From 040f32bcc646756ce39b9da53543ad16392855fb Mon Sep 17 00:00:00 2001 From: suyuan168 <175338101@qq.com> Date: Thu, 7 Jul 2022 23:14:11 +0800 Subject: [PATCH] Revert "fixfix" This reverts commit 993d00d5051b1fee4d148e7341785b2cce9786f6, reversing changes made to 7dafa5af80b81fdb86e626940f1678cf4d194917. --- root/target/linux/mediatek/Makefile | 19 + .../linux/mediatek/base-files/etc/inittab | 4 + .../base-files/etc/uci-defaults/99-net-ps | 7 + .../lib/preinit/05_set_preinit_iface | 9 + .../dts/mt7622-buffalo-wsr-2533dhp2.dts | 350 + .../dts/mt7622-elecom-wrc-2533gent.dts | 606 + .../mediatek/dts/mt7622-linksys-e8450-ubi.dts | 77 + .../mediatek/dts/mt7622-linksys-e8450.dts | 122 + .../mediatek/dts/mt7622-linksys-e8450.dtsi | 405 + .../linux/mediatek/dts/mt7622-rfb1-ubi.dts | 58 + .../dts/mt7622-ruijie-rg-ew3200gx-pro.dts | 327 + .../mediatek/dts/mt7622-totolink-a8000ru.dts | 339 + .../dts/mt7622-ubnt-unifi-6-lr-ubootmod.dts | 84 + .../mediatek/dts/mt7622-ubnt-unifi-6-lr.dts | 100 + .../mediatek/dts/mt7622-ubnt-unifi-6-lr.dtsi | 249 + .../dts/mt7622-xiaomi-redmi-router-ax6s.dts | 366 + .../mt7623a-unielec-u7623-02-emmc-512m.dts | 21 + .../mediatek/dts/mt7623a-unielec-u7623-02.dts | 12 + .../dts/mt7623a-unielec-u7623-02.dtsi | 356 + .../drivers/leds/leds-ubnt-ledbar.c | 210 + .../files-5.14/drivers/mtd/mtk-snand/Kconfig | 13 + .../files-5.14/drivers/mtd/mtk-snand/Makefile | 10 + .../drivers/mtd/mtk-snand/mtk-snand-def.h | 268 + .../drivers/mtd/mtk-snand/mtk-snand-ecc.c | 379 + .../drivers/mtd/mtk-snand/mtk-snand-ids.c | 511 + .../drivers/mtd/mtk-snand/mtk-snand-mtd.c | 681 + .../drivers/mtd/mtk-snand/mtk-snand-os.c | 48 + .../drivers/mtd/mtk-snand/mtk-snand-os.h | 127 + .../drivers/mtd/mtk-snand/mtk-snand.c | 1862 + .../drivers/mtd/mtk-snand/mtk-snand.h | 76 + .../drivers/net/phy/mtk/mt753x/Kconfig | 3 + .../drivers/net/phy/mtk/mt753x/Makefile | 11 + .../drivers/net/phy/mtk/mt753x/mt7530.c | 631 + .../drivers/net/phy/mtk/mt753x/mt7530.h | 13 + .../drivers/net/phy/mtk/mt753x/mt7531.c | 918 + .../drivers/net/phy/mtk/mt753x/mt7531.h | 13 + .../drivers/net/phy/mtk/mt753x/mt753x.h | 213 + .../net/phy/mtk/mt753x/mt753x_common.c | 90 + .../drivers/net/phy/mtk/mt753x/mt753x_mdio.c | 597 + .../drivers/net/phy/mtk/mt753x/mt753x_nl.c | 382 + .../drivers/net/phy/mtk/mt753x/mt753x_nl.h | 43 + .../drivers/net/phy/mtk/mt753x/mt753x_regs.h | 294 + .../net/phy/mtk/mt753x/mt753x_swconfig.c | 510 + .../net/phy/mtk/mt753x/mt753x_swconfig.h | 29 + .../drivers/net/phy/mtk/mt753x/mt753x_vlan.c | 183 + .../drivers/net/phy/mtk/mt753x/mt753x_vlan.h | 40 + .../files-5.14/drivers/net/phy/rtk/Makefile | 66 + .../drivers/net/phy/rtk/modules.builtin | 1 + .../drivers/net/phy/rtk/rtl8367c/acl.c | 2061 + .../drivers/net/phy/rtk/rtl8367c/cpu.c | 537 + .../drivers/net/phy/rtk/rtl8367c/dot1x.c | 843 + .../drivers/net/phy/rtk/rtl8367c/eee.c | 162 + .../drivers/net/phy/rtk/rtl8367c/i2c.c | 436 + .../drivers/net/phy/rtk/rtl8367c/igmp.c | 1555 + .../net/phy/rtk/rtl8367c/include/acl.h | 990 + .../net/phy/rtk/rtl8367c/include/cpu.h | 327 + .../net/phy/rtk/rtl8367c/include/dot1x.h | 470 + .../net/phy/rtk/rtl8367c/include/eee.h | 82 + .../net/phy/rtk/rtl8367c/include/i2c.h | 168 + .../net/phy/rtk/rtl8367c/include/igmp.h | 769 + .../net/phy/rtk/rtl8367c/include/interrupt.h | 254 + .../drivers/net/phy/rtk/rtl8367c/include/l2.h | 1181 + .../net/phy/rtk/rtl8367c/include/leaky.h | 371 + .../net/phy/rtk/rtl8367c/include/led.h | 481 + .../net/phy/rtk/rtl8367c/include/mirror.h | 272 + .../net/phy/rtk/rtl8367c/include/oam.h | 188 + .../net/phy/rtk/rtl8367c/include/port.h | 959 + .../net/phy/rtk/rtl8367c/include/ptp.h | 511 + .../net/phy/rtk/rtl8367c/include/qos.h | 781 + .../net/phy/rtk/rtl8367c/include/rate.h | 305 + .../net/phy/rtk/rtl8367c/include/rldp.h | 264 + .../net/phy/rtk/rtl8367c/include/rtk_error.h | 229 + .../net/phy/rtk/rtl8367c/include/rtk_hal.h | 44 + .../net/phy/rtk/rtl8367c/include/rtk_switch.h | 737 + .../net/phy/rtk/rtl8367c/include/rtk_types.h | 155 + .../rtk/rtl8367c/include/rtl8367c_asicdrv.h | 129 + .../rtl8367c/include/rtl8367c_asicdrv_acl.h | 231 + .../include/rtl8367c_asicdrv_cputag.h | 49 + .../rtl8367c/include/rtl8367c_asicdrv_dot1x.h | 52 + .../rtl8367c/include/rtl8367c_asicdrv_eav.h | 109 + .../rtl8367c/include/rtl8367c_asicdrv_eee.h | 31 + .../rtl8367c/include/rtl8367c_asicdrv_fc.h | 99 + .../rtl8367c/include/rtl8367c_asicdrv_green.h | 36 + .../rtl8367c/include/rtl8367c_asicdrv_hsb.h | 43 + .../rtl8367c/include/rtl8367c_asicdrv_i2c.h | 47 + .../rtl8367c/include/rtl8367c_asicdrv_igmp.h | 169 + .../include/rtl8367c_asicdrv_inbwctrl.h | 30 + .../include/rtl8367c_asicdrv_interrupt.h | 66 + .../rtl8367c/include/rtl8367c_asicdrv_led.h | 138 + .../rtl8367c/include/rtl8367c_asicdrv_lut.h | 159 + .../rtl8367c/include/rtl8367c_asicdrv_meter.h | 34 + .../rtl8367c/include/rtl8367c_asicdrv_mib.h | 133 + .../include/rtl8367c_asicdrv_mirror.h | 49 + .../rtl8367c/include/rtl8367c_asicdrv_misc.h | 34 + .../rtl8367c/include/rtl8367c_asicdrv_oam.h | 47 + .../rtl8367c/include/rtl8367c_asicdrv_phy.h | 43 + .../rtl8367c/include/rtl8367c_asicdrv_port.h | 237 + .../include/rtl8367c_asicdrv_portIsolation.h | 28 + .../rtl8367c/include/rtl8367c_asicdrv_qos.h | 96 + .../rtl8367c/include/rtl8367c_asicdrv_rldp.h | 60 + .../rtl8367c/include/rtl8367c_asicdrv_rma.h | 57 + .../include/rtl8367c_asicdrv_scheduling.h | 58 + .../rtl8367c/include/rtl8367c_asicdrv_storm.h | 61 + .../rtl8367c/include/rtl8367c_asicdrv_svlan.h | 132 + .../include/rtl8367c_asicdrv_trunking.h | 48 + .../rtl8367c_asicdrv_unknownMulticast.h | 59 + .../rtl8367c/include/rtl8367c_asicdrv_vlan.h | 157 + .../phy/rtk/rtl8367c/include/rtl8367c_base.h | 596 + .../phy/rtk/rtl8367c/include/rtl8367c_reg.h | 22819 ++ .../net/phy/rtk/rtl8367c/include/smi.h | 54 + .../net/phy/rtk/rtl8367c/include/stat.h | 433 + .../net/phy/rtk/rtl8367c/include/storm.h | 422 + .../net/phy/rtk/rtl8367c/include/svlan.h | 896 + .../net/phy/rtk/rtl8367c/include/trap.h | 757 + .../net/phy/rtk/rtl8367c/include/trunk.h | 328 + .../net/phy/rtk/rtl8367c/include/vlan.h | 892 + .../drivers/net/phy/rtk/rtl8367c/interrupt.c | 434 + .../drivers/net/phy/rtk/rtl8367c/l2.c | 2911 + .../drivers/net/phy/rtk/rtl8367c/leaky.c | 590 + .../drivers/net/phy/rtk/rtl8367c/led.c | 792 + .../drivers/net/phy/rtk/rtl8367c/mirror.c | 548 + .../drivers/net/phy/rtk/rtl8367c/oam.c | 245 + .../drivers/net/phy/rtk/rtl8367c/port.c | 2467 + .../drivers/net/phy/rtk/rtl8367c/ptp.c | 759 + .../drivers/net/phy/rtk/rtl8367c/qos.c | 1452 + .../drivers/net/phy/rtk/rtl8367c/rate.c | 607 + .../drivers/net/phy/rtk/rtl8367c/rldp.c | 468 + .../drivers/net/phy/rtk/rtl8367c/rtk_hal.c | 839 + .../drivers/net/phy/rtk/rtl8367c/rtk_switch.c | 1796 + .../net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c | 639 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c | 1173 + .../rtk/rtl8367c/rtl8367c_asicdrv_cputag.c | 369 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c | 415 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c | 877 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c | 141 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c | 1354 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c | 445 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c | 81 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c | 474 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c | 2109 + .../rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c | 164 + .../rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c | 205 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c | 727 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c | 1549 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c | 305 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c | 570 + .../rtk/rtl8367c/rtl8367c_asicdrv_mirror.c | 472 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c | 268 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c | 194 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c | 394 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c | 5752 + .../rtl8367c/rtl8367c_asicdrv_portIsolation.c | 119 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c | 778 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c | 674 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c | 362 + .../rtl8367c/rtl8367c_asicdrv_scheduling.c | 525 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c | 851 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c | 1003 + .../rtk/rtl8367c/rtl8367c_asicdrv_trunking.c | 356 + .../rtl8367c_asicdrv_unknownMulticast.c | 238 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c | 1505 + .../drivers/net/phy/rtk/rtl8367c/smi.c | 444 + .../drivers/net/phy/rtk/rtl8367c/stat.c | 626 + .../drivers/net/phy/rtk/rtl8367c/storm.c | 816 + .../drivers/net/phy/rtk/rtl8367c/svlan.c | 2415 + .../drivers/net/phy/rtk/rtl8367c/trap.c | 1229 + .../drivers/net/phy/rtk/rtl8367c/trunk.c | 605 + .../drivers/net/phy/rtk/rtl8367c/vlan.c | 2124 + .../files-5.14/drivers/net/phy/rtk/rtl8367s.c | 580 + .../drivers/net/phy/rtk/rtl8367s_dbg.c | 648 + .../drivers/net/phy/rtk/rtl8367s_mdio.c | 312 + .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 600 + .../arm64/boot/dts/mediatek/mt7622-rfb1.dts | 571 + .../arch/arm64/boot/dts/mediatek/mt7622.dtsi | 959 + .../files-5.4/drivers/leds/leds-ubnt-ledbar.c | 210 + .../drivers/net/phy/mtk/mt753x/Kconfig | 3 + .../drivers/net/phy/mtk/mt753x/Makefile | 11 + .../drivers/net/phy/mtk/mt753x/mt7530.c | 631 + .../drivers/net/phy/mtk/mt753x/mt7530.h | 13 + .../drivers/net/phy/mtk/mt753x/mt7531.c | 918 + .../drivers/net/phy/mtk/mt753x/mt7531.h | 13 + .../drivers/net/phy/mtk/mt753x/mt753x.h | 213 + .../net/phy/mtk/mt753x/mt753x_common.c | 90 + .../drivers/net/phy/mtk/mt753x/mt753x_mdio.c | 598 + .../drivers/net/phy/mtk/mt753x/mt753x_nl.c | 382 + .../drivers/net/phy/mtk/mt753x/mt753x_nl.h | 43 + .../drivers/net/phy/mtk/mt753x/mt753x_regs.h | 294 + .../net/phy/mtk/mt753x/mt753x_swconfig.c | 510 + .../net/phy/mtk/mt753x/mt753x_swconfig.h | 29 + .../drivers/net/phy/mtk/mt753x/mt753x_vlan.c | 183 + .../drivers/net/phy/mtk/mt753x/mt753x_vlan.h | 40 + .../files-5.4/drivers/net/phy/rtk/Makefile | 66 + .../drivers/net/phy/rtk/modules.builtin | 1 + .../drivers/net/phy/rtk/rtl8367c/acl.c | 2061 + .../drivers/net/phy/rtk/rtl8367c/cpu.c | 537 + .../drivers/net/phy/rtk/rtl8367c/dot1x.c | 843 + .../drivers/net/phy/rtk/rtl8367c/eee.c | 162 + .../drivers/net/phy/rtk/rtl8367c/i2c.c | 436 + .../drivers/net/phy/rtk/rtl8367c/igmp.c | 1555 + .../net/phy/rtk/rtl8367c/include/acl.h | 990 + .../net/phy/rtk/rtl8367c/include/cpu.h | 327 + .../net/phy/rtk/rtl8367c/include/dot1x.h | 470 + .../net/phy/rtk/rtl8367c/include/eee.h | 82 + .../net/phy/rtk/rtl8367c/include/i2c.h | 168 + .../net/phy/rtk/rtl8367c/include/igmp.h | 769 + .../net/phy/rtk/rtl8367c/include/interrupt.h | 254 + .../drivers/net/phy/rtk/rtl8367c/include/l2.h | 1181 + .../net/phy/rtk/rtl8367c/include/leaky.h | 371 + .../net/phy/rtk/rtl8367c/include/led.h | 481 + .../net/phy/rtk/rtl8367c/include/mirror.h | 272 + .../net/phy/rtk/rtl8367c/include/oam.h | 188 + .../net/phy/rtk/rtl8367c/include/port.h | 959 + .../net/phy/rtk/rtl8367c/include/ptp.h | 511 + .../net/phy/rtk/rtl8367c/include/qos.h | 781 + .../net/phy/rtk/rtl8367c/include/rate.h | 305 + .../net/phy/rtk/rtl8367c/include/rldp.h | 264 + .../net/phy/rtk/rtl8367c/include/rtk_error.h | 229 + .../net/phy/rtk/rtl8367c/include/rtk_hal.h | 44 + .../net/phy/rtk/rtl8367c/include/rtk_switch.h | 737 + .../net/phy/rtk/rtl8367c/include/rtk_types.h | 155 + .../rtk/rtl8367c/include/rtl8367c_asicdrv.h | 129 + .../rtl8367c/include/rtl8367c_asicdrv_acl.h | 231 + .../include/rtl8367c_asicdrv_cputag.h | 49 + .../rtl8367c/include/rtl8367c_asicdrv_dot1x.h | 52 + .../rtl8367c/include/rtl8367c_asicdrv_eav.h | 109 + .../rtl8367c/include/rtl8367c_asicdrv_eee.h | 31 + .../rtl8367c/include/rtl8367c_asicdrv_fc.h | 99 + .../rtl8367c/include/rtl8367c_asicdrv_green.h | 36 + .../rtl8367c/include/rtl8367c_asicdrv_hsb.h | 43 + .../rtl8367c/include/rtl8367c_asicdrv_i2c.h | 47 + .../rtl8367c/include/rtl8367c_asicdrv_igmp.h | 169 + .../include/rtl8367c_asicdrv_inbwctrl.h | 30 + .../include/rtl8367c_asicdrv_interrupt.h | 66 + .../rtl8367c/include/rtl8367c_asicdrv_led.h | 138 + .../rtl8367c/include/rtl8367c_asicdrv_lut.h | 159 + .../rtl8367c/include/rtl8367c_asicdrv_meter.h | 34 + .../rtl8367c/include/rtl8367c_asicdrv_mib.h | 133 + .../include/rtl8367c_asicdrv_mirror.h | 49 + .../rtl8367c/include/rtl8367c_asicdrv_misc.h | 34 + .../rtl8367c/include/rtl8367c_asicdrv_oam.h | 47 + .../rtl8367c/include/rtl8367c_asicdrv_phy.h | 43 + .../rtl8367c/include/rtl8367c_asicdrv_port.h | 237 + .../include/rtl8367c_asicdrv_portIsolation.h | 28 + .../rtl8367c/include/rtl8367c_asicdrv_qos.h | 96 + .../rtl8367c/include/rtl8367c_asicdrv_rldp.h | 60 + .../rtl8367c/include/rtl8367c_asicdrv_rma.h | 57 + .../include/rtl8367c_asicdrv_scheduling.h | 58 + .../rtl8367c/include/rtl8367c_asicdrv_storm.h | 61 + .../rtl8367c/include/rtl8367c_asicdrv_svlan.h | 132 + .../include/rtl8367c_asicdrv_trunking.h | 48 + .../rtl8367c_asicdrv_unknownMulticast.h | 59 + .../rtl8367c/include/rtl8367c_asicdrv_vlan.h | 157 + .../phy/rtk/rtl8367c/include/rtl8367c_base.h | 596 + .../phy/rtk/rtl8367c/include/rtl8367c_reg.h | 22819 ++ .../net/phy/rtk/rtl8367c/include/smi.h | 54 + .../net/phy/rtk/rtl8367c/include/stat.h | 433 + .../net/phy/rtk/rtl8367c/include/storm.h | 422 + .../net/phy/rtk/rtl8367c/include/svlan.h | 896 + .../net/phy/rtk/rtl8367c/include/trap.h | 757 + .../net/phy/rtk/rtl8367c/include/trunk.h | 328 + .../net/phy/rtk/rtl8367c/include/vlan.h | 892 + .../drivers/net/phy/rtk/rtl8367c/interrupt.c | 434 + .../drivers/net/phy/rtk/rtl8367c/l2.c | 2911 + .../drivers/net/phy/rtk/rtl8367c/leaky.c | 590 + .../drivers/net/phy/rtk/rtl8367c/led.c | 792 + .../drivers/net/phy/rtk/rtl8367c/mirror.c | 548 + .../drivers/net/phy/rtk/rtl8367c/oam.c | 245 + .../drivers/net/phy/rtk/rtl8367c/port.c | 2467 + .../drivers/net/phy/rtk/rtl8367c/ptp.c | 759 + .../drivers/net/phy/rtk/rtl8367c/qos.c | 1452 + .../drivers/net/phy/rtk/rtl8367c/rate.c | 607 + .../drivers/net/phy/rtk/rtl8367c/rldp.c | 468 + .../drivers/net/phy/rtk/rtl8367c/rtk_hal.c | 839 + .../drivers/net/phy/rtk/rtl8367c/rtk_switch.c | 1796 + .../net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c | 639 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c | 1173 + .../rtk/rtl8367c/rtl8367c_asicdrv_cputag.c | 369 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c | 415 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c | 877 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c | 141 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c | 1354 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c | 445 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c | 81 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c | 474 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c | 2109 + .../rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c | 164 + .../rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c | 205 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c | 727 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c | 1549 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c | 305 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c | 570 + .../rtk/rtl8367c/rtl8367c_asicdrv_mirror.c | 472 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c | 268 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c | 194 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c | 394 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c | 5752 + .../rtl8367c/rtl8367c_asicdrv_portIsolation.c | 119 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c | 778 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c | 674 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c | 362 + .../rtl8367c/rtl8367c_asicdrv_scheduling.c | 525 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c | 851 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c | 1003 + .../rtk/rtl8367c/rtl8367c_asicdrv_trunking.c | 356 + .../rtl8367c_asicdrv_unknownMulticast.c | 238 + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c | 1505 + .../drivers/net/phy/rtk/rtl8367c/smi.c | 444 + .../drivers/net/phy/rtk/rtl8367c/stat.c | 626 + .../drivers/net/phy/rtk/rtl8367c/storm.c | 816 + .../drivers/net/phy/rtk/rtl8367c/svlan.c | 2415 + .../drivers/net/phy/rtk/rtl8367c/trap.c | 1229 + .../drivers/net/phy/rtk/rtl8367c/trunk.c | 605 + .../drivers/net/phy/rtk/rtl8367c/vlan.c | 2124 + .../files-5.4/drivers/net/phy/rtk/rtl8367s.c | 580 + .../drivers/net/phy/rtk/rtl8367s_dbg.c | 655 + .../drivers/net/phy/rtk/rtl8367s_mdio.c | 312 + root/target/linux/mediatek/image/mt7622.mk | 290 + root/target/linux/mediatek/modules.mk | 51 + root/target/linux/mediatek/mt7622/config-5.14 | 465 + root/target/linux/mediatek/mt7622/config-5.4 | 476 + root/target/linux/mediatek/mt7622/target.mk | 10 + .../mt7623/base-files/etc/board.d/02_network | 36 + .../base-files/lib/preinit/07_set_iface_mac | 47 + .../base-files/lib/preinit/79_move_config | 19 + .../mt7623/base-files/lib/upgrade/platform.sh | 154 + root/target/linux/mediatek/mt7623/config-4.14 | 570 + root/target/linux/mediatek/mt7623/config-4.19 | 555 + root/target/linux/mediatek/mt7623/config-5.14 | 634 + root/target/linux/mediatek/mt7623/config-5.15 | 637 + root/target/linux/mediatek/mt7623/config-5.4 | 561 + .../0229-fix-memory-size-for-bpi-r2.patch | 23 + .../0229-update-gpio-leds-for-bpi-r2.patch | 27 + .../0230-update-pcie-for-bpi-r2.patch | 48 + .../0231-enable-trgmii-on-bpi-r2.patch | 22 + .../0232-merge-mt6625l-wifi-driver.patch | 217327 +++++++++++++++ .../0233-revert-unexport-vfs_read-write.patch | 35 + .../0234-fix-mtk-wlan_gen2-module.patch | 127 + .../0235-mtk_wdt-remove-debug-printk.patch | 12 + .../0236-mt6625l-rename-wlan.patch | 13 + .../0237-mt7623-add-HNAT-support.patch | 1824 + ...-and-build-script-change-gitignore-m.patch | 747 + .../0006-wifi-adding-driver-folder.patch | 216265 ++++++++++++++ ...-related-changes-outside-driver-dire.patch | 846 + ...y-Dominik-Koch-nic_rx-patch-from-htt.patch | 78 + .../0009-wifi-activated-wifi-options.patch | 52 + ...ssing-CONFIG_PCI_MSI-needed-for-pcie.patch | 34 + .../0014-dts-set-mac-address-eth0.patch | 34 + ...uild.sh-dts-added-devicetree-Overlay.patch | 40 + ...ields-for-holding-information-about-.patch | 60 + .../0020-net-dsa-add-helper-functions.patch | 86 + ...a-adding-handling-of-second-CPU-Port.patch | 102 + ...a-add-support-for-GMAC2-wired-to-ext.patch | 34 + .../0023-net-dsa-dsa-multi-cpu-mt7530.c.patch | 121 + ...A-when-we-are-turning-on-the-special.patch | 54 + ...5-net-dsa-mt7530-add-linking-to-mdio.patch | 47 + .../0026-net-dsa-changes-to-dts.patch | 81 + ...ek-add-refcount-for-DPI-power-on-off.patch | 171 + ...-move-hardware-register-to-node-data.patch | 101 + ...-adjust-EDGE-to-match-clock-and-data.patch | 62 + ...ek-add-clock-factor-for-different-IC.patch | 68 + ...vert-dpi-driver-to-use-drm_of_find_p.patch | 66 + ...add-dpi-driver-for-mt2701-and-mt7623.patch | 76 + ...-separate-hdmi-phy-to-different-file.patch | 641 + ...-add-support-for-SPDIF-audio-in-HDMI.patch | 32 + ...dd-hdmi-driver-for-MT2701-and-MT7623.patch | 309 + ...mplement-connection-from-BLS-to-DPI0.patch | 58 + ...-a-error-return-value-when-clock-dri.patch | 32 + ...fig-component-output-by-device-node-.patch | 142 + ...dd-a-performance-counter-unit-device.patch | 36 + ...pdate-subsystem-clock-controller-dev.patch | 76 + ...ts-mt7623-add-iommu-smi-device-nodes.patch | 120 + ...-mt7623-add-jpeg-decoder-device-node.patch | 41 + ...dd-display-subsystem-related-device-.patch | 493 + ...fix-boot-up-for-720-and-480-but-1080.patch | 72 + ...sing-different-round-rate-for-mt7623.patch | 103 + .../0046-hdmi-fix-possible_crtcs.patch | 26 + ...0047-hdmi-added-options-to-defconfig.patch | 31 + .../0049-hdmi-added-fbdev-options.patch | 24 + .../patches-4.19/0050-BT-fix-Bluetooth.patch | 69 + ...sable-some-debug-messages-evbug-gpio.patch | 34 + ...add-multiple-routing-tables-for-IPv4.patch | 25 + ...ig-added-options-for-Traffic-Shaping.patch | 33 + .../0061-defconfig-add-nftables.patch | 60 + ...defconfig-add-all-XT-matches-targets.patch | 100 + ...0064-dsa-fix-oops-in-br_vlan_enabled.patch | 34 + .../0066-defconfig-enable-mt76x2.patch | 25 + .../0067-dsa-fix-from-florian.patch | 34 + ...-atheros-wireless-lan-9k-10k-support.patch | 35 + .../0072-defconfig-add-ebtables.patch | 47 + .../0074-add-compiler-gcc8.h.patch | 78 + ...ig-add-mqueue-and-seccomp-for-docker.patch | 37 + .../0227-arm-dts-Add-Unielec-U7623-DTS.patch | 397 + .../0233-revert-unexport-vfs_read-write.patch | 35 + .../0234-fix-mtk-wlan_gen2-module.patch | 127 + .../0235-mtk_wdt-remove-debug-printk.patch | 12 + .../0236-mt6625l-rename-wlan.patch | 13 + .../patches-4.19/0999-wlan-memcpy-fix.patch | 20 + .../100-dts-update-mt7622-rfb1.patch | 119 + .../101-dts-update-mt7629-rfb.patch | 60 + .../105-dts-mt7622-enable-pstore.patch | 25 + .../110-dts-fix-bpi2-console.patch | 10 + .../111-dts-fix-bpi64-console.patch | 11 + .../112-dts-fix-bpi64-lan-names.patch | 37 + .../113-dts-fix-bpi64-leds-and-buttons.patch | 56 + .../114-dts-bpi64-disable-rtc.patch | 21 + .../115-dts-bpi64-add-snand-support.patch | 41 + .../130-dts-mt7629-add-snand-support.patch | 77 + .../131-dts-mt7622-add-snand-support.patch | 81 + ...s-mt7623-eip97-inside-secure-support.patch | 23 + .../160-dts-mt7623-bpi-r2-earlycon.patch | 11 + ...1-dts-mt7623-bpi-r2-mmc-device-order.patch | 11 + ...s-usb-mtk-musb-add-MT7623-compatible.patch | 23 + ...arm-dts-mt7623-add-musb-device-nodes.patch | 69 + ...-phy-phy-mtk-tphy-Add-hifsys-support.patch | 66 + .../patches-5.14/330-mtk-bmt-support.patch | 864 + ...ings-mtd-brcm-trx-Add-brcm-trx-magic.patch | 32 + ...ypto-add-eip97-inside-secure-support.patch | 27 + ...01-crypto-fix-eip97-cache-incoherent.patch | 26 + .../patches-5.14/410-bt-mtk-serial-fix.patch | 33 + ...or-add-support-for-Winbond-W25Q512JV.patch | 28 + .../500-gsw-rtl8367s-mt7622-support.patch | 25 + ...mediatek-add-flow-offload-for-mt7623.patch | 24 + ...ngs-PCI-Mediatek-Update-PCIe-binding.patch | 415 + ...e-regmap-to-get-shared-pcie-cfg-base.patch | 217 + ...ek-Split-PCIe-node-for-MT2712-MT7622.patch | 417 + ...dts-mediatek-Update-mt7629-PCIe-node.patch | 203 + ...diatek-fix-clearing-interrupt-status.patch | 24 + ..._eth_soc-add-support-for-coherent-DM.patch | 85 + ...ediatek-add-support-for-coherent-DMA.patch | 108 + .../patches-5.14/800-ubnt-ledbar-driver.patch | 29 + ...mt7622-bpi-r64-aliases-for-dtoverlay.patch | 80 + ...-spi-make-spi-max-frequency-optional.patch | 38 + ...port-for-mediatek-spi-nor-controller.patch | 761 + .../patches-5.4/0003-switch-add-mt7531.patch | 19 + ...cket-corruption-on-bridged-interface.patch | 51 + .../patches-5.4/0005-dts-mt7629-add-gsw.patch | 67 + .../0006-dts-fix-bpi2-console.patch | 10 + .../0006-dts-fix-bpi64-console.patch | 11 + ...ts-mt7629-rfb-fix-firmware-partition.patch | 13 + .../0103-net-support-net-labels.patch | 39 + .../patches-5.4/0110-rtc-mt6397.patch | 249 + .../patches-5.4/0111-mt6323-poweroff.patch | 160 + .../0112-dts-mt6323-add-key-rtc-power.patch | 57 + .../0170-dts-mt7623-add-display.patch | 500 + .../0171-dts-mt7623-add-mali450.patch | 77 + .../patches-5.4/0180-lima-power-on-off.patch | 68 + .../0181-drm-Add-get_possible_crtc.patch | 84 + .../0182-drm-change-possible_crtc.patch | 45 + .../patches-5.4/0183-drm-fix-DRM_INFO.patch | 21 + .../0184-drm-config-component-output.patch | 146 + .../patches-5.4/0185-drm-fix-boot-up.patch | 55 + .../patches-5.4/0190-thermal-add-sensor.patch | 56 + .../mediatek/patches-5.4/0191-thermal.patch | 35 + ...-phy-phy-mtk-tphy-Add-hifsys-support.patch | 66 + .../0227-arm-dts-Add-Unielec-U7623-DTS.patch | 387 + ...e-mtk-ecc-header-file-to-include-mtd.patch | 139 + .../0303-mtd-spinand-disable-on-die-ECC.patch | 31 + ...aTek-Add-SPI-NAND-Flash-interface-dr.patch | 1246 + .../0307-dts-mt7629-add-snand-support.patch | 97 + ...0-v5.6-crypto-backport-inside-secure.patch | 5464 + ...ypto-add-eip97-inside-secure-support.patch | 27 + ...s-mt7623-eip97-inside-secure-support.patch | 23 + ...03-crypto-fix-eip97-cache-incoherent.patch | 26 + ...agate-resolved-link-config-via-mac_l.patch | 246 + ...e-resolved-link-config-via-mac_link_.patch | 143 + ...se-resolved-link-config-in-mac_link_.patch | 145 + ...xtend-device-data-ready-for-adding-a.patch | 458 + ...530-Add-the-support-of-MT7531-switch.patch | 1510 + .../patches-5.4/0900-bt-mtk-serial-fix.patch | 33 + .../0990-gsw-rtl8367s-mt7622-support.patch | 23 + ...ngs-PCI-Mediatek-Update-PCIe-binding.patch | 415 + ...e-regmap-to-get-shared-pcie-cfg-base.patch | 217 + ...dts-mediatek-Update-mt7629-PCIe-node.patch | 203 + .../patches-5.4/0999-lan-to-wan.patch | 35 + ...diatek-fix-clearing-interrupt-status.patch | 24 + ..._eth_soc-add-support-for-coherent-DM.patch | 85 + .../patches-5.4/1020-spi-nor-w25q512jv.patch | 25 + .../patches-5.4/1021-ubnt-ledbar-driver.patch | 29 + ...dts-mediatek-add-mtk-snfi-for-mt7622.patch | 35 + ...s-mediatek-add-mt7622-pcie-slot-node.patch | 28 + 480 files changed, 669547 insertions(+) create mode 100755 root/target/linux/mediatek/Makefile create mode 100755 root/target/linux/mediatek/base-files/etc/inittab create mode 100755 root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps create mode 100755 root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface create mode 100755 root/target/linux/mediatek/dts/mt7622-buffalo-wsr-2533dhp2.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-elecom-wrc-2533gent.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-linksys-e8450-ubi.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-linksys-e8450.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-linksys-e8450.dtsi create mode 100755 root/target/linux/mediatek/dts/mt7622-rfb1-ubi.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-ruijie-rg-ew3200gx-pro.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-totolink-a8000ru.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr-ubootmod.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dts create mode 100755 root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dtsi create mode 100755 root/target/linux/mediatek/dts/mt7622-xiaomi-redmi-router-ax6s.dts create mode 100755 root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02-emmc-512m.dts create mode 100755 root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dts create mode 100755 root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dtsi create mode 100755 root/target/linux/mediatek/files-5.14/drivers/leds/leds-ubnt-ledbar.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Kconfig create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Makefile create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-def.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ecc.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ids.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-mtd.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Kconfig create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Makefile create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_common.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_mdio.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_regs.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/Makefile create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/modules.builtin create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/acl.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/cpu.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/dot1x.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/eee.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/i2c.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/igmp.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/acl.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/cpu.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/dot1x.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/eee.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/i2c.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/igmp.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/interrupt.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/l2.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/leaky.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/led.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/mirror.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/oam.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/port.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/ptp.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/qos.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rate.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rldp.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/smi.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/stat.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/storm.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/svlan.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trap.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trunk.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/vlan.h create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/interrupt.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/l2.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/leaky.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/led.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/mirror.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/oam.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/port.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/ptp.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/qos.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rate.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rldp.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtk_hal.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtk_switch.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mirror.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/smi.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/stat.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/storm.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/svlan.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trap.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trunk.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/vlan.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_dbg.c create mode 100755 root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_mdio.c create mode 100755 root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts create mode 100755 root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts create mode 100755 root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622.dtsi create mode 100755 root/target/linux/mediatek/files-5.4/drivers/leds/leds-ubnt-ledbar.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Kconfig create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Makefile create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_common.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_mdio.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_regs.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/Makefile create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/modules.builtin create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/acl.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/cpu.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/dot1x.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/eee.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/i2c.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/igmp.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/acl.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/cpu.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/dot1x.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/eee.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/i2c.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/igmp.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/interrupt.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/l2.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/leaky.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/led.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/mirror.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/oam.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/port.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/ptp.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/qos.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rate.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rldp.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/smi.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/stat.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/storm.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/svlan.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trap.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trunk.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/vlan.h create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/interrupt.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/l2.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/leaky.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/led.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/mirror.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/oam.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/port.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/ptp.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/qos.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rate.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rldp.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtk_hal.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtk_switch.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mirror.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/smi.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/stat.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/storm.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/svlan.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trap.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trunk.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/vlan.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_dbg.c create mode 100755 root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_mdio.c create mode 100755 root/target/linux/mediatek/image/mt7622.mk create mode 100755 root/target/linux/mediatek/modules.mk create mode 100755 root/target/linux/mediatek/mt7622/config-5.14 create mode 100755 root/target/linux/mediatek/mt7622/config-5.4 create mode 100755 root/target/linux/mediatek/mt7622/target.mk create mode 100755 root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network create mode 100755 root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac create mode 100755 root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config create mode 100755 root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh create mode 100755 root/target/linux/mediatek/mt7623/config-4.14 create mode 100755 root/target/linux/mediatek/mt7623/config-4.19 create mode 100755 root/target/linux/mediatek/mt7623/config-5.14 create mode 100755 root/target/linux/mediatek/mt7623/config-5.15 create mode 100755 root/target/linux/mediatek/mt7623/config-5.4 create mode 100755 root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch create mode 100755 root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch create mode 100755 root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch create mode 100755 root/target/linux/mediatek/patches-5.14/100-dts-update-mt7622-rfb1.patch create mode 100755 root/target/linux/mediatek/patches-5.14/101-dts-update-mt7629-rfb.patch create mode 100755 root/target/linux/mediatek/patches-5.14/105-dts-mt7622-enable-pstore.patch create mode 100755 root/target/linux/mediatek/patches-5.14/110-dts-fix-bpi2-console.patch create mode 100755 root/target/linux/mediatek/patches-5.14/111-dts-fix-bpi64-console.patch create mode 100755 root/target/linux/mediatek/patches-5.14/112-dts-fix-bpi64-lan-names.patch create mode 100755 root/target/linux/mediatek/patches-5.14/113-dts-fix-bpi64-leds-and-buttons.patch create mode 100755 root/target/linux/mediatek/patches-5.14/114-dts-bpi64-disable-rtc.patch create mode 100755 root/target/linux/mediatek/patches-5.14/115-dts-bpi64-add-snand-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/130-dts-mt7629-add-snand-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/131-dts-mt7622-add-snand-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/150-dts-mt7623-eip97-inside-secure-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/160-dts-mt7623-bpi-r2-earlycon.patch create mode 100755 root/target/linux/mediatek/patches-5.14/161-dts-mt7623-bpi-r2-mmc-device-order.patch create mode 100755 root/target/linux/mediatek/patches-5.14/172-dt-bindings-usb-mtk-musb-add-MT7623-compatible.patch create mode 100755 root/target/linux/mediatek/patches-5.14/173-arm-dts-mt7623-add-musb-device-nodes.patch create mode 100755 root/target/linux/mediatek/patches-5.14/200-phy-phy-mtk-tphy-Add-hifsys-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/330-mtk-bmt-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/350-dt-bindings-mtd-brcm-trx-Add-brcm-trx-magic.patch create mode 100755 root/target/linux/mediatek/patches-5.14/400-crypto-add-eip97-inside-secure-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/401-crypto-fix-eip97-cache-incoherent.patch create mode 100755 root/target/linux/mediatek/patches-5.14/410-bt-mtk-serial-fix.patch create mode 100755 root/target/linux/mediatek/patches-5.14/420-mtd-spi-nor-add-support-for-Winbond-W25Q512JV.patch create mode 100755 root/target/linux/mediatek/patches-5.14/500-gsw-rtl8367s-mt7622-support.patch create mode 100755 root/target/linux/mediatek/patches-5.14/510-net-mediatek-add-flow-offload-for-mt7623.patch create mode 100755 root/target/linux/mediatek/patches-5.14/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch create mode 100755 root/target/linux/mediatek/patches-5.14/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch create mode 100755 root/target/linux/mediatek/patches-5.14/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch create mode 100755 root/target/linux/mediatek/patches-5.14/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch create mode 100755 root/target/linux/mediatek/patches-5.14/610-pcie-mediatek-fix-clearing-interrupt-status.patch create mode 100755 root/target/linux/mediatek/patches-5.14/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch create mode 100755 root/target/linux/mediatek/patches-5.14/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch create mode 100755 root/target/linux/mediatek/patches-5.14/800-ubnt-ledbar-driver.patch create mode 100755 root/target/linux/mediatek/patches-5.14/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0191-thermal.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0227-arm-dts-Add-Unielec-U7623-DTS.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch create mode 100755 root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch create mode 100755 root/target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch create mode 100755 root/target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch create mode 100755 root/target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch create mode 100755 root/target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch create mode 100755 root/target/linux/mediatek/patches-5.4/120-14-arm64-dts-mediatek-add-mtk-snfi-for-mt7622.patch create mode 100755 root/target/linux/mediatek/patches-5.4/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch diff --git a/root/target/linux/mediatek/Makefile b/root/target/linux/mediatek/Makefile new file mode 100755 index 00000000..2cb1a156 --- /dev/null +++ b/root/target/linux/mediatek/Makefile @@ -0,0 +1,19 @@ +# Copyright (c) 2015 OpenWrt.org +# +include $(TOPDIR)/rules.mk + +ARCH:=arm +BOARD:=mediatek +BOARDNAME:=MediaTek Ralink ARM +SUBTARGETS:=mt7622 mt7623 mt7629 +#FEATURES:=squashfs nand ramdisk fpu +FEATURES:=dt-overlay emmc fpu gpio nand pci pcie rootfs-part separate_ramdisk squashfs usb + +KERNEL_PATCHVER:=5.4 +KERNEL_TESTING_PATCHVER:=5.4 + +include $(INCLUDE_DIR)/target.mk +DEFAULT_PACKAGES += \ + kmod-leds-gpio kmod-gpio-button-hotplug + +$(eval $(call BuildTarget)) diff --git a/root/target/linux/mediatek/base-files/etc/inittab b/root/target/linux/mediatek/base-files/etc/inittab new file mode 100755 index 00000000..18857874 --- /dev/null +++ b/root/target/linux/mediatek/base-files/etc/inittab @@ -0,0 +1,4 @@ +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K shutdown +::askconsole:/usr/libexec/login.sh +ttyS0::askfirst:/usr/libexec/login.sh diff --git a/root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps b/root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps new file mode 100755 index 00000000..96434001 --- /dev/null +++ b/root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps @@ -0,0 +1,7 @@ +#!/bin/sh +uci -q set network.globals.default_rps_val=14 +uci -q set network.globals.default_rps_flow_cnt=256 +uci -q set network.globals.default_xps_val=14 +uci -q set network.globals.default_ps=1 +uci -q commit +exit 0 diff --git a/root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface b/root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface new file mode 100755 index 00000000..0184a7c6 --- /dev/null +++ b/root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface @@ -0,0 +1,9 @@ +#!/bin/sh + +set_preinit_iface() { + ifconfig eth0 up + ifname=lan +} + +boot_hook_add preinit_main set_preinit_iface + diff --git a/root/target/linux/mediatek/dts/mt7622-buffalo-wsr-2533dhp2.dts b/root/target/linux/mediatek/dts/mt7622-buffalo-wsr-2533dhp2.dts new file mode 100755 index 00000000..6d77be53 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-buffalo-wsr-2533dhp2.dts @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "Buffalo WSR-2533DHP2"; + compatible = "buffalo,wsr-2533dhp2", "mediatek,mt7622"; + + aliases { + serial0 = &uart0; + led-boot = &power_green; + led-failsafe = &power_amber; + led-running = &power_green; + led-upgrade = &power_green; + }; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8 swiotlb=512"; + }; + + memory { + reg = <0 0x40000000 0 0x0F000000>; + }; + + leds { + compatible = "gpio-leds"; + + wireless_amber { + label = "amber:wireless"; + gpios = <&pio 2 GPIO_ACTIVE_HIGH>; + }; + + power_amber: power_amber { + label = "amber:power"; + gpios = <&pio 3 GPIO_ACTIVE_LOW>; + }; + + power_green: power_green { + label = "green:power"; + gpios = <&pio 4 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + wireless_green { + label = "green:wireless"; + gpios = <&pio 15 GPIO_ACTIVE_HIGH>; + }; + + internet { + label = "green:internet"; + gpios = <&pio 19 GPIO_ACTIVE_HIGH>; + }; + + router { + label = "green:router"; + gpios = <&pio 20 GPIO_ACTIVE_HIGH>; + }; + }; + + keys { + compatible = "gpio-keys"; + poll-interval = <100>; + + reset { + label = "reset"; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + /* GPIO 1 and 16 are a tri-state switch button with + * ROUTER / AP / WB. + */ + router { + label = "router"; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + bridge { + label = "wb"; + gpios = <&pio 16 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + /* GPIO 18 is a switch button with AUTO / MANUAL. */ + manual { + label = "manual"; + gpios = <&pio 18 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + wps { + label = "wps"; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + rtkgsw: rtkgsw@0 { + compatible = "mediatek,rtk-gsw"; + mediatek,ethsys = <ðsys>; + mediatek,mdio = <&mdio>; + mediatek,reset-pin = <&pio 54 GPIO_ACTIVE_HIGH>; + }; +}; + +&cpu0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; +}; + +&cpu1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&slot0 { + status = "okay"; + + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x5000>; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&pio { + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + /* Parallel nand is shared pin with eMMC */ + parallel_nand_pins: parallel-nand-pins { + mux { + function = "flash"; + groups = "par_nand"; + }; + + conf-cmd-dat { + pins = "NCEB", "NWEB", "NREB", + "NDL4", "NDL5", "NDL6", + "NDL7", "NRB", "NCLE", + "NALE", "NDL0", "NDL1", + "NDL2", "NDL3"; + input-enable; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm7_pins: pwm1-2-pins { + mux { + function = "pwm"; + groups = "pwm_ch7_2"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&bch { + status = "okay"; +}; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + + phy-connection-type = "2500base-x"; + + nvmem-cells = <&macaddr_factory_4>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <(-1)>; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&nandc { + pinctrl-names = "default"; + pinctrl-0 = <¶llel_nand_pins>; + status = "okay"; + + nand@0 { + reg = <0>; + nand-ecc-mode = "hw"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x40000>; + read-only; + }; + + partition@c0000 { + label = "Bootloader"; + reg = <0xc0000 0x80000>; + read-only; + }; + + partition@140000 { + label = "Config"; + reg = <0x140000 0x80000>; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x40000>; + read-only; + }; + + partition@200000 { + compatible = "brcm,trx"; + brcm,trx-magic = <0x32504844>; + label = "firmware"; + reg = <0x200000 0x3a00000>; + }; + + partition@3C00000 { + label = "Kernel2"; + reg = <0x3c00000 0x3a00000>; + }; + + partition@7600000 { + label = "glbcfg"; + reg = <0x7600000 0x200000>; + read-only; + }; + + partition@7800000 { + label = "board_data"; + reg = <0x7800000 0x200000>; + read-only; + }; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + status = "okay"; + + mediatek,mtd-eeprom = <&factory 0x0>; +}; + +&rtc { + status = "disabled"; +}; + +&factory { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_factory_4: macaddr@4 { + reg = <0x4 0x6>; + }; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-elecom-wrc-2533gent.dts b/root/target/linux/mediatek/dts/mt7622-elecom-wrc-2533gent.dts new file mode 100755 index 00000000..3e061ef9 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-elecom-wrc-2533gent.dts @@ -0,0 +1,606 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + */ + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "Elecom WRC-2533"; + compatible = "elecom,wrc-2533gent", "mediatek,mt7622"; + + aliases { + led-boot = &led_power; + led-failsafe = &led_power; + led-running = &led_power; + led-upgrade = &led_power; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512 console=ttyS0,115200n8"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + poll-interval = <100>; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_HIGH>; + }; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + }; + + switch0 { + label = "switch0"; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch1 { + label = "switch1"; + gpios = <&pio 16 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch2 { + label = "switch2"; + gpios = <&pio 17 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch3 { + label = "switch3"; + gpios = <&pio 18 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_power: power_g { + label = "wrc-2533:green:power"; + gpios = <&pio 2 GPIO_ACTIVE_HIGH>; + }; + + power_b { + label = "wrc-2533:blue:power"; + gpios = <&pio 19 GPIO_ACTIVE_HIGH>; + }; + + power_r { + label = "wrc-2533:red:power"; + gpios = <&pio 73 GPIO_ACTIVE_HIGH>; + }; + + usb { + label = "wrc-2533:blue:usb"; + gpios = <&pio 74 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "wrc-2533:red:wps"; + gpios = <&pio 76 GPIO_ACTIVE_LOW>; + }; + + wifi2 { + label = "wrc-2533:blue:wifi2g"; + gpios = <&pio 85 GPIO_ACTIVE_LOW>; + }; + + wifi5 { + label = "wrc-2533:blue:wifi5g"; + gpios = <&pio 91 GPIO_ACTIVE_LOW>; + }; + }; + + reg_usb_vbus: regulator { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pio 22 GPIO_ACTIVE_LOW>; + enable-active-high; + }; + + memory { + reg = <0 0x40000000 0 0x3F000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + rtkgsw: rtkgsw@0 { + compatible = "mediatek,rtk-gsw"; + mediatek,ethsys = <ðsys>; + mediatek,mdio = <&mdio>; + mediatek,reset-pin = <&pio 54 0>; + status = "okay"; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&slot0 { + mt7615@0,0 { + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x05000>; + }; +}; + +&pio { + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { + function = "emmc", "emmc_rst"; + groups = "emmc"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", + * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, + * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively + */ + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + bias-pull-down; + }; + }; + + emmc_pins_uhs: emmc-pins-uhs { + mux { + function = "emmc"; + groups = "emmc"; + }; + + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + drive-strength = <4>; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + drive-strength = <4>; + bias-pull-down; + }; + }; + + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + i2c1_pins: i2c1-pins { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + + i2c2_pins: i2c2-pins { + mux { + function = "i2c"; + groups = "i2c2_0"; + }; + }; + + i2s1_pins: i2s1-pins { + mux { + function = "i2s"; + groups = "i2s_out_mclk_bclk_ws", + "i2s1_in_data", + "i2s1_out_data"; + }; + + conf { + pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", + "I2S_WS", "I2S_MCLK"; + drive-strength = <12>; + bias-pull-down; + }; + }; + + irrx_pins: irrx-pins { + mux { + function = "ir"; + groups = "ir_1_rx"; + }; + }; + + irtx_pins: irtx-pins { + mux { + function = "ir"; + groups = "ir_1_tx"; + }; + }; + + /* Parallel nand is shared pin with eMMC */ + parallel_nand_pins: parallel-nand-pins { + mux { + function = "flash"; + groups = "par_nand"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm7_pins: pwm1-2-pins { + mux { + function = "pwm"; + groups = "pwm_ch7_2"; + }; + }; + + wled_pins: wled-pins { + mux { + function = "led"; + groups = "wled"; + }; + }; + + sd0_pins_default: sd0-pins-default { + mux { + function = "sd"; + groups = "sd_0"; + }; + + /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", + * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, + * DAT2, DAT3, CMD, CLK for SD respectively. + */ + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + drive-strength = <8>; + bias-pull-up; + }; + conf-clk { + pins = "I2S3_OUT"; + drive-strength = <12>; + bias-pull-down; + }; + conf-cd { + pins = "TXD3"; + bias-pull-up; + }; + }; + + sd0_pins_uhs: sd0-pins-uhs { + mux { + function = "sd"; + groups = "sd_0"; + }; + + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "I2S3_OUT"; + bias-pull-down; + }; + }; + + /* Serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + spic0_pins: spic0-pins { + mux { + function = "spi"; + groups = "spic0_0"; + }; + }; + + spic1_pins: spic1-pins { + mux { + function = "spi"; + groups = "spic1_0"; + }; + }; + + /* SPI-NOR is shared pin with serial NAND */ + spi_nor_pins: spi-nor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + /* serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + uart2_pins: uart2-pins { + mux { + function = "uart"; + groups = "uart2_1_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&btif { + status = "disabled"; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&irrx_pins>; + status = "okay"; +}; + +ð { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "sgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "rgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "okay"; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + + status = "okay"; +}; + +&bch { + status = "okay"; +}; + +&snfi { + pinctrl-names = "default"; + pinctrl-0 = <&serial_nand_pins>; + status = "okay"; + flash@0 { + compatible = "spi-nand"; + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + nand-ecc-engine = <&snfi>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x00000 0x0080000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x0040000>; + read-only; + }; + + partition@c0000 { + label = "uboot"; + reg = <0xc0000 0x0080000>; + read-only; + }; + + partition@140000 { + label = "uboot-env"; + reg = <0x140000 0x0080000>; + read-only; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x0040000>; + read-only; + }; + + partition@200000 { + label = "firmware"; + reg = <0x200000 0x2000000>; + }; + + partition@2200000 { + label = "reserved"; + reg = <0x2200000 0x4000000>; + }; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spic1_pins>; + status = "okay"; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_usb_vbus>; + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + mediatek,mtd-eeprom = <&factory 0x0000>; + status = "okay"; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-linksys-e8450-ubi.dts b/root/target/linux/mediatek/dts/mt7622-linksys-e8450-ubi.dts new file mode 100755 index 00000000..9df736eb --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-linksys-e8450-ubi.dts @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) + +/dts-v1/; +#include "mt7622-linksys-e8450.dtsi" + +/ { + model = "Linksys E8450 (UBI)"; + compatible = "linksys,e8450-ubi", "mediatek,mt7622"; + + aliases { + label-mac-device = &wan; + }; +}; + +&snand { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "bl2"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@80000 { + label = "fip"; + reg = <0x80000 0x140000>; + read-only; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x100000>; + read-only; + }; + + partition@300000 { + label = "ubi"; + reg = <0x300000 0x7d00000>; + }; + }; +}; + +&wmac { + mediatek,mtd-eeprom = <&factory 0x0>; + status = "okay"; +}; + +&wmac1 { + mediatek,mtd-eeprom = <&factory 0x5000>; +}; + +&gmac0 { + nvmem-cells = <&macaddr_factory_7fff4>; + nvmem-cell-names = "mac-address"; +}; + +&wan { + nvmem-cells = <&macaddr_factory_7fffa>; + nvmem-cell-names = "mac-address"; +}; + +&factory { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_factory_7fff4: macaddr@7fff4 { + reg = <0x7fff4 0x6>; + }; + + macaddr_factory_7fffa: macaddr@7fffa { + reg = <0x7fffa 0x6>; + }; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-linksys-e8450.dts b/root/target/linux/mediatek/dts/mt7622-linksys-e8450.dts new file mode 100755 index 00000000..8552dbf1 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-linksys-e8450.dts @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) + +/dts-v1/; +#include "mt7622-linksys-e8450.dtsi" + +/ { + model = "Linksys E8450"; + compatible = "linksys,e8450", "mediatek,mt7622"; + + aliases { + label-mac-device = &wan; + }; +}; + +&snand { + mediatek,bmt-v2; + mediatek,bmt-table-size = <0x1000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x00000 0x0080000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x0040000>; + }; + + partition@c0000 { + label = "u-boot"; + reg = <0xc0000 0x0080000>; + }; + + partition@140000 { + label = "u-boot-env"; + reg = <0x140000 0x0080000>; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x0100000>; + }; + + partition@300000 { + label = "devinfo"; + reg = <0x300000 0x020000>; + }; + + partition@320000 { + label = "senv"; + reg = <0x320000 0x020000>; + }; + + partition@360000 { + label = "bootseq"; + reg = <0x360000 0x020000>; + }; + + partition@500000 { + label = "firmware1"; + compatible = "denx,fit"; + openwrt,cmdline-match = "mtdparts=master"; + reg = <0x500000 0x1E00000>; + }; + + partition@2300000 { + label = "firmware2"; + compatible = "denx,fit"; + openwrt,cmdline-match = "mtdparts=slave"; + reg = <0x2300000 0x1E00000>; + }; + + partition@4100000 { + label = "data"; + reg = <0x4100000 0x1900000>; + }; + + partition@5100000 { + label = "mfg"; + reg = <0x5a00000 0x1400000>; + }; + }; +}; + +&wmac { + mediatek,mtd-eeprom = <&factory 0x0000>; + status = "okay"; +}; + +&wmac1 { + mediatek,mtd-eeprom = <&factory 0x05000>; +}; + +&gmac0 { + nvmem-cells = <&macaddr_factory_7fff4>; + nvmem-cell-names = "mac-address"; +}; + +&wan { + nvmem-cells = <&macaddr_factory_7fffa>; + nvmem-cell-names = "mac-address"; +}; + +&factory { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_factory_7fff4: macaddr@7fff4 { + reg = <0x7fff4 0x6>; + }; + + macaddr_factory_7fffa: macaddr@7fffa { + reg = <0x7fffa 0x6>; + }; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-linksys-e8450.dtsi b/root/target/linux/mediatek/dts/mt7622-linksys-e8450.dtsi new file mode 100755 index 00000000..9f0dabdb --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-linksys-e8450.dtsi @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + compatible = "linksys,e8450", "mediatek,mt7622"; + + aliases { + serial0 = &uart0; + led-boot = &led_power; + led-failsafe = &led_power; + led-running = &led_power; + led-upgrade = &led_power; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + factory { + label = "reset"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_power: power_blue { + label = "power:blue"; + gpios = <&pio 95 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + power_orange { + label = "power:orange"; + gpios = <&pio 96 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + inet_blue { + label = "inet:blue"; + gpios = <&pio 97 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + inet_orange { + label = "inet:orange"; + gpios = <&pio 98 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; + + memory { + reg = <0 0x40000000 0 0x40000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&btif { + status = "okay"; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&irrx_pins>; + status = "okay"; +}; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7531"; + reg = <0>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&pio>; + interrupts = <53 IRQ_TYPE_LEVEL_HIGH>; + reset-gpios = <&pio 54 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan1"; + }; + + port@1 { + reg = <1>; + label = "lan2"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + }; + + port@3 { + reg = <3>; + label = "lan4"; + }; + + wan: port@4 { + reg = <4>; + label = "wan"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; + + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_pins>; + status = "okay"; +}; + +&pio { + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + irrx_pins: irrx-pins { + mux { + function = "ir"; + groups = "ir_1_rx"; + }; + }; + + irtx_pins: irtx-pins { + mux { + function = "ir"; + groups = "ir_1_tx"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm7_pins: pwm1-2-pins { + mux { + function = "pwm"; + groups = "pwm_ch7_2"; + }; + }; + + wled_pins: wled-pins { + mux { + function = "led"; + groups = "wled"; + }; + }; + + /* Serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + spic0_pins: spic0-pins { + mux { + function = "spi"; + groups = "spic0_0"; + }; + }; + + spic1_pins: spic1-pins { + mux { + function = "spi"; + groups = "spic1_0"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + uart2_pins: uart2-pins { + mux { + function = "uart"; + groups = "uart2_1_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + + status = "okay"; +}; + +&sata { + status = "disabled"; +}; + +&sata_phy { + status = "disabled"; +}; + +&slot0 { + wmac1: mt7915@0,0 { + reg = <0x0000 0 0 0 0>; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&bch { + status = "okay"; +}; + +&snfi { + pinctrl-names = "default"; + pinctrl-0 = <&serial_nand_pins>; + status = "okay"; + + snand: flash@0 { + compatible = "spi-nand"; + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + nand-ecc-engine = <&snfi>; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spic1_pins>; + status = "okay"; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_5v>; + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; +}; + +&rtc { + status = "disabled"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-rfb1-ubi.dts b/root/target/linux/mediatek/dts/mt7622-rfb1-ubi.dts new file mode 100755 index 00000000..0f6d9bbc --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-rfb1-ubi.dts @@ -0,0 +1,58 @@ +/dts-v1/; + +#include "mt7622-rfb1.dts" +/ { + model = "MT7622_MT7531 RFB (UBI)"; + compatible = "mediatek,mt7622-rfb1-ubi"; +}; + +&snfi { + flash@0 { + mediatek,bmt-v2; + mediatek,bmt-remap-range = <0x0 0x6c0000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x00000 0x0080000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x0040000>; + }; + + partition@c0000 { + label = "Bootloader"; + reg = <0xc0000 0x0080000>; + }; + + partition@140000 { + label = "Config"; + reg = <0x140000 0x0080000>; + }; + + factory: partition@1c0000 { + label = "Factory"; + reg = <0x1c0000 0x0100000>; + }; + + partition@200000 { + label = "kernel"; + reg = <0x2c0000 0x400000>; + }; + + partition@6c0000 { + label = "ubi"; + reg = <0x6c0000 0x6f00000>; + }; + + /delete-node/ partition@2200000; + }; + }; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-ruijie-rg-ew3200gx-pro.dts b/root/target/linux/mediatek/dts/mt7622-ruijie-rg-ew3200gx-pro.dts new file mode 100755 index 00000000..df8f2a58 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-ruijie-rg-ew3200gx-pro.dts @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "Ruijie RG-EW3200GX PRO"; + compatible = "ruijie,rg-ew3200gx-pro", "mediatek,mt7622"; + + aliases { + ethernet0 = &gmac0; + label-mac-device = &gmac0; + led-boot = &led_system; + led-failsafe = &led_system; + led-running = &led_system; + led-upgrade = &led_system; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n1"; + bootargs = "console=ttyS0,115200n1 swiotlb=512"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + mesh_green { + label = "green:mesh"; + gpios = <&pio 79 GPIO_ACTIVE_LOW>; + }; + + mesh_red { + label = "red:mesh"; + gpios = <&pio 82 GPIO_ACTIVE_LOW>; + }; + + led_system: system_blue { + label = "blue:system"; + gpios = <&pio 81 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; + + memory { + reg = <0 0x40000000 0 0x40000000>; + }; +}; + +ð { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-connection-type = "2500base-x"; + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7531"; + reg = <0>; + reset-gpios = <&pio 54 GPIO_ACTIVE_HIGH>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&pio>; + interrupts = <53 IRQ_TYPE_LEVEL_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan1"; + }; + + port@1 { + reg = <1>; + label = "lan2"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + }; + + port@3 { + reg = <3>; + label = "lan4"; + }; + + wan: port@4 { + reg = <4>; + label = "wan"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; + }; +}; + +&pcie0 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; +}; + +&slot0 { + mt7915@0,0 { + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x5000>; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&pio { + epa_elna_pins: epa-elna-pins { + mux { + function = "antsel"; + groups = "antsel0", "antsel1", "antsel2", "antsel3", + "antsel4", "antsel5", "antsel6", "antsel7", + "antsel8", "antsel9", "antsel12", "antsel13", + "antsel14", "antsel15", "antsel16", "antsel17"; + }; + }; + + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_0_waken", + "pcie0_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + spi_nor_pins: spi-nor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx"; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&pwrap { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; +}; + +&nor_flash { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&spi_nor_pins>; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x0 0x40000>; + read-only; + }; + + partition@40000 { + label = "ATF"; + reg = <0x40000 0x20000>; + read-only; + }; + + partition@60000 { + label = "u-boot"; + reg = <0x60000 0x50000>; + read-only; + }; + + partition@B0000 { + label = "u-boot-env"; + reg = <0xb0000 0x20000>; + }; + + factory: partition@D0000 { + label = "Factory"; + reg = <0xd0000 0x80000>; + read-only; + }; + + partition@150000 { + label = "product_info"; + reg = <0x150000 0x10000>; + read-only; + }; + + partition@160000 { + label = "kdump"; + reg = <0x160000 0x10000>; + read-only; + }; + + partition@170000 { + compatible = "denx,fit"; + label = "firmware"; + reg = <0x170000 0xe90000>; + }; + }; + }; +}; + +&rtc { + status = "disabled"; +}; + +&uart0 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; +}; + +&watchdog { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; +}; + +&wmac { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&epa_elna_pins>; + mediatek,mtd-eeprom = <&factory 0x0>; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-totolink-a8000ru.dts b/root/target/linux/mediatek/dts/mt7622-totolink-a8000ru.dts new file mode 100755 index 00000000..d67fb4ef --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-totolink-a8000ru.dts @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "TOTOLINK A8000RU"; + compatible = "totolink,a8000ru", "mediatek,mt7622"; + + aliases { + label-mac-device = &gmac0; + led-boot = &led_status; + led-failsafe = &led_status; + led-running = &led_status; + led-upgrade = &led_status; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_status: status_red { + label = "red:status"; + gpios = <&pio 81 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + rtkgsw: rtkgsw@0 { + compatible = "mediatek,rtk-gsw"; + mediatek,ethsys = <ðsys>; + mediatek,mdio = <&mdio>; + mediatek,reset-pin = <&pio 54 0>; + status = "okay"; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&slot0 { + mt7615@0,0 { + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x5000>; + ieee80211-freq-limit = <5490000 6000000>; + }; +}; + +&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_pins>; + status = "okay"; +}; + +&slot1 { + mt7615@0,0 { + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x10000>; + ieee80211-freq-limit = <5000000 5490000>; + }; +}; + +&pio { + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + /* serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; + + epa_elna_pins: epa-elna-pins { + mux { + function = "antsel"; + groups = "antsel0", "antsel1", "antsel2", "antsel3", + "antsel4", "antsel5", "antsel6", "antsel7", + "antsel8", "antsel9", "antsel12", "antsel13", + "antsel14", "antsel15", "antsel16", "antsel17"; + }; + }; +}; + +ð { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + nvmem-cells = <&macaddr_factory_2a>; + nvmem-cell-names = "mac-address"; + phy-connection-type = "2500base-x"; + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "rgmii"; + nvmem-cells = <&macaddr_factory_24>; + nvmem-cell-names = "mac-address"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + status = "okay"; +}; + +&bch { + status = "okay"; +}; + +&snfi { + pinctrl-names = "default"; + pinctrl-0 = <&serial_nand_pins>; + status = "okay"; + flash@0 { + compatible = "spi-nand"; + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + nand-ecc-engine = <&snfi>; + mediatek,bmt-v2; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x40000>; + read-only; + }; + + partition@c0000 { + label = "u-boot"; + reg = <0xc0000 0x80000>; + read-only; + }; + + partition@140000 { + label = "u-boot-env"; + reg = <0x140000 0x80000>; + read-only; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x40000>; + read-only; + }; + + partition@200000 { + label = "ubi"; + reg = <0x200000 0x6400000>; + }; + + partition@6600000 { + label = "User_data"; + reg = <0x6600000 0x100000>; + }; + + /* size of this partition varies due to BMT & bad blocks. */ + partition@6700000 { + label = "reserved"; + reg = <0x6700000 0>; + }; + }; + }; +}; + +&factory { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_factory_24: macaddr@24 { + reg = <0x24 0x6>; + }; + + macaddr_factory_2a: macaddr@2a { + reg = <0x2a 0x6>; + }; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + pinctrl-names = "default"; + pinctrl-0 = <&epa_elna_pins>; + mediatek,mtd-eeprom = <&factory 0x0>; + status = "okay"; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr-ubootmod.dts b/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr-ubootmod.dts new file mode 100755 index 00000000..e573d309 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr-ubootmod.dts @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7622-ubnt-unifi-6-lr.dtsi" + +/ { + model = "Ubiquiti UniFi 6 LR (U-Boot mod)"; + compatible = "ubnt,unifi-6-lr-ubootmod", "mediatek,mt7622"; +}; + +&nor_partitions { + partition@0 { + label = "bl2"; + reg = <0x0 0x20000>; + }; + + partition@20000 { + label = "fip"; + reg = <0x20000 0xa0000>; + }; + + partition@c0000 { + label = "u-boot-env"; + reg = <0xc0000 0x10000>; + }; + + factory: partition@d0000 { + label = "factory"; + reg = <0xd0000 0x40000>; + read-only; + }; + + eeprom: partition@110000 { + label = "eeprom"; + reg = <0x110000 0x10000>; + read-only; + }; + + partition@120000 { + label = "recovery"; + reg = <0x120000 0xee0000>; + }; + + partition@1000000 { + compatible = "denx,fit"; + label = "firmware"; + reg = <0x1000000 0x3000000>; + }; +}; + +&wmac { + mediatek,mtd-eeprom = <&factory 0x0>; + nvmem-cells = <&macaddr_eeprom_0>; + nvmem-cell-names = "mac-address"; + status = "okay"; +}; + +&slot0 { + wifi@0,0 { + reg = <0x0 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x20000>; + nvmem-cells = <&macaddr_eeprom_6>; + nvmem-cell-names = "mac-address"; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&gmac0 { + nvmem-cells = <&macaddr_eeprom_0>; + nvmem-cell-names = "mac-address"; +}; + +&eeprom { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_eeprom_0: macaddr@0 { + reg = <0x0 0x6>; + }; + + macaddr_eeprom_6: macaddr@6 { + reg = <0x6 0x6>; + }; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dts b/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dts new file mode 100755 index 00000000..9b676b43 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dts @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "mt7622-ubnt-unifi-6-lr.dtsi" + +/ { + model = "Ubiquiti UniFi 6 LR"; + compatible = "ubnt,unifi-6-lr", "mediatek,mt7622"; +}; + +&nor_partitions { + partition@0 { + label = "preloader"; + reg = <0x0 0x40000>; + }; + + partition@40000 { + label = "atf"; + reg = <0x40000 0x20000>; + }; + + partition@60000 { + label = "u-boot"; + reg = <0x60000 0x60000>; + }; + + partition@c0000 { + label = "u-boot-env"; + reg = <0xc0000 0x10000>; + }; + + factory: partition@d0000 { + label = "factory"; + reg = <0xd0000 0x40000>; + read-only; + }; + + eeprom: partition@110000 { + label = "eeprom"; + reg = <0x110000 0x10000>; + read-only; + }; + + partition@120000 { + label = "bs"; + reg = <0x120000 0x10000>; + }; + + partition@130000 { + label = "cfg"; + reg = <0x130000 0x100000>; + read-only; + }; + + partition@230000 { + compatible = "denx,fit"; + label = "firmware"; + reg = <0x230000 0x1ee0000>; + }; + + partition@2110000 { + label = "kernel1"; + reg = <0x2110000 0x1ee0000>; + }; +}; + +&wmac { + mediatek,mtd-eeprom = <&factory 0x0>; + nvmem-cells = <&macaddr_eeprom_0>; + nvmem-cell-names = "mac-address"; + status = "okay"; +}; + +&slot0 { + wifi@0,0 { + reg = <0x0 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x20000>; + nvmem-cells = <&macaddr_eeprom_6>; + nvmem-cell-names = "mac-address"; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&gmac0 { + nvmem-cells = <&macaddr_eeprom_0>; + nvmem-cell-names = "mac-address"; +}; + +&eeprom { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_eeprom_0: macaddr@0 { + reg = <0x0 0x6>; + }; + + macaddr_eeprom_6: macaddr@6 { + reg = <0x6 0x6>; + }; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dtsi b/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dtsi new file mode 100755 index 00000000..ae587a11 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-ubnt-unifi-6-lr.dtsi @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +/dts-v1/; +#include +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + aliases { + led-boot = &led_blue; + led-failsafe = &led_blue; + led-running = &led_blue; + led-upgrade = &led_blue; + label-mac-device = &gmac0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512 console=ttyS0,115200n8"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&pio 62 GPIO_ACTIVE_LOW>; + }; + }; + + memory { + reg = <0 0x40000000 0 0x3f000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + + +&pio { + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + spi_nor_pins: spi-nor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + uart3_pins: uart3-pins { + mux { + function = "uart"; + groups = "uart3_1_tx_rx" ; + }; + }; + + i2c0_pins: i2c0-pins { + mux { + function = "i2c"; + groups = "i2c0"; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&bch { + status = "okay"; +}; + +&btif { + status = "disabled"; +}; + +ð { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + + phy-mode = "2500base-x"; + phy-handle = <&phy0>; + phy-connection-type = "2500base-x"; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@8 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x8>; + }; + }; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + + status = "okay"; +}; + +&nor_flash { + pinctrl-names = "default"; + pinctrl-0 = <&spi_nor_pins>; + + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + + nor_partitions: partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + }; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + status = "okay"; + + /* MT7915 Bluetooth */ +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "okay"; + + led-controller@30 { + compatible = "ubnt,ledbar"; + reg = <0x30>; + + enable-gpio = <&pio 59 0>; + + red { + label = "red"; + }; + + green { + label = "green"; + }; + + led_blue: blue { + label = "blue"; + }; + }; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; diff --git a/root/target/linux/mediatek/dts/mt7622-xiaomi-redmi-router-ax6s.dts b/root/target/linux/mediatek/dts/mt7622-xiaomi-redmi-router-ax6s.dts new file mode 100755 index 00000000..6c1208d4 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7622-xiaomi-redmi-router-ax6s.dts @@ -0,0 +1,366 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/dts-v1/; + +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "Xiaomi Redmi Router AX6S"; + compatible = "xiaomi,redmi-router-ax6s", "mediatek,mt7622"; + + aliases { + serial0 = &uart0; + led-boot = &led_power_amber; + led-failsafe = &led_power_amber; + led-running = &led_power_blue; + led-upgrade = &led_power_blue; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8 swiotlb=512"; + }; + + memory { + reg = <0 0x40000000 0 0x8000000>; + }; + + leds { + compatible = "gpio-leds"; + + led_power_blue: power_blue { + label = "blue:power"; + gpios = <&pio 18 GPIO_ACTIVE_LOW>; + }; + + led_power_amber: power_amber { + label = "amber:power"; + gpios = <&pio 17 GPIO_ACTIVE_LOW>; + }; + + led_net_blue: net_blue { + label = "blue:net"; + gpios = <&pio 01 GPIO_ACTIVE_LOW>; + }; + + led_net_amber: net_amber { + label = "amber:net"; + gpios = <&pio 16 GPIO_ACTIVE_LOW>; + }; + + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + mesh { + label = "mesh"; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + }; +}; + +&cpu0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; +}; + +&cpu1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; +}; + +&pio { + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm7_pins: pwm1-2-pins { + mux { + function = "pwm"; + groups = "pwm_ch7_2"; + }; + }; + + /* Serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + + phy-connection-type = "2500base-x"; + + nvmem-cells = <&macaddr_factory_4>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <(-1)>; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7531"; + reg = <0>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&pio>; + interrupts = <53 IRQ_TYPE_LEVEL_HIGH>; + reset-gpios = <&pio 54 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + wan: port@1 { + reg = <1>; + label = "wan"; + }; + + port@2 { + reg = <2>; + label = "lan1"; + }; + + port@3 { + reg = <3>; + label = "lan2"; + }; + + port@4 { + reg = <4>; + label = "lan3"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; + }; +}; + +&bch { + status = "okay"; +}; + +&snfi { + pinctrl-names = "default"; + pinctrl-0 = <&serial_nand_pins>; + status = "okay"; + + flash@0 { + compatible = "spi-nand"; + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + nand-ecc-engine = <&snfi>; + + mediatek,bmt-v2; + mediatek,bmt-table-size = <0x1000>; + mediatek,bmt-remap-range = <0x0 0x6c0000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x40000>; + read-only; + }; + + partition@c0000 { + label = "u-boot"; + reg = <0xc0000 0x80000>; + read-only; + }; + + partition@140000 { + label = "u-boot-env"; + reg = <0x140000 0x40000>; + }; + + partition@180000 { + label = "bdata"; + reg = <0x180000 0x40000>; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x80000>; + read-only; + + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_factory_4: macaddr@4 { + reg = <0x4 0x6>; + }; + }; + + partition@240000 { + label = "crash"; + reg = <0x240000 0x40000>; + read-only; + }; + + partition@280000 { + label = "crash_log"; + reg = <0x280000 0x40000>; + read-only; + }; + + /* Shrunk and renamed from "firmware" + * as to not break luci size checks + */ + partition@2c0000 { + label = "kernel"; + compatible = "denx,fit"; + reg = <0x2c0000 0x400000>; + }; + + /* ubi partition is the result of squashing + * consecutive stock partitions: + * - firmware (partially) + * - firmware1 + * - overlay + * - obr + */ + partition@6c0000 { + label = "ubi"; + reg = <0x6C0000 0x6f00000>; + }; + }; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&slot0 { + status = "okay"; + + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x5000>; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + status = "okay"; +}; + +&rtc { + status = "disabled"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + status = "okay"; + + mediatek,mtd-eeprom = <&factory 0x0>; +}; diff --git a/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02-emmc-512m.dts b/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02-emmc-512m.dts new file mode 100755 index 00000000..c255e9af --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02-emmc-512m.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright 2018 Kristian Evensen + */ + +/dts-v1/; +#include "mt7623a-unielec-u7623-02.dtsi" + +/ { + model = "UniElec U7623-02 eMMC (legacy loader, 512M RAM)"; + compatible = "unielec,u7623-02-emmc-512m", "unielec,u7623-02", "mediatek,mt7623"; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS0,115200 blkdevparts=mmcblk0:3M@6M(recovery),256M@9M(root) rootfstype=squashfs root=/dev/mmcblk0p2"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0 0x80000000 0 0x20000000>; + }; +}; diff --git a/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dts b/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dts new file mode 100755 index 00000000..bcd81ba6 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright 2018 Kristian Evensen + */ + +/dts-v1/; +#include "mt7623a-unielec-u7623-02.dtsi" + +/ { + model = "UniElec U7623-02 eMMC"; + compatible = "unielec,u7623-02", "mediatek,mt7623"; +}; diff --git a/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dtsi b/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dtsi new file mode 100755 index 00000000..50c7f3e8 --- /dev/null +++ b/root/target/linux/mediatek/dts/mt7623a-unielec-u7623-02.dtsi @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright 2018 Kristian Evensen + */ + +#include +#include "mt7623.dtsi" +#include "mt6323.dtsi" + +/ { + compatible = "unielec,u7623-02", "mediatek,mt7623"; + + aliases { + serial0 = &uart2; + ethernet0 = &gmac0; + mmc0 = &mmc0; + led-boot = &led3_green; + led-failsafe = &led3_green; + led-running = &led3_green; + led-upgrade = &led3_green; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@1 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@2 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@3 { + proc-supply = <&mt6323_vproc_reg>; + }; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&key_pins_a>; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 256 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_unielec>; + + led3_green: led3 { + label = "u7623-01:green:led3"; + gpios = <&pio 14 GPIO_ACTIVE_LOW>; + }; + + led4 { + label = "u7623-01:green:led4"; + gpios = <&pio 15 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&crypto { + status = "okay"; +}; + +ð { + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + mt7530: switch@0 { + compatible = "mediatek,mt7530"; + }; + }; +}; + +&mt7530 { + compatible = "mediatek,mt7530"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + pinctrl-names = "default"; + mediatek,mcm; + resets = <ðsys 2>; + reset-names = "mcm"; + core-supply = <&mt6323_vpa_reg>; + io-supply = <&mt6323_vemc3v3_reg>; + + dsa,mii-bus = <&mdio>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + port@0 { + reg = <0>; + label = "lan0"; + cpu = <&cpu_port0>; + }; + + port@1 { + reg = <1>; + label = "lan1"; + cpu = <&cpu_port0>; + }; + + port@2 { + reg = <2>; + label = "lan2"; + cpu = <&cpu_port0>; + }; + + port@3 { + reg = <3>; + label = "lan3"; + cpu = <&cpu_port0>; + }; + + port@4 { + reg = <4>; + label = "wan"; + cpu = <&cpu_port0>; + }; + + cpu_port0: port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_pins_default>; + pinctrl-1 = <&mmc0_pins_uhs>; + status = "okay"; + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + non-removable; +}; + +&pio { + key_pins_a: keys-alt { + pins-keys { + pinmux = , + ; + input-enable; + }; + }; + + led_pins_unielec: leds-unielec { + pins-leds { + pinmux = , + ; + }; + }; + + mmc0_pins_default: mmc0default { + pins_cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + bias-pull-up; + }; + + pins_clk { + pinmux = ; + bias-pull-down; + }; + + pins_rst { + pinmux = ; + bias-pull-up; + }; + }; + + mmc0_pins_uhs: mmc0 { + pins_cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + pins_clk { + pinmux = ; + drive-strength = ; + bias-pull-down = ; + }; + + pins_rst { + pinmux = ; + bias-pull-up; + }; + }; + + pcie_default: pcie_pin_default { + pins_cmd_dat { + pinmux = , + ; + bias-disable; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins_a>; + status = "okay"; +}; + +&pwrap { + mt6323 { + mt6323led: led { + compatible = "mediatek,mt6323-led"; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + label = "led0"; + }; + }; + }; +}; + +&mt6323keys { + mediatek,long-press-mode = <0>; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins_b>; + status = "okay"; +}; + +&usb1 { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_3p3v>; + status = "okay"; +}; + +&u3phy1 { + status = "okay"; +}; + +&u3phy2 { + status = "okay"; + mediatek,phy-switch = <&hifsys>; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_default>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + }; + + pcie@1,0 { + status = "okay"; + }; + + pcie@2,0 { + status = "okay"; + }; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + diff --git a/root/target/linux/mediatek/files-5.14/drivers/leds/leds-ubnt-ledbar.c b/root/target/linux/mediatek/files-5.14/drivers/leds/leds-ubnt-ledbar.c new file mode 100755 index 00000000..9c68d40e --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/leds/leds-ubnt-ledbar.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Driver for the Ubiquiti RGB LED controller (LEDBAR). + * This Controller is based on a Holtek HT32F52241 and connected + * via I2C. + * + * - The Controller needs an enable signal set to high when + * performing a transaction. On the U6-LR, this is located + * at Pin 18 (R6902) + * + * - The Pin is also printed when calling the "usetled" function + * contained in the ubntapp bootloader application. + */ + +#define UBNT_LEDBAR_MAX_BRIGHTNESS 0xff + +#define UBNT_LEDBAR_TRANSACTION_LENGTH 8 +#define UBNT_LEDBAR_TRANSACTION_SUCCESS 0xaa + +#define UBNT_LEDBAR_TRANSACTION_BLUE_IDX 2 +#define UBNT_LEDBAR_TRANSACTION_GREEN_IDX 3 +#define UBNT_LEDBAR_TRANSACTION_RED_IDX 4 + +struct ubnt_ledbar { + struct mutex lock; + struct i2c_client *client; + struct led_classdev led_red; + struct led_classdev led_green; + struct led_classdev led_blue; + struct gpio_desc *enable_gpio; +}; + +static int ubnt_ledbar_perform_transaction(struct ubnt_ledbar *ledbar, + char *transaction) +{ + int ret; + int i; + + for (i = 0; i < UBNT_LEDBAR_TRANSACTION_LENGTH; i++) + i2c_smbus_write_byte(ledbar->client, transaction[i]); + + return i2c_smbus_read_byte(ledbar->client); +} + +static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar) +{ + char setup_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11}; + char led_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00}; + char i2c_response; + int ret = 0; + + mutex_lock(&ledbar->lock); + + led_msg[UBNT_LEDBAR_TRANSACTION_BLUE_IDX] = ledbar->led_blue.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_GREEN_IDX] = ledbar->led_green.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_RED_IDX] = ledbar->led_red.brightness; + + gpiod_set_raw_value(ledbar->enable_gpio, 1); + + msleep(10); + + i2c_response = ubnt_ledbar_perform_transaction(ledbar, setup_msg); + if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { + dev_err(&ledbar->client->dev, "Error initializing LED transaction: %02x\n", ret); + ret = -EINVAL; + goto out_gpio; + } + + i2c_response = ubnt_ledbar_perform_transaction(ledbar, led_msg); + if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { + dev_err(&ledbar->client->dev, "Failed LED transaction: %02x\n", ret); + ret = -EINVAL; + goto out_gpio; + } + + msleep(10); +out_gpio: + gpiod_set_raw_value(ledbar->enable_gpio, 0); + + mutex_unlock(&ledbar->lock); + + return ret; +} + +#define UBNT_LEDBAR_CONTROL_RGBS(name) \ +static int ubnt_ledbar_set_##name##_brightness(struct led_classdev *led_cdev,\ + enum led_brightness value) \ +{ \ + struct ubnt_ledbar *ledbar = \ + container_of(led_cdev, struct ubnt_ledbar, led_##name); \ + int ret; \ + led_cdev->brightness = value; \ + ret = ubnt_ledbar_apply_state(ledbar); \ + return ret; \ +} + +UBNT_LEDBAR_CONTROL_RGBS(red); +UBNT_LEDBAR_CONTROL_RGBS(green); +UBNT_LEDBAR_CONTROL_RGBS(blue); + + +static int ubnt_ledbar_init_led(struct device_node *np, struct ubnt_ledbar *ledbar, + struct led_classdev *led_cdev) +{ + struct led_init_data init_data = {}; + int ret; + + if (!np) + return 0; + + init_data.fwnode = of_fwnode_handle(np); + + led_cdev->max_brightness = UBNT_LEDBAR_MAX_BRIGHTNESS; + + ret = devm_led_classdev_register_ext(&ledbar->client->dev, led_cdev, + &init_data); + if (ret) + dev_err(&ledbar->client->dev, "led register err: %d\n", ret); + + return ret; +} + + +static int ubnt_ledbar_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *np = client->dev.of_node; + struct ubnt_ledbar *ledbar; + int ret; + + ledbar = devm_kzalloc(&client->dev, sizeof(*ledbar), GFP_KERNEL); + if (!ledbar) + return -ENOMEM; + + ledbar->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW); + + if (IS_ERR(ledbar->enable_gpio)) { + ret = PTR_ERR(ledbar->enable_gpio); + dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret); + return ret; + } + + gpiod_direction_output(ledbar->enable_gpio, 0); + + ledbar->client = client; + + mutex_init(&ledbar->lock); + + i2c_set_clientdata(client, ledbar); + + ledbar->led_red.brightness_set_blocking = ubnt_ledbar_set_red_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "red"), ledbar, &ledbar->led_red); + + ledbar->led_green.brightness_set_blocking = ubnt_ledbar_set_green_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "green"), ledbar, &ledbar->led_green); + + ledbar->led_blue.brightness_set_blocking = ubnt_ledbar_set_blue_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "blue"), ledbar, &ledbar->led_blue); + + return ubnt_ledbar_apply_state(ledbar); +} + +static int ubnt_ledbar_remove(struct i2c_client *client) +{ + struct ubnt_ledbar *ledbar = i2c_get_clientdata(client); + + mutex_destroy(&ledbar->lock); + + return 0; +} + +static const struct i2c_device_id ubnt_ledbar_id[] = { + { "ubnt-ledbar", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ubnt_ledbar_id); + +static const struct of_device_id of_ubnt_ledbar_match[] = { + { .compatible = "ubnt,ledbar", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_ubnt_ledbar_match); + +static struct i2c_driver ubnt_ledbar_driver = { + .driver = { + .name = "ubnt-ledbar", + .of_match_table = of_ubnt_ledbar_match, + }, + .probe = ubnt_ledbar_probe, + .remove = ubnt_ledbar_remove, + .id_table = ubnt_ledbar_id, +}; +module_i2c_driver(ubnt_ledbar_driver); + +MODULE_DESCRIPTION("Ubiquiti LEDBAR driver"); +MODULE_AUTHOR("David Bauer "); +MODULE_LICENSE("GPL v2"); diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Kconfig b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Kconfig new file mode 100755 index 00000000..58aa5638 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2020 MediaTek Inc. All rights reserved. +# Author: Weijie Gao +# + +config MTK_SPI_NAND + tristate "MediaTek SPI NAND flash controller driver" + depends on MTD + default n + help + This option enables access to SPI-NAND flashes through the + MTD interface of MediaTek SPI NAND Flash Controller diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Makefile b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Makefile new file mode 100755 index 00000000..e6b37100 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2020 MediaTek Inc. All rights reserved. +# Author: Weijie Gao +# + +obj-y += mtk-snand.o mtk-snand-ecc.o mtk-snand-ids.o mtk-snand-os.o \ + mtk-snand-mtd.o + +ccflags-y += -DPRIVATE_MTK_SNAND_HEADER diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-def.h b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-def.h new file mode 100755 index 00000000..1a93d93d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-def.h @@ -0,0 +1,268 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#ifndef _MTK_SNAND_DEF_H_ +#define _MTK_SNAND_DEF_H_ + +#include "mtk-snand-os.h" + +#ifdef PRIVATE_MTK_SNAND_HEADER +#include "mtk-snand.h" +#else +#include +#endif + +struct mtk_snand_plat_dev; + +enum snand_flash_io { + SNAND_IO_1_1_1, + SNAND_IO_1_1_2, + SNAND_IO_1_2_2, + SNAND_IO_1_1_4, + SNAND_IO_1_4_4, + + __SNAND_IO_MAX +}; + +#define SPI_IO_1_1_1 BIT(SNAND_IO_1_1_1) +#define SPI_IO_1_1_2 BIT(SNAND_IO_1_1_2) +#define SPI_IO_1_2_2 BIT(SNAND_IO_1_2_2) +#define SPI_IO_1_1_4 BIT(SNAND_IO_1_1_4) +#define SPI_IO_1_4_4 BIT(SNAND_IO_1_4_4) + +struct snand_opcode { + uint8_t opcode; + uint8_t dummy; +}; + +struct snand_io_cap { + uint8_t caps; + struct snand_opcode opcodes[__SNAND_IO_MAX]; +}; + +#define SNAND_OP(_io, _opcode, _dummy) [_io] = { .opcode = (_opcode), \ + .dummy = (_dummy) } + +#define SNAND_IO_CAP(_name, _caps, ...) \ + struct snand_io_cap _name = { .caps = (_caps), \ + .opcodes = { __VA_ARGS__ } } + +#define SNAND_MAX_ID_LEN 4 + +enum snand_id_type { + SNAND_ID_DYMMY, + SNAND_ID_ADDR = SNAND_ID_DYMMY, + SNAND_ID_DIRECT, + + __SNAND_ID_TYPE_MAX +}; + +struct snand_id { + uint8_t type; /* enum snand_id_type */ + uint8_t len; + uint8_t id[SNAND_MAX_ID_LEN]; +}; + +#define SNAND_ID(_type, ...) \ + { .type = (_type), .id = { __VA_ARGS__ }, \ + .len = sizeof((uint8_t[]) { __VA_ARGS__ }) } + +struct snand_mem_org { + uint16_t pagesize; + uint16_t sparesize; + uint16_t pages_per_block; + uint16_t blocks_per_die; + uint16_t planes_per_die; + uint16_t ndies; +}; + +#define SNAND_MEMORG(_ps, _ss, _ppb, _bpd, _ppd, _nd) \ + { .pagesize = (_ps), .sparesize = (_ss), .pages_per_block = (_ppb), \ + .blocks_per_die = (_bpd), .planes_per_die = (_ppd), .ndies = (_nd) } + +typedef int (*snand_select_die_t)(struct mtk_snand *snf, uint32_t dieidx); + +struct snand_flash_info { + const char *model; + struct snand_id id; + const struct snand_mem_org memorg; + const struct snand_io_cap *cap_rd; + const struct snand_io_cap *cap_pl; + snand_select_die_t select_die; +}; + +#define SNAND_INFO(_model, _id, _memorg, _cap_rd, _cap_pl, ...) \ + { .model = (_model), .id = _id, .memorg = _memorg, \ + .cap_rd = (_cap_rd), .cap_pl = (_cap_pl), __VA_ARGS__ } + +const struct snand_flash_info *snand_flash_id_lookup(enum snand_id_type type, + const uint8_t *id); + +struct mtk_snand_soc_data { + uint16_t sector_size; + uint16_t max_sectors; + uint16_t fdm_size; + uint16_t fdm_ecc_size; + uint16_t fifo_size; + + bool bbm_swap; + bool empty_page_check; + uint32_t mastersta_mask; + + const uint8_t *spare_sizes; + uint32_t num_spare_size; +}; + +enum mtk_ecc_regs { + ECC_DECDONE, +}; + +struct mtk_ecc_soc_data { + const uint8_t *ecc_caps; + uint32_t num_ecc_cap; + const uint32_t *regs; + uint16_t mode_shift; + uint8_t errnum_bits; + uint8_t errnum_shift; +}; + +struct mtk_snand { + struct mtk_snand_plat_dev *pdev; + + void __iomem *nfi_base; + void __iomem *ecc_base; + + enum mtk_snand_soc soc; + const struct mtk_snand_soc_data *nfi_soc; + const struct mtk_ecc_soc_data *ecc_soc; + bool snfi_quad_spi; + bool quad_spi_op; + + const char *model; + uint64_t size; + uint64_t die_size; + uint32_t erasesize; + uint32_t writesize; + uint32_t oobsize; + + uint32_t num_dies; + snand_select_die_t select_die; + + uint8_t opcode_rfc; + uint8_t opcode_pl; + uint8_t dummy_rfc; + uint8_t mode_rfc; + uint8_t mode_pl; + + uint32_t writesize_mask; + uint32_t writesize_shift; + uint32_t erasesize_mask; + uint32_t erasesize_shift; + uint64_t die_mask; + uint32_t die_shift; + + uint32_t spare_per_sector; + uint32_t raw_sector_size; + uint32_t ecc_strength; + uint32_t ecc_steps; + uint32_t ecc_bytes; + uint32_t ecc_parity_bits; + + uint8_t *page_cache; /* Used by read/write page */ + uint8_t *buf_cache; /* Used by block bad/markbad & auto_oob */ + int *sect_bf; /* Used by ECC correction */ +}; + +enum mtk_snand_log_category { + SNAND_LOG_NFI, + SNAND_LOG_SNFI, + SNAND_LOG_ECC, + SNAND_LOG_CHIP, + + __SNAND_LOG_CAT_MAX +}; + +int mtk_ecc_setup(struct mtk_snand *snf, void *fmdaddr, uint32_t max_ecc_bytes, + uint32_t msg_size); +int mtk_snand_ecc_encoder_start(struct mtk_snand *snf); +void mtk_snand_ecc_encoder_stop(struct mtk_snand *snf); +int mtk_snand_ecc_decoder_start(struct mtk_snand *snf); +void mtk_snand_ecc_decoder_stop(struct mtk_snand *snf); +int mtk_ecc_wait_decoder_done(struct mtk_snand *snf); +int mtk_ecc_check_decode_error(struct mtk_snand *snf); +int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect); + +int mtk_snand_mac_io(struct mtk_snand *snf, const uint8_t *out, uint32_t outlen, + uint8_t *in, uint32_t inlen); +int mtk_snand_set_feature(struct mtk_snand *snf, uint32_t addr, uint32_t val); + +int mtk_snand_log(struct mtk_snand_plat_dev *pdev, + enum mtk_snand_log_category cat, const char *fmt, ...); + +#define snand_log_nfi(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_NFI, fmt, ##__VA_ARGS__) + +#define snand_log_snfi(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_SNFI, fmt, ##__VA_ARGS__) + +#define snand_log_ecc(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_ECC, fmt, ##__VA_ARGS__) + +#define snand_log_chip(pdev, fmt, ...) \ + mtk_snand_log(pdev, SNAND_LOG_CHIP, fmt, ##__VA_ARGS__) + +/* ffs64 */ +static inline int mtk_snand_ffs64(uint64_t x) +{ + if (!x) + return 0; + + if (!(x & 0xffffffff)) + return ffs((uint32_t)(x >> 32)) + 32; + + return ffs((uint32_t)(x & 0xffffffff)); +} + +/* NFI dummy commands */ +#define NFI_CMD_DUMMY_READ 0x00 +#define NFI_CMD_DUMMY_WRITE 0x80 + +/* SPI-NAND opcodes */ +#define SNAND_CMD_RESET 0xff +#define SNAND_CMD_BLOCK_ERASE 0xd8 +#define SNAND_CMD_READ_FROM_CACHE_QUAD 0xeb +#define SNAND_CMD_WINBOND_SELECT_DIE 0xc2 +#define SNAND_CMD_READ_FROM_CACHE_DUAL 0xbb +#define SNAND_CMD_READID 0x9f +#define SNAND_CMD_READ_FROM_CACHE_X4 0x6b +#define SNAND_CMD_READ_FROM_CACHE_X2 0x3b +#define SNAND_CMD_PROGRAM_LOAD_X4 0x32 +#define SNAND_CMD_SET_FEATURE 0x1f +#define SNAND_CMD_READ_TO_CACHE 0x13 +#define SNAND_CMD_PROGRAM_EXECUTE 0x10 +#define SNAND_CMD_GET_FEATURE 0x0f +#define SNAND_CMD_READ_FROM_CACHE 0x0b +#define SNAND_CMD_WRITE_ENABLE 0x06 +#define SNAND_CMD_PROGRAM_LOAD 0x02 + +/* SPI-NAND feature addresses */ +#define SNAND_FEATURE_MICRON_DIE_ADDR 0xd0 +#define SNAND_MICRON_DIE_SEL_1 BIT(6) + +#define SNAND_FEATURE_STATUS_ADDR 0xc0 +#define SNAND_STATUS_OIP BIT(0) +#define SNAND_STATUS_WEL BIT(1) +#define SNAND_STATUS_ERASE_FAIL BIT(2) +#define SNAND_STATUS_PROGRAM_FAIL BIT(3) + +#define SNAND_FEATURE_CONFIG_ADDR 0xb0 +#define SNAND_FEATURE_QUAD_ENABLE BIT(0) +#define SNAND_FEATURE_ECC_EN BIT(4) + +#define SNAND_FEATURE_PROTECT_ADDR 0xa0 + +#endif /* _MTK_SNAND_DEF_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ecc.c b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ecc.c new file mode 100755 index 00000000..6dd0f346 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ecc.c @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#include "mtk-snand-def.h" + +/* ECC registers */ +#define ECC_ENCCON 0x000 +#define ENC_EN BIT(0) + +#define ECC_ENCCNFG 0x004 +#define ENC_MS_S 16 +#define ENC_BURST_EN BIT(8) +#define ENC_TNUM_S 0 + +#define ECC_ENCIDLE 0x00c +#define ENC_IDLE BIT(0) + +#define ECC_DECCON 0x100 +#define DEC_EN BIT(0) + +#define ECC_DECCNFG 0x104 +#define DEC_EMPTY_EN BIT(31) +#define DEC_CS_S 16 +#define DEC_CON_S 12 +#define DEC_CON_CORRECT 3 +#define DEC_BURST_EN BIT(8) +#define DEC_TNUM_S 0 + +#define ECC_DECIDLE 0x10c +#define DEC_IDLE BIT(0) + +#define ECC_DECENUM0 0x114 +#define ECC_DECENUM(n) (ECC_DECENUM0 + (n) * 4) + +/* ECC_ENCIDLE & ECC_DECIDLE */ +#define ECC_IDLE BIT(0) + +/* ENC_MODE & DEC_MODE */ +#define ECC_MODE_NFI 1 + +#define ECC_TIMEOUT 500000 + +static const uint8_t mt7622_ecc_caps[] = { 4, 6, 8, 10, 12 }; + +static const uint32_t mt7622_ecc_regs[] = { + [ECC_DECDONE] = 0x11c, +}; + +static const struct mtk_ecc_soc_data mtk_ecc_socs[__SNAND_SOC_MAX] = { + [SNAND_SOC_MT7622] = { + .ecc_caps = mt7622_ecc_caps, + .num_ecc_cap = ARRAY_SIZE(mt7622_ecc_caps), + .regs = mt7622_ecc_regs, + .mode_shift = 4, + .errnum_bits = 5, + .errnum_shift = 5, + }, + [SNAND_SOC_MT7629] = { + .ecc_caps = mt7622_ecc_caps, + .num_ecc_cap = ARRAY_SIZE(mt7622_ecc_caps), + .regs = mt7622_ecc_regs, + .mode_shift = 4, + .errnum_bits = 5, + .errnum_shift = 5, + }, +}; + +static inline uint32_t ecc_read32(struct mtk_snand *snf, uint32_t reg) +{ + return readl(snf->ecc_base + reg); +} + +static inline void ecc_write32(struct mtk_snand *snf, uint32_t reg, + uint32_t val) +{ + writel(val, snf->ecc_base + reg); +} + +static inline void ecc_write16(struct mtk_snand *snf, uint32_t reg, + uint16_t val) +{ + writew(val, snf->ecc_base + reg); +} + +static int mtk_ecc_poll(struct mtk_snand *snf, uint32_t reg, uint32_t bits) +{ + uint32_t val; + + return read16_poll_timeout(snf->ecc_base + reg, val, (val & bits), 0, + ECC_TIMEOUT); +} + +static int mtk_ecc_wait_idle(struct mtk_snand *snf, uint32_t reg) +{ + int ret; + + ret = mtk_ecc_poll(snf, reg, ECC_IDLE); + if (ret) { + snand_log_ecc(snf->pdev, "ECC engine is busy\n"); + return -EBUSY; + } + + return 0; +} + +int mtk_ecc_setup(struct mtk_snand *snf, void *fmdaddr, uint32_t max_ecc_bytes, + uint32_t msg_size) +{ + uint32_t i, val, ecc_msg_bits, ecc_strength; + int ret; + + snf->ecc_soc = &mtk_ecc_socs[snf->soc]; + + snf->ecc_parity_bits = fls(1 + 8 * msg_size); + ecc_strength = max_ecc_bytes * 8 / snf->ecc_parity_bits; + + for (i = snf->ecc_soc->num_ecc_cap - 1; i >= 0; i--) { + if (snf->ecc_soc->ecc_caps[i] <= ecc_strength) + break; + } + + if (unlikely(i < 0)) { + snand_log_ecc(snf->pdev, "Page size %u+%u is not supported\n", + snf->writesize, snf->oobsize); + return -ENOTSUPP; + } + + snf->ecc_strength = snf->ecc_soc->ecc_caps[i]; + snf->ecc_bytes = DIV_ROUND_UP(snf->ecc_strength * snf->ecc_parity_bits, + 8); + + /* Encoder config */ + ecc_write16(snf, ECC_ENCCON, 0); + ret = mtk_ecc_wait_idle(snf, ECC_ENCIDLE); + if (ret) + return ret; + + ecc_msg_bits = msg_size * 8; + val = (ecc_msg_bits << ENC_MS_S) | + (ECC_MODE_NFI << snf->ecc_soc->mode_shift) | i; + ecc_write32(snf, ECC_ENCCNFG, val); + + /* Decoder config */ + ecc_write16(snf, ECC_DECCON, 0); + ret = mtk_ecc_wait_idle(snf, ECC_DECIDLE); + if (ret) + return ret; + + ecc_msg_bits += snf->ecc_strength * snf->ecc_parity_bits; + val = DEC_EMPTY_EN | (ecc_msg_bits << DEC_CS_S) | + (DEC_CON_CORRECT << DEC_CON_S) | + (ECC_MODE_NFI << snf->ecc_soc->mode_shift) | i; + ecc_write32(snf, ECC_DECCNFG, val); + + return 0; +} + +int mtk_snand_ecc_encoder_start(struct mtk_snand *snf) +{ + int ret; + + ret = mtk_ecc_wait_idle(snf, ECC_ENCIDLE); + if (ret) { + ecc_write16(snf, ECC_ENCCON, 0); + mtk_ecc_wait_idle(snf, ECC_ENCIDLE); + } + + ecc_write16(snf, ECC_ENCCON, ENC_EN); + + return 0; +} + +void mtk_snand_ecc_encoder_stop(struct mtk_snand *snf) +{ + mtk_ecc_wait_idle(snf, ECC_ENCIDLE); + ecc_write16(snf, ECC_ENCCON, 0); +} + +int mtk_snand_ecc_decoder_start(struct mtk_snand *snf) +{ + int ret; + + ret = mtk_ecc_wait_idle(snf, ECC_DECIDLE); + if (ret) { + ecc_write16(snf, ECC_DECCON, 0); + mtk_ecc_wait_idle(snf, ECC_DECIDLE); + } + + ecc_write16(snf, ECC_DECCON, DEC_EN); + + return 0; +} + +void mtk_snand_ecc_decoder_stop(struct mtk_snand *snf) +{ + mtk_ecc_wait_idle(snf, ECC_DECIDLE); + ecc_write16(snf, ECC_DECCON, 0); +} + +int mtk_ecc_wait_decoder_done(struct mtk_snand *snf) +{ + uint16_t val, step_mask = (1 << snf->ecc_steps) - 1; + uint32_t reg = snf->ecc_soc->regs[ECC_DECDONE]; + int ret; + + ret = read16_poll_timeout(snf->ecc_base + reg, val, + (val & step_mask) == step_mask, 0, + ECC_TIMEOUT); + if (ret) + snand_log_ecc(snf->pdev, "ECC decoder is busy\n"); + + return ret; +} + +int mtk_ecc_check_decode_error(struct mtk_snand *snf) +{ + uint32_t i, regi, fi, errnum; + uint32_t errnum_shift = snf->ecc_soc->errnum_shift; + uint32_t errnum_mask = (1 << snf->ecc_soc->errnum_bits) - 1; + int ret = 0; + + for (i = 0; i < snf->ecc_steps; i++) { + regi = i / 4; + fi = i % 4; + + errnum = ecc_read32(snf, ECC_DECENUM(regi)); + errnum = (errnum >> (fi * errnum_shift)) & errnum_mask; + + if (errnum <= snf->ecc_strength) { + snf->sect_bf[i] = errnum; + } else { + snf->sect_bf[i] = -1; + ret = -EBADMSG; + } + } + + return ret; +} + +static int mtk_ecc_check_buf_bitflips(struct mtk_snand *snf, const void *buf, + size_t len, uint32_t bitflips) +{ + const uint8_t *buf8 = buf; + const uint32_t *buf32; + uint32_t d, weight; + + while (len && ((uintptr_t)buf8) % sizeof(uint32_t)) { + weight = hweight8(*buf8); + bitflips += BITS_PER_BYTE - weight; + buf8++; + len--; + + if (bitflips > snf->ecc_strength) + return -EBADMSG; + } + + buf32 = (const uint32_t *)buf8; + while (len >= sizeof(uint32_t)) { + d = *buf32; + + if (d != ~0) { + weight = hweight32(d); + bitflips += sizeof(uint32_t) * BITS_PER_BYTE - weight; + } + + buf32++; + len -= sizeof(uint32_t); + + if (bitflips > snf->ecc_strength) + return -EBADMSG; + } + + buf8 = (const uint8_t *)buf32; + while (len) { + weight = hweight8(*buf8); + bitflips += BITS_PER_BYTE - weight; + buf8++; + len--; + + if (bitflips > snf->ecc_strength) + return -EBADMSG; + } + + return bitflips; +} + +static int mtk_ecc_check_parity_bitflips(struct mtk_snand *snf, const void *buf, + uint32_t bits, uint32_t bitflips) +{ + uint32_t len, i; + uint8_t b; + int rc; + + len = bits >> 3; + bits &= 7; + + rc = mtk_ecc_check_buf_bitflips(snf, buf, len, bitflips); + if (!bits || rc < 0) + return rc; + + bitflips = rc; + + /* We want a precise count of bits */ + b = ((const uint8_t *)buf)[len]; + for (i = 0; i < bits; i++) { + if (!(b & BIT(i))) + bitflips++; + } + + if (bitflips > snf->ecc_strength) + return -EBADMSG; + + return bitflips; +} + +static void mtk_ecc_reset_parity(void *buf, uint32_t bits) +{ + uint32_t len; + + len = bits >> 3; + bits &= 7; + + memset(buf, 0xff, len); + + /* Only reset bits protected by ECC to 1 */ + if (bits) + ((uint8_t *)buf)[len] |= GENMASK(bits - 1, 0); +} + +int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect) +{ + uint32_t ecc_bytes = snf->spare_per_sector - snf->nfi_soc->fdm_size; + uint8_t *oob = snf->page_cache + snf->writesize; + uint8_t *data_ptr, *fdm_ptr, *ecc_ptr; + int bitflips = 0, ecc_bits, parity_bits; + + parity_bits = fls(snf->nfi_soc->sector_size * 8); + ecc_bits = snf->ecc_strength * parity_bits; + + data_ptr = snf->page_cache + sect * snf->nfi_soc->sector_size; + fdm_ptr = oob + sect * snf->nfi_soc->fdm_size; + ecc_ptr = oob + snf->ecc_steps * snf->nfi_soc->fdm_size + + sect * ecc_bytes; + + /* + * Check whether DATA + FDM + ECC of a sector contains correctable + * bitflips + */ + bitflips = mtk_ecc_check_buf_bitflips(snf, data_ptr, + snf->nfi_soc->sector_size, + bitflips); + if (bitflips < 0) + return -EBADMSG; + + bitflips = mtk_ecc_check_buf_bitflips(snf, fdm_ptr, + snf->nfi_soc->fdm_ecc_size, + bitflips); + if (bitflips < 0) + return -EBADMSG; + + bitflips = mtk_ecc_check_parity_bitflips(snf, ecc_ptr, ecc_bits, + bitflips); + if (bitflips < 0) + return -EBADMSG; + + if (!bitflips) + return 0; + + /* Reset the data of this sector to 0xff */ + memset(data_ptr, 0xff, snf->nfi_soc->sector_size); + memset(fdm_ptr, 0xff, snf->nfi_soc->fdm_ecc_size); + mtk_ecc_reset_parity(ecc_ptr, ecc_bits); + + return bitflips; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ids.c b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ids.c new file mode 100755 index 00000000..1756ff7e --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-ids.c @@ -0,0 +1,511 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#include "mtk-snand-def.h" + +static int mtk_snand_winbond_select_die(struct mtk_snand *snf, uint32_t dieidx); +static int mtk_snand_micron_select_die(struct mtk_snand *snf, uint32_t dieidx); + +#define SNAND_MEMORG_512M_2K_64 SNAND_MEMORG(2048, 64, 64, 512, 1, 1) +#define SNAND_MEMORG_1G_2K_64 SNAND_MEMORG(2048, 64, 64, 1024, 1, 1) +#define SNAND_MEMORG_2G_2K_64 SNAND_MEMORG(2048, 64, 64, 2048, 1, 1) +#define SNAND_MEMORG_2G_2K_120 SNAND_MEMORG(2048, 120, 64, 2048, 1, 1) +#define SNAND_MEMORG_4G_2K_64 SNAND_MEMORG(2048, 64, 64, 4096, 1, 1) +#define SNAND_MEMORG_1G_2K_120 SNAND_MEMORG(2048, 120, 64, 1024, 1, 1) +#define SNAND_MEMORG_1G_2K_128 SNAND_MEMORG(2048, 128, 64, 1024, 1, 1) +#define SNAND_MEMORG_2G_2K_128 SNAND_MEMORG(2048, 128, 64, 2048, 1, 1) +#define SNAND_MEMORG_4G_2K_128 SNAND_MEMORG(2048, 128, 64, 4096, 1, 1) +#define SNAND_MEMORG_4G_4K_240 SNAND_MEMORG(4096, 240, 64, 2048, 1, 1) +#define SNAND_MEMORG_4G_4K_256 SNAND_MEMORG(4096, 256, 64, 2048, 1, 1) +#define SNAND_MEMORG_8G_4K_256 SNAND_MEMORG(4096, 256, 64, 4096, 1, 1) +#define SNAND_MEMORG_2G_2K_64_2P SNAND_MEMORG(2048, 64, 64, 2048, 2, 1) +#define SNAND_MEMORG_2G_2K_64_2D SNAND_MEMORG(2048, 64, 64, 1024, 1, 2) +#define SNAND_MEMORG_2G_2K_128_2P SNAND_MEMORG(2048, 128, 64, 2048, 2, 1) +#define SNAND_MEMORG_4G_2K_64_2P SNAND_MEMORG(2048, 64, 64, 4096, 2, 1) +#define SNAND_MEMORG_4G_2K_128_2P_2D SNAND_MEMORG(2048, 128, 64, 2048, 2, 2) +#define SNAND_MEMORG_8G_4K_256_2D SNAND_MEMORG(4096, 256, 64, 2048, 1, 2) + +static const SNAND_IO_CAP(snand_cap_read_from_cache_quad, + SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_2_2 | SPI_IO_1_1_4 | + SPI_IO_1_4_4, + SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8), + SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8), + SNAND_OP(SNAND_IO_1_2_2, SNAND_CMD_READ_FROM_CACHE_DUAL, 4), + SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8), + SNAND_OP(SNAND_IO_1_4_4, SNAND_CMD_READ_FROM_CACHE_QUAD, 4)); + +static const SNAND_IO_CAP(snand_cap_read_from_cache_quad_q2d, + SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_2_2 | SPI_IO_1_1_4 | + SPI_IO_1_4_4, + SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8), + SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8), + SNAND_OP(SNAND_IO_1_2_2, SNAND_CMD_READ_FROM_CACHE_DUAL, 4), + SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8), + SNAND_OP(SNAND_IO_1_4_4, SNAND_CMD_READ_FROM_CACHE_QUAD, 2)); + +static const SNAND_IO_CAP(snand_cap_read_from_cache_quad_a8d, + SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_2_2 | SPI_IO_1_1_4 | + SPI_IO_1_4_4, + SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8), + SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8), + SNAND_OP(SNAND_IO_1_2_2, SNAND_CMD_READ_FROM_CACHE_DUAL, 8), + SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8), + SNAND_OP(SNAND_IO_1_4_4, SNAND_CMD_READ_FROM_CACHE_QUAD, 8)); + +static const SNAND_IO_CAP(snand_cap_read_from_cache_x4, + SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_1_4, + SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8), + SNAND_OP(SNAND_IO_1_1_2, SNAND_CMD_READ_FROM_CACHE_X2, 8), + SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8)); + +static const SNAND_IO_CAP(snand_cap_read_from_cache_x4_only, + SPI_IO_1_1_1 | SPI_IO_1_1_4, + SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_READ_FROM_CACHE, 8), + SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_READ_FROM_CACHE_X4, 8)); + +static const SNAND_IO_CAP(snand_cap_program_load_x1, + SPI_IO_1_1_1, + SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_PROGRAM_LOAD, 0)); + +static const SNAND_IO_CAP(snand_cap_program_load_x4, + SPI_IO_1_1_1 | SPI_IO_1_1_4, + SNAND_OP(SNAND_IO_1_1_1, SNAND_CMD_PROGRAM_LOAD, 0), + SNAND_OP(SNAND_IO_1_1_4, SNAND_CMD_PROGRAM_LOAD_X4, 0)); + +static const struct snand_flash_info snand_flash_ids[] = { + SNAND_INFO("W25N512GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x20), + SNAND_MEMORG_512M_2K_64, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("W25N01GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x21), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("W25M02GV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xab, 0x21), + SNAND_MEMORG_2G_2K_64_2D, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4, + mtk_snand_winbond_select_die), + SNAND_INFO("W25N02KV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x22), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + + SNAND_INFO("GD5F1GQ4UAWxx", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0x10), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F1GQ4UExIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd1), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F1GQ4UExxH", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd9), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F1GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf1), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F2GQ4UExIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd2), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F2GQ5UExxH", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0x32), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_a8d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F2GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf2), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F4GQ4UBxIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xd4), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F4GQ4xAYIG", SNAND_ID(SNAND_ID_ADDR, 0xc8, 0xf4), + SNAND_MEMORG_4G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F2GQ5UExxG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x52), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("GD5F4GQ4UCxIG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0xb4), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + + SNAND_INFO("MX35LF1GE4AB", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x12), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("MX35LF1G24AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x14), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("MX31LF1GE4BC", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x1e), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("MX35LF2GE4AB", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x22), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("MX35LF2G24AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x24), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("MX35LF2GE4AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x26), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("MX35LF2G14AC", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x20), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("MX35LF4G24AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x35), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("MX35LF4GE4AD", SNAND_ID(SNAND_ID_DYMMY, 0xc2, 0x37), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + + SNAND_INFO("MT29F1G01AAADD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x12), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x1), + SNAND_INFO("MT29F1G01ABAFD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x14), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("MT29F2G01AAAED", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x9f), + SNAND_MEMORG_2G_2K_64_2P, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x1), + SNAND_INFO("MT29F2G01ABAGD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x24), + SNAND_MEMORG_2G_2K_128_2P, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("MT29F4G01AAADD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x32), + SNAND_MEMORG_4G_2K_64_2P, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x1), + SNAND_INFO("MT29F4G01ABAFD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x34), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("MT29F4G01ADAGD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x36), + SNAND_MEMORG_4G_2K_128_2P_2D, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4, + mtk_snand_micron_select_die), + SNAND_INFO("MT29F8G01ADAFD", SNAND_ID(SNAND_ID_DYMMY, 0x2c, 0x46), + SNAND_MEMORG_8G_4K_256_2D, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4, + mtk_snand_micron_select_die), + + SNAND_INFO("TC58CVG0S3HRAIG", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xc2), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x1), + SNAND_INFO("TC58CVG1S3HRAIG", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xcb), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x1), + SNAND_INFO("TC58CVG2S0HRAIG", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xcd), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x1), + SNAND_INFO("TC58CVG0S3HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xe2), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("TC58CVG1S3HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xeb), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("TC58CVG2S0HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xed), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("TH58CVG3S0HRAIJ", SNAND_ID(SNAND_ID_DYMMY, 0x98, 0xe4), + SNAND_MEMORG_8G_4K_256, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + + SNAND_INFO("F50L512M41A", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x20), + SNAND_MEMORG_512M_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("F50L1G41A", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x21), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + SNAND_INFO("F50L1G41LB", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x01), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4), + SNAND_INFO("F50L2G41LB", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x0a), + SNAND_MEMORG_2G_2K_64_2D, + &snand_cap_read_from_cache_quad, + &snand_cap_program_load_x4, + mtk_snand_winbond_select_die), + + SNAND_INFO("CS11G0T0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x00), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("CS11G0G0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x10), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("CS11G0S0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x20), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("CS11G1T0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x01), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("CS11G1S0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x21), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("CS11G2T0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x02), + SNAND_MEMORG_4G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("CS11G2S0A0AA", SNAND_ID(SNAND_ID_DYMMY, 0x6b, 0x22), + SNAND_MEMORG_4G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + + SNAND_INFO("EM73B044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x01), + SNAND_MEMORG_512M_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044SNB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x11), + SNAND_MEMORG_1G_2K_120, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044SNF", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x09), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x18), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x19), + SNAND_MEMORG(2048, 64, 128, 512, 1, 1), + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044VCD", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1c), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1d), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1e), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044VCC", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x22), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044VCF", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x25), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044SNC", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x31), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044SNC", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0a), + SNAND_MEMORG_2G_2K_120, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x12), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044SNF", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x10), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x13), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x14), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCD", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x17), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCH", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1b), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1d), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCG", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x1f), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCE", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x20), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCL", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2e), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044SNB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x32), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73E044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x03), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73E044SND", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0b), + SNAND_MEMORG_4G_4K_240, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73E044SNB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x23), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73E044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2c), + SNAND_MEMORG_4G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73E044VCB", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2f), + SNAND_MEMORG_4G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73F044SNA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x24), + SNAND_MEMORG_8G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73F044VCA", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x2d), + SNAND_MEMORG_8G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73E044SNE", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0e), + SNAND_MEMORG_8G_4K_256, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73C044SNG", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0c), + SNAND_MEMORG_1G_2K_120, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("EM73D044VCN", SNAND_ID(SNAND_ID_DYMMY, 0xd5, 0x0f), + SNAND_MEMORG_2G_2K_64, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + + SNAND_INFO("FM35Q1GA", SNAND_ID(SNAND_ID_DYMMY, 0xe5, 0x71), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + + SNAND_INFO("PN26G01A", SNAND_ID(SNAND_ID_DYMMY, 0xa1, 0xe1), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("PN26G02A", SNAND_ID(SNAND_ID_DYMMY, 0xa1, 0xe2), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + + SNAND_INFO("IS37SML01G1", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x21), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4, + &snand_cap_program_load_x4), + + SNAND_INFO("ATO25D1GA", SNAND_ID(SNAND_ID_DYMMY, 0x9b, 0x12), + SNAND_MEMORG_1G_2K_64, + &snand_cap_read_from_cache_x4_only, + &snand_cap_program_load_x4), + + SNAND_INFO("HYF1GQ4U", SNAND_ID(SNAND_ID_DYMMY, 0xc9, 0x51), + SNAND_MEMORG_1G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), + SNAND_INFO("HYF2GQ4U", SNAND_ID(SNAND_ID_DYMMY, 0xc9, 0x52), + SNAND_MEMORG_2G_2K_128, + &snand_cap_read_from_cache_quad_q2d, + &snand_cap_program_load_x4), +}; + +static int mtk_snand_winbond_select_die(struct mtk_snand *snf, uint32_t dieidx) +{ + uint8_t op[2]; + + if (dieidx > 1) { + snand_log_chip(snf->pdev, "Invalid die index %u\n", dieidx); + return -EINVAL; + } + + op[0] = SNAND_CMD_WINBOND_SELECT_DIE; + op[1] = (uint8_t)dieidx; + + return mtk_snand_mac_io(snf, op, sizeof(op), NULL, 0); +} + +static int mtk_snand_micron_select_die(struct mtk_snand *snf, uint32_t dieidx) +{ + int ret; + + if (dieidx > 1) { + snand_log_chip(snf->pdev, "Invalid die index %u\n", dieidx); + return -EINVAL; + } + + ret = mtk_snand_set_feature(snf, SNAND_FEATURE_MICRON_DIE_ADDR, + SNAND_MICRON_DIE_SEL_1); + if (ret) { + snand_log_chip(snf->pdev, + "Failed to set die selection feature\n"); + return ret; + } + + return 0; +} + +const struct snand_flash_info *snand_flash_id_lookup(enum snand_id_type type, + const uint8_t *id) +{ + const struct snand_id *fid; + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(snand_flash_ids); i++) { + if (snand_flash_ids[i].id.type != type) + continue; + + fid = &snand_flash_ids[i].id; + if (memcmp(fid->id, id, fid->len)) + continue; + + return &snand_flash_ids[i]; + } + + return NULL; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-mtd.c b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-mtd.c new file mode 100755 index 00000000..7e5baf03 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-mtd.c @@ -0,0 +1,681 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mtk-snand.h" +#include "mtk-snand-os.h" + +struct mtk_snand_of_id { + enum mtk_snand_soc soc; +}; + +struct mtk_snand_mtd { + struct mtk_snand_plat_dev pdev; + + struct clk *nfi_clk; + struct clk *pad_clk; + struct clk *ecc_clk; + + void __iomem *nfi_regs; + void __iomem *ecc_regs; + + int irq; + + bool quad_spi; + enum mtk_snand_soc soc; + + struct mtd_info mtd; + struct mtk_snand *snf; + struct mtk_snand_chip_info cinfo; + uint8_t *page_cache; + struct mutex lock; +}; + +#define mtd_to_msm(mtd) container_of(mtd, struct mtk_snand_mtd, mtd) + +static int mtk_snand_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + struct mtk_snand_mtd *msm = mtd_to_msm(mtd); + u64 start_addr, end_addr; + int ret; + + /* Do not allow write past end of device */ + if ((instr->addr + instr->len) > msm->cinfo.chipsize) { + dev_err(msm->pdev.dev, + "attempt to erase beyond end of device\n"); + return -EINVAL; + } + + start_addr = instr->addr & (~mtd->erasesize_mask); + end_addr = instr->addr + instr->len; + if (end_addr & mtd->erasesize_mask) { + end_addr = (end_addr + mtd->erasesize_mask) & + (~mtd->erasesize_mask); + } + + mutex_lock(&msm->lock); + + while (start_addr < end_addr) { + if (mtk_snand_block_isbad(msm->snf, start_addr)) { + instr->fail_addr = start_addr; + ret = -EIO; + break; + } + + ret = mtk_snand_erase_block(msm->snf, start_addr); + if (ret) { + instr->fail_addr = start_addr; + break; + } + + start_addr += mtd->erasesize; + } + + mutex_unlock(&msm->lock); + + return ret; +} + +static int mtk_snand_mtd_read_data(struct mtk_snand_mtd *msm, uint64_t addr, + struct mtd_oob_ops *ops) +{ + struct mtd_info *mtd = &msm->mtd; + size_t len, ooblen, maxooblen, chklen; + uint32_t col, ooboffs; + uint8_t *datcache, *oobcache; + bool ecc_failed = false, raw = ops->mode == MTD_OPS_RAW ? true : false; + int ret, max_bitflips = 0; + + col = addr & mtd->writesize_mask; + addr &= ~mtd->writesize_mask; + maxooblen = mtd_oobavail(mtd, ops); + ooboffs = ops->ooboffs; + ooblen = ops->ooblen; + len = ops->len; + + datcache = len ? msm->page_cache : NULL; + oobcache = ooblen ? msm->page_cache + mtd->writesize : NULL; + + ops->oobretlen = 0; + ops->retlen = 0; + + while (len || ooblen) { + if (ops->mode == MTD_OPS_AUTO_OOB) + ret = mtk_snand_read_page_auto_oob(msm->snf, addr, + datcache, oobcache, maxooblen, NULL, raw); + else + ret = mtk_snand_read_page(msm->snf, addr, datcache, + oobcache, raw); + + if (ret < 0 && ret != -EBADMSG) + return ret; + + if (ret == -EBADMSG) { + mtd->ecc_stats.failed++; + ecc_failed = true; + } else { + mtd->ecc_stats.corrected += ret; + max_bitflips = max_t(int, ret, max_bitflips); + } + + if (len) { + /* Move data */ + chklen = mtd->writesize - col; + if (chklen > len) + chklen = len; + + memcpy(ops->datbuf + ops->retlen, datcache + col, + chklen); + len -= chklen; + col = 0; /* (col + chklen) % */ + ops->retlen += chklen; + } + + if (ooblen) { + /* Move oob */ + chklen = maxooblen - ooboffs; + if (chklen > ooblen) + chklen = ooblen; + + memcpy(ops->oobbuf + ops->oobretlen, oobcache + ooboffs, + chklen); + ooblen -= chklen; + ooboffs = 0; /* (ooboffs + chklen) % maxooblen; */ + ops->oobretlen += chklen; + } + + addr += mtd->writesize; + } + + return ecc_failed ? -EBADMSG : max_bitflips; +} + +static int mtk_snand_mtd_read_oob(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) +{ + struct mtk_snand_mtd *msm = mtd_to_msm(mtd); + uint32_t maxooblen; + int ret; + + if (!ops->oobbuf && !ops->datbuf) { + if (ops->ooblen || ops->len) + return -EINVAL; + + return 0; + } + + switch (ops->mode) { + case MTD_OPS_PLACE_OOB: + case MTD_OPS_AUTO_OOB: + case MTD_OPS_RAW: + break; + default: + dev_err(msm->pdev.dev, "unsupported oob mode: %u\n", ops->mode); + return -EINVAL; + } + + maxooblen = mtd_oobavail(mtd, ops); + + /* Do not allow read past end of device */ + if (ops->datbuf && (from + ops->len) > msm->cinfo.chipsize) { + dev_err(msm->pdev.dev, + "attempt to read beyond end of device\n"); + return -EINVAL; + } + + if (unlikely(ops->ooboffs >= maxooblen)) { + dev_err(msm->pdev.dev, "attempt to start read outside oob\n"); + return -EINVAL; + } + + if (unlikely(from >= msm->cinfo.chipsize || + ops->ooboffs + ops->ooblen > + ((msm->cinfo.chipsize >> mtd->writesize_shift) - + (from >> mtd->writesize_shift)) * + maxooblen)) { + dev_err(msm->pdev.dev, + "attempt to read beyond end of device\n"); + return -EINVAL; + } + + mutex_lock(&msm->lock); + ret = mtk_snand_mtd_read_data(msm, from, ops); + mutex_unlock(&msm->lock); + + return ret; +} + +static int mtk_snand_mtd_write_data(struct mtk_snand_mtd *msm, uint64_t addr, + struct mtd_oob_ops *ops) +{ + struct mtd_info *mtd = &msm->mtd; + size_t len, ooblen, maxooblen, chklen, oobwrlen; + uint32_t col, ooboffs; + uint8_t *datcache, *oobcache; + bool raw = ops->mode == MTD_OPS_RAW ? true : false; + int ret; + + col = addr & mtd->writesize_mask; + addr &= ~mtd->writesize_mask; + maxooblen = mtd_oobavail(mtd, ops); + ooboffs = ops->ooboffs; + ooblen = ops->ooblen; + len = ops->len; + + datcache = len ? msm->page_cache : NULL; + oobcache = ooblen ? msm->page_cache + mtd->writesize : NULL; + + ops->oobretlen = 0; + ops->retlen = 0; + + while (len || ooblen) { + if (len) { + /* Move data */ + chklen = mtd->writesize - col; + if (chklen > len) + chklen = len; + + memset(datcache, 0xff, col); + memcpy(datcache + col, ops->datbuf + ops->retlen, + chklen); + memset(datcache + col + chklen, 0xff, + mtd->writesize - col - chklen); + len -= chklen; + col = 0; /* (col + chklen) % */ + ops->retlen += chklen; + } + + oobwrlen = 0; + if (ooblen) { + /* Move oob */ + chklen = maxooblen - ooboffs; + if (chklen > ooblen) + chklen = ooblen; + + memset(oobcache, 0xff, ooboffs); + memcpy(oobcache + ooboffs, + ops->oobbuf + ops->oobretlen, chklen); + memset(oobcache + ooboffs + chklen, 0xff, + mtd->oobsize - ooboffs - chklen); + oobwrlen = chklen + ooboffs; + ooblen -= chklen; + ooboffs = 0; /* (ooboffs + chklen) % maxooblen; */ + ops->oobretlen += chklen; + } + + if (ops->mode == MTD_OPS_AUTO_OOB) + ret = mtk_snand_write_page_auto_oob(msm->snf, addr, + datcache, oobcache, oobwrlen, NULL, raw); + else + ret = mtk_snand_write_page(msm->snf, addr, datcache, + oobcache, raw); + + if (ret) + return ret; + + addr += mtd->writesize; + } + + return 0; +} + +static int mtk_snand_mtd_write_oob(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) +{ + struct mtk_snand_mtd *msm = mtd_to_msm(mtd); + uint32_t maxooblen; + int ret; + + if (!ops->oobbuf && !ops->datbuf) { + if (ops->ooblen || ops->len) + return -EINVAL; + + return 0; + } + + switch (ops->mode) { + case MTD_OPS_PLACE_OOB: + case MTD_OPS_AUTO_OOB: + case MTD_OPS_RAW: + break; + default: + dev_err(msm->pdev.dev, "unsupported oob mode: %u\n", ops->mode); + return -EINVAL; + } + + maxooblen = mtd_oobavail(mtd, ops); + + /* Do not allow write past end of device */ + if (ops->datbuf && (to + ops->len) > msm->cinfo.chipsize) { + dev_err(msm->pdev.dev, + "attempt to write beyond end of device\n"); + return -EINVAL; + } + + if (unlikely(ops->ooboffs >= maxooblen)) { + dev_err(msm->pdev.dev, + "attempt to start write outside oob\n"); + return -EINVAL; + } + + if (unlikely(to >= msm->cinfo.chipsize || + ops->ooboffs + ops->ooblen > + ((msm->cinfo.chipsize >> mtd->writesize_shift) - + (to >> mtd->writesize_shift)) * + maxooblen)) { + dev_err(msm->pdev.dev, + "attempt to write beyond end of device\n"); + return -EINVAL; + } + + mutex_lock(&msm->lock); + ret = mtk_snand_mtd_write_data(msm, to, ops); + mutex_unlock(&msm->lock); + + return ret; +} + +static int mtk_snand_mtd_block_isbad(struct mtd_info *mtd, loff_t offs) +{ + struct mtk_snand_mtd *msm = mtd_to_msm(mtd); + int ret; + + mutex_lock(&msm->lock); + ret = mtk_snand_block_isbad(msm->snf, offs); + mutex_unlock(&msm->lock); + + return ret; +} + +static int mtk_snand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs) +{ + struct mtk_snand_mtd *msm = mtd_to_msm(mtd); + int ret; + + mutex_lock(&msm->lock); + ret = mtk_snand_block_markbad(msm->snf, offs); + mutex_unlock(&msm->lock); + + return ret; +} + +static int mtk_snand_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobecc) +{ + struct mtk_snand_mtd *msm = mtd_to_msm(mtd); + + if (section) + return -ERANGE; + + oobecc->offset = msm->cinfo.fdm_size * msm->cinfo.num_sectors; + oobecc->length = mtd->oobsize - oobecc->offset; + + return 0; +} + +static int mtk_snand_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobfree) +{ + struct mtk_snand_mtd *msm = mtd_to_msm(mtd); + + if (section >= msm->cinfo.num_sectors) + return -ERANGE; + + oobfree->length = msm->cinfo.fdm_size - 1; + oobfree->offset = section * msm->cinfo.fdm_size + 1; + + return 0; +} + +static irqreturn_t mtk_snand_irq(int irq, void *id) +{ + struct mtk_snand_mtd *msm = id; + int ret; + + ret = mtk_snand_irq_process(msm->snf); + if (ret > 0) + return IRQ_HANDLED; + + return IRQ_NONE; +} + +static int mtk_snand_enable_clk(struct mtk_snand_mtd *msm) +{ + int ret; + + ret = clk_prepare_enable(msm->nfi_clk); + if (ret) { + dev_err(msm->pdev.dev, "unable to enable nfi clk\n"); + return ret; + } + + ret = clk_prepare_enable(msm->pad_clk); + if (ret) { + dev_err(msm->pdev.dev, "unable to enable pad clk\n"); + clk_disable_unprepare(msm->nfi_clk); + return ret; + } + + ret = clk_prepare_enable(msm->ecc_clk); + if (ret) { + dev_err(msm->pdev.dev, "unable to enable ecc clk\n"); + clk_disable_unprepare(msm->nfi_clk); + clk_disable_unprepare(msm->pad_clk); + return ret; + } + + return 0; +} + +static void mtk_snand_disable_clk(struct mtk_snand_mtd *msm) +{ + clk_disable_unprepare(msm->nfi_clk); + clk_disable_unprepare(msm->pad_clk); + clk_disable_unprepare(msm->ecc_clk); +} + +static const struct mtd_ooblayout_ops mtk_snand_ooblayout = { + .ecc = mtk_snand_ooblayout_ecc, + .free = mtk_snand_ooblayout_free, +}; + +static struct mtk_snand_of_id mt7622_soc_id = { .soc = SNAND_SOC_MT7622 }; +static struct mtk_snand_of_id mt7629_soc_id = { .soc = SNAND_SOC_MT7629 }; + +static const struct of_device_id mtk_snand_ids[] = { + { .compatible = "mediatek,mt7622-snand", .data = &mt7622_soc_id }, + { .compatible = "mediatek,mt7629-snand", .data = &mt7629_soc_id }, + { }, +}; + +MODULE_DEVICE_TABLE(of, mtk_snand_ids); + +static int mtk_snand_probe(struct platform_device *pdev) +{ + struct mtk_snand_platdata mtk_snand_pdata = {}; + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *of_soc_id; + const struct mtk_snand_of_id *soc_id; + struct mtk_snand_mtd *msm; + struct mtd_info *mtd; + struct resource *r; + uint32_t size; + int ret; + + of_soc_id = of_match_node(mtk_snand_ids, np); + if (!of_soc_id) + return -EINVAL; + + soc_id = of_soc_id->data; + + msm = devm_kzalloc(&pdev->dev, sizeof(*msm), GFP_KERNEL); + if (!msm) + return -ENOMEM; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi"); + msm->nfi_regs = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(msm->nfi_regs)) { + ret = PTR_ERR(msm->nfi_regs); + goto errout1; + } + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecc"); + msm->ecc_regs = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(msm->ecc_regs)) { + ret = PTR_ERR(msm->ecc_regs); + goto errout1; + } + + msm->pdev.dev = &pdev->dev; + msm->quad_spi = of_property_read_bool(np, "mediatek,quad-spi"); + msm->soc = soc_id->soc; + + msm->nfi_clk = devm_clk_get(msm->pdev.dev, "nfi_clk"); + if (IS_ERR(msm->nfi_clk)) { + ret = PTR_ERR(msm->nfi_clk); + dev_err(msm->pdev.dev, "unable to get nfi_clk, err = %d\n", + ret); + goto errout1; + } + + msm->ecc_clk = devm_clk_get(msm->pdev.dev, "ecc_clk"); + if (IS_ERR(msm->ecc_clk)) { + ret = PTR_ERR(msm->ecc_clk); + dev_err(msm->pdev.dev, "unable to get ecc_clk, err = %d\n", + ret); + goto errout1; + } + + msm->pad_clk = devm_clk_get(msm->pdev.dev, "pad_clk"); + if (IS_ERR(msm->pad_clk)) { + ret = PTR_ERR(msm->pad_clk); + dev_err(msm->pdev.dev, "unable to get pad_clk, err = %d\n", + ret); + goto errout1; + } + + ret = mtk_snand_enable_clk(msm); + if (ret) + goto errout1; + + /* Probe SPI-NAND Flash */ + mtk_snand_pdata.soc = msm->soc; + mtk_snand_pdata.quad_spi = msm->quad_spi; + mtk_snand_pdata.nfi_base = msm->nfi_regs; + mtk_snand_pdata.ecc_base = msm->ecc_regs; + + ret = mtk_snand_init(&msm->pdev, &mtk_snand_pdata, &msm->snf); + if (ret) + goto errout1; + + msm->irq = platform_get_irq(pdev, 0); + if (msm->irq >= 0) { + ret = devm_request_irq(msm->pdev.dev, msm->irq, mtk_snand_irq, + 0x0, "mtk-snand", msm); + if (ret) { + dev_err(msm->pdev.dev, "failed to request snfi irq\n"); + goto errout2; + } + + ret = dma_set_mask(msm->pdev.dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(msm->pdev.dev, "failed to set dma mask\n"); + goto errout3; + } + } + + mtk_snand_get_chip_info(msm->snf, &msm->cinfo); + + size = msm->cinfo.pagesize + msm->cinfo.sparesize; + msm->page_cache = devm_kmalloc(msm->pdev.dev, size, GFP_KERNEL); + if (!msm->page_cache) { + dev_err(msm->pdev.dev, "failed to allocate page cache\n"); + ret = -ENOMEM; + goto errout3; + } + + mutex_init(&msm->lock); + + dev_info(msm->pdev.dev, + "chip is %s, size %lluMB, page size %u, oob size %u\n", + msm->cinfo.model, msm->cinfo.chipsize >> 20, + msm->cinfo.pagesize, msm->cinfo.sparesize); + + /* Initialize mtd for SPI-NAND */ + mtd = &msm->mtd; + + mtd->owner = THIS_MODULE; + mtd->dev.parent = &pdev->dev; + mtd->type = MTD_NANDFLASH; + mtd->flags = MTD_CAP_NANDFLASH; + + mtd_set_of_node(mtd, np); + + mtd->size = msm->cinfo.chipsize; + mtd->erasesize = msm->cinfo.blocksize; + mtd->writesize = msm->cinfo.pagesize; + mtd->writebufsize = mtd->writesize; + mtd->oobsize = msm->cinfo.sparesize; + mtd->oobavail = msm->cinfo.num_sectors * (msm->cinfo.fdm_size - 1); + + mtd->erasesize_shift = ffs(mtd->erasesize) - 1; + mtd->writesize_shift = ffs(mtd->writesize) - 1; + mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1; + mtd->writesize_mask = (1 << mtd->writesize_shift) - 1; + + mtd->ooblayout = &mtk_snand_ooblayout; + + mtd->ecc_strength = msm->cinfo.ecc_strength; + mtd->bitflip_threshold = (mtd->ecc_strength * 3) / 4; + mtd->ecc_step_size = msm->cinfo.sector_size; + + mtd->_erase = mtk_snand_mtd_erase; + mtd->_read_oob = mtk_snand_mtd_read_oob; + mtd->_write_oob = mtk_snand_mtd_write_oob; + mtd->_block_isbad = mtk_snand_mtd_block_isbad; + mtd->_block_markbad = mtk_snand_mtd_block_markbad; + + ret = mtd_device_register(mtd, NULL, 0); + if (ret) { + dev_err(msm->pdev.dev, "failed to register mtd partition\n"); + goto errout4; + } + + platform_set_drvdata(pdev, msm); + + return 0; + +errout4: + devm_kfree(msm->pdev.dev, msm->page_cache); + +errout3: + if (msm->irq >= 0) + devm_free_irq(msm->pdev.dev, msm->irq, msm); + +errout2: + mtk_snand_cleanup(msm->snf); + +errout1: + devm_kfree(msm->pdev.dev, msm); + + platform_set_drvdata(pdev, NULL); + + return ret; +} + +static int mtk_snand_remove(struct platform_device *pdev) +{ + struct mtk_snand_mtd *msm = platform_get_drvdata(pdev); + struct mtd_info *mtd = &msm->mtd; + int ret; + + ret = mtd_device_unregister(mtd); + if (ret) + return ret; + + mtk_snand_cleanup(msm->snf); + + if (msm->irq >= 0) + devm_free_irq(msm->pdev.dev, msm->irq, msm); + + mtk_snand_disable_clk(msm); + + devm_kfree(msm->pdev.dev, msm->page_cache); + devm_kfree(msm->pdev.dev, msm); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver mtk_snand_driver = { + .probe = mtk_snand_probe, + .remove = mtk_snand_remove, + .driver = { + .name = "mtk-snand", + .of_match_table = mtk_snand_ids, + }, +}; + +module_platform_driver(mtk_snand_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Weijie Gao "); +MODULE_DESCRIPTION("MeidaTek SPI-NAND Flash Controller Driver"); diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.c b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.c new file mode 100755 index 00000000..0c3ffec8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#include "mtk-snand-def.h" + +int mtk_snand_log(struct mtk_snand_plat_dev *pdev, + enum mtk_snand_log_category cat, const char *fmt, ...) +{ + const char *catname = ""; + va_list ap; + char *msg; + + switch (cat) { + case SNAND_LOG_NFI: + catname = "NFI"; + break; + case SNAND_LOG_SNFI: + catname = "SNFI"; + break; + case SNAND_LOG_ECC: + catname = "ECC"; + break; + default: + break; + } + + va_start(ap, fmt); + msg = kvasprintf(GFP_KERNEL, fmt, ap); + va_end(ap); + + if (!msg) { + dev_warn(pdev->dev, "unable to print log\n"); + return -1; + } + + if (*catname) + dev_warn(pdev->dev, "%s: %s", catname, msg); + else + dev_warn(pdev->dev, "%s", msg); + + kfree(msg); + + return 0; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.h b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.h new file mode 100755 index 00000000..eeeb83b5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand-os.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#ifndef _MTK_SNAND_OS_H_ +#define _MTK_SNAND_OS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mtk_snand_plat_dev { + struct device *dev; + struct completion done; +}; + +/* Polling helpers */ +#define read16_poll_timeout(addr, val, cond, sleep_us, timeout_us) \ + readw_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us)) + +#define read32_poll_timeout(addr, val, cond, sleep_us, timeout_us) \ + readl_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us)) + +/* Timer helpers */ +#define mtk_snand_time_t ktime_t + +static inline mtk_snand_time_t timer_get_ticks(void) +{ + return ktime_get(); +} + +static inline mtk_snand_time_t timer_time_to_tick(uint32_t timeout_us) +{ + return ktime_add_us(ktime_set(0, 0), timeout_us); +} + +static inline bool timer_is_timeout(mtk_snand_time_t start_tick, + mtk_snand_time_t timeout_tick) +{ + ktime_t tmo = ktime_add(start_tick, timeout_tick); + + return ktime_compare(ktime_get(), tmo) > 0; +} + +/* Memory helpers */ +static inline void *generic_mem_alloc(struct mtk_snand_plat_dev *pdev, + size_t size) +{ + return devm_kzalloc(pdev->dev, size, GFP_KERNEL); +} +static inline void generic_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr) +{ + devm_kfree(pdev->dev, ptr); +} + +static inline void *dma_mem_alloc(struct mtk_snand_plat_dev *pdev, size_t size) +{ + return kzalloc(size, GFP_KERNEL); +} +static inline void dma_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr) +{ + kfree(ptr); +} + +static inline int dma_mem_map(struct mtk_snand_plat_dev *pdev, void *vaddr, + uintptr_t *dma_addr, size_t size, bool to_device) +{ + dma_addr_t addr; + int ret; + + addr = dma_map_single(pdev->dev, vaddr, size, + to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + ret = dma_mapping_error(pdev->dev, addr); + if (ret) + return ret; + + *dma_addr = (uintptr_t)addr; + + return 0; +} + +static inline void dma_mem_unmap(struct mtk_snand_plat_dev *pdev, + uintptr_t dma_addr, size_t size, + bool to_device) +{ + dma_unmap_single(pdev->dev, dma_addr, size, + to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE); +} + +/* Interrupt helpers */ +static inline void irq_completion_done(struct mtk_snand_plat_dev *pdev) +{ + complete(&pdev->done); +} + +static inline void irq_completion_init(struct mtk_snand_plat_dev *pdev) +{ + init_completion(&pdev->done); +} + +static inline int irq_completion_wait(struct mtk_snand_plat_dev *pdev, + void __iomem *reg, uint32_t bit, + uint32_t timeout_us) +{ + int ret; + + ret = wait_for_completion_timeout(&pdev->done, + usecs_to_jiffies(timeout_us)); + if (!ret) + return -ETIMEDOUT; + + return 0; +} + +#endif /* _MTK_SNAND_OS_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.c b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.c new file mode 100755 index 00000000..729fd82d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.c @@ -0,0 +1,1862 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#include "mtk-snand-def.h" + +/* NFI registers */ +#define NFI_CNFG 0x000 +#define CNFG_OP_MODE_S 12 +#define CNFG_OP_MODE_CUST 6 +#define CNFG_OP_MODE_PROGRAM 3 +#define CNFG_AUTO_FMT_EN BIT(9) +#define CNFG_HW_ECC_EN BIT(8) +#define CNFG_DMA_BURST_EN BIT(2) +#define CNFG_READ_MODE BIT(1) +#define CNFG_DMA_MODE BIT(0) + +#define NFI_PAGEFMT 0x0004 +#define NFI_SPARE_SIZE_LS_S 16 +#define NFI_FDM_ECC_NUM_S 12 +#define NFI_FDM_NUM_S 8 +#define NFI_SPARE_SIZE_S 4 +#define NFI_SEC_SEL_512 BIT(2) +#define NFI_PAGE_SIZE_S 0 +#define NFI_PAGE_SIZE_512_2K 0 +#define NFI_PAGE_SIZE_2K_4K 1 +#define NFI_PAGE_SIZE_4K_8K 2 +#define NFI_PAGE_SIZE_8K_16K 3 + +#define NFI_CON 0x008 +#define CON_SEC_NUM_S 12 +#define CON_BWR BIT(9) +#define CON_BRD BIT(8) +#define CON_NFI_RST BIT(1) +#define CON_FIFO_FLUSH BIT(0) + +#define NFI_INTR_EN 0x010 +#define NFI_INTR_STA 0x014 +#define NFI_IRQ_INTR_EN BIT(31) +#define NFI_IRQ_CUS_READ BIT(8) +#define NFI_IRQ_CUS_PG BIT(7) + +#define NFI_CMD 0x020 + +#define NFI_STRDATA 0x040 +#define STR_DATA BIT(0) + +#define NFI_STA 0x060 +#define NFI_NAND_FSM GENMASK(28, 24) +#define NFI_FSM GENMASK(19, 16) +#define READ_EMPTY BIT(12) + +#define NFI_FIFOSTA 0x064 +#define FIFO_WR_REMAIN_S 8 +#define FIFO_RD_REMAIN_S 0 + +#define NFI_ADDRCNTR 0x070 +#define SEC_CNTR GENMASK(16, 12) +#define SEC_CNTR_S 12 +#define NFI_SEC_CNTR(val) (((val) & SEC_CNTR) >> SEC_CNTR_S) + +#define NFI_STRADDR 0x080 + +#define NFI_BYTELEN 0x084 +#define BUS_SEC_CNTR(val) (((val) & SEC_CNTR) >> SEC_CNTR_S) + +#define NFI_FDM0L 0x0a0 +#define NFI_FDM0M 0x0a4 +#define NFI_FDML(n) (NFI_FDM0L + (n) * 8) +#define NFI_FDMM(n) (NFI_FDM0M + (n) * 8) + +#define NFI_DEBUG_CON1 0x220 +#define WBUF_EN BIT(2) + +#define NFI_MASTERSTA 0x224 +#define MAS_ADDR GENMASK(11, 9) +#define MAS_RD GENMASK(8, 6) +#define MAS_WR GENMASK(5, 3) +#define MAS_RDDLY GENMASK(2, 0) +#define NFI_MASTERSTA_MASK_7622 (MAS_ADDR | MAS_RD | MAS_WR | MAS_RDDLY) + +/* SNFI registers */ +#define SNF_MAC_CTL 0x500 +#define MAC_XIO_SEL BIT(4) +#define SF_MAC_EN BIT(3) +#define SF_TRIG BIT(2) +#define WIP_READY BIT(1) +#define WIP BIT(0) + +#define SNF_MAC_OUTL 0x504 +#define SNF_MAC_INL 0x508 + +#define SNF_RD_CTL2 0x510 +#define DATA_READ_DUMMY_S 8 +#define DATA_READ_CMD_S 0 + +#define SNF_RD_CTL3 0x514 + +#define SNF_PG_CTL1 0x524 +#define PG_LOAD_CMD_S 8 + +#define SNF_PG_CTL2 0x528 + +#define SNF_MISC_CTL 0x538 +#define SW_RST BIT(28) +#define FIFO_RD_LTC_S 25 +#define PG_LOAD_X4_EN BIT(20) +#define DATA_READ_MODE_S 16 +#define DATA_READ_MODE GENMASK(18, 16) +#define DATA_READ_MODE_X1 0 +#define DATA_READ_MODE_X2 1 +#define DATA_READ_MODE_X4 2 +#define DATA_READ_MODE_DUAL 5 +#define DATA_READ_MODE_QUAD 6 +#define PG_LOAD_CUSTOM_EN BIT(7) +#define DATARD_CUSTOM_EN BIT(6) +#define CS_DESELECT_CYC_S 0 + +#define SNF_MISC_CTL2 0x53c +#define PROGRAM_LOAD_BYTE_NUM_S 16 +#define READ_DATA_BYTE_NUM_S 11 + +#define SNF_DLY_CTL3 0x548 +#define SFCK_SAM_DLY_S 0 + +#define SNF_STA_CTL1 0x550 +#define CUS_PG_DONE BIT(28) +#define CUS_READ_DONE BIT(27) +#define SPI_STATE_S 0 +#define SPI_STATE GENMASK(3, 0) + +#define SNF_CFG 0x55c +#define SPI_MODE BIT(0) + +#define SNF_GPRAM 0x800 +#define SNF_GPRAM_SIZE 0xa0 + +#define SNFI_POLL_INTERVAL 1000000 + +static const uint8_t mt7622_spare_sizes[] = { 16, 26, 27, 28 }; + +static const struct mtk_snand_soc_data mtk_snand_socs[__SNAND_SOC_MAX] = { + [SNAND_SOC_MT7622] = { + .sector_size = 512, + .max_sectors = 8, + .fdm_size = 8, + .fdm_ecc_size = 1, + .fifo_size = 32, + .bbm_swap = false, + .empty_page_check = false, + .mastersta_mask = NFI_MASTERSTA_MASK_7622, + .spare_sizes = mt7622_spare_sizes, + .num_spare_size = ARRAY_SIZE(mt7622_spare_sizes) + }, + [SNAND_SOC_MT7629] = { + .sector_size = 512, + .max_sectors = 8, + .fdm_size = 8, + .fdm_ecc_size = 1, + .fifo_size = 32, + .bbm_swap = true, + .empty_page_check = false, + .mastersta_mask = NFI_MASTERSTA_MASK_7622, + .spare_sizes = mt7622_spare_sizes, + .num_spare_size = ARRAY_SIZE(mt7622_spare_sizes) + }, +}; + +static inline uint32_t nfi_read32(struct mtk_snand *snf, uint32_t reg) +{ + return readl(snf->nfi_base + reg); +} + +static inline void nfi_write32(struct mtk_snand *snf, uint32_t reg, + uint32_t val) +{ + writel(val, snf->nfi_base + reg); +} + +static inline void nfi_write16(struct mtk_snand *snf, uint32_t reg, + uint16_t val) +{ + writew(val, snf->nfi_base + reg); +} + +static inline void nfi_rmw32(struct mtk_snand *snf, uint32_t reg, uint32_t clr, + uint32_t set) +{ + uint32_t val; + + val = readl(snf->nfi_base + reg); + val &= ~clr; + val |= set; + writel(val, snf->nfi_base + reg); +} + +static void nfi_write_data(struct mtk_snand *snf, uint32_t reg, + const uint8_t *data, uint32_t len) +{ + uint32_t i, val = 0, es = sizeof(uint32_t); + + for (i = reg; i < reg + len; i++) { + val |= ((uint32_t)*data++) << (8 * (i % es)); + + if (i % es == es - 1 || i == reg + len - 1) { + nfi_write32(snf, i & ~(es - 1), val); + val = 0; + } + } +} + +static void nfi_read_data(struct mtk_snand *snf, uint32_t reg, uint8_t *data, + uint32_t len) +{ + uint32_t i, val = 0, es = sizeof(uint32_t); + + for (i = reg; i < reg + len; i++) { + if (i == reg || i % es == 0) + val = nfi_read32(snf, i & ~(es - 1)); + + *data++ = (uint8_t)(val >> (8 * (i % es))); + } +} + +static inline void do_bm_swap(uint8_t *bm1, uint8_t *bm2) +{ + uint8_t tmp = *bm1; + *bm1 = *bm2; + *bm2 = tmp; +} + +static void mtk_snand_bm_swap_raw(struct mtk_snand *snf) +{ + uint32_t fdm_bbm_pos; + + if (!snf->nfi_soc->bbm_swap || snf->ecc_steps == 1) + return; + + fdm_bbm_pos = (snf->ecc_steps - 1) * snf->raw_sector_size + + snf->nfi_soc->sector_size; + do_bm_swap(&snf->page_cache[fdm_bbm_pos], + &snf->page_cache[snf->writesize]); +} + +static void mtk_snand_bm_swap(struct mtk_snand *snf) +{ + uint32_t buf_bbm_pos, fdm_bbm_pos; + + if (!snf->nfi_soc->bbm_swap || snf->ecc_steps == 1) + return; + + buf_bbm_pos = snf->writesize - + (snf->ecc_steps - 1) * snf->spare_per_sector; + fdm_bbm_pos = snf->writesize + + (snf->ecc_steps - 1) * snf->nfi_soc->fdm_size; + do_bm_swap(&snf->page_cache[fdm_bbm_pos], + &snf->page_cache[buf_bbm_pos]); +} + +static void mtk_snand_fdm_bm_swap_raw(struct mtk_snand *snf) +{ + uint32_t fdm_bbm_pos1, fdm_bbm_pos2; + + if (!snf->nfi_soc->bbm_swap || snf->ecc_steps == 1) + return; + + fdm_bbm_pos1 = snf->nfi_soc->sector_size; + fdm_bbm_pos2 = (snf->ecc_steps - 1) * snf->raw_sector_size + + snf->nfi_soc->sector_size; + do_bm_swap(&snf->page_cache[fdm_bbm_pos1], + &snf->page_cache[fdm_bbm_pos2]); +} + +static void mtk_snand_fdm_bm_swap(struct mtk_snand *snf) +{ + uint32_t fdm_bbm_pos1, fdm_bbm_pos2; + + if (!snf->nfi_soc->bbm_swap || snf->ecc_steps == 1) + return; + + fdm_bbm_pos1 = snf->writesize; + fdm_bbm_pos2 = snf->writesize + + (snf->ecc_steps - 1) * snf->nfi_soc->fdm_size; + do_bm_swap(&snf->page_cache[fdm_bbm_pos1], + &snf->page_cache[fdm_bbm_pos2]); +} + +static int mtk_nfi_reset(struct mtk_snand *snf) +{ + uint32_t val, fifo_mask; + int ret; + + nfi_write32(snf, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST); + + ret = read16_poll_timeout(snf->nfi_base + NFI_MASTERSTA, val, + !(val & snf->nfi_soc->mastersta_mask), 0, + SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, + "NFI master is still busy after reset\n"); + return ret; + } + + ret = read32_poll_timeout(snf->nfi_base + NFI_STA, val, + !(val & (NFI_FSM | NFI_NAND_FSM)), 0, + SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, "Failed to reset NFI\n"); + return ret; + } + + fifo_mask = ((snf->nfi_soc->fifo_size - 1) << FIFO_RD_REMAIN_S) | + ((snf->nfi_soc->fifo_size - 1) << FIFO_WR_REMAIN_S); + ret = read16_poll_timeout(snf->nfi_base + NFI_FIFOSTA, val, + !(val & fifo_mask), 0, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, "NFI FIFOs are not empty\n"); + return ret; + } + + return 0; +} + +static int mtk_snand_mac_reset(struct mtk_snand *snf) +{ + int ret; + uint32_t val; + + nfi_rmw32(snf, SNF_MISC_CTL, 0, SW_RST); + + ret = read32_poll_timeout(snf->nfi_base + SNF_STA_CTL1, val, + !(val & SPI_STATE), 0, SNFI_POLL_INTERVAL); + if (ret) + snand_log_snfi(snf->pdev, "Failed to reset SNFI MAC\n"); + + nfi_write32(snf, SNF_MISC_CTL, (2 << FIFO_RD_LTC_S) | + (10 << CS_DESELECT_CYC_S)); + + return ret; +} + +static int mtk_snand_mac_trigger(struct mtk_snand *snf, uint32_t outlen, + uint32_t inlen) +{ + int ret; + uint32_t val; + + nfi_write32(snf, SNF_MAC_CTL, SF_MAC_EN); + nfi_write32(snf, SNF_MAC_OUTL, outlen); + nfi_write32(snf, SNF_MAC_INL, inlen); + + nfi_write32(snf, SNF_MAC_CTL, SF_MAC_EN | SF_TRIG); + + ret = read32_poll_timeout(snf->nfi_base + SNF_MAC_CTL, val, + val & WIP_READY, 0, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_snfi(snf->pdev, "Timed out waiting for WIP_READY\n"); + goto cleanup; + } + + ret = read32_poll_timeout(snf->nfi_base + SNF_MAC_CTL, val, + !(val & WIP), 0, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_snfi(snf->pdev, + "Timed out waiting for WIP cleared\n"); + } + +cleanup: + nfi_write32(snf, SNF_MAC_CTL, 0); + + return ret; +} + +int mtk_snand_mac_io(struct mtk_snand *snf, const uint8_t *out, uint32_t outlen, + uint8_t *in, uint32_t inlen) +{ + int ret; + + if (outlen + inlen > SNF_GPRAM_SIZE) + return -EINVAL; + + mtk_snand_mac_reset(snf); + + nfi_write_data(snf, SNF_GPRAM, out, outlen); + + ret = mtk_snand_mac_trigger(snf, outlen, inlen); + if (ret) + return ret; + + if (!inlen) + return 0; + + nfi_read_data(snf, SNF_GPRAM + outlen, in, inlen); + + return 0; +} + +static int mtk_snand_get_feature(struct mtk_snand *snf, uint32_t addr) +{ + uint8_t op[2], val; + int ret; + + op[0] = SNAND_CMD_GET_FEATURE; + op[1] = (uint8_t)addr; + + ret = mtk_snand_mac_io(snf, op, sizeof(op), &val, 1); + if (ret) + return ret; + + return val; +} + +int mtk_snand_set_feature(struct mtk_snand *snf, uint32_t addr, uint32_t val) +{ + uint8_t op[3]; + + op[0] = SNAND_CMD_SET_FEATURE; + op[1] = (uint8_t)addr; + op[2] = (uint8_t)val; + + return mtk_snand_mac_io(snf, op, sizeof(op), NULL, 0); +} + +static int mtk_snand_poll_status(struct mtk_snand *snf, uint32_t wait_us) +{ + int val; + mtk_snand_time_t time_start, tmo; + + time_start = timer_get_ticks(); + tmo = timer_time_to_tick(wait_us); + + do { + val = mtk_snand_get_feature(snf, SNAND_FEATURE_STATUS_ADDR); + if (!(val & SNAND_STATUS_OIP)) + return val & (SNAND_STATUS_ERASE_FAIL | + SNAND_STATUS_PROGRAM_FAIL); + } while (!timer_is_timeout(time_start, tmo)); + + return -ETIMEDOUT; +} + +int mtk_snand_chip_reset(struct mtk_snand *snf) +{ + uint8_t op = SNAND_CMD_RESET; + int ret; + + ret = mtk_snand_mac_io(snf, &op, 1, NULL, 0); + if (ret) + return ret; + + ret = mtk_snand_poll_status(snf, SNFI_POLL_INTERVAL); + if (ret < 0) + return ret; + + return 0; +} + +static int mtk_snand_config_feature(struct mtk_snand *snf, uint8_t clr, + uint8_t set) +{ + int val, newval; + int ret; + + val = mtk_snand_get_feature(snf, SNAND_FEATURE_CONFIG_ADDR); + if (val < 0) { + snand_log_chip(snf->pdev, + "Failed to get configuration feature\n"); + return val; + } + + newval = (val & (~clr)) | set; + + if (newval == val) + return 0; + + ret = mtk_snand_set_feature(snf, SNAND_FEATURE_CONFIG_ADDR, + (uint8_t)newval); + if (val < 0) { + snand_log_chip(snf->pdev, + "Failed to set configuration feature\n"); + return ret; + } + + val = mtk_snand_get_feature(snf, SNAND_FEATURE_CONFIG_ADDR); + if (val < 0) { + snand_log_chip(snf->pdev, + "Failed to get configuration feature\n"); + return val; + } + + if (newval != val) + return -ENOTSUPP; + + return 0; +} + +static int mtk_snand_ondie_ecc_control(struct mtk_snand *snf, bool enable) +{ + int ret; + + if (enable) + ret = mtk_snand_config_feature(snf, 0, SNAND_FEATURE_ECC_EN); + else + ret = mtk_snand_config_feature(snf, SNAND_FEATURE_ECC_EN, 0); + + if (ret) { + snand_log_chip(snf->pdev, "Failed to %s On-Die ECC engine\n", + enable ? "enable" : "disable"); + } + + return ret; +} + +static int mtk_snand_qspi_control(struct mtk_snand *snf, bool enable) +{ + int ret; + + if (enable) { + ret = mtk_snand_config_feature(snf, 0, + SNAND_FEATURE_QUAD_ENABLE); + } else { + ret = mtk_snand_config_feature(snf, + SNAND_FEATURE_QUAD_ENABLE, 0); + } + + if (ret) { + snand_log_chip(snf->pdev, "Failed to %s quad spi\n", + enable ? "enable" : "disable"); + } + + return ret; +} + +static int mtk_snand_unlock(struct mtk_snand *snf) +{ + int ret; + + ret = mtk_snand_set_feature(snf, SNAND_FEATURE_PROTECT_ADDR, 0); + if (ret) { + snand_log_chip(snf->pdev, "Failed to set protection feature\n"); + return ret; + } + + return 0; +} + +static int mtk_snand_write_enable(struct mtk_snand *snf) +{ + uint8_t op = SNAND_CMD_WRITE_ENABLE; + int ret, val; + + ret = mtk_snand_mac_io(snf, &op, 1, NULL, 0); + if (ret) + return ret; + + val = mtk_snand_get_feature(snf, SNAND_FEATURE_STATUS_ADDR); + if (val < 0) + return ret; + + if (val & SNAND_STATUS_WEL) + return 0; + + snand_log_chip(snf->pdev, "Failed to send write-enable command\n"); + + return -ENOTSUPP; +} + +static int mtk_snand_select_die(struct mtk_snand *snf, uint32_t dieidx) +{ + if (!snf->select_die) + return 0; + + return snf->select_die(snf, dieidx); +} + +static uint64_t mtk_snand_select_die_address(struct mtk_snand *snf, + uint64_t addr) +{ + uint32_t dieidx; + + if (!snf->select_die) + return addr; + + dieidx = addr >> snf->die_shift; + + mtk_snand_select_die(snf, dieidx); + + return addr & snf->die_mask; +} + +static uint32_t mtk_snand_get_plane_address(struct mtk_snand *snf, + uint32_t page) +{ + uint32_t pages_per_block; + + pages_per_block = 1 << (snf->erasesize_shift - snf->writesize_shift); + + if (page & pages_per_block) + return 1 << (snf->writesize_shift + 1); + + return 0; +} + +static int mtk_snand_page_op(struct mtk_snand *snf, uint32_t page, uint8_t cmd) +{ + uint8_t op[4]; + + op[0] = cmd; + op[1] = (page >> 16) & 0xff; + op[2] = (page >> 8) & 0xff; + op[3] = page & 0xff; + + return mtk_snand_mac_io(snf, op, sizeof(op), NULL, 0); +} + +static void mtk_snand_read_fdm(struct mtk_snand *snf, uint8_t *buf) +{ + uint32_t vall, valm; + uint8_t *oobptr = buf; + int i, j; + + for (i = 0; i < snf->ecc_steps; i++) { + vall = nfi_read32(snf, NFI_FDML(i)); + valm = nfi_read32(snf, NFI_FDMM(i)); + + for (j = 0; j < snf->nfi_soc->fdm_size; j++) + oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8); + + oobptr += snf->nfi_soc->fdm_size; + } +} + +static int mtk_snand_read_ecc_parity(struct mtk_snand *snf, uint32_t page, + uint32_t sect, uint8_t *oob) +{ + uint32_t ecc_bytes = snf->spare_per_sector - snf->nfi_soc->fdm_size; + uint32_t coladdr, raw_offs, offs; + uint8_t op[4]; + + if (sizeof(op) + ecc_bytes > SNF_GPRAM_SIZE) { + snand_log_snfi(snf->pdev, + "ECC parity size does not fit the GPRAM\n"); + return -ENOTSUPP; + } + + raw_offs = sect * snf->raw_sector_size + snf->nfi_soc->sector_size + + snf->nfi_soc->fdm_size; + offs = snf->ecc_steps * snf->nfi_soc->fdm_size + sect * ecc_bytes; + + /* Column address with plane bit */ + coladdr = raw_offs | mtk_snand_get_plane_address(snf, page); + + op[0] = SNAND_CMD_READ_FROM_CACHE; + op[1] = (coladdr >> 8) & 0xff; + op[2] = coladdr & 0xff; + op[3] = 0; + + return mtk_snand_mac_io(snf, op, sizeof(op), oob + offs, ecc_bytes); +} + +static int mtk_snand_check_ecc_result(struct mtk_snand *snf, uint32_t page) +{ + uint8_t *oob = snf->page_cache + snf->writesize; + int i, rc, ret = 0, max_bitflips = 0; + + for (i = 0; i < snf->ecc_steps; i++) { + if (snf->sect_bf[i] >= 0) { + if (snf->sect_bf[i] > max_bitflips) + max_bitflips = snf->sect_bf[i]; + continue; + } + + rc = mtk_snand_read_ecc_parity(snf, page, i, oob); + if (rc) + return rc; + + rc = mtk_ecc_fixup_empty_sector(snf, i); + if (rc < 0) { + ret = -EBADMSG; + + snand_log_ecc(snf->pdev, + "Uncorrectable bitflips in page %u sect %u\n", + page, i); + } else if (rc) { + snf->sect_bf[i] = rc; + + if (snf->sect_bf[i] > max_bitflips) + max_bitflips = snf->sect_bf[i]; + + snand_log_ecc(snf->pdev, + "%u bitflip%s corrected in page %u sect %u\n", + rc, rc > 1 ? "s" : "", page, i); + } else { + snf->sect_bf[i] = 0; + } + } + + return ret ? ret : max_bitflips; +} + +static int mtk_snand_read_cache(struct mtk_snand *snf, uint32_t page, bool raw) +{ + uint32_t coladdr, rwbytes, mode, len, val; + uintptr_t dma_addr; + int ret; + + /* Column address with plane bit */ + coladdr = mtk_snand_get_plane_address(snf, page); + + mtk_snand_mac_reset(snf); + mtk_nfi_reset(snf); + + /* Command and dummy cycles */ + nfi_write32(snf, SNF_RD_CTL2, + ((uint32_t)snf->dummy_rfc << DATA_READ_DUMMY_S) | + (snf->opcode_rfc << DATA_READ_CMD_S)); + + /* Column address */ + nfi_write32(snf, SNF_RD_CTL3, coladdr); + + /* Set read mode */ + mode = (uint32_t)snf->mode_rfc << DATA_READ_MODE_S; + nfi_rmw32(snf, SNF_MISC_CTL, DATA_READ_MODE, mode | DATARD_CUSTOM_EN); + + /* Set bytes to read */ + rwbytes = snf->ecc_steps * snf->raw_sector_size; + nfi_write32(snf, SNF_MISC_CTL2, (rwbytes << PROGRAM_LOAD_BYTE_NUM_S) | + rwbytes); + + /* NFI read prepare */ + mode = raw ? 0 : CNFG_HW_ECC_EN | CNFG_AUTO_FMT_EN; + nfi_write16(snf, NFI_CNFG, (CNFG_OP_MODE_CUST << CNFG_OP_MODE_S) | + CNFG_DMA_BURST_EN | CNFG_READ_MODE | CNFG_DMA_MODE | mode); + + nfi_write32(snf, NFI_CON, (snf->ecc_steps << CON_SEC_NUM_S)); + + /* Prepare for DMA read */ + len = snf->writesize + snf->oobsize; + ret = dma_mem_map(snf->pdev, snf->page_cache, &dma_addr, len, false); + if (ret) { + snand_log_nfi(snf->pdev, + "DMA map from device failed with %d\n", ret); + return ret; + } + + nfi_write32(snf, NFI_STRADDR, (uint32_t)dma_addr); + + if (!raw) + mtk_snand_ecc_decoder_start(snf); + + /* Prepare for custom read interrupt */ + nfi_write32(snf, NFI_INTR_EN, NFI_IRQ_INTR_EN | NFI_IRQ_CUS_READ); + irq_completion_init(snf->pdev); + + /* Trigger NFI into custom mode */ + nfi_write16(snf, NFI_CMD, NFI_CMD_DUMMY_READ); + + /* Start DMA read */ + nfi_rmw32(snf, NFI_CON, 0, CON_BRD); + nfi_write16(snf, NFI_STRDATA, STR_DATA); + + /* Wait for operation finished */ + ret = irq_completion_wait(snf->pdev, snf->nfi_base + SNF_STA_CTL1, + CUS_READ_DONE, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, + "DMA timed out for reading from cache\n"); + goto cleanup; + } + + /* Wait for BUS_SEC_CNTR returning expected value */ + ret = read32_poll_timeout(snf->nfi_base + NFI_BYTELEN, val, + BUS_SEC_CNTR(val) >= snf->ecc_steps, + 0, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, + "Timed out waiting for BUS_SEC_CNTR\n"); + goto cleanup; + } + + /* Wait for bus becoming idle */ + ret = read32_poll_timeout(snf->nfi_base + NFI_MASTERSTA, val, + !(val & snf->nfi_soc->mastersta_mask), + 0, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, + "Timed out waiting for bus becoming idle\n"); + goto cleanup; + } + + if (!raw) { + ret = mtk_ecc_wait_decoder_done(snf); + if (ret) + goto cleanup; + + mtk_snand_read_fdm(snf, snf->page_cache + snf->writesize); + + mtk_ecc_check_decode_error(snf); + mtk_snand_ecc_decoder_stop(snf); + + ret = mtk_snand_check_ecc_result(snf, page); + } + +cleanup: + /* DMA cleanup */ + dma_mem_unmap(snf->pdev, dma_addr, len, false); + + /* Stop read */ + nfi_write32(snf, NFI_CON, 0); + nfi_write16(snf, NFI_CNFG, 0); + + /* Clear SNF done flag */ + nfi_rmw32(snf, SNF_STA_CTL1, 0, CUS_READ_DONE); + nfi_write32(snf, SNF_STA_CTL1, 0); + + /* Disable interrupt */ + nfi_read32(snf, NFI_INTR_STA); + nfi_write32(snf, NFI_INTR_EN, 0); + + nfi_rmw32(snf, SNF_MISC_CTL, DATARD_CUSTOM_EN, 0); + + return ret; +} + +static void mtk_snand_from_raw_page(struct mtk_snand *snf, void *buf, void *oob) +{ + uint32_t i, ecc_bytes = snf->spare_per_sector - snf->nfi_soc->fdm_size; + uint8_t *eccptr = oob + snf->ecc_steps * snf->nfi_soc->fdm_size; + uint8_t *bufptr = buf, *oobptr = oob, *raw_sector; + + for (i = 0; i < snf->ecc_steps; i++) { + raw_sector = snf->page_cache + i * snf->raw_sector_size; + + if (buf) { + memcpy(bufptr, raw_sector, snf->nfi_soc->sector_size); + bufptr += snf->nfi_soc->sector_size; + } + + raw_sector += snf->nfi_soc->sector_size; + + if (oob) { + memcpy(oobptr, raw_sector, snf->nfi_soc->fdm_size); + oobptr += snf->nfi_soc->fdm_size; + raw_sector += snf->nfi_soc->fdm_size; + + memcpy(eccptr, raw_sector, ecc_bytes); + eccptr += ecc_bytes; + } + } +} + +static int mtk_snand_do_read_page(struct mtk_snand *snf, uint64_t addr, + void *buf, void *oob, bool raw, bool format) +{ + uint64_t die_addr; + uint32_t page; + int ret; + + die_addr = mtk_snand_select_die_address(snf, addr); + page = die_addr >> snf->writesize_shift; + + ret = mtk_snand_page_op(snf, page, SNAND_CMD_READ_TO_CACHE); + if (ret) + return ret; + + ret = mtk_snand_poll_status(snf, SNFI_POLL_INTERVAL); + if (ret < 0) { + snand_log_chip(snf->pdev, "Read to cache command timed out\n"); + return ret; + } + + ret = mtk_snand_read_cache(snf, page, raw); + if (ret < 0 && ret != -EBADMSG) + return ret; + + if (raw) { + if (format) { + mtk_snand_bm_swap_raw(snf); + mtk_snand_fdm_bm_swap_raw(snf); + mtk_snand_from_raw_page(snf, buf, oob); + } else { + if (buf) + memcpy(buf, snf->page_cache, snf->writesize); + + if (oob) { + memset(oob, 0xff, snf->oobsize); + memcpy(oob, snf->page_cache + snf->writesize, + snf->ecc_steps * snf->spare_per_sector); + } + } + } else { + mtk_snand_bm_swap(snf); + mtk_snand_fdm_bm_swap(snf); + + if (buf) + memcpy(buf, snf->page_cache, snf->writesize); + + if (oob) { + memset(oob, 0xff, snf->oobsize); + memcpy(oob, snf->page_cache + snf->writesize, + snf->ecc_steps * snf->nfi_soc->fdm_size); + } + } + + return ret; +} + +int mtk_snand_read_page(struct mtk_snand *snf, uint64_t addr, void *buf, + void *oob, bool raw) +{ + if (!snf || (!buf && !oob)) + return -EINVAL; + + if (addr >= snf->size) + return -EINVAL; + + return mtk_snand_do_read_page(snf, addr, buf, oob, raw, true); +} + +static void mtk_snand_write_fdm(struct mtk_snand *snf, const uint8_t *buf) +{ + uint32_t vall, valm, fdm_size = snf->nfi_soc->fdm_size; + const uint8_t *oobptr = buf; + int i, j; + + for (i = 0; i < snf->ecc_steps; i++) { + vall = 0; + valm = 0; + + for (j = 0; j < 8; j++) { + if (j < 4) + vall |= (j < fdm_size ? oobptr[j] : 0xff) + << (j * 8); + else + valm |= (j < fdm_size ? oobptr[j] : 0xff) + << ((j - 4) * 8); + } + + nfi_write32(snf, NFI_FDML(i), vall); + nfi_write32(snf, NFI_FDMM(i), valm); + + oobptr += fdm_size; + } +} + +static int mtk_snand_program_load(struct mtk_snand *snf, uint32_t page, + bool raw) +{ + uint32_t coladdr, rwbytes, mode, len, val; + uintptr_t dma_addr; + int ret; + + /* Column address with plane bit */ + coladdr = mtk_snand_get_plane_address(snf, page); + + mtk_snand_mac_reset(snf); + mtk_nfi_reset(snf); + + /* Write FDM registers if necessary */ + if (!raw) + mtk_snand_write_fdm(snf, snf->page_cache + snf->writesize); + + /* Command */ + nfi_write32(snf, SNF_PG_CTL1, (snf->opcode_pl << PG_LOAD_CMD_S)); + + /* Column address */ + nfi_write32(snf, SNF_PG_CTL2, coladdr); + + /* Set write mode */ + mode = snf->mode_pl ? PG_LOAD_X4_EN : 0; + nfi_rmw32(snf, SNF_MISC_CTL, PG_LOAD_X4_EN, mode | PG_LOAD_CUSTOM_EN); + + /* Set bytes to write */ + rwbytes = snf->ecc_steps * snf->raw_sector_size; + nfi_write32(snf, SNF_MISC_CTL2, (rwbytes << PROGRAM_LOAD_BYTE_NUM_S) | + rwbytes); + + /* NFI write prepare */ + mode = raw ? 0 : CNFG_HW_ECC_EN | CNFG_AUTO_FMT_EN; + nfi_write16(snf, NFI_CNFG, (CNFG_OP_MODE_PROGRAM << CNFG_OP_MODE_S) | + CNFG_DMA_BURST_EN | CNFG_DMA_MODE | mode); + + nfi_write32(snf, NFI_CON, (snf->ecc_steps << CON_SEC_NUM_S)); + + /* Prepare for DMA write */ + len = snf->writesize + snf->oobsize; + ret = dma_mem_map(snf->pdev, snf->page_cache, &dma_addr, len, true); + if (ret) { + snand_log_nfi(snf->pdev, + "DMA map to device failed with %d\n", ret); + return ret; + } + + nfi_write32(snf, NFI_STRADDR, (uint32_t)dma_addr); + + if (!raw) + mtk_snand_ecc_encoder_start(snf); + + /* Prepare for custom write interrupt */ + nfi_write32(snf, NFI_INTR_EN, NFI_IRQ_INTR_EN | NFI_IRQ_CUS_PG); + irq_completion_init(snf->pdev); + + /* Trigger NFI into custom mode */ + nfi_write16(snf, NFI_CMD, NFI_CMD_DUMMY_WRITE); + + /* Start DMA write */ + nfi_rmw32(snf, NFI_CON, 0, CON_BWR); + nfi_write16(snf, NFI_STRDATA, STR_DATA); + + /* Wait for operation finished */ + ret = irq_completion_wait(snf->pdev, snf->nfi_base + SNF_STA_CTL1, + CUS_PG_DONE, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, + "DMA timed out for program load\n"); + goto cleanup; + } + + /* Wait for NFI_SEC_CNTR returning expected value */ + ret = read32_poll_timeout(snf->nfi_base + NFI_ADDRCNTR, val, + NFI_SEC_CNTR(val) >= snf->ecc_steps, + 0, SNFI_POLL_INTERVAL); + if (ret) { + snand_log_nfi(snf->pdev, + "Timed out waiting for NFI_SEC_CNTR\n"); + goto cleanup; + } + + if (!raw) + mtk_snand_ecc_encoder_stop(snf); + +cleanup: + /* DMA cleanup */ + dma_mem_unmap(snf->pdev, dma_addr, len, true); + + /* Stop write */ + nfi_write32(snf, NFI_CON, 0); + nfi_write16(snf, NFI_CNFG, 0); + + /* Clear SNF done flag */ + nfi_rmw32(snf, SNF_STA_CTL1, 0, CUS_PG_DONE); + nfi_write32(snf, SNF_STA_CTL1, 0); + + /* Disable interrupt */ + nfi_read32(snf, NFI_INTR_STA); + nfi_write32(snf, NFI_INTR_EN, 0); + + nfi_rmw32(snf, SNF_MISC_CTL, PG_LOAD_CUSTOM_EN, 0); + + return ret; +} + +static void mtk_snand_to_raw_page(struct mtk_snand *snf, + const void *buf, const void *oob, + bool empty_ecc) +{ + uint32_t i, ecc_bytes = snf->spare_per_sector - snf->nfi_soc->fdm_size; + const uint8_t *eccptr = oob + snf->ecc_steps * snf->nfi_soc->fdm_size; + const uint8_t *bufptr = buf, *oobptr = oob; + uint8_t *raw_sector; + + memset(snf->page_cache, 0xff, snf->writesize + snf->oobsize); + for (i = 0; i < snf->ecc_steps; i++) { + raw_sector = snf->page_cache + i * snf->raw_sector_size; + + if (buf) { + memcpy(raw_sector, bufptr, snf->nfi_soc->sector_size); + bufptr += snf->nfi_soc->sector_size; + } + + raw_sector += snf->nfi_soc->sector_size; + + if (oob) { + memcpy(raw_sector, oobptr, snf->nfi_soc->fdm_size); + oobptr += snf->nfi_soc->fdm_size; + raw_sector += snf->nfi_soc->fdm_size; + + if (empty_ecc) + memset(raw_sector, 0xff, ecc_bytes); + else + memcpy(raw_sector, eccptr, ecc_bytes); + eccptr += ecc_bytes; + } + } +} + +static bool mtk_snand_is_empty_page(struct mtk_snand *snf, const void *buf, + const void *oob) +{ + const uint8_t *p = buf; + uint32_t i, j; + + if (buf) { + for (i = 0; i < snf->writesize; i++) { + if (p[i] != 0xff) + return false; + } + } + + if (oob) { + for (j = 0; j < snf->ecc_steps; j++) { + p = oob + j * snf->nfi_soc->fdm_size; + + for (i = 0; i < snf->nfi_soc->fdm_ecc_size; i++) { + if (p[i] != 0xff) + return false; + } + } + } + + return true; +} + +static int mtk_snand_do_write_page(struct mtk_snand *snf, uint64_t addr, + const void *buf, const void *oob, + bool raw, bool format) +{ + uint64_t die_addr; + bool empty_ecc = false; + uint32_t page; + int ret; + + die_addr = mtk_snand_select_die_address(snf, addr); + page = die_addr >> snf->writesize_shift; + + if (!raw && mtk_snand_is_empty_page(snf, buf, oob)) { + /* + * If the data in the page to be ecc-ed is full 0xff, + * change to raw write mode + */ + raw = true; + format = true; + + /* fill ecc parity code region with 0xff */ + empty_ecc = true; + } + + if (raw) { + if (format) { + mtk_snand_to_raw_page(snf, buf, oob, empty_ecc); + mtk_snand_fdm_bm_swap_raw(snf); + mtk_snand_bm_swap_raw(snf); + } else { + memset(snf->page_cache, 0xff, + snf->writesize + snf->oobsize); + + if (buf) + memcpy(snf->page_cache, buf, snf->writesize); + + if (oob) { + memcpy(snf->page_cache + snf->writesize, oob, + snf->ecc_steps * snf->spare_per_sector); + } + } + } else { + memset(snf->page_cache, 0xff, snf->writesize + snf->oobsize); + if (buf) + memcpy(snf->page_cache, buf, snf->writesize); + + if (oob) { + memcpy(snf->page_cache + snf->writesize, oob, + snf->ecc_steps * snf->nfi_soc->fdm_size); + } + + mtk_snand_fdm_bm_swap(snf); + mtk_snand_bm_swap(snf); + } + + ret = mtk_snand_write_enable(snf); + if (ret) + return ret; + + ret = mtk_snand_program_load(snf, page, raw); + if (ret) + return ret; + + ret = mtk_snand_page_op(snf, page, SNAND_CMD_PROGRAM_EXECUTE); + if (ret) + return ret; + + ret = mtk_snand_poll_status(snf, SNFI_POLL_INTERVAL); + if (ret < 0) { + snand_log_chip(snf->pdev, + "Page program command timed out on page %u\n", + page); + return ret; + } + + if (ret & SNAND_STATUS_PROGRAM_FAIL) { + snand_log_chip(snf->pdev, + "Page program failed on page %u\n", page); + return -EIO; + } + + return 0; +} + +int mtk_snand_write_page(struct mtk_snand *snf, uint64_t addr, const void *buf, + const void *oob, bool raw) +{ + if (!snf || (!buf && !oob)) + return -EINVAL; + + if (addr >= snf->size) + return -EINVAL; + + return mtk_snand_do_write_page(snf, addr, buf, oob, raw, true); +} + +int mtk_snand_erase_block(struct mtk_snand *snf, uint64_t addr) +{ + uint64_t die_addr; + uint32_t page, block; + int ret; + + if (!snf) + return -EINVAL; + + if (addr >= snf->size) + return -EINVAL; + + die_addr = mtk_snand_select_die_address(snf, addr); + block = die_addr >> snf->erasesize_shift; + page = block << (snf->erasesize_shift - snf->writesize_shift); + + ret = mtk_snand_write_enable(snf); + if (ret) + return ret; + + ret = mtk_snand_page_op(snf, page, SNAND_CMD_BLOCK_ERASE); + if (ret) + return ret; + + ret = mtk_snand_poll_status(snf, SNFI_POLL_INTERVAL); + if (ret < 0) { + snand_log_chip(snf->pdev, + "Block erase command timed out on block %u\n", + block); + return ret; + } + + if (ret & SNAND_STATUS_ERASE_FAIL) { + snand_log_chip(snf->pdev, + "Block erase failed on block %u\n", block); + return -EIO; + } + + return 0; +} + +static int mtk_snand_block_isbad_std(struct mtk_snand *snf, uint64_t addr) +{ + int ret; + + ret = mtk_snand_do_read_page(snf, addr, NULL, snf->buf_cache, true, + false); + if (ret && ret != -EBADMSG) + return ret; + + return snf->buf_cache[0] != 0xff; +} + +static int mtk_snand_block_isbad_mtk(struct mtk_snand *snf, uint64_t addr) +{ + int ret; + + ret = mtk_snand_do_read_page(snf, addr, NULL, snf->buf_cache, true, + true); + if (ret && ret != -EBADMSG) + return ret; + + return snf->buf_cache[0] != 0xff; +} + +int mtk_snand_block_isbad(struct mtk_snand *snf, uint64_t addr) +{ + if (!snf) + return -EINVAL; + + if (addr >= snf->size) + return -EINVAL; + + addr &= ~snf->erasesize_mask; + + if (snf->nfi_soc->bbm_swap) + return mtk_snand_block_isbad_std(snf, addr); + + return mtk_snand_block_isbad_mtk(snf, addr); +} + +static int mtk_snand_block_markbad_std(struct mtk_snand *snf, uint64_t addr) +{ + /* Standard BBM position */ + memset(snf->buf_cache, 0xff, snf->oobsize); + snf->buf_cache[0] = 0; + + return mtk_snand_do_write_page(snf, addr, NULL, snf->buf_cache, true, + false); +} + +static int mtk_snand_block_markbad_mtk(struct mtk_snand *snf, uint64_t addr) +{ + /* Write the whole page with zeros */ + memset(snf->buf_cache, 0, snf->writesize + snf->oobsize); + + return mtk_snand_do_write_page(snf, addr, snf->buf_cache, + snf->buf_cache + snf->writesize, true, + true); +} + +int mtk_snand_block_markbad(struct mtk_snand *snf, uint64_t addr) +{ + if (!snf) + return -EINVAL; + + if (addr >= snf->size) + return -EINVAL; + + addr &= ~snf->erasesize_mask; + + if (snf->nfi_soc->bbm_swap) + return mtk_snand_block_markbad_std(snf, addr); + + return mtk_snand_block_markbad_mtk(snf, addr); +} + +int mtk_snand_fill_oob(struct mtk_snand *snf, uint8_t *oobraw, + const uint8_t *oobbuf, size_t ooblen) +{ + size_t len = ooblen, sect_fdm_len; + const uint8_t *oob = oobbuf; + uint32_t step = 0; + + if (!snf || !oobraw || !oob) + return -EINVAL; + + while (len && step < snf->ecc_steps) { + sect_fdm_len = snf->nfi_soc->fdm_size - 1; + if (sect_fdm_len > len) + sect_fdm_len = len; + + memcpy(oobraw + step * snf->nfi_soc->fdm_size + 1, oob, + sect_fdm_len); + + len -= sect_fdm_len; + oob += sect_fdm_len; + step++; + } + + return len; +} + +int mtk_snand_transfer_oob(struct mtk_snand *snf, uint8_t *oobbuf, + size_t ooblen, const uint8_t *oobraw) +{ + size_t len = ooblen, sect_fdm_len; + uint8_t *oob = oobbuf; + uint32_t step = 0; + + if (!snf || !oobraw || !oob) + return -EINVAL; + + while (len && step < snf->ecc_steps) { + sect_fdm_len = snf->nfi_soc->fdm_size - 1; + if (sect_fdm_len > len) + sect_fdm_len = len; + + memcpy(oob, oobraw + step * snf->nfi_soc->fdm_size + 1, + sect_fdm_len); + + len -= sect_fdm_len; + oob += sect_fdm_len; + step++; + } + + return len; +} + +int mtk_snand_read_page_auto_oob(struct mtk_snand *snf, uint64_t addr, + void *buf, void *oob, size_t ooblen, + size_t *actualooblen, bool raw) +{ + int ret, oobremain; + + if (!snf) + return -EINVAL; + + if (!oob) + return mtk_snand_read_page(snf, addr, buf, NULL, raw); + + ret = mtk_snand_read_page(snf, addr, buf, snf->buf_cache, raw); + if (ret && ret != -EBADMSG) { + if (actualooblen) + *actualooblen = 0; + return ret; + } + + oobremain = mtk_snand_transfer_oob(snf, oob, ooblen, snf->buf_cache); + if (actualooblen) + *actualooblen = ooblen - oobremain; + + return ret; +} + +int mtk_snand_write_page_auto_oob(struct mtk_snand *snf, uint64_t addr, + const void *buf, const void *oob, + size_t ooblen, size_t *actualooblen, bool raw) +{ + int oobremain; + + if (!snf) + return -EINVAL; + + if (!oob) + return mtk_snand_write_page(snf, addr, buf, NULL, raw); + + memset(snf->buf_cache, 0xff, snf->oobsize); + oobremain = mtk_snand_fill_oob(snf, snf->buf_cache, oob, ooblen); + if (actualooblen) + *actualooblen = ooblen - oobremain; + + return mtk_snand_write_page(snf, addr, buf, snf->buf_cache, raw); +} + +int mtk_snand_get_chip_info(struct mtk_snand *snf, + struct mtk_snand_chip_info *info) +{ + if (!snf || !info) + return -EINVAL; + + info->model = snf->model; + info->chipsize = snf->size; + info->blocksize = snf->erasesize; + info->pagesize = snf->writesize; + info->sparesize = snf->oobsize; + info->spare_per_sector = snf->spare_per_sector; + info->fdm_size = snf->nfi_soc->fdm_size; + info->fdm_ecc_size = snf->nfi_soc->fdm_ecc_size; + info->num_sectors = snf->ecc_steps; + info->sector_size = snf->nfi_soc->sector_size; + info->ecc_strength = snf->ecc_strength; + info->ecc_bytes = snf->ecc_bytes; + + return 0; +} + +int mtk_snand_irq_process(struct mtk_snand *snf) +{ + uint32_t sta, ien; + + if (!snf) + return -EINVAL; + + sta = nfi_read32(snf, NFI_INTR_STA); + ien = nfi_read32(snf, NFI_INTR_EN); + + if (!(sta & ien)) + return 0; + + nfi_write32(snf, NFI_INTR_EN, 0); + irq_completion_done(snf->pdev); + + return 1; +} + +static int mtk_snand_select_spare_per_sector(struct mtk_snand *snf) +{ + uint32_t spare_per_step = snf->oobsize / snf->ecc_steps; + int i, mul = 1; + + /* + * If we're using the 1KB sector size, HW will automatically + * double the spare size. So we should only use half of the value. + */ + if (snf->nfi_soc->sector_size == 1024) + mul = 2; + + spare_per_step /= mul; + + for (i = snf->nfi_soc->num_spare_size - 1; i >= 0; i--) { + if (snf->nfi_soc->spare_sizes[i] <= spare_per_step) { + snf->spare_per_sector = snf->nfi_soc->spare_sizes[i]; + snf->spare_per_sector *= mul; + return i; + } + } + + snand_log_nfi(snf->pdev, + "Page size %u+%u is not supported\n", snf->writesize, + snf->oobsize); + + return -1; +} + +static int mtk_snand_pagefmt_setup(struct mtk_snand *snf) +{ + uint32_t spare_size_idx, spare_size_shift, pagesize_idx; + uint32_t sector_size_512; + + if (snf->nfi_soc->sector_size == 512) { + sector_size_512 = NFI_SEC_SEL_512; + spare_size_shift = NFI_SPARE_SIZE_S; + } else { + sector_size_512 = 0; + spare_size_shift = NFI_SPARE_SIZE_LS_S; + } + + switch (snf->writesize) { + case SZ_512: + pagesize_idx = NFI_PAGE_SIZE_512_2K; + break; + case SZ_2K: + if (snf->nfi_soc->sector_size == 512) + pagesize_idx = NFI_PAGE_SIZE_2K_4K; + else + pagesize_idx = NFI_PAGE_SIZE_512_2K; + break; + case SZ_4K: + if (snf->nfi_soc->sector_size == 512) + pagesize_idx = NFI_PAGE_SIZE_4K_8K; + else + pagesize_idx = NFI_PAGE_SIZE_2K_4K; + break; + case SZ_8K: + if (snf->nfi_soc->sector_size == 512) + pagesize_idx = NFI_PAGE_SIZE_8K_16K; + else + pagesize_idx = NFI_PAGE_SIZE_4K_8K; + break; + case SZ_16K: + pagesize_idx = NFI_PAGE_SIZE_8K_16K; + break; + default: + snand_log_nfi(snf->pdev, "Page size %u is not supported\n", + snf->writesize); + return -ENOTSUPP; + } + + spare_size_idx = mtk_snand_select_spare_per_sector(snf); + if (unlikely(spare_size_idx < 0)) + return -ENOTSUPP; + + snf->raw_sector_size = snf->nfi_soc->sector_size + + snf->spare_per_sector; + + /* Setup page format */ + nfi_write32(snf, NFI_PAGEFMT, + (snf->nfi_soc->fdm_ecc_size << NFI_FDM_ECC_NUM_S) | + (snf->nfi_soc->fdm_size << NFI_FDM_NUM_S) | + (spare_size_idx << spare_size_shift) | + (pagesize_idx << NFI_PAGE_SIZE_S) | + sector_size_512); + + return 0; +} + +static enum snand_flash_io mtk_snand_select_opcode(struct mtk_snand *snf, + uint32_t snfi_caps, uint8_t *opcode, + uint8_t *dummy, + const struct snand_io_cap *op_cap) +{ + uint32_t i, caps; + + caps = snfi_caps & op_cap->caps; + + i = fls(caps); + if (i > 0) { + *opcode = op_cap->opcodes[i - 1].opcode; + if (dummy) + *dummy = op_cap->opcodes[i - 1].dummy; + return i - 1; + } + + return __SNAND_IO_MAX; +} + +static int mtk_snand_select_opcode_rfc(struct mtk_snand *snf, + uint32_t snfi_caps, + const struct snand_io_cap *op_cap) +{ + enum snand_flash_io idx; + + static const uint8_t rfc_modes[__SNAND_IO_MAX] = { + [SNAND_IO_1_1_1] = DATA_READ_MODE_X1, + [SNAND_IO_1_1_2] = DATA_READ_MODE_X2, + [SNAND_IO_1_2_2] = DATA_READ_MODE_DUAL, + [SNAND_IO_1_1_4] = DATA_READ_MODE_X4, + [SNAND_IO_1_4_4] = DATA_READ_MODE_QUAD, + }; + + idx = mtk_snand_select_opcode(snf, snfi_caps, &snf->opcode_rfc, + &snf->dummy_rfc, op_cap); + if (idx >= __SNAND_IO_MAX) { + snand_log_snfi(snf->pdev, + "No capable opcode for read from cache\n"); + return -ENOTSUPP; + } + + snf->mode_rfc = rfc_modes[idx]; + + if (idx == SNAND_IO_1_1_4 || idx == SNAND_IO_1_4_4) + snf->quad_spi_op = true; + + return 0; +} + +static int mtk_snand_select_opcode_pl(struct mtk_snand *snf, uint32_t snfi_caps, + const struct snand_io_cap *op_cap) +{ + enum snand_flash_io idx; + + static const uint8_t pl_modes[__SNAND_IO_MAX] = { + [SNAND_IO_1_1_1] = 0, + [SNAND_IO_1_1_4] = 1, + }; + + idx = mtk_snand_select_opcode(snf, snfi_caps, &snf->opcode_pl, + NULL, op_cap); + if (idx >= __SNAND_IO_MAX) { + snand_log_snfi(snf->pdev, + "No capable opcode for program load\n"); + return -ENOTSUPP; + } + + snf->mode_pl = pl_modes[idx]; + + if (idx == SNAND_IO_1_1_4) + snf->quad_spi_op = true; + + return 0; +} + +static int mtk_snand_setup(struct mtk_snand *snf, + const struct snand_flash_info *snand_info) +{ + const struct snand_mem_org *memorg = &snand_info->memorg; + uint32_t i, msg_size, snfi_caps; + int ret; + + /* Calculate flash memory organization */ + snf->model = snand_info->model; + snf->writesize = memorg->pagesize; + snf->oobsize = memorg->sparesize; + snf->erasesize = snf->writesize * memorg->pages_per_block; + snf->die_size = (uint64_t)snf->erasesize * memorg->blocks_per_die; + snf->size = snf->die_size * memorg->ndies; + snf->num_dies = memorg->ndies; + + snf->writesize_mask = snf->writesize - 1; + snf->erasesize_mask = snf->erasesize - 1; + snf->die_mask = snf->die_size - 1; + + snf->writesize_shift = ffs(snf->writesize) - 1; + snf->erasesize_shift = ffs(snf->erasesize) - 1; + snf->die_shift = mtk_snand_ffs64(snf->die_size) - 1; + + snf->select_die = snand_info->select_die; + + /* Determine opcodes for read from cache/program load */ + snfi_caps = SPI_IO_1_1_1 | SPI_IO_1_1_2 | SPI_IO_1_2_2; + if (snf->snfi_quad_spi) + snfi_caps |= SPI_IO_1_1_4 | SPI_IO_1_4_4; + + ret = mtk_snand_select_opcode_rfc(snf, snfi_caps, snand_info->cap_rd); + if (ret) + return ret; + + ret = mtk_snand_select_opcode_pl(snf, snfi_caps, snand_info->cap_pl); + if (ret) + return ret; + + /* ECC and page format */ + snf->ecc_steps = snf->writesize / snf->nfi_soc->sector_size; + if (snf->ecc_steps > snf->nfi_soc->max_sectors) { + snand_log_nfi(snf->pdev, "Page size %u is not supported\n", + snf->writesize); + return -ENOTSUPP; + } + + ret = mtk_snand_pagefmt_setup(snf); + if (ret) + return ret; + + msg_size = snf->nfi_soc->sector_size + snf->nfi_soc->fdm_ecc_size; + ret = mtk_ecc_setup(snf, snf->nfi_base + NFI_FDM0L, + snf->spare_per_sector - snf->nfi_soc->fdm_size, + msg_size); + if (ret) + return ret; + + nfi_write16(snf, NFI_CNFG, 0); + + /* Tuning options */ + nfi_write16(snf, NFI_DEBUG_CON1, WBUF_EN); + nfi_write32(snf, SNF_DLY_CTL3, (40 << SFCK_SAM_DLY_S)); + + /* Interrupts */ + nfi_read32(snf, NFI_INTR_STA); + nfi_write32(snf, NFI_INTR_EN, 0); + + /* Clear SNF done flag */ + nfi_rmw32(snf, SNF_STA_CTL1, 0, CUS_READ_DONE | CUS_PG_DONE); + nfi_write32(snf, SNF_STA_CTL1, 0); + + /* Initialization on all dies */ + for (i = 0; i < snf->num_dies; i++) { + mtk_snand_select_die(snf, i); + + /* Disable On-Die ECC engine */ + ret = mtk_snand_ondie_ecc_control(snf, false); + if (ret) + return ret; + + /* Disable block protection */ + mtk_snand_unlock(snf); + + /* Enable/disable quad-spi */ + mtk_snand_qspi_control(snf, snf->quad_spi_op); + } + + mtk_snand_select_die(snf, 0); + + return 0; +} + +static int mtk_snand_id_probe(struct mtk_snand *snf, + const struct snand_flash_info **snand_info) +{ + uint8_t id[4], op[2]; + int ret; + + /* Read SPI-NAND JEDEC ID, OP + dummy/addr + ID */ + op[0] = SNAND_CMD_READID; + op[1] = 0; + ret = mtk_snand_mac_io(snf, op, 2, id, sizeof(id)); + if (ret) + return ret; + + *snand_info = snand_flash_id_lookup(SNAND_ID_DYMMY, id); + if (*snand_info) + return 0; + + /* Read SPI-NAND JEDEC ID, OP + ID */ + op[0] = SNAND_CMD_READID; + ret = mtk_snand_mac_io(snf, op, 1, id, sizeof(id)); + if (ret) + return ret; + + *snand_info = snand_flash_id_lookup(SNAND_ID_DYMMY, id); + if (*snand_info) + return 0; + + snand_log_chip(snf->pdev, + "Unrecognized SPI-NAND ID: %02x %02x %02x %02x\n", + id[0], id[1], id[2], id[3]); + + return -EINVAL; +} + +int mtk_snand_init(void *dev, const struct mtk_snand_platdata *pdata, + struct mtk_snand **psnf) +{ + const struct snand_flash_info *snand_info; + uint32_t rawpage_size, sect_bf_size; + struct mtk_snand tmpsnf, *snf; + int ret; + + if (!pdata || !psnf) + return -EINVAL; + + if (pdata->soc >= __SNAND_SOC_MAX) { + snand_log_chip(dev, "Invalid SOC %u for MTK-SNAND\n", + pdata->soc); + return -EINVAL; + } + + /* Dummy instance only for initial reset and id probe */ + tmpsnf.nfi_base = pdata->nfi_base; + tmpsnf.ecc_base = pdata->ecc_base; + tmpsnf.soc = pdata->soc; + tmpsnf.nfi_soc = &mtk_snand_socs[pdata->soc]; + tmpsnf.pdev = dev; + + /* Switch to SNFI mode */ + writel(SPI_MODE, tmpsnf.nfi_base + SNF_CFG); + + /* Reset SNFI & NFI */ + mtk_snand_mac_reset(&tmpsnf); + mtk_nfi_reset(&tmpsnf); + + /* Reset SPI-NAND chip */ + ret = mtk_snand_chip_reset(&tmpsnf); + if (ret) { + snand_log_chip(dev, "Failed to reset SPI-NAND chip\n"); + return ret; + } + + /* Probe SPI-NAND flash by JEDEC ID */ + ret = mtk_snand_id_probe(&tmpsnf, &snand_info); + if (ret) + return ret; + + rawpage_size = snand_info->memorg.pagesize + + snand_info->memorg.sparesize; + + sect_bf_size = mtk_snand_socs[pdata->soc].max_sectors * + sizeof(*snf->sect_bf); + + /* Allocate memory for instance and cache */ + snf = generic_mem_alloc(dev, + sizeof(*snf) + rawpage_size + sect_bf_size); + if (!snf) { + snand_log_chip(dev, "Failed to allocate memory for instance\n"); + return -ENOMEM; + } + + snf->sect_bf = (int *)((uintptr_t)snf + sizeof(*snf)); + snf->buf_cache = (uint8_t *)((uintptr_t)snf->sect_bf + sect_bf_size); + + /* Allocate memory for DMA buffer */ + snf->page_cache = dma_mem_alloc(dev, rawpage_size); + if (!snf->page_cache) { + generic_mem_free(dev, snf); + snand_log_chip(dev, + "Failed to allocate memory for DMA buffer\n"); + return -ENOMEM; + } + + /* Fill up instance */ + snf->pdev = dev; + snf->nfi_base = pdata->nfi_base; + snf->ecc_base = pdata->ecc_base; + snf->soc = pdata->soc; + snf->nfi_soc = &mtk_snand_socs[pdata->soc]; + snf->snfi_quad_spi = pdata->quad_spi; + + /* Initialize SNFI & ECC engine */ + ret = mtk_snand_setup(snf, snand_info); + if (ret) { + dma_mem_free(dev, snf->page_cache); + generic_mem_free(dev, snf); + return ret; + } + + *psnf = snf; + + return 0; +} + +int mtk_snand_cleanup(struct mtk_snand *snf) +{ + if (!snf) + return 0; + + dma_mem_free(snf->pdev, snf->page_cache); + generic_mem_free(snf->pdev, snf); + + return 0; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.h b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.h new file mode 100755 index 00000000..73c5cc60 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/mtd/mtk-snand/mtk-snand.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao + */ + +#ifndef _MTK_SNAND_H_ +#define _MTK_SNAND_H_ + +#ifndef PRIVATE_MTK_SNAND_HEADER +#include +#include +#include +#endif + +enum mtk_snand_soc { + SNAND_SOC_MT7622, + SNAND_SOC_MT7629, + + __SNAND_SOC_MAX +}; + +struct mtk_snand_platdata { + void *nfi_base; + void *ecc_base; + enum mtk_snand_soc soc; + bool quad_spi; +}; + +struct mtk_snand_chip_info { + const char *model; + uint64_t chipsize; + uint32_t blocksize; + uint32_t pagesize; + uint32_t sparesize; + uint32_t spare_per_sector; + uint32_t fdm_size; + uint32_t fdm_ecc_size; + uint32_t num_sectors; + uint32_t sector_size; + uint32_t ecc_strength; + uint32_t ecc_bytes; +}; + +struct mtk_snand; +struct snand_flash_info; + +int mtk_snand_init(void *dev, const struct mtk_snand_platdata *pdata, + struct mtk_snand **psnf); +int mtk_snand_cleanup(struct mtk_snand *snf); + +int mtk_snand_chip_reset(struct mtk_snand *snf); +int mtk_snand_read_page(struct mtk_snand *snf, uint64_t addr, void *buf, + void *oob, bool raw); +int mtk_snand_write_page(struct mtk_snand *snf, uint64_t addr, const void *buf, + const void *oob, bool raw); +int mtk_snand_erase_block(struct mtk_snand *snf, uint64_t addr); +int mtk_snand_block_isbad(struct mtk_snand *snf, uint64_t addr); +int mtk_snand_block_markbad(struct mtk_snand *snf, uint64_t addr); +int mtk_snand_fill_oob(struct mtk_snand *snf, uint8_t *oobraw, + const uint8_t *oobbuf, size_t ooblen); +int mtk_snand_transfer_oob(struct mtk_snand *snf, uint8_t *oobbuf, + size_t ooblen, const uint8_t *oobraw); +int mtk_snand_read_page_auto_oob(struct mtk_snand *snf, uint64_t addr, + void *buf, void *oob, size_t ooblen, + size_t *actualooblen, bool raw); +int mtk_snand_write_page_auto_oob(struct mtk_snand *snf, uint64_t addr, + const void *buf, const void *oob, + size_t ooblen, size_t *actualooblen, + bool raw); +int mtk_snand_get_chip_info(struct mtk_snand *snf, + struct mtk_snand_chip_info *info); +int mtk_snand_irq_process(struct mtk_snand *snf); + +#endif /* _MTK_SNAND_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Kconfig b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Kconfig new file mode 100755 index 00000000..d9e0230c --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Kconfig @@ -0,0 +1,3 @@ + +config MT753X_GSW + tristate "Driver for the MediaTek MT753x switch" diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Makefile b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Makefile new file mode 100755 index 00000000..7aae451c --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for MediaTek MT753x gigabit switch +# + +obj-$(CONFIG_MT753X_GSW) += mt753x.o + +mt753x-$(CONFIG_SWCONFIG) += mt753x_swconfig.o + +mt753x-y += mt753x_mdio.o mt7530.o mt7531.o \ + mt753x_common.o mt753x_vlan.o \ + mt753x_nl.o diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.c new file mode 100755 index 00000000..6a94d0d2 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.c @@ -0,0 +1,631 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include + +#include "mt753x.h" +#include "mt753x_regs.h" + +/* MT7530 registers */ + +/* Unique fields of PMCR for MT7530 */ +#define FORCE_MODE BIT(15) + +/* Unique fields of GMACCR for MT7530 */ +#define VLAN_SUPT_NO_S 14 +#define VLAN_SUPT_NO_M 0x1c000 +#define LATE_COL_DROP BIT(13) + +/* Unique fields of (M)HWSTRAP for MT7530 */ +#define BOND_OPTION BIT(24) +#define P5_PHY0_SEL BIT(20) +#define CHG_TRAP BIT(16) +#define LOOPDET_DIS BIT(14) +#define P5_INTF_SEL_GMAC5 BIT(13) +#define SMI_ADDR_S 11 +#define SMI_ADDR_M 0x1800 +#define XTAL_FSEL_S 9 +#define XTAL_FSEL_M 0x600 +#define P6_INTF_DIS BIT(8) +#define P5_INTF_MODE_RGMII BIT(7) +#define P5_INTF_DIS_S BIT(6) +#define C_MDIO_BPS_S BIT(5) +#define EEPROM_EN_S BIT(4) + +/* PHY EEE Register bitmap of define */ +#define PHY_DEV07 0x07 +#define PHY_DEV07_REG_03C 0x3c + +/* PHY Extend Register 0x14 bitmap of define */ +#define PHY_EXT_REG_14 0x14 + +/* Fields of PHY_EXT_REG_14 */ +#define PHY_EN_DOWN_SHFIT BIT(4) + +/* PHY Token Ring Register 0x10 bitmap of define */ +#define PHY_TR_REG_10 0x10 + +/* PHY Token Ring Register 0x12 bitmap of define */ +#define PHY_TR_REG_12 0x12 + +/* PHY LPI PCS/DSP Control Register bitmap of define */ +#define PHY_LPI_REG_11 0x11 + +/* PHY DEV 0x1e Register bitmap of define */ +#define PHY_DEV1E 0x1e +#define PHY_DEV1E_REG_123 0x123 +#define PHY_DEV1E_REG_A6 0xa6 + +/* Values of XTAL_FSEL */ +#define XTAL_20MHZ 1 +#define XTAL_40MHZ 2 +#define XTAL_25MHZ 3 + +#define P6ECR 0x7830 +#define P6_INTF_MODE_TRGMII BIT(0) + +#define TRGMII_TXCTRL 0x7a40 +#define TRAIN_TXEN BIT(31) +#define TXC_INV BIT(30) +#define TX_DOEO BIT(29) +#define TX_RST BIT(28) + +#define TRGMII_TD0_CTRL 0x7a50 +#define TRGMII_TD1_CTRL 0x7a58 +#define TRGMII_TD2_CTRL 0x7a60 +#define TRGMII_TD3_CTRL 0x7a68 +#define TRGMII_TXCTL_CTRL 0x7a70 +#define TRGMII_TCK_CTRL 0x7a78 +#define TRGMII_TD_CTRL(n) (0x7a50 + (n) * 8) +#define NUM_TRGMII_CTRL 6 +#define TX_DMPEDRV BIT(31) +#define TX_DM_SR BIT(15) +#define TX_DMERODT BIT(14) +#define TX_DMOECTL BIT(13) +#define TX_TAP_S 8 +#define TX_TAP_M 0xf00 +#define TX_TRAIN_WD_S 0 +#define TX_TRAIN_WD_M 0xff + +#define TRGMII_TD0_ODT 0x7a54 +#define TRGMII_TD1_ODT 0x7a5c +#define TRGMII_TD2_ODT 0x7a64 +#define TRGMII_TD3_ODT 0x7a6c +#define TRGMII_TXCTL_ODT 0x7574 +#define TRGMII_TCK_ODT 0x757c +#define TRGMII_TD_ODT(n) (0x7a54 + (n) * 8) +#define NUM_TRGMII_ODT 6 +#define TX_DM_DRVN_PRE_S 30 +#define TX_DM_DRVN_PRE_M 0xc0000000 +#define TX_DM_DRVP_PRE_S 28 +#define TX_DM_DRVP_PRE_M 0x30000000 +#define TX_DM_TDSEL_S 24 +#define TX_DM_TDSEL_M 0xf000000 +#define TX_ODTEN BIT(23) +#define TX_DME_PRE BIT(20) +#define TX_DM_DRVNT0 BIT(19) +#define TX_DM_DRVPT0 BIT(18) +#define TX_DM_DRVNTE BIT(17) +#define TX_DM_DRVPTE BIT(16) +#define TX_DM_ODTN_S 12 +#define TX_DM_ODTN_M 0x7000 +#define TX_DM_ODTP_S 8 +#define TX_DM_ODTP_M 0x700 +#define TX_DM_DRVN_S 4 +#define TX_DM_DRVN_M 0xf0 +#define TX_DM_DRVP_S 0 +#define TX_DM_DRVP_M 0x0f + +#define P5RGMIIRXCR 0x7b00 +#define CSR_RGMII_RCTL_CFG_S 24 +#define CSR_RGMII_RCTL_CFG_M 0x7000000 +#define CSR_RGMII_RXD_CFG_S 16 +#define CSR_RGMII_RXD_CFG_M 0x70000 +#define CSR_RGMII_EDGE_ALIGN BIT(8) +#define CSR_RGMII_RXC_90DEG_CFG_S 4 +#define CSR_RGMII_RXC_90DEG_CFG_M 0xf0 +#define CSR_RGMII_RXC_0DEG_CFG_S 0 +#define CSR_RGMII_RXC_0DEG_CFG_M 0x0f + +#define P5RGMIITXCR 0x7b04 +#define CSR_RGMII_TXEN_CFG_S 16 +#define CSR_RGMII_TXEN_CFG_M 0x70000 +#define CSR_RGMII_TXD_CFG_S 8 +#define CSR_RGMII_TXD_CFG_M 0x700 +#define CSR_RGMII_TXC_CFG_S 0 +#define CSR_RGMII_TXC_CFG_M 0x1f + +#define CHIP_REV 0x7ffc +#define CHIP_NAME_S 16 +#define CHIP_NAME_M 0xffff0000 +#define CHIP_REV_S 0 +#define CHIP_REV_M 0x0f + +/* MMD registers */ +#define CORE_PLL_GROUP2 0x401 +#define RG_SYSPLL_EN_NORMAL BIT(15) +#define RG_SYSPLL_VODEN BIT(14) +#define RG_SYSPLL_POSDIV_S 5 +#define RG_SYSPLL_POSDIV_M 0x60 + +#define CORE_PLL_GROUP4 0x403 +#define RG_SYSPLL_DDSFBK_EN BIT(12) +#define RG_SYSPLL_BIAS_EN BIT(11) +#define RG_SYSPLL_BIAS_LPF_EN BIT(10) + +#define CORE_PLL_GROUP5 0x404 +#define RG_LCDDS_PCW_NCPO1_S 0 +#define RG_LCDDS_PCW_NCPO1_M 0xffff + +#define CORE_PLL_GROUP6 0x405 +#define RG_LCDDS_PCW_NCPO0_S 0 +#define RG_LCDDS_PCW_NCPO0_M 0xffff + +#define CORE_PLL_GROUP7 0x406 +#define RG_LCDDS_PWDB BIT(15) +#define RG_LCDDS_ISO_EN BIT(13) +#define RG_LCCDS_C_S 4 +#define RG_LCCDS_C_M 0x70 +#define RG_LCDDS_PCW_NCPO_CHG BIT(3) + +#define CORE_PLL_GROUP10 0x409 +#define RG_LCDDS_SSC_DELTA_S 0 +#define RG_LCDDS_SSC_DELTA_M 0xfff + +#define CORE_PLL_GROUP11 0x40a +#define RG_LCDDS_SSC_DELTA1_S 0 +#define RG_LCDDS_SSC_DELTA1_M 0xfff + +#define CORE_GSWPLL_GCR_1 0x040d +#define GSWPLL_PREDIV_S 14 +#define GSWPLL_PREDIV_M 0xc000 +#define GSWPLL_POSTDIV_200M_S 12 +#define GSWPLL_POSTDIV_200M_M 0x3000 +#define GSWPLL_EN_PRE BIT(11) +#define GSWPLL_FBKSEL BIT(10) +#define GSWPLL_BP BIT(9) +#define GSWPLL_BR BIT(8) +#define GSWPLL_FBKDIV_200M_S 0 +#define GSWPLL_FBKDIV_200M_M 0xff + +#define CORE_GSWPLL_GCR_2 0x040e +#define GSWPLL_POSTDIV_500M_S 8 +#define GSWPLL_POSTDIV_500M_M 0x300 +#define GSWPLL_FBKDIV_500M_S 0 +#define GSWPLL_FBKDIV_500M_M 0xff + +#define TRGMII_GSW_CLK_CG 0x0410 +#define TRGMIICK_EN BIT(1) +#define GSWCK_EN BIT(0) + +static int mt7530_mii_read(struct gsw_mt753x *gsw, int phy, int reg) +{ + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + return mdiobus_read(gsw->host_bus, phy, reg); +} + +static void mt7530_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val) +{ + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + mdiobus_write(gsw->host_bus, phy, reg, val); +} + +static int mt7530_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg) +{ + u16 val; + + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + val = gsw->host_bus->read(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG); + + mutex_unlock(&gsw->host_bus->mdio_lock); + + return val; +} + +static void mt7530_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, + u16 reg, u16 val) +{ + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, val); + + mutex_unlock(&gsw->host_bus->mdio_lock); +} + +static void mt7530_core_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val) +{ + gsw->mmd_write(gsw, 0, 0x1f, reg, val); +} + +static void mt7530_trgmii_setting(struct gsw_mt753x *gsw) +{ + u16 i; + + mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0780); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); + + /* PLL BIAS enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, + RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN); + mdelay(1); + + /* PLL LPF enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, + RG_SYSPLL_DDSFBK_EN | + RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); + + /* sys PLL enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP2, + RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | + (1 << RG_SYSPLL_POSDIV_S)); + + /* LCDDDS PWDS */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP7, + (3 << RG_LCCDS_C_S) | + RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); + mdelay(1); + + /* Enable MT7530 TRGMII clock */ + mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN | TRGMIICK_EN); + + /* lower Tx Driving */ + for (i = 0 ; i < NUM_TRGMII_ODT; i++) + mt753x_reg_write(gsw, TRGMII_TD_ODT(i), + (4 << TX_DM_DRVP_S) | (4 << TX_DM_DRVN_S)); +} + +static void mt7530_rgmii_setting(struct gsw_mt753x *gsw) +{ + u32 val; + + mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0c80); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); + + val = mt753x_reg_read(gsw, TRGMII_TXCTRL); + val &= ~TXC_INV; + mt753x_reg_write(gsw, TRGMII_TXCTRL, val); + + mt753x_reg_write(gsw, TRGMII_TCK_CTRL, + (8 << TX_TAP_S) | (0x55 << TX_TRAIN_WD_S)); +} + +static int mt7530_mac_port_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap, p6ecr = 0, p5mcr, p6mcr, phyad; + + hwstrap = mt753x_reg_read(gsw, MHWSTRAP); + hwstrap &= ~(P6_INTF_DIS | P5_INTF_MODE_RGMII | P5_INTF_DIS_S); + hwstrap |= P5_INTF_SEL_GMAC5; + if (!gsw->port5_cfg.enabled) { + p5mcr = FORCE_MODE; + hwstrap |= P5_INTF_DIS_S; + } else { + p5mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + MAC_MODE | MAC_TX_EN | MAC_RX_EN | + BKOFF_EN | BACKPR_EN; + + if (gsw->port5_cfg.force_link) { + p5mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC | + FORCE_TX_FC; + p5mcr |= gsw->port5_cfg.speed << FORCE_SPD_S; + + if (gsw->port5_cfg.duplex) + p5mcr |= FORCE_DPX; + } + + switch (gsw->port5_cfg.phy_mode) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_GMII: + break; + case PHY_INTERFACE_MODE_RGMII: + hwstrap |= P5_INTF_MODE_RGMII; + break; + default: + dev_info(gsw->dev, "%s is not supported by port5\n", + phy_modes(gsw->port5_cfg.phy_mode)); + p5mcr = FORCE_MODE; + hwstrap |= P5_INTF_DIS_S; + } + + /* Port5 to PHY direct mode */ + if (of_property_read_u32(gsw->port5_cfg.np, "phy-address", + &phyad)) + goto parse_p6; + + if (phyad != 0 && phyad != 4) { + dev_info(gsw->dev, + "Only PHY 0/4 can be connected to Port 5\n"); + goto parse_p6; + } + + hwstrap &= ~P5_INTF_SEL_GMAC5; + if (phyad == 0) + hwstrap |= P5_PHY0_SEL; + else + hwstrap &= ~P5_PHY0_SEL; + } + +parse_p6: + if (!gsw->port6_cfg.enabled) { + p6mcr = FORCE_MODE; + hwstrap |= P6_INTF_DIS; + } else { + p6mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + MAC_MODE | MAC_TX_EN | MAC_RX_EN | + BKOFF_EN | BACKPR_EN; + + if (gsw->port6_cfg.force_link) { + p6mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC | + FORCE_TX_FC; + p6mcr |= gsw->port6_cfg.speed << FORCE_SPD_S; + + if (gsw->port6_cfg.duplex) + p6mcr |= FORCE_DPX; + } + + switch (gsw->port6_cfg.phy_mode) { + case PHY_INTERFACE_MODE_RGMII: + p6ecr = BIT(1); + break; + case PHY_INTERFACE_MODE_TRGMII: + /* set MT7530 central align */ + p6ecr = BIT(0); + break; + default: + dev_info(gsw->dev, "%s is not supported by port6\n", + phy_modes(gsw->port6_cfg.phy_mode)); + p6mcr = FORCE_MODE; + hwstrap |= P6_INTF_DIS; + } + } + + mt753x_reg_write(gsw, MHWSTRAP, hwstrap); + mt753x_reg_write(gsw, P6ECR, p6ecr); + + mt753x_reg_write(gsw, PMCR(5), p5mcr); + mt753x_reg_write(gsw, PMCR(6), p6mcr); + + return 0; +} + +static void mt7530_core_pll_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap; + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + + switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { + case XTAL_40MHZ: + /* Disable MT7530 core clock */ + mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, 0); + + /* disable MT7530 PLL */ + mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1, + (2 << GSWPLL_POSTDIV_200M_S) | + (32 << GSWPLL_FBKDIV_200M_S)); + + /* For MT7530 core clock = 500Mhz */ + mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_2, + (1 << GSWPLL_POSTDIV_500M_S) | + (25 << GSWPLL_FBKDIV_500M_S)); + + /* Enable MT7530 PLL */ + mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1, + (2 << GSWPLL_POSTDIV_200M_S) | + (32 << GSWPLL_FBKDIV_200M_S) | + GSWPLL_EN_PRE); + + usleep_range(20, 40); + + /* Enable MT7530 core clock */ + mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN); + break; + default: + /* TODO: PLL settings for 20/25MHz */ + break; + } + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + hwstrap |= CHG_TRAP; + if (gsw->direct_phy_access) + hwstrap &= ~C_MDIO_BPS_S; + else + hwstrap |= C_MDIO_BPS_S; + + mt753x_reg_write(gsw, MHWSTRAP, hwstrap); + + if (gsw->port6_cfg.enabled && + gsw->port6_cfg.phy_mode == PHY_INTERFACE_MODE_TRGMII) { + mt7530_trgmii_setting(gsw); + } else { + /* RGMII */ + mt7530_rgmii_setting(gsw); + } + + /* delay setting for 10/1000M */ + mt753x_reg_write(gsw, P5RGMIIRXCR, + CSR_RGMII_EDGE_ALIGN | + (2 << CSR_RGMII_RXC_0DEG_CFG_S)); + mt753x_reg_write(gsw, P5RGMIITXCR, 0x14 << CSR_RGMII_TXC_CFG_S); +} + +static int mt7530_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev) +{ + u32 rev; + + rev = mt753x_reg_read(gsw, CHIP_REV); + + if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7530) { + if (crev) { + crev->rev = rev & CHIP_REV_M; + crev->name = "MT7530"; + } + + return 0; + } + + return -ENODEV; +} + +static void mt7530_phy_setting(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + /* Disable EEE */ + gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0); + + /* Enable HW auto downshift */ + gsw->mii_write(gsw, i, 0x1f, 0x1); + val = gsw->mii_read(gsw, i, PHY_EXT_REG_14); + val |= PHY_EN_DOWN_SHFIT; + gsw->mii_write(gsw, i, PHY_EXT_REG_14, val); + + /* Increase SlvDPSready time */ + gsw->mii_write(gsw, i, 0x1f, 0x52b5); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae); + gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae); + + /* Increase post_update_timer */ + gsw->mii_write(gsw, i, 0x1f, 0x3); + gsw->mii_write(gsw, i, PHY_LPI_REG_11, 0x4b); + gsw->mii_write(gsw, i, 0x1f, 0); + + /* Adjust 100_mse_threshold */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff); + + /* Disable mcc */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300); + } +} + +static inline bool get_phy_access_mode(const struct device_node *np) +{ + return of_property_read_bool(np, "mt7530,direct-phy-access"); +} + +static int mt7530_sw_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + gsw->direct_phy_access = get_phy_access_mode(gsw->dev->of_node); + + /* Force MT7530 to use (in)direct PHY access */ + val = mt753x_reg_read(gsw, HWSTRAP); + val |= CHG_TRAP; + if (gsw->direct_phy_access) + val &= ~C_MDIO_BPS_S; + else + val |= C_MDIO_BPS_S; + mt753x_reg_write(gsw, MHWSTRAP, val); + + /* Read PHY address base from HWSTRAP */ + gsw->phy_base = (((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3) + 8; + gsw->phy_base &= MT753X_SMI_ADDR_MASK; + + if (gsw->direct_phy_access) { + gsw->mii_read = mt7530_mii_read; + gsw->mii_write = mt7530_mii_write; + gsw->mmd_read = mt7530_mmd_read; + gsw->mmd_write = mt7530_mmd_write; + } else { + gsw->mii_read = mt753x_mii_read; + gsw->mii_write = mt753x_mii_write; + gsw->mmd_read = mt753x_mmd_ind_read; + gsw->mmd_write = mt753x_mmd_ind_write; + } + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val |= BMCR_PDOWN; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + /* Force MAC link down before reset */ + mt753x_reg_write(gsw, PMCR(5), FORCE_MODE); + mt753x_reg_write(gsw, PMCR(6), FORCE_MODE); + + /* Switch soft reset */ + /* BUG: sw reset causes gsw int flooding */ + mt753x_reg_write(gsw, SYS_CTRL, SW_PHY_RST | SW_SYS_RST | SW_REG_RST); + usleep_range(10, 20); + + /* global mac control settings configuration */ + mt753x_reg_write(gsw, GMACCR, + LATE_COL_DROP | (15 << MTCC_LMT_S) | + (2 << MAX_RX_JUMBO_S) | RX_PKT_LEN_MAX_JUMBO); + + mt7530_core_pll_setup(gsw); + mt7530_mac_port_setup(gsw); + + return 0; +} + +static int mt7530_sw_post_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + mt7530_phy_setting(gsw); + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val &= ~BMCR_PDOWN; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + return 0; +} + +struct mt753x_sw_id mt7530_id = { + .model = MT7530, + .detect = mt7530_sw_detect, + .init = mt7530_sw_init, + .post_init = mt7530_sw_post_init +}; diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.h new file mode 100755 index 00000000..40243d4e --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7530.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#ifndef _MT7530_H_ +#define _MT7530_H_ + +#include "mt753x.h" + +extern struct mt753x_sw_id mt7530_id; + +#endif /* _MT7530_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.c new file mode 100755 index 00000000..7ebf09c1 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.c @@ -0,0 +1,918 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Zhanguo Ju + */ + +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_regs.h" + +/* MT7531 registers */ +#define SGMII_REG_BASE 0x5000 +#define SGMII_REG_PORT_BASE 0x1000 +#define SGMII_REG(p, r) (SGMII_REG_BASE + \ + (p) * SGMII_REG_PORT_BASE + (r)) +#define PCS_CONTROL_1(p) SGMII_REG(p, 0x00) +#define SGMII_MODE(p) SGMII_REG(p, 0x20) +#define QPHY_PWR_STATE_CTRL(p) SGMII_REG(p, 0xe8) +#define PHYA_CTRL_SIGNAL3(p) SGMII_REG(p, 0x128) + +/* Fields of PCS_CONTROL_1 */ +#define SGMII_LINK_STATUS BIT(18) +#define SGMII_AN_ENABLE BIT(12) +#define SGMII_AN_RESTART BIT(9) + +/* Fields of SGMII_MODE */ +#define SGMII_REMOTE_FAULT_DIS BIT(8) +#define SGMII_IF_MODE_FORCE_DUPLEX BIT(4) +#define SGMII_IF_MODE_FORCE_SPEED_S 0x2 +#define SGMII_IF_MODE_FORCE_SPEED_M 0x0c +#define SGMII_IF_MODE_ADVERT_AN BIT(1) + +/* Values of SGMII_IF_MODE_FORCE_SPEED */ +#define SGMII_IF_MODE_FORCE_SPEED_10 0 +#define SGMII_IF_MODE_FORCE_SPEED_100 1 +#define SGMII_IF_MODE_FORCE_SPEED_1000 2 + +/* Fields of QPHY_PWR_STATE_CTRL */ +#define PHYA_PWD BIT(4) + +/* Fields of PHYA_CTRL_SIGNAL3 */ +#define RG_TPHY_SPEED_S 2 +#define RG_TPHY_SPEED_M 0x0c + +/* Values of RG_TPHY_SPEED */ +#define RG_TPHY_SPEED_1000 0 +#define RG_TPHY_SPEED_2500 1 + +/* Unique fields of (M)HWSTRAP for MT7531 */ +#define XTAL_FSEL_S 7 +#define XTAL_FSEL_M BIT(7) +#define PHY_EN BIT(6) +#define CHG_STRAP BIT(8) + +/* Efuse Register Define */ +#define GBE_EFUSE 0x7bc8 +#define GBE_SEL_EFUSE_EN BIT(0) + +/* PHY ENABLE Register bitmap define */ +#define PHY_DEV1F 0x1f +#define PHY_DEV1F_REG_44 0x44 +#define PHY_DEV1F_REG_104 0x104 +#define PHY_DEV1F_REG_10A 0x10a +#define PHY_DEV1F_REG_10B 0x10b +#define PHY_DEV1F_REG_10C 0x10c +#define PHY_DEV1F_REG_10D 0x10d +#define PHY_DEV1F_REG_268 0x268 +#define PHY_DEV1F_REG_269 0x269 +#define PHY_DEV1F_REG_403 0x403 + +/* Fields of PHY_DEV1F_REG_403 */ +#define GBE_EFUSE_SETTING BIT(3) +#define PHY_EN_BYPASS_MODE BIT(4) +#define POWER_ON_OFF BIT(5) +#define PHY_PLL_M GENMASK(9, 8) +#define PHY_PLL_SEL(x) (((x) << 8) & GENMASK(9, 8)) + +/* PHY EEE Register bitmap of define */ +#define PHY_DEV07 0x07 +#define PHY_DEV07_REG_03C 0x3c + +/* PHY Extend Register 0x14 bitmap of define */ +#define PHY_EXT_REG_14 0x14 + +/* Fields of PHY_EXT_REG_14 */ +#define PHY_EN_DOWN_SHFIT BIT(4) + +/* PHY Extend Register 0x17 bitmap of define */ +#define PHY_EXT_REG_17 0x17 + +/* Fields of PHY_EXT_REG_17 */ +#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4) + +/* PHY Token Ring Register 0x10 bitmap of define */ +#define PHY_TR_REG_10 0x10 + +/* PHY Token Ring Register 0x12 bitmap of define */ +#define PHY_TR_REG_12 0x12 + +/* PHY DEV 0x1e Register bitmap of define */ +#define PHY_DEV1E 0x1e +#define PHY_DEV1E_REG_13 0x13 +#define PHY_DEV1E_REG_14 0x14 +#define PHY_DEV1E_REG_41 0x41 +#define PHY_DEV1E_REG_A6 0xa6 +#define PHY_DEV1E_REG_0C6 0x0c6 +#define PHY_DEV1E_REG_0FE 0x0fe +#define PHY_DEV1E_REG_123 0x123 +#define PHY_DEV1E_REG_189 0x189 + +/* Fields of PHY_DEV1E_REG_0C6 */ +#define PHY_POWER_SAVING_S 8 +#define PHY_POWER_SAVING_M 0x300 +#define PHY_POWER_SAVING_TX 0x0 + +/* Fields of PHY_DEV1E_REG_189 */ +#define DESCRAMBLER_CLEAR_EN 0x1 + +/* Values of XTAL_FSEL_S */ +#define XTAL_40MHZ 0 +#define XTAL_25MHZ 1 + +#define PLLGP_EN 0x7820 +#define EN_COREPLL BIT(2) +#define SW_CLKSW BIT(1) +#define SW_PLLGP BIT(0) + +#define PLLGP_CR0 0x78a8 +#define RG_COREPLL_EN BIT(22) +#define RG_COREPLL_POSDIV_S 23 +#define RG_COREPLL_POSDIV_M 0x3800000 +#define RG_COREPLL_SDM_PCW_S 1 +#define RG_COREPLL_SDM_PCW_M 0x3ffffe +#define RG_COREPLL_SDM_PCW_CHG BIT(0) + +/* TOP Signals Status Register */ +#define TOP_SIG_SR 0x780c +#define PAD_DUAL_SGMII_EN BIT(1) + +/* RGMII and SGMII PLL clock */ +#define ANA_PLLGP_CR2 0x78b0 +#define ANA_PLLGP_CR5 0x78bc + +/* GPIO mode define */ +#define GPIO_MODE_REGS(x) (0x7c0c + (((x) / 8) * 4)) +#define GPIO_MODE_S 4 + +/* GPIO GROUP IOLB SMT0 Control */ +#define SMT0_IOLB 0x7f04 +#define SMT_IOLB_5_SMI_MDC_EN BIT(5) + +/* Unique fields of PMCR for MT7531 */ +#define FORCE_MODE_EEE1G BIT(25) +#define FORCE_MODE_EEE100 BIT(26) +#define FORCE_MODE_TX_FC BIT(27) +#define FORCE_MODE_RX_FC BIT(28) +#define FORCE_MODE_DPX BIT(29) +#define FORCE_MODE_SPD BIT(30) +#define FORCE_MODE_LNK BIT(31) +#define FORCE_MODE BIT(15) + +#define CHIP_REV 0x781C +#define CHIP_NAME_S 16 +#define CHIP_NAME_M 0xffff0000 +#define CHIP_REV_S 0 +#define CHIP_REV_M 0x0f +#define CHIP_REV_E1 0x0 + +#define CLKGEN_CTRL 0x7500 +#define CLK_SKEW_OUT_S 8 +#define CLK_SKEW_OUT_M 0x300 +#define CLK_SKEW_IN_S 6 +#define CLK_SKEW_IN_M 0xc0 +#define RXCLK_NO_DELAY BIT(5) +#define TXCLK_NO_REVERSE BIT(4) +#define GP_MODE_S 1 +#define GP_MODE_M 0x06 +#define GP_CLK_EN BIT(0) + +/* Values of GP_MODE */ +#define GP_MODE_RGMII 0 +#define GP_MODE_MII 1 +#define GP_MODE_REV_MII 2 + +/* Values of CLK_SKEW_IN */ +#define CLK_SKEW_IN_NO_CHANGE 0 +#define CLK_SKEW_IN_DELAY_100PPS 1 +#define CLK_SKEW_IN_DELAY_200PPS 2 +#define CLK_SKEW_IN_REVERSE 3 + +/* Values of CLK_SKEW_OUT */ +#define CLK_SKEW_OUT_NO_CHANGE 0 +#define CLK_SKEW_OUT_DELAY_100PPS 1 +#define CLK_SKEW_OUT_DELAY_200PPS 2 +#define CLK_SKEW_OUT_REVERSE 3 + +/* Proprietory Control Register of Internal Phy device 0x1e */ +#define RXADC_CONTROL_3 0xc2 +#define RXADC_LDO_CONTROL_2 0xd3 + +/* Proprietory Control Register of Internal Phy device 0x1f */ +#define TXVLD_DA_271 0x271 +#define TXVLD_DA_272 0x272 +#define TXVLD_DA_273 0x273 + +/* DSP Channel and NOD_ADDR*/ +#define DSP_CH 0x2 +#define DSP_NOD_ADDR 0xD + +/* gpio pinmux pins and functions define */ +static int gpio_int_pins[] = {0}; +static int gpio_int_funcs[] = {1}; +static int gpio_mdc_pins[] = {11, 20}; +static int gpio_mdc_funcs[] = {2, 2}; +static int gpio_mdio_pins[] = {12, 21}; +static int gpio_mdio_funcs[] = {2, 2}; + +static int mt7531_set_port_sgmii_force_mode(struct gsw_mt753x *gsw, u32 port, + struct mt753x_port_cfg *port_cfg) +{ + u32 speed, port_base, val; + ktime_t timeout; + u32 timeout_us; + + if (port < 5 || port >= MT753X_NUM_PORTS) { + dev_info(gsw->dev, "port %d is not a SGMII port\n", port); + return -EINVAL; + } + + port_base = port - 5; + + switch (port_cfg->speed) { + case MAC_SPD_1000: + speed = RG_TPHY_SPEED_1000; + break; + case MAC_SPD_2500: + speed = RG_TPHY_SPEED_2500; + break; + default: + dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n", + port_cfg->speed, port); + + speed = RG_TPHY_SPEED_1000; + } + + /* Step 1: Speed select register setting */ + val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base)); + val &= ~RG_TPHY_SPEED_M; + val |= speed << RG_TPHY_SPEED_S; + mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val); + + /* Step 2 : Disable AN */ + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base)); + val &= ~SGMII_AN_ENABLE; + mt753x_reg_write(gsw, PCS_CONTROL_1(port_base), val); + + /* Step 3: SGMII force mode setting */ + val = mt753x_reg_read(gsw, SGMII_MODE(port_base)); + val &= ~SGMII_IF_MODE_ADVERT_AN; + val &= ~SGMII_IF_MODE_FORCE_SPEED_M; + val |= SGMII_IF_MODE_FORCE_SPEED_1000 << SGMII_IF_MODE_FORCE_SPEED_S; + val |= SGMII_IF_MODE_FORCE_DUPLEX; + /* For sgmii force mode, 0 is full duplex and 1 is half duplex */ + if (port_cfg->duplex) + val &= ~SGMII_IF_MODE_FORCE_DUPLEX; + + mt753x_reg_write(gsw, SGMII_MODE(port_base), val); + + /* Step 4: XXX: Disable Link partner's AN and set force mode */ + + /* Step 5: XXX: Special setting for PHYA ==> reserved for flexible */ + + /* Step 6 : Release PHYA power down state */ + val = mt753x_reg_read(gsw, QPHY_PWR_STATE_CTRL(port_base)); + val &= ~PHYA_PWD; + mt753x_reg_write(gsw, QPHY_PWR_STATE_CTRL(port_base), val); + + /* Step 7 : Polling SGMII_LINK_STATUS */ + timeout_us = 2000000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base)); + val &= SGMII_LINK_STATUS; + + if (val) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + return 0; +} + +static int mt7531_set_port_sgmii_an_mode(struct gsw_mt753x *gsw, u32 port, + struct mt753x_port_cfg *port_cfg) +{ + u32 speed, port_base, val; + ktime_t timeout; + u32 timeout_us; + + if (port < 5 || port >= MT753X_NUM_PORTS) { + dev_info(gsw->dev, "port %d is not a SGMII port\n", port); + return -EINVAL; + } + + port_base = port - 5; + + switch (port_cfg->speed) { + case MAC_SPD_1000: + speed = RG_TPHY_SPEED_1000; + break; + case MAC_SPD_2500: + speed = RG_TPHY_SPEED_2500; + break; + default: + dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n", + port_cfg->speed, port); + + speed = RG_TPHY_SPEED_1000; + } + + /* Step 1: Speed select register setting */ + val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base)); + val &= ~RG_TPHY_SPEED_M; + val |= speed << RG_TPHY_SPEED_S; + mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val); + + /* Step 2: Remote fault disable */ + val = mt753x_reg_read(gsw, SGMII_MODE(port)); + val |= SGMII_REMOTE_FAULT_DIS; + mt753x_reg_write(gsw, SGMII_MODE(port), val); + + /* Step 3: Setting Link partner's AN enable = 1 */ + + /* Step 4: Setting Link partner's device ability for speed/duplex */ + + /* Step 5: AN re-start */ + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port)); + val |= SGMII_AN_RESTART; + mt753x_reg_write(gsw, PCS_CONTROL_1(port), val); + + /* Step 6: Special setting for PHYA ==> reserved for flexible */ + + /* Step 7 : Polling SGMII_LINK_STATUS */ + timeout_us = 2000000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base)); + val &= SGMII_LINK_STATUS; + + if (val) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + return 0; +} + +static int mt7531_set_port_rgmii(struct gsw_mt753x *gsw, u32 port) +{ + u32 val; + + if (port != 5) { + dev_info(gsw->dev, "RGMII mode is not available for port %d\n", + port); + return -EINVAL; + } + + val = mt753x_reg_read(gsw, CLKGEN_CTRL); + val |= GP_CLK_EN; + val &= ~GP_MODE_M; + val |= GP_MODE_RGMII << GP_MODE_S; + val |= TXCLK_NO_REVERSE; + val |= RXCLK_NO_DELAY; + val &= ~CLK_SKEW_IN_M; + val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S; + val &= ~CLK_SKEW_OUT_M; + val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S; + mt753x_reg_write(gsw, CLKGEN_CTRL, val); + + return 0; +} + +static int mt7531_mac_port_setup(struct gsw_mt753x *gsw, u32 port, + struct mt753x_port_cfg *port_cfg) +{ + u32 pmcr; + u32 speed; + + if (port < 5 || port >= MT753X_NUM_PORTS) { + dev_info(gsw->dev, "port %d is not a MAC port\n", port); + return -EINVAL; + } + + if (port_cfg->enabled) { + pmcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + MAC_MODE | MAC_TX_EN | MAC_RX_EN | + BKOFF_EN | BACKPR_EN; + + if (port_cfg->force_link) { + /* PMCR's speed field 0x11 is reserved, + * sw should set 0x10 + */ + speed = port_cfg->speed; + if (port_cfg->speed == MAC_SPD_2500) + speed = MAC_SPD_1000; + + pmcr |= FORCE_MODE_LNK | FORCE_LINK | + FORCE_MODE_SPD | FORCE_MODE_DPX | + FORCE_MODE_RX_FC | FORCE_MODE_TX_FC | + FORCE_RX_FC | FORCE_TX_FC | + (speed << FORCE_SPD_S); + + if (port_cfg->duplex) + pmcr |= FORCE_DPX; + } + } else { + pmcr = FORCE_MODE_LNK; + } + + switch (port_cfg->phy_mode) { + case PHY_INTERFACE_MODE_RGMII: + mt7531_set_port_rgmii(gsw, port); + break; + case PHY_INTERFACE_MODE_SGMII: + if (port_cfg->force_link) + mt7531_set_port_sgmii_force_mode(gsw, port, port_cfg); + else + mt7531_set_port_sgmii_an_mode(gsw, port, port_cfg); + break; + default: + if (port_cfg->enabled) + dev_info(gsw->dev, "%s is not supported by port %d\n", + phy_modes(port_cfg->phy_mode), port); + + pmcr = FORCE_MODE_LNK; + } + + mt753x_reg_write(gsw, PMCR(port), pmcr); + + return 0; +} + +static void mt7531_core_pll_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap; + u32 val; + + val = mt753x_reg_read(gsw, TOP_SIG_SR); + if (val & PAD_DUAL_SGMII_EN) + return; + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + + switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { + case XTAL_25MHZ: + /* Step 1 : Disable MT7531 COREPLL */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val &= ~EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 2: switch to XTAL output */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_CLKSW; + mt753x_reg_write(gsw, PLLGP_EN, val); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Step 3: disable PLLGP and enable program PLLGP */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_PLLGP; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 4: program COREPLL output frequency to 500MHz */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_POSDIV_M; + val |= 2 << RG_COREPLL_POSDIV_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + usleep_range(25, 35); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_M; + val |= 0x140000 << RG_COREPLL_SDM_PCW_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Set feedback divide ratio update signal to high */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + /* Wait for at least 16 XTAL clocks */ + usleep_range(10, 20); + + /* Step 5: set feedback divide ratio update signal to low */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Enable 325M clock for SGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000); + + /* Enable 250SSC clock for RGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000); + + /* Step 6: Enable MT7531 PLL */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + usleep_range(25, 35); + + break; + case XTAL_40MHZ: + /* Step 1 : Disable MT7531 COREPLL */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val &= ~EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 2: switch to XTAL output */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_CLKSW; + mt753x_reg_write(gsw, PLLGP_EN, val); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Step 3: disable PLLGP and enable program PLLGP */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_PLLGP; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 4: program COREPLL output frequency to 500MHz */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_POSDIV_M; + val |= 2 << RG_COREPLL_POSDIV_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + usleep_range(25, 35); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_M; + val |= 0x190000 << RG_COREPLL_SDM_PCW_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Set feedback divide ratio update signal to high */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + /* Wait for at least 16 XTAL clocks */ + usleep_range(10, 20); + + /* Step 5: set feedback divide ratio update signal to low */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Enable 325M clock for SGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000); + + /* Enable 250SSC clock for RGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000); + + /* Step 6: Enable MT7531 PLL */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + usleep_range(25, 35); + break; + } +} + +static int mt7531_internal_phy_calibration(struct gsw_mt753x *gsw) +{ + return 0; +} + +static int mt7531_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev) +{ + u32 rev, topsig; + + rev = mt753x_reg_read(gsw, CHIP_REV); + + if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7531) { + if (crev) { + topsig = mt753x_reg_read(gsw, TOP_SIG_SR); + + crev->rev = rev & CHIP_REV_M; + crev->name = topsig & PAD_DUAL_SGMII_EN ? + "MT7531AE" : "MT7531BE"; + } + + return 0; + } + + return -ENODEV; +} + +static void pinmux_set_mux_7531(struct gsw_mt753x *gsw, u32 pin, u32 mode) +{ + u32 val; + + val = mt753x_reg_read(gsw, GPIO_MODE_REGS(pin)); + val &= ~(0xf << (pin & 7) * GPIO_MODE_S); + val |= mode << (pin & 7) * GPIO_MODE_S; + mt753x_reg_write(gsw, GPIO_MODE_REGS(pin), val); +} + +static int mt7531_set_gpio_pinmux(struct gsw_mt753x *gsw) +{ + u32 group = 0; + struct device_node *np = gsw->dev->of_node; + + /* Set GPIO 0 interrupt mode */ + pinmux_set_mux_7531(gsw, gpio_int_pins[0], gpio_int_funcs[0]); + + of_property_read_u32(np, "mediatek,mdio_master_pinmux", &group); + + /* group = 0: do nothing, 1: 1st group (AE), 2: 2nd group (BE) */ + if (group > 0 && group <= 2) { + group--; + pinmux_set_mux_7531(gsw, gpio_mdc_pins[group], + gpio_mdc_funcs[group]); + pinmux_set_mux_7531(gsw, gpio_mdio_pins[group], + gpio_mdio_funcs[group]); + } + + return 0; +} + +static void mt7531_phy_pll_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap; + u32 val; + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + + switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { + case XTAL_25MHZ: + /* disable pll auto calibration */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608); + + /* change pll sel */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~(PHY_PLL_M); + val |= PHY_PLL_SEL(3); + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10A, 0x1009); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0x7c6); + + /* capacitance and resistance adjustment */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10C, 0xa8be); + + break; + case XTAL_40MHZ: + /* disable pll auto calibration */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608); + + /* change pll sel */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~(PHY_PLL_M); + val |= PHY_PLL_SEL(3); + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10A, 0x1018); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0xc676); + + /* capacitance and resistance adjustment */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10C, 0xd8be); + break; + } + + /* power down pll. additional delay is not required via mdio access */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x10); + + /* power up pll */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x14); +} + +static void mt7531_phy_setting(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + /* Adjust DAC TX Delay */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_44, 0xc0); + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + /* Disable EEE */ + gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0); + + /* Enable HW auto downshift */ + gsw->mii_write(gsw, i, 0x1f, 0x1); + val = gsw->mii_read(gsw, i, PHY_EXT_REG_14); + val |= PHY_EN_DOWN_SHFIT; + gsw->mii_write(gsw, i, PHY_EXT_REG_14, val); + + /* Increase SlvDPSready time */ + gsw->mii_write(gsw, i, 0x1f, 0x52b5); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae); + gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae); + gsw->mii_write(gsw, i, 0x1f, 0); + + /* Adjust 100_mse_threshold */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff); + + /* Disable mcc */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300); + + /* PHY link down power saving enable */ + val = gsw->mii_read(gsw, i, PHY_EXT_REG_17); + val |= PHY_LINKDOWN_POWER_SAVING_EN; + gsw->mii_write(gsw, i, PHY_EXT_REG_17, val); + + val = gsw->mmd_read(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6); + val &= ~PHY_POWER_SAVING_M; + val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S; + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6, val); + + /* Set TX Pair delay selection */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_13, 0x404); + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_14, 0x404); + } +} + +static void mt7531_adjust_line_driving(struct gsw_mt753x *gsw, u32 port) +{ + /* For ADC timing margin window for LDO calibration */ + gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_LDO_CONTROL_2, 0x2222); + + /* Adjust AD sample timing */ + gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_CONTROL_3, 0x4444); + + /* Adjust Line driver current for different mode */ + gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_271, 0x2ca5); + + /* Adjust Line driver current for different mode */ + gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_272, 0xc6b); + + /* Adjust Line driver amplitude for 10BT */ + gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_273, 0x3000); + + /* Adjust RX Echo path filter */ + gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_0FE, 0x2); + + /* Adjust RX HVGA bias current */ + gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_41, 0x3333); + + /* Adjust TX class AB driver 1 */ + gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x388); + + /* Adjust TX class AB driver 2 */ + gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0x4448); +} + +static void mt7531_eee_setting(struct gsw_mt753x *gsw, u32 port) +{ + u32 tr_reg_control; + u32 val; + + /* Disable generate signal to clear the scramble_lock when lpi mode */ + val = gsw->mmd_read(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189); + val &= ~DESCRAMBLER_CLEAR_EN; + gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189, val); + + /* roll back CR*/ + gsw->mii_write(gsw, port, 0x1f, 0x52b5); + gsw->mmd_write(gsw, port, 0x1e, 0x2d1, 0); + tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) | + (DSP_NOD_ADDR << 7) | (0x8 << 1); + gsw->mii_write(gsw, port, 17, 0x1b); + gsw->mii_write(gsw, port, 18, 0); + gsw->mii_write(gsw, port, 16, tr_reg_control); + tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) | + (DSP_NOD_ADDR << 7) | (0xf << 1); + gsw->mii_write(gsw, port, 17, 0); + gsw->mii_write(gsw, port, 18, 0); + gsw->mii_write(gsw, port, 16, tr_reg_control); + + tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) | + (DSP_NOD_ADDR << 7) | (0x10 << 1); + gsw->mii_write(gsw, port, 17, 0x500); + gsw->mii_write(gsw, port, 18, 0); + gsw->mii_write(gsw, port, 16, tr_reg_control); + gsw->mii_write(gsw, port, 0x1f, 0); +} + +static int mt7531_sw_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + gsw->phy_base = (gsw->smi_addr + 1) & MT753X_SMI_ADDR_MASK; + + gsw->mii_read = mt753x_mii_read; + gsw->mii_write = mt753x_mii_write; + gsw->mmd_read = mt753x_mmd_read; + gsw->mmd_write = mt753x_mmd_write; + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val |= BMCR_ISOLATE; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + /* Force MAC link down before reset */ + mt753x_reg_write(gsw, PMCR(5), FORCE_MODE_LNK); + mt753x_reg_write(gsw, PMCR(6), FORCE_MODE_LNK); + + /* Switch soft reset */ + mt753x_reg_write(gsw, SYS_CTRL, SW_SYS_RST | SW_REG_RST); + usleep_range(10, 20); + + /* Enable MDC input Schmitt Trigger */ + val = mt753x_reg_read(gsw, SMT0_IOLB); + mt753x_reg_write(gsw, SMT0_IOLB, val | SMT_IOLB_5_SMI_MDC_EN); + + /* Set 7531 gpio pinmux */ + mt7531_set_gpio_pinmux(gsw); + + /* Global mac control settings */ + mt753x_reg_write(gsw, GMACCR, + (15 << MTCC_LMT_S) | (11 << MAX_RX_JUMBO_S) | + RX_PKT_LEN_MAX_JUMBO); + + mt7531_core_pll_setup(gsw); + mt7531_mac_port_setup(gsw, 5, &gsw->port5_cfg); + mt7531_mac_port_setup(gsw, 6, &gsw->port6_cfg); + + return 0; +} + +static int mt7531_sw_post_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + mt7531_phy_pll_setup(gsw); + + /* Internal PHYs are disabled by default. SW should enable them. + * Note that this may already be enabled in bootloader stage. + */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403); + val |= PHY_EN_BYPASS_MODE; + val &= ~POWER_ON_OFF; + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + mt7531_phy_setting(gsw); + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val &= ~BMCR_ISOLATE; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + for (i = 0; i < MT753X_NUM_PHYS; i++) + mt7531_adjust_line_driving(gsw, i); + + for (i = 0; i < MT753X_NUM_PHYS; i++) + mt7531_eee_setting(gsw, i); + + val = mt753x_reg_read(gsw, CHIP_REV); + val &= CHIP_REV_M; + if (val == CHIP_REV_E1) { + mt7531_internal_phy_calibration(gsw); + } else { + val = mt753x_reg_read(gsw, GBE_EFUSE); + if (val & GBE_SEL_EFUSE_EN) { + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~GBE_EFUSE_SETTING; + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, + val); + } else { + mt7531_internal_phy_calibration(gsw); + } + } + + return 0; +} + +struct mt753x_sw_id mt7531_id = { + .model = MT7531, + .detect = mt7531_sw_detect, + .init = mt7531_sw_init, + .post_init = mt7531_sw_post_init +}; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Zhanguo Ju "); +MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch"); diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.h new file mode 100755 index 00000000..52c8a49f --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt7531.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#ifndef _MT7531_H_ +#define _MT7531_H_ + +#include "mt753x.h" + +extern struct mt753x_sw_id mt7531_id; + +#endif /* _MT7531_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x.h new file mode 100755 index 00000000..27cd6f4f --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x.h @@ -0,0 +1,213 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MT753X_H_ +#define _MT753X_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SWCONFIG +#include +#endif + +#include "mt753x_vlan.h" + +#define MT753X_DFL_CPU_PORT 6 +#define MT753X_NUM_PHYS 5 + +#define MT753X_DFL_SMI_ADDR 0x1f +#define MT753X_SMI_ADDR_MASK 0x1f + +struct gsw_mt753x; + +enum mt753x_model { + MT7530 = 0x7530, + MT7531 = 0x7531 +}; + +struct mt753x_port_cfg { + struct device_node *np; + phy_interface_t phy_mode; + u32 enabled: 1; + u32 force_link: 1; + u32 speed: 2; + u32 duplex: 1; +}; + +struct mt753x_phy { + struct gsw_mt753x *gsw; + struct net_device netdev; + struct phy_device *phydev; +}; + +struct gsw_mt753x { + u32 id; + + struct device *dev; + struct mii_bus *host_bus; + struct mii_bus *gphy_bus; + struct mutex mii_lock; /* MII access lock */ + u32 smi_addr; + u32 phy_base; + int direct_phy_access; + + enum mt753x_model model; + const char *name; + + struct mt753x_port_cfg port5_cfg; + struct mt753x_port_cfg port6_cfg; + + int phy_status_poll; + struct mt753x_phy phys[MT753X_NUM_PHYS]; + + int phy_link_sts; + + int irq; + int reset_pin; + struct work_struct irq_worker; + +#ifdef CONFIG_SWCONFIG + struct switch_dev swdev; + u32 cpu_port; +#endif + + int global_vlan_enable; + struct mt753x_vlan_entry vlan_entries[MT753X_NUM_VLANS]; + struct mt753x_port_entry port_entries[MT753X_NUM_PORTS]; + + int (*mii_read)(struct gsw_mt753x *gsw, int phy, int reg); + void (*mii_write)(struct gsw_mt753x *gsw, int phy, int reg, u16 val); + + int (*mmd_read)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg); + void (*mmd_write)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val); + + struct list_head list; +}; + +struct chip_rev { + const char *name; + u32 rev; +}; + +struct mt753x_sw_id { + enum mt753x_model model; + int (*detect)(struct gsw_mt753x *gsw, struct chip_rev *crev); + int (*init)(struct gsw_mt753x *gsw); + int (*post_init)(struct gsw_mt753x *gsw); +}; + +extern struct list_head mt753x_devs; + +struct gsw_mt753x *mt753x_get_gsw(u32 id); +struct gsw_mt753x *mt753x_get_first_gsw(void); +void mt753x_put_gsw(void); +void mt753x_lock_gsw(void); + +u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg); +void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val); + +int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg); +void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val); + +int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg); +void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val); + +int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg); +void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val); + +void mt753x_irq_worker(struct work_struct *work); +void mt753x_irq_enable(struct gsw_mt753x *gsw); + +/* MDIO Indirect Access Registers */ +#define MII_MMD_ACC_CTL_REG 0x0d +#define MMD_CMD_S 14 +#define MMD_CMD_M 0xc000 +#define MMD_DEVAD_S 0 +#define MMD_DEVAD_M 0x1f + +/* MMD_CMD: MMD commands */ +#define MMD_ADDR 0 +#define MMD_DATA 1 + +#define MII_MMD_ADDR_DATA_REG 0x0e + +/* Procedure of MT753x Internal Register Access + * + * 1. Internal Register Address + * + * The MT753x has a 16-bit register address and each register is 32-bit. + * This means the lowest two bits are not used as the register address is + * 4-byte aligned. + * + * Rest of the valid bits are divided into two parts: + * Bit 15..6 is the Page address + * Bit 5..2 is the low address + * + * ------------------------------------------------------------------- + * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 | + * |----------------------------------------|---------------|--------| + * | Page Address | Address | Unused | + * ------------------------------------------------------------------- + * + * 2. MDIO access timing + * + * The MT753x uses the following MDIO timing for a single register read + * + * Phase 1: Write Page Address + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | RSVD | TA | RSVD | PAGE_ADDR | + * ------------------------------------------------------------------- + * | 01 | 01 | 11111 | 1 | 1111 | xx | 00000 | REG_ADDR[15..6] | + * ------------------------------------------------------------------- + * + * Phase 2: Write low Address & Read low word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 10 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] | + * ------------------------------------------------------------------- + * + * Phase 3: Read high word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 10 | 11111 | 1 | 0000 | xx | DATA[31..16] | + * ------------------------------------------------------------------- + * + * The MT753x uses the following MDIO timing for a single register write + * + * Phase 1: Write Page Address (The same as read) + * + * Phase 2: Write low Address and low word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 01 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] | + * ------------------------------------------------------------------- + * + * Phase 3: write high word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 01 | 11111 | 1 | 0000 | xx | DATA[31..16] | + * ------------------------------------------------------------------- + * + */ + +/* Internal Register Address fields */ +#define MT753X_REG_PAGE_ADDR_S 6 +#define MT753X_REG_PAGE_ADDR_M 0xffc0 +#define MT753X_REG_ADDR_S 2 +#define MT753X_REG_ADDR_M 0x3c +#endif /* _MT753X_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_common.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_common.c new file mode 100755 index 00000000..4015ddf1 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_common.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include + +#include "mt753x.h" +#include "mt753x_regs.h" + +void mt753x_irq_enable(struct gsw_mt753x *gsw) +{ + u32 val; + int i; + + /* Record initial PHY link status */ + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMSR); + if (val & BMSR_LSTATUS) + gsw->phy_link_sts |= BIT(i); + } + + val = BIT(MT753X_NUM_PHYS) - 1; + + mt753x_reg_write(gsw, SYS_INT_EN, val); +} + +static void display_port_link_status(struct gsw_mt753x *gsw, u32 port) +{ + u32 pmsr, speed_bits; + const char *speed; + + pmsr = mt753x_reg_read(gsw, PMSR(port)); + + speed_bits = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S; + + switch (speed_bits) { + case MAC_SPD_10: + speed = "10Mbps"; + break; + case MAC_SPD_100: + speed = "100Mbps"; + break; + case MAC_SPD_1000: + speed = "1Gbps"; + break; + case MAC_SPD_2500: + speed = "2.5Gbps"; + break; + } + + if (pmsr & MAC_LNK_STS) { + dev_info(gsw->dev, "Port %d Link is Up - %s/%s\n", + port, speed, (pmsr & MAC_DPX_STS) ? "Full" : "Half"); + } else { + dev_info(gsw->dev, "Port %d Link is Down\n", port); + } +} + +void mt753x_irq_worker(struct work_struct *work) +{ + struct gsw_mt753x *gsw; + u32 sts, physts, laststs; + int i; + + gsw = container_of(work, struct gsw_mt753x, irq_worker); + + sts = mt753x_reg_read(gsw, SYS_INT_STS); + + /* Check for changed PHY link status */ + for (i = 0; i < MT753X_NUM_PHYS; i++) { + if (!(sts & PHY_LC_INT(i))) + continue; + + laststs = gsw->phy_link_sts & BIT(i); + physts = !!(gsw->mii_read(gsw, i, MII_BMSR) & BMSR_LSTATUS); + physts <<= i; + + if (physts ^ laststs) { + gsw->phy_link_sts ^= BIT(i); + display_port_link_status(gsw, i); + } + } + + mt753x_reg_write(gsw, SYS_INT_STS, sts); + + enable_irq(gsw->irq); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_mdio.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_mdio.c new file mode 100755 index 00000000..3e2e6d68 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_mdio.c @@ -0,0 +1,597 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_swconfig.h" +#include "mt753x_regs.h" +#include "mt753x_nl.h" +#include "mt7530.h" +#include "mt7531.h" + +static u32 mt753x_id; +struct list_head mt753x_devs; +static DEFINE_MUTEX(mt753x_devs_lock); + +static struct mt753x_sw_id *mt753x_sw_ids[] = { + &mt7530_id, + &mt7531_id, +}; + +u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg) +{ + u32 high, low; + + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f, + (reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S); + + low = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, + (reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S); + + high = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, 0x10); + + mutex_unlock(&gsw->host_bus->mdio_lock); + + return (high << 16) | (low & 0xffff); +} + +void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val) +{ + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f, + (reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, + (reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S, val & 0xffff); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x10, val >> 16); + + mutex_unlock(&gsw->host_bus->mdio_lock); +} + +/* Indirect MDIO clause 22/45 access */ +static int mt753x_mii_rw(struct gsw_mt753x *gsw, int phy, int reg, u16 data, + u32 cmd, u32 st) +{ + ktime_t timeout; + u32 val, timeout_us; + int ret = 0; + + timeout_us = 100000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PHY_IAC); + + if ((val & PHY_ACS_ST) == 0) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + val = (st << MDIO_ST_S) | + ((cmd << MDIO_CMD_S) & MDIO_CMD_M) | + ((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) | + ((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M); + + if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR) + val |= data & MDIO_RW_DATA_M; + + mt753x_reg_write(gsw, PHY_IAC, val | PHY_ACS_ST); + + timeout_us = 100000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PHY_IAC); + + if ((val & PHY_ACS_ST) == 0) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) { + val = mt753x_reg_read(gsw, PHY_IAC); + ret = val & MDIO_RW_DATA_M; + } + + return ret; +} + +int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg) +{ + int val; + + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + val = mt753x_mii_rw(gsw, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22); + mutex_unlock(&gsw->mii_lock); + + return val; +} + +void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val) +{ + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + mt753x_mii_rw(gsw, phy, reg, val, MDIO_CMD_WRITE, MDIO_ST_C22); + mutex_unlock(&gsw->mii_lock); +} + +int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg) +{ + int val; + + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45); + val = mt753x_mii_rw(gsw, addr, devad, 0, MDIO_CMD_READ_C45, + MDIO_ST_C45); + mutex_unlock(&gsw->mii_lock); + + return val; +} + +void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val) +{ + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45); + mt753x_mii_rw(gsw, addr, devad, val, MDIO_CMD_WRITE, MDIO_ST_C45); + mutex_unlock(&gsw->mii_lock); +} + +int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg) +{ + u16 val; + + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg, + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + val = mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, 0, + MDIO_CMD_READ, MDIO_ST_C22); + + mutex_unlock(&gsw->mii_lock); + + return val; +} + +void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val) +{ + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg, + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, val, + MDIO_CMD_WRITE, MDIO_ST_C22); + + mutex_unlock(&gsw->mii_lock); +} + +static inline int mt753x_get_duplex(const struct device_node *np) +{ + return of_property_read_bool(np, "full-duplex"); +} + +static void mt753x_load_port_cfg(struct gsw_mt753x *gsw) +{ + struct device_node *port_np; + struct device_node *fixed_link_node; + struct mt753x_port_cfg *port_cfg; + u32 port; + + for_each_child_of_node(gsw->dev->of_node, port_np) { + if (!of_device_is_compatible(port_np, "mediatek,mt753x-port")) + continue; + + if (!of_device_is_available(port_np)) + continue; + + if (of_property_read_u32(port_np, "reg", &port)) + continue; + + switch (port) { + case 5: + port_cfg = &gsw->port5_cfg; + break; + case 6: + port_cfg = &gsw->port6_cfg; + break; + default: + continue; + } + + if (port_cfg->enabled) { + dev_info(gsw->dev, "duplicated node for port%d\n", + port_cfg->phy_mode); + continue; + } + + port_cfg->np = port_np; + + if (of_get_phy_mode(port_np, &port_cfg->phy_mode) < 0) { + dev_info(gsw->dev, "incorrect phy-mode %d\n", port); + continue; + } + + fixed_link_node = of_get_child_by_name(port_np, "fixed-link"); + if (fixed_link_node) { + u32 speed; + + port_cfg->force_link = 1; + port_cfg->duplex = mt753x_get_duplex(fixed_link_node); + + if (of_property_read_u32(fixed_link_node, "speed", + &speed)) { + speed = 0; + continue; + } + + of_node_put(fixed_link_node); + + switch (speed) { + case 10: + port_cfg->speed = MAC_SPD_10; + break; + case 100: + port_cfg->speed = MAC_SPD_100; + break; + case 1000: + port_cfg->speed = MAC_SPD_1000; + break; + case 2500: + port_cfg->speed = MAC_SPD_2500; + break; + default: + dev_info(gsw->dev, "incorrect speed %d\n", + speed); + continue; + } + } + + port_cfg->enabled = 1; + } +} + +static void mt753x_add_gsw(struct gsw_mt753x *gsw) +{ + mutex_lock(&mt753x_devs_lock); + gsw->id = mt753x_id++; + INIT_LIST_HEAD(&gsw->list); + list_add_tail(&gsw->list, &mt753x_devs); + mutex_unlock(&mt753x_devs_lock); +} + +static void mt753x_remove_gsw(struct gsw_mt753x *gsw) +{ + mutex_lock(&mt753x_devs_lock); + list_del(&gsw->list); + mutex_unlock(&mt753x_devs_lock); +} + + +struct gsw_mt753x *mt753x_get_gsw(u32 id) +{ + struct gsw_mt753x *dev; + + mutex_lock(&mt753x_devs_lock); + + list_for_each_entry(dev, &mt753x_devs, list) { + if (dev->id == id) + return dev; + } + + mutex_unlock(&mt753x_devs_lock); + + return NULL; +} + +struct gsw_mt753x *mt753x_get_first_gsw(void) +{ + struct gsw_mt753x *dev; + + mutex_lock(&mt753x_devs_lock); + + list_for_each_entry(dev, &mt753x_devs, list) + return dev; + + mutex_unlock(&mt753x_devs_lock); + + return NULL; +} + +void mt753x_put_gsw(void) +{ + mutex_unlock(&mt753x_devs_lock); +} + +void mt753x_lock_gsw(void) +{ + mutex_lock(&mt753x_devs_lock); +} + +static int mt753x_hw_reset(struct gsw_mt753x *gsw) +{ + struct device_node *np = gsw->dev->of_node; + struct reset_control *rstc; + int mcm; + int ret = -EINVAL; + + mcm = of_property_read_bool(np, "mediatek,mcm"); + if (mcm) { + rstc = devm_reset_control_get(gsw->dev, "mcm"); + ret = IS_ERR(rstc); + if (IS_ERR(rstc)) { + dev_err(gsw->dev, "Missing reset ctrl of switch\n"); + return ret; + } + + reset_control_assert(rstc); + msleep(30); + reset_control_deassert(rstc); + + gsw->reset_pin = -1; + return 0; + } + + gsw->reset_pin = of_get_named_gpio(np, "reset-gpios", 0); + if (gsw->reset_pin < 0) { + dev_err(gsw->dev, "Missing reset pin of switch\n"); + return ret; + } + + ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mt753x-reset"); + if (ret) { + dev_info(gsw->dev, "Failed to request gpio %d\n", + gsw->reset_pin); + return ret; + } + + gpio_direction_output(gsw->reset_pin, 0); + msleep(30); + gpio_set_value(gsw->reset_pin, 1); + msleep(500); + + return 0; +} + +static irqreturn_t mt753x_irq_handler(int irq, void *dev) +{ + struct gsw_mt753x *gsw = dev; + + disable_irq_nosync(gsw->irq); + + schedule_work(&gsw->irq_worker); + + return IRQ_HANDLED; +} + +static int mt753x_probe(struct platform_device *pdev) +{ + struct gsw_mt753x *gsw; + struct mt753x_sw_id *sw; + struct device_node *np = pdev->dev.of_node; + struct device_node *mdio; + struct mii_bus *mdio_bus; + int ret = -EINVAL; + struct chip_rev rev; + struct mt753x_mapping *map; + int i; + + mdio = of_parse_phandle(np, "mediatek,mdio", 0); + if (!mdio) + return -EINVAL; + + mdio_bus = of_mdio_find_bus(mdio); + if (!mdio_bus) + return -EPROBE_DEFER; + + gsw = devm_kzalloc(&pdev->dev, sizeof(struct gsw_mt753x), GFP_KERNEL); + if (!gsw) + return -ENOMEM; + + gsw->host_bus = mdio_bus; + gsw->dev = &pdev->dev; + mutex_init(&gsw->mii_lock); + + /* Switch hard reset */ + if (mt753x_hw_reset(gsw)) + goto fail; + + /* Fetch the SMI address dirst */ + if (of_property_read_u32(np, "mediatek,smi-addr", &gsw->smi_addr)) + gsw->smi_addr = MT753X_DFL_SMI_ADDR; + + /* Get LAN/WAN port mapping */ + map = mt753x_find_mapping(np); + if (map) { + mt753x_apply_mapping(gsw, map); + gsw->global_vlan_enable = 1; + dev_info(gsw->dev, "LAN/WAN VLAN setting=%s\n", map->name); + } + + /* Load MAC port configurations */ + mt753x_load_port_cfg(gsw); + + /* Check for valid switch and then initialize */ + for (i = 0; i < ARRAY_SIZE(mt753x_sw_ids); i++) { + if (!mt753x_sw_ids[i]->detect(gsw, &rev)) { + sw = mt753x_sw_ids[i]; + + gsw->name = rev.name; + gsw->model = sw->model; + + dev_info(gsw->dev, "Switch is MediaTek %s rev %d", + gsw->name, rev.rev); + + /* Initialize the switch */ + ret = sw->init(gsw); + if (ret) + goto fail; + + break; + } + } + + if (i >= ARRAY_SIZE(mt753x_sw_ids)) { + dev_err(gsw->dev, "No mt753x switch found\n"); + goto fail; + } + + gsw->irq = platform_get_irq(pdev, 0); + if (gsw->irq >= 0) { + ret = devm_request_irq(gsw->dev, gsw->irq, mt753x_irq_handler, + 0, dev_name(gsw->dev), gsw); + if (ret) { + dev_err(gsw->dev, "Failed to request irq %d\n", + gsw->irq); + goto fail; + } + + INIT_WORK(&gsw->irq_worker, mt753x_irq_worker); + } + + platform_set_drvdata(pdev, gsw); + + gsw->phy_status_poll = of_property_read_bool(gsw->dev->of_node, + "mediatek,phy-poll"); + + mt753x_add_gsw(gsw); + + mt753x_swconfig_init(gsw); + + if (sw->post_init) + sw->post_init(gsw); + + if (gsw->irq >= 0) + mt753x_irq_enable(gsw); + + return 0; + +fail: + devm_kfree(&pdev->dev, gsw); + + return ret; +} + +static int mt753x_remove(struct platform_device *pdev) +{ + struct gsw_mt753x *gsw = platform_get_drvdata(pdev); + + if (gsw->irq >= 0) + cancel_work_sync(&gsw->irq_worker); + + if (gsw->reset_pin >= 0) + devm_gpio_free(&pdev->dev, gsw->reset_pin); + +#ifdef CONFIG_SWCONFIG + mt753x_swconfig_destroy(gsw); +#endif + + mt753x_remove_gsw(gsw); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id mt753x_ids[] = { + { .compatible = "mediatek,mt753x" }, + { }, +}; + +MODULE_DEVICE_TABLE(of, mt753x_ids); + +static struct platform_driver mt753x_driver = { + .probe = mt753x_probe, + .remove = mt753x_remove, + .driver = { + .name = "mt753x", + .of_match_table = mt753x_ids, + }, +}; + +static int __init mt753x_init(void) +{ + int ret; + + INIT_LIST_HEAD(&mt753x_devs); + ret = platform_driver_register(&mt753x_driver); + + mt753x_nl_init(); + + return ret; +} +module_init(mt753x_init); + +static void __exit mt753x_exit(void) +{ + mt753x_nl_exit(); + + platform_driver_unregister(&mt753x_driver); +} +module_exit(mt753x_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Weijie Gao "); +MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch"); diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.c new file mode 100755 index 00000000..ccde2c92 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Sirui Zhao + */ + +#include +#include +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_nl.h" + +struct mt753x_nl_cmd_item { + enum mt753x_cmd cmd; + bool require_dev; + int (*process)(struct genl_info *info, struct gsw_mt753x *gsw); + u32 nr_required_attrs; + const enum mt753x_attr *required_attrs; +}; + +static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info); + +/* +static const struct nla_policy mt753x_nl_cmd_policy[] = { + [MT753X_ATTR_TYPE_MESG] = { .type = NLA_STRING }, + [MT753X_ATTR_TYPE_PHY] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_REG] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_VAL] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_DEV_NAME] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_DEV_ID] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_DEVAD] = { .type = NLA_S32 }, +}; +*/ + +static const struct genl_ops mt753x_nl_ops[] = { + { + .cmd = MT753X_CMD_REQUEST, + .doit = mt753x_nl_response, +// .policy = mt753x_nl_cmd_policy, + .flags = GENL_ADMIN_PERM, + }, { + .cmd = MT753X_CMD_READ, + .doit = mt753x_nl_response, +// .policy = mt753x_nl_cmd_policy, + .flags = GENL_ADMIN_PERM, + }, { + .cmd = MT753X_CMD_WRITE, + .doit = mt753x_nl_response, +// .policy = mt753x_nl_cmd_policy, + .flags = GENL_ADMIN_PERM, + }, +}; + +static struct genl_family mt753x_nl_family = { + .name = MT753X_GENL_NAME, + .version = MT753X_GENL_VERSION, + .maxattr = MT753X_NR_ATTR_TYPE, + .ops = mt753x_nl_ops, + .n_ops = ARRAY_SIZE(mt753x_nl_ops), +}; + +static int mt753x_nl_list_devs(char *buff, int size) +{ + struct gsw_mt753x *gsw; + int len, total = 0; + char buf[80]; + + memset(buff, 0, size); + + mt753x_lock_gsw(); + + list_for_each_entry(gsw, &mt753x_devs, list) { + len = snprintf(buf, sizeof(buf), + "id: %d, model: %s, node: %s\n", + gsw->id, gsw->name, gsw->dev->of_node->name); + strncat(buff, buf, size - total); + total += len; + } + + mt753x_put_gsw(); + + return total; +} + +static int mt753x_nl_prepare_reply(struct genl_info *info, u8 cmd, + struct sk_buff **skbp) +{ + struct sk_buff *msg; + void *reply; + + if (!info) + return -EINVAL; + + msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + /* Construct send-back message header */ + reply = genlmsg_put(msg, info->snd_portid, info->snd_seq, + &mt753x_nl_family, 0, cmd); + if (!reply) { + nlmsg_free(msg); + return -EINVAL; + } + + *skbp = msg; + return 0; +} + +static int mt753x_nl_send_reply(struct sk_buff *skb, struct genl_info *info) +{ + struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb)); + void *reply = genlmsg_data(genlhdr); + + /* Finalize a generic netlink message (update message header) */ + genlmsg_end(skb, reply); + + /* reply to a request */ + return genlmsg_reply(skb, info); +} + +static s32 mt753x_nl_get_s32(struct genl_info *info, enum mt753x_attr attr, + s32 defval) +{ + struct nlattr *na; + + na = info->attrs[attr]; + if (na) + return nla_get_s32(na); + + return defval; +} + +static int mt753x_nl_get_u32(struct genl_info *info, enum mt753x_attr attr, + u32 *val) +{ + struct nlattr *na; + + na = info->attrs[attr]; + if (na) { + *val = nla_get_u32(na); + return 0; + } + + return -1; +} + +static struct gsw_mt753x *mt753x_nl_parse_find_gsw(struct genl_info *info) +{ + struct gsw_mt753x *gsw; + struct nlattr *na; + int gsw_id; + + na = info->attrs[MT753X_ATTR_TYPE_DEV_ID]; + if (na) { + gsw_id = nla_get_s32(na); + if (gsw_id >= 0) + gsw = mt753x_get_gsw(gsw_id); + else + gsw = mt753x_get_first_gsw(); + } else { + gsw = mt753x_get_first_gsw(); + } + + return gsw; +} + +static int mt753x_nl_get_swdevs(struct genl_info *info, struct gsw_mt753x *gsw) +{ + struct sk_buff *rep_skb = NULL; + char dev_info[512]; + int ret; + + ret = mt753x_nl_list_devs(dev_info, sizeof(dev_info)); + if (!ret) { + pr_info("No switch registered\n"); + return -EINVAL; + } + + ret = mt753x_nl_prepare_reply(info, MT753X_CMD_REPLY, &rep_skb); + if (ret < 0) + goto err; + + ret = nla_put_string(rep_skb, MT753X_ATTR_TYPE_MESG, dev_info); + if (ret < 0) + goto err; + + return mt753x_nl_send_reply(rep_skb, info); + +err: + if (rep_skb) + nlmsg_free(rep_skb); + + return ret; +} + +static int mt753x_nl_reply_read(struct genl_info *info, struct gsw_mt753x *gsw) +{ + struct sk_buff *rep_skb = NULL; + s32 phy, devad, reg; + int value; + int ret = 0; + + phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1); + devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1); + reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1); + + if (reg < 0) + goto err; + + ret = mt753x_nl_prepare_reply(info, MT753X_CMD_READ, &rep_skb); + if (ret < 0) + goto err; + + if (phy >= 0) { + if (devad < 0) + value = gsw->mii_read(gsw, phy, reg); + else + value = gsw->mmd_read(gsw, phy, devad, reg); + } else { + value = mt753x_reg_read(gsw, reg); + } + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg); + if (ret < 0) + goto err; + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value); + if (ret < 0) + goto err; + + return mt753x_nl_send_reply(rep_skb, info); + +err: + if (rep_skb) + nlmsg_free(rep_skb); + + return ret; +} + +static int mt753x_nl_reply_write(struct genl_info *info, struct gsw_mt753x *gsw) +{ + struct sk_buff *rep_skb = NULL; + s32 phy, devad, reg; + u32 value; + int ret = 0; + + phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1); + devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1); + reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1); + + if (mt753x_nl_get_u32(info, MT753X_ATTR_TYPE_VAL, &value)) + goto err; + + if (reg < 0) + goto err; + + ret = mt753x_nl_prepare_reply(info, MT753X_CMD_WRITE, &rep_skb); + if (ret < 0) + goto err; + + if (phy >= 0) { + if (devad < 0) + gsw->mii_write(gsw, phy, reg, value); + else + gsw->mmd_write(gsw, phy, devad, reg, value); + } else { + mt753x_reg_write(gsw, reg, value); + } + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg); + if (ret < 0) + goto err; + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value); + if (ret < 0) + goto err; + + return mt753x_nl_send_reply(rep_skb, info); + +err: + if (rep_skb) + nlmsg_free(rep_skb); + + return ret; +} + +static const enum mt753x_attr mt753x_nl_cmd_read_attrs[] = { + MT753X_ATTR_TYPE_REG +}; + +static const enum mt753x_attr mt753x_nl_cmd_write_attrs[] = { + MT753X_ATTR_TYPE_REG, + MT753X_ATTR_TYPE_VAL +}; + +static const struct mt753x_nl_cmd_item mt753x_nl_cmds[] = { + { + .cmd = MT753X_CMD_REQUEST, + .require_dev = false, + .process = mt753x_nl_get_swdevs + }, { + .cmd = MT753X_CMD_READ, + .require_dev = true, + .process = mt753x_nl_reply_read, + .required_attrs = mt753x_nl_cmd_read_attrs, + .nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_read_attrs), + }, { + .cmd = MT753X_CMD_WRITE, + .require_dev = true, + .process = mt753x_nl_reply_write, + .required_attrs = mt753x_nl_cmd_write_attrs, + .nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_write_attrs), + } +}; + +static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info) +{ + struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); + const struct mt753x_nl_cmd_item *cmditem = NULL; + struct gsw_mt753x *gsw = NULL; + u32 sat_req_attrs = 0; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(mt753x_nl_cmds); i++) { + if (hdr->cmd == mt753x_nl_cmds[i].cmd) { + cmditem = &mt753x_nl_cmds[i]; + break; + } + } + + if (!cmditem) { + pr_info("mt753x-nl: unknown cmd %u\n", hdr->cmd); + return -EINVAL; + } + + for (i = 0; i < cmditem->nr_required_attrs; i++) { + if (info->attrs[cmditem->required_attrs[i]]) + sat_req_attrs++; + } + + if (sat_req_attrs != cmditem->nr_required_attrs) { + pr_info("mt753x-nl: missing required attr(s) for cmd %u\n", + hdr->cmd); + return -EINVAL; + } + + if (cmditem->require_dev) { + gsw = mt753x_nl_parse_find_gsw(info); + if (!gsw) { + pr_info("mt753x-nl: failed to find switch dev\n"); + return -EINVAL; + } + } + + ret = cmditem->process(info, gsw); + + mt753x_put_gsw(); + + return ret; +} + +int __init mt753x_nl_init(void) +{ + int ret; + + ret = genl_register_family(&mt753x_nl_family); + if (ret) { + pr_info("mt753x-nl: genl_register_family_with_ops failed\n"); + return ret; + } + + return 0; +} + +void __exit mt753x_nl_exit(void) +{ + genl_unregister_family(&mt753x_nl_family); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.h new file mode 100755 index 00000000..85dc9e79 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_nl.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Sirui Zhao + */ + +#ifndef _MT753X_NL_H_ +#define _MT753X_NL_H_ + +#define MT753X_GENL_NAME "mt753x" +#define MT753X_GENL_VERSION 0x1 + +enum mt753x_cmd { + MT753X_CMD_UNSPEC = 0, + MT753X_CMD_REQUEST, + MT753X_CMD_REPLY, + MT753X_CMD_READ, + MT753X_CMD_WRITE, + + __MT753X_CMD_MAX, +}; + +enum mt753x_attr { + MT753X_ATTR_TYPE_UNSPEC = 0, + MT753X_ATTR_TYPE_MESG, + MT753X_ATTR_TYPE_PHY, + MT753X_ATTR_TYPE_DEVAD, + MT753X_ATTR_TYPE_REG, + MT753X_ATTR_TYPE_VAL, + MT753X_ATTR_TYPE_DEV_NAME, + MT753X_ATTR_TYPE_DEV_ID, + + __MT753X_ATTR_TYPE_MAX, +}; + +#define MT753X_NR_ATTR_TYPE (__MT753X_ATTR_TYPE_MAX - 1) + +#ifdef __KERNEL__ +int __init mt753x_nl_init(void); +void __exit mt753x_nl_exit(void); +#endif /* __KERNEL__ */ + +#endif /* _MT753X_NL_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_regs.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_regs.h new file mode 100755 index 00000000..3f23ae20 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_regs.h @@ -0,0 +1,294 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MT753X_REGS_H_ +#define _MT753X_REGS_H_ + +#include + +/* Values of Egress TAG Control */ +#define ETAG_CTRL_UNTAG 0 +#define ETAG_CTRL_TAG 2 +#define ETAG_CTRL_SWAP 1 +#define ETAG_CTRL_STACK 3 + +#define VTCR 0x90 +#define VAWD1 0x94 +#define VAWD2 0x98 + +/* Fields of VTCR */ +#define VTCR_BUSY BIT(31) +#define IDX_INVLD BIT(16) +#define VTCR_FUNC_S 12 +#define VTCR_FUNC_M 0xf000 +#define VTCR_VID_S 0 +#define VTCR_VID_M 0xfff + +/* Values of VTCR_FUNC */ +#define VTCR_READ_VLAN_ENTRY 0 +#define VTCR_WRITE_VLAN_ENTRY 1 +#define VTCR_INVD_VLAN_ENTRY 2 +#define VTCR_ENABLE_VLAN_ENTRY 3 +#define VTCR_READ_ACL_ENTRY 4 +#define VTCR_WRITE_ACL_ENTRY 5 +#define VTCR_READ_TRTCM_TABLE 6 +#define VTCR_WRITE_TRTCM_TABLE 7 +#define VTCR_READ_ACL_MASK_ENTRY 8 +#define VTCR_WRITE_ACL_MASK_ENTRY 9 +#define VTCR_READ_ACL_RULE_ENTRY 10 +#define VTCR_WRITE_ACL_RULE_ENTRY 11 +#define VTCR_READ_ACL_RATE_ENTRY 12 +#define VTCR_WRITE_ACL_RATE_ENTRY 13 + +/* VLAN entry fields */ +/* VAWD1 */ +#define PORT_STAG BIT(31) +#define IVL_MAC BIT(30) +#define EG_CON BIT(29) +#define VTAG_EN BIT(28) +#define COPY_PRI BIT(27) +#define USER_PRI_S 24 +#define USER_PRI_M 0x7000000 +#define PORT_MEM_S 16 +#define PORT_MEM_M 0xff0000 +#define S_TAG1_S 4 +#define S_TAG1_M 0xfff0 +#define FID_S 1 +#define FID_M 0x0e +#define VENTRY_VALID BIT(0) + +/* VAWD2 */ +#define S_TAG2_S 16 +#define S_TAG2_M 0xffff0000 +#define PORT_ETAG_S(p) ((p) * 2) +#define PORT_ETAG_M 0x03 + +#define PORT_CTRL_BASE 0x2000 +#define PORT_CTRL_PORT_OFFSET 0x100 +#define PORT_CTRL_REG(p, r) (PORT_CTRL_BASE + \ + (p) * PORT_CTRL_PORT_OFFSET + (r)) +#define CKGCR(p) PORT_CTRL_REG(p, 0x00) +#define PCR(p) PORT_CTRL_REG(p, 0x04) +#define PIC(p) PORT_CTRL_REG(p, 0x08) +#define PSC(p) PORT_CTRL_REG(p, 0x0c) +#define PVC(p) PORT_CTRL_REG(p, 0x10) +#define PPBV1(p) PORT_CTRL_REG(p, 0x14) +#define PPBV2(p) PORT_CTRL_REG(p, 0x18) +#define BSR(p) PORT_CTRL_REG(p, 0x1c) +#define STAG01 PORT_CTRL_REG(p, 0x20) +#define STAG23 PORT_CTRL_REG(p, 0x24) +#define STAG45 PORT_CTRL_REG(p, 0x28) +#define STAG67 PORT_CTRL_REG(p, 0x2c) + +#define PPBV(p, g) (PPBV1(p) + ((g) / 2) * 4) + +/* Fields of PCR */ +#define MLDV2_EN BIT(30) +#define EG_TAG_S 28 +#define EG_TAG_M 0x30000000 +#define PORT_PRI_S 24 +#define PORT_PRI_M 0x7000000 +#define PORT_MATRIX_S 16 +#define PORT_MATRIX_M 0xff0000 +#define UP2DSCP_EN BIT(12) +#define UP2TAG_EN BIT(11) +#define ACL_EN BIT(10) +#define PORT_TX_MIR BIT(9) +#define PORT_RX_MIR BIT(8) +#define ACL_MIR BIT(7) +#define MIS_PORT_FW_S 4 +#define MIS_PORT_FW_M 0x70 +#define VLAN_MIS BIT(2) +#define PORT_VLAN_S 0 +#define PORT_VLAN_M 0x03 + +/* Values of PORT_VLAN */ +#define PORT_MATRIX_MODE 0 +#define FALLBACK_MODE 1 +#define CHECK_MODE 2 +#define SECURITY_MODE 3 + +/* Fields of PVC */ +#define STAG_VPID_S 16 +#define STAG_VPID_M 0xffff0000 +#define DIS_PVID BIT(15) +#define FORCE_PVID BIT(14) +#define PT_VPM BIT(12) +#define PT_OPTION BIT(11) +#define PVC_EG_TAG_S 8 +#define PVC_EG_TAG_M 0x700 +#define VLAN_ATTR_S 6 +#define VLAN_ATTR_M 0xc0 +#define PVC_PORT_STAG BIT(5) +#define BC_LKYV_EN BIT(4) +#define MC_LKYV_EN BIT(3) +#define UC_LKYV_EN BIT(2) +#define ACC_FRM_S 0 +#define ACC_FRM_M 0x03 + +/* Values of VLAN_ATTR */ +#define VA_USER_PORT 0 +#define VA_STACK_PORT 1 +#define VA_TRANSLATION_PORT 2 +#define VA_TRANSPARENT_PORT 3 + +/* Fields of PPBV */ +#define GRP_PORT_PRI_S(g) (((g) % 2) * 16 + 13) +#define GRP_PORT_PRI_M 0x07 +#define GRP_PORT_VID_S(g) (((g) % 2) * 16) +#define GRP_PORT_VID_M 0xfff + +#define PORT_MAC_CTRL_BASE 0x3000 +#define PORT_MAC_CTRL_PORT_OFFSET 0x100 +#define PORT_MAC_CTRL_REG(p, r) (PORT_MAC_CTRL_BASE + \ + (p) * PORT_MAC_CTRL_PORT_OFFSET + (r)) +#define PMCR(p) PORT_MAC_CTRL_REG(p, 0x00) +#define PMEEECR(p) PORT_MAC_CTRL_REG(p, 0x04) +#define PMSR(p) PORT_MAC_CTRL_REG(p, 0x08) +#define PINT_EN(p) PORT_MAC_CTRL_REG(p, 0x10) +#define PINT_STS(p) PORT_MAC_CTRL_REG(p, 0x14) + +#define GMACCR (PORT_MAC_CTRL_BASE + 0xe0) +#define TXCRC_EN BIT(19) +#define RXCRC_EN BIT(18) +#define PRMBL_LMT_EN BIT(17) +#define MTCC_LMT_S 9 +#define MTCC_LMT_M 0x1e00 +#define MAX_RX_JUMBO_S 2 +#define MAX_RX_JUMBO_M 0x3c +#define MAX_RX_PKT_LEN_S 0 +#define MAX_RX_PKT_LEN_M 0x3 + +/* Values of MAX_RX_PKT_LEN */ +#define RX_PKT_LEN_1518 0 +#define RX_PKT_LEN_1536 1 +#define RX_PKT_LEN_1522 2 +#define RX_PKT_LEN_MAX_JUMBO 3 + +/* Fields of PMCR */ +#define IPG_CFG_S 18 +#define IPG_CFG_M 0xc0000 +#define EXT_PHY BIT(17) +#define MAC_MODE BIT(16) +#define MAC_TX_EN BIT(14) +#define MAC_RX_EN BIT(13) +#define MAC_PRE BIT(11) +#define BKOFF_EN BIT(9) +#define BACKPR_EN BIT(8) +#define FORCE_EEE1G BIT(7) +#define FORCE_EEE1000 BIT(6) +#define FORCE_RX_FC BIT(5) +#define FORCE_TX_FC BIT(4) +#define FORCE_SPD_S 2 +#define FORCE_SPD_M 0x0c +#define FORCE_DPX BIT(1) +#define FORCE_LINK BIT(0) + +/* Fields of PMSR */ +#define EEE1G_STS BIT(7) +#define EEE100_STS BIT(6) +#define RX_FC_STS BIT(5) +#define TX_FC_STS BIT(4) +#define MAC_SPD_STS_S 2 +#define MAC_SPD_STS_M 0x0c +#define MAC_DPX_STS BIT(1) +#define MAC_LNK_STS BIT(0) + +/* Values of MAC_SPD_STS */ +#define MAC_SPD_10 0 +#define MAC_SPD_100 1 +#define MAC_SPD_1000 2 +#define MAC_SPD_2500 3 + +/* Values of IPG_CFG */ +#define IPG_96BIT 0 +#define IPG_96BIT_WITH_SHORT_IPG 1 +#define IPG_64BIT 2 + +#define MIB_COUNTER_BASE 0x4000 +#define MIB_COUNTER_PORT_OFFSET 0x100 +#define MIB_COUNTER_REG(p, r) (MIB_COUNTER_BASE + \ + (p) * MIB_COUNTER_PORT_OFFSET + (r)) +#define STATS_TDPC 0x00 +#define STATS_TCRC 0x04 +#define STATS_TUPC 0x08 +#define STATS_TMPC 0x0C +#define STATS_TBPC 0x10 +#define STATS_TCEC 0x14 +#define STATS_TSCEC 0x18 +#define STATS_TMCEC 0x1C +#define STATS_TDEC 0x20 +#define STATS_TLCEC 0x24 +#define STATS_TXCEC 0x28 +#define STATS_TPPC 0x2C +#define STATS_TL64PC 0x30 +#define STATS_TL65PC 0x34 +#define STATS_TL128PC 0x38 +#define STATS_TL256PC 0x3C +#define STATS_TL512PC 0x40 +#define STATS_TL1024PC 0x44 +#define STATS_TOC 0x48 +#define STATS_RDPC 0x60 +#define STATS_RFPC 0x64 +#define STATS_RUPC 0x68 +#define STATS_RMPC 0x6C +#define STATS_RBPC 0x70 +#define STATS_RAEPC 0x74 +#define STATS_RCEPC 0x78 +#define STATS_RUSPC 0x7C +#define STATS_RFEPC 0x80 +#define STATS_ROSPC 0x84 +#define STATS_RJEPC 0x88 +#define STATS_RPPC 0x8C +#define STATS_RL64PC 0x90 +#define STATS_RL65PC 0x94 +#define STATS_RL128PC 0x98 +#define STATS_RL256PC 0x9C +#define STATS_RL512PC 0xA0 +#define STATS_RL1024PC 0xA4 +#define STATS_ROC 0xA8 +#define STATS_RDPC_CTRL 0xB0 +#define STATS_RDPC_ING 0xB4 +#define STATS_RDPC_ARL 0xB8 + +#define SYS_CTRL 0x7000 +#define SW_PHY_RST BIT(2) +#define SW_SYS_RST BIT(1) +#define SW_REG_RST BIT(0) + +#define SYS_INT_EN 0x7008 +#define SYS_INT_STS 0x700c +#define MAC_PC_INT BIT(16) +#define PHY_INT(p) BIT((p) + 8) +#define PHY_LC_INT(p) BIT(p) + +#define PHY_IAC 0x701c +#define PHY_ACS_ST BIT(31) +#define MDIO_REG_ADDR_S 25 +#define MDIO_REG_ADDR_M 0x3e000000 +#define MDIO_PHY_ADDR_S 20 +#define MDIO_PHY_ADDR_M 0x1f00000 +#define MDIO_CMD_S 18 +#define MDIO_CMD_M 0xc0000 +#define MDIO_ST_S 16 +#define MDIO_ST_M 0x30000 +#define MDIO_RW_DATA_S 0 +#define MDIO_RW_DATA_M 0xffff + +/* MDIO_CMD: MDIO commands */ +#define MDIO_CMD_ADDR 0 +#define MDIO_CMD_WRITE 1 +#define MDIO_CMD_READ 2 +#define MDIO_CMD_READ_C45 3 + +/* MDIO_ST: MDIO start field */ +#define MDIO_ST_C45 0 +#define MDIO_ST_C22 1 + +#define HWSTRAP 0x7800 +#define MHWSTRAP 0x7804 + +#endif /* _MT753X_REGS_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c new file mode 100755 index 00000000..342ad576 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c @@ -0,0 +1,510 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_swconfig.h" +#include "mt753x_regs.h" + +#define MT753X_PORT_MIB_TXB_ID 18 /* TxByte */ +#define MT753X_PORT_MIB_RXB_ID 37 /* RxByte */ + +#define MIB_DESC(_s, _o, _n) \ + { \ + .size = (_s), \ + .offset = (_o), \ + .name = (_n), \ + } + +struct mt753x_mib_desc { + unsigned int size; + unsigned int offset; + const char *name; +}; + +static const struct mt753x_mib_desc mt753x_mibs[] = { + MIB_DESC(1, STATS_TDPC, "TxDrop"), + MIB_DESC(1, STATS_TCRC, "TxCRC"), + MIB_DESC(1, STATS_TUPC, "TxUni"), + MIB_DESC(1, STATS_TMPC, "TxMulti"), + MIB_DESC(1, STATS_TBPC, "TxBroad"), + MIB_DESC(1, STATS_TCEC, "TxCollision"), + MIB_DESC(1, STATS_TSCEC, "TxSingleCol"), + MIB_DESC(1, STATS_TMCEC, "TxMultiCol"), + MIB_DESC(1, STATS_TDEC, "TxDefer"), + MIB_DESC(1, STATS_TLCEC, "TxLateCol"), + MIB_DESC(1, STATS_TXCEC, "TxExcCol"), + MIB_DESC(1, STATS_TPPC, "TxPause"), + MIB_DESC(1, STATS_TL64PC, "Tx64Byte"), + MIB_DESC(1, STATS_TL65PC, "Tx65Byte"), + MIB_DESC(1, STATS_TL128PC, "Tx128Byte"), + MIB_DESC(1, STATS_TL256PC, "Tx256Byte"), + MIB_DESC(1, STATS_TL512PC, "Tx512Byte"), + MIB_DESC(1, STATS_TL1024PC, "Tx1024Byte"), + MIB_DESC(2, STATS_TOC, "TxByte"), + MIB_DESC(1, STATS_RDPC, "RxDrop"), + MIB_DESC(1, STATS_RFPC, "RxFiltered"), + MIB_DESC(1, STATS_RUPC, "RxUni"), + MIB_DESC(1, STATS_RMPC, "RxMulti"), + MIB_DESC(1, STATS_RBPC, "RxBroad"), + MIB_DESC(1, STATS_RAEPC, "RxAlignErr"), + MIB_DESC(1, STATS_RCEPC, "RxCRC"), + MIB_DESC(1, STATS_RUSPC, "RxUnderSize"), + MIB_DESC(1, STATS_RFEPC, "RxFragment"), + MIB_DESC(1, STATS_ROSPC, "RxOverSize"), + MIB_DESC(1, STATS_RJEPC, "RxJabber"), + MIB_DESC(1, STATS_RPPC, "RxPause"), + MIB_DESC(1, STATS_RL64PC, "Rx64Byte"), + MIB_DESC(1, STATS_RL65PC, "Rx65Byte"), + MIB_DESC(1, STATS_RL128PC, "Rx128Byte"), + MIB_DESC(1, STATS_RL256PC, "Rx256Byte"), + MIB_DESC(1, STATS_RL512PC, "Rx512Byte"), + MIB_DESC(1, STATS_RL1024PC, "Rx1024Byte"), + MIB_DESC(2, STATS_ROC, "RxByte"), + MIB_DESC(1, STATS_RDPC_CTRL, "RxCtrlDrop"), + MIB_DESC(1, STATS_RDPC_ING, "RxIngDrop"), + MIB_DESC(1, STATS_RDPC_ARL, "RxARLDrop") +}; + +enum { + /* Global attributes. */ + MT753X_ATTR_ENABLE_VLAN, +}; + +static int mt753x_get_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + val->value.i = gsw->global_vlan_enable; + + return 0; +} + +static int mt753x_set_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + gsw->global_vlan_enable = val->value.i != 0; + + return 0; +} + +static int mt753x_get_port_pvid(struct switch_dev *dev, int port, int *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (port >= MT753X_NUM_PORTS) + return -EINVAL; + + *val = mt753x_reg_read(gsw, PPBV1(port)); + *val &= GRP_PORT_VID_M; + + return 0; +} + +static int mt753x_set_port_pvid(struct switch_dev *dev, int port, int pvid) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (port >= MT753X_NUM_PORTS) + return -EINVAL; + + if (pvid < MT753X_MIN_VID || pvid > MT753X_MAX_VID) + return -EINVAL; + + gsw->port_entries[port].pvid = pvid; + + return 0; +} + +static int mt753x_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + u32 member; + u32 etags; + int i; + + val->len = 0; + + if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS) + return -EINVAL; + + mt753x_vlan_ctrl(gsw, VTCR_READ_VLAN_ENTRY, val->port_vlan); + + member = mt753x_reg_read(gsw, VAWD1); + member &= PORT_MEM_M; + member >>= PORT_MEM_S; + + etags = mt753x_reg_read(gsw, VAWD2); + + for (i = 0; i < MT753X_NUM_PORTS; i++) { + struct switch_port *p; + int etag; + + if (!(member & BIT(i))) + continue; + + p = &val->value.ports[val->len++]; + p->id = i; + + etag = (etags >> PORT_ETAG_S(i)) & PORT_ETAG_M; + + if (etag == ETAG_CTRL_TAG) + p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED); + else if (etag != ETAG_CTRL_UNTAG) + dev_info(gsw->dev, + "vlan egress tag control neither untag nor tag.\n"); + } + + return 0; +} + +static int mt753x_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + u8 member = 0; + u8 etags = 0; + int i; + + if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS || + val->len > MT753X_NUM_PORTS) + return -EINVAL; + + for (i = 0; i < val->len; i++) { + struct switch_port *p = &val->value.ports[i]; + + if (p->id >= MT753X_NUM_PORTS) + return -EINVAL; + + member |= BIT(p->id); + + if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) + etags |= BIT(p->id); + } + + gsw->vlan_entries[val->port_vlan].member = member; + gsw->vlan_entries[val->port_vlan].etags = etags; + + return 0; +} + +static int mt753x_set_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + int vlan; + u16 vid; + + vlan = val->port_vlan; + vid = (u16)val->value.i; + + if (vlan < 0 || vlan >= MT753X_NUM_VLANS) + return -EINVAL; + + if (vid < MT753X_MIN_VID || vid > MT753X_MAX_VID) + return -EINVAL; + + gsw->vlan_entries[vlan].vid = vid; + return 0; +} + +static int mt753x_get_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + val->value.i = val->port_vlan; + return 0; +} + +static int mt753x_get_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + u32 speed, pmsr; + + if (port < 0 || port >= MT753X_NUM_PORTS) + return -EINVAL; + + pmsr = mt753x_reg_read(gsw, PMSR(port)); + + link->link = pmsr & MAC_LNK_STS; + link->duplex = pmsr & MAC_DPX_STS; + speed = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S; + + switch (speed) { + case MAC_SPD_10: + link->speed = SWITCH_PORT_SPEED_10; + break; + case MAC_SPD_100: + link->speed = SWITCH_PORT_SPEED_100; + break; + case MAC_SPD_1000: + link->speed = SWITCH_PORT_SPEED_1000; + break; + case MAC_SPD_2500: + /* TODO: swconfig has no support for 2500 now */ + link->speed = SWITCH_PORT_SPEED_UNKNOWN; + break; + } + + return 0; +} + +static int mt753x_set_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ +#ifndef MODULE + if (port >= MT753X_NUM_PHYS) + return -EINVAL; + + return switch_generic_set_link(dev, port, link); +#else + return -ENOTSUPP; +#endif +} + +static u64 get_mib_counter(struct gsw_mt753x *gsw, int i, int port) +{ + unsigned int offset; + u64 lo, hi, hi2; + + offset = mt753x_mibs[i].offset; + + if (mt753x_mibs[i].size == 1) + return mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset)); + + do { + hi = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4)); + lo = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset)); + hi2 = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4)); + } while (hi2 != hi); + + return (hi << 32) | lo; +} + +static int mt753x_get_port_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + static char buf[4096]; + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + int i, len = 0; + + if (val->port_vlan >= MT753X_NUM_PORTS) + return -EINVAL; + + len += snprintf(buf + len, sizeof(buf) - len, + "Port %d MIB counters\n", val->port_vlan); + + for (i = 0; i < ARRAY_SIZE(mt753x_mibs); ++i) { + u64 counter; + + len += snprintf(buf + len, sizeof(buf) - len, + "%-11s: ", mt753x_mibs[i].name); + counter = get_mib_counter(gsw, i, val->port_vlan); + len += snprintf(buf + len, sizeof(buf) - len, "%llu\n", + counter); + } + + val->value.s = buf; + val->len = len; + return 0; +} + +static int mt753x_get_port_stats(struct switch_dev *dev, int port, + struct switch_port_stats *stats) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (port < 0 || port >= MT753X_NUM_PORTS) + return -EINVAL; + + stats->tx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_TXB_ID, port); + stats->rx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_RXB_ID, port); + + return 0; +} + +static void mt753x_port_isolation(struct gsw_mt753x *gsw) +{ + int i; + + for (i = 0; i < MT753X_NUM_PORTS; i++) + mt753x_reg_write(gsw, PCR(i), + BIT(gsw->cpu_port) << PORT_MATRIX_S); + + mt753x_reg_write(gsw, PCR(gsw->cpu_port), PORT_MATRIX_M); + + for (i = 0; i < MT753X_NUM_PORTS; i++) + mt753x_reg_write(gsw, PVC(i), + (0x8100 << STAG_VPID_S) | + (VA_TRANSPARENT_PORT << VLAN_ATTR_S)); +} + +static int mt753x_apply_config(struct switch_dev *dev) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (!gsw->global_vlan_enable) { + mt753x_port_isolation(gsw); + return 0; + } + + mt753x_apply_vlan_config(gsw); + + return 0; +} + +static int mt753x_reset_switch(struct switch_dev *dev) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + int i; + + memset(gsw->port_entries, 0, sizeof(gsw->port_entries)); + memset(gsw->vlan_entries, 0, sizeof(gsw->vlan_entries)); + + /* set default vid of each vlan to the same number of vlan, so the vid + * won't need be set explicitly. + */ + for (i = 0; i < MT753X_NUM_VLANS; i++) + gsw->vlan_entries[i].vid = i; + + return 0; +} + +static int mt753x_phy_read16(struct switch_dev *dev, int addr, u8 reg, + u16 *value) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + *value = gsw->mii_read(gsw, addr, reg); + + return 0; +} + +static int mt753x_phy_write16(struct switch_dev *dev, int addr, u8 reg, + u16 value) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + gsw->mii_write(gsw, addr, reg, value); + + return 0; +} + +static const struct switch_attr mt753x_global[] = { + { + .type = SWITCH_TYPE_INT, + .name = "enable_vlan", + .description = "VLAN mode (1:enabled)", + .max = 1, + .id = MT753X_ATTR_ENABLE_VLAN, + .get = mt753x_get_vlan_enable, + .set = mt753x_set_vlan_enable, + } +}; + +static const struct switch_attr mt753x_port[] = { + { + .type = SWITCH_TYPE_STRING, + .name = "mib", + .description = "Get MIB counters for port", + .get = mt753x_get_port_mib, + .set = NULL, + }, +}; + +static const struct switch_attr mt753x_vlan[] = { + { + .type = SWITCH_TYPE_INT, + .name = "vid", + .description = "VLAN ID (0-4094)", + .set = mt753x_set_vid, + .get = mt753x_get_vid, + .max = 4094, + }, +}; + +static const struct switch_dev_ops mt753x_swdev_ops = { + .attr_global = { + .attr = mt753x_global, + .n_attr = ARRAY_SIZE(mt753x_global), + }, + .attr_port = { + .attr = mt753x_port, + .n_attr = ARRAY_SIZE(mt753x_port), + }, + .attr_vlan = { + .attr = mt753x_vlan, + .n_attr = ARRAY_SIZE(mt753x_vlan), + }, + .get_vlan_ports = mt753x_get_vlan_ports, + .set_vlan_ports = mt753x_set_vlan_ports, + .get_port_pvid = mt753x_get_port_pvid, + .set_port_pvid = mt753x_set_port_pvid, + .get_port_link = mt753x_get_port_link, + .set_port_link = mt753x_set_port_link, + .get_port_stats = mt753x_get_port_stats, + .apply_config = mt753x_apply_config, + .reset_switch = mt753x_reset_switch, + .phy_read16 = mt753x_phy_read16, + .phy_write16 = mt753x_phy_write16, +}; + +int mt753x_swconfig_init(struct gsw_mt753x *gsw) +{ + struct device_node *np = gsw->dev->of_node; + struct switch_dev *swdev; + int ret; + + if (of_property_read_u32(np, "mediatek,cpuport", &gsw->cpu_port)) + gsw->cpu_port = MT753X_DFL_CPU_PORT; + + swdev = &gsw->swdev; + + swdev->name = gsw->name; + swdev->alias = gsw->name; + swdev->cpu_port = gsw->cpu_port; + swdev->ports = MT753X_NUM_PORTS; + swdev->vlans = MT753X_NUM_VLANS; + swdev->ops = &mt753x_swdev_ops; + + ret = register_switch(swdev, NULL); + if (ret) { + dev_notice(gsw->dev, "Failed to register switch %s\n", + swdev->name); + return ret; + } + + mt753x_apply_config(swdev); + + return 0; +} + +void mt753x_swconfig_destroy(struct gsw_mt753x *gsw) +{ + unregister_switch(&gsw->swdev); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h new file mode 100755 index 00000000..f000364e --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MT753X_SWCONFIG_H_ +#define _MT753X_SWCONFIG_H_ + +#ifdef CONFIG_SWCONFIG +#include +#include "mt753x.h" + +int mt753x_swconfig_init(struct gsw_mt753x *gsw); +void mt753x_swconfig_destroy(struct gsw_mt753x *gsw); +#else +static inline int mt753x_swconfig_init(struct gsw_mt753x *gsw) +{ + mt753x_apply_vlan_config(gsw); + + return 0; +} + +static inline void mt753x_swconfig_destroy(struct gsw_mt753x *gsw) +{ +} +#endif + +#endif /* _MT753X_SWCONFIG_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.c new file mode 100755 index 00000000..4d88eee8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#include "mt753x.h" +#include "mt753x_regs.h" + +struct mt753x_mapping mt753x_def_mapping[] = { + { + .name = "llllw", + .pvids = { 1, 1, 1, 1, 2, 2, 1 }, + .members = { 0, 0x4f, 0x30 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, { + .name = "wllll", + .pvids = { 2, 1, 1, 1, 1, 2, 1 }, + .members = { 0, 0x5e, 0x21 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, { + .name = "lwlll", + .pvids = { 1, 2, 1, 1, 1, 2, 1 }, + .members = { 0, 0x5d, 0x22 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, +}; + +void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val) +{ + int i; + + mt753x_reg_write(gsw, VTCR, + VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) | + (val & VTCR_VID_M)); + + for (i = 0; i < 300; i++) { + u32 val = mt753x_reg_read(gsw, VTCR); + + if ((val & VTCR_BUSY) == 0) + break; + + usleep_range(1000, 1100); + } + + if (i == 300) + dev_info(gsw->dev, "vtcr timeout\n"); +} + +static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid, + u8 ports, u8 etags) +{ + int port; + u32 val; + + /* vlan port membership */ + if (ports) + mt753x_reg_write(gsw, VAWD1, + IVL_MAC | VTAG_EN | VENTRY_VALID | + ((ports << PORT_MEM_S) & PORT_MEM_M)); + else + mt753x_reg_write(gsw, VAWD1, 0); + + /* egress mode */ + val = 0; + for (port = 0; port < MT753X_NUM_PORTS; port++) { + if (etags & BIT(port)) + val |= ETAG_CTRL_TAG << PORT_ETAG_S(port); + else + val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port); + } + mt753x_reg_write(gsw, VAWD2, val); + + /* write to vlan table */ + mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid); +} + +void mt753x_apply_vlan_config(struct gsw_mt753x *gsw) +{ + int i, j; + u8 tag_ports; + u8 untag_ports; + + /* set all ports as security mode */ + for (i = 0; i < MT753X_NUM_PORTS; i++) + mt753x_reg_write(gsw, PCR(i), + PORT_MATRIX_M | SECURITY_MODE); + + /* check if a port is used in tag/untag vlan egress mode */ + tag_ports = 0; + untag_ports = 0; + + for (i = 0; i < MT753X_NUM_VLANS; i++) { + u8 member = gsw->vlan_entries[i].member; + u8 etags = gsw->vlan_entries[i].etags; + + if (!member) + continue; + + for (j = 0; j < MT753X_NUM_PORTS; j++) { + if (!(member & BIT(j))) + continue; + + if (etags & BIT(j)) + tag_ports |= 1u << j; + else + untag_ports |= 1u << j; + } + } + + /* set all untag-only ports as transparent and the rest as user port */ + for (i = 0; i < MT753X_NUM_PORTS; i++) { + u32 pvc_mode = 0x8100 << STAG_VPID_S; + + if (untag_ports & BIT(i) && !(tag_ports & BIT(i))) + pvc_mode = (0x8100 << STAG_VPID_S) | + (VA_TRANSPARENT_PORT << VLAN_ATTR_S); + + mt753x_reg_write(gsw, PVC(i), pvc_mode); + } + + /* first clear the switch vlan table */ + for (i = 0; i < MT753X_NUM_VLANS; i++) + mt753x_write_vlan_entry(gsw, i, i, 0, 0); + + /* now program only vlans with members to avoid + * clobbering remapped entries in later iterations + */ + for (i = 0; i < MT753X_NUM_VLANS; i++) { + u16 vid = gsw->vlan_entries[i].vid; + u8 member = gsw->vlan_entries[i].member; + u8 etags = gsw->vlan_entries[i].etags; + + if (member) + mt753x_write_vlan_entry(gsw, i, vid, member, etags); + } + + /* Port Default PVID */ + for (i = 0; i < MT753X_NUM_PORTS; i++) { + int vlan = gsw->port_entries[i].pvid; + u16 pvid = 0; + u32 val; + + if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member) + pvid = gsw->vlan_entries[vlan].vid; + + val = mt753x_reg_read(gsw, PPBV1(i)); + val &= ~GRP_PORT_VID_M; + val |= pvid; + mt753x_reg_write(gsw, PPBV1(i), val); + } +} + +struct mt753x_mapping *mt753x_find_mapping(struct device_node *np) +{ + const char *map; + int i; + + if (of_property_read_string(np, "mediatek,portmap", &map)) + return NULL; + + for (i = 0; i < ARRAY_SIZE(mt753x_def_mapping); i++) + if (!strcmp(map, mt753x_def_mapping[i].name)) + return &mt753x_def_mapping[i]; + + return NULL; +} + +void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map) +{ + int i = 0; + + for (i = 0; i < MT753X_NUM_PORTS; i++) + gsw->port_entries[i].pvid = map->pvids[i]; + + for (i = 0; i < MT753X_NUM_VLANS; i++) { + gsw->vlan_entries[i].member = map->members[i]; + gsw->vlan_entries[i].etags = map->etags[i]; + gsw->vlan_entries[i].vid = map->vids[i]; + } +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.h new file mode 100755 index 00000000..c726b8ea --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/mtk/mt753x/mt753x_vlan.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#ifndef _MT753X_VLAN_H_ +#define _MT753X_VLAN_H_ + +#define MT753X_NUM_PORTS 7 +#define MT753X_NUM_VLANS 4095 +#define MT753X_MAX_VID 4095 +#define MT753X_MIN_VID 0 + +struct gsw_mt753x; + +struct mt753x_port_entry { + u16 pvid; +}; + +struct mt753x_vlan_entry { + u16 vid; + u8 member; + u8 etags; +}; + +struct mt753x_mapping { + char *name; + u16 pvids[MT753X_NUM_PORTS]; + u8 members[MT753X_NUM_VLANS]; + u8 etags[MT753X_NUM_VLANS]; + u16 vids[MT753X_NUM_VLANS]; +}; + +extern struct mt753x_mapping mt753x_defaults[]; + +void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val); +void mt753x_apply_vlan_config(struct gsw_mt753x *gsw); +struct mt753x_mapping *mt753x_find_mapping(struct device_node *np); +void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map); +#endif /* _MT753X_VLAN_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/Makefile b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/Makefile new file mode 100755 index 00000000..0f2891ea --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/Makefile @@ -0,0 +1,66 @@ +obj-$(CONFIG_RTL8367S_GSW) += rtl8367s_gsw.o +rtl8367s_gsw-objs := rtl8367s_mdio.o rtl8367s_dbg.o +ifeq ($(CONFIG_SWCONFIG),y) +rtl8367s_gsw-objs += rtl8367s.o +endif +rtl8367s_gsw-objs += rtl8367c/acl.o +rtl8367s_gsw-objs += rtl8367c/cpu.o +rtl8367s_gsw-objs += rtl8367c/dot1x.o +rtl8367s_gsw-objs += rtl8367c/eee.o +rtl8367s_gsw-objs += rtl8367c/igmp.o +rtl8367s_gsw-objs += rtl8367c/interrupt.o +rtl8367s_gsw-objs += rtl8367c/l2.o +rtl8367s_gsw-objs += rtl8367c/leaky.o +rtl8367s_gsw-objs += rtl8367c/led.o +rtl8367s_gsw-objs += rtl8367c/mirror.o +rtl8367s_gsw-objs += rtl8367c/oam.o +rtl8367s_gsw-objs += rtl8367c/port.o +rtl8367s_gsw-objs += rtl8367c/ptp.o +rtl8367s_gsw-objs += rtl8367c/qos.o +rtl8367s_gsw-objs += rtl8367c/rate.o +rtl8367s_gsw-objs += rtl8367c/rldp.o +rtl8367s_gsw-objs += rtl8367c/rtk_switch.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_acl.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_cputag.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_dot1x.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eav.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eee.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_fc.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_green.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_hsb.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_igmp.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_inbwctrl.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_interrupt.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_led.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_lut.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_meter.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mib.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mirror.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_misc.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_oam.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_phy.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_port.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_portIsolation.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_qos.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rldp.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rma.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_scheduling.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_storm.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_svlan.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_trunking.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_unknownMulticast.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_vlan.o +rtl8367s_gsw-objs += rtl8367c/smi.o +rtl8367s_gsw-objs += rtl8367c/stat.o +rtl8367s_gsw-objs += rtl8367c/storm.o +rtl8367s_gsw-objs += rtl8367c/svlan.o +rtl8367s_gsw-objs += rtl8367c/trap.o +rtl8367s_gsw-objs += rtl8367c/trunk.o +rtl8367s_gsw-objs += rtl8367c/vlan.o + +ccflags-y += -Werror -D_LITTLE_ENDIAN -DMDC_MDIO_OPERATION + +ccflags-y += -Idrivers/net/phy/rtk/rtl8367c/include +ccflags-y += -Iinclude/linux/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/modules.builtin b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/modules.builtin new file mode 100755 index 00000000..961a70a1 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/modules.builtin @@ -0,0 +1 @@ +kernel/drivers/net/phy/rtk/rtl8367s_gsw.ko diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/acl.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/acl.c new file mode 100755 index 00000000..75e5a5e7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/acl.c @@ -0,0 +1,2061 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in ACL module. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +CONST_T rtk_uint8 filter_templateField[RTL8367C_ACLTEMPLATENO][RTL8367C_ACLRULEFIELDNO] = { + {ACL_DMAC0, ACL_DMAC1, ACL_DMAC2, ACL_SMAC0, ACL_SMAC1, ACL_SMAC2, ACL_ETHERTYPE, ACL_FIELD_SELECT15}, + {ACL_IP4SIP0, ACL_IP4SIP1, ACL_IP4DIP0, ACL_IP4DIP1, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT02, ACL_FIELD_SELECT15}, + {ACL_IP6SIP0WITHIPV4, ACL_IP6SIP1WITHIPV4,ACL_FIELD_SELECT03, ACL_FIELD_SELECT04, ACL_FIELD_SELECT05, ACL_FIELD_SELECT06, ACL_FIELD_SELECT07, ACL_FIELD_SELECT08}, + {ACL_IP6DIP0WITHIPV4, ACL_IP6DIP1WITHIPV4,ACL_FIELD_SELECT09, ACL_FIELD_SELECT10, ACL_FIELD_SELECT11, ACL_FIELD_SELECT12, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14}, + {ACL_VIDRANGE, ACL_IPRANGE, ACL_PORTRANGE, ACL_CTAG, ACL_STAG, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT15} +}; + +CONST_T rtk_uint8 filter_advanceCaretagField[RTL8367C_ACLTEMPLATENO][2] = { + {TRUE, 7}, + {TRUE, 7}, + {FALSE, 0}, + {FALSE, 0}, + {TRUE, 7}, +}; + + +CONST_T rtk_uint8 filter_fieldTemplateIndex[FILTER_FIELD_END][RTK_FILTER_FIELD_USED_MAX] = { + {0x00, 0x01,0x02}, + {0x03, 0x04,0x05}, + {0x06}, + {0x43}, + {0x44}, + {0x10, 0x11}, + {0x12, 0x13}, + {0x24}, + {0x25}, + {0x35}, + {0x35}, + {0x20, 0x21,0x22,0x23}, + {0x30, 0x31,0x32,0x33}, + {0x26}, + {0x27}, + {0x14}, + {0x15}, + {0x16}, + {0x14}, + {0x15}, + {0x14}, + {0x14}, + {0x14}, + + {0x40}, + {0x41}, + {0x42}, + + {0x14}, + {0x15}, + {0x16}, + {0x22}, + {0x23}, + {0x24}, + {0x25}, + {0x26}, + {0x27}, + {0x32}, + {0x33}, + {0x34}, + {0x35}, + {0x36}, + {0x37}, + {0x47}, + + {0xFF} /* Pattern Match */ +}; + +CONST_T rtk_uint8 filter_fieldSize[FILTER_FIELD_END] = { + 3, 3, 1, 1, 1, + 2, 2, 1, 1, 1, 1, 4, 4, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8 +}; + +CONST_T rtk_uint16 field_selector[RTL8367C_FIELDSEL_FORMAT_NUMBER][2] = +{ + {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 0 */ + {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 1 */ + {FIELDSEL_FORMAT_IPPAYLOAD, 12}, /* Field Selector 2 */ + {FIELDSEL_FORMAT_IPV6, 10}, /* Field Selector 3 */ + {FIELDSEL_FORMAT_IPV6, 8}, /* Field Selector 4 */ + {FIELDSEL_FORMAT_IPV4, 0}, /* Field Selector 5 */ + {FIELDSEL_FORMAT_IPV4, 8}, /* Field Selector 6 */ + {FIELDSEL_FORMAT_IPV6, 0}, /* Field Selector 7 */ + {FIELDSEL_FORMAT_IPV6, 6}, /* Field Selector 8 */ + {FIELDSEL_FORMAT_IPV6, 26}, /* Field Selector 9 */ + {FIELDSEL_FORMAT_IPV6, 24}, /* Field Selector 10 */ + {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 11 */ + {FIELDSEL_FORMAT_IPV4, 6}, /* Field Selector 12 */ + {FIELDSEL_FORMAT_IPPAYLOAD, 0}, /* Field Selector 13 */ + {FIELDSEL_FORMAT_IPPAYLOAD, 2}, /* Field Selector 14 */ + {FIELDSEL_FORMAT_DEFAULT, 0} /* Field Selector 15 */ +}; + + +static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr); + + +/* Function Name: + * rtk_filter_igrAcl_init + * Description: + * ACL initialization function + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * Note: + * This function enable and intialize ACL function + */ +rtk_api_ret_t rtk_filter_igrAcl_init(void) +{ + rtl8367c_acltemplate_t aclTemp; + rtk_uint32 i, j; + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((ret = rtk_filter_igrAcl_cfg_delAll()) != RT_ERR_OK) + return ret; + + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + for(j = 0; j < RTL8367C_ACLRULEFIELDNO;j++) + aclTemp.field[j] = filter_templateField[i][j]; + + if ((ret = rtl8367c_setAsicAclTemplate(i, &aclTemp)) != RT_ERR_OK) + return ret; + } + + for(i = 0; i < RTL8367C_FIELDSEL_FORMAT_NUMBER; i++) + { + if ((ret = rtl8367c_setAsicFieldSelector(i, field_selector[i][0], field_selector[i][1])) != RT_ERR_OK) + return ret; + } + + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((ret = rtl8367c_setAsicAcl(i, TRUE)) != RT_ERR_OK) + return ret; + + if ((ret = rtl8367c_setAsicAclUnmatchedPermit(i, TRUE)) != RT_ERR_OK) + return ret; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_field_add + * Description: + * Add comparison rule to an ACL configuration + * Input: + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_field - The comparison rule that will be added. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg). + * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL + * comparison rules by means of linked list. Pointer pFilter_field will be added to linked + * list keeped by structure that pFilter_cfg points to. + */ +rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t* pFilter_cfg, rtk_filter_field_t* pFilter_field) +{ + rtk_uint32 i; + rtk_filter_field_t *tailPtr; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pFilter_cfg || NULL == pFilter_field) + return RT_ERR_NULL_POINTER; + + if(pFilter_field->fieldType >= FILTER_FIELD_END) + return RT_ERR_ENTRY_INDEX; + + + if(0 == pFilter_field->fieldTemplateNo) + { + pFilter_field->fieldTemplateNo = filter_fieldSize[pFilter_field->fieldType]; + + for(i = 0; i < pFilter_field->fieldTemplateNo; i++) + { + pFilter_field->fieldTemplateIdx[i] = filter_fieldTemplateIndex[pFilter_field->fieldType][i]; + } + } + + if(NULL == pFilter_cfg->fieldHead) + { + pFilter_cfg->fieldHead = pFilter_field; + } + else + { + if (pFilter_cfg->fieldHead->next == NULL) + { + pFilter_cfg->fieldHead->next = pFilter_field; + } + else + { + tailPtr = pFilter_cfg->fieldHead->next; + while( tailPtr->next != NULL) + { + tailPtr = tailPtr->next; + } + tailPtr->next = pFilter_field; + } + } + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr) +{ + rtk_uint32 i, tempIdx,fieldIdx, ipValue, ipMask; + rtk_uint32 ip6addr[RTK_IPV6_ADDR_WORD_LENGTH]; + rtk_uint32 ip6mask[RTK_IPV6_ADDR_WORD_LENGTH]; + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + + aclRule[tempIdx].valid = TRUE; + } + + switch (fieldPtr->fieldType) + { + /* use DMAC structure as representative for mac structure */ + case FILTER_FIELD_DMAC: + case FILTER_FIELD_SMAC: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.value.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.value.octet[5 - (i*2 + 1)] << 8); + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.mask.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.mask.octet[5 - (i*2 + 1)] << 8); + } + break; + case FILTER_FIELD_ETHERTYPE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.mask; + } + break; + case FILTER_FIELD_IPV4_SIP: + case FILTER_FIELD_IPV4_DIP: + + ipValue = fieldPtr->filter_pattern_union.sip.value; + ipMask = fieldPtr->filter_pattern_union.sip.mask; + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = (0xFFFF & (ipValue >> (i*16))); + aclRule[tempIdx].care_bits.field[fieldIdx] = (0xFFFF & (ipMask >> (i*16))); + } + break; + case FILTER_FIELD_IPV4_TOS: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.value & 0xFF; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.mask & 0xFF; + } + break; + case FILTER_FIELD_IPV4_PROTOCOL: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.value & 0xFF; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.mask & 0xFF; + } + break; + case FILTER_FIELD_IPV6_SIPV6: + case FILTER_FIELD_IPV6_DIPV6: + for(i = 0; i < RTK_IPV6_ADDR_WORD_LENGTH; i++) + { + ip6addr[i] = fieldPtr->filter_pattern_union.sipv6.value.addr[i]; + ip6mask[i] = fieldPtr->filter_pattern_union.sipv6.mask.addr[i]; + } + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + if(i < 2) + { + aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[0] & (0xFFFF << (i * 16))) >> (i * 16)); + aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[0] & (0xFFFF << (i * 16))) >> (i * 16)); + } + else + { + /*default acl template for ipv6 address supports MSB 32-bits and LSB 32-bits only*/ + aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); + aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); + } + } + + break; + case FILTER_FIELD_CTAG: + case FILTER_FIELD_STAG: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.value << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.value << 12) | fieldPtr->filter_pattern_union.l2tag.vid.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.mask << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.mask << 12) | fieldPtr->filter_pattern_union.l2tag.vid.mask; + } + break; + case FILTER_FIELD_IPV4_FLAG: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x1FFF; + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.value << 15); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.value << 14); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.value << 13); + + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x1FFF; + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.mask << 15); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.mask << 14); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.mask << 13); + } + + break; + case FILTER_FIELD_IPV4_OFFSET: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xE000; + aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.value; + + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xE000; + aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.mask; + } + + break; + + case FILTER_FIELD_IPV6_TRAFFIC_CLASS: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + + aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.value << 4)&0x0FF0; + aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.mask << 4)&0x0FF0; + } + break; + case FILTER_FIELD_IPV6_NEXT_HEADER: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value << 8; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask << 8; + } + break; + case FILTER_FIELD_TCP_SPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.mask; + } + break; + case FILTER_FIELD_TCP_DPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.mask; + } + break; + case FILTER_FIELD_TCP_FLAG: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.value << 7); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.value << 6); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.value << 5); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.value << 4); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.value << 3); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.value << 2); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.value << 1); + aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.value; + + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.mask << 7); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.mask << 6); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.mask << 5); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.mask << 4); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.mask << 3); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.mask << 2); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.mask << 1); + aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.mask; + } + break; + case FILTER_FIELD_UDP_SPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.mask; + } + break; + case FILTER_FIELD_UDP_DPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.mask; + } + break; + case FILTER_FIELD_ICMP_CODE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xFF00; + aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.value; + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xFF00; + aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.mask; + } + break; + case FILTER_FIELD_ICMP_TYPE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x00FF; + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.value << 8); + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x00FF; + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.mask << 8); + } + break; + case FILTER_FIELD_IGMP_TYPE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.value << 8); + aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.mask << 8); + } + break; + case FILTER_FIELD_PATTERN_MATCH: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.value[i/2] >> (16 * (i%2))) & 0x0000FFFF ); + aclRule[tempIdx].care_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.mask[i/2] >> (16 * (i%2))) & 0x0000FFFF ); + } + break; + case FILTER_FIELD_VID_RANGE: + case FILTER_FIELD_IP_RANGE: + case FILTER_FIELD_PORT_RANGE: + default: + tempIdx = (fieldPtr->fieldTemplateIdx[0] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[0] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask; + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_add + * Description: + * Add an ACL configuration to ASIC + * Input: + * filter_id - Start index of ACL configuration. + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_action - Action(s) of ACL configuration. + * Output: + * ruleNum - number of rules written in acl table + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENTRY_INDEX - Invalid filter_id . + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip. + * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported. + * Note: + * This function store pFilter_cfg, pFilter_action into ASIC. The starting + * index(es) is filter_id. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t* pFilter_cfg, rtk_filter_action_t* pFilter_action, rtk_filter_number_t *ruleNum) +{ + rtk_api_ret_t retVal; + rtk_uint32 careTagData, careTagMask; + rtk_uint32 i,vidx, svidx, actType, ruleId; + rtk_uint32 aclActCtrl; + rtk_uint32 cpuPort; + rtk_filter_field_t* fieldPtr; + rtl8367c_aclrule aclRule[RTL8367C_ACLTEMPLATENO]; + rtl8367c_aclrule tempRule; + rtl8367c_acl_act_t aclAct; + rtk_uint32 noRulesAdd; + rtk_uint32 portmask; + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(filter_id > RTL8367C_ACLRULEMAX ) + return RT_ERR_ENTRY_INDEX; + + if((NULL == pFilter_cfg) || (NULL == pFilter_action) || (NULL == ruleNum)) + return RT_ERR_NULL_POINTER; + + fieldPtr = pFilter_cfg->fieldHead; + + /* init RULE */ + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + memset(&aclRule[i], 0, sizeof(rtl8367c_aclrule)); + + aclRule[i].data_bits.type= i; + aclRule[i].care_bits.type= 0x7; + } + + while(NULL != fieldPtr) + { + _rtk_filter_igrAcl_writeDataField(aclRule, fieldPtr); + + fieldPtr = fieldPtr->next; + } + + /*set care tag mask in User Defined Field 15*/ + /*Follow care tag should not be used while ACL template and User defined fields are fully control by system designer*/ + /*those advanced packet type care tag is used in default template design structure only*/ + careTagData = 0; + careTagMask = 0; + + for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) + { + if(pFilter_cfg->careTag.tagType[i].mask) + careTagMask = careTagMask | (1 << (i-CARE_TAG_TCP)); + + if(pFilter_cfg->careTag.tagType[i].value) + careTagData = careTagData | (1 << (i-CARE_TAG_TCP)); + } + + if(careTagData || careTagMask) + { + i = 0; + while(i < RTL8367C_ACLTEMPLATENO) + { + if(aclRule[i].valid == 1 && filter_advanceCaretagField[i][0] == TRUE) + { + + aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; + aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; + break; + } + i++; + } + /*none of previous used template containing field 15*/ + if(i == RTL8367C_ACLTEMPLATENO) + { + i = 0; + while(i < RTL8367C_ACLTEMPLATENO) + { + if(filter_advanceCaretagField[i][0] == TRUE) + { + aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; + aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; + aclRule[i].valid = 1; + break; + } + i++; + } + } + } + + /*Check rule number*/ + noRulesAdd = 0; + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + if(1 == aclRule[i].valid) + { + noRulesAdd ++; + } + } + + *ruleNum = noRulesAdd; + + if((filter_id + noRulesAdd - 1) > RTL8367C_ACLRULEMAX) + { + return RT_ERR_ENTRY_INDEX; + } + + /*set care tag mask in TAG Indicator*/ + careTagData = 0; + careTagMask = 0; + + for(i = 0; i <= CARE_TAG_IPV6;i++) + { + if(0 == pFilter_cfg->careTag.tagType[i].mask ) + { + careTagMask &= ~(1 << i); + } + else + { + careTagMask |= (1 << i); + if(0 == pFilter_cfg->careTag.tagType[i].value ) + careTagData &= ~(1 << i); + else + careTagData |= (1 << i); + } + } + + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + aclRule[i].data_bits.tag_exist = (careTagData) & ACL_RULE_CARETAG_MASK; + aclRule[i].care_bits.tag_exist = (careTagMask) & ACL_RULE_CARETAG_MASK; + } + + RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.value); + RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.mask); + + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + if(TRUE == aclRule[i].valid) + { + if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.value, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + + aclRule[i].data_bits.active_portmsk = portmask; + + if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.mask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + + aclRule[i].care_bits.active_portmsk = portmask; + } + } + + if(pFilter_cfg->invert >= FILTER_INVERT_END ) + return RT_ERR_INPUT; + + + /*Last action gets high priority if actions are the same*/ + memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); + aclActCtrl = 0; + for(actType = 0; actType < FILTER_ENACT_END; actType ++) + { + if(pFilter_action->actEnable[actType]) + { + switch (actType) + { + case FILTER_ENACT_CVLAN_INGRESS: + if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) + { + return retVal; + } + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + aclAct.cvidx_cact = vidx; + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_CVLAN_EGRESS: + if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) + return retVal; + + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + aclAct.cvidx_cact = vidx; + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_CVLAN_SVID: + + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_POLICING_1: + if(pFilter_action->filterPolicingIdx[1] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + aclAct.cvidx_cact = pFilter_action->filterPolicingIdx[1]; + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + + case FILTER_ENACT_SVLAN_INGRESS: + case FILTER_ENACT_SVLAN_EGRESS: + + if((retVal = rtk_svlan_checkAndCreateMbr(pFilter_action->filterSvlanVid, &svidx)) != RT_ERR_OK) + return retVal; + + aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); + aclAct.svidx_sact = svidx; + aclActCtrl |= FILTER_ENACT_SVLAN_MASK; + break; + case FILTER_ENACT_SVLAN_CVID: + + aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); + aclActCtrl |= FILTER_ENACT_SVLAN_MASK; + break; + case FILTER_ENACT_POLICING_2: + if(pFilter_action->filterPolicingIdx[2] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); + aclAct.svidx_sact = pFilter_action->filterPolicingIdx[2]; + aclActCtrl |= FILTER_ENACT_SVLAN_MASK; + break; + case FILTER_ENACT_POLICING_0: + if(pFilter_action->filterPolicingIdx[0] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.aclmeteridx = pFilter_action->filterPolicingIdx[0]; + aclActCtrl |= FILTER_ENACT_POLICING_MASK; + break; + case FILTER_ENACT_PRIORITY: + case FILTER_ENACT_1P_REMARK: + if(pFilter_action->filterPriority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); + aclAct.pridx = pFilter_action->filterPriority; + aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; + break; + case FILTER_ENACT_DSCP_REMARK: + if(pFilter_action->filterPriority > RTL8367C_DSCPMAX) + return RT_ERR_INPUT; + + aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); + aclAct.pridx = pFilter_action->filterPriority; + aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; + break; + case FILTER_ENACT_POLICING_3: + if(pFilter_action->filterPriority >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); + aclAct.pridx = pFilter_action->filterPolicingIdx[3]; + aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; + break; + case FILTER_ENACT_DROP: + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_REDIRECT); + aclAct.fwdact_ext = FALSE; + + aclAct.fwdpmask = 0; + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_REDIRECT: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.fwdact_ext = FALSE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + + case FILTER_ENACT_ADD_DSTPORT: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.fwdact_ext = FALSE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_MIRROR: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.cact_ext = FALSE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_TRAP_CPU: + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.fwdact_ext = FALSE; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_COPY_CPU: + if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) + return retVal; + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_MIRROR); + aclAct.fwdact_ext = FALSE; + + aclAct.fwdpmask = 1 << cpuPort; + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_ISOLATION: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact_ext = TRUE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + + case FILTER_ENACT_INTERRUPT: + + aclAct.aclint = TRUE; + aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; + break; + case FILTER_ENACT_GPO: + + aclAct.gpio_en = TRUE; + aclAct.gpio_pin = pFilter_action->filterPin; + aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_TAG: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_TAG; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_UNTAG: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_UNTAG; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_KEEP: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_KEEP; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_KEEP1PRMK; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + default: + return RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT; + } + } + } + + + /*check if free ACL rules are enough*/ + for(i = filter_id; i < (filter_id + noRulesAdd); i++) + { + if((retVal = rtl8367c_getAsicAclRule(i, &tempRule)) != RT_ERR_OK ) + return retVal; + + if(tempRule.valid == TRUE) + { + return RT_ERR_TBL_FULL; + } + } + + ruleId = 0; + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + if(aclRule[i].valid == TRUE) + { + /* write ACL action control */ + if((retVal = rtl8367c_setAsicAclActCtrl(filter_id + ruleId, aclActCtrl)) != RT_ERR_OK ) + return retVal; + /* write ACL action */ + if((retVal = rtl8367c_setAsicAclAct(filter_id + ruleId, &aclAct)) != RT_ERR_OK ) + return retVal; + + /* write ACL not */ + if((retVal = rtl8367c_setAsicAclNot(filter_id + ruleId, pFilter_cfg->invert)) != RT_ERR_OK ) + return retVal; + /* write ACL rule */ + if((retVal = rtl8367c_setAsicAclRule(filter_id + ruleId, &aclRule[i])) != RT_ERR_OK ) + return retVal; + + /* only the first rule will be written with input action control, aclActCtrl of other rules will be zero */ + aclActCtrl = 0; + memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); + + ruleId ++; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_del + * Description: + * Delete an ACL configuration from ASIC + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id. + * Note: + * This function delete a group of ACL rules starting from filter_id. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id) +{ + rtl8367c_aclrule initRule; + rtl8367c_acl_act_t initAct; + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(filter_id > RTL8367C_ACLRULEMAX ) + return RT_ERR_FILTER_ENTRYIDX; + + memset(&initRule, 0, sizeof(rtl8367c_aclrule)); + memset(&initAct, 0, sizeof(rtl8367c_acl_act_t)); + + if((ret = rtl8367c_setAsicAclRule(filter_id, &initRule)) != RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclActCtrl(filter_id, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclAct(filter_id, &initAct)) != RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclNot(filter_id, DISABLED)) != RT_ERR_OK ) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_delAll + * Description: + * Delete all ACL entries from ASIC + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function delete all ACL configuration from ASIC. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void) +{ + rtk_uint32 i; + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + for(i = 0; i < RTL8367C_ACLRULENO; i++) + { + if((ret = rtl8367c_setAsicAclActCtrl(i, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclNot(i, DISABLED)) != RT_ERR_OK ) + return ret; + } + + return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_RESET_CFG, RTL8367C_ACL_RESET_CFG_OFFSET, TRUE);; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_get + * Description: + * Get one ingress acl configuration from ASIC. + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * pFilter_cfg - buffer pointer of ingress acl data + * pFilter_action - buffer pointer of ingress acl action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_ENTRYIDX - Invalid entry index. + * Note: + * This function get configuration from ASIC. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, tmp; + rtl8367c_aclrule aclRule; + rtl8367c_acl_act_t aclAct; + rtk_uint32 cpuPort; + rtl8367c_acltemplate_t type; + rtl8367c_svlan_memconf_t svlan_cfg; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 phyPmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pFilter_cfg || NULL == pAction) + return RT_ERR_NULL_POINTER; + + if(filter_id > RTL8367C_ACLRULEMAX) + return RT_ERR_ENTRY_INDEX; + + if ((retVal = rtl8367c_getAsicAclRule(filter_id, &aclRule)) != RT_ERR_OK) + return retVal; + + /* Check valid */ + if(aclRule.valid == 0) + { + pFilter_cfg->valid = DISABLED; + return RT_ERR_OK; + } + + phyPmask = aclRule.data_bits.active_portmsk; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.value)) != RT_ERR_OK) + return RT_ERR_FAILED; + + phyPmask = aclRule.care_bits.active_portmsk; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.mask)) != RT_ERR_OK) + return RT_ERR_FAILED; + + for(i = 0; i <= CARE_TAG_IPV6; i++) + { + if(aclRule.data_bits.tag_exist & (1 << i)) + pFilter_cfg->careTag.tagType[i].value = 1; + else + pFilter_cfg->careTag.tagType[i].value = 0; + + if (aclRule.care_bits.tag_exist & (1 << i)) + pFilter_cfg->careTag.tagType[i].mask = 1; + else + pFilter_cfg->careTag.tagType[i].mask = 0; + } + + if(filter_advanceCaretagField[aclRule.data_bits.type][0] == TRUE) + { + /* Advanced Care tag setting */ + for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) + { + if(aclRule.data_bits.field[filter_advanceCaretagField[aclRule.data_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) + pFilter_cfg->careTag.tagType[i].value = 1; + else + pFilter_cfg->careTag.tagType[i].value = 0; + + if(aclRule.care_bits.field[filter_advanceCaretagField[aclRule.care_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) + pFilter_cfg->careTag.tagType[i].mask = 1; + else + pFilter_cfg->careTag.tagType[i].mask = 0; + } + } + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + { + pFilter_cfg->careFieldRaw[i] = aclRule.care_bits.field[i]; + pFilter_cfg->dataFieldRaw[i] = aclRule.data_bits.field[i]; + } + + if ((retVal = rtl8367c_getAsicAclNot(filter_id, &tmp))!= RT_ERR_OK) + return retVal; + + pFilter_cfg->invert = tmp; + + pFilter_cfg->valid = aclRule.valid; + + memset(pAction, 0, sizeof(rtk_filter_action_t)); + + if ((retVal = rtl8367c_getAsicAclActCtrl(filter_id, &tmp))!= RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicAclAct(filter_id, &aclAct)) != RT_ERR_OK) + return retVal; + + if(tmp & FILTER_ENACT_FWD_MASK) + { + if(TRUE == aclAct.fwdact_ext) + { + pAction->actEnable[FILTER_ENACT_ISOLATION] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + else if(aclAct.fwdact == RTL8367C_ACL_FWD_TRAP) + { + pAction->actEnable[FILTER_ENACT_TRAP_CPU] = TRUE; + } + else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRRORFUNTION ) + { + pAction->actEnable[FILTER_ENACT_MIRROR] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + else if (aclAct.fwdact == RTL8367C_ACL_FWD_REDIRECT) + { + if(aclAct.fwdpmask == 0 ) + pAction->actEnable[FILTER_ENACT_DROP] = TRUE; + else + { + pAction->actEnable[FILTER_ENACT_REDIRECT] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + } + else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRROR) + { + if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) + return retVal; + if (aclAct.fwdpmask == (1 << cpuPort)) + { + pAction->actEnable[FILTER_ENACT_COPY_CPU] = TRUE; + } + else + { + pAction->actEnable[FILTER_ENACT_ADD_DSTPORT] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + } + else + { + return RT_ERR_FAILED; + } + } + + if(tmp & FILTER_ENACT_POLICING_MASK) + { + pAction->actEnable[FILTER_ENACT_POLICING_0] = TRUE; + pAction->filterPolicingIdx[0] = aclAct.aclmeteridx; + } + + if(tmp & FILTER_ENACT_PRIORITY_MASK) + { + if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_PRIORITY)) + { + pAction->actEnable[FILTER_ENACT_PRIORITY] = TRUE; + pAction->filterPriority = aclAct.pridx; + } + else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_1P_REMARK)) + { + pAction->actEnable[FILTER_ENACT_1P_REMARK] = TRUE; + pAction->filterPriority = aclAct.pridx; + } + else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_DSCP_REMARK)) + { + pAction->actEnable[FILTER_ENACT_DSCP_REMARK] = TRUE; + pAction->filterPriority = aclAct.pridx; + } + else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_POLICING_3)) + { + pAction->actEnable[FILTER_ENACT_POLICING_3] = TRUE; + pAction->filterPolicingIdx[3] = aclAct.pridx; + } + } + + if(tmp & FILTER_ENACT_SVLAN_MASK) + { + if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_INGRESS)) + { + if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_SVLAN_INGRESS] = TRUE; + pAction->filterSvlanIdx = aclAct.svidx_sact; + pAction->filterSvlanVid = svlan_cfg.vs_svid; + } + else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_EGRESS)) + { + if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_SVLAN_EGRESS] = TRUE; + pAction->filterSvlanIdx = aclAct.svidx_sact; + pAction->filterSvlanVid = svlan_cfg.vs_svid; + } + else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_CVID)) + pAction->actEnable[FILTER_ENACT_SVLAN_CVID] = TRUE; + else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_POLICING_2)) + { + pAction->actEnable[FILTER_ENACT_POLICING_2] = TRUE; + pAction->filterPolicingIdx[2] = aclAct.svidx_sact; + } + } + + + if(tmp & FILTER_ENACT_CVLAN_MASK) + { + if(FILTER_ENACT_CACTEXT_TAGONLY == aclAct.cact_ext || + FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) + { + if(FILTER_CTAGFMT_UNTAG == aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_UNTAG] = TRUE; + } + else if(FILTER_CTAGFMT_TAG == aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_TAG] = TRUE; + } + else if(FILTER_CTAGFMT_KEEP == aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEP] = TRUE; + } + else if(FILTER_CTAGFMT_KEEP1PRMK== aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK] = TRUE; + } + + } + + if(FILTER_ENACT_CACTEXT_VLANONLY == aclAct.cact_ext || + FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) + { + if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_INGRESS)) + { + if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_CVLAN_INGRESS] = TRUE; + pAction->filterCvlanIdx = aclAct.cvidx_cact; + pAction->filterCvlanVid = vlanMC.evid; + } + else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_EGRESS)) + { + if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_CVLAN_EGRESS] = TRUE; + pAction->filterCvlanIdx = aclAct.cvidx_cact; + pAction->filterCvlanVid = vlanMC.evid; + } + else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_SVID)) + { + pAction->actEnable[FILTER_ENACT_CVLAN_SVID] = TRUE; + } + else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_POLICING_1)) + { + pAction->actEnable[FILTER_ENACT_POLICING_1] = TRUE; + pAction->filterPolicingIdx[1] = aclAct.cvidx_cact; + } + } + } + + if(tmp & FILTER_ENACT_INTGPIO_MASK) + { + if(TRUE == aclAct.aclint) + { + pAction->actEnable[FILTER_ENACT_INTERRUPT] = TRUE; + } + + if(TRUE == aclAct.gpio_en) + { + pAction->actEnable[FILTER_ENACT_GPO] = TRUE; + pAction->filterPin = aclAct.gpio_pin; + } + } + + /* Get field type of RAW data */ + if ((retVal = rtl8367c_getAsicAclTemplate(aclRule.data_bits.type, &type))!= RT_ERR_OK) + return retVal; + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + { + pFilter_cfg->fieldRawType[i] = type.field[i]; + }/* end of for(i...) */ + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_set + * Description: + * Set action to packets when no ACL configuration match + * Input: + * port - Port id. + * action - Action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function sets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(action >= FILTER_UNMATCH_END) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), action)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_get + * Description: + * Get action to packets when no ACL configuration match + * Input: + * port - Port id. + * Output: + * pAction - Action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* pAction) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if((ret = rtl8367c_getAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), pAction)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_state_set + * Description: + * Set state of ingress ACL. + * Input: + * port - Port id. + * state - Ingress ACL state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAcl(rtk_switch_port_L2P_get(port), state)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_state_get + * Description: + * Get state of ingress ACL. + * Input: + * port - Port id. + * Output: + * pState - Ingress ACL state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* pState) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pState) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if((ret = rtl8367c_getAsicAcl(rtk_switch_port_L2P_get(port), pState)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} +/* Function Name: + * rtk_filter_igrAcl_template_set + * Description: + * Set template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function set ACL template. + */ +rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate) +{ + rtk_api_ret_t retVal; + rtk_uint32 idxField; + rtl8367c_acltemplate_t aclType; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) + return RT_ERR_INPUT; + + for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) + { + if(aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_DMAC_15_0 || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_CTAG && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV4_SIP_15_0 ) || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV4_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV6_SIP_15_0 ) || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV6_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_VIDRANGE ) || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_FIELD_VALID && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_FIELD_SELECT00 ) || + aclTemplate->fieldType[idxField] >= FILTER_FIELD_RAW_END) + { + return RT_ERR_INPUT; + } + } + + for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) + { + aclType.field[idxField] = aclTemplate->fieldType[idxField]; + } + + if((retVal = rtl8367c_setAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_template_get + * Description: + * Get template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function gets template of ACL. + */ +rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate) +{ + rtk_api_ret_t ret; + rtk_uint32 idxField; + rtl8367c_acltemplate_t aclType; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == aclTemplate) + return RT_ERR_NULL_POINTER; + + if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) + return RT_ERR_INPUT; + + if((ret = rtl8367c_getAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) + return ret; + + for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField ++) + { + aclTemplate->fieldType[idxField] = aclType.field[idxField]; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_field_sel_set + * Description: + * Set user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * format - Format of field selector + * offset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * System support 16 user defined field selctors. + * Each selector can be enabled or disable. + * User can defined retrieving 16-bits in many predefiend + * standard l2/l3/l4 payload. + */ +rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if(format >= FORMAT_END) + return RT_ERR_OUT_OF_RANGE; + + if(offset > RTL8367C_FIELDSEL_MAX_OFFSET) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_setAsicFieldSelector(index, (rtk_uint32)format, offset)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_field_sel_get + * Description: + * Get user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * Output: + * pFormat - Format of field selector + * pOffset - Retrieving data offset + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pFormat || NULL == pOffset) + return RT_ERR_NULL_POINTER; + + if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicFieldSelector(index, pFormat, pOffset)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_iprange_set + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * upperIp - The upper bound of IP range + * lowerIp - The lower Bound of IP range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperIp must be larger or equal than lowerIp. + */ +rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(type >= IPRANGE_END) + return RT_ERR_OUT_OF_RANGE; + + if(lowerIp > upperIp) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAclIpRange(index, type, upperIp, lowerIp)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_iprange_get + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * pUpperIp - The upper bound of IP range + * pLowerIp - The lower Bound of IP range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((NULL == pType) || (NULL == pUpperIp) || (NULL == pLowerIp)) + return RT_ERR_NULL_POINTER; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicAclIpRange(index, pType, pUpperIp, pLowerIp)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_vidrange_set + * Description: + * Set VID Range check + * Input: + * index - index of VID Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID + * upperVid - The upper bound of VID range + * lowerVid - The lower Bound of VID range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperVid must be larger or equal than lowerVid. + */ +rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(type >= VIDRANGE_END) + return RT_ERR_OUT_OF_RANGE; + + if(lowerVid > upperVid) + return RT_ERR_INPUT; + + if( (upperVid > RTL8367C_VIDMAX) || (lowerVid > RTL8367C_VIDMAX)) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_setAsicAclVidRange(index, type, upperVid, lowerVid)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_vidrange_get + * Description: + * Get VID Range check + * Input: + * index - index of VID Range 0-15 + * Output: + * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID + * pUpperVid - The upper bound of VID range + * pLowerVid - The lower Bound of VID range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((NULL == pType) || (NULL == pUpperVid) || (NULL == pLowerVid)) + return RT_ERR_NULL_POINTER; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicAclVidRange(index, pType, pUpperVid, pLowerVid)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_portrange_set + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * upperPort - The upper bound of Port range + * lowerPort - The lower Bound of Port range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperPort must be larger or equal than lowerPort. + */ +rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(type >= PORTRANGE_END) + return RT_ERR_OUT_OF_RANGE; + + if(lowerPort > upperPort) + return RT_ERR_INPUT; + + if(upperPort > RTL8367C_ACL_PORTRANGEMAX) + return RT_ERR_INPUT; + + if(lowerPort > RTL8367C_ACL_PORTRANGEMAX) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAclPortRange(index, type, upperPort, lowerPort)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_portrange_get + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * pUpperPort - The upper bound of Port range + * pLowerPort - The lower Bound of Port range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((NULL == pType) || (NULL == pUpperPort) || (NULL == pLowerPort)) + return RT_ERR_NULL_POINTER; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicAclPortRange(index, pType, pUpperPort, pLowerPort)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAclPolarity_set + * Description: + * Set ACL Goip control palarity + * Input: + * polarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(polarity > 1) + return RT_ERR_OUT_OF_RANGE; + return rtl8367c_setAsicAclGpioPolarity(polarity); +} +/* Function Name: + * rtk_filter_igrAclPolarity_get + * Description: + * Get ACL Goip control palarity + * Input: + * pPolarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPolarity) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicAclGpioPolarity(pPolarity); +} + + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/cpu.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/cpu.c new file mode 100755 index 00000000..d1cd95b3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/cpu.c @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in CPU module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_cpu_enable_set + * Description: + * Set CPU port function enable/disable. + * Input: + * enable - CPU port function enable + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port function enable/disable. + */ +rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicCputagEnable(enable)) != RT_ERR_OK) + return retVal; + + if (DISABLED == enable) + { + if ((retVal = rtl8367c_setAsicCputagPortmask(0)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_enable_get + * Description: + * Get CPU port and its setting. + * Input: + * None + * Output: + * pEnable - CPU port function enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist + * Note: + * The API can get CPU port function enable/disable. + */ +rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagEnable(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagPort_set + * Description: + * Set CPU port and CPU tag insert mode. + * Input: + * port - Port id. + * mode - CPU tag insert for packets egress from CPU port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899) + * to the frame that transmitting to CPU port. + * The inset cpu tag mode is as following: + * - CPU_INSERT_TO_ALL + * - CPU_INSERT_TO_TRAPPING + * - CPU_INSERT_TO_NONE + */ +rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (mode >= CPU_INSERT_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagPortmask(1<= CPU_POS_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagPosition(position)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagPosition_get + * Description: + * Get CPU tag position. + * Input: + * None + * Output: + * pPosition - CPU tag position. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag position. + */ +rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPosition) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagPosition(pPosition)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagLength_set + * Description: + * Set CPU tag length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU tag length. + */ +rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (length >= CPU_LEN_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagMode(length)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagLength_get + * Description: + * Get CPU tag length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag length. + */ +rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pLength) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagMode(pLength)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_priRemap_set + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * new_pri - new internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (new_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if ((retVal = rtl8367c_setAsicCputagPriorityRemapping(int_pri, new_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_priRemap_get + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * Output: + * pNew_pri - new internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pNew_pri) + return RT_ERR_NULL_POINTER; + + if (int_pri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicCputagPriorityRemapping(int_pri, pNew_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_acceptLength_set + * Description: + * Set CPU accept length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU accept length. + */ +rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (length >= CPU_RX_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagRxMinLength(length)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_acceptLength_get + * Description: + * Get CPU accept length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU accept length. + */ +rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pLength) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagRxMinLength(pLength)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/dot1x.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/dot1x.c new file mode 100755 index 00000000..c9b146a6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/dot1x.c @@ -0,0 +1,843 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 75783 $ + * $Date: 2017-02-13 14:54:53 +0800 (週一, 13 二月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in 1X module. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_dot1x_unauthPacketOper_set + * Description: + * Set 802.1x unauth action configuration. + * Input: + * port - Port id. + * unauth_action - 802.1X unauth action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (unauth_action >= DOT1X_ACTION_END) + return RT_ERR_DOT1X_PROC; + + if ((retVal = rtl8367c_setAsic1xProcConfig(rtk_switch_port_L2P_get(port), unauth_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_unauthPacketOper_get + * Description: + * Get 802.1x unauth action configuration. + * Input: + * port - Port id. + * Output: + * pUnauth_action - 802.1X unauth action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pUnauth_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xProcConfig(rtk_switch_port_L2P_get(port), pUnauth_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_set + * Description: + * Set 802.1x EAPOL packet trap to CPU configuration + * Input: + * enable - The status of 802.1x EAPOL packet. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + rmacfg.operation = RMAOP_TRAP_TO_CPU; + else if (DISABLED == enable) + rmacfg.operation = RMAOP_FORWARD; + + if ((retVal = rtl8367c_setAsicRma(3, &rmacfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_get + * Description: + * Get 802.1x EAPOL packet trap to CPU configuration + * Input: + * None + * Output: + * pEnable - The status of 802.1x EAPOL packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK) + return retVal; + + if (RMAOP_TRAP_TO_CPU == rmacfg.operation) + *pEnable = ENABLED; + else + *pEnable = DISABLED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedEnable_set + * Description: + * Set 802.1x port-based enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error + * Note: + * The API can update the port-based port enable register content. If a port is 802.1x + * port based network access control "enabled", it should be authenticated so packets + * from that port won't be dropped or trapped to CPU. + * The status of 802.1x port-based network access control is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsic1xPBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedEnable_get + * Description: + * Get 802.1x port-based enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the 802.1x port-based port status. + */ +rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xPBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_set + * Description: + * Set 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * port_auth - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error + * Note: + * The authenticated status of 802.1x port-based network access control is as following: + * - UNAUTH + * - AUTH + */ +rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (port_auth >= AUTH_STATUS_END) + return RT_ERR_DOT1X_PORTBASEDAUTH; + + if ((retVal = rtl8367c_setAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), port_auth)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_get + * Description: + * Get 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * Output: + * pPort_auth - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based port auth.information. + */ +rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPort_auth) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), pPort_auth)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedDirection_set + * Description: + * Set 802.1x port-based operational direction configuration + * Input: + * port - Port id. + * port_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error + * Note: + * The operate controlled direction of 802.1x port-based network access control is as following: + * - BOTH + * - IN + */ +rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (port_direction >= DIRECTION_END) + return RT_ERR_DOT1X_PORTBASEDOPDIR; + + if ((retVal = rtl8367c_setAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), port_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedDirection_get + * Description: + * Get 802.1X port-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pPort_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based operational direction information. + */ +rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPort_direction) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), pPort_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedEnable_set + * Description: + * Set 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port won't be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsic1xMBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedEnable_get + * Description: + * Get 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port wont be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsic1xMBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_add + * Description: + * Add an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT, + * user can't add this MAC to auth status. + */ +rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1)) + return RT_ERR_MAC; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if ( RT_ERR_OK == retVal) + { + if (l2Table.spa != rtk_switch_port_L2P_get(port)) + return RT_ERR_DOT1X_MAC_PORT_MISMATCH; + + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + l2Table.efid = 0; + l2Table.auth = 1; + retVal = rtl8367c_setAsicL2LookupTb(&l2Table); + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_del + * Description: + * Delete an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of + * the MAC and won't delete it from LUT. + */ +rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1)) + return RT_ERR_MAC; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + if (l2Table.spa != rtk_switch_port_L2P_get(port)) + return RT_ERR_DOT1X_MAC_PORT_MISMATCH; + + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + l2Table.auth = 0; + retVal = rtl8367c_setAsicL2LookupTb(&l2Table); + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_dot1x_macBasedDirection_set + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * mac_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error + * Note: + * The operate controlled direction of 802.1x mac-based network access control is as following: + * - BOTH + * - IN + */ +rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mac_direction >= DIRECTION_END) + return RT_ERR_DOT1X_MACBASEDOPDIR; + + if ((retVal = rtl8367c_setAsic1xMBOpdirConfig(mac_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedDirection_get + * Description: + * Get 802.1x mac-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pMac_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x mac-based operational direction information. + */ +rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMac_direction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xMBOpdirConfig(pMac_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * Set 802.1x guest VLAN configuration + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * vid - 802.1x guest VLAN ID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operate controlled 802.1x guest VLAN + */ +rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid) +{ + rtk_api_ret_t retVal; + rtk_uint32 index; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if((retVal = rtk_vlan_checkAndCreateMbr(vid, &index)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsic1xGuestVidx(index)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_guestVlan_get + * Description: + * Get 802.1x guest VLAN configuration + * Input: + * None + * Output: + * pVid - 802.1x guest VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN information. + */ +rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid) +{ + rtk_api_ret_t retVal; + rtk_uint32 gvidx; + rtl8367c_vlanconfiguser vlanMC; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pVid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xGuestVidx(&gvidx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicVlanMemberConfig(gvidx, &vlanMC)) != RT_ERR_OK) + return retVal; + + *pVid = vlanMC.evid; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_set + * Description: + * Set 802.1x guest VLAN to auth host configuration + * Input: + * enable - The status of guest VLAN to auth host. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operational direction of 802.1x guest VLAN to auth host control is as following: + * - ENABLED + * - DISABLED + */ +rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsic1xGVOpdir(enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_get + * Description: + * Get 802.1x guest VLAN to auth host configuration + * Input: + * None + * Output: + * pEnable - The status of guest VLAN to auth host. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN to auth host information. + */ +rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xGVOpdir(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/eee.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/eee.c new file mode 100755 index 00000000..cd14c2ce --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/eee.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 48156 $ + * $Date: 2014-05-29 16:39:06 +0800 (週四, 29 五月 2014) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in EEE module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* Function Name: + * rtk_eee_init + * Description: + * EEE function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize EEE status. + */ +rtk_api_ret_t rtk_eee_init(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((retVal = rtl8367c_setAsicRegBit(0x0018, 10, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x0018, 11, 1)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_eee_portEnable_set + * Description: + * Set enable status of EEE function. + * Input: + * port - port id. + * enable - enable EEE status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is UTP port */ + RTK_CHK_PORT_IS_UTP(port); + + if (enable>=RTK_ENABLE_END) + return RT_ERR_INPUT; + + phy_port = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_setAsicEee100M(phy_port,enable))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicEeeGiga(phy_port,enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYReg(phy_port, RTL8367C_PHY_PAGE_ADDRESS, 0))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicPHYReg(phy_port, 0, ®Data))!=RT_ERR_OK) + return retVal; + regData |= 0x0200; + if ((retVal = rtl8367c_setAsicPHYReg(phy_port, 0, regData))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_eee_portEnable_get + * Description: + * Get enable status of EEE function + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ + +rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData1, regData2; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is UTP port */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + phy_port = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_getAsicEee100M(phy_port,®Data1))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicEeeGiga(phy_port,®Data2))!=RT_ERR_OK) + return retVal; + + if (regData1==1&®Data2==1) + *pEnable = ENABLED; + else + *pEnable = DISABLED; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/i2c.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/i2c.c new file mode 100755 index 00000000..17a5f378 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/i2c.c @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 63932 $ + * $Date: 2015-12-08 14:06:29 +0800 (周二, 08 å二月 2015) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in i2c module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +static rtk_I2C_16bit_mode_t rtk_i2c_mode = I2C_LSB_16BIT_MODE; + + +/* Function Name: + * rtk_i2c_init + * Description: + * I2C smart function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * This API is used to initialize EEE status. + * need used GPIO pins + * OpenDrain and clock + */ +rtk_api_ret_t rtk_i2c_init(void) +{ + rtk_uint32 retVal; + switch_chip_t ChipID; + /* probe switch */ + if((retVal = rtk_switch_probe(&ChipID)) != RT_ERR_OK) + return retVal; + + if( ChipID == CHIP_RTL8370B ) + { + /*set GPIO8, GPIO9, OpenDrain as I2C, clock = 252KHZ */ + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, 0x5c3f)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_FAILED; + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_i2c_mode_set + * Description: + * Set I2C data byte-order. + * Input: + * i2cmode - byte-order mode + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set I2c traffic's byte-order . + */ +rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode ) +{ + if(i2cmode >= I2C_Mode_END) + { + return RT_ERR_INPUT; + } + else if(i2cmode == I2C_70B_LSB_16BIT_MODE) + { + rtk_i2c_mode = I2C_70B_LSB_16BIT_MODE; + + return RT_ERR_OK; + } + else if( i2cmode == I2C_LSB_16BIT_MODE) + { + rtk_i2c_mode = I2C_LSB_16BIT_MODE; + return RT_ERR_OK; + } + else + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_i2c_mode_get + * Description: + * Get i2c traffic byte-order setting. + * Input: + * None + * Output: + * pI2cMode - i2c byte-order + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c traffic byte-order setting. + */ +rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + if(NULL == pI2cMode) + return RT_ERR_NULL_POINTER; + if(rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) + *pI2cMode = 1; + else if ((rtk_i2c_mode == I2C_LSB_16BIT_MODE)) + *pI2cMode = 0; + else + return RT_ERR_FAILED; + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_i2c_gpioPinGroup_set + * Description: + * Set i2c SDA & SCL used GPIO pins group. + * Input: + * pins_group - GPIO pins group + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The API can set i2c used gpio pins group. + * There are three group pins could be used + */ +rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group ) +{ + rtk_uint32 retVal; + + + if( ( pins_group > I2C_GPIO_PIN_END )|| ( pins_group < I2C_GPIO_PIN_8_9) ) + return RT_ERR_INPUT; + + if( (retVal = rtl8367c_setAsicI2CGpioPinGroup(pins_group) ) != RT_ERR_OK ) + return retVal ; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_i2c_gpioPinGroup_get + * Description: + * Get i2c SDA & SCL used GPIO pins group. + * Input: + * None + * Output: + * pPins_group - GPIO pins group + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c used gpio pins group. + * There are three group pins could be used + */ +rtk_api_ret_t rtk_i2c_gpioPinGroup_get( rtk_I2C_gpio_pin_t * pPins_group ) +{ + rtk_uint32 retVal; + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPins_group) + return RT_ERR_NULL_POINTER; + if( (retVal = rtl8367c_getAsicI2CGpioPinGroup(pPins_group) ) != RT_ERR_OK ) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_i2c_data_read + * Description: + * read i2c slave device register. + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * Output: + * pRegData - read data + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can access i2c slave and read i2c slave device register. + */ +rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData) +{ + rtk_uint32 retVal, counter=0; + rtk_uint8 controlByte_W, controlByte_R; + rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp; + rtk_uint8 regData_L, regData_H; + + /* control byte :deviceAddress + W, deviceAddress + R */ + controlByte_W = (rtk_uint8)(deviceAddr << 1) ; + controlByte_R = (rtk_uint8)(controlByte_W | 0x1); + + slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ; + slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ; + + if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) + { + temp = slaveRegAddr_L ; + slaveRegAddr_L = slaveRegAddr_H; + slaveRegAddr_H = temp; + } + + + /*check bus state: idle*/ + for(counter = 3000; counter>0; counter--) + { + if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK) + break; + } + if( counter ==0 ) + return retVal; /*i2c is busy*/ + + /*tx Start cmd*/ + if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) + return retVal ; + + + /*tx control _W*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + /* tx slave buffer address low 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK ) + return retVal ; + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + + /* tx slave buffer address high 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Start cmd*/ + if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) + return retVal ; + + /*tx control _R*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_R))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /* rx low 8bit data*/ + if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( ®Data_L) ) != RT_ERR_OK ) + return retVal; + + + + /* tx ack to slave, keep receive */ + if( (retVal = rtl8367c_setAsicI2CTxAckCmd()) != RT_ERR_OK ) + return retVal; + + /* rx high 8bit data*/ + if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( ®Data_H) ) != RT_ERR_OK ) + return retVal; + + + + /* tx Noack to slave, Stop receive */ + if( (retVal = rtl8367c_setAsicI2CTxNoAckCmd()) != RT_ERR_OK ) + return retVal; + + + /*tx Stop cmd */ + if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK ) + return retVal; + + *pRegData = (regData_H << 8) | regData_L; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_i2c_data_write + * Description: + * write data to i2c slave device register + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * regData - data to set + * Output: + * None + * Return: + * RT_ERR_OK - OK + * Note: + * The API can access i2c slave and setting i2c slave device register. + */ +rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData) +{ + rtk_uint32 retVal,counter; + rtk_uint8 controlByte_W; + rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp; + rtk_uint8 regData_L, regData_H; + + /* control byte :deviceAddress + W */ + controlByte_W = (rtk_uint8)(deviceAddr<< 1) ; + + slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ; + slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ; + + regData_H = (rtk_uint8) (regData>> 8); + regData_L = (rtk_uint8) (regData & 0x00FF); + + if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) + { + temp = slaveRegAddr_L ; + slaveRegAddr_L = slaveRegAddr_H; + slaveRegAddr_H = temp; + } + + + /*check bus state: idle*/ + for(counter = 3000; counter>0; counter--) + { + if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK) + break; + } + + if( counter ==0 ) + return retVal; /*i2c is busy*/ + + + /*tx Start cmd*/ + if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) + return retVal ; + + + /*tx control _W*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /* tx slave buffer address low 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /* tx slave buffer address high 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Datavlue LSB*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_L))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Datavlue MSB*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_H))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Stop cmd */ + if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK ) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/igmp.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/igmp.c new file mode 100755 index 00000000..170cbdaa --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/igmp.c @@ -0,0 +1,1555 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in IGMP module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + + +/* Function Name: + * rtk_igmp_init + * Description: + * This API enables H/W IGMP and set a default initial configuration. + * Input: + * None. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API enables H/W IGMP and set a default initial configuration. + */ +rtk_api_ret_t rtk_igmp_init(void) +{ + rtk_api_ret_t retVal; + rtk_port_t port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicMLDv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicMLDv2Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_switch_phyPortMask_get()))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn(ENABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(1))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIgmp(ENABLED))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_state_set + * Description: + * This API set H/W IGMP state. + * Input: + * enabled - H/W IGMP state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set H/W IGMP state. + */ +rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIgmp(enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_state_get + * Description: + * This API get H/W IGMP state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current H/W IGMP state. + */ +rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pEnabled == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIgmp(pEnabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_static_router_port_set + * Description: + * Configure static router port + * Input: + * pPortmask - Static Port mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set static router port + */ +rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Valid port mask */ + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPStaticRouterPort(pmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_static_router_port_get + * Description: + * Get static router port + * Input: + * None. + * Output: + * pPortmask - Static port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API get static router port + */ +rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPStaticRouterPort(&pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_protocol_set + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action) +{ + rtk_uint32 operation; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(protocol >= PROTOCOL_END) + return RT_ERR_INPUT; + + if(action >= IGMP_ACTION_END) + return RT_ERR_INPUT; + + switch(action) + { + case IGMP_ACTION_FORWARD: + operation = PROTOCOL_OP_FLOOD; + break; + case IGMP_ACTION_TRAP2CPU: + operation = PROTOCOL_OP_TRAP; + break; + case IGMP_ACTION_DROP: + operation = PROTOCOL_OP_DROP; + break; + case IGMP_ACTION_ASIC: + operation = PROTOCOL_OP_ASIC; + break; + default: + return RT_ERR_INPUT; + } + + switch(protocol) + { + case PROTOCOL_IGMPv1: + if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv2: + if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv3: + if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv1: + if ((retVal = rtl8367c_setAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv2: + if ((retVal = rtl8367c_setAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_INPUT; + + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_protocol_get + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction) +{ + rtk_uint32 operation; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(protocol >= PROTOCOL_END) + return RT_ERR_INPUT; + + if(pAction == NULL) + return RT_ERR_NULL_POINTER; + + switch(protocol) + { + case PROTOCOL_IGMPv1: + if ((retVal = rtl8367c_getAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv2: + if ((retVal = rtl8367c_getAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv3: + if ((retVal = rtl8367c_getAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv1: + if ((retVal = rtl8367c_getAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv2: + if ((retVal = rtl8367c_getAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_INPUT; + + } + + switch(operation) + { + case PROTOCOL_OP_FLOOD: + *pAction = IGMP_ACTION_FORWARD; + break; + case PROTOCOL_OP_TRAP: + *pAction = IGMP_ACTION_TRAP2CPU; + break; + case PROTOCOL_OP_DROP: + *pAction = IGMP_ACTION_DROP; + break; + case PROTOCOL_OP_ASIC: + *pAction = IGMP_ACTION_ASIC; + break; + default: + return RT_ERR_FAILED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_fastLeave_set + * Description: + * set IGMP/MLD FastLeave state + * Input: + * state - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set IGMP/MLD FastLeave state + */ +rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn((rtk_uint32)state))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_fastLeave_get + * Description: + * get IGMP/MLD FastLeave state + * Input: + * None + * Output: + * pState - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - NULL pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get IGMP/MLD FastLeave state + */ +rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState) +{ + rtk_uint32 fast_leave; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pState == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPFastLeaveEn(&fast_leave))!=RT_ERR_OK) + return retVal; + + *pState = ((fast_leave == 1) ? ENABLED : DISABLED); + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_maxGroup_set + * Description: + * Set per port multicast group learning limit. + * Input: + * port - Port ID + * group - The number of multicast group learning limit. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_OUT_OF_RANGE - parameter out of range + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set per port multicast group learning limit. + */ +rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(group > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_OUT_OF_RANGE; + + if ((retVal = rtl8367c_setAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), group))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_maxGroup_get + * Description: + * Get per port multicast group learning limit. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning limit. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning limit. + */ +rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(pGroup == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_currentGroup_get + * Description: + * Get per port multicast group learning count. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning count. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning count. + */ +rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(pGroup == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPPortCurrentGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_tableFullAction_set + * Description: + * set IGMP/MLD Table Full Action + * Input: + * action - Table Full Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(action >= IGMP_TABLE_FULL_OP_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPTableFullOP((rtk_uint32)action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_tableFullAction_get + * Description: + * get IGMP/MLD Table Full Action + * Input: + * None + * Output: + * pAction - Table Full Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPTableFullOP((rtk_uint32 *)pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_checksumErrorAction_set + * Description: + * set IGMP/MLD Checksum Error Action + * Input: + * action - Checksum error Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(action >= IGMP_CRC_ERR_OP_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPCRCErrOP((rtk_uint32)action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_igmp_checksumErrorAction_get + * Description: + * get IGMP/MLD Checksum Error Action + * Input: + * None + * Output: + * pAction - Checksum error Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPCRCErrOP((rtk_uint32 *)pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_leaveTimer_set + * Description: + * set IGMP/MLD Leave timer + * Input: + * timer - Leave timer + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(timer > RTL8367C_MAX_LEAVE_TIMER) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPLeaveTimer(timer))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_leaveTimer_get + * Description: + * get IGMP/MLD Leave timer + * Input: + * None + * Output: + * pTimer - Leave Timer. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pTimer) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPLeaveTimer(pTimer))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_queryInterval_set + * Description: + * set IGMP/MLD Query Interval + * Input: + * interval - Query Interval + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(interval > RTL8367C_MAX_QUERY_INT) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPQueryInterval(interval))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_queryInterval_get + * Description: + * get IGMP/MLD Query Interval + * Input: + * None. + * Output: + * pInterval - Query Interval + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pInterval) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPQueryInterval(pInterval))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_robustness_set + * Description: + * set IGMP/MLD Robustness value + * Input: + * robustness - Robustness value + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(robustness > RTL8367C_MAX_ROB_VAR) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPRobVar(robustness))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_robustness_get + * Description: + * get IGMP/MLD Robustness value + * Input: + * None + * Output: + * pRobustness - Robustness value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pRobustness) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPRobVar(pRobustness))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_set + * Description: + * Configure dynamic router port allow option + * Input: + * pPortmask - Dynamic Port allow mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(pmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_get + * Description: + * Get dynamic router port allow option + * Input: + * None. + * Output: + * pPortmask - Dynamic Port allow mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPAllowDynamicRouterPort(&pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dynamicRouterPort_get + * Description: + * Get dynamic router port + * Input: + * None. + * Output: + * pDynamicRouterPort - Dynamic Router Port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtk_uint32 timer; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pDynamicRouterPort) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort1(&port, &timer))!= RT_ERR_OK) + return retVal; + + if (port == RTL8367C_ROUTER_PORT_INVALID) + { + pDynamicRouterPort->dynamicRouterPort0Valid = DISABLED; + pDynamicRouterPort->dynamicRouterPort0 = 0; + pDynamicRouterPort->dynamicRouterPort0Timer = 0; + } + else + { + pDynamicRouterPort->dynamicRouterPort0Valid = ENABLED; + pDynamicRouterPort->dynamicRouterPort0 = rtk_switch_port_P2L_get(port); + pDynamicRouterPort->dynamicRouterPort0Timer = timer; + } + + if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort2(&port, &timer))!= RT_ERR_OK) + return retVal; + + if (port == RTL8367C_ROUTER_PORT_INVALID) + { + pDynamicRouterPort->dynamicRouterPort1Valid = DISABLED; + pDynamicRouterPort->dynamicRouterPort1 = 0; + pDynamicRouterPort->dynamicRouterPort1Timer = 0; + } + else + { + pDynamicRouterPort->dynamicRouterPort1Valid = ENABLED; + pDynamicRouterPort->dynamicRouterPort1 = rtk_switch_port_P2L_get(port); + pDynamicRouterPort->dynamicRouterPort1Timer = timer; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_suppressionEnable_set + * Description: + * Configure IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * reportSuppression - Report suppression + * leaveSuppression - Leave suppression + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(reportSuppression >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(leaveSuppression >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPSuppression((rtk_uint32)reportSuppression, (rtk_uint32)leaveSuppression))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_suppressionEnable_get + * Description: + * Get IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * None + * Output: + * pReportSuppression - Report suppression + * pLeaveSuppression - Leave suppression + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pReportSuppression) + return RT_ERR_NULL_POINTER; + + if(NULL == pLeaveSuppression) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPSuppression((rtk_uint32 *)pReportSuppression, (rtk_uint32 *)pLeaveSuppression))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_portRxPktEnable_set + * Description: + * Configure IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pRxCfg) + return RT_ERR_NULL_POINTER; + + if(pRxCfg->rxQuery >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxReport >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxLeave >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxMRP >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxMcast >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxQuery))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxReport))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxLeave))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMRP))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMcast))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_portRxPktEnable_get + * Description: + * Get IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pRxCfg) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxQuery)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxReport)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxLeave)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMRP)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMcast)))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_groupInfo_get + * Description: + * Get IGMP/MLD Group database + * Input: + * indes - Index (0~255) + * Output: + * pGroup - Group database information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup) +{ + rtk_api_ret_t retVal; + rtk_uint32 valid; + rtl8367c_igmpgroup grp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check index */ + if(index > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_INPUT; + + if(NULL == pGroup) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPGroup(index, &valid, &grp))!=RT_ERR_OK) + return retVal; + + memset(pGroup, 0x00, sizeof(rtk_igmp_groupInfo_t)); + pGroup->valid = valid; + pGroup->reportSuppFlag = grp.report_supp_flag; + + if(grp.p0_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(0)); + pGroup->timer[rtk_switch_port_P2L_get(0)] = grp.p0_timer; + } + + if(grp.p1_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(1)); + pGroup->timer[rtk_switch_port_P2L_get(1)] = grp.p1_timer; + } + + if(grp.p2_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(2)); + pGroup->timer[rtk_switch_port_P2L_get(2)] = grp.p2_timer; + } + + if(grp.p3_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(3)); + pGroup->timer[rtk_switch_port_P2L_get(3)] = grp.p3_timer; + } + + if(grp.p4_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(4)); + pGroup->timer[rtk_switch_port_P2L_get(4)] = grp.p4_timer; + } + + if(grp.p5_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(5)); + pGroup->timer[rtk_switch_port_P2L_get(5)] = grp.p5_timer; + } + + if(grp.p6_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(6)); + pGroup->timer[rtk_switch_port_P2L_get(6)] = grp.p6_timer; + } + + if(grp.p7_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(7)); + pGroup->timer[rtk_switch_port_P2L_get(7)] = grp.p7_timer; + } + + if(grp.p8_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(8)); + pGroup->timer[rtk_switch_port_P2L_get(8)] = grp.p8_timer; + } + + if(grp.p9_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(9)); + pGroup->timer[rtk_switch_port_P2L_get(9)] = grp.p9_timer; + } + + if(grp.p10_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(10)); + pGroup->timer[rtk_switch_port_P2L_get(10)] = grp.p10_timer; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_set + * Description: + * Set Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + switch(action) + { + case IGMP_REPORT_LEAVE_TO_ROUTER: + regData = 1; + break; + case IGMP_REPORT_LEAVE_TO_ALLPORT: + regData = 2; + break; + case IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV: + regData = 3; + break; + default: + return RT_ERR_INPUT; + } + + if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(regData))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_get + * Description: + * Get Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPReportLeaveFlood(®Data))!=RT_ERR_OK) + return retVal; + + switch(regData) + { + case 1: + *pAction = IGMP_REPORT_LEAVE_TO_ROUTER; + break; + case 2: + *pAction = IGMP_REPORT_LEAVE_TO_ALLPORT; + break; + case 3: + *pAction = IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV; + break; + default: + return RT_ERR_FAILED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_set + * Description: + * Set the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * enabled - Action 1: drop, 0:pass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPDropLeaveZero(enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_get + * Description: + * Get the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * None + * Output: + * pEnabled. - Action 1: drop, 0:pass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPDropLeaveZero((rtk_uint32 *)pEnabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_igmp_bypassGroupRange_set + * Description: + * Set Bypass group + * Input: + * group - bypassed group + * enabled - enabled 1: Bypassed, 0: not bypass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(group >= IGMP_BYPASS_GROUP_END) + return RT_ERR_INPUT; + + if(enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPBypassGroup(group, enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_bypassGroupRange_get + * Description: + * get Bypass group + * Input: + * group - bypassed group + * Output: + * pEnable - enabled 1: Bypassed, 0: not bypass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(group >= IGMP_BYPASS_GROUP_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPBypassGroup(group, pEnable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/acl.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/acl.h new file mode 100755 index 00000000..6308da8d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/acl.h @@ -0,0 +1,990 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes ACL module high-layer API defination + * + */ + +#ifndef __RTK_API_ACL_H__ +#define __RTK_API_ACL_H__ + +/* + * Data Type Declaration + */ +#define RTK_FILTER_RAW_FIELD_NUMBER 8 + +#define ACL_DEFAULT_ABILITY 0 +#define ACL_DEFAULT_UNMATCH_PERMIT 1 + +#define ACL_RULE_FREE 0 +#define ACL_RULE_INAVAILABLE 1 +#define ACL_RULE_CARETAG_MASK 0x1F +#define FILTER_POLICING_MAX 4 +#define FILTER_LOGGING_MAX 8 +#define FILTER_PATTERN_MAX 4 + +#define FILTER_ENACT_CVLAN_MASK 0x01 +#define FILTER_ENACT_SVLAN_MASK 0x02 +#define FILTER_ENACT_PRIORITY_MASK 0x04 +#define FILTER_ENACT_POLICING_MASK 0x08 +#define FILTER_ENACT_FWD_MASK 0x10 +#define FILTER_ENACT_INTGPIO_MASK 0x20 +#define FILTER_ENACT_INIT_MASK 0x3F + +typedef enum rtk_filter_act_cactext_e +{ + FILTER_ENACT_CACTEXT_VLANONLY=0, + FILTER_ENACT_CACTEXT_BOTHVLANTAG, + FILTER_ENACT_CACTEXT_TAGONLY, + FILTER_ENACT_CACTEXT_END, + + +}rtk_filter_act_cactext_t; + +typedef enum rtk_filter_act_ctagfmt_e +{ + FILTER_CTAGFMT_UNTAG=0, + FILTER_CTAGFMT_TAG, + FILTER_CTAGFMT_KEEP, + FILTER_CTAGFMT_KEEP1PRMK, + + +}rtk_filter_act_ctag_t; + + + + + +#define RTK_MAX_NUM_OF_FILTER_TYPE 5 +#define RTK_MAX_NUM_OF_FILTER_FIELD 8 + +#define RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH 3UL +#define RTK_IPV6_ADDR_WORD_LENGTH 4UL + +#define FILTER_ENACT_CVLAN_TYPE(type) (type - FILTER_ENACT_CVLAN_INGRESS) +#define FILTER_ENACT_SVLAN_TYPE(type) (type - FILTER_ENACT_SVLAN_INGRESS) +#define FILTER_ENACT_FWD_TYPE(type) (type - FILTER_ENACT_ADD_DSTPORT) +#define FILTER_ENACT_PRI_TYPE(type) (type - FILTER_ENACT_PRIORITY) + +#define RTK_FILTER_FIELD_USED_MAX 8 +#define RTK_FILTER_FIELD_INDEX(template, index) ((template << 4) + index) + + +typedef enum rtk_filter_act_enable_e +{ + /* CVLAN */ + FILTER_ENACT_CVLAN_INGRESS = 0, + FILTER_ENACT_CVLAN_EGRESS, + FILTER_ENACT_CVLAN_SVID, + FILTER_ENACT_POLICING_1, + + /* SVLAN */ + FILTER_ENACT_SVLAN_INGRESS, + FILTER_ENACT_SVLAN_EGRESS, + FILTER_ENACT_SVLAN_CVID, + FILTER_ENACT_POLICING_2, + + /* Policing and Logging */ + FILTER_ENACT_POLICING_0, + + /* Forward */ + FILTER_ENACT_COPY_CPU, + FILTER_ENACT_DROP, + FILTER_ENACT_ADD_DSTPORT, + FILTER_ENACT_REDIRECT, + FILTER_ENACT_MIRROR, + FILTER_ENACT_TRAP_CPU, + FILTER_ENACT_ISOLATION, + + /* QoS */ + FILTER_ENACT_PRIORITY, + FILTER_ENACT_DSCP_REMARK, + FILTER_ENACT_1P_REMARK, + FILTER_ENACT_POLICING_3, + + /* Interrutp and GPO */ + FILTER_ENACT_INTERRUPT, + FILTER_ENACT_GPO, + + /*VLAN tag*/ + FILTER_ENACT_EGRESSCTAG_UNTAG, + FILTER_ENACT_EGRESSCTAG_TAG, + FILTER_ENACT_EGRESSCTAG_KEEP, + FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK, + + FILTER_ENACT_END, +} rtk_filter_act_enable_t; + + +typedef struct +{ + rtk_filter_act_enable_t actEnable[FILTER_ENACT_END]; + + /* CVLAN acton */ + rtk_uint32 filterCvlanVid; + rtk_uint32 filterCvlanIdx; + /* SVLAN action */ + rtk_uint32 filterSvlanVid; + rtk_uint32 filterSvlanIdx; + + /* Policing action */ + rtk_uint32 filterPolicingIdx[FILTER_POLICING_MAX]; + + /* Forwarding action */ + rtk_portmask_t filterPortmask; + + /* QOS action */ + rtk_uint32 filterPriority; + + /*GPO*/ + rtk_uint32 filterPin; + +} rtk_filter_action_t; + +typedef struct rtk_filter_flag_s +{ + rtk_uint32 value; + rtk_uint32 mask; +} rtk_filter_flag_t; + +typedef enum rtk_filter_care_tag_index_e +{ + CARE_TAG_CTAG = 0, + CARE_TAG_STAG, + CARE_TAG_PPPOE, + CARE_TAG_IPV4, + CARE_TAG_IPV6, + CARE_TAG_TCP, + CARE_TAG_UDP, + CARE_TAG_ARP, + CARE_TAG_RSV1, + CARE_TAG_RSV2, + CARE_TAG_ICMP, + CARE_TAG_IGMP, + CARE_TAG_LLC, + CARE_TAG_RSV3, + CARE_TAG_HTTP, + CARE_TAG_RSV4, + CARE_TAG_RSV5, + CARE_TAG_DHCP, + CARE_TAG_DHCPV6, + CARE_TAG_SNMP, + CARE_TAG_OAM, + CARE_TAG_END, +} rtk_filter_care_tag_index_t; + +typedef struct rtk_filter_care_tag_s +{ + rtk_filter_flag_t tagType[CARE_TAG_END]; +} rtk_filter_care_tag_t; + +typedef struct rtk_filter_field rtk_filter_field_t; + +typedef struct +{ + rtk_uint32 value[RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH]; +} rtk_filter_dot1as_timestamp_t; + +typedef enum rtk_filter_field_data_type_e +{ + FILTER_FIELD_DATA_MASK = 0, + FILTER_FIELD_DATA_RANGE, + FILTER_FIELD_DATA_END , +} rtk_filter_field_data_type_t; + +typedef struct rtk_filter_ip_s +{ + rtk_uint32 dataType; + rtk_uint32 rangeStart; + rtk_uint32 rangeEnd; + rtk_uint32 value; + rtk_uint32 mask; +} rtk_filter_ip_t; + +typedef struct rtk_filter_mac_s +{ + rtk_uint32 dataType; + rtk_mac_t value; + rtk_mac_t mask; + rtk_mac_t rangeStart; + rtk_mac_t rangeEnd; +} rtk_filter_mac_t; + +typedef rtk_uint32 rtk_filter_op_t; + +typedef struct rtk_filter_value_s +{ + rtk_uint32 dataType; + rtk_uint32 value; + rtk_uint32 mask; + rtk_uint32 rangeStart; + rtk_uint32 rangeEnd; + +} rtk_filter_value_t; + +typedef struct rtk_filter_activeport_s +{ + rtk_portmask_t value; + rtk_portmask_t mask; + +} rtk_filter_activeport_t; + + + +typedef struct rtk_filter_tag_s +{ + rtk_filter_value_t pri; + rtk_filter_flag_t cfi; + rtk_filter_value_t vid; +} rtk_filter_tag_t; + +typedef struct rtk_filter_ipFlag_s +{ + rtk_filter_flag_t xf; + rtk_filter_flag_t mf; + rtk_filter_flag_t df; +} rtk_filter_ipFlag_t; + +typedef struct +{ + rtk_uint32 addr[RTK_IPV6_ADDR_WORD_LENGTH]; +} rtk_filter_ip6_addr_t; + +typedef struct +{ + rtk_uint32 dataType; + rtk_filter_ip6_addr_t value; + rtk_filter_ip6_addr_t mask; + rtk_filter_ip6_addr_t rangeStart; + rtk_filter_ip6_addr_t rangeEnd; +} rtk_filter_ip6_t; + +typedef rtk_uint32 rtk_filter_number_t; + +typedef struct rtk_filter_pattern_s +{ + rtk_uint32 value[FILTER_PATTERN_MAX]; + rtk_uint32 mask[FILTER_PATTERN_MAX]; +} rtk_filter_pattern_t; + +typedef struct rtk_filter_tcpFlag_s +{ + rtk_filter_flag_t urg; + rtk_filter_flag_t ack; + rtk_filter_flag_t psh; + rtk_filter_flag_t rst; + rtk_filter_flag_t syn; + rtk_filter_flag_t fin; + rtk_filter_flag_t ns; + rtk_filter_flag_t cwr; + rtk_filter_flag_t ece; +} rtk_filter_tcpFlag_t; + +typedef rtk_uint32 rtk_filter_field_raw_t; + +typedef enum rtk_filter_field_temple_input_e +{ + FILTER_FIELD_TEMPLE_INPUT_TYPE = 0, + FILTER_FIELD_TEMPLE_INPUT_INDEX, + FILTER_FIELD_TEMPLE_INPUT_MAX , +} rtk_filter_field_temple_input_t; + +struct rtk_filter_field +{ + rtk_uint32 fieldType; + + union + { + /* L2 struct */ + rtk_filter_mac_t dmac; + rtk_filter_mac_t smac; + rtk_filter_value_t etherType; + rtk_filter_tag_t ctag; + rtk_filter_tag_t relayCtag; + rtk_filter_tag_t stag; + rtk_filter_tag_t l2tag; + rtk_filter_dot1as_timestamp_t dot1asTimeStamp; + rtk_filter_mac_t mac; + + /* L3 struct */ + rtk_filter_ip_t sip; + rtk_filter_ip_t dip; + rtk_filter_ip_t ip; + rtk_filter_value_t protocol; + rtk_filter_value_t ipTos; + rtk_filter_ipFlag_t ipFlag; + rtk_filter_value_t ipOffset; + rtk_filter_ip6_t sipv6; + rtk_filter_ip6_t dipv6; + rtk_filter_ip6_t ipv6; + rtk_filter_value_t ipv6TrafficClass; + rtk_filter_value_t ipv6NextHeader; + rtk_filter_value_t flowLabel; + + /* L4 struct */ + rtk_filter_value_t tcpSrcPort; + rtk_filter_value_t tcpDstPort; + rtk_filter_tcpFlag_t tcpFlag; + rtk_filter_value_t tcpSeqNumber; + rtk_filter_value_t tcpAckNumber; + rtk_filter_value_t udpSrcPort; + rtk_filter_value_t udpDstPort; + rtk_filter_value_t icmpCode; + rtk_filter_value_t icmpType; + rtk_filter_value_t igmpType; + + /* pattern match */ + rtk_filter_pattern_t pattern; + + rtk_filter_value_t inData; + + } filter_pattern_union; + + rtk_uint32 fieldTemplateNo; + rtk_uint32 fieldTemplateIdx[RTK_FILTER_FIELD_USED_MAX]; + + struct rtk_filter_field *next; +}; + +typedef enum rtk_filter_field_type_e +{ + FILTER_FIELD_DMAC = 0, + FILTER_FIELD_SMAC, + FILTER_FIELD_ETHERTYPE, + FILTER_FIELD_CTAG, + FILTER_FIELD_STAG, + + FILTER_FIELD_IPV4_SIP, + FILTER_FIELD_IPV4_DIP, + FILTER_FIELD_IPV4_TOS, + FILTER_FIELD_IPV4_PROTOCOL, + FILTER_FIELD_IPV4_FLAG, + FILTER_FIELD_IPV4_OFFSET, + FILTER_FIELD_IPV6_SIPV6, + FILTER_FIELD_IPV6_DIPV6, + FILTER_FIELD_IPV6_TRAFFIC_CLASS, + FILTER_FIELD_IPV6_NEXT_HEADER, + + FILTER_FIELD_TCP_SPORT, + FILTER_FIELD_TCP_DPORT, + FILTER_FIELD_TCP_FLAG, + FILTER_FIELD_UDP_SPORT, + FILTER_FIELD_UDP_DPORT, + FILTER_FIELD_ICMP_CODE, + FILTER_FIELD_ICMP_TYPE, + FILTER_FIELD_IGMP_TYPE, + + FILTER_FIELD_VID_RANGE, + FILTER_FIELD_IP_RANGE, + FILTER_FIELD_PORT_RANGE, + + FILTER_FIELD_USER_DEFINED00, + FILTER_FIELD_USER_DEFINED01, + FILTER_FIELD_USER_DEFINED02, + FILTER_FIELD_USER_DEFINED03, + FILTER_FIELD_USER_DEFINED04, + FILTER_FIELD_USER_DEFINED05, + FILTER_FIELD_USER_DEFINED06, + FILTER_FIELD_USER_DEFINED07, + FILTER_FIELD_USER_DEFINED08, + FILTER_FIELD_USER_DEFINED09, + FILTER_FIELD_USER_DEFINED10, + FILTER_FIELD_USER_DEFINED11, + FILTER_FIELD_USER_DEFINED12, + FILTER_FIELD_USER_DEFINED13, + FILTER_FIELD_USER_DEFINED14, + FILTER_FIELD_USER_DEFINED15, + + FILTER_FIELD_PATTERN_MATCH, + + FILTER_FIELD_END, +} rtk_filter_field_type_t; + + +typedef enum rtk_filter_field_type_raw_e +{ + FILTER_FIELD_RAW_UNUSED = 0, + FILTER_FIELD_RAW_DMAC_15_0, + FILTER_FIELD_RAW_DMAC_31_16, + FILTER_FIELD_RAW_DMAC_47_32, + FILTER_FIELD_RAW_SMAC_15_0, + FILTER_FIELD_RAW_SMAC_31_16, + FILTER_FIELD_RAW_SMAC_47_32, + FILTER_FIELD_RAW_ETHERTYPE, + FILTER_FIELD_RAW_STAG, + FILTER_FIELD_RAW_CTAG, + + FILTER_FIELD_RAW_IPV4_SIP_15_0 = 0x10, + FILTER_FIELD_RAW_IPV4_SIP_31_16, + FILTER_FIELD_RAW_IPV4_DIP_15_0, + FILTER_FIELD_RAW_IPV4_DIP_31_16, + + + FILTER_FIELD_RAW_IPV6_SIP_15_0 = 0x20, + FILTER_FIELD_RAW_IPV6_SIP_31_16, + FILTER_FIELD_RAW_IPV6_DIP_15_0 = 0x28, + FILTER_FIELD_RAW_IPV6_DIP_31_16, + + FILTER_FIELD_RAW_VIDRANGE = 0x30, + FILTER_FIELD_RAW_IPRANGE, + FILTER_FIELD_RAW_PORTRANGE, + FILTER_FIELD_RAW_FIELD_VALID, + + FILTER_FIELD_RAW_FIELD_SELECT00 = 0x40, + FILTER_FIELD_RAW_FIELD_SELECT01, + FILTER_FIELD_RAW_FIELD_SELECT02, + FILTER_FIELD_RAW_FIELD_SELECT03, + FILTER_FIELD_RAW_FIELD_SELECT04, + FILTER_FIELD_RAW_FIELD_SELECT05, + FILTER_FIELD_RAW_FIELD_SELECT06, + FILTER_FIELD_RAW_FIELD_SELECT07, + FILTER_FIELD_RAW_FIELD_SELECT08, + FILTER_FIELD_RAW_FIELD_SELECT09, + FILTER_FIELD_RAW_FIELD_SELECT10, + FILTER_FIELD_RAW_FIELD_SELECT11, + FILTER_FIELD_RAW_FIELD_SELECT12, + FILTER_FIELD_RAW_FIELD_SELECT13, + FILTER_FIELD_RAW_FIELD_SELECT14, + FILTER_FIELD_RAW_FIELD_SELECT15, + + FILTER_FIELD_RAW_END, +} rtk_filter_field_type_raw_t; + +typedef enum rtk_filter_flag_care_type_e +{ + FILTER_FLAG_CARE_DONT_CARE = 0, + FILTER_FLAG_CARE_1, + FILTER_FLAG_CARE_0, + FILTER_FLAG_END +} rtk_filter_flag_care_type_t; + +typedef rtk_uint32 rtk_filter_id_t; /* filter id type */ + +typedef enum rtk_filter_invert_e +{ + FILTER_INVERT_DISABLE = 0, + FILTER_INVERT_ENABLE, + FILTER_INVERT_END, +} rtk_filter_invert_t; + +typedef rtk_uint32 rtk_filter_state_t; + +typedef rtk_uint32 rtk_filter_unmatch_action_t; + +typedef enum rtk_filter_unmatch_action_e +{ + FILTER_UNMATCH_DROP = 0, + FILTER_UNMATCH_PERMIT, + FILTER_UNMATCH_END, +} rtk_filter_unmatch_action_type_t; + +typedef struct +{ + rtk_filter_field_t *fieldHead; + rtk_filter_care_tag_t careTag; + rtk_filter_activeport_t activeport; + + rtk_filter_invert_t invert; +} rtk_filter_cfg_t; + +typedef struct +{ + rtk_filter_field_raw_t dataFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER]; + rtk_filter_field_raw_t careFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER]; + rtk_filter_field_type_raw_t fieldRawType[RTK_FILTER_RAW_FIELD_NUMBER]; + rtk_filter_care_tag_t careTag; + rtk_filter_activeport_t activeport; + + rtk_filter_invert_t invert; + rtk_enable_t valid; +} rtk_filter_cfg_raw_t; + +typedef struct +{ + rtk_uint32 index; + rtk_filter_field_type_raw_t fieldType[RTK_FILTER_RAW_FIELD_NUMBER]; +} rtk_filter_template_t; + +typedef enum rtk_field_sel_e +{ + FORMAT_DEFAULT = 0, + FORMAT_RAW, + FORMAT_LLC, + FORMAT_IPV4, + FORMAT_ARP, + FORMAT_IPV6, + FORMAT_IPPAYLOAD, + FORMAT_L4PAYLOAD, + FORMAT_END +}rtk_field_sel_t; + +typedef enum rtk_filter_iprange_e +{ + IPRANGE_UNUSED = 0, + IPRANGE_IPV4_SIP, + IPRANGE_IPV4_DIP, + IPRANGE_IPV6_SIP, + IPRANGE_IPV6_DIP, + IPRANGE_END +}rtk_filter_iprange_t; + +typedef enum rtk_filter_vidrange_e +{ + VIDRANGE_UNUSED = 0, + VIDRANGE_CVID, + VIDRANGE_SVID, + VIDRANGE_END +}rtk_filter_vidrange_t; + +typedef enum rtk_filter_portrange_e +{ + PORTRANGE_UNUSED = 0, + PORTRANGE_SPORT, + PORTRANGE_DPORT, + PORTRANGE_END +}rtk_filter_portrange_t; + +/* Function Name: + * rtk_filter_igrAcl_init + * Description: + * ACL initialization function + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * Note: + * This function enable and intialize ACL function + */ +extern rtk_api_ret_t rtk_filter_igrAcl_init(void); + +/* Function Name: + * rtk_filter_igrAcl_field_add + * Description: + * Add comparison rule to an ACL configuration + * Input: + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_field - The comparison rule that will be added. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg). + * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL + * comparison rules by means of linked list. Pointer pFilter_field will be added to linked + * list keeped by structure that pFilter_cfg points to. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t *pFilter_cfg, rtk_filter_field_t *pFilter_field); + +/* Function Name: + * rtk_filter_igrAcl_cfg_add + * Description: + * Add an ACL configuration to ASIC + * Input: + * filter_id - Start index of ACL configuration. + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_action - Action(s) of ACL configuration. + * Output: + * ruleNum - number of rules written in acl table + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENTRY_INDEX - Invalid filter_id . + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip. + * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported. + * Note: + * This function store pFilter_cfg, pFilter_action into ASIC. The starting + * index(es) is filter_id. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t *pFilter_cfg, rtk_filter_action_t *pAction, rtk_filter_number_t *ruleNum); + +/* Function Name: + * rtk_filter_igrAcl_cfg_del + * Description: + * Delete an ACL configuration from ASIC + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id. + * Note: + * This function delete a group of ACL rules starting from filter_id. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id); + +/* Function Name: + * rtk_filter_igrAcl_cfg_delAll + * Description: + * Delete all ACL entries from ASIC + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function delete all ACL configuration from ASIC. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void); + +/* Function Name: + * rtk_filter_igrAcl_cfg_get + * Description: + * Get one ingress acl configuration from ASIC. + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * pFilter_cfg - buffer pointer of ingress acl data + * pFilter_action - buffer pointer of ingress acl action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_ENTRYIDX - Invalid entry index. + * Note: + * This function delete all ACL configuration from ASIC. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction); + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_set + * Description: + * Set action to packets when no ACL configuration match + * Input: + * port - Port id. + * action - Action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function sets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action); + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_get + * Description: + * Get action to packets when no ACL configuration match + * Input: + * port - Port id. + * Output: + * pAction - Action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* action); + +/* Function Name: + * rtk_filter_igrAcl_state_set + * Description: + * Set state of ingress ACL. + * Input: + * port - Port id. + * state - Ingress ACL state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state); + +/* Function Name: + * rtk_filter_igrAcl_state_get + * Description: + * Get state of ingress ACL. + * Input: + * port - Port id. + * Output: + * pState - Ingress ACL state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* state); + +/* Function Name: + * rtk_filter_igrAcl_template_set + * Description: + * Set template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function set ACL template. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate); + +/* Function Name: + * rtk_filter_igrAcl_template_get + * Description: + * Get template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function gets template of ACL. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate); + +/* Function Name: + * rtk_filter_igrAcl_field_sel_set + * Description: + * Set user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * format - Format of field selector + * offset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * System support 16 user defined field selctors. + * Each selector can be enabled or disable. + * User can defined retrieving 16-bits in many predefiend + * standard l2/l3/l4 payload. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset); + +/* Function Name: + * rtk_filter_igrAcl_field_sel_get + * Description: + * Get user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * Output: + * pFormat - Format of field selector + * pOffset - Retrieving data offset + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset); + +/* Function Name: + * rtk_filter_iprange_set + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * upperIp - The upper bound of IP range + * lowerIp - The lower Bound of IP range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperIp must be larger or equal than lowerIp. + */ +extern rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp); + +/* Function Name: + * rtk_filter_iprange_get + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * pUpperIp - The upper bound of IP range + * pLowerIp - The lower Bound of IP range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * upperIp must be larger or equal than lowerIp. + */ +extern rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp); + +/* Function Name: + * rtk_filter_vidrange_set + * Description: + * Set VID Range check + * Input: + * index - index of VID Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID + * upperVid - The upper bound of VID range + * lowerVid - The lower Bound of VID range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperVid must be larger or equal than lowerVid. + */ +extern rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid); + +/* Function Name: + * rtk_filter_vidrange_get + * Description: + * Get VID Range check + * Input: + * index - index of VID Range 0-15 + * Output: + * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID + * pUpperVid - The upper bound of VID range + * pLowerVid - The lower Bound of VID range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * None. + */ +extern rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid); + +/* Function Name: + * rtk_filter_portrange_set + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * upperPort - The upper bound of Port range + * lowerPort - The lower Bound of Port range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperPort must be larger or equal than lowerPort. + */ +extern rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort); + +/* Function Name: + * rtk_filter_portrange_get + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * pUpperPort - The upper bound of Port range + * pLowerPort - The lower Bound of Port range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * None. + */ +extern rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort); + +/* Function Name: + * rtk_filter_igrAclPolarity_set + * Description: + * Set ACL Goip control palarity + * Input: + * polarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +extern rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity); + +/* Function Name: + * rtk_filter_igrAclPolarity_get + * Description: + * Get ACL Goip control palarity + * Input: + * pPolarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +extern rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity); + + +#endif /* __RTK_API_ACL_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/cpu.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/cpu.h new file mode 100755 index 00000000..5544aca7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/cpu.h @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes CPU module high-layer API defination + * + */ + +#ifndef __RTK_API_CPU_H__ +#define __RTK_API_CPU_H__ + + +/* + * Data Type Declaration + */ +typedef enum rtk_cpu_insert_e +{ + CPU_INSERT_TO_ALL = 0, + CPU_INSERT_TO_TRAPPING, + CPU_INSERT_TO_NONE, + CPU_INSERT_END +}rtk_cpu_insert_t; + +typedef enum rtk_cpu_position_e +{ + CPU_POS_AFTER_SA = 0, + CPU_POS_BEFORE_CRC, + CPU_POS_END +}rtk_cpu_position_t; + +typedef enum rtk_cpu_tag_length_e +{ + CPU_LEN_8BYTES = 0, + CPU_LEN_4BYTES, + CPU_LEN_END +}rtk_cpu_tag_length_t; + + +typedef enum rtk_cpu_rx_length_e +{ + CPU_RX_72BYTES = 0, + CPU_RX_64BYTES, + CPU_RX_END +}rtk_cpu_rx_length_t; + + +/* Function Name: + * rtk_cpu_enable_set + * Description: + * Set CPU port function enable/disable. + * Input: + * enable - CPU port function enable + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port function enable/disable. + */ +extern rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_cpu_enable_get + * Description: + * Get CPU port and its setting. + * Input: + * None + * Output: + * pEnable - CPU port function enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist + * Note: + * The API can get CPU port function enable/disable. + */ +extern rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_cpu_tagPort_set + * Description: + * Set CPU port and CPU tag insert mode. + * Input: + * port - Port id. + * mode - CPU tag insert for packets egress from CPU port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899) + * to the frame that transmitting to CPU port. + * The inset cpu tag mode is as following: + * - CPU_INSERT_TO_ALL + * - CPU_INSERT_TO_TRAPPING + * - CPU_INSERT_TO_NONE + */ +extern rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode); + +/* Function Name: + * rtk_cpu_tagPort_get + * Description: + * Get CPU port and CPU tag insert mode. + * Input: + * None + * Output: + * pPort - Port id. + * pMode - CPU tag insert for packets egress from CPU port, 0:all insert 1:Only for trapped packets 2:no insert. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist + * Note: + * The API can get configured CPU port and its setting. + * The inset cpu tag mode is as following: + * - CPU_INSERT_TO_ALL + * - CPU_INSERT_TO_TRAPPING + * - CPU_INSERT_TO_NONE + */ +extern rtk_api_ret_t rtk_cpu_tagPort_get(rtk_port_t *pPort, rtk_cpu_insert_t *pMode); + +/* Function Name: + * rtk_cpu_awarePort_set + * Description: + * Set CPU aware port mask. + * Input: + * portmask - Port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can set configured CPU aware port mask. + */ +extern rtk_api_ret_t rtk_cpu_awarePort_set(rtk_portmask_t *pPortmask); + + +/* Function Name: + * rtk_cpu_awarePort_get + * Description: + * Get CPU aware port mask. + * Input: + * None + * Output: + * pPortmask - Port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get configured CPU aware port mask. + */ +extern rtk_api_ret_t rtk_cpu_awarePort_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_cpu_tagPosition_set + * Description: + * Set CPU tag position. + * Input: + * position - CPU tag position. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU tag position. + */ +extern rtk_api_ret_t rtk_cpu_tagPosition_set(rtk_cpu_position_t position); + +/* Function Name: + * rtk_cpu_tagPosition_get + * Description: + * Get CPU tag position. + * Input: + * None + * Output: + * pPosition - CPU tag position. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag position. + */ +extern rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition); + +/* Function Name: + * rtk_cpu_tagLength_set + * Description: + * Set CPU tag length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU tag length. + */ +extern rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length); + +/* Function Name: + * rtk_cpu_tagLength_get + * Description: + * Get CPU tag length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag length. + */ +extern rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength); + +/* Function Name: + * rtk_cpu_acceptLength_set + * Description: + * Set CPU accept length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU accept length. + */ +extern rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length); + +/* Function Name: + * rtk_cpu_acceptLength_get + * Description: + * Get CPU accept length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU accept length. + */ +extern rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength); + +/* Function Name: + * rtk_cpu_priRemap_set + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * new_pri - new internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri); + +/* Function Name: + * rtk_cpu_priRemap_get + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * Output: + * pNew_pri - new internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri); + + +#endif /* __RTK_API_CPU_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/dot1x.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/dot1x.h new file mode 100755 index 00000000..ef0a05a0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/dot1x.h @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes 1X module high-layer API defination + * + */ + +#ifndef __RTK_API_DOT1X_H__ +#define __RTK_API_DOT1X_H__ + + +/* Type of port-based dot1x auth/unauth*/ +typedef enum rtk_dot1x_auth_status_e +{ + UNAUTH = 0, + AUTH, + AUTH_STATUS_END +} rtk_dot1x_auth_status_t; + +typedef enum rtk_dot1x_direction_e +{ + DIR_BOTH = 0, + DIR_IN, + DIRECTION_END +} rtk_dot1x_direction_t; + +/* unauth pkt action */ +typedef enum rtk_dot1x_unauth_action_e +{ + DOT1X_ACTION_DROP = 0, + DOT1X_ACTION_TRAP2CPU, + DOT1X_ACTION_GUESTVLAN, + DOT1X_ACTION_END +} rtk_dot1x_unauth_action_t; + +/* Function Name: + * rtk_dot1x_unauthPacketOper_set + * Description: + * Set 802.1x unauth action configuration. + * Input: + * port - Port id. + * unauth_action - 802.1X unauth action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action); + +/* Function Name: + * rtk_dot1x_unauthPacketOper_get + * Description: + * Get 802.1x unauth action configuration. + * Input: + * port - Port id. + * Output: + * pUnauth_action - 802.1X unauth action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action); + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_set + * Description: + * Set 802.1x EAPOL packet trap to CPU configuration + * Input: + * enable - The status of 802.1x EAPOL packet. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_get + * Description: + * Get 802.1x EAPOL packet trap to CPU configuration + * Input: + * None + * Output: + * pEnable - The status of 802.1x EAPOL packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_dot1x_portBasedEnable_set + * Description: + * Set 802.1x port-based enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error + * Note: + * The API can update the port-based port enable register content. If a port is 802.1x + * port based network access control "enabled", it should be authenticated so packets + * from that port won't be dropped or trapped to CPU. + * The status of 802.1x port-based network access control is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_portBasedEnable_get + * Description: + * Get 802.1x port-based enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the 802.1x port-based port status. + */ +extern rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_set + * Description: + * Set 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * port_auth - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error + * Note: + * The authenticated status of 802.1x port-based network access control is as following: + * - UNAUTH + * - AUTH + */ +extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth); + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_get + * Description: + * Get 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * Output: + * pPort_auth - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based port auth.information. + */ +extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth); + +/* Function Name: + * rtk_dot1x_portBasedDirection_set + * Description: + * Set 802.1x port-based operational direction configuration + * Input: + * port - Port id. + * port_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error + * Note: + * The operate controlled direction of 802.1x port-based network access control is as following: + * - BOTH + * - IN + */ +extern rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction); + +/* Function Name: + * rtk_dot1x_portBasedDirection_get + * Description: + * Get 802.1X port-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pPort_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based operational direction information. + */ +extern rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction); + +/* Function Name: + * rtk_dot1x_macBasedEnable_set + * Description: + * Set 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port won't be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_macBasedEnable_get + * Description: + * Get 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port wont be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_add + * Description: + * Add an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT, + * user can't add this MAC to auth status. + */ +extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid); + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_del + * Description: + * Delete an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of + * the MAC and won't delete it from LUT. + */ +extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid); + +/* Function Name: + * rtk_dot1x_macBasedDirection_set + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * mac_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error + * Note: + * The operate controlled direction of 802.1x mac-based network access control is as following: + * - BOTH + * - IN + */ +extern rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction); + +/* Function Name: + * rtk_dot1x_macBasedDirection_get + * Description: + * Get 802.1x mac-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pMac_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x mac-based operational direction information. + */ +extern rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction); + +/* Function Name: + * Set 802.1x guest VLAN configuration + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * vid - 802.1x guest VLAN ID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operate controlled 802.1x guest VLAN + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid); + +/* Function Name: + * rtk_dot1x_guestVlan_get + * Description: + * Get 802.1x guest VLAN configuration + * Input: + * None + * Output: + * pVid - 802.1x guest VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN information. + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid); + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_set + * Description: + * Set 802.1x guest VLAN to auth host configuration + * Input: + * enable - The status of guest VLAN to auth host. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operational direction of 802.1x guest VLAN to auth host control is as following: + * - ENABLED + * - DISABLED + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_get + * Description: + * Get 802.1x guest VLAN to auth host configuration + * Input: + * None + * Output: + * pEnable - The status of guest VLAN to auth host. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN to auth host information. + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable); + + +#endif /* __RTK_API_DOT1X_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/eee.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/eee.h new file mode 100755 index 00000000..b670998c --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/eee.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes EEE module high-layer API defination + * + */ + +#ifndef __RTK_API_EEE_H__ +#define __RTK_API_EEE_H__ + +/* Function Name: + * rtk_eee_init + * Description: + * EEE function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize EEE status. + */ +extern rtk_api_ret_t rtk_eee_init(void); + +/* Function Name: + * rtk_eee_portEnable_set + * Description: + * Set enable status of EEE function. + * Input: + * port - port id. + * enable - enable EEE status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_eee_portEnable_get + * Description: + * Get port admin configuration of the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can set EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + + +#endif /* __RTK_API_EEE_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/i2c.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/i2c.h new file mode 100755 index 00000000..2c7f0756 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/i2c.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes I2C module high-layer API defination + * + */ + + +#ifndef __RTK_API_I2C_H__ +#define __RTK_API_I2C_H__ +#include + +#define I2C_GPIO_MAX_GROUP (3) + +typedef enum rtk_I2C_16bit_mode_e{ + I2C_LSB_16BIT_MODE = 0, + I2C_70B_LSB_16BIT_MODE, + I2C_Mode_END +}rtk_I2C_16bit_mode_t; + + +typedef enum rtk_I2C_gpio_pin_e{ + I2C_GPIO_PIN_8_9 = 0, + I2C_GPIO_PIN_15_16 , + I2C_GPIO_PIN_35_36 , + I2C_GPIO_PIN_END +}rtk_I2C_gpio_pin_t; + + +/* Function Name: + * rtk_i2c_data_read + * Description: + * read i2c slave device register. + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * Output: + * pRegData - read data + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can access i2c slave and read i2c slave device register. + */ +extern rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData); + +/* Function Name: + * rtk_i2c_data_write + * Description: + * write data to i2c slave device register + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * regData - data to set + * Output: + * None + * Return: + * RT_ERR_OK - OK + * Note: + * The API can access i2c slave and setting i2c slave device register. + */ +extern rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData); + + +/* Function Name: + * rtk_i2c_init + * Description: + * I2C smart function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * This API is used to initialize EEE status. + * need used GPIO pins + * OpenDrain and clock + */ +extern rtk_api_ret_t rtk_i2c_init(void); + +/* Function Name: + * rtk_i2c_mode_set + * Description: + * Set I2C data byte-order. + * Input: + * i2cmode - byte-order mode + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set I2c traffic's byte-order . + */ +extern rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode); + +/* Function Name: + * rtk_i2c_mode_get + * Description: + * Get i2c traffic byte-order setting. + * Input: + * None + * Output: + * pI2cMode - i2c byte-order + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c traffic byte-order setting. + */ +extern rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode); + + +/* Function Name: + * rtk_i2c_gpioPinGroup_set + * Description: + * Set i2c SDA & SCL used GPIO pins group. + * Input: + * pins_group - GPIO pins group + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The API can set i2c used gpio pins group. + * There are three group pins could be used + */ +extern rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group); + +/* Function Name: + * rtk_i2c_gpioPinGroup_get + * Description: + * Get i2c SDA & SCL used GPIO pins group. + * Input: + * None + * Output: + * pPins_group - GPIO pins group + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c used gpio pins group. + * There are three group pins could be used + */ +extern rtk_api_ret_t rtk_i2c_gpioPinGroup_get(rtk_I2C_gpio_pin_t * pPins_group); + + + + + + + +#endif + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/igmp.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/igmp.h new file mode 100755 index 00000000..f088b0cc --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/igmp.h @@ -0,0 +1,769 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes IGMP module high-layer API defination + * + */ + +#ifndef __RTK_API_IGMP_H__ +#define __RTK_API_IGMP_H__ + +/* + * Data Type Declaration + */ +typedef enum rtk_igmp_type_e +{ + IGMP_IPV4 = 0, + IGMP_PPPOE_IPV4, + IGMP_MLD, + IGMP_PPPOE_MLD, + IGMP_TYPE_END +} rtk_igmp_type_t; + +typedef enum rtk_trap_igmp_action_e +{ + IGMP_ACTION_FORWARD = 0, + IGMP_ACTION_TRAP2CPU, + IGMP_ACTION_DROP, + IGMP_ACTION_ASIC, + IGMP_ACTION_END +} rtk_igmp_action_t; + +typedef enum rtk_igmp_protocol_e +{ + PROTOCOL_IGMPv1 = 0, + PROTOCOL_IGMPv2, + PROTOCOL_IGMPv3, + PROTOCOL_MLDv1, + PROTOCOL_MLDv2, + PROTOCOL_END +} rtk_igmp_protocol_t; + +typedef enum rtk_igmp_tableFullAction_e +{ + IGMP_TABLE_FULL_FORWARD = 0, + IGMP_TABLE_FULL_DROP, + IGMP_TABLE_FULL_TRAP, + IGMP_TABLE_FULL_OP_END +}rtk_igmp_tableFullAction_t; + +typedef enum rtk_igmp_checksumErrorAction_e +{ + IGMP_CRC_ERR_DROP = 0, + IGMP_CRC_ERR_TRAP, + IGMP_CRC_ERR_FORWARD, + IGMP_CRC_ERR_OP_END +}rtk_igmp_checksumErrorAction_t; + +typedef enum rtk_igmp_bypassGroup_e +{ + IGMP_BYPASS_224_0_0_X = 0, + IGMP_BYPASS_224_0_1_X, + IGMP_BYPASS_239_255_255_X, + IGMP_BYPASS_IPV6_00XX, + IGMP_BYPASS_GROUP_END +}rtk_igmp_bypassGroup_t; + + +typedef struct rtk_igmp_dynamicRouterPort_s +{ + rtk_enable_t dynamicRouterPort0Valid; + rtk_port_t dynamicRouterPort0; + rtk_uint32 dynamicRouterPort0Timer; + rtk_enable_t dynamicRouterPort1Valid; + rtk_port_t dynamicRouterPort1; + rtk_uint32 dynamicRouterPort1Timer; + +}rtk_igmp_dynamicRouterPort_t; + +typedef struct rtk_igmp_rxPktEnable_s +{ + rtk_enable_t rxQuery; + rtk_enable_t rxReport; + rtk_enable_t rxLeave; + rtk_enable_t rxMRP; + rtk_enable_t rxMcast; +}rtk_igmp_rxPktEnable_t; + +typedef struct rtk_igmp_groupInfo_s +{ + rtk_enable_t valid; + rtk_portmask_t member; + rtk_uint32 timer[RTK_PORT_MAX]; + rtk_uint32 reportSuppFlag; +}rtk_igmp_groupInfo_t; + +typedef enum rtk_igmp_ReportLeaveFwdAct_e +{ + IGMP_REPORT_LEAVE_TO_ROUTER = 0, + IGMP_REPORT_LEAVE_TO_ALLPORT, + IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV, + IGMP_REPORT_LEAVE_ACT_END +}rtk_igmp_ReportLeaveFwdAct_t; + +/* Function Name: + * rtk_igmp_init + * Description: + * This API enables H/W IGMP and set a default initial configuration. + * Input: + * None. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API enables H/W IGMP and set a default initial configuration. + */ +extern rtk_api_ret_t rtk_igmp_init(void); + +/* Function Name: + * rtk_igmp_state_set + * Description: + * This API set H/W IGMP state. + * Input: + * enabled - H/W IGMP state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set H/W IGMP state. + */ +extern rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_igmp_state_get + * Description: + * This API get H/W IGMP state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current H/W IGMP state. + */ +extern rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_igmp_static_router_port_set + * Description: + * Configure static router port + * Input: + * pPortmask - Static Port mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set static router port + */ +extern rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_static_router_port_get + * Description: + * Get static router port + * Input: + * None. + * Output: + * pPortmask - Static port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API get static router port + */ +extern rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_protocol_set + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +extern rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action); + +/* Function Name: + * rtk_igmp_protocol_get + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +extern rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction); + +/* Function Name: + * rtk_igmp_fastLeave_set + * Description: + * set IGMP/MLD FastLeave state + * Input: + * state - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set IGMP/MLD FastLeave state + */ +extern rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state); + +/* Function Name: + * rtk_igmp_fastLeave_get + * Description: + * get IGMP/MLD FastLeave state + * Input: + * None + * Output: + * pState - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - NULL pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get IGMP/MLD FastLeave state + */ +extern rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState); + +/* Function Name: + * rtk_igmp_maxGroup_set + * Description: + * Set per port multicast group learning limit. + * Input: + * port - Port ID + * group - The number of multicast group learning limit. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_OUT_OF_RANGE - parameter out of range + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set per port multicast group learning limit. + */ +extern rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group); + +/* Function Name: + * rtk_igmp_maxGroup_get + * Description: + * Get per port multicast group learning limit. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning limit. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning limit. + */ +extern rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup); + +/* Function Name: + * rtk_igmp_currentGroup_get + * Description: + * Get per port multicast group learning count. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning count. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning count. + */ +extern rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup); + +/* Function Name: + * rtk_igmp_tableFullAction_set + * Description: + * set IGMP/MLD Table Full Action + * Input: + * action - Table Full Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action); + +/* Function Name: + * rtk_igmp_tableFullAction_get + * Description: + * get IGMP/MLD Table Full Action + * Input: + * None + * Output: + * pAction - Table Full Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction); + +/* Function Name: + * rtk_igmp_checksumErrorAction_set + * Description: + * set IGMP/MLD Checksum Error Action + * Input: + * action - Checksum error Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action); + +/* Function Name: + * rtk_igmp_checksumErrorAction_get + * Description: + * get IGMP/MLD Checksum Error Action + * Input: + * None + * Output: + * pAction - Checksum error Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction); + +/* Function Name: + * rtk_igmp_leaveTimer_set + * Description: + * set IGMP/MLD Leave timer + * Input: + * timer - Leave timer + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer); + +/* Function Name: + * rtk_igmp_leaveTimer_get + * Description: + * get IGMP/MLD Leave timer + * Input: + * None + * Output: + * pTimer - Leave Timer. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer); + +/* Function Name: + * rtk_igmp_queryInterval_set + * Description: + * set IGMP/MLD Query Interval + * Input: + * interval - Query Interval + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval); + +/* Function Name: + * rtk_igmp_queryInterval_get + * Description: + * get IGMP/MLD Query Interval + * Input: + * None. + * Output: + * pInterval - Query Interval + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval); + +/* Function Name: + * rtk_igmp_robustness_set + * Description: + * set IGMP/MLD Robustness value + * Input: + * robustness - Robustness value + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness); + +/* Function Name: + * rtk_igmp_robustness_get + * Description: + * get IGMP/MLD Robustness value + * Input: + * None + * Output: + * pRobustness - Robustness value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness); + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_set + * Description: + * Configure dynamic router port allow option + * Input: + * pPortmask - Dynamic Port allow mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_get + * Description: + * Get dynamic router port allow option + * Input: + * None. + * Output: + * pPortmask - Dynamic Port allow mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_dynamicRouterPort_get + * Description: + * Get dynamic router port + * Input: + * None. + * Output: + * pDynamicRouterPort - Dynamic Router Port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort); + +/* Function Name: + * rtk_igmp_suppressionEnable_set + * Description: + * Configure IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * reportSuppression - Report suppression + * leaveSuppression - Leave suppression + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression); + +/* Function Name: + * rtk_igmp_suppressionEnable_get + * Description: + * Get IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * None + * Output: + * pReportSuppression - Report suppression + * pLeaveSuppression - Leave suppression + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression); + +/* Function Name: + * rtk_igmp_portRxPktEnable_set + * Description: + * Configure IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg); + +/* Function Name: + * rtk_igmp_portRxPktEnable_get + * Description: + * Get IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg); + +/* Function Name: + * rtk_igmp_groupInfo_get + * Description: + * Get IGMP/MLD Group database + * Input: + * indes - Index (0~255) + * Output: + * pGroup - Group database information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup); + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_set + * Description: + * Set Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action); + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_get + * Description: + * Get Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction); + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_set + * Description: + * Set the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * enabled - Action 1: drop, 0:pass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_get + * Description: + * Get the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * None + * Output: + * pEnabled. - Action 1: drop, 0:pass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_igmp_bypassGroupRange_set + * Description: + * Set Bypass group + * Input: + * group - bypassed group + * enabled - enabled 1: Bypassed, 0: not bypass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled); + +/* Function Name: + * rtk_igmp_bypassGroupRange_get + * Description: + * get Bypass group + * Input: + * group - bypassed group + * Output: + * pEnable - enabled 1: Bypassed, 0: not bypass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable); + +#endif /* __RTK_API_IGMP_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/interrupt.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/interrupt.h new file mode 100755 index 00000000..f2689ebc --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/interrupt.h @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Interrupt module high-layer API defination + * + */ + +#ifndef __RTK_API_INTERRUPT_H__ +#define __RTK_API_INTERRUPT_H__ + + +/* + * Data Type Declaration + */ +#define RTK_MAX_NUM_OF_INTERRUPT_TYPE 1 + + +typedef struct rtk_int_status_s +{ + rtk_uint16 value[RTK_MAX_NUM_OF_INTERRUPT_TYPE]; +} rtk_int_status_t; + +typedef struct rtk_int_info_s +{ + rtk_portmask_t portMask; + rtk_uint32 meterMask; + rtk_uint32 systemLearnOver; +}rtk_int_info_t; + +typedef enum rtk_int_type_e +{ + INT_TYPE_LINK_STATUS = 0, + INT_TYPE_METER_EXCEED, + INT_TYPE_LEARN_LIMIT, + INT_TYPE_LINK_SPEED, + INT_TYPE_CONGEST, + INT_TYPE_GREEN_FEATURE, + INT_TYPE_LOOP_DETECT, + INT_TYPE_8051, + INT_TYPE_CABLE_DIAG, + INT_TYPE_ACL, + INT_TYPE_RESERVED, /* Unused */ + INT_TYPE_SLIENT, + INT_TYPE_END +}rtk_int_type_t; + +typedef enum rtk_int_advType_e +{ + ADV_L2_LEARN_PORT_MASK = 0, + ADV_SPEED_CHANGE_PORT_MASK, + ADV_SPECIAL_CONGESTION_PORT_MASK, + ADV_PORT_LINKDOWN_PORT_MASK, + ADV_PORT_LINKUP_PORT_MASK, + ADV_METER_EXCEED_MASK, + ADV_RLDP_LOOPED, + ADV_RLDP_RELEASED, + ADV_END, +} rtk_int_advType_t; + +typedef enum rtk_int_polarity_e +{ + INT_POLAR_HIGH = 0, + INT_POLAR_LOW, + INT_POLAR_END +} rtk_int_polarity_t; + +/* Function Name: + * rtk_int_polarity_set + * Description: + * Set interrupt polarity configuration. + * Input: + * type - Interruptpolarity type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set interrupt polarity configuration. + */ +extern rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type); + +/* Function Name: + * rtk_int_polarity_get + * Description: + * Get interrupt polarity configuration. + * Input: + * None + * Output: + * pType - Interruptpolarity type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get interrupt polarity configuration. + */ +extern rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType); + +/* Function Name: + * rtk_int_control_set + * Description: + * Set interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set interrupt status configuration. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS + * - INT_TYPE_METER_EXCEED + * - INT_TYPE_LEARN_LIMIT + * - INT_TYPE_LINK_SPEED + * - INT_TYPE_CONGEST + * - INT_TYPE_GREEN_FEATURE + * - INT_TYPE_LOOP_DETECT + * - INT_TYPE_8051, + * - INT_TYPE_CABLE_DIAG, + * - INT_TYPE_ACL, + * - INT_TYPE_SLIENT + */ +extern rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_int_control_get + * Description: + * Get interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * Output: + * pEnable - Interrupt status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt status configuration. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS + * - INT_TYPE_METER_EXCEED + * - INT_TYPE_LEARN_LIMIT + * - INT_TYPE_LINK_SPEED + * - INT_TYPE_CONGEST + * - INT_TYPE_GREEN_FEATURE + * - INT_TYPE_LOOP_DETECT + * - INT_TYPE_8051, + * - INT_TYPE_CABLE_DIAG, + * - INT_TYPE_ACL, + * - INT_TYPE_SLIENT + */ +extern rtk_api_ret_t rtk_int_control_get(rtk_int_type_t type, rtk_enable_t* pEnable); + +/* Function Name: + * rtk_int_status_set + * Description: + * Set interrupt trigger status to clean. + * Input: + * None + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can clean interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) + * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) + * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) + * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) + * - INT_TYPE_CONGEST (value[0] (Bit4)) + * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) + * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) + * - INT_TYPE_8051 (value[0] (Bit7)) + * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) + * - INT_TYPE_ACL (value[0] (Bit9)) + * - INT_TYPE_SLIENT (value[0] (Bit11)) + * The status will be cleared after execute this API. + */ +extern rtk_api_ret_t rtk_int_status_set(rtk_int_status_t *pStatusMask); + +/* Function Name: + * rtk_int_status_get + * Description: + * Get interrupt trigger status. + * Input: + * None + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) + * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) + * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) + * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) + * - INT_TYPE_CONGEST (value[0] (Bit4)) + * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) + * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) + * - INT_TYPE_8051 (value[0] (Bit7)) + * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) + * - INT_TYPE_ACL (value[0] (Bit9)) + * - INT_TYPE_SLIENT (value[0] (Bit11)) + * + */ +extern rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask); + +/* Function Name: + * rtk_int_advanceInfo_get + * Description: + * Get interrupt advanced information. + * Input: + * adv_type - Advanced interrupt type. + * Output: + * info - Information per type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get advanced information when interrupt happened. + * The status will be cleared after execute this API. + */ +extern rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t* info); + + +#endif /* __RTK_API_INTERRUPT_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/l2.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/l2.h new file mode 100755 index 00000000..e0ccdbe3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/l2.h @@ -0,0 +1,1181 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes L2 module high-layer API defination + * + */ + +#ifndef __RTK_API_L2_H__ +#define __RTK_API_L2_H__ + + +/* + * Data Type Declaration + */ +#define RTK_MAX_NUM_OF_LEARN_LIMIT (rtk_switch_maxLutAddrNumber_get()) + +#define RTK_MAC_ADDR_LEN 6 +#define RTK_MAX_LUT_ADDRESS (RTK_MAX_NUM_OF_LEARN_LIMIT) +#define RTK_MAX_LUT_ADDR_ID (RTK_MAX_LUT_ADDRESS - 1) + +typedef rtk_uint32 rtk_l2_age_time_t; + +typedef enum rtk_l2_flood_type_e +{ + FLOOD_UNKNOWNDA = 0, + FLOOD_UNKNOWNMC, + FLOOD_BC, + FLOOD_END +} rtk_l2_flood_type_t; + +typedef rtk_uint32 rtk_l2_flushItem_t; + +typedef enum rtk_l2_flushType_e +{ + FLUSH_TYPE_BY_PORT = 0, /* physical port */ + FLUSH_TYPE_BY_PORT_VID, /* physical port + VID */ + FLUSH_TYPE_BY_PORT_FID, /* physical port + FID */ + FLUSH_TYPE_END +} rtk_l2_flushType_t; + +typedef struct rtk_l2_flushCfg_s +{ + rtk_enable_t flushByVid; + rtk_vlan_t vid; + rtk_enable_t flushByFid; + rtk_uint32 fid; + rtk_enable_t flushByPort; + rtk_port_t port; + rtk_enable_t flushByMac; + rtk_mac_t ucastAddr; + rtk_enable_t flushStaticAddr; + rtk_enable_t flushAddrOnAllPorts; /* this is used when flushByVid */ +} rtk_l2_flushCfg_t; + +typedef enum rtk_l2_read_method_e{ + + READMETHOD_MAC = 0, + READMETHOD_ADDRESS, + READMETHOD_NEXT_ADDRESS, + READMETHOD_NEXT_L2UC, + READMETHOD_NEXT_L2MC, + READMETHOD_NEXT_L3MC, + READMETHOD_NEXT_L2L3MC, + READMETHOD_NEXT_L2UCSPA, + READMETHOD_END +}rtk_l2_read_method_t; + +/* l2 limit learning count action */ +typedef enum rtk_l2_limitLearnCntAction_e +{ + LIMIT_LEARN_CNT_ACTION_DROP = 0, + LIMIT_LEARN_CNT_ACTION_FORWARD, + LIMIT_LEARN_CNT_ACTION_TO_CPU, + LIMIT_LEARN_CNT_ACTION_END +} rtk_l2_limitLearnCntAction_t; + +typedef enum rtk_l2_ipmc_lookup_type_e +{ + LOOKUP_MAC = 0, + LOOKUP_IP, + LOOKUP_IP_VID, + LOOKUP_END +} rtk_l2_ipmc_lookup_type_t; + +/* l2 address table - unicast data structure */ +typedef struct rtk_l2_ucastAddr_s +{ + rtk_mac_t mac; + rtk_uint32 ivl; + rtk_uint32 cvid; + rtk_uint32 fid; + rtk_uint32 efid; + rtk_uint32 port; + rtk_uint32 sa_block; + rtk_uint32 da_block; + rtk_uint32 auth; + rtk_uint32 is_static; + rtk_uint32 priority; + rtk_uint32 sa_pri_en; + rtk_uint32 fwd_pri_en; + rtk_uint32 address; +}rtk_l2_ucastAddr_t; + +/* l2 address table - multicast data structure */ +typedef struct rtk_l2_mcastAddr_s +{ + rtk_uint32 vid; + rtk_mac_t mac; + rtk_uint32 fid; + rtk_portmask_t portmask; + rtk_uint32 ivl; + rtk_uint32 priority; + rtk_uint32 fwd_pri_en; + rtk_uint32 igmp_asic; + rtk_uint32 igmp_index; + rtk_uint32 address; +}rtk_l2_mcastAddr_t; + +/* l2 address table - ip multicast data structure */ +typedef struct rtk_l2_ipMcastAddr_s +{ + ipaddr_t dip; + ipaddr_t sip; + rtk_portmask_t portmask; + rtk_uint32 priority; + rtk_uint32 fwd_pri_en; + rtk_uint32 igmp_asic; + rtk_uint32 igmp_index; + rtk_uint32 address; +}rtk_l2_ipMcastAddr_t; + +/* l2 address table - ip VID multicast data structure */ +typedef struct rtk_l2_ipVidMcastAddr_s +{ + ipaddr_t dip; + ipaddr_t sip; + rtk_uint32 vid; + rtk_portmask_t portmask; + rtk_uint32 address; +}rtk_l2_ipVidMcastAddr_t; + +typedef struct rtk_l2_addr_table_s +{ + rtk_uint32 index; + ipaddr_t sip; + ipaddr_t dip; + rtk_mac_t mac; + rtk_uint32 sa_block; + rtk_uint32 auth; + rtk_portmask_t portmask; + rtk_uint32 age; + rtk_uint32 ivl; + rtk_uint32 cvid; + rtk_uint32 fid; + rtk_uint32 is_ipmul; + rtk_uint32 is_static; + rtk_uint32 is_ipvidmul; + rtk_uint32 l3_vid; +}rtk_l2_addr_table_t; + +typedef enum rtk_l2_clearStatus_e +{ + L2_CLEAR_STATE_FINISH = 0, + L2_CLEAR_STATE_BUSY, + L2_CLEAR_STATE_END +}rtk_l2_clearStatus_t; + +/* Function Name: + * rtk_l2_init + * Description: + * Initialize l2 module of the specified device. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Initialize l2 module before calling any l2 APIs. + */ +extern rtk_api_ret_t rtk_l2_init(void); + +/* Function Name: + * rtk_l2_addr_add + * Description: + * Add LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * pL2_data - Unicast entry parameter + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address already existed in LUT, it will udpate the status of the entry. + * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries + * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +extern rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_addr_get + * Description: + * Get LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address existed in LUT, it will return the port and fid where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +extern rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_addr_next_get + * Description: + * Get Next LUT unicast entry. + * Input: + * read_method - The reading method. + * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA + * pAddress - The Address ID + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next unicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_addr_del + * Description: + * Delete LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * fid - Filtering database + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +extern rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_mcastAddr_add + * Description: + * Add LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address already existed in the LUT, it will udpate the + * port mask of the entry. Otherwise, it will find an empty or asic auto learned + * entry to write. If all the entries with the same hash value can't be replaced, + * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_mcastAddr_get + * Description: + * Get LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address existed in the LUT, it will return the port where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_mcastAddr_next_get + * Description: + * Get Next L2 Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next L2 multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all multicast entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_mcastAddr_del + * Description: + * Delete LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_add + * Description: + * Add Lut IP multicast entry + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user + * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to + * forward IP multicast frame directly without flooding. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_get + * Description: + * Get LUT IP multicast entry. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Lut table of IP multicast entry. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_next_get + * Description: + * Get Next IP Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_del + * Description: + * Delete a ip multicast address entry from the specified device. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can delete a IP multicast address entry from the specified device. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_add + * Description: + * Add Lut IP multicast+VID entry + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_get + * Description: + * Get LUT IP multicast+VID entry. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_next_get + * Description: + * Get Next IP Multicast+VID entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_del + * Description: + * Delete a ip multicast+VID address entry from the specified device. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ucastAddr_flush + * Description: + * Flush L2 mac address by type in the specified device (both dynamic and static). + * Input: + * pConfig - flush configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * flushByVid - 1: Flush by VID, 0: Don't flush by VID + * vid - VID (0 ~ 4095) + * flushByFid - 1: Flush by FID, 0: Don't flush by FID + * fid - FID (0 ~ 15) + * flushByPort - 1: Flush by Port, 0: Don't flush by Port + * port - Port ID + * flushByMac - Not Supported + * ucastAddr - Not Supported + * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries + * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. + */ +extern rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig); + +/* Function Name: + * rtk_l2_table_clear + * Description: + * Flush all static & dynamic entries in LUT. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_table_clear(void); + +/* Function Name: + * rtk_l2_table_clearStatus_get + * Description: + * Get table clear status + * Input: + * None + * Output: + * pStatus - Clear status, 1:Busy, 0:finish + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus); + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_set + * Description: + * Set HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * enable - link down flush status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_get + * Description: + * Get HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * Output: + * pEnable - link down flush status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_l2_agingEnable_set + * Description: + * Set L2 LUT aging status per port setting. + * Input: + * port - Port id. + * enable - Aging status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can be used to set L2 LUT aging status per port. + */ +extern rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_l2_agingEnable_get + * Description: + * Get L2 LUT aging status per port setting. + * Input: + * port - Port id. + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can be used to get L2 LUT aging function per port. + */ +extern rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_l2_limitLearningCnt_set + * Description: + * Set per-Port auto learning limit number + * Input: + * port - Port id. + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set per-port ASIC auto learning limit number from 0(disable learning) + * to 8k. + */ +extern rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt); + +/* Function Name: + * rtk_l2_limitLearningCnt_get + * Description: + * Get per-Port auto learning limit number + * Input: + * port - Port id. + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning limit number. + */ +extern rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_set + * Description: + * Set System auto learning limit number + * Input: + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set system ASIC auto learning limit number from 0(disable learning) + * to 2112. + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt); + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_get + * Description: + * Get System auto learning limit number + * Input: + * None + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get system ASIC auto learning limit number. + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt); + +/* Function Name: + * rtk_l2_limitLearningCntAction_set + * Description: + * Configure auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action); + +/* Function Name: + * rtk_l2_limitLearningCntAction_get + * Description: + * Get auto learn over limit number action. + * Input: + * port - Port id. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction); + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_set + * Description: + * Configure system auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action); + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_get + * Description: + * Get system auto learn over limit number action. + * Input: + * None. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction); + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_set + * Description: + * Configure system auto learn portmask + * Input: + * pPortmask - Port Mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_get + * Description: + * get system auto learn portmask + * Input: + * None + * Output: + * pPortmask - Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_learningCnt_get + * Description: + * Get per-Port current auto learning number + * Input: + * port - Port id. + * Output: + * pMac_cnt - ASIC auto learning entries number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning number + */ +extern rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); + +/* Function Name: + * rtk_l2_floodPortMask_set + * Description: + * Set flooding portmask + * Input: + * type - flooding type. + * pFlood_portmask - flooding porkmask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +extern rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); + +/* Function Name: + * rtk_l2_floodPortMask_get + * Description: + * Get flooding portmask + * Input: + * type - flooding type. + * Output: + * pFlood_portmask - flooding porkmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +extern rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); + +/* Function Name: + * rtk_l2_localPktPermit_set + * Description: + * Set permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * permit - permittion status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid permit value. + * Note: + * This API is setted to permit frame if its source port is equal to destination port. + */ +extern rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit); + +/* Function Name: + * rtk_l2_localPktPermit_get + * Description: + * Get permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * Output: + * pPermit - permittion status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API is to get permittion status for frames if its source port is equal to destination port. + */ +extern rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit); + +/* Function Name: + * rtk_l2_aging_set + * Description: + * Set LUT agging out speed + * Input: + * aging_time - Agging out time. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can set LUT agging out period for each entry and the range is from 14s to 800s. + */ +extern rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time); + +/* Function Name: + * rtk_l2_aging_get + * Description: + * Get LUT agging out time + * Input: + * None + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get LUT agging out period for each entry. + */ +extern rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time); + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_set + * Description: + * Set Lut IP multicast lookup function + * Input: + * type - Lookup type for IPMC packet. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can work with rtk_l2_ipMcastAddrLookupException_add. + * If users set the lookup type to DIP, the group in exception table + * will be lookup by DIP+SIP + * If users set the lookup type to DIP+SIP, the group in exception table + * will be lookup by only DIP + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type); + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_get + * Description: + * Get Lut IP multicast lookup function + * Input: + * None. + * Output: + * pType - Lookup type for IPMC packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType); + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_set + * Description: + * Set IPMC packet forward to rounter port also or not + * Input: + * enabled - 1: Inlcude router port, 0, exclude router port + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_get + * Description: + * Get IPMC packet forward to rounter port also or not + * Input: + * None. + * Output: + * pEnabled - 1: Inlcude router port, 0, exclude router port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_add + * Description: + * Add an IP Multicast entry to group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * pPortmask - portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Add an entry to IP Multicast Group table. + */ +extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_del + * Description: + * Delete an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid); + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_get + * Description: + * get an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * pPortmask - member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_entry_get + * Description: + * Get LUT unicast entry. + * Input: + * pL2_entry - Index field in the structure. + * Output: + * pL2_entry - other fields such as MAC, port, age... + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API is used to get address by index from 0~2111. + */ +extern rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry); + + +#endif /* __RTK_API_L2_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/leaky.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/leaky.h new file mode 100755 index 00000000..13ef60df --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/leaky.h @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Leaky module high-layer API defination + * + */ + +#ifndef __RTK_API_LEAKY_H__ +#define __RTK_API_LEAKY_H__ + + +typedef enum rtk_leaky_type_e +{ + LEAKY_BRG_GROUP = 0, + LEAKY_FD_PAUSE, + LEAKY_SP_MCAST, + LEAKY_1X_PAE, + LEAKY_UNDEF_BRG_04, + LEAKY_UNDEF_BRG_05, + LEAKY_UNDEF_BRG_06, + LEAKY_UNDEF_BRG_07, + LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + LEAKY_UNDEF_BRG_09, + LEAKY_UNDEF_BRG_0A, + LEAKY_UNDEF_BRG_0B, + LEAKY_UNDEF_BRG_0C, + LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + LEAKY_8021AB, + LEAKY_UNDEF_BRG_0F, + LEAKY_BRG_MNGEMENT, + LEAKY_UNDEFINED_11, + LEAKY_UNDEFINED_12, + LEAKY_UNDEFINED_13, + LEAKY_UNDEFINED_14, + LEAKY_UNDEFINED_15, + LEAKY_UNDEFINED_16, + LEAKY_UNDEFINED_17, + LEAKY_UNDEFINED_18, + LEAKY_UNDEFINED_19, + LEAKY_UNDEFINED_1A, + LEAKY_UNDEFINED_1B, + LEAKY_UNDEFINED_1C, + LEAKY_UNDEFINED_1D, + LEAKY_UNDEFINED_1E, + LEAKY_UNDEFINED_1F, + LEAKY_GMRP, + LEAKY_GVRP, + LEAKY_UNDEF_GARP_22, + LEAKY_UNDEF_GARP_23, + LEAKY_UNDEF_GARP_24, + LEAKY_UNDEF_GARP_25, + LEAKY_UNDEF_GARP_26, + LEAKY_UNDEF_GARP_27, + LEAKY_UNDEF_GARP_28, + LEAKY_UNDEF_GARP_29, + LEAKY_UNDEF_GARP_2A, + LEAKY_UNDEF_GARP_2B, + LEAKY_UNDEF_GARP_2C, + LEAKY_UNDEF_GARP_2D, + LEAKY_UNDEF_GARP_2E, + LEAKY_UNDEF_GARP_2F, + LEAKY_IGMP, + LEAKY_IPMULTICAST, + LEAKY_CDP, + LEAKY_CSSTP, + LEAKY_LLDP, + LEAKY_END, +}rtk_leaky_type_t; + +/* Function Name: + * rtk_leaky_vlan_set + * Description: + * Set VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set VLAN leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_leaky_vlan_get + * Description: + * Get VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get VLAN leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_leaky_portIsolation_set + * Description: + * Set port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set port isolation leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_leaky_portIsolation_get + * Description: + * Get port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get port isolation leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable); + +#endif /* __RTK_API_LEAKY_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/led.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/led.h new file mode 100755 index 00000000..71acc7c9 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/led.h @@ -0,0 +1,481 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes LED module high-layer API defination + * + */ + +#ifndef __RTK_API_LED_H__ +#define __RTK_API_LED_H__ + +typedef enum rtk_led_operation_e +{ + LED_OP_SCAN=0, + LED_OP_PARALLEL, + LED_OP_SERIAL, + LED_OP_END, +}rtk_led_operation_t; + + +typedef enum rtk_led_active_e +{ + LED_ACTIVE_HIGH=0, + LED_ACTIVE_LOW, + LED_ACTIVE_END, +}rtk_led_active_t; + +typedef enum rtk_led_config_e +{ + LED_CONFIG_LEDOFF=0, + LED_CONFIG_DUPCOL, + LED_CONFIG_LINK_ACT, + LED_CONFIG_SPD1000, + LED_CONFIG_SPD100, + LED_CONFIG_SPD10, + LED_CONFIG_SPD1000ACT, + LED_CONFIG_SPD100ACT, + LED_CONFIG_SPD10ACT, + LED_CONFIG_SPD10010ACT, + LED_CONFIG_LOOPDETECT, + LED_CONFIG_EEE, + LED_CONFIG_LINKRX, + LED_CONFIG_LINKTX, + LED_CONFIG_MASTER, + LED_CONFIG_ACT, + LED_CONFIG_END, +}rtk_led_congig_t; + +typedef struct rtk_led_ability_s +{ + rtk_enable_t link_10m; + rtk_enable_t link_100m; + rtk_enable_t link_500m; + rtk_enable_t link_1000m; + rtk_enable_t act_rx; + rtk_enable_t act_tx; +}rtk_led_ability_t; + +typedef enum rtk_led_blink_rate_e +{ + LED_BLINKRATE_32MS=0, + LED_BLINKRATE_64MS, + LED_BLINKRATE_128MS, + LED_BLINKRATE_256MS, + LED_BLINKRATE_512MS, + LED_BLINKRATE_1024MS, + LED_BLINKRATE_48MS, + LED_BLINKRATE_96MS, + LED_BLINKRATE_END, +}rtk_led_blink_rate_t; + +typedef enum rtk_led_group_e +{ + LED_GROUP_0 = 0, + LED_GROUP_1, + LED_GROUP_2, + LED_GROUP_END +}rtk_led_group_t; + + +typedef enum rtk_led_force_mode_e +{ + LED_FORCE_NORMAL=0, + LED_FORCE_BLINK, + LED_FORCE_OFF, + LED_FORCE_ON, + LED_FORCE_END +}rtk_led_force_mode_t; + +typedef enum rtk_led_serialOutput_e +{ + SERIAL_LED_NONE = 0, + SERIAL_LED_0, + SERIAL_LED_0_1, + SERIAL_LED_0_2, + SERIAL_LED_END, +}rtk_led_serialOutput_t; + + +/* Function Name: + * rtk_led_enable_set + * Description: + * Set Led enable congiuration + * Input: + * group - LED group id. + * pPortmask - LED enable port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can be used to enable LED per port per group. + */ +extern rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_led_enable_get + * Description: + * Get Led enable congiuration + * Input: + * group - LED group id. + * Output: + * pPortmask - LED enable port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can be used to get LED enable status. + */ +extern rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_led_operation_set + * Description: + * Set Led operation mode + * Input: + * mode - LED operation mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +extern rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode); + +/* Function Name: + * rtk_led_operation_get + * Description: + * Get Led operation mode + * Input: + * None + * Output: + * pMode - Support LED operation mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +extern rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode); + +/* Function Name: + * rtk_led_modeForce_set + * Description: + * Set Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * mode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can force to one force mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +extern rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode); + +/* Function Name: + * rtk_led_modeForce_get + * Description: + * Get Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * pMode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can get forced Led group mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +extern rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode); + +/* Function Name: + * rtk_led_blinkRate_set + * Description: + * Set LED blinking rate + * Input: + * blinkRate - blinking rate. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * ASIC support 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +extern rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate); + +/* Function Name: + * rtk_led_blinkRate_get + * Description: + * Get LED blinking rate at mode 0 to mode 3 + * Input: + * None + * Output: + * pBlinkRate - blinking rate. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +extern rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate); + +/* Function Name: + * rtk_led_groupConfig_set + * Description: + * Set per group Led to congiuration mode + * Input: + * group - LED group. + * config - LED configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. + * - Definition LED Statuses Description + * - 0000 LED_Off LED pin Tri-State. + * - 0001 Dup/Col Collision, Full duplex Indicator. + * - 0010 Link/Act Link, Activity Indicator. + * - 0011 Spd1000 1000Mb/s Speed Indicator. + * - 0100 Spd100 100Mb/s Speed Indicator. + * - 0101 Spd10 10Mb/s Speed Indicator. + * - 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. + * - 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. + * - 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. + * - 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. + * - 1010 LoopDetect LoopDetect Indicator. + * - 1011 EEE EEE Indicator. + * - 1100 Link/Rx Link, Activity Indicator. + * - 1101 Link/Tx Link, Activity Indicator. + * - 1110 Master Link on Master Indicator. + * - 1111 Act Activity Indicator. Low for link established. + */ +extern rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config); + +/* Function Name: + * rtk_led_groupConfig_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED indicated information configuration for each LED group. + */ +extern rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig); + +/* Function Name: + * rtk_led_groupAbility_set + * Description: + * Configure per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +extern rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility); + +/* Function Name: + * rtk_led_groupAbility_get + * Description: + * Get per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +extern rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility); + +/* Function Name: + * rtk_led_serialMode_set + * Description: + * Set Led serial mode active congiuration + * Input: + * active - LED group. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED serial mode active congiuration. + */ +extern rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active); + +/* Function Name: + * rtk_led_serialMode_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED serial mode active configuration. + */ +extern rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive); + +/* Function Name: + * rtk_led_OutputEnable_set + * Description: + * This API set LED I/O state. + * Input: + * enabled - LED I/O state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set LED I/O state. + */ +extern rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state); + + +/* Function Name: + * rtk_led_OutputEnable_get + * Description: + * This API get LED I/O state. + * Input: + * None. + * Output: + * pEnabled - LED I/O state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current LED I/O state. + */ +extern rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState); + +/* Function Name: + * rtk_led_serialModePortmask_set + * Description: + * This API configure Serial LED output Group and portmask + * Input: + * output - output group + * pPortmask - output portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +extern rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_led_serialModePortmask_get + * Description: + * This API get Serial LED output Group and portmask + * Input: + * None. + * Output: + * pOutput - output group + * pPortmask - output portmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +extern rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask); + +#endif /* __RTK_API_LED_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/mirror.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/mirror.h new file mode 100755 index 00000000..1e984b7d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/mirror.h @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Mirror module high-layer API defination + * + */ + +#ifndef __RTK_API_MIRROR_H__ +#define __RTK_API_MIRROR_H__ + +typedef enum rtk_mirror_keep_e +{ + MIRROR_FOLLOW_VLAN = 0, + MIRROR_KEEP_ORIGINAL, + MIRROR_KEEP_END +}rtk_mirror_keep_t; + + +/* Function Name: + * rtk_mirror_portBased_set + * Description: + * Set port mirror function. + * Input: + * mirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API is to set mirror function of source port and mirror port. + * The mirror port can only be set to one port and the TX and RX mirror ports + * should be identical. + */ +extern rtk_api_ret_t rtk_mirror_portBased_set(rtk_port_t mirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask); + +/* Function Name: + * rtk_mirror_portBased_get + * Description: + * Get port mirror function. + * Input: + * None + * Output: + * pMirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror function of source port and mirror port. + */ +extern rtk_api_ret_t rtk_mirror_portBased_get(rtk_port_t* pMirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask); + +/* Function Name: + * rtk_mirror_portIso_set + * Description: + * Set mirror port isolation. + * Input: + * enable |Mirror isolation status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror isolation function that prevent normal forwarding packets to miror port. + */ +extern rtk_api_ret_t rtk_mirror_portIso_set(rtk_enable_t enable); + +/* Function Name: + * rtk_mirror_portIso_get + * Description: + * Get mirror port isolation. + * Input: + * None + * Output: + * pEnable |Mirror isolation status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation status. + */ +extern rtk_api_ret_t rtk_mirror_portIso_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_mirror_vlanLeaky_set + * Description: + * Set mirror VLAN leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +extern rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable); + + +/* Function Name: + * rtk_mirror_vlanLeaky_get + * Description: + * Get mirror VLAN leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror VLAN leaky status. + */ +extern rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable); + +/* Function Name: + * rtk_mirror_isolationLeaky_set + * Description: + * Set mirror Isolation leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +extern rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable); + +/* Function Name: + * rtk_mirror_isolationLeaky_get + * Description: + * Get mirror isolation leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation leaky status. + */ +extern rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable); + +/* Function Name: + * rtk_mirror_keep_set + * Description: + * Set mirror packet format keep. + * Input: + * mode - -mirror keep mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set -mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +extern rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode); + + +/* Function Name: + * rtk_mirror_keep_get + * Description: + * Get mirror packet format keep. + * Input: + * None + * Output: + * pMode -mirror keep mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +extern rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode); + +/* Function Name: + * rtk_mirror_override_set + * Description: + * Set port mirror override function. + * Input: + * rxMirror - 1: output mirrored packet, 0: output normal forward packet + * txMirror - 1: output mirrored packet, 0: output normal forward packet + * aclMirror - 1: output mirrored packet, 0: output normal forward packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API is to set mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +extern rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror); + +/* Function Name: + * rtk_mirror_override_get + * Description: + * Get port mirror override function. + * Input: + * None + * Output: + * pRxMirror - 1: output mirrored packet, 0: output normal forward packet + * pTxMirror - 1: output mirrored packet, 0: output normal forward packet + * pAclMirror - 1: output mirrored packet, 0: output normal forward packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * The API is to Get mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +extern rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror); + +#endif /* __RTK_API_MIRROR_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/oam.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/oam.h new file mode 100755 index 00000000..1fc14bd6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/oam.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes the following modules and sub-modules + * (1) OAM (802.3ah) configuration + * + */ + +#ifndef __RTK_OAM_H__ +#define __RTK_OAM_H__ + +/* + * Symbol Definition + */ + + +/* + * Data Declaration + */ + + +/* + * Macro Declaration + */ + +typedef enum rtk_oam_parser_act_e +{ + OAM_PARSER_ACTION_FORWARD = 0, + OAM_PARSER_ACTION_LOOPBACK, + OAM_PARSER_ACTION_DISCARD, + OAM_PARSER_ACTION_END, + +} rtk_oam_parser_act_t; + +typedef enum rtk_oam_multiplexer_act_e +{ + OAM_MULTIPLEXER_ACTION_FORWARD = 0, + OAM_MULTIPLEXER_ACTION_DISCARD, + OAM_MULTIPLEXER_ACTION_CPUONLY, + OAM_MULTIPLEXER_ACTION_END, + +} rtk_oam_multiplexer_act_t; + + +/* + * Function Declaration + */ + +/* Function Name: + * rtk_oam_init + * Description: + * Initialize oam module. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * Must initialize oam module before calling any oam APIs. + */ +extern rtk_api_ret_t rtk_oam_init(void); + +/* Function Name: + * rtk_oam_state_set + * Description: + * This API set OAM state. + * Input: + * enabled -OAMstate + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set OAM state. + */ +extern rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_oam_state_get + * Description: + * This API get OAM state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current OAM state. + */ +extern rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled); + + +/* Module Name : OAM */ + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Set OAM parser action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action); + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Get OAM parser action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction); + + +/* Function Name: + * rtk_oam_multiplexerAction_set + * Description: + * Set OAM multiplexer action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action); + +/* Function Name: + * rtk_oam_multiplexerAction_set + * Description: + * Get OAM multiplexer action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction); + + +#endif /* __RTK_OAM_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/port.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/port.h new file mode 100755 index 00000000..fcac1bcb --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/port.h @@ -0,0 +1,959 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes port module high-layer API defination + * + */ + +#ifndef __RTK_API_PORT_H__ +#define __RTK_API_PORT_H__ + +/* + * Data Type Declaration + */ + +#define PHY_CONTROL_REG 0 +#define PHY_STATUS_REG 1 +#define PHY_AN_ADVERTISEMENT_REG 4 +#define PHY_AN_LINKPARTNER_REG 5 +#define PHY_1000_BASET_CONTROL_REG 9 +#define PHY_1000_BASET_STATUS_REG 10 +#define PHY_RESOLVED_REG 26 + +#define RTK_EFID_MAX 0x7 + +#define RTK_FIBER_FORCE_1000M 3 +#define RTK_FIBER_FORCE_100M 5 +#define RTK_FIBER_FORCE_100M1000M 7 + +#define RTK_INDRECT_ACCESS_CRTL 0x1f00 +#define RTK_INDRECT_ACCESS_STATUS 0x1f01 +#define RTK_INDRECT_ACCESS_ADDRESS 0x1f02 +#define RTK_INDRECT_ACCESS_WRITE_DATA 0x1f03 +#define RTK_INDRECT_ACCESS_READ_DATA 0x1f04 +#define RTK_INDRECT_ACCESS_DELAY 0x1f80 +#define RTK_INDRECT_ACCESS_BURST 0x1f81 +#define RTK_RW_MASK 0x2 +#define RTK_CMD_MASK 0x1 +#define RTK_PHY_BUSY_OFFSET 2 + + +typedef enum rtk_mode_ext_e +{ + MODE_EXT_DISABLE = 0, + MODE_EXT_RGMII, + MODE_EXT_MII_MAC, + MODE_EXT_MII_PHY, + MODE_EXT_TMII_MAC, + MODE_EXT_TMII_PHY, + MODE_EXT_GMII, + MODE_EXT_RMII_MAC, + MODE_EXT_RMII_PHY, + MODE_EXT_SGMII, + MODE_EXT_HSGMII, + MODE_EXT_1000X_100FX, + MODE_EXT_1000X, + MODE_EXT_100FX, + MODE_EXT_RGMII_2, + MODE_EXT_MII_MAC_2, + MODE_EXT_MII_PHY_2, + MODE_EXT_TMII_MAC_2, + MODE_EXT_TMII_PHY_2, + MODE_EXT_RMII_MAC_2, + MODE_EXT_RMII_PHY_2, + MODE_EXT_END +} rtk_mode_ext_t; + +typedef enum rtk_port_duplex_e +{ + PORT_HALF_DUPLEX = 0, + PORT_FULL_DUPLEX, + PORT_DUPLEX_END +} rtk_port_duplex_t; + +typedef enum rtk_port_linkStatus_e +{ + PORT_LINKDOWN = 0, + PORT_LINKUP, + PORT_LINKSTATUS_END +} rtk_port_linkStatus_t; + +typedef struct rtk_port_mac_ability_s +{ + rtk_uint32 forcemode; + rtk_uint32 speed; + rtk_uint32 duplex; + rtk_uint32 link; + rtk_uint32 nway; + rtk_uint32 txpause; + rtk_uint32 rxpause; +}rtk_port_mac_ability_t; + +typedef struct rtk_port_phy_ability_s +{ + rtk_uint32 AutoNegotiation; /*PHY register 0.12 setting for auto-negotiation process*/ + rtk_uint32 Half_10; /*PHY register 4.5 setting for 10BASE-TX half duplex capable*/ + rtk_uint32 Full_10; /*PHY register 4.6 setting for 10BASE-TX full duplex capable*/ + rtk_uint32 Half_100; /*PHY register 4.7 setting for 100BASE-TX half duplex capable*/ + rtk_uint32 Full_100; /*PHY register 4.8 setting for 100BASE-TX full duplex capable*/ + rtk_uint32 Full_1000; /*PHY register 9.9 setting for 1000BASE-T full duplex capable*/ + rtk_uint32 FC; /*PHY register 4.10 setting for flow control capability*/ + rtk_uint32 AsyFC; /*PHY register 4.11 setting for asymmetric flow control capability*/ +} rtk_port_phy_ability_t; + +typedef rtk_uint32 rtk_port_phy_data_t; /* phy page */ + +typedef enum rtk_port_phy_mdix_mode_e +{ + PHY_AUTO_CROSSOVER_MODE= 0, + PHY_FORCE_MDI_MODE, + PHY_FORCE_MDIX_MODE, + PHY_FORCE_MODE_END +} rtk_port_phy_mdix_mode_t; + +typedef enum rtk_port_phy_mdix_status_e +{ + PHY_STATUS_AUTO_MDI_MODE= 0, + PHY_STATUS_AUTO_MDIX_MODE, + PHY_STATUS_FORCE_MDI_MODE, + PHY_STATUS_FORCE_MDIX_MODE, + PHY_STATUS_FORCE_MODE_END +} rtk_port_phy_mdix_status_t; + +typedef rtk_uint32 rtk_port_phy_page_t; /* phy page */ + +typedef enum rtk_port_phy_reg_e +{ + PHY_REG_CONTROL = 0, + PHY_REG_STATUS, + PHY_REG_IDENTIFIER_1, + PHY_REG_IDENTIFIER_2, + PHY_REG_AN_ADVERTISEMENT, + PHY_REG_AN_LINKPARTNER, + PHY_REG_1000_BASET_CONTROL = 9, + PHY_REG_1000_BASET_STATUS, + PHY_REG_END = 32 +} rtk_port_phy_reg_t; + +typedef enum rtk_port_phy_test_mode_e +{ + PHY_TEST_MODE_NORMAL= 0, + PHY_TEST_MODE_1, + PHY_TEST_MODE_2, + PHY_TEST_MODE_3, + PHY_TEST_MODE_4, + PHY_TEST_MODE_END +} rtk_port_phy_test_mode_t; + +typedef enum rtk_port_speed_e +{ + PORT_SPEED_10M = 0, + PORT_SPEED_100M, + PORT_SPEED_1000M, + PORT_SPEED_500M, + PORT_SPEED_2500M, + PORT_SPEED_END +} rtk_port_speed_t; + +typedef enum rtk_port_media_e +{ + PORT_MEDIA_COPPER = 0, + PORT_MEDIA_FIBER, + PORT_MEDIA_END +}rtk_port_media_t; + +typedef struct rtk_rtctResult_s +{ + rtk_port_speed_t linkType; + union + { + struct fe_result_s + { + rtk_uint32 isRxShort; + rtk_uint32 isTxShort; + rtk_uint32 isRxOpen; + rtk_uint32 isTxOpen; + rtk_uint32 isRxMismatch; + rtk_uint32 isTxMismatch; + rtk_uint32 isRxLinedriver; + rtk_uint32 isTxLinedriver; + rtk_uint32 rxLen; + rtk_uint32 txLen; + } fe_result; + + struct ge_result_s + { + rtk_uint32 channelAShort; + rtk_uint32 channelBShort; + rtk_uint32 channelCShort; + rtk_uint32 channelDShort; + + rtk_uint32 channelAOpen; + rtk_uint32 channelBOpen; + rtk_uint32 channelCOpen; + rtk_uint32 channelDOpen; + + rtk_uint32 channelAMismatch; + rtk_uint32 channelBMismatch; + rtk_uint32 channelCMismatch; + rtk_uint32 channelDMismatch; + + rtk_uint32 channelALinedriver; + rtk_uint32 channelBLinedriver; + rtk_uint32 channelCLinedriver; + rtk_uint32 channelDLinedriver; + + rtk_uint32 channelALen; + rtk_uint32 channelBLen; + rtk_uint32 channelCLen; + rtk_uint32 channelDLen; + } ge_result; + }result; +} rtk_rtctResult_t; + +/* Function Name: + * rtk_port_phyAutoNegoAbility_set + * Description: + * Set ethernet PHY auto-negotiation desired ability. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + */ +extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyAutoNegoAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyForceModeAbility_set + * Description: + * Set the port speed/duplex mode/pause/asy_pause in the PHY force mode. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + */ +extern rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyForceModeAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +extern rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyStatus_get + * Description: + * Get ethernet PHY linking status + * Input: + * port - Port id. + * Output: + * linkStatus - PHY link status + * speed - PHY link speed + * duplex - PHY duplex mode + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * API will return auto negotiation status of phy. + */ +extern rtk_api_ret_t rtk_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex); + +/* Function Name: + * rtk_port_macForceLink_set + * Description: + * Set port force linking configuration. + * Input: + * port - port id. + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can set Port/MAC force mode properties. + */ +extern rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macForceLink_get + * Description: + * Get port force linking configuration. + * Input: + * port - Port id. + * Output: + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get Port/MAC force mode properties. + */ +extern rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macForceLinkExt_set + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * mode - external interface mode + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface force mode properties. + * The external interface can be set to: + * - MODE_EXT_DISABLE, + * - MODE_EXT_RGMII, + * - MODE_EXT_MII_MAC, + * - MODE_EXT_MII_PHY, + * - MODE_EXT_TMII_MAC, + * - MODE_EXT_TMII_PHY, + * - MODE_EXT_GMII, + * - MODE_EXT_RMII_MAC, + * - MODE_EXT_RMII_PHY, + * - MODE_EXT_SGMII, + * - MODE_EXT_HSGMII, + * - MODE_EXT_1000X_100FX, + * - MODE_EXT_1000X, + * - MODE_EXT_100FX, + */ +extern rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macForceLinkExt_get + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * Output: + * pMode - external interface mode + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get external interface force mode properties. + */ +extern rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macStatus_get + * Description: + * Get port link status. + * Input: + * port - Port id. + * Output: + * pPortstatus - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get Port/PHY properties. + */ +extern rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus); + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_set + * Description: + * Set Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * enable - Loopback state, 0:disable, 1:enable + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can enable/disable Local loopback in MAC. + * For UTP port, This API will also enable the digital + * loopback bit in PHY register for sync of speed between + * PHY and MAC. For EXT port, users need to force the + * link state by themself. + */ +extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_get + * Description: + * Get Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * Output: + * pEnable - Loopback state, 0:disable, 1:enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_phyReg_set + * Description: + * Set PHY register data of the specific port. + * Input: + * port - port id. + * reg - Register id + * regData - Register data + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can set PHY register data of the specific port. + */ +extern rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t value); + +/* Function Name: + * rtk_port_phyReg_get + * Description: + * Get PHY register data of the specific port. + * Input: + * port - Port id. + * reg - Register id + * Output: + * pData - Register data + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can get PHY register data of the specific port. + */ +extern rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData); + +/* Function Name: + * rtk_port_backpressureEnable_set + * Description: + * Set the half duplex backpressure enable status of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_port_backpressureEnable_get + * Description: + * Get the half duplex backpressure enable status of the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_adminEnable_set + * Description: + * Set port admin configuration of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_port_adminEnable_get + * Description: + * Get port admin configurationof the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_isolation_set + * Description: + * Set permitted port isolation portmask + * Input: + * port - port id. + * pPortmask - Permit port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * This API set the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +extern rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_port_isolation_get + * Description: + * Get permitted port isolation portmask + * Input: + * port - Port id. + * Output: + * pPortmask - Permit port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API get the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +extern rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_port_rgmiiDelayExt_set + * Description: + * Set RGMII interface delay value for TX and RX. + * Input: + * txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay + * rxDelay - RX delay value, 0~7 for delay setup. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for no-delay, and 7 for maximum delay. + */ +extern rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay); + +/* Function Name: + * rtk_port_rgmiiDelayExt_get + * Description: + * Get RGMII interface delay value for TX and RX. + * Input: + * None + * Output: + * pTxDelay - TX delay value + * pRxDelay - RX delay value + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for n0-delay, and 7 for maximum delay. + */ +extern rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay); + +/* Function Name: + * rtk_port_phyEnableAll_set + * Description: + * Set all PHY enable status. + * Input: + * enable - PHY Enable State. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable); + +/* Function Name: + * rtk_port_phyEnableAll_get + * Description: + * Get all PHY enable status. + * Input: + * None + * Output: + * pEnable - PHY Enable State. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_phyEnableAll_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_efid_set + * Description: + * Set port-based enhanced filtering database + * Input: + * port - Port id. + * efid - Specified enhanced filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based enhanced filtering database. + */ +extern rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid); + +/* Function Name: + * rtk_port_efid_get + * Description: + * Get port-based enhanced filtering database + * Input: + * port - Port id. + * Output: + * pEfid - Specified enhanced filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based enhanced filtering database status. + */ +extern rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid); + +/* Function Name: + * rtk_port_phyComboPortMedia_set + * Description: + * Set Combo port media type + * Input: + * port - Port id. (Should be Port 4) + * media - Media (COPPER or FIBER) + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +extern rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media); + +/* Function Name: + * rtk_port_phyComboPortMedia_get + * Description: + * Get Combo port media type + * Input: + * port - Port id. (Should be Port 4) + * Output: + * pMedia - Media (COPPER or FIBER) + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +extern rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia); + +/* Function Name: + * rtk_port_rtctEnable_set + * Description: + * Enable RTCT test + * Input: + * pPortmask - Port mask of RTCT enabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can enable RTCT Test + */ +extern rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_port_rtctDisable_set + * Description: + * Disable RTCT test + * Input: + * pPortmask - Port mask of RTCT disabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can disable RTCT Test + */ +rtk_api_ret_t rtk_port_rtctDisable_set(rtk_portmask_t *pPortmask); + + +/* Function Name: + * rtk_port_rtctResult_get + * Description: + * Get the result of RTCT test + * Input: + * port - Port ID + * Output: + * pRtctResult - The result of RTCT result + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_PHY_RTCT_NOT_FINISH - Testing does not finish. + * Note: + * The API can get RTCT test result. + * RTCT test may takes 4.8 seconds to finish its test at most. + * Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or + * other error code, the result can not be referenced and + * user should call this API again until this API returns + * a RT_ERR_OK. + * The result is stored at pRtctResult->ge_result + * pRtctResult->linkType is unused. + * The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M + */ +extern rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult); + +/* Function Name: + * rtk_port_sds_reset + * Description: + * Reset Serdes + * Input: + * port - Port ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +extern rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port); + +/* Function Name: + * rtk_port_sgmiiLinkStatus_get + * Description: + * Get SGMII status + * Input: + * port - Port ID + * Output: + * pSignalDetect - Signal detect + * pSync - Sync + * pLink - Link + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +extern rtk_api_ret_t rtk_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink); + +/* Function Name: + * rtk_port_sgmiiNway_set + * Description: + * Configure SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * state - Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API configure SGMII/HSGMII port Nway state + */ +extern rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state); + +/* Function Name: + * rtk_port_sgmiiNway_get + * Description: + * Get SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * Output: + * pState - Nway state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get SGMII/HSGMII port Nway state + */ +extern rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState); + +#endif /* __RTK_API_PORT_H__ */ + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/ptp.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/ptp.h new file mode 100755 index 00000000..6c4aca5a --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/ptp.h @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes time module high-layer API defination + * + */ + +#ifndef __RTK_API_PTP_H__ +#define __RTK_API_PTP_H__ + +/* + * Symbol Definition + */ +#define RTK_MAX_NUM_OF_NANO_SECOND 0x3B9AC9FF +#define RTK_PTP_INTR_MASK 0xFF +#define RTK_MAX_NUM_OF_TPID 0xFFFF + +/* Message Type */ +typedef enum rtk_ptp_msgType_e +{ + PTP_MSG_TYPE_TX_SYNC = 0, + PTP_MSG_TYPE_TX_DELAY_REQ, + PTP_MSG_TYPE_TX_PDELAY_REQ, + PTP_MSG_TYPE_TX_PDELAY_RESP, + PTP_MSG_TYPE_RX_SYNC, + PTP_MSG_TYPE_RX_DELAY_REQ, + PTP_MSG_TYPE_RX_PDELAY_REQ, + PTP_MSG_TYPE_RX_PDELAY_RESP, + PTP_MSG_TYPE_END +} rtk_ptp_msgType_t; + +typedef enum rtk_ptp_intType_e +{ + PTP_INT_TYPE_TX_SYNC = 0, + PTP_INT_TYPE_TX_DELAY_REQ, + PTP_INT_TYPE_TX_PDELAY_REQ, + PTP_INT_TYPE_TX_PDELAY_RESP, + PTP_INT_TYPE_RX_SYNC, + PTP_INT_TYPE_RX_DELAY_REQ, + PTP_INT_TYPE_RX_PDELAY_REQ, + PTP_INT_TYPE_RX_PDELAY_RESP, + PTP_INT_TYPE_ALL, + PTP_INT_TYPE_END +}rtk_ptp_intType_t; + +typedef enum rtk_ptp_sys_adjust_e +{ + SYS_ADJUST_PLUS = 0, + SYS_ADJUST_MINUS, + SYS_ADJUST_END +} rtk_ptp_sys_adjust_t; + + +/* Reference Time */ +typedef struct rtk_ptp_timeStamp_s +{ + rtk_uint32 sec; + rtk_uint32 nsec; +} rtk_ptp_timeStamp_t; + +typedef struct rtk_ptp_info_s +{ + rtk_uint32 sequenceId; + rtk_ptp_timeStamp_t timeStamp; +} rtk_ptp_info_t; + +typedef rtk_uint32 rtk_ptp_tpid_t; + +typedef rtk_uint32 rtk_ptp_intStatus_t; /* interrupt status mask */ + +/* + * Data Declaration + */ + +/* + * Function Declaration + */ +/* Function Name: + * rtk_time_init + * Description: + * PTP function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize EEE status. + */ +extern rtk_api_ret_t rtk_ptp_init(void); + +/* Function Name: + * rtk_ptp_mac_set + * Description: + * Configure PTP mac address. + * Input: + * mac - mac address to parser PTP packets. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac); + +/* Function Name: + * rtk_ptp_mac_get + * Description: + * Get PTP mac address. + * Input: + * None + * Output: + * pMac - mac address to parser PTP packets. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac); + +/* Function Name: + * rtk_ptp_tpid_set + * Description: + * Configure PTP accepted outer & inner tag TPID. + * Input: + * outerId - Ether type of S-tag frame parsing in PTP ports. + * innerId - Ether type of C-tag frame parsing in PTP ports. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId); + +/* Function Name: + * rtk_ptp_tpid_get + * Description: + * Get PTP accepted outer & inner tag TPID. + * Input: + * None + * Output: + * pOuterId - Ether type of S-tag frame parsing in PTP ports. + * pInnerId - Ether type of C-tag frame parsing in PTP ports. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId); + +/* Function Name: + * rtk_ptp_refTime_set + * Description: + * Set the reference time of the specified device. + * Input: + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp); + +/* Function Name: + * rtk_ptp_refTime_get + * Description: + * Get the reference time of the specified device. + * Input: + * Output: + * pTimeStamp - pointer buffer of the reference time + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp); + +/* Function Name: + * rtk_ptp_refTimeAdjust_set + * Description: + * Adjust the reference time. + * Input: + * unit - unit id + * sign - significant + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * sign=0 for positive adjustment, sign=1 for negative adjustment. + */ +extern rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp); + +/* Function Name: + * rtk_ptp_refTimeEnable_set + * Description: + * Set the enable state of reference time of the specified device. + * Input: + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTimeEnable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_refTimeEnable_get + * Description: + * Get the enable state of reference time of the specified device. + * Input: + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_ptp_portEnable_set + * Description: + * Set PTP status of the specified port. + * Input: + * port - port id + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_portEnable_get + * Description: + * Get PTP status of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_ptp_portTimestamp_get + * Description: + * Get PTP timstamp according to the PTP identifier on the dedicated port from the specified device. + * Input: + * unit - unit id + * port - port id + * type - PTP message type + * Output: + * pInfo - pointer buffer of sequence ID and timestamp + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo); + +/* Function Name: + * rtk_ptp_intControl_set + * Description: + * Set PTP interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set PTP interrupt status configuration. + * The interrupt trigger status is shown in the following: + * PTP_INT_TYPE_TX_SYNC = 0, + * PTP_INT_TYPE_TX_DELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_RESP, + * PTP_INT_TYPE_RX_SYNC, + * PTP_INT_TYPE_RX_DELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_RESP, + * PTP_INT_TYPE_ALL, + */ +extern rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_intControl_get + * Description: + * Get PTP interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * Output: + * pEnable - Interrupt status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt status configuration. + * The interrupt trigger status is shown in the following: + * PTP_INT_TYPE_TX_SYNC = 0, + * PTP_INT_TYPE_TX_DELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_RESP, + * PTP_INT_TYPE_RX_SYNC, + * PTP_INT_TYPE_RX_DELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_RESP, + */ +extern rtk_api_ret_t rtk_ptp_intControl_get(rtk_ptp_intType_t type, rtk_enable_t *pEnable); + + +/* Function Name: + * rtk_ptp_intStatus_get + * Description: + * Get PTP port interrupt trigger status. + * Input: + * port - physical port + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - PORT 0 INT (value[0] (Bit0)) + * - PORT 1 INT (value[0] (Bit1)) + * - PORT 2 INT (value[0] (Bit2)) + * - PORT 3 INT (value[0] (Bit3)) + * - PORT 4 INT (value[0] (Bit4)) + + * + */ +extern rtk_api_ret_t rtk_ptp_intStatus_get(rtk_ptp_intStatus_t *pStatusMask); + +/* Function Name: + * rtk_ptp_portIntStatus_set + * Description: + * Set PTP port interrupt trigger status to clean. + * Input: + * port - physical port + * statusMask - Interrupt status bit mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can clean interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0)) + * - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1)) + * - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2)) + * - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3)) + * - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4)) + * - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5)) + * - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6)) + * - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7)) + * The status will be cleared after execute this API. + */ +extern rtk_api_ret_t rtk_ptp_portIntStatus_set(rtk_port_t port, rtk_ptp_intStatus_t statusMask); + +/* Function Name: + * rtk_ptp_portIntStatus_get + * Description: + * Get PTP port interrupt trigger status. + * Input: + * port - physical port + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0)) + * - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1)) + * - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2)) + * - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3)) + * - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4)) + * - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5)) + * - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6)) + * - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7)) + * + */ +extern rtk_api_ret_t rtk_ptp_portIntStatus_get(rtk_port_t port, rtk_ptp_intStatus_t *pStatusMask); + +/* Function Name: + * rtk_ptp_portPtpTrap_set + * Description: + * Set PTP packet trap of the specified port. + * Input: + * port - port id + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portTrap_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_portPtpEnable_get + * Description: + * Get PTP packet trap of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portTrap_get(rtk_port_t port, rtk_enable_t *pEnable); + +#endif /* __RTK_API_PTP_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/qos.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/qos.h new file mode 100755 index 00000000..4be41748 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/qos.h @@ -0,0 +1,781 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes QoS module high-layer API defination + * + */ + +#ifndef __RTK_API_QOS_H__ +#define __RTK_API_QOS_H__ + +/* + * Data Type Declaration + */ +#define QOS_DEFAULT_TICK_PERIOD (19-1) +#define QOS_DEFAULT_BYTE_PER_TOKEN 34 +#define QOS_DEFAULT_LK_THRESHOLD (34*3) /* Why use 0x400? */ + + +#define QOS_DEFAULT_INGRESS_BANDWIDTH 0x3FFF /* 0x3FFF => unlimit */ +#define QOS_DEFAULT_EGRESS_BANDWIDTH 0x3D08 /*( 0x3D08 + 1) * 64Kbps => 1Gbps*/ +#define QOS_DEFAULT_PREIFP 1 +#define QOS_DEFAULT_PACKET_USED_PAGES_FC 0x60 +#define QOS_DEFAULT_PACKET_USED_FC_EN 0 +#define QOS_DEFAULT_QUEUE_BASED_FC_EN 1 + +#define QOS_DEFAULT_PRIORITY_SELECT_PORT 8 +#define QOS_DEFAULT_PRIORITY_SELECT_1Q 0 +#define QOS_DEFAULT_PRIORITY_SELECT_ACL 0 +#define QOS_DEFAULT_PRIORITY_SELECT_DSCP 0 + +#define QOS_DEFAULT_DSCP_MAPPING_PRIORITY 0 + +#define QOS_DEFAULT_1Q_REMARKING_ABILITY 0 +#define QOS_DEFAULT_DSCP_REMARKING_ABILITY 0 +#define QOS_DEFAULT_QUEUE_GAP 20 +#define QOS_DEFAULT_QUEUE_NO_MAX 6 +#define QOS_DEFAULT_AVERAGE_PACKET_RATE 0x3FFF +#define QOS_DEFAULT_BURST_SIZE_IN_APR 0x3F +#define QOS_DEFAULT_PEAK_PACKET_RATE 2 +#define QOS_DEFAULT_SCHEDULER_ABILITY_APR 1 /*disable*/ +#define QOS_DEFAULT_SCHEDULER_ABILITY_PPR 1 /*disable*/ +#define QOS_DEFAULT_SCHEDULER_ABILITY_WFQ 1 /*disable*/ + +#define QOS_WEIGHT_MAX 127 + +#define RTK_MAX_NUM_OF_PRIORITY 8 +#define RTK_MAX_NUM_OF_QUEUE 8 + +#define RTK_PRIMAX 7 +#define RTK_QIDMAX 7 +#define RTK_DSCPMAX 63 + + +/* enum Priority Selection Index */ +typedef enum rtk_qos_priDecTbl_e +{ + PRIDECTBL_IDX0 = 0, + PRIDECTBL_IDX1, + PRIDECTBL_END, +}rtk_qos_priDecTbl_t; + + +/* Types of 802.1p remarking source */ +typedef enum rtk_qos_1pRmkSrc_e +{ + DOT1P_RMK_SRC_USER_PRI, + DOT1P_RMK_SRC_TAG_PRI, + DOT1P_RMK_SRC_END +} rtk_qos_1pRmkSrc_t; + + +/* Types of DSCP remarking source */ +typedef enum rtk_qos_dscpRmkSrc_e +{ + DSCP_RMK_SRC_INT_PRI, + DSCP_RMK_SRC_DSCP, + DSCP_RMK_SRC_USER_PRI, + DSCP_RMK_SRC_END +} rtk_qos_dscpRmkSrc_t; + + + + +typedef struct rtk_priority_select_s +{ + rtk_uint32 port_pri; + rtk_uint32 dot1q_pri; + rtk_uint32 acl_pri; + rtk_uint32 dscp_pri; + rtk_uint32 cvlan_pri; + rtk_uint32 svlan_pri; + rtk_uint32 dmac_pri; + rtk_uint32 smac_pri; +} rtk_priority_select_t; + +typedef struct rtk_qos_pri2queue_s +{ + rtk_uint32 pri2queue[RTK_MAX_NUM_OF_PRIORITY]; +} rtk_qos_pri2queue_t; + +typedef struct rtk_qos_queue_weights_s +{ + rtk_uint32 weights[RTK_MAX_NUM_OF_QUEUE]; +} rtk_qos_queue_weights_t; + +typedef enum rtk_qos_scheduling_type_e +{ + WFQ = 0, /* Weighted-Fair-Queue */ + WRR, /* Weighted-Round-Robin */ + SCHEDULING_TYPE_END +} rtk_qos_scheduling_type_t; + +typedef rtk_uint32 rtk_queue_num_t; /* queue number*/ + +/* Function Name: + * rtk_qos_init + * Description: + * Configure Qos default settings with queue number assigment to each port. + * Input: + * queueNum - Queue number of each port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API will initialize related Qos setting with queue number assigment. + * The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum); + +/* Function Name: + * rtk_qos_priSel_set + * Description: + * Configure the priority order among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter. + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT + * - PRIDEC_ACL + * - PRIDEC_DSCP + * - PRIDEC_1Q + * - PRIDEC_1AD + * - PRIDEC_CVLAN + * - PRIDEC_DA + * - PRIDEC_SA + */ +extern rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec); + + +/* Function Name: + * rtk_qos_priSel_get + * Description: + * Get the priority order configuration among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * Output: + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision . + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT, + * - PRIDEC_ACL, + * - PRIDEC_DSCP, + * - PRIDEC_1Q, + * - PRIDEC_1AD, + * - PRIDEC_CVLAN, + * - PRIDEC_DA, + * - PRIDEC_SA, + */ +extern rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec); + +/* Function Name: + * rtk_qos_1pPriRemap_set + * Description: + * Configure 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri); + +/* Function Name: + * rtk_qos_1pPriRemap_get + * Description: + * Get 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value . + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assigment for internal asic priority, and it is uesed for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri); + + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_set + * Description: + * Set remarking source of 802.1p remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure 802.1p remark functionality to map original 802.1p value or internal + * priority to TX DSCP value. + */ +extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type); + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_get + * Description: + * Get remarking source of 802.1p remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType); + +/* Function Name: + * rtk_qos_dscpPriRemap_set + * Description: + * Map dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * int_pri - internal priority value . + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +extern rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri); + +/* Function Name: + * rtk_qos_dscpPriRemap_get + * Description: + * Get dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +extern rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri); + +/* Function Name: + * rtk_qos_portPri_set + * Description: + * Configure priority usage to each port. + * Input: + * port - Port id. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_SEL_PORT_PRI - Invalid port priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) ; + +/* Function Name: + * rtk_qos_portPri_get + * Description: + * Get priority usage to each port. + * Input: + * port - Port id. + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) ; + +/* Function Name: + * rtk_qos_queueNum_set + * Description: + * Set output queue number for each port. + * Input: + * port - Port id. + * index - Mapping queue number (1~8) + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can set the output queue number of the specified port. The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num); + +/* Function Name: + * rtk_qos_queueNum_get + * Description: + * Get output queue number. + * Input: + * port - Port id. + * Output: + * pQueue_num - Mapping queue number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API will return the output queue number of the specified port. The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num); + +/* Function Name: + * rtk_qos_priMap_set + * Description: + * Set output queue number for each port. + * Input: + * queue_num - Queue number usage. + * pPri2qid - Priority mapping to queue ID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_QUEUE_ID - Invalid queue id. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * ASIC supports priority mapping to queue with different queue number from 1 to 8. + * For different queue numbers usage, ASIC supports different internal available queue IDs. + */ +extern rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid); + + +/* Function Name: + * rtk_qos_priMap_get + * Description: + * Get priority to queue ID mapping table parameters. + * Input: + * queue_num - Queue number usage. + * Output: + * pPri2qid - Priority mapping to queue ID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can return the mapping queue id of the specified priority and queue number. + * The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid); + +/* Function Name: + * rtk_qos_schedulingQueue_set + * Description: + * Set weight and type of queues in dedicated port. + * Input: + * port - Port id. + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight. + * Note: + * The API can set weight and type, strict priority or weight fair queue (WFQ) for + * dedicated port for using queues. If queue id is not included in queue usage, + * then its type and weight setting in dummy for setting. There are priorities + * as queue id in strict queues. It means strict queue id 5 carrying higher priority + * than strict queue id 4. The WFQ queue weight is from 1 to 128, and weight 0 is + * for strict priority queue type. + */ +extern rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights); + +/* Function Name: + * rtk_qos_schedulingQueue_get + * Description: + * Get weight and type of queues in dedicated port. + * Input: + * port - Port id. + * Output: + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get weight and type, strict priority or weight fair queue (WFQ) for dedicated port for using queues. + * The WFQ queue weight is from 1 to 128, and weight 0 is for strict priority queue type. + */ +extern rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights); + +/* Function Name: + * rtk_qos_1pRemarkEnable_set + * Description: + * Set 1p Remarking state + * Input: + * port - Port id. + * enable - State of per-port 1p Remarking + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable 802.1p remarking ability for whole system. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_1pRemarkEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_qos_1pRemarkEnable_get + * Description: + * Get 802.1p remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - Status of 802.1p remark. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1p remarking ability. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_1pRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_qos_1pRemark_set + * Description: + * Set 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * dot1p_pri - 802.1p priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set 802.1p parameters source priority and new priority. + */ +extern rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri); + +/* Function Name: + * rtk_qos_1pRemark_get + * Description: + * Get 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * pDot1p_pri - 802.1p priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get 802.1p remarking parameters. It would return new priority of ingress priority. + */ +extern rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri); + +/* Function Name: + * rtk_qos_dscpRemarkEnable_set + * Description: + * Set DSCP remarking ability. + * Input: + * port - Port id. + * enable - status of DSCP remark. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable DSCP remarking ability for whole system. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_qos_dscpRemarkEnable_get + * Description: + * Get DSCP remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - status of DSCP remarking. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get DSCP remarking ability. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_qos_dscpRemark_set + * Description: + * Set DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * dscp - DSCP value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The API can set DSCP value and mapping priority. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp); + +/* Function Name: + * rtk_qos_dscpRemark_get + * Description: + * Get DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * Dscp - DSCP value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get DSCP parameters. It would return DSCP value for mapping priority. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp); + +/* Function Name: + * rtk_qos_dscpRemarkSrcSel_set + * Description: + * Set remarking source of DSCP remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure DSCP remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type); + + +/* Function Name: + * rtk_qos_dcpRemarkSrcSel_get + * Description: + * Get remarking source of DSCP remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType); + + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_set + * Description: + * Set DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * rmkDscp - remarked DSCP value + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * Note: + * dscp parameter can be DSCP value or internal priority according to configuration of API + * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP + * value or internal priority to TX DSCP value. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp); + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_get + * Description: + * Get DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * Output: + * pDscp - remarked DSCP value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp); + +/* Function Name: + * rtk_qos_portPriSelIndex_set + * Description: + * Configure priority decision index to each port. + * Input: + * port - Port id. + * index - priority decision index. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENTRY_INDEX - Invalid entry index. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index); + +/* Function Name: + * rtk_qos_portPriSelIndex_get + * Description: + * Get priority decision index from each port. + * Input: + * port - Port id. + * Output: + * pIndex - priority decision index. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex); + +#endif /* __RTK_API_QOS_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rate.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rate.h new file mode 100755 index 00000000..231ed01b --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rate.h @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes rate module high-layer API defination + * + */ + +#ifndef __RTK_API_RATE_H__ +#define __RTK_API_RATE_H__ + +/* + * Include Files + */ +//#include + +/* + * Data Type Declaration + */ +#define RTK_MAX_METER_ID (rtk_switch_maxMeterId_get()) +#define RTK_METER_NUM (RTK_MAX_METER_ID + 1) + +typedef enum rtk_meter_type_e{ + METER_TYPE_KBPS = 0, /* Kbps */ + METER_TYPE_PPS, /* Packet per second */ + METER_TYPE_END +}rtk_meter_type_t; + + +/* + * Function Declaration + */ + + /* Rate */ +/* Function Name: + * rtk_rate_shareMeter_set + * Description: + * Set meter configuration + * Input: + * index - shared meter index + * type - shared meter type + * rate - rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_RATE - Invalid rate + * RT_ERR_INPUT - Invalid input parameters + * Note: + * The API can set shared meter rate and ifg include for each meter. + * The rate unit is 1 kbps and the range is from 8k to 1048568k if type is METER_TYPE_KBPS and + * the granularity of rate is 8 kbps. + * The rate unit is packets per second and the range is 1 ~ 0x1FFF if type is METER_TYPE_PPS. + * The ifg_include parameter is used + * for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_shareMeter_set(rtk_meter_id_t index, rtk_meter_type_t type, rtk_rate_t rate, rtk_enable_t ifg_include); + +/* Function Name: + * rtk_rate_shareMeter_get + * Description: + * Get meter configuration + * Input: + * index - shared meter index + * Output: + * pType - Meter Type + * pRate - pointer of rate of share meter + * pIfg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_shareMeter_get(rtk_meter_id_t index, rtk_meter_type_t *pType, rtk_rate_t *pRate, rtk_enable_t *pIfg_include); + +/* Function Name: + * rtk_rate_shareMeterBucket_set + * Description: + * Set meter Bucket Size + * Input: + * index - shared meter index + * bucket_size - Bucket Size + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Error Input + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can set shared meter bucket size. + */ +extern rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size); + +/* Function Name: + * rtk_rate_shareMeterBucket_get + * Description: + * Get meter Bucket Size + * Input: + * index - shared meter index + * Output: + * pBucket_size - Bucket Size + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can get shared meter bucket size. + */ +extern rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size); + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_set + * Description: + * Set port ingress bandwidth control + * Input: + * port - Port id + * rate - Rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * fc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid IFG parameter. + * RT_ERR_INBW_RATE - Invalid ingress rate parameter. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include, rtk_enable_t fc_enable); + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_get + * Description: + * Get port ingress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of share meter + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * pFc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include, rtk_enable_t *pFc_enable); + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_set + * Description: + * Set port egress bandwidth control + * Input: + * port - Port id + * rate - Rate of egress bandwidth + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_EBW_RATE - Invalid egress bandwidth/rate + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set(rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_includ); + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_get + * Description: + * Get port egress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of egress bandwidth + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlEnable_set + * Description: + * Set enable status of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * enable - enable status of egress queue bandwidth control + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_get + * Description: + * Get rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * pIndex - shared meter index + * Output: + * pRate - pointer to rate of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * None. + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_set + * Description: + * Set rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * index - shared meter index + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_get + * Description: + * Get rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * pIndex - shared meter index + * Output: + * pRate - pointer to rate of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex); + +#endif /* __RTK_API_RATE_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rldp.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rldp.h new file mode 100755 index 00000000..111de0c0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rldp.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : Declaration of RLDP and RLPP API + * + * Feature : The file have include the following module and sub-modules + * 1) RLDP and RLPP configuration and status + * + */ + + +#ifndef __RTK_RLDP_H__ +#define __RTK_RLDP_H__ + + +/* + * Include Files + */ + + +/* + * Symbol Definition + */ +typedef enum rtk_rldp_trigger_e +{ + RTK_RLDP_TRIGGER_SAMOVING = 0, + RTK_RLDP_TRIGGER_PERIOD, + RTK_RLDP_TRIGGER_END +} rtk_rldp_trigger_t; + +typedef enum rtk_rldp_cmpType_e +{ + RTK_RLDP_CMPTYPE_MAGIC = 0, /* Compare the RLDP with magic only */ + RTK_RLDP_CMPTYPE_MAGIC_ID, /* Compare the RLDP with both magic + ID */ + RTK_RLDP_CMPTYPE_END +} rtk_rldp_cmpType_t; + +typedef enum rtk_rldp_loopStatus_e +{ + RTK_RLDP_LOOPSTS_NONE = 0, + RTK_RLDP_LOOPSTS_LOOPING, + RTK_RLDP_LOOPSTS_END +} rtk_rldp_loopStatus_t; + +typedef enum rtk_rlpp_trapType_e +{ + RTK_RLPP_TRAPTYPE_NONE = 0, + RTK_RLPP_TRAPTYPE_CPU, + RTK_RLPP_TRAPTYPE_END +} rtk_rlpp_trapType_t; + +typedef struct rtk_rldp_config_s +{ + rtk_enable_t rldp_enable; + rtk_rldp_trigger_t trigger_mode; + rtk_mac_t magic; + rtk_rldp_cmpType_t compare_type; + rtk_uint32 interval_check; /* Checking interval for check state */ + rtk_uint32 num_check; /* Checking number for check state */ + rtk_uint32 interval_loop; /* Checking interval for loop state */ + rtk_uint32 num_loop; /* Checking number for loop state */ +} rtk_rldp_config_t; + +typedef struct rtk_rldp_portConfig_s +{ + rtk_enable_t tx_enable; +} rtk_rldp_portConfig_t; + +typedef struct rtk_rldp_status_s +{ + rtk_mac_t id; +} rtk_rldp_status_t; + +typedef struct rtk_rldp_portStatus_s +{ + rtk_rldp_loopStatus_t loop_status; + rtk_rldp_loopStatus_t loop_enter; + rtk_rldp_loopStatus_t loop_leave; +} rtk_rldp_portStatus_t; + +/* + * Data Declaration + */ + + +/* + * Macro Declaration + */ + +#define RTK_RLDP_INTERVAL_MAX 0xffff +#define RTK_RLDP_NUM_MAX 0xff + + +/* + * Function Declaration + */ + +/* Module Name : RLDP */ + + +/* Function Name: + * rtk_rldp_config_set + * Description: + * Set RLDP module configuration + * Input: + * pConfig - configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig); + + +/* Function Name: + * rtk_rldp_config_get + * Description: + * Get RLDP module configuration + * Input: + * None + * Output: + * pConfig - configuration structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig); + + +/* Function Name: + * rtk_rldp_portConfig_set + * Description: + * Set per port RLDP module configuration + * Input: + * port - port number to be configured + * pPortConfig - per port configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig); + + +/* Function Name: + * rtk_rldp_portConfig_get + * Description: + * Get per port RLDP module configuration + * Input: + * port - port number to be get + * Output: + * pPortConfig - per port configuration structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portConfig_get(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig); + + +/* Function Name: + * rtk_rldp_status_get + * Description: + * Get RLDP module status + * Input: + * None + * Output: + * pStatus - status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus); + + +/* Function Name: + * rtk_rldp_portStatus_get + * Description: + * Get RLDP module status + * Input: + * port - port number to be get + * Output: + * pPortStatus - per port status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus); + + +/* Function Name: + * rtk_rldp_portStatus_clear + * Description: + * Clear RLDP module status + * Input: + * port - port number to be clear + * pPortStatus - per port status structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * Clear operation effect loop_enter and loop_leave only, other field in + * the structure are don't care + */ +extern rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus); + + +/* Function Name: + * rtk_rldp_portLoopPair_get + * Description: + * Get RLDP port loop pairs + * Input: + * port - port number to be get + * Output: + * pPortmask - per port related loop ports + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portLoopPair_get(rtk_port_t port, rtk_portmask_t *pPortmask); + +#endif /* __RTK_RLDP_H__ */ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h new file mode 100755 index 00000000..dc9c0bed --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : Definition the error number in the SDK. + * Feature : error definition + * + */ + +#ifndef __COMMON_RT_ERROR_H__ +#define __COMMON_RT_ERROR_H__ + +/* + * Include Files + */ + +/* + * Data Type Declaration + */ +typedef enum rt_error_code_e +{ + RT_ERR_FAILED = -1, /* General Error */ + + /* 0x0000xxxx for common error code */ + RT_ERR_OK = 0, /* 0x00000000, OK */ + RT_ERR_INPUT, /* 0x00000001, invalid input parameter */ + RT_ERR_UNIT_ID, /* 0x00000002, invalid unit id */ + RT_ERR_PORT_ID, /* 0x00000003, invalid port id */ + RT_ERR_PORT_MASK, /* 0x00000004, invalid port mask */ + RT_ERR_PORT_LINKDOWN, /* 0x00000005, link down port status */ + RT_ERR_ENTRY_INDEX, /* 0x00000006, invalid entry index */ + RT_ERR_NULL_POINTER, /* 0x00000007, input parameter is null pointer */ + RT_ERR_QUEUE_ID, /* 0x00000008, invalid queue id */ + RT_ERR_QUEUE_NUM, /* 0x00000009, invalid queue number */ + RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000000a, busy watting time out */ + RT_ERR_MAC, /* 0x0000000b, invalid mac address */ + RT_ERR_OUT_OF_RANGE, /* 0x0000000c, input parameter out of range */ + RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000000d, functions not supported by this chip model */ + RT_ERR_SMI, /* 0x0000000e, SMI error */ + RT_ERR_NOT_INIT, /* 0x0000000f, The module is not initial */ + RT_ERR_CHIP_NOT_FOUND, /* 0x00000010, The chip can not found */ + RT_ERR_NOT_ALLOWED, /* 0x00000011, actions not allowed by the function */ + RT_ERR_DRIVER_NOT_FOUND, /* 0x00000012, The driver can not found */ + RT_ERR_SEM_LOCK_FAILED, /* 0x00000013, Failed to lock semaphore */ + RT_ERR_SEM_UNLOCK_FAILED, /* 0x00000014, Failed to unlock semaphore */ + RT_ERR_ENABLE, /* 0x00000015, invalid enable parameter */ + RT_ERR_TBL_FULL, /* 0x00000016, input table full */ + + /* 0x0001xxxx for vlan */ + RT_ERR_VLAN_VID = 0x00010000, /* 0x00010000, invalid vid */ + RT_ERR_VLAN_PRIORITY, /* 0x00010001, invalid 1p priority */ + RT_ERR_VLAN_EMPTY_ENTRY, /* 0x00010002, emtpy entry of vlan table */ + RT_ERR_VLAN_ACCEPT_FRAME_TYPE, /* 0x00010003, invalid accept frame type */ + RT_ERR_VLAN_EXIST, /* 0x00010004, vlan is exist */ + RT_ERR_VLAN_ENTRY_NOT_FOUND, /* 0x00010005, specified vlan entry not found */ + RT_ERR_VLAN_PORT_MBR_EXIST, /* 0x00010006, member port exist in the specified vlan */ + RT_ERR_VLAN_PROTO_AND_PORT, /* 0x00010008, invalid protocol and port based vlan */ + + /* 0x0002xxxx for svlan */ + RT_ERR_SVLAN_ENTRY_INDEX = 0x00020000, /* 0x00020000, invalid svid entry no */ + RT_ERR_SVLAN_ETHER_TYPE, /* 0x00020001, invalid SVLAN ether type */ + RT_ERR_SVLAN_TABLE_FULL, /* 0x00020002, no empty entry in SVLAN table */ + RT_ERR_SVLAN_ENTRY_NOT_FOUND, /* 0x00020003, specified svlan entry not found */ + RT_ERR_SVLAN_EXIST, /* 0x00020004, SVLAN entry is exist */ + RT_ERR_SVLAN_VID, /* 0x00020005, invalid svid */ + + /* 0x0003xxxx for MSTP */ + RT_ERR_MSTI = 0x00030000, /* 0x00030000, invalid msti */ + RT_ERR_MSTP_STATE, /* 0x00030001, invalid spanning tree status */ + RT_ERR_MSTI_EXIST, /* 0x00030002, MSTI exist */ + RT_ERR_MSTI_NOT_EXIST, /* 0x00030003, MSTI not exist */ + + /* 0x0004xxxx for BUCKET */ + RT_ERR_TIMESLOT = 0x00040000, /* 0x00040000, invalid time slot */ + RT_ERR_TOKEN, /* 0x00040001, invalid token amount */ + RT_ERR_RATE, /* 0x00040002, invalid rate */ + RT_ERR_TICK, /* 0x00040003, invalid tick */ + + /* 0x0005xxxx for RMA */ + RT_ERR_RMA_ADDR = 0x00050000, /* 0x00050000, invalid rma mac address */ + RT_ERR_RMA_ACTION, /* 0x00050001, invalid rma action */ + + /* 0x0006xxxx for L2 */ + RT_ERR_L2_HASH_KEY = 0x00060000, /* 0x00060000, invalid L2 Hash key */ + RT_ERR_L2_HASH_INDEX, /* 0x00060001, invalid L2 Hash index */ + RT_ERR_L2_CAM_INDEX, /* 0x00060002, invalid L2 CAM index */ + RT_ERR_L2_ENRTYSEL, /* 0x00060003, invalid EntrySel */ + RT_ERR_L2_INDEXTABLE_INDEX, /* 0x00060004, invalid L2 index table(=portMask table) index */ + RT_ERR_LIMITED_L2ENTRY_NUM, /* 0x00060005, invalid limited L2 entry number */ + RT_ERR_L2_AGGREG_PORT, /* 0x00060006, this aggregated port is not the lowest physical + port of its aggregation group */ + RT_ERR_L2_FID, /* 0x00060007, invalid fid */ + RT_ERR_L2_VID, /* 0x00060008, invalid cvid */ + RT_ERR_L2_NO_EMPTY_ENTRY, /* 0x00060009, no empty entry in L2 table */ + RT_ERR_L2_ENTRY_NOTFOUND, /* 0x0006000a, specified entry not found */ + RT_ERR_L2_INDEXTBL_FULL, /* 0x0006000b, the L2 index table is full */ + RT_ERR_L2_INVALID_FLOWTYPE, /* 0x0006000c, invalid L2 flow type */ + RT_ERR_L2_L2UNI_PARAM, /* 0x0006000d, invalid L2 unicast parameter */ + RT_ERR_L2_L2MULTI_PARAM, /* 0x0006000e, invalid L2 multicast parameter */ + RT_ERR_L2_IPMULTI_PARAM, /* 0x0006000f, invalid L2 ip multicast parameter */ + RT_ERR_L2_PARTIAL_HASH_KEY, /* 0x00060010, invalid L2 partial Hash key */ + RT_ERR_L2_EMPTY_ENTRY, /* 0x00060011, the entry is empty(invalid) */ + RT_ERR_L2_FLUSH_TYPE, /* 0x00060012, the flush type is invalid */ + RT_ERR_L2_NO_CPU_PORT, /* 0x00060013, CPU port not exist */ + + /* 0x0007xxxx for FILTER (PIE) */ + RT_ERR_FILTER_BLOCKNUM = 0x00070000, /* 0x00070000, invalid block number */ + RT_ERR_FILTER_ENTRYIDX, /* 0x00070001, invalid entry index */ + RT_ERR_FILTER_CUTLINE, /* 0x00070002, invalid cutline value */ + RT_ERR_FILTER_FLOWTBLBLOCK, /* 0x00070003, block belongs to flow table */ + RT_ERR_FILTER_INACLBLOCK, /* 0x00070004, block belongs to ingress ACL */ + RT_ERR_FILTER_ACTION, /* 0x00070005, action doesn't consist to entry type */ + RT_ERR_FILTER_INACL_RULENUM, /* 0x00070006, invalid ACL rulenum */ + RT_ERR_FILTER_INACL_TYPE, /* 0x00070007, entry type isn't an ingress ACL rule */ + RT_ERR_FILTER_INACL_EXIST, /* 0x00070008, ACL entry is already exit */ + RT_ERR_FILTER_INACL_EMPTY, /* 0x00070009, ACL entry is empty */ + RT_ERR_FILTER_FLOWTBL_TYPE, /* 0x0007000a, entry type isn't an flow table rule */ + RT_ERR_FILTER_FLOWTBL_RULENUM, /* 0x0007000b, invalid flow table rulenum */ + RT_ERR_FILTER_FLOWTBL_EMPTY, /* 0x0007000c, flow table entry is empty */ + RT_ERR_FILTER_FLOWTBL_EXIST, /* 0x0007000d, flow table entry is already exist */ + RT_ERR_FILTER_METER_ID, /* 0x0007000e, invalid metering id */ + RT_ERR_FILTER_LOG_ID, /* 0x0007000f, invalid log id */ + RT_ERR_FILTER_INACL_NONE_BEGIN_IDX, /* 0x00070010, entry index is not starting index of a group of rules */ + RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT, /* 0x00070011, action not support */ + RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT, /* 0x00070012, rule not support */ + + /* 0x0008xxxx for ACL Rate Limit */ + RT_ERR_ACLRL_HTHR = 0x00080000, /* 0x00080000, invalid high threshold */ + RT_ERR_ACLRL_TIMESLOT, /* 0x00080001, invalid time slot */ + RT_ERR_ACLRL_TOKEN, /* 0x00080002, invalid token amount */ + RT_ERR_ACLRL_RATE, /* 0x00080003, invalid rate */ + + /* 0x0009xxxx for Link aggregation */ + RT_ERR_LA_CPUPORT = 0x00090000, /* 0x00090000, CPU port can not be aggregated port */ + RT_ERR_LA_TRUNK_ID, /* 0x00090001, invalid trunk id */ + RT_ERR_LA_PORTMASK, /* 0x00090002, invalid port mask */ + RT_ERR_LA_HASHMASK, /* 0x00090003, invalid hash mask */ + RT_ERR_LA_DUMB, /* 0x00090004, this API should be used in 802.1ad dumb mode */ + RT_ERR_LA_PORTNUM_DUMB, /* 0x00090005, it can only aggregate at most four ports when 802.1ad dumb mode */ + RT_ERR_LA_PORTNUM_NORMAL, /* 0x00090006, it can only aggregate at most eight ports when 802.1ad normal mode */ + RT_ERR_LA_MEMBER_OVERLAP, /* 0x00090007, the specified port mask is overlapped with other group */ + RT_ERR_LA_NOT_MEMBER_PORT, /* 0x00090008, the port is not a member port of the trunk */ + RT_ERR_LA_TRUNK_NOT_EXIST, /* 0x00090009, the trunk doesn't exist */ + + + /* 0x000axxxx for storm filter */ + RT_ERR_SFC_TICK_PERIOD = 0x000a0000, /* 0x000a0000, invalid SFC tick period */ + RT_ERR_SFC_UNKNOWN_GROUP, /* 0x000a0001, Unknown Storm filter group */ + + /* 0x000bxxxx for pattern match */ + RT_ERR_PM_MASK = 0x000b0000, /* 0x000b0000, invalid pattern length. Pattern length should be 8 */ + RT_ERR_PM_LENGTH, /* 0x000b0001, invalid pattern match mask, first byte must care */ + RT_ERR_PM_MODE, /* 0x000b0002, invalid pattern match mode */ + + /* 0x000cxxxx for input bandwidth control */ + RT_ERR_INBW_TICK_PERIOD = 0x000c0000, /* 0x000c0000, invalid tick period for input bandwidth control */ + RT_ERR_INBW_TOKEN_AMOUNT, /* 0x000c0001, invalid amount of token for input bandwidth control */ + RT_ERR_INBW_FCON_VALUE, /* 0x000c0002, invalid flow control ON threshold value for input bandwidth control */ + RT_ERR_INBW_FCOFF_VALUE, /* 0x000c0003, invalid flow control OFF threshold value for input bandwidth control */ + RT_ERR_INBW_FC_ALLOWANCE, /* 0x000c0004, invalid allowance of incomming packet for input bandwidth control */ + RT_ERR_INBW_RATE, /* 0x000c0005, invalid input bandwidth */ + + /* 0x000dxxxx for QoS */ + RT_ERR_QOS_1P_PRIORITY = 0x000d0000, /* 0x000d0000, invalid 802.1P priority */ + RT_ERR_QOS_DSCP_VALUE, /* 0x000d0001, invalid DSCP value */ + RT_ERR_QOS_INT_PRIORITY, /* 0x000d0002, invalid internal priority */ + RT_ERR_QOS_SEL_DSCP_PRI, /* 0x000d0003, invalid DSCP selection priority */ + RT_ERR_QOS_SEL_PORT_PRI, /* 0x000d0004, invalid port selection priority */ + RT_ERR_QOS_SEL_IN_ACL_PRI, /* 0x000d0005, invalid ingress ACL selection priority */ + RT_ERR_QOS_SEL_CLASS_PRI, /* 0x000d0006, invalid classifier selection priority */ + RT_ERR_QOS_EBW_RATE, /* 0x000d0007, invalid egress bandwidth rate */ + RT_ERR_QOS_SCHE_TYPE, /* 0x000d0008, invalid QoS scheduling type */ + RT_ERR_QOS_QUEUE_WEIGHT, /* 0x000d0009, invalid Queue weight */ + RT_ERR_QOS_SEL_PRI_SOURCE, /* 0x000d000a, invalid selection of priority source */ + + /* 0x000exxxx for port ability */ + RT_ERR_PHY_PAGE_ID = 0x000e0000, /* 0x000e0000, invalid PHY page id */ + RT_ERR_PHY_REG_ID, /* 0x000e0001, invalid PHY reg id */ + RT_ERR_PHY_DATAMASK, /* 0x000e0002, invalid PHY data mask */ + RT_ERR_PHY_AUTO_NEGO_MODE, /* 0x000e0003, invalid PHY auto-negotiation mode*/ + RT_ERR_PHY_SPEED, /* 0x000e0004, invalid PHY speed setting */ + RT_ERR_PHY_DUPLEX, /* 0x000e0005, invalid PHY duplex setting */ + RT_ERR_PHY_FORCE_ABILITY, /* 0x000e0006, invalid PHY force mode ability parameter */ + RT_ERR_PHY_FORCE_1000, /* 0x000e0007, invalid PHY force mode 1G speed setting */ + RT_ERR_PHY_TXRX, /* 0x000e0008, invalid PHY tx/rx */ + RT_ERR_PHY_ID, /* 0x000e0009, invalid PHY id */ + RT_ERR_PHY_RTCT_NOT_FINISH, /* 0x000e000a, PHY RTCT in progress */ + + /* 0x000fxxxx for mirror */ + RT_ERR_MIRROR_DIRECTION = 0x000f0000, /* 0x000f0000, invalid error mirror direction */ + RT_ERR_MIRROR_SESSION_FULL, /* 0x000f0001, mirroring session is full */ + RT_ERR_MIRROR_SESSION_NOEXIST, /* 0x000f0002, mirroring session not exist */ + RT_ERR_MIRROR_PORT_EXIST, /* 0x000f0003, mirroring port already exists */ + RT_ERR_MIRROR_PORT_NOT_EXIST, /* 0x000f0004, mirroring port does not exists */ + RT_ERR_MIRROR_PORT_FULL, /* 0x000f0005, Exceeds maximum number of supported mirroring port */ + + /* 0x0010xxxx for stat */ + RT_ERR_STAT_INVALID_GLOBAL_CNTR = 0x00100000, /* 0x00100000, Invalid Global Counter */ + RT_ERR_STAT_INVALID_PORT_CNTR, /* 0x00100001, Invalid Port Counter */ + RT_ERR_STAT_GLOBAL_CNTR_FAIL, /* 0x00100002, Could not retrieve/reset Global Counter */ + RT_ERR_STAT_PORT_CNTR_FAIL, /* 0x00100003, Could not retrieve/reset Port Counter */ + RT_ERR_STAT_INVALID_CNTR, /* 0x00100004, Invalid Counter */ + RT_ERR_STAT_CNTR_FAIL, /* 0x00100005, Could not retrieve/reset Counter */ + + /* 0x0011xxxx for dot1x */ + RT_ERR_DOT1X_INVALID_DIRECTION = 0x00110000, /* 0x00110000, Invalid Authentication Direction */ + RT_ERR_DOT1X_PORTBASEDPNEN, /* 0x00110001, Port-based enable port error */ + RT_ERR_DOT1X_PORTBASEDAUTH, /* 0x00110002, Port-based auth port error */ + RT_ERR_DOT1X_PORTBASEDOPDIR, /* 0x00110003, Port-based opdir error */ + RT_ERR_DOT1X_MACBASEDPNEN, /* 0x00110004, MAC-based enable port error */ + RT_ERR_DOT1X_MACBASEDOPDIR, /* 0x00110005, MAC-based opdir error */ + RT_ERR_DOT1X_PROC, /* 0x00110006, unauthorized behavior error */ + RT_ERR_DOT1X_GVLANIDX, /* 0x00110007, guest vlan index error */ + RT_ERR_DOT1X_GVLANTALK, /* 0x00110008, guest vlan OPDIR error */ + RT_ERR_DOT1X_MAC_PORT_MISMATCH, /* 0x00110009, Auth MAC and port mismatch eror */ + + RT_ERR_END /* The symbol is the latest symbol */ +} rt_error_code_t; + + +#endif /* __COMMON_RT_ERROR_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h new file mode 100755 index 00000000..6ddb23f2 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h @@ -0,0 +1,44 @@ +#ifndef __RTK_HAL_H__ +#define __RTK_HAL_H__ +#include "ra_ioctl.h" + +#define RTK_SW_VID_RANGE 16 +void rtk_hal_switch_init(void); +void rtk_hal_dump_mib(void); +void rtk_hal_dump_full_mib(void); +int rtk_hal_dump_vlan(void); +void rtk_hal_clear_vlan(void); +int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data); +int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data); +int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data); +void rtk_hal_dump_table(void); +void rtk_hal_clear_table(void); +void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data); +void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data); +void rtk_hal_read_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_write_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_en(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data); +void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data); +void rtk_hal_disable_igmpsnoop(void); +void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data); +void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data); +void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority); +void rtk_hal_add_table(struct ra_switch_ioctl_data *data); +void rtk_hal_del_table(struct ra_switch_ioctl_data *data); +void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data); +void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data); +#endif diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h new file mode 100755 index 00000000..b0ca1368 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h @@ -0,0 +1,737 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76336 $ + * $Date: 2017-03-09 10:41:21 +0800 (週四, 09 三月 2017) $ + * + * Purpose : RTK switch high-level API + * Feature : Here is a list of all functions and variables in this module. + * + */ + +#ifndef __RTK_SWITCH_H__ +#define __RTK_SWITCH_H__ + +#include + +#define UNDEFINE_PHY_PORT (0xFF) +#define RTK_SWITCH_PORT_NUM (32) + +#define MAXPKTLEN_CFG_ID_MAX (1) + +#define RTK_SWITCH_MAX_PKTLEN (0x3FFF) + +typedef enum init_state_e +{ + INIT_NOT_COMPLETED = 0, + INIT_COMPLETED, + INIT_STATE_END +} init_state_t; + +typedef enum switch_chip_e +{ + CHIP_RTL8367C = 0, + CHIP_RTL8370B, + CHIP_RTL8364B, + CHIP_RTL8363SC_VB, + CHIP_END +}switch_chip_t; + +typedef enum port_type_e +{ + UTP_PORT = 0, + EXT_PORT, + UNKNOWN_PORT = 0xFF, + PORT_TYPE_END +}port_type_t; + +typedef struct rtk_switch_halCtrl_s +{ + switch_chip_t switch_type; + rtk_uint32 l2p_port[RTK_SWITCH_PORT_NUM]; + rtk_uint32 p2l_port[RTK_SWITCH_PORT_NUM]; + port_type_t log_port_type[RTK_SWITCH_PORT_NUM]; + rtk_uint32 ptp_port[RTK_SWITCH_PORT_NUM]; + rtk_uint32 valid_portmask; + rtk_uint32 valid_utp_portmask; + rtk_uint32 valid_ext_portmask; + rtk_uint32 valid_cpu_portmask; + rtk_uint32 min_phy_port; + rtk_uint32 max_phy_port; + rtk_uint32 phy_portmask; + rtk_uint32 combo_logical_port; + rtk_uint32 hsg_logical_port; + rtk_uint32 sg_logical_portmask; + rtk_uint32 max_meter_id; + rtk_uint32 max_lut_addr_num; + rtk_uint32 trunk_group_mask; + +}rtk_switch_halCtrl_t; + +typedef enum rtk_switch_maxPktLen_linkSpeed_e { + MAXPKTLEN_LINK_SPEED_FE = 0, + MAXPKTLEN_LINK_SPEED_GE, + MAXPKTLEN_LINK_SPEED_END, +} rtk_switch_maxPktLen_linkSpeed_t; + + +/* UTIL MACRO */ +#define RTK_CHK_INIT_STATE() \ + do \ + { \ + if(rtk_switch_initialState_get() != INIT_COMPLETED) \ + { \ + return RT_ERR_NOT_INIT; \ + } \ + }while(0) + +#define RTK_CHK_PORT_VALID(__port__) \ + do \ + { \ + if(rtk_switch_logicalPortCheck(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_UTP(__port__) \ + do \ + { \ + if(rtk_switch_isUtpPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_EXT(__port__) \ + do \ + { \ + if(rtk_switch_isExtPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_COMBO(__port__) \ + do \ + { \ + if(rtk_switch_isComboPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_PTP(__port__) \ + do \ + { \ + if(rtk_switch_isPtpPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORTMASK_VALID(__portmask__) \ + do \ + { \ + if(rtk_switch_isPortMaskValid(__portmask__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_MASK; \ + } \ + }while(0) + +#define RTK_CHK_PORTMASK_VALID_ONLY_UTP(__portmask__) \ + do \ + { \ + if(rtk_switch_isPortMaskUtp(__portmask__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_MASK; \ + } \ + }while(0) + +#define RTK_CHK_PORTMASK_VALID_ONLY_EXT(__portmask__) \ + do \ + { \ + if(rtk_switch_isPortMaskExt(__portmask__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_MASK; \ + } \ + }while(0) + +#define RTK_CHK_TRUNK_GROUP_VALID(__grpId__) \ + do \ + { \ + if(rtk_switch_isValidTrunkGrpId(__grpId__) != RT_ERR_OK) \ + { \ + return RT_ERR_LA_TRUNK_ID; \ + } \ + }while(0) + +#define RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__) (((__portmask__).bits[0] & (0x00000001 << __port__)) ? 1 : 0) +#define RTK_PORTMASK_IS_EMPTY(__portmask__) (((__portmask__).bits[0] == 0) ? 1 : 0) +#define RTK_PORTMASK_CLEAR(__portmask__) ((__portmask__).bits[0] = 0) +#define RTK_PORTMASK_PORT_SET(__portmask__, __port__) ((__portmask__).bits[0] |= (0x00000001 << __port__)) +#define RTK_PORTMASK_PORT_CLEAR(__portmask__, __port__) ((__portmask__).bits[0] &= ~(0x00000001 << __port__)) +#define RTK_PORTMASK_ALLPORT_SET(__portmask__) (rtk_switch_logPortMask_get(&__portmask__)) +#define RTK_PORTMASK_SCAN(__portmask__, __port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if(RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__)) +#define RTK_PORTMASK_COMPARE(__portmask_A__, __portmask_B__) ((__portmask_A__).bits[0] - (__portmask_B__).bits[0]) + +#define RTK_SCAN_ALL_PHY_PORTMASK(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( (rtk_switch_phyPortMask_get() & (0x00000001 << __port__))) +#define RTK_SCAN_ALL_LOG_PORT(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( rtk_switch_logicalPortCheck(__port__) == RT_ERR_OK) +#define RTK_SCAN_ALL_LOG_PORTMASK(__portmask__) for((__portmask__).bits[0] = 0; (__portmask__).bits[0] < 0x7FFFF; (__portmask__).bits[0]++) if( rtk_switch_isPortMaskValid(&__portmask__) == RT_ERR_OK) + +/* Port mask defination */ +#define RTK_PHY_PORTMASK_ALL (rtk_switch_phyPortMask_get()) + +/* Port defination*/ +#define RTK_MAX_LOGICAL_PORT_ID (rtk_switch_maxLogicalPort_get()) + +/* Function Name: + * rtk_switch_probe + * Description: + * Probe switch + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Switch probed + * RT_ERR_FAILED - Switch Unprobed. + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip); + +/* Function Name: + * rtk_switch_initialState_set + * Description: + * Set initial status + * Input: + * state - Initial state; + * Output: + * None + * Return: + * RT_ERR_OK - Initialized + * RT_ERR_FAILED - Uninitialized + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_initialState_set(init_state_t state); + +/* Function Name: + * rtk_switch_initialState_get + * Description: + * Get initial status + * Input: + * None + * Output: + * None + * Return: + * INIT_COMPLETED - Initialized + * INIT_NOT_COMPLETED - Uninitialized + * Note: + * + */ +extern init_state_t rtk_switch_initialState_get(void); + +/* Function Name: + * rtk_switch_logicalPortCheck + * Description: + * Check logical port ID. + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is correct + * RT_ERR_FAILED - Port ID is not correct + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isUtpPort + * Description: + * Check is logical port a UTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a UTP port + * RT_ERR_FAILED - Port ID is not a UTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isExtPort + * Description: + * Check is logical port a Extension port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a EXT port + * RT_ERR_FAILED - Port ID is not a EXT port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isHsgPort + * Description: + * Check is logical port a HSG port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a HSG port + * RT_ERR_FAILED - Port ID is not a HSG port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isSgmiiPort + * Description: + * Check is logical port a SGMII port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a SGMII port + * RT_ERR_FAILED - Port ID is not a SGMII port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isCPUPort + * Description: + * Check is logical port a CPU port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a CPU port + * RT_ERR_FAILED - Port ID is not a CPU port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isComboPort + * Description: + * Check is logical port a Combo port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a combo port + * RT_ERR_FAILED - Port ID is not a combo port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_ComboPort_get + * Description: + * Get Combo port ID + * Input: + * None + * Output: + * None + * Return: + * Port ID of combo port + * Note: + * + */ +extern rtk_uint32 rtk_switch_ComboPort_get(void); + +/* Function Name: + * rtk_switch_isPtpPort + * Description: + * Check is logical port a PTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a PTP port + * RT_ERR_FAILED - Port ID is not a PTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_port_L2P_get + * Description: + * Get physical port ID + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * Physical port ID + * Note: + * + */ +extern rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_port_P2L_get + * Description: + * Get logical port ID + * Input: + * physicalPort - physical port ID + * Output: + * None + * Return: + * logical port ID + * Note: + * + */ +extern rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort); + +/* Function Name: + * rtk_switch_isPortMaskValid + * Description: + * Check portmask is valid or not + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - port mask is valid + * RT_ERR_FAILED - port mask is not valid + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask); + +/* Function Name: + * rtk_switch_isPortMaskUtp + * Description: + * Check all ports in portmask are only UTP port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only UTP port in port mask + * RT_ERR_FAILED - Not only UTP port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask); + +/* Function Name: + * rtk_switch_isPortMaskExt + * Description: + * Check all ports in portmask are only EXT port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only EXT port in port mask + * RT_ERR_FAILED - Not only EXT port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask); + +/* Function Name: + * rtk_switch_portmask_L2P_get + * Description: + * Get physicl portmask from logical portmask + * Input: + * pLogicalPmask - logical port mask + * Output: + * pPhysicalPortmask - physical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask); + +/* Function Name: + * rtk_switch_portmask_P2L_get + * Description: + * Get logical portmask from physical portmask + * Input: + * physicalPortmask - physical port mask + * Output: + * pLogicalPmask - logical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask); + +/* Function Name: + * rtk_switch_phyPortMask_get + * Description: + * Get physical portmask + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Physical port mask + * Note: + * + */ +rtk_uint32 rtk_switch_phyPortMask_get(void); + +/* Function Name: + * rtk_switch_logPortMask_get + * Description: + * Get Logical portmask + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_logPortMask_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_switch_init + * Description: + * Set chip to default configuration enviroment + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can set chip registers to default configuration for different release chip model. + */ +extern rtk_api_ret_t rtk_switch_init(void); + +/* Function Name: + * rtk_switch_portMaxPktLen_set + * Description: + * Set Max packet length + * Input: + * port - Port ID + * speed - Speed + * cfgId - Configuration ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId); + +/* Function Name: + * rtk_switch_portMaxPktLen_get + * Description: + * Get Max packet length + * Input: + * port - Port ID + * speed - Speed + * Output: + * pCfgId - Configuration ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId); + +/* Function Name: + * rtk_switch_maxPktLenCfg_set + * Description: + * Set Max packet length configuration + * Input: + * cfgId - Configuration ID + * pktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen); + +/* Function Name: + * rtk_switch_maxPktLenCfg_get + * Description: + * Get Max packet length configuration + * Input: + * cfgId - Configuration ID + * pPktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen); + +/* Function Name: + * rtk_switch_greenEthernet_set + * Description: + * Set all Ports Green Ethernet state. + * Input: + * enable - Green Ethernet state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all Ports Green Ethernet state. + * The configuration is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable); + +/* Function Name: + * rtk_switch_greenEthernet_get + * Description: + * Get all Ports Green Ethernet state. + * Input: + * None + * Output: + * pEnable - Green Ethernet state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can get Green Ethernet state. + */ +extern rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_switch_maxLogicalPort_get + * Description: + * Get Max logical port ID + * Input: + * None + * Output: + * None + * Return: + * Max logical port + * Note: + * This API can get max logical port + */ +extern rtk_port_t rtk_switch_maxLogicalPort_get(void); + +/* Function Name: + * rtk_switch_maxMeterId_get + * Description: + * Get Max Meter ID + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max Meter ID + * Note: + * + */ +extern rtk_uint32 rtk_switch_maxMeterId_get(void); + +/* Function Name: + * rtk_switch_maxLutAddrNumber_get + * Description: + * Get Max LUT Address number + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max LUT Address number + * Note: + * + */ +extern rtk_uint32 rtk_switch_maxLutAddrNumber_get(void); + +/* Function Name: + * rtk_switch_isValidTrunkGrpId + * Description: + * Check if trunk group is valid or not + * Input: + * grpId - Group ID + * Output: + * None + * Return: + * RT_ERR_OK - Trunk Group ID is valid + * RT_ERR_LA_TRUNK_ID - Trunk Group ID is not valid + * Note: + * + */ +rtk_uint32 rtk_switch_isValidTrunkGrpId(rtk_uint32 grpId); + +#endif diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h new file mode 100755 index 00000000..589ecb78 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level type enum definition. + * Feature : + * + */ + +#ifndef _RTL8367C_TYPES_H_ +#define _RTL8367C_TYPES_H_ + +//#include + +typedef unsigned long long rtk_uint64; +typedef long long rtk_int64; +typedef unsigned int rtk_uint32; +typedef int rtk_int32; +typedef unsigned short rtk_uint16; +typedef short rtk_int16; +typedef unsigned char rtk_uint8; +typedef char rtk_int8; + +#define CONST_T const + +#define RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST 1 + +#define RTK_MAX_NUM_OF_PORT 8 +#define RTK_PORT_ID_MAX (RTK_MAX_NUM_OF_PORT-1) +#define RTK_PHY_ID_MAX (RTK_MAX_NUM_OF_PORT-4) +#define RTK_MAX_PORT_MASK 0xFF + +#define RTK_WHOLE_SYSTEM 0xFF + +typedef struct rtk_portmask_s +{ + rtk_uint32 bits[RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST]; +} rtk_portmask_t; + +typedef enum rtk_enable_e +{ + DISABLED = 0, + ENABLED, + RTK_ENABLE_END +} rtk_enable_t; + +#ifndef ETHER_ADDR_LEN +#define ETHER_ADDR_LEN 6 +#endif + +/* ethernet address type */ +typedef struct rtk_mac_s +{ + rtk_uint8 octet[ETHER_ADDR_LEN]; +} rtk_mac_t; + +typedef rtk_uint32 rtk_pri_t; /* priority vlaue */ +typedef rtk_uint32 rtk_qid_t; /* queue id type */ +typedef rtk_uint32 rtk_data_t; +typedef rtk_uint32 rtk_dscp_t; /* dscp vlaue */ +typedef rtk_uint32 rtk_fid_t; /* filter id type */ +typedef rtk_uint32 rtk_vlan_t; /* vlan id type */ +typedef rtk_uint32 rtk_mac_cnt_t; /* MAC count type */ +typedef rtk_uint32 rtk_meter_id_t; /* meter id type */ +typedef rtk_uint32 rtk_rate_t; /* rate type */ + +typedef enum rtk_port_e +{ + UTP_PORT0 = 0, + UTP_PORT1, + UTP_PORT2, + UTP_PORT3, + UTP_PORT4, + UTP_PORT5, + UTP_PORT6, + UTP_PORT7, + + EXT_PORT0 = 16, + EXT_PORT1, + EXT_PORT2, + + UNDEFINE_PORT = 30, + RTK_PORT_MAX = 31 +} rtk_port_t; + + +#ifndef _RTL_TYPES_H + +#if 0 +typedef unsigned long long uint64; +typedef long long int64; +typedef unsigned int uint32; +typedef int int32; +typedef unsigned short uint16; +typedef short int16; +typedef unsigned char uint8; +typedef char int8; +#endif + +typedef rtk_uint32 ipaddr_t; +typedef rtk_uint32 memaddr; + +#ifndef ETHER_ADDR_LEN +#define ETHER_ADDR_LEN 6 +#endif + +typedef struct ether_addr_s { + rtk_uint8 octet[ETHER_ADDR_LEN]; +} ether_addr_t; + +#ifdef __KERNEL__ +#define rtlglue_printf printk +#else +#define rtlglue_printf printf +#endif +#define PRINT rtlglue_printf +#endif /*_RTL_TYPES_H*/ + +/* type abstraction */ +#ifdef EMBEDDED_SUPPORT + +typedef rtk_int16 rtk_api_ret_t; +typedef rtk_int16 ret_t; +typedef rtk_uint32 rtk_u_long; + +#else + +typedef rtk_int32 rtk_api_ret_t; +typedef rtk_int32 ret_t; +typedef rtk_uint64 rtk_u_long_t; + +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define CONST const +#endif /* _RTL8367C_TYPES_H_ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h new file mode 100755 index 00000000..55cb41b0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : + * + */ + + +#ifndef _RTL8367C_ASICDRV_H_ +#define _RTL8367C_ASICDRV_H_ + +#include +#include +#include +#include + +#define RTL8367C_REGBITLENGTH 16 +#define RTL8367C_REGDATAMAX 0xFFFF + +#define RTL8367C_VIDMAX 0xFFF +#define RTL8367C_EVIDMAX 0x1FFF +#define RTL8367C_CVIDXNO 32 +#define RTL8367C_CVIDXMAX (RTL8367C_CVIDXNO-1) + +#define RTL8367C_PRIMAX 7 +#define RTL8367C_DSCPMAX 63 + +#define RTL8367C_PORTNO 11 +#define RTL8367C_PORTIDMAX (RTL8367C_PORTNO-1) +#define RTL8367C_PMSKMAX ((1<<(RTL8367C_PORTNO))-1) +#define RTL8367C_PORTMASK 0x7FF + +#define RTL8367C_PHYNO 5 +#define RTL8367C_PHYIDMAX (RTL8367C_PHYNO-1) + +#define RTL8367C_SVIDXNO 64 +#define RTL8367C_SVIDXMAX (RTL8367C_SVIDXNO-1) +#define RTL8367C_MSTIMAX 15 + +#define RTL8367C_METERNO 64 +#define RTL8367C_METERMAX (RTL8367C_METERNO-1) +#define RTL8367C_METERBUCKETSIZEMAX 0xFFFF + +#define RTL8367C_QUEUENO 8 +#define RTL8367C_QIDMAX (RTL8367C_QUEUENO-1) + +#define RTL8367C_PHY_BUSY_CHECK_COUNTER 1000 + +#define RTL8367C_QOS_GRANULARTY_MAX 0x7FFFF +#define RTL8367C_QOS_GRANULARTY_LSB_MASK 0xFFFF +#define RTL8367C_QOS_GRANULARTY_LSB_OFFSET 0 +#define RTL8367C_QOS_GRANULARTY_MSB_MASK 0x70000 +#define RTL8367C_QOS_GRANULARTY_MSB_OFFSET 16 + +#define RTL8367C_QOS_GRANULARTY_UNIT_KBPS 8 + +#define RTL8367C_QOS_RATE_INPUT_MAX (0x1FFFF * 8) +#define RTL8367C_QOS_RATE_INPUT_MAX_HSG (0x7FFFF * 8) +#define RTL8367C_QOS_RATE_INPUT_MIN 8 +#define RTL8367C_QOS_PPS_INPUT_MAX (0x7FFFF) +#define RTL8367C_QOS_PPS_INPUT_MIN 1 + +#define RTL8367C_QUEUE_MASK 0xFF + +#define RTL8367C_EFIDMAX 0x7 +#define RTL8367C_FIDMAX 0xF + +#define RTL8367C_EAV_SECONDMAX 0xFFFFFFFF +#define RTL8367C_EAV_NANOSECONDMAX 0x3B9AC9FF + + +/* the above macro is generated by genDotH */ +#define RTL8367C_VALID_REG_NO 3869 + +/*======================================================================= + * Enum + *========================================================================*/ +enum RTL8367C_TABLE_ACCESS_OP +{ + TB_OP_READ = 0, + TB_OP_WRITE +}; + +enum RTL8367C_TABLE_ACCESS_TARGET +{ + TB_TARGET_ACLRULE = 1, + TB_TARGET_ACLACT, + TB_TARGET_CVLAN, + TB_TARGET_L2, + TB_TARGET_IGMP_GROUP +}; + +#define RTL8367C_TABLE_ACCESS_REG_DATA(op, target) ((op << 3) | target) + +/*======================================================================= + * Structures + *========================================================================*/ + + +#ifdef __cplusplus +extern "C" { +#endif +extern ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value); +extern ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue); + +extern ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value); +extern ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue); + +extern ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value); +extern ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue); + +#ifdef __cplusplus +} +#endif + + + +#endif /*#ifndef _RTL8367C_ASICDRV_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h new file mode 100755 index 00000000..8ae69ac3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : ACL related function drivers + * + */ + +#ifndef _RTL8367C_ASICDRV_ACL_H_ +#define _RTL8367C_ASICDRV_ACL_H_ + +#include + +#define RTL8367C_ACLRULENO 96 + +#define RTL8367C_ACLRULEMAX (RTL8367C_ACLRULENO-1) +#define RTL8367C_ACLRULEFIELDNO 8 +#define RTL8367C_ACLTEMPLATENO 5 +#define RTL8367C_ACLTYPEMAX (RTL8367C_ACLTEMPLATENO-1) + +#define RTL8367C_ACLRULETBLEN 9 +#define RTL8367C_ACLACTTBLEN 4 +#define RTL8367C_ACLRULETBADDR(type, rule) ((type << 6) | rule) +#define RTL8367C_ACLRULETBADDR2(type, rule) ((type << 5) | (rule + 64)) + +#define ACL_ACT_CVLAN_ENABLE_MASK 0x1 +#define ACL_ACT_SVLAN_ENABLE_MASK 0x2 +#define ACL_ACT_PRIORITY_ENABLE_MASK 0x4 +#define ACL_ACT_POLICING_ENABLE_MASK 0x8 +#define ACL_ACT_FWD_ENABLE_MASK 0x10 +#define ACL_ACT_INTGPIO_ENABLE_MASK 0x20 + +#define RTL8367C_ACLRULETAGBITS 5 + +#define RTL8367C_ACLRANGENO 16 + +#define RTL8367C_ACLRANGEMAX (RTL8367C_ACLRANGENO-1) + +#define RTL8367C_ACL_PORTRANGEMAX (0xFFFF) +#define RTL8367C_ACL_ACT_TABLE_LEN (4) + +enum ACLTCAMTYPES +{ + CAREBITS= 0, + DATABITS +}; + +typedef enum aclFwdAct +{ + RTL8367C_ACL_FWD_MIRROR = 0, + RTL8367C_ACL_FWD_REDIRECT, + RTL8367C_ACL_FWD_MIRRORFUNTION, + RTL8367C_ACL_FWD_TRAP, +} rtl8367c_aclFwd_t; + +enum ACLFIELDTYPES +{ + ACL_UNUSED, + ACL_DMAC0, + ACL_DMAC1, + ACL_DMAC2, + ACL_SMAC0, + ACL_SMAC1, + ACL_SMAC2, + ACL_ETHERTYPE, + ACL_STAG, + ACL_CTAG, + ACL_IP4SIP0 = 0x10, + ACL_IP4SIP1, + ACL_IP4DIP0, + ACL_IP4DIP1, + ACL_IP6SIP0WITHIPV4 = 0x20, + ACL_IP6SIP1WITHIPV4, + ACL_IP6DIP0WITHIPV4 = 0x28, + ACL_IP6DIP1WITHIPV4, + ACL_VIDRANGE = 0x30, + ACL_IPRANGE, + ACL_PORTRANGE, + ACL_FIELD_VALID, + ACL_FIELD_SELECT00 = 0x40, + ACL_FIELD_SELECT01, + ACL_FIELD_SELECT02, + ACL_FIELD_SELECT03, + ACL_FIELD_SELECT04, + ACL_FIELD_SELECT05, + ACL_FIELD_SELECT06, + ACL_FIELD_SELECT07, + ACL_FIELD_SELECT08, + ACL_FIELD_SELECT09, + ACL_FIELD_SELECT10, + ACL_FIELD_SELECT11, + ACL_FIELD_SELECT12, + ACL_FIELD_SELECT13, + ACL_FIELD_SELECT14, + ACL_FIELD_SELECT15, + ACL_TCPSPORT = 0x80, + ACL_TCPDPORT, + ACL_TCPFLAG, + ACL_UDPSPORT, + ACL_UDPDPORT, + ACL_ICMPCODETYPE, + ACL_IGMPTYPE, + ACL_SPORT, + ACL_DPORT, + ACL_IP4TOSPROTO, + ACL_IP4FLAGOFF, + ACL_TCNH, + ACL_CPUTAG, + ACL_L2PAYLOAD, + ACL_IP6SIP0, + ACL_IP6SIP1, + ACL_IP6SIP2, + ACL_IP6SIP3, + ACL_IP6SIP4, + ACL_IP6SIP5, + ACL_IP6SIP6, + ACL_IP6SIP7, + ACL_IP6DIP0, + ACL_IP6DIP1, + ACL_IP6DIP2, + ACL_IP6DIP3, + ACL_IP6DIP4, + ACL_IP6DIP5, + ACL_IP6DIP6, + ACL_IP6DIP7, + ACL_TYPE_END +}; + +struct acl_rule_smi_st{ + rtk_uint16 rule_info; + rtk_uint16 field[RTL8367C_ACLRULEFIELDNO]; +}; + +struct acl_rule_smi_ext_st{ + rtk_uint16 rule_info; +}; + +typedef struct ACLRULESMI{ + struct acl_rule_smi_st care_bits; + rtk_uint16 valid:1; + struct acl_rule_smi_st data_bits; + + struct acl_rule_smi_ext_st care_bits_ext; + struct acl_rule_smi_ext_st data_bits_ext; +}rtl8367c_aclrulesmi; + +struct acl_rule_st{ + rtk_uint16 active_portmsk:11; + rtk_uint16 type:3; + rtk_uint16 tag_exist:5; + rtk_uint16 field[RTL8367C_ACLRULEFIELDNO]; +}; + +typedef struct ACLRULE{ + struct acl_rule_st data_bits; + rtk_uint16 valid:1; + struct acl_rule_st care_bits; +}rtl8367c_aclrule; + + +typedef struct rtl8367c_acltemplate_s{ + rtk_uint8 field[8]; +}rtl8367c_acltemplate_t; + + +typedef struct acl_act_s{ + rtk_uint16 cvidx_cact:7; + rtk_uint16 cact:2; + rtk_uint16 svidx_sact:7; + rtk_uint16 sact:2; + + + rtk_uint16 aclmeteridx:7; + rtk_uint16 fwdpmask:11; + rtk_uint16 fwdact:2; + + rtk_uint16 pridx:7; + rtk_uint16 priact:2; + rtk_uint16 gpio_pin:4; + rtk_uint16 gpio_en:1; + rtk_uint16 aclint:1; + + rtk_uint16 cact_ext:2; + rtk_uint16 fwdact_ext:1; + rtk_uint16 tag_fmt:2; +}rtl8367c_acl_act_t; + +typedef struct acl_rule_union_s +{ + rtl8367c_aclrule aclRule; + rtl8367c_acl_act_t aclAct; + rtk_uint32 aclActCtrl; + rtk_uint32 aclNot; +}rtl8367c_acl_rule_union_t; + + +extern ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule); +extern ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule); +extern ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not); +extern ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot); +extern ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType); +extern ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType); +extern ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct); +extern ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct); +extern ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl); +extern ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *aclActCtrl); +extern ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort); +extern ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort); +extern ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid); +extern ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid); +extern ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp); +extern ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp); +extern ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity); +extern ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity); + +#endif /*_RTL8367C_ASICDRV_ACL_H_*/ + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h new file mode 100755 index 00000000..f7a46014 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Proprietary CPU-tag related function drivers + * + */ + +#ifndef _RTL8367C_ASICDRV_CPUTAG_H_ +#define _RTL8367C_ASICDRV_CPUTAG_H_ + +#include + +enum CPUTAG_INSERT_MODE +{ + CPUTAG_INSERT_TO_ALL = 0, + CPUTAG_INSERT_TO_TRAPPING, + CPUTAG_INSERT_TO_NO, + CPUTAG_INSERT_END +}; + +extern ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port); +extern ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort); +extern ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPmsk); +extern ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode); +extern ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri); +extern ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri); +extern ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 postion); +extern ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion); +extern ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode); +extern ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode); + +#endif /*#ifndef _RTL8367C_ASICDRV_CPUTAG_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h new file mode 100755 index 00000000..7639ae78 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : 802.1X related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_DOT1X_H_ +#define _RTL8367C_ASICDRV_DOT1X_H_ + +#include + +enum DOT1X_UNAUTH_BEHAV +{ + DOT1X_UNAUTH_DROP = 0, + DOT1X_UNAUTH_TRAP, + DOT1X_UNAUTH_GVLAN, + DOT1X_UNAUTH_END +}; + +extern ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth); +extern ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth); +extern ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir); +extern ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 *pOpdir); +extern ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir); +extern ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir); +extern ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc); +extern ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32 *pProc); +extern ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index); +extern ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex); +extern ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority); + + +#endif /*_RTL8367C_ASICDRV_DOT1X_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h new file mode 100755 index 00000000..b633f66f --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ethernet AV related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_EAV_H_ +#define _RTL8367C_ASICDRV_EAV_H_ + +#include + +typedef enum RTL8367C_PTP_TIME_CMD_E +{ + PTP_TIME_READ = 0, + PTP_TIME_WRITE, + PTP_TIME_INC, + PTP_TIME_DEC, + PTP_TIME_CMD_END +}RTL8367C_PTP_TIME_CMD; + +typedef enum RTL8367C_PTP_TIME_ADJ_E +{ + PTP_TIME_ADJ_INC = 0, + PTP_TIME_ADJ_DEC, + PTP_TIME_ADJ_END +}RTL8367C_PTP_TIME_ADJ; + +typedef enum RTL8367C_PTP_TIME_CTRL_E +{ + PTP_TIME_CTRL_STOP = 0, + PTP_TIME_CTRL_START, + PTP_TIME_CTRL_END +}RTL8367C_PTP_TIME_CTRL; + +typedef enum RTL8367C_PTP_INTR_IMRS_E +{ + PTP_IMRS_TX_SYNC, + PTP_IMRS_TX_DELAY_REQ, + PTP_IMRS_TX_PDELAY_REQ, + PTP_IMRS_TX_PDELAY_RESP, + PTP_IMRS_RX_SYNC, + PTP_IMRS_RX_DELAY_REQ, + PTP_IMRS_RX_PDELAY_REQ, + PTP_IMRS_RX_PDELAY_RESP, + PTP_IMRS_END, +}RTL8367C_PTP_INTR_IMRS; + + +typedef enum RTL8367C_PTP_PKT_TYPE_E +{ + PTP_PKT_TYPE_TX_SYNC, + PTP_PKT_TYPE_TX_DELAY_REQ, + PTP_PKT_TYPE_TX_PDELAY_REQ, + PTP_PKT_TYPE_TX_PDELAY_RESP, + PTP_PKT_TYPE_RX_SYNC, + PTP_PKT_TYPE_RX_DELAY_REQ, + PTP_PKT_TYPE_RX_PDELAY_REQ, + PTP_PKT_TYPE_RX_PDELAY_RESP, + PTP_PKT_TYPE_END, +}RTL8367C_PTP_PKT_TYPE; + +typedef struct rtl8367c_ptp_time_stamp_s{ + rtk_uint32 sequence_id; + rtk_uint32 second; + rtk_uint32 nano_second; +}rtl8367c_ptp_time_stamp_t; + +#define RTL8367C_PTP_INTR_MASK 0xFF + +#define RTL8367C_PTP_PORT_MASK 0x3FF + +extern ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac); +extern ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac); +extern ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag); +extern ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag); +extern ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond); +extern ret_t rtl8367c_getAsicEavSysTime(rtk_uint32* pSecond, rtk_uint32* pNanoSecond); +extern ret_t rtl8367c_setAsicEavSysTimeAdjust(rtk_uint32 type, rtk_uint32 second, rtk_uint32 nanoSecond); +extern ret_t rtl8367c_setAsicEavSysTimeCtrl(rtk_uint32 control); +extern ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl); +extern ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr); +extern ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr); +extern ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms); +extern ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims); +extern ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms); +extern ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp); + +extern ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority); +extern ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority); + +#endif /*#ifndef _RTL8367C_ASICDRV_EAV_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h new file mode 100755 index 00000000..6bedce62 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 48989 $ + * $Date: 2014-07-01 15:45:24 +0800 (¶g¤G, 01 ¤C¤ë 2014) $ + * + * Purpose : RTL8370 switch high-level API for RTL8367C + * Feature : + * + */ + +#ifndef _RTL8367C_ASICDRV_EEE_H_ +#define _RTL8367C_ASICDRV_EEE_H_ + +#include + +#define EEE_OCP_PHY_ADDR (0xA5D0) + +extern ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable); +extern ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable); + + +#endif /*_RTL8367C_ASICDRV_EEE_H_*/ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h new file mode 100755 index 00000000..ce67cdeb --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Flow control related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_FC_H_ +#define _RTL8367C_ASICDRV_FC_H_ + +#include + +#define RTL8367C_PAGE_NUMBER 0x600 + + +enum FLOW_CONTROL_TYPE +{ + FC_EGRESS = 0, + FC_INGRESS, +}; + +enum FC_JUMBO_SIZE +{ + FC_JUMBO_SIZE_3K = 0, + FC_JUMBO_SIZE_4K, + FC_JUMBO_SIZE_6K, + FC_JUMBO_SIZE_9K, + FC_JUMBO_SIZE_END, + +}; + + +extern ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select); +extern ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect); +extern ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size); +extern ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize); +extern ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall); +extern ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall); +extern ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold); +extern ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold); +extern ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); + +extern ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap); +extern ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap); +extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap); +extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap); +extern ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold); +extern ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold); +extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold); +extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold); +extern ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount); +extern ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable); + +#endif /*_RTL8367C_ASICDRV_FC_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h new file mode 100755 index 00000000..38fd085d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Green ethernet related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_GREEN_H_ +#define _RTL8367C_ASICDRV_GREEN_H_ + +#include +#include + +#define PHY_POWERSAVING_REG 24 + +extern ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype); +extern ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype); +extern ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage); +extern ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator); +extern ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port); +extern ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green); +extern ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green); +extern ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable); +#endif /*#ifndef _RTL8367C_ASICDRV_GREEN_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h new file mode 100755 index 00000000..f4f9bb37 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Field selector related functions + * + */ + +#ifndef _RTL8367C_ASICDRV__HSB_H_ +#define _RTL8367C_ASICDRV__HSB_H_ + +#include + +#define RTL8367C_FIELDSEL_FORMAT_NUMBER (16) +#define RTL8367C_FIELDSEL_MAX_OFFSET (255) + +enum FIELDSEL_FORMAT_FORMAT +{ + FIELDSEL_FORMAT_DEFAULT = 0, + FIELDSEL_FORMAT_RAW, + FIELDSEL_FORMAT_LLC, + FIELDSEL_FORMAT_IPV4, + FIELDSEL_FORMAT_ARP, + FIELDSEL_FORMAT_IPV6, + FIELDSEL_FORMAT_IPPAYLOAD, + FIELDSEL_FORMAT_L4PAYLOAD, + FIELDSEL_FORMAT_END +}; + +extern ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset); +extern ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset); + +#endif /*_RTL8367C_ASICDRV__HSB_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h new file mode 100755 index 00000000..d5b095a0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 38651 $ + * $Date: 2016-02-27 14:32:56 +0800 (©P¤T, 17 ¥|¤ë 2016) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : I2C related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_I2C_H_ +#define _RTL8367C_ASICDRV_I2C_H_ +#include +#include + + +#define TIMEROUT_FOR_MICROSEMI (0x400) + +#define GPIO_INPUT 1 +#define GPIO_OUTPUT 2 + +extern ret_t rtl8367c_setAsicI2C_checkBusIdle(void); +extern ret_t rtl8367c_setAsicI2CStartCmd(void); +extern ret_t rtl8367c_setAsicI2CStopCmd(void); +extern ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar); +extern ret_t rtl8367c_setAsicI2CcheckRxAck(void); +extern ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue); +extern ret_t rtl8367c_setAsicI2CTxAckCmd(void); +extern ret_t rtl8367c_setAsicI2CTxNoAckCmd(void); +extern ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void); +extern ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID); +extern ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID); + + + + + +#endif /*#ifndef _RTL8367C_ASICDRV_I2C_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h new file mode 100755 index 00000000..b879b6b5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : IGMP related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_IGMP_H_ +#define _RTL8367C_ASICDRV_IGMP_H_ + +/****************************************************************/ +/* Header File inclusion */ +/****************************************************************/ +#include + +#define RTL8367C_MAX_LEAVE_TIMER (7) +#define RTL8367C_MAX_QUERY_INT (0xFFFF) +#define RTL8367C_MAX_ROB_VAR (7) + +#define RTL8367C_IGMP_GOUP_NO (256) +#define RTL8367C_IGMP_MAX_GOUP (0xFF) +#define RTL8367C_IGMP_GRP_BLEN (3) +#define RTL8367C_ROUTER_PORT_INVALID (0xF) + +enum RTL8367C_IGMPTABLE_FULL_OP +{ + TABLE_FULL_FORWARD = 0, + TABLE_FULL_DROP, + TABLE_FULL_TRAP, + TABLE_FULL_OP_END +}; + +enum RTL8367C_CRC_ERR_OP +{ + CRC_ERR_DROP = 0, + CRC_ERR_TRAP, + CRC_ERR_FORWARD, + CRC_ERR_OP_END +}; + +enum RTL8367C_IGMP_MLD_PROTOCOL_OP +{ + PROTOCOL_OP_ASIC = 0, + PROTOCOL_OP_FLOOD, + PROTOCOL_OP_TRAP, + PROTOCOL_OP_DROP, + PROTOCOL_OP_END +}; + +enum RTL8367C_IGMP_MLD_BYPASS_GROUP +{ + BYPASS_224_0_0_X = 0, + BYPASS_224_0_1_X, + BYPASS_239_255_255_X, + BYPASS_IPV6_00XX, + BYPASS_GROUP_END +}; + +typedef struct +{ + rtk_uint32 p0_timer; + rtk_uint32 p1_timer; + rtk_uint32 p2_timer; + rtk_uint32 p3_timer; + rtk_uint32 p4_timer; + rtk_uint32 p5_timer; + rtk_uint32 p6_timer; + rtk_uint32 p7_timer; + rtk_uint32 p8_timer; + rtk_uint32 p9_timer; + rtk_uint32 p10_timer; + rtk_uint32 report_supp_flag; + +}rtl8367c_igmpgroup; +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * This program is the proprietary software of Realtek Semiconductor + * Corporation and/or its licensors, and only be used, duplicated, + * modified or distributed under the authorized license from Realtek. + * + * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER + * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : IGMP related functions + * + */ +#include + +ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled); +ret_t rtl8367c_getAsicIgmp(rtk_uint32 *pEnabled); +ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled ); +ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *pEnabled ); +ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation); +ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *pOperation); +ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation); +ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *pOperation); +ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled); +ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *pEnabled); +ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer); +ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pLeave_timer); +ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval); +ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pInterval); +ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var); +ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *pRob_var); +ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk); +ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pMsk); +ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk); +ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk); +ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *pPort, rtk_uint32 *pTimer); +ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *pPort, rtk_uint32 *pTimer); +ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled); +ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *pReport_supp_enabled, rtk_uint32 *pLeave_supp_enabled); +ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query); +ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *pAllow_query); +ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report); +ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *pAllow_report); +ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave); +ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *pAllow_leave); +ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp); +ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *pAllow_mrp); +ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata); +ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *pAllow_mcdata); +ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op); +ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv1_op); +ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op); +ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv2_op); +ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op); +ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv3_op); +ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op); +ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *pMldv1_op); +ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op); +ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *pMldv2_op); +ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group); +ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *pMax_group); +ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *pCurrent_group); +ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *pValid, rtl8367c_igmpgroup *pGrp); +ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled); +ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *pEnabled); +ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood); +ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood); +ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop); +ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop); +ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass); +ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass); +ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky); +ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky); +ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky); +ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky); +ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled); +ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled); + +#endif /*#ifndef _RTL8367C_ASICDRV_IGMP_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h new file mode 100755 index 00000000..10f35453 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ingress bandwidth control related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_INBWCTRL_H_ +#define _RTL8367C_ASICDRV_INBWCTRL_H_ + +#include + +extern ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC); +extern ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC ); +extern ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled); + + +#endif /*_RTL8367C_ASICDRV_INBWCTRL_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h new file mode 100755 index 00000000..8b78014a --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Interrupt related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_ +#define _RTL8367C_ASICDRV_INTERRUPT_H_ + +#include + +typedef enum RTL8367C_INTR_IMRS_E +{ + IMRS_LINK_CHANGE, + IMRS_METER_EXCEED, + IMRS_L2_LEARN, + IMRS_SPEED_CHANGE, + IMRS_SPECIAL_CONGESTION, + IMRS_GREEN_FEATURE, + IMRS_LOOP_DETECTION, + IMRS_8051, + IMRS_CABLE_DIAG, + IMRS_ACL, + IMRS_RESERVED, /* Unused */ + IMRS_SLIENT, + IMRS_END, +}RTL8367C_INTR_IMRS; + +typedef enum RTL8367C_INTR_INDICATOR_E +{ + INTRST_L2_LEARN = 0, + INTRST_SPEED_CHANGE, + INTRST_SPECIAL_CONGESTION, + INTRST_PORT_LINKDOWN, + INTRST_PORT_LINKUP, + INTRST_METER0_15, + INTRST_METER16_31, + INTRST_RLDP_LOOPED, + INTRST_RLDP_RELEASED, + INTRST_SYS_LEARN, + INTRST_END, +}RTL8367C_INTR_INDICATOR; + +extern ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity); +extern ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity); +extern ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr); +extern ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr); +extern ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims); +extern ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms); +extern ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status); +extern ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus); + + +#endif /*#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h new file mode 100755 index 00000000..a7f8e206 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LED related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_LED_H_ +#define _RTL8367C_ASICDRV_LED_H_ + +#include + +#define RTL8367C_LEDGROUPNO 3 +#define RTL8367C_LEDGROUPMASK 0x7 +#define RTL8367C_LED_FORCE_MODE_BASE RTL8367C_REG_CPU_FORCE_LED0_CFG0 +#define RTL8367C_LED_FORCE_CTRL RTL8367C_REG_CPU_FORCE_LED_CFG + +enum RTL8367C_LEDOP{ + + LEDOP_SCAN0=0, + LEDOP_SCAN1, + LEDOP_PARALLEL, + LEDOP_SERIAL, + LEDOP_END, +}; + +enum RTL8367C_LEDSERACT{ + + LEDSERACT_HIGH=0, + LEDSERACT_LOW, + LEDSERACT_MAX, +}; + +enum RTL8367C_LEDSER{ + + LEDSER_16G=0, + LEDSER_8G, + LEDSER_MAX, +}; + +enum RTL8367C_LEDCONF{ + + LEDCONF_LEDOFF=0, + LEDCONF_DUPCOL, + LEDCONF_LINK_ACT, + LEDCONF_SPD1000, + LEDCONF_SPD100, + LEDCONF_SPD10, + LEDCONF_SPD1000ACT, + LEDCONF_SPD100ACT, + LEDCONF_SPD10ACT, + LEDCONF_SPD10010ACT, + LEDCONF_LOOPDETECT, + LEDCONF_EEE, + LEDCONF_LINKRX, + LEDCONF_LINKTX, + LEDCONF_MASTER, + LEDCONF_ACT, + LEDCONF_END +}; + +enum RTL8367C_LEDBLINKRATE{ + + LEDBLINKRATE_32MS=0, + LEDBLINKRATE_64MS, + LEDBLINKRATE_128MS, + LEDBLINKRATE_256MS, + LEDBLINKRATE_512MS, + LEDBLINKRATE_1024MS, + LEDBLINKRATE_48MS, + LEDBLINKRATE_96MS, + LEDBLINKRATE_END, +}; + +enum RTL8367C_LEDFORCEMODE{ + + LEDFORCEMODE_NORMAL=0, + LEDFORCEMODE_BLINK, + LEDFORCEMODE_OFF, + LEDFORCEMODE_ON, + LEDFORCEMODE_END, +}; + +enum RTL8367C_LEDFORCERATE{ + + LEDFORCERATE_512MS=0, + LEDFORCERATE_1024MS, + LEDFORCERATE_2048MS, + LEDFORCERATE_NORMAL, + LEDFORCERATE_END, + +}; + +enum RTL8367C_LEDMODE +{ + RTL8367C_LED_MODE_0 = 0, + RTL8367C_LED_MODE_1, + RTL8367C_LED_MODE_2, + RTL8367C_LED_MODE_3, + RTL8367C_LED_MODE_END +}; + +extern ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config); +extern ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig); +extern ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate); +extern ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate); +extern ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate); +extern ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate); +extern ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask); +extern ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode); +extern ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode); +extern ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode); +extern ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled); +extern ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask); +extern ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask); + + +#endif /*#ifndef _RTL8367C_ASICDRV_LED_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h new file mode 100755 index 00000000..c94ea076 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LUT related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_LUT_H_ +#define _RTL8367C_ASICDRV_LUT_H_ + +#include + +#define RTL8367C_LUT_AGETIMERMAX (7) +#define RTL8367C_LUT_AGESPEEDMAX (3) +#define RTL8367C_LUT_LEARNLIMITMAX (0x1040) +#define RTL8367C_LUT_ADDRMAX (0x103F) +#define RTL8367C_LUT_IPMCGRP_TABLE_MAX (0x3F) +#define RTL8367C_LUT_ENTRY_SIZE (6) +#define RTL8367C_LUT_BUSY_CHECK_NO (10) + +#define RTL8367C_LUT_TABLE_SIZE (6) + +enum RTL8367C_LUTHASHMETHOD{ + + LUTHASHMETHOD_SVL=0, + LUTHASHMETHOD_IVL, + LUTHASHMETHOD_END, +}; + + +enum RTL8367C_LRNOVERACT{ + + LRNOVERACT_FORWARD=0, + LRNOVERACT_DROP, + LRNOVERACT_TRAP, + LRNOVERACT_END, +}; + +enum RTL8367C_LUTREADMETHOD{ + + LUTREADMETHOD_MAC =0, + LUTREADMETHOD_ADDRESS, + LUTREADMETHOD_NEXT_ADDRESS, + LUTREADMETHOD_NEXT_L2UC, + LUTREADMETHOD_NEXT_L2MC, + LUTREADMETHOD_NEXT_L3MC, + LUTREADMETHOD_NEXT_L2L3MC, + LUTREADMETHOD_NEXT_L2UCSPA, +}; + +enum RTL8367C_FLUSHMODE +{ + FLUSHMDOE_PORT = 0, + FLUSHMDOE_VID, + FLUSHMDOE_FID, + FLUSHMDOE_END, +}; + +enum RTL8367C_FLUSHTYPE +{ + FLUSHTYPE_DYNAMIC = 0, + FLUSHTYPE_BOTH, + FLUSHTYPE_END, +}; + + +typedef struct LUTTABLE{ + + ipaddr_t sip; + ipaddr_t dip; + ether_addr_t mac; + rtk_uint16 ivl_svl:1; + rtk_uint16 cvid_fid:12; + rtk_uint16 fid:4; + rtk_uint16 efid:3; + + rtk_uint16 nosalearn:1; + rtk_uint16 da_block:1; + rtk_uint16 sa_block:1; + rtk_uint16 auth:1; + rtk_uint16 lut_pri:3; + rtk_uint16 sa_en:1; + rtk_uint16 fwd_en:1; + rtk_uint16 mbr:11; + rtk_uint16 spa:4; + rtk_uint16 age:3; + rtk_uint16 l3lookup:1; + rtk_uint16 igmp_asic:1; + rtk_uint16 igmpidx:8; + + rtk_uint16 lookup_hit:1; + rtk_uint16 lookup_busy:1; + rtk_uint16 address:13; + + rtk_uint16 l3vidlookup:1; + rtk_uint16 l3_vid:12; + + rtk_uint16 wait_time; + +}rtl8367c_luttb; + +extern ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed); +extern ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed); +extern ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled); +extern ret_t rtl8367c_getAsicLutCamType(rtk_uint32* pType); +extern ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number); +extern ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber); +extern ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number); +extern ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber); +extern ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action); +extern ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction); +extern ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action); +extern ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction); +extern ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table); +extern ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table); +extern ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber); +extern ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type); +extern ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType); +extern ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type); +extern ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType); +extern ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid); +extern ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid); +extern ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid); +extern ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid); +extern ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled); +extern ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled); +extern ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid); +extern ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid); +extern ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable); +extern ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicLutFlushAll(void); +extern ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus); +extern ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable); +extern ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable); + +#endif /*_RTL8367C_ASICDRV_LUT_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h new file mode 100755 index 00000000..ba761a94 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Shared meter related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_METER_H_ +#define _RTL8367C_ASICDRV_METER_H_ + +#include + + +extern ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg); +extern ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg); +extern ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbThreshold); +extern ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbThreshold); +extern ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type); +extern ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType); +extern ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index); +extern ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus); + +#endif /*_RTL8367C_ASICDRV_FC_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h new file mode 100755 index 00000000..ca46e0f4 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : MIB related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_MIB_H_ +#define _RTL8367C_ASICDRV_MIB_H_ + +#include + +#define RTL8367C_MIB_PORT_OFFSET (0x7C) +#define RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET (0x420) + +#define RTL8367C_MAX_LOG_CNT_NUM (32) +#define RTL8367C_MIB_MAX_LOG_CNT_IDX (RTL8367C_MAX_LOG_CNT_NUM - 1) +#define RTL8367C_MIB_LOG_CNT_OFFSET (0x3E0) +#define RTL8367C_MIB_MAX_LOG_MODE_IDX (16-1) + +typedef enum RTL8367C_MIBCOUNTER_E{ + + /* RX */ + ifInOctets = 0, + + dot3StatsFCSErrors, + dot3StatsSymbolErrors, + dot3InPauseFrames, + dot3ControlInUnknownOpcodes, + + etherStatsFragments, + etherStatsJabbers, + ifInUcastPkts, + etherStatsDropEvents, + + ifInMulticastPkts, + ifInBroadcastPkts, + inMldChecksumError, + inIgmpChecksumError, + inMldSpecificQuery, + inMldGeneralQuery, + inIgmpSpecificQuery, + inIgmpGeneralQuery, + inMldLeaves, + inIgmpLeaves, + + /* TX/RX */ + etherStatsOctets, + + etherStatsUnderSizePkts, + etherOversizeStats, + etherStatsPkts64Octets, + etherStatsPkts65to127Octets, + etherStatsPkts128to255Octets, + etherStatsPkts256to511Octets, + etherStatsPkts512to1023Octets, + etherStatsPkts1024to1518Octets, + + /* TX */ + ifOutOctets, + + dot3StatsSingleCollisionFrames, + dot3StatMultipleCollisionFrames, + dot3sDeferredTransmissions, + dot3StatsLateCollisions, + etherStatsCollisions, + dot3StatsExcessiveCollisions, + dot3OutPauseFrames, + ifOutDiscards, + + /* ALE */ + dot1dTpPortInDiscards, + ifOutUcastPkts, + ifOutMulticastPkts, + ifOutBroadcastPkts, + outOampduPkts, + inOampduPkts, + + inIgmpJoinsSuccess, + inIgmpJoinsFail, + inMldJoinsSuccess, + inMldJoinsFail, + inReportSuppressionDrop, + inLeaveSuppressionDrop, + outIgmpReports, + outIgmpLeaves, + outIgmpGeneralQuery, + outIgmpSpecificQuery, + outMldReports, + outMldLeaves, + outMldGeneralQuery, + outMldSpecificQuery, + inKnownMulticastPkts, + + /*Device only */ + dot1dTpLearnedEntryDiscards, + RTL8367C_MIBS_NUMBER, + +}RTL8367C_MIBCOUNTER; + + +extern ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 pmask); +extern ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port,RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter); +extern ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter); +extern ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask); + +extern ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value); +extern ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value); + +extern ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer); +extern ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer); +extern ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type); +extern ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType); +extern ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index); +extern ret_t rtl8367c_setAsicMIBsLength(rtk_uint32 txLengthMode, rtk_uint32 rxLengthMode); +extern ret_t rtl8367c_getAsicMIBsLength(rtk_uint32 *pTxLengthMode, rtk_uint32 *pRxLengthMode); + +#endif /*#ifndef _RTL8367C_ASICDRV_MIB_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h new file mode 100755 index 00000000..23b788d7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port mirror related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_MIRROR_H_ +#define _RTL8367C_ASICDRV_MIRROR_H_ + +#include + +extern ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor); +extern ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor); +extern ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicPortMirrorPriority(rtk_uint32* pPriority); +extern ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask); +extern ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask); +extern ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror); +extern ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror); + +#endif /*#ifndef _RTL8367C_ASICDRV_MIRROR_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h new file mode 100755 index 00000000..c666a7b5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Miscellaneous functions + * + */ + +#ifndef _RTL8367C_ASICDRV_MISC_H_ +#define _RTL8367C_ASICDRV_MISC_H_ + +#include + +extern ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac); +extern ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac); +extern ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo); +extern ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength); +extern ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength); +extern ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId); +extern ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId); + +#endif /*_RTL8367C_ASICDRV_MISC_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h new file mode 100755 index 00000000..c09dc769 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : OAM related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_OAM_H_ +#define _RTL8367C_ASICDRV_OAM_H_ + +#include + +enum OAMPARACT +{ + OAM_PARFWD = 0, + OAM_PARLB, + OAM_PARDISCARD, + OAM_PARFWDCPU +}; + +enum OAMMULACT +{ + OAM_MULFWD = 0, + OAM_MULDISCARD, + OAM_MULCPU +}; + +extern ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser); +extern ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser); +extern ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer); +extern ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer); +extern ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority); +extern ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled); +#endif /*_RTL8367C_ASICDRV_OAM_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h new file mode 100755 index 00000000..e993d6ed --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : PHY related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_PHY_H_ +#define _RTL8367C_ASICDRV_PHY_H_ + +#include + +#define RTL8367C_PHY_REGNOMAX 0x1F +#define RTL8367C_PHY_EXTERNALMAX 0x7 + +#define RTL8367C_PHY_BASE 0x2000 +#define RTL8367C_PHY_EXT_BASE 0xA000 + +#define RTL8367C_PHY_OFFSET 5 +#define RTL8367C_PHY_EXT_OFFSET 9 + +#define RTL8367C_PHY_PAGE_ADDRESS 31 + + +extern ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 regData ); +extern ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32* pRegData ); +extern ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ); +extern ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ); +extern ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value); +extern ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value); + +#endif /*#ifndef _RTL8367C_ASICDRV_PHY_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h new file mode 100755 index 00000000..ad99d856 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76333 $ + * $Date: 2017-03-09 09:33:15 +0800 (¶g¥|, 09 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port security related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_PORTSECURITY_H_ +#define _RTL8367C_ASICDRV_PORTSECURITY_H_ + +#include +#include +#include + +/****************************************************************/ +/* Type Definition */ +/****************************************************************/ + +#define RTL8367C_MAC7 7 +#define RTL8367C_EXTNO 3 + +#define RTL8367C_RTCT_PAGE (11) +#define RTL8367C_RTCT_RESULT_A_REG (27) +#define RTL8367C_RTCT_RESULT_B_REG (28) +#define RTL8367C_RTCT_RESULT_C_REG (29) +#define RTL8367C_RTCT_RESULT_D_REG (30) +#define RTL8367C_RTCT_STATUS_REG (26) + +enum L2_SECURITY_BEHAVE +{ + L2_BEHAVE_FLOODING = 0, + L2_BEHAVE_DROP, + L2_BEHAVE_TRAP, + L2_BEHAVE_END +}; + +enum L2_UNDA_BEHAVE +{ + L2_UNDA_BEHAVE_FLOODING_PMASK = 0, + L2_UNDA_BEHAVE_DROP, + L2_UNDA_BEHAVE_TRAP, + L2_UNDA_BEHAVE_FLOODING, + L2_UNDA_BEHAVE_END +}; + +enum L2_SECURITY_SA_BEHAVE +{ + L2_BEHAVE_SA_FLOODING = 0, + L2_BEHAVE_SA_DROP, + L2_BEHAVE_SA_TRAP, + L2_BEHAVE_SA_COPY28051, + L2_BEHAVE_SA_END +}; + +/* enum for port current link speed */ +enum SPEEDMODE +{ + SPD_10M = 0, + SPD_100M, + SPD_1000M, + SPD_2500M +}; + +/* enum for mac link mode */ +enum LINKMODE +{ + MAC_NORMAL = 0, + MAC_FORCE, +}; + +/* enum for port current link duplex mode */ +enum DUPLEXMODE +{ + HALF_DUPLEX = 0, + FULL_DUPLEX +}; + +/* enum for port current MST mode */ +enum MSTMODE +{ + SLAVE_MODE= 0, + MASTER_MODE +}; + + +enum EXTMODE +{ + EXT_DISABLE = 0, + EXT_RGMII, + EXT_MII_MAC, + EXT_MII_PHY, + EXT_TMII_MAC, + EXT_TMII_PHY, + EXT_GMII, + EXT_RMII_MAC, + EXT_RMII_PHY, + EXT_SGMII, + EXT_HSGMII, + EXT_1000X_100FX, + EXT_1000X, + EXT_100FX, + EXT_RGMII_2, + EXT_MII_MAC_2, + EXT_MII_PHY_2, + EXT_TMII_MAC_2, + EXT_TMII_PHY_2, + EXT_RMII_MAC_2, + EXT_RMII_PHY_2, + EXT_END +}; + +enum DOSTYPE +{ + DOS_DAEQSA = 0, + DOS_LANDATTACKS, + DOS_BLATATTACKS, + DOS_SYNFINSCAN, + DOS_XMASCAN, + DOS_NULLSCAN, + DOS_SYN1024, + DOS_TCPSHORTHDR, + DOS_TCPFRAGERROR, + DOS_ICMPFRAGMENT, + DOS_END, + +}; + +typedef struct rtl8367c_port_ability_s{ + rtk_uint16 forcemode; + rtk_uint16 mstfault; + rtk_uint16 mstmode; + rtk_uint16 nway; + rtk_uint16 txpause; + rtk_uint16 rxpause; + rtk_uint16 link; + rtk_uint16 duplex; + rtk_uint16 speed; +}rtl8367c_port_ability_t; + +typedef struct rtl8367c_port_status_s{ + + rtk_uint16 lpi1000; + rtk_uint16 lpi100; + rtk_uint16 mstfault; + rtk_uint16 mstmode; + rtk_uint16 nway; + rtk_uint16 txpause; + rtk_uint16 rxpause; + rtk_uint16 link; + rtk_uint16 duplex; + rtk_uint16 speed; + +}rtl8367c_port_status_t; + +typedef struct rtct_result_s +{ + rtk_uint32 channelAShort; + rtk_uint32 channelBShort; + rtk_uint32 channelCShort; + rtk_uint32 channelDShort; + + rtk_uint32 channelAOpen; + rtk_uint32 channelBOpen; + rtk_uint32 channelCOpen; + rtk_uint32 channelDOpen; + + rtk_uint32 channelAMismatch; + rtk_uint32 channelBMismatch; + rtk_uint32 channelCMismatch; + rtk_uint32 channelDMismatch; + + rtk_uint32 channelALinedriver; + rtk_uint32 channelBLinedriver; + rtk_uint32 channelCLinedriver; + rtk_uint32 channelDLinedriver; + + rtk_uint32 channelALen; + rtk_uint32 channelBLen; + rtk_uint32 channelCLen; + rtk_uint32 channelDLen; +} rtl8367c_port_rtct_result_t; + + +/****************************************************************/ +/* Driver Proto Type Definition */ +/****************************************************************/ +extern ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior); +extern ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior); +extern ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior); +extern ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior); +extern ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior); +extern ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior); +extern ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 block); +extern ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 *pBlock); +extern ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus); +extern ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode); +extern ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop); +extern ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop); +extern ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable); +extern ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask); +extern ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult); +extern ret_t rtl8367c_sdsReset(rtk_uint32 id); +extern ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink); +extern ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state); +extern ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState); + +#endif /*_RTL8367C_ASICDRV_PORTSECURITY_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h new file mode 100755 index 00000000..e23d88e8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port isolation related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_PORTISOLATION_H_ +#define _RTL8367C_ASICDRV_PORTISOLATION_H_ + +#include + +extern ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask); +extern ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask); +extern ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid); +extern ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid); + +#endif /*_RTL8367C_ASICDRV_PORTISOLATION_H_*/ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h new file mode 100755 index 00000000..26042bfa --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Qos related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_QOS_H_ +#define _RTL8367C_ASICDRV_QOS_H_ + +#include + +#define RTL8367C_DECISIONPRIMAX 0xFF + +/* enum Priority Selection Types */ +enum PRIDECISION +{ + PRIDEC_PORT = 0, + PRIDEC_ACL, + PRIDEC_DSCP, + PRIDEC_1Q, + PRIDEC_1AD, + PRIDEC_CVLAN, + PRIDEC_DA, + PRIDEC_SA, + PRIDEC_END, +}; + +/* enum Priority Selection Index */ +enum RTL8367C_PRIDEC_TABLE +{ + PRIDEC_IDX0 = 0, + PRIDEC_IDX1, + PRIDEC_IDX_END, +}; + +enum RTL8367C_DOT1P_PRISEL +{ + DOT1P_PRISEL_USER = 0, + DOT1P_PRISEL_TAG, + DOT1P_PRISEL_END +}; + +enum RTL8367C_DSCP_PRISEL +{ + DSCP_PRISEL_INTERNAL = 0, + DSCP_PRISEL_DSCP, + DSCP_PRISEL_USER , + DSCP_PRISEL_END +}; + + +extern ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ); +extern ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ); +extern ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type); +extern ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType); +extern ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ); +extern ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ); + +extern ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ); +extern ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ); +extern ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ); +extern ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ); +extern ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ); +extern ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ); +extern ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri); +extern ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri); +extern ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32 qid ); +extern ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32* pQid); +extern ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 qnum ); +extern ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pQnum ); + +extern ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type); +extern ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType); +extern ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp); +extern ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp); + +extern ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ); +extern ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ); + +#endif /*#ifndef _RTL8367C_ASICDRV_QOS_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h new file mode 100755 index 00000000..cde970b6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RLDP related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_RLDP_H_ +#define _RTL8367C_ASICDRV_RLDP_H_ + +#include +#include + +extern ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src); +extern ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc); +extern ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); +extern ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); +extern ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); +extern ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); +extern ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed); +extern ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed); +extern ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask); + + +extern ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber); +extern ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair); +extern ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled); + +extern ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask); + +extern ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask); + +extern ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled); + +#endif /*_RTL8367C_ASICDRV_RLDP_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h new file mode 100755 index 00000000..10c70754 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 64716 $ + * $Date: 2015-12-31 16:31:55 +0800 (¶g¥|, 31 ¤Q¤G¤ë 2015) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RMA related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_RMA_H_ +#define _RTL8367C_ASICDRV_RMA_H_ + +#include + +#define RTL8367C_RMAMAX 0x2F + +enum RTL8367C_RMAOP +{ + RMAOP_FORWARD = 0, + RMAOP_TRAP_TO_CPU, + RMAOP_DROP, + RMAOP_FORWARD_EXCLUDE_CPU, + RMAOP_END +}; + + +typedef struct rtl8367c_rma_s{ + + rtk_uint16 operation; + rtk_uint16 discard_storm_filter; + rtk_uint16 trap_priority; + rtk_uint16 keep_format; + rtk_uint16 vlan_leaky; + rtk_uint16 portiso_leaky; + +}rtl8367c_rma_t; + + +extern ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg); + +#endif /*#ifndef _RTL8367C_ASICDRV_RMA_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h new file mode 100755 index 00000000..919a4ca6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Packet Scheduling related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_SCHEDULING_H_ +#define _RTL8367C_ASICDRV_SCHEDULING_H_ + +#include + +#define RTL8367C_QWEIGHTMAX 0x7F +#define RTL8367C_PORT_QUEUE_METER_INDEX_MAX 7 + +/* enum for queue type */ +enum QUEUETYPE +{ + QTYPE_STRICT = 0, + QTYPE_WFQ, +}; +extern ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token); +extern ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token); +extern ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx); +extern ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx); +extern ret_t rtl8367c_setAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx); +extern ret_t rtl8367c_getAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *ppridx); +extern ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable); +extern ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable); +extern ret_t rtl8367c_setAsicPprEnable(rtk_uint32 port, rtk_uint32 pprEnable); +extern ret_t rtl8367c_getAsicPprEnable(rtk_uint32 port, rtk_uint32 *pprEnable); + +extern ret_t rtl8367c_setAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 weight ); +extern ret_t rtl8367c_getAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 *weight ); +extern ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize); +extern ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize); + +extern ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType); +extern ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType); +extern ret_t rtl8367c_setAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx, rtk_uint32 apridx ); +extern ret_t rtl8367c_getAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* ppridx, rtk_uint32* apridx ); +extern ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate); +extern ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate); +extern ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg); +extern ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg); + +#endif /*_RTL8367C_ASICDRV_SCHEDULING_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h new file mode 100755 index 00000000..3865b522 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Storm control filtering related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_STORM_H_ +#define _RTL8367C_ASICDRV_STORM_H_ + +#include + +extern ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask); + + +#endif /*_RTL8367C_ASICDRV_STORM_H_*/ + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h new file mode 100755 index 00000000..5a6a4a83 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : SVLAN related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_SVLAN_H_ +#define _RTL8367C_ASICDRV_SVLAN_H_ + +#include + +#define RTL8367C_C2SIDXNO 128 +#define RTL8367C_C2SIDXMAX (RTL8367C_C2SIDXNO-1) +#define RTL8367C_MC2SIDXNO 32 +#define RTL8367C_MC2SIDXMAX (RTL8367C_MC2SIDXNO-1) +#define RTL8367C_SP2CIDXNO 128 +#define RTL8367C_SP2CMAX (RTL8367C_SP2CIDXNO-1) + +#define RTL8367C_SVLAN_MEMCONF_LEN 4 +#define RTL8367C_SVLAN_MC2S_LEN 5 +#define RTL8367C_SVLAN_SP2C_LEN 2 + +enum RTL8367C_SPRISEL +{ + SPRISEL_INTERNALPRI = 0, + SPRISEL_CTAGPRI, + SPRISEL_VSPRI, + SPRISEL_PBPRI, + SPRISEL_END +}; + +enum RTL8367C_SUNACCEPT +{ + SUNACCEPT_DROP = 0, + SUNACCEPT_TRAP, + SUNACCEPT_SVLAN, + SUNACCEPT_END +}; + +enum RTL8367C_SVLAN_MC2S_MODE +{ + SVLAN_MC2S_MODE_MAC = 0, + SVLAN_MC2S_MODE_IP, + SVLAN_MC2S_MODE_END +}; + + +typedef struct rtl8367c_svlan_memconf_s{ + + rtk_uint16 vs_member:11; + rtk_uint16 vs_untag:11; + + rtk_uint16 vs_fid_msti:4; + rtk_uint16 vs_priority:3; + rtk_uint16 vs_force_fid:1; + rtk_uint16 reserved:8; + + rtk_uint16 vs_svid:12; + rtk_uint16 vs_efiden:1; + rtk_uint16 vs_efid:3; + + +}rtl8367c_svlan_memconf_t; + + +typedef struct rtl8367c_svlan_mc2s_s{ + + rtk_uint16 valid:1; + rtk_uint16 format:1; + rtk_uint16 svidx:6; + rtk_uint32 sdata; + rtk_uint32 smask; +}rtl8367c_svlan_mc2s_t; + + +typedef struct rtl8367c_svlan_s2c_s{ + + rtk_uint16 valid:1; + rtk_uint16 svidx:6; + rtk_uint16 dstport:4; + rtk_uint32 vid:12; +}rtl8367c_svlan_s2c_t; + +extern ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority); +extern ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index); +extern ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex); + +extern ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); +extern ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); + +extern ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel); +extern ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel); +extern ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType); +extern ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType); +extern ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask); +extern ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask); +extern ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx); +extern ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx); +extern ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); +extern ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); +extern ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); +extern ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); +extern ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index); +extern ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex); +extern ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index); +extern ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex); +extern ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type); +extern ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType); + + +#endif /*#ifndef _RTL8367C_ASICDRV_SVLAN_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h new file mode 100755 index 00000000..2e3a6828 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port trunking related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_TRUNKING_H_ +#define _RTL8367C_ASICDRV_TRUNKING_H_ + +#include + +#define RTL8367C_MAX_TRUNK_GID (2) +#define RTL8367C_TRUNKING_PORTNO (4) +#define RTL8367C_TRUNKING1_PORTN0 (2) +#define RTL8367C_TRUNKING_HASHVALUE_MAX (15) + +extern ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask); +extern ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel); +extern ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel); + +extern ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* pPortmask); + +extern ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId); +extern ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId); +extern ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId); +extern ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId); + +#endif /*_RTL8367C_ASICDRV_TRUNKING_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h new file mode 100755 index 00000000..d142d25c --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Unkown multicast related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ +#define _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ + +#include + +enum L2_UNKOWN_MULTICAST_BEHAVE +{ + L2_UNKOWN_MULTICAST_FLOODING = 0, + L2_UNKOWN_MULTICAST_DROP, + L2_UNKOWN_MULTICAST_TRAP, + L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA, + L2_UNKOWN_MULTICAST_END +}; + +enum L3_UNKOWN_MULTICAST_BEHAVE +{ + L3_UNKOWN_MULTICAST_FLOODING = 0, + L3_UNKOWN_MULTICAST_DROP, + L3_UNKOWN_MULTICAST_TRAP, + L3_UNKOWN_MULTICAST_ROUTER, + L3_UNKOWN_MULTICAST_END +}; + +enum MULTICASTTYPE{ + MULTICAST_TYPE_IPV4 = 0, + MULTICAST_TYPE_IPV6, + MULTICAST_TYPE_L2, + MULTICAST_TYPE_END +}; + +extern ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); +extern ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); +extern ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); +extern ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); +extern ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); +extern ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); +extern ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority); + +#endif /*_RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_*/ + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h new file mode 100755 index 00000000..61848650 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : VLAN related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_VLAN_H_ +#define _RTL8367C_ASICDRV_VLAN_H_ + +/****************************************************************/ +/* Header File inclusion */ +/****************************************************************/ +#include + +/****************************************************************/ +/* Constant Definition */ +/****************************************************************/ +#define RTL8367C_PROTOVLAN_GIDX_MAX 3 +#define RTL8367C_PROTOVLAN_GROUPNO 4 + +#define RTL8367C_VLAN_BUSY_CHECK_NO (10) + +#define RTL8367C_VLAN_MBRCFG_LEN (4) +#define RTL8367C_VLAN_4KTABLE_LEN (3) + +/****************************************************************/ +/* Type Definition */ +/****************************************************************/ +typedef struct VLANCONFIGUSER +{ + rtk_uint16 evid; + rtk_uint16 mbr; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; +}rtl8367c_vlanconfiguser; + +typedef struct USER_VLANTABLE{ + + rtk_uint16 vid; + rtk_uint16 mbr; + rtk_uint16 untag; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; + rtk_uint16 ivl_svl; + +}rtl8367c_user_vlan4kentry; + +typedef enum +{ + FRAME_TYPE_BOTH = 0, + FRAME_TYPE_TAGGED_ONLY, + FRAME_TYPE_UNTAGGED_ONLY, + FRAME_TYPE_MAX_BOUND +} rtl8367c_accframetype; + +typedef enum +{ + EG_TAG_MODE_ORI = 0, + EG_TAG_MODE_KEEP, + EG_TAG_MODE_PRI_TAG, + EG_TAG_MODE_REAL_KEEP, + EG_TAG_MODE_END +} rtl8367c_egtagmode; + +typedef enum +{ + PPVLAN_FRAME_TYPE_ETHERNET = 0, + PPVLAN_FRAME_TYPE_LLC, + PPVLAN_FRAME_TYPE_RFC1042, + PPVLAN_FRAME_TYPE_END +} rtl8367c_provlan_frametype; + +enum RTL8367C_STPST +{ + STPST_DISABLED = 0, + STPST_BLOCKING, + STPST_LEARNING, + STPST_FORWARDING +}; + +enum RTL8367C_RESVIDACT +{ + RES_VID_ACT_UNTAG = 0, + RES_VID_ACT_TAG, + RES_VID_ACT_END +}; + +typedef struct +{ + rtl8367c_provlan_frametype frameType; + rtk_uint32 etherType; +} rtl8367c_protocolgdatacfg; + +typedef struct +{ + rtk_uint32 valid; + rtk_uint32 vlan_idx; + rtk_uint32 priority; +} rtl8367c_protocolvlancfg; + +extern ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); +extern ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); +extern ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); +extern ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); +extern ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType); +extern ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType); +extern ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode); +extern ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode); +extern ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri); +extern ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri); +extern ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); +extern ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); +extern ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); +extern ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); +extern ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled); + +extern ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid); +extern ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid); +extern ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state); +extern ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState); +extern ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled); +extern ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask); +extern ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action); +extern ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action); +extern ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled); +extern ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_resetVlan(void); + +#endif /*#ifndef _RTL8367C_ASICDRV_VLAN_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h new file mode 100755 index 00000000..676ca8ed --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h @@ -0,0 +1,596 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Regsiter MACRO related definition + * + */ + +#ifndef _RTL8367C_BASE_H_ +#define _RTL8367C_BASE_H_ + +#include + +/* (16'h0000) port_reg */ + +#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE RTL8367C_REG_PKTGEN_PORT0_TIMER +#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_REG(port) (RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE + (port << 5)) + +#define RTL8367C_PORT_MISC_CFG_BASE RTL8367C_REG_PORT0_MISC_CFG +#define RTL8367C_PORT_MISC_CFG_REG(port) (RTL8367C_PORT_MISC_CFG_BASE + (port << 5)) +#define RTL8367C_1QREMARK_ENABLE_OFFSET RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET +#define RTL8367C_1QREMARK_ENABLE_MASK RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK + +#define RTL8367C_INGRESSBW_PORT_IFG_MASK RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK +#define RTL8367C_VLAN_EGRESS_MDOE_MASK RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK +#define RTL8367C_SPECIALCONGEST_SUSTAIN_TIMER_MASK RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK + +#define RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 +#define RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port) (RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE + (port << 5)) + +#define RTL8367C_PORT_SMALL_IPG_REG(port) (RTL8367C_REG_PORT0_MISC_CFG + (port*0x20)) + +#define RTL8367C_PORT_EEE_CFG_BASE RTL8367C_REG_PORT0_EEECFG +#define RTL8367C_PORT_EEE_CFG_REG(port) (RTL8367C_REG_PORT0_EEECFG + (port << 5)) +#define RTL8367C_PORT_EEE_100M_OFFSET RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET +#define RTL8367C_PORT_EEE_100M_MASK RTL8367C_PORT0_EEECFG_EEE_100M_MASK +#define RTL8367C_PORT_EEE_GIGA_OFFSET RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET +#define RTL8367C_PORT_EEE_GIGA_MASK RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK + + +/* (16'h0200) outq_reg */ + +#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON +#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(queue) (RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE + queue) +#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK + +#define RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON +#define RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(PORT) (RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE + PORT) +#define RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK + +#define RTL8367C_FLOWCTRL_PORT_GAP_REG RTL8367C_REG_FLOWCTRL_PORT_GAP +#define RTL8367C_FLOWCTRL_QUEUE_GAP_REG RTL8367C_REG_FLOWCTRL_QUEUE_GAP +#define RTL8367C_FLOWCTRL_PORT_QEMPTY_REG RTL8367C_REG_PORT_QEMPTY + +/* (16'h0300) sch_reg */ + +#define RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE + +#define RTL8367C_SCHEDULE_QUEUE_TYPE_BASE RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port) (RTL8367C_SCHEDULE_QUEUE_TYPE_BASE + (port >> 1)) +#define RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) (((port & 0x1) << 3) + queue) +#define RTL8367C_SCHEDULE_QUEUE_TYPE_MASK(port, queue) RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) + +#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT +#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, queue) (RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE + (port << 3) + queue) + +#define RTL8367C_SCHEDULE_APR_CTRL_REG RTL8367C_REG_SCHEDULE_APR_CTRL0 +#define RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port) (port) +#define RTL8367C_SCHEDULE_APR_CTRL_MASK(port) (1 << RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port)) + +#define RTL8367C_SCHEDULE_PORT_APR_METER_BASE RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 +#define RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, queue) (RTL8367C_SCHEDULE_PORT_APR_METER_BASE + (port << 2) + (queue / 5)) +#define RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue) (3 * (queue % 5)) +#define RTL8367C_SCHEDULE_PORT_APR_METER_MASK(queue) (RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK << RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue)) + +#define RTL8367C_PORT_EGRESSBW_LSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL0 +#define RTL8367C_PORT_EGRESSBW_LSB_REG(port) (RTL8367C_PORT_EGRESSBW_LSB_BASE + (port << 1)) + +#define RTL8367C_PORT_EGRESSBW_MSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL1 +#define RTL8367C_PORT_EGRESSBW_MSB_REG(port) (RTL8367C_PORT_EGRESSBW_MSB_BASE + (port << 1)) + +/* (16'h0500) table_reg */ + +#define RTL8367C_TABLE_ACCESS_CTRL_REG RTL8367C_REG_TABLE_ACCESS_CTRL + +#define RTL8367C_TABLE_ACCESS_ADDR_REG RTL8367C_REG_TABLE_ACCESS_ADDR + +#define RTL8367C_TABLE_ACCESS_STATUS_REG RTL8367C_REG_TABLE_LUT_ADDR + +#define RTL8367C_TABLE_ACCESS_WRDATA_BASE RTL8367C_REG_TABLE_WRITE_DATA0 +#define RTL8367C_TABLE_ACCESS_WRDATA_REG(index) (RTL8367C_TABLE_ACCESS_WRDATA_BASE + index) + +#define RTL8367C_TABLE_ACCESS_RDDATA_BASE RTL8367C_REG_TABLE_READ_DATA0 +#define RTL8367C_TABLE_ACCESS_RDDATA_REG(index) (RTL8367C_TABLE_ACCESS_RDDATA_BASE + index) + + + +/* (16'h0600) acl_reg */ + +#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 +#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(template) (RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE + template * 0x4) +#define RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field) ((field & 0x01) <<3) +#define RTL8367C_ACL_TEMPLATE_FIELD_MASK(field) (0x3F << RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field)) + +#define RTL8367C_ACL_ACTION_CTRL_BASE RTL8367C_REG_ACL_ACTION_CTRL0 +#define RTL8367C_ACL_ACTION_CTRL_REG(rule) (RTL8367C_ACL_ACTION_CTRL_BASE + (rule >> 1)) +#define RTL8367C_ACL_ACTION_CTRL2_BASE RTL8367C_REG_ACL_ACTION_CTRL32 +#define RTL8367C_ACL_ACTION_CTRL2_REG(rule) (RTL8367C_ACL_ACTION_CTRL2_BASE + ((rule-64) >> 1)) + +#define RTL8367C_ACL_OP_NOT_OFFSET(rule) (6 + ((rule & 0x1) << 3)) +#define RTL8367C_ACL_OP_NOT_MASK(rule) (1 << RTL8367C_ACL_OP_NOT_OFFSET(rule)) +#define RTL8367C_ACL_OP_ACTION_OFFSET(rule) ((rule & 0x1) << 3) +#define RTL8367C_ACL_OP_ACTION_MASK(rule) (0x3F << RTL8367C_ACL_OP_ACTION_OFFSET(rule)) + +#define RTL8367C_ACL_ENABLE_REG RTL8367C_REG_ACL_ENABLE +#define RTL8367C_ACL_UNMATCH_PERMIT_REG RTL8367C_REG_ACL_UNMATCH_PERMIT + +/* (16'h0700) cvlan_reg */ + +#define RTL8367C_VLAN_PVID_CTRL_BASE RTL8367C_REG_VLAN_PVID_CTRL0 +#define RTL8367C_VLAN_PVID_CTRL_REG(port) (RTL8367C_VLAN_PVID_CTRL_BASE + (port >> 1)) +#define RTL8367C_PORT_VIDX_OFFSET(port) ((port &1)<<3) +#define RTL8367C_PORT_VIDX_MASK(port) (RTL8367C_PORT0_VIDX_MASK << RTL8367C_PORT_VIDX_OFFSET(port)) + +#define RTL8367C_VLAN_PPB_VALID_BASE RTL8367C_REG_VLAN_PPB0_VALID +#define RTL8367C_VLAN_PPB_VALID_REG(item) (RTL8367C_VLAN_PPB_VALID_BASE + (item << 3)) + +#define RTL8367C_VLAN_PPB_CTRL_BASE RTL8367C_REG_VLAN_PPB0_CTRL0 +#define RTL8367C_VLAN_PPB_CTRL_REG(item, port) (RTL8367C_VLAN_PPB_CTRL_BASE + (item << 3) + (port / 3) ) +#define RTL8367C_VLAN_PPB_CTRL_OFFSET(port) ((port % 3) * 5) +#define RTL8367C_VLAN_PPB_CTRL_MASK(port) (RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK << RTL8367C_VLAN_PPB_CTRL_OFFSET(port)) + +#define RTL8367C_VLAN_PPB_FRAMETYPE_BASE RTL8367C_REG_VLAN_PPB0_CTRL2 +#define RTL8367C_VLAN_PPB_FRAMETYPE_REG(item) (RTL8367C_VLAN_PPB_FRAMETYPE_BASE + (item << 3)) +#define RTL8367C_VLAN_PPB_FRAMETYPE_MASK RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK + +#define RTL8367C_VLAN_PPB_ETHERTYPR_BASE RTL8367C_REG_VLAN_PPB0_CTRL3 +#define RTL8367C_VLAN_PPB_ETHERTYPR_REG(item) (RTL8367C_VLAN_PPB_ETHERTYPR_BASE + (item << 3)) + +#define RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 + + +#define RTL8367C_VLAN_CTRL_REG RTL8367C_REG_VLAN_CTRL + +#define RTL8367C_VLAN_INGRESS_REG RTL8367C_REG_VLAN_INGRESS + +#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 +#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port) (RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE + (port >> 3)) +#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port) (RTL8367C_PORT0_FRAME_TYPE_MASK << ((port & 0x7) << 1)) + +#define RTL8367C_PORT_EFID_BASE RTL8367C_REG_PORT_EFID_CTRL0 +#define RTL8367C_PORT_EFID_REG(port) (RTL8367C_PORT_EFID_BASE + (port >> 2)) +#define RTL8367C_PORT_EFID_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_PORT_EFID_MASK(port) (RTL8367C_PORT0_EFID_MASK << RTL8367C_PORT_EFID_OFFSET(port)) + +#define RTL8367C_PORT_PBFIDEN_REG RTL8367C_REG_PORT_PBFIDEN + +#define RTL8367C_PORT_PBFID_BASE RTL8367C_REG_PORT0_PBFID +#define RTL8367C_PORT_PBFID_REG(port) (RTL8367C_PORT_PBFID_BASE + port) + +/* (16'h0800) dpm_reg */ + +#define RTL8367C_RMA_CTRL_BASE RTL8367C_REG_RMA_CTRL00 + + +#define RTL8367C_VLAN_PORTBASED_PRIORITY_BASE RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port) (RTL8367C_VLAN_PORTBASED_PRIORITY_BASE + (port >> 2)) +#define RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port)) + +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, item) (RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE + (item << 2)+ (port>>2)) +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port) ((port & 0x3) <<2) +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port) (RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK << RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port)) + +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(pri) (RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE + (pri >> 2)) +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(pri) (0x7 << RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri)) + +#define RTL8367C_QOS_DSCP_TO_PRIORITY_BASE RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 +#define RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp) (RTL8367C_QOS_DSCP_TO_PRIORITY_BASE + (dscp >> 2)) +#define RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp) ((dscp & 0x3) << 2) +#define RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp) (0x7 << RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp)) + +#define RTL8367C_QOS_PORTBASED_PRIORITY_BASE RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_REG(port) (RTL8367C_QOS_PORTBASED_PRIORITY_BASE + (port >> 2)) +#define RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port)) + +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE + (src >> 1)) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_OFFSET(src) ((src & 1) << 3) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) + +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE + (src >> 1)) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src) ((src & 1) << 3) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) + +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX(port) (1 << port) + +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(pri) (RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE + (pri >> 2)) +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(pri) (RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK << RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri)) + +#define RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG RTL8367C_REG_QOS_TRAP_PRIORITY0 + +#define RTL8367C_QOS_TRAP_PRIORITY_CTRL1_REG RTL8367C_REG_QOS_TRAP_PRIORITY1 + +#define RTL8367C_QOS_DSCP_TO_DSCP_BASE RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 +#define RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp) (RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 + (dscp >> 1)) +#define RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp) ((dscp & 0x1) << 8) +#define RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp) (0x3F << RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp)) + +#define RTL8367C_UNUCAST_FLOADING_PMSK_REG RTL8367C_REG_UNDA_FLOODING_PMSK + +#define RTL8367C_UNMCAST_FLOADING_PMSK_REG RTL8367C_REG_UNMCAST_FLOADING_PMSK + +#define RTL8367C_BCAST_FLOADING_PMSK_REG RTL8367C_REG_BCAST_FLOADING_PMSK + +#define RTL8367C_PORT_ISOLATION_PORT_MASK_BASE RTL8367C_REG_PORT_ISOLATION_PORT0_MASK +#define RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port) (RTL8367C_PORT_ISOLATION_PORT_MASK_BASE + port) + +#define RTL8367C_FORCE_CTRL_REG RTL8367C_REG_FORCE_CTRL + +#define RTL8367C_SOURCE_PORT_BLOCK_REG RTL8367C_REG_SOURCE_PORT_PERMIT + +#define RTL8367C_IPMCAST_VLAN_LEAKY_REG RTL8367C_REG_IPMCAST_VLAN_LEAKY + +#define RTL8367C_IPMCAST_PORTISO_LEAKY_REG RTL8367C_REG_IPMCAST_PORTISO_LEAKY + +#define RTL8367C_PORT_SECURIT_CTRL_REG RTL8367C_REG_PORT_SECURITY_CTRL + +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE + (port >> 3)) +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port)) + +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE + (port >> 3)) +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port)) + +#define RTL8367C_UNKNOWN_L2_MULTICAST_BASE RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 +#define RTL8367C_UNKNOWN_L2_MULTICAST_REG(port) (RTL8367C_UNKNOWN_L2_MULTICAST_BASE + (port >> 3)) +#define RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK << RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port)) + +#define RTL8367C_PORT_TRUNK_CTRL_REG RTL8367C_REG_PORT_TRUNK_CTRL +#define RTL8367C_PORT_TRUNK_HASH_MASK 0x007F + +#define RTL8367C_PORT_TRUNK_GROUP_MASK_REG RTL8367C_REG_PORT_TRUNK_GROUP_MASK +#define RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group) (group << 2) +#define RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(group) (RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group)) + +#define RTL8367C_PORT_TRUNK_FLOWCTRL_REG RTL8367C_REG_PORT_TRUNK_FLOWCTRL + +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port) (RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE + (port >> 2)) +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port) (0x7 << RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port)) + +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE + (index << 1) + (pri >> 2)) +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK << RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri)) + +#define RTL8367C_DEBUG_INFO_BASE RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 +#define RTL8367C_DEBUG_INFO_REG(port) (RTL8367C_DEBUG_INFO_BASE + (port >>1)) +#define RTL8367C_DEBUG_INFO_OFFSET(port) ((port&1)<<3) +#define RTL8367C_DEBUG_INFO_MASK(port) (RTL8367C_PORT0_DEBUG_INFO_MASK << RTL8367C_DEBUG_INFO_OFFSET(port)) + +/* (16'h0a00) l2_reg */ + +#define RTL8367C_VLAN_MSTI_BASE RTL8367C_REG_VLAN_MSTI0_CTRL0 +#define RTL8367C_VLAN_MSTI_REG(tree, port) (RTL8367C_VLAN_MSTI_BASE + (tree << 1) + (port >> 3)) +#define RTL8367C_VLAN_MSTI_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_VLAN_MSTI_MASK(port) (RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK << RTL8367C_VLAN_MSTI_OFFSET(port)) + +#define RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO +#define RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port) (RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE + port) + +#define RTL8367C_LUT_CFG_REG RTL8367C_REG_LUT_CFG + +#define RTL8367C_LUT_AGEOUT_CTRL_REG RTL8367C_REG_LUT_AGEOUT_CTRL + +#define RTL8367C_FORCE_FLUSH_REG RTL8367C_REG_FORCE_FLUSH + +#define RTL8367C_STORM_BCAST_REG RTL8367C_REG_STORM_BCAST + +#define RTL8367C_STORM_MCAST_REG RTL8367C_REG_STORM_MCAST + +#define RTL8367C_STORM_UNKNOWN_UCAST_REG RTL8367C_REG_STORM_UNKOWN_UCAST + +#define RTL8367C_STORM_UNKNOWN_MCAST_REG RTL8367C_REG_STORM_UNKOWN_MCAST + +#define RTL8367C_STORM_BCAST_METER_CTRL_BASE RTL8367C_REG_STORM_BCAST_METER_CTRL0 +#define RTL8367C_STORM_BCAST_METER_CTRL_REG(port) (RTL8367C_STORM_BCAST_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_BCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port)) + +#define RTL8367C_STORM_MCAST_METER_CTRL_BASE RTL8367C_REG_STORM_MCAST_METER_CTRL0 +#define RTL8367C_STORM_MCAST_METER_CTRL_REG(port) (RTL8367C_STORM_MCAST_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_MCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port)) + +#define RTL8367C_STORM_UNDA_METER_CTRL_BASE RTL8367C_REG_STORM_UNDA_METER_CTRL0 +#define RTL8367C_STORM_UNDA_METER_CTRL_REG(port) (RTL8367C_STORM_UNDA_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_UNDA_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port)) + +#define RTL8367C_STORM_UNMC_METER_CTRL_BASE RTL8367C_REG_STORM_UNMC_METER_CTRL0 +#define RTL8367C_STORM_UNMC_METER_CTRL_REG(port) (RTL8367C_STORM_UNMC_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_UNMC_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port)) + +#define RTL8367C_OAM_PARSER_OFFSET(port) (port*2) +#define RTL8367C_OAM_PARSER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_PARSER_OFFSET(port)) + +#define RTL8367C_OAM_MULTIPLEXER_OFFSET(port) (port*2) +#define RTL8367C_OAM_MULTIPLEXER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_MULTIPLEXER_OFFSET(port)) + +#define RTL8367C_OAM_CTRL_REG RTL8367C_REG_OAM_CTRL + +#define RTL8367C_DOT1X_PORT_ENABLE_REG RTL8367C_REG_DOT1X_PORT_ENABLE + +#define RTL8367C_DOT1X_MAC_ENABLE_REG RTL8367C_REG_DOT1X_MAC_ENABLE + +#define RTL8367C_DOT1X_PORT_AUTH_REG RTL8367C_REG_DOT1X_PORT_AUTH + +#define RTL8367C_DOT1X_PORT_OPDIR_REG RTL8367C_REG_DOT1X_PORT_OPDIR + +#define RTL8367C_DOT1X_UNAUTH_ACT_BASE RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 +#define RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_DOT1X_UNAUTH_ACT_MASK(port) (RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK << RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port)) + +#define RTL8367C_DOT1X_CFG_REG RTL8367C_REG_DOT1X_CFG + +#define RTL8367C_REG_L2_LRN_CNT_BASE RTL8367C_REG_L2_LRN_CNT_CTRL0 +#define RTL8367C_REG_L2_LRN_CNT_REG(port) (RTL8367C_REG_L2_LRN_CNT_BASE + port) + +/* (16'h0b00) mltvlan_reg */ + +#define RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 + index*5) + +/* (16'h0c00) svlan_reg */ + +#define RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 + index*3) +#define RTL8367C_SVLAN_C2SCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_C2SCFG0_CTRL0+ index*3) +#define RTL8367C_SVLAN_CFG_REG RTL8367C_REG_SVLAN_CFG + +/* (16'h0f00) hsactrl_reg */ + +#define RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 + index*2) + +/* (16'h1000) mib_reg */ + +#define RTL8367C_MIB_COUNTER_BASE_REG RTL8367C_REG_MIB_COUNTER0 + +#define RTL8367C_MIB_ADDRESS_REG RTL8367C_REG_MIB_ADDRESS + +#define RTL8367C_MIB_CTRL_REG RTL8367C_REG_MIB_CTRL0 +#define RTL8367C_MIB_PORT07_MASK (0xFF<> 4)) +#define RTL8367C_REG_METER_EXCEED_INDICATOR_OFFSET(meter) (meter & 0xF) + +/* (16'h1200) swcore_reg */ + +#define RTL8367C_VS_TPID_REG RTL8367C_REG_VS_TPID + +#define RTL8367C_SWITCH_MAC_BASE RTL8367C_REG_SWITCH_MAC0 + +#define RTL8367C_REMARKING_CTRL_REG RTL8367C_REG_SWITCH_CTRL0 + +#define RTL8367C_QOS_DSCP_REMARK_BASE RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 +#define RTL8367C_QOS_DSCP_REMARK_REG(pri) (RTL8367C_QOS_DSCP_REMARK_BASE + (pri >> 1)) +#define RTL8367C_QOS_DSCP_REMARK_OFFSET(pri) (((pri) & 0x1) << 3) +#define RTL8367C_QOS_DSCP_REMARK_MASK(pri) (0x3F << RTL8367C_QOS_DSCP_REMARK_OFFSET(pri)) + +#define RTL8367C_QOS_1Q_REMARK_BASE RTL8367C_REG_QOS_1Q_REMARK_CTRL0 +#define RTL8367C_QOS_1Q_REMARK_REG(pri) (RTL8367C_QOS_1Q_REMARK_BASE + (pri >> 2)) +#define RTL8367C_QOS_1Q_REMARK_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_1Q_REMARK_MASK(pri) (0x7 << RTL8367C_QOS_1Q_REMARK_OFFSET(pri)) + +#define RTL8367C_PTKGEN_PAYLOAD_CTRL0_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL0 + +#define RTL8367C_PTKGEN_PAYLOAD_CTRL1_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL1 + +#define RTL8367C_SVLAN_UPLINK_PORTMASK_REG RTL8367C_REG_SVLAN_UPLINK_PORTMASK + +#define RTL8367C_CPU_PORT_MASK_REG RTL8367C_REG_CPU_PORT_MASK + +#define RTL8367C_CPU_CTRL_REG RTL8367C_REG_CPU_CTRL + +#define RTL8367C_MIRROR_CTRL_REG RTL8367C_REG_MIRROR_CTRL + + +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port) (RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE + (port >> 1)) +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_MASK(port) (RTL8367C_PORT0_QUEUE_MASK_MASK << RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)) + + +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE + port) +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK + +#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX +#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE + port) +#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK + +#define RTL8367C_FIELD_SELECTOR_REG(index) (RTL8367C_REG_FIELD_SELECTOR0 + index) +#define RTL8367C_FIELD_SELECTOR_ENABLE_OFFSET RTL8367C_FIELD_SELECTOR0_ENABLE_OFFSET +#define RTL8367C_FIELD_SELECTOR_ENABLE_MASK RTL8367C_FIELD_SELECTOR0_ENABLE_MASK +#define RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET +#define RTL8367C_FIELD_SELECTOR_FORMAT_MASK RTL8367C_FIELD_SELECTOR0_FORMAT_MASK +#define RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET +#define RTL8367C_FIELD_SELECTOR_OFFSET_MASK RTL8367C_FIELD_SELECTOR0_OFFSET_MASK + +/* (16'h1300) chip_reg*/ + +/* (16'h1400) mtrpool_reg */ +#define RTL8367C_METER_RATE_BASE RTL8367C_REG_METER0_RATE_CTRL0 +#define RTL8367C_METER_RATE_REG(meter) ((meter << 1) + RTL8367C_METER_RATE_BASE) + +#define RTL8367C_METER_BUCKET_SIZE_BASE RTL8367C_REG_METER0_BUCKET_SIZE +#define RTL8367C_METER_BUCKET_SIZE_REG(meter) (RTL8367C_METER_BUCKET_SIZE_BASE + meter) + +#define RTL8367C_LEAKY_BUCKET_TICK_REG RTL8367C_REG_METER_CTRL0 +#define RTL8367C_LEAKY_BUCKET_TICK_OFFSET RTL8367C_METER_TICK_OFFSET +#define RTL8367C_LEAKY_BUCKET_TICK_MASK RTL8367C_METER_TICK_MASK + +#define RTL8367C_LEAKY_BUCKET_TOKEN_REG RTL8367C_REG_METER_CTRL1 +#define RTL8367C_LEAKY_BUCKET_TOKEN_OFFSET RTL8367C_METER_CTRL1_OFFSET +#define RTL8367C_LEAKY_BUCKET_TOKEN_MASK RTL8367C_METER_CTRL1_MASK + +#define RTL8367C_METER_OVERRATE_INDICATOR_BASE RTL8367C_REG_METER_OVERRATE_INDICATOR0 +#define RTL8367C_METER_OVERRATE_INDICATOR_REG(meter) (RTL8367C_METER_OVERRATE_INDICATOR_BASE + (meter >> 4)) +#define RTL8367C_METER_EXCEED_OFFSET(meter) (meter & 0xF) +#define RTL8367C_METER_EXCEED_MASK(meter) (1 << RTL8367C_METER_EXCEED_OFFSET(meter)) + +#define RTL8367C_METER_IFG_CTRL_BASE RTL8367C_REG_METER_IFG_CTRL0 +#define RTL8367C_METER_IFG_CTRL_REG(meter) (RTL8367C_METER_IFG_CTRL_BASE + (meter >> 4)) +#define RTL8367C_METER_IFG_OFFSET(meter) (meter & 0xF) +#define RTL8367C_METER_IFG_MASK(meter) (1 << RTL8367C_METER_IFG_OFFSET(meter)) + +#define RTL8367C_FLOWCTRL_CTRL_REG RTL8367C_REG_FLOWCTRL_CTRL0 + +/* (16'h1800)8051_RLDP_EEE_reg */ +#define RTL8367C_EEELLDP_CTRL0_REG RTL8367C_REG_EEELLDP_CTRL0 + +#define RTL8367C_EEELLDP_CTRL1_REG RTL8367C_REG_EEELLDP_CTRL1 + +#define RTL8367C_EEELLDP_PMSK_REG RTL8367C_REG_EEELLDP_PMSK + +#define RTL8367C_EEELLDP_TX_FRAMEU_REG_BASE RTL8367C_REG_EEELLDP_FRAMEU00 + +#define RTL8367C_EEELLDP_TX_CAP_FRAMEL_REG_BASE RTL8367C_REG_EEELLDP_CAP_FRAMEL00 + +#define RTL8367C_EEELLDP_RX_VALUE_PORT_BASE RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 +#define RTL8367C_EEELLDP_RX_VALUE_PORT_REG(port) (RTL8367C_EEELLDP_RX_VALUE_PORT_BASE + (port * 9)) + +#define RTL8367C_RLDP_CTRL0_REG RTL8367C_REG_RLDP_CTRL0 +#define RTL8367C_RLDP_MODE_OFFSET 14 + +#define RTL8367C_RLDP_RETRY_COUNT_REG RTL8367C_REG_RLDP_CTRL1 + +#define RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG RTL8367C_REG_RLDP_CTRL2 + +#define RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG RTL8367C_REG_RLDP_CTRL3 + +#define RTL8367C_RLDP_TX_PMSK_REG RTL8367C_REG_RLDP_CTRL4 + +#define RTL8367C_RLDP_RAND_NUM_REG_BASE RTL8367C_REG_RLDP_RAND_NUM0 + +#define RTL8367C_RLDP_MAGIC_NUM_REG_BASE RTL8367C_REG_RLDP_MAGIC_NUM0 + +#define RTL8367C_RLDP_LOOP_PMSK_REG RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR + +#define RTL8367C_RLDP_LOOP_PORT_BASE RTL8367C_REG_RLDP_LOOP_PORT_REG0 +#define RTL8367C_RLDP_LOOP_PORT_REG(port) (RTL8367C_RLDP_LOOP_PORT_BASE + (port >> 1)) +#define RTL8367C_RLDP_LOOP_PORT_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_RLDP_LOOP_PORT_MASK(port) (RTL8367C_RLDP_LOOP_PORT_00_MASK << RTL8367C_RLDP_LOOP_PORT_OFFSET(port)) + +#define RTL8367C_PAGEMETER_PORT_BASE RTL8367C_REG_PAGEMETER_PORT0_CTRL0 +#define RTL8367C_PAGEMETER_PORT_REG(port) (RTL8367C_PAGEMETER_PORT_BASE + 0x20*port) + +#define RTL8367C_HIGHPRI_INDICATOR_REG RTL8367C_REG_HIGHPRI_INDICATOR +#define RTL8367C_PORT_INDICATOR_OFFSET(port) (port) +#define RTL8367C_PORT_INDICATOR_MASK(port) (RTL8367C_PORT0_INDICATOR_MASK << RTL8367C_PORT_INDICATOR_OFFSET(port)) + +#define RTL8367C_HIGHPRI_CFG_REG RTL8367C_REG_HIGHPRI_CFG + +#define RTL8367C_EAV_PRIORITY_REMAPPING_BASE RTL8367C_REG_EAV_CTRL1 +#define RTL8367C_EAV_PRIORITY_REMAPPING_REG(pri) (RTL8367C_EAV_PRIORITY_REMAPPING_BASE + (pri >> 2)) +#define RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) * RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET) +#define RTL8367C_EAV_PRIORITY_REMAPPING_MASK(pri) (RTL8367C_REMAP_EAV_PRI0_REGEN_MASK << RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri)) + +#define RTL8367C_EEEP_CFG_BASE RTL8367C_REG_PORT0_EEECFG +#define RTL8367C_EEEP_CFG_REG(port) (RTL8367C_EEEP_CFG_BASE + (port*0x20)) + +#define RTL8367C_PKG_CFG_BASE RTL8367C_REG_PKTGEN_PORT0_CTRL +#define RTL8367C_PKG_CFG_REG(port) (RTL8367C_PKG_CFG_BASE + (port*0x20)) + +#define RTL8367C_PKG_DA_BASE RTL8367C_REG_PKTGEN_PORT0_DA0 +#define RTL8367C_PKG_DA_REG(port) (RTL8367C_PKG_DA_BASE + (port*0x20)) + +#define RTL8367C_PKG_SA_BASE RTL8367C_REG_PKTGEN_PORT0_SA0 +#define RTL8367C_PKG_SA_REG(port) (RTL8367C_PKG_SA_BASE + (port*0x20)) + +#define RTL8367C_PKG_NUM_BASE RTL8367C_REG_PKTGEN_PORT0_COUNTER0 +#define RTL8367C_PKG_NUM_REG(port) (RTL8367C_PKG_NUM_BASE + (port*0x20)) + +#define RTL8367C_PKG_LENGTH_BASE RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH +#define RTL8367C_PKG_LENGTH_REG(port) (RTL8367C_PKG_LENGTH_BASE + (port*0x20)) + +/* (16'h1c00)IGMP_MLD_reg */ +#define RTL8367C_IGMP_GROUP_USAGE_BASE RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 +#define RTL8367C_IGMP_GROUP_USAGE_REG(idx) (RTL8367C_IGMP_GROUP_USAGE_BASE + (idx / 16)) + +#define RTL8367C_FALLBACK_BASE RTL8367C_REG_FALLBACK_PORT0_CFG0 +#define RTL8367C_FALLBACK_PORT_CFG_REG(port) (RTL8367C_FALLBACK_BASE + (port * 4)) +#define RTL8367C_FALLBACK_PORT_MON_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 1 + (port * 4)) +#define RTL8367C_FALLBACK_PORT_ERR_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 3 + (port * 4)) + + +/* (16'h6400)timer_1588 */ +#define RTL8367C_EAV_CFG_BASE RTL8367C_REG_P0_EAV_CFG +#define RTL8367C_EAV_PORT_CFG_REG(port) (RTL8367C_EAV_CFG_BASE + (port *0x10)) +#define RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET +#define RTL8367C_EAV_CFG_RX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET +#define RTL8367C_EAV_CFG_RX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_RX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_RX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET +#define RTL8367C_EAV_CFG_TX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET +#define RTL8367C_EAV_CFG_TX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_TX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_TX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET + +#define RTL8367C_REG_TX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_TX_SYNC_SEQ_ID +#define RTL8367C_REG_TX_SYNC_SEQ_ID(port) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + (port *0x10)) +#define RTL8367C_REG_SEQ_ID(port, type) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + type + (port *0x10)) + +#define RTL8367C_REG_TX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID +#define RTL8367C_REG_TX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID +#define RTL8367C_REG_TX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID +#define RTL8367C_REG_RX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_RX_SYNC_SEQ_ID +#define RTL8367C_REG_RX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID +#define RTL8367C_REG_RX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID +#define RTL8367C_REG_RX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID + +#define RTL8367C_REG_PORT_NSEC_L_BASE RTL8367C_REG_P0_PORT_NSEC_15_0 +#define RTL8367C_REG_PORT_NSEC_L(port) (RTL8367C_REG_PORT_NSEC_L_BASE + (port *0x10)) +#define RTL8367C_REG_PORT_NSEC_H_BASE RTL8367C_REG_P0_PORT_NSEC_26_16 +#define RTL8367C_REG_PORT_NSEC_H(port) (RTL8367C_REG_PORT_NSEC_H_BASE + (port *0x10)) +#define RTL8367C_PORT_NSEC_H_OFFSET RTL8367C_P0_PORT_NSEC_26_16_OFFSET +#define RTL8367C_PORT_NSEC_H_MASK RTL8367C_P0_PORT_NSEC_26_16_MASK + +#define RTL8367C_REG_PORT_SEC_L_BASE RTL8367C_REG_P0_PORT_SEC_15_0 +#define RTL8367C_REG_PORT_SEC_L(port) (RTL8367C_REG_PORT_SEC_L_BASE + (port *0x10)) +#define RTL8367C_REG_PORT_SEC_H_BASE RTL8367C_REG_P0_PORT_SEC_31_16 +#define RTL8367C_REG_PORT_SEC_H(port) (RTL8367C_REG_PORT_SEC_H_BASE + (port *0x10)) + +#endif /*#ifndef _RTL8367C_BASE_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h new file mode 100755 index 00000000..eb4f48b8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h @@ -0,0 +1,22819 @@ +#ifndef _RTL8367C_REG_H_ +#define _RTL8367C_REG_H_ + +/************************************************************ +auto-generated register address and field data +*************************************************************/ + +/* (16'h0000)port_reg */ + +#define RTL8367C_REG_PORT0_CGST_HALF_CFG 0x0000 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT0_CTRL 0x0001 +#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT0 0x0002 +#define RTL8367C_TX_ERR_CNT_PORT0_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT0_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT0_DA0 0x0003 + +#define RTL8367C_REG_PKTGEN_PORT0_DA1 0x0004 + +#define RTL8367C_REG_PKTGEN_PORT0_DA2 0x0005 + +#define RTL8367C_REG_PKTGEN_PORT0_SA0 0x0006 + +#define RTL8367C_REG_PKTGEN_PORT0_SA1 0x0007 + +#define RTL8367C_REG_PKTGEN_PORT0_SA2 0x0008 + +#define RTL8367C_REG_PKTGEN_PORT0_COUNTER0 0x0009 + +#define RTL8367C_REG_PKTGEN_PORT0_COUNTER1 0x000a +#define RTL8367C_PKTGEN_PORT0_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT0_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH 0x000b +#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT0_TIMER 0x000d +#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT0_MISC_CFG 0x000e +#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT0_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT0_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 0x000f + +#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL1 0x0010 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT0_FORCE_RATE0 0x0011 + +#define RTL8367C_REG_PORT0_FORCE_RATE1 0x0012 + +#define RTL8367C_REG_PORT0_CURENT_RATE0 0x0013 + +#define RTL8367C_REG_PORT0_CURENT_RATE1 0x0014 + +#define RTL8367C_REG_PORT0_PAGE_COUNTER 0x0015 +#define RTL8367C_PORT0_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT0_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT0_CTRL0 0x0016 + +#define RTL8367C_REG_PAGEMETER_PORT0_CTRL1 0x0017 + +#define RTL8367C_REG_PORT0_EEECFG 0x0018 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT0_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT0_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT0_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT0_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT0_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT0_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT0_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT0_EEETXMTR 0x0019 + +#define RTL8367C_REG_PORT0_EEERXMTR 0x001a + +#define RTL8367C_REG_PORT0_EEEPTXMTR 0x001b + +#define RTL8367C_REG_PORT0_EEEPRXMTR 0x001c + +#define RTL8367C_REG_PTP_PORT0_CFG1 0x001e +#define RTL8367C_PTP_PORT0_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT0_CFG1_MASK 0xFF + +#define RTL8367C_REG_P0_MSIC1 0x001f +#define RTL8367C_P0_MSIC1_OFFSET 0 +#define RTL8367C_P0_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT1_CGST_HALF_CFG 0x0020 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT1_CTRL 0x0021 +#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT1 0x0022 +#define RTL8367C_TX_ERR_CNT_PORT1_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT1_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT1_DA0 0x0023 + +#define RTL8367C_REG_PKTGEN_PORT1_DA1 0x0024 + +#define RTL8367C_REG_PKTGEN_PORT1_DA2 0x0025 + +#define RTL8367C_REG_PKTGEN_PORT1_SA0 0x0026 + +#define RTL8367C_REG_PKTGEN_PORT1_SA1 0x0027 + +#define RTL8367C_REG_PKTGEN_PORT1_SA2 0x0028 + +#define RTL8367C_REG_PKTGEN_PORT1_COUNTER0 0x0029 + +#define RTL8367C_REG_PKTGEN_PORT1_COUNTER1 0x002a +#define RTL8367C_PKTGEN_PORT1_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT1_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT1_TX_LENGTH 0x002b +#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT1_TIMER 0x002d +#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT1_MISC_CFG 0x002e +#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT1_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT1_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL0 0x002f + +#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL1 0x0030 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT1_FORCE_RATE0 0x0031 + +#define RTL8367C_REG_PORT1_FORCE_RATE1 0x0032 + +#define RTL8367C_REG_PORT1_CURENT_RATE0 0x0033 + +#define RTL8367C_REG_PORT1_CURENT_RATE1 0x0034 + +#define RTL8367C_REG_PORT1_PAGE_COUNTER 0x0035 +#define RTL8367C_PORT1_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT1_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT1_CTRL0 0x0036 + +#define RTL8367C_REG_PAGEMETER_PORT1_CTRL1 0x0037 + +#define RTL8367C_REG_PORT1_EEECFG 0x0038 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT1_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT1_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT1_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT1_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT1_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT1_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT1_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT1_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT1_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT1_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT1_EEETXMTR 0x0039 + +#define RTL8367C_REG_PORT1_EEERXMTR 0x003a + +#define RTL8367C_REG_PORT1_EEEPTXMTR 0x003b + +#define RTL8367C_REG_PORT1_EEEPRXMTR 0x003c + +#define RTL8367C_REG_PTP_PORT1_CFG1 0x003e +#define RTL8367C_PTP_PORT1_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT1_CFG1_MASK 0xFF + +#define RTL8367C_REG_P1_MSIC1 0x003f +#define RTL8367C_P1_MSIC1_OFFSET 0 +#define RTL8367C_P1_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT2_CGST_HALF_CFG 0x0040 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT2_CTRL 0x0041 +#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT2 0x0042 +#define RTL8367C_TX_ERR_CNT_PORT2_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT2_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT2_DA0 0x0043 + +#define RTL8367C_REG_PKTGEN_PORT2_DA1 0x0044 + +#define RTL8367C_REG_PKTGEN_PORT2_DA2 0x0045 + +#define RTL8367C_REG_PKTGEN_PORT2_SA0 0x0046 + +#define RTL8367C_REG_PKTGEN_PORT2_SA1 0x0047 + +#define RTL8367C_REG_PKTGEN_PORT2_SA2 0x0048 + +#define RTL8367C_REG_PKTGEN_PORT2_COUNTER0 0x0049 + +#define RTL8367C_REG_PKTGEN_PORT2_COUNTER1 0x004a +#define RTL8367C_PKTGEN_PORT2_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT2_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT2_TX_LENGTH 0x004b +#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT2_TIMER 0x004d +#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT2_MISC_CFG 0x004e +#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT2_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT2_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL0 0x004f + +#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL1 0x0050 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT2_FORCE_RATE0 0x0051 + +#define RTL8367C_REG_PORT2_FORCE_RATE1 0x0052 + +#define RTL8367C_REG_PORT2_CURENT_RATE0 0x0053 + +#define RTL8367C_REG_PORT2_CURENT_RATE1 0x0054 + +#define RTL8367C_REG_PORT2_PAGE_COUNTER 0x0055 +#define RTL8367C_PORT2_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT2_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT2_CTRL0 0x0056 + +#define RTL8367C_REG_PAGEMETER_PORT2_CTRL1 0x0057 + +#define RTL8367C_REG_PORT2_EEECFG 0x0058 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT2_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT2_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT2_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT2_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT2_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT2_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT2_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT2_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT2_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT2_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT2_EEETXMTR 0x0059 + +#define RTL8367C_REG_PORT2_EEERXMTR 0x005a + +#define RTL8367C_REG_PORT2_EEEPTXMTR 0x005b + +#define RTL8367C_REG_PORT2_EEEPRXMTR 0x005c + +#define RTL8367C_REG_PTP_PORT2_CFG1 0x005e +#define RTL8367C_PTP_PORT2_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT2_CFG1_MASK 0xFF + +#define RTL8367C_REG_P2_MSIC1 0x005f +#define RTL8367C_P2_MSIC1_OFFSET 0 +#define RTL8367C_P2_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT3_CGST_HALF_CFG 0x0060 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT3_CTRL 0x0061 +#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT3 0x0062 +#define RTL8367C_TX_ERR_CNT_PORT3_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT3_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT3_DA0 0x0063 + +#define RTL8367C_REG_PKTGEN_PORT3_DA1 0x0064 + +#define RTL8367C_REG_PKTGEN_PORT3_DA2 0x0065 + +#define RTL8367C_REG_PKTGEN_PORT3_SA0 0x0066 + +#define RTL8367C_REG_PKTGEN_PORT3_SA1 0x0067 + +#define RTL8367C_REG_PKTGEN_PORT3_SA2 0x0068 + +#define RTL8367C_REG_PKTGEN_PORT3_COUNTER0 0x0069 + +#define RTL8367C_REG_PKTGEN_PORT3_COUNTER1 0x006a +#define RTL8367C_PKTGEN_PORT3_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT3_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT3_TX_LENGTH 0x006b +#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT3_TIMER 0x006d +#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT3_MISC_CFG 0x006e +#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT3_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT3_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL0 0x006f + +#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL1 0x0070 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT3_FORCE_RATE0 0x0071 + +#define RTL8367C_REG_PORT3_FORCE_RATE1 0x0072 + +#define RTL8367C_REG_PORT3_CURENT_RATE0 0x0073 + +#define RTL8367C_REG_PORT3_CURENT_RATE1 0x0074 + +#define RTL8367C_REG_PORT3_PAGE_COUNTER 0x0075 +#define RTL8367C_PORT3_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT3_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT3_CTRL0 0x0076 + +#define RTL8367C_REG_PAGEMETER_PORT3_CTRL1 0x0077 + +#define RTL8367C_REG_PORT3_EEECFG 0x0078 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT3_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT3_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT3_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT3_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT3_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT3_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT3_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT3_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT3_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT3_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT3_EEETXMTR 0x0079 + +#define RTL8367C_REG_PORT3_EEERXMTR 0x007a + +#define RTL8367C_REG_PORT3_EEEPTXMTR 0x007b + +#define RTL8367C_REG_PORT3_EEEPRXMTR 0x007c + +#define RTL8367C_REG_PTP_PORT3_CFG1 0x007e +#define RTL8367C_PTP_PORT3_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT3_CFG1_MASK 0xFF + +#define RTL8367C_REG_P3_MSIC1 0x007f +#define RTL8367C_P3_MSIC1_OFFSET 0 +#define RTL8367C_P3_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT4_CGST_HALF_CFG 0x0080 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT4_CTRL 0x0081 +#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT4 0x0082 +#define RTL8367C_TX_ERR_CNT_PORT4_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT4_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT4_DA0 0x0083 + +#define RTL8367C_REG_PKTGEN_PORT4_DA1 0x0084 + +#define RTL8367C_REG_PKTGEN_PORT4_DA2 0x0085 + +#define RTL8367C_REG_PKTGEN_PORT4_SA0 0x0086 + +#define RTL8367C_REG_PKTGEN_PORT4_SA1 0x0087 + +#define RTL8367C_REG_PKTGEN_PORT4_SA2 0x0088 + +#define RTL8367C_REG_PKTGEN_PORT4_COUNTER0 0x0089 + +#define RTL8367C_REG_PKTGEN_PORT4_COUNTER1 0x008a +#define RTL8367C_PKTGEN_PORT4_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT4_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT4_TX_LENGTH 0x008b +#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT4_TIMER 0x008d +#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT4_MISC_CFG 0x008e +#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT4_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT4_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL0 0x008f + +#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL1 0x0090 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT4_FORCE_RATE0 0x0091 + +#define RTL8367C_REG_PORT4_FORCE_RATE1 0x0092 + +#define RTL8367C_REG_PORT4_CURENT_RATE0 0x0093 + +#define RTL8367C_REG_PORT4_CURENT_RATE1 0x0094 + +#define RTL8367C_REG_PORT4_PAGE_COUNTER 0x0095 +#define RTL8367C_PORT4_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT4_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT4_CTRL0 0x0096 + +#define RTL8367C_REG_PAGEMETER_PORT4_CTRL1 0x0097 + +#define RTL8367C_REG_PORT4_EEECFG 0x0098 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT4_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT4_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT4_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT4_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT4_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT4_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT4_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT4_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT4_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT4_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT4_EEETXMTR 0x0099 + +#define RTL8367C_REG_PORT4_EEERXMTR 0x009a + +#define RTL8367C_REG_PORT4_EEEPTXMTR 0x009b + +#define RTL8367C_REG_PORT4_EEEPRXMTR 0x009c + +#define RTL8367C_REG_PTP_PORT4_CFG1 0x009e +#define RTL8367C_PTP_PORT4_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT4_CFG1_MASK 0xFF + +#define RTL8367C_REG_P4_MSIC1 0x009f +#define RTL8367C_P4_MSIC1_OFFSET 0 +#define RTL8367C_P4_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT5_CGST_HALF_CFG 0x00a0 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT5_CTRL 0x00a1 +#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT5 0x00a2 +#define RTL8367C_TX_ERR_CNT_PORT5_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT5_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT5_DA0 0x00a3 + +#define RTL8367C_REG_PKTGEN_PORT5_DA1 0x00a4 + +#define RTL8367C_REG_PKTGEN_PORT5_DA2 0x00a5 + +#define RTL8367C_REG_PKTGEN_PORT5_SA0 0x00a6 + +#define RTL8367C_REG_PKTGEN_PORT5_SA1 0x00a7 + +#define RTL8367C_REG_PKTGEN_PORT5_SA2 0x00a8 + +#define RTL8367C_REG_PKTGEN_PORT5_COUNTER0 0x00a9 + +#define RTL8367C_REG_PKTGEN_PORT5_COUNTER1 0x00aa +#define RTL8367C_PKTGEN_PORT5_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT5_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT5_TX_LENGTH 0x00ab +#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT5_TIMER 0x00ad +#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT5_MISC_CFG 0x00ae +#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT5_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT5_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL0 0x00af + +#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL1 0x00b0 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT5_FORCE_RATE0 0x00b1 + +#define RTL8367C_REG_PORT5_FORCE_RATE1 0x00b2 + +#define RTL8367C_REG_PORT5_CURENT_RATE0 0x00b3 + +#define RTL8367C_REG_PORT5_CURENT_RATE1 0x00b4 + +#define RTL8367C_REG_PORT5_PAGE_COUNTER 0x00b5 +#define RTL8367C_PORT5_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT5_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT5_CTRL0 0x00b6 + +#define RTL8367C_REG_PAGEMETER_PORT5_CTRL1 0x00b7 + +#define RTL8367C_REG_PORT5_EEECFG 0x00b8 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT5_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT5_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT5_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT5_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT5_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT5_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT5_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT5_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT5_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT5_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT5_EEETXMTR 0x00b9 + +#define RTL8367C_REG_PORT5_EEERXMTR 0x00ba + +#define RTL8367C_REG_PORT5_EEEPTXMTR 0x00bb + +#define RTL8367C_REG_PORT5_EEEPRXMTR 0x00bc + +#define RTL8367C_REG_PTP_PORT5_CFG1 0x00be +#define RTL8367C_PTP_PORT5_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT5_CFG1_MASK 0xFF + +#define RTL8367C_REG_P5_MSIC1 0x00bf +#define RTL8367C_P5_MSIC1_OFFSET 0 +#define RTL8367C_P5_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT6_CGST_HALF_CFG 0x00c0 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT6_CTRL 0x00c1 +#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT6 0x00c2 +#define RTL8367C_TX_ERR_CNT_PORT6_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT6_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT6_DA0 0x00c3 + +#define RTL8367C_REG_PKTGEN_PORT6_DA1 0x00c4 + +#define RTL8367C_REG_PKTGEN_PORT6_DA2 0x00c5 + +#define RTL8367C_REG_PKTGEN_PORT6_SA0 0x00c6 + +#define RTL8367C_REG_PKTGEN_PORT6_SA1 0x00c7 + +#define RTL8367C_REG_PKTGEN_PORT6_SA2 0x00c8 + +#define RTL8367C_REG_PKTGEN_PORT6_COUNTER0 0x00c9 + +#define RTL8367C_REG_PKTGEN_PORT6_COUNTER1 0x00ca +#define RTL8367C_PKTGEN_PORT6_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT6_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT6_TX_LENGTH 0x00cb +#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT6_TIMER 0x00cd +#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT6_MISC_CFG 0x00ce +#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT6_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT6_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL0 0x00cf + +#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL1 0x00d0 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT6_FORCE_RATE0 0x00d1 + +#define RTL8367C_REG_PORT6_FORCE_RATE1 0x00d2 + +#define RTL8367C_REG_PORT6_CURENT_RATE0 0x00d3 + +#define RTL8367C_REG_PORT6_CURENT_RATE1 0x00d4 + +#define RTL8367C_REG_PORT6_PAGE_COUNTER 0x00d5 +#define RTL8367C_PORT6_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT6_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT6_CTRL0 0x00d6 + +#define RTL8367C_REG_PAGEMETER_PORT6_CTRL1 0x00d7 + +#define RTL8367C_REG_PORT6_EEECFG 0x00d8 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT6_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT6_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT6_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT6_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT6_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT6_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT6_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT6_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT6_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT6_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT6_EEETXMTR 0x00d9 + +#define RTL8367C_REG_PORT6_EEERXMTR 0x00da + +#define RTL8367C_REG_PORT6_EEEPTXMTR 0x00db + +#define RTL8367C_REG_PORT6_EEEPRXMTR 0x00dc + +#define RTL8367C_REG_PTP_PORT6_CFG1 0x00de +#define RTL8367C_PTP_PORT6_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT6_CFG1_MASK 0xFF + +#define RTL8367C_REG_P6_MSIC1 0x00df +#define RTL8367C_P6_MSIC1_OFFSET 0 +#define RTL8367C_P6_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT7_CGST_HALF_CFG 0x00e0 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT7_CTRL 0x00e1 +#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT7 0x00e2 +#define RTL8367C_TX_ERR_CNT_PORT7_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT7_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT7_DA0 0x00e3 + +#define RTL8367C_REG_PKTGEN_PORT7_DA1 0x00e4 + +#define RTL8367C_REG_PKTGEN_PORT7_DA2 0x00e5 + +#define RTL8367C_REG_PKTGEN_PORT7_SA0 0x00e6 + +#define RTL8367C_REG_PKTGEN_PORT7_SA1 0x00e7 + +#define RTL8367C_REG_PKTGEN_PORT7_SA2 0x00e8 + +#define RTL8367C_REG_PKTGEN_PORT7_COUNTER0 0x00e9 + +#define RTL8367C_REG_PKTGEN_PORT7_COUNTER1 0x00ea +#define RTL8367C_PKTGEN_PORT7_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT7_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT7_TX_LENGTH 0x00eb +#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT7_TIMER 0x00ed +#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT7_MISC_CFG 0x00ee +#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT7_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT7_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL0 0x00ef + +#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL1 0x00f0 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT7_FORCE_RATE0 0x00f1 + +#define RTL8367C_REG_PORT7_FORCE_RATE1 0x00f2 + +#define RTL8367C_REG_PORT7_CURENT_RATE0 0x00f3 + +#define RTL8367C_REG_PORT7_CURENT_RATE1 0x00f4 + +#define RTL8367C_REG_PORT7_PAGE_COUNTER 0x00f5 +#define RTL8367C_PORT7_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT7_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT7_CTRL0 0x00f6 + +#define RTL8367C_REG_PAGEMETER_PORT7_CTRL1 0x00f7 + +#define RTL8367C_REG_PORT7_EEECFG 0x00f8 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT7_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT7_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT7_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT7_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT7_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT7_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT7_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT7_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT7_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT7_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT7_EEETXMTR 0x00f9 + +#define RTL8367C_REG_PORT7_EEERXMTR 0x00fa + +#define RTL8367C_REG_PORT7_EEEPTXMTR 0x00fb + +#define RTL8367C_REG_PORT7_EEEPRXMTR 0x00fc + +#define RTL8367C_REG_PTP_PORT7_CFG1 0x00fe +#define RTL8367C_PTP_PORT7_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT7_CFG1_MASK 0xFF + +#define RTL8367C_REG_P7_MSIC1 0x00ff +#define RTL8367C_P7_MSIC1_OFFSET 0 +#define RTL8367C_P7_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT8_CGST_HALF_CFG 0x0100 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT8_CTRL 0x0101 +#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT8 0x0102 +#define RTL8367C_TX_ERR_CNT_PORT8_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT8_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT8_DA0 0x0103 + +#define RTL8367C_REG_PKTGEN_PORT8_DA1 0x0104 + +#define RTL8367C_REG_PKTGEN_PORT8_DA2 0x0105 + +#define RTL8367C_REG_PKTGEN_PORT8_SA0 0x0106 + +#define RTL8367C_REG_PKTGEN_PORT8_SA1 0x0107 + +#define RTL8367C_REG_PKTGEN_PORT8_SA2 0x0108 + +#define RTL8367C_REG_PKTGEN_PORT8_COUNTER0 0x0109 + +#define RTL8367C_REG_PKTGEN_PORT8_COUNTER1 0x010a +#define RTL8367C_PKTGEN_PORT8_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT8_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT8_TX_LENGTH 0x010b +#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT8_TIMER 0x010d +#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT8_MISC_CFG 0x010e +#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT8_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT8_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL0 0x010f + +#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL1 0x0110 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT8_FORCE_RATE0 0x0111 + +#define RTL8367C_REG_PORT8_FORCE_RATE1 0x0112 + +#define RTL8367C_REG_PORT8_CURENT_RATE0 0x0113 + +#define RTL8367C_REG_PORT8_CURENT_RATE1 0x0114 + +#define RTL8367C_REG_PORT8_PAGE_COUNTER 0x0115 +#define RTL8367C_PORT8_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT8_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT8_CTRL0 0x0116 + +#define RTL8367C_REG_PAGEMETER_PORT8_CTRL1 0x0117 + +#define RTL8367C_REG_PORT8_EEECFG 0x0118 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT8_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT8_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT8_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT8_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT8_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT8_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT8_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT8_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT8_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT8_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT8_EEETXMTR 0x0119 + +#define RTL8367C_REG_PORT8_EEERXMTR 0x011a + +#define RTL8367C_REG_PORT8_EEEPTXMTR 0x011b + +#define RTL8367C_REG_PORT8_EEEPRXMTR 0x011c + +#define RTL8367C_REG_PTP_PORT8_CFG1 0x011e +#define RTL8367C_PTP_PORT8_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT8_CFG1_MASK 0xFF + +#define RTL8367C_REG_P8_MSIC1 0x011f +#define RTL8367C_P8_MSIC1_OFFSET 0 +#define RTL8367C_P8_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT9_CGST_HALF_CFG 0x0120 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT9_CTRL 0x0121 +#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT9 0x0122 +#define RTL8367C_TX_ERR_CNT_PORT9_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT9_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT9_DA0 0x0123 + +#define RTL8367C_REG_PKTGEN_PORT9_DA1 0x0124 + +#define RTL8367C_REG_PKTGEN_PORT9_DA2 0x0125 + +#define RTL8367C_REG_PKTGEN_PORT9_SA0 0x0126 + +#define RTL8367C_REG_PKTGEN_PORT9_SA1 0x0127 + +#define RTL8367C_REG_PKTGEN_PORT9_SA2 0x0128 + +#define RTL8367C_REG_PKTGEN_PORT9_COUNTER0 0x0129 + +#define RTL8367C_REG_PKTGEN_PORT9_COUNTER1 0x012a +#define RTL8367C_PKTGEN_PORT9_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT9_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT9_TX_LENGTH 0x012b +#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT9_TIMER 0x012d +#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT9_MISC_CFG 0x012e +#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT9_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT9_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL0 0x012f + +#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL1 0x0130 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT9_FORCE_RATE0 0x0131 + +#define RTL8367C_REG_PORT9_FORCE_RATE1 0x0132 + +#define RTL8367C_REG_PORT9_CURENT_RATE0 0x0133 + +#define RTL8367C_REG_PORT9_CURENT_RATE1 0x0134 + +#define RTL8367C_REG_PORT9_PAGE_COUNTER 0x0135 +#define RTL8367C_PORT9_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT9_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT9_CTRL0 0x0136 + +#define RTL8367C_REG_PAGEMETER_PORT9_CTRL1 0x0137 + +#define RTL8367C_REG_PORT9_EEECFG 0x0138 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT9_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT9_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT9_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT9_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT9_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT9_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT9_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT9_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT9_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT9_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT9_EEETXMTR 0x0139 + +#define RTL8367C_REG_PORT9_EEERXMTR 0x013a + +#define RTL8367C_REG_PORT9_EEEPTXMTR 0x013b + +#define RTL8367C_REG_PORT9_EEEPRXMTR 0x013c + +#define RTL8367C_REG_PTP_PORT9_CFG1 0x013e +#define RTL8367C_PTP_PORT9_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT9_CFG1_MASK 0xFF + +#define RTL8367C_REG_P9_MSIC1 0x013f +#define RTL8367C_P9_MSIC1_OFFSET 0 +#define RTL8367C_P9_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT10_CGST_HALF_CFG 0x0140 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT10_CTRL 0x0141 +#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT10 0x0142 +#define RTL8367C_TX_ERR_CNT_PORT10_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT10_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT10_DA0 0x0143 + +#define RTL8367C_REG_PKTGEN_PORT10_DA1 0x0144 + +#define RTL8367C_REG_PKTGEN_PORT10_DA2 0x0145 + +#define RTL8367C_REG_PKTGEN_PORT10_SA0 0x0146 + +#define RTL8367C_REG_PKTGEN_PORT10_SA1 0x0147 + +#define RTL8367C_REG_PKTGEN_PORT10_SA2 0x0148 + +#define RTL8367C_REG_PKTGEN_PORT10_COUNTER0 0x0149 + +#define RTL8367C_REG_PKTGEN_PORT10_COUNTER1 0x014a +#define RTL8367C_PKTGEN_PORT10_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT10_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT10_TX_LENGTH 0x014b +#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT10_TIMER 0x014d +#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT10_MISC_CFG 0x014e +#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT10_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT10_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL0 0x014f + +#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL1 0x0150 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT10_FORCE_RATE0 0x0151 + +#define RTL8367C_REG_PORT10_FORCE_RATE1 0x0152 + +#define RTL8367C_REG_PORT10_CURENT_RATE0 0x0153 + +#define RTL8367C_REG_PORT10_CURENT_RATE1 0x0154 + +#define RTL8367C_REG_PORT10_PAGE_COUNTER 0x0155 +#define RTL8367C_PORT10_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT10_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT10_CTRL0 0x0156 + +#define RTL8367C_REG_PAGEMETER_PORT10_CTRL1 0x0157 + +#define RTL8367C_REG_PORT10_EEECFG 0x0158 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT10_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT10_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT10_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT10_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT10_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT10_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT10_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT10_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT10_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT10_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT10_EEETXMTR 0x0159 + +#define RTL8367C_REG_PORT10_EEERXMTR 0x015a + +#define RTL8367C_REG_PORT10_EEEPTXMTR 0x015b + +#define RTL8367C_REG_PORT10_EEEPRXMTR 0x015c + +#define RTL8367C_REG_PTP_PORT10_CFG1 0x015e +#define RTL8367C_PTP_PORT10_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT10_CFG1_MASK 0xFF + +#define RTL8367C_REG_P10_MSIC1 0x015f +#define RTL8367C_P10_MSIC1_OFFSET 0 +#define RTL8367C_P10_MSIC1_MASK 0x1 + +/* (16'h0200)outq_reg */ + +#define RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON 0x0200 +#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE1_DROP_ON 0x0201 +#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE2_DROP_ON 0x0202 +#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE3_DROP_ON 0x0203 +#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE4_DROP_ON 0x0204 +#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE5_DROP_ON 0x0205 +#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE6_DROP_ON 0x0206 +#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE7_DROP_ON 0x0207 +#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON 0x0208 +#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT1_DROP_ON 0x0209 +#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT2_DROP_ON 0x020a +#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT3_DROP_ON 0x020b +#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT4_DROP_ON 0x020c +#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT5_DROP_ON 0x020d +#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT6_DROP_ON 0x020e +#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT7_DROP_ON 0x020f +#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT8_DROP_ON 0x0210 +#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT9_DROP_ON 0x0211 +#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT10_DROP_ON 0x0212 +#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_GAP 0x0218 +#define RTL8367C_FLOWCTRL_PORT_GAP_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_GAP_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE_GAP 0x0219 +#define RTL8367C_FLOWCTRL_QUEUE_GAP_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE_GAP_MASK 0x7FF + +#define RTL8367C_REG_PORT_QEMPTY 0x022d +#define RTL8367C_PORT_QEMPTY_OFFSET 0 +#define RTL8367C_PORT_QEMPTY_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL0 0x022e +#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_OFFSET 0 +#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_MASK 0xF + +#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL1 0x022f +#define RTL8367C_TOTAL_OFFSET 9 +#define RTL8367C_TOTAL_MASK 0x200 +#define RTL8367C_PORT_MAX_OFFSET 8 +#define RTL8367C_PORT_MAX_MASK 0x100 +#define RTL8367C_QMAX_MASK_OFFSET 0 +#define RTL8367C_QMAX_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCTRL_QUEUE0_PAGE_COUNT 0x0230 +#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE1_PAGE_COUNT 0x0231 +#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE2_PAGE_COUNT 0x0232 +#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE3_PAGE_COUNT 0x0233 +#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE4_PAGE_COUNT 0x0234 +#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE5_PAGE_COUNT 0x0235 +#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE6_PAGE_COUNT 0x0236 +#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE7_PAGE_COUNT 0x0237 +#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_PAGE_COUNT 0x0238 +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT 0x0239 +#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT 0x023a +#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT 0x023b +#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT 0x023c +#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT 0x023d +#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT 0x023e +#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT 0x023f +#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT 0x0240 +#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_MAX_PAGE_COUNT 0x0241 +#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_TOTAL_PACKET_COUNT 0x0243 + +#define RTL8367C_REG_HIGH_QUEUE_MASK0 0x0244 +#define RTL8367C_PORT1_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT1_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT0_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT0_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK1 0x0245 +#define RTL8367C_PORT3_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT3_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT2_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT2_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK2 0x0246 +#define RTL8367C_PORT5_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT5_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT4_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT4_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK3 0x0247 +#define RTL8367C_PORT7_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT7_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT6_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT6_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK4 0x0248 +#define RTL8367C_PORT9_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT9_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT8_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT8_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK5 0x0249 +#define RTL8367C_HIGH_QUEUE_MASK5_OFFSET 0 +#define RTL8367C_HIGH_QUEUE_MASK5_MASK 0xFF + +#define RTL8367C_REG_LOW_QUEUE_TH 0x024c +#define RTL8367C_LOW_QUEUE_TH_OFFSET 0 +#define RTL8367C_LOW_QUEUE_TH_MASK 0x7FF + +#define RTL8367C_REG_TH_TX_PREFET 0x0250 +#define RTL8367C_TH_TX_PREFET_OFFSET 0 +#define RTL8367C_TH_TX_PREFET_MASK 0xFF + +#define RTL8367C_REG_DUMMY_0251 0x0251 + +#define RTL8367C_REG_DUMMY_0252 0x0252 + +#define RTL8367C_REG_DUMMY_0253 0x0253 + +#define RTL8367C_REG_DUMMY_0254 0x0254 + +#define RTL8367C_REG_DUMMY_0255 0x0255 + +#define RTL8367C_REG_DUMMY_0256 0x0256 + +#define RTL8367C_REG_DUMMY_0257 0x0257 + +#define RTL8367C_REG_DUMMY_0258 0x0258 + +#define RTL8367C_REG_DUMMY_0259 0x0259 + +#define RTL8367C_REG_DUMMY_025A 0x025A + +#define RTL8367C_REG_DUMMY_025B 0x025B + +#define RTL8367C_REG_DUMMY_025C 0x025C + +#define RTL8367C_REG_Q_TXPKT_CNT_CTL 0x025d +#define RTL8367C_QUEUE_PKT_CNT_CLR_OFFSET 4 +#define RTL8367C_QUEUE_PKT_CNT_CLR_MASK 0x10 +#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_OFFSET 0 +#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_MASK 0xF + +#define RTL8367C_REG_Q0_TXPKT_CNT_L 0x025e + +#define RTL8367C_REG_Q0_TXPKT_CNT_H 0x025f + +#define RTL8367C_REG_Q1_TXPKT_CNT_L 0x0260 + +#define RTL8367C_REG_Q1_TXPKT_CNT_H 0x0261 + +#define RTL8367C_REG_Q2_TXPKT_CNT_L 0x0262 + +#define RTL8367C_REG_Q2_TXPKT_CNT_H 0x0263 + +#define RTL8367C_REG_Q3_TXPKT_CNT_L 0x0264 + +#define RTL8367C_REG_Q3_TXPKT_CNT_H 0x0265 + +#define RTL8367C_REG_Q4_TXPKT_CNT_L 0x0266 + +#define RTL8367C_REG_Q4_TXPKT_CNT_H 0x0267 + +#define RTL8367C_REG_Q5_TXPKT_CNT_L 0x0268 + +#define RTL8367C_REG_Q5_TXPKT_CNT_H 0x0269 + +#define RTL8367C_REG_Q6_TXPKT_CNT_L 0x026a + +#define RTL8367C_REG_Q6_TXPKT_CNT_H 0x026b + +#define RTL8367C_REG_Q7_TXPKT_CNT_L 0x026c + +#define RTL8367C_REG_Q7_TXPKT_CNT_H 0x026d + +/* (16'h0300)sch_reg */ + +#define RTL8367C_REG_SCHEDULE_WFQ_CTRL 0x0300 +#define RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET 0 +#define RTL8367C_SCHEDULE_WFQ_CTRL_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE 0x0301 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 0x0302 +#define RTL8367C_PORT1_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT1_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT1_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT1_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT1_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT1_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT1_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT1_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT1_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT1_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT1_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT1_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT1_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT1_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT1_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT1_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT0_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT0_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT0_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT0_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT0_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT0_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT0_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT0_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT0_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT0_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT0_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT0_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT0_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT0_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT0_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT0_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL1 0x0303 +#define RTL8367C_PORT3_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT3_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT3_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT3_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT3_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT3_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT3_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT3_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT3_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT3_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT3_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT3_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT3_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT3_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT3_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT3_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT2_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT2_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT2_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT2_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT2_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT2_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT2_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT2_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT2_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT2_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT2_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT2_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT2_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT2_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT2_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT2_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL2 0x0304 +#define RTL8367C_PORT5_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT5_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT5_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT5_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT5_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT5_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT5_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT5_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT5_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT5_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT5_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT5_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT5_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT5_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT5_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT5_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT4_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT4_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT4_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT4_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT4_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT4_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT4_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT4_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT4_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT4_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT4_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT4_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT4_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT4_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT4_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT4_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL3 0x0305 +#define RTL8367C_PORT7_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT7_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT7_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT7_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT7_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT7_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT7_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT7_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT7_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT7_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT7_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT7_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT7_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT7_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT7_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT7_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT6_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT6_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT6_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT6_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT6_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT6_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT6_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT6_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT6_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT6_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT6_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT6_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT6_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT6_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL4 0x0306 +#define RTL8367C_PORT9_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT9_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT9_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT9_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT9_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT9_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT9_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT9_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT9_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT9_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT9_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT9_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT9_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT9_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT9_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT9_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT8_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT8_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT8_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT8_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT8_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT8_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT8_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT8_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT8_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT8_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT8_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT8_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT8_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT8_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL5 0x0307 +#define RTL8367C_PORT10_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT10_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT10_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT10_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT10_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT10_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT10_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT10_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT10_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT10_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT10_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT10_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT10_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT10_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT10_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT10_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_APR_CTRL0 0x030a +#define RTL8367C_PORT10_APR_ENABLE_OFFSET 10 +#define RTL8367C_PORT10_APR_ENABLE_MASK 0x400 +#define RTL8367C_PORT9_APR_ENABLE_OFFSET 9 +#define RTL8367C_PORT9_APR_ENABLE_MASK 0x200 +#define RTL8367C_PORT8_APR_ENABLE_OFFSET 8 +#define RTL8367C_PORT8_APR_ENABLE_MASK 0x100 +#define RTL8367C_PORT7_APR_ENABLE_OFFSET 7 +#define RTL8367C_PORT7_APR_ENABLE_MASK 0x80 +#define RTL8367C_PORT6_APR_ENABLE_OFFSET 6 +#define RTL8367C_PORT6_APR_ENABLE_MASK 0x40 +#define RTL8367C_PORT5_APR_ENABLE_OFFSET 5 +#define RTL8367C_PORT5_APR_ENABLE_MASK 0x20 +#define RTL8367C_PORT4_APR_ENABLE_OFFSET 4 +#define RTL8367C_PORT4_APR_ENABLE_MASK 0x10 +#define RTL8367C_PORT3_APR_ENABLE_OFFSET 3 +#define RTL8367C_PORT3_APR_ENABLE_MASK 0x8 +#define RTL8367C_PORT2_APR_ENABLE_OFFSET 2 +#define RTL8367C_PORT2_APR_ENABLE_MASK 0x4 +#define RTL8367C_PORT1_APR_ENABLE_OFFSET 1 +#define RTL8367C_PORT1_APR_ENABLE_MASK 0x2 +#define RTL8367C_PORT0_APR_ENABLE_OFFSET 0 +#define RTL8367C_PORT0_APR_ENABLE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT 0x030c + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT 0x030d +#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT 0x030e +#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT 0x030f +#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT 0x0310 +#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT 0x0311 +#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT 0x0312 +#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT 0x0313 +#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE0_WFQ_WEIGHT 0x0314 + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT 0x0315 +#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT 0x0316 +#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT 0x0317 +#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT 0x0318 +#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT 0x0319 +#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT 0x031a +#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT 0x031b +#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE0_WFQ_WEIGHT 0x031c + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT 0x031d +#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT 0x031e +#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT 0x031f +#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT 0x0320 +#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT 0x0321 +#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT 0x0322 +#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT 0x0323 +#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE0_WFQ_WEIGHT 0x0324 + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT 0x0325 +#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT 0x0326 +#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT 0x0327 +#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT 0x0328 +#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT 0x0329 +#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT 0x032a +#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT 0x032b +#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE0_WFQ_WEIGHT 0x032c + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT 0x032d +#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT 0x032e +#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT 0x032f +#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT 0x0330 +#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT 0x0331 +#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT 0x0332 +#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT 0x0333 +#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE0_WFQ_WEIGHT 0x0334 + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT 0x0335 +#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT 0x0336 +#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT 0x0337 +#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT 0x0338 +#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT 0x0339 +#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT 0x033a +#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT 0x033b +#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE0_WFQ_WEIGHT 0x033c + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT 0x033d +#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT 0x033e +#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT 0x033f +#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT 0x0340 +#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT 0x0341 +#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT 0x0342 +#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT 0x0343 +#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE0_WFQ_WEIGHT 0x0344 + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT 0x0345 +#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT 0x0346 +#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT 0x0347 +#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT 0x0348 +#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT 0x0349 +#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT 0x034a +#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT 0x034b +#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE0_WFQ_WEIGHT 0x034c + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT 0x034d +#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT 0x034e +#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT 0x034f +#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT 0x0350 +#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT 0x0351 +#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT 0x0352 +#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT 0x0353 +#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE0_WFQ_WEIGHT 0x0354 + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT 0x0355 +#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT 0x0356 +#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT 0x0357 +#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT 0x0358 +#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT 0x0359 +#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT 0x035a +#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT 0x035b +#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE0_WFQ_WEIGHT 0x035c + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT 0x035d +#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT 0x035e +#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT 0x035f +#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT 0x0360 +#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT 0x0361 +#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT 0x0362 +#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT 0x0363 +#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_PORT0_EGRESSBW_CTRL0 0x038c + +#define RTL8367C_REG_PORT0_EGRESSBW_CTRL1 0x038d +#define RTL8367C_PORT0_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT0_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT1_EGRESSBW_CTRL0 0x038e + +#define RTL8367C_REG_PORT1_EGRESSBW_CTRL1 0x038f +#define RTL8367C_PORT1_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT1_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT2_EGRESSBW_CTRL0 0x0390 + +#define RTL8367C_REG_PORT2_EGRESSBW_CTRL1 0x0391 +#define RTL8367C_PORT2_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT2_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT3_EGRESSBW_CTRL0 0x0392 + +#define RTL8367C_REG_PORT3_EGRESSBW_CTRL1 0x0393 +#define RTL8367C_PORT3_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT3_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT4_EGRESSBW_CTRL0 0x0394 + +#define RTL8367C_REG_PORT4_EGRESSBW_CTRL1 0x0395 +#define RTL8367C_PORT4_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT4_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT5_EGRESSBW_CTRL0 0x0396 + +#define RTL8367C_REG_PORT5_EGRESSBW_CTRL1 0x0397 +#define RTL8367C_PORT5_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT5_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT6_EGRESSBW_CTRL0 0x0398 + +#define RTL8367C_REG_PORT6_EGRESSBW_CTRL1 0x0399 +#define RTL8367C_PORT6_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT6_EGRESSBW_CTRL1_MASK 0x7 + +#define RTL8367C_REG_PORT7_EGRESSBW_CTRL0 0x039a + +#define RTL8367C_REG_PORT7_EGRESSBW_CTRL1 0x039b +#define RTL8367C_PORT7_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT7_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT8_EGRESSBW_CTRL0 0x039c + +#define RTL8367C_REG_PORT8_EGRESSBW_CTRL1 0x039d +#define RTL8367C_PORT8_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT8_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT9_EGRESSBW_CTRL0 0x039e + +#define RTL8367C_REG_PORT9_EGRESSBW_CTRL1 0x039f +#define RTL8367C_PORT9_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT9_EGRESSBW_CTRL1_MASK 0x7 + +#define RTL8367C_REG_PORT10_EGRESSBW_CTRL0 0x03a0 + +#define RTL8367C_REG_PORT10_EGRESSBW_CTRL1 0x03a1 +#define RTL8367C_PORT10_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT10_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 0x03ac +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL1 0x03ad +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL0 0x03b0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL1 0x03b1 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL0 0x03b4 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL1 0x03b5 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL0 0x03b8 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL1 0x03b9 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL0 0x03bc +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL1 0x03bd +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL0 0x03c0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL1 0x03c1 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL0 0x03c4 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL1 0x03c5 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL0 0x03c8 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL1 0x03c9 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 0x03ca +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL1 0x03cb +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL0 0x03cc +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL1 0x03cd +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL0 0x03ce +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL1 0x03cf +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_LINE_RATE_1G_L 0x03ec + +#define RTL8367C_REG_LINE_RATE_1G_H 0x03ed +#define RTL8367C_LINE_RATE_1G_H_OFFSET 0 +#define RTL8367C_LINE_RATE_1G_H_MASK 0x1 + +#define RTL8367C_REG_LINE_RATE_100_L 0x03ee + +#define RTL8367C_REG_LINE_RATE_100_H 0x03ef +#define RTL8367C_LINE_RATE_100_H_OFFSET 0 +#define RTL8367C_LINE_RATE_100_H_MASK 0x1 + +#define RTL8367C_REG_LINE_RATE_10_L 0x03f0 + +#define RTL8367C_REG_LINE_RATE_10_H 0x03f1 +#define RTL8367C_LINE_RATE_10_H_OFFSET 0 +#define RTL8367C_LINE_RATE_10_H_MASK 0x1 + +#define RTL8367C_REG_DUMMY_03f2 0x03f2 + +#define RTL8367C_REG_DUMMY_03f3 0x03f3 + +#define RTL8367C_REG_DUMMY_03f4 0x03f4 + +#define RTL8367C_REG_DUMMY_03f5 0x03f5 + +#define RTL8367C_REG_DUMMY_03f6 0x03f6 + +#define RTL8367C_REG_BYPASS_LINE_RATE 0x03f7 +#define RTL8367C_BYPASS_PORT10_CONSTRAINT_OFFSET 5 +#define RTL8367C_BYPASS_PORT10_CONSTRAINT_MASK 0x20 +#define RTL8367C_BYPASS_PORT9_CONSTRAINT_OFFSET 4 +#define RTL8367C_BYPASS_PORT9_CONSTRAINT_MASK 0x10 +#define RTL8367C_BYPASS_PORT8_CONSTRAINT_OFFSET 3 +#define RTL8367C_BYPASS_PORT8_CONSTRAINT_MASK 0x8 +#define RTL8367C_BYPASS_PORT7_CONSTRAINT_OFFSET 2 +#define RTL8367C_BYPASS_PORT7_CONSTRAINT_MASK 0x4 +#define RTL8367C_BYPASS_PORT6_CONSTRAINT_OFFSET 1 +#define RTL8367C_BYPASS_PORT6_CONSTRAINT_MASK 0x2 +#define RTL8367C_BYPASS_PORT5_CONSTRAINT_OFFSET 0 +#define RTL8367C_BYPASS_PORT5_CONSTRAINT_MASK 0x1 + +#define RTL8367C_REG_LINE_RATE_500_H 0x03f8 +#define RTL8367C_LINE_RATE_500_H_OFFSET 0 +#define RTL8367C_LINE_RATE_500_H_MASK 0x7 + +#define RTL8367C_REG_LINE_RATE_500_L 0x03f9 + +#define RTL8367C_REG_LINE_RATE_HSG_H 0x03fa +#define RTL8367C_LINE_RATE_HSG_H_OFFSET 0 +#define RTL8367C_LINE_RATE_HSG_H_MASK 0x7 + +#define RTL8367C_REG_LINE_RATE_HSG_L 0x03fb + +/* (16'h0500)table_reg */ + +#define RTL8367C_REG_TABLE_ACCESS_CTRL 0x0500 +#define RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET 8 +#define RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK 0xF00 +#define RTL8367C_ACCESS_METHOD_OFFSET 4 +#define RTL8367C_ACCESS_METHOD_MASK 0x70 +#define RTL8367C_COMMAND_TYPE_OFFSET 3 +#define RTL8367C_COMMAND_TYPE_MASK 0x8 +#define RTL8367C_TABLE_TYPE_OFFSET 0 +#define RTL8367C_TABLE_TYPE_MASK 0x7 + +#define RTL8367C_REG_TABLE_ACCESS_ADDR 0x0501 +#define RTL8367C_TABLE_ACCESS_ADDR_OFFSET 0 +#define RTL8367C_TABLE_ACCESS_ADDR_MASK 0x1FFF + +#define RTL8367C_REG_TABLE_LUT_ADDR 0x0502 +#define RTL8367C_ADDRESS2_OFFSET 14 +#define RTL8367C_ADDRESS2_MASK 0x4000 +#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET 13 +#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_MASK 0x2000 +#define RTL8367C_HIT_STATUS_OFFSET 12 +#define RTL8367C_HIT_STATUS_MASK 0x1000 +#define RTL8367C_TABLE_LUT_ADDR_TYPE_OFFSET 11 +#define RTL8367C_TABLE_LUT_ADDR_TYPE_MASK 0x800 +#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_OFFSET 0 +#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK 0x7FF + +#define RTL8367C_REG_HSA_HSB_LATCH 0x0503 +#define RTL8367C_LATCH_ALWAYS_OFFSET 15 +#define RTL8367C_LATCH_ALWAYS_MASK 0x8000 +#define RTL8367C_LATCH_FIRST_OFFSET 14 +#define RTL8367C_LATCH_FIRST_MASK 0x4000 +#define RTL8367C_SPA_EN_OFFSET 13 +#define RTL8367C_SPA_EN_MASK 0x2000 +#define RTL8367C_FORWARD_EN_OFFSET 12 +#define RTL8367C_FORWARD_EN_MASK 0x1000 +#define RTL8367C_REASON_EN_OFFSET 11 +#define RTL8367C_REASON_EN_MASK 0x800 +#define RTL8367C_HSA_HSB_LATCH_SPA_OFFSET 8 +#define RTL8367C_HSA_HSB_LATCH_SPA_MASK 0x700 +#define RTL8367C_FORWARD_OFFSET 6 +#define RTL8367C_FORWARD_MASK 0xC0 +#define RTL8367C_REASON_OFFSET 0 +#define RTL8367C_REASON_MASK 0x3F + +#define RTL8367C_REG_HSA_HSB_LATCH2 0x0504 +#define RTL8367C_HSA_HSB_LATCH2_Reserved_OFFSET 1 +#define RTL8367C_HSA_HSB_LATCH2_Reserved_MASK 0xFFFE +#define RTL8367C_SPA2_OFFSET 0 +#define RTL8367C_SPA2_MASK 0x1 + +#define RTL8367C_REG_TABLE_WRITE_DATA0 0x0510 + +#define RTL8367C_REG_TABLE_WRITE_DATA1 0x0511 + +#define RTL8367C_REG_TABLE_WRITE_DATA2 0x0512 + +#define RTL8367C_REG_TABLE_WRITE_DATA3 0x0513 + +#define RTL8367C_REG_TABLE_WRITE_DATA4 0x0514 + +#define RTL8367C_REG_TABLE_WRITE_DATA5 0x0515 + +#define RTL8367C_REG_TABLE_WRITE_DATA6 0x0516 + +#define RTL8367C_REG_TABLE_WRITE_DATA7 0x0517 + +#define RTL8367C_REG_TABLE_WRITE_DATA8 0x0518 + +#define RTL8367C_REG_TABLE_WRITE_DATA9 0x0519 +#define RTL8367C_TABLE_WRITE_DATA9_OFFSET 0 +#define RTL8367C_TABLE_WRITE_DATA9_MASK 0xF + +#define RTL8367C_REG_TABLE_READ_DATA0 0x0520 + +#define RTL8367C_REG_TABLE_READ_DATA1 0x0521 + +#define RTL8367C_REG_TABLE_READ_DATA2 0x0522 + +#define RTL8367C_REG_TABLE_READ_DATA3 0x0523 + +#define RTL8367C_REG_TABLE_READ_DATA4 0x0524 + +#define RTL8367C_REG_TABLE_READ_DATA5 0x0525 + +#define RTL8367C_REG_TABLE_READ_DATA6 0x0526 + +#define RTL8367C_REG_TABLE_READ_DATA7 0x0527 + +#define RTL8367C_REG_TABLE_READ_DATA8 0x0528 + +#define RTL8367C_REG_TABLE_READ_DATA9 0x0529 +#define RTL8367C_TABLE_READ_DATA9_OFFSET 0 +#define RTL8367C_TABLE_READ_DATA9_MASK 0xF + +#define RTL8367C_REG_TBL_DUMMY00 0x0550 + +#define RTL8367C_REG_TBL_DUMMY01 0x0551 + +/* (16'h0600)acl_reg */ + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 0x0600 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL1 0x0601 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL2 0x0602 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL3 0x0603 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL0 0x0604 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL1 0x0605 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL2 0x0606 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL3 0x0607 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL0 0x0608 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL1 0x0609 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL2 0x060a +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL3 0x060b +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL0 0x060c +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL1 0x060d +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL2 0x060e +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL3 0x060f +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL0 0x0610 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL1 0x0611 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL2 0x0612 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL3 0x0613 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_ACTION_CTRL0 0x0614 +#define RTL8367C_OP1_NOT_OFFSET 14 +#define RTL8367C_OP1_NOT_MASK 0x4000 +#define RTL8367C_ACT1_GPIO_OFFSET 13 +#define RTL8367C_ACT1_GPIO_MASK 0x2000 +#define RTL8367C_ACT1_FORWARD_OFFSET 12 +#define RTL8367C_ACT1_FORWARD_MASK 0x1000 +#define RTL8367C_ACT1_POLICING_OFFSET 11 +#define RTL8367C_ACT1_POLICING_MASK 0x800 +#define RTL8367C_ACT1_PRIORITY_OFFSET 10 +#define RTL8367C_ACT1_PRIORITY_MASK 0x400 +#define RTL8367C_ACT1_SVID_OFFSET 9 +#define RTL8367C_ACT1_SVID_MASK 0x200 +#define RTL8367C_ACT1_CVID_OFFSET 8 +#define RTL8367C_ACT1_CVID_MASK 0x100 +#define RTL8367C_OP0_NOT_OFFSET 6 +#define RTL8367C_OP0_NOT_MASK 0x40 +#define RTL8367C_ACT0_GPIO_OFFSET 5 +#define RTL8367C_ACT0_GPIO_MASK 0x20 +#define RTL8367C_ACT0_FORWARD_OFFSET 4 +#define RTL8367C_ACT0_FORWARD_MASK 0x10 +#define RTL8367C_ACT0_POLICING_OFFSET 3 +#define RTL8367C_ACT0_POLICING_MASK 0x8 +#define RTL8367C_ACT0_PRIORITY_OFFSET 2 +#define RTL8367C_ACT0_PRIORITY_MASK 0x4 +#define RTL8367C_ACT0_SVID_OFFSET 1 +#define RTL8367C_ACT0_SVID_MASK 0x2 +#define RTL8367C_ACT0_CVID_OFFSET 0 +#define RTL8367C_ACT0_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL1 0x0615 +#define RTL8367C_OP3_NOT_OFFSET 14 +#define RTL8367C_OP3_NOT_MASK 0x4000 +#define RTL8367C_ACT3_GPIO_OFFSET 13 +#define RTL8367C_ACT3_GPIO_MASK 0x2000 +#define RTL8367C_ACT3_FORWARD_OFFSET 12 +#define RTL8367C_ACT3_FORWARD_MASK 0x1000 +#define RTL8367C_ACT3_POLICING_OFFSET 11 +#define RTL8367C_ACT3_POLICING_MASK 0x800 +#define RTL8367C_ACT3_PRIORITY_OFFSET 10 +#define RTL8367C_ACT3_PRIORITY_MASK 0x400 +#define RTL8367C_ACT3_SVID_OFFSET 9 +#define RTL8367C_ACT3_SVID_MASK 0x200 +#define RTL8367C_ACT3_CVID_OFFSET 8 +#define RTL8367C_ACT3_CVID_MASK 0x100 +#define RTL8367C_OP2_NOT_OFFSET 6 +#define RTL8367C_OP2_NOT_MASK 0x40 +#define RTL8367C_ACT2_GPIO_OFFSET 5 +#define RTL8367C_ACT2_GPIO_MASK 0x20 +#define RTL8367C_ACT2_FORWARD_OFFSET 4 +#define RTL8367C_ACT2_FORWARD_MASK 0x10 +#define RTL8367C_ACT2_POLICING_OFFSET 3 +#define RTL8367C_ACT2_POLICING_MASK 0x8 +#define RTL8367C_ACT2_PRIORITY_OFFSET 2 +#define RTL8367C_ACT2_PRIORITY_MASK 0x4 +#define RTL8367C_ACT2_SVID_OFFSET 1 +#define RTL8367C_ACT2_SVID_MASK 0x2 +#define RTL8367C_ACT2_CVID_OFFSET 0 +#define RTL8367C_ACT2_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL2 0x0616 +#define RTL8367C_OP5_NOT_OFFSET 14 +#define RTL8367C_OP5_NOT_MASK 0x4000 +#define RTL8367C_ACT5_GPIO_OFFSET 13 +#define RTL8367C_ACT5_GPIO_MASK 0x2000 +#define RTL8367C_ACT5_FORWARD_OFFSET 12 +#define RTL8367C_ACT5_FORWARD_MASK 0x1000 +#define RTL8367C_ACT5_POLICING_OFFSET 11 +#define RTL8367C_ACT5_POLICING_MASK 0x800 +#define RTL8367C_ACT5_PRIORITY_OFFSET 10 +#define RTL8367C_ACT5_PRIORITY_MASK 0x400 +#define RTL8367C_ACT5_SVID_OFFSET 9 +#define RTL8367C_ACT5_SVID_MASK 0x200 +#define RTL8367C_ACT5_CVID_OFFSET 8 +#define RTL8367C_ACT5_CVID_MASK 0x100 +#define RTL8367C_OP4_NOT_OFFSET 6 +#define RTL8367C_OP4_NOT_MASK 0x40 +#define RTL8367C_ACT4_GPIO_OFFSET 5 +#define RTL8367C_ACT4_GPIO_MASK 0x20 +#define RTL8367C_ACT4_FORWARD_OFFSET 4 +#define RTL8367C_ACT4_FORWARD_MASK 0x10 +#define RTL8367C_ACT4_POLICING_OFFSET 3 +#define RTL8367C_ACT4_POLICING_MASK 0x8 +#define RTL8367C_ACT4_PRIORITY_OFFSET 2 +#define RTL8367C_ACT4_PRIORITY_MASK 0x4 +#define RTL8367C_ACT4_SVID_OFFSET 1 +#define RTL8367C_ACT4_SVID_MASK 0x2 +#define RTL8367C_ACT4_CVID_OFFSET 0 +#define RTL8367C_ACT4_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL3 0x0617 +#define RTL8367C_OP7_NOT_OFFSET 14 +#define RTL8367C_OP7_NOT_MASK 0x4000 +#define RTL8367C_ACT7_GPIO_OFFSET 13 +#define RTL8367C_ACT7_GPIO_MASK 0x2000 +#define RTL8367C_ACT7_FORWARD_OFFSET 12 +#define RTL8367C_ACT7_FORWARD_MASK 0x1000 +#define RTL8367C_ACT7_POLICING_OFFSET 11 +#define RTL8367C_ACT7_POLICING_MASK 0x800 +#define RTL8367C_ACT7_PRIORITY_OFFSET 10 +#define RTL8367C_ACT7_PRIORITY_MASK 0x400 +#define RTL8367C_ACT7_SVID_OFFSET 9 +#define RTL8367C_ACT7_SVID_MASK 0x200 +#define RTL8367C_ACT7_CVID_OFFSET 8 +#define RTL8367C_ACT7_CVID_MASK 0x100 +#define RTL8367C_OP6_NOT_OFFSET 6 +#define RTL8367C_OP6_NOT_MASK 0x40 +#define RTL8367C_ACT6_GPIO_OFFSET 5 +#define RTL8367C_ACT6_GPIO_MASK 0x20 +#define RTL8367C_ACT6_FORWARD_OFFSET 4 +#define RTL8367C_ACT6_FORWARD_MASK 0x10 +#define RTL8367C_ACT6_POLICING_OFFSET 3 +#define RTL8367C_ACT6_POLICING_MASK 0x8 +#define RTL8367C_ACT6_PRIORITY_OFFSET 2 +#define RTL8367C_ACT6_PRIORITY_MASK 0x4 +#define RTL8367C_ACT6_SVID_OFFSET 1 +#define RTL8367C_ACT6_SVID_MASK 0x2 +#define RTL8367C_ACT6_CVID_OFFSET 0 +#define RTL8367C_ACT6_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL4 0x0618 +#define RTL8367C_OP9_NOT_OFFSET 14 +#define RTL8367C_OP9_NOT_MASK 0x4000 +#define RTL8367C_ACT9_GPIO_OFFSET 13 +#define RTL8367C_ACT9_GPIO_MASK 0x2000 +#define RTL8367C_ACT9_FORWARD_OFFSET 12 +#define RTL8367C_ACT9_FORWARD_MASK 0x1000 +#define RTL8367C_ACT9_POLICING_OFFSET 11 +#define RTL8367C_ACT9_POLICING_MASK 0x800 +#define RTL8367C_ACT9_PRIORITY_OFFSET 10 +#define RTL8367C_ACT9_PRIORITY_MASK 0x400 +#define RTL8367C_ACT9_SVID_OFFSET 9 +#define RTL8367C_ACT9_SVID_MASK 0x200 +#define RTL8367C_ACT9_CVID_OFFSET 8 +#define RTL8367C_ACT9_CVID_MASK 0x100 +#define RTL8367C_OP8_NOT_OFFSET 6 +#define RTL8367C_OP8_NOT_MASK 0x40 +#define RTL8367C_ACT8_GPIO_OFFSET 5 +#define RTL8367C_ACT8_GPIO_MASK 0x20 +#define RTL8367C_ACT8_FORWARD_OFFSET 4 +#define RTL8367C_ACT8_FORWARD_MASK 0x10 +#define RTL8367C_ACT8_POLICING_OFFSET 3 +#define RTL8367C_ACT8_POLICING_MASK 0x8 +#define RTL8367C_ACT8_PRIORITY_OFFSET 2 +#define RTL8367C_ACT8_PRIORITY_MASK 0x4 +#define RTL8367C_ACT8_SVID_OFFSET 1 +#define RTL8367C_ACT8_SVID_MASK 0x2 +#define RTL8367C_ACT8_CVID_OFFSET 0 +#define RTL8367C_ACT8_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL5 0x0619 +#define RTL8367C_OP11_NOT_OFFSET 14 +#define RTL8367C_OP11_NOT_MASK 0x4000 +#define RTL8367C_ACT11_GPIO_OFFSET 13 +#define RTL8367C_ACT11_GPIO_MASK 0x2000 +#define RTL8367C_ACT11_FORWARD_OFFSET 12 +#define RTL8367C_ACT11_FORWARD_MASK 0x1000 +#define RTL8367C_ACT11_POLICING_OFFSET 11 +#define RTL8367C_ACT11_POLICING_MASK 0x800 +#define RTL8367C_ACT11_PRIORITY_OFFSET 10 +#define RTL8367C_ACT11_PRIORITY_MASK 0x400 +#define RTL8367C_ACT11_SVID_OFFSET 9 +#define RTL8367C_ACT11_SVID_MASK 0x200 +#define RTL8367C_ACT11_CVID_OFFSET 8 +#define RTL8367C_ACT11_CVID_MASK 0x100 +#define RTL8367C_OP10_NOT_OFFSET 6 +#define RTL8367C_OP10_NOT_MASK 0x40 +#define RTL8367C_ACT10_GPIO_OFFSET 5 +#define RTL8367C_ACT10_GPIO_MASK 0x20 +#define RTL8367C_ACT10_FORWARD_OFFSET 4 +#define RTL8367C_ACT10_FORWARD_MASK 0x10 +#define RTL8367C_ACT10_POLICING_OFFSET 3 +#define RTL8367C_ACT10_POLICING_MASK 0x8 +#define RTL8367C_ACT10_PRIORITY_OFFSET 2 +#define RTL8367C_ACT10_PRIORITY_MASK 0x4 +#define RTL8367C_ACT10_SVID_OFFSET 1 +#define RTL8367C_ACT10_SVID_MASK 0x2 +#define RTL8367C_ACT10_CVID_OFFSET 0 +#define RTL8367C_ACT10_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL6 0x061a +#define RTL8367C_OP13_NOT_OFFSET 14 +#define RTL8367C_OP13_NOT_MASK 0x4000 +#define RTL8367C_ACT13_GPIO_OFFSET 13 +#define RTL8367C_ACT13_GPIO_MASK 0x2000 +#define RTL8367C_ACT13_FORWARD_OFFSET 12 +#define RTL8367C_ACT13_FORWARD_MASK 0x1000 +#define RTL8367C_ACT13_POLICING_OFFSET 11 +#define RTL8367C_ACT13_POLICING_MASK 0x800 +#define RTL8367C_ACT13_PRIORITY_OFFSET 10 +#define RTL8367C_ACT13_PRIORITY_MASK 0x400 +#define RTL8367C_ACT13_SVID_OFFSET 9 +#define RTL8367C_ACT13_SVID_MASK 0x200 +#define RTL8367C_ACT13_CVID_OFFSET 8 +#define RTL8367C_ACT13_CVID_MASK 0x100 +#define RTL8367C_OP12_NOT_OFFSET 6 +#define RTL8367C_OP12_NOT_MASK 0x40 +#define RTL8367C_ACT12_GPIO_OFFSET 5 +#define RTL8367C_ACT12_GPIO_MASK 0x20 +#define RTL8367C_ACT12_FORWARD_OFFSET 4 +#define RTL8367C_ACT12_FORWARD_MASK 0x10 +#define RTL8367C_ACT12_POLICING_OFFSET 3 +#define RTL8367C_ACT12_POLICING_MASK 0x8 +#define RTL8367C_ACT12_PRIORITY_OFFSET 2 +#define RTL8367C_ACT12_PRIORITY_MASK 0x4 +#define RTL8367C_ACT12_SVID_OFFSET 1 +#define RTL8367C_ACT12_SVID_MASK 0x2 +#define RTL8367C_ACT12_CVID_OFFSET 0 +#define RTL8367C_ACT12_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL7 0x061b +#define RTL8367C_OP15_NOT_OFFSET 14 +#define RTL8367C_OP15_NOT_MASK 0x4000 +#define RTL8367C_ACT15_GPIO_OFFSET 13 +#define RTL8367C_ACT15_GPIO_MASK 0x2000 +#define RTL8367C_ACT15_FORWARD_OFFSET 12 +#define RTL8367C_ACT15_FORWARD_MASK 0x1000 +#define RTL8367C_ACT15_POLICING_OFFSET 11 +#define RTL8367C_ACT15_POLICING_MASK 0x800 +#define RTL8367C_ACT15_PRIORITY_OFFSET 10 +#define RTL8367C_ACT15_PRIORITY_MASK 0x400 +#define RTL8367C_ACT15_SVID_OFFSET 9 +#define RTL8367C_ACT15_SVID_MASK 0x200 +#define RTL8367C_ACT15_CVID_OFFSET 8 +#define RTL8367C_ACT15_CVID_MASK 0x100 +#define RTL8367C_OP14_NOT_OFFSET 6 +#define RTL8367C_OP14_NOT_MASK 0x40 +#define RTL8367C_ACT14_GPIO_OFFSET 5 +#define RTL8367C_ACT14_GPIO_MASK 0x20 +#define RTL8367C_ACT14_FORWARD_OFFSET 4 +#define RTL8367C_ACT14_FORWARD_MASK 0x10 +#define RTL8367C_ACT14_POLICING_OFFSET 3 +#define RTL8367C_ACT14_POLICING_MASK 0x8 +#define RTL8367C_ACT14_PRIORITY_OFFSET 2 +#define RTL8367C_ACT14_PRIORITY_MASK 0x4 +#define RTL8367C_ACT14_SVID_OFFSET 1 +#define RTL8367C_ACT14_SVID_MASK 0x2 +#define RTL8367C_ACT14_CVID_OFFSET 0 +#define RTL8367C_ACT14_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL8 0x061c +#define RTL8367C_OP17_NOT_OFFSET 14 +#define RTL8367C_OP17_NOT_MASK 0x4000 +#define RTL8367C_ACT17_GPIO_OFFSET 13 +#define RTL8367C_ACT17_GPIO_MASK 0x2000 +#define RTL8367C_ACT17_FORWARD_OFFSET 12 +#define RTL8367C_ACT17_FORWARD_MASK 0x1000 +#define RTL8367C_ACT17_POLICING_OFFSET 11 +#define RTL8367C_ACT17_POLICING_MASK 0x800 +#define RTL8367C_ACT17_PRIORITY_OFFSET 10 +#define RTL8367C_ACT17_PRIORITY_MASK 0x400 +#define RTL8367C_ACT17_SVID_OFFSET 9 +#define RTL8367C_ACT17_SVID_MASK 0x200 +#define RTL8367C_ACT17_CVID_OFFSET 8 +#define RTL8367C_ACT17_CVID_MASK 0x100 +#define RTL8367C_OP16_NOT_OFFSET 6 +#define RTL8367C_OP16_NOT_MASK 0x40 +#define RTL8367C_ACT16_GPIO_OFFSET 5 +#define RTL8367C_ACT16_GPIO_MASK 0x20 +#define RTL8367C_ACT16_FORWARD_OFFSET 4 +#define RTL8367C_ACT16_FORWARD_MASK 0x10 +#define RTL8367C_ACT16_POLICING_OFFSET 3 +#define RTL8367C_ACT16_POLICING_MASK 0x8 +#define RTL8367C_ACT16_PRIORITY_OFFSET 2 +#define RTL8367C_ACT16_PRIORITY_MASK 0x4 +#define RTL8367C_ACT16_SVID_OFFSET 1 +#define RTL8367C_ACT16_SVID_MASK 0x2 +#define RTL8367C_ACT16_CVID_OFFSET 0 +#define RTL8367C_ACT16_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL9 0x061d +#define RTL8367C_OP19_NOT_OFFSET 14 +#define RTL8367C_OP19_NOT_MASK 0x4000 +#define RTL8367C_ACT19_GPIO_OFFSET 13 +#define RTL8367C_ACT19_GPIO_MASK 0x2000 +#define RTL8367C_ACT19_FORWARD_OFFSET 12 +#define RTL8367C_ACT19_FORWARD_MASK 0x1000 +#define RTL8367C_ACT19_POLICING_OFFSET 11 +#define RTL8367C_ACT19_POLICING_MASK 0x800 +#define RTL8367C_ACT19_PRIORITY_OFFSET 10 +#define RTL8367C_ACT19_PRIORITY_MASK 0x400 +#define RTL8367C_ACT19_SVID_OFFSET 9 +#define RTL8367C_ACT19_SVID_MASK 0x200 +#define RTL8367C_ACT19_CVID_OFFSET 8 +#define RTL8367C_ACT19_CVID_MASK 0x100 +#define RTL8367C_OP18_NOT_OFFSET 6 +#define RTL8367C_OP18_NOT_MASK 0x40 +#define RTL8367C_ACT18_GPIO_OFFSET 5 +#define RTL8367C_ACT18_GPIO_MASK 0x20 +#define RTL8367C_ACT18_FORWARD_OFFSET 4 +#define RTL8367C_ACT18_FORWARD_MASK 0x10 +#define RTL8367C_ACT18_POLICING_OFFSET 3 +#define RTL8367C_ACT18_POLICING_MASK 0x8 +#define RTL8367C_ACT18_PRIORITY_OFFSET 2 +#define RTL8367C_ACT18_PRIORITY_MASK 0x4 +#define RTL8367C_ACT18_SVID_OFFSET 1 +#define RTL8367C_ACT18_SVID_MASK 0x2 +#define RTL8367C_ACT18_CVID_OFFSET 0 +#define RTL8367C_ACT18_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL10 0x061e +#define RTL8367C_OP21_NOT_OFFSET 14 +#define RTL8367C_OP21_NOT_MASK 0x4000 +#define RTL8367C_ACT21_GPIO_OFFSET 13 +#define RTL8367C_ACT21_GPIO_MASK 0x2000 +#define RTL8367C_ACT21_FORWARD_OFFSET 12 +#define RTL8367C_ACT21_FORWARD_MASK 0x1000 +#define RTL8367C_ACT21_POLICING_OFFSET 11 +#define RTL8367C_ACT21_POLICING_MASK 0x800 +#define RTL8367C_ACT21_PRIORITY_OFFSET 10 +#define RTL8367C_ACT21_PRIORITY_MASK 0x400 +#define RTL8367C_ACT21_SVID_OFFSET 9 +#define RTL8367C_ACT21_SVID_MASK 0x200 +#define RTL8367C_ACT21_CVID_OFFSET 8 +#define RTL8367C_ACT21_CVID_MASK 0x100 +#define RTL8367C_OP20_NOT_OFFSET 6 +#define RTL8367C_OP20_NOT_MASK 0x40 +#define RTL8367C_ACT20_GPIO_OFFSET 5 +#define RTL8367C_ACT20_GPIO_MASK 0x20 +#define RTL8367C_ACT20_FORWARD_OFFSET 4 +#define RTL8367C_ACT20_FORWARD_MASK 0x10 +#define RTL8367C_ACT20_POLICING_OFFSET 3 +#define RTL8367C_ACT20_POLICING_MASK 0x8 +#define RTL8367C_ACT20_PRIORITY_OFFSET 2 +#define RTL8367C_ACT20_PRIORITY_MASK 0x4 +#define RTL8367C_ACT20_SVID_OFFSET 1 +#define RTL8367C_ACT20_SVID_MASK 0x2 +#define RTL8367C_ACT20_CVID_OFFSET 0 +#define RTL8367C_ACT20_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL11 0x061f +#define RTL8367C_OP23_NOT_OFFSET 14 +#define RTL8367C_OP23_NOT_MASK 0x4000 +#define RTL8367C_ACT23_GPIO_OFFSET 13 +#define RTL8367C_ACT23_GPIO_MASK 0x2000 +#define RTL8367C_ACT23_FORWARD_OFFSET 12 +#define RTL8367C_ACT23_FORWARD_MASK 0x1000 +#define RTL8367C_ACT23_POLICING_OFFSET 11 +#define RTL8367C_ACT23_POLICING_MASK 0x800 +#define RTL8367C_ACT23_PRIORITY_OFFSET 10 +#define RTL8367C_ACT23_PRIORITY_MASK 0x400 +#define RTL8367C_ACT23_SVID_OFFSET 9 +#define RTL8367C_ACT23_SVID_MASK 0x200 +#define RTL8367C_ACT23_CVID_OFFSET 8 +#define RTL8367C_ACT23_CVID_MASK 0x100 +#define RTL8367C_OP22_NOT_OFFSET 6 +#define RTL8367C_OP22_NOT_MASK 0x40 +#define RTL8367C_ACT22_GPIO_OFFSET 5 +#define RTL8367C_ACT22_GPIO_MASK 0x20 +#define RTL8367C_ACT22_FORWARD_OFFSET 4 +#define RTL8367C_ACT22_FORWARD_MASK 0x10 +#define RTL8367C_ACT22_POLICING_OFFSET 3 +#define RTL8367C_ACT22_POLICING_MASK 0x8 +#define RTL8367C_ACT22_PRIORITY_OFFSET 2 +#define RTL8367C_ACT22_PRIORITY_MASK 0x4 +#define RTL8367C_ACT22_SVID_OFFSET 1 +#define RTL8367C_ACT22_SVID_MASK 0x2 +#define RTL8367C_ACT22_CVID_OFFSET 0 +#define RTL8367C_ACT22_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL12 0x0620 +#define RTL8367C_OP25_NOT_OFFSET 14 +#define RTL8367C_OP25_NOT_MASK 0x4000 +#define RTL8367C_ACT25_GPIO_OFFSET 13 +#define RTL8367C_ACT25_GPIO_MASK 0x2000 +#define RTL8367C_ACT25_FORWARD_OFFSET 12 +#define RTL8367C_ACT25_FORWARD_MASK 0x1000 +#define RTL8367C_ACT25_POLICING_OFFSET 11 +#define RTL8367C_ACT25_POLICING_MASK 0x800 +#define RTL8367C_ACT25_PRIORITY_OFFSET 10 +#define RTL8367C_ACT25_PRIORITY_MASK 0x400 +#define RTL8367C_ACT25_SVID_OFFSET 9 +#define RTL8367C_ACT25_SVID_MASK 0x200 +#define RTL8367C_ACT25_CVID_OFFSET 8 +#define RTL8367C_ACT25_CVID_MASK 0x100 +#define RTL8367C_OP24_NOT_OFFSET 6 +#define RTL8367C_OP24_NOT_MASK 0x40 +#define RTL8367C_ACT24_GPIO_OFFSET 5 +#define RTL8367C_ACT24_GPIO_MASK 0x20 +#define RTL8367C_ACT24_FORWARD_OFFSET 4 +#define RTL8367C_ACT24_FORWARD_MASK 0x10 +#define RTL8367C_ACT24_POLICING_OFFSET 3 +#define RTL8367C_ACT24_POLICING_MASK 0x8 +#define RTL8367C_ACT24_PRIORITY_OFFSET 2 +#define RTL8367C_ACT24_PRIORITY_MASK 0x4 +#define RTL8367C_ACT24_SVID_OFFSET 1 +#define RTL8367C_ACT24_SVID_MASK 0x2 +#define RTL8367C_ACT24_CVID_OFFSET 0 +#define RTL8367C_ACT24_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL13 0x0621 +#define RTL8367C_OP27_NOT_OFFSET 14 +#define RTL8367C_OP27_NOT_MASK 0x4000 +#define RTL8367C_ACT27_GPIO_OFFSET 13 +#define RTL8367C_ACT27_GPIO_MASK 0x2000 +#define RTL8367C_ACT27_FORWARD_OFFSET 12 +#define RTL8367C_ACT27_FORWARD_MASK 0x1000 +#define RTL8367C_ACT27_POLICING_OFFSET 11 +#define RTL8367C_ACT27_POLICING_MASK 0x800 +#define RTL8367C_ACT27_PRIORITY_OFFSET 10 +#define RTL8367C_ACT27_PRIORITY_MASK 0x400 +#define RTL8367C_ACT27_SVID_OFFSET 9 +#define RTL8367C_ACT27_SVID_MASK 0x200 +#define RTL8367C_ACT27_CVID_OFFSET 8 +#define RTL8367C_ACT27_CVID_MASK 0x100 +#define RTL8367C_OP26_NOT_OFFSET 6 +#define RTL8367C_OP26_NOT_MASK 0x40 +#define RTL8367C_ACT26_GPIO_OFFSET 5 +#define RTL8367C_ACT26_GPIO_MASK 0x20 +#define RTL8367C_ACT26_FORWARD_OFFSET 4 +#define RTL8367C_ACT26_FORWARD_MASK 0x10 +#define RTL8367C_ACT26_POLICING_OFFSET 3 +#define RTL8367C_ACT26_POLICING_MASK 0x8 +#define RTL8367C_ACT26_PRIORITY_OFFSET 2 +#define RTL8367C_ACT26_PRIORITY_MASK 0x4 +#define RTL8367C_ACT26_SVID_OFFSET 1 +#define RTL8367C_ACT26_SVID_MASK 0x2 +#define RTL8367C_ACT26_CVID_OFFSET 0 +#define RTL8367C_ACT26_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL14 0x0622 +#define RTL8367C_OP29_NOT_OFFSET 14 +#define RTL8367C_OP29_NOT_MASK 0x4000 +#define RTL8367C_ACT29_GPIO_OFFSET 13 +#define RTL8367C_ACT29_GPIO_MASK 0x2000 +#define RTL8367C_ACT29_FORWARD_OFFSET 12 +#define RTL8367C_ACT29_FORWARD_MASK 0x1000 +#define RTL8367C_ACT29_POLICING_OFFSET 11 +#define RTL8367C_ACT29_POLICING_MASK 0x800 +#define RTL8367C_ACT29_PRIORITY_OFFSET 10 +#define RTL8367C_ACT29_PRIORITY_MASK 0x400 +#define RTL8367C_ACT29_SVID_OFFSET 9 +#define RTL8367C_ACT29_SVID_MASK 0x200 +#define RTL8367C_ACT29_CVID_OFFSET 8 +#define RTL8367C_ACT29_CVID_MASK 0x100 +#define RTL8367C_OP28_NOT_OFFSET 6 +#define RTL8367C_OP28_NOT_MASK 0x40 +#define RTL8367C_ACT28_GPIO_OFFSET 5 +#define RTL8367C_ACT28_GPIO_MASK 0x20 +#define RTL8367C_ACT28_FORWARD_OFFSET 4 +#define RTL8367C_ACT28_FORWARD_MASK 0x10 +#define RTL8367C_ACT28_POLICING_OFFSET 3 +#define RTL8367C_ACT28_POLICING_MASK 0x8 +#define RTL8367C_ACT28_PRIORITY_OFFSET 2 +#define RTL8367C_ACT28_PRIORITY_MASK 0x4 +#define RTL8367C_ACT28_SVID_OFFSET 1 +#define RTL8367C_ACT28_SVID_MASK 0x2 +#define RTL8367C_ACT28_CVID_OFFSET 0 +#define RTL8367C_ACT28_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL15 0x0623 +#define RTL8367C_OP31_NOT_OFFSET 14 +#define RTL8367C_OP31_NOT_MASK 0x4000 +#define RTL8367C_ACT31_GPIO_OFFSET 13 +#define RTL8367C_ACT31_GPIO_MASK 0x2000 +#define RTL8367C_ACT31_FORWARD_OFFSET 12 +#define RTL8367C_ACT31_FORWARD_MASK 0x1000 +#define RTL8367C_ACT31_POLICING_OFFSET 11 +#define RTL8367C_ACT31_POLICING_MASK 0x800 +#define RTL8367C_ACT31_PRIORITY_OFFSET 10 +#define RTL8367C_ACT31_PRIORITY_MASK 0x400 +#define RTL8367C_ACT31_SVID_OFFSET 9 +#define RTL8367C_ACT31_SVID_MASK 0x200 +#define RTL8367C_ACT31_CVID_OFFSET 8 +#define RTL8367C_ACT31_CVID_MASK 0x100 +#define RTL8367C_OP30_NOT_OFFSET 6 +#define RTL8367C_OP30_NOT_MASK 0x40 +#define RTL8367C_ACT30_GPIO_OFFSET 5 +#define RTL8367C_ACT30_GPIO_MASK 0x20 +#define RTL8367C_ACT30_FORWARD_OFFSET 4 +#define RTL8367C_ACT30_FORWARD_MASK 0x10 +#define RTL8367C_ACT30_POLICING_OFFSET 3 +#define RTL8367C_ACT30_POLICING_MASK 0x8 +#define RTL8367C_ACT30_PRIORITY_OFFSET 2 +#define RTL8367C_ACT30_PRIORITY_MASK 0x4 +#define RTL8367C_ACT30_SVID_OFFSET 1 +#define RTL8367C_ACT30_SVID_MASK 0x2 +#define RTL8367C_ACT30_CVID_OFFSET 0 +#define RTL8367C_ACT30_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL16 0x0624 +#define RTL8367C_OP33_NOT_OFFSET 14 +#define RTL8367C_OP33_NOT_MASK 0x4000 +#define RTL8367C_ACT33_GPIO_OFFSET 13 +#define RTL8367C_ACT33_GPIO_MASK 0x2000 +#define RTL8367C_ACT33_FORWARD_OFFSET 12 +#define RTL8367C_ACT33_FORWARD_MASK 0x1000 +#define RTL8367C_ACT33_POLICING_OFFSET 11 +#define RTL8367C_ACT33_POLICING_MASK 0x800 +#define RTL8367C_ACT33_PRIORITY_OFFSET 10 +#define RTL8367C_ACT33_PRIORITY_MASK 0x400 +#define RTL8367C_ACT33_SVID_OFFSET 9 +#define RTL8367C_ACT33_SVID_MASK 0x200 +#define RTL8367C_ACT33_CVID_OFFSET 8 +#define RTL8367C_ACT33_CVID_MASK 0x100 +#define RTL8367C_OP32_NOT_OFFSET 6 +#define RTL8367C_OP32_NOT_MASK 0x40 +#define RTL8367C_ACT32_GPIO_OFFSET 5 +#define RTL8367C_ACT32_GPIO_MASK 0x20 +#define RTL8367C_ACT32_FORWARD_OFFSET 4 +#define RTL8367C_ACT32_FORWARD_MASK 0x10 +#define RTL8367C_ACT32_POLICING_OFFSET 3 +#define RTL8367C_ACT32_POLICING_MASK 0x8 +#define RTL8367C_ACT32_PRIORITY_OFFSET 2 +#define RTL8367C_ACT32_PRIORITY_MASK 0x4 +#define RTL8367C_ACT32_SVID_OFFSET 1 +#define RTL8367C_ACT32_SVID_MASK 0x2 +#define RTL8367C_ACT32_CVID_OFFSET 0 +#define RTL8367C_ACT32_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL17 0x0625 +#define RTL8367C_OP35_NOT_OFFSET 14 +#define RTL8367C_OP35_NOT_MASK 0x4000 +#define RTL8367C_ACT35_GPIO_OFFSET 13 +#define RTL8367C_ACT35_GPIO_MASK 0x2000 +#define RTL8367C_ACT35_FORWARD_OFFSET 12 +#define RTL8367C_ACT35_FORWARD_MASK 0x1000 +#define RTL8367C_ACT35_POLICING_OFFSET 11 +#define RTL8367C_ACT35_POLICING_MASK 0x800 +#define RTL8367C_ACT35_PRIORITY_OFFSET 10 +#define RTL8367C_ACT35_PRIORITY_MASK 0x400 +#define RTL8367C_ACT35_SVID_OFFSET 9 +#define RTL8367C_ACT35_SVID_MASK 0x200 +#define RTL8367C_ACT35_CVID_OFFSET 8 +#define RTL8367C_ACT35_CVID_MASK 0x100 +#define RTL8367C_OP34_NOT_OFFSET 6 +#define RTL8367C_OP34_NOT_MASK 0x40 +#define RTL8367C_ACT34_GPIO_OFFSET 5 +#define RTL8367C_ACT34_GPIO_MASK 0x20 +#define RTL8367C_ACT34_FORWARD_OFFSET 4 +#define RTL8367C_ACT34_FORWARD_MASK 0x10 +#define RTL8367C_ACT34_POLICING_OFFSET 3 +#define RTL8367C_ACT34_POLICING_MASK 0x8 +#define RTL8367C_ACT34_PRIORITY_OFFSET 2 +#define RTL8367C_ACT34_PRIORITY_MASK 0x4 +#define RTL8367C_ACT34_SVID_OFFSET 1 +#define RTL8367C_ACT34_SVID_MASK 0x2 +#define RTL8367C_ACT34_CVID_OFFSET 0 +#define RTL8367C_ACT34_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL18 0x0626 +#define RTL8367C_OP37_NOT_OFFSET 14 +#define RTL8367C_OP37_NOT_MASK 0x4000 +#define RTL8367C_ACT37_GPIO_OFFSET 13 +#define RTL8367C_ACT37_GPIO_MASK 0x2000 +#define RTL8367C_ACT37_FORWARD_OFFSET 12 +#define RTL8367C_ACT37_FORWARD_MASK 0x1000 +#define RTL8367C_ACT37_POLICING_OFFSET 11 +#define RTL8367C_ACT37_POLICING_MASK 0x800 +#define RTL8367C_ACT37_PRIORITY_OFFSET 10 +#define RTL8367C_ACT37_PRIORITY_MASK 0x400 +#define RTL8367C_ACT37_SVID_OFFSET 9 +#define RTL8367C_ACT37_SVID_MASK 0x200 +#define RTL8367C_ACT37_CVID_OFFSET 8 +#define RTL8367C_ACT37_CVID_MASK 0x100 +#define RTL8367C_OP36_NOT_OFFSET 6 +#define RTL8367C_OP36_NOT_MASK 0x40 +#define RTL8367C_ACT36_GPIO_OFFSET 5 +#define RTL8367C_ACT36_GPIO_MASK 0x20 +#define RTL8367C_ACT36_FORWARD_OFFSET 4 +#define RTL8367C_ACT36_FORWARD_MASK 0x10 +#define RTL8367C_ACT36_POLICING_OFFSET 3 +#define RTL8367C_ACT36_POLICING_MASK 0x8 +#define RTL8367C_ACT36_PRIORITY_OFFSET 2 +#define RTL8367C_ACT36_PRIORITY_MASK 0x4 +#define RTL8367C_ACT36_SVID_OFFSET 1 +#define RTL8367C_ACT36_SVID_MASK 0x2 +#define RTL8367C_ACT36_CVID_OFFSET 0 +#define RTL8367C_ACT36_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL19 0x0627 +#define RTL8367C_OP39_NOT_OFFSET 14 +#define RTL8367C_OP39_NOT_MASK 0x4000 +#define RTL8367C_ACT39_GPIO_OFFSET 13 +#define RTL8367C_ACT39_GPIO_MASK 0x2000 +#define RTL8367C_ACT39_FORWARD_OFFSET 12 +#define RTL8367C_ACT39_FORWARD_MASK 0x1000 +#define RTL8367C_ACT39_POLICING_OFFSET 11 +#define RTL8367C_ACT39_POLICING_MASK 0x800 +#define RTL8367C_ACT39_PRIORITY_OFFSET 10 +#define RTL8367C_ACT39_PRIORITY_MASK 0x400 +#define RTL8367C_ACT39_SVID_OFFSET 9 +#define RTL8367C_ACT39_SVID_MASK 0x200 +#define RTL8367C_ACT39_CVID_OFFSET 8 +#define RTL8367C_ACT39_CVID_MASK 0x100 +#define RTL8367C_OP38_NOT_OFFSET 6 +#define RTL8367C_OP38_NOT_MASK 0x40 +#define RTL8367C_ACT38_GPIO_OFFSET 5 +#define RTL8367C_ACT38_GPIO_MASK 0x20 +#define RTL8367C_ACT38_FORWARD_OFFSET 4 +#define RTL8367C_ACT38_FORWARD_MASK 0x10 +#define RTL8367C_ACT38_POLICING_OFFSET 3 +#define RTL8367C_ACT38_POLICING_MASK 0x8 +#define RTL8367C_ACT38_PRIORITY_OFFSET 2 +#define RTL8367C_ACT38_PRIORITY_MASK 0x4 +#define RTL8367C_ACT38_SVID_OFFSET 1 +#define RTL8367C_ACT38_SVID_MASK 0x2 +#define RTL8367C_ACT38_CVID_OFFSET 0 +#define RTL8367C_ACT38_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL20 0x0628 +#define RTL8367C_OP41_NOT_OFFSET 14 +#define RTL8367C_OP41_NOT_MASK 0x4000 +#define RTL8367C_ACT41_GPIO_OFFSET 13 +#define RTL8367C_ACT41_GPIO_MASK 0x2000 +#define RTL8367C_ACT41_FORWARD_OFFSET 12 +#define RTL8367C_ACT41_FORWARD_MASK 0x1000 +#define RTL8367C_ACT41_POLICING_OFFSET 11 +#define RTL8367C_ACT41_POLICING_MASK 0x800 +#define RTL8367C_ACT41_PRIORITY_OFFSET 10 +#define RTL8367C_ACT41_PRIORITY_MASK 0x400 +#define RTL8367C_ACT41_SVID_OFFSET 9 +#define RTL8367C_ACT41_SVID_MASK 0x200 +#define RTL8367C_ACT41_CVID_OFFSET 8 +#define RTL8367C_ACT41_CVID_MASK 0x100 +#define RTL8367C_OP40_NOT_OFFSET 6 +#define RTL8367C_OP40_NOT_MASK 0x40 +#define RTL8367C_ACT40_GPIO_OFFSET 5 +#define RTL8367C_ACT40_GPIO_MASK 0x20 +#define RTL8367C_ACT40_FORWARD_OFFSET 4 +#define RTL8367C_ACT40_FORWARD_MASK 0x10 +#define RTL8367C_ACT40_POLICING_OFFSET 3 +#define RTL8367C_ACT40_POLICING_MASK 0x8 +#define RTL8367C_ACT40_PRIORITY_OFFSET 2 +#define RTL8367C_ACT40_PRIORITY_MASK 0x4 +#define RTL8367C_ACT40_SVID_OFFSET 1 +#define RTL8367C_ACT40_SVID_MASK 0x2 +#define RTL8367C_ACT40_CVID_OFFSET 0 +#define RTL8367C_ACT40_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL21 0x0629 +#define RTL8367C_OP43_NOT_OFFSET 14 +#define RTL8367C_OP43_NOT_MASK 0x4000 +#define RTL8367C_ACT43_GPIO_OFFSET 13 +#define RTL8367C_ACT43_GPIO_MASK 0x2000 +#define RTL8367C_ACT43_FORWARD_OFFSET 12 +#define RTL8367C_ACT43_FORWARD_MASK 0x1000 +#define RTL8367C_ACT43_POLICING_OFFSET 11 +#define RTL8367C_ACT43_POLICING_MASK 0x800 +#define RTL8367C_ACT43_PRIORITY_OFFSET 10 +#define RTL8367C_ACT43_PRIORITY_MASK 0x400 +#define RTL8367C_ACT43_SVID_OFFSET 9 +#define RTL8367C_ACT43_SVID_MASK 0x200 +#define RTL8367C_ACT43_CVID_OFFSET 8 +#define RTL8367C_ACT43_CVID_MASK 0x100 +#define RTL8367C_OP42_NOT_OFFSET 6 +#define RTL8367C_OP42_NOT_MASK 0x40 +#define RTL8367C_ACT42_GPIO_OFFSET 5 +#define RTL8367C_ACT42_GPIO_MASK 0x20 +#define RTL8367C_ACT42_FORWARD_OFFSET 4 +#define RTL8367C_ACT42_FORWARD_MASK 0x10 +#define RTL8367C_ACT42_POLICING_OFFSET 3 +#define RTL8367C_ACT42_POLICING_MASK 0x8 +#define RTL8367C_ACT42_PRIORITY_OFFSET 2 +#define RTL8367C_ACT42_PRIORITY_MASK 0x4 +#define RTL8367C_ACT42_SVID_OFFSET 1 +#define RTL8367C_ACT42_SVID_MASK 0x2 +#define RTL8367C_ACT42_CVID_OFFSET 0 +#define RTL8367C_ACT42_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL22 0x062a +#define RTL8367C_OP45_NOT_OFFSET 14 +#define RTL8367C_OP45_NOT_MASK 0x4000 +#define RTL8367C_ACT45_GPIO_OFFSET 13 +#define RTL8367C_ACT45_GPIO_MASK 0x2000 +#define RTL8367C_ACT45_FORWARD_OFFSET 12 +#define RTL8367C_ACT45_FORWARD_MASK 0x1000 +#define RTL8367C_ACT45_POLICING_OFFSET 11 +#define RTL8367C_ACT45_POLICING_MASK 0x800 +#define RTL8367C_ACT45_PRIORITY_OFFSET 10 +#define RTL8367C_ACT45_PRIORITY_MASK 0x400 +#define RTL8367C_ACT45_SVID_OFFSET 9 +#define RTL8367C_ACT45_SVID_MASK 0x200 +#define RTL8367C_ACT45_CVID_OFFSET 8 +#define RTL8367C_ACT45_CVID_MASK 0x100 +#define RTL8367C_OP44_NOT_OFFSET 6 +#define RTL8367C_OP44_NOT_MASK 0x40 +#define RTL8367C_ACT44_GPIO_OFFSET 5 +#define RTL8367C_ACT44_GPIO_MASK 0x20 +#define RTL8367C_ACT44_FORWARD_OFFSET 4 +#define RTL8367C_ACT44_FORWARD_MASK 0x10 +#define RTL8367C_ACT44_POLICING_OFFSET 3 +#define RTL8367C_ACT44_POLICING_MASK 0x8 +#define RTL8367C_ACT44_PRIORITY_OFFSET 2 +#define RTL8367C_ACT44_PRIORITY_MASK 0x4 +#define RTL8367C_ACT44_SVID_OFFSET 1 +#define RTL8367C_ACT44_SVID_MASK 0x2 +#define RTL8367C_ACT44_CVID_OFFSET 0 +#define RTL8367C_ACT44_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL23 0x062b +#define RTL8367C_OP47_NOT_OFFSET 14 +#define RTL8367C_OP47_NOT_MASK 0x4000 +#define RTL8367C_ACT47_GPIO_OFFSET 13 +#define RTL8367C_ACT47_GPIO_MASK 0x2000 +#define RTL8367C_ACT47_FORWARD_OFFSET 12 +#define RTL8367C_ACT47_FORWARD_MASK 0x1000 +#define RTL8367C_ACT47_POLICING_OFFSET 11 +#define RTL8367C_ACT47_POLICING_MASK 0x800 +#define RTL8367C_ACT47_PRIORITY_OFFSET 10 +#define RTL8367C_ACT47_PRIORITY_MASK 0x400 +#define RTL8367C_ACT47_SVID_OFFSET 9 +#define RTL8367C_ACT47_SVID_MASK 0x200 +#define RTL8367C_ACT47_CVID_OFFSET 8 +#define RTL8367C_ACT47_CVID_MASK 0x100 +#define RTL8367C_OP46_NOT_OFFSET 6 +#define RTL8367C_OP46_NOT_MASK 0x40 +#define RTL8367C_ACT46_GPIO_OFFSET 5 +#define RTL8367C_ACT46_GPIO_MASK 0x20 +#define RTL8367C_ACT46_FORWARD_OFFSET 4 +#define RTL8367C_ACT46_FORWARD_MASK 0x10 +#define RTL8367C_ACT46_POLICING_OFFSET 3 +#define RTL8367C_ACT46_POLICING_MASK 0x8 +#define RTL8367C_ACT46_PRIORITY_OFFSET 2 +#define RTL8367C_ACT46_PRIORITY_MASK 0x4 +#define RTL8367C_ACT46_SVID_OFFSET 1 +#define RTL8367C_ACT46_SVID_MASK 0x2 +#define RTL8367C_ACT46_CVID_OFFSET 0 +#define RTL8367C_ACT46_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL24 0x062c +#define RTL8367C_OP49_NOT_OFFSET 14 +#define RTL8367C_OP49_NOT_MASK 0x4000 +#define RTL8367C_ACT49_GPIO_OFFSET 13 +#define RTL8367C_ACT49_GPIO_MASK 0x2000 +#define RTL8367C_ACT49_FORWARD_OFFSET 12 +#define RTL8367C_ACT49_FORWARD_MASK 0x1000 +#define RTL8367C_ACT49_POLICING_OFFSET 11 +#define RTL8367C_ACT49_POLICING_MASK 0x800 +#define RTL8367C_ACT49_PRIORITY_OFFSET 10 +#define RTL8367C_ACT49_PRIORITY_MASK 0x400 +#define RTL8367C_ACT49_SVID_OFFSET 9 +#define RTL8367C_ACT49_SVID_MASK 0x200 +#define RTL8367C_ACT49_CVID_OFFSET 8 +#define RTL8367C_ACT49_CVID_MASK 0x100 +#define RTL8367C_OP48_NOT_OFFSET 6 +#define RTL8367C_OP48_NOT_MASK 0x40 +#define RTL8367C_ACT48_GPIO_OFFSET 5 +#define RTL8367C_ACT48_GPIO_MASK 0x20 +#define RTL8367C_ACT48_FORWARD_OFFSET 4 +#define RTL8367C_ACT48_FORWARD_MASK 0x10 +#define RTL8367C_ACT48_POLICING_OFFSET 3 +#define RTL8367C_ACT48_POLICING_MASK 0x8 +#define RTL8367C_ACT48_PRIORITY_OFFSET 2 +#define RTL8367C_ACT48_PRIORITY_MASK 0x4 +#define RTL8367C_ACT48_SVID_OFFSET 1 +#define RTL8367C_ACT48_SVID_MASK 0x2 +#define RTL8367C_ACT48_CVID_OFFSET 0 +#define RTL8367C_ACT48_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL25 0x062d +#define RTL8367C_OP51_NOT_OFFSET 14 +#define RTL8367C_OP51_NOT_MASK 0x4000 +#define RTL8367C_ACT51_GPIO_OFFSET 13 +#define RTL8367C_ACT51_GPIO_MASK 0x2000 +#define RTL8367C_ACT51_FORWARD_OFFSET 12 +#define RTL8367C_ACT51_FORWARD_MASK 0x1000 +#define RTL8367C_ACT51_POLICING_OFFSET 11 +#define RTL8367C_ACT51_POLICING_MASK 0x800 +#define RTL8367C_ACT51_PRIORITY_OFFSET 10 +#define RTL8367C_ACT51_PRIORITY_MASK 0x400 +#define RTL8367C_ACT51_SVID_OFFSET 9 +#define RTL8367C_ACT51_SVID_MASK 0x200 +#define RTL8367C_ACT51_CVID_OFFSET 8 +#define RTL8367C_ACT51_CVID_MASK 0x100 +#define RTL8367C_OP50_NOT_OFFSET 6 +#define RTL8367C_OP50_NOT_MASK 0x40 +#define RTL8367C_ACT50_GPIO_OFFSET 5 +#define RTL8367C_ACT50_GPIO_MASK 0x20 +#define RTL8367C_ACT50_FORWARD_OFFSET 4 +#define RTL8367C_ACT50_FORWARD_MASK 0x10 +#define RTL8367C_ACT50_POLICING_OFFSET 3 +#define RTL8367C_ACT50_POLICING_MASK 0x8 +#define RTL8367C_ACT50_PRIORITY_OFFSET 2 +#define RTL8367C_ACT50_PRIORITY_MASK 0x4 +#define RTL8367C_ACT50_SVID_OFFSET 1 +#define RTL8367C_ACT50_SVID_MASK 0x2 +#define RTL8367C_ACT50_CVID_OFFSET 0 +#define RTL8367C_ACT50_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL26 0x062e +#define RTL8367C_OP53_NOT_OFFSET 14 +#define RTL8367C_OP53_NOT_MASK 0x4000 +#define RTL8367C_ACT53_GPIO_OFFSET 13 +#define RTL8367C_ACT53_GPIO_MASK 0x2000 +#define RTL8367C_ACT53_FORWARD_OFFSET 12 +#define RTL8367C_ACT53_FORWARD_MASK 0x1000 +#define RTL8367C_ACT53_POLICING_OFFSET 11 +#define RTL8367C_ACT53_POLICING_MASK 0x800 +#define RTL8367C_ACT53_PRIORITY_OFFSET 10 +#define RTL8367C_ACT53_PRIORITY_MASK 0x400 +#define RTL8367C_ACT53_SVID_OFFSET 9 +#define RTL8367C_ACT53_SVID_MASK 0x200 +#define RTL8367C_ACT53_CVID_OFFSET 8 +#define RTL8367C_ACT53_CVID_MASK 0x100 +#define RTL8367C_OP52_NOT_OFFSET 6 +#define RTL8367C_OP52_NOT_MASK 0x40 +#define RTL8367C_ACT52_GPIO_OFFSET 5 +#define RTL8367C_ACT52_GPIO_MASK 0x20 +#define RTL8367C_ACT52_FORWARD_OFFSET 4 +#define RTL8367C_ACT52_FORWARD_MASK 0x10 +#define RTL8367C_ACT52_POLICING_OFFSET 3 +#define RTL8367C_ACT52_POLICING_MASK 0x8 +#define RTL8367C_ACT52_PRIORITY_OFFSET 2 +#define RTL8367C_ACT52_PRIORITY_MASK 0x4 +#define RTL8367C_ACT52_SVID_OFFSET 1 +#define RTL8367C_ACT52_SVID_MASK 0x2 +#define RTL8367C_ACT52_CVID_OFFSET 0 +#define RTL8367C_ACT52_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL27 0x062f +#define RTL8367C_OP55_NOT_OFFSET 14 +#define RTL8367C_OP55_NOT_MASK 0x4000 +#define RTL8367C_ACT55_GPIO_OFFSET 13 +#define RTL8367C_ACT55_GPIO_MASK 0x2000 +#define RTL8367C_ACT55_FORWARD_OFFSET 12 +#define RTL8367C_ACT55_FORWARD_MASK 0x1000 +#define RTL8367C_ACT55_POLICING_OFFSET 11 +#define RTL8367C_ACT55_POLICING_MASK 0x800 +#define RTL8367C_ACT55_PRIORITY_OFFSET 10 +#define RTL8367C_ACT55_PRIORITY_MASK 0x400 +#define RTL8367C_ACT55_SVID_OFFSET 9 +#define RTL8367C_ACT55_SVID_MASK 0x200 +#define RTL8367C_ACT55_CVID_OFFSET 8 +#define RTL8367C_ACT55_CVID_MASK 0x100 +#define RTL8367C_OP54_NOT_OFFSET 6 +#define RTL8367C_OP54_NOT_MASK 0x40 +#define RTL8367C_ACT54_GPIO_OFFSET 5 +#define RTL8367C_ACT54_GPIO_MASK 0x20 +#define RTL8367C_ACT54_FORWARD_OFFSET 4 +#define RTL8367C_ACT54_FORWARD_MASK 0x10 +#define RTL8367C_ACT54_POLICING_OFFSET 3 +#define RTL8367C_ACT54_POLICING_MASK 0x8 +#define RTL8367C_ACT54_PRIORITY_OFFSET 2 +#define RTL8367C_ACT54_PRIORITY_MASK 0x4 +#define RTL8367C_ACT54_SVID_OFFSET 1 +#define RTL8367C_ACT54_SVID_MASK 0x2 +#define RTL8367C_ACT54_CVID_OFFSET 0 +#define RTL8367C_ACT54_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL28 0x0630 +#define RTL8367C_OP57_NOT_OFFSET 14 +#define RTL8367C_OP57_NOT_MASK 0x4000 +#define RTL8367C_ACT57_GPIO_OFFSET 13 +#define RTL8367C_ACT57_GPIO_MASK 0x2000 +#define RTL8367C_ACT57_FORWARD_OFFSET 12 +#define RTL8367C_ACT57_FORWARD_MASK 0x1000 +#define RTL8367C_ACT57_POLICING_OFFSET 11 +#define RTL8367C_ACT57_POLICING_MASK 0x800 +#define RTL8367C_ACT57_PRIORITY_OFFSET 10 +#define RTL8367C_ACT57_PRIORITY_MASK 0x400 +#define RTL8367C_ACT57_SVID_OFFSET 9 +#define RTL8367C_ACT57_SVID_MASK 0x200 +#define RTL8367C_ACT57_CVID_OFFSET 8 +#define RTL8367C_ACT57_CVID_MASK 0x100 +#define RTL8367C_OP56_NOT_OFFSET 6 +#define RTL8367C_OP56_NOT_MASK 0x40 +#define RTL8367C_ACT56_GPIO_OFFSET 5 +#define RTL8367C_ACT56_GPIO_MASK 0x20 +#define RTL8367C_ACT56_FORWARD_OFFSET 4 +#define RTL8367C_ACT56_FORWARD_MASK 0x10 +#define RTL8367C_ACT56_POLICING_OFFSET 3 +#define RTL8367C_ACT56_POLICING_MASK 0x8 +#define RTL8367C_ACT56_PRIORITY_OFFSET 2 +#define RTL8367C_ACT56_PRIORITY_MASK 0x4 +#define RTL8367C_ACT56_SVID_OFFSET 1 +#define RTL8367C_ACT56_SVID_MASK 0x2 +#define RTL8367C_ACT56_CVID_OFFSET 0 +#define RTL8367C_ACT56_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL29 0x0631 +#define RTL8367C_OP59_NOT_OFFSET 14 +#define RTL8367C_OP59_NOT_MASK 0x4000 +#define RTL8367C_ACT59_GPIO_OFFSET 13 +#define RTL8367C_ACT59_GPIO_MASK 0x2000 +#define RTL8367C_ACT59_FORWARD_OFFSET 12 +#define RTL8367C_ACT59_FORWARD_MASK 0x1000 +#define RTL8367C_ACT59_POLICING_OFFSET 11 +#define RTL8367C_ACT59_POLICING_MASK 0x800 +#define RTL8367C_ACT59_PRIORITY_OFFSET 10 +#define RTL8367C_ACT59_PRIORITY_MASK 0x400 +#define RTL8367C_ACT59_SVID_OFFSET 9 +#define RTL8367C_ACT59_SVID_MASK 0x200 +#define RTL8367C_ACT59_CVID_OFFSET 8 +#define RTL8367C_ACT59_CVID_MASK 0x100 +#define RTL8367C_OP58_NOT_OFFSET 6 +#define RTL8367C_OP58_NOT_MASK 0x40 +#define RTL8367C_ACT58_GPIO_OFFSET 5 +#define RTL8367C_ACT58_GPIO_MASK 0x20 +#define RTL8367C_ACT58_FORWARD_OFFSET 4 +#define RTL8367C_ACT58_FORWARD_MASK 0x10 +#define RTL8367C_ACT58_POLICING_OFFSET 3 +#define RTL8367C_ACT58_POLICING_MASK 0x8 +#define RTL8367C_ACT58_PRIORITY_OFFSET 2 +#define RTL8367C_ACT58_PRIORITY_MASK 0x4 +#define RTL8367C_ACT58_SVID_OFFSET 1 +#define RTL8367C_ACT58_SVID_MASK 0x2 +#define RTL8367C_ACT58_CVID_OFFSET 0 +#define RTL8367C_ACT58_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL30 0x0632 +#define RTL8367C_OP61_NOT_OFFSET 14 +#define RTL8367C_OP61_NOT_MASK 0x4000 +#define RTL8367C_ACT61_GPIO_OFFSET 13 +#define RTL8367C_ACT61_GPIO_MASK 0x2000 +#define RTL8367C_ACT61_FORWARD_OFFSET 12 +#define RTL8367C_ACT61_FORWARD_MASK 0x1000 +#define RTL8367C_ACT61_POLICING_OFFSET 11 +#define RTL8367C_ACT61_POLICING_MASK 0x800 +#define RTL8367C_ACT61_PRIORITY_OFFSET 10 +#define RTL8367C_ACT61_PRIORITY_MASK 0x400 +#define RTL8367C_ACT61_SVID_OFFSET 9 +#define RTL8367C_ACT61_SVID_MASK 0x200 +#define RTL8367C_ACT61_CVID_OFFSET 8 +#define RTL8367C_ACT61_CVID_MASK 0x100 +#define RTL8367C_OP60_NOT_OFFSET 6 +#define RTL8367C_OP60_NOT_MASK 0x40 +#define RTL8367C_ACT60_GPIO_OFFSET 5 +#define RTL8367C_ACT60_GPIO_MASK 0x20 +#define RTL8367C_ACT60_FORWARD_OFFSET 4 +#define RTL8367C_ACT60_FORWARD_MASK 0x10 +#define RTL8367C_ACT60_POLICING_OFFSET 3 +#define RTL8367C_ACT60_POLICING_MASK 0x8 +#define RTL8367C_ACT60_PRIORITY_OFFSET 2 +#define RTL8367C_ACT60_PRIORITY_MASK 0x4 +#define RTL8367C_ACT60_SVID_OFFSET 1 +#define RTL8367C_ACT60_SVID_MASK 0x2 +#define RTL8367C_ACT60_CVID_OFFSET 0 +#define RTL8367C_ACT60_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL31 0x0633 +#define RTL8367C_OP63_NOT_OFFSET 14 +#define RTL8367C_OP63_NOT_MASK 0x4000 +#define RTL8367C_ACT63_GPIO_OFFSET 13 +#define RTL8367C_ACT63_GPIO_MASK 0x2000 +#define RTL8367C_ACT63_FORWARD_OFFSET 12 +#define RTL8367C_ACT63_FORWARD_MASK 0x1000 +#define RTL8367C_ACT63_POLICING_OFFSET 11 +#define RTL8367C_ACT63_POLICING_MASK 0x800 +#define RTL8367C_ACT63_PRIORITY_OFFSET 10 +#define RTL8367C_ACT63_PRIORITY_MASK 0x400 +#define RTL8367C_ACT63_SVID_OFFSET 9 +#define RTL8367C_ACT63_SVID_MASK 0x200 +#define RTL8367C_ACT63_CVID_OFFSET 8 +#define RTL8367C_ACT63_CVID_MASK 0x100 +#define RTL8367C_OP62_NOT_OFFSET 6 +#define RTL8367C_OP62_NOT_MASK 0x40 +#define RTL8367C_ACT62_GPIO_OFFSET 5 +#define RTL8367C_ACT62_GPIO_MASK 0x20 +#define RTL8367C_ACT62_FORWARD_OFFSET 4 +#define RTL8367C_ACT62_FORWARD_MASK 0x10 +#define RTL8367C_ACT62_POLICING_OFFSET 3 +#define RTL8367C_ACT62_POLICING_MASK 0x8 +#define RTL8367C_ACT62_PRIORITY_OFFSET 2 +#define RTL8367C_ACT62_PRIORITY_MASK 0x4 +#define RTL8367C_ACT62_SVID_OFFSET 1 +#define RTL8367C_ACT62_SVID_MASK 0x2 +#define RTL8367C_ACT62_CVID_OFFSET 0 +#define RTL8367C_ACT62_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 0x0635 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 0x0636 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 0x0637 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL0 0x0638 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL1 0x0639 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL2 0x063a +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL0 0x063b + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL1 0x063c + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL2 0x063d +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL0 0x063e + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL1 0x063f + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL2 0x0640 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL0 0x0641 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL1 0x0642 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL2 0x0643 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL0 0x0644 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL1 0x0645 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL2 0x0646 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL0 0x0647 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL1 0x0648 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL2 0x0649 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL0 0x064a + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL1 0x064b + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL2 0x064c +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL0 0x064d + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL1 0x064e + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL2 0x064f +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL0 0x0650 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL1 0x0651 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL2 0x0652 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL0 0x0653 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL1 0x0654 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL2 0x0655 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL0 0x0656 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL1 0x0657 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL2 0x0658 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL0 0x0659 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL1 0x065a + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL2 0x065b +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL0 0x065c + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL1 0x065d + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL2 0x065e +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL0 0x065f + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL1 0x0660 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL2 0x0661 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL0 0x0662 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL1 0x0663 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL2 0x0664 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 0x0665 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 0x0666 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL0 0x0667 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL1 0x0668 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL0 0x0669 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL1 0x066a +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL0 0x066b +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL1 0x066c +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL0 0x066d +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL1 0x066e +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL0 0x066f +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL1 0x0670 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL0 0x0671 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL1 0x0672 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL0 0x0673 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL1 0x0674 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL0 0x0675 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL1 0x0676 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL0 0x0677 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL1 0x0678 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL0 0x0679 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL1 0x067a +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL0 0x067b +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL1 0x067c +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL0 0x067d +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL1 0x067e +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL0 0x067f +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL1 0x0680 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL0 0x0681 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL1 0x0682 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL0 0x0683 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL1 0x0684 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 0x0685 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 0x0686 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 0x0687 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 0x0688 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 0x0689 +#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL0 0x068a + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL1 0x068b + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL2 0x068c + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL3 0x068d + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL4 0x068e +#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL0 0x068f + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL1 0x0690 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL2 0x0691 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL3 0x0692 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL4 0x0693 +#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL0 0x0694 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL1 0x0695 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL2 0x0696 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL3 0x0697 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL4 0x0698 +#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL0 0x0699 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL1 0x069a + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL2 0x069b + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL3 0x069c + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL4 0x069d +#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL0 0x069e + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL1 0x069f + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL2 0x06a0 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL3 0x06a1 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL4 0x06a2 +#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL0 0x06a3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL1 0x06a4 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL2 0x06a5 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL3 0x06a6 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL4 0x06a7 +#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL0 0x06a8 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL1 0x06a9 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL2 0x06aa + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL3 0x06ab + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL4 0x06ac +#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL0 0x06ad + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL1 0x06ae + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL2 0x06af + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL3 0x06b0 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL4 0x06b1 +#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL0 0x06b2 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL1 0x06b3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL2 0x06b4 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL3 0x06b5 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL4 0x06b6 +#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL0 0x06b7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL1 0x06b8 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL2 0x06b9 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL3 0x06ba + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL4 0x06bb +#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL0 0x06bc + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL1 0x06bd + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL2 0x06be + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL3 0x06bf + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL4 0x06c0 +#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL0 0x06c1 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL1 0x06c2 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL2 0x06c3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL3 0x06c4 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL4 0x06c5 +#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL0 0x06c6 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL1 0x06c7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL2 0x06c8 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL3 0x06c9 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL4 0x06ca +#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL0 0x06cb + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL1 0x06cc + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL2 0x06cd + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL3 0x06ce + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL4 0x06cf +#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL0 0x06d0 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL1 0x06d1 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL2 0x06d2 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL3 0x06d3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL4 0x06d4 +#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_ENABLE 0x06d5 +#define RTL8367C_PORT10_ENABLE_OFFSET 10 +#define RTL8367C_PORT10_ENABLE_MASK 0x400 +#define RTL8367C_PORT9_ENABLE_OFFSET 9 +#define RTL8367C_PORT9_ENABLE_MASK 0x200 +#define RTL8367C_PORT8_ENABLE_OFFSET 8 +#define RTL8367C_PORT8_ENABLE_MASK 0x100 +#define RTL8367C_PORT7_ENABLE_OFFSET 7 +#define RTL8367C_PORT7_ENABLE_MASK 0x80 +#define RTL8367C_PORT6_ENABLE_OFFSET 6 +#define RTL8367C_PORT6_ENABLE_MASK 0x40 +#define RTL8367C_PORT5_ENABLE_OFFSET 5 +#define RTL8367C_PORT5_ENABLE_MASK 0x20 +#define RTL8367C_PORT4_ENABLE_OFFSET 4 +#define RTL8367C_PORT4_ENABLE_MASK 0x10 +#define RTL8367C_PORT3_ENABLE_OFFSET 3 +#define RTL8367C_PORT3_ENABLE_MASK 0x8 +#define RTL8367C_PORT2_ENABLE_OFFSET 2 +#define RTL8367C_PORT2_ENABLE_MASK 0x4 +#define RTL8367C_PORT1_ENABLE_OFFSET 1 +#define RTL8367C_PORT1_ENABLE_MASK 0x2 +#define RTL8367C_PORT0_ENABLE_OFFSET 0 +#define RTL8367C_PORT0_ENABLE_MASK 0x1 + +#define RTL8367C_REG_ACL_UNMATCH_PERMIT 0x06d6 +#define RTL8367C_PORT10_PERMIT_OFFSET 10 +#define RTL8367C_PORT10_PERMIT_MASK 0x400 +#define RTL8367C_PORT9_PERMIT_OFFSET 9 +#define RTL8367C_PORT9_PERMIT_MASK 0x200 +#define RTL8367C_PORT8_PERMIT_OFFSET 8 +#define RTL8367C_PORT8_PERMIT_MASK 0x100 +#define RTL8367C_PORT7_PERMIT_OFFSET 7 +#define RTL8367C_PORT7_PERMIT_MASK 0x80 +#define RTL8367C_PORT6_PERMIT_OFFSET 6 +#define RTL8367C_PORT6_PERMIT_MASK 0x40 +#define RTL8367C_PORT5_PERMIT_OFFSET 5 +#define RTL8367C_PORT5_PERMIT_MASK 0x20 +#define RTL8367C_PORT4_PERMIT_OFFSET 4 +#define RTL8367C_PORT4_PERMIT_MASK 0x10 +#define RTL8367C_PORT3_PERMIT_OFFSET 3 +#define RTL8367C_PORT3_PERMIT_MASK 0x8 +#define RTL8367C_PORT2_PERMIT_OFFSET 2 +#define RTL8367C_PORT2_PERMIT_MASK 0x4 +#define RTL8367C_PORT1_PERMIT_OFFSET 1 +#define RTL8367C_PORT1_PERMIT_MASK 0x2 +#define RTL8367C_PORT0_PERMIT_OFFSET 0 +#define RTL8367C_PORT0_PERMIT_MASK 0x1 + +#define RTL8367C_REG_ACL_GPIO_POLARITY 0x06d7 +#define RTL8367C_ACL_GPIO_POLARITY_OFFSET 0 +#define RTL8367C_ACL_GPIO_POLARITY_MASK 0x1 + +#define RTL8367C_REG_ACL_LOG_CNT_TYPE 0x06d8 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_OFFSET 15 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_MASK 0x8000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_OFFSET 14 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_MASK 0x4000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_OFFSET 13 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_MASK 0x2000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_OFFSET 12 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_MASK 0x1000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_OFFSET 11 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_MASK 0x800 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_OFFSET 10 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_MASK 0x400 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_OFFSET 9 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_MASK 0x200 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_OFFSET 8 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_MASK 0x100 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_OFFSET 7 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_MASK 0x80 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_OFFSET 6 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_MASK 0x40 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_OFFSET 5 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_MASK 0x20 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_OFFSET 4 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_MASK 0x10 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_OFFSET 3 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_MASK 0x8 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_OFFSET 2 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_MASK 0x4 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_OFFSET 1 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_MASK 0x2 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_OFFSET 0 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_MASK 0x1 + +#define RTL8367C_REG_ACL_RESET_CFG 0x06d9 +#define RTL8367C_ACL_RESET_CFG_OFFSET 0 +#define RTL8367C_ACL_RESET_CFG_MASK 0x1 + +#define RTL8367C_REG_ACL_DUMMY00 0x06E0 + +#define RTL8367C_REG_ACL_DUMMY01 0x06E1 + +#define RTL8367C_REG_ACL_DUMMY02 0x06E2 + +#define RTL8367C_REG_ACL_DUMMY03 0x06E3 + +#define RTL8367C_REG_ACL_DUMMY04 0x06E4 + +#define RTL8367C_REG_ACL_DUMMY05 0x06E5 + +#define RTL8367C_REG_ACL_DUMMY06 0x06E6 + +#define RTL8367C_REG_ACL_DUMMY07 0x06E7 + +#define RTL8367C_REG_ACL_REASON_01 0x06E8 +#define RTL8367C_ACL_ACT_1_OFFSET 8 +#define RTL8367C_ACL_ACT_1_MASK 0xFF00 +#define RTL8367C_ACL_ACT_0_OFFSET 0 +#define RTL8367C_ACL_ACT_0_MASK 0xFF + +#define RTL8367C_REG_ACL_REASON_23 0x06E9 +#define RTL8367C_ACL_ACT_3_OFFSET 8 +#define RTL8367C_ACL_ACT_3_MASK 0xFF00 +#define RTL8367C_ACL_ACT_2_OFFSET 0 +#define RTL8367C_ACL_ACT_2_MASK 0xFF + +#define RTL8367C_REG_ACL_REASON_45 0x06EA +#define RTL8367C_ACL_ACT_5_OFFSET 8 +#define RTL8367C_ACL_ACT_5_MASK 0xFF00 +#define RTL8367C_ACL_ACT_4_OFFSET 0 +#define RTL8367C_ACL_ACT_4_MASK 0xFF + +#define RTL8367C_REG_ACL_ACCESS_MODE 0x06EB +#define RTL8367C_ACL_ACCESS_MODE_OFFSET 0 +#define RTL8367C_ACL_ACCESS_MODE_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL32 0x06F0 +#define RTL8367C_OP65_NOT_OFFSET 14 +#define RTL8367C_OP65_NOT_MASK 0x4000 +#define RTL8367C_ACT65_GPIO_OFFSET 13 +#define RTL8367C_ACT65_GPIO_MASK 0x2000 +#define RTL8367C_ACT65_FORWARD_OFFSET 12 +#define RTL8367C_ACT65_FORWARD_MASK 0x1000 +#define RTL8367C_ACT65_POLICING_OFFSET 11 +#define RTL8367C_ACT65_POLICING_MASK 0x800 +#define RTL8367C_ACT65_PRIORITY_OFFSET 10 +#define RTL8367C_ACT65_PRIORITY_MASK 0x400 +#define RTL8367C_ACT65_SVID_OFFSET 9 +#define RTL8367C_ACT65_SVID_MASK 0x200 +#define RTL8367C_ACT65_CVID_OFFSET 8 +#define RTL8367C_ACT65_CVID_MASK 0x100 +#define RTL8367C_OP64_NOT_OFFSET 6 +#define RTL8367C_OP64_NOT_MASK 0x40 +#define RTL8367C_ACT64_GPIO_OFFSET 5 +#define RTL8367C_ACT64_GPIO_MASK 0x20 +#define RTL8367C_ACT64_FORWARD_OFFSET 4 +#define RTL8367C_ACT64_FORWARD_MASK 0x10 +#define RTL8367C_ACT64_POLICING_OFFSET 3 +#define RTL8367C_ACT64_POLICING_MASK 0x8 +#define RTL8367C_ACT64_PRIORITY_OFFSET 2 +#define RTL8367C_ACT64_PRIORITY_MASK 0x4 +#define RTL8367C_ACT64_SVID_OFFSET 1 +#define RTL8367C_ACT64_SVID_MASK 0x2 +#define RTL8367C_ACT64_CVID_OFFSET 0 +#define RTL8367C_ACT64_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL33 0x06F1 +#define RTL8367C_OP67_NOT_OFFSET 14 +#define RTL8367C_OP67_NOT_MASK 0x4000 +#define RTL8367C_ACT67_GPIO_OFFSET 13 +#define RTL8367C_ACT67_GPIO_MASK 0x2000 +#define RTL8367C_ACT67_FORWARD_OFFSET 12 +#define RTL8367C_ACT67_FORWARD_MASK 0x1000 +#define RTL8367C_ACT67_POLICING_OFFSET 11 +#define RTL8367C_ACT67_POLICING_MASK 0x800 +#define RTL8367C_ACT67_PRIORITY_OFFSET 10 +#define RTL8367C_ACT67_PRIORITY_MASK 0x400 +#define RTL8367C_ACT67_SVID_OFFSET 9 +#define RTL8367C_ACT67_SVID_MASK 0x200 +#define RTL8367C_ACT67_CVID_OFFSET 8 +#define RTL8367C_ACT67_CVID_MASK 0x100 +#define RTL8367C_OP66_NOT_OFFSET 6 +#define RTL8367C_OP66_NOT_MASK 0x40 +#define RTL8367C_ACT66_GPIO_OFFSET 5 +#define RTL8367C_ACT66_GPIO_MASK 0x20 +#define RTL8367C_ACT66_FORWARD_OFFSET 4 +#define RTL8367C_ACT66_FORWARD_MASK 0x10 +#define RTL8367C_ACT66_POLICING_OFFSET 3 +#define RTL8367C_ACT66_POLICING_MASK 0x8 +#define RTL8367C_ACT66_PRIORITY_OFFSET 2 +#define RTL8367C_ACT66_PRIORITY_MASK 0x4 +#define RTL8367C_ACT66_SVID_OFFSET 1 +#define RTL8367C_ACT66_SVID_MASK 0x2 +#define RTL8367C_ACT66_CVID_OFFSET 0 +#define RTL8367C_ACT66_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL34 0x06F2 +#define RTL8367C_OP69_NOT_OFFSET 14 +#define RTL8367C_OP69_NOT_MASK 0x4000 +#define RTL8367C_ACT69_GPIO_OFFSET 13 +#define RTL8367C_ACT69_GPIO_MASK 0x2000 +#define RTL8367C_ACT69_FORWARD_OFFSET 12 +#define RTL8367C_ACT69_FORWARD_MASK 0x1000 +#define RTL8367C_ACT69_POLICING_OFFSET 11 +#define RTL8367C_ACT69_POLICING_MASK 0x800 +#define RTL8367C_ACT69_PRIORITY_OFFSET 10 +#define RTL8367C_ACT69_PRIORITY_MASK 0x400 +#define RTL8367C_ACT69_SVID_OFFSET 9 +#define RTL8367C_ACT69_SVID_MASK 0x200 +#define RTL8367C_ACT69_CVID_OFFSET 8 +#define RTL8367C_ACT69_CVID_MASK 0x100 +#define RTL8367C_OP68_NOT_OFFSET 6 +#define RTL8367C_OP68_NOT_MASK 0x40 +#define RTL8367C_ACT68_GPIO_OFFSET 5 +#define RTL8367C_ACT68_GPIO_MASK 0x20 +#define RTL8367C_ACT68_FORWARD_OFFSET 4 +#define RTL8367C_ACT68_FORWARD_MASK 0x10 +#define RTL8367C_ACT68_POLICING_OFFSET 3 +#define RTL8367C_ACT68_POLICING_MASK 0x8 +#define RTL8367C_ACT68_PRIORITY_OFFSET 2 +#define RTL8367C_ACT68_PRIORITY_MASK 0x4 +#define RTL8367C_ACT68_SVID_OFFSET 1 +#define RTL8367C_ACT68_SVID_MASK 0x2 +#define RTL8367C_ACT68_CVID_OFFSET 0 +#define RTL8367C_ACT68_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL35 0x06F3 +#define RTL8367C_OP71_NOT_OFFSET 14 +#define RTL8367C_OP71_NOT_MASK 0x4000 +#define RTL8367C_ACT71_GPIO_OFFSET 13 +#define RTL8367C_ACT71_GPIO_MASK 0x2000 +#define RTL8367C_ACT71_FORWARD_OFFSET 12 +#define RTL8367C_ACT71_FORWARD_MASK 0x1000 +#define RTL8367C_ACT71_POLICING_OFFSET 11 +#define RTL8367C_ACT71_POLICING_MASK 0x800 +#define RTL8367C_ACT71_PRIORITY_OFFSET 10 +#define RTL8367C_ACT71_PRIORITY_MASK 0x400 +#define RTL8367C_ACT71_SVID_OFFSET 9 +#define RTL8367C_ACT71_SVID_MASK 0x200 +#define RTL8367C_ACT71_CVID_OFFSET 8 +#define RTL8367C_ACT71_CVID_MASK 0x100 +#define RTL8367C_OP70_NOT_OFFSET 6 +#define RTL8367C_OP70_NOT_MASK 0x40 +#define RTL8367C_ACT70_GPIO_OFFSET 5 +#define RTL8367C_ACT70_GPIO_MASK 0x20 +#define RTL8367C_ACT70_FORWARD_OFFSET 4 +#define RTL8367C_ACT70_FORWARD_MASK 0x10 +#define RTL8367C_ACT70_POLICING_OFFSET 3 +#define RTL8367C_ACT70_POLICING_MASK 0x8 +#define RTL8367C_ACT70_PRIORITY_OFFSET 2 +#define RTL8367C_ACT70_PRIORITY_MASK 0x4 +#define RTL8367C_ACT70_SVID_OFFSET 1 +#define RTL8367C_ACT70_SVID_MASK 0x2 +#define RTL8367C_ACT70_CVID_OFFSET 0 +#define RTL8367C_ACT70_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL36 0x06F4 +#define RTL8367C_OP73_NOT_OFFSET 14 +#define RTL8367C_OP73_NOT_MASK 0x4000 +#define RTL8367C_ACT73_GPIO_OFFSET 13 +#define RTL8367C_ACT73_GPIO_MASK 0x2000 +#define RTL8367C_ACT73_FORWARD_OFFSET 12 +#define RTL8367C_ACT73_FORWARD_MASK 0x1000 +#define RTL8367C_ACT73_POLICING_OFFSET 11 +#define RTL8367C_ACT73_POLICING_MASK 0x800 +#define RTL8367C_ACT73_PRIORITY_OFFSET 10 +#define RTL8367C_ACT73_PRIORITY_MASK 0x400 +#define RTL8367C_ACT73_SVID_OFFSET 9 +#define RTL8367C_ACT73_SVID_MASK 0x200 +#define RTL8367C_ACT73_CVID_OFFSET 8 +#define RTL8367C_ACT73_CVID_MASK 0x100 +#define RTL8367C_OP72_NOT_OFFSET 6 +#define RTL8367C_OP72_NOT_MASK 0x40 +#define RTL8367C_ACT72_GPIO_OFFSET 5 +#define RTL8367C_ACT72_GPIO_MASK 0x20 +#define RTL8367C_ACT72_FORWARD_OFFSET 4 +#define RTL8367C_ACT72_FORWARD_MASK 0x10 +#define RTL8367C_ACT72_POLICING_OFFSET 3 +#define RTL8367C_ACT72_POLICING_MASK 0x8 +#define RTL8367C_ACT72_PRIORITY_OFFSET 2 +#define RTL8367C_ACT72_PRIORITY_MASK 0x4 +#define RTL8367C_ACT72_SVID_OFFSET 1 +#define RTL8367C_ACT72_SVID_MASK 0x2 +#define RTL8367C_ACT72_CVID_OFFSET 0 +#define RTL8367C_ACT72_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL37 0x06F5 +#define RTL8367C_OP75_NOT_OFFSET 14 +#define RTL8367C_OP75_NOT_MASK 0x4000 +#define RTL8367C_ACT75_GPIO_OFFSET 13 +#define RTL8367C_ACT75_GPIO_MASK 0x2000 +#define RTL8367C_ACT75_FORWARD_OFFSET 12 +#define RTL8367C_ACT75_FORWARD_MASK 0x1000 +#define RTL8367C_ACT75_POLICING_OFFSET 11 +#define RTL8367C_ACT75_POLICING_MASK 0x800 +#define RTL8367C_ACT75_PRIORITY_OFFSET 10 +#define RTL8367C_ACT75_PRIORITY_MASK 0x400 +#define RTL8367C_ACT75_SVID_OFFSET 9 +#define RTL8367C_ACT75_SVID_MASK 0x200 +#define RTL8367C_ACT75_CVID_OFFSET 8 +#define RTL8367C_ACT75_CVID_MASK 0x100 +#define RTL8367C_OP74_NOT_OFFSET 6 +#define RTL8367C_OP74_NOT_MASK 0x40 +#define RTL8367C_ACT74_GPIO_OFFSET 5 +#define RTL8367C_ACT74_GPIO_MASK 0x20 +#define RTL8367C_ACT74_FORWARD_OFFSET 4 +#define RTL8367C_ACT74_FORWARD_MASK 0x10 +#define RTL8367C_ACT74_POLICING_OFFSET 3 +#define RTL8367C_ACT74_POLICING_MASK 0x8 +#define RTL8367C_ACT74_PRIORITY_OFFSET 2 +#define RTL8367C_ACT74_PRIORITY_MASK 0x4 +#define RTL8367C_ACT74_SVID_OFFSET 1 +#define RTL8367C_ACT74_SVID_MASK 0x2 +#define RTL8367C_ACT74_CVID_OFFSET 0 +#define RTL8367C_ACT74_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL38 0x06F6 +#define RTL8367C_OP77_NOT_OFFSET 14 +#define RTL8367C_OP77_NOT_MASK 0x4000 +#define RTL8367C_ACT77_GPIO_OFFSET 13 +#define RTL8367C_ACT77_GPIO_MASK 0x2000 +#define RTL8367C_ACT77_FORWARD_OFFSET 12 +#define RTL8367C_ACT77_FORWARD_MASK 0x1000 +#define RTL8367C_ACT77_POLICING_OFFSET 11 +#define RTL8367C_ACT77_POLICING_MASK 0x800 +#define RTL8367C_ACT77_PRIORITY_OFFSET 10 +#define RTL8367C_ACT77_PRIORITY_MASK 0x400 +#define RTL8367C_ACT77_SVID_OFFSET 9 +#define RTL8367C_ACT77_SVID_MASK 0x200 +#define RTL8367C_ACT77_CVID_OFFSET 8 +#define RTL8367C_ACT77_CVID_MASK 0x100 +#define RTL8367C_OP76_NOT_OFFSET 6 +#define RTL8367C_OP76_NOT_MASK 0x40 +#define RTL8367C_ACT76_GPIO_OFFSET 5 +#define RTL8367C_ACT76_GPIO_MASK 0x20 +#define RTL8367C_ACT76_FORWARD_OFFSET 4 +#define RTL8367C_ACT76_FORWARD_MASK 0x10 +#define RTL8367C_ACT76_POLICING_OFFSET 3 +#define RTL8367C_ACT76_POLICING_MASK 0x8 +#define RTL8367C_ACT76_PRIORITY_OFFSET 2 +#define RTL8367C_ACT76_PRIORITY_MASK 0x4 +#define RTL8367C_ACT76_SVID_OFFSET 1 +#define RTL8367C_ACT76_SVID_MASK 0x2 +#define RTL8367C_ACT76_CVID_OFFSET 0 +#define RTL8367C_ACT76_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL39 0x06F7 +#define RTL8367C_OP79_NOT_OFFSET 14 +#define RTL8367C_OP79_NOT_MASK 0x4000 +#define RTL8367C_ACT79_GPIO_OFFSET 13 +#define RTL8367C_ACT79_GPIO_MASK 0x2000 +#define RTL8367C_ACT79_FORWARD_OFFSET 12 +#define RTL8367C_ACT79_FORWARD_MASK 0x1000 +#define RTL8367C_ACT79_POLICING_OFFSET 11 +#define RTL8367C_ACT79_POLICING_MASK 0x800 +#define RTL8367C_ACT79_PRIORITY_OFFSET 10 +#define RTL8367C_ACT79_PRIORITY_MASK 0x400 +#define RTL8367C_ACT79_SVID_OFFSET 9 +#define RTL8367C_ACT79_SVID_MASK 0x200 +#define RTL8367C_ACT79_CVID_OFFSET 8 +#define RTL8367C_ACT79_CVID_MASK 0x100 +#define RTL8367C_OP78_NOT_OFFSET 6 +#define RTL8367C_OP78_NOT_MASK 0x40 +#define RTL8367C_ACT78_GPIO_OFFSET 5 +#define RTL8367C_ACT78_GPIO_MASK 0x20 +#define RTL8367C_ACT78_FORWARD_OFFSET 4 +#define RTL8367C_ACT78_FORWARD_MASK 0x10 +#define RTL8367C_ACT78_POLICING_OFFSET 3 +#define RTL8367C_ACT78_POLICING_MASK 0x8 +#define RTL8367C_ACT78_PRIORITY_OFFSET 2 +#define RTL8367C_ACT78_PRIORITY_MASK 0x4 +#define RTL8367C_ACT78_SVID_OFFSET 1 +#define RTL8367C_ACT78_SVID_MASK 0x2 +#define RTL8367C_ACT78_CVID_OFFSET 0 +#define RTL8367C_ACT78_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL40 0x06F8 +#define RTL8367C_OP81_NOT_OFFSET 14 +#define RTL8367C_OP81_NOT_MASK 0x4000 +#define RTL8367C_ACT81_GPIO_OFFSET 13 +#define RTL8367C_ACT81_GPIO_MASK 0x2000 +#define RTL8367C_ACT81_FORWARD_OFFSET 12 +#define RTL8367C_ACT81_FORWARD_MASK 0x1000 +#define RTL8367C_ACT81_POLICING_OFFSET 11 +#define RTL8367C_ACT81_POLICING_MASK 0x800 +#define RTL8367C_ACT81_PRIORITY_OFFSET 10 +#define RTL8367C_ACT81_PRIORITY_MASK 0x400 +#define RTL8367C_ACT81_SVID_OFFSET 9 +#define RTL8367C_ACT81_SVID_MASK 0x200 +#define RTL8367C_ACT81_CVID_OFFSET 8 +#define RTL8367C_ACT81_CVID_MASK 0x100 +#define RTL8367C_OP80_NOT_OFFSET 6 +#define RTL8367C_OP80_NOT_MASK 0x40 +#define RTL8367C_ACT80_GPIO_OFFSET 5 +#define RTL8367C_ACT80_GPIO_MASK 0x20 +#define RTL8367C_ACT80_FORWARD_OFFSET 4 +#define RTL8367C_ACT80_FORWARD_MASK 0x10 +#define RTL8367C_ACT80_POLICING_OFFSET 3 +#define RTL8367C_ACT80_POLICING_MASK 0x8 +#define RTL8367C_ACT80_PRIORITY_OFFSET 2 +#define RTL8367C_ACT80_PRIORITY_MASK 0x4 +#define RTL8367C_ACT80_SVID_OFFSET 1 +#define RTL8367C_ACT80_SVID_MASK 0x2 +#define RTL8367C_ACT80_CVID_OFFSET 0 +#define RTL8367C_ACT80_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL41 0x06F9 +#define RTL8367C_OP83_NOT_OFFSET 14 +#define RTL8367C_OP83_NOT_MASK 0x4000 +#define RTL8367C_ACT83_GPIO_OFFSET 13 +#define RTL8367C_ACT83_GPIO_MASK 0x2000 +#define RTL8367C_ACT83_FORWARD_OFFSET 12 +#define RTL8367C_ACT83_FORWARD_MASK 0x1000 +#define RTL8367C_ACT83_POLICING_OFFSET 11 +#define RTL8367C_ACT83_POLICING_MASK 0x800 +#define RTL8367C_ACT83_PRIORITY_OFFSET 10 +#define RTL8367C_ACT83_PRIORITY_MASK 0x400 +#define RTL8367C_ACT83_SVID_OFFSET 9 +#define RTL8367C_ACT83_SVID_MASK 0x200 +#define RTL8367C_ACT83_CVID_OFFSET 8 +#define RTL8367C_ACT83_CVID_MASK 0x100 +#define RTL8367C_OP82_NOT_OFFSET 6 +#define RTL8367C_OP82_NOT_MASK 0x40 +#define RTL8367C_ACT82_GPIO_OFFSET 5 +#define RTL8367C_ACT82_GPIO_MASK 0x20 +#define RTL8367C_ACT82_FORWARD_OFFSET 4 +#define RTL8367C_ACT82_FORWARD_MASK 0x10 +#define RTL8367C_ACT82_POLICING_OFFSET 3 +#define RTL8367C_ACT82_POLICING_MASK 0x8 +#define RTL8367C_ACT82_PRIORITY_OFFSET 2 +#define RTL8367C_ACT82_PRIORITY_MASK 0x4 +#define RTL8367C_ACT82_SVID_OFFSET 1 +#define RTL8367C_ACT82_SVID_MASK 0x2 +#define RTL8367C_ACT82_CVID_OFFSET 0 +#define RTL8367C_ACT82_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL42 0x06FA +#define RTL8367C_OP85_NOT_OFFSET 14 +#define RTL8367C_OP85_NOT_MASK 0x4000 +#define RTL8367C_ACT85_GPIO_OFFSET 13 +#define RTL8367C_ACT85_GPIO_MASK 0x2000 +#define RTL8367C_ACT85_FORWARD_OFFSET 12 +#define RTL8367C_ACT85_FORWARD_MASK 0x1000 +#define RTL8367C_ACT85_POLICING_OFFSET 11 +#define RTL8367C_ACT85_POLICING_MASK 0x800 +#define RTL8367C_ACT85_PRIORITY_OFFSET 10 +#define RTL8367C_ACT85_PRIORITY_MASK 0x400 +#define RTL8367C_ACT85_SVID_OFFSET 9 +#define RTL8367C_ACT85_SVID_MASK 0x200 +#define RTL8367C_ACT85_CVID_OFFSET 8 +#define RTL8367C_ACT85_CVID_MASK 0x100 +#define RTL8367C_OP84_NOT_OFFSET 6 +#define RTL8367C_OP84_NOT_MASK 0x40 +#define RTL8367C_ACT84_GPIO_OFFSET 5 +#define RTL8367C_ACT84_GPIO_MASK 0x20 +#define RTL8367C_ACT84_FORWARD_OFFSET 4 +#define RTL8367C_ACT84_FORWARD_MASK 0x10 +#define RTL8367C_ACT84_POLICING_OFFSET 3 +#define RTL8367C_ACT84_POLICING_MASK 0x8 +#define RTL8367C_ACT84_PRIORITY_OFFSET 2 +#define RTL8367C_ACT84_PRIORITY_MASK 0x4 +#define RTL8367C_ACT84_SVID_OFFSET 1 +#define RTL8367C_ACT84_SVID_MASK 0x2 +#define RTL8367C_ACT84_CVID_OFFSET 0 +#define RTL8367C_ACT84_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL43 0x06FB +#define RTL8367C_OP87_NOT_OFFSET 14 +#define RTL8367C_OP87_NOT_MASK 0x4000 +#define RTL8367C_ACT87_GPIO_OFFSET 13 +#define RTL8367C_ACT87_GPIO_MASK 0x2000 +#define RTL8367C_ACT87_FORWARD_OFFSET 12 +#define RTL8367C_ACT87_FORWARD_MASK 0x1000 +#define RTL8367C_ACT87_POLICING_OFFSET 11 +#define RTL8367C_ACT87_POLICING_MASK 0x800 +#define RTL8367C_ACT87_PRIORITY_OFFSET 10 +#define RTL8367C_ACT87_PRIORITY_MASK 0x400 +#define RTL8367C_ACT87_SVID_OFFSET 9 +#define RTL8367C_ACT87_SVID_MASK 0x200 +#define RTL8367C_ACT87_CVID_OFFSET 8 +#define RTL8367C_ACT87_CVID_MASK 0x100 +#define RTL8367C_OP86_NOT_OFFSET 6 +#define RTL8367C_OP86_NOT_MASK 0x40 +#define RTL8367C_ACT86_GPIO_OFFSET 5 +#define RTL8367C_ACT86_GPIO_MASK 0x20 +#define RTL8367C_ACT86_FORWARD_OFFSET 4 +#define RTL8367C_ACT86_FORWARD_MASK 0x10 +#define RTL8367C_ACT86_POLICING_OFFSET 3 +#define RTL8367C_ACT86_POLICING_MASK 0x8 +#define RTL8367C_ACT86_PRIORITY_OFFSET 2 +#define RTL8367C_ACT86_PRIORITY_MASK 0x4 +#define RTL8367C_ACT86_SVID_OFFSET 1 +#define RTL8367C_ACT86_SVID_MASK 0x2 +#define RTL8367C_ACT86_CVID_OFFSET 0 +#define RTL8367C_ACT86_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL44 0x06FC +#define RTL8367C_OP89_NOT_OFFSET 14 +#define RTL8367C_OP89_NOT_MASK 0x4000 +#define RTL8367C_ACT89_GPIO_OFFSET 13 +#define RTL8367C_ACT89_GPIO_MASK 0x2000 +#define RTL8367C_ACT89_FORWARD_OFFSET 12 +#define RTL8367C_ACT89_FORWARD_MASK 0x1000 +#define RTL8367C_ACT89_POLICING_OFFSET 11 +#define RTL8367C_ACT89_POLICING_MASK 0x800 +#define RTL8367C_ACT89_PRIORITY_OFFSET 10 +#define RTL8367C_ACT89_PRIORITY_MASK 0x400 +#define RTL8367C_ACT89_SVID_OFFSET 9 +#define RTL8367C_ACT89_SVID_MASK 0x200 +#define RTL8367C_ACT89_CVID_OFFSET 8 +#define RTL8367C_ACT89_CVID_MASK 0x100 +#define RTL8367C_OP88_NOT_OFFSET 6 +#define RTL8367C_OP88_NOT_MASK 0x40 +#define RTL8367C_ACT88_GPIO_OFFSET 5 +#define RTL8367C_ACT88_GPIO_MASK 0x20 +#define RTL8367C_ACT88_FORWARD_OFFSET 4 +#define RTL8367C_ACT88_FORWARD_MASK 0x10 +#define RTL8367C_ACT88_POLICING_OFFSET 3 +#define RTL8367C_ACT88_POLICING_MASK 0x8 +#define RTL8367C_ACT88_PRIORITY_OFFSET 2 +#define RTL8367C_ACT88_PRIORITY_MASK 0x4 +#define RTL8367C_ACT88_SVID_OFFSET 1 +#define RTL8367C_ACT88_SVID_MASK 0x2 +#define RTL8367C_ACT88_CVID_OFFSET 0 +#define RTL8367C_ACT88_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL45 0x06FD +#define RTL8367C_OP91_NOT_OFFSET 14 +#define RTL8367C_OP91_NOT_MASK 0x4000 +#define RTL8367C_ACT91_GPIO_OFFSET 13 +#define RTL8367C_ACT91_GPIO_MASK 0x2000 +#define RTL8367C_ACT91_FORWARD_OFFSET 12 +#define RTL8367C_ACT91_FORWARD_MASK 0x1000 +#define RTL8367C_ACT91_POLICING_OFFSET 11 +#define RTL8367C_ACT91_POLICING_MASK 0x800 +#define RTL8367C_ACT91_PRIORITY_OFFSET 10 +#define RTL8367C_ACT91_PRIORITY_MASK 0x400 +#define RTL8367C_ACT91_SVID_OFFSET 9 +#define RTL8367C_ACT91_SVID_MASK 0x200 +#define RTL8367C_ACT91_CVID_OFFSET 8 +#define RTL8367C_ACT91_CVID_MASK 0x100 +#define RTL8367C_OP90_NOT_OFFSET 6 +#define RTL8367C_OP90_NOT_MASK 0x40 +#define RTL8367C_ACT90_GPIO_OFFSET 5 +#define RTL8367C_ACT90_GPIO_MASK 0x20 +#define RTL8367C_ACT90_FORWARD_OFFSET 4 +#define RTL8367C_ACT90_FORWARD_MASK 0x10 +#define RTL8367C_ACT90_POLICING_OFFSET 3 +#define RTL8367C_ACT90_POLICING_MASK 0x8 +#define RTL8367C_ACT90_PRIORITY_OFFSET 2 +#define RTL8367C_ACT90_PRIORITY_MASK 0x4 +#define RTL8367C_ACT90_SVID_OFFSET 1 +#define RTL8367C_ACT90_SVID_MASK 0x2 +#define RTL8367C_ACT90_CVID_OFFSET 0 +#define RTL8367C_ACT90_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL46 0x06FE +#define RTL8367C_OP93_NOT_OFFSET 14 +#define RTL8367C_OP93_NOT_MASK 0x4000 +#define RTL8367C_ACT93_GPIO_OFFSET 13 +#define RTL8367C_ACT93_GPIO_MASK 0x2000 +#define RTL8367C_ACT93_FORWARD_OFFSET 12 +#define RTL8367C_ACT93_FORWARD_MASK 0x1000 +#define RTL8367C_ACT93_POLICING_OFFSET 11 +#define RTL8367C_ACT93_POLICING_MASK 0x800 +#define RTL8367C_ACT93_PRIORITY_OFFSET 10 +#define RTL8367C_ACT93_PRIORITY_MASK 0x400 +#define RTL8367C_ACT93_SVID_OFFSET 9 +#define RTL8367C_ACT93_SVID_MASK 0x200 +#define RTL8367C_ACT93_CVID_OFFSET 8 +#define RTL8367C_ACT93_CVID_MASK 0x100 +#define RTL8367C_OP92_NOT_OFFSET 6 +#define RTL8367C_OP92_NOT_MASK 0x40 +#define RTL8367C_ACT92_GPIO_OFFSET 5 +#define RTL8367C_ACT92_GPIO_MASK 0x20 +#define RTL8367C_ACT92_FORWARD_OFFSET 4 +#define RTL8367C_ACT92_FORWARD_MASK 0x10 +#define RTL8367C_ACT92_POLICING_OFFSET 3 +#define RTL8367C_ACT92_POLICING_MASK 0x8 +#define RTL8367C_ACT92_PRIORITY_OFFSET 2 +#define RTL8367C_ACT92_PRIORITY_MASK 0x4 +#define RTL8367C_ACT92_SVID_OFFSET 1 +#define RTL8367C_ACT92_SVID_MASK 0x2 +#define RTL8367C_ACT92_CVID_OFFSET 0 +#define RTL8367C_ACT92_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL47 0x06FF +#define RTL8367C_OP95_NOT_OFFSET 14 +#define RTL8367C_OP95_NOT_MASK 0x4000 +#define RTL8367C_ACT95_GPIO_OFFSET 13 +#define RTL8367C_ACT95_GPIO_MASK 0x2000 +#define RTL8367C_ACT95_FORWARD_OFFSET 12 +#define RTL8367C_ACT95_FORWARD_MASK 0x1000 +#define RTL8367C_ACT95_POLICING_OFFSET 11 +#define RTL8367C_ACT95_POLICING_MASK 0x800 +#define RTL8367C_ACT95_PRIORITY_OFFSET 10 +#define RTL8367C_ACT95_PRIORITY_MASK 0x400 +#define RTL8367C_ACT95_SVID_OFFSET 9 +#define RTL8367C_ACT95_SVID_MASK 0x200 +#define RTL8367C_ACT95_CVID_OFFSET 8 +#define RTL8367C_ACT95_CVID_MASK 0x100 +#define RTL8367C_OP94_NOT_OFFSET 6 +#define RTL8367C_OP94_NOT_MASK 0x40 +#define RTL8367C_ACT94_GPIO_OFFSET 5 +#define RTL8367C_ACT94_GPIO_MASK 0x20 +#define RTL8367C_ACT94_FORWARD_OFFSET 4 +#define RTL8367C_ACT94_FORWARD_MASK 0x10 +#define RTL8367C_ACT94_POLICING_OFFSET 3 +#define RTL8367C_ACT94_POLICING_MASK 0x8 +#define RTL8367C_ACT94_PRIORITY_OFFSET 2 +#define RTL8367C_ACT94_PRIORITY_MASK 0x4 +#define RTL8367C_ACT94_SVID_OFFSET 1 +#define RTL8367C_ACT94_SVID_MASK 0x2 +#define RTL8367C_ACT94_CVID_OFFSET 0 +#define RTL8367C_ACT94_CVID_MASK 0x1 + +/* (16'h0700)cvlan_reg */ + +#define RTL8367C_REG_VLAN_PVID_CTRL0 0x0700 +#define RTL8367C_PORT1_VIDX_OFFSET 8 +#define RTL8367C_PORT1_VIDX_MASK 0x1F00 +#define RTL8367C_PORT0_VIDX_OFFSET 0 +#define RTL8367C_PORT0_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL1 0x0701 +#define RTL8367C_PORT3_VIDX_OFFSET 8 +#define RTL8367C_PORT3_VIDX_MASK 0x1F00 +#define RTL8367C_PORT2_VIDX_OFFSET 0 +#define RTL8367C_PORT2_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL2 0x0702 +#define RTL8367C_PORT5_VIDX_OFFSET 8 +#define RTL8367C_PORT5_VIDX_MASK 0x1F00 +#define RTL8367C_PORT4_VIDX_OFFSET 0 +#define RTL8367C_PORT4_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL3 0x0703 +#define RTL8367C_PORT7_VIDX_OFFSET 8 +#define RTL8367C_PORT7_VIDX_MASK 0x1F00 +#define RTL8367C_PORT6_VIDX_OFFSET 0 +#define RTL8367C_PORT6_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL4 0x0704 +#define RTL8367C_PORT9_VIDX_OFFSET 8 +#define RTL8367C_PORT9_VIDX_MASK 0x1F00 +#define RTL8367C_PORT8_VIDX_OFFSET 0 +#define RTL8367C_PORT8_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL5 0x0705 +#define RTL8367C_VLAN_PVID_CTRL5_OFFSET 0 +#define RTL8367C_VLAN_PVID_CTRL5_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_VALID 0x0708 +#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB0_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB0_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB0_CTRL0 0x0709 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL1 0x070a +#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL2 0x070b +#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL4 0x070c +#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL3 0x070f + +#define RTL8367C_REG_VLAN_PPB1_VALID 0x0710 +#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB1_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB1_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB1_CTRL0 0x0711 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL1 0x0712 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL2 0x0713 +#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL4 0x0714 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL3 0x0717 + +#define RTL8367C_REG_VLAN_PPB2_VALID 0x0718 +#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB2_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB2_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB2_CTRL0 0x0719 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL1 0x071a +#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL2 0x071b +#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL4 0x071c +#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL3 0x071f + +#define RTL8367C_REG_VLAN_PPB3_VALID 0x0720 +#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB3_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB3_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB3_CTRL0 0x0721 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL1 0x0722 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL2 0x0723 +#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL4 0x0724 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL3 0x0727 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 0x0728 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL1 0x0729 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL2 0x072a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL3 0x072b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL0 0x072c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL1 0x072d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL2 0x072e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL3 0x072f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL0 0x0730 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL1 0x0731 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL2 0x0732 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL3 0x0733 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL0 0x0734 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL1 0x0735 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL2 0x0736 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL3 0x0737 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL0 0x0738 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL1 0x0739 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL2 0x073a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL3 0x073b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL0 0x073c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL1 0x073d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL2 0x073e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL3 0x073f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL0 0x0740 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL1 0x0741 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL2 0x0742 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL3 0x0743 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL0 0x0744 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL1 0x0745 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL2 0x0746 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL3 0x0747 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL0 0x0748 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL1 0x0749 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL2 0x074a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL3 0x074b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL0 0x074c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL1 0x074d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL2 0x074e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL3 0x074f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL0 0x0750 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL1 0x0751 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL2 0x0752 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL3 0x0753 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL0 0x0754 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL1 0x0755 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL2 0x0756 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL3 0x0757 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL0 0x0758 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL1 0x0759 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL2 0x075a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL3 0x075b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL0 0x075c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL1 0x075d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL2 0x075e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL3 0x075f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL0 0x0760 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL1 0x0761 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL2 0x0762 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL3 0x0763 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL0 0x0764 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL1 0x0765 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL2 0x0766 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL3 0x0767 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL0 0x0768 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL1 0x0769 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL2 0x076a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL3 0x076b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL0 0x076c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL1 0x076d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL2 0x076e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL3 0x076f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL0 0x0770 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL1 0x0771 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL2 0x0772 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL3 0x0773 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL0 0x0774 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL1 0x0775 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL2 0x0776 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL3 0x0777 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL0 0x0778 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL1 0x0779 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL2 0x077a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL3 0x077b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL0 0x077c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL1 0x077d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL2 0x077e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL3 0x077f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL0 0x0780 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL1 0x0781 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL2 0x0782 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL3 0x0783 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL0 0x0784 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL1 0x0785 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL2 0x0786 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL3 0x0787 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL0 0x0788 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL1 0x0789 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL2 0x078a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL3 0x078b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL0 0x078c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL1 0x078d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL2 0x078e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL3 0x078f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL0 0x0790 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL1 0x0791 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL2 0x0792 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL3 0x0793 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL0 0x0794 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL1 0x0795 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL2 0x0796 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL3 0x0797 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL0 0x0798 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL1 0x0799 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL2 0x079a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL3 0x079b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL0 0x079c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL1 0x079d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL2 0x079e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL3 0x079f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL0 0x07a0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL1 0x07a1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL2 0x07a2 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL3 0x07a3 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL0 0x07a4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL1 0x07a5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL2 0x07a6 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL3 0x07a7 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_CTRL 0x07a8 +#define RTL8367C_VLAN_CTRL_OFFSET 0 +#define RTL8367C_VLAN_CTRL_MASK 0x1 + +#define RTL8367C_REG_VLAN_INGRESS 0x07a9 +#define RTL8367C_VLAN_INGRESS_OFFSET 0 +#define RTL8367C_VLAN_INGRESS_MASK 0x7FF + +#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 0x07aa +#define RTL8367C_PORT7_FRAME_TYPE_OFFSET 14 +#define RTL8367C_PORT7_FRAME_TYPE_MASK 0xC000 +#define RTL8367C_PORT6_FRAME_TYPE_OFFSET 12 +#define RTL8367C_PORT6_FRAME_TYPE_MASK 0x3000 +#define RTL8367C_PORT5_FRAME_TYPE_OFFSET 10 +#define RTL8367C_PORT5_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_PORT4_FRAME_TYPE_OFFSET 8 +#define RTL8367C_PORT4_FRAME_TYPE_MASK 0x300 +#define RTL8367C_PORT3_FRAME_TYPE_OFFSET 6 +#define RTL8367C_PORT3_FRAME_TYPE_MASK 0xC0 +#define RTL8367C_PORT2_FRAME_TYPE_OFFSET 4 +#define RTL8367C_PORT2_FRAME_TYPE_MASK 0x30 +#define RTL8367C_PORT1_FRAME_TYPE_OFFSET 2 +#define RTL8367C_PORT1_FRAME_TYPE_MASK 0xC +#define RTL8367C_PORT0_FRAME_TYPE_OFFSET 0 +#define RTL8367C_PORT0_FRAME_TYPE_MASK 0x3 + +#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL1 0x07ab +#define RTL8367C_PORT10_FRAME_TYPE_OFFSET 4 +#define RTL8367C_PORT10_FRAME_TYPE_MASK 0x30 +#define RTL8367C_PORT9_FRAME_TYPE_OFFSET 2 +#define RTL8367C_PORT9_FRAME_TYPE_MASK 0xC +#define RTL8367C_PORT8_FRAME_TYPE_OFFSET 0 +#define RTL8367C_PORT8_FRAME_TYPE_MASK 0x3 + +#define RTL8367C_REG_PORT_PBFIDEN 0x07ac +#define RTL8367C_PORT_PBFIDEN_OFFSET 0 +#define RTL8367C_PORT_PBFIDEN_MASK 0x7FF + +#define RTL8367C_REG_PORT0_PBFID 0x07ad +#define RTL8367C_PORT0_PBFID_OFFSET 0 +#define RTL8367C_PORT0_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT1_PBFID 0x07ae +#define RTL8367C_PORT1_PBFID_OFFSET 0 +#define RTL8367C_PORT1_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT2_PBFID 0x07af +#define RTL8367C_PORT2_PBFID_OFFSET 0 +#define RTL8367C_PORT2_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT3_PBFID 0x07b0 +#define RTL8367C_PORT3_PBFID_OFFSET 0 +#define RTL8367C_PORT3_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT4_PBFID 0x07b1 +#define RTL8367C_PORT4_PBFID_OFFSET 0 +#define RTL8367C_PORT4_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT5_PBFID 0x07b2 +#define RTL8367C_PORT5_PBFID_OFFSET 0 +#define RTL8367C_PORT5_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT6_PBFID 0x07b3 +#define RTL8367C_PORT6_PBFID_OFFSET 0 +#define RTL8367C_PORT6_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT7_PBFID 0x07b4 +#define RTL8367C_PORT7_PBFID_OFFSET 0 +#define RTL8367C_PORT7_PBFID_MASK 0xF + +#define RTL8367C_REG_VLAN_EXT_CTRL 0x07b5 +#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET 2 +#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_MASK 0x4 +#define RTL8367C_VLAN_VID4095_TYPE_OFFSET 1 +#define RTL8367C_VLAN_VID4095_TYPE_MASK 0x2 +#define RTL8367C_VLAN_VID0_TYPE_OFFSET 0 +#define RTL8367C_VLAN_VID0_TYPE_MASK 0x1 + +#define RTL8367C_REG_VLAN_EXT_CTRL2 0x07b6 +#define RTL8367C_VLAN_EXT_CTRL2_OFFSET 0 +#define RTL8367C_VLAN_EXT_CTRL2_MASK 0x1 + +#define RTL8367C_REG_PORT8_PBFID 0x07b7 +#define RTL8367C_PORT8_PBFID_OFFSET 0 +#define RTL8367C_PORT8_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT9_PBFID 0x07b8 +#define RTL8367C_PORT9_PBFID_OFFSET 0 +#define RTL8367C_PORT9_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT10_PBFID 0x07b9 +#define RTL8367C_PORT10_PBFID_OFFSET 0 +#define RTL8367C_PORT10_PBFID_MASK 0xF + +#define RTL8367C_REG_CVLAN_DUMMY00 0x07E0 + +#define RTL8367C_REG_CVLAN_DUMMY01 0x07E1 + +#define RTL8367C_REG_CVLAN_DUMMY02 0x07E2 + +#define RTL8367C_REG_CVLAN_DUMMY03 0x07E3 + +#define RTL8367C_REG_CVLAN_DUMMY04 0x07E4 + +#define RTL8367C_REG_CVLAN_DUMMY05 0x07E5 + +#define RTL8367C_REG_CVLAN_DUMMY06 0x07E6 + +#define RTL8367C_REG_CVLAN_DUMMY07 0x07E7 + +#define RTL8367C_REG_CVLAN_DUMMY08 0x07E8 + +#define RTL8367C_REG_CVLAN_DUMMY09 0x07E9 + +#define RTL8367C_REG_CVLAN_DUMMY10 0x07EA + +#define RTL8367C_REG_CVLAN_DUMMY11 0x07EB + +#define RTL8367C_REG_CVLAN_DUMMY12 0x07EC + +#define RTL8367C_REG_CVLAN_DUMMY13 0x07ED + +#define RTL8367C_REG_CVLAN_DUMMY14 0x07EE + +#define RTL8367C_REG_CVLAN_DUMMY15 0x07EF + +/* (16'h0800)dpm_reg */ + +#define RTL8367C_REG_RMA_CTRL00 0x0800 +#define RTL8367C_RMA_CTRL00_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL00_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_TRAP_PRIORITY_OFFSET 3 +#define RTL8367C_TRAP_PRIORITY_MASK 0x38 +#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL01 0x0801 +#define RTL8367C_RMA_CTRL01_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL01_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL02 0x0802 +#define RTL8367C_RMA_CTRL02_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL02_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL03 0x0803 +#define RTL8367C_RMA_CTRL03_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL03_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL04 0x0804 +#define RTL8367C_RMA_CTRL04_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL04_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL08 0x0808 +#define RTL8367C_RMA_CTRL08_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL08_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL0D 0x080d +#define RTL8367C_RMA_CTRL0D_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL0D_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL0E 0x080e +#define RTL8367C_RMA_CTRL0E_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL0E_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL10 0x0810 +#define RTL8367C_RMA_CTRL10_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL10_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL11 0x0811 +#define RTL8367C_RMA_CTRL11_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL11_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL12 0x0812 +#define RTL8367C_RMA_CTRL12_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL12_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL13 0x0813 +#define RTL8367C_RMA_CTRL13_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL13_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL18 0x0818 +#define RTL8367C_RMA_CTRL18_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL18_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL1A 0x081a +#define RTL8367C_RMA_CTRL1A_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL1A_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL20 0x0820 +#define RTL8367C_RMA_CTRL20_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL20_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL21 0x0821 +#define RTL8367C_RMA_CTRL21_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL21_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL22 0x0822 +#define RTL8367C_RMA_CTRL22_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL22_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL_CDP 0x0830 +#define RTL8367C_RMA_CTRL_CDP_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL_CDP_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL_CSSTP 0x0831 +#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL_LLDP 0x0832 +#define RTL8367C_RMA_CTRL_LLDP_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL_LLDP_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_LLDP_EN 0x0833 +#define RTL8367C_RMA_LLDP_EN_OFFSET 0 +#define RTL8367C_RMA_LLDP_EN_MASK 0x1 + +#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 0x0851 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL1 0x0852 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL2 0x0853 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 0x0855 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL1 0x0856 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL2 0x0857 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL0 0x0859 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL1 0x085a +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL2 0x085b +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL0 0x085d +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL1 0x085e +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL2 0x085f +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL0 0x0861 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL1 0x0862 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL2 0x0863 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 0x0865 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL1 0x0866 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 0x0867 +#define RTL8367C_DSCP3_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP3_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP2_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP2_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP1_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP1_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP0_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL1 0x0868 +#define RTL8367C_DSCP7_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP7_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP6_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP6_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP5_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP5_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP4_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL2 0x0869 +#define RTL8367C_DSCP11_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP11_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP10_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP10_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP9_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP9_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP8_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL3 0x086a +#define RTL8367C_DSCP15_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP15_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP14_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP14_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP13_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP13_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP12_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP12_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL4 0x086b +#define RTL8367C_DSCP19_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP19_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP18_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP18_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP17_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP17_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP16_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP16_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL5 0x086c +#define RTL8367C_DSCP23_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP23_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP22_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP22_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP21_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP21_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP20_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP20_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL6 0x086d +#define RTL8367C_DSCP27_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP27_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP26_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP26_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP25_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP25_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP24_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP24_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL7 0x086e +#define RTL8367C_DSCP31_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP31_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP30_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP30_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP29_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP29_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP28_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP28_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL8 0x086f +#define RTL8367C_DSCP35_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP35_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP34_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP34_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP33_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP33_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP32_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP32_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL9 0x0870 +#define RTL8367C_DSCP39_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP39_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP38_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP38_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP37_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP37_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP36_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP36_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL10 0x0871 +#define RTL8367C_DSCP43_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP43_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP42_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP42_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP41_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP41_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP40_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP40_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL11 0x0872 +#define RTL8367C_DSCP47_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP47_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP46_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP46_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP45_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP45_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP44_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP44_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL12 0x0873 +#define RTL8367C_DSCP51_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP51_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP50_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP50_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP49_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP49_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP48_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP48_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL13 0x0874 +#define RTL8367C_DSCP55_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP55_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP54_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP54_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP53_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP53_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP52_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP52_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL14 0x0875 +#define RTL8367C_DSCP59_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP59_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP58_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP58_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP57_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP57_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP56_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP56_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL15 0x0876 +#define RTL8367C_DSCP63_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP63_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP62_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP62_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP61_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP61_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP60_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP60_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 0x0877 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL1 0x0878 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_DUMMY0879 0x0879 +#define RTL8367C_DUMMY0879_OFFSET 0 +#define RTL8367C_DUMMY0879_MASK 0x1 + +#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2 0x087a +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 0x087b +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL1 0x087c +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL2 0x087d +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL3 0x087e +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 0x087f +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_OFFSET 12 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_MASK 0x7000 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_OFFSET 8 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_MASK 0x700 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_OFFSET 4 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_MASK 0x70 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_OFFSET 0 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK 0x7 + +#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1 0x0880 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_OFFSET 12 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_MASK 0x7000 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_OFFSET 8 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_MASK 0x700 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_OFFSET 4 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_MASK 0x70 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_OFFSET 0 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_MASK 0x7 + +#define RTL8367C_REG_QOS_TRAP_PRIORITY0 0x0881 +#define RTL8367C_UNKNOWN_MC_PRIORTY_OFFSET 12 +#define RTL8367C_UNKNOWN_MC_PRIORTY_MASK 0x7000 +#define RTL8367C_SVLAN_PRIOIRTY_OFFSET 8 +#define RTL8367C_SVLAN_PRIOIRTY_MASK 0x700 +#define RTL8367C_OAM_PRIOIRTY_OFFSET 4 +#define RTL8367C_OAM_PRIOIRTY_MASK 0x70 +#define RTL8367C_DOT1X_PRIORTY_OFFSET 0 +#define RTL8367C_DOT1X_PRIORTY_MASK 0x7 + +#define RTL8367C_REG_QOS_TRAP_PRIORITY1 0x0882 +#define RTL8367C_DW8051_TRAP_PRI_OFFSET 4 +#define RTL8367C_DW8051_TRAP_PRI_MASK 0x70 +#define RTL8367C_EEELLDP_TRAP_PRI_OFFSET 0 +#define RTL8367C_EEELLDP_TRAP_PRI_MASK 0x7 + +#define RTL8367C_REG_MAX_LENGTH_CFG 0x0883 +#define RTL8367C_MAX_LENGTH_GIGA_OFFSET 8 +#define RTL8367C_MAX_LENGTH_GIGA_MASK 0xFF00 +#define RTL8367C_MAX_LENGTH_10_100M_OFFSET 0 +#define RTL8367C_MAX_LENGTH_10_100M_MASK 0xFF + +#define RTL8367C_REG_MAX_LEN_RX_TX 0x0884 +#define RTL8367C_MAX_LEN_RX_TX_OFFSET 0 +#define RTL8367C_MAX_LEN_RX_TX_MASK 0x3 + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 0x0885 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1 0x0886 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2 0x0887 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3 0x0888 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX 0x0889 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_MASK 0x7FF + +#define RTL8367C_REG_MAX_LENGTH_CFG_EXT 0x088a +#define RTL8367C_MAX_LENGTH_GIGA_EXT_OFFSET 3 +#define RTL8367C_MAX_LENGTH_GIGA_EXT_MASK 0x38 +#define RTL8367C_MAX_LENGTH_10_100M_EXT_OFFSET 0 +#define RTL8367C_MAX_LENGTH_10_100M_EXT_MASK 0x7 + +#define RTL8367C_REG_MAX_LEN_RX_TX_CFG0 0x088c +#define RTL8367C_MAX_LEN_RX_TX_CFG0_OFFSET 0 +#define RTL8367C_MAX_LEN_RX_TX_CFG0_MASK 0x3FFF + +#define RTL8367C_REG_MAX_LEN_RX_TX_CFG1 0x088d +#define RTL8367C_MAX_LEN_RX_TX_CFG1_OFFSET 0 +#define RTL8367C_MAX_LEN_RX_TX_CFG1_MASK 0x3FFF + +#define RTL8367C_REG_UNDA_FLOODING_PMSK 0x0890 +#define RTL8367C_UNDA_FLOODING_PMSK_OFFSET 0 +#define RTL8367C_UNDA_FLOODING_PMSK_MASK 0x7FF + +#define RTL8367C_REG_UNMCAST_FLOADING_PMSK 0x0891 +#define RTL8367C_UNMCAST_FLOADING_PMSK_OFFSET 0 +#define RTL8367C_UNMCAST_FLOADING_PMSK_MASK 0x7FF + +#define RTL8367C_REG_BCAST_FLOADING_PMSK 0x0892 +#define RTL8367C_BCAST_FLOADING_PMSK_OFFSET 0 +#define RTL8367C_BCAST_FLOADING_PMSK_MASK 0x7FF + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2 0x08a0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK 0x3 + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3 0x08a1 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK 0x3 + +#define RTL8367C_REG_PORT_ISOLATION_PORT0_MASK 0x08a2 +#define RTL8367C_PORT_ISOLATION_PORT0_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT0_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT1_MASK 0x08a3 +#define RTL8367C_PORT_ISOLATION_PORT1_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT1_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT2_MASK 0x08a4 +#define RTL8367C_PORT_ISOLATION_PORT2_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT2_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT3_MASK 0x08a5 +#define RTL8367C_PORT_ISOLATION_PORT3_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT3_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT4_MASK 0x08a6 +#define RTL8367C_PORT_ISOLATION_PORT4_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT4_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT5_MASK 0x08a7 +#define RTL8367C_PORT_ISOLATION_PORT5_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT5_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT6_MASK 0x08a8 +#define RTL8367C_PORT_ISOLATION_PORT6_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT6_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT7_MASK 0x08a9 +#define RTL8367C_PORT_ISOLATION_PORT7_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT7_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT8_MASK 0x08aa +#define RTL8367C_PORT_ISOLATION_PORT8_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT8_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT9_MASK 0x08ab +#define RTL8367C_PORT_ISOLATION_PORT9_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT9_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT10_MASK 0x08ac +#define RTL8367C_PORT_ISOLATION_PORT10_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT10_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_CTRL 0x08b4 +#define RTL8367C_FORCE_CTRL_OFFSET 0 +#define RTL8367C_FORCE_CTRL_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT0_MASK 0x08b5 +#define RTL8367C_FORCE_PORT0_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT0_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT1_MASK 0x08b6 +#define RTL8367C_FORCE_PORT1_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT1_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT2_MASK 0x08b7 +#define RTL8367C_FORCE_PORT2_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT2_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT3_MASK 0x08b8 +#define RTL8367C_FORCE_PORT3_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT3_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT4_MASK 0x08b9 +#define RTL8367C_FORCE_PORT4_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT4_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT5_MASK 0x08ba +#define RTL8367C_FORCE_PORT5_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT5_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT6_MASK 0x08bb +#define RTL8367C_FORCE_PORT6_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT6_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT7_MASK 0x08bc +#define RTL8367C_FORCE_PORT7_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT7_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT8_MASK 0x08bd +#define RTL8367C_FORCE_PORT8_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT8_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT9_MASK 0x08be +#define RTL8367C_FORCE_PORT9_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT9_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT10_MASK 0x08bf +#define RTL8367C_FORCE_PORT10_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT10_MASK_MASK 0x7FF + +#define RTL8367C_REG_SOURCE_PORT_PERMIT 0x08c5 +#define RTL8367C_SOURCE_PORT_PERMIT_OFFSET 0 +#define RTL8367C_SOURCE_PORT_PERMIT_MASK 0x7FF + +#define RTL8367C_REG_IPMCAST_VLAN_LEAKY 0x08c6 +#define RTL8367C_IPMCAST_VLAN_LEAKY_OFFSET 0 +#define RTL8367C_IPMCAST_VLAN_LEAKY_MASK 0x7FF + +#define RTL8367C_REG_IPMCAST_PORTISO_LEAKY 0x08c7 +#define RTL8367C_IPMCAST_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_IPMCAST_PORTISO_LEAKY_MASK 0x7FF + +#define RTL8367C_REG_PORT_SECURITY_CTRL 0x08c8 +#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_OFFSET 6 +#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK 0xC0 +#define RTL8367C_LUT_LEARN_OVER_ACT_OFFSET 4 +#define RTL8367C_LUT_LEARN_OVER_ACT_MASK 0x30 +#define RTL8367C_UNMATCHED_SA_BEHAVE_OFFSET 2 +#define RTL8367C_UNMATCHED_SA_BEHAVE_MASK 0xC +#define RTL8367C_UNKNOWN_SA_BEHAVE_OFFSET 0 +#define RTL8367C_UNKNOWN_SA_BEHAVE_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 0x08c9 +#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_OFFSET 14 +#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_MASK 0xC000 +#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_OFFSET 12 +#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_MASK 0x3000 +#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_OFFSET 10 +#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_MASK 0xC00 +#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_OFFSET 8 +#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_MASK 0x300 +#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_OFFSET 6 +#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_MASK 0xC0 +#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_OFFSET 4 +#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_MASK 0x30 +#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_OFFSET 2 +#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_MASK 0xC +#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_OFFSET 0 +#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL1 0x08ca +#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_OFFSET 4 +#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_MASK 0x30 +#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_OFFSET 2 +#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_MASK 0xC +#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_OFFSET 0 +#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 0x08cb +#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_OFFSET 14 +#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_MASK 0xC000 +#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_OFFSET 12 +#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_MASK 0x3000 +#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_OFFSET 10 +#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_MASK 0xC00 +#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_OFFSET 8 +#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_MASK 0x300 +#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_OFFSET 6 +#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_MASK 0xC0 +#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_OFFSET 4 +#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_MASK 0x30 +#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_OFFSET 2 +#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_MASK 0xC +#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_OFFSET 0 +#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL1 0x08cc +#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_OFFSET 4 +#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_MASK 0x30 +#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_OFFSET 2 +#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_MASK 0xC +#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_OFFSET 0 +#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 0x08cd +#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_OFFSET 14 +#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_MASK 0xC000 +#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_OFFSET 12 +#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_MASK 0x3000 +#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_OFFSET 10 +#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_MASK 0xC00 +#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_OFFSET 8 +#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_MASK 0x300 +#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_OFFSET 6 +#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_MASK 0xC0 +#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_OFFSET 4 +#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_MASK 0x30 +#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_OFFSET 2 +#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_MASK 0xC +#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_OFFSET 0 +#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK 0x3 + +#define RTL8367C_REG_PORT_TRUNK_DROP_CTRL 0x08ce +#define RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET 0 +#define RTL8367C_PORT_TRUNK_DROP_CTRL_MASK 0x1 + +#define RTL8367C_REG_PORT_TRUNK_CTRL 0x08cf +#define RTL8367C_PORT_TRUNK_DUMB_OFFSET 8 +#define RTL8367C_PORT_TRUNK_DUMB_MASK 0x100 +#define RTL8367C_PORT_TRUNK_FLOOD_OFFSET 7 +#define RTL8367C_PORT_TRUNK_FLOOD_MASK 0x80 +#define RTL8367C_DPORT_HASH_OFFSET 6 +#define RTL8367C_DPORT_HASH_MASK 0x40 +#define RTL8367C_SPORT_HASH_OFFSET 5 +#define RTL8367C_SPORT_HASH_MASK 0x20 +#define RTL8367C_DIP_HASH_OFFSET 4 +#define RTL8367C_DIP_HASH_MASK 0x10 +#define RTL8367C_SIP_HASH_OFFSET 3 +#define RTL8367C_SIP_HASH_MASK 0x8 +#define RTL8367C_DMAC_HASH_OFFSET 2 +#define RTL8367C_DMAC_HASH_MASK 0x4 +#define RTL8367C_SMAC_HASH_OFFSET 1 +#define RTL8367C_SMAC_HASH_MASK 0x2 +#define RTL8367C_SPA_HASH_OFFSET 0 +#define RTL8367C_SPA_HASH_MASK 0x1 + +#define RTL8367C_REG_PORT_TRUNK_GROUP_MASK 0x08d0 +#define RTL8367C_PORT_TRUNK_GROUP2_MASK_OFFSET 8 +#define RTL8367C_PORT_TRUNK_GROUP2_MASK_MASK 0x300 +#define RTL8367C_PORT_TRUNK_GROUP1_MASK_OFFSET 4 +#define RTL8367C_PORT_TRUNK_GROUP1_MASK_MASK 0xF0 +#define RTL8367C_PORT_TRUNK_GROUP0_MASK_OFFSET 0 +#define RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK 0xF + +#define RTL8367C_REG_PORT_TRUNK_FLOWCTRL 0x08d1 +#define RTL8367C_EN_FLOWCTRL_TG2_OFFSET 2 +#define RTL8367C_EN_FLOWCTRL_TG2_MASK 0x4 +#define RTL8367C_EN_FLOWCTRL_TG1_OFFSET 1 +#define RTL8367C_EN_FLOWCTRL_TG1_MASK 0x2 +#define RTL8367C_EN_FLOWCTRL_TG0_OFFSET 0 +#define RTL8367C_EN_FLOWCTRL_TG0_MASK 0x1 + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0 0x08d2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK 0x3 + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1 0x08d3 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK 0x3 + +#define RTL8367C_REG_DOS_CFG 0x08d4 +#define RTL8367C_DROP_ICMPFRAGMENT_OFFSET 9 +#define RTL8367C_DROP_ICMPFRAGMENT_MASK 0x200 +#define RTL8367C_DROP_TCPFRAGERROR_OFFSET 8 +#define RTL8367C_DROP_TCPFRAGERROR_MASK 0x100 +#define RTL8367C_DROP_TCPSHORTHDR_OFFSET 7 +#define RTL8367C_DROP_TCPSHORTHDR_MASK 0x80 +#define RTL8367C_DROP_SYN1024_OFFSET 6 +#define RTL8367C_DROP_SYN1024_MASK 0x40 +#define RTL8367C_DROP_NULLSCAN_OFFSET 5 +#define RTL8367C_DROP_NULLSCAN_MASK 0x20 +#define RTL8367C_DROP_XMASCAN_OFFSET 4 +#define RTL8367C_DROP_XMASCAN_MASK 0x10 +#define RTL8367C_DROP_SYNFINSCAN_OFFSET 3 +#define RTL8367C_DROP_SYNFINSCAN_MASK 0x8 +#define RTL8367C_DROP_BLATATTACKS_OFFSET 2 +#define RTL8367C_DROP_BLATATTACKS_MASK 0x4 +#define RTL8367C_DROP_LANDATTACKS_OFFSET 1 +#define RTL8367C_DROP_LANDATTACKS_MASK 0x2 +#define RTL8367C_DROP_DAEQSA_OFFSET 0 +#define RTL8367C_DROP_DAEQSA_MASK 0x1 + +#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1 0x08d5 +#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_OFFSET 4 +#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_MASK 0x30 +#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_OFFSET 2 +#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_MASK 0xC +#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_OFFSET 0 +#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_MASK 0x3 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4 0x08d6 +#define RTL8367C_PORT9_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT9_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5 0x08d7 +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT 0x08d8 +#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1_EXT 0x08d9 +#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2_EXT 0x08da +#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3_EXT 0x08db +#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT 0x08dc +#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT 0x08dd +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL10 0x08de +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_MASK 0x7FF + +#define RTL8367C_REG_FPGA_VER_CEN 0x08e0 + +#define RTL8367C_REG_FPGA_TIME_CEN 0x08e1 + +#define RTL8367C_REG_FPGA_DATE_CEN 0x08e2 + +#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 0x0900 +#define RTL8367C_PORT3_NUMBER_OFFSET 12 +#define RTL8367C_PORT3_NUMBER_MASK 0x7000 +#define RTL8367C_PORT2_NUMBER_OFFSET 8 +#define RTL8367C_PORT2_NUMBER_MASK 0x700 +#define RTL8367C_PORT1_NUMBER_OFFSET 4 +#define RTL8367C_PORT1_NUMBER_MASK 0x70 +#define RTL8367C_PORT0_NUMBER_OFFSET 0 +#define RTL8367C_PORT0_NUMBER_MASK 0x7 + +#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL1 0x0901 +#define RTL8367C_PORT7_NUMBER_OFFSET 12 +#define RTL8367C_PORT7_NUMBER_MASK 0x7000 +#define RTL8367C_PORT6_NUMBER_OFFSET 8 +#define RTL8367C_PORT6_NUMBER_MASK 0x700 +#define RTL8367C_PORT5_NUMBER_OFFSET 4 +#define RTL8367C_PORT5_NUMBER_MASK 0x70 +#define RTL8367C_PORT4_NUMBER_OFFSET 0 +#define RTL8367C_PORT4_NUMBER_MASK 0x7 + +#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL2 0x0902 +#define RTL8367C_PORT10_NUMBER_OFFSET 8 +#define RTL8367C_PORT10_NUMBER_MASK 0x700 +#define RTL8367C_PORT9_NUMBER_OFFSET 4 +#define RTL8367C_PORT9_NUMBER_MASK 0x70 +#define RTL8367C_PORT8_NUMBER_OFFSET 0 +#define RTL8367C_PORT8_NUMBER_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 0x0904 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL1 0x0905 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL0 0x0906 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL1 0x0907 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL0 0x0908 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL1 0x0909 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL0 0x090a +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL1 0x090b +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL0 0x090c +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL1 0x090d +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL0 0x090e +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL1 0x090f +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL0 0x0910 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL1 0x0911 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL0 0x0912 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL1 0x0913 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_HIGHPRI_INDICATOR 0x0915 +#define RTL8367C_PORT10_INDICATOR_OFFSET 10 +#define RTL8367C_PORT10_INDICATOR_MASK 0x400 +#define RTL8367C_PORT9_INDICATOR_OFFSET 9 +#define RTL8367C_PORT9_INDICATOR_MASK 0x200 +#define RTL8367C_PORT8_INDICATOR_OFFSET 8 +#define RTL8367C_PORT8_INDICATOR_MASK 0x100 +#define RTL8367C_PORT7_INDICATOR_OFFSET 7 +#define RTL8367C_PORT7_INDICATOR_MASK 0x80 +#define RTL8367C_PORT6_INDICATOR_OFFSET 6 +#define RTL8367C_PORT6_INDICATOR_MASK 0x40 +#define RTL8367C_PORT5_INDICATOR_OFFSET 5 +#define RTL8367C_PORT5_INDICATOR_MASK 0x20 +#define RTL8367C_PORT4_INDICATOR_OFFSET 4 +#define RTL8367C_PORT4_INDICATOR_MASK 0x10 +#define RTL8367C_PORT3_INDICATOR_OFFSET 3 +#define RTL8367C_PORT3_INDICATOR_MASK 0x8 +#define RTL8367C_PORT2_INDICATOR_OFFSET 2 +#define RTL8367C_PORT2_INDICATOR_MASK 0x4 +#define RTL8367C_PORT1_INDICATOR_OFFSET 1 +#define RTL8367C_PORT1_INDICATOR_MASK 0x2 +#define RTL8367C_PORT0_INDICATOR_OFFSET 0 +#define RTL8367C_PORT0_INDICATOR_MASK 0x1 + +#define RTL8367C_REG_HIGHPRI_CFG 0x0916 +#define RTL8367C_HIGHPRI_CFG_OFFSET 0 +#define RTL8367C_HIGHPRI_CFG_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 0x0917 +#define RTL8367C_PORT1_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT1_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT0_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT0_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL1 0x0918 +#define RTL8367C_PORT3_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT3_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT2_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT2_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL2 0x0919 +#define RTL8367C_PORT5_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT5_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT4_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT4_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL3 0x091a +#define RTL8367C_PORT7_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT7_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT6_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT6_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL4 0x091b +#define RTL8367C_PORT9_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT9_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT8_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT8_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL5 0x091c +#define RTL8367C_PORT10_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT10_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL6 0x091d +#define RTL8367C_PORT7_DEBUG_INDICATOR_OFFSET 14 +#define RTL8367C_PORT7_DEBUG_INDICATOR_MASK 0xC000 +#define RTL8367C_PORT6_DEBUG_INDICATOR_OFFSET 12 +#define RTL8367C_PORT6_DEBUG_INDICATOR_MASK 0x3000 +#define RTL8367C_PORT5_DEBUG_INDICATOR_OFFSET 10 +#define RTL8367C_PORT5_DEBUG_INDICATOR_MASK 0xC00 +#define RTL8367C_PORT4_DEBUG_INDICATOR_OFFSET 8 +#define RTL8367C_PORT4_DEBUG_INDICATOR_MASK 0x300 +#define RTL8367C_PORT3_DEBUG_INDICATOR_OFFSET 6 +#define RTL8367C_PORT3_DEBUG_INDICATOR_MASK 0xC0 +#define RTL8367C_PORT2_DEBUG_INDICATOR_OFFSET 4 +#define RTL8367C_PORT2_DEBUG_INDICATOR_MASK 0x30 +#define RTL8367C_PORT1_DEBUG_INDICATOR_OFFSET 2 +#define RTL8367C_PORT1_DEBUG_INDICATOR_MASK 0xC +#define RTL8367C_PORT0_DEBUG_INDICATOR_OFFSET 0 +#define RTL8367C_PORT0_DEBUG_INDICATOR_MASK 0x3 + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL7 0x091e +#define RTL8367C_PORT10_DEBUG_INDICATOR_OFFSET 4 +#define RTL8367C_PORT10_DEBUG_INDICATOR_MASK 0x30 +#define RTL8367C_PORT9_DEBUG_INDICATOR_OFFSET 2 +#define RTL8367C_PORT9_DEBUG_INDICATOR_MASK 0xC +#define RTL8367C_PORT8_DEBUG_INDICATOR_OFFSET 0 +#define RTL8367C_PORT8_DEBUG_INDICATOR_MASK 0x3 + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 0x0930 +#define RTL8367C_PORT1_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT1_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT0_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT0_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL1 0x0931 +#define RTL8367C_PORT3_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT3_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT2_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT2_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL2 0x0932 +#define RTL8367C_PORT5_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT5_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT4_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT4_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL3 0x0933 +#define RTL8367C_PORT7_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT7_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT6_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT6_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL4 0x0934 +#define RTL8367C_PORT9_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT9_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT8_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT8_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5 0x0935 +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_OFFSET 0 +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_PORT_ENABLE 0x0938 +#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_OFFSET 0 +#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_MASK 0xFF + +#define RTL8367C_REG_EAV_CTRL 0x0939 +#define RTL8367C_EAV_TRAP_CPU_OFFSET 1 +#define RTL8367C_EAV_TRAP_CPU_MASK 0x2 +#define RTL8367C_EAV_TRAP_8051_OFFSET 0 +#define RTL8367C_EAV_TRAP_8051_MASK 0x1 + +#define RTL8367C_REG_UNTAG_DSCP_PRI_CFG 0x093a +#define RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET 0 +#define RTL8367C_UNTAG_DSCP_PRI_CFG_MASK 0x1 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 0x093b +#define RTL8367C_PORT1_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT1_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1 0x093c +#define RTL8367C_PORT3_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT3_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2 0x093d +#define RTL8367C_PORT5_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT5_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3 0x093e +#define RTL8367C_PORT7_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT7_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_TRANSPARENT_EN_CFG 0x093f +#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_OFFSET 0 +#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_MASK 0x1 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY0_H 0x0940 +#define RTL8367C_IPMC_GROUP_ENTRY0_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY0_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY0_L 0x0941 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY1_H 0x0942 +#define RTL8367C_IPMC_GROUP_ENTRY1_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY1_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY1_L 0x0943 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY2_H 0x0944 +#define RTL8367C_IPMC_GROUP_ENTRY2_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY2_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY2_L 0x0945 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY3_H 0x0946 +#define RTL8367C_IPMC_GROUP_ENTRY3_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY3_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY3_L 0x0947 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY4_H 0x0948 +#define RTL8367C_IPMC_GROUP_ENTRY4_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY4_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY4_L 0x0949 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY5_H 0x094a +#define RTL8367C_IPMC_GROUP_ENTRY5_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY5_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY5_L 0x094b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY6_H 0x094c +#define RTL8367C_IPMC_GROUP_ENTRY6_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY6_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY6_L 0x094d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY7_H 0x094e +#define RTL8367C_IPMC_GROUP_ENTRY7_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY7_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY7_L 0x094f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY8_H 0x0950 +#define RTL8367C_IPMC_GROUP_ENTRY8_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY8_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY8_L 0x0951 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY9_H 0x0952 +#define RTL8367C_IPMC_GROUP_ENTRY9_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY9_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY9_L 0x0953 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY10_H 0x0954 +#define RTL8367C_IPMC_GROUP_ENTRY10_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY10_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY10_L 0x0955 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY11_H 0x0956 +#define RTL8367C_IPMC_GROUP_ENTRY11_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY11_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY11_L 0x0957 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY12_H 0x0958 +#define RTL8367C_IPMC_GROUP_ENTRY12_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY12_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY12_L 0x0959 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY13_H 0x095a +#define RTL8367C_IPMC_GROUP_ENTRY13_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY13_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY13_L 0x095b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY14_H 0x095c +#define RTL8367C_IPMC_GROUP_ENTRY14_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY14_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY14_L 0x095d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY15_H 0x095e +#define RTL8367C_IPMC_GROUP_ENTRY15_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY15_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY15_L 0x095f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY16_H 0x0960 +#define RTL8367C_IPMC_GROUP_ENTRY16_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY16_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY16_L 0x0961 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY17_H 0x0962 +#define RTL8367C_IPMC_GROUP_ENTRY17_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY17_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY17_L 0x0963 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY18_H 0x0964 +#define RTL8367C_IPMC_GROUP_ENTRY18_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY18_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY18_L 0x0965 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY19_H 0x0966 +#define RTL8367C_IPMC_GROUP_ENTRY19_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY19_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY19_L 0x0967 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY20_H 0x0968 +#define RTL8367C_IPMC_GROUP_ENTRY20_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY20_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY20_L 0x0969 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY21_H 0x096a +#define RTL8367C_IPMC_GROUP_ENTRY21_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY21_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY21_L 0x096b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY22_H 0x096c +#define RTL8367C_IPMC_GROUP_ENTRY22_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY22_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY22_L 0x096d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY23_H 0x096e +#define RTL8367C_IPMC_GROUP_ENTRY23_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY23_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY23_L 0x096f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY24_H 0x0970 +#define RTL8367C_IPMC_GROUP_ENTRY24_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY24_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY24_L 0x0971 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY25_H 0x0972 +#define RTL8367C_IPMC_GROUP_ENTRY25_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY25_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY25_L 0x0973 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY26_H 0x0974 +#define RTL8367C_IPMC_GROUP_ENTRY26_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY26_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY26_L 0x0975 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY27_H 0x0976 +#define RTL8367C_IPMC_GROUP_ENTRY27_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY27_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY27_L 0x0977 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY28_H 0x0978 +#define RTL8367C_IPMC_GROUP_ENTRY28_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY28_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY28_L 0x0979 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY29_H 0x097a +#define RTL8367C_IPMC_GROUP_ENTRY29_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY29_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY29_L 0x097b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY30_H 0x097c +#define RTL8367C_IPMC_GROUP_ENTRY30_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY30_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY30_L 0x097d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY31_H 0x097e +#define RTL8367C_IPMC_GROUP_ENTRY31_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY31_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY31_L 0x097f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY32_H 0x0980 +#define RTL8367C_IPMC_GROUP_ENTRY32_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY32_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY32_L 0x0981 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY33_H 0x0982 +#define RTL8367C_IPMC_GROUP_ENTRY33_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY33_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY33_L 0x0983 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY34_H 0x0984 +#define RTL8367C_IPMC_GROUP_ENTRY34_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY34_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY34_L 0x0985 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY35_H 0x0986 +#define RTL8367C_IPMC_GROUP_ENTRY35_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY35_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY35_L 0x0987 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY36_H 0x0988 +#define RTL8367C_IPMC_GROUP_ENTRY36_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY36_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY36_L 0x0989 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY37_H 0x098a +#define RTL8367C_IPMC_GROUP_ENTRY37_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY37_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY37_L 0x098b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY38_H 0x098c +#define RTL8367C_IPMC_GROUP_ENTRY38_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY38_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY38_L 0x098d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY39_H 0x098e +#define RTL8367C_IPMC_GROUP_ENTRY39_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY39_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY39_L 0x098f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY40_H 0x0990 +#define RTL8367C_IPMC_GROUP_ENTRY40_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY40_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY40_L 0x0991 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY41_H 0x0992 +#define RTL8367C_IPMC_GROUP_ENTRY41_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY41_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY41_L 0x0993 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY42_H 0x0994 +#define RTL8367C_IPMC_GROUP_ENTRY42_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY42_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY42_L 0x0995 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY43_H 0x0996 +#define RTL8367C_IPMC_GROUP_ENTRY43_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY43_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY43_L 0x0997 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY44_H 0x0998 +#define RTL8367C_IPMC_GROUP_ENTRY44_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY44_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY44_L 0x0999 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY45_H 0x099a +#define RTL8367C_IPMC_GROUP_ENTRY45_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY45_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY45_L 0x099b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY46_H 0x099c +#define RTL8367C_IPMC_GROUP_ENTRY46_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY46_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY46_L 0x099d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY47_H 0x099e +#define RTL8367C_IPMC_GROUP_ENTRY47_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY47_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY47_L 0x099f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY48_H 0x09a0 +#define RTL8367C_IPMC_GROUP_ENTRY48_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY48_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY48_L 0x09a1 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY49_H 0x09a2 +#define RTL8367C_IPMC_GROUP_ENTRY49_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY49_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY49_L 0x09a3 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY50_H 0x09a4 +#define RTL8367C_IPMC_GROUP_ENTRY50_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY50_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY50_L 0x09a5 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY51_H 0x09a6 +#define RTL8367C_IPMC_GROUP_ENTRY51_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY51_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY51_L 0x09a7 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY52_H 0x09a8 +#define RTL8367C_IPMC_GROUP_ENTRY52_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY52_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY52_L 0x09a9 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY53_H 0x09aa +#define RTL8367C_IPMC_GROUP_ENTRY53_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY53_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY53_L 0x09ab + +#define RTL8367C_REG_IPMC_GROUP_ENTRY54_H 0x09ac +#define RTL8367C_IPMC_GROUP_ENTRY54_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY54_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY54_L 0x09ad + +#define RTL8367C_REG_IPMC_GROUP_ENTRY55_H 0x09ae +#define RTL8367C_IPMC_GROUP_ENTRY55_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY55_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY55_L 0x09af + +#define RTL8367C_REG_IPMC_GROUP_ENTRY56_H 0x09b0 +#define RTL8367C_IPMC_GROUP_ENTRY56_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY56_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY56_L 0x09b1 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY57_H 0x09b2 +#define RTL8367C_IPMC_GROUP_ENTRY57_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY57_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY57_L 0x09b3 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY58_H 0x09b4 +#define RTL8367C_IPMC_GROUP_ENTRY58_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY58_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY58_L 0x09b5 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY59_H 0x09b6 +#define RTL8367C_IPMC_GROUP_ENTRY59_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY59_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY59_L 0x09b7 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY60_H 0x09b8 +#define RTL8367C_IPMC_GROUP_ENTRY60_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY60_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY60_L 0x09b9 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY61_H 0x09ba +#define RTL8367C_IPMC_GROUP_ENTRY61_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY61_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY61_L 0x09bb + +#define RTL8367C_REG_IPMC_GROUP_ENTRY62_H 0x09bc +#define RTL8367C_IPMC_GROUP_ENTRY62_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY62_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY62_L 0x09bd + +#define RTL8367C_REG_IPMC_GROUP_ENTRY63_H 0x09be +#define RTL8367C_IPMC_GROUP_ENTRY63_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY63_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY63_L 0x09bf + +#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE 0x09C0 +#define RTL8367C_Port7_ACTION_OFFSET 14 +#define RTL8367C_Port7_ACTION_MASK 0xC000 +#define RTL8367C_Port6_ACTION_OFFSET 12 +#define RTL8367C_Port6_ACTION_MASK 0x3000 +#define RTL8367C_Port5_ACTION_OFFSET 10 +#define RTL8367C_Port5_ACTION_MASK 0xC00 +#define RTL8367C_Port4_ACTION_OFFSET 8 +#define RTL8367C_Port4_ACTION_MASK 0x300 +#define RTL8367C_Port3_ACTION_OFFSET 6 +#define RTL8367C_Port3_ACTION_MASK 0xC0 +#define RTL8367C_Port2_ACTION_OFFSET 4 +#define RTL8367C_Port2_ACTION_MASK 0x30 +#define RTL8367C_Port1_ACTION_OFFSET 2 +#define RTL8367C_Port1_ACTION_MASK 0xC +#define RTL8367C_Port0_ACTION_OFFSET 0 +#define RTL8367C_Port0_ACTION_MASK 0x3 + +#define RTL8367C_REG_MIRROR_CTRL3 0x09C1 +#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET 2 +#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_MASK 0x4 +#define RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET 1 +#define RTL8367C_MIRROR_TX_OVERRIDE_EN_MASK 0x2 +#define RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET 0 +#define RTL8367C_MIRROR_RX_OVERRIDE_EN_MASK 0x1 + +#define RTL8367C_REG_DPM_DUMMY02 0x09C2 + +#define RTL8367C_REG_DPM_DUMMY03 0x09C3 + +#define RTL8367C_REG_DPM_DUMMY04 0x09C4 + +#define RTL8367C_REG_DPM_DUMMY05 0x09C5 + +#define RTL8367C_REG_DPM_DUMMY06 0x09C6 + +#define RTL8367C_REG_DPM_DUMMY07 0x09C7 + +#define RTL8367C_REG_DPM_DUMMY08 0x09C8 + +#define RTL8367C_REG_DPM_DUMMY09 0x09C9 + +#define RTL8367C_REG_DPM_DUMMY10 0x09CA + +#define RTL8367C_REG_DPM_DUMMY11 0x09CB + +#define RTL8367C_REG_DPM_DUMMY12 0x09CC + +#define RTL8367C_REG_DPM_DUMMY13 0x09CD + +#define RTL8367C_REG_DPM_DUMMY14 0x09CE + +#define RTL8367C_REG_DPM_DUMMY15 0x09CF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 0x09D0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL1 0x09D1 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL2 0x09D2 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL3 0x09D3 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL4 0x09D4 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL5 0x09D5 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL6 0x09D6 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL7 0x09D7 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL8 0x09D8 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL9 0x09D9 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_MASK 0x7FF + +#define RTL8367C_REG_MIRROR_CTRL2 0x09DA +#define RTL8367C_MIRROR_REALKEEP_EN_OFFSET 4 +#define RTL8367C_MIRROR_REALKEEP_EN_MASK 0x10 +#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET 3 +#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_MASK 0x8 +#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET 2 +#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_MASK 0x4 +#define RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_MIRROR_RX_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET 0 +#define RTL8367C_MIRROR_TX_VLAN_LEAKY_MASK 0x1 + +#define RTL8367C_REG_OUTPUT_DROP_CFG 0x09DB +#define RTL8367C_ENABLE_PMASK_EXT_OFFSET 13 +#define RTL8367C_ENABLE_PMASK_EXT_MASK 0xE000 +#define RTL8367C_ENABLE_BC_OFFSET 12 +#define RTL8367C_ENABLE_BC_MASK 0x1000 +#define RTL8367C_ENABLE_MC_OFFSET 11 +#define RTL8367C_ENABLE_MC_MASK 0x800 +#define RTL8367C_ENABLE_UC_OFFSET 10 +#define RTL8367C_ENABLE_UC_MASK 0x400 +#define RTL8367C_ENABLE_PMASK_OFFSET 0 +#define RTL8367C_ENABLE_PMASK_MASK 0xFF + +#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT 0x09DC +#define RTL8367C_PORT10_ACTION_OFFSET 4 +#define RTL8367C_PORT10_ACTION_MASK 0x30 +#define RTL8367C_PORT9_ACTION_OFFSET 2 +#define RTL8367C_PORT9_ACTION_MASK 0xC +#define RTL8367C_PORT8_ACTION_OFFSET 0 +#define RTL8367C_PORT8_ACTION_MASK 0x3 + +#define RTL8367C_REG_RMK_CFG_SEL_CTRL 0x09DF +#define RTL8367C_RMK_1Q_CFG_SEL_OFFSET 2 +#define RTL8367C_RMK_1Q_CFG_SEL_MASK 0x4 +#define RTL8367C_RMK_DSCP_CFG_SEL_OFFSET 0 +#define RTL8367C_RMK_DSCP_CFG_SEL_MASK 0x3 + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 0x09E0 +#define RTL8367C_DSCP1_DSCP_OFFSET 8 +#define RTL8367C_DSCP1_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP0_DSCP_OFFSET 0 +#define RTL8367C_DSCP0_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL1 0x09E1 +#define RTL8367C_DSCP3_DSCP_OFFSET 8 +#define RTL8367C_DSCP3_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP2_DSCP_OFFSET 0 +#define RTL8367C_DSCP2_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL2 0x09E2 +#define RTL8367C_DSCP5_DSCP_OFFSET 8 +#define RTL8367C_DSCP5_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP4_DSCP_OFFSET 0 +#define RTL8367C_DSCP4_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL3 0x09E3 +#define RTL8367C_DSCP7_DSCP_OFFSET 8 +#define RTL8367C_DSCP7_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP6_DSCP_OFFSET 0 +#define RTL8367C_DSCP6_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL4 0x09E4 +#define RTL8367C_DSCP9_DSCP_OFFSET 8 +#define RTL8367C_DSCP9_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP8_DSCP_OFFSET 0 +#define RTL8367C_DSCP8_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL5 0x09E5 +#define RTL8367C_DSCP11_DSCP_OFFSET 8 +#define RTL8367C_DSCP11_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP10_DSCP_OFFSET 0 +#define RTL8367C_DSCP10_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL6 0x09E6 +#define RTL8367C_DSCP13_DSCP_OFFSET 8 +#define RTL8367C_DSCP13_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP12_DSCP_OFFSET 0 +#define RTL8367C_DSCP12_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL7 0x09E7 +#define RTL8367C_DSCP15_DSCP_OFFSET 8 +#define RTL8367C_DSCP15_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP14_DSCP_OFFSET 0 +#define RTL8367C_DSCP14_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL8 0x09E8 +#define RTL8367C_DSCP17_DSCP_OFFSET 8 +#define RTL8367C_DSCP17_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP16_DSCP_OFFSET 0 +#define RTL8367C_DSCP16_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL9 0x09E9 +#define RTL8367C_DSCP19_DSCP_OFFSET 8 +#define RTL8367C_DSCP19_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP18_DSCP_OFFSET 0 +#define RTL8367C_DSCP18_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL10 0x09EA +#define RTL8367C_DSCP21_DSCP_OFFSET 8 +#define RTL8367C_DSCP21_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP20_DSCP_OFFSET 0 +#define RTL8367C_DSCP20_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL11 0x09EB +#define RTL8367C_DSCP23_DSCP_OFFSET 8 +#define RTL8367C_DSCP23_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP22_DSCP_OFFSET 0 +#define RTL8367C_DSCP22_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL12 0x09EC +#define RTL8367C_DSCP25_DSCP_OFFSET 8 +#define RTL8367C_DSCP25_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP24_DSCP_OFFSET 0 +#define RTL8367C_DSCP24_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL13 0x09ED +#define RTL8367C_DSCP27_DSCP_OFFSET 8 +#define RTL8367C_DSCP27_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP26_DSCP_OFFSET 0 +#define RTL8367C_DSCP26_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL14 0x09EE +#define RTL8367C_DSCP29_DSCP_OFFSET 8 +#define RTL8367C_DSCP29_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP28_DSCP_OFFSET 0 +#define RTL8367C_DSCP28_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL15 0x09EF +#define RTL8367C_DSCP31_DSCP_OFFSET 8 +#define RTL8367C_DSCP31_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP30_DSCP_OFFSET 0 +#define RTL8367C_DSCP30_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL16 0x09F0 +#define RTL8367C_DSCP33_DSCP_OFFSET 8 +#define RTL8367C_DSCP33_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP32_DSCP_OFFSET 0 +#define RTL8367C_DSCP32_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL17 0x09F1 +#define RTL8367C_DSCP35_DSCP_OFFSET 8 +#define RTL8367C_DSCP35_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP34_DSCP_OFFSET 0 +#define RTL8367C_DSCP34_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL18 0x09F2 +#define RTL8367C_DSCP37_DSCP_OFFSET 8 +#define RTL8367C_DSCP37_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP36_DSCP_OFFSET 0 +#define RTL8367C_DSCP36_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL19 0x09F3 +#define RTL8367C_DSCP39_DSCP_OFFSET 8 +#define RTL8367C_DSCP39_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP38_DSCP_OFFSET 0 +#define RTL8367C_DSCP38_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL20 0x09F4 +#define RTL8367C_DSCP41_DSCP_OFFSET 8 +#define RTL8367C_DSCP41_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP40_DSCP_OFFSET 0 +#define RTL8367C_DSCP40_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL21 0x09F5 +#define RTL8367C_DSCP43_DSCP_OFFSET 8 +#define RTL8367C_DSCP43_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP42_DSCP_OFFSET 0 +#define RTL8367C_DSCP42_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL22 0x09F6 +#define RTL8367C_DSCP45_DSCP_OFFSET 8 +#define RTL8367C_DSCP45_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP44_DSCP_OFFSET 0 +#define RTL8367C_DSCP44_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL23 0x09F7 +#define RTL8367C_DSCP47_DSCP_OFFSET 8 +#define RTL8367C_DSCP47_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP46_DSCP_OFFSET 0 +#define RTL8367C_DSCP46_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL24 0x09F8 +#define RTL8367C_DSCP49_DSCP_OFFSET 8 +#define RTL8367C_DSCP49_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP48_DSCP_OFFSET 0 +#define RTL8367C_DSCP48_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL25 0x09F9 +#define RTL8367C_DSCP51_DSCP_OFFSET 8 +#define RTL8367C_DSCP51_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP50_DSCP_OFFSET 0 +#define RTL8367C_DSCP50_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL26 0x09FA +#define RTL8367C_DSCP53_DSCP_OFFSET 8 +#define RTL8367C_DSCP53_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP52_DSCP_OFFSET 0 +#define RTL8367C_DSCP52_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL27 0x09FB +#define RTL8367C_DSCP55_DSCP_OFFSET 8 +#define RTL8367C_DSCP55_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP54_DSCP_OFFSET 0 +#define RTL8367C_DSCP54_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL28 0x09FC +#define RTL8367C_DSCP57_DSCP_OFFSET 8 +#define RTL8367C_DSCP57_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP56_DSCP_OFFSET 0 +#define RTL8367C_DSCP56_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL29 0x09FD +#define RTL8367C_DSCP59_DSCP_OFFSET 8 +#define RTL8367C_DSCP59_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP58_DSCP_OFFSET 0 +#define RTL8367C_DSCP58_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL30 0x09FE +#define RTL8367C_DSCP61_DSCP_OFFSET 8 +#define RTL8367C_DSCP61_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP60_DSCP_OFFSET 0 +#define RTL8367C_DSCP60_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL31 0x09FF +#define RTL8367C_DSCP63_DSCP_OFFSET 8 +#define RTL8367C_DSCP63_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP62_DSCP_OFFSET 0 +#define RTL8367C_DSCP62_DSCP_MASK 0x3F + +/* (16'h0a00)l2_reg */ + +#define RTL8367C_REG_VLAN_MSTI0_CTRL0 0x0a00 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI0_CTRL1 0x0a01 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI1_CTRL0 0x0a02 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI1_CTRL1 0x0a03 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI2_CTRL0 0x0a04 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI2_CTRL1 0x0a05 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI3_CTRL0 0x0a06 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI3_CTRL1 0x0a07 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI4_CTRL0 0x0a08 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI4_CTRL1 0x0a09 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI5_CTRL0 0x0a0a +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI5_CTRL1 0x0a0b +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI6_CTRL0 0x0a0c +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI6_CTRL1 0x0a0d +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI7_CTRL0 0x0a0e +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI7_CTRL1 0x0a0f +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI8_CTRL0 0x0a10 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI8_CTRL1 0x0a11 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI9_CTRL0 0x0a12 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI9_CTRL1 0x0a13 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI10_CTRL0 0x0a14 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI10_CTRL1 0x0a15 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI11_CTRL0 0x0a16 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI11_CTRL1 0x0a17 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI12_CTRL0 0x0a18 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI12_CTRL1 0x0a19 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI13_CTRL0 0x0a1a +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI13_CTRL1 0x0a1b +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI14_CTRL0 0x0a1c +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI14_CTRL1 0x0a1d +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI15_CTRL0 0x0a1e +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI15_CTRL1 0x0a1f +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO 0x0a20 +#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT1_LEARN_LIMITNO 0x0a21 +#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT2_LEARN_LIMITNO 0x0a22 +#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT3_LEARN_LIMITNO 0x0a23 +#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT4_LEARN_LIMITNO 0x0a24 +#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT5_LEARN_LIMITNO 0x0a25 +#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT6_LEARN_LIMITNO 0x0a26 +#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT7_LEARN_LIMITNO 0x0a27 +#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_SYS_LEARN_LIMITNO 0x0a28 +#define RTL8367C_LUT_SYS_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_SYS_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL 0x0a29 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_OFFSET 12 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK 0x7000 +#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_OFFSET 10 +#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK 0xC00 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_OFFSET 0 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK 0xFF + +#define RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO 0x0a2a +#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT9_LEARN_LIMITNO 0x0a2b +#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT10_LEARN_LIMITNO 0x0a2c +#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_CFG 0x0a30 +#define RTL8367C_AGE_SPEED_OFFSET 8 +#define RTL8367C_AGE_SPEED_MASK 0x300 +#define RTL8367C_BCAM_DISABLE_OFFSET 6 +#define RTL8367C_BCAM_DISABLE_MASK 0x40 +#define RTL8367C_LINKDOWN_AGEOUT_OFFSET 5 +#define RTL8367C_LINKDOWN_AGEOUT_MASK 0x20 +#define RTL8367C_LUT_IPMC_HASH_OFFSET 4 +#define RTL8367C_LUT_IPMC_HASH_MASK 0x10 +#define RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET 3 +#define RTL8367C_LUT_IPMC_LOOKUP_OP_MASK 0x8 +#define RTL8367C_AGE_TIMER_OFFSET 0 +#define RTL8367C_AGE_TIMER_MASK 0x7 + +#define RTL8367C_REG_LUT_AGEOUT_CTRL 0x0a31 +#define RTL8367C_LUT_AGEOUT_CTRL_OFFSET 0 +#define RTL8367C_LUT_AGEOUT_CTRL_MASK 0x7FF + +#define RTL8367C_REG_PORT_EFID_CTRL0 0x0a32 +#define RTL8367C_PORT3_EFID_OFFSET 12 +#define RTL8367C_PORT3_EFID_MASK 0x7000 +#define RTL8367C_PORT2_EFID_OFFSET 8 +#define RTL8367C_PORT2_EFID_MASK 0x700 +#define RTL8367C_PORT1_EFID_OFFSET 4 +#define RTL8367C_PORT1_EFID_MASK 0x70 +#define RTL8367C_PORT0_EFID_OFFSET 0 +#define RTL8367C_PORT0_EFID_MASK 0x7 + +#define RTL8367C_REG_PORT_EFID_CTRL1 0x0a33 +#define RTL8367C_PORT7_EFID_OFFSET 12 +#define RTL8367C_PORT7_EFID_MASK 0x7000 +#define RTL8367C_PORT6_EFID_OFFSET 8 +#define RTL8367C_PORT6_EFID_MASK 0x700 +#define RTL8367C_PORT5_EFID_OFFSET 4 +#define RTL8367C_PORT5_EFID_MASK 0x70 +#define RTL8367C_PORT4_EFID_OFFSET 0 +#define RTL8367C_PORT4_EFID_MASK 0x7 + +#define RTL8367C_REG_PORT_EFID_CTRL2 0x0a34 +#define RTL8367C_PORT10_EFID_OFFSET 8 +#define RTL8367C_PORT10_EFID_MASK 0x700 +#define RTL8367C_PORT9_EFID_OFFSET 4 +#define RTL8367C_PORT9_EFID_MASK 0x70 +#define RTL8367C_PORT8_EFID_OFFSET 0 +#define RTL8367C_PORT8_EFID_MASK 0x7 + +#define RTL8367C_REG_FORCE_FLUSH1 0x0a35 +#define RTL8367C_BUSY_STATUS1_OFFSET 3 +#define RTL8367C_BUSY_STATUS1_MASK 0x38 +#define RTL8367C_PORTMASK1_OFFSET 0 +#define RTL8367C_PORTMASK1_MASK 0x7 + +#define RTL8367C_REG_FORCE_FLUSH 0x0a36 +#define RTL8367C_BUSY_STATUS_OFFSET 8 +#define RTL8367C_BUSY_STATUS_MASK 0xFF00 +#define RTL8367C_FORCE_FLUSH_PORTMASK_OFFSET 0 +#define RTL8367C_FORCE_FLUSH_PORTMASK_MASK 0xFF + +#define RTL8367C_REG_L2_FLUSH_CTRL1 0x0a37 +#define RTL8367C_LUT_FLUSH_FID_OFFSET 12 +#define RTL8367C_LUT_FLUSH_FID_MASK 0xF000 +#define RTL8367C_LUT_FLUSH_VID_OFFSET 0 +#define RTL8367C_LUT_FLUSH_VID_MASK 0xFFF + +#define RTL8367C_REG_L2_FLUSH_CTRL2 0x0a38 +#define RTL8367C_LUT_FLUSH_TYPE_OFFSET 2 +#define RTL8367C_LUT_FLUSH_TYPE_MASK 0x4 +#define RTL8367C_LUT_FLUSH_MODE_OFFSET 0 +#define RTL8367C_LUT_FLUSH_MODE_MASK 0x3 + +#define RTL8367C_REG_L2_FLUSH_CTRL3 0x0a39 +#define RTL8367C_L2_FLUSH_CTRL3_OFFSET 0 +#define RTL8367C_L2_FLUSH_CTRL3_MASK 0x1 + +#define RTL8367C_REG_LUT_CFG2 0x0a3a +#define RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET 1 +#define RTL8367C_LUT_IPMC_FWD_RPORT_MASK 0x2 +#define RTL8367C_LUT_IPMC_VID_HASH_OFFSET 0 +#define RTL8367C_LUT_IPMC_VID_HASH_MASK 0x1 + +#define RTL8367C_REG_FLUSH_STATUS 0x0a3f +#define RTL8367C_FLUSH_STATUS_OFFSET 0 +#define RTL8367C_FLUSH_STATUS_MASK 0x1 + +#define RTL8367C_REG_STORM_BCAST 0x0a40 +#define RTL8367C_STORM_BCAST_OFFSET 0 +#define RTL8367C_STORM_BCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_MCAST 0x0a41 +#define RTL8367C_STORM_MCAST_OFFSET 0 +#define RTL8367C_STORM_MCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_UNKOWN_UCAST 0x0a42 +#define RTL8367C_STORM_UNKOWN_UCAST_OFFSET 0 +#define RTL8367C_STORM_UNKOWN_UCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_UNKOWN_MCAST 0x0a43 +#define RTL8367C_STORM_UNKOWN_MCAST_OFFSET 0 +#define RTL8367C_STORM_UNKOWN_MCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL0 0x0a44 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL1 0x0a45 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL2 0x0a46 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL3 0x0a47 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL4 0x0a48 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL5 0x0a49 +#define RTL8367C_STORM_BCAST_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL0 0x0a4c +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL1 0x0a4d +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL2 0x0a4e +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL3 0x0a4f +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL4 0x0a50 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL5 0x0a51 +#define RTL8367C_STORM_MCAST_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL0 0x0a54 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL1 0x0a55 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL2 0x0a56 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL3 0x0a57 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL4 0x0a58 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL5 0x0a59 +#define RTL8367C_STORM_UNDA_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL0 0x0a5c +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL1 0x0a5d +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL2 0x0a5e +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL3 0x0a5f +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_EXT_CFG 0x0a60 +#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_OFFSET 14 +#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK 0x4000 +#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET 13 +#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_MASK 0x2000 +#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET 12 +#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_MASK 0x1000 +#define RTL8367C_STORM_MCAST_EXT_EN_OFFSET 11 +#define RTL8367C_STORM_MCAST_EXT_EN_MASK 0x800 +#define RTL8367C_STORM_BCAST_EXT_EN_OFFSET 10 +#define RTL8367C_STORM_BCAST_EXT_EN_MASK 0x400 +#define RTL8367C_STORM_EXT_EN_PORTMASK_OFFSET 0 +#define RTL8367C_STORM_EXT_EN_PORTMASK_MASK 0x3FF + +#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG0 0x0a61 +#define RTL8367C_MC_STORM_EXT_METERIDX_OFFSET 8 +#define RTL8367C_MC_STORM_EXT_METERIDX_MASK 0x3F00 +#define RTL8367C_BC_STORM_EXT_METERIDX_OFFSET 0 +#define RTL8367C_BC_STORM_EXT_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG1 0x0a62 +#define RTL8367C_UNMC_STORM_EXT_METERIDX_OFFSET 8 +#define RTL8367C_UNMC_STORM_EXT_METERIDX_MASK 0x3F00 +#define RTL8367C_UNUC_STORM_EXT_METERIDX_OFFSET 0 +#define RTL8367C_UNUC_STORM_EXT_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL4 0x0a63 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL5 0x0a64 +#define RTL8367C_STORM_UNMC_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_OAM_PARSER_CTRL0 0x0a70 +#define RTL8367C_PORT7_PARACT_OFFSET 14 +#define RTL8367C_PORT7_PARACT_MASK 0xC000 +#define RTL8367C_PORT6_PARACT_OFFSET 12 +#define RTL8367C_PORT6_PARACT_MASK 0x3000 +#define RTL8367C_PORT5_PARACT_OFFSET 10 +#define RTL8367C_PORT5_PARACT_MASK 0xC00 +#define RTL8367C_PORT4_PARACT_OFFSET 8 +#define RTL8367C_PORT4_PARACT_MASK 0x300 +#define RTL8367C_PORT3_PARACT_OFFSET 6 +#define RTL8367C_PORT3_PARACT_MASK 0xC0 +#define RTL8367C_PORT2_PARACT_OFFSET 4 +#define RTL8367C_PORT2_PARACT_MASK 0x30 +#define RTL8367C_PORT1_PARACT_OFFSET 2 +#define RTL8367C_PORT1_PARACT_MASK 0xC +#define RTL8367C_PORT0_PARACT_OFFSET 0 +#define RTL8367C_PORT0_PARACT_MASK 0x3 + +#define RTL8367C_REG_OAM_PARSER_CTRL1 0x0a71 +#define RTL8367C_PORT10_PARACT_OFFSET 4 +#define RTL8367C_PORT10_PARACT_MASK 0x30 +#define RTL8367C_PORT9_PARACT_OFFSET 2 +#define RTL8367C_PORT9_PARACT_MASK 0xC +#define RTL8367C_PORT8_PARACT_OFFSET 0 +#define RTL8367C_PORT8_PARACT_MASK 0x3 + +#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 0x0a72 +#define RTL8367C_PORT7_MULACT_OFFSET 14 +#define RTL8367C_PORT7_MULACT_MASK 0xC000 +#define RTL8367C_PORT6_MULACT_OFFSET 12 +#define RTL8367C_PORT6_MULACT_MASK 0x3000 +#define RTL8367C_PORT5_MULACT_OFFSET 10 +#define RTL8367C_PORT5_MULACT_MASK 0xC00 +#define RTL8367C_PORT4_MULACT_OFFSET 8 +#define RTL8367C_PORT4_MULACT_MASK 0x300 +#define RTL8367C_PORT3_MULACT_OFFSET 6 +#define RTL8367C_PORT3_MULACT_MASK 0xC0 +#define RTL8367C_PORT2_MULACT_OFFSET 4 +#define RTL8367C_PORT2_MULACT_MASK 0x30 +#define RTL8367C_PORT1_MULACT_OFFSET 2 +#define RTL8367C_PORT1_MULACT_MASK 0xC +#define RTL8367C_PORT0_MULACT_OFFSET 0 +#define RTL8367C_PORT0_MULACT_MASK 0x3 + +#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL1 0x0a73 +#define RTL8367C_PORT10_MULACT_OFFSET 4 +#define RTL8367C_PORT10_MULACT_MASK 0x30 +#define RTL8367C_PORT9_MULACT_OFFSET 2 +#define RTL8367C_PORT9_MULACT_MASK 0xC +#define RTL8367C_PORT8_MULACT_OFFSET 0 +#define RTL8367C_PORT8_MULACT_MASK 0x3 + +#define RTL8367C_REG_OAM_CTRL 0x0a74 +#define RTL8367C_OAM_CTRL_OFFSET 0 +#define RTL8367C_OAM_CTRL_MASK 0x1 + +#define RTL8367C_REG_DOT1X_PORT_ENABLE 0x0a80 +#define RTL8367C_DOT1X_PORT_ENABLE_OFFSET 0 +#define RTL8367C_DOT1X_PORT_ENABLE_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_MAC_ENABLE 0x0a81 +#define RTL8367C_DOT1X_MAC_ENABLE_OFFSET 0 +#define RTL8367C_DOT1X_MAC_ENABLE_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_PORT_AUTH 0x0a82 +#define RTL8367C_DOT1X_PORT_AUTH_OFFSET 0 +#define RTL8367C_DOT1X_PORT_AUTH_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_PORT_OPDIR 0x0a83 +#define RTL8367C_DOT1X_PORT_OPDIR_OFFSET 0 +#define RTL8367C_DOT1X_PORT_OPDIR_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 0x0a84 +#define RTL8367C_DOT1X_PORT7_UNAUTHBH_OFFSET 14 +#define RTL8367C_DOT1X_PORT7_UNAUTHBH_MASK 0xC000 +#define RTL8367C_DOT1X_PORT6_UNAUTHBH_OFFSET 12 +#define RTL8367C_DOT1X_PORT6_UNAUTHBH_MASK 0x3000 +#define RTL8367C_DOT1X_PORT5_UNAUTHBH_OFFSET 10 +#define RTL8367C_DOT1X_PORT5_UNAUTHBH_MASK 0xC00 +#define RTL8367C_DOT1X_PORT4_UNAUTHBH_OFFSET 8 +#define RTL8367C_DOT1X_PORT4_UNAUTHBH_MASK 0x300 +#define RTL8367C_DOT1X_PORT3_UNAUTHBH_OFFSET 6 +#define RTL8367C_DOT1X_PORT3_UNAUTHBH_MASK 0xC0 +#define RTL8367C_DOT1X_PORT2_UNAUTHBH_OFFSET 4 +#define RTL8367C_DOT1X_PORT2_UNAUTHBH_MASK 0x30 +#define RTL8367C_DOT1X_PORT1_UNAUTHBH_OFFSET 2 +#define RTL8367C_DOT1X_PORT1_UNAUTHBH_MASK 0xC +#define RTL8367C_DOT1X_PORT0_UNAUTHBH_OFFSET 0 +#define RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK 0x3 + +#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W1 0x0a85 +#define RTL8367C_DOT1X_PORT10_UNAUTHBH_OFFSET 4 +#define RTL8367C_DOT1X_PORT10_UNAUTHBH_MASK 0x30 +#define RTL8367C_DOT1X_PORT9_UNAUTHBH_OFFSET 2 +#define RTL8367C_DOT1X_PORT9_UNAUTHBH_MASK 0xC +#define RTL8367C_DOT1X_PORT8_UNAUTHBH_OFFSET 0 +#define RTL8367C_DOT1X_PORT8_UNAUTHBH_MASK 0x3 + +#define RTL8367C_REG_DOT1X_CFG 0x0a86 +#define RTL8367C_DOT1X_GVOPDIR_OFFSET 6 +#define RTL8367C_DOT1X_GVOPDIR_MASK 0x40 +#define RTL8367C_DOT1X_MAC_OPDIR_OFFSET 5 +#define RTL8367C_DOT1X_MAC_OPDIR_MASK 0x20 +#define RTL8367C_DOT1X_GVIDX_OFFSET 0 +#define RTL8367C_DOT1X_GVIDX_MASK 0x1F + +#define RTL8367C_REG_L2_LRN_CNT_CTRL0 0x0a87 +#define RTL8367C_L2_LRN_CNT_CTRL0_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL0_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL1 0x0a88 +#define RTL8367C_L2_LRN_CNT_CTRL1_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL1_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL2 0x0a89 +#define RTL8367C_L2_LRN_CNT_CTRL2_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL3 0x0a8a +#define RTL8367C_L2_LRN_CNT_CTRL3_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL4 0x0a8b +#define RTL8367C_L2_LRN_CNT_CTRL4_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL4_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL5 0x0a8c +#define RTL8367C_L2_LRN_CNT_CTRL5_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL5_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL6 0x0a8d +#define RTL8367C_L2_LRN_CNT_CTRL6_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL6_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL7 0x0a8e +#define RTL8367C_L2_LRN_CNT_CTRL7_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL7_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL8 0x0a8f +#define RTL8367C_L2_LRN_CNT_CTRL8_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL8_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL9 0x0a90 +#define RTL8367C_L2_LRN_CNT_CTRL9_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL9_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL10 0x0a92 +#define RTL8367C_L2_LRN_CNT_CTRL10_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL10_MASK 0x1FFF + +#define RTL8367C_REG_LUT_LRN_UNDER_STATUS 0x0a91 +#define RTL8367C_LUT_LRN_UNDER_STATUS_OFFSET 0 +#define RTL8367C_LUT_LRN_UNDER_STATUS_MASK 0x7FF + +#define RTL8367C_REG_L2_SA_MOVING_FORBID 0x0aa0 +#define RTL8367C_L2_SA_MOVING_FORBID_OFFSET 0 +#define RTL8367C_L2_SA_MOVING_FORBID_MASK 0x7FF + +#define RTL8367C_REG_DRPORT_LEARN_CTRL 0x0aa1 +#define RTL8367C_FORBID1_OFFSET 1 +#define RTL8367C_FORBID1_MASK 0x2 +#define RTL8367C_FORBID0_OFFSET 0 +#define RTL8367C_FORBID0_MASK 0x1 + +#define RTL8367C_REG_L2_DUMMY02 0x0aa2 + +#define RTL8367C_REG_L2_DUMMY03 0x0aa3 + +#define RTL8367C_REG_L2_DUMMY04 0x0aa4 + +#define RTL8367C_REG_L2_DUMMY05 0x0aa5 + +#define RTL8367C_REG_L2_DUMMY06 0x0aa6 + +#define RTL8367C_REG_L2_DUMMY07 0x0aa7 + +#define RTL8367C_REG_IPMC_GROUP_PMSK_00 0x0AC0 +#define RTL8367C_IPMC_GROUP_PMSK_00_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_00_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_01 0x0AC1 +#define RTL8367C_IPMC_GROUP_PMSK_01_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_01_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_02 0x0AC2 +#define RTL8367C_IPMC_GROUP_PMSK_02_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_02_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_03 0x0AC3 +#define RTL8367C_IPMC_GROUP_PMSK_03_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_03_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_04 0x0AC4 +#define RTL8367C_IPMC_GROUP_PMSK_04_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_04_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_05 0x0AC5 +#define RTL8367C_IPMC_GROUP_PMSK_05_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_05_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_06 0x0AC6 +#define RTL8367C_IPMC_GROUP_PMSK_06_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_06_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_07 0x0AC7 +#define RTL8367C_IPMC_GROUP_PMSK_07_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_07_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_08 0x0AC8 +#define RTL8367C_IPMC_GROUP_PMSK_08_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_08_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_09 0x0AC9 +#define RTL8367C_IPMC_GROUP_PMSK_09_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_09_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_10 0x0ACA +#define RTL8367C_IPMC_GROUP_PMSK_10_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_10_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_11 0x0ACB +#define RTL8367C_IPMC_GROUP_PMSK_11_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_11_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_12 0x0ACC +#define RTL8367C_IPMC_GROUP_PMSK_12_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_12_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_13 0x0ACD +#define RTL8367C_IPMC_GROUP_PMSK_13_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_13_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_14 0x0ACE +#define RTL8367C_IPMC_GROUP_PMSK_14_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_14_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_15 0x0ACF +#define RTL8367C_IPMC_GROUP_PMSK_15_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_15_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_16 0x0AD0 +#define RTL8367C_IPMC_GROUP_PMSK_16_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_16_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_17 0x0AD1 +#define RTL8367C_IPMC_GROUP_PMSK_17_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_17_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_18 0x0AD2 +#define RTL8367C_IPMC_GROUP_PMSK_18_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_18_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_19 0x0AD3 +#define RTL8367C_IPMC_GROUP_PMSK_19_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_19_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_20 0x0AD4 +#define RTL8367C_IPMC_GROUP_PMSK_20_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_20_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_21 0x0AD5 +#define RTL8367C_IPMC_GROUP_PMSK_21_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_21_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_22 0x0AD6 +#define RTL8367C_IPMC_GROUP_PMSK_22_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_22_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_23 0x0AD7 +#define RTL8367C_IPMC_GROUP_PMSK_23_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_23_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_24 0x0AD8 +#define RTL8367C_IPMC_GROUP_PMSK_24_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_24_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_25 0x0AD9 +#define RTL8367C_IPMC_GROUP_PMSK_25_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_25_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_26 0x0ADA +#define RTL8367C_IPMC_GROUP_PMSK_26_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_26_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_27 0x0ADB +#define RTL8367C_IPMC_GROUP_PMSK_27_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_27_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_28 0x0ADC +#define RTL8367C_IPMC_GROUP_PMSK_28_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_28_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_29 0x0ADD +#define RTL8367C_IPMC_GROUP_PMSK_29_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_29_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_30 0x0ADE +#define RTL8367C_IPMC_GROUP_PMSK_30_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_30_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_31 0x0ADF +#define RTL8367C_IPMC_GROUP_PMSK_31_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_31_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_32 0x0AE0 +#define RTL8367C_IPMC_GROUP_PMSK_32_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_32_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_33 0x0AE1 +#define RTL8367C_IPMC_GROUP_PMSK_33_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_33_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_34 0x0AE2 +#define RTL8367C_IPMC_GROUP_PMSK_34_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_34_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_35 0x0AE3 +#define RTL8367C_IPMC_GROUP_PMSK_35_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_35_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_36 0x0AE4 +#define RTL8367C_IPMC_GROUP_PMSK_36_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_36_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_37 0x0AE5 +#define RTL8367C_IPMC_GROUP_PMSK_37_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_37_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_38 0x0AE6 +#define RTL8367C_IPMC_GROUP_PMSK_38_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_38_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_39 0x0AE7 +#define RTL8367C_IPMC_GROUP_PMSK_39_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_39_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_40 0x0AE8 +#define RTL8367C_IPMC_GROUP_PMSK_40_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_40_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_41 0x0AE9 +#define RTL8367C_IPMC_GROUP_PMSK_41_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_41_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_42 0x0AEA +#define RTL8367C_IPMC_GROUP_PMSK_42_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_42_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_43 0x0AEB +#define RTL8367C_IPMC_GROUP_PMSK_43_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_43_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_44 0x0AEC +#define RTL8367C_IPMC_GROUP_PMSK_44_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_44_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_45 0x0AED +#define RTL8367C_IPMC_GROUP_PMSK_45_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_45_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_46 0x0AEE +#define RTL8367C_IPMC_GROUP_PMSK_46_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_46_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_47 0x0AEF +#define RTL8367C_IPMC_GROUP_PMSK_47_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_47_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_48 0x0AF0 +#define RTL8367C_IPMC_GROUP_PMSK_48_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_48_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_49 0x0AF1 +#define RTL8367C_IPMC_GROUP_PMSK_49_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_49_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_50 0x0AF2 +#define RTL8367C_IPMC_GROUP_PMSK_50_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_50_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_51 0x0AF3 +#define RTL8367C_IPMC_GROUP_PMSK_51_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_51_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_52 0x0AF4 +#define RTL8367C_IPMC_GROUP_PMSK_52_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_52_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_53 0x0AF5 +#define RTL8367C_IPMC_GROUP_PMSK_53_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_53_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_54 0x0AF6 +#define RTL8367C_IPMC_GROUP_PMSK_54_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_54_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_55 0x0AF7 +#define RTL8367C_IPMC_GROUP_PMSK_55_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_55_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_56 0x0AF8 +#define RTL8367C_IPMC_GROUP_PMSK_56_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_56_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_57 0x0AF9 +#define RTL8367C_IPMC_GROUP_PMSK_57_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_57_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_58 0x0AFA +#define RTL8367C_IPMC_GROUP_PMSK_58_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_58_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_59 0x0AFB +#define RTL8367C_IPMC_GROUP_PMSK_59_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_59_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_60 0x0AFC +#define RTL8367C_IPMC_GROUP_PMSK_60_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_60_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_61 0x0AFD +#define RTL8367C_IPMC_GROUP_PMSK_61_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_61_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_62 0x0AFE +#define RTL8367C_IPMC_GROUP_PMSK_62_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_62_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_63 0x0AFF +#define RTL8367C_IPMC_GROUP_PMSK_63_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_63_MASK 0x7FF + +/* (16'h0b00)mltvlan_reg */ + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 0x0b00 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL1 0x0b01 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL2 0x0b02 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL3 0x0b03 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL4 0x0b04 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL0 0x0b05 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL1 0x0b06 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL2 0x0b07 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL3 0x0b08 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL4 0x0b09 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL0 0x0b0a +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL1 0x0b0b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL2 0x0b0c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL3 0x0b0d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL4 0x0b0e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL0 0x0b0f +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL1 0x0b10 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL2 0x0b11 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL3 0x0b12 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL4 0x0b13 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL0 0x0b14 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL1 0x0b15 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL2 0x0b16 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL3 0x0b17 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL4 0x0b18 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL0 0x0b19 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL1 0x0b1a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL2 0x0b1b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL3 0x0b1c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL4 0x0b1d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL0 0x0b1e +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL1 0x0b1f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL2 0x0b20 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL3 0x0b21 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL4 0x0b22 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL0 0x0b23 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL1 0x0b24 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL2 0x0b25 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL3 0x0b26 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL4 0x0b27 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL0 0x0b28 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL1 0x0b29 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL2 0x0b2a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL3 0x0b2b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL4 0x0b2c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL0 0x0b2d +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL1 0x0b2e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL2 0x0b2f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL3 0x0b30 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL4 0x0b31 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL0 0x0b32 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL1 0x0b33 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL2 0x0b34 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL3 0x0b35 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL4 0x0b36 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL0 0x0b37 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL1 0x0b38 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL2 0x0b39 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL3 0x0b3a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL4 0x0b3b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL0 0x0b3c +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL1 0x0b3d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL2 0x0b3e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL3 0x0b3f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL4 0x0b40 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL0 0x0b41 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL1 0x0b42 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL2 0x0b43 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL3 0x0b44 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL4 0x0b45 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL0 0x0b46 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL1 0x0b47 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL2 0x0b48 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL3 0x0b49 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL4 0x0b4a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL0 0x0b4b +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL1 0x0b4c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL2 0x0b4d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL3 0x0b4e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL4 0x0b4f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL0 0x0b50 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL1 0x0b51 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL2 0x0b52 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL3 0x0b53 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL4 0x0b54 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL0 0x0b55 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL1 0x0b56 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL2 0x0b57 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL3 0x0b58 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL4 0x0b59 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL0 0x0b5a +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL1 0x0b5b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL2 0x0b5c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL3 0x0b5d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL4 0x0b5e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL0 0x0b5f +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL1 0x0b60 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL2 0x0b61 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL3 0x0b62 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL4 0x0b63 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL0 0x0b64 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL1 0x0b65 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL2 0x0b66 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL3 0x0b67 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL4 0x0b68 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL0 0x0b69 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL1 0x0b6a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL2 0x0b6b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL3 0x0b6c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL4 0x0b6d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL0 0x0b6e +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL1 0x0b6f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL2 0x0b70 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL3 0x0b71 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL4 0x0b72 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL0 0x0b73 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL1 0x0b74 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL2 0x0b75 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL3 0x0b76 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL4 0x0b77 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL0 0x0b78 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL1 0x0b79 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL2 0x0b7a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL3 0x0b7b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL4 0x0b7c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL0 0x0b7d +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL1 0x0b7e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL2 0x0b7f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL3 0x0b80 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL4 0x0b81 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL0 0x0b82 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL1 0x0b83 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL2 0x0b84 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL3 0x0b85 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL4 0x0b86 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL0 0x0b87 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL1 0x0b88 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL2 0x0b89 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL3 0x0b8a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL4 0x0b8b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL0 0x0b8c +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL1 0x0b8d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL2 0x0b8e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL3 0x0b8f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL4 0x0b90 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL0 0x0b91 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL1 0x0b92 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL2 0x0b93 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL3 0x0b94 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL4 0x0b95 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL0 0x0b96 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL1 0x0b97 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL2 0x0b98 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL3 0x0b99 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL4 0x0b9a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL0 0x0b9b +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL1 0x0b9c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL2 0x0b9d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL3 0x0b9e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL4 0x0b9f + +#define RTL8367C_REG_MLTVLAN_DUMMY_0 0x0ba0 + +#define RTL8367C_REG_MLTVLAN_DUMMY_1 0x0ba1 + +#define RTL8367C_REG_MLTVLAN_DUMMY_2 0x0ba2 + +#define RTL8367C_REG_MLTVLAN_DUMMY_3 0x0ba3 + +#define RTL8367C_REG_MLTVLAN_DUMMY_4 0x0ba4 + +#define RTL8367C_REG_MLTVLAN_DUMMY_5 0x0ba5 + +#define RTL8367C_REG_MLTVLAN_DUMMY_6 0x0ba6 + +#define RTL8367C_REG_MLTVLAN_DUMMY_7 0x0ba7 + +/* (16'h0c00)svlan_reg */ + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 0x0c01 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL2 0x0c02 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL3 0x0c03 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL1 0x0c04 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL2 0x0c05 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL3 0x0c06 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL1 0x0c07 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL2 0x0c08 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL3 0x0c09 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL1 0x0c0a +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL2 0x0c0b +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL3 0x0c0c +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL1 0x0c0d +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL2 0x0c0e +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL3 0x0c0f +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL1 0x0c10 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL2 0x0c11 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL3 0x0c12 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL1 0x0c13 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL2 0x0c14 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL3 0x0c15 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL1 0x0c16 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL2 0x0c17 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL3 0x0c18 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL1 0x0c19 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL2 0x0c1a +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL3 0x0c1b +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL1 0x0c1c +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL2 0x0c1d +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL3 0x0c1e +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL1 0x0c1f +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL2 0x0c20 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL3 0x0c21 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL1 0x0c22 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL2 0x0c23 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL3 0x0c24 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL1 0x0c25 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL2 0x0c26 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL3 0x0c27 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL1 0x0c28 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL2 0x0c29 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL3 0x0c2a +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL1 0x0c2b +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL2 0x0c2c +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL3 0x0c2d +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL1 0x0c2e +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL2 0x0c2f +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL3 0x0c30 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL1 0x0c31 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL2 0x0c32 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL3 0x0c33 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL1 0x0c34 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL2 0x0c35 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL3 0x0c36 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL1 0x0c37 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL2 0x0c38 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL3 0x0c39 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL1 0x0c3a +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL2 0x0c3b +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL3 0x0c3c +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL1 0x0c3d +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL2 0x0c3e +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL3 0x0c3f +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL1 0x0c40 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL2 0x0c41 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL3 0x0c42 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL1 0x0c43 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL2 0x0c44 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL3 0x0c45 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL1 0x0c46 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL2 0x0c47 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL3 0x0c48 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL1 0x0c49 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL2 0x0c4a +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL3 0x0c4b +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL1 0x0c4c +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL2 0x0c4d +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL3 0x0c4e +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL1 0x0c4f +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL2 0x0c50 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL3 0x0c51 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL1 0x0c52 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL2 0x0c53 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL3 0x0c54 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL1 0x0c55 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL2 0x0c56 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL3 0x0c57 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL1 0x0c58 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL2 0x0c59 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL3 0x0c5a +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL1 0x0c5b +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL2 0x0c5c +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL3 0x0c5d +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL1 0x0c5e +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL2 0x0c5f +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL3 0x0c60 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL1 0x0c61 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL2 0x0c62 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL3 0x0c63 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL1 0x0c64 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL2 0x0c65 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL3 0x0c66 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL1 0x0c67 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL2 0x0c68 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL3 0x0c69 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL1 0x0c6a +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL2 0x0c6b +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL3 0x0c6c +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL1 0x0c6d +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL2 0x0c6e +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL3 0x0c6f +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL1 0x0c70 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL2 0x0c71 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL3 0x0c72 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL1 0x0c73 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL2 0x0c74 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL3 0x0c75 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL1 0x0c76 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL2 0x0c77 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL3 0x0c78 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL1 0x0c79 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL2 0x0c7a +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL3 0x0c7b +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL1 0x0c7c +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL2 0x0c7d +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL3 0x0c7e +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL1 0x0c7f +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL2 0x0c80 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL3 0x0c81 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL1 0x0c82 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL2 0x0c83 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL3 0x0c84 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL1 0x0c85 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL2 0x0c86 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL3 0x0c87 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL1 0x0c88 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL2 0x0c89 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL3 0x0c8a +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL1 0x0c8b +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL2 0x0c8c +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL3 0x0c8d +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL1 0x0c8e +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL2 0x0c8f +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL3 0x0c90 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL1 0x0c91 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL2 0x0c92 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL3 0x0c93 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL1 0x0c94 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL2 0x0c95 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL3 0x0c96 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL1 0x0c97 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL2 0x0c98 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL3 0x0c99 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL1 0x0c9a +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL2 0x0c9b +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL3 0x0c9c +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL1 0x0c9d +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL2 0x0c9e +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL3 0x0c9f +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL1 0x0ca0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL2 0x0ca1 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL3 0x0ca2 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL1 0x0ca3 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL2 0x0ca4 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL3 0x0ca5 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL1 0x0ca6 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL2 0x0ca7 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL3 0x0ca8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL1 0x0ca9 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL2 0x0caa +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL3 0x0cab +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL1 0x0cac +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL2 0x0cad +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL3 0x0cae +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL1 0x0caf +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL2 0x0cb0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL3 0x0cb1 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL1 0x0cb2 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL2 0x0cb3 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL3 0x0cb4 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL1 0x0cb5 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL2 0x0cb6 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL3 0x0cb7 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL1 0x0cb8 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL2 0x0cb9 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL3 0x0cba +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL1 0x0cbb +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL2 0x0cbc +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL3 0x0cbd +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL1 0x0cbe +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL2 0x0cbf +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL3 0x0cc0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4 0x0cc1 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL4 0x0cc2 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL4 0x0cc3 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL4 0x0cc4 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL4 0x0cc5 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL4 0x0cc6 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL4 0x0cc7 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL4 0x0cc8 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL4 0x0cc9 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL4 0x0cca +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL4 0x0ccb +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL4 0x0ccc +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL4 0x0ccd +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL4 0x0cce +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL4 0x0ccf +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL4 0x0cd0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL4 0x0cd1 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL4 0x0cd2 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL4 0x0cd3 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL4 0x0cd4 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL4 0x0cd5 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL4 0x0cd6 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL4 0x0cd7 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL4 0x0cd8 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL4 0x0cd9 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL4 0x0cda +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL4 0x0cdb +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL4 0x0cdc +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL4 0x0cdd +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL4 0x0cde +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL4 0x0cdf +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL4 0x0ce0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL4 0x0ce1 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL4 0x0ce2 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL4 0x0ce3 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL4 0x0ce4 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL4 0x0ce5 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL4 0x0ce6 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL4 0x0ce7 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL4 0x0ce8 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL4 0x0ce9 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL4 0x0cea +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL4 0x0ceb +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL4 0x0cec +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL4 0x0ced +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL4 0x0cee +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL4 0x0cef +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL4 0x0cf0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL4 0x0cf1 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL4 0x0cf2 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL4 0x0cf3 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL4 0x0cf4 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL4 0x0cf5 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL4 0x0cf6 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL4 0x0cf7 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL4 0x0cf8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL4 0x0cf9 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL4 0x0cfa +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL4 0x0cfb +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL4 0x0cfc +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL4 0x0cfd +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL4 0x0cfe +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL4 0x0cff +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL0 0x0d00 +#define RTL8367C_SVLAN_C2SCFG0_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG0_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL1 0x0d01 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL2 0x0d02 +#define RTL8367C_SVLAN_C2SCFG0_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG0_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL0 0x0d03 +#define RTL8367C_SVLAN_C2SCFG1_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG1_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL1 0x0d04 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL2 0x0d05 +#define RTL8367C_SVLAN_C2SCFG1_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG1_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL0 0x0d06 +#define RTL8367C_SVLAN_C2SCFG2_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG2_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL1 0x0d07 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL2 0x0d08 +#define RTL8367C_SVLAN_C2SCFG2_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG2_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL0 0x0d09 +#define RTL8367C_SVLAN_C2SCFG3_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG3_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL1 0x0d0a +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL2 0x0d0b +#define RTL8367C_SVLAN_C2SCFG3_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG3_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL0 0x0d0c +#define RTL8367C_SVLAN_C2SCFG4_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG4_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL1 0x0d0d +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL2 0x0d0e +#define RTL8367C_SVLAN_C2SCFG4_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG4_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL0 0x0d0f +#define RTL8367C_SVLAN_C2SCFG5_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG5_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL1 0x0d10 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL2 0x0d11 +#define RTL8367C_SVLAN_C2SCFG5_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG5_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL0 0x0d12 +#define RTL8367C_SVLAN_C2SCFG6_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG6_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL1 0x0d13 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL2 0x0d14 +#define RTL8367C_SVLAN_C2SCFG6_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG6_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL0 0x0d15 +#define RTL8367C_SVLAN_C2SCFG7_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG7_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL1 0x0d16 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL2 0x0d17 +#define RTL8367C_SVLAN_C2SCFG7_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG7_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL0 0x0d18 +#define RTL8367C_SVLAN_C2SCFG8_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG8_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL1 0x0d19 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL2 0x0d1a +#define RTL8367C_SVLAN_C2SCFG8_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG8_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL0 0x0d1b +#define RTL8367C_SVLAN_C2SCFG9_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG9_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL1 0x0d1c +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL2 0x0d1d +#define RTL8367C_SVLAN_C2SCFG9_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG9_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL0 0x0d1e +#define RTL8367C_SVLAN_C2SCFG10_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG10_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL1 0x0d1f +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL2 0x0d20 +#define RTL8367C_SVLAN_C2SCFG10_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG10_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL0 0x0d21 +#define RTL8367C_SVLAN_C2SCFG11_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG11_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL1 0x0d22 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL2 0x0d23 +#define RTL8367C_SVLAN_C2SCFG11_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG11_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL0 0x0d24 +#define RTL8367C_SVLAN_C2SCFG12_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG12_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL1 0x0d25 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL2 0x0d26 +#define RTL8367C_SVLAN_C2SCFG12_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG12_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL0 0x0d27 +#define RTL8367C_SVLAN_C2SCFG13_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG13_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL1 0x0d28 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL2 0x0d29 +#define RTL8367C_SVLAN_C2SCFG13_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG13_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL0 0x0d2a +#define RTL8367C_SVLAN_C2SCFG14_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG14_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL1 0x0d2b +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL2 0x0d2c +#define RTL8367C_SVLAN_C2SCFG14_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG14_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL0 0x0d2d +#define RTL8367C_SVLAN_C2SCFG15_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG15_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL1 0x0d2e +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL2 0x0d2f +#define RTL8367C_SVLAN_C2SCFG15_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG15_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL0 0x0d30 +#define RTL8367C_SVLAN_C2SCFG16_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG16_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL1 0x0d31 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL2 0x0d32 +#define RTL8367C_SVLAN_C2SCFG16_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG16_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL0 0x0d33 +#define RTL8367C_SVLAN_C2SCFG17_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG17_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL1 0x0d34 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL2 0x0d35 +#define RTL8367C_SVLAN_C2SCFG17_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG17_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL0 0x0d36 +#define RTL8367C_SVLAN_C2SCFG18_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG18_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL1 0x0d37 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL2 0x0d38 +#define RTL8367C_SVLAN_C2SCFG18_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG18_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL0 0x0d39 +#define RTL8367C_SVLAN_C2SCFG19_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG19_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL1 0x0d3a +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL2 0x0d3b +#define RTL8367C_SVLAN_C2SCFG19_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG19_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL0 0x0d3c +#define RTL8367C_SVLAN_C2SCFG20_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG20_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL1 0x0d3d +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL2 0x0d3e +#define RTL8367C_SVLAN_C2SCFG20_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG20_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL0 0x0d3f +#define RTL8367C_SVLAN_C2SCFG21_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG21_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL1 0x0d40 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL2 0x0d41 +#define RTL8367C_SVLAN_C2SCFG21_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG21_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL0 0x0d42 +#define RTL8367C_SVLAN_C2SCFG22_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG22_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL1 0x0d43 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL2 0x0d44 +#define RTL8367C_SVLAN_C2SCFG22_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG22_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL0 0x0d45 +#define RTL8367C_SVLAN_C2SCFG23_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG23_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL1 0x0d46 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL2 0x0d47 +#define RTL8367C_SVLAN_C2SCFG23_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG23_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL0 0x0d48 +#define RTL8367C_SVLAN_C2SCFG24_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG24_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL1 0x0d49 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL2 0x0d4a +#define RTL8367C_SVLAN_C2SCFG24_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG24_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL0 0x0d4b +#define RTL8367C_SVLAN_C2SCFG25_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG25_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL1 0x0d4c +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL2 0x0d4d +#define RTL8367C_SVLAN_C2SCFG25_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG25_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL0 0x0d4e +#define RTL8367C_SVLAN_C2SCFG26_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG26_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL1 0x0d4f +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL2 0x0d50 +#define RTL8367C_SVLAN_C2SCFG26_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG26_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL0 0x0d51 +#define RTL8367C_SVLAN_C2SCFG27_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG27_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL1 0x0d52 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL2 0x0d53 +#define RTL8367C_SVLAN_C2SCFG27_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG27_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL0 0x0d54 +#define RTL8367C_SVLAN_C2SCFG28_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG28_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL1 0x0d55 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL2 0x0d56 +#define RTL8367C_SVLAN_C2SCFG28_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG28_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL0 0x0d57 +#define RTL8367C_SVLAN_C2SCFG29_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG29_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL1 0x0d58 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL2 0x0d59 +#define RTL8367C_SVLAN_C2SCFG29_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG29_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL0 0x0d5a +#define RTL8367C_SVLAN_C2SCFG30_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG30_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL1 0x0d5b +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL2 0x0d5c +#define RTL8367C_SVLAN_C2SCFG30_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG30_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL0 0x0d5d +#define RTL8367C_SVLAN_C2SCFG31_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG31_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL1 0x0d5e +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL2 0x0d5f +#define RTL8367C_SVLAN_C2SCFG31_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG31_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL0 0x0d60 +#define RTL8367C_SVLAN_C2SCFG32_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG32_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL1 0x0d61 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL2 0x0d62 +#define RTL8367C_SVLAN_C2SCFG32_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG32_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL0 0x0d63 +#define RTL8367C_SVLAN_C2SCFG33_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG33_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL1 0x0d64 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL2 0x0d65 +#define RTL8367C_SVLAN_C2SCFG33_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG33_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL0 0x0d66 +#define RTL8367C_SVLAN_C2SCFG34_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG34_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL1 0x0d67 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL2 0x0d68 +#define RTL8367C_SVLAN_C2SCFG34_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG34_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL0 0x0d69 +#define RTL8367C_SVLAN_C2SCFG35_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG35_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL1 0x0d6a +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL2 0x0d6b +#define RTL8367C_SVLAN_C2SCFG35_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG35_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL0 0x0d6c +#define RTL8367C_SVLAN_C2SCFG36_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG36_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL1 0x0d6d +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL2 0x0d6e +#define RTL8367C_SVLAN_C2SCFG36_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG36_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL0 0x0d6f +#define RTL8367C_SVLAN_C2SCFG37_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG37_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL1 0x0d70 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL2 0x0d71 +#define RTL8367C_SVLAN_C2SCFG37_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG37_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL0 0x0d72 +#define RTL8367C_SVLAN_C2SCFG38_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG38_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL1 0x0d73 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL2 0x0d74 +#define RTL8367C_SVLAN_C2SCFG38_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG38_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL0 0x0d75 +#define RTL8367C_SVLAN_C2SCFG39_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG39_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL1 0x0d76 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL2 0x0d77 +#define RTL8367C_SVLAN_C2SCFG39_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG39_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL0 0x0d78 +#define RTL8367C_SVLAN_C2SCFG40_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG40_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL1 0x0d79 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL2 0x0d7a +#define RTL8367C_SVLAN_C2SCFG40_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG40_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL0 0x0d7b +#define RTL8367C_SVLAN_C2SCFG41_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG41_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL1 0x0d7c +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL2 0x0d7d +#define RTL8367C_SVLAN_C2SCFG41_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG41_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL0 0x0d7e +#define RTL8367C_SVLAN_C2SCFG42_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG42_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL1 0x0d7f +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL2 0x0d80 +#define RTL8367C_SVLAN_C2SCFG42_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG42_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL0 0x0d81 +#define RTL8367C_SVLAN_C2SCFG43_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG43_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL1 0x0d82 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL2 0x0d83 +#define RTL8367C_SVLAN_C2SCFG43_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG43_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL0 0x0d84 +#define RTL8367C_SVLAN_C2SCFG44_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG44_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL1 0x0d85 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL2 0x0d86 +#define RTL8367C_SVLAN_C2SCFG44_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG44_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL0 0x0d87 +#define RTL8367C_SVLAN_C2SCFG45_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG45_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL1 0x0d88 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL2 0x0d89 +#define RTL8367C_SVLAN_C2SCFG45_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG45_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL0 0x0d8a +#define RTL8367C_SVLAN_C2SCFG46_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG46_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL1 0x0d8b +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL2 0x0d8c +#define RTL8367C_SVLAN_C2SCFG46_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG46_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL0 0x0d8d +#define RTL8367C_SVLAN_C2SCFG47_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG47_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL1 0x0d8e +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL2 0x0d8f +#define RTL8367C_SVLAN_C2SCFG47_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG47_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL0 0x0d90 +#define RTL8367C_SVLAN_C2SCFG48_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG48_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL1 0x0d91 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL2 0x0d92 +#define RTL8367C_SVLAN_C2SCFG48_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG48_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL0 0x0d93 +#define RTL8367C_SVLAN_C2SCFG49_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG49_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL1 0x0d94 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL2 0x0d95 +#define RTL8367C_SVLAN_C2SCFG49_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG49_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL0 0x0d96 +#define RTL8367C_SVLAN_C2SCFG50_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG50_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL1 0x0d97 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL2 0x0d98 +#define RTL8367C_SVLAN_C2SCFG50_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG50_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL0 0x0d99 +#define RTL8367C_SVLAN_C2SCFG51_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG51_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL1 0x0d9a +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL2 0x0d9b +#define RTL8367C_SVLAN_C2SCFG51_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG51_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL0 0x0d9c +#define RTL8367C_SVLAN_C2SCFG52_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG52_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL1 0x0d9d +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL2 0x0d9e +#define RTL8367C_SVLAN_C2SCFG52_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG52_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL0 0x0d9f +#define RTL8367C_SVLAN_C2SCFG53_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL1 0x0da0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL2 0x0da1 +#define RTL8367C_SVLAN_C2SCFG53_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL0 0x0da2 +#define RTL8367C_SVLAN_C2SCFG54_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG54_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL1 0x0da3 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL2 0x0da4 +#define RTL8367C_SVLAN_C2SCFG54_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG54_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL0 0x0da5 +#define RTL8367C_SVLAN_C2SCFG55_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG55_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL1 0x0da6 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL2 0x0da7 +#define RTL8367C_SVLAN_C2SCFG55_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG55_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL0 0x0da8 +#define RTL8367C_SVLAN_C2SCFG56_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG56_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL1 0x0da9 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL2 0x0daa +#define RTL8367C_SVLAN_C2SCFG56_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG56_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL0 0x0dab +#define RTL8367C_SVLAN_C2SCFG57_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG57_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL1 0x0dac +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL2 0x0dad +#define RTL8367C_SVLAN_C2SCFG57_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG57_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL0 0x0dae +#define RTL8367C_SVLAN_C2SCFG58_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL1 0x0daf +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL2 0x0db0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL0 0x0db1 +#define RTL8367C_SVLAN_C2SCFG59_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG59_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL1 0x0db2 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL2 0x0db3 +#define RTL8367C_SVLAN_C2SCFG59_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG59_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL0 0x0db4 +#define RTL8367C_SVLAN_C2SCFG60_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG60_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL1 0x0db5 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL2 0x0db6 +#define RTL8367C_SVLAN_C2SCFG60_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG60_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL0 0x0db7 +#define RTL8367C_SVLAN_C2SCFG61_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG61_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL1 0x0db8 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL2 0x0db9 +#define RTL8367C_SVLAN_C2SCFG61_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG61_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL0 0x0dba +#define RTL8367C_SVLAN_C2SCFG62_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG62_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL1 0x0dbb +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL2 0x0dbc +#define RTL8367C_SVLAN_C2SCFG62_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG62_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL0 0x0dbd +#define RTL8367C_SVLAN_C2SCFG63_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG63_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL1 0x0dbe +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL2 0x0dbf +#define RTL8367C_SVLAN_C2SCFG63_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG63_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL0 0x0dc0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL1 0x0dc1 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL2 0x0dc2 +#define RTL8367C_SVLAN_C2SCFG64_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL0 0x0dc3 +#define RTL8367C_SVLAN_C2SCFG65_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG65_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL1 0x0dc4 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL2 0x0dc5 +#define RTL8367C_SVLAN_C2SCFG65_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG65_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL0 0x0dc6 +#define RTL8367C_SVLAN_C2SCFG66_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG66_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL1 0x0dc7 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL2 0x0dc8 +#define RTL8367C_SVLAN_C2SCFG66_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG66_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL0 0x0dc9 +#define RTL8367C_SVLAN_C2SCFG67_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG67_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL1 0x0dca +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL2 0x0dcb +#define RTL8367C_SVLAN_C2SCFG67_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG67_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL0 0x0dcc +#define RTL8367C_SVLAN_C2SCFG68_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG68_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL1 0x0dcd +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL2 0x0dce +#define RTL8367C_SVLAN_C2SCFG68_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG68_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL0 0x0dcf +#define RTL8367C_SVLAN_C2SCFG69_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL1 0x0dd0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL2 0x0dd1 +#define RTL8367C_SVLAN_C2SCFG69_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL0 0x0dd2 +#define RTL8367C_SVLAN_C2SCFG70_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG70_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL1 0x0dd3 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL2 0x0dd4 +#define RTL8367C_SVLAN_C2SCFG70_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG70_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL0 0x0dd5 +#define RTL8367C_SVLAN_C2SCFG71_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG71_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL1 0x0dd6 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL2 0x0dd7 +#define RTL8367C_SVLAN_C2SCFG71_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG71_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL0 0x0dd8 +#define RTL8367C_SVLAN_C2SCFG72_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG72_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL1 0x0dd9 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL2 0x0dda +#define RTL8367C_SVLAN_C2SCFG72_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG72_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL0 0x0ddb +#define RTL8367C_SVLAN_C2SCFG73_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG73_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL1 0x0ddc +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL2 0x0ddd +#define RTL8367C_SVLAN_C2SCFG73_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG73_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL0 0x0dde +#define RTL8367C_SVLAN_C2SCFG74_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL1 0x0ddf +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL2 0x0de0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL0 0x0de1 +#define RTL8367C_SVLAN_C2SCFG75_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG75_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL1 0x0de2 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL2 0x0de3 +#define RTL8367C_SVLAN_C2SCFG75_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG75_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL0 0x0de4 +#define RTL8367C_SVLAN_C2SCFG76_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG76_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL1 0x0de5 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL2 0x0de6 +#define RTL8367C_SVLAN_C2SCFG76_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG76_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL0 0x0de7 +#define RTL8367C_SVLAN_C2SCFG77_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG77_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL1 0x0de8 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL2 0x0de9 +#define RTL8367C_SVLAN_C2SCFG77_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG77_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL0 0x0dea +#define RTL8367C_SVLAN_C2SCFG78_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG78_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL1 0x0deb +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL2 0x0dec +#define RTL8367C_SVLAN_C2SCFG78_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG78_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL0 0x0ded +#define RTL8367C_SVLAN_C2SCFG79_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG79_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL1 0x0dee +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL2 0x0def +#define RTL8367C_SVLAN_C2SCFG79_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG79_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL0 0x0df0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL1 0x0df1 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL2 0x0df2 +#define RTL8367C_SVLAN_C2SCFG80_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL0 0x0df3 +#define RTL8367C_SVLAN_C2SCFG81_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG81_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL1 0x0df4 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL2 0x0df5 +#define RTL8367C_SVLAN_C2SCFG81_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG81_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL0 0x0df6 +#define RTL8367C_SVLAN_C2SCFG82_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG82_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL1 0x0df7 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL2 0x0df8 +#define RTL8367C_SVLAN_C2SCFG82_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG82_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL0 0x0df9 +#define RTL8367C_SVLAN_C2SCFG83_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG83_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL1 0x0dfa +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL2 0x0dfb +#define RTL8367C_SVLAN_C2SCFG83_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG83_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL0 0x0dfc +#define RTL8367C_SVLAN_C2SCFG84_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG84_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL1 0x0dfd +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL2 0x0dfe +#define RTL8367C_SVLAN_C2SCFG84_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG84_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL0 0x0dff +#define RTL8367C_SVLAN_C2SCFG85_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG85_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL1 0x0e00 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL2 0x0e01 +#define RTL8367C_SVLAN_C2SCFG85_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG85_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL0 0x0e02 +#define RTL8367C_SVLAN_C2SCFG86_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG86_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL1 0x0e03 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL2 0x0e04 +#define RTL8367C_SVLAN_C2SCFG86_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG86_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL0 0x0e05 +#define RTL8367C_SVLAN_C2SCFG87_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG87_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL1 0x0e06 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL2 0x0e07 +#define RTL8367C_SVLAN_C2SCFG87_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG87_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL0 0x0e08 +#define RTL8367C_SVLAN_C2SCFG88_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG88_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL1 0x0e09 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL2 0x0e0a +#define RTL8367C_SVLAN_C2SCFG88_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG88_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL0 0x0e0b +#define RTL8367C_SVLAN_C2SCFG89_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG89_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL1 0x0e0c +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL2 0x0e0d +#define RTL8367C_SVLAN_C2SCFG89_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG89_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL0 0x0e0e +#define RTL8367C_SVLAN_C2SCFG90_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG90_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL1 0x0e0f +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL2 0x0e10 +#define RTL8367C_SVLAN_C2SCFG90_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG90_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL0 0x0e11 +#define RTL8367C_SVLAN_C2SCFG91_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG91_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL1 0x0e12 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL2 0x0e13 +#define RTL8367C_SVLAN_C2SCFG91_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG91_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL0 0x0e14 +#define RTL8367C_SVLAN_C2SCFG92_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG92_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL1 0x0e15 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL2 0x0e16 +#define RTL8367C_SVLAN_C2SCFG92_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG92_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL0 0x0e17 +#define RTL8367C_SVLAN_C2SCFG93_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG93_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL1 0x0e18 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL2 0x0e19 +#define RTL8367C_SVLAN_C2SCFG93_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG93_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL0 0x0e1a +#define RTL8367C_SVLAN_C2SCFG94_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG94_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL1 0x0e1b +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL2 0x0e1c +#define RTL8367C_SVLAN_C2SCFG94_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG94_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL0 0x0e1d +#define RTL8367C_SVLAN_C2SCFG95_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG95_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL1 0x0e1e +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL2 0x0e1f +#define RTL8367C_SVLAN_C2SCFG95_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG95_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL0 0x0e20 +#define RTL8367C_SVLAN_C2SCFG96_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG96_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL1 0x0e21 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL2 0x0e22 +#define RTL8367C_SVLAN_C2SCFG96_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG96_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL0 0x0e23 +#define RTL8367C_SVLAN_C2SCFG97_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG97_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL1 0x0e24 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL2 0x0e25 +#define RTL8367C_SVLAN_C2SCFG97_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG97_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL0 0x0e26 +#define RTL8367C_SVLAN_C2SCFG98_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG98_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL1 0x0e27 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL2 0x0e28 +#define RTL8367C_SVLAN_C2SCFG98_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG98_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL0 0x0e29 +#define RTL8367C_SVLAN_C2SCFG99_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG99_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL1 0x0e2a +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL2 0x0e2b +#define RTL8367C_SVLAN_C2SCFG99_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG99_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL0 0x0e2c +#define RTL8367C_SVLAN_C2SCFG100_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG100_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL1 0x0e2d +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL2 0x0e2e +#define RTL8367C_SVLAN_C2SCFG100_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG100_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL0 0x0e2f +#define RTL8367C_SVLAN_C2SCFG101_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG101_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL1 0x0e30 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL2 0x0e31 +#define RTL8367C_SVLAN_C2SCFG101_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG101_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL0 0x0e32 +#define RTL8367C_SVLAN_C2SCFG102_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG102_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL1 0x0e33 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL2 0x0e34 +#define RTL8367C_SVLAN_C2SCFG102_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG102_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL0 0x0e35 +#define RTL8367C_SVLAN_C2SCFG103_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG103_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL1 0x0e36 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL2 0x0e37 +#define RTL8367C_SVLAN_C2SCFG103_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG103_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL0 0x0e38 +#define RTL8367C_SVLAN_C2SCFG104_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG104_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL1 0x0e39 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL2 0x0e3a +#define RTL8367C_SVLAN_C2SCFG104_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG104_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL0 0x0e3b +#define RTL8367C_SVLAN_C2SCFG105_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG105_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL1 0x0e3c +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL2 0x0e3d +#define RTL8367C_SVLAN_C2SCFG105_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG105_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL0 0x0e3e +#define RTL8367C_SVLAN_C2SCFG106_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG106_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL1 0x0e3f +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL2 0x0e40 +#define RTL8367C_SVLAN_C2SCFG106_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG106_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL0 0x0e41 +#define RTL8367C_SVLAN_C2SCFG107_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG107_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL1 0x0e42 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL2 0x0e43 +#define RTL8367C_SVLAN_C2SCFG107_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG107_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL0 0x0e44 +#define RTL8367C_SVLAN_C2SCFG108_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG108_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL1 0x0e45 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL2 0x0e46 +#define RTL8367C_SVLAN_C2SCFG108_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG108_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL0 0x0e47 +#define RTL8367C_SVLAN_C2SCFG109_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG109_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL1 0x0e48 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL2 0x0e49 +#define RTL8367C_SVLAN_C2SCFG109_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG109_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL0 0x0e4a +#define RTL8367C_SVLAN_C2SCFG110_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG110_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL1 0x0e4b +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL2 0x0e4c +#define RTL8367C_SVLAN_C2SCFG110_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG110_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL0 0x0e4d +#define RTL8367C_SVLAN_C2SCFG111_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG111_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL1 0x0e4e +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL2 0x0e4f +#define RTL8367C_SVLAN_C2SCFG111_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG111_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL0 0x0e50 +#define RTL8367C_SVLAN_C2SCFG112_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG112_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL1 0x0e51 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL2 0x0e52 +#define RTL8367C_SVLAN_C2SCFG112_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG112_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL0 0x0e53 +#define RTL8367C_SVLAN_C2SCFG113_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG113_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL1 0x0e54 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL2 0x0e55 +#define RTL8367C_SVLAN_C2SCFG113_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG113_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL0 0x0e56 +#define RTL8367C_SVLAN_C2SCFG114_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG114_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL1 0x0e57 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL2 0x0e58 +#define RTL8367C_SVLAN_C2SCFG114_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG114_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL0 0x0e59 +#define RTL8367C_SVLAN_C2SCFG115_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG115_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL1 0x0e5a +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL2 0x0e5b +#define RTL8367C_SVLAN_C2SCFG115_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG115_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL0 0x0e5c +#define RTL8367C_SVLAN_C2SCFG116_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG116_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL1 0x0e5d +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL2 0x0e5e +#define RTL8367C_SVLAN_C2SCFG116_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG116_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL0 0x0e5f +#define RTL8367C_SVLAN_C2SCFG117_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG117_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL1 0x0e60 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL2 0x0e61 +#define RTL8367C_SVLAN_C2SCFG117_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG117_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL0 0x0e62 +#define RTL8367C_SVLAN_C2SCFG118_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG118_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL1 0x0e63 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL2 0x0e64 +#define RTL8367C_SVLAN_C2SCFG118_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG118_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL0 0x0e65 +#define RTL8367C_SVLAN_C2SCFG119_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG119_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL1 0x0e66 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL2 0x0e67 +#define RTL8367C_SVLAN_C2SCFG119_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG119_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL0 0x0e68 +#define RTL8367C_SVLAN_C2SCFG120_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG120_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL1 0x0e69 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL2 0x0e6a +#define RTL8367C_SVLAN_C2SCFG120_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG120_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL0 0x0e6b +#define RTL8367C_SVLAN_C2SCFG121_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG121_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL1 0x0e6c +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL2 0x0e6d +#define RTL8367C_SVLAN_C2SCFG121_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG121_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL0 0x0e6e +#define RTL8367C_SVLAN_C2SCFG122_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG122_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL1 0x0e6f +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL2 0x0e70 +#define RTL8367C_SVLAN_C2SCFG122_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG122_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL0 0x0e71 +#define RTL8367C_SVLAN_C2SCFG123_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG123_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL1 0x0e72 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL2 0x0e73 +#define RTL8367C_SVLAN_C2SCFG123_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG123_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL0 0x0e74 +#define RTL8367C_SVLAN_C2SCFG124_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG124_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL1 0x0e75 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL2 0x0e76 +#define RTL8367C_SVLAN_C2SCFG124_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG124_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL0 0x0e77 +#define RTL8367C_SVLAN_C2SCFG125_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG125_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL1 0x0e78 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL2 0x0e79 +#define RTL8367C_SVLAN_C2SCFG125_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG125_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL0 0x0e7a +#define RTL8367C_SVLAN_C2SCFG126_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG126_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL1 0x0e7b +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL2 0x0e7c +#define RTL8367C_SVLAN_C2SCFG126_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG126_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL0 0x0e7d +#define RTL8367C_SVLAN_C2SCFG127_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG127_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL1 0x0e7e +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL2 0x0e7f +#define RTL8367C_SVLAN_C2SCFG127_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG127_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_CFG 0x0e80 +#define RTL8367C_VS_PORT7_DMACVIDSEL_OFFSET 14 +#define RTL8367C_VS_PORT7_DMACVIDSEL_MASK 0x4000 +#define RTL8367C_VS_PORT6_DMACVIDSEL_OFFSET 13 +#define RTL8367C_VS_PORT6_DMACVIDSEL_MASK 0x2000 +#define RTL8367C_VS_PORT5_DMACVIDSEL_OFFSET 12 +#define RTL8367C_VS_PORT5_DMACVIDSEL_MASK 0x1000 +#define RTL8367C_VS_PORT4_DMACVIDSEL_OFFSET 11 +#define RTL8367C_VS_PORT4_DMACVIDSEL_MASK 0x800 +#define RTL8367C_VS_PORT3_DMACVIDSEL_OFFSET 10 +#define RTL8367C_VS_PORT3_DMACVIDSEL_MASK 0x400 +#define RTL8367C_VS_PORT2_DMACVIDSEL_OFFSET 9 +#define RTL8367C_VS_PORT2_DMACVIDSEL_MASK 0x200 +#define RTL8367C_VS_PORT1_DMACVIDSEL_OFFSET 8 +#define RTL8367C_VS_PORT1_DMACVIDSEL_MASK 0x100 +#define RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET 7 +#define RTL8367C_VS_PORT0_DMACVIDSEL_MASK 0x80 +#define RTL8367C_VS_UIFSEG_OFFSET 6 +#define RTL8367C_VS_UIFSEG_MASK 0x40 +#define RTL8367C_VS_UNMAT_OFFSET 4 +#define RTL8367C_VS_UNMAT_MASK 0x30 +#define RTL8367C_VS_UNTAG_OFFSET 2 +#define RTL8367C_VS_UNTAG_MASK 0xC +#define RTL8367C_VS_SPRISEL_OFFSET 0 +#define RTL8367C_VS_SPRISEL_MASK 0x3 + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 0x0e81 +#define RTL8367C_VS_PORT1_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT1_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT0_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL1 0x0e82 +#define RTL8367C_VS_PORT3_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT3_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT2_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT2_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL2 0x0e83 +#define RTL8367C_VS_PORT5_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT5_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT4_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT4_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL3 0x0e84 +#define RTL8367C_VS_PORT7_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT7_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT6_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT6_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG 0x0e85 +#define RTL8367C_VS_UNTAG_SVIDX_OFFSET 8 +#define RTL8367C_VS_UNTAG_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_UNMAT_SVIDX_OFFSET 0 +#define RTL8367C_VS_UNMAT_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_LOOKUP_TYPE 0x0e86 +#define RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET 0 +#define RTL8367C_SVLAN_LOOKUP_TYPE_MASK 0x1 + +#define RTL8367C_REG_IPMC_GROUP_VALID_15_0 0x0e87 + +#define RTL8367C_REG_IPMC_GROUP_VALID_31_16 0x0e88 + +#define RTL8367C_REG_IPMC_GROUP_VALID_47_32 0x0e89 + +#define RTL8367C_REG_IPMC_GROUP_VALID_63_48 0x0e8a + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4 0x0e8b +#define RTL8367C_VS_PORT9_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT9_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT8_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT8_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5 0x0e8c +#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_OFFSET 0 +#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK 0x3F + +#define RTL8367C_REG_SVLAN_CFG_EXT 0x0e8d +#define RTL8367C_VS_PORT10_DMACVIDSEL_OFFSET 2 +#define RTL8367C_VS_PORT10_DMACVIDSEL_MASK 0x4 +#define RTL8367C_VS_PORT9_DMACVIDSEL_OFFSET 1 +#define RTL8367C_VS_PORT9_DMACVIDSEL_MASK 0x2 +#define RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET 0 +#define RTL8367C_VS_PORT8_DMACVIDSEL_MASK 0x1 + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4 0x0e8e +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_DUMMY_0 0x0e90 + +#define RTL8367C_REG_SVLAN_DUMMY_1 0x0e91 + +#define RTL8367C_REG_SVLAN_DUMMY_2 0x0e92 + +#define RTL8367C_REG_SVLAN_DUMMY_3 0x0e93 + +#define RTL8367C_REG_SVLAN_DUMMY_4 0x0e94 + +#define RTL8367C_REG_SVLAN_DUMMY_5 0x0e95 + +#define RTL8367C_REG_SVLAN_DUMMY_6 0x0e96 + +#define RTL8367C_REG_SVLAN_DUMMY_7 0x0e97 + +#define RTL8367C_REG_SVLAN_DUMMY_8 0x0e98 + +#define RTL8367C_REG_SVLAN_DUMMY_9 0x0e99 + +#define RTL8367C_REG_SVLAN_DUMMY_10 0x0e9a + +#define RTL8367C_REG_SVLAN_DUMMY_11 0x0e9b + +#define RTL8367C_REG_SVLAN_DUMMY_12 0x0e9c + +#define RTL8367C_REG_SVLAN_DUMMY_13 0x0e9d + +#define RTL8367C_REG_SVLAN_DUMMY_14 0x0e9e + +#define RTL8367C_REG_SVLAN_DUMMY_15 0x0e9f + +#define RTL8367C_REG_SVLAN_DUMMY_16 0x0ea0 + +#define RTL8367C_REG_SVLAN_DUMMY_17 0x0ea1 + +#define RTL8367C_REG_SVLAN_DUMMY_18 0x0ea2 + +#define RTL8367C_REG_SVLAN_DUMMY_19 0x0ea3 + +#define RTL8367C_REG_SVLAN_DUMMY_20 0x0ea4 + +#define RTL8367C_REG_SVLAN_DUMMY_21 0x0ea5 + +#define RTL8367C_REG_SVLAN_DUMMY_22 0x0ea6 + +#define RTL8367C_REG_SVLAN_DUMMY_23 0x0ea7 + +#define RTL8367C_REG_SVLAN_DUMMY_24 0x0ea8 + +#define RTL8367C_REG_SVLAN_DUMMY_25 0x0ea9 + +#define RTL8367C_REG_SVLAN_DUMMY_26 0x0eaa + +#define RTL8367C_REG_SVLAN_DUMMY_27 0x0eab + +#define RTL8367C_REG_SVLAN_DUMMY_28 0x0eac + +#define RTL8367C_REG_SVLAN_DUMMY_29 0x0ead + +#define RTL8367C_REG_SVLAN_DUMMY_30 0x0eae + +#define RTL8367C_REG_SVLAN_DUMMY_31 0x0eaf + +#define RTL8367C_REG_IPMC_GROUP_VID_00 0x0eb0 +#define RTL8367C_IPMC_GROUP_VID_00_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_00_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_01 0x0eb1 +#define RTL8367C_IPMC_GROUP_VID_01_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_01_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_02 0x0eb2 +#define RTL8367C_IPMC_GROUP_VID_02_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_02_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_03 0x0eb3 +#define RTL8367C_IPMC_GROUP_VID_03_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_03_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_04 0x0eb4 +#define RTL8367C_IPMC_GROUP_VID_04_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_04_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_05 0x0eb5 +#define RTL8367C_IPMC_GROUP_VID_05_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_05_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_06 0x0eb6 +#define RTL8367C_IPMC_GROUP_VID_06_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_06_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_07 0x0eb7 +#define RTL8367C_IPMC_GROUP_VID_07_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_07_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_08 0x0eb8 +#define RTL8367C_IPMC_GROUP_VID_08_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_08_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_09 0x0eb9 +#define RTL8367C_IPMC_GROUP_VID_09_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_09_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_10 0x0eba +#define RTL8367C_IPMC_GROUP_VID_10_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_10_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_11 0x0ebb +#define RTL8367C_IPMC_GROUP_VID_11_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_11_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_12 0x0ebc +#define RTL8367C_IPMC_GROUP_VID_12_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_12_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_13 0x0ebd +#define RTL8367C_IPMC_GROUP_VID_13_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_13_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_14 0x0ebe +#define RTL8367C_IPMC_GROUP_VID_14_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_14_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_15 0x0ebf +#define RTL8367C_IPMC_GROUP_VID_15_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_15_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_16 0x0ec0 +#define RTL8367C_IPMC_GROUP_VID_16_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_16_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_17 0x0ec1 +#define RTL8367C_IPMC_GROUP_VID_17_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_17_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_18 0x0ec2 +#define RTL8367C_IPMC_GROUP_VID_18_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_18_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_19 0x0ec3 +#define RTL8367C_IPMC_GROUP_VID_19_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_19_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_20 0x0ec4 +#define RTL8367C_IPMC_GROUP_VID_20_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_20_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_21 0x0ec5 +#define RTL8367C_IPMC_GROUP_VID_21_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_21_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_22 0x0ec6 +#define RTL8367C_IPMC_GROUP_VID_22_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_22_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_23 0x0ec7 +#define RTL8367C_IPMC_GROUP_VID_23_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_23_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_24 0x0ec8 +#define RTL8367C_IPMC_GROUP_VID_24_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_24_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_25 0x0ec9 +#define RTL8367C_IPMC_GROUP_VID_25_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_25_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_26 0x0eca +#define RTL8367C_IPMC_GROUP_VID_26_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_26_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_27 0x0ecb +#define RTL8367C_IPMC_GROUP_VID_27_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_27_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_28 0x0ecc +#define RTL8367C_IPMC_GROUP_VID_28_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_28_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_29 0x0ecd +#define RTL8367C_IPMC_GROUP_VID_29_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_29_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_30 0x0ece +#define RTL8367C_IPMC_GROUP_VID_30_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_30_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_31 0x0ecf +#define RTL8367C_IPMC_GROUP_VID_31_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_31_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_32 0x0ed0 +#define RTL8367C_IPMC_GROUP_VID_32_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_32_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_33 0x0ed1 +#define RTL8367C_IPMC_GROUP_VID_33_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_33_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_34 0x0ed2 +#define RTL8367C_IPMC_GROUP_VID_34_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_34_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_35 0x0ed3 +#define RTL8367C_IPMC_GROUP_VID_35_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_35_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_36 0x0ed4 +#define RTL8367C_IPMC_GROUP_VID_36_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_36_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_37 0x0ed5 +#define RTL8367C_IPMC_GROUP_VID_37_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_37_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_38 0x0ed6 +#define RTL8367C_IPMC_GROUP_VID_38_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_38_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_39 0x0ed7 +#define RTL8367C_IPMC_GROUP_VID_39_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_39_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_40 0x0ed8 +#define RTL8367C_IPMC_GROUP_VID_40_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_40_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_41 0x0ed9 +#define RTL8367C_IPMC_GROUP_VID_41_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_41_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_42 0x0eda +#define RTL8367C_IPMC_GROUP_VID_42_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_42_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_43 0x0edb +#define RTL8367C_IPMC_GROUP_VID_43_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_43_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_44 0x0edc +#define RTL8367C_IPMC_GROUP_VID_44_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_44_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_45 0x0edd +#define RTL8367C_IPMC_GROUP_VID_45_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_45_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_46 0x0ede +#define RTL8367C_IPMC_GROUP_VID_46_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_46_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_47 0x0edf +#define RTL8367C_IPMC_GROUP_VID_47_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_47_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_48 0x0ef0 +#define RTL8367C_IPMC_GROUP_VID_48_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_48_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_49 0x0ef1 +#define RTL8367C_IPMC_GROUP_VID_49_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_49_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_50 0x0ef2 +#define RTL8367C_IPMC_GROUP_VID_50_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_50_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_51 0x0ef3 +#define RTL8367C_IPMC_GROUP_VID_51_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_51_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_52 0x0ef4 +#define RTL8367C_IPMC_GROUP_VID_52_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_52_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_53 0x0ef5 +#define RTL8367C_IPMC_GROUP_VID_53_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_53_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_54 0x0ef6 +#define RTL8367C_IPMC_GROUP_VID_54_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_54_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_55 0x0ef7 +#define RTL8367C_IPMC_GROUP_VID_55_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_55_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_56 0x0ef8 +#define RTL8367C_IPMC_GROUP_VID_56_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_56_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_57 0x0ef9 +#define RTL8367C_IPMC_GROUP_VID_57_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_57_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_58 0x0efa +#define RTL8367C_IPMC_GROUP_VID_58_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_58_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_59 0x0efb +#define RTL8367C_IPMC_GROUP_VID_59_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_59_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_60 0x0efc +#define RTL8367C_IPMC_GROUP_VID_60_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_60_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_61 0x0efd +#define RTL8367C_IPMC_GROUP_VID_61_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_61_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_62 0x0efe +#define RTL8367C_IPMC_GROUP_VID_62_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_62_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_63 0x0eff +#define RTL8367C_IPMC_GROUP_VID_63_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_63_MASK 0xFFF + +/* (16'h0f00)hsactrl_reg */ + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 0x0f00 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL1 0x0f01 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL0 0x0f02 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL1 0x0f03 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL0 0x0f04 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL1 0x0f05 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL0 0x0f06 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL1 0x0f07 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL0 0x0f08 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL1 0x0f09 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL0 0x0f0a +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL1 0x0f0b +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL0 0x0f0c +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL1 0x0f0d +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL0 0x0f0e +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL1 0x0f0f +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL0 0x0f10 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL1 0x0f11 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL0 0x0f12 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL1 0x0f13 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL0 0x0f14 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL1 0x0f15 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL0 0x0f16 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL1 0x0f17 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL0 0x0f18 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL1 0x0f19 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL0 0x0f1a +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL1 0x0f1b +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL0 0x0f1c +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL1 0x0f1d +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL0 0x0f1e +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL1 0x0f1f +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL0 0x0f20 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL1 0x0f21 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL0 0x0f22 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL1 0x0f23 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL0 0x0f24 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL1 0x0f25 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL0 0x0f26 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL1 0x0f27 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL0 0x0f28 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL1 0x0f29 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL0 0x0f2a +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL1 0x0f2b +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL0 0x0f2c +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL1 0x0f2d +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL0 0x0f2e +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL1 0x0f2f +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL0 0x0f30 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL1 0x0f31 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL0 0x0f32 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL1 0x0f33 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL0 0x0f34 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL1 0x0f35 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL0 0x0f36 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL1 0x0f37 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL0 0x0f38 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL1 0x0f39 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL0 0x0f3a +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL1 0x0f3b +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL0 0x0f3c +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL1 0x0f3d +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL0 0x0f3e +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL1 0x0f3f +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL0 0x0f40 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL1 0x0f41 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL0 0x0f42 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL1 0x0f43 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL0 0x0f44 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL1 0x0f45 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL0 0x0f46 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL1 0x0f47 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL0 0x0f48 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL1 0x0f49 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL0 0x0f4a +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL1 0x0f4b +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL0 0x0f4c +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL1 0x0f4d +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL0 0x0f4e +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL1 0x0f4f +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL0 0x0f50 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL1 0x0f51 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL0 0x0f52 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL1 0x0f53 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL0 0x0f54 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL1 0x0f55 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL0 0x0f56 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL1 0x0f57 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL0 0x0f58 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL1 0x0f59 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL0 0x0f5a +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL1 0x0f5b +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL0 0x0f5c +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL1 0x0f5d +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL0 0x0f5e +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL1 0x0f5f +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL0 0x0f60 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL1 0x0f61 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL0 0x0f62 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL1 0x0f63 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL0 0x0f64 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL1 0x0f65 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL0 0x0f66 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL1 0x0f67 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL0 0x0f68 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL1 0x0f69 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL0 0x0f6a +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL1 0x0f6b +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL0 0x0f6c +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL1 0x0f6d +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL0 0x0f6e +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL1 0x0f6f +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL0 0x0f70 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL1 0x0f71 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL0 0x0f72 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL1 0x0f73 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL0 0x0f74 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL1 0x0f75 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL0 0x0f76 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL1 0x0f77 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL0 0x0f78 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL1 0x0f79 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL0 0x0f7a +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL1 0x0f7b +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL0 0x0f7c +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL1 0x0f7d +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL0 0x0f7e +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL1 0x0f7f +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL0 0x0f80 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL1 0x0f81 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL0 0x0f82 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL1 0x0f83 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL0 0x0f84 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL1 0x0f85 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL0 0x0f86 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL1 0x0f87 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL0 0x0f88 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL1 0x0f89 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL0 0x0f8a +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL1 0x0f8b +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL0 0x0f8c +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL1 0x0f8d +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL0 0x0f8e +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL1 0x0f8f +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL0 0x0f90 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL1 0x0f91 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL0 0x0f92 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL1 0x0f93 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL0 0x0f94 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL1 0x0f95 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL0 0x0f96 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL1 0x0f97 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL0 0x0f98 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL1 0x0f99 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL0 0x0f9a +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL1 0x0f9b +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL0 0x0f9c +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL1 0x0f9d +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL0 0x0f9e +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL1 0x0f9f +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL0 0x0fa0 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL1 0x0fa1 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL0 0x0fa2 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL1 0x0fa3 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL0 0x0fa4 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL1 0x0fa5 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL0 0x0fa6 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL1 0x0fa7 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL0 0x0fa8 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL1 0x0fa9 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL0 0x0faa +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL1 0x0fab +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL0 0x0fac +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL1 0x0fad +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL0 0x0fae +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL1 0x0faf +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL0 0x0fb0 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL1 0x0fb1 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL0 0x0fb2 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL1 0x0fb3 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL0 0x0fb4 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL1 0x0fb5 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL0 0x0fb6 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL1 0x0fb7 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL0 0x0fb8 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL1 0x0fb9 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL0 0x0fba +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL1 0x0fbb +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL0 0x0fbc +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL1 0x0fbd +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL0 0x0fbe +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL1 0x0fbf +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL0 0x0fc0 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL1 0x0fc1 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL0 0x0fc2 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL1 0x0fc3 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL0 0x0fc4 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL1 0x0fc5 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL0 0x0fc6 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL1 0x0fc7 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL0 0x0fc8 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL1 0x0fc9 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL0 0x0fca +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL1 0x0fcb +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL0 0x0fcc +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL1 0x0fcd +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL0 0x0fce +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL1 0x0fcf +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL0 0x0fd0 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL1 0x0fd1 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL0 0x0fd2 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL1 0x0fd3 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL0 0x0fd4 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL1 0x0fd5 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL0 0x0fd6 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL1 0x0fd7 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL0 0x0fd8 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL1 0x0fd9 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL0 0x0fda +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL1 0x0fdb +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL0 0x0fdc +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL1 0x0fdd +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL0 0x0fde +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL1 0x0fdf +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL0 0x0fe0 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL1 0x0fe1 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL0 0x0fe2 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL1 0x0fe3 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL0 0x0fe4 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL1 0x0fe5 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL0 0x0fe6 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL1 0x0fe7 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL0 0x0fe8 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL1 0x0fe9 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL0 0x0fea +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL1 0x0feb +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL0 0x0fec +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL1 0x0fed +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL0 0x0fee +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL1 0x0fef +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL0 0x0ff0 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL1 0x0ff1 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL0 0x0ff2 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL1 0x0ff3 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL0 0x0ff4 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL1 0x0ff5 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL0 0x0ff6 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL1 0x0ff7 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL0 0x0ff8 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL1 0x0ff9 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL0 0x0ffa +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL1 0x0ffb +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL0 0x0ffc +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL1 0x0ffd +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL0 0x0ffe +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL1 0x0fff +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_MASK 0xFFF + +/* (16'h1000)mib_reg */ + +#define RTL8367C_REG_MIB_COUNTER0 0x1000 + +#define RTL8367C_REG_MIB_COUNTER1 0x1001 + +#define RTL8367C_REG_MIB_COUNTER2 0x1002 + +#define RTL8367C_REG_MIB_COUNTER3 0x1003 + +#define RTL8367C_REG_MIB_ADDRESS 0x1004 +#define RTL8367C_MIB_ADDRESS_OFFSET 0 +#define RTL8367C_MIB_ADDRESS_MASK 0x1FF + +#define RTL8367C_REG_MIB_CTRL0 0x1005 +#define RTL8367C_PORT10_RESET_OFFSET 15 +#define RTL8367C_PORT10_RESET_MASK 0x8000 +#define RTL8367C_PORT9_RESET_OFFSET 14 +#define RTL8367C_PORT9_RESET_MASK 0x4000 +#define RTL8367C_PORT8_RESET_OFFSET 13 +#define RTL8367C_PORT8_RESET_MASK 0x2000 +#define RTL8367C_RESET_VALUE_OFFSET 12 +#define RTL8367C_RESET_VALUE_MASK 0x1000 +#define RTL8367C_GLOBAL_RESET_OFFSET 11 +#define RTL8367C_GLOBAL_RESET_MASK 0x800 +#define RTL8367C_QM_RESET_OFFSET 10 +#define RTL8367C_QM_RESET_MASK 0x400 +#define RTL8367C_PORT7_RESET_OFFSET 9 +#define RTL8367C_PORT7_RESET_MASK 0x200 +#define RTL8367C_PORT6_RESET_OFFSET 8 +#define RTL8367C_PORT6_RESET_MASK 0x100 +#define RTL8367C_PORT5_RESET_OFFSET 7 +#define RTL8367C_PORT5_RESET_MASK 0x80 +#define RTL8367C_PORT4_RESET_OFFSET 6 +#define RTL8367C_PORT4_RESET_MASK 0x40 +#define RTL8367C_PORT3_RESET_OFFSET 5 +#define RTL8367C_PORT3_RESET_MASK 0x20 +#define RTL8367C_PORT2_RESET_OFFSET 4 +#define RTL8367C_PORT2_RESET_MASK 0x10 +#define RTL8367C_PORT1_RESET_OFFSET 3 +#define RTL8367C_PORT1_RESET_MASK 0x8 +#define RTL8367C_PORT0_RESET_OFFSET 2 +#define RTL8367C_PORT0_RESET_MASK 0x4 +#define RTL8367C_RESET_FLAG_OFFSET 1 +#define RTL8367C_RESET_FLAG_MASK 0x2 +#define RTL8367C_MIB_CTRL0_BUSY_FLAG_OFFSET 0 +#define RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL1 0x1007 +#define RTL8367C_COUNTER15_RESET_OFFSET 15 +#define RTL8367C_COUNTER15_RESET_MASK 0x8000 +#define RTL8367C_COUNTER14_RESET_OFFSET 14 +#define RTL8367C_COUNTER14_RESET_MASK 0x4000 +#define RTL8367C_COUNTER13_RESET_OFFSET 13 +#define RTL8367C_COUNTER13_RESET_MASK 0x2000 +#define RTL8367C_COUNTER12_RESET_OFFSET 12 +#define RTL8367C_COUNTER12_RESET_MASK 0x1000 +#define RTL8367C_COUNTER11_RESET_OFFSET 11 +#define RTL8367C_COUNTER11_RESET_MASK 0x800 +#define RTL8367C_COUNTER10_RESET_OFFSET 10 +#define RTL8367C_COUNTER10_RESET_MASK 0x400 +#define RTL8367C_COUNTER9_RESET_OFFSET 9 +#define RTL8367C_COUNTER9_RESET_MASK 0x200 +#define RTL8367C_COUNTER8_RESET_OFFSET 8 +#define RTL8367C_COUNTER8_RESET_MASK 0x100 +#define RTL8367C_COUNTER7_RESET_OFFSET 7 +#define RTL8367C_COUNTER7_RESET_MASK 0x80 +#define RTL8367C_COUNTER6_RESET_OFFSET 6 +#define RTL8367C_COUNTER6_RESET_MASK 0x40 +#define RTL8367C_COUNTER5_RESET_OFFSET 5 +#define RTL8367C_COUNTER5_RESET_MASK 0x20 +#define RTL8367C_COUNTER4_RESET_OFFSET 4 +#define RTL8367C_COUNTER4_RESET_MASK 0x10 +#define RTL8367C_COUNTER3_RESET_OFFSET 3 +#define RTL8367C_COUNTER3_RESET_MASK 0x8 +#define RTL8367C_COUNTER2_RESET_OFFSET 2 +#define RTL8367C_COUNTER2_RESET_MASK 0x4 +#define RTL8367C_COUNTER1_RESET_OFFSET 1 +#define RTL8367C_COUNTER1_RESET_MASK 0x2 +#define RTL8367C_COUNTER0_RESET_OFFSET 0 +#define RTL8367C_COUNTER0_RESET_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL2 0x1008 +#define RTL8367C_COUNTER31_RESET_OFFSET 15 +#define RTL8367C_COUNTER31_RESET_MASK 0x8000 +#define RTL8367C_COUNTER30_RESET_OFFSET 14 +#define RTL8367C_COUNTER30_RESET_MASK 0x4000 +#define RTL8367C_COUNTER29_RESET_OFFSET 13 +#define RTL8367C_COUNTER29_RESET_MASK 0x2000 +#define RTL8367C_COUNTER28_RESET_OFFSET 12 +#define RTL8367C_COUNTER28_RESET_MASK 0x1000 +#define RTL8367C_COUNTER27_RESET_OFFSET 11 +#define RTL8367C_COUNTER27_RESET_MASK 0x800 +#define RTL8367C_COUNTER26_RESET_OFFSET 10 +#define RTL8367C_COUNTER26_RESET_MASK 0x400 +#define RTL8367C_COUNTER25_RESET_OFFSET 9 +#define RTL8367C_COUNTER25_RESET_MASK 0x200 +#define RTL8367C_COUNTER24_RESET_OFFSET 8 +#define RTL8367C_COUNTER24_RESET_MASK 0x100 +#define RTL8367C_COUNTER23_RESET_OFFSET 7 +#define RTL8367C_COUNTER23_RESET_MASK 0x80 +#define RTL8367C_COUNTER22_RESET_OFFSET 6 +#define RTL8367C_COUNTER22_RESET_MASK 0x40 +#define RTL8367C_COUNTER21_RESET_OFFSET 5 +#define RTL8367C_COUNTER21_RESET_MASK 0x20 +#define RTL8367C_COUNTER20_RESET_OFFSET 4 +#define RTL8367C_COUNTER20_RESET_MASK 0x10 +#define RTL8367C_COUNTER19_RESET_OFFSET 3 +#define RTL8367C_COUNTER19_RESET_MASK 0x8 +#define RTL8367C_COUNTER18_RESET_OFFSET 2 +#define RTL8367C_COUNTER18_RESET_MASK 0x4 +#define RTL8367C_COUNTER17_RESET_OFFSET 1 +#define RTL8367C_COUNTER17_RESET_MASK 0x2 +#define RTL8367C_COUNTER16_RESET_OFFSET 0 +#define RTL8367C_COUNTER16_RESET_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL3 0x1009 +#define RTL8367C_COUNTER15_MODE_OFFSET 15 +#define RTL8367C_COUNTER15_MODE_MASK 0x8000 +#define RTL8367C_COUNTER14_MODE_OFFSET 14 +#define RTL8367C_COUNTER14_MODE_MASK 0x4000 +#define RTL8367C_COUNTER13_MODE_OFFSET 13 +#define RTL8367C_COUNTER13_MODE_MASK 0x2000 +#define RTL8367C_COUNTER12_MODE_OFFSET 12 +#define RTL8367C_COUNTER12_MODE_MASK 0x1000 +#define RTL8367C_COUNTER11_MODE_OFFSET 11 +#define RTL8367C_COUNTER11_MODE_MASK 0x800 +#define RTL8367C_COUNTER10_MODE_OFFSET 10 +#define RTL8367C_COUNTER10_MODE_MASK 0x400 +#define RTL8367C_COUNTER9_MODE_OFFSET 9 +#define RTL8367C_COUNTER9_MODE_MASK 0x200 +#define RTL8367C_COUNTER8_MODE_OFFSET 8 +#define RTL8367C_COUNTER8_MODE_MASK 0x100 +#define RTL8367C_COUNTER7_MODE_OFFSET 7 +#define RTL8367C_COUNTER7_MODE_MASK 0x80 +#define RTL8367C_COUNTER6_MODE_OFFSET 6 +#define RTL8367C_COUNTER6_MODE_MASK 0x40 +#define RTL8367C_COUNTER5_MODE_OFFSET 5 +#define RTL8367C_COUNTER5_MODE_MASK 0x20 +#define RTL8367C_COUNTER4_MODE_OFFSET 4 +#define RTL8367C_COUNTER4_MODE_MASK 0x10 +#define RTL8367C_COUNTER3_MODE_OFFSET 3 +#define RTL8367C_COUNTER3_MODE_MASK 0x8 +#define RTL8367C_COUNTER2_MODE_OFFSET 2 +#define RTL8367C_COUNTER2_MODE_MASK 0x4 +#define RTL8367C_COUNTER1_MODE_OFFSET 1 +#define RTL8367C_COUNTER1_MODE_MASK 0x2 +#define RTL8367C_COUNTER0_MODE_OFFSET 0 +#define RTL8367C_COUNTER0_MODE_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL4 0x100a +#define RTL8367C_MIB_USAGE_MODE_OFFSET 8 +#define RTL8367C_MIB_USAGE_MODE_MASK 0x100 +#define RTL8367C_MIB_TIMER_OFFSET 0 +#define RTL8367C_MIB_TIMER_MASK 0xFF + +#define RTL8367C_REG_MIB_CTRL5 0x100b +#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_OFFSET 15 +#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_MASK 0x8000 +#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_OFFSET 14 +#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_MASK 0x4000 +#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_OFFSET 13 +#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_MASK 0x2000 +#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_OFFSET 12 +#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_MASK 0x1000 +#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_OFFSET 11 +#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_MASK 0x800 +#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_OFFSET 10 +#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_MASK 0x400 +#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_OFFSET 9 +#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_MASK 0x200 +#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_OFFSET 8 +#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_MASK 0x100 +#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_OFFSET 7 +#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_MASK 0x80 +#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_OFFSET 6 +#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_MASK 0x40 +#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_OFFSET 5 +#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_MASK 0x20 +#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_OFFSET 4 +#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_MASK 0x10 +#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_OFFSET 3 +#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_MASK 0x8 +#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_OFFSET 2 +#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_MASK 0x4 +#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_OFFSET 1 +#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_MASK 0x2 +#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_OFFSET 0 +#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_MASK 0x1 + +/* (16'h1100)intrpt_reg */ + +#define RTL8367C_REG_INTR_CTRL 0x1100 +#define RTL8367C_INTR_CTRL_OFFSET 0 +#define RTL8367C_INTR_CTRL_MASK 0x1 + +#define RTL8367C_REG_INTR_IMR 0x1101 +#define RTL8367C_INTR_IMR_SLIENT_START_2_OFFSET 12 +#define RTL8367C_INTR_IMR_SLIENT_START_2_MASK 0x1000 +#define RTL8367C_INTR_IMR_SLIENT_START_OFFSET 11 +#define RTL8367C_INTR_IMR_SLIENT_START_MASK 0x800 +#define RTL8367C_INTR_IMR_ACL_ACTION_OFFSET 9 +#define RTL8367C_INTR_IMR_ACL_ACTION_MASK 0x200 +#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_OFFSET 8 +#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_MASK 0x100 +#define RTL8367C_INTR_IMR_INTERRUPT_8051_OFFSET 7 +#define RTL8367C_INTR_IMR_INTERRUPT_8051_MASK 0x80 +#define RTL8367C_INTR_IMR_LOOP_DETECTION_OFFSET 6 +#define RTL8367C_INTR_IMR_LOOP_DETECTION_MASK 0x40 +#define RTL8367C_INTR_IMR_GREEN_TIMER_OFFSET 5 +#define RTL8367C_INTR_IMR_GREEN_TIMER_MASK 0x20 +#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_OFFSET 4 +#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_MASK 0x10 +#define RTL8367C_INTR_IMR_SPEED_CHANGE_OFFSET 3 +#define RTL8367C_INTR_IMR_SPEED_CHANGE_MASK 0x8 +#define RTL8367C_INTR_IMR_LEARN_OVER_OFFSET 2 +#define RTL8367C_INTR_IMR_LEARN_OVER_MASK 0x4 +#define RTL8367C_INTR_IMR_METER_EXCEEDED_OFFSET 1 +#define RTL8367C_INTR_IMR_METER_EXCEEDED_MASK 0x2 +#define RTL8367C_INTR_IMR_LINK_CHANGE_OFFSET 0 +#define RTL8367C_INTR_IMR_LINK_CHANGE_MASK 0x1 + +#define RTL8367C_REG_INTR_IMS 0x1102 +#define RTL8367C_INTR_IMS_SLIENT_START_2_OFFSET 12 +#define RTL8367C_INTR_IMS_SLIENT_START_2_MASK 0x1000 +#define RTL8367C_INTR_IMS_SLIENT_START_OFFSET 11 +#define RTL8367C_INTR_IMS_SLIENT_START_MASK 0x800 +#define RTL8367C_INTR_IMS_ACL_ACTION_OFFSET 9 +#define RTL8367C_INTR_IMS_ACL_ACTION_MASK 0x200 +#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_OFFSET 8 +#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_MASK 0x100 +#define RTL8367C_INTR_IMS_INTERRUPT_8051_OFFSET 7 +#define RTL8367C_INTR_IMS_INTERRUPT_8051_MASK 0x80 +#define RTL8367C_INTR_IMS_LOOP_DETECTION_OFFSET 6 +#define RTL8367C_INTR_IMS_LOOP_DETECTION_MASK 0x40 +#define RTL8367C_INTR_IMS_GREEN_TIMER_OFFSET 5 +#define RTL8367C_INTR_IMS_GREEN_TIMER_MASK 0x20 +#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_OFFSET 4 +#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_MASK 0x10 +#define RTL8367C_INTR_IMS_SPEED_CHANGE_OFFSET 3 +#define RTL8367C_INTR_IMS_SPEED_CHANGE_MASK 0x8 +#define RTL8367C_INTR_IMS_LEARN_OVER_OFFSET 2 +#define RTL8367C_INTR_IMS_LEARN_OVER_MASK 0x4 +#define RTL8367C_INTR_IMS_METER_EXCEEDED_OFFSET 1 +#define RTL8367C_INTR_IMS_METER_EXCEEDED_MASK 0x2 +#define RTL8367C_INTR_IMS_LINK_CHANGE_OFFSET 0 +#define RTL8367C_INTR_IMS_LINK_CHANGE_MASK 0x1 + +#define RTL8367C_REG_LEARN_OVER_INDICATOR 0x1103 +#define RTL8367C_LEARN_OVER_INDICATOR_OFFSET 0 +#define RTL8367C_LEARN_OVER_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_SPEED_CHANGE_INDICATOR 0x1104 +#define RTL8367C_SPEED_CHANGE_INDICATOR_OFFSET 0 +#define RTL8367C_SPEED_CHANGE_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR 0x1105 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_OFFSET 0 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR 0x1106 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_OFFSET 0 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKUP_INDICATOR 0x1107 +#define RTL8367C_PORT_LINKUP_INDICATOR_OFFSET 0 +#define RTL8367C_PORT_LINKUP_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR 0x1108 +#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_OFFSET 0 +#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_MASK 0x1 + +#define RTL8367C_REG_INTR_IMR_8051 0x1118 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_OFFSET 13 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_MASK 0x2000 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_OFFSET 12 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_MASK 0x1000 +#define RTL8367C_INTR_IMR_8051_ACL_ACTION_OFFSET 10 +#define RTL8367C_INTR_IMR_8051_ACL_ACTION_MASK 0x400 +#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_OFFSET 9 +#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_MASK 0x200 +#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_OFFSET 8 +#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_MASK 0x100 +#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_OFFSET 7 +#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_MASK 0x80 +#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_OFFSET 6 +#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_MASK 0x40 +#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_OFFSET 5 +#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_MASK 0x20 +#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_OFFSET 4 +#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_MASK 0x10 +#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_OFFSET 3 +#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_MASK 0x8 +#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_OFFSET 2 +#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_MASK 0x4 +#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_OFFSET 1 +#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_MASK 0x2 +#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_OFFSET 0 +#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_MASK 0x1 + +#define RTL8367C_REG_INTR_IMS_8051 0x1119 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_OFFSET 13 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_MASK 0x2000 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_OFFSET 12 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_MASK 0x1000 +#define RTL8367C_INTR_IMS_8051_ACL_ACTION_OFFSET 10 +#define RTL8367C_INTR_IMS_8051_ACL_ACTION_MASK 0x400 +#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_OFFSET 9 +#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_MASK 0x200 +#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_OFFSET 8 +#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_MASK 0x100 +#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_OFFSET 7 +#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_MASK 0x80 +#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_OFFSET 6 +#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_MASK 0x40 +#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_OFFSET 5 +#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_MASK 0x20 +#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_OFFSET 4 +#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_MASK 0x10 +#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_OFFSET 3 +#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_MASK 0x8 +#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_OFFSET 2 +#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_MASK 0x4 +#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_OFFSET 1 +#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_MASK 0x2 +#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_OFFSET 0 +#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_MASK 0x1 + +#define RTL8367C_REG_DW8051_INT_CPU 0x111a +#define RTL8367C_DW8051_INT_CPU_OFFSET 0 +#define RTL8367C_DW8051_INT_CPU_MASK 0x1 + +#define RTL8367C_REG_LEARN_OVER_INDICATOR_8051 0x1120 +#define RTL8367C_LEARN_OVER_INDICATOR_8051_OFFSET 0 +#define RTL8367C_LEARN_OVER_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_SPEED_CHANGE_INDICATOR_8051 0x1121 +#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_OFFSET 0 +#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR_8051 0x1122 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_OFFSET 0 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR_8051 0x1123 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_OFFSET 0 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKUP_INDICATOR_8051 0x1124 +#define RTL8367C_PORT_LINKUP_INDICATOR_8051_OFFSET 0 +#define RTL8367C_PORT_LINKUP_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_DUMMY_1125 0x1125 + +#define RTL8367C_REG_DUMMY_1126 0x1126 + +#define RTL8367C_REG_DUMMY_1127 0x1127 + +#define RTL8367C_REG_DUMMY_1128 0x1128 + +#define RTL8367C_REG_DUMMY_1129 0x1129 + +#define RTL8367C_REG_INTR_IMS_BUFFER_RESET 0x112a +#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 +#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 +#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_OFFSET 0 +#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_MASK 0x1 + +#define RTL8367C_REG_INTR_IMS_8051_BUFFER_RESET 0x112b +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_OFFSET 0 +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_MASK 0x1 + +#define RTL8367C_REG_GPHY_INTRPT_8051 0x112c +#define RTL8367C_IMS_GPHY_8051_H_OFFSET 13 +#define RTL8367C_IMS_GPHY_8051_H_MASK 0xE000 +#define RTL8367C_IMR_GPHY_8051_H_OFFSET 10 +#define RTL8367C_IMR_GPHY_8051_H_MASK 0x1C00 +#define RTL8367C_IMS_GPHY_8051_OFFSET 5 +#define RTL8367C_IMS_GPHY_8051_MASK 0x3E0 +#define RTL8367C_IMR_GPHY_8051_OFFSET 0 +#define RTL8367C_IMR_GPHY_8051_MASK 0x1F + +#define RTL8367C_REG_GPHY_INTRPT 0x112d +#define RTL8367C_IMS_GPHY_H_OFFSET 13 +#define RTL8367C_IMS_GPHY_H_MASK 0xE000 +#define RTL8367C_IMR_GPHY_H_OFFSET 10 +#define RTL8367C_IMR_GPHY_H_MASK 0x1C00 +#define RTL8367C_IMS_GPHY_OFFSET 5 +#define RTL8367C_IMS_GPHY_MASK 0x3E0 +#define RTL8367C_IMR_GPHY_OFFSET 0 +#define RTL8367C_IMR_GPHY_MASK 0x1F + +#define RTL8367C_REG_THERMAL_INTRPT 0x112e +#define RTL8367C_IMS_TM_HIGH_OFFSET 3 +#define RTL8367C_IMS_TM_HIGH_MASK 0x8 +#define RTL8367C_IMR_TM_HIGH_OFFSET 2 +#define RTL8367C_IMR_TM_HIGH_MASK 0x4 +#define RTL8367C_IMS_TM_LOW_OFFSET 1 +#define RTL8367C_IMS_TM_LOW_MASK 0x2 +#define RTL8367C_IMR_TM_LOW_OFFSET 0 +#define RTL8367C_IMR_TM_LOW_MASK 0x1 + +#define RTL8367C_REG_THERMAL_INTRPT_8051 0x112f +#define RTL8367C_IMS_TM_HIGH_8051_OFFSET 3 +#define RTL8367C_IMS_TM_HIGH_8051_MASK 0x8 +#define RTL8367C_IMR_TM_HIGH_8051_OFFSET 2 +#define RTL8367C_IMR_TM_HIGH_8051_MASK 0x4 +#define RTL8367C_IMS_TM_LOW_8051_OFFSET 1 +#define RTL8367C_IMS_TM_LOW_8051_MASK 0x2 +#define RTL8367C_IMR_TM_LOW_8051_OFFSET 0 +#define RTL8367C_IMR_TM_LOW_8051_MASK 0x1 + +#define RTL8367C_REG_SDS_LINK_CHG_INT 0x1130 +#define RTL8367C_IMS_SDS_LINK_STS_C7_OFFSET 15 +#define RTL8367C_IMS_SDS_LINK_STS_C7_MASK 0x8000 +#define RTL8367C_IMS_SDS_LINK_STS_C6_OFFSET 14 +#define RTL8367C_IMS_SDS_LINK_STS_C6_MASK 0x4000 +#define RTL8367C_IMS_SDS_LINK_STS_C5_OFFSET 13 +#define RTL8367C_IMS_SDS_LINK_STS_C5_MASK 0x2000 +#define RTL8367C_IMS_SDS_LINK_STS_C4_OFFSET 12 +#define RTL8367C_IMS_SDS_LINK_STS_C4_MASK 0x1000 +#define RTL8367C_IMS_SDS_LINK_STS_C3_OFFSET 11 +#define RTL8367C_IMS_SDS_LINK_STS_C3_MASK 0x800 +#define RTL8367C_IMS_SDS_LINK_STS_C2_OFFSET 10 +#define RTL8367C_IMS_SDS_LINK_STS_C2_MASK 0x400 +#define RTL8367C_IMS_SDS_LINK_STS_C1_OFFSET 9 +#define RTL8367C_IMS_SDS_LINK_STS_C1_MASK 0x200 +#define RTL8367C_IMS_SDS_LINK_STS_C0_OFFSET 8 +#define RTL8367C_IMS_SDS_LINK_STS_C0_MASK 0x100 +#define RTL8367C_IMR_SDS_LINK_STS_C7_OFFSET 7 +#define RTL8367C_IMR_SDS_LINK_STS_C7_MASK 0x80 +#define RTL8367C_IMR_SDS_LINK_STS_C6_OFFSET 6 +#define RTL8367C_IMR_SDS_LINK_STS_C6_MASK 0x40 +#define RTL8367C_IMR_SDS_LINK_STS_C5_OFFSET 5 +#define RTL8367C_IMR_SDS_LINK_STS_C5_MASK 0x20 +#define RTL8367C_IMR_SDS_LINK_STS_C4_OFFSET 4 +#define RTL8367C_IMR_SDS_LINK_STS_C4_MASK 0x10 +#define RTL8367C_IMR_SDS_LINK_STS_C3_OFFSET 3 +#define RTL8367C_IMR_SDS_LINK_STS_C3_MASK 0x8 +#define RTL8367C_IMR_SDS_LINK_STS_C2_OFFSET 2 +#define RTL8367C_IMR_SDS_LINK_STS_C2_MASK 0x4 +#define RTL8367C_IMR_SDS_LINK_STS_C1_OFFSET 1 +#define RTL8367C_IMR_SDS_LINK_STS_C1_MASK 0x2 +#define RTL8367C_IMR_SDS_LINK_STS_C0_OFFSET 0 +#define RTL8367C_IMR_SDS_LINK_STS_C0_MASK 0x1 + +#define RTL8367C_REG_SDS_LINK_CHG_INT_8051 0x1131 +#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_OFFSET 15 +#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_MASK 0x8000 +#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_OFFSET 14 +#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_MASK 0x4000 +#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_OFFSET 13 +#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_MASK 0x2000 +#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_OFFSET 12 +#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_MASK 0x1000 +#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_OFFSET 11 +#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_MASK 0x800 +#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_OFFSET 10 +#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_MASK 0x400 +#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_OFFSET 9 +#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_MASK 0x200 +#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_OFFSET 8 +#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_MASK 0x100 +#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_OFFSET 7 +#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_MASK 0x80 +#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_OFFSET 6 +#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_MASK 0x40 +#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_OFFSET 5 +#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_MASK 0x20 +#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_OFFSET 4 +#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_MASK 0x10 +#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_OFFSET 3 +#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_MASK 0x8 +#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_OFFSET 2 +#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_MASK 0x4 +#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_OFFSET 1 +#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_MASK 0x2 +#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_OFFSET 0 +#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_MASK 0x1 + +/* (16'h1200)swcore_reg */ + +#define RTL8367C_REG_MAX_LENGTH_LIMINT_IPG 0x1200 +#define RTL8367C_MAX_LENTH_CTRL_OFFSET 13 +#define RTL8367C_MAX_LENTH_CTRL_MASK 0x6000 +#define RTL8367C_PAGES_BEFORE_FCDROP_OFFSET 6 +#define RTL8367C_PAGES_BEFORE_FCDROP_MASK 0x1FC0 +#define RTL8367C_CHECK_MIN_IPG_RXDV_OFFSET 5 +#define RTL8367C_CHECK_MIN_IPG_RXDV_MASK 0x20 +#define RTL8367C_LIMIT_IPG_CFG_OFFSET 0 +#define RTL8367C_LIMIT_IPG_CFG_MASK 0x1F + +#define RTL8367C_REG_IOL_RXDROP_CFG 0x1201 +#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_OFFSET 13 +#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_MASK 0x2000 +#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_OFFSET 12 +#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_MASK 0x1000 +#define RTL8367C_RX_NODROP_PAUSE_CFG_OFFSET 8 +#define RTL8367C_RX_NODROP_PAUSE_CFG_MASK 0x100 +#define RTL8367C_RX_DV_CNT_CFG_OFFSET 0 +#define RTL8367C_RX_DV_CNT_CFG_MASK 0x3F + +#define RTL8367C_REG_VS_TPID 0x1202 + +#define RTL8367C_REG_INBW_BOUND 0x1203 +#define RTL8367C_LBOUND_OFFSET 4 +#define RTL8367C_LBOUND_MASK 0xF0 +#define RTL8367C_HBOUND_OFFSET 0 +#define RTL8367C_HBOUND_MASK 0xF + +#define RTL8367C_REG_CFG_TX_ITFSP_OP 0x1204 +#define RTL8367C_MASK_OFFSET 1 +#define RTL8367C_MASK_MASK 0x2 +#define RTL8367C_OP_OFFSET 0 +#define RTL8367C_OP_MASK 0x1 + +#define RTL8367C_REG_INBW_BOUND2 0x1205 +#define RTL8367C_LBOUND2_H_OFFSET 9 +#define RTL8367C_LBOUND2_H_MASK 0x200 +#define RTL8367C_HBOUND2_H_OFFSET 8 +#define RTL8367C_HBOUND2_H_MASK 0x100 +#define RTL8367C_LBOUND2_OFFSET 4 +#define RTL8367C_LBOUND2_MASK 0xF0 +#define RTL8367C_HBOUND2_OFFSET 0 +#define RTL8367C_HBOUND2_MASK 0xF + +#define RTL8367C_REG_CFG_48PASS1_DROP 0x1206 +#define RTL8367C_CFG_48PASS1_DROP_OFFSET 0 +#define RTL8367C_CFG_48PASS1_DROP_MASK 0x1 + +#define RTL8367C_REG_CFG_BACKPRESSURE 0x1207 +#define RTL8367C_LONGTXE_OFFSET 12 +#define RTL8367C_LONGTXE_MASK 0x1000 +#define RTL8367C_EN_BYPASS_ERROR_OFFSET 8 +#define RTL8367C_EN_BYPASS_ERROR_MASK 0x100 +#define RTL8367C_EN_BACKPRESSURE_OFFSET 4 +#define RTL8367C_EN_BACKPRESSURE_MASK 0x10 +#define RTL8367C_EN_48_PASS_1_OFFSET 0 +#define RTL8367C_EN_48_PASS_1_MASK 0x1 + +#define RTL8367C_REG_CFG_UNHIOL 0x1208 +#define RTL8367C_IOL_BACKOFF_OFFSET 12 +#define RTL8367C_IOL_BACKOFF_MASK 0x1000 +#define RTL8367C_BACKOFF_RANDOM_TIME_OFFSET 8 +#define RTL8367C_BACKOFF_RANDOM_TIME_MASK 0x100 +#define RTL8367C_DISABLE_BACK_OFF_OFFSET 4 +#define RTL8367C_DISABLE_BACK_OFF_MASK 0x10 +#define RTL8367C_IPG_COMPENSATION_OFFSET 0 +#define RTL8367C_IPG_COMPENSATION_MASK 0x1 + +#define RTL8367C_REG_SWITCH_MAC0 0x1209 + +#define RTL8367C_REG_SWITCH_MAC1 0x120a + +#define RTL8367C_REG_SWITCH_MAC2 0x120b + +#define RTL8367C_REG_SWITCH_CTRL0 0x120c +#define RTL8367C_REMARKING_DSCP_ENABLE_OFFSET 8 +#define RTL8367C_REMARKING_DSCP_ENABLE_MASK 0x100 +#define RTL8367C_SHORT_IPG_OFFSET 4 +#define RTL8367C_SHORT_IPG_MASK 0x10 +#define RTL8367C_PAUSE_MAX128_OFFSET 0 +#define RTL8367C_PAUSE_MAX128_MASK 0x1 + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 0x120d +#define RTL8367C_INTPRI1_DSCP_OFFSET 8 +#define RTL8367C_INTPRI1_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI0_DSCP_OFFSET 0 +#define RTL8367C_INTPRI0_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL1 0x120e +#define RTL8367C_INTPRI3_DSCP_OFFSET 8 +#define RTL8367C_INTPRI3_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI2_DSCP_OFFSET 0 +#define RTL8367C_INTPRI2_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL2 0x120f +#define RTL8367C_INTPRI5_DSCP_OFFSET 8 +#define RTL8367C_INTPRI5_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI4_DSCP_OFFSET 0 +#define RTL8367C_INTPRI4_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL3 0x1210 +#define RTL8367C_INTPRI7_DSCP_OFFSET 8 +#define RTL8367C_INTPRI7_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI6_DSCP_OFFSET 0 +#define RTL8367C_INTPRI6_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_1Q_REMARK_CTRL0 0x1211 +#define RTL8367C_INTPRI3_PRI_OFFSET 12 +#define RTL8367C_INTPRI3_PRI_MASK 0x7000 +#define RTL8367C_INTPRI2_PRI_OFFSET 8 +#define RTL8367C_INTPRI2_PRI_MASK 0x700 +#define RTL8367C_INTPRI1_PRI_OFFSET 4 +#define RTL8367C_INTPRI1_PRI_MASK 0x70 +#define RTL8367C_INTPRI0_PRI_OFFSET 0 +#define RTL8367C_INTPRI0_PRI_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_REMARK_CTRL1 0x1212 +#define RTL8367C_INTPRI7_PRI_OFFSET 12 +#define RTL8367C_INTPRI7_PRI_MASK 0x7000 +#define RTL8367C_INTPRI6_PRI_OFFSET 8 +#define RTL8367C_INTPRI6_PRI_MASK 0x700 +#define RTL8367C_INTPRI5_PRI_OFFSET 4 +#define RTL8367C_INTPRI5_PRI_MASK 0x70 +#define RTL8367C_INTPRI4_PRI_OFFSET 0 +#define RTL8367C_INTPRI4_PRI_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_COMMAND 0x1213 +#define RTL8367C_PKTGEN_STOP_OFFSET 8 +#define RTL8367C_PKTGEN_STOP_MASK 0x100 +#define RTL8367C_PKTGEN_START_OFFSET 4 +#define RTL8367C_PKTGEN_START_MASK 0x10 +#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_OFFSET 0 +#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_MASK 0x1 + +#define RTL8367C_REG_SW_DUMMY0 0x1214 +#define RTL8367C_SW_DUMMY0_DUMMY_OFFSET 4 +#define RTL8367C_SW_DUMMY0_DUMMY_MASK 0xFFF0 +#define RTL8367C_EEE_DEFER_TXLPI_OFFSET 3 +#define RTL8367C_EEE_DEFER_TXLPI_MASK 0x8 +#define RTL8367C_INGRESSBW_BYPASS_EN_OFFSET 2 +#define RTL8367C_INGRESSBW_BYPASS_EN_MASK 0x4 +#define RTL8367C_CFG_RX_MIN_OFFSET 0 +#define RTL8367C_CFG_RX_MIN_MASK 0x3 + +#define RTL8367C_REG_SW_DUMMY1 0x1215 + +#define RTL8367C_REG_PKTGEN_PAUSE_TIME 0x1216 + +#define RTL8367C_REG_SVLAN_UPLINK_PORTMASK 0x1218 +#define RTL8367C_SVLAN_UPLINK_PORTMASK_OFFSET 0 +#define RTL8367C_SVLAN_UPLINK_PORTMASK_MASK 0x7FF + +#define RTL8367C_REG_CPU_PORT_MASK 0x1219 +#define RTL8367C_CPU_PORT_MASK_OFFSET 0 +#define RTL8367C_CPU_PORT_MASK_MASK 0x7FF + +#define RTL8367C_REG_CPU_CTRL 0x121a +#define RTL8367C_CPU_TRAP_PORT_EXT_OFFSET 10 +#define RTL8367C_CPU_TRAP_PORT_EXT_MASK 0x400 +#define RTL8367C_CPU_TAG_FORMAT_OFFSET 9 +#define RTL8367C_CPU_TAG_FORMAT_MASK 0x200 +#define RTL8367C_IOL_16DROP_OFFSET 8 +#define RTL8367C_IOL_16DROP_MASK 0x100 +#define RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET 7 +#define RTL8367C_CPU_TAG_RXBYTECOUNT_MASK 0x80 +#define RTL8367C_CPU_TAG_POSITION_OFFSET 6 +#define RTL8367C_CPU_TAG_POSITION_MASK 0x40 +#define RTL8367C_CPU_TRAP_PORT_OFFSET 3 +#define RTL8367C_CPU_TRAP_PORT_MASK 0x38 +#define RTL8367C_CPU_INSERTMODE_OFFSET 1 +#define RTL8367C_CPU_INSERTMODE_MASK 0x6 +#define RTL8367C_CPU_EN_OFFSET 0 +#define RTL8367C_CPU_EN_MASK 0x1 + +#define RTL8367C_REG_MIRROR_CTRL 0x121c +#define RTL8367C_MIRROR_CTRL_DUMMY_OFFSET 12 +#define RTL8367C_MIRROR_CTRL_DUMMY_MASK 0xF000 +#define RTL8367C_MIRROR_ISO_OFFSET 11 +#define RTL8367C_MIRROR_ISO_MASK 0x800 +#define RTL8367C_MIRROR_TX_OFFSET 10 +#define RTL8367C_MIRROR_TX_MASK 0x400 +#define RTL8367C_MIRROR_RX_OFFSET 9 +#define RTL8367C_MIRROR_RX_MASK 0x200 +#define RTL8367C_MIRROR_MONITOR_PORT_OFFSET 4 +#define RTL8367C_MIRROR_MONITOR_PORT_MASK 0xF0 +#define RTL8367C_MIRROR_SOURCE_PORT_OFFSET 0 +#define RTL8367C_MIRROR_SOURCE_PORT_MASK 0xF + +#define RTL8367C_REG_FLOWCTRL_CTRL0 0x121d +#define RTL8367C_FLOWCTRL_TYPE_OFFSET 15 +#define RTL8367C_FLOWCTRL_TYPE_MASK 0x8000 +#define RTL8367C_DROP_ALL_THRESHOLD_OFFSET 5 +#define RTL8367C_DROP_ALL_THRESHOLD_MASK 0x7FE0 +#define RTL8367C_DROP_ALL_THRESHOLD_MSB_OFFSET 4 +#define RTL8367C_DROP_ALL_THRESHOLD_MSB_MASK 0x10 +#define RTL8367C_ITFSP_REG_OFFSET 0 +#define RTL8367C_ITFSP_REG_MASK 0x7 + +#define RTL8367C_REG_FLOWCTRL_ALL_ON 0x121e +#define RTL8367C_CFG_RLDPACT_OFFSET 12 +#define RTL8367C_CFG_RLDPACT_MASK 0x1000 +#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_OFFSET 0 +#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SYS_ON 0x121f +#define RTL8367C_FLOWCTRL_SYS_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_SYS_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SYS_OFF 0x1220 +#define RTL8367C_FLOWCTRL_SYS_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_SYS_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SHARE_ON 0x1221 +#define RTL8367C_FLOWCTRL_SHARE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_SHARE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SHARE_OFF 0x1222 +#define RTL8367C_FLOWCTRL_SHARE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_SHARE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON 0x1223 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF 0x1224 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON 0x1225 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF 0x1226 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_ON 0x1227 +#define RTL8367C_FLOWCTRL_PORT_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_OFF 0x1228 +#define RTL8367C_FLOWCTRL_PORT_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON 0x1229 +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF 0x122a +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK 0x7FF + +#define RTL8367C_REG_RRCP_CTRL0 0x122b +#define RTL8367C_COL_SEL_OFFSET 14 +#define RTL8367C_COL_SEL_MASK 0x4000 +#define RTL8367C_CRS_SEL_OFFSET 13 +#define RTL8367C_CRS_SEL_MASK 0x2000 +#define RTL8367C_RRCP_PBVLAN_EN_OFFSET 11 +#define RTL8367C_RRCP_PBVLAN_EN_MASK 0x800 +#define RTL8367C_RRCPV3_SECURITY_CRC_OFFSET 10 +#define RTL8367C_RRCPV3_SECURITY_CRC_MASK 0x400 +#define RTL8367C_RRCPV3_HANDLE_OFFSET 8 +#define RTL8367C_RRCPV3_HANDLE_MASK 0x300 +#define RTL8367C_RRCPV1_MALFORMED_ACT_OFFSET 5 +#define RTL8367C_RRCPV1_MALFORMED_ACT_MASK 0x60 +#define RTL8367C_RRCP_VLANLEAKY_OFFSET 4 +#define RTL8367C_RRCP_VLANLEAKY_MASK 0x10 +#define RTL8367C_RRCPV1_SECURITY_CRC_GET_OFFSET 3 +#define RTL8367C_RRCPV1_SECURITY_CRC_GET_MASK 0x8 +#define RTL8367C_RRCPV1_SECURITY_CRC_SET_OFFSET 2 +#define RTL8367C_RRCPV1_SECURITY_CRC_SET_MASK 0x4 +#define RTL8367C_RRCPV1_HANDLE_OFFSET 1 +#define RTL8367C_RRCPV1_HANDLE_MASK 0x2 +#define RTL8367C_RRCP_ENABLE_OFFSET 0 +#define RTL8367C_RRCP_ENABLE_MASK 0x1 + +#define RTL8367C_REG_RRCP_CTRL1 0x122c +#define RTL8367C_RRCP_ADMIN_PMSK_OFFSET 8 +#define RTL8367C_RRCP_ADMIN_PMSK_MASK 0xFF00 +#define RTL8367C_RRCP_AUTH_PMSK_OFFSET 0 +#define RTL8367C_RRCP_AUTH_PMSK_MASK 0xFF + +#define RTL8367C_REG_RRCP_CTRL2 0x122d +#define RTL8367C_RRCPV1_HELLOFWD_TAG_OFFSET 9 +#define RTL8367C_RRCPV1_HELLOFWD_TAG_MASK 0x600 +#define RTL8367C_RRCP_FWD_TAG_OFFSET 7 +#define RTL8367C_RRCP_FWD_TAG_MASK 0x180 +#define RTL8367C_RRCPV1_REPLY_TAG_OFFSET 6 +#define RTL8367C_RRCPV1_REPLY_TAG_MASK 0x40 +#define RTL8367C_RRCPV1_HELLO_COUNT_OFFSET 3 +#define RTL8367C_RRCPV1_HELLO_COUNT_MASK 0x38 +#define RTL8367C_RRCPV1_HELLO_PEDIOD_OFFSET 0 +#define RTL8367C_RRCPV1_HELLO_PEDIOD_MASK 0x3 + +#define RTL8367C_REG_RRCP_CTRL3 0x122e +#define RTL8367C_RRCP_TAG_PRIORITY_OFFSET 13 +#define RTL8367C_RRCP_TAG_PRIORITY_MASK 0xE000 +#define RTL8367C_RRCP_TAG_VID_OFFSET 0 +#define RTL8367C_RRCP_TAG_VID_MASK 0xFFF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON 0x122f +#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF 0x1230 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON 0x1231 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF 0x1232 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON 0x1233 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF 0x1234 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON 0x1235 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF 0x1236 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON 0x1237 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF 0x1238 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON 0x1239 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF 0x123a +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SIZE 0x123b +#define RTL8367C_JUMBO_MODE_OFFSET 2 +#define RTL8367C_JUMBO_MODE_MASK 0x4 +#define RTL8367C_JUMBO_SIZE_OFFSET 0 +#define RTL8367C_JUMBO_SIZE_MASK 0x3 + +#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER 0x124c +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER 0x124d +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX 0x124e +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX 0x124f +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER 0x1250 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_COUNTER 0x1251 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_COUNTER 0x1252 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_COUNTER 0x1253 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_COUNTER 0x1254 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_COUNTER 0x1255 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_COUNTER 0x1256 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_COUNTER 0x1257 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER 0x1258 +#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER 0x1259 +#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER 0x125a +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER 0x125b +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX 0x1260 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_MAX 0x1261 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_MAX 0x1262 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_MAX 0x1263 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_MAX 0x1264 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_MAX 0x1265 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_MAX 0x1266 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_MAX 0x1267 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PAGE_COUNT_CLEAR 0x1268 +#define RTL8367C_DIS_SKIP_FP_OFFSET 1 +#define RTL8367C_DIS_SKIP_FP_MASK 0x2 +#define RTL8367C_PAGE_COUNT_CLEAR_OFFSET 0 +#define RTL8367C_PAGE_COUNT_CLEAR_MASK 0x1 + +#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_MAX 0x1269 +#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_MAX 0x126a +#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_MAX 0x126b +#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER 0x126c +#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_COUNTER 0x126d +#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_COUNTER 0x126e +#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_RRCP_CTRL1_H 0x126f +#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_OFFSET 3 +#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_MASK 0x38 +#define RTL8367C_RRCP_AUTH_PMSK_P10_8_OFFSET 0 +#define RTL8367C_RRCP_AUTH_PMSK_P10_8_MASK 0x7 + +#define RTL8367C_REG_EMA_CTRL0 0x1270 +#define RTL8367C_CFG_DVSE_VIAROM_OFFSET 13 +#define RTL8367C_CFG_DVSE_VIAROM_MASK 0x2000 +#define RTL8367C_CFG_DVSE_MIBRAM_OFFSET 12 +#define RTL8367C_CFG_DVSE_MIBRAM_MASK 0x1000 +#define RTL8367C_CFG_DVSE_IROM_OFFSET 11 +#define RTL8367C_CFG_DVSE_IROM_MASK 0x800 +#define RTL8367C_CFG_DVSE_ERAM_OFFSET 10 +#define RTL8367C_CFG_DVSE_ERAM_MASK 0x400 +#define RTL8367C_CFG_DVSE_IRAM_OFFSET 9 +#define RTL8367C_CFG_DVSE_IRAM_MASK 0x200 +#define RTL8367C_CFG_DVSE_NICRAM_OFFSET 8 +#define RTL8367C_CFG_DVSE_NICRAM_MASK 0x100 +#define RTL8367C_CFG_DVSE_CVLANRAM_OFFSET 7 +#define RTL8367C_CFG_DVSE_CVLANRAM_MASK 0x80 +#define RTL8367C_CFG_DVSE_ACTRAM_OFFSET 6 +#define RTL8367C_CFG_DVSE_ACTRAM_MASK 0x40 +#define RTL8367C_CFG_DVSE_INQRAM_OFFSET 5 +#define RTL8367C_CFG_DVSE_INQRAM_MASK 0x20 +#define RTL8367C_CFG_DVSE_HSARAM_OFFSET 4 +#define RTL8367C_CFG_DVSE_HSARAM_MASK 0x10 +#define RTL8367C_CFG_DVSE_OUTQRAM_OFFSET 3 +#define RTL8367C_CFG_DVSE_OUTQRAM_MASK 0x8 +#define RTL8367C_CFG_DVSE_HTRAM_OFFSET 2 +#define RTL8367C_CFG_DVSE_HTRAM_MASK 0x4 +#define RTL8367C_CFG_DVSE_PBRAM_OFFSET 1 +#define RTL8367C_CFG_DVSE_PBRAM_MASK 0x2 +#define RTL8367C_CFG_DVSE_L2RAM_OFFSET 0 +#define RTL8367C_CFG_DVSE_L2RAM_MASK 0x1 + +#define RTL8367C_REG_EMA_CTRL1 0x1271 +#define RTL8367C_CFG_DVS_OUTQRAM_OFFSET 12 +#define RTL8367C_CFG_DVS_OUTQRAM_MASK 0xF000 +#define RTL8367C_CFG_DVS_HTRAM_OFFSET 8 +#define RTL8367C_CFG_DVS_HTRAM_MASK 0x700 +#define RTL8367C_CFG_DVS_PBRAM_OFFSET 4 +#define RTL8367C_CFG_DVS_PBRAM_MASK 0xF0 +#define RTL8367C_CFG_DVS_L2RAM_OFFSET 0 +#define RTL8367C_CFG_DVS_L2RAM_MASK 0xF + +#define RTL8367C_REG_EMA_CTRL2 0x1272 +#define RTL8367C_CFG_DVS_CVLANRAM_OFFSET 12 +#define RTL8367C_CFG_DVS_CVLANRAM_MASK 0xF000 +#define RTL8367C_CFG_DVS_ACTRAM_OFFSET 8 +#define RTL8367C_CFG_DVS_ACTRAM_MASK 0xF00 +#define RTL8367C_CFG_DVS_INQRAM_OFFSET 4 +#define RTL8367C_CFG_DVS_INQRAM_MASK 0xF0 +#define RTL8367C_CFG_DVS_HSARAM_OFFSET 0 +#define RTL8367C_CFG_DVS_HSARAM_MASK 0xF + +#define RTL8367C_REG_EMA_CTRL3 0x1273 +#define RTL8367C_CFG_DVS_IROM_OFFSET 12 +#define RTL8367C_CFG_DVS_IROM_MASK 0xF000 +#define RTL8367C_CFG_DVS_ERAM_OFFSET 8 +#define RTL8367C_CFG_DVS_ERAM_MASK 0xF00 +#define RTL8367C_CFG_DVS_IRAM_OFFSET 4 +#define RTL8367C_CFG_DVS_IRAM_MASK 0xF0 +#define RTL8367C_CFG_DVS_NICRAM_OFFSET 0 +#define RTL8367C_CFG_DVS_NICRAM_MASK 0xF + +#define RTL8367C_REG_EMA_CTRL4 0x1274 +#define RTL8367C_CFG_DVS_VIAROM_OFFSET 4 +#define RTL8367C_CFG_DVS_VIAROM_MASK 0xF0 +#define RTL8367C_CFG_DVS_MIBRAM_OFFSET 0 +#define RTL8367C_CFG_DVS_MIBRAM_MASK 0xF + +#define RTL8367C_REG_DIAG_MODE 0x1275 +#define RTL8367C_DIAG_MODE_OFFSET 0 +#define RTL8367C_DIAG_MODE_MASK 0x1F + +#define RTL8367C_REG_BIST_MODE 0x1276 + +#define RTL8367C_REG_STS_BIST_DONE 0x1277 + +#define RTL8367C_REG_STS_BIST_RLT0 0x1278 +#define RTL8367C_STS_BIST_RLT0_OFFSET 0 +#define RTL8367C_STS_BIST_RLT0_MASK 0x1 + +#define RTL8367C_REG_STS_BIST_RLT1 0x1279 + +#define RTL8367C_REG_STS_BIST_RLT2 0x127a + +#define RTL8367C_REG_STS_BIST_RLT3 0x127b +#define RTL8367C_STS_BIST_RLT3_OFFSET 0 +#define RTL8367C_STS_BIST_RLT3_MASK 0x3FF + +#define RTL8367C_REG_STS_BIST_RLT4 0x127c +#define RTL8367C_STS_BIST_RLT4_OFFSET 0 +#define RTL8367C_STS_BIST_RLT4_MASK 0x7 + +#define RTL8367C_REG_VIAROM_MISR 0x127d + +#define RTL8367C_REG_DRF_BIST_MODE 0x1280 +#define RTL8367C_DRF_TCAMDEL_OFFSET 15 +#define RTL8367C_DRF_TCAMDEL_MASK 0x8000 +#define RTL8367C_CFG_DRF_BIST_MODE_OFFSET 0 +#define RTL8367C_CFG_DRF_BIST_MODE_MASK 0x7FFF + +#define RTL8367C_REG_STS_DRF_BIST 0x1281 +#define RTL8367C_STS_DRF_BIST_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_MASK 0x7FFF + +#define RTL8367C_REG_STS_DRF_BIST_RLT0 0x1282 +#define RTL8367C_STS_DRF_BIST_RLT0_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_RLT0_MASK 0x1 + +#define RTL8367C_REG_STS_DRF_BIST_RLT1 0x1283 + +#define RTL8367C_REG_STS_DRF_BIST_RLT2 0x1284 + +#define RTL8367C_REG_STS_DRF_BIST_RLT3 0x1285 +#define RTL8367C_STS_DRF_BIST_RLT3_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_RLT3_MASK 0x3FF + +#define RTL8367C_REG_STS_DRF_BIST_RLT4 0x1286 +#define RTL8367C_STS_DRF_BIST_RLT4_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_RLT4_MASK 0x7FFF + +#define RTL8367C_REG_RAM_DRF_CTRL 0x1289 +#define RTL8367C_RAM_DRF_CTRL_OFFSET 0 +#define RTL8367C_RAM_DRF_CTRL_MASK 0x1 + +#define RTL8367C_REG_MIB_RMON_LEN_CTRL 0x128a +#define RTL8367C_RX_LENGTH_CTRL_OFFSET 1 +#define RTL8367C_RX_LENGTH_CTRL_MASK 0x2 +#define RTL8367C_TX_LENGTH_CTRL_OFFSET 0 +#define RTL8367C_TX_LENGTH_CTRL_MASK 0x1 + +#define RTL8367C_REG_COND0_BISR_OUT0 0x1290 + +#define RTL8367C_REG_COND0_BISR_OUT1 0x1291 + +#define RTL8367C_REG_COND0_BISR_OUT2 0x1292 + +#define RTL8367C_REG_COND0_BISR_OUT3 0x1293 + +#define RTL8367C_REG_COND0_BISR_OUT4 0x1294 +#define RTL8367C_COND0_BISR_OUT4_OFFSET 0 +#define RTL8367C_COND0_BISR_OUT4_MASK 0x3F + +#define RTL8367C_REG_COND0_BISR_OUT5 0x1295 +#define RTL8367C_COND0_BISR_OUT5_OFFSET 0 +#define RTL8367C_COND0_BISR_OUT5_MASK 0x7 + +#define RTL8367C_REG_CHG_DUPLEX_CFG 0x1296 +#define RTL8367C_CHG_COL_CNT_PORT_OFFSET 13 +#define RTL8367C_CHG_COL_CNT_PORT_MASK 0xE000 +#define RTL8367C_CHG_COL_CNT_OFFSET 8 +#define RTL8367C_CHG_COL_CNT_MASK 0x1F00 +#define RTL8367C_CFG_CHG_DUP_EN_OFFSET 7 +#define RTL8367C_CFG_CHG_DUP_EN_MASK 0x80 +#define RTL8367C_CFG_CHG_DUP_THR_OFFSET 2 +#define RTL8367C_CFG_CHG_DUP_THR_MASK 0x7C +#define RTL8367C_CFG_CHG_DUP_CONGEST_OFFSET 1 +#define RTL8367C_CFG_CHG_DUP_CONGEST_MASK 0x2 +#define RTL8367C_CFG_CHG_DUP_REF_OFFSET 0 +#define RTL8367C_CFG_CHG_DUP_REF_MASK 0x1 + +#define RTL8367C_REG_COND0_BIST_PASS 0x1297 +#define RTL8367C_COND0_DRF_BIST_NOFAIL_OFFSET 1 +#define RTL8367C_COND0_DRF_BIST_NOFAIL_MASK 0x2 +#define RTL8367C_COND0_BIST_NOFAIL_OFFSET 0 +#define RTL8367C_COND0_BIST_NOFAIL_MASK 0x1 + +#define RTL8367C_REG_COND1_BISR_OUT0 0x1298 + +#define RTL8367C_REG_COND1_BISR_OUT1 0x1299 + +#define RTL8367C_REG_COND1_BISR_OUT2 0x129a + +#define RTL8367C_REG_COND1_BISR_OUT3 0x129b + +#define RTL8367C_REG_COND1_BISR_OUT4 0x129c +#define RTL8367C_COND1_BISR_OUT4_OFFSET 0 +#define RTL8367C_COND1_BISR_OUT4_MASK 0x3F + +#define RTL8367C_REG_COND1_BISR_OUT5 0x129d +#define RTL8367C_COND1_BISR_OUT5_OFFSET 0 +#define RTL8367C_COND1_BISR_OUT5_MASK 0x7 + +#define RTL8367C_REG_COND1_BIST_PASS 0x129f +#define RTL8367C_COND1_DRF_BIST_NOFAIL_OFFSET 1 +#define RTL8367C_COND1_DRF_BIST_NOFAIL_MASK 0x2 +#define RTL8367C_COND1_BIST_NOFAIL_OFFSET 0 +#define RTL8367C_COND1_BIST_NOFAIL_MASK 0x1 + +#define RTL8367C_REG_EEE_TX_THR_Giga_500M 0x12a0 + +#define RTL8367C_REG_EEE_TX_THR_FE 0x12a1 + +#define RTL8367C_REG_EEE_MISC 0x12a3 +#define RTL8367C_EEE_REQ_SET1_OFFSET 13 +#define RTL8367C_EEE_REQ_SET1_MASK 0x2000 +#define RTL8367C_EEE_REQ_SET0_OFFSET 12 +#define RTL8367C_EEE_REQ_SET0_MASK 0x1000 +#define RTL8367C_EEE_WAKE_SET1_OFFSET 9 +#define RTL8367C_EEE_WAKE_SET1_MASK 0x200 +#define RTL8367C_EEE_Wake_SET0_OFFSET 8 +#define RTL8367C_EEE_Wake_SET0_MASK 0x100 +#define RTL8367C_EEE_TU_GIGA_500M_OFFSET 4 +#define RTL8367C_EEE_TU_GIGA_500M_MASK 0x30 +#define RTL8367C_EEE_TU_100M_OFFSET 2 +#define RTL8367C_EEE_TU_100M_MASK 0xC + +#define RTL8367C_REG_EEE_GIGA_CTRL0 0x12a4 +#define RTL8367C_EEE_TW_GIGA_OFFSET 8 +#define RTL8367C_EEE_TW_GIGA_MASK 0xFF00 +#define RTL8367C_EEE_TR_GIGA_500M_OFFSET 0 +#define RTL8367C_EEE_TR_GIGA_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_GIGA_CTRL1 0x12a5 +#define RTL8367C_EEE_TD_GIGA_500M_OFFSET 8 +#define RTL8367C_EEE_TD_GIGA_500M_MASK 0xFF00 +#define RTL8367C_EEE_TP_GIGA_OFFSET 0 +#define RTL8367C_EEE_TP_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEE_100M_CTRL0 0x12a6 +#define RTL8367C_EEE_TW_100M_OFFSET 8 +#define RTL8367C_EEE_TW_100M_MASK 0xFF00 +#define RTL8367C_EEE_TR_100M_OFFSET 0 +#define RTL8367C_EEE_TR_100M_MASK 0xFF + +#define RTL8367C_REG_EEE_100M_CTRL1 0x12a7 +#define RTL8367C_EEE_TD_100M_OFFSET 8 +#define RTL8367C_EEE_TD_100M_MASK 0xFF00 +#define RTL8367C_EEE_TP_100M_OFFSET 0 +#define RTL8367C_EEE_TP_100M_MASK 0xFF + +#define RTL8367C_REG_RX_FC_REG 0x12aa +#define RTL8367C_EN_EEE_HALF_DUP_OFFSET 8 +#define RTL8367C_EN_EEE_HALF_DUP_MASK 0x100 +#define RTL8367C_RX_PGCNT_OFFSET 0 +#define RTL8367C_RX_PGCNT_MASK 0xFF + +#define RTL8367C_REG_MAX_FIFO_SIZE 0x12af +#define RTL8367C_MAX_FIFO_SIZE_OFFSET 0 +#define RTL8367C_MAX_FIFO_SIZE_MASK 0xF + +#define RTL8367C_REG_EEEP_RX_RATE_GIGA 0x12b0 + +#define RTL8367C_REG_EEEP_RX_RATE_100M 0x12b1 + +#define RTL8367C_REG_DUMMY_REG_12_2 0x12b2 + +#define RTL8367C_REG_EEEP_TX_RATE_GIGA 0x12b3 + +#define RTL8367C_REG_EEEP_TX_RATE_100M 0x12b4 + +#define RTL8367C_REG_DUMMY_REG_12_3 0x12b5 + +#define RTL8367C_REG_EEEP_GIGA_CTRL0 0x12b6 +#define RTL8367C_EEEP_TR_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TR_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_RW_GIGA_MST_OFFSET 0 +#define RTL8367C_EEEP_RW_GIGA_MST_MASK 0xFF + +#define RTL8367C_REG_EEEP_GIGA_CTRL1 0x12b7 +#define RTL8367C_EEEP_TW_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TW_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_TP_GIGA_OFFSET 0 +#define RTL8367C_EEEP_TP_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEEP_GIGA_CTRL2 0x12b8 +#define RTL8367C_EEEP_TXEN_GIGA_OFFSET 12 +#define RTL8367C_EEEP_TXEN_GIGA_MASK 0x1000 +#define RTL8367C_EEEP_TU_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TU_GIGA_MASK 0x300 +#define RTL8367C_EEEP_TS_GIGA_OFFSET 0 +#define RTL8367C_EEEP_TS_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEEP_100M_CTRL0 0x12b9 +#define RTL8367C_EEEP_TR_100M_OFFSET 8 +#define RTL8367C_EEEP_TR_100M_MASK 0xFF00 +#define RTL8367C_EEEP_RW_100M_OFFSET 0 +#define RTL8367C_EEEP_RW_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_100M_CTRL1 0x12ba +#define RTL8367C_EEEP_TW_100M_OFFSET 8 +#define RTL8367C_EEEP_TW_100M_MASK 0xFF00 +#define RTL8367C_EEEP_TP_100M_OFFSET 0 +#define RTL8367C_EEEP_TP_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_100M_CTRL2 0x12bb +#define RTL8367C_EEEP_TXEN_100M_OFFSET 12 +#define RTL8367C_EEEP_TXEN_100M_MASK 0x1000 +#define RTL8367C_EEEP_TU_100M_OFFSET 8 +#define RTL8367C_EEEP_TU_100M_MASK 0x300 +#define RTL8367C_EEEP_TS_100M_OFFSET 0 +#define RTL8367C_EEEP_TS_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_CTRL0 0x12bc +#define RTL8367C_EEEP_CTRL0_DUMMY_OFFSET 8 +#define RTL8367C_EEEP_CTRL0_DUMMY_MASK 0xFF00 +#define RTL8367C_EEEP_SLEEP_STEP_OFFSET 0 +#define RTL8367C_EEEP_SLEEP_STEP_MASK 0xFF + +#define RTL8367C_REG_EEEP_CTRL1 0x12bd +#define RTL8367C_EEEP_TXR_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TXR_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_TXR_100M_OFFSET 0 +#define RTL8367C_EEEP_TXR_100M_MASK 0xFF + +#define RTL8367C_REG_BACK_PRESSURE_IPG 0x12be +#define RTL8367C_BACK_PRESSURE_IPG_OFFSET 0 +#define RTL8367C_BACK_PRESSURE_IPG_MASK 0x3 + +#define RTL8367C_REG_TX_ESD_LEVEL 0x12bf +#define RTL8367C_TX_ESD_LEVEL_MODE_OFFSET 8 +#define RTL8367C_TX_ESD_LEVEL_MODE_MASK 0x100 +#define RTL8367C_LEVEL_OFFSET 0 +#define RTL8367C_LEVEL_MASK 0xFF + +#define RTL8367C_REG_RRCP_CTRL4 0x12e0 + +#define RTL8367C_REG_RRCP_CTRL5 0x12e1 + +#define RTL8367C_REG_RRCP_CTRL6 0x12e2 + +#define RTL8367C_REG_RRCP_CTRL7 0x12e3 + +#define RTL8367C_REG_RRCP_CTRL8 0x12e4 + +#define RTL8367C_REG_RRCP_CTRL9 0x12e5 + +#define RTL8367C_REG_RRCP_CTRL10 0x12e6 + +#define RTL8367C_REG_FIELD_SELECTOR0 0x12e7 +#define RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR0_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR0_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR1 0x12e8 +#define RTL8367C_FIELD_SELECTOR1_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR1_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR1_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR1_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR2 0x12e9 +#define RTL8367C_FIELD_SELECTOR2_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR2_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR2_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR2_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR3 0x12ea +#define RTL8367C_FIELD_SELECTOR3_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR3_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR3_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR3_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR4 0x12eb +#define RTL8367C_FIELD_SELECTOR4_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR4_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR4_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR4_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR5 0x12ec +#define RTL8367C_FIELD_SELECTOR5_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR5_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR5_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR5_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR6 0x12ed +#define RTL8367C_FIELD_SELECTOR6_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR6_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR6_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR6_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR7 0x12ee +#define RTL8367C_FIELD_SELECTOR7_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR7_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR7_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR7_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR8 0x12ef +#define RTL8367C_FIELD_SELECTOR8_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR8_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR8_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR8_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR9 0x12f0 +#define RTL8367C_FIELD_SELECTOR9_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR9_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR9_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR9_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR10 0x12f1 +#define RTL8367C_FIELD_SELECTOR10_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR10_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR10_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR10_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR11 0x12f2 +#define RTL8367C_FIELD_SELECTOR11_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR11_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR11_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR11_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR12 0x12f3 +#define RTL8367C_FIELD_SELECTOR12_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR12_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR12_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR12_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR13 0x12f4 +#define RTL8367C_FIELD_SELECTOR13_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR13_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR13_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR13_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR14 0x12f5 +#define RTL8367C_FIELD_SELECTOR14_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR14_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR14_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR14_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR15 0x12f6 +#define RTL8367C_FIELD_SELECTOR15_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR15_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR15_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR15_OFFSET_MASK 0xFF + +#define RTL8367C_REG_HWPKT_GEN_MISC_H 0x12f7 +#define RTL8367C_PKT_GEN_SUSPEND_P10_8_OFFSET 3 +#define RTL8367C_PKT_GEN_SUSPEND_P10_8_MASK 0x38 +#define RTL8367C_PKT_GEN_STATUS_P10_8_OFFSET 0 +#define RTL8367C_PKT_GEN_STATUS_P10_8_MASK 0x7 + +#define RTL8367C_REG_MIRROR_SRC_PMSK 0x12fb +#define RTL8367C_MIRROR_SRC_PMSK_OFFSET 0 +#define RTL8367C_MIRROR_SRC_PMSK_MASK 0x7FF + +#define RTL8367C_REG_EEE_BURSTSIZE 0x12fc + +#define RTL8367C_REG_EEE_IFG_CFG 0x12fd +#define RTL8367C_EEE_IFG_CFG_OFFSET 0 +#define RTL8367C_EEE_IFG_CFG_MASK 0x1 + +#define RTL8367C_REG_FPGA_VER_MAC 0x12fe + +#define RTL8367C_REG_HWPKT_GEN_MISC 0x12ff +#define RTL8367C_PKT_GEN_SUSPEND_OFFSET 8 +#define RTL8367C_PKT_GEN_SUSPEND_MASK 0xFF00 +#define RTL8367C_PKT_GEN_STATUS_OFFSET 0 +#define RTL8367C_PKT_GEN_STATUS_MASK 0xFF + +/* (16'h1300)chip_reg */ + +#define RTL8367C_REG_CHIP_NUMBER 0x1300 + +#define RTL8367C_REG_CHIP_VER 0x1301 +#define RTL8367C_VERID_OFFSET 12 +#define RTL8367C_VERID_MASK 0xF000 +#define RTL8367C_MCID_OFFSET 8 +#define RTL8367C_MCID_MASK 0xF00 +#define RTL8367C_MODEL_ID_OFFSET 4 +#define RTL8367C_MODEL_ID_MASK 0xF0 +#define RTL8367C_AFE_VERSION_OFFSET 0 +#define RTL8367C_AFE_VERSION_MASK 0x1 + +#define RTL8367C_REG_CHIP_DEBUG0 0x1303 +#define RTL8367C_SEL33_EXT2_OFFSET 10 +#define RTL8367C_SEL33_EXT2_MASK 0x400 +#define RTL8367C_SEL33_EXT1_OFFSET 9 +#define RTL8367C_SEL33_EXT1_MASK 0x200 +#define RTL8367C_SEL33_EXT0_OFFSET 8 +#define RTL8367C_SEL33_EXT0_MASK 0x100 +#define RTL8367C_DRI_OTHER_OFFSET 7 +#define RTL8367C_DRI_OTHER_MASK 0x80 +#define RTL8367C_DRI_EXT1_RG_OFFSET 6 +#define RTL8367C_DRI_EXT1_RG_MASK 0x40 +#define RTL8367C_DRI_EXT0_RG_OFFSET 5 +#define RTL8367C_DRI_EXT0_RG_MASK 0x20 +#define RTL8367C_DRI_EXT1_OFFSET 4 +#define RTL8367C_DRI_EXT1_MASK 0x10 +#define RTL8367C_DRI_EXT0_OFFSET 3 +#define RTL8367C_DRI_EXT0_MASK 0x8 +#define RTL8367C_SLR_OTHER_OFFSET 2 +#define RTL8367C_SLR_OTHER_MASK 0x4 +#define RTL8367C_SLR_EXT1_OFFSET 1 +#define RTL8367C_SLR_EXT1_MASK 0x2 +#define RTL8367C_SLR_EXT0_OFFSET 0 +#define RTL8367C_SLR_EXT0_MASK 0x1 + +#define RTL8367C_REG_CHIP_DEBUG1 0x1304 +#define RTL8367C_RG1_DN_OFFSET 12 +#define RTL8367C_RG1_DN_MASK 0x7000 +#define RTL8367C_RG1_DP_OFFSET 8 +#define RTL8367C_RG1_DP_MASK 0x700 +#define RTL8367C_RG0_DN_OFFSET 4 +#define RTL8367C_RG0_DN_MASK 0x70 +#define RTL8367C_RG0_DP_OFFSET 0 +#define RTL8367C_RG0_DP_MASK 0x7 + +#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT 0x1305 +#define RTL8367C_ORG_COL_OFFSET 15 +#define RTL8367C_ORG_COL_MASK 0x8000 +#define RTL8367C_ORG_CRS_OFFSET 14 +#define RTL8367C_ORG_CRS_MASK 0x4000 +#define RTL8367C_SKIP_MII_1_RXER_OFFSET 13 +#define RTL8367C_SKIP_MII_1_RXER_MASK 0x2000 +#define RTL8367C_SKIP_MII_0_RXER_OFFSET 12 +#define RTL8367C_SKIP_MII_0_RXER_MASK 0x1000 +#define RTL8367C_SELECT_GMII_1_OFFSET 4 +#define RTL8367C_SELECT_GMII_1_MASK 0xF0 +#define RTL8367C_SELECT_GMII_0_OFFSET 0 +#define RTL8367C_SELECT_GMII_0_MASK 0xF + +#define RTL8367C_REG_EXT0_RGMXF 0x1306 +#define RTL8367C_EXT0_RGTX_INV_OFFSET 6 +#define RTL8367C_EXT0_RGTX_INV_MASK 0x40 +#define RTL8367C_EXT0_RGRX_INV_OFFSET 5 +#define RTL8367C_EXT0_RGRX_INV_MASK 0x20 +#define RTL8367C_EXT0_RGMXF_OFFSET 0 +#define RTL8367C_EXT0_RGMXF_MASK 0x1F + +#define RTL8367C_REG_EXT1_RGMXF 0x1307 +#define RTL8367C_EXT1_RGTX_INV_OFFSET 6 +#define RTL8367C_EXT1_RGTX_INV_MASK 0x40 +#define RTL8367C_EXT1_RGRX_INV_OFFSET 5 +#define RTL8367C_EXT1_RGRX_INV_MASK 0x20 +#define RTL8367C_EXT1_RGMXF_OFFSET 0 +#define RTL8367C_EXT1_RGMXF_MASK 0x1F + +#define RTL8367C_REG_BISR_CTRL 0x1308 +#define RTL8367C_BISR_CTRL_OFFSET 0 +#define RTL8367C_BISR_CTRL_MASK 0x7 + +#define RTL8367C_REG_SLF_IF 0x1309 +#define RTL8367C_LINK_DOWN_CLR_FIFO_OFFSET 7 +#define RTL8367C_LINK_DOWN_CLR_FIFO_MASK 0x80 +#define RTL8367C_LOOPBACK_OFFSET 6 +#define RTL8367C_LOOPBACK_MASK 0x40 +#define RTL8367C_WATER_LEVEL_OFFSET 4 +#define RTL8367C_WATER_LEVEL_MASK 0x30 +#define RTL8367C_SLF_IF_OFFSET 0 +#define RTL8367C_SLF_IF_MASK 0x3 + +#define RTL8367C_REG_I2C_CLOCK_DIV 0x130a +#define RTL8367C_I2C_CLOCK_DIV_OFFSET 0 +#define RTL8367C_I2C_CLOCK_DIV_MASK 0x3FF + +#define RTL8367C_REG_MDX_MDC_DIV 0x130b +#define RTL8367C_MDX_MDC_DIV_OFFSET 0 +#define RTL8367C_MDX_MDC_DIV_MASK 0x3FF + +#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE0 0x130c +#define RTL8367C_ADCCKI_FROM_PAD_OFFSET 14 +#define RTL8367C_ADCCKI_FROM_PAD_MASK 0x4000 +#define RTL8367C_ADCCKI_EN_OFFSET 13 +#define RTL8367C_ADCCKI_EN_MASK 0x2000 +#define RTL8367C_FLASH_ENABLE_OFFSET 12 +#define RTL8367C_FLASH_ENABLE_MASK 0x1000 +#define RTL8367C_EEE_ENABLE_OFFSET 11 +#define RTL8367C_EEE_ENABLE_MASK 0x800 +#define RTL8367C_NIC_ENABLE_OFFSET 10 +#define RTL8367C_NIC_ENABLE_MASK 0x400 +#define RTL8367C_FT_ENABLE_OFFSET 9 +#define RTL8367C_FT_ENABLE_MASK 0x200 +#define RTL8367C_OLT_ENABLE_OFFSET 8 +#define RTL8367C_OLT_ENABLE_MASK 0x100 +#define RTL8367C_RTCT_EN_OFFSET 7 +#define RTL8367C_RTCT_EN_MASK 0x80 +#define RTL8367C_PON_LIGHT_EN_OFFSET 6 +#define RTL8367C_PON_LIGHT_EN_MASK 0x40 +#define RTL8367C_DW8051_EN_OFFSET 5 +#define RTL8367C_DW8051_EN_MASK 0x20 +#define RTL8367C_AUTOLOAD_EN_OFFSET 4 +#define RTL8367C_AUTOLOAD_EN_MASK 0x10 +#define RTL8367C_NRESTORE_EN_OFFSET 3 +#define RTL8367C_NRESTORE_EN_MASK 0x8 +#define RTL8367C_DIS_PON_TABLE_INIT_OFFSET 2 +#define RTL8367C_DIS_PON_TABLE_INIT_MASK 0x4 +#define RTL8367C_DIS_PON_BIST_OFFSET 1 +#define RTL8367C_DIS_PON_BIST_MASK 0x2 +#define RTL8367C_EFUSE_EN_OFFSET 0 +#define RTL8367C_EFUSE_EN_MASK 0x1 + +#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE1 0x130d +#define RTL8367C_EEPROM_DEV_ADR_OFFSET 8 +#define RTL8367C_EEPROM_DEV_ADR_MASK 0x7F00 +#define RTL8367C_EEPROM_MSB_OFFSET 7 +#define RTL8367C_EEPROM_MSB_MASK 0x80 +#define RTL8367C_EEPROM_ADDRESS_16B_OFFSET 6 +#define RTL8367C_EEPROM_ADDRESS_16B_MASK 0x40 +#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_OFFSET 3 +#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_MASK 0x8 +#define RTL8367C_SPI_SLAVE_EN_OFFSET 2 +#define RTL8367C_SPI_SLAVE_EN_MASK 0x4 +#define RTL8367C_SMI_SEL_OFFSET 0 +#define RTL8367C_SMI_SEL_MASK 0x3 + +#define RTL8367C_REG_PHY_AD 0x130f +#define RTL8367C_EN_PHY_MAX_POWER_OFFSET 14 +#define RTL8367C_EN_PHY_MAX_POWER_MASK 0x4000 +#define RTL8367C_EN_PHY_SEL_DEG_OFFSET 13 +#define RTL8367C_EN_PHY_SEL_DEG_MASK 0x2000 +#define RTL8367C_EXTPHY_AD_OFFSET 8 +#define RTL8367C_EXTPHY_AD_MASK 0x1F00 +#define RTL8367C_EN_PHY_LOW_POWER_MODE_OFFSET 7 +#define RTL8367C_EN_PHY_LOW_POWER_MODE_MASK 0x80 +#define RTL8367C_EN_PHY_GREEN_OFFSET 6 +#define RTL8367C_EN_PHY_GREEN_MASK 0x40 +#define RTL8367C_PDNPHY_OFFSET 5 +#define RTL8367C_PDNPHY_MASK 0x20 +#define RTL8367C_INTPHY_AD_OFFSET 0 +#define RTL8367C_INTPHY_AD_MASK 0x1F + +#define RTL8367C_REG_DIGITAL_INTERFACE0_FORCE 0x1310 +#define RTL8367C_GMII_0_FORCE_OFFSET 12 +#define RTL8367C_GMII_0_FORCE_MASK 0x1000 +#define RTL8367C_RGMII_0_FORCE_OFFSET 0 +#define RTL8367C_RGMII_0_FORCE_MASK 0xFFF + +#define RTL8367C_REG_DIGITAL_INTERFACE1_FORCE 0x1311 +#define RTL8367C_GMII_1_FORCE_OFFSET 12 +#define RTL8367C_GMII_1_FORCE_MASK 0x1000 +#define RTL8367C_RGMII_1_FORCE_OFFSET 0 +#define RTL8367C_RGMII_1_FORCE_MASK 0xFFF + +#define RTL8367C_REG_MAC0_FORCE_SELECT 0x1312 +#define RTL8367C_EN_MAC0_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC0_FORCE_MASK 0x1000 +#define RTL8367C_MAC0_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC0_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC1_FORCE_SELECT 0x1313 +#define RTL8367C_EN_MAC1_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC1_FORCE_MASK 0x1000 +#define RTL8367C_MAC1_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC1_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC2_FORCE_SELECT 0x1314 +#define RTL8367C_EN_MAC2_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC2_FORCE_MASK 0x1000 +#define RTL8367C_MAC2_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC2_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC3_FORCE_SELECT 0x1315 +#define RTL8367C_EN_MAC3_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC3_FORCE_MASK 0x1000 +#define RTL8367C_MAC3_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC3_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC4_FORCE_SELECT 0x1316 +#define RTL8367C_EN_MAC4_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC4_FORCE_MASK 0x1000 +#define RTL8367C_MAC4_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC4_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC5_FORCE_SELECT 0x1317 +#define RTL8367C_EN_MAC5_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC5_FORCE_MASK 0x1000 +#define RTL8367C_MAC5_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC5_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC6_FORCE_SELECT 0x1318 +#define RTL8367C_EN_MAC6_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC6_FORCE_MASK 0x1000 +#define RTL8367C_MAC6_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC6_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC7_FORCE_SELECT 0x1319 +#define RTL8367C_EN_MAC7_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC7_FORCE_MASK 0x1000 +#define RTL8367C_MAC7_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC7_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_M10_FORCE_SELECT 0x131c +#define RTL8367C_EN_M10_FORCE_OFFSET 12 +#define RTL8367C_EN_M10_FORCE_MASK 0x1000 +#define RTL8367C_M10_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_M10_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_CHIP_RESET 0x1322 +#define RTL8367C_GPHY_RESET_OFFSET 6 +#define RTL8367C_GPHY_RESET_MASK 0x40 +#define RTL8367C_NIC_RST_OFFSET 5 +#define RTL8367C_NIC_RST_MASK 0x20 +#define RTL8367C_DW8051_RST_OFFSET 4 +#define RTL8367C_DW8051_RST_MASK 0x10 +#define RTL8367C_SDS_RST_OFFSET 3 +#define RTL8367C_SDS_RST_MASK 0x8 +#define RTL8367C_CONFIG_RST_OFFSET 2 +#define RTL8367C_CONFIG_RST_MASK 0x4 +#define RTL8367C_SW_RST_OFFSET 1 +#define RTL8367C_SW_RST_MASK 0x2 +#define RTL8367C_CHIP_RST_OFFSET 0 +#define RTL8367C_CHIP_RST_MASK 0x1 + +#define RTL8367C_REG_DIGITAL_DEBUG_0 0x1323 + +#define RTL8367C_REG_DIGITAL_DEBUG_1 0x1324 + +#define RTL8367C_REG_INTERNAL_PHY_MDC_DRIVER 0x1325 +#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_OFFSET 0 +#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_MASK 0x3FF + +#define RTL8367C_REG_LINKDOWN_TIME_CTRL 0x1326 +#define RTL8367C_LINKDOWN_TIME_CFG_OFFSET 9 +#define RTL8367C_LINKDOWN_TIME_CFG_MASK 0x7E00 +#define RTL8367C_LINKDOWN_TIME_ENABLE_OFFSET 8 +#define RTL8367C_LINKDOWN_TIME_ENABLE_MASK 0x100 +#define RTL8367C_LINKDOWN_TIME_OFFSET 0 +#define RTL8367C_LINKDOWN_TIME_MASK 0xFF + +#define RTL8367C_REG_PHYACK_TIMEOUT 0x1331 + +#define RTL8367C_REG_MDXACK_TIMEOUT 0x1333 + +#define RTL8367C_REG_DW8051_RDY 0x1336 +#define RTL8367C_VIAROM_WRITE_EN_OFFSET 9 +#define RTL8367C_VIAROM_WRITE_EN_MASK 0x200 +#define RTL8367C_SPIF_CK2_OFFSET 8 +#define RTL8367C_SPIF_CK2_MASK 0x100 +#define RTL8367C_RRCP_MDOE_OFFSET 7 +#define RTL8367C_RRCP_MDOE_MASK 0x80 +#define RTL8367C_DW8051_RATE_OFFSET 4 +#define RTL8367C_DW8051_RATE_MASK 0x70 +#define RTL8367C_IROM_MSB_OFFSET 2 +#define RTL8367C_IROM_MSB_MASK 0xC +#define RTL8367C_ACS_IROM_ENABLE_OFFSET 1 +#define RTL8367C_ACS_IROM_ENABLE_MASK 0x2 +#define RTL8367C_DW8051_READY_OFFSET 0 +#define RTL8367C_DW8051_READY_MASK 0x1 + +#define RTL8367C_REG_BIST_CTRL 0x133c +#define RTL8367C_DRF_BIST_DONE_ALL_OFFSET 5 +#define RTL8367C_DRF_BIST_DONE_ALL_MASK 0x20 +#define RTL8367C_DRF_BIST_PAUSE_ALL_OFFSET 4 +#define RTL8367C_DRF_BIST_PAUSE_ALL_MASK 0x10 +#define RTL8367C_BIST_DOAN_ALL_OFFSET 3 +#define RTL8367C_BIST_DOAN_ALL_MASK 0x8 +#define RTL8367C_BIST_PASS_OFFSET 0 +#define RTL8367C_BIST_PASS_MASK 0x7 + +#define RTL8367C_REG_DIAG_MODE2 0x133d +#define RTL8367C_DIAG_MODE2_ACTRAM_OFFSET 1 +#define RTL8367C_DIAG_MODE2_ACTRAM_MASK 0x2 +#define RTL8367C_DIAG_MODE2_BCAM_ACTION_OFFSET 0 +#define RTL8367C_DIAG_MODE2_BCAM_ACTION_MASK 0x1 + +#define RTL8367C_REG_MDX_PHY_REG0 0x133e +#define RTL8367C_PHY_BRD_MASK_OFFSET 4 +#define RTL8367C_PHY_BRD_MASK_MASK 0x1F0 +#define RTL8367C_MDX_INDACC_PAGE_OFFSET 0 +#define RTL8367C_MDX_INDACC_PAGE_MASK 0xF + +#define RTL8367C_REG_MDX_PHY_REG1 0x133f +#define RTL8367C_PHY_BRD_MODE_OFFSET 5 +#define RTL8367C_PHY_BRD_MODE_MASK 0x20 +#define RTL8367C_BRD_PHYAD_OFFSET 0 +#define RTL8367C_BRD_PHYAD_MASK 0x1F + +#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_SW 0x1340 + +#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_B 0x1341 +#define RTL8367C_DEBUG_MX_OFFSET 9 +#define RTL8367C_DEBUG_MX_MASK 0xE00 +#define RTL8367C_DEBUG_SHIFT_MISC_OFFSET 6 +#define RTL8367C_DEBUG_SHIFT_MISC_MASK 0x1C0 +#define RTL8367C_DEBUG_SHIFT_SW_OFFSET 3 +#define RTL8367C_DEBUG_SHIFT_SW_MASK 0x38 +#define RTL8367C_DEBUG_SHIFT_GPHY_OFFSET 0 +#define RTL8367C_DEBUG_SHIFT_GPHY_MASK 0x7 + +#define RTL8367C_REG_DEBUG_SIGNAL_I 0x1343 + +#define RTL8367C_REG_DEBUG_SIGNAL_H 0x1344 + +#define RTL8367C_REG_DBGO_SEL_GPHY 0x1345 + +#define RTL8367C_REG_DBGO_SEL_MISC 0x1346 + +#define RTL8367C_REG_BYPASS_ABLTY_LOCK 0x1349 +#define RTL8367C_BYPASS_ABLTY_LOCK_OFFSET 0 +#define RTL8367C_BYPASS_ABLTY_LOCK_MASK 0xFF + +#define RTL8367C_REG_BYPASS_ABLTY_LOCK_EXT 0x134a +#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_OFFSET 3 +#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_MASK 0x8 +#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_OFFSET 0 +#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_MASK 0x7 + +#define RTL8367C_REG_ACL_GPIO 0x134f +#define RTL8367C_ACL_GPIO_13_OFFSET 13 +#define RTL8367C_ACL_GPIO_13_MASK 0x2000 +#define RTL8367C_ACL_GPIO_12_OFFSET 12 +#define RTL8367C_ACL_GPIO_12_MASK 0x1000 +#define RTL8367C_ACL_GPIO_11_OFFSET 11 +#define RTL8367C_ACL_GPIO_11_MASK 0x800 +#define RTL8367C_ACL_GPIO_10_OFFSET 10 +#define RTL8367C_ACL_GPIO_10_MASK 0x400 +#define RTL8367C_ACL_GPIO_9_OFFSET 9 +#define RTL8367C_ACL_GPIO_9_MASK 0x200 +#define RTL8367C_ACL_GPIO_8_OFFSET 8 +#define RTL8367C_ACL_GPIO_8_MASK 0x100 +#define RTL8367C_ACL_GPIO_7_OFFSET 7 +#define RTL8367C_ACL_GPIO_7_MASK 0x80 +#define RTL8367C_ACL_GPIO_6_OFFSET 6 +#define RTL8367C_ACL_GPIO_6_MASK 0x40 +#define RTL8367C_ACL_GPIO_5_OFFSET 5 +#define RTL8367C_ACL_GPIO_5_MASK 0x20 +#define RTL8367C_ACL_GPIO_4_OFFSET 4 +#define RTL8367C_ACL_GPIO_4_MASK 0x10 +#define RTL8367C_ACL_GPIO_3_OFFSET 3 +#define RTL8367C_ACL_GPIO_3_MASK 0x8 +#define RTL8367C_ACL_GPIO_2_OFFSET 2 +#define RTL8367C_ACL_GPIO_2_MASK 0x4 +#define RTL8367C_ACL_GPIO_1_OFFSET 1 +#define RTL8367C_ACL_GPIO_1_MASK 0x2 +#define RTL8367C_ACL_GPIO_0_OFFSET 0 +#define RTL8367C_ACL_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_EN_GPIO 0x1350 +#define RTL8367C_EN_GPIO_13_OFFSET 13 +#define RTL8367C_EN_GPIO_13_MASK 0x2000 +#define RTL8367C_EN_GPIO_12_OFFSET 12 +#define RTL8367C_EN_GPIO_12_MASK 0x1000 +#define RTL8367C_EN_GPIO_11_OFFSET 11 +#define RTL8367C_EN_GPIO_11_MASK 0x800 +#define RTL8367C_EN_GPIO_10_OFFSET 10 +#define RTL8367C_EN_GPIO_10_MASK 0x400 +#define RTL8367C_EN_GPIO_9_OFFSET 9 +#define RTL8367C_EN_GPIO_9_MASK 0x200 +#define RTL8367C_EN_GPIO_8_OFFSET 8 +#define RTL8367C_EN_GPIO_8_MASK 0x100 +#define RTL8367C_EN_GPIO_7_OFFSET 7 +#define RTL8367C_EN_GPIO_7_MASK 0x80 +#define RTL8367C_EN_GPIO_6_OFFSET 6 +#define RTL8367C_EN_GPIO_6_MASK 0x40 +#define RTL8367C_EN_GPIO_5_OFFSET 5 +#define RTL8367C_EN_GPIO_5_MASK 0x20 +#define RTL8367C_EN_GPIO_4_OFFSET 4 +#define RTL8367C_EN_GPIO_4_MASK 0x10 +#define RTL8367C_EN_GPIO_3_OFFSET 3 +#define RTL8367C_EN_GPIO_3_MASK 0x8 +#define RTL8367C_EN_GPIO_2_OFFSET 2 +#define RTL8367C_EN_GPIO_2_MASK 0x4 +#define RTL8367C_EN_GPIO_1_OFFSET 1 +#define RTL8367C_EN_GPIO_1_MASK 0x2 +#define RTL8367C_EN_GPIO_0_OFFSET 0 +#define RTL8367C_EN_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_CFG_MULTI_PIN 0x1351 +#define RTL8367C_CFG_MULTI_PIN_OFFSET 0 +#define RTL8367C_CFG_MULTI_PIN_MASK 0x3 + +#define RTL8367C_REG_PORT0_STATUS 0x1352 +#define RTL8367C_PORT0_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT0_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT0_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT0_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT0_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT0_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT0_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT0_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT0_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT0_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT0_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT0_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT1_STATUS 0x1353 +#define RTL8367C_PORT1_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT1_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT1_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT1_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT1_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT1_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT1_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT1_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT1_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT1_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT1_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT1_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT2_STATUS 0x1354 +#define RTL8367C_PORT2_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT2_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT2_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT2_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT2_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT2_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT2_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT2_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT2_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT2_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT2_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT2_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT3_STATUS 0x1355 +#define RTL8367C_PORT3_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT3_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT3_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT3_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT3_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT3_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT3_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT3_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT3_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT3_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT3_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT3_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT4_STATUS 0x1356 +#define RTL8367C_PORT4_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT4_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT4_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT4_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT4_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT4_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT4_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT4_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT4_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT4_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT4_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT4_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT5_STATUS 0x1357 +#define RTL8367C_PORT5_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT5_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT5_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT5_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT5_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT5_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT5_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT5_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT5_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT5_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT5_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT5_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT6_STATUS 0x1358 +#define RTL8367C_PORT6_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT6_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT6_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT6_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT6_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT6_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT6_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT6_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT6_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT6_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT6_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT6_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT7_STATUS 0x1359 +#define RTL8367C_PORT7_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT7_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT7_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT7_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT7_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT7_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT7_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT7_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT7_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT7_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT7_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT7_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT8_STATUS 0x135a +#define RTL8367C_PORT8_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT8_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT8_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT8_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT8_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT8_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT8_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT8_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT8_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT8_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT8_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT8_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT9_STATUS 0x135b +#define RTL8367C_PORT9_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT9_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT9_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT9_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT9_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT9_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT9_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT9_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT9_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT9_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT9_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT9_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT10_STATUS 0x135c +#define RTL8367C_PORT10_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT10_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT10_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT10_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT10_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT10_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT10_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT10_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT10_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT10_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT10_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT10_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_UPS_CTRL0 0x1362 +#define RTL8367C_P3_REF_SD_BIT0_OFFSET 8 +#define RTL8367C_P3_REF_SD_BIT0_MASK 0xFF00 +#define RTL8367C_P2_REF_SD_OFFSET 0 +#define RTL8367C_P2_REF_SD_MASK 0xFF + +#define RTL8367C_REG_UPS_CTRL1 0x1363 +#define RTL8367C_UPS_OUT_OFFSET 8 +#define RTL8367C_UPS_OUT_MASK 0xFF00 +#define RTL8367C_UPS_WRITE_PULSE_OFFSET 1 +#define RTL8367C_UPS_WRITE_PULSE_MASK 0x2 +#define RTL8367C_UPS_EN_OFFSET 0 +#define RTL8367C_UPS_EN_MASK 0x1 + +#define RTL8367C_REG_UPS_CTRL2 0x1364 +#define RTL8367C_IGNOE_MAC8_LINK_OFFSET 15 +#define RTL8367C_IGNOE_MAC8_LINK_MASK 0x8000 +#define RTL8367C_AGREE_SLEEP_OFFSET 14 +#define RTL8367C_AGREE_SLEEP_MASK 0x4000 +#define RTL8367C_WAIT_FOR_AGREEMENT_OFFSET 13 +#define RTL8367C_WAIT_FOR_AGREEMENT_MASK 0x2000 +#define RTL8367C_WAKE_UP_BY_LINK_OFFSET 12 +#define RTL8367C_WAKE_UP_BY_LINK_MASK 0x1000 +#define RTL8367C_WAKE_UP_BY_PHY_OFFSET 11 +#define RTL8367C_WAKE_UP_BY_PHY_MASK 0x800 +#define RTL8367C_SLOW_CLK_TGL_RATE_OFFSET 7 +#define RTL8367C_SLOW_CLK_TGL_RATE_MASK 0x780 +#define RTL8367C_PLL_G1_CTRL_EN_OFFSET 6 +#define RTL8367C_PLL_G1_CTRL_EN_MASK 0x40 +#define RTL8367C_PLL_G0_CTRL_EN_OFFSET 5 +#define RTL8367C_PLL_G0_CTRL_EN_MASK 0x20 +#define RTL8367C_SLOW_DOWN_PLL_EN_OFFSET 4 +#define RTL8367C_SLOW_DOWN_PLL_EN_MASK 0x10 +#define RTL8367C_SLOW_DOWN_CLK_EN_OFFSET 3 +#define RTL8367C_SLOW_DOWN_CLK_EN_MASK 0x8 +#define RTL8367C_GATING_CLK_SDS_EN_OFFSET 2 +#define RTL8367C_GATING_CLK_SDS_EN_MASK 0x4 +#define RTL8367C_GATING_CLK_CHIP_EN_OFFSET 1 +#define RTL8367C_GATING_CLK_CHIP_EN_MASK 0x2 +#define RTL8367C_GATING_SW_EN_OFFSET 0 +#define RTL8367C_GATING_SW_EN_MASK 0x1 + +#define RTL8367C_REG_GATING_CLK_1 0x1365 +#define RTL8367C_ALDPS_MODE_4_OFFSET 15 +#define RTL8367C_ALDPS_MODE_4_MASK 0x8000 +#define RTL8367C_ALDPS_MODE_3_OFFSET 14 +#define RTL8367C_ALDPS_MODE_3_MASK 0x4000 +#define RTL8367C_ALDPS_MODE_2_OFFSET 13 +#define RTL8367C_ALDPS_MODE_2_MASK 0x2000 +#define RTL8367C_ALDPS_MODE_1_OFFSET 12 +#define RTL8367C_ALDPS_MODE_1_MASK 0x1000 +#define RTL8367C_ALDPS_MODE_0_OFFSET 11 +#define RTL8367C_ALDPS_MODE_0_MASK 0x800 +#define RTL8367C_UPS_DBGO_OFFSET 10 +#define RTL8367C_UPS_DBGO_MASK 0x400 +#define RTL8367C_IFMX_AFF_NOT_FF_OUT_OFFSET 9 +#define RTL8367C_IFMX_AFF_NOT_FF_OUT_MASK 0x200 +#define RTL8367C_WATER_LEVEL_FD_OFFSET 6 +#define RTL8367C_WATER_LEVEL_FD_MASK 0x1C0 +#define RTL8367C_WATER_LEVEL_Y2X_OFFSET 3 +#define RTL8367C_WATER_LEVEL_Y2X_MASK 0x38 +#define RTL8367C_WATER_LEVEL_X2Y_2_OFFSET 2 +#define RTL8367C_WATER_LEVEL_X2Y_2_MASK 0x4 +#define RTL8367C_IGNOE_MAC10_LINK_OFFSET 1 +#define RTL8367C_IGNOE_MAC10_LINK_MASK 0x2 +#define RTL8367C_IGNOE_MAC9_LINK_OFFSET 0 +#define RTL8367C_IGNOE_MAC9_LINK_MASK 0x1 + +#define RTL8367C_REG_UPS_CTRL4 0x1366 +#define RTL8367C_PROB_EN_OFFSET 6 +#define RTL8367C_PROB_EN_MASK 0x40 +#define RTL8367C_PLL_DOWN_OFFSET 1 +#define RTL8367C_PLL_DOWN_MASK 0x2 +#define RTL8367C_XTAL_DOWN_OFFSET 0 +#define RTL8367C_XTAL_DOWN_MASK 0x1 + +#define RTL8367C_REG_UPS_CTRL5 0x1367 +#define RTL8367C_FRC_CPU_ACPT_OFFSET 3 +#define RTL8367C_FRC_CPU_ACPT_MASK 0x8 +#define RTL8367C_UPS_CPU_ACPT_OFFSET 2 +#define RTL8367C_UPS_CPU_ACPT_MASK 0x4 +#define RTL8367C_UPS_DBG_4_OFFSET 0 +#define RTL8367C_UPS_DBG_4_MASK 0x3 + +#define RTL8367C_REG_UPS_CTRL6 0x1368 +#define RTL8367C_UPS_CTRL6_OFFSET 0 +#define RTL8367C_UPS_CTRL6_MASK 0xF + +#define RTL8367C_REG_EFUSE_CMD_70B 0x1369 + +#define RTL8367C_REG_EFUSE_CMD 0x1370 +#define RTL8367C_EFUSE_TIME_OUT_FLAG_OFFSET 3 +#define RTL8367C_EFUSE_TIME_OUT_FLAG_MASK 0x8 +#define RTL8367C_EFUSE_ACCESS_BUSY_OFFSET 2 +#define RTL8367C_EFUSE_ACCESS_BUSY_MASK 0x4 +#define RTL8367C_EFUSE_COMMAND_EN_OFFSET 1 +#define RTL8367C_EFUSE_COMMAND_EN_MASK 0x2 +#define RTL8367C_EFUSE_WR_OFFSET 0 +#define RTL8367C_EFUSE_WR_MASK 0x1 + +#define RTL8367C_REG_EFUSE_ADR 0x1371 +#define RTL8367C_DUMMY_15_10_OFFSET 8 +#define RTL8367C_DUMMY_15_10_MASK 0xFF00 +#define RTL8367C_EFUSE_ADDRESS_OFFSET 0 +#define RTL8367C_EFUSE_ADDRESS_MASK 0xFF + +#define RTL8367C_REG_EFUSE_WDAT 0x1372 + +#define RTL8367C_REG_EFUSE_RDAT 0x1373 + +#define RTL8367C_REG_I2C_CTRL 0x1374 +#define RTL8367C_MDX_MST_FAIL_LAT_OFFSET 1 +#define RTL8367C_MDX_MST_FAIL_LAT_MASK 0x2 +#define RTL8367C_MDX_MST_FAIL_CLRPS_OFFSET 0 +#define RTL8367C_MDX_MST_FAIL_CLRPS_MASK 0x1 + +#define RTL8367C_REG_EEE_CFG 0x1375 +#define RTL8367C_CFG_BYPASS_GATELPTD_OFFSET 11 +#define RTL8367C_CFG_BYPASS_GATELPTD_MASK 0x800 +#define RTL8367C_EEE_ABT_ADDR2_OFFSET 6 +#define RTL8367C_EEE_ABT_ADDR2_MASK 0x7C0 +#define RTL8367C_EEE_ABT_ADDR1_OFFSET 1 +#define RTL8367C_EEE_ABT_ADDR1_MASK 0x3E +#define RTL8367C_EEE_POLL_EN_OFFSET 0 +#define RTL8367C_EEE_POLL_EN_MASK 0x1 + +#define RTL8367C_REG_EEE_PAGE 0x1376 + +#define RTL8367C_REG_EEE_EXT_PAGE 0x1377 + +#define RTL8367C_REG_EEE_EN_SPD1000 0x1378 + +#define RTL8367C_REG_EEE_EN_SPD100 0x1379 + +#define RTL8367C_REG_EEE_LP_SPD1000 0x137a + +#define RTL8367C_REG_EEE_LP_SPD100 0x137b + +#define RTL8367C_REG_DW8051_PRO_REG0 0x13a0 + +#define RTL8367C_REG_DW8051_PRO_REG1 0x13a1 + +#define RTL8367C_REG_DW8051_PRO_REG2 0x13a2 + +#define RTL8367C_REG_DW8051_PRO_REG3 0x13a3 + +#define RTL8367C_REG_DW8051_PRO_REG4 0x13a4 + +#define RTL8367C_REG_DW8051_PRO_REG5 0x13a5 + +#define RTL8367C_REG_DW8051_PRO_REG6 0x13a6 + +#define RTL8367C_REG_DW8051_PRO_REG7 0x13a7 + +#define RTL8367C_REG_PROTECT_ID 0x13c0 + +#define RTL8367C_REG_CHIP_VER_INTL 0x13c1 +#define RTL8367C_CHIP_VER_INTL_OFFSET 0 +#define RTL8367C_CHIP_VER_INTL_MASK 0xF + +#define RTL8367C_REG_MAGIC_ID 0x13c2 + +#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1 0x13c3 +#define RTL8367C_SKIP_MII_2_RXER_OFFSET 4 +#define RTL8367C_SKIP_MII_2_RXER_MASK 0x10 +#define RTL8367C_SELECT_GMII_2_OFFSET 0 +#define RTL8367C_SELECT_GMII_2_MASK 0xF + +#define RTL8367C_REG_DIGITAL_INTERFACE2_FORCE 0x13c4 +#define RTL8367C_GMII_2_FORCE_OFFSET 12 +#define RTL8367C_GMII_2_FORCE_MASK 0x1000 +#define RTL8367C_RGMII_2_FORCE_OFFSET 0 +#define RTL8367C_RGMII_2_FORCE_MASK 0xFFF + +#define RTL8367C_REG_EXT2_RGMXF 0x13c5 +#define RTL8367C_EXT2_RGTX_INV_OFFSET 6 +#define RTL8367C_EXT2_RGTX_INV_MASK 0x40 +#define RTL8367C_EXT2_RGRX_INV_OFFSET 5 +#define RTL8367C_EXT2_RGRX_INV_MASK 0x20 +#define RTL8367C_EXT2_RGMXF_OFFSET 0 +#define RTL8367C_EXT2_RGMXF_MASK 0x1F + +#define RTL8367C_REG_ROUTER_UPS_CFG 0x13c6 +#define RTL8367C_UPS_Status_OFFSET 1 +#define RTL8367C_UPS_Status_MASK 0x2 +#define RTL8367C_SoftStart_OFFSET 0 +#define RTL8367C_SoftStart_MASK 0x1 + +#define RTL8367C_REG_CTRL_GPIO 0x13c7 +#define RTL8367C_CTRL_GPIO_13_OFFSET 13 +#define RTL8367C_CTRL_GPIO_13_MASK 0x2000 +#define RTL8367C_CTRL_GPIO_12_OFFSET 12 +#define RTL8367C_CTRL_GPIO_12_MASK 0x1000 +#define RTL8367C_CTRL_GPIO_11_OFFSET 11 +#define RTL8367C_CTRL_GPIO_11_MASK 0x800 +#define RTL8367C_CTRL_GPIO_10_OFFSET 10 +#define RTL8367C_CTRL_GPIO_10_MASK 0x400 +#define RTL8367C_CTRL_GPIO_9_OFFSET 9 +#define RTL8367C_CTRL_GPIO_9_MASK 0x200 +#define RTL8367C_CTRL_GPIO_8_OFFSET 8 +#define RTL8367C_CTRL_GPIO_8_MASK 0x100 +#define RTL8367C_CTRL_GPIO_7_OFFSET 7 +#define RTL8367C_CTRL_GPIO_7_MASK 0x80 +#define RTL8367C_CTRL_GPIO_6_OFFSET 6 +#define RTL8367C_CTRL_GPIO_6_MASK 0x40 +#define RTL8367C_CTRL_GPIO_5_OFFSET 5 +#define RTL8367C_CTRL_GPIO_5_MASK 0x20 +#define RTL8367C_CTRL_GPIO_4_OFFSET 4 +#define RTL8367C_CTRL_GPIO_4_MASK 0x10 +#define RTL8367C_CTRL_GPIO_3_OFFSET 3 +#define RTL8367C_CTRL_GPIO_3_MASK 0x8 +#define RTL8367C_CTRL_GPIO_2_OFFSET 2 +#define RTL8367C_CTRL_GPIO_2_MASK 0x4 +#define RTL8367C_CTRL_GPIO_1_OFFSET 1 +#define RTL8367C_CTRL_GPIO_1_MASK 0x2 +#define RTL8367C_CTRL_GPIO_0_OFFSET 0 +#define RTL8367C_CTRL_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_SEL_GPIO 0x13c8 +#define RTL8367C_SEL_GPIO_13_OFFSET 13 +#define RTL8367C_SEL_GPIO_13_MASK 0x2000 +#define RTL8367C_SEL_GPIO_12_OFFSET 12 +#define RTL8367C_SEL_GPIO_12_MASK 0x1000 +#define RTL8367C_SEL_GPIO_11_OFFSET 11 +#define RTL8367C_SEL_GPIO_11_MASK 0x800 +#define RTL8367C_SEL_GPIO_10_OFFSET 10 +#define RTL8367C_SEL_GPIO_10_MASK 0x400 +#define RTL8367C_SEL_GPIO_9_OFFSET 9 +#define RTL8367C_SEL_GPIO_9_MASK 0x200 +#define RTL8367C_SEL_GPIO_8_OFFSET 8 +#define RTL8367C_SEL_GPIO_8_MASK 0x100 +#define RTL8367C_SEL_GPIO_7_OFFSET 7 +#define RTL8367C_SEL_GPIO_7_MASK 0x80 +#define RTL8367C_SEL_GPIO_6_OFFSET 6 +#define RTL8367C_SEL_GPIO_6_MASK 0x40 +#define RTL8367C_SEL_GPIO_5_OFFSET 5 +#define RTL8367C_SEL_GPIO_5_MASK 0x20 +#define RTL8367C_SEL_GPIO_4_OFFSET 4 +#define RTL8367C_SEL_GPIO_4_MASK 0x10 +#define RTL8367C_SEL_GPIO_3_OFFSET 3 +#define RTL8367C_SEL_GPIO_3_MASK 0x8 +#define RTL8367C_SEL_GPIO_2_OFFSET 2 +#define RTL8367C_SEL_GPIO_2_MASK 0x4 +#define RTL8367C_SEL_GPIO_1_OFFSET 1 +#define RTL8367C_SEL_GPIO_1_MASK 0x2 +#define RTL8367C_SEL_GPIO_0_OFFSET 0 +#define RTL8367C_SEL_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_STATUS_GPIO 0x13c9 +#define RTL8367C_STATUS_GPIO_OFFSET 0 +#define RTL8367C_STATUS_GPIO_MASK 0x3FFF + +#define RTL8367C_REG_SYNC_ETH_CFG 0x13e0 +#define RTL8367C_DUMMY2_OFFSET 9 +#define RTL8367C_DUMMY2_MASK 0xFE00 +#define RTL8367C_RFC2819_TYPE_OFFSET 8 +#define RTL8367C_RFC2819_TYPE_MASK 0x100 +#define RTL8367C_DUMMY1_OFFSET 7 +#define RTL8367C_DUMMY1_MASK 0x80 +#define RTL8367C_FIBER_SYNCE125_L_SEL_OFFSET 6 +#define RTL8367C_FIBER_SYNCE125_L_SEL_MASK 0x40 +#define RTL8367C_SYNC_ETH_EN_RTT2_OFFSET 5 +#define RTL8367C_SYNC_ETH_EN_RTT2_MASK 0x20 +#define RTL8367C_SYNC_ETH_EN_RTT1_OFFSET 4 +#define RTL8367C_SYNC_ETH_EN_RTT1_MASK 0x10 +#define RTL8367C_SYNC_ETH_SEL_DPLL_OFFSET 3 +#define RTL8367C_SYNC_ETH_SEL_DPLL_MASK 0x8 +#define RTL8367C_SYNC_ETH_SEL_PHYREF_OFFSET 2 +#define RTL8367C_SYNC_ETH_SEL_PHYREF_MASK 0x4 +#define RTL8367C_SYNC_ETH_SEL_XTAL_OFFSET 1 +#define RTL8367C_SYNC_ETH_SEL_XTAL_MASK 0x2 +#define RTL8367C_DUMMY0_OFFSET 0 +#define RTL8367C_DUMMY0_MASK 0x1 + +#define RTL8367C_REG_LED_DRI_CFG 0x13e1 +#define RTL8367C_LED_DRI_CFG_DUMMY_OFFSET 1 +#define RTL8367C_LED_DRI_CFG_DUMMY_MASK 0xFFFE +#define RTL8367C_LED_DRIVING_OFFSET 0 +#define RTL8367C_LED_DRIVING_MASK 0x1 + +#define RTL8367C_REG_CHIP_DEBUG2 0x13e2 +#define RTL8367C_RG2_DN_OFFSET 6 +#define RTL8367C_RG2_DN_MASK 0x1C0 +#define RTL8367C_RG2_DP_OFFSET 3 +#define RTL8367C_RG2_DP_MASK 0x38 +#define RTL8367C_DRI_EXT2_RG_OFFSET 2 +#define RTL8367C_DRI_EXT2_RG_MASK 0x4 +#define RTL8367C_DRI_EXT2_OFFSET 1 +#define RTL8367C_DRI_EXT2_MASK 0x2 +#define RTL8367C_SLR_EXT2_OFFSET 0 +#define RTL8367C_SLR_EXT2_MASK 0x1 + +#define RTL8367C_REG_DIGITAL_DEBUG_2 0x13e3 + +#define RTL8367C_REG_FIBER_RTL_OUI_CFG0 0x13e4 +#define RTL8367C_FIBER_RTL_OUI_CFG0_OFFSET 0 +#define RTL8367C_FIBER_RTL_OUI_CFG0_MASK 0xFF + +#define RTL8367C_REG_FIBER_RTL_OUI_CFG1 0x13e5 + +#define RTL8367C_REG_FIBER_CFG_0 0x13e6 +#define RTL8367C_REV_NUM_OFFSET 8 +#define RTL8367C_REV_NUM_MASK 0xF00 +#define RTL8367C_MODEL_NUM_OFFSET 0 +#define RTL8367C_MODEL_NUM_MASK 0x3F + +#define RTL8367C_REG_FIBER_CFG_1 0x13e7 +#define RTL8367C_SDS_FRC_REG4_OFFSET 12 +#define RTL8367C_SDS_FRC_REG4_MASK 0x1000 +#define RTL8367C_SDS_FRC_REG4_FIB100_OFFSET 11 +#define RTL8367C_SDS_FRC_REG4_FIB100_MASK 0x800 +#define RTL8367C_SEL_MASK_ONL_OFFSET 5 +#define RTL8367C_SEL_MASK_ONL_MASK 0x20 +#define RTL8367C_DIS_QUALITY_IN_MASK_OFFSET 4 +#define RTL8367C_DIS_QUALITY_IN_MASK_MASK 0x10 +#define RTL8367C_SDS_FRC_MODE_OFFSET 3 +#define RTL8367C_SDS_FRC_MODE_MASK 0x8 +#define RTL8367C_SDS_MODE_OFFSET 0 +#define RTL8367C_SDS_MODE_MASK 0x7 + +#define RTL8367C_REG_FIBER_CFG_2 0x13e8 +#define RTL8367C_SEL_SDET_PS_OFFSET 12 +#define RTL8367C_SEL_SDET_PS_MASK 0xF000 +#define RTL8367C_UTP_DIS_RX_OFFSET 10 +#define RTL8367C_UTP_DIS_RX_MASK 0xC00 +#define RTL8367C_UTP_FRC_LD_OFFSET 8 +#define RTL8367C_UTP_FRC_LD_MASK 0x300 +#define RTL8367C_SDS_RX_DISABLE_OFFSET 6 +#define RTL8367C_SDS_RX_DISABLE_MASK 0xC0 +#define RTL8367C_SDS_TX_DISABLE_OFFSET 4 +#define RTL8367C_SDS_TX_DISABLE_MASK 0x30 +#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_OFFSET 2 +#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_MASK 0xC +#define RTL8367C_SDS_FRC_LD_OFFSET 0 +#define RTL8367C_SDS_FRC_LD_MASK 0x3 + +#define RTL8367C_REG_FIBER_CFG_3 0x13e9 +#define RTL8367C_FIBER_CFG_3_OFFSET 0 +#define RTL8367C_FIBER_CFG_3_MASK 0xFFF + +#define RTL8367C_REG_FIBER_CFG_4 0x13ea + +#define RTL8367C_REG_UTP_FIB_DET 0x13eb +#define RTL8367C_FORCE_SEL_FIBER_OFFSET 14 +#define RTL8367C_FORCE_SEL_FIBER_MASK 0xC000 +#define RTL8367C_FIB_FINAL_TIMER_OFFSET 12 +#define RTL8367C_FIB_FINAL_TIMER_MASK 0x3000 +#define RTL8367C_FIB_LINK_TIMER_OFFSET 10 +#define RTL8367C_FIB_LINK_TIMER_MASK 0xC00 +#define RTL8367C_FIB_SDET_TIMER_OFFSET 8 +#define RTL8367C_FIB_SDET_TIMER_MASK 0x300 +#define RTL8367C_UTP_LINK_TIMER_OFFSET 6 +#define RTL8367C_UTP_LINK_TIMER_MASK 0xC0 +#define RTL8367C_UTP_SDET_TIMER_OFFSET 4 +#define RTL8367C_UTP_SDET_TIMER_MASK 0x30 +#define RTL8367C_FORCE_AUTODET_OFFSET 3 +#define RTL8367C_FORCE_AUTODET_MASK 0x8 +#define RTL8367C_AUTODET_FSM_CLR_OFFSET 2 +#define RTL8367C_AUTODET_FSM_CLR_MASK 0x4 +#define RTL8367C_UTP_FIRST_OFFSET 1 +#define RTL8367C_UTP_FIRST_MASK 0x2 +#define RTL8367C_UTP_FIB_DISAUTODET_OFFSET 0 +#define RTL8367C_UTP_FIB_DISAUTODET_MASK 0x1 + +#define RTL8367C_REG_NRESTORE_MAGIC_NUM 0x13ec +#define RTL8367C_NRESTORE_MAGIC_NUM_MASK 0xFFFF +#define RTL8367C_EEPROM_PROGRAM_CYCLE_OFFSET 0 +#define RTL8367C_EEPROM_PROGRAM_CYCLE_MASK 0x3 + +#define RTL8367C_REG_MAC_ACTIVE 0x13ee +#define RTL8367C_MAC_ACTIVE_H_OFFSET 9 +#define RTL8367C_MAC_ACTIVE_H_MASK 0xE00 +#define RTL8367C_FORCE_MAC_ACTIVE_OFFSET 8 +#define RTL8367C_FORCE_MAC_ACTIVE_MASK 0x100 +#define RTL8367C_MAC_ACTIVE_OFFSET 0 +#define RTL8367C_MAC_ACTIVE_MASK 0xFF + +#define RTL8367C_REG_SERDES_RESULT 0x13ef +#define RTL8367C_FIB100_DET_1_OFFSET 12 +#define RTL8367C_FIB100_DET_1_MASK 0x1000 +#define RTL8367C_FIB_ISO_1_OFFSET 11 +#define RTL8367C_FIB_ISO_1_MASK 0x800 +#define RTL8367C_SDS_ANFAULT_1_OFFSET 10 +#define RTL8367C_SDS_ANFAULT_1_MASK 0x400 +#define RTL8367C_SDS_INTB_1_OFFSET 9 +#define RTL8367C_SDS_INTB_1_MASK 0x200 +#define RTL8367C_SDS_LINK_OK_1_OFFSET 8 +#define RTL8367C_SDS_LINK_OK_1_MASK 0x100 +#define RTL8367C_FIB100_DET_OFFSET 4 +#define RTL8367C_FIB100_DET_MASK 0x10 +#define RTL8367C_FIB_ISO_OFFSET 3 +#define RTL8367C_FIB_ISO_MASK 0x8 +#define RTL8367C_SDS_ANFAULT_OFFSET 2 +#define RTL8367C_SDS_ANFAULT_MASK 0x4 +#define RTL8367C_SDS_INTB_OFFSET 1 +#define RTL8367C_SDS_INTB_MASK 0x2 +#define RTL8367C_SDS_LINK_OK_OFFSET 0 +#define RTL8367C_SDS_LINK_OK_MASK 0x1 + +#define RTL8367C_REG_CHIP_ECO 0x13f0 +#define RTL8367C_CFG_CHIP_ECO_OFFSET 1 +#define RTL8367C_CFG_CHIP_ECO_MASK 0xFFFE +#define RTL8367C_CFG_CKOUTEN_OFFSET 0 +#define RTL8367C_CFG_CKOUTEN_MASK 0x1 + +#define RTL8367C_REG_WAKELPI_SLOT_PRD 0x13f1 +#define RTL8367C_WAKELPI_SLOT_PRD_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_PRD_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG0 0x13f2 +#define RTL8367C_WAKELPI_SLOT_P1_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P1_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P0_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P0_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG1 0x13f3 +#define RTL8367C_WAKELPI_SLOT_P3_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P3_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P2_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P2_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG2 0x13f4 +#define RTL8367C_WAKELPI_SLOT_P5_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P5_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P4_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P4_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG3 0x13f5 +#define RTL8367C_WAKELPI_SLOT_P7_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P7_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P6_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P6_MASK 0x1F + +#define RTL8367C_REG_SYNC_FIFO_0 0x13f6 +#define RTL8367C_SYNC_FIFO_TX_OFFSET 8 +#define RTL8367C_SYNC_FIFO_TX_MASK 0x700 +#define RTL8367C_SYNC_FIFO_RX_OFFSET 0 +#define RTL8367C_SYNC_FIFO_RX_MASK 0xFF + +#define RTL8367C_REG_SYNC_FIFO_1 0x13f7 +#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_OFFSET 11 +#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_MASK 0x3800 +#define RTL8367C_SYNC_FIFO_TX_ERR_OFFSET 8 +#define RTL8367C_SYNC_FIFO_TX_ERR_MASK 0x700 +#define RTL8367C_SYNC_FIFO_RX_ERR_OFFSET 0 +#define RTL8367C_SYNC_FIFO_RX_ERR_MASK 0xFF + +#define RTL8367C_REG_RGM_EEE 0x13f8 +#define RTL8367C_EXT2_PAD_STOP_EN_OFFSET 14 +#define RTL8367C_EXT2_PAD_STOP_EN_MASK 0x4000 +#define RTL8367C_EXT1_PAD_STOP_EN_OFFSET 13 +#define RTL8367C_EXT1_PAD_STOP_EN_MASK 0x2000 +#define RTL8367C_EXT0_PAD_STOP_EN_OFFSET 12 +#define RTL8367C_EXT0_PAD_STOP_EN_MASK 0x1000 +#define RTL8367C_EXT2_CYCLE_PAD_OFFSET 8 +#define RTL8367C_EXT2_CYCLE_PAD_MASK 0xF00 +#define RTL8367C_EXT1_CYCLE_PAD_OFFSET 4 +#define RTL8367C_EXT1_CYCLE_PAD_MASK 0xF0 +#define RTL8367C_EXT0_CYCLE_PAD_OFFSET 0 +#define RTL8367C_EXT0_CYCLE_PAD_MASK 0xF + +#define RTL8367C_REG_EXT_TXC_DLY 0x13f9 +#define RTL8367C_EXT1_GMII_TX_DELAY_OFFSET 12 +#define RTL8367C_EXT1_GMII_TX_DELAY_MASK 0x7000 +#define RTL8367C_EXT0_GMII_TX_DELAY_OFFSET 9 +#define RTL8367C_EXT0_GMII_TX_DELAY_MASK 0xE00 +#define RTL8367C_EXT2_RGMII_TX_DELAY_OFFSET 6 +#define RTL8367C_EXT2_RGMII_TX_DELAY_MASK 0x1C0 +#define RTL8367C_EXT1_RGMII_TX_DELAY_OFFSET 3 +#define RTL8367C_EXT1_RGMII_TX_DELAY_MASK 0x38 +#define RTL8367C_EXT0_RGMII_TX_DELAY_OFFSET 0 +#define RTL8367C_EXT0_RGMII_TX_DELAY_MASK 0x7 + +#define RTL8367C_REG_IO_MISC_CTRL 0x13fa +#define RTL8367C_IO_BUZZER_EN_OFFSET 3 +#define RTL8367C_IO_BUZZER_EN_MASK 0x8 +#define RTL8367C_IO_INTRPT_EN_OFFSET 2 +#define RTL8367C_IO_INTRPT_EN_MASK 0x4 +#define RTL8367C_IO_NRESTORE_EN_OFFSET 1 +#define RTL8367C_IO_NRESTORE_EN_MASK 0x2 +#define RTL8367C_IO_UART_EN_OFFSET 0 +#define RTL8367C_IO_UART_EN_MASK 0x1 + +#define RTL8367C_REG_CHIP_DUMMY_NO 0x13fb +#define RTL8367C_CHIP_DUMMY_NO_OFFSET 0 +#define RTL8367C_CHIP_DUMMY_NO_MASK 0xF + +#define RTL8367C_REG_RC_CALIB_CFG 0x13fc +#define RTL8367C_TRIG_BURN_EFUSE_OFFSET 9 +#define RTL8367C_TRIG_BURN_EFUSE_MASK 0x200 +#define RTL8367C_AMP_CALIB_FAIL_OFFSET 8 +#define RTL8367C_AMP_CALIB_FAIL_MASK 0x100 +#define RTL8367C_R_CALIB_FAIL_OFFSET 7 +#define RTL8367C_R_CALIB_FAIL_MASK 0x80 +#define RTL8367C_CFG_CALIB_MODE_OFFSET 6 +#define RTL8367C_CFG_CALIB_MODE_MASK 0x40 +#define RTL8367C_CENTER_PORT_SEL_OFFSET 3 +#define RTL8367C_CENTER_PORT_SEL_MASK 0x38 +#define RTL8367C_CALIB_FINISH_OFFSET 2 +#define RTL8367C_CALIB_FINISH_MASK 0x4 +#define RTL8367C_CFG_CALIB_OPTION_OFFSET 1 +#define RTL8367C_CFG_CALIB_OPTION_MASK 0x2 +#define RTL8367C_CFG_CALIB_EN_OFFSET 0 +#define RTL8367C_CFG_CALIB_EN_MASK 0x1 + +#define RTL8367C_REG_WAKELPI_SLOT_PG4 0x13fd +#define RTL8367C_WAKELPI_SLOT_P9_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P9_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P8_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P8_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG5 0x13fe +#define RTL8367C_WAKELPI_SLOT_PG5_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_PG5_MASK 0x1F + +/* (16'h1400)mtrpool_reg */ + +#define RTL8367C_REG_METER0_RATE_CTRL0 0x1400 + +#define RTL8367C_REG_METER0_RATE_CTRL1 0x1401 +#define RTL8367C_METER0_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER0_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER1_RATE_CTRL0 0x1402 + +#define RTL8367C_REG_METER1_RATE_CTRL1 0x1403 +#define RTL8367C_METER1_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER1_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER2_RATE_CTRL0 0x1404 + +#define RTL8367C_REG_METER2_RATE_CTRL1 0x1405 +#define RTL8367C_METER2_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER2_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER3_RATE_CTRL0 0x1406 + +#define RTL8367C_REG_METER3_RATE_CTRL1 0x1407 +#define RTL8367C_METER3_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER3_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER4_RATE_CTRL0 0x1408 + +#define RTL8367C_REG_METER4_RATE_CTRL1 0x1409 +#define RTL8367C_METER4_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER4_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER5_RATE_CTRL0 0x140a + +#define RTL8367C_REG_METER5_RATE_CTRL1 0x140b +#define RTL8367C_METER5_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER5_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER6_RATE_CTRL0 0x140c + +#define RTL8367C_REG_METER6_RATE_CTRL1 0x140d +#define RTL8367C_METER6_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER6_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER7_RATE_CTRL0 0x140e + +#define RTL8367C_REG_METER7_RATE_CTRL1 0x140f +#define RTL8367C_METER7_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER7_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER8_RATE_CTRL0 0x1410 + +#define RTL8367C_REG_METER8_RATE_CTRL1 0x1411 +#define RTL8367C_METER8_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER8_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER9_RATE_CTRL0 0x1412 + +#define RTL8367C_REG_METER9_RATE_CTRL1 0x1413 +#define RTL8367C_METER9_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER9_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER10_RATE_CTRL0 0x1414 + +#define RTL8367C_REG_METER10_RATE_CTRL1 0x1415 +#define RTL8367C_METER10_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER10_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER11_RATE_CTRL0 0x1416 + +#define RTL8367C_REG_METER11_RATE_CTRL1 0x1417 +#define RTL8367C_METER11_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER11_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER12_RATE_CTRL0 0x1418 + +#define RTL8367C_REG_METER12_RATE_CTRL1 0x1419 +#define RTL8367C_METER12_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER12_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER13_RATE_CTRL0 0x141a + +#define RTL8367C_REG_METER13_RATE_CTRL1 0x141b +#define RTL8367C_METER13_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER13_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER14_RATE_CTRL0 0x141c + +#define RTL8367C_REG_METER14_RATE_CTRL1 0x141d +#define RTL8367C_METER14_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER14_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER15_RATE_CTRL0 0x141e + +#define RTL8367C_REG_METER15_RATE_CTRL1 0x141f +#define RTL8367C_METER15_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER15_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER16_RATE_CTRL0 0x1420 + +#define RTL8367C_REG_METER16_RATE_CTRL1 0x1421 +#define RTL8367C_METER16_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER16_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER17_RATE_CTRL0 0x1422 + +#define RTL8367C_REG_METER17_RATE_CTRL1 0x1423 +#define RTL8367C_METER17_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER17_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER18_RATE_CTRL0 0x1424 + +#define RTL8367C_REG_METER18_RATE_CTRL1 0x1425 +#define RTL8367C_METER18_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER18_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER19_RATE_CTRL0 0x1426 + +#define RTL8367C_REG_METER19_RATE_CTRL1 0x1427 +#define RTL8367C_METER19_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER19_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER20_RATE_CTRL0 0x1428 + +#define RTL8367C_REG_METER20_RATE_CTRL1 0x1429 +#define RTL8367C_METER20_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER20_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER21_RATE_CTRL0 0x142a + +#define RTL8367C_REG_METER21_RATE_CTRL1 0x142b +#define RTL8367C_METER21_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER21_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER22_RATE_CTRL0 0x142c + +#define RTL8367C_REG_METER22_RATE_CTRL1 0x142d +#define RTL8367C_METER22_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER22_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER23_RATE_CTRL0 0x142e + +#define RTL8367C_REG_METER23_RATE_CTRL1 0x142f +#define RTL8367C_METER23_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER23_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER24_RATE_CTRL0 0x1430 + +#define RTL8367C_REG_METER24_RATE_CTRL1 0x1431 +#define RTL8367C_METER24_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER24_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER25_RATE_CTRL0 0x1432 + +#define RTL8367C_REG_METER25_RATE_CTRL1 0x1433 +#define RTL8367C_METER25_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER25_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER26_RATE_CTRL0 0x1434 + +#define RTL8367C_REG_METER26_RATE_CTRL1 0x1435 +#define RTL8367C_METER26_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER26_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER27_RATE_CTRL0 0x1436 + +#define RTL8367C_REG_METER27_RATE_CTRL1 0x1437 +#define RTL8367C_METER27_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER27_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER28_RATE_CTRL0 0x1438 + +#define RTL8367C_REG_METER28_RATE_CTRL1 0x1439 +#define RTL8367C_METER28_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER28_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER29_RATE_CTRL0 0x143a + +#define RTL8367C_REG_METER29_RATE_CTRL1 0x143b +#define RTL8367C_METER29_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER29_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER30_RATE_CTRL0 0x143c + +#define RTL8367C_REG_METER30_RATE_CTRL1 0x143d +#define RTL8367C_METER30_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER30_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER31_RATE_CTRL0 0x143e + +#define RTL8367C_REG_METER31_RATE_CTRL1 0x143f +#define RTL8367C_METER31_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER31_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER_MODE_SETTING0 0x1440 + +#define RTL8367C_REG_METER_MODE_SETTING1 0x1441 + +#define RTL8367C_REG_METER_MODE_TOKEN_CFG 0x1442 +#define RTL8367C_METER_MODE_TOKEN_CFG_OFFSET 0 +#define RTL8367C_METER_MODE_TOKEN_CFG_MASK 0x7FF + +#define RTL8367C_REG_METER0_BUCKET_SIZE 0x1600 + +#define RTL8367C_REG_METER1_BUCKET_SIZE 0x1601 + +#define RTL8367C_REG_METER2_BUCKET_SIZE 0x1602 + +#define RTL8367C_REG_METER3_BUCKET_SIZE 0x1603 + +#define RTL8367C_REG_METER4_BUCKET_SIZE 0x1604 + +#define RTL8367C_REG_METER5_BUCKET_SIZE 0x1605 + +#define RTL8367C_REG_METER6_BUCKET_SIZE 0x1606 + +#define RTL8367C_REG_METER7_BUCKET_SIZE 0x1607 + +#define RTL8367C_REG_METER8_BUCKET_SIZE 0x1608 + +#define RTL8367C_REG_METER9_BUCKET_SIZE 0x1609 + +#define RTL8367C_REG_METER10_BUCKET_SIZE 0x160a + +#define RTL8367C_REG_METER11_BUCKET_SIZE 0x160b + +#define RTL8367C_REG_METER12_BUCKET_SIZE 0x160c + +#define RTL8367C_REG_METER13_BUCKET_SIZE 0x160d + +#define RTL8367C_REG_METER14_BUCKET_SIZE 0x160e + +#define RTL8367C_REG_METER15_BUCKET_SIZE 0x160f + +#define RTL8367C_REG_METER16_BUCKET_SIZE 0x1610 + +#define RTL8367C_REG_METER17_BUCKET_SIZE 0x1611 + +#define RTL8367C_REG_METER18_BUCKET_SIZE 0x1612 + +#define RTL8367C_REG_METER19_BUCKET_SIZE 0x1613 + +#define RTL8367C_REG_METER20_BUCKET_SIZE 0x1614 + +#define RTL8367C_REG_METER21_BUCKET_SIZE 0x1615 + +#define RTL8367C_REG_METER22_BUCKET_SIZE 0x1616 + +#define RTL8367C_REG_METER23_BUCKET_SIZE 0x1617 + +#define RTL8367C_REG_METER24_BUCKET_SIZE 0x1618 + +#define RTL8367C_REG_METER25_BUCKET_SIZE 0x1619 + +#define RTL8367C_REG_METER26_BUCKET_SIZE 0x161a + +#define RTL8367C_REG_METER27_BUCKET_SIZE 0x161b + +#define RTL8367C_REG_METER28_BUCKET_SIZE 0x161c + +#define RTL8367C_REG_METER29_BUCKET_SIZE 0x161d + +#define RTL8367C_REG_METER30_BUCKET_SIZE 0x161e + +#define RTL8367C_REG_METER31_BUCKET_SIZE 0x161f + +#define RTL8367C_REG_METER_CTRL0 0x1700 +#define RTL8367C_METER_OP_OFFSET 8 +#define RTL8367C_METER_OP_MASK 0x100 +#define RTL8367C_METER_TICK_OFFSET 0 +#define RTL8367C_METER_TICK_MASK 0xFF + +#define RTL8367C_REG_METER_CTRL1 0x1701 +#define RTL8367C_METER_CTRL1_OFFSET 0 +#define RTL8367C_METER_CTRL1_MASK 0xFF + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR0 0x1702 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR1 0x1703 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR0_8051 0x1704 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR1_8051 0x1705 + +#define RTL8367C_REG_METER_IFG_CTRL0 0x1712 +#define RTL8367C_METER15_IFG_OFFSET 15 +#define RTL8367C_METER15_IFG_MASK 0x8000 +#define RTL8367C_METER14_IFG_OFFSET 14 +#define RTL8367C_METER14_IFG_MASK 0x4000 +#define RTL8367C_METER13_IFG_OFFSET 13 +#define RTL8367C_METER13_IFG_MASK 0x2000 +#define RTL8367C_METER12_IFG_OFFSET 12 +#define RTL8367C_METER12_IFG_MASK 0x1000 +#define RTL8367C_METER11_IFG_OFFSET 11 +#define RTL8367C_METER11_IFG_MASK 0x800 +#define RTL8367C_METER10_IFG_OFFSET 10 +#define RTL8367C_METER10_IFG_MASK 0x400 +#define RTL8367C_METER9_IFG_OFFSET 9 +#define RTL8367C_METER9_IFG_MASK 0x200 +#define RTL8367C_METER8_IFG_OFFSET 8 +#define RTL8367C_METER8_IFG_MASK 0x100 +#define RTL8367C_METER7_IFG_OFFSET 7 +#define RTL8367C_METER7_IFG_MASK 0x80 +#define RTL8367C_METER6_IFG_OFFSET 6 +#define RTL8367C_METER6_IFG_MASK 0x40 +#define RTL8367C_METER5_IFG_OFFSET 5 +#define RTL8367C_METER5_IFG_MASK 0x20 +#define RTL8367C_METER4_IFG_OFFSET 4 +#define RTL8367C_METER4_IFG_MASK 0x10 +#define RTL8367C_METER3_IFG_OFFSET 3 +#define RTL8367C_METER3_IFG_MASK 0x8 +#define RTL8367C_METER2_IFG_OFFSET 2 +#define RTL8367C_METER2_IFG_MASK 0x4 +#define RTL8367C_METER1_IFG_OFFSET 1 +#define RTL8367C_METER1_IFG_MASK 0x2 +#define RTL8367C_METER0_IFG_OFFSET 0 +#define RTL8367C_METER0_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_IFG_CTRL1 0x1713 +#define RTL8367C_METER31_IFG_OFFSET 15 +#define RTL8367C_METER31_IFG_MASK 0x8000 +#define RTL8367C_METER30_IFG_OFFSET 14 +#define RTL8367C_METER30_IFG_MASK 0x4000 +#define RTL8367C_METER29_IFG_OFFSET 13 +#define RTL8367C_METER29_IFG_MASK 0x2000 +#define RTL8367C_METER28_IFG_OFFSET 12 +#define RTL8367C_METER28_IFG_MASK 0x1000 +#define RTL8367C_METER27_IFG_OFFSET 11 +#define RTL8367C_METER27_IFG_MASK 0x800 +#define RTL8367C_METER26_IFG_OFFSET 10 +#define RTL8367C_METER26_IFG_MASK 0x400 +#define RTL8367C_METER25_IFG_OFFSET 9 +#define RTL8367C_METER25_IFG_MASK 0x200 +#define RTL8367C_METER24_IFG_OFFSET 8 +#define RTL8367C_METER24_IFG_MASK 0x100 +#define RTL8367C_METER23_IFG_OFFSET 7 +#define RTL8367C_METER23_IFG_MASK 0x80 +#define RTL8367C_METER22_IFG_OFFSET 6 +#define RTL8367C_METER22_IFG_MASK 0x40 +#define RTL8367C_METER21_IFG_OFFSET 5 +#define RTL8367C_METER21_IFG_MASK 0x20 +#define RTL8367C_METER20_IFG_OFFSET 4 +#define RTL8367C_METER20_IFG_MASK 0x10 +#define RTL8367C_METER19_IFG_OFFSET 3 +#define RTL8367C_METER19_IFG_MASK 0x8 +#define RTL8367C_METER18_IFG_OFFSET 2 +#define RTL8367C_METER18_IFG_MASK 0x4 +#define RTL8367C_METER17_IFG_OFFSET 1 +#define RTL8367C_METER17_IFG_MASK 0x2 +#define RTL8367C_METER16_IFG_OFFSET 0 +#define RTL8367C_METER16_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_CTRL2 0x1722 +#define RTL8367C_cfg_mtr_tick_8g_OFFSET 8 +#define RTL8367C_cfg_mtr_tick_8g_MASK 0xFF00 +#define RTL8367C_cfg_mtr_dec_cnt_8g_OFFSET 0 +#define RTL8367C_cfg_mtr_dec_cnt_8g_MASK 0xFF + +#define RTL8367C_REG_DUMMY_1723 0x1723 + +#define RTL8367C_REG_DUMMY_1724 0x1724 + +#define RTL8367C_REG_DUMMY_1725 0x1725 + +#define RTL8367C_REG_DUMMY_1726 0x1726 + +#define RTL8367C_REG_DUMMY_1727 0x1727 + +#define RTL8367C_REG_DUMMY_1728 0x1728 + +#define RTL8367C_REG_DUMMY_1729 0x1729 + +#define RTL8367C_REG_DUMMY_172A 0x172a + +#define RTL8367C_REG_DUMMY_172B 0x172b + +#define RTL8367C_REG_DUMMY_172C 0x172c + +#define RTL8367C_REG_DUMMY_172D 0x172d + +#define RTL8367C_REG_DUMMY_172E 0x172e + +#define RTL8367C_REG_DUMMY_172F 0x172f + +#define RTL8367C_REG_DUMMY_1730 0x1730 + +#define RTL8367C_REG_DUMMY_1731 0x1731 + +#define RTL8367C_REG_METER32_RATE_CTRL0 0x1740 + +#define RTL8367C_REG_METER32_RATE_CTRL1 0x1741 +#define RTL8367C_METER32_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER32_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER33_RATE_CTRL0 0x1742 + +#define RTL8367C_REG_METER33_RATE_CTRL1 0x1743 +#define RTL8367C_METER33_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER33_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER34_RATE_CTRL0 0x1744 + +#define RTL8367C_REG_METER34_RATE_CTRL1 0x1745 +#define RTL8367C_METER34_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER34_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER35_RATE_CTRL0 0x1746 + +#define RTL8367C_REG_METER35_RATE_CTRL1 0x1747 +#define RTL8367C_METER35_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER35_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER36_RATE_CTRL0 0x1748 + +#define RTL8367C_REG_METER36_RATE_CTRL1 0x1749 +#define RTL8367C_METER36_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER36_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER37_RATE_CTRL0 0x174a + +#define RTL8367C_REG_METER37_RATE_CTRL1 0x174b +#define RTL8367C_METER37_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER37_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER38_RATE_CTRL0 0x174c + +#define RTL8367C_REG_METER38_RATE_CTRL1 0x174d +#define RTL8367C_METER38_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER38_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER39_RATE_CTRL0 0x174e + +#define RTL8367C_REG_METER39_RATE_CTRL1 0x174f +#define RTL8367C_METER39_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER39_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER40_RATE_CTRL0 0x1750 + +#define RTL8367C_REG_METER40_RATE_CTRL1 0x1751 +#define RTL8367C_METER40_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER40_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER41_RATE_CTRL0 0x1752 + +#define RTL8367C_REG_METER41_RATE_CTRL1 0x1753 +#define RTL8367C_METER41_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER41_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER42_RATE_CTRL0 0x1754 + +#define RTL8367C_REG_METER42_RATE_CTRL1 0x1755 +#define RTL8367C_METER42_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER42_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER43_RATE_CTRL0 0x1756 + +#define RTL8367C_REG_METER43_RATE_CTRL1 0x1757 +#define RTL8367C_METER43_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER43_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER44_RATE_CTRL0 0x1758 + +#define RTL8367C_REG_METER44_RATE_CTRL1 0x1759 +#define RTL8367C_METER44_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER44_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER45_RATE_CTRL0 0x175a + +#define RTL8367C_REG_METER45_RATE_CTRL1 0x175b +#define RTL8367C_METER45_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER45_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER46_RATE_CTRL0 0x175c + +#define RTL8367C_REG_METER46_RATE_CTRL1 0x175d +#define RTL8367C_METER46_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER46_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER47_RATE_CTRL0 0x175e + +#define RTL8367C_REG_METER47_RATE_CTRL1 0x175f +#define RTL8367C_METER47_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER47_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER48_RATE_CTRL0 0x1760 + +#define RTL8367C_REG_METER48_RATE_CTRL1 0x1761 +#define RTL8367C_METER48_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER48_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER49_RATE_CTRL0 0x1762 + +#define RTL8367C_REG_METER49_RATE_CTRL1 0x1763 +#define RTL8367C_METER49_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER49_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER50_RATE_CTRL0 0x1764 + +#define RTL8367C_REG_METER50_RATE_CTRL1 0x1765 +#define RTL8367C_METER50_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER50_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER51_RATE_CTRL0 0x1766 + +#define RTL8367C_REG_METER51_RATE_CTRL1 0x1767 +#define RTL8367C_METER51_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER51_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER52_RATE_CTRL0 0x1768 + +#define RTL8367C_REG_METER52_RATE_CTRL1 0x1769 +#define RTL8367C_METER52_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER52_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER53_RATE_CTRL0 0x176a + +#define RTL8367C_REG_METER53_RATE_CTRL1 0x176b +#define RTL8367C_METER53_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER53_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER54_RATE_CTRL0 0x176c + +#define RTL8367C_REG_METER54_RATE_CTRL1 0x176d +#define RTL8367C_METER54_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER54_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER55_RATE_CTRL0 0x176e + +#define RTL8367C_REG_METER55_RATE_CTRL1 0x176f +#define RTL8367C_METER55_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER55_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER56_RATE_CTRL0 0x1770 + +#define RTL8367C_REG_METER56_RATE_CTRL1 0x1771 +#define RTL8367C_METER56_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER56_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER57_RATE_CTRL0 0x1772 + +#define RTL8367C_REG_METER57_RATE_CTRL1 0x1773 +#define RTL8367C_METER57_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER57_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER58_RATE_CTRL0 0x1774 + +#define RTL8367C_REG_METER58_RATE_CTRL1 0x1775 +#define RTL8367C_METER58_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER58_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER59_RATE_CTRL0 0x1776 + +#define RTL8367C_REG_METER59_RATE_CTRL1 0x1777 +#define RTL8367C_METER59_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER59_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER60_RATE_CTRL0 0x1778 + +#define RTL8367C_REG_METER60_RATE_CTRL1 0x1779 +#define RTL8367C_METER60_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER60_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER61_RATE_CTRL0 0x177a + +#define RTL8367C_REG_METER61_RATE_CTRL1 0x177b +#define RTL8367C_METER61_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER61_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER62_RATE_CTRL0 0x177c + +#define RTL8367C_REG_METER62_RATE_CTRL1 0x177d +#define RTL8367C_METER62_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER62_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER63_RATE_CTRL0 0x177e + +#define RTL8367C_REG_METER63_RATE_CTRL1 0x177f +#define RTL8367C_METER63_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER63_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER_MODE_SETTING2 0x1780 + +#define RTL8367C_REG_METER_MODE_SETTING3 0x1781 + +#define RTL8367C_REG_METER32_BUCKET_SIZE 0x1790 + +#define RTL8367C_REG_METER33_BUCKET_SIZE 0x1791 + +#define RTL8367C_REG_METER34_BUCKET_SIZE 0x1792 + +#define RTL8367C_REG_METER35_BUCKET_SIZE 0x1793 + +#define RTL8367C_REG_METER36_BUCKET_SIZE 0x1794 + +#define RTL8367C_REG_METER37_BUCKET_SIZE 0x1795 + +#define RTL8367C_REG_METER38_BUCKET_SIZE 0x1796 + +#define RTL8367C_REG_METER39_BUCKET_SIZE 0x1797 + +#define RTL8367C_REG_METER40_BUCKET_SIZE 0x1798 + +#define RTL8367C_REG_METER41_BUCKET_SIZE 0x1799 + +#define RTL8367C_REG_METER42_BUCKET_SIZE 0x179a + +#define RTL8367C_REG_METER43_BUCKET_SIZE 0x179b + +#define RTL8367C_REG_METER44_BUCKET_SIZE 0x179c + +#define RTL8367C_REG_METER45_BUCKET_SIZE 0x179d + +#define RTL8367C_REG_METER46_BUCKET_SIZE 0x179e + +#define RTL8367C_REG_METER47_BUCKET_SIZE 0x179f + +#define RTL8367C_REG_METER48_BUCKET_SIZE 0x17a0 + +#define RTL8367C_REG_METER49_BUCKET_SIZE 0x17a1 + +#define RTL8367C_REG_METER50_BUCKET_SIZE 0x17a2 + +#define RTL8367C_REG_METER51_BUCKET_SIZE 0x17a3 + +#define RTL8367C_REG_METER52_BUCKET_SIZE 0x17a4 + +#define RTL8367C_REG_METER53_BUCKET_SIZE 0x17a5 + +#define RTL8367C_REG_METER54_BUCKET_SIZE 0x17a6 + +#define RTL8367C_REG_METER55_BUCKET_SIZE 0x17a7 + +#define RTL8367C_REG_METER56_BUCKET_SIZE 0x17a8 + +#define RTL8367C_REG_METER57_BUCKET_SIZE 0x17a9 + +#define RTL8367C_REG_METER58_BUCKET_SIZE 0x17aa + +#define RTL8367C_REG_METER59_BUCKET_SIZE 0x17ab + +#define RTL8367C_REG_METER60_BUCKET_SIZE 0x17ac + +#define RTL8367C_REG_METER61_BUCKET_SIZE 0x17ad + +#define RTL8367C_REG_METER62_BUCKET_SIZE 0x17ae + +#define RTL8367C_REG_METER63_BUCKET_SIZE 0x17af + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR2 0x17b0 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR3 0x17b1 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR2_8051 0x17b2 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR3_8051 0x17b3 + +#define RTL8367C_REG_METER_IFG_CTRL2 0x17b4 +#define RTL8367C_METER47_IFG_OFFSET 15 +#define RTL8367C_METER47_IFG_MASK 0x8000 +#define RTL8367C_METER46_IFG_OFFSET 14 +#define RTL8367C_METER46_IFG_MASK 0x4000 +#define RTL8367C_METER45_IFG_OFFSET 13 +#define RTL8367C_METER45_IFG_MASK 0x2000 +#define RTL8367C_METER44_IFG_OFFSET 12 +#define RTL8367C_METER44_IFG_MASK 0x1000 +#define RTL8367C_METER43_IFG_OFFSET 11 +#define RTL8367C_METER43_IFG_MASK 0x800 +#define RTL8367C_METER42_IFG_OFFSET 10 +#define RTL8367C_METER42_IFG_MASK 0x400 +#define RTL8367C_METER41_IFG_OFFSET 9 +#define RTL8367C_METER41_IFG_MASK 0x200 +#define RTL8367C_METER40_IFG_OFFSET 8 +#define RTL8367C_METER40_IFG_MASK 0x100 +#define RTL8367C_METER39_IFG_OFFSET 7 +#define RTL8367C_METER39_IFG_MASK 0x80 +#define RTL8367C_METER38_IFG_OFFSET 6 +#define RTL8367C_METER38_IFG_MASK 0x40 +#define RTL8367C_METER37_IFG_OFFSET 5 +#define RTL8367C_METER37_IFG_MASK 0x20 +#define RTL8367C_METER36_IFG_OFFSET 4 +#define RTL8367C_METER36_IFG_MASK 0x10 +#define RTL8367C_METER35_IFG_OFFSET 3 +#define RTL8367C_METER35_IFG_MASK 0x8 +#define RTL8367C_METER34_IFG_OFFSET 2 +#define RTL8367C_METER34_IFG_MASK 0x4 +#define RTL8367C_METER33_IFG_OFFSET 1 +#define RTL8367C_METER33_IFG_MASK 0x2 +#define RTL8367C_METER32_IFG_OFFSET 0 +#define RTL8367C_METER32_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_IFG_CTRL3 0x17b5 +#define RTL8367C_METER63_IFG_OFFSET 15 +#define RTL8367C_METER63_IFG_MASK 0x8000 +#define RTL8367C_METER62_IFG_OFFSET 14 +#define RTL8367C_METER62_IFG_MASK 0x4000 +#define RTL8367C_METER61_IFG_OFFSET 13 +#define RTL8367C_METER61_IFG_MASK 0x2000 +#define RTL8367C_METER60_IFG_OFFSET 12 +#define RTL8367C_METER60_IFG_MASK 0x1000 +#define RTL8367C_METER59_IFG_OFFSET 11 +#define RTL8367C_METER59_IFG_MASK 0x800 +#define RTL8367C_METER58_IFG_OFFSET 10 +#define RTL8367C_METER58_IFG_MASK 0x400 +#define RTL8367C_METER57_IFG_OFFSET 9 +#define RTL8367C_METER57_IFG_MASK 0x200 +#define RTL8367C_METER56_IFG_OFFSET 8 +#define RTL8367C_METER56_IFG_MASK 0x100 +#define RTL8367C_METER55_IFG_OFFSET 7 +#define RTL8367C_METER55_IFG_MASK 0x80 +#define RTL8367C_METER54_IFG_OFFSET 6 +#define RTL8367C_METER54_IFG_MASK 0x40 +#define RTL8367C_METER53_IFG_OFFSET 5 +#define RTL8367C_METER53_IFG_MASK 0x20 +#define RTL8367C_METER52_IFG_OFFSET 4 +#define RTL8367C_METER52_IFG_MASK 0x10 +#define RTL8367C_METER51_IFG_OFFSET 3 +#define RTL8367C_METER51_IFG_MASK 0x8 +#define RTL8367C_METER50_IFG_OFFSET 2 +#define RTL8367C_METER50_IFG_MASK 0x4 +#define RTL8367C_METER49_IFG_OFFSET 1 +#define RTL8367C_METER49_IFG_MASK 0x2 +#define RTL8367C_METER48_IFG_OFFSET 0 +#define RTL8367C_METER48_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_MISC 0x17b6 +#define RTL8367C_METER_MISC_OFFSET 0 +#define RTL8367C_METER_MISC_MASK 0x1 + +/* (16'h1800)8051_RLDP_EEE_reg */ + +#define RTL8367C_REG_EEELLDP_CTRL0 0x1820 +#define RTL8367C_EEELLDP_SUBTYPE_OFFSET 6 +#define RTL8367C_EEELLDP_SUBTYPE_MASK 0x3FC0 +#define RTL8367C_EEELLDP_TRAP_8051_OFFSET 2 +#define RTL8367C_EEELLDP_TRAP_8051_MASK 0x4 +#define RTL8367C_EEELLDP_TRAP_CPU_OFFSET 1 +#define RTL8367C_EEELLDP_TRAP_CPU_MASK 0x2 +#define RTL8367C_EEELLDP_ENABLE_OFFSET 0 +#define RTL8367C_EEELLDP_ENABLE_MASK 0x1 + +#define RTL8367C_REG_EEELLDP_PMSK 0x1822 +#define RTL8367C_EEELLDP_PMSK_OFFSET 0 +#define RTL8367C_EEELLDP_PMSK_MASK 0x7FF + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_08 0x1843 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_07 0x1844 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_06 0x1845 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_05 0x1846 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_04 0x1847 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_03 0x1848 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_02 0x1849 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_01 0x184a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 0x184b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_08 0x184c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_07 0x184d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_06 0x184e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_05 0x184f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_04 0x1850 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_03 0x1851 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_02 0x1852 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_01 0x1853 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_00 0x1854 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_08 0x1855 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_07 0x1856 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_06 0x1857 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_05 0x1858 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_04 0x1859 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_03 0x185a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_02 0x185b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_01 0x185c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_00 0x185d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_08 0x185e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_07 0x185f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_06 0x1860 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_05 0x1861 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_04 0x1862 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_03 0x1863 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_02 0x1864 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_01 0x1865 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_00 0x1866 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_08 0x1867 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_07 0x1868 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_06 0x1869 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_05 0x186a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_04 0x186b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_03 0x186c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_02 0x186d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_01 0x186e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_00 0x186f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_08 0x1870 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_07 0x1871 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_06 0x1872 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_05 0x1873 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_04 0x1874 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_03 0x1875 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_02 0x1876 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_01 0x1877 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_00 0x1878 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_08 0x1879 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_07 0x187a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_06 0x187b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_05 0x187c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_04 0x187d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_03 0x187e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_02 0x187f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_01 0x1880 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_00 0x1881 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_08 0x1882 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_07 0x1883 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_06 0x1884 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_05 0x1885 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_04 0x1886 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_03 0x1887 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_02 0x1888 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_01 0x1889 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_00 0x188a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_08 0x188b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_07 0x188c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_06 0x188d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_05 0x188e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_04 0x188f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_03 0x1890 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_02 0x1891 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_01 0x1892 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_00 0x1893 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_08 0x1894 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_07 0x1895 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_06 0x1896 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_05 0x1897 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_04 0x1898 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_03 0x1899 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_02 0x189a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_01 0x189b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_00 0x189c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_08 0x189d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_07 0x189e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_06 0x189f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_05 0x18a0 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_04 0x18a1 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_03 0x18a2 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_02 0x18a3 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_01 0x18a4 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_00 0x18a5 + +#define RTL8367C_REG_RLDP_CTRL0 0x18e0 +#define RTL8367C_RLDP_TRIGGER_MODE_OFFSET 14 +#define RTL8367C_RLDP_TRIGGER_MODE_MASK 0x4000 +#define RTL8367C_RLDP_8051_LOOP_PORTMSK_OFFSET 6 +#define RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK 0x3FC0 +#define RTL8367C_RLPP_8051_TRAP_OFFSET 5 +#define RTL8367C_RLPP_8051_TRAP_MASK 0x20 +#define RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET 4 +#define RTL8367C_RLDP_INDICATOR_SOURCE_MASK 0x10 +#define RTL8367C_RLDP_GEN_RANDOM_OFFSET 3 +#define RTL8367C_RLDP_GEN_RANDOM_MASK 0x8 +#define RTL8367C_RLDP_COMP_ID_OFFSET 2 +#define RTL8367C_RLDP_COMP_ID_MASK 0x4 +#define RTL8367C_RLDP_8051_ENABLE_OFFSET 1 +#define RTL8367C_RLDP_8051_ENABLE_MASK 0x2 +#define RTL8367C_RLDP_ENABLE_OFFSET 0 +#define RTL8367C_RLDP_ENABLE_MASK 0x1 + +#define RTL8367C_REG_RLDP_CTRL1 0x18e1 +#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_OFFSET 8 +#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK 0xFF00 +#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_OFFSET 0 +#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK 0xFF + +#define RTL8367C_REG_RLDP_CTRL2 0x18e2 + +#define RTL8367C_REG_RLDP_CTRL3 0x18e3 + +#define RTL8367C_REG_RLDP_CTRL4 0x18e4 +#define RTL8367C_RLDP_CTRL4_OFFSET 0 +#define RTL8367C_RLDP_CTRL4_MASK 0x7FF + +#define RTL8367C_REG_RLDP_RAND_NUM0 0x18e5 + +#define RTL8367C_REG_RLDP_RAND_NUM1 0x18e6 + +#define RTL8367C_REG_RLDP_RAND_NUM2 0x18e7 + +#define RTL8367C_REG_RLDP_MAGIC_NUM0 0x18e8 + +#define RTL8367C_REG_RLDP_MAGIC_NUM1 0x18e9 + +#define RTL8367C_REG_RLDP_MAGIC_NUM2 0x18ea + +#define RTL8367C_REG_RLDP_LOOPED_INDICATOR 0x18eb +#define RTL8367C_RLDP_LOOPED_INDICATOR_OFFSET 0 +#define RTL8367C_RLDP_LOOPED_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG0 0x18ec +#define RTL8367C_RLDP_LOOP_PORT_01_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_01_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_00_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_00_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG1 0x18ed +#define RTL8367C_RLDP_LOOP_PORT_03_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_03_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_02_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_02_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG2 0x18ee +#define RTL8367C_RLDP_LOOP_PORT_05_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_05_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_04_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_04_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG3 0x18ef +#define RTL8367C_RLDP_LOOP_PORT_07_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_07_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_06_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_06_MASK 0xF + +#define RTL8367C_REG_RLDP_RELEASED_INDICATOR 0x18f0 +#define RTL8367C_RLDP_RELEASED_INDICATOR_OFFSET 0 +#define RTL8367C_RLDP_RELEASED_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR 0x18f1 +#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_OFFSET 0 +#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG4 0x18f2 +#define RTL8367C_RLDP_LOOP_PORT_9_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_9_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_8_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_8_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG5 0x18f3 +#define RTL8367C_RLDP_LOOP_PORT_REG5_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_REG5_MASK 0xF + +#define RTL8367C_REG_RLDP_CTRL5 0x18f4 +#define RTL8367C_RLDP_CTRL5_OFFSET 0 +#define RTL8367C_RLDP_CTRL5_MASK 0x7 + +/* (16'h1900)EEE_EEEP_reg */ + +#define RTL8367C_REG_EEE_500M_CTRL0 0x1900 +#define RTL8367C_EEE_500M_CTRL0_OFFSET 0 +#define RTL8367C_EEE_500M_CTRL0_MASK 0xFF + +#define RTL8367C_REG_EEE_RXIDLE_GIGA_CTRL 0x1901 +#define RTL8367C_EEE_RXIDLE_GIGA_EN_OFFSET 8 +#define RTL8367C_EEE_RXIDLE_GIGA_EN_MASK 0x100 +#define RTL8367C_EEE_RXIDLE_GIGA_OFFSET 0 +#define RTL8367C_EEE_RXIDLE_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEE_RXIDLE_500M_CTRL 0x1902 +#define RTL8367C_EEE_RXIDLE_500M_EN_OFFSET 8 +#define RTL8367C_EEE_RXIDLE_500M_EN_MASK 0x100 +#define RTL8367C_EEE_RXIDLE_500M_OFFSET 0 +#define RTL8367C_EEE_RXIDLE_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_DECISION_GIGA_500M 0x1903 +#define RTL8367C_EEE_DECISION_GIGA_OFFSET 8 +#define RTL8367C_EEE_DECISION_GIGA_MASK 0xFF00 +#define RTL8367C_EEE_DECISION_500M_OFFSET 0 +#define RTL8367C_EEE_DECISION_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_DECISION_100M 0x1904 +#define RTL8367C_EEE_DECISION_100M_OFFSET 0 +#define RTL8367C_EEE_DECISION_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_DEFER_TXLPI 0x1905 +#define RTL8367C_EEEP_DEFER_TXLPI_OFFSET 0 +#define RTL8367C_EEEP_DEFER_TXLPI_MASK 0x1 + +#define RTL8367C_REG_EEEP_EN 0x1906 +#define RTL8367C_EEEP_SLAVE_EN_OFFSET 3 +#define RTL8367C_EEEP_SLAVE_EN_MASK 0x8 +#define RTL8367C_EEEP_100M_OFFSET 2 +#define RTL8367C_EEEP_100M_MASK 0x4 +#define RTL8367C_EEEP_500M_OFFSET 1 +#define RTL8367C_EEEP_500M_MASK 0x2 +#define RTL8367C_EEEP_GIGA_OFFSET 0 +#define RTL8367C_EEEP_GIGA_MASK 0x1 + +#define RTL8367C_REG_EEEP_TI_GIGA_500M 0x1907 +#define RTL8367C_EEEP_TI_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TI_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_TI_500M_OFFSET 0 +#define RTL8367C_EEEP_TI_500M_MASK 0xFF + +#define RTL8367C_REG_EEEP_TI_100M 0x1908 +#define RTL8367C_EEEP_TI_100M_OFFSET 0 +#define RTL8367C_EEEP_TI_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_CTRL2 0x1909 +#define RTL8367C_EEEP_CTRL2_OFFSET 0 +#define RTL8367C_EEEP_CTRL2_MASK 0xFF + +#define RTL8367C_REG_EEEP_RX_RATE_500M 0x190b + +#define RTL8367C_REG_EEEP_RW_GIGA_SLV 0x190c +#define RTL8367C_EEEP_RW_GIGA_SLV_OFFSET 0 +#define RTL8367C_EEEP_RW_GIGA_SLV_MASK 0xFF + +#define RTL8367C_REG_EEEP_TMR_GIGA 0x190d +#define RTL8367C_RX_IDLE_EEEP_GIGA_OFFSET 8 +#define RTL8367C_RX_IDLE_EEEP_GIGA_MASK 0xFF00 +#define RTL8367C_RX_MIN_SLP_TMR_GIGA_OFFSET 0 +#define RTL8367C_RX_MIN_SLP_TMR_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEEP_TMR_500M 0x190e +#define RTL8367C_RX_IDLE_EEEP_500M_OFFSET 8 +#define RTL8367C_RX_IDLE_EEEP_500M_MASK 0xFF00 +#define RTL8367C_RX_MIN_SLP_TMR_500M_OFFSET 0 +#define RTL8367C_RX_MIN_SLP_TMR_500M_MASK 0xFF + +#define RTL8367C_REG_EEEP_TMR_100M 0x190f +#define RTL8367C_RX_IDLE_EEEP_100M_OFFSET 8 +#define RTL8367C_RX_IDLE_EEEP_100M_MASK 0xFF00 +#define RTL8367C_RX_MIN_SLP_TMR_100M_OFFSET 0 +#define RTL8367C_RX_MIN_SLP_TMR_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_RW_500M_MST_SLV 0x1910 +#define RTL8367C_EEEP_RW_500M_MST_OFFSET 8 +#define RTL8367C_EEEP_RW_500M_MST_MASK 0xFF00 +#define RTL8367C_EEEP_RW_500M_SLV_OFFSET 0 +#define RTL8367C_EEEP_RW_500M_SLV_MASK 0xFF + +#define RTL8367C_REG_EEEP_500M_CTRL0 0x1911 +#define RTL8367C_EEEP_500M_CTRL0_OFFSET 0 +#define RTL8367C_EEEP_500M_CTRL0_MASK 0xFF + +#define RTL8367C_REG_EEEP_500M_CTRL1 0x1912 +#define RTL8367C_EEEP_TW_500M_OFFSET 8 +#define RTL8367C_EEEP_TW_500M_MASK 0xFF00 +#define RTL8367C_EEEP_TP_500M_OFFSET 0 +#define RTL8367C_EEEP_TP_500M_MASK 0xFF + +#define RTL8367C_REG_EEEP_500M_CTRL2 0x1913 +#define RTL8367C_EEEP_TXEN_500M_OFFSET 12 +#define RTL8367C_EEEP_TXEN_500M_MASK 0x1000 +#define RTL8367C_EEEP_TU_500M_OFFSET 8 +#define RTL8367C_EEEP_TU_500M_MASK 0x300 +#define RTL8367C_EEEP_TS_500M_OFFSET 0 +#define RTL8367C_EEEP_TS_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_NEW_CTRL0 0x1914 +#define RTL8367C_LINK_UP_DELAY_OFFSET 3 +#define RTL8367C_LINK_UP_DELAY_MASK 0x18 +#define RTL8367C_EEE_TXLPI_ORI_OFFSET 2 +#define RTL8367C_EEE_TXLPI_ORI_MASK 0x4 +#define RTL8367C_REALTX_SEL_OFFSET 1 +#define RTL8367C_REALTX_SEL_MASK 0x2 +#define RTL8367C_EN_FC_EFCT_OFFSET 0 +#define RTL8367C_EN_FC_EFCT_MASK 0x1 + +#define RTL8367C_REG_EEE_LONGIDLE_100M 0x1915 +#define RTL8367C_EEE_LONGIDLE_100M_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_100M_MASK 0x3FF + +#define RTL8367C_REG_EEE_LONGIDLE_500M 0x1916 +#define RTL8367C_EEE_LONGIDLE_500M_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_500M_MASK 0x3FF + +#define RTL8367C_REG_EEE_LONGIDLE_GIGA 0x1917 +#define RTL8367C_EEE_LONGIDLE_GIGA_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_GIGA_MASK 0x3FF + +#define RTL8367C_REG_EEE_MINIPG_100M 0x1918 + +#define RTL8367C_REG_EEE_MINIPG_500M 0x1919 + +#define RTL8367C_REG_EEE_MINIPG_GIGA 0x191A + +#define RTL8367C_REG_EEE_LONGIDLE_CTRL0 0x191B +#define RTL8367C_TX_IDLEN_REQ_100M_OFFSET 10 +#define RTL8367C_TX_IDLEN_REQ_100M_MASK 0x400 +#define RTL8367C_TX_IDLEN_REQ_500M_OFFSET 9 +#define RTL8367C_TX_IDLEN_REQ_500M_MASK 0x200 +#define RTL8367C_TX_IDLEN_REQ_GIGA_OFFSET 8 +#define RTL8367C_TX_IDLEN_REQ_GIGA_MASK 0x100 +#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_MASK 0xFF + +#define RTL8367C_REG_EEE_LONGIDLE_CTRL1 0x191C +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_OFFSET 8 +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_MASK 0xFF00 +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEE_TD_CTRL_H 0x191d +#define RTL8367C_REF_RXLPI_OFFSET 8 +#define RTL8367C_REF_RXLPI_MASK 0x100 +#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_OFFSET 4 +#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_MASK 0xF0 +#define RTL8367C_LOW_Q_TX_DELAY_FE_H_OFFSET 0 +#define RTL8367C_LOW_Q_TX_DELAY_FE_H_MASK 0xF + +/* (16'h1a00)nic_reg */ + +#define RTL8367C_REG_NIC_RXRDRL 0x1a04 +#define RTL8367C_NIC_RXRDRL_OFFSET 0 +#define RTL8367C_NIC_RXRDRL_MASK 0xFF + +#define RTL8367C_REG_NIC_RXRDRH 0x1a05 +#define RTL8367C_NIC_RXRDRH_OFFSET 0 +#define RTL8367C_NIC_RXRDRH_MASK 0xFF + +#define RTL8367C_REG_NIC_TXASRL 0x1a08 +#define RTL8367C_NIC_TXASRL_OFFSET 0 +#define RTL8367C_NIC_TXASRL_MASK 0xFF + +#define RTL8367C_REG_NIC_TXASRH 0x1a09 +#define RTL8367C_NIC_TXASRH_OFFSET 0 +#define RTL8367C_NIC_TXASRH_MASK 0xFF + +#define RTL8367C_REG_NIC_RXCMDR 0x1a0c +#define RTL8367C_NIC_RXCMDR_OFFSET 0 +#define RTL8367C_NIC_RXCMDR_MASK 0x1 + +#define RTL8367C_REG_NIC_TXCMDR 0x1a0d +#define RTL8367C_NIC_TXCMDR_OFFSET 0 +#define RTL8367C_NIC_TXCMDR_MASK 0x1 + +#define RTL8367C_REG_NIC_IMS 0x1a0e +#define RTL8367C_NIC_RXIS_OFFSET 7 +#define RTL8367C_NIC_RXIS_MASK 0x80 +#define RTL8367C_NIC_TXIS_OFFSET 6 +#define RTL8367C_NIC_TXIS_MASK 0x40 +#define RTL8367C_NIC_TXES_OFFSET 5 +#define RTL8367C_NIC_TXES_MASK 0x20 +#define RTL8367C_NIC_IMS_DMY_OFFSET 4 +#define RTL8367C_NIC_IMS_DMY_MASK 0x10 +#define RTL8367C_NIC_RXBUS_OFFSET 3 +#define RTL8367C_NIC_RXBUS_MASK 0x8 +#define RTL8367C_NIC_TXBOS_OFFSET 2 +#define RTL8367C_NIC_TXBOS_MASK 0x4 +#define RTL8367C_NIC_RXMIS_OFFSET 1 +#define RTL8367C_NIC_RXMIS_MASK 0x2 +#define RTL8367C_NIC_TXNLS_OFFSET 0 +#define RTL8367C_NIC_TXNLS_MASK 0x1 + +#define RTL8367C_REG_NIC_IMR 0x1a0f +#define RTL8367C_NIC_RXIE_OFFSET 7 +#define RTL8367C_NIC_RXIE_MASK 0x80 +#define RTL8367C_NIC_TXIE_OFFSET 6 +#define RTL8367C_NIC_TXIE_MASK 0x40 +#define RTL8367C_NIC_TXEE_OFFSET 5 +#define RTL8367C_NIC_TXEE_MASK 0x20 +#define RTL8367C_NIC_IMR_DMY_OFFSET 4 +#define RTL8367C_NIC_IMR_DMY_MASK 0x10 +#define RTL8367C_NIC_RXBUE_OFFSET 3 +#define RTL8367C_NIC_RXBUE_MASK 0x8 +#define RTL8367C_NIC_TXBOE_OFFSET 2 +#define RTL8367C_NIC_TXBOE_MASK 0x4 +#define RTL8367C_NIC_RXMIE_OFFSET 1 +#define RTL8367C_NIC_RXMIE_MASK 0x2 +#define RTL8367C_NIC_TXNLE_OFFSET 0 +#define RTL8367C_NIC_TXNLE_MASK 0x1 + +#define RTL8367C_REG_NIC_RXCR0 0x1a14 +#define RTL8367C_NIC_HFPPE_OFFSET 7 +#define RTL8367C_NIC_HFPPE_MASK 0x80 +#define RTL8367C_NIC_HFMPE_OFFSET 6 +#define RTL8367C_NIC_HFMPE_MASK 0x40 +#define RTL8367C_NIC_RXBPE_OFFSET 5 +#define RTL8367C_NIC_RXBPE_MASK 0x20 +#define RTL8367C_NIC_RXMPE_OFFSET 4 +#define RTL8367C_NIC_RXMPE_MASK 0x10 +#define RTL8367C_NIC_RXPPS_OFFSET 2 +#define RTL8367C_NIC_RXPPS_MASK 0xC +#define RTL8367C_NIC_RXAPE_OFFSET 1 +#define RTL8367C_NIC_RXAPE_MASK 0x2 +#define RTL8367C_NIC_ARPPE_OFFSET 0 +#define RTL8367C_NIC_ARPPE_MASK 0x1 + +#define RTL8367C_REG_NIC_RXCR1 0x1a15 +#define RTL8367C_NIC_RL4CEPE_OFFSET 4 +#define RTL8367C_NIC_RL4CEPE_MASK 0x10 +#define RTL8367C_NIC_RL3CEPE_OFFSET 3 +#define RTL8367C_NIC_RL3CEPE_MASK 0x8 +#define RTL8367C_NIC_RCRCEPE_OFFSET 2 +#define RTL8367C_NIC_RCRCEPE_MASK 0x4 +#define RTL8367C_NIC_RMCRC_OFFSET 1 +#define RTL8367C_NIC_RMCRC_MASK 0x2 +#define RTL8367C_NIC_RXENABLE_OFFSET 0 +#define RTL8367C_NIC_RXENABLE_MASK 0x1 + +#define RTL8367C_REG_NIC_TXCR 0x1a16 +#define RTL8367C_NIC_LBE_OFFSET 2 +#define RTL8367C_NIC_LBE_MASK 0x4 +#define RTL8367C_NIC_TXMFM_OFFSET 1 +#define RTL8367C_NIC_TXMFM_MASK 0x2 +#define RTL8367C_NIC_TXENABLE_OFFSET 0 +#define RTL8367C_NIC_TXENABLE_MASK 0x1 + +#define RTL8367C_REG_NIC_GCR 0x1a17 +#define RTL8367C_DUMMY_7_6_OFFSET 6 +#define RTL8367C_DUMMY_7_6_MASK 0xC0 +#define RTL8367C_NIC_RXMTU_OFFSET 4 +#define RTL8367C_NIC_RXMTU_MASK 0x30 +#define RTL8367C_NIC_GCR_DUMMY_0_OFFSET 0 +#define RTL8367C_NIC_GCR_DUMMY_0_MASK 0x1 + +#define RTL8367C_REG_NIC_MHR0 0x1a24 +#define RTL8367C_NIC_MHR0_OFFSET 0 +#define RTL8367C_NIC_MHR0_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR1 0x1a25 +#define RTL8367C_NIC_MHR1_OFFSET 0 +#define RTL8367C_NIC_MHR1_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR2 0x1a26 +#define RTL8367C_NIC_MHR2_OFFSET 0 +#define RTL8367C_NIC_MHR2_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR3 0x1a27 +#define RTL8367C_NIC_MHR3_OFFSET 0 +#define RTL8367C_NIC_MHR3_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR4 0x1a28 +#define RTL8367C_NIC_MHR4_OFFSET 0 +#define RTL8367C_NIC_MHR4_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR5 0x1a29 +#define RTL8367C_NIC_MHR5_OFFSET 0 +#define RTL8367C_NIC_MHR5_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR6 0x1a2a +#define RTL8367C_NIC_MHR6_OFFSET 0 +#define RTL8367C_NIC_MHR6_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR7 0x1a2b +#define RTL8367C_NIC_MHR7_OFFSET 0 +#define RTL8367C_NIC_MHR7_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR0 0x1a2c +#define RTL8367C_NIC_PAHR0_OFFSET 0 +#define RTL8367C_NIC_PAHR0_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR1 0x1a2d +#define RTL8367C_NIC_PAHR1_OFFSET 0 +#define RTL8367C_NIC_PAHR1_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR2 0x1a2e +#define RTL8367C_NIC_PAHR2_OFFSET 0 +#define RTL8367C_NIC_PAHR2_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR3 0x1a2f +#define RTL8367C_NIC_PAHR3_OFFSET 0 +#define RTL8367C_NIC_PAHR3_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR4 0x1a30 +#define RTL8367C_NIC_PAHR4_OFFSET 0 +#define RTL8367C_NIC_PAHR4_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR5 0x1a31 +#define RTL8367C_NIC_PAHR5_OFFSET 0 +#define RTL8367C_NIC_PAHR5_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR6 0x1a32 +#define RTL8367C_NIC_PAHR6_OFFSET 0 +#define RTL8367C_NIC_PAHR6_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR7 0x1a33 +#define RTL8367C_NIC_PAHR7_OFFSET 0 +#define RTL8367C_NIC_PAHR7_MASK 0xFF + +#define RTL8367C_REG_NIC_TXSTOPRL 0x1a44 +#define RTL8367C_NIC_TXSTOPRL_OFFSET 0 +#define RTL8367C_NIC_TXSTOPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_TXSTOPRH 0x1a45 +#define RTL8367C_NIC_TXSTOPRH_OFFSET 0 +#define RTL8367C_NIC_TXSTOPRH_MASK 0x3 + +#define RTL8367C_REG_NIC_RXSTOPRL 0x1a46 +#define RTL8367C_NIC_RXSTOPRL_OFFSET 0 +#define RTL8367C_NIC_RXSTOPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_RXSTOPRH 0x1a47 +#define RTL8367C_NIC_RXSTOPRH_OFFSET 0 +#define RTL8367C_NIC_RXSTOPRH_MASK 0x3 + +#define RTL8367C_REG_NIC_RXFSTR 0x1a48 +#define RTL8367C_NIC_RXFSTR_OFFSET 0 +#define RTL8367C_NIC_RXFSTR_MASK 0xFF + +#define RTL8367C_REG_NIC_RXMBTRL 0x1a4c +#define RTL8367C_NIC_RXMBTRL_OFFSET 0 +#define RTL8367C_NIC_RXMBTRL_MASK 0xFF + +#define RTL8367C_REG_NIC_RXMBTRH 0x1a4d +#define RTL8367C_NIC_RXMBTRH_OFFSET 0 +#define RTL8367C_NIC_RXMBTRH_MASK 0x7F + +#define RTL8367C_REG_NIC_RXMPTR 0x1a4e +#define RTL8367C_NIC_RXMPTR_OFFSET 0 +#define RTL8367C_NIC_RXMPTR_MASK 0xFF + +#define RTL8367C_REG_NIC_T0TR 0x1a4f +#define RTL8367C_NIC_T0TR_OFFSET 0 +#define RTL8367C_NIC_T0TR_MASK 0xFF + +#define RTL8367C_REG_NIC_CRXCPRL 0x1a50 +#define RTL8367C_NIC_CRXCPRL_OFFSET 0 +#define RTL8367C_NIC_CRXCPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_CRXCPRH 0x1a51 +#define RTL8367C_NIC_CRXCPRH_OFFSET 0 +#define RTL8367C_NIC_CRXCPRH_MASK 0xFF + +#define RTL8367C_REG_NIC_CTXCPRL 0x1a52 +#define RTL8367C_NIC_CTXCPRL_OFFSET 0 +#define RTL8367C_NIC_CTXCPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_CTXPCRH 0x1a53 +#define RTL8367C_NIC_CTXPCRH_OFFSET 0 +#define RTL8367C_NIC_CTXPCRH_MASK 0xFF + +#define RTL8367C_REG_NIC_SRXCURPKTRL 0x1a54 +#define RTL8367C_NIC_SRXCURPKTRL_OFFSET 0 +#define RTL8367C_NIC_SRXCURPKTRL_MASK 0xFF + +#define RTL8367C_REG_NIC_SRXCURPKTRH 0x1a55 +#define RTL8367C_NIC_SRXCURPKTRH_OFFSET 0 +#define RTL8367C_NIC_SRXCURPKTRH_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURPKTRL 0x1a56 +#define RTL8367C_NIC_STXCURPKTRL_OFFSET 0 +#define RTL8367C_NIC_STXCURPKTRL_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURPKTRH 0x1a57 +#define RTL8367C_NIC_STXCURPKTRH_OFFSET 0 +#define RTL8367C_NIC_STXCURPKTRH_MASK 0xFF + +#define RTL8367C_REG_NIC_STXPKTLENRL 0x1a58 +#define RTL8367C_NIC_STXPKTLENRL_OFFSET 0 +#define RTL8367C_NIC_STXPKTLENRL_MASK 0xFF + +#define RTL8367C_REG_NIC_STXPKTLENRH 0x1a59 +#define RTL8367C_NIC_STXPKTLENRH_OFFSET 0 +#define RTL8367C_NIC_STXPKTLENRH_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURUNITRL 0x1a5a +#define RTL8367C_NIC_STXCURUNITRL_OFFSET 0 +#define RTL8367C_NIC_STXCURUNITRL_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURUNITRH 0x1a5b +#define RTL8367C_NIC_STXCURUNITRH_OFFSET 0 +#define RTL8367C_NIC_STXCURUNITRH_MASK 0xFF + +#define RTL8367C_REG_NIC_DROP_MODE 0x1a5c +#define RTL8367C_NIC_RXDV_MODE_OFFSET 1 +#define RTL8367C_NIC_RXDV_MODE_MASK 0x2 +#define RTL8367C_NIC_DROP_MODE_OFFSET 0 +#define RTL8367C_NIC_DROP_MODE_MASK 0x1 + +/* (16'h1b00)LED */ + +#define RTL8367C_REG_LED_SYS_CONFIG 0x1b00 +#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_OFFSET 15 +#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_MASK 0x8000 +#define RTL8367C_LED_SERIAL_OUT_MODE_OFFSET 14 +#define RTL8367C_LED_SERIAL_OUT_MODE_MASK 0x4000 +#define RTL8367C_LED_EEE_LPI_MODE_OFFSET 13 +#define RTL8367C_LED_EEE_LPI_MODE_MASK 0x2000 +#define RTL8367C_LED_EEE_LPI_EN_OFFSET 12 +#define RTL8367C_LED_EEE_LPI_EN_MASK 0x1000 +#define RTL8367C_LED_EEE_LPI_10_OFFSET 11 +#define RTL8367C_LED_EEE_LPI_10_MASK 0x800 +#define RTL8367C_LED_EEE_CAP_10_OFFSET 10 +#define RTL8367C_LED_EEE_CAP_10_MASK 0x400 +#define RTL8367C_LED_LPI_SEL_OFFSET 8 +#define RTL8367C_LED_LPI_SEL_MASK 0x300 +#define RTL8367C_SERI_LED_ACT_LOW_OFFSET 7 +#define RTL8367C_SERI_LED_ACT_LOW_MASK 0x80 +#define RTL8367C_LED_POWERON_2_OFFSET 6 +#define RTL8367C_LED_POWERON_2_MASK 0x40 +#define RTL8367C_LED_POWERON_1_OFFSET 5 +#define RTL8367C_LED_POWERON_1_MASK 0x20 +#define RTL8367C_LED_POWERON_0_OFFSET 4 +#define RTL8367C_LED_POWERON_0_MASK 0x10 +#define RTL8367C_LED_IO_DISABLE_OFFSET 3 +#define RTL8367C_LED_IO_DISABLE_MASK 0x8 +#define RTL8367C_DUMMY_2_2_OFFSET 2 +#define RTL8367C_DUMMY_2_2_MASK 0x4 +#define RTL8367C_LED_SELECT_OFFSET 0 +#define RTL8367C_LED_SELECT_MASK 0x3 + +#define RTL8367C_REG_LED_SYS_CONFIG2 0x1b01 +#define RTL8367C_LED_SYS_CONFIG2_DUMMY_OFFSET 2 +#define RTL8367C_LED_SYS_CONFIG2_DUMMY_MASK 0xFFFC +#define RTL8367C_GATE_LPTD_BYPASS_OFFSET 1 +#define RTL8367C_GATE_LPTD_BYPASS_MASK 0x2 +#define RTL8367C_LED_SPD_MODE_OFFSET 0 +#define RTL8367C_LED_SPD_MODE_MASK 0x1 + +#define RTL8367C_REG_LED_MODE 0x1b02 +#define RTL8367C_DLINK_TIME_OFFSET 15 +#define RTL8367C_DLINK_TIME_MASK 0x8000 +#define RTL8367C_LED_BUZZ_DUTY_OFFSET 14 +#define RTL8367C_LED_BUZZ_DUTY_MASK 0x4000 +#define RTL8367C_BUZZER_RATE_OFFSET 12 +#define RTL8367C_BUZZER_RATE_MASK 0x3000 +#define RTL8367C_LOOP_DETECT_MODE_OFFSET 11 +#define RTL8367C_LOOP_DETECT_MODE_MASK 0x800 +#define RTL8367C_SEL_PWRON_TIME_OFFSET 9 +#define RTL8367C_SEL_PWRON_TIME_MASK 0x600 +#define RTL8367C_EN_DLINK_LED_OFFSET 8 +#define RTL8367C_EN_DLINK_LED_MASK 0x100 +#define RTL8367C_LOOP_DETECT_RATE_OFFSET 6 +#define RTL8367C_LOOP_DETECT_RATE_MASK 0xC0 +#define RTL8367C_FORCE_RATE_OFFSET 4 +#define RTL8367C_FORCE_RATE_MASK 0x30 +#define RTL8367C_SEL_LEDRATE_OFFSET 1 +#define RTL8367C_SEL_LEDRATE_MASK 0xE +#define RTL8367C_SPEED_UP_OFFSET 0 +#define RTL8367C_SPEED_UP_MASK 0x1 + +#define RTL8367C_REG_LED_CONFIGURATION 0x1b03 +#define RTL8367C_LED_CONFIGURATION_DUMMY_OFFSET 15 +#define RTL8367C_LED_CONFIGURATION_DUMMY_MASK 0x8000 +#define RTL8367C_LED_CONFIG_SEL_OFFSET 14 +#define RTL8367C_LED_CONFIG_SEL_MASK 0x4000 +#define RTL8367C_DATA_LED_OFFSET 12 +#define RTL8367C_DATA_LED_MASK 0x3000 +#define RTL8367C_LED2_CFG_OFFSET 8 +#define RTL8367C_LED2_CFG_MASK 0xF00 +#define RTL8367C_LED1_CFG_OFFSET 4 +#define RTL8367C_LED1_CFG_MASK 0xF0 +#define RTL8367C_LED0_CFG_OFFSET 0 +#define RTL8367C_LED0_CFG_MASK 0xF + +#define RTL8367C_REG_RTCT_RESULTS_CFG 0x1b04 +#define RTL8367C_RTCT_2PAIR_FTT_OFFSET 15 +#define RTL8367C_RTCT_2PAIR_FTT_MASK 0x8000 +#define RTL8367C_RTCT_2PAIR_MODE_OFFSET 14 +#define RTL8367C_RTCT_2PAIR_MODE_MASK 0x4000 +#define RTL8367C_BLINK_EN_OFFSET 13 +#define RTL8367C_BLINK_EN_MASK 0x2000 +#define RTL8367C_TIMEOUT_OFFSET 12 +#define RTL8367C_TIMEOUT_MASK 0x1000 +#define RTL8367C_EN_CD_SAME_SHORT_OFFSET 11 +#define RTL8367C_EN_CD_SAME_SHORT_MASK 0x800 +#define RTL8367C_EN_CD_SAME_OPEN_OFFSET 10 +#define RTL8367C_EN_CD_SAME_OPEN_MASK 0x400 +#define RTL8367C_EN_CD_SAME_LINEDRIVER_OFFSET 9 +#define RTL8367C_EN_CD_SAME_LINEDRIVER_MASK 0x200 +#define RTL8367C_EN_CD_SAME_MISMATCH_OFFSET 8 +#define RTL8367C_EN_CD_SAME_MISMATCH_MASK 0x100 +#define RTL8367C_EN_CD_SHORT_OFFSET 7 +#define RTL8367C_EN_CD_SHORT_MASK 0x80 +#define RTL8367C_EN_AB_SHORT_OFFSET 6 +#define RTL8367C_EN_AB_SHORT_MASK 0x40 +#define RTL8367C_EN_CD_OPEN_OFFSET 5 +#define RTL8367C_EN_CD_OPEN_MASK 0x20 +#define RTL8367C_EN_AB_OPEN_OFFSET 4 +#define RTL8367C_EN_AB_OPEN_MASK 0x10 +#define RTL8367C_EN_CD_MISMATCH_OFFSET 3 +#define RTL8367C_EN_CD_MISMATCH_MASK 0x8 +#define RTL8367C_EN_AB_MISMATCH_OFFSET 2 +#define RTL8367C_EN_AB_MISMATCH_MASK 0x4 +#define RTL8367C_EN_CD_LINEDRIVER_OFFSET 1 +#define RTL8367C_EN_CD_LINEDRIVER_MASK 0x2 +#define RTL8367C_EN_AB_LINEDRIVER_OFFSET 0 +#define RTL8367C_EN_AB_LINEDRIVER_MASK 0x1 + +#define RTL8367C_REG_RTCT_LED 0x1b05 +#define RTL8367C_DUMMY_1b05a_OFFSET 12 +#define RTL8367C_DUMMY_1b05a_MASK 0xF000 +#define RTL8367C_RTCT_LED2_OFFSET 8 +#define RTL8367C_RTCT_LED2_MASK 0xF00 +#define RTL8367C_RTCT_LED1_OFFSET 4 +#define RTL8367C_RTCT_LED1_MASK 0xF0 +#define RTL8367C_RTCT_LED0_OFFSET 0 +#define RTL8367C_RTCT_LED0_MASK 0xF + +#define RTL8367C_REG_CPU_FORCE_LED_CFG 0x1b07 +#define RTL8367C_DUMMY_1b07a_OFFSET 8 +#define RTL8367C_DUMMY_1b07a_MASK 0xFF00 +#define RTL8367C_LED_FORCE_MODE_OFFSET 2 +#define RTL8367C_LED_FORCE_MODE_MASK 0xFC +#define RTL8367C_FORCE_MODE_OFFSET 0 +#define RTL8367C_FORCE_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED0_CFG0 0x1b08 +#define RTL8367C_PORT7_LED0_MODE_OFFSET 14 +#define RTL8367C_PORT7_LED0_MODE_MASK 0xC000 +#define RTL8367C_PORT6_LED0_MODE_OFFSET 12 +#define RTL8367C_PORT6_LED0_MODE_MASK 0x3000 +#define RTL8367C_PORT5_LED0_MODE_OFFSET 10 +#define RTL8367C_PORT5_LED0_MODE_MASK 0xC00 +#define RTL8367C_PORT4_LED0_MODE_OFFSET 8 +#define RTL8367C_PORT4_LED0_MODE_MASK 0x300 +#define RTL8367C_PORT3_LED0_MODE_OFFSET 6 +#define RTL8367C_PORT3_LED0_MODE_MASK 0xC0 +#define RTL8367C_PORT2_LED0_MODE_OFFSET 4 +#define RTL8367C_PORT2_LED0_MODE_MASK 0x30 +#define RTL8367C_PORT1_LED0_MODE_OFFSET 2 +#define RTL8367C_PORT1_LED0_MODE_MASK 0xC +#define RTL8367C_PORT0_LED0_MODE_OFFSET 0 +#define RTL8367C_PORT0_LED0_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED0_CFG1 0x1b09 +#define RTL8367C_DUMMY_1b09a_OFFSET 4 +#define RTL8367C_DUMMY_1b09a_MASK 0xFFF0 +#define RTL8367C_PORT9_LED0_MODE_OFFSET 2 +#define RTL8367C_PORT9_LED0_MODE_MASK 0xC +#define RTL8367C_PORT8_LED0_MODE_OFFSET 0 +#define RTL8367C_PORT8_LED0_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED1_CFG0 0x1b0a +#define RTL8367C_PORT7_LED1_MODE_OFFSET 14 +#define RTL8367C_PORT7_LED1_MODE_MASK 0xC000 +#define RTL8367C_PORT6_LED1_MODE_OFFSET 12 +#define RTL8367C_PORT6_LED1_MODE_MASK 0x3000 +#define RTL8367C_PORT5_LED1_MODE_OFFSET 10 +#define RTL8367C_PORT5_LED1_MODE_MASK 0xC00 +#define RTL8367C_PORT4_LED1_MODE_OFFSET 8 +#define RTL8367C_PORT4_LED1_MODE_MASK 0x300 +#define RTL8367C_PORT3_LED1_MODE_OFFSET 6 +#define RTL8367C_PORT3_LED1_MODE_MASK 0xC0 +#define RTL8367C_PORT2_LED1_MODE_OFFSET 4 +#define RTL8367C_PORT2_LED1_MODE_MASK 0x30 +#define RTL8367C_PORT1_LED1_MODE_OFFSET 2 +#define RTL8367C_PORT1_LED1_MODE_MASK 0xC +#define RTL8367C_PORT0_LED1_MODE_OFFSET 0 +#define RTL8367C_PORT0_LED1_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED1_CFG1 0x1b0b +#define RTL8367C_DUMMY_1b0ba_OFFSET 4 +#define RTL8367C_DUMMY_1b0ba_MASK 0xFFF0 +#define RTL8367C_PORT9_LED1_MODE_OFFSET 2 +#define RTL8367C_PORT9_LED1_MODE_MASK 0xC +#define RTL8367C_PORT8_LED1_MODE_OFFSET 0 +#define RTL8367C_PORT8_LED1_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED2_CFG0 0x1b0c +#define RTL8367C_PORT7_LED2_MODE_OFFSET 14 +#define RTL8367C_PORT7_LED2_MODE_MASK 0xC000 +#define RTL8367C_PORT6_LED2_MODE_OFFSET 12 +#define RTL8367C_PORT6_LED2_MODE_MASK 0x3000 +#define RTL8367C_PORT5_LED2_MODE_OFFSET 10 +#define RTL8367C_PORT5_LED2_MODE_MASK 0xC00 +#define RTL8367C_PORT4_LED2_MODE_OFFSET 8 +#define RTL8367C_PORT4_LED2_MODE_MASK 0x300 +#define RTL8367C_PORT3_LED2_MODE_OFFSET 6 +#define RTL8367C_PORT3_LED2_MODE_MASK 0xC0 +#define RTL8367C_PORT2_LED2_MODE_OFFSET 4 +#define RTL8367C_PORT2_LED2_MODE_MASK 0x30 +#define RTL8367C_PORT1_LED2_MODE_OFFSET 2 +#define RTL8367C_PORT1_LED2_MODE_MASK 0xC +#define RTL8367C_PORT0_LED2_MODE_OFFSET 0 +#define RTL8367C_PORT0_LED2_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED2_CFG1 0x1b0d +#define RTL8367C_DUMMY_1b0da_OFFSET 4 +#define RTL8367C_DUMMY_1b0da_MASK 0xFFF0 +#define RTL8367C_PORT9_LED2_MODE_OFFSET 2 +#define RTL8367C_PORT9_LED2_MODE_MASK 0xC +#define RTL8367C_PORT8_LED2_MODE_OFFSET 0 +#define RTL8367C_PORT8_LED2_MODE_MASK 0x3 + +#define RTL8367C_REG_LED_ACTIVE_LOW_CFG0 0x1b0e +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_OFFSET 15 +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_MASK 0x8000 +#define RTL8367C_PORT3_LED_ACTIVE_LOW_OFFSET 12 +#define RTL8367C_PORT3_LED_ACTIVE_LOW_MASK 0x7000 +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_OFFSET 11 +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_MASK 0x800 +#define RTL8367C_PORT2_LED_ACTIVE_LOW_OFFSET 8 +#define RTL8367C_PORT2_LED_ACTIVE_LOW_MASK 0x700 +#define RTL8367C_DUMMY_7_OFFSET 7 +#define RTL8367C_DUMMY_7_MASK 0x80 +#define RTL8367C_PORT1_LED_ACTIVE_LOW_OFFSET 4 +#define RTL8367C_PORT1_LED_ACTIVE_LOW_MASK 0x70 +#define RTL8367C_DUMMY_3_OFFSET 3 +#define RTL8367C_DUMMY_3_MASK 0x8 +#define RTL8367C_PORT0_LED_ACTIVE_LOW_OFFSET 0 +#define RTL8367C_PORT0_LED_ACTIVE_LOW_MASK 0x7 + +#define RTL8367C_REG_LED_ACTIVE_LOW_CFG1 0x1b0f +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_OFFSET 15 +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_MASK 0x8000 +#define RTL8367C_PORT7_LED_ACTIVE_LOW_OFFSET 12 +#define RTL8367C_PORT7_LED_ACTIVE_LOW_MASK 0x7000 +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_OFFSET 11 +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_MASK 0x800 +#define RTL8367C_PORT6_LED_ACTIVE_LOW_OFFSET 8 +#define RTL8367C_PORT6_LED_ACTIVE_LOW_MASK 0x700 +#define RTL8367C_DUMMY_1b0f_b_OFFSET 7 +#define RTL8367C_DUMMY_1b0f_b_MASK 0x80 +#define RTL8367C_PORT5_LED_ACTIVE_LOW_OFFSET 4 +#define RTL8367C_PORT5_LED_ACTIVE_LOW_MASK 0x70 +#define RTL8367C_DUMMY_1b0f_a_OFFSET 3 +#define RTL8367C_DUMMY_1b0f_a_MASK 0x8 +#define RTL8367C_PORT4_LED_ACTIVE_LOW_OFFSET 0 +#define RTL8367C_PORT4_LED_ACTIVE_LOW_MASK 0x7 + +#define RTL8367C_REG_LED_ACTIVE_LOW_CFG2 0x1b10 +#define RTL8367C_DUMMY_1b10_b_OFFSET 7 +#define RTL8367C_DUMMY_1b10_b_MASK 0xFF80 +#define RTL8367C_PORT9_LED_ACTIVE_LOW_OFFSET 4 +#define RTL8367C_PORT9_LED_ACTIVE_LOW_MASK 0x70 +#define RTL8367C_DUMMY_1b10_a_OFFSET 3 +#define RTL8367C_DUMMY_1b10_a_MASK 0x8 +#define RTL8367C_PORT8_LED_ACTIVE_LOW_OFFSET 0 +#define RTL8367C_PORT8_LED_ACTIVE_LOW_MASK 0x7 + +#define RTL8367C_REG_SEL_RTCT_PARA 0x1b21 +#define RTL8367C_DO_RTCT_COMMAND_OFFSET 15 +#define RTL8367C_DO_RTCT_COMMAND_MASK 0x8000 +#define RTL8367C_SEL_RTCT_PARA_DUMMY_OFFSET 12 +#define RTL8367C_SEL_RTCT_PARA_DUMMY_MASK 0x7000 +#define RTL8367C_SEL_RTCT_RLSTLED_TIME_OFFSET 10 +#define RTL8367C_SEL_RTCT_RLSTLED_TIME_MASK 0xC00 +#define RTL8367C_SEL_RTCT_TEST_LED_TIME_OFFSET 8 +#define RTL8367C_SEL_RTCT_TEST_LED_TIME_MASK 0x300 +#define RTL8367C_EN_SCAN_RTCT_OFFSET 7 +#define RTL8367C_EN_SCAN_RTCT_MASK 0x80 +#define RTL8367C_EN_RTCT_TIMOUT_OFFSET 6 +#define RTL8367C_EN_RTCT_TIMOUT_MASK 0x40 +#define RTL8367C_EN_ALL_RTCT_OFFSET 5 +#define RTL8367C_EN_ALL_RTCT_MASK 0x20 +#define RTL8367C_SEL_RTCT_PLE_WID_OFFSET 0 +#define RTL8367C_SEL_RTCT_PLE_WID_MASK 0x1F + +#define RTL8367C_REG_RTCT_ENABLE 0x1b22 +#define RTL8367C_RTCT_ENABLE_DUMMY_OFFSET 8 +#define RTL8367C_RTCT_ENABLE_DUMMY_MASK 0xFF00 +#define RTL8367C_RTCT_ENABLE_PORT_MASK_OFFSET 0 +#define RTL8367C_RTCT_ENABLE_PORT_MASK_MASK 0xFF + +#define RTL8367C_REG_RTCT_TIMEOUT 0x1b23 + +#define RTL8367C_REG_PARA_LED_IO_EN1 0x1b24 +#define RTL8367C_LED1_PARA_P07_00_OFFSET 8 +#define RTL8367C_LED1_PARA_P07_00_MASK 0xFF00 +#define RTL8367C_LED0_PARA_P07_00_OFFSET 0 +#define RTL8367C_LED0_PARA_P07_00_MASK 0xFF + +#define RTL8367C_REG_PARA_LED_IO_EN2 0x1b25 +#define RTL8367C_DUMMY_15_8_OFFSET 8 +#define RTL8367C_DUMMY_15_8_MASK 0xFF00 +#define RTL8367C_LED2_PARA_P07_00_OFFSET 0 +#define RTL8367C_LED2_PARA_P07_00_MASK 0xFF + +#define RTL8367C_REG_SCAN0_LED_IO_EN1 0x1b26 +#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_OFFSET 3 +#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_MASK 0xFFF8 +#define RTL8367C_LED_LOOP_DET_BUZZER_EN_OFFSET 2 +#define RTL8367C_LED_LOOP_DET_BUZZER_EN_MASK 0x4 +#define RTL8367C_LED_SERI_DATA_EN_OFFSET 1 +#define RTL8367C_LED_SERI_DATA_EN_MASK 0x2 +#define RTL8367C_LED_SERI_CLK_EN_OFFSET 0 +#define RTL8367C_LED_SERI_CLK_EN_MASK 0x1 + +#define RTL8367C_REG_SCAN1_LED_IO_EN2 0x1b27 +#define RTL8367C_LED_SCAN1_BI_PORT_EN_OFFSET 8 +#define RTL8367C_LED_SCAN1_BI_PORT_EN_MASK 0xFF00 +#define RTL8367C_LED_SCAN1_BI_STA_EN_OFFSET 7 +#define RTL8367C_LED_SCAN1_BI_STA_EN_MASK 0x80 +#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_OFFSET 6 +#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_MASK 0x40 +#define RTL8367C_LED_SCAN1_SI_PORT_EN_OFFSET 2 +#define RTL8367C_LED_SCAN1_SI_PORT_EN_MASK 0x3C +#define RTL8367C_LED_SCAN1_SI_STA_EN_OFFSET 0 +#define RTL8367C_LED_SCAN1_SI_STA_EN_MASK 0x3 + +#define RTL8367C_REG_LPI_LED_OPT1 0x1b28 +#define RTL8367C_LPI_TAG4_OFFSET 12 +#define RTL8367C_LPI_TAG4_MASK 0xF000 +#define RTL8367C_LPI_TAG3_OFFSET 8 +#define RTL8367C_LPI_TAG3_MASK 0xF00 +#define RTL8367C_LPI_TAG2_OFFSET 4 +#define RTL8367C_LPI_TAG2_MASK 0xF0 +#define RTL8367C_LPI_TAG1_OFFSET 0 +#define RTL8367C_LPI_TAG1_MASK 0xF + +#define RTL8367C_REG_LPI_LED_OPT2 0x1b29 +#define RTL8367C_LPI_LED_OPT2_DUMMY_OFFSET 15 +#define RTL8367C_LPI_LED_OPT2_DUMMY_MASK 0x8000 +#define RTL8367C_LPI_LED2_WEAK_OFFSET 14 +#define RTL8367C_LPI_LED2_WEAK_MASK 0x4000 +#define RTL8367C_LPI_LED1_WEAK_OFFSET 13 +#define RTL8367C_LPI_LED1_WEAK_MASK 0x2000 +#define RTL8367C_LPI_LED0_WEAK_OFFSET 12 +#define RTL8367C_LPI_LED0_WEAK_MASK 0x1000 +#define RTL8367C_LPI_LED2_OFFSET 11 +#define RTL8367C_LPI_LED2_MASK 0x800 +#define RTL8367C_LPI_LED1_OFFSET 10 +#define RTL8367C_LPI_LED1_MASK 0x400 +#define RTL8367C_LPI_LED0_OFFSET 9 +#define RTL8367C_LPI_LED0_MASK 0x200 +#define RTL8367C_LPI_TAG8_OFFSET 8 +#define RTL8367C_LPI_TAG8_MASK 0x100 +#define RTL8367C_LPI_TAG7_OFFSET 6 +#define RTL8367C_LPI_TAG7_MASK 0xC0 +#define RTL8367C_LPI_TAG6_OFFSET 4 +#define RTL8367C_LPI_TAG6_MASK 0x30 +#define RTL8367C_LPI_TAG5_OFFSET 0 +#define RTL8367C_LPI_TAG5_MASK 0xF + +#define RTL8367C_REG_LPI_LED_OPT3 0x1b2a +#define RTL8367C_LPI_LED_OPT3_DUMMY_OFFSET 3 +#define RTL8367C_LPI_LED_OPT3_DUMMY_MASK 0xFFF8 +#define RTL8367C_RESTORE_LED_RATE_SEL_OFFSET 1 +#define RTL8367C_RESTORE_LED_RATE_SEL_MASK 0x6 +#define RTL8367C_RESTORE_LED_SEL_OFFSET 0 +#define RTL8367C_RESTORE_LED_SEL_MASK 0x1 + +#define RTL8367C_REG_P0_LED_MUX 0x1b2b +#define RTL8367C_CFG_P0_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P0_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P0_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P0_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P0_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P0_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P1_LED_MUX 0x1b2c +#define RTL8367C_CFG_P1_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P1_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P1_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P1_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P1_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P1_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P2_LED_MUX 0x1b2d +#define RTL8367C_CFG_P2_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P2_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P2_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P2_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P2_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P2_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P3_LED_MUX 0x1b2e +#define RTL8367C_CFG_P3_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P3_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P3_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P3_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P3_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P3_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P4_LED_MUX 0x1b2f +#define RTL8367C_CFG_P4_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P4_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P4_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P4_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P4_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P4_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_LED0_DATA_CTRL 0x1b30 +#define RTL8367C_CFG_DATA_LED0_SEL_OFFSET 6 +#define RTL8367C_CFG_DATA_LED0_SEL_MASK 0x40 +#define RTL8367C_CFG_DATA_LED0_ACT_OFFSET 4 +#define RTL8367C_CFG_DATA_LED0_ACT_MASK 0x30 +#define RTL8367C_CFG_DATA_LED0_SPD_OFFSET 0 +#define RTL8367C_CFG_DATA_LED0_SPD_MASK 0xF + +#define RTL8367C_REG_LED1_DATA_CTRL 0x1b31 +#define RTL8367C_CFG_DATA_LED1_SEL_OFFSET 6 +#define RTL8367C_CFG_DATA_LED1_SEL_MASK 0x40 +#define RTL8367C_CFG_DATA_LED1_ACT_OFFSET 4 +#define RTL8367C_CFG_DATA_LED1_ACT_MASK 0x30 +#define RTL8367C_CFG_DATA_LED1_SPD_OFFSET 0 +#define RTL8367C_CFG_DATA_LED1_SPD_MASK 0xF + +#define RTL8367C_REG_LED2_DATA_CTRL 0x1b32 +#define RTL8367C_CFG_DATA_LED2_SEL_OFFSET 6 +#define RTL8367C_CFG_DATA_LED2_SEL_MASK 0x40 +#define RTL8367C_CFG_DATA_LED2_ACT_OFFSET 4 +#define RTL8367C_CFG_DATA_LED2_ACT_MASK 0x30 +#define RTL8367C_CFG_DATA_LED2_SPD_OFFSET 0 +#define RTL8367C_CFG_DATA_LED2_SPD_MASK 0xF + +#define RTL8367C_REG_PARA_LED_IO_EN3 0x1b33 +#define RTL8367C_dummy_1b33a_OFFSET 6 +#define RTL8367C_dummy_1b33a_MASK 0xFFC0 +#define RTL8367C_LED2_PARA_P09_08_OFFSET 4 +#define RTL8367C_LED2_PARA_P09_08_MASK 0x30 +#define RTL8367C_LED1_PARA_P09_08_OFFSET 2 +#define RTL8367C_LED1_PARA_P09_08_MASK 0xC +#define RTL8367C_LED0_PARA_P09_08_OFFSET 0 +#define RTL8367C_LED0_PARA_P09_08_MASK 0x3 + +#define RTL8367C_REG_SCAN1_LED_IO_EN3 0x1b34 +#define RTL8367C_dummy_1b34a_OFFSET 3 +#define RTL8367C_dummy_1b34a_MASK 0xFFF8 +#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_OFFSET 1 +#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_MASK 0x6 +#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_OFFSET 0 +#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_MASK 0x1 + +#define RTL8367C_REG_P5_LED_MUX 0x1b35 +#define RTL8367C_CFG_P5_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P5_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P5_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P5_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P5_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P5_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P6_LED_MUX 0x1b36 +#define RTL8367C_CFG_P6_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P6_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P6_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P6_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P6_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P6_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P7_LED_MUX 0x1b37 +#define RTL8367C_CFG_P7_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P7_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P7_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P7_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P7_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P7_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P8_LED_MUX 0x1b38 +#define RTL8367C_CFG_P8_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P8_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P8_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P8_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P8_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P8_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P9_LED_MUX 0x1b39 +#define RTL8367C_CFG_P9_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P9_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P9_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P9_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P9_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P9_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_SERIAL_LED_CTRL 0x1b3a +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_OFFSET 13 +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_MASK 0x6000 +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_OFFSET 12 +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_MASK 0x1000 +#define RTL8367C_SERIAL_LED_GROUP_NUM_OFFSET 10 +#define RTL8367C_SERIAL_LED_GROUP_NUM_MASK 0xC00 +#define RTL8367C_SERIAL_LED_PORT_EN_OFFSET 0 +#define RTL8367C_SERIAL_LED_PORT_EN_MASK 0x3FF + +/* (16'h1c00)IGMP_EAV */ + +#define RTL8367C_REG_IGMP_MLD_CFG0 0x1c00 +#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET 15 +#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_MASK 0x8000 +#define RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET 14 +#define RTL8367C_IGMP_MLD_VLAN_LEAKY_MASK 0x4000 +#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET 13 +#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_MASK 0x2000 +#define RTL8367C_REPORT_FORWARD_OFFSET 12 +#define RTL8367C_REPORT_FORWARD_MASK 0x1000 +#define RTL8367C_ROBURSTNESS_VAR_OFFSET 9 +#define RTL8367C_ROBURSTNESS_VAR_MASK 0xE00 +#define RTL8367C_LEAVE_SUPPRESSION_OFFSET 8 +#define RTL8367C_LEAVE_SUPPRESSION_MASK 0x100 +#define RTL8367C_REPORT_SUPPRESSION_OFFSET 7 +#define RTL8367C_REPORT_SUPPRESSION_MASK 0x80 +#define RTL8367C_LEAVE_TIMER_OFFSET 4 +#define RTL8367C_LEAVE_TIMER_MASK 0x70 +#define RTL8367C_FAST_LEAVE_EN_OFFSET 3 +#define RTL8367C_FAST_LEAVE_EN_MASK 0x8 +#define RTL8367C_CKS_ERR_OP_OFFSET 1 +#define RTL8367C_CKS_ERR_OP_MASK 0x6 +#define RTL8367C_IGMP_MLD_EN_OFFSET 0 +#define RTL8367C_IGMP_MLD_EN_MASK 0x1 + +#define RTL8367C_REG_IGMP_MLD_CFG1 0x1c01 +#define RTL8367C_DROP_LEAVE_ZERO_OFFSET 2 +#define RTL8367C_DROP_LEAVE_ZERO_MASK 0x4 +#define RTL8367C_TABLE_FULL_OP_OFFSET 0 +#define RTL8367C_TABLE_FULL_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_MLD_CFG2 0x1c02 + +#define RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT 0x1c03 +#define RTL8367C_D_ROUTER_PORT_2_OFFSET 11 +#define RTL8367C_D_ROUTER_PORT_2_MASK 0x7800 +#define RTL8367C_D_ROUTER_PORT_TMR_2_OFFSET 8 +#define RTL8367C_D_ROUTER_PORT_TMR_2_MASK 0x700 +#define RTL8367C_D_ROUTER_PORT_1_OFFSET 3 +#define RTL8367C_D_ROUTER_PORT_1_MASK 0x78 +#define RTL8367C_D_ROUTER_PORT_TMR_1_OFFSET 0 +#define RTL8367C_D_ROUTER_PORT_TMR_1_MASK 0x7 + +#define RTL8367C_REG_IGMP_STATIC_ROUTER_PORT 0x1c04 +#define RTL8367C_IGMP_STATIC_ROUTER_PORT_OFFSET 0 +#define RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK 0x7FF + +#define RTL8367C_REG_IGMP_PORT0_CONTROL 0x1c05 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT1_CONTROL 0x1c06 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT2_CONTROL 0x1c07 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT3_CONTROL 0x1c08 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT4_CONTROL 0x1c09 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT5_CONTROL 0x1c0a +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT6_CONTROL 0x1c0b +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT7_CONTROL 0x1c0c +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT01_MAX_GROUP 0x1c0d +#define RTL8367C_PORT1_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT1_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT0_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT0_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT23_MAX_GROUP 0x1c0e +#define RTL8367C_PORT3_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT3_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT2_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT2_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT45_MAX_GROUP 0x1c0f +#define RTL8367C_PORT5_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT5_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT4_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT4_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT67_MAX_GROUP 0x1c10 +#define RTL8367C_PORT7_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT7_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT6_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT6_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP 0x1c11 +#define RTL8367C_PORT1_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT1_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT0_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT0_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT23_CURRENT_GROUP 0x1c12 +#define RTL8367C_PORT3_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT3_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT2_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT2_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT45_CURRENT_GROUP 0x1c13 +#define RTL8367C_PORT5_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT5_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT4_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT4_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT67_CURRENT_GROUP 0x1c14 +#define RTL8367C_PORT7_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT7_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT6_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT6_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_MLD_CFG3 0x1c15 +#define RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET 5 +#define RTL8367C_IGMP_MLD_IP6_BYPASS_MASK 0x20 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET 4 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_MASK 0x10 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET 3 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_MASK 0x8 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET 2 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_MASK 0x4 +#define RTL8367C_REPORT_LEAVE_FORWARD_OFFSET 0 +#define RTL8367C_REPORT_LEAVE_FORWARD_MASK 0x3 + +#define RTL8367C_REG_IGMP_MLD_CFG4 0x1c16 +#define RTL8367C_IGMP_MLD_CFG4_OFFSET 0 +#define RTL8367C_IGMP_MLD_CFG4_MASK 0x7FF + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 0x1c20 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST1 0x1c21 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST2 0x1c22 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST3 0x1c23 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST4 0x1c24 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST5 0x1c25 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST6 0x1c26 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST7 0x1c27 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST8 0x1c28 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST9 0x1c29 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST10 0x1c2a + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST11 0x1c2b + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST12 0x1c2c + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST13 0x1c2d + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST14 0x1c2e + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST15 0x1c2f + +#define RTL8367C_REG_EAV_CTRL0 0x1c30 +#define RTL8367C_EAV_CTRL0_OFFSET 0 +#define RTL8367C_EAV_CTRL0_MASK 0xFF + +#define RTL8367C_REG_EAV_CTRL1 0x1c31 +#define RTL8367C_REMAP_EAV_PRI3_REGEN_OFFSET 9 +#define RTL8367C_REMAP_EAV_PRI3_REGEN_MASK 0xE00 +#define RTL8367C_REMAP_EAV_PRI2_REGEN_OFFSET 6 +#define RTL8367C_REMAP_EAV_PRI2_REGEN_MASK 0x1C0 +#define RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET 3 +#define RTL8367C_REMAP_EAV_PRI1_REGEN_MASK 0x38 +#define RTL8367C_REMAP_EAV_PRI0_REGEN_OFFSET 0 +#define RTL8367C_REMAP_EAV_PRI0_REGEN_MASK 0x7 + +#define RTL8367C_REG_EAV_CTRL2 0x1c32 +#define RTL8367C_REMAP_EAV_PRI7_REGEN_OFFSET 9 +#define RTL8367C_REMAP_EAV_PRI7_REGEN_MASK 0xE00 +#define RTL8367C_REMAP_EAV_PRI6_REGEN_OFFSET 6 +#define RTL8367C_REMAP_EAV_PRI6_REGEN_MASK 0x1C0 +#define RTL8367C_REMAP_EAV_PRI5_REGEN_OFFSET 3 +#define RTL8367C_REMAP_EAV_PRI5_REGEN_MASK 0x38 +#define RTL8367C_REMAP_EAV_PRI4_REGEN_OFFSET 0 +#define RTL8367C_REMAP_EAV_PRI4_REGEN_MASK 0x7 + +#define RTL8367C_REG_SYS_TIME_FREQ 0x1c43 + +#define RTL8367C_REG_SYS_TIME_OFFSET_L 0x1c44 + +#define RTL8367C_REG_SYS_TIME_OFFSET_H 0x1c45 + +#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_L 0x1c46 + +#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_H 0x1c47 +#define RTL8367C_SYS_TIME_OFFSET_TUNE_OFFSET 5 +#define RTL8367C_SYS_TIME_OFFSET_TUNE_MASK 0x20 +#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_OFFSET 0 +#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_MASK 0x1F + +#define RTL8367C_REG_SYS_TIME_SEC_TRANSIT 0x1c48 +#define RTL8367C_SYS_TIME_SEC_TRANSIT_OFFSET 0 +#define RTL8367C_SYS_TIME_SEC_TRANSIT_MASK 0x1 + +#define RTL8367C_REG_SYS_TIME_SEC_HIGH_L 0x1c49 + +#define RTL8367C_REG_SYS_TIME_SEC_HIGH_H 0x1c4a + +#define RTL8367C_REG_SYS_TIME_512NS_L 0x1c4b + +#define RTL8367C_REG_SYS_TIME_512NS_H 0x1c4c +#define RTL8367C_SYS_TIME_512NS_H_OFFSET 0 +#define RTL8367C_SYS_TIME_512NS_H_MASK 0x1F + +#define RTL8367C_REG_FALLBACK_CTRL 0x1c70 +#define RTL8367C_FALLBACK_PL_DEC_EN_OFFSET 15 +#define RTL8367C_FALLBACK_PL_DEC_EN_MASK 0x8000 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_OFFSET 14 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_MASK 0x4000 +#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_OFFSET 11 +#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_MASK 0x3800 +#define RTL8367C_FALLBACK_MONITORMAX_OFFSET 8 +#define RTL8367C_FALLBACK_MONITORMAX_MASK 0x700 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_OFFSET 0 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT0_CFG0 0x1c71 +#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT0_CFG1 0x1c72 + +#define RTL8367C_REG_FALLBACK_PORT0_CFG2 0x1c73 +#define RTL8367C_FALLBACK_PORT0_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT0_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT0_CFG3 0x1c74 +#define RTL8367C_FALLBACK_PORT0_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT0_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT1_CFG0 0x1c75 +#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT1_CFG1 0x1c76 + +#define RTL8367C_REG_FALLBACK_PORT1_CFG2 0x1c77 +#define RTL8367C_FALLBACK_PORT1_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT1_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT1_CFG3 0x1c78 +#define RTL8367C_FALLBACK_PORT1_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT1_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT2_CFG0 0x1c79 +#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT2_CFG1 0x1c7a + +#define RTL8367C_REG_FALLBACK_PORT2_CFG2 0x1c7b +#define RTL8367C_FALLBACK_PORT2_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT2_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT2_CFG3 0x1c7c +#define RTL8367C_FALLBACK_PORT2_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT2_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT3_CFG0 0x1c7d +#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT3_CFG1 0x1c7e + +#define RTL8367C_REG_FALLBACK_PORT3_CFG2 0x1c7f +#define RTL8367C_FALLBACK_PORT3_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT3_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT3_CFG3 0x1c80 +#define RTL8367C_FALLBACK_PORT3_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT3_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT4_CFG0 0x1c81 +#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT4_CFG1 0x1c82 + +#define RTL8367C_REG_FALLBACK_PORT4_CFG2 0x1c83 +#define RTL8367C_FALLBACK_PORT4_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT4_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT4_CFG3 0x1c84 +#define RTL8367C_FALLBACK_PORT4_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT4_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_CTRL1 0x1c85 +#define RTL8367C_FALLBACK_VALIDFLOW_OFFSET 8 +#define RTL8367C_FALLBACK_VALIDFLOW_MASK 0xFF00 +#define RTL8367C_FALLBACK_STOP_TMR_OFFSET 0 +#define RTL8367C_FALLBACK_STOP_TMR_MASK 0x1 + +#define RTL8367C_REG_FALLBACK_CPL 0x1c86 +#define RTL8367C_PORT4_CPL_OFFSET 4 +#define RTL8367C_PORT4_CPL_MASK 0x10 +#define RTL8367C_PORT3_CPL_OFFSET 3 +#define RTL8367C_PORT3_CPL_MASK 0x8 +#define RTL8367C_PORT2_CPL_OFFSET 2 +#define RTL8367C_PORT2_CPL_MASK 0x4 +#define RTL8367C_PORT1_CPL_OFFSET 1 +#define RTL8367C_PORT1_CPL_MASK 0x2 +#define RTL8367C_PORT0_CPL_OFFSET 0 +#define RTL8367C_PORT0_CPL_MASK 0x1 + +#define RTL8367C_REG_FALLBACK_PHY_PAGE 0x1c87 +#define RTL8367C_FALLBACK_PHY_PAGE_OFFSET 0 +#define RTL8367C_FALLBACK_PHY_PAGE_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PHY_REG 0x1c88 +#define RTL8367C_FALLBACK_PHY_REG_OFFSET 0 +#define RTL8367C_FALLBACK_PHY_REG_MASK 0x1F + +#define RTL8367C_REG_AFBK_INFO_X0 0x1c89 + +#define RTL8367C_REG_AFBK_INFO_X1 0x1c8a + +#define RTL8367C_REG_AFBK_INFO_X2 0x1c8b + +#define RTL8367C_REG_AFBK_INFO_X3 0x1c8c + +#define RTL8367C_REG_AFBK_INFO_X4 0x1c8d + +#define RTL8367C_REG_AFBK_INFO_X5 0x1c8e + +#define RTL8367C_REG_AFBK_INFO_X6 0x1c8f + +#define RTL8367C_REG_AFBK_INFO_X7 0x1c90 + +#define RTL8367C_REG_AFBK_INFO_X8 0x1c91 + +#define RTL8367C_REG_AFBK_INFO_X9 0x1c92 + +#define RTL8367C_REG_AFBK_INFO_X10 0x1c93 + +#define RTL8367C_REG_AFBK_INFO_X11 0x1c94 + +#define RTL8367C_REG_FALLBACK_PORT5_CFG0 0x1ca0 +#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT5_CFG1 0x1ca1 + +#define RTL8367C_REG_FALLBACK_PORT5_CFG2 0x1ca2 +#define RTL8367C_FALLBACK_PORT5_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT5_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT5_CFG3 0x1ca3 +#define RTL8367C_FALLBACK_PORT5_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT5_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT6_CFG0 0x1ca4 +#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT6_CFG1 0x1ca5 + +#define RTL8367C_REG_FALLBACK_PORT6_CFG2 0x1ca6 +#define RTL8367C_FALLBACK_PORT6_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT6_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT6_CFG3 0x1ca7 +#define RTL8367C_FALLBACK_PORT6_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT6_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT7_CFG0 0x1ca8 +#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT7_CFG1 0x1ca9 + +#define RTL8367C_REG_FALLBACK_PORT7_CFG2 0x1caa +#define RTL8367C_FALLBACK_PORT7_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT7_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT7_CFG3 0x1cab +#define RTL8367C_FALLBACK_PORT7_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT7_CFG3_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT8_CONTROL 0x1cb0 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT9_CONTROL 0x1cb1 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT10_CONTROL 0x1cb2 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT89_MAX_GROUP 0x1cb3 +#define RTL8367C_PORT9_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT9_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT8_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT8_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT10_MAX_GROUP 0x1cb4 +#define RTL8367C_IGMP_PORT10_MAX_GROUP_OFFSET 0 +#define RTL8367C_IGMP_PORT10_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP 0x1cb5 +#define RTL8367C_PORT9_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT9_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT8_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT8_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT10_CURRENT_GROUP 0x1cb6 +#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_L3_CHECKSUM_CHECK 0x1cb7 +#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_OFFSET 0 +#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_MASK 0x1 + +/* (16'h1d00)chip_70b_reg */ + +#define RTL8367C_REG_PCSXF_CFG 0x1d00 +#define RTL8367C_PCSXF_CFG_Reserved_OFFSET 15 +#define RTL8367C_PCSXF_CFG_Reserved_MASK 0x8000 +#define RTL8367C_CFG_RST_RXFIFO_P7_5_OFFSET 12 +#define RTL8367C_CFG_RST_RXFIFO_P7_5_MASK 0x7000 +#define RTL8367C_CFG_PCSXF_OFFSET 8 +#define RTL8367C_CFG_PCSXF_MASK 0xF00 +#define RTL8367C_CFG_RST_RXFIFO_OFFSET 3 +#define RTL8367C_CFG_RST_RXFIFO_MASK 0xF8 +#define RTL8367C_CFG_COL2RXDV_OFFSET 2 +#define RTL8367C_CFG_COL2RXDV_MASK 0x4 +#define RTL8367C_CFG_PHY_SDET_OFFSET 0 +#define RTL8367C_CFG_PHY_SDET_MASK 0x3 + +#define RTL8367C_REG_PHYID_CFG0 0x1d01 +#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_OFFSET 11 +#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_MASK 0x3800 +#define RTL8367C_CFG_PHYAD_14C_OFFSET 10 +#define RTL8367C_CFG_PHYAD_14C_MASK 0x400 +#define RTL8367C_CFG_PHY_BRD_MODE_OFFSET 5 +#define RTL8367C_CFG_PHY_BRD_MODE_MASK 0x3E0 +#define RTL8367C_CFG_BRD_PHYAD_OFFSET 0 +#define RTL8367C_CFG_BRD_PHYAD_MASK 0x1F + +#define RTL8367C_REG_PHYID_CFG1 0x1d02 +#define RTL8367C_CFG_MSK_MDI_OFFSET 5 +#define RTL8367C_CFG_MSK_MDI_MASK 0x1FE0 +#define RTL8367C_CFG_BASE_PHYAD_OFFSET 0 +#define RTL8367C_CFG_BASE_PHYAD_MASK 0x1F + +#define RTL8367C_REG_PHY_POLL_CFG0 0x1d03 +#define RTL8367C_CFG_HOTCMD_PRD_EN_OFFSET 15 +#define RTL8367C_CFG_HOTCMD_PRD_EN_MASK 0x8000 +#define RTL8367C_CFG_HOTCMD_EN_OFFSET 12 +#define RTL8367C_CFG_HOTCMD_EN_MASK 0x7000 +#define RTL8367C_CFG_POLL_PERIOD_OFFSET 8 +#define RTL8367C_CFG_POLL_PERIOD_MASK 0xF00 +#define RTL8367C_CFG_PERI_CMDS_RD_OFFSET 4 +#define RTL8367C_CFG_PERI_CMDS_RD_MASK 0xF0 +#define RTL8367C_CFG_PERI_CMDS_WR_OFFSET 0 +#define RTL8367C_CFG_PERI_CMDS_WR_MASK 0xF + +#define RTL8367C_REG_PHY_POLL_CFG1 0x1d04 + +#define RTL8367C_REG_PHY_POLL_CFG2 0x1d05 + +#define RTL8367C_REG_PHY_POLL_CFG3 0x1d06 + +#define RTL8367C_REG_PHY_POLL_CFG4 0x1d07 + +#define RTL8367C_REG_PHY_POLL_CFG5 0x1d08 + +#define RTL8367C_REG_PHY_POLL_CFG6 0x1d09 + +#define RTL8367C_REG_PHY_POLL_CFG7 0x1d0a + +#define RTL8367C_REG_PHY_POLL_CFG8 0x1d0b + +#define RTL8367C_REG_PHY_POLL_CFG9 0x1d0c + +#define RTL8367C_REG_PHY_POLL_CFG10 0x1d0d + +#define RTL8367C_REG_PHY_POLL_CFG11 0x1d0e + +#define RTL8367C_REG_PHY_POLL_CFG12 0x1d0f + +#define RTL8367C_REG_EFUSE_MISC 0x1d10 +#define RTL8367C_CFG_SA_SEL_OFFSET 5 +#define RTL8367C_CFG_SA_SEL_MASK 0x20 +#define RTL8367C_CFG_PHYAD00_OFFSET 0 +#define RTL8367C_CFG_PHYAD00_MASK 0x1F + +#define RTL8367C_REG_SDS_MISC 0x1d11 +#define RTL8367C_CFG_SGMII_RXFC_OFFSET 14 +#define RTL8367C_CFG_SGMII_RXFC_MASK 0x4000 +#define RTL8367C_CFG_SGMII_TXFC_OFFSET 13 +#define RTL8367C_CFG_SGMII_TXFC_MASK 0x2000 +#define RTL8367C_INB_ARB_OFFSET 12 +#define RTL8367C_INB_ARB_MASK 0x1000 +#define RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET 11 +#define RTL8367C_CFG_MAC8_SEL_HSGMII_MASK 0x800 +#define RTL8367C_CFG_SGMII_FDUP_OFFSET 10 +#define RTL8367C_CFG_SGMII_FDUP_MASK 0x400 +#define RTL8367C_CFG_SGMII_LINK_OFFSET 9 +#define RTL8367C_CFG_SGMII_LINK_MASK 0x200 +#define RTL8367C_CFG_SGMII_SPD_OFFSET 7 +#define RTL8367C_CFG_SGMII_SPD_MASK 0x180 +#define RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET 6 +#define RTL8367C_CFG_MAC8_SEL_SGMII_MASK 0x40 +#define RTL8367C_CFG_INB_SEL_OFFSET 3 +#define RTL8367C_CFG_INB_SEL_MASK 0x38 +#define RTL8367C_CFG_SDS_MODE_18C_OFFSET 0 +#define RTL8367C_CFG_SDS_MODE_18C_MASK 0x7 + +#define RTL8367C_REG_FIFO_CTRL 0x1d12 +#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_OFFSET 11 +#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_MASK 0x800 +#define RTL8367C_CFG_LPBK_OFFSET 10 +#define RTL8367C_CFG_LPBK_MASK 0x400 +#define RTL8367C_CFG_NOT_FF_OUT_OFFSET 9 +#define RTL8367C_CFG_NOT_FF_OUT_MASK 0x200 +#define RTL8367C_CFG_WATER_LEVEL_FD_OFFSET 6 +#define RTL8367C_CFG_WATER_LEVEL_FD_MASK 0x1C0 +#define RTL8367C_CFG_WATER_LEVEL_Y2X_OFFSET 3 +#define RTL8367C_CFG_WATER_LEVEL_Y2X_MASK 0x38 +#define RTL8367C_CFG_WATER_LEVEL_X2Y_OFFSET 0 +#define RTL8367C_CFG_WATER_LEVEL_X2Y_MASK 0x7 + +#define RTL8367C_REG_BCAM_SETTING 0x1d13 +#define RTL8367C_CFG_BCAM_MDS_OFFSET 3 +#define RTL8367C_CFG_BCAM_MDS_MASK 0x18 +#define RTL8367C_CFG_BCAM_RDS_OFFSET 0 +#define RTL8367C_CFG_BCAM_RDS_MASK 0x7 + +#define RTL8367C_REG_GPHY_ACS_MISC 0x1d14 +#define RTL8367C_CFG_SEL_GPHY_SMI_OFFSET 3 +#define RTL8367C_CFG_SEL_GPHY_SMI_MASK 0x8 +#define RTL8367C_CFG_BRD_PHYIDX_OFFSET 0 +#define RTL8367C_CFG_BRD_PHYIDX_MASK 0x7 + +#define RTL8367C_REG_GPHY_OCP_MSB_0 0x1d15 +#define RTL8367C_CFG_CPU_OCPADR_MSB_OFFSET 6 +#define RTL8367C_CFG_CPU_OCPADR_MSB_MASK 0xFC0 +#define RTL8367C_CFG_DW8051_OCPADR_MSB_OFFSET 0 +#define RTL8367C_CFG_DW8051_OCPADR_MSB_MASK 0x3F + +#define RTL8367C_REG_GPHY_OCP_MSB_1 0x1d16 +#define RTL8367C_CFG_PATCH_OCPADR_MSB_OFFSET 6 +#define RTL8367C_CFG_PATCH_OCPADR_MSB_MASK 0xFC0 +#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_OFFSET 0 +#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_MASK 0x3F + +#define RTL8367C_REG_GPHY_OCP_MSB_2 0x1d17 +#define RTL8367C_CFG_RRCP_OCPADR_MSB_OFFSET 6 +#define RTL8367C_CFG_RRCP_OCPADR_MSB_MASK 0xFC0 +#define RTL8367C_CFG_RTCT_OCPADR_MSB_OFFSET 0 +#define RTL8367C_CFG_RTCT_OCPADR_MSB_MASK 0x3F + +#define RTL8367C_REG_GPHY_OCP_MSB_3 0x1d18 +#define RTL8367C_GPHY_OCP_MSB_3_OFFSET 0 +#define RTL8367C_GPHY_OCP_MSB_3_MASK 0x3F + +#define RTL8367C_REG_GPIO_67C_I_X0 0x1d19 + +#define RTL8367C_REG_GPIO_67C_I_X1 0x1d1a + +#define RTL8367C_REG_GPIO_67C_I_X2 0x1d1b + +#define RTL8367C_REG_GPIO_67C_I_X3 0x1d1c +#define RTL8367C_GPIO_67C_I_X3_OFFSET 0 +#define RTL8367C_GPIO_67C_I_X3_MASK 0x3FFF + +#define RTL8367C_REG_GPIO_67C_O_X0 0x1d1d + +#define RTL8367C_REG_GPIO_67C_O_X1 0x1d1e + +#define RTL8367C_REG_GPIO_67C_O_X2 0x1d1f + +#define RTL8367C_REG_GPIO_67C_O_X3 0x1d20 +#define RTL8367C_GPIO_67C_O_X3_OFFSET 0 +#define RTL8367C_GPIO_67C_O_X3_MASK 0x3FFF + +#define RTL8367C_REG_GPIO_67C_OE_X0 0x1d21 + +#define RTL8367C_REG_GPIO_67C_OE_X1 0x1d22 + +#define RTL8367C_REG_GPIO_67C_OE_X2 0x1d23 + +#define RTL8367C_REG_GPIO_67C_OE_X3 0x1d24 +#define RTL8367C_GPIO_67C_OE_X3_OFFSET 0 +#define RTL8367C_GPIO_67C_OE_X3_MASK 0x3FFF + +#define RTL8367C_REG_GPIO_MODE_67C_X0 0x1d25 + +#define RTL8367C_REG_GPIO_MODE_67C_X1 0x1d26 + +#define RTL8367C_REG_GPIO_MODE_67C_X2 0x1d27 + +#define RTL8367C_REG_GPIO_MODE_67C_X3 0x1d28 +#define RTL8367C_GPIO_MODE_67C_X3_OFFSET 0 +#define RTL8367C_GPIO_MODE_67C_X3_MASK 0x3FFF + +#define RTL8367C_REG_WGPHY_MISC_0 0x1d29 +#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_OFFSET 13 +#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_MASK 0xE000 +#define RTL8367C_CFG_INIPHY_PWRUP_OFFSET 5 +#define RTL8367C_CFG_INIPHY_PWRUP_MASK 0x1FE0 +#define RTL8367C_CFG_INIPHY_DISGIGA_OFFSET 0 +#define RTL8367C_CFG_INIPHY_DISGIGA_MASK 0x1F + +#define RTL8367C_REG_WGPHY_MISC_1 0x1d2a +#define RTL8367C_WGPHY_MISC_1_OFFSET 0 +#define RTL8367C_WGPHY_MISC_1_MASK 0xFF + +#define RTL8367C_REG_WGPHY_MISC_2 0x1d2b +#define RTL8367C_WGPHY_MISC_2_OFFSET 0 +#define RTL8367C_WGPHY_MISC_2_MASK 0x3FF + +#define RTL8367C_REG_CFG_AFBK_GPHY_0 0x1d2c +#define RTL8367C_CFG_AFBK_GPHY_0_OFFSET 0 +#define RTL8367C_CFG_AFBK_GPHY_0_MASK 0x1F + +#define RTL8367C_REG_CFG_AFBK_GPHY_1 0x1d2d +#define RTL8367C_CFG_AFBK_GPHY_1_OFFSET 0 +#define RTL8367C_CFG_AFBK_GPHY_1_MASK 0xFFF + +#define RTL8367C_REG_EF_SLV_CTRL_0 0x1d2e +#define RTL8367C_EF_SLV_BUSY_OFFSET 11 +#define RTL8367C_EF_SLV_BUSY_MASK 0x800 +#define RTL8367C_EF_SLV_ACK_OFFSET 10 +#define RTL8367C_EF_SLV_ACK_MASK 0x400 +#define RTL8367C_EF_SLV_A_OFFSET 2 +#define RTL8367C_EF_SLV_A_MASK 0x3FC +#define RTL8367C_EF_SLV_WE_OFFSET 1 +#define RTL8367C_EF_SLV_WE_MASK 0x2 +#define RTL8367C_EF_SLV_CE_OFFSET 0 +#define RTL8367C_EF_SLV_CE_MASK 0x1 + +#define RTL8367C_REG_EF_SLV_CTRL_1 0x1d2f + +#define RTL8367C_REG_EF_SLV_CTRL_2 0x1d30 + +#define RTL8367C_REG_EFUSE_MISC_1 0x1d31 +#define RTL8367C_EF_EN_EFUSE_OFFSET 10 +#define RTL8367C_EF_EN_EFUSE_MASK 0x400 +#define RTL8367C_EF_MODEL_ID_OFFSET 6 +#define RTL8367C_EF_MODEL_ID_MASK 0x3C0 +#define RTL8367C_EF_RSVD_OFFSET 2 +#define RTL8367C_EF_RSVD_MASK 0x3C +#define RTL8367C_EF_SYS_CLK_OFFSET 0 +#define RTL8367C_EF_SYS_CLK_MASK 0x3 + +#define RTL8367C_REG_IO_MISC_FUNC 0x1d32 +#define RTL8367C_TST_MODE_OFFSET 3 +#define RTL8367C_TST_MODE_MASK 0x8 +#define RTL8367C_UART_EN_OFFSET 2 +#define RTL8367C_UART_EN_MASK 0x4 +#define RTL8367C_INT_EN_OFFSET 1 +#define RTL8367C_INT_EN_MASK 0x2 +#define RTL8367C_BUZ_EN_OFFSET 0 +#define RTL8367C_BUZ_EN_MASK 0x1 + +#define RTL8367C_REG_HTRAM_DVS 0x1d33 +#define RTL8367C_HTRAM_DVS_OFFSET 0 +#define RTL8367C_HTRAM_DVS_MASK 0x1 + +#define RTL8367C_REG_EF_SLV_CTRL_3 0x1d34 +#define RTL8367C_EF_SLV_CTRL_3_OFFSET 0 +#define RTL8367C_EF_SLV_CTRL_3_MASK 0x1 + +#define RTL8367C_REG_INBAND_EN14C 0x1d35 +#define RTL8367C_INBAND_EN14C_OFFSET 0 +#define RTL8367C_INBAND_EN14C_MASK 0x1 + +#define RTL8367C_REG_CFG_SWR_L 0x1d36 +#define RTL8367C_ANARG_RDY_SWR_L_OFFSET 14 +#define RTL8367C_ANARG_RDY_SWR_L_MASK 0x4000 +#define RTL8367C_ANARG_VALID_SWR_L_OFFSET 13 +#define RTL8367C_ANARG_VALID_SWR_L_MASK 0x2000 +#define RTL8367C_SAW_SWR_L_OFFSET 9 +#define RTL8367C_SAW_SWR_L_MASK 0x1E00 +#define RTL8367C_SAW_VALID_SWR_L_OFFSET 8 +#define RTL8367C_SAW_VALID_SWR_L_MASK 0x100 +#define RTL8367C_UPS_DBGO_L_OFFSET 0 +#define RTL8367C_UPS_DBGO_L_MASK 0xFF + +#define RTL8367C_REG_BTCAM_CTRL 0x1d37 +#define RTL8367C_TCAM_RDS_OFFSET 2 +#define RTL8367C_TCAM_RDS_MASK 0x1C +#define RTL8367C_TCAM_MDS_OFFSET 0 +#define RTL8367C_TCAM_MDS_MASK 0x3 + +#define RTL8367C_REG_PBRAM_BISR_CTRL 0x1d38 +#define RTL8367C_HAS_HLDRMP_MD_OFFSET 9 +#define RTL8367C_HAS_HLDRMP_MD_MASK 0x200 +#define RTL8367C_PB_HLDRMP_MD_OFFSET 8 +#define RTL8367C_PB_HLDRMP_MD_MASK 0x100 +#define RTL8367C_HAS_BISR_BIRSTN_OFFSET 7 +#define RTL8367C_HAS_BISR_BIRSTN_MASK 0x80 +#define RTL8367C_SEC_RUN_HSA_OFFSET 6 +#define RTL8367C_SEC_RUN_HSA_MASK 0x40 +#define RTL8367C_HAS_HLDRMP_VAL_OFFSET 5 +#define RTL8367C_HAS_HLDRMP_VAL_MASK 0x20 +#define RTL8367C_HAS_BISR_PWRSTN_OFFSET 4 +#define RTL8367C_HAS_BISR_PWRSTN_MASK 0x10 +#define RTL8367C_SEC_RUN_PB_OFFSET 3 +#define RTL8367C_SEC_RUN_PB_MASK 0x8 +#define RTL8367C_PB_HLDRMP_VAL_OFFSET 2 +#define RTL8367C_PB_HLDRMP_VAL_MASK 0x4 +#define RTL8367C_PB_BISR_BIRSTN_OFFSET 1 +#define RTL8367C_PB_BISR_BIRSTN_MASK 0x2 +#define RTL8367C_PB_BISR_PWRSTN_OFFSET 0 +#define RTL8367C_PB_BISR_PWRSTN_MASK 0x1 + +#define RTL8367C_REG_CVLANRAM_BISR_CTRL 0x1d39 +#define RTL8367C_SEC_RUN_CVLAN_OFFSET 4 +#define RTL8367C_SEC_RUN_CVLAN_MASK 0x10 +#define RTL8367C_CVALN_HLDRMP_MD_OFFSET 3 +#define RTL8367C_CVALN_HLDRMP_MD_MASK 0x8 +#define RTL8367C_CVALN_HLDRMP_VAL_OFFSET 2 +#define RTL8367C_CVALN_HLDRMP_VAL_MASK 0x4 +#define RTL8367C_CVLAN_BISR_BIRSTN_OFFSET 1 +#define RTL8367C_CVLAN_BISR_BIRSTN_MASK 0x2 +#define RTL8367C_CVLAN_BISR_PWRSTN_OFFSET 0 +#define RTL8367C_CVLAN_BISR_PWRSTN_MASK 0x1 + +#define RTL8367C_REG_CFG_1588_TIMER_EN_GPI 0x1d3a +#define RTL8367C_CFG_1588_TIMER_EN_GPI_OFFSET 0 +#define RTL8367C_CFG_1588_TIMER_EN_GPI_MASK 0x1 + +#define RTL8367C_REG_MDIO_PRMB_SUPP 0x1d3b +#define RTL8367C_FIB_HIPRI_OFFSET 14 +#define RTL8367C_FIB_HIPRI_MASK 0x4000 +#define RTL8367C_SMT_EN_OFFSET 13 +#define RTL8367C_SMT_EN_MASK 0x2000 +#define RTL8367C_P4_FB_CPL_OFFSET 12 +#define RTL8367C_P4_FB_CPL_MASK 0x1000 +#define RTL8367C_P3_FB_CPL_OFFSET 11 +#define RTL8367C_P3_FB_CPL_MASK 0x800 +#define RTL8367C_P2_FB_CPL_OFFSET 10 +#define RTL8367C_P2_FB_CPL_MASK 0x400 +#define RTL8367C_P1_FB_CPL_OFFSET 9 +#define RTL8367C_P1_FB_CPL_MASK 0x200 +#define RTL8367C_P0_FB_CPL_OFFSET 8 +#define RTL8367C_P0_FB_CPL_MASK 0x100 +#define RTL8367C_DBG_PKG_8367N_OFFSET 7 +#define RTL8367C_DBG_PKG_8367N_MASK 0x80 +#define RTL8367C_DBG_PKG_8367VB_OFFSET 6 +#define RTL8367C_DBG_PKG_8367VB_MASK 0x40 +#define RTL8367C_CFG_DEBUG_EN_OFFSET 5 +#define RTL8367C_CFG_DEBUG_EN_MASK 0x20 +#define RTL8367C_CFG_TMR_ACK_OFFSET 1 +#define RTL8367C_CFG_TMR_ACK_MASK 0x1E +#define RTL8367C_CFG_PRMB_SUPP_OFFSET 0 +#define RTL8367C_CFG_PRMB_SUPP_MASK 0x1 + +#define RTL8367C_REG_BOND4READ 0x1d3c +#define RTL8367C_BOND_BOID0_OFFSET 8 +#define RTL8367C_BOND_BOID0_MASK 0x100 +#define RTL8367C_BOND_SYSCLK_OFFSET 7 +#define RTL8367C_BOND_SYSCLK_MASK 0x80 +#define RTL8367C_BOND_PHYMODE_OFFSET 6 +#define RTL8367C_BOND_PHYMODE_MASK 0x40 +#define RTL8367C_BOND_DIS_PON_BIST_OFFSET 5 +#define RTL8367C_BOND_DIS_PON_BIST_MASK 0x20 +#define RTL8367C_BOND_DIS_TABLE_INIT_OFFSET 4 +#define RTL8367C_BOND_DIS_TABLE_INIT_MASK 0x10 +#define RTL8367C_BOND_BYP_AFE_PLL_OFFSET 3 +#define RTL8367C_BOND_BYP_AFE_PLL_MASK 0x8 +#define RTL8367C_BOND_BYP_AFE_POR_OFFSET 2 +#define RTL8367C_BOND_BYP_AFE_POR_MASK 0x4 +#define RTL8367C_BOND_BISR_COND_OFFSET 1 +#define RTL8367C_BOND_BISR_COND_MASK 0x2 +#define RTL8367C_BOND_EF_EN_OFFSET 0 +#define RTL8367C_BOND_EF_EN_MASK 0x1 + +#define RTL8367C_REG_REG_TO_ECO0 0x1d3d + +#define RTL8367C_REG_REG_TO_ECO1 0x1d3e + +#define RTL8367C_REG_REG_TO_ECO2 0x1d3f + +#define RTL8367C_REG_REG_TO_ECO3 0x1d40 + +#define RTL8367C_REG_REG_TO_ECO4 0x1d41 + +#define RTL8367C_REG_PHYSTS_CTRL0 0x1d42 +#define RTL8367C_MACRX_DUPDET_EN_OFFSET 5 +#define RTL8367C_MACRX_DUPDET_EN_MASK 0x20 +#define RTL8367C_LNKUP_DLY_EN_OFFSET 4 +#define RTL8367C_LNKUP_DLY_EN_MASK 0x10 +#define RTL8367C_GE_100M_LNKUP_DLY_OFFSET 2 +#define RTL8367C_GE_100M_LNKUP_DLY_MASK 0xC +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_OFFSET 0 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_MASK 0x3 + +#define RTL8367C_REG_SSC_CTRL0_0 0x1d44 +#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL0_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL0_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL0_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL0_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL0_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL0_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED 0x1d45 + +#define RTL8367C_REG_SSC_PN_POLY_SEL 0x1d46 + +#define RTL8367C_REG_SSC_CTRL0_3 0x1d47 +#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL0_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL0_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL0_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL0_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL0_4 0x1d48 +#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL0_5 0x1d49 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL0_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL0_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS0 0x1d4a +#define RTL8367C_SSC_STS0_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS0_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS0_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS0_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS0_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS0_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS0_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS0_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL1_0 0x1d4b +#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL1_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL1_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL1_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL1_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL1_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL1_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED1 0x1d4c + +#define RTL8367C_REG_SSC_PN_POLY_SEL1 0x1d4d + +#define RTL8367C_REG_SSC_CTRL1_3 0x1d4e +#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL1_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL1_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL1_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL1_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL1_4 0x1d4f +#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL1_5 0x1d50 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL1_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL1_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS1 0x1d51 +#define RTL8367C_SSC_STS1_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS1_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS1_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS1_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS1_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS1_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS1_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS1_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL2_0 0x1d52 +#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL2_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL2_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL2_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL2_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL2_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL2_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED2 0x1d53 + +#define RTL8367C_REG_SSC_PN_POLY_SEL2 0x1d54 + +#define RTL8367C_REG_SSC_CTRL2_3 0x1d55 +#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL2_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL2_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL2_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL2_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL2_4 0x1d56 +#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL2_5 0x1d57 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL2_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL2_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS2 0x1d58 +#define RTL8367C_SSC_STS2_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS2_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS2_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS2_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS2_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS2_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS2_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS2_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL3_0 0x1d59 +#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL3_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL3_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL3_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL3_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL3_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL3_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED3 0x1d5a + +#define RTL8367C_REG_SSC_PN_POLY_SEL3 0x1d5b + +#define RTL8367C_REG_SSC_CTRL3_3 0x1d5c +#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL3_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL3_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL3_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL3_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL3_4 0x1d5d +#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL3_5 0x1d5e +#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL3_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL3_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL3_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL3_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS3 0x1d5f +#define RTL8367C_SSC_STS3_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS3_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS3_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS3_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS3_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS3_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS3_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS3_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_PHY_POLL_CFG13 0x1d60 + +#define RTL8367C_REG_PHY_POLL_CFG14 0x1d61 + +#define RTL8367C_REG_FRC_SYS_CLK 0x1d62 +#define RTL8367C_SYSCLK_FRC_MD_OFFSET 1 +#define RTL8367C_SYSCLK_FRC_MD_MASK 0x2 +#define RTL8367C_SYSCLK_FRC_VAL_OFFSET 0 +#define RTL8367C_SYSCLK_FRC_VAL_MASK 0x1 + +#define RTL8367C_REG_AFE_SSC_CTRL 0x1d63 +#define RTL8367C_PH_RSTB_TXD1_OFFSET 9 +#define RTL8367C_PH_RSTB_TXD1_MASK 0x200 +#define RTL8367C_PH_RSTB_TXC1_OFFSET 8 +#define RTL8367C_PH_RSTB_TXC1_MASK 0x100 +#define RTL8367C_PH_RSTB_TXD0_OFFSET 7 +#define RTL8367C_PH_RSTB_TXD0_MASK 0x80 +#define RTL8367C_PH_RSTB_TXC0_OFFSET 6 +#define RTL8367C_PH_RSTB_TXC0_MASK 0x40 +#define RTL8367C_PH_RSTBSYS_OFFSET 5 +#define RTL8367C_PH_RSTBSYS_MASK 0x20 +#define RTL8367C_PH_RSTB8051_OFFSET 4 +#define RTL8367C_PH_RSTB8051_MASK 0x10 +#define RTL8367C_OREG_SSC_OFFSET 0 +#define RTL8367C_OREG_SSC_MASK 0xF + +#define RTL8367C_REG_BUFF_RST_CTRL0 0x1d64 +#define RTL8367C_BUFFRST_TXESD_EN_OFFSET 13 +#define RTL8367C_BUFFRST_TXESD_EN_MASK 0x2000 +#define RTL8367C_BUFF_RST_TIME_LONG_OFFSET 8 +#define RTL8367C_BUFF_RST_TIME_LONG_MASK 0x1F00 +#define RTL8367C_BUFF_RST_TIME_SHORT_OFFSET 3 +#define RTL8367C_BUFF_RST_TIME_SHORT_MASK 0xF8 +#define RTL8367C_SW_BUFF_RST_OFFSET 2 +#define RTL8367C_SW_BUFF_RST_MASK 0x4 +#define RTL8367C_IMS_BUFF_RST_OFFSET 1 +#define RTL8367C_IMS_BUFF_RST_MASK 0x2 +#define RTL8367C_IMR_BUFF_RST_OFFSET 0 +#define RTL8367C_IMR_BUFF_RST_MASK 0x1 + +#define RTL8367C_REG_BUFF_RST_CTRL1 0x1d65 +#define RTL8367C_BUFFRST_SYSOVER_EN_OFFSET 10 +#define RTL8367C_BUFFRST_SYSOVER_EN_MASK 0x400 +#define RTL8367C_BUFFRST_SYSOVER_THR_OFFSET 0 +#define RTL8367C_BUFFRST_SYSOVER_THR_MASK 0x3FF + +#define RTL8367C_REG_BUFF_RST_CTRL2 0x1d66 +#define RTL8367C_BUFFRST_QOVER_EN_OFFSET 10 +#define RTL8367C_BUFFRST_QOVER_EN_MASK 0x400 +#define RTL8367C_BUFFRST_QOVER_THR_OFFSET 0 +#define RTL8367C_BUFFRST_QOVER_THR_MASK 0x3FF + +#define RTL8367C_REG_BUFF_RST_CTRL3 0x1d67 +#define RTL8367C_DSC_TIMER_OFFSET 11 +#define RTL8367C_DSC_TIMER_MASK 0x7800 +#define RTL8367C_BUFFRST_DSCOVER_THR_OFFSET 1 +#define RTL8367C_BUFFRST_DSCOVER_THR_MASK 0x7FE +#define RTL8367C_BUFFRST_DSCOVER_EN_OFFSET 0 +#define RTL8367C_BUFFRST_DSCOVER_EN_MASK 0x1 + +#define RTL8367C_REG_BUFF_RST_CTRL4 0x1d68 +#define RTL8367C_INDSC_TIMER_OFFSET 11 +#define RTL8367C_INDSC_TIMER_MASK 0x7800 +#define RTL8367C_BUFFRST_INDSCOVER_THR_OFFSET 1 +#define RTL8367C_BUFFRST_INDSCOVER_THR_MASK 0x7FE +#define RTL8367C_BUFFRST_INDSCOVER_EN_OFFSET 0 +#define RTL8367C_BUFFRST_INDSCOVER_EN_MASK 0x1 + +#define RTL8367C_REG_BUFF_RST_CTRL5 0x1d69 +#define RTL8367C_TX_ESD_MODE_OFFSET 8 +#define RTL8367C_TX_ESD_MODE_MASK 0x100 +#define RTL8367C_TX_ESD_LVL_OFFSET 0 +#define RTL8367C_TX_ESD_LVL_MASK 0xFF + +#define RTL8367C_REG_TOP_CON0 0x1d70 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_OFFSET 15 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_MASK 0x8000 +#define RTL8367C_OCP_TIMEOUT_P7_5_OFFSET 12 +#define RTL8367C_OCP_TIMEOUT_P7_5_MASK 0x7000 +#define RTL8367C_FIB_EEE_AB_OFFSET 11 +#define RTL8367C_FIB_EEE_AB_MASK 0x800 +#define RTL8367C_ADCCKIEN_OFFSET 10 +#define RTL8367C_ADCCKIEN_MASK 0x400 +#define RTL8367C_OCP_TIMEOUT_OFFSET 5 +#define RTL8367C_OCP_TIMEOUT_MASK 0x3E0 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_OFFSET 4 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_MASK 0x10 +#define RTL8367C_RG2_TXC_SEL_OFFSET 3 +#define RTL8367C_RG2_TXC_SEL_MASK 0x8 +#define RTL8367C_RG1TXC_SEL_OFFSET 2 +#define RTL8367C_RG1TXC_SEL_MASK 0x4 +#define RTL8367C_SYNC_1588_EN_OFFSET 1 +#define RTL8367C_SYNC_1588_EN_MASK 0x2 +#define RTL8367C_LS_MODE_OFFSET 0 +#define RTL8367C_LS_MODE_MASK 0x1 + +#define RTL8367C_REG_TOP_CON1 0x1d71 +#define RTL8367C_TA_CHK_EN_OFFSET 2 +#define RTL8367C_TA_CHK_EN_MASK 0x4 +#define RTL8367C_SLV_EG_SEL_OFFSET 1 +#define RTL8367C_SLV_EG_SEL_MASK 0x2 +#define RTL8367C_IIC_OP_DRAIN_OFFSET 0 +#define RTL8367C_IIC_OP_DRAIN_MASK 0x1 + +#define RTL8367C_REG_SWR_FPWM 0x1d72 +#define RTL8367C_SWR_FPWM_OFFSET 0 +#define RTL8367C_SWR_FPWM_MASK 0x1 + +#define RTL8367C_REG_EEEP_CTRL_500M 0x1d73 + +#define RTL8367C_REG_SHORT_PRMB 0x1d74 +#define RTL8367C_SHORT_PRMB_OFFSET 0 +#define RTL8367C_SHORT_PRMB_MASK 0x1 + +#define RTL8367C_REG_INDSC_THR_CTRL 0x1d75 +#define RTL8367C_INDSC_THR_CTRL_OFFSET 0 +#define RTL8367C_INDSC_THR_CTRL_MASK 0x7FF + +#define RTL8367C_REG_SET_PAD_CTRL_NEW 0x1d80 +#define RTL8367C_SET_PAD_CTRL_NEW_OFFSET 0 +#define RTL8367C_SET_PAD_CTRL_NEW_MASK 0x1 + +#define RTL8367C_REG_SET_PAD_DRI_0 0x1d81 + +#define RTL8367C_REG_SET_PAD_DRI_1 0x1d82 + +#define RTL8367C_REG_SET_PAD_DRI_2 0x1d83 + +#define RTL8367C_REG_SET_PAD_SLEW_0 0x1d84 + +#define RTL8367C_REG_SET_PAD_SLEW_1 0x1d85 + +#define RTL8367C_REG_SET_PAD_SLEW_2 0x1d86 + +#define RTL8367C_REG_SET_PAD_SMT_0 0x1d87 + +#define RTL8367C_REG_SET_PAD_SMT_1 0x1d88 + +#define RTL8367C_REG_SET_PAD_SMT_2 0x1d89 + +#define RTL8367C_REG_M_I2C_CTL_STA_REG 0x1d8a +#define RTL8367C_TX_RX_DATA_OFFSET 8 +#define RTL8367C_TX_RX_DATA_MASK 0xFF00 +#define RTL8367C_DUMB_RW_ERR_OFFSET 7 +#define RTL8367C_DUMB_RW_ERR_MASK 0x80 +#define RTL8367C_SLV_ACK_FLAG_OFFSET 6 +#define RTL8367C_SLV_ACK_FLAG_MASK 0x40 +#define RTL8367C_M_I2C_BUS_IDLE_OFFSET 5 +#define RTL8367C_M_I2C_BUS_IDLE_MASK 0x20 +#define RTL8367C_I2C_CMD_TYPE_OFFSET 1 +#define RTL8367C_I2C_CMD_TYPE_MASK 0x1E +#define RTL8367C_I2C_CMD_EXEC_OFFSET 0 +#define RTL8367C_I2C_CMD_EXEC_MASK 0x1 + +#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_0 0x1d8b + +#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_1 0x1d8c + +#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_0 0x1d8d + +#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_1 0x1d8e + +#define RTL8367C_REG_M_I2C_DUMB_RW_CTL 0x1d8f +#define RTL8367C_DUMB_I2C_CTL_CODE_OFFSET 8 +#define RTL8367C_DUMB_I2C_CTL_CODE_MASK 0x7F00 +#define RTL8367C_DUMB_RW_I2C_FORMAT_OFFSET 4 +#define RTL8367C_DUMB_RW_I2C_FORMAT_MASK 0x10 +#define RTL8367C_DUMB_RW_DATA_MODE_OFFSET 2 +#define RTL8367C_DUMB_RW_DATA_MODE_MASK 0xC +#define RTL8367C_DUMB_RW_ADDR_MODE_OFFSET 0 +#define RTL8367C_DUMB_RW_ADDR_MODE_MASK 0x3 + +#define RTL8367C_REG_M_I2C_SYS_CTL 0x1d90 +#define RTL8367C_M_I2C_SCL_IO_MUX_OFFSET 12 +#define RTL8367C_M_I2C_SCL_IO_MUX_MASK 0x3000 +#define RTL8367C_M_I2C_SDA_IO_MUX_OFFSET 10 +#define RTL8367C_M_I2C_SDA_IO_MUX_MASK 0xC00 +#define RTL8367C_M_I2C_SDA_OD_EN_OFFSET 9 +#define RTL8367C_M_I2C_SDA_OD_EN_MASK 0x200 +#define RTL8367C_M_I2C_SCL_OD_EN_OFFSET 8 +#define RTL8367C_M_I2C_SCL_OD_EN_MASK 0x100 +#define RTL8367C_M_I2C_SCL_F_DIV_OFFSET 0 +#define RTL8367C_M_I2C_SCL_F_DIV_MASK 0xFF + +#define RTL8367C_REG_HT_PB_SRAM_CTRL 0x1da0 +#define RTL8367C_HTPB_RW_OFFSET 2 +#define RTL8367C_HTPB_RW_MASK 0x4 +#define RTL8367C_HTPB_SEL_OFFSET 1 +#define RTL8367C_HTPB_SEL_MASK 0x2 +#define RTL8367C_HTPB_CE_OFFSET 0 +#define RTL8367C_HTPB_CE_MASK 0x1 + +#define RTL8367C_REG_HT_PB_SRAM_ADDR 0x1da1 + +#define RTL8367C_REG_HT_PB_SRAM_DIN0 0x1da2 + +#define RTL8367C_REG_HT_PB_SRAM_DIN1 0x1da3 + +#define RTL8367C_REG_HT_PB_SRAM_DOUT0 0x1da4 + +#define RTL8367C_REG_HT_PB_SRAM_DOUT1 0x1da5 + +#define RTL8367C_REG_PHY_STAT_0 0x1db0 + +#define RTL8367C_REG_PHY_STAT_1 0x1db1 + +#define RTL8367C_REG_PHY_STAT_2 0x1db2 + +#define RTL8367C_REG_PHY_STAT_3 0x1db3 + +#define RTL8367C_REG_PHY_STAT_4 0x1db4 + +#define RTL8367C_REG_PHY_STAT_5 0x1db5 + +#define RTL8367C_REG_PHY_STAT_6 0x1db6 + +#define RTL8367C_REG_PHY_STAT_7 0x1db7 + +#define RTL8367C_REG_SDS_STAT_0 0x1db8 + +#define RTL8367C_REG_SDS_STAT_1 0x1db9 + +#define RTL8367C_REG_MAC_LINK_STAT_0 0x1dba +#define RTL8367C_MAC_LINK_STAT_CUR_0_OFFSET 8 +#define RTL8367C_MAC_LINK_STAT_CUR_0_MASK 0xFF00 +#define RTL8367C_MAC_LINK_STAT_LATCH_0_OFFSET 0 +#define RTL8367C_MAC_LINK_STAT_LATCH_0_MASK 0xFF + +#define RTL8367C_REG_MAC_LINK_STAT_1 0x1dbb +#define RTL8367C_MAC_LINK_STAT_1_Reserved_OFFSET 6 +#define RTL8367C_MAC_LINK_STAT_1_Reserved_MASK 0xFFC0 +#define RTL8367C_MAC_LINK_STAT_CUR_1_OFFSET 3 +#define RTL8367C_MAC_LINK_STAT_CUR_1_MASK 0x38 +#define RTL8367C_MAC_LINK_STAT_LATCH_1_OFFSET 0 +#define RTL8367C_MAC_LINK_STAT_LATCH_1_MASK 0x7 + +#define RTL8367C_REG_MISC_CONTROL_1 0x1dc0 +#define RTL8367C_P7_FB_CPL_OFFSET 2 +#define RTL8367C_P7_FB_CPL_MASK 0x4 +#define RTL8367C_P6_FB_CPL_OFFSET 1 +#define RTL8367C_P6_FB_CPL_MASK 0x2 +#define RTL8367C_P5_FB_CPL_OFFSET 0 +#define RTL8367C_P5_FB_CPL_MASK 0x1 + +#define RTL8367C_REG_SDS_MISC_1 0x1dc1 +#define RTL8367C_CFG_SGMII_RXFC_1_OFFSET 14 +#define RTL8367C_CFG_SGMII_RXFC_1_MASK 0x4000 +#define RTL8367C_CFG_SGMII_TXFC_1_OFFSET 13 +#define RTL8367C_CFG_SGMII_TXFC_1_MASK 0x2000 +#define RTL8367C_CFG_MAC9_SEL_HSGMII_OFFSET 11 +#define RTL8367C_CFG_MAC9_SEL_HSGMII_MASK 0x800 +#define RTL8367C_CFG_SGMII_FDUP_1_OFFSET 10 +#define RTL8367C_CFG_SGMII_FDUP_1_MASK 0x400 +#define RTL8367C_CFG_SGMII_LINK_1_OFFSET 9 +#define RTL8367C_CFG_SGMII_LINK_1_MASK 0x200 +#define RTL8367C_CFG_SGMII_SPD_1_OFFSET 7 +#define RTL8367C_CFG_SGMII_SPD_1_MASK 0x180 +#define RTL8367C_CFG_MAC9_SEL_SGMII_OFFSET 6 +#define RTL8367C_CFG_MAC9_SEL_SGMII_MASK 0x40 +#define RTL8367C_CFG_SDS_MODE_14C_1_OFFSET 0 +#define RTL8367C_CFG_SDS_MODE_14C_1_MASK 0x7 + +#define RTL8367C_REG_FIBER_CFG_2_1 0x1dc2 +#define RTL8367C_SDS_RX_DISABLE_1_OFFSET 6 +#define RTL8367C_SDS_RX_DISABLE_1_MASK 0xC0 +#define RTL8367C_SDS_TX_DISABLE_1_OFFSET 4 +#define RTL8367C_SDS_TX_DISABLE_1_MASK 0x30 +#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_OFFSET 2 +#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_MASK 0xC +#define RTL8367C_SDS_FRC_LD_1_OFFSET 0 +#define RTL8367C_SDS_FRC_LD_1_MASK 0x3 + +#define RTL8367C_REG_FIBER_CFG_1_1 0x1dc3 +#define RTL8367C_SDS_FRC_REG4_1_OFFSET 12 +#define RTL8367C_SDS_FRC_REG4_1_MASK 0x1000 +#define RTL8367C_SDS_FRC_REG4_FIB100_1_OFFSET 11 +#define RTL8367C_SDS_FRC_REG4_FIB100_1_MASK 0x800 +#define RTL8367C_SDS_FRC_MODE_1_OFFSET 3 +#define RTL8367C_SDS_FRC_MODE_1_MASK 0x8 +#define RTL8367C_SDS_MODE_1_OFFSET 0 +#define RTL8367C_SDS_MODE_1_MASK 0x7 + +#define RTL8367C_REG_PHYSTS_CTRL0_1 0x1dc4 +#define RTL8367C_LNKUP_DLY_EN_EXT2_OFFSET 9 +#define RTL8367C_LNKUP_DLY_EN_EXT2_MASK 0x200 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_OFFSET 7 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_MASK 0x180 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_OFFSET 5 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_MASK 0x60 +#define RTL8367C_LNKUP_DLY_EN_EXT1_OFFSET 4 +#define RTL8367C_LNKUP_DLY_EN_EXT1_MASK 0x10 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_OFFSET 2 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_MASK 0xC +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_OFFSET 0 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_MASK 0x3 + +#define RTL8367C_REG_FIBER_CFG_3_1 0x1dc5 +#define RTL8367C_FIBER_CFG_3_1_OFFSET 0 +#define RTL8367C_FIBER_CFG_3_1_MASK 0xFFF + +#define RTL8367C_REG_FIBER_CFG_4_1 0x1dc6 + +#define RTL8367C_REG_BUFF_RST_CTRL2_2 0x1dc7 +#define RTL8367C_Cfg_buffrst_sysover_thr_1_OFFSET 3 +#define RTL8367C_Cfg_buffrst_sysover_thr_1_MASK 0x8 +#define RTL8367C_Cfg_buffrst_qover_thr_OFFSET 2 +#define RTL8367C_Cfg_buffrst_qover_thr_MASK 0x4 +#define RTL8367C_Cfg_buffrst_indscover_thr_1_OFFSET 1 +#define RTL8367C_Cfg_buffrst_indscover_thr_1_MASK 0x2 +#define RTL8367C_Cfg_buffrst_dscover_thr_1_OFFSET 0 +#define RTL8367C_Cfg_buffrst_dscover_thr_1_MASK 0x1 + +#define RTL8367C_REG_PHY_DEBUG_CNT_CTRL 0x1dc8 +#define RTL8367C_PHY_MIB_RST_7_OFFSET 15 +#define RTL8367C_PHY_MIB_RST_7_MASK 0x8000 +#define RTL8367C_PHY_MIB_RST_6_OFFSET 14 +#define RTL8367C_PHY_MIB_RST_6_MASK 0x4000 +#define RTL8367C_PHY_MIB_RST_5_OFFSET 13 +#define RTL8367C_PHY_MIB_RST_5_MASK 0x2000 +#define RTL8367C_PHY_MIB_RST_4_OFFSET 12 +#define RTL8367C_PHY_MIB_RST_4_MASK 0x1000 +#define RTL8367C_PHY_MIB_RST_3_OFFSET 11 +#define RTL8367C_PHY_MIB_RST_3_MASK 0x800 +#define RTL8367C_PHY_MIB_RST_2_OFFSET 10 +#define RTL8367C_PHY_MIB_RST_2_MASK 0x400 +#define RTL8367C_PHY_MIB_RST_1_OFFSET 9 +#define RTL8367C_PHY_MIB_RST_1_MASK 0x200 +#define RTL8367C_PHY_MIB_RST_0_OFFSET 8 +#define RTL8367C_PHY_MIB_RST_0_MASK 0x100 +#define RTL8367C_PHY_MIB_EN_7_OFFSET 7 +#define RTL8367C_PHY_MIB_EN_7_MASK 0x80 +#define RTL8367C_PHY_MIB_EN_6_OFFSET 6 +#define RTL8367C_PHY_MIB_EN_6_MASK 0x40 +#define RTL8367C_PHY_MIB_EN_5_OFFSET 5 +#define RTL8367C_PHY_MIB_EN_5_MASK 0x20 +#define RTL8367C_PHY_MIB_EN_4_OFFSET 4 +#define RTL8367C_PHY_MIB_EN_4_MASK 0x10 +#define RTL8367C_PHY_MIB_EN_3_OFFSET 3 +#define RTL8367C_PHY_MIB_EN_3_MASK 0x8 +#define RTL8367C_PHY_MIB_EN_2_OFFSET 2 +#define RTL8367C_PHY_MIB_EN_2_MASK 0x4 +#define RTL8367C_PHY_MIB_EN_1_OFFSET 1 +#define RTL8367C_PHY_MIB_EN_1_MASK 0x2 +#define RTL8367C_PHY_MIB_EN_0_OFFSET 0 +#define RTL8367C_PHY_MIB_EN_0_MASK 0x1 + +#define RTL8367C_REG_TXPKT_CNT_L_0 0x1dc9 + +#define RTL8367C_REG_TXPKT_CNT_H_0 0x1dca + +#define RTL8367C_REG_RXPKT_CNT_L_0 0x1dcb + +#define RTL8367C_REG_RXPKT_CNT_H_0 0x1dcc + +#define RTL8367C_REG_TX_CRC_0 0x1dcd + +#define RTL8367C_REG_RX_CRC_0 0x1dce + +#define RTL8367C_REG_TXPKT_CNT_L_1 0x1dcf + +#define RTL8367C_REG_TXPKT_CNT_H_1 0x1dd0 + +#define RTL8367C_REG_RXPKT_CNT_L_1 0x1dd1 + +#define RTL8367C_REG_RXPKT_CNT_H_1 0x1dd2 + +#define RTL8367C_REG_TX_CRC_1 0x1dd3 + +#define RTL8367C_REG_RX_CRC_1 0x1dd4 + +#define RTL8367C_REG_TXPKT_CNT_L_2 0x1dd5 + +#define RTL8367C_REG_TXPKT_CNT_H_2 0x1dd6 + +#define RTL8367C_REG_RXPKT_CNT_L_2 0x1dd7 + +#define RTL8367C_REG_RXPKT_CNT_H_2 0x1dd8 + +#define RTL8367C_REG_TX_CRC_2 0x1dd9 + +#define RTL8367C_REG_RX_CRC_2 0x1dda + +#define RTL8367C_REG_TXPKT_CNT_L_3 0x1ddb + +#define RTL8367C_REG_TXPKT_CNT_H_3 0x1ddc + +#define RTL8367C_REG_RXPKT_CNT_L_3 0x1ddd + +#define RTL8367C_REG_RXPKT_CNT_H_3 0x1dde + +#define RTL8367C_REG_TX_CRC_3 0x1ddf + +#define RTL8367C_REG_RX_CRC_3 0x1de0 + +#define RTL8367C_REG_TXPKT_CNT_L_4 0x1de1 + +#define RTL8367C_REG_TXPKT_CNT_H_4 0x1de2 + +#define RTL8367C_REG_RXPKT_CNT_L_4 0x1de3 + +#define RTL8367C_REG_RXPKT_CNT_H_4 0x1de4 + +#define RTL8367C_REG_TX_CRC_4 0x1de5 + +#define RTL8367C_REG_RX_CRC_4 0x1de6 + +#define RTL8367C_REG_TXPKT_CNT_L_5 0x1de7 + +#define RTL8367C_REG_TXPKT_CNT_H_5 0x1de8 + +#define RTL8367C_REG_RXPKT_CNT_L_5 0x1de9 + +#define RTL8367C_REG_RXPKT_CNT_H_5 0x1dea + +#define RTL8367C_REG_TX_CRC_5 0x1deb + +#define RTL8367C_REG_RX_CRC_5 0x1dec + +#define RTL8367C_REG_TXPKT_CNT_L_6 0x1ded + +#define RTL8367C_REG_TXPKT_CNT_H_6 0x1dee + +#define RTL8367C_REG_RXPKT_CNT_L_6 0x1def + +#define RTL8367C_REG_RXPKT_CNT_H_6 0x1df0 + +#define RTL8367C_REG_TX_CRC_6 0x1df1 + +#define RTL8367C_REG_RX_CRC_6 0x1df2 + +#define RTL8367C_REG_TXPKT_CNT_L_7 0x1df3 + +#define RTL8367C_REG_TXPKT_CNT_H_7 0x1df4 + +#define RTL8367C_REG_RXPKT_CNT_L_7 0x1df5 + +#define RTL8367C_REG_RXPKT_CNT_H_7 0x1df6 + +#define RTL8367C_REG_TX_CRC_7 0x1df7 + +#define RTL8367C_REG_RX_CRC_7 0x1df8 + +#define RTL8367C_REG_BOND_DBG_0 0x1df9 + +#define RTL8367C_REG_BOND_DBG_1 0x1dfa + +#define RTL8367C_REG_STRP_DBG_0 0x1dfb + +#define RTL8367C_REG_STRP_DBG_1 0x1dfc + +#define RTL8367C_REG_STRP_DBG_2 0x1dfd + +/* (16'h1f00)patch_reg */ + +#define RTL8367C_REG_INDRECT_ACCESS_CTRL 0x1f00 +#define RTL8367C_RW_OFFSET 1 +#define RTL8367C_RW_MASK 0x2 +#define RTL8367C_CMD_OFFSET 0 +#define RTL8367C_CMD_MASK 0x1 + +#define RTL8367C_REG_INDRECT_ACCESS_STATUS 0x1f01 +#define RTL8367C_INDRECT_ACCESS_STATUS_OFFSET 2 +#define RTL8367C_INDRECT_ACCESS_STATUS_MASK 0x7 + +#define RTL8367C_REG_INDRECT_ACCESS_ADDRESS 0x1f02 + +#define RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA 0x1f03 + +#define RTL8367C_REG_INDRECT_ACCESS_READ_DATA 0x1f04 + +/* (16'h6200)fib_page */ + +#define RTL8367C_REG_FIB0_CFG00 0x6200 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_OFFSET 15 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_MASK 0x8000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_OFFSET 14 +#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_MASK 0x4000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_OFFSET 12 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_MASK 0x1000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_OFFSET 11 +#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_MASK 0x800 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_OFFSET 10 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_MASK 0x400 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_OFFSET 9 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_MASK 0x200 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_OFFSET 8 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_MASK 0x100 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_OFFSET 5 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_MASK 0x20 + +#define RTL8367C_REG_FIB0_CFG01 0x6201 +#define RTL8367C_FIB0_CFG01_CAPBILITY_OFFSET 6 +#define RTL8367C_FIB0_CFG01_CAPBILITY_MASK 0xFFC0 +#define RTL8367C_FIB0_CFG01_AN_COMPLETE_OFFSET 5 +#define RTL8367C_FIB0_CFG01_AN_COMPLETE_MASK 0x20 +#define RTL8367C_FIB0_CFG01_R_FAULT_OFFSET 4 +#define RTL8367C_FIB0_CFG01_R_FAULT_MASK 0x10 +#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_OFFSET 3 +#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_MASK 0x8 +#define RTL8367C_FIB0_CFG01_LINK_STATUS_OFFSET 2 +#define RTL8367C_FIB0_CFG01_LINK_STATUS_MASK 0x4 +#define RTL8367C_FIB0_CFG01_JABBER_DETECT_OFFSET 1 +#define RTL8367C_FIB0_CFG01_JABBER_DETECT_MASK 0x2 +#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_OFFSET 0 +#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_MASK 0x1 + +#define RTL8367C_REG_FIB0_CFG02 0x6202 + +#define RTL8367C_REG_FIB0_CFG03 0x6203 +#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_OFFSET 10 +#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_MASK 0xFC00 +#define RTL8367C_FIB0_CFG03_MODEL_NO_OFFSET 4 +#define RTL8367C_FIB0_CFG03_MODEL_NO_MASK 0x3F0 +#define RTL8367C_FIB0_CFG03_REVISION_NO_OFFSET 0 +#define RTL8367C_FIB0_CFG03_REVISION_NO_MASK 0xF + +#define RTL8367C_REG_FIB0_CFG04 0x6204 + +#define RTL8367C_REG_FIB0_CFG05 0x6205 + +#define RTL8367C_REG_FIB0_CFG06 0x6206 +#define RTL8367C_FIB0_CFG06_FIB_NP_EN_OFFSET 2 +#define RTL8367C_FIB0_CFG06_FIB_NP_EN_MASK 0x4 +#define RTL8367C_FIB0_CFG06_RXPAGE_OFFSET 1 +#define RTL8367C_FIB0_CFG06_RXPAGE_MASK 0x2 + +#define RTL8367C_REG_FIB0_CFG07 0x6207 + +#define RTL8367C_REG_FIB0_CFG08 0x6208 + +#define RTL8367C_REG_FIB0_CFG09 0x6209 + +#define RTL8367C_REG_FIB0_CFG10 0x620a + +#define RTL8367C_REG_FIB0_CFG11 0x620b + +#define RTL8367C_REG_FIB0_CFG12 0x620c + +#define RTL8367C_REG_FIB0_CFG13 0x620d +#define RTL8367C_FIB0_CFG13_INDR_FUNC_OFFSET 14 +#define RTL8367C_FIB0_CFG13_INDR_FUNC_MASK 0xC000 +#define RTL8367C_FIB0_CFG13_DUMMY_OFFSET 5 +#define RTL8367C_FIB0_CFG13_DUMMY_MASK 0x3FE0 +#define RTL8367C_FIB0_CFG13_INDR_DEVAD_OFFSET 0 +#define RTL8367C_FIB0_CFG13_INDR_DEVAD_MASK 0x1F + +#define RTL8367C_REG_FIB0_CFG14 0x620e + +#define RTL8367C_REG_FIB0_CFG15 0x620f + +#define RTL8367C_REG_FIB1_CFG00 0x6210 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_OFFSET 15 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_MASK 0x8000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_OFFSET 14 +#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_MASK 0x4000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_OFFSET 12 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_MASK 0x1000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_OFFSET 11 +#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_MASK 0x800 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_OFFSET 10 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_MASK 0x400 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_OFFSET 9 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_MASK 0x200 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_OFFSET 8 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_MASK 0x100 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_OFFSET 5 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_MASK 0x20 + +#define RTL8367C_REG_FIB1_CFG01 0x6211 +#define RTL8367C_FIB1_CFG01_CAPBILITY_OFFSET 6 +#define RTL8367C_FIB1_CFG01_CAPBILITY_MASK 0xFFC0 +#define RTL8367C_FIB1_CFG01_AN_COMPLETE_OFFSET 5 +#define RTL8367C_FIB1_CFG01_AN_COMPLETE_MASK 0x20 +#define RTL8367C_FIB1_CFG01_R_FAULT_OFFSET 4 +#define RTL8367C_FIB1_CFG01_R_FAULT_MASK 0x10 +#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_OFFSET 3 +#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_MASK 0x8 +#define RTL8367C_FIB1_CFG01_LINK_STATUS_OFFSET 2 +#define RTL8367C_FIB1_CFG01_LINK_STATUS_MASK 0x4 +#define RTL8367C_FIB1_CFG01_JABBER_DETECT_OFFSET 1 +#define RTL8367C_FIB1_CFG01_JABBER_DETECT_MASK 0x2 +#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_OFFSET 0 +#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_MASK 0x1 + +#define RTL8367C_REG_FIB1_CFG02 0x6212 + +#define RTL8367C_REG_FIB1_CFG03 0x6213 +#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_OFFSET 10 +#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_MASK 0xFC00 +#define RTL8367C_FIB1_CFG03_MODEL_NO_OFFSET 4 +#define RTL8367C_FIB1_CFG03_MODEL_NO_MASK 0x3F0 +#define RTL8367C_FIB1_CFG03_REVISION_NO_OFFSET 0 +#define RTL8367C_FIB1_CFG03_REVISION_NO_MASK 0xF + +#define RTL8367C_REG_FIB1_CFG04 0x6214 + +#define RTL8367C_REG_FIB1_CFG05 0x6215 + +#define RTL8367C_REG_FIB1_CFG06 0x6216 +#define RTL8367C_FIB1_CFG06_FIB_NP_EN_OFFSET 2 +#define RTL8367C_FIB1_CFG06_FIB_NP_EN_MASK 0x4 +#define RTL8367C_FIB1_CFG06_RXPAGE_OFFSET 1 +#define RTL8367C_FIB1_CFG06_RXPAGE_MASK 0x2 + +#define RTL8367C_REG_FIB1_CFG07 0x6217 + +#define RTL8367C_REG_FIB1_CFG08 0x6218 + +#define RTL8367C_REG_FIB1_CFG09 0x6219 + +#define RTL8367C_REG_FIB1_CFG10 0x621a + +#define RTL8367C_REG_FIB1_CFG11 0x621b + +#define RTL8367C_REG_FIB1_CFG12 0x621c + +#define RTL8367C_REG_FIB1_CFG13 0x621d +#define RTL8367C_FIB1_CFG13_INDR_FUNC_OFFSET 14 +#define RTL8367C_FIB1_CFG13_INDR_FUNC_MASK 0xC000 +#define RTL8367C_FIB1_CFG13_DUMMY_OFFSET 5 +#define RTL8367C_FIB1_CFG13_DUMMY_MASK 0x3FE0 +#define RTL8367C_FIB1_CFG13_INDR_DEVAD_OFFSET 0 +#define RTL8367C_FIB1_CFG13_INDR_DEVAD_MASK 0x1F + +#define RTL8367C_REG_FIB1_CFG14 0x621e + +#define RTL8367C_REG_FIB1_CFG15 0x621f + +/* (16'h6400)timer_1588 */ + +#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC 0x6400 + +#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC 0x6401 +#define RTL8367C_PTP_TIME_NSEC_H_EXEC_OFFSET 15 +#define RTL8367C_PTP_TIME_NSEC_H_EXEC_MASK 0x8000 +#define RTL8367C_PTP_TIME_NSEC_H_CMD_OFFSET 12 +#define RTL8367C_PTP_TIME_NSEC_H_CMD_MASK 0x3000 +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_OFFSET 0 +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK 0x7FF + +#define RTL8367C_REG_PTP_TIME_SEC_L_SEC 0x6402 + +#define RTL8367C_REG_PTP_TIME_SEC_H_SEC 0x6403 + +#define RTL8367C_REG_PTP_TIME_CFG 0x6404 +#define RTL8367C_CFG_TIMER_EN_FRC_OFFSET 2 +#define RTL8367C_CFG_TIMER_EN_FRC_MASK 0x4 +#define RTL8367C_CFG_TIMER_1588_EN_OFFSET 1 +#define RTL8367C_CFG_TIMER_1588_EN_MASK 0x2 +#define RTL8367C_CFG_CLK_SRC_OFFSET 0 +#define RTL8367C_CFG_CLK_SRC_MASK 0x1 + +#define RTL8367C_REG_OTAG_TPID 0x6405 + +#define RTL8367C_REG_ITAG_TPID 0x6406 + +#define RTL8367C_REG_MAC_ADDR_L 0x6407 + +#define RTL8367C_REG_MAC_ADDR_M 0x6408 + +#define RTL8367C_REG_MAC_ADDR_H 0x6409 + +#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC_RD 0x640a + +#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC_RD 0x640b +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_OFFSET 0 +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_MASK 0x7FF + +#define RTL8367C_REG_PTP_TIME_SEC_L_SEC_RD 0x640c + +#define RTL8367C_REG_PTP_TIME_SEC_H_SEC_RD 0x640d + +#define RTL8367C_REG_PTP_TIME_CFG2 0x640e +#define RTL8367C_CFG_EN_OFFLOAD_OFFSET 9 +#define RTL8367C_CFG_EN_OFFLOAD_MASK 0x200 +#define RTL8367C_CFG_SAVE_OFF_TS_OFFSET 8 +#define RTL8367C_CFG_SAVE_OFF_TS_MASK 0x100 +#define RTL8367C_CFG_IMR_OFFSET 0 +#define RTL8367C_CFG_IMR_MASK 0xFF + +#define RTL8367C_REG_PTP_INTERRUPT_CFG 0x640f +#define RTL8367C_P9_INTERRUPT_OFFSET 9 +#define RTL8367C_P9_INTERRUPT_MASK 0x200 +#define RTL8367C_P8_INTERRUPT_OFFSET 8 +#define RTL8367C_P8_INTERRUPT_MASK 0x100 +#define RTL8367C_P7_INTERRUPT_OFFSET 7 +#define RTL8367C_P7_INTERRUPT_MASK 0x80 +#define RTL8367C_P6_INTERRUPT_OFFSET 6 +#define RTL8367C_P6_INTERRUPT_MASK 0x40 +#define RTL8367C_P5_INTERRUPT_OFFSET 5 +#define RTL8367C_P5_INTERRUPT_MASK 0x20 +#define RTL8367C_P4_INTERRUPT_OFFSET 4 +#define RTL8367C_P4_INTERRUPT_MASK 0x10 +#define RTL8367C_P3_INTERRUPT_OFFSET 3 +#define RTL8367C_P3_INTERRUPT_MASK 0x8 +#define RTL8367C_P2_INTERRUPT_OFFSET 2 +#define RTL8367C_P2_INTERRUPT_MASK 0x4 +#define RTL8367C_P1_INTERRUPT_OFFSET 1 +#define RTL8367C_P1_INTERRUPT_MASK 0x2 +#define RTL8367C_P0_INTERRUPT_OFFSET 0 +#define RTL8367C_P0_INTERRUPT_MASK 0x1 + +#define RTL8367C_REG_P0_TX_SYNC_SEQ_ID 0x6410 + +#define RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID 0x6411 + +#define RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID 0x6412 + +#define RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID 0x6413 + +#define RTL8367C_REG_P0_RX_SYNC_SEQ_ID 0x6414 + +#define RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID 0x6415 + +#define RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID 0x6416 + +#define RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID 0x6417 + +#define RTL8367C_REG_P0_PORT_NSEC_15_0 0x6418 + +#define RTL8367C_REG_P0_PORT_NSEC_26_16 0x6419 +#define RTL8367C_P0_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P0_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P0_PORT_SEC_15_0 0x641a + +#define RTL8367C_REG_P0_PORT_SEC_31_16 0x641b + +#define RTL8367C_REG_P0_EAV_CFG 0x641c +#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P0_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P0_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P1_TX_SYNC_SEQ_ID 0x6420 + +#define RTL8367C_REG_P1_TX_DELAY_REQ_SEQ_ID 0x6421 + +#define RTL8367C_REG_P1_TX_PDELAY_REQ_SEQ_ID 0x6422 + +#define RTL8367C_REG_P1_TX_PDELAY_RESP_SEQ_ID 0x6423 + +#define RTL8367C_REG_P1_RX_SYNC_SEQ_ID 0x6424 + +#define RTL8367C_REG_P1_RX_DELAY_REQ_SEQ_ID 0x6425 + +#define RTL8367C_REG_P1_RX_PDELAY_REQ_SEQ_ID 0x6426 + +#define RTL8367C_REG_P1_RX_PDELAY_RESP_SEQ_ID 0x6427 + +#define RTL8367C_REG_P1_PORT_NSEC_15_0 0x6428 + +#define RTL8367C_REG_P1_PORT_NSEC_26_16 0x6429 +#define RTL8367C_P1_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P1_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P1_PORT_SEC_15_0 0x642a + +#define RTL8367C_REG_P1_PORT_SEC_31_16 0x642b + +#define RTL8367C_REG_P1_EAV_CFG 0x642c +#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P1_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P1_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P1_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P1_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P2_TX_SYNC_SEQ_ID 0x6430 + +#define RTL8367C_REG_P2_TX_DELAY_REQ_SEQ_ID 0x6431 + +#define RTL8367C_REG_P2_TX_PDELAY_REQ_SEQ_ID 0x6432 + +#define RTL8367C_REG_P2_TX_PDELAY_RESP_SEQ_ID 0x6433 + +#define RTL8367C_REG_P2_RX_SYNC_SEQ_ID 0x6434 + +#define RTL8367C_REG_P2_RX_DELAY_REQ_SEQ_ID 0x6435 + +#define RTL8367C_REG_P2_RX_PDELAY_REQ_SEQ_ID 0x6436 + +#define RTL8367C_REG_P2_RX_PDELAY_RESP_SEQ_ID 0x6437 + +#define RTL8367C_REG_P2_PORT_NSEC_15_0 0x6438 + +#define RTL8367C_REG_P2_PORT_NSEC_26_16 0x6439 +#define RTL8367C_P2_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P2_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P2_PORT_SEC_15_0 0x643a + +#define RTL8367C_REG_P2_PORT_SEC_31_16 0x643b + +#define RTL8367C_REG_P2_EAV_CFG 0x643c +#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P2_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P2_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P2_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P2_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P3_TX_SYNC_SEQ_ID 0x6440 + +#define RTL8367C_REG_P3_TX_DELAY_REQ_SEQ_ID 0x6441 + +#define RTL8367C_REG_P3_TX_PDELAY_REQ_SEQ_ID 0x6442 + +#define RTL8367C_REG_P3_TX_PDELAY_RESP_SEQ_ID 0x6443 + +#define RTL8367C_REG_P3_RX_SYNC_SEQ_ID 0x6444 + +#define RTL8367C_REG_P3_RX_DELAY_REQ_SEQ_ID 0x6445 + +#define RTL8367C_REG_P3_RX_PDELAY_REQ_SEQ_ID 0x6446 + +#define RTL8367C_REG_P3_RX_PDELAY_RESP_SEQ_ID 0x6447 + +#define RTL8367C_REG_P3_PORT_NSEC_15_0 0x6448 + +#define RTL8367C_REG_P3_PORT_NSEC_26_16 0x6449 +#define RTL8367C_P3_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P3_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P3_PORT_SEC_15_0 0x644a + +#define RTL8367C_REG_P3_PORT_SEC_31_16 0x644b + +#define RTL8367C_REG_P3_EAV_CFG 0x644c +#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P3_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P3_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P3_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P3_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P4_TX_SYNC_SEQ_ID 0x6450 + +#define RTL8367C_REG_P4_TX_DELAY_REQ_SEQ_ID 0x6451 + +#define RTL8367C_REG_P4_TX_PDELAY_REQ_SEQ_ID 0x6452 + +#define RTL8367C_REG_P4_TX_PDELAY_RESP_SEQ_ID 0x6453 + +#define RTL8367C_REG_P4_RX_SYNC_SEQ_ID 0x6454 + +#define RTL8367C_REG_P4_RX_DELAY_REQ_SEQ_ID 0x6455 + +#define RTL8367C_REG_P4_RX_PDELAY_REQ_SEQ_ID 0x6456 + +#define RTL8367C_REG_P4_RX_PDELAY_RESP_SEQ_ID 0x6457 + +#define RTL8367C_REG_P4_PORT_NSEC_15_0 0x6458 + +#define RTL8367C_REG_P4_PORT_NSEC_26_16 0x6459 +#define RTL8367C_P4_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P4_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P4_PORT_SEC_15_0 0x645a + +#define RTL8367C_REG_P4_PORT_SEC_31_16 0x645b + +#define RTL8367C_REG_P4_EAV_CFG 0x645c +#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P4_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P4_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P4_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P4_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P6_TX_SYNC_SEQ_ID 0x6460 + +#define RTL8367C_REG_P6_TX_DELAY_REQ_SEQ_ID 0x6461 + +#define RTL8367C_REG_P6_TX_PDELAY_REQ_SEQ_ID 0x6462 + +#define RTL8367C_REG_P6_TX_PDELAY_RESP_SEQ_ID 0x6463 + +#define RTL8367C_REG_P6_RX_SYNC_SEQ_ID 0x6464 + +#define RTL8367C_REG_P6_RX_DELAY_REQ_SEQ_ID 0x6465 + +#define RTL8367C_REG_P6_RX_PDELAY_REQ_SEQ_ID 0x6466 + +#define RTL8367C_REG_P6_RX_PDELAY_RESP_SEQ_ID 0x6467 + +#define RTL8367C_REG_P6_PORT_NSEC_15_0 0x6468 + +#define RTL8367C_REG_P6_PORT_NSEC_26_16 0x6469 +#define RTL8367C_P6_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P6_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P6_PORT_SEC_15_0 0x646a + +#define RTL8367C_REG_P6_PORT_SEC_31_16 0x646b + +#define RTL8367C_REG_P6_EAV_CFG 0x646c +#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P6_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P6_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P6_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P6_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P7_TX_SYNC_SEQ_ID 0x6470 + +#define RTL8367C_REG_P7_TX_DELAY_REQ_SEQ_ID 0x6471 + +#define RTL8367C_REG_P7_TX_PDELAY_REQ_SEQ_ID 0x6472 + +#define RTL8367C_REG_P7_TX_PDELAY_RESP_SEQ_ID 0x6473 + +#define RTL8367C_REG_P7_RX_SYNC_SEQ_ID 0x6474 + +#define RTL8367C_REG_P7_RX_DELAY_REQ_SEQ_ID 0x6475 + +#define RTL8367C_REG_P7_RX_PDELAY_REQ_SEQ_ID 0x6476 + +#define RTL8367C_REG_P7_RX_PDELAY_RESP_SEQ_ID 0x6477 + +#define RTL8367C_REG_P7_PORT_NSEC_15_0 0x6478 + +#define RTL8367C_REG_P7_PORT_NSEC_26_16 0x6479 +#define RTL8367C_P7_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P7_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P7_PORT_SEC_15_0 0x647a + +#define RTL8367C_REG_P7_PORT_SEC_31_16 0x647b + +#define RTL8367C_REG_P7_EAV_CFG 0x647c +#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P7_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P7_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P7_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P7_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P5_TX_SYNC_SEQ_ID 0x6480 + +#define RTL8367C_REG_P5_TX_DELAY_REQ_SEQ_ID 0x6481 + +#define RTL8367C_REG_P5_TX_PDELAY_REQ_SEQ_ID 0x6482 + +#define RTL8367C_REG_P5_TX_PDELAY_RESP_SEQ_ID 0x6483 + +#define RTL8367C_REG_P5_RX_SYNC_SEQ_ID 0x6484 + +#define RTL8367C_REG_P5_RX_DELAY_REQ_SEQ_ID 0x6485 + +#define RTL8367C_REG_P5_RX_PDELAY_REQ_SEQ_ID 0x6486 + +#define RTL8367C_REG_P5_RX_PDELAY_RESP_SEQ_ID 0x6487 + +#define RTL8367C_REG_P5_PORT_NSEC_15_0 0x6488 + +#define RTL8367C_REG_P5_PORT_NSEC_26_16 0x6489 +#define RTL8367C_P5_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P5_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P5_PORT_SEC_15_0 0x648a + +#define RTL8367C_REG_P5_PORT_SEC_31_16 0x648b + +#define RTL8367C_REG_P5_EAV_CFG 0x648c +#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P5_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P5_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P5_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P5_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P8_TX_SYNC_SEQ_ID 0x6490 + +#define RTL8367C_REG_P8_TX_DELAY_REQ_SEQ_ID 0x6491 + +#define RTL8367C_REG_P8_TX_PDELAY_REQ_SEQ_ID 0x6492 + +#define RTL8367C_REG_P8_TX_PDELAY_RESP_SEQ_ID 0x6493 + +#define RTL8367C_REG_P8_RX_SYNC_SEQ_ID 0x6494 + +#define RTL8367C_REG_P8_RX_DELAY_REQ_SEQ_ID 0x6495 + +#define RTL8367C_REG_P8_RX_PDELAY_REQ_SEQ_ID 0x6496 + +#define RTL8367C_REG_P8_RX_PDELAY_RESP_SEQ_ID 0x6497 + +#define RTL8367C_REG_P8_PORT_NSEC_15_0 0x6498 + +#define RTL8367C_REG_P8_PORT_NSEC_26_16 0x6499 +#define RTL8367C_P8_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P8_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P8_PORT_SEC_15_0 0x649a + +#define RTL8367C_REG_P8_PORT_SEC_31_16 0x649b + +#define RTL8367C_REG_P8_EAV_CFG 0x649c +#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P8_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P8_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P8_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P8_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P9_TX_SYNC_SEQ_ID 0x64a0 + +#define RTL8367C_REG_P9_TX_DELAY_REQ_SEQ_ID 0x64a1 + +#define RTL8367C_REG_P9_TX_PDELAY_REQ_SEQ_ID 0x64a2 + +#define RTL8367C_REG_P9_TX_PDELAY_RESP_SEQ_ID 0x64a3 + +#define RTL8367C_REG_P9_RX_SYNC_SEQ_ID 0x64a4 + +#define RTL8367C_REG_P9_RX_DELAY_REQ_SEQ_ID 0x64a5 + +#define RTL8367C_REG_P9_RX_PDELAY_REQ_SEQ_ID 0x64a6 + +#define RTL8367C_REG_P9_RX_PDELAY_RESP_SEQ_ID 0x64a7 + +#define RTL8367C_REG_P9_PORT_NSEC_15_0 0x64a8 + +#define RTL8367C_REG_P9_PORT_NSEC_26_16 0x64a9 +#define RTL8367C_P9_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P9_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P9_PORT_SEC_15_0 0x64aa + +#define RTL8367C_REG_P9_PORT_SEC_31_16 0x64ab + +#define RTL8367C_REG_P9_EAV_CFG 0x64ac +#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P9_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P9_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P9_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P9_EAV_CFG_TX_SYNC_MASK 0x1 + +/* (16'h6600)sds_indacs_reg */ + +#define RTL8367C_REG_SDS_INDACS_CMD 0x6600 +#define RTL8367C_SDS_CMD_BUSY_OFFSET 8 +#define RTL8367C_SDS_CMD_BUSY_MASK 0x100 +#define RTL8367C_SDS_CMD_OFFSET 7 +#define RTL8367C_SDS_CMD_MASK 0x80 +#define RTL8367C_SDS_RWOP_OFFSET 6 +#define RTL8367C_SDS_RWOP_MASK 0x40 +#define RTL8367C_SDS_INDEX_OFFSET 0 +#define RTL8367C_SDS_INDEX_MASK 0x3F + +#define RTL8367C_REG_SDS_INDACS_ADR 0x6601 +#define RTL8367C_SDS_PAGE_OFFSET 5 +#define RTL8367C_SDS_PAGE_MASK 0x7E0 +#define RTL8367C_SDS_REGAD_OFFSET 0 +#define RTL8367C_SDS_REGAD_MASK 0x1F + +#define RTL8367C_REG_SDS_INDACS_DATA 0x6602 + + +#endif /*#ifndef _RTL8367C_REG_H_*/ + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/smi.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/smi.h new file mode 100755 index 00000000..b77d7607 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/smi.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367C switch low-level function for access register + * Feature : SMI related functions + * + */ + +#ifndef __SMI_H__ +#define __SMI_H__ + +#include +#include "rtk_error.h" + +#define MDC_MDIO_CTRL0_REG 31 +#define MDC_MDIO_START_REG 29 +#define MDC_MDIO_CTRL1_REG 21 +#define MDC_MDIO_ADDRESS_REG 23 +#define MDC_MDIO_DATA_WRITE_REG 24 +#define MDC_MDIO_DATA_READ_REG 25 +#define MDC_MDIO_PREAMBLE_LEN 32 + +#define MDC_MDIO_START_OP 0xFFFF +#define MDC_MDIO_ADDR_OP 0x000E +#define MDC_MDIO_READ_OP 0x0001 +#define MDC_MDIO_WRITE_OP 0x0003 + +#define SPI_READ_OP 0x3 +#define SPI_WRITE_OP 0x2 +#define SPI_READ_OP_LEN 0x8 +#define SPI_WRITE_OP_LEN 0x8 +#define SPI_REG_LEN 16 +#define SPI_DATA_LEN 16 + +#define GPIO_DIR_IN 1 +#define GPIO_DIR_OUT 0 + +#define ack_timer 5 + +#define DELAY 10000 +#define CLK_DURATION(clk) { int i; for(i=0; isvid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *psvlan_cfg); + +/* Function Name: + * rtk_svlan_memberPortEntry_get + * Description: + * Get SVLAN member Configure. + * Input: + * svid - SVLAN id + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *pSvlan_cfg); + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_set + * Description: + * Configure system SVLAN member by index + * Input: + * idx - Index (0 ~ 63) + * psvlan_cfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. + * Note: + * The API can set system 64 accepted s-tag frame format by index. + * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_get + * Description: + * Get SVLAN member Configure by index. + * Input: + * idx - Index (0 ~ 63) + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); + +/* Function Name: + * rtk_svlan_defaultSvlan_set + * Description: + * Configure default egress SVLAN. + * Input: + * port - Source port + * svid - SVLAN id + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * Note: + * The API can set port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +extern rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_defaultSvlan_get + * Description: + * Get the configure default egress SVLAN. + * Input: + * port - Source port + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +extern rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_c2s_add + * Description: + * Configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set system C2S configuration. ASIC will check upstream's VID and assign related + * SVID to mathed packet. There are 128 SVLAN C2S configurations. + */ +extern rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_c2s_del + * Description: + * Delete one C2S entry + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete system C2S configuration. There are 128 SVLAN C2S configurations. + */ +extern rtk_api_ret_t rtk_svlan_c2s_del(rtk_vlan_t vid, rtk_port_t src_port); + +/* Function Name: + * rtk_svlan_c2s_get + * Description: + * Get configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * Output: + * pSvid - SVLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. + */ +extern rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_untag_action_set + * Description: + * Configure Action of downstream Un-Stag packet + * Input: + * action - Action for UnStag + * svid - The SVID assigned to UnStag packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also supported by this API. The parameter of svid is + * only referenced when the action is set to UNTAG_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_untag_action_get + * Description: + * Get Action of downstream Un-Stag packet + * Input: + * None + * Output: + * pAction - Action for UnStag + * pSvid - The SVID assigned to UnStag packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNTAG_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_unmatch_action_set + * Description: + * Configure Action of downstream Unmatch packet + * Input: + * action - Action for Unmatch + * svid - The SVID assigned to Unmatch packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-match packet. A SVID assigned + * to the un-match is also supported by this API. The parameter od svid is + * only refernced when the action is set to UNMATCH_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_unmatch_action_get + * Description: + * Get Action of downstream Unmatch packet + * Input: + * None + * Output: + * pAction - Action for Unmatch + * pSvid - The SVID assigned to Unmatch packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-match packet. A SVID assigned + * to the un-match is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNMATCH_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_dmac_vidsel_set + * Description: + * Set DMAC CVID selection + * Input: + * port - Port + * enable - state of DMAC CVID Selection + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set DMAC CVID Selection state + */ +extern rtk_api_ret_t rtk_svlan_dmac_vidsel_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_svlan_dmac_vidsel_get + * Description: + * Get DMAC CVID selection + * Input: + * port - Port + * Output: + * pEnable - state of DMAC CVID Selection + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get DMAC CVID Selection state + */ +extern rtk_api_ret_t rtk_svlan_dmac_vidsel_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_svlan_ipmc2s_add + * Description: + * add ip multicast address to SVLAN + * Input: + * svid - SVLAN VID + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set IP mutlicast to SVID configuration. If upstream packet is IPv4 multicast + * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. + * There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_ipmc2s_del + * Description: + * delete ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk); + +/* Function Name: + * rtk_svlan_ipmc2s_get + * Description: + * Get ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_l2mc2s_add + * Description: + * Add L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set L2 Mutlicast to SVID configuration. If upstream packet is L2 multicast + * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 + * SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_l2mc2s_del + * Description: + * delete L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete Mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk); + +/* Function Name: + * rtk_svlan_l2mc2s_get + * Description: + * Get L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get L2 mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_sp2c_add + * Description: + * Add system SP2C configuration + * Input: + * cvid - VLAN ID + * dst_port - Destination port of SVLAN to CVLAN configuration + * svid - SVLAN VID + * + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned + * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. + * There are 128 SP2C configurations. + */ +extern rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid); + +/* Function Name: + * rtk_svlan_sp2c_get + * Description: + * Get configure system SP2C content + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * pCvid - VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * Note: + * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +extern rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid); + +/* Function Name: + * rtk_svlan_sp2c_del + * Description: + * Delete system SP2C configuration + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +extern rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port); + + +/* Function Name: + * rtk_svlan_lookupType_set + * Description: + * Set lookup type of SVLAN + * Input: + * type - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +extern rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type); + +/* Function Name: + * rtk_svlan_lookupType_get + * Description: + * Get lookup type of SVLAN + * Input: + * pType - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +extern rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType); + +/* Function Name: + * rtk_svlan_trapPri_set + * Description: + * Set svlan trap priority + * Input: + * priority - priority for trap packets + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_INT_PRIORITY + * Note: + * None + */ +extern rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority); + +/* Function Name: + * rtk_svlan_trapPri_get + * Description: + * Get svlan trap priority + * Input: + * None + * Output: + * pPriority - priority for trap packets + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +extern rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority); + +/* Function Name: + * rtk_svlan_unassign_action_set + * Description: + * Configure Action of upstream without svid assign action + * Input: + * action - Action for Un-assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of upstream Un-assign svid packet. If action is not + * trap to CPU, the port-based SVID sure be assign as system need + */ +extern rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action); + +/* Function Name: + * rtk_svlan_unassign_action_get + * Description: + * Get action of upstream without svid assignment + * Input: + * None + * Output: + * pAction - Action for Un-assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * None + */ +extern rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction); + + +/* Function Name: + * rtk_svlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +extern rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); + + +#endif /* __RTK_API_SVLAN_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trap.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trap.h new file mode 100755 index 00000000..0cdb64a7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trap.h @@ -0,0 +1,757 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Trap module high-layer API defination + * + */ + +#ifndef __RTK_API_TRAP_H__ +#define __RTK_API_TRAP_H__ + + +typedef enum rtk_trap_type_e +{ + TRAP_BRG_GROUP = 0, + TRAP_FD_PAUSE, + TRAP_SP_MCAST, + TRAP_1X_PAE, + TRAP_UNDEF_BRG_04, + TRAP_UNDEF_BRG_05, + TRAP_UNDEF_BRG_06, + TRAP_UNDEF_BRG_07, + TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + TRAP_UNDEF_BRG_09, + TRAP_UNDEF_BRG_0A, + TRAP_UNDEF_BRG_0B, + TRAP_UNDEF_BRG_0C, + TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + TRAP_8021AB, + TRAP_UNDEF_BRG_0F, + TRAP_BRG_MNGEMENT, + TRAP_UNDEFINED_11, + TRAP_UNDEFINED_12, + TRAP_UNDEFINED_13, + TRAP_UNDEFINED_14, + TRAP_UNDEFINED_15, + TRAP_UNDEFINED_16, + TRAP_UNDEFINED_17, + TRAP_UNDEFINED_18, + TRAP_UNDEFINED_19, + TRAP_UNDEFINED_1A, + TRAP_UNDEFINED_1B, + TRAP_UNDEFINED_1C, + TRAP_UNDEFINED_1D, + TRAP_UNDEFINED_1E, + TRAP_UNDEFINED_1F, + TRAP_GMRP, + TRAP_GVRP, + TRAP_UNDEF_GARP_22, + TRAP_UNDEF_GARP_23, + TRAP_UNDEF_GARP_24, + TRAP_UNDEF_GARP_25, + TRAP_UNDEF_GARP_26, + TRAP_UNDEF_GARP_27, + TRAP_UNDEF_GARP_28, + TRAP_UNDEF_GARP_29, + TRAP_UNDEF_GARP_2A, + TRAP_UNDEF_GARP_2B, + TRAP_UNDEF_GARP_2C, + TRAP_UNDEF_GARP_2D, + TRAP_UNDEF_GARP_2E, + TRAP_UNDEF_GARP_2F, + TRAP_CDP, + TRAP_CSSTP, + TRAP_LLDP, + TRAP_END, +}rtk_trap_type_t; + + +typedef enum rtk_mcast_type_e +{ + MCAST_L2 = 0, + MCAST_IPV4, + MCAST_IPV6, + MCAST_END +} rtk_mcast_type_t; + +typedef enum rtk_trap_mcast_action_e +{ + MCAST_ACTION_FORWARD = 0, + MCAST_ACTION_DROP, + MCAST_ACTION_TRAP2CPU, + MCAST_ACTION_ROUTER_PORT, + MCAST_ACTION_DROP_EX_RMA, + MCAST_ACTION_END +} rtk_trap_mcast_action_t; + +typedef enum rtk_trap_rma_action_e +{ + RMA_ACTION_FORWARD = 0, + RMA_ACTION_TRAP2CPU, + RMA_ACTION_DROP, + RMA_ACTION_FORWARD_EXCLUDE_CPU, + RMA_ACTION_END +} rtk_trap_rma_action_t; + +typedef enum rtk_trap_ucast_action_e +{ + UCAST_ACTION_FORWARD_PMASK = 0, + UCAST_ACTION_DROP, + UCAST_ACTION_TRAP2CPU, + UCAST_ACTION_FLOODING, + UCAST_ACTION_END +} rtk_trap_ucast_action_t; + +typedef enum rtk_trap_ucast_type_e +{ + UCAST_UNKNOWNDA = 0, + UCAST_UNKNOWNSA, + UCAST_UNMATCHSA, + UCAST_END +} rtk_trap_ucast_type_t; + +typedef enum rtk_trap_reason_type_e +{ + TRAP_REASON_RMA = 0, + TRAP_REASON_OAM, + TRAP_REASON_1XUNAUTH, + TRAP_REASON_VLANSTACK, + TRAP_REASON_UNKNOWNMC, + TRAP_REASON_END, +} rtk_trap_reason_type_t; + + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_set + * Description: + * Set unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * ucast_action - Unknown unicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action); + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_get + * Description: + * Get unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * Output: + * pUcast_action - Unknown unicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * This API can get unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action); + +/* Function Name: + * rtk_trap_unknownMacPktAction_set + * Description: + * Set unknown source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action); + +/* Function Name: + * rtk_trap_unknownMacPktAction_get + * Description: + * Get unknown source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); + +/* Function Name: + * rtk_trap_unmatchMacPktAction_set + * Description: + * Set unmatch source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action); + +/* Function Name: + * rtk_trap_unmatchMacPktAction_get + * Description: + * Get unmatch source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); + +/* Function Name: + * rtk_trap_unmatchMacMoving_set + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +extern rtk_api_ret_t rtk_trap_unmatchMacMoving_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_trap_unmatchMacMoving_get + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * Output: + * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +extern rtk_api_ret_t rtk_trap_unmatchMacMoving_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_trap_unknownMcastPktAction_set + * Description: + * Set behavior of unknown multicast + * Input: + * port - Port id. + * type - unknown multicast packet type. + * mcast_action - unknown multicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action); + +/* Function Name: + * rtk_trap_unknownMcastPktAction_get + * Description: + * Get behavior of unknown multicast + * Input: + * type - unknown multicast packet type. + * Output: + * pMcast_action - unknown multicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid operation. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action); + +/* Function Name: + * rtk_trap_lldpEnable_set + * Description: + * Set LLDP enable. + * Input: + * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + + */ +extern rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_trap_lldpEnable_get + * Description: + * Get LLDP status. + * Input: + * None + * Output: + * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * LLDP is as following definition. + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + */ +extern rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_set + * Description: + * Set priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * priority - internal priority that is going to be set for specific trap reason. + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority); + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_get + * Description: + * Get priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * Output: + * pPriority - configured internal priority for such reason. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority); + +/* Function Name: + * rtk_trap_rmaAction_set + * Description: + * Set Reserved multicast address action configuration. + * Input: + * type - rma type. + * rma_action - RMA action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +extern rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action); + +/* Function Name: + * rtk_trap_rmaAction_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pRma_action - RMA action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +extern rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action); + +/* Function Name: + * rtk_trap_rmaKeepFormat_set + * Description: + * Set Reserved multicast address keep format configuration. + * Input: + * type - rma type. + * enable - enable keep format. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +extern rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_trap_rmaKeepFormat_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pEnable - keep format status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +extern rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable); + + +#endif /* __RTK_API_TRAP_H__ */ + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trunk.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trunk.h new file mode 100755 index 00000000..dff61769 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/trunk.h @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Trunk module high-layer TRUNK defination + * + */ + +#ifndef __RTK_API_TRUNK_H__ +#define __RTK_API_TRUNK_H__ + +/* + * Data Type Declaration + */ +#define RTK_TRUNK_DPORT_HASH_MASK 0x40 +#define RTK_TRUNK_SPORT_HASH_MASK 0x20 +#define RTK_TRUNK_DIP_HASH_MASK 0x10 +#define RTK_TRUNK_SIP_HASH_MASK 0x8 +#define RTK_TRUNK_DMAC_HASH_MASK 0x4 +#define RTK_TRUNK_SMAC_HASH_MASK 0x2 +#define RTK_TRUNK_SPA_HASH_MASK 0x1 + + +#define RTK_MAX_NUM_OF_TRUNK_HASH_VAL 16 + +typedef struct rtk_trunk_hashVal2Port_s +{ + rtk_uint8 value[RTK_MAX_NUM_OF_TRUNK_HASH_VAL]; +} rtk_trunk_hashVal2Port_t; + +typedef enum rtk_trunk_group_e +{ + TRUNK_GROUP0 = 0, + TRUNK_GROUP1, + TRUNK_GROUP2, + TRUNK_GROUP3, + TRUNK_GROUP_END +} rtk_trunk_group_t; + +typedef enum rtk_trunk_separateType_e +{ + SEPARATE_NONE = 0, + SEPARATE_FLOOD, + SEPARATE_END + +} rtk_trunk_separateType_t; + +typedef enum rtk_trunk_mode_e +{ + TRUNK_MODE_NORMAL = 0, + TRUNK_MODE_DUMB, + TRUNK_MODE_END +} rtk_trunk_mode_t; + +/* Function Name: + * rtk_trunk_port_set + * Description: + * Set trunking group available port mask + * Input: + * trk_gid - trunk group id + * pTrunk_member_portmask - Logic trunking member port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking group port mask. Each port trunking group has max 4 ports. + * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. + */ +extern rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); + +/* Function Name: + * rtk_trunk_port_get + * Description: + * Get trunking group available port mask + * Input: + * trk_gid - trunk group id + * Output: + * pTrunk_member_portmask - Logic trunking member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get 2 port trunking group. + */ +extern rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); + +/* Function Name: + * rtk_trunk_distributionAlgorithm_set + * Description: + * Set port trunking hash select sources + * Input: + * trk_gid - trunk group id + * algo_bitmask - Bitmask of the distribution algorithm + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_LA_HASHMASK - Hash algorithm selection error. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking hash algorithm sources. + * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} + * - 0b0000001: SPA + * - 0b0000010: SMAC + * - 0b0000100: DMAC + * - 0b0001000: SIP + * - 0b0010000: DIP + * - 0b0100000: TCP/UDP Source Port + * - 0b1000000: TCP/UDP Destination Port + * Example: + * - 0b0000011: SMAC & SPA + * - Note that it could be an arbitrary combination or independent set + */ +extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask); + +/* Function Name: + * rtk_trunk_distributionAlgorithm_get + * Description: + * Get port trunking hash select sources + * Input: + * trk_gid - trunk group id + * Output: + * pAlgo_bitmask - Bitmask of the distribution algorithm + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get port trunking hash algorithm sources. + */ +extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask); + +/* Function Name: + * rtk_trunk_trafficSeparate_set + * Description: + * Set the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * separateType - traffic separation setting + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_LA_HASHMASK - invalid hash mask + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +extern rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType); + +/* Function Name: + * rtk_trunk_trafficSeparate_get + * Description: + * Get the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pSeparateType - pointer separated traffic type + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +extern rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType); + + +/* Function Name: + * rtk_trunk_mode_set + * Description: + * Set the trunk mode to the specified device. + * Input: + * mode - trunk mode + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +extern rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode); + +/* Function Name: + * rtk_trunk_mode_get + * Description: + * Get the trunk mode from the specified device. + * Input: + * None + * Output: + * pMode - pointer buffer of trunk mode + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +extern rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode); + +/* Function Name: + * rtk_trunk_trafficPause_set + * Description: + * Set the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * enable - traffic pause state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * Note: + * None. + */ +extern rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable); + +/* Function Name: + * rtk_trunk_trafficPause_get + * Description: + * Get the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * Output: + * pEnable - pointer of traffic pause state. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +extern rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_trunk_hashMappingTable_set + * Description: + * Set hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * pHash2Port_array - ports associate with the hash value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist + * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk + * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +extern rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); + +/* Function Name: + * rtk_trunk_hashMappingTable_get + * Description: + * Get hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pHash2Port_array - pointer buffer of ports associate with the hash value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +extern rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); + +/* Function Name: + * rtk_trunk_portQueueEmpty_get + * Description: + * Get the port mask which all queues are empty. + * Input: + * None. + * Output: + * pEmpty_portmask - pointer empty port mask + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +extern rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask); + +#endif /* __RTK_API_TRUNK_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/vlan.h b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/vlan.h new file mode 100755 index 00000000..8569fc0d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/include/vlan.h @@ -0,0 +1,892 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Trap module high-layer VLAN defination + * + */ + +#ifndef __RTK_API_VLAN_H__ +#define __RTK_API_VLAN_H__ + + +/* + * Data Type Declaration + */ +#define RTK_MAX_NUM_OF_PROTO_TYPE 0xFFFF +#define RTK_MAX_NUM_OF_MSTI 0xF +#define RTK_FID_MAX 0xF + +typedef struct rtk_vlan_cfg_s +{ + rtk_portmask_t mbr; + rtk_portmask_t untag; + rtk_uint16 ivl_en; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; +}rtk_vlan_cfg_t; + +typedef struct rtk_vlan_mbrcfg_s +{ + rtk_uint16 evid; + rtk_portmask_t mbr; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; +}rtk_vlan_mbrcfg_t; + +typedef rtk_uint32 rtk_stp_msti_id_t; /* MSTI ID */ + +typedef enum rtk_stp_state_e +{ + STP_STATE_DISABLED = 0, + STP_STATE_BLOCKING, + STP_STATE_LEARNING, + STP_STATE_FORWARDING, + STP_STATE_END +} rtk_stp_state_t; + +typedef rtk_uint32 rtk_vlan_proto_type_t; /* protocol and port based VLAN protocol type */ + + +typedef enum rtk_vlan_acceptFrameType_e +{ + ACCEPT_FRAME_TYPE_ALL = 0, /* untagged, priority-tagged and tagged */ + ACCEPT_FRAME_TYPE_TAG_ONLY, /* tagged */ + ACCEPT_FRAME_TYPE_UNTAG_ONLY, /* untagged and priority-tagged */ + ACCEPT_FRAME_TYPE_END +} rtk_vlan_acceptFrameType_t; + + +/* frame type of protocol vlan - reference 802.1v standard */ +typedef enum rtk_vlan_protoVlan_frameType_e +{ + FRAME_TYPE_ETHERNET = 0, + FRAME_TYPE_LLCOTHER, + FRAME_TYPE_RFC1042, + FRAME_TYPE_END +} rtk_vlan_protoVlan_frameType_t; + +/* Protocol-and-port-based Vlan structure */ +typedef struct rtk_vlan_protoAndPortInfo_s +{ + rtk_uint32 proto_type; + rtk_vlan_protoVlan_frameType_t frame_type; + rtk_vlan_t cvid; + rtk_pri_t cpri; +}rtk_vlan_protoAndPortInfo_t; + +/* tagged mode of VLAN - reference realtek private specification */ +typedef enum rtk_vlan_tagMode_e +{ + VLAN_TAG_MODE_ORIGINAL = 0, + VLAN_TAG_MODE_KEEP_FORMAT, + VLAN_TAG_MODE_PRI, + VLAN_TAG_MODE_REAL_KEEP_FORMAT, + VLAN_TAG_MODE_END +} rtk_vlan_tagMode_t; + +typedef enum rtk_vlan_resVidAction_e +{ + RESVID_ACTION_UNTAG = 0, + RESVID_ACTION_TAG, + RESVID_ACTION_END +} +rtk_vlan_resVidAction_t; + +/* Function Name: + * rtk_vlan_init + * Description: + * Initialize VLAN. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * VLAN is disabled by default. User has to call this API to enable VLAN before + * using it. And It will set a default VLAN(vid 1) including all ports and set + * all ports PVID to the default VLAN. + */ +extern rtk_api_ret_t rtk_vlan_init(void); + +/* Function Name: + * rtk_vlan_set + * Description: + * Set a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * pVlanCfg - VLAN Configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_FID - Invalid FID. + * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); + +/* Function Name: + * rtk_vlan_get + * Description: + * Get a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * Output: + * pVlanCfg - VLAN Configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); + +/* Function Name: + * rtk_vlan_egrFilterEnable_set + * Description: + * Set VLAN egress filter. + * Input: + * egrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter); + +/* Function Name: + * rtk_vlan_egrFilterEnable_get + * Description: + * Get VLAN egress filter. + * Input: + * pEgrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter); + +/* Function Name: + * rtk_vlan_mbrCfg_set + * Description: + * Set a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * pMbrcfg - VLAN member Configuration. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Set a VLAN Member Configuration entry by index. + */ +extern rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); + +/* Function Name: + * rtk_vlan_mbrCfg_get + * Description: + * Get a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * Output: + * pMbrcfg - VLAN member Configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Get a VLAN Member Configuration entry by index. + */ +extern rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); + +/* Function Name: + * rtk_vlan_portPvid_set + * Description: + * Set port to specified VLAN ID(PVID). + * Input: + * port - Port id. + * pvid - Specified VLAN ID. + * priority - 802.1p priority for the PVID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API is used for Port-based VLAN. The untagged frame received from the + * port will be classified to the specified VLAN and assigned to the specified priority. + */ +extern rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority); + +/* Function Name: + * rtk_vlan_portPvid_get + * Description: + * Get VLAN ID(PVID) on specified port. + * Input: + * port - Port id. + * Output: + * pPvid - Specified VLAN ID. + * pPriority - 802.1p priority for the PVID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the PVID and 802.1p priority for the PVID of Port-based VLAN. + */ +extern rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority); + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_set + * Description: + * Set VLAN ingress for each port. + * Input: + * port - Port id. + * igr_filter - VLAN ingress function enable status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member + * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. + */ +extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter); + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_get + * Description: + * Get VLAN Ingress Filter + * Input: + * port - Port id. + * Output: + * pIgr_filter - VLAN ingress function enable status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter status. + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter); + +/* Function Name: + * rtk_vlan_portAcceptFrameType_set + * Description: + * Set VLAN accept_frame_type + * Input: + * port - Port id. + * accept_frame_type - accept frame type + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. + * Note: + * The API is used for checking 802.1Q tagged frames. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type); + +/* Function Name: + * rtk_vlan_portAcceptFrameType_get + * Description: + * Get VLAN accept_frame_type + * Input: + * port - Port id. + * Output: + * pAccept_frame_type - accept frame type + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type); + +/* Function Name: + * rtk_vlan_tagMode_set + * Description: + * Set CVLAN egress tag mode + * Input: + * port - Port id. + * tag_mode - The egress tag mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +extern rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode); + +/* Function Name: + * rtk_vlan_tagMode_get + * Description: + * Get CVLAN egress tag mode + * Input: + * port - Port id. + * Output: + * pTag_mode - The egress tag mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +extern rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode); + +/* Function Name: + * rtk_vlan_transparent_set + * Description: + * Set VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_transparent_get + * Description: + * Get VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_keep_set + * Description: + * Set VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_keep_get + * Description: + * Get VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_stg_set + * Description: + * Set spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * stg - spanning tree group instance. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can set spanning tree group instance of the vlan to the specified device. + */ +extern rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg); + +/* Function Name: + * rtk_vlan_stg_get + * Description: + * Get spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * Output: + * pStg - spanning tree group instance. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can get spanning tree group instance of the vlan to the specified device. + */ +extern rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_add + * Description: + * Add the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * pInfo - Protocol and port based VLAN configuration information. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_TBL_FULL - Table is full. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_get + * Description: + * Get the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * pInfo - Protocol and port based VLAN configuration information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_del + * Description: + * Delete the protocol-and-port-based vlan from the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_delAll + * Description: + * Delete all protocol-and-port-based vlans from the specified port of device. + * Input: + * port - Port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * Delete all flow table protocol-and-port-based vlan entries. + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port); + +/* Function Name: + * rtk_vlan_portFid_set + * Description: + * Set port-based filtering database + * Input: + * port - Port id. + * enable - ebable port-based FID + * fid - Specified filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based filtering database. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +extern rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid); + +/* Function Name: + * rtk_vlan_portFid_get + * Description: + * Get port-based filtering database + * Input: + * port - Port id. + * Output: + * pEnable - ebable port-based FID + * pFid - Specified filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based filtering database status. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +extern rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid); + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_set + * Description: + * Set Untag DSCP priority assign + * Input: + * enable - state of Untag DSCP priority assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_get + * Description: + * Get Untag DSCP priority assign + * Input: + * None + * Output: + * pEnable - state of Untag DSCP priority assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable); + + +/*Spanning Tree*/ +/* Function Name: + * rtk_stp_mstpState_set + * Description: + * Configure spanning tree state per each port. + * Input: + * port - Port id + * msti - Multiple spanning tree instance. + * stp_state - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * RT_ERR_MSTP_STATE - Invalid STP state. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +extern rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state); + +/* Function Name: + * rtk_stp_mstpState_get + * Description: + * Get spanning tree state per each port. + * Input: + * port - Port id. + * msti - Multiple spanning tree instance. + * Output: + * pStp_state - Spanning tree state for msti + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +extern rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state); + +/* Function Name: + * rtk_vlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); + +/* Function Name: + * rtk_vlan_reservedVidAction_set + * Description: + * Set Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * action_vid0 - Action for VID 0. + * action_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095); + +/* Function Name: + * rtk_vlan_reservedVidAction_get + * Description: + * Get Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * pAction_vid0 - Action for VID 0. + * pAction_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095); + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_set + * Description: + * Set Real keep 1p remarking feature + * Input: + * enabled - State of 1p remarking at real keep packet + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_get + * Description: + * Get Real keep 1p remarking feature + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_vlan_reset + * Description: + * Reset VLAN + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reset(void); + +#endif /* __RTK_API_VLAN_H__ */ diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/interrupt.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/interrupt.c new file mode 100755 index 00000000..165ee417 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/interrupt.c @@ -0,0 +1,434 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Interrupt module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_int_polarity_set + * Description: + * Set interrupt polarity configuration. + * Input: + * type - Interruptpolarity type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set interrupt polarity configuration. + */ +rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(type >= INT_POLAR_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicInterruptPolarity(type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_polarity_get + * Description: + * Get interrupt polarity configuration. + * Input: + * None + * Output: + * pType - Interruptpolarity type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get interrupt polarity configuration. + */ +rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicInterruptPolarity(pType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_control_set + * Description: + * Set interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set interrupt status configuration. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS + * - INT_TYPE_METER_EXCEED + * - INT_TYPE_LEARN_LIMIT + * - INT_TYPE_LINK_SPEED + * - INT_TYPE_CONGEST + * - INT_TYPE_GREEN_FEATURE + * - INT_TYPE_LOOP_DETECT + * - INT_TYPE_8051, + * - INT_TYPE_CABLE_DIAG, + * - INT_TYPE_ACL, + * - INT_TYPE_SLIENT + */ +rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 mask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= INT_TYPE_END) + return RT_ERR_INPUT; + + if (type == INT_TYPE_RESERVED) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + mask = mask | (1<value[0] & (0x0001 << INT_TYPE_RESERVED)) + return RT_ERR_INPUT; + + if(pStatusMask->value[0] >= (0x0001 << INT_TYPE_END)) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicInterruptStatus((rtk_uint32)pStatusMask->value[0]))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_status_get + * Description: + * Get interrupt trigger status. + * Input: + * None + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) + * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) + * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) + * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) + * - INT_TYPE_CONGEST (value[0] (Bit4)) + * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) + * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) + * - INT_TYPE_8051 (value[0] (Bit7)) + * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) + * - INT_TYPE_ACL (value[0] (Bit9)) + * - INT_TYPE_SLIENT (value[0] (Bit11)) + * + */ +rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask) +{ + rtk_api_ret_t retVal; + rtk_uint32 ims_mask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pStatusMask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicInterruptStatus(&ims_mask)) != RT_ERR_OK) + return retVal; + + pStatusMask->value[0] = (ims_mask & 0x00000FFF); + return RT_ERR_OK; +} + +#define ADV_NOT_SUPPORT (0xFFFF) +static rtk_api_ret_t _rtk_int_Advidx_get(rtk_int_advType_t adv_type, rtk_uint32 *pAsic_idx) +{ + rtk_uint32 asic_idx[ADV_END] = + { + INTRST_L2_LEARN, + INTRST_SPEED_CHANGE, + INTRST_SPECIAL_CONGESTION, + INTRST_PORT_LINKDOWN, + INTRST_PORT_LINKUP, + ADV_NOT_SUPPORT, + INTRST_RLDP_LOOPED, + INTRST_RLDP_RELEASED, + }; + + if(adv_type >= ADV_END) + return RT_ERR_INPUT; + + if(asic_idx[adv_type] == ADV_NOT_SUPPORT) + return RT_ERR_CHIP_NOT_SUPPORTED; + + *pAsic_idx = asic_idx[adv_type]; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_advanceInfo_get + * Description: + * Get interrupt advanced information. + * Input: + * adv_type - Advanced interrupt type. + * Output: + * info - Information per type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get advanced information when interrupt happened. + * The status will be cleared after execute this API. + */ +rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t *pInfo) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + rtk_uint32 intAdvType; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(adv_type >= ADV_END) + return RT_ERR_INPUT; + + if(NULL == pInfo) + return RT_ERR_NULL_POINTER; + + if(adv_type != ADV_METER_EXCEED_MASK) + { + if((retVal = _rtk_int_Advidx_get(adv_type, &intAdvType)) != RT_ERR_OK) + return retVal; + } + + switch(adv_type) + { + case ADV_L2_LEARN_PORT_MASK: + /* Get physical portmask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) + return retVal; + + /* Translate to logical portmask */ + if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) + return retVal; + + /* Get system learn */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_SYS_LEARN, &data)) != RT_ERR_OK) + return retVal; + + /* Clear system learn */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_SYS_LEARN, 0x0001)) != RT_ERR_OK) + return retVal; + + pInfo->systemLearnOver = data; + break; + case ADV_SPEED_CHANGE_PORT_MASK: + case ADV_SPECIAL_CONGESTION_PORT_MASK: + case ADV_PORT_LINKDOWN_PORT_MASK: + case ADV_PORT_LINKUP_PORT_MASK: + case ADV_RLDP_LOOPED: + case ADV_RLDP_RELEASED: + /* Get physical portmask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) + return retVal; + + /* Translate to logical portmask */ + if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) + return retVal; + + break; + case ADV_METER_EXCEED_MASK: + /* Get Meter Mask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER0_15, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER0_15, 0xFFFF)) != RT_ERR_OK) + return retVal; + + pInfo->meterMask = data & 0xFFFF; + + /* Get Meter Mask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER16_31, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER16_31, 0xFFFF)) != RT_ERR_OK) + return retVal; + + pInfo->meterMask = pInfo->meterMask | ((data << 16) & 0xFFFF0000); + + break; + default: + return RT_ERR_INPUT; + } + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/l2.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/l2.c new file mode 100755 index 00000000..feff0b24 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/l2.c @@ -0,0 +1,2911 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in L2 module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* Function Name: + * rtk_l2_init + * Description: + * Initialize l2 module of the specified device. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Initialize l2 module before calling any l2 APIs. + */ +rtk_api_ret_t rtk_l2_init(void) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) + return retVal; + + /*Enable CAM Usage*/ + if ((retVal = rtl8367c_setAsicLutCamTbUsage(ENABLED)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutAgeTimerSpeed(6,2)) != RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_LOG_PORT(port) + { + if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), rtk_switch_maxLutAddrNumber_get())) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_l2_addr_add + * Description: + * Add LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * pL2_data - Unicast entry parameter + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address already existed in LUT, it will udpate the status of the entry. + * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries + * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pMac == NULL) || (pMac->octet[0] & 0x1)) + return RT_ERR_MAC; + + if(pL2_data == NULL) + return RT_ERR_MAC; + + RTK_CHK_PORT_VALID(pL2_data->port); + + if (pL2_data->ivl >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->cvid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if (pL2_data->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if (pL2_data->is_static>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->sa_block>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->da_block>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->auth>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->efid> RTL8367C_EFIDMAX) + return RT_ERR_INPUT; + + if (pL2_data->priority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + if (pL2_data->sa_pri_en >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->fwd_pri_en >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.fid = pL2_data->fid; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.efid = pL2_data->efid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal ) + { + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); + l2Table.nosalearn = pL2_data->is_static; + l2Table.sa_block = pL2_data->sa_block; + l2Table.da_block = pL2_data->da_block; + l2Table.l3lookup = 0; + l2Table.auth = pL2_data->auth; + l2Table.age = 6; + l2Table.lut_pri = pL2_data->priority; + l2Table.sa_en = pL2_data->sa_pri_en; + l2Table.fwd_en = pL2_data->fwd_pri_en; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pL2_data->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); + l2Table.nosalearn = pL2_data->is_static; + l2Table.sa_block = pL2_data->sa_block; + l2Table.da_block = pL2_data->da_block; + l2Table.l3lookup = 0; + l2Table.auth = pL2_data->auth; + l2Table.age = 6; + l2Table.lut_pri = pL2_data->priority; + l2Table.sa_en = pL2_data->sa_pri_en; + l2Table.fwd_en = pL2_data->fwd_pri_en; + + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pL2_data->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_l2_addr_get + * Description: + * Get LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address existed in LUT, it will return the port and fid where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pMac == NULL) || (pMac->octet[0] & 0x1)) + return RT_ERR_MAC; + + if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + method = LUTREADMETHOD_MAC; + + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + memcpy(pL2_data->mac.octet, pMac->octet,ETHER_ADDR_LEN); + pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); + pL2_data->fid = l2Table.fid; + pL2_data->efid = l2Table.efid; + pL2_data->ivl = l2Table.ivl_svl; + pL2_data->cvid = l2Table.cvid_fid; + pL2_data->is_static = l2Table.nosalearn; + pL2_data->auth = l2Table.auth; + pL2_data->sa_block = l2Table.sa_block; + pL2_data->da_block = l2Table.da_block; + pL2_data->priority = l2Table.lut_pri; + pL2_data->sa_pri_en = l2Table.sa_en; + pL2_data->fwd_pri_en= l2Table.fwd_en; + pL2_data->address = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_addr_next_get + * Description: + * Get Next LUT unicast entry. + * Input: + * read_method - The reading method. + * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA + * pAddress - The Address ID + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next unicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all entries is LUT. + */ +rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pL2_data == NULL) || (pAddress == NULL)) + return RT_ERR_MAC; + + if(read_method == READMETHOD_NEXT_L2UC) + method = LUTREADMETHOD_NEXT_L2UC; + else if(read_method == READMETHOD_NEXT_L2UCSPA) + method = LUTREADMETHOD_NEXT_L2UCSPA; + else + return RT_ERR_INPUT; + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + if(read_method == READMETHOD_NEXT_L2UCSPA) + l2Table.spa = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + memcpy(pL2_data->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); + pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); + pL2_data->fid = l2Table.fid; + pL2_data->efid = l2Table.efid; + pL2_data->ivl = l2Table.ivl_svl; + pL2_data->cvid = l2Table.cvid_fid; + pL2_data->is_static = l2Table.nosalearn; + pL2_data->auth = l2Table.auth; + pL2_data->sa_block = l2Table.sa_block; + pL2_data->da_block = l2Table.da_block; + pL2_data->priority = l2Table.lut_pri; + pL2_data->sa_pri_en = l2Table.sa_en; + pL2_data->fwd_pri_en= l2Table.fwd_en; + pL2_data->address = l2Table.address; + + *pAddress = l2Table.address; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_l2_addr_del + * Description: + * Delete LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * fid - Filtering database + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pMac == NULL) || (pMac->octet[0] & 0x1)) + return RT_ERR_MAC; + + if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + l2Table.spa = 0; + l2Table.nosalearn = 0; + l2Table.sa_block = 0; + l2Table.da_block = 0; + l2Table.auth = 0; + l2Table.age = 0; + l2Table.lut_pri = 0; + l2Table.sa_en = 0; + l2Table.fwd_en = 0; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pL2_data->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_mcastAddr_add + * Description: + * Add LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address already existed in the LUT, it will udpate the + * port mask of the entry. Otherwise, it will find an empty or asic auto learned + * entry to write. If all the entries with the same hash value can't be replaced, + * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMcastAddr) + return RT_ERR_NULL_POINTER; + + /* must be L2 multicast address */ + if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) + return RT_ERR_MAC; + + RTK_CHK_PORTMASK_VALID(&pMcastAddr->portmask); + + if(pMcastAddr->ivl == 1) + { + if (pMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + } + else if(pMcastAddr->ivl == 0) + { + if (pMcastAddr->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + } + else + return RT_ERR_INPUT; + + if(pMcastAddr->fwd_pri_en >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pMcastAddr->priority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + /* Get physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(&pMcastAddr->portmask, &pmask)) != RT_ERR_OK) + return retVal; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 0; + l2Table.lut_pri = pMcastAddr->priority; + l2Table.fwd_en = pMcastAddr->fwd_pri_en; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 0; + l2Table.lut_pri = pMcastAddr->priority; + l2Table.fwd_en = pMcastAddr->fwd_pri_en; + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_l2_mcastAddr_get + * Description: + * Get LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address existed in the LUT, it will return the port where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMcastAddr) + return RT_ERR_NULL_POINTER; + + /* must be L2 multicast address */ + if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) + return RT_ERR_MAC; + + if(pMcastAddr->ivl == 1) + { + if (pMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + } + else if(pMcastAddr->ivl == 0) + { + if (pMcastAddr->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + } + else + return RT_ERR_INPUT; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + method = LUTREADMETHOD_MAC; + + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->priority = l2Table.lut_pri; + pMcastAddr->fwd_pri_en = l2Table.fwd_en; + pMcastAddr->igmp_asic = l2Table.igmp_asic; + pMcastAddr->igmp_index = l2Table.igmpidx; + pMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_mcastAddr_next_get + * Description: + * Get Next L2 Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next L2 multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all multicast entries is LUT. + */ +rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pAddress == NULL) || (pMcastAddr == NULL)) + return RT_ERR_INPUT; + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L2MC, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + memcpy(pMcastAddr->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); + pMcastAddr->ivl = l2Table.ivl_svl; + + if(pMcastAddr->ivl) + pMcastAddr->vid = l2Table.cvid_fid; + else + pMcastAddr->fid = l2Table.cvid_fid; + + pMcastAddr->priority = l2Table.lut_pri; + pMcastAddr->fwd_pri_en = l2Table.fwd_en; + pMcastAddr->igmp_asic = l2Table.igmp_asic; + pMcastAddr->igmp_index = l2Table.igmpidx; + pMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + *pAddress = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_mcastAddr_del + * Description: + * Delete LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMcastAddr) + return RT_ERR_NULL_POINTER; + + /* must be L2 multicast address */ + if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) + return RT_ERR_MAC; + + if(pMcastAddr->ivl == 1) + { + if (pMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + } + else if(pMcastAddr->ivl == 0) + { + if (pMcastAddr->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + } + else + return RT_ERR_INPUT; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + l2Table.mbr = 0; + l2Table.nosalearn = 0; + l2Table.sa_block = 0; + l2Table.l3lookup = 0; + l2Table.lut_pri = 0; + l2Table.fwd_en = 0; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ipMcastAddr_add + * Description: + * Add Lut IP multicast entry + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user + * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to + * forward IP multicast frame directly without flooding. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpMcastAddr) + return RT_ERR_NULL_POINTER; + + /* check port mask */ + RTK_CHK_PORTMASK_VALID(&pIpMcastAddr->portmask); + + if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + if(pIpMcastAddr->fwd_pri_en >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pIpMcastAddr->priority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(&pIpMcastAddr->portmask, &pmask)) != RT_ERR_OK) + return retVal; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + l2Table.lut_pri = pIpMcastAddr->priority; + l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + l2Table.lut_pri = pIpMcastAddr->priority; + l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + + } + else + return retVal; + +} + +/* Function Name: + * rtk_l2_ipMcastAddr_get + * Description: + * Get LUT IP multicast entry. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Lut table of IP multicast entry. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpMcastAddr) + return RT_ERR_NULL_POINTER; + + if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + method = LUTREADMETHOD_MAC; + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->priority = l2Table.lut_pri; + pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; + pIpMcastAddr->igmp_asic = l2Table.igmp_asic; + pIpMcastAddr->igmp_index = l2Table.igmpidx; + pIpMcastAddr->address = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastAddr_next_get + * Description: + * Get Next IP Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pAddress == NULL) || (pIpMcastAddr == NULL) ) + return RT_ERR_INPUT; + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + do + { + if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + }while(l2Table.l3vidlookup == 1); + + pIpMcastAddr->sip = l2Table.sip; + pIpMcastAddr->dip = l2Table.dip; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->priority = l2Table.lut_pri; + pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; + pIpMcastAddr->igmp_asic = l2Table.igmp_asic; + pIpMcastAddr->igmp_index = l2Table.igmpidx; + pIpMcastAddr->address = l2Table.address; + *pAddress = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastAddr_del + * Description: + * Delete a ip multicast address entry from the specified device. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can delete a IP multicast address entry from the specified device. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if (pIpMcastAddr == NULL) + return RT_ERR_INPUT; + + if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.mbr = 0; + l2Table.nosalearn = 0; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + l2Table.lut_pri = 0; + l2Table.fwd_en = 0; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_add + * Description: + * Add Lut IP multicast+VID entry + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpVidMcastAddr) + return RT_ERR_NULL_POINTER; + + /* check port mask */ + RTK_CHK_PORTMASK_VALID(&pIpVidMcastAddr->portmask); + + if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(&pIpVidMcastAddr->portmask, &pmask)) != RT_ERR_OK) + return retVal; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_get + * Description: + * Get LUT IP multicast+VID entry. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpVidMcastAddr) + return RT_ERR_NULL_POINTER; + + if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + method = LUTREADMETHOD_MAC; + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_next_get + * Description: + * Get Next IP Multicast+VID entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pAddress == NULL) || (pIpVidMcastAddr == NULL)) + return RT_ERR_INPUT; + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + do + { + if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + }while(l2Table.l3vidlookup == 0); + + pIpVidMcastAddr->sip = l2Table.sip; + pIpVidMcastAddr->dip = l2Table.dip; + pIpVidMcastAddr->vid = l2Table.l3_vid; + pIpVidMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + *pAddress = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_del + * Description: + * Delete a ip multicast+VID address entry from the specified device. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpVidMcastAddr) + return RT_ERR_NULL_POINTER; + + if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.mbr= 0; + l2Table.nosalearn = 0; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ucastAddr_flush + * Description: + * Flush L2 mac address by type in the specified device (both dynamic and static). + * Input: + * pConfig - flush configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * flushByVid - 1: Flush by VID, 0: Don't flush by VID + * vid - VID (0 ~ 4095) + * flushByFid - 1: Flush by FID, 0: Don't flush by FID + * fid - FID (0 ~ 15) + * flushByPort - 1: Flush by Port, 0: Don't flush by Port + * port - Port ID + * flushByMac - Not Supported + * ucastAddr - Not Supported + * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries + * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. + */ +rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pConfig == NULL) + return RT_ERR_NULL_POINTER; + + if(pConfig->flushByVid >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushByFid >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushByPort >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushByMac >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushStaticAddr >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushAddrOnAllPorts >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if(pConfig->fid > RTL8367C_FIDMAX) + return RT_ERR_INPUT; + + /* check port valid */ + RTK_CHK_PORT_VALID(pConfig->port); + + if(pConfig->flushByVid == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_VID)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushVid(pConfig->vid)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) + return retVal; + + if(pConfig->flushAddrOnAllPorts == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) + return retVal; + } + else if(pConfig->flushByPort == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + } + else if(pConfig->flushByFid == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_FID)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushFid(pConfig->fid)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) + return retVal; + + if(pConfig->flushAddrOnAllPorts == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) + return retVal; + } + else if(pConfig->flushByPort == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + } + else if(pConfig->flushByPort == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_PORT)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) + return retVal; + } + else if(pConfig->flushByMac == ENABLED) + { + /* Should use API "rtk_l2_addr_del" to remove a specified entry*/ + return RT_ERR_CHIP_NOT_SUPPORTED; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_table_clear + * Description: + * Flush all static & dynamic entries in LUT. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_l2_table_clear(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicLutFlushAll()) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_table_clearStatus_get + * Description: + * Get table clear status + * Input: + * None + * Output: + * pStatus - Clear status, 1:Busy, 0:finish + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pStatus) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutFlushAllStatus((rtk_uint32 *)pStatus)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_set + * Description: + * Set HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * enable - link down flush status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicLutLinkDownForceAging(enable)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_get + * Description: + * Get HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * Output: + * pEnable - link down flush status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLinkDownForceAging(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_agingEnable_set + * Description: + * Set L2 LUT aging status per port setting. + * Input: + * port - Port id. + * enable - Aging status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can be used to set L2 LUT aging status per port. + */ +rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(enable == 1) + enable = 0; + else + enable = 1; + + if ((retVal = rtl8367c_setAsicLutDisableAging(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_agingEnable_get + * Description: + * Get L2 LUT aging status per port setting. + * Input: + * port - Port id. + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can be used to get L2 LUT aging function per port. + */ +rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutDisableAging(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + if(*pEnable == 1) + *pEnable = 0; + else + *pEnable = 1; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCnt_set + * Description: + * Set per-Port auto learning limit number + * Input: + * port - Port id. + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set per-port ASIC auto learning limit number from 0(disable learning) + * to 2112. + */ +rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), mac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCnt_get + * Description: + * Get per-Port auto learning limit number + * Input: + * port - Port id. + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning limit number. + */ +rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pMac_cnt) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_set + * Description: + * Set System auto learning limit number + * Input: + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set system ASIC auto learning limit number from 0(disable learning) + * to 2112. + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + if ((retVal = rtl8367c_setAsicSystemLutLearnLimitNo(mac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_get + * Description: + * Get System auto learning limit number + * Input: + * None + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get system ASIC auto learning limit number. + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMac_cnt) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSystemLutLearnLimitNo(pMac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCntAction_set + * Description: + * Configure auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) + data = 1; + else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) + data = 0; + else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) + data = 2; + else + return RT_ERR_NOT_ALLOWED; + + if ((retVal = rtl8367c_setAsicLutLearnOverAct(data)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCntAction_get + * Description: + * Get auto learn over limit number action. + * Input: + * port - Port id. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 action; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLearnOverAct(&action)) != RT_ERR_OK) + return retVal; + + if ( 1 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_DROP; + else if ( 0 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; + else if ( 2 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; + else + *pAction = action; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_set + * Description: + * Configure system auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) + data = 1; + else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) + data = 0; + else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) + data = 2; + else + return RT_ERR_NOT_ALLOWED; + + if ((retVal = rtl8367c_setAsicSystemLutLearnOverAct(data)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_get + * Description: + * Get system auto learn over limit number action. + * Input: + * None. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 action; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSystemLutLearnOverAct(&action)) != RT_ERR_OK) + return retVal; + + if ( 1 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_DROP; + else if ( 0 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; + else if ( 2 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; + else + *pAction = action; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_set + * Description: + * Configure system auto learn portmask + * Input: + * pPortmask - Port Mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + /* Check port mask */ + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicSystemLutLearnPortMask(pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_get + * Description: + * get system auto learn portmask + * Input: + * None + * Output: + * pPortmask - Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer. + * Note: + * + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSystemLutLearnPortMask(&pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_learningCnt_get + * Description: + * Get per-Port current auto learning number + * Input: + * port - Port id. + * Output: + * pMac_cnt - ASIC auto learning entries number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning number + */ +rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pMac_cnt) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLearnNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_floodPortMask_set + * Description: + * Set flooding portmask + * Input: + * type - flooding type. + * pFlood_portmask - flooding porkmask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (floood_type >= FLOOD_END) + return RT_ERR_INPUT; + + /* check port valid */ + RTK_CHK_PORTMASK_VALID(pFlood_portmask); + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(pFlood_portmask, &pmask))!=RT_ERR_OK) + return retVal; + + switch (floood_type) + { + case FLOOD_UNKNOWNDA: + if ((retVal = rtl8367c_setAsicPortUnknownDaFloodingPortmask(pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_UNKNOWNMC: + if ((retVal = rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_BC: + if ((retVal = rtl8367c_setAsicPortBcastFloodingPortmask(pmask)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtk_l2_floodPortMask_get + * Description: + * Get flooding portmask + * Input: + * type - flooding type. + * Output: + * pFlood_portmask - flooding porkmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (floood_type >= FLOOD_END) + return RT_ERR_INPUT; + + if(NULL == pFlood_portmask) + return RT_ERR_NULL_POINTER; + + switch (floood_type) + { + case FLOOD_UNKNOWNDA: + if ((retVal = rtl8367c_getAsicPortUnknownDaFloodingPortmask(&pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_UNKNOWNMC: + if ((retVal = rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(&pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_BC: + if ((retVal = rtl8367c_getAsicPortBcastFloodingPortmask(&pmask)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pFlood_portmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_localPktPermit_set + * Description: + * Set permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * permit - permittion status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid permit value. + * Note: + * This API is setted to permit frame if its source port is equal to destination port. + */ +rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (permit >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortBlockSpa(rtk_switch_port_L2P_get(port), permit)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_localPktPermit_get + * Description: + * Get permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * Output: + * pPermit - permittion status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API is to get permittion status for frames if its source port is equal to destination port. + */ +rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPermit) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortBlockSpa(rtk_switch_port_L2P_get(port), pPermit)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_aging_set + * Description: + * Set LUT agging out speed + * Input: + * aging_time - Agging out time. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can set LUT agging out period for each entry and the range is from 45s to 458s. + */ +rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time) +{ + rtk_uint32 i; + CONST_T rtk_uint32 agePara[10][3] = { + {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, + {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (aging_time>agePara[9][0]) + return RT_ERR_OUT_OF_RANGE; + + for (i = 0; i<10; i++) + { + if (aging_time<=agePara[i][0]) + { + return rtl8367c_setAsicLutAgeTimerSpeed(agePara[i][2], agePara[i][1]); + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_aging_get + * Description: + * Get LUT agging out time + * Input: + * None + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get LUT agging out period for each entry. + */ +rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time) +{ + rtk_api_ret_t retVal; + rtk_uint32 i,time, speed; + CONST_T rtk_uint32 agePara[10][3] = { + {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, + {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAging_time) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutAgeTimerSpeed(&time, &speed)) != RT_ERR_OK) + return retVal; + + for (i = 0; i<10; i++) + { + if (time==agePara[i][2]&&speed==agePara[i][1]) + { + *pAging_time = agePara[i][0]; + return RT_ERR_OK; + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_set + * Description: + * Set Lut IP multicast lookup function + * Input: + * type - Lookup type for IPMC packet. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * LOOKUP_MAC - Lookup by MAC address + * LOOKUP_IP - Lookup by IP address + * LOOKUP_IP_VID - Lookup by IP address & VLAN ID + */ +rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(type == LOOKUP_MAC) + { + if((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) + return retVal; + } + else if(type == LOOKUP_IP) + { + if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(DISABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + } + else if(type == LOOKUP_IP_VID) + { + if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(ENABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_get + * Description: + * Get Lut IP multicast lookup function + * Input: + * None. + * Output: + * pType - Lookup type for IPMC packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType) +{ + rtk_api_ret_t retVal; + rtk_uint32 enabled, vid_lookup; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicLutIpMulticastLookup(&enabled)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicLutIpMulticastVidLookup(&vid_lookup))!=RT_ERR_OK) + return retVal; + + if(enabled == ENABLED) + { + if(vid_lookup == ENABLED) + *pType = LOOKUP_IP_VID; + else + *pType = LOOKUP_IP; + } + else + *pType = LOOKUP_MAC; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_set + * Description: + * Set IPMC packet forward to rounter port also or not + * Input: + * enabled - 1: Inlcude router port, 0, exclude router port + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if((retVal = rtl8367c_setAsicLutIpmcFwdRouterPort(enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_get + * Description: + * Get IPMC packet forward to rounter port also or not + * Input: + * None. + * Output: + * pEnabled - 1: Inlcude router port, 0, exclude router port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicLutIpmcFwdRouterPort(pEnabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_add + * Description: + * Add an IP Multicast entry to group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * pPortmask - portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Add an entry to IP Multicast Group table. + */ +rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) +{ + rtk_uint32 empty_idx = 0xFFFF; + rtk_int32 index; + ipaddr_t group_addr; + rtk_uint32 group_vid; + rtk_uint32 pmask; + rtk_uint32 valid; + rtk_uint32 physicalPortmask; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if((ip_addr & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &physicalPortmask))!=RT_ERR_OK) + return retVal; + + for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) + { + if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) + return retVal; + + if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) + { + if(pmask != physicalPortmask) + { + pmask = physicalPortmask; + if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, ip_addr, vid, pmask, valid))!=RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; + } + + if( (valid == DISABLED) && (empty_idx == 0xFFFF) ) /* Unused */ + empty_idx = (rtk_uint32)index; + } + + if(empty_idx == 0xFFFF) + return RT_ERR_TBL_FULL; + + pmask = physicalPortmask; + if ((retVal = rtl8367c_setAsicLutIPMCGroup(empty_idx, ip_addr, vid, pmask, ENABLED))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_del + * Description: + * Delete an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid) +{ + rtk_int32 index; + ipaddr_t group_addr; + rtk_uint32 group_vid; + rtk_uint32 pmask; + rtk_uint32 valid; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if((ip_addr & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) + { + if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) + return retVal; + + if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) + { + group_addr = 0xE0000000; + group_vid = 0; + pmask = 0; + if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, group_addr, group_vid, pmask, DISABLED))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_get + * Description: + * get an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * pPortmask - member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) +{ + rtk_int32 index; + ipaddr_t group_addr; + rtk_uint32 group_vid; + rtk_uint32 valid; + rtk_uint32 pmask; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((ip_addr & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) + { + if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) + return retVal; + + if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) + { + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_entry_get + * Description: + * Get LUT unicast entry. + * Input: + * pL2_entry - Index field in the structure. + * Output: + * pL2_entry - other fields such as MAC, port, age... + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API is used to get address by index from 0~2111. + */ +rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (pL2_entry->index >= rtk_switch_maxLutAddrNumber_get()) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.address= pL2_entry->index; + method = LUTREADMETHOD_ADDRESS; + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + if ((pL2_entry->index>0x800)&&(l2Table.lookup_hit==0)) + return RT_ERR_L2_EMPTY_ENTRY; + + if(l2Table.l3lookup) + { + if(l2Table.l3vidlookup) + { + memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->sip = l2Table.sip; + pL2_entry->dip = l2Table.dip; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->fid = 0; + pL2_entry->age = 0; + pL2_entry->auth = 0; + pL2_entry->sa_block = 0; + pL2_entry->is_ipvidmul = 1; + pL2_entry->l3_vid = l2Table.l3_vid; + } + else + { + memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->sip = l2Table.sip; + pL2_entry->dip = l2Table.dip; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->fid = 0; + pL2_entry->age = 0; + pL2_entry->auth = 0; + pL2_entry->sa_block = 0; + pL2_entry->is_ipvidmul = 0; + pL2_entry->l3_vid = 0; + } + } + else if(l2Table.mac.octet[0]&0x01) + { + memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); + memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); + pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; + pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; + pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; + pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; + pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; + pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->ivl = l2Table.ivl_svl; + if(l2Table.ivl_svl == 1) /* IVL */ + { + pL2_entry->cvid = l2Table.cvid_fid; + pL2_entry->fid = 0; + } + else /* SVL*/ + { + pL2_entry->cvid = 0; + pL2_entry->fid = l2Table.cvid_fid; + } + pL2_entry->auth = l2Table.auth; + pL2_entry->sa_block = l2Table.sa_block; + pL2_entry->age = 0; + pL2_entry->is_ipvidmul = 0; + pL2_entry->l3_vid = 0; + } + else if((l2Table.age != 0)||(l2Table.nosalearn == 1)) + { + memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); + memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); + pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; + pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; + pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; + pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; + pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; + pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(1<<(l2Table.spa), &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->ivl = l2Table.ivl_svl; + pL2_entry->cvid = l2Table.cvid_fid; + pL2_entry->fid = l2Table.fid; + pL2_entry->auth = l2Table.auth; + pL2_entry->sa_block = l2Table.sa_block; + pL2_entry->age = l2Table.age; + pL2_entry->is_ipvidmul = 0; + pL2_entry->l3_vid = 0; + } + else + return RT_ERR_L2_EMPTY_ENTRY; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/leaky.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/leaky.c new file mode 100755 index 00000000..1b7d50a9 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/leaky.c @@ -0,0 +1,590 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Leaky module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + + +/* Function Name: + * rtk_leaky_vlan_set + * Description: + * Set VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set VLAN leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port <= RTK_PORT_ID_MAX; port++) + { + if ((retVal = rtl8367c_setAsicIpMulticastVlanLeaky(port,enable)) != RT_ERR_OK) + return retVal; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_setAsicIGMPVLANLeaky(enable)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_leaky_vlan_get + * Description: + * Get VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get VLAN leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port,tmp; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port <= RTK_PORT_ID_MAX; port++) + { + if ((retVal = rtl8367c_getAsicIpMulticastVlanLeaky(port, &tmp)) != RT_ERR_OK) + return retVal; + if (port>0&&(tmp!=*pEnable)) + return RT_ERR_FAILED; + *pEnable = tmp; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_getAsicIGMPVLANLeaky(&tmp)) != RT_ERR_OK) + return retVal; + + *pEnable = tmp; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_leaky_portIsolation_set + * Description: + * Set port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set port isolation leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) + { + if ((retVal = rtl8367c_setAsicIpMulticastPortIsoLeaky(port,enable)) != RT_ERR_OK) + return retVal; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_setAsicIGMPIsoLeaky(enable)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_leaky_portIsolation_get + * Description: + * Get port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get port isolation leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port, tmp; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) + { + if ((retVal = rtl8367c_getAsicIpMulticastPortIsoLeaky(port, &tmp)) != RT_ERR_OK) + return retVal; + if (port > 0 &&(tmp != *pEnable)) + return RT_ERR_FAILED; + *pEnable = tmp; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_getAsicIGMPIsoLeaky(&tmp)) != RT_ERR_OK) + return retVal; + + *pEnable = tmp; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + } + + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/led.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/led.c new file mode 100755 index 00000000..c00c331d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/led.c @@ -0,0 +1,792 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in LED module. + * + */ + +#include +#include +#include +#include + +#include +#include + + +/* Function Name: + * rtk_led_enable_set + * Description: + * Set Led enable congiuration + * Input: + * group - LED group id. + * pPortmask - LED enable port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_MASK - Error portmask + * Note: + * The API can be used to enable LED per port per group. + */ +rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + rtk_port_t port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + RTK_CHK_PORTMASK_VALID(pPortmask); + + RTK_PORTMASK_SCAN((*pPortmask), port) + { + if(rtk_switch_isCPUPort(port) == RT_ERR_OK) + return RT_ERR_PORT_MASK; + } + + if((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLedGroupEnable(group, pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_enable_get + * Description: + * Get Led enable congiuration + * Input: + * group - LED group id. + * Output: + * pPortmask - LED enable port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can be used to get LED enable status. + */ +rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicLedGroupEnable(group, &pmask)) != RT_ERR_OK) + return retVal; + + if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_led_operation_set + * Description: + * Set Led operation mode + * Input: + * mode - LED operation mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ( mode >= LED_OP_END) + return RT_ERR_INPUT; + + switch (mode) + { + case LED_OP_PARALLEL: + regData = LEDOP_PARALLEL; + break; + case LED_OP_SERIAL: + regData = LEDOP_SERIAL; + break; + default: + return RT_ERR_CHIP_NOT_SUPPORTED; + break; + } + + if ((retVal = rtl8367c_setAsicLedOperationMode(regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_operation_get + * Description: + * Get Led operation mode + * Input: + * None + * Output: + * pMode - Support LED operation mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedOperationMode(®Data)) != RT_ERR_OK) + return retVal; + + if (regData == LEDOP_SERIAL) + *pMode = LED_OP_SERIAL; + else if (regData ==LEDOP_PARALLEL) + *pMode = LED_OP_PARALLEL; + else + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_modeForce_set + * Description: + * Set Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * mode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can force to one force mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* No LED for CPU port */ + if(rtk_switch_isCPUPort(port) == RT_ERR_OK) + return RT_ERR_PORT_ID; + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + if (mode >= LED_FORCE_END) + return RT_ERR_NOT_ALLOWED; + + if ((retVal = rtl8367c_setAsicForceLed(rtk_switch_port_L2P_get(port), group, mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_modeForce_get + * Description: + * Get Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * pMode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can get forced Led group mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* No LED for CPU port */ + if(rtk_switch_isCPUPort(port) == RT_ERR_OK) + return RT_ERR_PORT_ID; + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + if (NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicForceLed(rtk_switch_port_L2P_get(port), group, pMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_blinkRate_set + * Description: + * Set LED blinking rate + * Input: + * blinkRate - blinking rate. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * ASIC support 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (blinkRate >= LED_BLINKRATE_END) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicLedBlinkRate(blinkRate)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_blinkRate_get + * Description: + * Get LED blinking rate at mode 0 to mode 3 + * Input: + * None + * Output: + * pBlinkRate - blinking rate. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pBlinkRate) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedBlinkRate(pBlinkRate)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupConfig_set + * Description: + * Set per group Led to congiuration mode + * Input: + * group - LED group. + * config - LED configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. + * - Definition LED Statuses Description + * - 0000 LED_Off LED pin Tri-State. + * - 0001 Dup/Col Collision, Full duplex Indicator. + * - 0010 Link/Act Link, Activity Indicator. + * - 0011 Spd1000 1000Mb/s Speed Indicator. + * - 0100 Spd100 100Mb/s Speed Indicator. + * - 0101 Spd10 10Mb/s Speed Indicator. + * - 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. + * - 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. + * - 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. + * - 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. + * - 1010 LoopDetect LoopDetect Indicator. + * - 1011 EEE EEE Indicator. + * - 1100 Link/Rx Link, Activity Indicator. + * - 1101 Link/Tx Link, Activity Indicator. + * - 1110 Master Link on Master Indicator. + * - 1111 Act Activity Indicator. Low for link established. + */ +rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if (LED_CONFIG_END <= config) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicLedIndicateInfoConfig(group, config)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupConfig_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED indicated information configuration for each LED group. + */ +rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if(NULL == pConfig) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedIndicateInfoConfig(group, pConfig)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupAbility_set + * Description: + * Configure per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if(pAbility == NULL) + return RT_ERR_NULL_POINTER; + + if( (pAbility->link_10m >= RTK_ENABLE_END) || (pAbility->link_100m >= RTK_ENABLE_END)|| + (pAbility->link_500m >= RTK_ENABLE_END) || (pAbility->link_1000m >= RTK_ENABLE_END)|| + (pAbility->act_rx >= RTK_ENABLE_END) || (pAbility->act_tx >= RTK_ENABLE_END) ) + { + return RT_ERR_INPUT; + } + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) + return retVal; + + if(pAbility->link_10m == ENABLED) + regData |= 0x0001; + else + regData &= ~0x0001; + + if(pAbility->link_100m == ENABLED) + regData |= 0x0002; + else + regData &= ~0x0002; + + if(pAbility->link_500m == ENABLED) + regData |= 0x0004; + else + regData &= ~0x0004; + + if(pAbility->link_1000m == ENABLED) + regData |= 0x0008; + else + regData &= ~0x0008; + + if(pAbility->act_rx == ENABLED) + regData |= 0x0010; + else + regData &= ~0x0010; + + if(pAbility->act_tx == ENABLED) + regData |= 0x0020; + else + regData &= ~0x0020; + + regData |= (0x0001 << 6); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupAbility_get + * Description: + * Get per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if(pAbility == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) + return retVal; + + pAbility->link_10m = (regData & 0x0001) ? ENABLED : DISABLED; + pAbility->link_100m = (regData & 0x0002) ? ENABLED : DISABLED; + pAbility->link_500m = (regData & 0x0004) ? ENABLED : DISABLED; + pAbility->link_1000m = (regData & 0x0008) ? ENABLED : DISABLED; + pAbility->act_rx = (regData & 0x0010) ? ENABLED : DISABLED; + pAbility->act_tx = (regData & 0x0020) ? ENABLED : DISABLED; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_led_serialMode_set + * Description: + * Set Led serial mode active congiuration + * Input: + * active - LED group. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED serial mode active congiuration. + */ +rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ( active >= LED_ACTIVE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicLedSerialModeConfig(active,1))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_serialMode_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED serial mode active configuration. + */ +rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pActive) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedSerialModeConfig(pActive,®Data))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_OutputEnable_set + * Description: + * This API set LED I/O state. + * Input: + * enabled - LED I/O state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set LED I/O state. + */ +rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicLedOutputEnable(state))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_OutputEnable_get + * Description: + * This API get LED I/O state. + * Input: + * None. + * Output: + * pEnabled - LED I/O state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current LED I/O state. + */ +rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pState == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedOutputEnable(pState))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_led_serialModePortmask_set + * Description: + * This API configure Serial LED output Group and portmask + * Input: + * output - output group + * pPortmask - output portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(output >= SERIAL_LED_END) + return RT_ERR_INPUT; + + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLedSerialOutput((rtk_uint32)output, pmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_serialModePortmask_get + * Description: + * This API get Serial LED output Group and portmask + * Input: + * None. + * Output: + * pOutput - output group + * pPortmask - output portmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pOutput == NULL) + return RT_ERR_NULL_POINTER; + + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedSerialOutput((rtk_uint32 *)pOutput, &pmask))!=RT_ERR_OK) + return retVal; + + if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/mirror.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/mirror.c new file mode 100755 index 00000000..1921d1a5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/mirror.c @@ -0,0 +1,548 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Mirror module. + * + */ + +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_mirror_portBased_set + * Description: + * Set port mirror function. + * Input: + * mirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API is to set mirror function of source port and mirror port. + * The mirror port can only be set to one port and the TX and RX mirror ports + * should be identical. + */ +rtk_api_ret_t rtk_mirror_portBased_set(rtk_port_t mirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask) +{ + rtk_api_ret_t retVal; + rtk_enable_t mirRx, mirTx; + rtk_uint32 i, pmask; + rtk_port_t source_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(mirroring_port); + + if(NULL == pMirrored_rx_portmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pMirrored_tx_portmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pMirrored_rx_portmask); + + RTK_CHK_PORTMASK_VALID(pMirrored_tx_portmask); + + /*Mirror Sorce Port Mask Check*/ + if (pMirrored_tx_portmask->bits[0]!=pMirrored_rx_portmask->bits[0]&&pMirrored_tx_portmask->bits[0]!=0&&pMirrored_rx_portmask->bits[0]!=0) + return RT_ERR_PORT_MASK; + + /*mirror port != source port*/ + if(RTK_PORTMASK_IS_PORT_SET((*pMirrored_tx_portmask), mirroring_port) || RTK_PORTMASK_IS_PORT_SET((*pMirrored_rx_portmask), mirroring_port)) + return RT_ERR_PORT_MASK; + + source_port = rtk_switch_maxLogicalPort_get(); + + RTK_SCAN_ALL_LOG_PORT(i) + { + if (pMirrored_tx_portmask->bits[0]&(1<bits[0]&(1<bits[0] != 0) + { + if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_rx_portmask, &pmask)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_tx_portmask, &pmask)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) + return retVal; + } + + + if (pMirrored_rx_portmask->bits[0]) + mirRx = ENABLED; + else + mirRx = DISABLED; + + if ((retVal = rtl8367c_setAsicPortMirrorRxFunction(mirRx)) != RT_ERR_OK) + return retVal; + + if (pMirrored_tx_portmask->bits[0]) + mirTx = ENABLED; + else + mirTx = DISABLED; + + if ((retVal = rtl8367c_setAsicPortMirrorTxFunction(mirTx)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_mirror_portBased_get + * Description: + * Get port mirror function. + * Input: + * None + * Output: + * pMirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror function of source port and mirror port. + */ +rtk_api_ret_t rtk_mirror_portBased_get(rtk_port_t *pMirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask) +{ + rtk_api_ret_t retVal; + rtk_port_t source_port; + rtk_enable_t mirRx, mirTx; + rtk_uint32 sport, mport, pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMirrored_rx_portmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pMirrored_tx_portmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pMirroring_port) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirror(&sport, &mport)) != RT_ERR_OK) + return retVal; + source_port = rtk_switch_port_P2L_get(sport); + *pMirroring_port = rtk_switch_port_P2L_get(mport); + + if ((retVal = rtl8367c_getAsicPortMirrorRxFunction((rtk_uint32*)&mirRx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorTxFunction((rtk_uint32*)&mirTx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorMask(&pmask)) != RT_ERR_OK) + return retVal; + + if (DISABLED == mirRx) + pMirrored_rx_portmask->bits[0]=0; + else + { + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_rx_portmask)) != RT_ERR_OK) + return retVal; + pMirrored_rx_portmask->bits[0] |= 1<bits[0]=0; + else + { + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_tx_portmask)) != RT_ERR_OK) + return retVal; + pMirrored_tx_portmask->bits[0] |= 1<= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorIsolation(enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_portIso_get + * Description: + * Get mirror port isolation. + * Input: + * None + * Output: + * pEnable |Mirror isolation status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation status. + */ +rtk_api_ret_t rtk_mirror_portIso_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorIsolation(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_vlanLeaky_set + * Description: + * Set mirror VLAN leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorVlanTxLeaky(txenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortMirrorVlanRxLeaky(rxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_vlanLeaky_get + * Description: + * Get mirror VLAN leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror VLAN leaky status. + */ +rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if( (NULL == pTxenable) || (NULL == pRxenable) ) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorVlanTxLeaky(pTxenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorVlanRxLeaky(pRxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_isolationLeaky_set + * Description: + * Set mirror Isolation leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(txenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortMirrorIsolationRxLeaky(rxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_isolationLeaky_get + * Description: + * Get mirror isolation leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation leaky status. + */ +rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if( (NULL == pTxenable) || (NULL == pRxenable) ) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorIsolationTxLeaky(pTxenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorIsolationRxLeaky(pRxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_keep_set + * Description: + * Set mirror packet format keep. + * Input: + * mode - -mirror keep mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set -mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mode >= MIRROR_KEEP_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorRealKeep(mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_keep_get + * Description: + * Get mirror packet format keep. + * Input: + * None + * Output: + * pMode -mirror keep mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorRealKeep(pMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_override_set + * Description: + * Set port mirror override function. + * Input: + * rxMirror - 1: output mirrored packet, 0: output normal forward packet + * txMirror - 1: output mirrored packet, 0: output normal forward packet + * aclMirror - 1: output mirrored packet, 0: output normal forward packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API is to set mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror) +{ + rtk_api_ret_t retVal; + + if( (rxMirror >= RTK_ENABLE_END) || (txMirror >= RTK_ENABLE_END) || (aclMirror >= RTK_ENABLE_END)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorOverride((rtk_uint32)rxMirror, (rtk_uint32)txMirror, (rtk_uint32)aclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_override_get + * Description: + * Get port mirror override function. + * Input: + * None + * Output: + * pRxMirror - 1: output mirrored packet, 0: output normal forward packet + * pTxMirror - 1: output mirrored packet, 0: output normal forward packet + * pAclMirror - 1: output mirrored packet, 0: output normal forward packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * The API is to Get mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror) +{ + rtk_api_ret_t retVal; + + if( (pRxMirror == NULL) || (pTxMirror == NULL) || (pAclMirror == NULL)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_getAsicPortMirrorOverride((rtk_uint32 *)pRxMirror, (rtk_uint32 *)pTxMirror, (rtk_uint32 *)pAclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/oam.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/oam.c new file mode 100755 index 00000000..dc1559ae --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/oam.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in OAM(802.3ah) module. + * + */ + +#include +#include +#include +#include + +#include +#include + + +/* Module Name : OAM */ + +/* Function Name: + * rtk_oam_init + * Description: + * Initialize oam module. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * Must initialize oam module before calling any oam APIs. + */ +rtk_api_ret_t rtk_oam_init(void) +{ + return RT_ERR_OK; +} /* end of rtk_oam_init */ + + +/* Function Name: + * rtk_oam_state_set + * Description: + * This API set OAM state. + * Input: + * enabled -OAMstate + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set OAM state. + */ +rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicOamEnable(enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_oam_state_get + * Description: + * This API get OAM state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current OAM state. + */ +rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicOamEnable(pEnabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Set OAM parser action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (action >= OAM_PARSER_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicOamParser(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Get OAM parser action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicOamParser(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_oam_multiplexerAction_set + * Description: + * Set OAM multiplexer action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (action >= OAM_MULTIPLEXER_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicOamMultiplexer(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Get OAM multiplexer action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicOamMultiplexer(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/port.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/port.c new file mode 100755 index 00000000..9f99d1b3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/port.c @@ -0,0 +1,2467 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Port module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define FIBER_INIT_SIZE 1507 +CONST_T rtk_uint8 Fiber[FIBER_INIT_SIZE] = { +0x02,0x04,0x41,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x05,0x2D,0xE4,0x90, +0x06,0x2A,0xF0,0xFD,0x7C,0x01,0x7F,0x3F, +0x7E,0x1D,0x12,0x05,0xAF,0x7D,0x40,0x12, +0x02,0x5F,0xE4,0xFF,0xFE,0xFD,0x80,0x08, +0x12,0x05,0x9E,0x50,0x0C,0x12,0x05,0x8B, +0xFC,0x90,0x06,0x24,0x12,0x03,0x76,0x80, +0xEF,0xE4,0xF5,0xA8,0xD2,0xAF,0x7D,0x1F, +0xFC,0x7F,0x49,0x7E,0x13,0x12,0x05,0xAF, +0x12,0x05,0xD6,0x7D,0xD7,0x12,0x02,0x1E, +0x7D,0x80,0x12,0x01,0xCA,0x7D,0x94,0x7C, +0xF9,0x12,0x02,0x3B,0x7D,0x81,0x12,0x01, +0xCA,0x7D,0xA2,0x7C,0x31,0x12,0x02,0x3B, +0x7D,0x82,0x12,0x01,0xDF,0x7D,0x60,0x7C, +0x69,0x12,0x02,0x43,0x7D,0x83,0x12,0x01, +0xDF,0x7D,0x28,0x7C,0x97,0x12,0x02,0x43, +0x7D,0x84,0x12,0x01,0xF4,0x7D,0x85,0x7C, +0x9D,0x12,0x02,0x57,0x7D,0x23,0x12,0x01, +0xF4,0x7D,0x10,0x7C,0xD8,0x12,0x02,0x57, +0x7D,0x24,0x7C,0x04,0x12,0x02,0x28,0x7D, +0x00,0x12,0x02,0x1E,0x7D,0x2F,0x12,0x02, +0x09,0x7D,0x20,0x7C,0x0F,0x7F,0x02,0x7E, +0x66,0x12,0x05,0xAF,0x7D,0x01,0x12,0x02, +0x09,0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x7F, +0x02,0x7E,0x66,0x12,0x02,0x4B,0x44,0x02, +0xFF,0x90,0x06,0x28,0xEE,0xF0,0xA3,0xEF, +0xF0,0x44,0x04,0xFF,0x90,0x06,0x28,0xEE, +0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F,0x02, +0x7E,0x66,0x12,0x05,0xAF,0x7D,0x04,0x7C, +0x00,0x12,0x02,0x28,0x7D,0xB9,0x7C,0x15, +0x7F,0xEB,0x7E,0x13,0x12,0x05,0xAF,0x7D, +0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, +0x05,0xAF,0x7D,0x40,0x7C,0x11,0x7F,0x00, +0x7E,0x62,0x12,0x05,0xAF,0x12,0x03,0x82, +0x7D,0x41,0x12,0x02,0x5F,0xE4,0xFF,0xFE, +0xFD,0x80,0x08,0x12,0x05,0x9E,0x50,0x0C, +0x12,0x05,0x8B,0xFC,0x90,0x06,0x24,0x12, +0x03,0x76,0x80,0xEF,0xC2,0x00,0xC2,0x01, +0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62, +0x12,0x02,0x4B,0x30,0xE2,0x05,0xE4,0xA3, +0xF0,0x80,0xF1,0x90,0x06,0x2A,0xE0,0x70, +0x12,0x12,0x01,0x89,0x90,0x06,0x2A,0x74, +0x01,0xF0,0xE4,0x90,0x06,0x2D,0xF0,0xA3, +0xF0,0x80,0xD9,0xC3,0x90,0x06,0x2E,0xE0, +0x94,0x64,0x90,0x06,0x2D,0xE0,0x94,0x00, +0x40,0xCA,0xE4,0xF0,0xA3,0xF0,0x12,0x01, +0x89,0x90,0x06,0x2A,0x74,0x01,0xF0,0x80, +0xBB,0x7D,0x04,0xFC,0x7F,0x02,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, +0xAF,0xE4,0xFD,0xFC,0x7F,0x02,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, +0xAF,0x22,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x05,0xAF,0x22,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF, +0x22,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C,0x04, +0x7F,0x02,0x7E,0x66,0x12,0x05,0xAF,0x22, +0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, +0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, +0x05,0xAF,0x22,0x12,0x05,0x67,0x90,0x06, +0x28,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7F, +0x02,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, +0x00,0x7F,0x36,0x7E,0x13,0x12,0x05,0xAF, +0x22,0xC5,0xF0,0xF8,0xA3,0xE0,0x28,0xF0, +0xC5,0xF0,0xF8,0xE5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xE0,0x38,0xF0,0x22,0x75, +0xF0,0x08,0x75,0x82,0x00,0xEF,0x2F,0xFF, +0xEE,0x33,0xFE,0xCD,0x33,0xCD,0xCC,0x33, +0xCC,0xC5,0x82,0x33,0xC5,0x82,0x9B,0xED, +0x9A,0xEC,0x99,0xE5,0x82,0x98,0x40,0x0C, +0xF5,0x82,0xEE,0x9B,0xFE,0xED,0x9A,0xFD, +0xEC,0x99,0xFC,0x0F,0xD5,0xF0,0xD6,0xE4, +0xCE,0xFB,0xE4,0xCD,0xFA,0xE4,0xCC,0xF9, +0xA8,0x82,0x22,0xB8,0x00,0xC1,0xB9,0x00, +0x59,0xBA,0x00,0x2D,0xEC,0x8B,0xF0,0x84, +0xCF,0xCE,0xCD,0xFC,0xE5,0xF0,0xCB,0xF9, +0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xEC,0x33,0xFC,0xEB,0x33, +0xFB,0x10,0xD7,0x03,0x99,0x40,0x04,0xEB, +0x99,0xFB,0x0F,0xD8,0xE5,0xE4,0xF9,0xFA, +0x22,0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33, +0xFE,0xED,0x33,0xFD,0xEC,0x33,0xFC,0xC9, +0x33,0xC9,0x10,0xD7,0x05,0x9B,0xE9,0x9A, +0x40,0x07,0xEC,0x9B,0xFC,0xE9,0x9A,0xF9, +0x0F,0xD8,0xE0,0xE4,0xC9,0xFA,0xE4,0xCC, +0xFB,0x22,0x75,0xF0,0x10,0xEF,0x2F,0xFF, +0xEE,0x33,0xFE,0xED,0x33,0xFD,0xCC,0x33, +0xCC,0xC8,0x33,0xC8,0x10,0xD7,0x07,0x9B, +0xEC,0x9A,0xE8,0x99,0x40,0x0A,0xED,0x9B, +0xFD,0xEC,0x9A,0xFC,0xE8,0x99,0xF8,0x0F, +0xD5,0xF0,0xDA,0xE4,0xCD,0xFB,0xE4,0xCC, +0xFA,0xE4,0xC8,0xF9,0x22,0xEB,0x9F,0xF5, +0xF0,0xEA,0x9E,0x42,0xF0,0xE9,0x9D,0x42, +0xF0,0xE8,0x9C,0x45,0xF0,0x22,0xE0,0xFC, +0xA3,0xE0,0xFD,0xA3,0xE0,0xFE,0xA3,0xE0, +0xFF,0x22,0xE0,0xF8,0xA3,0xE0,0xF9,0xA3, +0xE0,0xFA,0xA3,0xE0,0xFB,0x22,0xEC,0xF0, +0xA3,0xED,0xF0,0xA3,0xEE,0xF0,0xA3,0xEF, +0xF0,0x22,0x12,0x03,0xF8,0x12,0x04,0x1A, +0x44,0x40,0x12,0x04,0x0F,0x7D,0x03,0x7C, +0x00,0x12,0x04,0x23,0x12,0x05,0xAF,0x12, +0x03,0xF8,0x12,0x04,0x1A,0x54,0xBF,0x12, +0x04,0x0F,0x7D,0x03,0x7C,0x00,0x12,0x03, +0xD0,0x7F,0x02,0x7E,0x66,0x12,0x05,0x67, +0xEF,0x54,0xFD,0x54,0xFE,0x12,0x04,0x33, +0x12,0x03,0xD0,0x7F,0x02,0x7E,0x66,0x12, +0x05,0x67,0xEF,0x44,0x02,0x44,0x01,0x12, +0x04,0x33,0x12,0x04,0x23,0x02,0x05,0xAF, +0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x05,0xAF,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x22, +0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x05, +0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12,0x05, +0x67,0xEF,0x22,0x7F,0x01,0x7E,0x66,0x12, +0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x22,0xFD,0xAC,0x06,0x7F,0x02, +0x7E,0x66,0x12,0x05,0xAF,0xE4,0xFD,0xFC, +0x22,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x04,0x88,0x02,0x00,0x0E, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x05,0xCB,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0x75,0x0F,0x80, +0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, +0x83,0xE4,0xF5,0x10,0x75,0x0B,0xA0,0x75, +0x0A,0xAC,0x75,0x09,0xB9,0x75,0x08,0x03, +0x75,0x89,0x11,0x7B,0x60,0x7A,0x09,0xF9, +0xF8,0xAF,0x0B,0xAE,0x0A,0xAD,0x09,0xAC, +0x08,0x12,0x02,0xBB,0xAD,0x07,0xAC,0x06, +0xC3,0xE4,0x9D,0xFD,0xE4,0x9C,0xFC,0x78, +0x17,0xF6,0xAF,0x05,0xEF,0x08,0xF6,0x18, +0xE6,0xF5,0x8C,0x08,0xE6,0xF5,0x8A,0x74, +0x0D,0x2D,0xFD,0xE4,0x3C,0x18,0xF6,0xAF, +0x05,0xEF,0x08,0xF6,0x75,0x88,0x10,0x53, +0x8E,0xC7,0xD2,0xA9,0x22,0xC0,0xE0,0xC0, +0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, +0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, +0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, +0x2B,0xE4,0x75,0xF0,0x01,0x12,0x02,0x69, +0x90,0x06,0x2D,0xE4,0x75,0xF0,0x01,0x12, +0x02,0x69,0xD0,0x00,0xD0,0xD0,0xD0,0x82, +0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, +0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, +0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, +0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, +0xD2,0xAF,0x22,0x90,0x06,0x24,0x12,0x03, +0x5E,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, +0xE4,0x3D,0xFD,0xE4,0x3C,0x22,0xE4,0x7F, +0x20,0x7E,0x4E,0xFD,0xFC,0x90,0x06,0x24, +0x12,0x03,0x6A,0xC3,0x02,0x03,0x4D,0xC2, +0xAF,0xAB,0x07,0xAA,0x06,0x8A,0xA2,0x8B, +0xA3,0x8C,0xA4,0x8D,0xA5,0x75,0xA0,0x03, +0x00,0x00,0x00,0xAA,0xA1,0xBA,0x00,0xF8, +0xD2,0xAF,0x22,0x42,0x06,0x2D,0x00,0x00, +0x42,0x06,0x2B,0x00,0x00,0x00,0x12,0x05, +0xDF,0x12,0x04,0xCD,0x02,0x00,0x03,0xE4, +0xF5,0x8E,0x22}; + +static rtk_api_ret_t _rtk_port_FiberModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check Combo port or not */ + RTK_CHK_PORT_IS_COMBO(port); + + /* Flow Control */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG04, ®Data)) != RT_ERR_OK) + return retVal; + + if (pAbility->AsyFC == 1) + regData |= (0x0001 << 8); + else + regData &= ~(0x0001 << 8); + + if (pAbility->FC == 1) + regData |= (0x0001 << 7); + else + regData &= ~(0x0001 << 7); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG04, regData)) != RT_ERR_OK) + return retVal; + + /* Speed ability */ + if( (pAbility->Full_1000 == 1) && (pAbility->Full_100 == 1) && (pAbility->AutoNegotiation == 1) ) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 7)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) + return retVal; + } + else if(pAbility->Full_1000 == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 4)) != RT_ERR_OK) + return retVal; + + if(pAbility->AutoNegotiation == 1) + { + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x0140)) != RT_ERR_OK) + return retVal; + } + } + else if(pAbility->Full_100 == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 5)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x2100)) != RT_ERR_OK) + return retVal; + } + + /* Digital software reset */ + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= (0x0001 << 6); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0001 << 6); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /* CDR reset */ + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1401))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1403))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_port_FiberModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 data, regData; + + /* Check Combo port or not */ + RTK_CHK_PORT_IS_COMBO(port); + + memset(pAbility, 0x00, sizeof(rtk_port_phy_ability_t)); + + /* Flow Control */ + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_FIB100_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0044)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) + return retVal; + + if(regData & (0x0001 << 8)) + pAbility->AsyFC = 1; + + if(regData & (0x0001 << 7)) + pAbility->FC = 1; + + /* Speed ability */ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, &data)) != RT_ERR_OK) + return retVal; + + if(data == 0) + { + pAbility->AutoNegotiation = 1; + pAbility->Full_1000 = 1; + pAbility->Full_100 = 1; + } + else + { + if ((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, &data)) != RT_ERR_OK) + return retVal; + + if(data == 4) + { + pAbility->Full_1000 = 1; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG00, &data)) != RT_ERR_OK) + return retVal; + + if(data & 0x1000) + pAbility->AutoNegotiation = 1; + else + pAbility->AutoNegotiation = 0; + } + else if(data == 5) + pAbility->Full_100 = 1; + else + return RT_ERR_FAILED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyAutoNegoAbility_set + * Description: + * Set ethernet PHY auto-negotiation desired ability. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + */ +rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + rtk_uint32 phyEnMsk0; + rtk_uint32 phyEnMsk4; + rtk_uint32 phyEnMsk9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || + pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || + pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || + pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_set(port, pAbility); + } + } + + /*for PHY auto mode setup*/ + pAbility->AutoNegotiation = 1; + + phyEnMsk0 = 0; + phyEnMsk4 = 0; + phyEnMsk9 = 0; + + if (1 == pAbility->Half_10) + { + /*10BASE-TX half duplex capable in reg 4.5*/ + phyEnMsk4 = phyEnMsk4 | (1 << 5); + + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + } + + if (1 == pAbility->Full_10) + { + /*10BASE-TX full duplex capable in reg 4.6*/ + phyEnMsk4 = phyEnMsk4 | (1 << 6); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + + } + + if (1 == pAbility->Half_100) + { + /*100BASE-TX half duplex capable in reg 4.7*/ + phyEnMsk4 = phyEnMsk4 | (1 << 7); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + } + + + if (1 == pAbility->Full_100) + { + /*100BASE-TX full duplex capable in reg 4.8*/ + phyEnMsk4 = phyEnMsk4 | (1 << 8); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + } + + + if (1 == pAbility->Full_1000) + { + /*1000 BASE-T FULL duplex capable setting in reg 9.9*/ + phyEnMsk9 = phyEnMsk9 | (1 << 9); + + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 | (1 << 6); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + + + /*Auto-Negotiation setting in reg 0.12*/ + phyEnMsk0 = phyEnMsk0 | (1 << 12); + + } + + if (1 == pAbility->AutoNegotiation) + { + /*Auto-Negotiation setting in reg 0.12*/ + phyEnMsk0 = phyEnMsk0 | (1 << 12); + } + + if (1 == pAbility->AsyFC) + { + /*Asymetric flow control in reg 4.11*/ + phyEnMsk4 = phyEnMsk4 | (1 << 11); + } + if (1 == pAbility->FC) + { + /*Flow control in reg 4.10*/ + phyEnMsk4 = phyEnMsk4 | (1 << 10); + } + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0200)) | phyEnMsk9 ; + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0DE0)) | phyEnMsk4; + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Control register setting and restart auto*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x3140)) | phyEnMsk0; + /*If have auto-negotiation capable, then restart auto negotiation*/ + if (1 == pAbility->AutoNegotiation) + { + phyData = phyData | (1 << 9); + } + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyAutoNegoAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData0; + rtk_uint32 phyData4; + rtk_uint32 phyData9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_get(port, pAbility); + } + } + + /*Control register setting and restart auto*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) + return retVal; + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) + return retVal; + + if (phyData9 & (1 << 9)) + pAbility->Full_1000 = 1; + else + pAbility->Full_1000 = 0; + + if (phyData4 & (1 << 11)) + pAbility->AsyFC = 1; + else + pAbility->AsyFC = 0; + + if (phyData4 & (1 << 10)) + pAbility->FC = 1; + else + pAbility->FC = 0; + + + if (phyData4 & (1 << 8)) + pAbility->Full_100 = 1; + else + pAbility->Full_100 = 0; + + if (phyData4 & (1 << 7)) + pAbility->Half_100 = 1; + else + pAbility->Half_100 = 0; + + if (phyData4 & (1 << 6)) + pAbility->Full_10 = 1; + else + pAbility->Full_10 = 0; + + if (phyData4 & (1 << 5)) + pAbility->Half_10 = 1; + else + pAbility->Half_10 = 0; + + + if (phyData0 & (1 << 12)) + pAbility->AutoNegotiation = 1; + else + pAbility->AutoNegotiation = 0; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyForceModeAbility_set + * Description: + * Set the port speed/duplex mode/pause/asy_pause in the PHY force mode. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + * This API can be used to configure combo port in fiber mode. + * The possible parameters in fiber mode are Full_1000 and Full 100. + * All the other fields in rtk_port_phy_ability_t will be ignored in fiber port. + */ +rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + rtk_uint32 phyEnMsk0; + rtk_uint32 phyEnMsk4; + rtk_uint32 phyEnMsk9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || + pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || + pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || + pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_set(port, pAbility); + } + } + + if (1 == pAbility->Full_1000) + return RT_ERR_INPUT; + + /*for PHY force mode setup*/ + pAbility->AutoNegotiation = 0; + + phyEnMsk0 = 0; + phyEnMsk4 = 0; + phyEnMsk9 = 0; + + if (1 == pAbility->Half_10) + { + /*10BASE-TX half duplex capable in reg 4.5*/ + phyEnMsk4 = phyEnMsk4 | (1 << 5); + + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + } + + if (1 == pAbility->Full_10) + { + /*10BASE-TX full duplex capable in reg 4.6*/ + phyEnMsk4 = phyEnMsk4 | (1 << 6); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + + } + + if (1 == pAbility->Half_100) + { + /*100BASE-TX half duplex capable in reg 4.7*/ + phyEnMsk4 = phyEnMsk4 | (1 << 7); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + } + + + if (1 == pAbility->Full_100) + { + /*100BASE-TX full duplex capable in reg 4.8*/ + phyEnMsk4 = phyEnMsk4 | (1 << 8); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + } + + if (1 == pAbility->AsyFC) + { + /*Asymetric flow control in reg 4.11*/ + phyEnMsk4 = phyEnMsk4 | (1 << 11); + } + if (1 == pAbility->FC) + { + /*Flow control in reg 4.10*/ + phyEnMsk4 = phyEnMsk4 | ((1 << 10)); + } + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0200)) | phyEnMsk9 ; + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0DE0)) | phyEnMsk4; + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Control register setting and power off/on*/ + phyData = phyEnMsk0 & (~(1 << 12)); + phyData |= (1 << 11); /* power down PHY, bit 11 should be set to 1 */ + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + phyData = phyData & (~(1 << 11)); /* power on PHY, bit 11 should be set to 0*/ + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyForceModeAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData0; + rtk_uint32 phyData4; + rtk_uint32 phyData9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_get(port, pAbility); + } + } + + /*Control register setting and restart auto*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) + return retVal; + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) + return retVal; + + if (phyData9 & (1 << 9)) + pAbility->Full_1000 = 1; + else + pAbility->Full_1000 = 0; + + if (phyData4 & (1 << 11)) + pAbility->AsyFC = 1; + else + pAbility->AsyFC = 0; + + if (phyData4 & ((1 << 10))) + pAbility->FC = 1; + else + pAbility->FC = 0; + + + if (phyData4 & (1 << 8)) + pAbility->Full_100 = 1; + else + pAbility->Full_100 = 0; + + if (phyData4 & (1 << 7)) + pAbility->Half_100 = 1; + else + pAbility->Half_100 = 0; + + if (phyData4 & (1 << 6)) + pAbility->Full_10 = 1; + else + pAbility->Full_10 = 0; + + if (phyData4 & (1 << 5)) + pAbility->Half_10 = 1; + else + pAbility->Half_10 = 0; + + + if (phyData0 & (1 << 12)) + pAbility->AutoNegotiation = 1; + else + pAbility->AutoNegotiation = 0; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyStatus_get + * Description: + * Get ethernet PHY linking status + * Input: + * port - Port id. + * Output: + * linkStatus - PHY link status + * speed - PHY link speed + * duplex - PHY duplex mode + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * API will return auto negotiation status of phy. + */ +rtk_api_ret_t rtk_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if( (NULL == pLinkStatus) || (NULL == pSpeed) || (NULL == pDuplex) ) + return RT_ERR_NULL_POINTER; + + /*Get PHY resolved register*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_RESOLVED_REG, &phyData)) != RT_ERR_OK) + return retVal; + + /*check link status*/ + if (phyData & (1<<2)) + { + *pLinkStatus = 1; + + /*check link speed*/ + *pSpeed = (phyData&0x0030) >> 4; + + /*check link duplex*/ + *pDuplex = (phyData&0x0008) >> 3; + } + else + { + *pLinkStatus = 0; + *pSpeed = 0; + *pDuplex = 0; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLink_set + * Description: + * Set port force linking configuration. + * Input: + * port - port id. + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can set Port/MAC force mode properties. + */ +rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + if (pPortability->forcemode >1|| pPortability->speed > 2 || pPortability->duplex > 1 || + pPortability->link > 1 || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) + return retVal; + + ability.forcemode = pPortability->forcemode; + ability.speed = pPortability->speed; + ability.duplex = pPortability->duplex; + ability.link = pPortability->link; + ability.nway = pPortability->nway; + ability.txpause = pPortability->txpause; + ability.rxpause = pPortability->rxpause; + + if ((retVal = rtl8367c_setAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLink_get + * Description: + * Get port force linking configuration. + * Input: + * port - Port id. + * Output: + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get Port/MAC force mode properties. + */ +rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) + return retVal; + + pPortability->forcemode = ability.forcemode; + pPortability->speed = ability.speed; + pPortability->duplex = ability.duplex; + pPortability->link = ability.link; + pPortability->nway = ability.nway; + pPortability->txpause = ability.txpause; + pPortability->rxpause = ability.rxpause; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLinkExt_set + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * mode - external interface mode + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface force mode properties. + * The external interface can be set to: + * - MODE_EXT_DISABLE, + * - MODE_EXT_RGMII, + * - MODE_EXT_MII_MAC, + * - MODE_EXT_MII_PHY, + * - MODE_EXT_TMII_MAC, + * - MODE_EXT_TMII_PHY, + * - MODE_EXT_GMII, + * - MODE_EXT_RMII_MAC, + * - MODE_EXT_RMII_PHY, + * - MODE_EXT_SGMII, + * - MODE_EXT_HSGMII, + * - MODE_EXT_1000X_100FX, + * - MODE_EXT_1000X, + * - MODE_EXT_100FX, + */ +rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + if (mode >=MODE_EXT_END) + return RT_ERR_INPUT; + + if(mode == MODE_EXT_HSGMII) + { + if (pPortability->forcemode > 1 || pPortability->speed != PORT_SPEED_2500M || pPortability->duplex != PORT_FULL_DUPLEX || + pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) + return RT_ERR_INPUT; + + if(rtk_switch_isHsgPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + } + else + { + if (pPortability->forcemode > 1 || pPortability->speed > PORT_SPEED_1000M || pPortability->duplex >= PORT_DUPLEX_END || + pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) + return RT_ERR_INPUT; + } + + ext_id = port - 15; + + if(mode == MODE_EXT_DISABLE) + { + memset(&ability, 0x00, sizeof(rtl8367c_port_ability_t)); + if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + + ability.forcemode = pPortability->forcemode; + ability.speed = (mode == MODE_EXT_HSGMII) ? PORT_SPEED_1000M : pPortability->speed; + ability.duplex = pPortability->duplex; + ability.link = pPortability->link; + ability.nway = pPortability->nway; + ability.txpause = pPortability->txpause; + ability.rxpause = pPortability->rxpause; + + if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLinkExt_get + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * Output: + * pMode - external interface mode + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get external interface force mode properties. + */ +rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + ext_id = port - 15; + + if ((retVal = rtl8367c_getAsicPortExtMode(ext_id, (rtk_uint32 *)pMode)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + + pPortability->forcemode = ability.forcemode; + pPortability->speed = (*pMode == MODE_EXT_HSGMII) ? PORT_SPEED_2500M : ability.speed; + pPortability->duplex = ability.duplex; + pPortability->link = ability.link; + pPortability->nway = ability.nway; + pPortability->txpause = ability.txpause; + pPortability->rxpause = ability.rxpause; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_port_macStatus_get + * Description: + * Get port link status. + * Input: + * port - Port id. + * Output: + * pPortstatus - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get Port/PHY properties. + */ +rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus) +{ + rtk_api_ret_t retVal; + rtl8367c_port_status_t status; + rtk_uint32 hsgsel; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPortstatus) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortStatus(rtk_switch_port_L2P_get(port), &status)) != RT_ERR_OK) + return retVal; + + + pPortstatus->duplex = status.duplex; + pPortstatus->link = status.link; + pPortstatus->nway = status.nway; + pPortstatus->txpause = status.txpause; + pPortstatus->rxpause = status.rxpause; + + if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgsel)) != RT_ERR_OK) + return retVal; + + if( (rtk_switch_isHsgPort(port) == RT_ERR_OK) && (hsgsel == 1) ) + pPortstatus->speed = PORT_SPEED_2500M; + else + pPortstatus->speed = status.speed; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_set + * Description: + * Set Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * enable - Loopback state, 0:disable, 1:enable + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can enable/disable Local loopback in MAC. + * For UTP port, This API will also enable the digital + * loopback bit in PHY register for sync of speed between + * PHY and MAC. For EXT port, users need to force the + * link state by themself. + */ +rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortLoopback(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if(enable == ENABLED) + data |= (0x0001 << 14); + else + data &= ~(0x0001 << 14); + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, data)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_get + * Description: + * Get Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * Output: + * pEnable - Loopback state, 0:disable, 1:enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortLoopback(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyReg_set + * Description: + * Set PHY register data of the specific port. + * Input: + * port - port id. + * reg - Register id + * regData - Register data + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can set PHY register data of the specific port. + */ +rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t regData) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), reg, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyReg_get + * Description: + * Get PHY register data of the specific port. + * Input: + * port - Port id. + * reg - Register id + * Output: + * pData - Register data + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can get PHY register data of the specific port. + */ +rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), reg, pData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_backpressureEnable_set + * Description: + * Set the half duplex backpressure enable status of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE(Defer) + * - ENABLE (Backpressure) + */ +rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortJamMode(!enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_backpressureEnable_get + * Description: + * Get the half duplex backpressure enable status of the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE(Defer) + * - ENABLE (Backpressure) + */ +rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortJamMode(®Data)) != RT_ERR_OK) + return retVal; + + *pEnable = !regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_adminEnable_set + * Description: + * Set port admin configuration of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + { + data &= 0xF7FF; + data |= 0x0200; + } + else if (DISABLED == enable) + { + data |= 0x0800; + } + + if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_adminEnable_get + * Description: + * Get port admin configurationof the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if ( (data & 0x0800) == 0x0800) + { + *pEnable = DISABLED; + } + else + { + *pEnable = ENABLED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_isolation_set + * Description: + * Set permitted port isolation portmask + * Input: + * port - port id. + * pPortmask - Permit port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * This API set the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + /* check port mask */ + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_isolation_get + * Description: + * Get permitted port isolation portmask + * Input: + * port - Port id. + * Output: + * pPortmask - Permit port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API get the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rgmiiDelayExt_set + * Description: + * Set RGMII interface delay value for TX and RX. + * Input: + * txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay + * rxDelay - RX delay value, 0~7 for delay setup. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for no-delay, and 7 for maximum delay. + */ +rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay) +{ + rtk_api_ret_t retVal; + rtk_uint32 regAddr, regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if ((txDelay > 1) || (rxDelay > 7)) + return RT_ERR_INPUT; + + if(port == EXT_PORT0) + regAddr = RTL8367C_REG_EXT1_RGMXF; + else if(port == EXT_PORT1) + regAddr = RTL8367C_REG_EXT2_RGMXF; + else + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + regData = (regData & 0xFFF0) | ((txDelay << 3) & 0x0008) | (rxDelay & 0x0007); + + if ((retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rgmiiDelayExt_get + * Description: + * Get RGMII interface delay value for TX and RX. + * Input: + * None + * Output: + * pTxDelay - TX delay value + * pRxDelay - RX delay value + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for n0-delay, and 7 for maximum delay. + */ +rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay) +{ + rtk_api_ret_t retVal; + rtk_uint32 regAddr, regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if( (NULL == pTxDelay) || (NULL == pRxDelay) ) + return RT_ERR_NULL_POINTER; + + if(port == EXT_PORT0) + regAddr = RTL8367C_REG_EXT1_RGMXF; + else if(port == EXT_PORT1) + regAddr = RTL8367C_REG_EXT2_RGMXF; + else + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pTxDelay = (regData & 0x0008) >> 3; + *pRxDelay = regData & 0x0007; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyEnableAll_set + * Description: + * Set all PHY enable status. + * Input: + * enable - PHY Enable State. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + rtk_uint32 port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortEnableAll(enable)) != RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + { + data &= 0xF7FF; + data |= 0x0200; + } + else + { + data |= 0x0800; + } + + if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_port_phyEnableAll_get + * Description: + * Get all PHY enable status. + * Input: + * None + * Output: + * pEnable - PHY Enable State. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_phyEnableAll_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortEnableAll(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_efid_set + * Description: + * Set port-based enhanced filtering database + * Input: + * port - Port id. + * efid - Specified enhanced filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based enhanced filtering database. + */ +rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* efid must be 0~7 */ + if (efid > RTK_EFID_MAX) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), efid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_efid_get + * Description: + * Get port-based enhanced filtering database + * Input: + * port - Port id. + * Output: + * pEfid - Specified enhanced filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based enhanced filtering database status. + */ +rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEfid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), pEfid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyComboPortMedia_set + * Description: + * Set Combo port media type + * Input: + * port - Port id. + * media - Media (COPPER or FIBER) + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + rtk_uint32 idx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + /* Check Combo Port ID */ + RTK_CHK_PORT_IS_COMBO(port); + + if (media >= PORT_MEDIA_END) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + if(regData != 0x6367) + return RT_ERR_CHIP_NOT_SUPPORTED; + + if(media == PORT_MEDIA_FIBER) + { + /* software init */ + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + for(idx = 0; idx < FIBER_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber[idx])) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, 1))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_DW8051_READY_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyComboPortMedia_get + * Description: + * Get Combo port media type + * Input: + * port - Port id. + * Output: + * pMedia - Media (COPPER or FIBER) + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + /* Check Combo Port ID */ + RTK_CHK_PORT_IS_COMBO(port); + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + if(regData != 0x6367) + { + *pMedia = PORT_MEDIA_COPPER; + } + else + { + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, &data))!=RT_ERR_OK) + return retVal; + + if(data == 1) + *pMedia = PORT_MEDIA_COPPER; + else + *pMedia = PORT_MEDIA_FIBER; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rtctEnable_set + * Description: + * Enable RTCT test + * Input: + * pPortmask - Port mask of RTCT enabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can enable RTCT Test + */ +rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Mask Valid */ + RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); + + if ((retVal = rtl8367c_setAsicPortRTCTEnable(pPortmask->bits[0]))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rtctDisable_set + * Description: + * Disable RTCT test + * Input: + * pPortmask - Port mask of RTCT disabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can disable RTCT Test + */ +rtk_api_ret_t rtk_port_rtctDisable_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Mask Valid */ + RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); + + if ((retVal = rtl8367c_setAsicPortRTCTDisable(pPortmask->bits[0]))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_port_rtctResult_get + * Description: + * Get the result of RTCT test + * Input: + * port - Port ID + * Output: + * pRtctResult - The result of RTCT result + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_PHY_RTCT_NOT_FINISH - Testing does not finish. + * Note: + * The API can get RTCT test result. + * RTCT test may takes 4.8 seconds to finish its test at most. + * Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or + * other error code, the result can not be referenced and + * user should call this API again until this API returns + * a RT_ERR_OK. + * The result is stored at pRtctResult->ge_result + * pRtctResult->linkType is unused. + * The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M + */ +rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult) +{ + rtk_api_ret_t retVal; + rtl8367c_port_rtct_result_t result; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + memset(pRtctResult, 0x00, sizeof(rtk_rtctResult_t)); + if ((retVal = rtl8367c_getAsicPortRTCTResult(port, &result))!=RT_ERR_OK) + return retVal; + + pRtctResult->result.ge_result.channelALen = result.channelALen; + pRtctResult->result.ge_result.channelBLen = result.channelBLen; + pRtctResult->result.ge_result.channelCLen = result.channelCLen; + pRtctResult->result.ge_result.channelDLen = result.channelDLen; + + pRtctResult->result.ge_result.channelALinedriver = result.channelALinedriver; + pRtctResult->result.ge_result.channelBLinedriver = result.channelBLinedriver; + pRtctResult->result.ge_result.channelCLinedriver = result.channelCLinedriver; + pRtctResult->result.ge_result.channelDLinedriver = result.channelDLinedriver; + + pRtctResult->result.ge_result.channelAMismatch = result.channelAMismatch; + pRtctResult->result.ge_result.channelBMismatch = result.channelBMismatch; + pRtctResult->result.ge_result.channelCMismatch = result.channelCMismatch; + pRtctResult->result.ge_result.channelDMismatch = result.channelDMismatch; + + pRtctResult->result.ge_result.channelAOpen = result.channelAOpen; + pRtctResult->result.ge_result.channelBOpen = result.channelBOpen; + pRtctResult->result.ge_result.channelCOpen = result.channelCOpen; + pRtctResult->result.ge_result.channelDOpen = result.channelDOpen; + + pRtctResult->result.ge_result.channelAShort = result.channelAShort; + pRtctResult->result.ge_result.channelBShort = result.channelBShort; + pRtctResult->result.ge_result.channelCShort = result.channelCShort; + pRtctResult->result.ge_result.channelDShort = result.channelDShort; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_sds_reset + * Description: + * Reset Serdes + * Input: + * port - Port ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + ext_id = port - 15; + return rtl8367c_sdsReset(ext_id); +} + +/* Function Name: + * rtk_port_sgmiiLinkStatus_get + * Description: + * Get SGMII status + * Input: + * port - Port ID + * Output: + * pSignalDetect - Signal detect + * pSync - Sync + * pLink - Link + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +rtk_api_ret_t rtk_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + if(NULL == pSignalDetect) + return RT_ERR_NULL_POINTER; + + if(NULL == pSync) + return RT_ERR_NULL_POINTER; + + if(NULL == pLink) + return RT_ERR_NULL_POINTER; + + ext_id = port - 15; + return rtl8367c_getSdsLinkStatus(ext_id, (rtk_uint32 *)pSignalDetect, (rtk_uint32 *)pSync, (rtk_uint32 *)pLink); +} + +/* Function Name: + * rtk_port_sgmiiNway_set + * Description: + * Configure SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * state - Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API configure SGMII/HSGMII port Nway state + */ +rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + if(state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + ext_id = port - 15; + return rtl8367c_setSgmiiNway(ext_id, (rtk_uint32)state); +} + +/* Function Name: + * rtk_port_sgmiiNway_get + * Description: + * Get SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * Output: + * pState - Nway state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get SGMII/HSGMII port Nway state + */ +rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + if(NULL == pState) + return RT_ERR_NULL_POINTER; + + ext_id = port - 15; + return rtl8367c_getSgmiiNway(ext_id, (rtk_uint32 *)pState); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/ptp.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/ptp.c new file mode 100755 index 00000000..40962a0e --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/ptp.c @@ -0,0 +1,759 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 39583 $ + * $Date: 2013-05-20 16:59:23 +0800 (星期一, 20 五月 2013) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in time module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_ptp_init + * Description: + * PTP function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize PTP status. + */ +rtk_api_ret_t rtk_ptp_init(void) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_mac_set + * Description: + * Configure PTP mac address. + * Input: + * mac - mac address to parser PTP packets. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac) +{ + rtk_api_ret_t retVal; + ether_addr_t sw_mac; + + memcpy(sw_mac.octet, mac.octet, ETHER_ADDR_LEN); + + if((retVal=rtl8367c_setAsicEavMacAddress(sw_mac))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_mac_get + * Description: + * Get PTP mac address. + * Input: + * None + * Output: + * pMac - mac address to parser PTP packets. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac) +{ + rtk_api_ret_t retVal; + ether_addr_t sw_mac; + + if((retVal=rtl8367c_getAsicEavMacAddress(&sw_mac))!=RT_ERR_OK) + return retVal; + + memcpy(pMac->octet, sw_mac.octet, ETHER_ADDR_LEN); + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_tpid_set + * Description: + * Configure PTP accepted outer & inner tag TPID. + * Input: + * outerId - Ether type of S-tag frame parsing in PTP ports. + * innerId - Ether type of C-tag frame parsing in PTP ports. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((outerId>RTK_MAX_NUM_OF_TPID) ||(innerId>RTK_MAX_NUM_OF_TPID)) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavTpid(outerId, innerId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_tpid_get + * Description: + * Get PTP accepted outer & inner tag TPID. + * Input: + * None + * Output: + * pOuterId - Ether type of S-tag frame parsing in PTP ports. + * pInnerId - Ether type of C-tag frame parsing in PTP ports. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicEavTpid(pOuterId, pInnerId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTime_set + * Description: + * Set the reference time of the specified device. + * Input: + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavSysTime(timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTime_get + * Description: + * Get the reference time of the specified device. + * Input: + * Output: + * pTimeStamp - pointer buffer of the reference time + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicEavSysTime(&pTimeStamp->sec, &pTimeStamp->nsec))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTimeAdjust_set + * Description: + * Adjust the reference time. + * Input: + * unit - unit id + * sign - significant + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * sign=0 for positive adjustment, sign=1 for negative adjustment. + */ +rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavSysTimeAdjust(sign, timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTimeEnable_set + * Description: + * Set the enable state of reference time of the specified device. + * Input: + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTimeEnable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicEavSysTimeCtrl(enable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTimeEnable_get + * Description: + * Get the enable state of reference time of the specified device. + * Input: + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicEavSysTimeCtrl(pEnable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_portEnable_set + * Description: + * Set PTP status of the specified port. + * Input: + * port - port id + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is PTP port */ + RTK_CHK_PORT_IS_PTP(port); + + if (enable>=RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavPortEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_portEnable_get + * Description: + * Get PTP status of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is PTP port */ + RTK_CHK_PORT_IS_PTP(port); + + if ((retVal = rtl8367c_getAsicEavPortEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_ptp_portTimestamp_get + * Description: + * Get PTP timstamp according to the PTP identifier on the dedicated port from the specified device. + * Input: + * unit - unit id + * port - port id + * type - PTP message type + * Output: + * pInfo - pointer buffer of sequence ID and timestamp + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo) +{ + rtk_api_ret_t retVal; + rtl8367c_ptp_time_stamp_t time; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is PTP port */ + RTK_CHK_PORT_IS_PTP(port); + + if ((retVal = rtl8367c_getAsicEavPortTimeStamp(rtk_switch_port_L2P_get(port), type, &time)) != RT_ERR_OK) + return retVal; + + pInfo->sequenceId = time.sequence_id; + pInfo->timeStamp.sec = time.second; + pInfo->timeStamp.nsec = time.nano_second; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_intControl_set + * Description: + * Set PTP interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set PTP interrupt status configuration. + * The interrupt trigger status is shown in the following: + * PTP_INT_TYPE_TX_SYNC = 0, + * PTP_INT_TYPE_TX_DELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_RESP, + * PTP_INT_TYPE_RX_SYNC, + * PTP_INT_TYPE_RX_DELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_RESP, + * PTP_INT_TYPE_ALL, + */ +rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 mask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type>=PTP_INT_TYPE_END) + return RT_ERR_INPUT; + + if (PTP_INT_TYPE_ALL!=type) + { + if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + mask = mask | (1<=PTP_INT_TYPE_ALL) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) + return retVal; + + if (0 == (mask&(1<=RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavTrap(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_portPtpEnable_get + * Description: + * Get PTP packet trap of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portTrap_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicEavTrap(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/qos.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/qos.c new file mode 100755 index 00000000..70067a30 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/qos.c @@ -0,0 +1,1452 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in QoS module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Function Name: + * rtk_qos_init + * Description: + * Configure Qos default settings with queue number assigment to each port. + * Input: + * queueNum - Queue number of each port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API will initialize related Qos setting with queue number assigment. + * The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum) +{ + CONST_T rtk_uint16 g_prioritytToQid[8][8]= { + {0, 0,0,0,0,0,0,0}, + {0, 0,0,0,7,7,7,7}, + {0, 0,0,0,1,1,7,7}, + {0, 0,1,1,2,2,7,7}, + {0, 0,1,1,2,3,7,7}, + {0, 0,1,2,3,4,7,7}, + {0, 0,1,2,3,4,5,7}, + {0,1,2,3,4,5,6,7} + }; + + CONST_T rtk_uint32 g_priorityDecision[8] = {0x01, 0x80,0x04,0x02,0x20,0x40,0x10,0x08}; + CONST_T rtk_uint32 g_prioritytRemap[8] = {0,1,2,3,4,5,6,7}; + + rtk_api_ret_t retVal; + rtk_uint32 qmapidx; + rtk_uint32 priority; + rtk_uint32 priDec; + rtk_uint32 port; + rtk_uint32 dscp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (queueNum <= 0 || queueNum > RTK_MAX_NUM_OF_QUEUE) + return RT_ERR_QUEUE_NUM; + + /*Set Output Queue Number*/ + if (RTK_MAX_NUM_OF_QUEUE == queueNum) + qmapidx = 0; + else + qmapidx = queueNum; + + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(port, qmapidx)) != RT_ERR_OK) + return retVal; + } + + /*Set Priority to Qid*/ + for (priority = 0; priority <= RTK_PRIMAX; priority++) + { + if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queueNum - 1, priority, g_prioritytToQid[queueNum - 1][priority])) != RT_ERR_OK) + return retVal; + } + + /*Set Flow Control Type to Ingress Flow Control*/ + if ((retVal = rtl8367c_setAsicFlowControlSelect(FC_INGRESS)) != RT_ERR_OK) + return retVal; + + + /*Priority Decision Order*/ + for (priDec = 0;priDec < PRIDEC_END;priDec++) + { + if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX0, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX1, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) + return retVal; + } + + /*Set Port-based Priority to 0*/ + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicPriorityPortBased(port, 0)) != RT_ERR_OK) + return retVal; + } + + /*Disable 1p Remarking*/ + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(port, DISABLED)) != RT_ERR_OK) + return retVal; + } + + /*Disable DSCP Remarking*/ + if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(DISABLED)) != RT_ERR_OK) + return retVal; + + /*Set 1p & DSCP Priority Remapping & Remarking*/ + for (priority = 0; priority <= RTL8367C_PRIMAX; priority++) + { + if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(priority, g_prioritytRemap[priority])) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(priority, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(priority, 0)) != RT_ERR_OK) + return retVal; + } + + /*Set DSCP Priority*/ + for (dscp = 0; dscp <= 63; dscp++) + { + if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, 0)) != RT_ERR_OK) + return retVal; + } + + /* Finetune B/T value */ + if((retVal = rtl8367c_setAsicReg(0x1722, 0x1158)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priSel_set + * Description: + * Configure the priority order among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter. + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT + * - PRIDEC_ACL + * - PRIDEC_DSCP + * - PRIDEC_1Q + * - PRIDEC_1AD + * - PRIDEC_CVLAN + * - PRIDEC_DA + * - PRIDEC_SA + */ +rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) +{ + rtk_api_ret_t retVal; + rtk_uint32 port_pow; + rtk_uint32 dot1q_pow; + rtk_uint32 dscp_pow; + rtk_uint32 acl_pow; + rtk_uint32 svlan_pow; + rtk_uint32 cvlan_pow; + rtk_uint32 smac_pow; + rtk_uint32 dmac_pow; + rtk_uint32 i; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index < 0 || index >= PRIDECTBL_END) + return RT_ERR_ENTRY_INDEX; + + if (pPriDec->port_pri >= 8 || pPriDec->dot1q_pri >= 8 || pPriDec->acl_pri >= 8 || pPriDec->dscp_pri >= 8 || + pPriDec->cvlan_pri >= 8 || pPriDec->svlan_pri >= 8 || pPriDec->dmac_pri >= 8 || pPriDec->smac_pri >= 8) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + port_pow = 1; + for (i = pPriDec->port_pri; i > 0; i--) + port_pow = (port_pow)*2; + + dot1q_pow = 1; + for (i = pPriDec->dot1q_pri; i > 0; i--) + dot1q_pow = (dot1q_pow)*2; + + acl_pow = 1; + for (i = pPriDec->acl_pri; i > 0; i--) + acl_pow = (acl_pow)*2; + + dscp_pow = 1; + for (i = pPriDec->dscp_pri; i > 0; i--) + dscp_pow = (dscp_pow)*2; + + svlan_pow = 1; + for (i = pPriDec->svlan_pri; i > 0; i--) + svlan_pow = (svlan_pow)*2; + + cvlan_pow = 1; + for (i = pPriDec->cvlan_pri; i > 0; i--) + cvlan_pow = (cvlan_pow)*2; + + dmac_pow = 1; + for (i = pPriDec->dmac_pri; i > 0; i--) + dmac_pow = (dmac_pow)*2; + + smac_pow = 1; + for (i = pPriDec->smac_pri; i > 0; i--) + smac_pow = (smac_pow)*2; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_PORT, port_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_ACL, acl_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DSCP, dscp_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1Q, dot1q_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1AD, svlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_CVLAN, cvlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DA, dmac_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_SA, smac_pow)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priSel_get + * Description: + * Get the priority order configuration among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * Output: + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision . + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT, + * - PRIDEC_ACL, + * - PRIDEC_DSCP, + * - PRIDEC_1Q, + * - PRIDEC_1AD, + * - PRIDEC_CVLAN, + * - PRIDEC_DA, + * - PRIDEC_SA, + */ +rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) +{ + + rtk_api_ret_t retVal; + rtk_int32 i; + rtk_uint32 port_pow; + rtk_uint32 dot1q_pow; + rtk_uint32 dscp_pow; + rtk_uint32 acl_pow; + rtk_uint32 svlan_pow; + rtk_uint32 cvlan_pow; + rtk_uint32 smac_pow; + rtk_uint32 dmac_pow; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index < 0 || index >= PRIDECTBL_END) + return RT_ERR_ENTRY_INDEX; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_PORT, &port_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_ACL, &acl_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DSCP, &dscp_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1Q, &dot1q_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1AD, &svlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_CVLAN, &cvlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DA, &dmac_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_SA, &smac_pow)) != RT_ERR_OK) + return retVal; + + for (i = 31; i >= 0; i--) + { + if (port_pow & (1 << i)) + { + pPriDec->port_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (dot1q_pow & (1 << i)) + { + pPriDec->dot1q_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (acl_pow & (1 << i)) + { + pPriDec->acl_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (dscp_pow & (1 << i)) + { + pPriDec->dscp_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (svlan_pow & (1 << i)) + { + pPriDec->svlan_pri = i; + break; + } + } + + for (i = 31;i >= 0; i--) + { + if (cvlan_pow & (1 << i)) + { + pPriDec->cvlan_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (dmac_pow&(1<dmac_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (smac_pow & (1 << i)) + { + pPriDec->smac_pri = i; + break; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pPriRemap_set + * Description: + * Configure 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dot1p_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(dot1p_pri, int_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pPriRemap_get + * Description: + * Get 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value . + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assigment for internal asic priority, and it is uesed for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dot1p_pri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicPriorityDot1qRemapping(dot1p_pri, pInt_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpPriRemap_set + * Description: + * Map dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * int_pri - internal priority value . + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if (dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, int_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpPriRemap_get + * Description: + * Get dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_getAsicPriorityDscpBased(dscp, pInt_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPri_set + * Description: + * Configure priority usage to each port. + * Input: + * port - Port id. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_SEL_PORT_PRI - Invalid port priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_setAsicPriorityPortBased(rtk_switch_port_L2P_get(port), int_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPri_get + * Description: + * Get priority usage to each port. + * Input: + * port - Port id. + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicPriorityPortBased(rtk_switch_port_L2P_get(port), pInt_pri)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_queueNum_set + * Description: + * Set output queue number for each port. + * Input: + * port - Port id. + * index - Mapping queue number (1~8) + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can set the output queue number of the specified port. The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) + return RT_ERR_FAILED; + + if (RTK_MAX_NUM_OF_QUEUE == queue_num) + queue_num = 0; + + if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), queue_num)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_queueNum_get + * Description: + * Get output queue number. + * Input: + * port - Port id. + * Output: + * pQueue_num - Mapping queue number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API will return the output queue number of the specified port. The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num) +{ + rtk_api_ret_t retVal; + rtk_uint32 qidx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), &qidx)) != RT_ERR_OK) + return retVal; + + if (0 == qidx) + *pQueue_num = 8; + else + *pQueue_num = qidx; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priMap_set + * Description: + * Set output queue number for each port. + * Input: + * queue_num - Queue number usage. + * pPri2qid - Priority mapping to queue ID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_QUEUE_ID - Invalid queue id. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * ASIC supports priority mapping to queue with different queue number from 1 to 8. + * For different queue numbers usage, ASIC supports different internal available queue IDs. + */ +rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) +{ + rtk_api_ret_t retVal; + rtk_uint32 pri; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) + return RT_ERR_QUEUE_NUM; + + for (pri = 0; pri <= RTK_PRIMAX; pri++) + { + if (pPri2qid->pri2queue[pri] > RTK_QIDMAX) + return RT_ERR_QUEUE_ID; + + if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queue_num - 1, pri, pPri2qid->pri2queue[pri])) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priMap_get + * Description: + * Get priority to queue ID mapping table parameters. + * Input: + * queue_num - Queue number usage. + * Output: + * pPri2qid - Priority mapping to queue ID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can return the mapping queue id of the specified priority and queue number. + * The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) +{ + rtk_api_ret_t retVal; + rtk_uint32 pri; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) + return RT_ERR_QUEUE_NUM; + + for (pri = 0; pri <= RTK_PRIMAX; pri++) + { + if ((retVal = rtl8367c_getAsicPriorityToQIDMappingTable(queue_num-1, pri, &pPri2qid->pri2queue[pri])) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_schedulingQueue_set + * Description: + * Set weight and type of queues in dedicated port. + * Input: + * port - Port id. + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight. + * Note: + * The API can set weight and type, strict priority or weight fair queue (WFQ) for + * dedicated port for using queues. If queue id is not included in queue usage, + * then its type and weight setting in dummy for setting. There are priorities + * as queue id in strict queues. It means strict queue id 5 carrying higher priority + * than strict queue id 4. The WFQ queue weight is from 1 to 127, and weight 0 is + * for strict priority queue type. + */ +rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) +{ + rtk_api_ret_t retVal; + rtk_uint32 qid; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + for (qid = 0; qid < RTL8367C_QUEUENO; qid ++) + { + + if (pQweights->weights[qid] > QOS_WEIGHT_MAX) + return RT_ERR_QOS_QUEUE_WEIGHT; + + if (0 == pQweights->weights[qid]) + { + if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_STRICT)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_WFQ)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicWFQWeight(rtk_switch_port_L2P_get(port),qid, pQweights->weights[qid])) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_schedulingQueue_get + * Description: + * Get weight and type of queues in dedicated port. + * Input: + * port - Port id. + * Output: + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get weight and type, strict priority or weight fair queue (WFQ) for dedicated port for using queues. + * The WFQ queue weight is from 1 to 127, and weight 0 is for strict priority queue type. + */ +rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) +{ + rtk_api_ret_t retVal; + rtk_uint32 qid,qtype,qweight; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + for (qid = 0; qid < RTL8367C_QUEUENO; qid++) + { + if ((retVal = rtl8367c_getAsicQueueType(rtk_switch_port_L2P_get(port), qid, &qtype)) != RT_ERR_OK) + return retVal; + + if (QTYPE_STRICT == qtype) + { + pQweights->weights[qid] = 0; + } + else if (QTYPE_WFQ == qtype) + { + if ((retVal = rtl8367c_getAsicWFQWeight(rtk_switch_port_L2P_get(port), qid, &qweight)) != RT_ERR_OK) + return retVal; + pQweights->weights[qid] = qweight; + } + } + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkEnable_set + * Description: + * Set 1p Remarking state + * Input: + * port - Port id. + * enable - State of per-port 1p Remarking + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable 802.1p remarking ability for whole system. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_1pRemarkEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkEnable_get + * Description: + * Get 802.1p remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - Status of 802.1p remark. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1p remarking ability. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_1pRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemark_set + * Description: + * Set 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * dot1p_pri - 802.1p priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set 802.1p parameters source priority and new priority. + */ +rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if (dot1p_pri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(int_pri, dot1p_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemark_get + * Description: + * Get 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * pDot1p_pri - 802.1p priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get 802.1p remarking parameters. It would return new priority of ingress priority. + */ +rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicRemarkingDot1pParameter(int_pri, pDot1p_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_set + * Description: + * Set remarking source of 802.1p remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure 802.1p remark functionality to map original 802.1p value or internal + * priority to TX DSCP value. + */ +rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= DOT1P_RMK_SRC_END ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pSrc(type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_get + * Description: + * Get remarking source of 802.1p remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRemarkingDot1pSrc(pType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_qos_dscpRemarkEnable_set + * Description: + * Set DSCP remarking ability. + * Input: + * port - Port id. + * enable - status of DSCP remark. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable DSCP remarking ability for whole system. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /*for whole system function, the port value should be 0xFF*/ + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemarkEnable_get + * Description: + * Get DSCP remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - status of DSCP remarking. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get DSCP remarking ability. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /*for whole system function, the port value should be 0xFF*/ + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if ((retVal = rtl8367c_getAsicRemarkingDscpAbility(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemark_set + * Description: + * Set DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * dscp - DSCP value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The API can set DSCP value and mapping priority. + */ +rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTK_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if (dscp > RTK_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(int_pri, dscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_qos_dscpRemark_get + * Description: + * Get DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * Dscp - DSCP value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get DSCP parameters. It would return DSCP value for mapping priority. + */ +rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTK_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicRemarkingDscpParameter(int_pri, pDscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemarkSrcSel_set + * Description: + * Set remarking source of DSCP remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure DSCP remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= DSCP_RMK_SRC_END ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_setAsicRemarkingDscpSrc(type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dcpRemarkSrcSel_get + * Description: + * Get remarking source of DSCP remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRemarkingDscpSrc(pType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_set + * Description: + * Set DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * rmkDscp - remarked DSCP value + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * Note: + * dscp parameter can be DSCP value or internal priority according to configuration of API + * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP + * value or internal priority to TX DSCP value. + */ +rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((dscp > RTK_DSCPMAX) || (rmkDscp > RTK_DSCPMAX)) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_setAsicRemarkingDscp2Dscp(dscp, rmkDscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_get + * Description: + * Get DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * Output: + * pDscp - remarked DSCP value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None. + */ +rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dscp > RTK_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_getAsicRemarkingDscp2Dscp(dscp, pDscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPriSelIndex_set + * Description: + * Configure priority decision index to each port. + * Input: + * port - Port id. + * index - priority decision index. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENTRY_INDEX - Invalid entry index. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (index >= PRIDECTBL_END ) + return RT_ERR_ENTRY_INDEX; + + if ((retVal = rtl8367c_setAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), index)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPriSelIndex_get + * Description: + * Get priority decision index from each port. + * Input: + * port - Port id. + * Output: + * pIndex - priority decision index. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), pIndex)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rate.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rate.c new file mode 100755 index 00000000..a077e0c5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rate.c @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in rate module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Function Name: + * rtk_rate_shareMeter_set + * Description: + * Set meter configuration + * Input: + * index - shared meter index + * type - shared meter type + * rate - rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_RATE - Invalid rate + * RT_ERR_INPUT - Invalid input parameters + * Note: + * The API can set shared meter rate and ifg include for each meter. + * The rate unit is 1 kbps and the range is from 8k to 1048568k if type is METER_TYPE_KBPS and + * the granularity of rate is 8 kbps. + * The rate unit is packets per second and the range is 1 ~ 0x1FFF if type is METER_TYPE_PPS. + * The ifg_include parameter is used + * for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_shareMeter_set(rtk_meter_id_t index, rtk_meter_type_t type, rtk_rate_t rate, rtk_enable_t ifg_include) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if (type >= METER_TYPE_END) + return RT_ERR_INPUT; + + if (ifg_include >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + switch (type) + { + case METER_TYPE_KBPS: + if (rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG || rate < RTL8367C_QOS_RATE_INPUT_MIN) + return RT_ERR_RATE ; + + if ((retVal = rtl8367c_setAsicShareMeter(index, rate >> 3, ifg_include)) != RT_ERR_OK) + return retVal; + + break; + case METER_TYPE_PPS: + if (rate > RTL8367C_QOS_PPS_INPUT_MAX || rate < RTL8367C_QOS_PPS_INPUT_MIN) + return RT_ERR_RATE ; + + if ((retVal = rtl8367c_setAsicShareMeter(index, rate, ifg_include)) != RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_INPUT; + } + + /* Set Type */ + if ((retVal = rtl8367c_setAsicShareMeterType(index, (rtk_uint32)type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_shareMeter_get + * Description: + * Get meter configuration + * Input: + * index - shared meter index + * Output: + * pType - Meter Type + * pRate - pointer of rate of share meter + * pIfg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_shareMeter_get(rtk_meter_id_t index, rtk_meter_type_t *pType, rtk_rate_t *pRate, rtk_enable_t *pIfg_include) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if(NULL == pRate) + return RT_ERR_NULL_POINTER; + + if(NULL == pIfg_include) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicShareMeter(index, ®Data, pIfg_include)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicShareMeterType(index, (rtk_uint32 *)pType)) != RT_ERR_OK) + return retVal; + + if(*pType == METER_TYPE_KBPS) + *pRate = regData<<3; + else + *pRate = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_shareMeterBucket_set + * Description: + * Set meter Bucket Size + * Input: + * index - shared meter index + * bucket_size - Bucket Size + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Error Input + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can set shared meter bucket size. + */ +rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(bucket_size > RTL8367C_METERBUCKETSIZEMAX) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicShareMeterBucketSize(index, bucket_size)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_shareMeterBucket_get + * Description: + * Get meter Bucket Size + * Input: + * index - shared meter index + * Output: + * pBucket_size - Bucket Size + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can get shared meter bucket size. + */ +rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(NULL == pBucket_size) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicShareMeterBucketSize(index, pBucket_size)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_set + * Description: + * Set port ingress bandwidth control + * Input: + * port - Port id + * rate - Rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * fc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid IFG parameter. + * RT_ERR_INBW_RATE - Invalid ingress rate parameter. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_set(rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include, rtk_enable_t fc_enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(ifg_include >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(fc_enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(rtk_switch_isHsgPort(port) == RT_ERR_OK) + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + else + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + + if ((retVal = rtl8367c_setAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), rate>>3, ifg_include,fc_enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_get + * Description: + * Get port ingress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of share meter + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * pFc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include, rtk_enable_t *pFc_enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pIfg_include) + return RT_ERR_NULL_POINTER; + + if(NULL == pFc_enable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), ®Data, pIfg_include, pFc_enable)) != RT_ERR_OK) + return retVal; + + *pRate = regData<<3; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_set + * Description: + * Set port egress bandwidth control + * Input: + * port - Port id + * rate - Rate of egress bandwidth + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_EBW_RATE - Invalid egress bandwidth/rate + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(rtk_switch_isHsgPort(port) == RT_ERR_OK) + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + else + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + + if (ifg_include >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortEgressRate(rtk_switch_port_L2P_get(port), rate>>3)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortEgressRateIfg(ifg_include)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_get + * Description: + * Get port egress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of egress bandwidth + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pRate) + return RT_ERR_NULL_POINTER; + + if(NULL == pIfg_include) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortEgressRate(rtk_switch_port_L2P_get(port), ®Data)) != RT_ERR_OK) + return retVal; + + *pRate = regData << 3; + + if ((retVal = rtl8367c_getAsicPortEgressRateIfg((rtk_uint32*)pIfg_include)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rate_egrQueueBwCtrlEnable_get + * Description: + * Get enable status of egress bandwidth control on specified queue. + * Input: + * unit - unit id + * port - port id + * queue - queue id + * Output: + * pEnable - Pointer to enable status of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /*for whole port function, the queue value should be 0xFF*/ + if (queue != RTK_WHOLE_SYSTEM) + return RT_ERR_QUEUE_ID; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicAprEnable(rtk_switch_port_L2P_get(port),pEnable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrQueueBwCtrlEnable_set + * Description: + * Set enable status of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * enable - enable status of egress queue bandwidth control + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /*for whole port function, the queue value should be 0xFF*/ + if (queue != RTK_WHOLE_SYSTEM) + return RT_ERR_QUEUE_ID; + + if (enable>=RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicAprEnable(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_get + * Description: + * Get rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * pIndex - shared meter index + * Output: + * pRate - pointer to rate of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex) +{ + rtk_api_ret_t retVal; + rtk_uint32 offset_idx; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (queue >= RTK_MAX_NUM_OF_QUEUE) + return RT_ERR_QUEUE_ID; + + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + phy_port = rtk_switch_port_L2P_get(port); + if ((retVal=rtl8367c_getAsicAprMeter(phy_port, queue,&offset_idx))!=RT_ERR_OK) + return retVal; + + *pIndex = offset_idx + ((phy_port%4)*8); + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_set + * Description: + * Set rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * index - shared meter index + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index) +{ + rtk_api_ret_t retVal; + rtk_uint32 offset_idx; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (queue >= RTK_MAX_NUM_OF_QUEUE) + return RT_ERR_QUEUE_ID; + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + phy_port = rtk_switch_port_L2P_get(port); + if (index < ((phy_port%4)*8) || index > (7 + (phy_port%4)*8)) + return RT_ERR_FILTER_METER_ID; + + offset_idx = index - ((phy_port%4)*8); + + if ((retVal=rtl8367c_setAsicAprMeter(phy_port,queue,offset_idx))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rldp.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rldp.c new file mode 100755 index 00000000..d3ca0297 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rldp.c @@ -0,0 +1,468 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : Declaration of RLDP and RLPP API + * + * Feature : The file have include the following module and sub-modules + * 1) RLDP and RLPP configuration and status + * + */ + + +/* + * Include Files + */ +#include +#include +//#include +#include + +#include +#include + +/* + * Symbol Definition + */ + + +/* + * Data Declaration + */ + + +/* + * Macro Declaration + */ + + +/* + * Function Declaration + */ + +/* Module Name : RLDP */ + +/* Function Name: + * rtk_rldp_config_set + * Description: + * Set RLDP module configuration + * Input: + * pConfig - configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig) +{ + rtk_api_ret_t retVal; + ether_addr_t magic; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (pConfig->rldp_enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pConfig->trigger_mode >= RTK_RLDP_TRIGGER_END) + return RT_ERR_INPUT; + + if (pConfig->compare_type >= RTK_RLDP_CMPTYPE_END) + return RT_ERR_INPUT; + + if (pConfig->num_check >= RTK_RLDP_NUM_MAX) + return RT_ERR_INPUT; + + if (pConfig->interval_check >= RTK_RLDP_INTERVAL_MAX) + return RT_ERR_INPUT; + + if (pConfig->num_loop >= RTK_RLDP_NUM_MAX) + return RT_ERR_INPUT; + + if (pConfig->interval_loop >= RTK_RLDP_INTERVAL_MAX) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpTxPortmask(0x00))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpTxPortmask(pmsk))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldp(pConfig->rldp_enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpTriggerMode(pConfig->trigger_mode))!=RT_ERR_OK) + return retVal; + + memcpy(&magic, &pConfig->magic, sizeof(ether_addr_t)); + if ((retVal = rtl8367c_setAsicRldpMagicNum(magic))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpCheckingStatePara(pConfig->num_check, pConfig->interval_check))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpLoopStatePara(pConfig->num_loop, pConfig->interval_loop))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rldp_config_get + * Description: + * Get RLDP module configuration + * Input: + * None + * Output: + * pConfig - configuration structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig) +{ + rtk_api_ret_t retVal; + ether_addr_t magic; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRldp(&pConfig->rldp_enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpTriggerMode(&pConfig->trigger_mode))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpMagicNum(&magic))!=RT_ERR_OK) + return retVal; + memcpy(&pConfig->magic, &magic, sizeof(ether_addr_t)); + + if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpCheckingStatePara(&pConfig->num_check, &pConfig->interval_check))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpLoopStatePara(&pConfig->num_loop, &pConfig->interval_loop))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rldp_portConfig_set + * Description: + * Set per port RLDP module configuration + * Input: + * port - port number to be configured + * pPortConfig - per port configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (pPortConfig->tx_enable>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + phy_port = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + + if (pPortConfig->tx_enable) + { + pmsk |=(1<tx_enable = ENABLED; + } + else + { + pPortConfig->tx_enable = DISABLED; + } + + return RT_ERR_OK; +} /* end of rtk_rldp_portConfig_get */ + + +/* Function Name: + * rtk_rldp_status_get + * Description: + * Get RLDP module status + * Input: + * None + * Output: + * pStatus - status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus) +{ + rtk_api_ret_t retVal; + ether_addr_t seed; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRldpRandomNumber(&seed))!=RT_ERR_OK) + return retVal; + memcpy(&pStatus->id, &seed, sizeof(ether_addr_t)); + + return RT_ERR_OK; +} /* end of rtk_rldp_status_get */ + + +/* Function Name: + * rtk_rldp_portStatus_get + * Description: + * Get RLDP module status + * Input: + * port - port number to be get + * Output: + * pPortStatus - per port status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + rtk_portmask_t logicalPmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicRldpLoopedPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) + return retVal; + + if (logicalPmask.bits[0] & (1<loop_status = RTK_RLDP_LOOPSTS_LOOPING; + } + else + { + pPortStatus->loop_status = RTK_RLDP_LOOPSTS_NONE; + } + + if ((retVal = rtl8367c_getAsicRldpEnterLoopedPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) + return retVal; + + if (logicalPmask.bits[0] & (1<loop_enter = RTK_RLDP_LOOPSTS_LOOPING; + } + else + { + pPortStatus->loop_enter = RTK_RLDP_LOOPSTS_NONE; + } + + if ((retVal = rtl8367c_getAsicRldpLeaveLoopedPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) + return retVal; + + if (logicalPmask.bits[0] & (1<loop_leave = RTK_RLDP_LOOPSTS_LOOPING; + } + else + { + pPortStatus->loop_leave = RTK_RLDP_LOOPSTS_NONE; + } + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rldp_portStatus_clear + * Description: + * Clear RLDP module status + * Input: + * port - port number to be clear + * pPortStatus - per port status structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * Clear operation effect loop_enter and loop_leave only, other field in + * the structure are don't care. Loop status cab't be clean. + */ +rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + pmsk = (pPortStatus->loop_enter)<loop_leave)< +#include +#include "./include/rtk_switch.h" +#include "./include/vlan.h" +#include "./include/port.h" +#include "./include/rate.h" +#include "./include/rtk_hal.h" +#include "./include/l2.h" +#include "./include/stat.h" +#include "./include/igmp.h" +#include "./include/trap.h" +#include "./include/leaky.h" +#include "./include/mirror.h" +#include "./include/rtl8367c_asicdrv_port.h" +#include "./include/rtl8367c_asicdrv_mib.h" +#include "./include/smi.h" +#include "./include/qos.h" +#include "./include/trunk.h" + +void rtk_hal_switch_init(void) +{ + if(rtk_switch_init() != 0) + printk("rtk_switch_init failed\n"); + mdelay(500); + /*vlan init */ + if (rtk_vlan_init() != 0) + printk("rtk_vlan_init failed\n"); +} + +void rtk_hal_dump_full_mib(void) +{ + rtk_port_t port; + rtk_stat_counter_t Cntr; + rtk_stat_port_type_t cntr_idx; + + for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { + printk("\nPort%d\n", port); + for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu ", Cntr); + if (((cntr_idx%10) == 9)) + printk("\n"); + } + } + + for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { + printk("\nPort%d\n", port); + for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu ", Cntr); + if (((cntr_idx%10) == 9)) + printk("\n"); + } + } + rtk_stat_global_reset(); +} +void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) +{ + rtk_port_t port; + rtk_stat_counter_t Cntr; + + for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + printk("\n"); +} + +void rtk_hal_dump_mib(void) +{ + + printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", + "Port2", "Port3", "Port4", "Port16", "Port17"); + /* Get TX Unicast Pkts */ + printk("TX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfOutUcastPkts); + /* Get TX Multicast Pkts */ + printk("TX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfOutMulticastPkts); + /* Get TX BroadCast Pkts */ + printk("TX BroadCast Pkts:"); + rtk_dump_mib_type(STAT_IfOutBroadcastPkts); + /* Get TX Collisions */ + /* Get TX Puase Frames */ + printk("TX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3OutPauseFrames); + /* Get TX Drop Events */ + /* Get RX Unicast Pkts */ + printk("RX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfInUcastPkts); + /* Get RX Multicast Pkts */ + printk("RX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfInMulticastPkts); + /* Get RX Broadcast Pkts */ + printk("RX Broadcast Pkts:"); + rtk_dump_mib_type(STAT_IfInBroadcastPkts); + /* Get RX FCS Erros */ + printk("RX FCS Errors :"); + rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); + /* Get RX Undersize Pkts */ + printk("RX Undersize Pkts:"); + rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); + /* Get RX Discard Pkts */ + printk("RX Discard Pkts :"); + rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); + /* Get RX Fragments */ + printk("RX Fragments :"); + rtk_dump_mib_type(STAT_EtherStatsFragments); + /* Get RX Oversize Pkts */ + printk("RX Oversize Pkts :"); + rtk_dump_mib_type(STAT_EtherOversizeStats); + /* Get RX Jabbers */ + printk("RX Jabbers :"); + rtk_dump_mib_type(STAT_EtherStatsJabbers); + /* Get RX Pause Frames */ + printk("RX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3InPauseFrames); + /* clear MIB */ + rtk_stat_global_reset(); +} +EXPORT_SYMBOL(rtk_hal_dump_mib); + +int rtk_hal_dump_vlan(void) +{ + rtk_vlan_cfg_t vlan; + int i; + + printk("vid portmap\n"); + for (i = 0; i < RTK_SW_VID_RANGE; i++) { + rtk_vlan_get(i, &vlan); + printk("%3d ", i); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT1) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT2) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT3) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT4) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT1) ? '1' : '-'); + printk("\n"); + } + return 0; +} + +void rtk_hal_clear_vlan(void) +{ + rtk_api_ret_t ret; + + ret = rtk_vlan_reset(); + if (ret != RT_ERR_OK) + printk("rtk_vlan_reset failed\n"); +} + +int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data) +{ + rtk_vlan_cfg_t vlan; + rtk_api_ret_t ret; + int i; + + /* clear vlan entry first */ + memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); + RTK_PORTMASK_CLEAR(vlan.mbr); + RTK_PORTMASK_CLEAR(vlan.untag); + rtk_vlan_set(data->vid, &vlan); + + memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); + for (i = 0; i < 5; i++) { + if (data->port_map & (1 << i)) { + RTK_PORTMASK_PORT_SET(vlan.mbr, i); + RTK_PORTMASK_PORT_SET(vlan.untag, i); + rtk_vlan_portPvid_set(i, data->vid, 0); + } + } + for (i = 0; i < 2; i++) { + if (data->port_map & (1 << (i + 5))) { + RTK_PORTMASK_PORT_SET(vlan.mbr, (i + EXT_PORT0)); + RTK_PORTMASK_PORT_SET(vlan.untag, (i + EXT_PORT0)); + rtk_vlan_portPvid_set((i + EXT_PORT0), data->vid, 0); + } + } + vlan.ivl_en = 1; + ret = rtk_vlan_set(data->vid, &vlan); + + return 0; +} + +void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) +{ + rtk_vlan_portPvid_set(port, pvid, priority); +} + +int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + if (data->on_off == 1) + ret = + rtk_rate_igrBandwidthCtrlRate_set(data->port, data->bw, 0, + 1); + else + ret = + rtk_rate_igrBandwidthCtrlRate_set(data->port, 1048568, 0, + 1); + + return ret; +} + +int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + if (data->on_off == 1) + ret = + rtk_rate_egrBandwidthCtrlRate_set(data->port, data->bw, 1); + else + ret = rtk_rate_egrBandwidthCtrlRate_set(data->port, 1048568, 1); + + return ret; +} + +void rtk_hal_dump_table(void) +{ + rtk_uint32 i; + rtk_uint32 address = 0; + rtk_l2_ucastAddr_t l2_data; + rtk_l2_ipMcastAddr_t ipMcastAddr; + + printk("hash port(0:17) fid vid mac-address\n"); + while (1) { + if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { + break; + } else { + printk("%03x ", l2_data.address); + for (i = 0; i < 5; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + for (i = 16; i < 18; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + + printk(" %2d", l2_data.fid); + printk(" %4d", l2_data.cvid); + printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], + l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], + l2_data.mac.octet[4], l2_data.mac.octet[5]); + address ++; + } + } + + address = 0; + while (1) { + if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { + break; + } else { + printk("%03x ", ipMcastAddr.address); + for (i = 0; i < 5; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + for (i = 16; i < 18; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + printk(" "); + printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); + address ++; + } + } +} + +void rtk_hal_clear_table(void) +{ + rtk_api_ret_t ret; + + ret = rtk_l2_table_clear(); + if (ret != RT_ERR_OK) + printk("rtk_l2_table_clear failed\n"); +} + +void rtk_hal_add_table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_l2_ucastAddr_t l2_entry; + rtk_mac_t mac; + + mac.octet[0] =data->mac[0]; + mac.octet[1] =data->mac[1]; + mac.octet[2] =data->mac[2]; + mac.octet[3] =data->mac[3]; + mac.octet[4] =data->mac[4]; + mac.octet[5] =data->mac[5]; + + memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); + l2_entry.port = data->port; + l2_entry.ivl = 1; + l2_entry.cvid = data->vid; + l2_entry.fid = 0; + l2_entry.efid = 0; + l2_entry.is_static = 1; + ret = rtk_l2_addr_add(&mac, &l2_entry); + if (ret != RT_ERR_OK) + printk("rtk_hal_add_table failed\n"); +} + +void rtk_hal_del_table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_l2_ucastAddr_t l2_entry; + rtk_mac_t mac; + + mac.octet[0] =data->mac[0]; + mac.octet[1] =data->mac[1]; + mac.octet[2] =data->mac[2]; + mac.octet[3] =data->mac[3]; + mac.octet[4] =data->mac[4]; + mac.octet[5] =data->mac[5]; + + memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); + l2_entry.port = data->port; + l2_entry.ivl = 1; + l2_entry.cvid = data->vid; + l2_entry.fid = 0; + l2_entry.efid = 0; + ret = rtk_l2_addr_del(&mac, &l2_entry); + if (ret != RT_ERR_OK) + printk("rtk_hal_add_table failed\n"); +} +void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data) +{ + rtk_port_linkStatus_t linkStatus; + rtk_port_speed_t speed; + rtk_port_duplex_t duplex; + + rtk_port_phyStatus_get(data->port, &linkStatus, &speed, &duplex); + printk("Port%d Status:\n", data->port); + if (linkStatus == 1) { + printk("Link Up"); + if (speed == 0) + printk(" 10M"); + else if (speed == 1) + printk(" 100M"); + else if (speed == 2) + printk(" 1000M"); + if (duplex == 0) + printk(" Half Duplex\n"); + else + printk(" Full Duplex\n"); + } else + printk("Link Down\n"); + +} + +void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data) +{ + rtk_portmask_t rx_portmask; + rtk_portmask_t tx_portmask; + rtk_api_ret_t ret; + int i; + + rtk_mirror_portIso_set(ENABLED); + RTK_PORTMASK_CLEAR(rx_portmask); + RTK_PORTMASK_CLEAR(tx_portmask); + for (i = 0; i < 5; i++) + if (data->rx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(rx_portmask, i); + for (i = 0; i < 2; i++) + if (data->rx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); + + RTK_PORTMASK_CLEAR(tx_portmask); + for (i = 0; i < 5; i++) + if (data->tx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(tx_portmask, i); + for (i = 0; i < 2; i++) + if (data->tx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); + + ret = rtk_mirror_portBased_set(data->port, &rx_portmask, &tx_portmask); + if (!ret) + printk("rtk_mirror_portBased_set success\n"); +} + +void rtk_hal_read_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + + retVal = smi_read(data->reg_addr, &data->reg_val); + if(retVal != RT_ERR_OK) + printk("switch reg read failed\n"); + else + printk("reg0x%x = 0x%x\n", data->reg_addr, data->reg_val); +} + +void rtk_hal_write_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + + retVal = smi_write(data->reg_addr, data->reg_val); + if(retVal != RT_ERR_OK) + printk("switch reg write failed\n"); + else + printk("write switch reg0x%x 0x%x success\n", data->reg_addr, data->reg_val); +} + +void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + rtk_port_phy_data_t Data; + + retVal = rtk_port_phyReg_get(data->port, data->reg_addr, &Data); + if (retVal == RT_ERR_OK) + printk("Get: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, Data); + else + printk("read phy reg failed\n"); +} + +void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + + retVal = rtk_port_phyReg_set(data->port, data->reg_addr, data->reg_val); + if (retVal == RT_ERR_OK) + printk("Set: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, data->reg_val); + else + printk("write phy reg failed\n"); +} +void rtk_hal_qos_en(struct ra_switch_ioctl_data *data) +{ + + if (data->on_off == 1) { + if (rtk_qos_init(8) != 0) + printk("rtk_qos_init(8) failed\n"); + } + else { + if (rtk_qos_init(1) != 0) + printk("rtk_qos_init(1) failed\n"); + } +} + +void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_priority_select_t PriDec; + + /* write all pri to 0 */ + PriDec.port_pri = 0; + PriDec.dot1q_pri = 0; + PriDec.acl_pri = 0; + PriDec.cvlan_pri = 0; + PriDec.svlan_pri = 0; + PriDec.dscp_pri = 0; + PriDec.dmac_pri = 0; + PriDec.smac_pri = 0; + + if (data->qos_type == 0) + PriDec.port_pri = 1; + else if (data->qos_type == 1) + PriDec.dot1q_pri = 1; + else if (data->qos_type == 2) + PriDec.acl_pri = 1; + else if (data->qos_type == 3) + PriDec.dscp_pri = 1; + else if (data->qos_type == 4) + PriDec.cvlan_pri = 1; + else if (data->qos_type == 5) + PriDec.svlan_pri = 1; + else if (data->qos_type == 6) + PriDec.dmac_pri = 1; + else if (data->qos_type == 7) + PriDec.smac_pri = 1; + + if (data->qos_table_idx == 0) + ret = rtk_qos_priSel_set(PRIDECTBL_IDX0, &PriDec); + else + ret = rtk_qos_priSel_set(PRIDECTBL_IDX1, &PriDec); + + if (ret != 0) + printk("rtk_qos_priSel_set failed\n"); + +} + +void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_priority_select_t PriDec; + + if (data->qos_table_idx == 0) + ret = rtk_qos_priSel_get(PRIDECTBL_IDX0, &PriDec); + else + ret = rtk_qos_priSel_get(PRIDECTBL_IDX1, &PriDec); + + if (ret != 0) + printk("rtk_qos_priSel_set failed\n"); + else { + printk("port_pri = %d\n", PriDec.port_pri); + printk("dot1q_pri = %d\n", PriDec.dot1q_pri); + printk("acl_pri = %d\n", PriDec.acl_pri); + printk("dscp_pri = %d\n", PriDec.dscp_pri); + printk("cvlan_pri = %d\n", PriDec.cvlan_pri); + printk("svlan_pri = %d\n", PriDec.svlan_pri); + printk("dmac_pri = %d\n", PriDec.dmac_pri); + printk("smac_pri = %d\n", PriDec.smac_pri); + } +} + +void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_qos_portPriSelIndex_set(data->port, data->qos_table_idx); + if (ret != 0) + printk("rtk_qos_portPriSelIndex_set failed\n"); +} + +void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_qos_priDecTbl_t Index; + + ret = rtk_qos_portPriSelIndex_get(data->port, &Index); + if (ret != 0) + printk("rtk_qos_portPriSelIndex_set failed\n"); + else + printk("port%d belongs to table%d\n", data->port, Index); +} + +void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_qos_portPri_set(data->port, data->qos_pri); + if (ret != 0) + printk("rtk_qos_portPri_set failed\n"); +} + +void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_pri_t Int_pri; + + ret = rtk_qos_portPri_get(data->port, &Int_pri); + if (ret != 0) + printk("rtk_qos_portPri_set failed\n"); + else + printk("port%d priority = %d\n", data->port, Int_pri); +} + +void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_qos_dscpPriRemap_set(data->qos_dscp, data->qos_pri); + if (ret != 0) + printk("rtk_qos_dscpPriRemap_set failed\n"); +} + +void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_pri_t Int_pri; + + ret = rtk_qos_dscpPriRemap_get(data->qos_dscp, &Int_pri); + if (ret != 0) + printk("rtk_qos_dscpPriRemap_set failed\n"); + else + printk("dscp%d priority is %d\n", data->qos_dscp, Int_pri); +} + +void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_qos_pri2queue_t pri2qid; + + ret = rtk_qos_priMap_get(8, &pri2qid); + pri2qid.pri2queue[data->qos_queue_num] = data->qos_pri; + ret = rtk_qos_priMap_set(8, &pri2qid); + if (ret != 0) + printk("rtk_qos_priMap_set failed\n"); +} + +void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data) +{ + int i; + rtk_api_ret_t ret; + rtk_qos_pri2queue_t pri2qid; + + ret = rtk_qos_priMap_get(8, &pri2qid); + if (ret != 0) + printk("rtk_qos_priMap_get failed\n"); + else { + for (i = 0; i < 8; i++) + printk("pri2qid.pri2queue[%d] = %d\n", i, pri2qid.pri2queue[i]); + } +} + +void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_qos_queue_weights_t qweights; + + ret = rtk_qos_schedulingQueue_get(data->port, &qweights); + qweights.weights[data->qos_queue_num] = data->qos_weight; + ret = rtk_qos_schedulingQueue_set(data->port, &qweights); + if (ret != 0) + printk("rtk_qos_schedulingQueue_set failed\n"); +} + +void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data) +{ + int i; + rtk_api_ret_t ret; + rtk_qos_queue_weights_t qweights; + + ret = rtk_qos_schedulingQueue_get(data->port, &qweights); + if (ret != 0) + printk("rtk_qos_schedulingQueue_get failed\n"); + else { + printk("=== Port%d queue weight ===\n", data->port); + for (i = 0; i < 8; i++) + printk("qweights.weights[%d] = %d\n",i ,qweights.weights[i]); + } +} + +void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_portmask_t pmask; + + + ret = rtk_igmp_init(); + if (data->on_off == 1) { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + ret |= rtk_igmp_static_router_port_set(&pmask); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); + ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); + /* drop unknown multicast packets*/ + /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ + } else { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_igmp_static_router_port_set(&pmask); + } + if(ret != RT_ERR_OK) + printk("enable switch igmpsnoop failed\n"); +} + +void rtk_hal_disable_igmpsnoop(void) +{ + if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) + printk("Disable IGMP SNOOPING failed\n"); +} + +rtk_api_ret_t rtk_port_phyTestMode_set(rtk_port_t port, rtk_port_phy_test_mode_t mode) +{ + rtk_uint32 data, regData, i; + rtk_api_ret_t retVal; + + RTK_CHK_PORT_IS_UTP(port); + + if(mode >= PHY_TEST_MODE_END) + return RT_ERR_INPUT; + + if( (mode == PHY_TEST_MODE_2) || (mode == PHY_TEST_MODE_3) ) + return RT_ERR_INPUT; + + if (PHY_TEST_MODE_NORMAL != mode) + { + /* Other port should be Normal mode */ + RTK_SCAN_ALL_LOG_PORT(i) + { + if(rtk_switch_isUtpPort(i) == RT_ERR_OK) + { + if(i != port) + { + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(i), 9, &data)) != RT_ERR_OK) + return retVal; + + if((data & 0xE000) != 0) + return RT_ERR_NOT_ALLOWED; + } + } + } + } + + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 9, &data)) != RT_ERR_OK) + return retVal; + + data &= ~0xE000; + data |= (mode << 13); + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 9, data)) != RT_ERR_OK) + return retVal; + + if (PHY_TEST_MODE_4 == mode) + { + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x0276) || (regData == 0x0597) ) + { + if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xbcc2, 0xF4F4)) != RT_ERR_OK) + return retVal; + } + + if( (regData == 0x6367) ) + { + if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa436, 0x80c1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa438, 0xfe00)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_port_phyTestMode_set(data->port, data->mode); + if (ret != RT_ERR_OK) + printk("rtk_port_phyTestMode_set failed\n"); + else + printk("set port%d in test mode %d.\n", data->port, data->mode); +} + +void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data) +{ + + rtk_api_ret_t ret; + rtk_portmask_t member; + int i; + + RTK_PORTMASK_CLEAR(member); + for (i = 0; i < 4; i++) { + if (data->port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(member, i); + } + + ret = rtk_trunk_port_set(TRUNK_GROUP0, &member); + if (ret != RT_ERR_OK) + printk("rtk_trunk_port_set failed\n"); + + ret = rtk_trunk_distributionAlgorithm_set(RTK_WHOLE_SYSTEM, 0x7F); + if (ret != RT_ERR_OK) + printk("rtk_trunk_distributionAlgorithm_set failed\n"); +} + +void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_vlan_cfg_t vlan; + + ret = rtk_vlan_get(data->vid, &vlan); + if (ret != RT_ERR_OK) + printk("rtk_vlan_get failed\n"); + else { + if (data->on_off == 0) + RTK_PORTMASK_PORT_SET(vlan.untag, data->port); + else + RTK_PORTMASK_PORT_CLEAR(vlan.untag, data->port); + + ret = rtk_vlan_set(data->vid, &vlan); + if (ret != RT_ERR_OK) + printk("rtk_vlan_set failed\n"); + } +} + +void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data) +{ + rtk_vlan_cfg_t vlan1, vlan2; + rtk_api_ret_t ret; + + ret = rtk_vlan_get(1, &vlan1); + if (ret != RT_ERR_OK) + printk("rtk_vlan_get failed\n"); + + ret = rtk_vlan_get(2, &vlan2); + if (ret != RT_ERR_OK) + printk("rtk_vlan_get failed\n"); + + if (data->mode == 0) { //ivl + vlan1.ivl_en = 1; + vlan1.fid_msti = 0; + rtk_vlan_set(1, &vlan1); + vlan2.ivl_en = 1; + vlan2.fid_msti = 0; + rtk_vlan_set(2, &vlan2); + } else if(data->mode == 1) {//svl + vlan1.ivl_en = 0; + vlan1.fid_msti = 0; + rtk_vlan_set(1, &vlan1); + vlan2.ivl_en = 0; + vlan2.fid_msti = 1; + rtk_vlan_set(2, &vlan2); + } else + printk("mode not supported\n"); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtk_switch.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtk_switch.c new file mode 100755 index 00000000..0bb0db07 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtk_switch.c @@ -0,0 +1,1796 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76336 $ + * $Date: 2017-03-09 10:41:21 +0800 (週四, 09 三月 2017) $ + * + * Purpose : RTK switch high-level API + * Feature : Here is a list of all functions and variables in this module. + * + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if defined(FORCE_PROBE_RTL8367C) +static init_state_t init_state = INIT_COMPLETED; +#elif defined(FORCE_PROBE_RTL8370B) +static init_state_t init_state = INIT_COMPLETED; +#elif defined(FORCE_PROBE_RTL8364B) +static init_state_t init_state = INIT_COMPLETED; +#elif defined(FORCE_PROBE_RTL8363SC_VB) +static init_state_t init_state = INIT_COMPLETED; +#else +static init_state_t init_state = INIT_NOT_COMPLETED; +#endif + +#define AUTO_PROBE (!defined(FORCE_PROBE_RTL8367C) && !defined(FORCE_PROBE_RTL8370B) && !defined(FORCE_PROBE_RTL8364B) && !defined(FORCE_PROBE_RTL8363SC_VB)) + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8367C)) +static rtk_switch_halCtrl_t rtl8367c_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8367C, + + /* Logical to Physical */ + {0, 1, 2, 3, 4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid CPU port mask */ + 0x00, + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 7, + + /* Physical port mask */ + 0xDF, + + /* Combo Logical port ID */ + 4, + + /* HSG Logical port ID */ + EXT_PORT0, + + /* SGMII Logical portmask */ + (0x1 << EXT_PORT0), + + /* Max Meter ID */ + 31, + + /* MAX LUT Address Number */ + 2112, + + /* Trunk Group Mask */ + 0x03 +}; +#endif + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8370B)) +static rtk_switch_halCtrl_t rtl8370b_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8370B, + + /* Logical to Physical */ + {0, 1, 2, 3, 4, 5, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 8, 9, 10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UTP_PORT5, UTP_PORT6, UTP_PORT7, + EXT_PORT0, EXT_PORT1, EXT_PORT2, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), + + /* Valid CPU port mask */ + (0x1 << EXT_PORT2), + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 10, + + /* Physical port mask */ + 0x7FF, + + /* Combo Logical port ID */ + 7, + + /* HSG Logical port ID */ + EXT_PORT1, + + /* SGMII Logical portmask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Max Meter ID */ + 63, + + /* MAX LUT Address Number 4096 + 64*/ + 4160, + + /* Trunk Group Mask */ + 0x07 +}; +#endif + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8364B)) +static rtk_switch_halCtrl_t rtl8364b_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8364B, + + /* Logical to Physical */ + {0xFF, 1, 0xFF, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UNDEFINE_PORT, UTP_PORT1, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid CPU port mask */ + 0x00, + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 7, + + /* Physical port mask */ + 0xCA, + + /* Combo Logical port ID */ + 4, + + /* HSG Logical port ID */ + EXT_PORT0, + + /* SGMII Logical portmask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Max Meter ID */ + 32, + + /* MAX LUT Address Number */ + 2112, + + /* Trunk Group Mask */ + 0x01 +}; +#endif + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8363SC_VB)) +static rtk_switch_halCtrl_t rtl8363sc_vb_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8363SC_VB, + + /* Logical to Physical */ + {0xFF, 0xFF, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UNDEFINE_PORT, UTP_PORT2, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UNKNOWN_PORT, UNKNOWN_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid CPU port mask */ + 0x00, + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 7, + + /* Physical port mask */ + 0xCA, + + /* Combo Logical port ID */ + 4, + + /* HSG Logical port ID */ + EXT_PORT0, + + /* SGMII Logical portmask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Max Meter ID */ + 32, + + /* MAX LUT Address Number */ + 2112, + + /* Trunk Group Mask */ + 0x01 +}; +#endif + +#if defined(FORCE_PROBE_RTL8367C) +static rtk_switch_halCtrl_t *halCtrl = &rtl8367c_hal_Ctrl; +#elif defined(FORCE_PROBE_RTL8370B) +static rtk_switch_halCtrl_t *halCtrl = &rtl8370b_hal_Ctrl; +#elif defined(FORCE_PROBE_RTL8364B) +static rtk_switch_halCtrl_t *halCtrl = &rtl8364b_hal_Ctrl; +#elif defined(FORCE_PROBE_RTL8363SC_VB) +static rtk_switch_halCtrl_t *halCtrl = &rtl8363sc_vb_hal_Ctrl; +#else +static rtk_switch_halCtrl_t *halCtrl = NULL; +#endif + +static rtk_uint32 PatchChipData[210][2] = +{ + {0xa436, 0x8028}, {0xa438, 0x6800}, {0xb82e, 0x0001}, {0xa436, 0xb820}, {0xa438, 0x0090}, {0xa436, 0xa012}, {0xa438, 0x0000}, {0xa436, 0xa014}, {0xa438, 0x2c04}, {0xa438, 0x2c6c}, + {0xa438, 0x2c75}, {0xa438, 0x2c77}, {0xa438, 0x1414}, {0xa438, 0x1579}, {0xa438, 0x1536}, {0xa438, 0xc432}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, + {0xa438, 0x614c}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x318c}, {0xa438, 0x42d6}, {0xa438, 0xd702}, {0xa438, 0x31ef}, {0xa438, 0x42d6}, {0xa438, 0x629c}, {0xa438, 0x2c04}, + {0xa438, 0x653c}, {0xa438, 0x422a}, {0xa438, 0x5d83}, {0xa438, 0xd06a}, {0xa438, 0xd1b0}, {0xa438, 0x1536}, {0xa438, 0xc43a}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, + {0xa438, 0x003e}, {0xa438, 0x314a}, {0xa438, 0x42fe}, {0xa438, 0x337b}, {0xa438, 0x02d6}, {0xa438, 0x3063}, {0xa438, 0x0c1b}, {0xa438, 0x22fe}, {0xa438, 0xc435}, {0xa438, 0xd0be}, + {0xa438, 0xd1f7}, {0xa438, 0xe0f0}, {0xa438, 0x1a40}, {0xa438, 0xa320}, {0xa438, 0xd702}, {0xa438, 0x154a}, {0xa438, 0xc434}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, + {0xa438, 0x003e}, {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x619f}, {0xa438, 0xd702}, {0xa438, 0x414f}, {0xa438, 0x2c2e}, {0xa438, 0x610a}, {0xa438, 0xd705}, + {0xa438, 0x5e1f}, {0xa438, 0xc43f}, {0xa438, 0xc88b}, {0xa438, 0xd702}, {0xa438, 0x7fe0}, {0xa438, 0x22f3}, {0xa438, 0xd0a0}, {0xa438, 0xd1b2}, {0xa438, 0xd0c3}, {0xa438, 0xd1c3}, + {0xa438, 0x8d01}, {0xa438, 0x1536}, {0xa438, 0xc438}, {0xa438, 0xe0f0}, {0xa438, 0x1a80}, {0xa438, 0xd706}, {0xa438, 0x60c0}, {0xa438, 0xd710}, {0xa438, 0x409e}, {0xa438, 0xa804}, + {0xa438, 0xad01}, {0xa438, 0x8804}, {0xa438, 0xd702}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, {0xa438, 0x405b}, {0xa438, 0x1576}, {0xa438, 0x7c9c}, + {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd702}, {0xa438, 0x5d43}, {0xa438, 0x31ef}, {0xa438, 0x02fe}, {0xa438, 0x22d6}, {0xa438, 0x590a}, {0xa438, 0xd706}, {0xa438, 0x5c80}, + {0xa438, 0xd702}, {0xa438, 0x5c44}, {0xa438, 0x3063}, {0xa438, 0x02d6}, {0xa438, 0x5be2}, {0xa438, 0x22fb}, {0xa438, 0xa240}, {0xa438, 0xa104}, {0xa438, 0x8c03}, {0xa438, 0x8178}, + {0xa438, 0xd701}, {0xa438, 0x31ad}, {0xa438, 0x4917}, {0xa438, 0x8102}, {0xa438, 0x2917}, {0xa438, 0xc302}, {0xa438, 0x268a}, {0xa436, 0xA01A}, {0xa438, 0x0000}, {0xa436, 0xA006}, + {0xa438, 0x0fff}, {0xa436, 0xA004}, {0xa438, 0x0689}, {0xa436, 0xA002}, {0xa438, 0x0911}, {0xa436, 0xA000}, {0xa438, 0x7302}, {0xa436, 0xB820}, {0xa438, 0x0010}, {0xa436, 0x8412}, + {0xa438, 0xaf84}, {0xa438, 0x1eaf}, {0xa438, 0x8427}, {0xa438, 0xaf84}, {0xa438, 0x27af}, {0xa438, 0x8427}, {0xa438, 0x0251}, {0xa438, 0x6802}, {0xa438, 0x8427}, {0xa438, 0xaf04}, + {0xa438, 0x0af8}, {0xa438, 0xf9bf}, {0xa438, 0x5581}, {0xa438, 0x0255}, {0xa438, 0x27ef}, {0xa438, 0x310d}, {0xa438, 0x345b}, {0xa438, 0x0fa3}, {0xa438, 0x032a}, {0xa438, 0xe087}, + {0xa438, 0xffac}, {0xa438, 0x2040}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x5527}, {0xa438, 0xef31}, {0xa438, 0xef20}, {0xa438, 0xe787}, {0xa438, 0xfee6}, {0xa438, 0x87fd}, + {0xa438, 0xd488}, {0xa438, 0x88bf}, {0xa438, 0x5674}, {0xa438, 0x0254}, {0xa438, 0xe3e0}, {0xa438, 0x87ff}, {0xa438, 0xf720}, {0xa438, 0xe487}, {0xa438, 0xffaf}, {0xa438, 0x847e}, + {0xa438, 0xe087}, {0xa438, 0xffad}, {0xa438, 0x2016}, {0xa438, 0xe387}, {0xa438, 0xfee2}, {0xa438, 0x87fd}, {0xa438, 0xef45}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x54e3}, + {0xa438, 0xe087}, {0xa438, 0xfff6}, {0xa438, 0x20e4}, {0xa438, 0x87ff}, {0xa438, 0xfdfc}, {0xa438, 0x0400}, {0xa436, 0xb818}, {0xa438, 0x0407}, {0xa436, 0xb81a}, {0xa438, 0xfffd}, + {0xa436, 0xb81c}, {0xa438, 0xfffd}, {0xa436, 0xb81e}, {0xa438, 0xfffd}, {0xa436, 0xb832}, {0xa438, 0x0001}, {0xb820, 0x0000}, {0xb82e, 0x0000}, {0xa436, 0x8028}, {0xa438, 0x0000} +}; + +static rtk_api_ret_t _rtk_switch_init_8367c(void) +{ + rtk_port_t port; + rtk_uint32 retVal; + rtk_uint32 regData; + rtk_uint32 regValue; + + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA428, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0200); + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA428, regData)) != RT_ERR_OK) + return retVal; + + if((regValue & 0x00F0) == 0x00A0) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA5D0, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= 0x0006; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA5D0, regData)) != RT_ERR_OK) + return retVal; + } + } + } + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_UTP_FIB_DET, 0x15BB)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1303, 0x06D6)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1304, 0x0700)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13E2, 0x003F)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13F9, 0x0090)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x121e, 0x03CA)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1233, 0x0352)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1237, 0x00a0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x123a, 0x0030)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1239, 0x0084)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x0301, 0x1000)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1349, 0x001F)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x18e0, 0, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x122b, 14, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1305, 0xC000, 3)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_switch_init_8370b(void) +{ + ret_t retVal; + rtk_uint32 regData, tmp = 0; + rtk_uint32 i, prf, counter; + rtk_uint32 long_link[8] = {0x0210, 0x03e8, 0x0218, 0x03f0, 0x0220, 0x03f8, 0x0208, 0x03e0 }; + + if((retVal = rtl8367c_setAsicRegBits(0x1205, 0x0300, 3)) != RT_ERR_OK) + return retVal; + + + for(i=0; i<8; i++) + { + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa420, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x7 ; + if(tmp == 0x3) + { + prf = 1; + if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6fa9)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xa9)) != RT_ERR_OK) + return retVal; + for(counter = 0; counter < 10000; counter++); //delay + + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData | 0x10; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) + return retVal; + for(counter = 0; counter < 10000; counter++); //delay + counter = 0; + do{ + counter = counter + 1; + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x40; + if(tmp != 0) + break; + } while (counter < 20); //Wait for patch ready = 1... + } + } + if ((retVal = rtl8367c_getAsicReg(0x1d01, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData; + tmp = tmp | 0x3BE0; /*Broadcast port enable*/ + tmp = tmp & 0xFFE0; /*Phy_id = 0 */ + if((retVal = rtl8367c_setAsicReg(0x1d01, tmp)) != RT_ERR_OK) + return retVal; + + for(i=0;i < 210; i++) + { + if((retVal = rtl8367c_setAsicPHYOCPReg(0, PatchChipData[i][0], PatchChipData[i][1])) != RT_ERR_OK) + return retVal; + } + + if((retVal = rtl8367c_setAsicReg(0x1d01, regData)) != RT_ERR_OK) + return retVal; + + for(i=0; i < 8; i++) + { + if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa4b4, long_link[i])) != RT_ERR_OK) + return retVal; + } + + if (prf == 0x1) + { + for(i=0; i<8; i++) + { + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0xFFEF; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) + return retVal; + + for(counter = 0; counter < 10000; counter++); //delay + + counter = 0; + do{ + counter = counter + 1; + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x40; + if( tmp == 0 ) + break; + } while (counter < 20); //Wait for patch ready = 1... + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6f48)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xfa)) != RT_ERR_OK) + return retVal; + } + } + + /*Check phy link status*/ + for(i=0; i<8; i++) + { + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa400, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x800; + if(tmp == 0x0) + { + tmp = regData | 0x200; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa400, tmp)) != RT_ERR_OK) + return retVal; + } + } + + for(counter = 0; counter < 10000; counter++); //delay + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_switch_init_8364b(void) +{ + ret_t retVal; + rtk_uint32 regData; + + /*enable EEE, include mac & phy*/ + + if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + + /*PAD para*/ + + /*EXT1 PAD Para*/ + if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFFFFFFE; + regData |= 0x250; + if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) + return retVal; + + /*EXT2 PAD Para*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) + return retVal; + + + /*SDS PATCH*/ + /*SP_CFG_EN_LINK_FIB1G*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x4; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) + return retVal; + + /*FIB100 Down-speed*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x20; + if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_switch_init_8363sc_vb(void) +{ + + ret_t retVal; + rtk_uint32 regData; + + /*enable EEE, include mac & phy*/ + + if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + + /*PAD para*/ + + /*EXT1 PAD Para*/ + if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFFFFFFE; + regData |= 0x250; + if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) + return retVal; + + /*EXT2 PAD Para*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) + return retVal; + + + /*SDS PATCH*/ + /*SP_CFG_EN_LINK_FIB1G*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x4; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) + return retVal; + + /*FIB100 Down-speed*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x20; + if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_probe + * Description: + * Probe switch + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Switch probed + * RT_ERR_FAILED - Switch Unprobed. + * Note: + * + */ +rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip) +{ +#if defined(FORCE_PROBE_RTL8367C) + + *pSwitchChip = CHIP_RTL8367C; + halCtrl = &rtl8367c_hal_Ctrl; + +#elif defined(FORCE_PROBE_RTL8370B) + + *pSwitchChip = CHIP_RTL8370B; + halCtrl = &rtl8370b_hal_Ctrl; + +#elif defined(FORCE_PROBE_RTL8364B) + + *pSwitchChip = CHIP_RTL8364B; + halCtrl = &rtl8364b_hal_Ctrl; + +#elif defined(FORCE_PROBE_RTL8363SC_VB) + + *pSwitchChip = CHIP_RTL8363SC_VB; + halCtrl = &rtl8363sc_vb_hal_Ctrl; + +#else + rtk_uint32 retVal; + rtk_uint32 data, regValue; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (data) + { + case 0x0276: + case 0x0597: + case 0x6367: + *pSwitchChip = CHIP_RTL8367C; + halCtrl = &rtl8367c_hal_Ctrl; + break; + case 0x0652: + case 0x6368: + *pSwitchChip = CHIP_RTL8370B; + halCtrl = &rtl8370b_hal_Ctrl; + break; + case 0x0801: + case 0x6511: + if( (regValue & 0x00F0) == 0x0080) + { + *pSwitchChip = CHIP_RTL8363SC_VB; + halCtrl = &rtl8363sc_vb_hal_Ctrl; + } + else + { + *pSwitchChip = CHIP_RTL8364B; + halCtrl = &rtl8364b_hal_Ctrl; + } + break; + default: + return RT_ERR_FAILED; + } +#endif + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_initialState_set + * Description: + * Set initial status + * Input: + * state - Initial state; + * Output: + * None + * Return: + * RT_ERR_OK - Initialized + * RT_ERR_FAILED - Uninitialized + * Note: + * + */ +rtk_api_ret_t rtk_switch_initialState_set(init_state_t state) +{ + if(state >= INIT_STATE_END) + return RT_ERR_FAILED; + + init_state = state; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_initialState_get + * Description: + * Get initial status + * Input: + * None + * Output: + * None + * Return: + * INIT_COMPLETED - Initialized + * INIT_NOT_COMPLETED - Uninitialized + * Note: + * + */ +init_state_t rtk_switch_initialState_get(void) +{ + return init_state; +} + +/* Function Name: + * rtk_switch_logicalPortCheck + * Description: + * Check logical port ID. + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is correct + * RT_ERR_FAILED - Port ID is not correct + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->l2p_port[logicalPort] == 0xFF) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_isUtpPort + * Description: + * Check is logical port a UTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a UTP port + * RT_ERR_FAILED - Port ID is not a UTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->log_port_type[logicalPort] == UTP_PORT) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isExtPort + * Description: + * Check is logical port a Extension port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a EXT port + * RT_ERR_FAILED - Port ID is not a EXT port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->log_port_type[logicalPort] == EXT_PORT) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + + +/* Function Name: + * rtk_switch_isHsgPort + * Description: + * Check is logical port a HSG port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a HSG port + * RT_ERR_FAILED - Port ID is not a HSG port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(logicalPort == halCtrl->hsg_logical_port) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isSgmiiPort + * Description: + * Check is logical port a SGMII port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a SGMII port + * RT_ERR_FAILED - Port ID is not a SGMII port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if( ((0x01 << logicalPort) & halCtrl->sg_logical_portmask) != 0) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isCPUPort + * Description: + * Check is logical port a CPU port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a CPU port + * RT_ERR_FAILED - Port ID is not a CPU port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if( ((0x01 << logicalPort) & halCtrl->valid_cpu_portmask) != 0) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isComboPort + * Description: + * Check is logical port a Combo port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a combo port + * RT_ERR_FAILED - Port ID is not a combo port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->combo_logical_port == logicalPort) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_ComboPort_get + * Description: + * Get Combo port ID + * Input: + * None + * Output: + * None + * Return: + * Port ID of combo port + * Note: + * + */ +rtk_uint32 rtk_switch_ComboPort_get(void) +{ + return halCtrl->combo_logical_port; +} + +/* Function Name: + * rtk_switch_isPtpPort + * Description: + * Check is logical port a PTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a PTP port + * RT_ERR_FAILED - Port ID is not a PTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->ptp_port[logicalPort] == 1) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_port_L2P_get + * Description: + * Get physical port ID + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * Physical port ID + * Note: + * + */ +rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return UNDEFINE_PHY_PORT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return UNDEFINE_PHY_PORT; + + return (halCtrl->l2p_port[logicalPort]); +} + +/* Function Name: + * rtk_switch_port_P2L_get + * Description: + * Get logical port ID + * Input: + * physicalPort - physical port ID + * Output: + * None + * Return: + * logical port ID + * Note: + * + */ +rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort) +{ + if(init_state != INIT_COMPLETED) + return UNDEFINE_PORT; + + if(physicalPort >= RTK_SWITCH_PORT_NUM) + return UNDEFINE_PORT; + + return (halCtrl->p2l_port[physicalPort]); +} + +/* Function Name: + * rtk_switch_isPortMaskValid + * Description: + * Check portmask is valid or not + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - port mask is valid + * RT_ERR_FAILED - port mask is not valid + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pPmask) + return RT_ERR_NULL_POINTER; + + if( (pPmask->bits[0] | halCtrl->valid_portmask) != halCtrl->valid_portmask ) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_isPortMaskUtp + * Description: + * Check all ports in portmask are only UTP port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only UTP port in port mask + * RT_ERR_FAILED - Not only UTP port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pPmask) + return RT_ERR_NULL_POINTER; + + if( (pPmask->bits[0] | halCtrl->valid_utp_portmask) != halCtrl->valid_utp_portmask ) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_isPortMaskExt + * Description: + * Check all ports in portmask are only EXT port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only EXT port in port mask + * RT_ERR_FAILED - Not only EXT port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pPmask) + return RT_ERR_NULL_POINTER; + + if( (pPmask->bits[0] | halCtrl->valid_ext_portmask) != halCtrl->valid_ext_portmask ) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portmask_L2P_get + * Description: + * Get physicl portmask from logical portmask + * Input: + * pLogicalPmask - logical port mask + * Output: + * pPhysicalPortmask - physical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask) +{ + rtk_uint32 log_port, phy_port; + + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pLogicalPmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pPhysicalPortmask) + return RT_ERR_NULL_POINTER; + + if(rtk_switch_isPortMaskValid(pLogicalPmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + + /* reset physical port mask */ + *pPhysicalPortmask = 0; + + RTK_PORTMASK_SCAN((*pLogicalPmask), log_port) + { + phy_port = rtk_switch_port_L2P_get((rtk_port_t)log_port); + *pPhysicalPortmask |= (0x0001 << phy_port); + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portmask_P2L_get + * Description: + * Get logical portmask from physical portmask + * Input: + * physicalPortmask - physical port mask + * Output: + * pLogicalPmask - logical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask) +{ + rtk_uint32 log_port, phy_port; + + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pLogicalPmask) + return RT_ERR_NULL_POINTER; + + RTK_PORTMASK_CLEAR(*pLogicalPmask); + + for(phy_port = halCtrl->min_phy_port; phy_port <= halCtrl->max_phy_port; phy_port++) + { + if(physicalPortmask & (0x0001 << phy_port)) + { + log_port = rtk_switch_port_P2L_get(phy_port); + if(log_port != UNDEFINE_PORT) + { + RTK_PORTMASK_PORT_SET(*pLogicalPmask, log_port); + } + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_phyPortMask_get + * Description: + * Get physical portmask + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Physical port mask + * Note: + * + */ +rtk_uint32 rtk_switch_phyPortMask_get(void) +{ + if(init_state != INIT_COMPLETED) + return 0x00; /* No port in portmask */ + + return (halCtrl->phy_portmask); +} + +/* Function Name: + * rtk_switch_logPortMask_get + * Description: + * Get Logical portmask + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_logPortMask_get(rtk_portmask_t *pPortmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_FAILED; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + pPortmask->bits[0] = halCtrl->valid_portmask; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_init + * Description: + * Set chip to default configuration enviroment + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can set chip registers to default configuration for different release chip model. + */ +rtk_api_ret_t rtk_switch_init(void) +{ + rtk_uint32 retVal; + rtl8367c_rma_t rmaCfg; + switch_chip_t switchChip; + + /* probe switch */ + if((retVal = rtk_switch_probe(&switchChip)) != RT_ERR_OK) + return retVal; + + /* Set initial state */ + + if((retVal = rtk_switch_initialState_set(INIT_COMPLETED)) != RT_ERR_OK) + return retVal; + + /* Initial */ + switch(switchChip) + { + case CHIP_RTL8367C: + if((retVal = _rtk_switch_init_8367c()) != RT_ERR_OK) + return retVal; + break; + case CHIP_RTL8370B: + if((retVal = _rtk_switch_init_8370b()) != RT_ERR_OK) + return retVal; + break; + case CHIP_RTL8364B: + if((retVal = _rtk_switch_init_8364b()) != RT_ERR_OK) + return retVal; + break; + case CHIP_RTL8363SC_VB: + if((retVal = _rtk_switch_init_8363sc_vb()) != RT_ERR_OK) + return retVal; + break; + default: + return RT_ERR_CHIP_NOT_FOUND; + } + + /* Set Old max packet length to 16K */ + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LENGTH_LIMINT_IPG, RTL8367C_MAX_LENTH_CTRL_MASK, 3)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX, RTL8367C_MAX_LEN_RX_TX_MASK, 3)) != RT_ERR_OK) + return retVal; + + /* ACL Mode */ + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_ACCESS_MODE, RTL8367C_ACL_ACCESS_MODE_MASK, 1)) != RT_ERR_OK) + return retVal; + + /* Max rate */ + if((retVal = rtk_rate_igrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, DISABLED, ENABLED)) != RT_ERR_OK) + return retVal; + + if((retVal = rtk_rate_egrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, ENABLED)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x03fa, 0x0007)) != RT_ERR_OK) + return retVal; + + /* Change unknown DA to per port setting */ + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK, 3)) != RT_ERR_OK) + return retVal; + + /* LUT lookup OP = 1 */ + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + + /* Set RMA */ + rmaCfg.portiso_leaky = 0; + rmaCfg.vlan_leaky = 0; + rmaCfg.keep_format = 0; + rmaCfg.trap_priority = 0; + rmaCfg.discard_storm_filter = 0; + rmaCfg.operation = 0; + if ((retVal = rtl8367c_setAsicRma(2, &rmaCfg))!=RT_ERR_OK) + return retVal; + + /* Enable TX Mirror isolation leaky */ + if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(ENABLED)) != RT_ERR_OK) + return retVal; + + /* INT EN */ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IO_MISC_FUNC, RTL8367C_INT_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portMaxPktLen_set + * Description: + * Set Max packet length + * Input: + * port - Port ID + * speed - Speed + * cfgId - Configuration ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(speed >= MAXPKTLEN_LINK_SPEED_END) + return RT_ERR_INPUT; + + if(cfgId > MAXPKTLEN_CFG_ID_MAX) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, cfgId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portMaxPktLen_get + * Description: + * Get Max packet length + * Input: + * port - Port ID + * speed - Speed + * Output: + * pCfgId - Configuration ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(speed >= MAXPKTLEN_LINK_SPEED_END) + return RT_ERR_INPUT; + + if(NULL == pCfgId) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, pCfgId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_maxPktLenCfg_set + * Description: + * Set Max packet length configuration + * Input: + * cfgId - Configuration ID + * pktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(cfgId > MAXPKTLEN_CFG_ID_MAX) + return RT_ERR_INPUT; + + if(pktLen > RTK_SWITCH_MAX_PKTLEN) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicMaxLengthCfg(cfgId, pktLen)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_maxPktLenCfg_get + * Description: + * Get Max packet length configuration + * Input: + * cfgId - Configuration ID + * pPktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(cfgId > MAXPKTLEN_CFG_ID_MAX) + return RT_ERR_INPUT; + + if(NULL == pPktLen) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMaxLengthCfg(cfgId, pPktLen)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_greenEthernet_set + * Description: + * Set all Ports Green Ethernet state. + * Input: + * enable - Green Ethernet state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all Ports Green Ethernet state. + * The configuration is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtl8367c_setAsicPowerSaving(rtk_switch_port_L2P_get(port),enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicGreenEthernet(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_greenEthernet_get + * Description: + * Get all Ports Green Ethernet state. + * Input: + * None + * Output: + * pEnable - Green Ethernet state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can get Green Ethernet state. + */ +rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtk_uint32 state; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtl8367c_getAsicPowerSaving(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) + return retVal; + + if(state == DISABLED) + { + *pEnable = DISABLED; + return RT_ERR_OK; + } + + if ((retVal = rtl8367c_getAsicGreenEthernet(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) + return retVal; + + if(state == DISABLED) + { + *pEnable = DISABLED; + return RT_ERR_OK; + } + } + } + + *pEnable = ENABLED; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_maxLogicalPort_get + * Description: + * Get Max logical port ID + * Input: + * None + * Output: + * None + * Return: + * Max logical port + * Note: + * This API can get max logical port + */ +rtk_port_t rtk_switch_maxLogicalPort_get(void) +{ + rtk_port_t port, maxLogicalPort = 0; + + /* Check initialization state */ + if(rtk_switch_initialState_get() != INIT_COMPLETED) + { + return UNDEFINE_PORT; + } + + for(port = 0; port < RTK_SWITCH_PORT_NUM; port++) + { + if( (halCtrl->log_port_type[port] == UTP_PORT) || (halCtrl->log_port_type[port] == EXT_PORT) ) + maxLogicalPort = port; + } + + return maxLogicalPort; +} + +/* Function Name: + * rtk_switch_maxMeterId_get + * Description: + * Get Max Meter ID + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max Meter ID + * Note: + * + */ +rtk_uint32 rtk_switch_maxMeterId_get(void) +{ + if(init_state != INIT_COMPLETED) + return 0x00; + + return (halCtrl->max_meter_id); +} + +/* Function Name: + * rtk_switch_maxLutAddrNumber_get + * Description: + * Get Max LUT Address number + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max LUT Address number + * Note: + * + */ +rtk_uint32 rtk_switch_maxLutAddrNumber_get(void) +{ + if(init_state != INIT_COMPLETED) + return 0x00; + + return (halCtrl->max_lut_addr_num); +} + +/* Function Name: + * rtk_switch_isValidTrunkGrpId + * Description: + * Check if trunk group is valid or not + * Input: + * grpId - Group ID + * Output: + * None + * Return: + * RT_ERR_OK - Trunk Group ID is valid + * RT_ERR_LA_TRUNK_ID - Trunk Group ID is not valid + * Note: + * + */ +rtk_uint32 rtk_switch_isValidTrunkGrpId(rtk_uint32 grpId) +{ + if(init_state != INIT_COMPLETED) + return 0x00; + + if( (halCtrl->trunk_group_mask & (0x01 << grpId) ) != 0) + return RT_ERR_OK; + else + return RT_ERR_LA_TRUNK_ID; + +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c new file mode 100755 index 00000000..7858edcf --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c @@ -0,0 +1,639 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : + * + */ + +#include + +#if defined(RTK_X86_ASICDRV) +#include +#else +#include +#endif + +/*for driver verify testing only*/ +#ifdef CONFIG_RTL8367C_ASICDRV_TEST +#define CLE_VIRTUAL_REG_SIZE 0x10000 +rtk_uint16 CleVirtualReg[CLE_VIRTUAL_REG_SIZE]; +#endif + +#if defined(CONFIG_RTL865X_CLE) || defined (RTK_X86_CLE) +rtk_uint32 cleDebuggingDisplay; +#endif + +#ifdef EMBEDDED_SUPPORT +extern void setReg(rtk_uint16, rtk_uint16); +extern rtk_uint16 getReg(rtk_uint16); +#endif + +/* Function Name: + * rtl8367c_setAsicRegBit + * Description: + * Set a bit value of a specified register + * Input: + * reg - register's address + * bit - bit location + * value - value to set. It can be value 0 or 1. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Set a bit of a specified register to 1 or 0. + */ +ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value) +{ + +#if defined(RTK_X86_ASICDRV) + rtk_uint32 regData; + ret_t retVal; + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + + if(value) + regData = regData | (1 << bit); + else + regData = regData & (~(1 << bit)); + + retVal = Access_Write(reg,2, regData); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + else if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + if(value) + { + CleVirtualReg[reg] = CleVirtualReg[reg] | (1 << bit); + } + else + { + CleVirtualReg[reg] = CleVirtualReg[reg] & (~(1 << bit)); + } + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint16 tmp; + + if(reg > RTL8367C_REGDATAMAX || value > 1) + return RT_ERR_INPUT; + + tmp = getReg(reg); + tmp &= (1 << bitIdx); + tmp |= (value << bitIdx); + setReg(reg, tmp); + +#else + rtk_uint32 regData; + ret_t retVal; + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + if(value) + regData = regData | (1 << bit); + else + regData = regData & (~(1 << bit)); + + retVal = smi_write(reg, regData); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicRegBit + * Description: + * Get a bit value of a specified register + * Input: + * reg - register's address + * bit - bit location + * value - value to get. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + *pValue = (regData & (0x1 << bit)) >> bit; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + *pValue = (CleVirtualReg[reg] & (0x1 << bit)) >> bit; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint16 tmp; + + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + tmp = getReg(reg); + tmp = tmp >> bitIdx; + tmp &= 1; + *value = tmp; +#else + rtk_uint32 regData; + ret_t retVal; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + + *pValue = (regData & (0x1 << bit)) >> bit; + +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicRegBits + * Description: + * Set bits value of a specified register + * Input: + * reg - register's address + * bits - bits mask for setting + * value - bits value for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Set bits of a specified register to value. Both bits and value are be treated as bit-mask + */ +ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + valueShifted = value << bitsShift; + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + + regData = regData & (~bits); + regData = regData | (valueShifted & bits); + + retVal = Access_Write(reg,2, regData); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + rtk_uint32 regData; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + valueShifted = value << bitsShift; + + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + regData = CleVirtualReg[reg] & (~bits); + regData = regData | (valueShifted & bits); + + CleVirtualReg[reg] = regData; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint32 regData; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + valueShifted = value << bitsShift; + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + regData = getReg(reg); + regData = regData & (~bits); + regData = regData | (valueShifted & bits); + + setReg(reg, regData); + +#else + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + valueShifted = value << bitsShift; + + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + + regData = regData & (~bits); + regData = regData | (valueShifted & bits); + + retVal = smi_write(reg, regData); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicRegBits + * Description: + * Get bits value of a specified register + * Input: + * reg - register's address + * bits - bits mask for setting + * value - bits value for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + *pValue = (regData & bits) >> bitsShift; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + rtk_uint32 bitsShift; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + *pValue = (CleVirtualReg[reg] & bits) >> bitsShift; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint32 regData; + rtk_uint32 bitsShift; + + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + if(bits >= (1UL << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1UL << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + regData = getReg(reg); + *value = (regData & bits) >> bitsShift; + +#else + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + + if(bits>= (1<= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) return RT_ERR_SMI; + + *pValue = (regData & bits) >> bitsShift; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n",reg, regData); + #endif + +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicReg + * Description: + * Set content of asic register + * Input: + * reg - register's address + * value - Value setting to register + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * The value will be set to ASIC mapping address only and it is always return RT_ERR_OK while setting un-mapping address registers + */ +ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value) +{ +#if defined(RTK_X86_ASICDRV)/*RTK-CNSD2-NickWu-20061222: for x86 compile*/ + + ret_t retVal; + + retVal = Access_Write(reg,2,value); + if(TRUE != retVal) return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + + /*MIBs emulating*/ + if(reg == RTL8367C_REG_MIB_ADDRESS) + { + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG] = 0x1; + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+1] = 0x2; + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+2] = 0x3; + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+3] = 0x4; + } + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + CleVirtualReg[reg] = value; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n",reg,CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + if(reg > RTL8367C_REGDATAMAX || value > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + setReg(reg, value); + +#else + ret_t retVal; + + retVal = smi_write(reg, value); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); + #endif + +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicReg + * Description: + * Get content of asic register + * Input: + * reg - register's address + * value - Value setting to register + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * Value 0x0000 will be returned for ASIC un-mapping address + */ +ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + *pValue = regData; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + *pValue = CleVirtualReg[reg]; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + *value = getReg(reg); + +#else + rtk_uint32 regData; + ret_t retVal; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + *pValue = regData; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + +#endif + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c new file mode 100755 index 00000000..d9ccd971 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c @@ -0,0 +1,1173 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : ACL related function drivers + * + */ +#include + +#include + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) +rtl8367c_aclrulesmi Rtl8370sVirtualAclRuleTable[RTL8367C_ACLRULENO]; +rtk_uint16 Rtl8370sVirtualAclActTable[RTL8367C_ACLRULENO][RTL8367C_ACL_ACT_TABLE_LEN]; +#endif + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclRuleStSmi2User( rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) +{ + rtk_uint8 *care_ptr, *data_ptr; + rtk_uint8 care_tmp, data_tmp; + rtk_uint32 i; + + pAclUser->data_bits.active_portmsk = (((pAclSmi->data_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->data_bits.rule_info >> 8) & 0x00FF); + pAclUser->data_bits.type = (pAclSmi->data_bits.rule_info & 0x0007); + pAclUser->data_bits.tag_exist = (pAclSmi->data_bits.rule_info & 0x00F8) >> 3; + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits; + + for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) + { + care_tmp = *(care_ptr + i) ^ (*(data_ptr + i)); + data_tmp = *(data_ptr + i); + + *(care_ptr + i) = care_tmp; + *(data_ptr + i) = data_tmp; + } + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; + care_tmp = (*care_ptr) ^ (*data_ptr); + data_tmp = (*data_ptr); + *care_ptr = care_tmp; + *data_ptr = data_tmp; + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + pAclUser->data_bits.field[i] = pAclSmi->data_bits.field[i]; + + pAclUser->valid = pAclSmi->valid; + + pAclUser->care_bits.active_portmsk = (((pAclSmi->care_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->care_bits.rule_info >> 8) & 0x00FF); + pAclUser->care_bits.type = (pAclSmi->care_bits.rule_info & 0x0007); + pAclUser->care_bits.tag_exist = (pAclSmi->care_bits.rule_info & 0x00F8) >> 3; + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + pAclUser->care_bits.field[i] = pAclSmi->care_bits.field[i]; +} + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclRuleStUser2Smi(rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) +{ + rtk_uint8 *care_ptr, *data_ptr; + rtk_uint8 care_tmp, data_tmp; + rtk_uint32 i; + + pAclSmi->data_bits_ext.rule_info = ((pAclUser->data_bits.active_portmsk >> 8) & 0x7) << 1; + pAclSmi->data_bits.rule_info = ((pAclUser->data_bits.active_portmsk & 0xff) << 8) | ((pAclUser->data_bits.tag_exist & 0x1F) << 3) | (pAclUser->data_bits.type & 0x07); + + for(i = 0;i < RTL8367C_ACLRULEFIELDNO; i++) + pAclSmi->data_bits.field[i] = pAclUser->data_bits.field[i]; + + pAclSmi->valid = pAclUser->valid; + + pAclSmi->care_bits_ext.rule_info = ((pAclUser->care_bits.active_portmsk >> 8) & 0x7) << 1; + pAclSmi->care_bits.rule_info = ((pAclUser->care_bits.active_portmsk & 0xff) << 8) | ((pAclUser->care_bits.tag_exist & 0x1F) << 3) | (pAclUser->care_bits.type & 0x07); + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + pAclSmi->care_bits.field[i] = pAclUser->care_bits.field[i]; + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits; + + for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) + { + care_tmp = *(care_ptr + i) & ~(*(data_ptr + i)); + data_tmp = *(care_ptr + i) & *(data_ptr + i); + + *(care_ptr + i) = care_tmp; + *(data_ptr + i) = data_tmp; + } + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; + care_tmp = *care_ptr & ~(*data_ptr); + data_tmp = *care_ptr & *data_ptr; + + *care_ptr = care_tmp; + *data_ptr = data_tmp; +} + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclActStSmi2User(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) +{ + pAclUser->cact = (pAclSmi[0] & 0x00C0) >> 6; + pAclUser->cvidx_cact = (pAclSmi[0] & 0x003F) | (((pAclSmi[3] & 0x0008) >> 3) << 6); + + pAclUser->sact = (pAclSmi[0] & 0xC000) >> 14; + pAclUser->svidx_sact = ((pAclSmi[0] & 0x3F00) >> 8) | (((pAclSmi[3] & 0x0010) >> 4) << 6); + + pAclUser->aclmeteridx = (pAclSmi[1] & 0x003F) | (((pAclSmi[3] & 0x0020) >> 5) << 6); + + pAclUser->fwdact = (pAclSmi[1] & 0xC000) >> 14; + pAclUser->fwdpmask = ((pAclSmi[1] & 0x3FC0) >> 6) | (((pAclSmi[3] & 0x01C0) >> 6) << 8); + + pAclUser->priact = (pAclSmi[2] & 0x00C0) >> 6; + pAclUser->pridx = (pAclSmi[2] & 0x003F) | (((pAclSmi[3] & 0x0200) >> 9) << 6); + + pAclUser->aclint = (pAclSmi[2] & 0x2000) >> 13; + pAclUser->gpio_en = (pAclSmi[2] & 0x1000) >> 12; + pAclUser->gpio_pin = (pAclSmi[2] & 0x0F00) >> 8; + + pAclUser->cact_ext = (pAclSmi[2] & 0xC000) >> 14; + pAclUser->tag_fmt = (pAclSmi[3] & 0x0003); + pAclUser->fwdact_ext = (pAclSmi[3] & 0x0004) >> 2; +} + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclActStUser2Smi(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) +{ + pAclSmi[0] |= (pAclUser->cvidx_cact & 0x003F); + pAclSmi[0] |= (pAclUser->cact & 0x0003) << 6; + pAclSmi[0] |= (pAclUser->svidx_sact & 0x003F) << 8; + pAclSmi[0] |= (pAclUser->sact & 0x0003) << 14; + + pAclSmi[1] |= (pAclUser->aclmeteridx & 0x003F); + pAclSmi[1] |= (pAclUser->fwdpmask & 0x00FF) << 6; + pAclSmi[1] |= (pAclUser->fwdact & 0x0003) << 14; + + pAclSmi[2] |= (pAclUser->pridx & 0x003F); + pAclSmi[2] |= (pAclUser->priact & 0x0003) << 6; + pAclSmi[2] |= (pAclUser->gpio_pin & 0x000F) << 8; + pAclSmi[2] |= (pAclUser->gpio_en & 0x0001) << 12; + pAclSmi[2] |= (pAclUser->aclint & 0x0001) << 13; + pAclSmi[2] |= (pAclUser->cact_ext & 0x0003) << 14; + + pAclSmi[3] |= (pAclUser->tag_fmt & 0x0003); + pAclSmi[3] |= (pAclUser->fwdact_ext & 0x0001) << 2; + pAclSmi[3] |= ((pAclUser->cvidx_cact & 0x0040) >> 6) << 3; + pAclSmi[3] |= ((pAclUser->svidx_sact & 0x0040) >> 6) << 4; + pAclSmi[3] |= ((pAclUser->aclmeteridx & 0x0040) >> 6) << 5; + pAclSmi[3] |= ((pAclUser->fwdpmask & 0x0700) >> 8) << 6; + pAclSmi[3] |= ((pAclUser->pridx & 0x0040) >> 6) << 9; +} + +/* Function Name: + * rtl8367c_setAsicAcl + * Description: + * Set port acl function enable/disable + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicAcl + * Description: + * Get port acl function enable/disable + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicAclUnmatchedPermit + * Description: + * Set port acl function unmatched permit action + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicAclUnmatchedPermit + * Description: + * Get port acl function unmatched permit action + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicAclRule + * Description: + * Set acl rule content + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclRule - ACL rule stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * System supported 95 shared 289-bit ACL ingress rule. Index was available at range 0-95 only. + * If software want to modify ACL rule, the ACL function should be disable at first or unspecify + * acl action will be executed. + * One ACL rule structure has three parts setting: + * Bit 0-147 Data Bits of this Rule + * Bit 148 Valid Bit + * Bit 149-296 Care Bits of this Rule + * There are four kinds of field in Data Bits and Care Bits: Active Portmask, Type, Tag Exist, and 8 fields + */ +ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule* pAclRule) +{ + rtl8367c_aclrulesmi aclRuleSmi; + rtk_uint16* tableAddr; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint32 i; + ret_t retVal; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); + + _rtl8367c_aclRuleStUser2Smi(pAclRule, &aclRuleSmi); + + /* Write valid bit = 0 */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); + else + regData = RTL8367C_ACLRULETBADDR(DATABITS, index); + retVal = rtl8367c_setAsicReg(regAddr,regData); + if(retVal !=RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0x1, 0); + if(retVal !=RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal !=RT_ERR_OK) + return retVal; + + + + /* Write ACS_ADR register */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); + else + regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Care Bits to ACS_DATA registers */ + tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; + regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; + + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr++; + tableAddr++; + } + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.care_bits_ext.rule_info >> 1) & 0x0007); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,regData); + if(retVal != RT_ERR_OK) + return retVal; + + + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); + else + regData = RTL8367C_ACLRULETBADDR(DATABITS, index); + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Data Bits to ACS_DATA registers */ + tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; + regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; + + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr++; + tableAddr++; + } + + retVal = rtl8367c_setAsicRegBit(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0, aclRuleSmi.valid); + if(retVal != RT_ERR_OK) + return retVal; + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.data_bits_ext.rule_info >> 1) & 0x0007); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register for care bits*/ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(&Rtl8370sVirtualAclRuleTable[index], &aclRuleSmi, sizeof(rtl8367c_aclrulesmi)); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclRule + * Description: + * Get acl rule content + * Input: + * index - ACL rule index (0-63) of 64 ACL rules + * pAclRule - ACL rule stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-63) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule) +{ + rtl8367c_aclrulesmi aclRuleSmi; + rtk_uint32 regAddr, regData; + ret_t retVal; + rtk_uint16* tableAddr; + rtk_uint32 i; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); + else + regData = RTL8367C_ACLRULETBADDR(DATABITS, index); + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Data Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + + regAddr ++; + tableAddr ++; + } + + /* Read Valid Bit */ + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + aclRuleSmi.valid = regData & 0x1; + /* Read active_portmsk_ext Bits */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + aclRuleSmi.data_bits_ext.rule_info = (regData % 0x0007) << 1; + + + /* Write ACS_ADR register for carebits*/ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); + else + regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Care Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + + regAddr ++; + tableAddr ++; + } + /* Read active_portmsk_ext care Bits */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + aclRuleSmi.care_bits_ext.rule_info = (regData & 0x0007) << 1; + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(&aclRuleSmi,&Rtl8370sVirtualAclRuleTable[index], sizeof(rtl8367c_aclrulesmi)); +#endif + + _rtl8367c_aclRuleStSmi2User(pAclRule, &aclRuleSmi); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclNot + * Description: + * Set rule comparison result inversion / no inversion + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * not - 1: inverse, 0: don't inverse + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not) +{ + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index < 64) + return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); + else + return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); + +} +/* Function Name: + * rtl8367c_getAsicAcl + * Description: + * Get rule comparison result inversion / no inversion + * Input: + * index - ACL rule index (0-95) of 95 ACL rules + * pNot - 1: inverse, 0: don't inverse + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot) +{ + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index < 64) + return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); + else + return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); + +} +/* Function Name: + * rtl8367c_setAsicAclTemplate + * Description: + * Set fields of a ACL Template + * Input: + * index - ACL template index(0~4) + * pAclType - ACL type stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) + * Note: + * The API can set type field of the 5 ACL rule templates. + * Each type has 8 fields. One field means what data in one field of a ACL rule means + * 8 fields of ACL rule 0~95 is descripted by one type in ACL group + */ +ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType) +{ + ret_t retVal; + rtk_uint32 i; + rtk_uint32 regAddr, regData; + + if(index >= RTL8367C_ACLTEMPLATENO) + return RT_ERR_OUT_OF_RANGE; + + regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); + + for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) + { + regData = pAclType->field[i*2+1]; + regData = regData << 8 | pAclType->field[i*2]; + + retVal = rtl8367c_setAsicReg(regAddr + i, regData); + + if(retVal != RT_ERR_OK) + return retVal; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAclTemplate + * Description: + * Get fields of a ACL Template + * Input: + * index - ACL template index(0~4) + * pAclType - ACL type stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType) +{ + ret_t retVal; + rtk_uint32 i; + rtk_uint32 regData, regAddr; + + if(index >= RTL8367C_ACLTEMPLATENO) + return RT_ERR_OUT_OF_RANGE; + + regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); + + for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) + { + retVal = rtl8367c_getAsicReg(regAddr + i,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pAclType->field[i*2] = regData & 0xFF; + pAclType->field[i*2 + 1] = (regData >> 8) & 0xFF; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclAct + * Description: + * Set ACL rule matched Action + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclAct - ACL action stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct) +{ + rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint16* tableAddr; + rtk_uint32 i; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); + _rtl8367c_aclActStUser2Smi(pAclAct, aclActSmi); + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + regData = index; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Data Bits to ACS_DATA registers */ + tableAddr = aclActSmi; + regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; + + for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr++; + tableAddr++; + } + + /* Write ACS_CMD register for care bits*/ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLACT); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(&Rtl8370sVirtualAclActTable[index][0], aclActSmi, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclAct + * Description: + * Get ACL rule matched Action + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclAct - ACL action stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct) +{ + rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint16 *tableAddr; + rtk_uint32 i; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + regData = index; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLACT); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Data Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + tableAddr = aclActSmi; + for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + + regAddr ++; + tableAddr ++; + } + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(aclActSmi, &Rtl8370sVirtualAclActTable[index][0], sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); +#endif + + _rtl8367c_aclActStSmi2User(pAclAct, aclActSmi); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclActCtrl + * Description: + * Set ACL rule matched Action Control Bits + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * aclActCtrl - 6 ACL Control Bits + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * ACL Action Control Bits Indicate which actions will be take when a rule matches + */ +ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl) +{ + ret_t retVal; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index >= 64) + retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); + else + retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAclActCtrl + * Description: + * Get ACL rule matched Action Control Bits + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclActCtrl - 6 ACL Control Bits + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *pAclActCtrl) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index >= 64) + retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); + else + retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); + + if(retVal != RT_ERR_OK) + return retVal; + + *pAclActCtrl = regData; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclPortRange + * Description: + * Set ACL TCP/UDP range check + * Input: + * index - TCP/UDP port range check table index + * type - Range check type + * upperPort - TCP/UDP port range upper bound + * lowerPort - TCP/UDP port range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index + * Note: + * None + */ +ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort) +{ + ret_t retVal; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, type); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, upperPort); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, lowerPort); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclPortRange + * Description: + * Get ACL TCP/UDP range check + * Input: + * index - TCP/UDP port range check table index + * pType - Range check type + * pUpperPort - TCP/UDP port range upper bound + * pLowerPort - TCP/UDP port range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index + * Note: + * None + */ +ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort) +{ + ret_t retVal; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, pType); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, pUpperPort); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, pLowerPort); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclVidRange + * Description: + * Set ACL VID range check + * Input: + * index - ACL VID range check index(0~15) + * type - Range check type + * upperVid - VID range upper bound + * lowerVid - VID range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + regData = ((type << RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET) & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) | + (upperVid & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK); + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, regData); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, lowerVid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclVidRange + * Description: + * Get ACL VID range check + * Input: + * index - ACL VID range check index(0~15) + * pType - Range check type + * pUpperVid - VID range upper bound + * pLowerVid - VID range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pType = (regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) >> RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET; + *pUpperVid = regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, pLowerVid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclIpRange + * Description: + * Set ACL IP range check + * Input: + * index - ACL IP range check index(0~15) + * type - Range check type + * upperIp - IP range upper bound + * lowerIp - IP range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp) +{ + ret_t retVal; + rtk_uint32 regData; + ipaddr_t ipData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, type); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = upperIp; + + regData = ipData & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = (ipData>>16) & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = lowerIp; + + regData = ipData & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = (ipData>>16) & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclIpRange + * Description: + * Get ACL IP range check + * Input: + * index - ACL IP range check index(0~15) + * pType - Range check type + * pUpperIp - IP range upper bound + * pLowerIp - IP range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp) +{ + ret_t retVal; + rtk_uint32 regData; + ipaddr_t ipData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, pType); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + ipData = regData; + + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = (regData <<16) | ipData; + *pUpperIp = ipData; + + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + ipData = regData; + + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = (regData << 16) | ipData; + *pLowerIp = ipData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicAclGpioPolarity + * Description: + * Set ACL Goip control palarity + * Input: + * polarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, polarity); +} +/* Function Name: + * rtl8367c_getAsicAclGpioPolarity + * Description: + * Get ACL Goip control palarity + * Input: + * pPolarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, pPolarity); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c new file mode 100755 index 00000000..d22bf65e --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Proprietary CPU-tag related function drivers + * + */ +#include +/* Function Name: + * rtl8367c_setAsicCputagEnable + * Description: + * Set cpu tag function enable/disable + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable/disable input + * Note: + * If CPU tag function is disabled, CPU tag will not be added to frame + * forwarded to CPU port, and all ports cannot parse CPU tag. + */ +ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled) +{ + if(enabled > 1) + return RT_ERR_ENABLE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicCputagEnable + * Description: + * Get cpu tag function enable/disable + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicCputagTrapPort + * Description: + * Set cpu tag trap port + * Input: + * port - port number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * API can set destination port of trapping frame + */ +ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port) +{ + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, port & 7); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, (port>>3) & 1); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicCputagTrapPort + * Description: + * Get cpu tag trap port + * Input: + * pPort - port number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort) +{ + ret_t retVal; + rtk_uint32 tmpPort; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, &tmpPort); + if(retVal != RT_ERR_OK) + return retVal; + *pPort = tmpPort; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, &tmpPort); + if(retVal != RT_ERR_OK) + return retVal; + *pPort |= (tmpPort & 1) << 3; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicCputagPortmask + * Description: + * Set ports that can parse CPU tag + * Input: + * portmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_CPU_PORT_MASK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicCputagPortmask + * Description: + * Get ports that can parse CPU tag + * Input: + * pPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_CPU_PORT_MASK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicCputagInsertMode + * Description: + * Set CPU-tag insert mode + * Input: + * mode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Actions not allowed by the function + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode) +{ + if(mode >= CPUTAG_INSERT_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicCputagInsertMode + * Description: + * Get CPU-tag insert mode + * Input: + * pMode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicCputagPriorityRemapping + * Description: + * Set queue assignment of CPU port + * Input: + * srcPri - internal priority (0~7) + * newPri - internal priority after remapping (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri) +{ + if((srcPri > RTL8367C_PRIMAX) || (newPri > RTL8367C_PRIMAX)) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), newPri); +} +/* Function Name: + * rtl8367c_getAsicCputagPriorityRemapping + * Description: + * Get queue assignment of CPU port + * Input: + * srcPri - internal priority (0~7) + * pNewPri - internal priority after remapping (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri) +{ + if(srcPri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), pNewPri); +} +/* Function Name: + * rtl8367c_setAsicCputagPosition + * Description: + * Set cpu tag insert position + * Input: + * postion - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 postion) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, postion); +} +/* Function Name: + * rtl8367c_getAsicCputagPosition + * Description: + * Get cpu tag insert position + * Input: + * pPostion - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, pPostion); +} + +/* Function Name: + * rtl8367c_setAsicCputagMode + * Description: + * Set cpu tag mode + * Input: + * mode - 1: 4bytes mode, 0: 8bytes mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters + * Note: + * If CPU tag function is disabled, CPU tag will not be added to frame + * forwarded to CPU port, and all ports cannot parse CPU tag. + */ +ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode) +{ + if(mode > 1) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicCputagMode + * Description: + * Get cpu tag mode + * Input: + * pMode - 1: 4bytes mode, 0: 8bytes mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, pMode); +} +/* Function Name: + * rtl8367c_setAsicCputagRxMinLength + * Description: + * Set cpu tag mode + * Input: + * mode - 1: 64bytes, 0: 72bytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters + * Note: + * If CPU tag function is disabled, CPU tag will not be added to frame + * forwarded to CPU port, and all ports cannot parse CPU tag. + */ +ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode) +{ + if(mode > 1) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicCputagRxMinLength + * Description: + * Get cpu tag mode + * Input: + * pMode - 1: 64bytes, 0: 72bytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, pMode); +} + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c new file mode 100755 index 00000000..73153e17 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : 802.1X related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsic1xPBEnConfig + * Description: + * Set 802.1x port-based port enable configuration + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsic1xPBEnConfig + * Description: + * Get 802.1x port-based port enable configuration + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsic1xPBAuthConfig + * Description: + * Set 802.1x port-based authorised port configuration + * Input: + * port - Physical port number (0~7) + * auth - 1: authorised, 0: non-authorised + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, auth); +} +/* Function Name: + * rtl8367c_getAsic1xPBAuthConfig + * Description: + * Get 802.1x port-based authorised port configuration + * Input: + * port - Physical port number (0~7) + * pAuth - 1: authorised, 0: non-authorised + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, pAuth); +} +/* Function Name: + * rtl8367c_setAsic1xPBOpdirConfig + * Description: + * Set 802.1x port-based operational direction + * Input: + * port - Physical port number (0~7) + * opdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, opdir); +} +/* Function Name: + * rtl8367c_getAsic1xPBOpdirConfig + * Description: + * Get 802.1x port-based operational direction + * Input: + * port - Physical port number (0~7) + * pOpdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32* pOpdir) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, pOpdir); +} +/* Function Name: + * rtl8367c_setAsic1xMBEnConfig + * Description: + * Set 802.1x mac-based port enable configuration + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsic1xMBEnConfig + * Description: + * Get 802.1x mac-based port enable configuration + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsic1xMBOpdirConfig + * Description: + * Set 802.1x mac-based operational direction + * Input: + * opdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir) +{ + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, opdir); +} +/* Function Name: + * rtl8367c_getAsic1xMBOpdirConfig + * Description: + * Get 802.1x mac-based operational direction + * Input: + * pOpdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir) +{ + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, pOpdir); +} +/* Function Name: + * rtl8367c_setAsic1xProcConfig + * Description: + * Set 802.1x unauth. behavior configuration + * Input: + * port - Physical port number (0~7) + * proc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_DOT1X_PROC - Unauthorized behavior error + * Note: + * None + */ +ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc) +{ + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(proc >= DOT1X_UNAUTH_END) + return RT_ERR_DOT1X_PROC; + + if(port < 8) + { + return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); + } + else + { + return rtl8367c_setAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); + } +} +/* Function Name: + * rtl8367c_getAsic1xProcConfig + * Description: + * Get 802.1x unauth. behavior configuration + * Input: + * port - Physical port number (0~7) + * pProc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32* pProc) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); +} +/* Function Name: + * rtl8367c_setAsic1xGuestVidx + * Description: + * Set 802.1x guest vlan index + * Input: + * index - 802.1x guest vlan index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_DOT1X_GVLANIDX - Invalid cvid index + * Note: + * None + */ +ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index) +{ + if(index >= RTL8367C_CVIDXNO) + return RT_ERR_DOT1X_GVLANIDX; + + return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, index); +} +/* Function Name: + * rtl8367c_getAsic1xGuestVidx + * Description: + * Get 802.1x guest vlan index + * Input: + * pIndex - 802.1x guest vlan index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex) +{ + return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, pIndex); +} +/* Function Name: + * rtl8367c_setAsic1xGVOpdir + * Description: + * Set 802.1x guest vlan talk to auth. DA + * Input: + * enabled - 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsic1xGVOpdir + * Description: + * Get 802.1x guest vlan talk to auth. DA + * Input: + * pEnabled - 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsic1xTrapPriority + * Description: + * Set 802.1x Trap priority + * Input: + * priority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK,priority); +} +/* Function Name: + * rtl8367c_getAsic1xTrapPriority + * Description: + * Get 802.1x Trap priority + * Input: + * pPriority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK, pPriority); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c new file mode 100755 index 00000000..370b7c6f --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c @@ -0,0 +1,877 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ethernet AV related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicEavMacAddress + * Description: + * Set PTP MAC address + * Input: + * mac - PTP mac + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint8*)&mac; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + for(i = 0; i <=2; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MAC_ADDR_H - i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicEavMacAddress + * Description: + * Get PTP MAC address + * Input: + * None + * Output: + * pMac - PTP mac + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint8*)pMac; + + for(i = 0; i <= 2; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC_ADDR_H - i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = (regData & 0xFF00) >> 8; + accessPtr ++; + *accessPtr = regData & 0xFF; + accessPtr ++; + } + + return retVal; +} + +/* Function Name: + * rtl8367c_setAsicEavTpid + * Description: + * Set PTP parser tag TPID. + * Input: + * outerTag - outter tag TPID + * innerTag - inner tag TPID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_OTAG_TPID, outerTag)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_ITAG_TPID, innerTag)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicEavTpid + * Description: + * Get PTP parser tag TPID. + * Input: + * None + * Output: + * pOuterTag - outter tag TPID + * pInnerTag - inner tag TPID + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_OTAG_TPID, pOuterTag)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_ITAG_TPID, pInnerTag)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicEavSysTime + * Description: + * Set PTP system time + * Input: + * second - seconds + * nanoSecond - nano seconds + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * The time granuality is 8 nano seconds. + */ +ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond) +{ + ret_t retVal; + rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; + rtk_uint32 nano_second_8; + rtk_uint32 regData, busyFlag, count; + + if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) + return RT_ERR_INPUT; + + regData = 0; + sec_h = second >>16; + sec_l = second & 0xFFFF; + nano_second_8 = nanoSecond >> 3; + nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; + nsec8_l = nano_second_8 &0xFFFF; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) + return retVal; + + regData = nsec8_h | (PTP_TIME_WRITE<= PTP_TIME_ADJ_END) + return RT_ERR_INPUT; + if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) + return RT_ERR_INPUT; + + regData = 0; + sec_h = second >>16; + sec_l = second & 0xFFFF; + nano_second_8 = nanoSecond >> 3; + nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; + nsec8_l = nano_second_8 &0xFFFF; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) + return retVal; + + if (PTP_TIME_ADJ_INC == type) + regData = nsec8_h | (PTP_TIME_INC<=PTP_TIME_CTRL_END) + return RT_ERR_INPUT; + + regData = 0; + if (PTP_TIME_CTRL_START == control) + regData = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; + else + regData = 0; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_CFG, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicEavSysTimeCtrl + * Description: + * Get PTP system time control + * Input: + * None + * Output: + * pControl - start or stop + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 mask; + + mask = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; + + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PTP_TIME_CFG, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData & mask) == mask) + *pControl = PTP_TIME_CTRL_START; + else if( (regData & mask) == 0) + *pControl = PTP_TIME_CTRL_STOP; + else + return RT_ERR_NOT_ALLOWED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicEavInterruptMask + * Description: + * Set PTP interrupt enable mask + * Input: + * imr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr) +{ + if ((imr&(RTL8367C_PTP_INTR_MASK<<8))>0) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, imr); +} +/* Function Name: + * rtl8367c_getAsicEavInterruptMask + * Description: + * Get PTP interrupt enable mask + * Input: + * pImr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, pImr); +} + +/* Function Name: + * rtl8367c_getAsicEavInterruptStatus + * Description: + * Get PTP interrupt port status mask + * Input: + * pIms - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:p0 interrupt, + * [1]:p1 interrupt, + * [2]:p2 interrupt, + * [3]:p3 interrupt, + * [4]:p4 interrupt, + */ +ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_INTERRUPT_CFG, RTL8367C_PTP_PORT_MASK, pIms); +} + +/* Function Name: + * rtl8367c_setAsicInterruptMask + * Description: + * Clear interrupt enable mask + * Input: + * ims - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * This API can be used to clear ASIC interrupt status and register will be cleared by writting 1. + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims) +{ + + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 5) + return rtl8367c_setAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK,ims); + else if(port == 5) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 6) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 7) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 9) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicInterruptStatus + * Description: + * Get interrupt enable mask + * Input: + * pIms - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms) +{ + + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + if(port < 5) + return rtl8367c_getAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK, pIms); + else if(port == 5) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK, pIms); + else if(port == 6) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + else if(port == 7) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + else if(port == 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + else if(port == 9) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + + return RT_ERR_OK; + +} + + +/* Function Name: + * rtl8367c_setAsicEavPortEnable + * Description: + * Set per-port EAV function enable/disable + * Input: + * port - Physical port number (0~9) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * If EAV function is enabled, PTP event messgae packet will be attached PTP timestamp for trapping + */ +ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 5) + return rtl8367c_setAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 5) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 6) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 7) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 8) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 9) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicEavPortEnable + * Description: + * Get per-port EAV function enable/disable + * Input: + * port - Physical port number (0~9) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + + + if(port < 5) + return rtl8367c_getAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 5) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 6) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 7) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 8) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 9) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicEavPortTimeStamp + * Description: + * Get PTP port time stamp + * Input: + * port - Physical port number (0~9) + * type - PTP packet type + * Output: + * timeStamp - seconds + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * The time granuality is 8 nano seconds. + */ +ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp) +{ + ret_t retVal; + rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; + rtk_uint32 nano_second_8; + + if(port > 9) + return RT_ERR_PORT_ID; + if(type >= PTP_PKT_TYPE_END) + return RT_ERR_INPUT; + + if(port < 5){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SEQ_ID(port, type), &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_H(port) , &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_L(port), &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_NSEC_H(port) , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_NSEC_L(port) , &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 5){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P5_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 6){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P6_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 7){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P7_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 8){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P8_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 9){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P9_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + } + + timeStamp->second = (sec_h<<16) | sec_l; + nano_second_8 = (nsec8_h<<16) | nsec8_l; + timeStamp->nano_second = nano_second_8<<3; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtl8367c_setAsicEavTrap + * Description: + * Set per-port PTP packet trap to CPU + * Input: + * port - Physical port number (0~5) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * If EAV trap enabled, switch will trap PTP packet to CPU + */ +ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicEavTimeSyncEn + * Description: + * Get per-port EPTP packet trap to CPU + * Input: + * port - Physical port number (0~5) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicEavEnable + * Description: + * Set per-port EAV function enable/disable + * Input: + * port - Physical port number (0~5) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * If EAV function is enabled, PTP event messgae packet will be attached PTP timestamp for trapping + */ +ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicEavEnable + * Description: + * Get per-port EAV function enable/disable + * Input: + * port - Physical port number (0~5) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicEavPriRemapping + * Description: + * Set non-EAV streaming priority remapping + * Input: + * srcpriority - Priority value + * priority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority) +{ + if(srcpriority > RTL8367C_PRIMAX || priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),priority); +} +/* Function Name: + * rtl8367c_getAsicEavPriRemapping + * Description: + * Get non-EAV streaming priority remapping + * Input: + * srcpriority - Priority value + * pPriority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority) +{ + if(srcpriority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),pPriority); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c new file mode 100755 index 00000000..f4dda6a6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 48989 $ + * $Date: 2014-07-01 15:45:24 +0800 (週二, 01 七月 2014) $ + * + * Purpose : RTL8370 switch high-level API for RTL8367C + * Feature : + * + */ + +#include +#include + +/* +@func ret_t | rtl8367c_setAsicEee100M | Set eee force mode function enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API set the 100M EEE enable function. + +*/ +ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if (enable > 1) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + if(enable) + regData |= (0x0001 << 1); + else + regData &= ~(0x0001 << 1); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicEee100M | Get 100M eee enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API get the 100M EEE function. +*/ +ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + *enable = (regData & (0x0001 << 1)) ? ENABLED : DISABLED; + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_setAsicEeeGiga | Set eee force mode function enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API set the 100M EEE enable function. + +*/ +ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if (enable > 1) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + if(enable) + regData |= (0x0001 << 2); + else + regData &= ~(0x0001 << 2); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicEeeGiga | Get 100M eee enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API get the 100M EEE function. +*/ +ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + *enable = (regData & (0x0001 << 2)) ? ENABLED : DISABLED; + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c new file mode 100755 index 00000000..28f49b1b --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c @@ -0,0 +1,1354 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Flow control related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicFlowControlSelect + * Description: + * Set system flow control type + * Input: + * select - System flow control type 1: Ingress flow control 0:Egress flow control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, select); +} +/* Function Name: + * rtl8367c_getAsicFlowControlSelect + * Description: + * Get system flow control type + * Input: + * pSelect - System flow control type 1: Ingress flow control 0:Egress flow control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, pSelect); +} +/* Function Name: + * rtl8367c_setAsicFlowControlJumboMode + * Description: + * Set Jumbo threhsold for flow control + * Input: + * enabled - Jumbo mode flow control 1: Enable 0:Disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicFlowControlJumboMode + * Description: + * Get Jumbo threhsold for flow control + * Input: + * pEnabled - Jumbo mode flow control 1: Enable 0:Disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicFlowControlJumboModeSize + * Description: + * Set Jumbo size for Jumbo mode flow control + * Input: + * size - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size) +{ + if(size >= FC_JUMBO_SIZE_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, size); +} +/* Function Name: + * rtl8367c_getAsicFlowControlJumboModeSize + * Description: + * Get Jumbo size for Jumbo mode flow control + * Input: + * pSize - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, pSize); +} + +/* Function Name: + * rtl8367c_setAsicFlowControlQueueEgressEnable + * Description: + * Set flow control ability for each queue + * Input: + * port - Physical port number (0~7) + * qid - Queue id + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, enabled); +} +/* Function Name: + * rtl8367c_getAsicFlowControlQueueEgressEnable + * Description: + * Get flow control ability for each queue + * Input: + * port - Physical port number (0~7) + * qid - Queue id + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicFlowControlDropAll + * Description: + * Set system-based drop parameters + * Input: + * dropall - Whole system drop threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall) +{ + if(dropall >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, dropall); +} +/* Function Name: + * rtl8367c_getAsicFlowControlDropAll + * Description: + * Get system-based drop parameters + * Input: + * pDropall - Whole system drop threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, pDropall); +} +/* Function Name: + * rtl8367c_setAsicFlowControlPauseAll + * Description: + * Set system-based all ports enable flow control parameters + * Input: + * threshold - Whole system pause all threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold) +{ + if(threshold >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, threshold); +} +/* Function Name: + * rtl8367c_getAsicFlowControlPauseAllThreshold + * Description: + * Get system-based all ports enable flow control parameters + * Input: + * pThreshold - Whole system pause all threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, pThreshold); +} +/* Function Name: + * rtl8367c_setAsicFlowControlSystemThreshold + * Description: + * Set system-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSystemThreshold + * Description: + * Get system-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSharedThreshold + * Description: + * Set share-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSharedThreshold + * Description: + * Get share-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortThreshold + * Description: + * Set Port-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortThreshold + * Description: + * Get Port-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortPrivateThreshold + * Description: + * Set Port-private-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortPrivateThreshold + * Description: + * Get Port-private-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSystemDropThreshold + * Description: + * Set system-based drop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSystemDropThreshold + * Description: + * Get system-based drop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSharedDropThreshold + * Description: + * Set share-based fdrop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, offThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSharedDropThreshold + * Description: + * Get share-based fdrop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, pOffThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortDropThreshold + * Description: + * Set Port-based drop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortDropThreshold + * Description: + * Get Port-based drop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, pOffThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortPrivateDropThreshold + * Description: + * Set Port-private-based drop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortPrivateDropThreshold + * Description: + * Get Port-private-based drop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, pOffThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSystemJumboThreshold + * Description: + * Set Jumbo system-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSystemJumboThreshold + * Description: + * Get Jumbo system-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSharedJumboThreshold + * Description: + * Set Jumbo share-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSharedJumboThreshold + * Description: + * Get Jumbo share-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortJumboThreshold + * Description: + * Set Jumbo Port-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortJumboThreshold + * Description: + * Get Jumbo Port-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortPrivateJumboThreshold + * Description: + * Set Jumbo Port-private-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortPrivateJumboThreshold + * Description: + * Get Jumbo Port-private-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, pOnThreshold); + + return retVal; +} + + + +/* Function Name: + * rtl8367c_setAsicEgressFlowControlQueueDropThreshold + * Description: + * Set Queue-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * qid - The queue id + * threshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold) +{ + if( threshold >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, threshold); +} +/* Function Name: + * rtl8367c_getAsicEgressFlowControlQueueDropThreshold + * Description: + * Get Queue-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * qid - The queue id + * pThreshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold) +{ + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, pThreshold); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlPortDropThreshold + * Description: + * Set port-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * port - Physical port number (0~7) + * threshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(threshold >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, threshold); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlPortDropThreshold + * Description: + * Set port-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * port - Physical port number (0~7) + * pThreshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, pThreshold); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlPortDropGap + * Description: + * Set port-based egress flow control turn off or ingress flow control drop off gap + * Input: + * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap) +{ + if(gap >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, gap); +} +/* Function Name: + * rtl8367c_getAsicEgressFlowControlPortDropGap + * Description: + * Get port-based egress flow control turn off or ingress flow control drop off gap + * Input: + * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, pGap); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlQueueDropGap + * Description: + * Set Queue-based egress flow control turn off or ingress flow control drop off gap + * Input: + * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap) +{ + if(gap >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, gap); +} +/* Function Name: + * rtl8367c_getAsicEgressFlowControlQueueDropGap + * Description: + * Get Queue-based egress flow control turn off or ingress flow control drop off gap + * Input: + * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, pGap); +} +/* Function Name: + * rtl8367c_getAsicEgressQueueEmptyPortMask + * Description: + * Get queue empty port mask + * Input: + * pPortmask - Queue empty port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, pPortmask); +} +/* Function Name: + * rtl8367c_getAsicTotalPage + * Description: + * Get system total page usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER, RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPulbicPage + * Description: + * Get system public page usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER, RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicMaxTotalPage + * Description: + * Get system total page max usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX, RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPulbicPage + * Description: + * Get system public page max usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX, RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPortPage + * Description: + * Get per-port page usage number + * Input: + * port - Physical port number (0~7) + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER+port - 8, RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPortPage + * Description: + * Get per-port page max usage number + * Input: + * port - Physical port number (0~7) + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX+port-8, RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); + + +} + +/* Function Name: + * rtl8367c_setAsicFlowControlEgressPortIndep + * Description: + * Set per-port egress flow control independent + * Input: + * port - Physical port number (0~7) + * enabled - Egress port flow control usage 1:enable 0:disable. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20), RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,enable); +} + +/* Function Name: + * rtl8367c_getAsicFlowControlEgressPortIndep + * Description: + * Get per-port egress flow control independent + * Input: + * port - Physical port number (0~7) + * enabled - Egress port flow control usage 1:enable 0:disable. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20),RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,pEnable); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c new file mode 100755 index 00000000..a3862385 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Green ethernet related functions + * + */ +#include + +/* Function Name: + * rtl8367c_getAsicGreenPortPage + * Description: + * Get per-Port ingress page usage per second + * Input: + * port - Physical port number (0~7) + * pPage - page number of ingress packet occuping per second + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * Ingress traffic occuping page number per second for high layer green feature usage + */ +ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 pageMeter; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pageMeter = regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port) + 1, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pageMeter = pageMeter + (regData << 16); + + *pPage = pageMeter; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicGreenTrafficType + * Description: + * Set traffic type for each priority + * Input: + * priority - internal priority (0~7) + * traffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype) +{ + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, (traffictype?1:0)); +} +/* Function Name: + * rtl8367c_getAsicGreenTrafficType + * Description: + * Get traffic type for each priority + * Input: + * priority - internal priority (0~7) + * pTraffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, pTraffictype); +} + +/* Function Name: + * rtl8367c_setAsicGreenHighPriorityTraffic + * Description: + * Set indicator which ASIC had received high priority traffic + * Input: + * port - Physical port number (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, 1); +} + + +/* Function Name: + * rtl8367c_getAsicGreenHighPriorityTraffic + * Description: + * Get indicator which ASIC had received high priority traffic or not + * Input: + * port - Physical port number (0~7) + * pIndicator - Have received high priority traffic indicator. If 1 means ASCI had received high priority in 1second checking priod + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, pIndicator); +} + +/* +@func rtk_int32 | rtl8367c_setAsicGreenEthernet | Set green ethernet function. +@parm rtk_uint32 | green | Green feature function usage 1:enable 0:disable. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@comm + The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic + detect the cable length and then select different power mode for best performance with minimums power consumption. Link down + ports will enter power savining mode in 10 seconds after the cable disconnected if power saving function is enabled. +*/ +ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green) +{ + ret_t retVal; + rtk_uint32 checkCounter; + rtk_uint32 regData; + rtk_uint32 phy_status; + rtk_uint32 patchData[6][2] = { {0x809A, 0x8911}, {0x80A3, 0x9233}, {0x80AC, 0xA444}, {0x809F, 0x6B20}, {0x80A8, 0x6B22}, {0x80B1, 0x6B23} }; + rtk_uint32 idx; + rtk_uint32 data; + + if (green > 1) + return RT_ERR_INPUT; + + /* 0xa420[2:0] */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA420, ®Data)) != RT_ERR_OK) + return retVal; + phy_status = (regData & 0x0007); + + if(phy_status == 3) + { + /* 0xb820[4] = 1 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= (0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 1 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + else + checkCounter = 0; + } + } + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (data) + { + case 0x0276: + case 0x0597: + case 0x6367: + if(green) + { + for(idx = 0; idx < 6; idx++ ) + { + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, patchData[idx][0])) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, patchData[idx][1])) != RT_ERR_OK) + return retVal; + } + } + break; + default: + break;; + } + + + + /* 0xa436 = 0x8011 */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) + return retVal; + + /* wr 0xa438[15] = 0: disable, 1: enable */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) + return retVal; + + if(green) + regData |= 0x8000; + else + regData &= 0x7FFF; + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, regData)) != RT_ERR_OK) + return retVal; + + if(phy_status == 3) + { + /* 0xb820[4] = 0 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 0 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + else + checkCounter = 0; + } + } + + return RT_ERR_OK; +} + +/* +@func rtk_int32 | rtl8367c_getAsicGreenEthernet | Get green ethernet function. +@parm rtk_uint32 | *green | Green feature function usage 1:enable 0:disable. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@comm + The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic + detect the cable length and then select different power mode for best performance with minimums power consumption. Link down + ports will enter power savining mode in 10 seconds after the cable disconnected if power saving function is enabled. +*/ +ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green) +{ + ret_t retVal; + rtk_uint32 regData; + + /* 0xa436 = 0x8011 */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) + return retVal; + + /* wr 0xa438[15] = 0: disable, 1: enable */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) + return retVal; + + if(regData & 0x8000) + *green = ENABLED; + else + *green = DISABLED; + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_setAsicPowerSaving | Set power saving mode +@parm rtk_uint32 | phy | phy number +@parm rtk_uint32 | enable | enable power saving mode. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@comm + The API can set power saving mode per phy. +*/ +ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + rtk_uint32 regData; + rtk_uint32 phy_status; + rtk_uint32 checkCounter; + + if (enable > 1) + return RT_ERR_INPUT; + + /* 0xa420[2:0] */ + if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xA420, ®Data)) != RT_ERR_OK) + return retVal; + + phy_status = (regData & 0x0007); + + if(phy_status == 3) + { + /* 0xb820[4] = 1 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= (0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 1 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) + { + checkCounter --; + if(0 == checkCounter) + { + return RT_ERR_BUSYWAIT_TIMEOUT; + } + } + else + checkCounter = 0; + } + } + + if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) + return retVal; + + phyData = phyData & ~(0x0001 << 2); + phyData = phyData | (enable << 2); + + if ((retVal = rtl8367c_setAsicPHYReg(phy,PHY_POWERSAVING_REG,phyData))!=RT_ERR_OK) + return retVal; + + if(phy_status == 3) + { + /* 0xb820[4] = 0 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 0 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) + { + checkCounter --; + if(0 == checkCounter) + { + return RT_ERR_BUSYWAIT_TIMEOUT; + } + } + else + checkCounter = 0; + } + } + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicPowerSaving | Get power saving mode +@parm rtk_uint32 | port | The port number +@parm rtk_uint32* | enable | enable power saving mode. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@comm + The API can get power saving mode per phy. +*/ +ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + + if(NULL == enable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) + return retVal; + + if ((phyData & 0x0004) > 0) + *enable = 1; + else + *enable = 0; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c new file mode 100755 index 00000000..435368d5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Field selector related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicFieldSelector + * Description: + * Set user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * format - Format of field selector + * offset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * System support 16 user defined field selctors. + * Each selector can be enabled or disable. User can defined retrieving 16-bits in many predefiend + * standard l2/l3/l4 payload. + */ +ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset) +{ + rtk_uint32 regData; + + if(index > RTL8367C_FIELDSEL_FORMAT_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if(format >= FIELDSEL_FORMAT_END) + return RT_ERR_OUT_OF_RANGE; + + regData = (((format << RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET) & RTL8367C_FIELD_SELECTOR_FORMAT_MASK ) | + ((offset << RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET) & RTL8367C_FIELD_SELECTOR_OFFSET_MASK )); + + return rtl8367c_setAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), regData); +} +/* Function Name: + * rtl8367c_getAsicFieldSelector + * Description: + * Get user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * pFormat - Format of field selector + * pOffset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pFormat = ((regData & RTL8367C_FIELD_SELECTOR_FORMAT_MASK) >> RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET); + *pOffset = ((regData & RTL8367C_FIELD_SELECTOR_OFFSET_MASK) >> RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET); + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c new file mode 100755 index 00000000..69f20a01 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 38651 $ + * $Date: 2016-02-27 14:32:56 +0800 (周三, 17 四月 2016) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : I2C related functions + * + */ + + +#include +#include +#include + + + +/* Function Name: + * rtl8367c_setAsicI2C_checkBusIdle + * Description: + * Check i2c bus status idle or not + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_BUSYWAIT_TIMEOUT - i2c bus is busy + * Note: + * This API can check i2c bus status. + */ +ret_t rtl8367c_setAsicI2C_checkBusIdle(void) +{ + rtk_uint32 regData; + ret_t retVal; + + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_M_I2C_BUS_IDLE_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + if(regData == 0x0001) + return RT_ERR_OK; /*i2c is idle*/ + else + return RT_ERR_BUSYWAIT_TIMEOUT; /*i2c is busy*/ +} + + +/* Function Name: + * rtl8367c_setAsicI2CStartCmd + * Description: + * Set I2C start command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set i2c start command ,start a i2c traffic . + */ +ret_t rtl8367c_setAsicI2CStartCmd(void) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0000, Start Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0001; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + +/* Function Name: + * rtl8367c_setAsicI2CStopCmd + * Description: + * Set I2C stop command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set i2c stop command ,stop a i2c traffic. + */ +ret_t rtl8367c_setAsicI2CStopCmd(void) +{ + + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0001, Stop Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0003; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + +/* Function Name: + * rtl8367c_setAsicI2CTxOneCharCmd + * Description: + * Set I2C Tx a char command, with a 8-bit data + * Input: + * oneChar - 8-bit data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set i2c Tx command and with a 8-bit data. + */ +ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0010, tx one char; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= 0xFFE0; + regData |= 0x0005; + regData &= 0x00FF; + regData |= (rtk_uint16) (oneChar << 8); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + + +/* Function Name: + * rtl8367c_setAsicI2CcheckRxAck + * Description: + * Check if rx an Ack + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can check if rx an ack from i2c slave. + */ +ret_t rtl8367c_setAsicI2CcheckRxAck(void) +{ + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 count = 0; + + do{ + count++; + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_SLV_ACK_FLAG_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( (regData != 0x1) && (count < TIMEROUT_FOR_MICROSEMI) ); + + if(regData != 0x1) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + + +/* Function Name: + * rtl8367c_setAsicI2CRxOneCharCmd + * Description: + * Set I2C Rx command and get 8-bit data + * Input: + * None + * Output: + * pValue - 8bit-data + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C Rx command and get 8-bit data. + */ +ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0011, Rx one char; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0007; + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + }while( (regData & 0x1) != 0x0); + + *pValue = (rtk_uint8)(regData >> 8); + return RT_ERR_OK ; + +} + +/* Function Name: + * rtl8367c_setAsicI2CTxAckCmd + * Description: + * Set I2C Tx ACK command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C Tx ack command. + */ +ret_t rtl8367c_setAsicI2CTxAckCmd(void) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0100, tx ACK Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0009; + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; + +} + + +/* Function Name: + * rtl8367c_setAsicI2CTxNoAckCmd + * Description: + * Set I2C master Tx noACK command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C master Tx noACK command. + */ +ret_t rtl8367c_setAsicI2CTxNoAckCmd(void) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0101, tx noACK Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x000b; + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; + +} + +/* Function Name: + * rtl8367c_setAsicI2CSoftRSTseqCmd + * Description: + * set I2C master tx soft reset command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C master tx soft reset command. + */ +ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void) +{ + + rtk_uint32 regData; + ret_t retVal; + + /*Bits [4-1] = 0b0110, tx soft reset Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x000d; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + + +/* Function Name: + * rtl8367c_setAsicI2CGpioPinGroup + * Description: + * set I2C function used gpio pins + * Input: + * pinGroup_ID - gpio pins group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_INPUT _ Invalid input parameter + * Note: + * This API can set I2C function used gpio pins. + * There are three group gpio pins + */ +ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID) +{ + rtk_uint32 regData; + ret_t retVal; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) + return retVal; + if( pinGroup_ID==0 ) + { + regData &= 0x0FFF; + regData |= 0x5000; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) + return retVal; + } + + else if( pinGroup_ID==1 ) + { + regData &= 0x0FFF; + regData |= 0xA000; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) + return retVal; + } + + else if( pinGroup_ID==2 ) + { + regData &= 0x0FFF; + regData |= 0xF000; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK ; + +} + +/* Function Name: + * rtl8367c_setAsicI2CGpioPinGroup + * Description: + * set I2C function used gpio pins + * Input: + * pinGroup_ID - gpio pins group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_INPUT _ Invalid input parameter + * Note: + * This API can set I2C function used gpio pins. + * There are three group gpio pins + */ +ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID) +{ + + rtk_uint32 regData; + ret_t retVal; + if( (retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xF000 ; + regData = (regData >> 12); + + if( regData == 0x5 ) + *pPinGroup_ID = 0; + else if(regData == 0xA) + *pPinGroup_ID = 1; + else if(regData == 0xF) + *pPinGroup_ID = 2; + else + return RT_ERR_FAILED; + return RT_ERR_OK ; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c new file mode 100755 index 00000000..e0e734d6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c @@ -0,0 +1,2109 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : IGMP related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicIgmp + * Description: + * Set IGMP/MLD state + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled) +{ + ret_t retVal; + + /* Enable/Disable H/W IGMP/MLD */ + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, enabled); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicIgmp + * Description: + * Get IGMP/MLD state + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIgmp(rtk_uint32 *ptr_enabled) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, ptr_enabled); + return retVal; +} +/* Function Name: + * rtl8367c_setAsicIpMulticastVlanLeaky + * Description: + * Set IP multicast VLAN Leaky function + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * When enabling this function, + * if the lookup result(forwarding portmap) of IP Multicast packet is over VLAN boundary, + * the packet can be forwarded across VLAN + */ +ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, enabled); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicIpMulticastVlanLeaky + * Description: + * Get IP multicast VLAN Leaky function + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *ptr_enabled) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, ptr_enabled); + + return retVal; +} + +/* Function Name: + * rtl8367c_setAsicIGMPTableFullOP + * Description: + * Set Table Full operation + * Input: + * operation - The operation should be taken when the IGMP table is full. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation) +{ + ret_t retVal; + + if(operation >= TABLE_FULL_OP_END) + return RT_ERR_OUT_OF_RANGE; + + /* Table full Operation */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, operation); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPTableFullOP + * Description: + * Get Table Full operation + * Input: + * None + * Output: + * poperation - The operation should be taken when the IGMP table is full. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *poperation) +{ + ret_t retVal; + rtk_uint32 value; + + /* Table full Operation */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *poperation = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPCRCErrOP + * Description: + * Set the operation when ASIC receive a Checksum error packet + * Input: + * operation -The operation when ASIC receive a Checksum error packet + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation) +{ + ret_t retVal; + + if(operation >= CRC_ERR_OP_END) + return RT_ERR_OUT_OF_RANGE; + + /* CRC Error Operation */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, operation); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPCRCErrOP + * Description: + * Get the operation when ASIC receive a Checksum error packet + * Input: + * None + * Output: + * poperation - The operation of Checksum error packet + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *poperation) +{ + ret_t retVal; + rtk_uint32 value; + + /* CRC Error Operation */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *poperation = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPFastLeaveEn + * Description: + * Enable/Disable Fast Leave + * Input: + * enabled - 1:enable Fast Leave; 0:disable Fast Leave + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled) +{ + ret_t retVal; + + /* Fast Leave */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, (enabled >= 1) ? 1 : 0); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPFastLeaveEn + * Description: + * Get Fast Leave state + * Input: + * None + * Output: + * penabled - 1:enable Fast Leave; 0:disable Fast Leave + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *penabled) +{ + ret_t retVal; + rtk_uint32 value; + + /* Fast Leave */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *penabled = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPLeaveTimer + * Description: + * Set the Leave timer of IGMP/MLD + * Input: + * leave_timer - Leave timer + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer) +{ + ret_t retVal; + + if(leave_timer > RTL8367C_MAX_LEAVE_TIMER) + return RT_ERR_OUT_OF_RANGE; + + /* Leave timer */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, leave_timer); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPLeaveTimer + * Description: + * Get the Leave timer of IGMP/MLD + * Input: + * None + * Output: + * pleave_timer - Leave timer + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pleave_timer) +{ + ret_t retVal; + rtk_uint32 value; + + /* Leave timer */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *pleave_timer = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPQueryInterval + * Description: + * Set Query Interval of IGMP/MLD + * Input: + * interval - Query Interval + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval) +{ + ret_t retVal; + + if(interval > RTL8367C_MAX_QUERY_INT) + return RT_ERR_OUT_OF_RANGE; + + /* Query Interval */ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, interval); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPQueryInterval + * Description: + * Get Query Interval of IGMP/MLD + * Input: + * None + * Output: + * pinterval - Query Interval + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pinterval) +{ + ret_t retVal; + rtk_uint32 value; + + /* Query Interval */ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *pinterval = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPRobVar + * Description: + * Set Robustness Variable of IGMP/MLD + * Input: + * rob_var - Robustness Variable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var) +{ + ret_t retVal; + + if(rob_var > RTL8367C_MAX_ROB_VAR) + return RT_ERR_OUT_OF_RANGE; + + /* Bourstness variable */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBURSTNESS_VAR_MASK, rob_var); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPRobVar + * Description: + * Get Robustness Variable of IGMP/MLD + * Input: + * none + * Output: + * prob_var - Robustness Variable + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *prob_var) +{ + ret_t retVal; + rtk_uint32 value; + + /* Bourstness variable */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBURSTNESS_VAR_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *prob_var = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPStaticRouterPort + * Description: + * Set IGMP static router port mask + * Input: + * pmsk - Static portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk) +{ + if(pmsk > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); +} + +/* Function Name: + * rtl8367c_getAsicIGMPStaticRouterPort + * Description: + * Get IGMP static router port mask + * Input: + * pmsk - Static portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pmsk) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); +} + +/* Function Name: + * rtl8367c_setAsicIGMPAllowDynamicRouterPort + * Description: + * Set IGMP dynamic router port allow mask + * Input: + * pmsk - Allow dynamic router port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pmsk); +} + +/* Function Name: + * rtl8367c_getAsicIGMPAllowDynamicRouterPort + * Description: + * Get IGMP dynamic router port allow mask + * Input: + * None. + * Output: + * pPmsk - Allow dynamic router port mask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pPmsk); +} + +/* Function Name: + * rtl8367c_getAsicIGMPdynamicRouterPort1 + * Description: + * Get 1st dynamic router port and timer + * Input: + * port - Physical port number (0~7) + * timer - router port timer + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *port, rtk_uint32 *timer) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_1_MASK, port); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_1_MASK, timer); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPdynamicRouterPort2 + * Description: + * Get 2nd dynamic router port and timer + * Input: + * port - Physical port number (0~7) + * timer - router port timer + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *port, rtk_uint32 *timer) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_2_MASK, port); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_2_MASK, timer); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPSuppression + * Description: + * Set the suppression function + * Input: + * report_supp_enabled - Report suppression, 1:Enable, 0:disable + * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPSuppression + * Description: + * Get the suppression function + * Input: + * report_supp_enabled - Report suppression, 1:Enable, 0:disable + * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *report_supp_enabled, rtk_uint32 *leave_supp_enabled) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPQueryRX + * Description: + * Set port-based Query packet RX allowance + * Input: + * port - port number + * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Query */ + if (port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPQueryRX + * Description: + * Get port-based Query packet RX allowance + * Input: + * port - port number + * Output: + * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *allow_query) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Query */ + if (port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + *allow_query = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPReportRX + * Description: + * Set port-based Report packet RX allowance + * Input: + * port - port number + * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Report */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPReportRX + * Description: + * Get port-based Report packet RX allowance + * Input: + * port - port number + * Output: + * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *allow_report) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Report */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + *allow_report = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPLeaveRX + * Description: + * Set port-based Leave packet RX allowance + * Input: + * port - port number + * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Leave */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPLeaveRX + * Description: + * Get port-based Leave packet RX allowance + * Input: + * port - port number + * Output: + * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *allow_leave) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Leave */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *allow_leave = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPMRPRX + * Description: + * Set port-based Multicast Routing Protocol packet RX allowance + * Input: + * port - port number + * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Multicast Routing Protocol */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPMRPRX + * Description: + * Get port-based Multicast Routing Protocol packet RX allowance + * Input: + * port - port number + * Output: + * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *allow_mrp) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Multicast Routing Protocol */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + *allow_mrp = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPMcDataRX + * Description: + * Set port-based Multicast data packet RX allowance + * Input: + * port - port number + * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop + * Output: + * none + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Multicast Data */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPMcDataRX + * Description: + * Get port-based Multicast data packet RX allowance + * Input: + * port - port number + * Output: + * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *allow_mcdata) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Multicast data */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *allow_mcdata = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPv1Opeartion + * Description: + * Set port-based IGMPv1 Control packet action + * Input: + * port - port number + * igmpv1_op - IGMPv1 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(igmpv1_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* IGMPv1 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPv1Opeartion + * Description: + * Get port-based IGMPv1 Control packet action + * Input: + * port - port number + * Output: + * igmpv1_op - IGMPv1 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *igmpv1_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* IGMPv1 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *igmpv1_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPv2Opeartion + * Description: + * Set port-based IGMPv2 Control packet action + * Input: + * port - port number + * igmpv2_op - IGMPv2 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(igmpv2_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* IGMPv2 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPv2Opeartion + * Description: + * Get port-based IGMPv2 Control packet action + * Input: + * port - port number + * Output: + * igmpv2_op - IGMPv2 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *igmpv2_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* IGMPv2 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *igmpv2_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPv3Opeartion + * Description: + * Set port-based IGMPv3 Control packet action + * Input: + * port - port number + * igmpv3_op - IGMPv3 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(igmpv3_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* IGMPv3 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPv3Opeartion + * Description: + * Get port-based IGMPv3 Control packet action + * Input: + * port - port number + * Output: + * igmpv3_op - IGMPv3 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *igmpv3_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* IGMPv3 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *igmpv3_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicMLDv1Opeartion + * Description: + * Set port-based MLDv1 Control packet action + * Input: + * port - port number + * mldv1_op - MLDv1 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(mldv1_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* MLDv1 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMLDv1Opeartion + * Description: + * Get port-based MLDv1 Control packet action + * Input: + * port - port number + * Output: + * mldv1_op - MLDv1 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *mldv1_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* MLDv1 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *mldv1_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicMLDv2Opeartion + * Description: + * Set port-based MLDv2 Control packet action + * Input: + * port - port number + * mldv2_op - MLDv2 control packet action + * Output: + * none + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(mldv2_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* MLDv2 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMLDv2Opeartion + * Description: + * Get port-based MLDv2 Control packet action + * Input: + * port - port number + * Output: + * mldv2_op - MLDv2 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *mldv2_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* MLDv2 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *mldv2_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPPortMAXGroup + * Description: + * Set per-port Max group number + * Input: + * port - Physical port number (0~7) + * max_group - max IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(max_group > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_OUT_OF_RANGE; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicIGMPPortMAXGroup + * Description: + * Get per-port Max group number + * Input: + * port - Physical port number (0~7) + * max_group - max IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *max_group) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *max_group = value; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicIGMPPortCurrentGroup + * Description: + * Get per-port current group number + * Input: + * port - Physical port number (0~7) + * current_group - current IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *current_group) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP + (port/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP + ((port - 8)/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *current_group = value; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicIGMPGroup + * Description: + * Get IGMP group + * Input: + * idx - Group index (0~255) + * valid - valid bit + * grp - IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Group index is out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *valid, rtl8367c_igmpgroup *grp) +{ + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint32 i; + rtk_uint32 groupInfo = 0; + + if(idx > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_OUT_OF_RANGE; + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + regData = idx; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_IGMP_GROUP); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Data Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + for(i = 0 ;i <= 1; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + groupInfo |= ((regData & 0xFFFF) << (i * 16)); + regAddr ++; + } + + grp->p0_timer = groupInfo & 0x00000007; + grp->p1_timer = (groupInfo >> 3) & 0x00000007; + grp->p2_timer = (groupInfo >> 6) & 0x00000007; + grp->p3_timer = (groupInfo >> 9) & 0x00000007; + grp->p4_timer = (groupInfo >> 12) & 0x00000007; + grp->p5_timer = (groupInfo >> 15) & 0x00000007; + grp->p6_timer = (groupInfo >> 18) & 0x00000007; + grp->p7_timer = (groupInfo >> 21) & 0x00000007; + grp->report_supp_flag = (groupInfo >> 24) & 0x00000001; + grp->p8_timer = (groupInfo >> 25) & 0x00000007; + grp->p9_timer = (groupInfo >> 28) & 0x00000007; + grp->p10_timer = (groupInfo >> 31) & 0x00000001; + + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE + 2; + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + grp->p10_timer |= (regData & 0x00000003) << 1; + + /* Valid bit */ + retVal = rtl8367c_getAsicReg(RTL8367C_IGMP_GROUP_USAGE_REG(idx), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *valid = ((regData & (0x0001 << (idx %16))) != 0) ? 1 : 0; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicIpMulticastPortIsoLeaky + * Description: + * Set IP multicast Port Isolation leaky + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIpMulticastPortIsoLeaky + * Description: + * Get IP multicast Port Isolation leaky + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *enabled) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *enabled = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPReportLeaveFlood + * Description: + * Set IGMP/MLD Report/Leave flood + * Input: + * flood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, flood); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPReportLeaveFlood + * Description: + * Get IGMP/MLD Report/Leave flood + * Input: + * None + * Output: + * pflood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pFlood = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPDropLeaveZero + * Description: + * Set the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * drop - 1: Drop, 0:Bypass + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, drop); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPDropLeaveZero + * Description: + * Get the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * None + * Output: + * pDrop - 1: Drop, 0:Bypass + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pDrop = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPBypassStormCTRL + * Description: + * Set the function of bypass strom control for IGMP/MLD packet + * Input: + * bypass - 1: Bypass, 0:not bypass + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, bypass); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPBypassStormCTRL + * Description: + * Set the function of bypass strom control for IGMP/MLD packet + * Input: + * None + * Output: + * pBypass - 1: Bypass, 0:not bypass + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pBypass = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPIsoLeaky + * Description: + * Set Port Isolation leaky for IGMP/MLD packet + * Input: + * leaky - 1: Leaky, 0:not leaky + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, leaky); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPIsoLeaky + * Description: + * Get Port Isolation leaky for IGMP/MLD packet + * Input: + * Noen + * Output: + * pLeaky - 1: Leaky, 0:not leaky + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pLeaky = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPVLANLeaky + * Description: + * Set VLAN leaky for IGMP/MLD packet + * Input: + * leaky - 1: Leaky, 0:not leaky + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, leaky); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPVLANLeaky + * Description: + * Get VLAN leaky for IGMP/MLD packet + * Input: + * Noen + * Output: + * pLeaky - 1: Leaky, 0:not leaky + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pLeaky = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPBypassGroup + * Description: + * Set IGMP/MLD Bypass group + * Input: + * bypassType - Bypass type + * enabled - enabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled) +{ + ret_t retVal; + rtk_uint32 offset; + + switch(bypassType) + { + case BYPASS_224_0_0_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; + break; + case BYPASS_224_0_1_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; + break; + case BYPASS_239_255_255_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; + break; + case BYPASS_IPV6_00XX: + offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; + break; + default: + return RT_ERR_INPUT; + } + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPBypassGroup + * Description: + * Get IGMP/MLD Bypass group + * Input: + * bypassType - Bypass type + * Output: + * pEnabled - enabled + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled) +{ + ret_t retVal; + rtk_uint32 offset; + + switch(bypassType) + { + case BYPASS_224_0_0_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; + break; + case BYPASS_224_0_1_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; + break; + case BYPASS_239_255_255_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; + break; + case BYPASS_IPV6_00XX: + offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; + break; + default: + return RT_ERR_INPUT; + } + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, pEnabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c new file mode 100755 index 00000000..abb36bec --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ingress bandwidth control related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicPortIngressBandwidth + * Description: + * Set per-port total ingress bandwidth + * Input: + * port - Physical port number (0~7) + * bandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable + * preifg - Include preamble and IFG, 0:Exclude, 1:Include + * enableFC - Action when input rate exceeds. 0: Drop 1: Flow Control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 regAddr; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(bandwidth > RTL8367C_QOS_GRANULARTY_MAX) + return RT_ERR_OUT_OF_RANGE; + + regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); + regData = bandwidth & RTL8367C_QOS_GRANULARTY_LSB_MASK; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr += 1; + regData = (bandwidth & RTL8367C_QOS_GRANULARTY_MSB_MASK) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, preifg); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, enableFC); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortIngressBandwidth + * Description: + * Get per-port total ingress bandwidth + * Input: + * port - Physical port number (0~7) + * pBandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable + * pPreifg - Include preamble and IFG, 0:Exclude, 1:Include + * pEnableFC - Action when input rate exceeds. 0: Drop 1: Flow Control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 regAddr; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pBandwidth = regData; + + regAddr += 1; + retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pBandwidth |= (regData << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, pPreifg); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, pEnableFC); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortIngressBandwidthBypass + * Description: + * Set ingress bandwidth control bypasss 8899, RMA 01-80-C2-00-00-xx and IGMP + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortIngressBandwidthBypass + * Description: + * Set ingress bandwidth control bypasss 8899, RMA 01-80-C2-00-00-xx and IGMP + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, pEnabled); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c new file mode 100755 index 00000000..fb6cbcdf --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Interrupt related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicInterruptPolarity + * Description: + * Set interrupt trigger polarity + * Input: + * polarity - 0:pull high 1: pull low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, polarity); +} +/* Function Name: + * rtl8367c_getAsicInterruptPolarity + * Description: + * Get interrupt trigger polarity + * Input: + * pPolarity - 0:pull high 1: pull low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, pPolarity); +} +/* Function Name: + * rtl8367c_setAsicInterruptMask + * Description: + * Set interrupt enable mask + * Input: + * imr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMR, imr); +} +/* Function Name: + * rtl8367c_getAsicInterruptMask + * Description: + * Get interrupt enable mask + * Input: + * pImr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMR, pImr); +} +/* Function Name: + * rtl8367c_setAsicInterruptMask + * Description: + * Clear interrupt enable mask + * Input: + * ims - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * This API can be used to clear ASIC interrupt status and register will be cleared by writting 1. + * [0]:Link change, + * [1]:Share meter exceed, + * [2]:Learn number overed, + * [3]:Speed Change, + * [4]:Tx special congestion + * [5]:1 second green feature + * [6]:loop detection + * [7]:interrupt from 8051 + * [8]:Cable diagnostic finish + * [9]:ACL action interrupt trigger + * [11]: Silent Start + */ +ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMS, ims); +} +/* Function Name: + * rtl8367c_getAsicInterruptStatus + * Description: + * Get interrupt enable mask + * Input: + * pIms - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMS, pIms); +} +/* Function Name: + * rtl8367c_setAsicInterruptRelatedStatus + * Description: + * Clear interrupt status + * Input: + * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status + * status - exceed status, write 1 to clear + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status) +{ + CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, + RTL8367C_REG_SPEED_CHANGE_INDICATOR, + RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, + RTL8367C_REG_PORT_LINKDOWN_INDICATOR, + RTL8367C_REG_PORT_LINKUP_INDICATOR, + RTL8367C_REG_METER_OVERRATE_INDICATOR0, + RTL8367C_REG_METER_OVERRATE_INDICATOR1, + RTL8367C_REG_RLDP_LOOPED_INDICATOR, + RTL8367C_REG_RLDP_RELEASED_INDICATOR, + RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; + + if(type >= INTRST_END ) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicReg(indicatorAddress[type], status); +} +/* Function Name: + * rtl8367c_getAsicInterruptRelatedStatus + * Description: + * Get interrupt status + * Input: + * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status + * pStatus - exceed status, write 1 to clear + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus) +{ + CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, + RTL8367C_REG_SPEED_CHANGE_INDICATOR, + RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, + RTL8367C_REG_PORT_LINKDOWN_INDICATOR, + RTL8367C_REG_PORT_LINKUP_INDICATOR, + RTL8367C_REG_METER_OVERRATE_INDICATOR0, + RTL8367C_REG_METER_OVERRATE_INDICATOR1, + RTL8367C_REG_RLDP_LOOPED_INDICATOR, + RTL8367C_REG_RLDP_RELEASED_INDICATOR, + RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; + + if(type >= INTRST_END ) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicReg(indicatorAddress[type], pStatus); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c new file mode 100755 index 00000000..11890281 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c @@ -0,0 +1,727 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LED related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicLedIndicateInfoConfig + * Description: + * Set Leds indicated information mode + * Input: + * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group + * config - Support 16 types configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. + * Definition LED Statuses Description + * 0000 LED_Off LED pin Tri-State. + * 0001 Dup/Col Collision, Full duplex Indicator. Blinking every 43ms when collision happens. Low for full duplex, and high for half duplex mode. + * 0010 Link/Act Link, Activity Indicator. Low for link established. Link/Act Blinks every 43ms when the corresponding port is transmitting or receiving. + * 0011 Spd1000 1000Mb/s Speed Indicator. Low for 1000Mb/s. + * 0100 Spd100 100Mb/s Speed Indicator. Low for 100Mb/s. + * 0101 Spd10 10Mb/s Speed Indicator. Low for 10Mb/s. + * 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. Low for 1000Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. Low for 100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. Low for 10Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. Low for 10/100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 1010 Fiber Fiber link Indicator. Low for Fiber. + * 1011 Fault Auto-negotiation Fault Indicator. Low for Fault. + * 1100 Link/Rx Link, Activity Indicator. Low for link established. Link/Rx Blinks every 43ms when the corresponding port is transmitting. + * 1101 Link/Tx Link, Activity Indicator. Low for link established. Link/Tx Blinks every 43ms when the corresponding port is receiving. + * 1110 Master Link on Master Indicator. Low for link Master established. + * 1111 LED_Force Force LED output, LED output value reference + */ +ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config) +{ + ret_t retVal; + CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO] = {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; + + if(ledno >= RTL8367C_LEDGROUPNO) + return RT_ERR_OUT_OF_RANGE; + + if(config >= LEDCONF_END) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 0); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], config); +} +/* Function Name: + * rtl8367c_getAsicLedIndicateInfoConfig + * Description: + * Get Leds indicated information mode + * Input: + * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group + * pConfig - Support 16 types configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig) +{ + CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO]= {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; + + if(ledno >= RTL8367C_LEDGROUPNO) + return RT_ERR_OUT_OF_RANGE; + + /* Get register value */ + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], pConfig); +} +/* Function Name: + * rtl8367c_setAsicLedGroupMode + * Description: + * Set Led Group mode + * Input: + * mode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(mode >= RTL8367C_LED_MODE_END) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 1); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicLedGroupMode + * Description: + * Get Led Group mode + * Input: + * pMode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData!=1) + return RT_ERR_FAILED; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicForceLeds + * Description: + * Set group LED mode + * Input: + * port - Physical port number (0~7) + * group - LED group number + * mode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode) +{ + rtk_uint16 regAddr; + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(group >= RTL8367C_LEDGROUPNO) + return RT_ERR_OUT_OF_RANGE; + + if(mode >= LEDFORCEMODE_END) + return RT_ERR_OUT_OF_RANGE; + /* Set Related Registers */ + if(port < 8){ + regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); + if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << (port * 2), mode)) != RT_ERR_OK) + return retVal; + }else if(port >= 8){ + regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); + if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << ((port-8) * 2), mode)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicForceLed + * Description: + * Get group LED mode + * Input: + * port - Physical port number (0~7) + * group - LED group number + * pMode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode) +{ + rtk_uint16 regAddr; + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(group >= RTL8367C_LEDGROUPNO) + return RT_ERR_INPUT; + + /* Get Related Registers */ + if(port < 8){ + regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); + if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << (port * 2), pMode)) != RT_ERR_OK) + return retVal; + }else if(port >= 8){ + regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); + if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << ((port-8) * 2), pMode)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicForceGroupLed + * Description: + * Turn on/off Led of all ports + * Input: + * group - LED group number + * mode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode) +{ + ret_t retVal; + rtk_uint32 i,bitmask; + CONST rtk_uint16 bits[3]= {0x0004,0x0010,0x0040}; + + /* Invalid input parameter */ + if(groupmask > RTL8367C_LEDGROUPMASK) + return RT_ERR_OUT_OF_RANGE; + + if(mode >= LEDFORCEMODE_END) + return RT_ERR_OUT_OF_RANGE; + + bitmask = 0; + for(i = 0; i < RTL8367C_LEDGROUPNO; i++) + { + if(groupmask & (1 << i)) + { + bitmask = bitmask | bits[i]; + } + + } + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, bitmask); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, mode); + + if(LEDFORCEMODE_NORMAL == mode) + retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, 0); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicForceGroupLed + * Description: + * Turn on/off Led of all ports + * Input: + * group - LED group number + * pMode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode) +{ + ret_t retVal; + rtk_uint32 i,regData; + CONST rtk_uint16 bits[3] = {0x0004,0x0010,0x0040}; + + /* Get Related Registers */ + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, ®Data)) != RT_ERR_OK) + return retVal; + + for(i = 0; i< RTL8367C_LEDGROUPNO; i++) + { + if((regData & bits[i]) == bits[i]) + { + *groupmask = *groupmask | (1 << i); + } + } + + return rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicLedBlinkRate + * Description: + * Set led blinking rate at mode 0 to mode 3 + * Input: + * blinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * LED blink rate can be at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms + */ +ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate) +{ + if(blinkRate >= LEDBLINKRATE_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, blinkRate); +} +/* Function Name: + * rtl8367c_getAsicLedBlinkRate + * Description: + * Get led blinking rate at mode 0 to mode 3 + * Input: + * pBlinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, pBlinkRate); +} +/* Function Name: + * rtl8367c_setAsicLedForceBlinkRate + * Description: + * Set LEd blinking rate for force mode led + * Input: + * blinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate) +{ + if(blinkRate >= LEDFORCERATE_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, blinkRate); +} +/* Function Name: + * rtl8367c_getAsicLedForceBlinkRate + * Description: + * Get LED blinking rate for force mode led + * Input: + * pBlinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, pBlinkRate); +} + +/* +@func ret_t | rtl8367c_setAsicLedGroupEnable | Turn on/off Led of all system ports +@parm rtk_uint32 | group | LED group id. +@parm rtk_uint32 | portmask | LED port mask. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. + */ +ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regDataMask; + + if ( group >= RTL8367C_LEDGROUPNO ) + return RT_ERR_INPUT; + + regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; + regDataMask = 0xFF << ((group%2)*8); + retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, portmask&0xff); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_REG_PARA_LED_IO_EN3; + regDataMask = 0x3 << (group*2); + retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicLedGroupEnable | Get on/off status of Led of all system ports +@parm rtk_uint32 | group | LED group id. +@parm rtk_uint32 | *portmask | LED port mask. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. + */ +ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regDataMask,regData; + + if ( group >= RTL8367C_LEDGROUPNO ) + return RT_ERR_INPUT; + + regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; + regDataMask = 0xFF << ((group%2)*8); + retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, portmask); + if(retVal != RT_ERR_OK) + return retVal; + + + regAddr = RTL8367C_REG_PARA_LED_IO_EN3; + regDataMask = 0x3 << (group*2); + retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *portmask = (regData << 8) | *portmask; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_setAsicLedOperationMode | Set LED operation mode +@parm rtk_uint32 | mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off led serial mode and set signal to active high/low. + */ +ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode) +{ + ret_t retVal; + + /* Invalid input parameter */ + if( mode >= LEDOP_END) + return RT_ERR_INPUT; + + switch(mode) + { + case LEDOP_PARALLEL: + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 0))!= RT_ERR_OK) + return retVal; + /*Disable serial CLK mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 0))!= RT_ERR_OK) + return retVal; + /*Disable serial DATA mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 0))!= RT_ERR_OK) + return retVal; + break; + case LEDOP_SERIAL: + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 1))!= RT_ERR_OK) + return retVal; + /*Enable serial CLK mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 1))!= RT_ERR_OK) + return retVal; + /*Enable serial DATA mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 1))!= RT_ERR_OK) + return retVal; + break; + default: + return RT_ERR_INPUT; + break; + } + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_getAsicLedOperationMode | Get LED OP mode setup +@parm rtk_uint32*| mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can get LED serial mode setup and get signal active high/low. + */ +ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode) +{ + ret_t retVal; + rtk_uint32 regData; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, ®Data))!= RT_ERR_OK) + return retVal; + + if (regData == 1) + *mode = LEDOP_SERIAL; + else if (regData == 0) + *mode = LEDOP_PARALLEL; + else + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_setAsicLedSerialModeConfig | Set LED serial mode +@parm rtk_uint32 | active | Active High or Low. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off led serial mode and set signal to active high/low. + */ +ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode) +{ + ret_t retVal; + + /* Invalid input parameter */ + if( active >= LEDSERACT_MAX) + return RT_ERR_INPUT; + if( serimode >= LEDSER_MAX) + return RT_ERR_INPUT; + + /* Set Active High or Low */ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active)) != RT_ERR_OK) + return retVal; + + /*set to 8G mode (not 16G mode)*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_getAsicLedSerialModeConfig | Get LED serial mode setup +@parm rtk_uint32*| active | Active High or Low. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can get LED serial mode setup and get signal active high/low. + */ +ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active))!= RT_ERR_OK) + return retVal; + + /*get to 8G mode (not 16G mode)*/ + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_setAsicLedOutputEnable | Set LED output enable +@parm rtk_uint32 | enabled | enable or disalbe. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off LED output Enable + */ +ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled) +{ + ret_t retVal; + rtk_uint32 regdata; + + if (enabled == 1) + regdata = 0; + else + regdata = 1; + + /* Enable/Disable H/W IGMP/MLD */ + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, regdata); + + return retVal; +} + + +/* +@func ret_t | rtl8367c_getAsicLedOutputEnable | Get LED serial mode setup +@parm rtk_uint32*| active | Active High or Low. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can get LED serial mode setup and get signal active high/low. + */ +ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled) +{ + ret_t retVal; + rtk_uint32 regdata; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, ®data); + if (retVal != RT_ERR_OK) + return retVal; + + if (regdata == 1) + *ptr_enabled = 0; + else + *ptr_enabled = 1; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLedSerialOutput + * Description: + * Set serial LED output group and portmask. + * Input: + * output - Serial LED output group + * pmask - Serial LED output portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, output); + if (retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pmask); + if (retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicLedSerialOutput + * Description: + * Get serial LED output group and portmask. + * Input: + * None + * Output: + * pOutput - Serial LED output group + * pPmask - Serial LED output portmask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask) +{ + ret_t retVal; + + if(pOutput == NULL) + return RT_ERR_NULL_POINTER; + + if(pPmask == NULL) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, pOutput); + if (retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pPmask); + if (retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c new file mode 100755 index 00000000..343a6f15 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c @@ -0,0 +1,1549 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LUT related functions + * + */ + +#include + +#include + +static void _rtl8367c_fdbStUser2Smi( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) +{ + /* L3 lookup */ + if(pLutSt->l3lookup) + { + if(pLutSt->l3vidlookup) + { + pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); + pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; + + pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); + pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; + + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; + + pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); + pFdbSmi[4] |= (pLutSt->l3_vid & 0x00FF) << 8; + + pFdbSmi[5] |= ((pLutSt->l3_vid & 0x0F00) >> 8); + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; + } + else + { + pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); + pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; + + pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); + pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; + + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; + + pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); + pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; + + pFdbSmi[5] |= (pLutSt->igmp_asic & 0x0001); + pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; + pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; + } + } + else if(pLutSt->mac.octet[0] & 0x01) /*Multicast L2 Lookup*/ + { + pFdbSmi[0] |= pLutSt->mac.octet[5]; + pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; + + pFdbSmi[1] |= pLutSt->mac.octet[3]; + pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; + + pFdbSmi[2] |= pLutSt->mac.octet[1]; + pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; + + pFdbSmi[3] |= pLutSt->cvid_fid; + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; + + pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); + pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; + + pFdbSmi[5] |= pLutSt->igmp_asic; + pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; + pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; + } + else /*Asic auto-learning*/ + { + pFdbSmi[0] |= pLutSt->mac.octet[5]; + pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; + + pFdbSmi[1] |= pLutSt->mac.octet[3]; + pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; + + pFdbSmi[2] |= pLutSt->mac.octet[1]; + pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; + + pFdbSmi[3] |= pLutSt->cvid_fid; + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->spa & 0x0008) >> 3) << 15; + + pFdbSmi[4] |= pLutSt->efid; + pFdbSmi[4] |= (pLutSt->fid & 0x000F) << 3; + pFdbSmi[4] |= (pLutSt->sa_en & 0x0001) << 7; + pFdbSmi[4] |= (pLutSt->spa & 0x0007) << 8; + pFdbSmi[4] |= (pLutSt->age & 0x0007) << 11; + pFdbSmi[4] |= (pLutSt->auth & 0x0001) << 14; + pFdbSmi[4] |= (pLutSt->sa_block & 0x0001) << 15; + + pFdbSmi[5] |= pLutSt->da_block; + pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; + pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + } +} + + +static void _rtl8367c_fdbStSmi2User( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) +{ + /*L3 lookup*/ + if(pFdbSmi[3] & 0x1000) + { + if(pFdbSmi[3] & 0x2000) + { + pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); + pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); + + pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); + pLutSt->l3_vid = ((pFdbSmi[4] & 0xFF00) >> 8) | (pFdbSmi[5] & 0x000F); + + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->l3vidlookup = (pFdbSmi[3] & 0x2000) >> 13; + pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; + } + else + { + pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); + pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); + + pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; + pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; + + pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); + pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; + + pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; + } + } + else if(pFdbSmi[2] & 0x0100) /*Multicast L2 Lookup*/ + { + pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; + pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); + pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; + pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); + pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; + pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); + + pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; + pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; + pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; + + pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); + pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; + + pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; + pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; + } + else /*Asic auto-learning*/ + { + pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; + pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); + pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; + pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); + pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; + pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); + + pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; + pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; + pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; + + pLutSt->sa_en = (pFdbSmi[4] & 0x0080) >> 7; + pLutSt->auth = (pFdbSmi[4] & 0x4000) >> 14; + pLutSt->spa = ((pFdbSmi[4] & 0x0700) >> 8) | (((pFdbSmi[3] & 0x8000) >> 15) << 3); + pLutSt->age = (pFdbSmi[4] & 0x3800) >> 11; + pLutSt->fid = (pFdbSmi[4] & 0x0078) >> 3; + pLutSt->efid = (pFdbSmi[4] & 0x0007); + pLutSt->sa_block = (pFdbSmi[4] & 0x8000) >> 15; + + pLutSt->da_block = (pFdbSmi[5] & 0x0001); + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; + pLutSt->nosalearn = (pFdbSmi[3] & 0x0020) >> 5; + } +} + +/* Function Name: + * rtl8367c_setAsicLutIpMulticastLookup + * Description: + * Set Lut IP multicast lookup function + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicLutIpMulticastLookup + * Description: + * Get Lut IP multicast lookup function + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicLutIpMulticastLookup + * Description: + * Set Lut IP multicast + VID lookup function + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicLutIpMulticastVidLookup + * Description: + * Get Lut IP multicast lookup function + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicLutIpLookupMethod + * Description: + * Set Lut IP lookup hash with DIP or {DIP,SIP} pair + * Input: + * type - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. + * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, type); +} +/* Function Name: + * rtl8367c_getAsicLutIpLookupMethod + * Description: + * Get Lut IP lookup hash with DIP or {DIP,SIP} pair + * Input: + * pType - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. + * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, pType); +} +/* Function Name: + * rtl8367c_setAsicLutAgeTimerSpeed + * Description: + * Set LUT agging out speed + * Input: + * timer - Agging out timer 0:Has been aged out + * speed - Agging out speed 0-fastest 3-slowest + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed) +{ + if(timer>RTL8367C_LUT_AGETIMERMAX) + return RT_ERR_OUT_OF_RANGE; + + if(speed >RTL8367C_LUT_AGESPEEDMAX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_CFG, RTL8367C_AGE_TIMER_MASK | RTL8367C_AGE_SPEED_MASK, (timer << RTL8367C_AGE_TIMER_OFFSET) | (speed << RTL8367C_AGE_SPEED_OFFSET)); +} +/* Function Name: + * rtl8367c_getAsicLutAgeTimerSpeed + * Description: + * Get LUT agging out speed + * Input: + * pTimer - Agging out timer 0:Has been aged out + * pSpeed - Agging out speed 0-fastest 3-slowest + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed) +{ + rtk_uint32 regData; + ret_t retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_LUT_CFG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pTimer = (regData & RTL8367C_AGE_TIMER_MASK) >> RTL8367C_AGE_TIMER_OFFSET; + + *pSpeed = (regData & RTL8367C_AGE_SPEED_MASK) >> RTL8367C_AGE_SPEED_OFFSET; + + return RT_ERR_OK; + +} +/* Function Name: + * rtl8367c_setAsicLutCamTbUsage + * Description: + * Configure Lut CAM table usage + * Input: + * enabled - L2 CAM table usage 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, enabled ? 0 : 1); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicLutCamTbUsage + * Description: + * Get Lut CAM table usage + * Input: + * pEnabled - L2 CAM table usage 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled) +{ + ret_t retVal; + rtk_uint32 regData; + + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + *pEnabled = regData ? 0 : 1; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicLutLearnLimitNo + * Description: + * Set per-Port auto learning limit number + * Input: + * port - Physical port number (0~7) + * number - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_PORTIDMAX, RTL8367C_LUT_LEARNLIMITMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ +ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(number > RTL8367C_LUT_LEARNLIMITMAX) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + if(port < 8) + return rtl8367c_setAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), number); + else + return rtl8367c_setAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, number); + +} +/* Function Name: + * rtl8367c_getAsicLutLearnLimitNo + * Description: + * Get per-Port auto learning limit number + * Input: + * port - Physical port number (0~7) + * pNumber - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_PORTIDMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ +ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), pNumber); + else + return rtl8367c_getAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, pNumber); +} + +/* Function Name: + * rtl8367c_setAsicSystemLutLearnLimitNo + * Description: + * Set system auto learning limit number + * Input: + * number - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_LUT_LEARNLIMITMAX*/ +ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number) +{ + if(number > RTL8367C_LUT_LEARNLIMITMAX) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + return rtl8367c_setAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, number); +} + +/* Function Name: + * rtl8367c_getAsicSystemLutLearnLimitNo + * Description: + * Get system auto learning limit number + * Input: + * port - Physical port number (0~7) + * pNumber - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber) +{ + if(NULL == pNumber) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, pNumber); +} + +/* Function Name: + * rtl8367c_setAsicLutLearnOverAct + * Description: + * Set auto learn over limit number action + * Input: + * action - Learn over action 0:normal, 1:drop 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * None + */ +ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action) +{ + if(action >= LRNOVERACT_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, action); +} +/* Function Name: + * rtl8367c_getAsicLutLearnOverAct + * Description: + * Get auto learn over limit number action + * Input: + * pAction - Learn over action 0:normal, 1:drop 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, pAction); +} + +/* Function Name: + * rtl8367c_setAsicSystemLutLearnOverAct + * Description: + * Set system auto learn over limit number action + * Input: + * action - Learn over action 0:normal, 1:drop, 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * None + */ +ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action) +{ + if(action >= LRNOVERACT_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, action); +} + +/* Function Name: + * rtl8367c_getAsicSystemLutLearnOverAct + * Description: + * Get system auto learn over limit number action + * Input: + * pAction - Learn over action 0:normal, 1:drop 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction) +{ + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, pAction); +} + +/* Function Name: + * rtl8367c_setAsicSystemLutLearnPortMask + * Description: + * Set system auto learn limit port mask + * Input: + * portmask - port mask of system learning limit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error port mask + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ +ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask) +{ + ret_t retVal; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, (portmask>>8) & 0x7); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_getAsicSystemLutLearnPortMask + * Description: + * Get system auto learn limit port mask + * Input: + * None + * Output: + * pPortmask - port mask of system learning limit + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ +ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpmask; + ret_t retVal; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, &tmpmask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpmask & 0xff; + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, &tmpmask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpmask & 0x7) << 8; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicL2LookupTb + * Description: + * Set filtering database entry + * Input: + * pL2Table - L2 table entry writing to 8K+64 filtering database + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; + rtk_uint32 tblCmd; + rtk_uint32 busyCounter; + + memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); + _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!regData) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + accessPtr = smil2Table; + regData = *accessPtr; + for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + + } + + tblCmd = (RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK); + /* Write Command */ + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); + if(retVal != RT_ERR_OK) + return retVal; + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!regData) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + /*Read access status*/ + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_hit = regData; + if(!pL2Table->lookup_hit) + return RT_ERR_FAILED; + + /*Read access address*/ + /* + retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->address = regData;*/ + + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); + pL2Table->lookup_busy = 0; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicL2LookupTb + * Description: + * Get filtering database entry + * Input: + * pL2Table - L2 table entry writing to 2K+64 filtering database + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving + * Note: + * None + */ +ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16* accessPtr; + rtk_uint32 i; + rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; + rtk_uint32 busyCounter; + rtk_uint32 tblCmd; + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!pL2Table->lookup_busy) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + + tblCmd = (method << RTL8367C_ACCESS_METHOD_OFFSET) & RTL8367C_ACCESS_METHOD_MASK; + + switch(method) + { + case LUTREADMETHOD_ADDRESS: + case LUTREADMETHOD_NEXT_ADDRESS: + case LUTREADMETHOD_NEXT_L2UC: + case LUTREADMETHOD_NEXT_L2MC: + case LUTREADMETHOD_NEXT_L3MC: + case LUTREADMETHOD_NEXT_L2L3MC: + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, pL2Table->address); + if(retVal != RT_ERR_OK) + return retVal; + break; + case LUTREADMETHOD_MAC: + memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); + _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); + + accessPtr = smil2Table; + regData = *accessPtr; + for(i=0; iaddress); + if(retVal != RT_ERR_OK) + return retVal; + + tblCmd = tblCmd | ((pL2Table->spa << RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET) & RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK); + + break; + default: + return RT_ERR_INPUT; + } + + tblCmd = tblCmd | ((RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK)); + /* Read Command */ + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); + if(retVal != RT_ERR_OK) + return retVal; + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!pL2Table->lookup_busy) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + pL2Table->lookup_hit = regData; + if(!pL2Table->lookup_hit) + return RT_ERR_L2_ENTRY_NOTFOUND; + + /*Read access address*/ + //retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); + + /*read L2 entry */ + memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); + + accessPtr = smil2Table; + + for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + accessPtr ++; + } + + _rtl8367c_fdbStSmi2User(pL2Table, smil2Table); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicLutLearnNo + * Description: + * Get per-Port auto learning number + * Input: + * port - Physical port number (0~7) + * pNumber - ASIC auto learning entries number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸ÄRTL8367C_PORTIDMAX, RTL8367C_REG_L2_LRN_CNT_REG, port10 reg is not contnious, wait for updating of base.h*/ +ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 10) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_REG(port), pNumber); + if (retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_CTRL10, pNumber); + if (retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLutFlushAll + * Description: + * Flush all entries in LUT. Includes static & dynamic entries + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushAll(void) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, 1); +} + +/* Function Name: + * rtl8367c_getAsicLutFlushAllStatus + * Description: + * Get Flush all status, 1:Busy, 0 normal + * Input: + * None + * Output: + * pBusyStatus - Busy state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus) +{ + if(NULL == pBusyStatus) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, pBusyStatus); +} + +/* Function Name: + * rtl8367c_setAsicLutForceFlush + * Description: + * Set per port force flush setting + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ + /*port8~port10µÄÉèÖÃÔÚÁíÍâÒ»¸öregister, wait for updating of base.h, reg.h*/ +ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask) +{ + ret_t retVal; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_FORCE_FLUSH_PORTMASK_MASK, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_PORTMASK1_MASK, (portmask >> 8) & 0x7); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicLutForceFlushStatus + * Description: + * Get per port force flush status + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ + /*port8~port10µÄÉèÖÃÔÚÁíÍâÒ»¸öregister, wait for updating of base.h, reg.h*/ +ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpMask; + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_BUSY_STATUS_MASK,&tmpMask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpMask & 0xff; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_BUSY_STATUS1_MASK,&tmpMask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpMask & 7) << 8; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicLutFlushMode + * Description: + * Set user force L2 pLutSt table flush mode + * Input: + * mode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Actions not allowed by the function + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode) +{ + if( mode >= FLUSHMDOE_END ) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicLutFlushMode + * Description: + * Get user force L2 pLutSt table flush mode + * Input: + * pMode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicLutFlushType + * Description: + * Get L2 LUT flush type + * Input: + * type - 0: dynamice unicast; 1: both dynamic and static unicast entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,type); +} +/* Function Name: + * rtl8367c_getAsicLutFlushType + * Description: + * Set L2 LUT flush type + * Input: + * pType - 0: dynamice unicast; 1: both dynamic and static unicast entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,pType); +} + + +/* Function Name: + * rtl8367c_setAsicLutFlushVid + * Description: + * Set VID of Port + VID pLutSt flush mode + * Input: + * vid - Vid (0~4095) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid) +{ + if( vid > RTL8367C_VIDMAX ) + return RT_ERR_VLAN_VID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, vid); +} +/* Function Name: + * rtl8367c_getAsicLutFlushVid + * Description: + * Get VID of Port + VID pLutSt flush mode + * Input: + * pVid - Vid (0~4095) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, pVid); +} +/* Function Name: + * rtl8367c_setAsicPortFlusdFid + * Description: + * Set FID of Port + FID pLutSt flush mode + * Input: + * fid - FID/MSTI for force flush + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid FID (0~15) + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid) +{ + if( fid > RTL8367C_FIDMAX ) + return RT_ERR_L2_FID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, fid); +} +/* Function Name: + * rtl8367c_getAsicLutFlushFid + * Description: + * Get FID of Port + FID pLutSt flush mode + * Input: + * pFid - FID/MSTI for force flush + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, pFid); +} +/* Function Name: + * rtl8367c_setAsicLutDisableAging + * Description: + * Set L2 LUT aging per port setting + * Input: + * port - Physical port number (0~7) + * disabled - 0: enable aging; 1: disabling aging + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸ÄRTL8367C_PORTIDMAX*/ +ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, disabled); +} +/* Function Name: + * rtl8367c_getAsicLutDisableAging + * Description: + * Get L2 LUT aging per port setting + * Input: + * port - Physical port number (0~7) + * pDisabled - 0: enable aging; 1: disabling aging + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸ÄRTL8367C_PORTIDMAX*/ +ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, pDisabled); +} + +/* Function Name: + * rtl8367c_setAsicLutIPMCGroup + * Description: + * Set IPMC Group Table + * Input: + * index - the entry index in table (0 ~ 63) + * group_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) + * vid - VLAN ID + * pmask - portmask + * valid - valid bit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid) +{ + rtk_uint32 regAddr, regData, bitoffset; + ipaddr_t ipData; + ret_t retVal; + + if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) + return RT_ERR_INPUT; + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + ipData = group_addr; + + if( (ipData & 0xF0000000) != 0xE0000000) /* not in 224.0.0.0 ~ 239.255.255.255 */ + return RT_ERR_INPUT; + + /* Group Address */ + regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); + regData = ((ipData & 0x0FFFFFFF) >> 16); + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + regAddr++; + regData = (ipData & 0x0000FFFF); + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + /* VID */ + regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; + regData = vid; + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + /* portmask */ + regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; + regData = pmask; + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + /* valid */ + regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); + bitoffset = index % 16; + if( (retVal = rtl8367c_setAsicRegBit(regAddr, bitoffset, valid)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicLutIPMCGroup + * Description: + * Set IPMC Group Table + * Input: + * index - the entry index in table (0 ~ 63) + * Output: + * pGroup_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) + * pVid - VLAN ID + * pPmask - portmask + * pValid - Valid bit + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid) +{ + rtk_uint32 regAddr, regData, bitoffset; + ipaddr_t ipData; + ret_t retVal; + + if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) + return RT_ERR_INPUT; + + if (NULL == pGroup_addr) + return RT_ERR_NULL_POINTER; + + if (NULL == pVid) + return RT_ERR_NULL_POINTER; + + if (NULL == pPmask) + return RT_ERR_NULL_POINTER; + + /* Group address */ + regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pGroup_addr = (((regData & 0x00000FFF) << 16) | 0xE0000000); + + regAddr++; + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + ipData = (*pGroup_addr | (regData & 0x0000FFFF)); + *pGroup_addr = ipData; + + /* VID */ + regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pVid = regData; + + /* portmask */ + regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pPmask = regData; + + /* valid */ + regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); + bitoffset = index % 16; + if( (retVal = rtl8367c_getAsicRegBit(regAddr, bitoffset, ®Data)) != RT_ERR_OK) + return retVal; + + *pValid = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLutLinkDownForceAging + * Description: + * Set LUT link down aging setting. + * Input: + * enable - link down aging setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable) +{ + if(enable > 1) + return RT_ERR_ENABLE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, enable ? 0 : 1); +} + +/* Function Name: + * rtl8367c_getAsicLutLinkDownForceAging + * Description: + * Get LUT link down aging setting. + * Input: + * pEnable - link down aging setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable) +{ + rtk_uint32 value; + ret_t retVal; + + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, &value)) != RT_ERR_OK) + return retVal; + + *pEnable = value ? 0 : 1; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLutIpmcFwdRouterPort + * Description: + * Set IPMC packet forward to rounter port also or not + * Input: + * enable - 1: Inlcude router port, 0, exclude router port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable) +{ + if(enable > 1) + return RT_ERR_ENABLE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, enable); +} + +/* Function Name: + * rtl8367c_getAsicLutIpmcFwdRouterPort + * Description: + * Get IPMC packet forward to rounter port also or not + * Input: + * None + * Output: + * pEnable - 1: Inlcude router port, 0, exclude router port + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable) +{ + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, pEnable); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c new file mode 100755 index 00000000..5412591a --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Shared meter related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicShareMeter + * Description: + * Set meter configuration + * Input: + * index - hared meter index (0-31) + * rate - 17-bits rate of share meter, unit is 8Kpbs + * ifg - Including IFG in rate calculation, 1:include 0:exclude + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg) +{ + ret_t retVal; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + { + /*19-bits Rate*/ + retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index), rate&0xFFFF); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index) + 1, (rate &0x70000) >> 16); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), ifg); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + /*19-bits Rate*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), rate&0xFFFF); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, (rate &0x70000) >> 16); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), ifg); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicShareMeter + * Description: + * Get meter configuration + * Input: + * index - hared meter index (0-31) + * pRate - 17-bits rate of share meter, unit is 8Kpbs + * pIfg - Including IFG in rate calculation, 1:include 0:exclude + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg) +{ + rtk_uint32 regData; + rtk_uint32 regData2; + ret_t retVal; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + { + /*17-bits Rate*/ + retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index) + 1, ®Data2); + if(retVal != RT_ERR_OK) + return retVal; + + *pRate = ((regData2 << 16) & 0x70000) | regData; + /*IFG*/ + retVal = rtl8367c_getAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), pIfg); + + return retVal; + } + else + { + /*17-bits Rate*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, ®Data2); + if(retVal != RT_ERR_OK) + return retVal; + + *pRate = ((regData2 << 16) & 0x70000) | regData; + /*IFG*/ + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), pIfg); + + return retVal; + } +} +/* Function Name: + * rtl8367c_setAsicShareMeterBucketSize + * Description: + * Set meter related leaky bucket threshold + * Input: + * index - hared meter index (0-31) + * lbthreshold - Leaky bucket threshold of meter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbthreshold) +{ + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_setAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), lbthreshold); + else + return rtl8367c_setAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, lbthreshold); +} +/* Function Name: + * rtl8367c_getAsicShareMeterBucketSize + * Description: + * Get meter related leaky bucket threshold + * Input: + * index - hared meter index (0-31) + * pLbthreshold - Leaky bucket threshold of meter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbthreshold) +{ + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_getAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), pLbthreshold); + else + return rtl8367c_getAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, pLbthreshold); +} + +/* Function Name: + * rtl8367c_setAsicShareMeterType + * Description: + * Set meter Type + * Input: + * index - shared meter index (0-31) + * Type - 0: kbps, 1: pps + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type) +{ + rtk_uint32 reg; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); + else + reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); + return rtl8367c_setAsicRegBit(reg, index % 16, type); +} + +/* Function Name: + * rtl8367c_getAsicShareMeterType + * Description: + * Get meter Type + * Input: + * index - shared meter index (0-31) + * Output: + * pType - 0: kbps, 1: pps + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType) +{ + rtk_uint32 reg; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if(index < 32) + reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); + else + reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); + return rtl8367c_getAsicRegBit(reg, index % 16, pType); +} + + +/* Function Name: + * rtl8367c_setAsicMeterExceedStatus + * Description: + * Clear shared meter status + * Input: + * index - hared meter index (0-31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index) +{ + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_setAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), 1); + else + return rtl8367c_setAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), 1); + +} +/* Function Name: + * rtl8367c_getAsicMeterExceedStatus + * Description: + * Get shared meter status + * Input: + * index - hared meter index (0-31) + * pStatus - 0: rate doesn't exceed 1: rate exceeds + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * If rate is over rate*8Kbps of a meter, the state bit of this meter is set to 1. + */ +ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus) +{ + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_getAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); + else + return rtl8367c_getAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c new file mode 100755 index 00000000..c9aaa01d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c @@ -0,0 +1,570 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : MIB related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicMIBsCounterReset + * Description: + * Reset global/queue manage or per-port MIB counter + * Input: + * greset - Global reset + * qmreset - Queue maganement reset + * portmask - Port reset mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 regBits; + + regBits = RTL8367C_GLOBAL_RESET_MASK | + RTL8367C_QM_RESET_MASK | + RTL8367C_MIB_PORT07_MASK | + ((rtk_uint32)0x7 << 13); + regData = ((greset << RTL8367C_GLOBAL_RESET_OFFSET) & RTL8367C_GLOBAL_RESET_MASK) | + ((qmreset << RTL8367C_QM_RESET_OFFSET) & RTL8367C_QM_RESET_MASK) | + (((portmask & 0xFF) << RTL8367C_PORT0_RESET_OFFSET) & RTL8367C_MIB_PORT07_MASK) | + (((portmask >> 8)&0x7) << 13); + + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL0, regBits, (regData >> RTL8367C_PORT0_RESET_OFFSET)); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicMIBsCounter + * Description: + * Get MIBs counter + * Input: + * port - Physical port number (0~7) + * mibIdx - MIB counter index + * pCounter - MIB retrived counter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving + * RT_ERR_STAT_CNTR_FAIL - MIB is resetting + * Note: + * Before MIBs counter retrieving, writting accessing address to ASIC at first and check the MIB + * control register status. If busy bit of MIB control is set, that means MIB counter have been + * waiting for preparing, then software must wait atfer this busy flag reset by ASIC. This driver + * did not recycle reading user desired counter. Software must use driver again to get MIB counter + * if return value is not RT_ERR_OK. + */ +ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port, RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint32 mibAddr; + rtk_uint32 mibOff=0; + + /* address offset to MIBs counter */ + CONST rtk_uint16 mibLength[RTL8367C_MIBS_NUMBER]= { + 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 4,2,2,2,2,2,2,2,2, + 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}; + + rtk_uint16 i; + rtk_uint64 mibCounter; + + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(mibIdx >= RTL8367C_MIBS_NUMBER) + return RT_ERR_STAT_INVALID_CNTR; + + if(dot1dTpLearnedEntryDiscards == mibIdx) + { + mibAddr = RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET; + } + else + { + i = 0; + mibOff = RTL8367C_MIB_PORT_OFFSET * port; + + if(port > 7) + mibOff = mibOff + 68; + + while(i < mibIdx) + { + mibOff += mibLength[i]; + i++; + } + + mibAddr = mibOff; + } + + + /*writing access counter address first*/ + /*This address is SRAM address, and SRAM address = MIB register address >> 2*/ + /*then ASIC will prepare 64bits counter wait for being retrived*/ + /*Write Mib related address to access control register*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); + if(retVal != RT_ERR_OK) + return retVal; + + + + /* polling busy flag */ + i = 100; + while(i > 0) + { + /*read MIB control register*/ + retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if((regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) == 0) + { + break; + } + + i--; + } + + if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) + return RT_ERR_BUSYWAIT_TIMEOUT; + + if(regData & RTL8367C_RESET_FLAG_MASK) + return RT_ERR_STAT_CNTR_FAIL; + + mibCounter = 0; + i = mibLength[mibIdx]; + if(4 == i) + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; + else + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + ((mibOff + 1) % 4); + + while(i) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + mibCounter = (mibCounter << 16) | (regData & 0xFFFF); + + regAddr --; + i --; + + } + + *pCounter = mibCounter; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMIBsLogCounter + * Description: + * Get MIBs Loggin counter + * Input: + * index - The index of 32 logging counter (0 ~ 31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Wrong index + * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving + * RT_ERR_STAT_CNTR_FAIL - MIB is resetting + * Note: + * This API get 32 logging counter + */ +ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint32 mibAddr; + rtk_uint16 i; + rtk_uint64 mibCounter; + + if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_ENTRY_INDEX; + + mibAddr = RTL8367C_MIB_LOG_CNT_OFFSET + ((index / 2) * 4); + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); + if(retVal != RT_ERR_OK) + return retVal; + + /*read MIB control register*/ + retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) + return RT_ERR_BUSYWAIT_TIMEOUT; + + if(regData & RTL8367C_RESET_FLAG_MASK) + return RT_ERR_STAT_CNTR_FAIL; + + mibCounter = 0; + if((index % 2) == 1) + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; + else + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 1; + + for(i = 0; i <= 1; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + + if(retVal != RT_ERR_OK) + return retVal; + + mibCounter = (mibCounter << 16) | (regData & 0xFFFF); + + regAddr --; + } + + *pCounter = mibCounter; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMIBsControl + * Description: + * Get MIB control register + * Input: + * pMask - MIB control status mask bit[0]-busy bit[1] + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * Software need to check this control register atfer doing port resetting or global resetting + */ +ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pMask = regData & (RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK | RTL8367C_RESET_FLAG_MASK); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicMIBsResetValue + * Description: + * Reset all counter to 0 or 1 + * Input: + * value - Reset to value 0 or 1 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); +} +/* Function Name: + * rtl8367c_getAsicMIBsResetValue + * Description: + * Reset all counter to 0 or 1 + * Input: + * value - Reset to value 0 or 1 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); +} + +/* Function Name: + * rtl8367c_setAsicMIBsUsageMode + * Description: + * MIB update mode + * Input: + * mode - 1: latch all MIBs by timer 0:normal free run counting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicMIBsUsageMode + * Description: + * MIB update mode + * Input: + * pMode - 1: latch all MIBs by timer 0:normal free run counting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, pMode); +} + +/* Function Name: + * rtl8367c_setAsicMIBsTimer + * Description: + * MIB latching timer + * Input: + * timer - latch timer, unit 1 second + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, timer); +} +/* Function Name: + * rtl8367c_getAsicMIBsTimer + * Description: + * MIB latching timer + * Input: + * pTimer - latch timer, unit 1 second + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, pTimer); +} +/* Function Name: + * rtl8367c_setAsicMIBsLoggingMode + * Description: + * MIB logging counter mode + * Input: + * index - logging counter mode index (0~15) + * mode - 0:32-bits mode 1:64-bits mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,mode); +} +/* Function Name: + * rtl8367c_getAsicMIBsLoggingMode + * Description: + * MIB logging counter mode + * Input: + * index - logging counter mode index (0~15) + * pMode - 0:32-bits mode 1:64-bits mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,pMode); +} + +/* Function Name: + * rtl8367c_setAsicMIBsLoggingType + * Description: + * MIB logging counter type + * Input: + * index - logging counter mode index (0~15) + * type - 0:Packet count 1:Byte count + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,type); +} + +/* Function Name: + * rtl8367c_getAsicMIBsLoggingType + * Description: + * MIB logging counter type + * Input: + * index - logging counter mode index (0~15) + * pType - 0:Packet count 1:Byte count + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,pType); +} + +/* Function Name: + * rtl8367c_setAsicMIBsResetLoggingCounter + * Description: + * MIB logging counter type + * Input: + * index - logging counter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index) +{ + ret_t retVal; + + if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if(index < 16) + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_CTRL1, 1< +/* Function Name: + * rtl8367c_setAsicPortMirror + * Description: + * Set port mirror function + * Input: + * source - Source port + * monitor - Monitor (destination) port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor) +{ + ret_t retVal; + + if((source > RTL8367C_PORTIDMAX) || (monitor > RTL8367C_PORTIDMAX)) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, source); + if(retVal != RT_ERR_OK) + return retVal; + + + return rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, monitor); +} +/* Function Name: + * rtl8367c_getAsicPortMirror + * Description: + * Get port mirror function + * Input: + * pSource - Source port + * pMonitor - Monitor (destination) port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, pSource); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, pMonitor); +} +/* Function Name: + * rtl8367c_setAsicPortMirrorRxFunction + * Description: + * Set the mirror function on RX of the mirrored + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorRxFunction + * Description: + * Get the mirror function on RX of the mirrored + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicPortMirrorTxFunction + * Description: + * Set the mirror function on TX of the mirrored + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorTxFunction + * Description: + * Get the mirror function on TX of the mirrored + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicPortMirrorIsolation + * Description: + * Set the traffic isolation on monitor port + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorIsolation + * Description: + * Get the traffic isolation on monitor port + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorMask + * Description: + * Set mirror source port mask + * Input: + * SourcePortmask - Source Portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK- Port Mask Error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask) +{ + if( SourcePortmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, SourcePortmask); +} + +/* Function Name: + * rtl8367c_getAsicPortMirrorMask + * Description: + * Get mirror source port mask + * Input: + * None + * Output: + * pSourcePortmask - Source Portmask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK- Port Mask Error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, pSourcePortmask); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorVlanRxLeaky + * Description: + * Set the mirror function of VLAN RX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorVlanRxLeaky + * Description: + * Get the mirror function of VLAN RX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorVlanTxLeaky + * Description: + * Set the mirror function of VLAN TX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorVlanTxLeaky + * Description: + * Get the mirror function of VLAN TX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorIsolationRxLeaky + * Description: + * Set the mirror function of Isolation RX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorIsolationRxLeaky + * Description: + * Get the mirror function of VLAN RX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorIsolationTxLeaky + * Description: + * Set the mirror function of Isolation TX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorIsolationTxLeaky + * Description: + * Get the mirror function of VLAN TX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorRealKeep + * Description: + * Set the mirror function of keep format + * Input: + * mode - 1: keep original format, 0: follow VLAN config + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorRealKeep + * Description: + * Get the mirror function of keep format + * Input: + * pMode - 1: keep original format, 0: follow VLAN config + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, pMode); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorOverride + * Description: + * Set the mirror function of override + * Input: + * rxMirror - 1: output rx Mirror format, 0: output forward format + * txMirror - 1: output tx Mirror format, 0: output forward format + * aclMirror - 1: output ACL Mirror format, 0: output forward format + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, rxMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, txMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, aclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicPortMirrorOverride + * Description: + * Get the mirror function of override + * Input: + * None + * Output: + * pRxMirror - 1: output rx Mirror format, 0: output forward format + * pTxMirror - 1: output tx Mirror format, 0: output forward format + * pAclMirror - 1: output ACL Mirror format, 0: output forward format + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, pRxMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, pTxMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, pAclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c new file mode 100755 index 00000000..2189b151 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Miscellaneous functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicMacAddress + * Description: + * Set switch MAC address + * Input: + * mac - switch mac + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint8*)&mac; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + for(i = 0; i <=2; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicMacAddress + * Description: + * Get switch MAC address + * Input: + * pMac - switch mac + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + + accessPtr = (rtk_uint8*)pMac; + + for(i = 0; i <= 2; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = (regData & 0xFF00) >> 8; + accessPtr ++; + *accessPtr = regData & 0xFF; + accessPtr ++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicDebugInfo + * Description: + * Get per-port packet forward debugging information + * Input: + * port - Physical port number (0~7) + * pDebugifo - per-port packet trap/drop/forward reason + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_DEBUG_INFO_REG(port), RTL8367C_DEBUG_INFO_MASK(port), pDebugifo); +} +/* Function Name: + * rtl8367c_setAsicPortJamMode + * Description: + * Set half duplex flow control setting + * Input: + * mode - 0: Back-Pressure 1: DEFER + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET,mode); +} +/* Function Name: + * rtl8367c_getAsicPortJamMode + * Description: + * Get half duplex flow control setting + * Input: + * pMode - 0: Back-Pressure 1: DEFER + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET, pMode); +} + +/* Function Name: + * rtl8367c_setAsicMaxLengthCfg + * Description: + * Set Max packet length configuration + * Input: + * cfgId - Configuration ID + * maxLength - Max Length + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, maxLength); +} + +/* Function Name: + * rtl8367c_getAsicMaxLengthCfg + * Description: + * Get Max packet length configuration + * Input: + * cfgId - Configuration ID + * maxLength - Max Length + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, pMaxLength); +} + +/* Function Name: + * rtl8367c_setAsicMaxLength + * Description: + * Set Max packet length + * Input: + * port - port ID + * type - 0: 10M/100M speed, 1: giga speed + * cfgId - Configuration ID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId) +{ + ret_t retVal; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, cfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, cfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMaxLength + * Description: + * Get Max packet length + * Input: + * port - port ID + * type - 0: 10M/100M speed, 1: giga speed + * cfgId - Configuration ID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId) +{ + ret_t retVal; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, pCfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, pCfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c new file mode 100755 index 00000000..1556f450 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : OAM related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicOamParser + * Description: + * Set OAM parser state + * Input: + * port - Physical port number (0~7) + * parser - Per-Port OAM parser state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid paser state + * Note: + * None + */ +ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(parser > OAM_PARFWDCPU) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port % 8), parser); +} +/* Function Name: + * rtl8367c_getAsicOamParser + * Description: + * Get OAM parser state + * Input: + * port - Physical port number (0~7) + * pParser - Per-Port OAM parser state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port%8), pParser); +} +/* Function Name: + * rtl8367c_setAsicOamMultiplexer + * Description: + * Set OAM multiplexer state + * Input: + * port - Physical port number (0~7) + * multiplexer - Per-Port OAM multiplexer state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid multiplexer state + * Note: + * None + */ +ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(multiplexer > OAM_MULCPU) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), multiplexer); +} +/* Function Name: + * rtl8367c_getAsicOamMultiplexer + * Description: + * Get OAM multiplexer state + * Input: + * port - Physical port number (0~7) + * pMultiplexer - Per-Port OAM multiplexer state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), pMultiplexer); +} +/* Function Name: + * rtl8367c_setAsicOamCpuPri + * Description: + * Set trap priority for OAM packet + * Input: + * priority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, priority); +} +/* Function Name: + * rtl8367c_getAsicOamCpuPri + * Description: + * Get trap priority for OAM packet + * Input: + * pPriority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, pPriority); +} +/* Function Name: + * rtl8367c_setAsicOamEnable + * Description: + * Set OAM function state + * Input: + * enabled - OAM function usage 1:enable, 0:disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicOamEnable + * Description: + * Get OAM function state + * Input: + * pEnabled - OAM function usage 1:enable, 0:disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, pEnabled); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c new file mode 100755 index 00000000..fb4db113 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : PHY related functions + * + */ +#include + +#if defined(MDC_MDIO_OPERATION) +/* Function Name: + * rtl8367c_setAsicPHYOCPReg + * Description: + * Set PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - OCP address + * ocpData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + if((retVal = rtl8367c_setAsicReg(regAddr, ocpData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicPHYOCPReg + * Description: + * Get PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - PHY address + * pRegData - read data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + if((retVal = rtl8367c_getAsicReg(regAddr, pRegData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +#else + +/* Function Name: + * rtl8367c_setAsicPHYOCPReg + * Description: + * Set PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - OCP address + * ocpData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 busyFlag, checkCounter; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + + /*Check internal phy access busy or not*/ + /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if(retVal != RT_ERR_OK) + return retVal; + + if(busyFlag) + return RT_ERR_BUSYWAIT_TIMEOUT; + + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access data*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA, ocpData); + if(retVal != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /*Set WRITE Command*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK | RTL8367C_RW_MASK); + + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if((retVal != RT_ERR_OK) || busyFlag) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + else + { + checkCounter = 0; + } + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicPHYOCPReg + * Description: + * Get PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - PHY address + * pRegData - read data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 busyFlag,checkCounter; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + /*Check internal phy access busy or not*/ + /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if(retVal != RT_ERR_OK) + return retVal; + + if(busyFlag) + return RT_ERR_BUSYWAIT_TIMEOUT; + + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /*Set READ Command*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK ); + if(retVal != RT_ERR_OK) + return retVal; + + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if((retVal != RT_ERR_OK) || busyFlag) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_FAILED; + } + else + { + checkCounter = 0; + } + } + + /*get PHY register*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_READ_DATA, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pRegData = regData; + + return RT_ERR_OK; +} + +#endif + +/* Function Name: + * rtl8367c_setAsicPHYReg + * Description: + * Set PHY registers + * Input: + * phyNo - Physical port number (0~7) + * phyAddr - PHY address (0~31) + * phyData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 phyData ) +{ + rtk_uint32 ocp_addr; + + if(phyAddr > RTL8367C_PHY_REGNOMAX) + return RT_ERR_PHY_REG_ID; + + ocp_addr = 0xa400 + phyAddr*2; + + return rtl8367c_setAsicPHYOCPReg(phyNo, ocp_addr, phyData); +} +/* Function Name: + * rtl8367c_getAsicPHYReg + * Description: + * Get PHY registers + * Input: + * phyNo - Physical port number (0~7) + * phyAddr - PHY address (0~31) + * pRegData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 *pRegData ) +{ + rtk_uint32 ocp_addr; + + if(phyAddr > RTL8367C_PHY_REGNOMAX) + return RT_ERR_PHY_REG_ID; + + ocp_addr = 0xa400 + phyAddr*2; + + return rtl8367c_getAsicPHYOCPReg(phyNo, ocp_addr, pRegData); +} + + +/* Function Name: + * rtl8367c_setAsicSdsReg + * Description: + * Set Serdes registers + * Input: + * sdsId - sdsid (0~1) + * sdsReg - reg address (0~31) + * sdsPage - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + + * Note: + * None + */ + +ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value) +{ + rtk_uint32 retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0|sdsId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_getAiscSdsReg + * Description: + * Get Serdes registers + * Input: + * sdsId - sdsid (0~1) + * sdsReg - reg address (0~31) + * sdsPage - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + + * Note: + * None + */ +ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value) +{ + rtk_uint32 retVal, busy; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080|sdsId)) != RT_ERR_OK) + return retVal; + + while(1) + { + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_CMD, &busy))!=RT_ERR_OK) + return retVal; + + if ((busy & 0x100) == 0) + break; + } + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c new file mode 100755 index 00000000..78e80a0b --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c @@ -0,0 +1,5752 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76333 $ + * $Date: 2017-03-09 09:33:15 +0800 (週四, 09 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port security related functions + * + */ + +#include + +#include + + +#define FIBER2_AUTO_INIT_SIZE 2038 +rtk_uint8 Fiber2_Auto[FIBER2_AUTO_INIT_SIZE] = { +0x02,0x05,0x8F,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x07,0x2C,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, +0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x80,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, +0x12,0x07,0xAB,0x7D,0x81,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0x82,0x7C,0x04, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x60,0x7C,0x69,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x83,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x07,0xAB,0x7D,0x28,0x7C,0x97,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x84, +0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0x85,0x7C,0x9D, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x10,0x7C, +0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x00, +0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x66,0xEF,0x44,0x40,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x66,0xEF,0x54,0xBF,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x66,0xEF,0x54,0xFD,0x54,0xFE, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x66,0xEF,0x44,0x02,0x44,0x01, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x07,0xAB,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, +0xAB,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x07,0xAB,0x12,0x07,0xDB,0x12, +0x01,0x27,0x12,0x06,0x1B,0x12,0x07,0x8A, +0x12,0x06,0xEA,0x7D,0x41,0x7C,0x00,0x7F, +0x36,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, +0xFE,0xFD,0x80,0x26,0x7F,0xFF,0x7E,0xFF, +0x7D,0x05,0x7C,0x00,0x90,0x06,0x24,0x12, +0x01,0x0F,0xC3,0x12,0x00,0xF2,0x50,0x1B, +0x90,0x06,0x24,0x12,0x01,0x03,0xEF,0x24, +0x01,0xFF,0xE4,0x3E,0xFE,0xE4,0x3D,0xFD, +0xE4,0x3C,0xFC,0x90,0x06,0x24,0x12,0x01, +0x1B,0x80,0xD1,0xC2,0x00,0xC2,0x01,0xD2, +0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62,0x12, +0x07,0x66,0xEF,0x30,0xE2,0x07,0xE4,0x90, +0x06,0x2C,0xF0,0x80,0xEE,0x90,0x06,0x2C, +0xE0,0x70,0x12,0x12,0x04,0xF0,0x90,0x06, +0x2C,0x74,0x01,0xF0,0xE4,0x90,0x06,0x33, +0xF0,0xA3,0xF0,0x80,0xD6,0xC3,0x90,0x06, +0x34,0xE0,0x94,0x62,0x90,0x06,0x33,0xE0, +0x94,0x00,0x40,0xC7,0xE4,0xF0,0xA3,0xF0, +0x12,0x04,0xF0,0x90,0x06,0x2C,0x74,0x01, +0xF0,0x80,0xB8,0x75,0x0F,0x80,0x75,0x0E, +0x7E,0x75,0x0D,0xAA,0x75,0x0C,0x83,0xE4, +0xF5,0x10,0x7F,0x36,0x7E,0x13,0x12,0x07, +0x66,0xEE,0xC4,0xF8,0x54,0xF0,0xC8,0xEF, +0xC4,0x54,0x0F,0x48,0x54,0x07,0xFB,0x7A, +0x00,0xEA,0x70,0x4A,0xEB,0x14,0x60,0x1C, +0x14,0x60,0x27,0x24,0xFE,0x60,0x31,0x14, +0x60,0x3C,0x24,0x05,0x70,0x38,0x75,0x0B, +0x00,0x75,0x0A,0xC2,0x75,0x09,0xEB,0x75, +0x08,0x0B,0x80,0x36,0x75,0x0B,0x40,0x75, +0x0A,0x59,0x75,0x09,0x73,0x75,0x08,0x07, +0x80,0x28,0x75,0x0B,0x00,0x75,0x0A,0xE1, +0x75,0x09,0xF5,0x75,0x08,0x05,0x80,0x1A, +0x75,0x0B,0xA0,0x75,0x0A,0xAC,0x75,0x09, +0xB9,0x75,0x08,0x03,0x80,0x0C,0x75,0x0B, +0x00,0x75,0x0A,0x62,0x75,0x09,0x3D,0x75, +0x08,0x01,0x75,0x89,0x11,0xE4,0x7B,0x60, +0x7A,0x09,0xF9,0xF8,0xAF,0x0B,0xAE,0x0A, +0xAD,0x09,0xAC,0x08,0x12,0x00,0x60,0xAA, +0x06,0xAB,0x07,0xC3,0xE4,0x9B,0xFB,0xE4, +0x9A,0xFA,0x78,0x17,0xF6,0xAF,0x03,0xEF, +0x08,0xF6,0x18,0xE6,0xF5,0x8C,0x08,0xE6, +0xF5,0x8A,0x74,0x0D,0x2B,0xFB,0xE4,0x3A, +0x18,0xF6,0xAF,0x03,0xEF,0x08,0xF6,0x75, +0x88,0x10,0x53,0x8E,0xC7,0xD2,0xA9,0x22, +0x7F,0x10,0x7E,0x13,0x12,0x07,0x66,0x90, +0x06,0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE, +0x44,0x10,0xFE,0x90,0x06,0x2D,0xF0,0xA3, +0xEF,0xF0,0x54,0xEF,0xFF,0x90,0x06,0x2D, +0xEE,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F, +0x10,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, +0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF,0x64, +0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C,0x00, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0xE4,0xFD,0xFC, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7F,0x10,0x7E, +0x13,0x12,0x07,0x66,0x90,0x06,0x2D,0xEE, +0xF0,0xA3,0xEF,0xF0,0xEE,0x54,0xEF,0x90, +0x06,0x2D,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD, +0x7F,0x10,0x7E,0x13,0x02,0x07,0xAB,0x78, +0x7F,0xE4,0xF6,0xD8,0xFD,0x75,0x81,0x3C, +0x02,0x05,0xD6,0x02,0x03,0x2F,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0x40,0x03,0xF6, +0x80,0x01,0xF2,0x08,0xDF,0xF4,0x80,0x29, +0xE4,0x93,0xA3,0xF8,0x54,0x07,0x24,0x0C, +0xC8,0xC3,0x33,0xC4,0x54,0x0F,0x44,0x20, +0xC8,0x83,0x40,0x04,0xF4,0x56,0x80,0x01, +0x46,0xF6,0xDF,0xE4,0x80,0x0B,0x01,0x02, +0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x07, +0xE7,0xE4,0x7E,0x01,0x93,0x60,0xBC,0xA3, +0xFF,0x54,0x3F,0x30,0xE5,0x09,0x54,0x1F, +0xFE,0xE4,0x93,0xA3,0x60,0x01,0x0E,0xCF, +0x54,0xC0,0x25,0xE0,0x60,0xA8,0x40,0xB8, +0xE4,0x93,0xA3,0xFA,0xE4,0x93,0xA3,0xF8, +0xE4,0x93,0xA3,0xC8,0xC5,0x82,0xC8,0xCA, +0xC5,0x83,0xCA,0xF0,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xDF,0xE9,0xDE, +0xE7,0x80,0xBE,0x7D,0x40,0x7C,0x17,0x7F, +0x11,0x7E,0x1D,0x12,0x07,0xAB,0x7F,0x41, +0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, +0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, +0x1D,0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15, +0x7F,0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D, +0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, +0x07,0xAB,0x7D,0x40,0x7C,0x11,0x7F,0x00, +0x7E,0x62,0x12,0x07,0xAB,0x02,0x02,0x2F, +0x7D,0xC0,0x7C,0x16,0x7F,0x11,0x7E,0x1D, +0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15,0x7F, +0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D,0x0D, +0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07, +0xAB,0x7F,0x41,0x7E,0x1D,0x12,0x07,0x66, +0xEF,0x44,0x20,0x44,0x80,0xFD,0xAC,0x06, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0xAB,0x7D, +0x00,0x7C,0x21,0x7F,0x00,0x7E,0x62,0x12, +0x07,0xAB,0x02,0x02,0x2F,0x7D,0x40,0x7C, +0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xAB, +0x7D,0xBB,0x7C,0x15,0x7F,0xEB,0x7E,0x13, +0x12,0x07,0xAB,0x7D,0x0C,0x7C,0x00,0x7F, +0xE7,0x7E,0x13,0x12,0x07,0xAB,0x7F,0x41, +0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, +0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, +0x1D,0x12,0x07,0xAB,0x7D,0x40,0x7C,0x11, +0x7F,0x00,0x7E,0x62,0x12,0x07,0xAB,0x02, +0x02,0x2F,0x7D,0x04,0x7C,0x00,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x80,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, +0x7F,0x02,0x7E,0x66,0x12,0x07,0x66,0xEF, +0x44,0x02,0x44,0x04,0xFD,0xAC,0x06,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x04, +0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x02,0x07,0xAB,0xC0,0xE0,0xC0,0xF0, +0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75,0xD0, +0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5,0x8C, +0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06,0x31, +0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E,0x90, +0x06,0x33,0xE4,0x75,0xF0,0x01,0x12,0x00, +0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82,0xD0, +0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2,0xAF, +0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D,0xA3, +0x75,0xA0,0x01,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xAE,0xA1, +0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7,0xD2, +0xAF,0x22,0x7D,0x20,0x7C,0x0F,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x01,0x7C, +0x00,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x02,0x07,0xAB,0xC2,0xAF,0xAB,0x07,0xAA, +0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, +0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, +0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x7F, +0x0C,0x7E,0x13,0x12,0x07,0x66,0xEF,0x44, +0x50,0xFD,0xAC,0x06,0x7F,0x0C,0x7E,0x13, +0x02,0x07,0xAB,0x12,0x07,0xC7,0x12,0x07, +0xF2,0x12,0x04,0x2B,0x02,0x00,0x03,0x42, +0x06,0x33,0x00,0x00,0x42,0x06,0x31,0x00, +0x00,0x00,0xE4,0xF5,0x8E,0x22,}; + +#define FIBER2_1G_INIT_SIZE 2032 +rtk_uint8 Fiber2_1G[FIBER2_1G_INIT_SIZE] = { +0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, +0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, +0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, +0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, +0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, +0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, +0x01,0x27,0x12,0x06,0x9F,0x7D,0x41,0x7C, +0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, +0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, +0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, +0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, +0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, +0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, +0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, +0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, +0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, +0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, +0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, +0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, +0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, +0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, +0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, +0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, +0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, +0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, +0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, +0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, +0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, +0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, +0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, +0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, +0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, +0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, +0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, +0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, +0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, +0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, +0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, +0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, +0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, +0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, +0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, +0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, +0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, +0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, +0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, +0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, +0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, +0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, +0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, +0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, +0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, +0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, +0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, +0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, +0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, +0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, +0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, +0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, +0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, +0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, +0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, +0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, +0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, +0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, +0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, +0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, +0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, +0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, +0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, +0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, +0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, +0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, +0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, +0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, +0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, +0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, +0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, +0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, +0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, +0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, +0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, +0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, +0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, +0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, +0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, +0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, +0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, +0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, +0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, +0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, +0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, +0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, +0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, +0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; + +#define FIBER2_100M_INIT_SIZE 2032 +rtk_uint8 Fiber2_100M[FIBER2_100M_INIT_SIZE] = { +0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, +0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, +0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, +0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, +0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, +0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, +0x01,0x27,0x12,0x06,0x5A,0x7D,0x41,0x7C, +0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, +0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, +0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, +0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, +0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, +0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, +0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, +0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, +0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, +0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, +0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, +0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, +0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, +0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, +0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, +0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, +0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, +0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, +0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, +0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, +0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, +0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, +0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, +0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, +0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, +0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, +0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, +0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, +0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, +0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, +0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, +0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, +0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, +0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, +0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, +0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, +0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, +0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, +0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, +0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, +0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, +0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, +0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, +0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, +0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, +0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, +0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, +0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, +0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, +0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, +0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, +0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, +0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, +0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, +0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, +0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, +0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, +0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, +0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, +0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, +0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, +0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, +0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, +0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, +0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, +0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, +0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, +0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, +0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, +0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, +0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, +0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, +0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, +0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, +0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, +0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, +0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, +0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, +0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, +0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, +0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, +0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, +0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, +0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, +0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, +0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, +0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, +0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; + + +#define SGMII_INIT_SIZE 1183 +rtk_uint8 Sgmii_Init[SGMII_INIT_SIZE] = { +0x02,0x03,0x81,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x04,0x0D,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x04,0x6B,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x04, +0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x04,0x6B,0x12,0x04,0x92,0x7D, +0x41,0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12, +0x04,0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25, +0xE4,0x7F,0x20,0x7E,0x4E,0xFD,0xFC,0x90, +0x06,0x24,0x12,0x01,0x0F,0xC3,0x12,0x00, +0xF2,0x50,0x1B,0x90,0x06,0x24,0x12,0x01, +0x03,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, +0xE4,0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06, +0x24,0x12,0x01,0x1B,0x80,0xD2,0xC2,0x00, +0xC2,0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01, +0x7E,0x62,0x12,0x04,0x47,0xEF,0x30,0xE2, +0x07,0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE, +0x90,0x06,0x2C,0xE0,0x70,0x12,0x12,0x02, +0xDB,0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4, +0x90,0x06,0x2F,0xF0,0xA3,0xF0,0x80,0xD6, +0xC3,0x90,0x06,0x30,0xE0,0x94,0x62,0x90, +0x06,0x2F,0xE0,0x94,0x00,0x40,0xC7,0xE4, +0xF0,0xA3,0xF0,0x12,0x02,0xDB,0x90,0x06, +0x2C,0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F, +0x80,0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75, +0x0C,0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E, +0x13,0x12,0x04,0x47,0xEE,0xC4,0xF8,0x54, +0xF0,0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54, +0x07,0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB, +0x14,0x60,0x1C,0x14,0x60,0x27,0x24,0xFE, +0x60,0x31,0x14,0x60,0x3C,0x24,0x05,0x70, +0x38,0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75, +0x09,0xEB,0x75,0x08,0x0B,0x80,0x36,0x75, +0x0B,0x40,0x75,0x0A,0x59,0x75,0x09,0x73, +0x75,0x08,0x07,0x80,0x28,0x75,0x0B,0x00, +0x75,0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08, +0x05,0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A, +0xAC,0x75,0x09,0xB9,0x75,0x08,0x03,0x80, +0x0C,0x75,0x0B,0x00,0x75,0x0A,0x62,0x75, +0x09,0x3D,0x75,0x08,0x01,0x75,0x89,0x11, +0xE4,0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF, +0x0B,0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12, +0x00,0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4, +0x9B,0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6, +0xAF,0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5, +0x8C,0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B, +0xFB,0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF, +0x08,0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7, +0xD2,0xA9,0x22,0x7D,0x02,0x7C,0x00,0x7F, +0x4A,0x7E,0x13,0x12,0x04,0x6B,0x7D,0x46, +0x7C,0x71,0x7F,0x02,0x7E,0x66,0x12,0x04, +0x6B,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4, +0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF, +0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C, +0x00,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, +0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, +0xFC,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, +0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, +0xFC,0x7F,0x4A,0x7E,0x13,0x12,0x04,0x6B, +0x7D,0x06,0x7C,0x71,0x7F,0x02,0x7E,0x66, +0x12,0x04,0x6B,0x7D,0x03,0x7C,0x00,0x7F, +0x01,0x7E,0x66,0x12,0x04,0x6B,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x02,0x04, +0x6B,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x03,0xC8,0x02,0x01,0x27, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x04,0x87,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0xC0,0xE0,0xC0, +0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, +0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, +0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, +0x2D,0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E, +0x90,0x06,0x2F,0xE4,0x75,0xF0,0x01,0x12, +0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82, +0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, +0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, +0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, +0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, +0xD2,0xAF,0x22,0xC2,0xAF,0xAB,0x07,0xAA, +0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, +0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, +0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x42, +0x06,0x2F,0x00,0x00,0x42,0x06,0x2D,0x00, +0x00,0x00,0x12,0x04,0x9B,0x12,0x02,0x16, +0x02,0x00,0x03,0xE4,0xF5,0x8E,0x22,}; + + +/* Function Name: + * rtl8367c_setAsicPortUnknownDaBehavior + * Description: + * Set UNDA behavior + * Input: + * port - port ID + * behavior - 0: flooding to unknwon DA portmask; 1: drop; 2:trap; 3: flooding + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid behavior + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(behavior >= L2_UNDA_BEHAVE_END) + return RT_ERR_NOT_ALLOWED; + + if(port < 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), behavior); + else + return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), behavior); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownDaBehavior + * Description: + * Get UNDA behavior + * Input: + * port - port ID + * Output: + * pBehavior - 0: flooding to unknwon DA portmask; 1: drop; 2:trap; 3: flooding + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), pBehavior); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), pBehavior); +} +/* Function Name: + * rtl8367c_setAsicPortUnknownSaBehavior + * Description: + * Set UNSA behavior + * Input: + * behavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid behavior + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior) +{ + if(behavior >= L2_BEHAVE_SA_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, behavior); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownSaBehavior + * Description: + * Get UNSA behavior + * Input: + * pBehavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior) +{ + return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, pBehavior); +} +/* Function Name: + * rtl8367c_setAsicPortUnmatchedSaBehavior + * Description: + * Set Unmatched SA behavior + * Input: + * behavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid behavior + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior) +{ + if(behavior >= L2_BEHAVE_SA_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, behavior); +} +/* Function Name: + * rtl8367c_getAsicPortUnmatchedSaBehavior + * Description: + * Get Unmatched SA behavior + * Input: + * pBehavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior) +{ + return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, pBehavior); +} + +/* Function Name: + * rtl8367c_setAsicPortUnmatchedSaMoving + * Description: + * Set Unmatched SA moving state + * Input: + * port - Port ID + * enabled - 0: can't move to new port; 1: can move to new port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Error Port ID + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, (enabled == 1) ? 0 : 1); +} + +/* Function Name: + * rtl8367c_getAsicPortUnmatchedSaMoving + * Description: + * Get Unmatched SA moving state + * Input: + * port - Port ID + * Output: + * pEnabled - 0: can't move to new port; 1: can move to new port + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Error Port ID + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + rtk_uint32 data; + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, &data)) != RT_ERR_OK) + return retVal; + + *pEnabled = (data == 1) ? 0 : 1; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicPortUnknownDaFloodingPortmask + * Description: + * Set UNDA flooding portmask + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownDaFloodingPortmask + * Description: + * Get UNDA flooding portmask + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortUnknownMulticastFloodingPortmask + * Description: + * Set UNMC flooding portmask + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownMulticastFloodingPortmask + * Description: + * Get UNMC flooding portmask + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortBcastFloodingPortmask + * Description: + * Set Bcast flooding portmask + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicPortBcastFloodingPortmask + * Description: + * Get Bcast flooding portmask + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortBlockSpa + * Description: + * Set disabling blocking frame if source port and destination port are the same + * Input: + * port - Physical port number (0~7) + * permit - 0: block; 1: permit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 permit) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, permit); +} +/* Function Name: + * rtl8367c_getAsicPortBlockSpa + * Description: + * Get disabling blocking frame if source port and destination port are the same + * Input: + * port - Physical port number (0~7) + * pPermit - 0: block; 1: permit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32* pPermit) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, pPermit); +} +/* Function Name: + * rtl8367c_setAsicPortDos + * Description: + * Set DOS function + * Input: + * type - DOS type + * drop - 0: permit; 1: drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid payload index + * Note: + * None + */ +ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop) +{ + if(type >= DOS_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type, drop); +} +/* Function Name: + * rtl8367c_getAsicPortDos + * Description: + * Get DOS function + * Input: + * type - DOS type + * pDrop - 0: permit; 1: drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid payload index + * Note: + * None + */ +ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop) +{ + if(type >= DOS_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type,pDrop); +} +/* Function Name: + * rtl8367c_setAsicPortForceLink + * Description: + * Set port force linking configuration + * Input: + * port - Physical port number (0~7) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) +{ + rtk_uint32 regData = 0; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + regData |= pPortAbility->forcemode << 12; + regData |= pPortAbility->mstfault << 9; + regData |= pPortAbility->mstmode << 8; + regData |= pPortAbility->nway << 7; + regData |= pPortAbility->txpause << 6; + regData |= pPortAbility->rxpause << 5; + regData |= pPortAbility->link << 4; + regData |= pPortAbility->duplex << 2; + regData |= pPortAbility->speed; + + return rtl8367c_setAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT+port, regData); +} +/* Function Name: + * rtl8367c_getAsicPortForceLink + * Description: + * Get port force linking configuration + * Input: + * port - Physical port number (0~7) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) +{ + ret_t retVal; + rtk_uint32 regData; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT + port, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (regData >> 12) & 0x0001; + pPortAbility->mstfault = (regData >> 9) & 0x0001; + pPortAbility->mstmode = (regData >> 8) & 0x0001; + pPortAbility->nway = (regData >> 7) & 0x0001; + pPortAbility->txpause = (regData >> 6) & 0x0001; + pPortAbility->rxpause = (regData >> 5) & 0x0001; + pPortAbility->link = (regData >> 4) & 0x0001; + pPortAbility->duplex = (regData >> 2) & 0x0001; + pPortAbility->speed = regData & 0x0003; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortStatus + * Description: + * Get port link status + * Input: + * port - Physical port number (0~7) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus) +{ + ret_t retVal; + rtk_uint32 regData; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT0_STATUS+port,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pPortStatus->lpi1000 = (regData >> 11) & 0x0001; + pPortStatus->lpi100 = (regData >> 10) & 0x0001; + pPortStatus->mstfault = (regData >> 9) & 0x0001; + pPortStatus->mstmode = (regData >> 8) & 0x0001; + pPortStatus->nway = (regData >> 7) & 0x0001; + pPortStatus->txpause = (regData >> 6) & 0x0001; + pPortStatus->rxpause = (regData >> 5) & 0x0001; + pPortStatus->link = (regData >> 4) & 0x0001; + pPortStatus->duplex = (regData >> 2) & 0x0001; + pPortStatus->speed = regData & 0x0003; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortForceLinkExt + * Description: + * Set external interface force linking configuration + * Input: + * id - external interface id (0~2) + * portAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) +{ + rtk_uint32 retVal, regValue, regValue2, type, sgmiibit, hisgmiibit; + rtk_uint32 reg_data = 0; + rtk_uint32 i = 0; + + /* Invalid input parameter */ + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + + reg_data |= pPortAbility->forcemode << 12; + reg_data |= pPortAbility->mstfault << 9; + reg_data |= pPortAbility->mstmode << 8; + reg_data |= pPortAbility->nway << 7; + reg_data |= pPortAbility->txpause << 6; + reg_data |= pPortAbility->rxpause << 5; + reg_data |= pPortAbility->link << 4; + reg_data |= pPortAbility->duplex << 2; + reg_data |= pPortAbility->speed; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + /*get chip ID */ + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + if (1 == type) + { + if(1 == id) + { + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_REG_TO_ECO4, ®Value)) != RT_ERR_OK) + return retVal; + + if((regValue & (0x0001 << 5)) && (regValue & (0x0001 << 7))) + { + return RT_ERR_OK; + } + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + } + + if(0 == id || 1 == id) + return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE + id, reg_data); + else + return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, reg_data); + } + else if (2 == type) + { + if (1 == id) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + } + else if (2 == id) + { + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1dc1, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + } + + } + else if(3 == type) + { + if(1 == id) + { + if((retVal = rtl8367c_getAsicRegBit(0x1d11, 6, &sgmiibit)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, &hisgmiibit)) != RT_ERR_OK) + return retVal; + + if ((sgmiibit == 1) || (hisgmiibit == 1)) + { + /*for 1000x/100fx/1000x_100fx, param has to be set to serdes registers*/ + if((retVal = rtl8367c_getAsicReg(0x1d41, ®Value)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib =1, bit7: cfg_mac6_fib2=1*/ + if((regValue & 0xa0) == 0xa0) + { + /* new_cfg_sds_mode */ + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + + /*1000X*/ + if(regValue2 == 0x4) + { +#if 0 + /* new_cfg_sds_mode:reset mode */ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + /* Enable new sds mode config */ + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= (~0x80); + + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= (~0x100); + + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*new_cfg_sds_mode=1000x*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x5) + { +#if 0 + /*100FX*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + /*cfg_sds_mode_sel_new=1 */ + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= (~0x80); + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= (~0x100); + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + /* new_cfg_sds_mode=1000x */ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x7) + { +#if 0 + /*100FX*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= (~0x80); + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &=(~0x100); + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + /*sds_mode:*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + + } + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + + } + + /* new_cfg_sds_mode */ + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + if(regValue2 == 0x2) + { +#if 0 + /*SGMII*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + /* 0 2 0 bit 8-9 nway*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xfffffcff; + if (pPortAbility->nway) + reg_data &= 0xfffffcff; + else + reg_data |= 0x100; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + else if(regValue2 == 0x12) + { +#if 0 + /*HiSGMII*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + /* 0 2 0 bit 8-9 nway*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xfffffcff; + if (pPortAbility->nway) + reg_data &= 0xfffffcff; + else + reg_data |= 0x100; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + if((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0x1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + + } + } + else + { + if((retVal = rtl8367c_getAsicRegBits(0x1d3d, 10, ®Value2)) != RT_ERR_OK) + return retVal; + if (regValue2 == 0) + { + /*ext1_force_ablty*/ + if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + /*force mode for ext1*/ + if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + + + } + else if (2 == id) + { + + if((retVal = rtl8367c_getAsicRegBit(0x1d95, 0, &sgmiibit)) != RT_ERR_OK) + return retVal; + if (sgmiibit == 1) + { + /*for 1000x/100fx/1000x_100fx, param has to bet set to serdes registers*/ + if((retVal = rtl8367c_getAsicReg(0x1d95, ®Value)) != RT_ERR_OK) + return retVal; + /*cfg_mac7_sel_sgmii=1 & cfg_mac7_fib =1*/ + if((regValue & 0x3) == 0x3) + { + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + + if(regValue2 == 0x4) + { + /*1000X*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x5) + { + /*100FX*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x7) + { + /*100FX*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + + } + + if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + + } + /* new_cfg_sds_mode */ + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + if(regValue2 == 0x2) + { + /*SGMII*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + /* 0 2 0 bit 8-9 nway*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xfffffcff; + if (pPortAbility->nway) + reg_data &= 0xfffffcff; + else + reg_data |= 0x100; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + else + { + + /*ext2_force_ablty*/ + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + /*force mode for ext2*/ + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + + if((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + /*force mode for ext1*/ + if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + } + + + } + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) + return retVal; + } +#if 0 + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; +#endif + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortForceLinkExt + * Description: + * Get external interface force linking configuration + * Input: + * id - external interface id (0~1) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) +{ + rtk_uint32 reg_data, regValue, type; + rtk_uint32 sgmiiSel; + rtk_uint32 hsgmiiSel; + ret_t retVal; + + /* Invalid input parameter */ + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + /*cfg_magic_id & get chip_id*/ + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + if (1 == type) + { + if(1 == id) + { + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, &sgmiiSel)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgmiiSel)) != RT_ERR_OK) + return retVal; + + if( (sgmiiSel == 1) || (hsgmiiSel == 1) ) + { + memset(pPortAbility, 0x00, sizeof(rtl8367c_port_ability_t)); + pPortAbility->forcemode = 1; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->duplex = reg_data; + + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->speed = reg_data; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->link = reg_data; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->txpause = reg_data; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->rxpause = reg_data; + + return RT_ERR_OK; + } + } + + if(0 == id || 1 == id) + retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE+id, ®_data); + else + retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, ®_data); + + if(retVal != RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 0x0001; + pPortAbility->mstfault = (reg_data >> 9) & 0x0001; + pPortAbility->mstmode = (reg_data >> 8) & 0x0001; + pPortAbility->nway = (reg_data >> 7) & 0x0001; + pPortAbility->txpause = (reg_data >> 6) & 0x0001; + pPortAbility->rxpause = (reg_data >> 5) & 0x0001; + pPortAbility->link = (reg_data >> 4) & 0x0001; + pPortAbility->duplex = (reg_data >> 2) & 0x0001; + pPortAbility->speed = reg_data & 0x0003; + } + else if (2 == type) + { + if (id == 1) + { + if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + else if (2 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + } + else if (3 == type) + { + if (id == 1) + { + if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + else if (2 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + } + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortExtMode + * Description: + * Set external interface mode configuration + * Input: + * id - external interface id (0~2) + * mode - external interface mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode) +{ + ret_t retVal; + rtk_uint32 i, regValue, type, option,reg_data; + rtk_uint32 idx; + rtk_uint32 redData[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x21A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; + rtk_uint32 redDataSB[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x31A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; + rtk_uint32 redData1[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData5[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData6[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData8[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData9[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redDataHB[][2] = { {0x82F0, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x7960, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + + if(mode >= EXT_END) + return RT_ERR_OUT_OF_RANGE; + + /* magic number*/ + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + /* Chip num */ + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + + if (1==type) + { + if((mode == EXT_1000X_100FX) || (mode == EXT_1000X) || (mode == EXT_100FX)) + { + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 5, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 7, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if(mode == EXT_1000X_100FX) + { + for(idx = 0; idx < FIBER2_AUTO_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_Auto[idx])) != RT_ERR_OK) + return retVal; + } + } + + if(mode == EXT_1000X) + { + for(idx = 0; idx < FIBER2_1G_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_1G[idx])) != RT_ERR_OK) + return retVal; + } + } + + if(mode == EXT_100FX) + { + for(idx = 0; idx < FIBER2_100M_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_100M[idx])) != RT_ERR_OK) + return retVal; + } + } + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + + if(mode == EXT_GMII) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT0_RGMXF, RTL8367C_EXT0_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT1_RGMXF, RTL8367C_EXT1_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT1_GMII_TX_DELAY_MASK, 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT0_GMII_TX_DELAY_MASK, 6)) != RT_ERR_OK) + return retVal; + } + + /* Serdes reset */ + if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 0)) != RT_ERR_OK) + return retVal; + } + + if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) + { + if(id != 1) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x13C1, &option)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0000)) != RT_ERR_OK) + return retVal; + } + + if(mode == EXT_SGMII) + { + if(option == 0) + { + for(i = 0; i <= 7; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else + { + for(i = 0; i <= 7; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataSB[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataSB[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + } + + if(mode == EXT_HSGMII) + { + if(option == 0) + { + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) + return retVal; + + if ( ((regValue & 0x00F0) >> 4) == 0x0001) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData1[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData1[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0005) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData5[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData5[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0006) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData6[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData6[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0008) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData8[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData8[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0009) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData9[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData9[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + } + else + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataHB[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataHB[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + } + + /* Only one ext port should care SGMII setting */ + if(id == 1) + { + + if(mode == EXT_SGMII) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_HSGMII) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 1)) != RT_ERR_OK) + return retVal; + } + else + { + + if((mode != EXT_1000X_100FX) && (mode != EXT_1000X) && (mode != EXT_100FX)) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + } + } + + if(0 == id || 1 == id) + { + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), mode)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, mode)) != RT_ERR_OK) + return retVal; + } + + /* Serdes not reset */ + if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x7106)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + + if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + for(idx = 0; idx < SGMII_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Sgmii_Init[idx])) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + } + else if (2 == type) + { + /* Serdes reset */ + if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 0)) != RT_ERR_OK) + return retVal; + } + + /*set MAC mode*/ + if (id == 1) + { + if(mode == EXT_HSGMII) + return RT_ERR_PORT_ID; + + if (mode == EXT_SGMII) + { + /*cfg port8 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + + /*enable port8 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 1)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) + { + /*cfg port8 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + + /*disable port8 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) + return retVal; + + /*set fiber link up*/ + if((retVal = rtl8367c_setAsicRegBit(0x6210, 11, 0)) != RT_ERR_OK) + return retVal; + } + else + { + /*cfg port8 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) + return retVal; + + /*disable port8 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) + return retVal; + } + /*disable SDS 1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + } + else if(id == 2) + { + if (mode == EXT_HSGMII) + { + if ((retVal = rtl8367c_setAsicReg(0x130, 7)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x39f, 7)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicReg(0x130, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x39f, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x3fa, 4)) != RT_ERR_OK) + return retVal; + + } + + + if (mode == EXT_SGMII) + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*enable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 1)) != RT_ERR_OK) + return retVal; + + /*disable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_HSGMII) + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) + return retVal; + + /*enable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 1)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) + return retVal; + + /*set fiber link up*/ + if((retVal = rtl8367c_setAsicRegBit(0x6200, 11, 0)) != RT_ERR_OK) + return retVal; + } + else + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) + return retVal; + + /*disable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) + return retVal; + } + /*disable SDS 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) + return retVal; + } + + /*SET TO RGMII MODE*/ + if (mode == EXT_RGMII) + { + /*disable paral led pad*/ + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN3, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN2, 0)) != RT_ERR_OK) + return retVal; + + /*set MAC8 mode*/ + if (id == 1) + { + /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 9, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 6, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 4, 1)) != RT_ERR_OK) + return retVal; + + /*show rate = 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 1, 0)) != RT_ERR_OK) + return retVal; + + /*EXT1 RGMII TXC delay 2ns*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1307, 3, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_Ext1_rgtxc_dly = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) + return retVal; + + /*RXDLY = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1307, 0x7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dn = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 4)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dp = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x700, 4)) != RT_ERR_OK) + return retVal; + } + else if (id == 2) + { + /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 2, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 1, 1)) != RT_ERR_OK) + return retVal; + + /*show rate = 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 0, 0)) != RT_ERR_OK) + return retVal; + + /*EXT1 RGMII TXC delay 2ns*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13c5, 3, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_Ext1_rgtxc_dly = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) + return retVal; + + /*RXDLY = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c5, 0x7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dn = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x1c0, 4)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dp = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x38, 4)) != RT_ERR_OK) + return retVal; + } + } + else if (mode == EXT_SGMII) + { + if (id == 1) + { + /*sds 1 reg 1 page 0x21 write value 0xec91*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0xec91)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) + return retVal; + + /*sds 1 reg 5 page 0x24 write value 0x5825*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x5825)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 2)) != RT_ERR_OK) + return retVal; + + /*?????????????????*/ + + } + else if (id == 2) + { + /*sds 0 reg 0 page 0x28 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 0 page 0x24 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 2)) != RT_ERR_OK) + return retVal; + + /*?????????????????*/ + } + } + else if (mode == EXT_HSGMII) + { + if (id == 2) + { + /*sds 0 reg 0 page 0x28 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 0 page 0x24 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + + /* optimizing HISGMII performance while RGMII used & */ + /*sds 0 reg 9 page 0x21 write value 0x3931*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x3931)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5)|9) ) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x12)) != RT_ERR_OK) + return retVal; + + /*?????????????????*/ + } + } + else if (mode == EXT_1000X) + { + if (id == 1) + { + + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds1 1000M*/ + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0x9000; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFdFFF; + regValue |= 0x40; + if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) + return retVal; + + + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) + return retVal; + + } + else if (id == 2) + { + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds0 1000M*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0x9000; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFDFFF; + regValue |= 0x40; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) + return retVal; + + } + } + else if (mode == EXT_100FX) + { + if (id == 1) + { + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds1 100M*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0xb000; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFFFBF; + regValue |= 0x2000; + if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) + return retVal; +#if 0 + if( (retVal = rtl8367c_setAsicReg(0x6214, 0x1a0)) != RT_ERR_OK) + return retVal; +#endif + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) + return retVal; + } + else if (id == 2) + { + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds0 100M*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0xb000; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFFFBF; + regValue |= 0x2000; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) + return retVal; + } + } + else if (mode == EXT_1000X_100FX) + { + if (id == 1) + { + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 13, 0, 0x4616)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0, 0xf20)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 7)) != RT_ERR_OK) + return retVal; + } + else if (id == 2) + { + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 13, 0, 0x4616)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 0, 0xf20)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 7)) != RT_ERR_OK) + return retVal; + } + } + + } + else if (3 == type) + { + + /*restore patch, by designer. patch Tx FIFO issue, when not HSGMII 2.5G mode + #sds0, page 1, reg 1, bit4=0*/ + if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFFFEF; + if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) + return retVal; + + /*set for mac 6*/ + if (1 == id) + { + /*force port6 linkdown*/ + if ((retVal = rtl8367c_setAsicReg(0x137c, 0x1000)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) + return retVal; + while(reg_data == 0) + { + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) + return retVal; + } + + if (mode == EXT_SGMII) + { + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + /*cfg_bypass_line_rate[1]=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0: MAC7 is not SGMII mode*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) + return retVal; + + /*#cfg_sgmii_link=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x12 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + /* MAC link source*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) + return retVal; + + + } + else if (mode == EXT_HSGMII) + { + + /*restore patch, by designer. patch Tx FIFO issue, when HSGMII 2.5G mode + #sds0, page 1, reg 1, bit4=1*/ + if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) + return retVal; + regValue |= 0x10; + if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) + return retVal; + + /* mode_ext1 = disable*/ + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0xd0,7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x399, 7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x12 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) + return retVal; + /* + 1: MAC link = SGMII SerDes link + 0: MAC link = SGMII config link £¨cfg_sgmii_link£© + */ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) + return retVal; + + } + else if(mode == EXT_1000X) + { + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method + bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 + */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable + bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ + if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) + return retVal; + + /*bit3: Serdes force mode:cfg_sds_frc_mode=1 + bit[2:0]: Serdes chip mode, cfg_sds_mode=3b'100 (force sds FIB1G mode) */ + if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) + return retVal; + + + /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x4 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_100FX) + { + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method + bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 + */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable + bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ + if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) + return retVal; + + /*!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3b'101 (force sds fib100M mode)*/ + if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) + return retVal; + + + /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x5 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_1000X_100FX) + { + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method + bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 + */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable + bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ + if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) + return retVal; + + /*!!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3'b111: Fib1G/Fib100M auto detect */ + if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) + return retVal; + + + /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x7 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + } + else if(mode < EXT_SGMII) + { + if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel SerDes mode,*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + if (mode < EXT_GMII) + { + /* set mac6 mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_RMII_MAC) + { + /*!!!!!!*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 7)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_RMII_PHY) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 8)) != RT_ERR_OK) + return retVal; + } + + if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) + { + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 1)) != RT_ERR_OK) + return retVal; + } + } + + } + else if (2 == id) + { + + /*force port7 linkdown*/ + if ((retVal = rtl8367c_setAsicReg(0x137d, 0x1000)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) + return retVal; + while(reg_data == 0) + { + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) + return retVal; + } + + if (mode == EXT_SGMII) + { + /*disable mac7 sel ext2 xMII mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf,0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + /* disable mac7 mode_ext2 */ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /* + bit0:cfg_mac7_sel_sgmii=0,MAC7 is not SGMII mode + bit1:cfg_mac7_fib= 0 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x2 (SGMII mode)*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + /*select MAC link source when port6/7 be set sgmii mode £¨cfg_sgmii_link£©*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X) + { + /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel serdes*/ + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) + return retVal; + + /*new_cfg_sds_mode=0x4 (FIB1000 mode)*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + + } + else if (mode == EXT_100FX) + { + /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel serdes*/ + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x5 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X_100FX) + { + /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel serdes*/ + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x7 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + } + else if (mode < EXT_SGMII) + { + if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac7 sel SerDes mode*/ + if ((retVal = rtl8367c_setAsicReg(0x1d95, 0x1f00)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* set port7 mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) + return retVal; + + if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) + { + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) + return retVal; + } + + } + else if ((mode < EXT_END) && (mode > EXT_100FX)) + { + if ((retVal = rtl8367c_setAsicRegBits(0x13C3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + } + + /* set port7 mode*/ + if (mode < EXT_RMII_MAC_2) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-13))) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-12))) != RT_ERR_OK) + return retVal; + } + + if ((mode == EXT_TMII_MAC_2) || (mode == EXT_TMII_PHY_2)) + { + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) + return retVal; + } + } + + } + + } + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortExtMode + * Description: + * Get external interface mode configuration + * Input: + * id - external interface id (0~1) + * pMode - external interface mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode) +{ + ret_t retVal; + rtk_uint32 regData, regValue, type; + + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + /*cfg_magic_id & get chip_id*/ + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + + if (1 == type) + { + + if (1 == id) + { + if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + if(1 == regData) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + + if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + if(1 == regData) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } + } + + if(0 == id || 1 == id) + return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), pMode); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, pMode); + + } + else if (2 == type) + { + if (1 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData & 0x4000) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + + else if (((regData >> 8) & 0x1f) == 4) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if (((regData >> 8) & 0x1f) == 5) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if (((regData >> 8) & 0x1f) == 7) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + + return rtl8367c_getAsicRegBits(0x1305, 0xf0, pMode); + } + else if (2 == id) + { +#if 0 + if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 6, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData == 1) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + + if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 7, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData == 1) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } +#endif + if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData & 0x40) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + else if (regData & 0x80) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } + else if ((regData & 0x1f) == 4) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if ((regData & 0x1f) == 5) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if ((regData & 0x1f) == 7) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + + return rtl8367c_getAsicRegBits(0x1305, 0xf, pMode); + } + } + else if(3 == type) + { + if (1 == id) + { + /* SDS_CFG_NEW */ + if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicReg(0x1d41, ®Value))!=RT_ERR_OK) + return retVal; + + /* bit5: cfg_mac6_fib=1 && bit7: cfg_mac6_fib2 =1 */ + if((regValue & 0xa0) == 0xa0 ) + { + /* new_cfg_sds_mode */ + regData = regData >> 8; + if((regData & 0x1f) == 4) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if((regData & 0x1f) == 5) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if((regData & 0x1f) == 7) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + + } + + + if ((retVal = rtl8367c_getAsicReg(0x1d11, ®Data))!=RT_ERR_OK) + return retVal; + + /* check cfg_mac6_sel_sgmii */ + if((regData >> 6) & 1) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + else if((regData >> 11) & 1) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } + else + { + /* check port6 MAC mode */ + if ((retVal = rtl8367c_getAsicRegBits(0x1305, 0xf0, ®Data))!=RT_ERR_OK) + return retVal; + + if(regData < 6) + *pMode = regData; + else if(regData == 6) + *pMode = EXT_RMII_MAC; + else if(regData == 7) + *pMode = EXT_RMII_PHY; + + return RT_ERR_OK; + } + } + else if (2 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) + return retVal; + + /* bit0: cfg_mac7_sel_sgmii + bit1: cfg_mac7_fib + bit[12:8]: new_cfg_sds_mode*/ + if(((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x4)) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x5)) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x7)) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + else if(regData & 1) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + else + { + /* check port7 MAC mode */ + if ((retVal = rtl8367c_getAsicRegBits(0x13c3, 0xf, ®Data))!=RT_ERR_OK) + return retVal; + + *pMode = regData; + + return RT_ERR_OK; + } + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8370_setAsicPortEnableAll + * Description: + * Set ALL ports enable. + * Input: + * enable - enable all ports. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable) +{ + if(enable >= 2) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, !enable); +} + +/* Function Name: + * rtl8367c_getAsicPortEnableAll + * Description: + * Set ALL ports enable. + * Input: + * enable - enable all ports. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if (regData==0) + *pEnable = 1; + else + *pEnable = 0; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortSmallIpg + * Description: + * Set small ipg egress mode + * Input: + * port - Physical port number (0~7) + * enable - 0: normal, 1: small + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, enable); +} + +/* Function Name: + * rtl8367c_getAsicPortSmallIpg + * Description: + * Get small ipg egress mode + * Input: + * port - Physical port number (0~7) + * pEnable - 0: normal, 1: small + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, pEnable); +} + +/* Function Name: + * rtl8367c_setAsicPortLoopback + * Description: + * Set MAC loopback + * Input: + * port - Physical port number (0~7) + * enable - 0: Disable, 1: enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, enable); +} + +/* Function Name: + * rtl8367c_getAsicPortLoopback + * Description: + * Set MAC loopback + * Input: + * port - Physical port number (0~7) + * Output: + * pEnable - 0: Disable, 1: enable + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, pEnable); +} + +/* Function Name: + * rtl8367c_setAsicPortRTCTEnable + * Description: + * Set RTCT Enable echo response mode + * Input: + * portmask - Port mask of RTCT enabled (0-4) + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * RTCT test takes 4.8 seconds at most. + */ +ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 port; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x0276) || (regData == 0x0597) ) + return RT_ERR_CHIP_NOT_SUPPORTED; + + for(port = 0; port <= 10 ; port++) + { + if(portmask & (0x0001 << port)) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= 0x7FFF; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData |= 0x00F2;/*RTCT set to echo response mode*/ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData |= 0x0001; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicPortRTCTDisable + * Description: + * Set RTCT Disable + * Input: + * portmask - Port mask of RTCT enabled (0-4) + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * RTCT test takes 4.8 seconds at most. + */ +ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 port; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x0276) || (regData == 0x0597) ) + return RT_ERR_CHIP_NOT_SUPPORTED; + + for(port = 0; port <= 10 ; port++) + { + if(portmask & (0x0001 << port)) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= 0x7FFF; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData |= 0x00F0; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData &= ~0x0001; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + + +/* Function Name: + * rtl8367c_getAsicPortRTCTResult + * Description: + * Get RTCT result + * Input: + * port - Port ID of RTCT result + * Output: + * pResult - The result of port ID + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * RT_ERR_PHY_RTCT_NOT_FINISH - RTCT test doesn't finish. + * Note: + * RTCT test takes 4.8 seconds at most. + * If this API returns RT_ERR_PHY_RTCT_NOT_FINISH, + * users should wait a whole then read it again. + */ +ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult) +{ + ret_t retVal; + rtk_uint32 regData, finish = 1; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x6367) ) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + if((regData & 0x8000) == 0x8000) + { + /* Channel A */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelAShort = (regData == 0x0050) ? 1 : 0; + pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel B */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelBShort = (regData == 0x0050) ? 1 : 0; + pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel C */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelCShort = (regData == 0x0050) ? 1 : 0; + pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel D */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelDShort = (regData == 0x0050) ? 1 : 0; + pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel A Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelALen = (regData / 2); + + /* Channel B Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBLen = (regData / 2); + + /* Channel C Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCLen = (regData / 2); + + /* Channel D Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDLen = (regData / 2); + } + else + finish = 0; + } + else if(regData == 0x6368) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + if((regData & 0x8000) == 0x8000) + { + /* Channel A */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802b)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelAShort = (regData == 0x0050) ? 1 : 0; + pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel B */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802f)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelBShort = (regData == 0x0050) ? 1 : 0; + pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel C */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8033)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelCShort = (regData == 0x0050) ? 1 : 0; + pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel D */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8037)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelDShort = (regData == 0x0050) ? 1 : 0; + pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel A Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802d)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelALen = (regData / 2); + + /* Channel B Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8031)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBLen = (regData / 2); + + /* Channel C Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8035)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCLen = (regData / 2); + + /* Channel D Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8039)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDLen = (regData / 2); + } + else + finish = 0; + + } + else if((regData == 0x6511) || (regData == 0x0801)) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + if((regData & 0x8000) == 0x8000) + { + /* Channel A */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelAShort = (regData == 0x0050) ? 1 : 0; + pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel B */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelBShort = (regData == 0x0050) ? 1 : 0; + pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel C */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelCShort = (regData == 0x0050) ? 1 : 0; + pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel D */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelDShort = (regData == 0x0050) ? 1 : 0; + pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel A Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelALen = (regData / 2); + + /* Channel B Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBLen = (regData / 2); + + /* Channel C Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCLen = (regData / 2); + + /* Channel D Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDLen = (regData / 2); + } + else + finish = 0; + + } + else + return RT_ERR_CHIP_NOT_SUPPORTED; + + if(finish == 0) + return RT_ERR_PHY_RTCT_NOT_FINISH; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_sdsReset + * Description: + * Reset Serdes + * Input: + * id - EXT ID + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_sdsReset(rtk_uint32 id) +{ + rtk_uint32 retVal, regValue, state, i, option, running = 0, retVal2; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + option = 0; + break; + case 0x0652: + case 0x6368: + option = 1; + break; + case 0x0801: + case 0x6511: + option = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(option == 0) + { + if (1 == id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x0000); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6602, 0x1401); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6601, 0x0000); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6602, 0x1403); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(option == 1) + { + if (1 == id) + { + if((retVal = rtl8367c_getAsicReg(0x1311, &state)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1311, 0x66)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1311, 0x1066)) != RT_ERR_OK) + return retVal; + + while(1) + { + if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) + return retVal; + if((regValue >> 8) & 1) + break; + } + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x1311, state)) != RT_ERR_OK) + return retVal; + + + } + else if (2== id) + { + if((retVal = rtl8367c_getAsicReg(0x13c4, &state)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13c4, 0x66)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13c4, 0x1066)) != RT_ERR_OK) + return retVal; + + while(1) + { + if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) + return retVal; + if((regValue >> 9) & 1) + break; + } + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x13c4, state)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(option == 2) + { + if ((retVal = rtl8367c_getAsicSdsReg(0, 3, 0, ®Value))!=RT_ERR_OK) + return retVal; + regValue |= 0x40; + if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + regValue &= ~(0x40); + if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) + return retVal; + + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getSdsLinkStatus + * Description: + * Get SGMII status + * Input: + * id - EXT ID + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink) +{ + rtk_uint32 retVal, regValue, type, running = 0, retVal2; + + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(type == 0) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x003D); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x0080); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_getAsicReg(0x6602, ®Value); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 1) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + } + else if (2 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 2) + { + if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setSgmiiNway + * Description: + * Set SGMII Nway + * Input: + * ext_id - EXT ID + * state - SGMII Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state) +{ + rtk_uint32 retVal, regValue, type, running = 0, retVal2; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(type == 0) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x0002); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x0080); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_getAsicReg(0x6602, ®Value); + + if(retVal == RT_ERR_OK) + { + if(state) + regValue |= 0x0200; + else + regValue &= ~0x0200; + + regValue |= 0x0100; + } + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6602, regValue); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6601, 0x0002); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 1) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(state) + regValue |= 0x0200; + else + regValue &= ~0x0200; + + regValue |= 0x0100; + + if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C1))!=RT_ERR_OK) + return retVal; + } + else if (2 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(state) + regValue |= 0x0200; + else + regValue &= ~0x0200; + + regValue |= 0x0100; + + if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C0))!=RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 2) + { + if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) + return retVal; + + if(state & 1) + regValue &= ~0x100; + else + regValue |= 0x100; + + if ((retVal = rtl8367c_setAsicSdsReg(0, 2, 0, regValue))!=RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getSgmiiNway + * Description: + * Get SGMII Nway + * Input: + * ext_id - EXT ID + * state - SGMII Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState) +{ + rtk_uint32 retVal, regValue, type, running = 0, retVal2; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(type == 0) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x0002); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x0080); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_getAsicReg(0x6602, ®Value); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + + if(regValue & 0x0200) + *pState = 1; + else + *pState = 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 1) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(regValue & 0x0200) + *pState = 1; + else + *pState = 0; + } + else if (2 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(regValue & 0x0200) + *pState = 1; + else + *pState = 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 2) + { + if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) + return retVal; + + if(regValue & 0x100) + *pState = 0; + else + *pState = 1; + } + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c new file mode 100755 index 00000000..e0b9db4b --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port isolation related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicPortIsolationPermittedPortmask + * Description: + * Set permitted port isolation portmask + * Input: + * port - Physical port number (0~10) + * permitPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if( permitPortmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), permitPortmask); +} +/* Function Name: + * rtl8367c_getAsicPortIsolationPermittedPortmask + * Description: + * Get permitted port isolation portmask + * Input: + * port - Physical port number (0~10) + * pPermitPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), pPermitPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortIsolationEfid + * Description: + * Set port isolation EFID + * Input: + * port - Physical port number (0~10) + * efid - EFID (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - Input parameter out of range + * Note: + * EFID is used in individual learning in filtering database + */ +ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if( efid > RTL8367C_EFIDMAX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), efid); +} +/* Function Name: + * rtl8367c_getAsicPortIsolationEfid + * Description: + * Get port isolation EFID + * Input: + * port - Physical port number (0~10) + * pEfid - EFID (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), pEfid); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c new file mode 100755 index 00000000..89c3c3e0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c @@ -0,0 +1,778 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Qos related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicPriorityDot1qRemapping + * Description: + * Set 802.1Q absolutely priority + * Input: + * srcpriority - Priority value + * priority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ) +{ + if((srcpriority > RTL8367C_PRIMAX) || (priority > RTL8367C_PRIMAX)) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority),priority); +} +/* Function Name: + * rtl8367c_getAsicPriorityDot1qRemapping + * Description: + * Get 802.1Q absolutely priority + * Input: + * srcpriority - Priority value + * pPriority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ) +{ + if(srcpriority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority), pPriority); +} +/* Function Name: + * rtl8367c_setAsicPriorityPortBased + * Description: + * Set port based priority + * Input: + * port - Physical port number (0~7) + * priority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), priority); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), priority); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPriorityPortBased + * Description: + * Get port based priority + * Input: + * port - Physical port number (0~7) + * pPriority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), pPriority); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), pPriority); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPriorityDscpBased + * Description: + * Set DSCP-based priority + * Input: + * dscp - DSCP value + * priority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if(dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), priority); +} +/* Function Name: + * rtl8367c_getAsicPriorityDscpBased + * Description: + * Get DSCP-based priority + * Input: + * dscp - DSCP value + * pPriority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ) +{ + if(dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), pPriority); +} +/* Function Name: + * rtl8367c_setAsicPriorityDecision + * Description: + * Set priority decision table + * Input: + * prisrc - Priority decision source + * decisionPri - Decision priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri) +{ + ret_t retVal; + + if(index >= PRIDEC_IDX_END ) + return RT_ERR_ENTRY_INDEX; + + if(prisrc >= PRIDEC_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + if(decisionPri > RTL8367C_DECISIONPRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + switch(index) + { + case PRIDEC_IDX0: + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), decisionPri))!= RT_ERR_OK) + return retVal; + break; + case PRIDEC_IDX1: + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), decisionPri))!= RT_ERR_OK) + return retVal; + break; + default: + break; + }; + + return RT_ERR_OK; + + +} + +/* Function Name: + * rtl8367c_getAsicPriorityDecision + * Description: + * Get priority decision table + * Input: + * prisrc - Priority decision source + * pDecisionPri - Decision priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri) +{ + ret_t retVal; + + if(index >= PRIDEC_IDX_END ) + return RT_ERR_ENTRY_INDEX; + + if(prisrc >= PRIDEC_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + switch(index) + { + case PRIDEC_IDX0: + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) + return retVal; + break; + case PRIDEC_IDX1: + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) + return retVal; + break; + default: + break; + }; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_setAsicPortPriorityDecisionIndex + * Description: + * Set priority decision index for each port + * Input: + * port - Physical port number (0~7) + * index - Table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_NUM - Invalid queue number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index >= PRIDEC_IDX_END) + return RT_ERR_ENTRY_INDEX; + + return rtl8367c_setAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, index); +} +/* Function Name: + * rtl8367c_getAsicPortPriorityDecisionIndex + * Description: + * Get priority decision index for each port + * Input: + * port - Physical port number (0~7) + * pIndex - Table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, pIndex); +} + +/* Function Name: + * rtl8367c_setAsicOutputQueueMappingIndex + * Description: + * Set output queue number for each port + * Input: + * port - Physical port number (0~7) + * index - Mapping table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_NUM - Invalid queue number + * Note: + * None + */ +ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 index ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index >= RTL8367C_QUEUENO) + return RT_ERR_QUEUE_NUM; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), index); +} +/* Function Name: + * rtl8367c_getAsicOutputQueueMappingIndex + * Description: + * Get output queue number for each port + * Input: + * port - Physical port number (0~7) + * pIndex - Mapping table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pIndex ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), pIndex); +} +/* Function Name: + * rtl8367c_setAsicPriorityToQIDMappingTable + * Description: + * Set priority to QID mapping table parameters + * Input: + * index - Mapping table index + * priority - The priority value + * qid - Queue id + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_ID - Invalid queue id + * RT_ERR_QUEUE_NUM - Invalid queue number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32 qid ) +{ + if(index >= RTL8367C_QUEUENO) + return RT_ERR_QUEUE_NUM; + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), qid); +} +/* Function Name: + * rtl8367c_getAsicPriorityToQIDMappingTable + * Description: + * Get priority to QID mapping table parameters + * Input: + * index - Mapping table index + * priority - The priority value + * pQid - Queue id + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_NUM - Invalid queue number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32* pQid) +{ + if(index >= RTL8367C_QUEUENO) + return RT_ERR_QUEUE_NUM; + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), pQid); +} +/* Function Name: + * rtl8367c_setAsicRemarkingDot1pAbility + * Description: + * Set 802.1p remarking ability + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDot1pAbility + * Description: + * Get 802.1p remarking ability + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRemarkingDot1pParameter + * Description: + * Set 802.1p remarking parameter + * Input: + * priority - Priority value + * newPriority - New priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ) +{ + if(priority > RTL8367C_PRIMAX || newPriority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), newPriority); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDot1pParameter + * Description: + * Get 802.1p remarking parameter + * Input: + * priority - Priority value + * pNewPriority - New priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), pNewPriority); +} + +/* Function Name: + * rtl8367c_setAsicRemarkingDot1pSrc + * Description: + * Set remarking source of 802.1p remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure 802.1p remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type) +{ + + if(type >= DOT1P_PRISEL_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, type); +} + + +/* Function Name: + * rtl8367c_getAsicRemarkingDot1pSrc + * Description: + * Get remarking source of 802.1p remarking. + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, pType); +} + + + + + +/* Function Name: + * rtl8367c_setAsicRemarkingDscpAbility + * Description: + * Set DSCP remarking ability + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDscpAbility + * Description: + * Get DSCP remarking ability + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRemarkingDscpParameter + * Description: + * Set DSCP remarking parameter + * Input: + * priority - Priority value + * newDscp - New DSCP value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if(newDscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), newDscp); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDscpParameter + * Description: + * Get DSCP remarking parameter + * Input: + * priority - Priority value + * pNewDscp - New DSCP value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), pNewDscp); +} + +/* Function Name: + * rtl8367c_setAsicRemarkingDscpSrc + * Description: + * Set remarking source of DSCP remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure DSCP remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type) +{ + + if(type >= DSCP_PRISEL_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, type); +} + + +/* Function Name: + * rtl8367c_getAsicRemarkingDscpSrc + * Description: + * Get remarking source of DSCP remarking. + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, pType); +} + +/* Function Name: + * rtl8367c_setAsicRemarkingDscp2Dscp + * Description: + * Set DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * rmkDscp - remarked DSCP value + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - Invalid unit id + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * Note: + * dscp parameter can be DSCP value or internal priority according to configuration of API + * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP + * value or internal priority to TX DSCP value. + */ +ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp) +{ + if((dscp > RTL8367C_DSCPMAX ) || (rmkDscp > RTL8367C_DSCPMAX)) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), rmkDscp); +} + +/* Function Name: + * rtl8367c_getAsicRemarkingDscp2Dscp + * Description: + * Get DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * Output: + * pRmkDscp - remarked DSCP value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None. + */ +ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp) +{ + if(dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), pRmkDscp); + +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c new file mode 100755 index 00000000..0309689d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c @@ -0,0 +1,674 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RLDP related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicRldp + * Description: + * Set RLDP function enable/disable + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRldp + * Description: + * Get RLDP function enable/disable + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpEnable8051 + * Description: + * Set RLDP function handled by ASIC or 8051 + * Input: + * enabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_setAsicRldrtl8367c_getAsicRldpEnable8051pEnable8051 + * Description: + * Get RLDP function handled by ASIC or 8051 + * Input: + * pEnabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpCompareRandomNumber + * Description: + * Set enable compare the random number field and seed field of RLDP frame + * Input: + * enabled - 1: enabled comparing random number, 0: disabled comparing random number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRldpCompareRandomNumber + * Description: + * Get enable compare the random number field and seed field of RLDP frame + * Input: + * pEnabled - 1: enabled comparing random number, 0: disabled comparing random number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpIndicatorSource + * Description: + * Set buzzer and LED source when detecting a loop + * Input: + * src - 0: ASIC, 1: 8051 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, src); +} +/* Function Name: + * rtl8367c_getAsicRldpIndicatorSource + * Description: + * Get buzzer and LED source when detecting a loop + * Input: + * pSrc - 0: ASIC, 1: 8051 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, pSrc); +} +/* Function Name: + * rtl8367c_setAsicRldpCheckingStatePara + * Description: + * Set retry count and retry period of checking state + * Input: + * retryCount - 0~0xFF (times) + * retryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) +{ + ret_t retVal; + + if(retryCount > 0xFF) + return RT_ERR_OUT_OF_RANGE; + if(retryPeriod > RTL8367C_REGDATAMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, retryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, retryPeriod); +} +/* Function Name: + * rtl8367c_getAsicRldpCheckingStatePara + * Description: + * Get retry count and retry period of checking state + * Input: + * pRetryCount - 0~0xFF (times) + * pRetryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, pRetryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, pRetryPeriod); +} +/* Function Name: + * rtl8367c_setAsicRldpLoopStatePara + * Description: + * Set retry count and retry period of loop state + * Input: + * retryCount - 0~0xFF (times) + * retryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) +{ + ret_t retVal; + + if(retryCount > 0xFF) + return RT_ERR_OUT_OF_RANGE; + + if(retryPeriod > RTL8367C_REGDATAMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, retryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, retryPeriod); +} +/* Function Name: + * rtl8367c_getAsicRldpLoopStatePara + * Description: + * Get retry count and retry period of loop state + * Input: + * pRetryCount - 0~0xFF (times) + * pRetryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, pRetryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, pRetryPeriod); +} +/* Function Name: + * rtl8367c_setAsicRldpTxPortmask + * Description: + * Set portmask that send/forward RLDP frame + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_RLDP_TX_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicRldpTxPortmask + * Description: + * Get portmask that send/forward RLDP frame + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_RLDP_TX_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicRldpMagicNum + * Description: + * Set Random seed of RLDP + * Input: + * seed - MAC + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint16*)&seed; + + for (i = 0; i < 3; i++) + { + regData = *accessPtr; + retVal = rtl8367c_setAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicRldpMagicNum + * Description: + * Get Random seed of RLDP + * Input: + * pSeed - MAC + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint16*)pSeed; + + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + accessPtr++; + } + + return retVal; +} + +/* Function Name: + * rtl8367c_getAsicRldpLoopedPortmask + * Description: + * Get looped portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_RLDP_LOOP_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_getAsicRldpRandomNumber + * Description: + * Get Random number of RLDP + * Input: + * pRandNumber - MAC + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_int16 accessPtr[3]; + rtk_uint32 i; + + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_RAND_NUM_REG_BASE+ i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr[i] = regData; + } + + memcpy(pRandNumber, accessPtr, 6); + return retVal; +} +/* Function Name: + * rtl8367c_getAsicRldpLoopedPortmask + * Description: + * Get port number of looped pair + * Input: + * port - Physical port number (0~7) + * pLoopedPair - port (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_RLDP_LOOP_PORT_REG(port), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_LOOP_PORT_REG4 + ((port - 8) >> 1), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); +} +/* Function Name: + * rtl8367c_setAsicRlppTrap8051 + * Description: + * Set trap RLPP packet to 8051 + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRlppTrap8051 + * Description: + * Get trap RLPP packet to 8051 + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpLeaveLoopedPortmask + * Description: + * Clear leaved looped portmask + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, portmask); +} +/* Function Name: + * rtl8367c_getAsicRldpLeaveLoopedPortmask + * Description: + * Get leaved looped portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicRldpEnterLoopedPortmask + * Description: + * Clear enter loop portmask + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, portmask); +} +/* Function Name: + * rtl8367c_getAsicRldpEnterLoopedPortmask + * Description: + * Get enter loop portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, pPortmask); +} + +/* Function Name: + * rtl8367c_setAsicRldpTriggerMode + * Description: + * Set trigger RLDP mode + * Input: + * mode - 1: Periodically, 0: SA moving + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRldpTriggerMode + * Description: + * Get trigger RLDP mode + * Input: + * pMode - - 1: Periodically, 0: SA moving + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicRldp8051Portmask + * Description: + * Set 8051/CPU configured looped portmask + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask) +{ + ret_t retVal; + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,(portmask >> 8) & 7); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicRldp8051Portmask + * Description: + * Get 8051/CPU configured looped portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpPmsk; + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,&tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpPmsk & 0xff; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,&tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpPmsk & 7) <<8; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c new file mode 100755 index 00000000..f297defa --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 64716 $ + * $Date: 2015-12-31 16:31:55 +0800 (週四, 31 å二月 2015) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RMA related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicRma + * Description: + * Set reserved multicast address for CPU trapping + * Input: + * index - reserved multicast LSB byte, 0x00~0x2F is available value + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(index > RTL8367C_RMAMAX) + return RT_ERR_RMA_ADDR; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) + index = 0x04; + else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) + index = 0x13; + else if(index >= 0x22 && index <= 0x2F) + index = 0x22; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL00+index, regData); +} +/* Function Name: + * rtl8367c_getAsicRma + * Description: + * Get reserved multicast address for CPU trapping + * Input: + * index - reserved multicast LSB byte, 0x00~0x2F is available value + * rmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_RMAMAX) + return RT_ERR_RMA_ADDR; + + if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) + index = 0x04; + else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) + index = 0x13; + else if(index >= 0x22 && index <= 0x2F) + index = 0x22; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL00+index, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicRmaCdp + * Description: + * Set CDP(Cisco Discovery Protocol) for CPU trapping + * Input: + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(pRmacfg->operation >= RMAOP_END) + return RT_ERR_RMA_ACTION; + + if(pRmacfg->trap_priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CDP, regData); +} +/* Function Name: + * rtl8367c_getAsicRmaCdp + * Description: + * Get CDP(Cisco Discovery Protocol) for CPU trapping + * Input: + * None + * Output: + * pRmacfg - type of RMA for trapping frame type setting + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CDP, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicRmaCsstp + * Description: + * Set CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping + * Input: + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(pRmacfg->operation >= RMAOP_END) + return RT_ERR_RMA_ACTION; + + if(pRmacfg->trap_priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, regData); +} +/* Function Name: + * rtl8367c_getAsicRmaCsstp + * Description: + * Get CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping + * Input: + * None + * Output: + * pRmacfg - type of RMA for trapping frame type setting + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicRmaLldp + * Description: + * Set LLDP for CPU trapping + * Input: + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(enabled > 1) + return RT_ERR_ENABLE; + + if(pRmacfg->operation >= RMAOP_END) + return RT_ERR_RMA_ACTION; + + if(pRmacfg->trap_priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,enabled); + if(retVal != RT_ERR_OK) + return retVal; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, regData); +} +/* Function Name: + * rtl8367c_getAsicRmaLldp + * Description: + * Get LLDP for CPU trapping + * Input: + * None + * Output: + * pRmacfg - type of RMA for trapping frame type setting + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,pEnabled); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c new file mode 100755 index 00000000..8ebd6796 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Packet Scheduling related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicLeakyBucketParameter + * Description: + * Set Leaky Bucket Paramters + * Input: + * tick - Tick is used for time slot size unit + * token - Token is used for adding budget in each time slot + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_TICK - Invalid TICK + * RT_ERR_TOKEN - Invalid TOKEN + * Note: + * None + */ +ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token) +{ + ret_t retVal; + + if(tick > 0xFF) + return RT_ERR_TICK; + + if(token > 0xFF) + return RT_ERR_TOKEN; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicLeakyBucketParameter + * Description: + * Get Leaky Bucket Paramters + * Input: + * tick - Tick is used for time slot size unit + * token - Token is used for adding budget in each time slot + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicAprMeter + * Description: + * Set per-port per-queue APR shared meter index + * Input: + * port - Physical port number (0~10) + * qid - Queue id + * apridx - dedicated shared meter index for APR (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx) +{ + ret_t retVal; + rtk_uint32 regAddr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + if(apridx > RTL8367C_PORT_QUEUE_METER_INDEX_MAX) + return RT_ERR_FILTER_METER_ID; + + if(port < 8) + retVal = rtl8367c_setAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + else { + regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAprMeter + * Description: + * Get per-port per-queue APR shared meter index + * Input: + * port - Physical port number (0~10) + * qid - Queue id + * apridx - dedicated shared meter index for APR (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx) +{ + ret_t retVal; + rtk_uint32 regAddr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + if(port < 8) + retVal = rtl8367c_getAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + else { + regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); + retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + } + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicAprEnable + * Description: + * Set per-port APR enable + * Input: + * port - Physical port number (0~7) + * aprEnable - APR enable seting 1:enable 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAprEnable + * Description: + * Get per-port APR enable + * Input: + * port - Physical port number (0~7) + * aprEnable - APR enable seting 1:enable 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicWFQWeight + * Description: + * Set weight of a queue + * Input: + * port - Physical port number (0~10) + * qid - The queue ID wanted to set + * qWeight - The weight value wanted to set (valid:0~127) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight + * Note: + * None + */ +ret_t rtl8367c_setAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 qWeight) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + if(qWeight > RTL8367C_QWEIGHTMAX && qid > 0) + return RT_ERR_QOS_QUEUE_WEIGHT; + + retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicWFQWeight + * Description: + * Get weight of a queue + * Input: + * port - Physical port number (0~10) + * qid - The queue ID wanted to set + * qWeight - The weight value wanted to set (valid:0~127) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *qWeight) +{ + ret_t retVal; + + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + + retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicWFQBurstSize + * Description: + * Set WFQ leaky bucket burst size + * Input: + * burstsize - Leaky bucket burst size, unit byte + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicWFQBurstSize + * Description: + * Get WFQ leaky bucket burst size + * Input: + * burstsize - Leaky bucket burst size, unit byte + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicQueueType + * Description: + * Set type of a queue + * Input: + * port - Physical port number (0~10) + * qid - The queue ID wanted to set + * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + /* Set Related Registers */ + retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicQueueType + * Description: + * Get type of a queue + * Input: + * port - Physical port number (0~7) + * qid - The queue ID wanted to set + * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicPortEgressRate + * Description: + * Set per-port egress rate + * Input: + * port - Physical port number (0~10) + * rate - Egress rate + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_EBW_RATE - Invalid bandwidth/rate + * Note: + * None + */ +ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate) +{ + ret_t retVal; + rtk_uint32 regAddr, regData; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(rate > RTL8367C_QOS_GRANULARTY_MAX) + return RT_ERR_QOS_EBW_RATE; + + regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); + regData = RTL8367C_QOS_GRANULARTY_LSB_MASK & rate; + + retVal = rtl8367c_setAsicReg(regAddr, regData); + + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); + regData = (RTL8367C_QOS_GRANULARTY_MSB_MASK & rate) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; + + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, regData); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicPortEgressRate + * Description: + * Get per-port egress rate + * Input: + * port - Physical port number (0~10) + * rate - Egress rate + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate) +{ + ret_t retVal; + rtk_uint32 regAddr, regData,regData2; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); + + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); + retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, ®Data2); + if(retVal != RT_ERR_OK) + return retVal; + + *rate = regData | (regData2 << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortEgressRateIfg + * Description: + * Set per-port egress rate calculate include/exclude IFG + * Input: + * ifg - 1:include IFG 0:exclude IFG + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicPortEgressRateIfg + * Description: + * Get per-port egress rate calculate include/exclude IFG + * Input: + * ifg - 1:include IFG 0:exclude IFG + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); + + return retVal; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c new file mode 100755 index 00000000..a29f6476 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c @@ -0,0 +1,851 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Storm control filtering related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicStormFilterBroadcastEnable + * Description: + * Set per-port broadcast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_BCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterBroadcastEnable + * Description: + * Get per-port broadcast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_BCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterBroadcastMeter + * Description: + * Set per-port broadcast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), meter); +} +/* Function Name: + * rtl8367c_getAsicStormFilterBroadcastMeter + * Description: + * Get per-port broadcast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), pMeter); +} +/* Function Name: + * rtl8367c_setAsicStormFilterMulticastEnable + * Description: + * Set per-port multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_MCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterMulticastEnable + * Description: + * Get per-port multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_MCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterMulticastMeter + * Description: + * Set per-port multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), meter); +} +/* Function Name: + * rtl8367c_getAsicStormFilterMulticastMeter + * Description: + * Get per-port multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), pMeter); +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownMulticastEnable + * Description: + * Set per-port unknown multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownMulticastEnable + * Description: + * Get per-port unknown multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownMulticastMeter + * Description: + * Set per-port unknown multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownMulticastMeter + * Description: + * Get per-port unknown multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownUnicastEnable + * Description: + * Set per-port unknown unicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownUnicastEnable + * Description: + * get per-port unknown unicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownUnicastMeter + * Description: + * Set per-port unknown unicast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), meter); +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownUnicastMeter + * Description: + * Get per-port unknown unicast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtBroadcastMeter + * Description: + * Set extension broadcast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtBroadcastMeter + * Description: + * get extension broadcast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtMulticastMeter + * Description: + * Set extension multicast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtMulticastMeter + * Description: + * get extension multicast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownMulticastMeter + * Description: + * Set extension unknown multicast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownMulticastMeter + * Description: + * get extension unknown multicast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownUnicastMeter + * Description: + * Set extension unknown unicast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownUnicastMeter + * Description: + * get extension unknown unicast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtBroadcastEnable + * Description: + * Set extension broadcast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtBroadcastEnable + * Description: + * Get extension broadcast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtMulticastEnable + * Description: + * Set extension multicast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtMulticastEnable + * Description: + * Get extension multicast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownMulticastEnable + * Description: + * Set extension unknown multicast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownMulticastEnable + * Description: + * Get extension unknown multicast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownUnicastEnable + * Description: + * Set extension unknown unicast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownUnicastEnable + * Description: + * Get extension unknown unicast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtEnablePortMask + * Description: + * Set extension storm filter port mask + * Input: + * portmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, portmask & 0x3FF); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, (portmask >> 10)&1); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtEnablePortMask + * Description: + * Get extension storm filter port mask + * Input: + * portmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpPmsk; + ret_t retVal; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, &tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpPmsk & 0x3ff; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, &tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpPmsk & 1) << 10; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c new file mode 100755 index 00000000..f19ceba5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c @@ -0,0 +1,1003 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : SVLAN related functions + * + */ +#include + +#include + +static void _rtl8367c_svlanConfStUser2Smi( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pSmiSt[0] |= (pUserSt->vs_member & 0x00FF); + pSmiSt[0] |= (pUserSt->vs_untag & 0x00FF) << 8; + + pSmiSt[1] |= (pUserSt->vs_fid_msti & 0x000F); + pSmiSt[1] |= (pUserSt->vs_priority & 0x0007) << 4; + pSmiSt[1] |= (pUserSt->vs_force_fid & 0x0001) << 7; + + pSmiSt[2] |= (pUserSt->vs_svid & 0x0FFF); + pSmiSt[2] |= (pUserSt->vs_efiden & 0x0001) << 12; + pSmiSt[2] |= (pUserSt->vs_efid & 0x0007) << 13; + + pSmiSt[3] |= ((pUserSt->vs_member & 0x0700) >> 8); + pSmiSt[3] |= ((pUserSt->vs_untag & 0x0700) >> 8) << 3; +} + +static void _rtl8367c_svlanConfStSmi2User( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) +{ + + pUserSt->vs_member = (pSmiSt[0] & 0x00FF) | ((pSmiSt[3] & 0x0007) << 8); + pUserSt->vs_untag = ((pSmiSt[0] & 0xFF00) >> 8) | (((pSmiSt[3] & 0x0038) >> 3) << 8); + + pUserSt->vs_fid_msti = (pSmiSt[1] & 0x000F); + pUserSt->vs_priority = (pSmiSt[1] & 0x0070) >> 4; + pUserSt->vs_force_fid = (pSmiSt[1] & 0x0080) >> 7; + + pUserSt->vs_svid = (pSmiSt[2] & 0x0FFF); + pUserSt->vs_efiden = (pSmiSt[2] & 0x1000) >> 12; + pUserSt->vs_efid = (pSmiSt[2] & 0xE000) >> 13; +} + +static void _rtl8367c_svlanMc2sStUser2Smi(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pSmiSt[0] |= (pUserSt->svidx & 0x003F); + pSmiSt[0] |= (pUserSt->format & 0x0001) << 6; + pSmiSt[0] |= (pUserSt->valid & 0x0001) << 7; + + pSmiSt[1] = (rtk_uint16)(pUserSt->smask & 0x0000FFFF); + pSmiSt[2] = (rtk_uint16)((pUserSt->smask & 0xFFFF0000) >> 16); + + pSmiSt[3] = (rtk_uint16)(pUserSt->sdata & 0x0000FFFF); + pSmiSt[4] = (rtk_uint16)((pUserSt->sdata & 0xFFFF0000) >> 16); +} + +static void _rtl8367c_svlanMc2sStSmi2User(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pUserSt->svidx = (pSmiSt[0] & 0x003F); + pUserSt->format = (pSmiSt[0] & 0x0040) >> 6; + pUserSt->valid = (pSmiSt[0] & 0x0080) >> 7; + + pUserSt->smask = pSmiSt[1] | (pSmiSt[2] << 16); + pUserSt->sdata = pSmiSt[3] | (pSmiSt[4] << 16); +} + +static void _rtl8367c_svlanSp2cStUser2Smi(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pSmiSt[0] |= (pUserSt->dstport & 0x0007); + pSmiSt[0] |= (pUserSt->svidx & 0x003F) << 3; + pSmiSt[0] |= ((pUserSt->dstport & 0x0008) >> 3) << 9; + + pSmiSt[1] |= (pUserSt->vid & 0x0FFF); + pSmiSt[1] |= (pUserSt->valid & 0x0001) << 12; +} + +static void _rtl8367c_svlanSp2cStSmi2User(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pUserSt->dstport = (((pSmiSt[0] & 0x0200) >> 9) << 3) | (pSmiSt[0] & 0x0007); + pUserSt->svidx = (pSmiSt[0] & 0x01F8) >> 3; + pUserSt->vid = (pSmiSt[1] & 0x0FFF); + pUserSt->valid = (pSmiSt[1] & 0x1000) >> 12; +} + +/* Function Name: + * rtl8367c_setAsicSvlanUplinkPortMask + * Description: + * Set uplink ports mask + * Input: + * portMask - Uplink port mask setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, portMask); +} +/* Function Name: + * rtl8367c_getAsicSvlanUplinkPortMask + * Description: + * Get uplink ports mask + * Input: + * pPortmask - Uplink port mask setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicSvlanTpid + * Description: + * Set accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 + * Input: + * protocolType - Ether type of S-tag frame parsing in uplink ports + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 + * for Q-in-Q SLAN design. User can set mathced ether type as service provider supported protocol + */ +ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_VS_TPID, protocolType); +} +/* Function Name: + * rtl8367c_getAsicReg + * Description: + * Get accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 + * Input: + * pProtocolType - Ether type of S-tag frame parsing in uplink ports + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_VS_TPID, pProtocolType); +} +/* Function Name: + * rtl8367c_setAsicSvlanPrioritySel + * Description: + * Set SVLAN priority field setting + * Input: + * priSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel) +{ + if(priSel >= SPRISEL_END) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, priSel); +} +/* Function Name: + * rtl8367c_getAsicSvlanPrioritySel + * Description: + * Get SVLAN priority field setting + * Input: + * pPriSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, pPriSel); +} +/* Function Name: + * rtl8367c_setAsicSvlanTrapPriority + * Description: + * Set trap to CPU priority assignment + * Input: + * priority - Priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, priority); +} +/* Function Name: + * rtl8367c_getAsicSvlanTrapPriority + * Description: + * Get trap to CPU priority assignment + * Input: + * pPriority - Priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, pPriority); +} +/* Function Name: + * rtl8367c_setAsicSvlanDefaultVlan + * Description: + * Set default egress SVLAN + * Input: + * port - Physical port number (0~10) + * index - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + if(port < 8){ + if(port & 1) + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,index); + else + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,index); + }else{ + switch(port){ + case 8: + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,index); + break; + + case 9: + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,index); + break; + + case 10: + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,index); + break; + } + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicSvlanDefaultVlan + * Description: + * Get default egress SVLAN + * Input: + * port - Physical port number (0~7) + * pIndex - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8){ + if(port & 1) + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,pIndex); + else + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,pIndex); + }else{ + switch(port){ + case 8: + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,pIndex); + break; + + case 9: + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,pIndex); + break; + + case 10: + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,pIndex); + break; + } + } + + return retVal; + +} +/* Function Name: + * rtl8367c_setAsicSvlanIngressUntag + * Description: + * Set action received un-Stag frame from unplink port + * Input: + * mode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicSvlanIngressUntag + * Description: + * Get action received un-Stag frame from unplink port + * Input: + * pMode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicSvlanIngressUnmatch + * Description: + * Set action received unmatched Stag frame from unplink port + * Input: + * mode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicSvlanIngressUnmatch + * Description: + * Get action received unmatched Stag frame from unplink port + * Input: + * pMode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, pMode); + +} +/* Function Name: + * rtl8367c_setAsicSvlanEgressUnassign + * Description: + * Set unplink stream without egress SVID action + * Input: + * enabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicSvlanEgressUnassign + * Description: + * Get unplink stream without egress SVID action + * Input: + * pEnabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, pEnabled); +} + + +/* Function Name: + * rtl8367c_setAsicSvlanMemberConfiguration + * Description: + * Set system 64 S-tag content + * Input: + * index - index of 64 s-tag configuration + * pSvlanMemCfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index, rtl8367c_svlan_memconf_t* pSvlanMemCfg) +{ + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; + + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); + _rtl8367c_svlanConfStUser2Smi(pSvlanMemCfg, smiSvlanMemConf); + + accessPtr = smiSvlanMemConf; + + regData = *accessPtr; + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + } + + if(index < 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; + else if(index == 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} +/* Function Name: + * rtl8367c_getAsicSvlanMemberConfiguration + * Description: + * Get system 64 S-tag content + * Input: + * index - index of 64 s-tag configuration + * pSvlanMemCfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg) +{ + ret_t retVal; + rtk_uint32 regAddr,regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; + + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); + + accessPtr = smiSvlanMemConf; + + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + accessPtr ++; + } + + if(index < 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; + else if(index == 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; + + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + _rtl8367c_svlanConfStSmi2User(pSvlanMemCfg, smiSvlanMemConf); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicSvlanC2SConf + * Description: + * Set SVLAN C2S table + * Input: + * index - index of 128 Svlan C2S configuration + * evid - Enhanced VID + * portmask - available c2s port mask + * svidx - index of 64 Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * ASIC will check upstream's VID and assign related SVID to mathed packet + */ +ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx) +{ + ret_t retVal; + + if(index > RTL8367C_C2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), svidx); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, portmask); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, evid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicSvlanC2SConf + * Description: + * Get SVLAN C2S table + * Input: + * index - index of 128 Svlan C2S configuration + * pEvid - Enhanced VID + * pPortmask - available c2s port mask + * pSvidx - index of 64 Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx) +{ + ret_t retVal; + + if(index > RTL8367C_C2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), pSvidx); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, pPortmask); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, pEvid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicSvlanMC2SConf + * Description: + * Set system MC2S content + * Input: + * index - index of 32 SVLAN 32 MC2S configuration + * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * If upstream packet is L2 multicast or IPv4 multicast packet and DMAC/DIP is matched MC2S + * configuration, ASIC will assign egress SVID to the packet + */ +ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; + + if(index > RTL8367C_MC2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); + _rtl8367c_svlanMc2sStUser2Smi(pSvlanMc2sCfg, smiSvlanMC2S); + + accessPtr = smiSvlanMC2S; + + regData = *accessPtr; + for(i = 0; i < 5; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicSvlanMC2SConf + * Description: + * Get system MC2S content + * Input: + * index - index of 32 SVLAN 32 MC2S configuration + * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index, rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; + + if(index > RTL8367C_MC2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); + + accessPtr = smiSvlanMC2S; + + for(i = 0; i < 5; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + accessPtr ++; + } + + + _rtl8367c_svlanMc2sStSmi2User(pSvlanMc2sCfg, smiSvlanMC2S); + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicSvlanSP2CConf + * Description: + * Set system 128 SP2C content + * Input: + * index - index of 128 SVLAN & Port to CVLAN configuration + * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index, rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; + + if(index > RTL8367C_SP2CMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); + _rtl8367c_svlanSp2cStUser2Smi(pSvlanSp2cCfg,smiSvlanSP2C); + + accessPtr = smiSvlanSP2C; + + regData = *accessPtr; + for(i = 0; i < 2; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicSvlanSP2CConf + * Description: + * Get system 128 SP2C content + * Input: + * index - index of 128 SVLAN & Port to CVLAN configuration + * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; + + if(index > RTL8367C_SP2CMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); + + accessPtr = smiSvlanSP2C; + + for(i = 0; i < 2; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + accessPtr ++; + } + + _rtl8367c_svlanSp2cStSmi2User(pSvlanSp2cCfg, smiSvlanSP2C); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicSvlanDmacCvidSel + * Description: + * Set downstream CVID decision by DMAC + * Input: + * port - Physical port number (0~7) + * enabled - 0:disabled, 1:enabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, enabled); + else + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), enabled); +} +/* Function Name: + * rtl8367c_getAsicSvlanDmacCvidSel + * Description: + * Get downstream CVID decision by DMAC + * Input: + * port - Physical port number (0~7) + * pEnabled - 0:disabled, 1:enabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, pEnabled); + else + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), pEnabled); +} +/* Function Name: + * rtl8367c_setAsicSvlanUntagVlan + * Description: + * Set default ingress untag SVLAN + * Input: + * index - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index) +{ + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, index); +} +/* Function Name: + * rtl8367c_getAsicSvlanUntagVlan + * Description: + * Get default ingress untag SVLAN + * Input: + * pIndex - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, pIndex); +} + +/* Function Name: + * rtl8367c_setAsicSvlanUnmatchVlan + * Description: + * Set default ingress unmatch SVLAN + * Input: + * index - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index) +{ + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, index); +} +/* Function Name: + * rtl8367c_getAsicSvlanUnmatchVlan + * Description: + * Get default ingress unmatch SVLAN + * Input: + * pIndex - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, pIndex); +} + + +/* Function Name: + * rtl8367c_setAsicSvlanLookupType + * Description: + * Set svlan lookup table selection + * Input: + * type - lookup type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, type); +} + +/* Function Name: + * rtl8367c_getAsicSvlanLookupType + * Description: + * Get svlan lookup table selection + * Input: + * pType - lookup type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, pType); +} + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c new file mode 100755 index 00000000..26d4c29b --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port trunking related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicTrunkingMode + * Description: + * Set port trunking mode + * Input: + * mode - 1:dumb 0:user defined + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicTrunkingMode + * Description: + * Get port trunking mode + * Input: + * pMode - 1:dumb 0:user defined + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, pMode); +} +/* Function Name: + * rtl8367c_setAsicTrunkingFc + * Description: + * Set port trunking flow control + * Input: + * group - Trunk Group ID + * enabled - 0:disable, 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled) +{ + ret_t retVal; + + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_DROP_CTRL, RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET, ENABLED)) != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), enabled); +} +/* Function Name: + * rtl8367c_getAsicTrunkingFc + * Description: + * Get port trunking flow control + * Input: + * group - Trunk Group ID + * pEnabled - 0:disable, 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled) +{ + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), pEnabled); +} +/* Function Name: + * rtl8367c_setAsicTrunkingGroup + * Description: + * Set trunking group available port mask + * Input: + * group - Trunk Group ID + * portmask - Logic trunking enable port mask, max 4 ports + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask) +{ + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), portmask); +} +/* Function Name: + * rtl8367c_getAsicTrunkingGroup + * Description: + * Get trunking group available port mask + * Input: + * group - Trunk Group ID + * Output: + * pPortmask - Logic trunking enable port mask, max 4 ports + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask) +{ + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), pPortmask); +} +/* Function Name: + * rtl8367c_setAsicTrunkingFlood + * Description: + * Set port trunking flood function + * Input: + * enabled - Port trunking flooding function 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicTrunkingFlood + * Description: + * Get port trunking flood function + * Input: + * pEnabled - Port trunking flooding function 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicTrunkingHashSelect + * Description: + * Set port trunking hash select sources + * Input: + * hashsel - hash sources mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} + * 0b0000001: SPA + * 0b0000010: SMAC + * 0b0000100: DMAC + * 0b0001000: SIP + * 0b0010000: DIP + * 0b0100000: TCP/UDP Source Port + * 0b1000000: TCP/UDP Destination Port + */ +ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, hashsel); +} +/* Function Name: + * rtl8367c_getAsicTrunkingHashSelect + * Description: + * Get port trunking hash select sources + * Input: + * pHashsel - hash sources mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, pHashsel); +} +/* Function Name: + * rtl8367c_getAsicQeueuEmptyStatus + * Description: + * Get current output queue if empty status + * Input: + * portmask - queue empty port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* portmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, portmask); +} +/* Function Name: + * rtl8367c_setAsicTrunkingHashTable + * Description: + * Set port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * portId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(portId >= RTL8367C_TRUNKING_PORTNO) + return RT_ERR_PORT_ID; + + if(hashval >= 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), portId); + else + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), portId); +} +/* Function Name: + * rtl8367c_getAsicTrunkingHashTable + * Description: + * Get port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * pPortId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(hashval >= 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), pPortId); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), pPortId); +} + +/* Function Name: + * rtl8367c_setAsicTrunkingHashTable1 + * Description: + * Set port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * portId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(portId >= RTL8367C_TRUNKING1_PORTN0) + return RT_ERR_PORT_ID; + + if(hashval >= 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), portId); + else + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), portId); +} +/* Function Name: + * rtl8367c_getAsicTrunkingHashTable1 + * Description: + * Get port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * pPortId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(hashval >= 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), pPortId); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), pPortId); +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c new file mode 100755 index 00000000..fcebd1b7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Unkown multicast related functions + * + */ + +#include + +/* Function Name: + * rtl8367c_setAsicUnknownL2MulticastBehavior + * Description: + * Set behavior of L2 multicast + * Input: + * port - Physical port number (0~7) + * behave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid operation + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(behave >= L2_UNKOWN_MULTICAST_END) + return RT_ERR_NOT_ALLOWED; + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), behave); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), behave); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicUnknownL2MulticastBehavior + * Description: + * Get behavior of L2 multicast + * Input: + * port - Physical port number (0~7) + * pBehave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), pBehave); + if (retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), pBehave); + if (retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicUnknownIPv4MulticastBehavior + * Description: + * Set behavior of IPv4 multicast + * Input: + * port - Physical port number (0~7) + * behave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid operation + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(behave >= L3_UNKOWN_MULTICAST_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), behave); +} +/* Function Name: + * rtl8367c_getAsicUnknownIPv4MulticastBehavior + * Description: + * Get behavior of IPv4 multicast + * Input: + * port - Physical port number (0~7) + * pBehave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), pBehave); +} +/* Function Name: + * rtl8367c_setAsicUnknownIPv6MulticastBehavior + * Description: + * Set behavior of IPv6 multicast + * Input: + * port - Physical port number (0~7) + * behave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid operation + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(behave >= L3_UNKOWN_MULTICAST_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), behave); +} +/* Function Name: + * rtl8367c_getAsicUnknownIPv6MulticastBehavior + * Description: + * Get behavior of IPv6 multicast + * Input: + * port - Physical port number (0~7) + * pBehave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), pBehave); +} +/* Function Name: + * rtl8367c_setAsicUnknownMulticastTrapPriority + * Description: + * Set trap priority of unknown multicast frame + * Input: + * priority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, priority); +} +/* Function Name: + * rtl8367c_getAsicUnknownMulticastTrapPriority + * Description: + * Get trap priority of unknown multicast frame + * Input: + * pPriority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, pPriority); +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c new file mode 100755 index 00000000..1e283e74 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c @@ -0,0 +1,1505 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : VLAN related functions + * + */ +#include + +#include + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) +rtl8367c_user_vlan4kentry Rtl8370sVirtualVlanTable[RTL8367C_VIDMAX + 1]; +#endif + +static void _rtl8367c_VlanMCStUser2Smi(rtl8367c_vlanconfiguser *pVlanCg, rtk_uint16 *pSmiVlanCfg) +{ + pSmiVlanCfg[0] |= pVlanCg->mbr & 0x07FF; + + pSmiVlanCfg[1] |= pVlanCg->fid_msti & 0x000F; + + pSmiVlanCfg[2] |= pVlanCg->vbpen & 0x0001; + pSmiVlanCfg[2] |= (pVlanCg->vbpri & 0x0007) << 1; + pSmiVlanCfg[2] |= (pVlanCg->envlanpol & 0x0001) << 4; + pSmiVlanCfg[2] |= (pVlanCg->meteridx & 0x003F) << 5; + + pSmiVlanCfg[3] |= pVlanCg->evid & 0x1FFF; +} + +static void _rtl8367c_VlanMCStSmi2User(rtk_uint16 *pSmiVlanCfg, rtl8367c_vlanconfiguser *pVlanCg) +{ + pVlanCg->mbr = pSmiVlanCfg[0] & 0x07FF; + pVlanCg->fid_msti = pSmiVlanCfg[1] & 0x000F; + pVlanCg->meteridx = (pSmiVlanCfg[2] >> 5) & 0x003F; + pVlanCg->envlanpol = (pSmiVlanCfg[2] >> 4) & 0x0001; + pVlanCg->vbpri = (pSmiVlanCfg[2] >> 1) & 0x0007; + pVlanCg->vbpen = pSmiVlanCfg[2] & 0x0001; + pVlanCg->evid = pSmiVlanCfg[3] & 0x1FFF; +} + +static void _rtl8367c_Vlan4kStUser2Smi(rtl8367c_user_vlan4kentry *pUserVlan4kEntry, rtk_uint16 *pSmiVlan4kEntry) +{ + pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->mbr & 0x00FF); + pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->untag & 0x00FF) << 8; + + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->fid_msti & 0x000F); + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpen & 0x0001) << 4; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpri & 0x0007) << 5; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->envlanpol & 0x0001) << 8; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->meteridx & 0x001F) << 9; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->ivl_svl & 0x0001) << 14; + + pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->mbr & 0x0700) >> 8); + pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->untag & 0x0700) >> 8) << 3; + pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->meteridx & 0x0020) >> 5) << 6; +} + + +static void _rtl8367c_Vlan4kStSmi2User(rtk_uint16 *pSmiVlan4kEntry, rtl8367c_user_vlan4kentry *pUserVlan4kEntry) +{ + pUserVlan4kEntry->mbr = (pSmiVlan4kEntry[0] & 0x00FF) | ((pSmiVlan4kEntry[2] & 0x0007) << 8); + pUserVlan4kEntry->untag = ((pSmiVlan4kEntry[0] & 0xFF00) >> 8) | (((pSmiVlan4kEntry[2] & 0x0038) >> 3) << 8); + pUserVlan4kEntry->fid_msti = pSmiVlan4kEntry[1] & 0x000F; + pUserVlan4kEntry->vbpen = (pSmiVlan4kEntry[1] & 0x0010) >> 4; + pUserVlan4kEntry->vbpri = (pSmiVlan4kEntry[1] & 0x00E0) >> 5; + pUserVlan4kEntry->envlanpol = (pSmiVlan4kEntry[1] & 0x0100) >> 8; + pUserVlan4kEntry->meteridx = ((pSmiVlan4kEntry[1] & 0x3E00) >> 9) | (((pSmiVlan4kEntry[2] & 0x0040) >> 6) << 5); + pUserVlan4kEntry->ivl_svl = (pSmiVlan4kEntry[1] & 0x4000) >> 14; +} + +/* Function Name: + * rtl8367c_setAsicVlanMemberConfig + * Description: + * Set 32 VLAN member configurations + * Input: + * index - VLAN member configuration index (0~31) + * pVlanCg - VLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_L2_FID - Invalid FID + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint16 *tableAddr; + rtk_uint32 page_idx; + rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; + + /* Error Checking */ + if(index > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + if(pVlanCg->evid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + + if(pVlanCg->mbr > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(pVlanCg->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(pVlanCg->meteridx > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(pVlanCg->vbpri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); + _rtl8367c_VlanMCStUser2Smi(pVlanCg, smi_vlancfg); + tableAddr = smi_vlancfg; + + for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ + { + regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; + regData = *tableAddr; + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + tableAddr++; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanMemberConfig + * Description: + * Get 32 VLAN member configurations + * Input: + * index - VLAN member configuration index (0~31) + * pVlanCg - VLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) +{ + ret_t retVal; + rtk_uint32 page_idx; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint16 *tableAddr; + rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; + + if(index > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); + tableAddr = smi_vlancfg; + + for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ + { + regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; + + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = (rtk_uint16)regData; + tableAddr++; + } + + _rtl8367c_VlanMCStSmi2User(smi_vlancfg, pVlanCg); + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlan4kEntry + * Description: + * Set VID mapped entry to 4K VLAN table + * Input: + * pVlan4kEntry - 4K VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_L2_FID - Invalid FID + * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) +{ + rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; + rtk_uint32 page_idx; + rtk_uint16 *tableAddr; + ret_t retVal; + rtk_uint32 regData; + + if(pVlan4kEntry->vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if(pVlan4kEntry->mbr > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(pVlan4kEntry->untag > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(pVlan4kEntry->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(pVlan4kEntry->meteridx > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(pVlan4kEntry->vbpri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + memset(vlan_4k_entry, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_4KTABLE_LEN); + _rtl8367c_Vlan4kStUser2Smi(pVlan4kEntry, vlan_4k_entry); + + /* Prepare Data */ + tableAddr = vlan_4k_entry; + for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + page_idx, regData); + if(retVal != RT_ERR_OK) + return retVal; + + tableAddr++; + } + + /* Write Address (VLAN_ID) */ + regData = pVlan4kEntry->vid; + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Command */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_CVLAN)); + if(retVal != RT_ERR_OK) + return retVal; + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) + memcpy(&Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], pVlan4kEntry, sizeof(rtl8367c_user_vlan4kentry)); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlan4kEntry + * Description: + * Get VID mapped entry to 4K VLAN table + * Input: + * pVlan4kEntry - 4K VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) + * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving + * Note: + * None + */ +ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) +{ + rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; + rtk_uint32 page_idx; + rtk_uint16 *tableAddr; + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 busyCounter; + + if(pVlan4kEntry->vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Polling status */ + busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData == 0) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + /* Write Address (VLAN_ID) */ + regData = pVlan4kEntry->vid; + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Command */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_CVLAN)); + if(retVal != RT_ERR_OK) + return retVal; + + /* Polling status */ + busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData == 0) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + /* Read VLAN data from register */ + tableAddr = vlan_4k_entry; + for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + page_idx, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + tableAddr++; + } + + _rtl8367c_Vlan4kStSmi2User(vlan_4k_entry, pVlan4kEntry); + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) + memcpy(pVlan4kEntry, &Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], sizeof(rtl8367c_user_vlan4kentry)); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanAccpetFrameType + * Description: + * Set per-port acceptable frame type + * Input: + * port - Physical port number (0~10) + * frameType - The acceptable frame type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(frameType >= FRAME_TYPE_MAX_BOUND) + return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; + + return rtl8367c_setAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), frameType); +} +/* Function Name: + * rtl8367c_getAsicVlanAccpetFrameType + * Description: + * Get per-port acceptable frame type + * Input: + * port - Physical port number (0~10) + * pFrameType - The acceptable frame type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType) +{ + rtk_uint32 regData; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), ®Data)) != RT_ERR_OK) + return retVal; + + *pFrameType = (rtl8367c_accframetype)regData; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanIngressFilter + * Description: + * Set VLAN Ingress Filter + * Input: + * port - Physical port number (0~10) + * enabled - Enable or disable Ingress filter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicVlanIngressFilter + * Description: + * Get VLAN Ingress Filter + * Input: + * port - Physical port number (0~10) + * pEnable - Enable or disable Ingress filter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, pEnable); +} +/* Function Name: + * rtl8367c_setAsicVlanEgressTagMode + * Description: + * Set CVLAN egress tag mode + * Input: + * port - Physical port number (0~10) + * tagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(tagMode >= EG_TAG_MODE_END) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, tagMode); +} +/* Function Name: + * rtl8367c_getAsicVlanEgressTagMode + * Description: + * Get CVLAN egress tag mode + * Input: + * port - Physical port number (0~10) + * pTagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode) +{ + rtk_uint32 regData; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, ®Data)) != RT_ERR_OK) + return retVal; + + *pTagMode = (rtl8367c_egtagmode)regData; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanPortBasedVID + * Description: + * Set port based VID which is indexed to 32 VLAN member configurations + * Input: + * port - Physical port number (0~10) + * index - Index to VLAN member configuration + * pri - 1Q Port based VLAN priority + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri) +{ + rtk_uint32 regAddr, bit_mask; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + if(pri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); + bit_mask = RTL8367C_PORT_VIDX_MASK(port); + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, index); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); + bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, pri); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanPortBasedVID + * Description: + * Get port based VID which is indexed to 32 VLAN member configurations + * Input: + * port - Physical port number (0~10) + * pIndex - Index to VLAN member configuration + * pPri - 1Q Port based VLAN priority + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri) +{ + rtk_uint32 regAddr,bit_mask; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); + bit_mask = RTL8367C_PORT_VIDX_MASK(port); + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pIndex); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); + bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pPri); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanProtocolBasedGroupData + * Description: + * Set protocol and port based group database + * Input: + * index - Index to VLAN member configuration + * pPbCfg - Protocol and port based group database entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) +{ + rtk_uint32 frameType; + rtk_uint32 etherType; + ret_t retVal; + + /* Error Checking */ + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + if(pPbCfg->frameType >= PPVLAN_FRAME_TYPE_END ) + return RT_ERR_INPUT; + + frameType = pPbCfg->frameType; + etherType = pPbCfg->etherType; + + /* Frame type */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, frameType); + if(retVal != RT_ERR_OK) + return retVal; + + /* Ether type */ + retVal = rtl8367c_setAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), etherType); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanProtocolBasedGroupData + * Description: + * Get protocol and port based group database + * Input: + * index - Index to VLAN member configuration + * pPbCfg - Protocol and port based group database entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) +{ + rtk_uint32 frameType; + rtk_uint32 etherType; + ret_t retVal; + + /* Error Checking */ + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + /* Read Frame type */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, &frameType); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Ether type */ + retVal = rtl8367c_getAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), ðerType); + if(retVal != RT_ERR_OK) + return retVal; + + + pPbCfg->frameType = frameType; + pPbCfg->etherType = etherType; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanPortAndProtocolBased + * Description: + * Set protocol and port based VLAN configuration + * Input: + * port - Physical port number (0~10) + * index - Index of protocol and port based database index + * pPpbCfg - Protocol and port based VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) +{ + rtk_uint32 reg_addr, bit_mask, bit_value; + ret_t retVal; + + /* Error Checking */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + if( (pPpbCfg->valid != FALSE) && (pPpbCfg->valid != TRUE) ) + return RT_ERR_INPUT; + + if(pPpbCfg->vlan_idx > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + if(pPpbCfg->priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + /* Valid bit */ + reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); + bit_mask = 0x0001 << port; + bit_value = ((TRUE == pPpbCfg->valid) ? 0x1 : 0x0); + retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + /* Calculate the actual register address for CVLAN index*/ + if(port < 8) + { + reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); + bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); + } + else if(port == 8) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; + } + else if(port == 9) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; + } + else if(port == 10) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; + } + + bit_value = pPpbCfg->vlan_idx; + retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + /* write priority */ + reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, index); + bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); + bit_value = pPpbCfg->priority; + retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanPortAndProtocolBased + * Description: + * Get protocol and port based VLAN configuration + * Input: + * port - Physical port number (0~7) + * index - Index of protocol and port based database index + * pPpbCfg - Protocol and port based VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) +{ + rtk_uint32 reg_addr, bit_mask, bit_value; + ret_t retVal; + + /* Error Checking */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + if(pPpbCfg == NULL) + return RT_ERR_INPUT; + + /* Valid bit */ + reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); + bit_mask = 0x0001 << port; + retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + pPpbCfg->valid = bit_value; + + /* CVLAN index */ + if(port < 8) + { + reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); + bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); + } + else if(port == 8) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; + } + else if(port == 9) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; + } + else if(port == 10) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; + } + + retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + pPpbCfg->vlan_idx = bit_value; + + + /* priority */ + reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port,index); + bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); + retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + pPpbCfg->priority = bit_value; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanFilter + * Description: + * Set enable CVLAN filtering function + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicVlanFilter + * Description: + * Get enable CVLAN filtering function + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicVlanUntagDscpPriorityEn + * Description: + * Set enable Dscp to untag 1Q priority + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicVlanUntagDscpPriorityEn + * Description: + * Get enable Dscp to untag 1Q priority + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_setAsicPortBasedFid + * Description: + * Set port based FID + * Input: + * port - Physical port number (0~10) + * fid - Port based fid + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid FID + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid) +{ + rtk_uint32 reg_addr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(port < 8) + return rtl8367c_setAsicReg(RTL8367C_PORT_PBFID_REG(port),fid); + else { + reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; + return rtl8367c_setAsicReg(reg_addr, fid); + } + +} +/* Function Name: + * rtl8367c_getAsicPortBasedFid + * Description: + * Get port based FID + * Input: + * port - Physical port number (0~7) + * pFid - Port based fid + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid) +{ + rtk_uint32 reg_addr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicReg(RTL8367C_PORT_PBFID_REG(port), pFid); + else{ + reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; + return rtl8367c_getAsicReg(reg_addr, pFid); + } +} +/* Function Name: + * rtl8367c_setAsicPortBasedFidEn + * Description: + * Set port based FID selection enable + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortBasedFidEn + * Description: + * Get port based FID selection enable + * Input: + * port - Physical port number (0~10) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicSpanningTreeStatus + * Description: + * Set spanning tree state per each port + * Input: + * port - Physical port number (0~10) + * msti - Multiple spanning tree instance + * state - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_MSTP_STATE - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state) +{ + rtk_uint32 reg_addr,bits_msk; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(msti > RTL8367C_MSTIMAX) + return RT_ERR_MSTI; + + if(state > STPST_FORWARDING) + return RT_ERR_MSTP_STATE; + + if(port < 8) + return rtl8367c_setAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port),state); + else{ + reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); + switch(port){ + case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; + case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; + case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; + } + return rtl8367c_setAsicRegBits(reg_addr, bits_msk,state); + } +} +/* Function Name: + * rtl8367c_getAsicSpanningTreeStatus + * Description: + * Set spanning tree state per each port + * Input: + * port - Physical port number (0~10) + * msti - Multiple spanning tree instance + * pState - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState) +{ + rtk_uint32 reg_addr,bits_msk; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(msti > RTL8367C_MSTIMAX) + return RT_ERR_MSTI; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port), pState); + else{ + reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); + switch(port){ + case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; + case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; + case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; + } + return rtl8367c_getAsicRegBits(reg_addr, bits_msk, pState); + } + +} + +/* Function Name: + * rtl8367c_setAsicVlanTransparent + * Description: + * Set VLAN transparent + * Input: + * port - Physical port number (0~10) + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, portmask); +} + +/* Function Name: + * rtl8367c_getAsicVlanTransparent + * Description: + * Get VLAN transparent + * Input: + * port - Physical port number (0~10) + * Output: + * pPortmask - Ingress port mask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, pPortmask); +} + +/* Function Name: + * rtl8367c_setAsicVlanEgressKeep + * Description: + * Set per egress port VLAN keep mode + * Input: + * port - Physical port number (0~10) + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask) +{ + rtk_uint32 regAddr, bit_mask; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(port < 8){ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); + bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; + bit_mask <<= (port&1)*3; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + } + else{ + switch(port){ + case 8: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + break; + + case 9: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + break; + + case 10: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + break; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicVlanEgressKeep + * Description: + * Get per egress port VLAN keep mode + * Input: + * port - Physical port number (0~7) + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask) +{ + rtk_uint32 regAddr, bit_mask, regval_l, regval_h; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8){ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); + bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; + bit_mask <<= (port&1)*3; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = (regval_h << 8) | regval_l; + } + else{ + switch(port){ + case 8: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + + *pPortmask = (regval_h << 8) | regval_l; + break; + + case 9: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + + *pPortmask = (regval_h << 8) | regval_l; + break; + + case 10: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + + *pPortmask = (regval_h << 8) | regval_l; + break; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setReservedVidAction + * Description: + * Set reserved VID action + * Input: + * vid0Action - VID 0 action + * vid4095Action - VID 4095 action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error input + * Note: + * None + */ +ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action) +{ + ret_t retVal; + + if(vid0Action >= RES_VID_ACT_END) + return RT_ERR_INPUT; + + if(vid4095Action >= RES_VID_ACT_END) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, vid0Action)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, vid4095Action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getReservedVidAction + * Description: + * Get reserved VID action + * Input: + * pVid0Action - VID 0 action + * pVid4095Action - VID 4095 action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action) +{ + ret_t retVal; + + if(pVid0Action == NULL) + return RT_ERR_NULL_POINTER; + + if(pVid4095Action == NULL) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, pVid0Action)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, pVid4095Action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_setRealKeepRemarkEn + * Description: + * Set Real Keep Remark + * Input: + * enabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error input + * Note: + * None + */ +ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getRealKeepRemarkEn + * Description: + * Get Real Keep Remark + * Input: + * None + * Output: + * pEnabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error input + * Note: + * None + */ +ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, pEnabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_resetVlan + * Description: + * Reset VLAN table + * Input: + * None. + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_resetVlan(void) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL2, RTL8367C_VLAN_EXT_CTRL2_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/smi.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/smi.c new file mode 100755 index 00000000..c272cad4 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/smi.c @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367C switch low-level function for access register + * Feature : SMI related functions + * + */ + + +#include +#include +#include "rtk_error.h" + + +#if defined(MDC_MDIO_OPERATION) +/*******************************************************************************/ +/* MDC/MDIO porting */ +/*******************************************************************************/ +/* define the PHY ID currently used */ +/* carlos */ +#if 0 +#define MDC_MDIO_PHY_ID 0 /* PHY ID 0 or 29 */ +#else +#define MDC_MDIO_PHY_ID 29 /* PHY ID 0 or 29 */ +#endif + +/* MDC/MDIO, redefine/implement the following Macro */ /*carlos*/ +#if 0 +#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) +#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) +#else +#define u32 unsigned int +extern u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data); +extern u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data); + +#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) mii_mgr_write(phyID, regID, data) +#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) mii_mgr_read(phyID, regID, pData) +#endif + + + + + +#elif defined(SPI_OPERATION) +/*******************************************************************************/ +/* SPI porting */ +/*******************************************************************************/ +/* SPI, redefine/implement the following Macro */ +#define SPI_WRITE(data, length) +#define SPI_READ(pData, length) + + + + + +#else +/*******************************************************************************/ +/* I2C porting */ +/*******************************************************************************/ +/* Define the GPIO ID for SCK & SDA */ +rtk_uint32 smi_SCK = 1; /* GPIO used for SMI Clock Generation */ +rtk_uint32 smi_SDA = 2; /* GPIO used for SMI Data signal */ + +/* I2C, redefine/implement the following Macro */ +#define GPIO_DIRECTION_SET(gpioID, direction) +#define GPIO_DATA_SET(gpioID, data) +#define GPIO_DATA_GET(gpioID, pData) + + + + + +#endif + +static void rtlglue_drvMutexLock(void) +{ + /* It is empty currently. Implement this function if Lock/Unlock function is needed */ + return; +} + +static void rtlglue_drvMutexUnlock(void) +{ + /* It is empty currently. Implement this function if Lock/Unlock function is needed */ + return; +} + + + +#if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) + /* No local function in MDC/MDIO & SPI mode */ +#else +static void _smi_start(void) +{ + + /* change GPIO pin to Output only */ + GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_OUT); + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); + + /* Initial state: SCK: 0, SDA: 1 */ + GPIO_DATA_SET(smi_SCK, 0); + GPIO_DATA_SET(smi_SDA, 1); + CLK_DURATION(DELAY); + + /* CLK 1: 0 -> 1, 1 -> 0 */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + + /* CLK 2: */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 1); + +} + + + +static void _smi_writeBit(rtk_uint16 signal, rtk_uint32 bitLen) +{ + for( ; bitLen > 0; bitLen--) + { + CLK_DURATION(DELAY); + + /* prepare data */ + if ( signal & (1<<(bitLen-1)) ) + { + GPIO_DATA_SET(smi_SDA, 1); + } + else + { + GPIO_DATA_SET(smi_SDA, 0); + } + CLK_DURATION(DELAY); + + /* clocking */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + } +} + + + +static void _smi_readBit(rtk_uint32 bitLen, rtk_uint32 *rData) +{ + rtk_uint32 u = 0; + + /* change GPIO pin to Input only */ + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); + + for (*rData = 0; bitLen > 0; bitLen--) + { + CLK_DURATION(DELAY); + + /* clocking */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_GET(smi_SDA, &u); + GPIO_DATA_SET(smi_SCK, 0); + + *rData |= (u << (bitLen - 1)); + } + + /* change GPIO pin to Output only */ + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); +} + + + +static void _smi_stop(void) +{ + + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 0); + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 1); + + /* add a click */ + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 1); + + + /* change GPIO pin to Input only */ + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); + GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_IN); +} + +#endif /* End of #if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) */ + +rtk_int32 smi_read(rtk_uint32 mAddrs, rtk_uint32 *rData) +{ +#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) + rtk_uint32 rawData=0, ACK; + rtk_uint8 con; + rtk_uint32 ret = RT_ERR_OK; +#endif + + if(mAddrs > 0xFFFF) + return RT_ERR_INPUT; + + if(rData == NULL) + return RT_ERR_NULL_POINTER; + +#if defined(MDC_MDIO_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write address control code to register 31 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); + + /* Write address to register 23 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); + + /* Write read control code to register 21 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP); + + /* Read data from register 25 */ + MDC_MDIO_READ(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_READ_REG, rData); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; + +#elif defined(SPI_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write 8 bits READ OP_CODE */ + SPI_WRITE(SPI_READ_OP, SPI_READ_OP_LEN); + + /* Write 16 bits register address */ + SPI_WRITE(mAddrs, SPI_REG_LEN); + + /* Read 16 bits data */ + SPI_READ(rData, SPI_DATA_LEN); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; + +#else + + /*Disable CPU interrupt to ensure that the SMI operation is atomic. + The API is based on RTL865X, rewrite the API if porting to other platform.*/ + rtlglue_drvMutexLock(); + + _smi_start(); /* Start SMI */ + + _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370 */ + + _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ + + _smi_writeBit(0x1, 1); /* 1: issue READ command */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for issuing READ command*/ + } while ((ACK != 0) && (con < ack_timer)); + + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ + } while ((ACK != 0) && (con < ack_timer)); + + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK by RTL8369 */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_readBit(8, &rawData); /* Read DATA [7:0] */ + *rData = rawData&0xff; + + _smi_writeBit(0x00, 1); /* ACK by CPU */ + + _smi_readBit(8, &rawData); /* Read DATA [15: 8] */ + + _smi_writeBit(0x01, 1); /* ACK by CPU */ + *rData |= (rawData<<8); + + _smi_stop(); + + rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ + + return ret; +#endif /* end of #if defined(MDC_MDIO_OPERATION) */ +} + + + +rtk_int32 smi_write(rtk_uint32 mAddrs, rtk_uint32 rData) +{ +#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) + rtk_int8 con; + rtk_uint32 ACK; + rtk_uint32 ret = RT_ERR_OK; +#endif + + if(mAddrs > 0xFFFF) + return RT_ERR_INPUT; + + if(rData > 0xFFFF) + return RT_ERR_INPUT; + +#if defined(MDC_MDIO_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write address control code to register 31 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); + + /* Write address to register 23 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); + + /* Write data to register 24 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_WRITE_REG, rData); + + /* Write data control code to register 21 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_WRITE_OP); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; + +#elif defined(SPI_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write 8 bits WRITE OP_CODE */ + SPI_WRITE(SPI_WRITE_OP, SPI_WRITE_OP_LEN); + + /* Write 16 bits register address */ + SPI_WRITE(mAddrs, SPI_REG_LEN); + + /* Write 16 bits data */ + SPI_WRITE(rData, SPI_DATA_LEN); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; +#else + + /*Disable CPU interrupt to ensure that the SMI operation is atomic. + The API is based on RTL865X, rewrite the API if porting to other platform.*/ + rtlglue_drvMutexLock(); + + _smi_start(); /* Start SMI */ + + _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370*/ + + _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ + + _smi_writeBit(0x0, 1); /* 0: issue WRITE command */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for issuing WRITE command*/ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for setting reg_addr[15:8] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit(rData&0xff, 8); /* Write Data [7:0] out */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for writting data [7:0] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit(rData>>8, 8); /* Write Data [15:8] out */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for writting data [15:8] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_stop(); + + rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ + + return ret; +#endif /* end of #if defined(MDC_MDIO_OPERATION) */ +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/stat.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/stat.c new file mode 100755 index 00000000..3a328b0c --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/stat.c @@ -0,0 +1,626 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in MIB module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_stat_global_reset + * Description: + * Reset global MIB counter. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Reset MIB counter of ports. API will use global reset while port mask is all-ports. + */ +rtk_api_ret_t rtk_stat_global_reset(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicMIBsCounterReset(TRUE,FALSE, 0)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_port_reset + * Description: + * Reset per port MIB counter by port. + * Input: + * port - port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_stat_port_reset(rtk_port_t port) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,FALSE,1 << rtk_switch_port_L2P_get(port))) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_queueManage_reset + * Description: + * Reset queue manage MIB counter. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_stat_queueManage_reset(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,TRUE,0)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_stat_global_get + * Description: + * Get global MIB counter + * Input: + * cntr_idx - global counter index. + * Output: + * pCntr - global counter value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get global MIB counter by index definition. + */ +rtk_api_ret_t rtk_stat_global_get(rtk_stat_global_type_t cntr_idx, rtk_stat_counter_t *pCntr) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCntr) + return RT_ERR_NULL_POINTER; + + if (cntr_idx!=DOT1D_TP_LEARNED_ENTRY_DISCARDS_INDEX) + return RT_ERR_STAT_INVALID_GLOBAL_CNTR; + + if ((retVal = rtl8367c_getAsicMIBsCounter(0, cntr_idx, pCntr)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_global_getAll + * Description: + * Get all global MIB counter + * Input: + * None + * Output: + * pGlobal_cntrs - global counter structure. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get all global MIB counter by index definition. + */ +rtk_api_ret_t rtk_stat_global_getAll(rtk_stat_global_cntr_t *pGlobal_cntrs) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pGlobal_cntrs) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicMIBsCounter(0,DOT1D_TP_LEARNED_ENTRY_DISCARDS_INDEX, &pGlobal_cntrs->dot1dTpLearnedEntryDiscards)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +#define MIB_NOT_SUPPORT (0xFFFF) +static rtk_api_ret_t _get_asic_mib_idx(rtk_stat_port_type_t cnt_idx, RTL8367C_MIBCOUNTER *pMib_idx) +{ + RTL8367C_MIBCOUNTER mib_asic_idx[STAT_PORT_CNTR_END]= + { + ifInOctets, /* STAT_IfInOctets */ + dot3StatsFCSErrors, /* STAT_Dot3StatsFCSErrors */ + dot3StatsSymbolErrors, /* STAT_Dot3StatsSymbolErrors */ + dot3InPauseFrames, /* STAT_Dot3InPauseFrames */ + dot3ControlInUnknownOpcodes, /* STAT_Dot3ControlInUnknownOpcodes */ + etherStatsFragments, /* STAT_EtherStatsFragments */ + etherStatsJabbers, /* STAT_EtherStatsJabbers */ + ifInUcastPkts, /* STAT_IfInUcastPkts */ + etherStatsDropEvents, /* STAT_EtherStatsDropEvents */ + etherStatsOctets, /* STAT_EtherStatsOctets */ + etherStatsUnderSizePkts, /* STAT_EtherStatsUnderSizePkts */ + etherOversizeStats, /* STAT_EtherOversizeStats */ + etherStatsPkts64Octets, /* STAT_EtherStatsPkts64Octets */ + etherStatsPkts65to127Octets, /* STAT_EtherStatsPkts65to127Octets */ + etherStatsPkts128to255Octets, /* STAT_EtherStatsPkts128to255Octets */ + etherStatsPkts256to511Octets, /* STAT_EtherStatsPkts256to511Octets */ + etherStatsPkts512to1023Octets, /* STAT_EtherStatsPkts512to1023Octets */ + etherStatsPkts1024to1518Octets, /* STAT_EtherStatsPkts1024to1518Octets */ + ifInMulticastPkts, /* STAT_EtherStatsMulticastPkts */ + ifInBroadcastPkts, /* STAT_EtherStatsBroadcastPkts */ + ifOutOctets, /* STAT_IfOutOctets */ + dot3StatsSingleCollisionFrames, /* STAT_Dot3StatsSingleCollisionFrames */ + dot3StatMultipleCollisionFrames,/* STAT_Dot3StatsMultipleCollisionFrames */ + dot3sDeferredTransmissions, /* STAT_Dot3StatsDeferredTransmissions */ + dot3StatsLateCollisions, /* STAT_Dot3StatsLateCollisions */ + etherStatsCollisions, /* STAT_EtherStatsCollisions */ + dot3StatsExcessiveCollisions, /* STAT_Dot3StatsExcessiveCollisions */ + dot3OutPauseFrames, /* STAT_Dot3OutPauseFrames */ + MIB_NOT_SUPPORT, /* STAT_Dot1dBasePortDelayExceededDiscards */ + dot1dTpPortInDiscards, /* STAT_Dot1dTpPortInDiscards */ + ifOutUcastPkts, /* STAT_IfOutUcastPkts */ + ifOutMulticastPkts, /* STAT_IfOutMulticastPkts */ + ifOutBroadcastPkts, /* STAT_IfOutBroadcastPkts */ + outOampduPkts, /* STAT_OutOampduPkts */ + inOampduPkts, /* STAT_InOampduPkts */ + MIB_NOT_SUPPORT, /* STAT_PktgenPkts */ + inMldChecksumError, /* STAT_InMldChecksumError */ + inIgmpChecksumError, /* STAT_InIgmpChecksumError */ + inMldSpecificQuery, /* STAT_InMldSpecificQuery */ + inMldGeneralQuery, /* STAT_InMldGeneralQuery */ + inIgmpSpecificQuery, /* STAT_InIgmpSpecificQuery */ + inIgmpGeneralQuery, /* STAT_InIgmpGeneralQuery */ + inMldLeaves, /* STAT_InMldLeaves */ + inIgmpLeaves, /* STAT_InIgmpInterfaceLeaves */ + inIgmpJoinsSuccess, /* STAT_InIgmpJoinsSuccess */ + inIgmpJoinsFail, /* STAT_InIgmpJoinsFail */ + inMldJoinsSuccess, /* STAT_InMldJoinsSuccess */ + inMldJoinsFail, /* STAT_InMldJoinsFail */ + inReportSuppressionDrop, /* STAT_InReportSuppressionDrop */ + inLeaveSuppressionDrop, /* STAT_InLeaveSuppressionDrop */ + outIgmpReports, /* STAT_OutIgmpReports */ + outIgmpLeaves, /* STAT_OutIgmpLeaves */ + outIgmpGeneralQuery, /* STAT_OutIgmpGeneralQuery */ + outIgmpSpecificQuery, /* STAT_OutIgmpSpecificQuery */ + outMldReports, /* STAT_OutMldReports */ + outMldLeaves, /* STAT_OutMldLeaves */ + outMldGeneralQuery, /* STAT_OutMldGeneralQuery */ + outMldSpecificQuery, /* STAT_OutMldSpecificQuery */ + inKnownMulticastPkts, /* STAT_InKnownMulticastPkts */ + ifInMulticastPkts, /* STAT_IfInMulticastPkts */ + ifInBroadcastPkts, /* STAT_IfInBroadcastPkts */ + ifOutDiscards /* STAT_IfOutDiscards */ + }; + + if(cnt_idx >= STAT_PORT_CNTR_END) + return RT_ERR_STAT_INVALID_PORT_CNTR; + + if(mib_asic_idx[cnt_idx] == MIB_NOT_SUPPORT) + return RT_ERR_CHIP_NOT_SUPPORTED; + + *pMib_idx = mib_asic_idx[cnt_idx]; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_port_get + * Description: + * Get per port MIB counter by index + * Input: + * port - port id. + * cntr_idx - port counter index. + * Output: + * pCntr - MIB retrived counter. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Get per port MIB counter by index definition. + */ +rtk_api_ret_t rtk_stat_port_get(rtk_port_t port, rtk_stat_port_type_t cntr_idx, rtk_stat_counter_t *pCntr) +{ + rtk_api_ret_t retVal; + RTL8367C_MIBCOUNTER mib_idx; + rtk_stat_counter_t second_cnt; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCntr) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if (cntr_idx>=STAT_PORT_CNTR_END) + return RT_ERR_STAT_INVALID_PORT_CNTR; + + if((retVal = _get_asic_mib_idx(cntr_idx, &mib_idx)) != RT_ERR_OK) + return retVal; + + if(mib_idx == MIB_NOT_SUPPORT) + return RT_ERR_CHIP_NOT_SUPPORTED; + + if ((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, pCntr)) != RT_ERR_OK) + return retVal; + + if(cntr_idx == STAT_EtherStatsMulticastPkts) + { + if((retVal = _get_asic_mib_idx(STAT_IfOutMulticastPkts, &mib_idx)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) + return retVal; + + *pCntr += second_cnt; + } + + if(cntr_idx == STAT_EtherStatsBroadcastPkts) + { + if((retVal = _get_asic_mib_idx(STAT_IfOutBroadcastPkts, &mib_idx)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) + return retVal; + + *pCntr += second_cnt; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_port_getAll + * Description: + * Get all counters of one specified port in the specified device. + * Input: + * port - port id. + * Output: + * pPort_cntrs - buffer pointer of counter value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get all MIB counters of one port. + */ +rtk_api_ret_t rtk_stat_port_getAll(rtk_port_t port, rtk_stat_port_cntr_t *pPort_cntrs) +{ + rtk_api_ret_t retVal; + rtk_uint32 mibIndex; + rtk_uint64 mibCounter; + rtk_uint32 *accessPtr; + /* address offset to MIBs counter */ + CONST_T rtk_uint16 mibLength[STAT_PORT_CNTR_END]= { + 2,1,1,1,1,1,1,1,1, + 2,1,1,1,1,1,1,1,1,1,1, + 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPort_cntrs) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + accessPtr = (rtk_uint32*)pPort_cntrs; + for (mibIndex=0;mibIndex RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((idx % 2) == 1) + return RT_ERR_INPUT; + + if(mode >= LOGGING_MODE_END) + return RT_ERR_OUT_OF_RANGE; + + if(type >= LOGGING_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + if((retVal = rtl8367c_setAsicMIBsLoggingType((idx / 2), (rtk_uint32)type)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicMIBsLoggingMode((idx / 2), (rtk_uint32)mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_logging_counterCfg_get + * Description: + * Get the type and mode of Logging Counter + * Input: + * idx - The index of Logging Counter. Should be even number only.(0,2,4,6,8.....30) + * Output: + * pMode - 32 bits or 64 bits mode + * pType - Packet counter or byte counter + * Return: + * RT_ERR_OK - OK + * RT_ERR_OUT_OF_RANGE - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - NULL Pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the type and mode of Logging Counter. + */ +rtk_api_ret_t rtk_stat_logging_counterCfg_get(rtk_uint32 idx, rtk_logging_counter_mode_t *pMode, rtk_logging_counter_type_t *pType) +{ + rtk_api_ret_t retVal; + rtk_uint32 type, mode; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((idx % 2) == 1) + return RT_ERR_INPUT; + + if(pMode == NULL) + return RT_ERR_NULL_POINTER; + + if(pType == NULL) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMIBsLoggingType((idx / 2), &type)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicMIBsLoggingMode((idx / 2), &mode)) != RT_ERR_OK) + return retVal; + + *pMode = (rtk_logging_counter_mode_t)mode; + *pType = (rtk_logging_counter_type_t)type; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_stat_logging_counter_reset + * Description: + * Reset Logging Counter + * Input: + * idx - The index of Logging Counter. (0~31) + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_OUT_OF_RANGE - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Reset Logging Counter. + */ +rtk_api_ret_t rtk_stat_logging_counter_reset(rtk_uint32 idx) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((retVal = rtl8367c_setAsicMIBsResetLoggingCounter(idx)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_logging_counter_get + * Description: + * Get Logging Counter + * Input: + * idx - The index of Logging Counter. (0~31) + * Output: + * pCnt - Logging counter value + * Return: + * RT_ERR_OK - OK + * RT_ERR_OUT_OF_RANGE - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Get Logging Counter. + */ +rtk_api_ret_t rtk_stat_logging_counter_get(rtk_uint32 idx, rtk_uint32 *pCnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCnt) + return RT_ERR_NULL_POINTER; + + if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((retVal = rtl8367c_getAsicMIBsLogCounter(idx, pCnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_lengthMode_set + * Description: + * Set Legnth mode. + * Input: + * txMode - The length counting mode + * rxMode - The length counting mode + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_stat_lengthMode_set(rtk_stat_lengthMode_t txMode, rtk_stat_lengthMode_t rxMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(txMode >= LENGTH_MODE_END) + return RT_ERR_INPUT; + + if(rxMode >= LENGTH_MODE_END) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicMIBsLength((rtk_uint32)txMode, (rtk_uint32)rxMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_lengthMode_get + * Description: + * Get Legnth mode. + * Input: + * None. + * Output: + * pTxMode - The length counting mode + * pRxMode - The length counting mode + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_stat_lengthMode_get(rtk_stat_lengthMode_t *pTxMode, rtk_stat_lengthMode_t *pRxMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pTxMode) + return RT_ERR_NULL_POINTER; + + if(NULL == pRxMode) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMIBsLength((rtk_uint32 *)pTxMode, (rtk_uint32 *)pRxMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/storm.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/storm.c new file mode 100755 index 00000000..13cf4e3c --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/storm.c @@ -0,0 +1,816 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Storm module. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_rate_stormControlMeterIdx_set + * Description: + * Set the storm control meter index. + * Input: + * port - port id + * storm_type - storm group type + * index - storm control meter index. + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - Invalid port id + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlMeterIdx_set(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 index) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlMeterIdx_get + * Description: + * Get the storm control meter index. + * Input: + * port - port id + * storm_type - storm group type + * Output: + * pIndex - storm control meter index. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - Invalid port id + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlMeterIdx_get(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (NULL == pIndex ) + return RT_ERR_NULL_POINTER; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlPortEnable_set + * Description: + * Set enable status of storm control on specified port. + * Input: + * port - port id + * stormType - storm group type + * enable - enable status of storm control + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlPortEnable_set(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlPortEnable_set + * Description: + * Set enable status of storm control on specified port. + * Input: + * port - port id + * stormType - storm group type + * Output: + * pEnable - enable status of storm control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlPortEnable_get(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (NULL == pEnable) + return RT_ERR_ENABLE; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_storm_bypass_set + * Description: + * Set bypass storm filter control configuration. + * Input: + * type - Bypass storm filter control type. + * enable - Bypass status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * This API can set per-port bypass stomr filter control frame type including RMA and igmp. + * The bypass frame type is as following: + * - BYPASS_BRG_GROUP, + * - BYPASS_FD_PAUSE, + * - BYPASS_SP_MCAST, + * - BYPASS_1X_PAE, + * - BYPASS_UNDEF_BRG_04, + * - BYPASS_UNDEF_BRG_05, + * - BYPASS_UNDEF_BRG_06, + * - BYPASS_UNDEF_BRG_07, + * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - BYPASS_UNDEF_BRG_09, + * - BYPASS_UNDEF_BRG_0A, + * - BYPASS_UNDEF_BRG_0B, + * - BYPASS_UNDEF_BRG_0C, + * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - BYPASS_8021AB, + * - BYPASS_UNDEF_BRG_0F, + * - BYPASS_BRG_MNGEMENT, + * - BYPASS_UNDEFINED_11, + * - BYPASS_UNDEFINED_12, + * - BYPASS_UNDEFINED_13, + * - BYPASS_UNDEFINED_14, + * - BYPASS_UNDEFINED_15, + * - BYPASS_UNDEFINED_16, + * - BYPASS_UNDEFINED_17, + * - BYPASS_UNDEFINED_18, + * - BYPASS_UNDEFINED_19, + * - BYPASS_UNDEFINED_1A, + * - BYPASS_UNDEFINED_1B, + * - BYPASS_UNDEFINED_1C, + * - BYPASS_UNDEFINED_1D, + * - BYPASS_UNDEFINED_1E, + * - BYPASS_UNDEFINED_1F, + * - BYPASS_GMRP, + * - BYPASS_GVRP, + * - BYPASS_UNDEF_GARP_22, + * - BYPASS_UNDEF_GARP_23, + * - BYPASS_UNDEF_GARP_24, + * - BYPASS_UNDEF_GARP_25, + * - BYPASS_UNDEF_GARP_26, + * - BYPASS_UNDEF_GARP_27, + * - BYPASS_UNDEF_GARP_28, + * - BYPASS_UNDEF_GARP_29, + * - BYPASS_UNDEF_GARP_2A, + * - BYPASS_UNDEF_GARP_2B, + * - BYPASS_UNDEF_GARP_2C, + * - BYPASS_UNDEF_GARP_2D, + * - BYPASS_UNDEF_GARP_2E, + * - BYPASS_UNDEF_GARP_2F, + * - BYPASS_IGMP. + * - BYPASS_CDP. + * - BYPASS_CSSTP. + * - BYPASS_LLDP. + */ +rtk_api_ret_t rtk_storm_bypass_set(rtk_storm_bypass_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= BYPASS_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if(type == BYPASS_IGMP) + { + if ((retVal = rtl8367c_setAsicIGMPBypassStormCTRL(enable)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_storm_bypass_get + * Description: + * Get bypass storm filter control configuration. + * Input: + * type - Bypass storm filter control type. + * Output: + * pEnable - Bypass status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get per-port bypass stomr filter control frame type including RMA and igmp. + * The bypass frame type is as following: + * - BYPASS_BRG_GROUP, + * - BYPASS_FD_PAUSE, + * - BYPASS_SP_MCAST, + * - BYPASS_1X_PAE, + * - BYPASS_UNDEF_BRG_04, + * - BYPASS_UNDEF_BRG_05, + * - BYPASS_UNDEF_BRG_06, + * - BYPASS_UNDEF_BRG_07, + * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - BYPASS_UNDEF_BRG_09, + * - BYPASS_UNDEF_BRG_0A, + * - BYPASS_UNDEF_BRG_0B, + * - BYPASS_UNDEF_BRG_0C, + * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - BYPASS_8021AB, + * - BYPASS_UNDEF_BRG_0F, + * - BYPASS_BRG_MNGEMENT, + * - BYPASS_UNDEFINED_11, + * - BYPASS_UNDEFINED_12, + * - BYPASS_UNDEFINED_13, + * - BYPASS_UNDEFINED_14, + * - BYPASS_UNDEFINED_15, + * - BYPASS_UNDEFINED_16, + * - BYPASS_UNDEFINED_17, + * - BYPASS_UNDEFINED_18, + * - BYPASS_UNDEFINED_19, + * - BYPASS_UNDEFINED_1A, + * - BYPASS_UNDEFINED_1B, + * - BYPASS_UNDEFINED_1C, + * - BYPASS_UNDEFINED_1D, + * - BYPASS_UNDEFINED_1E, + * - BYPASS_UNDEFINED_1F, + * - BYPASS_GMRP, + * - BYPASS_GVRP, + * - BYPASS_UNDEF_GARP_22, + * - BYPASS_UNDEF_GARP_23, + * - BYPASS_UNDEF_GARP_24, + * - BYPASS_UNDEF_GARP_25, + * - BYPASS_UNDEF_GARP_26, + * - BYPASS_UNDEF_GARP_27, + * - BYPASS_UNDEF_GARP_28, + * - BYPASS_UNDEF_GARP_29, + * - BYPASS_UNDEF_GARP_2A, + * - BYPASS_UNDEF_GARP_2B, + * - BYPASS_UNDEF_GARP_2C, + * - BYPASS_UNDEF_GARP_2D, + * - BYPASS_UNDEF_GARP_2E, + * - BYPASS_UNDEF_GARP_2F, + * - BYPASS_IGMP. + * - BYPASS_CDP. + * - BYPASS_CSSTP. + * - BYPASS_LLDP. + */ +rtk_api_ret_t rtk_storm_bypass_get(rtk_storm_bypass_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= BYPASS_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else if(type == BYPASS_IGMP) + { + if ((retVal = rtl8367c_getAsicIGMPBypassStormCTRL(pEnable)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else if (type == BYPASS_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else if (type == BYPASS_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtPortmask_set + * Description: + * Set externsion storm control port mask + * Input: + * pPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtPortmask_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicStormFilterExtEnablePortMask(pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtPortmask_get + * Description: + * Set externsion storm control port mask + * Input: + * None + * Output: + * pPortmask - port mask + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtPortmask_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicStormFilterExtEnablePortMask(&pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtEnable_set + * Description: + * Set externsion storm control state + * Input: + * stormType - storm group type + * enable - externsion storm control state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtEnable_set(rtk_rate_storm_group_t stormType, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtMulticastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtEnable_get + * Description: + * Get externsion storm control state + * Input: + * stormType - storm group type + * Output: + * pEnable - externsion storm control state + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtEnable_get(rtk_rate_storm_group_t stormType, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (NULL == pEnable) + return RT_ERR_NULL_POINTER; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtMeterIdx_set + * Description: + * Set externsion storm control meter index + * Input: + * stormType - storm group type + * index - externsion storm control state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_set(rtk_rate_storm_group_t stormType, rtk_uint32 index) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtMulticastMeter(index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastMeter(index))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtMeterIdx_get + * Description: + * Get externsion storm control meter index + * Input: + * stormType - storm group type + * pIndex - externsion storm control state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_get(rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtMulticastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/svlan.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/svlan.c new file mode 100755 index 00000000..bf4ef044 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/svlan.c @@ -0,0 +1,2415 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in SVLAN module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +rtk_uint8 svlan_mbrCfgUsage[RTL8367C_SVIDXNO]; +rtk_uint16 svlan_mbrCfgVid[RTL8367C_SVIDXNO]; +rtk_svlan_lookupType_t svlan_lookupType; +/* Function Name: + * rtk_svlan_init + * Description: + * Initialize SVLAN Configuration + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 for Q-in-Q SLAN design. + * User can set mathced ether type as service provider supported protocol. + */ +rtk_api_ret_t rtk_svlan_init(void) +{ + rtk_uint32 i; + rtk_api_ret_t retVal; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + rtk_uint32 svidx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /*default use C-priority*/ + if ((retVal = rtl8367c_setAsicSvlanPrioritySel(SPRISEL_CTAGPRI)) != RT_ERR_OK) + return retVal; + + /*Drop SVLAN untag frame*/ + if ((retVal = rtl8367c_setAsicSvlanIngressUntag(UNTAG_DROP)) != RT_ERR_OK) + return retVal; + + /*Drop SVLAN unmatch frame*/ + if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch(UNMATCH_DROP)) != RT_ERR_OK) + return retVal; + + /*Set TPID to 0x88a8*/ + if ((retVal = rtl8367c_setAsicSvlanTpid(0x88a8)) != RT_ERR_OK) + return retVal; + + /*Clean Uplink Port Mask to none*/ + if ((retVal = rtl8367c_setAsicSvlanUplinkPortMask(0)) != RT_ERR_OK) + return retVal; + + /*Clean SVLAN Member Configuration*/ + for (i=0; i<= RTL8367C_SVIDXMAX; i++) + { + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + } + + /*Clean C2S Configuration*/ + for (i=0; i<= RTL8367C_C2SIDXMAX; i++) + { + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, 0,0,0)) != RT_ERR_OK) + return retVal; + } + + /*Clean SP2C Configuration*/ + for (i=0; i <= RTL8367C_SP2CMAX ; i++) + { + memset(&svlanSP2CConf, 0, sizeof(rtl8367c_svlan_s2c_t)); + if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + } + + /*Clean MC2S Configuration*/ + for (i=0 ; i<= RTL8367C_MC2SIDXMAX; i++) + { + memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + } + + + if ((retVal = rtk_svlan_lookupType_set(SVLAN_LOOKUP_S64MBRCGF)) != RT_ERR_OK) + return retVal; + + + for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) + { + svlan_mbrCfgUsage[svidx] = FALSE; + } + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_servicePort_add + * Description: + * Add one service port in the specified device + * Input: + * port - Port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API is setting which port is connected to provider switch. All frames receiving from this port must + * contain accept SVID in S-tag field. + */ +rtk_api_ret_t rtk_svlan_servicePort_add(rtk_port_t port) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicSvlanUplinkPortMask(&pmsk)) != RT_ERR_OK) + return retVal; + + pmsk = pmsk | (1<RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicSvlanTpid(svlan_tag_id)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_tpidEntry_get + * Description: + * Get accepted S-VLAN ether type setting. + * Input: + * None + * Output: + * pSvlan_tag_id - Ether type of S-tag frame parsing in uplink ports. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is setting which port is connected to provider switch. All frames receiving from this port must + * contain accept SVID in S-tag field. + */ +rtk_api_ret_t rtk_svlan_tpidEntry_get(rtk_svlan_tpid_t *pSvlan_tag_id) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_tag_id) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanTpid(pSvlan_tag_id)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_priorityRef_set + * Description: + * Set S-VLAN upstream priority reference setting. + * Input: + * ref - reference selection parameter. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The API can set the upstream SVLAN tag priority reference source. The related priority + * sources are as following: + * - REF_INTERNAL_PRI, + * - REF_CTAG_PRI, + * - REF_SVLAN_PRI, + * - REF_PB_PRI. + */ +rtk_api_ret_t rtk_svlan_priorityRef_set(rtk_svlan_pri_ref_t ref) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (ref >= REF_PRI_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicSvlanPrioritySel(ref)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_priorityRef_get + * Description: + * Get S-VLAN upstream priority reference setting. + * Input: + * None + * Output: + * pRef - reference selection parameter. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get the upstream SVLAN tag priority reference source. The related priority + * sources are as following: + * - REF_INTERNAL_PRI, + * - REF_CTAG_PRI, + * - REF_SVLAN_PRI, + * - REF_PB_PRI + */ +rtk_api_ret_t rtk_svlan_priorityRef_get(rtk_svlan_pri_ref_t *pRef) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pRef) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanPrioritySel(pRef)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_memberPortEntry_set + * Description: + * Configure system SVLAN member content + * Input: + * svid - SVLAN id + * psvlan_cfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. + * Note: + * The API can set system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped by default setup. + * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtk_int32 i; + rtk_uint32 empty_idx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_uint32 phyMbrPmask; + rtk_vlan_cfg_t vlanCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if(svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); + + if (pSvlan_cfg->fiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if (pSvlan_cfg->priority > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if (pSvlan_cfg->efiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + if(SVLAN_LOOKUP_C4KVLAN == svlan_lookupType) + { + if ((retVal = rtk_vlan_get(svid, &vlanCfg)) != RT_ERR_OK) + return retVal; + + vlanCfg.mbr = pSvlan_cfg->memberport; + vlanCfg.untag = pSvlan_cfg->untagport; + + if ((retVal = rtk_vlan_set(svid, &vlanCfg)) != RT_ERR_OK) + return retVal; + + empty_idx = 0xFF; + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) + { + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = svid; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + + /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + svlanMemConf.vs_efid = 1; + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) + { + empty_idx = i; + } + } + + if (empty_idx != 0xFF) + { + svlan_mbrCfgUsage[empty_idx] = TRUE; + svlan_mbrCfgVid[empty_idx] = svid; + + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = svid; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + + /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + svlanMemConf.vs_efid = 1; + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + } + + return RT_ERR_OK; + } + + + empty_idx = 0xFF; + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + /* + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + */ + if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) + { + svlanMemConf.vs_svid = svid; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_member = phyMbrPmask; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_untag = phyMbrPmask; + + svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; + svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + + /*all items are reset means deleting*/ + if( 0 == svlanMemConf.vs_member && + 0 == svlanMemConf.vs_untag && + 0 == svlanMemConf.vs_force_fid && + 0 == svlanMemConf.vs_fid_msti && + 0 == svlanMemConf.vs_priority && + 0 == svlanMemConf.vs_efiden && + 0 == svlanMemConf.vs_efid) + { + svlan_mbrCfgUsage[i] = FALSE; + svlan_mbrCfgVid[i] = 0; + + /* Clear SVID also */ + svlanMemConf.vs_svid = 0; + } + else + { + svlan_mbrCfgUsage[i] = TRUE; + svlan_mbrCfgVid[i] = svlanMemConf.vs_svid; + + if(0 == svlanMemConf.vs_svid) + { + /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + { + svlanMemConf.vs_efid = 1; + } + } + } + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) + { + empty_idx = i; + } + } + + if (empty_idx != 0xFF) + { + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = svid; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_member = phyMbrPmask; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_untag = phyMbrPmask; + + svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; + svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + + /*change efid for empty svid 0*/ + if(0 == svlanMemConf.vs_svid) + { /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + { + svlanMemConf.vs_efid = 1; + } + } + + svlan_mbrCfgUsage[empty_idx] = TRUE; + svlan_mbrCfgVid[empty_idx] = svlanMemConf.vs_svid; + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) + { + return retVal; + } + + return RT_ERR_OK; + } + + return RT_ERR_SVLAN_TABLE_FULL; +} + +/* Function Name: + * rtk_svlan_memberPortEntry_get + * Description: + * Get SVLAN member Configure. + * Input: + * svid - SVLAN id + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + pSvlan_cfg->svid = svlanMemConf.vs_svid; + + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; + pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; + pSvlan_cfg->priority = svlanMemConf.vs_priority; + pSvlan_cfg->efiden = svlanMemConf.vs_efiden; + pSvlan_cfg->efid = svlanMemConf.vs_efid; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + +} + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_set + * Description: + * Configure system SVLAN member by index + * Input: + * idx - Index (0 ~ 63) + * psvlan_cfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. + * Note: + * The API can set system 64 accepted s-tag frame format by index. + * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_uint32 phyMbrPmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if (idx > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + if (pSvlan_cfg->svid>RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); + + if (pSvlan_cfg->fiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if (pSvlan_cfg->priority > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if (pSvlan_cfg->efiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = pSvlan_cfg->svid; + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_member = phyMbrPmask; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_untag = phyMbrPmask; + + + svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; + svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + + if(0 == svlanMemConf.vs_svid && + 0 == svlanMemConf.vs_member && + 0 == svlanMemConf.vs_untag && + 0 == svlanMemConf.vs_force_fid && + 0 == svlanMemConf.vs_fid_msti && + 0 == svlanMemConf.vs_priority && + 0 == svlanMemConf.vs_efiden && + 0 == svlanMemConf.vs_efid) + { + svlan_mbrCfgUsage[idx] = FALSE; + svlan_mbrCfgVid[idx] = 0; + } + else + { + svlan_mbrCfgUsage[idx] = TRUE; + svlan_mbrCfgVid[idx] = svlanMemConf.vs_svid; + } + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_get + * Description: + * Get SVLAN member Configure by index. + * Input: + * idx - Index (0 ~ 63) + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if (idx > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + pSvlan_cfg->svid = svlanMemConf.vs_svid; + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; + pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; + pSvlan_cfg->priority = svlanMemConf.vs_priority; + pSvlan_cfg->efiden = svlanMemConf.vs_efiden; + pSvlan_cfg->efid = svlanMemConf.vs_efid; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_svlan_defaultSvlan_set + * Description: + * Configure default egress SVLAN. + * Input: + * port - Source port + * svid - SVLAN id + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * Note: + * The API can set port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + /* svid must be 0~4095 */ + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + if ((retVal = rtl8367c_setAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), i)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; +} + +/* Function Name: + * rtk_svlan_defaultSvlan_get + * Description: + * Get the configure default egress SVLAN. + * Input: + * port - Source port + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 idx; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), &idx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_c2s_add + * Description: + * Configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set system C2S configuration. ASIC will check upstream's VID and assign related + * SVID to mathed packet. There are 128 SVLAN C2S configurations. + */ +rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx; + rtk_uint32 evid, pmsk, svidx, c2s_svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_port_t phyPort; + rtk_uint16 doneFlag; + + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(src_port); + + phyPort = rtk_switch_port_L2P_get(src_port); + + empty_idx = 0xFFFF; + svidx = 0xFFFF; + doneFlag = FALSE; + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_VID; + + for (i=RTL8367C_C2SIDXMAX; i>=0; i--) + { + if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &c2s_svidx)) != RT_ERR_OK) + return retVal; + + if (evid == vid) + { + /* Check Src_port */ + if(pmsk & (1 << phyPort)) + { + /* Check SVIDX */ + if(c2s_svidx == svidx) + { + /* All the same, do nothing */ + } + else + { + /* New svidx, remove src_port and find a new slot to add a new enrty */ + pmsk = pmsk & ~(1 << phyPort); + if(pmsk == 0) + c2s_svidx = 0; + + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, c2s_svidx)) != RT_ERR_OK) + return retVal; + } + } + else + { + if(c2s_svidx == svidx && doneFlag == FALSE) + { + pmsk = pmsk | (1 << phyPort); + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) + return retVal; + + doneFlag = TRUE; + } + } + } + else if (evid==0&&pmsk==0) + { + empty_idx = i; + } + } + + if (0xFFFF != empty_idx && doneFlag ==FALSE) + { + if ((retVal = rtl8367c_setAsicSvlanC2SConf(empty_idx, vid, (1< RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(src_port); + phyPort = rtk_switch_port_L2P_get(src_port); + + for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) + return retVal; + + if (evid == vid) + { + if(pmsk & (1 << phyPort)) + { + pmsk = pmsk & ~(1 << phyPort); + if(pmsk == 0) + { + vid = 0; + svidx = 0; + } + + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_c2s_get + * Description: + * Get configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * Output: + * pSvid - SVLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. + */ +rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 evid, pmsk, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_port_t phyPort; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(src_port); + phyPort = rtk_switch_port_L2P_get(src_port); + + for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) + return retVal; + + if (evid == vid) + { + if(pmsk & (1 << phyPort)) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_untag_action_set + * Description: + * Configure Action of downstream UnStag packet + * Input: + * action - Action for UnStag + * svid - The SVID assigned to UnStag packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also supported by this API. The parameter of svid is + * only referenced when the action is set to UNTAG_ASSIGN + */ +rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (action >= UNTAG_END) + return RT_ERR_OUT_OF_RANGE; + + if(action == UNTAG_ASSIGN) + { + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + } + + if ((retVal = rtl8367c_setAsicSvlanIngressUntag((rtk_uint32)action)) != RT_ERR_OK) + return retVal; + + if(action == UNTAG_ASSIGN) + { + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + if ((retVal = rtl8367c_setAsicSvlanUntagVlan(i)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_untag_action_get + * Description: + * Get Action of downstream UnStag packet + * Input: + * None + * Output: + * pAction - Action for UnStag + * pSvid - The SVID assigned to UnStag packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNTAG_ASSIGN + */ +rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction || NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanIngressUntag(pAction)) != RT_ERR_OK) + return retVal; + + if(*pAction == UNTAG_ASSIGN) + { + if ((retVal = rtl8367c_getAsicSvlanUntagVlan(&svidx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_unmatch_action_set + * Description: + * Configure Action of downstream Unmatch packet + * Input: + * action - Action for Unmatch + * svid - The SVID assigned to Unmatch packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-match packet. A SVID assigned + * to the un-match is also supported by this API. The parameter od svid is + * only refernced when the action is set to UNMATCH_ASSIGN + */ +rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (action >= UNMATCH_END) + return RT_ERR_OUT_OF_RANGE; + + if (action == UNMATCH_ASSIGN) + { + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + } + + if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch((rtk_uint32)action)) != RT_ERR_OK) + return retVal; + + if(action == UNMATCH_ASSIGN) + { + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + if ((retVal = rtl8367c_setAsicSvlanUnmatchVlan(i)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_unmatch_action_get + * Description: + * Get Action of downstream Unmatch packet + * Input: + * None + * Output: + * pAction - Action for Unmatch + * pSvid - The SVID assigned to Unmatch packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-match packet. A SVID assigned + * to the un-match is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNMATCH_ASSIGN + */ +rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction || NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanIngressUnmatch(pAction)) != RT_ERR_OK) + return retVal; + + if(*pAction == UNMATCH_ASSIGN) + { + if ((retVal = rtl8367c_getAsicSvlanUnmatchVlan(&svidx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_unassign_action_set + * Description: + * Configure Action of upstream without svid assign action + * Input: + * action - Action for Un-assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of upstream Un-assign svid packet. If action is not + * trap to CPU, the port-based SVID sure be assign as system need + */ +rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (action >= UNASSIGN_END) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicSvlanEgressUnassign((rtk_uint32)action); + + return retVal; +} + +/* Function Name: + * rtk_svlan_unassign_action_get + * Description: + * Get action of upstream without svid assignment + * Input: + * None + * Output: + * pAction - Action for Un-assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * None + */ +rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicSvlanEgressUnassign(pAction); + + return retVal; +} + +/* Function Name: + * rtk_svlan_dmac_vidsel_set + * Description: + * Set DMAC CVID selection + * Input: + * port - Port + * enable - state of DMAC CVID Selection + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set DMAC CVID Selection state + */ +rtk_api_ret_t rtk_svlan_dmac_vidsel_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_dmac_vidsel_get + * Description: + * Get DMAC CVID selection + * Input: + * port - Port + * Output: + * pEnable - state of DMAC CVID Selection + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get DMAC CVID Selection state + */ +rtk_api_ret_t rtk_svlan_dmac_vidsel_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_ipmc2s_add + * Description: + * add ip multicast address to SVLAN + * Input: + * svid - SVLAN VID + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set IP mutlicast to SVID configuration. If upstream packet is IPv4 multicast + * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. + * There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk,rtk_vlan_t svid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx; + rtk_uint32 svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + if ((ipmc&0xF0000000)!=0xE0000000) + return RT_ERR_INPUT; + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + + empty_idx = 0xFFFF; + + for (i = RTL8367C_MC2SIDXMAX; i >= 0; i--) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && + svlanMC2SConf.sdata==ipmc&& + svlanMC2SConf.smask==ipmcMsk) + { + svlanMC2SConf.svidx = svidx; + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + } + } + else + { + empty_idx = i; + } + } + + if (empty_idx!=0xFFFF) + { + svlanMC2SConf.valid = TRUE; + svlanMC2SConf.svidx = svidx; + svlanMC2SConf.format = SVLAN_MC2S_MODE_IP; + svlanMC2SConf.sdata = ipmc; + svlanMC2SConf.smask = ipmcMsk; + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + return RT_ERR_OUT_OF_RANGE; + +} + +/* Function Name: + * rtk_svlan_ipmc2s_del + * Description: + * delete ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((ipmc&0xF0000000)!=0xE0000000) + return RT_ERR_INPUT; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && + svlanMC2SConf.sdata==ipmc&& + svlanMC2SConf.smask==ipmcMsk) + { + memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_ipmc2s_get + * Description: + * Get ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if ((ipmc&0xF0000000)!=0xE0000000) + return RT_ERR_INPUT; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid && + svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && + svlanMC2SConf.sdata == ipmc && + svlanMC2SConf.smask == ipmcMsk) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + *pSvid = svlanMemConf.vs_svid; + return RT_ERR_OK; + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_l2mc2s_add + * Description: + * Add L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set L2 Mutlicast to SVID configuration. If upstream packet is L2 multicast + * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 + * SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx; + rtk_uint32 svidx, l2add, l2Mask; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + if (mac.octet[0]!= 1&&mac.octet[1]!=0) + return RT_ERR_INPUT; + + l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; + l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + empty_idx = 0xFFFF; + + for (i = RTL8367C_MC2SIDXMAX; i >=0; i--) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && + svlanMC2SConf.sdata==l2add&& + svlanMC2SConf.smask==l2Mask) + { + svlanMC2SConf.svidx = svidx; + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + } + } + else + { + empty_idx = i; + } + } + + if (empty_idx!=0xFFFF) + { + svlanMC2SConf.valid = TRUE; + svlanMC2SConf.svidx = svidx; + svlanMC2SConf.format = SVLAN_MC2S_MODE_MAC; + svlanMC2SConf.sdata = l2add; + svlanMC2SConf.smask = l2Mask; + + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_l2mc2s_del + * Description: + * delete L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete Mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 l2add, l2Mask; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mac.octet[0]!= 1&&mac.octet[1]!=0) + return RT_ERR_INPUT; + + l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; + l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && + svlanMC2SConf.sdata==l2add&& + svlanMC2SConf.smask==l2Mask) + { + memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_l2mc2s_get + * Description: + * Get L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get L2 mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 l2add,l2Mask; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if (mac.octet[0]!= 1&&mac.octet[1]!=0) + return RT_ERR_INPUT; + + l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; + l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && + svlanMC2SConf.sdata==l2add&& + svlanMC2SConf.smask==l2Mask) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + *pSvid = svlanMemConf.vs_svid; + + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_sp2c_add + * Description: + * Add system SP2C configuration + * Input: + * cvid - VLAN ID + * dst_port - Destination port of SVLAN to CVLAN configuration + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned + * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. + * There are 128 SP2C configurations. + */ +rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + rtk_port_t port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + if (cvid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(dst_port); + port = rtk_switch_port_L2P_get(dst_port); + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + empty_idx = 0xFFFF; + + for (i=RTL8367C_SP2CMAX; i >=0 ; i--) + { + if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + + if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == port) && (svlanSP2CConf.valid == 1)) + { + empty_idx = i; + break; + } + else if (svlanSP2CConf.valid == 0) + { + empty_idx = i; + } + } + + if (empty_idx!=0xFFFF) + { + svlanSP2CConf.valid = 1; + svlanSP2CConf.vid = cvid; + svlanSP2CConf.svidx = svidx; + svlanSP2CConf.dstport = port; + + if ((retVal = rtl8367c_setAsicSvlanSP2CConf(empty_idx, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + return RT_ERR_OUT_OF_RANGE; + +} + +/* Function Name: + * rtk_svlan_sp2c_get + * Description: + * Get configure system SP2C content + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * pCvid - VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * Note: + * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCvid) + return RT_ERR_NULL_POINTER; + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(dst_port); + dst_port = rtk_switch_port_L2P_get(dst_port); + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + for (i = 0; i <= RTL8367C_SP2CMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + + if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) + { + *pCvid = svlanSP2CConf.vid; + return RT_ERR_OK; + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_sp2c_del + * Description: + * Delete system SP2C configuration + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(dst_port); + dst_port = rtk_switch_port_L2P_get(dst_port); + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + for (i = 0; i <= RTL8367C_SP2CMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + + if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) + { + svlanSP2CConf.valid = 0; + svlanSP2CConf.vid = 0; + svlanSP2CConf.svidx = 0; + svlanSP2CConf.dstport = 0; + + if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_lookupType_set + * Description: + * Set lookup type of SVLAN + * Input: + * type - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= SVLAN_LOOKUP_END) + return RT_ERR_CHIP_NOT_SUPPORTED; + + + svlan_lookupType = type; + + retVal = rtl8367c_setAsicSvlanLookupType((rtk_uint32)type); + + return retVal; +} + +/* Function Name: + * rtk_svlan_lookupType_get + * Description: + * Get lookup type of SVLAN + * Input: + * pType - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicSvlanLookupType(pType); + + svlan_lookupType = *pType; + + return retVal; +} + +/* Function Name: + * rtk_svlan_trapPri_set + * Description: + * Set svlan trap priority + * Input: + * priority - priority for trap packets + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_INT_PRIORITY + * Note: + * None + */ +rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority) +{ + rtk_api_ret_t retVal; + + RTK_CHK_INIT_STATE(); + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicSvlanTrapPriority(priority); + + return retVal; +} /* end of rtk_svlan_trapPri_set */ + +/* Function Name: + * rtk_svlan_trapPri_get + * Description: + * Get svlan trap priority + * Input: + * None + * Output: + * pPriority - priority for trap packets + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority) +{ + rtk_api_ret_t retVal; + + RTK_CHK_INIT_STATE(); + + if(NULL == pPriority) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority); + + return retVal; +} /* end of rtk_svlan_trapPri_get */ + + +/* Function Name: + * rtk_svlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + rtk_uint32 svidx; + rtk_uint32 empty_idx = 0xFFFF; + rtl8367c_svlan_memconf_t svlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + /* Search exist entry */ + for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) + { + if(svlan_mbrCfgUsage[svidx] == TRUE) + { + if(svlan_mbrCfgVid[svidx] == vid) + { + /* Found! return index */ + *pIndex = svidx; + return RT_ERR_OK; + } + } + else if(empty_idx == 0xFFFF) + { + empty_idx = svidx; + } + + } + + if(empty_idx == 0xFFFF) + { + /* No empty index */ + return RT_ERR_TBL_FULL; + } + + svlan_mbrCfgUsage[empty_idx] = TRUE; + svlan_mbrCfgVid[empty_idx] = vid; + + memset(&svlan_cfg, 0, sizeof(rtl8367c_svlan_memconf_t)); + + svlan_cfg.vs_svid = vid; + /*for create check*/ + if(vid == 0) + { + svlan_cfg.vs_efid = 1; + } + + if((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlan_cfg)) != RT_ERR_OK) + return retVal; + + *pIndex = empty_idx; + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trap.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trap.c new file mode 100755 index 00000000..af966105 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trap.c @@ -0,0 +1,1229 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Trap module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_set + * Description: + * Set unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * ucast_action - Unknown unicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (ucast_action >= UCAST_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), ucast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_get + * Description: + * Get unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * Output: + * pUcast_action - Unknown unicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * This API can get unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (NULL == pUcast_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), pUcast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMacPktAction_set + * Description: + * Set unknown source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (ucast_action >= UCAST_ACTION_FLOODING) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnknownSaBehavior(ucast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMacPktAction_get + * Description: + * Get unknown source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pUcast_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnknownSaBehavior(pUcast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacPktAction_set + * Description: + * Set unmatch source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (ucast_action >= UCAST_ACTION_FLOODING) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnmatchedSaBehavior(ucast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacPktAction_get + * Description: + * Get unmatch source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pUcast_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnmatchedSaBehavior(pUcast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacMoving_set + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +rtk_api_ret_t rtk_trap_unmatchMacMoving_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacMoving_get + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * Output: + * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +rtk_api_ret_t rtk_trap_unmatchMacMoving_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMcastPktAction_set + * Description: + * Set behavior of unknown multicast + * Input: + * port - Port id. + * type - unknown multicast packet type. + * mcast_action - unknown multicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action) +{ + rtk_api_ret_t retVal; + rtk_uint32 rawAction; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (type >= MCAST_END) + return RT_ERR_INPUT; + + if (mcast_action >= MCAST_ACTION_END) + return RT_ERR_INPUT; + + + switch (type) + { + case MCAST_L2: + if (MCAST_ACTION_ROUTER_PORT == mcast_action) + return RT_ERR_INPUT; + else if(MCAST_ACTION_DROP_EX_RMA == mcast_action) + rawAction = L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA; + else + rawAction = (rtk_uint32)mcast_action; + + if ((retVal = rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) + return retVal; + + break; + case MCAST_IPV4: + if (MCAST_ACTION_DROP_EX_RMA == mcast_action) + return RT_ERR_INPUT; + else + rawAction = (rtk_uint32)mcast_action; + + if ((retVal = rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) + return retVal; + + break; + case MCAST_IPV6: + if (MCAST_ACTION_DROP_EX_RMA == mcast_action) + return RT_ERR_INPUT; + else + rawAction = (rtk_uint32)mcast_action; + + if ((retVal = rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) + return retVal; + + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMcastPktAction_get + * Description: + * Get behavior of unknown multicast + * Input: + * type - unknown multicast packet type. + * Output: + * pMcast_action - unknown multicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid operation. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action) +{ + rtk_api_ret_t retVal; + rtk_uint32 rawAction; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (type >= MCAST_END) + return RT_ERR_INPUT; + + if(NULL == pMcast_action) + return RT_ERR_NULL_POINTER; + + switch (type) + { + case MCAST_L2: + if ((retVal = rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) + return retVal; + + if(L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA == rawAction) + *pMcast_action = MCAST_ACTION_DROP_EX_RMA; + else + *pMcast_action = (rtk_trap_mcast_action_t)rawAction; + + break; + case MCAST_IPV4: + if ((retVal = rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) + return retVal; + + *pMcast_action = (rtk_trap_mcast_action_t)rawAction; + break; + case MCAST_IPV6: + if ((retVal = rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) + return retVal; + + *pMcast_action = (rtk_trap_mcast_action_t)rawAction; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_lldpEnable_set + * Description: + * Set LLDP enable. + * Input: + * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + + */ +rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_enable_t tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRmaLldp(enabled, &rmacfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_lldpEnable_get + * Description: + * Get LLDP status. + * Input: + * None + * Output: + * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * LLDP is as following definition. + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + */ +rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicRmaLldp(pEnabled, &rmacfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_set + * Description: + * Set priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * priority - internal priority that is going to be set for specific trap reason. + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_REASON_END) + return RT_ERR_INPUT; + + if (priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + switch (type) + { + case TRAP_REASON_RMA: + if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) + return retVal; + rmacfg.trap_priority= priority; + if ((retVal = rtl8367c_setAsicRma(0, &rmacfg)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_OAM: + if ((retVal = rtl8367c_setAsicOamCpuPri(priority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_1XUNAUTH: + if ((retVal = rtl8367c_setAsic1xTrapPriority(priority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_VLANSTACK: + if ((retVal = rtl8367c_setAsicSvlanTrapPriority(priority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_UNKNOWNMC: + if ((retVal = rtl8367c_setAsicUnknownMulticastTrapPriority(priority)) != RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_CHIP_NOT_SUPPORTED; + } + + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_get + * Description: + * Get priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * Output: + * pPriority - configured internal priority for such reason. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_REASON_END) + return RT_ERR_INPUT; + + if(NULL == pPriority) + return RT_ERR_NULL_POINTER; + + switch (type) + { + case TRAP_REASON_RMA: + if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) + return retVal; + *pPriority = rmacfg.trap_priority; + + break; + case TRAP_REASON_OAM: + if ((retVal = rtl8367c_getAsicOamCpuPri(pPriority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_1XUNAUTH: + if ((retVal = rtl8367c_getAsic1xTrapPriority(pPriority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_VLANSTACK: + if ((retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_UNKNOWNMC: + if ((retVal = rtl8367c_getAsicUnknownMulticastTrapPriority(pPriority)) != RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_CHIP_NOT_SUPPORTED; + + } + + return RT_ERR_OK; +} + + + +/* Function Name: + * rtk_trap_rmaAction_set + * Description: + * Set Reserved multicast address action configuration. + * Input: + * type - rma type. + * rma_action - RMA action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if (rma_action >= RMA_ACTION_END) + return RT_ERR_RMA_ACTION; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_rmaAction_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pRma_action - RMA action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if(NULL == pRma_action) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_rmaKeepFormat_set + * Description: + * Set Reserved multicast address keep format configuration. + * Input: + * type - rma type. + * enable - enable keep format. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_rmaKeepFormat_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pEnable - keep format status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trunk.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trunk.c new file mode 100755 index 00000000..8a88dc5f --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/trunk.c @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Trunk module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_trunk_port_set + * Description: + * Set trunking group available port mask + * Input: + * trk_gid - trunk group id + * pTrunk_member_portmask - Logic trunking member port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking group port mask. Each port trunking group has max 4 ports. + * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. + */ +rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + rtk_uint32 regValue, type, tmp; + + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pTrunk_member_portmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pTrunk_member_portmask); + + if((retVal = rtk_switch_portmask_L2P_get(pTrunk_member_portmask, &pmsk)) != RT_ERR_OK) + return retVal; + + if((type == 0) || (type == 1)) + { + if ((pmsk | RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) != (rtk_uint32)RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) + return RT_ERR_PORT_MASK; + + pmsk = (pmsk & RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) >> RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); + } + else if(type == 2) + { + tmp = 0; + + if(pmsk & 0x2) + tmp |= 1; + if(pmsk & 0x8) + tmp |=2; + if(pmsk & 0x80) + tmp |=8; + + pmsk = tmp; + } + + if ((retVal = rtl8367c_setAsicTrunkingGroup(trk_gid, pmsk)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_port_get + * Description: + * Get trunking group available port mask + * Input: + * trk_gid - trunk group id + * Output: + * pTrunk_member_portmask - Logic trunking member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get 2 port trunking group. + */ +rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if ((retVal = rtl8367c_getAsicTrunkingGroup(trk_gid, &pmsk)) != RT_ERR_OK) + return retVal; + + pmsk = pmsk << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); + + if((retVal = rtk_switch_portmask_P2L_get(pmsk, pTrunk_member_portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_distributionAlgorithm_set + * Description: + * Set port trunking hash select sources + * Input: + * trk_gid - trunk group id + * algo_bitmask - Bitmask of the distribution algorithm + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_LA_HASHMASK - Hash algorithm selection error. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking hash algorithm sources. + * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} + * - 0b0000001: SPA + * - 0b0000010: SMAC + * - 0b0000100: DMAC + * - 0b0001000: SIP + * - 0b0010000: DIP + * - 0b0100000: TCP/UDP Source Port + * - 0b1000000: TCP/UDP Destination Port + * Example: + * - 0b0000011: SMAC & SPA + * - Note that it could be an arbitrary combination or independent set + */ +rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if (algo_bitmask >= 128) + return RT_ERR_LA_HASHMASK; + + if ((retVal = rtl8367c_setAsicTrunkingHashSelect(algo_bitmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_distributionAlgorithm_get + * Description: + * Get port trunking hash select sources + * Input: + * trk_gid - trunk group id + * Output: + * pAlgo_bitmask - Bitmask of the distribution algorithm + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get port trunking hash algorithm sources. + */ +rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if(NULL == pAlgo_bitmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingHashSelect((rtk_uint32 *)pAlgo_bitmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficSeparate_set + * Description: + * Set the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * separateType - traffic separation setting + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_LA_HASHMASK - invalid hash mask + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType) +{ + rtk_api_ret_t retVal; + rtk_uint32 enabled; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if(separateType >= SEPARATE_END) + return RT_ERR_INPUT; + + enabled = (separateType == SEPARATE_FLOOD) ? ENABLED : DISABLED; + if ((retVal = rtl8367c_setAsicTrunkingFlood(enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficSeparate_get + * Description: + * Get the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pSeparateType - pointer separated traffic type + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType) +{ + rtk_api_ret_t retVal; + rtk_uint32 enabled; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if(NULL == pSeparateType) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingFlood(&enabled)) != RT_ERR_OK) + return retVal; + + *pSeparateType = (enabled == ENABLED) ? SEPARATE_FLOOD : SEPARATE_NONE; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_mode_set + * Description: + * Set the trunk mode to the specified device. + * Input: + * mode - trunk mode + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(mode >= TRUNK_MODE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicTrunkingMode((rtk_uint32)mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_mode_get + * Description: + * Get the trunk mode from the specified device. + * Input: + * None + * Output: + * pMode - pointer buffer of trunk mode + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingMode((rtk_uint32 *)pMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficPause_set + * Description: + * Set the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * enable - traffic pause state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * Note: + * None. + */ +rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32)enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficPause_get + * Description: + * Get the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * Output: + * pEnable - pointer of traffic pause state. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_hashMappingTable_set + * Description: + * Set hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * pHash2Port_array - ports associate with the hash value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist + * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk + * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) +{ + rtk_api_ret_t retVal; + rtk_uint32 hashValue; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pHash2Port_array) + return RT_ERR_NULL_POINTER; + + if(trk_gid <= TRUNK_GROUP1) + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_setAsicTrunkingHashTable(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) + return retVal; + } + } + else + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_setAsicTrunkingHashTable1(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_hashMappingTable_get + * Description: + * Get hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pHash2Port_array - pointer buffer of ports associate with the hash value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) +{ + rtk_api_ret_t retVal; + rtk_uint32 hashValue; + rtk_uint32 hashPort; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pHash2Port_array) + return RT_ERR_NULL_POINTER; + + if(trk_gid <= TRUNK_GROUP1) + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_getAsicTrunkingHashTable(hashValue, &hashPort)) != RT_ERR_OK) + return retVal; + + pHash2Port_array->value[hashValue] = hashPort; + } + } + else + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_getAsicTrunkingHashTable1(hashValue, &hashPort)) != RT_ERR_OK) + return retVal; + + pHash2Port_array->value[hashValue] = hashPort; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_portQueueEmpty_get + * Description: + * Get the port mask which all queues are empty. + * Input: + * None. + * Output: + * pEmpty_portmask - pointer empty port mask + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEmpty_portmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicQeueuEmptyStatus(&pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pEmpty_portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/vlan.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/vlan.c new file mode 100755 index 00000000..f7480c49 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367c/vlan.c @@ -0,0 +1,2124 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in VLAN module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef enum vlan_mbrCfgType_e +{ + MBRCFG_UNUSED = 0, + MBRCFG_USED_BY_VLAN, + MBRCFG_END +}vlan_mbrCfgType_t; + +static rtk_vlan_t vlan_mbrCfgVid[RTL8367C_CVIDXNO]; +static vlan_mbrCfgType_t vlan_mbrCfgUsage[RTL8367C_CVIDXNO]; + +/* Function Name: + * rtk_vlan_init + * Description: + * Initialize VLAN. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * VLAN is disabled by default. User has to call this API to enable VLAN before + * using it. And It will set a default VLAN(vid 1) including all ports and set + * all ports PVID to the default VLAN. + */ +rtk_api_ret_t rtk_vlan_init(void) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Clean Database */ + memset(vlan_mbrCfgVid, 0x00, sizeof(rtk_vlan_t) * RTL8367C_CVIDXNO); + memset(vlan_mbrCfgUsage, 0x00, sizeof(vlan_mbrCfgType_t) * RTL8367C_CVIDXNO); + + /* clean 32 VLAN member configuration */ + for (i = 0; i <= RTL8367C_CVIDXMAX; i++) + { + vlanMC.evid = 0; + vlanMC.mbr = 0; + vlanMC.fid_msti = 0; + vlanMC.envlanpol = 0; + vlanMC.meteridx = 0; + vlanMC.vbpen = 0; + vlanMC.vbpri = 0; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(i, &vlanMC)) != RT_ERR_OK) + return retVal; + } + + /* Set a default VLAN with vid 1 to 4K table for all ports */ + memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); + vlan4K.vid = 1; + vlan4K.mbr = RTK_PHY_PORTMASK_ALL; + vlan4K.untag = RTK_PHY_PORTMASK_ALL; + vlan4K.fid_msti = 0; + if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + /* Also set the default VLAN to 32 member configuration index 0 */ + memset(&vlanMC, 0, sizeof(rtl8367c_vlanconfiguser)); + vlanMC.evid = 1; + vlanMC.mbr = RTK_PHY_PORTMASK_ALL; + vlanMC.fid_msti = 0; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(0, &vlanMC)) != RT_ERR_OK) + return retVal; + + /* Set all ports PVID to default VLAN and tag-mode to original */ + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((retVal = rtl8367c_setAsicVlanPortBasedVID(i, 0, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicVlanEgressTagMode(i, EG_TAG_MODE_ORI)) != RT_ERR_OK) + return retVal; + } + + /* Updata Databse */ + vlan_mbrCfgUsage[0] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[0] = 1; + + /* Enable Ingress filter */ + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((retVal = rtl8367c_setAsicVlanIngressFilter(i, ENABLED)) != RT_ERR_OK) + return retVal; + } + + /* enable VLAN */ + if ((retVal = rtl8367c_setAsicVlanFilter(ENABLED)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_set + * Description: + * Set a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * pVlanCfg - VLAN Configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_FID - Invalid FID. + * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtk_uint32 phyUntagPmask; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 idx; + rtk_uint32 empty_index = 0xffff; + rtk_uint32 update_evid = 0; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~8191 */ + if (vid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pVlanCfg) + return RT_ERR_NULL_POINTER; + + /* Check port mask valid */ + RTK_CHK_PORTMASK_VALID(&(pVlanCfg->mbr)); + + if (vid <= RTL8367C_VIDMAX) + { + /* Check untag port mask valid */ + RTK_CHK_PORTMASK_VALID(&(pVlanCfg->untag)); + } + + /* IVL_EN */ + if(pVlanCfg->ivl_en >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* fid must be 0~15 */ + if(pVlanCfg->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + /* Policing */ + if(pVlanCfg->envlanpol >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* Meter ID */ + if(pVlanCfg->meteridx > RTK_MAX_METER_ID) + return RT_ERR_INPUT; + + /* VLAN based priority */ + if(pVlanCfg->vbpen >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* Priority */ + if(pVlanCfg->vbpri > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + /* Get physical port mask */ + if(rtk_switch_portmask_L2P_get(&(pVlanCfg->mbr), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_L2P_get(&(pVlanCfg->untag), &phyUntagPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if (vid <= RTL8367C_VIDMAX) + { + /* update 4K table */ + memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); + vlan4K.vid = vid; + + vlan4K.mbr = (phyMbrPmask & 0xFFFF); + vlan4K.untag = (phyUntagPmask & 0xFFFF); + + vlan4K.ivl_svl = pVlanCfg->ivl_en; + vlan4K.fid_msti = pVlanCfg->fid_msti; + vlan4K.envlanpol = pVlanCfg->envlanpol; + vlan4K.meteridx = pVlanCfg->meteridx; + vlan4K.vbpen = pVlanCfg->vbpen; + vlan4K.vbpri = pVlanCfg->vbpri; + + if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + /* Update Member configuration if exist */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! Update */ + if(phyMbrPmask == 0x00) + { + /* Member port = 0x00, delete this VLAN from Member Configuration */ + memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + /* Clear Database */ + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + /* Normal VLAN config, update to member configuration */ + vlanMC.evid = vid; + vlanMC.mbr = vlan4K.mbr; + vlanMC.fid_msti = vlan4K.fid_msti; + vlanMC.meteridx = vlan4K.meteridx; + vlanMC.envlanpol= vlan4K.envlanpol; + vlanMC.vbpen = vlan4K.vbpen; + vlanMC.vbpri = vlan4K.vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + } + + break; + } + } + } + } + else + { + /* vid > 4095 */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! Update */ + if(phyMbrPmask == 0x00) + { + /* Member port = 0x00, delete this VLAN from Member Configuration */ + memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + /* Clear Database */ + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + /* Normal VLAN config, update to member configuration */ + vlanMC.evid = vid; + vlanMC.mbr = phyMbrPmask; + vlanMC.fid_msti = pVlanCfg->fid_msti; + vlanMC.meteridx = pVlanCfg->meteridx; + vlanMC.envlanpol= pVlanCfg->envlanpol; + vlanMC.vbpen = pVlanCfg->vbpen; + vlanMC.vbpri = pVlanCfg->vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + break; + } + + update_evid = 1; + } + } + + if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) + { + if(0xffff == empty_index) + empty_index = idx; + } + } + + /* doesn't find out same EVID entry and there is empty index in member configuration */ + if( (phyMbrPmask != 0x00) && (update_evid == 0) && (empty_index != 0xFFFF) ) + { + vlanMC.evid = vid; + vlanMC.mbr = phyMbrPmask; + vlanMC.fid_msti = pVlanCfg->fid_msti; + vlanMC.meteridx = pVlanCfg->meteridx; + vlanMC.envlanpol= pVlanCfg->envlanpol; + vlanMC.vbpen = pVlanCfg->vbpen; + vlanMC.vbpri = pVlanCfg->vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_index, &vlanMC)) != RT_ERR_OK) + return retVal; + + vlan_mbrCfgUsage[empty_index] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[empty_index] = vid; + + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_get + * Description: + * Get a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * Output: + * pVlanCfg - VLAN Configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtk_uint32 phyUntagPmask; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 idx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~8191 */ + if (vid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pVlanCfg) + return RT_ERR_NULL_POINTER; + + if (vid <= RTL8367C_VIDMAX) + { + vlan4K.vid = vid; + + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + phyMbrPmask = vlan4K.mbr; + phyUntagPmask = vlan4K.untag; + if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_P2L_get(phyUntagPmask, &(pVlanCfg->untag)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pVlanCfg->ivl_en = vlan4K.ivl_svl; + pVlanCfg->fid_msti = vlan4K.fid_msti; + pVlanCfg->envlanpol = vlan4K.envlanpol; + pVlanCfg->meteridx = vlan4K.meteridx; + pVlanCfg->vbpen = vlan4K.vbpen; + pVlanCfg->vbpri = vlan4K.vbpri; + } + else + { + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + phyMbrPmask = vlanMC.mbr; + if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pVlanCfg->untag.bits[0] = 0; + pVlanCfg->ivl_en = 0; + pVlanCfg->fid_msti = vlanMC.fid_msti; + pVlanCfg->envlanpol = vlanMC.envlanpol; + pVlanCfg->meteridx = vlanMC.meteridx; + pVlanCfg->vbpen = vlanMC.vbpen; + pVlanCfg->vbpri = vlanMC.vbpri; + } + } + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_egrFilterEnable_set + * Description: + * Set VLAN egress filter. + * Input: + * egrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(egrFilter >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* enable VLAN */ + if ((retVal = rtl8367c_setAsicVlanFilter((rtk_uint32)egrFilter)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_egrFilterEnable_get + * Description: + * Get VLAN egress filter. + * Input: + * pEgrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter) +{ + rtk_api_ret_t retVal; + rtk_uint32 state; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEgrFilter) + return RT_ERR_NULL_POINTER; + + /* enable VLAN */ + if ((retVal = rtl8367c_getAsicVlanFilter(&state)) != RT_ERR_OK) + return retVal; + + *pEgrFilter = (rtk_enable_t)state; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_mbrCfg_set + * Description: + * Set a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * pMbrcfg - VLAN member Configuration. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Set a VLAN Member Configuration entry by index. + */ +rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtl8367c_vlanconfiguser mbrCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error check */ + if(pMbrcfg == NULL) + return RT_ERR_NULL_POINTER; + + if(idx > RTL8367C_CVIDXMAX) + return RT_ERR_INPUT; + + if(pMbrcfg->evid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + if(pMbrcfg->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(pMbrcfg->envlanpol >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pMbrcfg->meteridx > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(pMbrcfg->vbpen >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pMbrcfg->vbpri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + /* Check port mask valid */ + RTK_CHK_PORTMASK_VALID(&(pMbrcfg->mbr)); + + mbrCfg.evid = pMbrcfg->evid; + mbrCfg.fid_msti = pMbrcfg->fid_msti; + mbrCfg.envlanpol = pMbrcfg->envlanpol; + mbrCfg.meteridx = pMbrcfg->meteridx; + mbrCfg.vbpen = pMbrcfg->vbpen; + mbrCfg.vbpri = pMbrcfg->vbpri; + + if(rtk_switch_portmask_L2P_get(&(pMbrcfg->mbr), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + mbrCfg.mbr = phyMbrPmask; + + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) + return retVal; + + /* Update Database */ + if( (mbrCfg.evid == 0) && (mbrCfg.mbr == 0) ) + { + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[idx] = mbrCfg.evid; + } + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_vlan_mbrCfg_get + * Description: + * Get a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * Output: + * pMbrcfg - VLAN member Configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Get a VLAN Member Configuration entry by index. + */ +rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtl8367c_vlanconfiguser mbrCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error check */ + if(pMbrcfg == NULL) + return RT_ERR_NULL_POINTER; + + if(idx > RTL8367C_CVIDXMAX) + return RT_ERR_INPUT; + + memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) + return retVal; + + pMbrcfg->evid = mbrCfg.evid; + pMbrcfg->fid_msti = mbrCfg.fid_msti; + pMbrcfg->envlanpol = mbrCfg.envlanpol; + pMbrcfg->meteridx = mbrCfg.meteridx; + pMbrcfg->vbpen = mbrCfg.vbpen; + pMbrcfg->vbpri = mbrCfg.vbpri; + + phyMbrPmask = mbrCfg.mbr; + if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pMbrcfg->mbr)) != RT_ERR_OK) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portPvid_set + * Description: + * Set port to specified VLAN ID(PVID). + * Input: + * port - Port id. + * pvid - Specified VLAN ID. + * priority - 802.1p priority for the PVID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API is used for Port-based VLAN. The untagged frame received from the + * port will be classified to the specified VLAN and assigned to the specified priority. + */ +rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) +{ + rtk_api_ret_t retVal; + rtk_uint32 index; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* vid must be 0~8191 */ + if (pvid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* priority must be 0~7 */ + if (priority > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if((retVal = rtk_vlan_checkAndCreateMbr(pvid, &index)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), index, priority)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portPvid_get + * Description: + * Get VLAN ID(PVID) on specified port. + * Input: + * port - Port id. + * Output: + * pPvid - Specified VLAN ID. + * pPriority - 802.1p priority for the PVID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the PVID and 802.1p priority for the PVID of Port-based VLAN. + */ +rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority) +{ + rtk_api_ret_t retVal; + rtk_uint32 index, pri; + rtl8367c_vlanconfiguser mbrCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPvid) + return RT_ERR_NULL_POINTER; + + if(NULL == pPriority) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), &index, &pri)) != RT_ERR_OK) + return retVal; + + memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_getAsicVlanMemberConfig(index, &mbrCfg)) != RT_ERR_OK) + return retVal; + + *pPvid = mbrCfg.evid; + *pPriority = pri; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_set + * Description: + * Set VLAN ingress for each port. + * Input: + * port - Port id. + * igr_filter - VLAN ingress function enable status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member + * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. + */ +rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (igr_filter >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), igr_filter)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_get + * Description: + * Get VLAN Ingress Filter + * Input: + * port - Port id. + * Output: + * pIgr_filter - VLAN ingress function enable status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter status. + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pIgr_filter) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), pIgr_filter)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portAcceptFrameType_set + * Description: + * Set VLAN accept_frame_type + * Input: + * port - Port id. + * accept_frame_type - accept frame type + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. + * Note: + * The API is used for checking 802.1Q tagged frames. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (accept_frame_type >= ACCEPT_FRAME_TYPE_END) + return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; + + if ((retVal = rtl8367c_setAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), (rtl8367c_accframetype)accept_frame_type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portAcceptFrameType_get + * Description: + * Get VLAN accept_frame_type + * Input: + * port - Port id. + * Output: + * pAccept_frame_type - accept frame type + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type) +{ + rtk_api_ret_t retVal; + rtl8367c_accframetype acc_frm_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pAccept_frame_type) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), &acc_frm_type)) != RT_ERR_OK) + return retVal; + + *pAccept_frame_type = (rtk_vlan_acceptFrameType_t)acc_frm_type; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_add + * Description: + * Add the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * pInfo - Protocol and port based VLAN configuration information. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_TBL_FULL - Table is full. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 exist, empty, used, index; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + rtl8367c_provlan_frametype tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pInfo) + return RT_ERR_NULL_POINTER; + + if (pInfo->proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_OUT_OF_RANGE; + + if (pInfo->frame_type >= FRAME_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + if (pInfo->cvid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if (pInfo->cpri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + exist = 0xFF; + empty = 0xFF; + for (i = RTL8367C_PROTOVLAN_GIDX_MAX; i >= 0; i--) + { + if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + tmp = pInfo->frame_type; + if (ppb_data_cfg.etherType == pInfo->proto_type && ppb_data_cfg.frameType == tmp) + { + /*Already exist*/ + exist = i; + break; + } + else if (ppb_data_cfg.etherType == 0 && ppb_data_cfg.frameType == 0) + { + /*find empty index*/ + empty = i; + } + } + + used = 0xFF; + /*No empty and exist index*/ + if (0xFF == exist && 0xFF == empty) + return RT_ERR_TBL_FULL; + else if (existframe_type; + ppb_data_cfg.etherType = pInfo->proto_type; + if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(empty, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + used = empty; + } + else + return RT_ERR_FAILED; + + if((retVal = rtk_vlan_checkAndCreateMbr(pInfo->cvid, &index)) != RT_ERR_OK) + return retVal; + + ppb_vlan_cfg.vlan_idx = index; + ppb_vlan_cfg.valid = TRUE; + ppb_vlan_cfg.priority = pInfo->cpri; + if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), used, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_get + * Description: + * Get the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * pInfo - Protocol and port based VLAN configuration information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 ppb_idx; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_OUT_OF_RANGE; + + if (frame_type >= FRAME_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + ppb_idx = 0; + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + + if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) + { + ppb_idx = i; + break; + } + else if (RTL8367C_PROTOVLAN_GIDX_MAX == i) + return RT_ERR_TBL_FULL; + } + + if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + if (FALSE == ppb_vlan_cfg.valid) + return RT_ERR_FAILED; + + pInfo->frame_type = frame_type; + pInfo->proto_type = proto_type; + pInfo->cvid = vlan_mbrCfgVid[ppb_vlan_cfg.vlan_idx]; + pInfo->cpri = ppb_vlan_cfg.priority; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_del + * Description: + * Delete the protocol-and-port-based vlan from the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, bUsed; + rtk_uint32 ppb_idx; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_OUT_OF_RANGE; + + if (frame_type >= FRAME_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + ppb_idx = 0; + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + + if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) + { + ppb_idx = i; + ppb_vlan_cfg.valid = FALSE; + ppb_vlan_cfg.vlan_idx = 0; + ppb_vlan_cfg.priority = 0; + if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + } + } + + bUsed = FALSE; + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i, ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + if (TRUE == ppb_vlan_cfg.valid) + { + bUsed = TRUE; + break; + } + } + + if (FALSE == bUsed) /*No Port use this PPB Index, Delete it*/ + { + ppb_data_cfg.etherType=0; + ppb_data_cfg.frameType=0; + if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(ppb_idx, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_delAll + * Description: + * Delete all protocol-and-port-based vlans from the specified port of device. + * Input: + * port - Port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * Delete all flow table protocol-and-port-based vlan entries. + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, j, bUsed[4]; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + ppb_vlan_cfg.valid = FALSE; + ppb_vlan_cfg.vlan_idx = 0; + ppb_vlan_cfg.priority = 0; + if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), i, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + } + + bUsed[0] = FALSE; + bUsed[1] = FALSE; + bUsed[2] = FALSE; + bUsed[3] = FALSE; + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + for (j = 0; j <= RTL8367C_PROTOVLAN_GIDX_MAX; j++) + { + if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i,j, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + if (TRUE == ppb_vlan_cfg.valid) + { + bUsed[j] = TRUE; + } + } + } + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + if (FALSE == bUsed[i]) /*No Port use this PPB Index, Delete it*/ + { + ppb_data_cfg.etherType=0; + ppb_data_cfg.frameType=0; + if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + } + } + + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_tagMode_set + * Description: + * Set CVLAN egress tag mode + * Input: + * port - Port id. + * tag_mode - The egress tag mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (tag_mode >= VLAN_TAG_MODE_END) + return RT_ERR_PORT_ID; + + if ((retVal = rtl8367c_setAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), tag_mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_tagMode_get + * Description: + * Get CVLAN egress tag mode + * Input: + * port - Port id. + * Output: + * pTag_mode - The egress tag mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode) +{ + rtk_api_ret_t retVal; + rtl8367c_egtagmode mode; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pTag_mode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), &mode)) != RT_ERR_OK) + return retVal; + + *pTag_mode = (rtk_vlan_tagMode_t)mode; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_transparent_set + * Description: + * Set VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pIgr_pmask); + + if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_transparent_get + * Description: + * Get VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) + return retVal; + + if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_keep_set + * Description: + * Set VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pIgr_pmask); + + if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_keep_get + * Description: + * Get VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) + return retVal; + + if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_stg_set + * Description: + * Set spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * stg - spanning tree group instance. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can set spanning tree group instance of the vlan to the specified device. + */ +rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg) +{ + rtk_api_ret_t retVal; + rtl8367c_user_vlan4kentry vlan4K; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* priority must be 0~15 */ + if (stg > RTL8367C_MSTIMAX) + return RT_ERR_MSTI; + + /* update 4K table */ + vlan4K.vid = vid; + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + vlan4K.fid_msti= stg; + if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_stg_get + * Description: + * Get spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * Output: + * pStg - spanning tree group instance. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can get spanning tree group instance of the vlan to the specified device. + */ +rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg) +{ + rtk_api_ret_t retVal; + rtl8367c_user_vlan4kentry vlan4K; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if(NULL == pStg) + return RT_ERR_NULL_POINTER; + + /* update 4K table */ + vlan4K.vid = vid; + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + *pStg = vlan4K.fid_msti; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portFid_set + * Description: + * Set port-based filtering database + * Input: + * port - Port id. + * enable - ebable port-based FID + * fid - Specified filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based filtering database. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable>=RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* fid must be 0~4095 */ + if (fid > RTK_FID_MAX) + return RT_ERR_L2_FID; + + if ((retVal = rtl8367c_setAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortBasedFid(rtk_switch_port_L2P_get(port), fid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portFid_get + * Description: + * Get port-based filtering database + * Input: + * port - Port id. + * Output: + * pEnable - ebable port-based FID + * pFid - Specified filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based filtering database status. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if(NULL == pFid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), pEnable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortBasedFid(rtk_switch_port_L2P_get(port), pFid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_set + * Description: + * Set Untag DSCP priority assign + * Input: + * enable - state of Untag DSCP priority assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicVlanUntagDscpPriorityEn((rtk_uint32)enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_get + * Description: + * Get Untag DSCP priority assign + * Input: + * None + * Output: + * pEnable - state of Untag DSCP priority assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 value; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanUntagDscpPriorityEn(&value)) != RT_ERR_OK) + return retVal; + + *pEnable = (rtk_enable_t)value; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stp_mstpState_set + * Description: + * Configure spanning tree state per each port. + * Input: + * port - Port id + * msti - Multiple spanning tree instance. + * stp_state - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * RT_ERR_MSTP_STATE - Invalid STP state. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (msti > RTK_MAX_NUM_OF_MSTI) + return RT_ERR_MSTI; + + if (stp_state >= STP_STATE_END) + return RT_ERR_MSTP_STATE; + + if ((retVal = rtl8367c_setAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, stp_state)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stp_mstpState_get + * Description: + * Get spanning tree state per each port. + * Input: + * port - Port id. + * msti - Multiple spanning tree instance. + * Output: + * pStp_state - Spanning tree state for msti + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (msti > RTK_MAX_NUM_OF_MSTI) + return RT_ERR_MSTI; + + if(NULL == pStp_state) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, pStp_state)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 idx; + rtk_uint32 empty_idx = 0xFFFF; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~8191 */ + if (vid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + /* Get 4K VLAN */ + if (vid <= RTL8367C_VIDMAX) + { + memset(&vlan4K, 0x00, sizeof(rtl8367c_user_vlan4kentry)); + vlan4K.vid = vid; + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + } + + /* Search exist entry */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! return index */ + *pIndex = idx; + return RT_ERR_OK; + } + } + } + + /* Not found, Read H/W Member Configuration table to update database */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + if( (vlanMC.evid == 0) && (vlanMC.mbr == 0x00)) + { + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[idx] = vlanMC.evid; + } + } + + /* Search exist entry again */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! return index */ + *pIndex = idx; + return RT_ERR_OK; + } + } + } + + /* try to look up an empty index */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) + { + empty_idx = idx; + break; + } + } + + if(empty_idx == 0xFFFF) + { + /* No empty index */ + return RT_ERR_TBL_FULL; + } + + if (vid > RTL8367C_VIDMAX) + { + /* > 4K, there is no 4K entry, create on member configuration directly */ + memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); + vlanMC.evid = vid; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) + return retVal; + } + else + { + /* Copy from 4K table */ + vlanMC.evid = vid; + vlanMC.mbr = vlan4K.mbr; + vlanMC.fid_msti = vlan4K.fid_msti; + vlanMC.meteridx= vlan4K.meteridx; + vlanMC.envlanpol= vlan4K.envlanpol; + vlanMC.vbpen = vlan4K.vbpen; + vlanMC.vbpri = vlan4K.vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) + return retVal; + } + + /* Update Database */ + vlan_mbrCfgUsage[empty_idx] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[empty_idx] = vid; + + *pIndex = empty_idx; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_reservedVidAction_set + * Description: + * Set Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * action_vid0 - Action for VID 0. + * action_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(action_vid0 >= RESVID_ACTION_END) + return RT_ERR_INPUT; + + if(action_vid4095 >= RESVID_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setReservedVidAction((rtk_uint32)action_vid0, (rtk_uint32)action_vid4095)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_reservedVidAction_get + * Description: + * Get Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * pAction_vid0 - Action for VID 0. + * pAction_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pAction_vid0 == NULL) + return RT_ERR_NULL_POINTER; + + if(pAction_vid4095 == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getReservedVidAction((rtk_uint32 *)pAction_vid0, (rtk_uint32 *)pAction_vid4095)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_set + * Description: + * Set Real keep 1p remarking feature + * Input: + * enabled - State of 1p remarking at real keep packet + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setRealKeepRemarkEn((rtk_uint32)enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_get + * Description: + * Get Real keep 1p remarking feature + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getRealKeepRemarkEn((rtk_uint32 *)pEnabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_reset + * Description: + * Reset VLAN + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reset(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_resetVlan()) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s.c new file mode 100755 index 00000000..6a55631d --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s.c @@ -0,0 +1,580 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +//include from rtl8367c dir +#include "./rtl8367c/include/rtk_switch.h" +#include "./rtl8367c/include/vlan.h" +#include "./rtl8367c/include/stat.h" +#include "./rtl8367c/include/port.h" + +#define RTL8367C_SW_CPU_PORT 6 + + //RTL8367C_PHY_PORT_NUM + ext0 + ext1 +#define RTL8367C_NUM_PORTS 7 +#define RTL8367C_NUM_VIDS 4096 + +struct rtl8367_priv { + struct switch_dev swdev; + bool global_vlan_enable; +}; + +struct rtl8367_mib_counter { + const char *name; +}; + +struct rtl8367_vlan_info { + unsigned short vid; + unsigned int untag; + unsigned int member; + unsigned char fid; +}; + +struct rtl8367_priv rtl8367_priv_data; + +unsigned int rtl8367c_port_id[RTL8367C_NUM_PORTS]={0,1,2,3,4,EXT_PORT1,EXT_PORT0}; + +void (*rtl8367_switch_reset_func)(void)=NULL; + +static struct rtl8367_mib_counter rtl8367c_mib_counters[] = { + {"ifInOctets"}, + {"dot3StatsFCSErrors"}, + {"dot3StatsSymbolErrors"}, + {"dot3InPauseFrames"}, + {"dot3ControlInUnknownOpcodes"}, + {"etherStatsFragments"}, + {"etherStatsJabbers"}, + {"ifInUcastPkts"}, + {"etherStatsDropEvents"}, + {"etherStatsOctets"}, + {"etherStatsUndersizePkts"}, + {"etherStatsOversizePkts"}, + {"etherStatsPkts64Octets"}, + {"etherStatsPkts65to127Octets"}, + {"etherStatsPkts128to255Octets"}, + {"etherStatsPkts256to511Octets"}, + {"etherStatsPkts512to1023Octets"}, + {"etherStatsPkts1024toMaxOctets"}, + {"etherStatsMcastPkts"}, + {"etherStatsBcastPkts"}, + {"ifOutOctets"}, + {"dot3StatsSingleCollisionFrames"}, + {"dot3StatsMultipleCollisionFrames"}, + {"dot3StatsDeferredTransmissions"}, + {"dot3StatsLateCollisions"}, + {"etherStatsCollisions"}, + {"dot3StatsExcessiveCollisions"}, + {"dot3OutPauseFrames"}, + {"dot1dBasePortDelayExceededDiscards"}, + {"dot1dTpPortInDiscards"}, + {"ifOutUcastPkts"}, + {"ifOutMulticastPkts"}, + {"ifOutBrocastPkts"}, + {"outOampduPkts"}, + {"inOampduPkts"}, + {"pktgenPkts"}, + {"inMldChecksumError"}, + {"inIgmpChecksumError"}, + {"inMldSpecificQuery"}, + {"inMldGeneralQuery"}, + {"inIgmpSpecificQuery"}, + {"inIgmpGeneralQuery"}, + {"inMldLeaves"}, + {"inIgmpLeaves"}, + {"inIgmpJoinsSuccess"}, + {"inIgmpJoinsFail"}, + {"inMldJoinsSuccess"}, + {"inMldJoinsFail"}, + {"inReportSuppressionDrop"}, + {"inLeaveSuppressionDrop"}, + {"outIgmpReports"}, + {"outIgmpLeaves"}, + {"outIgmpGeneralQuery"}, + {"outIgmpSpecificQuery"}, + {"outMldReports"}, + {"outMldLeaves"}, + {"outMldGeneralQuery"}, + {"outMldSpecificQuery"}, + {"inKnownMulticastPkts"}, + {"ifInMulticastPkts"}, + {"ifInBroadcastPkts"}, + {"ifOutDiscards"} +}; + +/*rtl8367c proprietary switch API wrapper */ +static inline unsigned int rtl8367c_sw_to_phy_port(int port) +{ + return rtl8367c_port_id[port]; +} + +static inline unsigned int rtl8367c_portmask_phy_to_sw(rtk_portmask_t phy_portmask) +{ + int i; + for (i = 0; i < RTL8367C_NUM_PORTS; i++) { + if(RTK_PORTMASK_IS_PORT_SET(phy_portmask,rtl8367c_sw_to_phy_port(i))) { + RTK_PORTMASK_PORT_CLEAR(phy_portmask,rtl8367c_sw_to_phy_port(i)); + RTK_PORTMASK_PORT_SET(phy_portmask,i); + } + + } + return (unsigned int)phy_portmask.bits[0]; +} + +static int rtl8367c_reset_mibs(void) +{ + return rtk_stat_global_reset(); +} + +static int rtl8367c_reset_port_mibs(int port) +{ + + return rtk_stat_port_reset(rtl8367c_sw_to_phy_port(port)); +} + +static int rtl8367c_get_mibs_num(void) +{ + return ARRAY_SIZE(rtl8367c_mib_counters); +} + +static const char *rtl8367c_get_mib_name(int idx) +{ + + return rtl8367c_mib_counters[idx].name; +} + +static int rtl8367c_get_port_mib_counter(int idx, int port, unsigned long long *counter) +{ + return rtk_stat_port_get(rtl8367c_sw_to_phy_port(port), idx, counter); +} + +static int rtl8367c_is_vlan_valid(unsigned int vlan) +{ + unsigned max = RTL8367C_NUM_VIDS; + + if (vlan == 0 || vlan >= max) + return 0; + + return 1; +} + +static int rtl8367c_get_vlan( unsigned short vid, struct rtl8367_vlan_info *vlan) +{ + rtk_vlan_cfg_t vlan_cfg; + + memset(vlan, '\0', sizeof(struct rtl8367_vlan_info)); + + if (vid >= RTL8367C_NUM_VIDS) + return -EINVAL; + + if(rtk_vlan_get(vid,&vlan_cfg)) + return -EINVAL; + + vlan->vid = vid; + vlan->member = rtl8367c_portmask_phy_to_sw(vlan_cfg.mbr); + vlan->untag = rtl8367c_portmask_phy_to_sw(vlan_cfg.untag); + vlan->fid = vlan_cfg.fid_msti; + + return 0; +} + +static int rtl8367c_set_vlan( unsigned short vid, u32 mbr, u32 untag, u8 fid) +{ + rtk_vlan_cfg_t vlan_cfg; + int i; + + memset(&vlan_cfg, 0x00, sizeof(rtk_vlan_cfg_t)); + + for (i = 0; i < RTL8367C_NUM_PORTS; i++) { + if (mbr & (1 << i)) { + RTK_PORTMASK_PORT_SET(vlan_cfg.mbr, rtl8367c_sw_to_phy_port(i)); + if(untag & (1 << i)) + RTK_PORTMASK_PORT_SET(vlan_cfg.untag, rtl8367c_sw_to_phy_port(i)); + } + } + vlan_cfg.fid_msti=fid; + vlan_cfg.ivl_en = 1; + return rtk_vlan_set(vid, &vlan_cfg); +} + + +static int rtl8367c_get_pvid( int port, int *pvid) +{ + u32 prio=0; + + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + return rtk_vlan_portPvid_get(rtl8367c_sw_to_phy_port(port),pvid,&prio); +} + + +static int rtl8367c_set_pvid( int port, int pvid) +{ + u32 prio=0; + + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + return rtk_vlan_portPvid_set(rtl8367c_sw_to_phy_port(port),pvid,prio); +} + +static int rtl8367c_get_port_link(int port, int *link, int *speed, int *duplex) +{ + + if(rtk_port_phyStatus_get(rtl8367c_sw_to_phy_port(port),(rtk_port_linkStatus_t *)link, + (rtk_port_speed_t *)speed,(rtk_port_duplex_t *)duplex)) + return -EINVAL; + + return 0; +} + +/*common rtl8367 swconfig entry API*/ + +static int +rtl8367_sw_set_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); + + priv->global_vlan_enable = val->value.i ; + + return 0; +} + +static int +rtl8367_sw_get_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); + + val->value.i = priv->global_vlan_enable; + + return 0; +} + +static int rtl8367_sw_reset_mibs(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + return rtl8367c_reset_mibs(); +} + + +static int rtl8367_sw_reset_port_mibs(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int port; + + port = val->port_vlan; + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + return rtl8367c_reset_port_mibs(port); +} + +static int rtl8367_sw_get_port_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int i, len = 0; + unsigned long long counter = 0; + static char mib_buf[4096]; + + if (val->port_vlan >= RTL8367C_NUM_PORTS) + return -EINVAL; + + len += snprintf(mib_buf + len, sizeof(mib_buf) - len, + "Port %d MIB counters\n", + val->port_vlan); + + for (i = 0; i port_vlan, + &counter)) + len += snprintf(mib_buf + len, sizeof(mib_buf) - len, + "%llu\n", counter); + else + len += snprintf(mib_buf + len, sizeof(mib_buf) - len, + "%s\n", "N/A"); + } + + val->value.s = mib_buf; + val->len = len; + return 0; +} + + +static int rtl8367_sw_get_vlan_info(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int i; + u32 len = 0; + struct rtl8367_vlan_info vlan; + static char vlan_buf[256]; + int err; + + if (!rtl8367c_is_vlan_valid(val->port_vlan)) + return -EINVAL; + + memset(vlan_buf, '\0', sizeof(vlan_buf)); + + err = rtl8367c_get_vlan(val->port_vlan, &vlan); + if (err) + return err; + + len += snprintf(vlan_buf + len, sizeof(vlan_buf) - len, + "VLAN %d: Ports: '", vlan.vid); + + for (i = 0; i value.s = vlan_buf; + val->len = len; + + return 0; +} + + +static int rtl8367_sw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct switch_port *port; + struct rtl8367_vlan_info vlan; + int i; + + if (!rtl8367c_is_vlan_valid(val->port_vlan)) + return -EINVAL; + + if(rtl8367c_get_vlan(val->port_vlan, &vlan)) + return -EINVAL; + + port = &val->value.ports[0]; + val->len = 0; + for (i = 0; i id = i; + port->flags = (vlan.untag & BIT(i)) ? + 0 : BIT(SWITCH_PORT_FLAG_TAGGED); + val->len++; + port++; + } + return 0; +} + + +static int rtl8367_sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct switch_port *port; + u32 member = 0; + u32 untag = 0; + u8 fid=0; + int err; + int i; + + if (!rtl8367c_is_vlan_valid(val->port_vlan)) + return -EINVAL; + + port = &val->value.ports[0]; + for (i = 0; i < val->len; i++, port++) { + int pvid = 0; + member |= BIT(port->id); + + if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) + untag |= BIT(port->id); + + /* + * To ensure that we have a valid MC entry for this VLAN, + * initialize the port VLAN ID here. + */ + err = rtl8367c_get_pvid(port->id, &pvid); + if (err < 0) + return err; + if (pvid == 0) { + err = rtl8367c_set_pvid(port->id, val->port_vlan); + if (err < 0) + return err; + } + } + + //pr_info("[%s] vid=%d , mem=%x,untag=%x,fid=%d \n",__func__,val->port_vlan,member,untag,fid); + + return rtl8367c_set_vlan(val->port_vlan, member, untag, fid); + +} + + +static int rtl8367_sw_get_port_pvid(struct switch_dev *dev, int port, int *val) +{ + return rtl8367c_get_pvid(port, val); +} + + +static int rtl8367_sw_set_port_pvid(struct switch_dev *dev, int port, int val) +{ + return rtl8367c_set_pvid(port, val); +} + + +static int rtl8367_sw_reset_switch(struct switch_dev *dev) +{ + if(rtl8367_switch_reset_func) + (*rtl8367_switch_reset_func)(); + else + printk("rest switch is not supported\n"); + + return 0; +} + +static int rtl8367_sw_get_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ + int speed; + + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + if(rtl8367c_get_port_link(port,(int *)&link->link,(int *)&speed,(int *)&link->duplex)) + return -EINVAL; + + if (!link->link) + return 0; + + switch (speed) { + case 0: + link->speed = SWITCH_PORT_SPEED_10; + break; + case 1: + link->speed = SWITCH_PORT_SPEED_100; + break; + case 2: + link->speed = SWITCH_PORT_SPEED_1000; + break; + default: + link->speed = SWITCH_PORT_SPEED_UNKNOWN; + break; + } + + return 0; +} + + +static struct switch_attr rtl8367_globals[] = { + { + .type = SWITCH_TYPE_INT, + .name = "enable_vlan", + .description = "Enable VLAN mode", + .set = rtl8367_sw_set_vlan_enable, + .get = rtl8367_sw_get_vlan_enable, + .max = 1, + }, { + .type = SWITCH_TYPE_NOVAL, + .name = "reset_mibs", + .description = "Reset all MIB counters", + .set = rtl8367_sw_reset_mibs, + } +}; + +static struct switch_attr rtl8367_port[] = { + { + .type = SWITCH_TYPE_NOVAL, + .name = "reset_mib", + .description = "Reset single port MIB counters", + .set = rtl8367_sw_reset_port_mibs, + }, { + .type = SWITCH_TYPE_STRING, + .name = "mib", + .description = "Get MIB counters for port", + //.max = 33, + .set = NULL, + .get = rtl8367_sw_get_port_mib, + }, +}; + +static struct switch_attr rtl8367_vlan[] = { + { + .type = SWITCH_TYPE_STRING, + .name = "info", + .description = "Get vlan information", + .max = 1, + .set = NULL, + .get = rtl8367_sw_get_vlan_info, + }, +}; + +static const struct switch_dev_ops rtl8367_sw_ops = { + .attr_global = { + .attr = rtl8367_globals, + .n_attr = ARRAY_SIZE(rtl8367_globals), + }, + .attr_port = { + .attr = rtl8367_port, + .n_attr = ARRAY_SIZE(rtl8367_port), + }, + .attr_vlan = { + .attr = rtl8367_vlan, + .n_attr = ARRAY_SIZE(rtl8367_vlan), + }, + + .get_vlan_ports = rtl8367_sw_get_vlan_ports, + .set_vlan_ports = rtl8367_sw_set_vlan_ports, + .get_port_pvid = rtl8367_sw_get_port_pvid, + .set_port_pvid = rtl8367_sw_set_port_pvid, + .reset_switch = rtl8367_sw_reset_switch, + .get_port_link = rtl8367_sw_get_port_link, +}; + +int rtl8367s_swconfig_init(void (*reset_func)(void)) +{ + struct rtl8367_priv *priv = &rtl8367_priv_data; + struct switch_dev *dev=&priv->swdev; + int err=0; + + rtl8367_switch_reset_func = reset_func ; + + memset(priv, 0, sizeof(struct rtl8367_priv)); + priv->global_vlan_enable =0; + + dev->name = "RTL8367C"; + dev->cpu_port = RTL8367C_SW_CPU_PORT; + dev->ports = RTL8367C_NUM_PORTS; + dev->vlans = RTL8367C_NUM_VIDS; + dev->ops = &rtl8367_sw_ops; + dev->alias = "RTL8367C"; + err = register_switch(dev, NULL); + + pr_info("[%s]\n",__func__); + + return err; +} diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_dbg.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_dbg.c new file mode 100755 index 00000000..039d73d8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_dbg.c @@ -0,0 +1,648 @@ +#include +#include +#include +#include +#include + +#include "./rtl8367c/include/rtk_switch.h" +#include "./rtl8367c/include/port.h" +#include "./rtl8367c/include/vlan.h" +#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" +#include "./rtl8367c/include/stat.h" +#include "./rtl8367c/include/l2.h" +#include "./rtl8367c/include/smi.h" +#include "./rtl8367c/include/mirror.h" +#include "./rtl8367c/include/igmp.h" +#include "./rtl8367c/include/leaky.h" + +static struct proc_dir_entry *proc_reg_dir; +static struct proc_dir_entry *proc_esw_cnt; +static struct proc_dir_entry *proc_vlan_cnt; +static struct proc_dir_entry *proc_mac_tbl; +static struct proc_dir_entry *proc_reg; +static struct proc_dir_entry *proc_phyreg; +static struct proc_dir_entry *proc_mirror; +static struct proc_dir_entry *proc_igmp; + +#define PROCREG_ESW_CNT "esw_cnt" +#define PROCREG_VLAN "vlan" +#define PROCREG_MAC_TBL "mac_tbl" +#define PROCREG_REG "reg" +#define PROCREG_PHYREG "phyreg" +#define PROCREG_MIRROR "mirror" +#define PROCREG_IGMP "igmp" +#define PROCREG_DIR "rtk_gsw" + +#define RTK_SW_VID_RANGE 16 + +static void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) +{ + rtk_port_t port; + rtk_stat_counter_t Cntr; + + for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + + for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + + printk("\n"); +} +static void rtk_hal_dump_mib(void) +{ + + printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", + "Port2", "Port3", "Port4", "Port16", "Port17"); + /* Get TX Unicast Pkts */ + printk("TX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfOutUcastPkts); + /* Get TX Multicast Pkts */ + printk("TX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfOutMulticastPkts); + /* Get TX BroadCast Pkts */ + printk("TX BroadCast Pkts:"); + rtk_dump_mib_type(STAT_IfOutBroadcastPkts); + /* Get TX Collisions */ + /* Get TX Puase Frames */ + printk("TX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3OutPauseFrames); + /* Get TX Drop Events */ + /* Get RX Unicast Pkts */ + printk("RX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfInUcastPkts); + /* Get RX Multicast Pkts */ + printk("RX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfInMulticastPkts); + /* Get RX Broadcast Pkts */ + printk("RX Broadcast Pkts:"); + rtk_dump_mib_type(STAT_IfInBroadcastPkts); + /* Get RX FCS Erros */ + printk("RX FCS Errors :"); + rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); + /* Get RX Undersize Pkts */ + printk("RX Undersize Pkts:"); + rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); + /* Get RX Discard Pkts */ + printk("RX Discard Pkts :"); + rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); + /* Get RX Fragments */ + printk("RX Fragments :"); + rtk_dump_mib_type(STAT_EtherStatsFragments); + /* Get RX Oversize Pkts */ + printk("RX Oversize Pkts :"); + rtk_dump_mib_type(STAT_EtherOversizeStats); + /* Get RX Jabbers */ + printk("RX Jabbers :"); + rtk_dump_mib_type(STAT_EtherStatsJabbers); + /* Get RX Pause Frames */ + printk("RX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3InPauseFrames); + /* clear MIB */ + rtk_stat_global_reset(); + +} + +static int rtk_hal_dump_vlan(void) +{ + rtk_vlan_cfg_t vlan; + int i; + + printk("vid portmap\n"); + for (i = 0; i < RTK_SW_VID_RANGE; i++) { + rtk_vlan_get(i, &vlan); + printk("%3d ", i); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT1) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT2) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT3) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT4) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT1) ? '1' : '-'); + printk("\n"); + } + + return 0; +} + +static void rtk_hal_dump_table(void) +{ + rtk_uint32 i; + rtk_uint32 address = 0; + rtk_l2_ucastAddr_t l2_data; + rtk_l2_ipMcastAddr_t ipMcastAddr; + rtk_l2_age_time_t age_timout; + + rtk_l2_aging_get(&age_timout); + printk("Mac table age timeout =%d\n",(unsigned int)age_timout); + + printk("hash port(0:17) fid vid mac-address\n"); + while (1) { + if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { + break; + } else { + printk("%03x ", l2_data.address); + for (i = 0; i < 5; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + for (i = 16; i < 18; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + + printk(" %2d", l2_data.fid); + printk(" %4d", l2_data.cvid); + printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], + l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], + l2_data.mac.octet[4], l2_data.mac.octet[5]); + address ++; + } + } + + address = 0; + while (1) { + if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { + break; + } else { + printk("%03x ", ipMcastAddr.address); + for (i = 0; i < 5; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + for (i = 16; i < 18; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + printk(" "); + printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); + address ++; + } + } +} + +static void rtk_hal_clear_table(void) +{ + rtk_api_ret_t ret; + + ret = rtk_l2_table_clear(); + if (ret != RT_ERR_OK) + printk("rtk_l2_table_clear failed\n"); +} + +static void rtk_hal_read_reg(unsigned int reg_addr) +{ + ret_t retVal; + unsigned int reg_val; + + retVal = smi_read(reg_addr, ®_val); + + if(retVal != RT_ERR_OK) + printk("switch reg read failed\n"); + else + printk("reg0x%x = 0x%x\n", reg_addr, reg_val); +} + +static void rtk_hal_write_reg(unsigned int reg_addr , unsigned int reg_val) +{ + ret_t retVal; + + retVal = smi_write(reg_addr, reg_val); + + if(retVal != RT_ERR_OK) + printk("switch reg write failed\n"); + else + printk("write switch reg0x%x 0x%x success\n", reg_addr, reg_val); +} + +static void rtk_hal_get_phy_reg(unsigned int port ,unsigned int reg_addr ) +{ + ret_t retVal; + rtk_port_phy_data_t Data; + + retVal = rtk_port_phyReg_get(port, reg_addr, &Data); + if (retVal == RT_ERR_OK) + printk("Get: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, Data); + else + printk("read phy reg failed\n"); +} + +static void rtk_hal_set_phy_reg(unsigned int port ,unsigned int reg_addr,unsigned int reg_val) +{ + ret_t retVal; + + retVal = rtk_port_phyReg_set(port, reg_addr, reg_val); + if (retVal == RT_ERR_OK) + printk("Set: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, reg_val); + else + printk("write phy reg failed\n"); +} + +static void rtk_hal_set_port_mirror(unsigned int port ,unsigned int rx_port_map,unsigned int tx_port_map) +{ + rtk_portmask_t rx_portmask; + rtk_portmask_t tx_portmask; + rtk_api_ret_t ret; + int i; + + rtk_mirror_portIso_set(ENABLED); + RTK_PORTMASK_CLEAR(rx_portmask); + RTK_PORTMASK_CLEAR(tx_portmask); + + for (i = 0; i < 5; i++) + if (rx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(rx_portmask, i); + + for (i = 0; i < 2; i++) + if (rx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); + + RTK_PORTMASK_CLEAR(tx_portmask); + + for (i = 0; i < 5; i++) + if (tx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(tx_portmask, i); + + for (i = 0; i < 2; i++) + if (tx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); + + ret = rtk_mirror_portBased_set(port, &rx_portmask, &tx_portmask); + + if (!ret) + printk("rtk_mirror_portBased_set success\n"); + +} + +static void rtk_hal_enable_igmpsnoop(int hw_on) +{ + rtk_api_ret_t ret; + rtk_portmask_t pmask; + + ret = rtk_igmp_init(); + if (hw_on == 1) { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + ret |= rtk_igmp_static_router_port_set(&pmask); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); + ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); + /* drop unknown multicast packets*/ + /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ + } else { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_igmp_static_router_port_set(&pmask); + } + + if(ret != RT_ERR_OK) + printk("enable switch igmpsnoop failed\n"); + +} + +static void rtk_hal_disable_igmpsnoop(void) +{ + if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) + printk("Disable IGMP SNOOPING failed\n"); +} + +static ssize_t mac_tbl_write(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + rtk_hal_clear_table(); + + return count; +} + + +static ssize_t phyreg_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[64]; + unsigned int port; + unsigned int offset; + unsigned int val; + + memset(buf, 0, 64); + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + + if(buf[0] == 'w') { + + if(sscanf(buf, "w %d %x %x", &port,&offset,&val) == -1) + return -EFAULT; + else + rtk_hal_set_phy_reg(port,offset,val); + + } else { + + if(sscanf(buf, "r %d %x",&port, &offset) == -1) + return -EFAULT; + else + rtk_hal_get_phy_reg(port,offset); + } + + return count; +} + +static ssize_t reg_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[64]; + unsigned int offset; + unsigned int val; + + memset(buf, 0, 64); + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + + if(buf[0] == 'w') { + + if(sscanf(buf, "w %x %x", &offset,&val) == -1) + return -EFAULT; + else + rtk_hal_write_reg(offset,val); + + } else { + + if(sscanf(buf, "r %x", &offset) == -1) + return -EFAULT; + else + rtk_hal_read_reg(offset); + } + + return count; +} + +static ssize_t mirror_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[64]; + unsigned int port; + unsigned int tx_map,rx_map; + + memset(buf, 0, 64); + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if(sscanf(buf, "%d %x %x", &port,&rx_map,&tx_map) == -1) + return -EFAULT; + else + rtk_hal_set_port_mirror(port,rx_map,tx_map); + + return count; +} + + +static ssize_t igmp_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[8]; + unsigned int ops; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if(sscanf(buf, "%d", &ops) == -1) + return -EFAULT; + + if(ops == 0) + rtk_hal_disable_igmpsnoop(); + else if (ops == 1) + rtk_hal_enable_igmpsnoop(0); + else //hw igmp + rtk_hal_enable_igmpsnoop(1); + + return count; +} + + +static int esw_cnt_read(struct seq_file *seq, void *v) +{ + rtk_hal_dump_mib(); + return 0; +} + +static int vlan_read(struct seq_file *seq, void *v) +{ + rtk_hal_dump_vlan(); + return 0; +} + +static int mac_tbl_read(struct seq_file *seq, void *v) +{ + rtk_hal_dump_table(); + return 0; +} + +static int reg_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int phyreg_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int mirror_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int igmp_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int switch_count_open(struct inode *inode, struct file *file) +{ + return single_open(file, esw_cnt_read, 0); +} + +static int switch_vlan_open(struct inode *inode, struct file *file) +{ + return single_open(file, vlan_read, 0); +} + +static int mac_tbl_open(struct inode *inode, struct file *file) +{ + return single_open(file, mac_tbl_read, 0); +} + +static int reg_open(struct inode *inode, struct file *file) +{ + return single_open(file, reg_show, 0); +} + +static int phyreg_open(struct inode *inode, struct file *file) +{ + return single_open(file, phyreg_show, 0); +} + +static int mirror_open(struct inode *inode, struct file *file) +{ + return single_open(file, mirror_show, 0); +} + +static int igmp_open(struct inode *inode, struct file *file) +{ + return single_open(file, igmp_show, 0); +} + + +static const struct proc_ops switch_count_fops = { + .proc_open = switch_count_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release +}; + +static const struct proc_ops switch_vlan_fops = { + .proc_open = switch_vlan_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release +}; + +static const struct proc_ops mac_tbl_fops = { + .proc_open = mac_tbl_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_write = mac_tbl_write, + .proc_release = single_release +}; + +static const struct proc_ops reg_fops = { + .proc_open = reg_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_write = reg_ops, + .proc_release = single_release +}; + +static const struct proc_ops phyreg_fops = { + .proc_open = phyreg_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_write = phyreg_ops, + .proc_release = single_release +}; + +static const struct proc_ops mirror_fops = { + .proc_open = mirror_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_write = mirror_ops, + .proc_release = single_release +}; + +static const struct proc_ops igmp_fops = { + .proc_open = igmp_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_write = igmp_ops, + .proc_release = single_release +}; + +int gsw_debug_proc_init(void) +{ + + if (!proc_reg_dir) + proc_reg_dir = proc_mkdir(PROCREG_DIR, NULL); + + proc_esw_cnt = + proc_create(PROCREG_ESW_CNT, 0, proc_reg_dir, &switch_count_fops); + + if (!proc_esw_cnt) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT); + + proc_vlan_cnt = + proc_create(PROCREG_VLAN, 0, proc_reg_dir, &switch_vlan_fops); + + if (!proc_vlan_cnt) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_VLAN); + + proc_mac_tbl = + proc_create(PROCREG_MAC_TBL, 0, proc_reg_dir, &mac_tbl_fops); + + if (!proc_mac_tbl) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MAC_TBL); + + proc_reg = + proc_create(PROCREG_REG, 0, proc_reg_dir, ®_fops); + + if (!proc_reg) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_REG); + + proc_phyreg = + proc_create(PROCREG_PHYREG, 0, proc_reg_dir, &phyreg_fops); + + if (!proc_phyreg) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_PHYREG); + + proc_mirror = + proc_create(PROCREG_MIRROR, 0, proc_reg_dir, &mirror_fops); + + if (!proc_mirror) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MIRROR); + + proc_igmp = + proc_create(PROCREG_IGMP, 0, proc_reg_dir, &igmp_fops); + + if (!proc_igmp) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_IGMP); + + return 0; +} + +void gsw_debug_proc_exit(void) +{ + if (proc_esw_cnt) + remove_proc_entry(PROCREG_ESW_CNT, proc_reg_dir); +} + + diff --git a/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_mdio.c b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_mdio.c new file mode 100755 index 00000000..ae958e89 --- /dev/null +++ b/root/target/linux/mediatek/files-5.14/drivers/net/phy/rtk/rtl8367s_mdio.c @@ -0,0 +1,312 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "./rtl8367c/include/rtk_switch.h" +#include "./rtl8367c/include/port.h" +#include "./rtl8367c/include/vlan.h" +#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" + +struct rtk_gsw { + struct device *dev; + struct mii_bus *bus; + int reset_pin; +}; + +static struct rtk_gsw *_gsw; + +extern int gsw_debug_proc_init(void); +extern void gsw_debug_proc_exit(void); + +#ifdef CONFIG_SWCONFIG +extern int rtl8367s_swconfig_init( void (*reset_func)(void) ); +#endif + +/*mii_mgr_read/mii_mgr_write is the callback API for rtl8367 driver*/ +unsigned int mii_mgr_read(unsigned int phy_addr,unsigned int phy_register,unsigned int *read_data) +{ + struct mii_bus *bus = _gsw->bus; + + mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); + + *read_data = bus->read(bus, phy_addr, phy_register); + + mutex_unlock(&bus->mdio_lock); + + return 0; +} + +unsigned int mii_mgr_write(unsigned int phy_addr,unsigned int phy_register,unsigned int write_data) +{ + struct mii_bus *bus = _gsw->bus; + + mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); + + bus->write(bus, phy_addr, phy_register, write_data); + + mutex_unlock(&bus->mdio_lock); + + return 0; +} + +static int rtl8367s_hw_reset(void) +{ + struct rtk_gsw *gsw = _gsw; + int ret; + + if (gsw->reset_pin < 0) + return 0; + + ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mediatek,reset-pin"); + + if (ret) + printk("fail to devm_gpio_request\n"); + + gpio_direction_output(gsw->reset_pin, 0); + + usleep_range(1000, 1100); + + gpio_set_value(gsw->reset_pin, 1); + + mdelay(500); + + devm_gpio_free(gsw->dev, gsw->reset_pin); + + return 0; + +} + +static int rtl8367s_vlan_config(int want_at_p0) +{ + rtk_vlan_cfg_t vlan1, vlan2; + + /* Set LAN/WAN VLAN partition */ + memset(&vlan1, 0x00, sizeof(rtk_vlan_cfg_t)); + + RTK_PORTMASK_PORT_SET(vlan1.mbr, EXT_PORT0); + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT1); + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT2); + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT3); + RTK_PORTMASK_PORT_SET(vlan1.untag, EXT_PORT0); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT1); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT2); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT3); + + if (want_at_p0) { + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT4); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT4); + } else { + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT0); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT0); + } + + vlan1.ivl_en = 1; + + rtk_vlan_set(1, &vlan1); + + memset(&vlan2, 0x00, sizeof(rtk_vlan_cfg_t)); + + RTK_PORTMASK_PORT_SET(vlan2.mbr, EXT_PORT1); + RTK_PORTMASK_PORT_SET(vlan2.untag, EXT_PORT1); + + if (want_at_p0) { + RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT0); + RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT0); + } else { + RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT4); + RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT4); + } + + vlan2.ivl_en = 1; + rtk_vlan_set(2, &vlan2); + + rtk_vlan_portPvid_set(EXT_PORT0, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT1, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT2, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT3, 1, 0); + rtk_vlan_portPvid_set(EXT_PORT1, 2, 0); + + if (want_at_p0) { + rtk_vlan_portPvid_set(UTP_PORT0, 2, 0); + rtk_vlan_portPvid_set(UTP_PORT4, 1, 0); + } else { + rtk_vlan_portPvid_set(UTP_PORT0, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT4, 2, 0); + } + + return 0; +} + +static int rtl8367s_hw_init(void) +{ + + rtl8367s_hw_reset(); + + if(rtk_switch_init()) + return -1; + + mdelay(500); + + if (rtk_vlan_reset()) + return -1; + + if (rtk_vlan_init()) + return -1; + + return 0; +} + +static void set_rtl8367s_sgmii(void) +{ + rtk_port_mac_ability_t mac_cfg; + rtk_mode_ext_t mode; + + mode = MODE_EXT_HSGMII; + mac_cfg.forcemode = MAC_FORCE; + mac_cfg.speed = PORT_SPEED_2500M; + mac_cfg.duplex = PORT_FULL_DUPLEX; + mac_cfg.link = PORT_LINKUP; + mac_cfg.nway = DISABLED; + mac_cfg.txpause = ENABLED; + mac_cfg.rxpause = ENABLED; + rtk_port_macForceLinkExt_set(EXT_PORT0, mode, &mac_cfg); + rtk_port_sgmiiNway_set(EXT_PORT0, DISABLED); + rtk_port_phyEnableAll_set(ENABLED); + +} + +static void set_rtl8367s_rgmii(void) +{ + rtk_port_mac_ability_t mac_cfg; + rtk_mode_ext_t mode; + + mode = MODE_EXT_RGMII; + mac_cfg.forcemode = MAC_FORCE; + mac_cfg.speed = PORT_SPEED_1000M; + mac_cfg.duplex = PORT_FULL_DUPLEX; + mac_cfg.link = PORT_LINKUP; + mac_cfg.nway = DISABLED; + mac_cfg.txpause = ENABLED; + mac_cfg.rxpause = ENABLED; + rtk_port_macForceLinkExt_set(EXT_PORT1, mode, &mac_cfg); + rtk_port_rgmiiDelayExt_set(EXT_PORT1, 1, 3); + rtk_port_phyEnableAll_set(ENABLED); + +} + +void init_gsw(void) +{ + rtl8367s_hw_init(); + set_rtl8367s_sgmii(); + set_rtl8367s_rgmii(); +} + +// bleow are platform driver +static const struct of_device_id rtk_gsw_match[] = { + { .compatible = "mediatek,rtk-gsw" }, + {}, +}; + +MODULE_DEVICE_TABLE(of, rtk_gsw_match); + +static int rtk_gsw_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device_node *mdio; + struct mii_bus *mdio_bus; + struct rtk_gsw *gsw; + const char *pm; + + mdio = of_parse_phandle(np, "mediatek,mdio", 0); + + if (!mdio) + return -EINVAL; + + mdio_bus = of_mdio_find_bus(mdio); + + if (!mdio_bus) + return -EPROBE_DEFER; + + gsw = devm_kzalloc(&pdev->dev, sizeof(struct rtk_gsw), GFP_KERNEL); + + if (!gsw) + return -ENOMEM; + + gsw->dev = &pdev->dev; + + gsw->bus = mdio_bus; + + gsw->reset_pin = of_get_named_gpio(np, "mediatek,reset-pin", 0); + + _gsw = gsw; + + init_gsw(); + + //init default vlan or init swocnfig + if(!of_property_read_string(pdev->dev.of_node, + "mediatek,port_map", &pm)) { + + if (!strcasecmp(pm, "wllll")) + rtl8367s_vlan_config(1); + else + rtl8367s_vlan_config(0); + + } else { +#ifdef CONFIG_SWCONFIG + rtl8367s_swconfig_init(&init_gsw); +#else + rtl8367s_vlan_config(0); +#endif + } + + gsw_debug_proc_init(); + + platform_set_drvdata(pdev, gsw); + + return 0; + +} + +static int rtk_gsw_remove(struct platform_device *pdev) +{ + platform_set_drvdata(pdev, NULL); + gsw_debug_proc_exit(); + + return 0; +} + +static struct platform_driver gsw_driver = { + .probe = rtk_gsw_probe, + .remove = rtk_gsw_remove, + .driver = { + .name = "rtk-gsw", + .owner = THIS_MODULE, + .of_match_table = rtk_gsw_match, + }, +}; + +module_platform_driver(gsw_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mark Lee "); +MODULE_DESCRIPTION("rtl8367c switch driver for MT7622"); + diff --git a/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts new file mode 100755 index 00000000..2b9bf8dd --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Ryder Lee + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "Bananapi BPI-R64"; + compatible = "bananapi,bpi-r64", "mediatek,mt7622"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 102 GPIO_ACTIVE_HIGH>; + }; + }; + + leds { + compatible = "gpio-leds"; + + green { + label = "bpi-r64:pio:green"; + gpios = <&pio 89 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + red { + label = "bpi-r64:pio:red"; + gpios = <&pio 88 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + memory { + reg = <0 0x40000000 0 0x40000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&bch { + status = "disabled"; +}; + +&btif { + status = "okay"; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&irrx_pins>; + status = "okay"; +}; + +ð { + status = "okay"; + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "rgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7531"; + reg = <0>; + reset-gpios = <&pio 54 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "wan"; + }; + + port@1 { + reg = <1>; + label = "lan0"; + }; + + port@2 { + reg = <2>; + label = "lan1"; + }; + + port@3 { + reg = <3>; + label = "lan2"; + }; + + port@4 { + reg = <4>; + label = "lan3"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; + + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&emmc_pins_default>; + pinctrl-1 = <&emmc_pins_uhs>; + status = "okay"; + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; + non-removable; +}; + +&mmc1 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&sd0_pins_default>; + pinctrl-1 = <&sd0_pins_uhs>; + status = "okay"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + r_smpl = <1>; + cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; +}; + +&nandc { + pinctrl-names = "default"; + pinctrl-0 = <¶llel_nand_pins>; + status = "disabled"; +}; + +&nor_flash { + pinctrl-names = "default"; + pinctrl-0 = <&spi_nor_pins>; + status = "disabled"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_pins>; + status = "okay"; +}; + +&pio { + /* Attention: GPIO 90 is used to switch between PCIe@1,0 and + * SATA functions. i.e. output-high: PCIe, output-low: SATA + */ + asm_sel { + gpio-hog; + gpios = <90 GPIO_ACTIVE_HIGH>; + output-high; + }; + + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { + function = "emmc", "emmc_rst"; + groups = "emmc"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", + * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, + * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively + */ + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + bias-pull-down; + }; + }; + + emmc_pins_uhs: emmc-pins-uhs { + mux { + function = "emmc"; + groups = "emmc"; + }; + + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + drive-strength = <4>; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + drive-strength = <4>; + bias-pull-down; + }; + }; + + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + i2c1_pins: i2c1-pins { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + + i2c2_pins: i2c2-pins { + mux { + function = "i2c"; + groups = "i2c2_0"; + }; + }; + + i2s1_pins: i2s1-pins { + mux { + function = "i2s"; + groups = "i2s_out_mclk_bclk_ws", + "i2s1_in_data", + "i2s1_out_data"; + }; + + conf { + pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", + "I2S_WS", "I2S_MCLK"; + drive-strength = <12>; + bias-pull-down; + }; + }; + + irrx_pins: irrx-pins { + mux { + function = "ir"; + groups = "ir_1_rx"; + }; + }; + + irtx_pins: irtx-pins { + mux { + function = "ir"; + groups = "ir_1_tx"; + }; + }; + + /* Parallel nand is shared pin with eMMC */ + parallel_nand_pins: parallel-nand-pins { + mux { + function = "flash"; + groups = "par_nand"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm_pins: pwm-pins { + mux { + function = "pwm"; + groups = "pwm_ch1_0", /* mt7622_pwm_ch1_0_pins[] = { 51, }; */ + "pwm_ch2_0", /* mt7622_pwm_ch2_0_pins[] = { 52, }; */ + "pwm_ch3_2", /* mt7622_pwm_ch3_2_pins[] = { 97, }; */ + "pwm_ch4_1", /* mt7622_pwm_ch4_1_pins[] = { 67, }; */ + "pwm_ch5_0", /* mt7622_pwm_ch5_0_pins[] = { 68, }; */ + "pwm_ch6_0"; /* mt7622_pwm_ch6_0_pins[] = { 69, }; */ + }; + }; + + wled_pins: wled-pins { + mux { + function = "led"; + groups = "wled"; + }; + }; + + sd0_pins_default: sd0-pins-default { + mux { + function = "sd"; + groups = "sd_0"; + }; + + /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", + * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, + * DAT2, DAT3, CMD, CLK for SD respectively. + */ + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + drive-strength = <8>; + bias-pull-up; + }; + conf-clk { + pins = "I2S3_OUT"; + drive-strength = <12>; + bias-pull-down; + }; + conf-cd { + pins = "TXD3"; + bias-pull-up; + }; + }; + + sd0_pins_uhs: sd0-pins-uhs { + mux { + function = "sd"; + groups = "sd_0"; + }; + + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "I2S3_OUT"; + bias-pull-down; + }; + }; + + /* Serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + spic0_pins: spic0-pins { + mux { + function = "spi"; + groups = "spic0_0"; + }; + }; + + spic1_pins: spic1-pins { + mux { + function = "spi"; + groups = "spic1_0"; + }; + }; + + /* SPI-NOR is shared pin with serial NAND */ + spi_nor_pins: spi-nor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + /* serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + uart2_pins: uart2-pins { + mux { + function = "uart"; + groups = "uart2_1_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + + status = "okay"; +}; + +&sata { + status = "disable"; +}; + +&sata_phy { + status = "disable"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spic1_pins>; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_5v>; + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + status = "okay"; +}; diff --git a/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts new file mode 100755 index 00000000..596c073d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "MediaTek MT7622 RFB1 board"; + compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + poll-interval = <100>; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 0 0>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 102 0>; + }; + }; + + memory { + reg = <0 0x40000000 0 0x20000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&bch { + status = "disabled"; +}; + +&btif { + status = "okay"; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&irrx_pins>; + status = "okay"; +}; + +ð { + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7531"; + reg = <0>; + reset-gpios = <&pio 54 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan0"; + }; + + port@1 { + reg = <1>; + label = "lan1"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan3"; + }; + + port@4 { + reg = <4>; + label = "wan"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; + + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&emmc_pins_default>; + pinctrl-1 = <&emmc_pins_uhs>; + status = "okay"; + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; + non-removable; +}; + +&mmc1 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&sd0_pins_default>; + pinctrl-1 = <&sd0_pins_uhs>; + status = "okay"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + r_smpl = <1>; + cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; +}; + +&nandc { + pinctrl-names = "default"; + pinctrl-0 = <¶llel_nand_pins>; + status = "disabled"; +}; + +&nor_flash { + pinctrl-names = "default"; + pinctrl-0 = <&spi_nor_pins>; + status = "disabled"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>; + status = "okay"; +}; + +&pio { + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { + function = "emmc", "emmc_rst"; + groups = "emmc"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", + * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, + * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively + */ + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + bias-pull-down; + }; + }; + + emmc_pins_uhs: emmc-pins-uhs { + mux { + function = "emmc"; + groups = "emmc"; + }; + + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + drive-strength = <4>; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + drive-strength = <4>; + bias-pull-down; + }; + }; + + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + i2c1_pins: i2c1-pins { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + + i2c2_pins: i2c2-pins { + mux { + function = "i2c"; + groups = "i2c2_0"; + }; + }; + + i2s1_pins: i2s1-pins { + mux { + function = "i2s"; + groups = "i2s_out_mclk_bclk_ws", + "i2s1_in_data", + "i2s1_out_data"; + }; + + conf { + pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", + "I2S_WS", "I2S_MCLK"; + drive-strength = <12>; + bias-pull-down; + }; + }; + + irrx_pins: irrx-pins { + mux { + function = "ir"; + groups = "ir_1_rx"; + }; + }; + + irtx_pins: irtx-pins { + mux { + function = "ir"; + groups = "ir_1_tx"; + }; + }; + + /* Parallel nand is shared pin with eMMC */ + parallel_nand_pins: parallel-nand-pins { + mux { + function = "flash"; + groups = "par_nand"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm7_pins: pwm1-2-pins { + mux { + function = "pwm"; + groups = "pwm_ch7_2"; + }; + }; + + wled_pins: wled-pins { + mux { + function = "led"; + groups = "wled"; + }; + }; + + sd0_pins_default: sd0-pins-default { + mux { + function = "sd"; + groups = "sd_0"; + }; + + /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", + * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, + * DAT2, DAT3, CMD, CLK for SD respectively. + */ + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + drive-strength = <8>; + bias-pull-up; + }; + conf-clk { + pins = "I2S3_OUT"; + drive-strength = <12>; + bias-pull-down; + }; + conf-cd { + pins = "TXD3"; + bias-pull-up; + }; + }; + + sd0_pins_uhs: sd0-pins-uhs { + mux { + function = "sd"; + groups = "sd_0"; + }; + + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "I2S3_OUT"; + bias-pull-down; + }; + }; + + /* Serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + spic0_pins: spic0-pins { + mux { + function = "spi"; + groups = "spic0_0"; + }; + }; + + spic1_pins: spic1-pins { + mux { + function = "spi"; + groups = "spic1_0"; + }; + }; + + /* SPI-NOR is shared pin with serial NAND */ + spi_nor_pins: spi-nor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + /* serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + uart2_pins: uart2-pins { + mux { + function = "uart"; + groups = "uart2_1_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; + + wmac_pins: wmac-pins { + mux { + function = "antsel"; + groups = "antsel0", "antsel1", "antsel2", "antsel3", + "antsel4", "antsel5", "antsel6", "antsel7", + "antsel8", "antsel9", "antsel12", "antsel13", + "antsel14", "antsel15", "antsel16", "antsel17"; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&sata_phy { + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spic1_pins>; + status = "okay"; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_5v>; + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + pinctrl-names = "default"; + pinctrl-0 = <&wmac_pins>; + status = "okay"; +}; diff --git a/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622.dtsi new file mode 100755 index 00000000..6f8cb3ad --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -0,0 +1,959 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + compatible = "mediatek,mt7622"; + interrupt-parent = <&sysirq>; + #address-cells = <2>; + #size-cells = <2>; + + cpu_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-shared; + opp-300000000 { + opp-hz = /bits/ 64 <30000000>; + opp-microvolt = <950000>; + }; + + opp-437500000 { + opp-hz = /bits/ 64 <437500000>; + opp-microvolt = <1000000>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <1050000>; + }; + + opp-812500000 { + opp-hz = /bits/ 64 <812500000>; + opp-microvolt = <1100000>; + }; + + opp-1025000000 { + opp-hz = /bits/ 64 <1025000000>; + opp-microvolt = <1150000>; + }; + + opp-1137500000 { + opp-hz = /bits/ 64 <1137500000>; + opp-microvolt = <1200000>; + }; + + opp-1262500000 { + opp-hz = /bits/ 64 <1262500000>; + opp-microvolt = <1250000>; + }; + + opp-1350000000 { + opp-hz = /bits/ 64 <1350000000>; + opp-microvolt = <1310000>; + }; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x0>; + clocks = <&infracfg CLK_INFRA_MUX1_SEL>, + <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; + enable-method = "psci"; + clock-frequency = <1300000000>; + cci-control-port = <&cci_control2>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x1>; + clocks = <&infracfg CLK_INFRA_MUX1_SEL>, + <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; + enable-method = "psci"; + clock-frequency = <1300000000>; + cci-control-port = <&cci_control2>; + }; + }; + + pwrap_clk: dummy40m { + compatible = "fixed-clock"; + clock-frequency = <40000000>; + #clock-cells = <0>; + }; + + clk25m: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "clkxtal"; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + ; + interrupt-affinity = <&cpu0>, <&cpu1>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + secmon_reserved: secmon@43000000 { + reg = <0 0x43000000 0 0x30000>; + no-map; + }; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = <&thermal 0>; + + trips { + cpu_passive: cpu-passive { + temperature = <47000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_active: cpu-active { + temperature = <67000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_hot: cpu-hot { + temperature = <87000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu-crit { + temperature = <107000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_passive>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&cpu_active>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map2 { + trip = <&cpu_hot>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + infracfg: infracfg@10000000 { + compatible = "mediatek,mt7622-infracfg", + "syscon"; + reg = <0 0x10000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pwrap: pwrap@10001000 { + compatible = "mediatek,mt7622-pwrap"; + reg = <0 0x10001000 0 0x250>; + reg-names = "pwrap"; + clocks = <&infracfg CLK_INFRA_PMIC_PD>, <&pwrap_clk>; + clock-names = "spi", "wrap"; + resets = <&infracfg MT7622_INFRA_PMIC_WRAP_RST>; + reset-names = "pwrap"; + interrupts = ; + status = "disabled"; + }; + + pericfg: pericfg@10002000 { + compatible = "mediatek,mt7622-pericfg", + "syscon"; + reg = <0 0x10002000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + scpsys: power-controller@10006000 { + compatible = "mediatek,mt7622-scpsys", + "syscon"; + #power-domain-cells = <1>; + reg = <0 0x10006000 0 0x1000>; + interrupts = , + , + , + ; + infracfg = <&infracfg>; + clocks = <&topckgen CLK_TOP_HIF_SEL>; + clock-names = "hif_sel"; + }; + + cir: cir@10009000 { + compatible = "mediatek,mt7622-cir"; + reg = <0 0x10009000 0 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_IRRX_PD>, + <&topckgen CLK_TOP_AXI_SEL>; + clock-names = "clk", "bus"; + status = "disabled"; + }; + + sysirq: interrupt-controller@10200620 { + compatible = "mediatek,mt7622-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10200620 0 0x20>; + }; + + efuse: efuse@10206000 { + compatible = "mediatek,mt7622-efuse", + "mediatek,efuse"; + reg = <0 0x10206000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + thermal_calibration: calib@198 { + reg = <0x198 0xc>; + }; + }; + + apmixedsys: apmixedsys@10209000 { + compatible = "mediatek,mt7622-apmixedsys", + "syscon"; + reg = <0 0x10209000 0 0x1000>; + #clock-cells = <1>; + }; + + topckgen: topckgen@10210000 { + compatible = "mediatek,mt7622-topckgen", + "syscon"; + reg = <0 0x10210000 0 0x1000>; + #clock-cells = <1>; + }; + + rng: rng@1020f000 { + compatible = "mediatek,mt7622-rng", + "mediatek,mt7623-rng"; + reg = <0 0x1020f000 0 0x1000>; + clocks = <&infracfg CLK_INFRA_TRNG>; + clock-names = "rng"; + }; + + pio: pinctrl@10211000 { + compatible = "mediatek,mt7622-pinctrl"; + reg = <0 0x10211000 0 0x1000>, + <0 0x10005000 0 0x1000>; + reg-names = "base", "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 103>; + interrupt-controller; + interrupts = ; + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + }; + + watchdog: watchdog@10212000 { + compatible = "mediatek,mt7622-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10212000 0 0x800>; + }; + + rtc: rtc@10212800 { + compatible = "mediatek,mt7622-rtc", + "mediatek,soc-rtc"; + reg = <0 0x10212800 0 0x200>; + interrupts = ; + clocks = <&topckgen CLK_TOP_RTC>; + clock-names = "rtc"; + }; + + gic: interrupt-controller@10300000 { + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10310000 0 0x1000>, + <0 0x10320000 0 0x1000>, + <0 0x10340000 0 0x2000>, + <0 0x10360000 0 0x2000>; + }; + + cci: cci@10390000 { + compatible = "arm,cci-400"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0x10390000 0 0x1000>; + ranges = <0 0 0x10390000 0x10000>; + + cci_control0: slave-if@1000 { + compatible = "arm,cci-400-ctrl-if"; + interface-type = "ace-lite"; + reg = <0x1000 0x1000>; + }; + + cci_control1: slave-if@4000 { + compatible = "arm,cci-400-ctrl-if"; + interface-type = "ace"; + reg = <0x4000 0x1000>; + }; + + cci_control2: slave-if@5000 { + compatible = "arm,cci-400-ctrl-if"; + interface-type = "ace"; + reg = <0x5000 0x1000>; + }; + + pmu@9000 { + compatible = "arm,cci-400-pmu,r1"; + reg = <0x9000 0x5000>; + interrupts = , + , + , + , + ; + }; + }; + + auxadc: adc@11001000 { + compatible = "mediatek,mt7622-auxadc"; + reg = <0 0x11001000 0 0x1000>; + clocks = <&pericfg CLK_PERI_AUXADC_PD>; + clock-names = "main"; + #io-channel-cells = <1>; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt7622-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x400>; + interrupts = ; + clocks = <&topckgen CLK_TOP_UART_SEL>, + <&pericfg CLK_PERI_UART0_PD>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart1: serial@11003000 { + compatible = "mediatek,mt7622-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11003000 0 0x400>; + interrupts = ; + clocks = <&topckgen CLK_TOP_UART_SEL>, + <&pericfg CLK_PERI_UART1_PD>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,mt7622-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11004000 0 0x400>; + interrupts = ; + clocks = <&topckgen CLK_TOP_UART_SEL>, + <&pericfg CLK_PERI_UART2_PD>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart3: serial@11005000 { + compatible = "mediatek,mt7622-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11005000 0 0x400>; + interrupts = ; + clocks = <&topckgen CLK_TOP_UART_SEL>, + <&pericfg CLK_PERI_UART3_PD>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + pwm: pwm@11006000 { + compatible = "mediatek,mt7622-pwm"; + reg = <0 0x11006000 0 0x1000>; + interrupts = ; + clocks = <&topckgen CLK_TOP_PWM_SEL>, + <&pericfg CLK_PERI_PWM_PD>, + <&pericfg CLK_PERI_PWM1_PD>, + <&pericfg CLK_PERI_PWM2_PD>, + <&pericfg CLK_PERI_PWM3_PD>, + <&pericfg CLK_PERI_PWM4_PD>, + <&pericfg CLK_PERI_PWM5_PD>, + <&pericfg CLK_PERI_PWM6_PD>; + clock-names = "top", "main", "pwm1", "pwm2", "pwm3", "pwm4", + "pwm5", "pwm6"; + status = "disabled"; + }; + + i2c0: i2c@11007000 { + compatible = "mediatek,mt7622-i2c"; + reg = <0 0x11007000 0 0x90>, + <0 0x11000100 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C0_PD>, + <&pericfg CLK_PERI_AP_DMA_PD>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@11008000 { + compatible = "mediatek,mt7622-i2c"; + reg = <0 0x11008000 0 0x90>, + <0 0x11000180 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C1_PD>, + <&pericfg CLK_PERI_AP_DMA_PD>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@11009000 { + compatible = "mediatek,mt7622-i2c"; + reg = <0 0x11009000 0 0x90>, + <0 0x11000200 0 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C2_PD>, + <&pericfg CLK_PERI_AP_DMA_PD>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,mt7622-spi"; + reg = <0 0x1100a000 0 0x100>; + interrupts = ; + clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, + <&topckgen CLK_TOP_SPI0_SEL>, + <&pericfg CLK_PERI_SPI0_PD>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + thermal: thermal@1100b000 { + #thermal-sensor-cells = <1>; + compatible = "mediatek,mt7622-thermal"; + reg = <0 0x1100b000 0 0x1000>; + interrupts = <0 78 IRQ_TYPE_LEVEL_LOW>; + clocks = <&pericfg CLK_PERI_THERM_PD>, + <&pericfg CLK_PERI_AUXADC_PD>; + clock-names = "therm", "auxadc"; + resets = <&pericfg MT7622_PERI_THERM_SW_RST>; + reset-names = "therm"; + mediatek,auxadc = <&auxadc>; + mediatek,apmixedsys = <&apmixedsys>; + nvmem-cells = <&thermal_calibration>; + nvmem-cell-names = "calibration-data"; + }; + + btif: serial@1100c000 { + compatible = "mediatek,mt7622-btif", + "mediatek,mtk-btif"; + reg = <0 0x1100c000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_BTIF_PD>; + clock-names = "main"; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + + bluetooth { + compatible = "mediatek,mt7622-bluetooth"; + power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>; + clocks = <&clk25m>; + clock-names = "ref"; + }; + }; + + nandc: nfi@1100d000 { + compatible = "mediatek,mt7622-nfc"; + reg = <0 0x1100D000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_NFI_PD>, + <&pericfg CLK_PERI_SNFI_PD>; + clock-names = "nfi_clk", "pad_clk"; + ecc-engine = <&bch>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + bch: ecc@1100e000 { + compatible = "mediatek,mt7622-ecc"; + reg = <0 0x1100e000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_NFIECC_PD>; + clock-names = "nfiecc_clk"; + status = "disabled"; + }; + + nor_flash: spi@11014000 { + compatible = "mediatek,mt7622-nor", + "mediatek,mt8173-nor"; + reg = <0 0x11014000 0 0xe0>; + clocks = <&pericfg CLK_PERI_FLASH_PD>, + <&topckgen CLK_TOP_FLASH_SEL>; + clock-names = "spi", "sf"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@11016000 { + compatible = "mediatek,mt7622-spi"; + reg = <0 0x11016000 0 0x100>; + interrupts = ; + clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, + <&topckgen CLK_TOP_SPI1_SEL>, + <&pericfg CLK_PERI_SPI1_PD>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + uart4: serial@11019000 { + compatible = "mediatek,mt7622-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11019000 0 0x400>; + interrupts = ; + clocks = <&topckgen CLK_TOP_UART_SEL>, + <&pericfg CLK_PERI_UART4_PD>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + audsys: clock-controller@11220000 { + compatible = "mediatek,mt7622-audsys", "syscon"; + reg = <0 0x11220000 0 0x2000>; + #clock-cells = <1>; + + afe: audio-controller { + compatible = "mediatek,mt7622-audio"; + interrupts = , + ; + interrupt-names = "afe", "asys"; + + clocks = <&infracfg CLK_INFRA_AUDIO_PD>, + <&topckgen CLK_TOP_AUD1_SEL>, + <&topckgen CLK_TOP_AUD2_SEL>, + <&topckgen CLK_TOP_A1SYS_HP_DIV_PD>, + <&topckgen CLK_TOP_A2SYS_HP_DIV_PD>, + <&topckgen CLK_TOP_I2S0_MCK_SEL>, + <&topckgen CLK_TOP_I2S1_MCK_SEL>, + <&topckgen CLK_TOP_I2S2_MCK_SEL>, + <&topckgen CLK_TOP_I2S3_MCK_SEL>, + <&topckgen CLK_TOP_I2S0_MCK_DIV>, + <&topckgen CLK_TOP_I2S1_MCK_DIV>, + <&topckgen CLK_TOP_I2S2_MCK_DIV>, + <&topckgen CLK_TOP_I2S3_MCK_DIV>, + <&topckgen CLK_TOP_I2S0_MCK_DIV_PD>, + <&topckgen CLK_TOP_I2S1_MCK_DIV_PD>, + <&topckgen CLK_TOP_I2S2_MCK_DIV_PD>, + <&topckgen CLK_TOP_I2S3_MCK_DIV_PD>, + <&audsys CLK_AUDIO_I2SO1>, + <&audsys CLK_AUDIO_I2SO2>, + <&audsys CLK_AUDIO_I2SO3>, + <&audsys CLK_AUDIO_I2SO4>, + <&audsys CLK_AUDIO_I2SIN1>, + <&audsys CLK_AUDIO_I2SIN2>, + <&audsys CLK_AUDIO_I2SIN3>, + <&audsys CLK_AUDIO_I2SIN4>, + <&audsys CLK_AUDIO_ASRCO1>, + <&audsys CLK_AUDIO_ASRCO2>, + <&audsys CLK_AUDIO_ASRCO3>, + <&audsys CLK_AUDIO_ASRCO4>, + <&audsys CLK_AUDIO_AFE>, + <&audsys CLK_AUDIO_AFE_CONN>, + <&audsys CLK_AUDIO_A1SYS>, + <&audsys CLK_AUDIO_A2SYS>; + + clock-names = "infra_sys_audio_clk", + "top_audio_mux1_sel", + "top_audio_mux2_sel", + "top_audio_a1sys_hp", + "top_audio_a2sys_hp", + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd"; + + assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP_SEL>, + <&topckgen CLK_TOP_A2SYS_HP_SEL>, + <&topckgen CLK_TOP_A1SYS_HP_DIV>, + <&topckgen CLK_TOP_A2SYS_HP_DIV>; + assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL>, + <&topckgen CLK_TOP_AUD2PLL>; + assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; + }; + }; + + mmc0: mmc@11230000 { + compatible = "mediatek,mt7622-mmc"; + reg = <0 0x11230000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_MSDC30_0_PD>, + <&topckgen CLK_TOP_MSDC50_0_SEL>; + clock-names = "source", "hclk"; + resets = <&pericfg MT7622_PERI_MSDC0_SW_RST>; + reset-names = "hrst"; + status = "disabled"; + }; + + mmc1: mmc@11240000 { + compatible = "mediatek,mt7622-mmc"; + reg = <0 0x11240000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_MSDC30_1_PD>, + <&topckgen CLK_TOP_AXI_SEL>; + clock-names = "source", "hclk"; + resets = <&pericfg MT7622_PERI_MSDC1_SW_RST>; + reset-names = "hrst"; + status = "disabled"; + }; + + wmac: wmac@18000000 { + compatible = "mediatek,mt7622-wmac"; + reg = <0 0x18000000 0 0x100000>; + interrupts = ; + + mediatek,infracfg = <&infracfg>; + status = "disabled"; + + power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>; + }; + + ssusbsys: ssusbsys@1a000000 { + compatible = "mediatek,mt7622-ssusbsys", + "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + ssusb: usb@1a0c0000 { + compatible = "mediatek,mt7622-xhci", + "mediatek,mtk-xhci"; + reg = <0 0x1a0c0000 0 0x01000>, + <0 0x1a0c4700 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF1>; + clocks = <&ssusbsys CLK_SSUSB_SYS_EN>, + <&ssusbsys CLK_SSUSB_REF_EN>, + <&ssusbsys CLK_SSUSB_MCU_EN>, + <&ssusbsys CLK_SSUSB_DMA_EN>; + clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck"; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>, + <&u2port1 PHY_TYPE_USB2>; + + status = "disabled"; + }; + + u3phy: t-phy@1a0c4000 { + compatible = "mediatek,mt7622-tphy", + "mediatek,generic-tphy-v1"; + reg = <0 0x1a0c4000 0 0x700>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + u2port0: usb-phy@1a0c4800 { + reg = <0 0x1a0c4800 0 0x0100>; + #phy-cells = <1>; + clocks = <&ssusbsys CLK_SSUSB_U2_PHY_EN>; + clock-names = "ref"; + }; + + u3port0: usb-phy@1a0c4900 { + reg = <0 0x1a0c4900 0 0x0700>; + #phy-cells = <1>; + clocks = <&clk25m>; + clock-names = "ref"; + }; + + u2port1: usb-phy@1a0c5000 { + reg = <0 0x1a0c5000 0 0x0100>; + #phy-cells = <1>; + clocks = <&ssusbsys CLK_SSUSB_U2_PHY_1P_EN>; + clock-names = "ref"; + }; + }; + + pciesys: pciesys@1a100800 { + compatible = "mediatek,mt7622-pciesys", + "syscon"; + reg = <0 0x1a100800 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pciecfg: pciecfg@1a140000 { + compatible = "mediatek,generic-pciecfg", "syscon"; + reg = <0 0x1a140000 0 0x1000>; + }; + + pcie0: pcie@1a143000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; + reg = <0 0x1a143000 0 0x1000>; + reg-names = "port0"; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + interrupt-names = "pcie_irq"; + clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P0_AUX_EN>, + <&pciesys CLK_PCIE_P0_AXI_EN>, + <&pciesys CLK_PCIE_P0_OBFF_EN>, + <&pciesys CLK_PCIE_P0_PIPE_EN>; + clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", + "axi_ck0", "obff_ck0", "pipe_ck0"; + + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; + status = "disabled"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie1: pcie@1a145000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; + reg = <0 0x1a145000 0 0x1000>; + reg-names = "port1"; + linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; + interrupt-names = "pcie_irq"; + clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, + /* designer has connect RC1 with p0_ahb clock */ + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P1_AUX_EN>, + <&pciesys CLK_PCIE_P1_AXI_EN>, + <&pciesys CLK_PCIE_P1_OBFF_EN>, + <&pciesys CLK_PCIE_P1_PIPE_EN>; + clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", + "axi_ck1", "obff_ck1", "pipe_ck1"; + + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; + status = "disabled"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + sata: sata@1a200000 { + compatible = "mediatek,mt7622-ahci", + "mediatek,mtk-ahci"; + reg = <0 0x1a200000 0 0x1100>; + interrupts = ; + interrupt-names = "hostc"; + clocks = <&pciesys CLK_SATA_AHB_EN>, + <&pciesys CLK_SATA_AXI_EN>, + <&pciesys CLK_SATA_ASIC_EN>, + <&pciesys CLK_SATA_RBC_EN>, + <&pciesys CLK_SATA_PM_EN>; + clock-names = "ahb", "axi", "asic", "rbc", "pm"; + phys = <&sata_port PHY_TYPE_SATA>; + phy-names = "sata-phy"; + ports-implemented = <0x1>; + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + resets = <&pciesys MT7622_SATA_AXI_BUS_RST>, + <&pciesys MT7622_SATA_PHY_SW_RST>, + <&pciesys MT7622_SATA_PHY_REG_RST>; + reset-names = "axi", "sw", "reg"; + mediatek,phy-mode = <&pciesys>; + status = "disabled"; + }; + + sata_phy: t-phy@1a243000 { + compatible = "mediatek,mt7622-tphy", + "mediatek,generic-tphy-v1"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + sata_port: sata-phy@1a243000 { + reg = <0 0x1a243000 0 0x0100>; + clocks = <&topckgen CLK_TOP_ETH_500M>; + clock-names = "ref"; + #phy-cells = <1>; + }; + }; + + ethsys: syscon@1b000000 { + compatible = "mediatek,mt7622-ethsys", + "syscon"; + reg = <0 0x1b000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + hsdma: dma-controller@1b007000 { + compatible = "mediatek,mt7622-hsdma"; + reg = <0 0x1b007000 0 0x1000>; + interrupts = ; + clocks = <ðsys CLK_ETH_HSDMA_EN>; + clock-names = "hsdma"; + power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; + #dma-cells = <1>; + }; + + eth: ethernet@1b100000 { + compatible = "mediatek,mt7622-eth", + "mediatek,mt2701-eth", + "syscon"; + reg = <0 0x1b100000 0 0x20000>; + interrupts = , + , + ; + clocks = <&topckgen CLK_TOP_ETH_SEL>, + <ðsys CLK_ETH_ESW_EN>, + <ðsys CLK_ETH_GP0_EN>, + <ðsys CLK_ETH_GP1_EN>, + <ðsys CLK_ETH_GP2_EN>, + <&sgmiisys CLK_SGMII_TX250M_EN>, + <&sgmiisys CLK_SGMII_RX250M_EN>, + <&sgmiisys CLK_SGMII_CDR_REF>, + <&sgmiisys CLK_SGMII_CDR_FB>, + <&topckgen CLK_TOP_SGMIIPLL>, + <&apmixedsys CLK_APMIXED_ETH2PLL>; + clock-names = "ethif", "esw", "gp0", "gp1", "gp2", + "sgmii_tx250m", "sgmii_rx250m", + "sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck", + "eth2pll"; + power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + sgmiisys: sgmiisys@1b128000 { + compatible = "mediatek,mt7622-sgmiisys", + "syscon"; + reg = <0 0x1b128000 0 0x3000>; + #clock-cells = <1>; + }; +}; diff --git a/root/target/linux/mediatek/files-5.4/drivers/leds/leds-ubnt-ledbar.c b/root/target/linux/mediatek/files-5.4/drivers/leds/leds-ubnt-ledbar.c new file mode 100755 index 00000000..1f50038b --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/leds/leds-ubnt-ledbar.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Driver for the Ubiquiti RGB LED controller (LEDBAR). + * This Controller is based on a Holtek HT32F52241 and connected + * via I2C. + * + * - The Controller needs an enable signal set to high when + * performing a transaction. On the U6-LR, this is located + * at Pin 18 (R6902) + * + * - The Pin is also printed when calling the "usetled" function + * contained in the ubntapp bootloader application. + */ + +#define UBNT_LEDBAR_MAX_BRIGHTNESS 0xff + +#define UBNT_LEDBAR_TRANSACTION_LENGTH 8 +#define UBNT_LEDBAR_TRANSACTION_SUCCESS 0xaa + +#define UBNT_LEDBAR_TRANSACTION_BLUE_IDX 2 +#define UBNT_LEDBAR_TRANSACTION_GREEN_IDX 3 +#define UBNT_LEDBAR_TRANSACTION_RED_IDX 4 + +struct ubnt_ledbar { + struct mutex lock; + struct i2c_client *client; + struct led_classdev led_red; + struct led_classdev led_green; + struct led_classdev led_blue; + struct gpio_desc *enable_gpio; +}; + +static int ubnt_ledbar_perform_transaction(struct ubnt_ledbar *ledbar, + char *transaction) +{ + int ret; + int i; + + for (i = 0; i < UBNT_LEDBAR_TRANSACTION_LENGTH; i++) + i2c_smbus_write_byte(ledbar->client, transaction[i]); + + return i2c_smbus_read_byte(ledbar->client); +} + +static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar) +{ + char setup_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11}; + char led_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00}; + char i2c_response; + int ret = 0; + + mutex_lock(&ledbar->lock); + + led_msg[UBNT_LEDBAR_TRANSACTION_BLUE_IDX] = ledbar->led_blue.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_GREEN_IDX] = ledbar->led_green.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_RED_IDX] = ledbar->led_red.brightness; + + gpiod_set_raw_value(ledbar->enable_gpio, 1); + + msleep(10); + + i2c_response = ubnt_ledbar_perform_transaction(ledbar, setup_msg); + if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { + dev_err(&ledbar->client->dev, "Error initializing LED transaction: %02x\n", ret); + ret = -EINVAL; + goto out_gpio; + } + + i2c_response = ubnt_ledbar_perform_transaction(ledbar, led_msg); + if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { + dev_err(&ledbar->client->dev, "Failed LED transaction: %02x\n", ret); + ret = -EINVAL; + goto out_gpio; + } + + msleep(10); +out_gpio: + gpiod_set_raw_value(ledbar->enable_gpio, 0); + + mutex_unlock(&ledbar->lock); + + return ret; +} + +#define UBNT_LEDBAR_CONTROL_RGBS(name) \ +static int ubnt_ledbar_set_##name##_brightness(struct led_classdev *led_cdev,\ + enum led_brightness value) \ +{ \ + struct ubnt_ledbar *ledbar = \ + container_of(led_cdev, struct ubnt_ledbar, led_##name); \ + int ret; \ + led_cdev->brightness = value; \ + ret = ubnt_ledbar_apply_state(ledbar); \ + return ret; \ +} + +UBNT_LEDBAR_CONTROL_RGBS(red); +UBNT_LEDBAR_CONTROL_RGBS(green); +UBNT_LEDBAR_CONTROL_RGBS(blue); + + +static int ubnt_ledbar_init_led(struct device_node *np, struct ubnt_ledbar *ledbar, + struct led_classdev *led_cdev) +{ + struct led_init_data init_data = {}; + int ret; + + if (!np) + return 0; + + init_data.fwnode = of_fwnode_handle(np); + + led_cdev->max_brightness = UBNT_LEDBAR_MAX_BRIGHTNESS; + + ret = devm_led_classdev_register_ext(&ledbar->client->dev, led_cdev, + &init_data); + if (ret) + dev_err(&ledbar->client->dev, "led register err: %d\n", ret); + + return ret; +} + + +static int ubnt_ledbar_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device_node *np = client->dev.of_node; + struct ubnt_ledbar *ledbar; + int ret; + + ledbar = devm_kzalloc(&client->dev, sizeof(*ledbar), GFP_KERNEL); + if (!ledbar) + return -ENOMEM; + + ledbar->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW); + + if (IS_ERR(ledbar->enable_gpio)) { + ret = PTR_ERR(ledbar->enable_gpio); + dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret); + return ret; + } + + gpiod_direction_output(ledbar->enable_gpio, 0); + + ledbar->client = client; + + mutex_init(&ledbar->lock); + + i2c_set_clientdata(client, ledbar); + + ledbar->led_red.brightness_set_blocking = ubnt_ledbar_set_red_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "red"), ledbar, &ledbar->led_red); + + ledbar->led_green.brightness_set_blocking = ubnt_ledbar_set_green_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "green"), ledbar, &ledbar->led_green); + + ledbar->led_blue.brightness_set_blocking = ubnt_ledbar_set_blue_brightness; + ubnt_ledbar_init_led(of_get_child_by_name(np, "blue"), ledbar, &ledbar->led_blue); + + return ubnt_ledbar_apply_state(ledbar); +} + +static int ubnt_ledbar_remove(struct i2c_client *client) +{ + struct ubnt_ledbar *ledbar = i2c_get_clientdata(client); + + mutex_destroy(&ledbar->lock); + + return 0; +} + +static const struct i2c_device_id ubnt_ledbar_id[] = { + { "ubnt-ledbar", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ubnt_ledbar_id); + +static const struct of_device_id of_ubnt_ledbar_match[] = { + { .compatible = "ubnt,ledbar", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_ubnt_ledbar_match); + +static struct i2c_driver ubnt_ledbar_driver = { + .driver = { + .name = "ubnt-ledbar", + .of_match_table = of_ubnt_ledbar_match, + }, + .probe = ubnt_ledbar_probe, + .remove = ubnt_ledbar_remove, + .id_table = ubnt_ledbar_id, +}; +module_i2c_driver(ubnt_ledbar_driver); + +MODULE_DESCRIPTION("Ubiquiti LEDBAR driver"); +MODULE_AUTHOR("David Bauer "); +MODULE_LICENSE("GPL v2"); diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Kconfig b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Kconfig new file mode 100755 index 00000000..d9e0230c --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Kconfig @@ -0,0 +1,3 @@ + +config MT753X_GSW + tristate "Driver for the MediaTek MT753x switch" diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Makefile b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Makefile new file mode 100755 index 00000000..7aae451c --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for MediaTek MT753x gigabit switch +# + +obj-$(CONFIG_MT753X_GSW) += mt753x.o + +mt753x-$(CONFIG_SWCONFIG) += mt753x_swconfig.o + +mt753x-y += mt753x_mdio.o mt7530.o mt7531.o \ + mt753x_common.o mt753x_vlan.o \ + mt753x_nl.o diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.c new file mode 100755 index 00000000..6a94d0d2 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.c @@ -0,0 +1,631 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include + +#include "mt753x.h" +#include "mt753x_regs.h" + +/* MT7530 registers */ + +/* Unique fields of PMCR for MT7530 */ +#define FORCE_MODE BIT(15) + +/* Unique fields of GMACCR for MT7530 */ +#define VLAN_SUPT_NO_S 14 +#define VLAN_SUPT_NO_M 0x1c000 +#define LATE_COL_DROP BIT(13) + +/* Unique fields of (M)HWSTRAP for MT7530 */ +#define BOND_OPTION BIT(24) +#define P5_PHY0_SEL BIT(20) +#define CHG_TRAP BIT(16) +#define LOOPDET_DIS BIT(14) +#define P5_INTF_SEL_GMAC5 BIT(13) +#define SMI_ADDR_S 11 +#define SMI_ADDR_M 0x1800 +#define XTAL_FSEL_S 9 +#define XTAL_FSEL_M 0x600 +#define P6_INTF_DIS BIT(8) +#define P5_INTF_MODE_RGMII BIT(7) +#define P5_INTF_DIS_S BIT(6) +#define C_MDIO_BPS_S BIT(5) +#define EEPROM_EN_S BIT(4) + +/* PHY EEE Register bitmap of define */ +#define PHY_DEV07 0x07 +#define PHY_DEV07_REG_03C 0x3c + +/* PHY Extend Register 0x14 bitmap of define */ +#define PHY_EXT_REG_14 0x14 + +/* Fields of PHY_EXT_REG_14 */ +#define PHY_EN_DOWN_SHFIT BIT(4) + +/* PHY Token Ring Register 0x10 bitmap of define */ +#define PHY_TR_REG_10 0x10 + +/* PHY Token Ring Register 0x12 bitmap of define */ +#define PHY_TR_REG_12 0x12 + +/* PHY LPI PCS/DSP Control Register bitmap of define */ +#define PHY_LPI_REG_11 0x11 + +/* PHY DEV 0x1e Register bitmap of define */ +#define PHY_DEV1E 0x1e +#define PHY_DEV1E_REG_123 0x123 +#define PHY_DEV1E_REG_A6 0xa6 + +/* Values of XTAL_FSEL */ +#define XTAL_20MHZ 1 +#define XTAL_40MHZ 2 +#define XTAL_25MHZ 3 + +#define P6ECR 0x7830 +#define P6_INTF_MODE_TRGMII BIT(0) + +#define TRGMII_TXCTRL 0x7a40 +#define TRAIN_TXEN BIT(31) +#define TXC_INV BIT(30) +#define TX_DOEO BIT(29) +#define TX_RST BIT(28) + +#define TRGMII_TD0_CTRL 0x7a50 +#define TRGMII_TD1_CTRL 0x7a58 +#define TRGMII_TD2_CTRL 0x7a60 +#define TRGMII_TD3_CTRL 0x7a68 +#define TRGMII_TXCTL_CTRL 0x7a70 +#define TRGMII_TCK_CTRL 0x7a78 +#define TRGMII_TD_CTRL(n) (0x7a50 + (n) * 8) +#define NUM_TRGMII_CTRL 6 +#define TX_DMPEDRV BIT(31) +#define TX_DM_SR BIT(15) +#define TX_DMERODT BIT(14) +#define TX_DMOECTL BIT(13) +#define TX_TAP_S 8 +#define TX_TAP_M 0xf00 +#define TX_TRAIN_WD_S 0 +#define TX_TRAIN_WD_M 0xff + +#define TRGMII_TD0_ODT 0x7a54 +#define TRGMII_TD1_ODT 0x7a5c +#define TRGMII_TD2_ODT 0x7a64 +#define TRGMII_TD3_ODT 0x7a6c +#define TRGMII_TXCTL_ODT 0x7574 +#define TRGMII_TCK_ODT 0x757c +#define TRGMII_TD_ODT(n) (0x7a54 + (n) * 8) +#define NUM_TRGMII_ODT 6 +#define TX_DM_DRVN_PRE_S 30 +#define TX_DM_DRVN_PRE_M 0xc0000000 +#define TX_DM_DRVP_PRE_S 28 +#define TX_DM_DRVP_PRE_M 0x30000000 +#define TX_DM_TDSEL_S 24 +#define TX_DM_TDSEL_M 0xf000000 +#define TX_ODTEN BIT(23) +#define TX_DME_PRE BIT(20) +#define TX_DM_DRVNT0 BIT(19) +#define TX_DM_DRVPT0 BIT(18) +#define TX_DM_DRVNTE BIT(17) +#define TX_DM_DRVPTE BIT(16) +#define TX_DM_ODTN_S 12 +#define TX_DM_ODTN_M 0x7000 +#define TX_DM_ODTP_S 8 +#define TX_DM_ODTP_M 0x700 +#define TX_DM_DRVN_S 4 +#define TX_DM_DRVN_M 0xf0 +#define TX_DM_DRVP_S 0 +#define TX_DM_DRVP_M 0x0f + +#define P5RGMIIRXCR 0x7b00 +#define CSR_RGMII_RCTL_CFG_S 24 +#define CSR_RGMII_RCTL_CFG_M 0x7000000 +#define CSR_RGMII_RXD_CFG_S 16 +#define CSR_RGMII_RXD_CFG_M 0x70000 +#define CSR_RGMII_EDGE_ALIGN BIT(8) +#define CSR_RGMII_RXC_90DEG_CFG_S 4 +#define CSR_RGMII_RXC_90DEG_CFG_M 0xf0 +#define CSR_RGMII_RXC_0DEG_CFG_S 0 +#define CSR_RGMII_RXC_0DEG_CFG_M 0x0f + +#define P5RGMIITXCR 0x7b04 +#define CSR_RGMII_TXEN_CFG_S 16 +#define CSR_RGMII_TXEN_CFG_M 0x70000 +#define CSR_RGMII_TXD_CFG_S 8 +#define CSR_RGMII_TXD_CFG_M 0x700 +#define CSR_RGMII_TXC_CFG_S 0 +#define CSR_RGMII_TXC_CFG_M 0x1f + +#define CHIP_REV 0x7ffc +#define CHIP_NAME_S 16 +#define CHIP_NAME_M 0xffff0000 +#define CHIP_REV_S 0 +#define CHIP_REV_M 0x0f + +/* MMD registers */ +#define CORE_PLL_GROUP2 0x401 +#define RG_SYSPLL_EN_NORMAL BIT(15) +#define RG_SYSPLL_VODEN BIT(14) +#define RG_SYSPLL_POSDIV_S 5 +#define RG_SYSPLL_POSDIV_M 0x60 + +#define CORE_PLL_GROUP4 0x403 +#define RG_SYSPLL_DDSFBK_EN BIT(12) +#define RG_SYSPLL_BIAS_EN BIT(11) +#define RG_SYSPLL_BIAS_LPF_EN BIT(10) + +#define CORE_PLL_GROUP5 0x404 +#define RG_LCDDS_PCW_NCPO1_S 0 +#define RG_LCDDS_PCW_NCPO1_M 0xffff + +#define CORE_PLL_GROUP6 0x405 +#define RG_LCDDS_PCW_NCPO0_S 0 +#define RG_LCDDS_PCW_NCPO0_M 0xffff + +#define CORE_PLL_GROUP7 0x406 +#define RG_LCDDS_PWDB BIT(15) +#define RG_LCDDS_ISO_EN BIT(13) +#define RG_LCCDS_C_S 4 +#define RG_LCCDS_C_M 0x70 +#define RG_LCDDS_PCW_NCPO_CHG BIT(3) + +#define CORE_PLL_GROUP10 0x409 +#define RG_LCDDS_SSC_DELTA_S 0 +#define RG_LCDDS_SSC_DELTA_M 0xfff + +#define CORE_PLL_GROUP11 0x40a +#define RG_LCDDS_SSC_DELTA1_S 0 +#define RG_LCDDS_SSC_DELTA1_M 0xfff + +#define CORE_GSWPLL_GCR_1 0x040d +#define GSWPLL_PREDIV_S 14 +#define GSWPLL_PREDIV_M 0xc000 +#define GSWPLL_POSTDIV_200M_S 12 +#define GSWPLL_POSTDIV_200M_M 0x3000 +#define GSWPLL_EN_PRE BIT(11) +#define GSWPLL_FBKSEL BIT(10) +#define GSWPLL_BP BIT(9) +#define GSWPLL_BR BIT(8) +#define GSWPLL_FBKDIV_200M_S 0 +#define GSWPLL_FBKDIV_200M_M 0xff + +#define CORE_GSWPLL_GCR_2 0x040e +#define GSWPLL_POSTDIV_500M_S 8 +#define GSWPLL_POSTDIV_500M_M 0x300 +#define GSWPLL_FBKDIV_500M_S 0 +#define GSWPLL_FBKDIV_500M_M 0xff + +#define TRGMII_GSW_CLK_CG 0x0410 +#define TRGMIICK_EN BIT(1) +#define GSWCK_EN BIT(0) + +static int mt7530_mii_read(struct gsw_mt753x *gsw, int phy, int reg) +{ + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + return mdiobus_read(gsw->host_bus, phy, reg); +} + +static void mt7530_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val) +{ + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + mdiobus_write(gsw->host_bus, phy, reg, val); +} + +static int mt7530_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg) +{ + u16 val; + + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + val = gsw->host_bus->read(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG); + + mutex_unlock(&gsw->host_bus->mdio_lock); + + return val; +} + +static void mt7530_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, + u16 reg, u16 val) +{ + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, reg); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M)); + + gsw->host_bus->write(gsw->host_bus, addr, MII_MMD_ADDR_DATA_REG, val); + + mutex_unlock(&gsw->host_bus->mdio_lock); +} + +static void mt7530_core_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val) +{ + gsw->mmd_write(gsw, 0, 0x1f, reg, val); +} + +static void mt7530_trgmii_setting(struct gsw_mt753x *gsw) +{ + u16 i; + + mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0780); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); + + /* PLL BIAS enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, + RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN); + mdelay(1); + + /* PLL LPF enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, + RG_SYSPLL_DDSFBK_EN | + RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); + + /* sys PLL enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP2, + RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | + (1 << RG_SYSPLL_POSDIV_S)); + + /* LCDDDS PWDS */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP7, + (3 << RG_LCCDS_C_S) | + RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); + mdelay(1); + + /* Enable MT7530 TRGMII clock */ + mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN | TRGMIICK_EN); + + /* lower Tx Driving */ + for (i = 0 ; i < NUM_TRGMII_ODT; i++) + mt753x_reg_write(gsw, TRGMII_TD_ODT(i), + (4 << TX_DM_DRVP_S) | (4 << TX_DM_DRVN_S)); +} + +static void mt7530_rgmii_setting(struct gsw_mt753x *gsw) +{ + u32 val; + + mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0c80); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); + + val = mt753x_reg_read(gsw, TRGMII_TXCTRL); + val &= ~TXC_INV; + mt753x_reg_write(gsw, TRGMII_TXCTRL, val); + + mt753x_reg_write(gsw, TRGMII_TCK_CTRL, + (8 << TX_TAP_S) | (0x55 << TX_TRAIN_WD_S)); +} + +static int mt7530_mac_port_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap, p6ecr = 0, p5mcr, p6mcr, phyad; + + hwstrap = mt753x_reg_read(gsw, MHWSTRAP); + hwstrap &= ~(P6_INTF_DIS | P5_INTF_MODE_RGMII | P5_INTF_DIS_S); + hwstrap |= P5_INTF_SEL_GMAC5; + if (!gsw->port5_cfg.enabled) { + p5mcr = FORCE_MODE; + hwstrap |= P5_INTF_DIS_S; + } else { + p5mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + MAC_MODE | MAC_TX_EN | MAC_RX_EN | + BKOFF_EN | BACKPR_EN; + + if (gsw->port5_cfg.force_link) { + p5mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC | + FORCE_TX_FC; + p5mcr |= gsw->port5_cfg.speed << FORCE_SPD_S; + + if (gsw->port5_cfg.duplex) + p5mcr |= FORCE_DPX; + } + + switch (gsw->port5_cfg.phy_mode) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_GMII: + break; + case PHY_INTERFACE_MODE_RGMII: + hwstrap |= P5_INTF_MODE_RGMII; + break; + default: + dev_info(gsw->dev, "%s is not supported by port5\n", + phy_modes(gsw->port5_cfg.phy_mode)); + p5mcr = FORCE_MODE; + hwstrap |= P5_INTF_DIS_S; + } + + /* Port5 to PHY direct mode */ + if (of_property_read_u32(gsw->port5_cfg.np, "phy-address", + &phyad)) + goto parse_p6; + + if (phyad != 0 && phyad != 4) { + dev_info(gsw->dev, + "Only PHY 0/4 can be connected to Port 5\n"); + goto parse_p6; + } + + hwstrap &= ~P5_INTF_SEL_GMAC5; + if (phyad == 0) + hwstrap |= P5_PHY0_SEL; + else + hwstrap &= ~P5_PHY0_SEL; + } + +parse_p6: + if (!gsw->port6_cfg.enabled) { + p6mcr = FORCE_MODE; + hwstrap |= P6_INTF_DIS; + } else { + p6mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + MAC_MODE | MAC_TX_EN | MAC_RX_EN | + BKOFF_EN | BACKPR_EN; + + if (gsw->port6_cfg.force_link) { + p6mcr |= FORCE_MODE | FORCE_LINK | FORCE_RX_FC | + FORCE_TX_FC; + p6mcr |= gsw->port6_cfg.speed << FORCE_SPD_S; + + if (gsw->port6_cfg.duplex) + p6mcr |= FORCE_DPX; + } + + switch (gsw->port6_cfg.phy_mode) { + case PHY_INTERFACE_MODE_RGMII: + p6ecr = BIT(1); + break; + case PHY_INTERFACE_MODE_TRGMII: + /* set MT7530 central align */ + p6ecr = BIT(0); + break; + default: + dev_info(gsw->dev, "%s is not supported by port6\n", + phy_modes(gsw->port6_cfg.phy_mode)); + p6mcr = FORCE_MODE; + hwstrap |= P6_INTF_DIS; + } + } + + mt753x_reg_write(gsw, MHWSTRAP, hwstrap); + mt753x_reg_write(gsw, P6ECR, p6ecr); + + mt753x_reg_write(gsw, PMCR(5), p5mcr); + mt753x_reg_write(gsw, PMCR(6), p6mcr); + + return 0; +} + +static void mt7530_core_pll_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap; + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + + switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { + case XTAL_40MHZ: + /* Disable MT7530 core clock */ + mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, 0); + + /* disable MT7530 PLL */ + mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1, + (2 << GSWPLL_POSTDIV_200M_S) | + (32 << GSWPLL_FBKDIV_200M_S)); + + /* For MT7530 core clock = 500Mhz */ + mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_2, + (1 << GSWPLL_POSTDIV_500M_S) | + (25 << GSWPLL_FBKDIV_500M_S)); + + /* Enable MT7530 PLL */ + mt7530_core_reg_write(gsw, CORE_GSWPLL_GCR_1, + (2 << GSWPLL_POSTDIV_200M_S) | + (32 << GSWPLL_FBKDIV_200M_S) | + GSWPLL_EN_PRE); + + usleep_range(20, 40); + + /* Enable MT7530 core clock */ + mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN); + break; + default: + /* TODO: PLL settings for 20/25MHz */ + break; + } + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + hwstrap |= CHG_TRAP; + if (gsw->direct_phy_access) + hwstrap &= ~C_MDIO_BPS_S; + else + hwstrap |= C_MDIO_BPS_S; + + mt753x_reg_write(gsw, MHWSTRAP, hwstrap); + + if (gsw->port6_cfg.enabled && + gsw->port6_cfg.phy_mode == PHY_INTERFACE_MODE_TRGMII) { + mt7530_trgmii_setting(gsw); + } else { + /* RGMII */ + mt7530_rgmii_setting(gsw); + } + + /* delay setting for 10/1000M */ + mt753x_reg_write(gsw, P5RGMIIRXCR, + CSR_RGMII_EDGE_ALIGN | + (2 << CSR_RGMII_RXC_0DEG_CFG_S)); + mt753x_reg_write(gsw, P5RGMIITXCR, 0x14 << CSR_RGMII_TXC_CFG_S); +} + +static int mt7530_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev) +{ + u32 rev; + + rev = mt753x_reg_read(gsw, CHIP_REV); + + if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7530) { + if (crev) { + crev->rev = rev & CHIP_REV_M; + crev->name = "MT7530"; + } + + return 0; + } + + return -ENODEV; +} + +static void mt7530_phy_setting(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + /* Disable EEE */ + gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0); + + /* Enable HW auto downshift */ + gsw->mii_write(gsw, i, 0x1f, 0x1); + val = gsw->mii_read(gsw, i, PHY_EXT_REG_14); + val |= PHY_EN_DOWN_SHFIT; + gsw->mii_write(gsw, i, PHY_EXT_REG_14, val); + + /* Increase SlvDPSready time */ + gsw->mii_write(gsw, i, 0x1f, 0x52b5); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae); + gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae); + + /* Increase post_update_timer */ + gsw->mii_write(gsw, i, 0x1f, 0x3); + gsw->mii_write(gsw, i, PHY_LPI_REG_11, 0x4b); + gsw->mii_write(gsw, i, 0x1f, 0); + + /* Adjust 100_mse_threshold */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff); + + /* Disable mcc */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300); + } +} + +static inline bool get_phy_access_mode(const struct device_node *np) +{ + return of_property_read_bool(np, "mt7530,direct-phy-access"); +} + +static int mt7530_sw_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + gsw->direct_phy_access = get_phy_access_mode(gsw->dev->of_node); + + /* Force MT7530 to use (in)direct PHY access */ + val = mt753x_reg_read(gsw, HWSTRAP); + val |= CHG_TRAP; + if (gsw->direct_phy_access) + val &= ~C_MDIO_BPS_S; + else + val |= C_MDIO_BPS_S; + mt753x_reg_write(gsw, MHWSTRAP, val); + + /* Read PHY address base from HWSTRAP */ + gsw->phy_base = (((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3) + 8; + gsw->phy_base &= MT753X_SMI_ADDR_MASK; + + if (gsw->direct_phy_access) { + gsw->mii_read = mt7530_mii_read; + gsw->mii_write = mt7530_mii_write; + gsw->mmd_read = mt7530_mmd_read; + gsw->mmd_write = mt7530_mmd_write; + } else { + gsw->mii_read = mt753x_mii_read; + gsw->mii_write = mt753x_mii_write; + gsw->mmd_read = mt753x_mmd_ind_read; + gsw->mmd_write = mt753x_mmd_ind_write; + } + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val |= BMCR_PDOWN; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + /* Force MAC link down before reset */ + mt753x_reg_write(gsw, PMCR(5), FORCE_MODE); + mt753x_reg_write(gsw, PMCR(6), FORCE_MODE); + + /* Switch soft reset */ + /* BUG: sw reset causes gsw int flooding */ + mt753x_reg_write(gsw, SYS_CTRL, SW_PHY_RST | SW_SYS_RST | SW_REG_RST); + usleep_range(10, 20); + + /* global mac control settings configuration */ + mt753x_reg_write(gsw, GMACCR, + LATE_COL_DROP | (15 << MTCC_LMT_S) | + (2 << MAX_RX_JUMBO_S) | RX_PKT_LEN_MAX_JUMBO); + + mt7530_core_pll_setup(gsw); + mt7530_mac_port_setup(gsw); + + return 0; +} + +static int mt7530_sw_post_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + mt7530_phy_setting(gsw); + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val &= ~BMCR_PDOWN; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + return 0; +} + +struct mt753x_sw_id mt7530_id = { + .model = MT7530, + .detect = mt7530_sw_detect, + .init = mt7530_sw_init, + .post_init = mt7530_sw_post_init +}; diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.h new file mode 100755 index 00000000..40243d4e --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7530.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#ifndef _MT7530_H_ +#define _MT7530_H_ + +#include "mt753x.h" + +extern struct mt753x_sw_id mt7530_id; + +#endif /* _MT7530_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c new file mode 100755 index 00000000..7ebf09c1 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.c @@ -0,0 +1,918 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Zhanguo Ju + */ + +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_regs.h" + +/* MT7531 registers */ +#define SGMII_REG_BASE 0x5000 +#define SGMII_REG_PORT_BASE 0x1000 +#define SGMII_REG(p, r) (SGMII_REG_BASE + \ + (p) * SGMII_REG_PORT_BASE + (r)) +#define PCS_CONTROL_1(p) SGMII_REG(p, 0x00) +#define SGMII_MODE(p) SGMII_REG(p, 0x20) +#define QPHY_PWR_STATE_CTRL(p) SGMII_REG(p, 0xe8) +#define PHYA_CTRL_SIGNAL3(p) SGMII_REG(p, 0x128) + +/* Fields of PCS_CONTROL_1 */ +#define SGMII_LINK_STATUS BIT(18) +#define SGMII_AN_ENABLE BIT(12) +#define SGMII_AN_RESTART BIT(9) + +/* Fields of SGMII_MODE */ +#define SGMII_REMOTE_FAULT_DIS BIT(8) +#define SGMII_IF_MODE_FORCE_DUPLEX BIT(4) +#define SGMII_IF_MODE_FORCE_SPEED_S 0x2 +#define SGMII_IF_MODE_FORCE_SPEED_M 0x0c +#define SGMII_IF_MODE_ADVERT_AN BIT(1) + +/* Values of SGMII_IF_MODE_FORCE_SPEED */ +#define SGMII_IF_MODE_FORCE_SPEED_10 0 +#define SGMII_IF_MODE_FORCE_SPEED_100 1 +#define SGMII_IF_MODE_FORCE_SPEED_1000 2 + +/* Fields of QPHY_PWR_STATE_CTRL */ +#define PHYA_PWD BIT(4) + +/* Fields of PHYA_CTRL_SIGNAL3 */ +#define RG_TPHY_SPEED_S 2 +#define RG_TPHY_SPEED_M 0x0c + +/* Values of RG_TPHY_SPEED */ +#define RG_TPHY_SPEED_1000 0 +#define RG_TPHY_SPEED_2500 1 + +/* Unique fields of (M)HWSTRAP for MT7531 */ +#define XTAL_FSEL_S 7 +#define XTAL_FSEL_M BIT(7) +#define PHY_EN BIT(6) +#define CHG_STRAP BIT(8) + +/* Efuse Register Define */ +#define GBE_EFUSE 0x7bc8 +#define GBE_SEL_EFUSE_EN BIT(0) + +/* PHY ENABLE Register bitmap define */ +#define PHY_DEV1F 0x1f +#define PHY_DEV1F_REG_44 0x44 +#define PHY_DEV1F_REG_104 0x104 +#define PHY_DEV1F_REG_10A 0x10a +#define PHY_DEV1F_REG_10B 0x10b +#define PHY_DEV1F_REG_10C 0x10c +#define PHY_DEV1F_REG_10D 0x10d +#define PHY_DEV1F_REG_268 0x268 +#define PHY_DEV1F_REG_269 0x269 +#define PHY_DEV1F_REG_403 0x403 + +/* Fields of PHY_DEV1F_REG_403 */ +#define GBE_EFUSE_SETTING BIT(3) +#define PHY_EN_BYPASS_MODE BIT(4) +#define POWER_ON_OFF BIT(5) +#define PHY_PLL_M GENMASK(9, 8) +#define PHY_PLL_SEL(x) (((x) << 8) & GENMASK(9, 8)) + +/* PHY EEE Register bitmap of define */ +#define PHY_DEV07 0x07 +#define PHY_DEV07_REG_03C 0x3c + +/* PHY Extend Register 0x14 bitmap of define */ +#define PHY_EXT_REG_14 0x14 + +/* Fields of PHY_EXT_REG_14 */ +#define PHY_EN_DOWN_SHFIT BIT(4) + +/* PHY Extend Register 0x17 bitmap of define */ +#define PHY_EXT_REG_17 0x17 + +/* Fields of PHY_EXT_REG_17 */ +#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4) + +/* PHY Token Ring Register 0x10 bitmap of define */ +#define PHY_TR_REG_10 0x10 + +/* PHY Token Ring Register 0x12 bitmap of define */ +#define PHY_TR_REG_12 0x12 + +/* PHY DEV 0x1e Register bitmap of define */ +#define PHY_DEV1E 0x1e +#define PHY_DEV1E_REG_13 0x13 +#define PHY_DEV1E_REG_14 0x14 +#define PHY_DEV1E_REG_41 0x41 +#define PHY_DEV1E_REG_A6 0xa6 +#define PHY_DEV1E_REG_0C6 0x0c6 +#define PHY_DEV1E_REG_0FE 0x0fe +#define PHY_DEV1E_REG_123 0x123 +#define PHY_DEV1E_REG_189 0x189 + +/* Fields of PHY_DEV1E_REG_0C6 */ +#define PHY_POWER_SAVING_S 8 +#define PHY_POWER_SAVING_M 0x300 +#define PHY_POWER_SAVING_TX 0x0 + +/* Fields of PHY_DEV1E_REG_189 */ +#define DESCRAMBLER_CLEAR_EN 0x1 + +/* Values of XTAL_FSEL_S */ +#define XTAL_40MHZ 0 +#define XTAL_25MHZ 1 + +#define PLLGP_EN 0x7820 +#define EN_COREPLL BIT(2) +#define SW_CLKSW BIT(1) +#define SW_PLLGP BIT(0) + +#define PLLGP_CR0 0x78a8 +#define RG_COREPLL_EN BIT(22) +#define RG_COREPLL_POSDIV_S 23 +#define RG_COREPLL_POSDIV_M 0x3800000 +#define RG_COREPLL_SDM_PCW_S 1 +#define RG_COREPLL_SDM_PCW_M 0x3ffffe +#define RG_COREPLL_SDM_PCW_CHG BIT(0) + +/* TOP Signals Status Register */ +#define TOP_SIG_SR 0x780c +#define PAD_DUAL_SGMII_EN BIT(1) + +/* RGMII and SGMII PLL clock */ +#define ANA_PLLGP_CR2 0x78b0 +#define ANA_PLLGP_CR5 0x78bc + +/* GPIO mode define */ +#define GPIO_MODE_REGS(x) (0x7c0c + (((x) / 8) * 4)) +#define GPIO_MODE_S 4 + +/* GPIO GROUP IOLB SMT0 Control */ +#define SMT0_IOLB 0x7f04 +#define SMT_IOLB_5_SMI_MDC_EN BIT(5) + +/* Unique fields of PMCR for MT7531 */ +#define FORCE_MODE_EEE1G BIT(25) +#define FORCE_MODE_EEE100 BIT(26) +#define FORCE_MODE_TX_FC BIT(27) +#define FORCE_MODE_RX_FC BIT(28) +#define FORCE_MODE_DPX BIT(29) +#define FORCE_MODE_SPD BIT(30) +#define FORCE_MODE_LNK BIT(31) +#define FORCE_MODE BIT(15) + +#define CHIP_REV 0x781C +#define CHIP_NAME_S 16 +#define CHIP_NAME_M 0xffff0000 +#define CHIP_REV_S 0 +#define CHIP_REV_M 0x0f +#define CHIP_REV_E1 0x0 + +#define CLKGEN_CTRL 0x7500 +#define CLK_SKEW_OUT_S 8 +#define CLK_SKEW_OUT_M 0x300 +#define CLK_SKEW_IN_S 6 +#define CLK_SKEW_IN_M 0xc0 +#define RXCLK_NO_DELAY BIT(5) +#define TXCLK_NO_REVERSE BIT(4) +#define GP_MODE_S 1 +#define GP_MODE_M 0x06 +#define GP_CLK_EN BIT(0) + +/* Values of GP_MODE */ +#define GP_MODE_RGMII 0 +#define GP_MODE_MII 1 +#define GP_MODE_REV_MII 2 + +/* Values of CLK_SKEW_IN */ +#define CLK_SKEW_IN_NO_CHANGE 0 +#define CLK_SKEW_IN_DELAY_100PPS 1 +#define CLK_SKEW_IN_DELAY_200PPS 2 +#define CLK_SKEW_IN_REVERSE 3 + +/* Values of CLK_SKEW_OUT */ +#define CLK_SKEW_OUT_NO_CHANGE 0 +#define CLK_SKEW_OUT_DELAY_100PPS 1 +#define CLK_SKEW_OUT_DELAY_200PPS 2 +#define CLK_SKEW_OUT_REVERSE 3 + +/* Proprietory Control Register of Internal Phy device 0x1e */ +#define RXADC_CONTROL_3 0xc2 +#define RXADC_LDO_CONTROL_2 0xd3 + +/* Proprietory Control Register of Internal Phy device 0x1f */ +#define TXVLD_DA_271 0x271 +#define TXVLD_DA_272 0x272 +#define TXVLD_DA_273 0x273 + +/* DSP Channel and NOD_ADDR*/ +#define DSP_CH 0x2 +#define DSP_NOD_ADDR 0xD + +/* gpio pinmux pins and functions define */ +static int gpio_int_pins[] = {0}; +static int gpio_int_funcs[] = {1}; +static int gpio_mdc_pins[] = {11, 20}; +static int gpio_mdc_funcs[] = {2, 2}; +static int gpio_mdio_pins[] = {12, 21}; +static int gpio_mdio_funcs[] = {2, 2}; + +static int mt7531_set_port_sgmii_force_mode(struct gsw_mt753x *gsw, u32 port, + struct mt753x_port_cfg *port_cfg) +{ + u32 speed, port_base, val; + ktime_t timeout; + u32 timeout_us; + + if (port < 5 || port >= MT753X_NUM_PORTS) { + dev_info(gsw->dev, "port %d is not a SGMII port\n", port); + return -EINVAL; + } + + port_base = port - 5; + + switch (port_cfg->speed) { + case MAC_SPD_1000: + speed = RG_TPHY_SPEED_1000; + break; + case MAC_SPD_2500: + speed = RG_TPHY_SPEED_2500; + break; + default: + dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n", + port_cfg->speed, port); + + speed = RG_TPHY_SPEED_1000; + } + + /* Step 1: Speed select register setting */ + val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base)); + val &= ~RG_TPHY_SPEED_M; + val |= speed << RG_TPHY_SPEED_S; + mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val); + + /* Step 2 : Disable AN */ + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base)); + val &= ~SGMII_AN_ENABLE; + mt753x_reg_write(gsw, PCS_CONTROL_1(port_base), val); + + /* Step 3: SGMII force mode setting */ + val = mt753x_reg_read(gsw, SGMII_MODE(port_base)); + val &= ~SGMII_IF_MODE_ADVERT_AN; + val &= ~SGMII_IF_MODE_FORCE_SPEED_M; + val |= SGMII_IF_MODE_FORCE_SPEED_1000 << SGMII_IF_MODE_FORCE_SPEED_S; + val |= SGMII_IF_MODE_FORCE_DUPLEX; + /* For sgmii force mode, 0 is full duplex and 1 is half duplex */ + if (port_cfg->duplex) + val &= ~SGMII_IF_MODE_FORCE_DUPLEX; + + mt753x_reg_write(gsw, SGMII_MODE(port_base), val); + + /* Step 4: XXX: Disable Link partner's AN and set force mode */ + + /* Step 5: XXX: Special setting for PHYA ==> reserved for flexible */ + + /* Step 6 : Release PHYA power down state */ + val = mt753x_reg_read(gsw, QPHY_PWR_STATE_CTRL(port_base)); + val &= ~PHYA_PWD; + mt753x_reg_write(gsw, QPHY_PWR_STATE_CTRL(port_base), val); + + /* Step 7 : Polling SGMII_LINK_STATUS */ + timeout_us = 2000000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base)); + val &= SGMII_LINK_STATUS; + + if (val) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + return 0; +} + +static int mt7531_set_port_sgmii_an_mode(struct gsw_mt753x *gsw, u32 port, + struct mt753x_port_cfg *port_cfg) +{ + u32 speed, port_base, val; + ktime_t timeout; + u32 timeout_us; + + if (port < 5 || port >= MT753X_NUM_PORTS) { + dev_info(gsw->dev, "port %d is not a SGMII port\n", port); + return -EINVAL; + } + + port_base = port - 5; + + switch (port_cfg->speed) { + case MAC_SPD_1000: + speed = RG_TPHY_SPEED_1000; + break; + case MAC_SPD_2500: + speed = RG_TPHY_SPEED_2500; + break; + default: + dev_info(gsw->dev, "invalid SGMII speed idx %d for port %d\n", + port_cfg->speed, port); + + speed = RG_TPHY_SPEED_1000; + } + + /* Step 1: Speed select register setting */ + val = mt753x_reg_read(gsw, PHYA_CTRL_SIGNAL3(port_base)); + val &= ~RG_TPHY_SPEED_M; + val |= speed << RG_TPHY_SPEED_S; + mt753x_reg_write(gsw, PHYA_CTRL_SIGNAL3(port_base), val); + + /* Step 2: Remote fault disable */ + val = mt753x_reg_read(gsw, SGMII_MODE(port)); + val |= SGMII_REMOTE_FAULT_DIS; + mt753x_reg_write(gsw, SGMII_MODE(port), val); + + /* Step 3: Setting Link partner's AN enable = 1 */ + + /* Step 4: Setting Link partner's device ability for speed/duplex */ + + /* Step 5: AN re-start */ + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port)); + val |= SGMII_AN_RESTART; + mt753x_reg_write(gsw, PCS_CONTROL_1(port), val); + + /* Step 6: Special setting for PHYA ==> reserved for flexible */ + + /* Step 7 : Polling SGMII_LINK_STATUS */ + timeout_us = 2000000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PCS_CONTROL_1(port_base)); + val &= SGMII_LINK_STATUS; + + if (val) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + return 0; +} + +static int mt7531_set_port_rgmii(struct gsw_mt753x *gsw, u32 port) +{ + u32 val; + + if (port != 5) { + dev_info(gsw->dev, "RGMII mode is not available for port %d\n", + port); + return -EINVAL; + } + + val = mt753x_reg_read(gsw, CLKGEN_CTRL); + val |= GP_CLK_EN; + val &= ~GP_MODE_M; + val |= GP_MODE_RGMII << GP_MODE_S; + val |= TXCLK_NO_REVERSE; + val |= RXCLK_NO_DELAY; + val &= ~CLK_SKEW_IN_M; + val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S; + val &= ~CLK_SKEW_OUT_M; + val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S; + mt753x_reg_write(gsw, CLKGEN_CTRL, val); + + return 0; +} + +static int mt7531_mac_port_setup(struct gsw_mt753x *gsw, u32 port, + struct mt753x_port_cfg *port_cfg) +{ + u32 pmcr; + u32 speed; + + if (port < 5 || port >= MT753X_NUM_PORTS) { + dev_info(gsw->dev, "port %d is not a MAC port\n", port); + return -EINVAL; + } + + if (port_cfg->enabled) { + pmcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + MAC_MODE | MAC_TX_EN | MAC_RX_EN | + BKOFF_EN | BACKPR_EN; + + if (port_cfg->force_link) { + /* PMCR's speed field 0x11 is reserved, + * sw should set 0x10 + */ + speed = port_cfg->speed; + if (port_cfg->speed == MAC_SPD_2500) + speed = MAC_SPD_1000; + + pmcr |= FORCE_MODE_LNK | FORCE_LINK | + FORCE_MODE_SPD | FORCE_MODE_DPX | + FORCE_MODE_RX_FC | FORCE_MODE_TX_FC | + FORCE_RX_FC | FORCE_TX_FC | + (speed << FORCE_SPD_S); + + if (port_cfg->duplex) + pmcr |= FORCE_DPX; + } + } else { + pmcr = FORCE_MODE_LNK; + } + + switch (port_cfg->phy_mode) { + case PHY_INTERFACE_MODE_RGMII: + mt7531_set_port_rgmii(gsw, port); + break; + case PHY_INTERFACE_MODE_SGMII: + if (port_cfg->force_link) + mt7531_set_port_sgmii_force_mode(gsw, port, port_cfg); + else + mt7531_set_port_sgmii_an_mode(gsw, port, port_cfg); + break; + default: + if (port_cfg->enabled) + dev_info(gsw->dev, "%s is not supported by port %d\n", + phy_modes(port_cfg->phy_mode), port); + + pmcr = FORCE_MODE_LNK; + } + + mt753x_reg_write(gsw, PMCR(port), pmcr); + + return 0; +} + +static void mt7531_core_pll_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap; + u32 val; + + val = mt753x_reg_read(gsw, TOP_SIG_SR); + if (val & PAD_DUAL_SGMII_EN) + return; + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + + switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { + case XTAL_25MHZ: + /* Step 1 : Disable MT7531 COREPLL */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val &= ~EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 2: switch to XTAL output */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_CLKSW; + mt753x_reg_write(gsw, PLLGP_EN, val); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Step 3: disable PLLGP and enable program PLLGP */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_PLLGP; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 4: program COREPLL output frequency to 500MHz */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_POSDIV_M; + val |= 2 << RG_COREPLL_POSDIV_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + usleep_range(25, 35); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_M; + val |= 0x140000 << RG_COREPLL_SDM_PCW_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Set feedback divide ratio update signal to high */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + /* Wait for at least 16 XTAL clocks */ + usleep_range(10, 20); + + /* Step 5: set feedback divide ratio update signal to low */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Enable 325M clock for SGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000); + + /* Enable 250SSC clock for RGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000); + + /* Step 6: Enable MT7531 PLL */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + usleep_range(25, 35); + + break; + case XTAL_40MHZ: + /* Step 1 : Disable MT7531 COREPLL */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val &= ~EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 2: switch to XTAL output */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_CLKSW; + mt753x_reg_write(gsw, PLLGP_EN, val); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Step 3: disable PLLGP and enable program PLLGP */ + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= SW_PLLGP; + mt753x_reg_write(gsw, PLLGP_EN, val); + + /* Step 4: program COREPLL output frequency to 500MHz */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_POSDIV_M; + val |= 2 << RG_COREPLL_POSDIV_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + usleep_range(25, 35); + + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_M; + val |= 0x190000 << RG_COREPLL_SDM_PCW_S; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Set feedback divide ratio update signal to high */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + /* Wait for at least 16 XTAL clocks */ + usleep_range(10, 20); + + /* Step 5: set feedback divide ratio update signal to low */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val &= ~RG_COREPLL_SDM_PCW_CHG; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + /* Enable 325M clock for SGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR5, 0xad0000); + + /* Enable 250SSC clock for RGMII */ + mt753x_reg_write(gsw, ANA_PLLGP_CR2, 0x4f40000); + + /* Step 6: Enable MT7531 PLL */ + val = mt753x_reg_read(gsw, PLLGP_CR0); + val |= RG_COREPLL_EN; + mt753x_reg_write(gsw, PLLGP_CR0, val); + + val = mt753x_reg_read(gsw, PLLGP_EN); + val |= EN_COREPLL; + mt753x_reg_write(gsw, PLLGP_EN, val); + usleep_range(25, 35); + break; + } +} + +static int mt7531_internal_phy_calibration(struct gsw_mt753x *gsw) +{ + return 0; +} + +static int mt7531_sw_detect(struct gsw_mt753x *gsw, struct chip_rev *crev) +{ + u32 rev, topsig; + + rev = mt753x_reg_read(gsw, CHIP_REV); + + if (((rev & CHIP_NAME_M) >> CHIP_NAME_S) == MT7531) { + if (crev) { + topsig = mt753x_reg_read(gsw, TOP_SIG_SR); + + crev->rev = rev & CHIP_REV_M; + crev->name = topsig & PAD_DUAL_SGMII_EN ? + "MT7531AE" : "MT7531BE"; + } + + return 0; + } + + return -ENODEV; +} + +static void pinmux_set_mux_7531(struct gsw_mt753x *gsw, u32 pin, u32 mode) +{ + u32 val; + + val = mt753x_reg_read(gsw, GPIO_MODE_REGS(pin)); + val &= ~(0xf << (pin & 7) * GPIO_MODE_S); + val |= mode << (pin & 7) * GPIO_MODE_S; + mt753x_reg_write(gsw, GPIO_MODE_REGS(pin), val); +} + +static int mt7531_set_gpio_pinmux(struct gsw_mt753x *gsw) +{ + u32 group = 0; + struct device_node *np = gsw->dev->of_node; + + /* Set GPIO 0 interrupt mode */ + pinmux_set_mux_7531(gsw, gpio_int_pins[0], gpio_int_funcs[0]); + + of_property_read_u32(np, "mediatek,mdio_master_pinmux", &group); + + /* group = 0: do nothing, 1: 1st group (AE), 2: 2nd group (BE) */ + if (group > 0 && group <= 2) { + group--; + pinmux_set_mux_7531(gsw, gpio_mdc_pins[group], + gpio_mdc_funcs[group]); + pinmux_set_mux_7531(gsw, gpio_mdio_pins[group], + gpio_mdio_funcs[group]); + } + + return 0; +} + +static void mt7531_phy_pll_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap; + u32 val; + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + + switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { + case XTAL_25MHZ: + /* disable pll auto calibration */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608); + + /* change pll sel */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~(PHY_PLL_M); + val |= PHY_PLL_SEL(3); + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10A, 0x1009); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0x7c6); + + /* capacitance and resistance adjustment */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10C, 0xa8be); + + break; + case XTAL_40MHZ: + /* disable pll auto calibration */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608); + + /* change pll sel */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~(PHY_PLL_M); + val |= PHY_PLL_SEL(3); + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10A, 0x1018); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0xc676); + + /* capacitance and resistance adjustment */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10C, 0xd8be); + break; + } + + /* power down pll. additional delay is not required via mdio access */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x10); + + /* power up pll */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x14); +} + +static void mt7531_phy_setting(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + /* Adjust DAC TX Delay */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_44, 0xc0); + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + /* Disable EEE */ + gsw->mmd_write(gsw, i, PHY_DEV07, PHY_DEV07_REG_03C, 0); + + /* Enable HW auto downshift */ + gsw->mii_write(gsw, i, 0x1f, 0x1); + val = gsw->mii_read(gsw, i, PHY_EXT_REG_14); + val |= PHY_EN_DOWN_SHFIT; + gsw->mii_write(gsw, i, PHY_EXT_REG_14, val); + + /* Increase SlvDPSready time */ + gsw->mii_write(gsw, i, 0x1f, 0x52b5); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0xafae); + gsw->mii_write(gsw, i, PHY_TR_REG_12, 0x2f); + gsw->mii_write(gsw, i, PHY_TR_REG_10, 0x8fae); + gsw->mii_write(gsw, i, 0x1f, 0); + + /* Adjust 100_mse_threshold */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff); + + /* Disable mcc */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300); + + /* PHY link down power saving enable */ + val = gsw->mii_read(gsw, i, PHY_EXT_REG_17); + val |= PHY_LINKDOWN_POWER_SAVING_EN; + gsw->mii_write(gsw, i, PHY_EXT_REG_17, val); + + val = gsw->mmd_read(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6); + val &= ~PHY_POWER_SAVING_M; + val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S; + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_0C6, val); + + /* Set TX Pair delay selection */ + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_13, 0x404); + gsw->mmd_write(gsw, i, PHY_DEV1E, PHY_DEV1E_REG_14, 0x404); + } +} + +static void mt7531_adjust_line_driving(struct gsw_mt753x *gsw, u32 port) +{ + /* For ADC timing margin window for LDO calibration */ + gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_LDO_CONTROL_2, 0x2222); + + /* Adjust AD sample timing */ + gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_CONTROL_3, 0x4444); + + /* Adjust Line driver current for different mode */ + gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_271, 0x2ca5); + + /* Adjust Line driver current for different mode */ + gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_272, 0xc6b); + + /* Adjust Line driver amplitude for 10BT */ + gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_273, 0x3000); + + /* Adjust RX Echo path filter */ + gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_0FE, 0x2); + + /* Adjust RX HVGA bias current */ + gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_41, 0x3333); + + /* Adjust TX class AB driver 1 */ + gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x388); + + /* Adjust TX class AB driver 2 */ + gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0x4448); +} + +static void mt7531_eee_setting(struct gsw_mt753x *gsw, u32 port) +{ + u32 tr_reg_control; + u32 val; + + /* Disable generate signal to clear the scramble_lock when lpi mode */ + val = gsw->mmd_read(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189); + val &= ~DESCRAMBLER_CLEAR_EN; + gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_189, val); + + /* roll back CR*/ + gsw->mii_write(gsw, port, 0x1f, 0x52b5); + gsw->mmd_write(gsw, port, 0x1e, 0x2d1, 0); + tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) | + (DSP_NOD_ADDR << 7) | (0x8 << 1); + gsw->mii_write(gsw, port, 17, 0x1b); + gsw->mii_write(gsw, port, 18, 0); + gsw->mii_write(gsw, port, 16, tr_reg_control); + tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) | + (DSP_NOD_ADDR << 7) | (0xf << 1); + gsw->mii_write(gsw, port, 17, 0); + gsw->mii_write(gsw, port, 18, 0); + gsw->mii_write(gsw, port, 16, tr_reg_control); + + tr_reg_control = (1 << 15) | (0 << 13) | (DSP_CH << 11) | + (DSP_NOD_ADDR << 7) | (0x10 << 1); + gsw->mii_write(gsw, port, 17, 0x500); + gsw->mii_write(gsw, port, 18, 0); + gsw->mii_write(gsw, port, 16, tr_reg_control); + gsw->mii_write(gsw, port, 0x1f, 0); +} + +static int mt7531_sw_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + gsw->phy_base = (gsw->smi_addr + 1) & MT753X_SMI_ADDR_MASK; + + gsw->mii_read = mt753x_mii_read; + gsw->mii_write = mt753x_mii_write; + gsw->mmd_read = mt753x_mmd_read; + gsw->mmd_write = mt753x_mmd_write; + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val |= BMCR_ISOLATE; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + /* Force MAC link down before reset */ + mt753x_reg_write(gsw, PMCR(5), FORCE_MODE_LNK); + mt753x_reg_write(gsw, PMCR(6), FORCE_MODE_LNK); + + /* Switch soft reset */ + mt753x_reg_write(gsw, SYS_CTRL, SW_SYS_RST | SW_REG_RST); + usleep_range(10, 20); + + /* Enable MDC input Schmitt Trigger */ + val = mt753x_reg_read(gsw, SMT0_IOLB); + mt753x_reg_write(gsw, SMT0_IOLB, val | SMT_IOLB_5_SMI_MDC_EN); + + /* Set 7531 gpio pinmux */ + mt7531_set_gpio_pinmux(gsw); + + /* Global mac control settings */ + mt753x_reg_write(gsw, GMACCR, + (15 << MTCC_LMT_S) | (11 << MAX_RX_JUMBO_S) | + RX_PKT_LEN_MAX_JUMBO); + + mt7531_core_pll_setup(gsw); + mt7531_mac_port_setup(gsw, 5, &gsw->port5_cfg); + mt7531_mac_port_setup(gsw, 6, &gsw->port6_cfg); + + return 0; +} + +static int mt7531_sw_post_init(struct gsw_mt753x *gsw) +{ + int i; + u32 val; + + mt7531_phy_pll_setup(gsw); + + /* Internal PHYs are disabled by default. SW should enable them. + * Note that this may already be enabled in bootloader stage. + */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403); + val |= PHY_EN_BYPASS_MODE; + val &= ~POWER_ON_OFF; + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + mt7531_phy_setting(gsw); + + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMCR); + val &= ~BMCR_ISOLATE; + gsw->mii_write(gsw, i, MII_BMCR, val); + } + + for (i = 0; i < MT753X_NUM_PHYS; i++) + mt7531_adjust_line_driving(gsw, i); + + for (i = 0; i < MT753X_NUM_PHYS; i++) + mt7531_eee_setting(gsw, i); + + val = mt753x_reg_read(gsw, CHIP_REV); + val &= CHIP_REV_M; + if (val == CHIP_REV_E1) { + mt7531_internal_phy_calibration(gsw); + } else { + val = mt753x_reg_read(gsw, GBE_EFUSE); + if (val & GBE_SEL_EFUSE_EN) { + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~GBE_EFUSE_SETTING; + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, + val); + } else { + mt7531_internal_phy_calibration(gsw); + } + } + + return 0; +} + +struct mt753x_sw_id mt7531_id = { + .model = MT7531, + .detect = mt7531_sw_detect, + .init = mt7531_sw_init, + .post_init = mt7531_sw_post_init +}; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Zhanguo Ju "); +MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch"); diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.h new file mode 100755 index 00000000..52c8a49f --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt7531.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#ifndef _MT7531_H_ +#define _MT7531_H_ + +#include "mt753x.h" + +extern struct mt753x_sw_id mt7531_id; + +#endif /* _MT7531_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x.h new file mode 100755 index 00000000..837a4156 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x.h @@ -0,0 +1,213 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MT753X_H_ +#define _MT753X_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SWCONFIG +#include +#endif + +#include "mt753x_vlan.h" + +#define MT753X_DFL_CPU_PORT 6 +#define MT753X_NUM_PHYS 5 + +#define MT753X_DFL_SMI_ADDR 0x1f +#define MT753X_SMI_ADDR_MASK 0x1f + +struct gsw_mt753x; + +enum mt753x_model { + MT7530 = 0x7530, + MT7531 = 0x7531 +}; + +struct mt753x_port_cfg { + struct device_node *np; + int phy_mode; + u32 enabled: 1; + u32 force_link: 1; + u32 speed: 2; + u32 duplex: 1; +}; + +struct mt753x_phy { + struct gsw_mt753x *gsw; + struct net_device netdev; + struct phy_device *phydev; +}; + +struct gsw_mt753x { + u32 id; + + struct device *dev; + struct mii_bus *host_bus; + struct mii_bus *gphy_bus; + struct mutex mii_lock; /* MII access lock */ + u32 smi_addr; + u32 phy_base; + int direct_phy_access; + + enum mt753x_model model; + const char *name; + + struct mt753x_port_cfg port5_cfg; + struct mt753x_port_cfg port6_cfg; + + int phy_status_poll; + struct mt753x_phy phys[MT753X_NUM_PHYS]; + + int phy_link_sts; + + int irq; + int reset_pin; + struct work_struct irq_worker; + +#ifdef CONFIG_SWCONFIG + struct switch_dev swdev; + u32 cpu_port; +#endif + + int global_vlan_enable; + struct mt753x_vlan_entry vlan_entries[MT753X_NUM_VLANS]; + struct mt753x_port_entry port_entries[MT753X_NUM_PORTS]; + + int (*mii_read)(struct gsw_mt753x *gsw, int phy, int reg); + void (*mii_write)(struct gsw_mt753x *gsw, int phy, int reg, u16 val); + + int (*mmd_read)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg); + void (*mmd_write)(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val); + + struct list_head list; +}; + +struct chip_rev { + const char *name; + u32 rev; +}; + +struct mt753x_sw_id { + enum mt753x_model model; + int (*detect)(struct gsw_mt753x *gsw, struct chip_rev *crev); + int (*init)(struct gsw_mt753x *gsw); + int (*post_init)(struct gsw_mt753x *gsw); +}; + +extern struct list_head mt753x_devs; + +struct gsw_mt753x *mt753x_get_gsw(u32 id); +struct gsw_mt753x *mt753x_get_first_gsw(void); +void mt753x_put_gsw(void); +void mt753x_lock_gsw(void); + +u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg); +void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val); + +int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg); +void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val); + +int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg); +void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val); + +int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg); +void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val); + +void mt753x_irq_worker(struct work_struct *work); +void mt753x_irq_enable(struct gsw_mt753x *gsw); + +/* MDIO Indirect Access Registers */ +#define MII_MMD_ACC_CTL_REG 0x0d +#define MMD_CMD_S 14 +#define MMD_CMD_M 0xc000 +#define MMD_DEVAD_S 0 +#define MMD_DEVAD_M 0x1f + +/* MMD_CMD: MMD commands */ +#define MMD_ADDR 0 +#define MMD_DATA 1 + +#define MII_MMD_ADDR_DATA_REG 0x0e + +/* Procedure of MT753x Internal Register Access + * + * 1. Internal Register Address + * + * The MT753x has a 16-bit register address and each register is 32-bit. + * This means the lowest two bits are not used as the register address is + * 4-byte aligned. + * + * Rest of the valid bits are divided into two parts: + * Bit 15..6 is the Page address + * Bit 5..2 is the low address + * + * ------------------------------------------------------------------- + * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 | + * |----------------------------------------|---------------|--------| + * | Page Address | Address | Unused | + * ------------------------------------------------------------------- + * + * 2. MDIO access timing + * + * The MT753x uses the following MDIO timing for a single register read + * + * Phase 1: Write Page Address + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | RSVD | TA | RSVD | PAGE_ADDR | + * ------------------------------------------------------------------- + * | 01 | 01 | 11111 | 1 | 1111 | xx | 00000 | REG_ADDR[15..6] | + * ------------------------------------------------------------------- + * + * Phase 2: Write low Address & Read low word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 10 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] | + * ------------------------------------------------------------------- + * + * Phase 3: Read high word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 10 | 11111 | 1 | 0000 | xx | DATA[31..16] | + * ------------------------------------------------------------------- + * + * The MT753x uses the following MDIO timing for a single register write + * + * Phase 1: Write Page Address (The same as read) + * + * Phase 2: Write low Address and low word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | LOW_ADDR | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 01 | 11111 | 0 | REG_ADDR[5..2] | xx | DATA[15..0] | + * ------------------------------------------------------------------- + * + * Phase 3: write high word + * ------------------------------------------------------------------- + * | ST | OP | PHY_ADDR | TYPE | RSVD | TA | DATA | + * ------------------------------------------------------------------- + * | 01 | 01 | 11111 | 1 | 0000 | xx | DATA[31..16] | + * ------------------------------------------------------------------- + * + */ + +/* Internal Register Address fields */ +#define MT753X_REG_PAGE_ADDR_S 6 +#define MT753X_REG_PAGE_ADDR_M 0xffc0 +#define MT753X_REG_ADDR_S 2 +#define MT753X_REG_ADDR_M 0x3c +#endif /* _MT753X_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_common.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_common.c new file mode 100755 index 00000000..4015ddf1 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_common.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include + +#include "mt753x.h" +#include "mt753x_regs.h" + +void mt753x_irq_enable(struct gsw_mt753x *gsw) +{ + u32 val; + int i; + + /* Record initial PHY link status */ + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMSR); + if (val & BMSR_LSTATUS) + gsw->phy_link_sts |= BIT(i); + } + + val = BIT(MT753X_NUM_PHYS) - 1; + + mt753x_reg_write(gsw, SYS_INT_EN, val); +} + +static void display_port_link_status(struct gsw_mt753x *gsw, u32 port) +{ + u32 pmsr, speed_bits; + const char *speed; + + pmsr = mt753x_reg_read(gsw, PMSR(port)); + + speed_bits = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S; + + switch (speed_bits) { + case MAC_SPD_10: + speed = "10Mbps"; + break; + case MAC_SPD_100: + speed = "100Mbps"; + break; + case MAC_SPD_1000: + speed = "1Gbps"; + break; + case MAC_SPD_2500: + speed = "2.5Gbps"; + break; + } + + if (pmsr & MAC_LNK_STS) { + dev_info(gsw->dev, "Port %d Link is Up - %s/%s\n", + port, speed, (pmsr & MAC_DPX_STS) ? "Full" : "Half"); + } else { + dev_info(gsw->dev, "Port %d Link is Down\n", port); + } +} + +void mt753x_irq_worker(struct work_struct *work) +{ + struct gsw_mt753x *gsw; + u32 sts, physts, laststs; + int i; + + gsw = container_of(work, struct gsw_mt753x, irq_worker); + + sts = mt753x_reg_read(gsw, SYS_INT_STS); + + /* Check for changed PHY link status */ + for (i = 0; i < MT753X_NUM_PHYS; i++) { + if (!(sts & PHY_LC_INT(i))) + continue; + + laststs = gsw->phy_link_sts & BIT(i); + physts = !!(gsw->mii_read(gsw, i, MII_BMSR) & BMSR_LSTATUS); + physts <<= i; + + if (physts ^ laststs) { + gsw->phy_link_sts ^= BIT(i); + display_port_link_status(gsw, i); + } + } + + mt753x_reg_write(gsw, SYS_INT_STS, sts); + + enable_irq(gsw->irq); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_mdio.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_mdio.c new file mode 100755 index 00000000..a3f0c5d3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_mdio.c @@ -0,0 +1,598 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_swconfig.h" +#include "mt753x_regs.h" +#include "mt753x_nl.h" +#include "mt7530.h" +#include "mt7531.h" + +static u32 mt753x_id; +struct list_head mt753x_devs; +static DEFINE_MUTEX(mt753x_devs_lock); + +static struct mt753x_sw_id *mt753x_sw_ids[] = { + &mt7530_id, + &mt7531_id, +}; + +u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg) +{ + u32 high, low; + + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f, + (reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S); + + low = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, + (reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S); + + high = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, 0x10); + + mutex_unlock(&gsw->host_bus->mdio_lock); + + return (high << 16) | (low & 0xffff); +} + +void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val) +{ + mutex_lock(&gsw->host_bus->mdio_lock); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f, + (reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, + (reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S, val & 0xffff); + + gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x10, val >> 16); + + mutex_unlock(&gsw->host_bus->mdio_lock); +} + +/* Indirect MDIO clause 22/45 access */ +static int mt753x_mii_rw(struct gsw_mt753x *gsw, int phy, int reg, u16 data, + u32 cmd, u32 st) +{ + ktime_t timeout; + u32 val, timeout_us; + int ret = 0; + + timeout_us = 100000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PHY_IAC); + + if ((val & PHY_ACS_ST) == 0) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + val = (st << MDIO_ST_S) | + ((cmd << MDIO_CMD_S) & MDIO_CMD_M) | + ((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) | + ((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M); + + if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR) + val |= data & MDIO_RW_DATA_M; + + mt753x_reg_write(gsw, PHY_IAC, val | PHY_ACS_ST); + + timeout_us = 100000; + timeout = ktime_add_us(ktime_get(), timeout_us); + while (1) { + val = mt753x_reg_read(gsw, PHY_IAC); + + if ((val & PHY_ACS_ST) == 0) + break; + + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) { + val = mt753x_reg_read(gsw, PHY_IAC); + ret = val & MDIO_RW_DATA_M; + } + + return ret; +} + +int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg) +{ + int val; + + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + val = mt753x_mii_rw(gsw, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22); + mutex_unlock(&gsw->mii_lock); + + return val; +} + +void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val) +{ + if (phy < MT753X_NUM_PHYS) + phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + mt753x_mii_rw(gsw, phy, reg, val, MDIO_CMD_WRITE, MDIO_ST_C22); + mutex_unlock(&gsw->mii_lock); +} + +int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg) +{ + int val; + + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45); + val = mt753x_mii_rw(gsw, addr, devad, 0, MDIO_CMD_READ_C45, + MDIO_ST_C45); + mutex_unlock(&gsw->mii_lock); + + return val; +} + +void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val) +{ + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45); + mt753x_mii_rw(gsw, addr, devad, val, MDIO_CMD_WRITE, MDIO_ST_C45); + mutex_unlock(&gsw->mii_lock); +} + +int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg) +{ + u16 val; + + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg, + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + val = mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, 0, + MDIO_CMD_READ, MDIO_ST_C22); + + mutex_unlock(&gsw->mii_lock); + + return val; +} + +void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, + u16 val) +{ + if (addr < MT753X_NUM_PHYS) + addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK; + + mutex_lock(&gsw->mii_lock); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_ADDR << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg, + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG, + (MMD_DATA << MMD_CMD_S) | + ((devad << MMD_DEVAD_S) & MMD_DEVAD_M), + MDIO_CMD_WRITE, MDIO_ST_C22); + + mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, val, + MDIO_CMD_WRITE, MDIO_ST_C22); + + mutex_unlock(&gsw->mii_lock); +} + +static inline int mt753x_get_duplex(const struct device_node *np) +{ + return of_property_read_bool(np, "full-duplex"); +} + +static void mt753x_load_port_cfg(struct gsw_mt753x *gsw) +{ + struct device_node *port_np; + struct device_node *fixed_link_node; + struct mt753x_port_cfg *port_cfg; + u32 port; + + for_each_child_of_node(gsw->dev->of_node, port_np) { + if (!of_device_is_compatible(port_np, "mediatek,mt753x-port")) + continue; + + if (!of_device_is_available(port_np)) + continue; + + if (of_property_read_u32(port_np, "reg", &port)) + continue; + + switch (port) { + case 5: + port_cfg = &gsw->port5_cfg; + break; + case 6: + port_cfg = &gsw->port6_cfg; + break; + default: + continue; + } + + if (port_cfg->enabled) { + dev_info(gsw->dev, "duplicated node for port%d\n", + port_cfg->phy_mode); + continue; + } + + port_cfg->np = port_np; + + port_cfg->phy_mode = of_get_phy_mode(port_np); + if (port_cfg->phy_mode < 0) { + dev_info(gsw->dev, "incorrect phy-mode %d\n", port); + continue; + } + + fixed_link_node = of_get_child_by_name(port_np, "fixed-link"); + if (fixed_link_node) { + u32 speed; + + port_cfg->force_link = 1; + port_cfg->duplex = mt753x_get_duplex(fixed_link_node); + + if (of_property_read_u32(fixed_link_node, "speed", + &speed)) { + speed = 0; + continue; + } + + of_node_put(fixed_link_node); + + switch (speed) { + case 10: + port_cfg->speed = MAC_SPD_10; + break; + case 100: + port_cfg->speed = MAC_SPD_100; + break; + case 1000: + port_cfg->speed = MAC_SPD_1000; + break; + case 2500: + port_cfg->speed = MAC_SPD_2500; + break; + default: + dev_info(gsw->dev, "incorrect speed %d\n", + speed); + continue; + } + } + + port_cfg->enabled = 1; + } +} + +static void mt753x_add_gsw(struct gsw_mt753x *gsw) +{ + mutex_lock(&mt753x_devs_lock); + gsw->id = mt753x_id++; + INIT_LIST_HEAD(&gsw->list); + list_add_tail(&gsw->list, &mt753x_devs); + mutex_unlock(&mt753x_devs_lock); +} + +static void mt753x_remove_gsw(struct gsw_mt753x *gsw) +{ + mutex_lock(&mt753x_devs_lock); + list_del(&gsw->list); + mutex_unlock(&mt753x_devs_lock); +} + + +struct gsw_mt753x *mt753x_get_gsw(u32 id) +{ + struct gsw_mt753x *dev; + + mutex_lock(&mt753x_devs_lock); + + list_for_each_entry(dev, &mt753x_devs, list) { + if (dev->id == id) + return dev; + } + + mutex_unlock(&mt753x_devs_lock); + + return NULL; +} + +struct gsw_mt753x *mt753x_get_first_gsw(void) +{ + struct gsw_mt753x *dev; + + mutex_lock(&mt753x_devs_lock); + + list_for_each_entry(dev, &mt753x_devs, list) + return dev; + + mutex_unlock(&mt753x_devs_lock); + + return NULL; +} + +void mt753x_put_gsw(void) +{ + mutex_unlock(&mt753x_devs_lock); +} + +void mt753x_lock_gsw(void) +{ + mutex_lock(&mt753x_devs_lock); +} + +static int mt753x_hw_reset(struct gsw_mt753x *gsw) +{ + struct device_node *np = gsw->dev->of_node; + struct reset_control *rstc; + int mcm; + int ret = -EINVAL; + + mcm = of_property_read_bool(np, "mediatek,mcm"); + if (mcm) { + rstc = devm_reset_control_get(gsw->dev, "mcm"); + ret = IS_ERR(rstc); + if (IS_ERR(rstc)) { + dev_err(gsw->dev, "Missing reset ctrl of switch\n"); + return ret; + } + + reset_control_assert(rstc); + msleep(30); + reset_control_deassert(rstc); + + gsw->reset_pin = -1; + return 0; + } + + gsw->reset_pin = of_get_named_gpio(np, "reset-gpios", 0); + if (gsw->reset_pin < 0) { + dev_err(gsw->dev, "Missing reset pin of switch\n"); + return ret; + } + + ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mt753x-reset"); + if (ret) { + dev_info(gsw->dev, "Failed to request gpio %d\n", + gsw->reset_pin); + return ret; + } + + gpio_direction_output(gsw->reset_pin, 0); + msleep(30); + gpio_set_value(gsw->reset_pin, 1); + msleep(500); + + return 0; +} + +static irqreturn_t mt753x_irq_handler(int irq, void *dev) +{ + struct gsw_mt753x *gsw = dev; + + disable_irq_nosync(gsw->irq); + + schedule_work(&gsw->irq_worker); + + return IRQ_HANDLED; +} + +static int mt753x_probe(struct platform_device *pdev) +{ + struct gsw_mt753x *gsw; + struct mt753x_sw_id *sw; + struct device_node *np = pdev->dev.of_node; + struct device_node *mdio; + struct mii_bus *mdio_bus; + int ret = -EINVAL; + struct chip_rev rev; + struct mt753x_mapping *map; + int i; + + mdio = of_parse_phandle(np, "mediatek,mdio", 0); + if (!mdio) + return -EINVAL; + + mdio_bus = of_mdio_find_bus(mdio); + if (!mdio_bus) + return -EPROBE_DEFER; + + gsw = devm_kzalloc(&pdev->dev, sizeof(struct gsw_mt753x), GFP_KERNEL); + if (!gsw) + return -ENOMEM; + + gsw->host_bus = mdio_bus; + gsw->dev = &pdev->dev; + mutex_init(&gsw->mii_lock); + + /* Switch hard reset */ + if (mt753x_hw_reset(gsw)) + goto fail; + + /* Fetch the SMI address dirst */ + if (of_property_read_u32(np, "mediatek,smi-addr", &gsw->smi_addr)) + gsw->smi_addr = MT753X_DFL_SMI_ADDR; + + /* Get LAN/WAN port mapping */ + map = mt753x_find_mapping(np); + if (map) { + mt753x_apply_mapping(gsw, map); + gsw->global_vlan_enable = 1; + dev_info(gsw->dev, "LAN/WAN VLAN setting=%s\n", map->name); + } + + /* Load MAC port configurations */ + mt753x_load_port_cfg(gsw); + + /* Check for valid switch and then initialize */ + for (i = 0; i < ARRAY_SIZE(mt753x_sw_ids); i++) { + if (!mt753x_sw_ids[i]->detect(gsw, &rev)) { + sw = mt753x_sw_ids[i]; + + gsw->name = rev.name; + gsw->model = sw->model; + + dev_info(gsw->dev, "Switch is MediaTek %s rev %d", + gsw->name, rev.rev); + + /* Initialize the switch */ + ret = sw->init(gsw); + if (ret) + goto fail; + + break; + } + } + + if (i >= ARRAY_SIZE(mt753x_sw_ids)) { + dev_err(gsw->dev, "No mt753x switch found\n"); + goto fail; + } + + gsw->irq = platform_get_irq(pdev, 0); + if (gsw->irq >= 0) { + ret = devm_request_irq(gsw->dev, gsw->irq, mt753x_irq_handler, + 0, dev_name(gsw->dev), gsw); + if (ret) { + dev_err(gsw->dev, "Failed to request irq %d\n", + gsw->irq); + goto fail; + } + + INIT_WORK(&gsw->irq_worker, mt753x_irq_worker); + } + + platform_set_drvdata(pdev, gsw); + + gsw->phy_status_poll = of_property_read_bool(gsw->dev->of_node, + "mediatek,phy-poll"); + + mt753x_add_gsw(gsw); + + mt753x_swconfig_init(gsw); + + if (sw->post_init) + sw->post_init(gsw); + + if (gsw->irq >= 0) + mt753x_irq_enable(gsw); + + return 0; + +fail: + devm_kfree(&pdev->dev, gsw); + + return ret; +} + +static int mt753x_remove(struct platform_device *pdev) +{ + struct gsw_mt753x *gsw = platform_get_drvdata(pdev); + + if (gsw->irq >= 0) + cancel_work_sync(&gsw->irq_worker); + + if (gsw->reset_pin >= 0) + devm_gpio_free(&pdev->dev, gsw->reset_pin); + +#ifdef CONFIG_SWCONFIG + mt753x_swconfig_destroy(gsw); +#endif + + mt753x_remove_gsw(gsw); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id mt753x_ids[] = { + { .compatible = "mediatek,mt753x" }, + { }, +}; + +MODULE_DEVICE_TABLE(of, mt753x_ids); + +static struct platform_driver mt753x_driver = { + .probe = mt753x_probe, + .remove = mt753x_remove, + .driver = { + .name = "mt753x", + .of_match_table = mt753x_ids, + }, +}; + +static int __init mt753x_init(void) +{ + int ret; + + INIT_LIST_HEAD(&mt753x_devs); + ret = platform_driver_register(&mt753x_driver); + + mt753x_nl_init(); + + return ret; +} +module_init(mt753x_init); + +static void __exit mt753x_exit(void) +{ + mt753x_nl_exit(); + + platform_driver_unregister(&mt753x_driver); +} +module_exit(mt753x_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Weijie Gao "); +MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch"); diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.c new file mode 100755 index 00000000..ccde2c92 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Sirui Zhao + */ + +#include +#include +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_nl.h" + +struct mt753x_nl_cmd_item { + enum mt753x_cmd cmd; + bool require_dev; + int (*process)(struct genl_info *info, struct gsw_mt753x *gsw); + u32 nr_required_attrs; + const enum mt753x_attr *required_attrs; +}; + +static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info); + +/* +static const struct nla_policy mt753x_nl_cmd_policy[] = { + [MT753X_ATTR_TYPE_MESG] = { .type = NLA_STRING }, + [MT753X_ATTR_TYPE_PHY] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_REG] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_VAL] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_DEV_NAME] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_DEV_ID] = { .type = NLA_S32 }, + [MT753X_ATTR_TYPE_DEVAD] = { .type = NLA_S32 }, +}; +*/ + +static const struct genl_ops mt753x_nl_ops[] = { + { + .cmd = MT753X_CMD_REQUEST, + .doit = mt753x_nl_response, +// .policy = mt753x_nl_cmd_policy, + .flags = GENL_ADMIN_PERM, + }, { + .cmd = MT753X_CMD_READ, + .doit = mt753x_nl_response, +// .policy = mt753x_nl_cmd_policy, + .flags = GENL_ADMIN_PERM, + }, { + .cmd = MT753X_CMD_WRITE, + .doit = mt753x_nl_response, +// .policy = mt753x_nl_cmd_policy, + .flags = GENL_ADMIN_PERM, + }, +}; + +static struct genl_family mt753x_nl_family = { + .name = MT753X_GENL_NAME, + .version = MT753X_GENL_VERSION, + .maxattr = MT753X_NR_ATTR_TYPE, + .ops = mt753x_nl_ops, + .n_ops = ARRAY_SIZE(mt753x_nl_ops), +}; + +static int mt753x_nl_list_devs(char *buff, int size) +{ + struct gsw_mt753x *gsw; + int len, total = 0; + char buf[80]; + + memset(buff, 0, size); + + mt753x_lock_gsw(); + + list_for_each_entry(gsw, &mt753x_devs, list) { + len = snprintf(buf, sizeof(buf), + "id: %d, model: %s, node: %s\n", + gsw->id, gsw->name, gsw->dev->of_node->name); + strncat(buff, buf, size - total); + total += len; + } + + mt753x_put_gsw(); + + return total; +} + +static int mt753x_nl_prepare_reply(struct genl_info *info, u8 cmd, + struct sk_buff **skbp) +{ + struct sk_buff *msg; + void *reply; + + if (!info) + return -EINVAL; + + msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + /* Construct send-back message header */ + reply = genlmsg_put(msg, info->snd_portid, info->snd_seq, + &mt753x_nl_family, 0, cmd); + if (!reply) { + nlmsg_free(msg); + return -EINVAL; + } + + *skbp = msg; + return 0; +} + +static int mt753x_nl_send_reply(struct sk_buff *skb, struct genl_info *info) +{ + struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb)); + void *reply = genlmsg_data(genlhdr); + + /* Finalize a generic netlink message (update message header) */ + genlmsg_end(skb, reply); + + /* reply to a request */ + return genlmsg_reply(skb, info); +} + +static s32 mt753x_nl_get_s32(struct genl_info *info, enum mt753x_attr attr, + s32 defval) +{ + struct nlattr *na; + + na = info->attrs[attr]; + if (na) + return nla_get_s32(na); + + return defval; +} + +static int mt753x_nl_get_u32(struct genl_info *info, enum mt753x_attr attr, + u32 *val) +{ + struct nlattr *na; + + na = info->attrs[attr]; + if (na) { + *val = nla_get_u32(na); + return 0; + } + + return -1; +} + +static struct gsw_mt753x *mt753x_nl_parse_find_gsw(struct genl_info *info) +{ + struct gsw_mt753x *gsw; + struct nlattr *na; + int gsw_id; + + na = info->attrs[MT753X_ATTR_TYPE_DEV_ID]; + if (na) { + gsw_id = nla_get_s32(na); + if (gsw_id >= 0) + gsw = mt753x_get_gsw(gsw_id); + else + gsw = mt753x_get_first_gsw(); + } else { + gsw = mt753x_get_first_gsw(); + } + + return gsw; +} + +static int mt753x_nl_get_swdevs(struct genl_info *info, struct gsw_mt753x *gsw) +{ + struct sk_buff *rep_skb = NULL; + char dev_info[512]; + int ret; + + ret = mt753x_nl_list_devs(dev_info, sizeof(dev_info)); + if (!ret) { + pr_info("No switch registered\n"); + return -EINVAL; + } + + ret = mt753x_nl_prepare_reply(info, MT753X_CMD_REPLY, &rep_skb); + if (ret < 0) + goto err; + + ret = nla_put_string(rep_skb, MT753X_ATTR_TYPE_MESG, dev_info); + if (ret < 0) + goto err; + + return mt753x_nl_send_reply(rep_skb, info); + +err: + if (rep_skb) + nlmsg_free(rep_skb); + + return ret; +} + +static int mt753x_nl_reply_read(struct genl_info *info, struct gsw_mt753x *gsw) +{ + struct sk_buff *rep_skb = NULL; + s32 phy, devad, reg; + int value; + int ret = 0; + + phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1); + devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1); + reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1); + + if (reg < 0) + goto err; + + ret = mt753x_nl_prepare_reply(info, MT753X_CMD_READ, &rep_skb); + if (ret < 0) + goto err; + + if (phy >= 0) { + if (devad < 0) + value = gsw->mii_read(gsw, phy, reg); + else + value = gsw->mmd_read(gsw, phy, devad, reg); + } else { + value = mt753x_reg_read(gsw, reg); + } + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg); + if (ret < 0) + goto err; + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value); + if (ret < 0) + goto err; + + return mt753x_nl_send_reply(rep_skb, info); + +err: + if (rep_skb) + nlmsg_free(rep_skb); + + return ret; +} + +static int mt753x_nl_reply_write(struct genl_info *info, struct gsw_mt753x *gsw) +{ + struct sk_buff *rep_skb = NULL; + s32 phy, devad, reg; + u32 value; + int ret = 0; + + phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1); + devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1); + reg = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_REG, -1); + + if (mt753x_nl_get_u32(info, MT753X_ATTR_TYPE_VAL, &value)) + goto err; + + if (reg < 0) + goto err; + + ret = mt753x_nl_prepare_reply(info, MT753X_CMD_WRITE, &rep_skb); + if (ret < 0) + goto err; + + if (phy >= 0) { + if (devad < 0) + gsw->mii_write(gsw, phy, reg, value); + else + gsw->mmd_write(gsw, phy, devad, reg, value); + } else { + mt753x_reg_write(gsw, reg, value); + } + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_REG, reg); + if (ret < 0) + goto err; + + ret = nla_put_s32(rep_skb, MT753X_ATTR_TYPE_VAL, value); + if (ret < 0) + goto err; + + return mt753x_nl_send_reply(rep_skb, info); + +err: + if (rep_skb) + nlmsg_free(rep_skb); + + return ret; +} + +static const enum mt753x_attr mt753x_nl_cmd_read_attrs[] = { + MT753X_ATTR_TYPE_REG +}; + +static const enum mt753x_attr mt753x_nl_cmd_write_attrs[] = { + MT753X_ATTR_TYPE_REG, + MT753X_ATTR_TYPE_VAL +}; + +static const struct mt753x_nl_cmd_item mt753x_nl_cmds[] = { + { + .cmd = MT753X_CMD_REQUEST, + .require_dev = false, + .process = mt753x_nl_get_swdevs + }, { + .cmd = MT753X_CMD_READ, + .require_dev = true, + .process = mt753x_nl_reply_read, + .required_attrs = mt753x_nl_cmd_read_attrs, + .nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_read_attrs), + }, { + .cmd = MT753X_CMD_WRITE, + .require_dev = true, + .process = mt753x_nl_reply_write, + .required_attrs = mt753x_nl_cmd_write_attrs, + .nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_write_attrs), + } +}; + +static int mt753x_nl_response(struct sk_buff *skb, struct genl_info *info) +{ + struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); + const struct mt753x_nl_cmd_item *cmditem = NULL; + struct gsw_mt753x *gsw = NULL; + u32 sat_req_attrs = 0; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(mt753x_nl_cmds); i++) { + if (hdr->cmd == mt753x_nl_cmds[i].cmd) { + cmditem = &mt753x_nl_cmds[i]; + break; + } + } + + if (!cmditem) { + pr_info("mt753x-nl: unknown cmd %u\n", hdr->cmd); + return -EINVAL; + } + + for (i = 0; i < cmditem->nr_required_attrs; i++) { + if (info->attrs[cmditem->required_attrs[i]]) + sat_req_attrs++; + } + + if (sat_req_attrs != cmditem->nr_required_attrs) { + pr_info("mt753x-nl: missing required attr(s) for cmd %u\n", + hdr->cmd); + return -EINVAL; + } + + if (cmditem->require_dev) { + gsw = mt753x_nl_parse_find_gsw(info); + if (!gsw) { + pr_info("mt753x-nl: failed to find switch dev\n"); + return -EINVAL; + } + } + + ret = cmditem->process(info, gsw); + + mt753x_put_gsw(); + + return ret; +} + +int __init mt753x_nl_init(void) +{ + int ret; + + ret = genl_register_family(&mt753x_nl_family); + if (ret) { + pr_info("mt753x-nl: genl_register_family_with_ops failed\n"); + return ret; + } + + return 0; +} + +void __exit mt753x_nl_exit(void) +{ + genl_unregister_family(&mt753x_nl_family); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.h new file mode 100755 index 00000000..85dc9e79 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_nl.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Sirui Zhao + */ + +#ifndef _MT753X_NL_H_ +#define _MT753X_NL_H_ + +#define MT753X_GENL_NAME "mt753x" +#define MT753X_GENL_VERSION 0x1 + +enum mt753x_cmd { + MT753X_CMD_UNSPEC = 0, + MT753X_CMD_REQUEST, + MT753X_CMD_REPLY, + MT753X_CMD_READ, + MT753X_CMD_WRITE, + + __MT753X_CMD_MAX, +}; + +enum mt753x_attr { + MT753X_ATTR_TYPE_UNSPEC = 0, + MT753X_ATTR_TYPE_MESG, + MT753X_ATTR_TYPE_PHY, + MT753X_ATTR_TYPE_DEVAD, + MT753X_ATTR_TYPE_REG, + MT753X_ATTR_TYPE_VAL, + MT753X_ATTR_TYPE_DEV_NAME, + MT753X_ATTR_TYPE_DEV_ID, + + __MT753X_ATTR_TYPE_MAX, +}; + +#define MT753X_NR_ATTR_TYPE (__MT753X_ATTR_TYPE_MAX - 1) + +#ifdef __KERNEL__ +int __init mt753x_nl_init(void); +void __exit mt753x_nl_exit(void); +#endif /* __KERNEL__ */ + +#endif /* _MT753X_NL_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_regs.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_regs.h new file mode 100755 index 00000000..3f23ae20 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_regs.h @@ -0,0 +1,294 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MT753X_REGS_H_ +#define _MT753X_REGS_H_ + +#include + +/* Values of Egress TAG Control */ +#define ETAG_CTRL_UNTAG 0 +#define ETAG_CTRL_TAG 2 +#define ETAG_CTRL_SWAP 1 +#define ETAG_CTRL_STACK 3 + +#define VTCR 0x90 +#define VAWD1 0x94 +#define VAWD2 0x98 + +/* Fields of VTCR */ +#define VTCR_BUSY BIT(31) +#define IDX_INVLD BIT(16) +#define VTCR_FUNC_S 12 +#define VTCR_FUNC_M 0xf000 +#define VTCR_VID_S 0 +#define VTCR_VID_M 0xfff + +/* Values of VTCR_FUNC */ +#define VTCR_READ_VLAN_ENTRY 0 +#define VTCR_WRITE_VLAN_ENTRY 1 +#define VTCR_INVD_VLAN_ENTRY 2 +#define VTCR_ENABLE_VLAN_ENTRY 3 +#define VTCR_READ_ACL_ENTRY 4 +#define VTCR_WRITE_ACL_ENTRY 5 +#define VTCR_READ_TRTCM_TABLE 6 +#define VTCR_WRITE_TRTCM_TABLE 7 +#define VTCR_READ_ACL_MASK_ENTRY 8 +#define VTCR_WRITE_ACL_MASK_ENTRY 9 +#define VTCR_READ_ACL_RULE_ENTRY 10 +#define VTCR_WRITE_ACL_RULE_ENTRY 11 +#define VTCR_READ_ACL_RATE_ENTRY 12 +#define VTCR_WRITE_ACL_RATE_ENTRY 13 + +/* VLAN entry fields */ +/* VAWD1 */ +#define PORT_STAG BIT(31) +#define IVL_MAC BIT(30) +#define EG_CON BIT(29) +#define VTAG_EN BIT(28) +#define COPY_PRI BIT(27) +#define USER_PRI_S 24 +#define USER_PRI_M 0x7000000 +#define PORT_MEM_S 16 +#define PORT_MEM_M 0xff0000 +#define S_TAG1_S 4 +#define S_TAG1_M 0xfff0 +#define FID_S 1 +#define FID_M 0x0e +#define VENTRY_VALID BIT(0) + +/* VAWD2 */ +#define S_TAG2_S 16 +#define S_TAG2_M 0xffff0000 +#define PORT_ETAG_S(p) ((p) * 2) +#define PORT_ETAG_M 0x03 + +#define PORT_CTRL_BASE 0x2000 +#define PORT_CTRL_PORT_OFFSET 0x100 +#define PORT_CTRL_REG(p, r) (PORT_CTRL_BASE + \ + (p) * PORT_CTRL_PORT_OFFSET + (r)) +#define CKGCR(p) PORT_CTRL_REG(p, 0x00) +#define PCR(p) PORT_CTRL_REG(p, 0x04) +#define PIC(p) PORT_CTRL_REG(p, 0x08) +#define PSC(p) PORT_CTRL_REG(p, 0x0c) +#define PVC(p) PORT_CTRL_REG(p, 0x10) +#define PPBV1(p) PORT_CTRL_REG(p, 0x14) +#define PPBV2(p) PORT_CTRL_REG(p, 0x18) +#define BSR(p) PORT_CTRL_REG(p, 0x1c) +#define STAG01 PORT_CTRL_REG(p, 0x20) +#define STAG23 PORT_CTRL_REG(p, 0x24) +#define STAG45 PORT_CTRL_REG(p, 0x28) +#define STAG67 PORT_CTRL_REG(p, 0x2c) + +#define PPBV(p, g) (PPBV1(p) + ((g) / 2) * 4) + +/* Fields of PCR */ +#define MLDV2_EN BIT(30) +#define EG_TAG_S 28 +#define EG_TAG_M 0x30000000 +#define PORT_PRI_S 24 +#define PORT_PRI_M 0x7000000 +#define PORT_MATRIX_S 16 +#define PORT_MATRIX_M 0xff0000 +#define UP2DSCP_EN BIT(12) +#define UP2TAG_EN BIT(11) +#define ACL_EN BIT(10) +#define PORT_TX_MIR BIT(9) +#define PORT_RX_MIR BIT(8) +#define ACL_MIR BIT(7) +#define MIS_PORT_FW_S 4 +#define MIS_PORT_FW_M 0x70 +#define VLAN_MIS BIT(2) +#define PORT_VLAN_S 0 +#define PORT_VLAN_M 0x03 + +/* Values of PORT_VLAN */ +#define PORT_MATRIX_MODE 0 +#define FALLBACK_MODE 1 +#define CHECK_MODE 2 +#define SECURITY_MODE 3 + +/* Fields of PVC */ +#define STAG_VPID_S 16 +#define STAG_VPID_M 0xffff0000 +#define DIS_PVID BIT(15) +#define FORCE_PVID BIT(14) +#define PT_VPM BIT(12) +#define PT_OPTION BIT(11) +#define PVC_EG_TAG_S 8 +#define PVC_EG_TAG_M 0x700 +#define VLAN_ATTR_S 6 +#define VLAN_ATTR_M 0xc0 +#define PVC_PORT_STAG BIT(5) +#define BC_LKYV_EN BIT(4) +#define MC_LKYV_EN BIT(3) +#define UC_LKYV_EN BIT(2) +#define ACC_FRM_S 0 +#define ACC_FRM_M 0x03 + +/* Values of VLAN_ATTR */ +#define VA_USER_PORT 0 +#define VA_STACK_PORT 1 +#define VA_TRANSLATION_PORT 2 +#define VA_TRANSPARENT_PORT 3 + +/* Fields of PPBV */ +#define GRP_PORT_PRI_S(g) (((g) % 2) * 16 + 13) +#define GRP_PORT_PRI_M 0x07 +#define GRP_PORT_VID_S(g) (((g) % 2) * 16) +#define GRP_PORT_VID_M 0xfff + +#define PORT_MAC_CTRL_BASE 0x3000 +#define PORT_MAC_CTRL_PORT_OFFSET 0x100 +#define PORT_MAC_CTRL_REG(p, r) (PORT_MAC_CTRL_BASE + \ + (p) * PORT_MAC_CTRL_PORT_OFFSET + (r)) +#define PMCR(p) PORT_MAC_CTRL_REG(p, 0x00) +#define PMEEECR(p) PORT_MAC_CTRL_REG(p, 0x04) +#define PMSR(p) PORT_MAC_CTRL_REG(p, 0x08) +#define PINT_EN(p) PORT_MAC_CTRL_REG(p, 0x10) +#define PINT_STS(p) PORT_MAC_CTRL_REG(p, 0x14) + +#define GMACCR (PORT_MAC_CTRL_BASE + 0xe0) +#define TXCRC_EN BIT(19) +#define RXCRC_EN BIT(18) +#define PRMBL_LMT_EN BIT(17) +#define MTCC_LMT_S 9 +#define MTCC_LMT_M 0x1e00 +#define MAX_RX_JUMBO_S 2 +#define MAX_RX_JUMBO_M 0x3c +#define MAX_RX_PKT_LEN_S 0 +#define MAX_RX_PKT_LEN_M 0x3 + +/* Values of MAX_RX_PKT_LEN */ +#define RX_PKT_LEN_1518 0 +#define RX_PKT_LEN_1536 1 +#define RX_PKT_LEN_1522 2 +#define RX_PKT_LEN_MAX_JUMBO 3 + +/* Fields of PMCR */ +#define IPG_CFG_S 18 +#define IPG_CFG_M 0xc0000 +#define EXT_PHY BIT(17) +#define MAC_MODE BIT(16) +#define MAC_TX_EN BIT(14) +#define MAC_RX_EN BIT(13) +#define MAC_PRE BIT(11) +#define BKOFF_EN BIT(9) +#define BACKPR_EN BIT(8) +#define FORCE_EEE1G BIT(7) +#define FORCE_EEE1000 BIT(6) +#define FORCE_RX_FC BIT(5) +#define FORCE_TX_FC BIT(4) +#define FORCE_SPD_S 2 +#define FORCE_SPD_M 0x0c +#define FORCE_DPX BIT(1) +#define FORCE_LINK BIT(0) + +/* Fields of PMSR */ +#define EEE1G_STS BIT(7) +#define EEE100_STS BIT(6) +#define RX_FC_STS BIT(5) +#define TX_FC_STS BIT(4) +#define MAC_SPD_STS_S 2 +#define MAC_SPD_STS_M 0x0c +#define MAC_DPX_STS BIT(1) +#define MAC_LNK_STS BIT(0) + +/* Values of MAC_SPD_STS */ +#define MAC_SPD_10 0 +#define MAC_SPD_100 1 +#define MAC_SPD_1000 2 +#define MAC_SPD_2500 3 + +/* Values of IPG_CFG */ +#define IPG_96BIT 0 +#define IPG_96BIT_WITH_SHORT_IPG 1 +#define IPG_64BIT 2 + +#define MIB_COUNTER_BASE 0x4000 +#define MIB_COUNTER_PORT_OFFSET 0x100 +#define MIB_COUNTER_REG(p, r) (MIB_COUNTER_BASE + \ + (p) * MIB_COUNTER_PORT_OFFSET + (r)) +#define STATS_TDPC 0x00 +#define STATS_TCRC 0x04 +#define STATS_TUPC 0x08 +#define STATS_TMPC 0x0C +#define STATS_TBPC 0x10 +#define STATS_TCEC 0x14 +#define STATS_TSCEC 0x18 +#define STATS_TMCEC 0x1C +#define STATS_TDEC 0x20 +#define STATS_TLCEC 0x24 +#define STATS_TXCEC 0x28 +#define STATS_TPPC 0x2C +#define STATS_TL64PC 0x30 +#define STATS_TL65PC 0x34 +#define STATS_TL128PC 0x38 +#define STATS_TL256PC 0x3C +#define STATS_TL512PC 0x40 +#define STATS_TL1024PC 0x44 +#define STATS_TOC 0x48 +#define STATS_RDPC 0x60 +#define STATS_RFPC 0x64 +#define STATS_RUPC 0x68 +#define STATS_RMPC 0x6C +#define STATS_RBPC 0x70 +#define STATS_RAEPC 0x74 +#define STATS_RCEPC 0x78 +#define STATS_RUSPC 0x7C +#define STATS_RFEPC 0x80 +#define STATS_ROSPC 0x84 +#define STATS_RJEPC 0x88 +#define STATS_RPPC 0x8C +#define STATS_RL64PC 0x90 +#define STATS_RL65PC 0x94 +#define STATS_RL128PC 0x98 +#define STATS_RL256PC 0x9C +#define STATS_RL512PC 0xA0 +#define STATS_RL1024PC 0xA4 +#define STATS_ROC 0xA8 +#define STATS_RDPC_CTRL 0xB0 +#define STATS_RDPC_ING 0xB4 +#define STATS_RDPC_ARL 0xB8 + +#define SYS_CTRL 0x7000 +#define SW_PHY_RST BIT(2) +#define SW_SYS_RST BIT(1) +#define SW_REG_RST BIT(0) + +#define SYS_INT_EN 0x7008 +#define SYS_INT_STS 0x700c +#define MAC_PC_INT BIT(16) +#define PHY_INT(p) BIT((p) + 8) +#define PHY_LC_INT(p) BIT(p) + +#define PHY_IAC 0x701c +#define PHY_ACS_ST BIT(31) +#define MDIO_REG_ADDR_S 25 +#define MDIO_REG_ADDR_M 0x3e000000 +#define MDIO_PHY_ADDR_S 20 +#define MDIO_PHY_ADDR_M 0x1f00000 +#define MDIO_CMD_S 18 +#define MDIO_CMD_M 0xc0000 +#define MDIO_ST_S 16 +#define MDIO_ST_M 0x30000 +#define MDIO_RW_DATA_S 0 +#define MDIO_RW_DATA_M 0xffff + +/* MDIO_CMD: MDIO commands */ +#define MDIO_CMD_ADDR 0 +#define MDIO_CMD_WRITE 1 +#define MDIO_CMD_READ 2 +#define MDIO_CMD_READ_C45 3 + +/* MDIO_ST: MDIO start field */ +#define MDIO_ST_C45 0 +#define MDIO_ST_C22 1 + +#define HWSTRAP 0x7800 +#define MHWSTRAP 0x7804 + +#endif /* _MT753X_REGS_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c new file mode 100755 index 00000000..342ad576 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c @@ -0,0 +1,510 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mt753x.h" +#include "mt753x_swconfig.h" +#include "mt753x_regs.h" + +#define MT753X_PORT_MIB_TXB_ID 18 /* TxByte */ +#define MT753X_PORT_MIB_RXB_ID 37 /* RxByte */ + +#define MIB_DESC(_s, _o, _n) \ + { \ + .size = (_s), \ + .offset = (_o), \ + .name = (_n), \ + } + +struct mt753x_mib_desc { + unsigned int size; + unsigned int offset; + const char *name; +}; + +static const struct mt753x_mib_desc mt753x_mibs[] = { + MIB_DESC(1, STATS_TDPC, "TxDrop"), + MIB_DESC(1, STATS_TCRC, "TxCRC"), + MIB_DESC(1, STATS_TUPC, "TxUni"), + MIB_DESC(1, STATS_TMPC, "TxMulti"), + MIB_DESC(1, STATS_TBPC, "TxBroad"), + MIB_DESC(1, STATS_TCEC, "TxCollision"), + MIB_DESC(1, STATS_TSCEC, "TxSingleCol"), + MIB_DESC(1, STATS_TMCEC, "TxMultiCol"), + MIB_DESC(1, STATS_TDEC, "TxDefer"), + MIB_DESC(1, STATS_TLCEC, "TxLateCol"), + MIB_DESC(1, STATS_TXCEC, "TxExcCol"), + MIB_DESC(1, STATS_TPPC, "TxPause"), + MIB_DESC(1, STATS_TL64PC, "Tx64Byte"), + MIB_DESC(1, STATS_TL65PC, "Tx65Byte"), + MIB_DESC(1, STATS_TL128PC, "Tx128Byte"), + MIB_DESC(1, STATS_TL256PC, "Tx256Byte"), + MIB_DESC(1, STATS_TL512PC, "Tx512Byte"), + MIB_DESC(1, STATS_TL1024PC, "Tx1024Byte"), + MIB_DESC(2, STATS_TOC, "TxByte"), + MIB_DESC(1, STATS_RDPC, "RxDrop"), + MIB_DESC(1, STATS_RFPC, "RxFiltered"), + MIB_DESC(1, STATS_RUPC, "RxUni"), + MIB_DESC(1, STATS_RMPC, "RxMulti"), + MIB_DESC(1, STATS_RBPC, "RxBroad"), + MIB_DESC(1, STATS_RAEPC, "RxAlignErr"), + MIB_DESC(1, STATS_RCEPC, "RxCRC"), + MIB_DESC(1, STATS_RUSPC, "RxUnderSize"), + MIB_DESC(1, STATS_RFEPC, "RxFragment"), + MIB_DESC(1, STATS_ROSPC, "RxOverSize"), + MIB_DESC(1, STATS_RJEPC, "RxJabber"), + MIB_DESC(1, STATS_RPPC, "RxPause"), + MIB_DESC(1, STATS_RL64PC, "Rx64Byte"), + MIB_DESC(1, STATS_RL65PC, "Rx65Byte"), + MIB_DESC(1, STATS_RL128PC, "Rx128Byte"), + MIB_DESC(1, STATS_RL256PC, "Rx256Byte"), + MIB_DESC(1, STATS_RL512PC, "Rx512Byte"), + MIB_DESC(1, STATS_RL1024PC, "Rx1024Byte"), + MIB_DESC(2, STATS_ROC, "RxByte"), + MIB_DESC(1, STATS_RDPC_CTRL, "RxCtrlDrop"), + MIB_DESC(1, STATS_RDPC_ING, "RxIngDrop"), + MIB_DESC(1, STATS_RDPC_ARL, "RxARLDrop") +}; + +enum { + /* Global attributes. */ + MT753X_ATTR_ENABLE_VLAN, +}; + +static int mt753x_get_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + val->value.i = gsw->global_vlan_enable; + + return 0; +} + +static int mt753x_set_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + gsw->global_vlan_enable = val->value.i != 0; + + return 0; +} + +static int mt753x_get_port_pvid(struct switch_dev *dev, int port, int *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (port >= MT753X_NUM_PORTS) + return -EINVAL; + + *val = mt753x_reg_read(gsw, PPBV1(port)); + *val &= GRP_PORT_VID_M; + + return 0; +} + +static int mt753x_set_port_pvid(struct switch_dev *dev, int port, int pvid) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (port >= MT753X_NUM_PORTS) + return -EINVAL; + + if (pvid < MT753X_MIN_VID || pvid > MT753X_MAX_VID) + return -EINVAL; + + gsw->port_entries[port].pvid = pvid; + + return 0; +} + +static int mt753x_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + u32 member; + u32 etags; + int i; + + val->len = 0; + + if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS) + return -EINVAL; + + mt753x_vlan_ctrl(gsw, VTCR_READ_VLAN_ENTRY, val->port_vlan); + + member = mt753x_reg_read(gsw, VAWD1); + member &= PORT_MEM_M; + member >>= PORT_MEM_S; + + etags = mt753x_reg_read(gsw, VAWD2); + + for (i = 0; i < MT753X_NUM_PORTS; i++) { + struct switch_port *p; + int etag; + + if (!(member & BIT(i))) + continue; + + p = &val->value.ports[val->len++]; + p->id = i; + + etag = (etags >> PORT_ETAG_S(i)) & PORT_ETAG_M; + + if (etag == ETAG_CTRL_TAG) + p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED); + else if (etag != ETAG_CTRL_UNTAG) + dev_info(gsw->dev, + "vlan egress tag control neither untag nor tag.\n"); + } + + return 0; +} + +static int mt753x_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + u8 member = 0; + u8 etags = 0; + int i; + + if (val->port_vlan < 0 || val->port_vlan >= MT753X_NUM_VLANS || + val->len > MT753X_NUM_PORTS) + return -EINVAL; + + for (i = 0; i < val->len; i++) { + struct switch_port *p = &val->value.ports[i]; + + if (p->id >= MT753X_NUM_PORTS) + return -EINVAL; + + member |= BIT(p->id); + + if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) + etags |= BIT(p->id); + } + + gsw->vlan_entries[val->port_vlan].member = member; + gsw->vlan_entries[val->port_vlan].etags = etags; + + return 0; +} + +static int mt753x_set_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + int vlan; + u16 vid; + + vlan = val->port_vlan; + vid = (u16)val->value.i; + + if (vlan < 0 || vlan >= MT753X_NUM_VLANS) + return -EINVAL; + + if (vid < MT753X_MIN_VID || vid > MT753X_MAX_VID) + return -EINVAL; + + gsw->vlan_entries[vlan].vid = vid; + return 0; +} + +static int mt753x_get_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + val->value.i = val->port_vlan; + return 0; +} + +static int mt753x_get_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + u32 speed, pmsr; + + if (port < 0 || port >= MT753X_NUM_PORTS) + return -EINVAL; + + pmsr = mt753x_reg_read(gsw, PMSR(port)); + + link->link = pmsr & MAC_LNK_STS; + link->duplex = pmsr & MAC_DPX_STS; + speed = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S; + + switch (speed) { + case MAC_SPD_10: + link->speed = SWITCH_PORT_SPEED_10; + break; + case MAC_SPD_100: + link->speed = SWITCH_PORT_SPEED_100; + break; + case MAC_SPD_1000: + link->speed = SWITCH_PORT_SPEED_1000; + break; + case MAC_SPD_2500: + /* TODO: swconfig has no support for 2500 now */ + link->speed = SWITCH_PORT_SPEED_UNKNOWN; + break; + } + + return 0; +} + +static int mt753x_set_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ +#ifndef MODULE + if (port >= MT753X_NUM_PHYS) + return -EINVAL; + + return switch_generic_set_link(dev, port, link); +#else + return -ENOTSUPP; +#endif +} + +static u64 get_mib_counter(struct gsw_mt753x *gsw, int i, int port) +{ + unsigned int offset; + u64 lo, hi, hi2; + + offset = mt753x_mibs[i].offset; + + if (mt753x_mibs[i].size == 1) + return mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset)); + + do { + hi = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4)); + lo = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset)); + hi2 = mt753x_reg_read(gsw, MIB_COUNTER_REG(port, offset + 4)); + } while (hi2 != hi); + + return (hi << 32) | lo; +} + +static int mt753x_get_port_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + static char buf[4096]; + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + int i, len = 0; + + if (val->port_vlan >= MT753X_NUM_PORTS) + return -EINVAL; + + len += snprintf(buf + len, sizeof(buf) - len, + "Port %d MIB counters\n", val->port_vlan); + + for (i = 0; i < ARRAY_SIZE(mt753x_mibs); ++i) { + u64 counter; + + len += snprintf(buf + len, sizeof(buf) - len, + "%-11s: ", mt753x_mibs[i].name); + counter = get_mib_counter(gsw, i, val->port_vlan); + len += snprintf(buf + len, sizeof(buf) - len, "%llu\n", + counter); + } + + val->value.s = buf; + val->len = len; + return 0; +} + +static int mt753x_get_port_stats(struct switch_dev *dev, int port, + struct switch_port_stats *stats) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (port < 0 || port >= MT753X_NUM_PORTS) + return -EINVAL; + + stats->tx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_TXB_ID, port); + stats->rx_bytes = get_mib_counter(gsw, MT753X_PORT_MIB_RXB_ID, port); + + return 0; +} + +static void mt753x_port_isolation(struct gsw_mt753x *gsw) +{ + int i; + + for (i = 0; i < MT753X_NUM_PORTS; i++) + mt753x_reg_write(gsw, PCR(i), + BIT(gsw->cpu_port) << PORT_MATRIX_S); + + mt753x_reg_write(gsw, PCR(gsw->cpu_port), PORT_MATRIX_M); + + for (i = 0; i < MT753X_NUM_PORTS; i++) + mt753x_reg_write(gsw, PVC(i), + (0x8100 << STAG_VPID_S) | + (VA_TRANSPARENT_PORT << VLAN_ATTR_S)); +} + +static int mt753x_apply_config(struct switch_dev *dev) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + if (!gsw->global_vlan_enable) { + mt753x_port_isolation(gsw); + return 0; + } + + mt753x_apply_vlan_config(gsw); + + return 0; +} + +static int mt753x_reset_switch(struct switch_dev *dev) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + int i; + + memset(gsw->port_entries, 0, sizeof(gsw->port_entries)); + memset(gsw->vlan_entries, 0, sizeof(gsw->vlan_entries)); + + /* set default vid of each vlan to the same number of vlan, so the vid + * won't need be set explicitly. + */ + for (i = 0; i < MT753X_NUM_VLANS; i++) + gsw->vlan_entries[i].vid = i; + + return 0; +} + +static int mt753x_phy_read16(struct switch_dev *dev, int addr, u8 reg, + u16 *value) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + *value = gsw->mii_read(gsw, addr, reg); + + return 0; +} + +static int mt753x_phy_write16(struct switch_dev *dev, int addr, u8 reg, + u16 value) +{ + struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); + + gsw->mii_write(gsw, addr, reg, value); + + return 0; +} + +static const struct switch_attr mt753x_global[] = { + { + .type = SWITCH_TYPE_INT, + .name = "enable_vlan", + .description = "VLAN mode (1:enabled)", + .max = 1, + .id = MT753X_ATTR_ENABLE_VLAN, + .get = mt753x_get_vlan_enable, + .set = mt753x_set_vlan_enable, + } +}; + +static const struct switch_attr mt753x_port[] = { + { + .type = SWITCH_TYPE_STRING, + .name = "mib", + .description = "Get MIB counters for port", + .get = mt753x_get_port_mib, + .set = NULL, + }, +}; + +static const struct switch_attr mt753x_vlan[] = { + { + .type = SWITCH_TYPE_INT, + .name = "vid", + .description = "VLAN ID (0-4094)", + .set = mt753x_set_vid, + .get = mt753x_get_vid, + .max = 4094, + }, +}; + +static const struct switch_dev_ops mt753x_swdev_ops = { + .attr_global = { + .attr = mt753x_global, + .n_attr = ARRAY_SIZE(mt753x_global), + }, + .attr_port = { + .attr = mt753x_port, + .n_attr = ARRAY_SIZE(mt753x_port), + }, + .attr_vlan = { + .attr = mt753x_vlan, + .n_attr = ARRAY_SIZE(mt753x_vlan), + }, + .get_vlan_ports = mt753x_get_vlan_ports, + .set_vlan_ports = mt753x_set_vlan_ports, + .get_port_pvid = mt753x_get_port_pvid, + .set_port_pvid = mt753x_set_port_pvid, + .get_port_link = mt753x_get_port_link, + .set_port_link = mt753x_set_port_link, + .get_port_stats = mt753x_get_port_stats, + .apply_config = mt753x_apply_config, + .reset_switch = mt753x_reset_switch, + .phy_read16 = mt753x_phy_read16, + .phy_write16 = mt753x_phy_write16, +}; + +int mt753x_swconfig_init(struct gsw_mt753x *gsw) +{ + struct device_node *np = gsw->dev->of_node; + struct switch_dev *swdev; + int ret; + + if (of_property_read_u32(np, "mediatek,cpuport", &gsw->cpu_port)) + gsw->cpu_port = MT753X_DFL_CPU_PORT; + + swdev = &gsw->swdev; + + swdev->name = gsw->name; + swdev->alias = gsw->name; + swdev->cpu_port = gsw->cpu_port; + swdev->ports = MT753X_NUM_PORTS; + swdev->vlans = MT753X_NUM_VLANS; + swdev->ops = &mt753x_swdev_ops; + + ret = register_switch(swdev, NULL); + if (ret) { + dev_notice(gsw->dev, "Failed to register switch %s\n", + swdev->name); + return ret; + } + + mt753x_apply_config(swdev); + + return 0; +} + +void mt753x_swconfig_destroy(struct gsw_mt753x *gsw) +{ + unregister_switch(&gsw->swdev); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h new file mode 100755 index 00000000..f000364e --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MT753X_SWCONFIG_H_ +#define _MT753X_SWCONFIG_H_ + +#ifdef CONFIG_SWCONFIG +#include +#include "mt753x.h" + +int mt753x_swconfig_init(struct gsw_mt753x *gsw); +void mt753x_swconfig_destroy(struct gsw_mt753x *gsw); +#else +static inline int mt753x_swconfig_init(struct gsw_mt753x *gsw) +{ + mt753x_apply_vlan_config(gsw); + + return 0; +} + +static inline void mt753x_swconfig_destroy(struct gsw_mt753x *gsw) +{ +} +#endif + +#endif /* _MT753X_SWCONFIG_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.c new file mode 100755 index 00000000..4d88eee8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#include "mt753x.h" +#include "mt753x_regs.h" + +struct mt753x_mapping mt753x_def_mapping[] = { + { + .name = "llllw", + .pvids = { 1, 1, 1, 1, 2, 2, 1 }, + .members = { 0, 0x4f, 0x30 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, { + .name = "wllll", + .pvids = { 2, 1, 1, 1, 1, 2, 1 }, + .members = { 0, 0x5e, 0x21 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, { + .name = "lwlll", + .pvids = { 1, 2, 1, 1, 1, 2, 1 }, + .members = { 0, 0x5d, 0x22 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, +}; + +void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val) +{ + int i; + + mt753x_reg_write(gsw, VTCR, + VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) | + (val & VTCR_VID_M)); + + for (i = 0; i < 300; i++) { + u32 val = mt753x_reg_read(gsw, VTCR); + + if ((val & VTCR_BUSY) == 0) + break; + + usleep_range(1000, 1100); + } + + if (i == 300) + dev_info(gsw->dev, "vtcr timeout\n"); +} + +static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid, + u8 ports, u8 etags) +{ + int port; + u32 val; + + /* vlan port membership */ + if (ports) + mt753x_reg_write(gsw, VAWD1, + IVL_MAC | VTAG_EN | VENTRY_VALID | + ((ports << PORT_MEM_S) & PORT_MEM_M)); + else + mt753x_reg_write(gsw, VAWD1, 0); + + /* egress mode */ + val = 0; + for (port = 0; port < MT753X_NUM_PORTS; port++) { + if (etags & BIT(port)) + val |= ETAG_CTRL_TAG << PORT_ETAG_S(port); + else + val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port); + } + mt753x_reg_write(gsw, VAWD2, val); + + /* write to vlan table */ + mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid); +} + +void mt753x_apply_vlan_config(struct gsw_mt753x *gsw) +{ + int i, j; + u8 tag_ports; + u8 untag_ports; + + /* set all ports as security mode */ + for (i = 0; i < MT753X_NUM_PORTS; i++) + mt753x_reg_write(gsw, PCR(i), + PORT_MATRIX_M | SECURITY_MODE); + + /* check if a port is used in tag/untag vlan egress mode */ + tag_ports = 0; + untag_ports = 0; + + for (i = 0; i < MT753X_NUM_VLANS; i++) { + u8 member = gsw->vlan_entries[i].member; + u8 etags = gsw->vlan_entries[i].etags; + + if (!member) + continue; + + for (j = 0; j < MT753X_NUM_PORTS; j++) { + if (!(member & BIT(j))) + continue; + + if (etags & BIT(j)) + tag_ports |= 1u << j; + else + untag_ports |= 1u << j; + } + } + + /* set all untag-only ports as transparent and the rest as user port */ + for (i = 0; i < MT753X_NUM_PORTS; i++) { + u32 pvc_mode = 0x8100 << STAG_VPID_S; + + if (untag_ports & BIT(i) && !(tag_ports & BIT(i))) + pvc_mode = (0x8100 << STAG_VPID_S) | + (VA_TRANSPARENT_PORT << VLAN_ATTR_S); + + mt753x_reg_write(gsw, PVC(i), pvc_mode); + } + + /* first clear the switch vlan table */ + for (i = 0; i < MT753X_NUM_VLANS; i++) + mt753x_write_vlan_entry(gsw, i, i, 0, 0); + + /* now program only vlans with members to avoid + * clobbering remapped entries in later iterations + */ + for (i = 0; i < MT753X_NUM_VLANS; i++) { + u16 vid = gsw->vlan_entries[i].vid; + u8 member = gsw->vlan_entries[i].member; + u8 etags = gsw->vlan_entries[i].etags; + + if (member) + mt753x_write_vlan_entry(gsw, i, vid, member, etags); + } + + /* Port Default PVID */ + for (i = 0; i < MT753X_NUM_PORTS; i++) { + int vlan = gsw->port_entries[i].pvid; + u16 pvid = 0; + u32 val; + + if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member) + pvid = gsw->vlan_entries[vlan].vid; + + val = mt753x_reg_read(gsw, PPBV1(i)); + val &= ~GRP_PORT_VID_M; + val |= pvid; + mt753x_reg_write(gsw, PPBV1(i), val); + } +} + +struct mt753x_mapping *mt753x_find_mapping(struct device_node *np) +{ + const char *map; + int i; + + if (of_property_read_string(np, "mediatek,portmap", &map)) + return NULL; + + for (i = 0; i < ARRAY_SIZE(mt753x_def_mapping); i++) + if (!strcmp(map, mt753x_def_mapping[i].name)) + return &mt753x_def_mapping[i]; + + return NULL; +} + +void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map) +{ + int i = 0; + + for (i = 0; i < MT753X_NUM_PORTS; i++) + gsw->port_entries[i].pvid = map->pvids[i]; + + for (i = 0; i < MT753X_NUM_VLANS; i++) { + gsw->vlan_entries[i].member = map->members[i]; + gsw->vlan_entries[i].etags = map->etags[i]; + gsw->vlan_entries[i].vid = map->vids[i]; + } +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.h new file mode 100755 index 00000000..c726b8ea --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/mtk/mt753x/mt753x_vlan.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#ifndef _MT753X_VLAN_H_ +#define _MT753X_VLAN_H_ + +#define MT753X_NUM_PORTS 7 +#define MT753X_NUM_VLANS 4095 +#define MT753X_MAX_VID 4095 +#define MT753X_MIN_VID 0 + +struct gsw_mt753x; + +struct mt753x_port_entry { + u16 pvid; +}; + +struct mt753x_vlan_entry { + u16 vid; + u8 member; + u8 etags; +}; + +struct mt753x_mapping { + char *name; + u16 pvids[MT753X_NUM_PORTS]; + u8 members[MT753X_NUM_VLANS]; + u8 etags[MT753X_NUM_VLANS]; + u16 vids[MT753X_NUM_VLANS]; +}; + +extern struct mt753x_mapping mt753x_defaults[]; + +void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val); +void mt753x_apply_vlan_config(struct gsw_mt753x *gsw); +struct mt753x_mapping *mt753x_find_mapping(struct device_node *np); +void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map); +#endif /* _MT753X_VLAN_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/Makefile b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/Makefile new file mode 100755 index 00000000..0f2891ea --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/Makefile @@ -0,0 +1,66 @@ +obj-$(CONFIG_RTL8367S_GSW) += rtl8367s_gsw.o +rtl8367s_gsw-objs := rtl8367s_mdio.o rtl8367s_dbg.o +ifeq ($(CONFIG_SWCONFIG),y) +rtl8367s_gsw-objs += rtl8367s.o +endif +rtl8367s_gsw-objs += rtl8367c/acl.o +rtl8367s_gsw-objs += rtl8367c/cpu.o +rtl8367s_gsw-objs += rtl8367c/dot1x.o +rtl8367s_gsw-objs += rtl8367c/eee.o +rtl8367s_gsw-objs += rtl8367c/igmp.o +rtl8367s_gsw-objs += rtl8367c/interrupt.o +rtl8367s_gsw-objs += rtl8367c/l2.o +rtl8367s_gsw-objs += rtl8367c/leaky.o +rtl8367s_gsw-objs += rtl8367c/led.o +rtl8367s_gsw-objs += rtl8367c/mirror.o +rtl8367s_gsw-objs += rtl8367c/oam.o +rtl8367s_gsw-objs += rtl8367c/port.o +rtl8367s_gsw-objs += rtl8367c/ptp.o +rtl8367s_gsw-objs += rtl8367c/qos.o +rtl8367s_gsw-objs += rtl8367c/rate.o +rtl8367s_gsw-objs += rtl8367c/rldp.o +rtl8367s_gsw-objs += rtl8367c/rtk_switch.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_acl.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_cputag.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_dot1x.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eav.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eee.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_fc.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_green.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_hsb.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_igmp.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_inbwctrl.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_interrupt.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_led.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_lut.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_meter.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mib.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mirror.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_misc.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_oam.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_phy.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_port.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_portIsolation.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_qos.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rldp.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rma.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_scheduling.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_storm.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_svlan.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_trunking.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_unknownMulticast.o +rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_vlan.o +rtl8367s_gsw-objs += rtl8367c/smi.o +rtl8367s_gsw-objs += rtl8367c/stat.o +rtl8367s_gsw-objs += rtl8367c/storm.o +rtl8367s_gsw-objs += rtl8367c/svlan.o +rtl8367s_gsw-objs += rtl8367c/trap.o +rtl8367s_gsw-objs += rtl8367c/trunk.o +rtl8367s_gsw-objs += rtl8367c/vlan.o + +ccflags-y += -Werror -D_LITTLE_ENDIAN -DMDC_MDIO_OPERATION + +ccflags-y += -Idrivers/net/phy/rtk/rtl8367c/include +ccflags-y += -Iinclude/linux/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/modules.builtin b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/modules.builtin new file mode 100755 index 00000000..961a70a1 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/modules.builtin @@ -0,0 +1 @@ +kernel/drivers/net/phy/rtk/rtl8367s_gsw.ko diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/acl.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/acl.c new file mode 100755 index 00000000..75e5a5e7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/acl.c @@ -0,0 +1,2061 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in ACL module. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +CONST_T rtk_uint8 filter_templateField[RTL8367C_ACLTEMPLATENO][RTL8367C_ACLRULEFIELDNO] = { + {ACL_DMAC0, ACL_DMAC1, ACL_DMAC2, ACL_SMAC0, ACL_SMAC1, ACL_SMAC2, ACL_ETHERTYPE, ACL_FIELD_SELECT15}, + {ACL_IP4SIP0, ACL_IP4SIP1, ACL_IP4DIP0, ACL_IP4DIP1, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT02, ACL_FIELD_SELECT15}, + {ACL_IP6SIP0WITHIPV4, ACL_IP6SIP1WITHIPV4,ACL_FIELD_SELECT03, ACL_FIELD_SELECT04, ACL_FIELD_SELECT05, ACL_FIELD_SELECT06, ACL_FIELD_SELECT07, ACL_FIELD_SELECT08}, + {ACL_IP6DIP0WITHIPV4, ACL_IP6DIP1WITHIPV4,ACL_FIELD_SELECT09, ACL_FIELD_SELECT10, ACL_FIELD_SELECT11, ACL_FIELD_SELECT12, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14}, + {ACL_VIDRANGE, ACL_IPRANGE, ACL_PORTRANGE, ACL_CTAG, ACL_STAG, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT15} +}; + +CONST_T rtk_uint8 filter_advanceCaretagField[RTL8367C_ACLTEMPLATENO][2] = { + {TRUE, 7}, + {TRUE, 7}, + {FALSE, 0}, + {FALSE, 0}, + {TRUE, 7}, +}; + + +CONST_T rtk_uint8 filter_fieldTemplateIndex[FILTER_FIELD_END][RTK_FILTER_FIELD_USED_MAX] = { + {0x00, 0x01,0x02}, + {0x03, 0x04,0x05}, + {0x06}, + {0x43}, + {0x44}, + {0x10, 0x11}, + {0x12, 0x13}, + {0x24}, + {0x25}, + {0x35}, + {0x35}, + {0x20, 0x21,0x22,0x23}, + {0x30, 0x31,0x32,0x33}, + {0x26}, + {0x27}, + {0x14}, + {0x15}, + {0x16}, + {0x14}, + {0x15}, + {0x14}, + {0x14}, + {0x14}, + + {0x40}, + {0x41}, + {0x42}, + + {0x14}, + {0x15}, + {0x16}, + {0x22}, + {0x23}, + {0x24}, + {0x25}, + {0x26}, + {0x27}, + {0x32}, + {0x33}, + {0x34}, + {0x35}, + {0x36}, + {0x37}, + {0x47}, + + {0xFF} /* Pattern Match */ +}; + +CONST_T rtk_uint8 filter_fieldSize[FILTER_FIELD_END] = { + 3, 3, 1, 1, 1, + 2, 2, 1, 1, 1, 1, 4, 4, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8 +}; + +CONST_T rtk_uint16 field_selector[RTL8367C_FIELDSEL_FORMAT_NUMBER][2] = +{ + {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 0 */ + {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 1 */ + {FIELDSEL_FORMAT_IPPAYLOAD, 12}, /* Field Selector 2 */ + {FIELDSEL_FORMAT_IPV6, 10}, /* Field Selector 3 */ + {FIELDSEL_FORMAT_IPV6, 8}, /* Field Selector 4 */ + {FIELDSEL_FORMAT_IPV4, 0}, /* Field Selector 5 */ + {FIELDSEL_FORMAT_IPV4, 8}, /* Field Selector 6 */ + {FIELDSEL_FORMAT_IPV6, 0}, /* Field Selector 7 */ + {FIELDSEL_FORMAT_IPV6, 6}, /* Field Selector 8 */ + {FIELDSEL_FORMAT_IPV6, 26}, /* Field Selector 9 */ + {FIELDSEL_FORMAT_IPV6, 24}, /* Field Selector 10 */ + {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 11 */ + {FIELDSEL_FORMAT_IPV4, 6}, /* Field Selector 12 */ + {FIELDSEL_FORMAT_IPPAYLOAD, 0}, /* Field Selector 13 */ + {FIELDSEL_FORMAT_IPPAYLOAD, 2}, /* Field Selector 14 */ + {FIELDSEL_FORMAT_DEFAULT, 0} /* Field Selector 15 */ +}; + + +static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr); + + +/* Function Name: + * rtk_filter_igrAcl_init + * Description: + * ACL initialization function + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * Note: + * This function enable and intialize ACL function + */ +rtk_api_ret_t rtk_filter_igrAcl_init(void) +{ + rtl8367c_acltemplate_t aclTemp; + rtk_uint32 i, j; + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((ret = rtk_filter_igrAcl_cfg_delAll()) != RT_ERR_OK) + return ret; + + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + for(j = 0; j < RTL8367C_ACLRULEFIELDNO;j++) + aclTemp.field[j] = filter_templateField[i][j]; + + if ((ret = rtl8367c_setAsicAclTemplate(i, &aclTemp)) != RT_ERR_OK) + return ret; + } + + for(i = 0; i < RTL8367C_FIELDSEL_FORMAT_NUMBER; i++) + { + if ((ret = rtl8367c_setAsicFieldSelector(i, field_selector[i][0], field_selector[i][1])) != RT_ERR_OK) + return ret; + } + + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((ret = rtl8367c_setAsicAcl(i, TRUE)) != RT_ERR_OK) + return ret; + + if ((ret = rtl8367c_setAsicAclUnmatchedPermit(i, TRUE)) != RT_ERR_OK) + return ret; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_field_add + * Description: + * Add comparison rule to an ACL configuration + * Input: + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_field - The comparison rule that will be added. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg). + * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL + * comparison rules by means of linked list. Pointer pFilter_field will be added to linked + * list keeped by structure that pFilter_cfg points to. + */ +rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t* pFilter_cfg, rtk_filter_field_t* pFilter_field) +{ + rtk_uint32 i; + rtk_filter_field_t *tailPtr; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pFilter_cfg || NULL == pFilter_field) + return RT_ERR_NULL_POINTER; + + if(pFilter_field->fieldType >= FILTER_FIELD_END) + return RT_ERR_ENTRY_INDEX; + + + if(0 == pFilter_field->fieldTemplateNo) + { + pFilter_field->fieldTemplateNo = filter_fieldSize[pFilter_field->fieldType]; + + for(i = 0; i < pFilter_field->fieldTemplateNo; i++) + { + pFilter_field->fieldTemplateIdx[i] = filter_fieldTemplateIndex[pFilter_field->fieldType][i]; + } + } + + if(NULL == pFilter_cfg->fieldHead) + { + pFilter_cfg->fieldHead = pFilter_field; + } + else + { + if (pFilter_cfg->fieldHead->next == NULL) + { + pFilter_cfg->fieldHead->next = pFilter_field; + } + else + { + tailPtr = pFilter_cfg->fieldHead->next; + while( tailPtr->next != NULL) + { + tailPtr = tailPtr->next; + } + tailPtr->next = pFilter_field; + } + } + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr) +{ + rtk_uint32 i, tempIdx,fieldIdx, ipValue, ipMask; + rtk_uint32 ip6addr[RTK_IPV6_ADDR_WORD_LENGTH]; + rtk_uint32 ip6mask[RTK_IPV6_ADDR_WORD_LENGTH]; + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + + aclRule[tempIdx].valid = TRUE; + } + + switch (fieldPtr->fieldType) + { + /* use DMAC structure as representative for mac structure */ + case FILTER_FIELD_DMAC: + case FILTER_FIELD_SMAC: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.value.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.value.octet[5 - (i*2 + 1)] << 8); + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.mask.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.mask.octet[5 - (i*2 + 1)] << 8); + } + break; + case FILTER_FIELD_ETHERTYPE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.mask; + } + break; + case FILTER_FIELD_IPV4_SIP: + case FILTER_FIELD_IPV4_DIP: + + ipValue = fieldPtr->filter_pattern_union.sip.value; + ipMask = fieldPtr->filter_pattern_union.sip.mask; + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = (0xFFFF & (ipValue >> (i*16))); + aclRule[tempIdx].care_bits.field[fieldIdx] = (0xFFFF & (ipMask >> (i*16))); + } + break; + case FILTER_FIELD_IPV4_TOS: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.value & 0xFF; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.mask & 0xFF; + } + break; + case FILTER_FIELD_IPV4_PROTOCOL: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.value & 0xFF; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.mask & 0xFF; + } + break; + case FILTER_FIELD_IPV6_SIPV6: + case FILTER_FIELD_IPV6_DIPV6: + for(i = 0; i < RTK_IPV6_ADDR_WORD_LENGTH; i++) + { + ip6addr[i] = fieldPtr->filter_pattern_union.sipv6.value.addr[i]; + ip6mask[i] = fieldPtr->filter_pattern_union.sipv6.mask.addr[i]; + } + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + if(i < 2) + { + aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[0] & (0xFFFF << (i * 16))) >> (i * 16)); + aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[0] & (0xFFFF << (i * 16))) >> (i * 16)); + } + else + { + /*default acl template for ipv6 address supports MSB 32-bits and LSB 32-bits only*/ + aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); + aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); + } + } + + break; + case FILTER_FIELD_CTAG: + case FILTER_FIELD_STAG: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.value << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.value << 12) | fieldPtr->filter_pattern_union.l2tag.vid.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.mask << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.mask << 12) | fieldPtr->filter_pattern_union.l2tag.vid.mask; + } + break; + case FILTER_FIELD_IPV4_FLAG: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x1FFF; + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.value << 15); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.value << 14); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.value << 13); + + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x1FFF; + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.mask << 15); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.mask << 14); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.mask << 13); + } + + break; + case FILTER_FIELD_IPV4_OFFSET: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xE000; + aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.value; + + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xE000; + aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.mask; + } + + break; + + case FILTER_FIELD_IPV6_TRAFFIC_CLASS: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + + aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.value << 4)&0x0FF0; + aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.mask << 4)&0x0FF0; + } + break; + case FILTER_FIELD_IPV6_NEXT_HEADER: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value << 8; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask << 8; + } + break; + case FILTER_FIELD_TCP_SPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.mask; + } + break; + case FILTER_FIELD_TCP_DPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.mask; + } + break; + case FILTER_FIELD_TCP_FLAG: + + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.value << 7); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.value << 6); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.value << 5); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.value << 4); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.value << 3); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.value << 2); + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.value << 1); + aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.value; + + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.mask << 7); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.mask << 6); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.mask << 5); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.mask << 4); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.mask << 3); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.mask << 2); + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.mask << 1); + aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.mask; + } + break; + case FILTER_FIELD_UDP_SPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.mask; + } + break; + case FILTER_FIELD_UDP_DPORT: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.mask; + } + break; + case FILTER_FIELD_ICMP_CODE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xFF00; + aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.value; + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xFF00; + aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.mask; + } + break; + case FILTER_FIELD_ICMP_TYPE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x00FF; + aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.value << 8); + aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x00FF; + aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.mask << 8); + } + break; + case FILTER_FIELD_IGMP_TYPE: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.value << 8); + aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.mask << 8); + } + break; + case FILTER_FIELD_PATTERN_MATCH: + for(i = 0; i < fieldPtr->fieldTemplateNo; i++) + { + tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.value[i/2] >> (16 * (i%2))) & 0x0000FFFF ); + aclRule[tempIdx].care_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.mask[i/2] >> (16 * (i%2))) & 0x0000FFFF ); + } + break; + case FILTER_FIELD_VID_RANGE: + case FILTER_FIELD_IP_RANGE: + case FILTER_FIELD_PORT_RANGE: + default: + tempIdx = (fieldPtr->fieldTemplateIdx[0] & 0xF0) >> 4; + fieldIdx = fieldPtr->fieldTemplateIdx[0] & 0x0F; + + aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value; + aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask; + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_add + * Description: + * Add an ACL configuration to ASIC + * Input: + * filter_id - Start index of ACL configuration. + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_action - Action(s) of ACL configuration. + * Output: + * ruleNum - number of rules written in acl table + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENTRY_INDEX - Invalid filter_id . + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip. + * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported. + * Note: + * This function store pFilter_cfg, pFilter_action into ASIC. The starting + * index(es) is filter_id. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t* pFilter_cfg, rtk_filter_action_t* pFilter_action, rtk_filter_number_t *ruleNum) +{ + rtk_api_ret_t retVal; + rtk_uint32 careTagData, careTagMask; + rtk_uint32 i,vidx, svidx, actType, ruleId; + rtk_uint32 aclActCtrl; + rtk_uint32 cpuPort; + rtk_filter_field_t* fieldPtr; + rtl8367c_aclrule aclRule[RTL8367C_ACLTEMPLATENO]; + rtl8367c_aclrule tempRule; + rtl8367c_acl_act_t aclAct; + rtk_uint32 noRulesAdd; + rtk_uint32 portmask; + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(filter_id > RTL8367C_ACLRULEMAX ) + return RT_ERR_ENTRY_INDEX; + + if((NULL == pFilter_cfg) || (NULL == pFilter_action) || (NULL == ruleNum)) + return RT_ERR_NULL_POINTER; + + fieldPtr = pFilter_cfg->fieldHead; + + /* init RULE */ + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + memset(&aclRule[i], 0, sizeof(rtl8367c_aclrule)); + + aclRule[i].data_bits.type= i; + aclRule[i].care_bits.type= 0x7; + } + + while(NULL != fieldPtr) + { + _rtk_filter_igrAcl_writeDataField(aclRule, fieldPtr); + + fieldPtr = fieldPtr->next; + } + + /*set care tag mask in User Defined Field 15*/ + /*Follow care tag should not be used while ACL template and User defined fields are fully control by system designer*/ + /*those advanced packet type care tag is used in default template design structure only*/ + careTagData = 0; + careTagMask = 0; + + for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) + { + if(pFilter_cfg->careTag.tagType[i].mask) + careTagMask = careTagMask | (1 << (i-CARE_TAG_TCP)); + + if(pFilter_cfg->careTag.tagType[i].value) + careTagData = careTagData | (1 << (i-CARE_TAG_TCP)); + } + + if(careTagData || careTagMask) + { + i = 0; + while(i < RTL8367C_ACLTEMPLATENO) + { + if(aclRule[i].valid == 1 && filter_advanceCaretagField[i][0] == TRUE) + { + + aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; + aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; + break; + } + i++; + } + /*none of previous used template containing field 15*/ + if(i == RTL8367C_ACLTEMPLATENO) + { + i = 0; + while(i < RTL8367C_ACLTEMPLATENO) + { + if(filter_advanceCaretagField[i][0] == TRUE) + { + aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; + aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; + aclRule[i].valid = 1; + break; + } + i++; + } + } + } + + /*Check rule number*/ + noRulesAdd = 0; + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + if(1 == aclRule[i].valid) + { + noRulesAdd ++; + } + } + + *ruleNum = noRulesAdd; + + if((filter_id + noRulesAdd - 1) > RTL8367C_ACLRULEMAX) + { + return RT_ERR_ENTRY_INDEX; + } + + /*set care tag mask in TAG Indicator*/ + careTagData = 0; + careTagMask = 0; + + for(i = 0; i <= CARE_TAG_IPV6;i++) + { + if(0 == pFilter_cfg->careTag.tagType[i].mask ) + { + careTagMask &= ~(1 << i); + } + else + { + careTagMask |= (1 << i); + if(0 == pFilter_cfg->careTag.tagType[i].value ) + careTagData &= ~(1 << i); + else + careTagData |= (1 << i); + } + } + + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + aclRule[i].data_bits.tag_exist = (careTagData) & ACL_RULE_CARETAG_MASK; + aclRule[i].care_bits.tag_exist = (careTagMask) & ACL_RULE_CARETAG_MASK; + } + + RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.value); + RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.mask); + + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + if(TRUE == aclRule[i].valid) + { + if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.value, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + + aclRule[i].data_bits.active_portmsk = portmask; + + if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.mask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + + aclRule[i].care_bits.active_portmsk = portmask; + } + } + + if(pFilter_cfg->invert >= FILTER_INVERT_END ) + return RT_ERR_INPUT; + + + /*Last action gets high priority if actions are the same*/ + memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); + aclActCtrl = 0; + for(actType = 0; actType < FILTER_ENACT_END; actType ++) + { + if(pFilter_action->actEnable[actType]) + { + switch (actType) + { + case FILTER_ENACT_CVLAN_INGRESS: + if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) + { + return retVal; + } + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + aclAct.cvidx_cact = vidx; + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_CVLAN_EGRESS: + if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) + return retVal; + + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + aclAct.cvidx_cact = vidx; + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_CVLAN_SVID: + + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_POLICING_1: + if(pFilter_action->filterPolicingIdx[1] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); + aclAct.cvidx_cact = pFilter_action->filterPolicingIdx[1]; + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; + } + + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + + case FILTER_ENACT_SVLAN_INGRESS: + case FILTER_ENACT_SVLAN_EGRESS: + + if((retVal = rtk_svlan_checkAndCreateMbr(pFilter_action->filterSvlanVid, &svidx)) != RT_ERR_OK) + return retVal; + + aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); + aclAct.svidx_sact = svidx; + aclActCtrl |= FILTER_ENACT_SVLAN_MASK; + break; + case FILTER_ENACT_SVLAN_CVID: + + aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); + aclActCtrl |= FILTER_ENACT_SVLAN_MASK; + break; + case FILTER_ENACT_POLICING_2: + if(pFilter_action->filterPolicingIdx[2] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); + aclAct.svidx_sact = pFilter_action->filterPolicingIdx[2]; + aclActCtrl |= FILTER_ENACT_SVLAN_MASK; + break; + case FILTER_ENACT_POLICING_0: + if(pFilter_action->filterPolicingIdx[0] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.aclmeteridx = pFilter_action->filterPolicingIdx[0]; + aclActCtrl |= FILTER_ENACT_POLICING_MASK; + break; + case FILTER_ENACT_PRIORITY: + case FILTER_ENACT_1P_REMARK: + if(pFilter_action->filterPriority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); + aclAct.pridx = pFilter_action->filterPriority; + aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; + break; + case FILTER_ENACT_DSCP_REMARK: + if(pFilter_action->filterPriority > RTL8367C_DSCPMAX) + return RT_ERR_INPUT; + + aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); + aclAct.pridx = pFilter_action->filterPriority; + aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; + break; + case FILTER_ENACT_POLICING_3: + if(pFilter_action->filterPriority >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) + return RT_ERR_INPUT; + + aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); + aclAct.pridx = pFilter_action->filterPolicingIdx[3]; + aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; + break; + case FILTER_ENACT_DROP: + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_REDIRECT); + aclAct.fwdact_ext = FALSE; + + aclAct.fwdpmask = 0; + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_REDIRECT: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.fwdact_ext = FALSE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + + case FILTER_ENACT_ADD_DSTPORT: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.fwdact_ext = FALSE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_MIRROR: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.cact_ext = FALSE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_TRAP_CPU: + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); + aclAct.fwdact_ext = FALSE; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_COPY_CPU: + if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) + return retVal; + + aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_MIRROR); + aclAct.fwdact_ext = FALSE; + + aclAct.fwdpmask = 1 << cpuPort; + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + case FILTER_ENACT_ISOLATION: + RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); + + aclAct.fwdact_ext = TRUE; + + if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + aclAct.fwdpmask = portmask; + + aclActCtrl |= FILTER_ENACT_FWD_MASK; + break; + + case FILTER_ENACT_INTERRUPT: + + aclAct.aclint = TRUE; + aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; + break; + case FILTER_ENACT_GPO: + + aclAct.gpio_en = TRUE; + aclAct.gpio_pin = pFilter_action->filterPin; + aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_TAG: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_TAG; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_UNTAG: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_UNTAG; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_KEEP: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_KEEP; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + case FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK: + + if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) + { + if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) + aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; + } + else + { + aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; + } + aclAct.tag_fmt = FILTER_CTAGFMT_KEEP1PRMK; + aclActCtrl |= FILTER_ENACT_CVLAN_MASK; + break; + default: + return RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT; + } + } + } + + + /*check if free ACL rules are enough*/ + for(i = filter_id; i < (filter_id + noRulesAdd); i++) + { + if((retVal = rtl8367c_getAsicAclRule(i, &tempRule)) != RT_ERR_OK ) + return retVal; + + if(tempRule.valid == TRUE) + { + return RT_ERR_TBL_FULL; + } + } + + ruleId = 0; + for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) + { + if(aclRule[i].valid == TRUE) + { + /* write ACL action control */ + if((retVal = rtl8367c_setAsicAclActCtrl(filter_id + ruleId, aclActCtrl)) != RT_ERR_OK ) + return retVal; + /* write ACL action */ + if((retVal = rtl8367c_setAsicAclAct(filter_id + ruleId, &aclAct)) != RT_ERR_OK ) + return retVal; + + /* write ACL not */ + if((retVal = rtl8367c_setAsicAclNot(filter_id + ruleId, pFilter_cfg->invert)) != RT_ERR_OK ) + return retVal; + /* write ACL rule */ + if((retVal = rtl8367c_setAsicAclRule(filter_id + ruleId, &aclRule[i])) != RT_ERR_OK ) + return retVal; + + /* only the first rule will be written with input action control, aclActCtrl of other rules will be zero */ + aclActCtrl = 0; + memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); + + ruleId ++; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_del + * Description: + * Delete an ACL configuration from ASIC + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id. + * Note: + * This function delete a group of ACL rules starting from filter_id. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id) +{ + rtl8367c_aclrule initRule; + rtl8367c_acl_act_t initAct; + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(filter_id > RTL8367C_ACLRULEMAX ) + return RT_ERR_FILTER_ENTRYIDX; + + memset(&initRule, 0, sizeof(rtl8367c_aclrule)); + memset(&initAct, 0, sizeof(rtl8367c_acl_act_t)); + + if((ret = rtl8367c_setAsicAclRule(filter_id, &initRule)) != RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclActCtrl(filter_id, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclAct(filter_id, &initAct)) != RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclNot(filter_id, DISABLED)) != RT_ERR_OK ) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_delAll + * Description: + * Delete all ACL entries from ASIC + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function delete all ACL configuration from ASIC. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void) +{ + rtk_uint32 i; + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + for(i = 0; i < RTL8367C_ACLRULENO; i++) + { + if((ret = rtl8367c_setAsicAclActCtrl(i, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) + return ret; + if((ret = rtl8367c_setAsicAclNot(i, DISABLED)) != RT_ERR_OK ) + return ret; + } + + return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_RESET_CFG, RTL8367C_ACL_RESET_CFG_OFFSET, TRUE);; +} + +/* Function Name: + * rtk_filter_igrAcl_cfg_get + * Description: + * Get one ingress acl configuration from ASIC. + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * pFilter_cfg - buffer pointer of ingress acl data + * pFilter_action - buffer pointer of ingress acl action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_ENTRYIDX - Invalid entry index. + * Note: + * This function get configuration from ASIC. + */ +rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, tmp; + rtl8367c_aclrule aclRule; + rtl8367c_acl_act_t aclAct; + rtk_uint32 cpuPort; + rtl8367c_acltemplate_t type; + rtl8367c_svlan_memconf_t svlan_cfg; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 phyPmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pFilter_cfg || NULL == pAction) + return RT_ERR_NULL_POINTER; + + if(filter_id > RTL8367C_ACLRULEMAX) + return RT_ERR_ENTRY_INDEX; + + if ((retVal = rtl8367c_getAsicAclRule(filter_id, &aclRule)) != RT_ERR_OK) + return retVal; + + /* Check valid */ + if(aclRule.valid == 0) + { + pFilter_cfg->valid = DISABLED; + return RT_ERR_OK; + } + + phyPmask = aclRule.data_bits.active_portmsk; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.value)) != RT_ERR_OK) + return RT_ERR_FAILED; + + phyPmask = aclRule.care_bits.active_portmsk; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.mask)) != RT_ERR_OK) + return RT_ERR_FAILED; + + for(i = 0; i <= CARE_TAG_IPV6; i++) + { + if(aclRule.data_bits.tag_exist & (1 << i)) + pFilter_cfg->careTag.tagType[i].value = 1; + else + pFilter_cfg->careTag.tagType[i].value = 0; + + if (aclRule.care_bits.tag_exist & (1 << i)) + pFilter_cfg->careTag.tagType[i].mask = 1; + else + pFilter_cfg->careTag.tagType[i].mask = 0; + } + + if(filter_advanceCaretagField[aclRule.data_bits.type][0] == TRUE) + { + /* Advanced Care tag setting */ + for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) + { + if(aclRule.data_bits.field[filter_advanceCaretagField[aclRule.data_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) + pFilter_cfg->careTag.tagType[i].value = 1; + else + pFilter_cfg->careTag.tagType[i].value = 0; + + if(aclRule.care_bits.field[filter_advanceCaretagField[aclRule.care_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) + pFilter_cfg->careTag.tagType[i].mask = 1; + else + pFilter_cfg->careTag.tagType[i].mask = 0; + } + } + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + { + pFilter_cfg->careFieldRaw[i] = aclRule.care_bits.field[i]; + pFilter_cfg->dataFieldRaw[i] = aclRule.data_bits.field[i]; + } + + if ((retVal = rtl8367c_getAsicAclNot(filter_id, &tmp))!= RT_ERR_OK) + return retVal; + + pFilter_cfg->invert = tmp; + + pFilter_cfg->valid = aclRule.valid; + + memset(pAction, 0, sizeof(rtk_filter_action_t)); + + if ((retVal = rtl8367c_getAsicAclActCtrl(filter_id, &tmp))!= RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicAclAct(filter_id, &aclAct)) != RT_ERR_OK) + return retVal; + + if(tmp & FILTER_ENACT_FWD_MASK) + { + if(TRUE == aclAct.fwdact_ext) + { + pAction->actEnable[FILTER_ENACT_ISOLATION] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + else if(aclAct.fwdact == RTL8367C_ACL_FWD_TRAP) + { + pAction->actEnable[FILTER_ENACT_TRAP_CPU] = TRUE; + } + else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRRORFUNTION ) + { + pAction->actEnable[FILTER_ENACT_MIRROR] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + else if (aclAct.fwdact == RTL8367C_ACL_FWD_REDIRECT) + { + if(aclAct.fwdpmask == 0 ) + pAction->actEnable[FILTER_ENACT_DROP] = TRUE; + else + { + pAction->actEnable[FILTER_ENACT_REDIRECT] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + } + else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRROR) + { + if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) + return retVal; + if (aclAct.fwdpmask == (1 << cpuPort)) + { + pAction->actEnable[FILTER_ENACT_COPY_CPU] = TRUE; + } + else + { + pAction->actEnable[FILTER_ENACT_ADD_DSTPORT] = TRUE; + + phyPmask = aclAct.fwdpmask; + if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) + return RT_ERR_FAILED; + } + } + else + { + return RT_ERR_FAILED; + } + } + + if(tmp & FILTER_ENACT_POLICING_MASK) + { + pAction->actEnable[FILTER_ENACT_POLICING_0] = TRUE; + pAction->filterPolicingIdx[0] = aclAct.aclmeteridx; + } + + if(tmp & FILTER_ENACT_PRIORITY_MASK) + { + if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_PRIORITY)) + { + pAction->actEnable[FILTER_ENACT_PRIORITY] = TRUE; + pAction->filterPriority = aclAct.pridx; + } + else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_1P_REMARK)) + { + pAction->actEnable[FILTER_ENACT_1P_REMARK] = TRUE; + pAction->filterPriority = aclAct.pridx; + } + else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_DSCP_REMARK)) + { + pAction->actEnable[FILTER_ENACT_DSCP_REMARK] = TRUE; + pAction->filterPriority = aclAct.pridx; + } + else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_POLICING_3)) + { + pAction->actEnable[FILTER_ENACT_POLICING_3] = TRUE; + pAction->filterPolicingIdx[3] = aclAct.pridx; + } + } + + if(tmp & FILTER_ENACT_SVLAN_MASK) + { + if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_INGRESS)) + { + if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_SVLAN_INGRESS] = TRUE; + pAction->filterSvlanIdx = aclAct.svidx_sact; + pAction->filterSvlanVid = svlan_cfg.vs_svid; + } + else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_EGRESS)) + { + if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_SVLAN_EGRESS] = TRUE; + pAction->filterSvlanIdx = aclAct.svidx_sact; + pAction->filterSvlanVid = svlan_cfg.vs_svid; + } + else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_CVID)) + pAction->actEnable[FILTER_ENACT_SVLAN_CVID] = TRUE; + else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_POLICING_2)) + { + pAction->actEnable[FILTER_ENACT_POLICING_2] = TRUE; + pAction->filterPolicingIdx[2] = aclAct.svidx_sact; + } + } + + + if(tmp & FILTER_ENACT_CVLAN_MASK) + { + if(FILTER_ENACT_CACTEXT_TAGONLY == aclAct.cact_ext || + FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) + { + if(FILTER_CTAGFMT_UNTAG == aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_UNTAG] = TRUE; + } + else if(FILTER_CTAGFMT_TAG == aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_TAG] = TRUE; + } + else if(FILTER_CTAGFMT_KEEP == aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEP] = TRUE; + } + else if(FILTER_CTAGFMT_KEEP1PRMK== aclAct.tag_fmt) + { + pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK] = TRUE; + } + + } + + if(FILTER_ENACT_CACTEXT_VLANONLY == aclAct.cact_ext || + FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) + { + if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_INGRESS)) + { + if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_CVLAN_INGRESS] = TRUE; + pAction->filterCvlanIdx = aclAct.cvidx_cact; + pAction->filterCvlanVid = vlanMC.evid; + } + else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_EGRESS)) + { + if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) + return retVal; + + pAction->actEnable[FILTER_ENACT_CVLAN_EGRESS] = TRUE; + pAction->filterCvlanIdx = aclAct.cvidx_cact; + pAction->filterCvlanVid = vlanMC.evid; + } + else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_SVID)) + { + pAction->actEnable[FILTER_ENACT_CVLAN_SVID] = TRUE; + } + else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_POLICING_1)) + { + pAction->actEnable[FILTER_ENACT_POLICING_1] = TRUE; + pAction->filterPolicingIdx[1] = aclAct.cvidx_cact; + } + } + } + + if(tmp & FILTER_ENACT_INTGPIO_MASK) + { + if(TRUE == aclAct.aclint) + { + pAction->actEnable[FILTER_ENACT_INTERRUPT] = TRUE; + } + + if(TRUE == aclAct.gpio_en) + { + pAction->actEnable[FILTER_ENACT_GPO] = TRUE; + pAction->filterPin = aclAct.gpio_pin; + } + } + + /* Get field type of RAW data */ + if ((retVal = rtl8367c_getAsicAclTemplate(aclRule.data_bits.type, &type))!= RT_ERR_OK) + return retVal; + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + { + pFilter_cfg->fieldRawType[i] = type.field[i]; + }/* end of for(i...) */ + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_set + * Description: + * Set action to packets when no ACL configuration match + * Input: + * port - Port id. + * action - Action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function sets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(action >= FILTER_UNMATCH_END) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), action)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_get + * Description: + * Get action to packets when no ACL configuration match + * Input: + * port - Port id. + * Output: + * pAction - Action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* pAction) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if((ret = rtl8367c_getAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), pAction)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_state_set + * Description: + * Set state of ingress ACL. + * Input: + * port - Port id. + * state - Ingress ACL state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAcl(rtk_switch_port_L2P_get(port), state)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_state_get + * Description: + * Get state of ingress ACL. + * Input: + * port - Port id. + * Output: + * pState - Ingress ACL state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* pState) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pState) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if((ret = rtl8367c_getAsicAcl(rtk_switch_port_L2P_get(port), pState)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} +/* Function Name: + * rtk_filter_igrAcl_template_set + * Description: + * Set template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function set ACL template. + */ +rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate) +{ + rtk_api_ret_t retVal; + rtk_uint32 idxField; + rtl8367c_acltemplate_t aclType; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) + return RT_ERR_INPUT; + + for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) + { + if(aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_DMAC_15_0 || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_CTAG && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV4_SIP_15_0 ) || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV4_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV6_SIP_15_0 ) || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV6_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_VIDRANGE ) || + (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_FIELD_VALID && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_FIELD_SELECT00 ) || + aclTemplate->fieldType[idxField] >= FILTER_FIELD_RAW_END) + { + return RT_ERR_INPUT; + } + } + + for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) + { + aclType.field[idxField] = aclTemplate->fieldType[idxField]; + } + + if((retVal = rtl8367c_setAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_template_get + * Description: + * Get template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function gets template of ACL. + */ +rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate) +{ + rtk_api_ret_t ret; + rtk_uint32 idxField; + rtl8367c_acltemplate_t aclType; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == aclTemplate) + return RT_ERR_NULL_POINTER; + + if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) + return RT_ERR_INPUT; + + if((ret = rtl8367c_getAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) + return ret; + + for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField ++) + { + aclTemplate->fieldType[idxField] = aclType.field[idxField]; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_field_sel_set + * Description: + * Set user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * format - Format of field selector + * offset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * System support 16 user defined field selctors. + * Each selector can be enabled or disable. + * User can defined retrieving 16-bits in many predefiend + * standard l2/l3/l4 payload. + */ +rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if(format >= FORMAT_END) + return RT_ERR_OUT_OF_RANGE; + + if(offset > RTL8367C_FIELDSEL_MAX_OFFSET) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_setAsicFieldSelector(index, (rtk_uint32)format, offset)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAcl_field_sel_get + * Description: + * Get user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * Output: + * pFormat - Format of field selector + * pOffset - Retrieving data offset + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pFormat || NULL == pOffset) + return RT_ERR_NULL_POINTER; + + if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicFieldSelector(index, pFormat, pOffset)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_iprange_set + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * upperIp - The upper bound of IP range + * lowerIp - The lower Bound of IP range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperIp must be larger or equal than lowerIp. + */ +rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(type >= IPRANGE_END) + return RT_ERR_OUT_OF_RANGE; + + if(lowerIp > upperIp) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAclIpRange(index, type, upperIp, lowerIp)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_iprange_get + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * pUpperIp - The upper bound of IP range + * pLowerIp - The lower Bound of IP range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((NULL == pType) || (NULL == pUpperIp) || (NULL == pLowerIp)) + return RT_ERR_NULL_POINTER; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicAclIpRange(index, pType, pUpperIp, pLowerIp)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_vidrange_set + * Description: + * Set VID Range check + * Input: + * index - index of VID Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID + * upperVid - The upper bound of VID range + * lowerVid - The lower Bound of VID range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperVid must be larger or equal than lowerVid. + */ +rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(type >= VIDRANGE_END) + return RT_ERR_OUT_OF_RANGE; + + if(lowerVid > upperVid) + return RT_ERR_INPUT; + + if( (upperVid > RTL8367C_VIDMAX) || (lowerVid > RTL8367C_VIDMAX)) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_setAsicAclVidRange(index, type, upperVid, lowerVid)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_vidrange_get + * Description: + * Get VID Range check + * Input: + * index - index of VID Range 0-15 + * Output: + * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID + * pUpperVid - The upper bound of VID range + * pLowerVid - The lower Bound of VID range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((NULL == pType) || (NULL == pUpperVid) || (NULL == pLowerVid)) + return RT_ERR_NULL_POINTER; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicAclVidRange(index, pType, pUpperVid, pLowerVid)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_portrange_set + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * upperPort - The upper bound of Port range + * lowerPort - The lower Bound of Port range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperPort must be larger or equal than lowerPort. + */ +rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(type >= PORTRANGE_END) + return RT_ERR_OUT_OF_RANGE; + + if(lowerPort > upperPort) + return RT_ERR_INPUT; + + if(upperPort > RTL8367C_ACL_PORTRANGEMAX) + return RT_ERR_INPUT; + + if(lowerPort > RTL8367C_ACL_PORTRANGEMAX) + return RT_ERR_INPUT; + + if((ret = rtl8367c_setAsicAclPortRange(index, type, upperPort, lowerPort)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_portrange_get + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * pUpperPort - The upper bound of Port range + * pLowerPort - The lower Bound of Port range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * None. + */ +rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort) +{ + rtk_api_ret_t ret; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((NULL == pType) || (NULL == pUpperPort) || (NULL == pLowerPort)) + return RT_ERR_NULL_POINTER; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + if((ret = rtl8367c_getAsicAclPortRange(index, pType, pUpperPort, pLowerPort)) != RT_ERR_OK) + return ret; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_filter_igrAclPolarity_set + * Description: + * Set ACL Goip control palarity + * Input: + * polarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(polarity > 1) + return RT_ERR_OUT_OF_RANGE; + return rtl8367c_setAsicAclGpioPolarity(polarity); +} +/* Function Name: + * rtk_filter_igrAclPolarity_get + * Description: + * Get ACL Goip control palarity + * Input: + * pPolarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPolarity) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicAclGpioPolarity(pPolarity); +} + + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/cpu.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/cpu.c new file mode 100755 index 00000000..d1cd95b3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/cpu.c @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in CPU module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_cpu_enable_set + * Description: + * Set CPU port function enable/disable. + * Input: + * enable - CPU port function enable + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port function enable/disable. + */ +rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicCputagEnable(enable)) != RT_ERR_OK) + return retVal; + + if (DISABLED == enable) + { + if ((retVal = rtl8367c_setAsicCputagPortmask(0)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_enable_get + * Description: + * Get CPU port and its setting. + * Input: + * None + * Output: + * pEnable - CPU port function enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist + * Note: + * The API can get CPU port function enable/disable. + */ +rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagEnable(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagPort_set + * Description: + * Set CPU port and CPU tag insert mode. + * Input: + * port - Port id. + * mode - CPU tag insert for packets egress from CPU port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899) + * to the frame that transmitting to CPU port. + * The inset cpu tag mode is as following: + * - CPU_INSERT_TO_ALL + * - CPU_INSERT_TO_TRAPPING + * - CPU_INSERT_TO_NONE + */ +rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (mode >= CPU_INSERT_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagPortmask(1<= CPU_POS_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagPosition(position)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagPosition_get + * Description: + * Get CPU tag position. + * Input: + * None + * Output: + * pPosition - CPU tag position. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag position. + */ +rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPosition) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagPosition(pPosition)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagLength_set + * Description: + * Set CPU tag length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU tag length. + */ +rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (length >= CPU_LEN_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagMode(length)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_tagLength_get + * Description: + * Get CPU tag length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag length. + */ +rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pLength) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagMode(pLength)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_priRemap_set + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * new_pri - new internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (new_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if ((retVal = rtl8367c_setAsicCputagPriorityRemapping(int_pri, new_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_priRemap_get + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * Output: + * pNew_pri - new internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pNew_pri) + return RT_ERR_NULL_POINTER; + + if (int_pri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicCputagPriorityRemapping(int_pri, pNew_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_acceptLength_set + * Description: + * Set CPU accept length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU accept length. + */ +rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (length >= CPU_RX_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicCputagRxMinLength(length)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_cpu_acceptLength_get + * Description: + * Get CPU accept length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU accept length. + */ +rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pLength) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicCputagRxMinLength(pLength)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/dot1x.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/dot1x.c new file mode 100755 index 00000000..c9b146a6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/dot1x.c @@ -0,0 +1,843 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 75783 $ + * $Date: 2017-02-13 14:54:53 +0800 (週一, 13 二月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in 1X module. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_dot1x_unauthPacketOper_set + * Description: + * Set 802.1x unauth action configuration. + * Input: + * port - Port id. + * unauth_action - 802.1X unauth action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (unauth_action >= DOT1X_ACTION_END) + return RT_ERR_DOT1X_PROC; + + if ((retVal = rtl8367c_setAsic1xProcConfig(rtk_switch_port_L2P_get(port), unauth_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_unauthPacketOper_get + * Description: + * Get 802.1x unauth action configuration. + * Input: + * port - Port id. + * Output: + * pUnauth_action - 802.1X unauth action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pUnauth_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xProcConfig(rtk_switch_port_L2P_get(port), pUnauth_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_set + * Description: + * Set 802.1x EAPOL packet trap to CPU configuration + * Input: + * enable - The status of 802.1x EAPOL packet. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + rmacfg.operation = RMAOP_TRAP_TO_CPU; + else if (DISABLED == enable) + rmacfg.operation = RMAOP_FORWARD; + + if ((retVal = rtl8367c_setAsicRma(3, &rmacfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_get + * Description: + * Get 802.1x EAPOL packet trap to CPU configuration + * Input: + * None + * Output: + * pEnable - The status of 802.1x EAPOL packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK) + return retVal; + + if (RMAOP_TRAP_TO_CPU == rmacfg.operation) + *pEnable = ENABLED; + else + *pEnable = DISABLED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedEnable_set + * Description: + * Set 802.1x port-based enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error + * Note: + * The API can update the port-based port enable register content. If a port is 802.1x + * port based network access control "enabled", it should be authenticated so packets + * from that port won't be dropped or trapped to CPU. + * The status of 802.1x port-based network access control is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsic1xPBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedEnable_get + * Description: + * Get 802.1x port-based enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the 802.1x port-based port status. + */ +rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xPBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_set + * Description: + * Set 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * port_auth - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error + * Note: + * The authenticated status of 802.1x port-based network access control is as following: + * - UNAUTH + * - AUTH + */ +rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (port_auth >= AUTH_STATUS_END) + return RT_ERR_DOT1X_PORTBASEDAUTH; + + if ((retVal = rtl8367c_setAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), port_auth)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_get + * Description: + * Get 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * Output: + * pPort_auth - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based port auth.information. + */ +rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPort_auth) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), pPort_auth)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedDirection_set + * Description: + * Set 802.1x port-based operational direction configuration + * Input: + * port - Port id. + * port_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error + * Note: + * The operate controlled direction of 802.1x port-based network access control is as following: + * - BOTH + * - IN + */ +rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (port_direction >= DIRECTION_END) + return RT_ERR_DOT1X_PORTBASEDOPDIR; + + if ((retVal = rtl8367c_setAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), port_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_portBasedDirection_get + * Description: + * Get 802.1X port-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pPort_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based operational direction information. + */ +rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPort_direction) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), pPort_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedEnable_set + * Description: + * Set 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port won't be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsic1xMBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedEnable_get + * Description: + * Get 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port wont be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsic1xMBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_add + * Description: + * Add an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT, + * user can't add this MAC to auth status. + */ +rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1)) + return RT_ERR_MAC; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if ( RT_ERR_OK == retVal) + { + if (l2Table.spa != rtk_switch_port_L2P_get(port)) + return RT_ERR_DOT1X_MAC_PORT_MISMATCH; + + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + l2Table.efid = 0; + l2Table.auth = 1; + retVal = rtl8367c_setAsicL2LookupTb(&l2Table); + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_del + * Description: + * Delete an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of + * the MAC and won't delete it from LUT. + */ +rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1)) + return RT_ERR_MAC; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + if (l2Table.spa != rtk_switch_port_L2P_get(port)) + return RT_ERR_DOT1X_MAC_PORT_MISMATCH; + + memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); + l2Table.fid = fid; + l2Table.auth = 0; + retVal = rtl8367c_setAsicL2LookupTb(&l2Table); + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_dot1x_macBasedDirection_set + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * mac_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error + * Note: + * The operate controlled direction of 802.1x mac-based network access control is as following: + * - BOTH + * - IN + */ +rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mac_direction >= DIRECTION_END) + return RT_ERR_DOT1X_MACBASEDOPDIR; + + if ((retVal = rtl8367c_setAsic1xMBOpdirConfig(mac_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_macBasedDirection_get + * Description: + * Get 802.1x mac-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pMac_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x mac-based operational direction information. + */ +rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMac_direction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xMBOpdirConfig(pMac_direction)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * Set 802.1x guest VLAN configuration + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * vid - 802.1x guest VLAN ID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operate controlled 802.1x guest VLAN + */ +rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid) +{ + rtk_api_ret_t retVal; + rtk_uint32 index; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if((retVal = rtk_vlan_checkAndCreateMbr(vid, &index)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsic1xGuestVidx(index)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_guestVlan_get + * Description: + * Get 802.1x guest VLAN configuration + * Input: + * None + * Output: + * pVid - 802.1x guest VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN information. + */ +rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid) +{ + rtk_api_ret_t retVal; + rtk_uint32 gvidx; + rtl8367c_vlanconfiguser vlanMC; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pVid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xGuestVidx(&gvidx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicVlanMemberConfig(gvidx, &vlanMC)) != RT_ERR_OK) + return retVal; + + *pVid = vlanMC.evid; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_set + * Description: + * Set 802.1x guest VLAN to auth host configuration + * Input: + * enable - The status of guest VLAN to auth host. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operational direction of 802.1x guest VLAN to auth host control is as following: + * - ENABLED + * - DISABLED + */ +rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsic1xGVOpdir(enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_get + * Description: + * Get 802.1x guest VLAN to auth host configuration + * Input: + * None + * Output: + * pEnable - The status of guest VLAN to auth host. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN to auth host information. + */ +rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsic1xGVOpdir(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/eee.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/eee.c new file mode 100755 index 00000000..cd14c2ce --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/eee.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 48156 $ + * $Date: 2014-05-29 16:39:06 +0800 (週四, 29 五月 2014) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in EEE module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* Function Name: + * rtk_eee_init + * Description: + * EEE function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize EEE status. + */ +rtk_api_ret_t rtk_eee_init(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((retVal = rtl8367c_setAsicRegBit(0x0018, 10, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x0018, 11, 1)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_eee_portEnable_set + * Description: + * Set enable status of EEE function. + * Input: + * port - port id. + * enable - enable EEE status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is UTP port */ + RTK_CHK_PORT_IS_UTP(port); + + if (enable>=RTK_ENABLE_END) + return RT_ERR_INPUT; + + phy_port = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_setAsicEee100M(phy_port,enable))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicEeeGiga(phy_port,enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYReg(phy_port, RTL8367C_PHY_PAGE_ADDRESS, 0))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicPHYReg(phy_port, 0, ®Data))!=RT_ERR_OK) + return retVal; + regData |= 0x0200; + if ((retVal = rtl8367c_setAsicPHYReg(phy_port, 0, regData))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_eee_portEnable_get + * Description: + * Get enable status of EEE function + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ + +rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData1, regData2; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is UTP port */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + phy_port = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_getAsicEee100M(phy_port,®Data1))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicEeeGiga(phy_port,®Data2))!=RT_ERR_OK) + return retVal; + + if (regData1==1&®Data2==1) + *pEnable = ENABLED; + else + *pEnable = DISABLED; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/i2c.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/i2c.c new file mode 100755 index 00000000..17a5f378 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/i2c.c @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 63932 $ + * $Date: 2015-12-08 14:06:29 +0800 (周二, 08 å二月 2015) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in i2c module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +static rtk_I2C_16bit_mode_t rtk_i2c_mode = I2C_LSB_16BIT_MODE; + + +/* Function Name: + * rtk_i2c_init + * Description: + * I2C smart function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * This API is used to initialize EEE status. + * need used GPIO pins + * OpenDrain and clock + */ +rtk_api_ret_t rtk_i2c_init(void) +{ + rtk_uint32 retVal; + switch_chip_t ChipID; + /* probe switch */ + if((retVal = rtk_switch_probe(&ChipID)) != RT_ERR_OK) + return retVal; + + if( ChipID == CHIP_RTL8370B ) + { + /*set GPIO8, GPIO9, OpenDrain as I2C, clock = 252KHZ */ + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, 0x5c3f)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_FAILED; + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_i2c_mode_set + * Description: + * Set I2C data byte-order. + * Input: + * i2cmode - byte-order mode + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set I2c traffic's byte-order . + */ +rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode ) +{ + if(i2cmode >= I2C_Mode_END) + { + return RT_ERR_INPUT; + } + else if(i2cmode == I2C_70B_LSB_16BIT_MODE) + { + rtk_i2c_mode = I2C_70B_LSB_16BIT_MODE; + + return RT_ERR_OK; + } + else if( i2cmode == I2C_LSB_16BIT_MODE) + { + rtk_i2c_mode = I2C_LSB_16BIT_MODE; + return RT_ERR_OK; + } + else + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_i2c_mode_get + * Description: + * Get i2c traffic byte-order setting. + * Input: + * None + * Output: + * pI2cMode - i2c byte-order + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c traffic byte-order setting. + */ +rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + if(NULL == pI2cMode) + return RT_ERR_NULL_POINTER; + if(rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) + *pI2cMode = 1; + else if ((rtk_i2c_mode == I2C_LSB_16BIT_MODE)) + *pI2cMode = 0; + else + return RT_ERR_FAILED; + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_i2c_gpioPinGroup_set + * Description: + * Set i2c SDA & SCL used GPIO pins group. + * Input: + * pins_group - GPIO pins group + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The API can set i2c used gpio pins group. + * There are three group pins could be used + */ +rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group ) +{ + rtk_uint32 retVal; + + + if( ( pins_group > I2C_GPIO_PIN_END )|| ( pins_group < I2C_GPIO_PIN_8_9) ) + return RT_ERR_INPUT; + + if( (retVal = rtl8367c_setAsicI2CGpioPinGroup(pins_group) ) != RT_ERR_OK ) + return retVal ; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_i2c_gpioPinGroup_get + * Description: + * Get i2c SDA & SCL used GPIO pins group. + * Input: + * None + * Output: + * pPins_group - GPIO pins group + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c used gpio pins group. + * There are three group pins could be used + */ +rtk_api_ret_t rtk_i2c_gpioPinGroup_get( rtk_I2C_gpio_pin_t * pPins_group ) +{ + rtk_uint32 retVal; + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPins_group) + return RT_ERR_NULL_POINTER; + if( (retVal = rtl8367c_getAsicI2CGpioPinGroup(pPins_group) ) != RT_ERR_OK ) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_i2c_data_read + * Description: + * read i2c slave device register. + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * Output: + * pRegData - read data + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can access i2c slave and read i2c slave device register. + */ +rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData) +{ + rtk_uint32 retVal, counter=0; + rtk_uint8 controlByte_W, controlByte_R; + rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp; + rtk_uint8 regData_L, regData_H; + + /* control byte :deviceAddress + W, deviceAddress + R */ + controlByte_W = (rtk_uint8)(deviceAddr << 1) ; + controlByte_R = (rtk_uint8)(controlByte_W | 0x1); + + slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ; + slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ; + + if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) + { + temp = slaveRegAddr_L ; + slaveRegAddr_L = slaveRegAddr_H; + slaveRegAddr_H = temp; + } + + + /*check bus state: idle*/ + for(counter = 3000; counter>0; counter--) + { + if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK) + break; + } + if( counter ==0 ) + return retVal; /*i2c is busy*/ + + /*tx Start cmd*/ + if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) + return retVal ; + + + /*tx control _W*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + /* tx slave buffer address low 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK ) + return retVal ; + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + + /* tx slave buffer address high 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Start cmd*/ + if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) + return retVal ; + + /*tx control _R*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_R))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /* rx low 8bit data*/ + if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( ®Data_L) ) != RT_ERR_OK ) + return retVal; + + + + /* tx ack to slave, keep receive */ + if( (retVal = rtl8367c_setAsicI2CTxAckCmd()) != RT_ERR_OK ) + return retVal; + + /* rx high 8bit data*/ + if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( ®Data_H) ) != RT_ERR_OK ) + return retVal; + + + + /* tx Noack to slave, Stop receive */ + if( (retVal = rtl8367c_setAsicI2CTxNoAckCmd()) != RT_ERR_OK ) + return retVal; + + + /*tx Stop cmd */ + if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK ) + return retVal; + + *pRegData = (regData_H << 8) | regData_L; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_i2c_data_write + * Description: + * write data to i2c slave device register + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * regData - data to set + * Output: + * None + * Return: + * RT_ERR_OK - OK + * Note: + * The API can access i2c slave and setting i2c slave device register. + */ +rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData) +{ + rtk_uint32 retVal,counter; + rtk_uint8 controlByte_W; + rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp; + rtk_uint8 regData_L, regData_H; + + /* control byte :deviceAddress + W */ + controlByte_W = (rtk_uint8)(deviceAddr<< 1) ; + + slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ; + slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ; + + regData_H = (rtk_uint8) (regData>> 8); + regData_L = (rtk_uint8) (regData & 0x00FF); + + if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) + { + temp = slaveRegAddr_L ; + slaveRegAddr_L = slaveRegAddr_H; + slaveRegAddr_H = temp; + } + + + /*check bus state: idle*/ + for(counter = 3000; counter>0; counter--) + { + if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK) + break; + } + + if( counter ==0 ) + return retVal; /*i2c is busy*/ + + + /*tx Start cmd*/ + if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) + return retVal ; + + + /*tx control _W*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK ) + return retVal ; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /* tx slave buffer address low 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /* tx slave buffer address high 8 bits */ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Datavlue LSB*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_L))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Datavlue MSB*/ + if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_H))!= RT_ERR_OK ) + return retVal; + + + /*check if RX ack from slave*/ + if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) + return retVal; + + + /*tx Stop cmd */ + if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK ) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/igmp.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/igmp.c new file mode 100755 index 00000000..170cbdaa --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/igmp.c @@ -0,0 +1,1555 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in IGMP module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + + +/* Function Name: + * rtk_igmp_init + * Description: + * This API enables H/W IGMP and set a default initial configuration. + * Input: + * None. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API enables H/W IGMP and set a default initial configuration. + */ +rtk_api_ret_t rtk_igmp_init(void) +{ + rtk_api_ret_t retVal; + rtk_port_t port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicMLDv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicMLDv2Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_switch_phyPortMask_get()))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn(ENABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(1))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIgmp(ENABLED))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_state_set + * Description: + * This API set H/W IGMP state. + * Input: + * enabled - H/W IGMP state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set H/W IGMP state. + */ +rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIgmp(enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_state_get + * Description: + * This API get H/W IGMP state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current H/W IGMP state. + */ +rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pEnabled == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIgmp(pEnabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_static_router_port_set + * Description: + * Configure static router port + * Input: + * pPortmask - Static Port mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set static router port + */ +rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Valid port mask */ + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPStaticRouterPort(pmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_static_router_port_get + * Description: + * Get static router port + * Input: + * None. + * Output: + * pPortmask - Static port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API get static router port + */ +rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPStaticRouterPort(&pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_protocol_set + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action) +{ + rtk_uint32 operation; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(protocol >= PROTOCOL_END) + return RT_ERR_INPUT; + + if(action >= IGMP_ACTION_END) + return RT_ERR_INPUT; + + switch(action) + { + case IGMP_ACTION_FORWARD: + operation = PROTOCOL_OP_FLOOD; + break; + case IGMP_ACTION_TRAP2CPU: + operation = PROTOCOL_OP_TRAP; + break; + case IGMP_ACTION_DROP: + operation = PROTOCOL_OP_DROP; + break; + case IGMP_ACTION_ASIC: + operation = PROTOCOL_OP_ASIC; + break; + default: + return RT_ERR_INPUT; + } + + switch(protocol) + { + case PROTOCOL_IGMPv1: + if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv2: + if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv3: + if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv1: + if ((retVal = rtl8367c_setAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv2: + if ((retVal = rtl8367c_setAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_INPUT; + + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_protocol_get + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction) +{ + rtk_uint32 operation; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(protocol >= PROTOCOL_END) + return RT_ERR_INPUT; + + if(pAction == NULL) + return RT_ERR_NULL_POINTER; + + switch(protocol) + { + case PROTOCOL_IGMPv1: + if ((retVal = rtl8367c_getAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv2: + if ((retVal = rtl8367c_getAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_IGMPv3: + if ((retVal = rtl8367c_getAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv1: + if ((retVal = rtl8367c_getAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + case PROTOCOL_MLDv2: + if ((retVal = rtl8367c_getAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_INPUT; + + } + + switch(operation) + { + case PROTOCOL_OP_FLOOD: + *pAction = IGMP_ACTION_FORWARD; + break; + case PROTOCOL_OP_TRAP: + *pAction = IGMP_ACTION_TRAP2CPU; + break; + case PROTOCOL_OP_DROP: + *pAction = IGMP_ACTION_DROP; + break; + case PROTOCOL_OP_ASIC: + *pAction = IGMP_ACTION_ASIC; + break; + default: + return RT_ERR_FAILED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_fastLeave_set + * Description: + * set IGMP/MLD FastLeave state + * Input: + * state - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set IGMP/MLD FastLeave state + */ +rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn((rtk_uint32)state))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_fastLeave_get + * Description: + * get IGMP/MLD FastLeave state + * Input: + * None + * Output: + * pState - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - NULL pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get IGMP/MLD FastLeave state + */ +rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState) +{ + rtk_uint32 fast_leave; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pState == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPFastLeaveEn(&fast_leave))!=RT_ERR_OK) + return retVal; + + *pState = ((fast_leave == 1) ? ENABLED : DISABLED); + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_maxGroup_set + * Description: + * Set per port multicast group learning limit. + * Input: + * port - Port ID + * group - The number of multicast group learning limit. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_OUT_OF_RANGE - parameter out of range + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set per port multicast group learning limit. + */ +rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(group > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_OUT_OF_RANGE; + + if ((retVal = rtl8367c_setAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), group))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_maxGroup_get + * Description: + * Get per port multicast group learning limit. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning limit. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning limit. + */ +rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(pGroup == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_currentGroup_get + * Description: + * Get per port multicast group learning count. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning count. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning count. + */ +rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(pGroup == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPPortCurrentGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_tableFullAction_set + * Description: + * set IGMP/MLD Table Full Action + * Input: + * action - Table Full Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(action >= IGMP_TABLE_FULL_OP_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPTableFullOP((rtk_uint32)action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_tableFullAction_get + * Description: + * get IGMP/MLD Table Full Action + * Input: + * None + * Output: + * pAction - Table Full Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPTableFullOP((rtk_uint32 *)pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_checksumErrorAction_set + * Description: + * set IGMP/MLD Checksum Error Action + * Input: + * action - Checksum error Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(action >= IGMP_CRC_ERR_OP_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPCRCErrOP((rtk_uint32)action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_igmp_checksumErrorAction_get + * Description: + * get IGMP/MLD Checksum Error Action + * Input: + * None + * Output: + * pAction - Checksum error Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPCRCErrOP((rtk_uint32 *)pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_leaveTimer_set + * Description: + * set IGMP/MLD Leave timer + * Input: + * timer - Leave timer + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(timer > RTL8367C_MAX_LEAVE_TIMER) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPLeaveTimer(timer))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_leaveTimer_get + * Description: + * get IGMP/MLD Leave timer + * Input: + * None + * Output: + * pTimer - Leave Timer. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pTimer) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPLeaveTimer(pTimer))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_queryInterval_set + * Description: + * set IGMP/MLD Query Interval + * Input: + * interval - Query Interval + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(interval > RTL8367C_MAX_QUERY_INT) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPQueryInterval(interval))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_queryInterval_get + * Description: + * get IGMP/MLD Query Interval + * Input: + * None. + * Output: + * pInterval - Query Interval + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pInterval) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPQueryInterval(pInterval))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_robustness_set + * Description: + * set IGMP/MLD Robustness value + * Input: + * robustness - Robustness value + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(robustness > RTL8367C_MAX_ROB_VAR) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPRobVar(robustness))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_robustness_get + * Description: + * get IGMP/MLD Robustness value + * Input: + * None + * Output: + * pRobustness - Robustness value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pRobustness) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPRobVar(pRobustness))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_set + * Description: + * Configure dynamic router port allow option + * Input: + * pPortmask - Dynamic Port allow mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(pmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_get + * Description: + * Get dynamic router port allow option + * Input: + * None. + * Output: + * pPortmask - Dynamic Port allow mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPAllowDynamicRouterPort(&pmask))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dynamicRouterPort_get + * Description: + * Get dynamic router port + * Input: + * None. + * Output: + * pDynamicRouterPort - Dynamic Router Port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtk_uint32 timer; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pDynamicRouterPort) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort1(&port, &timer))!= RT_ERR_OK) + return retVal; + + if (port == RTL8367C_ROUTER_PORT_INVALID) + { + pDynamicRouterPort->dynamicRouterPort0Valid = DISABLED; + pDynamicRouterPort->dynamicRouterPort0 = 0; + pDynamicRouterPort->dynamicRouterPort0Timer = 0; + } + else + { + pDynamicRouterPort->dynamicRouterPort0Valid = ENABLED; + pDynamicRouterPort->dynamicRouterPort0 = rtk_switch_port_P2L_get(port); + pDynamicRouterPort->dynamicRouterPort0Timer = timer; + } + + if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort2(&port, &timer))!= RT_ERR_OK) + return retVal; + + if (port == RTL8367C_ROUTER_PORT_INVALID) + { + pDynamicRouterPort->dynamicRouterPort1Valid = DISABLED; + pDynamicRouterPort->dynamicRouterPort1 = 0; + pDynamicRouterPort->dynamicRouterPort1Timer = 0; + } + else + { + pDynamicRouterPort->dynamicRouterPort1Valid = ENABLED; + pDynamicRouterPort->dynamicRouterPort1 = rtk_switch_port_P2L_get(port); + pDynamicRouterPort->dynamicRouterPort1Timer = timer; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_suppressionEnable_set + * Description: + * Configure IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * reportSuppression - Report suppression + * leaveSuppression - Leave suppression + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(reportSuppression >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(leaveSuppression >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPSuppression((rtk_uint32)reportSuppression, (rtk_uint32)leaveSuppression))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_suppressionEnable_get + * Description: + * Get IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * None + * Output: + * pReportSuppression - Report suppression + * pLeaveSuppression - Leave suppression + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pReportSuppression) + return RT_ERR_NULL_POINTER; + + if(NULL == pLeaveSuppression) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPSuppression((rtk_uint32 *)pReportSuppression, (rtk_uint32 *)pLeaveSuppression))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_portRxPktEnable_set + * Description: + * Configure IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pRxCfg) + return RT_ERR_NULL_POINTER; + + if(pRxCfg->rxQuery >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxReport >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxLeave >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxMRP >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pRxCfg->rxMcast >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxQuery))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxReport))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxLeave))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMRP))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMcast))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_portRxPktEnable_get + * Description: + * Get IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pRxCfg) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxQuery)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxReport)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxLeave)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMRP)))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMcast)))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_groupInfo_get + * Description: + * Get IGMP/MLD Group database + * Input: + * indes - Index (0~255) + * Output: + * pGroup - Group database information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup) +{ + rtk_api_ret_t retVal; + rtk_uint32 valid; + rtl8367c_igmpgroup grp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check index */ + if(index > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_INPUT; + + if(NULL == pGroup) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPGroup(index, &valid, &grp))!=RT_ERR_OK) + return retVal; + + memset(pGroup, 0x00, sizeof(rtk_igmp_groupInfo_t)); + pGroup->valid = valid; + pGroup->reportSuppFlag = grp.report_supp_flag; + + if(grp.p0_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(0)); + pGroup->timer[rtk_switch_port_P2L_get(0)] = grp.p0_timer; + } + + if(grp.p1_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(1)); + pGroup->timer[rtk_switch_port_P2L_get(1)] = grp.p1_timer; + } + + if(grp.p2_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(2)); + pGroup->timer[rtk_switch_port_P2L_get(2)] = grp.p2_timer; + } + + if(grp.p3_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(3)); + pGroup->timer[rtk_switch_port_P2L_get(3)] = grp.p3_timer; + } + + if(grp.p4_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(4)); + pGroup->timer[rtk_switch_port_P2L_get(4)] = grp.p4_timer; + } + + if(grp.p5_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(5)); + pGroup->timer[rtk_switch_port_P2L_get(5)] = grp.p5_timer; + } + + if(grp.p6_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(6)); + pGroup->timer[rtk_switch_port_P2L_get(6)] = grp.p6_timer; + } + + if(grp.p7_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(7)); + pGroup->timer[rtk_switch_port_P2L_get(7)] = grp.p7_timer; + } + + if(grp.p8_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(8)); + pGroup->timer[rtk_switch_port_P2L_get(8)] = grp.p8_timer; + } + + if(grp.p9_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(9)); + pGroup->timer[rtk_switch_port_P2L_get(9)] = grp.p9_timer; + } + + if(grp.p10_timer != 0) + { + RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(10)); + pGroup->timer[rtk_switch_port_P2L_get(10)] = grp.p10_timer; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_set + * Description: + * Set Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + switch(action) + { + case IGMP_REPORT_LEAVE_TO_ROUTER: + regData = 1; + break; + case IGMP_REPORT_LEAVE_TO_ALLPORT: + regData = 2; + break; + case IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV: + regData = 3; + break; + default: + return RT_ERR_INPUT; + } + + if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(regData))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_get + * Description: + * Get Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPReportLeaveFlood(®Data))!=RT_ERR_OK) + return retVal; + + switch(regData) + { + case 1: + *pAction = IGMP_REPORT_LEAVE_TO_ROUTER; + break; + case 2: + *pAction = IGMP_REPORT_LEAVE_TO_ALLPORT; + break; + case 3: + *pAction = IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV; + break; + default: + return RT_ERR_FAILED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_set + * Description: + * Set the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * enabled - Action 1: drop, 0:pass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPDropLeaveZero(enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_get + * Description: + * Get the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * None + * Output: + * pEnabled. - Action 1: drop, 0:pass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPDropLeaveZero((rtk_uint32 *)pEnabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_igmp_bypassGroupRange_set + * Description: + * Set Bypass group + * Input: + * group - bypassed group + * enabled - enabled 1: Bypassed, 0: not bypass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(group >= IGMP_BYPASS_GROUP_END) + return RT_ERR_INPUT; + + if(enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicIGMPBypassGroup(group, enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_igmp_bypassGroupRange_get + * Description: + * get Bypass group + * Input: + * group - bypassed group + * Output: + * pEnable - enabled 1: Bypassed, 0: not bypass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(group >= IGMP_BYPASS_GROUP_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicIGMPBypassGroup(group, pEnable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/acl.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/acl.h new file mode 100755 index 00000000..6308da8d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/acl.h @@ -0,0 +1,990 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes ACL module high-layer API defination + * + */ + +#ifndef __RTK_API_ACL_H__ +#define __RTK_API_ACL_H__ + +/* + * Data Type Declaration + */ +#define RTK_FILTER_RAW_FIELD_NUMBER 8 + +#define ACL_DEFAULT_ABILITY 0 +#define ACL_DEFAULT_UNMATCH_PERMIT 1 + +#define ACL_RULE_FREE 0 +#define ACL_RULE_INAVAILABLE 1 +#define ACL_RULE_CARETAG_MASK 0x1F +#define FILTER_POLICING_MAX 4 +#define FILTER_LOGGING_MAX 8 +#define FILTER_PATTERN_MAX 4 + +#define FILTER_ENACT_CVLAN_MASK 0x01 +#define FILTER_ENACT_SVLAN_MASK 0x02 +#define FILTER_ENACT_PRIORITY_MASK 0x04 +#define FILTER_ENACT_POLICING_MASK 0x08 +#define FILTER_ENACT_FWD_MASK 0x10 +#define FILTER_ENACT_INTGPIO_MASK 0x20 +#define FILTER_ENACT_INIT_MASK 0x3F + +typedef enum rtk_filter_act_cactext_e +{ + FILTER_ENACT_CACTEXT_VLANONLY=0, + FILTER_ENACT_CACTEXT_BOTHVLANTAG, + FILTER_ENACT_CACTEXT_TAGONLY, + FILTER_ENACT_CACTEXT_END, + + +}rtk_filter_act_cactext_t; + +typedef enum rtk_filter_act_ctagfmt_e +{ + FILTER_CTAGFMT_UNTAG=0, + FILTER_CTAGFMT_TAG, + FILTER_CTAGFMT_KEEP, + FILTER_CTAGFMT_KEEP1PRMK, + + +}rtk_filter_act_ctag_t; + + + + + +#define RTK_MAX_NUM_OF_FILTER_TYPE 5 +#define RTK_MAX_NUM_OF_FILTER_FIELD 8 + +#define RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH 3UL +#define RTK_IPV6_ADDR_WORD_LENGTH 4UL + +#define FILTER_ENACT_CVLAN_TYPE(type) (type - FILTER_ENACT_CVLAN_INGRESS) +#define FILTER_ENACT_SVLAN_TYPE(type) (type - FILTER_ENACT_SVLAN_INGRESS) +#define FILTER_ENACT_FWD_TYPE(type) (type - FILTER_ENACT_ADD_DSTPORT) +#define FILTER_ENACT_PRI_TYPE(type) (type - FILTER_ENACT_PRIORITY) + +#define RTK_FILTER_FIELD_USED_MAX 8 +#define RTK_FILTER_FIELD_INDEX(template, index) ((template << 4) + index) + + +typedef enum rtk_filter_act_enable_e +{ + /* CVLAN */ + FILTER_ENACT_CVLAN_INGRESS = 0, + FILTER_ENACT_CVLAN_EGRESS, + FILTER_ENACT_CVLAN_SVID, + FILTER_ENACT_POLICING_1, + + /* SVLAN */ + FILTER_ENACT_SVLAN_INGRESS, + FILTER_ENACT_SVLAN_EGRESS, + FILTER_ENACT_SVLAN_CVID, + FILTER_ENACT_POLICING_2, + + /* Policing and Logging */ + FILTER_ENACT_POLICING_0, + + /* Forward */ + FILTER_ENACT_COPY_CPU, + FILTER_ENACT_DROP, + FILTER_ENACT_ADD_DSTPORT, + FILTER_ENACT_REDIRECT, + FILTER_ENACT_MIRROR, + FILTER_ENACT_TRAP_CPU, + FILTER_ENACT_ISOLATION, + + /* QoS */ + FILTER_ENACT_PRIORITY, + FILTER_ENACT_DSCP_REMARK, + FILTER_ENACT_1P_REMARK, + FILTER_ENACT_POLICING_3, + + /* Interrutp and GPO */ + FILTER_ENACT_INTERRUPT, + FILTER_ENACT_GPO, + + /*VLAN tag*/ + FILTER_ENACT_EGRESSCTAG_UNTAG, + FILTER_ENACT_EGRESSCTAG_TAG, + FILTER_ENACT_EGRESSCTAG_KEEP, + FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK, + + FILTER_ENACT_END, +} rtk_filter_act_enable_t; + + +typedef struct +{ + rtk_filter_act_enable_t actEnable[FILTER_ENACT_END]; + + /* CVLAN acton */ + rtk_uint32 filterCvlanVid; + rtk_uint32 filterCvlanIdx; + /* SVLAN action */ + rtk_uint32 filterSvlanVid; + rtk_uint32 filterSvlanIdx; + + /* Policing action */ + rtk_uint32 filterPolicingIdx[FILTER_POLICING_MAX]; + + /* Forwarding action */ + rtk_portmask_t filterPortmask; + + /* QOS action */ + rtk_uint32 filterPriority; + + /*GPO*/ + rtk_uint32 filterPin; + +} rtk_filter_action_t; + +typedef struct rtk_filter_flag_s +{ + rtk_uint32 value; + rtk_uint32 mask; +} rtk_filter_flag_t; + +typedef enum rtk_filter_care_tag_index_e +{ + CARE_TAG_CTAG = 0, + CARE_TAG_STAG, + CARE_TAG_PPPOE, + CARE_TAG_IPV4, + CARE_TAG_IPV6, + CARE_TAG_TCP, + CARE_TAG_UDP, + CARE_TAG_ARP, + CARE_TAG_RSV1, + CARE_TAG_RSV2, + CARE_TAG_ICMP, + CARE_TAG_IGMP, + CARE_TAG_LLC, + CARE_TAG_RSV3, + CARE_TAG_HTTP, + CARE_TAG_RSV4, + CARE_TAG_RSV5, + CARE_TAG_DHCP, + CARE_TAG_DHCPV6, + CARE_TAG_SNMP, + CARE_TAG_OAM, + CARE_TAG_END, +} rtk_filter_care_tag_index_t; + +typedef struct rtk_filter_care_tag_s +{ + rtk_filter_flag_t tagType[CARE_TAG_END]; +} rtk_filter_care_tag_t; + +typedef struct rtk_filter_field rtk_filter_field_t; + +typedef struct +{ + rtk_uint32 value[RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH]; +} rtk_filter_dot1as_timestamp_t; + +typedef enum rtk_filter_field_data_type_e +{ + FILTER_FIELD_DATA_MASK = 0, + FILTER_FIELD_DATA_RANGE, + FILTER_FIELD_DATA_END , +} rtk_filter_field_data_type_t; + +typedef struct rtk_filter_ip_s +{ + rtk_uint32 dataType; + rtk_uint32 rangeStart; + rtk_uint32 rangeEnd; + rtk_uint32 value; + rtk_uint32 mask; +} rtk_filter_ip_t; + +typedef struct rtk_filter_mac_s +{ + rtk_uint32 dataType; + rtk_mac_t value; + rtk_mac_t mask; + rtk_mac_t rangeStart; + rtk_mac_t rangeEnd; +} rtk_filter_mac_t; + +typedef rtk_uint32 rtk_filter_op_t; + +typedef struct rtk_filter_value_s +{ + rtk_uint32 dataType; + rtk_uint32 value; + rtk_uint32 mask; + rtk_uint32 rangeStart; + rtk_uint32 rangeEnd; + +} rtk_filter_value_t; + +typedef struct rtk_filter_activeport_s +{ + rtk_portmask_t value; + rtk_portmask_t mask; + +} rtk_filter_activeport_t; + + + +typedef struct rtk_filter_tag_s +{ + rtk_filter_value_t pri; + rtk_filter_flag_t cfi; + rtk_filter_value_t vid; +} rtk_filter_tag_t; + +typedef struct rtk_filter_ipFlag_s +{ + rtk_filter_flag_t xf; + rtk_filter_flag_t mf; + rtk_filter_flag_t df; +} rtk_filter_ipFlag_t; + +typedef struct +{ + rtk_uint32 addr[RTK_IPV6_ADDR_WORD_LENGTH]; +} rtk_filter_ip6_addr_t; + +typedef struct +{ + rtk_uint32 dataType; + rtk_filter_ip6_addr_t value; + rtk_filter_ip6_addr_t mask; + rtk_filter_ip6_addr_t rangeStart; + rtk_filter_ip6_addr_t rangeEnd; +} rtk_filter_ip6_t; + +typedef rtk_uint32 rtk_filter_number_t; + +typedef struct rtk_filter_pattern_s +{ + rtk_uint32 value[FILTER_PATTERN_MAX]; + rtk_uint32 mask[FILTER_PATTERN_MAX]; +} rtk_filter_pattern_t; + +typedef struct rtk_filter_tcpFlag_s +{ + rtk_filter_flag_t urg; + rtk_filter_flag_t ack; + rtk_filter_flag_t psh; + rtk_filter_flag_t rst; + rtk_filter_flag_t syn; + rtk_filter_flag_t fin; + rtk_filter_flag_t ns; + rtk_filter_flag_t cwr; + rtk_filter_flag_t ece; +} rtk_filter_tcpFlag_t; + +typedef rtk_uint32 rtk_filter_field_raw_t; + +typedef enum rtk_filter_field_temple_input_e +{ + FILTER_FIELD_TEMPLE_INPUT_TYPE = 0, + FILTER_FIELD_TEMPLE_INPUT_INDEX, + FILTER_FIELD_TEMPLE_INPUT_MAX , +} rtk_filter_field_temple_input_t; + +struct rtk_filter_field +{ + rtk_uint32 fieldType; + + union + { + /* L2 struct */ + rtk_filter_mac_t dmac; + rtk_filter_mac_t smac; + rtk_filter_value_t etherType; + rtk_filter_tag_t ctag; + rtk_filter_tag_t relayCtag; + rtk_filter_tag_t stag; + rtk_filter_tag_t l2tag; + rtk_filter_dot1as_timestamp_t dot1asTimeStamp; + rtk_filter_mac_t mac; + + /* L3 struct */ + rtk_filter_ip_t sip; + rtk_filter_ip_t dip; + rtk_filter_ip_t ip; + rtk_filter_value_t protocol; + rtk_filter_value_t ipTos; + rtk_filter_ipFlag_t ipFlag; + rtk_filter_value_t ipOffset; + rtk_filter_ip6_t sipv6; + rtk_filter_ip6_t dipv6; + rtk_filter_ip6_t ipv6; + rtk_filter_value_t ipv6TrafficClass; + rtk_filter_value_t ipv6NextHeader; + rtk_filter_value_t flowLabel; + + /* L4 struct */ + rtk_filter_value_t tcpSrcPort; + rtk_filter_value_t tcpDstPort; + rtk_filter_tcpFlag_t tcpFlag; + rtk_filter_value_t tcpSeqNumber; + rtk_filter_value_t tcpAckNumber; + rtk_filter_value_t udpSrcPort; + rtk_filter_value_t udpDstPort; + rtk_filter_value_t icmpCode; + rtk_filter_value_t icmpType; + rtk_filter_value_t igmpType; + + /* pattern match */ + rtk_filter_pattern_t pattern; + + rtk_filter_value_t inData; + + } filter_pattern_union; + + rtk_uint32 fieldTemplateNo; + rtk_uint32 fieldTemplateIdx[RTK_FILTER_FIELD_USED_MAX]; + + struct rtk_filter_field *next; +}; + +typedef enum rtk_filter_field_type_e +{ + FILTER_FIELD_DMAC = 0, + FILTER_FIELD_SMAC, + FILTER_FIELD_ETHERTYPE, + FILTER_FIELD_CTAG, + FILTER_FIELD_STAG, + + FILTER_FIELD_IPV4_SIP, + FILTER_FIELD_IPV4_DIP, + FILTER_FIELD_IPV4_TOS, + FILTER_FIELD_IPV4_PROTOCOL, + FILTER_FIELD_IPV4_FLAG, + FILTER_FIELD_IPV4_OFFSET, + FILTER_FIELD_IPV6_SIPV6, + FILTER_FIELD_IPV6_DIPV6, + FILTER_FIELD_IPV6_TRAFFIC_CLASS, + FILTER_FIELD_IPV6_NEXT_HEADER, + + FILTER_FIELD_TCP_SPORT, + FILTER_FIELD_TCP_DPORT, + FILTER_FIELD_TCP_FLAG, + FILTER_FIELD_UDP_SPORT, + FILTER_FIELD_UDP_DPORT, + FILTER_FIELD_ICMP_CODE, + FILTER_FIELD_ICMP_TYPE, + FILTER_FIELD_IGMP_TYPE, + + FILTER_FIELD_VID_RANGE, + FILTER_FIELD_IP_RANGE, + FILTER_FIELD_PORT_RANGE, + + FILTER_FIELD_USER_DEFINED00, + FILTER_FIELD_USER_DEFINED01, + FILTER_FIELD_USER_DEFINED02, + FILTER_FIELD_USER_DEFINED03, + FILTER_FIELD_USER_DEFINED04, + FILTER_FIELD_USER_DEFINED05, + FILTER_FIELD_USER_DEFINED06, + FILTER_FIELD_USER_DEFINED07, + FILTER_FIELD_USER_DEFINED08, + FILTER_FIELD_USER_DEFINED09, + FILTER_FIELD_USER_DEFINED10, + FILTER_FIELD_USER_DEFINED11, + FILTER_FIELD_USER_DEFINED12, + FILTER_FIELD_USER_DEFINED13, + FILTER_FIELD_USER_DEFINED14, + FILTER_FIELD_USER_DEFINED15, + + FILTER_FIELD_PATTERN_MATCH, + + FILTER_FIELD_END, +} rtk_filter_field_type_t; + + +typedef enum rtk_filter_field_type_raw_e +{ + FILTER_FIELD_RAW_UNUSED = 0, + FILTER_FIELD_RAW_DMAC_15_0, + FILTER_FIELD_RAW_DMAC_31_16, + FILTER_FIELD_RAW_DMAC_47_32, + FILTER_FIELD_RAW_SMAC_15_0, + FILTER_FIELD_RAW_SMAC_31_16, + FILTER_FIELD_RAW_SMAC_47_32, + FILTER_FIELD_RAW_ETHERTYPE, + FILTER_FIELD_RAW_STAG, + FILTER_FIELD_RAW_CTAG, + + FILTER_FIELD_RAW_IPV4_SIP_15_0 = 0x10, + FILTER_FIELD_RAW_IPV4_SIP_31_16, + FILTER_FIELD_RAW_IPV4_DIP_15_0, + FILTER_FIELD_RAW_IPV4_DIP_31_16, + + + FILTER_FIELD_RAW_IPV6_SIP_15_0 = 0x20, + FILTER_FIELD_RAW_IPV6_SIP_31_16, + FILTER_FIELD_RAW_IPV6_DIP_15_0 = 0x28, + FILTER_FIELD_RAW_IPV6_DIP_31_16, + + FILTER_FIELD_RAW_VIDRANGE = 0x30, + FILTER_FIELD_RAW_IPRANGE, + FILTER_FIELD_RAW_PORTRANGE, + FILTER_FIELD_RAW_FIELD_VALID, + + FILTER_FIELD_RAW_FIELD_SELECT00 = 0x40, + FILTER_FIELD_RAW_FIELD_SELECT01, + FILTER_FIELD_RAW_FIELD_SELECT02, + FILTER_FIELD_RAW_FIELD_SELECT03, + FILTER_FIELD_RAW_FIELD_SELECT04, + FILTER_FIELD_RAW_FIELD_SELECT05, + FILTER_FIELD_RAW_FIELD_SELECT06, + FILTER_FIELD_RAW_FIELD_SELECT07, + FILTER_FIELD_RAW_FIELD_SELECT08, + FILTER_FIELD_RAW_FIELD_SELECT09, + FILTER_FIELD_RAW_FIELD_SELECT10, + FILTER_FIELD_RAW_FIELD_SELECT11, + FILTER_FIELD_RAW_FIELD_SELECT12, + FILTER_FIELD_RAW_FIELD_SELECT13, + FILTER_FIELD_RAW_FIELD_SELECT14, + FILTER_FIELD_RAW_FIELD_SELECT15, + + FILTER_FIELD_RAW_END, +} rtk_filter_field_type_raw_t; + +typedef enum rtk_filter_flag_care_type_e +{ + FILTER_FLAG_CARE_DONT_CARE = 0, + FILTER_FLAG_CARE_1, + FILTER_FLAG_CARE_0, + FILTER_FLAG_END +} rtk_filter_flag_care_type_t; + +typedef rtk_uint32 rtk_filter_id_t; /* filter id type */ + +typedef enum rtk_filter_invert_e +{ + FILTER_INVERT_DISABLE = 0, + FILTER_INVERT_ENABLE, + FILTER_INVERT_END, +} rtk_filter_invert_t; + +typedef rtk_uint32 rtk_filter_state_t; + +typedef rtk_uint32 rtk_filter_unmatch_action_t; + +typedef enum rtk_filter_unmatch_action_e +{ + FILTER_UNMATCH_DROP = 0, + FILTER_UNMATCH_PERMIT, + FILTER_UNMATCH_END, +} rtk_filter_unmatch_action_type_t; + +typedef struct +{ + rtk_filter_field_t *fieldHead; + rtk_filter_care_tag_t careTag; + rtk_filter_activeport_t activeport; + + rtk_filter_invert_t invert; +} rtk_filter_cfg_t; + +typedef struct +{ + rtk_filter_field_raw_t dataFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER]; + rtk_filter_field_raw_t careFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER]; + rtk_filter_field_type_raw_t fieldRawType[RTK_FILTER_RAW_FIELD_NUMBER]; + rtk_filter_care_tag_t careTag; + rtk_filter_activeport_t activeport; + + rtk_filter_invert_t invert; + rtk_enable_t valid; +} rtk_filter_cfg_raw_t; + +typedef struct +{ + rtk_uint32 index; + rtk_filter_field_type_raw_t fieldType[RTK_FILTER_RAW_FIELD_NUMBER]; +} rtk_filter_template_t; + +typedef enum rtk_field_sel_e +{ + FORMAT_DEFAULT = 0, + FORMAT_RAW, + FORMAT_LLC, + FORMAT_IPV4, + FORMAT_ARP, + FORMAT_IPV6, + FORMAT_IPPAYLOAD, + FORMAT_L4PAYLOAD, + FORMAT_END +}rtk_field_sel_t; + +typedef enum rtk_filter_iprange_e +{ + IPRANGE_UNUSED = 0, + IPRANGE_IPV4_SIP, + IPRANGE_IPV4_DIP, + IPRANGE_IPV6_SIP, + IPRANGE_IPV6_DIP, + IPRANGE_END +}rtk_filter_iprange_t; + +typedef enum rtk_filter_vidrange_e +{ + VIDRANGE_UNUSED = 0, + VIDRANGE_CVID, + VIDRANGE_SVID, + VIDRANGE_END +}rtk_filter_vidrange_t; + +typedef enum rtk_filter_portrange_e +{ + PORTRANGE_UNUSED = 0, + PORTRANGE_SPORT, + PORTRANGE_DPORT, + PORTRANGE_END +}rtk_filter_portrange_t; + +/* Function Name: + * rtk_filter_igrAcl_init + * Description: + * ACL initialization function + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * Note: + * This function enable and intialize ACL function + */ +extern rtk_api_ret_t rtk_filter_igrAcl_init(void); + +/* Function Name: + * rtk_filter_igrAcl_field_add + * Description: + * Add comparison rule to an ACL configuration + * Input: + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_field - The comparison rule that will be added. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg). + * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL + * comparison rules by means of linked list. Pointer pFilter_field will be added to linked + * list keeped by structure that pFilter_cfg points to. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t *pFilter_cfg, rtk_filter_field_t *pFilter_field); + +/* Function Name: + * rtk_filter_igrAcl_cfg_add + * Description: + * Add an ACL configuration to ASIC + * Input: + * filter_id - Start index of ACL configuration. + * pFilter_cfg - The ACL configuration that this function will add comparison rule + * pFilter_action - Action(s) of ACL configuration. + * Output: + * ruleNum - number of rules written in acl table + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENTRY_INDEX - Invalid filter_id . + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip. + * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported. + * Note: + * This function store pFilter_cfg, pFilter_action into ASIC. The starting + * index(es) is filter_id. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t *pFilter_cfg, rtk_filter_action_t *pAction, rtk_filter_number_t *ruleNum); + +/* Function Name: + * rtk_filter_igrAcl_cfg_del + * Description: + * Delete an ACL configuration from ASIC + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id. + * Note: + * This function delete a group of ACL rules starting from filter_id. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id); + +/* Function Name: + * rtk_filter_igrAcl_cfg_delAll + * Description: + * Delete all ACL entries from ASIC + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function delete all ACL configuration from ASIC. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void); + +/* Function Name: + * rtk_filter_igrAcl_cfg_get + * Description: + * Get one ingress acl configuration from ASIC. + * Input: + * filter_id - Start index of ACL configuration. + * Output: + * pFilter_cfg - buffer pointer of ingress acl data + * pFilter_action - buffer pointer of ingress acl action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. + * RT_ERR_FILTER_ENTRYIDX - Invalid entry index. + * Note: + * This function delete all ACL configuration from ASIC. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction); + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_set + * Description: + * Set action to packets when no ACL configuration match + * Input: + * port - Port id. + * action - Action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function sets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action); + +/* Function Name: + * rtk_filter_igrAcl_unmatchAction_get + * Description: + * Get action to packets when no ACL configuration match + * Input: + * port - Port id. + * Output: + * pAction - Action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* action); + +/* Function Name: + * rtk_filter_igrAcl_state_set + * Description: + * Set state of ingress ACL. + * Input: + * port - Port id. + * state - Ingress ACL state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state); + +/* Function Name: + * rtk_filter_igrAcl_state_get + * Description: + * Get state of ingress ACL. + * Input: + * port - Port id. + * Output: + * pState - Ingress ACL state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port id. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function gets action of packets when no ACL configruation matches. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* state); + +/* Function Name: + * rtk_filter_igrAcl_template_set + * Description: + * Set template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This function set ACL template. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate); + +/* Function Name: + * rtk_filter_igrAcl_template_get + * Description: + * Get template of ingress ACL. + * Input: + * template - Ingress ACL template + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This function gets template of ACL. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate); + +/* Function Name: + * rtk_filter_igrAcl_field_sel_set + * Description: + * Set user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * format - Format of field selector + * offset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * System support 16 user defined field selctors. + * Each selector can be enabled or disable. + * User can defined retrieving 16-bits in many predefiend + * standard l2/l3/l4 payload. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset); + +/* Function Name: + * rtk_filter_igrAcl_field_sel_get + * Description: + * Get user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * Output: + * pFormat - Format of field selector + * pOffset - Retrieving data offset + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset); + +/* Function Name: + * rtk_filter_iprange_set + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * upperIp - The upper bound of IP range + * lowerIp - The lower Bound of IP range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperIp must be larger or equal than lowerIp. + */ +extern rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp); + +/* Function Name: + * rtk_filter_iprange_get + * Description: + * Set IP Range check + * Input: + * index - index of IP Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP + * pUpperIp - The upper bound of IP range + * pLowerIp - The lower Bound of IP range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * upperIp must be larger or equal than lowerIp. + */ +extern rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp); + +/* Function Name: + * rtk_filter_vidrange_set + * Description: + * Set VID Range check + * Input: + * index - index of VID Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID + * upperVid - The upper bound of VID range + * lowerVid - The lower Bound of VID range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperVid must be larger or equal than lowerVid. + */ +extern rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid); + +/* Function Name: + * rtk_filter_vidrange_get + * Description: + * Get VID Range check + * Input: + * index - index of VID Range 0-15 + * Output: + * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID + * pUpperVid - The upper bound of VID range + * pLowerVid - The lower Bound of VID range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * Note: + * None. + */ +extern rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid); + +/* Function Name: + * rtk_filter_portrange_set + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * upperPort - The upper bound of Port range + * lowerPort - The lower Bound of Port range + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * upperPort must be larger or equal than lowerPort. + */ +extern rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort); + +/* Function Name: + * rtk_filter_portrange_get + * Description: + * Set Port Range check + * Input: + * index - index of Port Range 0-15 + * Output: + * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port + * pUpperPort - The upper bound of Port range + * pLowerPort - The lower Bound of Port range + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - The parameter is out of range + * RT_ERR_INPUT - Input error + * Note: + * None. + */ +extern rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort); + +/* Function Name: + * rtk_filter_igrAclPolarity_set + * Description: + * Set ACL Goip control palarity + * Input: + * polarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +extern rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity); + +/* Function Name: + * rtk_filter_igrAclPolarity_get + * Description: + * Get ACL Goip control palarity + * Input: + * pPolarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +extern rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity); + + +#endif /* __RTK_API_ACL_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/cpu.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/cpu.h new file mode 100755 index 00000000..5544aca7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/cpu.h @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes CPU module high-layer API defination + * + */ + +#ifndef __RTK_API_CPU_H__ +#define __RTK_API_CPU_H__ + + +/* + * Data Type Declaration + */ +typedef enum rtk_cpu_insert_e +{ + CPU_INSERT_TO_ALL = 0, + CPU_INSERT_TO_TRAPPING, + CPU_INSERT_TO_NONE, + CPU_INSERT_END +}rtk_cpu_insert_t; + +typedef enum rtk_cpu_position_e +{ + CPU_POS_AFTER_SA = 0, + CPU_POS_BEFORE_CRC, + CPU_POS_END +}rtk_cpu_position_t; + +typedef enum rtk_cpu_tag_length_e +{ + CPU_LEN_8BYTES = 0, + CPU_LEN_4BYTES, + CPU_LEN_END +}rtk_cpu_tag_length_t; + + +typedef enum rtk_cpu_rx_length_e +{ + CPU_RX_72BYTES = 0, + CPU_RX_64BYTES, + CPU_RX_END +}rtk_cpu_rx_length_t; + + +/* Function Name: + * rtk_cpu_enable_set + * Description: + * Set CPU port function enable/disable. + * Input: + * enable - CPU port function enable + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port function enable/disable. + */ +extern rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_cpu_enable_get + * Description: + * Get CPU port and its setting. + * Input: + * None + * Output: + * pEnable - CPU port function enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist + * Note: + * The API can get CPU port function enable/disable. + */ +extern rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_cpu_tagPort_set + * Description: + * Set CPU port and CPU tag insert mode. + * Input: + * port - Port id. + * mode - CPU tag insert for packets egress from CPU port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899) + * to the frame that transmitting to CPU port. + * The inset cpu tag mode is as following: + * - CPU_INSERT_TO_ALL + * - CPU_INSERT_TO_TRAPPING + * - CPU_INSERT_TO_NONE + */ +extern rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode); + +/* Function Name: + * rtk_cpu_tagPort_get + * Description: + * Get CPU port and CPU tag insert mode. + * Input: + * None + * Output: + * pPort - Port id. + * pMode - CPU tag insert for packets egress from CPU port, 0:all insert 1:Only for trapped packets 2:no insert. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist + * Note: + * The API can get configured CPU port and its setting. + * The inset cpu tag mode is as following: + * - CPU_INSERT_TO_ALL + * - CPU_INSERT_TO_TRAPPING + * - CPU_INSERT_TO_NONE + */ +extern rtk_api_ret_t rtk_cpu_tagPort_get(rtk_port_t *pPort, rtk_cpu_insert_t *pMode); + +/* Function Name: + * rtk_cpu_awarePort_set + * Description: + * Set CPU aware port mask. + * Input: + * portmask - Port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can set configured CPU aware port mask. + */ +extern rtk_api_ret_t rtk_cpu_awarePort_set(rtk_portmask_t *pPortmask); + + +/* Function Name: + * rtk_cpu_awarePort_get + * Description: + * Get CPU aware port mask. + * Input: + * None + * Output: + * pPortmask - Port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get configured CPU aware port mask. + */ +extern rtk_api_ret_t rtk_cpu_awarePort_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_cpu_tagPosition_set + * Description: + * Set CPU tag position. + * Input: + * position - CPU tag position. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU tag position. + */ +extern rtk_api_ret_t rtk_cpu_tagPosition_set(rtk_cpu_position_t position); + +/* Function Name: + * rtk_cpu_tagPosition_get + * Description: + * Get CPU tag position. + * Input: + * None + * Output: + * pPosition - CPU tag position. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag position. + */ +extern rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition); + +/* Function Name: + * rtk_cpu_tagLength_set + * Description: + * Set CPU tag length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU tag length. + */ +extern rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length); + +/* Function Name: + * rtk_cpu_tagLength_get + * Description: + * Get CPU tag length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU tag length. + */ +extern rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength); + +/* Function Name: + * rtk_cpu_acceptLength_set + * Description: + * Set CPU accept length. + * Input: + * length - CPU tag length. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can set CPU accept length. + */ +extern rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length); + +/* Function Name: + * rtk_cpu_acceptLength_get + * Description: + * Get CPU accept length. + * Input: + * None + * Output: + * pLength - CPU tag length. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input. + * Note: + * The API can get CPU accept length. + */ +extern rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength); + +/* Function Name: + * rtk_cpu_priRemap_set + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * new_pri - new internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri); + +/* Function Name: + * rtk_cpu_priRemap_get + * Description: + * Configure CPU priorities mapping to internal absolute priority. + * Input: + * int_pri - internal priority value. + * Output: + * pNew_pri - new internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri); + + +#endif /* __RTK_API_CPU_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/dot1x.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/dot1x.h new file mode 100755 index 00000000..ef0a05a0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/dot1x.h @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes 1X module high-layer API defination + * + */ + +#ifndef __RTK_API_DOT1X_H__ +#define __RTK_API_DOT1X_H__ + + +/* Type of port-based dot1x auth/unauth*/ +typedef enum rtk_dot1x_auth_status_e +{ + UNAUTH = 0, + AUTH, + AUTH_STATUS_END +} rtk_dot1x_auth_status_t; + +typedef enum rtk_dot1x_direction_e +{ + DIR_BOTH = 0, + DIR_IN, + DIRECTION_END +} rtk_dot1x_direction_t; + +/* unauth pkt action */ +typedef enum rtk_dot1x_unauth_action_e +{ + DOT1X_ACTION_DROP = 0, + DOT1X_ACTION_TRAP2CPU, + DOT1X_ACTION_GUESTVLAN, + DOT1X_ACTION_END +} rtk_dot1x_unauth_action_t; + +/* Function Name: + * rtk_dot1x_unauthPacketOper_set + * Description: + * Set 802.1x unauth action configuration. + * Input: + * port - Port id. + * unauth_action - 802.1X unauth action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action); + +/* Function Name: + * rtk_dot1x_unauthPacketOper_get + * Description: + * Get 802.1x unauth action configuration. + * Input: + * port - Port id. + * Output: + * pUnauth_action - 802.1X unauth action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get 802.1x unauth action configuration. + * The unauth action is as following: + * - DOT1X_ACTION_DROP + * - DOT1X_ACTION_TRAP2CPU + * - DOT1X_ACTION_GUESTVLAN + */ +extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action); + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_set + * Description: + * Set 802.1x EAPOL packet trap to CPU configuration + * Input: + * enable - The status of 802.1x EAPOL packet. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_eapolFrame2CpuEnable_get + * Description: + * Get 802.1x EAPOL packet trap to CPU configuration + * Input: + * None + * Output: + * pEnable - The status of 802.1x EAPOL packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to + * be trapped to CPU. + * The status of EAPOL frame trap to CPU is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_dot1x_portBasedEnable_set + * Description: + * Set 802.1x port-based enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error + * Note: + * The API can update the port-based port enable register content. If a port is 802.1x + * port based network access control "enabled", it should be authenticated so packets + * from that port won't be dropped or trapped to CPU. + * The status of 802.1x port-based network access control is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_portBasedEnable_get + * Description: + * Get 802.1x port-based enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the 802.1x port-based port status. + */ +extern rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_set + * Description: + * Set 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * port_auth - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error + * Note: + * The authenticated status of 802.1x port-based network access control is as following: + * - UNAUTH + * - AUTH + */ +extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth); + +/* Function Name: + * rtk_dot1x_portBasedAuthStatus_get + * Description: + * Get 802.1x port-based auth. port configuration + * Input: + * port - Port id. + * Output: + * pPort_auth - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based port auth.information. + */ +extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth); + +/* Function Name: + * rtk_dot1x_portBasedDirection_set + * Description: + * Set 802.1x port-based operational direction configuration + * Input: + * port - Port id. + * port_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error + * Note: + * The operate controlled direction of 802.1x port-based network access control is as following: + * - BOTH + * - IN + */ +extern rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction); + +/* Function Name: + * rtk_dot1x_portBasedDirection_get + * Description: + * Get 802.1X port-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pPort_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1x port-based operational direction information. + */ +extern rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction); + +/* Function Name: + * rtk_dot1x_macBasedEnable_set + * Description: + * Set 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * enable - The status of 802.1x port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port won't be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_macBasedEnable_get + * Description: + * Get 802.1x mac-based port enable configuration + * Input: + * port - Port id. + * Output: + * pEnable - The status of 802.1x port. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * If a port is 802.1x MAC based network access control "enabled", the incoming packets should + * be authenticated so packets from that port wont be dropped or trapped to CPU. + * The status of 802.1x MAC-based network access control is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_add + * Description: + * Add an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error + * Note: + * The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT, + * user can't add this MAC to auth status. + */ +extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid); + +/* Function Name: + * rtk_dot1x_macBasedAuthMac_del + * Description: + * Delete an authenticated MAC to ASIC + * Input: + * port - Port id. + * pAuth_mac - The authenticated MAC. + * fid - filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of + * the MAC and won't delete it from LUT. + */ +extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid); + +/* Function Name: + * rtk_dot1x_macBasedDirection_set + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * mac_direction - Operation direction + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error + * Note: + * The operate controlled direction of 802.1x mac-based network access control is as following: + * - BOTH + * - IN + */ +extern rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction); + +/* Function Name: + * rtk_dot1x_macBasedDirection_get + * Description: + * Get 802.1x mac-based operational direction configuration + * Input: + * port - Port id. + * Output: + * pMac_direction - Operation direction + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x mac-based operational direction information. + */ +extern rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction); + +/* Function Name: + * Set 802.1x guest VLAN configuration + * Description: + * Set 802.1x mac-based operational direction configuration + * Input: + * vid - 802.1x guest VLAN ID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operate controlled 802.1x guest VLAN + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid); + +/* Function Name: + * rtk_dot1x_guestVlan_get + * Description: + * Get 802.1x guest VLAN configuration + * Input: + * None + * Output: + * pVid - 802.1x guest VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN information. + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid); + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_set + * Description: + * Set 802.1x guest VLAN to auth host configuration + * Input: + * enable - The status of guest VLAN to auth host. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The operational direction of 802.1x guest VLAN to auth host control is as following: + * - ENABLED + * - DISABLED + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable); + +/* Function Name: + * rtk_dot1x_guestVlan2Auth_get + * Description: + * Get 802.1x guest VLAN to auth host configuration + * Input: + * None + * Output: + * pEnable - The status of guest VLAN to auth host. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get 802.1x guest VLAN to auth host information. + */ +extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable); + + +#endif /* __RTK_API_DOT1X_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/eee.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/eee.h new file mode 100755 index 00000000..b670998c --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/eee.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes EEE module high-layer API defination + * + */ + +#ifndef __RTK_API_EEE_H__ +#define __RTK_API_EEE_H__ + +/* Function Name: + * rtk_eee_init + * Description: + * EEE function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize EEE status. + */ +extern rtk_api_ret_t rtk_eee_init(void); + +/* Function Name: + * rtk_eee_portEnable_set + * Description: + * Set enable status of EEE function. + * Input: + * port - port id. + * enable - enable EEE status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_eee_portEnable_get + * Description: + * Get port admin configuration of the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can set EEE function to the specific port. + * The configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + + +#endif /* __RTK_API_EEE_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/i2c.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/i2c.h new file mode 100755 index 00000000..2c7f0756 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/i2c.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes I2C module high-layer API defination + * + */ + + +#ifndef __RTK_API_I2C_H__ +#define __RTK_API_I2C_H__ +#include + +#define I2C_GPIO_MAX_GROUP (3) + +typedef enum rtk_I2C_16bit_mode_e{ + I2C_LSB_16BIT_MODE = 0, + I2C_70B_LSB_16BIT_MODE, + I2C_Mode_END +}rtk_I2C_16bit_mode_t; + + +typedef enum rtk_I2C_gpio_pin_e{ + I2C_GPIO_PIN_8_9 = 0, + I2C_GPIO_PIN_15_16 , + I2C_GPIO_PIN_35_36 , + I2C_GPIO_PIN_END +}rtk_I2C_gpio_pin_t; + + +/* Function Name: + * rtk_i2c_data_read + * Description: + * read i2c slave device register. + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * Output: + * pRegData - read data + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can access i2c slave and read i2c slave device register. + */ +extern rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData); + +/* Function Name: + * rtk_i2c_data_write + * Description: + * write data to i2c slave device register + * Input: + * deviceAddr - access Slave device address + * slaveRegAddr - access Slave register address + * regData - data to set + * Output: + * None + * Return: + * RT_ERR_OK - OK + * Note: + * The API can access i2c slave and setting i2c slave device register. + */ +extern rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData); + + +/* Function Name: + * rtk_i2c_init + * Description: + * I2C smart function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * This API is used to initialize EEE status. + * need used GPIO pins + * OpenDrain and clock + */ +extern rtk_api_ret_t rtk_i2c_init(void); + +/* Function Name: + * rtk_i2c_mode_set + * Description: + * Set I2C data byte-order. + * Input: + * i2cmode - byte-order mode + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * This API can set I2c traffic's byte-order . + */ +extern rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode); + +/* Function Name: + * rtk_i2c_mode_get + * Description: + * Get i2c traffic byte-order setting. + * Input: + * None + * Output: + * pI2cMode - i2c byte-order + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c traffic byte-order setting. + */ +extern rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode); + + +/* Function Name: + * rtk_i2c_gpioPinGroup_set + * Description: + * Set i2c SDA & SCL used GPIO pins group. + * Input: + * pins_group - GPIO pins group + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The API can set i2c used gpio pins group. + * There are three group pins could be used + */ +extern rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group); + +/* Function Name: + * rtk_i2c_gpioPinGroup_get + * Description: + * Get i2c SDA & SCL used GPIO pins group. + * Input: + * None + * Output: + * pPins_group - GPIO pins group + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - input parameter is null pointer + * Note: + * The API can get i2c used gpio pins group. + * There are three group pins could be used + */ +extern rtk_api_ret_t rtk_i2c_gpioPinGroup_get(rtk_I2C_gpio_pin_t * pPins_group); + + + + + + + +#endif + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/igmp.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/igmp.h new file mode 100755 index 00000000..f088b0cc --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/igmp.h @@ -0,0 +1,769 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes IGMP module high-layer API defination + * + */ + +#ifndef __RTK_API_IGMP_H__ +#define __RTK_API_IGMP_H__ + +/* + * Data Type Declaration + */ +typedef enum rtk_igmp_type_e +{ + IGMP_IPV4 = 0, + IGMP_PPPOE_IPV4, + IGMP_MLD, + IGMP_PPPOE_MLD, + IGMP_TYPE_END +} rtk_igmp_type_t; + +typedef enum rtk_trap_igmp_action_e +{ + IGMP_ACTION_FORWARD = 0, + IGMP_ACTION_TRAP2CPU, + IGMP_ACTION_DROP, + IGMP_ACTION_ASIC, + IGMP_ACTION_END +} rtk_igmp_action_t; + +typedef enum rtk_igmp_protocol_e +{ + PROTOCOL_IGMPv1 = 0, + PROTOCOL_IGMPv2, + PROTOCOL_IGMPv3, + PROTOCOL_MLDv1, + PROTOCOL_MLDv2, + PROTOCOL_END +} rtk_igmp_protocol_t; + +typedef enum rtk_igmp_tableFullAction_e +{ + IGMP_TABLE_FULL_FORWARD = 0, + IGMP_TABLE_FULL_DROP, + IGMP_TABLE_FULL_TRAP, + IGMP_TABLE_FULL_OP_END +}rtk_igmp_tableFullAction_t; + +typedef enum rtk_igmp_checksumErrorAction_e +{ + IGMP_CRC_ERR_DROP = 0, + IGMP_CRC_ERR_TRAP, + IGMP_CRC_ERR_FORWARD, + IGMP_CRC_ERR_OP_END +}rtk_igmp_checksumErrorAction_t; + +typedef enum rtk_igmp_bypassGroup_e +{ + IGMP_BYPASS_224_0_0_X = 0, + IGMP_BYPASS_224_0_1_X, + IGMP_BYPASS_239_255_255_X, + IGMP_BYPASS_IPV6_00XX, + IGMP_BYPASS_GROUP_END +}rtk_igmp_bypassGroup_t; + + +typedef struct rtk_igmp_dynamicRouterPort_s +{ + rtk_enable_t dynamicRouterPort0Valid; + rtk_port_t dynamicRouterPort0; + rtk_uint32 dynamicRouterPort0Timer; + rtk_enable_t dynamicRouterPort1Valid; + rtk_port_t dynamicRouterPort1; + rtk_uint32 dynamicRouterPort1Timer; + +}rtk_igmp_dynamicRouterPort_t; + +typedef struct rtk_igmp_rxPktEnable_s +{ + rtk_enable_t rxQuery; + rtk_enable_t rxReport; + rtk_enable_t rxLeave; + rtk_enable_t rxMRP; + rtk_enable_t rxMcast; +}rtk_igmp_rxPktEnable_t; + +typedef struct rtk_igmp_groupInfo_s +{ + rtk_enable_t valid; + rtk_portmask_t member; + rtk_uint32 timer[RTK_PORT_MAX]; + rtk_uint32 reportSuppFlag; +}rtk_igmp_groupInfo_t; + +typedef enum rtk_igmp_ReportLeaveFwdAct_e +{ + IGMP_REPORT_LEAVE_TO_ROUTER = 0, + IGMP_REPORT_LEAVE_TO_ALLPORT, + IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV, + IGMP_REPORT_LEAVE_ACT_END +}rtk_igmp_ReportLeaveFwdAct_t; + +/* Function Name: + * rtk_igmp_init + * Description: + * This API enables H/W IGMP and set a default initial configuration. + * Input: + * None. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API enables H/W IGMP and set a default initial configuration. + */ +extern rtk_api_ret_t rtk_igmp_init(void); + +/* Function Name: + * rtk_igmp_state_set + * Description: + * This API set H/W IGMP state. + * Input: + * enabled - H/W IGMP state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set H/W IGMP state. + */ +extern rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_igmp_state_get + * Description: + * This API get H/W IGMP state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current H/W IGMP state. + */ +extern rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_igmp_static_router_port_set + * Description: + * Configure static router port + * Input: + * pPortmask - Static Port mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set static router port + */ +extern rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_static_router_port_get + * Description: + * Get static router port + * Input: + * None. + * Output: + * pPortmask - Static port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API get static router port + */ +extern rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_protocol_set + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +extern rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action); + +/* Function Name: + * rtk_igmp_protocol_get + * Description: + * set IGMP/MLD protocol action + * Input: + * port - Port ID + * protocol - IGMP/MLD protocol + * action - Per-port and per-protocol IGMP action seeting + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * This API set IGMP/MLD protocol action + */ +extern rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction); + +/* Function Name: + * rtk_igmp_fastLeave_set + * Description: + * set IGMP/MLD FastLeave state + * Input: + * state - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set IGMP/MLD FastLeave state + */ +extern rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state); + +/* Function Name: + * rtk_igmp_fastLeave_get + * Description: + * get IGMP/MLD FastLeave state + * Input: + * None + * Output: + * pState - ENABLED: Enable FastLeave, DISABLED: disable FastLeave + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - NULL pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get IGMP/MLD FastLeave state + */ +extern rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState); + +/* Function Name: + * rtk_igmp_maxGroup_set + * Description: + * Set per port multicast group learning limit. + * Input: + * port - Port ID + * group - The number of multicast group learning limit. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_OUT_OF_RANGE - parameter out of range + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API set per port multicast group learning limit. + */ +extern rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group); + +/* Function Name: + * rtk_igmp_maxGroup_get + * Description: + * Get per port multicast group learning limit. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning limit. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning limit. + */ +extern rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup); + +/* Function Name: + * rtk_igmp_currentGroup_get + * Description: + * Get per port multicast group learning count. + * Input: + * port - Port ID + * Output: + * pGroup - The number of multicast group learning count. + * Return: + * RT_ERR_OK - OK + * RT_ERR_PORT_ID - Error Port ID + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API get per port multicast group learning count. + */ +extern rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup); + +/* Function Name: + * rtk_igmp_tableFullAction_set + * Description: + * set IGMP/MLD Table Full Action + * Input: + * action - Table Full Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action); + +/* Function Name: + * rtk_igmp_tableFullAction_get + * Description: + * get IGMP/MLD Table Full Action + * Input: + * None + * Output: + * pAction - Table Full Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction); + +/* Function Name: + * rtk_igmp_checksumErrorAction_set + * Description: + * set IGMP/MLD Checksum Error Action + * Input: + * action - Checksum error Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action); + +/* Function Name: + * rtk_igmp_checksumErrorAction_get + * Description: + * get IGMP/MLD Checksum Error Action + * Input: + * None + * Output: + * pAction - Checksum error Action + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction); + +/* Function Name: + * rtk_igmp_leaveTimer_set + * Description: + * set IGMP/MLD Leave timer + * Input: + * timer - Leave timer + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer); + +/* Function Name: + * rtk_igmp_leaveTimer_get + * Description: + * get IGMP/MLD Leave timer + * Input: + * None + * Output: + * pTimer - Leave Timer. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer); + +/* Function Name: + * rtk_igmp_queryInterval_set + * Description: + * set IGMP/MLD Query Interval + * Input: + * interval - Query Interval + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval); + +/* Function Name: + * rtk_igmp_queryInterval_get + * Description: + * get IGMP/MLD Query Interval + * Input: + * None. + * Output: + * pInterval - Query Interval + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval); + +/* Function Name: + * rtk_igmp_robustness_set + * Description: + * set IGMP/MLD Robustness value + * Input: + * robustness - Robustness value + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Error Input + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness); + +/* Function Name: + * rtk_igmp_robustness_get + * Description: + * get IGMP/MLD Robustness value + * Input: + * None + * Output: + * pRobustness - Robustness value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +extern rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness); + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_set + * Description: + * Configure dynamic router port allow option + * Input: + * pPortmask - Dynamic Port allow mask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_dynamicRouterRortAllow_get + * Description: + * Get dynamic router port allow option + * Input: + * None. + * Output: + * pPortmask - Dynamic Port allow mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_igmp_dynamicRouterPort_get + * Description: + * Get dynamic router port + * Input: + * None. + * Output: + * pDynamicRouterPort - Dynamic Router Port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error parameter + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort); + +/* Function Name: + * rtk_igmp_suppressionEnable_set + * Description: + * Configure IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * reportSuppression - Report suppression + * leaveSuppression - Leave suppression + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression); + +/* Function Name: + * rtk_igmp_suppressionEnable_get + * Description: + * Get IGMPv1/v2 & MLDv1 Report/Leave/Done suppression + * Input: + * None + * Output: + * pReportSuppression - Report suppression + * pLeaveSuppression - Leave suppression + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression); + +/* Function Name: + * rtk_igmp_portRxPktEnable_set + * Description: + * Configure IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg); + +/* Function Name: + * rtk_igmp_portRxPktEnable_get + * Description: + * Get IGMP/MLD RX Packet configuration + * Input: + * port - Port ID + * pRxCfg - RX Packet Configuration + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg); + +/* Function Name: + * rtk_igmp_groupInfo_get + * Description: + * Get IGMP/MLD Group database + * Input: + * indes - Index (0~255) + * Output: + * pGroup - Group database information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup); + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_set + * Description: + * Set Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action); + +/* Function Name: + * rtk_igmp_ReportLeaveFwdAction_get + * Description: + * Get Report Leave packet forwarding action + * Input: + * action - Action + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction); + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_set + * Description: + * Set the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * enabled - Action 1: drop, 0:pass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_igmp_dropLeaveZeroEnable_get + * Description: + * Get the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * None + * Output: + * pEnabled. - Action 1: drop, 0:pass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_igmp_bypassGroupRange_set + * Description: + * Set Bypass group + * Input: + * group - bypassed group + * enabled - enabled 1: Bypassed, 0: not bypass + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled); + +/* Function Name: + * rtk_igmp_bypassGroupRange_get + * Description: + * get Bypass group + * Input: + * group - bypassed group + * Output: + * pEnable - enabled 1: Bypassed, 0: not bypass + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable); + +#endif /* __RTK_API_IGMP_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/interrupt.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/interrupt.h new file mode 100755 index 00000000..f2689ebc --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/interrupt.h @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Interrupt module high-layer API defination + * + */ + +#ifndef __RTK_API_INTERRUPT_H__ +#define __RTK_API_INTERRUPT_H__ + + +/* + * Data Type Declaration + */ +#define RTK_MAX_NUM_OF_INTERRUPT_TYPE 1 + + +typedef struct rtk_int_status_s +{ + rtk_uint16 value[RTK_MAX_NUM_OF_INTERRUPT_TYPE]; +} rtk_int_status_t; + +typedef struct rtk_int_info_s +{ + rtk_portmask_t portMask; + rtk_uint32 meterMask; + rtk_uint32 systemLearnOver; +}rtk_int_info_t; + +typedef enum rtk_int_type_e +{ + INT_TYPE_LINK_STATUS = 0, + INT_TYPE_METER_EXCEED, + INT_TYPE_LEARN_LIMIT, + INT_TYPE_LINK_SPEED, + INT_TYPE_CONGEST, + INT_TYPE_GREEN_FEATURE, + INT_TYPE_LOOP_DETECT, + INT_TYPE_8051, + INT_TYPE_CABLE_DIAG, + INT_TYPE_ACL, + INT_TYPE_RESERVED, /* Unused */ + INT_TYPE_SLIENT, + INT_TYPE_END +}rtk_int_type_t; + +typedef enum rtk_int_advType_e +{ + ADV_L2_LEARN_PORT_MASK = 0, + ADV_SPEED_CHANGE_PORT_MASK, + ADV_SPECIAL_CONGESTION_PORT_MASK, + ADV_PORT_LINKDOWN_PORT_MASK, + ADV_PORT_LINKUP_PORT_MASK, + ADV_METER_EXCEED_MASK, + ADV_RLDP_LOOPED, + ADV_RLDP_RELEASED, + ADV_END, +} rtk_int_advType_t; + +typedef enum rtk_int_polarity_e +{ + INT_POLAR_HIGH = 0, + INT_POLAR_LOW, + INT_POLAR_END +} rtk_int_polarity_t; + +/* Function Name: + * rtk_int_polarity_set + * Description: + * Set interrupt polarity configuration. + * Input: + * type - Interruptpolarity type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set interrupt polarity configuration. + */ +extern rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type); + +/* Function Name: + * rtk_int_polarity_get + * Description: + * Get interrupt polarity configuration. + * Input: + * None + * Output: + * pType - Interruptpolarity type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get interrupt polarity configuration. + */ +extern rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType); + +/* Function Name: + * rtk_int_control_set + * Description: + * Set interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set interrupt status configuration. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS + * - INT_TYPE_METER_EXCEED + * - INT_TYPE_LEARN_LIMIT + * - INT_TYPE_LINK_SPEED + * - INT_TYPE_CONGEST + * - INT_TYPE_GREEN_FEATURE + * - INT_TYPE_LOOP_DETECT + * - INT_TYPE_8051, + * - INT_TYPE_CABLE_DIAG, + * - INT_TYPE_ACL, + * - INT_TYPE_SLIENT + */ +extern rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_int_control_get + * Description: + * Get interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * Output: + * pEnable - Interrupt status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt status configuration. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS + * - INT_TYPE_METER_EXCEED + * - INT_TYPE_LEARN_LIMIT + * - INT_TYPE_LINK_SPEED + * - INT_TYPE_CONGEST + * - INT_TYPE_GREEN_FEATURE + * - INT_TYPE_LOOP_DETECT + * - INT_TYPE_8051, + * - INT_TYPE_CABLE_DIAG, + * - INT_TYPE_ACL, + * - INT_TYPE_SLIENT + */ +extern rtk_api_ret_t rtk_int_control_get(rtk_int_type_t type, rtk_enable_t* pEnable); + +/* Function Name: + * rtk_int_status_set + * Description: + * Set interrupt trigger status to clean. + * Input: + * None + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can clean interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) + * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) + * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) + * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) + * - INT_TYPE_CONGEST (value[0] (Bit4)) + * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) + * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) + * - INT_TYPE_8051 (value[0] (Bit7)) + * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) + * - INT_TYPE_ACL (value[0] (Bit9)) + * - INT_TYPE_SLIENT (value[0] (Bit11)) + * The status will be cleared after execute this API. + */ +extern rtk_api_ret_t rtk_int_status_set(rtk_int_status_t *pStatusMask); + +/* Function Name: + * rtk_int_status_get + * Description: + * Get interrupt trigger status. + * Input: + * None + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) + * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) + * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) + * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) + * - INT_TYPE_CONGEST (value[0] (Bit4)) + * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) + * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) + * - INT_TYPE_8051 (value[0] (Bit7)) + * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) + * - INT_TYPE_ACL (value[0] (Bit9)) + * - INT_TYPE_SLIENT (value[0] (Bit11)) + * + */ +extern rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask); + +/* Function Name: + * rtk_int_advanceInfo_get + * Description: + * Get interrupt advanced information. + * Input: + * adv_type - Advanced interrupt type. + * Output: + * info - Information per type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get advanced information when interrupt happened. + * The status will be cleared after execute this API. + */ +extern rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t* info); + + +#endif /* __RTK_API_INTERRUPT_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/l2.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/l2.h new file mode 100755 index 00000000..e0ccdbe3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/l2.h @@ -0,0 +1,1181 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes L2 module high-layer API defination + * + */ + +#ifndef __RTK_API_L2_H__ +#define __RTK_API_L2_H__ + + +/* + * Data Type Declaration + */ +#define RTK_MAX_NUM_OF_LEARN_LIMIT (rtk_switch_maxLutAddrNumber_get()) + +#define RTK_MAC_ADDR_LEN 6 +#define RTK_MAX_LUT_ADDRESS (RTK_MAX_NUM_OF_LEARN_LIMIT) +#define RTK_MAX_LUT_ADDR_ID (RTK_MAX_LUT_ADDRESS - 1) + +typedef rtk_uint32 rtk_l2_age_time_t; + +typedef enum rtk_l2_flood_type_e +{ + FLOOD_UNKNOWNDA = 0, + FLOOD_UNKNOWNMC, + FLOOD_BC, + FLOOD_END +} rtk_l2_flood_type_t; + +typedef rtk_uint32 rtk_l2_flushItem_t; + +typedef enum rtk_l2_flushType_e +{ + FLUSH_TYPE_BY_PORT = 0, /* physical port */ + FLUSH_TYPE_BY_PORT_VID, /* physical port + VID */ + FLUSH_TYPE_BY_PORT_FID, /* physical port + FID */ + FLUSH_TYPE_END +} rtk_l2_flushType_t; + +typedef struct rtk_l2_flushCfg_s +{ + rtk_enable_t flushByVid; + rtk_vlan_t vid; + rtk_enable_t flushByFid; + rtk_uint32 fid; + rtk_enable_t flushByPort; + rtk_port_t port; + rtk_enable_t flushByMac; + rtk_mac_t ucastAddr; + rtk_enable_t flushStaticAddr; + rtk_enable_t flushAddrOnAllPorts; /* this is used when flushByVid */ +} rtk_l2_flushCfg_t; + +typedef enum rtk_l2_read_method_e{ + + READMETHOD_MAC = 0, + READMETHOD_ADDRESS, + READMETHOD_NEXT_ADDRESS, + READMETHOD_NEXT_L2UC, + READMETHOD_NEXT_L2MC, + READMETHOD_NEXT_L3MC, + READMETHOD_NEXT_L2L3MC, + READMETHOD_NEXT_L2UCSPA, + READMETHOD_END +}rtk_l2_read_method_t; + +/* l2 limit learning count action */ +typedef enum rtk_l2_limitLearnCntAction_e +{ + LIMIT_LEARN_CNT_ACTION_DROP = 0, + LIMIT_LEARN_CNT_ACTION_FORWARD, + LIMIT_LEARN_CNT_ACTION_TO_CPU, + LIMIT_LEARN_CNT_ACTION_END +} rtk_l2_limitLearnCntAction_t; + +typedef enum rtk_l2_ipmc_lookup_type_e +{ + LOOKUP_MAC = 0, + LOOKUP_IP, + LOOKUP_IP_VID, + LOOKUP_END +} rtk_l2_ipmc_lookup_type_t; + +/* l2 address table - unicast data structure */ +typedef struct rtk_l2_ucastAddr_s +{ + rtk_mac_t mac; + rtk_uint32 ivl; + rtk_uint32 cvid; + rtk_uint32 fid; + rtk_uint32 efid; + rtk_uint32 port; + rtk_uint32 sa_block; + rtk_uint32 da_block; + rtk_uint32 auth; + rtk_uint32 is_static; + rtk_uint32 priority; + rtk_uint32 sa_pri_en; + rtk_uint32 fwd_pri_en; + rtk_uint32 address; +}rtk_l2_ucastAddr_t; + +/* l2 address table - multicast data structure */ +typedef struct rtk_l2_mcastAddr_s +{ + rtk_uint32 vid; + rtk_mac_t mac; + rtk_uint32 fid; + rtk_portmask_t portmask; + rtk_uint32 ivl; + rtk_uint32 priority; + rtk_uint32 fwd_pri_en; + rtk_uint32 igmp_asic; + rtk_uint32 igmp_index; + rtk_uint32 address; +}rtk_l2_mcastAddr_t; + +/* l2 address table - ip multicast data structure */ +typedef struct rtk_l2_ipMcastAddr_s +{ + ipaddr_t dip; + ipaddr_t sip; + rtk_portmask_t portmask; + rtk_uint32 priority; + rtk_uint32 fwd_pri_en; + rtk_uint32 igmp_asic; + rtk_uint32 igmp_index; + rtk_uint32 address; +}rtk_l2_ipMcastAddr_t; + +/* l2 address table - ip VID multicast data structure */ +typedef struct rtk_l2_ipVidMcastAddr_s +{ + ipaddr_t dip; + ipaddr_t sip; + rtk_uint32 vid; + rtk_portmask_t portmask; + rtk_uint32 address; +}rtk_l2_ipVidMcastAddr_t; + +typedef struct rtk_l2_addr_table_s +{ + rtk_uint32 index; + ipaddr_t sip; + ipaddr_t dip; + rtk_mac_t mac; + rtk_uint32 sa_block; + rtk_uint32 auth; + rtk_portmask_t portmask; + rtk_uint32 age; + rtk_uint32 ivl; + rtk_uint32 cvid; + rtk_uint32 fid; + rtk_uint32 is_ipmul; + rtk_uint32 is_static; + rtk_uint32 is_ipvidmul; + rtk_uint32 l3_vid; +}rtk_l2_addr_table_t; + +typedef enum rtk_l2_clearStatus_e +{ + L2_CLEAR_STATE_FINISH = 0, + L2_CLEAR_STATE_BUSY, + L2_CLEAR_STATE_END +}rtk_l2_clearStatus_t; + +/* Function Name: + * rtk_l2_init + * Description: + * Initialize l2 module of the specified device. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Initialize l2 module before calling any l2 APIs. + */ +extern rtk_api_ret_t rtk_l2_init(void); + +/* Function Name: + * rtk_l2_addr_add + * Description: + * Add LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * pL2_data - Unicast entry parameter + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address already existed in LUT, it will udpate the status of the entry. + * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries + * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +extern rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_addr_get + * Description: + * Get LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address existed in LUT, it will return the port and fid where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +extern rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_addr_next_get + * Description: + * Get Next LUT unicast entry. + * Input: + * read_method - The reading method. + * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA + * pAddress - The Address ID + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next unicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_addr_del + * Description: + * Delete LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * fid - Filtering database + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +extern rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); + +/* Function Name: + * rtk_l2_mcastAddr_add + * Description: + * Add LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address already existed in the LUT, it will udpate the + * port mask of the entry. Otherwise, it will find an empty or asic auto learned + * entry to write. If all the entries with the same hash value can't be replaced, + * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_mcastAddr_get + * Description: + * Get LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address existed in the LUT, it will return the port where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_mcastAddr_next_get + * Description: + * Get Next L2 Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next L2 multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all multicast entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_mcastAddr_del + * Description: + * Delete LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +extern rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_add + * Description: + * Add Lut IP multicast entry + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user + * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to + * forward IP multicast frame directly without flooding. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_get + * Description: + * Get LUT IP multicast entry. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Lut table of IP multicast entry. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_next_get + * Description: + * Get Next IP Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipMcastAddr_del + * Description: + * Delete a ip multicast address entry from the specified device. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can delete a IP multicast address entry from the specified device. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_add + * Description: + * Add Lut IP multicast+VID entry + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_get + * Description: + * Get LUT IP multicast+VID entry. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_next_get + * Description: + * Get Next IP Multicast+VID entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ipVidMcastAddr_del + * Description: + * Delete a ip multicast+VID address entry from the specified device. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); + +/* Function Name: + * rtk_l2_ucastAddr_flush + * Description: + * Flush L2 mac address by type in the specified device (both dynamic and static). + * Input: + * pConfig - flush configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * flushByVid - 1: Flush by VID, 0: Don't flush by VID + * vid - VID (0 ~ 4095) + * flushByFid - 1: Flush by FID, 0: Don't flush by FID + * fid - FID (0 ~ 15) + * flushByPort - 1: Flush by Port, 0: Don't flush by Port + * port - Port ID + * flushByMac - Not Supported + * ucastAddr - Not Supported + * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries + * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. + */ +extern rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig); + +/* Function Name: + * rtk_l2_table_clear + * Description: + * Flush all static & dynamic entries in LUT. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_table_clear(void); + +/* Function Name: + * rtk_l2_table_clearStatus_get + * Description: + * Get table clear status + * Input: + * None + * Output: + * pStatus - Clear status, 1:Busy, 0:finish + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus); + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_set + * Description: + * Set HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * enable - link down flush status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_get + * Description: + * Get HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * Output: + * pEnable - link down flush status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_l2_agingEnable_set + * Description: + * Set L2 LUT aging status per port setting. + * Input: + * port - Port id. + * enable - Aging status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can be used to set L2 LUT aging status per port. + */ +extern rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_l2_agingEnable_get + * Description: + * Get L2 LUT aging status per port setting. + * Input: + * port - Port id. + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can be used to get L2 LUT aging function per port. + */ +extern rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_l2_limitLearningCnt_set + * Description: + * Set per-Port auto learning limit number + * Input: + * port - Port id. + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set per-port ASIC auto learning limit number from 0(disable learning) + * to 8k. + */ +extern rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt); + +/* Function Name: + * rtk_l2_limitLearningCnt_get + * Description: + * Get per-Port auto learning limit number + * Input: + * port - Port id. + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning limit number. + */ +extern rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_set + * Description: + * Set System auto learning limit number + * Input: + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set system ASIC auto learning limit number from 0(disable learning) + * to 2112. + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt); + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_get + * Description: + * Get System auto learning limit number + * Input: + * None + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get system ASIC auto learning limit number. + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt); + +/* Function Name: + * rtk_l2_limitLearningCntAction_set + * Description: + * Configure auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action); + +/* Function Name: + * rtk_l2_limitLearningCntAction_get + * Description: + * Get auto learn over limit number action. + * Input: + * port - Port id. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction); + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_set + * Description: + * Configure system auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action); + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_get + * Description: + * Get system auto learn over limit number action. + * Input: + * None. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction); + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_set + * Description: + * Configure system auto learn portmask + * Input: + * pPortmask - Port Mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_get + * Description: + * get system auto learn portmask + * Input: + * None + * Output: + * pPortmask - Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer. + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_learningCnt_get + * Description: + * Get per-Port current auto learning number + * Input: + * port - Port id. + * Output: + * pMac_cnt - ASIC auto learning entries number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning number + */ +extern rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); + +/* Function Name: + * rtk_l2_floodPortMask_set + * Description: + * Set flooding portmask + * Input: + * type - flooding type. + * pFlood_portmask - flooding porkmask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +extern rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); + +/* Function Name: + * rtk_l2_floodPortMask_get + * Description: + * Get flooding portmask + * Input: + * type - flooding type. + * Output: + * pFlood_portmask - flooding porkmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +extern rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); + +/* Function Name: + * rtk_l2_localPktPermit_set + * Description: + * Set permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * permit - permittion status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid permit value. + * Note: + * This API is setted to permit frame if its source port is equal to destination port. + */ +extern rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit); + +/* Function Name: + * rtk_l2_localPktPermit_get + * Description: + * Get permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * Output: + * pPermit - permittion status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API is to get permittion status for frames if its source port is equal to destination port. + */ +extern rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit); + +/* Function Name: + * rtk_l2_aging_set + * Description: + * Set LUT agging out speed + * Input: + * aging_time - Agging out time. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can set LUT agging out period for each entry and the range is from 14s to 800s. + */ +extern rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time); + +/* Function Name: + * rtk_l2_aging_get + * Description: + * Get LUT agging out time + * Input: + * None + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get LUT agging out period for each entry. + */ +extern rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time); + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_set + * Description: + * Set Lut IP multicast lookup function + * Input: + * type - Lookup type for IPMC packet. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can work with rtk_l2_ipMcastAddrLookupException_add. + * If users set the lookup type to DIP, the group in exception table + * will be lookup by DIP+SIP + * If users set the lookup type to DIP+SIP, the group in exception table + * will be lookup by only DIP + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type); + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_get + * Description: + * Get Lut IP multicast lookup function + * Input: + * None. + * Output: + * pType - Lookup type for IPMC packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType); + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_set + * Description: + * Set IPMC packet forward to rounter port also or not + * Input: + * enabled - 1: Inlcude router port, 0, exclude router port + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_get + * Description: + * Get IPMC packet forward to rounter port also or not + * Input: + * None. + * Output: + * pEnabled - 1: Inlcude router port, 0, exclude router port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_add + * Description: + * Add an IP Multicast entry to group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * pPortmask - portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Add an entry to IP Multicast Group table. + */ +extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_del + * Description: + * Delete an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid); + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_get + * Description: + * get an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * pPortmask - member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_l2_entry_get + * Description: + * Get LUT unicast entry. + * Input: + * pL2_entry - Index field in the structure. + * Output: + * pL2_entry - other fields such as MAC, port, age... + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API is used to get address by index from 0~2111. + */ +extern rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry); + + +#endif /* __RTK_API_L2_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/leaky.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/leaky.h new file mode 100755 index 00000000..13ef60df --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/leaky.h @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Leaky module high-layer API defination + * + */ + +#ifndef __RTK_API_LEAKY_H__ +#define __RTK_API_LEAKY_H__ + + +typedef enum rtk_leaky_type_e +{ + LEAKY_BRG_GROUP = 0, + LEAKY_FD_PAUSE, + LEAKY_SP_MCAST, + LEAKY_1X_PAE, + LEAKY_UNDEF_BRG_04, + LEAKY_UNDEF_BRG_05, + LEAKY_UNDEF_BRG_06, + LEAKY_UNDEF_BRG_07, + LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + LEAKY_UNDEF_BRG_09, + LEAKY_UNDEF_BRG_0A, + LEAKY_UNDEF_BRG_0B, + LEAKY_UNDEF_BRG_0C, + LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + LEAKY_8021AB, + LEAKY_UNDEF_BRG_0F, + LEAKY_BRG_MNGEMENT, + LEAKY_UNDEFINED_11, + LEAKY_UNDEFINED_12, + LEAKY_UNDEFINED_13, + LEAKY_UNDEFINED_14, + LEAKY_UNDEFINED_15, + LEAKY_UNDEFINED_16, + LEAKY_UNDEFINED_17, + LEAKY_UNDEFINED_18, + LEAKY_UNDEFINED_19, + LEAKY_UNDEFINED_1A, + LEAKY_UNDEFINED_1B, + LEAKY_UNDEFINED_1C, + LEAKY_UNDEFINED_1D, + LEAKY_UNDEFINED_1E, + LEAKY_UNDEFINED_1F, + LEAKY_GMRP, + LEAKY_GVRP, + LEAKY_UNDEF_GARP_22, + LEAKY_UNDEF_GARP_23, + LEAKY_UNDEF_GARP_24, + LEAKY_UNDEF_GARP_25, + LEAKY_UNDEF_GARP_26, + LEAKY_UNDEF_GARP_27, + LEAKY_UNDEF_GARP_28, + LEAKY_UNDEF_GARP_29, + LEAKY_UNDEF_GARP_2A, + LEAKY_UNDEF_GARP_2B, + LEAKY_UNDEF_GARP_2C, + LEAKY_UNDEF_GARP_2D, + LEAKY_UNDEF_GARP_2E, + LEAKY_UNDEF_GARP_2F, + LEAKY_IGMP, + LEAKY_IPMULTICAST, + LEAKY_CDP, + LEAKY_CSSTP, + LEAKY_LLDP, + LEAKY_END, +}rtk_leaky_type_t; + +/* Function Name: + * rtk_leaky_vlan_set + * Description: + * Set VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set VLAN leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_leaky_vlan_get + * Description: + * Get VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get VLAN leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_leaky_portIsolation_set + * Description: + * Set port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set port isolation leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_leaky_portIsolation_get + * Description: + * Get port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get port isolation leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +extern rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable); + +#endif /* __RTK_API_LEAKY_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/led.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/led.h new file mode 100755 index 00000000..71acc7c9 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/led.h @@ -0,0 +1,481 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes LED module high-layer API defination + * + */ + +#ifndef __RTK_API_LED_H__ +#define __RTK_API_LED_H__ + +typedef enum rtk_led_operation_e +{ + LED_OP_SCAN=0, + LED_OP_PARALLEL, + LED_OP_SERIAL, + LED_OP_END, +}rtk_led_operation_t; + + +typedef enum rtk_led_active_e +{ + LED_ACTIVE_HIGH=0, + LED_ACTIVE_LOW, + LED_ACTIVE_END, +}rtk_led_active_t; + +typedef enum rtk_led_config_e +{ + LED_CONFIG_LEDOFF=0, + LED_CONFIG_DUPCOL, + LED_CONFIG_LINK_ACT, + LED_CONFIG_SPD1000, + LED_CONFIG_SPD100, + LED_CONFIG_SPD10, + LED_CONFIG_SPD1000ACT, + LED_CONFIG_SPD100ACT, + LED_CONFIG_SPD10ACT, + LED_CONFIG_SPD10010ACT, + LED_CONFIG_LOOPDETECT, + LED_CONFIG_EEE, + LED_CONFIG_LINKRX, + LED_CONFIG_LINKTX, + LED_CONFIG_MASTER, + LED_CONFIG_ACT, + LED_CONFIG_END, +}rtk_led_congig_t; + +typedef struct rtk_led_ability_s +{ + rtk_enable_t link_10m; + rtk_enable_t link_100m; + rtk_enable_t link_500m; + rtk_enable_t link_1000m; + rtk_enable_t act_rx; + rtk_enable_t act_tx; +}rtk_led_ability_t; + +typedef enum rtk_led_blink_rate_e +{ + LED_BLINKRATE_32MS=0, + LED_BLINKRATE_64MS, + LED_BLINKRATE_128MS, + LED_BLINKRATE_256MS, + LED_BLINKRATE_512MS, + LED_BLINKRATE_1024MS, + LED_BLINKRATE_48MS, + LED_BLINKRATE_96MS, + LED_BLINKRATE_END, +}rtk_led_blink_rate_t; + +typedef enum rtk_led_group_e +{ + LED_GROUP_0 = 0, + LED_GROUP_1, + LED_GROUP_2, + LED_GROUP_END +}rtk_led_group_t; + + +typedef enum rtk_led_force_mode_e +{ + LED_FORCE_NORMAL=0, + LED_FORCE_BLINK, + LED_FORCE_OFF, + LED_FORCE_ON, + LED_FORCE_END +}rtk_led_force_mode_t; + +typedef enum rtk_led_serialOutput_e +{ + SERIAL_LED_NONE = 0, + SERIAL_LED_0, + SERIAL_LED_0_1, + SERIAL_LED_0_2, + SERIAL_LED_END, +}rtk_led_serialOutput_t; + + +/* Function Name: + * rtk_led_enable_set + * Description: + * Set Led enable congiuration + * Input: + * group - LED group id. + * pPortmask - LED enable port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can be used to enable LED per port per group. + */ +extern rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_led_enable_get + * Description: + * Get Led enable congiuration + * Input: + * group - LED group id. + * Output: + * pPortmask - LED enable port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can be used to get LED enable status. + */ +extern rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_led_operation_set + * Description: + * Set Led operation mode + * Input: + * mode - LED operation mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +extern rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode); + +/* Function Name: + * rtk_led_operation_get + * Description: + * Get Led operation mode + * Input: + * None + * Output: + * pMode - Support LED operation mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +extern rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode); + +/* Function Name: + * rtk_led_modeForce_set + * Description: + * Set Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * mode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can force to one force mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +extern rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode); + +/* Function Name: + * rtk_led_modeForce_get + * Description: + * Get Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * pMode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can get forced Led group mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +extern rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode); + +/* Function Name: + * rtk_led_blinkRate_set + * Description: + * Set LED blinking rate + * Input: + * blinkRate - blinking rate. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * ASIC support 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +extern rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate); + +/* Function Name: + * rtk_led_blinkRate_get + * Description: + * Get LED blinking rate at mode 0 to mode 3 + * Input: + * None + * Output: + * pBlinkRate - blinking rate. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +extern rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate); + +/* Function Name: + * rtk_led_groupConfig_set + * Description: + * Set per group Led to congiuration mode + * Input: + * group - LED group. + * config - LED configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. + * - Definition LED Statuses Description + * - 0000 LED_Off LED pin Tri-State. + * - 0001 Dup/Col Collision, Full duplex Indicator. + * - 0010 Link/Act Link, Activity Indicator. + * - 0011 Spd1000 1000Mb/s Speed Indicator. + * - 0100 Spd100 100Mb/s Speed Indicator. + * - 0101 Spd10 10Mb/s Speed Indicator. + * - 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. + * - 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. + * - 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. + * - 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. + * - 1010 LoopDetect LoopDetect Indicator. + * - 1011 EEE EEE Indicator. + * - 1100 Link/Rx Link, Activity Indicator. + * - 1101 Link/Tx Link, Activity Indicator. + * - 1110 Master Link on Master Indicator. + * - 1111 Act Activity Indicator. Low for link established. + */ +extern rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config); + +/* Function Name: + * rtk_led_groupConfig_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED indicated information configuration for each LED group. + */ +extern rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig); + +/* Function Name: + * rtk_led_groupAbility_set + * Description: + * Configure per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +extern rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility); + +/* Function Name: + * rtk_led_groupAbility_get + * Description: + * Get per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +extern rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility); + +/* Function Name: + * rtk_led_serialMode_set + * Description: + * Set Led serial mode active congiuration + * Input: + * active - LED group. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED serial mode active congiuration. + */ +extern rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active); + +/* Function Name: + * rtk_led_serialMode_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED serial mode active configuration. + */ +extern rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive); + +/* Function Name: + * rtk_led_OutputEnable_set + * Description: + * This API set LED I/O state. + * Input: + * enabled - LED I/O state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set LED I/O state. + */ +extern rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state); + + +/* Function Name: + * rtk_led_OutputEnable_get + * Description: + * This API get LED I/O state. + * Input: + * None. + * Output: + * pEnabled - LED I/O state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current LED I/O state. + */ +extern rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState); + +/* Function Name: + * rtk_led_serialModePortmask_set + * Description: + * This API configure Serial LED output Group and portmask + * Input: + * output - output group + * pPortmask - output portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +extern rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_led_serialModePortmask_get + * Description: + * This API get Serial LED output Group and portmask + * Input: + * None. + * Output: + * pOutput - output group + * pPortmask - output portmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +extern rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask); + +#endif /* __RTK_API_LED_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/mirror.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/mirror.h new file mode 100755 index 00000000..1e984b7d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/mirror.h @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Mirror module high-layer API defination + * + */ + +#ifndef __RTK_API_MIRROR_H__ +#define __RTK_API_MIRROR_H__ + +typedef enum rtk_mirror_keep_e +{ + MIRROR_FOLLOW_VLAN = 0, + MIRROR_KEEP_ORIGINAL, + MIRROR_KEEP_END +}rtk_mirror_keep_t; + + +/* Function Name: + * rtk_mirror_portBased_set + * Description: + * Set port mirror function. + * Input: + * mirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API is to set mirror function of source port and mirror port. + * The mirror port can only be set to one port and the TX and RX mirror ports + * should be identical. + */ +extern rtk_api_ret_t rtk_mirror_portBased_set(rtk_port_t mirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask); + +/* Function Name: + * rtk_mirror_portBased_get + * Description: + * Get port mirror function. + * Input: + * None + * Output: + * pMirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror function of source port and mirror port. + */ +extern rtk_api_ret_t rtk_mirror_portBased_get(rtk_port_t* pMirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask); + +/* Function Name: + * rtk_mirror_portIso_set + * Description: + * Set mirror port isolation. + * Input: + * enable |Mirror isolation status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror isolation function that prevent normal forwarding packets to miror port. + */ +extern rtk_api_ret_t rtk_mirror_portIso_set(rtk_enable_t enable); + +/* Function Name: + * rtk_mirror_portIso_get + * Description: + * Get mirror port isolation. + * Input: + * None + * Output: + * pEnable |Mirror isolation status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation status. + */ +extern rtk_api_ret_t rtk_mirror_portIso_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_mirror_vlanLeaky_set + * Description: + * Set mirror VLAN leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +extern rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable); + + +/* Function Name: + * rtk_mirror_vlanLeaky_get + * Description: + * Get mirror VLAN leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror VLAN leaky status. + */ +extern rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable); + +/* Function Name: + * rtk_mirror_isolationLeaky_set + * Description: + * Set mirror Isolation leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +extern rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable); + +/* Function Name: + * rtk_mirror_isolationLeaky_get + * Description: + * Get mirror isolation leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation leaky status. + */ +extern rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable); + +/* Function Name: + * rtk_mirror_keep_set + * Description: + * Set mirror packet format keep. + * Input: + * mode - -mirror keep mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set -mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +extern rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode); + + +/* Function Name: + * rtk_mirror_keep_get + * Description: + * Get mirror packet format keep. + * Input: + * None + * Output: + * pMode -mirror keep mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +extern rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode); + +/* Function Name: + * rtk_mirror_override_set + * Description: + * Set port mirror override function. + * Input: + * rxMirror - 1: output mirrored packet, 0: output normal forward packet + * txMirror - 1: output mirrored packet, 0: output normal forward packet + * aclMirror - 1: output mirrored packet, 0: output normal forward packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API is to set mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +extern rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror); + +/* Function Name: + * rtk_mirror_override_get + * Description: + * Get port mirror override function. + * Input: + * None + * Output: + * pRxMirror - 1: output mirrored packet, 0: output normal forward packet + * pTxMirror - 1: output mirrored packet, 0: output normal forward packet + * pAclMirror - 1: output mirrored packet, 0: output normal forward packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * The API is to Get mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +extern rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror); + +#endif /* __RTK_API_MIRROR_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/oam.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/oam.h new file mode 100755 index 00000000..1fc14bd6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/oam.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes the following modules and sub-modules + * (1) OAM (802.3ah) configuration + * + */ + +#ifndef __RTK_OAM_H__ +#define __RTK_OAM_H__ + +/* + * Symbol Definition + */ + + +/* + * Data Declaration + */ + + +/* + * Macro Declaration + */ + +typedef enum rtk_oam_parser_act_e +{ + OAM_PARSER_ACTION_FORWARD = 0, + OAM_PARSER_ACTION_LOOPBACK, + OAM_PARSER_ACTION_DISCARD, + OAM_PARSER_ACTION_END, + +} rtk_oam_parser_act_t; + +typedef enum rtk_oam_multiplexer_act_e +{ + OAM_MULTIPLEXER_ACTION_FORWARD = 0, + OAM_MULTIPLEXER_ACTION_DISCARD, + OAM_MULTIPLEXER_ACTION_CPUONLY, + OAM_MULTIPLEXER_ACTION_END, + +} rtk_oam_multiplexer_act_t; + + +/* + * Function Declaration + */ + +/* Function Name: + * rtk_oam_init + * Description: + * Initialize oam module. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * Must initialize oam module before calling any oam APIs. + */ +extern rtk_api_ret_t rtk_oam_init(void); + +/* Function Name: + * rtk_oam_state_set + * Description: + * This API set OAM state. + * Input: + * enabled -OAMstate + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set OAM state. + */ +extern rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_oam_state_get + * Description: + * This API get OAM state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current OAM state. + */ +extern rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled); + + +/* Module Name : OAM */ + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Set OAM parser action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action); + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Get OAM parser action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction); + + +/* Function Name: + * rtk_oam_multiplexerAction_set + * Description: + * Set OAM multiplexer action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action); + +/* Function Name: + * rtk_oam_multiplexerAction_set + * Description: + * Get OAM multiplexer action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +extern rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction); + + +#endif /* __RTK_OAM_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/port.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/port.h new file mode 100755 index 00000000..fcac1bcb --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/port.h @@ -0,0 +1,959 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes port module high-layer API defination + * + */ + +#ifndef __RTK_API_PORT_H__ +#define __RTK_API_PORT_H__ + +/* + * Data Type Declaration + */ + +#define PHY_CONTROL_REG 0 +#define PHY_STATUS_REG 1 +#define PHY_AN_ADVERTISEMENT_REG 4 +#define PHY_AN_LINKPARTNER_REG 5 +#define PHY_1000_BASET_CONTROL_REG 9 +#define PHY_1000_BASET_STATUS_REG 10 +#define PHY_RESOLVED_REG 26 + +#define RTK_EFID_MAX 0x7 + +#define RTK_FIBER_FORCE_1000M 3 +#define RTK_FIBER_FORCE_100M 5 +#define RTK_FIBER_FORCE_100M1000M 7 + +#define RTK_INDRECT_ACCESS_CRTL 0x1f00 +#define RTK_INDRECT_ACCESS_STATUS 0x1f01 +#define RTK_INDRECT_ACCESS_ADDRESS 0x1f02 +#define RTK_INDRECT_ACCESS_WRITE_DATA 0x1f03 +#define RTK_INDRECT_ACCESS_READ_DATA 0x1f04 +#define RTK_INDRECT_ACCESS_DELAY 0x1f80 +#define RTK_INDRECT_ACCESS_BURST 0x1f81 +#define RTK_RW_MASK 0x2 +#define RTK_CMD_MASK 0x1 +#define RTK_PHY_BUSY_OFFSET 2 + + +typedef enum rtk_mode_ext_e +{ + MODE_EXT_DISABLE = 0, + MODE_EXT_RGMII, + MODE_EXT_MII_MAC, + MODE_EXT_MII_PHY, + MODE_EXT_TMII_MAC, + MODE_EXT_TMII_PHY, + MODE_EXT_GMII, + MODE_EXT_RMII_MAC, + MODE_EXT_RMII_PHY, + MODE_EXT_SGMII, + MODE_EXT_HSGMII, + MODE_EXT_1000X_100FX, + MODE_EXT_1000X, + MODE_EXT_100FX, + MODE_EXT_RGMII_2, + MODE_EXT_MII_MAC_2, + MODE_EXT_MII_PHY_2, + MODE_EXT_TMII_MAC_2, + MODE_EXT_TMII_PHY_2, + MODE_EXT_RMII_MAC_2, + MODE_EXT_RMII_PHY_2, + MODE_EXT_END +} rtk_mode_ext_t; + +typedef enum rtk_port_duplex_e +{ + PORT_HALF_DUPLEX = 0, + PORT_FULL_DUPLEX, + PORT_DUPLEX_END +} rtk_port_duplex_t; + +typedef enum rtk_port_linkStatus_e +{ + PORT_LINKDOWN = 0, + PORT_LINKUP, + PORT_LINKSTATUS_END +} rtk_port_linkStatus_t; + +typedef struct rtk_port_mac_ability_s +{ + rtk_uint32 forcemode; + rtk_uint32 speed; + rtk_uint32 duplex; + rtk_uint32 link; + rtk_uint32 nway; + rtk_uint32 txpause; + rtk_uint32 rxpause; +}rtk_port_mac_ability_t; + +typedef struct rtk_port_phy_ability_s +{ + rtk_uint32 AutoNegotiation; /*PHY register 0.12 setting for auto-negotiation process*/ + rtk_uint32 Half_10; /*PHY register 4.5 setting for 10BASE-TX half duplex capable*/ + rtk_uint32 Full_10; /*PHY register 4.6 setting for 10BASE-TX full duplex capable*/ + rtk_uint32 Half_100; /*PHY register 4.7 setting for 100BASE-TX half duplex capable*/ + rtk_uint32 Full_100; /*PHY register 4.8 setting for 100BASE-TX full duplex capable*/ + rtk_uint32 Full_1000; /*PHY register 9.9 setting for 1000BASE-T full duplex capable*/ + rtk_uint32 FC; /*PHY register 4.10 setting for flow control capability*/ + rtk_uint32 AsyFC; /*PHY register 4.11 setting for asymmetric flow control capability*/ +} rtk_port_phy_ability_t; + +typedef rtk_uint32 rtk_port_phy_data_t; /* phy page */ + +typedef enum rtk_port_phy_mdix_mode_e +{ + PHY_AUTO_CROSSOVER_MODE= 0, + PHY_FORCE_MDI_MODE, + PHY_FORCE_MDIX_MODE, + PHY_FORCE_MODE_END +} rtk_port_phy_mdix_mode_t; + +typedef enum rtk_port_phy_mdix_status_e +{ + PHY_STATUS_AUTO_MDI_MODE= 0, + PHY_STATUS_AUTO_MDIX_MODE, + PHY_STATUS_FORCE_MDI_MODE, + PHY_STATUS_FORCE_MDIX_MODE, + PHY_STATUS_FORCE_MODE_END +} rtk_port_phy_mdix_status_t; + +typedef rtk_uint32 rtk_port_phy_page_t; /* phy page */ + +typedef enum rtk_port_phy_reg_e +{ + PHY_REG_CONTROL = 0, + PHY_REG_STATUS, + PHY_REG_IDENTIFIER_1, + PHY_REG_IDENTIFIER_2, + PHY_REG_AN_ADVERTISEMENT, + PHY_REG_AN_LINKPARTNER, + PHY_REG_1000_BASET_CONTROL = 9, + PHY_REG_1000_BASET_STATUS, + PHY_REG_END = 32 +} rtk_port_phy_reg_t; + +typedef enum rtk_port_phy_test_mode_e +{ + PHY_TEST_MODE_NORMAL= 0, + PHY_TEST_MODE_1, + PHY_TEST_MODE_2, + PHY_TEST_MODE_3, + PHY_TEST_MODE_4, + PHY_TEST_MODE_END +} rtk_port_phy_test_mode_t; + +typedef enum rtk_port_speed_e +{ + PORT_SPEED_10M = 0, + PORT_SPEED_100M, + PORT_SPEED_1000M, + PORT_SPEED_500M, + PORT_SPEED_2500M, + PORT_SPEED_END +} rtk_port_speed_t; + +typedef enum rtk_port_media_e +{ + PORT_MEDIA_COPPER = 0, + PORT_MEDIA_FIBER, + PORT_MEDIA_END +}rtk_port_media_t; + +typedef struct rtk_rtctResult_s +{ + rtk_port_speed_t linkType; + union + { + struct fe_result_s + { + rtk_uint32 isRxShort; + rtk_uint32 isTxShort; + rtk_uint32 isRxOpen; + rtk_uint32 isTxOpen; + rtk_uint32 isRxMismatch; + rtk_uint32 isTxMismatch; + rtk_uint32 isRxLinedriver; + rtk_uint32 isTxLinedriver; + rtk_uint32 rxLen; + rtk_uint32 txLen; + } fe_result; + + struct ge_result_s + { + rtk_uint32 channelAShort; + rtk_uint32 channelBShort; + rtk_uint32 channelCShort; + rtk_uint32 channelDShort; + + rtk_uint32 channelAOpen; + rtk_uint32 channelBOpen; + rtk_uint32 channelCOpen; + rtk_uint32 channelDOpen; + + rtk_uint32 channelAMismatch; + rtk_uint32 channelBMismatch; + rtk_uint32 channelCMismatch; + rtk_uint32 channelDMismatch; + + rtk_uint32 channelALinedriver; + rtk_uint32 channelBLinedriver; + rtk_uint32 channelCLinedriver; + rtk_uint32 channelDLinedriver; + + rtk_uint32 channelALen; + rtk_uint32 channelBLen; + rtk_uint32 channelCLen; + rtk_uint32 channelDLen; + } ge_result; + }result; +} rtk_rtctResult_t; + +/* Function Name: + * rtk_port_phyAutoNegoAbility_set + * Description: + * Set ethernet PHY auto-negotiation desired ability. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + */ +extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyAutoNegoAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyForceModeAbility_set + * Description: + * Set the port speed/duplex mode/pause/asy_pause in the PHY force mode. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + */ +extern rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyForceModeAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +extern rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility); + +/* Function Name: + * rtk_port_phyStatus_get + * Description: + * Get ethernet PHY linking status + * Input: + * port - Port id. + * Output: + * linkStatus - PHY link status + * speed - PHY link speed + * duplex - PHY duplex mode + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * API will return auto negotiation status of phy. + */ +extern rtk_api_ret_t rtk_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex); + +/* Function Name: + * rtk_port_macForceLink_set + * Description: + * Set port force linking configuration. + * Input: + * port - port id. + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can set Port/MAC force mode properties. + */ +extern rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macForceLink_get + * Description: + * Get port force linking configuration. + * Input: + * port - Port id. + * Output: + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get Port/MAC force mode properties. + */ +extern rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macForceLinkExt_set + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * mode - external interface mode + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface force mode properties. + * The external interface can be set to: + * - MODE_EXT_DISABLE, + * - MODE_EXT_RGMII, + * - MODE_EXT_MII_MAC, + * - MODE_EXT_MII_PHY, + * - MODE_EXT_TMII_MAC, + * - MODE_EXT_TMII_PHY, + * - MODE_EXT_GMII, + * - MODE_EXT_RMII_MAC, + * - MODE_EXT_RMII_PHY, + * - MODE_EXT_SGMII, + * - MODE_EXT_HSGMII, + * - MODE_EXT_1000X_100FX, + * - MODE_EXT_1000X, + * - MODE_EXT_100FX, + */ +extern rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macForceLinkExt_get + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * Output: + * pMode - external interface mode + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get external interface force mode properties. + */ +extern rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability); + +/* Function Name: + * rtk_port_macStatus_get + * Description: + * Get port link status. + * Input: + * port - Port id. + * Output: + * pPortstatus - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get Port/PHY properties. + */ +extern rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus); + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_set + * Description: + * Set Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * enable - Loopback state, 0:disable, 1:enable + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can enable/disable Local loopback in MAC. + * For UTP port, This API will also enable the digital + * loopback bit in PHY register for sync of speed between + * PHY and MAC. For EXT port, users need to force the + * link state by themself. + */ +extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_get + * Description: + * Get Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * Output: + * pEnable - Loopback state, 0:disable, 1:enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_phyReg_set + * Description: + * Set PHY register data of the specific port. + * Input: + * port - port id. + * reg - Register id + * regData - Register data + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can set PHY register data of the specific port. + */ +extern rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t value); + +/* Function Name: + * rtk_port_phyReg_get + * Description: + * Get PHY register data of the specific port. + * Input: + * port - Port id. + * reg - Register id + * Output: + * pData - Register data + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can get PHY register data of the specific port. + */ +extern rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData); + +/* Function Name: + * rtk_port_backpressureEnable_set + * Description: + * Set the half duplex backpressure enable status of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_port_backpressureEnable_get + * Description: + * Get the half duplex backpressure enable status of the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_adminEnable_set + * Description: + * Set port admin configuration of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_port_adminEnable_get + * Description: + * Get port admin configurationof the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_isolation_set + * Description: + * Set permitted port isolation portmask + * Input: + * port - port id. + * pPortmask - Permit port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * This API set the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +extern rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_port_isolation_get + * Description: + * Get permitted port isolation portmask + * Input: + * port - Port id. + * Output: + * pPortmask - Permit port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API get the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +extern rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_port_rgmiiDelayExt_set + * Description: + * Set RGMII interface delay value for TX and RX. + * Input: + * txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay + * rxDelay - RX delay value, 0~7 for delay setup. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for no-delay, and 7 for maximum delay. + */ +extern rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay); + +/* Function Name: + * rtk_port_rgmiiDelayExt_get + * Description: + * Get RGMII interface delay value for TX and RX. + * Input: + * None + * Output: + * pTxDelay - TX delay value + * pRxDelay - RX delay value + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for n0-delay, and 7 for maximum delay. + */ +extern rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay); + +/* Function Name: + * rtk_port_phyEnableAll_set + * Description: + * Set all PHY enable status. + * Input: + * enable - PHY Enable State. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable); + +/* Function Name: + * rtk_port_phyEnableAll_get + * Description: + * Get all PHY enable status. + * Input: + * None + * Output: + * pEnable - PHY Enable State. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_port_phyEnableAll_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_port_efid_set + * Description: + * Set port-based enhanced filtering database + * Input: + * port - Port id. + * efid - Specified enhanced filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based enhanced filtering database. + */ +extern rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid); + +/* Function Name: + * rtk_port_efid_get + * Description: + * Get port-based enhanced filtering database + * Input: + * port - Port id. + * Output: + * pEfid - Specified enhanced filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based enhanced filtering database status. + */ +extern rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid); + +/* Function Name: + * rtk_port_phyComboPortMedia_set + * Description: + * Set Combo port media type + * Input: + * port - Port id. (Should be Port 4) + * media - Media (COPPER or FIBER) + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +extern rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media); + +/* Function Name: + * rtk_port_phyComboPortMedia_get + * Description: + * Get Combo port media type + * Input: + * port - Port id. (Should be Port 4) + * Output: + * pMedia - Media (COPPER or FIBER) + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +extern rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia); + +/* Function Name: + * rtk_port_rtctEnable_set + * Description: + * Enable RTCT test + * Input: + * pPortmask - Port mask of RTCT enabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can enable RTCT Test + */ +extern rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_port_rtctDisable_set + * Description: + * Disable RTCT test + * Input: + * pPortmask - Port mask of RTCT disabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can disable RTCT Test + */ +rtk_api_ret_t rtk_port_rtctDisable_set(rtk_portmask_t *pPortmask); + + +/* Function Name: + * rtk_port_rtctResult_get + * Description: + * Get the result of RTCT test + * Input: + * port - Port ID + * Output: + * pRtctResult - The result of RTCT result + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_PHY_RTCT_NOT_FINISH - Testing does not finish. + * Note: + * The API can get RTCT test result. + * RTCT test may takes 4.8 seconds to finish its test at most. + * Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or + * other error code, the result can not be referenced and + * user should call this API again until this API returns + * a RT_ERR_OK. + * The result is stored at pRtctResult->ge_result + * pRtctResult->linkType is unused. + * The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M + */ +extern rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult); + +/* Function Name: + * rtk_port_sds_reset + * Description: + * Reset Serdes + * Input: + * port - Port ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +extern rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port); + +/* Function Name: + * rtk_port_sgmiiLinkStatus_get + * Description: + * Get SGMII status + * Input: + * port - Port ID + * Output: + * pSignalDetect - Signal detect + * pSync - Sync + * pLink - Link + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +extern rtk_api_ret_t rtk_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink); + +/* Function Name: + * rtk_port_sgmiiNway_set + * Description: + * Configure SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * state - Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API configure SGMII/HSGMII port Nway state + */ +extern rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state); + +/* Function Name: + * rtk_port_sgmiiNway_get + * Description: + * Get SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * Output: + * pState - Nway state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get SGMII/HSGMII port Nway state + */ +extern rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState); + +#endif /* __RTK_API_PORT_H__ */ + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/ptp.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/ptp.h new file mode 100755 index 00000000..6c4aca5a --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/ptp.h @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes time module high-layer API defination + * + */ + +#ifndef __RTK_API_PTP_H__ +#define __RTK_API_PTP_H__ + +/* + * Symbol Definition + */ +#define RTK_MAX_NUM_OF_NANO_SECOND 0x3B9AC9FF +#define RTK_PTP_INTR_MASK 0xFF +#define RTK_MAX_NUM_OF_TPID 0xFFFF + +/* Message Type */ +typedef enum rtk_ptp_msgType_e +{ + PTP_MSG_TYPE_TX_SYNC = 0, + PTP_MSG_TYPE_TX_DELAY_REQ, + PTP_MSG_TYPE_TX_PDELAY_REQ, + PTP_MSG_TYPE_TX_PDELAY_RESP, + PTP_MSG_TYPE_RX_SYNC, + PTP_MSG_TYPE_RX_DELAY_REQ, + PTP_MSG_TYPE_RX_PDELAY_REQ, + PTP_MSG_TYPE_RX_PDELAY_RESP, + PTP_MSG_TYPE_END +} rtk_ptp_msgType_t; + +typedef enum rtk_ptp_intType_e +{ + PTP_INT_TYPE_TX_SYNC = 0, + PTP_INT_TYPE_TX_DELAY_REQ, + PTP_INT_TYPE_TX_PDELAY_REQ, + PTP_INT_TYPE_TX_PDELAY_RESP, + PTP_INT_TYPE_RX_SYNC, + PTP_INT_TYPE_RX_DELAY_REQ, + PTP_INT_TYPE_RX_PDELAY_REQ, + PTP_INT_TYPE_RX_PDELAY_RESP, + PTP_INT_TYPE_ALL, + PTP_INT_TYPE_END +}rtk_ptp_intType_t; + +typedef enum rtk_ptp_sys_adjust_e +{ + SYS_ADJUST_PLUS = 0, + SYS_ADJUST_MINUS, + SYS_ADJUST_END +} rtk_ptp_sys_adjust_t; + + +/* Reference Time */ +typedef struct rtk_ptp_timeStamp_s +{ + rtk_uint32 sec; + rtk_uint32 nsec; +} rtk_ptp_timeStamp_t; + +typedef struct rtk_ptp_info_s +{ + rtk_uint32 sequenceId; + rtk_ptp_timeStamp_t timeStamp; +} rtk_ptp_info_t; + +typedef rtk_uint32 rtk_ptp_tpid_t; + +typedef rtk_uint32 rtk_ptp_intStatus_t; /* interrupt status mask */ + +/* + * Data Declaration + */ + +/* + * Function Declaration + */ +/* Function Name: + * rtk_time_init + * Description: + * PTP function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize EEE status. + */ +extern rtk_api_ret_t rtk_ptp_init(void); + +/* Function Name: + * rtk_ptp_mac_set + * Description: + * Configure PTP mac address. + * Input: + * mac - mac address to parser PTP packets. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac); + +/* Function Name: + * rtk_ptp_mac_get + * Description: + * Get PTP mac address. + * Input: + * None + * Output: + * pMac - mac address to parser PTP packets. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac); + +/* Function Name: + * rtk_ptp_tpid_set + * Description: + * Configure PTP accepted outer & inner tag TPID. + * Input: + * outerId - Ether type of S-tag frame parsing in PTP ports. + * innerId - Ether type of C-tag frame parsing in PTP ports. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId); + +/* Function Name: + * rtk_ptp_tpid_get + * Description: + * Get PTP accepted outer & inner tag TPID. + * Input: + * None + * Output: + * pOuterId - Ether type of S-tag frame parsing in PTP ports. + * pInnerId - Ether type of C-tag frame parsing in PTP ports. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId); + +/* Function Name: + * rtk_ptp_refTime_set + * Description: + * Set the reference time of the specified device. + * Input: + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp); + +/* Function Name: + * rtk_ptp_refTime_get + * Description: + * Get the reference time of the specified device. + * Input: + * Output: + * pTimeStamp - pointer buffer of the reference time + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp); + +/* Function Name: + * rtk_ptp_refTimeAdjust_set + * Description: + * Adjust the reference time. + * Input: + * unit - unit id + * sign - significant + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * sign=0 for positive adjustment, sign=1 for negative adjustment. + */ +extern rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp); + +/* Function Name: + * rtk_ptp_refTimeEnable_set + * Description: + * Set the enable state of reference time of the specified device. + * Input: + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTimeEnable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_refTimeEnable_get + * Description: + * Get the enable state of reference time of the specified device. + * Input: + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_ptp_portEnable_set + * Description: + * Set PTP status of the specified port. + * Input: + * port - port id + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_portEnable_get + * Description: + * Get PTP status of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_ptp_portTimestamp_get + * Description: + * Get PTP timstamp according to the PTP identifier on the dedicated port from the specified device. + * Input: + * unit - unit id + * port - port id + * type - PTP message type + * Output: + * pInfo - pointer buffer of sequence ID and timestamp + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo); + +/* Function Name: + * rtk_ptp_intControl_set + * Description: + * Set PTP interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set PTP interrupt status configuration. + * The interrupt trigger status is shown in the following: + * PTP_INT_TYPE_TX_SYNC = 0, + * PTP_INT_TYPE_TX_DELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_RESP, + * PTP_INT_TYPE_RX_SYNC, + * PTP_INT_TYPE_RX_DELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_RESP, + * PTP_INT_TYPE_ALL, + */ +extern rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_intControl_get + * Description: + * Get PTP interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * Output: + * pEnable - Interrupt status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt status configuration. + * The interrupt trigger status is shown in the following: + * PTP_INT_TYPE_TX_SYNC = 0, + * PTP_INT_TYPE_TX_DELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_RESP, + * PTP_INT_TYPE_RX_SYNC, + * PTP_INT_TYPE_RX_DELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_RESP, + */ +extern rtk_api_ret_t rtk_ptp_intControl_get(rtk_ptp_intType_t type, rtk_enable_t *pEnable); + + +/* Function Name: + * rtk_ptp_intStatus_get + * Description: + * Get PTP port interrupt trigger status. + * Input: + * port - physical port + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - PORT 0 INT (value[0] (Bit0)) + * - PORT 1 INT (value[0] (Bit1)) + * - PORT 2 INT (value[0] (Bit2)) + * - PORT 3 INT (value[0] (Bit3)) + * - PORT 4 INT (value[0] (Bit4)) + + * + */ +extern rtk_api_ret_t rtk_ptp_intStatus_get(rtk_ptp_intStatus_t *pStatusMask); + +/* Function Name: + * rtk_ptp_portIntStatus_set + * Description: + * Set PTP port interrupt trigger status to clean. + * Input: + * port - physical port + * statusMask - Interrupt status bit mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can clean interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0)) + * - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1)) + * - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2)) + * - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3)) + * - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4)) + * - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5)) + * - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6)) + * - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7)) + * The status will be cleared after execute this API. + */ +extern rtk_api_ret_t rtk_ptp_portIntStatus_set(rtk_port_t port, rtk_ptp_intStatus_t statusMask); + +/* Function Name: + * rtk_ptp_portIntStatus_get + * Description: + * Get PTP port interrupt trigger status. + * Input: + * port - physical port + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0)) + * - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1)) + * - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2)) + * - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3)) + * - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4)) + * - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5)) + * - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6)) + * - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7)) + * + */ +extern rtk_api_ret_t rtk_ptp_portIntStatus_get(rtk_port_t port, rtk_ptp_intStatus_t *pStatusMask); + +/* Function Name: + * rtk_ptp_portPtpTrap_set + * Description: + * Set PTP packet trap of the specified port. + * Input: + * port - port id + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portTrap_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_ptp_portPtpEnable_get + * Description: + * Get PTP packet trap of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +extern rtk_api_ret_t rtk_ptp_portTrap_get(rtk_port_t port, rtk_enable_t *pEnable); + +#endif /* __RTK_API_PTP_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/qos.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/qos.h new file mode 100755 index 00000000..4be41748 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/qos.h @@ -0,0 +1,781 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes QoS module high-layer API defination + * + */ + +#ifndef __RTK_API_QOS_H__ +#define __RTK_API_QOS_H__ + +/* + * Data Type Declaration + */ +#define QOS_DEFAULT_TICK_PERIOD (19-1) +#define QOS_DEFAULT_BYTE_PER_TOKEN 34 +#define QOS_DEFAULT_LK_THRESHOLD (34*3) /* Why use 0x400? */ + + +#define QOS_DEFAULT_INGRESS_BANDWIDTH 0x3FFF /* 0x3FFF => unlimit */ +#define QOS_DEFAULT_EGRESS_BANDWIDTH 0x3D08 /*( 0x3D08 + 1) * 64Kbps => 1Gbps*/ +#define QOS_DEFAULT_PREIFP 1 +#define QOS_DEFAULT_PACKET_USED_PAGES_FC 0x60 +#define QOS_DEFAULT_PACKET_USED_FC_EN 0 +#define QOS_DEFAULT_QUEUE_BASED_FC_EN 1 + +#define QOS_DEFAULT_PRIORITY_SELECT_PORT 8 +#define QOS_DEFAULT_PRIORITY_SELECT_1Q 0 +#define QOS_DEFAULT_PRIORITY_SELECT_ACL 0 +#define QOS_DEFAULT_PRIORITY_SELECT_DSCP 0 + +#define QOS_DEFAULT_DSCP_MAPPING_PRIORITY 0 + +#define QOS_DEFAULT_1Q_REMARKING_ABILITY 0 +#define QOS_DEFAULT_DSCP_REMARKING_ABILITY 0 +#define QOS_DEFAULT_QUEUE_GAP 20 +#define QOS_DEFAULT_QUEUE_NO_MAX 6 +#define QOS_DEFAULT_AVERAGE_PACKET_RATE 0x3FFF +#define QOS_DEFAULT_BURST_SIZE_IN_APR 0x3F +#define QOS_DEFAULT_PEAK_PACKET_RATE 2 +#define QOS_DEFAULT_SCHEDULER_ABILITY_APR 1 /*disable*/ +#define QOS_DEFAULT_SCHEDULER_ABILITY_PPR 1 /*disable*/ +#define QOS_DEFAULT_SCHEDULER_ABILITY_WFQ 1 /*disable*/ + +#define QOS_WEIGHT_MAX 127 + +#define RTK_MAX_NUM_OF_PRIORITY 8 +#define RTK_MAX_NUM_OF_QUEUE 8 + +#define RTK_PRIMAX 7 +#define RTK_QIDMAX 7 +#define RTK_DSCPMAX 63 + + +/* enum Priority Selection Index */ +typedef enum rtk_qos_priDecTbl_e +{ + PRIDECTBL_IDX0 = 0, + PRIDECTBL_IDX1, + PRIDECTBL_END, +}rtk_qos_priDecTbl_t; + + +/* Types of 802.1p remarking source */ +typedef enum rtk_qos_1pRmkSrc_e +{ + DOT1P_RMK_SRC_USER_PRI, + DOT1P_RMK_SRC_TAG_PRI, + DOT1P_RMK_SRC_END +} rtk_qos_1pRmkSrc_t; + + +/* Types of DSCP remarking source */ +typedef enum rtk_qos_dscpRmkSrc_e +{ + DSCP_RMK_SRC_INT_PRI, + DSCP_RMK_SRC_DSCP, + DSCP_RMK_SRC_USER_PRI, + DSCP_RMK_SRC_END +} rtk_qos_dscpRmkSrc_t; + + + + +typedef struct rtk_priority_select_s +{ + rtk_uint32 port_pri; + rtk_uint32 dot1q_pri; + rtk_uint32 acl_pri; + rtk_uint32 dscp_pri; + rtk_uint32 cvlan_pri; + rtk_uint32 svlan_pri; + rtk_uint32 dmac_pri; + rtk_uint32 smac_pri; +} rtk_priority_select_t; + +typedef struct rtk_qos_pri2queue_s +{ + rtk_uint32 pri2queue[RTK_MAX_NUM_OF_PRIORITY]; +} rtk_qos_pri2queue_t; + +typedef struct rtk_qos_queue_weights_s +{ + rtk_uint32 weights[RTK_MAX_NUM_OF_QUEUE]; +} rtk_qos_queue_weights_t; + +typedef enum rtk_qos_scheduling_type_e +{ + WFQ = 0, /* Weighted-Fair-Queue */ + WRR, /* Weighted-Round-Robin */ + SCHEDULING_TYPE_END +} rtk_qos_scheduling_type_t; + +typedef rtk_uint32 rtk_queue_num_t; /* queue number*/ + +/* Function Name: + * rtk_qos_init + * Description: + * Configure Qos default settings with queue number assigment to each port. + * Input: + * queueNum - Queue number of each port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API will initialize related Qos setting with queue number assigment. + * The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum); + +/* Function Name: + * rtk_qos_priSel_set + * Description: + * Configure the priority order among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter. + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT + * - PRIDEC_ACL + * - PRIDEC_DSCP + * - PRIDEC_1Q + * - PRIDEC_1AD + * - PRIDEC_CVLAN + * - PRIDEC_DA + * - PRIDEC_SA + */ +extern rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec); + + +/* Function Name: + * rtk_qos_priSel_get + * Description: + * Get the priority order configuration among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * Output: + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision . + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT, + * - PRIDEC_ACL, + * - PRIDEC_DSCP, + * - PRIDEC_1Q, + * - PRIDEC_1AD, + * - PRIDEC_CVLAN, + * - PRIDEC_DA, + * - PRIDEC_SA, + */ +extern rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec); + +/* Function Name: + * rtk_qos_1pPriRemap_set + * Description: + * Configure 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri); + +/* Function Name: + * rtk_qos_1pPriRemap_get + * Description: + * Get 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value . + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assigment for internal asic priority, and it is uesed for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri); + + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_set + * Description: + * Set remarking source of 802.1p remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure 802.1p remark functionality to map original 802.1p value or internal + * priority to TX DSCP value. + */ +extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type); + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_get + * Description: + * Get remarking source of 802.1p remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType); + +/* Function Name: + * rtk_qos_dscpPriRemap_set + * Description: + * Map dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * int_pri - internal priority value . + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +extern rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri); + +/* Function Name: + * rtk_qos_dscpPriRemap_get + * Description: + * Get dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +extern rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri); + +/* Function Name: + * rtk_qos_portPri_set + * Description: + * Configure priority usage to each port. + * Input: + * port - Port id. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_SEL_PORT_PRI - Invalid port priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) ; + +/* Function Name: + * rtk_qos_portPri_get + * Description: + * Get priority usage to each port. + * Input: + * port - Port id. + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) ; + +/* Function Name: + * rtk_qos_queueNum_set + * Description: + * Set output queue number for each port. + * Input: + * port - Port id. + * index - Mapping queue number (1~8) + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can set the output queue number of the specified port. The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num); + +/* Function Name: + * rtk_qos_queueNum_get + * Description: + * Get output queue number. + * Input: + * port - Port id. + * Output: + * pQueue_num - Mapping queue number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API will return the output queue number of the specified port. The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num); + +/* Function Name: + * rtk_qos_priMap_set + * Description: + * Set output queue number for each port. + * Input: + * queue_num - Queue number usage. + * pPri2qid - Priority mapping to queue ID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_QUEUE_ID - Invalid queue id. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * ASIC supports priority mapping to queue with different queue number from 1 to 8. + * For different queue numbers usage, ASIC supports different internal available queue IDs. + */ +extern rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid); + + +/* Function Name: + * rtk_qos_priMap_get + * Description: + * Get priority to queue ID mapping table parameters. + * Input: + * queue_num - Queue number usage. + * Output: + * pPri2qid - Priority mapping to queue ID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can return the mapping queue id of the specified priority and queue number. + * The queue number is from 1 to 8. + */ +extern rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid); + +/* Function Name: + * rtk_qos_schedulingQueue_set + * Description: + * Set weight and type of queues in dedicated port. + * Input: + * port - Port id. + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight. + * Note: + * The API can set weight and type, strict priority or weight fair queue (WFQ) for + * dedicated port for using queues. If queue id is not included in queue usage, + * then its type and weight setting in dummy for setting. There are priorities + * as queue id in strict queues. It means strict queue id 5 carrying higher priority + * than strict queue id 4. The WFQ queue weight is from 1 to 128, and weight 0 is + * for strict priority queue type. + */ +extern rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights); + +/* Function Name: + * rtk_qos_schedulingQueue_get + * Description: + * Get weight and type of queues in dedicated port. + * Input: + * port - Port id. + * Output: + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get weight and type, strict priority or weight fair queue (WFQ) for dedicated port for using queues. + * The WFQ queue weight is from 1 to 128, and weight 0 is for strict priority queue type. + */ +extern rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights); + +/* Function Name: + * rtk_qos_1pRemarkEnable_set + * Description: + * Set 1p Remarking state + * Input: + * port - Port id. + * enable - State of per-port 1p Remarking + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable 802.1p remarking ability for whole system. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_1pRemarkEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_qos_1pRemarkEnable_get + * Description: + * Get 802.1p remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - Status of 802.1p remark. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1p remarking ability. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_1pRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_qos_1pRemark_set + * Description: + * Set 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * dot1p_pri - 802.1p priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set 802.1p parameters source priority and new priority. + */ +extern rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri); + +/* Function Name: + * rtk_qos_1pRemark_get + * Description: + * Get 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * pDot1p_pri - 802.1p priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get 802.1p remarking parameters. It would return new priority of ingress priority. + */ +extern rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri); + +/* Function Name: + * rtk_qos_dscpRemarkEnable_set + * Description: + * Set DSCP remarking ability. + * Input: + * port - Port id. + * enable - status of DSCP remark. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable DSCP remarking ability for whole system. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_qos_dscpRemarkEnable_get + * Description: + * Get DSCP remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - status of DSCP remarking. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get DSCP remarking ability. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_qos_dscpRemark_set + * Description: + * Set DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * dscp - DSCP value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The API can set DSCP value and mapping priority. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp); + +/* Function Name: + * rtk_qos_dscpRemark_get + * Description: + * Get DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * Dscp - DSCP value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get DSCP parameters. It would return DSCP value for mapping priority. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp); + +/* Function Name: + * rtk_qos_dscpRemarkSrcSel_set + * Description: + * Set remarking source of DSCP remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure DSCP remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type); + + +/* Function Name: + * rtk_qos_dcpRemarkSrcSel_get + * Description: + * Get remarking source of DSCP remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType); + + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_set + * Description: + * Set DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * rmkDscp - remarked DSCP value + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * Note: + * dscp parameter can be DSCP value or internal priority according to configuration of API + * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP + * value or internal priority to TX DSCP value. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp); + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_get + * Description: + * Get DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * Output: + * pDscp - remarked DSCP value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None. + */ +extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp); + +/* Function Name: + * rtk_qos_portPriSelIndex_set + * Description: + * Configure priority decision index to each port. + * Input: + * port - Port id. + * index - priority decision index. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENTRY_INDEX - Invalid entry index. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index); + +/* Function Name: + * rtk_qos_portPriSelIndex_get + * Description: + * Get priority decision index from each port. + * Input: + * port - Port id. + * Output: + * pIndex - priority decision index. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +extern rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex); + +#endif /* __RTK_API_QOS_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rate.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rate.h new file mode 100755 index 00000000..231ed01b --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rate.h @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes rate module high-layer API defination + * + */ + +#ifndef __RTK_API_RATE_H__ +#define __RTK_API_RATE_H__ + +/* + * Include Files + */ +//#include + +/* + * Data Type Declaration + */ +#define RTK_MAX_METER_ID (rtk_switch_maxMeterId_get()) +#define RTK_METER_NUM (RTK_MAX_METER_ID + 1) + +typedef enum rtk_meter_type_e{ + METER_TYPE_KBPS = 0, /* Kbps */ + METER_TYPE_PPS, /* Packet per second */ + METER_TYPE_END +}rtk_meter_type_t; + + +/* + * Function Declaration + */ + + /* Rate */ +/* Function Name: + * rtk_rate_shareMeter_set + * Description: + * Set meter configuration + * Input: + * index - shared meter index + * type - shared meter type + * rate - rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_RATE - Invalid rate + * RT_ERR_INPUT - Invalid input parameters + * Note: + * The API can set shared meter rate and ifg include for each meter. + * The rate unit is 1 kbps and the range is from 8k to 1048568k if type is METER_TYPE_KBPS and + * the granularity of rate is 8 kbps. + * The rate unit is packets per second and the range is 1 ~ 0x1FFF if type is METER_TYPE_PPS. + * The ifg_include parameter is used + * for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_shareMeter_set(rtk_meter_id_t index, rtk_meter_type_t type, rtk_rate_t rate, rtk_enable_t ifg_include); + +/* Function Name: + * rtk_rate_shareMeter_get + * Description: + * Get meter configuration + * Input: + * index - shared meter index + * Output: + * pType - Meter Type + * pRate - pointer of rate of share meter + * pIfg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_shareMeter_get(rtk_meter_id_t index, rtk_meter_type_t *pType, rtk_rate_t *pRate, rtk_enable_t *pIfg_include); + +/* Function Name: + * rtk_rate_shareMeterBucket_set + * Description: + * Set meter Bucket Size + * Input: + * index - shared meter index + * bucket_size - Bucket Size + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Error Input + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can set shared meter bucket size. + */ +extern rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size); + +/* Function Name: + * rtk_rate_shareMeterBucket_get + * Description: + * Get meter Bucket Size + * Input: + * index - shared meter index + * Output: + * pBucket_size - Bucket Size + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can get shared meter bucket size. + */ +extern rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size); + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_set + * Description: + * Set port ingress bandwidth control + * Input: + * port - Port id + * rate - Rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * fc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid IFG parameter. + * RT_ERR_INBW_RATE - Invalid ingress rate parameter. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include, rtk_enable_t fc_enable); + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_get + * Description: + * Get port ingress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of share meter + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * pFc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include, rtk_enable_t *pFc_enable); + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_set + * Description: + * Set port egress bandwidth control + * Input: + * port - Port id + * rate - Rate of egress bandwidth + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_EBW_RATE - Invalid egress bandwidth/rate + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set(rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_includ); + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_get + * Description: + * Get port egress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of egress bandwidth + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlEnable_set + * Description: + * Set enable status of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * enable - enable status of egress queue bandwidth control + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_get + * Description: + * Get rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * pIndex - shared meter index + * Output: + * pRate - pointer to rate of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * None. + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_set + * Description: + * Set rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * index - shared meter index + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index); + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_get + * Description: + * Get rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * pIndex - shared meter index + * Output: + * pRate - pointer to rate of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex); + +#endif /* __RTK_API_RATE_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rldp.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rldp.h new file mode 100755 index 00000000..111de0c0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rldp.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : Declaration of RLDP and RLPP API + * + * Feature : The file have include the following module and sub-modules + * 1) RLDP and RLPP configuration and status + * + */ + + +#ifndef __RTK_RLDP_H__ +#define __RTK_RLDP_H__ + + +/* + * Include Files + */ + + +/* + * Symbol Definition + */ +typedef enum rtk_rldp_trigger_e +{ + RTK_RLDP_TRIGGER_SAMOVING = 0, + RTK_RLDP_TRIGGER_PERIOD, + RTK_RLDP_TRIGGER_END +} rtk_rldp_trigger_t; + +typedef enum rtk_rldp_cmpType_e +{ + RTK_RLDP_CMPTYPE_MAGIC = 0, /* Compare the RLDP with magic only */ + RTK_RLDP_CMPTYPE_MAGIC_ID, /* Compare the RLDP with both magic + ID */ + RTK_RLDP_CMPTYPE_END +} rtk_rldp_cmpType_t; + +typedef enum rtk_rldp_loopStatus_e +{ + RTK_RLDP_LOOPSTS_NONE = 0, + RTK_RLDP_LOOPSTS_LOOPING, + RTK_RLDP_LOOPSTS_END +} rtk_rldp_loopStatus_t; + +typedef enum rtk_rlpp_trapType_e +{ + RTK_RLPP_TRAPTYPE_NONE = 0, + RTK_RLPP_TRAPTYPE_CPU, + RTK_RLPP_TRAPTYPE_END +} rtk_rlpp_trapType_t; + +typedef struct rtk_rldp_config_s +{ + rtk_enable_t rldp_enable; + rtk_rldp_trigger_t trigger_mode; + rtk_mac_t magic; + rtk_rldp_cmpType_t compare_type; + rtk_uint32 interval_check; /* Checking interval for check state */ + rtk_uint32 num_check; /* Checking number for check state */ + rtk_uint32 interval_loop; /* Checking interval for loop state */ + rtk_uint32 num_loop; /* Checking number for loop state */ +} rtk_rldp_config_t; + +typedef struct rtk_rldp_portConfig_s +{ + rtk_enable_t tx_enable; +} rtk_rldp_portConfig_t; + +typedef struct rtk_rldp_status_s +{ + rtk_mac_t id; +} rtk_rldp_status_t; + +typedef struct rtk_rldp_portStatus_s +{ + rtk_rldp_loopStatus_t loop_status; + rtk_rldp_loopStatus_t loop_enter; + rtk_rldp_loopStatus_t loop_leave; +} rtk_rldp_portStatus_t; + +/* + * Data Declaration + */ + + +/* + * Macro Declaration + */ + +#define RTK_RLDP_INTERVAL_MAX 0xffff +#define RTK_RLDP_NUM_MAX 0xff + + +/* + * Function Declaration + */ + +/* Module Name : RLDP */ + + +/* Function Name: + * rtk_rldp_config_set + * Description: + * Set RLDP module configuration + * Input: + * pConfig - configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig); + + +/* Function Name: + * rtk_rldp_config_get + * Description: + * Get RLDP module configuration + * Input: + * None + * Output: + * pConfig - configuration structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig); + + +/* Function Name: + * rtk_rldp_portConfig_set + * Description: + * Set per port RLDP module configuration + * Input: + * port - port number to be configured + * pPortConfig - per port configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig); + + +/* Function Name: + * rtk_rldp_portConfig_get + * Description: + * Get per port RLDP module configuration + * Input: + * port - port number to be get + * Output: + * pPortConfig - per port configuration structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portConfig_get(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig); + + +/* Function Name: + * rtk_rldp_status_get + * Description: + * Get RLDP module status + * Input: + * None + * Output: + * pStatus - status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus); + + +/* Function Name: + * rtk_rldp_portStatus_get + * Description: + * Get RLDP module status + * Input: + * port - port number to be get + * Output: + * pPortStatus - per port status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus); + + +/* Function Name: + * rtk_rldp_portStatus_clear + * Description: + * Clear RLDP module status + * Input: + * port - port number to be clear + * pPortStatus - per port status structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * Clear operation effect loop_enter and loop_leave only, other field in + * the structure are don't care + */ +extern rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus); + + +/* Function Name: + * rtk_rldp_portLoopPair_get + * Description: + * Get RLDP port loop pairs + * Input: + * port - port number to be get + * Output: + * pPortmask - per port related loop ports + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +extern rtk_api_ret_t rtk_rldp_portLoopPair_get(rtk_port_t port, rtk_portmask_t *pPortmask); + +#endif /* __RTK_RLDP_H__ */ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h new file mode 100755 index 00000000..dc9c0bed --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : Definition the error number in the SDK. + * Feature : error definition + * + */ + +#ifndef __COMMON_RT_ERROR_H__ +#define __COMMON_RT_ERROR_H__ + +/* + * Include Files + */ + +/* + * Data Type Declaration + */ +typedef enum rt_error_code_e +{ + RT_ERR_FAILED = -1, /* General Error */ + + /* 0x0000xxxx for common error code */ + RT_ERR_OK = 0, /* 0x00000000, OK */ + RT_ERR_INPUT, /* 0x00000001, invalid input parameter */ + RT_ERR_UNIT_ID, /* 0x00000002, invalid unit id */ + RT_ERR_PORT_ID, /* 0x00000003, invalid port id */ + RT_ERR_PORT_MASK, /* 0x00000004, invalid port mask */ + RT_ERR_PORT_LINKDOWN, /* 0x00000005, link down port status */ + RT_ERR_ENTRY_INDEX, /* 0x00000006, invalid entry index */ + RT_ERR_NULL_POINTER, /* 0x00000007, input parameter is null pointer */ + RT_ERR_QUEUE_ID, /* 0x00000008, invalid queue id */ + RT_ERR_QUEUE_NUM, /* 0x00000009, invalid queue number */ + RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000000a, busy watting time out */ + RT_ERR_MAC, /* 0x0000000b, invalid mac address */ + RT_ERR_OUT_OF_RANGE, /* 0x0000000c, input parameter out of range */ + RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000000d, functions not supported by this chip model */ + RT_ERR_SMI, /* 0x0000000e, SMI error */ + RT_ERR_NOT_INIT, /* 0x0000000f, The module is not initial */ + RT_ERR_CHIP_NOT_FOUND, /* 0x00000010, The chip can not found */ + RT_ERR_NOT_ALLOWED, /* 0x00000011, actions not allowed by the function */ + RT_ERR_DRIVER_NOT_FOUND, /* 0x00000012, The driver can not found */ + RT_ERR_SEM_LOCK_FAILED, /* 0x00000013, Failed to lock semaphore */ + RT_ERR_SEM_UNLOCK_FAILED, /* 0x00000014, Failed to unlock semaphore */ + RT_ERR_ENABLE, /* 0x00000015, invalid enable parameter */ + RT_ERR_TBL_FULL, /* 0x00000016, input table full */ + + /* 0x0001xxxx for vlan */ + RT_ERR_VLAN_VID = 0x00010000, /* 0x00010000, invalid vid */ + RT_ERR_VLAN_PRIORITY, /* 0x00010001, invalid 1p priority */ + RT_ERR_VLAN_EMPTY_ENTRY, /* 0x00010002, emtpy entry of vlan table */ + RT_ERR_VLAN_ACCEPT_FRAME_TYPE, /* 0x00010003, invalid accept frame type */ + RT_ERR_VLAN_EXIST, /* 0x00010004, vlan is exist */ + RT_ERR_VLAN_ENTRY_NOT_FOUND, /* 0x00010005, specified vlan entry not found */ + RT_ERR_VLAN_PORT_MBR_EXIST, /* 0x00010006, member port exist in the specified vlan */ + RT_ERR_VLAN_PROTO_AND_PORT, /* 0x00010008, invalid protocol and port based vlan */ + + /* 0x0002xxxx for svlan */ + RT_ERR_SVLAN_ENTRY_INDEX = 0x00020000, /* 0x00020000, invalid svid entry no */ + RT_ERR_SVLAN_ETHER_TYPE, /* 0x00020001, invalid SVLAN ether type */ + RT_ERR_SVLAN_TABLE_FULL, /* 0x00020002, no empty entry in SVLAN table */ + RT_ERR_SVLAN_ENTRY_NOT_FOUND, /* 0x00020003, specified svlan entry not found */ + RT_ERR_SVLAN_EXIST, /* 0x00020004, SVLAN entry is exist */ + RT_ERR_SVLAN_VID, /* 0x00020005, invalid svid */ + + /* 0x0003xxxx for MSTP */ + RT_ERR_MSTI = 0x00030000, /* 0x00030000, invalid msti */ + RT_ERR_MSTP_STATE, /* 0x00030001, invalid spanning tree status */ + RT_ERR_MSTI_EXIST, /* 0x00030002, MSTI exist */ + RT_ERR_MSTI_NOT_EXIST, /* 0x00030003, MSTI not exist */ + + /* 0x0004xxxx for BUCKET */ + RT_ERR_TIMESLOT = 0x00040000, /* 0x00040000, invalid time slot */ + RT_ERR_TOKEN, /* 0x00040001, invalid token amount */ + RT_ERR_RATE, /* 0x00040002, invalid rate */ + RT_ERR_TICK, /* 0x00040003, invalid tick */ + + /* 0x0005xxxx for RMA */ + RT_ERR_RMA_ADDR = 0x00050000, /* 0x00050000, invalid rma mac address */ + RT_ERR_RMA_ACTION, /* 0x00050001, invalid rma action */ + + /* 0x0006xxxx for L2 */ + RT_ERR_L2_HASH_KEY = 0x00060000, /* 0x00060000, invalid L2 Hash key */ + RT_ERR_L2_HASH_INDEX, /* 0x00060001, invalid L2 Hash index */ + RT_ERR_L2_CAM_INDEX, /* 0x00060002, invalid L2 CAM index */ + RT_ERR_L2_ENRTYSEL, /* 0x00060003, invalid EntrySel */ + RT_ERR_L2_INDEXTABLE_INDEX, /* 0x00060004, invalid L2 index table(=portMask table) index */ + RT_ERR_LIMITED_L2ENTRY_NUM, /* 0x00060005, invalid limited L2 entry number */ + RT_ERR_L2_AGGREG_PORT, /* 0x00060006, this aggregated port is not the lowest physical + port of its aggregation group */ + RT_ERR_L2_FID, /* 0x00060007, invalid fid */ + RT_ERR_L2_VID, /* 0x00060008, invalid cvid */ + RT_ERR_L2_NO_EMPTY_ENTRY, /* 0x00060009, no empty entry in L2 table */ + RT_ERR_L2_ENTRY_NOTFOUND, /* 0x0006000a, specified entry not found */ + RT_ERR_L2_INDEXTBL_FULL, /* 0x0006000b, the L2 index table is full */ + RT_ERR_L2_INVALID_FLOWTYPE, /* 0x0006000c, invalid L2 flow type */ + RT_ERR_L2_L2UNI_PARAM, /* 0x0006000d, invalid L2 unicast parameter */ + RT_ERR_L2_L2MULTI_PARAM, /* 0x0006000e, invalid L2 multicast parameter */ + RT_ERR_L2_IPMULTI_PARAM, /* 0x0006000f, invalid L2 ip multicast parameter */ + RT_ERR_L2_PARTIAL_HASH_KEY, /* 0x00060010, invalid L2 partial Hash key */ + RT_ERR_L2_EMPTY_ENTRY, /* 0x00060011, the entry is empty(invalid) */ + RT_ERR_L2_FLUSH_TYPE, /* 0x00060012, the flush type is invalid */ + RT_ERR_L2_NO_CPU_PORT, /* 0x00060013, CPU port not exist */ + + /* 0x0007xxxx for FILTER (PIE) */ + RT_ERR_FILTER_BLOCKNUM = 0x00070000, /* 0x00070000, invalid block number */ + RT_ERR_FILTER_ENTRYIDX, /* 0x00070001, invalid entry index */ + RT_ERR_FILTER_CUTLINE, /* 0x00070002, invalid cutline value */ + RT_ERR_FILTER_FLOWTBLBLOCK, /* 0x00070003, block belongs to flow table */ + RT_ERR_FILTER_INACLBLOCK, /* 0x00070004, block belongs to ingress ACL */ + RT_ERR_FILTER_ACTION, /* 0x00070005, action doesn't consist to entry type */ + RT_ERR_FILTER_INACL_RULENUM, /* 0x00070006, invalid ACL rulenum */ + RT_ERR_FILTER_INACL_TYPE, /* 0x00070007, entry type isn't an ingress ACL rule */ + RT_ERR_FILTER_INACL_EXIST, /* 0x00070008, ACL entry is already exit */ + RT_ERR_FILTER_INACL_EMPTY, /* 0x00070009, ACL entry is empty */ + RT_ERR_FILTER_FLOWTBL_TYPE, /* 0x0007000a, entry type isn't an flow table rule */ + RT_ERR_FILTER_FLOWTBL_RULENUM, /* 0x0007000b, invalid flow table rulenum */ + RT_ERR_FILTER_FLOWTBL_EMPTY, /* 0x0007000c, flow table entry is empty */ + RT_ERR_FILTER_FLOWTBL_EXIST, /* 0x0007000d, flow table entry is already exist */ + RT_ERR_FILTER_METER_ID, /* 0x0007000e, invalid metering id */ + RT_ERR_FILTER_LOG_ID, /* 0x0007000f, invalid log id */ + RT_ERR_FILTER_INACL_NONE_BEGIN_IDX, /* 0x00070010, entry index is not starting index of a group of rules */ + RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT, /* 0x00070011, action not support */ + RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT, /* 0x00070012, rule not support */ + + /* 0x0008xxxx for ACL Rate Limit */ + RT_ERR_ACLRL_HTHR = 0x00080000, /* 0x00080000, invalid high threshold */ + RT_ERR_ACLRL_TIMESLOT, /* 0x00080001, invalid time slot */ + RT_ERR_ACLRL_TOKEN, /* 0x00080002, invalid token amount */ + RT_ERR_ACLRL_RATE, /* 0x00080003, invalid rate */ + + /* 0x0009xxxx for Link aggregation */ + RT_ERR_LA_CPUPORT = 0x00090000, /* 0x00090000, CPU port can not be aggregated port */ + RT_ERR_LA_TRUNK_ID, /* 0x00090001, invalid trunk id */ + RT_ERR_LA_PORTMASK, /* 0x00090002, invalid port mask */ + RT_ERR_LA_HASHMASK, /* 0x00090003, invalid hash mask */ + RT_ERR_LA_DUMB, /* 0x00090004, this API should be used in 802.1ad dumb mode */ + RT_ERR_LA_PORTNUM_DUMB, /* 0x00090005, it can only aggregate at most four ports when 802.1ad dumb mode */ + RT_ERR_LA_PORTNUM_NORMAL, /* 0x00090006, it can only aggregate at most eight ports when 802.1ad normal mode */ + RT_ERR_LA_MEMBER_OVERLAP, /* 0x00090007, the specified port mask is overlapped with other group */ + RT_ERR_LA_NOT_MEMBER_PORT, /* 0x00090008, the port is not a member port of the trunk */ + RT_ERR_LA_TRUNK_NOT_EXIST, /* 0x00090009, the trunk doesn't exist */ + + + /* 0x000axxxx for storm filter */ + RT_ERR_SFC_TICK_PERIOD = 0x000a0000, /* 0x000a0000, invalid SFC tick period */ + RT_ERR_SFC_UNKNOWN_GROUP, /* 0x000a0001, Unknown Storm filter group */ + + /* 0x000bxxxx for pattern match */ + RT_ERR_PM_MASK = 0x000b0000, /* 0x000b0000, invalid pattern length. Pattern length should be 8 */ + RT_ERR_PM_LENGTH, /* 0x000b0001, invalid pattern match mask, first byte must care */ + RT_ERR_PM_MODE, /* 0x000b0002, invalid pattern match mode */ + + /* 0x000cxxxx for input bandwidth control */ + RT_ERR_INBW_TICK_PERIOD = 0x000c0000, /* 0x000c0000, invalid tick period for input bandwidth control */ + RT_ERR_INBW_TOKEN_AMOUNT, /* 0x000c0001, invalid amount of token for input bandwidth control */ + RT_ERR_INBW_FCON_VALUE, /* 0x000c0002, invalid flow control ON threshold value for input bandwidth control */ + RT_ERR_INBW_FCOFF_VALUE, /* 0x000c0003, invalid flow control OFF threshold value for input bandwidth control */ + RT_ERR_INBW_FC_ALLOWANCE, /* 0x000c0004, invalid allowance of incomming packet for input bandwidth control */ + RT_ERR_INBW_RATE, /* 0x000c0005, invalid input bandwidth */ + + /* 0x000dxxxx for QoS */ + RT_ERR_QOS_1P_PRIORITY = 0x000d0000, /* 0x000d0000, invalid 802.1P priority */ + RT_ERR_QOS_DSCP_VALUE, /* 0x000d0001, invalid DSCP value */ + RT_ERR_QOS_INT_PRIORITY, /* 0x000d0002, invalid internal priority */ + RT_ERR_QOS_SEL_DSCP_PRI, /* 0x000d0003, invalid DSCP selection priority */ + RT_ERR_QOS_SEL_PORT_PRI, /* 0x000d0004, invalid port selection priority */ + RT_ERR_QOS_SEL_IN_ACL_PRI, /* 0x000d0005, invalid ingress ACL selection priority */ + RT_ERR_QOS_SEL_CLASS_PRI, /* 0x000d0006, invalid classifier selection priority */ + RT_ERR_QOS_EBW_RATE, /* 0x000d0007, invalid egress bandwidth rate */ + RT_ERR_QOS_SCHE_TYPE, /* 0x000d0008, invalid QoS scheduling type */ + RT_ERR_QOS_QUEUE_WEIGHT, /* 0x000d0009, invalid Queue weight */ + RT_ERR_QOS_SEL_PRI_SOURCE, /* 0x000d000a, invalid selection of priority source */ + + /* 0x000exxxx for port ability */ + RT_ERR_PHY_PAGE_ID = 0x000e0000, /* 0x000e0000, invalid PHY page id */ + RT_ERR_PHY_REG_ID, /* 0x000e0001, invalid PHY reg id */ + RT_ERR_PHY_DATAMASK, /* 0x000e0002, invalid PHY data mask */ + RT_ERR_PHY_AUTO_NEGO_MODE, /* 0x000e0003, invalid PHY auto-negotiation mode*/ + RT_ERR_PHY_SPEED, /* 0x000e0004, invalid PHY speed setting */ + RT_ERR_PHY_DUPLEX, /* 0x000e0005, invalid PHY duplex setting */ + RT_ERR_PHY_FORCE_ABILITY, /* 0x000e0006, invalid PHY force mode ability parameter */ + RT_ERR_PHY_FORCE_1000, /* 0x000e0007, invalid PHY force mode 1G speed setting */ + RT_ERR_PHY_TXRX, /* 0x000e0008, invalid PHY tx/rx */ + RT_ERR_PHY_ID, /* 0x000e0009, invalid PHY id */ + RT_ERR_PHY_RTCT_NOT_FINISH, /* 0x000e000a, PHY RTCT in progress */ + + /* 0x000fxxxx for mirror */ + RT_ERR_MIRROR_DIRECTION = 0x000f0000, /* 0x000f0000, invalid error mirror direction */ + RT_ERR_MIRROR_SESSION_FULL, /* 0x000f0001, mirroring session is full */ + RT_ERR_MIRROR_SESSION_NOEXIST, /* 0x000f0002, mirroring session not exist */ + RT_ERR_MIRROR_PORT_EXIST, /* 0x000f0003, mirroring port already exists */ + RT_ERR_MIRROR_PORT_NOT_EXIST, /* 0x000f0004, mirroring port does not exists */ + RT_ERR_MIRROR_PORT_FULL, /* 0x000f0005, Exceeds maximum number of supported mirroring port */ + + /* 0x0010xxxx for stat */ + RT_ERR_STAT_INVALID_GLOBAL_CNTR = 0x00100000, /* 0x00100000, Invalid Global Counter */ + RT_ERR_STAT_INVALID_PORT_CNTR, /* 0x00100001, Invalid Port Counter */ + RT_ERR_STAT_GLOBAL_CNTR_FAIL, /* 0x00100002, Could not retrieve/reset Global Counter */ + RT_ERR_STAT_PORT_CNTR_FAIL, /* 0x00100003, Could not retrieve/reset Port Counter */ + RT_ERR_STAT_INVALID_CNTR, /* 0x00100004, Invalid Counter */ + RT_ERR_STAT_CNTR_FAIL, /* 0x00100005, Could not retrieve/reset Counter */ + + /* 0x0011xxxx for dot1x */ + RT_ERR_DOT1X_INVALID_DIRECTION = 0x00110000, /* 0x00110000, Invalid Authentication Direction */ + RT_ERR_DOT1X_PORTBASEDPNEN, /* 0x00110001, Port-based enable port error */ + RT_ERR_DOT1X_PORTBASEDAUTH, /* 0x00110002, Port-based auth port error */ + RT_ERR_DOT1X_PORTBASEDOPDIR, /* 0x00110003, Port-based opdir error */ + RT_ERR_DOT1X_MACBASEDPNEN, /* 0x00110004, MAC-based enable port error */ + RT_ERR_DOT1X_MACBASEDOPDIR, /* 0x00110005, MAC-based opdir error */ + RT_ERR_DOT1X_PROC, /* 0x00110006, unauthorized behavior error */ + RT_ERR_DOT1X_GVLANIDX, /* 0x00110007, guest vlan index error */ + RT_ERR_DOT1X_GVLANTALK, /* 0x00110008, guest vlan OPDIR error */ + RT_ERR_DOT1X_MAC_PORT_MISMATCH, /* 0x00110009, Auth MAC and port mismatch eror */ + + RT_ERR_END /* The symbol is the latest symbol */ +} rt_error_code_t; + + +#endif /* __COMMON_RT_ERROR_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h new file mode 100755 index 00000000..6ddb23f2 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h @@ -0,0 +1,44 @@ +#ifndef __RTK_HAL_H__ +#define __RTK_HAL_H__ +#include "ra_ioctl.h" + +#define RTK_SW_VID_RANGE 16 +void rtk_hal_switch_init(void); +void rtk_hal_dump_mib(void); +void rtk_hal_dump_full_mib(void); +int rtk_hal_dump_vlan(void); +void rtk_hal_clear_vlan(void); +int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data); +int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data); +int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data); +void rtk_hal_dump_table(void); +void rtk_hal_clear_table(void); +void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data); +void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data); +void rtk_hal_read_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_write_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_en(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data); +void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data); +void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data); +void rtk_hal_disable_igmpsnoop(void); +void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data); +void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data); +void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data); +void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority); +void rtk_hal_add_table(struct ra_switch_ioctl_data *data); +void rtk_hal_del_table(struct ra_switch_ioctl_data *data); +void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data); +void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data); +#endif diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h new file mode 100755 index 00000000..b0ca1368 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h @@ -0,0 +1,737 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76336 $ + * $Date: 2017-03-09 10:41:21 +0800 (週四, 09 三月 2017) $ + * + * Purpose : RTK switch high-level API + * Feature : Here is a list of all functions and variables in this module. + * + */ + +#ifndef __RTK_SWITCH_H__ +#define __RTK_SWITCH_H__ + +#include + +#define UNDEFINE_PHY_PORT (0xFF) +#define RTK_SWITCH_PORT_NUM (32) + +#define MAXPKTLEN_CFG_ID_MAX (1) + +#define RTK_SWITCH_MAX_PKTLEN (0x3FFF) + +typedef enum init_state_e +{ + INIT_NOT_COMPLETED = 0, + INIT_COMPLETED, + INIT_STATE_END +} init_state_t; + +typedef enum switch_chip_e +{ + CHIP_RTL8367C = 0, + CHIP_RTL8370B, + CHIP_RTL8364B, + CHIP_RTL8363SC_VB, + CHIP_END +}switch_chip_t; + +typedef enum port_type_e +{ + UTP_PORT = 0, + EXT_PORT, + UNKNOWN_PORT = 0xFF, + PORT_TYPE_END +}port_type_t; + +typedef struct rtk_switch_halCtrl_s +{ + switch_chip_t switch_type; + rtk_uint32 l2p_port[RTK_SWITCH_PORT_NUM]; + rtk_uint32 p2l_port[RTK_SWITCH_PORT_NUM]; + port_type_t log_port_type[RTK_SWITCH_PORT_NUM]; + rtk_uint32 ptp_port[RTK_SWITCH_PORT_NUM]; + rtk_uint32 valid_portmask; + rtk_uint32 valid_utp_portmask; + rtk_uint32 valid_ext_portmask; + rtk_uint32 valid_cpu_portmask; + rtk_uint32 min_phy_port; + rtk_uint32 max_phy_port; + rtk_uint32 phy_portmask; + rtk_uint32 combo_logical_port; + rtk_uint32 hsg_logical_port; + rtk_uint32 sg_logical_portmask; + rtk_uint32 max_meter_id; + rtk_uint32 max_lut_addr_num; + rtk_uint32 trunk_group_mask; + +}rtk_switch_halCtrl_t; + +typedef enum rtk_switch_maxPktLen_linkSpeed_e { + MAXPKTLEN_LINK_SPEED_FE = 0, + MAXPKTLEN_LINK_SPEED_GE, + MAXPKTLEN_LINK_SPEED_END, +} rtk_switch_maxPktLen_linkSpeed_t; + + +/* UTIL MACRO */ +#define RTK_CHK_INIT_STATE() \ + do \ + { \ + if(rtk_switch_initialState_get() != INIT_COMPLETED) \ + { \ + return RT_ERR_NOT_INIT; \ + } \ + }while(0) + +#define RTK_CHK_PORT_VALID(__port__) \ + do \ + { \ + if(rtk_switch_logicalPortCheck(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_UTP(__port__) \ + do \ + { \ + if(rtk_switch_isUtpPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_EXT(__port__) \ + do \ + { \ + if(rtk_switch_isExtPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_COMBO(__port__) \ + do \ + { \ + if(rtk_switch_isComboPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORT_IS_PTP(__port__) \ + do \ + { \ + if(rtk_switch_isPtpPort(__port__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_ID; \ + } \ + }while(0) + +#define RTK_CHK_PORTMASK_VALID(__portmask__) \ + do \ + { \ + if(rtk_switch_isPortMaskValid(__portmask__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_MASK; \ + } \ + }while(0) + +#define RTK_CHK_PORTMASK_VALID_ONLY_UTP(__portmask__) \ + do \ + { \ + if(rtk_switch_isPortMaskUtp(__portmask__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_MASK; \ + } \ + }while(0) + +#define RTK_CHK_PORTMASK_VALID_ONLY_EXT(__portmask__) \ + do \ + { \ + if(rtk_switch_isPortMaskExt(__portmask__) != RT_ERR_OK) \ + { \ + return RT_ERR_PORT_MASK; \ + } \ + }while(0) + +#define RTK_CHK_TRUNK_GROUP_VALID(__grpId__) \ + do \ + { \ + if(rtk_switch_isValidTrunkGrpId(__grpId__) != RT_ERR_OK) \ + { \ + return RT_ERR_LA_TRUNK_ID; \ + } \ + }while(0) + +#define RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__) (((__portmask__).bits[0] & (0x00000001 << __port__)) ? 1 : 0) +#define RTK_PORTMASK_IS_EMPTY(__portmask__) (((__portmask__).bits[0] == 0) ? 1 : 0) +#define RTK_PORTMASK_CLEAR(__portmask__) ((__portmask__).bits[0] = 0) +#define RTK_PORTMASK_PORT_SET(__portmask__, __port__) ((__portmask__).bits[0] |= (0x00000001 << __port__)) +#define RTK_PORTMASK_PORT_CLEAR(__portmask__, __port__) ((__portmask__).bits[0] &= ~(0x00000001 << __port__)) +#define RTK_PORTMASK_ALLPORT_SET(__portmask__) (rtk_switch_logPortMask_get(&__portmask__)) +#define RTK_PORTMASK_SCAN(__portmask__, __port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if(RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__)) +#define RTK_PORTMASK_COMPARE(__portmask_A__, __portmask_B__) ((__portmask_A__).bits[0] - (__portmask_B__).bits[0]) + +#define RTK_SCAN_ALL_PHY_PORTMASK(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( (rtk_switch_phyPortMask_get() & (0x00000001 << __port__))) +#define RTK_SCAN_ALL_LOG_PORT(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( rtk_switch_logicalPortCheck(__port__) == RT_ERR_OK) +#define RTK_SCAN_ALL_LOG_PORTMASK(__portmask__) for((__portmask__).bits[0] = 0; (__portmask__).bits[0] < 0x7FFFF; (__portmask__).bits[0]++) if( rtk_switch_isPortMaskValid(&__portmask__) == RT_ERR_OK) + +/* Port mask defination */ +#define RTK_PHY_PORTMASK_ALL (rtk_switch_phyPortMask_get()) + +/* Port defination*/ +#define RTK_MAX_LOGICAL_PORT_ID (rtk_switch_maxLogicalPort_get()) + +/* Function Name: + * rtk_switch_probe + * Description: + * Probe switch + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Switch probed + * RT_ERR_FAILED - Switch Unprobed. + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip); + +/* Function Name: + * rtk_switch_initialState_set + * Description: + * Set initial status + * Input: + * state - Initial state; + * Output: + * None + * Return: + * RT_ERR_OK - Initialized + * RT_ERR_FAILED - Uninitialized + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_initialState_set(init_state_t state); + +/* Function Name: + * rtk_switch_initialState_get + * Description: + * Get initial status + * Input: + * None + * Output: + * None + * Return: + * INIT_COMPLETED - Initialized + * INIT_NOT_COMPLETED - Uninitialized + * Note: + * + */ +extern init_state_t rtk_switch_initialState_get(void); + +/* Function Name: + * rtk_switch_logicalPortCheck + * Description: + * Check logical port ID. + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is correct + * RT_ERR_FAILED - Port ID is not correct + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isUtpPort + * Description: + * Check is logical port a UTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a UTP port + * RT_ERR_FAILED - Port ID is not a UTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isExtPort + * Description: + * Check is logical port a Extension port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a EXT port + * RT_ERR_FAILED - Port ID is not a EXT port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isHsgPort + * Description: + * Check is logical port a HSG port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a HSG port + * RT_ERR_FAILED - Port ID is not a HSG port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isSgmiiPort + * Description: + * Check is logical port a SGMII port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a SGMII port + * RT_ERR_FAILED - Port ID is not a SGMII port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isCPUPort + * Description: + * Check is logical port a CPU port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a CPU port + * RT_ERR_FAILED - Port ID is not a CPU port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_isComboPort + * Description: + * Check is logical port a Combo port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a combo port + * RT_ERR_FAILED - Port ID is not a combo port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_ComboPort_get + * Description: + * Get Combo port ID + * Input: + * None + * Output: + * None + * Return: + * Port ID of combo port + * Note: + * + */ +extern rtk_uint32 rtk_switch_ComboPort_get(void); + +/* Function Name: + * rtk_switch_isPtpPort + * Description: + * Check is logical port a PTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a PTP port + * RT_ERR_FAILED - Port ID is not a PTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_port_L2P_get + * Description: + * Get physical port ID + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * Physical port ID + * Note: + * + */ +extern rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort); + +/* Function Name: + * rtk_switch_port_P2L_get + * Description: + * Get logical port ID + * Input: + * physicalPort - physical port ID + * Output: + * None + * Return: + * logical port ID + * Note: + * + */ +extern rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort); + +/* Function Name: + * rtk_switch_isPortMaskValid + * Description: + * Check portmask is valid or not + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - port mask is valid + * RT_ERR_FAILED - port mask is not valid + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask); + +/* Function Name: + * rtk_switch_isPortMaskUtp + * Description: + * Check all ports in portmask are only UTP port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only UTP port in port mask + * RT_ERR_FAILED - Not only UTP port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask); + +/* Function Name: + * rtk_switch_isPortMaskExt + * Description: + * Check all ports in portmask are only EXT port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only EXT port in port mask + * RT_ERR_FAILED - Not only EXT port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask); + +/* Function Name: + * rtk_switch_portmask_L2P_get + * Description: + * Get physicl portmask from logical portmask + * Input: + * pLogicalPmask - logical port mask + * Output: + * pPhysicalPortmask - physical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask); + +/* Function Name: + * rtk_switch_portmask_P2L_get + * Description: + * Get logical portmask from physical portmask + * Input: + * physicalPortmask - physical port mask + * Output: + * pLogicalPmask - logical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +extern rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask); + +/* Function Name: + * rtk_switch_phyPortMask_get + * Description: + * Get physical portmask + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Physical port mask + * Note: + * + */ +rtk_uint32 rtk_switch_phyPortMask_get(void); + +/* Function Name: + * rtk_switch_logPortMask_get + * Description: + * Get Logical portmask + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_logPortMask_get(rtk_portmask_t *pPortmask); + +/* Function Name: + * rtk_switch_init + * Description: + * Set chip to default configuration enviroment + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can set chip registers to default configuration for different release chip model. + */ +extern rtk_api_ret_t rtk_switch_init(void); + +/* Function Name: + * rtk_switch_portMaxPktLen_set + * Description: + * Set Max packet length + * Input: + * port - Port ID + * speed - Speed + * cfgId - Configuration ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId); + +/* Function Name: + * rtk_switch_portMaxPktLen_get + * Description: + * Get Max packet length + * Input: + * port - Port ID + * speed - Speed + * Output: + * pCfgId - Configuration ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId); + +/* Function Name: + * rtk_switch_maxPktLenCfg_set + * Description: + * Set Max packet length configuration + * Input: + * cfgId - Configuration ID + * pktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen); + +/* Function Name: + * rtk_switch_maxPktLenCfg_get + * Description: + * Get Max packet length configuration + * Input: + * cfgId - Configuration ID + * pPktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +extern rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen); + +/* Function Name: + * rtk_switch_greenEthernet_set + * Description: + * Set all Ports Green Ethernet state. + * Input: + * enable - Green Ethernet state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all Ports Green Ethernet state. + * The configuration is as following: + * - DISABLE + * - ENABLE + */ +extern rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable); + +/* Function Name: + * rtk_switch_greenEthernet_get + * Description: + * Get all Ports Green Ethernet state. + * Input: + * None + * Output: + * pEnable - Green Ethernet state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can get Green Ethernet state. + */ +extern rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable); + +/* Function Name: + * rtk_switch_maxLogicalPort_get + * Description: + * Get Max logical port ID + * Input: + * None + * Output: + * None + * Return: + * Max logical port + * Note: + * This API can get max logical port + */ +extern rtk_port_t rtk_switch_maxLogicalPort_get(void); + +/* Function Name: + * rtk_switch_maxMeterId_get + * Description: + * Get Max Meter ID + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max Meter ID + * Note: + * + */ +extern rtk_uint32 rtk_switch_maxMeterId_get(void); + +/* Function Name: + * rtk_switch_maxLutAddrNumber_get + * Description: + * Get Max LUT Address number + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max LUT Address number + * Note: + * + */ +extern rtk_uint32 rtk_switch_maxLutAddrNumber_get(void); + +/* Function Name: + * rtk_switch_isValidTrunkGrpId + * Description: + * Check if trunk group is valid or not + * Input: + * grpId - Group ID + * Output: + * None + * Return: + * RT_ERR_OK - Trunk Group ID is valid + * RT_ERR_LA_TRUNK_ID - Trunk Group ID is not valid + * Note: + * + */ +rtk_uint32 rtk_switch_isValidTrunkGrpId(rtk_uint32 grpId); + +#endif diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h new file mode 100755 index 00000000..589ecb78 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level type enum definition. + * Feature : + * + */ + +#ifndef _RTL8367C_TYPES_H_ +#define _RTL8367C_TYPES_H_ + +//#include + +typedef unsigned long long rtk_uint64; +typedef long long rtk_int64; +typedef unsigned int rtk_uint32; +typedef int rtk_int32; +typedef unsigned short rtk_uint16; +typedef short rtk_int16; +typedef unsigned char rtk_uint8; +typedef char rtk_int8; + +#define CONST_T const + +#define RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST 1 + +#define RTK_MAX_NUM_OF_PORT 8 +#define RTK_PORT_ID_MAX (RTK_MAX_NUM_OF_PORT-1) +#define RTK_PHY_ID_MAX (RTK_MAX_NUM_OF_PORT-4) +#define RTK_MAX_PORT_MASK 0xFF + +#define RTK_WHOLE_SYSTEM 0xFF + +typedef struct rtk_portmask_s +{ + rtk_uint32 bits[RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST]; +} rtk_portmask_t; + +typedef enum rtk_enable_e +{ + DISABLED = 0, + ENABLED, + RTK_ENABLE_END +} rtk_enable_t; + +#ifndef ETHER_ADDR_LEN +#define ETHER_ADDR_LEN 6 +#endif + +/* ethernet address type */ +typedef struct rtk_mac_s +{ + rtk_uint8 octet[ETHER_ADDR_LEN]; +} rtk_mac_t; + +typedef rtk_uint32 rtk_pri_t; /* priority vlaue */ +typedef rtk_uint32 rtk_qid_t; /* queue id type */ +typedef rtk_uint32 rtk_data_t; +typedef rtk_uint32 rtk_dscp_t; /* dscp vlaue */ +typedef rtk_uint32 rtk_fid_t; /* filter id type */ +typedef rtk_uint32 rtk_vlan_t; /* vlan id type */ +typedef rtk_uint32 rtk_mac_cnt_t; /* MAC count type */ +typedef rtk_uint32 rtk_meter_id_t; /* meter id type */ +typedef rtk_uint32 rtk_rate_t; /* rate type */ + +typedef enum rtk_port_e +{ + UTP_PORT0 = 0, + UTP_PORT1, + UTP_PORT2, + UTP_PORT3, + UTP_PORT4, + UTP_PORT5, + UTP_PORT6, + UTP_PORT7, + + EXT_PORT0 = 16, + EXT_PORT1, + EXT_PORT2, + + UNDEFINE_PORT = 30, + RTK_PORT_MAX = 31 +} rtk_port_t; + + +#ifndef _RTL_TYPES_H + +#if 0 +typedef unsigned long long uint64; +typedef long long int64; +typedef unsigned int uint32; +typedef int int32; +typedef unsigned short uint16; +typedef short int16; +typedef unsigned char uint8; +typedef char int8; +#endif + +typedef rtk_uint32 ipaddr_t; +typedef rtk_uint32 memaddr; + +#ifndef ETHER_ADDR_LEN +#define ETHER_ADDR_LEN 6 +#endif + +typedef struct ether_addr_s { + rtk_uint8 octet[ETHER_ADDR_LEN]; +} ether_addr_t; + +#ifdef __KERNEL__ +#define rtlglue_printf printk +#else +#define rtlglue_printf printf +#endif +#define PRINT rtlglue_printf +#endif /*_RTL_TYPES_H*/ + +/* type abstraction */ +#ifdef EMBEDDED_SUPPORT + +typedef rtk_int16 rtk_api_ret_t; +typedef rtk_int16 ret_t; +typedef rtk_uint32 rtk_u_long; + +#else + +typedef rtk_int32 rtk_api_ret_t; +typedef rtk_int32 ret_t; +typedef rtk_uint64 rtk_u_long_t; + +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define CONST const +#endif /* _RTL8367C_TYPES_H_ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h new file mode 100755 index 00000000..55cb41b0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : + * + */ + + +#ifndef _RTL8367C_ASICDRV_H_ +#define _RTL8367C_ASICDRV_H_ + +#include +#include +#include +#include + +#define RTL8367C_REGBITLENGTH 16 +#define RTL8367C_REGDATAMAX 0xFFFF + +#define RTL8367C_VIDMAX 0xFFF +#define RTL8367C_EVIDMAX 0x1FFF +#define RTL8367C_CVIDXNO 32 +#define RTL8367C_CVIDXMAX (RTL8367C_CVIDXNO-1) + +#define RTL8367C_PRIMAX 7 +#define RTL8367C_DSCPMAX 63 + +#define RTL8367C_PORTNO 11 +#define RTL8367C_PORTIDMAX (RTL8367C_PORTNO-1) +#define RTL8367C_PMSKMAX ((1<<(RTL8367C_PORTNO))-1) +#define RTL8367C_PORTMASK 0x7FF + +#define RTL8367C_PHYNO 5 +#define RTL8367C_PHYIDMAX (RTL8367C_PHYNO-1) + +#define RTL8367C_SVIDXNO 64 +#define RTL8367C_SVIDXMAX (RTL8367C_SVIDXNO-1) +#define RTL8367C_MSTIMAX 15 + +#define RTL8367C_METERNO 64 +#define RTL8367C_METERMAX (RTL8367C_METERNO-1) +#define RTL8367C_METERBUCKETSIZEMAX 0xFFFF + +#define RTL8367C_QUEUENO 8 +#define RTL8367C_QIDMAX (RTL8367C_QUEUENO-1) + +#define RTL8367C_PHY_BUSY_CHECK_COUNTER 1000 + +#define RTL8367C_QOS_GRANULARTY_MAX 0x7FFFF +#define RTL8367C_QOS_GRANULARTY_LSB_MASK 0xFFFF +#define RTL8367C_QOS_GRANULARTY_LSB_OFFSET 0 +#define RTL8367C_QOS_GRANULARTY_MSB_MASK 0x70000 +#define RTL8367C_QOS_GRANULARTY_MSB_OFFSET 16 + +#define RTL8367C_QOS_GRANULARTY_UNIT_KBPS 8 + +#define RTL8367C_QOS_RATE_INPUT_MAX (0x1FFFF * 8) +#define RTL8367C_QOS_RATE_INPUT_MAX_HSG (0x7FFFF * 8) +#define RTL8367C_QOS_RATE_INPUT_MIN 8 +#define RTL8367C_QOS_PPS_INPUT_MAX (0x7FFFF) +#define RTL8367C_QOS_PPS_INPUT_MIN 1 + +#define RTL8367C_QUEUE_MASK 0xFF + +#define RTL8367C_EFIDMAX 0x7 +#define RTL8367C_FIDMAX 0xF + +#define RTL8367C_EAV_SECONDMAX 0xFFFFFFFF +#define RTL8367C_EAV_NANOSECONDMAX 0x3B9AC9FF + + +/* the above macro is generated by genDotH */ +#define RTL8367C_VALID_REG_NO 3869 + +/*======================================================================= + * Enum + *========================================================================*/ +enum RTL8367C_TABLE_ACCESS_OP +{ + TB_OP_READ = 0, + TB_OP_WRITE +}; + +enum RTL8367C_TABLE_ACCESS_TARGET +{ + TB_TARGET_ACLRULE = 1, + TB_TARGET_ACLACT, + TB_TARGET_CVLAN, + TB_TARGET_L2, + TB_TARGET_IGMP_GROUP +}; + +#define RTL8367C_TABLE_ACCESS_REG_DATA(op, target) ((op << 3) | target) + +/*======================================================================= + * Structures + *========================================================================*/ + + +#ifdef __cplusplus +extern "C" { +#endif +extern ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value); +extern ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue); + +extern ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value); +extern ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue); + +extern ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value); +extern ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue); + +#ifdef __cplusplus +} +#endif + + + +#endif /*#ifndef _RTL8367C_ASICDRV_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h new file mode 100755 index 00000000..8ae69ac3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : ACL related function drivers + * + */ + +#ifndef _RTL8367C_ASICDRV_ACL_H_ +#define _RTL8367C_ASICDRV_ACL_H_ + +#include + +#define RTL8367C_ACLRULENO 96 + +#define RTL8367C_ACLRULEMAX (RTL8367C_ACLRULENO-1) +#define RTL8367C_ACLRULEFIELDNO 8 +#define RTL8367C_ACLTEMPLATENO 5 +#define RTL8367C_ACLTYPEMAX (RTL8367C_ACLTEMPLATENO-1) + +#define RTL8367C_ACLRULETBLEN 9 +#define RTL8367C_ACLACTTBLEN 4 +#define RTL8367C_ACLRULETBADDR(type, rule) ((type << 6) | rule) +#define RTL8367C_ACLRULETBADDR2(type, rule) ((type << 5) | (rule + 64)) + +#define ACL_ACT_CVLAN_ENABLE_MASK 0x1 +#define ACL_ACT_SVLAN_ENABLE_MASK 0x2 +#define ACL_ACT_PRIORITY_ENABLE_MASK 0x4 +#define ACL_ACT_POLICING_ENABLE_MASK 0x8 +#define ACL_ACT_FWD_ENABLE_MASK 0x10 +#define ACL_ACT_INTGPIO_ENABLE_MASK 0x20 + +#define RTL8367C_ACLRULETAGBITS 5 + +#define RTL8367C_ACLRANGENO 16 + +#define RTL8367C_ACLRANGEMAX (RTL8367C_ACLRANGENO-1) + +#define RTL8367C_ACL_PORTRANGEMAX (0xFFFF) +#define RTL8367C_ACL_ACT_TABLE_LEN (4) + +enum ACLTCAMTYPES +{ + CAREBITS= 0, + DATABITS +}; + +typedef enum aclFwdAct +{ + RTL8367C_ACL_FWD_MIRROR = 0, + RTL8367C_ACL_FWD_REDIRECT, + RTL8367C_ACL_FWD_MIRRORFUNTION, + RTL8367C_ACL_FWD_TRAP, +} rtl8367c_aclFwd_t; + +enum ACLFIELDTYPES +{ + ACL_UNUSED, + ACL_DMAC0, + ACL_DMAC1, + ACL_DMAC2, + ACL_SMAC0, + ACL_SMAC1, + ACL_SMAC2, + ACL_ETHERTYPE, + ACL_STAG, + ACL_CTAG, + ACL_IP4SIP0 = 0x10, + ACL_IP4SIP1, + ACL_IP4DIP0, + ACL_IP4DIP1, + ACL_IP6SIP0WITHIPV4 = 0x20, + ACL_IP6SIP1WITHIPV4, + ACL_IP6DIP0WITHIPV4 = 0x28, + ACL_IP6DIP1WITHIPV4, + ACL_VIDRANGE = 0x30, + ACL_IPRANGE, + ACL_PORTRANGE, + ACL_FIELD_VALID, + ACL_FIELD_SELECT00 = 0x40, + ACL_FIELD_SELECT01, + ACL_FIELD_SELECT02, + ACL_FIELD_SELECT03, + ACL_FIELD_SELECT04, + ACL_FIELD_SELECT05, + ACL_FIELD_SELECT06, + ACL_FIELD_SELECT07, + ACL_FIELD_SELECT08, + ACL_FIELD_SELECT09, + ACL_FIELD_SELECT10, + ACL_FIELD_SELECT11, + ACL_FIELD_SELECT12, + ACL_FIELD_SELECT13, + ACL_FIELD_SELECT14, + ACL_FIELD_SELECT15, + ACL_TCPSPORT = 0x80, + ACL_TCPDPORT, + ACL_TCPFLAG, + ACL_UDPSPORT, + ACL_UDPDPORT, + ACL_ICMPCODETYPE, + ACL_IGMPTYPE, + ACL_SPORT, + ACL_DPORT, + ACL_IP4TOSPROTO, + ACL_IP4FLAGOFF, + ACL_TCNH, + ACL_CPUTAG, + ACL_L2PAYLOAD, + ACL_IP6SIP0, + ACL_IP6SIP1, + ACL_IP6SIP2, + ACL_IP6SIP3, + ACL_IP6SIP4, + ACL_IP6SIP5, + ACL_IP6SIP6, + ACL_IP6SIP7, + ACL_IP6DIP0, + ACL_IP6DIP1, + ACL_IP6DIP2, + ACL_IP6DIP3, + ACL_IP6DIP4, + ACL_IP6DIP5, + ACL_IP6DIP6, + ACL_IP6DIP7, + ACL_TYPE_END +}; + +struct acl_rule_smi_st{ + rtk_uint16 rule_info; + rtk_uint16 field[RTL8367C_ACLRULEFIELDNO]; +}; + +struct acl_rule_smi_ext_st{ + rtk_uint16 rule_info; +}; + +typedef struct ACLRULESMI{ + struct acl_rule_smi_st care_bits; + rtk_uint16 valid:1; + struct acl_rule_smi_st data_bits; + + struct acl_rule_smi_ext_st care_bits_ext; + struct acl_rule_smi_ext_st data_bits_ext; +}rtl8367c_aclrulesmi; + +struct acl_rule_st{ + rtk_uint16 active_portmsk:11; + rtk_uint16 type:3; + rtk_uint16 tag_exist:5; + rtk_uint16 field[RTL8367C_ACLRULEFIELDNO]; +}; + +typedef struct ACLRULE{ + struct acl_rule_st data_bits; + rtk_uint16 valid:1; + struct acl_rule_st care_bits; +}rtl8367c_aclrule; + + +typedef struct rtl8367c_acltemplate_s{ + rtk_uint8 field[8]; +}rtl8367c_acltemplate_t; + + +typedef struct acl_act_s{ + rtk_uint16 cvidx_cact:7; + rtk_uint16 cact:2; + rtk_uint16 svidx_sact:7; + rtk_uint16 sact:2; + + + rtk_uint16 aclmeteridx:7; + rtk_uint16 fwdpmask:11; + rtk_uint16 fwdact:2; + + rtk_uint16 pridx:7; + rtk_uint16 priact:2; + rtk_uint16 gpio_pin:4; + rtk_uint16 gpio_en:1; + rtk_uint16 aclint:1; + + rtk_uint16 cact_ext:2; + rtk_uint16 fwdact_ext:1; + rtk_uint16 tag_fmt:2; +}rtl8367c_acl_act_t; + +typedef struct acl_rule_union_s +{ + rtl8367c_aclrule aclRule; + rtl8367c_acl_act_t aclAct; + rtk_uint32 aclActCtrl; + rtk_uint32 aclNot; +}rtl8367c_acl_rule_union_t; + + +extern ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule); +extern ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule); +extern ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not); +extern ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot); +extern ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType); +extern ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType); +extern ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct); +extern ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct); +extern ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl); +extern ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *aclActCtrl); +extern ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort); +extern ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort); +extern ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid); +extern ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid); +extern ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp); +extern ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp); +extern ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity); +extern ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity); + +#endif /*_RTL8367C_ASICDRV_ACL_H_*/ + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h new file mode 100755 index 00000000..f7a46014 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Proprietary CPU-tag related function drivers + * + */ + +#ifndef _RTL8367C_ASICDRV_CPUTAG_H_ +#define _RTL8367C_ASICDRV_CPUTAG_H_ + +#include + +enum CPUTAG_INSERT_MODE +{ + CPUTAG_INSERT_TO_ALL = 0, + CPUTAG_INSERT_TO_TRAPPING, + CPUTAG_INSERT_TO_NO, + CPUTAG_INSERT_END +}; + +extern ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port); +extern ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort); +extern ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPmsk); +extern ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode); +extern ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri); +extern ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri); +extern ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 postion); +extern ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion); +extern ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode); +extern ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode); + +#endif /*#ifndef _RTL8367C_ASICDRV_CPUTAG_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h new file mode 100755 index 00000000..7639ae78 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : 802.1X related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_DOT1X_H_ +#define _RTL8367C_ASICDRV_DOT1X_H_ + +#include + +enum DOT1X_UNAUTH_BEHAV +{ + DOT1X_UNAUTH_DROP = 0, + DOT1X_UNAUTH_TRAP, + DOT1X_UNAUTH_GVLAN, + DOT1X_UNAUTH_END +}; + +extern ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth); +extern ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth); +extern ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir); +extern ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 *pOpdir); +extern ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir); +extern ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir); +extern ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc); +extern ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32 *pProc); +extern ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index); +extern ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex); +extern ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority); + + +#endif /*_RTL8367C_ASICDRV_DOT1X_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h new file mode 100755 index 00000000..b633f66f --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ethernet AV related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_EAV_H_ +#define _RTL8367C_ASICDRV_EAV_H_ + +#include + +typedef enum RTL8367C_PTP_TIME_CMD_E +{ + PTP_TIME_READ = 0, + PTP_TIME_WRITE, + PTP_TIME_INC, + PTP_TIME_DEC, + PTP_TIME_CMD_END +}RTL8367C_PTP_TIME_CMD; + +typedef enum RTL8367C_PTP_TIME_ADJ_E +{ + PTP_TIME_ADJ_INC = 0, + PTP_TIME_ADJ_DEC, + PTP_TIME_ADJ_END +}RTL8367C_PTP_TIME_ADJ; + +typedef enum RTL8367C_PTP_TIME_CTRL_E +{ + PTP_TIME_CTRL_STOP = 0, + PTP_TIME_CTRL_START, + PTP_TIME_CTRL_END +}RTL8367C_PTP_TIME_CTRL; + +typedef enum RTL8367C_PTP_INTR_IMRS_E +{ + PTP_IMRS_TX_SYNC, + PTP_IMRS_TX_DELAY_REQ, + PTP_IMRS_TX_PDELAY_REQ, + PTP_IMRS_TX_PDELAY_RESP, + PTP_IMRS_RX_SYNC, + PTP_IMRS_RX_DELAY_REQ, + PTP_IMRS_RX_PDELAY_REQ, + PTP_IMRS_RX_PDELAY_RESP, + PTP_IMRS_END, +}RTL8367C_PTP_INTR_IMRS; + + +typedef enum RTL8367C_PTP_PKT_TYPE_E +{ + PTP_PKT_TYPE_TX_SYNC, + PTP_PKT_TYPE_TX_DELAY_REQ, + PTP_PKT_TYPE_TX_PDELAY_REQ, + PTP_PKT_TYPE_TX_PDELAY_RESP, + PTP_PKT_TYPE_RX_SYNC, + PTP_PKT_TYPE_RX_DELAY_REQ, + PTP_PKT_TYPE_RX_PDELAY_REQ, + PTP_PKT_TYPE_RX_PDELAY_RESP, + PTP_PKT_TYPE_END, +}RTL8367C_PTP_PKT_TYPE; + +typedef struct rtl8367c_ptp_time_stamp_s{ + rtk_uint32 sequence_id; + rtk_uint32 second; + rtk_uint32 nano_second; +}rtl8367c_ptp_time_stamp_t; + +#define RTL8367C_PTP_INTR_MASK 0xFF + +#define RTL8367C_PTP_PORT_MASK 0x3FF + +extern ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac); +extern ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac); +extern ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag); +extern ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag); +extern ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond); +extern ret_t rtl8367c_getAsicEavSysTime(rtk_uint32* pSecond, rtk_uint32* pNanoSecond); +extern ret_t rtl8367c_setAsicEavSysTimeAdjust(rtk_uint32 type, rtk_uint32 second, rtk_uint32 nanoSecond); +extern ret_t rtl8367c_setAsicEavSysTimeCtrl(rtk_uint32 control); +extern ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl); +extern ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr); +extern ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr); +extern ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms); +extern ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims); +extern ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms); +extern ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp); + +extern ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority); +extern ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority); + +#endif /*#ifndef _RTL8367C_ASICDRV_EAV_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h new file mode 100755 index 00000000..6bedce62 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 48989 $ + * $Date: 2014-07-01 15:45:24 +0800 (¶g¤G, 01 ¤C¤ë 2014) $ + * + * Purpose : RTL8370 switch high-level API for RTL8367C + * Feature : + * + */ + +#ifndef _RTL8367C_ASICDRV_EEE_H_ +#define _RTL8367C_ASICDRV_EEE_H_ + +#include + +#define EEE_OCP_PHY_ADDR (0xA5D0) + +extern ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable); +extern ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable); + + +#endif /*_RTL8367C_ASICDRV_EEE_H_*/ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h new file mode 100755 index 00000000..ce67cdeb --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Flow control related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_FC_H_ +#define _RTL8367C_ASICDRV_FC_H_ + +#include + +#define RTL8367C_PAGE_NUMBER 0x600 + + +enum FLOW_CONTROL_TYPE +{ + FC_EGRESS = 0, + FC_INGRESS, +}; + +enum FC_JUMBO_SIZE +{ + FC_JUMBO_SIZE_3K = 0, + FC_JUMBO_SIZE_4K, + FC_JUMBO_SIZE_6K, + FC_JUMBO_SIZE_9K, + FC_JUMBO_SIZE_END, + +}; + + +extern ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select); +extern ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect); +extern ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size); +extern ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize); +extern ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall); +extern ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall); +extern ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold); +extern ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold); +extern ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); +extern ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); +extern ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); + +extern ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap); +extern ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap); +extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap); +extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap); +extern ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold); +extern ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold); +extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold); +extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold); +extern ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount); +extern ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount); +extern ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable); + +#endif /*_RTL8367C_ASICDRV_FC_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h new file mode 100755 index 00000000..38fd085d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Green ethernet related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_GREEN_H_ +#define _RTL8367C_ASICDRV_GREEN_H_ + +#include +#include + +#define PHY_POWERSAVING_REG 24 + +extern ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype); +extern ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype); +extern ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage); +extern ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator); +extern ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port); +extern ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green); +extern ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green); +extern ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable); +#endif /*#ifndef _RTL8367C_ASICDRV_GREEN_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h new file mode 100755 index 00000000..f4f9bb37 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Field selector related functions + * + */ + +#ifndef _RTL8367C_ASICDRV__HSB_H_ +#define _RTL8367C_ASICDRV__HSB_H_ + +#include + +#define RTL8367C_FIELDSEL_FORMAT_NUMBER (16) +#define RTL8367C_FIELDSEL_MAX_OFFSET (255) + +enum FIELDSEL_FORMAT_FORMAT +{ + FIELDSEL_FORMAT_DEFAULT = 0, + FIELDSEL_FORMAT_RAW, + FIELDSEL_FORMAT_LLC, + FIELDSEL_FORMAT_IPV4, + FIELDSEL_FORMAT_ARP, + FIELDSEL_FORMAT_IPV6, + FIELDSEL_FORMAT_IPPAYLOAD, + FIELDSEL_FORMAT_L4PAYLOAD, + FIELDSEL_FORMAT_END +}; + +extern ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset); +extern ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset); + +#endif /*_RTL8367C_ASICDRV__HSB_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h new file mode 100755 index 00000000..d5b095a0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 38651 $ + * $Date: 2016-02-27 14:32:56 +0800 (©P¤T, 17 ¥|¤ë 2016) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : I2C related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_I2C_H_ +#define _RTL8367C_ASICDRV_I2C_H_ +#include +#include + + +#define TIMEROUT_FOR_MICROSEMI (0x400) + +#define GPIO_INPUT 1 +#define GPIO_OUTPUT 2 + +extern ret_t rtl8367c_setAsicI2C_checkBusIdle(void); +extern ret_t rtl8367c_setAsicI2CStartCmd(void); +extern ret_t rtl8367c_setAsicI2CStopCmd(void); +extern ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar); +extern ret_t rtl8367c_setAsicI2CcheckRxAck(void); +extern ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue); +extern ret_t rtl8367c_setAsicI2CTxAckCmd(void); +extern ret_t rtl8367c_setAsicI2CTxNoAckCmd(void); +extern ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void); +extern ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID); +extern ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID); + + + + + +#endif /*#ifndef _RTL8367C_ASICDRV_I2C_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h new file mode 100755 index 00000000..b879b6b5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : IGMP related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_IGMP_H_ +#define _RTL8367C_ASICDRV_IGMP_H_ + +/****************************************************************/ +/* Header File inclusion */ +/****************************************************************/ +#include + +#define RTL8367C_MAX_LEAVE_TIMER (7) +#define RTL8367C_MAX_QUERY_INT (0xFFFF) +#define RTL8367C_MAX_ROB_VAR (7) + +#define RTL8367C_IGMP_GOUP_NO (256) +#define RTL8367C_IGMP_MAX_GOUP (0xFF) +#define RTL8367C_IGMP_GRP_BLEN (3) +#define RTL8367C_ROUTER_PORT_INVALID (0xF) + +enum RTL8367C_IGMPTABLE_FULL_OP +{ + TABLE_FULL_FORWARD = 0, + TABLE_FULL_DROP, + TABLE_FULL_TRAP, + TABLE_FULL_OP_END +}; + +enum RTL8367C_CRC_ERR_OP +{ + CRC_ERR_DROP = 0, + CRC_ERR_TRAP, + CRC_ERR_FORWARD, + CRC_ERR_OP_END +}; + +enum RTL8367C_IGMP_MLD_PROTOCOL_OP +{ + PROTOCOL_OP_ASIC = 0, + PROTOCOL_OP_FLOOD, + PROTOCOL_OP_TRAP, + PROTOCOL_OP_DROP, + PROTOCOL_OP_END +}; + +enum RTL8367C_IGMP_MLD_BYPASS_GROUP +{ + BYPASS_224_0_0_X = 0, + BYPASS_224_0_1_X, + BYPASS_239_255_255_X, + BYPASS_IPV6_00XX, + BYPASS_GROUP_END +}; + +typedef struct +{ + rtk_uint32 p0_timer; + rtk_uint32 p1_timer; + rtk_uint32 p2_timer; + rtk_uint32 p3_timer; + rtk_uint32 p4_timer; + rtk_uint32 p5_timer; + rtk_uint32 p6_timer; + rtk_uint32 p7_timer; + rtk_uint32 p8_timer; + rtk_uint32 p9_timer; + rtk_uint32 p10_timer; + rtk_uint32 report_supp_flag; + +}rtl8367c_igmpgroup; +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * This program is the proprietary software of Realtek Semiconductor + * Corporation and/or its licensors, and only be used, duplicated, + * modified or distributed under the authorized license from Realtek. + * + * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER + * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : IGMP related functions + * + */ +#include + +ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled); +ret_t rtl8367c_getAsicIgmp(rtk_uint32 *pEnabled); +ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled ); +ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *pEnabled ); +ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation); +ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *pOperation); +ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation); +ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *pOperation); +ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled); +ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *pEnabled); +ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer); +ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pLeave_timer); +ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval); +ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pInterval); +ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var); +ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *pRob_var); +ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk); +ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pMsk); +ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk); +ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk); +ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *pPort, rtk_uint32 *pTimer); +ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *pPort, rtk_uint32 *pTimer); +ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled); +ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *pReport_supp_enabled, rtk_uint32 *pLeave_supp_enabled); +ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query); +ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *pAllow_query); +ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report); +ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *pAllow_report); +ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave); +ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *pAllow_leave); +ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp); +ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *pAllow_mrp); +ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata); +ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *pAllow_mcdata); +ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op); +ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv1_op); +ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op); +ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv2_op); +ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op); +ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv3_op); +ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op); +ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *pMldv1_op); +ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op); +ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *pMldv2_op); +ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group); +ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *pMax_group); +ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *pCurrent_group); +ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *pValid, rtl8367c_igmpgroup *pGrp); +ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled); +ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *pEnabled); +ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood); +ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood); +ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop); +ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop); +ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass); +ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass); +ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky); +ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky); +ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky); +ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky); +ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled); +ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled); + +#endif /*#ifndef _RTL8367C_ASICDRV_IGMP_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h new file mode 100755 index 00000000..10f35453 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ingress bandwidth control related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_INBWCTRL_H_ +#define _RTL8367C_ASICDRV_INBWCTRL_H_ + +#include + +extern ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC); +extern ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC ); +extern ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled); + + +#endif /*_RTL8367C_ASICDRV_INBWCTRL_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h new file mode 100755 index 00000000..8b78014a --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Interrupt related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_ +#define _RTL8367C_ASICDRV_INTERRUPT_H_ + +#include + +typedef enum RTL8367C_INTR_IMRS_E +{ + IMRS_LINK_CHANGE, + IMRS_METER_EXCEED, + IMRS_L2_LEARN, + IMRS_SPEED_CHANGE, + IMRS_SPECIAL_CONGESTION, + IMRS_GREEN_FEATURE, + IMRS_LOOP_DETECTION, + IMRS_8051, + IMRS_CABLE_DIAG, + IMRS_ACL, + IMRS_RESERVED, /* Unused */ + IMRS_SLIENT, + IMRS_END, +}RTL8367C_INTR_IMRS; + +typedef enum RTL8367C_INTR_INDICATOR_E +{ + INTRST_L2_LEARN = 0, + INTRST_SPEED_CHANGE, + INTRST_SPECIAL_CONGESTION, + INTRST_PORT_LINKDOWN, + INTRST_PORT_LINKUP, + INTRST_METER0_15, + INTRST_METER16_31, + INTRST_RLDP_LOOPED, + INTRST_RLDP_RELEASED, + INTRST_SYS_LEARN, + INTRST_END, +}RTL8367C_INTR_INDICATOR; + +extern ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity); +extern ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity); +extern ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr); +extern ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr); +extern ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims); +extern ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms); +extern ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status); +extern ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus); + + +#endif /*#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h new file mode 100755 index 00000000..a7f8e206 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LED related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_LED_H_ +#define _RTL8367C_ASICDRV_LED_H_ + +#include + +#define RTL8367C_LEDGROUPNO 3 +#define RTL8367C_LEDGROUPMASK 0x7 +#define RTL8367C_LED_FORCE_MODE_BASE RTL8367C_REG_CPU_FORCE_LED0_CFG0 +#define RTL8367C_LED_FORCE_CTRL RTL8367C_REG_CPU_FORCE_LED_CFG + +enum RTL8367C_LEDOP{ + + LEDOP_SCAN0=0, + LEDOP_SCAN1, + LEDOP_PARALLEL, + LEDOP_SERIAL, + LEDOP_END, +}; + +enum RTL8367C_LEDSERACT{ + + LEDSERACT_HIGH=0, + LEDSERACT_LOW, + LEDSERACT_MAX, +}; + +enum RTL8367C_LEDSER{ + + LEDSER_16G=0, + LEDSER_8G, + LEDSER_MAX, +}; + +enum RTL8367C_LEDCONF{ + + LEDCONF_LEDOFF=0, + LEDCONF_DUPCOL, + LEDCONF_LINK_ACT, + LEDCONF_SPD1000, + LEDCONF_SPD100, + LEDCONF_SPD10, + LEDCONF_SPD1000ACT, + LEDCONF_SPD100ACT, + LEDCONF_SPD10ACT, + LEDCONF_SPD10010ACT, + LEDCONF_LOOPDETECT, + LEDCONF_EEE, + LEDCONF_LINKRX, + LEDCONF_LINKTX, + LEDCONF_MASTER, + LEDCONF_ACT, + LEDCONF_END +}; + +enum RTL8367C_LEDBLINKRATE{ + + LEDBLINKRATE_32MS=0, + LEDBLINKRATE_64MS, + LEDBLINKRATE_128MS, + LEDBLINKRATE_256MS, + LEDBLINKRATE_512MS, + LEDBLINKRATE_1024MS, + LEDBLINKRATE_48MS, + LEDBLINKRATE_96MS, + LEDBLINKRATE_END, +}; + +enum RTL8367C_LEDFORCEMODE{ + + LEDFORCEMODE_NORMAL=0, + LEDFORCEMODE_BLINK, + LEDFORCEMODE_OFF, + LEDFORCEMODE_ON, + LEDFORCEMODE_END, +}; + +enum RTL8367C_LEDFORCERATE{ + + LEDFORCERATE_512MS=0, + LEDFORCERATE_1024MS, + LEDFORCERATE_2048MS, + LEDFORCERATE_NORMAL, + LEDFORCERATE_END, + +}; + +enum RTL8367C_LEDMODE +{ + RTL8367C_LED_MODE_0 = 0, + RTL8367C_LED_MODE_1, + RTL8367C_LED_MODE_2, + RTL8367C_LED_MODE_3, + RTL8367C_LED_MODE_END +}; + +extern ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config); +extern ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig); +extern ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate); +extern ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate); +extern ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate); +extern ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate); +extern ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask); +extern ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode); +extern ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode); +extern ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode); +extern ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled); +extern ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask); +extern ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask); + + +#endif /*#ifndef _RTL8367C_ASICDRV_LED_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h new file mode 100755 index 00000000..c94ea076 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LUT related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_LUT_H_ +#define _RTL8367C_ASICDRV_LUT_H_ + +#include + +#define RTL8367C_LUT_AGETIMERMAX (7) +#define RTL8367C_LUT_AGESPEEDMAX (3) +#define RTL8367C_LUT_LEARNLIMITMAX (0x1040) +#define RTL8367C_LUT_ADDRMAX (0x103F) +#define RTL8367C_LUT_IPMCGRP_TABLE_MAX (0x3F) +#define RTL8367C_LUT_ENTRY_SIZE (6) +#define RTL8367C_LUT_BUSY_CHECK_NO (10) + +#define RTL8367C_LUT_TABLE_SIZE (6) + +enum RTL8367C_LUTHASHMETHOD{ + + LUTHASHMETHOD_SVL=0, + LUTHASHMETHOD_IVL, + LUTHASHMETHOD_END, +}; + + +enum RTL8367C_LRNOVERACT{ + + LRNOVERACT_FORWARD=0, + LRNOVERACT_DROP, + LRNOVERACT_TRAP, + LRNOVERACT_END, +}; + +enum RTL8367C_LUTREADMETHOD{ + + LUTREADMETHOD_MAC =0, + LUTREADMETHOD_ADDRESS, + LUTREADMETHOD_NEXT_ADDRESS, + LUTREADMETHOD_NEXT_L2UC, + LUTREADMETHOD_NEXT_L2MC, + LUTREADMETHOD_NEXT_L3MC, + LUTREADMETHOD_NEXT_L2L3MC, + LUTREADMETHOD_NEXT_L2UCSPA, +}; + +enum RTL8367C_FLUSHMODE +{ + FLUSHMDOE_PORT = 0, + FLUSHMDOE_VID, + FLUSHMDOE_FID, + FLUSHMDOE_END, +}; + +enum RTL8367C_FLUSHTYPE +{ + FLUSHTYPE_DYNAMIC = 0, + FLUSHTYPE_BOTH, + FLUSHTYPE_END, +}; + + +typedef struct LUTTABLE{ + + ipaddr_t sip; + ipaddr_t dip; + ether_addr_t mac; + rtk_uint16 ivl_svl:1; + rtk_uint16 cvid_fid:12; + rtk_uint16 fid:4; + rtk_uint16 efid:3; + + rtk_uint16 nosalearn:1; + rtk_uint16 da_block:1; + rtk_uint16 sa_block:1; + rtk_uint16 auth:1; + rtk_uint16 lut_pri:3; + rtk_uint16 sa_en:1; + rtk_uint16 fwd_en:1; + rtk_uint16 mbr:11; + rtk_uint16 spa:4; + rtk_uint16 age:3; + rtk_uint16 l3lookup:1; + rtk_uint16 igmp_asic:1; + rtk_uint16 igmpidx:8; + + rtk_uint16 lookup_hit:1; + rtk_uint16 lookup_busy:1; + rtk_uint16 address:13; + + rtk_uint16 l3vidlookup:1; + rtk_uint16 l3_vid:12; + + rtk_uint16 wait_time; + +}rtl8367c_luttb; + +extern ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed); +extern ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed); +extern ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled); +extern ret_t rtl8367c_getAsicLutCamType(rtk_uint32* pType); +extern ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number); +extern ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber); +extern ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number); +extern ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber); +extern ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action); +extern ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction); +extern ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action); +extern ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction); +extern ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table); +extern ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table); +extern ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber); +extern ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type); +extern ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType); +extern ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type); +extern ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType); +extern ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid); +extern ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid); +extern ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid); +extern ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid); +extern ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled); +extern ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled); +extern ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid); +extern ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid); +extern ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable); +extern ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicLutFlushAll(void); +extern ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus); +extern ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable); +extern ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable); + +#endif /*_RTL8367C_ASICDRV_LUT_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h new file mode 100755 index 00000000..ba761a94 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Shared meter related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_METER_H_ +#define _RTL8367C_ASICDRV_METER_H_ + +#include + + +extern ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg); +extern ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg); +extern ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbThreshold); +extern ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbThreshold); +extern ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type); +extern ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType); +extern ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index); +extern ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus); + +#endif /*_RTL8367C_ASICDRV_FC_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h new file mode 100755 index 00000000..ca46e0f4 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : MIB related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_MIB_H_ +#define _RTL8367C_ASICDRV_MIB_H_ + +#include + +#define RTL8367C_MIB_PORT_OFFSET (0x7C) +#define RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET (0x420) + +#define RTL8367C_MAX_LOG_CNT_NUM (32) +#define RTL8367C_MIB_MAX_LOG_CNT_IDX (RTL8367C_MAX_LOG_CNT_NUM - 1) +#define RTL8367C_MIB_LOG_CNT_OFFSET (0x3E0) +#define RTL8367C_MIB_MAX_LOG_MODE_IDX (16-1) + +typedef enum RTL8367C_MIBCOUNTER_E{ + + /* RX */ + ifInOctets = 0, + + dot3StatsFCSErrors, + dot3StatsSymbolErrors, + dot3InPauseFrames, + dot3ControlInUnknownOpcodes, + + etherStatsFragments, + etherStatsJabbers, + ifInUcastPkts, + etherStatsDropEvents, + + ifInMulticastPkts, + ifInBroadcastPkts, + inMldChecksumError, + inIgmpChecksumError, + inMldSpecificQuery, + inMldGeneralQuery, + inIgmpSpecificQuery, + inIgmpGeneralQuery, + inMldLeaves, + inIgmpLeaves, + + /* TX/RX */ + etherStatsOctets, + + etherStatsUnderSizePkts, + etherOversizeStats, + etherStatsPkts64Octets, + etherStatsPkts65to127Octets, + etherStatsPkts128to255Octets, + etherStatsPkts256to511Octets, + etherStatsPkts512to1023Octets, + etherStatsPkts1024to1518Octets, + + /* TX */ + ifOutOctets, + + dot3StatsSingleCollisionFrames, + dot3StatMultipleCollisionFrames, + dot3sDeferredTransmissions, + dot3StatsLateCollisions, + etherStatsCollisions, + dot3StatsExcessiveCollisions, + dot3OutPauseFrames, + ifOutDiscards, + + /* ALE */ + dot1dTpPortInDiscards, + ifOutUcastPkts, + ifOutMulticastPkts, + ifOutBroadcastPkts, + outOampduPkts, + inOampduPkts, + + inIgmpJoinsSuccess, + inIgmpJoinsFail, + inMldJoinsSuccess, + inMldJoinsFail, + inReportSuppressionDrop, + inLeaveSuppressionDrop, + outIgmpReports, + outIgmpLeaves, + outIgmpGeneralQuery, + outIgmpSpecificQuery, + outMldReports, + outMldLeaves, + outMldGeneralQuery, + outMldSpecificQuery, + inKnownMulticastPkts, + + /*Device only */ + dot1dTpLearnedEntryDiscards, + RTL8367C_MIBS_NUMBER, + +}RTL8367C_MIBCOUNTER; + + +extern ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 pmask); +extern ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port,RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter); +extern ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter); +extern ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask); + +extern ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value); +extern ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value); + +extern ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer); +extern ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer); +extern ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type); +extern ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType); +extern ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index); +extern ret_t rtl8367c_setAsicMIBsLength(rtk_uint32 txLengthMode, rtk_uint32 rxLengthMode); +extern ret_t rtl8367c_getAsicMIBsLength(rtk_uint32 *pTxLengthMode, rtk_uint32 *pRxLengthMode); + +#endif /*#ifndef _RTL8367C_ASICDRV_MIB_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h new file mode 100755 index 00000000..23b788d7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port mirror related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_MIRROR_H_ +#define _RTL8367C_ASICDRV_MIRROR_H_ + +#include + +extern ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor); +extern ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor); +extern ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicPortMirrorPriority(rtk_uint32* pPriority); +extern ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask); +extern ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask); +extern ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror); +extern ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror); + +#endif /*#ifndef _RTL8367C_ASICDRV_MIRROR_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h new file mode 100755 index 00000000..c666a7b5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Miscellaneous functions + * + */ + +#ifndef _RTL8367C_ASICDRV_MISC_H_ +#define _RTL8367C_ASICDRV_MISC_H_ + +#include + +extern ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac); +extern ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac); +extern ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo); +extern ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength); +extern ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength); +extern ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId); +extern ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId); + +#endif /*_RTL8367C_ASICDRV_MISC_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h new file mode 100755 index 00000000..c09dc769 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : OAM related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_OAM_H_ +#define _RTL8367C_ASICDRV_OAM_H_ + +#include + +enum OAMPARACT +{ + OAM_PARFWD = 0, + OAM_PARLB, + OAM_PARDISCARD, + OAM_PARFWDCPU +}; + +enum OAMMULACT +{ + OAM_MULFWD = 0, + OAM_MULDISCARD, + OAM_MULCPU +}; + +extern ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser); +extern ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser); +extern ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer); +extern ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer); +extern ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority); +extern ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled); +#endif /*_RTL8367C_ASICDRV_OAM_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h new file mode 100755 index 00000000..e993d6ed --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : PHY related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_PHY_H_ +#define _RTL8367C_ASICDRV_PHY_H_ + +#include + +#define RTL8367C_PHY_REGNOMAX 0x1F +#define RTL8367C_PHY_EXTERNALMAX 0x7 + +#define RTL8367C_PHY_BASE 0x2000 +#define RTL8367C_PHY_EXT_BASE 0xA000 + +#define RTL8367C_PHY_OFFSET 5 +#define RTL8367C_PHY_EXT_OFFSET 9 + +#define RTL8367C_PHY_PAGE_ADDRESS 31 + + +extern ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 regData ); +extern ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32* pRegData ); +extern ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ); +extern ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ); +extern ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value); +extern ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value); + +#endif /*#ifndef _RTL8367C_ASICDRV_PHY_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h new file mode 100755 index 00000000..ad99d856 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76333 $ + * $Date: 2017-03-09 09:33:15 +0800 (¶g¥|, 09 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port security related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_PORTSECURITY_H_ +#define _RTL8367C_ASICDRV_PORTSECURITY_H_ + +#include +#include +#include + +/****************************************************************/ +/* Type Definition */ +/****************************************************************/ + +#define RTL8367C_MAC7 7 +#define RTL8367C_EXTNO 3 + +#define RTL8367C_RTCT_PAGE (11) +#define RTL8367C_RTCT_RESULT_A_REG (27) +#define RTL8367C_RTCT_RESULT_B_REG (28) +#define RTL8367C_RTCT_RESULT_C_REG (29) +#define RTL8367C_RTCT_RESULT_D_REG (30) +#define RTL8367C_RTCT_STATUS_REG (26) + +enum L2_SECURITY_BEHAVE +{ + L2_BEHAVE_FLOODING = 0, + L2_BEHAVE_DROP, + L2_BEHAVE_TRAP, + L2_BEHAVE_END +}; + +enum L2_UNDA_BEHAVE +{ + L2_UNDA_BEHAVE_FLOODING_PMASK = 0, + L2_UNDA_BEHAVE_DROP, + L2_UNDA_BEHAVE_TRAP, + L2_UNDA_BEHAVE_FLOODING, + L2_UNDA_BEHAVE_END +}; + +enum L2_SECURITY_SA_BEHAVE +{ + L2_BEHAVE_SA_FLOODING = 0, + L2_BEHAVE_SA_DROP, + L2_BEHAVE_SA_TRAP, + L2_BEHAVE_SA_COPY28051, + L2_BEHAVE_SA_END +}; + +/* enum for port current link speed */ +enum SPEEDMODE +{ + SPD_10M = 0, + SPD_100M, + SPD_1000M, + SPD_2500M +}; + +/* enum for mac link mode */ +enum LINKMODE +{ + MAC_NORMAL = 0, + MAC_FORCE, +}; + +/* enum for port current link duplex mode */ +enum DUPLEXMODE +{ + HALF_DUPLEX = 0, + FULL_DUPLEX +}; + +/* enum for port current MST mode */ +enum MSTMODE +{ + SLAVE_MODE= 0, + MASTER_MODE +}; + + +enum EXTMODE +{ + EXT_DISABLE = 0, + EXT_RGMII, + EXT_MII_MAC, + EXT_MII_PHY, + EXT_TMII_MAC, + EXT_TMII_PHY, + EXT_GMII, + EXT_RMII_MAC, + EXT_RMII_PHY, + EXT_SGMII, + EXT_HSGMII, + EXT_1000X_100FX, + EXT_1000X, + EXT_100FX, + EXT_RGMII_2, + EXT_MII_MAC_2, + EXT_MII_PHY_2, + EXT_TMII_MAC_2, + EXT_TMII_PHY_2, + EXT_RMII_MAC_2, + EXT_RMII_PHY_2, + EXT_END +}; + +enum DOSTYPE +{ + DOS_DAEQSA = 0, + DOS_LANDATTACKS, + DOS_BLATATTACKS, + DOS_SYNFINSCAN, + DOS_XMASCAN, + DOS_NULLSCAN, + DOS_SYN1024, + DOS_TCPSHORTHDR, + DOS_TCPFRAGERROR, + DOS_ICMPFRAGMENT, + DOS_END, + +}; + +typedef struct rtl8367c_port_ability_s{ + rtk_uint16 forcemode; + rtk_uint16 mstfault; + rtk_uint16 mstmode; + rtk_uint16 nway; + rtk_uint16 txpause; + rtk_uint16 rxpause; + rtk_uint16 link; + rtk_uint16 duplex; + rtk_uint16 speed; +}rtl8367c_port_ability_t; + +typedef struct rtl8367c_port_status_s{ + + rtk_uint16 lpi1000; + rtk_uint16 lpi100; + rtk_uint16 mstfault; + rtk_uint16 mstmode; + rtk_uint16 nway; + rtk_uint16 txpause; + rtk_uint16 rxpause; + rtk_uint16 link; + rtk_uint16 duplex; + rtk_uint16 speed; + +}rtl8367c_port_status_t; + +typedef struct rtct_result_s +{ + rtk_uint32 channelAShort; + rtk_uint32 channelBShort; + rtk_uint32 channelCShort; + rtk_uint32 channelDShort; + + rtk_uint32 channelAOpen; + rtk_uint32 channelBOpen; + rtk_uint32 channelCOpen; + rtk_uint32 channelDOpen; + + rtk_uint32 channelAMismatch; + rtk_uint32 channelBMismatch; + rtk_uint32 channelCMismatch; + rtk_uint32 channelDMismatch; + + rtk_uint32 channelALinedriver; + rtk_uint32 channelBLinedriver; + rtk_uint32 channelCLinedriver; + rtk_uint32 channelDLinedriver; + + rtk_uint32 channelALen; + rtk_uint32 channelBLen; + rtk_uint32 channelCLen; + rtk_uint32 channelDLen; +} rtl8367c_port_rtct_result_t; + + +/****************************************************************/ +/* Driver Proto Type Definition */ +/****************************************************************/ +extern ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior); +extern ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior); +extern ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior); +extern ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior); +extern ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior); +extern ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior); +extern ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 block); +extern ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 *pBlock); +extern ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus); +extern ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); +extern ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode); +extern ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode); +extern ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop); +extern ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop); +extern ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable); +extern ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable); +extern ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask); +extern ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult); +extern ret_t rtl8367c_sdsReset(rtk_uint32 id); +extern ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink); +extern ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state); +extern ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState); + +#endif /*_RTL8367C_ASICDRV_PORTSECURITY_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h new file mode 100755 index 00000000..e23d88e8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port isolation related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_PORTISOLATION_H_ +#define _RTL8367C_ASICDRV_PORTISOLATION_H_ + +#include + +extern ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask); +extern ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask); +extern ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid); +extern ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid); + +#endif /*_RTL8367C_ASICDRV_PORTISOLATION_H_*/ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h new file mode 100755 index 00000000..26042bfa --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Qos related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_QOS_H_ +#define _RTL8367C_ASICDRV_QOS_H_ + +#include + +#define RTL8367C_DECISIONPRIMAX 0xFF + +/* enum Priority Selection Types */ +enum PRIDECISION +{ + PRIDEC_PORT = 0, + PRIDEC_ACL, + PRIDEC_DSCP, + PRIDEC_1Q, + PRIDEC_1AD, + PRIDEC_CVLAN, + PRIDEC_DA, + PRIDEC_SA, + PRIDEC_END, +}; + +/* enum Priority Selection Index */ +enum RTL8367C_PRIDEC_TABLE +{ + PRIDEC_IDX0 = 0, + PRIDEC_IDX1, + PRIDEC_IDX_END, +}; + +enum RTL8367C_DOT1P_PRISEL +{ + DOT1P_PRISEL_USER = 0, + DOT1P_PRISEL_TAG, + DOT1P_PRISEL_END +}; + +enum RTL8367C_DSCP_PRISEL +{ + DSCP_PRISEL_INTERNAL = 0, + DSCP_PRISEL_DSCP, + DSCP_PRISEL_USER , + DSCP_PRISEL_END +}; + + +extern ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ); +extern ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ); +extern ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type); +extern ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType); +extern ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ); +extern ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ); + +extern ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ); +extern ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ); +extern ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ); +extern ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ); +extern ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ); +extern ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ); +extern ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri); +extern ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri); +extern ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32 qid ); +extern ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32* pQid); +extern ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 qnum ); +extern ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pQnum ); + +extern ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type); +extern ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType); +extern ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp); +extern ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp); + +extern ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ); +extern ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ); + +#endif /*#ifndef _RTL8367C_ASICDRV_QOS_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h new file mode 100755 index 00000000..cde970b6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RLDP related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_RLDP_H_ +#define _RTL8367C_ASICDRV_RLDP_H_ + +#include +#include + +extern ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src); +extern ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc); +extern ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); +extern ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); +extern ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); +extern ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); +extern ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed); +extern ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed); +extern ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask); + + +extern ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber); +extern ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair); +extern ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled); + +extern ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask); + +extern ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask); + +extern ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled); + +#endif /*_RTL8367C_ASICDRV_RLDP_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h new file mode 100755 index 00000000..10c70754 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 64716 $ + * $Date: 2015-12-31 16:31:55 +0800 (¶g¥|, 31 ¤Q¤G¤ë 2015) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RMA related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_RMA_H_ +#define _RTL8367C_ASICDRV_RMA_H_ + +#include + +#define RTL8367C_RMAMAX 0x2F + +enum RTL8367C_RMAOP +{ + RMAOP_FORWARD = 0, + RMAOP_TRAP_TO_CPU, + RMAOP_DROP, + RMAOP_FORWARD_EXCLUDE_CPU, + RMAOP_END +}; + + +typedef struct rtl8367c_rma_s{ + + rtk_uint16 operation; + rtk_uint16 discard_storm_filter; + rtk_uint16 trap_priority; + rtk_uint16 keep_format; + rtk_uint16 vlan_leaky; + rtk_uint16 portiso_leaky; + +}rtl8367c_rma_t; + + +extern ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg); +extern ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg); + +#endif /*#ifndef _RTL8367C_ASICDRV_RMA_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h new file mode 100755 index 00000000..919a4ca6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Packet Scheduling related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_SCHEDULING_H_ +#define _RTL8367C_ASICDRV_SCHEDULING_H_ + +#include + +#define RTL8367C_QWEIGHTMAX 0x7F +#define RTL8367C_PORT_QUEUE_METER_INDEX_MAX 7 + +/* enum for queue type */ +enum QUEUETYPE +{ + QTYPE_STRICT = 0, + QTYPE_WFQ, +}; +extern ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token); +extern ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token); +extern ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx); +extern ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx); +extern ret_t rtl8367c_setAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx); +extern ret_t rtl8367c_getAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *ppridx); +extern ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable); +extern ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable); +extern ret_t rtl8367c_setAsicPprEnable(rtk_uint32 port, rtk_uint32 pprEnable); +extern ret_t rtl8367c_getAsicPprEnable(rtk_uint32 port, rtk_uint32 *pprEnable); + +extern ret_t rtl8367c_setAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 weight ); +extern ret_t rtl8367c_getAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 *weight ); +extern ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize); +extern ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize); + +extern ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType); +extern ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType); +extern ret_t rtl8367c_setAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx, rtk_uint32 apridx ); +extern ret_t rtl8367c_getAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* ppridx, rtk_uint32* apridx ); +extern ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate); +extern ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate); +extern ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg); +extern ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg); + +#endif /*_RTL8367C_ASICDRV_SCHEDULING_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h new file mode 100755 index 00000000..3865b522 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Storm control filtering related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_STORM_H_ +#define _RTL8367C_ASICDRV_STORM_H_ + +#include + +extern ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter); +extern ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask); + + +#endif /*_RTL8367C_ASICDRV_STORM_H_*/ + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h new file mode 100755 index 00000000..5a6a4a83 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : SVLAN related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_SVLAN_H_ +#define _RTL8367C_ASICDRV_SVLAN_H_ + +#include + +#define RTL8367C_C2SIDXNO 128 +#define RTL8367C_C2SIDXMAX (RTL8367C_C2SIDXNO-1) +#define RTL8367C_MC2SIDXNO 32 +#define RTL8367C_MC2SIDXMAX (RTL8367C_MC2SIDXNO-1) +#define RTL8367C_SP2CIDXNO 128 +#define RTL8367C_SP2CMAX (RTL8367C_SP2CIDXNO-1) + +#define RTL8367C_SVLAN_MEMCONF_LEN 4 +#define RTL8367C_SVLAN_MC2S_LEN 5 +#define RTL8367C_SVLAN_SP2C_LEN 2 + +enum RTL8367C_SPRISEL +{ + SPRISEL_INTERNALPRI = 0, + SPRISEL_CTAGPRI, + SPRISEL_VSPRI, + SPRISEL_PBPRI, + SPRISEL_END +}; + +enum RTL8367C_SUNACCEPT +{ + SUNACCEPT_DROP = 0, + SUNACCEPT_TRAP, + SUNACCEPT_SVLAN, + SUNACCEPT_END +}; + +enum RTL8367C_SVLAN_MC2S_MODE +{ + SVLAN_MC2S_MODE_MAC = 0, + SVLAN_MC2S_MODE_IP, + SVLAN_MC2S_MODE_END +}; + + +typedef struct rtl8367c_svlan_memconf_s{ + + rtk_uint16 vs_member:11; + rtk_uint16 vs_untag:11; + + rtk_uint16 vs_fid_msti:4; + rtk_uint16 vs_priority:3; + rtk_uint16 vs_force_fid:1; + rtk_uint16 reserved:8; + + rtk_uint16 vs_svid:12; + rtk_uint16 vs_efiden:1; + rtk_uint16 vs_efid:3; + + +}rtl8367c_svlan_memconf_t; + + +typedef struct rtl8367c_svlan_mc2s_s{ + + rtk_uint16 valid:1; + rtk_uint16 format:1; + rtk_uint16 svidx:6; + rtk_uint32 sdata; + rtk_uint32 smask; +}rtl8367c_svlan_mc2s_t; + + +typedef struct rtl8367c_svlan_s2c_s{ + + rtk_uint16 valid:1; + rtk_uint16 svidx:6; + rtk_uint16 dstport:4; + rtk_uint32 vid:12; +}rtl8367c_svlan_s2c_t; + +extern ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority); +extern ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index); +extern ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex); + +extern ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); +extern ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); + +extern ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel); +extern ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel); +extern ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType); +extern ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType); +extern ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask); +extern ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask); +extern ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx); +extern ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx); +extern ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); +extern ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); +extern ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); +extern ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); +extern ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index); +extern ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex); +extern ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index); +extern ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex); +extern ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type); +extern ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType); + + +#endif /*#ifndef _RTL8367C_ASICDRV_SVLAN_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h new file mode 100755 index 00000000..2e3a6828 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port trunking related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_TRUNKING_H_ +#define _RTL8367C_ASICDRV_TRUNKING_H_ + +#include + +#define RTL8367C_MAX_TRUNK_GID (2) +#define RTL8367C_TRUNKING_PORTNO (4) +#define RTL8367C_TRUNKING1_PORTN0 (2) +#define RTL8367C_TRUNKING_HASHVALUE_MAX (15) + +extern ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask); +extern ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel); +extern ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel); + +extern ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* pPortmask); + +extern ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode); +extern ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode); +extern ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId); +extern ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId); +extern ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId); +extern ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId); + +#endif /*_RTL8367C_ASICDRV_TRUNKING_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h new file mode 100755 index 00000000..d142d25c --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Unkown multicast related functions + * + */ + +#ifndef _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ +#define _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ + +#include + +enum L2_UNKOWN_MULTICAST_BEHAVE +{ + L2_UNKOWN_MULTICAST_FLOODING = 0, + L2_UNKOWN_MULTICAST_DROP, + L2_UNKOWN_MULTICAST_TRAP, + L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA, + L2_UNKOWN_MULTICAST_END +}; + +enum L3_UNKOWN_MULTICAST_BEHAVE +{ + L3_UNKOWN_MULTICAST_FLOODING = 0, + L3_UNKOWN_MULTICAST_DROP, + L3_UNKOWN_MULTICAST_TRAP, + L3_UNKOWN_MULTICAST_ROUTER, + L3_UNKOWN_MULTICAST_END +}; + +enum MULTICASTTYPE{ + MULTICAST_TYPE_IPV4 = 0, + MULTICAST_TYPE_IPV6, + MULTICAST_TYPE_L2, + MULTICAST_TYPE_END +}; + +extern ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); +extern ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); +extern ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); +extern ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); +extern ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); +extern ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); +extern ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority); +extern ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority); + +#endif /*_RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_*/ + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h new file mode 100755 index 00000000..61848650 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : VLAN related functions + * + */ + + +#ifndef _RTL8367C_ASICDRV_VLAN_H_ +#define _RTL8367C_ASICDRV_VLAN_H_ + +/****************************************************************/ +/* Header File inclusion */ +/****************************************************************/ +#include + +/****************************************************************/ +/* Constant Definition */ +/****************************************************************/ +#define RTL8367C_PROTOVLAN_GIDX_MAX 3 +#define RTL8367C_PROTOVLAN_GROUPNO 4 + +#define RTL8367C_VLAN_BUSY_CHECK_NO (10) + +#define RTL8367C_VLAN_MBRCFG_LEN (4) +#define RTL8367C_VLAN_4KTABLE_LEN (3) + +/****************************************************************/ +/* Type Definition */ +/****************************************************************/ +typedef struct VLANCONFIGUSER +{ + rtk_uint16 evid; + rtk_uint16 mbr; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; +}rtl8367c_vlanconfiguser; + +typedef struct USER_VLANTABLE{ + + rtk_uint16 vid; + rtk_uint16 mbr; + rtk_uint16 untag; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; + rtk_uint16 ivl_svl; + +}rtl8367c_user_vlan4kentry; + +typedef enum +{ + FRAME_TYPE_BOTH = 0, + FRAME_TYPE_TAGGED_ONLY, + FRAME_TYPE_UNTAGGED_ONLY, + FRAME_TYPE_MAX_BOUND +} rtl8367c_accframetype; + +typedef enum +{ + EG_TAG_MODE_ORI = 0, + EG_TAG_MODE_KEEP, + EG_TAG_MODE_PRI_TAG, + EG_TAG_MODE_REAL_KEEP, + EG_TAG_MODE_END +} rtl8367c_egtagmode; + +typedef enum +{ + PPVLAN_FRAME_TYPE_ETHERNET = 0, + PPVLAN_FRAME_TYPE_LLC, + PPVLAN_FRAME_TYPE_RFC1042, + PPVLAN_FRAME_TYPE_END +} rtl8367c_provlan_frametype; + +enum RTL8367C_STPST +{ + STPST_DISABLED = 0, + STPST_BLOCKING, + STPST_LEARNING, + STPST_FORWARDING +}; + +enum RTL8367C_RESVIDACT +{ + RES_VID_ACT_UNTAG = 0, + RES_VID_ACT_TAG, + RES_VID_ACT_END +}; + +typedef struct +{ + rtl8367c_provlan_frametype frameType; + rtk_uint32 etherType; +} rtl8367c_protocolgdatacfg; + +typedef struct +{ + rtk_uint32 valid; + rtk_uint32 vlan_idx; + rtk_uint32 priority; +} rtl8367c_protocolvlancfg; + +extern ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); +extern ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); +extern ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); +extern ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); +extern ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType); +extern ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType); +extern ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable); +extern ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode); +extern ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode); +extern ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri); +extern ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri); +extern ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); +extern ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); +extern ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); +extern ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); +extern ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled); + +extern ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid); +extern ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid); +extern ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled); +extern ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state); +extern ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState); +extern ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled); +extern ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled); +extern ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask); +extern ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask); +extern ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask); +extern ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action); +extern ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action); +extern ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled); +extern ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled); +extern ret_t rtl8367c_resetVlan(void); + +#endif /*#ifndef _RTL8367C_ASICDRV_VLAN_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h new file mode 100755 index 00000000..676ca8ed --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h @@ -0,0 +1,596 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Regsiter MACRO related definition + * + */ + +#ifndef _RTL8367C_BASE_H_ +#define _RTL8367C_BASE_H_ + +#include + +/* (16'h0000) port_reg */ + +#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE RTL8367C_REG_PKTGEN_PORT0_TIMER +#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_REG(port) (RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE + (port << 5)) + +#define RTL8367C_PORT_MISC_CFG_BASE RTL8367C_REG_PORT0_MISC_CFG +#define RTL8367C_PORT_MISC_CFG_REG(port) (RTL8367C_PORT_MISC_CFG_BASE + (port << 5)) +#define RTL8367C_1QREMARK_ENABLE_OFFSET RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET +#define RTL8367C_1QREMARK_ENABLE_MASK RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK + +#define RTL8367C_INGRESSBW_PORT_IFG_MASK RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK +#define RTL8367C_VLAN_EGRESS_MDOE_MASK RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK +#define RTL8367C_SPECIALCONGEST_SUSTAIN_TIMER_MASK RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK + +#define RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 +#define RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port) (RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE + (port << 5)) + +#define RTL8367C_PORT_SMALL_IPG_REG(port) (RTL8367C_REG_PORT0_MISC_CFG + (port*0x20)) + +#define RTL8367C_PORT_EEE_CFG_BASE RTL8367C_REG_PORT0_EEECFG +#define RTL8367C_PORT_EEE_CFG_REG(port) (RTL8367C_REG_PORT0_EEECFG + (port << 5)) +#define RTL8367C_PORT_EEE_100M_OFFSET RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET +#define RTL8367C_PORT_EEE_100M_MASK RTL8367C_PORT0_EEECFG_EEE_100M_MASK +#define RTL8367C_PORT_EEE_GIGA_OFFSET RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET +#define RTL8367C_PORT_EEE_GIGA_MASK RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK + + +/* (16'h0200) outq_reg */ + +#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON +#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(queue) (RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE + queue) +#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK + +#define RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON +#define RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(PORT) (RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE + PORT) +#define RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK + +#define RTL8367C_FLOWCTRL_PORT_GAP_REG RTL8367C_REG_FLOWCTRL_PORT_GAP +#define RTL8367C_FLOWCTRL_QUEUE_GAP_REG RTL8367C_REG_FLOWCTRL_QUEUE_GAP +#define RTL8367C_FLOWCTRL_PORT_QEMPTY_REG RTL8367C_REG_PORT_QEMPTY + +/* (16'h0300) sch_reg */ + +#define RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE + +#define RTL8367C_SCHEDULE_QUEUE_TYPE_BASE RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port) (RTL8367C_SCHEDULE_QUEUE_TYPE_BASE + (port >> 1)) +#define RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) (((port & 0x1) << 3) + queue) +#define RTL8367C_SCHEDULE_QUEUE_TYPE_MASK(port, queue) RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) + +#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT +#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, queue) (RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE + (port << 3) + queue) + +#define RTL8367C_SCHEDULE_APR_CTRL_REG RTL8367C_REG_SCHEDULE_APR_CTRL0 +#define RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port) (port) +#define RTL8367C_SCHEDULE_APR_CTRL_MASK(port) (1 << RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port)) + +#define RTL8367C_SCHEDULE_PORT_APR_METER_BASE RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 +#define RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, queue) (RTL8367C_SCHEDULE_PORT_APR_METER_BASE + (port << 2) + (queue / 5)) +#define RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue) (3 * (queue % 5)) +#define RTL8367C_SCHEDULE_PORT_APR_METER_MASK(queue) (RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK << RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue)) + +#define RTL8367C_PORT_EGRESSBW_LSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL0 +#define RTL8367C_PORT_EGRESSBW_LSB_REG(port) (RTL8367C_PORT_EGRESSBW_LSB_BASE + (port << 1)) + +#define RTL8367C_PORT_EGRESSBW_MSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL1 +#define RTL8367C_PORT_EGRESSBW_MSB_REG(port) (RTL8367C_PORT_EGRESSBW_MSB_BASE + (port << 1)) + +/* (16'h0500) table_reg */ + +#define RTL8367C_TABLE_ACCESS_CTRL_REG RTL8367C_REG_TABLE_ACCESS_CTRL + +#define RTL8367C_TABLE_ACCESS_ADDR_REG RTL8367C_REG_TABLE_ACCESS_ADDR + +#define RTL8367C_TABLE_ACCESS_STATUS_REG RTL8367C_REG_TABLE_LUT_ADDR + +#define RTL8367C_TABLE_ACCESS_WRDATA_BASE RTL8367C_REG_TABLE_WRITE_DATA0 +#define RTL8367C_TABLE_ACCESS_WRDATA_REG(index) (RTL8367C_TABLE_ACCESS_WRDATA_BASE + index) + +#define RTL8367C_TABLE_ACCESS_RDDATA_BASE RTL8367C_REG_TABLE_READ_DATA0 +#define RTL8367C_TABLE_ACCESS_RDDATA_REG(index) (RTL8367C_TABLE_ACCESS_RDDATA_BASE + index) + + + +/* (16'h0600) acl_reg */ + +#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 +#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(template) (RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE + template * 0x4) +#define RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field) ((field & 0x01) <<3) +#define RTL8367C_ACL_TEMPLATE_FIELD_MASK(field) (0x3F << RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field)) + +#define RTL8367C_ACL_ACTION_CTRL_BASE RTL8367C_REG_ACL_ACTION_CTRL0 +#define RTL8367C_ACL_ACTION_CTRL_REG(rule) (RTL8367C_ACL_ACTION_CTRL_BASE + (rule >> 1)) +#define RTL8367C_ACL_ACTION_CTRL2_BASE RTL8367C_REG_ACL_ACTION_CTRL32 +#define RTL8367C_ACL_ACTION_CTRL2_REG(rule) (RTL8367C_ACL_ACTION_CTRL2_BASE + ((rule-64) >> 1)) + +#define RTL8367C_ACL_OP_NOT_OFFSET(rule) (6 + ((rule & 0x1) << 3)) +#define RTL8367C_ACL_OP_NOT_MASK(rule) (1 << RTL8367C_ACL_OP_NOT_OFFSET(rule)) +#define RTL8367C_ACL_OP_ACTION_OFFSET(rule) ((rule & 0x1) << 3) +#define RTL8367C_ACL_OP_ACTION_MASK(rule) (0x3F << RTL8367C_ACL_OP_ACTION_OFFSET(rule)) + +#define RTL8367C_ACL_ENABLE_REG RTL8367C_REG_ACL_ENABLE +#define RTL8367C_ACL_UNMATCH_PERMIT_REG RTL8367C_REG_ACL_UNMATCH_PERMIT + +/* (16'h0700) cvlan_reg */ + +#define RTL8367C_VLAN_PVID_CTRL_BASE RTL8367C_REG_VLAN_PVID_CTRL0 +#define RTL8367C_VLAN_PVID_CTRL_REG(port) (RTL8367C_VLAN_PVID_CTRL_BASE + (port >> 1)) +#define RTL8367C_PORT_VIDX_OFFSET(port) ((port &1)<<3) +#define RTL8367C_PORT_VIDX_MASK(port) (RTL8367C_PORT0_VIDX_MASK << RTL8367C_PORT_VIDX_OFFSET(port)) + +#define RTL8367C_VLAN_PPB_VALID_BASE RTL8367C_REG_VLAN_PPB0_VALID +#define RTL8367C_VLAN_PPB_VALID_REG(item) (RTL8367C_VLAN_PPB_VALID_BASE + (item << 3)) + +#define RTL8367C_VLAN_PPB_CTRL_BASE RTL8367C_REG_VLAN_PPB0_CTRL0 +#define RTL8367C_VLAN_PPB_CTRL_REG(item, port) (RTL8367C_VLAN_PPB_CTRL_BASE + (item << 3) + (port / 3) ) +#define RTL8367C_VLAN_PPB_CTRL_OFFSET(port) ((port % 3) * 5) +#define RTL8367C_VLAN_PPB_CTRL_MASK(port) (RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK << RTL8367C_VLAN_PPB_CTRL_OFFSET(port)) + +#define RTL8367C_VLAN_PPB_FRAMETYPE_BASE RTL8367C_REG_VLAN_PPB0_CTRL2 +#define RTL8367C_VLAN_PPB_FRAMETYPE_REG(item) (RTL8367C_VLAN_PPB_FRAMETYPE_BASE + (item << 3)) +#define RTL8367C_VLAN_PPB_FRAMETYPE_MASK RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK + +#define RTL8367C_VLAN_PPB_ETHERTYPR_BASE RTL8367C_REG_VLAN_PPB0_CTRL3 +#define RTL8367C_VLAN_PPB_ETHERTYPR_REG(item) (RTL8367C_VLAN_PPB_ETHERTYPR_BASE + (item << 3)) + +#define RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 + + +#define RTL8367C_VLAN_CTRL_REG RTL8367C_REG_VLAN_CTRL + +#define RTL8367C_VLAN_INGRESS_REG RTL8367C_REG_VLAN_INGRESS + +#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 +#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port) (RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE + (port >> 3)) +#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port) (RTL8367C_PORT0_FRAME_TYPE_MASK << ((port & 0x7) << 1)) + +#define RTL8367C_PORT_EFID_BASE RTL8367C_REG_PORT_EFID_CTRL0 +#define RTL8367C_PORT_EFID_REG(port) (RTL8367C_PORT_EFID_BASE + (port >> 2)) +#define RTL8367C_PORT_EFID_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_PORT_EFID_MASK(port) (RTL8367C_PORT0_EFID_MASK << RTL8367C_PORT_EFID_OFFSET(port)) + +#define RTL8367C_PORT_PBFIDEN_REG RTL8367C_REG_PORT_PBFIDEN + +#define RTL8367C_PORT_PBFID_BASE RTL8367C_REG_PORT0_PBFID +#define RTL8367C_PORT_PBFID_REG(port) (RTL8367C_PORT_PBFID_BASE + port) + +/* (16'h0800) dpm_reg */ + +#define RTL8367C_RMA_CTRL_BASE RTL8367C_REG_RMA_CTRL00 + + +#define RTL8367C_VLAN_PORTBASED_PRIORITY_BASE RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port) (RTL8367C_VLAN_PORTBASED_PRIORITY_BASE + (port >> 2)) +#define RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port)) + +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, item) (RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE + (item << 2)+ (port>>2)) +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port) ((port & 0x3) <<2) +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port) (RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK << RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port)) + +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(pri) (RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE + (pri >> 2)) +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(pri) (0x7 << RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri)) + +#define RTL8367C_QOS_DSCP_TO_PRIORITY_BASE RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 +#define RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp) (RTL8367C_QOS_DSCP_TO_PRIORITY_BASE + (dscp >> 2)) +#define RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp) ((dscp & 0x3) << 2) +#define RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp) (0x7 << RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp)) + +#define RTL8367C_QOS_PORTBASED_PRIORITY_BASE RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_REG(port) (RTL8367C_QOS_PORTBASED_PRIORITY_BASE + (port >> 2)) +#define RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port)) + +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE + (src >> 1)) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_OFFSET(src) ((src & 1) << 3) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) + +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE + (src >> 1)) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src) ((src & 1) << 3) +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) + +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX(port) (1 << port) + +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(pri) (RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE + (pri >> 2)) +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(pri) (RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK << RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri)) + +#define RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG RTL8367C_REG_QOS_TRAP_PRIORITY0 + +#define RTL8367C_QOS_TRAP_PRIORITY_CTRL1_REG RTL8367C_REG_QOS_TRAP_PRIORITY1 + +#define RTL8367C_QOS_DSCP_TO_DSCP_BASE RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 +#define RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp) (RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 + (dscp >> 1)) +#define RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp) ((dscp & 0x1) << 8) +#define RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp) (0x3F << RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp)) + +#define RTL8367C_UNUCAST_FLOADING_PMSK_REG RTL8367C_REG_UNDA_FLOODING_PMSK + +#define RTL8367C_UNMCAST_FLOADING_PMSK_REG RTL8367C_REG_UNMCAST_FLOADING_PMSK + +#define RTL8367C_BCAST_FLOADING_PMSK_REG RTL8367C_REG_BCAST_FLOADING_PMSK + +#define RTL8367C_PORT_ISOLATION_PORT_MASK_BASE RTL8367C_REG_PORT_ISOLATION_PORT0_MASK +#define RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port) (RTL8367C_PORT_ISOLATION_PORT_MASK_BASE + port) + +#define RTL8367C_FORCE_CTRL_REG RTL8367C_REG_FORCE_CTRL + +#define RTL8367C_SOURCE_PORT_BLOCK_REG RTL8367C_REG_SOURCE_PORT_PERMIT + +#define RTL8367C_IPMCAST_VLAN_LEAKY_REG RTL8367C_REG_IPMCAST_VLAN_LEAKY + +#define RTL8367C_IPMCAST_PORTISO_LEAKY_REG RTL8367C_REG_IPMCAST_PORTISO_LEAKY + +#define RTL8367C_PORT_SECURIT_CTRL_REG RTL8367C_REG_PORT_SECURITY_CTRL + +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE + (port >> 3)) +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port)) + +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE + (port >> 3)) +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port)) + +#define RTL8367C_UNKNOWN_L2_MULTICAST_BASE RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 +#define RTL8367C_UNKNOWN_L2_MULTICAST_REG(port) (RTL8367C_UNKNOWN_L2_MULTICAST_BASE + (port >> 3)) +#define RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK << RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port)) + +#define RTL8367C_PORT_TRUNK_CTRL_REG RTL8367C_REG_PORT_TRUNK_CTRL +#define RTL8367C_PORT_TRUNK_HASH_MASK 0x007F + +#define RTL8367C_PORT_TRUNK_GROUP_MASK_REG RTL8367C_REG_PORT_TRUNK_GROUP_MASK +#define RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group) (group << 2) +#define RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(group) (RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group)) + +#define RTL8367C_PORT_TRUNK_FLOWCTRL_REG RTL8367C_REG_PORT_TRUNK_FLOWCTRL + +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port) (RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE + (port >> 2)) +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port) ((port & 0x3) << 2) +#define RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port) (0x7 << RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port)) + +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE + (index << 1) + (pri >> 2)) +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK << RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri)) + +#define RTL8367C_DEBUG_INFO_BASE RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 +#define RTL8367C_DEBUG_INFO_REG(port) (RTL8367C_DEBUG_INFO_BASE + (port >>1)) +#define RTL8367C_DEBUG_INFO_OFFSET(port) ((port&1)<<3) +#define RTL8367C_DEBUG_INFO_MASK(port) (RTL8367C_PORT0_DEBUG_INFO_MASK << RTL8367C_DEBUG_INFO_OFFSET(port)) + +/* (16'h0a00) l2_reg */ + +#define RTL8367C_VLAN_MSTI_BASE RTL8367C_REG_VLAN_MSTI0_CTRL0 +#define RTL8367C_VLAN_MSTI_REG(tree, port) (RTL8367C_VLAN_MSTI_BASE + (tree << 1) + (port >> 3)) +#define RTL8367C_VLAN_MSTI_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_VLAN_MSTI_MASK(port) (RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK << RTL8367C_VLAN_MSTI_OFFSET(port)) + +#define RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO +#define RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port) (RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE + port) + +#define RTL8367C_LUT_CFG_REG RTL8367C_REG_LUT_CFG + +#define RTL8367C_LUT_AGEOUT_CTRL_REG RTL8367C_REG_LUT_AGEOUT_CTRL + +#define RTL8367C_FORCE_FLUSH_REG RTL8367C_REG_FORCE_FLUSH + +#define RTL8367C_STORM_BCAST_REG RTL8367C_REG_STORM_BCAST + +#define RTL8367C_STORM_MCAST_REG RTL8367C_REG_STORM_MCAST + +#define RTL8367C_STORM_UNKNOWN_UCAST_REG RTL8367C_REG_STORM_UNKOWN_UCAST + +#define RTL8367C_STORM_UNKNOWN_MCAST_REG RTL8367C_REG_STORM_UNKOWN_MCAST + +#define RTL8367C_STORM_BCAST_METER_CTRL_BASE RTL8367C_REG_STORM_BCAST_METER_CTRL0 +#define RTL8367C_STORM_BCAST_METER_CTRL_REG(port) (RTL8367C_STORM_BCAST_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_BCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port)) + +#define RTL8367C_STORM_MCAST_METER_CTRL_BASE RTL8367C_REG_STORM_MCAST_METER_CTRL0 +#define RTL8367C_STORM_MCAST_METER_CTRL_REG(port) (RTL8367C_STORM_MCAST_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_MCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port)) + +#define RTL8367C_STORM_UNDA_METER_CTRL_BASE RTL8367C_REG_STORM_UNDA_METER_CTRL0 +#define RTL8367C_STORM_UNDA_METER_CTRL_REG(port) (RTL8367C_STORM_UNDA_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_UNDA_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port)) + +#define RTL8367C_STORM_UNMC_METER_CTRL_BASE RTL8367C_REG_STORM_UNMC_METER_CTRL0 +#define RTL8367C_STORM_UNMC_METER_CTRL_REG(port) (RTL8367C_STORM_UNMC_METER_CTRL_BASE + (port >> 1)) +#define RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_STORM_UNMC_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port)) + +#define RTL8367C_OAM_PARSER_OFFSET(port) (port*2) +#define RTL8367C_OAM_PARSER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_PARSER_OFFSET(port)) + +#define RTL8367C_OAM_MULTIPLEXER_OFFSET(port) (port*2) +#define RTL8367C_OAM_MULTIPLEXER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_MULTIPLEXER_OFFSET(port)) + +#define RTL8367C_OAM_CTRL_REG RTL8367C_REG_OAM_CTRL + +#define RTL8367C_DOT1X_PORT_ENABLE_REG RTL8367C_REG_DOT1X_PORT_ENABLE + +#define RTL8367C_DOT1X_MAC_ENABLE_REG RTL8367C_REG_DOT1X_MAC_ENABLE + +#define RTL8367C_DOT1X_PORT_AUTH_REG RTL8367C_REG_DOT1X_PORT_AUTH + +#define RTL8367C_DOT1X_PORT_OPDIR_REG RTL8367C_REG_DOT1X_PORT_OPDIR + +#define RTL8367C_DOT1X_UNAUTH_ACT_BASE RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 +#define RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port) ((port & 0x7) << 1) +#define RTL8367C_DOT1X_UNAUTH_ACT_MASK(port) (RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK << RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port)) + +#define RTL8367C_DOT1X_CFG_REG RTL8367C_REG_DOT1X_CFG + +#define RTL8367C_REG_L2_LRN_CNT_BASE RTL8367C_REG_L2_LRN_CNT_CTRL0 +#define RTL8367C_REG_L2_LRN_CNT_REG(port) (RTL8367C_REG_L2_LRN_CNT_BASE + port) + +/* (16'h0b00) mltvlan_reg */ + +#define RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 + index*5) + +/* (16'h0c00) svlan_reg */ + +#define RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 + index*3) +#define RTL8367C_SVLAN_C2SCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_C2SCFG0_CTRL0+ index*3) +#define RTL8367C_SVLAN_CFG_REG RTL8367C_REG_SVLAN_CFG + +/* (16'h0f00) hsactrl_reg */ + +#define RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 + index*2) + +/* (16'h1000) mib_reg */ + +#define RTL8367C_MIB_COUNTER_BASE_REG RTL8367C_REG_MIB_COUNTER0 + +#define RTL8367C_MIB_ADDRESS_REG RTL8367C_REG_MIB_ADDRESS + +#define RTL8367C_MIB_CTRL_REG RTL8367C_REG_MIB_CTRL0 +#define RTL8367C_MIB_PORT07_MASK (0xFF<> 4)) +#define RTL8367C_REG_METER_EXCEED_INDICATOR_OFFSET(meter) (meter & 0xF) + +/* (16'h1200) swcore_reg */ + +#define RTL8367C_VS_TPID_REG RTL8367C_REG_VS_TPID + +#define RTL8367C_SWITCH_MAC_BASE RTL8367C_REG_SWITCH_MAC0 + +#define RTL8367C_REMARKING_CTRL_REG RTL8367C_REG_SWITCH_CTRL0 + +#define RTL8367C_QOS_DSCP_REMARK_BASE RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 +#define RTL8367C_QOS_DSCP_REMARK_REG(pri) (RTL8367C_QOS_DSCP_REMARK_BASE + (pri >> 1)) +#define RTL8367C_QOS_DSCP_REMARK_OFFSET(pri) (((pri) & 0x1) << 3) +#define RTL8367C_QOS_DSCP_REMARK_MASK(pri) (0x3F << RTL8367C_QOS_DSCP_REMARK_OFFSET(pri)) + +#define RTL8367C_QOS_1Q_REMARK_BASE RTL8367C_REG_QOS_1Q_REMARK_CTRL0 +#define RTL8367C_QOS_1Q_REMARK_REG(pri) (RTL8367C_QOS_1Q_REMARK_BASE + (pri >> 2)) +#define RTL8367C_QOS_1Q_REMARK_OFFSET(pri) ((pri & 0x3) << 2) +#define RTL8367C_QOS_1Q_REMARK_MASK(pri) (0x7 << RTL8367C_QOS_1Q_REMARK_OFFSET(pri)) + +#define RTL8367C_PTKGEN_PAYLOAD_CTRL0_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL0 + +#define RTL8367C_PTKGEN_PAYLOAD_CTRL1_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL1 + +#define RTL8367C_SVLAN_UPLINK_PORTMASK_REG RTL8367C_REG_SVLAN_UPLINK_PORTMASK + +#define RTL8367C_CPU_PORT_MASK_REG RTL8367C_REG_CPU_PORT_MASK + +#define RTL8367C_CPU_CTRL_REG RTL8367C_REG_CPU_CTRL + +#define RTL8367C_MIRROR_CTRL_REG RTL8367C_REG_MIRROR_CTRL + + +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port) (RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE + (port >> 1)) +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_MASK(port) (RTL8367C_PORT0_QUEUE_MASK_MASK << RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)) + + +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE + port) +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK + +#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX +#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE + port) +#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK + +#define RTL8367C_FIELD_SELECTOR_REG(index) (RTL8367C_REG_FIELD_SELECTOR0 + index) +#define RTL8367C_FIELD_SELECTOR_ENABLE_OFFSET RTL8367C_FIELD_SELECTOR0_ENABLE_OFFSET +#define RTL8367C_FIELD_SELECTOR_ENABLE_MASK RTL8367C_FIELD_SELECTOR0_ENABLE_MASK +#define RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET +#define RTL8367C_FIELD_SELECTOR_FORMAT_MASK RTL8367C_FIELD_SELECTOR0_FORMAT_MASK +#define RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET +#define RTL8367C_FIELD_SELECTOR_OFFSET_MASK RTL8367C_FIELD_SELECTOR0_OFFSET_MASK + +/* (16'h1300) chip_reg*/ + +/* (16'h1400) mtrpool_reg */ +#define RTL8367C_METER_RATE_BASE RTL8367C_REG_METER0_RATE_CTRL0 +#define RTL8367C_METER_RATE_REG(meter) ((meter << 1) + RTL8367C_METER_RATE_BASE) + +#define RTL8367C_METER_BUCKET_SIZE_BASE RTL8367C_REG_METER0_BUCKET_SIZE +#define RTL8367C_METER_BUCKET_SIZE_REG(meter) (RTL8367C_METER_BUCKET_SIZE_BASE + meter) + +#define RTL8367C_LEAKY_BUCKET_TICK_REG RTL8367C_REG_METER_CTRL0 +#define RTL8367C_LEAKY_BUCKET_TICK_OFFSET RTL8367C_METER_TICK_OFFSET +#define RTL8367C_LEAKY_BUCKET_TICK_MASK RTL8367C_METER_TICK_MASK + +#define RTL8367C_LEAKY_BUCKET_TOKEN_REG RTL8367C_REG_METER_CTRL1 +#define RTL8367C_LEAKY_BUCKET_TOKEN_OFFSET RTL8367C_METER_CTRL1_OFFSET +#define RTL8367C_LEAKY_BUCKET_TOKEN_MASK RTL8367C_METER_CTRL1_MASK + +#define RTL8367C_METER_OVERRATE_INDICATOR_BASE RTL8367C_REG_METER_OVERRATE_INDICATOR0 +#define RTL8367C_METER_OVERRATE_INDICATOR_REG(meter) (RTL8367C_METER_OVERRATE_INDICATOR_BASE + (meter >> 4)) +#define RTL8367C_METER_EXCEED_OFFSET(meter) (meter & 0xF) +#define RTL8367C_METER_EXCEED_MASK(meter) (1 << RTL8367C_METER_EXCEED_OFFSET(meter)) + +#define RTL8367C_METER_IFG_CTRL_BASE RTL8367C_REG_METER_IFG_CTRL0 +#define RTL8367C_METER_IFG_CTRL_REG(meter) (RTL8367C_METER_IFG_CTRL_BASE + (meter >> 4)) +#define RTL8367C_METER_IFG_OFFSET(meter) (meter & 0xF) +#define RTL8367C_METER_IFG_MASK(meter) (1 << RTL8367C_METER_IFG_OFFSET(meter)) + +#define RTL8367C_FLOWCTRL_CTRL_REG RTL8367C_REG_FLOWCTRL_CTRL0 + +/* (16'h1800)8051_RLDP_EEE_reg */ +#define RTL8367C_EEELLDP_CTRL0_REG RTL8367C_REG_EEELLDP_CTRL0 + +#define RTL8367C_EEELLDP_CTRL1_REG RTL8367C_REG_EEELLDP_CTRL1 + +#define RTL8367C_EEELLDP_PMSK_REG RTL8367C_REG_EEELLDP_PMSK + +#define RTL8367C_EEELLDP_TX_FRAMEU_REG_BASE RTL8367C_REG_EEELLDP_FRAMEU00 + +#define RTL8367C_EEELLDP_TX_CAP_FRAMEL_REG_BASE RTL8367C_REG_EEELLDP_CAP_FRAMEL00 + +#define RTL8367C_EEELLDP_RX_VALUE_PORT_BASE RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 +#define RTL8367C_EEELLDP_RX_VALUE_PORT_REG(port) (RTL8367C_EEELLDP_RX_VALUE_PORT_BASE + (port * 9)) + +#define RTL8367C_RLDP_CTRL0_REG RTL8367C_REG_RLDP_CTRL0 +#define RTL8367C_RLDP_MODE_OFFSET 14 + +#define RTL8367C_RLDP_RETRY_COUNT_REG RTL8367C_REG_RLDP_CTRL1 + +#define RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG RTL8367C_REG_RLDP_CTRL2 + +#define RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG RTL8367C_REG_RLDP_CTRL3 + +#define RTL8367C_RLDP_TX_PMSK_REG RTL8367C_REG_RLDP_CTRL4 + +#define RTL8367C_RLDP_RAND_NUM_REG_BASE RTL8367C_REG_RLDP_RAND_NUM0 + +#define RTL8367C_RLDP_MAGIC_NUM_REG_BASE RTL8367C_REG_RLDP_MAGIC_NUM0 + +#define RTL8367C_RLDP_LOOP_PMSK_REG RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR + +#define RTL8367C_RLDP_LOOP_PORT_BASE RTL8367C_REG_RLDP_LOOP_PORT_REG0 +#define RTL8367C_RLDP_LOOP_PORT_REG(port) (RTL8367C_RLDP_LOOP_PORT_BASE + (port >> 1)) +#define RTL8367C_RLDP_LOOP_PORT_OFFSET(port) ((port & 0x1) << 3) +#define RTL8367C_RLDP_LOOP_PORT_MASK(port) (RTL8367C_RLDP_LOOP_PORT_00_MASK << RTL8367C_RLDP_LOOP_PORT_OFFSET(port)) + +#define RTL8367C_PAGEMETER_PORT_BASE RTL8367C_REG_PAGEMETER_PORT0_CTRL0 +#define RTL8367C_PAGEMETER_PORT_REG(port) (RTL8367C_PAGEMETER_PORT_BASE + 0x20*port) + +#define RTL8367C_HIGHPRI_INDICATOR_REG RTL8367C_REG_HIGHPRI_INDICATOR +#define RTL8367C_PORT_INDICATOR_OFFSET(port) (port) +#define RTL8367C_PORT_INDICATOR_MASK(port) (RTL8367C_PORT0_INDICATOR_MASK << RTL8367C_PORT_INDICATOR_OFFSET(port)) + +#define RTL8367C_HIGHPRI_CFG_REG RTL8367C_REG_HIGHPRI_CFG + +#define RTL8367C_EAV_PRIORITY_REMAPPING_BASE RTL8367C_REG_EAV_CTRL1 +#define RTL8367C_EAV_PRIORITY_REMAPPING_REG(pri) (RTL8367C_EAV_PRIORITY_REMAPPING_BASE + (pri >> 2)) +#define RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) * RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET) +#define RTL8367C_EAV_PRIORITY_REMAPPING_MASK(pri) (RTL8367C_REMAP_EAV_PRI0_REGEN_MASK << RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri)) + +#define RTL8367C_EEEP_CFG_BASE RTL8367C_REG_PORT0_EEECFG +#define RTL8367C_EEEP_CFG_REG(port) (RTL8367C_EEEP_CFG_BASE + (port*0x20)) + +#define RTL8367C_PKG_CFG_BASE RTL8367C_REG_PKTGEN_PORT0_CTRL +#define RTL8367C_PKG_CFG_REG(port) (RTL8367C_PKG_CFG_BASE + (port*0x20)) + +#define RTL8367C_PKG_DA_BASE RTL8367C_REG_PKTGEN_PORT0_DA0 +#define RTL8367C_PKG_DA_REG(port) (RTL8367C_PKG_DA_BASE + (port*0x20)) + +#define RTL8367C_PKG_SA_BASE RTL8367C_REG_PKTGEN_PORT0_SA0 +#define RTL8367C_PKG_SA_REG(port) (RTL8367C_PKG_SA_BASE + (port*0x20)) + +#define RTL8367C_PKG_NUM_BASE RTL8367C_REG_PKTGEN_PORT0_COUNTER0 +#define RTL8367C_PKG_NUM_REG(port) (RTL8367C_PKG_NUM_BASE + (port*0x20)) + +#define RTL8367C_PKG_LENGTH_BASE RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH +#define RTL8367C_PKG_LENGTH_REG(port) (RTL8367C_PKG_LENGTH_BASE + (port*0x20)) + +/* (16'h1c00)IGMP_MLD_reg */ +#define RTL8367C_IGMP_GROUP_USAGE_BASE RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 +#define RTL8367C_IGMP_GROUP_USAGE_REG(idx) (RTL8367C_IGMP_GROUP_USAGE_BASE + (idx / 16)) + +#define RTL8367C_FALLBACK_BASE RTL8367C_REG_FALLBACK_PORT0_CFG0 +#define RTL8367C_FALLBACK_PORT_CFG_REG(port) (RTL8367C_FALLBACK_BASE + (port * 4)) +#define RTL8367C_FALLBACK_PORT_MON_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 1 + (port * 4)) +#define RTL8367C_FALLBACK_PORT_ERR_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 3 + (port * 4)) + + +/* (16'h6400)timer_1588 */ +#define RTL8367C_EAV_CFG_BASE RTL8367C_REG_P0_EAV_CFG +#define RTL8367C_EAV_PORT_CFG_REG(port) (RTL8367C_EAV_CFG_BASE + (port *0x10)) +#define RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET +#define RTL8367C_EAV_CFG_RX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET +#define RTL8367C_EAV_CFG_RX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_RX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_RX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET +#define RTL8367C_EAV_CFG_TX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET +#define RTL8367C_EAV_CFG_TX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_TX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET +#define RTL8367C_EAV_CFG_TX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET + +#define RTL8367C_REG_TX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_TX_SYNC_SEQ_ID +#define RTL8367C_REG_TX_SYNC_SEQ_ID(port) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + (port *0x10)) +#define RTL8367C_REG_SEQ_ID(port, type) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + type + (port *0x10)) + +#define RTL8367C_REG_TX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID +#define RTL8367C_REG_TX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID +#define RTL8367C_REG_TX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID +#define RTL8367C_REG_RX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_RX_SYNC_SEQ_ID +#define RTL8367C_REG_RX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID +#define RTL8367C_REG_RX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID +#define RTL8367C_REG_RX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID + +#define RTL8367C_REG_PORT_NSEC_L_BASE RTL8367C_REG_P0_PORT_NSEC_15_0 +#define RTL8367C_REG_PORT_NSEC_L(port) (RTL8367C_REG_PORT_NSEC_L_BASE + (port *0x10)) +#define RTL8367C_REG_PORT_NSEC_H_BASE RTL8367C_REG_P0_PORT_NSEC_26_16 +#define RTL8367C_REG_PORT_NSEC_H(port) (RTL8367C_REG_PORT_NSEC_H_BASE + (port *0x10)) +#define RTL8367C_PORT_NSEC_H_OFFSET RTL8367C_P0_PORT_NSEC_26_16_OFFSET +#define RTL8367C_PORT_NSEC_H_MASK RTL8367C_P0_PORT_NSEC_26_16_MASK + +#define RTL8367C_REG_PORT_SEC_L_BASE RTL8367C_REG_P0_PORT_SEC_15_0 +#define RTL8367C_REG_PORT_SEC_L(port) (RTL8367C_REG_PORT_SEC_L_BASE + (port *0x10)) +#define RTL8367C_REG_PORT_SEC_H_BASE RTL8367C_REG_P0_PORT_SEC_31_16 +#define RTL8367C_REG_PORT_SEC_H(port) (RTL8367C_REG_PORT_SEC_H_BASE + (port *0x10)) + +#endif /*#ifndef _RTL8367C_BASE_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h new file mode 100755 index 00000000..eb4f48b8 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h @@ -0,0 +1,22819 @@ +#ifndef _RTL8367C_REG_H_ +#define _RTL8367C_REG_H_ + +/************************************************************ +auto-generated register address and field data +*************************************************************/ + +/* (16'h0000)port_reg */ + +#define RTL8367C_REG_PORT0_CGST_HALF_CFG 0x0000 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT0_CTRL 0x0001 +#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT0 0x0002 +#define RTL8367C_TX_ERR_CNT_PORT0_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT0_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT0_DA0 0x0003 + +#define RTL8367C_REG_PKTGEN_PORT0_DA1 0x0004 + +#define RTL8367C_REG_PKTGEN_PORT0_DA2 0x0005 + +#define RTL8367C_REG_PKTGEN_PORT0_SA0 0x0006 + +#define RTL8367C_REG_PKTGEN_PORT0_SA1 0x0007 + +#define RTL8367C_REG_PKTGEN_PORT0_SA2 0x0008 + +#define RTL8367C_REG_PKTGEN_PORT0_COUNTER0 0x0009 + +#define RTL8367C_REG_PKTGEN_PORT0_COUNTER1 0x000a +#define RTL8367C_PKTGEN_PORT0_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT0_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH 0x000b +#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT0_TIMER 0x000d +#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT0_MISC_CFG 0x000e +#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT0_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT0_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 0x000f + +#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL1 0x0010 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT0_FORCE_RATE0 0x0011 + +#define RTL8367C_REG_PORT0_FORCE_RATE1 0x0012 + +#define RTL8367C_REG_PORT0_CURENT_RATE0 0x0013 + +#define RTL8367C_REG_PORT0_CURENT_RATE1 0x0014 + +#define RTL8367C_REG_PORT0_PAGE_COUNTER 0x0015 +#define RTL8367C_PORT0_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT0_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT0_CTRL0 0x0016 + +#define RTL8367C_REG_PAGEMETER_PORT0_CTRL1 0x0017 + +#define RTL8367C_REG_PORT0_EEECFG 0x0018 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT0_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT0_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT0_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT0_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT0_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT0_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT0_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT0_EEETXMTR 0x0019 + +#define RTL8367C_REG_PORT0_EEERXMTR 0x001a + +#define RTL8367C_REG_PORT0_EEEPTXMTR 0x001b + +#define RTL8367C_REG_PORT0_EEEPRXMTR 0x001c + +#define RTL8367C_REG_PTP_PORT0_CFG1 0x001e +#define RTL8367C_PTP_PORT0_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT0_CFG1_MASK 0xFF + +#define RTL8367C_REG_P0_MSIC1 0x001f +#define RTL8367C_P0_MSIC1_OFFSET 0 +#define RTL8367C_P0_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT1_CGST_HALF_CFG 0x0020 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT1_CTRL 0x0021 +#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT1 0x0022 +#define RTL8367C_TX_ERR_CNT_PORT1_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT1_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT1_DA0 0x0023 + +#define RTL8367C_REG_PKTGEN_PORT1_DA1 0x0024 + +#define RTL8367C_REG_PKTGEN_PORT1_DA2 0x0025 + +#define RTL8367C_REG_PKTGEN_PORT1_SA0 0x0026 + +#define RTL8367C_REG_PKTGEN_PORT1_SA1 0x0027 + +#define RTL8367C_REG_PKTGEN_PORT1_SA2 0x0028 + +#define RTL8367C_REG_PKTGEN_PORT1_COUNTER0 0x0029 + +#define RTL8367C_REG_PKTGEN_PORT1_COUNTER1 0x002a +#define RTL8367C_PKTGEN_PORT1_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT1_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT1_TX_LENGTH 0x002b +#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT1_TIMER 0x002d +#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT1_MISC_CFG 0x002e +#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT1_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT1_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL0 0x002f + +#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL1 0x0030 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT1_FORCE_RATE0 0x0031 + +#define RTL8367C_REG_PORT1_FORCE_RATE1 0x0032 + +#define RTL8367C_REG_PORT1_CURENT_RATE0 0x0033 + +#define RTL8367C_REG_PORT1_CURENT_RATE1 0x0034 + +#define RTL8367C_REG_PORT1_PAGE_COUNTER 0x0035 +#define RTL8367C_PORT1_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT1_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT1_CTRL0 0x0036 + +#define RTL8367C_REG_PAGEMETER_PORT1_CTRL1 0x0037 + +#define RTL8367C_REG_PORT1_EEECFG 0x0038 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT1_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT1_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT1_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT1_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT1_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT1_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT1_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT1_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT1_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT1_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT1_EEETXMTR 0x0039 + +#define RTL8367C_REG_PORT1_EEERXMTR 0x003a + +#define RTL8367C_REG_PORT1_EEEPTXMTR 0x003b + +#define RTL8367C_REG_PORT1_EEEPRXMTR 0x003c + +#define RTL8367C_REG_PTP_PORT1_CFG1 0x003e +#define RTL8367C_PTP_PORT1_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT1_CFG1_MASK 0xFF + +#define RTL8367C_REG_P1_MSIC1 0x003f +#define RTL8367C_P1_MSIC1_OFFSET 0 +#define RTL8367C_P1_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT2_CGST_HALF_CFG 0x0040 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT2_CTRL 0x0041 +#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT2 0x0042 +#define RTL8367C_TX_ERR_CNT_PORT2_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT2_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT2_DA0 0x0043 + +#define RTL8367C_REG_PKTGEN_PORT2_DA1 0x0044 + +#define RTL8367C_REG_PKTGEN_PORT2_DA2 0x0045 + +#define RTL8367C_REG_PKTGEN_PORT2_SA0 0x0046 + +#define RTL8367C_REG_PKTGEN_PORT2_SA1 0x0047 + +#define RTL8367C_REG_PKTGEN_PORT2_SA2 0x0048 + +#define RTL8367C_REG_PKTGEN_PORT2_COUNTER0 0x0049 + +#define RTL8367C_REG_PKTGEN_PORT2_COUNTER1 0x004a +#define RTL8367C_PKTGEN_PORT2_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT2_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT2_TX_LENGTH 0x004b +#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT2_TIMER 0x004d +#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT2_MISC_CFG 0x004e +#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT2_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT2_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL0 0x004f + +#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL1 0x0050 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT2_FORCE_RATE0 0x0051 + +#define RTL8367C_REG_PORT2_FORCE_RATE1 0x0052 + +#define RTL8367C_REG_PORT2_CURENT_RATE0 0x0053 + +#define RTL8367C_REG_PORT2_CURENT_RATE1 0x0054 + +#define RTL8367C_REG_PORT2_PAGE_COUNTER 0x0055 +#define RTL8367C_PORT2_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT2_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT2_CTRL0 0x0056 + +#define RTL8367C_REG_PAGEMETER_PORT2_CTRL1 0x0057 + +#define RTL8367C_REG_PORT2_EEECFG 0x0058 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT2_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT2_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT2_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT2_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT2_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT2_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT2_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT2_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT2_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT2_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT2_EEETXMTR 0x0059 + +#define RTL8367C_REG_PORT2_EEERXMTR 0x005a + +#define RTL8367C_REG_PORT2_EEEPTXMTR 0x005b + +#define RTL8367C_REG_PORT2_EEEPRXMTR 0x005c + +#define RTL8367C_REG_PTP_PORT2_CFG1 0x005e +#define RTL8367C_PTP_PORT2_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT2_CFG1_MASK 0xFF + +#define RTL8367C_REG_P2_MSIC1 0x005f +#define RTL8367C_P2_MSIC1_OFFSET 0 +#define RTL8367C_P2_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT3_CGST_HALF_CFG 0x0060 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT3_CTRL 0x0061 +#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT3 0x0062 +#define RTL8367C_TX_ERR_CNT_PORT3_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT3_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT3_DA0 0x0063 + +#define RTL8367C_REG_PKTGEN_PORT3_DA1 0x0064 + +#define RTL8367C_REG_PKTGEN_PORT3_DA2 0x0065 + +#define RTL8367C_REG_PKTGEN_PORT3_SA0 0x0066 + +#define RTL8367C_REG_PKTGEN_PORT3_SA1 0x0067 + +#define RTL8367C_REG_PKTGEN_PORT3_SA2 0x0068 + +#define RTL8367C_REG_PKTGEN_PORT3_COUNTER0 0x0069 + +#define RTL8367C_REG_PKTGEN_PORT3_COUNTER1 0x006a +#define RTL8367C_PKTGEN_PORT3_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT3_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT3_TX_LENGTH 0x006b +#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT3_TIMER 0x006d +#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT3_MISC_CFG 0x006e +#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT3_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT3_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL0 0x006f + +#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL1 0x0070 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT3_FORCE_RATE0 0x0071 + +#define RTL8367C_REG_PORT3_FORCE_RATE1 0x0072 + +#define RTL8367C_REG_PORT3_CURENT_RATE0 0x0073 + +#define RTL8367C_REG_PORT3_CURENT_RATE1 0x0074 + +#define RTL8367C_REG_PORT3_PAGE_COUNTER 0x0075 +#define RTL8367C_PORT3_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT3_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT3_CTRL0 0x0076 + +#define RTL8367C_REG_PAGEMETER_PORT3_CTRL1 0x0077 + +#define RTL8367C_REG_PORT3_EEECFG 0x0078 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT3_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT3_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT3_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT3_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT3_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT3_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT3_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT3_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT3_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT3_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT3_EEETXMTR 0x0079 + +#define RTL8367C_REG_PORT3_EEERXMTR 0x007a + +#define RTL8367C_REG_PORT3_EEEPTXMTR 0x007b + +#define RTL8367C_REG_PORT3_EEEPRXMTR 0x007c + +#define RTL8367C_REG_PTP_PORT3_CFG1 0x007e +#define RTL8367C_PTP_PORT3_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT3_CFG1_MASK 0xFF + +#define RTL8367C_REG_P3_MSIC1 0x007f +#define RTL8367C_P3_MSIC1_OFFSET 0 +#define RTL8367C_P3_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT4_CGST_HALF_CFG 0x0080 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT4_CTRL 0x0081 +#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT4 0x0082 +#define RTL8367C_TX_ERR_CNT_PORT4_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT4_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT4_DA0 0x0083 + +#define RTL8367C_REG_PKTGEN_PORT4_DA1 0x0084 + +#define RTL8367C_REG_PKTGEN_PORT4_DA2 0x0085 + +#define RTL8367C_REG_PKTGEN_PORT4_SA0 0x0086 + +#define RTL8367C_REG_PKTGEN_PORT4_SA1 0x0087 + +#define RTL8367C_REG_PKTGEN_PORT4_SA2 0x0088 + +#define RTL8367C_REG_PKTGEN_PORT4_COUNTER0 0x0089 + +#define RTL8367C_REG_PKTGEN_PORT4_COUNTER1 0x008a +#define RTL8367C_PKTGEN_PORT4_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT4_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT4_TX_LENGTH 0x008b +#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT4_TIMER 0x008d +#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT4_MISC_CFG 0x008e +#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT4_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT4_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL0 0x008f + +#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL1 0x0090 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT4_FORCE_RATE0 0x0091 + +#define RTL8367C_REG_PORT4_FORCE_RATE1 0x0092 + +#define RTL8367C_REG_PORT4_CURENT_RATE0 0x0093 + +#define RTL8367C_REG_PORT4_CURENT_RATE1 0x0094 + +#define RTL8367C_REG_PORT4_PAGE_COUNTER 0x0095 +#define RTL8367C_PORT4_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT4_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT4_CTRL0 0x0096 + +#define RTL8367C_REG_PAGEMETER_PORT4_CTRL1 0x0097 + +#define RTL8367C_REG_PORT4_EEECFG 0x0098 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT4_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT4_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT4_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT4_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT4_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT4_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT4_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT4_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT4_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT4_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT4_EEETXMTR 0x0099 + +#define RTL8367C_REG_PORT4_EEERXMTR 0x009a + +#define RTL8367C_REG_PORT4_EEEPTXMTR 0x009b + +#define RTL8367C_REG_PORT4_EEEPRXMTR 0x009c + +#define RTL8367C_REG_PTP_PORT4_CFG1 0x009e +#define RTL8367C_PTP_PORT4_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT4_CFG1_MASK 0xFF + +#define RTL8367C_REG_P4_MSIC1 0x009f +#define RTL8367C_P4_MSIC1_OFFSET 0 +#define RTL8367C_P4_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT5_CGST_HALF_CFG 0x00a0 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT5_CTRL 0x00a1 +#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT5 0x00a2 +#define RTL8367C_TX_ERR_CNT_PORT5_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT5_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT5_DA0 0x00a3 + +#define RTL8367C_REG_PKTGEN_PORT5_DA1 0x00a4 + +#define RTL8367C_REG_PKTGEN_PORT5_DA2 0x00a5 + +#define RTL8367C_REG_PKTGEN_PORT5_SA0 0x00a6 + +#define RTL8367C_REG_PKTGEN_PORT5_SA1 0x00a7 + +#define RTL8367C_REG_PKTGEN_PORT5_SA2 0x00a8 + +#define RTL8367C_REG_PKTGEN_PORT5_COUNTER0 0x00a9 + +#define RTL8367C_REG_PKTGEN_PORT5_COUNTER1 0x00aa +#define RTL8367C_PKTGEN_PORT5_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT5_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT5_TX_LENGTH 0x00ab +#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT5_TIMER 0x00ad +#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT5_MISC_CFG 0x00ae +#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT5_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT5_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL0 0x00af + +#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL1 0x00b0 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT5_FORCE_RATE0 0x00b1 + +#define RTL8367C_REG_PORT5_FORCE_RATE1 0x00b2 + +#define RTL8367C_REG_PORT5_CURENT_RATE0 0x00b3 + +#define RTL8367C_REG_PORT5_CURENT_RATE1 0x00b4 + +#define RTL8367C_REG_PORT5_PAGE_COUNTER 0x00b5 +#define RTL8367C_PORT5_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT5_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT5_CTRL0 0x00b6 + +#define RTL8367C_REG_PAGEMETER_PORT5_CTRL1 0x00b7 + +#define RTL8367C_REG_PORT5_EEECFG 0x00b8 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT5_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT5_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT5_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT5_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT5_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT5_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT5_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT5_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT5_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT5_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT5_EEETXMTR 0x00b9 + +#define RTL8367C_REG_PORT5_EEERXMTR 0x00ba + +#define RTL8367C_REG_PORT5_EEEPTXMTR 0x00bb + +#define RTL8367C_REG_PORT5_EEEPRXMTR 0x00bc + +#define RTL8367C_REG_PTP_PORT5_CFG1 0x00be +#define RTL8367C_PTP_PORT5_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT5_CFG1_MASK 0xFF + +#define RTL8367C_REG_P5_MSIC1 0x00bf +#define RTL8367C_P5_MSIC1_OFFSET 0 +#define RTL8367C_P5_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT6_CGST_HALF_CFG 0x00c0 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT6_CTRL 0x00c1 +#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT6 0x00c2 +#define RTL8367C_TX_ERR_CNT_PORT6_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT6_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT6_DA0 0x00c3 + +#define RTL8367C_REG_PKTGEN_PORT6_DA1 0x00c4 + +#define RTL8367C_REG_PKTGEN_PORT6_DA2 0x00c5 + +#define RTL8367C_REG_PKTGEN_PORT6_SA0 0x00c6 + +#define RTL8367C_REG_PKTGEN_PORT6_SA1 0x00c7 + +#define RTL8367C_REG_PKTGEN_PORT6_SA2 0x00c8 + +#define RTL8367C_REG_PKTGEN_PORT6_COUNTER0 0x00c9 + +#define RTL8367C_REG_PKTGEN_PORT6_COUNTER1 0x00ca +#define RTL8367C_PKTGEN_PORT6_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT6_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT6_TX_LENGTH 0x00cb +#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT6_TIMER 0x00cd +#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT6_MISC_CFG 0x00ce +#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT6_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT6_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL0 0x00cf + +#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL1 0x00d0 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT6_FORCE_RATE0 0x00d1 + +#define RTL8367C_REG_PORT6_FORCE_RATE1 0x00d2 + +#define RTL8367C_REG_PORT6_CURENT_RATE0 0x00d3 + +#define RTL8367C_REG_PORT6_CURENT_RATE1 0x00d4 + +#define RTL8367C_REG_PORT6_PAGE_COUNTER 0x00d5 +#define RTL8367C_PORT6_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT6_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT6_CTRL0 0x00d6 + +#define RTL8367C_REG_PAGEMETER_PORT6_CTRL1 0x00d7 + +#define RTL8367C_REG_PORT6_EEECFG 0x00d8 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT6_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT6_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT6_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT6_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT6_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT6_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT6_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT6_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT6_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT6_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT6_EEETXMTR 0x00d9 + +#define RTL8367C_REG_PORT6_EEERXMTR 0x00da + +#define RTL8367C_REG_PORT6_EEEPTXMTR 0x00db + +#define RTL8367C_REG_PORT6_EEEPRXMTR 0x00dc + +#define RTL8367C_REG_PTP_PORT6_CFG1 0x00de +#define RTL8367C_PTP_PORT6_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT6_CFG1_MASK 0xFF + +#define RTL8367C_REG_P6_MSIC1 0x00df +#define RTL8367C_P6_MSIC1_OFFSET 0 +#define RTL8367C_P6_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT7_CGST_HALF_CFG 0x00e0 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT7_CTRL 0x00e1 +#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT7 0x00e2 +#define RTL8367C_TX_ERR_CNT_PORT7_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT7_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT7_DA0 0x00e3 + +#define RTL8367C_REG_PKTGEN_PORT7_DA1 0x00e4 + +#define RTL8367C_REG_PKTGEN_PORT7_DA2 0x00e5 + +#define RTL8367C_REG_PKTGEN_PORT7_SA0 0x00e6 + +#define RTL8367C_REG_PKTGEN_PORT7_SA1 0x00e7 + +#define RTL8367C_REG_PKTGEN_PORT7_SA2 0x00e8 + +#define RTL8367C_REG_PKTGEN_PORT7_COUNTER0 0x00e9 + +#define RTL8367C_REG_PKTGEN_PORT7_COUNTER1 0x00ea +#define RTL8367C_PKTGEN_PORT7_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT7_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT7_TX_LENGTH 0x00eb +#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT7_TIMER 0x00ed +#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT7_MISC_CFG 0x00ee +#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT7_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT7_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL0 0x00ef + +#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL1 0x00f0 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT7_FORCE_RATE0 0x00f1 + +#define RTL8367C_REG_PORT7_FORCE_RATE1 0x00f2 + +#define RTL8367C_REG_PORT7_CURENT_RATE0 0x00f3 + +#define RTL8367C_REG_PORT7_CURENT_RATE1 0x00f4 + +#define RTL8367C_REG_PORT7_PAGE_COUNTER 0x00f5 +#define RTL8367C_PORT7_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT7_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT7_CTRL0 0x00f6 + +#define RTL8367C_REG_PAGEMETER_PORT7_CTRL1 0x00f7 + +#define RTL8367C_REG_PORT7_EEECFG 0x00f8 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT7_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT7_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT7_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT7_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT7_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT7_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT7_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT7_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT7_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT7_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT7_EEETXMTR 0x00f9 + +#define RTL8367C_REG_PORT7_EEERXMTR 0x00fa + +#define RTL8367C_REG_PORT7_EEEPTXMTR 0x00fb + +#define RTL8367C_REG_PORT7_EEEPRXMTR 0x00fc + +#define RTL8367C_REG_PTP_PORT7_CFG1 0x00fe +#define RTL8367C_PTP_PORT7_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT7_CFG1_MASK 0xFF + +#define RTL8367C_REG_P7_MSIC1 0x00ff +#define RTL8367C_P7_MSIC1_OFFSET 0 +#define RTL8367C_P7_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT8_CGST_HALF_CFG 0x0100 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT8_CTRL 0x0101 +#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT8 0x0102 +#define RTL8367C_TX_ERR_CNT_PORT8_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT8_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT8_DA0 0x0103 + +#define RTL8367C_REG_PKTGEN_PORT8_DA1 0x0104 + +#define RTL8367C_REG_PKTGEN_PORT8_DA2 0x0105 + +#define RTL8367C_REG_PKTGEN_PORT8_SA0 0x0106 + +#define RTL8367C_REG_PKTGEN_PORT8_SA1 0x0107 + +#define RTL8367C_REG_PKTGEN_PORT8_SA2 0x0108 + +#define RTL8367C_REG_PKTGEN_PORT8_COUNTER0 0x0109 + +#define RTL8367C_REG_PKTGEN_PORT8_COUNTER1 0x010a +#define RTL8367C_PKTGEN_PORT8_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT8_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT8_TX_LENGTH 0x010b +#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT8_TIMER 0x010d +#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT8_MISC_CFG 0x010e +#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT8_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT8_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL0 0x010f + +#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL1 0x0110 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT8_FORCE_RATE0 0x0111 + +#define RTL8367C_REG_PORT8_FORCE_RATE1 0x0112 + +#define RTL8367C_REG_PORT8_CURENT_RATE0 0x0113 + +#define RTL8367C_REG_PORT8_CURENT_RATE1 0x0114 + +#define RTL8367C_REG_PORT8_PAGE_COUNTER 0x0115 +#define RTL8367C_PORT8_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT8_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT8_CTRL0 0x0116 + +#define RTL8367C_REG_PAGEMETER_PORT8_CTRL1 0x0117 + +#define RTL8367C_REG_PORT8_EEECFG 0x0118 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT8_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT8_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT8_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT8_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT8_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT8_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT8_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT8_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT8_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT8_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT8_EEETXMTR 0x0119 + +#define RTL8367C_REG_PORT8_EEERXMTR 0x011a + +#define RTL8367C_REG_PORT8_EEEPTXMTR 0x011b + +#define RTL8367C_REG_PORT8_EEEPRXMTR 0x011c + +#define RTL8367C_REG_PTP_PORT8_CFG1 0x011e +#define RTL8367C_PTP_PORT8_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT8_CFG1_MASK 0xFF + +#define RTL8367C_REG_P8_MSIC1 0x011f +#define RTL8367C_P8_MSIC1_OFFSET 0 +#define RTL8367C_P8_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT9_CGST_HALF_CFG 0x0120 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT9_CTRL 0x0121 +#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT9 0x0122 +#define RTL8367C_TX_ERR_CNT_PORT9_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT9_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT9_DA0 0x0123 + +#define RTL8367C_REG_PKTGEN_PORT9_DA1 0x0124 + +#define RTL8367C_REG_PKTGEN_PORT9_DA2 0x0125 + +#define RTL8367C_REG_PKTGEN_PORT9_SA0 0x0126 + +#define RTL8367C_REG_PKTGEN_PORT9_SA1 0x0127 + +#define RTL8367C_REG_PKTGEN_PORT9_SA2 0x0128 + +#define RTL8367C_REG_PKTGEN_PORT9_COUNTER0 0x0129 + +#define RTL8367C_REG_PKTGEN_PORT9_COUNTER1 0x012a +#define RTL8367C_PKTGEN_PORT9_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT9_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT9_TX_LENGTH 0x012b +#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT9_TIMER 0x012d +#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT9_MISC_CFG 0x012e +#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT9_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT9_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL0 0x012f + +#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL1 0x0130 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT9_FORCE_RATE0 0x0131 + +#define RTL8367C_REG_PORT9_FORCE_RATE1 0x0132 + +#define RTL8367C_REG_PORT9_CURENT_RATE0 0x0133 + +#define RTL8367C_REG_PORT9_CURENT_RATE1 0x0134 + +#define RTL8367C_REG_PORT9_PAGE_COUNTER 0x0135 +#define RTL8367C_PORT9_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT9_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT9_CTRL0 0x0136 + +#define RTL8367C_REG_PAGEMETER_PORT9_CTRL1 0x0137 + +#define RTL8367C_REG_PORT9_EEECFG 0x0138 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT9_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT9_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT9_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT9_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT9_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT9_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT9_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT9_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT9_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT9_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT9_EEETXMTR 0x0139 + +#define RTL8367C_REG_PORT9_EEERXMTR 0x013a + +#define RTL8367C_REG_PORT9_EEEPTXMTR 0x013b + +#define RTL8367C_REG_PORT9_EEEPRXMTR 0x013c + +#define RTL8367C_REG_PTP_PORT9_CFG1 0x013e +#define RTL8367C_PTP_PORT9_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT9_CFG1_MASK 0xFF + +#define RTL8367C_REG_P9_MSIC1 0x013f +#define RTL8367C_P9_MSIC1_OFFSET 0 +#define RTL8367C_P9_MSIC1_MASK 0x1 + +#define RTL8367C_REG_PORT10_CGST_HALF_CFG 0x0140 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_PKTGEN_PORT10_CTRL 0x0141 +#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_OFFSET 15 +#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_MASK 0x8000 +#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_OFFSET 13 +#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_MASK 0x2000 +#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_OFFSET 4 +#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_MASK 0x10 +#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_OFFSET 0 +#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_MASK 0x1 + +#define RTL8367C_REG_TX_ERR_CNT_PORT10 0x0142 +#define RTL8367C_TX_ERR_CNT_PORT10_OFFSET 0 +#define RTL8367C_TX_ERR_CNT_PORT10_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_PORT10_DA0 0x0143 + +#define RTL8367C_REG_PKTGEN_PORT10_DA1 0x0144 + +#define RTL8367C_REG_PKTGEN_PORT10_DA2 0x0145 + +#define RTL8367C_REG_PKTGEN_PORT10_SA0 0x0146 + +#define RTL8367C_REG_PKTGEN_PORT10_SA1 0x0147 + +#define RTL8367C_REG_PKTGEN_PORT10_SA2 0x0148 + +#define RTL8367C_REG_PKTGEN_PORT10_COUNTER0 0x0149 + +#define RTL8367C_REG_PKTGEN_PORT10_COUNTER1 0x014a +#define RTL8367C_PKTGEN_PORT10_COUNTER1_OFFSET 0 +#define RTL8367C_PKTGEN_PORT10_COUNTER1_MASK 0xFF + +#define RTL8367C_REG_PKTGEN_PORT10_TX_LENGTH 0x014b +#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_OFFSET 0 +#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_MASK 0x3FFF + +#define RTL8367C_REG_PKTGEN_PORT10_TIMER 0x014d +#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_OFFSET 4 +#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_MASK 0xF0 +#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 +#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 + +#define RTL8367C_REG_PORT10_MISC_CFG 0x014e +#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 +#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 +#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 +#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 +#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 +#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 +#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 +#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_OFFSET 10 +#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_MASK 0x400 +#define RTL8367C_PORT10_MISC_CFG_RX_SPC_OFFSET 9 +#define RTL8367C_PORT10_MISC_CFG_RX_SPC_MASK 0x200 +#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_OFFSET 8 +#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_MASK 0x100 +#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 +#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 +#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_OFFSET 6 +#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_MASK 0x40 +#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 +#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 +#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 +#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF + +#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL0 0x014f + +#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL1 0x0150 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_OFFSET 3 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_MASK 0xFFF8 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 +#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 + +#define RTL8367C_REG_PORT10_FORCE_RATE0 0x0151 + +#define RTL8367C_REG_PORT10_FORCE_RATE1 0x0152 + +#define RTL8367C_REG_PORT10_CURENT_RATE0 0x0153 + +#define RTL8367C_REG_PORT10_CURENT_RATE1 0x0154 + +#define RTL8367C_REG_PORT10_PAGE_COUNTER 0x0155 +#define RTL8367C_PORT10_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_PORT10_PAGE_COUNTER_MASK 0x7F + +#define RTL8367C_REG_PAGEMETER_PORT10_CTRL0 0x0156 + +#define RTL8367C_REG_PAGEMETER_PORT10_CTRL1 0x0157 + +#define RTL8367C_REG_PORT10_EEECFG 0x0158 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_OFFSET 14 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_OFFSET 13 +#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 +#define RTL8367C_PORT10_EEECFG_EEE_FORCE_OFFSET 12 +#define RTL8367C_PORT10_EEECFG_EEE_FORCE_MASK 0x1000 +#define RTL8367C_PORT10_EEECFG_EEE_100M_OFFSET 11 +#define RTL8367C_PORT10_EEECFG_EEE_100M_MASK 0x800 +#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_OFFSET 10 +#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_MASK 0x400 +#define RTL8367C_PORT10_EEECFG_EEE_TX_OFFSET 9 +#define RTL8367C_PORT10_EEECFG_EEE_TX_MASK 0x200 +#define RTL8367C_PORT10_EEECFG_EEE_RX_OFFSET 8 +#define RTL8367C_PORT10_EEECFG_EEE_RX_MASK 0x100 +#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_OFFSET 6 +#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_MASK 0x40 +#define RTL8367C_PORT10_EEECFG_EEE_LPI_OFFSET 5 +#define RTL8367C_PORT10_EEECFG_EEE_LPI_MASK 0x20 +#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_OFFSET 4 +#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_MASK 0x10 +#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_OFFSET 3 +#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_MASK 0x8 +#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 +#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 +#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_OFFSET 1 +#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_MASK 0x2 +#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_OFFSET 0 +#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_MASK 0x1 + +#define RTL8367C_REG_PORT10_EEETXMTR 0x0159 + +#define RTL8367C_REG_PORT10_EEERXMTR 0x015a + +#define RTL8367C_REG_PORT10_EEEPTXMTR 0x015b + +#define RTL8367C_REG_PORT10_EEEPRXMTR 0x015c + +#define RTL8367C_REG_PTP_PORT10_CFG1 0x015e +#define RTL8367C_PTP_PORT10_CFG1_OFFSET 7 +#define RTL8367C_PTP_PORT10_CFG1_MASK 0xFF + +#define RTL8367C_REG_P10_MSIC1 0x015f +#define RTL8367C_P10_MSIC1_OFFSET 0 +#define RTL8367C_P10_MSIC1_MASK 0x1 + +/* (16'h0200)outq_reg */ + +#define RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON 0x0200 +#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE1_DROP_ON 0x0201 +#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE2_DROP_ON 0x0202 +#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE3_DROP_ON 0x0203 +#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE4_DROP_ON 0x0204 +#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE5_DROP_ON 0x0205 +#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE6_DROP_ON 0x0206 +#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE7_DROP_ON 0x0207 +#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON 0x0208 +#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT1_DROP_ON 0x0209 +#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT2_DROP_ON 0x020a +#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT3_DROP_ON 0x020b +#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT4_DROP_ON 0x020c +#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT5_DROP_ON 0x020d +#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT6_DROP_ON 0x020e +#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT7_DROP_ON 0x020f +#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT8_DROP_ON 0x0210 +#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT9_DROP_ON 0x0211 +#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT10_DROP_ON 0x0212 +#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_GAP 0x0218 +#define RTL8367C_FLOWCTRL_PORT_GAP_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_GAP_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE_GAP 0x0219 +#define RTL8367C_FLOWCTRL_QUEUE_GAP_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE_GAP_MASK 0x7FF + +#define RTL8367C_REG_PORT_QEMPTY 0x022d +#define RTL8367C_PORT_QEMPTY_OFFSET 0 +#define RTL8367C_PORT_QEMPTY_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL0 0x022e +#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_OFFSET 0 +#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_MASK 0xF + +#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL1 0x022f +#define RTL8367C_TOTAL_OFFSET 9 +#define RTL8367C_TOTAL_MASK 0x200 +#define RTL8367C_PORT_MAX_OFFSET 8 +#define RTL8367C_PORT_MAX_MASK 0x100 +#define RTL8367C_QMAX_MASK_OFFSET 0 +#define RTL8367C_QMAX_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCTRL_QUEUE0_PAGE_COUNT 0x0230 +#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE1_PAGE_COUNT 0x0231 +#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE2_PAGE_COUNT 0x0232 +#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE3_PAGE_COUNT 0x0233 +#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE4_PAGE_COUNT 0x0234 +#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE5_PAGE_COUNT 0x0235 +#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE6_PAGE_COUNT 0x0236 +#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE7_PAGE_COUNT 0x0237 +#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_PAGE_COUNT 0x0238 +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT 0x0239 +#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT 0x023a +#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT 0x023b +#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT 0x023c +#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT 0x023d +#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT 0x023e +#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT 0x023f +#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT 0x0240 +#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_MAX_PAGE_COUNT 0x0241 +#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_TOTAL_PACKET_COUNT 0x0243 + +#define RTL8367C_REG_HIGH_QUEUE_MASK0 0x0244 +#define RTL8367C_PORT1_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT1_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT0_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT0_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK1 0x0245 +#define RTL8367C_PORT3_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT3_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT2_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT2_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK2 0x0246 +#define RTL8367C_PORT5_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT5_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT4_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT4_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK3 0x0247 +#define RTL8367C_PORT7_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT7_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT6_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT6_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK4 0x0248 +#define RTL8367C_PORT9_HIGH_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT9_HIGH_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT8_HIGH_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT8_HIGH_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_HIGH_QUEUE_MASK5 0x0249 +#define RTL8367C_HIGH_QUEUE_MASK5_OFFSET 0 +#define RTL8367C_HIGH_QUEUE_MASK5_MASK 0xFF + +#define RTL8367C_REG_LOW_QUEUE_TH 0x024c +#define RTL8367C_LOW_QUEUE_TH_OFFSET 0 +#define RTL8367C_LOW_QUEUE_TH_MASK 0x7FF + +#define RTL8367C_REG_TH_TX_PREFET 0x0250 +#define RTL8367C_TH_TX_PREFET_OFFSET 0 +#define RTL8367C_TH_TX_PREFET_MASK 0xFF + +#define RTL8367C_REG_DUMMY_0251 0x0251 + +#define RTL8367C_REG_DUMMY_0252 0x0252 + +#define RTL8367C_REG_DUMMY_0253 0x0253 + +#define RTL8367C_REG_DUMMY_0254 0x0254 + +#define RTL8367C_REG_DUMMY_0255 0x0255 + +#define RTL8367C_REG_DUMMY_0256 0x0256 + +#define RTL8367C_REG_DUMMY_0257 0x0257 + +#define RTL8367C_REG_DUMMY_0258 0x0258 + +#define RTL8367C_REG_DUMMY_0259 0x0259 + +#define RTL8367C_REG_DUMMY_025A 0x025A + +#define RTL8367C_REG_DUMMY_025B 0x025B + +#define RTL8367C_REG_DUMMY_025C 0x025C + +#define RTL8367C_REG_Q_TXPKT_CNT_CTL 0x025d +#define RTL8367C_QUEUE_PKT_CNT_CLR_OFFSET 4 +#define RTL8367C_QUEUE_PKT_CNT_CLR_MASK 0x10 +#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_OFFSET 0 +#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_MASK 0xF + +#define RTL8367C_REG_Q0_TXPKT_CNT_L 0x025e + +#define RTL8367C_REG_Q0_TXPKT_CNT_H 0x025f + +#define RTL8367C_REG_Q1_TXPKT_CNT_L 0x0260 + +#define RTL8367C_REG_Q1_TXPKT_CNT_H 0x0261 + +#define RTL8367C_REG_Q2_TXPKT_CNT_L 0x0262 + +#define RTL8367C_REG_Q2_TXPKT_CNT_H 0x0263 + +#define RTL8367C_REG_Q3_TXPKT_CNT_L 0x0264 + +#define RTL8367C_REG_Q3_TXPKT_CNT_H 0x0265 + +#define RTL8367C_REG_Q4_TXPKT_CNT_L 0x0266 + +#define RTL8367C_REG_Q4_TXPKT_CNT_H 0x0267 + +#define RTL8367C_REG_Q5_TXPKT_CNT_L 0x0268 + +#define RTL8367C_REG_Q5_TXPKT_CNT_H 0x0269 + +#define RTL8367C_REG_Q6_TXPKT_CNT_L 0x026a + +#define RTL8367C_REG_Q6_TXPKT_CNT_H 0x026b + +#define RTL8367C_REG_Q7_TXPKT_CNT_L 0x026c + +#define RTL8367C_REG_Q7_TXPKT_CNT_H 0x026d + +/* (16'h0300)sch_reg */ + +#define RTL8367C_REG_SCHEDULE_WFQ_CTRL 0x0300 +#define RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET 0 +#define RTL8367C_SCHEDULE_WFQ_CTRL_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE 0x0301 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 0x0302 +#define RTL8367C_PORT1_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT1_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT1_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT1_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT1_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT1_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT1_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT1_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT1_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT1_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT1_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT1_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT1_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT1_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT1_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT1_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT0_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT0_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT0_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT0_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT0_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT0_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT0_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT0_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT0_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT0_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT0_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT0_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT0_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT0_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT0_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT0_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL1 0x0303 +#define RTL8367C_PORT3_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT3_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT3_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT3_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT3_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT3_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT3_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT3_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT3_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT3_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT3_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT3_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT3_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT3_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT3_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT3_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT2_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT2_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT2_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT2_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT2_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT2_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT2_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT2_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT2_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT2_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT2_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT2_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT2_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT2_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT2_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT2_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL2 0x0304 +#define RTL8367C_PORT5_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT5_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT5_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT5_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT5_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT5_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT5_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT5_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT5_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT5_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT5_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT5_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT5_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT5_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT5_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT5_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT4_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT4_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT4_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT4_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT4_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT4_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT4_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT4_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT4_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT4_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT4_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT4_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT4_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT4_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT4_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT4_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL3 0x0305 +#define RTL8367C_PORT7_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT7_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT7_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT7_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT7_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT7_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT7_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT7_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT7_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT7_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT7_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT7_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT7_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT7_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT7_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT7_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT6_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT6_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT6_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT6_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT6_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT6_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT6_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT6_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT6_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT6_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT6_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT6_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT6_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT6_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL4 0x0306 +#define RTL8367C_PORT9_QUEUE7_TYPE_OFFSET 15 +#define RTL8367C_PORT9_QUEUE7_TYPE_MASK 0x8000 +#define RTL8367C_PORT9_QUEUE6_TYPE_OFFSET 14 +#define RTL8367C_PORT9_QUEUE6_TYPE_MASK 0x4000 +#define RTL8367C_PORT9_QUEUE5_TYPE_OFFSET 13 +#define RTL8367C_PORT9_QUEUE5_TYPE_MASK 0x2000 +#define RTL8367C_PORT9_QUEUE4_TYPE_OFFSET 12 +#define RTL8367C_PORT9_QUEUE4_TYPE_MASK 0x1000 +#define RTL8367C_PORT9_QUEUE3_TYPE_OFFSET 11 +#define RTL8367C_PORT9_QUEUE3_TYPE_MASK 0x800 +#define RTL8367C_PORT9_QUEUE2_TYPE_OFFSET 10 +#define RTL8367C_PORT9_QUEUE2_TYPE_MASK 0x400 +#define RTL8367C_PORT9_QUEUE1_TYPE_OFFSET 9 +#define RTL8367C_PORT9_QUEUE1_TYPE_MASK 0x200 +#define RTL8367C_PORT9_QUEUE0_TYPE_OFFSET 8 +#define RTL8367C_PORT9_QUEUE0_TYPE_MASK 0x100 +#define RTL8367C_PORT8_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT8_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT8_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT8_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT8_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT8_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT8_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT8_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT8_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT8_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT8_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT8_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT8_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT8_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL5 0x0307 +#define RTL8367C_PORT10_QUEUE7_TYPE_OFFSET 7 +#define RTL8367C_PORT10_QUEUE7_TYPE_MASK 0x80 +#define RTL8367C_PORT10_QUEUE6_TYPE_OFFSET 6 +#define RTL8367C_PORT10_QUEUE6_TYPE_MASK 0x40 +#define RTL8367C_PORT10_QUEUE5_TYPE_OFFSET 5 +#define RTL8367C_PORT10_QUEUE5_TYPE_MASK 0x20 +#define RTL8367C_PORT10_QUEUE4_TYPE_OFFSET 4 +#define RTL8367C_PORT10_QUEUE4_TYPE_MASK 0x10 +#define RTL8367C_PORT10_QUEUE3_TYPE_OFFSET 3 +#define RTL8367C_PORT10_QUEUE3_TYPE_MASK 0x8 +#define RTL8367C_PORT10_QUEUE2_TYPE_OFFSET 2 +#define RTL8367C_PORT10_QUEUE2_TYPE_MASK 0x4 +#define RTL8367C_PORT10_QUEUE1_TYPE_OFFSET 1 +#define RTL8367C_PORT10_QUEUE1_TYPE_MASK 0x2 +#define RTL8367C_PORT10_QUEUE0_TYPE_OFFSET 0 +#define RTL8367C_PORT10_QUEUE0_TYPE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_APR_CTRL0 0x030a +#define RTL8367C_PORT10_APR_ENABLE_OFFSET 10 +#define RTL8367C_PORT10_APR_ENABLE_MASK 0x400 +#define RTL8367C_PORT9_APR_ENABLE_OFFSET 9 +#define RTL8367C_PORT9_APR_ENABLE_MASK 0x200 +#define RTL8367C_PORT8_APR_ENABLE_OFFSET 8 +#define RTL8367C_PORT8_APR_ENABLE_MASK 0x100 +#define RTL8367C_PORT7_APR_ENABLE_OFFSET 7 +#define RTL8367C_PORT7_APR_ENABLE_MASK 0x80 +#define RTL8367C_PORT6_APR_ENABLE_OFFSET 6 +#define RTL8367C_PORT6_APR_ENABLE_MASK 0x40 +#define RTL8367C_PORT5_APR_ENABLE_OFFSET 5 +#define RTL8367C_PORT5_APR_ENABLE_MASK 0x20 +#define RTL8367C_PORT4_APR_ENABLE_OFFSET 4 +#define RTL8367C_PORT4_APR_ENABLE_MASK 0x10 +#define RTL8367C_PORT3_APR_ENABLE_OFFSET 3 +#define RTL8367C_PORT3_APR_ENABLE_MASK 0x8 +#define RTL8367C_PORT2_APR_ENABLE_OFFSET 2 +#define RTL8367C_PORT2_APR_ENABLE_MASK 0x4 +#define RTL8367C_PORT1_APR_ENABLE_OFFSET 1 +#define RTL8367C_PORT1_APR_ENABLE_MASK 0x2 +#define RTL8367C_PORT0_APR_ENABLE_OFFSET 0 +#define RTL8367C_PORT0_APR_ENABLE_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT 0x030c + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT 0x030d +#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT 0x030e +#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT 0x030f +#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT 0x0310 +#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT 0x0311 +#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT 0x0312 +#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT 0x0313 +#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE0_WFQ_WEIGHT 0x0314 + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT 0x0315 +#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT 0x0316 +#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT 0x0317 +#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT 0x0318 +#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT 0x0319 +#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT 0x031a +#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT 0x031b +#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE0_WFQ_WEIGHT 0x031c + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT 0x031d +#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT 0x031e +#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT 0x031f +#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT 0x0320 +#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT 0x0321 +#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT 0x0322 +#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT 0x0323 +#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE0_WFQ_WEIGHT 0x0324 + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT 0x0325 +#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT 0x0326 +#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT 0x0327 +#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT 0x0328 +#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT 0x0329 +#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT 0x032a +#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT 0x032b +#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE0_WFQ_WEIGHT 0x032c + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT 0x032d +#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT 0x032e +#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT 0x032f +#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT 0x0330 +#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT 0x0331 +#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT 0x0332 +#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT 0x0333 +#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE0_WFQ_WEIGHT 0x0334 + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT 0x0335 +#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT 0x0336 +#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT 0x0337 +#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT 0x0338 +#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT 0x0339 +#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT 0x033a +#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT 0x033b +#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE0_WFQ_WEIGHT 0x033c + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT 0x033d +#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT 0x033e +#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT 0x033f +#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT 0x0340 +#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT 0x0341 +#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT 0x0342 +#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT 0x0343 +#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE0_WFQ_WEIGHT 0x0344 + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT 0x0345 +#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT 0x0346 +#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT 0x0347 +#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT 0x0348 +#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT 0x0349 +#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT 0x034a +#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT 0x034b +#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE0_WFQ_WEIGHT 0x034c + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT 0x034d +#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT 0x034e +#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT 0x034f +#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT 0x0350 +#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT 0x0351 +#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT 0x0352 +#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT 0x0353 +#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE0_WFQ_WEIGHT 0x0354 + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT 0x0355 +#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT 0x0356 +#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT 0x0357 +#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT 0x0358 +#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT 0x0359 +#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT 0x035a +#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT 0x035b +#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE0_WFQ_WEIGHT 0x035c + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT 0x035d +#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT 0x035e +#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT 0x035f +#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT 0x0360 +#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT 0x0361 +#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT 0x0362 +#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT 0x0363 +#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_MASK 0x7F + +#define RTL8367C_REG_PORT0_EGRESSBW_CTRL0 0x038c + +#define RTL8367C_REG_PORT0_EGRESSBW_CTRL1 0x038d +#define RTL8367C_PORT0_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT0_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT1_EGRESSBW_CTRL0 0x038e + +#define RTL8367C_REG_PORT1_EGRESSBW_CTRL1 0x038f +#define RTL8367C_PORT1_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT1_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT2_EGRESSBW_CTRL0 0x0390 + +#define RTL8367C_REG_PORT2_EGRESSBW_CTRL1 0x0391 +#define RTL8367C_PORT2_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT2_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT3_EGRESSBW_CTRL0 0x0392 + +#define RTL8367C_REG_PORT3_EGRESSBW_CTRL1 0x0393 +#define RTL8367C_PORT3_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT3_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT4_EGRESSBW_CTRL0 0x0394 + +#define RTL8367C_REG_PORT4_EGRESSBW_CTRL1 0x0395 +#define RTL8367C_PORT4_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT4_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT5_EGRESSBW_CTRL0 0x0396 + +#define RTL8367C_REG_PORT5_EGRESSBW_CTRL1 0x0397 +#define RTL8367C_PORT5_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT5_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT6_EGRESSBW_CTRL0 0x0398 + +#define RTL8367C_REG_PORT6_EGRESSBW_CTRL1 0x0399 +#define RTL8367C_PORT6_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT6_EGRESSBW_CTRL1_MASK 0x7 + +#define RTL8367C_REG_PORT7_EGRESSBW_CTRL0 0x039a + +#define RTL8367C_REG_PORT7_EGRESSBW_CTRL1 0x039b +#define RTL8367C_PORT7_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT7_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT8_EGRESSBW_CTRL0 0x039c + +#define RTL8367C_REG_PORT8_EGRESSBW_CTRL1 0x039d +#define RTL8367C_PORT8_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT8_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_PORT9_EGRESSBW_CTRL0 0x039e + +#define RTL8367C_REG_PORT9_EGRESSBW_CTRL1 0x039f +#define RTL8367C_PORT9_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT9_EGRESSBW_CTRL1_MASK 0x7 + +#define RTL8367C_REG_PORT10_EGRESSBW_CTRL0 0x03a0 + +#define RTL8367C_REG_PORT10_EGRESSBW_CTRL1 0x03a1 +#define RTL8367C_PORT10_EGRESSBW_CTRL1_OFFSET 0 +#define RTL8367C_PORT10_EGRESSBW_CTRL1_MASK 0x1 + +#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 0x03ac +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL1 0x03ad +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL0 0x03b0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL1 0x03b1 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL0 0x03b4 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL1 0x03b5 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL0 0x03b8 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL1 0x03b9 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL0 0x03bc +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL1 0x03bd +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL0 0x03c0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL1 0x03c1 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL0 0x03c4 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL1 0x03c5 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL0 0x03c8 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL1 0x03c9 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 0x03ca +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL1 0x03cb +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL0 0x03cc +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL1 0x03cd +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL0 0x03ce +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 + +#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL1 0x03cf +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 +#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 + +#define RTL8367C_REG_LINE_RATE_1G_L 0x03ec + +#define RTL8367C_REG_LINE_RATE_1G_H 0x03ed +#define RTL8367C_LINE_RATE_1G_H_OFFSET 0 +#define RTL8367C_LINE_RATE_1G_H_MASK 0x1 + +#define RTL8367C_REG_LINE_RATE_100_L 0x03ee + +#define RTL8367C_REG_LINE_RATE_100_H 0x03ef +#define RTL8367C_LINE_RATE_100_H_OFFSET 0 +#define RTL8367C_LINE_RATE_100_H_MASK 0x1 + +#define RTL8367C_REG_LINE_RATE_10_L 0x03f0 + +#define RTL8367C_REG_LINE_RATE_10_H 0x03f1 +#define RTL8367C_LINE_RATE_10_H_OFFSET 0 +#define RTL8367C_LINE_RATE_10_H_MASK 0x1 + +#define RTL8367C_REG_DUMMY_03f2 0x03f2 + +#define RTL8367C_REG_DUMMY_03f3 0x03f3 + +#define RTL8367C_REG_DUMMY_03f4 0x03f4 + +#define RTL8367C_REG_DUMMY_03f5 0x03f5 + +#define RTL8367C_REG_DUMMY_03f6 0x03f6 + +#define RTL8367C_REG_BYPASS_LINE_RATE 0x03f7 +#define RTL8367C_BYPASS_PORT10_CONSTRAINT_OFFSET 5 +#define RTL8367C_BYPASS_PORT10_CONSTRAINT_MASK 0x20 +#define RTL8367C_BYPASS_PORT9_CONSTRAINT_OFFSET 4 +#define RTL8367C_BYPASS_PORT9_CONSTRAINT_MASK 0x10 +#define RTL8367C_BYPASS_PORT8_CONSTRAINT_OFFSET 3 +#define RTL8367C_BYPASS_PORT8_CONSTRAINT_MASK 0x8 +#define RTL8367C_BYPASS_PORT7_CONSTRAINT_OFFSET 2 +#define RTL8367C_BYPASS_PORT7_CONSTRAINT_MASK 0x4 +#define RTL8367C_BYPASS_PORT6_CONSTRAINT_OFFSET 1 +#define RTL8367C_BYPASS_PORT6_CONSTRAINT_MASK 0x2 +#define RTL8367C_BYPASS_PORT5_CONSTRAINT_OFFSET 0 +#define RTL8367C_BYPASS_PORT5_CONSTRAINT_MASK 0x1 + +#define RTL8367C_REG_LINE_RATE_500_H 0x03f8 +#define RTL8367C_LINE_RATE_500_H_OFFSET 0 +#define RTL8367C_LINE_RATE_500_H_MASK 0x7 + +#define RTL8367C_REG_LINE_RATE_500_L 0x03f9 + +#define RTL8367C_REG_LINE_RATE_HSG_H 0x03fa +#define RTL8367C_LINE_RATE_HSG_H_OFFSET 0 +#define RTL8367C_LINE_RATE_HSG_H_MASK 0x7 + +#define RTL8367C_REG_LINE_RATE_HSG_L 0x03fb + +/* (16'h0500)table_reg */ + +#define RTL8367C_REG_TABLE_ACCESS_CTRL 0x0500 +#define RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET 8 +#define RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK 0xF00 +#define RTL8367C_ACCESS_METHOD_OFFSET 4 +#define RTL8367C_ACCESS_METHOD_MASK 0x70 +#define RTL8367C_COMMAND_TYPE_OFFSET 3 +#define RTL8367C_COMMAND_TYPE_MASK 0x8 +#define RTL8367C_TABLE_TYPE_OFFSET 0 +#define RTL8367C_TABLE_TYPE_MASK 0x7 + +#define RTL8367C_REG_TABLE_ACCESS_ADDR 0x0501 +#define RTL8367C_TABLE_ACCESS_ADDR_OFFSET 0 +#define RTL8367C_TABLE_ACCESS_ADDR_MASK 0x1FFF + +#define RTL8367C_REG_TABLE_LUT_ADDR 0x0502 +#define RTL8367C_ADDRESS2_OFFSET 14 +#define RTL8367C_ADDRESS2_MASK 0x4000 +#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET 13 +#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_MASK 0x2000 +#define RTL8367C_HIT_STATUS_OFFSET 12 +#define RTL8367C_HIT_STATUS_MASK 0x1000 +#define RTL8367C_TABLE_LUT_ADDR_TYPE_OFFSET 11 +#define RTL8367C_TABLE_LUT_ADDR_TYPE_MASK 0x800 +#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_OFFSET 0 +#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK 0x7FF + +#define RTL8367C_REG_HSA_HSB_LATCH 0x0503 +#define RTL8367C_LATCH_ALWAYS_OFFSET 15 +#define RTL8367C_LATCH_ALWAYS_MASK 0x8000 +#define RTL8367C_LATCH_FIRST_OFFSET 14 +#define RTL8367C_LATCH_FIRST_MASK 0x4000 +#define RTL8367C_SPA_EN_OFFSET 13 +#define RTL8367C_SPA_EN_MASK 0x2000 +#define RTL8367C_FORWARD_EN_OFFSET 12 +#define RTL8367C_FORWARD_EN_MASK 0x1000 +#define RTL8367C_REASON_EN_OFFSET 11 +#define RTL8367C_REASON_EN_MASK 0x800 +#define RTL8367C_HSA_HSB_LATCH_SPA_OFFSET 8 +#define RTL8367C_HSA_HSB_LATCH_SPA_MASK 0x700 +#define RTL8367C_FORWARD_OFFSET 6 +#define RTL8367C_FORWARD_MASK 0xC0 +#define RTL8367C_REASON_OFFSET 0 +#define RTL8367C_REASON_MASK 0x3F + +#define RTL8367C_REG_HSA_HSB_LATCH2 0x0504 +#define RTL8367C_HSA_HSB_LATCH2_Reserved_OFFSET 1 +#define RTL8367C_HSA_HSB_LATCH2_Reserved_MASK 0xFFFE +#define RTL8367C_SPA2_OFFSET 0 +#define RTL8367C_SPA2_MASK 0x1 + +#define RTL8367C_REG_TABLE_WRITE_DATA0 0x0510 + +#define RTL8367C_REG_TABLE_WRITE_DATA1 0x0511 + +#define RTL8367C_REG_TABLE_WRITE_DATA2 0x0512 + +#define RTL8367C_REG_TABLE_WRITE_DATA3 0x0513 + +#define RTL8367C_REG_TABLE_WRITE_DATA4 0x0514 + +#define RTL8367C_REG_TABLE_WRITE_DATA5 0x0515 + +#define RTL8367C_REG_TABLE_WRITE_DATA6 0x0516 + +#define RTL8367C_REG_TABLE_WRITE_DATA7 0x0517 + +#define RTL8367C_REG_TABLE_WRITE_DATA8 0x0518 + +#define RTL8367C_REG_TABLE_WRITE_DATA9 0x0519 +#define RTL8367C_TABLE_WRITE_DATA9_OFFSET 0 +#define RTL8367C_TABLE_WRITE_DATA9_MASK 0xF + +#define RTL8367C_REG_TABLE_READ_DATA0 0x0520 + +#define RTL8367C_REG_TABLE_READ_DATA1 0x0521 + +#define RTL8367C_REG_TABLE_READ_DATA2 0x0522 + +#define RTL8367C_REG_TABLE_READ_DATA3 0x0523 + +#define RTL8367C_REG_TABLE_READ_DATA4 0x0524 + +#define RTL8367C_REG_TABLE_READ_DATA5 0x0525 + +#define RTL8367C_REG_TABLE_READ_DATA6 0x0526 + +#define RTL8367C_REG_TABLE_READ_DATA7 0x0527 + +#define RTL8367C_REG_TABLE_READ_DATA8 0x0528 + +#define RTL8367C_REG_TABLE_READ_DATA9 0x0529 +#define RTL8367C_TABLE_READ_DATA9_OFFSET 0 +#define RTL8367C_TABLE_READ_DATA9_MASK 0xF + +#define RTL8367C_REG_TBL_DUMMY00 0x0550 + +#define RTL8367C_REG_TBL_DUMMY01 0x0551 + +/* (16'h0600)acl_reg */ + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 0x0600 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL1 0x0601 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL2 0x0602 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL3 0x0603 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL0 0x0604 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL1 0x0605 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL2 0x0606 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL3 0x0607 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL0 0x0608 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL1 0x0609 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL2 0x060a +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL3 0x060b +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL0 0x060c +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL1 0x060d +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL2 0x060e +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL3 0x060f +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL0 0x0610 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL1 0x0611 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL2 0x0612 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_MASK 0x7F + +#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL3 0x0613 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_OFFSET 8 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_MASK 0x7F00 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_OFFSET 0 +#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_MASK 0x7F + +#define RTL8367C_REG_ACL_ACTION_CTRL0 0x0614 +#define RTL8367C_OP1_NOT_OFFSET 14 +#define RTL8367C_OP1_NOT_MASK 0x4000 +#define RTL8367C_ACT1_GPIO_OFFSET 13 +#define RTL8367C_ACT1_GPIO_MASK 0x2000 +#define RTL8367C_ACT1_FORWARD_OFFSET 12 +#define RTL8367C_ACT1_FORWARD_MASK 0x1000 +#define RTL8367C_ACT1_POLICING_OFFSET 11 +#define RTL8367C_ACT1_POLICING_MASK 0x800 +#define RTL8367C_ACT1_PRIORITY_OFFSET 10 +#define RTL8367C_ACT1_PRIORITY_MASK 0x400 +#define RTL8367C_ACT1_SVID_OFFSET 9 +#define RTL8367C_ACT1_SVID_MASK 0x200 +#define RTL8367C_ACT1_CVID_OFFSET 8 +#define RTL8367C_ACT1_CVID_MASK 0x100 +#define RTL8367C_OP0_NOT_OFFSET 6 +#define RTL8367C_OP0_NOT_MASK 0x40 +#define RTL8367C_ACT0_GPIO_OFFSET 5 +#define RTL8367C_ACT0_GPIO_MASK 0x20 +#define RTL8367C_ACT0_FORWARD_OFFSET 4 +#define RTL8367C_ACT0_FORWARD_MASK 0x10 +#define RTL8367C_ACT0_POLICING_OFFSET 3 +#define RTL8367C_ACT0_POLICING_MASK 0x8 +#define RTL8367C_ACT0_PRIORITY_OFFSET 2 +#define RTL8367C_ACT0_PRIORITY_MASK 0x4 +#define RTL8367C_ACT0_SVID_OFFSET 1 +#define RTL8367C_ACT0_SVID_MASK 0x2 +#define RTL8367C_ACT0_CVID_OFFSET 0 +#define RTL8367C_ACT0_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL1 0x0615 +#define RTL8367C_OP3_NOT_OFFSET 14 +#define RTL8367C_OP3_NOT_MASK 0x4000 +#define RTL8367C_ACT3_GPIO_OFFSET 13 +#define RTL8367C_ACT3_GPIO_MASK 0x2000 +#define RTL8367C_ACT3_FORWARD_OFFSET 12 +#define RTL8367C_ACT3_FORWARD_MASK 0x1000 +#define RTL8367C_ACT3_POLICING_OFFSET 11 +#define RTL8367C_ACT3_POLICING_MASK 0x800 +#define RTL8367C_ACT3_PRIORITY_OFFSET 10 +#define RTL8367C_ACT3_PRIORITY_MASK 0x400 +#define RTL8367C_ACT3_SVID_OFFSET 9 +#define RTL8367C_ACT3_SVID_MASK 0x200 +#define RTL8367C_ACT3_CVID_OFFSET 8 +#define RTL8367C_ACT3_CVID_MASK 0x100 +#define RTL8367C_OP2_NOT_OFFSET 6 +#define RTL8367C_OP2_NOT_MASK 0x40 +#define RTL8367C_ACT2_GPIO_OFFSET 5 +#define RTL8367C_ACT2_GPIO_MASK 0x20 +#define RTL8367C_ACT2_FORWARD_OFFSET 4 +#define RTL8367C_ACT2_FORWARD_MASK 0x10 +#define RTL8367C_ACT2_POLICING_OFFSET 3 +#define RTL8367C_ACT2_POLICING_MASK 0x8 +#define RTL8367C_ACT2_PRIORITY_OFFSET 2 +#define RTL8367C_ACT2_PRIORITY_MASK 0x4 +#define RTL8367C_ACT2_SVID_OFFSET 1 +#define RTL8367C_ACT2_SVID_MASK 0x2 +#define RTL8367C_ACT2_CVID_OFFSET 0 +#define RTL8367C_ACT2_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL2 0x0616 +#define RTL8367C_OP5_NOT_OFFSET 14 +#define RTL8367C_OP5_NOT_MASK 0x4000 +#define RTL8367C_ACT5_GPIO_OFFSET 13 +#define RTL8367C_ACT5_GPIO_MASK 0x2000 +#define RTL8367C_ACT5_FORWARD_OFFSET 12 +#define RTL8367C_ACT5_FORWARD_MASK 0x1000 +#define RTL8367C_ACT5_POLICING_OFFSET 11 +#define RTL8367C_ACT5_POLICING_MASK 0x800 +#define RTL8367C_ACT5_PRIORITY_OFFSET 10 +#define RTL8367C_ACT5_PRIORITY_MASK 0x400 +#define RTL8367C_ACT5_SVID_OFFSET 9 +#define RTL8367C_ACT5_SVID_MASK 0x200 +#define RTL8367C_ACT5_CVID_OFFSET 8 +#define RTL8367C_ACT5_CVID_MASK 0x100 +#define RTL8367C_OP4_NOT_OFFSET 6 +#define RTL8367C_OP4_NOT_MASK 0x40 +#define RTL8367C_ACT4_GPIO_OFFSET 5 +#define RTL8367C_ACT4_GPIO_MASK 0x20 +#define RTL8367C_ACT4_FORWARD_OFFSET 4 +#define RTL8367C_ACT4_FORWARD_MASK 0x10 +#define RTL8367C_ACT4_POLICING_OFFSET 3 +#define RTL8367C_ACT4_POLICING_MASK 0x8 +#define RTL8367C_ACT4_PRIORITY_OFFSET 2 +#define RTL8367C_ACT4_PRIORITY_MASK 0x4 +#define RTL8367C_ACT4_SVID_OFFSET 1 +#define RTL8367C_ACT4_SVID_MASK 0x2 +#define RTL8367C_ACT4_CVID_OFFSET 0 +#define RTL8367C_ACT4_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL3 0x0617 +#define RTL8367C_OP7_NOT_OFFSET 14 +#define RTL8367C_OP7_NOT_MASK 0x4000 +#define RTL8367C_ACT7_GPIO_OFFSET 13 +#define RTL8367C_ACT7_GPIO_MASK 0x2000 +#define RTL8367C_ACT7_FORWARD_OFFSET 12 +#define RTL8367C_ACT7_FORWARD_MASK 0x1000 +#define RTL8367C_ACT7_POLICING_OFFSET 11 +#define RTL8367C_ACT7_POLICING_MASK 0x800 +#define RTL8367C_ACT7_PRIORITY_OFFSET 10 +#define RTL8367C_ACT7_PRIORITY_MASK 0x400 +#define RTL8367C_ACT7_SVID_OFFSET 9 +#define RTL8367C_ACT7_SVID_MASK 0x200 +#define RTL8367C_ACT7_CVID_OFFSET 8 +#define RTL8367C_ACT7_CVID_MASK 0x100 +#define RTL8367C_OP6_NOT_OFFSET 6 +#define RTL8367C_OP6_NOT_MASK 0x40 +#define RTL8367C_ACT6_GPIO_OFFSET 5 +#define RTL8367C_ACT6_GPIO_MASK 0x20 +#define RTL8367C_ACT6_FORWARD_OFFSET 4 +#define RTL8367C_ACT6_FORWARD_MASK 0x10 +#define RTL8367C_ACT6_POLICING_OFFSET 3 +#define RTL8367C_ACT6_POLICING_MASK 0x8 +#define RTL8367C_ACT6_PRIORITY_OFFSET 2 +#define RTL8367C_ACT6_PRIORITY_MASK 0x4 +#define RTL8367C_ACT6_SVID_OFFSET 1 +#define RTL8367C_ACT6_SVID_MASK 0x2 +#define RTL8367C_ACT6_CVID_OFFSET 0 +#define RTL8367C_ACT6_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL4 0x0618 +#define RTL8367C_OP9_NOT_OFFSET 14 +#define RTL8367C_OP9_NOT_MASK 0x4000 +#define RTL8367C_ACT9_GPIO_OFFSET 13 +#define RTL8367C_ACT9_GPIO_MASK 0x2000 +#define RTL8367C_ACT9_FORWARD_OFFSET 12 +#define RTL8367C_ACT9_FORWARD_MASK 0x1000 +#define RTL8367C_ACT9_POLICING_OFFSET 11 +#define RTL8367C_ACT9_POLICING_MASK 0x800 +#define RTL8367C_ACT9_PRIORITY_OFFSET 10 +#define RTL8367C_ACT9_PRIORITY_MASK 0x400 +#define RTL8367C_ACT9_SVID_OFFSET 9 +#define RTL8367C_ACT9_SVID_MASK 0x200 +#define RTL8367C_ACT9_CVID_OFFSET 8 +#define RTL8367C_ACT9_CVID_MASK 0x100 +#define RTL8367C_OP8_NOT_OFFSET 6 +#define RTL8367C_OP8_NOT_MASK 0x40 +#define RTL8367C_ACT8_GPIO_OFFSET 5 +#define RTL8367C_ACT8_GPIO_MASK 0x20 +#define RTL8367C_ACT8_FORWARD_OFFSET 4 +#define RTL8367C_ACT8_FORWARD_MASK 0x10 +#define RTL8367C_ACT8_POLICING_OFFSET 3 +#define RTL8367C_ACT8_POLICING_MASK 0x8 +#define RTL8367C_ACT8_PRIORITY_OFFSET 2 +#define RTL8367C_ACT8_PRIORITY_MASK 0x4 +#define RTL8367C_ACT8_SVID_OFFSET 1 +#define RTL8367C_ACT8_SVID_MASK 0x2 +#define RTL8367C_ACT8_CVID_OFFSET 0 +#define RTL8367C_ACT8_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL5 0x0619 +#define RTL8367C_OP11_NOT_OFFSET 14 +#define RTL8367C_OP11_NOT_MASK 0x4000 +#define RTL8367C_ACT11_GPIO_OFFSET 13 +#define RTL8367C_ACT11_GPIO_MASK 0x2000 +#define RTL8367C_ACT11_FORWARD_OFFSET 12 +#define RTL8367C_ACT11_FORWARD_MASK 0x1000 +#define RTL8367C_ACT11_POLICING_OFFSET 11 +#define RTL8367C_ACT11_POLICING_MASK 0x800 +#define RTL8367C_ACT11_PRIORITY_OFFSET 10 +#define RTL8367C_ACT11_PRIORITY_MASK 0x400 +#define RTL8367C_ACT11_SVID_OFFSET 9 +#define RTL8367C_ACT11_SVID_MASK 0x200 +#define RTL8367C_ACT11_CVID_OFFSET 8 +#define RTL8367C_ACT11_CVID_MASK 0x100 +#define RTL8367C_OP10_NOT_OFFSET 6 +#define RTL8367C_OP10_NOT_MASK 0x40 +#define RTL8367C_ACT10_GPIO_OFFSET 5 +#define RTL8367C_ACT10_GPIO_MASK 0x20 +#define RTL8367C_ACT10_FORWARD_OFFSET 4 +#define RTL8367C_ACT10_FORWARD_MASK 0x10 +#define RTL8367C_ACT10_POLICING_OFFSET 3 +#define RTL8367C_ACT10_POLICING_MASK 0x8 +#define RTL8367C_ACT10_PRIORITY_OFFSET 2 +#define RTL8367C_ACT10_PRIORITY_MASK 0x4 +#define RTL8367C_ACT10_SVID_OFFSET 1 +#define RTL8367C_ACT10_SVID_MASK 0x2 +#define RTL8367C_ACT10_CVID_OFFSET 0 +#define RTL8367C_ACT10_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL6 0x061a +#define RTL8367C_OP13_NOT_OFFSET 14 +#define RTL8367C_OP13_NOT_MASK 0x4000 +#define RTL8367C_ACT13_GPIO_OFFSET 13 +#define RTL8367C_ACT13_GPIO_MASK 0x2000 +#define RTL8367C_ACT13_FORWARD_OFFSET 12 +#define RTL8367C_ACT13_FORWARD_MASK 0x1000 +#define RTL8367C_ACT13_POLICING_OFFSET 11 +#define RTL8367C_ACT13_POLICING_MASK 0x800 +#define RTL8367C_ACT13_PRIORITY_OFFSET 10 +#define RTL8367C_ACT13_PRIORITY_MASK 0x400 +#define RTL8367C_ACT13_SVID_OFFSET 9 +#define RTL8367C_ACT13_SVID_MASK 0x200 +#define RTL8367C_ACT13_CVID_OFFSET 8 +#define RTL8367C_ACT13_CVID_MASK 0x100 +#define RTL8367C_OP12_NOT_OFFSET 6 +#define RTL8367C_OP12_NOT_MASK 0x40 +#define RTL8367C_ACT12_GPIO_OFFSET 5 +#define RTL8367C_ACT12_GPIO_MASK 0x20 +#define RTL8367C_ACT12_FORWARD_OFFSET 4 +#define RTL8367C_ACT12_FORWARD_MASK 0x10 +#define RTL8367C_ACT12_POLICING_OFFSET 3 +#define RTL8367C_ACT12_POLICING_MASK 0x8 +#define RTL8367C_ACT12_PRIORITY_OFFSET 2 +#define RTL8367C_ACT12_PRIORITY_MASK 0x4 +#define RTL8367C_ACT12_SVID_OFFSET 1 +#define RTL8367C_ACT12_SVID_MASK 0x2 +#define RTL8367C_ACT12_CVID_OFFSET 0 +#define RTL8367C_ACT12_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL7 0x061b +#define RTL8367C_OP15_NOT_OFFSET 14 +#define RTL8367C_OP15_NOT_MASK 0x4000 +#define RTL8367C_ACT15_GPIO_OFFSET 13 +#define RTL8367C_ACT15_GPIO_MASK 0x2000 +#define RTL8367C_ACT15_FORWARD_OFFSET 12 +#define RTL8367C_ACT15_FORWARD_MASK 0x1000 +#define RTL8367C_ACT15_POLICING_OFFSET 11 +#define RTL8367C_ACT15_POLICING_MASK 0x800 +#define RTL8367C_ACT15_PRIORITY_OFFSET 10 +#define RTL8367C_ACT15_PRIORITY_MASK 0x400 +#define RTL8367C_ACT15_SVID_OFFSET 9 +#define RTL8367C_ACT15_SVID_MASK 0x200 +#define RTL8367C_ACT15_CVID_OFFSET 8 +#define RTL8367C_ACT15_CVID_MASK 0x100 +#define RTL8367C_OP14_NOT_OFFSET 6 +#define RTL8367C_OP14_NOT_MASK 0x40 +#define RTL8367C_ACT14_GPIO_OFFSET 5 +#define RTL8367C_ACT14_GPIO_MASK 0x20 +#define RTL8367C_ACT14_FORWARD_OFFSET 4 +#define RTL8367C_ACT14_FORWARD_MASK 0x10 +#define RTL8367C_ACT14_POLICING_OFFSET 3 +#define RTL8367C_ACT14_POLICING_MASK 0x8 +#define RTL8367C_ACT14_PRIORITY_OFFSET 2 +#define RTL8367C_ACT14_PRIORITY_MASK 0x4 +#define RTL8367C_ACT14_SVID_OFFSET 1 +#define RTL8367C_ACT14_SVID_MASK 0x2 +#define RTL8367C_ACT14_CVID_OFFSET 0 +#define RTL8367C_ACT14_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL8 0x061c +#define RTL8367C_OP17_NOT_OFFSET 14 +#define RTL8367C_OP17_NOT_MASK 0x4000 +#define RTL8367C_ACT17_GPIO_OFFSET 13 +#define RTL8367C_ACT17_GPIO_MASK 0x2000 +#define RTL8367C_ACT17_FORWARD_OFFSET 12 +#define RTL8367C_ACT17_FORWARD_MASK 0x1000 +#define RTL8367C_ACT17_POLICING_OFFSET 11 +#define RTL8367C_ACT17_POLICING_MASK 0x800 +#define RTL8367C_ACT17_PRIORITY_OFFSET 10 +#define RTL8367C_ACT17_PRIORITY_MASK 0x400 +#define RTL8367C_ACT17_SVID_OFFSET 9 +#define RTL8367C_ACT17_SVID_MASK 0x200 +#define RTL8367C_ACT17_CVID_OFFSET 8 +#define RTL8367C_ACT17_CVID_MASK 0x100 +#define RTL8367C_OP16_NOT_OFFSET 6 +#define RTL8367C_OP16_NOT_MASK 0x40 +#define RTL8367C_ACT16_GPIO_OFFSET 5 +#define RTL8367C_ACT16_GPIO_MASK 0x20 +#define RTL8367C_ACT16_FORWARD_OFFSET 4 +#define RTL8367C_ACT16_FORWARD_MASK 0x10 +#define RTL8367C_ACT16_POLICING_OFFSET 3 +#define RTL8367C_ACT16_POLICING_MASK 0x8 +#define RTL8367C_ACT16_PRIORITY_OFFSET 2 +#define RTL8367C_ACT16_PRIORITY_MASK 0x4 +#define RTL8367C_ACT16_SVID_OFFSET 1 +#define RTL8367C_ACT16_SVID_MASK 0x2 +#define RTL8367C_ACT16_CVID_OFFSET 0 +#define RTL8367C_ACT16_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL9 0x061d +#define RTL8367C_OP19_NOT_OFFSET 14 +#define RTL8367C_OP19_NOT_MASK 0x4000 +#define RTL8367C_ACT19_GPIO_OFFSET 13 +#define RTL8367C_ACT19_GPIO_MASK 0x2000 +#define RTL8367C_ACT19_FORWARD_OFFSET 12 +#define RTL8367C_ACT19_FORWARD_MASK 0x1000 +#define RTL8367C_ACT19_POLICING_OFFSET 11 +#define RTL8367C_ACT19_POLICING_MASK 0x800 +#define RTL8367C_ACT19_PRIORITY_OFFSET 10 +#define RTL8367C_ACT19_PRIORITY_MASK 0x400 +#define RTL8367C_ACT19_SVID_OFFSET 9 +#define RTL8367C_ACT19_SVID_MASK 0x200 +#define RTL8367C_ACT19_CVID_OFFSET 8 +#define RTL8367C_ACT19_CVID_MASK 0x100 +#define RTL8367C_OP18_NOT_OFFSET 6 +#define RTL8367C_OP18_NOT_MASK 0x40 +#define RTL8367C_ACT18_GPIO_OFFSET 5 +#define RTL8367C_ACT18_GPIO_MASK 0x20 +#define RTL8367C_ACT18_FORWARD_OFFSET 4 +#define RTL8367C_ACT18_FORWARD_MASK 0x10 +#define RTL8367C_ACT18_POLICING_OFFSET 3 +#define RTL8367C_ACT18_POLICING_MASK 0x8 +#define RTL8367C_ACT18_PRIORITY_OFFSET 2 +#define RTL8367C_ACT18_PRIORITY_MASK 0x4 +#define RTL8367C_ACT18_SVID_OFFSET 1 +#define RTL8367C_ACT18_SVID_MASK 0x2 +#define RTL8367C_ACT18_CVID_OFFSET 0 +#define RTL8367C_ACT18_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL10 0x061e +#define RTL8367C_OP21_NOT_OFFSET 14 +#define RTL8367C_OP21_NOT_MASK 0x4000 +#define RTL8367C_ACT21_GPIO_OFFSET 13 +#define RTL8367C_ACT21_GPIO_MASK 0x2000 +#define RTL8367C_ACT21_FORWARD_OFFSET 12 +#define RTL8367C_ACT21_FORWARD_MASK 0x1000 +#define RTL8367C_ACT21_POLICING_OFFSET 11 +#define RTL8367C_ACT21_POLICING_MASK 0x800 +#define RTL8367C_ACT21_PRIORITY_OFFSET 10 +#define RTL8367C_ACT21_PRIORITY_MASK 0x400 +#define RTL8367C_ACT21_SVID_OFFSET 9 +#define RTL8367C_ACT21_SVID_MASK 0x200 +#define RTL8367C_ACT21_CVID_OFFSET 8 +#define RTL8367C_ACT21_CVID_MASK 0x100 +#define RTL8367C_OP20_NOT_OFFSET 6 +#define RTL8367C_OP20_NOT_MASK 0x40 +#define RTL8367C_ACT20_GPIO_OFFSET 5 +#define RTL8367C_ACT20_GPIO_MASK 0x20 +#define RTL8367C_ACT20_FORWARD_OFFSET 4 +#define RTL8367C_ACT20_FORWARD_MASK 0x10 +#define RTL8367C_ACT20_POLICING_OFFSET 3 +#define RTL8367C_ACT20_POLICING_MASK 0x8 +#define RTL8367C_ACT20_PRIORITY_OFFSET 2 +#define RTL8367C_ACT20_PRIORITY_MASK 0x4 +#define RTL8367C_ACT20_SVID_OFFSET 1 +#define RTL8367C_ACT20_SVID_MASK 0x2 +#define RTL8367C_ACT20_CVID_OFFSET 0 +#define RTL8367C_ACT20_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL11 0x061f +#define RTL8367C_OP23_NOT_OFFSET 14 +#define RTL8367C_OP23_NOT_MASK 0x4000 +#define RTL8367C_ACT23_GPIO_OFFSET 13 +#define RTL8367C_ACT23_GPIO_MASK 0x2000 +#define RTL8367C_ACT23_FORWARD_OFFSET 12 +#define RTL8367C_ACT23_FORWARD_MASK 0x1000 +#define RTL8367C_ACT23_POLICING_OFFSET 11 +#define RTL8367C_ACT23_POLICING_MASK 0x800 +#define RTL8367C_ACT23_PRIORITY_OFFSET 10 +#define RTL8367C_ACT23_PRIORITY_MASK 0x400 +#define RTL8367C_ACT23_SVID_OFFSET 9 +#define RTL8367C_ACT23_SVID_MASK 0x200 +#define RTL8367C_ACT23_CVID_OFFSET 8 +#define RTL8367C_ACT23_CVID_MASK 0x100 +#define RTL8367C_OP22_NOT_OFFSET 6 +#define RTL8367C_OP22_NOT_MASK 0x40 +#define RTL8367C_ACT22_GPIO_OFFSET 5 +#define RTL8367C_ACT22_GPIO_MASK 0x20 +#define RTL8367C_ACT22_FORWARD_OFFSET 4 +#define RTL8367C_ACT22_FORWARD_MASK 0x10 +#define RTL8367C_ACT22_POLICING_OFFSET 3 +#define RTL8367C_ACT22_POLICING_MASK 0x8 +#define RTL8367C_ACT22_PRIORITY_OFFSET 2 +#define RTL8367C_ACT22_PRIORITY_MASK 0x4 +#define RTL8367C_ACT22_SVID_OFFSET 1 +#define RTL8367C_ACT22_SVID_MASK 0x2 +#define RTL8367C_ACT22_CVID_OFFSET 0 +#define RTL8367C_ACT22_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL12 0x0620 +#define RTL8367C_OP25_NOT_OFFSET 14 +#define RTL8367C_OP25_NOT_MASK 0x4000 +#define RTL8367C_ACT25_GPIO_OFFSET 13 +#define RTL8367C_ACT25_GPIO_MASK 0x2000 +#define RTL8367C_ACT25_FORWARD_OFFSET 12 +#define RTL8367C_ACT25_FORWARD_MASK 0x1000 +#define RTL8367C_ACT25_POLICING_OFFSET 11 +#define RTL8367C_ACT25_POLICING_MASK 0x800 +#define RTL8367C_ACT25_PRIORITY_OFFSET 10 +#define RTL8367C_ACT25_PRIORITY_MASK 0x400 +#define RTL8367C_ACT25_SVID_OFFSET 9 +#define RTL8367C_ACT25_SVID_MASK 0x200 +#define RTL8367C_ACT25_CVID_OFFSET 8 +#define RTL8367C_ACT25_CVID_MASK 0x100 +#define RTL8367C_OP24_NOT_OFFSET 6 +#define RTL8367C_OP24_NOT_MASK 0x40 +#define RTL8367C_ACT24_GPIO_OFFSET 5 +#define RTL8367C_ACT24_GPIO_MASK 0x20 +#define RTL8367C_ACT24_FORWARD_OFFSET 4 +#define RTL8367C_ACT24_FORWARD_MASK 0x10 +#define RTL8367C_ACT24_POLICING_OFFSET 3 +#define RTL8367C_ACT24_POLICING_MASK 0x8 +#define RTL8367C_ACT24_PRIORITY_OFFSET 2 +#define RTL8367C_ACT24_PRIORITY_MASK 0x4 +#define RTL8367C_ACT24_SVID_OFFSET 1 +#define RTL8367C_ACT24_SVID_MASK 0x2 +#define RTL8367C_ACT24_CVID_OFFSET 0 +#define RTL8367C_ACT24_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL13 0x0621 +#define RTL8367C_OP27_NOT_OFFSET 14 +#define RTL8367C_OP27_NOT_MASK 0x4000 +#define RTL8367C_ACT27_GPIO_OFFSET 13 +#define RTL8367C_ACT27_GPIO_MASK 0x2000 +#define RTL8367C_ACT27_FORWARD_OFFSET 12 +#define RTL8367C_ACT27_FORWARD_MASK 0x1000 +#define RTL8367C_ACT27_POLICING_OFFSET 11 +#define RTL8367C_ACT27_POLICING_MASK 0x800 +#define RTL8367C_ACT27_PRIORITY_OFFSET 10 +#define RTL8367C_ACT27_PRIORITY_MASK 0x400 +#define RTL8367C_ACT27_SVID_OFFSET 9 +#define RTL8367C_ACT27_SVID_MASK 0x200 +#define RTL8367C_ACT27_CVID_OFFSET 8 +#define RTL8367C_ACT27_CVID_MASK 0x100 +#define RTL8367C_OP26_NOT_OFFSET 6 +#define RTL8367C_OP26_NOT_MASK 0x40 +#define RTL8367C_ACT26_GPIO_OFFSET 5 +#define RTL8367C_ACT26_GPIO_MASK 0x20 +#define RTL8367C_ACT26_FORWARD_OFFSET 4 +#define RTL8367C_ACT26_FORWARD_MASK 0x10 +#define RTL8367C_ACT26_POLICING_OFFSET 3 +#define RTL8367C_ACT26_POLICING_MASK 0x8 +#define RTL8367C_ACT26_PRIORITY_OFFSET 2 +#define RTL8367C_ACT26_PRIORITY_MASK 0x4 +#define RTL8367C_ACT26_SVID_OFFSET 1 +#define RTL8367C_ACT26_SVID_MASK 0x2 +#define RTL8367C_ACT26_CVID_OFFSET 0 +#define RTL8367C_ACT26_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL14 0x0622 +#define RTL8367C_OP29_NOT_OFFSET 14 +#define RTL8367C_OP29_NOT_MASK 0x4000 +#define RTL8367C_ACT29_GPIO_OFFSET 13 +#define RTL8367C_ACT29_GPIO_MASK 0x2000 +#define RTL8367C_ACT29_FORWARD_OFFSET 12 +#define RTL8367C_ACT29_FORWARD_MASK 0x1000 +#define RTL8367C_ACT29_POLICING_OFFSET 11 +#define RTL8367C_ACT29_POLICING_MASK 0x800 +#define RTL8367C_ACT29_PRIORITY_OFFSET 10 +#define RTL8367C_ACT29_PRIORITY_MASK 0x400 +#define RTL8367C_ACT29_SVID_OFFSET 9 +#define RTL8367C_ACT29_SVID_MASK 0x200 +#define RTL8367C_ACT29_CVID_OFFSET 8 +#define RTL8367C_ACT29_CVID_MASK 0x100 +#define RTL8367C_OP28_NOT_OFFSET 6 +#define RTL8367C_OP28_NOT_MASK 0x40 +#define RTL8367C_ACT28_GPIO_OFFSET 5 +#define RTL8367C_ACT28_GPIO_MASK 0x20 +#define RTL8367C_ACT28_FORWARD_OFFSET 4 +#define RTL8367C_ACT28_FORWARD_MASK 0x10 +#define RTL8367C_ACT28_POLICING_OFFSET 3 +#define RTL8367C_ACT28_POLICING_MASK 0x8 +#define RTL8367C_ACT28_PRIORITY_OFFSET 2 +#define RTL8367C_ACT28_PRIORITY_MASK 0x4 +#define RTL8367C_ACT28_SVID_OFFSET 1 +#define RTL8367C_ACT28_SVID_MASK 0x2 +#define RTL8367C_ACT28_CVID_OFFSET 0 +#define RTL8367C_ACT28_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL15 0x0623 +#define RTL8367C_OP31_NOT_OFFSET 14 +#define RTL8367C_OP31_NOT_MASK 0x4000 +#define RTL8367C_ACT31_GPIO_OFFSET 13 +#define RTL8367C_ACT31_GPIO_MASK 0x2000 +#define RTL8367C_ACT31_FORWARD_OFFSET 12 +#define RTL8367C_ACT31_FORWARD_MASK 0x1000 +#define RTL8367C_ACT31_POLICING_OFFSET 11 +#define RTL8367C_ACT31_POLICING_MASK 0x800 +#define RTL8367C_ACT31_PRIORITY_OFFSET 10 +#define RTL8367C_ACT31_PRIORITY_MASK 0x400 +#define RTL8367C_ACT31_SVID_OFFSET 9 +#define RTL8367C_ACT31_SVID_MASK 0x200 +#define RTL8367C_ACT31_CVID_OFFSET 8 +#define RTL8367C_ACT31_CVID_MASK 0x100 +#define RTL8367C_OP30_NOT_OFFSET 6 +#define RTL8367C_OP30_NOT_MASK 0x40 +#define RTL8367C_ACT30_GPIO_OFFSET 5 +#define RTL8367C_ACT30_GPIO_MASK 0x20 +#define RTL8367C_ACT30_FORWARD_OFFSET 4 +#define RTL8367C_ACT30_FORWARD_MASK 0x10 +#define RTL8367C_ACT30_POLICING_OFFSET 3 +#define RTL8367C_ACT30_POLICING_MASK 0x8 +#define RTL8367C_ACT30_PRIORITY_OFFSET 2 +#define RTL8367C_ACT30_PRIORITY_MASK 0x4 +#define RTL8367C_ACT30_SVID_OFFSET 1 +#define RTL8367C_ACT30_SVID_MASK 0x2 +#define RTL8367C_ACT30_CVID_OFFSET 0 +#define RTL8367C_ACT30_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL16 0x0624 +#define RTL8367C_OP33_NOT_OFFSET 14 +#define RTL8367C_OP33_NOT_MASK 0x4000 +#define RTL8367C_ACT33_GPIO_OFFSET 13 +#define RTL8367C_ACT33_GPIO_MASK 0x2000 +#define RTL8367C_ACT33_FORWARD_OFFSET 12 +#define RTL8367C_ACT33_FORWARD_MASK 0x1000 +#define RTL8367C_ACT33_POLICING_OFFSET 11 +#define RTL8367C_ACT33_POLICING_MASK 0x800 +#define RTL8367C_ACT33_PRIORITY_OFFSET 10 +#define RTL8367C_ACT33_PRIORITY_MASK 0x400 +#define RTL8367C_ACT33_SVID_OFFSET 9 +#define RTL8367C_ACT33_SVID_MASK 0x200 +#define RTL8367C_ACT33_CVID_OFFSET 8 +#define RTL8367C_ACT33_CVID_MASK 0x100 +#define RTL8367C_OP32_NOT_OFFSET 6 +#define RTL8367C_OP32_NOT_MASK 0x40 +#define RTL8367C_ACT32_GPIO_OFFSET 5 +#define RTL8367C_ACT32_GPIO_MASK 0x20 +#define RTL8367C_ACT32_FORWARD_OFFSET 4 +#define RTL8367C_ACT32_FORWARD_MASK 0x10 +#define RTL8367C_ACT32_POLICING_OFFSET 3 +#define RTL8367C_ACT32_POLICING_MASK 0x8 +#define RTL8367C_ACT32_PRIORITY_OFFSET 2 +#define RTL8367C_ACT32_PRIORITY_MASK 0x4 +#define RTL8367C_ACT32_SVID_OFFSET 1 +#define RTL8367C_ACT32_SVID_MASK 0x2 +#define RTL8367C_ACT32_CVID_OFFSET 0 +#define RTL8367C_ACT32_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL17 0x0625 +#define RTL8367C_OP35_NOT_OFFSET 14 +#define RTL8367C_OP35_NOT_MASK 0x4000 +#define RTL8367C_ACT35_GPIO_OFFSET 13 +#define RTL8367C_ACT35_GPIO_MASK 0x2000 +#define RTL8367C_ACT35_FORWARD_OFFSET 12 +#define RTL8367C_ACT35_FORWARD_MASK 0x1000 +#define RTL8367C_ACT35_POLICING_OFFSET 11 +#define RTL8367C_ACT35_POLICING_MASK 0x800 +#define RTL8367C_ACT35_PRIORITY_OFFSET 10 +#define RTL8367C_ACT35_PRIORITY_MASK 0x400 +#define RTL8367C_ACT35_SVID_OFFSET 9 +#define RTL8367C_ACT35_SVID_MASK 0x200 +#define RTL8367C_ACT35_CVID_OFFSET 8 +#define RTL8367C_ACT35_CVID_MASK 0x100 +#define RTL8367C_OP34_NOT_OFFSET 6 +#define RTL8367C_OP34_NOT_MASK 0x40 +#define RTL8367C_ACT34_GPIO_OFFSET 5 +#define RTL8367C_ACT34_GPIO_MASK 0x20 +#define RTL8367C_ACT34_FORWARD_OFFSET 4 +#define RTL8367C_ACT34_FORWARD_MASK 0x10 +#define RTL8367C_ACT34_POLICING_OFFSET 3 +#define RTL8367C_ACT34_POLICING_MASK 0x8 +#define RTL8367C_ACT34_PRIORITY_OFFSET 2 +#define RTL8367C_ACT34_PRIORITY_MASK 0x4 +#define RTL8367C_ACT34_SVID_OFFSET 1 +#define RTL8367C_ACT34_SVID_MASK 0x2 +#define RTL8367C_ACT34_CVID_OFFSET 0 +#define RTL8367C_ACT34_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL18 0x0626 +#define RTL8367C_OP37_NOT_OFFSET 14 +#define RTL8367C_OP37_NOT_MASK 0x4000 +#define RTL8367C_ACT37_GPIO_OFFSET 13 +#define RTL8367C_ACT37_GPIO_MASK 0x2000 +#define RTL8367C_ACT37_FORWARD_OFFSET 12 +#define RTL8367C_ACT37_FORWARD_MASK 0x1000 +#define RTL8367C_ACT37_POLICING_OFFSET 11 +#define RTL8367C_ACT37_POLICING_MASK 0x800 +#define RTL8367C_ACT37_PRIORITY_OFFSET 10 +#define RTL8367C_ACT37_PRIORITY_MASK 0x400 +#define RTL8367C_ACT37_SVID_OFFSET 9 +#define RTL8367C_ACT37_SVID_MASK 0x200 +#define RTL8367C_ACT37_CVID_OFFSET 8 +#define RTL8367C_ACT37_CVID_MASK 0x100 +#define RTL8367C_OP36_NOT_OFFSET 6 +#define RTL8367C_OP36_NOT_MASK 0x40 +#define RTL8367C_ACT36_GPIO_OFFSET 5 +#define RTL8367C_ACT36_GPIO_MASK 0x20 +#define RTL8367C_ACT36_FORWARD_OFFSET 4 +#define RTL8367C_ACT36_FORWARD_MASK 0x10 +#define RTL8367C_ACT36_POLICING_OFFSET 3 +#define RTL8367C_ACT36_POLICING_MASK 0x8 +#define RTL8367C_ACT36_PRIORITY_OFFSET 2 +#define RTL8367C_ACT36_PRIORITY_MASK 0x4 +#define RTL8367C_ACT36_SVID_OFFSET 1 +#define RTL8367C_ACT36_SVID_MASK 0x2 +#define RTL8367C_ACT36_CVID_OFFSET 0 +#define RTL8367C_ACT36_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL19 0x0627 +#define RTL8367C_OP39_NOT_OFFSET 14 +#define RTL8367C_OP39_NOT_MASK 0x4000 +#define RTL8367C_ACT39_GPIO_OFFSET 13 +#define RTL8367C_ACT39_GPIO_MASK 0x2000 +#define RTL8367C_ACT39_FORWARD_OFFSET 12 +#define RTL8367C_ACT39_FORWARD_MASK 0x1000 +#define RTL8367C_ACT39_POLICING_OFFSET 11 +#define RTL8367C_ACT39_POLICING_MASK 0x800 +#define RTL8367C_ACT39_PRIORITY_OFFSET 10 +#define RTL8367C_ACT39_PRIORITY_MASK 0x400 +#define RTL8367C_ACT39_SVID_OFFSET 9 +#define RTL8367C_ACT39_SVID_MASK 0x200 +#define RTL8367C_ACT39_CVID_OFFSET 8 +#define RTL8367C_ACT39_CVID_MASK 0x100 +#define RTL8367C_OP38_NOT_OFFSET 6 +#define RTL8367C_OP38_NOT_MASK 0x40 +#define RTL8367C_ACT38_GPIO_OFFSET 5 +#define RTL8367C_ACT38_GPIO_MASK 0x20 +#define RTL8367C_ACT38_FORWARD_OFFSET 4 +#define RTL8367C_ACT38_FORWARD_MASK 0x10 +#define RTL8367C_ACT38_POLICING_OFFSET 3 +#define RTL8367C_ACT38_POLICING_MASK 0x8 +#define RTL8367C_ACT38_PRIORITY_OFFSET 2 +#define RTL8367C_ACT38_PRIORITY_MASK 0x4 +#define RTL8367C_ACT38_SVID_OFFSET 1 +#define RTL8367C_ACT38_SVID_MASK 0x2 +#define RTL8367C_ACT38_CVID_OFFSET 0 +#define RTL8367C_ACT38_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL20 0x0628 +#define RTL8367C_OP41_NOT_OFFSET 14 +#define RTL8367C_OP41_NOT_MASK 0x4000 +#define RTL8367C_ACT41_GPIO_OFFSET 13 +#define RTL8367C_ACT41_GPIO_MASK 0x2000 +#define RTL8367C_ACT41_FORWARD_OFFSET 12 +#define RTL8367C_ACT41_FORWARD_MASK 0x1000 +#define RTL8367C_ACT41_POLICING_OFFSET 11 +#define RTL8367C_ACT41_POLICING_MASK 0x800 +#define RTL8367C_ACT41_PRIORITY_OFFSET 10 +#define RTL8367C_ACT41_PRIORITY_MASK 0x400 +#define RTL8367C_ACT41_SVID_OFFSET 9 +#define RTL8367C_ACT41_SVID_MASK 0x200 +#define RTL8367C_ACT41_CVID_OFFSET 8 +#define RTL8367C_ACT41_CVID_MASK 0x100 +#define RTL8367C_OP40_NOT_OFFSET 6 +#define RTL8367C_OP40_NOT_MASK 0x40 +#define RTL8367C_ACT40_GPIO_OFFSET 5 +#define RTL8367C_ACT40_GPIO_MASK 0x20 +#define RTL8367C_ACT40_FORWARD_OFFSET 4 +#define RTL8367C_ACT40_FORWARD_MASK 0x10 +#define RTL8367C_ACT40_POLICING_OFFSET 3 +#define RTL8367C_ACT40_POLICING_MASK 0x8 +#define RTL8367C_ACT40_PRIORITY_OFFSET 2 +#define RTL8367C_ACT40_PRIORITY_MASK 0x4 +#define RTL8367C_ACT40_SVID_OFFSET 1 +#define RTL8367C_ACT40_SVID_MASK 0x2 +#define RTL8367C_ACT40_CVID_OFFSET 0 +#define RTL8367C_ACT40_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL21 0x0629 +#define RTL8367C_OP43_NOT_OFFSET 14 +#define RTL8367C_OP43_NOT_MASK 0x4000 +#define RTL8367C_ACT43_GPIO_OFFSET 13 +#define RTL8367C_ACT43_GPIO_MASK 0x2000 +#define RTL8367C_ACT43_FORWARD_OFFSET 12 +#define RTL8367C_ACT43_FORWARD_MASK 0x1000 +#define RTL8367C_ACT43_POLICING_OFFSET 11 +#define RTL8367C_ACT43_POLICING_MASK 0x800 +#define RTL8367C_ACT43_PRIORITY_OFFSET 10 +#define RTL8367C_ACT43_PRIORITY_MASK 0x400 +#define RTL8367C_ACT43_SVID_OFFSET 9 +#define RTL8367C_ACT43_SVID_MASK 0x200 +#define RTL8367C_ACT43_CVID_OFFSET 8 +#define RTL8367C_ACT43_CVID_MASK 0x100 +#define RTL8367C_OP42_NOT_OFFSET 6 +#define RTL8367C_OP42_NOT_MASK 0x40 +#define RTL8367C_ACT42_GPIO_OFFSET 5 +#define RTL8367C_ACT42_GPIO_MASK 0x20 +#define RTL8367C_ACT42_FORWARD_OFFSET 4 +#define RTL8367C_ACT42_FORWARD_MASK 0x10 +#define RTL8367C_ACT42_POLICING_OFFSET 3 +#define RTL8367C_ACT42_POLICING_MASK 0x8 +#define RTL8367C_ACT42_PRIORITY_OFFSET 2 +#define RTL8367C_ACT42_PRIORITY_MASK 0x4 +#define RTL8367C_ACT42_SVID_OFFSET 1 +#define RTL8367C_ACT42_SVID_MASK 0x2 +#define RTL8367C_ACT42_CVID_OFFSET 0 +#define RTL8367C_ACT42_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL22 0x062a +#define RTL8367C_OP45_NOT_OFFSET 14 +#define RTL8367C_OP45_NOT_MASK 0x4000 +#define RTL8367C_ACT45_GPIO_OFFSET 13 +#define RTL8367C_ACT45_GPIO_MASK 0x2000 +#define RTL8367C_ACT45_FORWARD_OFFSET 12 +#define RTL8367C_ACT45_FORWARD_MASK 0x1000 +#define RTL8367C_ACT45_POLICING_OFFSET 11 +#define RTL8367C_ACT45_POLICING_MASK 0x800 +#define RTL8367C_ACT45_PRIORITY_OFFSET 10 +#define RTL8367C_ACT45_PRIORITY_MASK 0x400 +#define RTL8367C_ACT45_SVID_OFFSET 9 +#define RTL8367C_ACT45_SVID_MASK 0x200 +#define RTL8367C_ACT45_CVID_OFFSET 8 +#define RTL8367C_ACT45_CVID_MASK 0x100 +#define RTL8367C_OP44_NOT_OFFSET 6 +#define RTL8367C_OP44_NOT_MASK 0x40 +#define RTL8367C_ACT44_GPIO_OFFSET 5 +#define RTL8367C_ACT44_GPIO_MASK 0x20 +#define RTL8367C_ACT44_FORWARD_OFFSET 4 +#define RTL8367C_ACT44_FORWARD_MASK 0x10 +#define RTL8367C_ACT44_POLICING_OFFSET 3 +#define RTL8367C_ACT44_POLICING_MASK 0x8 +#define RTL8367C_ACT44_PRIORITY_OFFSET 2 +#define RTL8367C_ACT44_PRIORITY_MASK 0x4 +#define RTL8367C_ACT44_SVID_OFFSET 1 +#define RTL8367C_ACT44_SVID_MASK 0x2 +#define RTL8367C_ACT44_CVID_OFFSET 0 +#define RTL8367C_ACT44_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL23 0x062b +#define RTL8367C_OP47_NOT_OFFSET 14 +#define RTL8367C_OP47_NOT_MASK 0x4000 +#define RTL8367C_ACT47_GPIO_OFFSET 13 +#define RTL8367C_ACT47_GPIO_MASK 0x2000 +#define RTL8367C_ACT47_FORWARD_OFFSET 12 +#define RTL8367C_ACT47_FORWARD_MASK 0x1000 +#define RTL8367C_ACT47_POLICING_OFFSET 11 +#define RTL8367C_ACT47_POLICING_MASK 0x800 +#define RTL8367C_ACT47_PRIORITY_OFFSET 10 +#define RTL8367C_ACT47_PRIORITY_MASK 0x400 +#define RTL8367C_ACT47_SVID_OFFSET 9 +#define RTL8367C_ACT47_SVID_MASK 0x200 +#define RTL8367C_ACT47_CVID_OFFSET 8 +#define RTL8367C_ACT47_CVID_MASK 0x100 +#define RTL8367C_OP46_NOT_OFFSET 6 +#define RTL8367C_OP46_NOT_MASK 0x40 +#define RTL8367C_ACT46_GPIO_OFFSET 5 +#define RTL8367C_ACT46_GPIO_MASK 0x20 +#define RTL8367C_ACT46_FORWARD_OFFSET 4 +#define RTL8367C_ACT46_FORWARD_MASK 0x10 +#define RTL8367C_ACT46_POLICING_OFFSET 3 +#define RTL8367C_ACT46_POLICING_MASK 0x8 +#define RTL8367C_ACT46_PRIORITY_OFFSET 2 +#define RTL8367C_ACT46_PRIORITY_MASK 0x4 +#define RTL8367C_ACT46_SVID_OFFSET 1 +#define RTL8367C_ACT46_SVID_MASK 0x2 +#define RTL8367C_ACT46_CVID_OFFSET 0 +#define RTL8367C_ACT46_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL24 0x062c +#define RTL8367C_OP49_NOT_OFFSET 14 +#define RTL8367C_OP49_NOT_MASK 0x4000 +#define RTL8367C_ACT49_GPIO_OFFSET 13 +#define RTL8367C_ACT49_GPIO_MASK 0x2000 +#define RTL8367C_ACT49_FORWARD_OFFSET 12 +#define RTL8367C_ACT49_FORWARD_MASK 0x1000 +#define RTL8367C_ACT49_POLICING_OFFSET 11 +#define RTL8367C_ACT49_POLICING_MASK 0x800 +#define RTL8367C_ACT49_PRIORITY_OFFSET 10 +#define RTL8367C_ACT49_PRIORITY_MASK 0x400 +#define RTL8367C_ACT49_SVID_OFFSET 9 +#define RTL8367C_ACT49_SVID_MASK 0x200 +#define RTL8367C_ACT49_CVID_OFFSET 8 +#define RTL8367C_ACT49_CVID_MASK 0x100 +#define RTL8367C_OP48_NOT_OFFSET 6 +#define RTL8367C_OP48_NOT_MASK 0x40 +#define RTL8367C_ACT48_GPIO_OFFSET 5 +#define RTL8367C_ACT48_GPIO_MASK 0x20 +#define RTL8367C_ACT48_FORWARD_OFFSET 4 +#define RTL8367C_ACT48_FORWARD_MASK 0x10 +#define RTL8367C_ACT48_POLICING_OFFSET 3 +#define RTL8367C_ACT48_POLICING_MASK 0x8 +#define RTL8367C_ACT48_PRIORITY_OFFSET 2 +#define RTL8367C_ACT48_PRIORITY_MASK 0x4 +#define RTL8367C_ACT48_SVID_OFFSET 1 +#define RTL8367C_ACT48_SVID_MASK 0x2 +#define RTL8367C_ACT48_CVID_OFFSET 0 +#define RTL8367C_ACT48_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL25 0x062d +#define RTL8367C_OP51_NOT_OFFSET 14 +#define RTL8367C_OP51_NOT_MASK 0x4000 +#define RTL8367C_ACT51_GPIO_OFFSET 13 +#define RTL8367C_ACT51_GPIO_MASK 0x2000 +#define RTL8367C_ACT51_FORWARD_OFFSET 12 +#define RTL8367C_ACT51_FORWARD_MASK 0x1000 +#define RTL8367C_ACT51_POLICING_OFFSET 11 +#define RTL8367C_ACT51_POLICING_MASK 0x800 +#define RTL8367C_ACT51_PRIORITY_OFFSET 10 +#define RTL8367C_ACT51_PRIORITY_MASK 0x400 +#define RTL8367C_ACT51_SVID_OFFSET 9 +#define RTL8367C_ACT51_SVID_MASK 0x200 +#define RTL8367C_ACT51_CVID_OFFSET 8 +#define RTL8367C_ACT51_CVID_MASK 0x100 +#define RTL8367C_OP50_NOT_OFFSET 6 +#define RTL8367C_OP50_NOT_MASK 0x40 +#define RTL8367C_ACT50_GPIO_OFFSET 5 +#define RTL8367C_ACT50_GPIO_MASK 0x20 +#define RTL8367C_ACT50_FORWARD_OFFSET 4 +#define RTL8367C_ACT50_FORWARD_MASK 0x10 +#define RTL8367C_ACT50_POLICING_OFFSET 3 +#define RTL8367C_ACT50_POLICING_MASK 0x8 +#define RTL8367C_ACT50_PRIORITY_OFFSET 2 +#define RTL8367C_ACT50_PRIORITY_MASK 0x4 +#define RTL8367C_ACT50_SVID_OFFSET 1 +#define RTL8367C_ACT50_SVID_MASK 0x2 +#define RTL8367C_ACT50_CVID_OFFSET 0 +#define RTL8367C_ACT50_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL26 0x062e +#define RTL8367C_OP53_NOT_OFFSET 14 +#define RTL8367C_OP53_NOT_MASK 0x4000 +#define RTL8367C_ACT53_GPIO_OFFSET 13 +#define RTL8367C_ACT53_GPIO_MASK 0x2000 +#define RTL8367C_ACT53_FORWARD_OFFSET 12 +#define RTL8367C_ACT53_FORWARD_MASK 0x1000 +#define RTL8367C_ACT53_POLICING_OFFSET 11 +#define RTL8367C_ACT53_POLICING_MASK 0x800 +#define RTL8367C_ACT53_PRIORITY_OFFSET 10 +#define RTL8367C_ACT53_PRIORITY_MASK 0x400 +#define RTL8367C_ACT53_SVID_OFFSET 9 +#define RTL8367C_ACT53_SVID_MASK 0x200 +#define RTL8367C_ACT53_CVID_OFFSET 8 +#define RTL8367C_ACT53_CVID_MASK 0x100 +#define RTL8367C_OP52_NOT_OFFSET 6 +#define RTL8367C_OP52_NOT_MASK 0x40 +#define RTL8367C_ACT52_GPIO_OFFSET 5 +#define RTL8367C_ACT52_GPIO_MASK 0x20 +#define RTL8367C_ACT52_FORWARD_OFFSET 4 +#define RTL8367C_ACT52_FORWARD_MASK 0x10 +#define RTL8367C_ACT52_POLICING_OFFSET 3 +#define RTL8367C_ACT52_POLICING_MASK 0x8 +#define RTL8367C_ACT52_PRIORITY_OFFSET 2 +#define RTL8367C_ACT52_PRIORITY_MASK 0x4 +#define RTL8367C_ACT52_SVID_OFFSET 1 +#define RTL8367C_ACT52_SVID_MASK 0x2 +#define RTL8367C_ACT52_CVID_OFFSET 0 +#define RTL8367C_ACT52_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL27 0x062f +#define RTL8367C_OP55_NOT_OFFSET 14 +#define RTL8367C_OP55_NOT_MASK 0x4000 +#define RTL8367C_ACT55_GPIO_OFFSET 13 +#define RTL8367C_ACT55_GPIO_MASK 0x2000 +#define RTL8367C_ACT55_FORWARD_OFFSET 12 +#define RTL8367C_ACT55_FORWARD_MASK 0x1000 +#define RTL8367C_ACT55_POLICING_OFFSET 11 +#define RTL8367C_ACT55_POLICING_MASK 0x800 +#define RTL8367C_ACT55_PRIORITY_OFFSET 10 +#define RTL8367C_ACT55_PRIORITY_MASK 0x400 +#define RTL8367C_ACT55_SVID_OFFSET 9 +#define RTL8367C_ACT55_SVID_MASK 0x200 +#define RTL8367C_ACT55_CVID_OFFSET 8 +#define RTL8367C_ACT55_CVID_MASK 0x100 +#define RTL8367C_OP54_NOT_OFFSET 6 +#define RTL8367C_OP54_NOT_MASK 0x40 +#define RTL8367C_ACT54_GPIO_OFFSET 5 +#define RTL8367C_ACT54_GPIO_MASK 0x20 +#define RTL8367C_ACT54_FORWARD_OFFSET 4 +#define RTL8367C_ACT54_FORWARD_MASK 0x10 +#define RTL8367C_ACT54_POLICING_OFFSET 3 +#define RTL8367C_ACT54_POLICING_MASK 0x8 +#define RTL8367C_ACT54_PRIORITY_OFFSET 2 +#define RTL8367C_ACT54_PRIORITY_MASK 0x4 +#define RTL8367C_ACT54_SVID_OFFSET 1 +#define RTL8367C_ACT54_SVID_MASK 0x2 +#define RTL8367C_ACT54_CVID_OFFSET 0 +#define RTL8367C_ACT54_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL28 0x0630 +#define RTL8367C_OP57_NOT_OFFSET 14 +#define RTL8367C_OP57_NOT_MASK 0x4000 +#define RTL8367C_ACT57_GPIO_OFFSET 13 +#define RTL8367C_ACT57_GPIO_MASK 0x2000 +#define RTL8367C_ACT57_FORWARD_OFFSET 12 +#define RTL8367C_ACT57_FORWARD_MASK 0x1000 +#define RTL8367C_ACT57_POLICING_OFFSET 11 +#define RTL8367C_ACT57_POLICING_MASK 0x800 +#define RTL8367C_ACT57_PRIORITY_OFFSET 10 +#define RTL8367C_ACT57_PRIORITY_MASK 0x400 +#define RTL8367C_ACT57_SVID_OFFSET 9 +#define RTL8367C_ACT57_SVID_MASK 0x200 +#define RTL8367C_ACT57_CVID_OFFSET 8 +#define RTL8367C_ACT57_CVID_MASK 0x100 +#define RTL8367C_OP56_NOT_OFFSET 6 +#define RTL8367C_OP56_NOT_MASK 0x40 +#define RTL8367C_ACT56_GPIO_OFFSET 5 +#define RTL8367C_ACT56_GPIO_MASK 0x20 +#define RTL8367C_ACT56_FORWARD_OFFSET 4 +#define RTL8367C_ACT56_FORWARD_MASK 0x10 +#define RTL8367C_ACT56_POLICING_OFFSET 3 +#define RTL8367C_ACT56_POLICING_MASK 0x8 +#define RTL8367C_ACT56_PRIORITY_OFFSET 2 +#define RTL8367C_ACT56_PRIORITY_MASK 0x4 +#define RTL8367C_ACT56_SVID_OFFSET 1 +#define RTL8367C_ACT56_SVID_MASK 0x2 +#define RTL8367C_ACT56_CVID_OFFSET 0 +#define RTL8367C_ACT56_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL29 0x0631 +#define RTL8367C_OP59_NOT_OFFSET 14 +#define RTL8367C_OP59_NOT_MASK 0x4000 +#define RTL8367C_ACT59_GPIO_OFFSET 13 +#define RTL8367C_ACT59_GPIO_MASK 0x2000 +#define RTL8367C_ACT59_FORWARD_OFFSET 12 +#define RTL8367C_ACT59_FORWARD_MASK 0x1000 +#define RTL8367C_ACT59_POLICING_OFFSET 11 +#define RTL8367C_ACT59_POLICING_MASK 0x800 +#define RTL8367C_ACT59_PRIORITY_OFFSET 10 +#define RTL8367C_ACT59_PRIORITY_MASK 0x400 +#define RTL8367C_ACT59_SVID_OFFSET 9 +#define RTL8367C_ACT59_SVID_MASK 0x200 +#define RTL8367C_ACT59_CVID_OFFSET 8 +#define RTL8367C_ACT59_CVID_MASK 0x100 +#define RTL8367C_OP58_NOT_OFFSET 6 +#define RTL8367C_OP58_NOT_MASK 0x40 +#define RTL8367C_ACT58_GPIO_OFFSET 5 +#define RTL8367C_ACT58_GPIO_MASK 0x20 +#define RTL8367C_ACT58_FORWARD_OFFSET 4 +#define RTL8367C_ACT58_FORWARD_MASK 0x10 +#define RTL8367C_ACT58_POLICING_OFFSET 3 +#define RTL8367C_ACT58_POLICING_MASK 0x8 +#define RTL8367C_ACT58_PRIORITY_OFFSET 2 +#define RTL8367C_ACT58_PRIORITY_MASK 0x4 +#define RTL8367C_ACT58_SVID_OFFSET 1 +#define RTL8367C_ACT58_SVID_MASK 0x2 +#define RTL8367C_ACT58_CVID_OFFSET 0 +#define RTL8367C_ACT58_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL30 0x0632 +#define RTL8367C_OP61_NOT_OFFSET 14 +#define RTL8367C_OP61_NOT_MASK 0x4000 +#define RTL8367C_ACT61_GPIO_OFFSET 13 +#define RTL8367C_ACT61_GPIO_MASK 0x2000 +#define RTL8367C_ACT61_FORWARD_OFFSET 12 +#define RTL8367C_ACT61_FORWARD_MASK 0x1000 +#define RTL8367C_ACT61_POLICING_OFFSET 11 +#define RTL8367C_ACT61_POLICING_MASK 0x800 +#define RTL8367C_ACT61_PRIORITY_OFFSET 10 +#define RTL8367C_ACT61_PRIORITY_MASK 0x400 +#define RTL8367C_ACT61_SVID_OFFSET 9 +#define RTL8367C_ACT61_SVID_MASK 0x200 +#define RTL8367C_ACT61_CVID_OFFSET 8 +#define RTL8367C_ACT61_CVID_MASK 0x100 +#define RTL8367C_OP60_NOT_OFFSET 6 +#define RTL8367C_OP60_NOT_MASK 0x40 +#define RTL8367C_ACT60_GPIO_OFFSET 5 +#define RTL8367C_ACT60_GPIO_MASK 0x20 +#define RTL8367C_ACT60_FORWARD_OFFSET 4 +#define RTL8367C_ACT60_FORWARD_MASK 0x10 +#define RTL8367C_ACT60_POLICING_OFFSET 3 +#define RTL8367C_ACT60_POLICING_MASK 0x8 +#define RTL8367C_ACT60_PRIORITY_OFFSET 2 +#define RTL8367C_ACT60_PRIORITY_MASK 0x4 +#define RTL8367C_ACT60_SVID_OFFSET 1 +#define RTL8367C_ACT60_SVID_MASK 0x2 +#define RTL8367C_ACT60_CVID_OFFSET 0 +#define RTL8367C_ACT60_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL31 0x0633 +#define RTL8367C_OP63_NOT_OFFSET 14 +#define RTL8367C_OP63_NOT_MASK 0x4000 +#define RTL8367C_ACT63_GPIO_OFFSET 13 +#define RTL8367C_ACT63_GPIO_MASK 0x2000 +#define RTL8367C_ACT63_FORWARD_OFFSET 12 +#define RTL8367C_ACT63_FORWARD_MASK 0x1000 +#define RTL8367C_ACT63_POLICING_OFFSET 11 +#define RTL8367C_ACT63_POLICING_MASK 0x800 +#define RTL8367C_ACT63_PRIORITY_OFFSET 10 +#define RTL8367C_ACT63_PRIORITY_MASK 0x400 +#define RTL8367C_ACT63_SVID_OFFSET 9 +#define RTL8367C_ACT63_SVID_MASK 0x200 +#define RTL8367C_ACT63_CVID_OFFSET 8 +#define RTL8367C_ACT63_CVID_MASK 0x100 +#define RTL8367C_OP62_NOT_OFFSET 6 +#define RTL8367C_OP62_NOT_MASK 0x40 +#define RTL8367C_ACT62_GPIO_OFFSET 5 +#define RTL8367C_ACT62_GPIO_MASK 0x20 +#define RTL8367C_ACT62_FORWARD_OFFSET 4 +#define RTL8367C_ACT62_FORWARD_MASK 0x10 +#define RTL8367C_ACT62_POLICING_OFFSET 3 +#define RTL8367C_ACT62_POLICING_MASK 0x8 +#define RTL8367C_ACT62_PRIORITY_OFFSET 2 +#define RTL8367C_ACT62_PRIORITY_MASK 0x4 +#define RTL8367C_ACT62_SVID_OFFSET 1 +#define RTL8367C_ACT62_SVID_MASK 0x2 +#define RTL8367C_ACT62_CVID_OFFSET 0 +#define RTL8367C_ACT62_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 0x0635 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 0x0636 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 0x0637 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL0 0x0638 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL1 0x0639 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL2 0x063a +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL0 0x063b + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL1 0x063c + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL2 0x063d +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL0 0x063e + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL1 0x063f + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL2 0x0640 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL0 0x0641 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL1 0x0642 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL2 0x0643 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL0 0x0644 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL1 0x0645 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL2 0x0646 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL0 0x0647 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL1 0x0648 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL2 0x0649 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL0 0x064a + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL1 0x064b + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL2 0x064c +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL0 0x064d + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL1 0x064e + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL2 0x064f +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL0 0x0650 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL1 0x0651 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL2 0x0652 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL0 0x0653 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL1 0x0654 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL2 0x0655 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL0 0x0656 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL1 0x0657 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL2 0x0658 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL0 0x0659 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL1 0x065a + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL2 0x065b +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL0 0x065c + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL1 0x065d + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL2 0x065e +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL0 0x065f + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL1 0x0660 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL2 0x0661 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL0 0x0662 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL1 0x0663 + +#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL2 0x0664 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_OFFSET 0 +#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_MASK 0x3 + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 0x0665 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 0x0666 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL0 0x0667 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL1 0x0668 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL0 0x0669 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL1 0x066a +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL0 0x066b +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL1 0x066c +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL0 0x066d +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL1 0x066e +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL0 0x066f +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL1 0x0670 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL0 0x0671 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL1 0x0672 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL0 0x0673 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL1 0x0674 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL0 0x0675 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL1 0x0676 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL0 0x0677 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL1 0x0678 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL0 0x0679 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL1 0x067a +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL0 0x067b +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL1 0x067c +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL0 0x067d +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL1 0x067e +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL0 0x067f +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL1 0x0680 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL0 0x0681 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL1 0x0682 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL0 0x0683 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_MASK 0xFFF + +#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL1 0x0684 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_OFFSET 12 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_MASK 0x3000 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_OFFSET 0 +#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_MASK 0xFFF + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 0x0685 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 0x0686 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 0x0687 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 0x0688 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 0x0689 +#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL0 0x068a + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL1 0x068b + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL2 0x068c + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL3 0x068d + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL4 0x068e +#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL0 0x068f + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL1 0x0690 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL2 0x0691 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL3 0x0692 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL4 0x0693 +#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL0 0x0694 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL1 0x0695 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL2 0x0696 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL3 0x0697 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL4 0x0698 +#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL0 0x0699 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL1 0x069a + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL2 0x069b + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL3 0x069c + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL4 0x069d +#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL0 0x069e + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL1 0x069f + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL2 0x06a0 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL3 0x06a1 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL4 0x06a2 +#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL0 0x06a3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL1 0x06a4 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL2 0x06a5 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL3 0x06a6 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL4 0x06a7 +#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL0 0x06a8 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL1 0x06a9 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL2 0x06aa + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL3 0x06ab + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL4 0x06ac +#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL0 0x06ad + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL1 0x06ae + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL2 0x06af + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL3 0x06b0 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL4 0x06b1 +#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL0 0x06b2 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL1 0x06b3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL2 0x06b4 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL3 0x06b5 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL4 0x06b6 +#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL0 0x06b7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL1 0x06b8 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL2 0x06b9 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL3 0x06ba + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL4 0x06bb +#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL0 0x06bc + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL1 0x06bd + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL2 0x06be + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL3 0x06bf + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL4 0x06c0 +#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL0 0x06c1 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL1 0x06c2 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL2 0x06c3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL3 0x06c4 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL4 0x06c5 +#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL0 0x06c6 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL1 0x06c7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL2 0x06c8 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL3 0x06c9 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL4 0x06ca +#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL0 0x06cb + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL1 0x06cc + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL2 0x06cd + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL3 0x06ce + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL4 0x06cf +#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL0 0x06d0 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL1 0x06d1 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL2 0x06d2 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL3 0x06d3 + +#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL4 0x06d4 +#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_OFFSET 0 +#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_MASK 0x7 + +#define RTL8367C_REG_ACL_ENABLE 0x06d5 +#define RTL8367C_PORT10_ENABLE_OFFSET 10 +#define RTL8367C_PORT10_ENABLE_MASK 0x400 +#define RTL8367C_PORT9_ENABLE_OFFSET 9 +#define RTL8367C_PORT9_ENABLE_MASK 0x200 +#define RTL8367C_PORT8_ENABLE_OFFSET 8 +#define RTL8367C_PORT8_ENABLE_MASK 0x100 +#define RTL8367C_PORT7_ENABLE_OFFSET 7 +#define RTL8367C_PORT7_ENABLE_MASK 0x80 +#define RTL8367C_PORT6_ENABLE_OFFSET 6 +#define RTL8367C_PORT6_ENABLE_MASK 0x40 +#define RTL8367C_PORT5_ENABLE_OFFSET 5 +#define RTL8367C_PORT5_ENABLE_MASK 0x20 +#define RTL8367C_PORT4_ENABLE_OFFSET 4 +#define RTL8367C_PORT4_ENABLE_MASK 0x10 +#define RTL8367C_PORT3_ENABLE_OFFSET 3 +#define RTL8367C_PORT3_ENABLE_MASK 0x8 +#define RTL8367C_PORT2_ENABLE_OFFSET 2 +#define RTL8367C_PORT2_ENABLE_MASK 0x4 +#define RTL8367C_PORT1_ENABLE_OFFSET 1 +#define RTL8367C_PORT1_ENABLE_MASK 0x2 +#define RTL8367C_PORT0_ENABLE_OFFSET 0 +#define RTL8367C_PORT0_ENABLE_MASK 0x1 + +#define RTL8367C_REG_ACL_UNMATCH_PERMIT 0x06d6 +#define RTL8367C_PORT10_PERMIT_OFFSET 10 +#define RTL8367C_PORT10_PERMIT_MASK 0x400 +#define RTL8367C_PORT9_PERMIT_OFFSET 9 +#define RTL8367C_PORT9_PERMIT_MASK 0x200 +#define RTL8367C_PORT8_PERMIT_OFFSET 8 +#define RTL8367C_PORT8_PERMIT_MASK 0x100 +#define RTL8367C_PORT7_PERMIT_OFFSET 7 +#define RTL8367C_PORT7_PERMIT_MASK 0x80 +#define RTL8367C_PORT6_PERMIT_OFFSET 6 +#define RTL8367C_PORT6_PERMIT_MASK 0x40 +#define RTL8367C_PORT5_PERMIT_OFFSET 5 +#define RTL8367C_PORT5_PERMIT_MASK 0x20 +#define RTL8367C_PORT4_PERMIT_OFFSET 4 +#define RTL8367C_PORT4_PERMIT_MASK 0x10 +#define RTL8367C_PORT3_PERMIT_OFFSET 3 +#define RTL8367C_PORT3_PERMIT_MASK 0x8 +#define RTL8367C_PORT2_PERMIT_OFFSET 2 +#define RTL8367C_PORT2_PERMIT_MASK 0x4 +#define RTL8367C_PORT1_PERMIT_OFFSET 1 +#define RTL8367C_PORT1_PERMIT_MASK 0x2 +#define RTL8367C_PORT0_PERMIT_OFFSET 0 +#define RTL8367C_PORT0_PERMIT_MASK 0x1 + +#define RTL8367C_REG_ACL_GPIO_POLARITY 0x06d7 +#define RTL8367C_ACL_GPIO_POLARITY_OFFSET 0 +#define RTL8367C_ACL_GPIO_POLARITY_MASK 0x1 + +#define RTL8367C_REG_ACL_LOG_CNT_TYPE 0x06d8 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_OFFSET 15 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_MASK 0x8000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_OFFSET 14 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_MASK 0x4000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_OFFSET 13 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_MASK 0x2000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_OFFSET 12 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_MASK 0x1000 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_OFFSET 11 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_MASK 0x800 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_OFFSET 10 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_MASK 0x400 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_OFFSET 9 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_MASK 0x200 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_OFFSET 8 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_MASK 0x100 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_OFFSET 7 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_MASK 0x80 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_OFFSET 6 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_MASK 0x40 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_OFFSET 5 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_MASK 0x20 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_OFFSET 4 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_MASK 0x10 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_OFFSET 3 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_MASK 0x8 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_OFFSET 2 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_MASK 0x4 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_OFFSET 1 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_MASK 0x2 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_OFFSET 0 +#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_MASK 0x1 + +#define RTL8367C_REG_ACL_RESET_CFG 0x06d9 +#define RTL8367C_ACL_RESET_CFG_OFFSET 0 +#define RTL8367C_ACL_RESET_CFG_MASK 0x1 + +#define RTL8367C_REG_ACL_DUMMY00 0x06E0 + +#define RTL8367C_REG_ACL_DUMMY01 0x06E1 + +#define RTL8367C_REG_ACL_DUMMY02 0x06E2 + +#define RTL8367C_REG_ACL_DUMMY03 0x06E3 + +#define RTL8367C_REG_ACL_DUMMY04 0x06E4 + +#define RTL8367C_REG_ACL_DUMMY05 0x06E5 + +#define RTL8367C_REG_ACL_DUMMY06 0x06E6 + +#define RTL8367C_REG_ACL_DUMMY07 0x06E7 + +#define RTL8367C_REG_ACL_REASON_01 0x06E8 +#define RTL8367C_ACL_ACT_1_OFFSET 8 +#define RTL8367C_ACL_ACT_1_MASK 0xFF00 +#define RTL8367C_ACL_ACT_0_OFFSET 0 +#define RTL8367C_ACL_ACT_0_MASK 0xFF + +#define RTL8367C_REG_ACL_REASON_23 0x06E9 +#define RTL8367C_ACL_ACT_3_OFFSET 8 +#define RTL8367C_ACL_ACT_3_MASK 0xFF00 +#define RTL8367C_ACL_ACT_2_OFFSET 0 +#define RTL8367C_ACL_ACT_2_MASK 0xFF + +#define RTL8367C_REG_ACL_REASON_45 0x06EA +#define RTL8367C_ACL_ACT_5_OFFSET 8 +#define RTL8367C_ACL_ACT_5_MASK 0xFF00 +#define RTL8367C_ACL_ACT_4_OFFSET 0 +#define RTL8367C_ACL_ACT_4_MASK 0xFF + +#define RTL8367C_REG_ACL_ACCESS_MODE 0x06EB +#define RTL8367C_ACL_ACCESS_MODE_OFFSET 0 +#define RTL8367C_ACL_ACCESS_MODE_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL32 0x06F0 +#define RTL8367C_OP65_NOT_OFFSET 14 +#define RTL8367C_OP65_NOT_MASK 0x4000 +#define RTL8367C_ACT65_GPIO_OFFSET 13 +#define RTL8367C_ACT65_GPIO_MASK 0x2000 +#define RTL8367C_ACT65_FORWARD_OFFSET 12 +#define RTL8367C_ACT65_FORWARD_MASK 0x1000 +#define RTL8367C_ACT65_POLICING_OFFSET 11 +#define RTL8367C_ACT65_POLICING_MASK 0x800 +#define RTL8367C_ACT65_PRIORITY_OFFSET 10 +#define RTL8367C_ACT65_PRIORITY_MASK 0x400 +#define RTL8367C_ACT65_SVID_OFFSET 9 +#define RTL8367C_ACT65_SVID_MASK 0x200 +#define RTL8367C_ACT65_CVID_OFFSET 8 +#define RTL8367C_ACT65_CVID_MASK 0x100 +#define RTL8367C_OP64_NOT_OFFSET 6 +#define RTL8367C_OP64_NOT_MASK 0x40 +#define RTL8367C_ACT64_GPIO_OFFSET 5 +#define RTL8367C_ACT64_GPIO_MASK 0x20 +#define RTL8367C_ACT64_FORWARD_OFFSET 4 +#define RTL8367C_ACT64_FORWARD_MASK 0x10 +#define RTL8367C_ACT64_POLICING_OFFSET 3 +#define RTL8367C_ACT64_POLICING_MASK 0x8 +#define RTL8367C_ACT64_PRIORITY_OFFSET 2 +#define RTL8367C_ACT64_PRIORITY_MASK 0x4 +#define RTL8367C_ACT64_SVID_OFFSET 1 +#define RTL8367C_ACT64_SVID_MASK 0x2 +#define RTL8367C_ACT64_CVID_OFFSET 0 +#define RTL8367C_ACT64_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL33 0x06F1 +#define RTL8367C_OP67_NOT_OFFSET 14 +#define RTL8367C_OP67_NOT_MASK 0x4000 +#define RTL8367C_ACT67_GPIO_OFFSET 13 +#define RTL8367C_ACT67_GPIO_MASK 0x2000 +#define RTL8367C_ACT67_FORWARD_OFFSET 12 +#define RTL8367C_ACT67_FORWARD_MASK 0x1000 +#define RTL8367C_ACT67_POLICING_OFFSET 11 +#define RTL8367C_ACT67_POLICING_MASK 0x800 +#define RTL8367C_ACT67_PRIORITY_OFFSET 10 +#define RTL8367C_ACT67_PRIORITY_MASK 0x400 +#define RTL8367C_ACT67_SVID_OFFSET 9 +#define RTL8367C_ACT67_SVID_MASK 0x200 +#define RTL8367C_ACT67_CVID_OFFSET 8 +#define RTL8367C_ACT67_CVID_MASK 0x100 +#define RTL8367C_OP66_NOT_OFFSET 6 +#define RTL8367C_OP66_NOT_MASK 0x40 +#define RTL8367C_ACT66_GPIO_OFFSET 5 +#define RTL8367C_ACT66_GPIO_MASK 0x20 +#define RTL8367C_ACT66_FORWARD_OFFSET 4 +#define RTL8367C_ACT66_FORWARD_MASK 0x10 +#define RTL8367C_ACT66_POLICING_OFFSET 3 +#define RTL8367C_ACT66_POLICING_MASK 0x8 +#define RTL8367C_ACT66_PRIORITY_OFFSET 2 +#define RTL8367C_ACT66_PRIORITY_MASK 0x4 +#define RTL8367C_ACT66_SVID_OFFSET 1 +#define RTL8367C_ACT66_SVID_MASK 0x2 +#define RTL8367C_ACT66_CVID_OFFSET 0 +#define RTL8367C_ACT66_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL34 0x06F2 +#define RTL8367C_OP69_NOT_OFFSET 14 +#define RTL8367C_OP69_NOT_MASK 0x4000 +#define RTL8367C_ACT69_GPIO_OFFSET 13 +#define RTL8367C_ACT69_GPIO_MASK 0x2000 +#define RTL8367C_ACT69_FORWARD_OFFSET 12 +#define RTL8367C_ACT69_FORWARD_MASK 0x1000 +#define RTL8367C_ACT69_POLICING_OFFSET 11 +#define RTL8367C_ACT69_POLICING_MASK 0x800 +#define RTL8367C_ACT69_PRIORITY_OFFSET 10 +#define RTL8367C_ACT69_PRIORITY_MASK 0x400 +#define RTL8367C_ACT69_SVID_OFFSET 9 +#define RTL8367C_ACT69_SVID_MASK 0x200 +#define RTL8367C_ACT69_CVID_OFFSET 8 +#define RTL8367C_ACT69_CVID_MASK 0x100 +#define RTL8367C_OP68_NOT_OFFSET 6 +#define RTL8367C_OP68_NOT_MASK 0x40 +#define RTL8367C_ACT68_GPIO_OFFSET 5 +#define RTL8367C_ACT68_GPIO_MASK 0x20 +#define RTL8367C_ACT68_FORWARD_OFFSET 4 +#define RTL8367C_ACT68_FORWARD_MASK 0x10 +#define RTL8367C_ACT68_POLICING_OFFSET 3 +#define RTL8367C_ACT68_POLICING_MASK 0x8 +#define RTL8367C_ACT68_PRIORITY_OFFSET 2 +#define RTL8367C_ACT68_PRIORITY_MASK 0x4 +#define RTL8367C_ACT68_SVID_OFFSET 1 +#define RTL8367C_ACT68_SVID_MASK 0x2 +#define RTL8367C_ACT68_CVID_OFFSET 0 +#define RTL8367C_ACT68_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL35 0x06F3 +#define RTL8367C_OP71_NOT_OFFSET 14 +#define RTL8367C_OP71_NOT_MASK 0x4000 +#define RTL8367C_ACT71_GPIO_OFFSET 13 +#define RTL8367C_ACT71_GPIO_MASK 0x2000 +#define RTL8367C_ACT71_FORWARD_OFFSET 12 +#define RTL8367C_ACT71_FORWARD_MASK 0x1000 +#define RTL8367C_ACT71_POLICING_OFFSET 11 +#define RTL8367C_ACT71_POLICING_MASK 0x800 +#define RTL8367C_ACT71_PRIORITY_OFFSET 10 +#define RTL8367C_ACT71_PRIORITY_MASK 0x400 +#define RTL8367C_ACT71_SVID_OFFSET 9 +#define RTL8367C_ACT71_SVID_MASK 0x200 +#define RTL8367C_ACT71_CVID_OFFSET 8 +#define RTL8367C_ACT71_CVID_MASK 0x100 +#define RTL8367C_OP70_NOT_OFFSET 6 +#define RTL8367C_OP70_NOT_MASK 0x40 +#define RTL8367C_ACT70_GPIO_OFFSET 5 +#define RTL8367C_ACT70_GPIO_MASK 0x20 +#define RTL8367C_ACT70_FORWARD_OFFSET 4 +#define RTL8367C_ACT70_FORWARD_MASK 0x10 +#define RTL8367C_ACT70_POLICING_OFFSET 3 +#define RTL8367C_ACT70_POLICING_MASK 0x8 +#define RTL8367C_ACT70_PRIORITY_OFFSET 2 +#define RTL8367C_ACT70_PRIORITY_MASK 0x4 +#define RTL8367C_ACT70_SVID_OFFSET 1 +#define RTL8367C_ACT70_SVID_MASK 0x2 +#define RTL8367C_ACT70_CVID_OFFSET 0 +#define RTL8367C_ACT70_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL36 0x06F4 +#define RTL8367C_OP73_NOT_OFFSET 14 +#define RTL8367C_OP73_NOT_MASK 0x4000 +#define RTL8367C_ACT73_GPIO_OFFSET 13 +#define RTL8367C_ACT73_GPIO_MASK 0x2000 +#define RTL8367C_ACT73_FORWARD_OFFSET 12 +#define RTL8367C_ACT73_FORWARD_MASK 0x1000 +#define RTL8367C_ACT73_POLICING_OFFSET 11 +#define RTL8367C_ACT73_POLICING_MASK 0x800 +#define RTL8367C_ACT73_PRIORITY_OFFSET 10 +#define RTL8367C_ACT73_PRIORITY_MASK 0x400 +#define RTL8367C_ACT73_SVID_OFFSET 9 +#define RTL8367C_ACT73_SVID_MASK 0x200 +#define RTL8367C_ACT73_CVID_OFFSET 8 +#define RTL8367C_ACT73_CVID_MASK 0x100 +#define RTL8367C_OP72_NOT_OFFSET 6 +#define RTL8367C_OP72_NOT_MASK 0x40 +#define RTL8367C_ACT72_GPIO_OFFSET 5 +#define RTL8367C_ACT72_GPIO_MASK 0x20 +#define RTL8367C_ACT72_FORWARD_OFFSET 4 +#define RTL8367C_ACT72_FORWARD_MASK 0x10 +#define RTL8367C_ACT72_POLICING_OFFSET 3 +#define RTL8367C_ACT72_POLICING_MASK 0x8 +#define RTL8367C_ACT72_PRIORITY_OFFSET 2 +#define RTL8367C_ACT72_PRIORITY_MASK 0x4 +#define RTL8367C_ACT72_SVID_OFFSET 1 +#define RTL8367C_ACT72_SVID_MASK 0x2 +#define RTL8367C_ACT72_CVID_OFFSET 0 +#define RTL8367C_ACT72_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL37 0x06F5 +#define RTL8367C_OP75_NOT_OFFSET 14 +#define RTL8367C_OP75_NOT_MASK 0x4000 +#define RTL8367C_ACT75_GPIO_OFFSET 13 +#define RTL8367C_ACT75_GPIO_MASK 0x2000 +#define RTL8367C_ACT75_FORWARD_OFFSET 12 +#define RTL8367C_ACT75_FORWARD_MASK 0x1000 +#define RTL8367C_ACT75_POLICING_OFFSET 11 +#define RTL8367C_ACT75_POLICING_MASK 0x800 +#define RTL8367C_ACT75_PRIORITY_OFFSET 10 +#define RTL8367C_ACT75_PRIORITY_MASK 0x400 +#define RTL8367C_ACT75_SVID_OFFSET 9 +#define RTL8367C_ACT75_SVID_MASK 0x200 +#define RTL8367C_ACT75_CVID_OFFSET 8 +#define RTL8367C_ACT75_CVID_MASK 0x100 +#define RTL8367C_OP74_NOT_OFFSET 6 +#define RTL8367C_OP74_NOT_MASK 0x40 +#define RTL8367C_ACT74_GPIO_OFFSET 5 +#define RTL8367C_ACT74_GPIO_MASK 0x20 +#define RTL8367C_ACT74_FORWARD_OFFSET 4 +#define RTL8367C_ACT74_FORWARD_MASK 0x10 +#define RTL8367C_ACT74_POLICING_OFFSET 3 +#define RTL8367C_ACT74_POLICING_MASK 0x8 +#define RTL8367C_ACT74_PRIORITY_OFFSET 2 +#define RTL8367C_ACT74_PRIORITY_MASK 0x4 +#define RTL8367C_ACT74_SVID_OFFSET 1 +#define RTL8367C_ACT74_SVID_MASK 0x2 +#define RTL8367C_ACT74_CVID_OFFSET 0 +#define RTL8367C_ACT74_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL38 0x06F6 +#define RTL8367C_OP77_NOT_OFFSET 14 +#define RTL8367C_OP77_NOT_MASK 0x4000 +#define RTL8367C_ACT77_GPIO_OFFSET 13 +#define RTL8367C_ACT77_GPIO_MASK 0x2000 +#define RTL8367C_ACT77_FORWARD_OFFSET 12 +#define RTL8367C_ACT77_FORWARD_MASK 0x1000 +#define RTL8367C_ACT77_POLICING_OFFSET 11 +#define RTL8367C_ACT77_POLICING_MASK 0x800 +#define RTL8367C_ACT77_PRIORITY_OFFSET 10 +#define RTL8367C_ACT77_PRIORITY_MASK 0x400 +#define RTL8367C_ACT77_SVID_OFFSET 9 +#define RTL8367C_ACT77_SVID_MASK 0x200 +#define RTL8367C_ACT77_CVID_OFFSET 8 +#define RTL8367C_ACT77_CVID_MASK 0x100 +#define RTL8367C_OP76_NOT_OFFSET 6 +#define RTL8367C_OP76_NOT_MASK 0x40 +#define RTL8367C_ACT76_GPIO_OFFSET 5 +#define RTL8367C_ACT76_GPIO_MASK 0x20 +#define RTL8367C_ACT76_FORWARD_OFFSET 4 +#define RTL8367C_ACT76_FORWARD_MASK 0x10 +#define RTL8367C_ACT76_POLICING_OFFSET 3 +#define RTL8367C_ACT76_POLICING_MASK 0x8 +#define RTL8367C_ACT76_PRIORITY_OFFSET 2 +#define RTL8367C_ACT76_PRIORITY_MASK 0x4 +#define RTL8367C_ACT76_SVID_OFFSET 1 +#define RTL8367C_ACT76_SVID_MASK 0x2 +#define RTL8367C_ACT76_CVID_OFFSET 0 +#define RTL8367C_ACT76_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL39 0x06F7 +#define RTL8367C_OP79_NOT_OFFSET 14 +#define RTL8367C_OP79_NOT_MASK 0x4000 +#define RTL8367C_ACT79_GPIO_OFFSET 13 +#define RTL8367C_ACT79_GPIO_MASK 0x2000 +#define RTL8367C_ACT79_FORWARD_OFFSET 12 +#define RTL8367C_ACT79_FORWARD_MASK 0x1000 +#define RTL8367C_ACT79_POLICING_OFFSET 11 +#define RTL8367C_ACT79_POLICING_MASK 0x800 +#define RTL8367C_ACT79_PRIORITY_OFFSET 10 +#define RTL8367C_ACT79_PRIORITY_MASK 0x400 +#define RTL8367C_ACT79_SVID_OFFSET 9 +#define RTL8367C_ACT79_SVID_MASK 0x200 +#define RTL8367C_ACT79_CVID_OFFSET 8 +#define RTL8367C_ACT79_CVID_MASK 0x100 +#define RTL8367C_OP78_NOT_OFFSET 6 +#define RTL8367C_OP78_NOT_MASK 0x40 +#define RTL8367C_ACT78_GPIO_OFFSET 5 +#define RTL8367C_ACT78_GPIO_MASK 0x20 +#define RTL8367C_ACT78_FORWARD_OFFSET 4 +#define RTL8367C_ACT78_FORWARD_MASK 0x10 +#define RTL8367C_ACT78_POLICING_OFFSET 3 +#define RTL8367C_ACT78_POLICING_MASK 0x8 +#define RTL8367C_ACT78_PRIORITY_OFFSET 2 +#define RTL8367C_ACT78_PRIORITY_MASK 0x4 +#define RTL8367C_ACT78_SVID_OFFSET 1 +#define RTL8367C_ACT78_SVID_MASK 0x2 +#define RTL8367C_ACT78_CVID_OFFSET 0 +#define RTL8367C_ACT78_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL40 0x06F8 +#define RTL8367C_OP81_NOT_OFFSET 14 +#define RTL8367C_OP81_NOT_MASK 0x4000 +#define RTL8367C_ACT81_GPIO_OFFSET 13 +#define RTL8367C_ACT81_GPIO_MASK 0x2000 +#define RTL8367C_ACT81_FORWARD_OFFSET 12 +#define RTL8367C_ACT81_FORWARD_MASK 0x1000 +#define RTL8367C_ACT81_POLICING_OFFSET 11 +#define RTL8367C_ACT81_POLICING_MASK 0x800 +#define RTL8367C_ACT81_PRIORITY_OFFSET 10 +#define RTL8367C_ACT81_PRIORITY_MASK 0x400 +#define RTL8367C_ACT81_SVID_OFFSET 9 +#define RTL8367C_ACT81_SVID_MASK 0x200 +#define RTL8367C_ACT81_CVID_OFFSET 8 +#define RTL8367C_ACT81_CVID_MASK 0x100 +#define RTL8367C_OP80_NOT_OFFSET 6 +#define RTL8367C_OP80_NOT_MASK 0x40 +#define RTL8367C_ACT80_GPIO_OFFSET 5 +#define RTL8367C_ACT80_GPIO_MASK 0x20 +#define RTL8367C_ACT80_FORWARD_OFFSET 4 +#define RTL8367C_ACT80_FORWARD_MASK 0x10 +#define RTL8367C_ACT80_POLICING_OFFSET 3 +#define RTL8367C_ACT80_POLICING_MASK 0x8 +#define RTL8367C_ACT80_PRIORITY_OFFSET 2 +#define RTL8367C_ACT80_PRIORITY_MASK 0x4 +#define RTL8367C_ACT80_SVID_OFFSET 1 +#define RTL8367C_ACT80_SVID_MASK 0x2 +#define RTL8367C_ACT80_CVID_OFFSET 0 +#define RTL8367C_ACT80_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL41 0x06F9 +#define RTL8367C_OP83_NOT_OFFSET 14 +#define RTL8367C_OP83_NOT_MASK 0x4000 +#define RTL8367C_ACT83_GPIO_OFFSET 13 +#define RTL8367C_ACT83_GPIO_MASK 0x2000 +#define RTL8367C_ACT83_FORWARD_OFFSET 12 +#define RTL8367C_ACT83_FORWARD_MASK 0x1000 +#define RTL8367C_ACT83_POLICING_OFFSET 11 +#define RTL8367C_ACT83_POLICING_MASK 0x800 +#define RTL8367C_ACT83_PRIORITY_OFFSET 10 +#define RTL8367C_ACT83_PRIORITY_MASK 0x400 +#define RTL8367C_ACT83_SVID_OFFSET 9 +#define RTL8367C_ACT83_SVID_MASK 0x200 +#define RTL8367C_ACT83_CVID_OFFSET 8 +#define RTL8367C_ACT83_CVID_MASK 0x100 +#define RTL8367C_OP82_NOT_OFFSET 6 +#define RTL8367C_OP82_NOT_MASK 0x40 +#define RTL8367C_ACT82_GPIO_OFFSET 5 +#define RTL8367C_ACT82_GPIO_MASK 0x20 +#define RTL8367C_ACT82_FORWARD_OFFSET 4 +#define RTL8367C_ACT82_FORWARD_MASK 0x10 +#define RTL8367C_ACT82_POLICING_OFFSET 3 +#define RTL8367C_ACT82_POLICING_MASK 0x8 +#define RTL8367C_ACT82_PRIORITY_OFFSET 2 +#define RTL8367C_ACT82_PRIORITY_MASK 0x4 +#define RTL8367C_ACT82_SVID_OFFSET 1 +#define RTL8367C_ACT82_SVID_MASK 0x2 +#define RTL8367C_ACT82_CVID_OFFSET 0 +#define RTL8367C_ACT82_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL42 0x06FA +#define RTL8367C_OP85_NOT_OFFSET 14 +#define RTL8367C_OP85_NOT_MASK 0x4000 +#define RTL8367C_ACT85_GPIO_OFFSET 13 +#define RTL8367C_ACT85_GPIO_MASK 0x2000 +#define RTL8367C_ACT85_FORWARD_OFFSET 12 +#define RTL8367C_ACT85_FORWARD_MASK 0x1000 +#define RTL8367C_ACT85_POLICING_OFFSET 11 +#define RTL8367C_ACT85_POLICING_MASK 0x800 +#define RTL8367C_ACT85_PRIORITY_OFFSET 10 +#define RTL8367C_ACT85_PRIORITY_MASK 0x400 +#define RTL8367C_ACT85_SVID_OFFSET 9 +#define RTL8367C_ACT85_SVID_MASK 0x200 +#define RTL8367C_ACT85_CVID_OFFSET 8 +#define RTL8367C_ACT85_CVID_MASK 0x100 +#define RTL8367C_OP84_NOT_OFFSET 6 +#define RTL8367C_OP84_NOT_MASK 0x40 +#define RTL8367C_ACT84_GPIO_OFFSET 5 +#define RTL8367C_ACT84_GPIO_MASK 0x20 +#define RTL8367C_ACT84_FORWARD_OFFSET 4 +#define RTL8367C_ACT84_FORWARD_MASK 0x10 +#define RTL8367C_ACT84_POLICING_OFFSET 3 +#define RTL8367C_ACT84_POLICING_MASK 0x8 +#define RTL8367C_ACT84_PRIORITY_OFFSET 2 +#define RTL8367C_ACT84_PRIORITY_MASK 0x4 +#define RTL8367C_ACT84_SVID_OFFSET 1 +#define RTL8367C_ACT84_SVID_MASK 0x2 +#define RTL8367C_ACT84_CVID_OFFSET 0 +#define RTL8367C_ACT84_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL43 0x06FB +#define RTL8367C_OP87_NOT_OFFSET 14 +#define RTL8367C_OP87_NOT_MASK 0x4000 +#define RTL8367C_ACT87_GPIO_OFFSET 13 +#define RTL8367C_ACT87_GPIO_MASK 0x2000 +#define RTL8367C_ACT87_FORWARD_OFFSET 12 +#define RTL8367C_ACT87_FORWARD_MASK 0x1000 +#define RTL8367C_ACT87_POLICING_OFFSET 11 +#define RTL8367C_ACT87_POLICING_MASK 0x800 +#define RTL8367C_ACT87_PRIORITY_OFFSET 10 +#define RTL8367C_ACT87_PRIORITY_MASK 0x400 +#define RTL8367C_ACT87_SVID_OFFSET 9 +#define RTL8367C_ACT87_SVID_MASK 0x200 +#define RTL8367C_ACT87_CVID_OFFSET 8 +#define RTL8367C_ACT87_CVID_MASK 0x100 +#define RTL8367C_OP86_NOT_OFFSET 6 +#define RTL8367C_OP86_NOT_MASK 0x40 +#define RTL8367C_ACT86_GPIO_OFFSET 5 +#define RTL8367C_ACT86_GPIO_MASK 0x20 +#define RTL8367C_ACT86_FORWARD_OFFSET 4 +#define RTL8367C_ACT86_FORWARD_MASK 0x10 +#define RTL8367C_ACT86_POLICING_OFFSET 3 +#define RTL8367C_ACT86_POLICING_MASK 0x8 +#define RTL8367C_ACT86_PRIORITY_OFFSET 2 +#define RTL8367C_ACT86_PRIORITY_MASK 0x4 +#define RTL8367C_ACT86_SVID_OFFSET 1 +#define RTL8367C_ACT86_SVID_MASK 0x2 +#define RTL8367C_ACT86_CVID_OFFSET 0 +#define RTL8367C_ACT86_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL44 0x06FC +#define RTL8367C_OP89_NOT_OFFSET 14 +#define RTL8367C_OP89_NOT_MASK 0x4000 +#define RTL8367C_ACT89_GPIO_OFFSET 13 +#define RTL8367C_ACT89_GPIO_MASK 0x2000 +#define RTL8367C_ACT89_FORWARD_OFFSET 12 +#define RTL8367C_ACT89_FORWARD_MASK 0x1000 +#define RTL8367C_ACT89_POLICING_OFFSET 11 +#define RTL8367C_ACT89_POLICING_MASK 0x800 +#define RTL8367C_ACT89_PRIORITY_OFFSET 10 +#define RTL8367C_ACT89_PRIORITY_MASK 0x400 +#define RTL8367C_ACT89_SVID_OFFSET 9 +#define RTL8367C_ACT89_SVID_MASK 0x200 +#define RTL8367C_ACT89_CVID_OFFSET 8 +#define RTL8367C_ACT89_CVID_MASK 0x100 +#define RTL8367C_OP88_NOT_OFFSET 6 +#define RTL8367C_OP88_NOT_MASK 0x40 +#define RTL8367C_ACT88_GPIO_OFFSET 5 +#define RTL8367C_ACT88_GPIO_MASK 0x20 +#define RTL8367C_ACT88_FORWARD_OFFSET 4 +#define RTL8367C_ACT88_FORWARD_MASK 0x10 +#define RTL8367C_ACT88_POLICING_OFFSET 3 +#define RTL8367C_ACT88_POLICING_MASK 0x8 +#define RTL8367C_ACT88_PRIORITY_OFFSET 2 +#define RTL8367C_ACT88_PRIORITY_MASK 0x4 +#define RTL8367C_ACT88_SVID_OFFSET 1 +#define RTL8367C_ACT88_SVID_MASK 0x2 +#define RTL8367C_ACT88_CVID_OFFSET 0 +#define RTL8367C_ACT88_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL45 0x06FD +#define RTL8367C_OP91_NOT_OFFSET 14 +#define RTL8367C_OP91_NOT_MASK 0x4000 +#define RTL8367C_ACT91_GPIO_OFFSET 13 +#define RTL8367C_ACT91_GPIO_MASK 0x2000 +#define RTL8367C_ACT91_FORWARD_OFFSET 12 +#define RTL8367C_ACT91_FORWARD_MASK 0x1000 +#define RTL8367C_ACT91_POLICING_OFFSET 11 +#define RTL8367C_ACT91_POLICING_MASK 0x800 +#define RTL8367C_ACT91_PRIORITY_OFFSET 10 +#define RTL8367C_ACT91_PRIORITY_MASK 0x400 +#define RTL8367C_ACT91_SVID_OFFSET 9 +#define RTL8367C_ACT91_SVID_MASK 0x200 +#define RTL8367C_ACT91_CVID_OFFSET 8 +#define RTL8367C_ACT91_CVID_MASK 0x100 +#define RTL8367C_OP90_NOT_OFFSET 6 +#define RTL8367C_OP90_NOT_MASK 0x40 +#define RTL8367C_ACT90_GPIO_OFFSET 5 +#define RTL8367C_ACT90_GPIO_MASK 0x20 +#define RTL8367C_ACT90_FORWARD_OFFSET 4 +#define RTL8367C_ACT90_FORWARD_MASK 0x10 +#define RTL8367C_ACT90_POLICING_OFFSET 3 +#define RTL8367C_ACT90_POLICING_MASK 0x8 +#define RTL8367C_ACT90_PRIORITY_OFFSET 2 +#define RTL8367C_ACT90_PRIORITY_MASK 0x4 +#define RTL8367C_ACT90_SVID_OFFSET 1 +#define RTL8367C_ACT90_SVID_MASK 0x2 +#define RTL8367C_ACT90_CVID_OFFSET 0 +#define RTL8367C_ACT90_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL46 0x06FE +#define RTL8367C_OP93_NOT_OFFSET 14 +#define RTL8367C_OP93_NOT_MASK 0x4000 +#define RTL8367C_ACT93_GPIO_OFFSET 13 +#define RTL8367C_ACT93_GPIO_MASK 0x2000 +#define RTL8367C_ACT93_FORWARD_OFFSET 12 +#define RTL8367C_ACT93_FORWARD_MASK 0x1000 +#define RTL8367C_ACT93_POLICING_OFFSET 11 +#define RTL8367C_ACT93_POLICING_MASK 0x800 +#define RTL8367C_ACT93_PRIORITY_OFFSET 10 +#define RTL8367C_ACT93_PRIORITY_MASK 0x400 +#define RTL8367C_ACT93_SVID_OFFSET 9 +#define RTL8367C_ACT93_SVID_MASK 0x200 +#define RTL8367C_ACT93_CVID_OFFSET 8 +#define RTL8367C_ACT93_CVID_MASK 0x100 +#define RTL8367C_OP92_NOT_OFFSET 6 +#define RTL8367C_OP92_NOT_MASK 0x40 +#define RTL8367C_ACT92_GPIO_OFFSET 5 +#define RTL8367C_ACT92_GPIO_MASK 0x20 +#define RTL8367C_ACT92_FORWARD_OFFSET 4 +#define RTL8367C_ACT92_FORWARD_MASK 0x10 +#define RTL8367C_ACT92_POLICING_OFFSET 3 +#define RTL8367C_ACT92_POLICING_MASK 0x8 +#define RTL8367C_ACT92_PRIORITY_OFFSET 2 +#define RTL8367C_ACT92_PRIORITY_MASK 0x4 +#define RTL8367C_ACT92_SVID_OFFSET 1 +#define RTL8367C_ACT92_SVID_MASK 0x2 +#define RTL8367C_ACT92_CVID_OFFSET 0 +#define RTL8367C_ACT92_CVID_MASK 0x1 + +#define RTL8367C_REG_ACL_ACTION_CTRL47 0x06FF +#define RTL8367C_OP95_NOT_OFFSET 14 +#define RTL8367C_OP95_NOT_MASK 0x4000 +#define RTL8367C_ACT95_GPIO_OFFSET 13 +#define RTL8367C_ACT95_GPIO_MASK 0x2000 +#define RTL8367C_ACT95_FORWARD_OFFSET 12 +#define RTL8367C_ACT95_FORWARD_MASK 0x1000 +#define RTL8367C_ACT95_POLICING_OFFSET 11 +#define RTL8367C_ACT95_POLICING_MASK 0x800 +#define RTL8367C_ACT95_PRIORITY_OFFSET 10 +#define RTL8367C_ACT95_PRIORITY_MASK 0x400 +#define RTL8367C_ACT95_SVID_OFFSET 9 +#define RTL8367C_ACT95_SVID_MASK 0x200 +#define RTL8367C_ACT95_CVID_OFFSET 8 +#define RTL8367C_ACT95_CVID_MASK 0x100 +#define RTL8367C_OP94_NOT_OFFSET 6 +#define RTL8367C_OP94_NOT_MASK 0x40 +#define RTL8367C_ACT94_GPIO_OFFSET 5 +#define RTL8367C_ACT94_GPIO_MASK 0x20 +#define RTL8367C_ACT94_FORWARD_OFFSET 4 +#define RTL8367C_ACT94_FORWARD_MASK 0x10 +#define RTL8367C_ACT94_POLICING_OFFSET 3 +#define RTL8367C_ACT94_POLICING_MASK 0x8 +#define RTL8367C_ACT94_PRIORITY_OFFSET 2 +#define RTL8367C_ACT94_PRIORITY_MASK 0x4 +#define RTL8367C_ACT94_SVID_OFFSET 1 +#define RTL8367C_ACT94_SVID_MASK 0x2 +#define RTL8367C_ACT94_CVID_OFFSET 0 +#define RTL8367C_ACT94_CVID_MASK 0x1 + +/* (16'h0700)cvlan_reg */ + +#define RTL8367C_REG_VLAN_PVID_CTRL0 0x0700 +#define RTL8367C_PORT1_VIDX_OFFSET 8 +#define RTL8367C_PORT1_VIDX_MASK 0x1F00 +#define RTL8367C_PORT0_VIDX_OFFSET 0 +#define RTL8367C_PORT0_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL1 0x0701 +#define RTL8367C_PORT3_VIDX_OFFSET 8 +#define RTL8367C_PORT3_VIDX_MASK 0x1F00 +#define RTL8367C_PORT2_VIDX_OFFSET 0 +#define RTL8367C_PORT2_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL2 0x0702 +#define RTL8367C_PORT5_VIDX_OFFSET 8 +#define RTL8367C_PORT5_VIDX_MASK 0x1F00 +#define RTL8367C_PORT4_VIDX_OFFSET 0 +#define RTL8367C_PORT4_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL3 0x0703 +#define RTL8367C_PORT7_VIDX_OFFSET 8 +#define RTL8367C_PORT7_VIDX_MASK 0x1F00 +#define RTL8367C_PORT6_VIDX_OFFSET 0 +#define RTL8367C_PORT6_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL4 0x0704 +#define RTL8367C_PORT9_VIDX_OFFSET 8 +#define RTL8367C_PORT9_VIDX_MASK 0x1F00 +#define RTL8367C_PORT8_VIDX_OFFSET 0 +#define RTL8367C_PORT8_VIDX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PVID_CTRL5 0x0705 +#define RTL8367C_VLAN_PVID_CTRL5_OFFSET 0 +#define RTL8367C_VLAN_PVID_CTRL5_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_VALID 0x0708 +#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB0_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB0_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB0_CTRL0 0x0709 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL1 0x070a +#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL2 0x070b +#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL4 0x070c +#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB0_CTRL3 0x070f + +#define RTL8367C_REG_VLAN_PPB1_VALID 0x0710 +#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB1_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB1_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB1_CTRL0 0x0711 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL1 0x0712 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL2 0x0713 +#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL4 0x0714 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB1_CTRL3 0x0717 + +#define RTL8367C_REG_VLAN_PPB2_VALID 0x0718 +#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB2_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB2_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB2_CTRL0 0x0719 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL1 0x071a +#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL2 0x071b +#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL4 0x071c +#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB2_CTRL3 0x071f + +#define RTL8367C_REG_VLAN_PPB3_VALID 0x0720 +#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_OFFSET 8 +#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_MASK 0x700 +#define RTL8367C_VLAN_PPB3_VALID_VALID_OFFSET 0 +#define RTL8367C_VLAN_PPB3_VALID_VALID_MASK 0xFF + +#define RTL8367C_REG_VLAN_PPB3_CTRL0 0x0721 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL1 0x0722 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL2 0x0723 +#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL4 0x0724 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_OFFSET 10 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_MASK 0x7C00 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_OFFSET 5 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_MASK 0x3E0 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_OFFSET 0 +#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_MASK 0x1F + +#define RTL8367C_REG_VLAN_PPB3_CTRL3 0x0727 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 0x0728 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL1 0x0729 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL2 0x072a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL3 0x072b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL0 0x072c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL1 0x072d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL2 0x072e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL3 0x072f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL0 0x0730 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL1 0x0731 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL2 0x0732 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL3 0x0733 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL0 0x0734 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL1 0x0735 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL2 0x0736 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL3 0x0737 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL0 0x0738 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL1 0x0739 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL2 0x073a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL3 0x073b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL0 0x073c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL1 0x073d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL2 0x073e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL3 0x073f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL0 0x0740 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL1 0x0741 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL2 0x0742 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL3 0x0743 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL0 0x0744 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL1 0x0745 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL2 0x0746 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL3 0x0747 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL0 0x0748 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL1 0x0749 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL2 0x074a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL3 0x074b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL0 0x074c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL1 0x074d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL2 0x074e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL3 0x074f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL0 0x0750 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL1 0x0751 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL2 0x0752 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL3 0x0753 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL0 0x0754 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL1 0x0755 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL2 0x0756 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL3 0x0757 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL0 0x0758 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL1 0x0759 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL2 0x075a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL3 0x075b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL0 0x075c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL1 0x075d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL2 0x075e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL3 0x075f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL0 0x0760 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL1 0x0761 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL2 0x0762 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL3 0x0763 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL0 0x0764 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL1 0x0765 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL2 0x0766 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL3 0x0767 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL0 0x0768 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL1 0x0769 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL2 0x076a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL3 0x076b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL0 0x076c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL1 0x076d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL2 0x076e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL3 0x076f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL0 0x0770 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL1 0x0771 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL2 0x0772 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL3 0x0773 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL0 0x0774 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL1 0x0775 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL2 0x0776 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL3 0x0777 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL0 0x0778 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL1 0x0779 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL2 0x077a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL3 0x077b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL0 0x077c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL1 0x077d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL2 0x077e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL3 0x077f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL0 0x0780 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL1 0x0781 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL2 0x0782 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL3 0x0783 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL0 0x0784 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL1 0x0785 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL2 0x0786 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL3 0x0787 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL0 0x0788 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL1 0x0789 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL2 0x078a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL3 0x078b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL0 0x078c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL1 0x078d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL2 0x078e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL3 0x078f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL0 0x0790 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL1 0x0791 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL2 0x0792 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL3 0x0793 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL0 0x0794 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL1 0x0795 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL2 0x0796 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL3 0x0797 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL0 0x0798 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL1 0x0799 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL2 0x079a +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL3 0x079b +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL0 0x079c +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL1 0x079d +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL2 0x079e +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL3 0x079f +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL0 0x07a0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL1 0x07a1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL2 0x07a2 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL3 0x07a3 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL0 0x07a4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_OFFSET 8 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_MASK 0x700 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_MASK 0xFF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL1 0x07a5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_MASK 0xF + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL2 0x07a6 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_OFFSET 10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_MASK 0x400 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_OFFSET 5 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_MASK 0x3E0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_OFFSET 4 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_MASK 0x10 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_OFFSET 1 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_MASK 0xE +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_MASK 0x1 + +#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL3 0x07a7 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_VLAN_CTRL 0x07a8 +#define RTL8367C_VLAN_CTRL_OFFSET 0 +#define RTL8367C_VLAN_CTRL_MASK 0x1 + +#define RTL8367C_REG_VLAN_INGRESS 0x07a9 +#define RTL8367C_VLAN_INGRESS_OFFSET 0 +#define RTL8367C_VLAN_INGRESS_MASK 0x7FF + +#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 0x07aa +#define RTL8367C_PORT7_FRAME_TYPE_OFFSET 14 +#define RTL8367C_PORT7_FRAME_TYPE_MASK 0xC000 +#define RTL8367C_PORT6_FRAME_TYPE_OFFSET 12 +#define RTL8367C_PORT6_FRAME_TYPE_MASK 0x3000 +#define RTL8367C_PORT5_FRAME_TYPE_OFFSET 10 +#define RTL8367C_PORT5_FRAME_TYPE_MASK 0xC00 +#define RTL8367C_PORT4_FRAME_TYPE_OFFSET 8 +#define RTL8367C_PORT4_FRAME_TYPE_MASK 0x300 +#define RTL8367C_PORT3_FRAME_TYPE_OFFSET 6 +#define RTL8367C_PORT3_FRAME_TYPE_MASK 0xC0 +#define RTL8367C_PORT2_FRAME_TYPE_OFFSET 4 +#define RTL8367C_PORT2_FRAME_TYPE_MASK 0x30 +#define RTL8367C_PORT1_FRAME_TYPE_OFFSET 2 +#define RTL8367C_PORT1_FRAME_TYPE_MASK 0xC +#define RTL8367C_PORT0_FRAME_TYPE_OFFSET 0 +#define RTL8367C_PORT0_FRAME_TYPE_MASK 0x3 + +#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL1 0x07ab +#define RTL8367C_PORT10_FRAME_TYPE_OFFSET 4 +#define RTL8367C_PORT10_FRAME_TYPE_MASK 0x30 +#define RTL8367C_PORT9_FRAME_TYPE_OFFSET 2 +#define RTL8367C_PORT9_FRAME_TYPE_MASK 0xC +#define RTL8367C_PORT8_FRAME_TYPE_OFFSET 0 +#define RTL8367C_PORT8_FRAME_TYPE_MASK 0x3 + +#define RTL8367C_REG_PORT_PBFIDEN 0x07ac +#define RTL8367C_PORT_PBFIDEN_OFFSET 0 +#define RTL8367C_PORT_PBFIDEN_MASK 0x7FF + +#define RTL8367C_REG_PORT0_PBFID 0x07ad +#define RTL8367C_PORT0_PBFID_OFFSET 0 +#define RTL8367C_PORT0_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT1_PBFID 0x07ae +#define RTL8367C_PORT1_PBFID_OFFSET 0 +#define RTL8367C_PORT1_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT2_PBFID 0x07af +#define RTL8367C_PORT2_PBFID_OFFSET 0 +#define RTL8367C_PORT2_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT3_PBFID 0x07b0 +#define RTL8367C_PORT3_PBFID_OFFSET 0 +#define RTL8367C_PORT3_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT4_PBFID 0x07b1 +#define RTL8367C_PORT4_PBFID_OFFSET 0 +#define RTL8367C_PORT4_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT5_PBFID 0x07b2 +#define RTL8367C_PORT5_PBFID_OFFSET 0 +#define RTL8367C_PORT5_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT6_PBFID 0x07b3 +#define RTL8367C_PORT6_PBFID_OFFSET 0 +#define RTL8367C_PORT6_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT7_PBFID 0x07b4 +#define RTL8367C_PORT7_PBFID_OFFSET 0 +#define RTL8367C_PORT7_PBFID_MASK 0xF + +#define RTL8367C_REG_VLAN_EXT_CTRL 0x07b5 +#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET 2 +#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_MASK 0x4 +#define RTL8367C_VLAN_VID4095_TYPE_OFFSET 1 +#define RTL8367C_VLAN_VID4095_TYPE_MASK 0x2 +#define RTL8367C_VLAN_VID0_TYPE_OFFSET 0 +#define RTL8367C_VLAN_VID0_TYPE_MASK 0x1 + +#define RTL8367C_REG_VLAN_EXT_CTRL2 0x07b6 +#define RTL8367C_VLAN_EXT_CTRL2_OFFSET 0 +#define RTL8367C_VLAN_EXT_CTRL2_MASK 0x1 + +#define RTL8367C_REG_PORT8_PBFID 0x07b7 +#define RTL8367C_PORT8_PBFID_OFFSET 0 +#define RTL8367C_PORT8_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT9_PBFID 0x07b8 +#define RTL8367C_PORT9_PBFID_OFFSET 0 +#define RTL8367C_PORT9_PBFID_MASK 0xF + +#define RTL8367C_REG_PORT10_PBFID 0x07b9 +#define RTL8367C_PORT10_PBFID_OFFSET 0 +#define RTL8367C_PORT10_PBFID_MASK 0xF + +#define RTL8367C_REG_CVLAN_DUMMY00 0x07E0 + +#define RTL8367C_REG_CVLAN_DUMMY01 0x07E1 + +#define RTL8367C_REG_CVLAN_DUMMY02 0x07E2 + +#define RTL8367C_REG_CVLAN_DUMMY03 0x07E3 + +#define RTL8367C_REG_CVLAN_DUMMY04 0x07E4 + +#define RTL8367C_REG_CVLAN_DUMMY05 0x07E5 + +#define RTL8367C_REG_CVLAN_DUMMY06 0x07E6 + +#define RTL8367C_REG_CVLAN_DUMMY07 0x07E7 + +#define RTL8367C_REG_CVLAN_DUMMY08 0x07E8 + +#define RTL8367C_REG_CVLAN_DUMMY09 0x07E9 + +#define RTL8367C_REG_CVLAN_DUMMY10 0x07EA + +#define RTL8367C_REG_CVLAN_DUMMY11 0x07EB + +#define RTL8367C_REG_CVLAN_DUMMY12 0x07EC + +#define RTL8367C_REG_CVLAN_DUMMY13 0x07ED + +#define RTL8367C_REG_CVLAN_DUMMY14 0x07EE + +#define RTL8367C_REG_CVLAN_DUMMY15 0x07EF + +/* (16'h0800)dpm_reg */ + +#define RTL8367C_REG_RMA_CTRL00 0x0800 +#define RTL8367C_RMA_CTRL00_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL00_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_TRAP_PRIORITY_OFFSET 3 +#define RTL8367C_TRAP_PRIORITY_MASK 0x38 +#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL01 0x0801 +#define RTL8367C_RMA_CTRL01_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL01_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL02 0x0802 +#define RTL8367C_RMA_CTRL02_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL02_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL03 0x0803 +#define RTL8367C_RMA_CTRL03_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL03_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL04 0x0804 +#define RTL8367C_RMA_CTRL04_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL04_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL08 0x0808 +#define RTL8367C_RMA_CTRL08_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL08_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL0D 0x080d +#define RTL8367C_RMA_CTRL0D_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL0D_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL0E 0x080e +#define RTL8367C_RMA_CTRL0E_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL0E_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL10 0x0810 +#define RTL8367C_RMA_CTRL10_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL10_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL11 0x0811 +#define RTL8367C_RMA_CTRL11_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL11_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL12 0x0812 +#define RTL8367C_RMA_CTRL12_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL12_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL13 0x0813 +#define RTL8367C_RMA_CTRL13_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL13_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL18 0x0818 +#define RTL8367C_RMA_CTRL18_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL18_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL1A 0x081a +#define RTL8367C_RMA_CTRL1A_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL1A_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL20 0x0820 +#define RTL8367C_RMA_CTRL20_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL20_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL21 0x0821 +#define RTL8367C_RMA_CTRL21_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL21_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL22 0x0822 +#define RTL8367C_RMA_CTRL22_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL22_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL_CDP 0x0830 +#define RTL8367C_RMA_CTRL_CDP_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL_CDP_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL_CSSTP 0x0831 +#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_CTRL_LLDP 0x0832 +#define RTL8367C_RMA_CTRL_LLDP_OPERATION_OFFSET 7 +#define RTL8367C_RMA_CTRL_LLDP_OPERATION_MASK 0x180 +#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_OFFSET 6 +#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_MASK 0x40 +#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_OFFSET 2 +#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_MASK 0x4 +#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_MASK 0x1 + +#define RTL8367C_REG_RMA_LLDP_EN 0x0833 +#define RTL8367C_RMA_LLDP_EN_OFFSET 0 +#define RTL8367C_RMA_LLDP_EN_MASK 0x1 + +#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 0x0851 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL1 0x0852 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL2 0x0853 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 0x0855 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL1 0x0856 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL2 0x0857 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL0 0x0859 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL1 0x085a +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL2 0x085b +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL0 0x085d +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL1 0x085e +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL2 0x085f +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL0 0x0861 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL1 0x0862 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL2 0x0863 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 0x0865 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL1 0x0866 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 0x0867 +#define RTL8367C_DSCP3_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP3_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP2_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP2_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP1_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP1_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP0_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL1 0x0868 +#define RTL8367C_DSCP7_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP7_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP6_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP6_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP5_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP5_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP4_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL2 0x0869 +#define RTL8367C_DSCP11_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP11_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP10_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP10_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP9_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP9_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP8_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL3 0x086a +#define RTL8367C_DSCP15_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP15_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP14_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP14_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP13_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP13_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP12_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP12_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL4 0x086b +#define RTL8367C_DSCP19_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP19_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP18_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP18_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP17_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP17_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP16_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP16_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL5 0x086c +#define RTL8367C_DSCP23_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP23_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP22_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP22_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP21_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP21_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP20_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP20_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL6 0x086d +#define RTL8367C_DSCP27_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP27_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP26_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP26_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP25_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP25_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP24_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP24_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL7 0x086e +#define RTL8367C_DSCP31_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP31_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP30_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP30_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP29_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP29_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP28_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP28_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL8 0x086f +#define RTL8367C_DSCP35_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP35_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP34_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP34_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP33_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP33_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP32_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP32_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL9 0x0870 +#define RTL8367C_DSCP39_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP39_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP38_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP38_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP37_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP37_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP36_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP36_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL10 0x0871 +#define RTL8367C_DSCP43_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP43_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP42_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP42_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP41_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP41_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP40_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP40_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL11 0x0872 +#define RTL8367C_DSCP47_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP47_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP46_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP46_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP45_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP45_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP44_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP44_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL12 0x0873 +#define RTL8367C_DSCP51_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP51_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP50_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP50_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP49_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP49_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP48_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP48_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL13 0x0874 +#define RTL8367C_DSCP55_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP55_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP54_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP54_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP53_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP53_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP52_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP52_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL14 0x0875 +#define RTL8367C_DSCP59_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP59_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP58_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP58_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP57_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP57_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP56_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP56_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL15 0x0876 +#define RTL8367C_DSCP63_PRIORITY_OFFSET 12 +#define RTL8367C_DSCP63_PRIORITY_MASK 0x7000 +#define RTL8367C_DSCP62_PRIORITY_OFFSET 8 +#define RTL8367C_DSCP62_PRIORITY_MASK 0x700 +#define RTL8367C_DSCP61_PRIORITY_OFFSET 4 +#define RTL8367C_DSCP61_PRIORITY_MASK 0x70 +#define RTL8367C_DSCP60_PRIORITY_OFFSET 0 +#define RTL8367C_DSCP60_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 0x0877 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL1 0x0878 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_DUMMY0879 0x0879 +#define RTL8367C_DUMMY0879_OFFSET 0 +#define RTL8367C_DUMMY0879_MASK 0x1 + +#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2 0x087a +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 +#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 0x087b +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL1 0x087c +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL2 0x087d +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL3 0x087e +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 0x087f +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_OFFSET 12 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_MASK 0x7000 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_OFFSET 8 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_MASK 0x700 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_OFFSET 4 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_MASK 0x70 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_OFFSET 0 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK 0x7 + +#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1 0x0880 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_OFFSET 12 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_MASK 0x7000 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_OFFSET 8 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_MASK 0x700 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_OFFSET 4 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_MASK 0x70 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_OFFSET 0 +#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_MASK 0x7 + +#define RTL8367C_REG_QOS_TRAP_PRIORITY0 0x0881 +#define RTL8367C_UNKNOWN_MC_PRIORTY_OFFSET 12 +#define RTL8367C_UNKNOWN_MC_PRIORTY_MASK 0x7000 +#define RTL8367C_SVLAN_PRIOIRTY_OFFSET 8 +#define RTL8367C_SVLAN_PRIOIRTY_MASK 0x700 +#define RTL8367C_OAM_PRIOIRTY_OFFSET 4 +#define RTL8367C_OAM_PRIOIRTY_MASK 0x70 +#define RTL8367C_DOT1X_PRIORTY_OFFSET 0 +#define RTL8367C_DOT1X_PRIORTY_MASK 0x7 + +#define RTL8367C_REG_QOS_TRAP_PRIORITY1 0x0882 +#define RTL8367C_DW8051_TRAP_PRI_OFFSET 4 +#define RTL8367C_DW8051_TRAP_PRI_MASK 0x70 +#define RTL8367C_EEELLDP_TRAP_PRI_OFFSET 0 +#define RTL8367C_EEELLDP_TRAP_PRI_MASK 0x7 + +#define RTL8367C_REG_MAX_LENGTH_CFG 0x0883 +#define RTL8367C_MAX_LENGTH_GIGA_OFFSET 8 +#define RTL8367C_MAX_LENGTH_GIGA_MASK 0xFF00 +#define RTL8367C_MAX_LENGTH_10_100M_OFFSET 0 +#define RTL8367C_MAX_LENGTH_10_100M_MASK 0xFF + +#define RTL8367C_REG_MAX_LEN_RX_TX 0x0884 +#define RTL8367C_MAX_LEN_RX_TX_OFFSET 0 +#define RTL8367C_MAX_LEN_RX_TX_MASK 0x3 + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 0x0885 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1 0x0886 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2 0x0887 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3 0x0888 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_OFFSET 8 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF + +#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX 0x0889 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_OFFSET 0 +#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_MASK 0x7FF + +#define RTL8367C_REG_MAX_LENGTH_CFG_EXT 0x088a +#define RTL8367C_MAX_LENGTH_GIGA_EXT_OFFSET 3 +#define RTL8367C_MAX_LENGTH_GIGA_EXT_MASK 0x38 +#define RTL8367C_MAX_LENGTH_10_100M_EXT_OFFSET 0 +#define RTL8367C_MAX_LENGTH_10_100M_EXT_MASK 0x7 + +#define RTL8367C_REG_MAX_LEN_RX_TX_CFG0 0x088c +#define RTL8367C_MAX_LEN_RX_TX_CFG0_OFFSET 0 +#define RTL8367C_MAX_LEN_RX_TX_CFG0_MASK 0x3FFF + +#define RTL8367C_REG_MAX_LEN_RX_TX_CFG1 0x088d +#define RTL8367C_MAX_LEN_RX_TX_CFG1_OFFSET 0 +#define RTL8367C_MAX_LEN_RX_TX_CFG1_MASK 0x3FFF + +#define RTL8367C_REG_UNDA_FLOODING_PMSK 0x0890 +#define RTL8367C_UNDA_FLOODING_PMSK_OFFSET 0 +#define RTL8367C_UNDA_FLOODING_PMSK_MASK 0x7FF + +#define RTL8367C_REG_UNMCAST_FLOADING_PMSK 0x0891 +#define RTL8367C_UNMCAST_FLOADING_PMSK_OFFSET 0 +#define RTL8367C_UNMCAST_FLOADING_PMSK_MASK 0x7FF + +#define RTL8367C_REG_BCAST_FLOADING_PMSK 0x0892 +#define RTL8367C_BCAST_FLOADING_PMSK_OFFSET 0 +#define RTL8367C_BCAST_FLOADING_PMSK_MASK 0x7FF + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2 0x08a0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK 0x3 + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3 0x08a1 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK 0x3 + +#define RTL8367C_REG_PORT_ISOLATION_PORT0_MASK 0x08a2 +#define RTL8367C_PORT_ISOLATION_PORT0_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT0_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT1_MASK 0x08a3 +#define RTL8367C_PORT_ISOLATION_PORT1_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT1_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT2_MASK 0x08a4 +#define RTL8367C_PORT_ISOLATION_PORT2_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT2_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT3_MASK 0x08a5 +#define RTL8367C_PORT_ISOLATION_PORT3_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT3_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT4_MASK 0x08a6 +#define RTL8367C_PORT_ISOLATION_PORT4_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT4_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT5_MASK 0x08a7 +#define RTL8367C_PORT_ISOLATION_PORT5_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT5_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT6_MASK 0x08a8 +#define RTL8367C_PORT_ISOLATION_PORT6_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT6_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT7_MASK 0x08a9 +#define RTL8367C_PORT_ISOLATION_PORT7_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT7_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT8_MASK 0x08aa +#define RTL8367C_PORT_ISOLATION_PORT8_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT8_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT9_MASK 0x08ab +#define RTL8367C_PORT_ISOLATION_PORT9_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT9_MASK_MASK 0x7FF + +#define RTL8367C_REG_PORT_ISOLATION_PORT10_MASK 0x08ac +#define RTL8367C_PORT_ISOLATION_PORT10_MASK_OFFSET 0 +#define RTL8367C_PORT_ISOLATION_PORT10_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_CTRL 0x08b4 +#define RTL8367C_FORCE_CTRL_OFFSET 0 +#define RTL8367C_FORCE_CTRL_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT0_MASK 0x08b5 +#define RTL8367C_FORCE_PORT0_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT0_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT1_MASK 0x08b6 +#define RTL8367C_FORCE_PORT1_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT1_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT2_MASK 0x08b7 +#define RTL8367C_FORCE_PORT2_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT2_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT3_MASK 0x08b8 +#define RTL8367C_FORCE_PORT3_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT3_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT4_MASK 0x08b9 +#define RTL8367C_FORCE_PORT4_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT4_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT5_MASK 0x08ba +#define RTL8367C_FORCE_PORT5_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT5_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT6_MASK 0x08bb +#define RTL8367C_FORCE_PORT6_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT6_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT7_MASK 0x08bc +#define RTL8367C_FORCE_PORT7_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT7_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT8_MASK 0x08bd +#define RTL8367C_FORCE_PORT8_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT8_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT9_MASK 0x08be +#define RTL8367C_FORCE_PORT9_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT9_MASK_MASK 0x7FF + +#define RTL8367C_REG_FORCE_PORT10_MASK 0x08bf +#define RTL8367C_FORCE_PORT10_MASK_OFFSET 0 +#define RTL8367C_FORCE_PORT10_MASK_MASK 0x7FF + +#define RTL8367C_REG_SOURCE_PORT_PERMIT 0x08c5 +#define RTL8367C_SOURCE_PORT_PERMIT_OFFSET 0 +#define RTL8367C_SOURCE_PORT_PERMIT_MASK 0x7FF + +#define RTL8367C_REG_IPMCAST_VLAN_LEAKY 0x08c6 +#define RTL8367C_IPMCAST_VLAN_LEAKY_OFFSET 0 +#define RTL8367C_IPMCAST_VLAN_LEAKY_MASK 0x7FF + +#define RTL8367C_REG_IPMCAST_PORTISO_LEAKY 0x08c7 +#define RTL8367C_IPMCAST_PORTISO_LEAKY_OFFSET 0 +#define RTL8367C_IPMCAST_PORTISO_LEAKY_MASK 0x7FF + +#define RTL8367C_REG_PORT_SECURITY_CTRL 0x08c8 +#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_OFFSET 6 +#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK 0xC0 +#define RTL8367C_LUT_LEARN_OVER_ACT_OFFSET 4 +#define RTL8367C_LUT_LEARN_OVER_ACT_MASK 0x30 +#define RTL8367C_UNMATCHED_SA_BEHAVE_OFFSET 2 +#define RTL8367C_UNMATCHED_SA_BEHAVE_MASK 0xC +#define RTL8367C_UNKNOWN_SA_BEHAVE_OFFSET 0 +#define RTL8367C_UNKNOWN_SA_BEHAVE_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 0x08c9 +#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_OFFSET 14 +#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_MASK 0xC000 +#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_OFFSET 12 +#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_MASK 0x3000 +#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_OFFSET 10 +#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_MASK 0xC00 +#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_OFFSET 8 +#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_MASK 0x300 +#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_OFFSET 6 +#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_MASK 0xC0 +#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_OFFSET 4 +#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_MASK 0x30 +#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_OFFSET 2 +#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_MASK 0xC +#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_OFFSET 0 +#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL1 0x08ca +#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_OFFSET 4 +#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_MASK 0x30 +#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_OFFSET 2 +#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_MASK 0xC +#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_OFFSET 0 +#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 0x08cb +#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_OFFSET 14 +#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_MASK 0xC000 +#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_OFFSET 12 +#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_MASK 0x3000 +#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_OFFSET 10 +#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_MASK 0xC00 +#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_OFFSET 8 +#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_MASK 0x300 +#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_OFFSET 6 +#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_MASK 0xC0 +#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_OFFSET 4 +#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_MASK 0x30 +#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_OFFSET 2 +#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_MASK 0xC +#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_OFFSET 0 +#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL1 0x08cc +#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_OFFSET 4 +#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_MASK 0x30 +#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_OFFSET 2 +#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_MASK 0xC +#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_OFFSET 0 +#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_MASK 0x3 + +#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 0x08cd +#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_OFFSET 14 +#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_MASK 0xC000 +#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_OFFSET 12 +#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_MASK 0x3000 +#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_OFFSET 10 +#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_MASK 0xC00 +#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_OFFSET 8 +#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_MASK 0x300 +#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_OFFSET 6 +#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_MASK 0xC0 +#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_OFFSET 4 +#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_MASK 0x30 +#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_OFFSET 2 +#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_MASK 0xC +#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_OFFSET 0 +#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK 0x3 + +#define RTL8367C_REG_PORT_TRUNK_DROP_CTRL 0x08ce +#define RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET 0 +#define RTL8367C_PORT_TRUNK_DROP_CTRL_MASK 0x1 + +#define RTL8367C_REG_PORT_TRUNK_CTRL 0x08cf +#define RTL8367C_PORT_TRUNK_DUMB_OFFSET 8 +#define RTL8367C_PORT_TRUNK_DUMB_MASK 0x100 +#define RTL8367C_PORT_TRUNK_FLOOD_OFFSET 7 +#define RTL8367C_PORT_TRUNK_FLOOD_MASK 0x80 +#define RTL8367C_DPORT_HASH_OFFSET 6 +#define RTL8367C_DPORT_HASH_MASK 0x40 +#define RTL8367C_SPORT_HASH_OFFSET 5 +#define RTL8367C_SPORT_HASH_MASK 0x20 +#define RTL8367C_DIP_HASH_OFFSET 4 +#define RTL8367C_DIP_HASH_MASK 0x10 +#define RTL8367C_SIP_HASH_OFFSET 3 +#define RTL8367C_SIP_HASH_MASK 0x8 +#define RTL8367C_DMAC_HASH_OFFSET 2 +#define RTL8367C_DMAC_HASH_MASK 0x4 +#define RTL8367C_SMAC_HASH_OFFSET 1 +#define RTL8367C_SMAC_HASH_MASK 0x2 +#define RTL8367C_SPA_HASH_OFFSET 0 +#define RTL8367C_SPA_HASH_MASK 0x1 + +#define RTL8367C_REG_PORT_TRUNK_GROUP_MASK 0x08d0 +#define RTL8367C_PORT_TRUNK_GROUP2_MASK_OFFSET 8 +#define RTL8367C_PORT_TRUNK_GROUP2_MASK_MASK 0x300 +#define RTL8367C_PORT_TRUNK_GROUP1_MASK_OFFSET 4 +#define RTL8367C_PORT_TRUNK_GROUP1_MASK_MASK 0xF0 +#define RTL8367C_PORT_TRUNK_GROUP0_MASK_OFFSET 0 +#define RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK 0xF + +#define RTL8367C_REG_PORT_TRUNK_FLOWCTRL 0x08d1 +#define RTL8367C_EN_FLOWCTRL_TG2_OFFSET 2 +#define RTL8367C_EN_FLOWCTRL_TG2_MASK 0x4 +#define RTL8367C_EN_FLOWCTRL_TG1_OFFSET 1 +#define RTL8367C_EN_FLOWCTRL_TG1_MASK 0x2 +#define RTL8367C_EN_FLOWCTRL_TG0_OFFSET 0 +#define RTL8367C_EN_FLOWCTRL_TG0_MASK 0x1 + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0 0x08d2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK 0x3 + +#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1 0x08d3 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_OFFSET 14 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_MASK 0xC000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_OFFSET 12 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_MASK 0x3000 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_OFFSET 10 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_MASK 0xC00 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_OFFSET 8 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_MASK 0x300 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_OFFSET 6 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_MASK 0xC0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_OFFSET 4 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_MASK 0x30 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_OFFSET 2 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_MASK 0xC +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_OFFSET 0 +#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK 0x3 + +#define RTL8367C_REG_DOS_CFG 0x08d4 +#define RTL8367C_DROP_ICMPFRAGMENT_OFFSET 9 +#define RTL8367C_DROP_ICMPFRAGMENT_MASK 0x200 +#define RTL8367C_DROP_TCPFRAGERROR_OFFSET 8 +#define RTL8367C_DROP_TCPFRAGERROR_MASK 0x100 +#define RTL8367C_DROP_TCPSHORTHDR_OFFSET 7 +#define RTL8367C_DROP_TCPSHORTHDR_MASK 0x80 +#define RTL8367C_DROP_SYN1024_OFFSET 6 +#define RTL8367C_DROP_SYN1024_MASK 0x40 +#define RTL8367C_DROP_NULLSCAN_OFFSET 5 +#define RTL8367C_DROP_NULLSCAN_MASK 0x20 +#define RTL8367C_DROP_XMASCAN_OFFSET 4 +#define RTL8367C_DROP_XMASCAN_MASK 0x10 +#define RTL8367C_DROP_SYNFINSCAN_OFFSET 3 +#define RTL8367C_DROP_SYNFINSCAN_MASK 0x8 +#define RTL8367C_DROP_BLATATTACKS_OFFSET 2 +#define RTL8367C_DROP_BLATATTACKS_MASK 0x4 +#define RTL8367C_DROP_LANDATTACKS_OFFSET 1 +#define RTL8367C_DROP_LANDATTACKS_MASK 0x2 +#define RTL8367C_DROP_DAEQSA_OFFSET 0 +#define RTL8367C_DROP_DAEQSA_MASK 0x1 + +#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1 0x08d5 +#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_OFFSET 4 +#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_MASK 0x30 +#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_OFFSET 2 +#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_MASK 0xC +#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_OFFSET 0 +#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_MASK 0x3 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4 0x08d6 +#define RTL8367C_PORT9_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT9_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5 0x08d7 +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT 0x08d8 +#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1_EXT 0x08d9 +#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2_EXT 0x08da +#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3_EXT 0x08db +#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT 0x08dc +#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_OFFSET 3 +#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK 0x38 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_OFFSET 0 +#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT 0x08dd +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK 0x7 + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL10 0x08de +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_MASK 0x7FF + +#define RTL8367C_REG_FPGA_VER_CEN 0x08e0 + +#define RTL8367C_REG_FPGA_TIME_CEN 0x08e1 + +#define RTL8367C_REG_FPGA_DATE_CEN 0x08e2 + +#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 0x0900 +#define RTL8367C_PORT3_NUMBER_OFFSET 12 +#define RTL8367C_PORT3_NUMBER_MASK 0x7000 +#define RTL8367C_PORT2_NUMBER_OFFSET 8 +#define RTL8367C_PORT2_NUMBER_MASK 0x700 +#define RTL8367C_PORT1_NUMBER_OFFSET 4 +#define RTL8367C_PORT1_NUMBER_MASK 0x70 +#define RTL8367C_PORT0_NUMBER_OFFSET 0 +#define RTL8367C_PORT0_NUMBER_MASK 0x7 + +#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL1 0x0901 +#define RTL8367C_PORT7_NUMBER_OFFSET 12 +#define RTL8367C_PORT7_NUMBER_MASK 0x7000 +#define RTL8367C_PORT6_NUMBER_OFFSET 8 +#define RTL8367C_PORT6_NUMBER_MASK 0x700 +#define RTL8367C_PORT5_NUMBER_OFFSET 4 +#define RTL8367C_PORT5_NUMBER_MASK 0x70 +#define RTL8367C_PORT4_NUMBER_OFFSET 0 +#define RTL8367C_PORT4_NUMBER_MASK 0x7 + +#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL2 0x0902 +#define RTL8367C_PORT10_NUMBER_OFFSET 8 +#define RTL8367C_PORT10_NUMBER_MASK 0x700 +#define RTL8367C_PORT9_NUMBER_OFFSET 4 +#define RTL8367C_PORT9_NUMBER_MASK 0x70 +#define RTL8367C_PORT8_NUMBER_OFFSET 0 +#define RTL8367C_PORT8_NUMBER_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 0x0904 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL1 0x0905 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL0 0x0906 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL1 0x0907 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL0 0x0908 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL1 0x0909 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL0 0x090a +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL1 0x090b +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL0 0x090c +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL1 0x090d +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL0 0x090e +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL1 0x090f +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL0 0x0910 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL1 0x0911 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL0 0x0912 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 + +#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL1 0x0913 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 +#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 + +#define RTL8367C_REG_HIGHPRI_INDICATOR 0x0915 +#define RTL8367C_PORT10_INDICATOR_OFFSET 10 +#define RTL8367C_PORT10_INDICATOR_MASK 0x400 +#define RTL8367C_PORT9_INDICATOR_OFFSET 9 +#define RTL8367C_PORT9_INDICATOR_MASK 0x200 +#define RTL8367C_PORT8_INDICATOR_OFFSET 8 +#define RTL8367C_PORT8_INDICATOR_MASK 0x100 +#define RTL8367C_PORT7_INDICATOR_OFFSET 7 +#define RTL8367C_PORT7_INDICATOR_MASK 0x80 +#define RTL8367C_PORT6_INDICATOR_OFFSET 6 +#define RTL8367C_PORT6_INDICATOR_MASK 0x40 +#define RTL8367C_PORT5_INDICATOR_OFFSET 5 +#define RTL8367C_PORT5_INDICATOR_MASK 0x20 +#define RTL8367C_PORT4_INDICATOR_OFFSET 4 +#define RTL8367C_PORT4_INDICATOR_MASK 0x10 +#define RTL8367C_PORT3_INDICATOR_OFFSET 3 +#define RTL8367C_PORT3_INDICATOR_MASK 0x8 +#define RTL8367C_PORT2_INDICATOR_OFFSET 2 +#define RTL8367C_PORT2_INDICATOR_MASK 0x4 +#define RTL8367C_PORT1_INDICATOR_OFFSET 1 +#define RTL8367C_PORT1_INDICATOR_MASK 0x2 +#define RTL8367C_PORT0_INDICATOR_OFFSET 0 +#define RTL8367C_PORT0_INDICATOR_MASK 0x1 + +#define RTL8367C_REG_HIGHPRI_CFG 0x0916 +#define RTL8367C_HIGHPRI_CFG_OFFSET 0 +#define RTL8367C_HIGHPRI_CFG_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 0x0917 +#define RTL8367C_PORT1_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT1_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT0_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT0_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL1 0x0918 +#define RTL8367C_PORT3_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT3_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT2_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT2_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL2 0x0919 +#define RTL8367C_PORT5_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT5_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT4_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT4_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL3 0x091a +#define RTL8367C_PORT7_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT7_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT6_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT6_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL4 0x091b +#define RTL8367C_PORT9_DEBUG_INFO_OFFSET 8 +#define RTL8367C_PORT9_DEBUG_INFO_MASK 0xFF00 +#define RTL8367C_PORT8_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT8_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL5 0x091c +#define RTL8367C_PORT10_DEBUG_INFO_OFFSET 0 +#define RTL8367C_PORT10_DEBUG_INFO_MASK 0xFF + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL6 0x091d +#define RTL8367C_PORT7_DEBUG_INDICATOR_OFFSET 14 +#define RTL8367C_PORT7_DEBUG_INDICATOR_MASK 0xC000 +#define RTL8367C_PORT6_DEBUG_INDICATOR_OFFSET 12 +#define RTL8367C_PORT6_DEBUG_INDICATOR_MASK 0x3000 +#define RTL8367C_PORT5_DEBUG_INDICATOR_OFFSET 10 +#define RTL8367C_PORT5_DEBUG_INDICATOR_MASK 0xC00 +#define RTL8367C_PORT4_DEBUG_INDICATOR_OFFSET 8 +#define RTL8367C_PORT4_DEBUG_INDICATOR_MASK 0x300 +#define RTL8367C_PORT3_DEBUG_INDICATOR_OFFSET 6 +#define RTL8367C_PORT3_DEBUG_INDICATOR_MASK 0xC0 +#define RTL8367C_PORT2_DEBUG_INDICATOR_OFFSET 4 +#define RTL8367C_PORT2_DEBUG_INDICATOR_MASK 0x30 +#define RTL8367C_PORT1_DEBUG_INDICATOR_OFFSET 2 +#define RTL8367C_PORT1_DEBUG_INDICATOR_MASK 0xC +#define RTL8367C_PORT0_DEBUG_INDICATOR_OFFSET 0 +#define RTL8367C_PORT0_DEBUG_INDICATOR_MASK 0x3 + +#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL7 0x091e +#define RTL8367C_PORT10_DEBUG_INDICATOR_OFFSET 4 +#define RTL8367C_PORT10_DEBUG_INDICATOR_MASK 0x30 +#define RTL8367C_PORT9_DEBUG_INDICATOR_OFFSET 2 +#define RTL8367C_PORT9_DEBUG_INDICATOR_MASK 0xC +#define RTL8367C_PORT8_DEBUG_INDICATOR_OFFSET 0 +#define RTL8367C_PORT8_DEBUG_INDICATOR_MASK 0x3 + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 0x0930 +#define RTL8367C_PORT1_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT1_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT0_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT0_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL1 0x0931 +#define RTL8367C_PORT3_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT3_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT2_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT2_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL2 0x0932 +#define RTL8367C_PORT5_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT5_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT4_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT4_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL3 0x0933 +#define RTL8367C_PORT7_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT7_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT6_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT6_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL4 0x0934 +#define RTL8367C_PORT9_QUEUE_MASK_OFFSET 8 +#define RTL8367C_PORT9_QUEUE_MASK_MASK 0xFF00 +#define RTL8367C_PORT8_QUEUE_MASK_OFFSET 0 +#define RTL8367C_PORT8_QUEUE_MASK_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5 0x0935 +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_OFFSET 0 +#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_MASK 0xFF + +#define RTL8367C_REG_FLOWCRTL_EGRESS_PORT_ENABLE 0x0938 +#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_OFFSET 0 +#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_MASK 0xFF + +#define RTL8367C_REG_EAV_CTRL 0x0939 +#define RTL8367C_EAV_TRAP_CPU_OFFSET 1 +#define RTL8367C_EAV_TRAP_CPU_MASK 0x2 +#define RTL8367C_EAV_TRAP_8051_OFFSET 0 +#define RTL8367C_EAV_TRAP_8051_MASK 0x1 + +#define RTL8367C_REG_UNTAG_DSCP_PRI_CFG 0x093a +#define RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET 0 +#define RTL8367C_UNTAG_DSCP_PRI_CFG_MASK 0x1 + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 0x093b +#define RTL8367C_PORT1_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT1_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT0_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1 0x093c +#define RTL8367C_PORT3_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT3_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT2_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2 0x093d +#define RTL8367C_PORT5_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT5_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT4_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3 0x093e +#define RTL8367C_PORT7_VLAN_KEEP_MASK_OFFSET 8 +#define RTL8367C_PORT7_VLAN_KEEP_MASK_MASK 0xFF00 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_OFFSET 0 +#define RTL8367C_PORT6_VLAN_KEEP_MASK_MASK 0xFF + +#define RTL8367C_REG_VLAN_TRANSPARENT_EN_CFG 0x093f +#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_OFFSET 0 +#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_MASK 0x1 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY0_H 0x0940 +#define RTL8367C_IPMC_GROUP_ENTRY0_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY0_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY0_L 0x0941 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY1_H 0x0942 +#define RTL8367C_IPMC_GROUP_ENTRY1_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY1_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY1_L 0x0943 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY2_H 0x0944 +#define RTL8367C_IPMC_GROUP_ENTRY2_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY2_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY2_L 0x0945 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY3_H 0x0946 +#define RTL8367C_IPMC_GROUP_ENTRY3_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY3_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY3_L 0x0947 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY4_H 0x0948 +#define RTL8367C_IPMC_GROUP_ENTRY4_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY4_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY4_L 0x0949 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY5_H 0x094a +#define RTL8367C_IPMC_GROUP_ENTRY5_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY5_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY5_L 0x094b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY6_H 0x094c +#define RTL8367C_IPMC_GROUP_ENTRY6_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY6_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY6_L 0x094d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY7_H 0x094e +#define RTL8367C_IPMC_GROUP_ENTRY7_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY7_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY7_L 0x094f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY8_H 0x0950 +#define RTL8367C_IPMC_GROUP_ENTRY8_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY8_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY8_L 0x0951 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY9_H 0x0952 +#define RTL8367C_IPMC_GROUP_ENTRY9_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY9_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY9_L 0x0953 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY10_H 0x0954 +#define RTL8367C_IPMC_GROUP_ENTRY10_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY10_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY10_L 0x0955 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY11_H 0x0956 +#define RTL8367C_IPMC_GROUP_ENTRY11_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY11_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY11_L 0x0957 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY12_H 0x0958 +#define RTL8367C_IPMC_GROUP_ENTRY12_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY12_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY12_L 0x0959 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY13_H 0x095a +#define RTL8367C_IPMC_GROUP_ENTRY13_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY13_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY13_L 0x095b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY14_H 0x095c +#define RTL8367C_IPMC_GROUP_ENTRY14_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY14_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY14_L 0x095d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY15_H 0x095e +#define RTL8367C_IPMC_GROUP_ENTRY15_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY15_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY15_L 0x095f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY16_H 0x0960 +#define RTL8367C_IPMC_GROUP_ENTRY16_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY16_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY16_L 0x0961 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY17_H 0x0962 +#define RTL8367C_IPMC_GROUP_ENTRY17_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY17_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY17_L 0x0963 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY18_H 0x0964 +#define RTL8367C_IPMC_GROUP_ENTRY18_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY18_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY18_L 0x0965 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY19_H 0x0966 +#define RTL8367C_IPMC_GROUP_ENTRY19_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY19_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY19_L 0x0967 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY20_H 0x0968 +#define RTL8367C_IPMC_GROUP_ENTRY20_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY20_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY20_L 0x0969 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY21_H 0x096a +#define RTL8367C_IPMC_GROUP_ENTRY21_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY21_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY21_L 0x096b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY22_H 0x096c +#define RTL8367C_IPMC_GROUP_ENTRY22_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY22_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY22_L 0x096d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY23_H 0x096e +#define RTL8367C_IPMC_GROUP_ENTRY23_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY23_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY23_L 0x096f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY24_H 0x0970 +#define RTL8367C_IPMC_GROUP_ENTRY24_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY24_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY24_L 0x0971 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY25_H 0x0972 +#define RTL8367C_IPMC_GROUP_ENTRY25_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY25_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY25_L 0x0973 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY26_H 0x0974 +#define RTL8367C_IPMC_GROUP_ENTRY26_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY26_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY26_L 0x0975 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY27_H 0x0976 +#define RTL8367C_IPMC_GROUP_ENTRY27_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY27_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY27_L 0x0977 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY28_H 0x0978 +#define RTL8367C_IPMC_GROUP_ENTRY28_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY28_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY28_L 0x0979 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY29_H 0x097a +#define RTL8367C_IPMC_GROUP_ENTRY29_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY29_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY29_L 0x097b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY30_H 0x097c +#define RTL8367C_IPMC_GROUP_ENTRY30_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY30_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY30_L 0x097d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY31_H 0x097e +#define RTL8367C_IPMC_GROUP_ENTRY31_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY31_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY31_L 0x097f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY32_H 0x0980 +#define RTL8367C_IPMC_GROUP_ENTRY32_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY32_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY32_L 0x0981 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY33_H 0x0982 +#define RTL8367C_IPMC_GROUP_ENTRY33_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY33_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY33_L 0x0983 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY34_H 0x0984 +#define RTL8367C_IPMC_GROUP_ENTRY34_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY34_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY34_L 0x0985 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY35_H 0x0986 +#define RTL8367C_IPMC_GROUP_ENTRY35_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY35_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY35_L 0x0987 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY36_H 0x0988 +#define RTL8367C_IPMC_GROUP_ENTRY36_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY36_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY36_L 0x0989 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY37_H 0x098a +#define RTL8367C_IPMC_GROUP_ENTRY37_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY37_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY37_L 0x098b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY38_H 0x098c +#define RTL8367C_IPMC_GROUP_ENTRY38_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY38_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY38_L 0x098d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY39_H 0x098e +#define RTL8367C_IPMC_GROUP_ENTRY39_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY39_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY39_L 0x098f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY40_H 0x0990 +#define RTL8367C_IPMC_GROUP_ENTRY40_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY40_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY40_L 0x0991 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY41_H 0x0992 +#define RTL8367C_IPMC_GROUP_ENTRY41_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY41_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY41_L 0x0993 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY42_H 0x0994 +#define RTL8367C_IPMC_GROUP_ENTRY42_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY42_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY42_L 0x0995 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY43_H 0x0996 +#define RTL8367C_IPMC_GROUP_ENTRY43_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY43_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY43_L 0x0997 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY44_H 0x0998 +#define RTL8367C_IPMC_GROUP_ENTRY44_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY44_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY44_L 0x0999 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY45_H 0x099a +#define RTL8367C_IPMC_GROUP_ENTRY45_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY45_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY45_L 0x099b + +#define RTL8367C_REG_IPMC_GROUP_ENTRY46_H 0x099c +#define RTL8367C_IPMC_GROUP_ENTRY46_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY46_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY46_L 0x099d + +#define RTL8367C_REG_IPMC_GROUP_ENTRY47_H 0x099e +#define RTL8367C_IPMC_GROUP_ENTRY47_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY47_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY47_L 0x099f + +#define RTL8367C_REG_IPMC_GROUP_ENTRY48_H 0x09a0 +#define RTL8367C_IPMC_GROUP_ENTRY48_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY48_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY48_L 0x09a1 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY49_H 0x09a2 +#define RTL8367C_IPMC_GROUP_ENTRY49_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY49_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY49_L 0x09a3 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY50_H 0x09a4 +#define RTL8367C_IPMC_GROUP_ENTRY50_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY50_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY50_L 0x09a5 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY51_H 0x09a6 +#define RTL8367C_IPMC_GROUP_ENTRY51_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY51_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY51_L 0x09a7 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY52_H 0x09a8 +#define RTL8367C_IPMC_GROUP_ENTRY52_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY52_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY52_L 0x09a9 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY53_H 0x09aa +#define RTL8367C_IPMC_GROUP_ENTRY53_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY53_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY53_L 0x09ab + +#define RTL8367C_REG_IPMC_GROUP_ENTRY54_H 0x09ac +#define RTL8367C_IPMC_GROUP_ENTRY54_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY54_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY54_L 0x09ad + +#define RTL8367C_REG_IPMC_GROUP_ENTRY55_H 0x09ae +#define RTL8367C_IPMC_GROUP_ENTRY55_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY55_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY55_L 0x09af + +#define RTL8367C_REG_IPMC_GROUP_ENTRY56_H 0x09b0 +#define RTL8367C_IPMC_GROUP_ENTRY56_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY56_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY56_L 0x09b1 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY57_H 0x09b2 +#define RTL8367C_IPMC_GROUP_ENTRY57_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY57_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY57_L 0x09b3 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY58_H 0x09b4 +#define RTL8367C_IPMC_GROUP_ENTRY58_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY58_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY58_L 0x09b5 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY59_H 0x09b6 +#define RTL8367C_IPMC_GROUP_ENTRY59_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY59_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY59_L 0x09b7 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY60_H 0x09b8 +#define RTL8367C_IPMC_GROUP_ENTRY60_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY60_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY60_L 0x09b9 + +#define RTL8367C_REG_IPMC_GROUP_ENTRY61_H 0x09ba +#define RTL8367C_IPMC_GROUP_ENTRY61_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY61_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY61_L 0x09bb + +#define RTL8367C_REG_IPMC_GROUP_ENTRY62_H 0x09bc +#define RTL8367C_IPMC_GROUP_ENTRY62_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY62_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY62_L 0x09bd + +#define RTL8367C_REG_IPMC_GROUP_ENTRY63_H 0x09be +#define RTL8367C_IPMC_GROUP_ENTRY63_H_OFFSET 0 +#define RTL8367C_IPMC_GROUP_ENTRY63_H_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_ENTRY63_L 0x09bf + +#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE 0x09C0 +#define RTL8367C_Port7_ACTION_OFFSET 14 +#define RTL8367C_Port7_ACTION_MASK 0xC000 +#define RTL8367C_Port6_ACTION_OFFSET 12 +#define RTL8367C_Port6_ACTION_MASK 0x3000 +#define RTL8367C_Port5_ACTION_OFFSET 10 +#define RTL8367C_Port5_ACTION_MASK 0xC00 +#define RTL8367C_Port4_ACTION_OFFSET 8 +#define RTL8367C_Port4_ACTION_MASK 0x300 +#define RTL8367C_Port3_ACTION_OFFSET 6 +#define RTL8367C_Port3_ACTION_MASK 0xC0 +#define RTL8367C_Port2_ACTION_OFFSET 4 +#define RTL8367C_Port2_ACTION_MASK 0x30 +#define RTL8367C_Port1_ACTION_OFFSET 2 +#define RTL8367C_Port1_ACTION_MASK 0xC +#define RTL8367C_Port0_ACTION_OFFSET 0 +#define RTL8367C_Port0_ACTION_MASK 0x3 + +#define RTL8367C_REG_MIRROR_CTRL3 0x09C1 +#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET 2 +#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_MASK 0x4 +#define RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET 1 +#define RTL8367C_MIRROR_TX_OVERRIDE_EN_MASK 0x2 +#define RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET 0 +#define RTL8367C_MIRROR_RX_OVERRIDE_EN_MASK 0x1 + +#define RTL8367C_REG_DPM_DUMMY02 0x09C2 + +#define RTL8367C_REG_DPM_DUMMY03 0x09C3 + +#define RTL8367C_REG_DPM_DUMMY04 0x09C4 + +#define RTL8367C_REG_DPM_DUMMY05 0x09C5 + +#define RTL8367C_REG_DPM_DUMMY06 0x09C6 + +#define RTL8367C_REG_DPM_DUMMY07 0x09C7 + +#define RTL8367C_REG_DPM_DUMMY08 0x09C8 + +#define RTL8367C_REG_DPM_DUMMY09 0x09C9 + +#define RTL8367C_REG_DPM_DUMMY10 0x09CA + +#define RTL8367C_REG_DPM_DUMMY11 0x09CB + +#define RTL8367C_REG_DPM_DUMMY12 0x09CC + +#define RTL8367C_REG_DPM_DUMMY13 0x09CD + +#define RTL8367C_REG_DPM_DUMMY14 0x09CE + +#define RTL8367C_REG_DPM_DUMMY15 0x09CF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 0x09D0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL1 0x09D1 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL2 0x09D2 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL3 0x09D3 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL4 0x09D4 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL5 0x09D5 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL6 0x09D6 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL7 0x09D7 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL8 0x09D8 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_MASK 0x7FF + +#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL9 0x09D9 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_OFFSET 0 +#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_MASK 0x7FF + +#define RTL8367C_REG_MIRROR_CTRL2 0x09DA +#define RTL8367C_MIRROR_REALKEEP_EN_OFFSET 4 +#define RTL8367C_MIRROR_REALKEEP_EN_MASK 0x10 +#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET 3 +#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_MASK 0x8 +#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET 2 +#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_MASK 0x4 +#define RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET 1 +#define RTL8367C_MIRROR_RX_VLAN_LEAKY_MASK 0x2 +#define RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET 0 +#define RTL8367C_MIRROR_TX_VLAN_LEAKY_MASK 0x1 + +#define RTL8367C_REG_OUTPUT_DROP_CFG 0x09DB +#define RTL8367C_ENABLE_PMASK_EXT_OFFSET 13 +#define RTL8367C_ENABLE_PMASK_EXT_MASK 0xE000 +#define RTL8367C_ENABLE_BC_OFFSET 12 +#define RTL8367C_ENABLE_BC_MASK 0x1000 +#define RTL8367C_ENABLE_MC_OFFSET 11 +#define RTL8367C_ENABLE_MC_MASK 0x800 +#define RTL8367C_ENABLE_UC_OFFSET 10 +#define RTL8367C_ENABLE_UC_MASK 0x400 +#define RTL8367C_ENABLE_PMASK_OFFSET 0 +#define RTL8367C_ENABLE_PMASK_MASK 0xFF + +#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT 0x09DC +#define RTL8367C_PORT10_ACTION_OFFSET 4 +#define RTL8367C_PORT10_ACTION_MASK 0x30 +#define RTL8367C_PORT9_ACTION_OFFSET 2 +#define RTL8367C_PORT9_ACTION_MASK 0xC +#define RTL8367C_PORT8_ACTION_OFFSET 0 +#define RTL8367C_PORT8_ACTION_MASK 0x3 + +#define RTL8367C_REG_RMK_CFG_SEL_CTRL 0x09DF +#define RTL8367C_RMK_1Q_CFG_SEL_OFFSET 2 +#define RTL8367C_RMK_1Q_CFG_SEL_MASK 0x4 +#define RTL8367C_RMK_DSCP_CFG_SEL_OFFSET 0 +#define RTL8367C_RMK_DSCP_CFG_SEL_MASK 0x3 + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 0x09E0 +#define RTL8367C_DSCP1_DSCP_OFFSET 8 +#define RTL8367C_DSCP1_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP0_DSCP_OFFSET 0 +#define RTL8367C_DSCP0_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL1 0x09E1 +#define RTL8367C_DSCP3_DSCP_OFFSET 8 +#define RTL8367C_DSCP3_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP2_DSCP_OFFSET 0 +#define RTL8367C_DSCP2_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL2 0x09E2 +#define RTL8367C_DSCP5_DSCP_OFFSET 8 +#define RTL8367C_DSCP5_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP4_DSCP_OFFSET 0 +#define RTL8367C_DSCP4_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL3 0x09E3 +#define RTL8367C_DSCP7_DSCP_OFFSET 8 +#define RTL8367C_DSCP7_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP6_DSCP_OFFSET 0 +#define RTL8367C_DSCP6_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL4 0x09E4 +#define RTL8367C_DSCP9_DSCP_OFFSET 8 +#define RTL8367C_DSCP9_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP8_DSCP_OFFSET 0 +#define RTL8367C_DSCP8_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL5 0x09E5 +#define RTL8367C_DSCP11_DSCP_OFFSET 8 +#define RTL8367C_DSCP11_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP10_DSCP_OFFSET 0 +#define RTL8367C_DSCP10_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL6 0x09E6 +#define RTL8367C_DSCP13_DSCP_OFFSET 8 +#define RTL8367C_DSCP13_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP12_DSCP_OFFSET 0 +#define RTL8367C_DSCP12_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL7 0x09E7 +#define RTL8367C_DSCP15_DSCP_OFFSET 8 +#define RTL8367C_DSCP15_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP14_DSCP_OFFSET 0 +#define RTL8367C_DSCP14_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL8 0x09E8 +#define RTL8367C_DSCP17_DSCP_OFFSET 8 +#define RTL8367C_DSCP17_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP16_DSCP_OFFSET 0 +#define RTL8367C_DSCP16_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL9 0x09E9 +#define RTL8367C_DSCP19_DSCP_OFFSET 8 +#define RTL8367C_DSCP19_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP18_DSCP_OFFSET 0 +#define RTL8367C_DSCP18_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL10 0x09EA +#define RTL8367C_DSCP21_DSCP_OFFSET 8 +#define RTL8367C_DSCP21_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP20_DSCP_OFFSET 0 +#define RTL8367C_DSCP20_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL11 0x09EB +#define RTL8367C_DSCP23_DSCP_OFFSET 8 +#define RTL8367C_DSCP23_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP22_DSCP_OFFSET 0 +#define RTL8367C_DSCP22_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL12 0x09EC +#define RTL8367C_DSCP25_DSCP_OFFSET 8 +#define RTL8367C_DSCP25_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP24_DSCP_OFFSET 0 +#define RTL8367C_DSCP24_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL13 0x09ED +#define RTL8367C_DSCP27_DSCP_OFFSET 8 +#define RTL8367C_DSCP27_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP26_DSCP_OFFSET 0 +#define RTL8367C_DSCP26_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL14 0x09EE +#define RTL8367C_DSCP29_DSCP_OFFSET 8 +#define RTL8367C_DSCP29_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP28_DSCP_OFFSET 0 +#define RTL8367C_DSCP28_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL15 0x09EF +#define RTL8367C_DSCP31_DSCP_OFFSET 8 +#define RTL8367C_DSCP31_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP30_DSCP_OFFSET 0 +#define RTL8367C_DSCP30_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL16 0x09F0 +#define RTL8367C_DSCP33_DSCP_OFFSET 8 +#define RTL8367C_DSCP33_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP32_DSCP_OFFSET 0 +#define RTL8367C_DSCP32_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL17 0x09F1 +#define RTL8367C_DSCP35_DSCP_OFFSET 8 +#define RTL8367C_DSCP35_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP34_DSCP_OFFSET 0 +#define RTL8367C_DSCP34_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL18 0x09F2 +#define RTL8367C_DSCP37_DSCP_OFFSET 8 +#define RTL8367C_DSCP37_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP36_DSCP_OFFSET 0 +#define RTL8367C_DSCP36_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL19 0x09F3 +#define RTL8367C_DSCP39_DSCP_OFFSET 8 +#define RTL8367C_DSCP39_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP38_DSCP_OFFSET 0 +#define RTL8367C_DSCP38_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL20 0x09F4 +#define RTL8367C_DSCP41_DSCP_OFFSET 8 +#define RTL8367C_DSCP41_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP40_DSCP_OFFSET 0 +#define RTL8367C_DSCP40_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL21 0x09F5 +#define RTL8367C_DSCP43_DSCP_OFFSET 8 +#define RTL8367C_DSCP43_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP42_DSCP_OFFSET 0 +#define RTL8367C_DSCP42_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL22 0x09F6 +#define RTL8367C_DSCP45_DSCP_OFFSET 8 +#define RTL8367C_DSCP45_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP44_DSCP_OFFSET 0 +#define RTL8367C_DSCP44_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL23 0x09F7 +#define RTL8367C_DSCP47_DSCP_OFFSET 8 +#define RTL8367C_DSCP47_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP46_DSCP_OFFSET 0 +#define RTL8367C_DSCP46_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL24 0x09F8 +#define RTL8367C_DSCP49_DSCP_OFFSET 8 +#define RTL8367C_DSCP49_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP48_DSCP_OFFSET 0 +#define RTL8367C_DSCP48_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL25 0x09F9 +#define RTL8367C_DSCP51_DSCP_OFFSET 8 +#define RTL8367C_DSCP51_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP50_DSCP_OFFSET 0 +#define RTL8367C_DSCP50_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL26 0x09FA +#define RTL8367C_DSCP53_DSCP_OFFSET 8 +#define RTL8367C_DSCP53_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP52_DSCP_OFFSET 0 +#define RTL8367C_DSCP52_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL27 0x09FB +#define RTL8367C_DSCP55_DSCP_OFFSET 8 +#define RTL8367C_DSCP55_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP54_DSCP_OFFSET 0 +#define RTL8367C_DSCP54_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL28 0x09FC +#define RTL8367C_DSCP57_DSCP_OFFSET 8 +#define RTL8367C_DSCP57_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP56_DSCP_OFFSET 0 +#define RTL8367C_DSCP56_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL29 0x09FD +#define RTL8367C_DSCP59_DSCP_OFFSET 8 +#define RTL8367C_DSCP59_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP58_DSCP_OFFSET 0 +#define RTL8367C_DSCP58_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL30 0x09FE +#define RTL8367C_DSCP61_DSCP_OFFSET 8 +#define RTL8367C_DSCP61_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP60_DSCP_OFFSET 0 +#define RTL8367C_DSCP60_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL31 0x09FF +#define RTL8367C_DSCP63_DSCP_OFFSET 8 +#define RTL8367C_DSCP63_DSCP_MASK 0x3F00 +#define RTL8367C_DSCP62_DSCP_OFFSET 0 +#define RTL8367C_DSCP62_DSCP_MASK 0x3F + +/* (16'h0a00)l2_reg */ + +#define RTL8367C_REG_VLAN_MSTI0_CTRL0 0x0a00 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI0_CTRL1 0x0a01 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI1_CTRL0 0x0a02 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI1_CTRL1 0x0a03 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI2_CTRL0 0x0a04 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI2_CTRL1 0x0a05 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI3_CTRL0 0x0a06 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI3_CTRL1 0x0a07 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI4_CTRL0 0x0a08 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI4_CTRL1 0x0a09 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI5_CTRL0 0x0a0a +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI5_CTRL1 0x0a0b +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI6_CTRL0 0x0a0c +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI6_CTRL1 0x0a0d +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI7_CTRL0 0x0a0e +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI7_CTRL1 0x0a0f +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI8_CTRL0 0x0a10 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI8_CTRL1 0x0a11 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI9_CTRL0 0x0a12 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI9_CTRL1 0x0a13 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI10_CTRL0 0x0a14 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI10_CTRL1 0x0a15 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI11_CTRL0 0x0a16 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI11_CTRL1 0x0a17 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI12_CTRL0 0x0a18 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI12_CTRL1 0x0a19 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI13_CTRL0 0x0a1a +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI13_CTRL1 0x0a1b +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI14_CTRL0 0x0a1c +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI14_CTRL1 0x0a1d +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI15_CTRL0 0x0a1e +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_OFFSET 14 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_MASK 0xC000 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_OFFSET 12 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_MASK 0x3000 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_OFFSET 10 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_MASK 0xC00 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_OFFSET 8 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_MASK 0x300 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_OFFSET 6 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_MASK 0xC0 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_MASK 0x3 + +#define RTL8367C_REG_VLAN_MSTI15_CTRL1 0x0a1f +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_OFFSET 4 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_MASK 0x30 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_OFFSET 2 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_MASK 0xC +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_OFFSET 0 +#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_MASK 0x3 + +#define RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO 0x0a20 +#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT1_LEARN_LIMITNO 0x0a21 +#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT2_LEARN_LIMITNO 0x0a22 +#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT3_LEARN_LIMITNO 0x0a23 +#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT4_LEARN_LIMITNO 0x0a24 +#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT5_LEARN_LIMITNO 0x0a25 +#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT6_LEARN_LIMITNO 0x0a26 +#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT7_LEARN_LIMITNO 0x0a27 +#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_SYS_LEARN_LIMITNO 0x0a28 +#define RTL8367C_LUT_SYS_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_SYS_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL 0x0a29 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_OFFSET 12 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK 0x7000 +#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_OFFSET 10 +#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK 0xC00 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_OFFSET 0 +#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK 0xFF + +#define RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO 0x0a2a +#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT9_LEARN_LIMITNO 0x0a2b +#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_PORT10_LEARN_LIMITNO 0x0a2c +#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_OFFSET 0 +#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_MASK 0x1FFF + +#define RTL8367C_REG_LUT_CFG 0x0a30 +#define RTL8367C_AGE_SPEED_OFFSET 8 +#define RTL8367C_AGE_SPEED_MASK 0x300 +#define RTL8367C_BCAM_DISABLE_OFFSET 6 +#define RTL8367C_BCAM_DISABLE_MASK 0x40 +#define RTL8367C_LINKDOWN_AGEOUT_OFFSET 5 +#define RTL8367C_LINKDOWN_AGEOUT_MASK 0x20 +#define RTL8367C_LUT_IPMC_HASH_OFFSET 4 +#define RTL8367C_LUT_IPMC_HASH_MASK 0x10 +#define RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET 3 +#define RTL8367C_LUT_IPMC_LOOKUP_OP_MASK 0x8 +#define RTL8367C_AGE_TIMER_OFFSET 0 +#define RTL8367C_AGE_TIMER_MASK 0x7 + +#define RTL8367C_REG_LUT_AGEOUT_CTRL 0x0a31 +#define RTL8367C_LUT_AGEOUT_CTRL_OFFSET 0 +#define RTL8367C_LUT_AGEOUT_CTRL_MASK 0x7FF + +#define RTL8367C_REG_PORT_EFID_CTRL0 0x0a32 +#define RTL8367C_PORT3_EFID_OFFSET 12 +#define RTL8367C_PORT3_EFID_MASK 0x7000 +#define RTL8367C_PORT2_EFID_OFFSET 8 +#define RTL8367C_PORT2_EFID_MASK 0x700 +#define RTL8367C_PORT1_EFID_OFFSET 4 +#define RTL8367C_PORT1_EFID_MASK 0x70 +#define RTL8367C_PORT0_EFID_OFFSET 0 +#define RTL8367C_PORT0_EFID_MASK 0x7 + +#define RTL8367C_REG_PORT_EFID_CTRL1 0x0a33 +#define RTL8367C_PORT7_EFID_OFFSET 12 +#define RTL8367C_PORT7_EFID_MASK 0x7000 +#define RTL8367C_PORT6_EFID_OFFSET 8 +#define RTL8367C_PORT6_EFID_MASK 0x700 +#define RTL8367C_PORT5_EFID_OFFSET 4 +#define RTL8367C_PORT5_EFID_MASK 0x70 +#define RTL8367C_PORT4_EFID_OFFSET 0 +#define RTL8367C_PORT4_EFID_MASK 0x7 + +#define RTL8367C_REG_PORT_EFID_CTRL2 0x0a34 +#define RTL8367C_PORT10_EFID_OFFSET 8 +#define RTL8367C_PORT10_EFID_MASK 0x700 +#define RTL8367C_PORT9_EFID_OFFSET 4 +#define RTL8367C_PORT9_EFID_MASK 0x70 +#define RTL8367C_PORT8_EFID_OFFSET 0 +#define RTL8367C_PORT8_EFID_MASK 0x7 + +#define RTL8367C_REG_FORCE_FLUSH1 0x0a35 +#define RTL8367C_BUSY_STATUS1_OFFSET 3 +#define RTL8367C_BUSY_STATUS1_MASK 0x38 +#define RTL8367C_PORTMASK1_OFFSET 0 +#define RTL8367C_PORTMASK1_MASK 0x7 + +#define RTL8367C_REG_FORCE_FLUSH 0x0a36 +#define RTL8367C_BUSY_STATUS_OFFSET 8 +#define RTL8367C_BUSY_STATUS_MASK 0xFF00 +#define RTL8367C_FORCE_FLUSH_PORTMASK_OFFSET 0 +#define RTL8367C_FORCE_FLUSH_PORTMASK_MASK 0xFF + +#define RTL8367C_REG_L2_FLUSH_CTRL1 0x0a37 +#define RTL8367C_LUT_FLUSH_FID_OFFSET 12 +#define RTL8367C_LUT_FLUSH_FID_MASK 0xF000 +#define RTL8367C_LUT_FLUSH_VID_OFFSET 0 +#define RTL8367C_LUT_FLUSH_VID_MASK 0xFFF + +#define RTL8367C_REG_L2_FLUSH_CTRL2 0x0a38 +#define RTL8367C_LUT_FLUSH_TYPE_OFFSET 2 +#define RTL8367C_LUT_FLUSH_TYPE_MASK 0x4 +#define RTL8367C_LUT_FLUSH_MODE_OFFSET 0 +#define RTL8367C_LUT_FLUSH_MODE_MASK 0x3 + +#define RTL8367C_REG_L2_FLUSH_CTRL3 0x0a39 +#define RTL8367C_L2_FLUSH_CTRL3_OFFSET 0 +#define RTL8367C_L2_FLUSH_CTRL3_MASK 0x1 + +#define RTL8367C_REG_LUT_CFG2 0x0a3a +#define RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET 1 +#define RTL8367C_LUT_IPMC_FWD_RPORT_MASK 0x2 +#define RTL8367C_LUT_IPMC_VID_HASH_OFFSET 0 +#define RTL8367C_LUT_IPMC_VID_HASH_MASK 0x1 + +#define RTL8367C_REG_FLUSH_STATUS 0x0a3f +#define RTL8367C_FLUSH_STATUS_OFFSET 0 +#define RTL8367C_FLUSH_STATUS_MASK 0x1 + +#define RTL8367C_REG_STORM_BCAST 0x0a40 +#define RTL8367C_STORM_BCAST_OFFSET 0 +#define RTL8367C_STORM_BCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_MCAST 0x0a41 +#define RTL8367C_STORM_MCAST_OFFSET 0 +#define RTL8367C_STORM_MCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_UNKOWN_UCAST 0x0a42 +#define RTL8367C_STORM_UNKOWN_UCAST_OFFSET 0 +#define RTL8367C_STORM_UNKOWN_UCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_UNKOWN_MCAST 0x0a43 +#define RTL8367C_STORM_UNKOWN_MCAST_OFFSET 0 +#define RTL8367C_STORM_UNKOWN_MCAST_MASK 0x7FF + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL0 0x0a44 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL1 0x0a45 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL2 0x0a46 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL3 0x0a47 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL4 0x0a48 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_BCAST_METER_CTRL5 0x0a49 +#define RTL8367C_STORM_BCAST_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_BCAST_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL0 0x0a4c +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL1 0x0a4d +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL2 0x0a4e +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL3 0x0a4f +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL4 0x0a50 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_MCAST_METER_CTRL5 0x0a51 +#define RTL8367C_STORM_MCAST_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_MCAST_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL0 0x0a54 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL1 0x0a55 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL2 0x0a56 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL3 0x0a57 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL4 0x0a58 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNDA_METER_CTRL5 0x0a59 +#define RTL8367C_STORM_UNDA_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_UNDA_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL0 0x0a5c +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL1 0x0a5d +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL2 0x0a5e +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL3 0x0a5f +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_EXT_CFG 0x0a60 +#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_OFFSET 14 +#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK 0x4000 +#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET 13 +#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_MASK 0x2000 +#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET 12 +#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_MASK 0x1000 +#define RTL8367C_STORM_MCAST_EXT_EN_OFFSET 11 +#define RTL8367C_STORM_MCAST_EXT_EN_MASK 0x800 +#define RTL8367C_STORM_BCAST_EXT_EN_OFFSET 10 +#define RTL8367C_STORM_BCAST_EXT_EN_MASK 0x400 +#define RTL8367C_STORM_EXT_EN_PORTMASK_OFFSET 0 +#define RTL8367C_STORM_EXT_EN_PORTMASK_MASK 0x3FF + +#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG0 0x0a61 +#define RTL8367C_MC_STORM_EXT_METERIDX_OFFSET 8 +#define RTL8367C_MC_STORM_EXT_METERIDX_MASK 0x3F00 +#define RTL8367C_BC_STORM_EXT_METERIDX_OFFSET 0 +#define RTL8367C_BC_STORM_EXT_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG1 0x0a62 +#define RTL8367C_UNMC_STORM_EXT_METERIDX_OFFSET 8 +#define RTL8367C_UNMC_STORM_EXT_METERIDX_MASK 0x3F00 +#define RTL8367C_UNUC_STORM_EXT_METERIDX_OFFSET 0 +#define RTL8367C_UNUC_STORM_EXT_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL4 0x0a63 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_OFFSET 8 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_MASK 0x3F + +#define RTL8367C_REG_STORM_UNMC_METER_CTRL5 0x0a64 +#define RTL8367C_STORM_UNMC_METER_CTRL5_OFFSET 0 +#define RTL8367C_STORM_UNMC_METER_CTRL5_MASK 0x3F + +#define RTL8367C_REG_OAM_PARSER_CTRL0 0x0a70 +#define RTL8367C_PORT7_PARACT_OFFSET 14 +#define RTL8367C_PORT7_PARACT_MASK 0xC000 +#define RTL8367C_PORT6_PARACT_OFFSET 12 +#define RTL8367C_PORT6_PARACT_MASK 0x3000 +#define RTL8367C_PORT5_PARACT_OFFSET 10 +#define RTL8367C_PORT5_PARACT_MASK 0xC00 +#define RTL8367C_PORT4_PARACT_OFFSET 8 +#define RTL8367C_PORT4_PARACT_MASK 0x300 +#define RTL8367C_PORT3_PARACT_OFFSET 6 +#define RTL8367C_PORT3_PARACT_MASK 0xC0 +#define RTL8367C_PORT2_PARACT_OFFSET 4 +#define RTL8367C_PORT2_PARACT_MASK 0x30 +#define RTL8367C_PORT1_PARACT_OFFSET 2 +#define RTL8367C_PORT1_PARACT_MASK 0xC +#define RTL8367C_PORT0_PARACT_OFFSET 0 +#define RTL8367C_PORT0_PARACT_MASK 0x3 + +#define RTL8367C_REG_OAM_PARSER_CTRL1 0x0a71 +#define RTL8367C_PORT10_PARACT_OFFSET 4 +#define RTL8367C_PORT10_PARACT_MASK 0x30 +#define RTL8367C_PORT9_PARACT_OFFSET 2 +#define RTL8367C_PORT9_PARACT_MASK 0xC +#define RTL8367C_PORT8_PARACT_OFFSET 0 +#define RTL8367C_PORT8_PARACT_MASK 0x3 + +#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 0x0a72 +#define RTL8367C_PORT7_MULACT_OFFSET 14 +#define RTL8367C_PORT7_MULACT_MASK 0xC000 +#define RTL8367C_PORT6_MULACT_OFFSET 12 +#define RTL8367C_PORT6_MULACT_MASK 0x3000 +#define RTL8367C_PORT5_MULACT_OFFSET 10 +#define RTL8367C_PORT5_MULACT_MASK 0xC00 +#define RTL8367C_PORT4_MULACT_OFFSET 8 +#define RTL8367C_PORT4_MULACT_MASK 0x300 +#define RTL8367C_PORT3_MULACT_OFFSET 6 +#define RTL8367C_PORT3_MULACT_MASK 0xC0 +#define RTL8367C_PORT2_MULACT_OFFSET 4 +#define RTL8367C_PORT2_MULACT_MASK 0x30 +#define RTL8367C_PORT1_MULACT_OFFSET 2 +#define RTL8367C_PORT1_MULACT_MASK 0xC +#define RTL8367C_PORT0_MULACT_OFFSET 0 +#define RTL8367C_PORT0_MULACT_MASK 0x3 + +#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL1 0x0a73 +#define RTL8367C_PORT10_MULACT_OFFSET 4 +#define RTL8367C_PORT10_MULACT_MASK 0x30 +#define RTL8367C_PORT9_MULACT_OFFSET 2 +#define RTL8367C_PORT9_MULACT_MASK 0xC +#define RTL8367C_PORT8_MULACT_OFFSET 0 +#define RTL8367C_PORT8_MULACT_MASK 0x3 + +#define RTL8367C_REG_OAM_CTRL 0x0a74 +#define RTL8367C_OAM_CTRL_OFFSET 0 +#define RTL8367C_OAM_CTRL_MASK 0x1 + +#define RTL8367C_REG_DOT1X_PORT_ENABLE 0x0a80 +#define RTL8367C_DOT1X_PORT_ENABLE_OFFSET 0 +#define RTL8367C_DOT1X_PORT_ENABLE_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_MAC_ENABLE 0x0a81 +#define RTL8367C_DOT1X_MAC_ENABLE_OFFSET 0 +#define RTL8367C_DOT1X_MAC_ENABLE_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_PORT_AUTH 0x0a82 +#define RTL8367C_DOT1X_PORT_AUTH_OFFSET 0 +#define RTL8367C_DOT1X_PORT_AUTH_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_PORT_OPDIR 0x0a83 +#define RTL8367C_DOT1X_PORT_OPDIR_OFFSET 0 +#define RTL8367C_DOT1X_PORT_OPDIR_MASK 0x7FF + +#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 0x0a84 +#define RTL8367C_DOT1X_PORT7_UNAUTHBH_OFFSET 14 +#define RTL8367C_DOT1X_PORT7_UNAUTHBH_MASK 0xC000 +#define RTL8367C_DOT1X_PORT6_UNAUTHBH_OFFSET 12 +#define RTL8367C_DOT1X_PORT6_UNAUTHBH_MASK 0x3000 +#define RTL8367C_DOT1X_PORT5_UNAUTHBH_OFFSET 10 +#define RTL8367C_DOT1X_PORT5_UNAUTHBH_MASK 0xC00 +#define RTL8367C_DOT1X_PORT4_UNAUTHBH_OFFSET 8 +#define RTL8367C_DOT1X_PORT4_UNAUTHBH_MASK 0x300 +#define RTL8367C_DOT1X_PORT3_UNAUTHBH_OFFSET 6 +#define RTL8367C_DOT1X_PORT3_UNAUTHBH_MASK 0xC0 +#define RTL8367C_DOT1X_PORT2_UNAUTHBH_OFFSET 4 +#define RTL8367C_DOT1X_PORT2_UNAUTHBH_MASK 0x30 +#define RTL8367C_DOT1X_PORT1_UNAUTHBH_OFFSET 2 +#define RTL8367C_DOT1X_PORT1_UNAUTHBH_MASK 0xC +#define RTL8367C_DOT1X_PORT0_UNAUTHBH_OFFSET 0 +#define RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK 0x3 + +#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W1 0x0a85 +#define RTL8367C_DOT1X_PORT10_UNAUTHBH_OFFSET 4 +#define RTL8367C_DOT1X_PORT10_UNAUTHBH_MASK 0x30 +#define RTL8367C_DOT1X_PORT9_UNAUTHBH_OFFSET 2 +#define RTL8367C_DOT1X_PORT9_UNAUTHBH_MASK 0xC +#define RTL8367C_DOT1X_PORT8_UNAUTHBH_OFFSET 0 +#define RTL8367C_DOT1X_PORT8_UNAUTHBH_MASK 0x3 + +#define RTL8367C_REG_DOT1X_CFG 0x0a86 +#define RTL8367C_DOT1X_GVOPDIR_OFFSET 6 +#define RTL8367C_DOT1X_GVOPDIR_MASK 0x40 +#define RTL8367C_DOT1X_MAC_OPDIR_OFFSET 5 +#define RTL8367C_DOT1X_MAC_OPDIR_MASK 0x20 +#define RTL8367C_DOT1X_GVIDX_OFFSET 0 +#define RTL8367C_DOT1X_GVIDX_MASK 0x1F + +#define RTL8367C_REG_L2_LRN_CNT_CTRL0 0x0a87 +#define RTL8367C_L2_LRN_CNT_CTRL0_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL0_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL1 0x0a88 +#define RTL8367C_L2_LRN_CNT_CTRL1_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL1_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL2 0x0a89 +#define RTL8367C_L2_LRN_CNT_CTRL2_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL3 0x0a8a +#define RTL8367C_L2_LRN_CNT_CTRL3_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL3_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL4 0x0a8b +#define RTL8367C_L2_LRN_CNT_CTRL4_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL4_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL5 0x0a8c +#define RTL8367C_L2_LRN_CNT_CTRL5_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL5_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL6 0x0a8d +#define RTL8367C_L2_LRN_CNT_CTRL6_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL6_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL7 0x0a8e +#define RTL8367C_L2_LRN_CNT_CTRL7_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL7_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL8 0x0a8f +#define RTL8367C_L2_LRN_CNT_CTRL8_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL8_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL9 0x0a90 +#define RTL8367C_L2_LRN_CNT_CTRL9_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL9_MASK 0x1FFF + +#define RTL8367C_REG_L2_LRN_CNT_CTRL10 0x0a92 +#define RTL8367C_L2_LRN_CNT_CTRL10_OFFSET 0 +#define RTL8367C_L2_LRN_CNT_CTRL10_MASK 0x1FFF + +#define RTL8367C_REG_LUT_LRN_UNDER_STATUS 0x0a91 +#define RTL8367C_LUT_LRN_UNDER_STATUS_OFFSET 0 +#define RTL8367C_LUT_LRN_UNDER_STATUS_MASK 0x7FF + +#define RTL8367C_REG_L2_SA_MOVING_FORBID 0x0aa0 +#define RTL8367C_L2_SA_MOVING_FORBID_OFFSET 0 +#define RTL8367C_L2_SA_MOVING_FORBID_MASK 0x7FF + +#define RTL8367C_REG_DRPORT_LEARN_CTRL 0x0aa1 +#define RTL8367C_FORBID1_OFFSET 1 +#define RTL8367C_FORBID1_MASK 0x2 +#define RTL8367C_FORBID0_OFFSET 0 +#define RTL8367C_FORBID0_MASK 0x1 + +#define RTL8367C_REG_L2_DUMMY02 0x0aa2 + +#define RTL8367C_REG_L2_DUMMY03 0x0aa3 + +#define RTL8367C_REG_L2_DUMMY04 0x0aa4 + +#define RTL8367C_REG_L2_DUMMY05 0x0aa5 + +#define RTL8367C_REG_L2_DUMMY06 0x0aa6 + +#define RTL8367C_REG_L2_DUMMY07 0x0aa7 + +#define RTL8367C_REG_IPMC_GROUP_PMSK_00 0x0AC0 +#define RTL8367C_IPMC_GROUP_PMSK_00_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_00_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_01 0x0AC1 +#define RTL8367C_IPMC_GROUP_PMSK_01_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_01_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_02 0x0AC2 +#define RTL8367C_IPMC_GROUP_PMSK_02_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_02_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_03 0x0AC3 +#define RTL8367C_IPMC_GROUP_PMSK_03_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_03_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_04 0x0AC4 +#define RTL8367C_IPMC_GROUP_PMSK_04_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_04_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_05 0x0AC5 +#define RTL8367C_IPMC_GROUP_PMSK_05_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_05_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_06 0x0AC6 +#define RTL8367C_IPMC_GROUP_PMSK_06_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_06_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_07 0x0AC7 +#define RTL8367C_IPMC_GROUP_PMSK_07_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_07_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_08 0x0AC8 +#define RTL8367C_IPMC_GROUP_PMSK_08_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_08_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_09 0x0AC9 +#define RTL8367C_IPMC_GROUP_PMSK_09_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_09_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_10 0x0ACA +#define RTL8367C_IPMC_GROUP_PMSK_10_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_10_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_11 0x0ACB +#define RTL8367C_IPMC_GROUP_PMSK_11_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_11_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_12 0x0ACC +#define RTL8367C_IPMC_GROUP_PMSK_12_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_12_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_13 0x0ACD +#define RTL8367C_IPMC_GROUP_PMSK_13_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_13_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_14 0x0ACE +#define RTL8367C_IPMC_GROUP_PMSK_14_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_14_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_15 0x0ACF +#define RTL8367C_IPMC_GROUP_PMSK_15_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_15_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_16 0x0AD0 +#define RTL8367C_IPMC_GROUP_PMSK_16_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_16_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_17 0x0AD1 +#define RTL8367C_IPMC_GROUP_PMSK_17_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_17_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_18 0x0AD2 +#define RTL8367C_IPMC_GROUP_PMSK_18_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_18_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_19 0x0AD3 +#define RTL8367C_IPMC_GROUP_PMSK_19_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_19_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_20 0x0AD4 +#define RTL8367C_IPMC_GROUP_PMSK_20_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_20_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_21 0x0AD5 +#define RTL8367C_IPMC_GROUP_PMSK_21_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_21_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_22 0x0AD6 +#define RTL8367C_IPMC_GROUP_PMSK_22_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_22_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_23 0x0AD7 +#define RTL8367C_IPMC_GROUP_PMSK_23_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_23_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_24 0x0AD8 +#define RTL8367C_IPMC_GROUP_PMSK_24_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_24_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_25 0x0AD9 +#define RTL8367C_IPMC_GROUP_PMSK_25_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_25_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_26 0x0ADA +#define RTL8367C_IPMC_GROUP_PMSK_26_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_26_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_27 0x0ADB +#define RTL8367C_IPMC_GROUP_PMSK_27_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_27_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_28 0x0ADC +#define RTL8367C_IPMC_GROUP_PMSK_28_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_28_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_29 0x0ADD +#define RTL8367C_IPMC_GROUP_PMSK_29_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_29_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_30 0x0ADE +#define RTL8367C_IPMC_GROUP_PMSK_30_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_30_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_31 0x0ADF +#define RTL8367C_IPMC_GROUP_PMSK_31_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_31_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_32 0x0AE0 +#define RTL8367C_IPMC_GROUP_PMSK_32_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_32_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_33 0x0AE1 +#define RTL8367C_IPMC_GROUP_PMSK_33_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_33_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_34 0x0AE2 +#define RTL8367C_IPMC_GROUP_PMSK_34_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_34_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_35 0x0AE3 +#define RTL8367C_IPMC_GROUP_PMSK_35_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_35_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_36 0x0AE4 +#define RTL8367C_IPMC_GROUP_PMSK_36_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_36_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_37 0x0AE5 +#define RTL8367C_IPMC_GROUP_PMSK_37_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_37_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_38 0x0AE6 +#define RTL8367C_IPMC_GROUP_PMSK_38_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_38_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_39 0x0AE7 +#define RTL8367C_IPMC_GROUP_PMSK_39_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_39_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_40 0x0AE8 +#define RTL8367C_IPMC_GROUP_PMSK_40_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_40_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_41 0x0AE9 +#define RTL8367C_IPMC_GROUP_PMSK_41_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_41_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_42 0x0AEA +#define RTL8367C_IPMC_GROUP_PMSK_42_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_42_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_43 0x0AEB +#define RTL8367C_IPMC_GROUP_PMSK_43_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_43_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_44 0x0AEC +#define RTL8367C_IPMC_GROUP_PMSK_44_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_44_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_45 0x0AED +#define RTL8367C_IPMC_GROUP_PMSK_45_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_45_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_46 0x0AEE +#define RTL8367C_IPMC_GROUP_PMSK_46_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_46_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_47 0x0AEF +#define RTL8367C_IPMC_GROUP_PMSK_47_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_47_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_48 0x0AF0 +#define RTL8367C_IPMC_GROUP_PMSK_48_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_48_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_49 0x0AF1 +#define RTL8367C_IPMC_GROUP_PMSK_49_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_49_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_50 0x0AF2 +#define RTL8367C_IPMC_GROUP_PMSK_50_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_50_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_51 0x0AF3 +#define RTL8367C_IPMC_GROUP_PMSK_51_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_51_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_52 0x0AF4 +#define RTL8367C_IPMC_GROUP_PMSK_52_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_52_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_53 0x0AF5 +#define RTL8367C_IPMC_GROUP_PMSK_53_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_53_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_54 0x0AF6 +#define RTL8367C_IPMC_GROUP_PMSK_54_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_54_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_55 0x0AF7 +#define RTL8367C_IPMC_GROUP_PMSK_55_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_55_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_56 0x0AF8 +#define RTL8367C_IPMC_GROUP_PMSK_56_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_56_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_57 0x0AF9 +#define RTL8367C_IPMC_GROUP_PMSK_57_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_57_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_58 0x0AFA +#define RTL8367C_IPMC_GROUP_PMSK_58_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_58_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_59 0x0AFB +#define RTL8367C_IPMC_GROUP_PMSK_59_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_59_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_60 0x0AFC +#define RTL8367C_IPMC_GROUP_PMSK_60_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_60_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_61 0x0AFD +#define RTL8367C_IPMC_GROUP_PMSK_61_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_61_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_62 0x0AFE +#define RTL8367C_IPMC_GROUP_PMSK_62_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_62_MASK 0x7FF + +#define RTL8367C_REG_IPMC_GROUP_PMSK_63 0x0AFF +#define RTL8367C_IPMC_GROUP_PMSK_63_OFFSET 0 +#define RTL8367C_IPMC_GROUP_PMSK_63_MASK 0x7FF + +/* (16'h0b00)mltvlan_reg */ + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 0x0b00 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL1 0x0b01 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL2 0x0b02 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL3 0x0b03 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL4 0x0b04 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL0 0x0b05 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL1 0x0b06 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL2 0x0b07 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL3 0x0b08 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL4 0x0b09 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL0 0x0b0a +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL1 0x0b0b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL2 0x0b0c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL3 0x0b0d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL4 0x0b0e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL0 0x0b0f +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL1 0x0b10 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL2 0x0b11 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL3 0x0b12 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL4 0x0b13 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL0 0x0b14 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL1 0x0b15 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL2 0x0b16 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL3 0x0b17 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL4 0x0b18 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL0 0x0b19 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL1 0x0b1a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL2 0x0b1b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL3 0x0b1c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL4 0x0b1d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL0 0x0b1e +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL1 0x0b1f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL2 0x0b20 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL3 0x0b21 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL4 0x0b22 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL0 0x0b23 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL1 0x0b24 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL2 0x0b25 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL3 0x0b26 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL4 0x0b27 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL0 0x0b28 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL1 0x0b29 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL2 0x0b2a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL3 0x0b2b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL4 0x0b2c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL0 0x0b2d +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL1 0x0b2e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL2 0x0b2f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL3 0x0b30 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL4 0x0b31 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL0 0x0b32 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL1 0x0b33 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL2 0x0b34 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL3 0x0b35 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL4 0x0b36 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL0 0x0b37 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL1 0x0b38 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL2 0x0b39 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL3 0x0b3a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL4 0x0b3b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL0 0x0b3c +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL1 0x0b3d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL2 0x0b3e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL3 0x0b3f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL4 0x0b40 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL0 0x0b41 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL1 0x0b42 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL2 0x0b43 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL3 0x0b44 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL4 0x0b45 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL0 0x0b46 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL1 0x0b47 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL2 0x0b48 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL3 0x0b49 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL4 0x0b4a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL0 0x0b4b +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL1 0x0b4c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL2 0x0b4d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL3 0x0b4e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL4 0x0b4f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL0 0x0b50 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL1 0x0b51 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL2 0x0b52 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL3 0x0b53 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL4 0x0b54 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL0 0x0b55 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL1 0x0b56 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL2 0x0b57 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL3 0x0b58 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL4 0x0b59 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL0 0x0b5a +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL1 0x0b5b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL2 0x0b5c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL3 0x0b5d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL4 0x0b5e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL0 0x0b5f +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL1 0x0b60 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL2 0x0b61 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL3 0x0b62 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL4 0x0b63 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL0 0x0b64 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL1 0x0b65 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL2 0x0b66 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL3 0x0b67 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL4 0x0b68 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL0 0x0b69 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL1 0x0b6a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL2 0x0b6b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL3 0x0b6c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL4 0x0b6d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL0 0x0b6e +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL1 0x0b6f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL2 0x0b70 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL3 0x0b71 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL4 0x0b72 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL0 0x0b73 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL1 0x0b74 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL2 0x0b75 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL3 0x0b76 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL4 0x0b77 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL0 0x0b78 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL1 0x0b79 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL2 0x0b7a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL3 0x0b7b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL4 0x0b7c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL0 0x0b7d +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL1 0x0b7e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL2 0x0b7f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL3 0x0b80 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL4 0x0b81 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL0 0x0b82 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL1 0x0b83 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL2 0x0b84 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL3 0x0b85 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL4 0x0b86 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL0 0x0b87 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL1 0x0b88 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL2 0x0b89 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL3 0x0b8a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL4 0x0b8b + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL0 0x0b8c +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL1 0x0b8d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL2 0x0b8e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL3 0x0b8f + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL4 0x0b90 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL0 0x0b91 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL1 0x0b92 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL2 0x0b93 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL3 0x0b94 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL4 0x0b95 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL0 0x0b96 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL1 0x0b97 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL2 0x0b98 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL3 0x0b99 + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL4 0x0b9a + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL0 0x0b9b +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_OFFSET 7 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_MASK 0x80 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_OFFSET 6 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_MASK 0x40 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_OFFSET 0 +#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL1 0x0b9c + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL2 0x0b9d + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL3 0x0b9e + +#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL4 0x0b9f + +#define RTL8367C_REG_MLTVLAN_DUMMY_0 0x0ba0 + +#define RTL8367C_REG_MLTVLAN_DUMMY_1 0x0ba1 + +#define RTL8367C_REG_MLTVLAN_DUMMY_2 0x0ba2 + +#define RTL8367C_REG_MLTVLAN_DUMMY_3 0x0ba3 + +#define RTL8367C_REG_MLTVLAN_DUMMY_4 0x0ba4 + +#define RTL8367C_REG_MLTVLAN_DUMMY_5 0x0ba5 + +#define RTL8367C_REG_MLTVLAN_DUMMY_6 0x0ba6 + +#define RTL8367C_REG_MLTVLAN_DUMMY_7 0x0ba7 + +/* (16'h0c00)svlan_reg */ + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 0x0c01 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL2 0x0c02 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL3 0x0c03 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL1 0x0c04 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL2 0x0c05 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL3 0x0c06 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL1 0x0c07 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL2 0x0c08 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL3 0x0c09 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL1 0x0c0a +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL2 0x0c0b +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL3 0x0c0c +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL1 0x0c0d +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL2 0x0c0e +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL3 0x0c0f +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL1 0x0c10 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL2 0x0c11 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL3 0x0c12 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL1 0x0c13 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL2 0x0c14 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL3 0x0c15 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL1 0x0c16 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL2 0x0c17 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL3 0x0c18 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL1 0x0c19 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL2 0x0c1a +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL3 0x0c1b +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL1 0x0c1c +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL2 0x0c1d +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL3 0x0c1e +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL1 0x0c1f +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL2 0x0c20 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL3 0x0c21 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL1 0x0c22 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL2 0x0c23 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL3 0x0c24 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL1 0x0c25 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL2 0x0c26 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL3 0x0c27 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL1 0x0c28 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL2 0x0c29 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL3 0x0c2a +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL1 0x0c2b +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL2 0x0c2c +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL3 0x0c2d +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL1 0x0c2e +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL2 0x0c2f +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL3 0x0c30 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL1 0x0c31 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL2 0x0c32 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL3 0x0c33 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL1 0x0c34 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL2 0x0c35 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL3 0x0c36 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL1 0x0c37 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL2 0x0c38 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL3 0x0c39 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL1 0x0c3a +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL2 0x0c3b +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL3 0x0c3c +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL1 0x0c3d +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL2 0x0c3e +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL3 0x0c3f +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL1 0x0c40 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL2 0x0c41 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL3 0x0c42 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL1 0x0c43 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL2 0x0c44 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL3 0x0c45 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL1 0x0c46 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL2 0x0c47 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL3 0x0c48 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL1 0x0c49 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL2 0x0c4a +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL3 0x0c4b +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL1 0x0c4c +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL2 0x0c4d +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL3 0x0c4e +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL1 0x0c4f +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL2 0x0c50 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL3 0x0c51 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL1 0x0c52 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL2 0x0c53 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL3 0x0c54 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL1 0x0c55 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL2 0x0c56 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL3 0x0c57 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL1 0x0c58 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL2 0x0c59 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL3 0x0c5a +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL1 0x0c5b +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL2 0x0c5c +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL3 0x0c5d +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL1 0x0c5e +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL2 0x0c5f +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL3 0x0c60 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL1 0x0c61 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL2 0x0c62 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL3 0x0c63 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL1 0x0c64 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL2 0x0c65 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL3 0x0c66 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL1 0x0c67 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL2 0x0c68 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL3 0x0c69 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL1 0x0c6a +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL2 0x0c6b +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL3 0x0c6c +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL1 0x0c6d +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL2 0x0c6e +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL3 0x0c6f +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL1 0x0c70 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL2 0x0c71 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL3 0x0c72 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL1 0x0c73 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL2 0x0c74 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL3 0x0c75 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL1 0x0c76 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL2 0x0c77 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL3 0x0c78 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL1 0x0c79 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL2 0x0c7a +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL3 0x0c7b +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL1 0x0c7c +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL2 0x0c7d +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL3 0x0c7e +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL1 0x0c7f +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL2 0x0c80 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL3 0x0c81 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL1 0x0c82 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL2 0x0c83 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL3 0x0c84 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL1 0x0c85 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL2 0x0c86 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL3 0x0c87 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL1 0x0c88 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL2 0x0c89 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL3 0x0c8a +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL1 0x0c8b +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL2 0x0c8c +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL3 0x0c8d +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL1 0x0c8e +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL2 0x0c8f +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL3 0x0c90 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL1 0x0c91 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL2 0x0c92 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL3 0x0c93 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL1 0x0c94 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL2 0x0c95 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL3 0x0c96 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL1 0x0c97 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL2 0x0c98 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL3 0x0c99 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL1 0x0c9a +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL2 0x0c9b +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL3 0x0c9c +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL1 0x0c9d +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL2 0x0c9e +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL3 0x0c9f +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL1 0x0ca0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL2 0x0ca1 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL3 0x0ca2 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL1 0x0ca3 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL2 0x0ca4 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL3 0x0ca5 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL1 0x0ca6 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL2 0x0ca7 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL3 0x0ca8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL1 0x0ca9 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL2 0x0caa +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL3 0x0cab +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL1 0x0cac +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL2 0x0cad +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL3 0x0cae +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL1 0x0caf +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL2 0x0cb0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL3 0x0cb1 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL1 0x0cb2 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL2 0x0cb3 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL3 0x0cb4 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL1 0x0cb5 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL2 0x0cb6 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL3 0x0cb7 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL1 0x0cb8 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL2 0x0cb9 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL3 0x0cba +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL1 0x0cbb +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL2 0x0cbc +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL3 0x0cbd +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL1 0x0cbe +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_MASK 0xFF00 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_MASK 0xFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL2 0x0cbf +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_OFFSET 7 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_MASK 0x80 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_OFFSET 4 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_MASK 0x70 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_MASK 0xF + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL3 0x0cc0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_OFFSET 13 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_MASK 0xE000 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_OFFSET 12 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_MASK 0x1000 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4 0x0cc1 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL4 0x0cc2 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL4 0x0cc3 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL4 0x0cc4 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL4 0x0cc5 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL4 0x0cc6 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL4 0x0cc7 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL4 0x0cc8 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL4 0x0cc9 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL4 0x0cca +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL4 0x0ccb +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL4 0x0ccc +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL4 0x0ccd +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL4 0x0cce +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL4 0x0ccf +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL4 0x0cd0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL4 0x0cd1 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL4 0x0cd2 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL4 0x0cd3 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL4 0x0cd4 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL4 0x0cd5 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL4 0x0cd6 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL4 0x0cd7 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL4 0x0cd8 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL4 0x0cd9 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL4 0x0cda +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL4 0x0cdb +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL4 0x0cdc +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL4 0x0cdd +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL4 0x0cde +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL4 0x0cdf +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL4 0x0ce0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL4 0x0ce1 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL4 0x0ce2 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL4 0x0ce3 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL4 0x0ce4 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL4 0x0ce5 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL4 0x0ce6 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL4 0x0ce7 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL4 0x0ce8 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL4 0x0ce9 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL4 0x0cea +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL4 0x0ceb +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL4 0x0cec +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL4 0x0ced +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL4 0x0cee +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL4 0x0cef +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL4 0x0cf0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL4 0x0cf1 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL4 0x0cf2 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL4 0x0cf3 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL4 0x0cf4 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL4 0x0cf5 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL4 0x0cf6 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL4 0x0cf7 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL4 0x0cf8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL4 0x0cf9 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL4 0x0cfa +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL4 0x0cfb +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL4 0x0cfc +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL4 0x0cfd +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL4 0x0cfe +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL4 0x0cff +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL0 0x0d00 +#define RTL8367C_SVLAN_C2SCFG0_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG0_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL1 0x0d01 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL2 0x0d02 +#define RTL8367C_SVLAN_C2SCFG0_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG0_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL0 0x0d03 +#define RTL8367C_SVLAN_C2SCFG1_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG1_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL1 0x0d04 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL2 0x0d05 +#define RTL8367C_SVLAN_C2SCFG1_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG1_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL0 0x0d06 +#define RTL8367C_SVLAN_C2SCFG2_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG2_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL1 0x0d07 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL2 0x0d08 +#define RTL8367C_SVLAN_C2SCFG2_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG2_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL0 0x0d09 +#define RTL8367C_SVLAN_C2SCFG3_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG3_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL1 0x0d0a +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL2 0x0d0b +#define RTL8367C_SVLAN_C2SCFG3_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG3_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL0 0x0d0c +#define RTL8367C_SVLAN_C2SCFG4_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG4_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL1 0x0d0d +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL2 0x0d0e +#define RTL8367C_SVLAN_C2SCFG4_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG4_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL0 0x0d0f +#define RTL8367C_SVLAN_C2SCFG5_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG5_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL1 0x0d10 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL2 0x0d11 +#define RTL8367C_SVLAN_C2SCFG5_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG5_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL0 0x0d12 +#define RTL8367C_SVLAN_C2SCFG6_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG6_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL1 0x0d13 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL2 0x0d14 +#define RTL8367C_SVLAN_C2SCFG6_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG6_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL0 0x0d15 +#define RTL8367C_SVLAN_C2SCFG7_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG7_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL1 0x0d16 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL2 0x0d17 +#define RTL8367C_SVLAN_C2SCFG7_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG7_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL0 0x0d18 +#define RTL8367C_SVLAN_C2SCFG8_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG8_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL1 0x0d19 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL2 0x0d1a +#define RTL8367C_SVLAN_C2SCFG8_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG8_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL0 0x0d1b +#define RTL8367C_SVLAN_C2SCFG9_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG9_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL1 0x0d1c +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL2 0x0d1d +#define RTL8367C_SVLAN_C2SCFG9_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG9_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL0 0x0d1e +#define RTL8367C_SVLAN_C2SCFG10_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG10_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL1 0x0d1f +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL2 0x0d20 +#define RTL8367C_SVLAN_C2SCFG10_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG10_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL0 0x0d21 +#define RTL8367C_SVLAN_C2SCFG11_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG11_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL1 0x0d22 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL2 0x0d23 +#define RTL8367C_SVLAN_C2SCFG11_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG11_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL0 0x0d24 +#define RTL8367C_SVLAN_C2SCFG12_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG12_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL1 0x0d25 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL2 0x0d26 +#define RTL8367C_SVLAN_C2SCFG12_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG12_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL0 0x0d27 +#define RTL8367C_SVLAN_C2SCFG13_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG13_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL1 0x0d28 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL2 0x0d29 +#define RTL8367C_SVLAN_C2SCFG13_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG13_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL0 0x0d2a +#define RTL8367C_SVLAN_C2SCFG14_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG14_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL1 0x0d2b +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL2 0x0d2c +#define RTL8367C_SVLAN_C2SCFG14_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG14_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL0 0x0d2d +#define RTL8367C_SVLAN_C2SCFG15_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG15_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL1 0x0d2e +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL2 0x0d2f +#define RTL8367C_SVLAN_C2SCFG15_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG15_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL0 0x0d30 +#define RTL8367C_SVLAN_C2SCFG16_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG16_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL1 0x0d31 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL2 0x0d32 +#define RTL8367C_SVLAN_C2SCFG16_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG16_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL0 0x0d33 +#define RTL8367C_SVLAN_C2SCFG17_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG17_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL1 0x0d34 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL2 0x0d35 +#define RTL8367C_SVLAN_C2SCFG17_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG17_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL0 0x0d36 +#define RTL8367C_SVLAN_C2SCFG18_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG18_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL1 0x0d37 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL2 0x0d38 +#define RTL8367C_SVLAN_C2SCFG18_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG18_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL0 0x0d39 +#define RTL8367C_SVLAN_C2SCFG19_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG19_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL1 0x0d3a +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL2 0x0d3b +#define RTL8367C_SVLAN_C2SCFG19_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG19_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL0 0x0d3c +#define RTL8367C_SVLAN_C2SCFG20_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG20_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL1 0x0d3d +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL2 0x0d3e +#define RTL8367C_SVLAN_C2SCFG20_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG20_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL0 0x0d3f +#define RTL8367C_SVLAN_C2SCFG21_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG21_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL1 0x0d40 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL2 0x0d41 +#define RTL8367C_SVLAN_C2SCFG21_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG21_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL0 0x0d42 +#define RTL8367C_SVLAN_C2SCFG22_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG22_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL1 0x0d43 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL2 0x0d44 +#define RTL8367C_SVLAN_C2SCFG22_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG22_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL0 0x0d45 +#define RTL8367C_SVLAN_C2SCFG23_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG23_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL1 0x0d46 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL2 0x0d47 +#define RTL8367C_SVLAN_C2SCFG23_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG23_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL0 0x0d48 +#define RTL8367C_SVLAN_C2SCFG24_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG24_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL1 0x0d49 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL2 0x0d4a +#define RTL8367C_SVLAN_C2SCFG24_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG24_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL0 0x0d4b +#define RTL8367C_SVLAN_C2SCFG25_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG25_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL1 0x0d4c +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL2 0x0d4d +#define RTL8367C_SVLAN_C2SCFG25_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG25_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL0 0x0d4e +#define RTL8367C_SVLAN_C2SCFG26_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG26_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL1 0x0d4f +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL2 0x0d50 +#define RTL8367C_SVLAN_C2SCFG26_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG26_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL0 0x0d51 +#define RTL8367C_SVLAN_C2SCFG27_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG27_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL1 0x0d52 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL2 0x0d53 +#define RTL8367C_SVLAN_C2SCFG27_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG27_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL0 0x0d54 +#define RTL8367C_SVLAN_C2SCFG28_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG28_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL1 0x0d55 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL2 0x0d56 +#define RTL8367C_SVLAN_C2SCFG28_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG28_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL0 0x0d57 +#define RTL8367C_SVLAN_C2SCFG29_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG29_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL1 0x0d58 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL2 0x0d59 +#define RTL8367C_SVLAN_C2SCFG29_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG29_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL0 0x0d5a +#define RTL8367C_SVLAN_C2SCFG30_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG30_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL1 0x0d5b +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL2 0x0d5c +#define RTL8367C_SVLAN_C2SCFG30_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG30_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL0 0x0d5d +#define RTL8367C_SVLAN_C2SCFG31_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG31_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL1 0x0d5e +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL2 0x0d5f +#define RTL8367C_SVLAN_C2SCFG31_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG31_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL0 0x0d60 +#define RTL8367C_SVLAN_C2SCFG32_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG32_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL1 0x0d61 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL2 0x0d62 +#define RTL8367C_SVLAN_C2SCFG32_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG32_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL0 0x0d63 +#define RTL8367C_SVLAN_C2SCFG33_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG33_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL1 0x0d64 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL2 0x0d65 +#define RTL8367C_SVLAN_C2SCFG33_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG33_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL0 0x0d66 +#define RTL8367C_SVLAN_C2SCFG34_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG34_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL1 0x0d67 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL2 0x0d68 +#define RTL8367C_SVLAN_C2SCFG34_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG34_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL0 0x0d69 +#define RTL8367C_SVLAN_C2SCFG35_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG35_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL1 0x0d6a +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL2 0x0d6b +#define RTL8367C_SVLAN_C2SCFG35_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG35_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL0 0x0d6c +#define RTL8367C_SVLAN_C2SCFG36_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG36_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL1 0x0d6d +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL2 0x0d6e +#define RTL8367C_SVLAN_C2SCFG36_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG36_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL0 0x0d6f +#define RTL8367C_SVLAN_C2SCFG37_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG37_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL1 0x0d70 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL2 0x0d71 +#define RTL8367C_SVLAN_C2SCFG37_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG37_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL0 0x0d72 +#define RTL8367C_SVLAN_C2SCFG38_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG38_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL1 0x0d73 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL2 0x0d74 +#define RTL8367C_SVLAN_C2SCFG38_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG38_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL0 0x0d75 +#define RTL8367C_SVLAN_C2SCFG39_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG39_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL1 0x0d76 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL2 0x0d77 +#define RTL8367C_SVLAN_C2SCFG39_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG39_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL0 0x0d78 +#define RTL8367C_SVLAN_C2SCFG40_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG40_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL1 0x0d79 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL2 0x0d7a +#define RTL8367C_SVLAN_C2SCFG40_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG40_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL0 0x0d7b +#define RTL8367C_SVLAN_C2SCFG41_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG41_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL1 0x0d7c +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL2 0x0d7d +#define RTL8367C_SVLAN_C2SCFG41_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG41_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL0 0x0d7e +#define RTL8367C_SVLAN_C2SCFG42_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG42_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL1 0x0d7f +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL2 0x0d80 +#define RTL8367C_SVLAN_C2SCFG42_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG42_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL0 0x0d81 +#define RTL8367C_SVLAN_C2SCFG43_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG43_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL1 0x0d82 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL2 0x0d83 +#define RTL8367C_SVLAN_C2SCFG43_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG43_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL0 0x0d84 +#define RTL8367C_SVLAN_C2SCFG44_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG44_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL1 0x0d85 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL2 0x0d86 +#define RTL8367C_SVLAN_C2SCFG44_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG44_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL0 0x0d87 +#define RTL8367C_SVLAN_C2SCFG45_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG45_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL1 0x0d88 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL2 0x0d89 +#define RTL8367C_SVLAN_C2SCFG45_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG45_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL0 0x0d8a +#define RTL8367C_SVLAN_C2SCFG46_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG46_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL1 0x0d8b +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL2 0x0d8c +#define RTL8367C_SVLAN_C2SCFG46_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG46_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL0 0x0d8d +#define RTL8367C_SVLAN_C2SCFG47_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG47_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL1 0x0d8e +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL2 0x0d8f +#define RTL8367C_SVLAN_C2SCFG47_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG47_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL0 0x0d90 +#define RTL8367C_SVLAN_C2SCFG48_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG48_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL1 0x0d91 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL2 0x0d92 +#define RTL8367C_SVLAN_C2SCFG48_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG48_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL0 0x0d93 +#define RTL8367C_SVLAN_C2SCFG49_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG49_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL1 0x0d94 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL2 0x0d95 +#define RTL8367C_SVLAN_C2SCFG49_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG49_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL0 0x0d96 +#define RTL8367C_SVLAN_C2SCFG50_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG50_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL1 0x0d97 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL2 0x0d98 +#define RTL8367C_SVLAN_C2SCFG50_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG50_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL0 0x0d99 +#define RTL8367C_SVLAN_C2SCFG51_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG51_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL1 0x0d9a +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL2 0x0d9b +#define RTL8367C_SVLAN_C2SCFG51_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG51_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL0 0x0d9c +#define RTL8367C_SVLAN_C2SCFG52_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG52_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL1 0x0d9d +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL2 0x0d9e +#define RTL8367C_SVLAN_C2SCFG52_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG52_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL0 0x0d9f +#define RTL8367C_SVLAN_C2SCFG53_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL1 0x0da0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL2 0x0da1 +#define RTL8367C_SVLAN_C2SCFG53_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG53_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL0 0x0da2 +#define RTL8367C_SVLAN_C2SCFG54_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG54_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL1 0x0da3 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL2 0x0da4 +#define RTL8367C_SVLAN_C2SCFG54_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG54_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL0 0x0da5 +#define RTL8367C_SVLAN_C2SCFG55_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG55_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL1 0x0da6 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL2 0x0da7 +#define RTL8367C_SVLAN_C2SCFG55_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG55_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL0 0x0da8 +#define RTL8367C_SVLAN_C2SCFG56_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG56_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL1 0x0da9 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL2 0x0daa +#define RTL8367C_SVLAN_C2SCFG56_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG56_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL0 0x0dab +#define RTL8367C_SVLAN_C2SCFG57_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG57_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL1 0x0dac +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL2 0x0dad +#define RTL8367C_SVLAN_C2SCFG57_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG57_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL0 0x0dae +#define RTL8367C_SVLAN_C2SCFG58_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL1 0x0daf +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL2 0x0db0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG58_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL0 0x0db1 +#define RTL8367C_SVLAN_C2SCFG59_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG59_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL1 0x0db2 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL2 0x0db3 +#define RTL8367C_SVLAN_C2SCFG59_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG59_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL0 0x0db4 +#define RTL8367C_SVLAN_C2SCFG60_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG60_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL1 0x0db5 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL2 0x0db6 +#define RTL8367C_SVLAN_C2SCFG60_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG60_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL0 0x0db7 +#define RTL8367C_SVLAN_C2SCFG61_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG61_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL1 0x0db8 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL2 0x0db9 +#define RTL8367C_SVLAN_C2SCFG61_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG61_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL0 0x0dba +#define RTL8367C_SVLAN_C2SCFG62_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG62_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL1 0x0dbb +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL2 0x0dbc +#define RTL8367C_SVLAN_C2SCFG62_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG62_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL0 0x0dbd +#define RTL8367C_SVLAN_C2SCFG63_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG63_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL1 0x0dbe +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL2 0x0dbf +#define RTL8367C_SVLAN_C2SCFG63_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG63_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL0 0x0dc0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL1 0x0dc1 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL2 0x0dc2 +#define RTL8367C_SVLAN_C2SCFG64_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG64_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL0 0x0dc3 +#define RTL8367C_SVLAN_C2SCFG65_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG65_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL1 0x0dc4 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL2 0x0dc5 +#define RTL8367C_SVLAN_C2SCFG65_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG65_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL0 0x0dc6 +#define RTL8367C_SVLAN_C2SCFG66_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG66_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL1 0x0dc7 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL2 0x0dc8 +#define RTL8367C_SVLAN_C2SCFG66_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG66_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL0 0x0dc9 +#define RTL8367C_SVLAN_C2SCFG67_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG67_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL1 0x0dca +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL2 0x0dcb +#define RTL8367C_SVLAN_C2SCFG67_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG67_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL0 0x0dcc +#define RTL8367C_SVLAN_C2SCFG68_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG68_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL1 0x0dcd +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL2 0x0dce +#define RTL8367C_SVLAN_C2SCFG68_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG68_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL0 0x0dcf +#define RTL8367C_SVLAN_C2SCFG69_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL1 0x0dd0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL2 0x0dd1 +#define RTL8367C_SVLAN_C2SCFG69_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG69_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL0 0x0dd2 +#define RTL8367C_SVLAN_C2SCFG70_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG70_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL1 0x0dd3 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL2 0x0dd4 +#define RTL8367C_SVLAN_C2SCFG70_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG70_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL0 0x0dd5 +#define RTL8367C_SVLAN_C2SCFG71_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG71_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL1 0x0dd6 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL2 0x0dd7 +#define RTL8367C_SVLAN_C2SCFG71_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG71_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL0 0x0dd8 +#define RTL8367C_SVLAN_C2SCFG72_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG72_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL1 0x0dd9 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL2 0x0dda +#define RTL8367C_SVLAN_C2SCFG72_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG72_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL0 0x0ddb +#define RTL8367C_SVLAN_C2SCFG73_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG73_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL1 0x0ddc +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL2 0x0ddd +#define RTL8367C_SVLAN_C2SCFG73_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG73_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL0 0x0dde +#define RTL8367C_SVLAN_C2SCFG74_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL1 0x0ddf +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL2 0x0de0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG74_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL0 0x0de1 +#define RTL8367C_SVLAN_C2SCFG75_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG75_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL1 0x0de2 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL2 0x0de3 +#define RTL8367C_SVLAN_C2SCFG75_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG75_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL0 0x0de4 +#define RTL8367C_SVLAN_C2SCFG76_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG76_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL1 0x0de5 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL2 0x0de6 +#define RTL8367C_SVLAN_C2SCFG76_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG76_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL0 0x0de7 +#define RTL8367C_SVLAN_C2SCFG77_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG77_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL1 0x0de8 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL2 0x0de9 +#define RTL8367C_SVLAN_C2SCFG77_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG77_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL0 0x0dea +#define RTL8367C_SVLAN_C2SCFG78_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG78_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL1 0x0deb +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL2 0x0dec +#define RTL8367C_SVLAN_C2SCFG78_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG78_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL0 0x0ded +#define RTL8367C_SVLAN_C2SCFG79_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG79_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL1 0x0dee +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL2 0x0def +#define RTL8367C_SVLAN_C2SCFG79_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG79_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL0 0x0df0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL1 0x0df1 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL2 0x0df2 +#define RTL8367C_SVLAN_C2SCFG80_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG80_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL0 0x0df3 +#define RTL8367C_SVLAN_C2SCFG81_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG81_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL1 0x0df4 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL2 0x0df5 +#define RTL8367C_SVLAN_C2SCFG81_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG81_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL0 0x0df6 +#define RTL8367C_SVLAN_C2SCFG82_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG82_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL1 0x0df7 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL2 0x0df8 +#define RTL8367C_SVLAN_C2SCFG82_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG82_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL0 0x0df9 +#define RTL8367C_SVLAN_C2SCFG83_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG83_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL1 0x0dfa +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL2 0x0dfb +#define RTL8367C_SVLAN_C2SCFG83_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG83_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL0 0x0dfc +#define RTL8367C_SVLAN_C2SCFG84_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG84_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL1 0x0dfd +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL2 0x0dfe +#define RTL8367C_SVLAN_C2SCFG84_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG84_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL0 0x0dff +#define RTL8367C_SVLAN_C2SCFG85_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG85_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL1 0x0e00 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL2 0x0e01 +#define RTL8367C_SVLAN_C2SCFG85_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG85_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL0 0x0e02 +#define RTL8367C_SVLAN_C2SCFG86_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG86_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL1 0x0e03 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL2 0x0e04 +#define RTL8367C_SVLAN_C2SCFG86_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG86_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL0 0x0e05 +#define RTL8367C_SVLAN_C2SCFG87_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG87_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL1 0x0e06 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL2 0x0e07 +#define RTL8367C_SVLAN_C2SCFG87_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG87_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL0 0x0e08 +#define RTL8367C_SVLAN_C2SCFG88_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG88_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL1 0x0e09 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL2 0x0e0a +#define RTL8367C_SVLAN_C2SCFG88_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG88_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL0 0x0e0b +#define RTL8367C_SVLAN_C2SCFG89_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG89_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL1 0x0e0c +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL2 0x0e0d +#define RTL8367C_SVLAN_C2SCFG89_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG89_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL0 0x0e0e +#define RTL8367C_SVLAN_C2SCFG90_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG90_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL1 0x0e0f +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL2 0x0e10 +#define RTL8367C_SVLAN_C2SCFG90_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG90_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL0 0x0e11 +#define RTL8367C_SVLAN_C2SCFG91_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG91_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL1 0x0e12 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL2 0x0e13 +#define RTL8367C_SVLAN_C2SCFG91_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG91_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL0 0x0e14 +#define RTL8367C_SVLAN_C2SCFG92_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG92_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL1 0x0e15 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL2 0x0e16 +#define RTL8367C_SVLAN_C2SCFG92_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG92_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL0 0x0e17 +#define RTL8367C_SVLAN_C2SCFG93_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG93_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL1 0x0e18 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL2 0x0e19 +#define RTL8367C_SVLAN_C2SCFG93_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG93_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL0 0x0e1a +#define RTL8367C_SVLAN_C2SCFG94_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG94_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL1 0x0e1b +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL2 0x0e1c +#define RTL8367C_SVLAN_C2SCFG94_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG94_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL0 0x0e1d +#define RTL8367C_SVLAN_C2SCFG95_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG95_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL1 0x0e1e +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL2 0x0e1f +#define RTL8367C_SVLAN_C2SCFG95_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG95_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL0 0x0e20 +#define RTL8367C_SVLAN_C2SCFG96_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG96_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL1 0x0e21 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL2 0x0e22 +#define RTL8367C_SVLAN_C2SCFG96_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG96_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL0 0x0e23 +#define RTL8367C_SVLAN_C2SCFG97_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG97_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL1 0x0e24 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL2 0x0e25 +#define RTL8367C_SVLAN_C2SCFG97_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG97_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL0 0x0e26 +#define RTL8367C_SVLAN_C2SCFG98_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG98_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL1 0x0e27 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL2 0x0e28 +#define RTL8367C_SVLAN_C2SCFG98_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG98_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL0 0x0e29 +#define RTL8367C_SVLAN_C2SCFG99_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG99_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL1 0x0e2a +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL2 0x0e2b +#define RTL8367C_SVLAN_C2SCFG99_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG99_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL0 0x0e2c +#define RTL8367C_SVLAN_C2SCFG100_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG100_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL1 0x0e2d +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL2 0x0e2e +#define RTL8367C_SVLAN_C2SCFG100_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG100_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL0 0x0e2f +#define RTL8367C_SVLAN_C2SCFG101_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG101_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL1 0x0e30 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL2 0x0e31 +#define RTL8367C_SVLAN_C2SCFG101_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG101_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL0 0x0e32 +#define RTL8367C_SVLAN_C2SCFG102_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG102_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL1 0x0e33 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL2 0x0e34 +#define RTL8367C_SVLAN_C2SCFG102_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG102_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL0 0x0e35 +#define RTL8367C_SVLAN_C2SCFG103_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG103_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL1 0x0e36 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL2 0x0e37 +#define RTL8367C_SVLAN_C2SCFG103_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG103_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL0 0x0e38 +#define RTL8367C_SVLAN_C2SCFG104_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG104_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL1 0x0e39 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL2 0x0e3a +#define RTL8367C_SVLAN_C2SCFG104_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG104_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL0 0x0e3b +#define RTL8367C_SVLAN_C2SCFG105_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG105_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL1 0x0e3c +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL2 0x0e3d +#define RTL8367C_SVLAN_C2SCFG105_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG105_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL0 0x0e3e +#define RTL8367C_SVLAN_C2SCFG106_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG106_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL1 0x0e3f +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL2 0x0e40 +#define RTL8367C_SVLAN_C2SCFG106_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG106_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL0 0x0e41 +#define RTL8367C_SVLAN_C2SCFG107_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG107_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL1 0x0e42 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL2 0x0e43 +#define RTL8367C_SVLAN_C2SCFG107_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG107_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL0 0x0e44 +#define RTL8367C_SVLAN_C2SCFG108_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG108_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL1 0x0e45 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL2 0x0e46 +#define RTL8367C_SVLAN_C2SCFG108_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG108_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL0 0x0e47 +#define RTL8367C_SVLAN_C2SCFG109_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG109_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL1 0x0e48 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL2 0x0e49 +#define RTL8367C_SVLAN_C2SCFG109_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG109_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL0 0x0e4a +#define RTL8367C_SVLAN_C2SCFG110_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG110_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL1 0x0e4b +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL2 0x0e4c +#define RTL8367C_SVLAN_C2SCFG110_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG110_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL0 0x0e4d +#define RTL8367C_SVLAN_C2SCFG111_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG111_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL1 0x0e4e +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL2 0x0e4f +#define RTL8367C_SVLAN_C2SCFG111_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG111_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL0 0x0e50 +#define RTL8367C_SVLAN_C2SCFG112_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG112_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL1 0x0e51 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL2 0x0e52 +#define RTL8367C_SVLAN_C2SCFG112_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG112_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL0 0x0e53 +#define RTL8367C_SVLAN_C2SCFG113_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG113_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL1 0x0e54 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL2 0x0e55 +#define RTL8367C_SVLAN_C2SCFG113_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG113_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL0 0x0e56 +#define RTL8367C_SVLAN_C2SCFG114_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG114_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL1 0x0e57 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL2 0x0e58 +#define RTL8367C_SVLAN_C2SCFG114_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG114_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL0 0x0e59 +#define RTL8367C_SVLAN_C2SCFG115_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG115_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL1 0x0e5a +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL2 0x0e5b +#define RTL8367C_SVLAN_C2SCFG115_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG115_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL0 0x0e5c +#define RTL8367C_SVLAN_C2SCFG116_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG116_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL1 0x0e5d +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL2 0x0e5e +#define RTL8367C_SVLAN_C2SCFG116_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG116_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL0 0x0e5f +#define RTL8367C_SVLAN_C2SCFG117_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG117_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL1 0x0e60 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL2 0x0e61 +#define RTL8367C_SVLAN_C2SCFG117_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG117_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL0 0x0e62 +#define RTL8367C_SVLAN_C2SCFG118_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG118_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL1 0x0e63 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL2 0x0e64 +#define RTL8367C_SVLAN_C2SCFG118_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG118_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL0 0x0e65 +#define RTL8367C_SVLAN_C2SCFG119_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG119_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL1 0x0e66 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL2 0x0e67 +#define RTL8367C_SVLAN_C2SCFG119_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG119_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL0 0x0e68 +#define RTL8367C_SVLAN_C2SCFG120_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG120_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL1 0x0e69 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL2 0x0e6a +#define RTL8367C_SVLAN_C2SCFG120_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG120_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL0 0x0e6b +#define RTL8367C_SVLAN_C2SCFG121_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG121_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL1 0x0e6c +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL2 0x0e6d +#define RTL8367C_SVLAN_C2SCFG121_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG121_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL0 0x0e6e +#define RTL8367C_SVLAN_C2SCFG122_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG122_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL1 0x0e6f +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL2 0x0e70 +#define RTL8367C_SVLAN_C2SCFG122_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG122_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL0 0x0e71 +#define RTL8367C_SVLAN_C2SCFG123_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG123_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL1 0x0e72 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL2 0x0e73 +#define RTL8367C_SVLAN_C2SCFG123_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG123_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL0 0x0e74 +#define RTL8367C_SVLAN_C2SCFG124_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG124_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL1 0x0e75 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL2 0x0e76 +#define RTL8367C_SVLAN_C2SCFG124_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG124_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL0 0x0e77 +#define RTL8367C_SVLAN_C2SCFG125_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG125_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL1 0x0e78 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL2 0x0e79 +#define RTL8367C_SVLAN_C2SCFG125_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG125_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL0 0x0e7a +#define RTL8367C_SVLAN_C2SCFG126_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG126_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL1 0x0e7b +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL2 0x0e7c +#define RTL8367C_SVLAN_C2SCFG126_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG126_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL0 0x0e7d +#define RTL8367C_SVLAN_C2SCFG127_CTRL0_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG127_CTRL0_MASK 0x3F + +#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL1 0x0e7e +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_OFFSET 8 +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_MASK 0x700 +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_MASK 0xFF + +#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL2 0x0e7f +#define RTL8367C_SVLAN_C2SCFG127_CTRL2_OFFSET 0 +#define RTL8367C_SVLAN_C2SCFG127_CTRL2_MASK 0x1FFF + +#define RTL8367C_REG_SVLAN_CFG 0x0e80 +#define RTL8367C_VS_PORT7_DMACVIDSEL_OFFSET 14 +#define RTL8367C_VS_PORT7_DMACVIDSEL_MASK 0x4000 +#define RTL8367C_VS_PORT6_DMACVIDSEL_OFFSET 13 +#define RTL8367C_VS_PORT6_DMACVIDSEL_MASK 0x2000 +#define RTL8367C_VS_PORT5_DMACVIDSEL_OFFSET 12 +#define RTL8367C_VS_PORT5_DMACVIDSEL_MASK 0x1000 +#define RTL8367C_VS_PORT4_DMACVIDSEL_OFFSET 11 +#define RTL8367C_VS_PORT4_DMACVIDSEL_MASK 0x800 +#define RTL8367C_VS_PORT3_DMACVIDSEL_OFFSET 10 +#define RTL8367C_VS_PORT3_DMACVIDSEL_MASK 0x400 +#define RTL8367C_VS_PORT2_DMACVIDSEL_OFFSET 9 +#define RTL8367C_VS_PORT2_DMACVIDSEL_MASK 0x200 +#define RTL8367C_VS_PORT1_DMACVIDSEL_OFFSET 8 +#define RTL8367C_VS_PORT1_DMACVIDSEL_MASK 0x100 +#define RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET 7 +#define RTL8367C_VS_PORT0_DMACVIDSEL_MASK 0x80 +#define RTL8367C_VS_UIFSEG_OFFSET 6 +#define RTL8367C_VS_UIFSEG_MASK 0x40 +#define RTL8367C_VS_UNMAT_OFFSET 4 +#define RTL8367C_VS_UNMAT_MASK 0x30 +#define RTL8367C_VS_UNTAG_OFFSET 2 +#define RTL8367C_VS_UNTAG_MASK 0xC +#define RTL8367C_VS_SPRISEL_OFFSET 0 +#define RTL8367C_VS_SPRISEL_MASK 0x3 + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 0x0e81 +#define RTL8367C_VS_PORT1_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT1_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT0_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT0_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL1 0x0e82 +#define RTL8367C_VS_PORT3_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT3_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT2_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT2_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL2 0x0e83 +#define RTL8367C_VS_PORT5_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT5_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT4_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT4_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL3 0x0e84 +#define RTL8367C_VS_PORT7_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT7_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT6_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT6_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG 0x0e85 +#define RTL8367C_VS_UNTAG_SVIDX_OFFSET 8 +#define RTL8367C_VS_UNTAG_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_UNMAT_SVIDX_OFFSET 0 +#define RTL8367C_VS_UNMAT_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_LOOKUP_TYPE 0x0e86 +#define RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET 0 +#define RTL8367C_SVLAN_LOOKUP_TYPE_MASK 0x1 + +#define RTL8367C_REG_IPMC_GROUP_VALID_15_0 0x0e87 + +#define RTL8367C_REG_IPMC_GROUP_VALID_31_16 0x0e88 + +#define RTL8367C_REG_IPMC_GROUP_VALID_47_32 0x0e89 + +#define RTL8367C_REG_IPMC_GROUP_VALID_63_48 0x0e8a + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4 0x0e8b +#define RTL8367C_VS_PORT9_SVIDX_OFFSET 8 +#define RTL8367C_VS_PORT9_SVIDX_MASK 0x3F00 +#define RTL8367C_VS_PORT8_SVIDX_OFFSET 0 +#define RTL8367C_VS_PORT8_SVIDX_MASK 0x3F + +#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5 0x0e8c +#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_OFFSET 0 +#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK 0x3F + +#define RTL8367C_REG_SVLAN_CFG_EXT 0x0e8d +#define RTL8367C_VS_PORT10_DMACVIDSEL_OFFSET 2 +#define RTL8367C_VS_PORT10_DMACVIDSEL_MASK 0x4 +#define RTL8367C_VS_PORT9_DMACVIDSEL_OFFSET 1 +#define RTL8367C_VS_PORT9_DMACVIDSEL_MASK 0x2 +#define RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET 0 +#define RTL8367C_VS_PORT8_DMACVIDSEL_MASK 0x1 + +#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4 0x0e8e +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_OFFSET 0 +#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_DUMMY_0 0x0e90 + +#define RTL8367C_REG_SVLAN_DUMMY_1 0x0e91 + +#define RTL8367C_REG_SVLAN_DUMMY_2 0x0e92 + +#define RTL8367C_REG_SVLAN_DUMMY_3 0x0e93 + +#define RTL8367C_REG_SVLAN_DUMMY_4 0x0e94 + +#define RTL8367C_REG_SVLAN_DUMMY_5 0x0e95 + +#define RTL8367C_REG_SVLAN_DUMMY_6 0x0e96 + +#define RTL8367C_REG_SVLAN_DUMMY_7 0x0e97 + +#define RTL8367C_REG_SVLAN_DUMMY_8 0x0e98 + +#define RTL8367C_REG_SVLAN_DUMMY_9 0x0e99 + +#define RTL8367C_REG_SVLAN_DUMMY_10 0x0e9a + +#define RTL8367C_REG_SVLAN_DUMMY_11 0x0e9b + +#define RTL8367C_REG_SVLAN_DUMMY_12 0x0e9c + +#define RTL8367C_REG_SVLAN_DUMMY_13 0x0e9d + +#define RTL8367C_REG_SVLAN_DUMMY_14 0x0e9e + +#define RTL8367C_REG_SVLAN_DUMMY_15 0x0e9f + +#define RTL8367C_REG_SVLAN_DUMMY_16 0x0ea0 + +#define RTL8367C_REG_SVLAN_DUMMY_17 0x0ea1 + +#define RTL8367C_REG_SVLAN_DUMMY_18 0x0ea2 + +#define RTL8367C_REG_SVLAN_DUMMY_19 0x0ea3 + +#define RTL8367C_REG_SVLAN_DUMMY_20 0x0ea4 + +#define RTL8367C_REG_SVLAN_DUMMY_21 0x0ea5 + +#define RTL8367C_REG_SVLAN_DUMMY_22 0x0ea6 + +#define RTL8367C_REG_SVLAN_DUMMY_23 0x0ea7 + +#define RTL8367C_REG_SVLAN_DUMMY_24 0x0ea8 + +#define RTL8367C_REG_SVLAN_DUMMY_25 0x0ea9 + +#define RTL8367C_REG_SVLAN_DUMMY_26 0x0eaa + +#define RTL8367C_REG_SVLAN_DUMMY_27 0x0eab + +#define RTL8367C_REG_SVLAN_DUMMY_28 0x0eac + +#define RTL8367C_REG_SVLAN_DUMMY_29 0x0ead + +#define RTL8367C_REG_SVLAN_DUMMY_30 0x0eae + +#define RTL8367C_REG_SVLAN_DUMMY_31 0x0eaf + +#define RTL8367C_REG_IPMC_GROUP_VID_00 0x0eb0 +#define RTL8367C_IPMC_GROUP_VID_00_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_00_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_01 0x0eb1 +#define RTL8367C_IPMC_GROUP_VID_01_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_01_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_02 0x0eb2 +#define RTL8367C_IPMC_GROUP_VID_02_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_02_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_03 0x0eb3 +#define RTL8367C_IPMC_GROUP_VID_03_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_03_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_04 0x0eb4 +#define RTL8367C_IPMC_GROUP_VID_04_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_04_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_05 0x0eb5 +#define RTL8367C_IPMC_GROUP_VID_05_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_05_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_06 0x0eb6 +#define RTL8367C_IPMC_GROUP_VID_06_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_06_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_07 0x0eb7 +#define RTL8367C_IPMC_GROUP_VID_07_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_07_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_08 0x0eb8 +#define RTL8367C_IPMC_GROUP_VID_08_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_08_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_09 0x0eb9 +#define RTL8367C_IPMC_GROUP_VID_09_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_09_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_10 0x0eba +#define RTL8367C_IPMC_GROUP_VID_10_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_10_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_11 0x0ebb +#define RTL8367C_IPMC_GROUP_VID_11_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_11_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_12 0x0ebc +#define RTL8367C_IPMC_GROUP_VID_12_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_12_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_13 0x0ebd +#define RTL8367C_IPMC_GROUP_VID_13_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_13_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_14 0x0ebe +#define RTL8367C_IPMC_GROUP_VID_14_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_14_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_15 0x0ebf +#define RTL8367C_IPMC_GROUP_VID_15_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_15_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_16 0x0ec0 +#define RTL8367C_IPMC_GROUP_VID_16_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_16_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_17 0x0ec1 +#define RTL8367C_IPMC_GROUP_VID_17_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_17_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_18 0x0ec2 +#define RTL8367C_IPMC_GROUP_VID_18_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_18_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_19 0x0ec3 +#define RTL8367C_IPMC_GROUP_VID_19_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_19_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_20 0x0ec4 +#define RTL8367C_IPMC_GROUP_VID_20_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_20_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_21 0x0ec5 +#define RTL8367C_IPMC_GROUP_VID_21_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_21_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_22 0x0ec6 +#define RTL8367C_IPMC_GROUP_VID_22_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_22_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_23 0x0ec7 +#define RTL8367C_IPMC_GROUP_VID_23_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_23_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_24 0x0ec8 +#define RTL8367C_IPMC_GROUP_VID_24_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_24_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_25 0x0ec9 +#define RTL8367C_IPMC_GROUP_VID_25_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_25_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_26 0x0eca +#define RTL8367C_IPMC_GROUP_VID_26_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_26_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_27 0x0ecb +#define RTL8367C_IPMC_GROUP_VID_27_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_27_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_28 0x0ecc +#define RTL8367C_IPMC_GROUP_VID_28_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_28_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_29 0x0ecd +#define RTL8367C_IPMC_GROUP_VID_29_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_29_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_30 0x0ece +#define RTL8367C_IPMC_GROUP_VID_30_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_30_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_31 0x0ecf +#define RTL8367C_IPMC_GROUP_VID_31_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_31_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_32 0x0ed0 +#define RTL8367C_IPMC_GROUP_VID_32_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_32_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_33 0x0ed1 +#define RTL8367C_IPMC_GROUP_VID_33_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_33_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_34 0x0ed2 +#define RTL8367C_IPMC_GROUP_VID_34_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_34_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_35 0x0ed3 +#define RTL8367C_IPMC_GROUP_VID_35_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_35_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_36 0x0ed4 +#define RTL8367C_IPMC_GROUP_VID_36_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_36_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_37 0x0ed5 +#define RTL8367C_IPMC_GROUP_VID_37_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_37_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_38 0x0ed6 +#define RTL8367C_IPMC_GROUP_VID_38_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_38_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_39 0x0ed7 +#define RTL8367C_IPMC_GROUP_VID_39_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_39_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_40 0x0ed8 +#define RTL8367C_IPMC_GROUP_VID_40_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_40_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_41 0x0ed9 +#define RTL8367C_IPMC_GROUP_VID_41_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_41_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_42 0x0eda +#define RTL8367C_IPMC_GROUP_VID_42_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_42_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_43 0x0edb +#define RTL8367C_IPMC_GROUP_VID_43_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_43_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_44 0x0edc +#define RTL8367C_IPMC_GROUP_VID_44_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_44_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_45 0x0edd +#define RTL8367C_IPMC_GROUP_VID_45_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_45_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_46 0x0ede +#define RTL8367C_IPMC_GROUP_VID_46_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_46_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_47 0x0edf +#define RTL8367C_IPMC_GROUP_VID_47_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_47_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_48 0x0ef0 +#define RTL8367C_IPMC_GROUP_VID_48_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_48_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_49 0x0ef1 +#define RTL8367C_IPMC_GROUP_VID_49_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_49_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_50 0x0ef2 +#define RTL8367C_IPMC_GROUP_VID_50_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_50_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_51 0x0ef3 +#define RTL8367C_IPMC_GROUP_VID_51_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_51_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_52 0x0ef4 +#define RTL8367C_IPMC_GROUP_VID_52_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_52_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_53 0x0ef5 +#define RTL8367C_IPMC_GROUP_VID_53_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_53_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_54 0x0ef6 +#define RTL8367C_IPMC_GROUP_VID_54_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_54_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_55 0x0ef7 +#define RTL8367C_IPMC_GROUP_VID_55_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_55_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_56 0x0ef8 +#define RTL8367C_IPMC_GROUP_VID_56_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_56_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_57 0x0ef9 +#define RTL8367C_IPMC_GROUP_VID_57_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_57_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_58 0x0efa +#define RTL8367C_IPMC_GROUP_VID_58_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_58_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_59 0x0efb +#define RTL8367C_IPMC_GROUP_VID_59_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_59_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_60 0x0efc +#define RTL8367C_IPMC_GROUP_VID_60_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_60_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_61 0x0efd +#define RTL8367C_IPMC_GROUP_VID_61_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_61_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_62 0x0efe +#define RTL8367C_IPMC_GROUP_VID_62_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_62_MASK 0xFFF + +#define RTL8367C_REG_IPMC_GROUP_VID_63 0x0eff +#define RTL8367C_IPMC_GROUP_VID_63_OFFSET 0 +#define RTL8367C_IPMC_GROUP_VID_63_MASK 0xFFF + +/* (16'h0f00)hsactrl_reg */ + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 0x0f00 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL1 0x0f01 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL0 0x0f02 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL1 0x0f03 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL0 0x0f04 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL1 0x0f05 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL0 0x0f06 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL1 0x0f07 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL0 0x0f08 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL1 0x0f09 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL0 0x0f0a +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL1 0x0f0b +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL0 0x0f0c +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL1 0x0f0d +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL0 0x0f0e +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL1 0x0f0f +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL0 0x0f10 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL1 0x0f11 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL0 0x0f12 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL1 0x0f13 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL0 0x0f14 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL1 0x0f15 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL0 0x0f16 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL1 0x0f17 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL0 0x0f18 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL1 0x0f19 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL0 0x0f1a +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL1 0x0f1b +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL0 0x0f1c +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL1 0x0f1d +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL0 0x0f1e +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL1 0x0f1f +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL0 0x0f20 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL1 0x0f21 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL0 0x0f22 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL1 0x0f23 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL0 0x0f24 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL1 0x0f25 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL0 0x0f26 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL1 0x0f27 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL0 0x0f28 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL1 0x0f29 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL0 0x0f2a +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL1 0x0f2b +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL0 0x0f2c +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL1 0x0f2d +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL0 0x0f2e +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL1 0x0f2f +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL0 0x0f30 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL1 0x0f31 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL0 0x0f32 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL1 0x0f33 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL0 0x0f34 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL1 0x0f35 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL0 0x0f36 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL1 0x0f37 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL0 0x0f38 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL1 0x0f39 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL0 0x0f3a +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL1 0x0f3b +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL0 0x0f3c +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL1 0x0f3d +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL0 0x0f3e +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL1 0x0f3f +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL0 0x0f40 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL1 0x0f41 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL0 0x0f42 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL1 0x0f43 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL0 0x0f44 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL1 0x0f45 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL0 0x0f46 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL1 0x0f47 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL0 0x0f48 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL1 0x0f49 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL0 0x0f4a +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL1 0x0f4b +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL0 0x0f4c +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL1 0x0f4d +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL0 0x0f4e +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL1 0x0f4f +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL0 0x0f50 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL1 0x0f51 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL0 0x0f52 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL1 0x0f53 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL0 0x0f54 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL1 0x0f55 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL0 0x0f56 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL1 0x0f57 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL0 0x0f58 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL1 0x0f59 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL0 0x0f5a +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL1 0x0f5b +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL0 0x0f5c +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL1 0x0f5d +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL0 0x0f5e +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL1 0x0f5f +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL0 0x0f60 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL1 0x0f61 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL0 0x0f62 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL1 0x0f63 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL0 0x0f64 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL1 0x0f65 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL0 0x0f66 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL1 0x0f67 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL0 0x0f68 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL1 0x0f69 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL0 0x0f6a +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL1 0x0f6b +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL0 0x0f6c +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL1 0x0f6d +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL0 0x0f6e +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL1 0x0f6f +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL0 0x0f70 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL1 0x0f71 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL0 0x0f72 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL1 0x0f73 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL0 0x0f74 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL1 0x0f75 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL0 0x0f76 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL1 0x0f77 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL0 0x0f78 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL1 0x0f79 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL0 0x0f7a +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL1 0x0f7b +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL0 0x0f7c +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL1 0x0f7d +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL0 0x0f7e +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL1 0x0f7f +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL0 0x0f80 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL1 0x0f81 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL0 0x0f82 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL1 0x0f83 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL0 0x0f84 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL1 0x0f85 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL0 0x0f86 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL1 0x0f87 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL0 0x0f88 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL1 0x0f89 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL0 0x0f8a +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL1 0x0f8b +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL0 0x0f8c +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL1 0x0f8d +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL0 0x0f8e +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL1 0x0f8f +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL0 0x0f90 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL1 0x0f91 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL0 0x0f92 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL1 0x0f93 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL0 0x0f94 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL1 0x0f95 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL0 0x0f96 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL1 0x0f97 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL0 0x0f98 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL1 0x0f99 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL0 0x0f9a +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL1 0x0f9b +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL0 0x0f9c +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL1 0x0f9d +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL0 0x0f9e +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL1 0x0f9f +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL0 0x0fa0 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL1 0x0fa1 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL0 0x0fa2 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL1 0x0fa3 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL0 0x0fa4 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL1 0x0fa5 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL0 0x0fa6 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL1 0x0fa7 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL0 0x0fa8 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL1 0x0fa9 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL0 0x0faa +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL1 0x0fab +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL0 0x0fac +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL1 0x0fad +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL0 0x0fae +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL1 0x0faf +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL0 0x0fb0 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL1 0x0fb1 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL0 0x0fb2 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL1 0x0fb3 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL0 0x0fb4 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL1 0x0fb5 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL0 0x0fb6 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL1 0x0fb7 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL0 0x0fb8 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL1 0x0fb9 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL0 0x0fba +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL1 0x0fbb +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL0 0x0fbc +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL1 0x0fbd +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL0 0x0fbe +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL1 0x0fbf +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL0 0x0fc0 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL1 0x0fc1 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL0 0x0fc2 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL1 0x0fc3 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL0 0x0fc4 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL1 0x0fc5 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL0 0x0fc6 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL1 0x0fc7 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL0 0x0fc8 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL1 0x0fc9 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL0 0x0fca +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL1 0x0fcb +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL0 0x0fcc +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL1 0x0fcd +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL0 0x0fce +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL1 0x0fcf +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL0 0x0fd0 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL1 0x0fd1 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL0 0x0fd2 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL1 0x0fd3 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL0 0x0fd4 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL1 0x0fd5 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL0 0x0fd6 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL1 0x0fd7 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL0 0x0fd8 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL1 0x0fd9 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL0 0x0fda +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL1 0x0fdb +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL0 0x0fdc +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL1 0x0fdd +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL0 0x0fde +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL1 0x0fdf +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL0 0x0fe0 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL1 0x0fe1 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL0 0x0fe2 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL1 0x0fe3 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL0 0x0fe4 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL1 0x0fe5 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL0 0x0fe6 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL1 0x0fe7 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL0 0x0fe8 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL1 0x0fe9 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL0 0x0fea +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL1 0x0feb +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL0 0x0fec +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL1 0x0fed +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL0 0x0fee +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL1 0x0fef +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL0 0x0ff0 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL1 0x0ff1 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL0 0x0ff2 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL1 0x0ff3 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL0 0x0ff4 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL1 0x0ff5 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL0 0x0ff6 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL1 0x0ff7 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL0 0x0ff8 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL1 0x0ff9 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL0 0x0ffa +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL1 0x0ffb +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL0 0x0ffc +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL1 0x0ffd +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_MASK 0xFFF + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL0 0x0ffe +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_OFFSET 9 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_MASK 0x200 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_OFFSET 3 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_MASK 0x1F8 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_MASK 0x7 + +#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL1 0x0fff +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_OFFSET 12 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_MASK 0x1000 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_OFFSET 0 +#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_MASK 0xFFF + +/* (16'h1000)mib_reg */ + +#define RTL8367C_REG_MIB_COUNTER0 0x1000 + +#define RTL8367C_REG_MIB_COUNTER1 0x1001 + +#define RTL8367C_REG_MIB_COUNTER2 0x1002 + +#define RTL8367C_REG_MIB_COUNTER3 0x1003 + +#define RTL8367C_REG_MIB_ADDRESS 0x1004 +#define RTL8367C_MIB_ADDRESS_OFFSET 0 +#define RTL8367C_MIB_ADDRESS_MASK 0x1FF + +#define RTL8367C_REG_MIB_CTRL0 0x1005 +#define RTL8367C_PORT10_RESET_OFFSET 15 +#define RTL8367C_PORT10_RESET_MASK 0x8000 +#define RTL8367C_PORT9_RESET_OFFSET 14 +#define RTL8367C_PORT9_RESET_MASK 0x4000 +#define RTL8367C_PORT8_RESET_OFFSET 13 +#define RTL8367C_PORT8_RESET_MASK 0x2000 +#define RTL8367C_RESET_VALUE_OFFSET 12 +#define RTL8367C_RESET_VALUE_MASK 0x1000 +#define RTL8367C_GLOBAL_RESET_OFFSET 11 +#define RTL8367C_GLOBAL_RESET_MASK 0x800 +#define RTL8367C_QM_RESET_OFFSET 10 +#define RTL8367C_QM_RESET_MASK 0x400 +#define RTL8367C_PORT7_RESET_OFFSET 9 +#define RTL8367C_PORT7_RESET_MASK 0x200 +#define RTL8367C_PORT6_RESET_OFFSET 8 +#define RTL8367C_PORT6_RESET_MASK 0x100 +#define RTL8367C_PORT5_RESET_OFFSET 7 +#define RTL8367C_PORT5_RESET_MASK 0x80 +#define RTL8367C_PORT4_RESET_OFFSET 6 +#define RTL8367C_PORT4_RESET_MASK 0x40 +#define RTL8367C_PORT3_RESET_OFFSET 5 +#define RTL8367C_PORT3_RESET_MASK 0x20 +#define RTL8367C_PORT2_RESET_OFFSET 4 +#define RTL8367C_PORT2_RESET_MASK 0x10 +#define RTL8367C_PORT1_RESET_OFFSET 3 +#define RTL8367C_PORT1_RESET_MASK 0x8 +#define RTL8367C_PORT0_RESET_OFFSET 2 +#define RTL8367C_PORT0_RESET_MASK 0x4 +#define RTL8367C_RESET_FLAG_OFFSET 1 +#define RTL8367C_RESET_FLAG_MASK 0x2 +#define RTL8367C_MIB_CTRL0_BUSY_FLAG_OFFSET 0 +#define RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL1 0x1007 +#define RTL8367C_COUNTER15_RESET_OFFSET 15 +#define RTL8367C_COUNTER15_RESET_MASK 0x8000 +#define RTL8367C_COUNTER14_RESET_OFFSET 14 +#define RTL8367C_COUNTER14_RESET_MASK 0x4000 +#define RTL8367C_COUNTER13_RESET_OFFSET 13 +#define RTL8367C_COUNTER13_RESET_MASK 0x2000 +#define RTL8367C_COUNTER12_RESET_OFFSET 12 +#define RTL8367C_COUNTER12_RESET_MASK 0x1000 +#define RTL8367C_COUNTER11_RESET_OFFSET 11 +#define RTL8367C_COUNTER11_RESET_MASK 0x800 +#define RTL8367C_COUNTER10_RESET_OFFSET 10 +#define RTL8367C_COUNTER10_RESET_MASK 0x400 +#define RTL8367C_COUNTER9_RESET_OFFSET 9 +#define RTL8367C_COUNTER9_RESET_MASK 0x200 +#define RTL8367C_COUNTER8_RESET_OFFSET 8 +#define RTL8367C_COUNTER8_RESET_MASK 0x100 +#define RTL8367C_COUNTER7_RESET_OFFSET 7 +#define RTL8367C_COUNTER7_RESET_MASK 0x80 +#define RTL8367C_COUNTER6_RESET_OFFSET 6 +#define RTL8367C_COUNTER6_RESET_MASK 0x40 +#define RTL8367C_COUNTER5_RESET_OFFSET 5 +#define RTL8367C_COUNTER5_RESET_MASK 0x20 +#define RTL8367C_COUNTER4_RESET_OFFSET 4 +#define RTL8367C_COUNTER4_RESET_MASK 0x10 +#define RTL8367C_COUNTER3_RESET_OFFSET 3 +#define RTL8367C_COUNTER3_RESET_MASK 0x8 +#define RTL8367C_COUNTER2_RESET_OFFSET 2 +#define RTL8367C_COUNTER2_RESET_MASK 0x4 +#define RTL8367C_COUNTER1_RESET_OFFSET 1 +#define RTL8367C_COUNTER1_RESET_MASK 0x2 +#define RTL8367C_COUNTER0_RESET_OFFSET 0 +#define RTL8367C_COUNTER0_RESET_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL2 0x1008 +#define RTL8367C_COUNTER31_RESET_OFFSET 15 +#define RTL8367C_COUNTER31_RESET_MASK 0x8000 +#define RTL8367C_COUNTER30_RESET_OFFSET 14 +#define RTL8367C_COUNTER30_RESET_MASK 0x4000 +#define RTL8367C_COUNTER29_RESET_OFFSET 13 +#define RTL8367C_COUNTER29_RESET_MASK 0x2000 +#define RTL8367C_COUNTER28_RESET_OFFSET 12 +#define RTL8367C_COUNTER28_RESET_MASK 0x1000 +#define RTL8367C_COUNTER27_RESET_OFFSET 11 +#define RTL8367C_COUNTER27_RESET_MASK 0x800 +#define RTL8367C_COUNTER26_RESET_OFFSET 10 +#define RTL8367C_COUNTER26_RESET_MASK 0x400 +#define RTL8367C_COUNTER25_RESET_OFFSET 9 +#define RTL8367C_COUNTER25_RESET_MASK 0x200 +#define RTL8367C_COUNTER24_RESET_OFFSET 8 +#define RTL8367C_COUNTER24_RESET_MASK 0x100 +#define RTL8367C_COUNTER23_RESET_OFFSET 7 +#define RTL8367C_COUNTER23_RESET_MASK 0x80 +#define RTL8367C_COUNTER22_RESET_OFFSET 6 +#define RTL8367C_COUNTER22_RESET_MASK 0x40 +#define RTL8367C_COUNTER21_RESET_OFFSET 5 +#define RTL8367C_COUNTER21_RESET_MASK 0x20 +#define RTL8367C_COUNTER20_RESET_OFFSET 4 +#define RTL8367C_COUNTER20_RESET_MASK 0x10 +#define RTL8367C_COUNTER19_RESET_OFFSET 3 +#define RTL8367C_COUNTER19_RESET_MASK 0x8 +#define RTL8367C_COUNTER18_RESET_OFFSET 2 +#define RTL8367C_COUNTER18_RESET_MASK 0x4 +#define RTL8367C_COUNTER17_RESET_OFFSET 1 +#define RTL8367C_COUNTER17_RESET_MASK 0x2 +#define RTL8367C_COUNTER16_RESET_OFFSET 0 +#define RTL8367C_COUNTER16_RESET_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL3 0x1009 +#define RTL8367C_COUNTER15_MODE_OFFSET 15 +#define RTL8367C_COUNTER15_MODE_MASK 0x8000 +#define RTL8367C_COUNTER14_MODE_OFFSET 14 +#define RTL8367C_COUNTER14_MODE_MASK 0x4000 +#define RTL8367C_COUNTER13_MODE_OFFSET 13 +#define RTL8367C_COUNTER13_MODE_MASK 0x2000 +#define RTL8367C_COUNTER12_MODE_OFFSET 12 +#define RTL8367C_COUNTER12_MODE_MASK 0x1000 +#define RTL8367C_COUNTER11_MODE_OFFSET 11 +#define RTL8367C_COUNTER11_MODE_MASK 0x800 +#define RTL8367C_COUNTER10_MODE_OFFSET 10 +#define RTL8367C_COUNTER10_MODE_MASK 0x400 +#define RTL8367C_COUNTER9_MODE_OFFSET 9 +#define RTL8367C_COUNTER9_MODE_MASK 0x200 +#define RTL8367C_COUNTER8_MODE_OFFSET 8 +#define RTL8367C_COUNTER8_MODE_MASK 0x100 +#define RTL8367C_COUNTER7_MODE_OFFSET 7 +#define RTL8367C_COUNTER7_MODE_MASK 0x80 +#define RTL8367C_COUNTER6_MODE_OFFSET 6 +#define RTL8367C_COUNTER6_MODE_MASK 0x40 +#define RTL8367C_COUNTER5_MODE_OFFSET 5 +#define RTL8367C_COUNTER5_MODE_MASK 0x20 +#define RTL8367C_COUNTER4_MODE_OFFSET 4 +#define RTL8367C_COUNTER4_MODE_MASK 0x10 +#define RTL8367C_COUNTER3_MODE_OFFSET 3 +#define RTL8367C_COUNTER3_MODE_MASK 0x8 +#define RTL8367C_COUNTER2_MODE_OFFSET 2 +#define RTL8367C_COUNTER2_MODE_MASK 0x4 +#define RTL8367C_COUNTER1_MODE_OFFSET 1 +#define RTL8367C_COUNTER1_MODE_MASK 0x2 +#define RTL8367C_COUNTER0_MODE_OFFSET 0 +#define RTL8367C_COUNTER0_MODE_MASK 0x1 + +#define RTL8367C_REG_MIB_CTRL4 0x100a +#define RTL8367C_MIB_USAGE_MODE_OFFSET 8 +#define RTL8367C_MIB_USAGE_MODE_MASK 0x100 +#define RTL8367C_MIB_TIMER_OFFSET 0 +#define RTL8367C_MIB_TIMER_MASK 0xFF + +#define RTL8367C_REG_MIB_CTRL5 0x100b +#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_OFFSET 15 +#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_MASK 0x8000 +#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_OFFSET 14 +#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_MASK 0x4000 +#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_OFFSET 13 +#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_MASK 0x2000 +#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_OFFSET 12 +#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_MASK 0x1000 +#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_OFFSET 11 +#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_MASK 0x800 +#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_OFFSET 10 +#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_MASK 0x400 +#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_OFFSET 9 +#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_MASK 0x200 +#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_OFFSET 8 +#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_MASK 0x100 +#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_OFFSET 7 +#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_MASK 0x80 +#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_OFFSET 6 +#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_MASK 0x40 +#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_OFFSET 5 +#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_MASK 0x20 +#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_OFFSET 4 +#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_MASK 0x10 +#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_OFFSET 3 +#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_MASK 0x8 +#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_OFFSET 2 +#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_MASK 0x4 +#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_OFFSET 1 +#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_MASK 0x2 +#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_OFFSET 0 +#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_MASK 0x1 + +/* (16'h1100)intrpt_reg */ + +#define RTL8367C_REG_INTR_CTRL 0x1100 +#define RTL8367C_INTR_CTRL_OFFSET 0 +#define RTL8367C_INTR_CTRL_MASK 0x1 + +#define RTL8367C_REG_INTR_IMR 0x1101 +#define RTL8367C_INTR_IMR_SLIENT_START_2_OFFSET 12 +#define RTL8367C_INTR_IMR_SLIENT_START_2_MASK 0x1000 +#define RTL8367C_INTR_IMR_SLIENT_START_OFFSET 11 +#define RTL8367C_INTR_IMR_SLIENT_START_MASK 0x800 +#define RTL8367C_INTR_IMR_ACL_ACTION_OFFSET 9 +#define RTL8367C_INTR_IMR_ACL_ACTION_MASK 0x200 +#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_OFFSET 8 +#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_MASK 0x100 +#define RTL8367C_INTR_IMR_INTERRUPT_8051_OFFSET 7 +#define RTL8367C_INTR_IMR_INTERRUPT_8051_MASK 0x80 +#define RTL8367C_INTR_IMR_LOOP_DETECTION_OFFSET 6 +#define RTL8367C_INTR_IMR_LOOP_DETECTION_MASK 0x40 +#define RTL8367C_INTR_IMR_GREEN_TIMER_OFFSET 5 +#define RTL8367C_INTR_IMR_GREEN_TIMER_MASK 0x20 +#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_OFFSET 4 +#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_MASK 0x10 +#define RTL8367C_INTR_IMR_SPEED_CHANGE_OFFSET 3 +#define RTL8367C_INTR_IMR_SPEED_CHANGE_MASK 0x8 +#define RTL8367C_INTR_IMR_LEARN_OVER_OFFSET 2 +#define RTL8367C_INTR_IMR_LEARN_OVER_MASK 0x4 +#define RTL8367C_INTR_IMR_METER_EXCEEDED_OFFSET 1 +#define RTL8367C_INTR_IMR_METER_EXCEEDED_MASK 0x2 +#define RTL8367C_INTR_IMR_LINK_CHANGE_OFFSET 0 +#define RTL8367C_INTR_IMR_LINK_CHANGE_MASK 0x1 + +#define RTL8367C_REG_INTR_IMS 0x1102 +#define RTL8367C_INTR_IMS_SLIENT_START_2_OFFSET 12 +#define RTL8367C_INTR_IMS_SLIENT_START_2_MASK 0x1000 +#define RTL8367C_INTR_IMS_SLIENT_START_OFFSET 11 +#define RTL8367C_INTR_IMS_SLIENT_START_MASK 0x800 +#define RTL8367C_INTR_IMS_ACL_ACTION_OFFSET 9 +#define RTL8367C_INTR_IMS_ACL_ACTION_MASK 0x200 +#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_OFFSET 8 +#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_MASK 0x100 +#define RTL8367C_INTR_IMS_INTERRUPT_8051_OFFSET 7 +#define RTL8367C_INTR_IMS_INTERRUPT_8051_MASK 0x80 +#define RTL8367C_INTR_IMS_LOOP_DETECTION_OFFSET 6 +#define RTL8367C_INTR_IMS_LOOP_DETECTION_MASK 0x40 +#define RTL8367C_INTR_IMS_GREEN_TIMER_OFFSET 5 +#define RTL8367C_INTR_IMS_GREEN_TIMER_MASK 0x20 +#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_OFFSET 4 +#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_MASK 0x10 +#define RTL8367C_INTR_IMS_SPEED_CHANGE_OFFSET 3 +#define RTL8367C_INTR_IMS_SPEED_CHANGE_MASK 0x8 +#define RTL8367C_INTR_IMS_LEARN_OVER_OFFSET 2 +#define RTL8367C_INTR_IMS_LEARN_OVER_MASK 0x4 +#define RTL8367C_INTR_IMS_METER_EXCEEDED_OFFSET 1 +#define RTL8367C_INTR_IMS_METER_EXCEEDED_MASK 0x2 +#define RTL8367C_INTR_IMS_LINK_CHANGE_OFFSET 0 +#define RTL8367C_INTR_IMS_LINK_CHANGE_MASK 0x1 + +#define RTL8367C_REG_LEARN_OVER_INDICATOR 0x1103 +#define RTL8367C_LEARN_OVER_INDICATOR_OFFSET 0 +#define RTL8367C_LEARN_OVER_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_SPEED_CHANGE_INDICATOR 0x1104 +#define RTL8367C_SPEED_CHANGE_INDICATOR_OFFSET 0 +#define RTL8367C_SPEED_CHANGE_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR 0x1105 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_OFFSET 0 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR 0x1106 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_OFFSET 0 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKUP_INDICATOR 0x1107 +#define RTL8367C_PORT_LINKUP_INDICATOR_OFFSET 0 +#define RTL8367C_PORT_LINKUP_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR 0x1108 +#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_OFFSET 0 +#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_MASK 0x1 + +#define RTL8367C_REG_INTR_IMR_8051 0x1118 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_OFFSET 13 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_MASK 0x2000 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_OFFSET 12 +#define RTL8367C_INTR_IMR_8051_SLIENT_START_MASK 0x1000 +#define RTL8367C_INTR_IMR_8051_ACL_ACTION_OFFSET 10 +#define RTL8367C_INTR_IMR_8051_ACL_ACTION_MASK 0x400 +#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_OFFSET 9 +#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_MASK 0x200 +#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_OFFSET 8 +#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_MASK 0x100 +#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_OFFSET 7 +#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_MASK 0x80 +#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_OFFSET 6 +#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_MASK 0x40 +#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_OFFSET 5 +#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_MASK 0x20 +#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_OFFSET 4 +#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_MASK 0x10 +#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_OFFSET 3 +#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_MASK 0x8 +#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_OFFSET 2 +#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_MASK 0x4 +#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_OFFSET 1 +#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_MASK 0x2 +#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_OFFSET 0 +#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_MASK 0x1 + +#define RTL8367C_REG_INTR_IMS_8051 0x1119 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_OFFSET 13 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_MASK 0x2000 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_OFFSET 12 +#define RTL8367C_INTR_IMS_8051_SLIENT_START_MASK 0x1000 +#define RTL8367C_INTR_IMS_8051_ACL_ACTION_OFFSET 10 +#define RTL8367C_INTR_IMS_8051_ACL_ACTION_MASK 0x400 +#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_OFFSET 9 +#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_MASK 0x200 +#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_OFFSET 8 +#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_MASK 0x100 +#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_OFFSET 7 +#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_MASK 0x80 +#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_OFFSET 6 +#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_MASK 0x40 +#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_OFFSET 5 +#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_MASK 0x20 +#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_OFFSET 4 +#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_MASK 0x10 +#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_OFFSET 3 +#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_MASK 0x8 +#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_OFFSET 2 +#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_MASK 0x4 +#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_OFFSET 1 +#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_MASK 0x2 +#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_OFFSET 0 +#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_MASK 0x1 + +#define RTL8367C_REG_DW8051_INT_CPU 0x111a +#define RTL8367C_DW8051_INT_CPU_OFFSET 0 +#define RTL8367C_DW8051_INT_CPU_MASK 0x1 + +#define RTL8367C_REG_LEARN_OVER_INDICATOR_8051 0x1120 +#define RTL8367C_LEARN_OVER_INDICATOR_8051_OFFSET 0 +#define RTL8367C_LEARN_OVER_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_SPEED_CHANGE_INDICATOR_8051 0x1121 +#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_OFFSET 0 +#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR_8051 0x1122 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_OFFSET 0 +#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR_8051 0x1123 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_OFFSET 0 +#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_PORT_LINKUP_INDICATOR_8051 0x1124 +#define RTL8367C_PORT_LINKUP_INDICATOR_8051_OFFSET 0 +#define RTL8367C_PORT_LINKUP_INDICATOR_8051_MASK 0x7FF + +#define RTL8367C_REG_DUMMY_1125 0x1125 + +#define RTL8367C_REG_DUMMY_1126 0x1126 + +#define RTL8367C_REG_DUMMY_1127 0x1127 + +#define RTL8367C_REG_DUMMY_1128 0x1128 + +#define RTL8367C_REG_DUMMY_1129 0x1129 + +#define RTL8367C_REG_INTR_IMS_BUFFER_RESET 0x112a +#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 +#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 +#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_OFFSET 0 +#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_MASK 0x1 + +#define RTL8367C_REG_INTR_IMS_8051_BUFFER_RESET 0x112b +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_OFFSET 0 +#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_MASK 0x1 + +#define RTL8367C_REG_GPHY_INTRPT_8051 0x112c +#define RTL8367C_IMS_GPHY_8051_H_OFFSET 13 +#define RTL8367C_IMS_GPHY_8051_H_MASK 0xE000 +#define RTL8367C_IMR_GPHY_8051_H_OFFSET 10 +#define RTL8367C_IMR_GPHY_8051_H_MASK 0x1C00 +#define RTL8367C_IMS_GPHY_8051_OFFSET 5 +#define RTL8367C_IMS_GPHY_8051_MASK 0x3E0 +#define RTL8367C_IMR_GPHY_8051_OFFSET 0 +#define RTL8367C_IMR_GPHY_8051_MASK 0x1F + +#define RTL8367C_REG_GPHY_INTRPT 0x112d +#define RTL8367C_IMS_GPHY_H_OFFSET 13 +#define RTL8367C_IMS_GPHY_H_MASK 0xE000 +#define RTL8367C_IMR_GPHY_H_OFFSET 10 +#define RTL8367C_IMR_GPHY_H_MASK 0x1C00 +#define RTL8367C_IMS_GPHY_OFFSET 5 +#define RTL8367C_IMS_GPHY_MASK 0x3E0 +#define RTL8367C_IMR_GPHY_OFFSET 0 +#define RTL8367C_IMR_GPHY_MASK 0x1F + +#define RTL8367C_REG_THERMAL_INTRPT 0x112e +#define RTL8367C_IMS_TM_HIGH_OFFSET 3 +#define RTL8367C_IMS_TM_HIGH_MASK 0x8 +#define RTL8367C_IMR_TM_HIGH_OFFSET 2 +#define RTL8367C_IMR_TM_HIGH_MASK 0x4 +#define RTL8367C_IMS_TM_LOW_OFFSET 1 +#define RTL8367C_IMS_TM_LOW_MASK 0x2 +#define RTL8367C_IMR_TM_LOW_OFFSET 0 +#define RTL8367C_IMR_TM_LOW_MASK 0x1 + +#define RTL8367C_REG_THERMAL_INTRPT_8051 0x112f +#define RTL8367C_IMS_TM_HIGH_8051_OFFSET 3 +#define RTL8367C_IMS_TM_HIGH_8051_MASK 0x8 +#define RTL8367C_IMR_TM_HIGH_8051_OFFSET 2 +#define RTL8367C_IMR_TM_HIGH_8051_MASK 0x4 +#define RTL8367C_IMS_TM_LOW_8051_OFFSET 1 +#define RTL8367C_IMS_TM_LOW_8051_MASK 0x2 +#define RTL8367C_IMR_TM_LOW_8051_OFFSET 0 +#define RTL8367C_IMR_TM_LOW_8051_MASK 0x1 + +#define RTL8367C_REG_SDS_LINK_CHG_INT 0x1130 +#define RTL8367C_IMS_SDS_LINK_STS_C7_OFFSET 15 +#define RTL8367C_IMS_SDS_LINK_STS_C7_MASK 0x8000 +#define RTL8367C_IMS_SDS_LINK_STS_C6_OFFSET 14 +#define RTL8367C_IMS_SDS_LINK_STS_C6_MASK 0x4000 +#define RTL8367C_IMS_SDS_LINK_STS_C5_OFFSET 13 +#define RTL8367C_IMS_SDS_LINK_STS_C5_MASK 0x2000 +#define RTL8367C_IMS_SDS_LINK_STS_C4_OFFSET 12 +#define RTL8367C_IMS_SDS_LINK_STS_C4_MASK 0x1000 +#define RTL8367C_IMS_SDS_LINK_STS_C3_OFFSET 11 +#define RTL8367C_IMS_SDS_LINK_STS_C3_MASK 0x800 +#define RTL8367C_IMS_SDS_LINK_STS_C2_OFFSET 10 +#define RTL8367C_IMS_SDS_LINK_STS_C2_MASK 0x400 +#define RTL8367C_IMS_SDS_LINK_STS_C1_OFFSET 9 +#define RTL8367C_IMS_SDS_LINK_STS_C1_MASK 0x200 +#define RTL8367C_IMS_SDS_LINK_STS_C0_OFFSET 8 +#define RTL8367C_IMS_SDS_LINK_STS_C0_MASK 0x100 +#define RTL8367C_IMR_SDS_LINK_STS_C7_OFFSET 7 +#define RTL8367C_IMR_SDS_LINK_STS_C7_MASK 0x80 +#define RTL8367C_IMR_SDS_LINK_STS_C6_OFFSET 6 +#define RTL8367C_IMR_SDS_LINK_STS_C6_MASK 0x40 +#define RTL8367C_IMR_SDS_LINK_STS_C5_OFFSET 5 +#define RTL8367C_IMR_SDS_LINK_STS_C5_MASK 0x20 +#define RTL8367C_IMR_SDS_LINK_STS_C4_OFFSET 4 +#define RTL8367C_IMR_SDS_LINK_STS_C4_MASK 0x10 +#define RTL8367C_IMR_SDS_LINK_STS_C3_OFFSET 3 +#define RTL8367C_IMR_SDS_LINK_STS_C3_MASK 0x8 +#define RTL8367C_IMR_SDS_LINK_STS_C2_OFFSET 2 +#define RTL8367C_IMR_SDS_LINK_STS_C2_MASK 0x4 +#define RTL8367C_IMR_SDS_LINK_STS_C1_OFFSET 1 +#define RTL8367C_IMR_SDS_LINK_STS_C1_MASK 0x2 +#define RTL8367C_IMR_SDS_LINK_STS_C0_OFFSET 0 +#define RTL8367C_IMR_SDS_LINK_STS_C0_MASK 0x1 + +#define RTL8367C_REG_SDS_LINK_CHG_INT_8051 0x1131 +#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_OFFSET 15 +#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_MASK 0x8000 +#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_OFFSET 14 +#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_MASK 0x4000 +#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_OFFSET 13 +#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_MASK 0x2000 +#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_OFFSET 12 +#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_MASK 0x1000 +#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_OFFSET 11 +#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_MASK 0x800 +#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_OFFSET 10 +#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_MASK 0x400 +#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_OFFSET 9 +#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_MASK 0x200 +#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_OFFSET 8 +#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_MASK 0x100 +#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_OFFSET 7 +#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_MASK 0x80 +#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_OFFSET 6 +#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_MASK 0x40 +#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_OFFSET 5 +#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_MASK 0x20 +#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_OFFSET 4 +#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_MASK 0x10 +#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_OFFSET 3 +#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_MASK 0x8 +#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_OFFSET 2 +#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_MASK 0x4 +#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_OFFSET 1 +#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_MASK 0x2 +#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_OFFSET 0 +#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_MASK 0x1 + +/* (16'h1200)swcore_reg */ + +#define RTL8367C_REG_MAX_LENGTH_LIMINT_IPG 0x1200 +#define RTL8367C_MAX_LENTH_CTRL_OFFSET 13 +#define RTL8367C_MAX_LENTH_CTRL_MASK 0x6000 +#define RTL8367C_PAGES_BEFORE_FCDROP_OFFSET 6 +#define RTL8367C_PAGES_BEFORE_FCDROP_MASK 0x1FC0 +#define RTL8367C_CHECK_MIN_IPG_RXDV_OFFSET 5 +#define RTL8367C_CHECK_MIN_IPG_RXDV_MASK 0x20 +#define RTL8367C_LIMIT_IPG_CFG_OFFSET 0 +#define RTL8367C_LIMIT_IPG_CFG_MASK 0x1F + +#define RTL8367C_REG_IOL_RXDROP_CFG 0x1201 +#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_OFFSET 13 +#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_MASK 0x2000 +#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_OFFSET 12 +#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_MASK 0x1000 +#define RTL8367C_RX_NODROP_PAUSE_CFG_OFFSET 8 +#define RTL8367C_RX_NODROP_PAUSE_CFG_MASK 0x100 +#define RTL8367C_RX_DV_CNT_CFG_OFFSET 0 +#define RTL8367C_RX_DV_CNT_CFG_MASK 0x3F + +#define RTL8367C_REG_VS_TPID 0x1202 + +#define RTL8367C_REG_INBW_BOUND 0x1203 +#define RTL8367C_LBOUND_OFFSET 4 +#define RTL8367C_LBOUND_MASK 0xF0 +#define RTL8367C_HBOUND_OFFSET 0 +#define RTL8367C_HBOUND_MASK 0xF + +#define RTL8367C_REG_CFG_TX_ITFSP_OP 0x1204 +#define RTL8367C_MASK_OFFSET 1 +#define RTL8367C_MASK_MASK 0x2 +#define RTL8367C_OP_OFFSET 0 +#define RTL8367C_OP_MASK 0x1 + +#define RTL8367C_REG_INBW_BOUND2 0x1205 +#define RTL8367C_LBOUND2_H_OFFSET 9 +#define RTL8367C_LBOUND2_H_MASK 0x200 +#define RTL8367C_HBOUND2_H_OFFSET 8 +#define RTL8367C_HBOUND2_H_MASK 0x100 +#define RTL8367C_LBOUND2_OFFSET 4 +#define RTL8367C_LBOUND2_MASK 0xF0 +#define RTL8367C_HBOUND2_OFFSET 0 +#define RTL8367C_HBOUND2_MASK 0xF + +#define RTL8367C_REG_CFG_48PASS1_DROP 0x1206 +#define RTL8367C_CFG_48PASS1_DROP_OFFSET 0 +#define RTL8367C_CFG_48PASS1_DROP_MASK 0x1 + +#define RTL8367C_REG_CFG_BACKPRESSURE 0x1207 +#define RTL8367C_LONGTXE_OFFSET 12 +#define RTL8367C_LONGTXE_MASK 0x1000 +#define RTL8367C_EN_BYPASS_ERROR_OFFSET 8 +#define RTL8367C_EN_BYPASS_ERROR_MASK 0x100 +#define RTL8367C_EN_BACKPRESSURE_OFFSET 4 +#define RTL8367C_EN_BACKPRESSURE_MASK 0x10 +#define RTL8367C_EN_48_PASS_1_OFFSET 0 +#define RTL8367C_EN_48_PASS_1_MASK 0x1 + +#define RTL8367C_REG_CFG_UNHIOL 0x1208 +#define RTL8367C_IOL_BACKOFF_OFFSET 12 +#define RTL8367C_IOL_BACKOFF_MASK 0x1000 +#define RTL8367C_BACKOFF_RANDOM_TIME_OFFSET 8 +#define RTL8367C_BACKOFF_RANDOM_TIME_MASK 0x100 +#define RTL8367C_DISABLE_BACK_OFF_OFFSET 4 +#define RTL8367C_DISABLE_BACK_OFF_MASK 0x10 +#define RTL8367C_IPG_COMPENSATION_OFFSET 0 +#define RTL8367C_IPG_COMPENSATION_MASK 0x1 + +#define RTL8367C_REG_SWITCH_MAC0 0x1209 + +#define RTL8367C_REG_SWITCH_MAC1 0x120a + +#define RTL8367C_REG_SWITCH_MAC2 0x120b + +#define RTL8367C_REG_SWITCH_CTRL0 0x120c +#define RTL8367C_REMARKING_DSCP_ENABLE_OFFSET 8 +#define RTL8367C_REMARKING_DSCP_ENABLE_MASK 0x100 +#define RTL8367C_SHORT_IPG_OFFSET 4 +#define RTL8367C_SHORT_IPG_MASK 0x10 +#define RTL8367C_PAUSE_MAX128_OFFSET 0 +#define RTL8367C_PAUSE_MAX128_MASK 0x1 + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 0x120d +#define RTL8367C_INTPRI1_DSCP_OFFSET 8 +#define RTL8367C_INTPRI1_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI0_DSCP_OFFSET 0 +#define RTL8367C_INTPRI0_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL1 0x120e +#define RTL8367C_INTPRI3_DSCP_OFFSET 8 +#define RTL8367C_INTPRI3_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI2_DSCP_OFFSET 0 +#define RTL8367C_INTPRI2_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL2 0x120f +#define RTL8367C_INTPRI5_DSCP_OFFSET 8 +#define RTL8367C_INTPRI5_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI4_DSCP_OFFSET 0 +#define RTL8367C_INTPRI4_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL3 0x1210 +#define RTL8367C_INTPRI7_DSCP_OFFSET 8 +#define RTL8367C_INTPRI7_DSCP_MASK 0x3F00 +#define RTL8367C_INTPRI6_DSCP_OFFSET 0 +#define RTL8367C_INTPRI6_DSCP_MASK 0x3F + +#define RTL8367C_REG_QOS_1Q_REMARK_CTRL0 0x1211 +#define RTL8367C_INTPRI3_PRI_OFFSET 12 +#define RTL8367C_INTPRI3_PRI_MASK 0x7000 +#define RTL8367C_INTPRI2_PRI_OFFSET 8 +#define RTL8367C_INTPRI2_PRI_MASK 0x700 +#define RTL8367C_INTPRI1_PRI_OFFSET 4 +#define RTL8367C_INTPRI1_PRI_MASK 0x70 +#define RTL8367C_INTPRI0_PRI_OFFSET 0 +#define RTL8367C_INTPRI0_PRI_MASK 0x7 + +#define RTL8367C_REG_QOS_1Q_REMARK_CTRL1 0x1212 +#define RTL8367C_INTPRI7_PRI_OFFSET 12 +#define RTL8367C_INTPRI7_PRI_MASK 0x7000 +#define RTL8367C_INTPRI6_PRI_OFFSET 8 +#define RTL8367C_INTPRI6_PRI_MASK 0x700 +#define RTL8367C_INTPRI5_PRI_OFFSET 4 +#define RTL8367C_INTPRI5_PRI_MASK 0x70 +#define RTL8367C_INTPRI4_PRI_OFFSET 0 +#define RTL8367C_INTPRI4_PRI_MASK 0x7 + +#define RTL8367C_REG_PKTGEN_COMMAND 0x1213 +#define RTL8367C_PKTGEN_STOP_OFFSET 8 +#define RTL8367C_PKTGEN_STOP_MASK 0x100 +#define RTL8367C_PKTGEN_START_OFFSET 4 +#define RTL8367C_PKTGEN_START_MASK 0x10 +#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_OFFSET 0 +#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_MASK 0x1 + +#define RTL8367C_REG_SW_DUMMY0 0x1214 +#define RTL8367C_SW_DUMMY0_DUMMY_OFFSET 4 +#define RTL8367C_SW_DUMMY0_DUMMY_MASK 0xFFF0 +#define RTL8367C_EEE_DEFER_TXLPI_OFFSET 3 +#define RTL8367C_EEE_DEFER_TXLPI_MASK 0x8 +#define RTL8367C_INGRESSBW_BYPASS_EN_OFFSET 2 +#define RTL8367C_INGRESSBW_BYPASS_EN_MASK 0x4 +#define RTL8367C_CFG_RX_MIN_OFFSET 0 +#define RTL8367C_CFG_RX_MIN_MASK 0x3 + +#define RTL8367C_REG_SW_DUMMY1 0x1215 + +#define RTL8367C_REG_PKTGEN_PAUSE_TIME 0x1216 + +#define RTL8367C_REG_SVLAN_UPLINK_PORTMASK 0x1218 +#define RTL8367C_SVLAN_UPLINK_PORTMASK_OFFSET 0 +#define RTL8367C_SVLAN_UPLINK_PORTMASK_MASK 0x7FF + +#define RTL8367C_REG_CPU_PORT_MASK 0x1219 +#define RTL8367C_CPU_PORT_MASK_OFFSET 0 +#define RTL8367C_CPU_PORT_MASK_MASK 0x7FF + +#define RTL8367C_REG_CPU_CTRL 0x121a +#define RTL8367C_CPU_TRAP_PORT_EXT_OFFSET 10 +#define RTL8367C_CPU_TRAP_PORT_EXT_MASK 0x400 +#define RTL8367C_CPU_TAG_FORMAT_OFFSET 9 +#define RTL8367C_CPU_TAG_FORMAT_MASK 0x200 +#define RTL8367C_IOL_16DROP_OFFSET 8 +#define RTL8367C_IOL_16DROP_MASK 0x100 +#define RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET 7 +#define RTL8367C_CPU_TAG_RXBYTECOUNT_MASK 0x80 +#define RTL8367C_CPU_TAG_POSITION_OFFSET 6 +#define RTL8367C_CPU_TAG_POSITION_MASK 0x40 +#define RTL8367C_CPU_TRAP_PORT_OFFSET 3 +#define RTL8367C_CPU_TRAP_PORT_MASK 0x38 +#define RTL8367C_CPU_INSERTMODE_OFFSET 1 +#define RTL8367C_CPU_INSERTMODE_MASK 0x6 +#define RTL8367C_CPU_EN_OFFSET 0 +#define RTL8367C_CPU_EN_MASK 0x1 + +#define RTL8367C_REG_MIRROR_CTRL 0x121c +#define RTL8367C_MIRROR_CTRL_DUMMY_OFFSET 12 +#define RTL8367C_MIRROR_CTRL_DUMMY_MASK 0xF000 +#define RTL8367C_MIRROR_ISO_OFFSET 11 +#define RTL8367C_MIRROR_ISO_MASK 0x800 +#define RTL8367C_MIRROR_TX_OFFSET 10 +#define RTL8367C_MIRROR_TX_MASK 0x400 +#define RTL8367C_MIRROR_RX_OFFSET 9 +#define RTL8367C_MIRROR_RX_MASK 0x200 +#define RTL8367C_MIRROR_MONITOR_PORT_OFFSET 4 +#define RTL8367C_MIRROR_MONITOR_PORT_MASK 0xF0 +#define RTL8367C_MIRROR_SOURCE_PORT_OFFSET 0 +#define RTL8367C_MIRROR_SOURCE_PORT_MASK 0xF + +#define RTL8367C_REG_FLOWCTRL_CTRL0 0x121d +#define RTL8367C_FLOWCTRL_TYPE_OFFSET 15 +#define RTL8367C_FLOWCTRL_TYPE_MASK 0x8000 +#define RTL8367C_DROP_ALL_THRESHOLD_OFFSET 5 +#define RTL8367C_DROP_ALL_THRESHOLD_MASK 0x7FE0 +#define RTL8367C_DROP_ALL_THRESHOLD_MSB_OFFSET 4 +#define RTL8367C_DROP_ALL_THRESHOLD_MSB_MASK 0x10 +#define RTL8367C_ITFSP_REG_OFFSET 0 +#define RTL8367C_ITFSP_REG_MASK 0x7 + +#define RTL8367C_REG_FLOWCTRL_ALL_ON 0x121e +#define RTL8367C_CFG_RLDPACT_OFFSET 12 +#define RTL8367C_CFG_RLDPACT_MASK 0x1000 +#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_OFFSET 0 +#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SYS_ON 0x121f +#define RTL8367C_FLOWCTRL_SYS_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_SYS_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SYS_OFF 0x1220 +#define RTL8367C_FLOWCTRL_SYS_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_SYS_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SHARE_ON 0x1221 +#define RTL8367C_FLOWCTRL_SHARE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_SHARE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_SHARE_OFF 0x1222 +#define RTL8367C_FLOWCTRL_SHARE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_SHARE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON 0x1223 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF 0x1224 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON 0x1225 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF 0x1226 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_ON 0x1227 +#define RTL8367C_FLOWCTRL_PORT_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_OFF 0x1228 +#define RTL8367C_FLOWCTRL_PORT_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON 0x1229 +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF 0x122a +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK 0x7FF + +#define RTL8367C_REG_RRCP_CTRL0 0x122b +#define RTL8367C_COL_SEL_OFFSET 14 +#define RTL8367C_COL_SEL_MASK 0x4000 +#define RTL8367C_CRS_SEL_OFFSET 13 +#define RTL8367C_CRS_SEL_MASK 0x2000 +#define RTL8367C_RRCP_PBVLAN_EN_OFFSET 11 +#define RTL8367C_RRCP_PBVLAN_EN_MASK 0x800 +#define RTL8367C_RRCPV3_SECURITY_CRC_OFFSET 10 +#define RTL8367C_RRCPV3_SECURITY_CRC_MASK 0x400 +#define RTL8367C_RRCPV3_HANDLE_OFFSET 8 +#define RTL8367C_RRCPV3_HANDLE_MASK 0x300 +#define RTL8367C_RRCPV1_MALFORMED_ACT_OFFSET 5 +#define RTL8367C_RRCPV1_MALFORMED_ACT_MASK 0x60 +#define RTL8367C_RRCP_VLANLEAKY_OFFSET 4 +#define RTL8367C_RRCP_VLANLEAKY_MASK 0x10 +#define RTL8367C_RRCPV1_SECURITY_CRC_GET_OFFSET 3 +#define RTL8367C_RRCPV1_SECURITY_CRC_GET_MASK 0x8 +#define RTL8367C_RRCPV1_SECURITY_CRC_SET_OFFSET 2 +#define RTL8367C_RRCPV1_SECURITY_CRC_SET_MASK 0x4 +#define RTL8367C_RRCPV1_HANDLE_OFFSET 1 +#define RTL8367C_RRCPV1_HANDLE_MASK 0x2 +#define RTL8367C_RRCP_ENABLE_OFFSET 0 +#define RTL8367C_RRCP_ENABLE_MASK 0x1 + +#define RTL8367C_REG_RRCP_CTRL1 0x122c +#define RTL8367C_RRCP_ADMIN_PMSK_OFFSET 8 +#define RTL8367C_RRCP_ADMIN_PMSK_MASK 0xFF00 +#define RTL8367C_RRCP_AUTH_PMSK_OFFSET 0 +#define RTL8367C_RRCP_AUTH_PMSK_MASK 0xFF + +#define RTL8367C_REG_RRCP_CTRL2 0x122d +#define RTL8367C_RRCPV1_HELLOFWD_TAG_OFFSET 9 +#define RTL8367C_RRCPV1_HELLOFWD_TAG_MASK 0x600 +#define RTL8367C_RRCP_FWD_TAG_OFFSET 7 +#define RTL8367C_RRCP_FWD_TAG_MASK 0x180 +#define RTL8367C_RRCPV1_REPLY_TAG_OFFSET 6 +#define RTL8367C_RRCPV1_REPLY_TAG_MASK 0x40 +#define RTL8367C_RRCPV1_HELLO_COUNT_OFFSET 3 +#define RTL8367C_RRCPV1_HELLO_COUNT_MASK 0x38 +#define RTL8367C_RRCPV1_HELLO_PEDIOD_OFFSET 0 +#define RTL8367C_RRCPV1_HELLO_PEDIOD_MASK 0x3 + +#define RTL8367C_REG_RRCP_CTRL3 0x122e +#define RTL8367C_RRCP_TAG_PRIORITY_OFFSET 13 +#define RTL8367C_RRCP_TAG_PRIORITY_MASK 0xE000 +#define RTL8367C_RRCP_TAG_VID_OFFSET 0 +#define RTL8367C_RRCP_TAG_VID_MASK 0xFFF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON 0x122f +#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF 0x1230 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON 0x1231 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF 0x1232 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON 0x1233 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF 0x1234 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON 0x1235 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF 0x1236 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON 0x1237 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF 0x1238 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON 0x1239 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF 0x123a +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_OFFSET 0 +#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_JUMBO_SIZE 0x123b +#define RTL8367C_JUMBO_MODE_OFFSET 2 +#define RTL8367C_JUMBO_MODE_MASK 0x4 +#define RTL8367C_JUMBO_SIZE_OFFSET 0 +#define RTL8367C_JUMBO_SIZE_MASK 0x3 + +#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER 0x124c +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER 0x124d +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX 0x124e +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX 0x124f +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER 0x1250 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_COUNTER 0x1251 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_COUNTER 0x1252 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_COUNTER 0x1253 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_COUNTER 0x1254 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_COUNTER 0x1255 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_COUNTER 0x1256 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_COUNTER 0x1257 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER 0x1258 +#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER 0x1259 +#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER 0x125a +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER 0x125b +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX 0x1260 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_MAX 0x1261 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_MAX 0x1262 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_MAX 0x1263 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_MAX 0x1264 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_MAX 0x1265 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_MAX 0x1266 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_MAX 0x1267 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PAGE_COUNT_CLEAR 0x1268 +#define RTL8367C_DIS_SKIP_FP_OFFSET 1 +#define RTL8367C_DIS_SKIP_FP_MASK 0x2 +#define RTL8367C_PAGE_COUNT_CLEAR_OFFSET 0 +#define RTL8367C_PAGE_COUNT_CLEAR_MASK 0x1 + +#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_MAX 0x1269 +#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_MAX 0x126a +#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_MAX 0x126b +#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER 0x126c +#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_COUNTER 0x126d +#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_COUNTER 0x126e +#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_OFFSET 0 +#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_MASK 0x7FF + +#define RTL8367C_REG_RRCP_CTRL1_H 0x126f +#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_OFFSET 3 +#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_MASK 0x38 +#define RTL8367C_RRCP_AUTH_PMSK_P10_8_OFFSET 0 +#define RTL8367C_RRCP_AUTH_PMSK_P10_8_MASK 0x7 + +#define RTL8367C_REG_EMA_CTRL0 0x1270 +#define RTL8367C_CFG_DVSE_VIAROM_OFFSET 13 +#define RTL8367C_CFG_DVSE_VIAROM_MASK 0x2000 +#define RTL8367C_CFG_DVSE_MIBRAM_OFFSET 12 +#define RTL8367C_CFG_DVSE_MIBRAM_MASK 0x1000 +#define RTL8367C_CFG_DVSE_IROM_OFFSET 11 +#define RTL8367C_CFG_DVSE_IROM_MASK 0x800 +#define RTL8367C_CFG_DVSE_ERAM_OFFSET 10 +#define RTL8367C_CFG_DVSE_ERAM_MASK 0x400 +#define RTL8367C_CFG_DVSE_IRAM_OFFSET 9 +#define RTL8367C_CFG_DVSE_IRAM_MASK 0x200 +#define RTL8367C_CFG_DVSE_NICRAM_OFFSET 8 +#define RTL8367C_CFG_DVSE_NICRAM_MASK 0x100 +#define RTL8367C_CFG_DVSE_CVLANRAM_OFFSET 7 +#define RTL8367C_CFG_DVSE_CVLANRAM_MASK 0x80 +#define RTL8367C_CFG_DVSE_ACTRAM_OFFSET 6 +#define RTL8367C_CFG_DVSE_ACTRAM_MASK 0x40 +#define RTL8367C_CFG_DVSE_INQRAM_OFFSET 5 +#define RTL8367C_CFG_DVSE_INQRAM_MASK 0x20 +#define RTL8367C_CFG_DVSE_HSARAM_OFFSET 4 +#define RTL8367C_CFG_DVSE_HSARAM_MASK 0x10 +#define RTL8367C_CFG_DVSE_OUTQRAM_OFFSET 3 +#define RTL8367C_CFG_DVSE_OUTQRAM_MASK 0x8 +#define RTL8367C_CFG_DVSE_HTRAM_OFFSET 2 +#define RTL8367C_CFG_DVSE_HTRAM_MASK 0x4 +#define RTL8367C_CFG_DVSE_PBRAM_OFFSET 1 +#define RTL8367C_CFG_DVSE_PBRAM_MASK 0x2 +#define RTL8367C_CFG_DVSE_L2RAM_OFFSET 0 +#define RTL8367C_CFG_DVSE_L2RAM_MASK 0x1 + +#define RTL8367C_REG_EMA_CTRL1 0x1271 +#define RTL8367C_CFG_DVS_OUTQRAM_OFFSET 12 +#define RTL8367C_CFG_DVS_OUTQRAM_MASK 0xF000 +#define RTL8367C_CFG_DVS_HTRAM_OFFSET 8 +#define RTL8367C_CFG_DVS_HTRAM_MASK 0x700 +#define RTL8367C_CFG_DVS_PBRAM_OFFSET 4 +#define RTL8367C_CFG_DVS_PBRAM_MASK 0xF0 +#define RTL8367C_CFG_DVS_L2RAM_OFFSET 0 +#define RTL8367C_CFG_DVS_L2RAM_MASK 0xF + +#define RTL8367C_REG_EMA_CTRL2 0x1272 +#define RTL8367C_CFG_DVS_CVLANRAM_OFFSET 12 +#define RTL8367C_CFG_DVS_CVLANRAM_MASK 0xF000 +#define RTL8367C_CFG_DVS_ACTRAM_OFFSET 8 +#define RTL8367C_CFG_DVS_ACTRAM_MASK 0xF00 +#define RTL8367C_CFG_DVS_INQRAM_OFFSET 4 +#define RTL8367C_CFG_DVS_INQRAM_MASK 0xF0 +#define RTL8367C_CFG_DVS_HSARAM_OFFSET 0 +#define RTL8367C_CFG_DVS_HSARAM_MASK 0xF + +#define RTL8367C_REG_EMA_CTRL3 0x1273 +#define RTL8367C_CFG_DVS_IROM_OFFSET 12 +#define RTL8367C_CFG_DVS_IROM_MASK 0xF000 +#define RTL8367C_CFG_DVS_ERAM_OFFSET 8 +#define RTL8367C_CFG_DVS_ERAM_MASK 0xF00 +#define RTL8367C_CFG_DVS_IRAM_OFFSET 4 +#define RTL8367C_CFG_DVS_IRAM_MASK 0xF0 +#define RTL8367C_CFG_DVS_NICRAM_OFFSET 0 +#define RTL8367C_CFG_DVS_NICRAM_MASK 0xF + +#define RTL8367C_REG_EMA_CTRL4 0x1274 +#define RTL8367C_CFG_DVS_VIAROM_OFFSET 4 +#define RTL8367C_CFG_DVS_VIAROM_MASK 0xF0 +#define RTL8367C_CFG_DVS_MIBRAM_OFFSET 0 +#define RTL8367C_CFG_DVS_MIBRAM_MASK 0xF + +#define RTL8367C_REG_DIAG_MODE 0x1275 +#define RTL8367C_DIAG_MODE_OFFSET 0 +#define RTL8367C_DIAG_MODE_MASK 0x1F + +#define RTL8367C_REG_BIST_MODE 0x1276 + +#define RTL8367C_REG_STS_BIST_DONE 0x1277 + +#define RTL8367C_REG_STS_BIST_RLT0 0x1278 +#define RTL8367C_STS_BIST_RLT0_OFFSET 0 +#define RTL8367C_STS_BIST_RLT0_MASK 0x1 + +#define RTL8367C_REG_STS_BIST_RLT1 0x1279 + +#define RTL8367C_REG_STS_BIST_RLT2 0x127a + +#define RTL8367C_REG_STS_BIST_RLT3 0x127b +#define RTL8367C_STS_BIST_RLT3_OFFSET 0 +#define RTL8367C_STS_BIST_RLT3_MASK 0x3FF + +#define RTL8367C_REG_STS_BIST_RLT4 0x127c +#define RTL8367C_STS_BIST_RLT4_OFFSET 0 +#define RTL8367C_STS_BIST_RLT4_MASK 0x7 + +#define RTL8367C_REG_VIAROM_MISR 0x127d + +#define RTL8367C_REG_DRF_BIST_MODE 0x1280 +#define RTL8367C_DRF_TCAMDEL_OFFSET 15 +#define RTL8367C_DRF_TCAMDEL_MASK 0x8000 +#define RTL8367C_CFG_DRF_BIST_MODE_OFFSET 0 +#define RTL8367C_CFG_DRF_BIST_MODE_MASK 0x7FFF + +#define RTL8367C_REG_STS_DRF_BIST 0x1281 +#define RTL8367C_STS_DRF_BIST_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_MASK 0x7FFF + +#define RTL8367C_REG_STS_DRF_BIST_RLT0 0x1282 +#define RTL8367C_STS_DRF_BIST_RLT0_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_RLT0_MASK 0x1 + +#define RTL8367C_REG_STS_DRF_BIST_RLT1 0x1283 + +#define RTL8367C_REG_STS_DRF_BIST_RLT2 0x1284 + +#define RTL8367C_REG_STS_DRF_BIST_RLT3 0x1285 +#define RTL8367C_STS_DRF_BIST_RLT3_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_RLT3_MASK 0x3FF + +#define RTL8367C_REG_STS_DRF_BIST_RLT4 0x1286 +#define RTL8367C_STS_DRF_BIST_RLT4_OFFSET 0 +#define RTL8367C_STS_DRF_BIST_RLT4_MASK 0x7FFF + +#define RTL8367C_REG_RAM_DRF_CTRL 0x1289 +#define RTL8367C_RAM_DRF_CTRL_OFFSET 0 +#define RTL8367C_RAM_DRF_CTRL_MASK 0x1 + +#define RTL8367C_REG_MIB_RMON_LEN_CTRL 0x128a +#define RTL8367C_RX_LENGTH_CTRL_OFFSET 1 +#define RTL8367C_RX_LENGTH_CTRL_MASK 0x2 +#define RTL8367C_TX_LENGTH_CTRL_OFFSET 0 +#define RTL8367C_TX_LENGTH_CTRL_MASK 0x1 + +#define RTL8367C_REG_COND0_BISR_OUT0 0x1290 + +#define RTL8367C_REG_COND0_BISR_OUT1 0x1291 + +#define RTL8367C_REG_COND0_BISR_OUT2 0x1292 + +#define RTL8367C_REG_COND0_BISR_OUT3 0x1293 + +#define RTL8367C_REG_COND0_BISR_OUT4 0x1294 +#define RTL8367C_COND0_BISR_OUT4_OFFSET 0 +#define RTL8367C_COND0_BISR_OUT4_MASK 0x3F + +#define RTL8367C_REG_COND0_BISR_OUT5 0x1295 +#define RTL8367C_COND0_BISR_OUT5_OFFSET 0 +#define RTL8367C_COND0_BISR_OUT5_MASK 0x7 + +#define RTL8367C_REG_CHG_DUPLEX_CFG 0x1296 +#define RTL8367C_CHG_COL_CNT_PORT_OFFSET 13 +#define RTL8367C_CHG_COL_CNT_PORT_MASK 0xE000 +#define RTL8367C_CHG_COL_CNT_OFFSET 8 +#define RTL8367C_CHG_COL_CNT_MASK 0x1F00 +#define RTL8367C_CFG_CHG_DUP_EN_OFFSET 7 +#define RTL8367C_CFG_CHG_DUP_EN_MASK 0x80 +#define RTL8367C_CFG_CHG_DUP_THR_OFFSET 2 +#define RTL8367C_CFG_CHG_DUP_THR_MASK 0x7C +#define RTL8367C_CFG_CHG_DUP_CONGEST_OFFSET 1 +#define RTL8367C_CFG_CHG_DUP_CONGEST_MASK 0x2 +#define RTL8367C_CFG_CHG_DUP_REF_OFFSET 0 +#define RTL8367C_CFG_CHG_DUP_REF_MASK 0x1 + +#define RTL8367C_REG_COND0_BIST_PASS 0x1297 +#define RTL8367C_COND0_DRF_BIST_NOFAIL_OFFSET 1 +#define RTL8367C_COND0_DRF_BIST_NOFAIL_MASK 0x2 +#define RTL8367C_COND0_BIST_NOFAIL_OFFSET 0 +#define RTL8367C_COND0_BIST_NOFAIL_MASK 0x1 + +#define RTL8367C_REG_COND1_BISR_OUT0 0x1298 + +#define RTL8367C_REG_COND1_BISR_OUT1 0x1299 + +#define RTL8367C_REG_COND1_BISR_OUT2 0x129a + +#define RTL8367C_REG_COND1_BISR_OUT3 0x129b + +#define RTL8367C_REG_COND1_BISR_OUT4 0x129c +#define RTL8367C_COND1_BISR_OUT4_OFFSET 0 +#define RTL8367C_COND1_BISR_OUT4_MASK 0x3F + +#define RTL8367C_REG_COND1_BISR_OUT5 0x129d +#define RTL8367C_COND1_BISR_OUT5_OFFSET 0 +#define RTL8367C_COND1_BISR_OUT5_MASK 0x7 + +#define RTL8367C_REG_COND1_BIST_PASS 0x129f +#define RTL8367C_COND1_DRF_BIST_NOFAIL_OFFSET 1 +#define RTL8367C_COND1_DRF_BIST_NOFAIL_MASK 0x2 +#define RTL8367C_COND1_BIST_NOFAIL_OFFSET 0 +#define RTL8367C_COND1_BIST_NOFAIL_MASK 0x1 + +#define RTL8367C_REG_EEE_TX_THR_Giga_500M 0x12a0 + +#define RTL8367C_REG_EEE_TX_THR_FE 0x12a1 + +#define RTL8367C_REG_EEE_MISC 0x12a3 +#define RTL8367C_EEE_REQ_SET1_OFFSET 13 +#define RTL8367C_EEE_REQ_SET1_MASK 0x2000 +#define RTL8367C_EEE_REQ_SET0_OFFSET 12 +#define RTL8367C_EEE_REQ_SET0_MASK 0x1000 +#define RTL8367C_EEE_WAKE_SET1_OFFSET 9 +#define RTL8367C_EEE_WAKE_SET1_MASK 0x200 +#define RTL8367C_EEE_Wake_SET0_OFFSET 8 +#define RTL8367C_EEE_Wake_SET0_MASK 0x100 +#define RTL8367C_EEE_TU_GIGA_500M_OFFSET 4 +#define RTL8367C_EEE_TU_GIGA_500M_MASK 0x30 +#define RTL8367C_EEE_TU_100M_OFFSET 2 +#define RTL8367C_EEE_TU_100M_MASK 0xC + +#define RTL8367C_REG_EEE_GIGA_CTRL0 0x12a4 +#define RTL8367C_EEE_TW_GIGA_OFFSET 8 +#define RTL8367C_EEE_TW_GIGA_MASK 0xFF00 +#define RTL8367C_EEE_TR_GIGA_500M_OFFSET 0 +#define RTL8367C_EEE_TR_GIGA_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_GIGA_CTRL1 0x12a5 +#define RTL8367C_EEE_TD_GIGA_500M_OFFSET 8 +#define RTL8367C_EEE_TD_GIGA_500M_MASK 0xFF00 +#define RTL8367C_EEE_TP_GIGA_OFFSET 0 +#define RTL8367C_EEE_TP_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEE_100M_CTRL0 0x12a6 +#define RTL8367C_EEE_TW_100M_OFFSET 8 +#define RTL8367C_EEE_TW_100M_MASK 0xFF00 +#define RTL8367C_EEE_TR_100M_OFFSET 0 +#define RTL8367C_EEE_TR_100M_MASK 0xFF + +#define RTL8367C_REG_EEE_100M_CTRL1 0x12a7 +#define RTL8367C_EEE_TD_100M_OFFSET 8 +#define RTL8367C_EEE_TD_100M_MASK 0xFF00 +#define RTL8367C_EEE_TP_100M_OFFSET 0 +#define RTL8367C_EEE_TP_100M_MASK 0xFF + +#define RTL8367C_REG_RX_FC_REG 0x12aa +#define RTL8367C_EN_EEE_HALF_DUP_OFFSET 8 +#define RTL8367C_EN_EEE_HALF_DUP_MASK 0x100 +#define RTL8367C_RX_PGCNT_OFFSET 0 +#define RTL8367C_RX_PGCNT_MASK 0xFF + +#define RTL8367C_REG_MAX_FIFO_SIZE 0x12af +#define RTL8367C_MAX_FIFO_SIZE_OFFSET 0 +#define RTL8367C_MAX_FIFO_SIZE_MASK 0xF + +#define RTL8367C_REG_EEEP_RX_RATE_GIGA 0x12b0 + +#define RTL8367C_REG_EEEP_RX_RATE_100M 0x12b1 + +#define RTL8367C_REG_DUMMY_REG_12_2 0x12b2 + +#define RTL8367C_REG_EEEP_TX_RATE_GIGA 0x12b3 + +#define RTL8367C_REG_EEEP_TX_RATE_100M 0x12b4 + +#define RTL8367C_REG_DUMMY_REG_12_3 0x12b5 + +#define RTL8367C_REG_EEEP_GIGA_CTRL0 0x12b6 +#define RTL8367C_EEEP_TR_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TR_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_RW_GIGA_MST_OFFSET 0 +#define RTL8367C_EEEP_RW_GIGA_MST_MASK 0xFF + +#define RTL8367C_REG_EEEP_GIGA_CTRL1 0x12b7 +#define RTL8367C_EEEP_TW_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TW_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_TP_GIGA_OFFSET 0 +#define RTL8367C_EEEP_TP_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEEP_GIGA_CTRL2 0x12b8 +#define RTL8367C_EEEP_TXEN_GIGA_OFFSET 12 +#define RTL8367C_EEEP_TXEN_GIGA_MASK 0x1000 +#define RTL8367C_EEEP_TU_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TU_GIGA_MASK 0x300 +#define RTL8367C_EEEP_TS_GIGA_OFFSET 0 +#define RTL8367C_EEEP_TS_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEEP_100M_CTRL0 0x12b9 +#define RTL8367C_EEEP_TR_100M_OFFSET 8 +#define RTL8367C_EEEP_TR_100M_MASK 0xFF00 +#define RTL8367C_EEEP_RW_100M_OFFSET 0 +#define RTL8367C_EEEP_RW_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_100M_CTRL1 0x12ba +#define RTL8367C_EEEP_TW_100M_OFFSET 8 +#define RTL8367C_EEEP_TW_100M_MASK 0xFF00 +#define RTL8367C_EEEP_TP_100M_OFFSET 0 +#define RTL8367C_EEEP_TP_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_100M_CTRL2 0x12bb +#define RTL8367C_EEEP_TXEN_100M_OFFSET 12 +#define RTL8367C_EEEP_TXEN_100M_MASK 0x1000 +#define RTL8367C_EEEP_TU_100M_OFFSET 8 +#define RTL8367C_EEEP_TU_100M_MASK 0x300 +#define RTL8367C_EEEP_TS_100M_OFFSET 0 +#define RTL8367C_EEEP_TS_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_CTRL0 0x12bc +#define RTL8367C_EEEP_CTRL0_DUMMY_OFFSET 8 +#define RTL8367C_EEEP_CTRL0_DUMMY_MASK 0xFF00 +#define RTL8367C_EEEP_SLEEP_STEP_OFFSET 0 +#define RTL8367C_EEEP_SLEEP_STEP_MASK 0xFF + +#define RTL8367C_REG_EEEP_CTRL1 0x12bd +#define RTL8367C_EEEP_TXR_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TXR_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_TXR_100M_OFFSET 0 +#define RTL8367C_EEEP_TXR_100M_MASK 0xFF + +#define RTL8367C_REG_BACK_PRESSURE_IPG 0x12be +#define RTL8367C_BACK_PRESSURE_IPG_OFFSET 0 +#define RTL8367C_BACK_PRESSURE_IPG_MASK 0x3 + +#define RTL8367C_REG_TX_ESD_LEVEL 0x12bf +#define RTL8367C_TX_ESD_LEVEL_MODE_OFFSET 8 +#define RTL8367C_TX_ESD_LEVEL_MODE_MASK 0x100 +#define RTL8367C_LEVEL_OFFSET 0 +#define RTL8367C_LEVEL_MASK 0xFF + +#define RTL8367C_REG_RRCP_CTRL4 0x12e0 + +#define RTL8367C_REG_RRCP_CTRL5 0x12e1 + +#define RTL8367C_REG_RRCP_CTRL6 0x12e2 + +#define RTL8367C_REG_RRCP_CTRL7 0x12e3 + +#define RTL8367C_REG_RRCP_CTRL8 0x12e4 + +#define RTL8367C_REG_RRCP_CTRL9 0x12e5 + +#define RTL8367C_REG_RRCP_CTRL10 0x12e6 + +#define RTL8367C_REG_FIELD_SELECTOR0 0x12e7 +#define RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR0_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR0_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR1 0x12e8 +#define RTL8367C_FIELD_SELECTOR1_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR1_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR1_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR1_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR2 0x12e9 +#define RTL8367C_FIELD_SELECTOR2_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR2_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR2_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR2_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR3 0x12ea +#define RTL8367C_FIELD_SELECTOR3_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR3_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR3_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR3_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR4 0x12eb +#define RTL8367C_FIELD_SELECTOR4_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR4_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR4_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR4_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR5 0x12ec +#define RTL8367C_FIELD_SELECTOR5_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR5_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR5_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR5_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR6 0x12ed +#define RTL8367C_FIELD_SELECTOR6_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR6_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR6_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR6_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR7 0x12ee +#define RTL8367C_FIELD_SELECTOR7_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR7_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR7_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR7_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR8 0x12ef +#define RTL8367C_FIELD_SELECTOR8_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR8_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR8_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR8_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR9 0x12f0 +#define RTL8367C_FIELD_SELECTOR9_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR9_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR9_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR9_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR10 0x12f1 +#define RTL8367C_FIELD_SELECTOR10_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR10_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR10_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR10_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR11 0x12f2 +#define RTL8367C_FIELD_SELECTOR11_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR11_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR11_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR11_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR12 0x12f3 +#define RTL8367C_FIELD_SELECTOR12_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR12_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR12_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR12_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR13 0x12f4 +#define RTL8367C_FIELD_SELECTOR13_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR13_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR13_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR13_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR14 0x12f5 +#define RTL8367C_FIELD_SELECTOR14_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR14_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR14_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR14_OFFSET_MASK 0xFF + +#define RTL8367C_REG_FIELD_SELECTOR15 0x12f6 +#define RTL8367C_FIELD_SELECTOR15_FORMAT_OFFSET 8 +#define RTL8367C_FIELD_SELECTOR15_FORMAT_MASK 0x700 +#define RTL8367C_FIELD_SELECTOR15_OFFSET_OFFSET 0 +#define RTL8367C_FIELD_SELECTOR15_OFFSET_MASK 0xFF + +#define RTL8367C_REG_HWPKT_GEN_MISC_H 0x12f7 +#define RTL8367C_PKT_GEN_SUSPEND_P10_8_OFFSET 3 +#define RTL8367C_PKT_GEN_SUSPEND_P10_8_MASK 0x38 +#define RTL8367C_PKT_GEN_STATUS_P10_8_OFFSET 0 +#define RTL8367C_PKT_GEN_STATUS_P10_8_MASK 0x7 + +#define RTL8367C_REG_MIRROR_SRC_PMSK 0x12fb +#define RTL8367C_MIRROR_SRC_PMSK_OFFSET 0 +#define RTL8367C_MIRROR_SRC_PMSK_MASK 0x7FF + +#define RTL8367C_REG_EEE_BURSTSIZE 0x12fc + +#define RTL8367C_REG_EEE_IFG_CFG 0x12fd +#define RTL8367C_EEE_IFG_CFG_OFFSET 0 +#define RTL8367C_EEE_IFG_CFG_MASK 0x1 + +#define RTL8367C_REG_FPGA_VER_MAC 0x12fe + +#define RTL8367C_REG_HWPKT_GEN_MISC 0x12ff +#define RTL8367C_PKT_GEN_SUSPEND_OFFSET 8 +#define RTL8367C_PKT_GEN_SUSPEND_MASK 0xFF00 +#define RTL8367C_PKT_GEN_STATUS_OFFSET 0 +#define RTL8367C_PKT_GEN_STATUS_MASK 0xFF + +/* (16'h1300)chip_reg */ + +#define RTL8367C_REG_CHIP_NUMBER 0x1300 + +#define RTL8367C_REG_CHIP_VER 0x1301 +#define RTL8367C_VERID_OFFSET 12 +#define RTL8367C_VERID_MASK 0xF000 +#define RTL8367C_MCID_OFFSET 8 +#define RTL8367C_MCID_MASK 0xF00 +#define RTL8367C_MODEL_ID_OFFSET 4 +#define RTL8367C_MODEL_ID_MASK 0xF0 +#define RTL8367C_AFE_VERSION_OFFSET 0 +#define RTL8367C_AFE_VERSION_MASK 0x1 + +#define RTL8367C_REG_CHIP_DEBUG0 0x1303 +#define RTL8367C_SEL33_EXT2_OFFSET 10 +#define RTL8367C_SEL33_EXT2_MASK 0x400 +#define RTL8367C_SEL33_EXT1_OFFSET 9 +#define RTL8367C_SEL33_EXT1_MASK 0x200 +#define RTL8367C_SEL33_EXT0_OFFSET 8 +#define RTL8367C_SEL33_EXT0_MASK 0x100 +#define RTL8367C_DRI_OTHER_OFFSET 7 +#define RTL8367C_DRI_OTHER_MASK 0x80 +#define RTL8367C_DRI_EXT1_RG_OFFSET 6 +#define RTL8367C_DRI_EXT1_RG_MASK 0x40 +#define RTL8367C_DRI_EXT0_RG_OFFSET 5 +#define RTL8367C_DRI_EXT0_RG_MASK 0x20 +#define RTL8367C_DRI_EXT1_OFFSET 4 +#define RTL8367C_DRI_EXT1_MASK 0x10 +#define RTL8367C_DRI_EXT0_OFFSET 3 +#define RTL8367C_DRI_EXT0_MASK 0x8 +#define RTL8367C_SLR_OTHER_OFFSET 2 +#define RTL8367C_SLR_OTHER_MASK 0x4 +#define RTL8367C_SLR_EXT1_OFFSET 1 +#define RTL8367C_SLR_EXT1_MASK 0x2 +#define RTL8367C_SLR_EXT0_OFFSET 0 +#define RTL8367C_SLR_EXT0_MASK 0x1 + +#define RTL8367C_REG_CHIP_DEBUG1 0x1304 +#define RTL8367C_RG1_DN_OFFSET 12 +#define RTL8367C_RG1_DN_MASK 0x7000 +#define RTL8367C_RG1_DP_OFFSET 8 +#define RTL8367C_RG1_DP_MASK 0x700 +#define RTL8367C_RG0_DN_OFFSET 4 +#define RTL8367C_RG0_DN_MASK 0x70 +#define RTL8367C_RG0_DP_OFFSET 0 +#define RTL8367C_RG0_DP_MASK 0x7 + +#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT 0x1305 +#define RTL8367C_ORG_COL_OFFSET 15 +#define RTL8367C_ORG_COL_MASK 0x8000 +#define RTL8367C_ORG_CRS_OFFSET 14 +#define RTL8367C_ORG_CRS_MASK 0x4000 +#define RTL8367C_SKIP_MII_1_RXER_OFFSET 13 +#define RTL8367C_SKIP_MII_1_RXER_MASK 0x2000 +#define RTL8367C_SKIP_MII_0_RXER_OFFSET 12 +#define RTL8367C_SKIP_MII_0_RXER_MASK 0x1000 +#define RTL8367C_SELECT_GMII_1_OFFSET 4 +#define RTL8367C_SELECT_GMII_1_MASK 0xF0 +#define RTL8367C_SELECT_GMII_0_OFFSET 0 +#define RTL8367C_SELECT_GMII_0_MASK 0xF + +#define RTL8367C_REG_EXT0_RGMXF 0x1306 +#define RTL8367C_EXT0_RGTX_INV_OFFSET 6 +#define RTL8367C_EXT0_RGTX_INV_MASK 0x40 +#define RTL8367C_EXT0_RGRX_INV_OFFSET 5 +#define RTL8367C_EXT0_RGRX_INV_MASK 0x20 +#define RTL8367C_EXT0_RGMXF_OFFSET 0 +#define RTL8367C_EXT0_RGMXF_MASK 0x1F + +#define RTL8367C_REG_EXT1_RGMXF 0x1307 +#define RTL8367C_EXT1_RGTX_INV_OFFSET 6 +#define RTL8367C_EXT1_RGTX_INV_MASK 0x40 +#define RTL8367C_EXT1_RGRX_INV_OFFSET 5 +#define RTL8367C_EXT1_RGRX_INV_MASK 0x20 +#define RTL8367C_EXT1_RGMXF_OFFSET 0 +#define RTL8367C_EXT1_RGMXF_MASK 0x1F + +#define RTL8367C_REG_BISR_CTRL 0x1308 +#define RTL8367C_BISR_CTRL_OFFSET 0 +#define RTL8367C_BISR_CTRL_MASK 0x7 + +#define RTL8367C_REG_SLF_IF 0x1309 +#define RTL8367C_LINK_DOWN_CLR_FIFO_OFFSET 7 +#define RTL8367C_LINK_DOWN_CLR_FIFO_MASK 0x80 +#define RTL8367C_LOOPBACK_OFFSET 6 +#define RTL8367C_LOOPBACK_MASK 0x40 +#define RTL8367C_WATER_LEVEL_OFFSET 4 +#define RTL8367C_WATER_LEVEL_MASK 0x30 +#define RTL8367C_SLF_IF_OFFSET 0 +#define RTL8367C_SLF_IF_MASK 0x3 + +#define RTL8367C_REG_I2C_CLOCK_DIV 0x130a +#define RTL8367C_I2C_CLOCK_DIV_OFFSET 0 +#define RTL8367C_I2C_CLOCK_DIV_MASK 0x3FF + +#define RTL8367C_REG_MDX_MDC_DIV 0x130b +#define RTL8367C_MDX_MDC_DIV_OFFSET 0 +#define RTL8367C_MDX_MDC_DIV_MASK 0x3FF + +#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE0 0x130c +#define RTL8367C_ADCCKI_FROM_PAD_OFFSET 14 +#define RTL8367C_ADCCKI_FROM_PAD_MASK 0x4000 +#define RTL8367C_ADCCKI_EN_OFFSET 13 +#define RTL8367C_ADCCKI_EN_MASK 0x2000 +#define RTL8367C_FLASH_ENABLE_OFFSET 12 +#define RTL8367C_FLASH_ENABLE_MASK 0x1000 +#define RTL8367C_EEE_ENABLE_OFFSET 11 +#define RTL8367C_EEE_ENABLE_MASK 0x800 +#define RTL8367C_NIC_ENABLE_OFFSET 10 +#define RTL8367C_NIC_ENABLE_MASK 0x400 +#define RTL8367C_FT_ENABLE_OFFSET 9 +#define RTL8367C_FT_ENABLE_MASK 0x200 +#define RTL8367C_OLT_ENABLE_OFFSET 8 +#define RTL8367C_OLT_ENABLE_MASK 0x100 +#define RTL8367C_RTCT_EN_OFFSET 7 +#define RTL8367C_RTCT_EN_MASK 0x80 +#define RTL8367C_PON_LIGHT_EN_OFFSET 6 +#define RTL8367C_PON_LIGHT_EN_MASK 0x40 +#define RTL8367C_DW8051_EN_OFFSET 5 +#define RTL8367C_DW8051_EN_MASK 0x20 +#define RTL8367C_AUTOLOAD_EN_OFFSET 4 +#define RTL8367C_AUTOLOAD_EN_MASK 0x10 +#define RTL8367C_NRESTORE_EN_OFFSET 3 +#define RTL8367C_NRESTORE_EN_MASK 0x8 +#define RTL8367C_DIS_PON_TABLE_INIT_OFFSET 2 +#define RTL8367C_DIS_PON_TABLE_INIT_MASK 0x4 +#define RTL8367C_DIS_PON_BIST_OFFSET 1 +#define RTL8367C_DIS_PON_BIST_MASK 0x2 +#define RTL8367C_EFUSE_EN_OFFSET 0 +#define RTL8367C_EFUSE_EN_MASK 0x1 + +#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE1 0x130d +#define RTL8367C_EEPROM_DEV_ADR_OFFSET 8 +#define RTL8367C_EEPROM_DEV_ADR_MASK 0x7F00 +#define RTL8367C_EEPROM_MSB_OFFSET 7 +#define RTL8367C_EEPROM_MSB_MASK 0x80 +#define RTL8367C_EEPROM_ADDRESS_16B_OFFSET 6 +#define RTL8367C_EEPROM_ADDRESS_16B_MASK 0x40 +#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_OFFSET 3 +#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_MASK 0x8 +#define RTL8367C_SPI_SLAVE_EN_OFFSET 2 +#define RTL8367C_SPI_SLAVE_EN_MASK 0x4 +#define RTL8367C_SMI_SEL_OFFSET 0 +#define RTL8367C_SMI_SEL_MASK 0x3 + +#define RTL8367C_REG_PHY_AD 0x130f +#define RTL8367C_EN_PHY_MAX_POWER_OFFSET 14 +#define RTL8367C_EN_PHY_MAX_POWER_MASK 0x4000 +#define RTL8367C_EN_PHY_SEL_DEG_OFFSET 13 +#define RTL8367C_EN_PHY_SEL_DEG_MASK 0x2000 +#define RTL8367C_EXTPHY_AD_OFFSET 8 +#define RTL8367C_EXTPHY_AD_MASK 0x1F00 +#define RTL8367C_EN_PHY_LOW_POWER_MODE_OFFSET 7 +#define RTL8367C_EN_PHY_LOW_POWER_MODE_MASK 0x80 +#define RTL8367C_EN_PHY_GREEN_OFFSET 6 +#define RTL8367C_EN_PHY_GREEN_MASK 0x40 +#define RTL8367C_PDNPHY_OFFSET 5 +#define RTL8367C_PDNPHY_MASK 0x20 +#define RTL8367C_INTPHY_AD_OFFSET 0 +#define RTL8367C_INTPHY_AD_MASK 0x1F + +#define RTL8367C_REG_DIGITAL_INTERFACE0_FORCE 0x1310 +#define RTL8367C_GMII_0_FORCE_OFFSET 12 +#define RTL8367C_GMII_0_FORCE_MASK 0x1000 +#define RTL8367C_RGMII_0_FORCE_OFFSET 0 +#define RTL8367C_RGMII_0_FORCE_MASK 0xFFF + +#define RTL8367C_REG_DIGITAL_INTERFACE1_FORCE 0x1311 +#define RTL8367C_GMII_1_FORCE_OFFSET 12 +#define RTL8367C_GMII_1_FORCE_MASK 0x1000 +#define RTL8367C_RGMII_1_FORCE_OFFSET 0 +#define RTL8367C_RGMII_1_FORCE_MASK 0xFFF + +#define RTL8367C_REG_MAC0_FORCE_SELECT 0x1312 +#define RTL8367C_EN_MAC0_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC0_FORCE_MASK 0x1000 +#define RTL8367C_MAC0_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC0_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC1_FORCE_SELECT 0x1313 +#define RTL8367C_EN_MAC1_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC1_FORCE_MASK 0x1000 +#define RTL8367C_MAC1_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC1_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC2_FORCE_SELECT 0x1314 +#define RTL8367C_EN_MAC2_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC2_FORCE_MASK 0x1000 +#define RTL8367C_MAC2_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC2_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC3_FORCE_SELECT 0x1315 +#define RTL8367C_EN_MAC3_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC3_FORCE_MASK 0x1000 +#define RTL8367C_MAC3_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC3_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC4_FORCE_SELECT 0x1316 +#define RTL8367C_EN_MAC4_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC4_FORCE_MASK 0x1000 +#define RTL8367C_MAC4_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC4_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC5_FORCE_SELECT 0x1317 +#define RTL8367C_EN_MAC5_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC5_FORCE_MASK 0x1000 +#define RTL8367C_MAC5_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC5_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC6_FORCE_SELECT 0x1318 +#define RTL8367C_EN_MAC6_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC6_FORCE_MASK 0x1000 +#define RTL8367C_MAC6_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC6_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_MAC7_FORCE_SELECT 0x1319 +#define RTL8367C_EN_MAC7_FORCE_OFFSET 12 +#define RTL8367C_EN_MAC7_FORCE_MASK 0x1000 +#define RTL8367C_MAC7_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_MAC7_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_M10_FORCE_SELECT 0x131c +#define RTL8367C_EN_M10_FORCE_OFFSET 12 +#define RTL8367C_EN_M10_FORCE_MASK 0x1000 +#define RTL8367C_M10_FORCE_ABLTY_OFFSET 0 +#define RTL8367C_M10_FORCE_ABLTY_MASK 0xFFF + +#define RTL8367C_REG_CHIP_RESET 0x1322 +#define RTL8367C_GPHY_RESET_OFFSET 6 +#define RTL8367C_GPHY_RESET_MASK 0x40 +#define RTL8367C_NIC_RST_OFFSET 5 +#define RTL8367C_NIC_RST_MASK 0x20 +#define RTL8367C_DW8051_RST_OFFSET 4 +#define RTL8367C_DW8051_RST_MASK 0x10 +#define RTL8367C_SDS_RST_OFFSET 3 +#define RTL8367C_SDS_RST_MASK 0x8 +#define RTL8367C_CONFIG_RST_OFFSET 2 +#define RTL8367C_CONFIG_RST_MASK 0x4 +#define RTL8367C_SW_RST_OFFSET 1 +#define RTL8367C_SW_RST_MASK 0x2 +#define RTL8367C_CHIP_RST_OFFSET 0 +#define RTL8367C_CHIP_RST_MASK 0x1 + +#define RTL8367C_REG_DIGITAL_DEBUG_0 0x1323 + +#define RTL8367C_REG_DIGITAL_DEBUG_1 0x1324 + +#define RTL8367C_REG_INTERNAL_PHY_MDC_DRIVER 0x1325 +#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_OFFSET 0 +#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_MASK 0x3FF + +#define RTL8367C_REG_LINKDOWN_TIME_CTRL 0x1326 +#define RTL8367C_LINKDOWN_TIME_CFG_OFFSET 9 +#define RTL8367C_LINKDOWN_TIME_CFG_MASK 0x7E00 +#define RTL8367C_LINKDOWN_TIME_ENABLE_OFFSET 8 +#define RTL8367C_LINKDOWN_TIME_ENABLE_MASK 0x100 +#define RTL8367C_LINKDOWN_TIME_OFFSET 0 +#define RTL8367C_LINKDOWN_TIME_MASK 0xFF + +#define RTL8367C_REG_PHYACK_TIMEOUT 0x1331 + +#define RTL8367C_REG_MDXACK_TIMEOUT 0x1333 + +#define RTL8367C_REG_DW8051_RDY 0x1336 +#define RTL8367C_VIAROM_WRITE_EN_OFFSET 9 +#define RTL8367C_VIAROM_WRITE_EN_MASK 0x200 +#define RTL8367C_SPIF_CK2_OFFSET 8 +#define RTL8367C_SPIF_CK2_MASK 0x100 +#define RTL8367C_RRCP_MDOE_OFFSET 7 +#define RTL8367C_RRCP_MDOE_MASK 0x80 +#define RTL8367C_DW8051_RATE_OFFSET 4 +#define RTL8367C_DW8051_RATE_MASK 0x70 +#define RTL8367C_IROM_MSB_OFFSET 2 +#define RTL8367C_IROM_MSB_MASK 0xC +#define RTL8367C_ACS_IROM_ENABLE_OFFSET 1 +#define RTL8367C_ACS_IROM_ENABLE_MASK 0x2 +#define RTL8367C_DW8051_READY_OFFSET 0 +#define RTL8367C_DW8051_READY_MASK 0x1 + +#define RTL8367C_REG_BIST_CTRL 0x133c +#define RTL8367C_DRF_BIST_DONE_ALL_OFFSET 5 +#define RTL8367C_DRF_BIST_DONE_ALL_MASK 0x20 +#define RTL8367C_DRF_BIST_PAUSE_ALL_OFFSET 4 +#define RTL8367C_DRF_BIST_PAUSE_ALL_MASK 0x10 +#define RTL8367C_BIST_DOAN_ALL_OFFSET 3 +#define RTL8367C_BIST_DOAN_ALL_MASK 0x8 +#define RTL8367C_BIST_PASS_OFFSET 0 +#define RTL8367C_BIST_PASS_MASK 0x7 + +#define RTL8367C_REG_DIAG_MODE2 0x133d +#define RTL8367C_DIAG_MODE2_ACTRAM_OFFSET 1 +#define RTL8367C_DIAG_MODE2_ACTRAM_MASK 0x2 +#define RTL8367C_DIAG_MODE2_BCAM_ACTION_OFFSET 0 +#define RTL8367C_DIAG_MODE2_BCAM_ACTION_MASK 0x1 + +#define RTL8367C_REG_MDX_PHY_REG0 0x133e +#define RTL8367C_PHY_BRD_MASK_OFFSET 4 +#define RTL8367C_PHY_BRD_MASK_MASK 0x1F0 +#define RTL8367C_MDX_INDACC_PAGE_OFFSET 0 +#define RTL8367C_MDX_INDACC_PAGE_MASK 0xF + +#define RTL8367C_REG_MDX_PHY_REG1 0x133f +#define RTL8367C_PHY_BRD_MODE_OFFSET 5 +#define RTL8367C_PHY_BRD_MODE_MASK 0x20 +#define RTL8367C_BRD_PHYAD_OFFSET 0 +#define RTL8367C_BRD_PHYAD_MASK 0x1F + +#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_SW 0x1340 + +#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_B 0x1341 +#define RTL8367C_DEBUG_MX_OFFSET 9 +#define RTL8367C_DEBUG_MX_MASK 0xE00 +#define RTL8367C_DEBUG_SHIFT_MISC_OFFSET 6 +#define RTL8367C_DEBUG_SHIFT_MISC_MASK 0x1C0 +#define RTL8367C_DEBUG_SHIFT_SW_OFFSET 3 +#define RTL8367C_DEBUG_SHIFT_SW_MASK 0x38 +#define RTL8367C_DEBUG_SHIFT_GPHY_OFFSET 0 +#define RTL8367C_DEBUG_SHIFT_GPHY_MASK 0x7 + +#define RTL8367C_REG_DEBUG_SIGNAL_I 0x1343 + +#define RTL8367C_REG_DEBUG_SIGNAL_H 0x1344 + +#define RTL8367C_REG_DBGO_SEL_GPHY 0x1345 + +#define RTL8367C_REG_DBGO_SEL_MISC 0x1346 + +#define RTL8367C_REG_BYPASS_ABLTY_LOCK 0x1349 +#define RTL8367C_BYPASS_ABLTY_LOCK_OFFSET 0 +#define RTL8367C_BYPASS_ABLTY_LOCK_MASK 0xFF + +#define RTL8367C_REG_BYPASS_ABLTY_LOCK_EXT 0x134a +#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_OFFSET 3 +#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_MASK 0x8 +#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_OFFSET 0 +#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_MASK 0x7 + +#define RTL8367C_REG_ACL_GPIO 0x134f +#define RTL8367C_ACL_GPIO_13_OFFSET 13 +#define RTL8367C_ACL_GPIO_13_MASK 0x2000 +#define RTL8367C_ACL_GPIO_12_OFFSET 12 +#define RTL8367C_ACL_GPIO_12_MASK 0x1000 +#define RTL8367C_ACL_GPIO_11_OFFSET 11 +#define RTL8367C_ACL_GPIO_11_MASK 0x800 +#define RTL8367C_ACL_GPIO_10_OFFSET 10 +#define RTL8367C_ACL_GPIO_10_MASK 0x400 +#define RTL8367C_ACL_GPIO_9_OFFSET 9 +#define RTL8367C_ACL_GPIO_9_MASK 0x200 +#define RTL8367C_ACL_GPIO_8_OFFSET 8 +#define RTL8367C_ACL_GPIO_8_MASK 0x100 +#define RTL8367C_ACL_GPIO_7_OFFSET 7 +#define RTL8367C_ACL_GPIO_7_MASK 0x80 +#define RTL8367C_ACL_GPIO_6_OFFSET 6 +#define RTL8367C_ACL_GPIO_6_MASK 0x40 +#define RTL8367C_ACL_GPIO_5_OFFSET 5 +#define RTL8367C_ACL_GPIO_5_MASK 0x20 +#define RTL8367C_ACL_GPIO_4_OFFSET 4 +#define RTL8367C_ACL_GPIO_4_MASK 0x10 +#define RTL8367C_ACL_GPIO_3_OFFSET 3 +#define RTL8367C_ACL_GPIO_3_MASK 0x8 +#define RTL8367C_ACL_GPIO_2_OFFSET 2 +#define RTL8367C_ACL_GPIO_2_MASK 0x4 +#define RTL8367C_ACL_GPIO_1_OFFSET 1 +#define RTL8367C_ACL_GPIO_1_MASK 0x2 +#define RTL8367C_ACL_GPIO_0_OFFSET 0 +#define RTL8367C_ACL_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_EN_GPIO 0x1350 +#define RTL8367C_EN_GPIO_13_OFFSET 13 +#define RTL8367C_EN_GPIO_13_MASK 0x2000 +#define RTL8367C_EN_GPIO_12_OFFSET 12 +#define RTL8367C_EN_GPIO_12_MASK 0x1000 +#define RTL8367C_EN_GPIO_11_OFFSET 11 +#define RTL8367C_EN_GPIO_11_MASK 0x800 +#define RTL8367C_EN_GPIO_10_OFFSET 10 +#define RTL8367C_EN_GPIO_10_MASK 0x400 +#define RTL8367C_EN_GPIO_9_OFFSET 9 +#define RTL8367C_EN_GPIO_9_MASK 0x200 +#define RTL8367C_EN_GPIO_8_OFFSET 8 +#define RTL8367C_EN_GPIO_8_MASK 0x100 +#define RTL8367C_EN_GPIO_7_OFFSET 7 +#define RTL8367C_EN_GPIO_7_MASK 0x80 +#define RTL8367C_EN_GPIO_6_OFFSET 6 +#define RTL8367C_EN_GPIO_6_MASK 0x40 +#define RTL8367C_EN_GPIO_5_OFFSET 5 +#define RTL8367C_EN_GPIO_5_MASK 0x20 +#define RTL8367C_EN_GPIO_4_OFFSET 4 +#define RTL8367C_EN_GPIO_4_MASK 0x10 +#define RTL8367C_EN_GPIO_3_OFFSET 3 +#define RTL8367C_EN_GPIO_3_MASK 0x8 +#define RTL8367C_EN_GPIO_2_OFFSET 2 +#define RTL8367C_EN_GPIO_2_MASK 0x4 +#define RTL8367C_EN_GPIO_1_OFFSET 1 +#define RTL8367C_EN_GPIO_1_MASK 0x2 +#define RTL8367C_EN_GPIO_0_OFFSET 0 +#define RTL8367C_EN_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_CFG_MULTI_PIN 0x1351 +#define RTL8367C_CFG_MULTI_PIN_OFFSET 0 +#define RTL8367C_CFG_MULTI_PIN_MASK 0x3 + +#define RTL8367C_REG_PORT0_STATUS 0x1352 +#define RTL8367C_PORT0_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT0_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT0_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT0_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT0_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT0_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT0_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT0_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT0_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT0_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT0_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT0_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT1_STATUS 0x1353 +#define RTL8367C_PORT1_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT1_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT1_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT1_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT1_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT1_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT1_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT1_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT1_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT1_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT1_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT1_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT2_STATUS 0x1354 +#define RTL8367C_PORT2_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT2_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT2_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT2_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT2_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT2_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT2_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT2_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT2_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT2_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT2_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT2_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT3_STATUS 0x1355 +#define RTL8367C_PORT3_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT3_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT3_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT3_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT3_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT3_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT3_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT3_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT3_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT3_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT3_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT3_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT4_STATUS 0x1356 +#define RTL8367C_PORT4_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT4_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT4_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT4_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT4_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT4_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT4_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT4_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT4_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT4_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT4_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT4_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT5_STATUS 0x1357 +#define RTL8367C_PORT5_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT5_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT5_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT5_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT5_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT5_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT5_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT5_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT5_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT5_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT5_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT5_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT6_STATUS 0x1358 +#define RTL8367C_PORT6_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT6_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT6_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT6_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT6_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT6_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT6_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT6_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT6_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT6_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT6_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT6_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT7_STATUS 0x1359 +#define RTL8367C_PORT7_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT7_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT7_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT7_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT7_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT7_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT7_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT7_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT7_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT7_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT7_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT7_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT8_STATUS 0x135a +#define RTL8367C_PORT8_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT8_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT8_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT8_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT8_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT8_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT8_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT8_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT8_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT8_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT8_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT8_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT9_STATUS 0x135b +#define RTL8367C_PORT9_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT9_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT9_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT9_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT9_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT9_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT9_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT9_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT9_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT9_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT9_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT9_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_PORT10_STATUS 0x135c +#define RTL8367C_PORT10_STATUS_EN_1000_LPI_OFFSET 11 +#define RTL8367C_PORT10_STATUS_EN_1000_LPI_MASK 0x800 +#define RTL8367C_PORT10_STATUS_EN_100_LPI_OFFSET 10 +#define RTL8367C_PORT10_STATUS_EN_100_LPI_MASK 0x400 +#define RTL8367C_PORT10_STATUS_NWAY_FAULT_OFFSET 9 +#define RTL8367C_PORT10_STATUS_NWAY_FAULT_MASK 0x200 +#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_OFFSET 8 +#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_MASK 0x100 +#define RTL8367C_PORT10_STATUS_NWAY_CAP_OFFSET 7 +#define RTL8367C_PORT10_STATUS_NWAY_CAP_MASK 0x80 +#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 +#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 +#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 +#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 +#define RTL8367C_PORT10_STATUS_LINK_STATE_OFFSET 4 +#define RTL8367C_PORT10_STATUS_LINK_STATE_MASK 0x10 +#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_OFFSET 2 +#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_MASK 0x4 +#define RTL8367C_PORT10_STATUS_LINK_SPEED_OFFSET 0 +#define RTL8367C_PORT10_STATUS_LINK_SPEED_MASK 0x3 + +#define RTL8367C_REG_UPS_CTRL0 0x1362 +#define RTL8367C_P3_REF_SD_BIT0_OFFSET 8 +#define RTL8367C_P3_REF_SD_BIT0_MASK 0xFF00 +#define RTL8367C_P2_REF_SD_OFFSET 0 +#define RTL8367C_P2_REF_SD_MASK 0xFF + +#define RTL8367C_REG_UPS_CTRL1 0x1363 +#define RTL8367C_UPS_OUT_OFFSET 8 +#define RTL8367C_UPS_OUT_MASK 0xFF00 +#define RTL8367C_UPS_WRITE_PULSE_OFFSET 1 +#define RTL8367C_UPS_WRITE_PULSE_MASK 0x2 +#define RTL8367C_UPS_EN_OFFSET 0 +#define RTL8367C_UPS_EN_MASK 0x1 + +#define RTL8367C_REG_UPS_CTRL2 0x1364 +#define RTL8367C_IGNOE_MAC8_LINK_OFFSET 15 +#define RTL8367C_IGNOE_MAC8_LINK_MASK 0x8000 +#define RTL8367C_AGREE_SLEEP_OFFSET 14 +#define RTL8367C_AGREE_SLEEP_MASK 0x4000 +#define RTL8367C_WAIT_FOR_AGREEMENT_OFFSET 13 +#define RTL8367C_WAIT_FOR_AGREEMENT_MASK 0x2000 +#define RTL8367C_WAKE_UP_BY_LINK_OFFSET 12 +#define RTL8367C_WAKE_UP_BY_LINK_MASK 0x1000 +#define RTL8367C_WAKE_UP_BY_PHY_OFFSET 11 +#define RTL8367C_WAKE_UP_BY_PHY_MASK 0x800 +#define RTL8367C_SLOW_CLK_TGL_RATE_OFFSET 7 +#define RTL8367C_SLOW_CLK_TGL_RATE_MASK 0x780 +#define RTL8367C_PLL_G1_CTRL_EN_OFFSET 6 +#define RTL8367C_PLL_G1_CTRL_EN_MASK 0x40 +#define RTL8367C_PLL_G0_CTRL_EN_OFFSET 5 +#define RTL8367C_PLL_G0_CTRL_EN_MASK 0x20 +#define RTL8367C_SLOW_DOWN_PLL_EN_OFFSET 4 +#define RTL8367C_SLOW_DOWN_PLL_EN_MASK 0x10 +#define RTL8367C_SLOW_DOWN_CLK_EN_OFFSET 3 +#define RTL8367C_SLOW_DOWN_CLK_EN_MASK 0x8 +#define RTL8367C_GATING_CLK_SDS_EN_OFFSET 2 +#define RTL8367C_GATING_CLK_SDS_EN_MASK 0x4 +#define RTL8367C_GATING_CLK_CHIP_EN_OFFSET 1 +#define RTL8367C_GATING_CLK_CHIP_EN_MASK 0x2 +#define RTL8367C_GATING_SW_EN_OFFSET 0 +#define RTL8367C_GATING_SW_EN_MASK 0x1 + +#define RTL8367C_REG_GATING_CLK_1 0x1365 +#define RTL8367C_ALDPS_MODE_4_OFFSET 15 +#define RTL8367C_ALDPS_MODE_4_MASK 0x8000 +#define RTL8367C_ALDPS_MODE_3_OFFSET 14 +#define RTL8367C_ALDPS_MODE_3_MASK 0x4000 +#define RTL8367C_ALDPS_MODE_2_OFFSET 13 +#define RTL8367C_ALDPS_MODE_2_MASK 0x2000 +#define RTL8367C_ALDPS_MODE_1_OFFSET 12 +#define RTL8367C_ALDPS_MODE_1_MASK 0x1000 +#define RTL8367C_ALDPS_MODE_0_OFFSET 11 +#define RTL8367C_ALDPS_MODE_0_MASK 0x800 +#define RTL8367C_UPS_DBGO_OFFSET 10 +#define RTL8367C_UPS_DBGO_MASK 0x400 +#define RTL8367C_IFMX_AFF_NOT_FF_OUT_OFFSET 9 +#define RTL8367C_IFMX_AFF_NOT_FF_OUT_MASK 0x200 +#define RTL8367C_WATER_LEVEL_FD_OFFSET 6 +#define RTL8367C_WATER_LEVEL_FD_MASK 0x1C0 +#define RTL8367C_WATER_LEVEL_Y2X_OFFSET 3 +#define RTL8367C_WATER_LEVEL_Y2X_MASK 0x38 +#define RTL8367C_WATER_LEVEL_X2Y_2_OFFSET 2 +#define RTL8367C_WATER_LEVEL_X2Y_2_MASK 0x4 +#define RTL8367C_IGNOE_MAC10_LINK_OFFSET 1 +#define RTL8367C_IGNOE_MAC10_LINK_MASK 0x2 +#define RTL8367C_IGNOE_MAC9_LINK_OFFSET 0 +#define RTL8367C_IGNOE_MAC9_LINK_MASK 0x1 + +#define RTL8367C_REG_UPS_CTRL4 0x1366 +#define RTL8367C_PROB_EN_OFFSET 6 +#define RTL8367C_PROB_EN_MASK 0x40 +#define RTL8367C_PLL_DOWN_OFFSET 1 +#define RTL8367C_PLL_DOWN_MASK 0x2 +#define RTL8367C_XTAL_DOWN_OFFSET 0 +#define RTL8367C_XTAL_DOWN_MASK 0x1 + +#define RTL8367C_REG_UPS_CTRL5 0x1367 +#define RTL8367C_FRC_CPU_ACPT_OFFSET 3 +#define RTL8367C_FRC_CPU_ACPT_MASK 0x8 +#define RTL8367C_UPS_CPU_ACPT_OFFSET 2 +#define RTL8367C_UPS_CPU_ACPT_MASK 0x4 +#define RTL8367C_UPS_DBG_4_OFFSET 0 +#define RTL8367C_UPS_DBG_4_MASK 0x3 + +#define RTL8367C_REG_UPS_CTRL6 0x1368 +#define RTL8367C_UPS_CTRL6_OFFSET 0 +#define RTL8367C_UPS_CTRL6_MASK 0xF + +#define RTL8367C_REG_EFUSE_CMD_70B 0x1369 + +#define RTL8367C_REG_EFUSE_CMD 0x1370 +#define RTL8367C_EFUSE_TIME_OUT_FLAG_OFFSET 3 +#define RTL8367C_EFUSE_TIME_OUT_FLAG_MASK 0x8 +#define RTL8367C_EFUSE_ACCESS_BUSY_OFFSET 2 +#define RTL8367C_EFUSE_ACCESS_BUSY_MASK 0x4 +#define RTL8367C_EFUSE_COMMAND_EN_OFFSET 1 +#define RTL8367C_EFUSE_COMMAND_EN_MASK 0x2 +#define RTL8367C_EFUSE_WR_OFFSET 0 +#define RTL8367C_EFUSE_WR_MASK 0x1 + +#define RTL8367C_REG_EFUSE_ADR 0x1371 +#define RTL8367C_DUMMY_15_10_OFFSET 8 +#define RTL8367C_DUMMY_15_10_MASK 0xFF00 +#define RTL8367C_EFUSE_ADDRESS_OFFSET 0 +#define RTL8367C_EFUSE_ADDRESS_MASK 0xFF + +#define RTL8367C_REG_EFUSE_WDAT 0x1372 + +#define RTL8367C_REG_EFUSE_RDAT 0x1373 + +#define RTL8367C_REG_I2C_CTRL 0x1374 +#define RTL8367C_MDX_MST_FAIL_LAT_OFFSET 1 +#define RTL8367C_MDX_MST_FAIL_LAT_MASK 0x2 +#define RTL8367C_MDX_MST_FAIL_CLRPS_OFFSET 0 +#define RTL8367C_MDX_MST_FAIL_CLRPS_MASK 0x1 + +#define RTL8367C_REG_EEE_CFG 0x1375 +#define RTL8367C_CFG_BYPASS_GATELPTD_OFFSET 11 +#define RTL8367C_CFG_BYPASS_GATELPTD_MASK 0x800 +#define RTL8367C_EEE_ABT_ADDR2_OFFSET 6 +#define RTL8367C_EEE_ABT_ADDR2_MASK 0x7C0 +#define RTL8367C_EEE_ABT_ADDR1_OFFSET 1 +#define RTL8367C_EEE_ABT_ADDR1_MASK 0x3E +#define RTL8367C_EEE_POLL_EN_OFFSET 0 +#define RTL8367C_EEE_POLL_EN_MASK 0x1 + +#define RTL8367C_REG_EEE_PAGE 0x1376 + +#define RTL8367C_REG_EEE_EXT_PAGE 0x1377 + +#define RTL8367C_REG_EEE_EN_SPD1000 0x1378 + +#define RTL8367C_REG_EEE_EN_SPD100 0x1379 + +#define RTL8367C_REG_EEE_LP_SPD1000 0x137a + +#define RTL8367C_REG_EEE_LP_SPD100 0x137b + +#define RTL8367C_REG_DW8051_PRO_REG0 0x13a0 + +#define RTL8367C_REG_DW8051_PRO_REG1 0x13a1 + +#define RTL8367C_REG_DW8051_PRO_REG2 0x13a2 + +#define RTL8367C_REG_DW8051_PRO_REG3 0x13a3 + +#define RTL8367C_REG_DW8051_PRO_REG4 0x13a4 + +#define RTL8367C_REG_DW8051_PRO_REG5 0x13a5 + +#define RTL8367C_REG_DW8051_PRO_REG6 0x13a6 + +#define RTL8367C_REG_DW8051_PRO_REG7 0x13a7 + +#define RTL8367C_REG_PROTECT_ID 0x13c0 + +#define RTL8367C_REG_CHIP_VER_INTL 0x13c1 +#define RTL8367C_CHIP_VER_INTL_OFFSET 0 +#define RTL8367C_CHIP_VER_INTL_MASK 0xF + +#define RTL8367C_REG_MAGIC_ID 0x13c2 + +#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1 0x13c3 +#define RTL8367C_SKIP_MII_2_RXER_OFFSET 4 +#define RTL8367C_SKIP_MII_2_RXER_MASK 0x10 +#define RTL8367C_SELECT_GMII_2_OFFSET 0 +#define RTL8367C_SELECT_GMII_2_MASK 0xF + +#define RTL8367C_REG_DIGITAL_INTERFACE2_FORCE 0x13c4 +#define RTL8367C_GMII_2_FORCE_OFFSET 12 +#define RTL8367C_GMII_2_FORCE_MASK 0x1000 +#define RTL8367C_RGMII_2_FORCE_OFFSET 0 +#define RTL8367C_RGMII_2_FORCE_MASK 0xFFF + +#define RTL8367C_REG_EXT2_RGMXF 0x13c5 +#define RTL8367C_EXT2_RGTX_INV_OFFSET 6 +#define RTL8367C_EXT2_RGTX_INV_MASK 0x40 +#define RTL8367C_EXT2_RGRX_INV_OFFSET 5 +#define RTL8367C_EXT2_RGRX_INV_MASK 0x20 +#define RTL8367C_EXT2_RGMXF_OFFSET 0 +#define RTL8367C_EXT2_RGMXF_MASK 0x1F + +#define RTL8367C_REG_ROUTER_UPS_CFG 0x13c6 +#define RTL8367C_UPS_Status_OFFSET 1 +#define RTL8367C_UPS_Status_MASK 0x2 +#define RTL8367C_SoftStart_OFFSET 0 +#define RTL8367C_SoftStart_MASK 0x1 + +#define RTL8367C_REG_CTRL_GPIO 0x13c7 +#define RTL8367C_CTRL_GPIO_13_OFFSET 13 +#define RTL8367C_CTRL_GPIO_13_MASK 0x2000 +#define RTL8367C_CTRL_GPIO_12_OFFSET 12 +#define RTL8367C_CTRL_GPIO_12_MASK 0x1000 +#define RTL8367C_CTRL_GPIO_11_OFFSET 11 +#define RTL8367C_CTRL_GPIO_11_MASK 0x800 +#define RTL8367C_CTRL_GPIO_10_OFFSET 10 +#define RTL8367C_CTRL_GPIO_10_MASK 0x400 +#define RTL8367C_CTRL_GPIO_9_OFFSET 9 +#define RTL8367C_CTRL_GPIO_9_MASK 0x200 +#define RTL8367C_CTRL_GPIO_8_OFFSET 8 +#define RTL8367C_CTRL_GPIO_8_MASK 0x100 +#define RTL8367C_CTRL_GPIO_7_OFFSET 7 +#define RTL8367C_CTRL_GPIO_7_MASK 0x80 +#define RTL8367C_CTRL_GPIO_6_OFFSET 6 +#define RTL8367C_CTRL_GPIO_6_MASK 0x40 +#define RTL8367C_CTRL_GPIO_5_OFFSET 5 +#define RTL8367C_CTRL_GPIO_5_MASK 0x20 +#define RTL8367C_CTRL_GPIO_4_OFFSET 4 +#define RTL8367C_CTRL_GPIO_4_MASK 0x10 +#define RTL8367C_CTRL_GPIO_3_OFFSET 3 +#define RTL8367C_CTRL_GPIO_3_MASK 0x8 +#define RTL8367C_CTRL_GPIO_2_OFFSET 2 +#define RTL8367C_CTRL_GPIO_2_MASK 0x4 +#define RTL8367C_CTRL_GPIO_1_OFFSET 1 +#define RTL8367C_CTRL_GPIO_1_MASK 0x2 +#define RTL8367C_CTRL_GPIO_0_OFFSET 0 +#define RTL8367C_CTRL_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_SEL_GPIO 0x13c8 +#define RTL8367C_SEL_GPIO_13_OFFSET 13 +#define RTL8367C_SEL_GPIO_13_MASK 0x2000 +#define RTL8367C_SEL_GPIO_12_OFFSET 12 +#define RTL8367C_SEL_GPIO_12_MASK 0x1000 +#define RTL8367C_SEL_GPIO_11_OFFSET 11 +#define RTL8367C_SEL_GPIO_11_MASK 0x800 +#define RTL8367C_SEL_GPIO_10_OFFSET 10 +#define RTL8367C_SEL_GPIO_10_MASK 0x400 +#define RTL8367C_SEL_GPIO_9_OFFSET 9 +#define RTL8367C_SEL_GPIO_9_MASK 0x200 +#define RTL8367C_SEL_GPIO_8_OFFSET 8 +#define RTL8367C_SEL_GPIO_8_MASK 0x100 +#define RTL8367C_SEL_GPIO_7_OFFSET 7 +#define RTL8367C_SEL_GPIO_7_MASK 0x80 +#define RTL8367C_SEL_GPIO_6_OFFSET 6 +#define RTL8367C_SEL_GPIO_6_MASK 0x40 +#define RTL8367C_SEL_GPIO_5_OFFSET 5 +#define RTL8367C_SEL_GPIO_5_MASK 0x20 +#define RTL8367C_SEL_GPIO_4_OFFSET 4 +#define RTL8367C_SEL_GPIO_4_MASK 0x10 +#define RTL8367C_SEL_GPIO_3_OFFSET 3 +#define RTL8367C_SEL_GPIO_3_MASK 0x8 +#define RTL8367C_SEL_GPIO_2_OFFSET 2 +#define RTL8367C_SEL_GPIO_2_MASK 0x4 +#define RTL8367C_SEL_GPIO_1_OFFSET 1 +#define RTL8367C_SEL_GPIO_1_MASK 0x2 +#define RTL8367C_SEL_GPIO_0_OFFSET 0 +#define RTL8367C_SEL_GPIO_0_MASK 0x1 + +#define RTL8367C_REG_STATUS_GPIO 0x13c9 +#define RTL8367C_STATUS_GPIO_OFFSET 0 +#define RTL8367C_STATUS_GPIO_MASK 0x3FFF + +#define RTL8367C_REG_SYNC_ETH_CFG 0x13e0 +#define RTL8367C_DUMMY2_OFFSET 9 +#define RTL8367C_DUMMY2_MASK 0xFE00 +#define RTL8367C_RFC2819_TYPE_OFFSET 8 +#define RTL8367C_RFC2819_TYPE_MASK 0x100 +#define RTL8367C_DUMMY1_OFFSET 7 +#define RTL8367C_DUMMY1_MASK 0x80 +#define RTL8367C_FIBER_SYNCE125_L_SEL_OFFSET 6 +#define RTL8367C_FIBER_SYNCE125_L_SEL_MASK 0x40 +#define RTL8367C_SYNC_ETH_EN_RTT2_OFFSET 5 +#define RTL8367C_SYNC_ETH_EN_RTT2_MASK 0x20 +#define RTL8367C_SYNC_ETH_EN_RTT1_OFFSET 4 +#define RTL8367C_SYNC_ETH_EN_RTT1_MASK 0x10 +#define RTL8367C_SYNC_ETH_SEL_DPLL_OFFSET 3 +#define RTL8367C_SYNC_ETH_SEL_DPLL_MASK 0x8 +#define RTL8367C_SYNC_ETH_SEL_PHYREF_OFFSET 2 +#define RTL8367C_SYNC_ETH_SEL_PHYREF_MASK 0x4 +#define RTL8367C_SYNC_ETH_SEL_XTAL_OFFSET 1 +#define RTL8367C_SYNC_ETH_SEL_XTAL_MASK 0x2 +#define RTL8367C_DUMMY0_OFFSET 0 +#define RTL8367C_DUMMY0_MASK 0x1 + +#define RTL8367C_REG_LED_DRI_CFG 0x13e1 +#define RTL8367C_LED_DRI_CFG_DUMMY_OFFSET 1 +#define RTL8367C_LED_DRI_CFG_DUMMY_MASK 0xFFFE +#define RTL8367C_LED_DRIVING_OFFSET 0 +#define RTL8367C_LED_DRIVING_MASK 0x1 + +#define RTL8367C_REG_CHIP_DEBUG2 0x13e2 +#define RTL8367C_RG2_DN_OFFSET 6 +#define RTL8367C_RG2_DN_MASK 0x1C0 +#define RTL8367C_RG2_DP_OFFSET 3 +#define RTL8367C_RG2_DP_MASK 0x38 +#define RTL8367C_DRI_EXT2_RG_OFFSET 2 +#define RTL8367C_DRI_EXT2_RG_MASK 0x4 +#define RTL8367C_DRI_EXT2_OFFSET 1 +#define RTL8367C_DRI_EXT2_MASK 0x2 +#define RTL8367C_SLR_EXT2_OFFSET 0 +#define RTL8367C_SLR_EXT2_MASK 0x1 + +#define RTL8367C_REG_DIGITAL_DEBUG_2 0x13e3 + +#define RTL8367C_REG_FIBER_RTL_OUI_CFG0 0x13e4 +#define RTL8367C_FIBER_RTL_OUI_CFG0_OFFSET 0 +#define RTL8367C_FIBER_RTL_OUI_CFG0_MASK 0xFF + +#define RTL8367C_REG_FIBER_RTL_OUI_CFG1 0x13e5 + +#define RTL8367C_REG_FIBER_CFG_0 0x13e6 +#define RTL8367C_REV_NUM_OFFSET 8 +#define RTL8367C_REV_NUM_MASK 0xF00 +#define RTL8367C_MODEL_NUM_OFFSET 0 +#define RTL8367C_MODEL_NUM_MASK 0x3F + +#define RTL8367C_REG_FIBER_CFG_1 0x13e7 +#define RTL8367C_SDS_FRC_REG4_OFFSET 12 +#define RTL8367C_SDS_FRC_REG4_MASK 0x1000 +#define RTL8367C_SDS_FRC_REG4_FIB100_OFFSET 11 +#define RTL8367C_SDS_FRC_REG4_FIB100_MASK 0x800 +#define RTL8367C_SEL_MASK_ONL_OFFSET 5 +#define RTL8367C_SEL_MASK_ONL_MASK 0x20 +#define RTL8367C_DIS_QUALITY_IN_MASK_OFFSET 4 +#define RTL8367C_DIS_QUALITY_IN_MASK_MASK 0x10 +#define RTL8367C_SDS_FRC_MODE_OFFSET 3 +#define RTL8367C_SDS_FRC_MODE_MASK 0x8 +#define RTL8367C_SDS_MODE_OFFSET 0 +#define RTL8367C_SDS_MODE_MASK 0x7 + +#define RTL8367C_REG_FIBER_CFG_2 0x13e8 +#define RTL8367C_SEL_SDET_PS_OFFSET 12 +#define RTL8367C_SEL_SDET_PS_MASK 0xF000 +#define RTL8367C_UTP_DIS_RX_OFFSET 10 +#define RTL8367C_UTP_DIS_RX_MASK 0xC00 +#define RTL8367C_UTP_FRC_LD_OFFSET 8 +#define RTL8367C_UTP_FRC_LD_MASK 0x300 +#define RTL8367C_SDS_RX_DISABLE_OFFSET 6 +#define RTL8367C_SDS_RX_DISABLE_MASK 0xC0 +#define RTL8367C_SDS_TX_DISABLE_OFFSET 4 +#define RTL8367C_SDS_TX_DISABLE_MASK 0x30 +#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_OFFSET 2 +#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_MASK 0xC +#define RTL8367C_SDS_FRC_LD_OFFSET 0 +#define RTL8367C_SDS_FRC_LD_MASK 0x3 + +#define RTL8367C_REG_FIBER_CFG_3 0x13e9 +#define RTL8367C_FIBER_CFG_3_OFFSET 0 +#define RTL8367C_FIBER_CFG_3_MASK 0xFFF + +#define RTL8367C_REG_FIBER_CFG_4 0x13ea + +#define RTL8367C_REG_UTP_FIB_DET 0x13eb +#define RTL8367C_FORCE_SEL_FIBER_OFFSET 14 +#define RTL8367C_FORCE_SEL_FIBER_MASK 0xC000 +#define RTL8367C_FIB_FINAL_TIMER_OFFSET 12 +#define RTL8367C_FIB_FINAL_TIMER_MASK 0x3000 +#define RTL8367C_FIB_LINK_TIMER_OFFSET 10 +#define RTL8367C_FIB_LINK_TIMER_MASK 0xC00 +#define RTL8367C_FIB_SDET_TIMER_OFFSET 8 +#define RTL8367C_FIB_SDET_TIMER_MASK 0x300 +#define RTL8367C_UTP_LINK_TIMER_OFFSET 6 +#define RTL8367C_UTP_LINK_TIMER_MASK 0xC0 +#define RTL8367C_UTP_SDET_TIMER_OFFSET 4 +#define RTL8367C_UTP_SDET_TIMER_MASK 0x30 +#define RTL8367C_FORCE_AUTODET_OFFSET 3 +#define RTL8367C_FORCE_AUTODET_MASK 0x8 +#define RTL8367C_AUTODET_FSM_CLR_OFFSET 2 +#define RTL8367C_AUTODET_FSM_CLR_MASK 0x4 +#define RTL8367C_UTP_FIRST_OFFSET 1 +#define RTL8367C_UTP_FIRST_MASK 0x2 +#define RTL8367C_UTP_FIB_DISAUTODET_OFFSET 0 +#define RTL8367C_UTP_FIB_DISAUTODET_MASK 0x1 + +#define RTL8367C_REG_NRESTORE_MAGIC_NUM 0x13ec +#define RTL8367C_NRESTORE_MAGIC_NUM_MASK 0xFFFF +#define RTL8367C_EEPROM_PROGRAM_CYCLE_OFFSET 0 +#define RTL8367C_EEPROM_PROGRAM_CYCLE_MASK 0x3 + +#define RTL8367C_REG_MAC_ACTIVE 0x13ee +#define RTL8367C_MAC_ACTIVE_H_OFFSET 9 +#define RTL8367C_MAC_ACTIVE_H_MASK 0xE00 +#define RTL8367C_FORCE_MAC_ACTIVE_OFFSET 8 +#define RTL8367C_FORCE_MAC_ACTIVE_MASK 0x100 +#define RTL8367C_MAC_ACTIVE_OFFSET 0 +#define RTL8367C_MAC_ACTIVE_MASK 0xFF + +#define RTL8367C_REG_SERDES_RESULT 0x13ef +#define RTL8367C_FIB100_DET_1_OFFSET 12 +#define RTL8367C_FIB100_DET_1_MASK 0x1000 +#define RTL8367C_FIB_ISO_1_OFFSET 11 +#define RTL8367C_FIB_ISO_1_MASK 0x800 +#define RTL8367C_SDS_ANFAULT_1_OFFSET 10 +#define RTL8367C_SDS_ANFAULT_1_MASK 0x400 +#define RTL8367C_SDS_INTB_1_OFFSET 9 +#define RTL8367C_SDS_INTB_1_MASK 0x200 +#define RTL8367C_SDS_LINK_OK_1_OFFSET 8 +#define RTL8367C_SDS_LINK_OK_1_MASK 0x100 +#define RTL8367C_FIB100_DET_OFFSET 4 +#define RTL8367C_FIB100_DET_MASK 0x10 +#define RTL8367C_FIB_ISO_OFFSET 3 +#define RTL8367C_FIB_ISO_MASK 0x8 +#define RTL8367C_SDS_ANFAULT_OFFSET 2 +#define RTL8367C_SDS_ANFAULT_MASK 0x4 +#define RTL8367C_SDS_INTB_OFFSET 1 +#define RTL8367C_SDS_INTB_MASK 0x2 +#define RTL8367C_SDS_LINK_OK_OFFSET 0 +#define RTL8367C_SDS_LINK_OK_MASK 0x1 + +#define RTL8367C_REG_CHIP_ECO 0x13f0 +#define RTL8367C_CFG_CHIP_ECO_OFFSET 1 +#define RTL8367C_CFG_CHIP_ECO_MASK 0xFFFE +#define RTL8367C_CFG_CKOUTEN_OFFSET 0 +#define RTL8367C_CFG_CKOUTEN_MASK 0x1 + +#define RTL8367C_REG_WAKELPI_SLOT_PRD 0x13f1 +#define RTL8367C_WAKELPI_SLOT_PRD_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_PRD_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG0 0x13f2 +#define RTL8367C_WAKELPI_SLOT_P1_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P1_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P0_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P0_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG1 0x13f3 +#define RTL8367C_WAKELPI_SLOT_P3_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P3_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P2_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P2_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG2 0x13f4 +#define RTL8367C_WAKELPI_SLOT_P5_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P5_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P4_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P4_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG3 0x13f5 +#define RTL8367C_WAKELPI_SLOT_P7_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P7_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P6_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P6_MASK 0x1F + +#define RTL8367C_REG_SYNC_FIFO_0 0x13f6 +#define RTL8367C_SYNC_FIFO_TX_OFFSET 8 +#define RTL8367C_SYNC_FIFO_TX_MASK 0x700 +#define RTL8367C_SYNC_FIFO_RX_OFFSET 0 +#define RTL8367C_SYNC_FIFO_RX_MASK 0xFF + +#define RTL8367C_REG_SYNC_FIFO_1 0x13f7 +#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_OFFSET 11 +#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_MASK 0x3800 +#define RTL8367C_SYNC_FIFO_TX_ERR_OFFSET 8 +#define RTL8367C_SYNC_FIFO_TX_ERR_MASK 0x700 +#define RTL8367C_SYNC_FIFO_RX_ERR_OFFSET 0 +#define RTL8367C_SYNC_FIFO_RX_ERR_MASK 0xFF + +#define RTL8367C_REG_RGM_EEE 0x13f8 +#define RTL8367C_EXT2_PAD_STOP_EN_OFFSET 14 +#define RTL8367C_EXT2_PAD_STOP_EN_MASK 0x4000 +#define RTL8367C_EXT1_PAD_STOP_EN_OFFSET 13 +#define RTL8367C_EXT1_PAD_STOP_EN_MASK 0x2000 +#define RTL8367C_EXT0_PAD_STOP_EN_OFFSET 12 +#define RTL8367C_EXT0_PAD_STOP_EN_MASK 0x1000 +#define RTL8367C_EXT2_CYCLE_PAD_OFFSET 8 +#define RTL8367C_EXT2_CYCLE_PAD_MASK 0xF00 +#define RTL8367C_EXT1_CYCLE_PAD_OFFSET 4 +#define RTL8367C_EXT1_CYCLE_PAD_MASK 0xF0 +#define RTL8367C_EXT0_CYCLE_PAD_OFFSET 0 +#define RTL8367C_EXT0_CYCLE_PAD_MASK 0xF + +#define RTL8367C_REG_EXT_TXC_DLY 0x13f9 +#define RTL8367C_EXT1_GMII_TX_DELAY_OFFSET 12 +#define RTL8367C_EXT1_GMII_TX_DELAY_MASK 0x7000 +#define RTL8367C_EXT0_GMII_TX_DELAY_OFFSET 9 +#define RTL8367C_EXT0_GMII_TX_DELAY_MASK 0xE00 +#define RTL8367C_EXT2_RGMII_TX_DELAY_OFFSET 6 +#define RTL8367C_EXT2_RGMII_TX_DELAY_MASK 0x1C0 +#define RTL8367C_EXT1_RGMII_TX_DELAY_OFFSET 3 +#define RTL8367C_EXT1_RGMII_TX_DELAY_MASK 0x38 +#define RTL8367C_EXT0_RGMII_TX_DELAY_OFFSET 0 +#define RTL8367C_EXT0_RGMII_TX_DELAY_MASK 0x7 + +#define RTL8367C_REG_IO_MISC_CTRL 0x13fa +#define RTL8367C_IO_BUZZER_EN_OFFSET 3 +#define RTL8367C_IO_BUZZER_EN_MASK 0x8 +#define RTL8367C_IO_INTRPT_EN_OFFSET 2 +#define RTL8367C_IO_INTRPT_EN_MASK 0x4 +#define RTL8367C_IO_NRESTORE_EN_OFFSET 1 +#define RTL8367C_IO_NRESTORE_EN_MASK 0x2 +#define RTL8367C_IO_UART_EN_OFFSET 0 +#define RTL8367C_IO_UART_EN_MASK 0x1 + +#define RTL8367C_REG_CHIP_DUMMY_NO 0x13fb +#define RTL8367C_CHIP_DUMMY_NO_OFFSET 0 +#define RTL8367C_CHIP_DUMMY_NO_MASK 0xF + +#define RTL8367C_REG_RC_CALIB_CFG 0x13fc +#define RTL8367C_TRIG_BURN_EFUSE_OFFSET 9 +#define RTL8367C_TRIG_BURN_EFUSE_MASK 0x200 +#define RTL8367C_AMP_CALIB_FAIL_OFFSET 8 +#define RTL8367C_AMP_CALIB_FAIL_MASK 0x100 +#define RTL8367C_R_CALIB_FAIL_OFFSET 7 +#define RTL8367C_R_CALIB_FAIL_MASK 0x80 +#define RTL8367C_CFG_CALIB_MODE_OFFSET 6 +#define RTL8367C_CFG_CALIB_MODE_MASK 0x40 +#define RTL8367C_CENTER_PORT_SEL_OFFSET 3 +#define RTL8367C_CENTER_PORT_SEL_MASK 0x38 +#define RTL8367C_CALIB_FINISH_OFFSET 2 +#define RTL8367C_CALIB_FINISH_MASK 0x4 +#define RTL8367C_CFG_CALIB_OPTION_OFFSET 1 +#define RTL8367C_CFG_CALIB_OPTION_MASK 0x2 +#define RTL8367C_CFG_CALIB_EN_OFFSET 0 +#define RTL8367C_CFG_CALIB_EN_MASK 0x1 + +#define RTL8367C_REG_WAKELPI_SLOT_PG4 0x13fd +#define RTL8367C_WAKELPI_SLOT_P9_OFFSET 8 +#define RTL8367C_WAKELPI_SLOT_P9_MASK 0x1F00 +#define RTL8367C_WAKELPI_SLOT_P8_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_P8_MASK 0x1F + +#define RTL8367C_REG_WAKELPI_SLOT_PG5 0x13fe +#define RTL8367C_WAKELPI_SLOT_PG5_OFFSET 0 +#define RTL8367C_WAKELPI_SLOT_PG5_MASK 0x1F + +/* (16'h1400)mtrpool_reg */ + +#define RTL8367C_REG_METER0_RATE_CTRL0 0x1400 + +#define RTL8367C_REG_METER0_RATE_CTRL1 0x1401 +#define RTL8367C_METER0_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER0_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER1_RATE_CTRL0 0x1402 + +#define RTL8367C_REG_METER1_RATE_CTRL1 0x1403 +#define RTL8367C_METER1_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER1_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER2_RATE_CTRL0 0x1404 + +#define RTL8367C_REG_METER2_RATE_CTRL1 0x1405 +#define RTL8367C_METER2_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER2_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER3_RATE_CTRL0 0x1406 + +#define RTL8367C_REG_METER3_RATE_CTRL1 0x1407 +#define RTL8367C_METER3_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER3_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER4_RATE_CTRL0 0x1408 + +#define RTL8367C_REG_METER4_RATE_CTRL1 0x1409 +#define RTL8367C_METER4_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER4_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER5_RATE_CTRL0 0x140a + +#define RTL8367C_REG_METER5_RATE_CTRL1 0x140b +#define RTL8367C_METER5_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER5_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER6_RATE_CTRL0 0x140c + +#define RTL8367C_REG_METER6_RATE_CTRL1 0x140d +#define RTL8367C_METER6_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER6_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER7_RATE_CTRL0 0x140e + +#define RTL8367C_REG_METER7_RATE_CTRL1 0x140f +#define RTL8367C_METER7_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER7_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER8_RATE_CTRL0 0x1410 + +#define RTL8367C_REG_METER8_RATE_CTRL1 0x1411 +#define RTL8367C_METER8_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER8_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER9_RATE_CTRL0 0x1412 + +#define RTL8367C_REG_METER9_RATE_CTRL1 0x1413 +#define RTL8367C_METER9_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER9_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER10_RATE_CTRL0 0x1414 + +#define RTL8367C_REG_METER10_RATE_CTRL1 0x1415 +#define RTL8367C_METER10_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER10_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER11_RATE_CTRL0 0x1416 + +#define RTL8367C_REG_METER11_RATE_CTRL1 0x1417 +#define RTL8367C_METER11_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER11_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER12_RATE_CTRL0 0x1418 + +#define RTL8367C_REG_METER12_RATE_CTRL1 0x1419 +#define RTL8367C_METER12_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER12_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER13_RATE_CTRL0 0x141a + +#define RTL8367C_REG_METER13_RATE_CTRL1 0x141b +#define RTL8367C_METER13_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER13_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER14_RATE_CTRL0 0x141c + +#define RTL8367C_REG_METER14_RATE_CTRL1 0x141d +#define RTL8367C_METER14_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER14_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER15_RATE_CTRL0 0x141e + +#define RTL8367C_REG_METER15_RATE_CTRL1 0x141f +#define RTL8367C_METER15_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER15_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER16_RATE_CTRL0 0x1420 + +#define RTL8367C_REG_METER16_RATE_CTRL1 0x1421 +#define RTL8367C_METER16_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER16_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER17_RATE_CTRL0 0x1422 + +#define RTL8367C_REG_METER17_RATE_CTRL1 0x1423 +#define RTL8367C_METER17_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER17_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER18_RATE_CTRL0 0x1424 + +#define RTL8367C_REG_METER18_RATE_CTRL1 0x1425 +#define RTL8367C_METER18_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER18_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER19_RATE_CTRL0 0x1426 + +#define RTL8367C_REG_METER19_RATE_CTRL1 0x1427 +#define RTL8367C_METER19_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER19_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER20_RATE_CTRL0 0x1428 + +#define RTL8367C_REG_METER20_RATE_CTRL1 0x1429 +#define RTL8367C_METER20_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER20_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER21_RATE_CTRL0 0x142a + +#define RTL8367C_REG_METER21_RATE_CTRL1 0x142b +#define RTL8367C_METER21_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER21_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER22_RATE_CTRL0 0x142c + +#define RTL8367C_REG_METER22_RATE_CTRL1 0x142d +#define RTL8367C_METER22_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER22_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER23_RATE_CTRL0 0x142e + +#define RTL8367C_REG_METER23_RATE_CTRL1 0x142f +#define RTL8367C_METER23_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER23_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER24_RATE_CTRL0 0x1430 + +#define RTL8367C_REG_METER24_RATE_CTRL1 0x1431 +#define RTL8367C_METER24_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER24_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER25_RATE_CTRL0 0x1432 + +#define RTL8367C_REG_METER25_RATE_CTRL1 0x1433 +#define RTL8367C_METER25_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER25_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER26_RATE_CTRL0 0x1434 + +#define RTL8367C_REG_METER26_RATE_CTRL1 0x1435 +#define RTL8367C_METER26_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER26_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER27_RATE_CTRL0 0x1436 + +#define RTL8367C_REG_METER27_RATE_CTRL1 0x1437 +#define RTL8367C_METER27_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER27_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER28_RATE_CTRL0 0x1438 + +#define RTL8367C_REG_METER28_RATE_CTRL1 0x1439 +#define RTL8367C_METER28_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER28_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER29_RATE_CTRL0 0x143a + +#define RTL8367C_REG_METER29_RATE_CTRL1 0x143b +#define RTL8367C_METER29_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER29_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER30_RATE_CTRL0 0x143c + +#define RTL8367C_REG_METER30_RATE_CTRL1 0x143d +#define RTL8367C_METER30_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER30_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER31_RATE_CTRL0 0x143e + +#define RTL8367C_REG_METER31_RATE_CTRL1 0x143f +#define RTL8367C_METER31_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER31_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER_MODE_SETTING0 0x1440 + +#define RTL8367C_REG_METER_MODE_SETTING1 0x1441 + +#define RTL8367C_REG_METER_MODE_TOKEN_CFG 0x1442 +#define RTL8367C_METER_MODE_TOKEN_CFG_OFFSET 0 +#define RTL8367C_METER_MODE_TOKEN_CFG_MASK 0x7FF + +#define RTL8367C_REG_METER0_BUCKET_SIZE 0x1600 + +#define RTL8367C_REG_METER1_BUCKET_SIZE 0x1601 + +#define RTL8367C_REG_METER2_BUCKET_SIZE 0x1602 + +#define RTL8367C_REG_METER3_BUCKET_SIZE 0x1603 + +#define RTL8367C_REG_METER4_BUCKET_SIZE 0x1604 + +#define RTL8367C_REG_METER5_BUCKET_SIZE 0x1605 + +#define RTL8367C_REG_METER6_BUCKET_SIZE 0x1606 + +#define RTL8367C_REG_METER7_BUCKET_SIZE 0x1607 + +#define RTL8367C_REG_METER8_BUCKET_SIZE 0x1608 + +#define RTL8367C_REG_METER9_BUCKET_SIZE 0x1609 + +#define RTL8367C_REG_METER10_BUCKET_SIZE 0x160a + +#define RTL8367C_REG_METER11_BUCKET_SIZE 0x160b + +#define RTL8367C_REG_METER12_BUCKET_SIZE 0x160c + +#define RTL8367C_REG_METER13_BUCKET_SIZE 0x160d + +#define RTL8367C_REG_METER14_BUCKET_SIZE 0x160e + +#define RTL8367C_REG_METER15_BUCKET_SIZE 0x160f + +#define RTL8367C_REG_METER16_BUCKET_SIZE 0x1610 + +#define RTL8367C_REG_METER17_BUCKET_SIZE 0x1611 + +#define RTL8367C_REG_METER18_BUCKET_SIZE 0x1612 + +#define RTL8367C_REG_METER19_BUCKET_SIZE 0x1613 + +#define RTL8367C_REG_METER20_BUCKET_SIZE 0x1614 + +#define RTL8367C_REG_METER21_BUCKET_SIZE 0x1615 + +#define RTL8367C_REG_METER22_BUCKET_SIZE 0x1616 + +#define RTL8367C_REG_METER23_BUCKET_SIZE 0x1617 + +#define RTL8367C_REG_METER24_BUCKET_SIZE 0x1618 + +#define RTL8367C_REG_METER25_BUCKET_SIZE 0x1619 + +#define RTL8367C_REG_METER26_BUCKET_SIZE 0x161a + +#define RTL8367C_REG_METER27_BUCKET_SIZE 0x161b + +#define RTL8367C_REG_METER28_BUCKET_SIZE 0x161c + +#define RTL8367C_REG_METER29_BUCKET_SIZE 0x161d + +#define RTL8367C_REG_METER30_BUCKET_SIZE 0x161e + +#define RTL8367C_REG_METER31_BUCKET_SIZE 0x161f + +#define RTL8367C_REG_METER_CTRL0 0x1700 +#define RTL8367C_METER_OP_OFFSET 8 +#define RTL8367C_METER_OP_MASK 0x100 +#define RTL8367C_METER_TICK_OFFSET 0 +#define RTL8367C_METER_TICK_MASK 0xFF + +#define RTL8367C_REG_METER_CTRL1 0x1701 +#define RTL8367C_METER_CTRL1_OFFSET 0 +#define RTL8367C_METER_CTRL1_MASK 0xFF + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR0 0x1702 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR1 0x1703 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR0_8051 0x1704 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR1_8051 0x1705 + +#define RTL8367C_REG_METER_IFG_CTRL0 0x1712 +#define RTL8367C_METER15_IFG_OFFSET 15 +#define RTL8367C_METER15_IFG_MASK 0x8000 +#define RTL8367C_METER14_IFG_OFFSET 14 +#define RTL8367C_METER14_IFG_MASK 0x4000 +#define RTL8367C_METER13_IFG_OFFSET 13 +#define RTL8367C_METER13_IFG_MASK 0x2000 +#define RTL8367C_METER12_IFG_OFFSET 12 +#define RTL8367C_METER12_IFG_MASK 0x1000 +#define RTL8367C_METER11_IFG_OFFSET 11 +#define RTL8367C_METER11_IFG_MASK 0x800 +#define RTL8367C_METER10_IFG_OFFSET 10 +#define RTL8367C_METER10_IFG_MASK 0x400 +#define RTL8367C_METER9_IFG_OFFSET 9 +#define RTL8367C_METER9_IFG_MASK 0x200 +#define RTL8367C_METER8_IFG_OFFSET 8 +#define RTL8367C_METER8_IFG_MASK 0x100 +#define RTL8367C_METER7_IFG_OFFSET 7 +#define RTL8367C_METER7_IFG_MASK 0x80 +#define RTL8367C_METER6_IFG_OFFSET 6 +#define RTL8367C_METER6_IFG_MASK 0x40 +#define RTL8367C_METER5_IFG_OFFSET 5 +#define RTL8367C_METER5_IFG_MASK 0x20 +#define RTL8367C_METER4_IFG_OFFSET 4 +#define RTL8367C_METER4_IFG_MASK 0x10 +#define RTL8367C_METER3_IFG_OFFSET 3 +#define RTL8367C_METER3_IFG_MASK 0x8 +#define RTL8367C_METER2_IFG_OFFSET 2 +#define RTL8367C_METER2_IFG_MASK 0x4 +#define RTL8367C_METER1_IFG_OFFSET 1 +#define RTL8367C_METER1_IFG_MASK 0x2 +#define RTL8367C_METER0_IFG_OFFSET 0 +#define RTL8367C_METER0_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_IFG_CTRL1 0x1713 +#define RTL8367C_METER31_IFG_OFFSET 15 +#define RTL8367C_METER31_IFG_MASK 0x8000 +#define RTL8367C_METER30_IFG_OFFSET 14 +#define RTL8367C_METER30_IFG_MASK 0x4000 +#define RTL8367C_METER29_IFG_OFFSET 13 +#define RTL8367C_METER29_IFG_MASK 0x2000 +#define RTL8367C_METER28_IFG_OFFSET 12 +#define RTL8367C_METER28_IFG_MASK 0x1000 +#define RTL8367C_METER27_IFG_OFFSET 11 +#define RTL8367C_METER27_IFG_MASK 0x800 +#define RTL8367C_METER26_IFG_OFFSET 10 +#define RTL8367C_METER26_IFG_MASK 0x400 +#define RTL8367C_METER25_IFG_OFFSET 9 +#define RTL8367C_METER25_IFG_MASK 0x200 +#define RTL8367C_METER24_IFG_OFFSET 8 +#define RTL8367C_METER24_IFG_MASK 0x100 +#define RTL8367C_METER23_IFG_OFFSET 7 +#define RTL8367C_METER23_IFG_MASK 0x80 +#define RTL8367C_METER22_IFG_OFFSET 6 +#define RTL8367C_METER22_IFG_MASK 0x40 +#define RTL8367C_METER21_IFG_OFFSET 5 +#define RTL8367C_METER21_IFG_MASK 0x20 +#define RTL8367C_METER20_IFG_OFFSET 4 +#define RTL8367C_METER20_IFG_MASK 0x10 +#define RTL8367C_METER19_IFG_OFFSET 3 +#define RTL8367C_METER19_IFG_MASK 0x8 +#define RTL8367C_METER18_IFG_OFFSET 2 +#define RTL8367C_METER18_IFG_MASK 0x4 +#define RTL8367C_METER17_IFG_OFFSET 1 +#define RTL8367C_METER17_IFG_MASK 0x2 +#define RTL8367C_METER16_IFG_OFFSET 0 +#define RTL8367C_METER16_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_CTRL2 0x1722 +#define RTL8367C_cfg_mtr_tick_8g_OFFSET 8 +#define RTL8367C_cfg_mtr_tick_8g_MASK 0xFF00 +#define RTL8367C_cfg_mtr_dec_cnt_8g_OFFSET 0 +#define RTL8367C_cfg_mtr_dec_cnt_8g_MASK 0xFF + +#define RTL8367C_REG_DUMMY_1723 0x1723 + +#define RTL8367C_REG_DUMMY_1724 0x1724 + +#define RTL8367C_REG_DUMMY_1725 0x1725 + +#define RTL8367C_REG_DUMMY_1726 0x1726 + +#define RTL8367C_REG_DUMMY_1727 0x1727 + +#define RTL8367C_REG_DUMMY_1728 0x1728 + +#define RTL8367C_REG_DUMMY_1729 0x1729 + +#define RTL8367C_REG_DUMMY_172A 0x172a + +#define RTL8367C_REG_DUMMY_172B 0x172b + +#define RTL8367C_REG_DUMMY_172C 0x172c + +#define RTL8367C_REG_DUMMY_172D 0x172d + +#define RTL8367C_REG_DUMMY_172E 0x172e + +#define RTL8367C_REG_DUMMY_172F 0x172f + +#define RTL8367C_REG_DUMMY_1730 0x1730 + +#define RTL8367C_REG_DUMMY_1731 0x1731 + +#define RTL8367C_REG_METER32_RATE_CTRL0 0x1740 + +#define RTL8367C_REG_METER32_RATE_CTRL1 0x1741 +#define RTL8367C_METER32_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER32_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER33_RATE_CTRL0 0x1742 + +#define RTL8367C_REG_METER33_RATE_CTRL1 0x1743 +#define RTL8367C_METER33_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER33_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER34_RATE_CTRL0 0x1744 + +#define RTL8367C_REG_METER34_RATE_CTRL1 0x1745 +#define RTL8367C_METER34_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER34_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER35_RATE_CTRL0 0x1746 + +#define RTL8367C_REG_METER35_RATE_CTRL1 0x1747 +#define RTL8367C_METER35_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER35_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER36_RATE_CTRL0 0x1748 + +#define RTL8367C_REG_METER36_RATE_CTRL1 0x1749 +#define RTL8367C_METER36_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER36_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER37_RATE_CTRL0 0x174a + +#define RTL8367C_REG_METER37_RATE_CTRL1 0x174b +#define RTL8367C_METER37_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER37_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER38_RATE_CTRL0 0x174c + +#define RTL8367C_REG_METER38_RATE_CTRL1 0x174d +#define RTL8367C_METER38_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER38_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER39_RATE_CTRL0 0x174e + +#define RTL8367C_REG_METER39_RATE_CTRL1 0x174f +#define RTL8367C_METER39_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER39_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER40_RATE_CTRL0 0x1750 + +#define RTL8367C_REG_METER40_RATE_CTRL1 0x1751 +#define RTL8367C_METER40_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER40_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER41_RATE_CTRL0 0x1752 + +#define RTL8367C_REG_METER41_RATE_CTRL1 0x1753 +#define RTL8367C_METER41_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER41_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER42_RATE_CTRL0 0x1754 + +#define RTL8367C_REG_METER42_RATE_CTRL1 0x1755 +#define RTL8367C_METER42_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER42_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER43_RATE_CTRL0 0x1756 + +#define RTL8367C_REG_METER43_RATE_CTRL1 0x1757 +#define RTL8367C_METER43_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER43_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER44_RATE_CTRL0 0x1758 + +#define RTL8367C_REG_METER44_RATE_CTRL1 0x1759 +#define RTL8367C_METER44_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER44_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER45_RATE_CTRL0 0x175a + +#define RTL8367C_REG_METER45_RATE_CTRL1 0x175b +#define RTL8367C_METER45_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER45_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER46_RATE_CTRL0 0x175c + +#define RTL8367C_REG_METER46_RATE_CTRL1 0x175d +#define RTL8367C_METER46_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER46_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER47_RATE_CTRL0 0x175e + +#define RTL8367C_REG_METER47_RATE_CTRL1 0x175f +#define RTL8367C_METER47_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER47_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER48_RATE_CTRL0 0x1760 + +#define RTL8367C_REG_METER48_RATE_CTRL1 0x1761 +#define RTL8367C_METER48_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER48_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER49_RATE_CTRL0 0x1762 + +#define RTL8367C_REG_METER49_RATE_CTRL1 0x1763 +#define RTL8367C_METER49_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER49_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER50_RATE_CTRL0 0x1764 + +#define RTL8367C_REG_METER50_RATE_CTRL1 0x1765 +#define RTL8367C_METER50_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER50_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER51_RATE_CTRL0 0x1766 + +#define RTL8367C_REG_METER51_RATE_CTRL1 0x1767 +#define RTL8367C_METER51_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER51_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER52_RATE_CTRL0 0x1768 + +#define RTL8367C_REG_METER52_RATE_CTRL1 0x1769 +#define RTL8367C_METER52_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER52_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER53_RATE_CTRL0 0x176a + +#define RTL8367C_REG_METER53_RATE_CTRL1 0x176b +#define RTL8367C_METER53_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER53_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER54_RATE_CTRL0 0x176c + +#define RTL8367C_REG_METER54_RATE_CTRL1 0x176d +#define RTL8367C_METER54_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER54_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER55_RATE_CTRL0 0x176e + +#define RTL8367C_REG_METER55_RATE_CTRL1 0x176f +#define RTL8367C_METER55_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER55_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER56_RATE_CTRL0 0x1770 + +#define RTL8367C_REG_METER56_RATE_CTRL1 0x1771 +#define RTL8367C_METER56_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER56_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER57_RATE_CTRL0 0x1772 + +#define RTL8367C_REG_METER57_RATE_CTRL1 0x1773 +#define RTL8367C_METER57_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER57_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER58_RATE_CTRL0 0x1774 + +#define RTL8367C_REG_METER58_RATE_CTRL1 0x1775 +#define RTL8367C_METER58_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER58_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER59_RATE_CTRL0 0x1776 + +#define RTL8367C_REG_METER59_RATE_CTRL1 0x1777 +#define RTL8367C_METER59_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER59_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER60_RATE_CTRL0 0x1778 + +#define RTL8367C_REG_METER60_RATE_CTRL1 0x1779 +#define RTL8367C_METER60_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER60_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER61_RATE_CTRL0 0x177a + +#define RTL8367C_REG_METER61_RATE_CTRL1 0x177b +#define RTL8367C_METER61_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER61_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER62_RATE_CTRL0 0x177c + +#define RTL8367C_REG_METER62_RATE_CTRL1 0x177d +#define RTL8367C_METER62_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER62_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER63_RATE_CTRL0 0x177e + +#define RTL8367C_REG_METER63_RATE_CTRL1 0x177f +#define RTL8367C_METER63_RATE_CTRL1_OFFSET 0 +#define RTL8367C_METER63_RATE_CTRL1_MASK 0x7 + +#define RTL8367C_REG_METER_MODE_SETTING2 0x1780 + +#define RTL8367C_REG_METER_MODE_SETTING3 0x1781 + +#define RTL8367C_REG_METER32_BUCKET_SIZE 0x1790 + +#define RTL8367C_REG_METER33_BUCKET_SIZE 0x1791 + +#define RTL8367C_REG_METER34_BUCKET_SIZE 0x1792 + +#define RTL8367C_REG_METER35_BUCKET_SIZE 0x1793 + +#define RTL8367C_REG_METER36_BUCKET_SIZE 0x1794 + +#define RTL8367C_REG_METER37_BUCKET_SIZE 0x1795 + +#define RTL8367C_REG_METER38_BUCKET_SIZE 0x1796 + +#define RTL8367C_REG_METER39_BUCKET_SIZE 0x1797 + +#define RTL8367C_REG_METER40_BUCKET_SIZE 0x1798 + +#define RTL8367C_REG_METER41_BUCKET_SIZE 0x1799 + +#define RTL8367C_REG_METER42_BUCKET_SIZE 0x179a + +#define RTL8367C_REG_METER43_BUCKET_SIZE 0x179b + +#define RTL8367C_REG_METER44_BUCKET_SIZE 0x179c + +#define RTL8367C_REG_METER45_BUCKET_SIZE 0x179d + +#define RTL8367C_REG_METER46_BUCKET_SIZE 0x179e + +#define RTL8367C_REG_METER47_BUCKET_SIZE 0x179f + +#define RTL8367C_REG_METER48_BUCKET_SIZE 0x17a0 + +#define RTL8367C_REG_METER49_BUCKET_SIZE 0x17a1 + +#define RTL8367C_REG_METER50_BUCKET_SIZE 0x17a2 + +#define RTL8367C_REG_METER51_BUCKET_SIZE 0x17a3 + +#define RTL8367C_REG_METER52_BUCKET_SIZE 0x17a4 + +#define RTL8367C_REG_METER53_BUCKET_SIZE 0x17a5 + +#define RTL8367C_REG_METER54_BUCKET_SIZE 0x17a6 + +#define RTL8367C_REG_METER55_BUCKET_SIZE 0x17a7 + +#define RTL8367C_REG_METER56_BUCKET_SIZE 0x17a8 + +#define RTL8367C_REG_METER57_BUCKET_SIZE 0x17a9 + +#define RTL8367C_REG_METER58_BUCKET_SIZE 0x17aa + +#define RTL8367C_REG_METER59_BUCKET_SIZE 0x17ab + +#define RTL8367C_REG_METER60_BUCKET_SIZE 0x17ac + +#define RTL8367C_REG_METER61_BUCKET_SIZE 0x17ad + +#define RTL8367C_REG_METER62_BUCKET_SIZE 0x17ae + +#define RTL8367C_REG_METER63_BUCKET_SIZE 0x17af + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR2 0x17b0 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR3 0x17b1 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR2_8051 0x17b2 + +#define RTL8367C_REG_METER_OVERRATE_INDICATOR3_8051 0x17b3 + +#define RTL8367C_REG_METER_IFG_CTRL2 0x17b4 +#define RTL8367C_METER47_IFG_OFFSET 15 +#define RTL8367C_METER47_IFG_MASK 0x8000 +#define RTL8367C_METER46_IFG_OFFSET 14 +#define RTL8367C_METER46_IFG_MASK 0x4000 +#define RTL8367C_METER45_IFG_OFFSET 13 +#define RTL8367C_METER45_IFG_MASK 0x2000 +#define RTL8367C_METER44_IFG_OFFSET 12 +#define RTL8367C_METER44_IFG_MASK 0x1000 +#define RTL8367C_METER43_IFG_OFFSET 11 +#define RTL8367C_METER43_IFG_MASK 0x800 +#define RTL8367C_METER42_IFG_OFFSET 10 +#define RTL8367C_METER42_IFG_MASK 0x400 +#define RTL8367C_METER41_IFG_OFFSET 9 +#define RTL8367C_METER41_IFG_MASK 0x200 +#define RTL8367C_METER40_IFG_OFFSET 8 +#define RTL8367C_METER40_IFG_MASK 0x100 +#define RTL8367C_METER39_IFG_OFFSET 7 +#define RTL8367C_METER39_IFG_MASK 0x80 +#define RTL8367C_METER38_IFG_OFFSET 6 +#define RTL8367C_METER38_IFG_MASK 0x40 +#define RTL8367C_METER37_IFG_OFFSET 5 +#define RTL8367C_METER37_IFG_MASK 0x20 +#define RTL8367C_METER36_IFG_OFFSET 4 +#define RTL8367C_METER36_IFG_MASK 0x10 +#define RTL8367C_METER35_IFG_OFFSET 3 +#define RTL8367C_METER35_IFG_MASK 0x8 +#define RTL8367C_METER34_IFG_OFFSET 2 +#define RTL8367C_METER34_IFG_MASK 0x4 +#define RTL8367C_METER33_IFG_OFFSET 1 +#define RTL8367C_METER33_IFG_MASK 0x2 +#define RTL8367C_METER32_IFG_OFFSET 0 +#define RTL8367C_METER32_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_IFG_CTRL3 0x17b5 +#define RTL8367C_METER63_IFG_OFFSET 15 +#define RTL8367C_METER63_IFG_MASK 0x8000 +#define RTL8367C_METER62_IFG_OFFSET 14 +#define RTL8367C_METER62_IFG_MASK 0x4000 +#define RTL8367C_METER61_IFG_OFFSET 13 +#define RTL8367C_METER61_IFG_MASK 0x2000 +#define RTL8367C_METER60_IFG_OFFSET 12 +#define RTL8367C_METER60_IFG_MASK 0x1000 +#define RTL8367C_METER59_IFG_OFFSET 11 +#define RTL8367C_METER59_IFG_MASK 0x800 +#define RTL8367C_METER58_IFG_OFFSET 10 +#define RTL8367C_METER58_IFG_MASK 0x400 +#define RTL8367C_METER57_IFG_OFFSET 9 +#define RTL8367C_METER57_IFG_MASK 0x200 +#define RTL8367C_METER56_IFG_OFFSET 8 +#define RTL8367C_METER56_IFG_MASK 0x100 +#define RTL8367C_METER55_IFG_OFFSET 7 +#define RTL8367C_METER55_IFG_MASK 0x80 +#define RTL8367C_METER54_IFG_OFFSET 6 +#define RTL8367C_METER54_IFG_MASK 0x40 +#define RTL8367C_METER53_IFG_OFFSET 5 +#define RTL8367C_METER53_IFG_MASK 0x20 +#define RTL8367C_METER52_IFG_OFFSET 4 +#define RTL8367C_METER52_IFG_MASK 0x10 +#define RTL8367C_METER51_IFG_OFFSET 3 +#define RTL8367C_METER51_IFG_MASK 0x8 +#define RTL8367C_METER50_IFG_OFFSET 2 +#define RTL8367C_METER50_IFG_MASK 0x4 +#define RTL8367C_METER49_IFG_OFFSET 1 +#define RTL8367C_METER49_IFG_MASK 0x2 +#define RTL8367C_METER48_IFG_OFFSET 0 +#define RTL8367C_METER48_IFG_MASK 0x1 + +#define RTL8367C_REG_METER_MISC 0x17b6 +#define RTL8367C_METER_MISC_OFFSET 0 +#define RTL8367C_METER_MISC_MASK 0x1 + +/* (16'h1800)8051_RLDP_EEE_reg */ + +#define RTL8367C_REG_EEELLDP_CTRL0 0x1820 +#define RTL8367C_EEELLDP_SUBTYPE_OFFSET 6 +#define RTL8367C_EEELLDP_SUBTYPE_MASK 0x3FC0 +#define RTL8367C_EEELLDP_TRAP_8051_OFFSET 2 +#define RTL8367C_EEELLDP_TRAP_8051_MASK 0x4 +#define RTL8367C_EEELLDP_TRAP_CPU_OFFSET 1 +#define RTL8367C_EEELLDP_TRAP_CPU_MASK 0x2 +#define RTL8367C_EEELLDP_ENABLE_OFFSET 0 +#define RTL8367C_EEELLDP_ENABLE_MASK 0x1 + +#define RTL8367C_REG_EEELLDP_PMSK 0x1822 +#define RTL8367C_EEELLDP_PMSK_OFFSET 0 +#define RTL8367C_EEELLDP_PMSK_MASK 0x7FF + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_08 0x1843 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_07 0x1844 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_06 0x1845 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_05 0x1846 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_04 0x1847 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_03 0x1848 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_02 0x1849 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_01 0x184a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 0x184b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_08 0x184c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_07 0x184d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_06 0x184e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_05 0x184f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_04 0x1850 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_03 0x1851 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_02 0x1852 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_01 0x1853 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_00 0x1854 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_08 0x1855 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_07 0x1856 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_06 0x1857 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_05 0x1858 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_04 0x1859 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_03 0x185a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_02 0x185b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_01 0x185c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_00 0x185d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_08 0x185e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_07 0x185f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_06 0x1860 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_05 0x1861 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_04 0x1862 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_03 0x1863 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_02 0x1864 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_01 0x1865 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_00 0x1866 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_08 0x1867 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_07 0x1868 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_06 0x1869 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_05 0x186a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_04 0x186b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_03 0x186c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_02 0x186d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_01 0x186e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_00 0x186f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_08 0x1870 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_07 0x1871 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_06 0x1872 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_05 0x1873 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_04 0x1874 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_03 0x1875 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_02 0x1876 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_01 0x1877 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_00 0x1878 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_08 0x1879 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_07 0x187a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_06 0x187b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_05 0x187c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_04 0x187d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_03 0x187e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_02 0x187f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_01 0x1880 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_00 0x1881 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_08 0x1882 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_07 0x1883 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_06 0x1884 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_05 0x1885 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_04 0x1886 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_03 0x1887 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_02 0x1888 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_01 0x1889 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_00 0x188a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_08 0x188b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_07 0x188c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_06 0x188d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_05 0x188e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_04 0x188f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_03 0x1890 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_02 0x1891 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_01 0x1892 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_00 0x1893 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_08 0x1894 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_07 0x1895 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_06 0x1896 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_05 0x1897 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_04 0x1898 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_03 0x1899 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_02 0x189a + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_01 0x189b + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_00 0x189c + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_08 0x189d + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_07 0x189e + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_06 0x189f + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_05 0x18a0 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_04 0x18a1 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_03 0x18a2 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_02 0x18a3 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_01 0x18a4 + +#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_00 0x18a5 + +#define RTL8367C_REG_RLDP_CTRL0 0x18e0 +#define RTL8367C_RLDP_TRIGGER_MODE_OFFSET 14 +#define RTL8367C_RLDP_TRIGGER_MODE_MASK 0x4000 +#define RTL8367C_RLDP_8051_LOOP_PORTMSK_OFFSET 6 +#define RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK 0x3FC0 +#define RTL8367C_RLPP_8051_TRAP_OFFSET 5 +#define RTL8367C_RLPP_8051_TRAP_MASK 0x20 +#define RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET 4 +#define RTL8367C_RLDP_INDICATOR_SOURCE_MASK 0x10 +#define RTL8367C_RLDP_GEN_RANDOM_OFFSET 3 +#define RTL8367C_RLDP_GEN_RANDOM_MASK 0x8 +#define RTL8367C_RLDP_COMP_ID_OFFSET 2 +#define RTL8367C_RLDP_COMP_ID_MASK 0x4 +#define RTL8367C_RLDP_8051_ENABLE_OFFSET 1 +#define RTL8367C_RLDP_8051_ENABLE_MASK 0x2 +#define RTL8367C_RLDP_ENABLE_OFFSET 0 +#define RTL8367C_RLDP_ENABLE_MASK 0x1 + +#define RTL8367C_REG_RLDP_CTRL1 0x18e1 +#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_OFFSET 8 +#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK 0xFF00 +#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_OFFSET 0 +#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK 0xFF + +#define RTL8367C_REG_RLDP_CTRL2 0x18e2 + +#define RTL8367C_REG_RLDP_CTRL3 0x18e3 + +#define RTL8367C_REG_RLDP_CTRL4 0x18e4 +#define RTL8367C_RLDP_CTRL4_OFFSET 0 +#define RTL8367C_RLDP_CTRL4_MASK 0x7FF + +#define RTL8367C_REG_RLDP_RAND_NUM0 0x18e5 + +#define RTL8367C_REG_RLDP_RAND_NUM1 0x18e6 + +#define RTL8367C_REG_RLDP_RAND_NUM2 0x18e7 + +#define RTL8367C_REG_RLDP_MAGIC_NUM0 0x18e8 + +#define RTL8367C_REG_RLDP_MAGIC_NUM1 0x18e9 + +#define RTL8367C_REG_RLDP_MAGIC_NUM2 0x18ea + +#define RTL8367C_REG_RLDP_LOOPED_INDICATOR 0x18eb +#define RTL8367C_RLDP_LOOPED_INDICATOR_OFFSET 0 +#define RTL8367C_RLDP_LOOPED_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG0 0x18ec +#define RTL8367C_RLDP_LOOP_PORT_01_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_01_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_00_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_00_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG1 0x18ed +#define RTL8367C_RLDP_LOOP_PORT_03_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_03_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_02_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_02_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG2 0x18ee +#define RTL8367C_RLDP_LOOP_PORT_05_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_05_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_04_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_04_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG3 0x18ef +#define RTL8367C_RLDP_LOOP_PORT_07_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_07_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_06_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_06_MASK 0xF + +#define RTL8367C_REG_RLDP_RELEASED_INDICATOR 0x18f0 +#define RTL8367C_RLDP_RELEASED_INDICATOR_OFFSET 0 +#define RTL8367C_RLDP_RELEASED_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR 0x18f1 +#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_OFFSET 0 +#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_MASK 0x7FF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG4 0x18f2 +#define RTL8367C_RLDP_LOOP_PORT_9_OFFSET 8 +#define RTL8367C_RLDP_LOOP_PORT_9_MASK 0xF00 +#define RTL8367C_RLDP_LOOP_PORT_8_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_8_MASK 0xF + +#define RTL8367C_REG_RLDP_LOOP_PORT_REG5 0x18f3 +#define RTL8367C_RLDP_LOOP_PORT_REG5_OFFSET 0 +#define RTL8367C_RLDP_LOOP_PORT_REG5_MASK 0xF + +#define RTL8367C_REG_RLDP_CTRL5 0x18f4 +#define RTL8367C_RLDP_CTRL5_OFFSET 0 +#define RTL8367C_RLDP_CTRL5_MASK 0x7 + +/* (16'h1900)EEE_EEEP_reg */ + +#define RTL8367C_REG_EEE_500M_CTRL0 0x1900 +#define RTL8367C_EEE_500M_CTRL0_OFFSET 0 +#define RTL8367C_EEE_500M_CTRL0_MASK 0xFF + +#define RTL8367C_REG_EEE_RXIDLE_GIGA_CTRL 0x1901 +#define RTL8367C_EEE_RXIDLE_GIGA_EN_OFFSET 8 +#define RTL8367C_EEE_RXIDLE_GIGA_EN_MASK 0x100 +#define RTL8367C_EEE_RXIDLE_GIGA_OFFSET 0 +#define RTL8367C_EEE_RXIDLE_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEE_RXIDLE_500M_CTRL 0x1902 +#define RTL8367C_EEE_RXIDLE_500M_EN_OFFSET 8 +#define RTL8367C_EEE_RXIDLE_500M_EN_MASK 0x100 +#define RTL8367C_EEE_RXIDLE_500M_OFFSET 0 +#define RTL8367C_EEE_RXIDLE_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_DECISION_GIGA_500M 0x1903 +#define RTL8367C_EEE_DECISION_GIGA_OFFSET 8 +#define RTL8367C_EEE_DECISION_GIGA_MASK 0xFF00 +#define RTL8367C_EEE_DECISION_500M_OFFSET 0 +#define RTL8367C_EEE_DECISION_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_DECISION_100M 0x1904 +#define RTL8367C_EEE_DECISION_100M_OFFSET 0 +#define RTL8367C_EEE_DECISION_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_DEFER_TXLPI 0x1905 +#define RTL8367C_EEEP_DEFER_TXLPI_OFFSET 0 +#define RTL8367C_EEEP_DEFER_TXLPI_MASK 0x1 + +#define RTL8367C_REG_EEEP_EN 0x1906 +#define RTL8367C_EEEP_SLAVE_EN_OFFSET 3 +#define RTL8367C_EEEP_SLAVE_EN_MASK 0x8 +#define RTL8367C_EEEP_100M_OFFSET 2 +#define RTL8367C_EEEP_100M_MASK 0x4 +#define RTL8367C_EEEP_500M_OFFSET 1 +#define RTL8367C_EEEP_500M_MASK 0x2 +#define RTL8367C_EEEP_GIGA_OFFSET 0 +#define RTL8367C_EEEP_GIGA_MASK 0x1 + +#define RTL8367C_REG_EEEP_TI_GIGA_500M 0x1907 +#define RTL8367C_EEEP_TI_GIGA_OFFSET 8 +#define RTL8367C_EEEP_TI_GIGA_MASK 0xFF00 +#define RTL8367C_EEEP_TI_500M_OFFSET 0 +#define RTL8367C_EEEP_TI_500M_MASK 0xFF + +#define RTL8367C_REG_EEEP_TI_100M 0x1908 +#define RTL8367C_EEEP_TI_100M_OFFSET 0 +#define RTL8367C_EEEP_TI_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_CTRL2 0x1909 +#define RTL8367C_EEEP_CTRL2_OFFSET 0 +#define RTL8367C_EEEP_CTRL2_MASK 0xFF + +#define RTL8367C_REG_EEEP_RX_RATE_500M 0x190b + +#define RTL8367C_REG_EEEP_RW_GIGA_SLV 0x190c +#define RTL8367C_EEEP_RW_GIGA_SLV_OFFSET 0 +#define RTL8367C_EEEP_RW_GIGA_SLV_MASK 0xFF + +#define RTL8367C_REG_EEEP_TMR_GIGA 0x190d +#define RTL8367C_RX_IDLE_EEEP_GIGA_OFFSET 8 +#define RTL8367C_RX_IDLE_EEEP_GIGA_MASK 0xFF00 +#define RTL8367C_RX_MIN_SLP_TMR_GIGA_OFFSET 0 +#define RTL8367C_RX_MIN_SLP_TMR_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEEP_TMR_500M 0x190e +#define RTL8367C_RX_IDLE_EEEP_500M_OFFSET 8 +#define RTL8367C_RX_IDLE_EEEP_500M_MASK 0xFF00 +#define RTL8367C_RX_MIN_SLP_TMR_500M_OFFSET 0 +#define RTL8367C_RX_MIN_SLP_TMR_500M_MASK 0xFF + +#define RTL8367C_REG_EEEP_TMR_100M 0x190f +#define RTL8367C_RX_IDLE_EEEP_100M_OFFSET 8 +#define RTL8367C_RX_IDLE_EEEP_100M_MASK 0xFF00 +#define RTL8367C_RX_MIN_SLP_TMR_100M_OFFSET 0 +#define RTL8367C_RX_MIN_SLP_TMR_100M_MASK 0xFF + +#define RTL8367C_REG_EEEP_RW_500M_MST_SLV 0x1910 +#define RTL8367C_EEEP_RW_500M_MST_OFFSET 8 +#define RTL8367C_EEEP_RW_500M_MST_MASK 0xFF00 +#define RTL8367C_EEEP_RW_500M_SLV_OFFSET 0 +#define RTL8367C_EEEP_RW_500M_SLV_MASK 0xFF + +#define RTL8367C_REG_EEEP_500M_CTRL0 0x1911 +#define RTL8367C_EEEP_500M_CTRL0_OFFSET 0 +#define RTL8367C_EEEP_500M_CTRL0_MASK 0xFF + +#define RTL8367C_REG_EEEP_500M_CTRL1 0x1912 +#define RTL8367C_EEEP_TW_500M_OFFSET 8 +#define RTL8367C_EEEP_TW_500M_MASK 0xFF00 +#define RTL8367C_EEEP_TP_500M_OFFSET 0 +#define RTL8367C_EEEP_TP_500M_MASK 0xFF + +#define RTL8367C_REG_EEEP_500M_CTRL2 0x1913 +#define RTL8367C_EEEP_TXEN_500M_OFFSET 12 +#define RTL8367C_EEEP_TXEN_500M_MASK 0x1000 +#define RTL8367C_EEEP_TU_500M_OFFSET 8 +#define RTL8367C_EEEP_TU_500M_MASK 0x300 +#define RTL8367C_EEEP_TS_500M_OFFSET 0 +#define RTL8367C_EEEP_TS_500M_MASK 0xFF + +#define RTL8367C_REG_EEE_NEW_CTRL0 0x1914 +#define RTL8367C_LINK_UP_DELAY_OFFSET 3 +#define RTL8367C_LINK_UP_DELAY_MASK 0x18 +#define RTL8367C_EEE_TXLPI_ORI_OFFSET 2 +#define RTL8367C_EEE_TXLPI_ORI_MASK 0x4 +#define RTL8367C_REALTX_SEL_OFFSET 1 +#define RTL8367C_REALTX_SEL_MASK 0x2 +#define RTL8367C_EN_FC_EFCT_OFFSET 0 +#define RTL8367C_EN_FC_EFCT_MASK 0x1 + +#define RTL8367C_REG_EEE_LONGIDLE_100M 0x1915 +#define RTL8367C_EEE_LONGIDLE_100M_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_100M_MASK 0x3FF + +#define RTL8367C_REG_EEE_LONGIDLE_500M 0x1916 +#define RTL8367C_EEE_LONGIDLE_500M_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_500M_MASK 0x3FF + +#define RTL8367C_REG_EEE_LONGIDLE_GIGA 0x1917 +#define RTL8367C_EEE_LONGIDLE_GIGA_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_GIGA_MASK 0x3FF + +#define RTL8367C_REG_EEE_MINIPG_100M 0x1918 + +#define RTL8367C_REG_EEE_MINIPG_500M 0x1919 + +#define RTL8367C_REG_EEE_MINIPG_GIGA 0x191A + +#define RTL8367C_REG_EEE_LONGIDLE_CTRL0 0x191B +#define RTL8367C_TX_IDLEN_REQ_100M_OFFSET 10 +#define RTL8367C_TX_IDLEN_REQ_100M_MASK 0x400 +#define RTL8367C_TX_IDLEN_REQ_500M_OFFSET 9 +#define RTL8367C_TX_IDLEN_REQ_500M_MASK 0x200 +#define RTL8367C_TX_IDLEN_REQ_GIGA_OFFSET 8 +#define RTL8367C_TX_IDLEN_REQ_GIGA_MASK 0x100 +#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_MASK 0xFF + +#define RTL8367C_REG_EEE_LONGIDLE_CTRL1 0x191C +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_OFFSET 8 +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_MASK 0xFF00 +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_OFFSET 0 +#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_MASK 0xFF + +#define RTL8367C_REG_EEE_TD_CTRL_H 0x191d +#define RTL8367C_REF_RXLPI_OFFSET 8 +#define RTL8367C_REF_RXLPI_MASK 0x100 +#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_OFFSET 4 +#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_MASK 0xF0 +#define RTL8367C_LOW_Q_TX_DELAY_FE_H_OFFSET 0 +#define RTL8367C_LOW_Q_TX_DELAY_FE_H_MASK 0xF + +/* (16'h1a00)nic_reg */ + +#define RTL8367C_REG_NIC_RXRDRL 0x1a04 +#define RTL8367C_NIC_RXRDRL_OFFSET 0 +#define RTL8367C_NIC_RXRDRL_MASK 0xFF + +#define RTL8367C_REG_NIC_RXRDRH 0x1a05 +#define RTL8367C_NIC_RXRDRH_OFFSET 0 +#define RTL8367C_NIC_RXRDRH_MASK 0xFF + +#define RTL8367C_REG_NIC_TXASRL 0x1a08 +#define RTL8367C_NIC_TXASRL_OFFSET 0 +#define RTL8367C_NIC_TXASRL_MASK 0xFF + +#define RTL8367C_REG_NIC_TXASRH 0x1a09 +#define RTL8367C_NIC_TXASRH_OFFSET 0 +#define RTL8367C_NIC_TXASRH_MASK 0xFF + +#define RTL8367C_REG_NIC_RXCMDR 0x1a0c +#define RTL8367C_NIC_RXCMDR_OFFSET 0 +#define RTL8367C_NIC_RXCMDR_MASK 0x1 + +#define RTL8367C_REG_NIC_TXCMDR 0x1a0d +#define RTL8367C_NIC_TXCMDR_OFFSET 0 +#define RTL8367C_NIC_TXCMDR_MASK 0x1 + +#define RTL8367C_REG_NIC_IMS 0x1a0e +#define RTL8367C_NIC_RXIS_OFFSET 7 +#define RTL8367C_NIC_RXIS_MASK 0x80 +#define RTL8367C_NIC_TXIS_OFFSET 6 +#define RTL8367C_NIC_TXIS_MASK 0x40 +#define RTL8367C_NIC_TXES_OFFSET 5 +#define RTL8367C_NIC_TXES_MASK 0x20 +#define RTL8367C_NIC_IMS_DMY_OFFSET 4 +#define RTL8367C_NIC_IMS_DMY_MASK 0x10 +#define RTL8367C_NIC_RXBUS_OFFSET 3 +#define RTL8367C_NIC_RXBUS_MASK 0x8 +#define RTL8367C_NIC_TXBOS_OFFSET 2 +#define RTL8367C_NIC_TXBOS_MASK 0x4 +#define RTL8367C_NIC_RXMIS_OFFSET 1 +#define RTL8367C_NIC_RXMIS_MASK 0x2 +#define RTL8367C_NIC_TXNLS_OFFSET 0 +#define RTL8367C_NIC_TXNLS_MASK 0x1 + +#define RTL8367C_REG_NIC_IMR 0x1a0f +#define RTL8367C_NIC_RXIE_OFFSET 7 +#define RTL8367C_NIC_RXIE_MASK 0x80 +#define RTL8367C_NIC_TXIE_OFFSET 6 +#define RTL8367C_NIC_TXIE_MASK 0x40 +#define RTL8367C_NIC_TXEE_OFFSET 5 +#define RTL8367C_NIC_TXEE_MASK 0x20 +#define RTL8367C_NIC_IMR_DMY_OFFSET 4 +#define RTL8367C_NIC_IMR_DMY_MASK 0x10 +#define RTL8367C_NIC_RXBUE_OFFSET 3 +#define RTL8367C_NIC_RXBUE_MASK 0x8 +#define RTL8367C_NIC_TXBOE_OFFSET 2 +#define RTL8367C_NIC_TXBOE_MASK 0x4 +#define RTL8367C_NIC_RXMIE_OFFSET 1 +#define RTL8367C_NIC_RXMIE_MASK 0x2 +#define RTL8367C_NIC_TXNLE_OFFSET 0 +#define RTL8367C_NIC_TXNLE_MASK 0x1 + +#define RTL8367C_REG_NIC_RXCR0 0x1a14 +#define RTL8367C_NIC_HFPPE_OFFSET 7 +#define RTL8367C_NIC_HFPPE_MASK 0x80 +#define RTL8367C_NIC_HFMPE_OFFSET 6 +#define RTL8367C_NIC_HFMPE_MASK 0x40 +#define RTL8367C_NIC_RXBPE_OFFSET 5 +#define RTL8367C_NIC_RXBPE_MASK 0x20 +#define RTL8367C_NIC_RXMPE_OFFSET 4 +#define RTL8367C_NIC_RXMPE_MASK 0x10 +#define RTL8367C_NIC_RXPPS_OFFSET 2 +#define RTL8367C_NIC_RXPPS_MASK 0xC +#define RTL8367C_NIC_RXAPE_OFFSET 1 +#define RTL8367C_NIC_RXAPE_MASK 0x2 +#define RTL8367C_NIC_ARPPE_OFFSET 0 +#define RTL8367C_NIC_ARPPE_MASK 0x1 + +#define RTL8367C_REG_NIC_RXCR1 0x1a15 +#define RTL8367C_NIC_RL4CEPE_OFFSET 4 +#define RTL8367C_NIC_RL4CEPE_MASK 0x10 +#define RTL8367C_NIC_RL3CEPE_OFFSET 3 +#define RTL8367C_NIC_RL3CEPE_MASK 0x8 +#define RTL8367C_NIC_RCRCEPE_OFFSET 2 +#define RTL8367C_NIC_RCRCEPE_MASK 0x4 +#define RTL8367C_NIC_RMCRC_OFFSET 1 +#define RTL8367C_NIC_RMCRC_MASK 0x2 +#define RTL8367C_NIC_RXENABLE_OFFSET 0 +#define RTL8367C_NIC_RXENABLE_MASK 0x1 + +#define RTL8367C_REG_NIC_TXCR 0x1a16 +#define RTL8367C_NIC_LBE_OFFSET 2 +#define RTL8367C_NIC_LBE_MASK 0x4 +#define RTL8367C_NIC_TXMFM_OFFSET 1 +#define RTL8367C_NIC_TXMFM_MASK 0x2 +#define RTL8367C_NIC_TXENABLE_OFFSET 0 +#define RTL8367C_NIC_TXENABLE_MASK 0x1 + +#define RTL8367C_REG_NIC_GCR 0x1a17 +#define RTL8367C_DUMMY_7_6_OFFSET 6 +#define RTL8367C_DUMMY_7_6_MASK 0xC0 +#define RTL8367C_NIC_RXMTU_OFFSET 4 +#define RTL8367C_NIC_RXMTU_MASK 0x30 +#define RTL8367C_NIC_GCR_DUMMY_0_OFFSET 0 +#define RTL8367C_NIC_GCR_DUMMY_0_MASK 0x1 + +#define RTL8367C_REG_NIC_MHR0 0x1a24 +#define RTL8367C_NIC_MHR0_OFFSET 0 +#define RTL8367C_NIC_MHR0_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR1 0x1a25 +#define RTL8367C_NIC_MHR1_OFFSET 0 +#define RTL8367C_NIC_MHR1_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR2 0x1a26 +#define RTL8367C_NIC_MHR2_OFFSET 0 +#define RTL8367C_NIC_MHR2_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR3 0x1a27 +#define RTL8367C_NIC_MHR3_OFFSET 0 +#define RTL8367C_NIC_MHR3_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR4 0x1a28 +#define RTL8367C_NIC_MHR4_OFFSET 0 +#define RTL8367C_NIC_MHR4_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR5 0x1a29 +#define RTL8367C_NIC_MHR5_OFFSET 0 +#define RTL8367C_NIC_MHR5_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR6 0x1a2a +#define RTL8367C_NIC_MHR6_OFFSET 0 +#define RTL8367C_NIC_MHR6_MASK 0xFF + +#define RTL8367C_REG_NIC_MHR7 0x1a2b +#define RTL8367C_NIC_MHR7_OFFSET 0 +#define RTL8367C_NIC_MHR7_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR0 0x1a2c +#define RTL8367C_NIC_PAHR0_OFFSET 0 +#define RTL8367C_NIC_PAHR0_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR1 0x1a2d +#define RTL8367C_NIC_PAHR1_OFFSET 0 +#define RTL8367C_NIC_PAHR1_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR2 0x1a2e +#define RTL8367C_NIC_PAHR2_OFFSET 0 +#define RTL8367C_NIC_PAHR2_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR3 0x1a2f +#define RTL8367C_NIC_PAHR3_OFFSET 0 +#define RTL8367C_NIC_PAHR3_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR4 0x1a30 +#define RTL8367C_NIC_PAHR4_OFFSET 0 +#define RTL8367C_NIC_PAHR4_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR5 0x1a31 +#define RTL8367C_NIC_PAHR5_OFFSET 0 +#define RTL8367C_NIC_PAHR5_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR6 0x1a32 +#define RTL8367C_NIC_PAHR6_OFFSET 0 +#define RTL8367C_NIC_PAHR6_MASK 0xFF + +#define RTL8367C_REG_NIC_PAHR7 0x1a33 +#define RTL8367C_NIC_PAHR7_OFFSET 0 +#define RTL8367C_NIC_PAHR7_MASK 0xFF + +#define RTL8367C_REG_NIC_TXSTOPRL 0x1a44 +#define RTL8367C_NIC_TXSTOPRL_OFFSET 0 +#define RTL8367C_NIC_TXSTOPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_TXSTOPRH 0x1a45 +#define RTL8367C_NIC_TXSTOPRH_OFFSET 0 +#define RTL8367C_NIC_TXSTOPRH_MASK 0x3 + +#define RTL8367C_REG_NIC_RXSTOPRL 0x1a46 +#define RTL8367C_NIC_RXSTOPRL_OFFSET 0 +#define RTL8367C_NIC_RXSTOPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_RXSTOPRH 0x1a47 +#define RTL8367C_NIC_RXSTOPRH_OFFSET 0 +#define RTL8367C_NIC_RXSTOPRH_MASK 0x3 + +#define RTL8367C_REG_NIC_RXFSTR 0x1a48 +#define RTL8367C_NIC_RXFSTR_OFFSET 0 +#define RTL8367C_NIC_RXFSTR_MASK 0xFF + +#define RTL8367C_REG_NIC_RXMBTRL 0x1a4c +#define RTL8367C_NIC_RXMBTRL_OFFSET 0 +#define RTL8367C_NIC_RXMBTRL_MASK 0xFF + +#define RTL8367C_REG_NIC_RXMBTRH 0x1a4d +#define RTL8367C_NIC_RXMBTRH_OFFSET 0 +#define RTL8367C_NIC_RXMBTRH_MASK 0x7F + +#define RTL8367C_REG_NIC_RXMPTR 0x1a4e +#define RTL8367C_NIC_RXMPTR_OFFSET 0 +#define RTL8367C_NIC_RXMPTR_MASK 0xFF + +#define RTL8367C_REG_NIC_T0TR 0x1a4f +#define RTL8367C_NIC_T0TR_OFFSET 0 +#define RTL8367C_NIC_T0TR_MASK 0xFF + +#define RTL8367C_REG_NIC_CRXCPRL 0x1a50 +#define RTL8367C_NIC_CRXCPRL_OFFSET 0 +#define RTL8367C_NIC_CRXCPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_CRXCPRH 0x1a51 +#define RTL8367C_NIC_CRXCPRH_OFFSET 0 +#define RTL8367C_NIC_CRXCPRH_MASK 0xFF + +#define RTL8367C_REG_NIC_CTXCPRL 0x1a52 +#define RTL8367C_NIC_CTXCPRL_OFFSET 0 +#define RTL8367C_NIC_CTXCPRL_MASK 0xFF + +#define RTL8367C_REG_NIC_CTXPCRH 0x1a53 +#define RTL8367C_NIC_CTXPCRH_OFFSET 0 +#define RTL8367C_NIC_CTXPCRH_MASK 0xFF + +#define RTL8367C_REG_NIC_SRXCURPKTRL 0x1a54 +#define RTL8367C_NIC_SRXCURPKTRL_OFFSET 0 +#define RTL8367C_NIC_SRXCURPKTRL_MASK 0xFF + +#define RTL8367C_REG_NIC_SRXCURPKTRH 0x1a55 +#define RTL8367C_NIC_SRXCURPKTRH_OFFSET 0 +#define RTL8367C_NIC_SRXCURPKTRH_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURPKTRL 0x1a56 +#define RTL8367C_NIC_STXCURPKTRL_OFFSET 0 +#define RTL8367C_NIC_STXCURPKTRL_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURPKTRH 0x1a57 +#define RTL8367C_NIC_STXCURPKTRH_OFFSET 0 +#define RTL8367C_NIC_STXCURPKTRH_MASK 0xFF + +#define RTL8367C_REG_NIC_STXPKTLENRL 0x1a58 +#define RTL8367C_NIC_STXPKTLENRL_OFFSET 0 +#define RTL8367C_NIC_STXPKTLENRL_MASK 0xFF + +#define RTL8367C_REG_NIC_STXPKTLENRH 0x1a59 +#define RTL8367C_NIC_STXPKTLENRH_OFFSET 0 +#define RTL8367C_NIC_STXPKTLENRH_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURUNITRL 0x1a5a +#define RTL8367C_NIC_STXCURUNITRL_OFFSET 0 +#define RTL8367C_NIC_STXCURUNITRL_MASK 0xFF + +#define RTL8367C_REG_NIC_STXCURUNITRH 0x1a5b +#define RTL8367C_NIC_STXCURUNITRH_OFFSET 0 +#define RTL8367C_NIC_STXCURUNITRH_MASK 0xFF + +#define RTL8367C_REG_NIC_DROP_MODE 0x1a5c +#define RTL8367C_NIC_RXDV_MODE_OFFSET 1 +#define RTL8367C_NIC_RXDV_MODE_MASK 0x2 +#define RTL8367C_NIC_DROP_MODE_OFFSET 0 +#define RTL8367C_NIC_DROP_MODE_MASK 0x1 + +/* (16'h1b00)LED */ + +#define RTL8367C_REG_LED_SYS_CONFIG 0x1b00 +#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_OFFSET 15 +#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_MASK 0x8000 +#define RTL8367C_LED_SERIAL_OUT_MODE_OFFSET 14 +#define RTL8367C_LED_SERIAL_OUT_MODE_MASK 0x4000 +#define RTL8367C_LED_EEE_LPI_MODE_OFFSET 13 +#define RTL8367C_LED_EEE_LPI_MODE_MASK 0x2000 +#define RTL8367C_LED_EEE_LPI_EN_OFFSET 12 +#define RTL8367C_LED_EEE_LPI_EN_MASK 0x1000 +#define RTL8367C_LED_EEE_LPI_10_OFFSET 11 +#define RTL8367C_LED_EEE_LPI_10_MASK 0x800 +#define RTL8367C_LED_EEE_CAP_10_OFFSET 10 +#define RTL8367C_LED_EEE_CAP_10_MASK 0x400 +#define RTL8367C_LED_LPI_SEL_OFFSET 8 +#define RTL8367C_LED_LPI_SEL_MASK 0x300 +#define RTL8367C_SERI_LED_ACT_LOW_OFFSET 7 +#define RTL8367C_SERI_LED_ACT_LOW_MASK 0x80 +#define RTL8367C_LED_POWERON_2_OFFSET 6 +#define RTL8367C_LED_POWERON_2_MASK 0x40 +#define RTL8367C_LED_POWERON_1_OFFSET 5 +#define RTL8367C_LED_POWERON_1_MASK 0x20 +#define RTL8367C_LED_POWERON_0_OFFSET 4 +#define RTL8367C_LED_POWERON_0_MASK 0x10 +#define RTL8367C_LED_IO_DISABLE_OFFSET 3 +#define RTL8367C_LED_IO_DISABLE_MASK 0x8 +#define RTL8367C_DUMMY_2_2_OFFSET 2 +#define RTL8367C_DUMMY_2_2_MASK 0x4 +#define RTL8367C_LED_SELECT_OFFSET 0 +#define RTL8367C_LED_SELECT_MASK 0x3 + +#define RTL8367C_REG_LED_SYS_CONFIG2 0x1b01 +#define RTL8367C_LED_SYS_CONFIG2_DUMMY_OFFSET 2 +#define RTL8367C_LED_SYS_CONFIG2_DUMMY_MASK 0xFFFC +#define RTL8367C_GATE_LPTD_BYPASS_OFFSET 1 +#define RTL8367C_GATE_LPTD_BYPASS_MASK 0x2 +#define RTL8367C_LED_SPD_MODE_OFFSET 0 +#define RTL8367C_LED_SPD_MODE_MASK 0x1 + +#define RTL8367C_REG_LED_MODE 0x1b02 +#define RTL8367C_DLINK_TIME_OFFSET 15 +#define RTL8367C_DLINK_TIME_MASK 0x8000 +#define RTL8367C_LED_BUZZ_DUTY_OFFSET 14 +#define RTL8367C_LED_BUZZ_DUTY_MASK 0x4000 +#define RTL8367C_BUZZER_RATE_OFFSET 12 +#define RTL8367C_BUZZER_RATE_MASK 0x3000 +#define RTL8367C_LOOP_DETECT_MODE_OFFSET 11 +#define RTL8367C_LOOP_DETECT_MODE_MASK 0x800 +#define RTL8367C_SEL_PWRON_TIME_OFFSET 9 +#define RTL8367C_SEL_PWRON_TIME_MASK 0x600 +#define RTL8367C_EN_DLINK_LED_OFFSET 8 +#define RTL8367C_EN_DLINK_LED_MASK 0x100 +#define RTL8367C_LOOP_DETECT_RATE_OFFSET 6 +#define RTL8367C_LOOP_DETECT_RATE_MASK 0xC0 +#define RTL8367C_FORCE_RATE_OFFSET 4 +#define RTL8367C_FORCE_RATE_MASK 0x30 +#define RTL8367C_SEL_LEDRATE_OFFSET 1 +#define RTL8367C_SEL_LEDRATE_MASK 0xE +#define RTL8367C_SPEED_UP_OFFSET 0 +#define RTL8367C_SPEED_UP_MASK 0x1 + +#define RTL8367C_REG_LED_CONFIGURATION 0x1b03 +#define RTL8367C_LED_CONFIGURATION_DUMMY_OFFSET 15 +#define RTL8367C_LED_CONFIGURATION_DUMMY_MASK 0x8000 +#define RTL8367C_LED_CONFIG_SEL_OFFSET 14 +#define RTL8367C_LED_CONFIG_SEL_MASK 0x4000 +#define RTL8367C_DATA_LED_OFFSET 12 +#define RTL8367C_DATA_LED_MASK 0x3000 +#define RTL8367C_LED2_CFG_OFFSET 8 +#define RTL8367C_LED2_CFG_MASK 0xF00 +#define RTL8367C_LED1_CFG_OFFSET 4 +#define RTL8367C_LED1_CFG_MASK 0xF0 +#define RTL8367C_LED0_CFG_OFFSET 0 +#define RTL8367C_LED0_CFG_MASK 0xF + +#define RTL8367C_REG_RTCT_RESULTS_CFG 0x1b04 +#define RTL8367C_RTCT_2PAIR_FTT_OFFSET 15 +#define RTL8367C_RTCT_2PAIR_FTT_MASK 0x8000 +#define RTL8367C_RTCT_2PAIR_MODE_OFFSET 14 +#define RTL8367C_RTCT_2PAIR_MODE_MASK 0x4000 +#define RTL8367C_BLINK_EN_OFFSET 13 +#define RTL8367C_BLINK_EN_MASK 0x2000 +#define RTL8367C_TIMEOUT_OFFSET 12 +#define RTL8367C_TIMEOUT_MASK 0x1000 +#define RTL8367C_EN_CD_SAME_SHORT_OFFSET 11 +#define RTL8367C_EN_CD_SAME_SHORT_MASK 0x800 +#define RTL8367C_EN_CD_SAME_OPEN_OFFSET 10 +#define RTL8367C_EN_CD_SAME_OPEN_MASK 0x400 +#define RTL8367C_EN_CD_SAME_LINEDRIVER_OFFSET 9 +#define RTL8367C_EN_CD_SAME_LINEDRIVER_MASK 0x200 +#define RTL8367C_EN_CD_SAME_MISMATCH_OFFSET 8 +#define RTL8367C_EN_CD_SAME_MISMATCH_MASK 0x100 +#define RTL8367C_EN_CD_SHORT_OFFSET 7 +#define RTL8367C_EN_CD_SHORT_MASK 0x80 +#define RTL8367C_EN_AB_SHORT_OFFSET 6 +#define RTL8367C_EN_AB_SHORT_MASK 0x40 +#define RTL8367C_EN_CD_OPEN_OFFSET 5 +#define RTL8367C_EN_CD_OPEN_MASK 0x20 +#define RTL8367C_EN_AB_OPEN_OFFSET 4 +#define RTL8367C_EN_AB_OPEN_MASK 0x10 +#define RTL8367C_EN_CD_MISMATCH_OFFSET 3 +#define RTL8367C_EN_CD_MISMATCH_MASK 0x8 +#define RTL8367C_EN_AB_MISMATCH_OFFSET 2 +#define RTL8367C_EN_AB_MISMATCH_MASK 0x4 +#define RTL8367C_EN_CD_LINEDRIVER_OFFSET 1 +#define RTL8367C_EN_CD_LINEDRIVER_MASK 0x2 +#define RTL8367C_EN_AB_LINEDRIVER_OFFSET 0 +#define RTL8367C_EN_AB_LINEDRIVER_MASK 0x1 + +#define RTL8367C_REG_RTCT_LED 0x1b05 +#define RTL8367C_DUMMY_1b05a_OFFSET 12 +#define RTL8367C_DUMMY_1b05a_MASK 0xF000 +#define RTL8367C_RTCT_LED2_OFFSET 8 +#define RTL8367C_RTCT_LED2_MASK 0xF00 +#define RTL8367C_RTCT_LED1_OFFSET 4 +#define RTL8367C_RTCT_LED1_MASK 0xF0 +#define RTL8367C_RTCT_LED0_OFFSET 0 +#define RTL8367C_RTCT_LED0_MASK 0xF + +#define RTL8367C_REG_CPU_FORCE_LED_CFG 0x1b07 +#define RTL8367C_DUMMY_1b07a_OFFSET 8 +#define RTL8367C_DUMMY_1b07a_MASK 0xFF00 +#define RTL8367C_LED_FORCE_MODE_OFFSET 2 +#define RTL8367C_LED_FORCE_MODE_MASK 0xFC +#define RTL8367C_FORCE_MODE_OFFSET 0 +#define RTL8367C_FORCE_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED0_CFG0 0x1b08 +#define RTL8367C_PORT7_LED0_MODE_OFFSET 14 +#define RTL8367C_PORT7_LED0_MODE_MASK 0xC000 +#define RTL8367C_PORT6_LED0_MODE_OFFSET 12 +#define RTL8367C_PORT6_LED0_MODE_MASK 0x3000 +#define RTL8367C_PORT5_LED0_MODE_OFFSET 10 +#define RTL8367C_PORT5_LED0_MODE_MASK 0xC00 +#define RTL8367C_PORT4_LED0_MODE_OFFSET 8 +#define RTL8367C_PORT4_LED0_MODE_MASK 0x300 +#define RTL8367C_PORT3_LED0_MODE_OFFSET 6 +#define RTL8367C_PORT3_LED0_MODE_MASK 0xC0 +#define RTL8367C_PORT2_LED0_MODE_OFFSET 4 +#define RTL8367C_PORT2_LED0_MODE_MASK 0x30 +#define RTL8367C_PORT1_LED0_MODE_OFFSET 2 +#define RTL8367C_PORT1_LED0_MODE_MASK 0xC +#define RTL8367C_PORT0_LED0_MODE_OFFSET 0 +#define RTL8367C_PORT0_LED0_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED0_CFG1 0x1b09 +#define RTL8367C_DUMMY_1b09a_OFFSET 4 +#define RTL8367C_DUMMY_1b09a_MASK 0xFFF0 +#define RTL8367C_PORT9_LED0_MODE_OFFSET 2 +#define RTL8367C_PORT9_LED0_MODE_MASK 0xC +#define RTL8367C_PORT8_LED0_MODE_OFFSET 0 +#define RTL8367C_PORT8_LED0_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED1_CFG0 0x1b0a +#define RTL8367C_PORT7_LED1_MODE_OFFSET 14 +#define RTL8367C_PORT7_LED1_MODE_MASK 0xC000 +#define RTL8367C_PORT6_LED1_MODE_OFFSET 12 +#define RTL8367C_PORT6_LED1_MODE_MASK 0x3000 +#define RTL8367C_PORT5_LED1_MODE_OFFSET 10 +#define RTL8367C_PORT5_LED1_MODE_MASK 0xC00 +#define RTL8367C_PORT4_LED1_MODE_OFFSET 8 +#define RTL8367C_PORT4_LED1_MODE_MASK 0x300 +#define RTL8367C_PORT3_LED1_MODE_OFFSET 6 +#define RTL8367C_PORT3_LED1_MODE_MASK 0xC0 +#define RTL8367C_PORT2_LED1_MODE_OFFSET 4 +#define RTL8367C_PORT2_LED1_MODE_MASK 0x30 +#define RTL8367C_PORT1_LED1_MODE_OFFSET 2 +#define RTL8367C_PORT1_LED1_MODE_MASK 0xC +#define RTL8367C_PORT0_LED1_MODE_OFFSET 0 +#define RTL8367C_PORT0_LED1_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED1_CFG1 0x1b0b +#define RTL8367C_DUMMY_1b0ba_OFFSET 4 +#define RTL8367C_DUMMY_1b0ba_MASK 0xFFF0 +#define RTL8367C_PORT9_LED1_MODE_OFFSET 2 +#define RTL8367C_PORT9_LED1_MODE_MASK 0xC +#define RTL8367C_PORT8_LED1_MODE_OFFSET 0 +#define RTL8367C_PORT8_LED1_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED2_CFG0 0x1b0c +#define RTL8367C_PORT7_LED2_MODE_OFFSET 14 +#define RTL8367C_PORT7_LED2_MODE_MASK 0xC000 +#define RTL8367C_PORT6_LED2_MODE_OFFSET 12 +#define RTL8367C_PORT6_LED2_MODE_MASK 0x3000 +#define RTL8367C_PORT5_LED2_MODE_OFFSET 10 +#define RTL8367C_PORT5_LED2_MODE_MASK 0xC00 +#define RTL8367C_PORT4_LED2_MODE_OFFSET 8 +#define RTL8367C_PORT4_LED2_MODE_MASK 0x300 +#define RTL8367C_PORT3_LED2_MODE_OFFSET 6 +#define RTL8367C_PORT3_LED2_MODE_MASK 0xC0 +#define RTL8367C_PORT2_LED2_MODE_OFFSET 4 +#define RTL8367C_PORT2_LED2_MODE_MASK 0x30 +#define RTL8367C_PORT1_LED2_MODE_OFFSET 2 +#define RTL8367C_PORT1_LED2_MODE_MASK 0xC +#define RTL8367C_PORT0_LED2_MODE_OFFSET 0 +#define RTL8367C_PORT0_LED2_MODE_MASK 0x3 + +#define RTL8367C_REG_CPU_FORCE_LED2_CFG1 0x1b0d +#define RTL8367C_DUMMY_1b0da_OFFSET 4 +#define RTL8367C_DUMMY_1b0da_MASK 0xFFF0 +#define RTL8367C_PORT9_LED2_MODE_OFFSET 2 +#define RTL8367C_PORT9_LED2_MODE_MASK 0xC +#define RTL8367C_PORT8_LED2_MODE_OFFSET 0 +#define RTL8367C_PORT8_LED2_MODE_MASK 0x3 + +#define RTL8367C_REG_LED_ACTIVE_LOW_CFG0 0x1b0e +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_OFFSET 15 +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_MASK 0x8000 +#define RTL8367C_PORT3_LED_ACTIVE_LOW_OFFSET 12 +#define RTL8367C_PORT3_LED_ACTIVE_LOW_MASK 0x7000 +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_OFFSET 11 +#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_MASK 0x800 +#define RTL8367C_PORT2_LED_ACTIVE_LOW_OFFSET 8 +#define RTL8367C_PORT2_LED_ACTIVE_LOW_MASK 0x700 +#define RTL8367C_DUMMY_7_OFFSET 7 +#define RTL8367C_DUMMY_7_MASK 0x80 +#define RTL8367C_PORT1_LED_ACTIVE_LOW_OFFSET 4 +#define RTL8367C_PORT1_LED_ACTIVE_LOW_MASK 0x70 +#define RTL8367C_DUMMY_3_OFFSET 3 +#define RTL8367C_DUMMY_3_MASK 0x8 +#define RTL8367C_PORT0_LED_ACTIVE_LOW_OFFSET 0 +#define RTL8367C_PORT0_LED_ACTIVE_LOW_MASK 0x7 + +#define RTL8367C_REG_LED_ACTIVE_LOW_CFG1 0x1b0f +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_OFFSET 15 +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_MASK 0x8000 +#define RTL8367C_PORT7_LED_ACTIVE_LOW_OFFSET 12 +#define RTL8367C_PORT7_LED_ACTIVE_LOW_MASK 0x7000 +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_OFFSET 11 +#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_MASK 0x800 +#define RTL8367C_PORT6_LED_ACTIVE_LOW_OFFSET 8 +#define RTL8367C_PORT6_LED_ACTIVE_LOW_MASK 0x700 +#define RTL8367C_DUMMY_1b0f_b_OFFSET 7 +#define RTL8367C_DUMMY_1b0f_b_MASK 0x80 +#define RTL8367C_PORT5_LED_ACTIVE_LOW_OFFSET 4 +#define RTL8367C_PORT5_LED_ACTIVE_LOW_MASK 0x70 +#define RTL8367C_DUMMY_1b0f_a_OFFSET 3 +#define RTL8367C_DUMMY_1b0f_a_MASK 0x8 +#define RTL8367C_PORT4_LED_ACTIVE_LOW_OFFSET 0 +#define RTL8367C_PORT4_LED_ACTIVE_LOW_MASK 0x7 + +#define RTL8367C_REG_LED_ACTIVE_LOW_CFG2 0x1b10 +#define RTL8367C_DUMMY_1b10_b_OFFSET 7 +#define RTL8367C_DUMMY_1b10_b_MASK 0xFF80 +#define RTL8367C_PORT9_LED_ACTIVE_LOW_OFFSET 4 +#define RTL8367C_PORT9_LED_ACTIVE_LOW_MASK 0x70 +#define RTL8367C_DUMMY_1b10_a_OFFSET 3 +#define RTL8367C_DUMMY_1b10_a_MASK 0x8 +#define RTL8367C_PORT8_LED_ACTIVE_LOW_OFFSET 0 +#define RTL8367C_PORT8_LED_ACTIVE_LOW_MASK 0x7 + +#define RTL8367C_REG_SEL_RTCT_PARA 0x1b21 +#define RTL8367C_DO_RTCT_COMMAND_OFFSET 15 +#define RTL8367C_DO_RTCT_COMMAND_MASK 0x8000 +#define RTL8367C_SEL_RTCT_PARA_DUMMY_OFFSET 12 +#define RTL8367C_SEL_RTCT_PARA_DUMMY_MASK 0x7000 +#define RTL8367C_SEL_RTCT_RLSTLED_TIME_OFFSET 10 +#define RTL8367C_SEL_RTCT_RLSTLED_TIME_MASK 0xC00 +#define RTL8367C_SEL_RTCT_TEST_LED_TIME_OFFSET 8 +#define RTL8367C_SEL_RTCT_TEST_LED_TIME_MASK 0x300 +#define RTL8367C_EN_SCAN_RTCT_OFFSET 7 +#define RTL8367C_EN_SCAN_RTCT_MASK 0x80 +#define RTL8367C_EN_RTCT_TIMOUT_OFFSET 6 +#define RTL8367C_EN_RTCT_TIMOUT_MASK 0x40 +#define RTL8367C_EN_ALL_RTCT_OFFSET 5 +#define RTL8367C_EN_ALL_RTCT_MASK 0x20 +#define RTL8367C_SEL_RTCT_PLE_WID_OFFSET 0 +#define RTL8367C_SEL_RTCT_PLE_WID_MASK 0x1F + +#define RTL8367C_REG_RTCT_ENABLE 0x1b22 +#define RTL8367C_RTCT_ENABLE_DUMMY_OFFSET 8 +#define RTL8367C_RTCT_ENABLE_DUMMY_MASK 0xFF00 +#define RTL8367C_RTCT_ENABLE_PORT_MASK_OFFSET 0 +#define RTL8367C_RTCT_ENABLE_PORT_MASK_MASK 0xFF + +#define RTL8367C_REG_RTCT_TIMEOUT 0x1b23 + +#define RTL8367C_REG_PARA_LED_IO_EN1 0x1b24 +#define RTL8367C_LED1_PARA_P07_00_OFFSET 8 +#define RTL8367C_LED1_PARA_P07_00_MASK 0xFF00 +#define RTL8367C_LED0_PARA_P07_00_OFFSET 0 +#define RTL8367C_LED0_PARA_P07_00_MASK 0xFF + +#define RTL8367C_REG_PARA_LED_IO_EN2 0x1b25 +#define RTL8367C_DUMMY_15_8_OFFSET 8 +#define RTL8367C_DUMMY_15_8_MASK 0xFF00 +#define RTL8367C_LED2_PARA_P07_00_OFFSET 0 +#define RTL8367C_LED2_PARA_P07_00_MASK 0xFF + +#define RTL8367C_REG_SCAN0_LED_IO_EN1 0x1b26 +#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_OFFSET 3 +#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_MASK 0xFFF8 +#define RTL8367C_LED_LOOP_DET_BUZZER_EN_OFFSET 2 +#define RTL8367C_LED_LOOP_DET_BUZZER_EN_MASK 0x4 +#define RTL8367C_LED_SERI_DATA_EN_OFFSET 1 +#define RTL8367C_LED_SERI_DATA_EN_MASK 0x2 +#define RTL8367C_LED_SERI_CLK_EN_OFFSET 0 +#define RTL8367C_LED_SERI_CLK_EN_MASK 0x1 + +#define RTL8367C_REG_SCAN1_LED_IO_EN2 0x1b27 +#define RTL8367C_LED_SCAN1_BI_PORT_EN_OFFSET 8 +#define RTL8367C_LED_SCAN1_BI_PORT_EN_MASK 0xFF00 +#define RTL8367C_LED_SCAN1_BI_STA_EN_OFFSET 7 +#define RTL8367C_LED_SCAN1_BI_STA_EN_MASK 0x80 +#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_OFFSET 6 +#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_MASK 0x40 +#define RTL8367C_LED_SCAN1_SI_PORT_EN_OFFSET 2 +#define RTL8367C_LED_SCAN1_SI_PORT_EN_MASK 0x3C +#define RTL8367C_LED_SCAN1_SI_STA_EN_OFFSET 0 +#define RTL8367C_LED_SCAN1_SI_STA_EN_MASK 0x3 + +#define RTL8367C_REG_LPI_LED_OPT1 0x1b28 +#define RTL8367C_LPI_TAG4_OFFSET 12 +#define RTL8367C_LPI_TAG4_MASK 0xF000 +#define RTL8367C_LPI_TAG3_OFFSET 8 +#define RTL8367C_LPI_TAG3_MASK 0xF00 +#define RTL8367C_LPI_TAG2_OFFSET 4 +#define RTL8367C_LPI_TAG2_MASK 0xF0 +#define RTL8367C_LPI_TAG1_OFFSET 0 +#define RTL8367C_LPI_TAG1_MASK 0xF + +#define RTL8367C_REG_LPI_LED_OPT2 0x1b29 +#define RTL8367C_LPI_LED_OPT2_DUMMY_OFFSET 15 +#define RTL8367C_LPI_LED_OPT2_DUMMY_MASK 0x8000 +#define RTL8367C_LPI_LED2_WEAK_OFFSET 14 +#define RTL8367C_LPI_LED2_WEAK_MASK 0x4000 +#define RTL8367C_LPI_LED1_WEAK_OFFSET 13 +#define RTL8367C_LPI_LED1_WEAK_MASK 0x2000 +#define RTL8367C_LPI_LED0_WEAK_OFFSET 12 +#define RTL8367C_LPI_LED0_WEAK_MASK 0x1000 +#define RTL8367C_LPI_LED2_OFFSET 11 +#define RTL8367C_LPI_LED2_MASK 0x800 +#define RTL8367C_LPI_LED1_OFFSET 10 +#define RTL8367C_LPI_LED1_MASK 0x400 +#define RTL8367C_LPI_LED0_OFFSET 9 +#define RTL8367C_LPI_LED0_MASK 0x200 +#define RTL8367C_LPI_TAG8_OFFSET 8 +#define RTL8367C_LPI_TAG8_MASK 0x100 +#define RTL8367C_LPI_TAG7_OFFSET 6 +#define RTL8367C_LPI_TAG7_MASK 0xC0 +#define RTL8367C_LPI_TAG6_OFFSET 4 +#define RTL8367C_LPI_TAG6_MASK 0x30 +#define RTL8367C_LPI_TAG5_OFFSET 0 +#define RTL8367C_LPI_TAG5_MASK 0xF + +#define RTL8367C_REG_LPI_LED_OPT3 0x1b2a +#define RTL8367C_LPI_LED_OPT3_DUMMY_OFFSET 3 +#define RTL8367C_LPI_LED_OPT3_DUMMY_MASK 0xFFF8 +#define RTL8367C_RESTORE_LED_RATE_SEL_OFFSET 1 +#define RTL8367C_RESTORE_LED_RATE_SEL_MASK 0x6 +#define RTL8367C_RESTORE_LED_SEL_OFFSET 0 +#define RTL8367C_RESTORE_LED_SEL_MASK 0x1 + +#define RTL8367C_REG_P0_LED_MUX 0x1b2b +#define RTL8367C_CFG_P0_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P0_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P0_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P0_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P0_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P0_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P1_LED_MUX 0x1b2c +#define RTL8367C_CFG_P1_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P1_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P1_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P1_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P1_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P1_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P2_LED_MUX 0x1b2d +#define RTL8367C_CFG_P2_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P2_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P2_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P2_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P2_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P2_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P3_LED_MUX 0x1b2e +#define RTL8367C_CFG_P3_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P3_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P3_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P3_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P3_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P3_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P4_LED_MUX 0x1b2f +#define RTL8367C_CFG_P4_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P4_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P4_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P4_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P4_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P4_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_LED0_DATA_CTRL 0x1b30 +#define RTL8367C_CFG_DATA_LED0_SEL_OFFSET 6 +#define RTL8367C_CFG_DATA_LED0_SEL_MASK 0x40 +#define RTL8367C_CFG_DATA_LED0_ACT_OFFSET 4 +#define RTL8367C_CFG_DATA_LED0_ACT_MASK 0x30 +#define RTL8367C_CFG_DATA_LED0_SPD_OFFSET 0 +#define RTL8367C_CFG_DATA_LED0_SPD_MASK 0xF + +#define RTL8367C_REG_LED1_DATA_CTRL 0x1b31 +#define RTL8367C_CFG_DATA_LED1_SEL_OFFSET 6 +#define RTL8367C_CFG_DATA_LED1_SEL_MASK 0x40 +#define RTL8367C_CFG_DATA_LED1_ACT_OFFSET 4 +#define RTL8367C_CFG_DATA_LED1_ACT_MASK 0x30 +#define RTL8367C_CFG_DATA_LED1_SPD_OFFSET 0 +#define RTL8367C_CFG_DATA_LED1_SPD_MASK 0xF + +#define RTL8367C_REG_LED2_DATA_CTRL 0x1b32 +#define RTL8367C_CFG_DATA_LED2_SEL_OFFSET 6 +#define RTL8367C_CFG_DATA_LED2_SEL_MASK 0x40 +#define RTL8367C_CFG_DATA_LED2_ACT_OFFSET 4 +#define RTL8367C_CFG_DATA_LED2_ACT_MASK 0x30 +#define RTL8367C_CFG_DATA_LED2_SPD_OFFSET 0 +#define RTL8367C_CFG_DATA_LED2_SPD_MASK 0xF + +#define RTL8367C_REG_PARA_LED_IO_EN3 0x1b33 +#define RTL8367C_dummy_1b33a_OFFSET 6 +#define RTL8367C_dummy_1b33a_MASK 0xFFC0 +#define RTL8367C_LED2_PARA_P09_08_OFFSET 4 +#define RTL8367C_LED2_PARA_P09_08_MASK 0x30 +#define RTL8367C_LED1_PARA_P09_08_OFFSET 2 +#define RTL8367C_LED1_PARA_P09_08_MASK 0xC +#define RTL8367C_LED0_PARA_P09_08_OFFSET 0 +#define RTL8367C_LED0_PARA_P09_08_MASK 0x3 + +#define RTL8367C_REG_SCAN1_LED_IO_EN3 0x1b34 +#define RTL8367C_dummy_1b34a_OFFSET 3 +#define RTL8367C_dummy_1b34a_MASK 0xFFF8 +#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_OFFSET 1 +#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_MASK 0x6 +#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_OFFSET 0 +#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_MASK 0x1 + +#define RTL8367C_REG_P5_LED_MUX 0x1b35 +#define RTL8367C_CFG_P5_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P5_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P5_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P5_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P5_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P5_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P6_LED_MUX 0x1b36 +#define RTL8367C_CFG_P6_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P6_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P6_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P6_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P6_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P6_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P7_LED_MUX 0x1b37 +#define RTL8367C_CFG_P7_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P7_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P7_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P7_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P7_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P7_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P8_LED_MUX 0x1b38 +#define RTL8367C_CFG_P8_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P8_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P8_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P8_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P8_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P8_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_P9_LED_MUX 0x1b39 +#define RTL8367C_CFG_P9_LED2_MUX_OFFSET 10 +#define RTL8367C_CFG_P9_LED2_MUX_MASK 0x7C00 +#define RTL8367C_CFG_P9_LED1_MUX_OFFSET 5 +#define RTL8367C_CFG_P9_LED1_MUX_MASK 0x3E0 +#define RTL8367C_CFG_P9_LED0_MUX_OFFSET 0 +#define RTL8367C_CFG_P9_LED0_MUX_MASK 0x1F + +#define RTL8367C_REG_SERIAL_LED_CTRL 0x1b3a +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_OFFSET 13 +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_MASK 0x6000 +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_OFFSET 12 +#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_MASK 0x1000 +#define RTL8367C_SERIAL_LED_GROUP_NUM_OFFSET 10 +#define RTL8367C_SERIAL_LED_GROUP_NUM_MASK 0xC00 +#define RTL8367C_SERIAL_LED_PORT_EN_OFFSET 0 +#define RTL8367C_SERIAL_LED_PORT_EN_MASK 0x3FF + +/* (16'h1c00)IGMP_EAV */ + +#define RTL8367C_REG_IGMP_MLD_CFG0 0x1c00 +#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET 15 +#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_MASK 0x8000 +#define RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET 14 +#define RTL8367C_IGMP_MLD_VLAN_LEAKY_MASK 0x4000 +#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET 13 +#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_MASK 0x2000 +#define RTL8367C_REPORT_FORWARD_OFFSET 12 +#define RTL8367C_REPORT_FORWARD_MASK 0x1000 +#define RTL8367C_ROBURSTNESS_VAR_OFFSET 9 +#define RTL8367C_ROBURSTNESS_VAR_MASK 0xE00 +#define RTL8367C_LEAVE_SUPPRESSION_OFFSET 8 +#define RTL8367C_LEAVE_SUPPRESSION_MASK 0x100 +#define RTL8367C_REPORT_SUPPRESSION_OFFSET 7 +#define RTL8367C_REPORT_SUPPRESSION_MASK 0x80 +#define RTL8367C_LEAVE_TIMER_OFFSET 4 +#define RTL8367C_LEAVE_TIMER_MASK 0x70 +#define RTL8367C_FAST_LEAVE_EN_OFFSET 3 +#define RTL8367C_FAST_LEAVE_EN_MASK 0x8 +#define RTL8367C_CKS_ERR_OP_OFFSET 1 +#define RTL8367C_CKS_ERR_OP_MASK 0x6 +#define RTL8367C_IGMP_MLD_EN_OFFSET 0 +#define RTL8367C_IGMP_MLD_EN_MASK 0x1 + +#define RTL8367C_REG_IGMP_MLD_CFG1 0x1c01 +#define RTL8367C_DROP_LEAVE_ZERO_OFFSET 2 +#define RTL8367C_DROP_LEAVE_ZERO_MASK 0x4 +#define RTL8367C_TABLE_FULL_OP_OFFSET 0 +#define RTL8367C_TABLE_FULL_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_MLD_CFG2 0x1c02 + +#define RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT 0x1c03 +#define RTL8367C_D_ROUTER_PORT_2_OFFSET 11 +#define RTL8367C_D_ROUTER_PORT_2_MASK 0x7800 +#define RTL8367C_D_ROUTER_PORT_TMR_2_OFFSET 8 +#define RTL8367C_D_ROUTER_PORT_TMR_2_MASK 0x700 +#define RTL8367C_D_ROUTER_PORT_1_OFFSET 3 +#define RTL8367C_D_ROUTER_PORT_1_MASK 0x78 +#define RTL8367C_D_ROUTER_PORT_TMR_1_OFFSET 0 +#define RTL8367C_D_ROUTER_PORT_TMR_1_MASK 0x7 + +#define RTL8367C_REG_IGMP_STATIC_ROUTER_PORT 0x1c04 +#define RTL8367C_IGMP_STATIC_ROUTER_PORT_OFFSET 0 +#define RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK 0x7FF + +#define RTL8367C_REG_IGMP_PORT0_CONTROL 0x1c05 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT1_CONTROL 0x1c06 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT2_CONTROL 0x1c07 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT3_CONTROL 0x1c08 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT4_CONTROL 0x1c09 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT5_CONTROL 0x1c0a +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT6_CONTROL 0x1c0b +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT7_CONTROL 0x1c0c +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT01_MAX_GROUP 0x1c0d +#define RTL8367C_PORT1_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT1_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT0_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT0_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT23_MAX_GROUP 0x1c0e +#define RTL8367C_PORT3_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT3_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT2_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT2_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT45_MAX_GROUP 0x1c0f +#define RTL8367C_PORT5_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT5_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT4_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT4_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT67_MAX_GROUP 0x1c10 +#define RTL8367C_PORT7_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT7_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT6_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT6_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP 0x1c11 +#define RTL8367C_PORT1_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT1_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT0_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT0_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT23_CURRENT_GROUP 0x1c12 +#define RTL8367C_PORT3_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT3_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT2_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT2_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT45_CURRENT_GROUP 0x1c13 +#define RTL8367C_PORT5_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT5_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT4_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT4_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT67_CURRENT_GROUP 0x1c14 +#define RTL8367C_PORT7_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT7_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT6_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT6_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_MLD_CFG3 0x1c15 +#define RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET 5 +#define RTL8367C_IGMP_MLD_IP6_BYPASS_MASK 0x20 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET 4 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_MASK 0x10 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET 3 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_MASK 0x8 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET 2 +#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_MASK 0x4 +#define RTL8367C_REPORT_LEAVE_FORWARD_OFFSET 0 +#define RTL8367C_REPORT_LEAVE_FORWARD_MASK 0x3 + +#define RTL8367C_REG_IGMP_MLD_CFG4 0x1c16 +#define RTL8367C_IGMP_MLD_CFG4_OFFSET 0 +#define RTL8367C_IGMP_MLD_CFG4_MASK 0x7FF + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 0x1c20 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST1 0x1c21 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST2 0x1c22 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST3 0x1c23 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST4 0x1c24 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST5 0x1c25 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST6 0x1c26 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST7 0x1c27 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST8 0x1c28 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST9 0x1c29 + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST10 0x1c2a + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST11 0x1c2b + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST12 0x1c2c + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST13 0x1c2d + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST14 0x1c2e + +#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST15 0x1c2f + +#define RTL8367C_REG_EAV_CTRL0 0x1c30 +#define RTL8367C_EAV_CTRL0_OFFSET 0 +#define RTL8367C_EAV_CTRL0_MASK 0xFF + +#define RTL8367C_REG_EAV_CTRL1 0x1c31 +#define RTL8367C_REMAP_EAV_PRI3_REGEN_OFFSET 9 +#define RTL8367C_REMAP_EAV_PRI3_REGEN_MASK 0xE00 +#define RTL8367C_REMAP_EAV_PRI2_REGEN_OFFSET 6 +#define RTL8367C_REMAP_EAV_PRI2_REGEN_MASK 0x1C0 +#define RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET 3 +#define RTL8367C_REMAP_EAV_PRI1_REGEN_MASK 0x38 +#define RTL8367C_REMAP_EAV_PRI0_REGEN_OFFSET 0 +#define RTL8367C_REMAP_EAV_PRI0_REGEN_MASK 0x7 + +#define RTL8367C_REG_EAV_CTRL2 0x1c32 +#define RTL8367C_REMAP_EAV_PRI7_REGEN_OFFSET 9 +#define RTL8367C_REMAP_EAV_PRI7_REGEN_MASK 0xE00 +#define RTL8367C_REMAP_EAV_PRI6_REGEN_OFFSET 6 +#define RTL8367C_REMAP_EAV_PRI6_REGEN_MASK 0x1C0 +#define RTL8367C_REMAP_EAV_PRI5_REGEN_OFFSET 3 +#define RTL8367C_REMAP_EAV_PRI5_REGEN_MASK 0x38 +#define RTL8367C_REMAP_EAV_PRI4_REGEN_OFFSET 0 +#define RTL8367C_REMAP_EAV_PRI4_REGEN_MASK 0x7 + +#define RTL8367C_REG_SYS_TIME_FREQ 0x1c43 + +#define RTL8367C_REG_SYS_TIME_OFFSET_L 0x1c44 + +#define RTL8367C_REG_SYS_TIME_OFFSET_H 0x1c45 + +#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_L 0x1c46 + +#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_H 0x1c47 +#define RTL8367C_SYS_TIME_OFFSET_TUNE_OFFSET 5 +#define RTL8367C_SYS_TIME_OFFSET_TUNE_MASK 0x20 +#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_OFFSET 0 +#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_MASK 0x1F + +#define RTL8367C_REG_SYS_TIME_SEC_TRANSIT 0x1c48 +#define RTL8367C_SYS_TIME_SEC_TRANSIT_OFFSET 0 +#define RTL8367C_SYS_TIME_SEC_TRANSIT_MASK 0x1 + +#define RTL8367C_REG_SYS_TIME_SEC_HIGH_L 0x1c49 + +#define RTL8367C_REG_SYS_TIME_SEC_HIGH_H 0x1c4a + +#define RTL8367C_REG_SYS_TIME_512NS_L 0x1c4b + +#define RTL8367C_REG_SYS_TIME_512NS_H 0x1c4c +#define RTL8367C_SYS_TIME_512NS_H_OFFSET 0 +#define RTL8367C_SYS_TIME_512NS_H_MASK 0x1F + +#define RTL8367C_REG_FALLBACK_CTRL 0x1c70 +#define RTL8367C_FALLBACK_PL_DEC_EN_OFFSET 15 +#define RTL8367C_FALLBACK_PL_DEC_EN_MASK 0x8000 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_OFFSET 14 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_MASK 0x4000 +#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_OFFSET 11 +#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_MASK 0x3800 +#define RTL8367C_FALLBACK_MONITORMAX_OFFSET 8 +#define RTL8367C_FALLBACK_MONITORMAX_MASK 0x700 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_OFFSET 0 +#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT0_CFG0 0x1c71 +#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT0_CFG1 0x1c72 + +#define RTL8367C_REG_FALLBACK_PORT0_CFG2 0x1c73 +#define RTL8367C_FALLBACK_PORT0_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT0_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT0_CFG3 0x1c74 +#define RTL8367C_FALLBACK_PORT0_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT0_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT1_CFG0 0x1c75 +#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT1_CFG1 0x1c76 + +#define RTL8367C_REG_FALLBACK_PORT1_CFG2 0x1c77 +#define RTL8367C_FALLBACK_PORT1_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT1_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT1_CFG3 0x1c78 +#define RTL8367C_FALLBACK_PORT1_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT1_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT2_CFG0 0x1c79 +#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT2_CFG1 0x1c7a + +#define RTL8367C_REG_FALLBACK_PORT2_CFG2 0x1c7b +#define RTL8367C_FALLBACK_PORT2_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT2_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT2_CFG3 0x1c7c +#define RTL8367C_FALLBACK_PORT2_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT2_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT3_CFG0 0x1c7d +#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT3_CFG1 0x1c7e + +#define RTL8367C_REG_FALLBACK_PORT3_CFG2 0x1c7f +#define RTL8367C_FALLBACK_PORT3_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT3_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT3_CFG3 0x1c80 +#define RTL8367C_FALLBACK_PORT3_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT3_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT4_CFG0 0x1c81 +#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT4_CFG1 0x1c82 + +#define RTL8367C_REG_FALLBACK_PORT4_CFG2 0x1c83 +#define RTL8367C_FALLBACK_PORT4_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT4_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT4_CFG3 0x1c84 +#define RTL8367C_FALLBACK_PORT4_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT4_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_CTRL1 0x1c85 +#define RTL8367C_FALLBACK_VALIDFLOW_OFFSET 8 +#define RTL8367C_FALLBACK_VALIDFLOW_MASK 0xFF00 +#define RTL8367C_FALLBACK_STOP_TMR_OFFSET 0 +#define RTL8367C_FALLBACK_STOP_TMR_MASK 0x1 + +#define RTL8367C_REG_FALLBACK_CPL 0x1c86 +#define RTL8367C_PORT4_CPL_OFFSET 4 +#define RTL8367C_PORT4_CPL_MASK 0x10 +#define RTL8367C_PORT3_CPL_OFFSET 3 +#define RTL8367C_PORT3_CPL_MASK 0x8 +#define RTL8367C_PORT2_CPL_OFFSET 2 +#define RTL8367C_PORT2_CPL_MASK 0x4 +#define RTL8367C_PORT1_CPL_OFFSET 1 +#define RTL8367C_PORT1_CPL_MASK 0x2 +#define RTL8367C_PORT0_CPL_OFFSET 0 +#define RTL8367C_PORT0_CPL_MASK 0x1 + +#define RTL8367C_REG_FALLBACK_PHY_PAGE 0x1c87 +#define RTL8367C_FALLBACK_PHY_PAGE_OFFSET 0 +#define RTL8367C_FALLBACK_PHY_PAGE_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PHY_REG 0x1c88 +#define RTL8367C_FALLBACK_PHY_REG_OFFSET 0 +#define RTL8367C_FALLBACK_PHY_REG_MASK 0x1F + +#define RTL8367C_REG_AFBK_INFO_X0 0x1c89 + +#define RTL8367C_REG_AFBK_INFO_X1 0x1c8a + +#define RTL8367C_REG_AFBK_INFO_X2 0x1c8b + +#define RTL8367C_REG_AFBK_INFO_X3 0x1c8c + +#define RTL8367C_REG_AFBK_INFO_X4 0x1c8d + +#define RTL8367C_REG_AFBK_INFO_X5 0x1c8e + +#define RTL8367C_REG_AFBK_INFO_X6 0x1c8f + +#define RTL8367C_REG_AFBK_INFO_X7 0x1c90 + +#define RTL8367C_REG_AFBK_INFO_X8 0x1c91 + +#define RTL8367C_REG_AFBK_INFO_X9 0x1c92 + +#define RTL8367C_REG_AFBK_INFO_X10 0x1c93 + +#define RTL8367C_REG_AFBK_INFO_X11 0x1c94 + +#define RTL8367C_REG_FALLBACK_PORT5_CFG0 0x1ca0 +#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT5_CFG1 0x1ca1 + +#define RTL8367C_REG_FALLBACK_PORT5_CFG2 0x1ca2 +#define RTL8367C_FALLBACK_PORT5_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT5_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT5_CFG3 0x1ca3 +#define RTL8367C_FALLBACK_PORT5_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT5_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT6_CFG0 0x1ca4 +#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT6_CFG1 0x1ca5 + +#define RTL8367C_REG_FALLBACK_PORT6_CFG2 0x1ca6 +#define RTL8367C_FALLBACK_PORT6_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT6_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT6_CFG3 0x1ca7 +#define RTL8367C_FALLBACK_PORT6_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT6_CFG3_MASK 0xFF + +#define RTL8367C_REG_FALLBACK_PORT7_CFG0 0x1ca8 +#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_OFFSET 15 +#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_MASK 0x8000 +#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_OFFSET 14 +#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_MASK 0x4000 + +#define RTL8367C_REG_FALLBACK_PORT7_CFG1 0x1ca9 + +#define RTL8367C_REG_FALLBACK_PORT7_CFG2 0x1caa +#define RTL8367C_FALLBACK_PORT7_CFG2_OFFSET 0 +#define RTL8367C_FALLBACK_PORT7_CFG2_MASK 0xFFF + +#define RTL8367C_REG_FALLBACK_PORT7_CFG3 0x1cab +#define RTL8367C_FALLBACK_PORT7_CFG3_OFFSET 0 +#define RTL8367C_FALLBACK_PORT7_CFG3_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT8_CONTROL 0x1cb0 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT9_CONTROL 0x1cb1 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT10_CONTROL 0x1cb2 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_OFFSET 14 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_MASK 0x4000 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_OFFSET 13 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_MASK 0x2000 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_OFFSET 12 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_MASK 0x1000 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_OFFSET 11 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_MASK 0x800 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_OFFSET 10 +#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_MASK 0x400 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_OFFSET 8 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_MASK 0x300 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_OFFSET 6 +#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_MASK 0xC0 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_OFFSET 4 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_MASK 0x30 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_OFFSET 2 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_MASK 0xC +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_OFFSET 0 +#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_MASK 0x3 + +#define RTL8367C_REG_IGMP_PORT89_MAX_GROUP 0x1cb3 +#define RTL8367C_PORT9_MAX_GROUP_OFFSET 8 +#define RTL8367C_PORT9_MAX_GROUP_MASK 0xFF00 +#define RTL8367C_PORT8_MAX_GROUP_OFFSET 0 +#define RTL8367C_PORT8_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT10_MAX_GROUP 0x1cb4 +#define RTL8367C_IGMP_PORT10_MAX_GROUP_OFFSET 0 +#define RTL8367C_IGMP_PORT10_MAX_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP 0x1cb5 +#define RTL8367C_PORT9_CURRENT_GROUP_OFFSET 8 +#define RTL8367C_PORT9_CURRENT_GROUP_MASK 0xFF00 +#define RTL8367C_PORT8_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_PORT8_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_PORT10_CURRENT_GROUP 0x1cb6 +#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_OFFSET 0 +#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_MASK 0xFF + +#define RTL8367C_REG_IGMP_L3_CHECKSUM_CHECK 0x1cb7 +#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_OFFSET 0 +#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_MASK 0x1 + +/* (16'h1d00)chip_70b_reg */ + +#define RTL8367C_REG_PCSXF_CFG 0x1d00 +#define RTL8367C_PCSXF_CFG_Reserved_OFFSET 15 +#define RTL8367C_PCSXF_CFG_Reserved_MASK 0x8000 +#define RTL8367C_CFG_RST_RXFIFO_P7_5_OFFSET 12 +#define RTL8367C_CFG_RST_RXFIFO_P7_5_MASK 0x7000 +#define RTL8367C_CFG_PCSXF_OFFSET 8 +#define RTL8367C_CFG_PCSXF_MASK 0xF00 +#define RTL8367C_CFG_RST_RXFIFO_OFFSET 3 +#define RTL8367C_CFG_RST_RXFIFO_MASK 0xF8 +#define RTL8367C_CFG_COL2RXDV_OFFSET 2 +#define RTL8367C_CFG_COL2RXDV_MASK 0x4 +#define RTL8367C_CFG_PHY_SDET_OFFSET 0 +#define RTL8367C_CFG_PHY_SDET_MASK 0x3 + +#define RTL8367C_REG_PHYID_CFG0 0x1d01 +#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_OFFSET 11 +#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_MASK 0x3800 +#define RTL8367C_CFG_PHYAD_14C_OFFSET 10 +#define RTL8367C_CFG_PHYAD_14C_MASK 0x400 +#define RTL8367C_CFG_PHY_BRD_MODE_OFFSET 5 +#define RTL8367C_CFG_PHY_BRD_MODE_MASK 0x3E0 +#define RTL8367C_CFG_BRD_PHYAD_OFFSET 0 +#define RTL8367C_CFG_BRD_PHYAD_MASK 0x1F + +#define RTL8367C_REG_PHYID_CFG1 0x1d02 +#define RTL8367C_CFG_MSK_MDI_OFFSET 5 +#define RTL8367C_CFG_MSK_MDI_MASK 0x1FE0 +#define RTL8367C_CFG_BASE_PHYAD_OFFSET 0 +#define RTL8367C_CFG_BASE_PHYAD_MASK 0x1F + +#define RTL8367C_REG_PHY_POLL_CFG0 0x1d03 +#define RTL8367C_CFG_HOTCMD_PRD_EN_OFFSET 15 +#define RTL8367C_CFG_HOTCMD_PRD_EN_MASK 0x8000 +#define RTL8367C_CFG_HOTCMD_EN_OFFSET 12 +#define RTL8367C_CFG_HOTCMD_EN_MASK 0x7000 +#define RTL8367C_CFG_POLL_PERIOD_OFFSET 8 +#define RTL8367C_CFG_POLL_PERIOD_MASK 0xF00 +#define RTL8367C_CFG_PERI_CMDS_RD_OFFSET 4 +#define RTL8367C_CFG_PERI_CMDS_RD_MASK 0xF0 +#define RTL8367C_CFG_PERI_CMDS_WR_OFFSET 0 +#define RTL8367C_CFG_PERI_CMDS_WR_MASK 0xF + +#define RTL8367C_REG_PHY_POLL_CFG1 0x1d04 + +#define RTL8367C_REG_PHY_POLL_CFG2 0x1d05 + +#define RTL8367C_REG_PHY_POLL_CFG3 0x1d06 + +#define RTL8367C_REG_PHY_POLL_CFG4 0x1d07 + +#define RTL8367C_REG_PHY_POLL_CFG5 0x1d08 + +#define RTL8367C_REG_PHY_POLL_CFG6 0x1d09 + +#define RTL8367C_REG_PHY_POLL_CFG7 0x1d0a + +#define RTL8367C_REG_PHY_POLL_CFG8 0x1d0b + +#define RTL8367C_REG_PHY_POLL_CFG9 0x1d0c + +#define RTL8367C_REG_PHY_POLL_CFG10 0x1d0d + +#define RTL8367C_REG_PHY_POLL_CFG11 0x1d0e + +#define RTL8367C_REG_PHY_POLL_CFG12 0x1d0f + +#define RTL8367C_REG_EFUSE_MISC 0x1d10 +#define RTL8367C_CFG_SA_SEL_OFFSET 5 +#define RTL8367C_CFG_SA_SEL_MASK 0x20 +#define RTL8367C_CFG_PHYAD00_OFFSET 0 +#define RTL8367C_CFG_PHYAD00_MASK 0x1F + +#define RTL8367C_REG_SDS_MISC 0x1d11 +#define RTL8367C_CFG_SGMII_RXFC_OFFSET 14 +#define RTL8367C_CFG_SGMII_RXFC_MASK 0x4000 +#define RTL8367C_CFG_SGMII_TXFC_OFFSET 13 +#define RTL8367C_CFG_SGMII_TXFC_MASK 0x2000 +#define RTL8367C_INB_ARB_OFFSET 12 +#define RTL8367C_INB_ARB_MASK 0x1000 +#define RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET 11 +#define RTL8367C_CFG_MAC8_SEL_HSGMII_MASK 0x800 +#define RTL8367C_CFG_SGMII_FDUP_OFFSET 10 +#define RTL8367C_CFG_SGMII_FDUP_MASK 0x400 +#define RTL8367C_CFG_SGMII_LINK_OFFSET 9 +#define RTL8367C_CFG_SGMII_LINK_MASK 0x200 +#define RTL8367C_CFG_SGMII_SPD_OFFSET 7 +#define RTL8367C_CFG_SGMII_SPD_MASK 0x180 +#define RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET 6 +#define RTL8367C_CFG_MAC8_SEL_SGMII_MASK 0x40 +#define RTL8367C_CFG_INB_SEL_OFFSET 3 +#define RTL8367C_CFG_INB_SEL_MASK 0x38 +#define RTL8367C_CFG_SDS_MODE_18C_OFFSET 0 +#define RTL8367C_CFG_SDS_MODE_18C_MASK 0x7 + +#define RTL8367C_REG_FIFO_CTRL 0x1d12 +#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_OFFSET 11 +#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_MASK 0x800 +#define RTL8367C_CFG_LPBK_OFFSET 10 +#define RTL8367C_CFG_LPBK_MASK 0x400 +#define RTL8367C_CFG_NOT_FF_OUT_OFFSET 9 +#define RTL8367C_CFG_NOT_FF_OUT_MASK 0x200 +#define RTL8367C_CFG_WATER_LEVEL_FD_OFFSET 6 +#define RTL8367C_CFG_WATER_LEVEL_FD_MASK 0x1C0 +#define RTL8367C_CFG_WATER_LEVEL_Y2X_OFFSET 3 +#define RTL8367C_CFG_WATER_LEVEL_Y2X_MASK 0x38 +#define RTL8367C_CFG_WATER_LEVEL_X2Y_OFFSET 0 +#define RTL8367C_CFG_WATER_LEVEL_X2Y_MASK 0x7 + +#define RTL8367C_REG_BCAM_SETTING 0x1d13 +#define RTL8367C_CFG_BCAM_MDS_OFFSET 3 +#define RTL8367C_CFG_BCAM_MDS_MASK 0x18 +#define RTL8367C_CFG_BCAM_RDS_OFFSET 0 +#define RTL8367C_CFG_BCAM_RDS_MASK 0x7 + +#define RTL8367C_REG_GPHY_ACS_MISC 0x1d14 +#define RTL8367C_CFG_SEL_GPHY_SMI_OFFSET 3 +#define RTL8367C_CFG_SEL_GPHY_SMI_MASK 0x8 +#define RTL8367C_CFG_BRD_PHYIDX_OFFSET 0 +#define RTL8367C_CFG_BRD_PHYIDX_MASK 0x7 + +#define RTL8367C_REG_GPHY_OCP_MSB_0 0x1d15 +#define RTL8367C_CFG_CPU_OCPADR_MSB_OFFSET 6 +#define RTL8367C_CFG_CPU_OCPADR_MSB_MASK 0xFC0 +#define RTL8367C_CFG_DW8051_OCPADR_MSB_OFFSET 0 +#define RTL8367C_CFG_DW8051_OCPADR_MSB_MASK 0x3F + +#define RTL8367C_REG_GPHY_OCP_MSB_1 0x1d16 +#define RTL8367C_CFG_PATCH_OCPADR_MSB_OFFSET 6 +#define RTL8367C_CFG_PATCH_OCPADR_MSB_MASK 0xFC0 +#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_OFFSET 0 +#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_MASK 0x3F + +#define RTL8367C_REG_GPHY_OCP_MSB_2 0x1d17 +#define RTL8367C_CFG_RRCP_OCPADR_MSB_OFFSET 6 +#define RTL8367C_CFG_RRCP_OCPADR_MSB_MASK 0xFC0 +#define RTL8367C_CFG_RTCT_OCPADR_MSB_OFFSET 0 +#define RTL8367C_CFG_RTCT_OCPADR_MSB_MASK 0x3F + +#define RTL8367C_REG_GPHY_OCP_MSB_3 0x1d18 +#define RTL8367C_GPHY_OCP_MSB_3_OFFSET 0 +#define RTL8367C_GPHY_OCP_MSB_3_MASK 0x3F + +#define RTL8367C_REG_GPIO_67C_I_X0 0x1d19 + +#define RTL8367C_REG_GPIO_67C_I_X1 0x1d1a + +#define RTL8367C_REG_GPIO_67C_I_X2 0x1d1b + +#define RTL8367C_REG_GPIO_67C_I_X3 0x1d1c +#define RTL8367C_GPIO_67C_I_X3_OFFSET 0 +#define RTL8367C_GPIO_67C_I_X3_MASK 0x3FFF + +#define RTL8367C_REG_GPIO_67C_O_X0 0x1d1d + +#define RTL8367C_REG_GPIO_67C_O_X1 0x1d1e + +#define RTL8367C_REG_GPIO_67C_O_X2 0x1d1f + +#define RTL8367C_REG_GPIO_67C_O_X3 0x1d20 +#define RTL8367C_GPIO_67C_O_X3_OFFSET 0 +#define RTL8367C_GPIO_67C_O_X3_MASK 0x3FFF + +#define RTL8367C_REG_GPIO_67C_OE_X0 0x1d21 + +#define RTL8367C_REG_GPIO_67C_OE_X1 0x1d22 + +#define RTL8367C_REG_GPIO_67C_OE_X2 0x1d23 + +#define RTL8367C_REG_GPIO_67C_OE_X3 0x1d24 +#define RTL8367C_GPIO_67C_OE_X3_OFFSET 0 +#define RTL8367C_GPIO_67C_OE_X3_MASK 0x3FFF + +#define RTL8367C_REG_GPIO_MODE_67C_X0 0x1d25 + +#define RTL8367C_REG_GPIO_MODE_67C_X1 0x1d26 + +#define RTL8367C_REG_GPIO_MODE_67C_X2 0x1d27 + +#define RTL8367C_REG_GPIO_MODE_67C_X3 0x1d28 +#define RTL8367C_GPIO_MODE_67C_X3_OFFSET 0 +#define RTL8367C_GPIO_MODE_67C_X3_MASK 0x3FFF + +#define RTL8367C_REG_WGPHY_MISC_0 0x1d29 +#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_OFFSET 13 +#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_MASK 0xE000 +#define RTL8367C_CFG_INIPHY_PWRUP_OFFSET 5 +#define RTL8367C_CFG_INIPHY_PWRUP_MASK 0x1FE0 +#define RTL8367C_CFG_INIPHY_DISGIGA_OFFSET 0 +#define RTL8367C_CFG_INIPHY_DISGIGA_MASK 0x1F + +#define RTL8367C_REG_WGPHY_MISC_1 0x1d2a +#define RTL8367C_WGPHY_MISC_1_OFFSET 0 +#define RTL8367C_WGPHY_MISC_1_MASK 0xFF + +#define RTL8367C_REG_WGPHY_MISC_2 0x1d2b +#define RTL8367C_WGPHY_MISC_2_OFFSET 0 +#define RTL8367C_WGPHY_MISC_2_MASK 0x3FF + +#define RTL8367C_REG_CFG_AFBK_GPHY_0 0x1d2c +#define RTL8367C_CFG_AFBK_GPHY_0_OFFSET 0 +#define RTL8367C_CFG_AFBK_GPHY_0_MASK 0x1F + +#define RTL8367C_REG_CFG_AFBK_GPHY_1 0x1d2d +#define RTL8367C_CFG_AFBK_GPHY_1_OFFSET 0 +#define RTL8367C_CFG_AFBK_GPHY_1_MASK 0xFFF + +#define RTL8367C_REG_EF_SLV_CTRL_0 0x1d2e +#define RTL8367C_EF_SLV_BUSY_OFFSET 11 +#define RTL8367C_EF_SLV_BUSY_MASK 0x800 +#define RTL8367C_EF_SLV_ACK_OFFSET 10 +#define RTL8367C_EF_SLV_ACK_MASK 0x400 +#define RTL8367C_EF_SLV_A_OFFSET 2 +#define RTL8367C_EF_SLV_A_MASK 0x3FC +#define RTL8367C_EF_SLV_WE_OFFSET 1 +#define RTL8367C_EF_SLV_WE_MASK 0x2 +#define RTL8367C_EF_SLV_CE_OFFSET 0 +#define RTL8367C_EF_SLV_CE_MASK 0x1 + +#define RTL8367C_REG_EF_SLV_CTRL_1 0x1d2f + +#define RTL8367C_REG_EF_SLV_CTRL_2 0x1d30 + +#define RTL8367C_REG_EFUSE_MISC_1 0x1d31 +#define RTL8367C_EF_EN_EFUSE_OFFSET 10 +#define RTL8367C_EF_EN_EFUSE_MASK 0x400 +#define RTL8367C_EF_MODEL_ID_OFFSET 6 +#define RTL8367C_EF_MODEL_ID_MASK 0x3C0 +#define RTL8367C_EF_RSVD_OFFSET 2 +#define RTL8367C_EF_RSVD_MASK 0x3C +#define RTL8367C_EF_SYS_CLK_OFFSET 0 +#define RTL8367C_EF_SYS_CLK_MASK 0x3 + +#define RTL8367C_REG_IO_MISC_FUNC 0x1d32 +#define RTL8367C_TST_MODE_OFFSET 3 +#define RTL8367C_TST_MODE_MASK 0x8 +#define RTL8367C_UART_EN_OFFSET 2 +#define RTL8367C_UART_EN_MASK 0x4 +#define RTL8367C_INT_EN_OFFSET 1 +#define RTL8367C_INT_EN_MASK 0x2 +#define RTL8367C_BUZ_EN_OFFSET 0 +#define RTL8367C_BUZ_EN_MASK 0x1 + +#define RTL8367C_REG_HTRAM_DVS 0x1d33 +#define RTL8367C_HTRAM_DVS_OFFSET 0 +#define RTL8367C_HTRAM_DVS_MASK 0x1 + +#define RTL8367C_REG_EF_SLV_CTRL_3 0x1d34 +#define RTL8367C_EF_SLV_CTRL_3_OFFSET 0 +#define RTL8367C_EF_SLV_CTRL_3_MASK 0x1 + +#define RTL8367C_REG_INBAND_EN14C 0x1d35 +#define RTL8367C_INBAND_EN14C_OFFSET 0 +#define RTL8367C_INBAND_EN14C_MASK 0x1 + +#define RTL8367C_REG_CFG_SWR_L 0x1d36 +#define RTL8367C_ANARG_RDY_SWR_L_OFFSET 14 +#define RTL8367C_ANARG_RDY_SWR_L_MASK 0x4000 +#define RTL8367C_ANARG_VALID_SWR_L_OFFSET 13 +#define RTL8367C_ANARG_VALID_SWR_L_MASK 0x2000 +#define RTL8367C_SAW_SWR_L_OFFSET 9 +#define RTL8367C_SAW_SWR_L_MASK 0x1E00 +#define RTL8367C_SAW_VALID_SWR_L_OFFSET 8 +#define RTL8367C_SAW_VALID_SWR_L_MASK 0x100 +#define RTL8367C_UPS_DBGO_L_OFFSET 0 +#define RTL8367C_UPS_DBGO_L_MASK 0xFF + +#define RTL8367C_REG_BTCAM_CTRL 0x1d37 +#define RTL8367C_TCAM_RDS_OFFSET 2 +#define RTL8367C_TCAM_RDS_MASK 0x1C +#define RTL8367C_TCAM_MDS_OFFSET 0 +#define RTL8367C_TCAM_MDS_MASK 0x3 + +#define RTL8367C_REG_PBRAM_BISR_CTRL 0x1d38 +#define RTL8367C_HAS_HLDRMP_MD_OFFSET 9 +#define RTL8367C_HAS_HLDRMP_MD_MASK 0x200 +#define RTL8367C_PB_HLDRMP_MD_OFFSET 8 +#define RTL8367C_PB_HLDRMP_MD_MASK 0x100 +#define RTL8367C_HAS_BISR_BIRSTN_OFFSET 7 +#define RTL8367C_HAS_BISR_BIRSTN_MASK 0x80 +#define RTL8367C_SEC_RUN_HSA_OFFSET 6 +#define RTL8367C_SEC_RUN_HSA_MASK 0x40 +#define RTL8367C_HAS_HLDRMP_VAL_OFFSET 5 +#define RTL8367C_HAS_HLDRMP_VAL_MASK 0x20 +#define RTL8367C_HAS_BISR_PWRSTN_OFFSET 4 +#define RTL8367C_HAS_BISR_PWRSTN_MASK 0x10 +#define RTL8367C_SEC_RUN_PB_OFFSET 3 +#define RTL8367C_SEC_RUN_PB_MASK 0x8 +#define RTL8367C_PB_HLDRMP_VAL_OFFSET 2 +#define RTL8367C_PB_HLDRMP_VAL_MASK 0x4 +#define RTL8367C_PB_BISR_BIRSTN_OFFSET 1 +#define RTL8367C_PB_BISR_BIRSTN_MASK 0x2 +#define RTL8367C_PB_BISR_PWRSTN_OFFSET 0 +#define RTL8367C_PB_BISR_PWRSTN_MASK 0x1 + +#define RTL8367C_REG_CVLANRAM_BISR_CTRL 0x1d39 +#define RTL8367C_SEC_RUN_CVLAN_OFFSET 4 +#define RTL8367C_SEC_RUN_CVLAN_MASK 0x10 +#define RTL8367C_CVALN_HLDRMP_MD_OFFSET 3 +#define RTL8367C_CVALN_HLDRMP_MD_MASK 0x8 +#define RTL8367C_CVALN_HLDRMP_VAL_OFFSET 2 +#define RTL8367C_CVALN_HLDRMP_VAL_MASK 0x4 +#define RTL8367C_CVLAN_BISR_BIRSTN_OFFSET 1 +#define RTL8367C_CVLAN_BISR_BIRSTN_MASK 0x2 +#define RTL8367C_CVLAN_BISR_PWRSTN_OFFSET 0 +#define RTL8367C_CVLAN_BISR_PWRSTN_MASK 0x1 + +#define RTL8367C_REG_CFG_1588_TIMER_EN_GPI 0x1d3a +#define RTL8367C_CFG_1588_TIMER_EN_GPI_OFFSET 0 +#define RTL8367C_CFG_1588_TIMER_EN_GPI_MASK 0x1 + +#define RTL8367C_REG_MDIO_PRMB_SUPP 0x1d3b +#define RTL8367C_FIB_HIPRI_OFFSET 14 +#define RTL8367C_FIB_HIPRI_MASK 0x4000 +#define RTL8367C_SMT_EN_OFFSET 13 +#define RTL8367C_SMT_EN_MASK 0x2000 +#define RTL8367C_P4_FB_CPL_OFFSET 12 +#define RTL8367C_P4_FB_CPL_MASK 0x1000 +#define RTL8367C_P3_FB_CPL_OFFSET 11 +#define RTL8367C_P3_FB_CPL_MASK 0x800 +#define RTL8367C_P2_FB_CPL_OFFSET 10 +#define RTL8367C_P2_FB_CPL_MASK 0x400 +#define RTL8367C_P1_FB_CPL_OFFSET 9 +#define RTL8367C_P1_FB_CPL_MASK 0x200 +#define RTL8367C_P0_FB_CPL_OFFSET 8 +#define RTL8367C_P0_FB_CPL_MASK 0x100 +#define RTL8367C_DBG_PKG_8367N_OFFSET 7 +#define RTL8367C_DBG_PKG_8367N_MASK 0x80 +#define RTL8367C_DBG_PKG_8367VB_OFFSET 6 +#define RTL8367C_DBG_PKG_8367VB_MASK 0x40 +#define RTL8367C_CFG_DEBUG_EN_OFFSET 5 +#define RTL8367C_CFG_DEBUG_EN_MASK 0x20 +#define RTL8367C_CFG_TMR_ACK_OFFSET 1 +#define RTL8367C_CFG_TMR_ACK_MASK 0x1E +#define RTL8367C_CFG_PRMB_SUPP_OFFSET 0 +#define RTL8367C_CFG_PRMB_SUPP_MASK 0x1 + +#define RTL8367C_REG_BOND4READ 0x1d3c +#define RTL8367C_BOND_BOID0_OFFSET 8 +#define RTL8367C_BOND_BOID0_MASK 0x100 +#define RTL8367C_BOND_SYSCLK_OFFSET 7 +#define RTL8367C_BOND_SYSCLK_MASK 0x80 +#define RTL8367C_BOND_PHYMODE_OFFSET 6 +#define RTL8367C_BOND_PHYMODE_MASK 0x40 +#define RTL8367C_BOND_DIS_PON_BIST_OFFSET 5 +#define RTL8367C_BOND_DIS_PON_BIST_MASK 0x20 +#define RTL8367C_BOND_DIS_TABLE_INIT_OFFSET 4 +#define RTL8367C_BOND_DIS_TABLE_INIT_MASK 0x10 +#define RTL8367C_BOND_BYP_AFE_PLL_OFFSET 3 +#define RTL8367C_BOND_BYP_AFE_PLL_MASK 0x8 +#define RTL8367C_BOND_BYP_AFE_POR_OFFSET 2 +#define RTL8367C_BOND_BYP_AFE_POR_MASK 0x4 +#define RTL8367C_BOND_BISR_COND_OFFSET 1 +#define RTL8367C_BOND_BISR_COND_MASK 0x2 +#define RTL8367C_BOND_EF_EN_OFFSET 0 +#define RTL8367C_BOND_EF_EN_MASK 0x1 + +#define RTL8367C_REG_REG_TO_ECO0 0x1d3d + +#define RTL8367C_REG_REG_TO_ECO1 0x1d3e + +#define RTL8367C_REG_REG_TO_ECO2 0x1d3f + +#define RTL8367C_REG_REG_TO_ECO3 0x1d40 + +#define RTL8367C_REG_REG_TO_ECO4 0x1d41 + +#define RTL8367C_REG_PHYSTS_CTRL0 0x1d42 +#define RTL8367C_MACRX_DUPDET_EN_OFFSET 5 +#define RTL8367C_MACRX_DUPDET_EN_MASK 0x20 +#define RTL8367C_LNKUP_DLY_EN_OFFSET 4 +#define RTL8367C_LNKUP_DLY_EN_MASK 0x10 +#define RTL8367C_GE_100M_LNKUP_DLY_OFFSET 2 +#define RTL8367C_GE_100M_LNKUP_DLY_MASK 0xC +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_OFFSET 0 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_MASK 0x3 + +#define RTL8367C_REG_SSC_CTRL0_0 0x1d44 +#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL0_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL0_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL0_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL0_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL0_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL0_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED 0x1d45 + +#define RTL8367C_REG_SSC_PN_POLY_SEL 0x1d46 + +#define RTL8367C_REG_SSC_CTRL0_3 0x1d47 +#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL0_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL0_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL0_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL0_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL0_4 0x1d48 +#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL0_5 0x1d49 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL0_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL0_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL0_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS0 0x1d4a +#define RTL8367C_SSC_STS0_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS0_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS0_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS0_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS0_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS0_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS0_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS0_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL1_0 0x1d4b +#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL1_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL1_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL1_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL1_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL1_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL1_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED1 0x1d4c + +#define RTL8367C_REG_SSC_PN_POLY_SEL1 0x1d4d + +#define RTL8367C_REG_SSC_CTRL1_3 0x1d4e +#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL1_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL1_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL1_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL1_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL1_4 0x1d4f +#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL1_5 0x1d50 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL1_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL1_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL1_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS1 0x1d51 +#define RTL8367C_SSC_STS1_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS1_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS1_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS1_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS1_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS1_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS1_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS1_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL2_0 0x1d52 +#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL2_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL2_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL2_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL2_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL2_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL2_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED2 0x1d53 + +#define RTL8367C_REG_SSC_PN_POLY_SEL2 0x1d54 + +#define RTL8367C_REG_SSC_CTRL2_3 0x1d55 +#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL2_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL2_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL2_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL2_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL2_4 0x1d56 +#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL2_5 0x1d57 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL2_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL2_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL2_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS2 0x1d58 +#define RTL8367C_SSC_STS2_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS2_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS2_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS2_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS2_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS2_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS2_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS2_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL3_0 0x1d59 +#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_OFFSET 13 +#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_MASK 0x2000 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_OFFSET 5 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_MASK 0x1FE0 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_OFFSET 4 +#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_MASK 0x10 +#define RTL8367C_SSC_CTRL3_0_DLL_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL3_0_DLL_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL3_0_SSC_EN_OFFSET 1 +#define RTL8367C_SSC_CTRL3_0_SSC_EN_MASK 0x2 +#define RTL8367C_SSC_CTRL3_0_SSC_MODE_OFFSET 0 +#define RTL8367C_SSC_CTRL3_0_SSC_MODE_MASK 0x1 + +#define RTL8367C_REG_SSC_RDM_SEED3 0x1d5a + +#define RTL8367C_REG_SSC_PN_POLY_SEL3 0x1d5b + +#define RTL8367C_REG_SSC_CTRL3_3 0x1d5c +#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_OFFSET 8 +#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_MASK 0x7F00 +#define RTL8367C_SSC_CTRL3_3_PHSFT_A_OFFSET 7 +#define RTL8367C_SSC_CTRL3_3_PHSFT_A_MASK 0x80 +#define RTL8367C_SSC_CTRL3_3_PHSFT_B_OFFSET 6 +#define RTL8367C_SSC_CTRL3_3_PHSFT_B_MASK 0x40 +#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_OFFSET 5 +#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_MASK 0x20 +#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_OFFSET 4 +#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_MASK 0x10 +#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_OFFSET 0 +#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_MASK 0xF + +#define RTL8367C_REG_SSC_CTRL3_4 0x1d5d +#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_OFFSET 15 +#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_MASK 0x8000 +#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_OFFSET 8 +#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_MASK 0x7F00 +#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_OFFSET 0 +#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_MASK 0xFF + +#define RTL8367C_REG_SSC_CTRL3_5 0x1d5e +#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_OFFSET 15 +#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_MASK 0x8000 +#define RTL8367C_SSC_CTRL3_5_PH_OFS_OFFSET 10 +#define RTL8367C_SSC_CTRL3_5_PH_OFS_MASK 0x7C00 +#define RTL8367C_SSC_CTRL3_5_SSC_STEP_OFFSET 4 +#define RTL8367C_SSC_CTRL3_5_SSC_STEP_MASK 0x3F0 +#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_OFFSET 2 +#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_MASK 0xC +#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_OFFSET 0 +#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_MASK 0x3 + +#define RTL8367C_REG_SSC_STS3 0x1d5f +#define RTL8367C_SSC_STS3_OFS_BUSY_OFFSET 13 +#define RTL8367C_SSC_STS3_OFS_BUSY_MASK 0x2000 +#define RTL8367C_SSC_STS3_OFS_TOTAL_R_OFFSET 8 +#define RTL8367C_SSC_STS3_OFS_TOTAL_R_MASK 0x1F00 +#define RTL8367C_SSC_STS3_CNT_GRY0_OFFSET 4 +#define RTL8367C_SSC_STS3_CNT_GRY0_MASK 0xF0 +#define RTL8367C_SSC_STS3_OFS_GRY0_OFFSET 0 +#define RTL8367C_SSC_STS3_OFS_GRY0_MASK 0xF + +#define RTL8367C_REG_PHY_POLL_CFG13 0x1d60 + +#define RTL8367C_REG_PHY_POLL_CFG14 0x1d61 + +#define RTL8367C_REG_FRC_SYS_CLK 0x1d62 +#define RTL8367C_SYSCLK_FRC_MD_OFFSET 1 +#define RTL8367C_SYSCLK_FRC_MD_MASK 0x2 +#define RTL8367C_SYSCLK_FRC_VAL_OFFSET 0 +#define RTL8367C_SYSCLK_FRC_VAL_MASK 0x1 + +#define RTL8367C_REG_AFE_SSC_CTRL 0x1d63 +#define RTL8367C_PH_RSTB_TXD1_OFFSET 9 +#define RTL8367C_PH_RSTB_TXD1_MASK 0x200 +#define RTL8367C_PH_RSTB_TXC1_OFFSET 8 +#define RTL8367C_PH_RSTB_TXC1_MASK 0x100 +#define RTL8367C_PH_RSTB_TXD0_OFFSET 7 +#define RTL8367C_PH_RSTB_TXD0_MASK 0x80 +#define RTL8367C_PH_RSTB_TXC0_OFFSET 6 +#define RTL8367C_PH_RSTB_TXC0_MASK 0x40 +#define RTL8367C_PH_RSTBSYS_OFFSET 5 +#define RTL8367C_PH_RSTBSYS_MASK 0x20 +#define RTL8367C_PH_RSTB8051_OFFSET 4 +#define RTL8367C_PH_RSTB8051_MASK 0x10 +#define RTL8367C_OREG_SSC_OFFSET 0 +#define RTL8367C_OREG_SSC_MASK 0xF + +#define RTL8367C_REG_BUFF_RST_CTRL0 0x1d64 +#define RTL8367C_BUFFRST_TXESD_EN_OFFSET 13 +#define RTL8367C_BUFFRST_TXESD_EN_MASK 0x2000 +#define RTL8367C_BUFF_RST_TIME_LONG_OFFSET 8 +#define RTL8367C_BUFF_RST_TIME_LONG_MASK 0x1F00 +#define RTL8367C_BUFF_RST_TIME_SHORT_OFFSET 3 +#define RTL8367C_BUFF_RST_TIME_SHORT_MASK 0xF8 +#define RTL8367C_SW_BUFF_RST_OFFSET 2 +#define RTL8367C_SW_BUFF_RST_MASK 0x4 +#define RTL8367C_IMS_BUFF_RST_OFFSET 1 +#define RTL8367C_IMS_BUFF_RST_MASK 0x2 +#define RTL8367C_IMR_BUFF_RST_OFFSET 0 +#define RTL8367C_IMR_BUFF_RST_MASK 0x1 + +#define RTL8367C_REG_BUFF_RST_CTRL1 0x1d65 +#define RTL8367C_BUFFRST_SYSOVER_EN_OFFSET 10 +#define RTL8367C_BUFFRST_SYSOVER_EN_MASK 0x400 +#define RTL8367C_BUFFRST_SYSOVER_THR_OFFSET 0 +#define RTL8367C_BUFFRST_SYSOVER_THR_MASK 0x3FF + +#define RTL8367C_REG_BUFF_RST_CTRL2 0x1d66 +#define RTL8367C_BUFFRST_QOVER_EN_OFFSET 10 +#define RTL8367C_BUFFRST_QOVER_EN_MASK 0x400 +#define RTL8367C_BUFFRST_QOVER_THR_OFFSET 0 +#define RTL8367C_BUFFRST_QOVER_THR_MASK 0x3FF + +#define RTL8367C_REG_BUFF_RST_CTRL3 0x1d67 +#define RTL8367C_DSC_TIMER_OFFSET 11 +#define RTL8367C_DSC_TIMER_MASK 0x7800 +#define RTL8367C_BUFFRST_DSCOVER_THR_OFFSET 1 +#define RTL8367C_BUFFRST_DSCOVER_THR_MASK 0x7FE +#define RTL8367C_BUFFRST_DSCOVER_EN_OFFSET 0 +#define RTL8367C_BUFFRST_DSCOVER_EN_MASK 0x1 + +#define RTL8367C_REG_BUFF_RST_CTRL4 0x1d68 +#define RTL8367C_INDSC_TIMER_OFFSET 11 +#define RTL8367C_INDSC_TIMER_MASK 0x7800 +#define RTL8367C_BUFFRST_INDSCOVER_THR_OFFSET 1 +#define RTL8367C_BUFFRST_INDSCOVER_THR_MASK 0x7FE +#define RTL8367C_BUFFRST_INDSCOVER_EN_OFFSET 0 +#define RTL8367C_BUFFRST_INDSCOVER_EN_MASK 0x1 + +#define RTL8367C_REG_BUFF_RST_CTRL5 0x1d69 +#define RTL8367C_TX_ESD_MODE_OFFSET 8 +#define RTL8367C_TX_ESD_MODE_MASK 0x100 +#define RTL8367C_TX_ESD_LVL_OFFSET 0 +#define RTL8367C_TX_ESD_LVL_MASK 0xFF + +#define RTL8367C_REG_TOP_CON0 0x1d70 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_OFFSET 15 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_MASK 0x8000 +#define RTL8367C_OCP_TIMEOUT_P7_5_OFFSET 12 +#define RTL8367C_OCP_TIMEOUT_P7_5_MASK 0x7000 +#define RTL8367C_FIB_EEE_AB_OFFSET 11 +#define RTL8367C_FIB_EEE_AB_MASK 0x800 +#define RTL8367C_ADCCKIEN_OFFSET 10 +#define RTL8367C_ADCCKIEN_MASK 0x400 +#define RTL8367C_OCP_TIMEOUT_OFFSET 5 +#define RTL8367C_OCP_TIMEOUT_MASK 0x3E0 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_OFFSET 4 +#define RTL8367C_TOP_CON0_SDS_PWR_ISO_MASK 0x10 +#define RTL8367C_RG2_TXC_SEL_OFFSET 3 +#define RTL8367C_RG2_TXC_SEL_MASK 0x8 +#define RTL8367C_RG1TXC_SEL_OFFSET 2 +#define RTL8367C_RG1TXC_SEL_MASK 0x4 +#define RTL8367C_SYNC_1588_EN_OFFSET 1 +#define RTL8367C_SYNC_1588_EN_MASK 0x2 +#define RTL8367C_LS_MODE_OFFSET 0 +#define RTL8367C_LS_MODE_MASK 0x1 + +#define RTL8367C_REG_TOP_CON1 0x1d71 +#define RTL8367C_TA_CHK_EN_OFFSET 2 +#define RTL8367C_TA_CHK_EN_MASK 0x4 +#define RTL8367C_SLV_EG_SEL_OFFSET 1 +#define RTL8367C_SLV_EG_SEL_MASK 0x2 +#define RTL8367C_IIC_OP_DRAIN_OFFSET 0 +#define RTL8367C_IIC_OP_DRAIN_MASK 0x1 + +#define RTL8367C_REG_SWR_FPWM 0x1d72 +#define RTL8367C_SWR_FPWM_OFFSET 0 +#define RTL8367C_SWR_FPWM_MASK 0x1 + +#define RTL8367C_REG_EEEP_CTRL_500M 0x1d73 + +#define RTL8367C_REG_SHORT_PRMB 0x1d74 +#define RTL8367C_SHORT_PRMB_OFFSET 0 +#define RTL8367C_SHORT_PRMB_MASK 0x1 + +#define RTL8367C_REG_INDSC_THR_CTRL 0x1d75 +#define RTL8367C_INDSC_THR_CTRL_OFFSET 0 +#define RTL8367C_INDSC_THR_CTRL_MASK 0x7FF + +#define RTL8367C_REG_SET_PAD_CTRL_NEW 0x1d80 +#define RTL8367C_SET_PAD_CTRL_NEW_OFFSET 0 +#define RTL8367C_SET_PAD_CTRL_NEW_MASK 0x1 + +#define RTL8367C_REG_SET_PAD_DRI_0 0x1d81 + +#define RTL8367C_REG_SET_PAD_DRI_1 0x1d82 + +#define RTL8367C_REG_SET_PAD_DRI_2 0x1d83 + +#define RTL8367C_REG_SET_PAD_SLEW_0 0x1d84 + +#define RTL8367C_REG_SET_PAD_SLEW_1 0x1d85 + +#define RTL8367C_REG_SET_PAD_SLEW_2 0x1d86 + +#define RTL8367C_REG_SET_PAD_SMT_0 0x1d87 + +#define RTL8367C_REG_SET_PAD_SMT_1 0x1d88 + +#define RTL8367C_REG_SET_PAD_SMT_2 0x1d89 + +#define RTL8367C_REG_M_I2C_CTL_STA_REG 0x1d8a +#define RTL8367C_TX_RX_DATA_OFFSET 8 +#define RTL8367C_TX_RX_DATA_MASK 0xFF00 +#define RTL8367C_DUMB_RW_ERR_OFFSET 7 +#define RTL8367C_DUMB_RW_ERR_MASK 0x80 +#define RTL8367C_SLV_ACK_FLAG_OFFSET 6 +#define RTL8367C_SLV_ACK_FLAG_MASK 0x40 +#define RTL8367C_M_I2C_BUS_IDLE_OFFSET 5 +#define RTL8367C_M_I2C_BUS_IDLE_MASK 0x20 +#define RTL8367C_I2C_CMD_TYPE_OFFSET 1 +#define RTL8367C_I2C_CMD_TYPE_MASK 0x1E +#define RTL8367C_I2C_CMD_EXEC_OFFSET 0 +#define RTL8367C_I2C_CMD_EXEC_MASK 0x1 + +#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_0 0x1d8b + +#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_1 0x1d8c + +#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_0 0x1d8d + +#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_1 0x1d8e + +#define RTL8367C_REG_M_I2C_DUMB_RW_CTL 0x1d8f +#define RTL8367C_DUMB_I2C_CTL_CODE_OFFSET 8 +#define RTL8367C_DUMB_I2C_CTL_CODE_MASK 0x7F00 +#define RTL8367C_DUMB_RW_I2C_FORMAT_OFFSET 4 +#define RTL8367C_DUMB_RW_I2C_FORMAT_MASK 0x10 +#define RTL8367C_DUMB_RW_DATA_MODE_OFFSET 2 +#define RTL8367C_DUMB_RW_DATA_MODE_MASK 0xC +#define RTL8367C_DUMB_RW_ADDR_MODE_OFFSET 0 +#define RTL8367C_DUMB_RW_ADDR_MODE_MASK 0x3 + +#define RTL8367C_REG_M_I2C_SYS_CTL 0x1d90 +#define RTL8367C_M_I2C_SCL_IO_MUX_OFFSET 12 +#define RTL8367C_M_I2C_SCL_IO_MUX_MASK 0x3000 +#define RTL8367C_M_I2C_SDA_IO_MUX_OFFSET 10 +#define RTL8367C_M_I2C_SDA_IO_MUX_MASK 0xC00 +#define RTL8367C_M_I2C_SDA_OD_EN_OFFSET 9 +#define RTL8367C_M_I2C_SDA_OD_EN_MASK 0x200 +#define RTL8367C_M_I2C_SCL_OD_EN_OFFSET 8 +#define RTL8367C_M_I2C_SCL_OD_EN_MASK 0x100 +#define RTL8367C_M_I2C_SCL_F_DIV_OFFSET 0 +#define RTL8367C_M_I2C_SCL_F_DIV_MASK 0xFF + +#define RTL8367C_REG_HT_PB_SRAM_CTRL 0x1da0 +#define RTL8367C_HTPB_RW_OFFSET 2 +#define RTL8367C_HTPB_RW_MASK 0x4 +#define RTL8367C_HTPB_SEL_OFFSET 1 +#define RTL8367C_HTPB_SEL_MASK 0x2 +#define RTL8367C_HTPB_CE_OFFSET 0 +#define RTL8367C_HTPB_CE_MASK 0x1 + +#define RTL8367C_REG_HT_PB_SRAM_ADDR 0x1da1 + +#define RTL8367C_REG_HT_PB_SRAM_DIN0 0x1da2 + +#define RTL8367C_REG_HT_PB_SRAM_DIN1 0x1da3 + +#define RTL8367C_REG_HT_PB_SRAM_DOUT0 0x1da4 + +#define RTL8367C_REG_HT_PB_SRAM_DOUT1 0x1da5 + +#define RTL8367C_REG_PHY_STAT_0 0x1db0 + +#define RTL8367C_REG_PHY_STAT_1 0x1db1 + +#define RTL8367C_REG_PHY_STAT_2 0x1db2 + +#define RTL8367C_REG_PHY_STAT_3 0x1db3 + +#define RTL8367C_REG_PHY_STAT_4 0x1db4 + +#define RTL8367C_REG_PHY_STAT_5 0x1db5 + +#define RTL8367C_REG_PHY_STAT_6 0x1db6 + +#define RTL8367C_REG_PHY_STAT_7 0x1db7 + +#define RTL8367C_REG_SDS_STAT_0 0x1db8 + +#define RTL8367C_REG_SDS_STAT_1 0x1db9 + +#define RTL8367C_REG_MAC_LINK_STAT_0 0x1dba +#define RTL8367C_MAC_LINK_STAT_CUR_0_OFFSET 8 +#define RTL8367C_MAC_LINK_STAT_CUR_0_MASK 0xFF00 +#define RTL8367C_MAC_LINK_STAT_LATCH_0_OFFSET 0 +#define RTL8367C_MAC_LINK_STAT_LATCH_0_MASK 0xFF + +#define RTL8367C_REG_MAC_LINK_STAT_1 0x1dbb +#define RTL8367C_MAC_LINK_STAT_1_Reserved_OFFSET 6 +#define RTL8367C_MAC_LINK_STAT_1_Reserved_MASK 0xFFC0 +#define RTL8367C_MAC_LINK_STAT_CUR_1_OFFSET 3 +#define RTL8367C_MAC_LINK_STAT_CUR_1_MASK 0x38 +#define RTL8367C_MAC_LINK_STAT_LATCH_1_OFFSET 0 +#define RTL8367C_MAC_LINK_STAT_LATCH_1_MASK 0x7 + +#define RTL8367C_REG_MISC_CONTROL_1 0x1dc0 +#define RTL8367C_P7_FB_CPL_OFFSET 2 +#define RTL8367C_P7_FB_CPL_MASK 0x4 +#define RTL8367C_P6_FB_CPL_OFFSET 1 +#define RTL8367C_P6_FB_CPL_MASK 0x2 +#define RTL8367C_P5_FB_CPL_OFFSET 0 +#define RTL8367C_P5_FB_CPL_MASK 0x1 + +#define RTL8367C_REG_SDS_MISC_1 0x1dc1 +#define RTL8367C_CFG_SGMII_RXFC_1_OFFSET 14 +#define RTL8367C_CFG_SGMII_RXFC_1_MASK 0x4000 +#define RTL8367C_CFG_SGMII_TXFC_1_OFFSET 13 +#define RTL8367C_CFG_SGMII_TXFC_1_MASK 0x2000 +#define RTL8367C_CFG_MAC9_SEL_HSGMII_OFFSET 11 +#define RTL8367C_CFG_MAC9_SEL_HSGMII_MASK 0x800 +#define RTL8367C_CFG_SGMII_FDUP_1_OFFSET 10 +#define RTL8367C_CFG_SGMII_FDUP_1_MASK 0x400 +#define RTL8367C_CFG_SGMII_LINK_1_OFFSET 9 +#define RTL8367C_CFG_SGMII_LINK_1_MASK 0x200 +#define RTL8367C_CFG_SGMII_SPD_1_OFFSET 7 +#define RTL8367C_CFG_SGMII_SPD_1_MASK 0x180 +#define RTL8367C_CFG_MAC9_SEL_SGMII_OFFSET 6 +#define RTL8367C_CFG_MAC9_SEL_SGMII_MASK 0x40 +#define RTL8367C_CFG_SDS_MODE_14C_1_OFFSET 0 +#define RTL8367C_CFG_SDS_MODE_14C_1_MASK 0x7 + +#define RTL8367C_REG_FIBER_CFG_2_1 0x1dc2 +#define RTL8367C_SDS_RX_DISABLE_1_OFFSET 6 +#define RTL8367C_SDS_RX_DISABLE_1_MASK 0xC0 +#define RTL8367C_SDS_TX_DISABLE_1_OFFSET 4 +#define RTL8367C_SDS_TX_DISABLE_1_MASK 0x30 +#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_OFFSET 2 +#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_MASK 0xC +#define RTL8367C_SDS_FRC_LD_1_OFFSET 0 +#define RTL8367C_SDS_FRC_LD_1_MASK 0x3 + +#define RTL8367C_REG_FIBER_CFG_1_1 0x1dc3 +#define RTL8367C_SDS_FRC_REG4_1_OFFSET 12 +#define RTL8367C_SDS_FRC_REG4_1_MASK 0x1000 +#define RTL8367C_SDS_FRC_REG4_FIB100_1_OFFSET 11 +#define RTL8367C_SDS_FRC_REG4_FIB100_1_MASK 0x800 +#define RTL8367C_SDS_FRC_MODE_1_OFFSET 3 +#define RTL8367C_SDS_FRC_MODE_1_MASK 0x8 +#define RTL8367C_SDS_MODE_1_OFFSET 0 +#define RTL8367C_SDS_MODE_1_MASK 0x7 + +#define RTL8367C_REG_PHYSTS_CTRL0_1 0x1dc4 +#define RTL8367C_LNKUP_DLY_EN_EXT2_OFFSET 9 +#define RTL8367C_LNKUP_DLY_EN_EXT2_MASK 0x200 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_OFFSET 7 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_MASK 0x180 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_OFFSET 5 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_MASK 0x60 +#define RTL8367C_LNKUP_DLY_EN_EXT1_OFFSET 4 +#define RTL8367C_LNKUP_DLY_EN_EXT1_MASK 0x10 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_OFFSET 2 +#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_MASK 0xC +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_OFFSET 0 +#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_MASK 0x3 + +#define RTL8367C_REG_FIBER_CFG_3_1 0x1dc5 +#define RTL8367C_FIBER_CFG_3_1_OFFSET 0 +#define RTL8367C_FIBER_CFG_3_1_MASK 0xFFF + +#define RTL8367C_REG_FIBER_CFG_4_1 0x1dc6 + +#define RTL8367C_REG_BUFF_RST_CTRL2_2 0x1dc7 +#define RTL8367C_Cfg_buffrst_sysover_thr_1_OFFSET 3 +#define RTL8367C_Cfg_buffrst_sysover_thr_1_MASK 0x8 +#define RTL8367C_Cfg_buffrst_qover_thr_OFFSET 2 +#define RTL8367C_Cfg_buffrst_qover_thr_MASK 0x4 +#define RTL8367C_Cfg_buffrst_indscover_thr_1_OFFSET 1 +#define RTL8367C_Cfg_buffrst_indscover_thr_1_MASK 0x2 +#define RTL8367C_Cfg_buffrst_dscover_thr_1_OFFSET 0 +#define RTL8367C_Cfg_buffrst_dscover_thr_1_MASK 0x1 + +#define RTL8367C_REG_PHY_DEBUG_CNT_CTRL 0x1dc8 +#define RTL8367C_PHY_MIB_RST_7_OFFSET 15 +#define RTL8367C_PHY_MIB_RST_7_MASK 0x8000 +#define RTL8367C_PHY_MIB_RST_6_OFFSET 14 +#define RTL8367C_PHY_MIB_RST_6_MASK 0x4000 +#define RTL8367C_PHY_MIB_RST_5_OFFSET 13 +#define RTL8367C_PHY_MIB_RST_5_MASK 0x2000 +#define RTL8367C_PHY_MIB_RST_4_OFFSET 12 +#define RTL8367C_PHY_MIB_RST_4_MASK 0x1000 +#define RTL8367C_PHY_MIB_RST_3_OFFSET 11 +#define RTL8367C_PHY_MIB_RST_3_MASK 0x800 +#define RTL8367C_PHY_MIB_RST_2_OFFSET 10 +#define RTL8367C_PHY_MIB_RST_2_MASK 0x400 +#define RTL8367C_PHY_MIB_RST_1_OFFSET 9 +#define RTL8367C_PHY_MIB_RST_1_MASK 0x200 +#define RTL8367C_PHY_MIB_RST_0_OFFSET 8 +#define RTL8367C_PHY_MIB_RST_0_MASK 0x100 +#define RTL8367C_PHY_MIB_EN_7_OFFSET 7 +#define RTL8367C_PHY_MIB_EN_7_MASK 0x80 +#define RTL8367C_PHY_MIB_EN_6_OFFSET 6 +#define RTL8367C_PHY_MIB_EN_6_MASK 0x40 +#define RTL8367C_PHY_MIB_EN_5_OFFSET 5 +#define RTL8367C_PHY_MIB_EN_5_MASK 0x20 +#define RTL8367C_PHY_MIB_EN_4_OFFSET 4 +#define RTL8367C_PHY_MIB_EN_4_MASK 0x10 +#define RTL8367C_PHY_MIB_EN_3_OFFSET 3 +#define RTL8367C_PHY_MIB_EN_3_MASK 0x8 +#define RTL8367C_PHY_MIB_EN_2_OFFSET 2 +#define RTL8367C_PHY_MIB_EN_2_MASK 0x4 +#define RTL8367C_PHY_MIB_EN_1_OFFSET 1 +#define RTL8367C_PHY_MIB_EN_1_MASK 0x2 +#define RTL8367C_PHY_MIB_EN_0_OFFSET 0 +#define RTL8367C_PHY_MIB_EN_0_MASK 0x1 + +#define RTL8367C_REG_TXPKT_CNT_L_0 0x1dc9 + +#define RTL8367C_REG_TXPKT_CNT_H_0 0x1dca + +#define RTL8367C_REG_RXPKT_CNT_L_0 0x1dcb + +#define RTL8367C_REG_RXPKT_CNT_H_0 0x1dcc + +#define RTL8367C_REG_TX_CRC_0 0x1dcd + +#define RTL8367C_REG_RX_CRC_0 0x1dce + +#define RTL8367C_REG_TXPKT_CNT_L_1 0x1dcf + +#define RTL8367C_REG_TXPKT_CNT_H_1 0x1dd0 + +#define RTL8367C_REG_RXPKT_CNT_L_1 0x1dd1 + +#define RTL8367C_REG_RXPKT_CNT_H_1 0x1dd2 + +#define RTL8367C_REG_TX_CRC_1 0x1dd3 + +#define RTL8367C_REG_RX_CRC_1 0x1dd4 + +#define RTL8367C_REG_TXPKT_CNT_L_2 0x1dd5 + +#define RTL8367C_REG_TXPKT_CNT_H_2 0x1dd6 + +#define RTL8367C_REG_RXPKT_CNT_L_2 0x1dd7 + +#define RTL8367C_REG_RXPKT_CNT_H_2 0x1dd8 + +#define RTL8367C_REG_TX_CRC_2 0x1dd9 + +#define RTL8367C_REG_RX_CRC_2 0x1dda + +#define RTL8367C_REG_TXPKT_CNT_L_3 0x1ddb + +#define RTL8367C_REG_TXPKT_CNT_H_3 0x1ddc + +#define RTL8367C_REG_RXPKT_CNT_L_3 0x1ddd + +#define RTL8367C_REG_RXPKT_CNT_H_3 0x1dde + +#define RTL8367C_REG_TX_CRC_3 0x1ddf + +#define RTL8367C_REG_RX_CRC_3 0x1de0 + +#define RTL8367C_REG_TXPKT_CNT_L_4 0x1de1 + +#define RTL8367C_REG_TXPKT_CNT_H_4 0x1de2 + +#define RTL8367C_REG_RXPKT_CNT_L_4 0x1de3 + +#define RTL8367C_REG_RXPKT_CNT_H_4 0x1de4 + +#define RTL8367C_REG_TX_CRC_4 0x1de5 + +#define RTL8367C_REG_RX_CRC_4 0x1de6 + +#define RTL8367C_REG_TXPKT_CNT_L_5 0x1de7 + +#define RTL8367C_REG_TXPKT_CNT_H_5 0x1de8 + +#define RTL8367C_REG_RXPKT_CNT_L_5 0x1de9 + +#define RTL8367C_REG_RXPKT_CNT_H_5 0x1dea + +#define RTL8367C_REG_TX_CRC_5 0x1deb + +#define RTL8367C_REG_RX_CRC_5 0x1dec + +#define RTL8367C_REG_TXPKT_CNT_L_6 0x1ded + +#define RTL8367C_REG_TXPKT_CNT_H_6 0x1dee + +#define RTL8367C_REG_RXPKT_CNT_L_6 0x1def + +#define RTL8367C_REG_RXPKT_CNT_H_6 0x1df0 + +#define RTL8367C_REG_TX_CRC_6 0x1df1 + +#define RTL8367C_REG_RX_CRC_6 0x1df2 + +#define RTL8367C_REG_TXPKT_CNT_L_7 0x1df3 + +#define RTL8367C_REG_TXPKT_CNT_H_7 0x1df4 + +#define RTL8367C_REG_RXPKT_CNT_L_7 0x1df5 + +#define RTL8367C_REG_RXPKT_CNT_H_7 0x1df6 + +#define RTL8367C_REG_TX_CRC_7 0x1df7 + +#define RTL8367C_REG_RX_CRC_7 0x1df8 + +#define RTL8367C_REG_BOND_DBG_0 0x1df9 + +#define RTL8367C_REG_BOND_DBG_1 0x1dfa + +#define RTL8367C_REG_STRP_DBG_0 0x1dfb + +#define RTL8367C_REG_STRP_DBG_1 0x1dfc + +#define RTL8367C_REG_STRP_DBG_2 0x1dfd + +/* (16'h1f00)patch_reg */ + +#define RTL8367C_REG_INDRECT_ACCESS_CTRL 0x1f00 +#define RTL8367C_RW_OFFSET 1 +#define RTL8367C_RW_MASK 0x2 +#define RTL8367C_CMD_OFFSET 0 +#define RTL8367C_CMD_MASK 0x1 + +#define RTL8367C_REG_INDRECT_ACCESS_STATUS 0x1f01 +#define RTL8367C_INDRECT_ACCESS_STATUS_OFFSET 2 +#define RTL8367C_INDRECT_ACCESS_STATUS_MASK 0x7 + +#define RTL8367C_REG_INDRECT_ACCESS_ADDRESS 0x1f02 + +#define RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA 0x1f03 + +#define RTL8367C_REG_INDRECT_ACCESS_READ_DATA 0x1f04 + +/* (16'h6200)fib_page */ + +#define RTL8367C_REG_FIB0_CFG00 0x6200 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_OFFSET 15 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_MASK 0x8000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_OFFSET 14 +#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_MASK 0x4000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_OFFSET 12 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_MASK 0x1000 +#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_OFFSET 11 +#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_MASK 0x800 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_OFFSET 10 +#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_MASK 0x400 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_OFFSET 9 +#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_MASK 0x200 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_OFFSET 8 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_MASK 0x100 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 +#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_OFFSET 5 +#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_MASK 0x20 + +#define RTL8367C_REG_FIB0_CFG01 0x6201 +#define RTL8367C_FIB0_CFG01_CAPBILITY_OFFSET 6 +#define RTL8367C_FIB0_CFG01_CAPBILITY_MASK 0xFFC0 +#define RTL8367C_FIB0_CFG01_AN_COMPLETE_OFFSET 5 +#define RTL8367C_FIB0_CFG01_AN_COMPLETE_MASK 0x20 +#define RTL8367C_FIB0_CFG01_R_FAULT_OFFSET 4 +#define RTL8367C_FIB0_CFG01_R_FAULT_MASK 0x10 +#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_OFFSET 3 +#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_MASK 0x8 +#define RTL8367C_FIB0_CFG01_LINK_STATUS_OFFSET 2 +#define RTL8367C_FIB0_CFG01_LINK_STATUS_MASK 0x4 +#define RTL8367C_FIB0_CFG01_JABBER_DETECT_OFFSET 1 +#define RTL8367C_FIB0_CFG01_JABBER_DETECT_MASK 0x2 +#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_OFFSET 0 +#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_MASK 0x1 + +#define RTL8367C_REG_FIB0_CFG02 0x6202 + +#define RTL8367C_REG_FIB0_CFG03 0x6203 +#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_OFFSET 10 +#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_MASK 0xFC00 +#define RTL8367C_FIB0_CFG03_MODEL_NO_OFFSET 4 +#define RTL8367C_FIB0_CFG03_MODEL_NO_MASK 0x3F0 +#define RTL8367C_FIB0_CFG03_REVISION_NO_OFFSET 0 +#define RTL8367C_FIB0_CFG03_REVISION_NO_MASK 0xF + +#define RTL8367C_REG_FIB0_CFG04 0x6204 + +#define RTL8367C_REG_FIB0_CFG05 0x6205 + +#define RTL8367C_REG_FIB0_CFG06 0x6206 +#define RTL8367C_FIB0_CFG06_FIB_NP_EN_OFFSET 2 +#define RTL8367C_FIB0_CFG06_FIB_NP_EN_MASK 0x4 +#define RTL8367C_FIB0_CFG06_RXPAGE_OFFSET 1 +#define RTL8367C_FIB0_CFG06_RXPAGE_MASK 0x2 + +#define RTL8367C_REG_FIB0_CFG07 0x6207 + +#define RTL8367C_REG_FIB0_CFG08 0x6208 + +#define RTL8367C_REG_FIB0_CFG09 0x6209 + +#define RTL8367C_REG_FIB0_CFG10 0x620a + +#define RTL8367C_REG_FIB0_CFG11 0x620b + +#define RTL8367C_REG_FIB0_CFG12 0x620c + +#define RTL8367C_REG_FIB0_CFG13 0x620d +#define RTL8367C_FIB0_CFG13_INDR_FUNC_OFFSET 14 +#define RTL8367C_FIB0_CFG13_INDR_FUNC_MASK 0xC000 +#define RTL8367C_FIB0_CFG13_DUMMY_OFFSET 5 +#define RTL8367C_FIB0_CFG13_DUMMY_MASK 0x3FE0 +#define RTL8367C_FIB0_CFG13_INDR_DEVAD_OFFSET 0 +#define RTL8367C_FIB0_CFG13_INDR_DEVAD_MASK 0x1F + +#define RTL8367C_REG_FIB0_CFG14 0x620e + +#define RTL8367C_REG_FIB0_CFG15 0x620f + +#define RTL8367C_REG_FIB1_CFG00 0x6210 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_OFFSET 15 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_MASK 0x8000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_OFFSET 14 +#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_MASK 0x4000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_OFFSET 12 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_MASK 0x1000 +#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_OFFSET 11 +#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_MASK 0x800 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_OFFSET 10 +#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_MASK 0x400 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_OFFSET 9 +#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_MASK 0x200 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_OFFSET 8 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_MASK 0x100 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 +#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_OFFSET 5 +#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_MASK 0x20 + +#define RTL8367C_REG_FIB1_CFG01 0x6211 +#define RTL8367C_FIB1_CFG01_CAPBILITY_OFFSET 6 +#define RTL8367C_FIB1_CFG01_CAPBILITY_MASK 0xFFC0 +#define RTL8367C_FIB1_CFG01_AN_COMPLETE_OFFSET 5 +#define RTL8367C_FIB1_CFG01_AN_COMPLETE_MASK 0x20 +#define RTL8367C_FIB1_CFG01_R_FAULT_OFFSET 4 +#define RTL8367C_FIB1_CFG01_R_FAULT_MASK 0x10 +#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_OFFSET 3 +#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_MASK 0x8 +#define RTL8367C_FIB1_CFG01_LINK_STATUS_OFFSET 2 +#define RTL8367C_FIB1_CFG01_LINK_STATUS_MASK 0x4 +#define RTL8367C_FIB1_CFG01_JABBER_DETECT_OFFSET 1 +#define RTL8367C_FIB1_CFG01_JABBER_DETECT_MASK 0x2 +#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_OFFSET 0 +#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_MASK 0x1 + +#define RTL8367C_REG_FIB1_CFG02 0x6212 + +#define RTL8367C_REG_FIB1_CFG03 0x6213 +#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_OFFSET 10 +#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_MASK 0xFC00 +#define RTL8367C_FIB1_CFG03_MODEL_NO_OFFSET 4 +#define RTL8367C_FIB1_CFG03_MODEL_NO_MASK 0x3F0 +#define RTL8367C_FIB1_CFG03_REVISION_NO_OFFSET 0 +#define RTL8367C_FIB1_CFG03_REVISION_NO_MASK 0xF + +#define RTL8367C_REG_FIB1_CFG04 0x6214 + +#define RTL8367C_REG_FIB1_CFG05 0x6215 + +#define RTL8367C_REG_FIB1_CFG06 0x6216 +#define RTL8367C_FIB1_CFG06_FIB_NP_EN_OFFSET 2 +#define RTL8367C_FIB1_CFG06_FIB_NP_EN_MASK 0x4 +#define RTL8367C_FIB1_CFG06_RXPAGE_OFFSET 1 +#define RTL8367C_FIB1_CFG06_RXPAGE_MASK 0x2 + +#define RTL8367C_REG_FIB1_CFG07 0x6217 + +#define RTL8367C_REG_FIB1_CFG08 0x6218 + +#define RTL8367C_REG_FIB1_CFG09 0x6219 + +#define RTL8367C_REG_FIB1_CFG10 0x621a + +#define RTL8367C_REG_FIB1_CFG11 0x621b + +#define RTL8367C_REG_FIB1_CFG12 0x621c + +#define RTL8367C_REG_FIB1_CFG13 0x621d +#define RTL8367C_FIB1_CFG13_INDR_FUNC_OFFSET 14 +#define RTL8367C_FIB1_CFG13_INDR_FUNC_MASK 0xC000 +#define RTL8367C_FIB1_CFG13_DUMMY_OFFSET 5 +#define RTL8367C_FIB1_CFG13_DUMMY_MASK 0x3FE0 +#define RTL8367C_FIB1_CFG13_INDR_DEVAD_OFFSET 0 +#define RTL8367C_FIB1_CFG13_INDR_DEVAD_MASK 0x1F + +#define RTL8367C_REG_FIB1_CFG14 0x621e + +#define RTL8367C_REG_FIB1_CFG15 0x621f + +/* (16'h6400)timer_1588 */ + +#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC 0x6400 + +#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC 0x6401 +#define RTL8367C_PTP_TIME_NSEC_H_EXEC_OFFSET 15 +#define RTL8367C_PTP_TIME_NSEC_H_EXEC_MASK 0x8000 +#define RTL8367C_PTP_TIME_NSEC_H_CMD_OFFSET 12 +#define RTL8367C_PTP_TIME_NSEC_H_CMD_MASK 0x3000 +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_OFFSET 0 +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK 0x7FF + +#define RTL8367C_REG_PTP_TIME_SEC_L_SEC 0x6402 + +#define RTL8367C_REG_PTP_TIME_SEC_H_SEC 0x6403 + +#define RTL8367C_REG_PTP_TIME_CFG 0x6404 +#define RTL8367C_CFG_TIMER_EN_FRC_OFFSET 2 +#define RTL8367C_CFG_TIMER_EN_FRC_MASK 0x4 +#define RTL8367C_CFG_TIMER_1588_EN_OFFSET 1 +#define RTL8367C_CFG_TIMER_1588_EN_MASK 0x2 +#define RTL8367C_CFG_CLK_SRC_OFFSET 0 +#define RTL8367C_CFG_CLK_SRC_MASK 0x1 + +#define RTL8367C_REG_OTAG_TPID 0x6405 + +#define RTL8367C_REG_ITAG_TPID 0x6406 + +#define RTL8367C_REG_MAC_ADDR_L 0x6407 + +#define RTL8367C_REG_MAC_ADDR_M 0x6408 + +#define RTL8367C_REG_MAC_ADDR_H 0x6409 + +#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC_RD 0x640a + +#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC_RD 0x640b +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_OFFSET 0 +#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_MASK 0x7FF + +#define RTL8367C_REG_PTP_TIME_SEC_L_SEC_RD 0x640c + +#define RTL8367C_REG_PTP_TIME_SEC_H_SEC_RD 0x640d + +#define RTL8367C_REG_PTP_TIME_CFG2 0x640e +#define RTL8367C_CFG_EN_OFFLOAD_OFFSET 9 +#define RTL8367C_CFG_EN_OFFLOAD_MASK 0x200 +#define RTL8367C_CFG_SAVE_OFF_TS_OFFSET 8 +#define RTL8367C_CFG_SAVE_OFF_TS_MASK 0x100 +#define RTL8367C_CFG_IMR_OFFSET 0 +#define RTL8367C_CFG_IMR_MASK 0xFF + +#define RTL8367C_REG_PTP_INTERRUPT_CFG 0x640f +#define RTL8367C_P9_INTERRUPT_OFFSET 9 +#define RTL8367C_P9_INTERRUPT_MASK 0x200 +#define RTL8367C_P8_INTERRUPT_OFFSET 8 +#define RTL8367C_P8_INTERRUPT_MASK 0x100 +#define RTL8367C_P7_INTERRUPT_OFFSET 7 +#define RTL8367C_P7_INTERRUPT_MASK 0x80 +#define RTL8367C_P6_INTERRUPT_OFFSET 6 +#define RTL8367C_P6_INTERRUPT_MASK 0x40 +#define RTL8367C_P5_INTERRUPT_OFFSET 5 +#define RTL8367C_P5_INTERRUPT_MASK 0x20 +#define RTL8367C_P4_INTERRUPT_OFFSET 4 +#define RTL8367C_P4_INTERRUPT_MASK 0x10 +#define RTL8367C_P3_INTERRUPT_OFFSET 3 +#define RTL8367C_P3_INTERRUPT_MASK 0x8 +#define RTL8367C_P2_INTERRUPT_OFFSET 2 +#define RTL8367C_P2_INTERRUPT_MASK 0x4 +#define RTL8367C_P1_INTERRUPT_OFFSET 1 +#define RTL8367C_P1_INTERRUPT_MASK 0x2 +#define RTL8367C_P0_INTERRUPT_OFFSET 0 +#define RTL8367C_P0_INTERRUPT_MASK 0x1 + +#define RTL8367C_REG_P0_TX_SYNC_SEQ_ID 0x6410 + +#define RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID 0x6411 + +#define RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID 0x6412 + +#define RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID 0x6413 + +#define RTL8367C_REG_P0_RX_SYNC_SEQ_ID 0x6414 + +#define RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID 0x6415 + +#define RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID 0x6416 + +#define RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID 0x6417 + +#define RTL8367C_REG_P0_PORT_NSEC_15_0 0x6418 + +#define RTL8367C_REG_P0_PORT_NSEC_26_16 0x6419 +#define RTL8367C_P0_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P0_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P0_PORT_SEC_15_0 0x641a + +#define RTL8367C_REG_P0_PORT_SEC_31_16 0x641b + +#define RTL8367C_REG_P0_EAV_CFG 0x641c +#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P0_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P0_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P1_TX_SYNC_SEQ_ID 0x6420 + +#define RTL8367C_REG_P1_TX_DELAY_REQ_SEQ_ID 0x6421 + +#define RTL8367C_REG_P1_TX_PDELAY_REQ_SEQ_ID 0x6422 + +#define RTL8367C_REG_P1_TX_PDELAY_RESP_SEQ_ID 0x6423 + +#define RTL8367C_REG_P1_RX_SYNC_SEQ_ID 0x6424 + +#define RTL8367C_REG_P1_RX_DELAY_REQ_SEQ_ID 0x6425 + +#define RTL8367C_REG_P1_RX_PDELAY_REQ_SEQ_ID 0x6426 + +#define RTL8367C_REG_P1_RX_PDELAY_RESP_SEQ_ID 0x6427 + +#define RTL8367C_REG_P1_PORT_NSEC_15_0 0x6428 + +#define RTL8367C_REG_P1_PORT_NSEC_26_16 0x6429 +#define RTL8367C_P1_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P1_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P1_PORT_SEC_15_0 0x642a + +#define RTL8367C_REG_P1_PORT_SEC_31_16 0x642b + +#define RTL8367C_REG_P1_EAV_CFG 0x642c +#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P1_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P1_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P1_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P1_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P2_TX_SYNC_SEQ_ID 0x6430 + +#define RTL8367C_REG_P2_TX_DELAY_REQ_SEQ_ID 0x6431 + +#define RTL8367C_REG_P2_TX_PDELAY_REQ_SEQ_ID 0x6432 + +#define RTL8367C_REG_P2_TX_PDELAY_RESP_SEQ_ID 0x6433 + +#define RTL8367C_REG_P2_RX_SYNC_SEQ_ID 0x6434 + +#define RTL8367C_REG_P2_RX_DELAY_REQ_SEQ_ID 0x6435 + +#define RTL8367C_REG_P2_RX_PDELAY_REQ_SEQ_ID 0x6436 + +#define RTL8367C_REG_P2_RX_PDELAY_RESP_SEQ_ID 0x6437 + +#define RTL8367C_REG_P2_PORT_NSEC_15_0 0x6438 + +#define RTL8367C_REG_P2_PORT_NSEC_26_16 0x6439 +#define RTL8367C_P2_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P2_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P2_PORT_SEC_15_0 0x643a + +#define RTL8367C_REG_P2_PORT_SEC_31_16 0x643b + +#define RTL8367C_REG_P2_EAV_CFG 0x643c +#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P2_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P2_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P2_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P2_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P3_TX_SYNC_SEQ_ID 0x6440 + +#define RTL8367C_REG_P3_TX_DELAY_REQ_SEQ_ID 0x6441 + +#define RTL8367C_REG_P3_TX_PDELAY_REQ_SEQ_ID 0x6442 + +#define RTL8367C_REG_P3_TX_PDELAY_RESP_SEQ_ID 0x6443 + +#define RTL8367C_REG_P3_RX_SYNC_SEQ_ID 0x6444 + +#define RTL8367C_REG_P3_RX_DELAY_REQ_SEQ_ID 0x6445 + +#define RTL8367C_REG_P3_RX_PDELAY_REQ_SEQ_ID 0x6446 + +#define RTL8367C_REG_P3_RX_PDELAY_RESP_SEQ_ID 0x6447 + +#define RTL8367C_REG_P3_PORT_NSEC_15_0 0x6448 + +#define RTL8367C_REG_P3_PORT_NSEC_26_16 0x6449 +#define RTL8367C_P3_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P3_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P3_PORT_SEC_15_0 0x644a + +#define RTL8367C_REG_P3_PORT_SEC_31_16 0x644b + +#define RTL8367C_REG_P3_EAV_CFG 0x644c +#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P3_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P3_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P3_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P3_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P4_TX_SYNC_SEQ_ID 0x6450 + +#define RTL8367C_REG_P4_TX_DELAY_REQ_SEQ_ID 0x6451 + +#define RTL8367C_REG_P4_TX_PDELAY_REQ_SEQ_ID 0x6452 + +#define RTL8367C_REG_P4_TX_PDELAY_RESP_SEQ_ID 0x6453 + +#define RTL8367C_REG_P4_RX_SYNC_SEQ_ID 0x6454 + +#define RTL8367C_REG_P4_RX_DELAY_REQ_SEQ_ID 0x6455 + +#define RTL8367C_REG_P4_RX_PDELAY_REQ_SEQ_ID 0x6456 + +#define RTL8367C_REG_P4_RX_PDELAY_RESP_SEQ_ID 0x6457 + +#define RTL8367C_REG_P4_PORT_NSEC_15_0 0x6458 + +#define RTL8367C_REG_P4_PORT_NSEC_26_16 0x6459 +#define RTL8367C_P4_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P4_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P4_PORT_SEC_15_0 0x645a + +#define RTL8367C_REG_P4_PORT_SEC_31_16 0x645b + +#define RTL8367C_REG_P4_EAV_CFG 0x645c +#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P4_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P4_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P4_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P4_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P6_TX_SYNC_SEQ_ID 0x6460 + +#define RTL8367C_REG_P6_TX_DELAY_REQ_SEQ_ID 0x6461 + +#define RTL8367C_REG_P6_TX_PDELAY_REQ_SEQ_ID 0x6462 + +#define RTL8367C_REG_P6_TX_PDELAY_RESP_SEQ_ID 0x6463 + +#define RTL8367C_REG_P6_RX_SYNC_SEQ_ID 0x6464 + +#define RTL8367C_REG_P6_RX_DELAY_REQ_SEQ_ID 0x6465 + +#define RTL8367C_REG_P6_RX_PDELAY_REQ_SEQ_ID 0x6466 + +#define RTL8367C_REG_P6_RX_PDELAY_RESP_SEQ_ID 0x6467 + +#define RTL8367C_REG_P6_PORT_NSEC_15_0 0x6468 + +#define RTL8367C_REG_P6_PORT_NSEC_26_16 0x6469 +#define RTL8367C_P6_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P6_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P6_PORT_SEC_15_0 0x646a + +#define RTL8367C_REG_P6_PORT_SEC_31_16 0x646b + +#define RTL8367C_REG_P6_EAV_CFG 0x646c +#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P6_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P6_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P6_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P6_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P7_TX_SYNC_SEQ_ID 0x6470 + +#define RTL8367C_REG_P7_TX_DELAY_REQ_SEQ_ID 0x6471 + +#define RTL8367C_REG_P7_TX_PDELAY_REQ_SEQ_ID 0x6472 + +#define RTL8367C_REG_P7_TX_PDELAY_RESP_SEQ_ID 0x6473 + +#define RTL8367C_REG_P7_RX_SYNC_SEQ_ID 0x6474 + +#define RTL8367C_REG_P7_RX_DELAY_REQ_SEQ_ID 0x6475 + +#define RTL8367C_REG_P7_RX_PDELAY_REQ_SEQ_ID 0x6476 + +#define RTL8367C_REG_P7_RX_PDELAY_RESP_SEQ_ID 0x6477 + +#define RTL8367C_REG_P7_PORT_NSEC_15_0 0x6478 + +#define RTL8367C_REG_P7_PORT_NSEC_26_16 0x6479 +#define RTL8367C_P7_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P7_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P7_PORT_SEC_15_0 0x647a + +#define RTL8367C_REG_P7_PORT_SEC_31_16 0x647b + +#define RTL8367C_REG_P7_EAV_CFG 0x647c +#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P7_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P7_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P7_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P7_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P5_TX_SYNC_SEQ_ID 0x6480 + +#define RTL8367C_REG_P5_TX_DELAY_REQ_SEQ_ID 0x6481 + +#define RTL8367C_REG_P5_TX_PDELAY_REQ_SEQ_ID 0x6482 + +#define RTL8367C_REG_P5_TX_PDELAY_RESP_SEQ_ID 0x6483 + +#define RTL8367C_REG_P5_RX_SYNC_SEQ_ID 0x6484 + +#define RTL8367C_REG_P5_RX_DELAY_REQ_SEQ_ID 0x6485 + +#define RTL8367C_REG_P5_RX_PDELAY_REQ_SEQ_ID 0x6486 + +#define RTL8367C_REG_P5_RX_PDELAY_RESP_SEQ_ID 0x6487 + +#define RTL8367C_REG_P5_PORT_NSEC_15_0 0x6488 + +#define RTL8367C_REG_P5_PORT_NSEC_26_16 0x6489 +#define RTL8367C_P5_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P5_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P5_PORT_SEC_15_0 0x648a + +#define RTL8367C_REG_P5_PORT_SEC_31_16 0x648b + +#define RTL8367C_REG_P5_EAV_CFG 0x648c +#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P5_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P5_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P5_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P5_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P8_TX_SYNC_SEQ_ID 0x6490 + +#define RTL8367C_REG_P8_TX_DELAY_REQ_SEQ_ID 0x6491 + +#define RTL8367C_REG_P8_TX_PDELAY_REQ_SEQ_ID 0x6492 + +#define RTL8367C_REG_P8_TX_PDELAY_RESP_SEQ_ID 0x6493 + +#define RTL8367C_REG_P8_RX_SYNC_SEQ_ID 0x6494 + +#define RTL8367C_REG_P8_RX_DELAY_REQ_SEQ_ID 0x6495 + +#define RTL8367C_REG_P8_RX_PDELAY_REQ_SEQ_ID 0x6496 + +#define RTL8367C_REG_P8_RX_PDELAY_RESP_SEQ_ID 0x6497 + +#define RTL8367C_REG_P8_PORT_NSEC_15_0 0x6498 + +#define RTL8367C_REG_P8_PORT_NSEC_26_16 0x6499 +#define RTL8367C_P8_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P8_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P8_PORT_SEC_15_0 0x649a + +#define RTL8367C_REG_P8_PORT_SEC_31_16 0x649b + +#define RTL8367C_REG_P8_EAV_CFG 0x649c +#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P8_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P8_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P8_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P8_EAV_CFG_TX_SYNC_MASK 0x1 + +#define RTL8367C_REG_P9_TX_SYNC_SEQ_ID 0x64a0 + +#define RTL8367C_REG_P9_TX_DELAY_REQ_SEQ_ID 0x64a1 + +#define RTL8367C_REG_P9_TX_PDELAY_REQ_SEQ_ID 0x64a2 + +#define RTL8367C_REG_P9_TX_PDELAY_RESP_SEQ_ID 0x64a3 + +#define RTL8367C_REG_P9_RX_SYNC_SEQ_ID 0x64a4 + +#define RTL8367C_REG_P9_RX_DELAY_REQ_SEQ_ID 0x64a5 + +#define RTL8367C_REG_P9_RX_PDELAY_REQ_SEQ_ID 0x64a6 + +#define RTL8367C_REG_P9_RX_PDELAY_RESP_SEQ_ID 0x64a7 + +#define RTL8367C_REG_P9_PORT_NSEC_15_0 0x64a8 + +#define RTL8367C_REG_P9_PORT_NSEC_26_16 0x64a9 +#define RTL8367C_P9_PORT_NSEC_26_16_OFFSET 0 +#define RTL8367C_P9_PORT_NSEC_26_16_MASK 0x7FF + +#define RTL8367C_REG_P9_PORT_SEC_15_0 0x64aa + +#define RTL8367C_REG_P9_PORT_SEC_31_16 0x64ab + +#define RTL8367C_REG_P9_EAV_CFG 0x64ac +#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 +#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 +#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 +#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_OFFSET 5 +#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_MASK 0x20 +#define RTL8367C_P9_EAV_CFG_RX_SYNC_OFFSET 4 +#define RTL8367C_P9_EAV_CFG_RX_SYNC_MASK 0x10 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 +#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 +#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_OFFSET 1 +#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_MASK 0x2 +#define RTL8367C_P9_EAV_CFG_TX_SYNC_OFFSET 0 +#define RTL8367C_P9_EAV_CFG_TX_SYNC_MASK 0x1 + +/* (16'h6600)sds_indacs_reg */ + +#define RTL8367C_REG_SDS_INDACS_CMD 0x6600 +#define RTL8367C_SDS_CMD_BUSY_OFFSET 8 +#define RTL8367C_SDS_CMD_BUSY_MASK 0x100 +#define RTL8367C_SDS_CMD_OFFSET 7 +#define RTL8367C_SDS_CMD_MASK 0x80 +#define RTL8367C_SDS_RWOP_OFFSET 6 +#define RTL8367C_SDS_RWOP_MASK 0x40 +#define RTL8367C_SDS_INDEX_OFFSET 0 +#define RTL8367C_SDS_INDEX_MASK 0x3F + +#define RTL8367C_REG_SDS_INDACS_ADR 0x6601 +#define RTL8367C_SDS_PAGE_OFFSET 5 +#define RTL8367C_SDS_PAGE_MASK 0x7E0 +#define RTL8367C_SDS_REGAD_OFFSET 0 +#define RTL8367C_SDS_REGAD_MASK 0x1F + +#define RTL8367C_REG_SDS_INDACS_DATA 0x6602 + + +#endif /*#ifndef _RTL8367C_REG_H_*/ + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/smi.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/smi.h new file mode 100755 index 00000000..b77d7607 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/smi.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367C switch low-level function for access register + * Feature : SMI related functions + * + */ + +#ifndef __SMI_H__ +#define __SMI_H__ + +#include +#include "rtk_error.h" + +#define MDC_MDIO_CTRL0_REG 31 +#define MDC_MDIO_START_REG 29 +#define MDC_MDIO_CTRL1_REG 21 +#define MDC_MDIO_ADDRESS_REG 23 +#define MDC_MDIO_DATA_WRITE_REG 24 +#define MDC_MDIO_DATA_READ_REG 25 +#define MDC_MDIO_PREAMBLE_LEN 32 + +#define MDC_MDIO_START_OP 0xFFFF +#define MDC_MDIO_ADDR_OP 0x000E +#define MDC_MDIO_READ_OP 0x0001 +#define MDC_MDIO_WRITE_OP 0x0003 + +#define SPI_READ_OP 0x3 +#define SPI_WRITE_OP 0x2 +#define SPI_READ_OP_LEN 0x8 +#define SPI_WRITE_OP_LEN 0x8 +#define SPI_REG_LEN 16 +#define SPI_DATA_LEN 16 + +#define GPIO_DIR_IN 1 +#define GPIO_DIR_OUT 0 + +#define ack_timer 5 + +#define DELAY 10000 +#define CLK_DURATION(clk) { int i; for(i=0; isvid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *psvlan_cfg); + +/* Function Name: + * rtk_svlan_memberPortEntry_get + * Description: + * Get SVLAN member Configure. + * Input: + * svid - SVLAN id + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *pSvlan_cfg); + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_set + * Description: + * Configure system SVLAN member by index + * Input: + * idx - Index (0 ~ 63) + * psvlan_cfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. + * Note: + * The API can set system 64 accepted s-tag frame format by index. + * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_get + * Description: + * Get SVLAN member Configure by index. + * Input: + * idx - Index (0 ~ 63) + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); + +/* Function Name: + * rtk_svlan_defaultSvlan_set + * Description: + * Configure default egress SVLAN. + * Input: + * port - Source port + * svid - SVLAN id + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * Note: + * The API can set port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +extern rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_defaultSvlan_get + * Description: + * Get the configure default egress SVLAN. + * Input: + * port - Source port + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +extern rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_c2s_add + * Description: + * Configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set system C2S configuration. ASIC will check upstream's VID and assign related + * SVID to mathed packet. There are 128 SVLAN C2S configurations. + */ +extern rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_c2s_del + * Description: + * Delete one C2S entry + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete system C2S configuration. There are 128 SVLAN C2S configurations. + */ +extern rtk_api_ret_t rtk_svlan_c2s_del(rtk_vlan_t vid, rtk_port_t src_port); + +/* Function Name: + * rtk_svlan_c2s_get + * Description: + * Get configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * Output: + * pSvid - SVLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. + */ +extern rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_untag_action_set + * Description: + * Configure Action of downstream Un-Stag packet + * Input: + * action - Action for UnStag + * svid - The SVID assigned to UnStag packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also supported by this API. The parameter of svid is + * only referenced when the action is set to UNTAG_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_untag_action_get + * Description: + * Get Action of downstream Un-Stag packet + * Input: + * None + * Output: + * pAction - Action for UnStag + * pSvid - The SVID assigned to UnStag packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNTAG_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_unmatch_action_set + * Description: + * Configure Action of downstream Unmatch packet + * Input: + * action - Action for Unmatch + * svid - The SVID assigned to Unmatch packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-match packet. A SVID assigned + * to the un-match is also supported by this API. The parameter od svid is + * only refernced when the action is set to UNMATCH_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_unmatch_action_get + * Description: + * Get Action of downstream Unmatch packet + * Input: + * None + * Output: + * pAction - Action for Unmatch + * pSvid - The SVID assigned to Unmatch packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-match packet. A SVID assigned + * to the un-match is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNMATCH_ASSIGN + */ +extern rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_dmac_vidsel_set + * Description: + * Set DMAC CVID selection + * Input: + * port - Port + * enable - state of DMAC CVID Selection + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set DMAC CVID Selection state + */ +extern rtk_api_ret_t rtk_svlan_dmac_vidsel_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_svlan_dmac_vidsel_get + * Description: + * Get DMAC CVID selection + * Input: + * port - Port + * Output: + * pEnable - state of DMAC CVID Selection + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get DMAC CVID Selection state + */ +extern rtk_api_ret_t rtk_svlan_dmac_vidsel_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_svlan_ipmc2s_add + * Description: + * add ip multicast address to SVLAN + * Input: + * svid - SVLAN VID + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set IP mutlicast to SVID configuration. If upstream packet is IPv4 multicast + * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. + * There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_ipmc2s_del + * Description: + * delete ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk); + +/* Function Name: + * rtk_svlan_ipmc2s_get + * Description: + * Get ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_l2mc2s_add + * Description: + * Add L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set L2 Mutlicast to SVID configuration. If upstream packet is L2 multicast + * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 + * SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid); + +/* Function Name: + * rtk_svlan_l2mc2s_del + * Description: + * delete L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete Mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk); + +/* Function Name: + * rtk_svlan_l2mc2s_get + * Description: + * Get L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get L2 mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +extern rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid); + +/* Function Name: + * rtk_svlan_sp2c_add + * Description: + * Add system SP2C configuration + * Input: + * cvid - VLAN ID + * dst_port - Destination port of SVLAN to CVLAN configuration + * svid - SVLAN VID + * + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned + * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. + * There are 128 SP2C configurations. + */ +extern rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid); + +/* Function Name: + * rtk_svlan_sp2c_get + * Description: + * Get configure system SP2C content + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * pCvid - VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * Note: + * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +extern rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid); + +/* Function Name: + * rtk_svlan_sp2c_del + * Description: + * Delete system SP2C configuration + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +extern rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port); + + +/* Function Name: + * rtk_svlan_lookupType_set + * Description: + * Set lookup type of SVLAN + * Input: + * type - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +extern rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type); + +/* Function Name: + * rtk_svlan_lookupType_get + * Description: + * Get lookup type of SVLAN + * Input: + * pType - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +extern rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType); + +/* Function Name: + * rtk_svlan_trapPri_set + * Description: + * Set svlan trap priority + * Input: + * priority - priority for trap packets + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_INT_PRIORITY + * Note: + * None + */ +extern rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority); + +/* Function Name: + * rtk_svlan_trapPri_get + * Description: + * Get svlan trap priority + * Input: + * None + * Output: + * pPriority - priority for trap packets + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +extern rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority); + +/* Function Name: + * rtk_svlan_unassign_action_set + * Description: + * Configure Action of upstream without svid assign action + * Input: + * action - Action for Un-assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of upstream Un-assign svid packet. If action is not + * trap to CPU, the port-based SVID sure be assign as system need + */ +extern rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action); + +/* Function Name: + * rtk_svlan_unassign_action_get + * Description: + * Get action of upstream without svid assignment + * Input: + * None + * Output: + * pAction - Action for Un-assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * None + */ +extern rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction); + + +/* Function Name: + * rtk_svlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +extern rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); + + +#endif /* __RTK_API_SVLAN_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trap.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trap.h new file mode 100755 index 00000000..0cdb64a7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trap.h @@ -0,0 +1,757 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Trap module high-layer API defination + * + */ + +#ifndef __RTK_API_TRAP_H__ +#define __RTK_API_TRAP_H__ + + +typedef enum rtk_trap_type_e +{ + TRAP_BRG_GROUP = 0, + TRAP_FD_PAUSE, + TRAP_SP_MCAST, + TRAP_1X_PAE, + TRAP_UNDEF_BRG_04, + TRAP_UNDEF_BRG_05, + TRAP_UNDEF_BRG_06, + TRAP_UNDEF_BRG_07, + TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + TRAP_UNDEF_BRG_09, + TRAP_UNDEF_BRG_0A, + TRAP_UNDEF_BRG_0B, + TRAP_UNDEF_BRG_0C, + TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + TRAP_8021AB, + TRAP_UNDEF_BRG_0F, + TRAP_BRG_MNGEMENT, + TRAP_UNDEFINED_11, + TRAP_UNDEFINED_12, + TRAP_UNDEFINED_13, + TRAP_UNDEFINED_14, + TRAP_UNDEFINED_15, + TRAP_UNDEFINED_16, + TRAP_UNDEFINED_17, + TRAP_UNDEFINED_18, + TRAP_UNDEFINED_19, + TRAP_UNDEFINED_1A, + TRAP_UNDEFINED_1B, + TRAP_UNDEFINED_1C, + TRAP_UNDEFINED_1D, + TRAP_UNDEFINED_1E, + TRAP_UNDEFINED_1F, + TRAP_GMRP, + TRAP_GVRP, + TRAP_UNDEF_GARP_22, + TRAP_UNDEF_GARP_23, + TRAP_UNDEF_GARP_24, + TRAP_UNDEF_GARP_25, + TRAP_UNDEF_GARP_26, + TRAP_UNDEF_GARP_27, + TRAP_UNDEF_GARP_28, + TRAP_UNDEF_GARP_29, + TRAP_UNDEF_GARP_2A, + TRAP_UNDEF_GARP_2B, + TRAP_UNDEF_GARP_2C, + TRAP_UNDEF_GARP_2D, + TRAP_UNDEF_GARP_2E, + TRAP_UNDEF_GARP_2F, + TRAP_CDP, + TRAP_CSSTP, + TRAP_LLDP, + TRAP_END, +}rtk_trap_type_t; + + +typedef enum rtk_mcast_type_e +{ + MCAST_L2 = 0, + MCAST_IPV4, + MCAST_IPV6, + MCAST_END +} rtk_mcast_type_t; + +typedef enum rtk_trap_mcast_action_e +{ + MCAST_ACTION_FORWARD = 0, + MCAST_ACTION_DROP, + MCAST_ACTION_TRAP2CPU, + MCAST_ACTION_ROUTER_PORT, + MCAST_ACTION_DROP_EX_RMA, + MCAST_ACTION_END +} rtk_trap_mcast_action_t; + +typedef enum rtk_trap_rma_action_e +{ + RMA_ACTION_FORWARD = 0, + RMA_ACTION_TRAP2CPU, + RMA_ACTION_DROP, + RMA_ACTION_FORWARD_EXCLUDE_CPU, + RMA_ACTION_END +} rtk_trap_rma_action_t; + +typedef enum rtk_trap_ucast_action_e +{ + UCAST_ACTION_FORWARD_PMASK = 0, + UCAST_ACTION_DROP, + UCAST_ACTION_TRAP2CPU, + UCAST_ACTION_FLOODING, + UCAST_ACTION_END +} rtk_trap_ucast_action_t; + +typedef enum rtk_trap_ucast_type_e +{ + UCAST_UNKNOWNDA = 0, + UCAST_UNKNOWNSA, + UCAST_UNMATCHSA, + UCAST_END +} rtk_trap_ucast_type_t; + +typedef enum rtk_trap_reason_type_e +{ + TRAP_REASON_RMA = 0, + TRAP_REASON_OAM, + TRAP_REASON_1XUNAUTH, + TRAP_REASON_VLANSTACK, + TRAP_REASON_UNKNOWNMC, + TRAP_REASON_END, +} rtk_trap_reason_type_t; + + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_set + * Description: + * Set unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * ucast_action - Unknown unicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action); + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_get + * Description: + * Get unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * Output: + * pUcast_action - Unknown unicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * This API can get unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action); + +/* Function Name: + * rtk_trap_unknownMacPktAction_set + * Description: + * Set unknown source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action); + +/* Function Name: + * rtk_trap_unknownMacPktAction_get + * Description: + * Get unknown source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); + +/* Function Name: + * rtk_trap_unmatchMacPktAction_set + * Description: + * Set unmatch source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action); + +/* Function Name: + * rtk_trap_unmatchMacPktAction_get + * Description: + * Get unmatch source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); + +/* Function Name: + * rtk_trap_unmatchMacMoving_set + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +extern rtk_api_ret_t rtk_trap_unmatchMacMoving_set(rtk_port_t port, rtk_enable_t enable); + +/* Function Name: + * rtk_trap_unmatchMacMoving_get + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * Output: + * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +extern rtk_api_ret_t rtk_trap_unmatchMacMoving_get(rtk_port_t port, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_trap_unknownMcastPktAction_set + * Description: + * Set behavior of unknown multicast + * Input: + * port - Port id. + * type - unknown multicast packet type. + * mcast_action - unknown multicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action); + +/* Function Name: + * rtk_trap_unknownMcastPktAction_get + * Description: + * Get behavior of unknown multicast + * Input: + * type - unknown multicast packet type. + * Output: + * pMcast_action - unknown multicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid operation. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action); + +/* Function Name: + * rtk_trap_lldpEnable_set + * Description: + * Set LLDP enable. + * Input: + * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + + */ +extern rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_trap_lldpEnable_get + * Description: + * Get LLDP status. + * Input: + * None + * Output: + * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * LLDP is as following definition. + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + */ +extern rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_set + * Description: + * Set priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * priority - internal priority that is going to be set for specific trap reason. + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority); + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_get + * Description: + * Get priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * Output: + * pPriority - configured internal priority for such reason. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority); + +/* Function Name: + * rtk_trap_rmaAction_set + * Description: + * Set Reserved multicast address action configuration. + * Input: + * type - rma type. + * rma_action - RMA action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +extern rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action); + +/* Function Name: + * rtk_trap_rmaAction_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pRma_action - RMA action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +extern rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action); + +/* Function Name: + * rtk_trap_rmaKeepFormat_set + * Description: + * Set Reserved multicast address keep format configuration. + * Input: + * type - rma type. + * enable - enable keep format. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +extern rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable); + +/* Function Name: + * rtk_trap_rmaKeepFormat_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pEnable - keep format status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +extern rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable); + + +#endif /* __RTK_API_TRAP_H__ */ + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trunk.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trunk.h new file mode 100755 index 00000000..dff61769 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/trunk.h @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Trunk module high-layer TRUNK defination + * + */ + +#ifndef __RTK_API_TRUNK_H__ +#define __RTK_API_TRUNK_H__ + +/* + * Data Type Declaration + */ +#define RTK_TRUNK_DPORT_HASH_MASK 0x40 +#define RTK_TRUNK_SPORT_HASH_MASK 0x20 +#define RTK_TRUNK_DIP_HASH_MASK 0x10 +#define RTK_TRUNK_SIP_HASH_MASK 0x8 +#define RTK_TRUNK_DMAC_HASH_MASK 0x4 +#define RTK_TRUNK_SMAC_HASH_MASK 0x2 +#define RTK_TRUNK_SPA_HASH_MASK 0x1 + + +#define RTK_MAX_NUM_OF_TRUNK_HASH_VAL 16 + +typedef struct rtk_trunk_hashVal2Port_s +{ + rtk_uint8 value[RTK_MAX_NUM_OF_TRUNK_HASH_VAL]; +} rtk_trunk_hashVal2Port_t; + +typedef enum rtk_trunk_group_e +{ + TRUNK_GROUP0 = 0, + TRUNK_GROUP1, + TRUNK_GROUP2, + TRUNK_GROUP3, + TRUNK_GROUP_END +} rtk_trunk_group_t; + +typedef enum rtk_trunk_separateType_e +{ + SEPARATE_NONE = 0, + SEPARATE_FLOOD, + SEPARATE_END + +} rtk_trunk_separateType_t; + +typedef enum rtk_trunk_mode_e +{ + TRUNK_MODE_NORMAL = 0, + TRUNK_MODE_DUMB, + TRUNK_MODE_END +} rtk_trunk_mode_t; + +/* Function Name: + * rtk_trunk_port_set + * Description: + * Set trunking group available port mask + * Input: + * trk_gid - trunk group id + * pTrunk_member_portmask - Logic trunking member port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking group port mask. Each port trunking group has max 4 ports. + * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. + */ +extern rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); + +/* Function Name: + * rtk_trunk_port_get + * Description: + * Get trunking group available port mask + * Input: + * trk_gid - trunk group id + * Output: + * pTrunk_member_portmask - Logic trunking member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get 2 port trunking group. + */ +extern rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); + +/* Function Name: + * rtk_trunk_distributionAlgorithm_set + * Description: + * Set port trunking hash select sources + * Input: + * trk_gid - trunk group id + * algo_bitmask - Bitmask of the distribution algorithm + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_LA_HASHMASK - Hash algorithm selection error. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking hash algorithm sources. + * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} + * - 0b0000001: SPA + * - 0b0000010: SMAC + * - 0b0000100: DMAC + * - 0b0001000: SIP + * - 0b0010000: DIP + * - 0b0100000: TCP/UDP Source Port + * - 0b1000000: TCP/UDP Destination Port + * Example: + * - 0b0000011: SMAC & SPA + * - Note that it could be an arbitrary combination or independent set + */ +extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask); + +/* Function Name: + * rtk_trunk_distributionAlgorithm_get + * Description: + * Get port trunking hash select sources + * Input: + * trk_gid - trunk group id + * Output: + * pAlgo_bitmask - Bitmask of the distribution algorithm + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get port trunking hash algorithm sources. + */ +extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask); + +/* Function Name: + * rtk_trunk_trafficSeparate_set + * Description: + * Set the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * separateType - traffic separation setting + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_LA_HASHMASK - invalid hash mask + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +extern rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType); + +/* Function Name: + * rtk_trunk_trafficSeparate_get + * Description: + * Get the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pSeparateType - pointer separated traffic type + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +extern rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType); + + +/* Function Name: + * rtk_trunk_mode_set + * Description: + * Set the trunk mode to the specified device. + * Input: + * mode - trunk mode + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +extern rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode); + +/* Function Name: + * rtk_trunk_mode_get + * Description: + * Get the trunk mode from the specified device. + * Input: + * None + * Output: + * pMode - pointer buffer of trunk mode + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +extern rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode); + +/* Function Name: + * rtk_trunk_trafficPause_set + * Description: + * Set the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * enable - traffic pause state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * Note: + * None. + */ +extern rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable); + +/* Function Name: + * rtk_trunk_trafficPause_get + * Description: + * Get the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * Output: + * pEnable - pointer of traffic pause state. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +extern rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable); + +/* Function Name: + * rtk_trunk_hashMappingTable_set + * Description: + * Set hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * pHash2Port_array - ports associate with the hash value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist + * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk + * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +extern rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); + +/* Function Name: + * rtk_trunk_hashMappingTable_get + * Description: + * Get hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pHash2Port_array - pointer buffer of ports associate with the hash value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +extern rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); + +/* Function Name: + * rtk_trunk_portQueueEmpty_get + * Description: + * Get the port mask which all queues are empty. + * Input: + * None. + * Output: + * pEmpty_portmask - pointer empty port mask + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +extern rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask); + +#endif /* __RTK_API_TRUNK_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/vlan.h b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/vlan.h new file mode 100755 index 00000000..8569fc0d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/include/vlan.h @@ -0,0 +1,892 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367/RTL8367C switch high-level API + * + * Feature : The file includes Trap module high-layer VLAN defination + * + */ + +#ifndef __RTK_API_VLAN_H__ +#define __RTK_API_VLAN_H__ + + +/* + * Data Type Declaration + */ +#define RTK_MAX_NUM_OF_PROTO_TYPE 0xFFFF +#define RTK_MAX_NUM_OF_MSTI 0xF +#define RTK_FID_MAX 0xF + +typedef struct rtk_vlan_cfg_s +{ + rtk_portmask_t mbr; + rtk_portmask_t untag; + rtk_uint16 ivl_en; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; +}rtk_vlan_cfg_t; + +typedef struct rtk_vlan_mbrcfg_s +{ + rtk_uint16 evid; + rtk_portmask_t mbr; + rtk_uint16 fid_msti; + rtk_uint16 envlanpol; + rtk_uint16 meteridx; + rtk_uint16 vbpen; + rtk_uint16 vbpri; +}rtk_vlan_mbrcfg_t; + +typedef rtk_uint32 rtk_stp_msti_id_t; /* MSTI ID */ + +typedef enum rtk_stp_state_e +{ + STP_STATE_DISABLED = 0, + STP_STATE_BLOCKING, + STP_STATE_LEARNING, + STP_STATE_FORWARDING, + STP_STATE_END +} rtk_stp_state_t; + +typedef rtk_uint32 rtk_vlan_proto_type_t; /* protocol and port based VLAN protocol type */ + + +typedef enum rtk_vlan_acceptFrameType_e +{ + ACCEPT_FRAME_TYPE_ALL = 0, /* untagged, priority-tagged and tagged */ + ACCEPT_FRAME_TYPE_TAG_ONLY, /* tagged */ + ACCEPT_FRAME_TYPE_UNTAG_ONLY, /* untagged and priority-tagged */ + ACCEPT_FRAME_TYPE_END +} rtk_vlan_acceptFrameType_t; + + +/* frame type of protocol vlan - reference 802.1v standard */ +typedef enum rtk_vlan_protoVlan_frameType_e +{ + FRAME_TYPE_ETHERNET = 0, + FRAME_TYPE_LLCOTHER, + FRAME_TYPE_RFC1042, + FRAME_TYPE_END +} rtk_vlan_protoVlan_frameType_t; + +/* Protocol-and-port-based Vlan structure */ +typedef struct rtk_vlan_protoAndPortInfo_s +{ + rtk_uint32 proto_type; + rtk_vlan_protoVlan_frameType_t frame_type; + rtk_vlan_t cvid; + rtk_pri_t cpri; +}rtk_vlan_protoAndPortInfo_t; + +/* tagged mode of VLAN - reference realtek private specification */ +typedef enum rtk_vlan_tagMode_e +{ + VLAN_TAG_MODE_ORIGINAL = 0, + VLAN_TAG_MODE_KEEP_FORMAT, + VLAN_TAG_MODE_PRI, + VLAN_TAG_MODE_REAL_KEEP_FORMAT, + VLAN_TAG_MODE_END +} rtk_vlan_tagMode_t; + +typedef enum rtk_vlan_resVidAction_e +{ + RESVID_ACTION_UNTAG = 0, + RESVID_ACTION_TAG, + RESVID_ACTION_END +} +rtk_vlan_resVidAction_t; + +/* Function Name: + * rtk_vlan_init + * Description: + * Initialize VLAN. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * VLAN is disabled by default. User has to call this API to enable VLAN before + * using it. And It will set a default VLAN(vid 1) including all ports and set + * all ports PVID to the default VLAN. + */ +extern rtk_api_ret_t rtk_vlan_init(void); + +/* Function Name: + * rtk_vlan_set + * Description: + * Set a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * pVlanCfg - VLAN Configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_FID - Invalid FID. + * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); + +/* Function Name: + * rtk_vlan_get + * Description: + * Get a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * Output: + * pVlanCfg - VLAN Configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); + +/* Function Name: + * rtk_vlan_egrFilterEnable_set + * Description: + * Set VLAN egress filter. + * Input: + * egrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter); + +/* Function Name: + * rtk_vlan_egrFilterEnable_get + * Description: + * Get VLAN egress filter. + * Input: + * pEgrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter); + +/* Function Name: + * rtk_vlan_mbrCfg_set + * Description: + * Set a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * pMbrcfg - VLAN member Configuration. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Set a VLAN Member Configuration entry by index. + */ +extern rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); + +/* Function Name: + * rtk_vlan_mbrCfg_get + * Description: + * Get a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * Output: + * pMbrcfg - VLAN member Configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Get a VLAN Member Configuration entry by index. + */ +extern rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); + +/* Function Name: + * rtk_vlan_portPvid_set + * Description: + * Set port to specified VLAN ID(PVID). + * Input: + * port - Port id. + * pvid - Specified VLAN ID. + * priority - 802.1p priority for the PVID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API is used for Port-based VLAN. The untagged frame received from the + * port will be classified to the specified VLAN and assigned to the specified priority. + */ +extern rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority); + +/* Function Name: + * rtk_vlan_portPvid_get + * Description: + * Get VLAN ID(PVID) on specified port. + * Input: + * port - Port id. + * Output: + * pPvid - Specified VLAN ID. + * pPriority - 802.1p priority for the PVID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the PVID and 802.1p priority for the PVID of Port-based VLAN. + */ +extern rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority); + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_set + * Description: + * Set VLAN ingress for each port. + * Input: + * port - Port id. + * igr_filter - VLAN ingress function enable status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member + * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. + */ +extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter); + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_get + * Description: + * Get VLAN Ingress Filter + * Input: + * port - Port id. + * Output: + * pIgr_filter - VLAN ingress function enable status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter status. + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + */ +extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter); + +/* Function Name: + * rtk_vlan_portAcceptFrameType_set + * Description: + * Set VLAN accept_frame_type + * Input: + * port - Port id. + * accept_frame_type - accept frame type + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. + * Note: + * The API is used for checking 802.1Q tagged frames. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type); + +/* Function Name: + * rtk_vlan_portAcceptFrameType_get + * Description: + * Get VLAN accept_frame_type + * Input: + * port - Port id. + * Output: + * pAccept_frame_type - accept frame type + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type); + +/* Function Name: + * rtk_vlan_tagMode_set + * Description: + * Set CVLAN egress tag mode + * Input: + * port - Port id. + * tag_mode - The egress tag mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +extern rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode); + +/* Function Name: + * rtk_vlan_tagMode_get + * Description: + * Get CVLAN egress tag mode + * Input: + * port - Port id. + * Output: + * pTag_mode - The egress tag mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +extern rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode); + +/* Function Name: + * rtk_vlan_transparent_set + * Description: + * Set VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_transparent_get + * Description: + * Get VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_keep_set + * Description: + * Set VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_keep_get + * Description: + * Get VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +extern rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); + +/* Function Name: + * rtk_vlan_stg_set + * Description: + * Set spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * stg - spanning tree group instance. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can set spanning tree group instance of the vlan to the specified device. + */ +extern rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg); + +/* Function Name: + * rtk_vlan_stg_get + * Description: + * Get spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * Output: + * pStg - spanning tree group instance. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can get spanning tree group instance of the vlan to the specified device. + */ +extern rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_add + * Description: + * Add the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * pInfo - Protocol and port based VLAN configuration information. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_TBL_FULL - Table is full. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_get + * Description: + * Get the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * pInfo - Protocol and port based VLAN configuration information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_del + * Description: + * Delete the protocol-and-port-based vlan from the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type); + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_delAll + * Description: + * Delete all protocol-and-port-based vlans from the specified port of device. + * Input: + * port - Port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * Delete all flow table protocol-and-port-based vlan entries. + */ +extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port); + +/* Function Name: + * rtk_vlan_portFid_set + * Description: + * Set port-based filtering database + * Input: + * port - Port id. + * enable - ebable port-based FID + * fid - Specified filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based filtering database. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +extern rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid); + +/* Function Name: + * rtk_vlan_portFid_get + * Description: + * Get port-based filtering database + * Input: + * port - Port id. + * Output: + * pEnable - ebable port-based FID + * pFid - Specified filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based filtering database status. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +extern rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid); + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_set + * Description: + * Set Untag DSCP priority assign + * Input: + * enable - state of Untag DSCP priority assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_set(rtk_enable_t enable); + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_get + * Description: + * Get Untag DSCP priority assign + * Input: + * None + * Output: + * pEnable - state of Untag DSCP priority assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable); + + +/*Spanning Tree*/ +/* Function Name: + * rtk_stp_mstpState_set + * Description: + * Configure spanning tree state per each port. + * Input: + * port - Port id + * msti - Multiple spanning tree instance. + * stp_state - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * RT_ERR_MSTP_STATE - Invalid STP state. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +extern rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state); + +/* Function Name: + * rtk_stp_mstpState_get + * Description: + * Get spanning tree state per each port. + * Input: + * port - Port id. + * msti - Multiple spanning tree instance. + * Output: + * pStp_state - Spanning tree state for msti + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +extern rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state); + +/* Function Name: + * rtk_vlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); + +/* Function Name: + * rtk_vlan_reservedVidAction_set + * Description: + * Set Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * action_vid0 - Action for VID 0. + * action_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095); + +/* Function Name: + * rtk_vlan_reservedVidAction_get + * Description: + * Get Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * pAction_vid0 - Action for VID 0. + * pAction_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095); + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_set + * Description: + * Set Real keep 1p remarking feature + * Input: + * enabled - State of 1p remarking at real keep packet + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled); + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_get + * Description: + * Get Real keep 1p remarking feature + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +extern rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled); + +/* Function Name: + * rtk_vlan_reset + * Description: + * Reset VLAN + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reset(void); + +#endif /* __RTK_API_VLAN_H__ */ diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/interrupt.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/interrupt.c new file mode 100755 index 00000000..165ee417 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/interrupt.c @@ -0,0 +1,434 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Interrupt module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_int_polarity_set + * Description: + * Set interrupt polarity configuration. + * Input: + * type - Interruptpolarity type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set interrupt polarity configuration. + */ +rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(type >= INT_POLAR_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicInterruptPolarity(type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_polarity_get + * Description: + * Get interrupt polarity configuration. + * Input: + * None + * Output: + * pType - Interruptpolarity type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get interrupt polarity configuration. + */ +rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicInterruptPolarity(pType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_control_set + * Description: + * Set interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set interrupt status configuration. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS + * - INT_TYPE_METER_EXCEED + * - INT_TYPE_LEARN_LIMIT + * - INT_TYPE_LINK_SPEED + * - INT_TYPE_CONGEST + * - INT_TYPE_GREEN_FEATURE + * - INT_TYPE_LOOP_DETECT + * - INT_TYPE_8051, + * - INT_TYPE_CABLE_DIAG, + * - INT_TYPE_ACL, + * - INT_TYPE_SLIENT + */ +rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 mask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= INT_TYPE_END) + return RT_ERR_INPUT; + + if (type == INT_TYPE_RESERVED) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + mask = mask | (1<value[0] & (0x0001 << INT_TYPE_RESERVED)) + return RT_ERR_INPUT; + + if(pStatusMask->value[0] >= (0x0001 << INT_TYPE_END)) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicInterruptStatus((rtk_uint32)pStatusMask->value[0]))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_status_get + * Description: + * Get interrupt trigger status. + * Input: + * None + * Output: + * pStatusMask - Interrupt status bit mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get interrupt trigger status when interrupt happened. + * The interrupt trigger status is shown in the following: + * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) + * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) + * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) + * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) + * - INT_TYPE_CONGEST (value[0] (Bit4)) + * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) + * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) + * - INT_TYPE_8051 (value[0] (Bit7)) + * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) + * - INT_TYPE_ACL (value[0] (Bit9)) + * - INT_TYPE_SLIENT (value[0] (Bit11)) + * + */ +rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask) +{ + rtk_api_ret_t retVal; + rtk_uint32 ims_mask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pStatusMask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicInterruptStatus(&ims_mask)) != RT_ERR_OK) + return retVal; + + pStatusMask->value[0] = (ims_mask & 0x00000FFF); + return RT_ERR_OK; +} + +#define ADV_NOT_SUPPORT (0xFFFF) +static rtk_api_ret_t _rtk_int_Advidx_get(rtk_int_advType_t adv_type, rtk_uint32 *pAsic_idx) +{ + rtk_uint32 asic_idx[ADV_END] = + { + INTRST_L2_LEARN, + INTRST_SPEED_CHANGE, + INTRST_SPECIAL_CONGESTION, + INTRST_PORT_LINKDOWN, + INTRST_PORT_LINKUP, + ADV_NOT_SUPPORT, + INTRST_RLDP_LOOPED, + INTRST_RLDP_RELEASED, + }; + + if(adv_type >= ADV_END) + return RT_ERR_INPUT; + + if(asic_idx[adv_type] == ADV_NOT_SUPPORT) + return RT_ERR_CHIP_NOT_SUPPORTED; + + *pAsic_idx = asic_idx[adv_type]; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_int_advanceInfo_get + * Description: + * Get interrupt advanced information. + * Input: + * adv_type - Advanced interrupt type. + * Output: + * info - Information per type. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get advanced information when interrupt happened. + * The status will be cleared after execute this API. + */ +rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t *pInfo) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + rtk_uint32 intAdvType; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(adv_type >= ADV_END) + return RT_ERR_INPUT; + + if(NULL == pInfo) + return RT_ERR_NULL_POINTER; + + if(adv_type != ADV_METER_EXCEED_MASK) + { + if((retVal = _rtk_int_Advidx_get(adv_type, &intAdvType)) != RT_ERR_OK) + return retVal; + } + + switch(adv_type) + { + case ADV_L2_LEARN_PORT_MASK: + /* Get physical portmask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) + return retVal; + + /* Translate to logical portmask */ + if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) + return retVal; + + /* Get system learn */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_SYS_LEARN, &data)) != RT_ERR_OK) + return retVal; + + /* Clear system learn */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_SYS_LEARN, 0x0001)) != RT_ERR_OK) + return retVal; + + pInfo->systemLearnOver = data; + break; + case ADV_SPEED_CHANGE_PORT_MASK: + case ADV_SPECIAL_CONGESTION_PORT_MASK: + case ADV_PORT_LINKDOWN_PORT_MASK: + case ADV_PORT_LINKUP_PORT_MASK: + case ADV_RLDP_LOOPED: + case ADV_RLDP_RELEASED: + /* Get physical portmask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) + return retVal; + + /* Translate to logical portmask */ + if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) + return retVal; + + break; + case ADV_METER_EXCEED_MASK: + /* Get Meter Mask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER0_15, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER0_15, 0xFFFF)) != RT_ERR_OK) + return retVal; + + pInfo->meterMask = data & 0xFFFF; + + /* Get Meter Mask */ + if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER16_31, &data)) != RT_ERR_OK) + return retVal; + + /* Clear Advanced Info */ + if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER16_31, 0xFFFF)) != RT_ERR_OK) + return retVal; + + pInfo->meterMask = pInfo->meterMask | ((data << 16) & 0xFFFF0000); + + break; + default: + return RT_ERR_INPUT; + } + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/l2.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/l2.c new file mode 100755 index 00000000..feff0b24 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/l2.c @@ -0,0 +1,2911 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in L2 module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* Function Name: + * rtk_l2_init + * Description: + * Initialize l2 module of the specified device. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Initialize l2 module before calling any l2 APIs. + */ +rtk_api_ret_t rtk_l2_init(void) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) + return retVal; + + /*Enable CAM Usage*/ + if ((retVal = rtl8367c_setAsicLutCamTbUsage(ENABLED)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutAgeTimerSpeed(6,2)) != RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_LOG_PORT(port) + { + if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), rtk_switch_maxLutAddrNumber_get())) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_l2_addr_add + * Description: + * Add LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * pL2_data - Unicast entry parameter + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address already existed in LUT, it will udpate the status of the entry. + * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries + * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pMac == NULL) || (pMac->octet[0] & 0x1)) + return RT_ERR_MAC; + + if(pL2_data == NULL) + return RT_ERR_MAC; + + RTK_CHK_PORT_VALID(pL2_data->port); + + if (pL2_data->ivl >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->cvid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if (pL2_data->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if (pL2_data->is_static>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->sa_block>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->da_block>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->auth>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->efid> RTL8367C_EFIDMAX) + return RT_ERR_INPUT; + + if (pL2_data->priority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + if (pL2_data->sa_pri_en >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pL2_data->fwd_pri_en >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.fid = pL2_data->fid; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.efid = pL2_data->efid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal ) + { + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); + l2Table.nosalearn = pL2_data->is_static; + l2Table.sa_block = pL2_data->sa_block; + l2Table.da_block = pL2_data->da_block; + l2Table.l3lookup = 0; + l2Table.auth = pL2_data->auth; + l2Table.age = 6; + l2Table.lut_pri = pL2_data->priority; + l2Table.sa_en = pL2_data->sa_pri_en; + l2Table.fwd_en = pL2_data->fwd_pri_en; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pL2_data->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); + l2Table.nosalearn = pL2_data->is_static; + l2Table.sa_block = pL2_data->sa_block; + l2Table.da_block = pL2_data->da_block; + l2Table.l3lookup = 0; + l2Table.auth = pL2_data->auth; + l2Table.age = 6; + l2Table.lut_pri = pL2_data->priority; + l2Table.sa_en = pL2_data->sa_pri_en; + l2Table.fwd_en = pL2_data->fwd_pri_en; + + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pL2_data->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_l2_addr_get + * Description: + * Get LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the unicast mac address existed in LUT, it will return the port and fid where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pMac == NULL) || (pMac->octet[0] & 0x1)) + return RT_ERR_MAC; + + if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + method = LUTREADMETHOD_MAC; + + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + memcpy(pL2_data->mac.octet, pMac->octet,ETHER_ADDR_LEN); + pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); + pL2_data->fid = l2Table.fid; + pL2_data->efid = l2Table.efid; + pL2_data->ivl = l2Table.ivl_svl; + pL2_data->cvid = l2Table.cvid_fid; + pL2_data->is_static = l2Table.nosalearn; + pL2_data->auth = l2Table.auth; + pL2_data->sa_block = l2Table.sa_block; + pL2_data->da_block = l2Table.da_block; + pL2_data->priority = l2Table.lut_pri; + pL2_data->sa_pri_en = l2Table.sa_en; + pL2_data->fwd_pri_en= l2Table.fwd_en; + pL2_data->address = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_addr_next_get + * Description: + * Get Next LUT unicast entry. + * Input: + * read_method - The reading method. + * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA + * pAddress - The Address ID + * Output: + * pL2_data - Unicast entry parameter + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next unicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all entries is LUT. + */ +rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pL2_data == NULL) || (pAddress == NULL)) + return RT_ERR_MAC; + + if(read_method == READMETHOD_NEXT_L2UC) + method = LUTREADMETHOD_NEXT_L2UC; + else if(read_method == READMETHOD_NEXT_L2UCSPA) + method = LUTREADMETHOD_NEXT_L2UCSPA; + else + return RT_ERR_INPUT; + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + if(read_method == READMETHOD_NEXT_L2UCSPA) + l2Table.spa = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + memcpy(pL2_data->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); + pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); + pL2_data->fid = l2Table.fid; + pL2_data->efid = l2Table.efid; + pL2_data->ivl = l2Table.ivl_svl; + pL2_data->cvid = l2Table.cvid_fid; + pL2_data->is_static = l2Table.nosalearn; + pL2_data->auth = l2Table.auth; + pL2_data->sa_block = l2Table.sa_block; + pL2_data->da_block = l2Table.da_block; + pL2_data->priority = l2Table.lut_pri; + pL2_data->sa_pri_en = l2Table.sa_en; + pL2_data->fwd_pri_en= l2Table.fwd_en; + pL2_data->address = l2Table.address; + + *pAddress = l2Table.address; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_l2_addr_del + * Description: + * Delete LUT unicast entry. + * Input: + * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. + * fid - Filtering database + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* must be unicast address */ + if ((pMac == NULL) || (pMac->octet[0] & 0x1)) + return RT_ERR_MAC; + + if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pL2_data->ivl; + l2Table.cvid_fid = pL2_data->cvid; + l2Table.fid = pL2_data->fid; + l2Table.efid = pL2_data->efid; + l2Table.spa = 0; + l2Table.nosalearn = 0; + l2Table.sa_block = 0; + l2Table.da_block = 0; + l2Table.auth = 0; + l2Table.age = 0; + l2Table.lut_pri = 0; + l2Table.sa_en = 0; + l2Table.fwd_en = 0; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pL2_data->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_mcastAddr_add + * Description: + * Add LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address already existed in the LUT, it will udpate the + * port mask of the entry. Otherwise, it will find an empty or asic auto learned + * entry to write. If all the entries with the same hash value can't be replaced, + * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. + */ +rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMcastAddr) + return RT_ERR_NULL_POINTER; + + /* must be L2 multicast address */ + if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) + return RT_ERR_MAC; + + RTK_CHK_PORTMASK_VALID(&pMcastAddr->portmask); + + if(pMcastAddr->ivl == 1) + { + if (pMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + } + else if(pMcastAddr->ivl == 0) + { + if (pMcastAddr->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + } + else + return RT_ERR_INPUT; + + if(pMcastAddr->fwd_pri_en >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(pMcastAddr->priority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + /* Get physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(&pMcastAddr->portmask, &pmask)) != RT_ERR_OK) + return retVal; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 0; + l2Table.lut_pri = pMcastAddr->priority; + l2Table.fwd_en = pMcastAddr->fwd_pri_en; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 0; + l2Table.lut_pri = pMcastAddr->priority; + l2Table.fwd_en = pMcastAddr->fwd_pri_en; + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + } + else + return retVal; + +} + +/* Function Name: + * rtk_l2_mcastAddr_get + * Description: + * Get LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the multicast mac address existed in the LUT, it will return the port where + * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. + */ +rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMcastAddr) + return RT_ERR_NULL_POINTER; + + /* must be L2 multicast address */ + if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) + return RT_ERR_MAC; + + if(pMcastAddr->ivl == 1) + { + if (pMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + } + else if(pMcastAddr->ivl == 0) + { + if (pMcastAddr->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + } + else + return RT_ERR_INPUT; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + method = LUTREADMETHOD_MAC; + + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->priority = l2Table.lut_pri; + pMcastAddr->fwd_pri_en = l2Table.fwd_en; + pMcastAddr->igmp_asic = l2Table.igmp_asic; + pMcastAddr->igmp_index = l2Table.igmpidx; + pMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_mcastAddr_next_get + * Description: + * Get Next L2 Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pMcastAddr - L2 multicast entry structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next L2 multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all multicast entries is LUT. + */ +rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pAddress == NULL) || (pMcastAddr == NULL)) + return RT_ERR_INPUT; + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L2MC, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + memcpy(pMcastAddr->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); + pMcastAddr->ivl = l2Table.ivl_svl; + + if(pMcastAddr->ivl) + pMcastAddr->vid = l2Table.cvid_fid; + else + pMcastAddr->fid = l2Table.cvid_fid; + + pMcastAddr->priority = l2Table.lut_pri; + pMcastAddr->fwd_pri_en = l2Table.fwd_en; + pMcastAddr->igmp_asic = l2Table.igmp_asic; + pMcastAddr->igmp_index = l2Table.igmpidx; + pMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + *pAddress = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_mcastAddr_del + * Description: + * Delete LUT multicast entry. + * Input: + * pMcastAddr - L2 multicast entry structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MAC - Invalid MAC address. + * RT_ERR_L2_FID - Invalid FID . + * RT_ERR_L2_VID - Invalid VID . + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. + */ +rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMcastAddr) + return RT_ERR_NULL_POINTER; + + /* must be L2 multicast address */ + if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) + return RT_ERR_MAC; + + if(pMcastAddr->ivl == 1) + { + if (pMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + } + else if(pMcastAddr->ivl == 0) + { + if (pMcastAddr->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + } + else + return RT_ERR_INPUT; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + + /* fill key (MAC,FID) to get L2 entry */ + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); + l2Table.ivl_svl = pMcastAddr->ivl; + + if(pMcastAddr->ivl) + l2Table.cvid_fid = pMcastAddr->vid; + else + l2Table.cvid_fid = pMcastAddr->fid; + + l2Table.mbr = 0; + l2Table.nosalearn = 0; + l2Table.sa_block = 0; + l2Table.l3lookup = 0; + l2Table.lut_pri = 0; + l2Table.fwd_en = 0; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ipMcastAddr_add + * Description: + * Add Lut IP multicast entry + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user + * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to + * forward IP multicast frame directly without flooding. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpMcastAddr) + return RT_ERR_NULL_POINTER; + + /* check port mask */ + RTK_CHK_PORTMASK_VALID(&pIpMcastAddr->portmask); + + if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + if(pIpMcastAddr->fwd_pri_en >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pIpMcastAddr->priority > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(&pIpMcastAddr->portmask, &pmask)) != RT_ERR_OK) + return retVal; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + l2Table.lut_pri = pIpMcastAddr->priority; + l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + l2Table.lut_pri = pIpMcastAddr->priority; + l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + + } + else + return retVal; + +} + +/* Function Name: + * rtk_l2_ipMcastAddr_get + * Description: + * Get LUT IP multicast entry. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Lut table of IP multicast entry. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpMcastAddr) + return RT_ERR_NULL_POINTER; + + if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + method = LUTREADMETHOD_MAC; + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->priority = l2Table.lut_pri; + pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; + pIpMcastAddr->igmp_asic = l2Table.igmp_asic; + pIpMcastAddr->igmp_index = l2Table.igmpidx; + pIpMcastAddr->address = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastAddr_next_get + * Description: + * Get Next IP Multicast entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpMcastAddr - IP Multicast entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pAddress == NULL) || (pIpMcastAddr == NULL) ) + return RT_ERR_INPUT; + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + do + { + if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + }while(l2Table.l3vidlookup == 1); + + pIpMcastAddr->sip = l2Table.sip; + pIpMcastAddr->dip = l2Table.dip; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->priority = l2Table.lut_pri; + pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; + pIpMcastAddr->igmp_asic = l2Table.igmp_asic; + pIpMcastAddr->igmp_index = l2Table.igmpidx; + pIpMcastAddr->address = l2Table.address; + *pAddress = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastAddr_del + * Description: + * Delete a ip multicast address entry from the specified device. + * Input: + * pIpMcastAddr - IP Multicast entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can delete a IP multicast address entry from the specified device. + */ +rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if (pIpMcastAddr == NULL) + return RT_ERR_INPUT; + + if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpMcastAddr->sip; + l2Table.dip = pIpMcastAddr->dip; + l2Table.mbr = 0; + l2Table.nosalearn = 0; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 0; + l2Table.lut_pri = 0; + l2Table.fwd_en = 0; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_add + * Description: + * Add Lut IP multicast+VID entry + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpVidMcastAddr) + return RT_ERR_NULL_POINTER; + + /* check port mask */ + RTK_CHK_PORTMASK_VALID(&pIpVidMcastAddr->portmask); + + if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(&pIpVidMcastAddr->portmask, &pmask)) != RT_ERR_OK) + return retVal; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + { + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.mbr = pmask; + l2Table.nosalearn = 1; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) + return RT_ERR_L2_INDEXTBL_FULL; + else + return retVal; + + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_get + * Description: + * Get LUT IP multicast+VID entry. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpVidMcastAddr) + return RT_ERR_NULL_POINTER; + + if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + method = LUTREADMETHOD_MAC; + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_next_get + * Description: + * Get Next IP Multicast+VID entry. + * Input: + * pAddress - The Address ID + * Output: + * pIpVidMcastAddr - IP & VID multicast Entry + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the next IP multicast entry after the current entry pointed by pAddress. + * The address of next entry is returned by pAddress. User can use (address + 1) + * as pAddress to call this API again for dumping all IP multicast entries is LUT. + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error Checking */ + if ((pAddress == NULL) || (pIpVidMcastAddr == NULL)) + return RT_ERR_INPUT; + + if(*pAddress > RTK_MAX_LUT_ADDR_ID ) + return RT_ERR_L2_L2UNI_PARAM; + + memset(&l2Table, 0, sizeof(rtl8367c_luttb)); + l2Table.address = *pAddress; + + do + { + if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) + return retVal; + + if(l2Table.address < *pAddress) + return RT_ERR_L2_ENTRY_NOTFOUND; + + }while(l2Table.l3vidlookup == 0); + + pIpVidMcastAddr->sip = l2Table.sip; + pIpVidMcastAddr->dip = l2Table.dip; + pIpVidMcastAddr->vid = l2Table.l3_vid; + pIpVidMcastAddr->address = l2Table.address; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) + return retVal; + + *pAddress = l2Table.address; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipVidMcastAddr_del + * Description: + * Delete a ip multicast+VID address entry from the specified device. + * Input: + * pIpVidMcastAddr - IP & VID multicast Entry + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pIpVidMcastAddr) + return RT_ERR_NULL_POINTER; + + if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + method = LUTREADMETHOD_MAC; + retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); + if (RT_ERR_OK == retVal) + { + l2Table.sip = pIpVidMcastAddr->sip; + l2Table.dip = pIpVidMcastAddr->dip; + l2Table.mbr= 0; + l2Table.nosalearn = 0; + l2Table.l3lookup = 1; + l2Table.l3vidlookup = 1; + l2Table.l3_vid = pIpVidMcastAddr->vid; + if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) + return retVal; + + pIpVidMcastAddr->address = l2Table.address; + return RT_ERR_OK; + } + else + return retVal; +} + +/* Function Name: + * rtk_l2_ucastAddr_flush + * Description: + * Flush L2 mac address by type in the specified device (both dynamic and static). + * Input: + * pConfig - flush configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * flushByVid - 1: Flush by VID, 0: Don't flush by VID + * vid - VID (0 ~ 4095) + * flushByFid - 1: Flush by FID, 0: Don't flush by FID + * fid - FID (0 ~ 15) + * flushByPort - 1: Flush by Port, 0: Don't flush by Port + * port - Port ID + * flushByMac - Not Supported + * ucastAddr - Not Supported + * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries + * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. + */ +rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pConfig == NULL) + return RT_ERR_NULL_POINTER; + + if(pConfig->flushByVid >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushByFid >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushByPort >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushByMac >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushStaticAddr >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->flushAddrOnAllPorts >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pConfig->vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if(pConfig->fid > RTL8367C_FIDMAX) + return RT_ERR_INPUT; + + /* check port valid */ + RTK_CHK_PORT_VALID(pConfig->port); + + if(pConfig->flushByVid == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_VID)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushVid(pConfig->vid)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) + return retVal; + + if(pConfig->flushAddrOnAllPorts == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) + return retVal; + } + else if(pConfig->flushByPort == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + } + else if(pConfig->flushByFid == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_FID)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushFid(pConfig->fid)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) + return retVal; + + if(pConfig->flushAddrOnAllPorts == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) + return retVal; + } + else if(pConfig->flushByPort == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + } + else if(pConfig->flushByPort == ENABLED) + { + if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_PORT)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) + return retVal; + } + else if(pConfig->flushByMac == ENABLED) + { + /* Should use API "rtk_l2_addr_del" to remove a specified entry*/ + return RT_ERR_CHIP_NOT_SUPPORTED; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_table_clear + * Description: + * Flush all static & dynamic entries in LUT. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_l2_table_clear(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicLutFlushAll()) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_table_clearStatus_get + * Description: + * Get table clear status + * Input: + * None + * Output: + * pStatus - Clear status, 1:Busy, 0:finish + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pStatus) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutFlushAllStatus((rtk_uint32 *)pStatus)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_set + * Description: + * Set HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * enable - link down flush status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicLutLinkDownForceAging(enable)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_flushLinkDownPortAddrEnable_get + * Description: + * Get HW flush linkdown port mac configuration of the specified device. + * Input: + * port - Port id. + * Output: + * pEnable - link down flush status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The status of flush linkdown port address is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLinkDownForceAging(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_agingEnable_set + * Description: + * Set L2 LUT aging status per port setting. + * Input: + * port - Port id. + * enable - Aging status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can be used to set L2 LUT aging status per port. + */ +rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(enable == 1) + enable = 0; + else + enable = 1; + + if ((retVal = rtl8367c_setAsicLutDisableAging(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_agingEnable_get + * Description: + * Get L2 LUT aging status per port setting. + * Input: + * port - Port id. + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can be used to get L2 LUT aging function per port. + */ +rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutDisableAging(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + if(*pEnable == 1) + *pEnable = 0; + else + *pEnable = 1; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCnt_set + * Description: + * Set per-Port auto learning limit number + * Input: + * port - Port id. + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set per-port ASIC auto learning limit number from 0(disable learning) + * to 2112. + */ +rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), mac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCnt_get + * Description: + * Get per-Port auto learning limit number + * Input: + * port - Port id. + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning limit number. + */ +rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pMac_cnt) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_set + * Description: + * Set System auto learning limit number + * Input: + * mac_cnt - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * The API can set system ASIC auto learning limit number from 0(disable learning) + * to 2112. + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + if ((retVal = rtl8367c_setAsicSystemLutLearnLimitNo(mac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCnt_get + * Description: + * Get System auto learning limit number + * Input: + * None + * Output: + * pMac_cnt - Auto learning entries limit number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get system ASIC auto learning limit number. + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMac_cnt) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSystemLutLearnLimitNo(pMac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCntAction_set + * Description: + * Configure auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) + data = 1; + else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) + data = 0; + else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) + data = 2; + else + return RT_ERR_NOT_ALLOWED; + + if ((retVal = rtl8367c_setAsicLutLearnOverAct(data)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitLearningCntAction_get + * Description: + * Get auto learn over limit number action. + * Input: + * port - Port id. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 action; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLearnOverAct(&action)) != RT_ERR_OK) + return retVal; + + if ( 1 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_DROP; + else if ( 0 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; + else if ( 2 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; + else + *pAction = action; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_set + * Description: + * Configure system auto learn over limit number action. + * Input: + * port - Port id. + * action - Auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * The API can set SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) + data = 1; + else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) + data = 0; + else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) + data = 2; + else + return RT_ERR_NOT_ALLOWED; + + if ((retVal = rtl8367c_setAsicSystemLutLearnOverAct(data)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntAction_get + * Description: + * Get system auto learn over limit number action. + * Input: + * None. + * Output: + * pAction - Learn over action + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get SA unknown packet action while auto learn limit number is over + * The action symbol as following: + * - LIMIT_LEARN_CNT_ACTION_DROP, + * - LIMIT_LEARN_CNT_ACTION_FORWARD, + * - LIMIT_LEARN_CNT_ACTION_TO_CPU, + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction) +{ + rtk_api_ret_t retVal; + rtk_uint32 action; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSystemLutLearnOverAct(&action)) != RT_ERR_OK) + return retVal; + + if ( 1 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_DROP; + else if ( 0 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; + else if ( 2 == action ) + *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; + else + *pAction = action; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_set + * Description: + * Configure system auto learn portmask + * Input: + * pPortmask - Port Mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + /* Check port mask */ + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicSystemLutLearnPortMask(pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_limitSystemLearningCntPortMask_get + * Description: + * get system auto learn portmask + * Input: + * None + * Output: + * pPortmask - Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer. + * Note: + * + */ +rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSystemLutLearnPortMask(&pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_learningCnt_get + * Description: + * Get per-Port current auto learning number + * Input: + * port - Port id. + * Output: + * pMac_cnt - ASIC auto learning entries number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get per-port ASIC auto learning number + */ +rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pMac_cnt) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutLearnNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_floodPortMask_set + * Description: + * Set flooding portmask + * Input: + * type - flooding type. + * pFlood_portmask - flooding porkmask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (floood_type >= FLOOD_END) + return RT_ERR_INPUT; + + /* check port valid */ + RTK_CHK_PORTMASK_VALID(pFlood_portmask); + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(pFlood_portmask, &pmask))!=RT_ERR_OK) + return retVal; + + switch (floood_type) + { + case FLOOD_UNKNOWNDA: + if ((retVal = rtl8367c_setAsicPortUnknownDaFloodingPortmask(pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_UNKNOWNMC: + if ((retVal = rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_BC: + if ((retVal = rtl8367c_setAsicPortBcastFloodingPortmask(pmask)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtk_l2_floodPortMask_get + * Description: + * Get flooding portmask + * Input: + * type - flooding type. + * Output: + * pFlood_portmask - flooding porkmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the flooding mask. + * The flooding type is as following: + * - FLOOD_UNKNOWNDA + * - FLOOD_UNKNOWNMC + * - FLOOD_BC + */ +rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (floood_type >= FLOOD_END) + return RT_ERR_INPUT; + + if(NULL == pFlood_portmask) + return RT_ERR_NULL_POINTER; + + switch (floood_type) + { + case FLOOD_UNKNOWNDA: + if ((retVal = rtl8367c_getAsicPortUnknownDaFloodingPortmask(&pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_UNKNOWNMC: + if ((retVal = rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(&pmask)) != RT_ERR_OK) + return retVal; + break; + case FLOOD_BC: + if ((retVal = rtl8367c_getAsicPortBcastFloodingPortmask(&pmask)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pFlood_portmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_localPktPermit_set + * Description: + * Set permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * permit - permittion status + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid permit value. + * Note: + * This API is setted to permit frame if its source port is equal to destination port. + */ +rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (permit >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortBlockSpa(rtk_switch_port_L2P_get(port), permit)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_localPktPermit_get + * Description: + * Get permittion of frames if source port and destination port are the same. + * Input: + * port - Port id. + * Output: + * pPermit - permittion status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API is to get permittion status for frames if its source port is equal to destination port. + */ +rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPermit) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortBlockSpa(rtk_switch_port_L2P_get(port), pPermit)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_aging_set + * Description: + * Set LUT agging out speed + * Input: + * aging_time - Agging out time. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can set LUT agging out period for each entry and the range is from 45s to 458s. + */ +rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time) +{ + rtk_uint32 i; + CONST_T rtk_uint32 agePara[10][3] = { + {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, + {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (aging_time>agePara[9][0]) + return RT_ERR_OUT_OF_RANGE; + + for (i = 0; i<10; i++) + { + if (aging_time<=agePara[i][0]) + { + return rtl8367c_setAsicLutAgeTimerSpeed(agePara[i][2], agePara[i][1]); + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_aging_get + * Description: + * Get LUT agging out time + * Input: + * None + * Output: + * pEnable - Aging status + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get LUT agging out period for each entry. + */ +rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time) +{ + rtk_api_ret_t retVal; + rtk_uint32 i,time, speed; + CONST_T rtk_uint32 agePara[10][3] = { + {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, + {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAging_time) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLutAgeTimerSpeed(&time, &speed)) != RT_ERR_OK) + return retVal; + + for (i = 0; i<10; i++) + { + if (time==agePara[i][2]&&speed==agePara[i][1]) + { + *pAging_time = agePara[i][0]; + return RT_ERR_OK; + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_set + * Description: + * Set Lut IP multicast lookup function + * Input: + * type - Lookup type for IPMC packet. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * LOOKUP_MAC - Lookup by MAC address + * LOOKUP_IP - Lookup by IP address + * LOOKUP_IP_VID - Lookup by IP address & VLAN ID + */ +rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(type == LOOKUP_MAC) + { + if((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) + return retVal; + } + else if(type == LOOKUP_IP) + { + if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(DISABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + } + else if(type == LOOKUP_IP_VID) + { + if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(ENABLED))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastAddrLookup_get + * Description: + * Get Lut IP multicast lookup function + * Input: + * None. + * Output: + * pType - Lookup type for IPMC packet. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType) +{ + rtk_api_ret_t retVal; + rtk_uint32 enabled, vid_lookup; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicLutIpMulticastLookup(&enabled)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicLutIpMulticastVidLookup(&vid_lookup))!=RT_ERR_OK) + return retVal; + + if(enabled == ENABLED) + { + if(vid_lookup == ENABLED) + *pType = LOOKUP_IP_VID; + else + *pType = LOOKUP_IP; + } + else + *pType = LOOKUP_MAC; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_set + * Description: + * Set IPMC packet forward to rounter port also or not + * Input: + * enabled - 1: Inlcude router port, 0, exclude router port + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if((retVal = rtl8367c_setAsicLutIpmcFwdRouterPort(enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastForwardRouterPort_get + * Description: + * Get IPMC packet forward to rounter port also or not + * Input: + * None. + * Output: + * pEnabled - 1: Inlcude router port, 0, exclude router port + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicLutIpmcFwdRouterPort(pEnabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_add + * Description: + * Add an IP Multicast entry to group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * pPortmask - portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Add an entry to IP Multicast Group table. + */ +rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) +{ + rtk_uint32 empty_idx = 0xFFFF; + rtk_int32 index; + ipaddr_t group_addr; + rtk_uint32 group_vid; + rtk_uint32 pmask; + rtk_uint32 valid; + rtk_uint32 physicalPortmask; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if((ip_addr & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + /* Get Physical port mask */ + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &physicalPortmask))!=RT_ERR_OK) + return retVal; + + for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) + { + if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) + return retVal; + + if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) + { + if(pmask != physicalPortmask) + { + pmask = physicalPortmask; + if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, ip_addr, vid, pmask, valid))!=RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; + } + + if( (valid == DISABLED) && (empty_idx == 0xFFFF) ) /* Unused */ + empty_idx = (rtk_uint32)index; + } + + if(empty_idx == 0xFFFF) + return RT_ERR_TBL_FULL; + + pmask = physicalPortmask; + if ((retVal = rtl8367c_setAsicLutIPMCGroup(empty_idx, ip_addr, vid, pmask, ENABLED))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_del + * Description: + * Delete an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid) +{ + rtk_int32 index; + ipaddr_t group_addr; + rtk_uint32 group_vid; + rtk_uint32 pmask; + rtk_uint32 valid; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if((ip_addr & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) + { + if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) + return retVal; + + if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) + { + group_addr = 0xE0000000; + group_vid = 0; + pmask = 0; + if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, group_addr, group_vid, pmask, DISABLED))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_ipMcastGroupEntry_get + * Description: + * get an entry from IP Multicast group table + * Input: + * ip_addr - IP address + * vid - VLAN ID + * Output: + * pPortmask - member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_TBL_FULL - Table Full + * Note: + * Delete an entry from IP Multicast group table. + */ +rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) +{ + rtk_int32 index; + ipaddr_t group_addr; + rtk_uint32 group_vid; + rtk_uint32 valid; + rtk_uint32 pmask; + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if((ip_addr & 0xF0000000) != 0xE0000000) + return RT_ERR_INPUT; + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_L2_VID; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) + { + if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) + return retVal; + + if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) + { + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_l2_entry_get + * Description: + * Get LUT unicast entry. + * Input: + * pL2_entry - Index field in the structure. + * Output: + * pL2_entry - other fields such as MAC, port, age... + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API is used to get address by index from 0~2111. + */ +rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry) +{ + rtk_api_ret_t retVal; + rtk_uint32 method; + rtl8367c_luttb l2Table; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (pL2_entry->index >= rtk_switch_maxLutAddrNumber_get()) + return RT_ERR_INPUT; + + memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); + l2Table.address= pL2_entry->index; + method = LUTREADMETHOD_ADDRESS; + if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) + return retVal; + + if ((pL2_entry->index>0x800)&&(l2Table.lookup_hit==0)) + return RT_ERR_L2_EMPTY_ENTRY; + + if(l2Table.l3lookup) + { + if(l2Table.l3vidlookup) + { + memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->sip = l2Table.sip; + pL2_entry->dip = l2Table.dip; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->fid = 0; + pL2_entry->age = 0; + pL2_entry->auth = 0; + pL2_entry->sa_block = 0; + pL2_entry->is_ipvidmul = 1; + pL2_entry->l3_vid = l2Table.l3_vid; + } + else + { + memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->sip = l2Table.sip; + pL2_entry->dip = l2Table.dip; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->fid = 0; + pL2_entry->age = 0; + pL2_entry->auth = 0; + pL2_entry->sa_block = 0; + pL2_entry->is_ipvidmul = 0; + pL2_entry->l3_vid = 0; + } + } + else if(l2Table.mac.octet[0]&0x01) + { + memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); + memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); + pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; + pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; + pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; + pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; + pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; + pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->ivl = l2Table.ivl_svl; + if(l2Table.ivl_svl == 1) /* IVL */ + { + pL2_entry->cvid = l2Table.cvid_fid; + pL2_entry->fid = 0; + } + else /* SVL*/ + { + pL2_entry->cvid = 0; + pL2_entry->fid = l2Table.cvid_fid; + } + pL2_entry->auth = l2Table.auth; + pL2_entry->sa_block = l2Table.sa_block; + pL2_entry->age = 0; + pL2_entry->is_ipvidmul = 0; + pL2_entry->l3_vid = 0; + } + else if((l2Table.age != 0)||(l2Table.nosalearn == 1)) + { + memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); + memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); + pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; + pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; + pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; + pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; + pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; + pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; + pL2_entry->is_ipmul = l2Table.l3lookup; + pL2_entry->is_static = l2Table.nosalearn; + + /* Get Logical port mask */ + if ((retVal = rtk_switch_portmask_P2L_get(1<<(l2Table.spa), &(pL2_entry->portmask)))!=RT_ERR_OK) + return retVal; + + pL2_entry->ivl = l2Table.ivl_svl; + pL2_entry->cvid = l2Table.cvid_fid; + pL2_entry->fid = l2Table.fid; + pL2_entry->auth = l2Table.auth; + pL2_entry->sa_block = l2Table.sa_block; + pL2_entry->age = l2Table.age; + pL2_entry->is_ipvidmul = 0; + pL2_entry->l3_vid = 0; + } + else + return RT_ERR_L2_EMPTY_ENTRY; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/leaky.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/leaky.c new file mode 100755 index 00000000..1b7d50a9 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/leaky.c @@ -0,0 +1,590 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Leaky module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + + +/* Function Name: + * rtk_leaky_vlan_set + * Description: + * Set VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set VLAN leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port <= RTK_PORT_ID_MAX; port++) + { + if ((retVal = rtl8367c_setAsicIpMulticastVlanLeaky(port,enable)) != RT_ERR_OK) + return retVal; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_setAsicIGMPVLANLeaky(enable)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.vlan_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_leaky_vlan_get + * Description: + * Get VLAN leaky. + * Input: + * type - Packet type for VLAN leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get VLAN leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port,tmp; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port <= RTK_PORT_ID_MAX; port++) + { + if ((retVal = rtl8367c_getAsicIpMulticastVlanLeaky(port, &tmp)) != RT_ERR_OK) + return retVal; + if (port>0&&(tmp!=*pEnable)) + return RT_ERR_FAILED; + *pEnable = tmp; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_getAsicIGMPVLANLeaky(&tmp)) != RT_ERR_OK) + return retVal; + + *pEnable = tmp; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.vlan_leaky; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_leaky_portIsolation_set + * Description: + * Set port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * enable - Leaky status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input + * Note: + * This API can set port isolation leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) + { + if ((retVal = rtl8367c_setAsicIpMulticastPortIsoLeaky(port,enable)) != RT_ERR_OK) + return retVal; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_setAsicIGMPIsoLeaky(enable)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.portiso_leaky = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_leaky_portIsolation_get + * Description: + * Get port isolation leaky. + * Input: + * type - Packet type for port isolation leaky. + * Output: + * pEnable - Leaky status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get port isolation leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. + * The leaky frame types are as following: + * - LEAKY_BRG_GROUP, + * - LEAKY_FD_PAUSE, + * - LEAKY_SP_MCAST, + * - LEAKY_1X_PAE, + * - LEAKY_UNDEF_BRG_04, + * - LEAKY_UNDEF_BRG_05, + * - LEAKY_UNDEF_BRG_06, + * - LEAKY_UNDEF_BRG_07, + * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - LEAKY_UNDEF_BRG_09, + * - LEAKY_UNDEF_BRG_0A, + * - LEAKY_UNDEF_BRG_0B, + * - LEAKY_UNDEF_BRG_0C, + * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - LEAKY_8021AB, + * - LEAKY_UNDEF_BRG_0F, + * - LEAKY_BRG_MNGEMENT, + * - LEAKY_UNDEFINED_11, + * - LEAKY_UNDEFINED_12, + * - LEAKY_UNDEFINED_13, + * - LEAKY_UNDEFINED_14, + * - LEAKY_UNDEFINED_15, + * - LEAKY_UNDEFINED_16, + * - LEAKY_UNDEFINED_17, + * - LEAKY_UNDEFINED_18, + * - LEAKY_UNDEFINED_19, + * - LEAKY_UNDEFINED_1A, + * - LEAKY_UNDEFINED_1B, + * - LEAKY_UNDEFINED_1C, + * - LEAKY_UNDEFINED_1D, + * - LEAKY_UNDEFINED_1E, + * - LEAKY_UNDEFINED_1F, + * - LEAKY_GMRP, + * - LEAKY_GVRP, + * - LEAKY_UNDEF_GARP_22, + * - LEAKY_UNDEF_GARP_23, + * - LEAKY_UNDEF_GARP_24, + * - LEAKY_UNDEF_GARP_25, + * - LEAKY_UNDEF_GARP_26, + * - LEAKY_UNDEF_GARP_27, + * - LEAKY_UNDEF_GARP_28, + * - LEAKY_UNDEF_GARP_29, + * - LEAKY_UNDEF_GARP_2A, + * - LEAKY_UNDEF_GARP_2B, + * - LEAKY_UNDEF_GARP_2C, + * - LEAKY_UNDEF_GARP_2D, + * - LEAKY_UNDEF_GARP_2E, + * - LEAKY_UNDEF_GARP_2F, + * - LEAKY_IGMP, + * - LEAKY_IPMULTICAST. + * - LEAKY_CDP, + * - LEAKY_CSSTP, + * - LEAKY_LLDP. + */ +rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port, tmp; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= LEAKY_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + + } + else if (LEAKY_IPMULTICAST == type) + { + for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) + { + if ((retVal = rtl8367c_getAsicIpMulticastPortIsoLeaky(port, &tmp)) != RT_ERR_OK) + return retVal; + if (port > 0 &&(tmp != *pEnable)) + return RT_ERR_FAILED; + *pEnable = tmp; + } + } + else if (LEAKY_IGMP == type) + { + if ((retVal = rtl8367c_getAsicIGMPIsoLeaky(&tmp)) != RT_ERR_OK) + return retVal; + + *pEnable = tmp; + } + else if (LEAKY_CDP == type) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + } + else if (LEAKY_CSSTP == type) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + } + else if (LEAKY_LLDP == type) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.portiso_leaky; + } + + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/led.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/led.c new file mode 100755 index 00000000..c00c331d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/led.c @@ -0,0 +1,792 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in LED module. + * + */ + +#include +#include +#include +#include + +#include +#include + + +/* Function Name: + * rtk_led_enable_set + * Description: + * Set Led enable congiuration + * Input: + * group - LED group id. + * pPortmask - LED enable port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_MASK - Error portmask + * Note: + * The API can be used to enable LED per port per group. + */ +rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + rtk_port_t port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + RTK_CHK_PORTMASK_VALID(pPortmask); + + RTK_PORTMASK_SCAN((*pPortmask), port) + { + if(rtk_switch_isCPUPort(port) == RT_ERR_OK) + return RT_ERR_PORT_MASK; + } + + if((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLedGroupEnable(group, pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_enable_get + * Description: + * Get Led enable congiuration + * Input: + * group - LED group id. + * Output: + * pPortmask - LED enable port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can be used to get LED enable status. + */ +rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicLedGroupEnable(group, &pmask)) != RT_ERR_OK) + return retVal; + + if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_led_operation_set + * Description: + * Set Led operation mode + * Input: + * mode - LED operation mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ( mode >= LED_OP_END) + return RT_ERR_INPUT; + + switch (mode) + { + case LED_OP_PARALLEL: + regData = LEDOP_PARALLEL; + break; + case LED_OP_SERIAL: + regData = LEDOP_SERIAL; + break; + default: + return RT_ERR_CHIP_NOT_SUPPORTED; + break; + } + + if ((retVal = rtl8367c_setAsicLedOperationMode(regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_operation_get + * Description: + * Get Led operation mode + * Input: + * None + * Output: + * pMode - Support LED operation mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get Led operation mode. + * The modes that can be set are as following: + * - LED_OP_SCAN, + * - LED_OP_PARALLEL, + * - LED_OP_SERIAL, + */ +rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedOperationMode(®Data)) != RT_ERR_OK) + return retVal; + + if (regData == LEDOP_SERIAL) + *pMode = LED_OP_SERIAL; + else if (regData ==LEDOP_PARALLEL) + *pMode = LED_OP_PARALLEL; + else + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_modeForce_set + * Description: + * Set Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * mode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can force to one force mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* No LED for CPU port */ + if(rtk_switch_isCPUPort(port) == RT_ERR_OK) + return RT_ERR_PORT_ID; + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + if (mode >= LED_FORCE_END) + return RT_ERR_NOT_ALLOWED; + + if ((retVal = rtl8367c_setAsicForceLed(rtk_switch_port_L2P_get(port), group, mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_modeForce_get + * Description: + * Get Led group to congiuration force mode + * Input: + * port - port ID + * group - Support LED group id. + * pMode - Support LED force mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Error Port ID + * Note: + * The API can get forced Led group mode. + * The force modes that can be set are as following: + * - LED_FORCE_NORMAL, + * - LED_FORCE_BLINK, + * - LED_FORCE_OFF, + * - LED_FORCE_ON. + */ +rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* No LED for CPU port */ + if(rtk_switch_isCPUPort(port) == RT_ERR_OK) + return RT_ERR_PORT_ID; + + if (group >= LED_GROUP_END) + return RT_ERR_INPUT; + + if (NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicForceLed(rtk_switch_port_L2P_get(port), group, pMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_blinkRate_set + * Description: + * Set LED blinking rate + * Input: + * blinkRate - blinking rate. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * ASIC support 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (blinkRate >= LED_BLINKRATE_END) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicLedBlinkRate(blinkRate)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_blinkRate_get + * Description: + * Get LED blinking rate at mode 0 to mode 3 + * Input: + * None + * Output: + * pBlinkRate - blinking rate. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. + */ +rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pBlinkRate) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedBlinkRate(pBlinkRate)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupConfig_set + * Description: + * Set per group Led to congiuration mode + * Input: + * group - LED group. + * config - LED configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. + * - Definition LED Statuses Description + * - 0000 LED_Off LED pin Tri-State. + * - 0001 Dup/Col Collision, Full duplex Indicator. + * - 0010 Link/Act Link, Activity Indicator. + * - 0011 Spd1000 1000Mb/s Speed Indicator. + * - 0100 Spd100 100Mb/s Speed Indicator. + * - 0101 Spd10 10Mb/s Speed Indicator. + * - 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. + * - 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. + * - 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. + * - 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. + * - 1010 LoopDetect LoopDetect Indicator. + * - 1011 EEE EEE Indicator. + * - 1100 Link/Rx Link, Activity Indicator. + * - 1101 Link/Tx Link, Activity Indicator. + * - 1110 Master Link on Master Indicator. + * - 1111 Act Activity Indicator. Low for link established. + */ +rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if (LED_CONFIG_END <= config) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicLedIndicateInfoConfig(group, config)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupConfig_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED indicated information configuration for each LED group. + */ +rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if(NULL == pConfig) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedIndicateInfoConfig(group, pConfig)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupAbility_set + * Description: + * Configure per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if(pAbility == NULL) + return RT_ERR_NULL_POINTER; + + if( (pAbility->link_10m >= RTK_ENABLE_END) || (pAbility->link_100m >= RTK_ENABLE_END)|| + (pAbility->link_500m >= RTK_ENABLE_END) || (pAbility->link_1000m >= RTK_ENABLE_END)|| + (pAbility->act_rx >= RTK_ENABLE_END) || (pAbility->act_tx >= RTK_ENABLE_END) ) + { + return RT_ERR_INPUT; + } + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) + return retVal; + + if(pAbility->link_10m == ENABLED) + regData |= 0x0001; + else + regData &= ~0x0001; + + if(pAbility->link_100m == ENABLED) + regData |= 0x0002; + else + regData &= ~0x0002; + + if(pAbility->link_500m == ENABLED) + regData |= 0x0004; + else + regData &= ~0x0004; + + if(pAbility->link_1000m == ENABLED) + regData |= 0x0008; + else + regData &= ~0x0008; + + if(pAbility->act_rx == ENABLED) + regData |= 0x0010; + else + regData &= ~0x0010; + + if(pAbility->act_tx == ENABLED) + regData |= 0x0020; + else + regData &= ~0x0020; + + regData |= (0x0001 << 6); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_groupAbility_get + * Description: + * Get per group Led ability + * Input: + * group - LED group. + * pAbility - LED ability + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * None. + */ + +rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (LED_GROUP_END <= group) + return RT_ERR_FAILED; + + if(pAbility == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) + return retVal; + + pAbility->link_10m = (regData & 0x0001) ? ENABLED : DISABLED; + pAbility->link_100m = (regData & 0x0002) ? ENABLED : DISABLED; + pAbility->link_500m = (regData & 0x0004) ? ENABLED : DISABLED; + pAbility->link_1000m = (regData & 0x0008) ? ENABLED : DISABLED; + pAbility->act_rx = (regData & 0x0010) ? ENABLED : DISABLED; + pAbility->act_tx = (regData & 0x0020) ? ENABLED : DISABLED; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_led_serialMode_set + * Description: + * Set Led serial mode active congiuration + * Input: + * active - LED group. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set LED serial mode active congiuration. + */ +rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ( active >= LED_ACTIVE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicLedSerialModeConfig(active,1))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_serialMode_get + * Description: + * Get Led group congiuration mode + * Input: + * group - LED group. + * Output: + * pConfig - LED configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get LED serial mode active configuration. + */ +rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pActive) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedSerialModeConfig(pActive,®Data))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_OutputEnable_set + * Description: + * This API set LED I/O state. + * Input: + * enabled - LED I/O state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set LED I/O state. + */ +rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicLedOutputEnable(state))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_OutputEnable_get + * Description: + * This API get LED I/O state. + * Input: + * None. + * Output: + * pEnabled - LED I/O state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current LED I/O state. + */ +rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pState == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedOutputEnable(pState))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_led_serialModePortmask_set + * Description: + * This API configure Serial LED output Group and portmask + * Input: + * output - output group + * pPortmask - output portmask + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(output >= SERIAL_LED_END) + return RT_ERR_INPUT; + + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicLedSerialOutput((rtk_uint32)output, pmask))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_led_serialModePortmask_get + * Description: + * This API get Serial LED output Group and portmask + * Input: + * None. + * Output: + * pOutput - output group + * pPortmask - output portmask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * None. + */ +rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pOutput == NULL) + return RT_ERR_NULL_POINTER; + + if(pPortmask == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicLedSerialOutput((rtk_uint32 *)pOutput, &pmask))!=RT_ERR_OK) + return retVal; + + if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/mirror.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/mirror.c new file mode 100755 index 00000000..1921d1a5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/mirror.c @@ -0,0 +1,548 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Mirror module. + * + */ + +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_mirror_portBased_set + * Description: + * Set port mirror function. + * Input: + * mirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API is to set mirror function of source port and mirror port. + * The mirror port can only be set to one port and the TX and RX mirror ports + * should be identical. + */ +rtk_api_ret_t rtk_mirror_portBased_set(rtk_port_t mirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask) +{ + rtk_api_ret_t retVal; + rtk_enable_t mirRx, mirTx; + rtk_uint32 i, pmask; + rtk_port_t source_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(mirroring_port); + + if(NULL == pMirrored_rx_portmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pMirrored_tx_portmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pMirrored_rx_portmask); + + RTK_CHK_PORTMASK_VALID(pMirrored_tx_portmask); + + /*Mirror Sorce Port Mask Check*/ + if (pMirrored_tx_portmask->bits[0]!=pMirrored_rx_portmask->bits[0]&&pMirrored_tx_portmask->bits[0]!=0&&pMirrored_rx_portmask->bits[0]!=0) + return RT_ERR_PORT_MASK; + + /*mirror port != source port*/ + if(RTK_PORTMASK_IS_PORT_SET((*pMirrored_tx_portmask), mirroring_port) || RTK_PORTMASK_IS_PORT_SET((*pMirrored_rx_portmask), mirroring_port)) + return RT_ERR_PORT_MASK; + + source_port = rtk_switch_maxLogicalPort_get(); + + RTK_SCAN_ALL_LOG_PORT(i) + { + if (pMirrored_tx_portmask->bits[0]&(1<bits[0]&(1<bits[0] != 0) + { + if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_rx_portmask, &pmask)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_tx_portmask, &pmask)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) + return retVal; + } + + + if (pMirrored_rx_portmask->bits[0]) + mirRx = ENABLED; + else + mirRx = DISABLED; + + if ((retVal = rtl8367c_setAsicPortMirrorRxFunction(mirRx)) != RT_ERR_OK) + return retVal; + + if (pMirrored_tx_portmask->bits[0]) + mirTx = ENABLED; + else + mirTx = DISABLED; + + if ((retVal = rtl8367c_setAsicPortMirrorTxFunction(mirTx)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_mirror_portBased_get + * Description: + * Get port mirror function. + * Input: + * None + * Output: + * pMirroring_port - Monitor port. + * pMirrored_rx_portmask - Rx mirror port mask. + * pMirrored_tx_portmask - Tx mirror port mask. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror function of source port and mirror port. + */ +rtk_api_ret_t rtk_mirror_portBased_get(rtk_port_t *pMirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask) +{ + rtk_api_ret_t retVal; + rtk_port_t source_port; + rtk_enable_t mirRx, mirTx; + rtk_uint32 sport, mport, pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMirrored_rx_portmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pMirrored_tx_portmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pMirroring_port) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirror(&sport, &mport)) != RT_ERR_OK) + return retVal; + source_port = rtk_switch_port_P2L_get(sport); + *pMirroring_port = rtk_switch_port_P2L_get(mport); + + if ((retVal = rtl8367c_getAsicPortMirrorRxFunction((rtk_uint32*)&mirRx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorTxFunction((rtk_uint32*)&mirTx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorMask(&pmask)) != RT_ERR_OK) + return retVal; + + if (DISABLED == mirRx) + pMirrored_rx_portmask->bits[0]=0; + else + { + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_rx_portmask)) != RT_ERR_OK) + return retVal; + pMirrored_rx_portmask->bits[0] |= 1<bits[0]=0; + else + { + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_tx_portmask)) != RT_ERR_OK) + return retVal; + pMirrored_tx_portmask->bits[0] |= 1<= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorIsolation(enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_portIso_get + * Description: + * Get mirror port isolation. + * Input: + * None + * Output: + * pEnable |Mirror isolation status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation status. + */ +rtk_api_ret_t rtk_mirror_portIso_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorIsolation(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_vlanLeaky_set + * Description: + * Set mirror VLAN leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorVlanTxLeaky(txenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortMirrorVlanRxLeaky(rxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_vlanLeaky_get + * Description: + * Get mirror VLAN leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror VLAN leaky status. + */ +rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if( (NULL == pTxenable) || (NULL == pRxenable) ) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorVlanTxLeaky(pTxenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorVlanRxLeaky(pRxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_isolationLeaky_set + * Description: + * Set mirror Isolation leaky. + * Input: + * txenable -TX leaky enable. + * rxenable - RX leaky enable. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set mirror VLAN leaky function forwarding packets to miror port. + */ +rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(txenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortMirrorIsolationRxLeaky(rxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_isolationLeaky_get + * Description: + * Get mirror isolation leaky. + * Input: + * None + * Output: + * pTxenable - TX leaky enable. + * pRxenable - RX leaky enable. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror isolation leaky status. + */ +rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if( (NULL == pTxenable) || (NULL == pRxenable) ) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorIsolationTxLeaky(pTxenable)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortMirrorIsolationRxLeaky(pRxenable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_keep_set + * Description: + * Set mirror packet format keep. + * Input: + * mode - -mirror keep mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The API is to set -mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mode >= MIRROR_KEEP_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorRealKeep(mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_keep_get + * Description: + * Get mirror packet format keep. + * Input: + * None + * Output: + * pMode -mirror keep mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API is to get mirror keep mode. + * The mirror keep mode is as following: + * - MIRROR_FOLLOW_VLAN + * - MIRROR_KEEP_ORIGINAL + * - MIRROR_KEEP_END + */ +rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortMirrorRealKeep(pMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_override_set + * Description: + * Set port mirror override function. + * Input: + * rxMirror - 1: output mirrored packet, 0: output normal forward packet + * txMirror - 1: output mirrored packet, 0: output normal forward packet + * aclMirror - 1: output mirrored packet, 0: output normal forward packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API is to set mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror) +{ + rtk_api_ret_t retVal; + + if( (rxMirror >= RTK_ENABLE_END) || (txMirror >= RTK_ENABLE_END) || (aclMirror >= RTK_ENABLE_END)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortMirrorOverride((rtk_uint32)rxMirror, (rtk_uint32)txMirror, (rtk_uint32)aclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_mirror_override_get + * Description: + * Get port mirror override function. + * Input: + * None + * Output: + * pRxMirror - 1: output mirrored packet, 0: output normal forward packet + * pTxMirror - 1: output mirrored packet, 0: output normal forward packet + * pAclMirror - 1: output mirrored packet, 0: output normal forward packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer + * Note: + * The API is to Get mirror override function. + * This function control the output format when a port output + * normal forward & mirrored packet at the same time. + */ +rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror) +{ + rtk_api_ret_t retVal; + + if( (pRxMirror == NULL) || (pTxMirror == NULL) || (pAclMirror == NULL)) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_getAsicPortMirrorOverride((rtk_uint32 *)pRxMirror, (rtk_uint32 *)pTxMirror, (rtk_uint32 *)pAclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/oam.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/oam.c new file mode 100755 index 00000000..dc1559ae --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/oam.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in OAM(802.3ah) module. + * + */ + +#include +#include +#include +#include + +#include +#include + + +/* Module Name : OAM */ + +/* Function Name: + * rtk_oam_init + * Description: + * Initialize oam module. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * Must initialize oam module before calling any oam APIs. + */ +rtk_api_ret_t rtk_oam_init(void) +{ + return RT_ERR_OK; +} /* end of rtk_oam_init */ + + +/* Function Name: + * rtk_oam_state_set + * Description: + * This API set OAM state. + * Input: + * enabled -OAMstate + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set OAM state. + */ +rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicOamEnable(enabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_oam_state_get + * Description: + * This API get OAM state. + * Input: + * None. + * Output: + * pEnabled - H/W IGMP state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error parameter + * Note: + * This API set current OAM state. + */ +rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicOamEnable(pEnabled))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Set OAM parser action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (action >= OAM_PARSER_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicOamParser(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Get OAM parser action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicOamParser(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_oam_multiplexerAction_set + * Description: + * Set OAM multiplexer action + * Input: + * port - port id + * action - parser action + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (action >= OAM_MULTIPLEXER_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicOamMultiplexer(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_oam_parserAction_set + * Description: + * Get OAM multiplexer action + * Input: + * port - port id + * Output: + * pAction - parser action + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * Note: + * None + */ +rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicOamMultiplexer(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/port.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/port.c new file mode 100755 index 00000000..9f99d1b3 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/port.c @@ -0,0 +1,2467 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Port module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define FIBER_INIT_SIZE 1507 +CONST_T rtk_uint8 Fiber[FIBER_INIT_SIZE] = { +0x02,0x04,0x41,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x05,0x2D,0xE4,0x90, +0x06,0x2A,0xF0,0xFD,0x7C,0x01,0x7F,0x3F, +0x7E,0x1D,0x12,0x05,0xAF,0x7D,0x40,0x12, +0x02,0x5F,0xE4,0xFF,0xFE,0xFD,0x80,0x08, +0x12,0x05,0x9E,0x50,0x0C,0x12,0x05,0x8B, +0xFC,0x90,0x06,0x24,0x12,0x03,0x76,0x80, +0xEF,0xE4,0xF5,0xA8,0xD2,0xAF,0x7D,0x1F, +0xFC,0x7F,0x49,0x7E,0x13,0x12,0x05,0xAF, +0x12,0x05,0xD6,0x7D,0xD7,0x12,0x02,0x1E, +0x7D,0x80,0x12,0x01,0xCA,0x7D,0x94,0x7C, +0xF9,0x12,0x02,0x3B,0x7D,0x81,0x12,0x01, +0xCA,0x7D,0xA2,0x7C,0x31,0x12,0x02,0x3B, +0x7D,0x82,0x12,0x01,0xDF,0x7D,0x60,0x7C, +0x69,0x12,0x02,0x43,0x7D,0x83,0x12,0x01, +0xDF,0x7D,0x28,0x7C,0x97,0x12,0x02,0x43, +0x7D,0x84,0x12,0x01,0xF4,0x7D,0x85,0x7C, +0x9D,0x12,0x02,0x57,0x7D,0x23,0x12,0x01, +0xF4,0x7D,0x10,0x7C,0xD8,0x12,0x02,0x57, +0x7D,0x24,0x7C,0x04,0x12,0x02,0x28,0x7D, +0x00,0x12,0x02,0x1E,0x7D,0x2F,0x12,0x02, +0x09,0x7D,0x20,0x7C,0x0F,0x7F,0x02,0x7E, +0x66,0x12,0x05,0xAF,0x7D,0x01,0x12,0x02, +0x09,0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x7F, +0x02,0x7E,0x66,0x12,0x02,0x4B,0x44,0x02, +0xFF,0x90,0x06,0x28,0xEE,0xF0,0xA3,0xEF, +0xF0,0x44,0x04,0xFF,0x90,0x06,0x28,0xEE, +0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F,0x02, +0x7E,0x66,0x12,0x05,0xAF,0x7D,0x04,0x7C, +0x00,0x12,0x02,0x28,0x7D,0xB9,0x7C,0x15, +0x7F,0xEB,0x7E,0x13,0x12,0x05,0xAF,0x7D, +0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, +0x05,0xAF,0x7D,0x40,0x7C,0x11,0x7F,0x00, +0x7E,0x62,0x12,0x05,0xAF,0x12,0x03,0x82, +0x7D,0x41,0x12,0x02,0x5F,0xE4,0xFF,0xFE, +0xFD,0x80,0x08,0x12,0x05,0x9E,0x50,0x0C, +0x12,0x05,0x8B,0xFC,0x90,0x06,0x24,0x12, +0x03,0x76,0x80,0xEF,0xC2,0x00,0xC2,0x01, +0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62, +0x12,0x02,0x4B,0x30,0xE2,0x05,0xE4,0xA3, +0xF0,0x80,0xF1,0x90,0x06,0x2A,0xE0,0x70, +0x12,0x12,0x01,0x89,0x90,0x06,0x2A,0x74, +0x01,0xF0,0xE4,0x90,0x06,0x2D,0xF0,0xA3, +0xF0,0x80,0xD9,0xC3,0x90,0x06,0x2E,0xE0, +0x94,0x64,0x90,0x06,0x2D,0xE0,0x94,0x00, +0x40,0xCA,0xE4,0xF0,0xA3,0xF0,0x12,0x01, +0x89,0x90,0x06,0x2A,0x74,0x01,0xF0,0x80, +0xBB,0x7D,0x04,0xFC,0x7F,0x02,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, +0xAF,0xE4,0xFD,0xFC,0x7F,0x02,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, +0xAF,0x22,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x05,0xAF,0x22,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF, +0x22,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C,0x04, +0x7F,0x02,0x7E,0x66,0x12,0x05,0xAF,0x22, +0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, +0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, +0x05,0xAF,0x22,0x12,0x05,0x67,0x90,0x06, +0x28,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7F, +0x02,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, +0x00,0x7F,0x36,0x7E,0x13,0x12,0x05,0xAF, +0x22,0xC5,0xF0,0xF8,0xA3,0xE0,0x28,0xF0, +0xC5,0xF0,0xF8,0xE5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xE0,0x38,0xF0,0x22,0x75, +0xF0,0x08,0x75,0x82,0x00,0xEF,0x2F,0xFF, +0xEE,0x33,0xFE,0xCD,0x33,0xCD,0xCC,0x33, +0xCC,0xC5,0x82,0x33,0xC5,0x82,0x9B,0xED, +0x9A,0xEC,0x99,0xE5,0x82,0x98,0x40,0x0C, +0xF5,0x82,0xEE,0x9B,0xFE,0xED,0x9A,0xFD, +0xEC,0x99,0xFC,0x0F,0xD5,0xF0,0xD6,0xE4, +0xCE,0xFB,0xE4,0xCD,0xFA,0xE4,0xCC,0xF9, +0xA8,0x82,0x22,0xB8,0x00,0xC1,0xB9,0x00, +0x59,0xBA,0x00,0x2D,0xEC,0x8B,0xF0,0x84, +0xCF,0xCE,0xCD,0xFC,0xE5,0xF0,0xCB,0xF9, +0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xEC,0x33,0xFC,0xEB,0x33, +0xFB,0x10,0xD7,0x03,0x99,0x40,0x04,0xEB, +0x99,0xFB,0x0F,0xD8,0xE5,0xE4,0xF9,0xFA, +0x22,0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33, +0xFE,0xED,0x33,0xFD,0xEC,0x33,0xFC,0xC9, +0x33,0xC9,0x10,0xD7,0x05,0x9B,0xE9,0x9A, +0x40,0x07,0xEC,0x9B,0xFC,0xE9,0x9A,0xF9, +0x0F,0xD8,0xE0,0xE4,0xC9,0xFA,0xE4,0xCC, +0xFB,0x22,0x75,0xF0,0x10,0xEF,0x2F,0xFF, +0xEE,0x33,0xFE,0xED,0x33,0xFD,0xCC,0x33, +0xCC,0xC8,0x33,0xC8,0x10,0xD7,0x07,0x9B, +0xEC,0x9A,0xE8,0x99,0x40,0x0A,0xED,0x9B, +0xFD,0xEC,0x9A,0xFC,0xE8,0x99,0xF8,0x0F, +0xD5,0xF0,0xDA,0xE4,0xCD,0xFB,0xE4,0xCC, +0xFA,0xE4,0xC8,0xF9,0x22,0xEB,0x9F,0xF5, +0xF0,0xEA,0x9E,0x42,0xF0,0xE9,0x9D,0x42, +0xF0,0xE8,0x9C,0x45,0xF0,0x22,0xE0,0xFC, +0xA3,0xE0,0xFD,0xA3,0xE0,0xFE,0xA3,0xE0, +0xFF,0x22,0xE0,0xF8,0xA3,0xE0,0xF9,0xA3, +0xE0,0xFA,0xA3,0xE0,0xFB,0x22,0xEC,0xF0, +0xA3,0xED,0xF0,0xA3,0xEE,0xF0,0xA3,0xEF, +0xF0,0x22,0x12,0x03,0xF8,0x12,0x04,0x1A, +0x44,0x40,0x12,0x04,0x0F,0x7D,0x03,0x7C, +0x00,0x12,0x04,0x23,0x12,0x05,0xAF,0x12, +0x03,0xF8,0x12,0x04,0x1A,0x54,0xBF,0x12, +0x04,0x0F,0x7D,0x03,0x7C,0x00,0x12,0x03, +0xD0,0x7F,0x02,0x7E,0x66,0x12,0x05,0x67, +0xEF,0x54,0xFD,0x54,0xFE,0x12,0x04,0x33, +0x12,0x03,0xD0,0x7F,0x02,0x7E,0x66,0x12, +0x05,0x67,0xEF,0x44,0x02,0x44,0x01,0x12, +0x04,0x33,0x12,0x04,0x23,0x02,0x05,0xAF, +0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x05,0xAF,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x22, +0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66, +0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x05, +0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12,0x05, +0x67,0xEF,0x22,0x7F,0x01,0x7E,0x66,0x12, +0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x22,0xFD,0xAC,0x06,0x7F,0x02, +0x7E,0x66,0x12,0x05,0xAF,0xE4,0xFD,0xFC, +0x22,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x04,0x88,0x02,0x00,0x0E, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x05,0xCB,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0x75,0x0F,0x80, +0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, +0x83,0xE4,0xF5,0x10,0x75,0x0B,0xA0,0x75, +0x0A,0xAC,0x75,0x09,0xB9,0x75,0x08,0x03, +0x75,0x89,0x11,0x7B,0x60,0x7A,0x09,0xF9, +0xF8,0xAF,0x0B,0xAE,0x0A,0xAD,0x09,0xAC, +0x08,0x12,0x02,0xBB,0xAD,0x07,0xAC,0x06, +0xC3,0xE4,0x9D,0xFD,0xE4,0x9C,0xFC,0x78, +0x17,0xF6,0xAF,0x05,0xEF,0x08,0xF6,0x18, +0xE6,0xF5,0x8C,0x08,0xE6,0xF5,0x8A,0x74, +0x0D,0x2D,0xFD,0xE4,0x3C,0x18,0xF6,0xAF, +0x05,0xEF,0x08,0xF6,0x75,0x88,0x10,0x53, +0x8E,0xC7,0xD2,0xA9,0x22,0xC0,0xE0,0xC0, +0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, +0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, +0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, +0x2B,0xE4,0x75,0xF0,0x01,0x12,0x02,0x69, +0x90,0x06,0x2D,0xE4,0x75,0xF0,0x01,0x12, +0x02,0x69,0xD0,0x00,0xD0,0xD0,0xD0,0x82, +0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, +0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, +0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, +0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, +0xD2,0xAF,0x22,0x90,0x06,0x24,0x12,0x03, +0x5E,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, +0xE4,0x3D,0xFD,0xE4,0x3C,0x22,0xE4,0x7F, +0x20,0x7E,0x4E,0xFD,0xFC,0x90,0x06,0x24, +0x12,0x03,0x6A,0xC3,0x02,0x03,0x4D,0xC2, +0xAF,0xAB,0x07,0xAA,0x06,0x8A,0xA2,0x8B, +0xA3,0x8C,0xA4,0x8D,0xA5,0x75,0xA0,0x03, +0x00,0x00,0x00,0xAA,0xA1,0xBA,0x00,0xF8, +0xD2,0xAF,0x22,0x42,0x06,0x2D,0x00,0x00, +0x42,0x06,0x2B,0x00,0x00,0x00,0x12,0x05, +0xDF,0x12,0x04,0xCD,0x02,0x00,0x03,0xE4, +0xF5,0x8E,0x22}; + +static rtk_api_ret_t _rtk_port_FiberModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check Combo port or not */ + RTK_CHK_PORT_IS_COMBO(port); + + /* Flow Control */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG04, ®Data)) != RT_ERR_OK) + return retVal; + + if (pAbility->AsyFC == 1) + regData |= (0x0001 << 8); + else + regData &= ~(0x0001 << 8); + + if (pAbility->FC == 1) + regData |= (0x0001 << 7); + else + regData &= ~(0x0001 << 7); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG04, regData)) != RT_ERR_OK) + return retVal; + + /* Speed ability */ + if( (pAbility->Full_1000 == 1) && (pAbility->Full_100 == 1) && (pAbility->AutoNegotiation == 1) ) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 7)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) + return retVal; + } + else if(pAbility->Full_1000 == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 4)) != RT_ERR_OK) + return retVal; + + if(pAbility->AutoNegotiation == 1) + { + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x0140)) != RT_ERR_OK) + return retVal; + } + } + else if(pAbility->Full_100 == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 5)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x2100)) != RT_ERR_OK) + return retVal; + } + + /* Digital software reset */ + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= (0x0001 << 6); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0001 << 6); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /* CDR reset */ + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1401))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1403))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_port_FiberModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 data, regData; + + /* Check Combo port or not */ + RTK_CHK_PORT_IS_COMBO(port); + + memset(pAbility, 0x00, sizeof(rtk_port_phy_ability_t)); + + /* Flow Control */ + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_FIB100_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0044)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) + return retVal; + + if(regData & (0x0001 << 8)) + pAbility->AsyFC = 1; + + if(regData & (0x0001 << 7)) + pAbility->FC = 1; + + /* Speed ability */ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, &data)) != RT_ERR_OK) + return retVal; + + if(data == 0) + { + pAbility->AutoNegotiation = 1; + pAbility->Full_1000 = 1; + pAbility->Full_100 = 1; + } + else + { + if ((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, &data)) != RT_ERR_OK) + return retVal; + + if(data == 4) + { + pAbility->Full_1000 = 1; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG00, &data)) != RT_ERR_OK) + return retVal; + + if(data & 0x1000) + pAbility->AutoNegotiation = 1; + else + pAbility->AutoNegotiation = 0; + } + else if(data == 5) + pAbility->Full_100 = 1; + else + return RT_ERR_FAILED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyAutoNegoAbility_set + * Description: + * Set ethernet PHY auto-negotiation desired ability. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + */ +rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + rtk_uint32 phyEnMsk0; + rtk_uint32 phyEnMsk4; + rtk_uint32 phyEnMsk9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || + pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || + pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || + pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_set(port, pAbility); + } + } + + /*for PHY auto mode setup*/ + pAbility->AutoNegotiation = 1; + + phyEnMsk0 = 0; + phyEnMsk4 = 0; + phyEnMsk9 = 0; + + if (1 == pAbility->Half_10) + { + /*10BASE-TX half duplex capable in reg 4.5*/ + phyEnMsk4 = phyEnMsk4 | (1 << 5); + + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + } + + if (1 == pAbility->Full_10) + { + /*10BASE-TX full duplex capable in reg 4.6*/ + phyEnMsk4 = phyEnMsk4 | (1 << 6); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + + } + + if (1 == pAbility->Half_100) + { + /*100BASE-TX half duplex capable in reg 4.7*/ + phyEnMsk4 = phyEnMsk4 | (1 << 7); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + } + + + if (1 == pAbility->Full_100) + { + /*100BASE-TX full duplex capable in reg 4.8*/ + phyEnMsk4 = phyEnMsk4 | (1 << 8); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + } + + + if (1 == pAbility->Full_1000) + { + /*1000 BASE-T FULL duplex capable setting in reg 9.9*/ + phyEnMsk9 = phyEnMsk9 | (1 << 9); + + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 | (1 << 6); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + + + /*Auto-Negotiation setting in reg 0.12*/ + phyEnMsk0 = phyEnMsk0 | (1 << 12); + + } + + if (1 == pAbility->AutoNegotiation) + { + /*Auto-Negotiation setting in reg 0.12*/ + phyEnMsk0 = phyEnMsk0 | (1 << 12); + } + + if (1 == pAbility->AsyFC) + { + /*Asymetric flow control in reg 4.11*/ + phyEnMsk4 = phyEnMsk4 | (1 << 11); + } + if (1 == pAbility->FC) + { + /*Flow control in reg 4.10*/ + phyEnMsk4 = phyEnMsk4 | (1 << 10); + } + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0200)) | phyEnMsk9 ; + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0DE0)) | phyEnMsk4; + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Control register setting and restart auto*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x3140)) | phyEnMsk0; + /*If have auto-negotiation capable, then restart auto negotiation*/ + if (1 == pAbility->AutoNegotiation) + { + phyData = phyData | (1 << 9); + } + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyAutoNegoAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData0; + rtk_uint32 phyData4; + rtk_uint32 phyData9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_get(port, pAbility); + } + } + + /*Control register setting and restart auto*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) + return retVal; + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) + return retVal; + + if (phyData9 & (1 << 9)) + pAbility->Full_1000 = 1; + else + pAbility->Full_1000 = 0; + + if (phyData4 & (1 << 11)) + pAbility->AsyFC = 1; + else + pAbility->AsyFC = 0; + + if (phyData4 & (1 << 10)) + pAbility->FC = 1; + else + pAbility->FC = 0; + + + if (phyData4 & (1 << 8)) + pAbility->Full_100 = 1; + else + pAbility->Full_100 = 0; + + if (phyData4 & (1 << 7)) + pAbility->Half_100 = 1; + else + pAbility->Half_100 = 0; + + if (phyData4 & (1 << 6)) + pAbility->Full_10 = 1; + else + pAbility->Full_10 = 0; + + if (phyData4 & (1 << 5)) + pAbility->Half_10 = 1; + else + pAbility->Half_10 = 0; + + + if (phyData0 & (1 << 12)) + pAbility->AutoNegotiation = 1; + else + pAbility->AutoNegotiation = 0; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyForceModeAbility_set + * Description: + * Set the port speed/duplex mode/pause/asy_pause in the PHY force mode. + * Input: + * port - port id. + * pAbility - Ability structure + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will + * be set as following 100F > 100H > 10F > 10H priority sequence. + * This API can be used to configure combo port in fiber mode. + * The possible parameters in fiber mode are Full_1000 and Full 100. + * All the other fields in rtk_port_phy_ability_t will be ignored in fiber port. + */ +rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + rtk_uint32 phyEnMsk0; + rtk_uint32 phyEnMsk4; + rtk_uint32 phyEnMsk9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || + pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || + pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || + pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_set(port, pAbility); + } + } + + if (1 == pAbility->Full_1000) + return RT_ERR_INPUT; + + /*for PHY force mode setup*/ + pAbility->AutoNegotiation = 0; + + phyEnMsk0 = 0; + phyEnMsk4 = 0; + phyEnMsk9 = 0; + + if (1 == pAbility->Half_10) + { + /*10BASE-TX half duplex capable in reg 4.5*/ + phyEnMsk4 = phyEnMsk4 | (1 << 5); + + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + } + + if (1 == pAbility->Full_10) + { + /*10BASE-TX full duplex capable in reg 4.6*/ + phyEnMsk4 = phyEnMsk4 | (1 << 6); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); + + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + + } + + if (1 == pAbility->Half_100) + { + /*100BASE-TX half duplex capable in reg 4.7*/ + phyEnMsk4 = phyEnMsk4 | (1 << 7); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + } + + + if (1 == pAbility->Full_100) + { + /*100BASE-TX full duplex capable in reg 4.8*/ + phyEnMsk4 = phyEnMsk4 | (1 << 8); + /*Speed selection [1:0] */ + /* 11=Reserved*/ + /* 10= 1000Mpbs*/ + /* 01= 100Mpbs*/ + /* 00= 10Mpbs*/ + phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); + phyEnMsk0 = phyEnMsk0 | (1 << 13); + /*Full duplex mode in reg 0.8*/ + phyEnMsk0 = phyEnMsk0 | (1 << 8); + } + + if (1 == pAbility->AsyFC) + { + /*Asymetric flow control in reg 4.11*/ + phyEnMsk4 = phyEnMsk4 | (1 << 11); + } + if (1 == pAbility->FC) + { + /*Flow control in reg 4.10*/ + phyEnMsk4 = phyEnMsk4 | ((1 << 10)); + } + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0200)) | phyEnMsk9 ; + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) + return retVal; + + phyData = (phyData & (~0x0DE0)) | phyEnMsk4; + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) + return retVal; + + /*Control register setting and power off/on*/ + phyData = phyEnMsk0 & (~(1 << 12)); + phyData |= (1 << 11); /* power down PHY, bit 11 should be set to 1 */ + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + phyData = phyData & (~(1 << 11)); /* power on PHY, bit 11 should be set to 0*/ + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyForceModeAbility_get + * Description: + * Get PHY ability through PHY registers. + * Input: + * port - Port id. + * Output: + * pAbility - Ability structure + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * Get the capablity of specified PHY. + */ +rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData0; + rtk_uint32 phyData4; + rtk_uint32 phyData9; + rtk_port_media_t media_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pAbility) + return RT_ERR_NULL_POINTER; + + if (rtk_switch_isComboPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) + return retVal; + + if(media_type == PORT_MEDIA_FIBER) + { + return _rtk_port_FiberModeAbility_get(port, pAbility); + } + } + + /*Control register setting and restart auto*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) + return retVal; + + /*Auto-Negotiation control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) + return retVal; + + /*1000 BASE-T control register setting*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) + return retVal; + + if (phyData9 & (1 << 9)) + pAbility->Full_1000 = 1; + else + pAbility->Full_1000 = 0; + + if (phyData4 & (1 << 11)) + pAbility->AsyFC = 1; + else + pAbility->AsyFC = 0; + + if (phyData4 & ((1 << 10))) + pAbility->FC = 1; + else + pAbility->FC = 0; + + + if (phyData4 & (1 << 8)) + pAbility->Full_100 = 1; + else + pAbility->Full_100 = 0; + + if (phyData4 & (1 << 7)) + pAbility->Half_100 = 1; + else + pAbility->Half_100 = 0; + + if (phyData4 & (1 << 6)) + pAbility->Full_10 = 1; + else + pAbility->Full_10 = 0; + + if (phyData4 & (1 << 5)) + pAbility->Half_10 = 1; + else + pAbility->Half_10 = 0; + + + if (phyData0 & (1 << 12)) + pAbility->AutoNegotiation = 1; + else + pAbility->AutoNegotiation = 0; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyStatus_get + * Description: + * Get ethernet PHY linking status + * Input: + * port - Port id. + * Output: + * linkStatus - PHY link status + * speed - PHY link speed + * duplex - PHY duplex mode + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * API will return auto negotiation status of phy. + */ +rtk_api_ret_t rtk_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if( (NULL == pLinkStatus) || (NULL == pSpeed) || (NULL == pDuplex) ) + return RT_ERR_NULL_POINTER; + + /*Get PHY resolved register*/ + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_RESOLVED_REG, &phyData)) != RT_ERR_OK) + return retVal; + + /*check link status*/ + if (phyData & (1<<2)) + { + *pLinkStatus = 1; + + /*check link speed*/ + *pSpeed = (phyData&0x0030) >> 4; + + /*check link duplex*/ + *pDuplex = (phyData&0x0008) >> 3; + } + else + { + *pLinkStatus = 0; + *pSpeed = 0; + *pDuplex = 0; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLink_set + * Description: + * Set port force linking configuration. + * Input: + * port - port id. + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can set Port/MAC force mode properties. + */ +rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + if (pPortability->forcemode >1|| pPortability->speed > 2 || pPortability->duplex > 1 || + pPortability->link > 1 || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) + return retVal; + + ability.forcemode = pPortability->forcemode; + ability.speed = pPortability->speed; + ability.duplex = pPortability->duplex; + ability.link = pPortability->link; + ability.nway = pPortability->nway; + ability.txpause = pPortability->txpause; + ability.rxpause = pPortability->rxpause; + + if ((retVal = rtl8367c_setAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLink_get + * Description: + * Get port force linking configuration. + * Input: + * port - Port id. + * Output: + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get Port/MAC force mode properties. + */ +rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) + return retVal; + + pPortability->forcemode = ability.forcemode; + pPortability->speed = ability.speed; + pPortability->duplex = ability.duplex; + pPortability->link = ability.link; + pPortability->nway = ability.nway; + pPortability->txpause = ability.txpause; + pPortability->rxpause = ability.rxpause; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLinkExt_set + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * mode - external interface mode + * pPortability - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface force mode properties. + * The external interface can be set to: + * - MODE_EXT_DISABLE, + * - MODE_EXT_RGMII, + * - MODE_EXT_MII_MAC, + * - MODE_EXT_MII_PHY, + * - MODE_EXT_TMII_MAC, + * - MODE_EXT_TMII_PHY, + * - MODE_EXT_GMII, + * - MODE_EXT_RMII_MAC, + * - MODE_EXT_RMII_PHY, + * - MODE_EXT_SGMII, + * - MODE_EXT_HSGMII, + * - MODE_EXT_1000X_100FX, + * - MODE_EXT_1000X, + * - MODE_EXT_100FX, + */ +rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + if (mode >=MODE_EXT_END) + return RT_ERR_INPUT; + + if(mode == MODE_EXT_HSGMII) + { + if (pPortability->forcemode > 1 || pPortability->speed != PORT_SPEED_2500M || pPortability->duplex != PORT_FULL_DUPLEX || + pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) + return RT_ERR_INPUT; + + if(rtk_switch_isHsgPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + } + else + { + if (pPortability->forcemode > 1 || pPortability->speed > PORT_SPEED_1000M || pPortability->duplex >= PORT_DUPLEX_END || + pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) + return RT_ERR_INPUT; + } + + ext_id = port - 15; + + if(mode == MODE_EXT_DISABLE) + { + memset(&ability, 0x00, sizeof(rtl8367c_port_ability_t)); + if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + + ability.forcemode = pPortability->forcemode; + ability.speed = (mode == MODE_EXT_HSGMII) ? PORT_SPEED_1000M : pPortability->speed; + ability.duplex = pPortability->duplex; + ability.link = pPortability->link; + ability.nway = pPortability->nway; + ability.txpause = pPortability->txpause; + ability.rxpause = pPortability->rxpause; + + if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macForceLinkExt_get + * Description: + * Set external interface force linking configuration. + * Input: + * port - external port ID + * Output: + * pMode - external interface mode + * pPortability - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get external interface force mode properties. + */ +rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability) +{ + rtk_api_ret_t retVal; + rtl8367c_port_ability_t ability; + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if(NULL == pPortability) + return RT_ERR_NULL_POINTER; + + ext_id = port - 15; + + if ((retVal = rtl8367c_getAsicPortExtMode(ext_id, (rtk_uint32 *)pMode)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) + return retVal; + + pPortability->forcemode = ability.forcemode; + pPortability->speed = (*pMode == MODE_EXT_HSGMII) ? PORT_SPEED_2500M : ability.speed; + pPortability->duplex = ability.duplex; + pPortability->link = ability.link; + pPortability->nway = ability.nway; + pPortability->txpause = ability.txpause; + pPortability->rxpause = ability.rxpause; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_port_macStatus_get + * Description: + * Get port link status. + * Input: + * port - Port id. + * Output: + * pPortstatus - port ability configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get Port/PHY properties. + */ +rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus) +{ + rtk_api_ret_t retVal; + rtl8367c_port_status_t status; + rtk_uint32 hsgsel; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPortstatus) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortStatus(rtk_switch_port_L2P_get(port), &status)) != RT_ERR_OK) + return retVal; + + + pPortstatus->duplex = status.duplex; + pPortstatus->link = status.link; + pPortstatus->nway = status.nway; + pPortstatus->txpause = status.txpause; + pPortstatus->rxpause = status.rxpause; + + if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgsel)) != RT_ERR_OK) + return retVal; + + if( (rtk_switch_isHsgPort(port) == RT_ERR_OK) && (hsgsel == 1) ) + pPortstatus->speed = PORT_SPEED_2500M; + else + pPortstatus->speed = status.speed; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_set + * Description: + * Set Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * enable - Loopback state, 0:disable, 1:enable + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can enable/disable Local loopback in MAC. + * For UTP port, This API will also enable the digital + * loopback bit in PHY register for sync of speed between + * PHY and MAC. For EXT port, users need to force the + * link state by themself. + */ +rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortLoopback(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if(enable == ENABLED) + data |= (0x0001 << 14); + else + data &= ~(0x0001 << 14); + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, data)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_macLocalLoopbackEnable_get + * Description: + * Get Port Local Loopback. (Redirect TX to RX.) + * Input: + * port - Port id. + * Output: + * pEnable - Loopback state, 0:disable, 1:enable + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortLoopback(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyReg_set + * Description: + * Set PHY register data of the specific port. + * Input: + * port - port id. + * reg - Register id + * regData - Register data + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can set PHY register data of the specific port. + */ +rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t regData) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), reg, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyReg_get + * Description: + * Get PHY register data of the specific port. + * Input: + * port - Port id. + * reg - Register id + * Output: + * pData - Register data + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PHY_REG_ID - Invalid PHY address + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * This API can get PHY register data of the specific port. + */ +rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), reg, pData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_backpressureEnable_set + * Description: + * Set the half duplex backpressure enable status of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE(Defer) + * - ENABLE (Backpressure) + */ +rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortJamMode(!enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_backpressureEnable_get + * Description: + * Get the half duplex backpressure enable status of the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get the half duplex backpressure enable status of the specific port. + * The half duplex backpressure enable status of the port is as following: + * - DISABLE(Defer) + * - ENABLE (Backpressure) + */ +rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortJamMode(®Data)) != RT_ERR_OK) + return retVal; + + *pEnable = !regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_adminEnable_set + * Description: + * Set port admin configuration of the specific port. + * Input: + * port - port id. + * enable - Back pressure status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + { + data &= 0xF7FF; + data |= 0x0200; + } + else if (DISABLED == enable) + { + data |= 0x0800; + } + + if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_adminEnable_get + * Description: + * Get port admin configurationof the specific port. + * Input: + * port - Port id. + * Output: + * pEnable - Back pressure status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API can get port admin configuration of the specific port. + * The port admin configuration of the port is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if ( (data & 0x0800) == 0x0800) + { + *pEnable = DISABLED; + } + else + { + *pEnable = ENABLED; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_isolation_set + * Description: + * Set permitted port isolation portmask + * Input: + * port - port id. + * pPortmask - Permit port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * This API set the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + /* check port mask */ + RTK_CHK_PORTMASK_VALID(pPortmask); + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_isolation_get + * Description: + * Get permitted port isolation portmask + * Input: + * port - Port id. + * Output: + * pPortmask - Permit port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * This API get the port mask that a port can trasmit packet to of each port + * A port can only transmit packet to ports included in permitted portmask + */ +rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rgmiiDelayExt_set + * Description: + * Set RGMII interface delay value for TX and RX. + * Input: + * txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay + * rxDelay - RX delay value, 0~7 for delay setup. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for no-delay, and 7 for maximum delay. + */ +rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay) +{ + rtk_api_ret_t retVal; + rtk_uint32 regAddr, regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if ((txDelay > 1) || (rxDelay > 7)) + return RT_ERR_INPUT; + + if(port == EXT_PORT0) + regAddr = RTL8367C_REG_EXT1_RGMXF; + else if(port == EXT_PORT1) + regAddr = RTL8367C_REG_EXT2_RGMXF; + else + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + regData = (regData & 0xFFF0) | ((txDelay << 3) & 0x0008) | (rxDelay & 0x0007); + + if ((retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rgmiiDelayExt_get + * Description: + * Get RGMII interface delay value for TX and RX. + * Input: + * None + * Output: + * pTxDelay - TX delay value + * pRxDelay - RX delay value + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set external interface 2 RGMII delay. + * In TX delay, there are 2 selection: no-delay and 2ns delay. + * In RX dekay, there are 8 steps for delay tunning. 0 for n0-delay, and 7 for maximum delay. + */ +rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay) +{ + rtk_api_ret_t retVal; + rtk_uint32 regAddr, regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_EXT(port); + + if( (NULL == pTxDelay) || (NULL == pRxDelay) ) + return RT_ERR_NULL_POINTER; + + if(port == EXT_PORT0) + regAddr = RTL8367C_REG_EXT1_RGMXF; + else if(port == EXT_PORT1) + regAddr = RTL8367C_REG_EXT2_RGMXF; + else + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pTxDelay = (regData & 0x0008) >> 3; + *pRxDelay = regData & 0x0007; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyEnableAll_set + * Description: + * Set all PHY enable status. + * Input: + * enable - PHY Enable State. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 data; + rtk_uint32 port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortEnableAll(enable)) != RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + { + data &= 0xF7FF; + data |= 0x0200; + } + else + { + data |= 0x0800; + } + + if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_port_phyEnableAll_get + * Description: + * Get all PHY enable status. + * Input: + * None + * Output: + * pEnable - PHY Enable State. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can set all PHY status. + * The configuration of all PHY is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_port_phyEnableAll_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortEnableAll(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_efid_set + * Description: + * Set port-based enhanced filtering database + * Input: + * port - Port id. + * efid - Specified enhanced filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based enhanced filtering database. + */ +rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* efid must be 0~7 */ + if (efid > RTK_EFID_MAX) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), efid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_efid_get + * Description: + * Get port-based enhanced filtering database + * Input: + * port - Port id. + * Output: + * pEfid - Specified enhanced filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based enhanced filtering database status. + */ +rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEfid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), pEfid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyComboPortMedia_set + * Description: + * Set Combo port media type + * Input: + * port - Port id. + * media - Media (COPPER or FIBER) + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + rtk_uint32 idx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + /* Check Combo Port ID */ + RTK_CHK_PORT_IS_COMBO(port); + + if (media >= PORT_MEDIA_END) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + if(regData != 0x6367) + return RT_ERR_CHIP_NOT_SUPPORTED; + + if(media == PORT_MEDIA_FIBER) + { + /* software init */ + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + for(idx = 0; idx < FIBER_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber[idx])) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, 1))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_DW8051_READY_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_phyComboPortMedia_get + * Description: + * Get Combo port media type + * Input: + * port - Port id. + * Output: + * pMedia - Media (COPPER or FIBER) + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can Set Combo port media type. + */ +rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + rtk_uint32 data; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + /* Check Combo Port ID */ + RTK_CHK_PORT_IS_COMBO(port); + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + if(regData != 0x6367) + { + *pMedia = PORT_MEDIA_COPPER; + } + else + { + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, &data))!=RT_ERR_OK) + return retVal; + + if(data == 1) + *pMedia = PORT_MEDIA_COPPER; + else + *pMedia = PORT_MEDIA_FIBER; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rtctEnable_set + * Description: + * Enable RTCT test + * Input: + * pPortmask - Port mask of RTCT enabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can enable RTCT Test + */ +rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Mask Valid */ + RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); + + if ((retVal = rtl8367c_setAsicPortRTCTEnable(pPortmask->bits[0]))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_rtctDisable_set + * Description: + * Disable RTCT test + * Input: + * pPortmask - Port mask of RTCT disabled port + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask. + * Note: + * The API can disable RTCT Test + */ +rtk_api_ret_t rtk_port_rtctDisable_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Mask Valid */ + RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); + + if ((retVal = rtl8367c_setAsicPortRTCTDisable(pPortmask->bits[0]))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_port_rtctResult_get + * Description: + * Get the result of RTCT test + * Input: + * port - Port ID + * Output: + * pRtctResult - The result of RTCT result + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_PHY_RTCT_NOT_FINISH - Testing does not finish. + * Note: + * The API can get RTCT test result. + * RTCT test may takes 4.8 seconds to finish its test at most. + * Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or + * other error code, the result can not be referenced and + * user should call this API again until this API returns + * a RT_ERR_OK. + * The result is stored at pRtctResult->ge_result + * pRtctResult->linkType is unused. + * The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M + */ +rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult) +{ + rtk_api_ret_t retVal; + rtl8367c_port_rtct_result_t result; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_IS_UTP(port); + + memset(pRtctResult, 0x00, sizeof(rtk_rtctResult_t)); + if ((retVal = rtl8367c_getAsicPortRTCTResult(port, &result))!=RT_ERR_OK) + return retVal; + + pRtctResult->result.ge_result.channelALen = result.channelALen; + pRtctResult->result.ge_result.channelBLen = result.channelBLen; + pRtctResult->result.ge_result.channelCLen = result.channelCLen; + pRtctResult->result.ge_result.channelDLen = result.channelDLen; + + pRtctResult->result.ge_result.channelALinedriver = result.channelALinedriver; + pRtctResult->result.ge_result.channelBLinedriver = result.channelBLinedriver; + pRtctResult->result.ge_result.channelCLinedriver = result.channelCLinedriver; + pRtctResult->result.ge_result.channelDLinedriver = result.channelDLinedriver; + + pRtctResult->result.ge_result.channelAMismatch = result.channelAMismatch; + pRtctResult->result.ge_result.channelBMismatch = result.channelBMismatch; + pRtctResult->result.ge_result.channelCMismatch = result.channelCMismatch; + pRtctResult->result.ge_result.channelDMismatch = result.channelDMismatch; + + pRtctResult->result.ge_result.channelAOpen = result.channelAOpen; + pRtctResult->result.ge_result.channelBOpen = result.channelBOpen; + pRtctResult->result.ge_result.channelCOpen = result.channelCOpen; + pRtctResult->result.ge_result.channelDOpen = result.channelDOpen; + + pRtctResult->result.ge_result.channelAShort = result.channelAShort; + pRtctResult->result.ge_result.channelBShort = result.channelBShort; + pRtctResult->result.ge_result.channelCShort = result.channelCShort; + pRtctResult->result.ge_result.channelDShort = result.channelDShort; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_port_sds_reset + * Description: + * Reset Serdes + * Input: + * port - Port ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + ext_id = port - 15; + return rtl8367c_sdsReset(ext_id); +} + +/* Function Name: + * rtk_port_sgmiiLinkStatus_get + * Description: + * Get SGMII status + * Input: + * port - Port ID + * Output: + * pSignalDetect - Signal detect + * pSync - Sync + * pLink - Link + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can reset Serdes + */ +rtk_api_ret_t rtk_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + if(NULL == pSignalDetect) + return RT_ERR_NULL_POINTER; + + if(NULL == pSync) + return RT_ERR_NULL_POINTER; + + if(NULL == pLink) + return RT_ERR_NULL_POINTER; + + ext_id = port - 15; + return rtl8367c_getSdsLinkStatus(ext_id, (rtk_uint32 *)pSignalDetect, (rtk_uint32 *)pSync, (rtk_uint32 *)pLink); +} + +/* Function Name: + * rtk_port_sgmiiNway_set + * Description: + * Configure SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * state - Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API configure SGMII/HSGMII port Nway state + */ +rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + if(state >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + ext_id = port - 15; + return rtl8367c_setSgmiiNway(ext_id, (rtk_uint32)state); +} + +/* Function Name: + * rtk_port_sgmiiNway_get + * Description: + * Get SGMII/HSGMII port Nway state + * Input: + * port - Port ID + * Output: + * pState - Nway state + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get SGMII/HSGMII port Nway state + */ +rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState) +{ + rtk_uint32 ext_id; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) + return RT_ERR_PORT_ID; + + if(NULL == pState) + return RT_ERR_NULL_POINTER; + + ext_id = port - 15; + return rtl8367c_getSgmiiNway(ext_id, (rtk_uint32 *)pState); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/ptp.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/ptp.c new file mode 100755 index 00000000..40962a0e --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/ptp.c @@ -0,0 +1,759 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 39583 $ + * $Date: 2013-05-20 16:59:23 +0800 (星期一, 20 五月 2013) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in time module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_ptp_init + * Description: + * PTP function initialization. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is used to initialize PTP status. + */ +rtk_api_ret_t rtk_ptp_init(void) +{ + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_mac_set + * Description: + * Configure PTP mac address. + * Input: + * mac - mac address to parser PTP packets. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac) +{ + rtk_api_ret_t retVal; + ether_addr_t sw_mac; + + memcpy(sw_mac.octet, mac.octet, ETHER_ADDR_LEN); + + if((retVal=rtl8367c_setAsicEavMacAddress(sw_mac))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_mac_get + * Description: + * Get PTP mac address. + * Input: + * None + * Output: + * pMac - mac address to parser PTP packets. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac) +{ + rtk_api_ret_t retVal; + ether_addr_t sw_mac; + + if((retVal=rtl8367c_getAsicEavMacAddress(&sw_mac))!=RT_ERR_OK) + return retVal; + + memcpy(pMac->octet, sw_mac.octet, ETHER_ADDR_LEN); + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_tpid_set + * Description: + * Configure PTP accepted outer & inner tag TPID. + * Input: + * outerId - Ether type of S-tag frame parsing in PTP ports. + * innerId - Ether type of C-tag frame parsing in PTP ports. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((outerId>RTK_MAX_NUM_OF_TPID) ||(innerId>RTK_MAX_NUM_OF_TPID)) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavTpid(outerId, innerId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_tpid_get + * Description: + * Get PTP accepted outer & inner tag TPID. + * Input: + * None + * Output: + * pOuterId - Ether type of S-tag frame parsing in PTP ports. + * pInnerId - Ether type of C-tag frame parsing in PTP ports. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicEavTpid(pOuterId, pInnerId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTime_set + * Description: + * Set the reference time of the specified device. + * Input: + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavSysTime(timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTime_get + * Description: + * Get the reference time of the specified device. + * Input: + * Output: + * pTimeStamp - pointer buffer of the reference time + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicEavSysTime(&pTimeStamp->sec, &pTimeStamp->nsec))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTimeAdjust_set + * Description: + * Adjust the reference time. + * Input: + * unit - unit id + * sign - significant + * timeStamp - reference timestamp value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * sign=0 for positive adjustment, sign=1 for negative adjustment. + */ +rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavSysTimeAdjust(sign, timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTimeEnable_set + * Description: + * Set the enable state of reference time of the specified device. + * Input: + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTimeEnable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicEavSysTimeCtrl(enable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_refTimeEnable_get + * Description: + * Get the enable state of reference time of the specified device. + * Input: + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicEavSysTimeCtrl(pEnable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_portEnable_set + * Description: + * Set PTP status of the specified port. + * Input: + * port - port id + * enable - status + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is PTP port */ + RTK_CHK_PORT_IS_PTP(port); + + if (enable>=RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavPortEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_portEnable_get + * Description: + * Get PTP status of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is PTP port */ + RTK_CHK_PORT_IS_PTP(port); + + if ((retVal = rtl8367c_getAsicEavPortEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_ptp_portTimestamp_get + * Description: + * Get PTP timstamp according to the PTP identifier on the dedicated port from the specified device. + * Input: + * unit - unit id + * port - port id + * type - PTP message type + * Output: + * pInfo - pointer buffer of sequence ID and timestamp + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Applicable: + * 8390, 8380 + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo) +{ + rtk_api_ret_t retVal; + rtl8367c_ptp_time_stamp_t time; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port is PTP port */ + RTK_CHK_PORT_IS_PTP(port); + + if ((retVal = rtl8367c_getAsicEavPortTimeStamp(rtk_switch_port_L2P_get(port), type, &time)) != RT_ERR_OK) + return retVal; + + pInfo->sequenceId = time.sequence_id; + pInfo->timeStamp.sec = time.second; + pInfo->timeStamp.nsec = time.nano_second; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_intControl_set + * Description: + * Set PTP interrupt trigger status configuration. + * Input: + * type - Interrupt type. + * enable - Interrupt status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set PTP interrupt status configuration. + * The interrupt trigger status is shown in the following: + * PTP_INT_TYPE_TX_SYNC = 0, + * PTP_INT_TYPE_TX_DELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_REQ, + * PTP_INT_TYPE_TX_PDELAY_RESP, + * PTP_INT_TYPE_RX_SYNC, + * PTP_INT_TYPE_RX_DELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_REQ, + * PTP_INT_TYPE_RX_PDELAY_RESP, + * PTP_INT_TYPE_ALL, + */ +rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 mask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type>=PTP_INT_TYPE_END) + return RT_ERR_INPUT; + + if (PTP_INT_TYPE_ALL!=type) + { + if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) + return retVal; + + if (ENABLED == enable) + mask = mask | (1<=PTP_INT_TYPE_ALL) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) + return retVal; + + if (0 == (mask&(1<=RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicEavTrap(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_ptp_portPtpEnable_get + * Description: + * Get PTP packet trap of the specified port. + * Input: + * port - port id + * Output: + * pEnable - status + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT - invalid port id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_ptp_portTrap_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicEavTrap(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/qos.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/qos.c new file mode 100755 index 00000000..70067a30 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/qos.c @@ -0,0 +1,1452 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in QoS module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Function Name: + * rtk_qos_init + * Description: + * Configure Qos default settings with queue number assigment to each port. + * Input: + * queueNum - Queue number of each port. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API will initialize related Qos setting with queue number assigment. + * The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum) +{ + CONST_T rtk_uint16 g_prioritytToQid[8][8]= { + {0, 0,0,0,0,0,0,0}, + {0, 0,0,0,7,7,7,7}, + {0, 0,0,0,1,1,7,7}, + {0, 0,1,1,2,2,7,7}, + {0, 0,1,1,2,3,7,7}, + {0, 0,1,2,3,4,7,7}, + {0, 0,1,2,3,4,5,7}, + {0,1,2,3,4,5,6,7} + }; + + CONST_T rtk_uint32 g_priorityDecision[8] = {0x01, 0x80,0x04,0x02,0x20,0x40,0x10,0x08}; + CONST_T rtk_uint32 g_prioritytRemap[8] = {0,1,2,3,4,5,6,7}; + + rtk_api_ret_t retVal; + rtk_uint32 qmapidx; + rtk_uint32 priority; + rtk_uint32 priDec; + rtk_uint32 port; + rtk_uint32 dscp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (queueNum <= 0 || queueNum > RTK_MAX_NUM_OF_QUEUE) + return RT_ERR_QUEUE_NUM; + + /*Set Output Queue Number*/ + if (RTK_MAX_NUM_OF_QUEUE == queueNum) + qmapidx = 0; + else + qmapidx = queueNum; + + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(port, qmapidx)) != RT_ERR_OK) + return retVal; + } + + /*Set Priority to Qid*/ + for (priority = 0; priority <= RTK_PRIMAX; priority++) + { + if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queueNum - 1, priority, g_prioritytToQid[queueNum - 1][priority])) != RT_ERR_OK) + return retVal; + } + + /*Set Flow Control Type to Ingress Flow Control*/ + if ((retVal = rtl8367c_setAsicFlowControlSelect(FC_INGRESS)) != RT_ERR_OK) + return retVal; + + + /*Priority Decision Order*/ + for (priDec = 0;priDec < PRIDEC_END;priDec++) + { + if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX0, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX1, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) + return retVal; + } + + /*Set Port-based Priority to 0*/ + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicPriorityPortBased(port, 0)) != RT_ERR_OK) + return retVal; + } + + /*Disable 1p Remarking*/ + RTK_SCAN_ALL_PHY_PORTMASK(port) + { + if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(port, DISABLED)) != RT_ERR_OK) + return retVal; + } + + /*Disable DSCP Remarking*/ + if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(DISABLED)) != RT_ERR_OK) + return retVal; + + /*Set 1p & DSCP Priority Remapping & Remarking*/ + for (priority = 0; priority <= RTL8367C_PRIMAX; priority++) + { + if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(priority, g_prioritytRemap[priority])) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(priority, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(priority, 0)) != RT_ERR_OK) + return retVal; + } + + /*Set DSCP Priority*/ + for (dscp = 0; dscp <= 63; dscp++) + { + if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, 0)) != RT_ERR_OK) + return retVal; + } + + /* Finetune B/T value */ + if((retVal = rtl8367c_setAsicReg(0x1722, 0x1158)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priSel_set + * Description: + * Configure the priority order among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter. + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT + * - PRIDEC_ACL + * - PRIDEC_DSCP + * - PRIDEC_1Q + * - PRIDEC_1AD + * - PRIDEC_CVLAN + * - PRIDEC_DA + * - PRIDEC_SA + */ +rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) +{ + rtk_api_ret_t retVal; + rtk_uint32 port_pow; + rtk_uint32 dot1q_pow; + rtk_uint32 dscp_pow; + rtk_uint32 acl_pow; + rtk_uint32 svlan_pow; + rtk_uint32 cvlan_pow; + rtk_uint32 smac_pow; + rtk_uint32 dmac_pow; + rtk_uint32 i; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index < 0 || index >= PRIDECTBL_END) + return RT_ERR_ENTRY_INDEX; + + if (pPriDec->port_pri >= 8 || pPriDec->dot1q_pri >= 8 || pPriDec->acl_pri >= 8 || pPriDec->dscp_pri >= 8 || + pPriDec->cvlan_pri >= 8 || pPriDec->svlan_pri >= 8 || pPriDec->dmac_pri >= 8 || pPriDec->smac_pri >= 8) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + port_pow = 1; + for (i = pPriDec->port_pri; i > 0; i--) + port_pow = (port_pow)*2; + + dot1q_pow = 1; + for (i = pPriDec->dot1q_pri; i > 0; i--) + dot1q_pow = (dot1q_pow)*2; + + acl_pow = 1; + for (i = pPriDec->acl_pri; i > 0; i--) + acl_pow = (acl_pow)*2; + + dscp_pow = 1; + for (i = pPriDec->dscp_pri; i > 0; i--) + dscp_pow = (dscp_pow)*2; + + svlan_pow = 1; + for (i = pPriDec->svlan_pri; i > 0; i--) + svlan_pow = (svlan_pow)*2; + + cvlan_pow = 1; + for (i = pPriDec->cvlan_pri; i > 0; i--) + cvlan_pow = (cvlan_pow)*2; + + dmac_pow = 1; + for (i = pPriDec->dmac_pri; i > 0; i--) + dmac_pow = (dmac_pow)*2; + + smac_pow = 1; + for (i = pPriDec->smac_pri; i > 0; i--) + smac_pow = (smac_pow)*2; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_PORT, port_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_ACL, acl_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DSCP, dscp_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1Q, dot1q_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1AD, svlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_CVLAN, cvlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DA, dmac_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_SA, smac_pow)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priSel_get + * Description: + * Get the priority order configuration among different priority mechanism. + * Input: + * index - Priority decision table index (0~1) + * Output: + * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision . + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. + * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to + * assign queue priority to receiving frame. + * The priority sources are: + * - PRIDEC_PORT, + * - PRIDEC_ACL, + * - PRIDEC_DSCP, + * - PRIDEC_1Q, + * - PRIDEC_1AD, + * - PRIDEC_CVLAN, + * - PRIDEC_DA, + * - PRIDEC_SA, + */ +rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) +{ + + rtk_api_ret_t retVal; + rtk_int32 i; + rtk_uint32 port_pow; + rtk_uint32 dot1q_pow; + rtk_uint32 dscp_pow; + rtk_uint32 acl_pow; + rtk_uint32 svlan_pow; + rtk_uint32 cvlan_pow; + rtk_uint32 smac_pow; + rtk_uint32 dmac_pow; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index < 0 || index >= PRIDECTBL_END) + return RT_ERR_ENTRY_INDEX; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_PORT, &port_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_ACL, &acl_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DSCP, &dscp_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1Q, &dot1q_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1AD, &svlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_CVLAN, &cvlan_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DA, &dmac_pow)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_SA, &smac_pow)) != RT_ERR_OK) + return retVal; + + for (i = 31; i >= 0; i--) + { + if (port_pow & (1 << i)) + { + pPriDec->port_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (dot1q_pow & (1 << i)) + { + pPriDec->dot1q_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (acl_pow & (1 << i)) + { + pPriDec->acl_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (dscp_pow & (1 << i)) + { + pPriDec->dscp_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (svlan_pow & (1 << i)) + { + pPriDec->svlan_pri = i; + break; + } + } + + for (i = 31;i >= 0; i--) + { + if (cvlan_pow & (1 << i)) + { + pPriDec->cvlan_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (dmac_pow&(1<dmac_pri = i; + break; + } + } + + for (i = 31; i >= 0; i--) + { + if (smac_pow & (1 << i)) + { + pPriDec->smac_pri = i; + break; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pPriRemap_set + * Description: + * Configure 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dot1p_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(dot1p_pri, int_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pPriRemap_get + * Description: + * Get 1Q priorities mapping to internal absolute priority. + * Input: + * dot1p_pri - 802.1p priority value . + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * Priority of 802.1Q assigment for internal asic priority, and it is uesed for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dot1p_pri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicPriorityDot1qRemapping(dot1p_pri, pInt_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpPriRemap_set + * Description: + * Map dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * int_pri - internal priority value . + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if (dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, int_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpPriRemap_get + * Description: + * Get dscp value to internal priority. + * Input: + * dscp - Dscp value of receiving frame + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically + * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of + * DSCP are carefully chosen then backward compatibility can be achieved. + */ +rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_getAsicPriorityDscpBased(dscp, pInt_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPri_set + * Description: + * Configure priority usage to each port. + * Input: + * port - Port id. + * int_pri - internal priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_SEL_PORT_PRI - Invalid port priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_setAsicPriorityPortBased(rtk_switch_port_L2P_get(port), int_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPri_get + * Description: + * Get priority usage to each port. + * Input: + * port - Port id. + * Output: + * pInt_pri - internal priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicPriorityPortBased(rtk_switch_port_L2P_get(port), pInt_pri)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_queueNum_set + * Description: + * Set output queue number for each port. + * Input: + * port - Port id. + * index - Mapping queue number (1~8) + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can set the output queue number of the specified port. The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) + return RT_ERR_FAILED; + + if (RTK_MAX_NUM_OF_QUEUE == queue_num) + queue_num = 0; + + if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), queue_num)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_queueNum_get + * Description: + * Get output queue number. + * Input: + * port - Port id. + * Output: + * pQueue_num - Mapping queue number + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API will return the output queue number of the specified port. The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num) +{ + rtk_api_ret_t retVal; + rtk_uint32 qidx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), &qidx)) != RT_ERR_OK) + return retVal; + + if (0 == qidx) + *pQueue_num = 8; + else + *pQueue_num = qidx; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priMap_set + * Description: + * Set output queue number for each port. + * Input: + * queue_num - Queue number usage. + * pPri2qid - Priority mapping to queue ID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * RT_ERR_QUEUE_ID - Invalid queue id. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * ASIC supports priority mapping to queue with different queue number from 1 to 8. + * For different queue numbers usage, ASIC supports different internal available queue IDs. + */ +rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) +{ + rtk_api_ret_t retVal; + rtk_uint32 pri; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) + return RT_ERR_QUEUE_NUM; + + for (pri = 0; pri <= RTK_PRIMAX; pri++) + { + if (pPri2qid->pri2queue[pri] > RTK_QIDMAX) + return RT_ERR_QUEUE_ID; + + if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queue_num - 1, pri, pPri2qid->pri2queue[pri])) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_priMap_get + * Description: + * Get priority to queue ID mapping table parameters. + * Input: + * queue_num - Queue number usage. + * Output: + * pPri2qid - Priority mapping to queue ID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QUEUE_NUM - Invalid queue number. + * Note: + * The API can return the mapping queue id of the specified priority and queue number. + * The queue number is from 1 to 8. + */ +rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) +{ + rtk_api_ret_t retVal; + rtk_uint32 pri; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) + return RT_ERR_QUEUE_NUM; + + for (pri = 0; pri <= RTK_PRIMAX; pri++) + { + if ((retVal = rtl8367c_getAsicPriorityToQIDMappingTable(queue_num-1, pri, &pPri2qid->pri2queue[pri])) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_schedulingQueue_set + * Description: + * Set weight and type of queues in dedicated port. + * Input: + * port - Port id. + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight. + * Note: + * The API can set weight and type, strict priority or weight fair queue (WFQ) for + * dedicated port for using queues. If queue id is not included in queue usage, + * then its type and weight setting in dummy for setting. There are priorities + * as queue id in strict queues. It means strict queue id 5 carrying higher priority + * than strict queue id 4. The WFQ queue weight is from 1 to 127, and weight 0 is + * for strict priority queue type. + */ +rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) +{ + rtk_api_ret_t retVal; + rtk_uint32 qid; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + for (qid = 0; qid < RTL8367C_QUEUENO; qid ++) + { + + if (pQweights->weights[qid] > QOS_WEIGHT_MAX) + return RT_ERR_QOS_QUEUE_WEIGHT; + + if (0 == pQweights->weights[qid]) + { + if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_STRICT)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_WFQ)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicWFQWeight(rtk_switch_port_L2P_get(port),qid, pQweights->weights[qid])) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_schedulingQueue_get + * Description: + * Get weight and type of queues in dedicated port. + * Input: + * port - Port id. + * Output: + * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get weight and type, strict priority or weight fair queue (WFQ) for dedicated port for using queues. + * The WFQ queue weight is from 1 to 127, and weight 0 is for strict priority queue type. + */ +rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) +{ + rtk_api_ret_t retVal; + rtk_uint32 qid,qtype,qweight; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + for (qid = 0; qid < RTL8367C_QUEUENO; qid++) + { + if ((retVal = rtl8367c_getAsicQueueType(rtk_switch_port_L2P_get(port), qid, &qtype)) != RT_ERR_OK) + return retVal; + + if (QTYPE_STRICT == qtype) + { + pQweights->weights[qid] = 0; + } + else if (QTYPE_WFQ == qtype) + { + if ((retVal = rtl8367c_getAsicWFQWeight(rtk_switch_port_L2P_get(port), qid, &qweight)) != RT_ERR_OK) + return retVal; + pQweights->weights[qid] = qweight; + } + } + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkEnable_set + * Description: + * Set 1p Remarking state + * Input: + * port - Port id. + * enable - State of per-port 1p Remarking + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable 802.1p remarking ability for whole system. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_1pRemarkEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkEnable_get + * Description: + * Get 802.1p remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - Status of 802.1p remark. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get 802.1p remarking ability. + * The status of 802.1p remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_1pRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemark_set + * Description: + * Set 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * dot1p_pri - 802.1p priority value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can set 802.1p parameters source priority and new priority. + */ +rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if (dot1p_pri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(int_pri, dot1p_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemark_get + * Description: + * Get 802.1p remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * pDot1p_pri - 802.1p priority value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get 802.1p remarking parameters. It would return new priority of ingress priority. + */ +rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicRemarkingDot1pParameter(int_pri, pDot1p_pri)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_set + * Description: + * Set remarking source of 802.1p remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure 802.1p remark functionality to map original 802.1p value or internal + * priority to TX DSCP value. + */ +rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= DOT1P_RMK_SRC_END ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_setAsicRemarkingDot1pSrc(type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_1pRemarkSrcSel_get + * Description: + * Get remarking source of 802.1p remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRemarkingDot1pSrc(pType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_qos_dscpRemarkEnable_set + * Description: + * Set DSCP remarking ability. + * Input: + * port - Port id. + * enable - status of DSCP remark. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_ENABLE - Invalid enable parameter. + * Note: + * The API can enable or disable DSCP remarking ability for whole system. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /*for whole system function, the port value should be 0xFF*/ + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemarkEnable_get + * Description: + * Get DSCP remarking ability. + * Input: + * port - Port id. + * Output: + * pEnable - status of DSCP remarking. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get DSCP remarking ability. + * The status of DSCP remark: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /*for whole system function, the port value should be 0xFF*/ + if (port != RTK_WHOLE_SYSTEM) + return RT_ERR_PORT_ID; + + if ((retVal = rtl8367c_getAsicRemarkingDscpAbility(pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemark_set + * Description: + * Set DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * dscp - DSCP value. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. + * Note: + * The API can set DSCP value and mapping priority. + */ +rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTK_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if (dscp > RTK_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(int_pri, dscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_qos_dscpRemark_get + * Description: + * Get DSCP remarking parameter. + * Input: + * int_pri - Internal priority value. + * Output: + * Dscp - DSCP value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority. + * Note: + * The API can get DSCP parameters. It would return DSCP value for mapping priority. + */ +rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (int_pri > RTK_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_getAsicRemarkingDscpParameter(int_pri, pDscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemarkSrcSel_set + * Description: + * Set remarking source of DSCP remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure DSCP remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= DSCP_RMK_SRC_END ) + return RT_ERR_QOS_INT_PRIORITY; + + if ((retVal = rtl8367c_setAsicRemarkingDscpSrc(type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dcpRemarkSrcSel_get + * Description: + * Get remarking source of DSCP remarking. + * Input: + * none + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRemarkingDscpSrc(pType)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_set + * Description: + * Set DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * rmkDscp - remarked DSCP value + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * Note: + * dscp parameter can be DSCP value or internal priority according to configuration of API + * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP + * value or internal priority to TX DSCP value. + */ +rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((dscp > RTK_DSCPMAX) || (rmkDscp > RTK_DSCPMAX)) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_setAsicRemarkingDscp2Dscp(dscp, rmkDscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_dscpRemark2Dscp_get + * Description: + * Get DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * Output: + * pDscp - remarked DSCP value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None. + */ +rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (dscp > RTK_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + if ((retVal = rtl8367c_getAsicRemarkingDscp2Dscp(dscp, pDscp)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPriSelIndex_set + * Description: + * Configure priority decision index to each port. + * Input: + * port - Port id. + * index - priority decision index. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENTRY_INDEX - Invalid entry index. + * Note: + * The API can set priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (index >= PRIDECTBL_END ) + return RT_ERR_ENTRY_INDEX; + + if ((retVal = rtl8367c_setAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), index)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_qos_portPriSelIndex_get + * Description: + * Get priority decision index from each port. + * Input: + * port - Port id. + * Output: + * pIndex - priority decision index. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get priority of port assignments for queue usage and packet scheduling. + */ +rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), pIndex)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rate.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rate.c new file mode 100755 index 00000000..a077e0c5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rate.c @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in rate module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Function Name: + * rtk_rate_shareMeter_set + * Description: + * Set meter configuration + * Input: + * index - shared meter index + * type - shared meter type + * rate - rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_RATE - Invalid rate + * RT_ERR_INPUT - Invalid input parameters + * Note: + * The API can set shared meter rate and ifg include for each meter. + * The rate unit is 1 kbps and the range is from 8k to 1048568k if type is METER_TYPE_KBPS and + * the granularity of rate is 8 kbps. + * The rate unit is packets per second and the range is 1 ~ 0x1FFF if type is METER_TYPE_PPS. + * The ifg_include parameter is used + * for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_shareMeter_set(rtk_meter_id_t index, rtk_meter_type_t type, rtk_rate_t rate, rtk_enable_t ifg_include) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if (type >= METER_TYPE_END) + return RT_ERR_INPUT; + + if (ifg_include >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + switch (type) + { + case METER_TYPE_KBPS: + if (rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG || rate < RTL8367C_QOS_RATE_INPUT_MIN) + return RT_ERR_RATE ; + + if ((retVal = rtl8367c_setAsicShareMeter(index, rate >> 3, ifg_include)) != RT_ERR_OK) + return retVal; + + break; + case METER_TYPE_PPS: + if (rate > RTL8367C_QOS_PPS_INPUT_MAX || rate < RTL8367C_QOS_PPS_INPUT_MIN) + return RT_ERR_RATE ; + + if ((retVal = rtl8367c_setAsicShareMeter(index, rate, ifg_include)) != RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_INPUT; + } + + /* Set Type */ + if ((retVal = rtl8367c_setAsicShareMeterType(index, (rtk_uint32)type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_shareMeter_get + * Description: + * Get meter configuration + * Input: + * index - shared meter index + * Output: + * pType - Meter Type + * pRate - pointer of rate of share meter + * pIfg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_shareMeter_get(rtk_meter_id_t index, rtk_meter_type_t *pType, rtk_rate_t *pRate, rtk_enable_t *pIfg_include) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if(NULL == pRate) + return RT_ERR_NULL_POINTER; + + if(NULL == pIfg_include) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicShareMeter(index, ®Data, pIfg_include)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicShareMeterType(index, (rtk_uint32 *)pType)) != RT_ERR_OK) + return retVal; + + if(*pType == METER_TYPE_KBPS) + *pRate = regData<<3; + else + *pRate = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_shareMeterBucket_set + * Description: + * Set meter Bucket Size + * Input: + * index - shared meter index + * bucket_size - Bucket Size + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_INPUT - Error Input + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can set shared meter bucket size. + */ +rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(bucket_size > RTL8367C_METERBUCKETSIZEMAX) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicShareMeterBucketSize(index, bucket_size)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_shareMeterBucket_get + * Description: + * Get meter Bucket Size + * Input: + * index - shared meter index + * Output: + * pBucket_size - Bucket Size + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * The API can get shared meter bucket size. + */ +rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(NULL == pBucket_size) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicShareMeterBucketSize(index, pBucket_size)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_set + * Description: + * Set port ingress bandwidth control + * Input: + * port - Port id + * rate - Rate of share meter + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * fc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_ENABLE - Invalid IFG parameter. + * RT_ERR_INBW_RATE - Invalid ingress rate parameter. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_set(rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include, rtk_enable_t fc_enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(ifg_include >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(fc_enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if(rtk_switch_isHsgPort(port) == RT_ERR_OK) + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + else + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + + if ((retVal = rtl8367c_setAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), rate>>3, ifg_include,fc_enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_igrBandwidthCtrlRate_get + * Description: + * Get port ingress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of share meter + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * pFc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include, rtk_enable_t *pFc_enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pIfg_include) + return RT_ERR_NULL_POINTER; + + if(NULL == pFc_enable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), ®Data, pIfg_include, pFc_enable)) != RT_ERR_OK) + return retVal; + + *pRate = regData<<3; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_set + * Description: + * Set port egress bandwidth control + * Input: + * port - Port id + * rate - Rate of egress bandwidth + * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_QOS_EBW_RATE - Invalid egress bandwidth/rate + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(rtk_switch_isHsgPort(port) == RT_ERR_OK) + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + else + { + if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) + return RT_ERR_QOS_EBW_RATE ; + } + + if (ifg_include >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicPortEgressRate(rtk_switch_port_L2P_get(port), rate>>3)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortEgressRateIfg(ifg_include)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrBandwidthCtrlRate_get + * Description: + * Get port egress bandwidth control + * Input: + * port - Port id + * Output: + * pRate - Rate of egress bandwidth + * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. + * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. + */ +rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pRate) + return RT_ERR_NULL_POINTER; + + if(NULL == pIfg_include) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortEgressRate(rtk_switch_port_L2P_get(port), ®Data)) != RT_ERR_OK) + return retVal; + + *pRate = regData << 3; + + if ((retVal = rtl8367c_getAsicPortEgressRateIfg((rtk_uint32*)pIfg_include)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rate_egrQueueBwCtrlEnable_get + * Description: + * Get enable status of egress bandwidth control on specified queue. + * Input: + * unit - unit id + * port - port id + * queue - queue id + * Output: + * pEnable - Pointer to enable status of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /*for whole port function, the queue value should be 0xFF*/ + if (queue != RTK_WHOLE_SYSTEM) + return RT_ERR_QUEUE_ID; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicAprEnable(rtk_switch_port_L2P_get(port),pEnable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrQueueBwCtrlEnable_set + * Description: + * Set enable status of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * enable - enable status of egress queue bandwidth control + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_INPUT - invalid input parameter + * Note: + * None + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /*for whole port function, the queue value should be 0xFF*/ + if (queue != RTK_WHOLE_SYSTEM) + return RT_ERR_QUEUE_ID; + + if (enable>=RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicAprEnable(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_get + * Description: + * Get rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * pIndex - shared meter index + * Output: + * pRate - pointer to rate of egress queue bandwidth control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex) +{ + rtk_api_ret_t retVal; + rtk_uint32 offset_idx; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (queue >= RTK_MAX_NUM_OF_QUEUE) + return RT_ERR_QUEUE_ID; + + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + phy_port = rtk_switch_port_L2P_get(port); + if ((retVal=rtl8367c_getAsicAprMeter(phy_port, queue,&offset_idx))!=RT_ERR_OK) + return retVal; + + *pIndex = offset_idx + ((phy_port%4)*8); + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rate_egrQueueBwCtrlRate_set + * Description: + * Set rate of egress bandwidth control on specified queue. + * Input: + * port - port id + * queue - queue id + * index - shared meter index + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_QUEUE_ID - invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter id + * Note: + * The actual rate control is set in shared meters. + * The unit of granularity is 8Kbps. + */ +rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index) +{ + rtk_api_ret_t retVal; + rtk_uint32 offset_idx; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (queue >= RTK_MAX_NUM_OF_QUEUE) + return RT_ERR_QUEUE_ID; + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + phy_port = rtk_switch_port_L2P_get(port); + if (index < ((phy_port%4)*8) || index > (7 + (phy_port%4)*8)) + return RT_ERR_FILTER_METER_ID; + + offset_idx = index - ((phy_port%4)*8); + + if ((retVal=rtl8367c_setAsicAprMeter(phy_port,queue,offset_idx))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rldp.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rldp.c new file mode 100755 index 00000000..d3ca0297 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rldp.c @@ -0,0 +1,468 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ + * + * Purpose : Declaration of RLDP and RLPP API + * + * Feature : The file have include the following module and sub-modules + * 1) RLDP and RLPP configuration and status + * + */ + + +/* + * Include Files + */ +#include +#include +//#include +#include + +#include +#include + +/* + * Symbol Definition + */ + + +/* + * Data Declaration + */ + + +/* + * Macro Declaration + */ + + +/* + * Function Declaration + */ + +/* Module Name : RLDP */ + +/* Function Name: + * rtk_rldp_config_set + * Description: + * Set RLDP module configuration + * Input: + * pConfig - configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig) +{ + rtk_api_ret_t retVal; + ether_addr_t magic; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (pConfig->rldp_enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (pConfig->trigger_mode >= RTK_RLDP_TRIGGER_END) + return RT_ERR_INPUT; + + if (pConfig->compare_type >= RTK_RLDP_CMPTYPE_END) + return RT_ERR_INPUT; + + if (pConfig->num_check >= RTK_RLDP_NUM_MAX) + return RT_ERR_INPUT; + + if (pConfig->interval_check >= RTK_RLDP_INTERVAL_MAX) + return RT_ERR_INPUT; + + if (pConfig->num_loop >= RTK_RLDP_NUM_MAX) + return RT_ERR_INPUT; + + if (pConfig->interval_loop >= RTK_RLDP_INTERVAL_MAX) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpTxPortmask(0x00))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpTxPortmask(pmsk))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldp(pConfig->rldp_enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpTriggerMode(pConfig->trigger_mode))!=RT_ERR_OK) + return retVal; + + memcpy(&magic, &pConfig->magic, sizeof(ether_addr_t)); + if ((retVal = rtl8367c_setAsicRldpMagicNum(magic))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpCheckingStatePara(pConfig->num_check, pConfig->interval_check))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRldpLoopStatePara(pConfig->num_loop, pConfig->interval_loop))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rldp_config_get + * Description: + * Get RLDP module configuration + * Input: + * None + * Output: + * pConfig - configuration structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig) +{ + rtk_api_ret_t retVal; + ether_addr_t magic; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRldp(&pConfig->rldp_enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpTriggerMode(&pConfig->trigger_mode))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpMagicNum(&magic))!=RT_ERR_OK) + return retVal; + memcpy(&pConfig->magic, &magic, sizeof(ether_addr_t)); + + if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpCheckingStatePara(&pConfig->num_check, &pConfig->interval_check))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRldpLoopStatePara(&pConfig->num_loop, &pConfig->interval_loop))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rldp_portConfig_set + * Description: + * Set per port RLDP module configuration + * Input: + * port - port number to be configured + * pPortConfig - per port configuration structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + rtk_uint32 phy_port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (pPortConfig->tx_enable>= RTK_ENABLE_END) + return RT_ERR_INPUT; + + phy_port = rtk_switch_port_L2P_get(port); + + if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + + if (pPortConfig->tx_enable) + { + pmsk |=(1<tx_enable = ENABLED; + } + else + { + pPortConfig->tx_enable = DISABLED; + } + + return RT_ERR_OK; +} /* end of rtk_rldp_portConfig_get */ + + +/* Function Name: + * rtk_rldp_status_get + * Description: + * Get RLDP module status + * Input: + * None + * Output: + * pStatus - status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus) +{ + rtk_api_ret_t retVal; + ether_addr_t seed; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_getAsicRldpRandomNumber(&seed))!=RT_ERR_OK) + return retVal; + memcpy(&pStatus->id, &seed, sizeof(ether_addr_t)); + + return RT_ERR_OK; +} /* end of rtk_rldp_status_get */ + + +/* Function Name: + * rtk_rldp_portStatus_get + * Description: + * Get RLDP module status + * Input: + * port - port number to be get + * Output: + * pPortStatus - per port status structure of RLDP + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * None + */ +rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + rtk_portmask_t logicalPmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicRldpLoopedPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) + return retVal; + + if (logicalPmask.bits[0] & (1<loop_status = RTK_RLDP_LOOPSTS_LOOPING; + } + else + { + pPortStatus->loop_status = RTK_RLDP_LOOPSTS_NONE; + } + + if ((retVal = rtl8367c_getAsicRldpEnterLoopedPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) + return retVal; + + if (logicalPmask.bits[0] & (1<loop_enter = RTK_RLDP_LOOPSTS_LOOPING; + } + else + { + pPortStatus->loop_enter = RTK_RLDP_LOOPSTS_NONE; + } + + if ((retVal = rtl8367c_getAsicRldpLeaveLoopedPortmask(&pmsk))!=RT_ERR_OK) + return retVal; + if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) + return retVal; + + if (logicalPmask.bits[0] & (1<loop_leave = RTK_RLDP_LOOPSTS_LOOPING; + } + else + { + pPortStatus->loop_leave = RTK_RLDP_LOOPSTS_NONE; + } + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_rldp_portStatus_clear + * Description: + * Clear RLDP module status + * Input: + * port - port number to be clear + * pPortStatus - per port status structure of RLDP + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT + * RT_ERR_NULL_POINTER + * Note: + * Clear operation effect loop_enter and loop_leave only, other field in + * the structure are don't care. Loop status cab't be clean. + */ +rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + pmsk = (pPortStatus->loop_enter)<loop_leave)< +#include +#include "./include/rtk_switch.h" +#include "./include/vlan.h" +#include "./include/port.h" +#include "./include/rate.h" +#include "./include/rtk_hal.h" +#include "./include/l2.h" +#include "./include/stat.h" +#include "./include/igmp.h" +#include "./include/trap.h" +#include "./include/leaky.h" +#include "./include/mirror.h" +#include "./include/rtl8367c_asicdrv_port.h" +#include "./include/rtl8367c_asicdrv_mib.h" +#include "./include/smi.h" +#include "./include/qos.h" +#include "./include/trunk.h" + +void rtk_hal_switch_init(void) +{ + if(rtk_switch_init() != 0) + printk("rtk_switch_init failed\n"); + mdelay(500); + /*vlan init */ + if (rtk_vlan_init() != 0) + printk("rtk_vlan_init failed\n"); +} + +void rtk_hal_dump_full_mib(void) +{ + rtk_port_t port; + rtk_stat_counter_t Cntr; + rtk_stat_port_type_t cntr_idx; + + for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { + printk("\nPort%d\n", port); + for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu ", Cntr); + if (((cntr_idx%10) == 9)) + printk("\n"); + } + } + + for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { + printk("\nPort%d\n", port); + for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu ", Cntr); + if (((cntr_idx%10) == 9)) + printk("\n"); + } + } + rtk_stat_global_reset(); +} +void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) +{ + rtk_port_t port; + rtk_stat_counter_t Cntr; + + for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + printk("\n"); +} + +void rtk_hal_dump_mib(void) +{ + + printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", + "Port2", "Port3", "Port4", "Port16", "Port17"); + /* Get TX Unicast Pkts */ + printk("TX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfOutUcastPkts); + /* Get TX Multicast Pkts */ + printk("TX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfOutMulticastPkts); + /* Get TX BroadCast Pkts */ + printk("TX BroadCast Pkts:"); + rtk_dump_mib_type(STAT_IfOutBroadcastPkts); + /* Get TX Collisions */ + /* Get TX Puase Frames */ + printk("TX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3OutPauseFrames); + /* Get TX Drop Events */ + /* Get RX Unicast Pkts */ + printk("RX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfInUcastPkts); + /* Get RX Multicast Pkts */ + printk("RX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfInMulticastPkts); + /* Get RX Broadcast Pkts */ + printk("RX Broadcast Pkts:"); + rtk_dump_mib_type(STAT_IfInBroadcastPkts); + /* Get RX FCS Erros */ + printk("RX FCS Errors :"); + rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); + /* Get RX Undersize Pkts */ + printk("RX Undersize Pkts:"); + rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); + /* Get RX Discard Pkts */ + printk("RX Discard Pkts :"); + rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); + /* Get RX Fragments */ + printk("RX Fragments :"); + rtk_dump_mib_type(STAT_EtherStatsFragments); + /* Get RX Oversize Pkts */ + printk("RX Oversize Pkts :"); + rtk_dump_mib_type(STAT_EtherOversizeStats); + /* Get RX Jabbers */ + printk("RX Jabbers :"); + rtk_dump_mib_type(STAT_EtherStatsJabbers); + /* Get RX Pause Frames */ + printk("RX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3InPauseFrames); + /* clear MIB */ + rtk_stat_global_reset(); +} +EXPORT_SYMBOL(rtk_hal_dump_mib); + +int rtk_hal_dump_vlan(void) +{ + rtk_vlan_cfg_t vlan; + int i; + + printk("vid portmap\n"); + for (i = 0; i < RTK_SW_VID_RANGE; i++) { + rtk_vlan_get(i, &vlan); + printk("%3d ", i); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT1) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT2) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT3) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT4) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT1) ? '1' : '-'); + printk("\n"); + } + return 0; +} + +void rtk_hal_clear_vlan(void) +{ + rtk_api_ret_t ret; + + ret = rtk_vlan_reset(); + if (ret != RT_ERR_OK) + printk("rtk_vlan_reset failed\n"); +} + +int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data) +{ + rtk_vlan_cfg_t vlan; + rtk_api_ret_t ret; + int i; + + /* clear vlan entry first */ + memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); + RTK_PORTMASK_CLEAR(vlan.mbr); + RTK_PORTMASK_CLEAR(vlan.untag); + rtk_vlan_set(data->vid, &vlan); + + memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); + for (i = 0; i < 5; i++) { + if (data->port_map & (1 << i)) { + RTK_PORTMASK_PORT_SET(vlan.mbr, i); + RTK_PORTMASK_PORT_SET(vlan.untag, i); + rtk_vlan_portPvid_set(i, data->vid, 0); + } + } + for (i = 0; i < 2; i++) { + if (data->port_map & (1 << (i + 5))) { + RTK_PORTMASK_PORT_SET(vlan.mbr, (i + EXT_PORT0)); + RTK_PORTMASK_PORT_SET(vlan.untag, (i + EXT_PORT0)); + rtk_vlan_portPvid_set((i + EXT_PORT0), data->vid, 0); + } + } + vlan.ivl_en = 1; + ret = rtk_vlan_set(data->vid, &vlan); + + return 0; +} + +void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) +{ + rtk_vlan_portPvid_set(port, pvid, priority); +} + +int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + if (data->on_off == 1) + ret = + rtk_rate_igrBandwidthCtrlRate_set(data->port, data->bw, 0, + 1); + else + ret = + rtk_rate_igrBandwidthCtrlRate_set(data->port, 1048568, 0, + 1); + + return ret; +} + +int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + if (data->on_off == 1) + ret = + rtk_rate_egrBandwidthCtrlRate_set(data->port, data->bw, 1); + else + ret = rtk_rate_egrBandwidthCtrlRate_set(data->port, 1048568, 1); + + return ret; +} + +void rtk_hal_dump_table(void) +{ + rtk_uint32 i; + rtk_uint32 address = 0; + rtk_l2_ucastAddr_t l2_data; + rtk_l2_ipMcastAddr_t ipMcastAddr; + + printk("hash port(0:17) fid vid mac-address\n"); + while (1) { + if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { + break; + } else { + printk("%03x ", l2_data.address); + for (i = 0; i < 5; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + for (i = 16; i < 18; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + + printk(" %2d", l2_data.fid); + printk(" %4d", l2_data.cvid); + printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], + l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], + l2_data.mac.octet[4], l2_data.mac.octet[5]); + address ++; + } + } + + address = 0; + while (1) { + if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { + break; + } else { + printk("%03x ", ipMcastAddr.address); + for (i = 0; i < 5; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + for (i = 16; i < 18; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + printk(" "); + printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); + address ++; + } + } +} + +void rtk_hal_clear_table(void) +{ + rtk_api_ret_t ret; + + ret = rtk_l2_table_clear(); + if (ret != RT_ERR_OK) + printk("rtk_l2_table_clear failed\n"); +} + +void rtk_hal_add_table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_l2_ucastAddr_t l2_entry; + rtk_mac_t mac; + + mac.octet[0] =data->mac[0]; + mac.octet[1] =data->mac[1]; + mac.octet[2] =data->mac[2]; + mac.octet[3] =data->mac[3]; + mac.octet[4] =data->mac[4]; + mac.octet[5] =data->mac[5]; + + memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); + l2_entry.port = data->port; + l2_entry.ivl = 1; + l2_entry.cvid = data->vid; + l2_entry.fid = 0; + l2_entry.efid = 0; + l2_entry.is_static = 1; + ret = rtk_l2_addr_add(&mac, &l2_entry); + if (ret != RT_ERR_OK) + printk("rtk_hal_add_table failed\n"); +} + +void rtk_hal_del_table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_l2_ucastAddr_t l2_entry; + rtk_mac_t mac; + + mac.octet[0] =data->mac[0]; + mac.octet[1] =data->mac[1]; + mac.octet[2] =data->mac[2]; + mac.octet[3] =data->mac[3]; + mac.octet[4] =data->mac[4]; + mac.octet[5] =data->mac[5]; + + memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); + l2_entry.port = data->port; + l2_entry.ivl = 1; + l2_entry.cvid = data->vid; + l2_entry.fid = 0; + l2_entry.efid = 0; + ret = rtk_l2_addr_del(&mac, &l2_entry); + if (ret != RT_ERR_OK) + printk("rtk_hal_add_table failed\n"); +} +void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data) +{ + rtk_port_linkStatus_t linkStatus; + rtk_port_speed_t speed; + rtk_port_duplex_t duplex; + + rtk_port_phyStatus_get(data->port, &linkStatus, &speed, &duplex); + printk("Port%d Status:\n", data->port); + if (linkStatus == 1) { + printk("Link Up"); + if (speed == 0) + printk(" 10M"); + else if (speed == 1) + printk(" 100M"); + else if (speed == 2) + printk(" 1000M"); + if (duplex == 0) + printk(" Half Duplex\n"); + else + printk(" Full Duplex\n"); + } else + printk("Link Down\n"); + +} + +void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data) +{ + rtk_portmask_t rx_portmask; + rtk_portmask_t tx_portmask; + rtk_api_ret_t ret; + int i; + + rtk_mirror_portIso_set(ENABLED); + RTK_PORTMASK_CLEAR(rx_portmask); + RTK_PORTMASK_CLEAR(tx_portmask); + for (i = 0; i < 5; i++) + if (data->rx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(rx_portmask, i); + for (i = 0; i < 2; i++) + if (data->rx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); + + RTK_PORTMASK_CLEAR(tx_portmask); + for (i = 0; i < 5; i++) + if (data->tx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(tx_portmask, i); + for (i = 0; i < 2; i++) + if (data->tx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); + + ret = rtk_mirror_portBased_set(data->port, &rx_portmask, &tx_portmask); + if (!ret) + printk("rtk_mirror_portBased_set success\n"); +} + +void rtk_hal_read_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + + retVal = smi_read(data->reg_addr, &data->reg_val); + if(retVal != RT_ERR_OK) + printk("switch reg read failed\n"); + else + printk("reg0x%x = 0x%x\n", data->reg_addr, data->reg_val); +} + +void rtk_hal_write_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + + retVal = smi_write(data->reg_addr, data->reg_val); + if(retVal != RT_ERR_OK) + printk("switch reg write failed\n"); + else + printk("write switch reg0x%x 0x%x success\n", data->reg_addr, data->reg_val); +} + +void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + rtk_port_phy_data_t Data; + + retVal = rtk_port_phyReg_get(data->port, data->reg_addr, &Data); + if (retVal == RT_ERR_OK) + printk("Get: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, Data); + else + printk("read phy reg failed\n"); +} + +void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data) +{ + ret_t retVal; + + retVal = rtk_port_phyReg_set(data->port, data->reg_addr, data->reg_val); + if (retVal == RT_ERR_OK) + printk("Set: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, data->reg_val); + else + printk("write phy reg failed\n"); +} +void rtk_hal_qos_en(struct ra_switch_ioctl_data *data) +{ + + if (data->on_off == 1) { + if (rtk_qos_init(8) != 0) + printk("rtk_qos_init(8) failed\n"); + } + else { + if (rtk_qos_init(1) != 0) + printk("rtk_qos_init(1) failed\n"); + } +} + +void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_priority_select_t PriDec; + + /* write all pri to 0 */ + PriDec.port_pri = 0; + PriDec.dot1q_pri = 0; + PriDec.acl_pri = 0; + PriDec.cvlan_pri = 0; + PriDec.svlan_pri = 0; + PriDec.dscp_pri = 0; + PriDec.dmac_pri = 0; + PriDec.smac_pri = 0; + + if (data->qos_type == 0) + PriDec.port_pri = 1; + else if (data->qos_type == 1) + PriDec.dot1q_pri = 1; + else if (data->qos_type == 2) + PriDec.acl_pri = 1; + else if (data->qos_type == 3) + PriDec.dscp_pri = 1; + else if (data->qos_type == 4) + PriDec.cvlan_pri = 1; + else if (data->qos_type == 5) + PriDec.svlan_pri = 1; + else if (data->qos_type == 6) + PriDec.dmac_pri = 1; + else if (data->qos_type == 7) + PriDec.smac_pri = 1; + + if (data->qos_table_idx == 0) + ret = rtk_qos_priSel_set(PRIDECTBL_IDX0, &PriDec); + else + ret = rtk_qos_priSel_set(PRIDECTBL_IDX1, &PriDec); + + if (ret != 0) + printk("rtk_qos_priSel_set failed\n"); + +} + +void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_priority_select_t PriDec; + + if (data->qos_table_idx == 0) + ret = rtk_qos_priSel_get(PRIDECTBL_IDX0, &PriDec); + else + ret = rtk_qos_priSel_get(PRIDECTBL_IDX1, &PriDec); + + if (ret != 0) + printk("rtk_qos_priSel_set failed\n"); + else { + printk("port_pri = %d\n", PriDec.port_pri); + printk("dot1q_pri = %d\n", PriDec.dot1q_pri); + printk("acl_pri = %d\n", PriDec.acl_pri); + printk("dscp_pri = %d\n", PriDec.dscp_pri); + printk("cvlan_pri = %d\n", PriDec.cvlan_pri); + printk("svlan_pri = %d\n", PriDec.svlan_pri); + printk("dmac_pri = %d\n", PriDec.dmac_pri); + printk("smac_pri = %d\n", PriDec.smac_pri); + } +} + +void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_qos_portPriSelIndex_set(data->port, data->qos_table_idx); + if (ret != 0) + printk("rtk_qos_portPriSelIndex_set failed\n"); +} + +void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_qos_priDecTbl_t Index; + + ret = rtk_qos_portPriSelIndex_get(data->port, &Index); + if (ret != 0) + printk("rtk_qos_portPriSelIndex_set failed\n"); + else + printk("port%d belongs to table%d\n", data->port, Index); +} + +void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_qos_portPri_set(data->port, data->qos_pri); + if (ret != 0) + printk("rtk_qos_portPri_set failed\n"); +} + +void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_pri_t Int_pri; + + ret = rtk_qos_portPri_get(data->port, &Int_pri); + if (ret != 0) + printk("rtk_qos_portPri_set failed\n"); + else + printk("port%d priority = %d\n", data->port, Int_pri); +} + +void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_qos_dscpPriRemap_set(data->qos_dscp, data->qos_pri); + if (ret != 0) + printk("rtk_qos_dscpPriRemap_set failed\n"); +} + +void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_pri_t Int_pri; + + ret = rtk_qos_dscpPriRemap_get(data->qos_dscp, &Int_pri); + if (ret != 0) + printk("rtk_qos_dscpPriRemap_set failed\n"); + else + printk("dscp%d priority is %d\n", data->qos_dscp, Int_pri); +} + +void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_qos_pri2queue_t pri2qid; + + ret = rtk_qos_priMap_get(8, &pri2qid); + pri2qid.pri2queue[data->qos_queue_num] = data->qos_pri; + ret = rtk_qos_priMap_set(8, &pri2qid); + if (ret != 0) + printk("rtk_qos_priMap_set failed\n"); +} + +void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data) +{ + int i; + rtk_api_ret_t ret; + rtk_qos_pri2queue_t pri2qid; + + ret = rtk_qos_priMap_get(8, &pri2qid); + if (ret != 0) + printk("rtk_qos_priMap_get failed\n"); + else { + for (i = 0; i < 8; i++) + printk("pri2qid.pri2queue[%d] = %d\n", i, pri2qid.pri2queue[i]); + } +} + +void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_qos_queue_weights_t qweights; + + ret = rtk_qos_schedulingQueue_get(data->port, &qweights); + qweights.weights[data->qos_queue_num] = data->qos_weight; + ret = rtk_qos_schedulingQueue_set(data->port, &qweights); + if (ret != 0) + printk("rtk_qos_schedulingQueue_set failed\n"); +} + +void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data) +{ + int i; + rtk_api_ret_t ret; + rtk_qos_queue_weights_t qweights; + + ret = rtk_qos_schedulingQueue_get(data->port, &qweights); + if (ret != 0) + printk("rtk_qos_schedulingQueue_get failed\n"); + else { + printk("=== Port%d queue weight ===\n", data->port); + for (i = 0; i < 8; i++) + printk("qweights.weights[%d] = %d\n",i ,qweights.weights[i]); + } +} + +void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_portmask_t pmask; + + + ret = rtk_igmp_init(); + if (data->on_off == 1) { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + ret |= rtk_igmp_static_router_port_set(&pmask); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); + ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); + /* drop unknown multicast packets*/ + /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ + } else { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_igmp_static_router_port_set(&pmask); + } + if(ret != RT_ERR_OK) + printk("enable switch igmpsnoop failed\n"); +} + +void rtk_hal_disable_igmpsnoop(void) +{ + if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) + printk("Disable IGMP SNOOPING failed\n"); +} + +rtk_api_ret_t rtk_port_phyTestMode_set(rtk_port_t port, rtk_port_phy_test_mode_t mode) +{ + rtk_uint32 data, regData, i; + rtk_api_ret_t retVal; + + RTK_CHK_PORT_IS_UTP(port); + + if(mode >= PHY_TEST_MODE_END) + return RT_ERR_INPUT; + + if( (mode == PHY_TEST_MODE_2) || (mode == PHY_TEST_MODE_3) ) + return RT_ERR_INPUT; + + if (PHY_TEST_MODE_NORMAL != mode) + { + /* Other port should be Normal mode */ + RTK_SCAN_ALL_LOG_PORT(i) + { + if(rtk_switch_isUtpPort(i) == RT_ERR_OK) + { + if(i != port) + { + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(i), 9, &data)) != RT_ERR_OK) + return retVal; + + if((data & 0xE000) != 0) + return RT_ERR_NOT_ALLOWED; + } + } + } + } + + if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 9, &data)) != RT_ERR_OK) + return retVal; + + data &= ~0xE000; + data |= (mode << 13); + if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 9, data)) != RT_ERR_OK) + return retVal; + + if (PHY_TEST_MODE_4 == mode) + { + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x0276) || (regData == 0x0597) ) + { + if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xbcc2, 0xF4F4)) != RT_ERR_OK) + return retVal; + } + + if( (regData == 0x6367) ) + { + if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa436, 0x80c1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa438, 0xfe00)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + + ret = rtk_port_phyTestMode_set(data->port, data->mode); + if (ret != RT_ERR_OK) + printk("rtk_port_phyTestMode_set failed\n"); + else + printk("set port%d in test mode %d.\n", data->port, data->mode); +} + +void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data) +{ + + rtk_api_ret_t ret; + rtk_portmask_t member; + int i; + + RTK_PORTMASK_CLEAR(member); + for (i = 0; i < 4; i++) { + if (data->port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(member, i); + } + + ret = rtk_trunk_port_set(TRUNK_GROUP0, &member); + if (ret != RT_ERR_OK) + printk("rtk_trunk_port_set failed\n"); + + ret = rtk_trunk_distributionAlgorithm_set(RTK_WHOLE_SYSTEM, 0x7F); + if (ret != RT_ERR_OK) + printk("rtk_trunk_distributionAlgorithm_set failed\n"); +} + +void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data) +{ + rtk_api_ret_t ret; + rtk_vlan_cfg_t vlan; + + ret = rtk_vlan_get(data->vid, &vlan); + if (ret != RT_ERR_OK) + printk("rtk_vlan_get failed\n"); + else { + if (data->on_off == 0) + RTK_PORTMASK_PORT_SET(vlan.untag, data->port); + else + RTK_PORTMASK_PORT_CLEAR(vlan.untag, data->port); + + ret = rtk_vlan_set(data->vid, &vlan); + if (ret != RT_ERR_OK) + printk("rtk_vlan_set failed\n"); + } +} + +void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data) +{ + rtk_vlan_cfg_t vlan1, vlan2; + rtk_api_ret_t ret; + + ret = rtk_vlan_get(1, &vlan1); + if (ret != RT_ERR_OK) + printk("rtk_vlan_get failed\n"); + + ret = rtk_vlan_get(2, &vlan2); + if (ret != RT_ERR_OK) + printk("rtk_vlan_get failed\n"); + + if (data->mode == 0) { //ivl + vlan1.ivl_en = 1; + vlan1.fid_msti = 0; + rtk_vlan_set(1, &vlan1); + vlan2.ivl_en = 1; + vlan2.fid_msti = 0; + rtk_vlan_set(2, &vlan2); + } else if(data->mode == 1) {//svl + vlan1.ivl_en = 0; + vlan1.fid_msti = 0; + rtk_vlan_set(1, &vlan1); + vlan2.ivl_en = 0; + vlan2.fid_msti = 1; + rtk_vlan_set(2, &vlan2); + } else + printk("mode not supported\n"); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtk_switch.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtk_switch.c new file mode 100755 index 00000000..0bb0db07 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtk_switch.c @@ -0,0 +1,1796 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76336 $ + * $Date: 2017-03-09 10:41:21 +0800 (週四, 09 三月 2017) $ + * + * Purpose : RTK switch high-level API + * Feature : Here is a list of all functions and variables in this module. + * + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if defined(FORCE_PROBE_RTL8367C) +static init_state_t init_state = INIT_COMPLETED; +#elif defined(FORCE_PROBE_RTL8370B) +static init_state_t init_state = INIT_COMPLETED; +#elif defined(FORCE_PROBE_RTL8364B) +static init_state_t init_state = INIT_COMPLETED; +#elif defined(FORCE_PROBE_RTL8363SC_VB) +static init_state_t init_state = INIT_COMPLETED; +#else +static init_state_t init_state = INIT_NOT_COMPLETED; +#endif + +#define AUTO_PROBE (!defined(FORCE_PROBE_RTL8367C) && !defined(FORCE_PROBE_RTL8370B) && !defined(FORCE_PROBE_RTL8364B) && !defined(FORCE_PROBE_RTL8363SC_VB)) + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8367C)) +static rtk_switch_halCtrl_t rtl8367c_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8367C, + + /* Logical to Physical */ + {0, 1, 2, 3, 4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid CPU port mask */ + 0x00, + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 7, + + /* Physical port mask */ + 0xDF, + + /* Combo Logical port ID */ + 4, + + /* HSG Logical port ID */ + EXT_PORT0, + + /* SGMII Logical portmask */ + (0x1 << EXT_PORT0), + + /* Max Meter ID */ + 31, + + /* MAX LUT Address Number */ + 2112, + + /* Trunk Group Mask */ + 0x03 +}; +#endif + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8370B)) +static rtk_switch_halCtrl_t rtl8370b_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8370B, + + /* Logical to Physical */ + {0, 1, 2, 3, 4, 5, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 8, 9, 10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UTP_PORT5, UTP_PORT6, UTP_PORT7, + EXT_PORT0, EXT_PORT1, EXT_PORT2, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), + + /* Valid CPU port mask */ + (0x1 << EXT_PORT2), + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 10, + + /* Physical port mask */ + 0x7FF, + + /* Combo Logical port ID */ + 7, + + /* HSG Logical port ID */ + EXT_PORT1, + + /* SGMII Logical portmask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Max Meter ID */ + 63, + + /* MAX LUT Address Number 4096 + 64*/ + 4160, + + /* Trunk Group Mask */ + 0x07 +}; +#endif + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8364B)) +static rtk_switch_halCtrl_t rtl8364b_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8364B, + + /* Logical to Physical */ + {0xFF, 1, 0xFF, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UNDEFINE_PORT, UTP_PORT1, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid CPU port mask */ + 0x00, + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 7, + + /* Physical port mask */ + 0xCA, + + /* Combo Logical port ID */ + 4, + + /* HSG Logical port ID */ + EXT_PORT0, + + /* SGMII Logical portmask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Max Meter ID */ + 32, + + /* MAX LUT Address Number */ + 2112, + + /* Trunk Group Mask */ + 0x01 +}; +#endif + +#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8363SC_VB)) +static rtk_switch_halCtrl_t rtl8363sc_vb_hal_Ctrl = +{ + /* Switch Chip */ + CHIP_RTL8363SC_VB, + + /* Logical to Physical */ + {0xFF, 0xFF, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + + /* Physical to Logical */ + {UNDEFINE_PORT, UTP_PORT2, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, + UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, + + /* Port Type */ + {UNKNOWN_PORT, UNKNOWN_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, + UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, + + /* PTP port */ + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }, + + /* Valid port mask */ + ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid UTP port mask */ + ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) ), + + /* Valid EXT port mask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Valid CPU port mask */ + 0x00, + + /* Minimum physical port number */ + 0, + + /* Maxmum physical port number */ + 7, + + /* Physical port mask */ + 0xCA, + + /* Combo Logical port ID */ + 4, + + /* HSG Logical port ID */ + EXT_PORT0, + + /* SGMII Logical portmask */ + ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), + + /* Max Meter ID */ + 32, + + /* MAX LUT Address Number */ + 2112, + + /* Trunk Group Mask */ + 0x01 +}; +#endif + +#if defined(FORCE_PROBE_RTL8367C) +static rtk_switch_halCtrl_t *halCtrl = &rtl8367c_hal_Ctrl; +#elif defined(FORCE_PROBE_RTL8370B) +static rtk_switch_halCtrl_t *halCtrl = &rtl8370b_hal_Ctrl; +#elif defined(FORCE_PROBE_RTL8364B) +static rtk_switch_halCtrl_t *halCtrl = &rtl8364b_hal_Ctrl; +#elif defined(FORCE_PROBE_RTL8363SC_VB) +static rtk_switch_halCtrl_t *halCtrl = &rtl8363sc_vb_hal_Ctrl; +#else +static rtk_switch_halCtrl_t *halCtrl = NULL; +#endif + +static rtk_uint32 PatchChipData[210][2] = +{ + {0xa436, 0x8028}, {0xa438, 0x6800}, {0xb82e, 0x0001}, {0xa436, 0xb820}, {0xa438, 0x0090}, {0xa436, 0xa012}, {0xa438, 0x0000}, {0xa436, 0xa014}, {0xa438, 0x2c04}, {0xa438, 0x2c6c}, + {0xa438, 0x2c75}, {0xa438, 0x2c77}, {0xa438, 0x1414}, {0xa438, 0x1579}, {0xa438, 0x1536}, {0xa438, 0xc432}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, + {0xa438, 0x614c}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x318c}, {0xa438, 0x42d6}, {0xa438, 0xd702}, {0xa438, 0x31ef}, {0xa438, 0x42d6}, {0xa438, 0x629c}, {0xa438, 0x2c04}, + {0xa438, 0x653c}, {0xa438, 0x422a}, {0xa438, 0x5d83}, {0xa438, 0xd06a}, {0xa438, 0xd1b0}, {0xa438, 0x1536}, {0xa438, 0xc43a}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, + {0xa438, 0x003e}, {0xa438, 0x314a}, {0xa438, 0x42fe}, {0xa438, 0x337b}, {0xa438, 0x02d6}, {0xa438, 0x3063}, {0xa438, 0x0c1b}, {0xa438, 0x22fe}, {0xa438, 0xc435}, {0xa438, 0xd0be}, + {0xa438, 0xd1f7}, {0xa438, 0xe0f0}, {0xa438, 0x1a40}, {0xa438, 0xa320}, {0xa438, 0xd702}, {0xa438, 0x154a}, {0xa438, 0xc434}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, + {0xa438, 0x003e}, {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x619f}, {0xa438, 0xd702}, {0xa438, 0x414f}, {0xa438, 0x2c2e}, {0xa438, 0x610a}, {0xa438, 0xd705}, + {0xa438, 0x5e1f}, {0xa438, 0xc43f}, {0xa438, 0xc88b}, {0xa438, 0xd702}, {0xa438, 0x7fe0}, {0xa438, 0x22f3}, {0xa438, 0xd0a0}, {0xa438, 0xd1b2}, {0xa438, 0xd0c3}, {0xa438, 0xd1c3}, + {0xa438, 0x8d01}, {0xa438, 0x1536}, {0xa438, 0xc438}, {0xa438, 0xe0f0}, {0xa438, 0x1a80}, {0xa438, 0xd706}, {0xa438, 0x60c0}, {0xa438, 0xd710}, {0xa438, 0x409e}, {0xa438, 0xa804}, + {0xa438, 0xad01}, {0xa438, 0x8804}, {0xa438, 0xd702}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, {0xa438, 0x405b}, {0xa438, 0x1576}, {0xa438, 0x7c9c}, + {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd702}, {0xa438, 0x5d43}, {0xa438, 0x31ef}, {0xa438, 0x02fe}, {0xa438, 0x22d6}, {0xa438, 0x590a}, {0xa438, 0xd706}, {0xa438, 0x5c80}, + {0xa438, 0xd702}, {0xa438, 0x5c44}, {0xa438, 0x3063}, {0xa438, 0x02d6}, {0xa438, 0x5be2}, {0xa438, 0x22fb}, {0xa438, 0xa240}, {0xa438, 0xa104}, {0xa438, 0x8c03}, {0xa438, 0x8178}, + {0xa438, 0xd701}, {0xa438, 0x31ad}, {0xa438, 0x4917}, {0xa438, 0x8102}, {0xa438, 0x2917}, {0xa438, 0xc302}, {0xa438, 0x268a}, {0xa436, 0xA01A}, {0xa438, 0x0000}, {0xa436, 0xA006}, + {0xa438, 0x0fff}, {0xa436, 0xA004}, {0xa438, 0x0689}, {0xa436, 0xA002}, {0xa438, 0x0911}, {0xa436, 0xA000}, {0xa438, 0x7302}, {0xa436, 0xB820}, {0xa438, 0x0010}, {0xa436, 0x8412}, + {0xa438, 0xaf84}, {0xa438, 0x1eaf}, {0xa438, 0x8427}, {0xa438, 0xaf84}, {0xa438, 0x27af}, {0xa438, 0x8427}, {0xa438, 0x0251}, {0xa438, 0x6802}, {0xa438, 0x8427}, {0xa438, 0xaf04}, + {0xa438, 0x0af8}, {0xa438, 0xf9bf}, {0xa438, 0x5581}, {0xa438, 0x0255}, {0xa438, 0x27ef}, {0xa438, 0x310d}, {0xa438, 0x345b}, {0xa438, 0x0fa3}, {0xa438, 0x032a}, {0xa438, 0xe087}, + {0xa438, 0xffac}, {0xa438, 0x2040}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x5527}, {0xa438, 0xef31}, {0xa438, 0xef20}, {0xa438, 0xe787}, {0xa438, 0xfee6}, {0xa438, 0x87fd}, + {0xa438, 0xd488}, {0xa438, 0x88bf}, {0xa438, 0x5674}, {0xa438, 0x0254}, {0xa438, 0xe3e0}, {0xa438, 0x87ff}, {0xa438, 0xf720}, {0xa438, 0xe487}, {0xa438, 0xffaf}, {0xa438, 0x847e}, + {0xa438, 0xe087}, {0xa438, 0xffad}, {0xa438, 0x2016}, {0xa438, 0xe387}, {0xa438, 0xfee2}, {0xa438, 0x87fd}, {0xa438, 0xef45}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x54e3}, + {0xa438, 0xe087}, {0xa438, 0xfff6}, {0xa438, 0x20e4}, {0xa438, 0x87ff}, {0xa438, 0xfdfc}, {0xa438, 0x0400}, {0xa436, 0xb818}, {0xa438, 0x0407}, {0xa436, 0xb81a}, {0xa438, 0xfffd}, + {0xa436, 0xb81c}, {0xa438, 0xfffd}, {0xa436, 0xb81e}, {0xa438, 0xfffd}, {0xa436, 0xb832}, {0xa438, 0x0001}, {0xb820, 0x0000}, {0xb82e, 0x0000}, {0xa436, 0x8028}, {0xa438, 0x0000} +}; + +static rtk_api_ret_t _rtk_switch_init_8367c(void) +{ + rtk_port_t port; + rtk_uint32 retVal; + rtk_uint32 regData; + rtk_uint32 regValue; + + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) + return retVal; + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA428, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0200); + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA428, regData)) != RT_ERR_OK) + return retVal; + + if((regValue & 0x00F0) == 0x00A0) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA5D0, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= 0x0006; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA5D0, regData)) != RT_ERR_OK) + return retVal; + } + } + } + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_UTP_FIB_DET, 0x15BB)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1303, 0x06D6)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1304, 0x0700)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13E2, 0x003F)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13F9, 0x0090)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x121e, 0x03CA)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1233, 0x0352)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1237, 0x00a0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x123a, 0x0030)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1239, 0x0084)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x0301, 0x1000)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1349, 0x001F)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x18e0, 0, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x122b, 14, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1305, 0xC000, 3)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_switch_init_8370b(void) +{ + ret_t retVal; + rtk_uint32 regData, tmp = 0; + rtk_uint32 i, prf, counter; + rtk_uint32 long_link[8] = {0x0210, 0x03e8, 0x0218, 0x03f0, 0x0220, 0x03f8, 0x0208, 0x03e0 }; + + if((retVal = rtl8367c_setAsicRegBits(0x1205, 0x0300, 3)) != RT_ERR_OK) + return retVal; + + + for(i=0; i<8; i++) + { + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa420, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x7 ; + if(tmp == 0x3) + { + prf = 1; + if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6fa9)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xa9)) != RT_ERR_OK) + return retVal; + for(counter = 0; counter < 10000; counter++); //delay + + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData | 0x10; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) + return retVal; + for(counter = 0; counter < 10000; counter++); //delay + counter = 0; + do{ + counter = counter + 1; + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x40; + if(tmp != 0) + break; + } while (counter < 20); //Wait for patch ready = 1... + } + } + if ((retVal = rtl8367c_getAsicReg(0x1d01, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData; + tmp = tmp | 0x3BE0; /*Broadcast port enable*/ + tmp = tmp & 0xFFE0; /*Phy_id = 0 */ + if((retVal = rtl8367c_setAsicReg(0x1d01, tmp)) != RT_ERR_OK) + return retVal; + + for(i=0;i < 210; i++) + { + if((retVal = rtl8367c_setAsicPHYOCPReg(0, PatchChipData[i][0], PatchChipData[i][1])) != RT_ERR_OK) + return retVal; + } + + if((retVal = rtl8367c_setAsicReg(0x1d01, regData)) != RT_ERR_OK) + return retVal; + + for(i=0; i < 8; i++) + { + if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa4b4, long_link[i])) != RT_ERR_OK) + return retVal; + } + + if (prf == 0x1) + { + for(i=0; i<8; i++) + { + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0xFFEF; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) + return retVal; + + for(counter = 0; counter < 10000; counter++); //delay + + counter = 0; + do{ + counter = counter + 1; + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x40; + if( tmp == 0 ) + break; + } while (counter < 20); //Wait for patch ready = 1... + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6f48)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xfa)) != RT_ERR_OK) + return retVal; + } + } + + /*Check phy link status*/ + for(i=0; i<8; i++) + { + if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa400, ®Data)) != RT_ERR_OK) + return retVal; + tmp = regData & 0x800; + if(tmp == 0x0) + { + tmp = regData | 0x200; + if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa400, tmp)) != RT_ERR_OK) + return retVal; + } + } + + for(counter = 0; counter < 10000; counter++); //delay + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_switch_init_8364b(void) +{ + ret_t retVal; + rtk_uint32 regData; + + /*enable EEE, include mac & phy*/ + + if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + + /*PAD para*/ + + /*EXT1 PAD Para*/ + if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFFFFFFE; + regData |= 0x250; + if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) + return retVal; + + /*EXT2 PAD Para*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) + return retVal; + + + /*SDS PATCH*/ + /*SP_CFG_EN_LINK_FIB1G*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x4; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) + return retVal; + + /*FIB100 Down-speed*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x20; + if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +static rtk_api_ret_t _rtk_switch_init_8363sc_vb(void) +{ + + ret_t retVal; + rtk_uint32 regData; + + /*enable EEE, include mac & phy*/ + + if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) + return retVal; + + /*PAD para*/ + + /*EXT1 PAD Para*/ + if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFFFFFFE; + regData |= 0x250; + if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) + return retVal; + + /*EXT2 PAD Para*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) + return retVal; + + + /*SDS PATCH*/ + /*SP_CFG_EN_LINK_FIB1G*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x4; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) + return retVal; + + /*FIB100 Down-speed*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) + return retVal; + regData |= 0x20; + if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_probe + * Description: + * Probe switch + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Switch probed + * RT_ERR_FAILED - Switch Unprobed. + * Note: + * + */ +rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip) +{ +#if defined(FORCE_PROBE_RTL8367C) + + *pSwitchChip = CHIP_RTL8367C; + halCtrl = &rtl8367c_hal_Ctrl; + +#elif defined(FORCE_PROBE_RTL8370B) + + *pSwitchChip = CHIP_RTL8370B; + halCtrl = &rtl8370b_hal_Ctrl; + +#elif defined(FORCE_PROBE_RTL8364B) + + *pSwitchChip = CHIP_RTL8364B; + halCtrl = &rtl8364b_hal_Ctrl; + +#elif defined(FORCE_PROBE_RTL8363SC_VB) + + *pSwitchChip = CHIP_RTL8363SC_VB; + halCtrl = &rtl8363sc_vb_hal_Ctrl; + +#else + rtk_uint32 retVal; + rtk_uint32 data, regValue; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (data) + { + case 0x0276: + case 0x0597: + case 0x6367: + *pSwitchChip = CHIP_RTL8367C; + halCtrl = &rtl8367c_hal_Ctrl; + break; + case 0x0652: + case 0x6368: + *pSwitchChip = CHIP_RTL8370B; + halCtrl = &rtl8370b_hal_Ctrl; + break; + case 0x0801: + case 0x6511: + if( (regValue & 0x00F0) == 0x0080) + { + *pSwitchChip = CHIP_RTL8363SC_VB; + halCtrl = &rtl8363sc_vb_hal_Ctrl; + } + else + { + *pSwitchChip = CHIP_RTL8364B; + halCtrl = &rtl8364b_hal_Ctrl; + } + break; + default: + return RT_ERR_FAILED; + } +#endif + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_initialState_set + * Description: + * Set initial status + * Input: + * state - Initial state; + * Output: + * None + * Return: + * RT_ERR_OK - Initialized + * RT_ERR_FAILED - Uninitialized + * Note: + * + */ +rtk_api_ret_t rtk_switch_initialState_set(init_state_t state) +{ + if(state >= INIT_STATE_END) + return RT_ERR_FAILED; + + init_state = state; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_initialState_get + * Description: + * Get initial status + * Input: + * None + * Output: + * None + * Return: + * INIT_COMPLETED - Initialized + * INIT_NOT_COMPLETED - Uninitialized + * Note: + * + */ +init_state_t rtk_switch_initialState_get(void) +{ + return init_state; +} + +/* Function Name: + * rtk_switch_logicalPortCheck + * Description: + * Check logical port ID. + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is correct + * RT_ERR_FAILED - Port ID is not correct + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->l2p_port[logicalPort] == 0xFF) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_isUtpPort + * Description: + * Check is logical port a UTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a UTP port + * RT_ERR_FAILED - Port ID is not a UTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->log_port_type[logicalPort] == UTP_PORT) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isExtPort + * Description: + * Check is logical port a Extension port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a EXT port + * RT_ERR_FAILED - Port ID is not a EXT port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->log_port_type[logicalPort] == EXT_PORT) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + + +/* Function Name: + * rtk_switch_isHsgPort + * Description: + * Check is logical port a HSG port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a HSG port + * RT_ERR_FAILED - Port ID is not a HSG port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(logicalPort == halCtrl->hsg_logical_port) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isSgmiiPort + * Description: + * Check is logical port a SGMII port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a SGMII port + * RT_ERR_FAILED - Port ID is not a SGMII port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if( ((0x01 << logicalPort) & halCtrl->sg_logical_portmask) != 0) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isCPUPort + * Description: + * Check is logical port a CPU port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a CPU port + * RT_ERR_FAILED - Port ID is not a CPU port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if( ((0x01 << logicalPort) & halCtrl->valid_cpu_portmask) != 0) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_isComboPort + * Description: + * Check is logical port a Combo port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a combo port + * RT_ERR_FAILED - Port ID is not a combo port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->combo_logical_port == logicalPort) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_ComboPort_get + * Description: + * Get Combo port ID + * Input: + * None + * Output: + * None + * Return: + * Port ID of combo port + * Note: + * + */ +rtk_uint32 rtk_switch_ComboPort_get(void) +{ + return halCtrl->combo_logical_port; +} + +/* Function Name: + * rtk_switch_isPtpPort + * Description: + * Check is logical port a PTP port + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * RT_ERR_OK - Port ID is a PTP port + * RT_ERR_FAILED - Port ID is not a PTP port + * RT_ERR_NOT_INIT - Not Initialize + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return RT_ERR_FAILED; + + if(halCtrl->ptp_port[logicalPort] == 1) + return RT_ERR_OK; + else + return RT_ERR_FAILED; +} + +/* Function Name: + * rtk_switch_port_L2P_get + * Description: + * Get physical port ID + * Input: + * logicalPort - logical port ID + * Output: + * None + * Return: + * Physical port ID + * Note: + * + */ +rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort) +{ + if(init_state != INIT_COMPLETED) + return UNDEFINE_PHY_PORT; + + if(logicalPort >= RTK_SWITCH_PORT_NUM) + return UNDEFINE_PHY_PORT; + + return (halCtrl->l2p_port[logicalPort]); +} + +/* Function Name: + * rtk_switch_port_P2L_get + * Description: + * Get logical port ID + * Input: + * physicalPort - physical port ID + * Output: + * None + * Return: + * logical port ID + * Note: + * + */ +rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort) +{ + if(init_state != INIT_COMPLETED) + return UNDEFINE_PORT; + + if(physicalPort >= RTK_SWITCH_PORT_NUM) + return UNDEFINE_PORT; + + return (halCtrl->p2l_port[physicalPort]); +} + +/* Function Name: + * rtk_switch_isPortMaskValid + * Description: + * Check portmask is valid or not + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - port mask is valid + * RT_ERR_FAILED - port mask is not valid + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pPmask) + return RT_ERR_NULL_POINTER; + + if( (pPmask->bits[0] | halCtrl->valid_portmask) != halCtrl->valid_portmask ) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_isPortMaskUtp + * Description: + * Check all ports in portmask are only UTP port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only UTP port in port mask + * RT_ERR_FAILED - Not only UTP port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pPmask) + return RT_ERR_NULL_POINTER; + + if( (pPmask->bits[0] | halCtrl->valid_utp_portmask) != halCtrl->valid_utp_portmask ) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_isPortMaskExt + * Description: + * Check all ports in portmask are only EXT port + * Input: + * pPmask - logical port mask + * Output: + * None + * Return: + * RT_ERR_OK - Only EXT port in port mask + * RT_ERR_FAILED - Not only EXT port in port mask + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pPmask) + return RT_ERR_NULL_POINTER; + + if( (pPmask->bits[0] | halCtrl->valid_ext_portmask) != halCtrl->valid_ext_portmask ) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portmask_L2P_get + * Description: + * Get physicl portmask from logical portmask + * Input: + * pLogicalPmask - logical port mask + * Output: + * pPhysicalPortmask - physical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask) +{ + rtk_uint32 log_port, phy_port; + + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pLogicalPmask) + return RT_ERR_NULL_POINTER; + + if(NULL == pPhysicalPortmask) + return RT_ERR_NULL_POINTER; + + if(rtk_switch_isPortMaskValid(pLogicalPmask) != RT_ERR_OK) + return RT_ERR_PORT_MASK; + + /* reset physical port mask */ + *pPhysicalPortmask = 0; + + RTK_PORTMASK_SCAN((*pLogicalPmask), log_port) + { + phy_port = rtk_switch_port_L2P_get((rtk_port_t)log_port); + *pPhysicalPortmask |= (0x0001 << phy_port); + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portmask_P2L_get + * Description: + * Get logical portmask from physical portmask + * Input: + * physicalPortmask - physical port mask + * Output: + * pLogicalPmask - logical port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * RT_ERR_PORT_MASK - Error port mask + * Note: + * + */ +rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask) +{ + rtk_uint32 log_port, phy_port; + + if(init_state != INIT_COMPLETED) + return RT_ERR_NOT_INIT; + + if(NULL == pLogicalPmask) + return RT_ERR_NULL_POINTER; + + RTK_PORTMASK_CLEAR(*pLogicalPmask); + + for(phy_port = halCtrl->min_phy_port; phy_port <= halCtrl->max_phy_port; phy_port++) + { + if(physicalPortmask & (0x0001 << phy_port)) + { + log_port = rtk_switch_port_P2L_get(phy_port); + if(log_port != UNDEFINE_PORT) + { + RTK_PORTMASK_PORT_SET(*pLogicalPmask, log_port); + } + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_phyPortMask_get + * Description: + * Get physical portmask + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Physical port mask + * Note: + * + */ +rtk_uint32 rtk_switch_phyPortMask_get(void) +{ + if(init_state != INIT_COMPLETED) + return 0x00; /* No port in portmask */ + + return (halCtrl->phy_portmask); +} + +/* Function Name: + * rtk_switch_logPortMask_get + * Description: + * Get Logical portmask + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_NOT_INIT - Not Initialize + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_switch_logPortMask_get(rtk_portmask_t *pPortmask) +{ + if(init_state != INIT_COMPLETED) + return RT_ERR_FAILED; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + pPortmask->bits[0] = halCtrl->valid_portmask; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_init + * Description: + * Set chip to default configuration enviroment + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can set chip registers to default configuration for different release chip model. + */ +rtk_api_ret_t rtk_switch_init(void) +{ + rtk_uint32 retVal; + rtl8367c_rma_t rmaCfg; + switch_chip_t switchChip; + + /* probe switch */ + if((retVal = rtk_switch_probe(&switchChip)) != RT_ERR_OK) + return retVal; + + /* Set initial state */ + + if((retVal = rtk_switch_initialState_set(INIT_COMPLETED)) != RT_ERR_OK) + return retVal; + + /* Initial */ + switch(switchChip) + { + case CHIP_RTL8367C: + if((retVal = _rtk_switch_init_8367c()) != RT_ERR_OK) + return retVal; + break; + case CHIP_RTL8370B: + if((retVal = _rtk_switch_init_8370b()) != RT_ERR_OK) + return retVal; + break; + case CHIP_RTL8364B: + if((retVal = _rtk_switch_init_8364b()) != RT_ERR_OK) + return retVal; + break; + case CHIP_RTL8363SC_VB: + if((retVal = _rtk_switch_init_8363sc_vb()) != RT_ERR_OK) + return retVal; + break; + default: + return RT_ERR_CHIP_NOT_FOUND; + } + + /* Set Old max packet length to 16K */ + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LENGTH_LIMINT_IPG, RTL8367C_MAX_LENTH_CTRL_MASK, 3)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX, RTL8367C_MAX_LEN_RX_TX_MASK, 3)) != RT_ERR_OK) + return retVal; + + /* ACL Mode */ + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_ACCESS_MODE, RTL8367C_ACL_ACCESS_MODE_MASK, 1)) != RT_ERR_OK) + return retVal; + + /* Max rate */ + if((retVal = rtk_rate_igrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, DISABLED, ENABLED)) != RT_ERR_OK) + return retVal; + + if((retVal = rtk_rate_egrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, ENABLED)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x03fa, 0x0007)) != RT_ERR_OK) + return retVal; + + /* Change unknown DA to per port setting */ + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK, 3)) != RT_ERR_OK) + return retVal; + + /* LUT lookup OP = 1 */ + if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) + return retVal; + + /* Set RMA */ + rmaCfg.portiso_leaky = 0; + rmaCfg.vlan_leaky = 0; + rmaCfg.keep_format = 0; + rmaCfg.trap_priority = 0; + rmaCfg.discard_storm_filter = 0; + rmaCfg.operation = 0; + if ((retVal = rtl8367c_setAsicRma(2, &rmaCfg))!=RT_ERR_OK) + return retVal; + + /* Enable TX Mirror isolation leaky */ + if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(ENABLED)) != RT_ERR_OK) + return retVal; + + /* INT EN */ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IO_MISC_FUNC, RTL8367C_INT_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portMaxPktLen_set + * Description: + * Set Max packet length + * Input: + * port - Port ID + * speed - Speed + * cfgId - Configuration ID + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(speed >= MAXPKTLEN_LINK_SPEED_END) + return RT_ERR_INPUT; + + if(cfgId > MAXPKTLEN_CFG_ID_MAX) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, cfgId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_portMaxPktLen_get + * Description: + * Get Max packet length + * Input: + * port - Port ID + * speed - Speed + * Output: + * pCfgId - Configuration ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(speed >= MAXPKTLEN_LINK_SPEED_END) + return RT_ERR_INPUT; + + if(NULL == pCfgId) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, pCfgId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_maxPktLenCfg_set + * Description: + * Set Max packet length configuration + * Input: + * cfgId - Configuration ID + * pktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(cfgId > MAXPKTLEN_CFG_ID_MAX) + return RT_ERR_INPUT; + + if(pktLen > RTK_SWITCH_MAX_PKTLEN) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicMaxLengthCfg(cfgId, pktLen)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_maxPktLenCfg_get + * Description: + * Get Max packet length configuration + * Input: + * cfgId - Configuration ID + * pPktLen - Max packet length + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + */ +rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(cfgId > MAXPKTLEN_CFG_ID_MAX) + return RT_ERR_INPUT; + + if(NULL == pPktLen) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMaxLengthCfg(cfgId, pPktLen)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_greenEthernet_set + * Description: + * Set all Ports Green Ethernet state. + * Input: + * enable - Green Ethernet state. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * This API can set all Ports Green Ethernet state. + * The configuration is as following: + * - DISABLE + * - ENABLE + */ +rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtl8367c_setAsicPowerSaving(rtk_switch_port_L2P_get(port),enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicGreenEthernet(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_greenEthernet_get + * Description: + * Get all Ports Green Ethernet state. + * Input: + * None + * Output: + * pEnable - Green Ethernet state. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API can get Green Ethernet state. + */ +rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 port; + rtk_uint32 state; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + RTK_SCAN_ALL_LOG_PORT(port) + { + if(rtk_switch_isUtpPort(port) == RT_ERR_OK) + { + if ((retVal = rtl8367c_getAsicPowerSaving(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) + return retVal; + + if(state == DISABLED) + { + *pEnable = DISABLED; + return RT_ERR_OK; + } + + if ((retVal = rtl8367c_getAsicGreenEthernet(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) + return retVal; + + if(state == DISABLED) + { + *pEnable = DISABLED; + return RT_ERR_OK; + } + } + } + + *pEnable = ENABLED; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_switch_maxLogicalPort_get + * Description: + * Get Max logical port ID + * Input: + * None + * Output: + * None + * Return: + * Max logical port + * Note: + * This API can get max logical port + */ +rtk_port_t rtk_switch_maxLogicalPort_get(void) +{ + rtk_port_t port, maxLogicalPort = 0; + + /* Check initialization state */ + if(rtk_switch_initialState_get() != INIT_COMPLETED) + { + return UNDEFINE_PORT; + } + + for(port = 0; port < RTK_SWITCH_PORT_NUM; port++) + { + if( (halCtrl->log_port_type[port] == UTP_PORT) || (halCtrl->log_port_type[port] == EXT_PORT) ) + maxLogicalPort = port; + } + + return maxLogicalPort; +} + +/* Function Name: + * rtk_switch_maxMeterId_get + * Description: + * Get Max Meter ID + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max Meter ID + * Note: + * + */ +rtk_uint32 rtk_switch_maxMeterId_get(void) +{ + if(init_state != INIT_COMPLETED) + return 0x00; + + return (halCtrl->max_meter_id); +} + +/* Function Name: + * rtk_switch_maxLutAddrNumber_get + * Description: + * Get Max LUT Address number + * Input: + * None + * Output: + * None + * Return: + * 0x00 - Not Initialize + * Other value - Max LUT Address number + * Note: + * + */ +rtk_uint32 rtk_switch_maxLutAddrNumber_get(void) +{ + if(init_state != INIT_COMPLETED) + return 0x00; + + return (halCtrl->max_lut_addr_num); +} + +/* Function Name: + * rtk_switch_isValidTrunkGrpId + * Description: + * Check if trunk group is valid or not + * Input: + * grpId - Group ID + * Output: + * None + * Return: + * RT_ERR_OK - Trunk Group ID is valid + * RT_ERR_LA_TRUNK_ID - Trunk Group ID is not valid + * Note: + * + */ +rtk_uint32 rtk_switch_isValidTrunkGrpId(rtk_uint32 grpId) +{ + if(init_state != INIT_COMPLETED) + return 0x00; + + if( (halCtrl->trunk_group_mask & (0x01 << grpId) ) != 0) + return RT_ERR_OK; + else + return RT_ERR_LA_TRUNK_ID; + +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c new file mode 100755 index 00000000..7858edcf --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c @@ -0,0 +1,639 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : + * + */ + +#include + +#if defined(RTK_X86_ASICDRV) +#include +#else +#include +#endif + +/*for driver verify testing only*/ +#ifdef CONFIG_RTL8367C_ASICDRV_TEST +#define CLE_VIRTUAL_REG_SIZE 0x10000 +rtk_uint16 CleVirtualReg[CLE_VIRTUAL_REG_SIZE]; +#endif + +#if defined(CONFIG_RTL865X_CLE) || defined (RTK_X86_CLE) +rtk_uint32 cleDebuggingDisplay; +#endif + +#ifdef EMBEDDED_SUPPORT +extern void setReg(rtk_uint16, rtk_uint16); +extern rtk_uint16 getReg(rtk_uint16); +#endif + +/* Function Name: + * rtl8367c_setAsicRegBit + * Description: + * Set a bit value of a specified register + * Input: + * reg - register's address + * bit - bit location + * value - value to set. It can be value 0 or 1. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Set a bit of a specified register to 1 or 0. + */ +ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value) +{ + +#if defined(RTK_X86_ASICDRV) + rtk_uint32 regData; + ret_t retVal; + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + + if(value) + regData = regData | (1 << bit); + else + regData = regData & (~(1 << bit)); + + retVal = Access_Write(reg,2, regData); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + else if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + if(value) + { + CleVirtualReg[reg] = CleVirtualReg[reg] | (1 << bit); + } + else + { + CleVirtualReg[reg] = CleVirtualReg[reg] & (~(1 << bit)); + } + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint16 tmp; + + if(reg > RTL8367C_REGDATAMAX || value > 1) + return RT_ERR_INPUT; + + tmp = getReg(reg); + tmp &= (1 << bitIdx); + tmp |= (value << bitIdx); + setReg(reg, tmp); + +#else + rtk_uint32 regData; + ret_t retVal; + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + if(value) + regData = regData | (1 << bit); + else + regData = regData & (~(1 << bit)); + + retVal = smi_write(reg, regData); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicRegBit + * Description: + * Get a bit value of a specified register + * Input: + * reg - register's address + * bit - bit location + * value - value to get. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + *pValue = (regData & (0x1 << bit)) >> bit; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + + if(bit >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + *pValue = (CleVirtualReg[reg] & (0x1 << bit)) >> bit; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint16 tmp; + + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + tmp = getReg(reg); + tmp = tmp >> bitIdx; + tmp &= 1; + *value = tmp; +#else + rtk_uint32 regData; + ret_t retVal; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + + *pValue = (regData & (0x1 << bit)) >> bit; + +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicRegBits + * Description: + * Set bits value of a specified register + * Input: + * reg - register's address + * bits - bits mask for setting + * value - bits value for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Set bits of a specified register to value. Both bits and value are be treated as bit-mask + */ +ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + valueShifted = value << bitsShift; + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + + regData = regData & (~bits); + regData = regData | (valueShifted & bits); + + retVal = Access_Write(reg,2, regData); + if(TRUE != retVal) + return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + rtk_uint32 regData; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + valueShifted = value << bitsShift; + + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + regData = CleVirtualReg[reg] & (~bits); + regData = regData | (valueShifted & bits); + + CleVirtualReg[reg] = regData; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint32 regData; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + valueShifted = value << bitsShift; + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + regData = getReg(reg); + regData = regData & (~bits); + regData = regData | (valueShifted & bits); + + setReg(reg, regData); + +#else + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + rtk_uint32 valueShifted; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + valueShifted = value << bitsShift; + + if(valueShifted > RTL8367C_REGDATAMAX) + return RT_ERR_INPUT; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + + regData = regData & (~bits); + regData = regData | (valueShifted & bits); + + retVal = smi_write(reg, regData); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicRegBits + * Description: + * Get bits value of a specified register + * Input: + * reg - register's address + * bits - bits mask for setting + * value - bits value for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + *pValue = (regData & bits) >> bitsShift; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + rtk_uint32 bitsShift; + + if(bits >= (1 << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1 << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + *pValue = (CleVirtualReg[reg] & bits) >> bitsShift; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + rtk_uint32 regData; + rtk_uint32 bitsShift; + + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + if(bits >= (1UL << RTL8367C_REGBITLENGTH) ) + return RT_ERR_INPUT; + + bitsShift = 0; + while(!(bits & (1UL << bitsShift))) + { + bitsShift++; + if(bitsShift >= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + regData = getReg(reg); + *value = (regData & bits) >> bitsShift; + +#else + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 bitsShift; + + if(bits>= (1<= RTL8367C_REGBITLENGTH) + return RT_ERR_INPUT; + } + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) return RT_ERR_SMI; + + *pValue = (regData & bits) >> bitsShift; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n",reg, regData); + #endif + +#endif + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicReg + * Description: + * Set content of asic register + * Input: + * reg - register's address + * value - Value setting to register + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * The value will be set to ASIC mapping address only and it is always return RT_ERR_OK while setting un-mapping address registers + */ +ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value) +{ +#if defined(RTK_X86_ASICDRV)/*RTK-CNSD2-NickWu-20061222: for x86 compile*/ + + ret_t retVal; + + retVal = Access_Write(reg,2,value); + if(TRUE != retVal) return RT_ERR_SMI; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + + /*MIBs emulating*/ + if(reg == RTL8367C_REG_MIB_ADDRESS) + { + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG] = 0x1; + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+1] = 0x2; + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+2] = 0x3; + CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+3] = 0x4; + } + + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + CleVirtualReg[reg] = value; + + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n",reg,CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + if(reg > RTL8367C_REGDATAMAX || value > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + setReg(reg, value); + +#else + ret_t retVal; + + retVal = smi_write(reg, value); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); + #endif + +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicReg + * Description: + * Get content of asic register + * Input: + * reg - register's address + * value - Value setting to register + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * Value 0x0000 will be returned for ASIC un-mapping address + */ +ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue) +{ + +#if defined(RTK_X86_ASICDRV) + + rtk_uint32 regData; + ret_t retVal; + + retVal = Access_Read(reg, 2, ®Data); + if(TRUE != retVal) + return RT_ERR_SMI; + + *pValue = regData; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + +#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) + if(reg >= CLE_VIRTUAL_REG_SIZE) + return RT_ERR_OUT_OF_RANGE; + + *pValue = CleVirtualReg[reg]; + + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); + +#elif defined(EMBEDDED_SUPPORT) + if(reg > RTL8367C_REGDATAMAX ) + return RT_ERR_INPUT; + + *value = getReg(reg); + +#else + rtk_uint32 regData; + ret_t retVal; + + retVal = smi_read(reg, ®Data); + if(retVal != RT_ERR_OK) + return RT_ERR_SMI; + + *pValue = regData; + #ifdef CONFIG_RTL865X_CLE + if(0x8367B == cleDebuggingDisplay) + PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); + #endif + +#endif + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c new file mode 100755 index 00000000..d9ccd971 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c @@ -0,0 +1,1173 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : ACL related function drivers + * + */ +#include + +#include + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) +rtl8367c_aclrulesmi Rtl8370sVirtualAclRuleTable[RTL8367C_ACLRULENO]; +rtk_uint16 Rtl8370sVirtualAclActTable[RTL8367C_ACLRULENO][RTL8367C_ACL_ACT_TABLE_LEN]; +#endif + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclRuleStSmi2User( rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) +{ + rtk_uint8 *care_ptr, *data_ptr; + rtk_uint8 care_tmp, data_tmp; + rtk_uint32 i; + + pAclUser->data_bits.active_portmsk = (((pAclSmi->data_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->data_bits.rule_info >> 8) & 0x00FF); + pAclUser->data_bits.type = (pAclSmi->data_bits.rule_info & 0x0007); + pAclUser->data_bits.tag_exist = (pAclSmi->data_bits.rule_info & 0x00F8) >> 3; + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits; + + for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) + { + care_tmp = *(care_ptr + i) ^ (*(data_ptr + i)); + data_tmp = *(data_ptr + i); + + *(care_ptr + i) = care_tmp; + *(data_ptr + i) = data_tmp; + } + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; + care_tmp = (*care_ptr) ^ (*data_ptr); + data_tmp = (*data_ptr); + *care_ptr = care_tmp; + *data_ptr = data_tmp; + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + pAclUser->data_bits.field[i] = pAclSmi->data_bits.field[i]; + + pAclUser->valid = pAclSmi->valid; + + pAclUser->care_bits.active_portmsk = (((pAclSmi->care_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->care_bits.rule_info >> 8) & 0x00FF); + pAclUser->care_bits.type = (pAclSmi->care_bits.rule_info & 0x0007); + pAclUser->care_bits.tag_exist = (pAclSmi->care_bits.rule_info & 0x00F8) >> 3; + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + pAclUser->care_bits.field[i] = pAclSmi->care_bits.field[i]; +} + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclRuleStUser2Smi(rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) +{ + rtk_uint8 *care_ptr, *data_ptr; + rtk_uint8 care_tmp, data_tmp; + rtk_uint32 i; + + pAclSmi->data_bits_ext.rule_info = ((pAclUser->data_bits.active_portmsk >> 8) & 0x7) << 1; + pAclSmi->data_bits.rule_info = ((pAclUser->data_bits.active_portmsk & 0xff) << 8) | ((pAclUser->data_bits.tag_exist & 0x1F) << 3) | (pAclUser->data_bits.type & 0x07); + + for(i = 0;i < RTL8367C_ACLRULEFIELDNO; i++) + pAclSmi->data_bits.field[i] = pAclUser->data_bits.field[i]; + + pAclSmi->valid = pAclUser->valid; + + pAclSmi->care_bits_ext.rule_info = ((pAclUser->care_bits.active_portmsk >> 8) & 0x7) << 1; + pAclSmi->care_bits.rule_info = ((pAclUser->care_bits.active_portmsk & 0xff) << 8) | ((pAclUser->care_bits.tag_exist & 0x1F) << 3) | (pAclUser->care_bits.type & 0x07); + + for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) + pAclSmi->care_bits.field[i] = pAclUser->care_bits.field[i]; + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits; + + for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) + { + care_tmp = *(care_ptr + i) & ~(*(data_ptr + i)); + data_tmp = *(care_ptr + i) & *(data_ptr + i); + + *(care_ptr + i) = care_tmp; + *(data_ptr + i) = data_tmp; + } + + care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; + data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; + care_tmp = *care_ptr & ~(*data_ptr); + data_tmp = *care_ptr & *data_ptr; + + *care_ptr = care_tmp; + *data_ptr = data_tmp; +} + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclActStSmi2User(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) +{ + pAclUser->cact = (pAclSmi[0] & 0x00C0) >> 6; + pAclUser->cvidx_cact = (pAclSmi[0] & 0x003F) | (((pAclSmi[3] & 0x0008) >> 3) << 6); + + pAclUser->sact = (pAclSmi[0] & 0xC000) >> 14; + pAclUser->svidx_sact = ((pAclSmi[0] & 0x3F00) >> 8) | (((pAclSmi[3] & 0x0010) >> 4) << 6); + + pAclUser->aclmeteridx = (pAclSmi[1] & 0x003F) | (((pAclSmi[3] & 0x0020) >> 5) << 6); + + pAclUser->fwdact = (pAclSmi[1] & 0xC000) >> 14; + pAclUser->fwdpmask = ((pAclSmi[1] & 0x3FC0) >> 6) | (((pAclSmi[3] & 0x01C0) >> 6) << 8); + + pAclUser->priact = (pAclSmi[2] & 0x00C0) >> 6; + pAclUser->pridx = (pAclSmi[2] & 0x003F) | (((pAclSmi[3] & 0x0200) >> 9) << 6); + + pAclUser->aclint = (pAclSmi[2] & 0x2000) >> 13; + pAclUser->gpio_en = (pAclSmi[2] & 0x1000) >> 12; + pAclUser->gpio_pin = (pAclSmi[2] & 0x0F00) >> 8; + + pAclUser->cact_ext = (pAclSmi[2] & 0xC000) >> 14; + pAclUser->tag_fmt = (pAclSmi[3] & 0x0003); + pAclUser->fwdact_ext = (pAclSmi[3] & 0x0004) >> 2; +} + +/* + Exchange structure type define with MMI and SMI +*/ +static void _rtl8367c_aclActStUser2Smi(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) +{ + pAclSmi[0] |= (pAclUser->cvidx_cact & 0x003F); + pAclSmi[0] |= (pAclUser->cact & 0x0003) << 6; + pAclSmi[0] |= (pAclUser->svidx_sact & 0x003F) << 8; + pAclSmi[0] |= (pAclUser->sact & 0x0003) << 14; + + pAclSmi[1] |= (pAclUser->aclmeteridx & 0x003F); + pAclSmi[1] |= (pAclUser->fwdpmask & 0x00FF) << 6; + pAclSmi[1] |= (pAclUser->fwdact & 0x0003) << 14; + + pAclSmi[2] |= (pAclUser->pridx & 0x003F); + pAclSmi[2] |= (pAclUser->priact & 0x0003) << 6; + pAclSmi[2] |= (pAclUser->gpio_pin & 0x000F) << 8; + pAclSmi[2] |= (pAclUser->gpio_en & 0x0001) << 12; + pAclSmi[2] |= (pAclUser->aclint & 0x0001) << 13; + pAclSmi[2] |= (pAclUser->cact_ext & 0x0003) << 14; + + pAclSmi[3] |= (pAclUser->tag_fmt & 0x0003); + pAclSmi[3] |= (pAclUser->fwdact_ext & 0x0001) << 2; + pAclSmi[3] |= ((pAclUser->cvidx_cact & 0x0040) >> 6) << 3; + pAclSmi[3] |= ((pAclUser->svidx_sact & 0x0040) >> 6) << 4; + pAclSmi[3] |= ((pAclUser->aclmeteridx & 0x0040) >> 6) << 5; + pAclSmi[3] |= ((pAclUser->fwdpmask & 0x0700) >> 8) << 6; + pAclSmi[3] |= ((pAclUser->pridx & 0x0040) >> 6) << 9; +} + +/* Function Name: + * rtl8367c_setAsicAcl + * Description: + * Set port acl function enable/disable + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicAcl + * Description: + * Get port acl function enable/disable + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicAclUnmatchedPermit + * Description: + * Set port acl function unmatched permit action + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicAclUnmatchedPermit + * Description: + * Get port acl function unmatched permit action + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicAclRule + * Description: + * Set acl rule content + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclRule - ACL rule stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * System supported 95 shared 289-bit ACL ingress rule. Index was available at range 0-95 only. + * If software want to modify ACL rule, the ACL function should be disable at first or unspecify + * acl action will be executed. + * One ACL rule structure has three parts setting: + * Bit 0-147 Data Bits of this Rule + * Bit 148 Valid Bit + * Bit 149-296 Care Bits of this Rule + * There are four kinds of field in Data Bits and Care Bits: Active Portmask, Type, Tag Exist, and 8 fields + */ +ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule* pAclRule) +{ + rtl8367c_aclrulesmi aclRuleSmi; + rtk_uint16* tableAddr; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint32 i; + ret_t retVal; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); + + _rtl8367c_aclRuleStUser2Smi(pAclRule, &aclRuleSmi); + + /* Write valid bit = 0 */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); + else + regData = RTL8367C_ACLRULETBADDR(DATABITS, index); + retVal = rtl8367c_setAsicReg(regAddr,regData); + if(retVal !=RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0x1, 0); + if(retVal !=RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal !=RT_ERR_OK) + return retVal; + + + + /* Write ACS_ADR register */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); + else + regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Care Bits to ACS_DATA registers */ + tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; + regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; + + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr++; + tableAddr++; + } + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.care_bits_ext.rule_info >> 1) & 0x0007); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,regData); + if(retVal != RT_ERR_OK) + return retVal; + + + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); + else + regData = RTL8367C_ACLRULETBADDR(DATABITS, index); + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Data Bits to ACS_DATA registers */ + tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; + regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; + + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr++; + tableAddr++; + } + + retVal = rtl8367c_setAsicRegBit(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0, aclRuleSmi.valid); + if(retVal != RT_ERR_OK) + return retVal; + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.data_bits_ext.rule_info >> 1) & 0x0007); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register for care bits*/ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(&Rtl8370sVirtualAclRuleTable[index], &aclRuleSmi, sizeof(rtl8367c_aclrulesmi)); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclRule + * Description: + * Get acl rule content + * Input: + * index - ACL rule index (0-63) of 64 ACL rules + * pAclRule - ACL rule stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-63) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule) +{ + rtl8367c_aclrulesmi aclRuleSmi; + rtk_uint32 regAddr, regData; + ret_t retVal; + rtk_uint16* tableAddr; + rtk_uint32 i; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); + else + regData = RTL8367C_ACLRULETBADDR(DATABITS, index); + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Data Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + + regAddr ++; + tableAddr ++; + } + + /* Read Valid Bit */ + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + aclRuleSmi.valid = regData & 0x1; + /* Read active_portmsk_ext Bits */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + aclRuleSmi.data_bits_ext.rule_info = (regData % 0x0007) << 1; + + + /* Write ACS_ADR register for carebits*/ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + if(index >= 64) + regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); + else + regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Care Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; + for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + + regAddr ++; + tableAddr ++; + } + /* Read active_portmsk_ext care Bits */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + aclRuleSmi.care_bits_ext.rule_info = (regData & 0x0007) << 1; + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(&aclRuleSmi,&Rtl8370sVirtualAclRuleTable[index], sizeof(rtl8367c_aclrulesmi)); +#endif + + _rtl8367c_aclRuleStSmi2User(pAclRule, &aclRuleSmi); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclNot + * Description: + * Set rule comparison result inversion / no inversion + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * not - 1: inverse, 0: don't inverse + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not) +{ + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index < 64) + return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); + else + return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); + +} +/* Function Name: + * rtl8367c_getAsicAcl + * Description: + * Get rule comparison result inversion / no inversion + * Input: + * index - ACL rule index (0-95) of 95 ACL rules + * pNot - 1: inverse, 0: don't inverse + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot) +{ + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index < 64) + return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); + else + return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); + +} +/* Function Name: + * rtl8367c_setAsicAclTemplate + * Description: + * Set fields of a ACL Template + * Input: + * index - ACL template index(0~4) + * pAclType - ACL type stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) + * Note: + * The API can set type field of the 5 ACL rule templates. + * Each type has 8 fields. One field means what data in one field of a ACL rule means + * 8 fields of ACL rule 0~95 is descripted by one type in ACL group + */ +ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType) +{ + ret_t retVal; + rtk_uint32 i; + rtk_uint32 regAddr, regData; + + if(index >= RTL8367C_ACLTEMPLATENO) + return RT_ERR_OUT_OF_RANGE; + + regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); + + for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) + { + regData = pAclType->field[i*2+1]; + regData = regData << 8 | pAclType->field[i*2]; + + retVal = rtl8367c_setAsicReg(regAddr + i, regData); + + if(retVal != RT_ERR_OK) + return retVal; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAclTemplate + * Description: + * Get fields of a ACL Template + * Input: + * index - ACL template index(0~4) + * pAclType - ACL type stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType) +{ + ret_t retVal; + rtk_uint32 i; + rtk_uint32 regData, regAddr; + + if(index >= RTL8367C_ACLTEMPLATENO) + return RT_ERR_OUT_OF_RANGE; + + regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); + + for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) + { + retVal = rtl8367c_getAsicReg(regAddr + i,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pAclType->field[i*2] = regData & 0xFF; + pAclType->field[i*2 + 1] = (regData >> 8) & 0xFF; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclAct + * Description: + * Set ACL rule matched Action + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclAct - ACL action stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct) +{ + rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint16* tableAddr; + rtk_uint32 i; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); + _rtl8367c_aclActStUser2Smi(pAclAct, aclActSmi); + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + regData = index; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Data Bits to ACS_DATA registers */ + tableAddr = aclActSmi; + regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; + + for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr++; + tableAddr++; + } + + /* Write ACS_CMD register for care bits*/ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLACT); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(&Rtl8370sVirtualAclActTable[index][0], aclActSmi, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclAct + * Description: + * Get ACL rule matched Action + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclAct - ACL action stucture for setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct) +{ + rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint16 *tableAddr; + rtk_uint32 i; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + regData = index; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLACT); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Data Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + tableAddr = aclActSmi; + for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + + regAddr ++; + tableAddr ++; + } + +#ifdef CONFIG_RTL8367C_ASICDRV_TEST + memcpy(aclActSmi, &Rtl8370sVirtualAclActTable[index][0], sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); +#endif + + _rtl8367c_aclActStSmi2User(pAclAct, aclActSmi); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclActCtrl + * Description: + * Set ACL rule matched Action Control Bits + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * aclActCtrl - 6 ACL Control Bits + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * ACL Action Control Bits Indicate which actions will be take when a rule matches + */ +ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl) +{ + ret_t retVal; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index >= 64) + retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); + else + retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAclActCtrl + * Description: + * Get ACL rule matched Action Control Bits + * Input: + * index - ACL rule index (0-95) of 96 ACL rules + * pAclActCtrl - 6 ACL Control Bits + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *pAclActCtrl) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_ACLRULEMAX) + return RT_ERR_OUT_OF_RANGE; + + if(index >= 64) + retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); + else + retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); + + if(retVal != RT_ERR_OK) + return retVal; + + *pAclActCtrl = regData; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclPortRange + * Description: + * Set ACL TCP/UDP range check + * Input: + * index - TCP/UDP port range check table index + * type - Range check type + * upperPort - TCP/UDP port range upper bound + * lowerPort - TCP/UDP port range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index + * Note: + * None + */ +ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort) +{ + ret_t retVal; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, type); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, upperPort); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, lowerPort); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclPortRange + * Description: + * Get ACL TCP/UDP range check + * Input: + * index - TCP/UDP port range check table index + * pType - Range check type + * pUpperPort - TCP/UDP port range upper bound + * pLowerPort - TCP/UDP port range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index + * Note: + * None + */ +ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort) +{ + ret_t retVal; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, pType); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, pUpperPort); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, pLowerPort); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclVidRange + * Description: + * Set ACL VID range check + * Input: + * index - ACL VID range check index(0~15) + * type - Range check type + * upperVid - VID range upper bound + * lowerVid - VID range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + regData = ((type << RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET) & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) | + (upperVid & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK); + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, regData); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, lowerVid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclVidRange + * Description: + * Get ACL VID range check + * Input: + * index - ACL VID range check index(0~15) + * pType - Range check type + * pUpperVid - VID range upper bound + * pLowerVid - VID range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pType = (regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) >> RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET; + *pUpperVid = regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, pLowerVid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicAclIpRange + * Description: + * Set ACL IP range check + * Input: + * index - ACL IP range check index(0~15) + * type - Range check type + * upperIp - IP range upper bound + * lowerIp - IP range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp) +{ + ret_t retVal; + rtk_uint32 regData; + ipaddr_t ipData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, type); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = upperIp; + + regData = ipData & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = (ipData>>16) & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = lowerIp; + + regData = ipData & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = (ipData>>16) & 0xFFFF; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, regData); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicAclIpRange + * Description: + * Get ACL IP range check + * Input: + * index - ACL IP range check index(0~15) + * pType - Range check type + * pUpperIp - IP range upper bound + * pLowerIp - IP range lower bound + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) + * Note: + * None + */ +ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp) +{ + ret_t retVal; + rtk_uint32 regData; + ipaddr_t ipData; + + if(index > RTL8367C_ACLRANGEMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, pType); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + ipData = regData; + + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = (regData <<16) | ipData; + *pUpperIp = ipData; + + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + ipData = regData; + + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + ipData = (regData << 16) | ipData; + *pLowerIp = ipData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicAclGpioPolarity + * Description: + * Set ACL Goip control palarity + * Input: + * polarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, polarity); +} +/* Function Name: + * rtl8367c_getAsicAclGpioPolarity + * Description: + * Get ACL Goip control palarity + * Input: + * pPolarity - 1: High, 0: Low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * none + */ +ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, pPolarity); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c new file mode 100755 index 00000000..d22bf65e --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Proprietary CPU-tag related function drivers + * + */ +#include +/* Function Name: + * rtl8367c_setAsicCputagEnable + * Description: + * Set cpu tag function enable/disable + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid enable/disable input + * Note: + * If CPU tag function is disabled, CPU tag will not be added to frame + * forwarded to CPU port, and all ports cannot parse CPU tag. + */ +ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled) +{ + if(enabled > 1) + return RT_ERR_ENABLE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicCputagEnable + * Description: + * Get cpu tag function enable/disable + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicCputagTrapPort + * Description: + * Set cpu tag trap port + * Input: + * port - port number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * API can set destination port of trapping frame + */ +ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port) +{ + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, port & 7); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, (port>>3) & 1); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicCputagTrapPort + * Description: + * Get cpu tag trap port + * Input: + * pPort - port number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort) +{ + ret_t retVal; + rtk_uint32 tmpPort; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, &tmpPort); + if(retVal != RT_ERR_OK) + return retVal; + *pPort = tmpPort; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, &tmpPort); + if(retVal != RT_ERR_OK) + return retVal; + *pPort |= (tmpPort & 1) << 3; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicCputagPortmask + * Description: + * Set ports that can parse CPU tag + * Input: + * portmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_CPU_PORT_MASK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicCputagPortmask + * Description: + * Get ports that can parse CPU tag + * Input: + * pPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_CPU_PORT_MASK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicCputagInsertMode + * Description: + * Set CPU-tag insert mode + * Input: + * mode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Actions not allowed by the function + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode) +{ + if(mode >= CPUTAG_INSERT_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicCputagInsertMode + * Description: + * Get CPU-tag insert mode + * Input: + * pMode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicCputagPriorityRemapping + * Description: + * Set queue assignment of CPU port + * Input: + * srcPri - internal priority (0~7) + * newPri - internal priority after remapping (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri) +{ + if((srcPri > RTL8367C_PRIMAX) || (newPri > RTL8367C_PRIMAX)) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), newPri); +} +/* Function Name: + * rtl8367c_getAsicCputagPriorityRemapping + * Description: + * Get queue assignment of CPU port + * Input: + * srcPri - internal priority (0~7) + * pNewPri - internal priority after remapping (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri) +{ + if(srcPri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), pNewPri); +} +/* Function Name: + * rtl8367c_setAsicCputagPosition + * Description: + * Set cpu tag insert position + * Input: + * postion - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 postion) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, postion); +} +/* Function Name: + * rtl8367c_getAsicCputagPosition + * Description: + * Get cpu tag insert position + * Input: + * pPostion - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, pPostion); +} + +/* Function Name: + * rtl8367c_setAsicCputagMode + * Description: + * Set cpu tag mode + * Input: + * mode - 1: 4bytes mode, 0: 8bytes mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters + * Note: + * If CPU tag function is disabled, CPU tag will not be added to frame + * forwarded to CPU port, and all ports cannot parse CPU tag. + */ +ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode) +{ + if(mode > 1) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicCputagMode + * Description: + * Get cpu tag mode + * Input: + * pMode - 1: 4bytes mode, 0: 8bytes mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, pMode); +} +/* Function Name: + * rtl8367c_setAsicCputagRxMinLength + * Description: + * Set cpu tag mode + * Input: + * mode - 1: 64bytes, 0: 72bytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters + * Note: + * If CPU tag function is disabled, CPU tag will not be added to frame + * forwarded to CPU port, and all ports cannot parse CPU tag. + */ +ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode) +{ + if(mode > 1) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicCputagRxMinLength + * Description: + * Get cpu tag mode + * Input: + * pMode - 1: 64bytes, 0: 72bytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, pMode); +} + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c new file mode 100755 index 00000000..73153e17 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : 802.1X related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsic1xPBEnConfig + * Description: + * Set 802.1x port-based port enable configuration + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsic1xPBEnConfig + * Description: + * Get 802.1x port-based port enable configuration + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsic1xPBAuthConfig + * Description: + * Set 802.1x port-based authorised port configuration + * Input: + * port - Physical port number (0~7) + * auth - 1: authorised, 0: non-authorised + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, auth); +} +/* Function Name: + * rtl8367c_getAsic1xPBAuthConfig + * Description: + * Get 802.1x port-based authorised port configuration + * Input: + * port - Physical port number (0~7) + * pAuth - 1: authorised, 0: non-authorised + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, pAuth); +} +/* Function Name: + * rtl8367c_setAsic1xPBOpdirConfig + * Description: + * Set 802.1x port-based operational direction + * Input: + * port - Physical port number (0~7) + * opdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, opdir); +} +/* Function Name: + * rtl8367c_getAsic1xPBOpdirConfig + * Description: + * Get 802.1x port-based operational direction + * Input: + * port - Physical port number (0~7) + * pOpdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32* pOpdir) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, pOpdir); +} +/* Function Name: + * rtl8367c_setAsic1xMBEnConfig + * Description: + * Set 802.1x mac-based port enable configuration + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsic1xMBEnConfig + * Description: + * Get 802.1x mac-based port enable configuration + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsic1xMBOpdirConfig + * Description: + * Set 802.1x mac-based operational direction + * Input: + * opdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir) +{ + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, opdir); +} +/* Function Name: + * rtl8367c_getAsic1xMBOpdirConfig + * Description: + * Get 802.1x mac-based operational direction + * Input: + * pOpdir - Operation direction 1: IN, 0:BOTH + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir) +{ + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, pOpdir); +} +/* Function Name: + * rtl8367c_setAsic1xProcConfig + * Description: + * Set 802.1x unauth. behavior configuration + * Input: + * port - Physical port number (0~7) + * proc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_DOT1X_PROC - Unauthorized behavior error + * Note: + * None + */ +ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc) +{ + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(proc >= DOT1X_UNAUTH_END) + return RT_ERR_DOT1X_PROC; + + if(port < 8) + { + return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); + } + else + { + return rtl8367c_setAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); + } +} +/* Function Name: + * rtl8367c_getAsic1xProcConfig + * Description: + * Get 802.1x unauth. behavior configuration + * Input: + * port - Physical port number (0~7) + * pProc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32* pProc) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); +} +/* Function Name: + * rtl8367c_setAsic1xGuestVidx + * Description: + * Set 802.1x guest vlan index + * Input: + * index - 802.1x guest vlan index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_DOT1X_GVLANIDX - Invalid cvid index + * Note: + * None + */ +ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index) +{ + if(index >= RTL8367C_CVIDXNO) + return RT_ERR_DOT1X_GVLANIDX; + + return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, index); +} +/* Function Name: + * rtl8367c_getAsic1xGuestVidx + * Description: + * Get 802.1x guest vlan index + * Input: + * pIndex - 802.1x guest vlan index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex) +{ + return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, pIndex); +} +/* Function Name: + * rtl8367c_setAsic1xGVOpdir + * Description: + * Set 802.1x guest vlan talk to auth. DA + * Input: + * enabled - 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsic1xGVOpdir + * Description: + * Get 802.1x guest vlan talk to auth. DA + * Input: + * pEnabled - 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsic1xTrapPriority + * Description: + * Set 802.1x Trap priority + * Input: + * priority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK,priority); +} +/* Function Name: + * rtl8367c_getAsic1xTrapPriority + * Description: + * Get 802.1x Trap priority + * Input: + * pPriority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK, pPriority); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c new file mode 100755 index 00000000..370b7c6f --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c @@ -0,0 +1,877 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ethernet AV related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicEavMacAddress + * Description: + * Set PTP MAC address + * Input: + * mac - PTP mac + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint8*)&mac; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + for(i = 0; i <=2; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MAC_ADDR_H - i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicEavMacAddress + * Description: + * Get PTP MAC address + * Input: + * None + * Output: + * pMac - PTP mac + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint8*)pMac; + + for(i = 0; i <= 2; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC_ADDR_H - i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = (regData & 0xFF00) >> 8; + accessPtr ++; + *accessPtr = regData & 0xFF; + accessPtr ++; + } + + return retVal; +} + +/* Function Name: + * rtl8367c_setAsicEavTpid + * Description: + * Set PTP parser tag TPID. + * Input: + * outerTag - outter tag TPID + * innerTag - inner tag TPID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_OTAG_TPID, outerTag)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_ITAG_TPID, innerTag)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicEavTpid + * Description: + * Get PTP parser tag TPID. + * Input: + * None + * Output: + * pOuterTag - outter tag TPID + * pInnerTag - inner tag TPID + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_OTAG_TPID, pOuterTag)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_ITAG_TPID, pInnerTag)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicEavSysTime + * Description: + * Set PTP system time + * Input: + * second - seconds + * nanoSecond - nano seconds + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * The time granuality is 8 nano seconds. + */ +ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond) +{ + ret_t retVal; + rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; + rtk_uint32 nano_second_8; + rtk_uint32 regData, busyFlag, count; + + if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) + return RT_ERR_INPUT; + + regData = 0; + sec_h = second >>16; + sec_l = second & 0xFFFF; + nano_second_8 = nanoSecond >> 3; + nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; + nsec8_l = nano_second_8 &0xFFFF; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) + return retVal; + + regData = nsec8_h | (PTP_TIME_WRITE<= PTP_TIME_ADJ_END) + return RT_ERR_INPUT; + if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) + return RT_ERR_INPUT; + + regData = 0; + sec_h = second >>16; + sec_l = second & 0xFFFF; + nano_second_8 = nanoSecond >> 3; + nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; + nsec8_l = nano_second_8 &0xFFFF; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) + return retVal; + + if (PTP_TIME_ADJ_INC == type) + regData = nsec8_h | (PTP_TIME_INC<=PTP_TIME_CTRL_END) + return RT_ERR_INPUT; + + regData = 0; + if (PTP_TIME_CTRL_START == control) + regData = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; + else + regData = 0; + + if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_CFG, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicEavSysTimeCtrl + * Description: + * Get PTP system time control + * Input: + * None + * Output: + * pControl - start or stop + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 mask; + + mask = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; + + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PTP_TIME_CFG, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData & mask) == mask) + *pControl = PTP_TIME_CTRL_START; + else if( (regData & mask) == 0) + *pControl = PTP_TIME_CTRL_STOP; + else + return RT_ERR_NOT_ALLOWED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicEavInterruptMask + * Description: + * Set PTP interrupt enable mask + * Input: + * imr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr) +{ + if ((imr&(RTL8367C_PTP_INTR_MASK<<8))>0) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, imr); +} +/* Function Name: + * rtl8367c_getAsicEavInterruptMask + * Description: + * Get PTP interrupt enable mask + * Input: + * pImr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, pImr); +} + +/* Function Name: + * rtl8367c_getAsicEavInterruptStatus + * Description: + * Get PTP interrupt port status mask + * Input: + * pIms - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:p0 interrupt, + * [1]:p1 interrupt, + * [2]:p2 interrupt, + * [3]:p3 interrupt, + * [4]:p4 interrupt, + */ +ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_INTERRUPT_CFG, RTL8367C_PTP_PORT_MASK, pIms); +} + +/* Function Name: + * rtl8367c_setAsicInterruptMask + * Description: + * Clear interrupt enable mask + * Input: + * ims - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * This API can be used to clear ASIC interrupt status and register will be cleared by writting 1. + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims) +{ + + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 5) + return rtl8367c_setAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK,ims); + else if(port == 5) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 6) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 7) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + else if(port == 9) + return rtl8367c_setAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicInterruptStatus + * Description: + * Get interrupt enable mask + * Input: + * pIms - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * [0]:TX_SYNC, + * [1]:TX_DELAY, + * [2]:TX_PDELAY_REQ, + * [3]:TX_PDELAY_RESP, + * [4]:RX_SYNC, + * [5]:RX_DELAY, + * [6]:RX_PDELAY_REQ, + * [7]:RX_PDELAY_RESP, + */ +ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms) +{ + + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + if(port < 5) + return rtl8367c_getAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK, pIms); + else if(port == 5) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK, pIms); + else if(port == 6) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + else if(port == 7) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + else if(port == 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + else if(port == 9) + return rtl8367c_getAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); + + return RT_ERR_OK; + +} + + +/* Function Name: + * rtl8367c_setAsicEavPortEnable + * Description: + * Set per-port EAV function enable/disable + * Input: + * port - Physical port number (0~9) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * If EAV function is enabled, PTP event messgae packet will be attached PTP timestamp for trapping + */ +ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 5) + return rtl8367c_setAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 5) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 6) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 7) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 8) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + else if(port == 9) + return rtl8367c_setAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); + + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicEavPortEnable + * Description: + * Get per-port EAV function enable/disable + * Input: + * port - Physical port number (0~9) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + + + if(port < 5) + return rtl8367c_getAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 5) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 6) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 7) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 8) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + else if(port == 9) + return rtl8367c_getAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); + + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicEavPortTimeStamp + * Description: + * Get PTP port time stamp + * Input: + * port - Physical port number (0~9) + * type - PTP packet type + * Output: + * timeStamp - seconds + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * The time granuality is 8 nano seconds. + */ +ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp) +{ + ret_t retVal; + rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; + rtk_uint32 nano_second_8; + + if(port > 9) + return RT_ERR_PORT_ID; + if(type >= PTP_PKT_TYPE_END) + return RT_ERR_INPUT; + + if(port < 5){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SEQ_ID(port, type), &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_H(port) , &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_L(port), &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_NSEC_H(port) , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_NSEC_L(port) , &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 5){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P5_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 6){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P6_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 7){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P7_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 8){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P8_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + }else if(port == 9){ + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P9_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) + return retVal; + } + + timeStamp->second = (sec_h<<16) | sec_l; + nano_second_8 = (nsec8_h<<16) | nsec8_l; + timeStamp->nano_second = nano_second_8<<3; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtl8367c_setAsicEavTrap + * Description: + * Set per-port PTP packet trap to CPU + * Input: + * port - Physical port number (0~5) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * If EAV trap enabled, switch will trap PTP packet to CPU + */ +ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicEavTimeSyncEn + * Description: + * Get per-port EPTP packet trap to CPU + * Input: + * port - Physical port number (0~5) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicEavEnable + * Description: + * Set per-port EAV function enable/disable + * Input: + * port - Physical port number (0~5) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * If EAV function is enabled, PTP event messgae packet will be attached PTP timestamp for trapping + */ +ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicEavEnable + * Description: + * Get per-port EAV function enable/disable + * Input: + * port - Physical port number (0~5) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port > RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicEavPriRemapping + * Description: + * Set non-EAV streaming priority remapping + * Input: + * srcpriority - Priority value + * priority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority) +{ + if(srcpriority > RTL8367C_PRIMAX || priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),priority); +} +/* Function Name: + * rtl8367c_getAsicEavPriRemapping + * Description: + * Get non-EAV streaming priority remapping + * Input: + * srcpriority - Priority value + * pPriority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority) +{ + if(srcpriority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),pPriority); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c new file mode 100755 index 00000000..f4dda6a6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 48989 $ + * $Date: 2014-07-01 15:45:24 +0800 (週二, 01 七月 2014) $ + * + * Purpose : RTL8370 switch high-level API for RTL8367C + * Feature : + * + */ + +#include +#include + +/* +@func ret_t | rtl8367c_setAsicEee100M | Set eee force mode function enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API set the 100M EEE enable function. + +*/ +ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if (enable > 1) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + if(enable) + regData |= (0x0001 << 1); + else + regData &= ~(0x0001 << 1); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicEee100M | Get 100M eee enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API get the 100M EEE function. +*/ +ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + *enable = (regData & (0x0001 << 1)) ? ENABLED : DISABLED; + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_setAsicEeeGiga | Set eee force mode function enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API set the 100M EEE enable function. + +*/ +ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if (enable > 1) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + if(enable) + regData |= (0x0001 << 2); + else + regData &= ~(0x0001 << 2); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicEeeGiga | Get 100M eee enable/disable. +@parm rtk_uint32 | port | The port number. +@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input parameter. +@comm + This API get the 100M EEE function. +*/ +ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 regData; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) + return retVal; + + *enable = (regData & (0x0001 << 2)) ? ENABLED : DISABLED; + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c new file mode 100755 index 00000000..28f49b1b --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c @@ -0,0 +1,1354 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Flow control related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicFlowControlSelect + * Description: + * Set system flow control type + * Input: + * select - System flow control type 1: Ingress flow control 0:Egress flow control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, select); +} +/* Function Name: + * rtl8367c_getAsicFlowControlSelect + * Description: + * Get system flow control type + * Input: + * pSelect - System flow control type 1: Ingress flow control 0:Egress flow control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, pSelect); +} +/* Function Name: + * rtl8367c_setAsicFlowControlJumboMode + * Description: + * Set Jumbo threhsold for flow control + * Input: + * enabled - Jumbo mode flow control 1: Enable 0:Disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicFlowControlJumboMode + * Description: + * Get Jumbo threhsold for flow control + * Input: + * pEnabled - Jumbo mode flow control 1: Enable 0:Disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicFlowControlJumboModeSize + * Description: + * Set Jumbo size for Jumbo mode flow control + * Input: + * size - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size) +{ + if(size >= FC_JUMBO_SIZE_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, size); +} +/* Function Name: + * rtl8367c_getAsicFlowControlJumboModeSize + * Description: + * Get Jumbo size for Jumbo mode flow control + * Input: + * pSize - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, pSize); +} + +/* Function Name: + * rtl8367c_setAsicFlowControlQueueEgressEnable + * Description: + * Set flow control ability for each queue + * Input: + * port - Physical port number (0~7) + * qid - Queue id + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, enabled); +} +/* Function Name: + * rtl8367c_getAsicFlowControlQueueEgressEnable + * Description: + * Get flow control ability for each queue + * Input: + * port - Physical port number (0~7) + * qid - Queue id + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicFlowControlDropAll + * Description: + * Set system-based drop parameters + * Input: + * dropall - Whole system drop threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall) +{ + if(dropall >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, dropall); +} +/* Function Name: + * rtl8367c_getAsicFlowControlDropAll + * Description: + * Get system-based drop parameters + * Input: + * pDropall - Whole system drop threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, pDropall); +} +/* Function Name: + * rtl8367c_setAsicFlowControlPauseAll + * Description: + * Set system-based all ports enable flow control parameters + * Input: + * threshold - Whole system pause all threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold) +{ + if(threshold >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, threshold); +} +/* Function Name: + * rtl8367c_getAsicFlowControlPauseAllThreshold + * Description: + * Get system-based all ports enable flow control parameters + * Input: + * pThreshold - Whole system pause all threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, pThreshold); +} +/* Function Name: + * rtl8367c_setAsicFlowControlSystemThreshold + * Description: + * Set system-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSystemThreshold + * Description: + * Get system-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSharedThreshold + * Description: + * Set share-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSharedThreshold + * Description: + * Get share-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortThreshold + * Description: + * Set Port-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortThreshold + * Description: + * Get Port-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortPrivateThreshold + * Description: + * Set Port-private-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortPrivateThreshold + * Description: + * Get Port-private-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSystemDropThreshold + * Description: + * Set system-based drop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSystemDropThreshold + * Description: + * Get system-based drop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSharedDropThreshold + * Description: + * Set share-based fdrop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, offThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSharedDropThreshold + * Description: + * Get share-based fdrop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, pOffThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortDropThreshold + * Description: + * Set Port-based drop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortDropThreshold + * Description: + * Get Port-based drop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, pOffThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortPrivateDropThreshold + * Description: + * Set Port-private-based drop parameters + * Input: + * onThreshold - Drop turn ON threshold + * offThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortPrivateDropThreshold + * Description: + * Get Port-private-based drop parameters + * Input: + * pOnThreshold - Drop turn ON threshold + * pOffThreshold - Drop turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, pOffThreshold); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSystemJumboThreshold + * Description: + * Set Jumbo system-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSystemJumboThreshold + * Description: + * Get Jumbo system-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlSharedJumboThreshold + * Description: + * Set Jumbo share-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlSharedJumboThreshold + * Description: + * Get Jumbo share-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortJumboThreshold + * Description: + * Set Jumbo Port-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortJumboThreshold + * Description: + * Get Jumbo Port-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, pOnThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicFlowControlPortPrivateJumboThreshold + * Description: + * Set Jumbo Port-private-based flow control parameters + * Input: + * onThreshold - Flow control turn ON threshold + * offThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) +{ + ret_t retVal; + + if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, offThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, onThreshold); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicFlowControlPortPrivateJumboThreshold + * Description: + * Get Jumbo Port-private-based flow control parameters + * Input: + * pOnThreshold - Flow control turn ON threshold + * pOffThreshold - Flow control turn OFF threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, pOffThreshold); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, pOnThreshold); + + return retVal; +} + + + +/* Function Name: + * rtl8367c_setAsicEgressFlowControlQueueDropThreshold + * Description: + * Set Queue-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * qid - The queue id + * threshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold) +{ + if( threshold >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, threshold); +} +/* Function Name: + * rtl8367c_getAsicEgressFlowControlQueueDropThreshold + * Description: + * Get Queue-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * qid - The queue id + * pThreshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold) +{ + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, pThreshold); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlPortDropThreshold + * Description: + * Set port-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * port - Physical port number (0~7) + * threshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(threshold >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, threshold); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlPortDropThreshold + * Description: + * Set port-based egress flow control turn on or ingress flow control drop on threshold + * Input: + * port - Physical port number (0~7) + * pThreshold - Queue-based flown control/drop turn ON threshold + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, pThreshold); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlPortDropGap + * Description: + * Set port-based egress flow control turn off or ingress flow control drop off gap + * Input: + * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap) +{ + if(gap >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, gap); +} +/* Function Name: + * rtl8367c_getAsicEgressFlowControlPortDropGap + * Description: + * Get port-based egress flow control turn off or ingress flow control drop off gap + * Input: + * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, pGap); +} +/* Function Name: + * rtl8367c_setAsicEgressFlowControlQueueDropGap + * Description: + * Set Queue-based egress flow control turn off or ingress flow control drop off gap + * Input: + * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap) +{ + if(gap >= RTL8367C_PAGE_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, gap); +} +/* Function Name: + * rtl8367c_getAsicEgressFlowControlQueueDropGap + * Description: + * Get Queue-based egress flow control turn off or ingress flow control drop off gap + * Input: + * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, pGap); +} +/* Function Name: + * rtl8367c_getAsicEgressQueueEmptyPortMask + * Description: + * Get queue empty port mask + * Input: + * pPortmask - Queue empty port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, pPortmask); +} +/* Function Name: + * rtl8367c_getAsicTotalPage + * Description: + * Get system total page usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER, RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPulbicPage + * Description: + * Get system public page usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER, RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicMaxTotalPage + * Description: + * Get system total page max usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX, RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPulbicPage + * Description: + * Get system public page max usage number + * Input: + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX, RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPortPage + * Description: + * Get per-port page usage number + * Input: + * port - Physical port number (0~7) + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER+port - 8, RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); +} +/* Function Name: + * rtl8367c_getAsicPortPage + * Description: + * Get per-port page max usage number + * Input: + * port - Physical port number (0~7) + * pPageCount - page usage number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX+port-8, RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); + + +} + +/* Function Name: + * rtl8367c_setAsicFlowControlEgressPortIndep + * Description: + * Set per-port egress flow control independent + * Input: + * port - Physical port number (0~7) + * enabled - Egress port flow control usage 1:enable 0:disable. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20), RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,enable); +} + +/* Function Name: + * rtl8367c_getAsicFlowControlEgressPortIndep + * Description: + * Get per-port egress flow control independent + * Input: + * port - Physical port number (0~7) + * enabled - Egress port flow control usage 1:enable 0:disable. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20),RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,pEnable); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c new file mode 100755 index 00000000..a3862385 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Green ethernet related functions + * + */ +#include + +/* Function Name: + * rtl8367c_getAsicGreenPortPage + * Description: + * Get per-Port ingress page usage per second + * Input: + * port - Physical port number (0~7) + * pPage - page number of ingress packet occuping per second + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * Ingress traffic occuping page number per second for high layer green feature usage + */ +ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 pageMeter; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pageMeter = regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port) + 1, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pageMeter = pageMeter + (regData << 16); + + *pPage = pageMeter; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicGreenTrafficType + * Description: + * Set traffic type for each priority + * Input: + * priority - internal priority (0~7) + * traffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype) +{ + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, (traffictype?1:0)); +} +/* Function Name: + * rtl8367c_getAsicGreenTrafficType + * Description: + * Get traffic type for each priority + * Input: + * priority - internal priority (0~7) + * pTraffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, pTraffictype); +} + +/* Function Name: + * rtl8367c_setAsicGreenHighPriorityTraffic + * Description: + * Set indicator which ASIC had received high priority traffic + * Input: + * port - Physical port number (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, 1); +} + + +/* Function Name: + * rtl8367c_getAsicGreenHighPriorityTraffic + * Description: + * Get indicator which ASIC had received high priority traffic or not + * Input: + * port - Physical port number (0~7) + * pIndicator - Have received high priority traffic indicator. If 1 means ASCI had received high priority in 1second checking priod + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, pIndicator); +} + +/* +@func rtk_int32 | rtl8367c_setAsicGreenEthernet | Set green ethernet function. +@parm rtk_uint32 | green | Green feature function usage 1:enable 0:disable. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@comm + The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic + detect the cable length and then select different power mode for best performance with minimums power consumption. Link down + ports will enter power savining mode in 10 seconds after the cable disconnected if power saving function is enabled. +*/ +ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green) +{ + ret_t retVal; + rtk_uint32 checkCounter; + rtk_uint32 regData; + rtk_uint32 phy_status; + rtk_uint32 patchData[6][2] = { {0x809A, 0x8911}, {0x80A3, 0x9233}, {0x80AC, 0xA444}, {0x809F, 0x6B20}, {0x80A8, 0x6B22}, {0x80B1, 0x6B23} }; + rtk_uint32 idx; + rtk_uint32 data; + + if (green > 1) + return RT_ERR_INPUT; + + /* 0xa420[2:0] */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA420, ®Data)) != RT_ERR_OK) + return retVal; + phy_status = (regData & 0x0007); + + if(phy_status == 3) + { + /* 0xb820[4] = 1 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= (0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 1 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + else + checkCounter = 0; + } + } + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (data) + { + case 0x0276: + case 0x0597: + case 0x6367: + if(green) + { + for(idx = 0; idx < 6; idx++ ) + { + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, patchData[idx][0])) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, patchData[idx][1])) != RT_ERR_OK) + return retVal; + } + } + break; + default: + break;; + } + + + + /* 0xa436 = 0x8011 */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) + return retVal; + + /* wr 0xa438[15] = 0: disable, 1: enable */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) + return retVal; + + if(green) + regData |= 0x8000; + else + regData &= 0x7FFF; + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, regData)) != RT_ERR_OK) + return retVal; + + if(phy_status == 3) + { + /* 0xb820[4] = 0 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 0 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + else + checkCounter = 0; + } + } + + return RT_ERR_OK; +} + +/* +@func rtk_int32 | rtl8367c_getAsicGreenEthernet | Get green ethernet function. +@parm rtk_uint32 | *green | Green feature function usage 1:enable 0:disable. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@comm + The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic + detect the cable length and then select different power mode for best performance with minimums power consumption. Link down + ports will enter power savining mode in 10 seconds after the cable disconnected if power saving function is enabled. +*/ +ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green) +{ + ret_t retVal; + rtk_uint32 regData; + + /* 0xa436 = 0x8011 */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) + return retVal; + + /* wr 0xa438[15] = 0: disable, 1: enable */ + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) + return retVal; + + if(regData & 0x8000) + *green = ENABLED; + else + *green = DISABLED; + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_setAsicPowerSaving | Set power saving mode +@parm rtk_uint32 | phy | phy number +@parm rtk_uint32 | enable | enable power saving mode. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@comm + The API can set power saving mode per phy. +*/ +ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + rtk_uint32 regData; + rtk_uint32 phy_status; + rtk_uint32 checkCounter; + + if (enable > 1) + return RT_ERR_INPUT; + + /* 0xa420[2:0] */ + if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xA420, ®Data)) != RT_ERR_OK) + return retVal; + + phy_status = (regData & 0x0007); + + if(phy_status == 3) + { + /* 0xb820[4] = 1 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData |= (0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 1 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) + { + checkCounter --; + if(0 == checkCounter) + { + return RT_ERR_BUSYWAIT_TIMEOUT; + } + } + else + checkCounter = 0; + } + } + + if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) + return retVal; + + phyData = phyData & ~(0x0001 << 2); + phyData = phyData | (enable << 2); + + if ((retVal = rtl8367c_setAsicPHYReg(phy,PHY_POWERSAVING_REG,phyData))!=RT_ERR_OK) + return retVal; + + if(phy_status == 3) + { + /* 0xb820[4] = 0 */ + if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= ~(0x0001 << 4); + + if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) + return retVal; + + /* wait 0xb800[6] = 0 */ + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); + if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) + { + checkCounter --; + if(0 == checkCounter) + { + return RT_ERR_BUSYWAIT_TIMEOUT; + } + } + else + checkCounter = 0; + } + } + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicPowerSaving | Get power saving mode +@parm rtk_uint32 | port | The port number +@parm rtk_uint32* | enable | enable power saving mode. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@comm + The API can get power saving mode per phy. +*/ +ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyData; + + if(NULL == enable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) + return retVal; + + if ((phyData & 0x0004) > 0) + *enable = 1; + else + *enable = 0; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c new file mode 100755 index 00000000..435368d5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Field selector related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicFieldSelector + * Description: + * Set user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * format - Format of field selector + * offset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * System support 16 user defined field selctors. + * Each selector can be enabled or disable. User can defined retrieving 16-bits in many predefiend + * standard l2/l3/l4 payload. + */ +ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset) +{ + rtk_uint32 regData; + + if(index > RTL8367C_FIELDSEL_FORMAT_NUMBER) + return RT_ERR_OUT_OF_RANGE; + + if(format >= FIELDSEL_FORMAT_END) + return RT_ERR_OUT_OF_RANGE; + + regData = (((format << RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET) & RTL8367C_FIELD_SELECTOR_FORMAT_MASK ) | + ((offset << RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET) & RTL8367C_FIELD_SELECTOR_OFFSET_MASK )); + + return rtl8367c_setAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), regData); +} +/* Function Name: + * rtl8367c_getAsicFieldSelector + * Description: + * Get user defined field selectors in HSB + * Input: + * index - index of field selector 0-15 + * pFormat - Format of field selector + * pOffset - Retrieving data offset + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pFormat = ((regData & RTL8367C_FIELD_SELECTOR_FORMAT_MASK) >> RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET); + *pOffset = ((regData & RTL8367C_FIELD_SELECTOR_OFFSET_MASK) >> RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET); + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c new file mode 100755 index 00000000..69f20a01 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 38651 $ + * $Date: 2016-02-27 14:32:56 +0800 (周三, 17 四月 2016) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : I2C related functions + * + */ + + +#include +#include +#include + + + +/* Function Name: + * rtl8367c_setAsicI2C_checkBusIdle + * Description: + * Check i2c bus status idle or not + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_BUSYWAIT_TIMEOUT - i2c bus is busy + * Note: + * This API can check i2c bus status. + */ +ret_t rtl8367c_setAsicI2C_checkBusIdle(void) +{ + rtk_uint32 regData; + ret_t retVal; + + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_M_I2C_BUS_IDLE_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + if(regData == 0x0001) + return RT_ERR_OK; /*i2c is idle*/ + else + return RT_ERR_BUSYWAIT_TIMEOUT; /*i2c is busy*/ +} + + +/* Function Name: + * rtl8367c_setAsicI2CStartCmd + * Description: + * Set I2C start command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set i2c start command ,start a i2c traffic . + */ +ret_t rtl8367c_setAsicI2CStartCmd(void) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0000, Start Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0001; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + +/* Function Name: + * rtl8367c_setAsicI2CStopCmd + * Description: + * Set I2C stop command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set i2c stop command ,stop a i2c traffic. + */ +ret_t rtl8367c_setAsicI2CStopCmd(void) +{ + + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0001, Stop Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0003; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + +/* Function Name: + * rtl8367c_setAsicI2CTxOneCharCmd + * Description: + * Set I2C Tx a char command, with a 8-bit data + * Input: + * oneChar - 8-bit data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set i2c Tx command and with a 8-bit data. + */ +ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0010, tx one char; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= 0xFFE0; + regData |= 0x0005; + regData &= 0x00FF; + regData |= (rtk_uint16) (oneChar << 8); + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + + +/* Function Name: + * rtl8367c_setAsicI2CcheckRxAck + * Description: + * Check if rx an Ack + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can check if rx an ack from i2c slave. + */ +ret_t rtl8367c_setAsicI2CcheckRxAck(void) +{ + rtk_uint32 regData; + ret_t retVal; + rtk_uint32 count = 0; + + do{ + count++; + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_SLV_ACK_FLAG_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( (regData != 0x1) && (count < TIMEROUT_FOR_MICROSEMI) ); + + if(regData != 0x1) + return RT_ERR_FAILED; + else + return RT_ERR_OK; +} + + +/* Function Name: + * rtl8367c_setAsicI2CRxOneCharCmd + * Description: + * Set I2C Rx command and get 8-bit data + * Input: + * None + * Output: + * pValue - 8bit-data + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C Rx command and get 8-bit data. + */ +ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0011, Rx one char; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0007; + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + }while( (regData & 0x1) != 0x0); + + *pValue = (rtk_uint8)(regData >> 8); + return RT_ERR_OK ; + +} + +/* Function Name: + * rtl8367c_setAsicI2CTxAckCmd + * Description: + * Set I2C Tx ACK command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C Tx ack command. + */ +ret_t rtl8367c_setAsicI2CTxAckCmd(void) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0100, tx ACK Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x0009; + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; + +} + + +/* Function Name: + * rtl8367c_setAsicI2CTxNoAckCmd + * Description: + * Set I2C master Tx noACK command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C master Tx noACK command. + */ +ret_t rtl8367c_setAsicI2CTxNoAckCmd(void) +{ + rtk_uint32 regData; + ret_t retVal; + + /* Bits [4-1] = 0b0101, tx noACK Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x000b; + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; + +} + +/* Function Name: + * rtl8367c_setAsicI2CSoftRSTseqCmd + * Description: + * set I2C master tx soft reset command + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * Note: + * This API can set I2C master tx soft reset command. + */ +ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void) +{ + + rtk_uint32 regData; + ret_t retVal; + + /*Bits [4-1] = 0b0110, tx soft reset Command; Bit [0] = 1, Trigger the Command */ + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xFFE0; + regData |= 0x000d; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) + return retVal; + + + /* wait for command finished */ + do{ + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + }while( regData != 0x0); + + return RT_ERR_OK ; +} + + +/* Function Name: + * rtl8367c_setAsicI2CGpioPinGroup + * Description: + * set I2C function used gpio pins + * Input: + * pinGroup_ID - gpio pins group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_INPUT _ Invalid input parameter + * Note: + * This API can set I2C function used gpio pins. + * There are three group gpio pins + */ +ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID) +{ + rtk_uint32 regData; + ret_t retVal; + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) + return retVal; + if( pinGroup_ID==0 ) + { + regData &= 0x0FFF; + regData |= 0x5000; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) + return retVal; + } + + else if( pinGroup_ID==1 ) + { + regData &= 0x0FFF; + regData |= 0xA000; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) + return retVal; + } + + else if( pinGroup_ID==2 ) + { + regData &= 0x0FFF; + regData |= 0xF000; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK ; + +} + +/* Function Name: + * rtl8367c_setAsicI2CGpioPinGroup + * Description: + * set I2C function used gpio pins + * Input: + * pinGroup_ID - gpio pins group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_INPUT _ Invalid input parameter + * Note: + * This API can set I2C function used gpio pins. + * There are three group gpio pins + */ +ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID) +{ + + rtk_uint32 regData; + ret_t retVal; + if( (retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) + return retVal; + regData &= 0xF000 ; + regData = (regData >> 12); + + if( regData == 0x5 ) + *pPinGroup_ID = 0; + else if(regData == 0xA) + *pPinGroup_ID = 1; + else if(regData == 0xF) + *pPinGroup_ID = 2; + else + return RT_ERR_FAILED; + return RT_ERR_OK ; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c new file mode 100755 index 00000000..e0e734d6 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c @@ -0,0 +1,2109 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : IGMP related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicIgmp + * Description: + * Set IGMP/MLD state + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled) +{ + ret_t retVal; + + /* Enable/Disable H/W IGMP/MLD */ + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, enabled); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicIgmp + * Description: + * Get IGMP/MLD state + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIgmp(rtk_uint32 *ptr_enabled) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, ptr_enabled); + return retVal; +} +/* Function Name: + * rtl8367c_setAsicIpMulticastVlanLeaky + * Description: + * Set IP multicast VLAN Leaky function + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * When enabling this function, + * if the lookup result(forwarding portmap) of IP Multicast packet is over VLAN boundary, + * the packet can be forwarded across VLAN + */ +ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, enabled); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicIpMulticastVlanLeaky + * Description: + * Get IP multicast VLAN Leaky function + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *ptr_enabled) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, ptr_enabled); + + return retVal; +} + +/* Function Name: + * rtl8367c_setAsicIGMPTableFullOP + * Description: + * Set Table Full operation + * Input: + * operation - The operation should be taken when the IGMP table is full. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation) +{ + ret_t retVal; + + if(operation >= TABLE_FULL_OP_END) + return RT_ERR_OUT_OF_RANGE; + + /* Table full Operation */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, operation); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPTableFullOP + * Description: + * Get Table Full operation + * Input: + * None + * Output: + * poperation - The operation should be taken when the IGMP table is full. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *poperation) +{ + ret_t retVal; + rtk_uint32 value; + + /* Table full Operation */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *poperation = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPCRCErrOP + * Description: + * Set the operation when ASIC receive a Checksum error packet + * Input: + * operation -The operation when ASIC receive a Checksum error packet + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation) +{ + ret_t retVal; + + if(operation >= CRC_ERR_OP_END) + return RT_ERR_OUT_OF_RANGE; + + /* CRC Error Operation */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, operation); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPCRCErrOP + * Description: + * Get the operation when ASIC receive a Checksum error packet + * Input: + * None + * Output: + * poperation - The operation of Checksum error packet + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *poperation) +{ + ret_t retVal; + rtk_uint32 value; + + /* CRC Error Operation */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *poperation = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPFastLeaveEn + * Description: + * Enable/Disable Fast Leave + * Input: + * enabled - 1:enable Fast Leave; 0:disable Fast Leave + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled) +{ + ret_t retVal; + + /* Fast Leave */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, (enabled >= 1) ? 1 : 0); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPFastLeaveEn + * Description: + * Get Fast Leave state + * Input: + * None + * Output: + * penabled - 1:enable Fast Leave; 0:disable Fast Leave + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *penabled) +{ + ret_t retVal; + rtk_uint32 value; + + /* Fast Leave */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *penabled = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPLeaveTimer + * Description: + * Set the Leave timer of IGMP/MLD + * Input: + * leave_timer - Leave timer + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer) +{ + ret_t retVal; + + if(leave_timer > RTL8367C_MAX_LEAVE_TIMER) + return RT_ERR_OUT_OF_RANGE; + + /* Leave timer */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, leave_timer); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPLeaveTimer + * Description: + * Get the Leave timer of IGMP/MLD + * Input: + * None + * Output: + * pleave_timer - Leave timer + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pleave_timer) +{ + ret_t retVal; + rtk_uint32 value; + + /* Leave timer */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *pleave_timer = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPQueryInterval + * Description: + * Set Query Interval of IGMP/MLD + * Input: + * interval - Query Interval + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval) +{ + ret_t retVal; + + if(interval > RTL8367C_MAX_QUERY_INT) + return RT_ERR_OUT_OF_RANGE; + + /* Query Interval */ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, interval); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPQueryInterval + * Description: + * Get Query Interval of IGMP/MLD + * Input: + * None + * Output: + * pinterval - Query Interval + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pinterval) +{ + ret_t retVal; + rtk_uint32 value; + + /* Query Interval */ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *pinterval = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPRobVar + * Description: + * Set Robustness Variable of IGMP/MLD + * Input: + * rob_var - Robustness Variable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter is out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var) +{ + ret_t retVal; + + if(rob_var > RTL8367C_MAX_ROB_VAR) + return RT_ERR_OUT_OF_RANGE; + + /* Bourstness variable */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBURSTNESS_VAR_MASK, rob_var); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPRobVar + * Description: + * Get Robustness Variable of IGMP/MLD + * Input: + * none + * Output: + * prob_var - Robustness Variable + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *prob_var) +{ + ret_t retVal; + rtk_uint32 value; + + /* Bourstness variable */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBURSTNESS_VAR_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + + *prob_var = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPStaticRouterPort + * Description: + * Set IGMP static router port mask + * Input: + * pmsk - Static portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk) +{ + if(pmsk > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); +} + +/* Function Name: + * rtl8367c_getAsicIGMPStaticRouterPort + * Description: + * Get IGMP static router port mask + * Input: + * pmsk - Static portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pmsk) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); +} + +/* Function Name: + * rtl8367c_setAsicIGMPAllowDynamicRouterPort + * Description: + * Set IGMP dynamic router port allow mask + * Input: + * pmsk - Allow dynamic router port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pmsk); +} + +/* Function Name: + * rtl8367c_getAsicIGMPAllowDynamicRouterPort + * Description: + * Get IGMP dynamic router port allow mask + * Input: + * None. + * Output: + * pPmsk - Allow dynamic router port mask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pPmsk); +} + +/* Function Name: + * rtl8367c_getAsicIGMPdynamicRouterPort1 + * Description: + * Get 1st dynamic router port and timer + * Input: + * port - Physical port number (0~7) + * timer - router port timer + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *port, rtk_uint32 *timer) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_1_MASK, port); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_1_MASK, timer); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPdynamicRouterPort2 + * Description: + * Get 2nd dynamic router port and timer + * Input: + * port - Physical port number (0~7) + * timer - router port timer + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *port, rtk_uint32 *timer) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_2_MASK, port); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_2_MASK, timer); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPSuppression + * Description: + * Set the suppression function + * Input: + * report_supp_enabled - Report suppression, 1:Enable, 0:disable + * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPSuppression + * Description: + * Get the suppression function + * Input: + * report_supp_enabled - Report suppression, 1:Enable, 0:disable + * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *report_supp_enabled, rtk_uint32 *leave_supp_enabled) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPQueryRX + * Description: + * Set port-based Query packet RX allowance + * Input: + * port - port number + * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Query */ + if (port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPQueryRX + * Description: + * Get port-based Query packet RX allowance + * Input: + * port - port number + * Output: + * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *allow_query) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Query */ + if (port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + *allow_query = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPReportRX + * Description: + * Set port-based Report packet RX allowance + * Input: + * port - port number + * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Report */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPReportRX + * Description: + * Get port-based Report packet RX allowance + * Input: + * port - port number + * Output: + * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *allow_report) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Report */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + *allow_report = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPLeaveRX + * Description: + * Set port-based Leave packet RX allowance + * Input: + * port - port number + * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Leave */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPLeaveRX + * Description: + * Get port-based Leave packet RX allowance + * Input: + * port - port number + * Output: + * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *allow_leave) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Leave */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *allow_leave = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPMRPRX + * Description: + * Set port-based Multicast Routing Protocol packet RX allowance + * Input: + * port - port number + * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + /* Allow Multicast Routing Protocol */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPMRPRX + * Description: + * Get port-based Multicast Routing Protocol packet RX allowance + * Input: + * port - port number + * Output: + * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *allow_mrp) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Multicast Routing Protocol */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + *allow_mrp = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPMcDataRX + * Description: + * Set port-based Multicast data packet RX allowance + * Input: + * port - port number + * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop + * Output: + * none + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Multicast Data */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPMcDataRX + * Description: + * Get port-based Multicast data packet RX allowance + * Input: + * port - port number + * Output: + * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *allow_mcdata) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* Allow Multicast data */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *allow_mcdata = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPv1Opeartion + * Description: + * Set port-based IGMPv1 Control packet action + * Input: + * port - port number + * igmpv1_op - IGMPv1 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(igmpv1_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* IGMPv1 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPv1Opeartion + * Description: + * Get port-based IGMPv1 Control packet action + * Input: + * port - port number + * Output: + * igmpv1_op - IGMPv1 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *igmpv1_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* IGMPv1 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *igmpv1_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPv2Opeartion + * Description: + * Set port-based IGMPv2 Control packet action + * Input: + * port - port number + * igmpv2_op - IGMPv2 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(igmpv2_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* IGMPv2 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPv2Opeartion + * Description: + * Get port-based IGMPv2 Control packet action + * Input: + * port - port number + * Output: + * igmpv2_op - IGMPv2 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *igmpv2_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* IGMPv2 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *igmpv2_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPv3Opeartion + * Description: + * Set port-based IGMPv3 Control packet action + * Input: + * port - port number + * igmpv3_op - IGMPv3 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(igmpv3_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* IGMPv3 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPv3Opeartion + * Description: + * Get port-based IGMPv3 Control packet action + * Input: + * port - port number + * Output: + * igmpv3_op - IGMPv3 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *igmpv3_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* IGMPv3 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *igmpv3_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicMLDv1Opeartion + * Description: + * Set port-based MLDv1 Control packet action + * Input: + * port - port number + * mldv1_op - MLDv1 control packet action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(mldv1_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* MLDv1 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMLDv1Opeartion + * Description: + * Get port-based MLDv1 Control packet action + * Input: + * port - port number + * Output: + * mldv1_op - MLDv1 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *mldv1_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* MLDv1 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *mldv1_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicMLDv2Opeartion + * Description: + * Set port-based MLDv2 Control packet action + * Input: + * port - port number + * mldv2_op - MLDv2 control packet action + * Output: + * none + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(mldv2_op >= PROTOCOL_OP_END) + return RT_ERR_INPUT; + + /* MLDv2 operation */ + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMLDv2Opeartion + * Description: + * Get port-based MLDv2 Control packet action + * Input: + * port - port number + * Output: + * mldv2_op - MLDv2 control packet action + * Return: + * RT_ERR_OK - Success + * RT_ERR_PORT_ID - Error PORT ID + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *mldv2_op) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + /* MLDv2 operation */ + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *mldv2_op = value; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPPortMAXGroup + * Description: + * Set per-port Max group number + * Input: + * port - Physical port number (0~7) + * max_group - max IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(max_group > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_OUT_OF_RANGE; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicIGMPPortMAXGroup + * Description: + * Get per-port Max group number + * Input: + * port - Physical port number (0~7) + * max_group - max IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *max_group) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *max_group = value; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicIGMPPortCurrentGroup + * Description: + * Get per-port current group number + * Input: + * port - Physical port number (0~7) + * current_group - current IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *current_group) +{ + ret_t retVal; + rtk_uint32 value; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP + (port/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP + ((port - 8)/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); + if(retVal != RT_ERR_OK) + return retVal; + } + + *current_group = value; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicIGMPGroup + * Description: + * Get IGMP group + * Input: + * idx - Group index (0~255) + * valid - valid bit + * grp - IGMP group + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Group index is out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *valid, rtl8367c_igmpgroup *grp) +{ + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint32 i; + rtk_uint32 groupInfo = 0; + + if(idx > RTL8367C_IGMP_MAX_GOUP) + return RT_ERR_OUT_OF_RANGE; + + /* Write ACS_ADR register for data bits */ + regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; + regData = idx; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write ACS_CMD register */ + regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; + regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_IGMP_GROUP); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Data Bits */ + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; + for(i = 0 ;i <= 1; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + groupInfo |= ((regData & 0xFFFF) << (i * 16)); + regAddr ++; + } + + grp->p0_timer = groupInfo & 0x00000007; + grp->p1_timer = (groupInfo >> 3) & 0x00000007; + grp->p2_timer = (groupInfo >> 6) & 0x00000007; + grp->p3_timer = (groupInfo >> 9) & 0x00000007; + grp->p4_timer = (groupInfo >> 12) & 0x00000007; + grp->p5_timer = (groupInfo >> 15) & 0x00000007; + grp->p6_timer = (groupInfo >> 18) & 0x00000007; + grp->p7_timer = (groupInfo >> 21) & 0x00000007; + grp->report_supp_flag = (groupInfo >> 24) & 0x00000001; + grp->p8_timer = (groupInfo >> 25) & 0x00000007; + grp->p9_timer = (groupInfo >> 28) & 0x00000007; + grp->p10_timer = (groupInfo >> 31) & 0x00000001; + + regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE + 2; + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + grp->p10_timer |= (regData & 0x00000003) << 1; + + /* Valid bit */ + retVal = rtl8367c_getAsicReg(RTL8367C_IGMP_GROUP_USAGE_REG(idx), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *valid = ((regData & (0x0001 << (idx %16))) != 0) ? 1 : 0; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicIpMulticastPortIsoLeaky + * Description: + * Set IP multicast Port Isolation leaky + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIpMulticastPortIsoLeaky + * Description: + * Get IP multicast Port Isolation leaky + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *enabled) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *enabled = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPReportLeaveFlood + * Description: + * Set IGMP/MLD Report/Leave flood + * Input: + * flood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, flood); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPReportLeaveFlood + * Description: + * Get IGMP/MLD Report/Leave flood + * Input: + * None + * Output: + * pflood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pFlood = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPDropLeaveZero + * Description: + * Set the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * drop - 1: Drop, 0:Bypass + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, drop); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPDropLeaveZero + * Description: + * Get the function of droppping Leave packet with group IP = 0.0.0.0 + * Input: + * None + * Output: + * pDrop - 1: Drop, 0:Bypass + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pDrop = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPBypassStormCTRL + * Description: + * Set the function of bypass strom control for IGMP/MLD packet + * Input: + * bypass - 1: Bypass, 0:not bypass + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, bypass); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPBypassStormCTRL + * Description: + * Set the function of bypass strom control for IGMP/MLD packet + * Input: + * None + * Output: + * pBypass - 1: Bypass, 0:not bypass + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pBypass = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPIsoLeaky + * Description: + * Set Port Isolation leaky for IGMP/MLD packet + * Input: + * leaky - 1: Leaky, 0:not leaky + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, leaky); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPIsoLeaky + * Description: + * Get Port Isolation leaky for IGMP/MLD packet + * Input: + * Noen + * Output: + * pLeaky - 1: Leaky, 0:not leaky + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pLeaky = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPVLANLeaky + * Description: + * Set VLAN leaky for IGMP/MLD packet + * Input: + * leaky - 1: Leaky, 0:not leaky + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, leaky); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPVLANLeaky + * Description: + * Get VLAN leaky for IGMP/MLD packet + * Input: + * Noen + * Output: + * pLeaky - 1: Leaky, 0:not leaky + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pLeaky = regData; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicIGMPBypassGroup + * Description: + * Set IGMP/MLD Bypass group + * Input: + * bypassType - Bypass type + * enabled - enabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled) +{ + ret_t retVal; + rtk_uint32 offset; + + switch(bypassType) + { + case BYPASS_224_0_0_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; + break; + case BYPASS_224_0_1_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; + break; + case BYPASS_239_255_255_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; + break; + case BYPASS_IPV6_00XX: + offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; + break; + default: + return RT_ERR_INPUT; + } + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, enabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicIGMPBypassGroup + * Description: + * Get IGMP/MLD Bypass group + * Input: + * bypassType - Bypass type + * Output: + * pEnabled - enabled + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled) +{ + ret_t retVal; + rtk_uint32 offset; + + switch(bypassType) + { + case BYPASS_224_0_0_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; + break; + case BYPASS_224_0_1_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; + break; + case BYPASS_239_255_255_X: + offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; + break; + case BYPASS_IPV6_00XX: + offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; + break; + default: + return RT_ERR_INPUT; + } + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, pEnabled); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c new file mode 100755 index 00000000..abb36bec --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Ingress bandwidth control related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicPortIngressBandwidth + * Description: + * Set per-port total ingress bandwidth + * Input: + * port - Physical port number (0~7) + * bandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable + * preifg - Include preamble and IFG, 0:Exclude, 1:Include + * enableFC - Action when input rate exceeds. 0: Drop 1: Flow Control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 regAddr; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(bandwidth > RTL8367C_QOS_GRANULARTY_MAX) + return RT_ERR_OUT_OF_RANGE; + + regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); + regData = bandwidth & RTL8367C_QOS_GRANULARTY_LSB_MASK; + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr += 1; + regData = (bandwidth & RTL8367C_QOS_GRANULARTY_MSB_MASK) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, preifg); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, enableFC); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortIngressBandwidth + * Description: + * Get per-port total ingress bandwidth + * Input: + * port - Physical port number (0~7) + * pBandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable + * pPreifg - Include preamble and IFG, 0:Exclude, 1:Include + * pEnableFC - Action when input rate exceeds. 0: Drop 1: Flow Control + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 regAddr; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pBandwidth = regData; + + regAddr += 1; + retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pBandwidth |= (regData << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, pPreifg); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_MISC_CFG_REG(port); + retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, pEnableFC); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortIngressBandwidthBypass + * Description: + * Set ingress bandwidth control bypasss 8899, RMA 01-80-C2-00-00-xx and IGMP + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortIngressBandwidthBypass + * Description: + * Set ingress bandwidth control bypasss 8899, RMA 01-80-C2-00-00-xx and IGMP + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, pEnabled); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c new file mode 100755 index 00000000..fb6cbcdf --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Interrupt related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicInterruptPolarity + * Description: + * Set interrupt trigger polarity + * Input: + * polarity - 0:pull high 1: pull low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, polarity); +} +/* Function Name: + * rtl8367c_getAsicInterruptPolarity + * Description: + * Get interrupt trigger polarity + * Input: + * pPolarity - 0:pull high 1: pull low + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, pPolarity); +} +/* Function Name: + * rtl8367c_setAsicInterruptMask + * Description: + * Set interrupt enable mask + * Input: + * imr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMR, imr); +} +/* Function Name: + * rtl8367c_getAsicInterruptMask + * Description: + * Get interrupt enable mask + * Input: + * pImr - Interrupt mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMR, pImr); +} +/* Function Name: + * rtl8367c_setAsicInterruptMask + * Description: + * Clear interrupt enable mask + * Input: + * ims - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * This API can be used to clear ASIC interrupt status and register will be cleared by writting 1. + * [0]:Link change, + * [1]:Share meter exceed, + * [2]:Learn number overed, + * [3]:Speed Change, + * [4]:Tx special congestion + * [5]:1 second green feature + * [6]:loop detection + * [7]:interrupt from 8051 + * [8]:Cable diagnostic finish + * [9]:ACL action interrupt trigger + * [11]: Silent Start + */ +ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMS, ims); +} +/* Function Name: + * rtl8367c_getAsicInterruptStatus + * Description: + * Get interrupt enable mask + * Input: + * pIms - Interrupt status mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMS, pIms); +} +/* Function Name: + * rtl8367c_setAsicInterruptRelatedStatus + * Description: + * Clear interrupt status + * Input: + * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status + * status - exceed status, write 1 to clear + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status) +{ + CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, + RTL8367C_REG_SPEED_CHANGE_INDICATOR, + RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, + RTL8367C_REG_PORT_LINKDOWN_INDICATOR, + RTL8367C_REG_PORT_LINKUP_INDICATOR, + RTL8367C_REG_METER_OVERRATE_INDICATOR0, + RTL8367C_REG_METER_OVERRATE_INDICATOR1, + RTL8367C_REG_RLDP_LOOPED_INDICATOR, + RTL8367C_REG_RLDP_RELEASED_INDICATOR, + RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; + + if(type >= INTRST_END ) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicReg(indicatorAddress[type], status); +} +/* Function Name: + * rtl8367c_getAsicInterruptRelatedStatus + * Description: + * Get interrupt status + * Input: + * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status + * pStatus - exceed status, write 1 to clear + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus) +{ + CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, + RTL8367C_REG_SPEED_CHANGE_INDICATOR, + RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, + RTL8367C_REG_PORT_LINKDOWN_INDICATOR, + RTL8367C_REG_PORT_LINKUP_INDICATOR, + RTL8367C_REG_METER_OVERRATE_INDICATOR0, + RTL8367C_REG_METER_OVERRATE_INDICATOR1, + RTL8367C_REG_RLDP_LOOPED_INDICATOR, + RTL8367C_REG_RLDP_RELEASED_INDICATOR, + RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; + + if(type >= INTRST_END ) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicReg(indicatorAddress[type], pStatus); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c new file mode 100755 index 00000000..11890281 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c @@ -0,0 +1,727 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LED related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicLedIndicateInfoConfig + * Description: + * Set Leds indicated information mode + * Input: + * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group + * config - Support 16 types configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. + * Definition LED Statuses Description + * 0000 LED_Off LED pin Tri-State. + * 0001 Dup/Col Collision, Full duplex Indicator. Blinking every 43ms when collision happens. Low for full duplex, and high for half duplex mode. + * 0010 Link/Act Link, Activity Indicator. Low for link established. Link/Act Blinks every 43ms when the corresponding port is transmitting or receiving. + * 0011 Spd1000 1000Mb/s Speed Indicator. Low for 1000Mb/s. + * 0100 Spd100 100Mb/s Speed Indicator. Low for 100Mb/s. + * 0101 Spd10 10Mb/s Speed Indicator. Low for 10Mb/s. + * 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. Low for 1000Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. Low for 100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. Low for 10Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. Low for 10/100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. + * 1010 Fiber Fiber link Indicator. Low for Fiber. + * 1011 Fault Auto-negotiation Fault Indicator. Low for Fault. + * 1100 Link/Rx Link, Activity Indicator. Low for link established. Link/Rx Blinks every 43ms when the corresponding port is transmitting. + * 1101 Link/Tx Link, Activity Indicator. Low for link established. Link/Tx Blinks every 43ms when the corresponding port is receiving. + * 1110 Master Link on Master Indicator. Low for link Master established. + * 1111 LED_Force Force LED output, LED output value reference + */ +ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config) +{ + ret_t retVal; + CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO] = {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; + + if(ledno >= RTL8367C_LEDGROUPNO) + return RT_ERR_OUT_OF_RANGE; + + if(config >= LEDCONF_END) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 0); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], config); +} +/* Function Name: + * rtl8367c_getAsicLedIndicateInfoConfig + * Description: + * Get Leds indicated information mode + * Input: + * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group + * pConfig - Support 16 types configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig) +{ + CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO]= {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; + + if(ledno >= RTL8367C_LEDGROUPNO) + return RT_ERR_OUT_OF_RANGE; + + /* Get register value */ + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], pConfig); +} +/* Function Name: + * rtl8367c_setAsicLedGroupMode + * Description: + * Set Led Group mode + * Input: + * mode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(mode >= RTL8367C_LED_MODE_END) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 1); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicLedGroupMode + * Description: + * Get Led Group mode + * Input: + * pMode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData!=1) + return RT_ERR_FAILED; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicForceLeds + * Description: + * Set group LED mode + * Input: + * port - Physical port number (0~7) + * group - LED group number + * mode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode) +{ + rtk_uint16 regAddr; + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(group >= RTL8367C_LEDGROUPNO) + return RT_ERR_OUT_OF_RANGE; + + if(mode >= LEDFORCEMODE_END) + return RT_ERR_OUT_OF_RANGE; + /* Set Related Registers */ + if(port < 8){ + regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); + if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << (port * 2), mode)) != RT_ERR_OK) + return retVal; + }else if(port >= 8){ + regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); + if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << ((port-8) * 2), mode)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicForceLed + * Description: + * Get group LED mode + * Input: + * port - Physical port number (0~7) + * group - LED group number + * pMode - LED mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode) +{ + rtk_uint16 regAddr; + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(group >= RTL8367C_LEDGROUPNO) + return RT_ERR_INPUT; + + /* Get Related Registers */ + if(port < 8){ + regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); + if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << (port * 2), pMode)) != RT_ERR_OK) + return retVal; + }else if(port >= 8){ + regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); + if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << ((port-8) * 2), pMode)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicForceGroupLed + * Description: + * Turn on/off Led of all ports + * Input: + * group - LED group number + * mode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode) +{ + ret_t retVal; + rtk_uint32 i,bitmask; + CONST rtk_uint16 bits[3]= {0x0004,0x0010,0x0040}; + + /* Invalid input parameter */ + if(groupmask > RTL8367C_LEDGROUPMASK) + return RT_ERR_OUT_OF_RANGE; + + if(mode >= LEDFORCEMODE_END) + return RT_ERR_OUT_OF_RANGE; + + bitmask = 0; + for(i = 0; i < RTL8367C_LEDGROUPNO; i++) + { + if(groupmask & (1 << i)) + { + bitmask = bitmask | bits[i]; + } + + } + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, bitmask); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, mode); + + if(LEDFORCEMODE_NORMAL == mode) + retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, 0); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicForceGroupLed + * Description: + * Turn on/off Led of all ports + * Input: + * group - LED group number + * pMode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode) +{ + ret_t retVal; + rtk_uint32 i,regData; + CONST rtk_uint16 bits[3] = {0x0004,0x0010,0x0040}; + + /* Get Related Registers */ + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, ®Data)) != RT_ERR_OK) + return retVal; + + for(i = 0; i< RTL8367C_LEDGROUPNO; i++) + { + if((regData & bits[i]) == bits[i]) + { + *groupmask = *groupmask | (1 << i); + } + } + + return rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicLedBlinkRate + * Description: + * Set led blinking rate at mode 0 to mode 3 + * Input: + * blinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * LED blink rate can be at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms + */ +ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate) +{ + if(blinkRate >= LEDBLINKRATE_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, blinkRate); +} +/* Function Name: + * rtl8367c_getAsicLedBlinkRate + * Description: + * Get led blinking rate at mode 0 to mode 3 + * Input: + * pBlinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, pBlinkRate); +} +/* Function Name: + * rtl8367c_setAsicLedForceBlinkRate + * Description: + * Set LEd blinking rate for force mode led + * Input: + * blinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate) +{ + if(blinkRate >= LEDFORCERATE_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, blinkRate); +} +/* Function Name: + * rtl8367c_getAsicLedForceBlinkRate + * Description: + * Get LED blinking rate for force mode led + * Input: + * pBlinkRate - Support 6 blink rates + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, pBlinkRate); +} + +/* +@func ret_t | rtl8367c_setAsicLedGroupEnable | Turn on/off Led of all system ports +@parm rtk_uint32 | group | LED group id. +@parm rtk_uint32 | portmask | LED port mask. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. + */ +ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regDataMask; + + if ( group >= RTL8367C_LEDGROUPNO ) + return RT_ERR_INPUT; + + regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; + regDataMask = 0xFF << ((group%2)*8); + retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, portmask&0xff); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_REG_PARA_LED_IO_EN3; + regDataMask = 0x3 << (group*2); + retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_getAsicLedGroupEnable | Get on/off status of Led of all system ports +@parm rtk_uint32 | group | LED group id. +@parm rtk_uint32 | *portmask | LED port mask. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_PORT_ID | Invalid port number. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. + */ +ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regDataMask,regData; + + if ( group >= RTL8367C_LEDGROUPNO ) + return RT_ERR_INPUT; + + regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; + regDataMask = 0xFF << ((group%2)*8); + retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, portmask); + if(retVal != RT_ERR_OK) + return retVal; + + + regAddr = RTL8367C_REG_PARA_LED_IO_EN3; + regDataMask = 0x3 << (group*2); + retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *portmask = (regData << 8) | *portmask; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_setAsicLedOperationMode | Set LED operation mode +@parm rtk_uint32 | mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off led serial mode and set signal to active high/low. + */ +ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode) +{ + ret_t retVal; + + /* Invalid input parameter */ + if( mode >= LEDOP_END) + return RT_ERR_INPUT; + + switch(mode) + { + case LEDOP_PARALLEL: + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 0))!= RT_ERR_OK) + return retVal; + /*Disable serial CLK mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 0))!= RT_ERR_OK) + return retVal; + /*Disable serial DATA mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 0))!= RT_ERR_OK) + return retVal; + break; + case LEDOP_SERIAL: + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 1))!= RT_ERR_OK) + return retVal; + /*Enable serial CLK mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 1))!= RT_ERR_OK) + return retVal; + /*Enable serial DATA mode*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 1))!= RT_ERR_OK) + return retVal; + break; + default: + return RT_ERR_INPUT; + break; + } + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_getAsicLedOperationMode | Get LED OP mode setup +@parm rtk_uint32*| mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can get LED serial mode setup and get signal active high/low. + */ +ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode) +{ + ret_t retVal; + rtk_uint32 regData; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, ®Data))!= RT_ERR_OK) + return retVal; + + if (regData == 1) + *mode = LEDOP_SERIAL; + else if (regData == 0) + *mode = LEDOP_PARALLEL; + else + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* +@func ret_t | rtl8367c_setAsicLedSerialModeConfig | Set LED serial mode +@parm rtk_uint32 | active | Active High or Low. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off led serial mode and set signal to active high/low. + */ +ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode) +{ + ret_t retVal; + + /* Invalid input parameter */ + if( active >= LEDSERACT_MAX) + return RT_ERR_INPUT; + if( serimode >= LEDSER_MAX) + return RT_ERR_INPUT; + + /* Set Active High or Low */ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active)) != RT_ERR_OK) + return retVal; + + /*set to 8G mode (not 16G mode)*/ + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_getAsicLedSerialModeConfig | Get LED serial mode setup +@parm rtk_uint32*| active | Active High or Low. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can get LED serial mode setup and get signal active high/low. + */ +ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active))!= RT_ERR_OK) + return retVal; + + /*get to 8G mode (not 16G mode)*/ + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* +@func ret_t | rtl8367c_setAsicLedOutputEnable | Set LED output enable +@parm rtk_uint32 | enabled | enable or disalbe. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can turn on/off LED output Enable + */ +ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled) +{ + ret_t retVal; + rtk_uint32 regdata; + + if (enabled == 1) + regdata = 0; + else + regdata = 1; + + /* Enable/Disable H/W IGMP/MLD */ + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, regdata); + + return retVal; +} + + +/* +@func ret_t | rtl8367c_getAsicLedOutputEnable | Get LED serial mode setup +@parm rtk_uint32*| active | Active High or Low. +@rvalue RT_ERR_OK | Success. +@rvalue RT_ERR_SMI | SMI access error. +@rvalue RT_ERR_INPUT | Invalid input value. +@comm + The API can get LED serial mode setup and get signal active high/low. + */ +ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled) +{ + ret_t retVal; + rtk_uint32 regdata; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, ®data); + if (retVal != RT_ERR_OK) + return retVal; + + if (regdata == 1) + *ptr_enabled = 0; + else + *ptr_enabled = 1; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLedSerialOutput + * Description: + * Set serial LED output group and portmask. + * Input: + * output - Serial LED output group + * pmask - Serial LED output portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, output); + if (retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pmask); + if (retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicLedSerialOutput + * Description: + * Get serial LED output group and portmask. + * Input: + * None + * Output: + * pOutput - Serial LED output group + * pPmask - Serial LED output portmask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask) +{ + ret_t retVal; + + if(pOutput == NULL) + return RT_ERR_NULL_POINTER; + + if(pPmask == NULL) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, pOutput); + if (retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pPmask); + if (retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c new file mode 100755 index 00000000..343a6f15 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c @@ -0,0 +1,1549 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : LUT related functions + * + */ + +#include + +#include + +static void _rtl8367c_fdbStUser2Smi( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) +{ + /* L3 lookup */ + if(pLutSt->l3lookup) + { + if(pLutSt->l3vidlookup) + { + pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); + pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; + + pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); + pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; + + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; + + pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); + pFdbSmi[4] |= (pLutSt->l3_vid & 0x00FF) << 8; + + pFdbSmi[5] |= ((pLutSt->l3_vid & 0x0F00) >> 8); + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; + } + else + { + pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); + pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; + + pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); + pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; + + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; + + pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); + pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; + + pFdbSmi[5] |= (pLutSt->igmp_asic & 0x0001); + pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; + pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; + } + } + else if(pLutSt->mac.octet[0] & 0x01) /*Multicast L2 Lookup*/ + { + pFdbSmi[0] |= pLutSt->mac.octet[5]; + pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; + + pFdbSmi[1] |= pLutSt->mac.octet[3]; + pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; + + pFdbSmi[2] |= pLutSt->mac.octet[1]; + pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; + + pFdbSmi[3] |= pLutSt->cvid_fid; + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; + + pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); + pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; + + pFdbSmi[5] |= pLutSt->igmp_asic; + pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; + pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; + } + else /*Asic auto-learning*/ + { + pFdbSmi[0] |= pLutSt->mac.octet[5]; + pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; + + pFdbSmi[1] |= pLutSt->mac.octet[3]; + pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; + + pFdbSmi[2] |= pLutSt->mac.octet[1]; + pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; + + pFdbSmi[3] |= pLutSt->cvid_fid; + pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; + pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; + pFdbSmi[3] |= ((pLutSt->spa & 0x0008) >> 3) << 15; + + pFdbSmi[4] |= pLutSt->efid; + pFdbSmi[4] |= (pLutSt->fid & 0x000F) << 3; + pFdbSmi[4] |= (pLutSt->sa_en & 0x0001) << 7; + pFdbSmi[4] |= (pLutSt->spa & 0x0007) << 8; + pFdbSmi[4] |= (pLutSt->age & 0x0007) << 11; + pFdbSmi[4] |= (pLutSt->auth & 0x0001) << 14; + pFdbSmi[4] |= (pLutSt->sa_block & 0x0001) << 15; + + pFdbSmi[5] |= pLutSt->da_block; + pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; + pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; + pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; + } +} + + +static void _rtl8367c_fdbStSmi2User( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) +{ + /*L3 lookup*/ + if(pFdbSmi[3] & 0x1000) + { + if(pFdbSmi[3] & 0x2000) + { + pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); + pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); + + pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); + pLutSt->l3_vid = ((pFdbSmi[4] & 0xFF00) >> 8) | (pFdbSmi[5] & 0x000F); + + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->l3vidlookup = (pFdbSmi[3] & 0x2000) >> 13; + pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; + } + else + { + pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); + pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); + + pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; + pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; + + pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); + pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; + + pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; + } + } + else if(pFdbSmi[2] & 0x0100) /*Multicast L2 Lookup*/ + { + pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; + pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); + pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; + pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); + pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; + pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); + + pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; + pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; + pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; + + pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); + pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; + + pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; + pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; + } + else /*Asic auto-learning*/ + { + pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; + pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); + pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; + pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); + pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; + pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); + + pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; + pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; + pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; + + pLutSt->sa_en = (pFdbSmi[4] & 0x0080) >> 7; + pLutSt->auth = (pFdbSmi[4] & 0x4000) >> 14; + pLutSt->spa = ((pFdbSmi[4] & 0x0700) >> 8) | (((pFdbSmi[3] & 0x8000) >> 15) << 3); + pLutSt->age = (pFdbSmi[4] & 0x3800) >> 11; + pLutSt->fid = (pFdbSmi[4] & 0x0078) >> 3; + pLutSt->efid = (pFdbSmi[4] & 0x0007); + pLutSt->sa_block = (pFdbSmi[4] & 0x8000) >> 15; + + pLutSt->da_block = (pFdbSmi[5] & 0x0001); + pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; + pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; + pLutSt->nosalearn = (pFdbSmi[3] & 0x0020) >> 5; + } +} + +/* Function Name: + * rtl8367c_setAsicLutIpMulticastLookup + * Description: + * Set Lut IP multicast lookup function + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicLutIpMulticastLookup + * Description: + * Get Lut IP multicast lookup function + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicLutIpMulticastLookup + * Description: + * Set Lut IP multicast + VID lookup function + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicLutIpMulticastVidLookup + * Description: + * Get Lut IP multicast lookup function + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicLutIpLookupMethod + * Description: + * Set Lut IP lookup hash with DIP or {DIP,SIP} pair + * Input: + * type - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. + * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, type); +} +/* Function Name: + * rtl8367c_getAsicLutIpLookupMethod + * Description: + * Get Lut IP lookup hash with DIP or {DIP,SIP} pair + * Input: + * pType - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. + * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, pType); +} +/* Function Name: + * rtl8367c_setAsicLutAgeTimerSpeed + * Description: + * Set LUT agging out speed + * Input: + * timer - Agging out timer 0:Has been aged out + * speed - Agging out speed 0-fastest 3-slowest + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed) +{ + if(timer>RTL8367C_LUT_AGETIMERMAX) + return RT_ERR_OUT_OF_RANGE; + + if(speed >RTL8367C_LUT_AGESPEEDMAX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_CFG, RTL8367C_AGE_TIMER_MASK | RTL8367C_AGE_SPEED_MASK, (timer << RTL8367C_AGE_TIMER_OFFSET) | (speed << RTL8367C_AGE_SPEED_OFFSET)); +} +/* Function Name: + * rtl8367c_getAsicLutAgeTimerSpeed + * Description: + * Get LUT agging out speed + * Input: + * pTimer - Agging out timer 0:Has been aged out + * pSpeed - Agging out speed 0-fastest 3-slowest + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed) +{ + rtk_uint32 regData; + ret_t retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_LUT_CFG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pTimer = (regData & RTL8367C_AGE_TIMER_MASK) >> RTL8367C_AGE_TIMER_OFFSET; + + *pSpeed = (regData & RTL8367C_AGE_SPEED_MASK) >> RTL8367C_AGE_SPEED_OFFSET; + + return RT_ERR_OK; + +} +/* Function Name: + * rtl8367c_setAsicLutCamTbUsage + * Description: + * Configure Lut CAM table usage + * Input: + * enabled - L2 CAM table usage 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, enabled ? 0 : 1); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicLutCamTbUsage + * Description: + * Get Lut CAM table usage + * Input: + * pEnabled - L2 CAM table usage 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled) +{ + ret_t retVal; + rtk_uint32 regData; + + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + *pEnabled = regData ? 0 : 1; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicLutLearnLimitNo + * Description: + * Set per-Port auto learning limit number + * Input: + * port - Physical port number (0~7) + * number - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_PORTIDMAX, RTL8367C_LUT_LEARNLIMITMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ +ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(number > RTL8367C_LUT_LEARNLIMITMAX) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + if(port < 8) + return rtl8367c_setAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), number); + else + return rtl8367c_setAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, number); + +} +/* Function Name: + * rtl8367c_getAsicLutLearnLimitNo + * Description: + * Get per-Port auto learning limit number + * Input: + * port - Physical port number (0~7) + * pNumber - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_PORTIDMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ +ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), pNumber); + else + return rtl8367c_getAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, pNumber); +} + +/* Function Name: + * rtl8367c_setAsicSystemLutLearnLimitNo + * Description: + * Set system auto learning limit number + * Input: + * number - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_LUT_LEARNLIMITMAX*/ +ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number) +{ + if(number > RTL8367C_LUT_LEARNLIMITMAX) + return RT_ERR_LIMITED_L2ENTRY_NUM; + + return rtl8367c_setAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, number); +} + +/* Function Name: + * rtl8367c_getAsicSystemLutLearnLimitNo + * Description: + * Get system auto learning limit number + * Input: + * port - Physical port number (0~7) + * pNumber - ASIC auto learning entries limit number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber) +{ + if(NULL == pNumber) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, pNumber); +} + +/* Function Name: + * rtl8367c_setAsicLutLearnOverAct + * Description: + * Set auto learn over limit number action + * Input: + * action - Learn over action 0:normal, 1:drop 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * None + */ +ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action) +{ + if(action >= LRNOVERACT_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, action); +} +/* Function Name: + * rtl8367c_getAsicLutLearnOverAct + * Description: + * Get auto learn over limit number action + * Input: + * pAction - Learn over action 0:normal, 1:drop 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, pAction); +} + +/* Function Name: + * rtl8367c_setAsicSystemLutLearnOverAct + * Description: + * Set system auto learn over limit number action + * Input: + * action - Learn over action 0:normal, 1:drop, 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid learn over action + * Note: + * None + */ +ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action) +{ + if(action >= LRNOVERACT_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, action); +} + +/* Function Name: + * rtl8367c_getAsicSystemLutLearnOverAct + * Description: + * Get system auto learn over limit number action + * Input: + * pAction - Learn over action 0:normal, 1:drop 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction) +{ + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, pAction); +} + +/* Function Name: + * rtl8367c_setAsicSystemLutLearnPortMask + * Description: + * Set system auto learn limit port mask + * Input: + * portmask - port mask of system learning limit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Error port mask + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ +ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask) +{ + ret_t retVal; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, (portmask>>8) & 0x7); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_getAsicSystemLutLearnPortMask + * Description: + * Get system auto learn limit port mask + * Input: + * None + * Output: + * pPortmask - port mask of system learning limit + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None + */ + /*ÐÞ¸Ä: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ +ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpmask; + ret_t retVal; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, &tmpmask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpmask & 0xff; + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, &tmpmask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpmask & 0x7) << 8; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicL2LookupTb + * Description: + * Set filtering database entry + * Input: + * pL2Table - L2 table entry writing to 8K+64 filtering database + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; + rtk_uint32 tblCmd; + rtk_uint32 busyCounter; + + memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); + _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!regData) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + accessPtr = smil2Table; + regData = *accessPtr; + for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + + } + + tblCmd = (RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK); + /* Write Command */ + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); + if(retVal != RT_ERR_OK) + return retVal; + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!regData) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + /*Read access status*/ + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_hit = regData; + if(!pL2Table->lookup_hit) + return RT_ERR_FAILED; + + /*Read access address*/ + /* + retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->address = regData;*/ + + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); + pL2Table->lookup_busy = 0; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicL2LookupTb + * Description: + * Get filtering database entry + * Input: + * pL2Table - L2 table entry writing to 2K+64 filtering database + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving + * Note: + * None + */ +ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16* accessPtr; + rtk_uint32 i; + rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; + rtk_uint32 busyCounter; + rtk_uint32 tblCmd; + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!pL2Table->lookup_busy) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + + tblCmd = (method << RTL8367C_ACCESS_METHOD_OFFSET) & RTL8367C_ACCESS_METHOD_MASK; + + switch(method) + { + case LUTREADMETHOD_ADDRESS: + case LUTREADMETHOD_NEXT_ADDRESS: + case LUTREADMETHOD_NEXT_L2UC: + case LUTREADMETHOD_NEXT_L2MC: + case LUTREADMETHOD_NEXT_L3MC: + case LUTREADMETHOD_NEXT_L2L3MC: + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, pL2Table->address); + if(retVal != RT_ERR_OK) + return retVal; + break; + case LUTREADMETHOD_MAC: + memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); + _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); + + accessPtr = smil2Table; + regData = *accessPtr; + for(i=0; iaddress); + if(retVal != RT_ERR_OK) + return retVal; + + tblCmd = tblCmd | ((pL2Table->spa << RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET) & RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK); + + break; + default: + return RT_ERR_INPUT; + } + + tblCmd = tblCmd | ((RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK)); + /* Read Command */ + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); + if(retVal != RT_ERR_OK) + return retVal; + + if(pL2Table->wait_time == 0) + busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; + else + busyCounter = pL2Table->wait_time; + + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->lookup_busy = regData; + if(!pL2Table->lookup_busy) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + pL2Table->lookup_hit = regData; + if(!pL2Table->lookup_hit) + return RT_ERR_L2_ENTRY_NOTFOUND; + + /*Read access address*/ + //retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); + + /*read L2 entry */ + memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); + + accessPtr = smil2Table; + + for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + accessPtr ++; + } + + _rtl8367c_fdbStSmi2User(pL2Table, smil2Table); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicLutLearnNo + * Description: + * Get per-Port auto learning number + * Input: + * port - Physical port number (0~7) + * pNumber - ASIC auto learning entries number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸ÄRTL8367C_PORTIDMAX, RTL8367C_REG_L2_LRN_CNT_REG, port10 reg is not contnious, wait for updating of base.h*/ +ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 10) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_REG(port), pNumber); + if (retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_CTRL10, pNumber); + if (retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLutFlushAll + * Description: + * Flush all entries in LUT. Includes static & dynamic entries + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushAll(void) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, 1); +} + +/* Function Name: + * rtl8367c_getAsicLutFlushAllStatus + * Description: + * Get Flush all status, 1:Busy, 0 normal + * Input: + * None + * Output: + * pBusyStatus - Busy state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus) +{ + if(NULL == pBusyStatus) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, pBusyStatus); +} + +/* Function Name: + * rtl8367c_setAsicLutForceFlush + * Description: + * Set per port force flush setting + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ + /*port8~port10µÄÉèÖÃÔÚÁíÍâÒ»¸öregister, wait for updating of base.h, reg.h*/ +ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask) +{ + ret_t retVal; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_FORCE_FLUSH_PORTMASK_MASK, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_PORTMASK1_MASK, (portmask >> 8) & 0x7); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicLutForceFlushStatus + * Description: + * Get per port force flush status + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ + /*port8~port10µÄÉèÖÃÔÚÁíÍâÒ»¸öregister, wait for updating of base.h, reg.h*/ +ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpMask; + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_BUSY_STATUS_MASK,&tmpMask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpMask & 0xff; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_BUSY_STATUS1_MASK,&tmpMask); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpMask & 7) << 8; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicLutFlushMode + * Description: + * Set user force L2 pLutSt table flush mode + * Input: + * mode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Actions not allowed by the function + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode) +{ + if( mode >= FLUSHMDOE_END ) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicLutFlushMode + * Description: + * Get user force L2 pLutSt table flush mode + * Input: + * pMode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicLutFlushType + * Description: + * Get L2 LUT flush type + * Input: + * type - 0: dynamice unicast; 1: both dynamic and static unicast entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,type); +} +/* Function Name: + * rtl8367c_getAsicLutFlushType + * Description: + * Set L2 LUT flush type + * Input: + * pType - 0: dynamice unicast; 1: both dynamic and static unicast entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,pType); +} + + +/* Function Name: + * rtl8367c_setAsicLutFlushVid + * Description: + * Set VID of Port + VID pLutSt flush mode + * Input: + * vid - Vid (0~4095) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid) +{ + if( vid > RTL8367C_VIDMAX ) + return RT_ERR_VLAN_VID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, vid); +} +/* Function Name: + * rtl8367c_getAsicLutFlushVid + * Description: + * Get VID of Port + VID pLutSt flush mode + * Input: + * pVid - Vid (0~4095) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, pVid); +} +/* Function Name: + * rtl8367c_setAsicPortFlusdFid + * Description: + * Set FID of Port + FID pLutSt flush mode + * Input: + * fid - FID/MSTI for force flush + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid FID (0~15) + * Note: + * None + */ +ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid) +{ + if( fid > RTL8367C_FIDMAX ) + return RT_ERR_L2_FID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, fid); +} +/* Function Name: + * rtl8367c_getAsicLutFlushFid + * Description: + * Get FID of Port + FID pLutSt flush mode + * Input: + * pFid - FID/MSTI for force flush + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, pFid); +} +/* Function Name: + * rtl8367c_setAsicLutDisableAging + * Description: + * Set L2 LUT aging per port setting + * Input: + * port - Physical port number (0~7) + * disabled - 0: enable aging; 1: disabling aging + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸ÄRTL8367C_PORTIDMAX*/ +ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, disabled); +} +/* Function Name: + * rtl8367c_getAsicLutDisableAging + * Description: + * Get L2 LUT aging per port setting + * Input: + * port - Physical port number (0~7) + * pDisabled - 0: enable aging; 1: disabling aging + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ + /*ÐÞ¸ÄRTL8367C_PORTIDMAX*/ +ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, pDisabled); +} + +/* Function Name: + * rtl8367c_setAsicLutIPMCGroup + * Description: + * Set IPMC Group Table + * Input: + * index - the entry index in table (0 ~ 63) + * group_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) + * vid - VLAN ID + * pmask - portmask + * valid - valid bit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid) +{ + rtk_uint32 regAddr, regData, bitoffset; + ipaddr_t ipData; + ret_t retVal; + + if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) + return RT_ERR_INPUT; + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + ipData = group_addr; + + if( (ipData & 0xF0000000) != 0xE0000000) /* not in 224.0.0.0 ~ 239.255.255.255 */ + return RT_ERR_INPUT; + + /* Group Address */ + regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); + regData = ((ipData & 0x0FFFFFFF) >> 16); + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + regAddr++; + regData = (ipData & 0x0000FFFF); + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + /* VID */ + regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; + regData = vid; + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + /* portmask */ + regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; + regData = pmask; + + if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) + return retVal; + + /* valid */ + regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); + bitoffset = index % 16; + if( (retVal = rtl8367c_setAsicRegBit(regAddr, bitoffset, valid)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicLutIPMCGroup + * Description: + * Set IPMC Group Table + * Input: + * index - the entry index in table (0 ~ 63) + * Output: + * pGroup_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) + * pVid - VLAN ID + * pPmask - portmask + * pValid - Valid bit + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid) +{ + rtk_uint32 regAddr, regData, bitoffset; + ipaddr_t ipData; + ret_t retVal; + + if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) + return RT_ERR_INPUT; + + if (NULL == pGroup_addr) + return RT_ERR_NULL_POINTER; + + if (NULL == pVid) + return RT_ERR_NULL_POINTER; + + if (NULL == pPmask) + return RT_ERR_NULL_POINTER; + + /* Group address */ + regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pGroup_addr = (((regData & 0x00000FFF) << 16) | 0xE0000000); + + regAddr++; + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + ipData = (*pGroup_addr | (regData & 0x0000FFFF)); + *pGroup_addr = ipData; + + /* VID */ + regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pVid = regData; + + /* portmask */ + regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; + if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) + return retVal; + + *pPmask = regData; + + /* valid */ + regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); + bitoffset = index % 16; + if( (retVal = rtl8367c_getAsicRegBit(regAddr, bitoffset, ®Data)) != RT_ERR_OK) + return retVal; + + *pValid = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLutLinkDownForceAging + * Description: + * Set LUT link down aging setting. + * Input: + * enable - link down aging setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable) +{ + if(enable > 1) + return RT_ERR_ENABLE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, enable ? 0 : 1); +} + +/* Function Name: + * rtl8367c_getAsicLutLinkDownForceAging + * Description: + * Get LUT link down aging setting. + * Input: + * pEnable - link down aging setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable) +{ + rtk_uint32 value; + ret_t retVal; + + if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, &value)) != RT_ERR_OK) + return retVal; + + *pEnable = value ? 0 : 1; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicLutIpmcFwdRouterPort + * Description: + * Set IPMC packet forward to rounter port also or not + * Input: + * enable - 1: Inlcude router port, 0, exclude router port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE Invalid parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable) +{ + if(enable > 1) + return RT_ERR_ENABLE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, enable); +} + +/* Function Name: + * rtl8367c_getAsicLutIpmcFwdRouterPort + * Description: + * Get IPMC packet forward to rounter port also or not + * Input: + * None + * Output: + * pEnable - 1: Inlcude router port, 0, exclude router port + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable) +{ + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, pEnable); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c new file mode 100755 index 00000000..5412591a --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Shared meter related functions + * + */ +#include +/* Function Name: + * rtl8367c_setAsicShareMeter + * Description: + * Set meter configuration + * Input: + * index - hared meter index (0-31) + * rate - 17-bits rate of share meter, unit is 8Kpbs + * ifg - Including IFG in rate calculation, 1:include 0:exclude + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg) +{ + ret_t retVal; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + { + /*19-bits Rate*/ + retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index), rate&0xFFFF); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index) + 1, (rate &0x70000) >> 16); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), ifg); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + /*19-bits Rate*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), rate&0xFFFF); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, (rate &0x70000) >> 16); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), ifg); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicShareMeter + * Description: + * Get meter configuration + * Input: + * index - hared meter index (0-31) + * pRate - 17-bits rate of share meter, unit is 8Kpbs + * pIfg - Including IFG in rate calculation, 1:include 0:exclude + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg) +{ + rtk_uint32 regData; + rtk_uint32 regData2; + ret_t retVal; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + { + /*17-bits Rate*/ + retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index) + 1, ®Data2); + if(retVal != RT_ERR_OK) + return retVal; + + *pRate = ((regData2 << 16) & 0x70000) | regData; + /*IFG*/ + retVal = rtl8367c_getAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), pIfg); + + return retVal; + } + else + { + /*17-bits Rate*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, ®Data2); + if(retVal != RT_ERR_OK) + return retVal; + + *pRate = ((regData2 << 16) & 0x70000) | regData; + /*IFG*/ + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), pIfg); + + return retVal; + } +} +/* Function Name: + * rtl8367c_setAsicShareMeterBucketSize + * Description: + * Set meter related leaky bucket threshold + * Input: + * index - hared meter index (0-31) + * lbthreshold - Leaky bucket threshold of meter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbthreshold) +{ + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_setAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), lbthreshold); + else + return rtl8367c_setAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, lbthreshold); +} +/* Function Name: + * rtl8367c_getAsicShareMeterBucketSize + * Description: + * Get meter related leaky bucket threshold + * Input: + * index - hared meter index (0-31) + * pLbthreshold - Leaky bucket threshold of meter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbthreshold) +{ + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_getAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), pLbthreshold); + else + return rtl8367c_getAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, pLbthreshold); +} + +/* Function Name: + * rtl8367c_setAsicShareMeterType + * Description: + * Set meter Type + * Input: + * index - shared meter index (0-31) + * Type - 0: kbps, 1: pps + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type) +{ + rtk_uint32 reg; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); + else + reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); + return rtl8367c_setAsicRegBit(reg, index % 16, type); +} + +/* Function Name: + * rtl8367c_getAsicShareMeterType + * Description: + * Get meter Type + * Input: + * index - shared meter index (0-31) + * Output: + * pType - 0: kbps, 1: pps + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType) +{ + rtk_uint32 reg; + + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + if(index < 32) + reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); + else + reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); + return rtl8367c_getAsicRegBit(reg, index % 16, pType); +} + + +/* Function Name: + * rtl8367c_setAsicMeterExceedStatus + * Description: + * Clear shared meter status + * Input: + * index - hared meter index (0-31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index) +{ + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_setAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), 1); + else + return rtl8367c_setAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), 1); + +} +/* Function Name: + * rtl8367c_getAsicMeterExceedStatus + * Description: + * Get shared meter status + * Input: + * index - hared meter index (0-31) + * pStatus - 0: rate doesn't exceed 1: rate exceeds + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * If rate is over rate*8Kbps of a meter, the state bit of this meter is set to 1. + */ +ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus) +{ + if(index > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(index < 32) + return rtl8367c_getAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); + else + return rtl8367c_getAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c new file mode 100755 index 00000000..c9aaa01d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c @@ -0,0 +1,570 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : MIB related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicMIBsCounterReset + * Description: + * Reset global/queue manage or per-port MIB counter + * Input: + * greset - Global reset + * qmreset - Queue maganement reset + * portmask - Port reset mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 regBits; + + regBits = RTL8367C_GLOBAL_RESET_MASK | + RTL8367C_QM_RESET_MASK | + RTL8367C_MIB_PORT07_MASK | + ((rtk_uint32)0x7 << 13); + regData = ((greset << RTL8367C_GLOBAL_RESET_OFFSET) & RTL8367C_GLOBAL_RESET_MASK) | + ((qmreset << RTL8367C_QM_RESET_OFFSET) & RTL8367C_QM_RESET_MASK) | + (((portmask & 0xFF) << RTL8367C_PORT0_RESET_OFFSET) & RTL8367C_MIB_PORT07_MASK) | + (((portmask >> 8)&0x7) << 13); + + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL0, regBits, (regData >> RTL8367C_PORT0_RESET_OFFSET)); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicMIBsCounter + * Description: + * Get MIBs counter + * Input: + * port - Physical port number (0~7) + * mibIdx - MIB counter index + * pCounter - MIB retrived counter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving + * RT_ERR_STAT_CNTR_FAIL - MIB is resetting + * Note: + * Before MIBs counter retrieving, writting accessing address to ASIC at first and check the MIB + * control register status. If busy bit of MIB control is set, that means MIB counter have been + * waiting for preparing, then software must wait atfer this busy flag reset by ASIC. This driver + * did not recycle reading user desired counter. Software must use driver again to get MIB counter + * if return value is not RT_ERR_OK. + */ +ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port, RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint32 mibAddr; + rtk_uint32 mibOff=0; + + /* address offset to MIBs counter */ + CONST rtk_uint16 mibLength[RTL8367C_MIBS_NUMBER]= { + 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 4,2,2,2,2,2,2,2,2, + 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}; + + rtk_uint16 i; + rtk_uint64 mibCounter; + + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(mibIdx >= RTL8367C_MIBS_NUMBER) + return RT_ERR_STAT_INVALID_CNTR; + + if(dot1dTpLearnedEntryDiscards == mibIdx) + { + mibAddr = RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET; + } + else + { + i = 0; + mibOff = RTL8367C_MIB_PORT_OFFSET * port; + + if(port > 7) + mibOff = mibOff + 68; + + while(i < mibIdx) + { + mibOff += mibLength[i]; + i++; + } + + mibAddr = mibOff; + } + + + /*writing access counter address first*/ + /*This address is SRAM address, and SRAM address = MIB register address >> 2*/ + /*then ASIC will prepare 64bits counter wait for being retrived*/ + /*Write Mib related address to access control register*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); + if(retVal != RT_ERR_OK) + return retVal; + + + + /* polling busy flag */ + i = 100; + while(i > 0) + { + /*read MIB control register*/ + retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if((regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) == 0) + { + break; + } + + i--; + } + + if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) + return RT_ERR_BUSYWAIT_TIMEOUT; + + if(regData & RTL8367C_RESET_FLAG_MASK) + return RT_ERR_STAT_CNTR_FAIL; + + mibCounter = 0; + i = mibLength[mibIdx]; + if(4 == i) + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; + else + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + ((mibOff + 1) % 4); + + while(i) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + mibCounter = (mibCounter << 16) | (regData & 0xFFFF); + + regAddr --; + i --; + + } + + *pCounter = mibCounter; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMIBsLogCounter + * Description: + * Get MIBs Loggin counter + * Input: + * index - The index of 32 logging counter (0 ~ 31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Wrong index + * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving + * RT_ERR_STAT_CNTR_FAIL - MIB is resetting + * Note: + * This API get 32 logging counter + */ +ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint32 mibAddr; + rtk_uint16 i; + rtk_uint64 mibCounter; + + if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_ENTRY_INDEX; + + mibAddr = RTL8367C_MIB_LOG_CNT_OFFSET + ((index / 2) * 4); + + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); + if(retVal != RT_ERR_OK) + return retVal; + + /*read MIB control register*/ + retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) + return RT_ERR_BUSYWAIT_TIMEOUT; + + if(regData & RTL8367C_RESET_FLAG_MASK) + return RT_ERR_STAT_CNTR_FAIL; + + mibCounter = 0; + if((index % 2) == 1) + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; + else + regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 1; + + for(i = 0; i <= 1; i++) + { + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + + if(retVal != RT_ERR_OK) + return retVal; + + mibCounter = (mibCounter << 16) | (regData & 0xFFFF); + + regAddr --; + } + + *pCounter = mibCounter; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMIBsControl + * Description: + * Get MIB control register + * Input: + * pMask - MIB control status mask bit[0]-busy bit[1] + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * Software need to check this control register atfer doing port resetting or global resetting + */ +ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pMask = regData & (RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK | RTL8367C_RESET_FLAG_MASK); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicMIBsResetValue + * Description: + * Reset all counter to 0 or 1 + * Input: + * value - Reset to value 0 or 1 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); +} +/* Function Name: + * rtl8367c_getAsicMIBsResetValue + * Description: + * Reset all counter to 0 or 1 + * Input: + * value - Reset to value 0 or 1 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); +} + +/* Function Name: + * rtl8367c_setAsicMIBsUsageMode + * Description: + * MIB update mode + * Input: + * mode - 1: latch all MIBs by timer 0:normal free run counting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicMIBsUsageMode + * Description: + * MIB update mode + * Input: + * pMode - 1: latch all MIBs by timer 0:normal free run counting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, pMode); +} + +/* Function Name: + * rtl8367c_setAsicMIBsTimer + * Description: + * MIB latching timer + * Input: + * timer - latch timer, unit 1 second + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, timer); +} +/* Function Name: + * rtl8367c_getAsicMIBsTimer + * Description: + * MIB latching timer + * Input: + * pTimer - latch timer, unit 1 second + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, pTimer); +} +/* Function Name: + * rtl8367c_setAsicMIBsLoggingMode + * Description: + * MIB logging counter mode + * Input: + * index - logging counter mode index (0~15) + * mode - 0:32-bits mode 1:64-bits mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,mode); +} +/* Function Name: + * rtl8367c_getAsicMIBsLoggingMode + * Description: + * MIB logging counter mode + * Input: + * index - logging counter mode index (0~15) + * pMode - 0:32-bits mode 1:64-bits mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,pMode); +} + +/* Function Name: + * rtl8367c_setAsicMIBsLoggingType + * Description: + * MIB logging counter type + * Input: + * index - logging counter mode index (0~15) + * type - 0:Packet count 1:Byte count + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,type); +} + +/* Function Name: + * rtl8367c_getAsicMIBsLoggingType + * Description: + * MIB logging counter type + * Input: + * index - logging counter mode index (0~15) + * pType - 0:Packet count 1:Byte count + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType) +{ + if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,pType); +} + +/* Function Name: + * rtl8367c_setAsicMIBsResetLoggingCounter + * Description: + * MIB logging counter type + * Input: + * index - logging counter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index) +{ + ret_t retVal; + + if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if(index < 16) + retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_CTRL1, 1< +/* Function Name: + * rtl8367c_setAsicPortMirror + * Description: + * Set port mirror function + * Input: + * source - Source port + * monitor - Monitor (destination) port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor) +{ + ret_t retVal; + + if((source > RTL8367C_PORTIDMAX) || (monitor > RTL8367C_PORTIDMAX)) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, source); + if(retVal != RT_ERR_OK) + return retVal; + + + return rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, monitor); +} +/* Function Name: + * rtl8367c_getAsicPortMirror + * Description: + * Get port mirror function + * Input: + * pSource - Source port + * pMonitor - Monitor (destination) port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, pSource); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, pMonitor); +} +/* Function Name: + * rtl8367c_setAsicPortMirrorRxFunction + * Description: + * Set the mirror function on RX of the mirrored + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorRxFunction + * Description: + * Get the mirror function on RX of the mirrored + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicPortMirrorTxFunction + * Description: + * Set the mirror function on TX of the mirrored + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorTxFunction + * Description: + * Get the mirror function on TX of the mirrored + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicPortMirrorIsolation + * Description: + * Set the traffic isolation on monitor port + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorIsolation + * Description: + * Get the traffic isolation on monitor port + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorMask + * Description: + * Set mirror source port mask + * Input: + * SourcePortmask - Source Portmask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK- Port Mask Error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask) +{ + if( SourcePortmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, SourcePortmask); +} + +/* Function Name: + * rtl8367c_getAsicPortMirrorMask + * Description: + * Get mirror source port mask + * Input: + * None + * Output: + * pSourcePortmask - Source Portmask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK- Port Mask Error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, pSourcePortmask); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorVlanRxLeaky + * Description: + * Set the mirror function of VLAN RX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorVlanRxLeaky + * Description: + * Get the mirror function of VLAN RX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorVlanTxLeaky + * Description: + * Set the mirror function of VLAN TX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorVlanTxLeaky + * Description: + * Get the mirror function of VLAN TX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorIsolationRxLeaky + * Description: + * Set the mirror function of Isolation RX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorIsolationRxLeaky + * Description: + * Get the mirror function of VLAN RX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorIsolationTxLeaky + * Description: + * Set the mirror function of Isolation TX leaky + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorIsolationTxLeaky + * Description: + * Get the mirror function of VLAN TX leaky + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorRealKeep + * Description: + * Set the mirror function of keep format + * Input: + * mode - 1: keep original format, 0: follow VLAN config + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicPortMirrorRealKeep + * Description: + * Get the mirror function of keep format + * Input: + * pMode - 1: keep original format, 0: follow VLAN config + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, pMode); +} + +/* Function Name: + * rtl8367c_setAsicPortMirrorOverride + * Description: + * Set the mirror function of override + * Input: + * rxMirror - 1: output rx Mirror format, 0: output forward format + * txMirror - 1: output tx Mirror format, 0: output forward format + * aclMirror - 1: output ACL Mirror format, 0: output forward format + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, rxMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, txMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, aclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicPortMirrorOverride + * Description: + * Get the mirror function of override + * Input: + * None + * Output: + * pRxMirror - 1: output rx Mirror format, 0: output forward format + * pTxMirror - 1: output tx Mirror format, 0: output forward format + * pAclMirror - 1: output ACL Mirror format, 0: output forward format + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, pRxMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, pTxMirror)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, pAclMirror)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c new file mode 100755 index 00000000..2189b151 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Miscellaneous functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicMacAddress + * Description: + * Set switch MAC address + * Input: + * mac - switch mac + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint8*)&mac; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + for(i = 0; i <=2; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + regData = *accessPtr; + accessPtr ++; + regData = (regData << 8) | *accessPtr; + accessPtr ++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicMacAddress + * Description: + * Get switch MAC address + * Input: + * pMac - switch mac + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint8 *accessPtr; + rtk_uint32 i; + + + accessPtr = (rtk_uint8*)pMac; + + for(i = 0; i <= 2; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = (regData & 0xFF00) >> 8; + accessPtr ++; + *accessPtr = regData & 0xFF; + accessPtr ++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicDebugInfo + * Description: + * Get per-port packet forward debugging information + * Input: + * port - Physical port number (0~7) + * pDebugifo - per-port packet trap/drop/forward reason + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_DEBUG_INFO_REG(port), RTL8367C_DEBUG_INFO_MASK(port), pDebugifo); +} +/* Function Name: + * rtl8367c_setAsicPortJamMode + * Description: + * Set half duplex flow control setting + * Input: + * mode - 0: Back-Pressure 1: DEFER + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET,mode); +} +/* Function Name: + * rtl8367c_getAsicPortJamMode + * Description: + * Get half duplex flow control setting + * Input: + * pMode - 0: Back-Pressure 1: DEFER + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET, pMode); +} + +/* Function Name: + * rtl8367c_setAsicMaxLengthCfg + * Description: + * Set Max packet length configuration + * Input: + * cfgId - Configuration ID + * maxLength - Max Length + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, maxLength); +} + +/* Function Name: + * rtl8367c_getAsicMaxLengthCfg + * Description: + * Get Max packet length configuration + * Input: + * cfgId - Configuration ID + * maxLength - Max Length + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, pMaxLength); +} + +/* Function Name: + * rtl8367c_setAsicMaxLength + * Description: + * Set Max packet length + * Input: + * port - port ID + * type - 0: 10M/100M speed, 1: giga speed + * cfgId - Configuration ID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId) +{ + ret_t retVal; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, cfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, cfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicMaxLength + * Description: + * Get Max packet length + * Input: + * port - port ID + * type - 0: 10M/100M speed, 1: giga speed + * cfgId - Configuration ID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId) +{ + ret_t retVal; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, pCfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, pCfgId); + if(retVal != RT_ERR_OK) + return retVal; + } + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c new file mode 100755 index 00000000..1556f450 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : OAM related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicOamParser + * Description: + * Set OAM parser state + * Input: + * port - Physical port number (0~7) + * parser - Per-Port OAM parser state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid paser state + * Note: + * None + */ +ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(parser > OAM_PARFWDCPU) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port % 8), parser); +} +/* Function Name: + * rtl8367c_getAsicOamParser + * Description: + * Get OAM parser state + * Input: + * port - Physical port number (0~7) + * pParser - Per-Port OAM parser state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port%8), pParser); +} +/* Function Name: + * rtl8367c_setAsicOamMultiplexer + * Description: + * Set OAM multiplexer state + * Input: + * port - Physical port number (0~7) + * multiplexer - Per-Port OAM multiplexer state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid multiplexer state + * Note: + * None + */ +ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(multiplexer > OAM_MULCPU) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), multiplexer); +} +/* Function Name: + * rtl8367c_getAsicOamMultiplexer + * Description: + * Get OAM multiplexer state + * Input: + * port - Physical port number (0~7) + * pMultiplexer - Per-Port OAM multiplexer state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), pMultiplexer); +} +/* Function Name: + * rtl8367c_setAsicOamCpuPri + * Description: + * Set trap priority for OAM packet + * Input: + * priority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, priority); +} +/* Function Name: + * rtl8367c_getAsicOamCpuPri + * Description: + * Get trap priority for OAM packet + * Input: + * pPriority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, pPriority); +} +/* Function Name: + * rtl8367c_setAsicOamEnable + * Description: + * Set OAM function state + * Input: + * enabled - OAM function usage 1:enable, 0:disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicOamEnable + * Description: + * Get OAM function state + * Input: + * pEnabled - OAM function usage 1:enable, 0:disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, pEnabled); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c new file mode 100755 index 00000000..fb4db113 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : PHY related functions + * + */ +#include + +#if defined(MDC_MDIO_OPERATION) +/* Function Name: + * rtl8367c_setAsicPHYOCPReg + * Description: + * Set PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - OCP address + * ocpData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + if((retVal = rtl8367c_setAsicReg(regAddr, ocpData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicPHYOCPReg + * Description: + * Get PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - PHY address + * pRegData - read data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + if((retVal = rtl8367c_getAsicReg(regAddr, pRegData)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +#else + +/* Function Name: + * rtl8367c_setAsicPHYOCPReg + * Description: + * Set PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - OCP address + * ocpData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 busyFlag, checkCounter; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + + /*Check internal phy access busy or not*/ + /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if(retVal != RT_ERR_OK) + return retVal; + + if(busyFlag) + return RT_ERR_BUSYWAIT_TIMEOUT; + + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access data*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA, ocpData); + if(retVal != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /*Set WRITE Command*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK | RTL8367C_RW_MASK); + + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if((retVal != RT_ERR_OK) || busyFlag) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + else + { + checkCounter = 0; + } + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicPHYOCPReg + * Description: + * Get PHY OCP registers + * Input: + * phyNo - Physical port number (0~7) + * ocpAddr - PHY address + * pRegData - read data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 busyFlag,checkCounter; + rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; + /*Check internal phy access busy or not*/ + /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if(retVal != RT_ERR_OK) + return retVal; + + if(busyFlag) + return RT_ERR_BUSYWAIT_TIMEOUT; + + /* OCP prefix */ + ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) + return retVal; + + /*prepare access address*/ + ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); + ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); + regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /*Set READ Command*/ + retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK ); + if(retVal != RT_ERR_OK) + return retVal; + + checkCounter = 100; + while(checkCounter) + { + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); + if((retVal != RT_ERR_OK) || busyFlag) + { + checkCounter --; + if(0 == checkCounter) + return RT_ERR_FAILED; + } + else + { + checkCounter = 0; + } + } + + /*get PHY register*/ + retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_READ_DATA, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *pRegData = regData; + + return RT_ERR_OK; +} + +#endif + +/* Function Name: + * rtl8367c_setAsicPHYReg + * Description: + * Set PHY registers + * Input: + * phyNo - Physical port number (0~7) + * phyAddr - PHY address (0~31) + * phyData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 phyData ) +{ + rtk_uint32 ocp_addr; + + if(phyAddr > RTL8367C_PHY_REGNOMAX) + return RT_ERR_PHY_REG_ID; + + ocp_addr = 0xa400 + phyAddr*2; + + return rtl8367c_setAsicPHYOCPReg(phyNo, ocp_addr, phyData); +} +/* Function Name: + * rtl8367c_getAsicPHYReg + * Description: + * Get PHY registers + * Input: + * phyNo - Physical port number (0~7) + * phyAddr - PHY address (0~31) + * pRegData - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PHY_REG_ID - invalid PHY address + * RT_ERR_PHY_ID - invalid PHY no + * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy + * Note: + * None + */ +ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 *pRegData ) +{ + rtk_uint32 ocp_addr; + + if(phyAddr > RTL8367C_PHY_REGNOMAX) + return RT_ERR_PHY_REG_ID; + + ocp_addr = 0xa400 + phyAddr*2; + + return rtl8367c_getAsicPHYOCPReg(phyNo, ocp_addr, pRegData); +} + + +/* Function Name: + * rtl8367c_setAsicSdsReg + * Description: + * Set Serdes registers + * Input: + * sdsId - sdsid (0~1) + * sdsReg - reg address (0~31) + * sdsPage - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + + * Note: + * None + */ + +ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value) +{ + rtk_uint32 retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0|sdsId)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_getAiscSdsReg + * Description: + * Get Serdes registers + * Input: + * sdsId - sdsid (0~1) + * sdsReg - reg address (0~31) + * sdsPage - Writing data + * Output: + * None + * Return: + * RT_ERR_OK - Success + + * Note: + * None + */ +ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value) +{ + rtk_uint32 retVal, busy; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080|sdsId)) != RT_ERR_OK) + return retVal; + + while(1) + { + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_CMD, &busy))!=RT_ERR_OK) + return retVal; + + if ((busy & 0x100) == 0) + break; + } + + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c new file mode 100755 index 00000000..78e80a0b --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c @@ -0,0 +1,5752 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76333 $ + * $Date: 2017-03-09 09:33:15 +0800 (週四, 09 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port security related functions + * + */ + +#include + +#include + + +#define FIBER2_AUTO_INIT_SIZE 2038 +rtk_uint8 Fiber2_Auto[FIBER2_AUTO_INIT_SIZE] = { +0x02,0x05,0x8F,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x07,0x2C,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, +0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x80,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, +0x12,0x07,0xAB,0x7D,0x81,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0x82,0x7C,0x04, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x60,0x7C,0x69,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x83,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x07,0xAB,0x7D,0x28,0x7C,0x97,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x84, +0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0x85,0x7C,0x9D, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x10,0x7C, +0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x00, +0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x66,0xEF,0x44,0x40,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x66,0xEF,0x54,0xBF,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x66,0xEF,0x54,0xFD,0x54,0xFE, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x66,0xEF,0x44,0x02,0x44,0x01, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x07,0xAB,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, +0xAB,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x07,0xAB,0x12,0x07,0xDB,0x12, +0x01,0x27,0x12,0x06,0x1B,0x12,0x07,0x8A, +0x12,0x06,0xEA,0x7D,0x41,0x7C,0x00,0x7F, +0x36,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, +0xFE,0xFD,0x80,0x26,0x7F,0xFF,0x7E,0xFF, +0x7D,0x05,0x7C,0x00,0x90,0x06,0x24,0x12, +0x01,0x0F,0xC3,0x12,0x00,0xF2,0x50,0x1B, +0x90,0x06,0x24,0x12,0x01,0x03,0xEF,0x24, +0x01,0xFF,0xE4,0x3E,0xFE,0xE4,0x3D,0xFD, +0xE4,0x3C,0xFC,0x90,0x06,0x24,0x12,0x01, +0x1B,0x80,0xD1,0xC2,0x00,0xC2,0x01,0xD2, +0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62,0x12, +0x07,0x66,0xEF,0x30,0xE2,0x07,0xE4,0x90, +0x06,0x2C,0xF0,0x80,0xEE,0x90,0x06,0x2C, +0xE0,0x70,0x12,0x12,0x04,0xF0,0x90,0x06, +0x2C,0x74,0x01,0xF0,0xE4,0x90,0x06,0x33, +0xF0,0xA3,0xF0,0x80,0xD6,0xC3,0x90,0x06, +0x34,0xE0,0x94,0x62,0x90,0x06,0x33,0xE0, +0x94,0x00,0x40,0xC7,0xE4,0xF0,0xA3,0xF0, +0x12,0x04,0xF0,0x90,0x06,0x2C,0x74,0x01, +0xF0,0x80,0xB8,0x75,0x0F,0x80,0x75,0x0E, +0x7E,0x75,0x0D,0xAA,0x75,0x0C,0x83,0xE4, +0xF5,0x10,0x7F,0x36,0x7E,0x13,0x12,0x07, +0x66,0xEE,0xC4,0xF8,0x54,0xF0,0xC8,0xEF, +0xC4,0x54,0x0F,0x48,0x54,0x07,0xFB,0x7A, +0x00,0xEA,0x70,0x4A,0xEB,0x14,0x60,0x1C, +0x14,0x60,0x27,0x24,0xFE,0x60,0x31,0x14, +0x60,0x3C,0x24,0x05,0x70,0x38,0x75,0x0B, +0x00,0x75,0x0A,0xC2,0x75,0x09,0xEB,0x75, +0x08,0x0B,0x80,0x36,0x75,0x0B,0x40,0x75, +0x0A,0x59,0x75,0x09,0x73,0x75,0x08,0x07, +0x80,0x28,0x75,0x0B,0x00,0x75,0x0A,0xE1, +0x75,0x09,0xF5,0x75,0x08,0x05,0x80,0x1A, +0x75,0x0B,0xA0,0x75,0x0A,0xAC,0x75,0x09, +0xB9,0x75,0x08,0x03,0x80,0x0C,0x75,0x0B, +0x00,0x75,0x0A,0x62,0x75,0x09,0x3D,0x75, +0x08,0x01,0x75,0x89,0x11,0xE4,0x7B,0x60, +0x7A,0x09,0xF9,0xF8,0xAF,0x0B,0xAE,0x0A, +0xAD,0x09,0xAC,0x08,0x12,0x00,0x60,0xAA, +0x06,0xAB,0x07,0xC3,0xE4,0x9B,0xFB,0xE4, +0x9A,0xFA,0x78,0x17,0xF6,0xAF,0x03,0xEF, +0x08,0xF6,0x18,0xE6,0xF5,0x8C,0x08,0xE6, +0xF5,0x8A,0x74,0x0D,0x2B,0xFB,0xE4,0x3A, +0x18,0xF6,0xAF,0x03,0xEF,0x08,0xF6,0x75, +0x88,0x10,0x53,0x8E,0xC7,0xD2,0xA9,0x22, +0x7F,0x10,0x7E,0x13,0x12,0x07,0x66,0x90, +0x06,0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE, +0x44,0x10,0xFE,0x90,0x06,0x2D,0xF0,0xA3, +0xEF,0xF0,0x54,0xEF,0xFF,0x90,0x06,0x2D, +0xEE,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F, +0x10,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, +0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF,0x64, +0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C,0x00, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0xE4,0xFD,0xFC, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, +0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xAB,0x7F,0x10,0x7E, +0x13,0x12,0x07,0x66,0x90,0x06,0x2D,0xEE, +0xF0,0xA3,0xEF,0xF0,0xEE,0x54,0xEF,0x90, +0x06,0x2D,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD, +0x7F,0x10,0x7E,0x13,0x02,0x07,0xAB,0x78, +0x7F,0xE4,0xF6,0xD8,0xFD,0x75,0x81,0x3C, +0x02,0x05,0xD6,0x02,0x03,0x2F,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0x40,0x03,0xF6, +0x80,0x01,0xF2,0x08,0xDF,0xF4,0x80,0x29, +0xE4,0x93,0xA3,0xF8,0x54,0x07,0x24,0x0C, +0xC8,0xC3,0x33,0xC4,0x54,0x0F,0x44,0x20, +0xC8,0x83,0x40,0x04,0xF4,0x56,0x80,0x01, +0x46,0xF6,0xDF,0xE4,0x80,0x0B,0x01,0x02, +0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x07, +0xE7,0xE4,0x7E,0x01,0x93,0x60,0xBC,0xA3, +0xFF,0x54,0x3F,0x30,0xE5,0x09,0x54,0x1F, +0xFE,0xE4,0x93,0xA3,0x60,0x01,0x0E,0xCF, +0x54,0xC0,0x25,0xE0,0x60,0xA8,0x40,0xB8, +0xE4,0x93,0xA3,0xFA,0xE4,0x93,0xA3,0xF8, +0xE4,0x93,0xA3,0xC8,0xC5,0x82,0xC8,0xCA, +0xC5,0x83,0xCA,0xF0,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xDF,0xE9,0xDE, +0xE7,0x80,0xBE,0x7D,0x40,0x7C,0x17,0x7F, +0x11,0x7E,0x1D,0x12,0x07,0xAB,0x7F,0x41, +0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, +0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, +0x1D,0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15, +0x7F,0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D, +0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, +0x07,0xAB,0x7D,0x40,0x7C,0x11,0x7F,0x00, +0x7E,0x62,0x12,0x07,0xAB,0x02,0x02,0x2F, +0x7D,0xC0,0x7C,0x16,0x7F,0x11,0x7E,0x1D, +0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15,0x7F, +0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D,0x0D, +0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07, +0xAB,0x7F,0x41,0x7E,0x1D,0x12,0x07,0x66, +0xEF,0x44,0x20,0x44,0x80,0xFD,0xAC,0x06, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0xAB,0x7D, +0x00,0x7C,0x21,0x7F,0x00,0x7E,0x62,0x12, +0x07,0xAB,0x02,0x02,0x2F,0x7D,0x40,0x7C, +0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xAB, +0x7D,0xBB,0x7C,0x15,0x7F,0xEB,0x7E,0x13, +0x12,0x07,0xAB,0x7D,0x0C,0x7C,0x00,0x7F, +0xE7,0x7E,0x13,0x12,0x07,0xAB,0x7F,0x41, +0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, +0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, +0x1D,0x12,0x07,0xAB,0x7D,0x40,0x7C,0x11, +0x7F,0x00,0x7E,0x62,0x12,0x07,0xAB,0x02, +0x02,0x2F,0x7D,0x04,0x7C,0x00,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x80,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, +0x7F,0x02,0x7E,0x66,0x12,0x07,0x66,0xEF, +0x44,0x02,0x44,0x04,0xFD,0xAC,0x06,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x04, +0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x02,0x07,0xAB,0xC0,0xE0,0xC0,0xF0, +0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75,0xD0, +0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5,0x8C, +0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06,0x31, +0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E,0x90, +0x06,0x33,0xE4,0x75,0xF0,0x01,0x12,0x00, +0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82,0xD0, +0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2,0xAF, +0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D,0xA3, +0x75,0xA0,0x01,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xAE,0xA1, +0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7,0xD2, +0xAF,0x22,0x7D,0x20,0x7C,0x0F,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xAB,0x7D,0x01,0x7C, +0x00,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x02,0x07,0xAB,0xC2,0xAF,0xAB,0x07,0xAA, +0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, +0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, +0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x7F, +0x0C,0x7E,0x13,0x12,0x07,0x66,0xEF,0x44, +0x50,0xFD,0xAC,0x06,0x7F,0x0C,0x7E,0x13, +0x02,0x07,0xAB,0x12,0x07,0xC7,0x12,0x07, +0xF2,0x12,0x04,0x2B,0x02,0x00,0x03,0x42, +0x06,0x33,0x00,0x00,0x42,0x06,0x31,0x00, +0x00,0x00,0xE4,0xF5,0x8E,0x22,}; + +#define FIBER2_1G_INIT_SIZE 2032 +rtk_uint8 Fiber2_1G[FIBER2_1G_INIT_SIZE] = { +0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, +0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, +0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, +0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, +0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, +0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, +0x01,0x27,0x12,0x06,0x9F,0x7D,0x41,0x7C, +0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, +0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, +0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, +0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, +0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, +0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, +0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, +0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, +0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, +0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, +0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, +0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, +0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, +0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, +0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, +0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, +0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, +0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, +0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, +0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, +0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, +0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, +0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, +0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, +0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, +0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, +0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, +0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, +0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, +0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, +0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, +0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, +0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, +0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, +0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, +0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, +0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, +0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, +0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, +0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, +0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, +0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, +0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, +0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, +0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, +0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, +0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, +0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, +0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, +0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, +0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, +0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, +0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, +0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, +0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, +0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, +0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, +0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, +0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, +0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, +0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, +0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, +0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, +0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, +0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, +0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, +0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, +0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, +0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, +0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, +0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, +0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, +0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, +0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, +0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, +0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, +0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, +0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, +0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, +0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, +0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, +0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, +0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, +0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, +0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, +0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, +0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, +0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; + +#define FIBER2_100M_INIT_SIZE 2032 +rtk_uint8 Fiber2_100M[FIBER2_100M_INIT_SIZE] = { +0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, +0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, +0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, +0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, +0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, +0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, +0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, +0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, +0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, +0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, +0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, +0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, +0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, +0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, +0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, +0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, +0x01,0x27,0x12,0x06,0x5A,0x7D,0x41,0x7C, +0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, +0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, +0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, +0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, +0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, +0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, +0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, +0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, +0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, +0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, +0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, +0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, +0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, +0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, +0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, +0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, +0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, +0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, +0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, +0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, +0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, +0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, +0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, +0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, +0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, +0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, +0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, +0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, +0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, +0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, +0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, +0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, +0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, +0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, +0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, +0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, +0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, +0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, +0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, +0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, +0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, +0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, +0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, +0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, +0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, +0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, +0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, +0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, +0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, +0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, +0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, +0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, +0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, +0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, +0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, +0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, +0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, +0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, +0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, +0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, +0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, +0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, +0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, +0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, +0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, +0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, +0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, +0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, +0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, +0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, +0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, +0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, +0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, +0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, +0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, +0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, +0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, +0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, +0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, +0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, +0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, +0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, +0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, +0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, +0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, +0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, +0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, +0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, +0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, +0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, +0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, +0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, +0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, +0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, +0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, +0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, +0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, +0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, +0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, +0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, +0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, +0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, +0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, +0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; + + +#define SGMII_INIT_SIZE 1183 +rtk_uint8 Sgmii_Init[SGMII_INIT_SIZE] = { +0x02,0x03,0x81,0xE4,0xF5,0xA8,0xD2,0xAF, +0x22,0x00,0x00,0x02,0x04,0x0D,0xC5,0xF0, +0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, +0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, +0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, +0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, +0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, +0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, +0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, +0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, +0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, +0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, +0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, +0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, +0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, +0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, +0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, +0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, +0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, +0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, +0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, +0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, +0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, +0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, +0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, +0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, +0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, +0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, +0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, +0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, +0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, +0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, +0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, +0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, +0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, +0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0xE4, +0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, +0x3F,0x7E,0x1D,0x12,0x04,0x6B,0x7D,0x40, +0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x04, +0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, +0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, +0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, +0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, +0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, +0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, +0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, +0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, +0x13,0x12,0x04,0x6B,0x12,0x04,0x92,0x7D, +0x41,0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12, +0x04,0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25, +0xE4,0x7F,0x20,0x7E,0x4E,0xFD,0xFC,0x90, +0x06,0x24,0x12,0x01,0x0F,0xC3,0x12,0x00, +0xF2,0x50,0x1B,0x90,0x06,0x24,0x12,0x01, +0x03,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, +0xE4,0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06, +0x24,0x12,0x01,0x1B,0x80,0xD2,0xC2,0x00, +0xC2,0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01, +0x7E,0x62,0x12,0x04,0x47,0xEF,0x30,0xE2, +0x07,0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE, +0x90,0x06,0x2C,0xE0,0x70,0x12,0x12,0x02, +0xDB,0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4, +0x90,0x06,0x2F,0xF0,0xA3,0xF0,0x80,0xD6, +0xC3,0x90,0x06,0x30,0xE0,0x94,0x62,0x90, +0x06,0x2F,0xE0,0x94,0x00,0x40,0xC7,0xE4, +0xF0,0xA3,0xF0,0x12,0x02,0xDB,0x90,0x06, +0x2C,0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F, +0x80,0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75, +0x0C,0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E, +0x13,0x12,0x04,0x47,0xEE,0xC4,0xF8,0x54, +0xF0,0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54, +0x07,0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB, +0x14,0x60,0x1C,0x14,0x60,0x27,0x24,0xFE, +0x60,0x31,0x14,0x60,0x3C,0x24,0x05,0x70, +0x38,0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75, +0x09,0xEB,0x75,0x08,0x0B,0x80,0x36,0x75, +0x0B,0x40,0x75,0x0A,0x59,0x75,0x09,0x73, +0x75,0x08,0x07,0x80,0x28,0x75,0x0B,0x00, +0x75,0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08, +0x05,0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A, +0xAC,0x75,0x09,0xB9,0x75,0x08,0x03,0x80, +0x0C,0x75,0x0B,0x00,0x75,0x0A,0x62,0x75, +0x09,0x3D,0x75,0x08,0x01,0x75,0x89,0x11, +0xE4,0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF, +0x0B,0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12, +0x00,0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4, +0x9B,0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6, +0xAF,0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5, +0x8C,0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B, +0xFB,0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF, +0x08,0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7, +0xD2,0xA9,0x22,0x7D,0x02,0x7C,0x00,0x7F, +0x4A,0x7E,0x13,0x12,0x04,0x6B,0x7D,0x46, +0x7C,0x71,0x7F,0x02,0x7E,0x66,0x12,0x04, +0x6B,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, +0x66,0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00, +0x7F,0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4, +0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF, +0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C, +0x00,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, +0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, +0xFC,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, +0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, +0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, +0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, +0xFC,0x7F,0x4A,0x7E,0x13,0x12,0x04,0x6B, +0x7D,0x06,0x7C,0x71,0x7F,0x02,0x7E,0x66, +0x12,0x04,0x6B,0x7D,0x03,0x7C,0x00,0x7F, +0x01,0x7E,0x66,0x12,0x04,0x6B,0x7D,0xC0, +0x7C,0x00,0x7F,0x00,0x7E,0x66,0x02,0x04, +0x6B,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, +0x81,0x3C,0x02,0x03,0xC8,0x02,0x01,0x27, +0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, +0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, +0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, +0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, +0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, +0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, +0x90,0x04,0x87,0xE4,0x7E,0x01,0x93,0x60, +0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, +0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, +0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, +0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, +0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, +0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, +0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, +0xE9,0xDE,0xE7,0x80,0xBE,0xC0,0xE0,0xC0, +0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, +0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, +0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, +0x2D,0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E, +0x90,0x06,0x2F,0xE4,0x75,0xF0,0x01,0x12, +0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82, +0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, +0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, +0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, +0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, +0xD2,0xAF,0x22,0xC2,0xAF,0xAB,0x07,0xAA, +0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, +0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, +0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x42, +0x06,0x2F,0x00,0x00,0x42,0x06,0x2D,0x00, +0x00,0x00,0x12,0x04,0x9B,0x12,0x02,0x16, +0x02,0x00,0x03,0xE4,0xF5,0x8E,0x22,}; + + +/* Function Name: + * rtl8367c_setAsicPortUnknownDaBehavior + * Description: + * Set UNDA behavior + * Input: + * port - port ID + * behavior - 0: flooding to unknwon DA portmask; 1: drop; 2:trap; 3: flooding + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid behavior + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(behavior >= L2_UNDA_BEHAVE_END) + return RT_ERR_NOT_ALLOWED; + + if(port < 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), behavior); + else + return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), behavior); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownDaBehavior + * Description: + * Get UNDA behavior + * Input: + * port - port ID + * Output: + * pBehavior - 0: flooding to unknwon DA portmask; 1: drop; 2:trap; 3: flooding + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), pBehavior); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), pBehavior); +} +/* Function Name: + * rtl8367c_setAsicPortUnknownSaBehavior + * Description: + * Set UNSA behavior + * Input: + * behavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid behavior + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior) +{ + if(behavior >= L2_BEHAVE_SA_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, behavior); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownSaBehavior + * Description: + * Get UNSA behavior + * Input: + * pBehavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior) +{ + return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, pBehavior); +} +/* Function Name: + * rtl8367c_setAsicPortUnmatchedSaBehavior + * Description: + * Set Unmatched SA behavior + * Input: + * behavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid behavior + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior) +{ + if(behavior >= L2_BEHAVE_SA_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, behavior); +} +/* Function Name: + * rtl8367c_getAsicPortUnmatchedSaBehavior + * Description: + * Get Unmatched SA behavior + * Input: + * pBehavior - 0: flooding; 1: drop; 2:trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior) +{ + return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, pBehavior); +} + +/* Function Name: + * rtl8367c_setAsicPortUnmatchedSaMoving + * Description: + * Set Unmatched SA moving state + * Input: + * port - Port ID + * enabled - 0: can't move to new port; 1: can move to new port + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Error Port ID + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, (enabled == 1) ? 0 : 1); +} + +/* Function Name: + * rtl8367c_getAsicPortUnmatchedSaMoving + * Description: + * Get Unmatched SA moving state + * Input: + * port - Port ID + * Output: + * pEnabled - 0: can't move to new port; 1: can move to new port + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Error Port ID + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + rtk_uint32 data; + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, &data)) != RT_ERR_OK) + return retVal; + + *pEnabled = (data == 1) ? 0 : 1; + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicPortUnknownDaFloodingPortmask + * Description: + * Set UNDA flooding portmask + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownDaFloodingPortmask + * Description: + * Get UNDA flooding portmask + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortUnknownMulticastFloodingPortmask + * Description: + * Set UNMC flooding portmask + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicPortUnknownMulticastFloodingPortmask + * Description: + * Get UNMC flooding portmask + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortBcastFloodingPortmask + * Description: + * Set Bcast flooding portmask + * Input: + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicPortBcastFloodingPortmask + * Description: + * Get Bcast flooding portmask + * Input: + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortBlockSpa + * Description: + * Set disabling blocking frame if source port and destination port are the same + * Input: + * port - Physical port number (0~7) + * permit - 0: block; 1: permit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 permit) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, permit); +} +/* Function Name: + * rtl8367c_getAsicPortBlockSpa + * Description: + * Get disabling blocking frame if source port and destination port are the same + * Input: + * port - Physical port number (0~7) + * pPermit - 0: block; 1: permit + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32* pPermit) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, pPermit); +} +/* Function Name: + * rtl8367c_setAsicPortDos + * Description: + * Set DOS function + * Input: + * type - DOS type + * drop - 0: permit; 1: drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid payload index + * Note: + * None + */ +ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop) +{ + if(type >= DOS_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type, drop); +} +/* Function Name: + * rtl8367c_getAsicPortDos + * Description: + * Get DOS function + * Input: + * type - DOS type + * pDrop - 0: permit; 1: drop + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid payload index + * Note: + * None + */ +ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop) +{ + if(type >= DOS_END) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type,pDrop); +} +/* Function Name: + * rtl8367c_setAsicPortForceLink + * Description: + * Set port force linking configuration + * Input: + * port - Physical port number (0~7) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) +{ + rtk_uint32 regData = 0; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + regData |= pPortAbility->forcemode << 12; + regData |= pPortAbility->mstfault << 9; + regData |= pPortAbility->mstmode << 8; + regData |= pPortAbility->nway << 7; + regData |= pPortAbility->txpause << 6; + regData |= pPortAbility->rxpause << 5; + regData |= pPortAbility->link << 4; + regData |= pPortAbility->duplex << 2; + regData |= pPortAbility->speed; + + return rtl8367c_setAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT+port, regData); +} +/* Function Name: + * rtl8367c_getAsicPortForceLink + * Description: + * Get port force linking configuration + * Input: + * port - Physical port number (0~7) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) +{ + ret_t retVal; + rtk_uint32 regData; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT + port, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (regData >> 12) & 0x0001; + pPortAbility->mstfault = (regData >> 9) & 0x0001; + pPortAbility->mstmode = (regData >> 8) & 0x0001; + pPortAbility->nway = (regData >> 7) & 0x0001; + pPortAbility->txpause = (regData >> 6) & 0x0001; + pPortAbility->rxpause = (regData >> 5) & 0x0001; + pPortAbility->link = (regData >> 4) & 0x0001; + pPortAbility->duplex = (regData >> 2) & 0x0001; + pPortAbility->speed = regData & 0x0003; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortStatus + * Description: + * Get port link status + * Input: + * port - Physical port number (0~7) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus) +{ + ret_t retVal; + rtk_uint32 regData; + + /* Invalid input parameter */ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT0_STATUS+port,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pPortStatus->lpi1000 = (regData >> 11) & 0x0001; + pPortStatus->lpi100 = (regData >> 10) & 0x0001; + pPortStatus->mstfault = (regData >> 9) & 0x0001; + pPortStatus->mstmode = (regData >> 8) & 0x0001; + pPortStatus->nway = (regData >> 7) & 0x0001; + pPortStatus->txpause = (regData >> 6) & 0x0001; + pPortStatus->rxpause = (regData >> 5) & 0x0001; + pPortStatus->link = (regData >> 4) & 0x0001; + pPortStatus->duplex = (regData >> 2) & 0x0001; + pPortStatus->speed = regData & 0x0003; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortForceLinkExt + * Description: + * Set external interface force linking configuration + * Input: + * id - external interface id (0~2) + * portAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) +{ + rtk_uint32 retVal, regValue, regValue2, type, sgmiibit, hisgmiibit; + rtk_uint32 reg_data = 0; + rtk_uint32 i = 0; + + /* Invalid input parameter */ + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + + reg_data |= pPortAbility->forcemode << 12; + reg_data |= pPortAbility->mstfault << 9; + reg_data |= pPortAbility->mstmode << 8; + reg_data |= pPortAbility->nway << 7; + reg_data |= pPortAbility->txpause << 6; + reg_data |= pPortAbility->rxpause << 5; + reg_data |= pPortAbility->link << 4; + reg_data |= pPortAbility->duplex << 2; + reg_data |= pPortAbility->speed; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + /*get chip ID */ + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + if (1 == type) + { + if(1 == id) + { + if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_REG_TO_ECO4, ®Value)) != RT_ERR_OK) + return retVal; + + if((regValue & (0x0001 << 5)) && (regValue & (0x0001 << 7))) + { + return RT_ERR_OK; + } + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + } + + if(0 == id || 1 == id) + return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE + id, reg_data); + else + return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, reg_data); + } + else if (2 == type) + { + if (1 == id) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + } + else if (2 == id) + { + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1dc1, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + } + + } + else if(3 == type) + { + if(1 == id) + { + if((retVal = rtl8367c_getAsicRegBit(0x1d11, 6, &sgmiibit)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, &hisgmiibit)) != RT_ERR_OK) + return retVal; + + if ((sgmiibit == 1) || (hisgmiibit == 1)) + { + /*for 1000x/100fx/1000x_100fx, param has to be set to serdes registers*/ + if((retVal = rtl8367c_getAsicReg(0x1d41, ®Value)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib =1, bit7: cfg_mac6_fib2=1*/ + if((regValue & 0xa0) == 0xa0) + { + /* new_cfg_sds_mode */ + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + + /*1000X*/ + if(regValue2 == 0x4) + { +#if 0 + /* new_cfg_sds_mode:reset mode */ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + /* Enable new sds mode config */ + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= (~0x80); + + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= (~0x100); + + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*new_cfg_sds_mode=1000x*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x5) + { +#if 0 + /*100FX*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + /*cfg_sds_mode_sel_new=1 */ + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= (~0x80); + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= (~0x100); + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + /* new_cfg_sds_mode=1000x */ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x7) + { +#if 0 + /*100FX*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= (~0x80); + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &=(~0x100); + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + /*sds_mode:*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + + } + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + + } + + /* new_cfg_sds_mode */ + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + if(regValue2 == 0x2) + { +#if 0 + /*SGMII*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + /* 0 2 0 bit 8-9 nway*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xfffffcff; + if (pPortAbility->nway) + reg_data &= 0xfffffcff; + else + reg_data |= 0x100; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + else if(regValue2 == 0x12) + { +#if 0 + /*HiSGMII*/ + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + /* 0 2 0 bit 8-9 nway*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xfffffcff; + if (pPortAbility->nway) + reg_data &= 0xfffffcff; + else + reg_data |= 0x100; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + if((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0x1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + + } + } + else + { + if((retVal = rtl8367c_getAsicRegBits(0x1d3d, 10, ®Value2)) != RT_ERR_OK) + return retVal; + if (regValue2 == 0) + { + /*ext1_force_ablty*/ + if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + /*force mode for ext1*/ + if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + + + } + else if (2 == id) + { + + if((retVal = rtl8367c_getAsicRegBit(0x1d95, 0, &sgmiibit)) != RT_ERR_OK) + return retVal; + if (sgmiibit == 1) + { + /*for 1000x/100fx/1000x_100fx, param has to bet set to serdes registers*/ + if((retVal = rtl8367c_getAsicReg(0x1d95, ®Value)) != RT_ERR_OK) + return retVal; + /*cfg_mac7_sel_sgmii=1 & cfg_mac7_fib =1*/ + if((regValue & 0x3) == 0x3) + { + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + + if(regValue2 == 0x4) + { + /*1000X*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x5) + { + /*100FX*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + + } + else if(regValue2 == 0x7) + { + /*100FX*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0x9000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFDFFF; + reg_data |= 0x40; + if(pPortAbility->forcemode) + reg_data &= 0xffffefff; + else + reg_data |= 0x1000; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFF0FFF; + reg_data |= 0xB000; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFFBF; + reg_data |= 0x2000; + reg_data &= 0xffffefff; + + if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) + return retVal; + if (pPortAbility->txpause) + reg_data |= 0x80; + else + reg_data &= 0xffffff7f; + if (pPortAbility->rxpause) + reg_data |= 0x100; + else + reg_data &= 0xfffffeff; + if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) + return retVal; + + /* 0 4 0 bit 12 set 0*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFEFFF; + if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + + } + + if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + + } + /* new_cfg_sds_mode */ + if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) + return retVal; + if(regValue2 == 0x2) + { + /*SGMII*/ +#if 0 + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; +#endif + if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + /* 0 2 0 bit 8-9 nway*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xfffffcff; + if (pPortAbility->nway) + reg_data &= 0xfffffcff; + else + reg_data |= 0x100; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + for(i=0;i<0xfff; i++); + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + else + { + + /*ext2_force_ablty*/ + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + /*force mode for ext2*/ + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + + + if((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + /*force mode for ext1*/ + if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) + return retVal; + + if (pPortAbility->link == 1) + { + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) + return retVal; + } + } + + + } + + /*disable force ability --- */ + if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) + return retVal; + } +#if 0 + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) + return retVal; +#endif + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortForceLinkExt + * Description: + * Get external interface force linking configuration + * Input: + * id - external interface id (0~1) + * pPortAbility - port ability configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) +{ + rtk_uint32 reg_data, regValue, type; + rtk_uint32 sgmiiSel; + rtk_uint32 hsgmiiSel; + ret_t retVal; + + /* Invalid input parameter */ + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + /*cfg_magic_id & get chip_id*/ + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + if (1 == type) + { + if(1 == id) + { + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, &sgmiiSel)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgmiiSel)) != RT_ERR_OK) + return retVal; + + if( (sgmiiSel == 1) || (hsgmiiSel == 1) ) + { + memset(pPortAbility, 0x00, sizeof(rtl8367c_port_ability_t)); + pPortAbility->forcemode = 1; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->duplex = reg_data; + + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->speed = reg_data; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->link = reg_data; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->txpause = reg_data; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, ®_data)) != RT_ERR_OK) + return retVal; + + pPortAbility->rxpause = reg_data; + + return RT_ERR_OK; + } + } + + if(0 == id || 1 == id) + retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE+id, ®_data); + else + retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, ®_data); + + if(retVal != RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 0x0001; + pPortAbility->mstfault = (reg_data >> 9) & 0x0001; + pPortAbility->mstmode = (reg_data >> 8) & 0x0001; + pPortAbility->nway = (reg_data >> 7) & 0x0001; + pPortAbility->txpause = (reg_data >> 6) & 0x0001; + pPortAbility->rxpause = (reg_data >> 5) & 0x0001; + pPortAbility->link = (reg_data >> 4) & 0x0001; + pPortAbility->duplex = (reg_data >> 2) & 0x0001; + pPortAbility->speed = reg_data & 0x0003; + } + else if (2 == type) + { + if (id == 1) + { + if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + else if (2 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + } + else if (3 == type) + { + if (id == 1) + { + if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + else if (2 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) + return retVal; + + pPortAbility->forcemode = (reg_data >> 12) & 1; + pPortAbility->duplex = (reg_data >> 2) & 1; + pPortAbility->link = (reg_data >> 4) & 1; + pPortAbility->speed = reg_data & 3; + pPortAbility->rxpause = (reg_data >> 5) & 1; + pPortAbility->txpause = (reg_data >> 6) & 1; + } + } + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortExtMode + * Description: + * Set external interface mode configuration + * Input: + * id - external interface id (0~2) + * mode - external interface mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode) +{ + ret_t retVal; + rtk_uint32 i, regValue, type, option,reg_data; + rtk_uint32 idx; + rtk_uint32 redData[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x21A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; + rtk_uint32 redDataSB[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x31A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; + rtk_uint32 redData1[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData5[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData6[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData8[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redData9[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + rtk_uint32 redDataHB[][2] = { {0x82F0, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x7960, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; + + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + + if(mode >= EXT_END) + return RT_ERR_OUT_OF_RANGE; + + /* magic number*/ + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + /* Chip num */ + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + + if (1==type) + { + if((mode == EXT_1000X_100FX) || (mode == EXT_1000X) || (mode == EXT_100FX)) + { + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 5, 1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 7, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if(mode == EXT_1000X_100FX) + { + for(idx = 0; idx < FIBER2_AUTO_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_Auto[idx])) != RT_ERR_OK) + return retVal; + } + } + + if(mode == EXT_1000X) + { + for(idx = 0; idx < FIBER2_1G_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_1G[idx])) != RT_ERR_OK) + return retVal; + } + } + + if(mode == EXT_100FX) + { + for(idx = 0; idx < FIBER2_100M_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_100M[idx])) != RT_ERR_OK) + return retVal; + } + } + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + + if(mode == EXT_GMII) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT0_RGMXF, RTL8367C_EXT0_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT1_RGMXF, RTL8367C_EXT1_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT1_GMII_TX_DELAY_MASK, 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT0_GMII_TX_DELAY_MASK, 6)) != RT_ERR_OK) + return retVal; + } + + /* Serdes reset */ + if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 0)) != RT_ERR_OK) + return retVal; + } + + if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) + { + if(id != 1) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x13C1, &option)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0000)) != RT_ERR_OK) + return retVal; + } + + if(mode == EXT_SGMII) + { + if(option == 0) + { + for(i = 0; i <= 7; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else + { + for(i = 0; i <= 7; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataSB[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataSB[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + } + + if(mode == EXT_HSGMII) + { + if(option == 0) + { + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) + return retVal; + + if ( ((regValue & 0x00F0) >> 4) == 0x0001) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData1[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData1[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0005) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData5[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData5[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0006) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData6[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData6[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0008) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData8[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData8[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + else if ( ((regValue & 0x00F0) >> 4) == 0x0009) + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData9[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData9[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + } + else + { + for(i = 0; i <= 8; i++) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataHB[i][0])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataHB[i][1])) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + } + } + + /* Only one ext port should care SGMII setting */ + if(id == 1) + { + + if(mode == EXT_SGMII) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_HSGMII) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 1)) != RT_ERR_OK) + return retVal; + } + else + { + + if((mode != EXT_1000X_100FX) && (mode != EXT_1000X) && (mode != EXT_100FX)) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + } + } + + if(0 == id || 1 == id) + { + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), mode)) != RT_ERR_OK) + return retVal; + } + else + { + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, mode)) != RT_ERR_OK) + return retVal; + } + + /* Serdes not reset */ + if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) + { + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x7106)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + } + + if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) + { + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + for(idx = 0; idx < SGMII_INIT_SIZE; idx++) + { + if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Sgmii_Init[idx])) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) + return retVal; + } + } + else if (2 == type) + { + /* Serdes reset */ + if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 1)) != RT_ERR_OK) + return retVal; + } + else + { + if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 0)) != RT_ERR_OK) + return retVal; + } + + /*set MAC mode*/ + if (id == 1) + { + if(mode == EXT_HSGMII) + return RT_ERR_PORT_ID; + + if (mode == EXT_SGMII) + { + /*cfg port8 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + + /*enable port8 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 1)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) + { + /*cfg port8 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + + /*disable port8 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) + return retVal; + + /*set fiber link up*/ + if((retVal = rtl8367c_setAsicRegBit(0x6210, 11, 0)) != RT_ERR_OK) + return retVal; + } + else + { + /*cfg port8 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) + return retVal; + + /*disable port8 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) + return retVal; + } + /*disable SDS 1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + } + else if(id == 2) + { + if (mode == EXT_HSGMII) + { + if ((retVal = rtl8367c_setAsicReg(0x130, 7)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x39f, 7)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicReg(0x130, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x39f, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x3fa, 4)) != RT_ERR_OK) + return retVal; + + } + + + if (mode == EXT_SGMII) + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*enable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 1)) != RT_ERR_OK) + return retVal; + + /*disable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_HSGMII) + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) + return retVal; + + /*enable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 1)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) + return retVal; + + /*set fiber link up*/ + if((retVal = rtl8367c_setAsicRegBit(0x6200, 11, 0)) != RT_ERR_OK) + return retVal; + } + else + { + /*cfg port9 with MII mac mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) + return retVal; + + /*disable port9 SGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) + return retVal; + + /*disable port9 HSGMII*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) + return retVal; + } + /*disable SDS 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) + return retVal; + } + + /*SET TO RGMII MODE*/ + if (mode == EXT_RGMII) + { + /*disable paral led pad*/ + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN3, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN2, 0)) != RT_ERR_OK) + return retVal; + + /*set MAC8 mode*/ + if (id == 1) + { + /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 9, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 6, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 4, 1)) != RT_ERR_OK) + return retVal; + + /*show rate = 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 1, 0)) != RT_ERR_OK) + return retVal; + + /*EXT1 RGMII TXC delay 2ns*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1307, 3, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_Ext1_rgtxc_dly = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) + return retVal; + + /*RXDLY = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1307, 0x7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dn = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 4)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dp = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x700, 4)) != RT_ERR_OK) + return retVal; + } + else if (id == 2) + { + /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 2, 1)) != RT_ERR_OK) + return retVal; + + /*drving 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 1, 1)) != RT_ERR_OK) + return retVal; + + /*show rate = 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 0, 0)) != RT_ERR_OK) + return retVal; + + /*EXT1 RGMII TXC delay 2ns*/ + if ((retVal = rtl8367c_setAsicRegBit(0x13c5, 3, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_Ext1_rgtxc_dly = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) + return retVal; + + /*RXDLY = 0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c5, 0x7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dn = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x1c0, 4)) != RT_ERR_OK) + return retVal; + + /*cfg_rg1_dp = 4*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x38, 4)) != RT_ERR_OK) + return retVal; + } + } + else if (mode == EXT_SGMII) + { + if (id == 1) + { + /*sds 1 reg 1 page 0x21 write value 0xec91*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0xec91)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 1)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) + return retVal; + + /*sds 1 reg 5 page 0x24 write value 0x5825*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x5825)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 2)) != RT_ERR_OK) + return retVal; + + /*?????????????????*/ + + } + else if (id == 2) + { + /*sds 0 reg 0 page 0x28 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 0 page 0x24 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 2)) != RT_ERR_OK) + return retVal; + + /*?????????????????*/ + } + } + else if (mode == EXT_HSGMII) + { + if (id == 2) + { + /*sds 0 reg 0 page 0x28 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 0 page 0x24 write value 0x942c*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + + /* optimizing HISGMII performance while RGMII used & */ + /*sds 0 reg 9 page 0x21 write value 0x3931*/ + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x3931)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5)|9) ) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) + return retVal; + + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x12)) != RT_ERR_OK) + return retVal; + + /*?????????????????*/ + } + } + else if (mode == EXT_1000X) + { + if (id == 1) + { + + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds1 1000M*/ + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0x9000; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFdFFF; + regValue |= 0x40; + if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) + return retVal; + + + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) + return retVal; + + } + else if (id == 2) + { + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds0 1000M*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0x9000; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFDFFF; + regValue |= 0x40; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) + return retVal; + + } + } + else if (mode == EXT_100FX) + { + if (id == 1) + { + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds1 100M*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0xb000; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFFFBF; + regValue |= 0x2000; + if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) + return retVal; +#if 0 + if( (retVal = rtl8367c_setAsicReg(0x6214, 0x1a0)) != RT_ERR_OK) + return retVal; +#endif + if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) + return retVal; + } + else if (id == 2) + { + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) + return retVal; + + /*patch speed change sds0 100M*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFF0FFF; + regValue |= 0xb000; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFFFBF; + regValue |= 0x2000; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) + return retVal; + + if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFEFFF; + if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) + return retVal; + } + } + else if (mode == EXT_1000X_100FX) + { + if (id == 1) + { + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 13, 0, 0x4616)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0, 0xf20)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 7)) != RT_ERR_OK) + return retVal; + } + else if (id == 2) + { + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 13, 0, 0x4616)) != RT_ERR_OK) + return retVal; + if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 0, 0xf20)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 7)) != RT_ERR_OK) + return retVal; + } + } + + } + else if (3 == type) + { + + /*restore patch, by designer. patch Tx FIFO issue, when not HSGMII 2.5G mode + #sds0, page 1, reg 1, bit4=0*/ + if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) + return retVal; + regValue &= 0xFFFFFFEF; + if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) + return retVal; + + /*set for mac 6*/ + if (1 == id) + { + /*force port6 linkdown*/ + if ((retVal = rtl8367c_setAsicReg(0x137c, 0x1000)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) + return retVal; + while(reg_data == 0) + { + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) + return retVal; + } + + if (mode == EXT_SGMII) + { + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + /*cfg_bypass_line_rate[1]=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0: MAC7 is not SGMII mode*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) + return retVal; + + /*#cfg_sgmii_link=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x12 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + /* MAC link source*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) + return retVal; + + + } + else if (mode == EXT_HSGMII) + { + + /*restore patch, by designer. patch Tx FIFO issue, when HSGMII 2.5G mode + #sds0, page 1, reg 1, bit4=1*/ + if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) + return retVal; + regValue |= 0x10; + if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) + return retVal; + + /* mode_ext1 = disable*/ + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0xd0,7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x399, 7)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x12 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) + return retVal; + /* + 1: MAC link = SGMII SerDes link + 0: MAC link = SGMII config link £¨cfg_sgmii_link£© + */ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) + return retVal; + + } + else if(mode == EXT_1000X) + { + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method + bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 + */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable + bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ + if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) + return retVal; + + /*bit3: Serdes force mode:cfg_sds_frc_mode=1 + bit[2:0]: Serdes chip mode, cfg_sds_mode=3b'100 (force sds FIB1G mode) */ + if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) + return retVal; + + + /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x4 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_100FX) + { + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method + bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 + */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable + bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ + if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) + return retVal; + + /*!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3b'101 (force sds fib100M mode)*/ + if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) + return retVal; + + + /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x5 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_1000X_100FX) + { + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /* disable mac6 mode_ext1 mode*/ + if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) + return retVal; + } + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method + bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 + */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable + bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ + if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) + return retVal; + + /*!!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3'b111: Fib1G/Fib100M auto detect */ + if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) + return retVal; + + + /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x7 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + } + else if(mode < EXT_SGMII) + { + if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel SerDes mode,*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + if (mode < EXT_GMII) + { + /* set mac6 mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_RMII_MAC) + { + /*!!!!!!*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 7)) != RT_ERR_OK) + return retVal; + } + else if(mode == EXT_RMII_PHY) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 8)) != RT_ERR_OK) + return retVal; + } + + if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) + { + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 1)) != RT_ERR_OK) + return retVal; + } + } + + } + else if (2 == id) + { + + /*force port7 linkdown*/ + if ((retVal = rtl8367c_setAsicReg(0x137d, 0x1000)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) + return retVal; + while(reg_data == 0) + { + if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) + return retVal; + } + + if (mode == EXT_SGMII) + { + /*disable mac7 sel ext2 xMII mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf,0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + /* disable mac7 mode_ext2 */ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /* + bit0:cfg_mac7_sel_sgmii=0,MAC7 is not SGMII mode + bit1:cfg_mac7_fib= 0 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_hsgmii=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac6_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x2 (SGMII mode)*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) + return retVal; + + /*select MAC link source when port6/7 be set sgmii mode £¨cfg_sgmii_link£©*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X) + { + /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel serdes*/ + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) + return retVal; + + /*new_cfg_sds_mode=0x4 (FIB1000 mode)*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) + return retVal; + + } + else if (mode == EXT_100FX) + { + /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel serdes*/ + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x5 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) + return retVal; + } + else if (mode == EXT_1000X_100FX) + { + /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) + return retVal; + + /* 0 2 0 bit 8~9 set 0, force n-way*/ + if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) + return retVal; + reg_data &= 0xFFFFFCFF; + if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) + return retVal; + + /*restore ext2 ability*/ + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac6 sel serdes*/ + if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) + return retVal; + + /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x1F (reset mode) */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) + return retVal; + + /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) + return retVal; + + /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 + new_cfg_sds_mode=0x7 */ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) + return retVal; + } + else if (mode < EXT_SGMII) + { + if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /* keep default setting, disable mac7 sel SerDes mode*/ + if ((retVal = rtl8367c_setAsicReg(0x1d95, 0x1f00)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + /* set port7 mode*/ + if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) + return retVal; + + if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) + { + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) + return retVal; + } + + } + else if ((mode < EXT_END) && (mode > EXT_100FX)) + { + if ((retVal = rtl8367c_setAsicRegBits(0x13C3, 0xf, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) + return retVal; + + /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ + if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 1)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, ®_data)) != RT_ERR_OK) + return retVal; + if(reg_data == 0) + { + if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) + return retVal; + } + + /* set port7 mode*/ + if (mode < EXT_RMII_MAC_2) + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-13))) != RT_ERR_OK) + return retVal; + } + else + { + if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-12))) != RT_ERR_OK) + return retVal; + } + + if ((mode == EXT_TMII_MAC_2) || (mode == EXT_TMII_PHY_2)) + { + if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) + return retVal; + } + } + + } + + } + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPortExtMode + * Description: + * Get external interface mode configuration + * Input: + * id - external interface id (0~1) + * pMode - external interface mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode) +{ + ret_t retVal; + rtk_uint32 regData, regValue, type; + + if(id >= RTL8367C_EXTNO) + return RT_ERR_OUT_OF_RANGE; + /*cfg_magic_id & get chip_id*/ + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + type = 0; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 1; + break; + case 0x0652: + case 0x6368: + type = 2; + break; + case 0x0801: + case 0x6511: + type = 3; + break; + default: + return RT_ERR_FAILED; + } + + + if (1 == type) + { + + if (1 == id) + { + if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + if(1 == regData) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + + if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, ®Data)) != RT_ERR_OK) + return retVal; + + if(1 == regData) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } + } + + if(0 == id || 1 == id) + return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), pMode); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, pMode); + + } + else if (2 == type) + { + if (1 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData & 0x4000) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + + else if (((regData >> 8) & 0x1f) == 4) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if (((regData >> 8) & 0x1f) == 5) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if (((regData >> 8) & 0x1f) == 7) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + + return rtl8367c_getAsicRegBits(0x1305, 0xf0, pMode); + } + else if (2 == id) + { +#if 0 + if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 6, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData == 1) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + + if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 7, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData == 1) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } +#endif + if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) + return retVal; + + if (regData & 0x40) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + else if (regData & 0x80) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } + else if ((regData & 0x1f) == 4) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if ((regData & 0x1f) == 5) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if ((regData & 0x1f) == 7) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + + return rtl8367c_getAsicRegBits(0x1305, 0xf, pMode); + } + } + else if(3 == type) + { + if (1 == id) + { + /* SDS_CFG_NEW */ + if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicReg(0x1d41, ®Value))!=RT_ERR_OK) + return retVal; + + /* bit5: cfg_mac6_fib=1 && bit7: cfg_mac6_fib2 =1 */ + if((regValue & 0xa0) == 0xa0 ) + { + /* new_cfg_sds_mode */ + regData = regData >> 8; + if((regData & 0x1f) == 4) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if((regData & 0x1f) == 5) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if((regData & 0x1f) == 7) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + + } + + + if ((retVal = rtl8367c_getAsicReg(0x1d11, ®Data))!=RT_ERR_OK) + return retVal; + + /* check cfg_mac6_sel_sgmii */ + if((regData >> 6) & 1) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + else if((regData >> 11) & 1) + { + *pMode = EXT_HSGMII; + return RT_ERR_OK; + } + else + { + /* check port6 MAC mode */ + if ((retVal = rtl8367c_getAsicRegBits(0x1305, 0xf0, ®Data))!=RT_ERR_OK) + return retVal; + + if(regData < 6) + *pMode = regData; + else if(regData == 6) + *pMode = EXT_RMII_MAC; + else if(regData == 7) + *pMode = EXT_RMII_PHY; + + return RT_ERR_OK; + } + } + else if (2 == id) + { + if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) + return retVal; + + /* bit0: cfg_mac7_sel_sgmii + bit1: cfg_mac7_fib + bit[12:8]: new_cfg_sds_mode*/ + if(((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x4)) + { + *pMode = EXT_1000X; + return RT_ERR_OK; + } + else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x5)) + { + *pMode = EXT_100FX; + return RT_ERR_OK; + } + else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x7)) + { + *pMode = EXT_1000X_100FX; + return RT_ERR_OK; + } + else if(regData & 1) + { + *pMode = EXT_SGMII; + return RT_ERR_OK; + } + else + { + /* check port7 MAC mode */ + if ((retVal = rtl8367c_getAsicRegBits(0x13c3, 0xf, ®Data))!=RT_ERR_OK) + return retVal; + + *pMode = regData; + + return RT_ERR_OK; + } + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8370_setAsicPortEnableAll + * Description: + * Set ALL ports enable. + * Input: + * enable - enable all ports. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable) +{ + if(enable >= 2) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, !enable); +} + +/* Function Name: + * rtl8367c_getAsicPortEnableAll + * Description: + * Set ALL ports enable. + * Input: + * enable - enable all ports. + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if (regData==0) + *pEnable = 1; + else + *pEnable = 0; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortSmallIpg + * Description: + * Set small ipg egress mode + * Input: + * port - Physical port number (0~7) + * enable - 0: normal, 1: small + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, enable); +} + +/* Function Name: + * rtl8367c_getAsicPortSmallIpg + * Description: + * Get small ipg egress mode + * Input: + * port - Physical port number (0~7) + * pEnable - 0: normal, 1: small + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, pEnable); +} + +/* Function Name: + * rtl8367c_setAsicPortLoopback + * Description: + * Set MAC loopback + * Input: + * port - Physical port number (0~7) + * enable - 0: Disable, 1: enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, enable); +} + +/* Function Name: + * rtl8367c_getAsicPortLoopback + * Description: + * Set MAC loopback + * Input: + * port - Physical port number (0~7) + * Output: + * pEnable - 0: Disable, 1: enable + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, pEnable); +} + +/* Function Name: + * rtl8367c_setAsicPortRTCTEnable + * Description: + * Set RTCT Enable echo response mode + * Input: + * portmask - Port mask of RTCT enabled (0-4) + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * RTCT test takes 4.8 seconds at most. + */ +ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 port; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x0276) || (regData == 0x0597) ) + return RT_ERR_CHIP_NOT_SUPPORTED; + + for(port = 0; port <= 10 ; port++) + { + if(portmask & (0x0001 << port)) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= 0x7FFF; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData |= 0x00F2;/*RTCT set to echo response mode*/ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData |= 0x0001; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicPortRTCTDisable + * Description: + * Set RTCT Disable + * Input: + * portmask - Port mask of RTCT enabled (0-4) + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * Note: + * RTCT test takes 4.8 seconds at most. + */ +ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 port; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x0276) || (regData == 0x0597) ) + return RT_ERR_CHIP_NOT_SUPPORTED; + + for(port = 0; port <= 10 ; port++) + { + if(portmask & (0x0001 << port)) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + regData &= 0x7FFF; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData |= 0x00F0; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + + regData &= ~0x0001; + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + + +/* Function Name: + * rtl8367c_getAsicPortRTCTResult + * Description: + * Get RTCT result + * Input: + * port - Port ID of RTCT result + * Output: + * pResult - The result of port ID + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid port mask + * RT_ERR_PHY_RTCT_NOT_FINISH - RTCT test doesn't finish. + * Note: + * RTCT test takes 4.8 seconds at most. + * If this API returns RT_ERR_PHY_RTCT_NOT_FINISH, + * users should wait a whole then read it again. + */ +ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult) +{ + ret_t retVal; + rtk_uint32 regData, finish = 1; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) + return retVal; + + if( (regData == 0x6367) ) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + if((regData & 0x8000) == 0x8000) + { + /* Channel A */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelAShort = (regData == 0x0050) ? 1 : 0; + pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel B */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelBShort = (regData == 0x0050) ? 1 : 0; + pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel C */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelCShort = (regData == 0x0050) ? 1 : 0; + pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel D */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelDShort = (regData == 0x0050) ? 1 : 0; + pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel A Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelALen = (regData / 2); + + /* Channel B Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBLen = (regData / 2); + + /* Channel C Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCLen = (regData / 2); + + /* Channel D Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDLen = (regData / 2); + } + else + finish = 0; + } + else if(regData == 0x6368) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + if((regData & 0x8000) == 0x8000) + { + /* Channel A */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802b)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelAShort = (regData == 0x0050) ? 1 : 0; + pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel B */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802f)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelBShort = (regData == 0x0050) ? 1 : 0; + pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel C */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8033)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelCShort = (regData == 0x0050) ? 1 : 0; + pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel D */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8037)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelDShort = (regData == 0x0050) ? 1 : 0; + pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel A Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802d)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelALen = (regData / 2); + + /* Channel B Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8031)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBLen = (regData / 2); + + /* Channel C Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8035)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCLen = (regData / 2); + + /* Channel D Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8039)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDLen = (regData / 2); + } + else + finish = 0; + + } + else if((regData == 0x6511) || (regData == 0x0801)) + { + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) + return retVal; + + if((regData & 0x8000) == 0x8000) + { + /* Channel A */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelAShort = (regData == 0x0050) ? 1 : 0; + pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel B */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelBShort = (regData == 0x0050) ? 1 : 0; + pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel C */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelCShort = (regData == 0x0050) ? 1 : 0; + pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel D */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; + pResult->channelDShort = (regData == 0x0050) ? 1 : 0; + pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; + pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; + + /* Channel A Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelALen = (regData / 2); + + /* Channel B Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelBLen = (regData / 2); + + /* Channel C Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelCLen = (regData / 2); + + /* Channel D Length */ + if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) + return retVal; + + pResult->channelDLen = (regData / 2); + } + else + finish = 0; + + } + else + return RT_ERR_CHIP_NOT_SUPPORTED; + + if(finish == 0) + return RT_ERR_PHY_RTCT_NOT_FINISH; + else + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_sdsReset + * Description: + * Reset Serdes + * Input: + * id - EXT ID + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_sdsReset(rtk_uint32 id) +{ + rtk_uint32 retVal, regValue, state, i, option, running = 0, retVal2; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + option = 0; + break; + case 0x0652: + case 0x6368: + option = 1; + break; + case 0x0801: + case 0x6511: + option = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(option == 0) + { + if (1 == id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x0000); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6602, 0x1401); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6601, 0x0000); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6602, 0x1403); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(option == 1) + { + if (1 == id) + { + if((retVal = rtl8367c_getAsicReg(0x1311, &state)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1311, 0x66)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x1311, 0x1066)) != RT_ERR_OK) + return retVal; + + while(1) + { + if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) + return retVal; + if((regValue >> 8) & 1) + break; + } + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x1311, state)) != RT_ERR_OK) + return retVal; + + + } + else if (2== id) + { + if((retVal = rtl8367c_getAsicReg(0x13c4, &state)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13c4, 0x66)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13c4, 0x1066)) != RT_ERR_OK) + return retVal; + + while(1) + { + if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) + return retVal; + if((regValue >> 9) & 1) + break; + } + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + if((retVal = rtl8367c_setAsicReg(0x13c4, state)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(option == 2) + { + if ((retVal = rtl8367c_getAsicSdsReg(0, 3, 0, ®Value))!=RT_ERR_OK) + return retVal; + regValue |= 0x40; + if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) + return retVal; + + for (i=0; i<0xffff; i++); + + regValue &= ~(0x40); + if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) + return retVal; + + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getSdsLinkStatus + * Description: + * Get SGMII status + * Input: + * id - EXT ID + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink) +{ + rtk_uint32 retVal, regValue, type, running = 0, retVal2; + + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(type == 0) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x003D); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x0080); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_getAsicReg(0x6602, ®Value); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 1) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + } + else if (2 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 2) + { + if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) + return retVal; + if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) + return retVal; + + *pSignalDetect = (regValue & 0x0100) ? 1 : 0; + *pSync = (regValue & 0x0001) ? 1 : 0; + *pLink = (regValue & 0x0010) ? 1 : 0; + + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setSgmiiNway + * Description: + * Set SGMII Nway + * Input: + * ext_id - EXT ID + * state - SGMII Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state) +{ + rtk_uint32 retVal, regValue, type, running = 0, retVal2; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(type == 0) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x0002); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x0080); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_getAsicReg(0x6602, ®Value); + + if(retVal == RT_ERR_OK) + { + if(state) + regValue |= 0x0200; + else + regValue &= ~0x0200; + + regValue |= 0x0100; + } + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6602, regValue); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6601, 0x0002); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 1) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(state) + regValue |= 0x0200; + else + regValue &= ~0x0200; + + regValue |= 0x0100; + + if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C1))!=RT_ERR_OK) + return retVal; + } + else if (2 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(state) + regValue |= 0x0200; + else + regValue &= ~0x0200; + + regValue |= 0x0100; + + if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C0))!=RT_ERR_OK) + return retVal; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 2) + { + if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) + return retVal; + + if(state & 1) + regValue &= ~0x100; + else + regValue |= 0x100; + + if ((retVal = rtl8367c_setAsicSdsReg(0, 2, 0, regValue))!=RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getSgmiiNway + * Description: + * Get SGMII Nway + * Input: + * ext_id - EXT ID + * state - SGMII Nway state + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None. + */ +ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState) +{ + rtk_uint32 retVal, regValue, type, running = 0, retVal2; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + if(type == 0) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) + return retVal; + + if(running == 1) + { + if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) + return retVal; + } + + retVal = rtl8367c_setAsicReg(0x6601, 0x0002); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_setAsicReg(0x6600, 0x0080); + + if(retVal == RT_ERR_OK) + retVal = rtl8367c_getAsicReg(0x6602, ®Value); + + if(running == 1) + { + if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) + return retVal2; + } + + if(retVal != RT_ERR_OK) + return retVal; + + if(regValue & 0x0200) + *pState = 1; + else + *pState = 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 1) + { + if (1 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(regValue & 0x0200) + *pState = 1; + else + *pState = 0; + } + else if (2 == ext_id) + { + if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) + return retVal; + + if(regValue & 0x0200) + *pState = 1; + else + *pState = 0; + } + else + return RT_ERR_PORT_ID; + } + else if(type == 2) + { + if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) + return retVal; + + if(regValue & 0x100) + *pState = 0; + else + *pState = 1; + } + + return RT_ERR_OK; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c new file mode 100755 index 00000000..e0b9db4b --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port isolation related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicPortIsolationPermittedPortmask + * Description: + * Set permitted port isolation portmask + * Input: + * port - Physical port number (0~10) + * permitPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if( permitPortmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), permitPortmask); +} +/* Function Name: + * rtl8367c_getAsicPortIsolationPermittedPortmask + * Description: + * Get permitted port isolation portmask + * Input: + * port - Physical port number (0~10) + * pPermitPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), pPermitPortmask); +} +/* Function Name: + * rtl8367c_setAsicPortIsolationEfid + * Description: + * Set port isolation EFID + * Input: + * port - Physical port number (0~10) + * efid - EFID (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - Input parameter out of range + * Note: + * EFID is used in individual learning in filtering database + */ +ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if( efid > RTL8367C_EFIDMAX) + return RT_ERR_OUT_OF_RANGE; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), efid); +} +/* Function Name: + * rtl8367c_getAsicPortIsolationEfid + * Description: + * Get port isolation EFID + * Input: + * port - Physical port number (0~10) + * pEfid - EFID (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), pEfid); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c new file mode 100755 index 00000000..89c3c3e0 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c @@ -0,0 +1,778 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Qos related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicPriorityDot1qRemapping + * Description: + * Set 802.1Q absolutely priority + * Input: + * srcpriority - Priority value + * priority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ) +{ + if((srcpriority > RTL8367C_PRIMAX) || (priority > RTL8367C_PRIMAX)) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority),priority); +} +/* Function Name: + * rtl8367c_getAsicPriorityDot1qRemapping + * Description: + * Get 802.1Q absolutely priority + * Input: + * srcpriority - Priority value + * pPriority - Absolute priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ) +{ + if(srcpriority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority), pPriority); +} +/* Function Name: + * rtl8367c_setAsicPriorityPortBased + * Description: + * Set port based priority + * Input: + * port - Physical port number (0~7) + * priority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), priority); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), priority); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicPriorityPortBased + * Description: + * Get port based priority + * Input: + * port - Physical port number (0~7) + * pPriority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), pPriority); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), pPriority); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPriorityDscpBased + * Description: + * Set DSCP-based priority + * Input: + * dscp - DSCP value + * priority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if(dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), priority); +} +/* Function Name: + * rtl8367c_getAsicPriorityDscpBased + * Description: + * Get DSCP-based priority + * Input: + * dscp - DSCP value + * pPriority - Priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ) +{ + if(dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), pPriority); +} +/* Function Name: + * rtl8367c_setAsicPriorityDecision + * Description: + * Set priority decision table + * Input: + * prisrc - Priority decision source + * decisionPri - Decision priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri) +{ + ret_t retVal; + + if(index >= PRIDEC_IDX_END ) + return RT_ERR_ENTRY_INDEX; + + if(prisrc >= PRIDEC_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + if(decisionPri > RTL8367C_DECISIONPRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + switch(index) + { + case PRIDEC_IDX0: + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), decisionPri))!= RT_ERR_OK) + return retVal; + break; + case PRIDEC_IDX1: + if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), decisionPri))!= RT_ERR_OK) + return retVal; + break; + default: + break; + }; + + return RT_ERR_OK; + + +} + +/* Function Name: + * rtl8367c_getAsicPriorityDecision + * Description: + * Get priority decision table + * Input: + * prisrc - Priority decision source + * pDecisionPri - Decision priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri) +{ + ret_t retVal; + + if(index >= PRIDEC_IDX_END ) + return RT_ERR_ENTRY_INDEX; + + if(prisrc >= PRIDEC_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + switch(index) + { + case PRIDEC_IDX0: + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) + return retVal; + break; + case PRIDEC_IDX1: + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) + return retVal; + break; + default: + break; + }; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_setAsicPortPriorityDecisionIndex + * Description: + * Set priority decision index for each port + * Input: + * port - Physical port number (0~7) + * index - Table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_NUM - Invalid queue number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index >= PRIDEC_IDX_END) + return RT_ERR_ENTRY_INDEX; + + return rtl8367c_setAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, index); +} +/* Function Name: + * rtl8367c_getAsicPortPriorityDecisionIndex + * Description: + * Get priority decision index for each port + * Input: + * port - Physical port number (0~7) + * pIndex - Table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, pIndex); +} + +/* Function Name: + * rtl8367c_setAsicOutputQueueMappingIndex + * Description: + * Set output queue number for each port + * Input: + * port - Physical port number (0~7) + * index - Mapping table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_NUM - Invalid queue number + * Note: + * None + */ +ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 index ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index >= RTL8367C_QUEUENO) + return RT_ERR_QUEUE_NUM; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), index); +} +/* Function Name: + * rtl8367c_getAsicOutputQueueMappingIndex + * Description: + * Get output queue number for each port + * Input: + * port - Physical port number (0~7) + * pIndex - Mapping table index + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pIndex ) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), pIndex); +} +/* Function Name: + * rtl8367c_setAsicPriorityToQIDMappingTable + * Description: + * Set priority to QID mapping table parameters + * Input: + * index - Mapping table index + * priority - The priority value + * qid - Queue id + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_ID - Invalid queue id + * RT_ERR_QUEUE_NUM - Invalid queue number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32 qid ) +{ + if(index >= RTL8367C_QUEUENO) + return RT_ERR_QUEUE_NUM; + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), qid); +} +/* Function Name: + * rtl8367c_getAsicPriorityToQIDMappingTable + * Description: + * Get priority to QID mapping table parameters + * Input: + * index - Mapping table index + * priority - The priority value + * pQid - Queue id + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QUEUE_NUM - Invalid queue number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32* pQid) +{ + if(index >= RTL8367C_QUEUENO) + return RT_ERR_QUEUE_NUM; + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), pQid); +} +/* Function Name: + * rtl8367c_setAsicRemarkingDot1pAbility + * Description: + * Set 802.1p remarking ability + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDot1pAbility + * Description: + * Get 802.1p remarking ability + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRemarkingDot1pParameter + * Description: + * Set 802.1p remarking parameter + * Input: + * priority - Priority value + * newPriority - New priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ) +{ + if(priority > RTL8367C_PRIMAX || newPriority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), newPriority); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDot1pParameter + * Description: + * Get 802.1p remarking parameter + * Input: + * priority - Priority value + * pNewPriority - New priority value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), pNewPriority); +} + +/* Function Name: + * rtl8367c_setAsicRemarkingDot1pSrc + * Description: + * Set remarking source of 802.1p remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure 802.1p remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type) +{ + + if(type >= DOT1P_PRISEL_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, type); +} + + +/* Function Name: + * rtl8367c_getAsicRemarkingDot1pSrc + * Description: + * Get remarking source of 802.1p remarking. + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, pType); +} + + + + + +/* Function Name: + * rtl8367c_setAsicRemarkingDscpAbility + * Description: + * Set DSCP remarking ability + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDscpAbility + * Description: + * Get DSCP remarking ability + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRemarkingDscpParameter + * Description: + * Set DSCP remarking parameter + * Input: + * priority - Priority value + * newDscp - New DSCP value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + if(newDscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), newDscp); +} +/* Function Name: + * rtl8367c_getAsicRemarkingDscpParameter + * Description: + * Get DSCP remarking parameter + * Input: + * priority - Priority value + * pNewDscp - New DSCP value + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ) +{ + if(priority > RTL8367C_PRIMAX ) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), pNewDscp); +} + +/* Function Name: + * rtl8367c_setAsicRemarkingDscpSrc + * Description: + * Set remarking source of DSCP remarking. + * Input: + * type - remarking source + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + + * Note: + * The API can configure DSCP remark functionality to map original DSCP value or internal + * priority to TX DSCP value. + */ +ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type) +{ + + if(type >= DSCP_PRISEL_END ) + return RT_ERR_QOS_SEL_PRI_SOURCE; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, type); +} + + +/* Function Name: + * rtl8367c_getAsicRemarkingDscpSrc + * Description: + * Get remarking source of DSCP remarking. + * Output: + * pType - remarking source + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * RT_ERR_NULL_POINTER - input parameter may be null pointer + + * Note: + * None + */ +ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, pType); +} + +/* Function Name: + * rtl8367c_setAsicRemarkingDscp2Dscp + * Description: + * Set DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * rmkDscp - remarked DSCP value + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - Invalid unit id + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * Note: + * dscp parameter can be DSCP value or internal priority according to configuration of API + * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP + * value or internal priority to TX DSCP value. + */ +ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp) +{ + if((dscp > RTL8367C_DSCPMAX ) || (rmkDscp > RTL8367C_DSCPMAX)) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), rmkDscp); +} + +/* Function Name: + * rtl8367c_getAsicRemarkingDscp2Dscp + * Description: + * Get DSCP to remarked DSCP mapping. + * Input: + * dscp - DSCP value + * Output: + * pRmkDscp - remarked DSCP value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * None. + */ +ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp) +{ + if(dscp > RTL8367C_DSCPMAX) + return RT_ERR_QOS_DSCP_VALUE; + + return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), pRmkDscp); + +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c new file mode 100755 index 00000000..0309689d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c @@ -0,0 +1,674 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 42321 $ + * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RLDP related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicRldp + * Description: + * Set RLDP function enable/disable + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRldp + * Description: + * Get RLDP function enable/disable + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpEnable8051 + * Description: + * Set RLDP function handled by ASIC or 8051 + * Input: + * enabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_setAsicRldrtl8367c_getAsicRldpEnable8051pEnable8051 + * Description: + * Get RLDP function handled by ASIC or 8051 + * Input: + * pEnabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpCompareRandomNumber + * Description: + * Set enable compare the random number field and seed field of RLDP frame + * Input: + * enabled - 1: enabled comparing random number, 0: disabled comparing random number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRldpCompareRandomNumber + * Description: + * Get enable compare the random number field and seed field of RLDP frame + * Input: + * pEnabled - 1: enabled comparing random number, 0: disabled comparing random number + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpIndicatorSource + * Description: + * Set buzzer and LED source when detecting a loop + * Input: + * src - 0: ASIC, 1: 8051 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, src); +} +/* Function Name: + * rtl8367c_getAsicRldpIndicatorSource + * Description: + * Get buzzer and LED source when detecting a loop + * Input: + * pSrc - 0: ASIC, 1: 8051 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, pSrc); +} +/* Function Name: + * rtl8367c_setAsicRldpCheckingStatePara + * Description: + * Set retry count and retry period of checking state + * Input: + * retryCount - 0~0xFF (times) + * retryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) +{ + ret_t retVal; + + if(retryCount > 0xFF) + return RT_ERR_OUT_OF_RANGE; + if(retryPeriod > RTL8367C_REGDATAMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, retryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, retryPeriod); +} +/* Function Name: + * rtl8367c_getAsicRldpCheckingStatePara + * Description: + * Get retry count and retry period of checking state + * Input: + * pRetryCount - 0~0xFF (times) + * pRetryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, pRetryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, pRetryPeriod); +} +/* Function Name: + * rtl8367c_setAsicRldpLoopStatePara + * Description: + * Set retry count and retry period of loop state + * Input: + * retryCount - 0~0xFF (times) + * retryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) +{ + ret_t retVal; + + if(retryCount > 0xFF) + return RT_ERR_OUT_OF_RANGE; + + if(retryPeriod > RTL8367C_REGDATAMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, retryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, retryPeriod); +} +/* Function Name: + * rtl8367c_getAsicRldpLoopStatePara + * Description: + * Get retry count and retry period of loop state + * Input: + * pRetryCount - 0~0xFF (times) + * pRetryPeriod - 0~0xFFFF (ms) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - input parameter out of range + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, pRetryCount); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, pRetryPeriod); +} +/* Function Name: + * rtl8367c_setAsicRldpTxPortmask + * Description: + * Set portmask that send/forward RLDP frame + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask) +{ + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicReg(RTL8367C_RLDP_TX_PMSK_REG, portmask); +} +/* Function Name: + * rtl8367c_getAsicRldpTxPortmask + * Description: + * Get portmask that send/forward RLDP frame + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_RLDP_TX_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicRldpMagicNum + * Description: + * Set Random seed of RLDP + * Input: + * seed - MAC + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint16*)&seed; + + for (i = 0; i < 3; i++) + { + regData = *accessPtr; + retVal = rtl8367c_setAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr++; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicRldpMagicNum + * Description: + * Get Random seed of RLDP + * Input: + * pSeed - MAC + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + + accessPtr = (rtk_uint16*)pSeed; + + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + accessPtr++; + } + + return retVal; +} + +/* Function Name: + * rtl8367c_getAsicRldpLoopedPortmask + * Description: + * Get looped portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_RLDP_LOOP_PMSK_REG, pPortmask); +} +/* Function Name: + * rtl8367c_getAsicRldpRandomNumber + * Description: + * Get Random number of RLDP + * Input: + * pRandNumber - MAC + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_int16 accessPtr[3]; + rtk_uint32 i; + + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_RAND_NUM_REG_BASE+ i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr[i] = regData; + } + + memcpy(pRandNumber, accessPtr, 6); + return retVal; +} +/* Function Name: + * rtl8367c_getAsicRldpLoopedPortmask + * Description: + * Get port number of looped pair + * Input: + * port - Physical port number (0~7) + * pLoopedPair - port (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_RLDP_LOOP_PORT_REG(port), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_LOOP_PORT_REG4 + ((port - 8) >> 1), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); +} +/* Function Name: + * rtl8367c_setAsicRlppTrap8051 + * Description: + * Set trap RLPP packet to 8051 + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRlppTrap8051 + * Description: + * Get trap RLPP packet to 8051 + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicRldpLeaveLoopedPortmask + * Description: + * Clear leaved looped portmask + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, portmask); +} +/* Function Name: + * rtl8367c_getAsicRldpLeaveLoopedPortmask + * Description: + * Get leaved looped portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicRldpEnterLoopedPortmask + * Description: + * Clear enter loop portmask + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, portmask); +} +/* Function Name: + * rtl8367c_getAsicRldpEnterLoopedPortmask + * Description: + * Get enter loop portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, pPortmask); +} + +/* Function Name: + * rtl8367c_setAsicRldpTriggerMode + * Description: + * Set trigger RLDP mode + * Input: + * mode - 1: Periodically, 0: SA moving + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicRldpTriggerMode + * Description: + * Get trigger RLDP mode + * Input: + * pMode - - 1: Periodically, 0: SA moving + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicRldp8051Portmask + * Description: + * Set 8051/CPU configured looped portmask + * Input: + * portmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * Note: + * None + */ +ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask) +{ + ret_t retVal; + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,(portmask >> 8) & 7); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicRldp8051Portmask + * Description: + * Get 8051/CPU configured looped portmask + * Input: + * pPortmask - 0~0xFF + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpPmsk; + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,&tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpPmsk & 0xff; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,&tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpPmsk & 7) <<8; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c new file mode 100755 index 00000000..f297defa --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 64716 $ + * $Date: 2015-12-31 16:31:55 +0800 (週四, 31 å二月 2015) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : RMA related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicRma + * Description: + * Set reserved multicast address for CPU trapping + * Input: + * index - reserved multicast LSB byte, 0x00~0x2F is available value + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(index > RTL8367C_RMAMAX) + return RT_ERR_RMA_ADDR; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) + index = 0x04; + else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) + index = 0x13; + else if(index >= 0x22 && index <= 0x2F) + index = 0x22; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL00+index, regData); +} +/* Function Name: + * rtl8367c_getAsicRma + * Description: + * Get reserved multicast address for CPU trapping + * Input: + * index - reserved multicast LSB byte, 0x00~0x2F is available value + * rmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + if(index > RTL8367C_RMAMAX) + return RT_ERR_RMA_ADDR; + + if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) + index = 0x04; + else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) + index = 0x13; + else if(index >= 0x22 && index <= 0x2F) + index = 0x22; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL00+index, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicRmaCdp + * Description: + * Set CDP(Cisco Discovery Protocol) for CPU trapping + * Input: + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(pRmacfg->operation >= RMAOP_END) + return RT_ERR_RMA_ACTION; + + if(pRmacfg->trap_priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CDP, regData); +} +/* Function Name: + * rtl8367c_getAsicRmaCdp + * Description: + * Get CDP(Cisco Discovery Protocol) for CPU trapping + * Input: + * None + * Output: + * pRmacfg - type of RMA for trapping frame type setting + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CDP, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicRmaCsstp + * Description: + * Set CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping + * Input: + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(pRmacfg->operation >= RMAOP_END) + return RT_ERR_RMA_ACTION; + + if(pRmacfg->trap_priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, regData); +} +/* Function Name: + * rtl8367c_getAsicRmaCsstp + * Description: + * Get CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping + * Input: + * None + * Output: + * pRmacfg - type of RMA for trapping frame type setting + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicRmaLldp + * Description: + * Set LLDP for CPU trapping + * Input: + * pRmacfg - type of RMA for trapping frame type setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg) +{ + rtk_uint32 regData = 0; + ret_t retVal; + + if(enabled > 1) + return RT_ERR_ENABLE; + + if(pRmacfg->operation >= RMAOP_END) + return RT_ERR_RMA_ACTION; + + if(pRmacfg->trap_priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,enabled); + if(retVal != RT_ERR_OK) + return retVal; + + regData |= (pRmacfg->portiso_leaky & 0x0001); + regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); + regData |= ((pRmacfg->keep_format & 0x0001) << 2); + regData |= ((pRmacfg->trap_priority & 0x0007) << 3); + regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); + regData |= ((pRmacfg->operation & 0x0003) << 7); + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); + if(retVal != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, regData); +} +/* Function Name: + * rtl8367c_getAsicRmaLldp + * Description: + * Get LLDP for CPU trapping + * Input: + * None + * Output: + * pRmacfg - type of RMA for trapping frame type setting + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_RMA_ADDR - Invalid RMA address index + * Note: + * None + */ +ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg) +{ + ret_t retVal; + rtk_uint32 regData; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,pEnabled); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->operation = ((regData >> 7) & 0x0003); + pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); + pRmacfg->trap_priority = ((regData >> 3) & 0x0007); + pRmacfg->keep_format = ((regData >> 2) & 0x0001); + pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); + pRmacfg->portiso_leaky = (regData & 0x0001); + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + pRmacfg->trap_priority = regData; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c new file mode 100755 index 00000000..8ebd6796 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Packet Scheduling related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicLeakyBucketParameter + * Description: + * Set Leaky Bucket Paramters + * Input: + * tick - Tick is used for time slot size unit + * token - Token is used for adding budget in each time slot + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_TICK - Invalid TICK + * RT_ERR_TOKEN - Invalid TOKEN + * Note: + * None + */ +ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token) +{ + ret_t retVal; + + if(tick > 0xFF) + return RT_ERR_TICK; + + if(token > 0xFF) + return RT_ERR_TOKEN; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicLeakyBucketParameter + * Description: + * Get Leaky Bucket Paramters + * Input: + * tick - Tick is used for time slot size unit + * token - Token is used for adding budget in each time slot + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); + + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicAprMeter + * Description: + * Set per-port per-queue APR shared meter index + * Input: + * port - Physical port number (0~10) + * qid - Queue id + * apridx - dedicated shared meter index for APR (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * None + */ +ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx) +{ + ret_t retVal; + rtk_uint32 regAddr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + if(apridx > RTL8367C_PORT_QUEUE_METER_INDEX_MAX) + return RT_ERR_FILTER_METER_ID; + + if(port < 8) + retVal = rtl8367c_setAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + else { + regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAprMeter + * Description: + * Get per-port per-queue APR shared meter index + * Input: + * port - Physical port number (0~10) + * qid - Queue id + * apridx - dedicated shared meter index for APR (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx) +{ + ret_t retVal; + rtk_uint32 regAddr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + if(port < 8) + retVal = rtl8367c_getAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + else { + regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); + retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); + } + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicAprEnable + * Description: + * Set per-port APR enable + * Input: + * port - Physical port number (0~7) + * aprEnable - APR enable seting 1:enable 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicAprEnable + * Description: + * Get per-port APR enable + * Input: + * port - Physical port number (0~7) + * aprEnable - APR enable seting 1:enable 0:disable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicWFQWeight + * Description: + * Set weight of a queue + * Input: + * port - Physical port number (0~10) + * qid - The queue ID wanted to set + * qWeight - The weight value wanted to set (valid:0~127) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight + * Note: + * None + */ +ret_t rtl8367c_setAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 qWeight) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + if(qWeight > RTL8367C_QWEIGHTMAX && qid > 0) + return RT_ERR_QOS_QUEUE_WEIGHT; + + retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicWFQWeight + * Description: + * Get weight of a queue + * Input: + * port - Physical port number (0~10) + * qid - The queue ID wanted to set + * qWeight - The weight value wanted to set (valid:0~127) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *qWeight) +{ + ret_t retVal; + + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + + retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicWFQBurstSize + * Description: + * Set WFQ leaky bucket burst size + * Input: + * burstsize - Leaky bucket burst size, unit byte + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicWFQBurstSize + * Description: + * Get WFQ leaky bucket burst size + * Input: + * burstsize - Leaky bucket burst size, unit byte + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicQueueType + * Description: + * Set type of a queue + * Input: + * port - Physical port number (0~10) + * qid - The queue ID wanted to set + * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + /* Set Related Registers */ + retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicQueueType + * Description: + * Get type of a queue + * Input: + * port - Physical port number (0~7) + * qid - The queue ID wanted to set + * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QUEUE_ID - Invalid queue id + * Note: + * None + */ +ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType) +{ + ret_t retVal; + + /* Invalid input parameter */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(qid > RTL8367C_QIDMAX) + return RT_ERR_QUEUE_ID; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); + + return retVal; +} +/* Function Name: + * rtl8367c_setAsicPortEgressRate + * Description: + * Set per-port egress rate + * Input: + * port - Physical port number (0~10) + * rate - Egress rate + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_EBW_RATE - Invalid bandwidth/rate + * Note: + * None + */ +ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate) +{ + ret_t retVal; + rtk_uint32 regAddr, regData; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(rate > RTL8367C_QOS_GRANULARTY_MAX) + return RT_ERR_QOS_EBW_RATE; + + regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); + regData = RTL8367C_QOS_GRANULARTY_LSB_MASK & rate; + + retVal = rtl8367c_setAsicReg(regAddr, regData); + + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); + regData = (RTL8367C_QOS_GRANULARTY_MSB_MASK & rate) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; + + retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, regData); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicPortEgressRate + * Description: + * Get per-port egress rate + * Input: + * port - Physical port number (0~10) + * rate - Egress rate + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate) +{ + ret_t retVal; + rtk_uint32 regAddr, regData,regData2; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); + + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); + retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, ®Data2); + if(retVal != RT_ERR_OK) + return retVal; + + *rate = regData | (regData2 << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicPortEgressRateIfg + * Description: + * Set per-port egress rate calculate include/exclude IFG + * Input: + * ifg - 1:include IFG 0:exclude IFG + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicPortEgressRateIfg + * Description: + * Get per-port egress rate calculate include/exclude IFG + * Input: + * ifg - 1:include IFG 0:exclude IFG + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg) +{ + ret_t retVal; + + retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); + + return retVal; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c new file mode 100755 index 00000000..a29f6476 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c @@ -0,0 +1,851 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Storm control filtering related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicStormFilterBroadcastEnable + * Description: + * Set per-port broadcast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_BCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterBroadcastEnable + * Description: + * Get per-port broadcast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_BCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterBroadcastMeter + * Description: + * Set per-port broadcast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), meter); +} +/* Function Name: + * rtl8367c_getAsicStormFilterBroadcastMeter + * Description: + * Get per-port broadcast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), pMeter); +} +/* Function Name: + * rtl8367c_setAsicStormFilterMulticastEnable + * Description: + * Set per-port multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_MCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterMulticastEnable + * Description: + * Get per-port multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_MCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterMulticastMeter + * Description: + * Set per-port multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), meter); +} +/* Function Name: + * rtl8367c_getAsicStormFilterMulticastMeter + * Description: + * Get per-port multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), pMeter); +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownMulticastEnable + * Description: + * Set per-port unknown multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownMulticastEnable + * Description: + * Get per-port unknown multicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownMulticastMeter + * Description: + * Set per-port unknown multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownMulticastMeter + * Description: + * Get per-port unknown multicast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + ret_t retVal; + + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownUnicastEnable + * Description: + * Set per-port unknown unicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownUnicastEnable + * Description: + * get per-port unknown unicast storm filter enable/disable + * Input: + * port - Physical port number (0~7) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicStormFilterUnknownUnicastMeter + * Description: + * Set per-port unknown unicast storm filter meter + * Input: + * port - Physical port number (0~7) + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), meter); +} +/* Function Name: + * rtl8367c_getAsicStormFilterUnknownUnicastMeter + * Description: + * Get per-port unknown unicast storm filter meter + * Input: + * port - Physical port number (0~7) + * pMeter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter) +{ + if(port >= RTL8367C_PORTNO) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtBroadcastMeter + * Description: + * Set extension broadcast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtBroadcastMeter + * Description: + * get extension broadcast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtMulticastMeter + * Description: + * Set extension multicast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtMulticastMeter + * Description: + * get extension multicast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownMulticastMeter + * Description: + * Set extension unknown multicast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownMulticastMeter + * Description: + * get extension unknown multicast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownUnicastMeter + * Description: + * Set extension unknown unicast storm filter meter + * Input: + * meter - meter index (0~31) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_FILTER_METER_ID - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter) +{ + if(meter > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, meter); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownUnicastMeter + * Description: + * get extension unknown unicast storm filter meter + * Input: + * None + * Output: + * pMeter - meter index (0~31) + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Invalid meter index + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter) +{ + if(NULL == pMeter) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, pMeter); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtBroadcastEnable + * Description: + * Set extension broadcast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtBroadcastEnable + * Description: + * Get extension broadcast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtMulticastEnable + * Description: + * Set extension multicast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtMulticastEnable + * Description: + * Get extension multicast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownMulticastEnable + * Description: + * Set extension unknown multicast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownMulticastEnable + * Description: + * Get extension unknown multicast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtUnknownUnicastEnable + * Description: + * Set extension unknown unicast storm filter state + * Input: + * enabled - state + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, enabled); +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtUnknownUnicastEnable + * Description: + * Get extension unknown unicast storm filter state + * Input: + * None + * Output: + * pEnabled - state + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled) +{ + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, pEnabled); +} + +/* Function Name: + * rtl8367c_setAsicStormFilterExtEnablePortMask + * Description: + * Set extension storm filter port mask + * Input: + * portmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask) +{ + ret_t retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, portmask & 0x3FF); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, (portmask >> 10)&1); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicStormFilterExtEnablePortMask + * Description: + * Get extension storm filter port mask + * Input: + * portmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask) +{ + rtk_uint32 tmpPmsk; + ret_t retVal; + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, &tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = tmpPmsk & 0x3ff; + + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, &tmpPmsk); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask |= (tmpPmsk & 1) << 10; + + return RT_ERR_OK; +} + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c new file mode 100755 index 00000000..f19ceba5 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c @@ -0,0 +1,1003 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : SVLAN related functions + * + */ +#include + +#include + +static void _rtl8367c_svlanConfStUser2Smi( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pSmiSt[0] |= (pUserSt->vs_member & 0x00FF); + pSmiSt[0] |= (pUserSt->vs_untag & 0x00FF) << 8; + + pSmiSt[1] |= (pUserSt->vs_fid_msti & 0x000F); + pSmiSt[1] |= (pUserSt->vs_priority & 0x0007) << 4; + pSmiSt[1] |= (pUserSt->vs_force_fid & 0x0001) << 7; + + pSmiSt[2] |= (pUserSt->vs_svid & 0x0FFF); + pSmiSt[2] |= (pUserSt->vs_efiden & 0x0001) << 12; + pSmiSt[2] |= (pUserSt->vs_efid & 0x0007) << 13; + + pSmiSt[3] |= ((pUserSt->vs_member & 0x0700) >> 8); + pSmiSt[3] |= ((pUserSt->vs_untag & 0x0700) >> 8) << 3; +} + +static void _rtl8367c_svlanConfStSmi2User( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) +{ + + pUserSt->vs_member = (pSmiSt[0] & 0x00FF) | ((pSmiSt[3] & 0x0007) << 8); + pUserSt->vs_untag = ((pSmiSt[0] & 0xFF00) >> 8) | (((pSmiSt[3] & 0x0038) >> 3) << 8); + + pUserSt->vs_fid_msti = (pSmiSt[1] & 0x000F); + pUserSt->vs_priority = (pSmiSt[1] & 0x0070) >> 4; + pUserSt->vs_force_fid = (pSmiSt[1] & 0x0080) >> 7; + + pUserSt->vs_svid = (pSmiSt[2] & 0x0FFF); + pUserSt->vs_efiden = (pSmiSt[2] & 0x1000) >> 12; + pUserSt->vs_efid = (pSmiSt[2] & 0xE000) >> 13; +} + +static void _rtl8367c_svlanMc2sStUser2Smi(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pSmiSt[0] |= (pUserSt->svidx & 0x003F); + pSmiSt[0] |= (pUserSt->format & 0x0001) << 6; + pSmiSt[0] |= (pUserSt->valid & 0x0001) << 7; + + pSmiSt[1] = (rtk_uint16)(pUserSt->smask & 0x0000FFFF); + pSmiSt[2] = (rtk_uint16)((pUserSt->smask & 0xFFFF0000) >> 16); + + pSmiSt[3] = (rtk_uint16)(pUserSt->sdata & 0x0000FFFF); + pSmiSt[4] = (rtk_uint16)((pUserSt->sdata & 0xFFFF0000) >> 16); +} + +static void _rtl8367c_svlanMc2sStSmi2User(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pUserSt->svidx = (pSmiSt[0] & 0x003F); + pUserSt->format = (pSmiSt[0] & 0x0040) >> 6; + pUserSt->valid = (pSmiSt[0] & 0x0080) >> 7; + + pUserSt->smask = pSmiSt[1] | (pSmiSt[2] << 16); + pUserSt->sdata = pSmiSt[3] | (pSmiSt[4] << 16); +} + +static void _rtl8367c_svlanSp2cStUser2Smi(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pSmiSt[0] |= (pUserSt->dstport & 0x0007); + pSmiSt[0] |= (pUserSt->svidx & 0x003F) << 3; + pSmiSt[0] |= ((pUserSt->dstport & 0x0008) >> 3) << 9; + + pSmiSt[1] |= (pUserSt->vid & 0x0FFF); + pSmiSt[1] |= (pUserSt->valid & 0x0001) << 12; +} + +static void _rtl8367c_svlanSp2cStSmi2User(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) +{ + pUserSt->dstport = (((pSmiSt[0] & 0x0200) >> 9) << 3) | (pSmiSt[0] & 0x0007); + pUserSt->svidx = (pSmiSt[0] & 0x01F8) >> 3; + pUserSt->vid = (pSmiSt[1] & 0x0FFF); + pUserSt->valid = (pSmiSt[1] & 0x1000) >> 12; +} + +/* Function Name: + * rtl8367c_setAsicSvlanUplinkPortMask + * Description: + * Set uplink ports mask + * Input: + * portMask - Uplink port mask setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, portMask); +} +/* Function Name: + * rtl8367c_getAsicSvlanUplinkPortMask + * Description: + * Get uplink ports mask + * Input: + * pPortmask - Uplink port mask setting + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, pPortmask); +} +/* Function Name: + * rtl8367c_setAsicSvlanTpid + * Description: + * Set accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 + * Input: + * protocolType - Ether type of S-tag frame parsing in uplink ports + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 + * for Q-in-Q SLAN design. User can set mathced ether type as service provider supported protocol + */ +ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType) +{ + return rtl8367c_setAsicReg(RTL8367C_REG_VS_TPID, protocolType); +} +/* Function Name: + * rtl8367c_getAsicReg + * Description: + * Get accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 + * Input: + * pProtocolType - Ether type of S-tag frame parsing in uplink ports + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_VS_TPID, pProtocolType); +} +/* Function Name: + * rtl8367c_setAsicSvlanPrioritySel + * Description: + * Set SVLAN priority field setting + * Input: + * priSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel) +{ + if(priSel >= SPRISEL_END) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, priSel); +} +/* Function Name: + * rtl8367c_getAsicSvlanPrioritySel + * Description: + * Get SVLAN priority field setting + * Input: + * pPriSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, pPriSel); +} +/* Function Name: + * rtl8367c_setAsicSvlanTrapPriority + * Description: + * Set trap to CPU priority assignment + * Input: + * priority - Priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, priority); +} +/* Function Name: + * rtl8367c_getAsicSvlanTrapPriority + * Description: + * Get trap to CPU priority assignment + * Input: + * pPriority - Priority assignment + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, pPriority); +} +/* Function Name: + * rtl8367c_setAsicSvlanDefaultVlan + * Description: + * Set default egress SVLAN + * Input: + * port - Physical port number (0~10) + * index - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + if(port < 8){ + if(port & 1) + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,index); + else + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,index); + }else{ + switch(port){ + case 8: + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,index); + break; + + case 9: + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,index); + break; + + case 10: + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,index); + break; + } + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicSvlanDefaultVlan + * Description: + * Get default egress SVLAN + * Input: + * port - Physical port number (0~7) + * pIndex - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8){ + if(port & 1) + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,pIndex); + else + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,pIndex); + }else{ + switch(port){ + case 8: + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,pIndex); + break; + + case 9: + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,pIndex); + break; + + case 10: + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,pIndex); + break; + } + } + + return retVal; + +} +/* Function Name: + * rtl8367c_setAsicSvlanIngressUntag + * Description: + * Set action received un-Stag frame from unplink port + * Input: + * mode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicSvlanIngressUntag + * Description: + * Get action received un-Stag frame from unplink port + * Input: + * pMode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, pMode); +} +/* Function Name: + * rtl8367c_setAsicSvlanIngressUnmatch + * Description: + * Set action received unmatched Stag frame from unplink port + * Input: + * mode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, mode); +} +/* Function Name: + * rtl8367c_getAsicSvlanIngressUnmatch + * Description: + * Get action received unmatched Stag frame from unplink port + * Input: + * pMode - 0:Drop 1:Trap 2:Assign SVLAN + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, pMode); + +} +/* Function Name: + * rtl8367c_setAsicSvlanEgressUnassign + * Description: + * Set unplink stream without egress SVID action + * Input: + * enabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicSvlanEgressUnassign + * Description: + * Get unplink stream without egress SVID action + * Input: + * pEnabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, pEnabled); +} + + +/* Function Name: + * rtl8367c_setAsicSvlanMemberConfiguration + * Description: + * Set system 64 S-tag content + * Input: + * index - index of 64 s-tag configuration + * pSvlanMemCfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index, rtl8367c_svlan_memconf_t* pSvlanMemCfg) +{ + ret_t retVal; + rtk_uint32 regAddr, regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; + + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); + _rtl8367c_svlanConfStUser2Smi(pSvlanMemCfg, smiSvlanMemConf); + + accessPtr = smiSvlanMemConf; + + regData = *accessPtr; + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + } + + if(index < 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; + else if(index == 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} +/* Function Name: + * rtl8367c_getAsicSvlanMemberConfiguration + * Description: + * Get system 64 S-tag content + * Input: + * index - index of 64 s-tag configuration + * pSvlanMemCfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg) +{ + ret_t retVal; + rtk_uint32 regAddr,regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; + + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); + + accessPtr = smiSvlanMemConf; + + for(i = 0; i < 3; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + accessPtr ++; + } + + if(index < 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; + else if(index == 63) + regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; + + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + _rtl8367c_svlanConfStSmi2User(pSvlanMemCfg, smiSvlanMemConf); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicSvlanC2SConf + * Description: + * Set SVLAN C2S table + * Input: + * index - index of 128 Svlan C2S configuration + * evid - Enhanced VID + * portmask - available c2s port mask + * svidx - index of 64 Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * ASIC will check upstream's VID and assign related SVID to mathed packet + */ +ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx) +{ + ret_t retVal; + + if(index > RTL8367C_C2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), svidx); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, portmask); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, evid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicSvlanC2SConf + * Description: + * Get SVLAN C2S table + * Input: + * index - index of 128 Svlan C2S configuration + * pEvid - Enhanced VID + * pPortmask - available c2s port mask + * pSvidx - index of 64 Svlan member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx) +{ + ret_t retVal; + + if(index > RTL8367C_C2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), pSvidx); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, pPortmask); + if(retVal != RT_ERR_OK) + return retVal; + + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, pEvid); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicSvlanMC2SConf + * Description: + * Set system MC2S content + * Input: + * index - index of 32 SVLAN 32 MC2S configuration + * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * If upstream packet is L2 multicast or IPv4 multicast packet and DMAC/DIP is matched MC2S + * configuration, ASIC will assign egress SVID to the packet + */ +ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; + + if(index > RTL8367C_MC2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); + _rtl8367c_svlanMc2sStUser2Smi(pSvlanMc2sCfg, smiSvlanMC2S); + + accessPtr = smiSvlanMC2S; + + regData = *accessPtr; + for(i = 0; i < 5; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicSvlanMC2SConf + * Description: + * Get system MC2S content + * Input: + * index - index of 32 SVLAN 32 MC2S configuration + * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index, rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; + + if(index > RTL8367C_MC2SIDXMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); + + accessPtr = smiSvlanMC2S; + + for(i = 0; i < 5; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + accessPtr ++; + } + + + _rtl8367c_svlanMc2sStSmi2User(pSvlanMc2sCfg, smiSvlanMC2S); + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setAsicSvlanSP2CConf + * Description: + * Set system 128 SP2C content + * Input: + * index - index of 128 SVLAN & Port to CVLAN configuration + * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index, rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; + + if(index > RTL8367C_SP2CMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); + _rtl8367c_svlanSp2cStUser2Smi(pSvlanSp2cCfg,smiSvlanSP2C); + + accessPtr = smiSvlanSP2C; + + regData = *accessPtr; + for(i = 0; i < 2; i++) + { + retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, regData); + if(retVal != RT_ERR_OK) + return retVal; + + accessPtr ++; + regData = *accessPtr; + } + + return retVal; +} +/* Function Name: + * rtl8367c_getAsicSvlanSP2CConf + * Description: + * Get system 128 SP2C content + * Input: + * index - index of 128 SVLAN & Port to CVLAN configuration + * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_ENTRY_INDEX - Invalid entry index + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) +{ + ret_t retVal; + rtk_uint32 regData; + rtk_uint16 *accessPtr; + rtk_uint32 i; + rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; + + if(index > RTL8367C_SP2CMAX) + return RT_ERR_ENTRY_INDEX; + + memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); + + accessPtr = smiSvlanSP2C; + + for(i = 0; i < 2; i++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *accessPtr = regData; + + accessPtr ++; + } + + _rtl8367c_svlanSp2cStSmi2User(pSvlanSp2cCfg, smiSvlanSP2C); + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicSvlanDmacCvidSel + * Description: + * Set downstream CVID decision by DMAC + * Input: + * port - Physical port number (0~7) + * enabled - 0:disabled, 1:enabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, enabled); + else + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), enabled); +} +/* Function Name: + * rtl8367c_getAsicSvlanDmacCvidSel + * Description: + * Get downstream CVID decision by DMAC + * Input: + * port - Physical port number (0~7) + * pEnabled - 0:disabled, 1:enabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, pEnabled); + else + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), pEnabled); +} +/* Function Name: + * rtl8367c_setAsicSvlanUntagVlan + * Description: + * Set default ingress untag SVLAN + * Input: + * index - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index) +{ + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, index); +} +/* Function Name: + * rtl8367c_getAsicSvlanUntagVlan + * Description: + * Get default ingress untag SVLAN + * Input: + * pIndex - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, pIndex); +} + +/* Function Name: + * rtl8367c_setAsicSvlanUnmatchVlan + * Description: + * Set default ingress unmatch SVLAN + * Input: + * index - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index) +{ + if(index > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, index); +} +/* Function Name: + * rtl8367c_getAsicSvlanUnmatchVlan + * Description: + * Get default ingress unmatch SVLAN + * Input: + * pIndex - index SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, pIndex); +} + + +/* Function Name: + * rtl8367c_setAsicSvlanLookupType + * Description: + * Set svlan lookup table selection + * Input: + * type - lookup type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, type); +} + +/* Function Name: + * rtl8367c_getAsicSvlanLookupType + * Description: + * Get svlan lookup table selection + * Input: + * pType - lookup type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, pType); +} + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c new file mode 100755 index 00000000..26d4c29b --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Port trunking related functions + * + */ + +#include +/* Function Name: + * rtl8367c_setAsicTrunkingMode + * Description: + * Set port trunking mode + * Input: + * mode - 1:dumb 0:user defined + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, mode); +} +/* Function Name: + * rtl8367c_getAsicTrunkingMode + * Description: + * Get port trunking mode + * Input: + * pMode - 1:dumb 0:user defined + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, pMode); +} +/* Function Name: + * rtl8367c_setAsicTrunkingFc + * Description: + * Set port trunking flow control + * Input: + * group - Trunk Group ID + * enabled - 0:disable, 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled) +{ + ret_t retVal; + + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_DROP_CTRL, RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET, ENABLED)) != RT_ERR_OK) + return retVal; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), enabled); +} +/* Function Name: + * rtl8367c_getAsicTrunkingFc + * Description: + * Get port trunking flow control + * Input: + * group - Trunk Group ID + * pEnabled - 0:disable, 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled) +{ + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), pEnabled); +} +/* Function Name: + * rtl8367c_setAsicTrunkingGroup + * Description: + * Set trunking group available port mask + * Input: + * group - Trunk Group ID + * portmask - Logic trunking enable port mask, max 4 ports + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask) +{ + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), portmask); +} +/* Function Name: + * rtl8367c_getAsicTrunkingGroup + * Description: + * Get trunking group available port mask + * Input: + * group - Trunk Group ID + * Output: + * pPortmask - Logic trunking enable port mask, max 4 ports + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask) +{ + if(group > RTL8367C_MAX_TRUNK_GID) + return RT_ERR_LA_TRUNK_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), pPortmask); +} +/* Function Name: + * rtl8367c_setAsicTrunkingFlood + * Description: + * Set port trunking flood function + * Input: + * enabled - Port trunking flooding function 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicTrunkingFlood + * Description: + * Get port trunking flood function + * Input: + * pEnabled - Port trunking flooding function 0:disable 1:enable + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicTrunkingHashSelect + * Description: + * Set port trunking hash select sources + * Input: + * hashsel - hash sources mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} + * 0b0000001: SPA + * 0b0000010: SMAC + * 0b0000100: DMAC + * 0b0001000: SIP + * 0b0010000: DIP + * 0b0100000: TCP/UDP Source Port + * 0b1000000: TCP/UDP Destination Port + */ +ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel) +{ + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, hashsel); +} +/* Function Name: + * rtl8367c_getAsicTrunkingHashSelect + * Description: + * Get port trunking hash select sources + * Input: + * pHashsel - hash sources mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel) +{ + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, pHashsel); +} +/* Function Name: + * rtl8367c_getAsicQeueuEmptyStatus + * Description: + * Get current output queue if empty status + * Input: + * portmask - queue empty port mask + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* portmask) +{ + return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, portmask); +} +/* Function Name: + * rtl8367c_setAsicTrunkingHashTable + * Description: + * Set port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * portId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(portId >= RTL8367C_TRUNKING_PORTNO) + return RT_ERR_PORT_ID; + + if(hashval >= 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), portId); + else + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), portId); +} +/* Function Name: + * rtl8367c_getAsicTrunkingHashTable + * Description: + * Get port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * pPortId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(hashval >= 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), pPortId); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), pPortId); +} + +/* Function Name: + * rtl8367c_setAsicTrunkingHashTable1 + * Description: + * Set port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * portId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(portId >= RTL8367C_TRUNKING1_PORTN0) + return RT_ERR_PORT_ID; + + if(hashval >= 8) + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), portId); + else + return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), portId); +} +/* Function Name: + * rtl8367c_getAsicTrunkingHashTable1 + * Description: + * Get port trunking hash value mapping table + * Input: + * hashval - hashing value 0-15 + * pPortId - trunking port id 0-3 + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) + * Note: + * None + */ +ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId) +{ + if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) + return RT_ERR_OUT_OF_RANGE; + + if(hashval >= 8) + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), pPortId); + else + return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), pPortId); +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c new file mode 100755 index 00000000..fcebd1b7 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : Unkown multicast related functions + * + */ + +#include + +/* Function Name: + * rtl8367c_setAsicUnknownL2MulticastBehavior + * Description: + * Set behavior of L2 multicast + * Input: + * port - Physical port number (0~7) + * behave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid operation + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(behave >= L2_UNKOWN_MULTICAST_END) + return RT_ERR_NOT_ALLOWED; + if(port < 8) + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), behave); + if(retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), behave); + if(retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicUnknownL2MulticastBehavior + * Description: + * Get behavior of L2 multicast + * Input: + * port - Physical port number (0~7) + * pBehave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) +{ + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), pBehave); + if (retVal != RT_ERR_OK) + return retVal; + } + else + { + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), pBehave); + if (retVal != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicUnknownIPv4MulticastBehavior + * Description: + * Set behavior of IPv4 multicast + * Input: + * port - Physical port number (0~7) + * behave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid operation + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(behave >= L3_UNKOWN_MULTICAST_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), behave); +} +/* Function Name: + * rtl8367c_getAsicUnknownIPv4MulticastBehavior + * Description: + * Get behavior of IPv4 multicast + * Input: + * port - Physical port number (0~7) + * pBehave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), pBehave); +} +/* Function Name: + * rtl8367c_setAsicUnknownIPv6MulticastBehavior + * Description: + * Set behavior of IPv6 multicast + * Input: + * port - Physical port number (0~7) + * behave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_NOT_ALLOWED - Invalid operation + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(behave >= L3_UNKOWN_MULTICAST_END) + return RT_ERR_NOT_ALLOWED; + + return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), behave); +} +/* Function Name: + * rtl8367c_getAsicUnknownIPv6MulticastBehavior + * Description: + * Get behavior of IPv6 multicast + * Input: + * port - Physical port number (0~7) + * pBehave - 0: flooding, 1: drop, 2: trap + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), pBehave); +} +/* Function Name: + * rtl8367c_setAsicUnknownMulticastTrapPriority + * Description: + * Set trap priority of unknown multicast frame + * Input: + * priority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority) +{ + if(priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + return rtl8367c_setAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, priority); +} +/* Function Name: + * rtl8367c_getAsicUnknownMulticastTrapPriority + * Description: + * Get trap priority of unknown multicast frame + * Input: + * pPriority - priority (0~7) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority) +{ + return rtl8367c_getAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, pPriority); +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c new file mode 100755 index 00000000..1e283e74 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c @@ -0,0 +1,1505 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTL8367C switch high-level API for RTL8367C + * Feature : VLAN related functions + * + */ +#include + +#include + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) +rtl8367c_user_vlan4kentry Rtl8370sVirtualVlanTable[RTL8367C_VIDMAX + 1]; +#endif + +static void _rtl8367c_VlanMCStUser2Smi(rtl8367c_vlanconfiguser *pVlanCg, rtk_uint16 *pSmiVlanCfg) +{ + pSmiVlanCfg[0] |= pVlanCg->mbr & 0x07FF; + + pSmiVlanCfg[1] |= pVlanCg->fid_msti & 0x000F; + + pSmiVlanCfg[2] |= pVlanCg->vbpen & 0x0001; + pSmiVlanCfg[2] |= (pVlanCg->vbpri & 0x0007) << 1; + pSmiVlanCfg[2] |= (pVlanCg->envlanpol & 0x0001) << 4; + pSmiVlanCfg[2] |= (pVlanCg->meteridx & 0x003F) << 5; + + pSmiVlanCfg[3] |= pVlanCg->evid & 0x1FFF; +} + +static void _rtl8367c_VlanMCStSmi2User(rtk_uint16 *pSmiVlanCfg, rtl8367c_vlanconfiguser *pVlanCg) +{ + pVlanCg->mbr = pSmiVlanCfg[0] & 0x07FF; + pVlanCg->fid_msti = pSmiVlanCfg[1] & 0x000F; + pVlanCg->meteridx = (pSmiVlanCfg[2] >> 5) & 0x003F; + pVlanCg->envlanpol = (pSmiVlanCfg[2] >> 4) & 0x0001; + pVlanCg->vbpri = (pSmiVlanCfg[2] >> 1) & 0x0007; + pVlanCg->vbpen = pSmiVlanCfg[2] & 0x0001; + pVlanCg->evid = pSmiVlanCfg[3] & 0x1FFF; +} + +static void _rtl8367c_Vlan4kStUser2Smi(rtl8367c_user_vlan4kentry *pUserVlan4kEntry, rtk_uint16 *pSmiVlan4kEntry) +{ + pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->mbr & 0x00FF); + pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->untag & 0x00FF) << 8; + + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->fid_msti & 0x000F); + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpen & 0x0001) << 4; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpri & 0x0007) << 5; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->envlanpol & 0x0001) << 8; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->meteridx & 0x001F) << 9; + pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->ivl_svl & 0x0001) << 14; + + pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->mbr & 0x0700) >> 8); + pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->untag & 0x0700) >> 8) << 3; + pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->meteridx & 0x0020) >> 5) << 6; +} + + +static void _rtl8367c_Vlan4kStSmi2User(rtk_uint16 *pSmiVlan4kEntry, rtl8367c_user_vlan4kentry *pUserVlan4kEntry) +{ + pUserVlan4kEntry->mbr = (pSmiVlan4kEntry[0] & 0x00FF) | ((pSmiVlan4kEntry[2] & 0x0007) << 8); + pUserVlan4kEntry->untag = ((pSmiVlan4kEntry[0] & 0xFF00) >> 8) | (((pSmiVlan4kEntry[2] & 0x0038) >> 3) << 8); + pUserVlan4kEntry->fid_msti = pSmiVlan4kEntry[1] & 0x000F; + pUserVlan4kEntry->vbpen = (pSmiVlan4kEntry[1] & 0x0010) >> 4; + pUserVlan4kEntry->vbpri = (pSmiVlan4kEntry[1] & 0x00E0) >> 5; + pUserVlan4kEntry->envlanpol = (pSmiVlan4kEntry[1] & 0x0100) >> 8; + pUserVlan4kEntry->meteridx = ((pSmiVlan4kEntry[1] & 0x3E00) >> 9) | (((pSmiVlan4kEntry[2] & 0x0040) >> 6) << 5); + pUserVlan4kEntry->ivl_svl = (pSmiVlan4kEntry[1] & 0x4000) >> 14; +} + +/* Function Name: + * rtl8367c_setAsicVlanMemberConfig + * Description: + * Set 32 VLAN member configurations + * Input: + * index - VLAN member configuration index (0~31) + * pVlanCg - VLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_L2_FID - Invalid FID + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) +{ + ret_t retVal; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint16 *tableAddr; + rtk_uint32 page_idx; + rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; + + /* Error Checking */ + if(index > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + if(pVlanCg->evid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + + if(pVlanCg->mbr > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(pVlanCg->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(pVlanCg->meteridx > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(pVlanCg->vbpri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); + _rtl8367c_VlanMCStUser2Smi(pVlanCg, smi_vlancfg); + tableAddr = smi_vlancfg; + + for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ + { + regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; + regData = *tableAddr; + + retVal = rtl8367c_setAsicReg(regAddr, regData); + if(retVal != RT_ERR_OK) + return retVal; + + tableAddr++; + } + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanMemberConfig + * Description: + * Get 32 VLAN member configurations + * Input: + * index - VLAN member configuration index (0~31) + * pVlanCg - VLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) +{ + ret_t retVal; + rtk_uint32 page_idx; + rtk_uint32 regAddr; + rtk_uint32 regData; + rtk_uint16 *tableAddr; + rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; + + if(index > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); + tableAddr = smi_vlancfg; + + for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ + { + regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; + + retVal = rtl8367c_getAsicReg(regAddr, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = (rtk_uint16)regData; + tableAddr++; + } + + _rtl8367c_VlanMCStSmi2User(smi_vlancfg, pVlanCg); + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlan4kEntry + * Description: + * Set VID mapped entry to 4K VLAN table + * Input: + * pVlan4kEntry - 4K VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_L2_FID - Invalid FID + * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_FILTER_METER_ID - Invalid meter + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * Note: + * None + */ +ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) +{ + rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; + rtk_uint32 page_idx; + rtk_uint16 *tableAddr; + ret_t retVal; + rtk_uint32 regData; + + if(pVlan4kEntry->vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if(pVlan4kEntry->mbr > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(pVlan4kEntry->untag > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(pVlan4kEntry->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(pVlan4kEntry->meteridx > RTL8367C_METERMAX) + return RT_ERR_FILTER_METER_ID; + + if(pVlan4kEntry->vbpri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + memset(vlan_4k_entry, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_4KTABLE_LEN); + _rtl8367c_Vlan4kStUser2Smi(pVlan4kEntry, vlan_4k_entry); + + /* Prepare Data */ + tableAddr = vlan_4k_entry; + for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) + { + regData = *tableAddr; + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + page_idx, regData); + if(retVal != RT_ERR_OK) + return retVal; + + tableAddr++; + } + + /* Write Address (VLAN_ID) */ + regData = pVlan4kEntry->vid; + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Write Command */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_CVLAN)); + if(retVal != RT_ERR_OK) + return retVal; + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) + memcpy(&Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], pVlan4kEntry, sizeof(rtl8367c_user_vlan4kentry)); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlan4kEntry + * Description: + * Get VID mapped entry to 4K VLAN table + * Input: + * pVlan4kEntry - 4K VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) + * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving + * Note: + * None + */ +ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) +{ + rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; + rtk_uint32 page_idx; + rtk_uint16 *tableAddr; + ret_t retVal; + rtk_uint32 regData; + rtk_uint32 busyCounter; + + if(pVlan4kEntry->vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Polling status */ + busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData == 0) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + /* Write Address (VLAN_ID) */ + regData = pVlan4kEntry->vid; + retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Command */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_CVLAN)); + if(retVal != RT_ERR_OK) + return retVal; + + /* Polling status */ + busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; + while(busyCounter) + { + retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); + if(retVal != RT_ERR_OK) + return retVal; + + if(regData == 0) + break; + + busyCounter --; + if(busyCounter == 0) + return RT_ERR_BUSYWAIT_TIMEOUT; + } + + /* Read VLAN data from register */ + tableAddr = vlan_4k_entry; + for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) + { + retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + page_idx, ®Data); + if(retVal != RT_ERR_OK) + return retVal; + + *tableAddr = regData; + tableAddr++; + } + + _rtl8367c_Vlan4kStSmi2User(vlan_4k_entry, pVlan4kEntry); + +#if defined(CONFIG_RTL8367C_ASICDRV_TEST) + memcpy(pVlan4kEntry, &Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], sizeof(rtl8367c_user_vlan4kentry)); +#endif + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanAccpetFrameType + * Description: + * Set per-port acceptable frame type + * Input: + * port - Physical port number (0~10) + * frameType - The acceptable frame type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(frameType >= FRAME_TYPE_MAX_BOUND) + return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; + + return rtl8367c_setAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), frameType); +} +/* Function Name: + * rtl8367c_getAsicVlanAccpetFrameType + * Description: + * Get per-port acceptable frame type + * Input: + * port - Physical port number (0~10) + * pFrameType - The acceptable frame type + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType) +{ + rtk_uint32 regData; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), ®Data)) != RT_ERR_OK) + return retVal; + + *pFrameType = (rtl8367c_accframetype)regData; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanIngressFilter + * Description: + * Set VLAN Ingress Filter + * Input: + * port - Physical port number (0~10) + * enabled - Enable or disable Ingress filter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, enabled); +} +/* Function Name: + * rtl8367c_getAsicVlanIngressFilter + * Description: + * Get VLAN Ingress Filter + * Input: + * port - Physical port number (0~10) + * pEnable - Enable or disable Ingress filter + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, pEnable); +} +/* Function Name: + * rtl8367c_setAsicVlanEgressTagMode + * Description: + * Set CVLAN egress tag mode + * Input: + * port - Physical port number (0~10) + * tagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(tagMode >= EG_TAG_MODE_END) + return RT_ERR_INPUT; + + return rtl8367c_setAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, tagMode); +} +/* Function Name: + * rtl8367c_getAsicVlanEgressTagMode + * Description: + * Get CVLAN egress tag mode + * Input: + * port - Physical port number (0~10) + * pTagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode) +{ + rtk_uint32 regData; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if((retVal = rtl8367c_getAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, ®Data)) != RT_ERR_OK) + return retVal; + + *pTagMode = (rtl8367c_egtagmode)regData; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanPortBasedVID + * Description: + * Set port based VID which is indexed to 32 VLAN member configurations + * Input: + * port - Physical port number (0~10) + * index - Index to VLAN member configuration + * pri - 1Q Port based VLAN priority + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri) +{ + rtk_uint32 regAddr, bit_mask; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + if(pri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); + bit_mask = RTL8367C_PORT_VIDX_MASK(port); + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, index); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); + bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, pri); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanPortBasedVID + * Description: + * Get port based VID which is indexed to 32 VLAN member configurations + * Input: + * port - Physical port number (0~10) + * pIndex - Index to VLAN member configuration + * pPri - 1Q Port based VLAN priority + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri) +{ + rtk_uint32 regAddr,bit_mask; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); + bit_mask = RTL8367C_PORT_VIDX_MASK(port); + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pIndex); + if(retVal != RT_ERR_OK) + return retVal; + + regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); + bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pPri); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanProtocolBasedGroupData + * Description: + * Set protocol and port based group database + * Input: + * index - Index to VLAN member configuration + * pPbCfg - Protocol and port based group database entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) +{ + rtk_uint32 frameType; + rtk_uint32 etherType; + ret_t retVal; + + /* Error Checking */ + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + if(pPbCfg->frameType >= PPVLAN_FRAME_TYPE_END ) + return RT_ERR_INPUT; + + frameType = pPbCfg->frameType; + etherType = pPbCfg->etherType; + + /* Frame type */ + retVal = rtl8367c_setAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, frameType); + if(retVal != RT_ERR_OK) + return retVal; + + /* Ether type */ + retVal = rtl8367c_setAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), etherType); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanProtocolBasedGroupData + * Description: + * Get protocol and port based group database + * Input: + * index - Index to VLAN member configuration + * pPbCfg - Protocol and port based group database entry + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) +{ + rtk_uint32 frameType; + rtk_uint32 etherType; + ret_t retVal; + + /* Error Checking */ + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + /* Read Frame type */ + retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, &frameType); + if(retVal != RT_ERR_OK) + return retVal; + + /* Read Ether type */ + retVal = rtl8367c_getAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), ðerType); + if(retVal != RT_ERR_OK) + return retVal; + + + pPbCfg->frameType = frameType; + pPbCfg->etherType = etherType; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanPortAndProtocolBased + * Description: + * Set protocol and port based VLAN configuration + * Input: + * port - Physical port number (0~10) + * index - Index of protocol and port based database index + * pPpbCfg - Protocol and port based VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_QOS_INT_PRIORITY - Invalid priority + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) +{ + rtk_uint32 reg_addr, bit_mask, bit_value; + ret_t retVal; + + /* Error Checking */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + if( (pPpbCfg->valid != FALSE) && (pPpbCfg->valid != TRUE) ) + return RT_ERR_INPUT; + + if(pPpbCfg->vlan_idx > RTL8367C_CVIDXMAX) + return RT_ERR_VLAN_ENTRY_NOT_FOUND; + + if(pPpbCfg->priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + /* Valid bit */ + reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); + bit_mask = 0x0001 << port; + bit_value = ((TRUE == pPpbCfg->valid) ? 0x1 : 0x0); + retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + /* Calculate the actual register address for CVLAN index*/ + if(port < 8) + { + reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); + bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); + } + else if(port == 8) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; + } + else if(port == 9) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; + } + else if(port == 10) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; + } + + bit_value = pPpbCfg->vlan_idx; + retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + /* write priority */ + reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, index); + bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); + bit_value = pPpbCfg->priority; + retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_getAsicVlanPortAndProtocolBased + * Description: + * Get protocol and port based VLAN configuration + * Input: + * port - Physical port number (0~7) + * index - Index of protocol and port based database index + * pPpbCfg - Protocol and port based VLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) +{ + rtk_uint32 reg_addr, bit_mask, bit_value; + ret_t retVal; + + /* Error Checking */ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(index > RTL8367C_PROTOVLAN_GIDX_MAX) + return RT_ERR_VLAN_PROTO_AND_PORT; + + if(pPpbCfg == NULL) + return RT_ERR_INPUT; + + /* Valid bit */ + reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); + bit_mask = 0x0001 << port; + retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + pPpbCfg->valid = bit_value; + + /* CVLAN index */ + if(port < 8) + { + reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); + bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); + } + else if(port == 8) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; + } + else if(port == 9) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; + } + else if(port == 10) + { + reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; + bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; + } + + retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + pPpbCfg->vlan_idx = bit_value; + + + /* priority */ + reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port,index); + bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); + retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); + if(retVal != RT_ERR_OK) + return retVal; + + pPpbCfg->priority = bit_value; + return RT_ERR_OK; +} +/* Function Name: + * rtl8367c_setAsicVlanFilter + * Description: + * Set enable CVLAN filtering function + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicVlanFilter + * Description: + * Get enable CVLAN filtering function + * Input: + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicVlanUntagDscpPriorityEn + * Description: + * Set enable Dscp to untag 1Q priority + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled) +{ + return rtl8367c_setAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_getAsicVlanUntagDscpPriorityEn + * Description: + * Get enable Dscp to untag 1Q priority + * Input: + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled) +{ + return rtl8367c_getAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); +} +/* Function Name: + * rtl8367c_setAsicPortBasedFid + * Description: + * Set port based FID + * Input: + * port - Physical port number (0~10) + * fid - Port based fid + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid FID + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid) +{ + rtk_uint32 reg_addr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(port < 8) + return rtl8367c_setAsicReg(RTL8367C_PORT_PBFID_REG(port),fid); + else { + reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; + return rtl8367c_setAsicReg(reg_addr, fid); + } + +} +/* Function Name: + * rtl8367c_getAsicPortBasedFid + * Description: + * Get port based FID + * Input: + * port - Physical port number (0~7) + * pFid - Port based fid + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid) +{ + rtk_uint32 reg_addr; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8) + return rtl8367c_getAsicReg(RTL8367C_PORT_PBFID_REG(port), pFid); + else{ + reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; + return rtl8367c_getAsicReg(reg_addr, pFid); + } +} +/* Function Name: + * rtl8367c_setAsicPortBasedFidEn + * Description: + * Set port based FID selection enable + * Input: + * port - Physical port number (0~10) + * enabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, enabled); +} +/* Function Name: + * rtl8367c_getAsicPortBasedFidEn + * Description: + * Get port based FID selection enable + * Input: + * port - Physical port number (0~10) + * pEnabled - 1: enabled, 0: disabled + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, pEnabled); +} +/* Function Name: + * rtl8367c_setAsicSpanningTreeStatus + * Description: + * Set spanning tree state per each port + * Input: + * port - Physical port number (0~10) + * msti - Multiple spanning tree instance + * state - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_MSTP_STATE - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state) +{ + rtk_uint32 reg_addr,bits_msk; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(msti > RTL8367C_MSTIMAX) + return RT_ERR_MSTI; + + if(state > STPST_FORWARDING) + return RT_ERR_MSTP_STATE; + + if(port < 8) + return rtl8367c_setAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port),state); + else{ + reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); + switch(port){ + case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; + case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; + case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; + } + return rtl8367c_setAsicRegBits(reg_addr, bits_msk,state); + } +} +/* Function Name: + * rtl8367c_getAsicSpanningTreeStatus + * Description: + * Set spanning tree state per each port + * Input: + * port - Physical port number (0~10) + * msti - Multiple spanning tree instance + * pState - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState) +{ + rtk_uint32 reg_addr,bits_msk; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(msti > RTL8367C_MSTIMAX) + return RT_ERR_MSTI; + + if(port < 8) + return rtl8367c_getAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port), pState); + else{ + reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); + switch(port){ + case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; + case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; + case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; + } + return rtl8367c_getAsicRegBits(reg_addr, bits_msk, pState); + } + +} + +/* Function Name: + * rtl8367c_setAsicVlanTransparent + * Description: + * Set VLAN transparent + * Input: + * port - Physical port number (0~10) + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + return rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, portmask); +} + +/* Function Name: + * rtl8367c_getAsicVlanTransparent + * Description: + * Get VLAN transparent + * Input: + * port - Physical port number (0~10) + * Output: + * pPortmask - Ingress port mask + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask) +{ + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + return rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, pPortmask); +} + +/* Function Name: + * rtl8367c_setAsicVlanEgressKeep + * Description: + * Set per egress port VLAN keep mode + * Input: + * port - Physical port number (0~10) + * portmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_MASK - Invalid portmask + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask) +{ + rtk_uint32 regAddr, bit_mask; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(portmask > RTL8367C_PORTMASK) + return RT_ERR_PORT_MASK; + + if(port < 8){ + retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); + bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; + bit_mask <<= (port&1)*3; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + } + else{ + switch(port){ + case 8: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + break; + + case 9: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + break; + + case 10: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; + retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); + if(retVal != RT_ERR_OK) + return retVal; + break; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getAsicVlanEgressKeep + * Description: + * Get per egress port VLAN keep mode + * Input: + * port - Physical port number (0~7) + * pPortmask - portmask(0~0xFF) + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * Note: + * None + */ +ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask) +{ + rtk_uint32 regAddr, bit_mask, regval_l, regval_h; + ret_t retVal; + + if(port > RTL8367C_PORTIDMAX) + return RT_ERR_PORT_ID; + + if(port < 8){ + retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); + bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; + bit_mask <<= (port&1)*3; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + *pPortmask = (regval_h << 8) | regval_l; + } + else{ + switch(port){ + case 8: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + + *pPortmask = (regval_h << 8) | regval_l; + break; + + case 9: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; + bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + + *pPortmask = (regval_h << 8) | regval_l; + break; + + case 10: + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); + if(retVal != RT_ERR_OK) + return retVal; + regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; + bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; + retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); + if(retVal != RT_ERR_OK) + return retVal; + + *pPortmask = (regval_h << 8) | regval_l; + break; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_setReservedVidAction + * Description: + * Set reserved VID action + * Input: + * vid0Action - VID 0 action + * vid4095Action - VID 4095 action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error input + * Note: + * None + */ +ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action) +{ + ret_t retVal; + + if(vid0Action >= RES_VID_ACT_END) + return RT_ERR_INPUT; + + if(vid4095Action >= RES_VID_ACT_END) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, vid0Action)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, vid4095Action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getReservedVidAction + * Description: + * Get reserved VID action + * Input: + * pVid0Action - VID 0 action + * pVid4095Action - VID 4095 action + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * None + */ +ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action) +{ + ret_t retVal; + + if(pVid0Action == NULL) + return RT_ERR_NULL_POINTER; + + if(pVid4095Action == NULL) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, pVid0Action)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, pVid4095Action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtl8367c_setRealKeepRemarkEn + * Description: + * Set Real Keep Remark + * Input: + * enabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet + * Output: + * None + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error input + * Note: + * None + */ +ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_getRealKeepRemarkEn + * Description: + * Get Real Keep Remark + * Input: + * None + * Output: + * pEnabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error input + * Note: + * None + */ +ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled) +{ + ret_t retVal; + + if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, pEnabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtl8367c_resetVlan + * Description: + * Reset VLAN table + * Input: + * None. + * Output: + * None. + * Return: + * RT_ERR_OK - Success + * RT_ERR_SMI - SMI access error + * Note: + * None + */ +ret_t rtl8367c_resetVlan(void) +{ + ret_t retVal; + + if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL2, RTL8367C_VLAN_EXT_CTRL2_OFFSET, 1)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/smi.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/smi.c new file mode 100755 index 00000000..c272cad4 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/smi.c @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * Purpose : RTL8367C switch low-level function for access register + * Feature : SMI related functions + * + */ + + +#include +#include +#include "rtk_error.h" + + +#if defined(MDC_MDIO_OPERATION) +/*******************************************************************************/ +/* MDC/MDIO porting */ +/*******************************************************************************/ +/* define the PHY ID currently used */ +/* carlos */ +#if 0 +#define MDC_MDIO_PHY_ID 0 /* PHY ID 0 or 29 */ +#else +#define MDC_MDIO_PHY_ID 29 /* PHY ID 0 or 29 */ +#endif + +/* MDC/MDIO, redefine/implement the following Macro */ /*carlos*/ +#if 0 +#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) +#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) +#else +#define u32 unsigned int +extern u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data); +extern u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data); + +#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) mii_mgr_write(phyID, regID, data) +#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) mii_mgr_read(phyID, regID, pData) +#endif + + + + + +#elif defined(SPI_OPERATION) +/*******************************************************************************/ +/* SPI porting */ +/*******************************************************************************/ +/* SPI, redefine/implement the following Macro */ +#define SPI_WRITE(data, length) +#define SPI_READ(pData, length) + + + + + +#else +/*******************************************************************************/ +/* I2C porting */ +/*******************************************************************************/ +/* Define the GPIO ID for SCK & SDA */ +rtk_uint32 smi_SCK = 1; /* GPIO used for SMI Clock Generation */ +rtk_uint32 smi_SDA = 2; /* GPIO used for SMI Data signal */ + +/* I2C, redefine/implement the following Macro */ +#define GPIO_DIRECTION_SET(gpioID, direction) +#define GPIO_DATA_SET(gpioID, data) +#define GPIO_DATA_GET(gpioID, pData) + + + + + +#endif + +static void rtlglue_drvMutexLock(void) +{ + /* It is empty currently. Implement this function if Lock/Unlock function is needed */ + return; +} + +static void rtlglue_drvMutexUnlock(void) +{ + /* It is empty currently. Implement this function if Lock/Unlock function is needed */ + return; +} + + + +#if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) + /* No local function in MDC/MDIO & SPI mode */ +#else +static void _smi_start(void) +{ + + /* change GPIO pin to Output only */ + GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_OUT); + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); + + /* Initial state: SCK: 0, SDA: 1 */ + GPIO_DATA_SET(smi_SCK, 0); + GPIO_DATA_SET(smi_SDA, 1); + CLK_DURATION(DELAY); + + /* CLK 1: 0 -> 1, 1 -> 0 */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + + /* CLK 2: */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 1); + +} + + + +static void _smi_writeBit(rtk_uint16 signal, rtk_uint32 bitLen) +{ + for( ; bitLen > 0; bitLen--) + { + CLK_DURATION(DELAY); + + /* prepare data */ + if ( signal & (1<<(bitLen-1)) ) + { + GPIO_DATA_SET(smi_SDA, 1); + } + else + { + GPIO_DATA_SET(smi_SDA, 0); + } + CLK_DURATION(DELAY); + + /* clocking */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + } +} + + + +static void _smi_readBit(rtk_uint32 bitLen, rtk_uint32 *rData) +{ + rtk_uint32 u = 0; + + /* change GPIO pin to Input only */ + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); + + for (*rData = 0; bitLen > 0; bitLen--) + { + CLK_DURATION(DELAY); + + /* clocking */ + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_GET(smi_SDA, &u); + GPIO_DATA_SET(smi_SCK, 0); + + *rData |= (u << (bitLen - 1)); + } + + /* change GPIO pin to Output only */ + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); +} + + + +static void _smi_stop(void) +{ + + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 0); + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SDA, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 1); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 1); + + /* add a click */ + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 0); + CLK_DURATION(DELAY); + GPIO_DATA_SET(smi_SCK, 1); + + + /* change GPIO pin to Input only */ + GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); + GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_IN); +} + +#endif /* End of #if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) */ + +rtk_int32 smi_read(rtk_uint32 mAddrs, rtk_uint32 *rData) +{ +#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) + rtk_uint32 rawData=0, ACK; + rtk_uint8 con; + rtk_uint32 ret = RT_ERR_OK; +#endif + + if(mAddrs > 0xFFFF) + return RT_ERR_INPUT; + + if(rData == NULL) + return RT_ERR_NULL_POINTER; + +#if defined(MDC_MDIO_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write address control code to register 31 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); + + /* Write address to register 23 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); + + /* Write read control code to register 21 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP); + + /* Read data from register 25 */ + MDC_MDIO_READ(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_READ_REG, rData); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; + +#elif defined(SPI_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write 8 bits READ OP_CODE */ + SPI_WRITE(SPI_READ_OP, SPI_READ_OP_LEN); + + /* Write 16 bits register address */ + SPI_WRITE(mAddrs, SPI_REG_LEN); + + /* Read 16 bits data */ + SPI_READ(rData, SPI_DATA_LEN); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; + +#else + + /*Disable CPU interrupt to ensure that the SMI operation is atomic. + The API is based on RTL865X, rewrite the API if porting to other platform.*/ + rtlglue_drvMutexLock(); + + _smi_start(); /* Start SMI */ + + _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370 */ + + _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ + + _smi_writeBit(0x1, 1); /* 1: issue READ command */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for issuing READ command*/ + } while ((ACK != 0) && (con < ack_timer)); + + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ + } while ((ACK != 0) && (con < ack_timer)); + + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK by RTL8369 */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_readBit(8, &rawData); /* Read DATA [7:0] */ + *rData = rawData&0xff; + + _smi_writeBit(0x00, 1); /* ACK by CPU */ + + _smi_readBit(8, &rawData); /* Read DATA [15: 8] */ + + _smi_writeBit(0x01, 1); /* ACK by CPU */ + *rData |= (rawData<<8); + + _smi_stop(); + + rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ + + return ret; +#endif /* end of #if defined(MDC_MDIO_OPERATION) */ +} + + + +rtk_int32 smi_write(rtk_uint32 mAddrs, rtk_uint32 rData) +{ +#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) + rtk_int8 con; + rtk_uint32 ACK; + rtk_uint32 ret = RT_ERR_OK; +#endif + + if(mAddrs > 0xFFFF) + return RT_ERR_INPUT; + + if(rData > 0xFFFF) + return RT_ERR_INPUT; + +#if defined(MDC_MDIO_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write address control code to register 31 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); + + /* Write address to register 23 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); + + /* Write data to register 24 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_WRITE_REG, rData); + + /* Write data control code to register 21 */ + MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_WRITE_OP); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; + +#elif defined(SPI_OPERATION) + + /* Lock */ + rtlglue_drvMutexLock(); + + /* Write 8 bits WRITE OP_CODE */ + SPI_WRITE(SPI_WRITE_OP, SPI_WRITE_OP_LEN); + + /* Write 16 bits register address */ + SPI_WRITE(mAddrs, SPI_REG_LEN); + + /* Write 16 bits data */ + SPI_WRITE(rData, SPI_DATA_LEN); + + /* Unlock */ + rtlglue_drvMutexUnlock(); + + return RT_ERR_OK; +#else + + /*Disable CPU interrupt to ensure that the SMI operation is atomic. + The API is based on RTL865X, rewrite the API if porting to other platform.*/ + rtlglue_drvMutexLock(); + + _smi_start(); /* Start SMI */ + + _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370*/ + + _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ + + _smi_writeBit(0x0, 1); /* 0: issue WRITE command */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for issuing WRITE command*/ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for setting reg_addr[15:8] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit(rData&0xff, 8); /* Write Data [7:0] out */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for writting data [7:0] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_writeBit(rData>>8, 8); /* Write Data [15:8] out */ + + con = 0; + do { + con++; + _smi_readBit(1, &ACK); /* ACK for writting data [15:8] */ + } while ((ACK != 0) && (con < ack_timer)); + if (ACK != 0) ret = RT_ERR_FAILED; + + _smi_stop(); + + rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ + + return ret; +#endif /* end of #if defined(MDC_MDIO_OPERATION) */ +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/stat.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/stat.c new file mode 100755 index 00000000..3a328b0c --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/stat.c @@ -0,0 +1,626 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in MIB module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_stat_global_reset + * Description: + * Reset global MIB counter. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Reset MIB counter of ports. API will use global reset while port mask is all-ports. + */ +rtk_api_ret_t rtk_stat_global_reset(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicMIBsCounterReset(TRUE,FALSE, 0)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_port_reset + * Description: + * Reset per port MIB counter by port. + * Input: + * port - port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_stat_port_reset(rtk_port_t port) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,FALSE,1 << rtk_switch_port_L2P_get(port))) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_queueManage_reset + * Description: + * Reset queue manage MIB counter. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_stat_queueManage_reset(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,TRUE,0)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_stat_global_get + * Description: + * Get global MIB counter + * Input: + * cntr_idx - global counter index. + * Output: + * pCntr - global counter value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get global MIB counter by index definition. + */ +rtk_api_ret_t rtk_stat_global_get(rtk_stat_global_type_t cntr_idx, rtk_stat_counter_t *pCntr) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCntr) + return RT_ERR_NULL_POINTER; + + if (cntr_idx!=DOT1D_TP_LEARNED_ENTRY_DISCARDS_INDEX) + return RT_ERR_STAT_INVALID_GLOBAL_CNTR; + + if ((retVal = rtl8367c_getAsicMIBsCounter(0, cntr_idx, pCntr)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_global_getAll + * Description: + * Get all global MIB counter + * Input: + * None + * Output: + * pGlobal_cntrs - global counter structure. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get all global MIB counter by index definition. + */ +rtk_api_ret_t rtk_stat_global_getAll(rtk_stat_global_cntr_t *pGlobal_cntrs) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pGlobal_cntrs) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicMIBsCounter(0,DOT1D_TP_LEARNED_ENTRY_DISCARDS_INDEX, &pGlobal_cntrs->dot1dTpLearnedEntryDiscards)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +#define MIB_NOT_SUPPORT (0xFFFF) +static rtk_api_ret_t _get_asic_mib_idx(rtk_stat_port_type_t cnt_idx, RTL8367C_MIBCOUNTER *pMib_idx) +{ + RTL8367C_MIBCOUNTER mib_asic_idx[STAT_PORT_CNTR_END]= + { + ifInOctets, /* STAT_IfInOctets */ + dot3StatsFCSErrors, /* STAT_Dot3StatsFCSErrors */ + dot3StatsSymbolErrors, /* STAT_Dot3StatsSymbolErrors */ + dot3InPauseFrames, /* STAT_Dot3InPauseFrames */ + dot3ControlInUnknownOpcodes, /* STAT_Dot3ControlInUnknownOpcodes */ + etherStatsFragments, /* STAT_EtherStatsFragments */ + etherStatsJabbers, /* STAT_EtherStatsJabbers */ + ifInUcastPkts, /* STAT_IfInUcastPkts */ + etherStatsDropEvents, /* STAT_EtherStatsDropEvents */ + etherStatsOctets, /* STAT_EtherStatsOctets */ + etherStatsUnderSizePkts, /* STAT_EtherStatsUnderSizePkts */ + etherOversizeStats, /* STAT_EtherOversizeStats */ + etherStatsPkts64Octets, /* STAT_EtherStatsPkts64Octets */ + etherStatsPkts65to127Octets, /* STAT_EtherStatsPkts65to127Octets */ + etherStatsPkts128to255Octets, /* STAT_EtherStatsPkts128to255Octets */ + etherStatsPkts256to511Octets, /* STAT_EtherStatsPkts256to511Octets */ + etherStatsPkts512to1023Octets, /* STAT_EtherStatsPkts512to1023Octets */ + etherStatsPkts1024to1518Octets, /* STAT_EtherStatsPkts1024to1518Octets */ + ifInMulticastPkts, /* STAT_EtherStatsMulticastPkts */ + ifInBroadcastPkts, /* STAT_EtherStatsBroadcastPkts */ + ifOutOctets, /* STAT_IfOutOctets */ + dot3StatsSingleCollisionFrames, /* STAT_Dot3StatsSingleCollisionFrames */ + dot3StatMultipleCollisionFrames,/* STAT_Dot3StatsMultipleCollisionFrames */ + dot3sDeferredTransmissions, /* STAT_Dot3StatsDeferredTransmissions */ + dot3StatsLateCollisions, /* STAT_Dot3StatsLateCollisions */ + etherStatsCollisions, /* STAT_EtherStatsCollisions */ + dot3StatsExcessiveCollisions, /* STAT_Dot3StatsExcessiveCollisions */ + dot3OutPauseFrames, /* STAT_Dot3OutPauseFrames */ + MIB_NOT_SUPPORT, /* STAT_Dot1dBasePortDelayExceededDiscards */ + dot1dTpPortInDiscards, /* STAT_Dot1dTpPortInDiscards */ + ifOutUcastPkts, /* STAT_IfOutUcastPkts */ + ifOutMulticastPkts, /* STAT_IfOutMulticastPkts */ + ifOutBroadcastPkts, /* STAT_IfOutBroadcastPkts */ + outOampduPkts, /* STAT_OutOampduPkts */ + inOampduPkts, /* STAT_InOampduPkts */ + MIB_NOT_SUPPORT, /* STAT_PktgenPkts */ + inMldChecksumError, /* STAT_InMldChecksumError */ + inIgmpChecksumError, /* STAT_InIgmpChecksumError */ + inMldSpecificQuery, /* STAT_InMldSpecificQuery */ + inMldGeneralQuery, /* STAT_InMldGeneralQuery */ + inIgmpSpecificQuery, /* STAT_InIgmpSpecificQuery */ + inIgmpGeneralQuery, /* STAT_InIgmpGeneralQuery */ + inMldLeaves, /* STAT_InMldLeaves */ + inIgmpLeaves, /* STAT_InIgmpInterfaceLeaves */ + inIgmpJoinsSuccess, /* STAT_InIgmpJoinsSuccess */ + inIgmpJoinsFail, /* STAT_InIgmpJoinsFail */ + inMldJoinsSuccess, /* STAT_InMldJoinsSuccess */ + inMldJoinsFail, /* STAT_InMldJoinsFail */ + inReportSuppressionDrop, /* STAT_InReportSuppressionDrop */ + inLeaveSuppressionDrop, /* STAT_InLeaveSuppressionDrop */ + outIgmpReports, /* STAT_OutIgmpReports */ + outIgmpLeaves, /* STAT_OutIgmpLeaves */ + outIgmpGeneralQuery, /* STAT_OutIgmpGeneralQuery */ + outIgmpSpecificQuery, /* STAT_OutIgmpSpecificQuery */ + outMldReports, /* STAT_OutMldReports */ + outMldLeaves, /* STAT_OutMldLeaves */ + outMldGeneralQuery, /* STAT_OutMldGeneralQuery */ + outMldSpecificQuery, /* STAT_OutMldSpecificQuery */ + inKnownMulticastPkts, /* STAT_InKnownMulticastPkts */ + ifInMulticastPkts, /* STAT_IfInMulticastPkts */ + ifInBroadcastPkts, /* STAT_IfInBroadcastPkts */ + ifOutDiscards /* STAT_IfOutDiscards */ + }; + + if(cnt_idx >= STAT_PORT_CNTR_END) + return RT_ERR_STAT_INVALID_PORT_CNTR; + + if(mib_asic_idx[cnt_idx] == MIB_NOT_SUPPORT) + return RT_ERR_CHIP_NOT_SUPPORTED; + + *pMib_idx = mib_asic_idx[cnt_idx]; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_port_get + * Description: + * Get per port MIB counter by index + * Input: + * port - port id. + * cntr_idx - port counter index. + * Output: + * pCntr - MIB retrived counter. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Get per port MIB counter by index definition. + */ +rtk_api_ret_t rtk_stat_port_get(rtk_port_t port, rtk_stat_port_type_t cntr_idx, rtk_stat_counter_t *pCntr) +{ + rtk_api_ret_t retVal; + RTL8367C_MIBCOUNTER mib_idx; + rtk_stat_counter_t second_cnt; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCntr) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + if (cntr_idx>=STAT_PORT_CNTR_END) + return RT_ERR_STAT_INVALID_PORT_CNTR; + + if((retVal = _get_asic_mib_idx(cntr_idx, &mib_idx)) != RT_ERR_OK) + return retVal; + + if(mib_idx == MIB_NOT_SUPPORT) + return RT_ERR_CHIP_NOT_SUPPORTED; + + if ((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, pCntr)) != RT_ERR_OK) + return retVal; + + if(cntr_idx == STAT_EtherStatsMulticastPkts) + { + if((retVal = _get_asic_mib_idx(STAT_IfOutMulticastPkts, &mib_idx)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) + return retVal; + + *pCntr += second_cnt; + } + + if(cntr_idx == STAT_EtherStatsBroadcastPkts) + { + if((retVal = _get_asic_mib_idx(STAT_IfOutBroadcastPkts, &mib_idx)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) + return retVal; + + *pCntr += second_cnt; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_port_getAll + * Description: + * Get all counters of one specified port in the specified device. + * Input: + * port - port id. + * Output: + * pPort_cntrs - buffer pointer of counter value. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get all MIB counters of one port. + */ +rtk_api_ret_t rtk_stat_port_getAll(rtk_port_t port, rtk_stat_port_cntr_t *pPort_cntrs) +{ + rtk_api_ret_t retVal; + rtk_uint32 mibIndex; + rtk_uint64 mibCounter; + rtk_uint32 *accessPtr; + /* address offset to MIBs counter */ + CONST_T rtk_uint16 mibLength[STAT_PORT_CNTR_END]= { + 2,1,1,1,1,1,1,1,1, + 2,1,1,1,1,1,1,1,1,1,1, + 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPort_cntrs) + return RT_ERR_NULL_POINTER; + + /* Check port valid */ + RTK_CHK_PORT_VALID(port); + + accessPtr = (rtk_uint32*)pPort_cntrs; + for (mibIndex=0;mibIndex RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((idx % 2) == 1) + return RT_ERR_INPUT; + + if(mode >= LOGGING_MODE_END) + return RT_ERR_OUT_OF_RANGE; + + if(type >= LOGGING_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + if((retVal = rtl8367c_setAsicMIBsLoggingType((idx / 2), (rtk_uint32)type)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicMIBsLoggingMode((idx / 2), (rtk_uint32)mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_logging_counterCfg_get + * Description: + * Get the type and mode of Logging Counter + * Input: + * idx - The index of Logging Counter. Should be even number only.(0,2,4,6,8.....30) + * Output: + * pMode - 32 bits or 64 bits mode + * pType - Packet counter or byte counter + * Return: + * RT_ERR_OK - OK + * RT_ERR_OUT_OF_RANGE - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_NULL_POINTER - NULL Pointer + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * Get the type and mode of Logging Counter. + */ +rtk_api_ret_t rtk_stat_logging_counterCfg_get(rtk_uint32 idx, rtk_logging_counter_mode_t *pMode, rtk_logging_counter_type_t *pType) +{ + rtk_api_ret_t retVal; + rtk_uint32 type, mode; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((idx % 2) == 1) + return RT_ERR_INPUT; + + if(pMode == NULL) + return RT_ERR_NULL_POINTER; + + if(pType == NULL) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMIBsLoggingType((idx / 2), &type)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicMIBsLoggingMode((idx / 2), &mode)) != RT_ERR_OK) + return retVal; + + *pMode = (rtk_logging_counter_mode_t)mode; + *pType = (rtk_logging_counter_type_t)type; + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_stat_logging_counter_reset + * Description: + * Reset Logging Counter + * Input: + * idx - The index of Logging Counter. (0~31) + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_OUT_OF_RANGE - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Reset Logging Counter. + */ +rtk_api_ret_t rtk_stat_logging_counter_reset(rtk_uint32 idx) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((retVal = rtl8367c_setAsicMIBsResetLoggingCounter(idx)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_logging_counter_get + * Description: + * Get Logging Counter + * Input: + * idx - The index of Logging Counter. (0~31) + * Output: + * pCnt - Logging counter value + * Return: + * RT_ERR_OK - OK + * RT_ERR_OUT_OF_RANGE - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Get Logging Counter. + */ +rtk_api_ret_t rtk_stat_logging_counter_get(rtk_uint32 idx, rtk_uint32 *pCnt) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCnt) + return RT_ERR_NULL_POINTER; + + if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) + return RT_ERR_OUT_OF_RANGE; + + if((retVal = rtl8367c_getAsicMIBsLogCounter(idx, pCnt)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_lengthMode_set + * Description: + * Set Legnth mode. + * Input: + * txMode - The length counting mode + * rxMode - The length counting mode + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * + */ +rtk_api_ret_t rtk_stat_lengthMode_set(rtk_stat_lengthMode_t txMode, rtk_stat_lengthMode_t rxMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(txMode >= LENGTH_MODE_END) + return RT_ERR_INPUT; + + if(rxMode >= LENGTH_MODE_END) + return RT_ERR_INPUT; + + if((retVal = rtl8367c_setAsicMIBsLength((rtk_uint32)txMode, (rtk_uint32)rxMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stat_lengthMode_get + * Description: + * Get Legnth mode. + * Input: + * None. + * Output: + * pTxMode - The length counting mode + * pRxMode - The length counting mode + * Return: + * RT_ERR_OK - OK + * RT_ERR_INPUT - Out of range. + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + */ +rtk_api_ret_t rtk_stat_lengthMode_get(rtk_stat_lengthMode_t *pTxMode, rtk_stat_lengthMode_t *pRxMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pTxMode) + return RT_ERR_NULL_POINTER; + + if(NULL == pRxMode) + return RT_ERR_NULL_POINTER; + + if((retVal = rtl8367c_getAsicMIBsLength((rtk_uint32 *)pTxMode, (rtk_uint32 *)pRxMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/storm.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/storm.c new file mode 100755 index 00000000..13cf4e3c --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/storm.c @@ -0,0 +1,816 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Storm module. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_rate_stormControlMeterIdx_set + * Description: + * Set the storm control meter index. + * Input: + * port - port id + * storm_type - storm group type + * index - storm control meter index. + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - Invalid port id + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlMeterIdx_set(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 index) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlMeterIdx_get + * Description: + * Get the storm control meter index. + * Input: + * port - port id + * storm_type - storm group type + * Output: + * pIndex - storm control meter index. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_PORT_ID - Invalid port id + * RT_ERR_FILTER_METER_ID - Invalid meter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlMeterIdx_get(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (NULL == pIndex ) + return RT_ERR_NULL_POINTER; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlPortEnable_set + * Description: + * Set enable status of storm control on specified port. + * Input: + * port - port id + * stormType - storm group type + * enable - enable status of storm control + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlPortEnable_set(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlPortEnable_set + * Description: + * Set enable status of storm control on specified port. + * Input: + * port - port id + * stormType - storm group type + * Output: + * pEnable - enable status of storm control + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_PORT_ID - invalid port id + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlPortEnable_get(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (NULL == pEnable) + return RT_ERR_ENABLE; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_storm_bypass_set + * Description: + * Set bypass storm filter control configuration. + * Input: + * type - Bypass storm filter control type. + * enable - Bypass status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * This API can set per-port bypass stomr filter control frame type including RMA and igmp. + * The bypass frame type is as following: + * - BYPASS_BRG_GROUP, + * - BYPASS_FD_PAUSE, + * - BYPASS_SP_MCAST, + * - BYPASS_1X_PAE, + * - BYPASS_UNDEF_BRG_04, + * - BYPASS_UNDEF_BRG_05, + * - BYPASS_UNDEF_BRG_06, + * - BYPASS_UNDEF_BRG_07, + * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - BYPASS_UNDEF_BRG_09, + * - BYPASS_UNDEF_BRG_0A, + * - BYPASS_UNDEF_BRG_0B, + * - BYPASS_UNDEF_BRG_0C, + * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - BYPASS_8021AB, + * - BYPASS_UNDEF_BRG_0F, + * - BYPASS_BRG_MNGEMENT, + * - BYPASS_UNDEFINED_11, + * - BYPASS_UNDEFINED_12, + * - BYPASS_UNDEFINED_13, + * - BYPASS_UNDEFINED_14, + * - BYPASS_UNDEFINED_15, + * - BYPASS_UNDEFINED_16, + * - BYPASS_UNDEFINED_17, + * - BYPASS_UNDEFINED_18, + * - BYPASS_UNDEFINED_19, + * - BYPASS_UNDEFINED_1A, + * - BYPASS_UNDEFINED_1B, + * - BYPASS_UNDEFINED_1C, + * - BYPASS_UNDEFINED_1D, + * - BYPASS_UNDEFINED_1E, + * - BYPASS_UNDEFINED_1F, + * - BYPASS_GMRP, + * - BYPASS_GVRP, + * - BYPASS_UNDEF_GARP_22, + * - BYPASS_UNDEF_GARP_23, + * - BYPASS_UNDEF_GARP_24, + * - BYPASS_UNDEF_GARP_25, + * - BYPASS_UNDEF_GARP_26, + * - BYPASS_UNDEF_GARP_27, + * - BYPASS_UNDEF_GARP_28, + * - BYPASS_UNDEF_GARP_29, + * - BYPASS_UNDEF_GARP_2A, + * - BYPASS_UNDEF_GARP_2B, + * - BYPASS_UNDEF_GARP_2C, + * - BYPASS_UNDEF_GARP_2D, + * - BYPASS_UNDEF_GARP_2E, + * - BYPASS_UNDEF_GARP_2F, + * - BYPASS_IGMP. + * - BYPASS_CDP. + * - BYPASS_CSSTP. + * - BYPASS_LLDP. + */ +rtk_api_ret_t rtk_storm_bypass_set(rtk_storm_bypass_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= BYPASS_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if(type == BYPASS_IGMP) + { + if ((retVal = rtl8367c_setAsicIGMPBypassStormCTRL(enable)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.discard_storm_filter = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_storm_bypass_get + * Description: + * Get bypass storm filter control configuration. + * Input: + * type - Bypass storm filter control type. + * Output: + * pEnable - Bypass status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get per-port bypass stomr filter control frame type including RMA and igmp. + * The bypass frame type is as following: + * - BYPASS_BRG_GROUP, + * - BYPASS_FD_PAUSE, + * - BYPASS_SP_MCAST, + * - BYPASS_1X_PAE, + * - BYPASS_UNDEF_BRG_04, + * - BYPASS_UNDEF_BRG_05, + * - BYPASS_UNDEF_BRG_06, + * - BYPASS_UNDEF_BRG_07, + * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - BYPASS_UNDEF_BRG_09, + * - BYPASS_UNDEF_BRG_0A, + * - BYPASS_UNDEF_BRG_0B, + * - BYPASS_UNDEF_BRG_0C, + * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - BYPASS_8021AB, + * - BYPASS_UNDEF_BRG_0F, + * - BYPASS_BRG_MNGEMENT, + * - BYPASS_UNDEFINED_11, + * - BYPASS_UNDEFINED_12, + * - BYPASS_UNDEFINED_13, + * - BYPASS_UNDEFINED_14, + * - BYPASS_UNDEFINED_15, + * - BYPASS_UNDEFINED_16, + * - BYPASS_UNDEFINED_17, + * - BYPASS_UNDEFINED_18, + * - BYPASS_UNDEFINED_19, + * - BYPASS_UNDEFINED_1A, + * - BYPASS_UNDEFINED_1B, + * - BYPASS_UNDEFINED_1C, + * - BYPASS_UNDEFINED_1D, + * - BYPASS_UNDEFINED_1E, + * - BYPASS_UNDEFINED_1F, + * - BYPASS_GMRP, + * - BYPASS_GVRP, + * - BYPASS_UNDEF_GARP_22, + * - BYPASS_UNDEF_GARP_23, + * - BYPASS_UNDEF_GARP_24, + * - BYPASS_UNDEF_GARP_25, + * - BYPASS_UNDEF_GARP_26, + * - BYPASS_UNDEF_GARP_27, + * - BYPASS_UNDEF_GARP_28, + * - BYPASS_UNDEF_GARP_29, + * - BYPASS_UNDEF_GARP_2A, + * - BYPASS_UNDEF_GARP_2B, + * - BYPASS_UNDEF_GARP_2C, + * - BYPASS_UNDEF_GARP_2D, + * - BYPASS_UNDEF_GARP_2E, + * - BYPASS_UNDEF_GARP_2F, + * - BYPASS_IGMP. + * - BYPASS_CDP. + * - BYPASS_CSSTP. + * - BYPASS_LLDP. + */ +rtk_api_ret_t rtk_storm_bypass_get(rtk_storm_bypass_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= BYPASS_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else if(type == BYPASS_IGMP) + { + if ((retVal = rtl8367c_getAsicIGMPBypassStormCTRL(pEnable)) != RT_ERR_OK) + return retVal; + } + else if (type == BYPASS_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else if (type == BYPASS_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else if (type == BYPASS_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.discard_storm_filter; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtPortmask_set + * Description: + * Set externsion storm control port mask + * Input: + * pPortmask - port mask + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtPortmask_set(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicStormFilterExtEnablePortMask(pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtPortmask_get + * Description: + * Set externsion storm control port mask + * Input: + * None + * Output: + * pPortmask - port mask + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtPortmask_get(rtk_portmask_t *pPortmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pPortmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicStormFilterExtEnablePortMask(&pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtEnable_set + * Description: + * Set externsion storm control state + * Input: + * stormType - storm group type + * enable - externsion storm control state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtEnable_set(rtk_rate_storm_group_t stormType, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtMulticastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastEnable(enable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtEnable_get + * Description: + * Get externsion storm control state + * Input: + * stormType - storm group type + * Output: + * pEnable - externsion storm control state + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtEnable_get(rtk_rate_storm_group_t stormType, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (NULL == pEnable) + return RT_ERR_NULL_POINTER; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtMeterIdx_set + * Description: + * Set externsion storm control meter index + * Input: + * stormType - storm group type + * index - externsion storm control state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_set(rtk_rate_storm_group_t stormType, rtk_uint32 index) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if (index > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_setAsicStormFilterExtMulticastMeter(index))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastMeter(index))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_rate_stormControlExtMeterIdx_get + * Description: + * Get externsion storm control meter index + * Input: + * stormType - storm group type + * pIndex - externsion storm control state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - invalid input parameter + * Note: + * + */ +rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_get(rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (stormType >= STORM_GROUP_END) + return RT_ERR_SFC_UNKNOWN_GROUP; + + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + switch (stormType) + { + case STORM_GROUP_UNKNOWN_UNICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_UNKNOWN_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_MULTICAST: + if ((retVal = rtl8367c_getAsicStormFilterExtMulticastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + case STORM_GROUP_BROADCAST: + if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastMeter(pIndex))!=RT_ERR_OK) + return retVal; + break; + default: + break; + } + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/svlan.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/svlan.c new file mode 100755 index 00000000..bf4ef044 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/svlan.c @@ -0,0 +1,2415 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in SVLAN module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +rtk_uint8 svlan_mbrCfgUsage[RTL8367C_SVIDXNO]; +rtk_uint16 svlan_mbrCfgVid[RTL8367C_SVIDXNO]; +rtk_svlan_lookupType_t svlan_lookupType; +/* Function Name: + * rtk_svlan_init + * Description: + * Initialize SVLAN Configuration + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 for Q-in-Q SLAN design. + * User can set mathced ether type as service provider supported protocol. + */ +rtk_api_ret_t rtk_svlan_init(void) +{ + rtk_uint32 i; + rtk_api_ret_t retVal; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + rtk_uint32 svidx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /*default use C-priority*/ + if ((retVal = rtl8367c_setAsicSvlanPrioritySel(SPRISEL_CTAGPRI)) != RT_ERR_OK) + return retVal; + + /*Drop SVLAN untag frame*/ + if ((retVal = rtl8367c_setAsicSvlanIngressUntag(UNTAG_DROP)) != RT_ERR_OK) + return retVal; + + /*Drop SVLAN unmatch frame*/ + if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch(UNMATCH_DROP)) != RT_ERR_OK) + return retVal; + + /*Set TPID to 0x88a8*/ + if ((retVal = rtl8367c_setAsicSvlanTpid(0x88a8)) != RT_ERR_OK) + return retVal; + + /*Clean Uplink Port Mask to none*/ + if ((retVal = rtl8367c_setAsicSvlanUplinkPortMask(0)) != RT_ERR_OK) + return retVal; + + /*Clean SVLAN Member Configuration*/ + for (i=0; i<= RTL8367C_SVIDXMAX; i++) + { + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + } + + /*Clean C2S Configuration*/ + for (i=0; i<= RTL8367C_C2SIDXMAX; i++) + { + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, 0,0,0)) != RT_ERR_OK) + return retVal; + } + + /*Clean SP2C Configuration*/ + for (i=0; i <= RTL8367C_SP2CMAX ; i++) + { + memset(&svlanSP2CConf, 0, sizeof(rtl8367c_svlan_s2c_t)); + if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + } + + /*Clean MC2S Configuration*/ + for (i=0 ; i<= RTL8367C_MC2SIDXMAX; i++) + { + memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + } + + + if ((retVal = rtk_svlan_lookupType_set(SVLAN_LOOKUP_S64MBRCGF)) != RT_ERR_OK) + return retVal; + + + for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) + { + svlan_mbrCfgUsage[svidx] = FALSE; + } + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_servicePort_add + * Description: + * Add one service port in the specified device + * Input: + * port - Port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API is setting which port is connected to provider switch. All frames receiving from this port must + * contain accept SVID in S-tag field. + */ +rtk_api_ret_t rtk_svlan_servicePort_add(rtk_port_t port) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicSvlanUplinkPortMask(&pmsk)) != RT_ERR_OK) + return retVal; + + pmsk = pmsk | (1<RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicSvlanTpid(svlan_tag_id)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_tpidEntry_get + * Description: + * Get accepted S-VLAN ether type setting. + * Input: + * None + * Output: + * pSvlan_tag_id - Ether type of S-tag frame parsing in uplink ports. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * This API is setting which port is connected to provider switch. All frames receiving from this port must + * contain accept SVID in S-tag field. + */ +rtk_api_ret_t rtk_svlan_tpidEntry_get(rtk_svlan_tpid_t *pSvlan_tag_id) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_tag_id) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanTpid(pSvlan_tag_id)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_priorityRef_set + * Description: + * Set S-VLAN upstream priority reference setting. + * Input: + * ref - reference selection parameter. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * Note: + * The API can set the upstream SVLAN tag priority reference source. The related priority + * sources are as following: + * - REF_INTERNAL_PRI, + * - REF_CTAG_PRI, + * - REF_SVLAN_PRI, + * - REF_PB_PRI. + */ +rtk_api_ret_t rtk_svlan_priorityRef_set(rtk_svlan_pri_ref_t ref) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (ref >= REF_PRI_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicSvlanPrioritySel(ref)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_priorityRef_get + * Description: + * Get S-VLAN upstream priority reference setting. + * Input: + * None + * Output: + * pRef - reference selection parameter. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * The API can get the upstream SVLAN tag priority reference source. The related priority + * sources are as following: + * - REF_INTERNAL_PRI, + * - REF_CTAG_PRI, + * - REF_SVLAN_PRI, + * - REF_PB_PRI + */ +rtk_api_ret_t rtk_svlan_priorityRef_get(rtk_svlan_pri_ref_t *pRef) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pRef) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanPrioritySel(pRef)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_memberPortEntry_set + * Description: + * Configure system SVLAN member content + * Input: + * svid - SVLAN id + * psvlan_cfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. + * Note: + * The API can set system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped by default setup. + * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtk_int32 i; + rtk_uint32 empty_idx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_uint32 phyMbrPmask; + rtk_vlan_cfg_t vlanCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if(svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); + + if (pSvlan_cfg->fiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if (pSvlan_cfg->priority > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if (pSvlan_cfg->efiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + if(SVLAN_LOOKUP_C4KVLAN == svlan_lookupType) + { + if ((retVal = rtk_vlan_get(svid, &vlanCfg)) != RT_ERR_OK) + return retVal; + + vlanCfg.mbr = pSvlan_cfg->memberport; + vlanCfg.untag = pSvlan_cfg->untagport; + + if ((retVal = rtk_vlan_set(svid, &vlanCfg)) != RT_ERR_OK) + return retVal; + + empty_idx = 0xFF; + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) + { + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = svid; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + + /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + svlanMemConf.vs_efid = 1; + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) + { + empty_idx = i; + } + } + + if (empty_idx != 0xFF) + { + svlan_mbrCfgUsage[empty_idx] = TRUE; + svlan_mbrCfgVid[empty_idx] = svid; + + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = svid; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + + /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + svlanMemConf.vs_efid = 1; + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + } + + return RT_ERR_OK; + } + + + empty_idx = 0xFF; + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + /* + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + */ + if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) + { + svlanMemConf.vs_svid = svid; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_member = phyMbrPmask; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_untag = phyMbrPmask; + + svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; + svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + + /*all items are reset means deleting*/ + if( 0 == svlanMemConf.vs_member && + 0 == svlanMemConf.vs_untag && + 0 == svlanMemConf.vs_force_fid && + 0 == svlanMemConf.vs_fid_msti && + 0 == svlanMemConf.vs_priority && + 0 == svlanMemConf.vs_efiden && + 0 == svlanMemConf.vs_efid) + { + svlan_mbrCfgUsage[i] = FALSE; + svlan_mbrCfgVid[i] = 0; + + /* Clear SVID also */ + svlanMemConf.vs_svid = 0; + } + else + { + svlan_mbrCfgUsage[i] = TRUE; + svlan_mbrCfgVid[i] = svlanMemConf.vs_svid; + + if(0 == svlanMemConf.vs_svid) + { + /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + { + svlanMemConf.vs_efid = 1; + } + } + } + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) + { + empty_idx = i; + } + } + + if (empty_idx != 0xFF) + { + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = svid; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_member = phyMbrPmask; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_untag = phyMbrPmask; + + svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; + svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + + /*change efid for empty svid 0*/ + if(0 == svlanMemConf.vs_svid) + { /*for create check*/ + if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) + { + svlanMemConf.vs_efid = 1; + } + } + + svlan_mbrCfgUsage[empty_idx] = TRUE; + svlan_mbrCfgVid[empty_idx] = svlanMemConf.vs_svid; + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) + { + return retVal; + } + + return RT_ERR_OK; + } + + return RT_ERR_SVLAN_TABLE_FULL; +} + +/* Function Name: + * rtk_svlan_memberPortEntry_get + * Description: + * Get SVLAN member Configure. + * Input: + * svid - SVLAN id + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + pSvlan_cfg->svid = svlanMemConf.vs_svid; + + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; + pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; + pSvlan_cfg->priority = svlanMemConf.vs_priority; + pSvlan_cfg->efiden = svlanMemConf.vs_efiden; + pSvlan_cfg->efid = svlanMemConf.vs_efid; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + +} + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_set + * Description: + * Configure system SVLAN member by index + * Input: + * idx - Index (0 ~ 63) + * psvlan_cfg - SVLAN member configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_PORT_MASK - Invalid portmask. + * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. + * Note: + * The API can set system 64 accepted s-tag frame format by index. + * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. + * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_uint32 phyMbrPmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if (idx > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + if (pSvlan_cfg->svid>RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); + + RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); + + if (pSvlan_cfg->fiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->fid > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if (pSvlan_cfg->priority > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if (pSvlan_cfg->efiden > ENABLED) + return RT_ERR_ENABLE; + + if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) + return RT_ERR_L2_FID; + + memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); + svlanMemConf.vs_svid = pSvlan_cfg->svid; + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_member = phyMbrPmask; + + if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + svlanMemConf.vs_untag = phyMbrPmask; + + + svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; + svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; + svlanMemConf.vs_priority = pSvlan_cfg->priority; + svlanMemConf.vs_efiden = pSvlan_cfg->efiden; + svlanMemConf.vs_efid = pSvlan_cfg->efid; + + if(0 == svlanMemConf.vs_svid && + 0 == svlanMemConf.vs_member && + 0 == svlanMemConf.vs_untag && + 0 == svlanMemConf.vs_force_fid && + 0 == svlanMemConf.vs_fid_msti && + 0 == svlanMemConf.vs_priority && + 0 == svlanMemConf.vs_efiden && + 0 == svlanMemConf.vs_efid) + { + svlan_mbrCfgUsage[idx] = FALSE; + svlan_mbrCfgVid[idx] = 0; + } + else + { + svlan_mbrCfgUsage[idx] = TRUE; + svlan_mbrCfgVid[idx] = svlanMemConf.vs_svid; + } + + if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_memberPortEntry_adv_get + * Description: + * Get SVLAN member Configure by index. + * Input: + * idx - Index (0 ~ 63) + * Output: + * pSvlan_cfg - SVLAN member configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted + * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. + */ +rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) +{ + rtk_api_ret_t retVal; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvlan_cfg) + return RT_ERR_NULL_POINTER; + + if (idx > RTL8367C_SVIDXMAX) + return RT_ERR_SVLAN_ENTRY_INDEX; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + pSvlan_cfg->svid = svlanMemConf.vs_svid; + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; + pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; + pSvlan_cfg->priority = svlanMemConf.vs_priority; + pSvlan_cfg->efiden = svlanMemConf.vs_efiden; + pSvlan_cfg->efid = svlanMemConf.vs_efid; + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_svlan_defaultSvlan_set + * Description: + * Configure default egress SVLAN. + * Input: + * port - Source port + * svid - SVLAN id + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * Note: + * The API can set port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + /* svid must be 0~4095 */ + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + if ((retVal = rtl8367c_setAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), i)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; +} + +/* Function Name: + * rtk_svlan_defaultSvlan_get + * Description: + * Get the configure default egress SVLAN. + * Input: + * port - Source port + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can get port n S-tag format index while receiving frame from port n + * is transmit through uplink port with s-tag field + */ +rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 idx; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), &idx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_c2s_add + * Description: + * Configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set system C2S configuration. ASIC will check upstream's VID and assign related + * SVID to mathed packet. There are 128 SVLAN C2S configurations. + */ +rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx; + rtk_uint32 evid, pmsk, svidx, c2s_svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_port_t phyPort; + rtk_uint16 doneFlag; + + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(src_port); + + phyPort = rtk_switch_port_L2P_get(src_port); + + empty_idx = 0xFFFF; + svidx = 0xFFFF; + doneFlag = FALSE; + + for (i = 0; i<= RTL8367C_SVIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_VID; + + for (i=RTL8367C_C2SIDXMAX; i>=0; i--) + { + if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &c2s_svidx)) != RT_ERR_OK) + return retVal; + + if (evid == vid) + { + /* Check Src_port */ + if(pmsk & (1 << phyPort)) + { + /* Check SVIDX */ + if(c2s_svidx == svidx) + { + /* All the same, do nothing */ + } + else + { + /* New svidx, remove src_port and find a new slot to add a new enrty */ + pmsk = pmsk & ~(1 << phyPort); + if(pmsk == 0) + c2s_svidx = 0; + + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, c2s_svidx)) != RT_ERR_OK) + return retVal; + } + } + else + { + if(c2s_svidx == svidx && doneFlag == FALSE) + { + pmsk = pmsk | (1 << phyPort); + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) + return retVal; + + doneFlag = TRUE; + } + } + } + else if (evid==0&&pmsk==0) + { + empty_idx = i; + } + } + + if (0xFFFF != empty_idx && doneFlag ==FALSE) + { + if ((retVal = rtl8367c_setAsicSvlanC2SConf(empty_idx, vid, (1< RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(src_port); + phyPort = rtk_switch_port_L2P_get(src_port); + + for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) + return retVal; + + if (evid == vid) + { + if(pmsk & (1 << phyPort)) + { + pmsk = pmsk & ~(1 << phyPort); + if(pmsk == 0) + { + vid = 0; + svidx = 0; + } + + if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_c2s_get + * Description: + * Get configure SVLAN C2S table + * Input: + * vid - VLAN ID + * src_port - Ingress Port + * Output: + * pSvid - SVLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. + */ +rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 evid, pmsk, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtk_port_t phyPort; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(src_port); + phyPort = rtk_switch_port_L2P_get(src_port); + + for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) + return retVal; + + if (evid == vid) + { + if(pmsk & (1 << phyPort)) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_untag_action_set + * Description: + * Configure Action of downstream UnStag packet + * Input: + * action - Action for UnStag + * svid - The SVID assigned to UnStag packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also supported by this API. The parameter of svid is + * only referenced when the action is set to UNTAG_ASSIGN + */ +rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (action >= UNTAG_END) + return RT_ERR_OUT_OF_RANGE; + + if(action == UNTAG_ASSIGN) + { + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + } + + if ((retVal = rtl8367c_setAsicSvlanIngressUntag((rtk_uint32)action)) != RT_ERR_OK) + return retVal; + + if(action == UNTAG_ASSIGN) + { + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + if ((retVal = rtl8367c_setAsicSvlanUntagVlan(i)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_untag_action_get + * Description: + * Get Action of downstream UnStag packet + * Input: + * None + * Output: + * pAction - Action for UnStag + * pSvid - The SVID assigned to UnStag packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-Stag packet. A SVID assigned + * to the un-stag is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNTAG_ASSIGN + */ +rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction || NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanIngressUntag(pAction)) != RT_ERR_OK) + return retVal; + + if(*pAction == UNTAG_ASSIGN) + { + if ((retVal = rtl8367c_getAsicSvlanUntagVlan(&svidx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_unmatch_action_set + * Description: + * Configure Action of downstream Unmatch packet + * Input: + * action - Action for Unmatch + * svid - The SVID assigned to Unmatch packet + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of downstream Un-match packet. A SVID assigned + * to the un-match is also supported by this API. The parameter od svid is + * only refernced when the action is set to UNMATCH_ASSIGN + */ +rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (action >= UNMATCH_END) + return RT_ERR_OUT_OF_RANGE; + + if (action == UNMATCH_ASSIGN) + { + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + } + + if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch((rtk_uint32)action)) != RT_ERR_OK) + return retVal; + + if(action == UNMATCH_ASSIGN) + { + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + if ((retVal = rtl8367c_setAsicSvlanUnmatchVlan(i)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; + } + } + + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_unmatch_action_get + * Description: + * Get Action of downstream Unmatch packet + * Input: + * None + * Output: + * pAction - Action for Unmatch + * pSvid - The SVID assigned to Unmatch packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can Get action of downstream Un-match packet. A SVID assigned + * to the un-match is also retrieved by this API. The parameter pSvid is + * only refernced when the action is UNMATCH_ASSIGN + */ +rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction || NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSvlanIngressUnmatch(pAction)) != RT_ERR_OK) + return retVal; + + if(*pAction == UNMATCH_ASSIGN) + { + if ((retVal = rtl8367c_getAsicSvlanUnmatchVlan(&svidx)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + *pSvid = svlanMemConf.vs_svid; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_unassign_action_set + * Description: + * Configure Action of upstream without svid assign action + * Input: + * action - Action for Un-assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can configure action of upstream Un-assign svid packet. If action is not + * trap to CPU, the port-based SVID sure be assign as system need + */ +rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (action >= UNASSIGN_END) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicSvlanEgressUnassign((rtk_uint32)action); + + return retVal; +} + +/* Function Name: + * rtk_svlan_unassign_action_get + * Description: + * Get action of upstream without svid assignment + * Input: + * None + * Output: + * pAction - Action for Un-assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * Note: + * None + */ +rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pAction) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicSvlanEgressUnassign(pAction); + + return retVal; +} + +/* Function Name: + * rtk_svlan_dmac_vidsel_set + * Description: + * Set DMAC CVID selection + * Input: + * port - Port + * enable - state of DMAC CVID Selection + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set DMAC CVID Selection state + */ +rtk_api_ret_t rtk_svlan_dmac_vidsel_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_dmac_vidsel_get + * Description: + * Get DMAC CVID selection + * Input: + * port - Port + * Output: + * pEnable - state of DMAC CVID Selection + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can get DMAC CVID Selection state + */ +rtk_api_ret_t rtk_svlan_dmac_vidsel_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(port); + + if ((retVal = rtl8367c_getAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_svlan_ipmc2s_add + * Description: + * add ip multicast address to SVLAN + * Input: + * svid - SVLAN VID + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set IP mutlicast to SVID configuration. If upstream packet is IPv4 multicast + * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. + * There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk,rtk_vlan_t svid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx; + rtk_uint32 svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + if ((ipmc&0xF0000000)!=0xE0000000) + return RT_ERR_INPUT; + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + + empty_idx = 0xFFFF; + + for (i = RTL8367C_MC2SIDXMAX; i >= 0; i--) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && + svlanMC2SConf.sdata==ipmc&& + svlanMC2SConf.smask==ipmcMsk) + { + svlanMC2SConf.svidx = svidx; + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + } + } + else + { + empty_idx = i; + } + } + + if (empty_idx!=0xFFFF) + { + svlanMC2SConf.valid = TRUE; + svlanMC2SConf.svidx = svidx; + svlanMC2SConf.format = SVLAN_MC2S_MODE_IP; + svlanMC2SConf.sdata = ipmc; + svlanMC2SConf.smask = ipmcMsk; + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + return RT_ERR_OUT_OF_RANGE; + +} + +/* Function Name: + * rtk_svlan_ipmc2s_del + * Description: + * delete ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((ipmc&0xF0000000)!=0xE0000000) + return RT_ERR_INPUT; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && + svlanMC2SConf.sdata==ipmc&& + svlanMC2SConf.smask==ipmcMsk) + { + memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_ipmc2s_get + * Description: + * Get ip multicast address to SVLAN + * Input: + * ipmc - ip multicast address + * ipmcMsk - ip multicast mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if ((ipmc&0xF0000000)!=0xE0000000) + return RT_ERR_INPUT; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid && + svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && + svlanMC2SConf.sdata == ipmc && + svlanMC2SConf.smask == ipmcMsk) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + *pSvid = svlanMemConf.vs_svid; + return RT_ERR_OK; + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_l2mc2s_add + * Description: + * Add L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can set L2 Mutlicast to SVID configuration. If upstream packet is L2 multicast + * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 + * SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx; + rtk_uint32 svidx, l2add, l2Mask; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + if (mac.octet[0]!= 1&&mac.octet[1]!=0) + return RT_ERR_INPUT; + + l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; + l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + empty_idx = 0xFFFF; + + for (i = RTL8367C_MC2SIDXMAX; i >=0; i--) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && + svlanMC2SConf.sdata==l2add&& + svlanMC2SConf.smask==l2Mask) + { + svlanMC2SConf.svidx = svidx; + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + } + } + else + { + empty_idx = i; + } + } + + if (empty_idx!=0xFFFF) + { + svlanMC2SConf.valid = TRUE; + svlanMC2SConf.svidx = svidx; + svlanMC2SConf.format = SVLAN_MC2S_MODE_MAC; + svlanMC2SConf.sdata = l2add; + svlanMC2SConf.smask = l2Mask; + + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_l2mc2s_del + * Description: + * delete L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete Mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 l2add, l2Mask; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (mac.octet[0]!= 1&&mac.octet[1]!=0) + return RT_ERR_INPUT; + + l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; + l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && + svlanMC2SConf.sdata==l2add&& + svlanMC2SConf.smask==l2Mask) + { + memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); + if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_l2mc2s_get + * Description: + * Get L2 multicast address to SVLAN + * Input: + * mac - L2 multicast address + * macMsk - L2 multicast address mask + * Output: + * pSvid - SVLAN VID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can get L2 mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. + */ +rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 l2add,l2Mask; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_mc2s_t svlanMC2SConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pSvid) + return RT_ERR_NULL_POINTER; + + if (mac.octet[0]!= 1&&mac.octet[1]!=0) + return RT_ERR_INPUT; + + l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; + l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; + + for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) + return retVal; + + if (TRUE == svlanMC2SConf.valid) + { + if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && + svlanMC2SConf.sdata==l2add&& + svlanMC2SConf.smask==l2Mask) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) + return retVal; + *pSvid = svlanMemConf.vs_svid; + + return RT_ERR_OK; + } + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_sp2c_add + * Description: + * Add system SP2C configuration + * Input: + * cvid - VLAN ID + * dst_port - Destination port of SVLAN to CVLAN configuration + * svid - SVLAN VID + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned + * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. + * There are 128 SP2C configurations. + */ +rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 empty_idx, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + rtk_port_t port; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + if (cvid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(dst_port); + port = rtk_switch_port_L2P_get(dst_port); + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + empty_idx = 0xFFFF; + + for (i=RTL8367C_SP2CMAX; i >=0 ; i--) + { + if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + + if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == port) && (svlanSP2CConf.valid == 1)) + { + empty_idx = i; + break; + } + else if (svlanSP2CConf.valid == 0) + { + empty_idx = i; + } + } + + if (empty_idx!=0xFFFF) + { + svlanSP2CConf.valid = 1; + svlanSP2CConf.vid = cvid; + svlanSP2CConf.svidx = svidx; + svlanSP2CConf.dstport = port; + + if ((retVal = rtl8367c_setAsicSvlanSP2CConf(empty_idx, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + return RT_ERR_OUT_OF_RANGE; + +} + +/* Function Name: + * rtk_svlan_sp2c_get + * Description: + * Get configure system SP2C content + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * pCvid - VLAN ID + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * Note: + * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pCvid) + return RT_ERR_NULL_POINTER; + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(dst_port); + dst_port = rtk_switch_port_L2P_get(dst_port); + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + for (i = 0; i <= RTL8367C_SP2CMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + + if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) + { + *pCvid = svlanSP2CConf.vid; + return RT_ERR_OK; + } + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_sp2c_del + * Description: + * Delete system SP2C configuration + * Input: + * svid - SVLAN VID + * dst_port - Destination port of SVLAN to CVLAN configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. + */ +rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, svidx; + rtl8367c_svlan_memconf_t svlanMemConf; + rtl8367c_svlan_s2c_t svlanSP2CConf; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (svid > RTL8367C_VIDMAX) + return RT_ERR_SVLAN_VID; + + /* Check port Valid */ + RTK_CHK_PORT_VALID(dst_port); + dst_port = rtk_switch_port_L2P_get(dst_port); + + svidx = 0xFFFF; + + for (i = 0; i < RTL8367C_SVIDXNO; i++) + { + if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) + return retVal; + + if (svid == svlanMemConf.vs_svid) + { + svidx = i; + break; + } + } + + if (0xFFFF == svidx) + return RT_ERR_SVLAN_ENTRY_NOT_FOUND; + + for (i = 0; i <= RTL8367C_SP2CMAX; i++) + { + if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + + if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) + { + svlanSP2CConf.valid = 0; + svlanSP2CConf.vid = 0; + svlanSP2CConf.svidx = 0; + svlanSP2CConf.dstport = 0; + + if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) + return retVal; + return RT_ERR_OK; + } + + } + + return RT_ERR_OUT_OF_RANGE; +} + +/* Function Name: + * rtk_svlan_lookupType_set + * Description: + * Set lookup type of SVLAN + * Input: + * type - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= SVLAN_LOOKUP_END) + return RT_ERR_CHIP_NOT_SUPPORTED; + + + svlan_lookupType = type; + + retVal = rtl8367c_setAsicSvlanLookupType((rtk_uint32)type); + + return retVal; +} + +/* Function Name: + * rtk_svlan_lookupType_get + * Description: + * Get lookup type of SVLAN + * Input: + * pType - lookup type + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * Note: + * none + */ +rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pType) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicSvlanLookupType(pType); + + svlan_lookupType = *pType; + + return retVal; +} + +/* Function Name: + * rtk_svlan_trapPri_set + * Description: + * Set svlan trap priority + * Input: + * priority - priority for trap packets + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_QOS_INT_PRIORITY + * Note: + * None + */ +rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority) +{ + rtk_api_ret_t retVal; + + RTK_CHK_INIT_STATE(); + + if(priority > RTL8367C_PRIMAX) + return RT_ERR_OUT_OF_RANGE; + + retVal = rtl8367c_setAsicSvlanTrapPriority(priority); + + return retVal; +} /* end of rtk_svlan_trapPri_set */ + +/* Function Name: + * rtk_svlan_trapPri_get + * Description: + * Get svlan trap priority + * Input: + * None + * Output: + * pPriority - priority for trap packets + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None + */ +rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority) +{ + rtk_api_ret_t retVal; + + RTK_CHK_INIT_STATE(); + + if(NULL == pPriority) + return RT_ERR_NULL_POINTER; + + retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority); + + return retVal; +} /* end of rtk_svlan_trapPri_get */ + + +/* Function Name: + * rtk_svlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + rtk_uint32 svidx; + rtk_uint32 empty_idx = 0xFFFF; + rtl8367c_svlan_memconf_t svlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + /* Search exist entry */ + for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) + { + if(svlan_mbrCfgUsage[svidx] == TRUE) + { + if(svlan_mbrCfgVid[svidx] == vid) + { + /* Found! return index */ + *pIndex = svidx; + return RT_ERR_OK; + } + } + else if(empty_idx == 0xFFFF) + { + empty_idx = svidx; + } + + } + + if(empty_idx == 0xFFFF) + { + /* No empty index */ + return RT_ERR_TBL_FULL; + } + + svlan_mbrCfgUsage[empty_idx] = TRUE; + svlan_mbrCfgVid[empty_idx] = vid; + + memset(&svlan_cfg, 0, sizeof(rtl8367c_svlan_memconf_t)); + + svlan_cfg.vs_svid = vid; + /*for create check*/ + if(vid == 0) + { + svlan_cfg.vs_efid = 1; + } + + if((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlan_cfg)) != RT_ERR_OK) + return retVal; + + *pIndex = empty_idx; + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trap.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trap.c new file mode 100755 index 00000000..af966105 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trap.c @@ -0,0 +1,1229 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Trap module. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_set + * Description: + * Set unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * ucast_action - Unknown unicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (ucast_action >= UCAST_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), ucast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownUnicastPktAction_get + * Description: + * Get unknown unicast packet action configuration. + * Input: + * port - ingress port ID for unknown unicast packet + * Output: + * pUcast_action - Unknown unicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * This API can get unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + * - UCAST_ACTION_FLOODING + */ +rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if (NULL == pUcast_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), pUcast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMacPktAction_set + * Description: + * Set unknown source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (ucast_action >= UCAST_ACTION_FLOODING) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnknownSaBehavior(ucast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMacPktAction_get + * Description: + * Get unknown source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null Pointer. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pUcast_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnknownSaBehavior(pUcast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacPktAction_set + * Description: + * Set unmatch source MAC packet action configuration. + * Input: + * ucast_action - Unknown source MAC action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (ucast_action >= UCAST_ACTION_FLOODING) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnmatchedSaBehavior(ucast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacPktAction_get + * Description: + * Get unmatch source MAC packet action configuration. + * Input: + * None. + * Output: + * pUcast_action - Unknown source MAC action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * This API can set unknown unicast packet action configuration. + * The unknown unicast action is as following: + * - UCAST_ACTION_FORWARD_PMASK + * - UCAST_ACTION_DROP + * - UCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pUcast_action) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnmatchedSaBehavior(pUcast_action)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacMoving_set + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +rtk_api_ret_t rtk_trap_unmatchMacMoving_set(rtk_port_t port, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unmatchMacMoving_get + * Description: + * Set unmatch source MAC packet moving state. + * Input: + * port - Port ID. + * Output: + * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + */ +rtk_api_ret_t rtk_trap_unmatchMacMoving_get(rtk_port_t port, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* check port valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMcastPktAction_set + * Description: + * Set behavior of unknown multicast + * Input: + * port - Port id. + * type - unknown multicast packet type. + * mcast_action - unknown multicast action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action) +{ + rtk_api_ret_t retVal; + rtk_uint32 rawAction; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (type >= MCAST_END) + return RT_ERR_INPUT; + + if (mcast_action >= MCAST_ACTION_END) + return RT_ERR_INPUT; + + + switch (type) + { + case MCAST_L2: + if (MCAST_ACTION_ROUTER_PORT == mcast_action) + return RT_ERR_INPUT; + else if(MCAST_ACTION_DROP_EX_RMA == mcast_action) + rawAction = L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA; + else + rawAction = (rtk_uint32)mcast_action; + + if ((retVal = rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) + return retVal; + + break; + case MCAST_IPV4: + if (MCAST_ACTION_DROP_EX_RMA == mcast_action) + return RT_ERR_INPUT; + else + rawAction = (rtk_uint32)mcast_action; + + if ((retVal = rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) + return retVal; + + break; + case MCAST_IPV6: + if (MCAST_ACTION_DROP_EX_RMA == mcast_action) + return RT_ERR_INPUT; + else + rawAction = (rtk_uint32)mcast_action; + + if ((retVal = rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) + return retVal; + + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_unknownMcastPktAction_get + * Description: + * Get behavior of unknown multicast + * Input: + * type - unknown multicast packet type. + * Output: + * pMcast_action - unknown multicast action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_NOT_ALLOWED - Invalid operation. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * When receives an unknown multicast packet, switch may trap, drop or flood this packet + * (1) The unknown multicast packet type is as following: + * - MCAST_L2 + * - MCAST_IPV4 + * - MCAST_IPV6 + * (2) The unknown multicast action is as following: + * - MCAST_ACTION_FORWARD + * - MCAST_ACTION_DROP + * - MCAST_ACTION_TRAP2CPU + */ +rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action) +{ + rtk_api_ret_t retVal; + rtk_uint32 rawAction; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (type >= MCAST_END) + return RT_ERR_INPUT; + + if(NULL == pMcast_action) + return RT_ERR_NULL_POINTER; + + switch (type) + { + case MCAST_L2: + if ((retVal = rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) + return retVal; + + if(L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA == rawAction) + *pMcast_action = MCAST_ACTION_DROP_EX_RMA; + else + *pMcast_action = (rtk_trap_mcast_action_t)rawAction; + + break; + case MCAST_IPV4: + if ((retVal = rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) + return retVal; + + *pMcast_action = (rtk_trap_mcast_action_t)rawAction; + break; + case MCAST_IPV6: + if ((retVal = rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) + return retVal; + + *pMcast_action = (rtk_trap_mcast_action_t)rawAction; + break; + default: + break; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_lldpEnable_set + * Description: + * Set LLDP enable. + * Input: + * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NOT_ALLOWED - Invalid action. + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + + */ +rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_enable_t tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (enabled >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicRmaLldp(enabled, &rmacfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_lldpEnable_get + * Description: + * Get LLDP status. + * Input: + * None + * Output: + * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * LLDP is as following definition. + * - DMAC Assignment + * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP + * - 01:80:c2:00:00:03 ethertype = 0x88CC + * - 01:80:c2:00:00:00 ethertype = 0x88CC + */ +rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicRmaLldp(pEnabled, &rmacfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_set + * Description: + * Set priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * priority - internal priority that is going to be set for specific trap reason. + * Output: + * None. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_REASON_END) + return RT_ERR_INPUT; + + if (priority > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + switch (type) + { + case TRAP_REASON_RMA: + if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) + return retVal; + rmacfg.trap_priority= priority; + if ((retVal = rtl8367c_setAsicRma(0, &rmacfg)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_OAM: + if ((retVal = rtl8367c_setAsicOamCpuPri(priority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_1XUNAUTH: + if ((retVal = rtl8367c_setAsic1xTrapPriority(priority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_VLANSTACK: + if ((retVal = rtl8367c_setAsicSvlanTrapPriority(priority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_UNKNOWNMC: + if ((retVal = rtl8367c_setAsicUnknownMulticastTrapPriority(priority)) != RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_CHIP_NOT_SUPPORTED; + } + + + return RT_ERR_OK; +} + + +/* Function Name: + * rtk_trap_reasonTrapToCpuPriority_get + * Description: + * Get priority value of a packet that trapped to CPU port according to specific reason. + * Input: + * type - reason that trap to CPU port. + * Output: + * pPriority - configured internal priority for such reason. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NOT_INIT - The module is not initial + * RT_ERR_INPUT - Invalid input parameter + * RT_ERR_NULL_POINTER - NULL pointer + * Note: + * Currently the trap reason that supported are listed as follows: + * - TRAP_REASON_RMA + * - TRAP_REASON_OAM + * - TRAP_REASON_1XUNAUTH + * - TRAP_REASON_VLANSTACK + * - TRAP_REASON_UNKNOWNMC + */ +rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_REASON_END) + return RT_ERR_INPUT; + + if(NULL == pPriority) + return RT_ERR_NULL_POINTER; + + switch (type) + { + case TRAP_REASON_RMA: + if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) + return retVal; + *pPriority = rmacfg.trap_priority; + + break; + case TRAP_REASON_OAM: + if ((retVal = rtl8367c_getAsicOamCpuPri(pPriority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_1XUNAUTH: + if ((retVal = rtl8367c_getAsic1xTrapPriority(pPriority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_VLANSTACK: + if ((retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority)) != RT_ERR_OK) + return retVal; + + break; + case TRAP_REASON_UNKNOWNMC: + if ((retVal = rtl8367c_getAsicUnknownMulticastTrapPriority(pPriority)) != RT_ERR_OK) + return retVal; + + break; + default: + return RT_ERR_CHIP_NOT_SUPPORTED; + + } + + return RT_ERR_OK; +} + + + +/* Function Name: + * rtk_trap_rmaAction_set + * Description: + * Set Reserved multicast address action configuration. + * Input: + * type - rma type. + * rma_action - RMA action. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if (rma_action >= RMA_ACTION_END) + return RT_ERR_RMA_ACTION; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.operation = rma_action; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_rmaAction_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pRma_action - RMA action. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * (1)They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + * (2) The RMA action is as following: + * - RMA_ACTION_FORWARD + * - RMA_ACTION_TRAP2CPU + * - RMA_ACTION_DROP + * - RMA_ACTION_FORWARD_EXCLUDE_CPU + */ +rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if(NULL == pRma_action) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + *pRma_action = rmacfg.operation; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_rmaKeepFormat_set + * Description: + * Set Reserved multicast address keep format configuration. + * Input: + * type - rma type. + * enable - enable keep format. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_ENABLE - Invalid IFG parameter + * Note: + * + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if (enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + + rmacfg.keep_format = enable; + + if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) + return retVal; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trap_rmaKeepFormat_get + * Description: + * Get Reserved multicast address action configuration. + * Input: + * type - rma type. + * Output: + * pEnable - keep format status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * Note: + * There are 48 types of Reserved Multicast Address frame for application usage. + * They are as following definition. + * - TRAP_BRG_GROUP, + * - TRAP_FD_PAUSE, + * - TRAP_SP_MCAST, + * - TRAP_1X_PAE, + * - TRAP_UNDEF_BRG_04, + * - TRAP_UNDEF_BRG_05, + * - TRAP_UNDEF_BRG_06, + * - TRAP_UNDEF_BRG_07, + * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, + * - TRAP_UNDEF_BRG_09, + * - TRAP_UNDEF_BRG_0A, + * - TRAP_UNDEF_BRG_0B, + * - TRAP_UNDEF_BRG_0C, + * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, + * - TRAP_8021AB, + * - TRAP_UNDEF_BRG_0F, + * - TRAP_BRG_MNGEMENT, + * - TRAP_UNDEFINED_11, + * - TRAP_UNDEFINED_12, + * - TRAP_UNDEFINED_13, + * - TRAP_UNDEFINED_14, + * - TRAP_UNDEFINED_15, + * - TRAP_UNDEFINED_16, + * - TRAP_UNDEFINED_17, + * - TRAP_UNDEFINED_18, + * - TRAP_UNDEFINED_19, + * - TRAP_UNDEFINED_1A, + * - TRAP_UNDEFINED_1B, + * - TRAP_UNDEFINED_1C, + * - TRAP_UNDEFINED_1D, + * - TRAP_UNDEFINED_1E, + * - TRAP_UNDEFINED_1F, + * - TRAP_GMRP, + * - TRAP_GVRP, + * - TRAP_UNDEF_GARP_22, + * - TRAP_UNDEF_GARP_23, + * - TRAP_UNDEF_GARP_24, + * - TRAP_UNDEF_GARP_25, + * - TRAP_UNDEF_GARP_26, + * - TRAP_UNDEF_GARP_27, + * - TRAP_UNDEF_GARP_28, + * - TRAP_UNDEF_GARP_29, + * - TRAP_UNDEF_GARP_2A, + * - TRAP_UNDEF_GARP_2B, + * - TRAP_UNDEF_GARP_2C, + * - TRAP_UNDEF_GARP_2D, + * - TRAP_UNDEF_GARP_2E, + * - TRAP_UNDEF_GARP_2F, + * - TRAP_CDP. + * - TRAP_CSSTP. + * - TRAP_LLDP. + */ +rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtl8367c_rma_t rmacfg; + rtk_uint32 tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (type >= TRAP_END) + return RT_ERR_INPUT; + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) + { + if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else if (type == TRAP_CDP) + { + if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else if (type == TRAP_CSSTP) + { + if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else if (type == TRAP_LLDP) + { + if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) + return retVal; + + *pEnable = rmacfg.keep_format; + } + else + return RT_ERR_INPUT; + + return RT_ERR_OK; +} + + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trunk.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trunk.c new file mode 100755 index 00000000..8a88dc5f --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/trunk.c @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in Trunk module. + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Function Name: + * rtk_trunk_port_set + * Description: + * Set trunking group available port mask + * Input: + * trk_gid - trunk group id + * pTrunk_member_portmask - Logic trunking member port mask + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking group port mask. Each port trunking group has max 4 ports. + * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. + */ +rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + rtk_uint32 regValue, type, tmp; + + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) + return retVal; + + if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) + return retVal; + + switch (regValue) + { + case 0x0276: + case 0x0597: + case 0x6367: + type = 0; + break; + case 0x0652: + case 0x6368: + type = 1; + break; + case 0x0801: + case 0x6511: + type = 2; + break; + default: + return RT_ERR_FAILED; + } + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pTrunk_member_portmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pTrunk_member_portmask); + + if((retVal = rtk_switch_portmask_L2P_get(pTrunk_member_portmask, &pmsk)) != RT_ERR_OK) + return retVal; + + if((type == 0) || (type == 1)) + { + if ((pmsk | RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) != (rtk_uint32)RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) + return RT_ERR_PORT_MASK; + + pmsk = (pmsk & RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) >> RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); + } + else if(type == 2) + { + tmp = 0; + + if(pmsk & 0x2) + tmp |= 1; + if(pmsk & 0x8) + tmp |=2; + if(pmsk & 0x80) + tmp |=8; + + pmsk = tmp; + } + + if ((retVal = rtl8367c_setAsicTrunkingGroup(trk_gid, pmsk)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_port_get + * Description: + * Get trunking group available port mask + * Input: + * trk_gid - trunk group id + * Output: + * pTrunk_member_portmask - Logic trunking member port mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get 2 port trunking group. + */ +rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmsk; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if ((retVal = rtl8367c_getAsicTrunkingGroup(trk_gid, &pmsk)) != RT_ERR_OK) + return retVal; + + pmsk = pmsk << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); + + if((retVal = rtk_switch_portmask_P2L_get(pmsk, pTrunk_member_portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_distributionAlgorithm_set + * Description: + * Set port trunking hash select sources + * Input: + * trk_gid - trunk group id + * algo_bitmask - Bitmask of the distribution algorithm + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * RT_ERR_LA_HASHMASK - Hash algorithm selection error. + * RT_ERR_PORT_MASK - Invalid portmask. + * Note: + * The API can set port trunking hash algorithm sources. + * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} + * - 0b0000001: SPA + * - 0b0000010: SMAC + * - 0b0000100: DMAC + * - 0b0001000: SIP + * - 0b0010000: DIP + * - 0b0100000: TCP/UDP Source Port + * - 0b1000000: TCP/UDP Destination Port + * Example: + * - 0b0000011: SMAC & SPA + * - Note that it could be an arbitrary combination or independent set + */ +rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if (algo_bitmask >= 128) + return RT_ERR_LA_HASHMASK; + + if ((retVal = rtl8367c_setAsicTrunkingHashSelect(algo_bitmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_distributionAlgorithm_get + * Description: + * Get port trunking hash select sources + * Input: + * trk_gid - trunk group id + * Output: + * pAlgo_bitmask - Bitmask of the distribution algorithm + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_LA_TRUNK_ID - Invalid trunking group + * Note: + * The API can get port trunking hash algorithm sources. + */ +rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if(NULL == pAlgo_bitmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingHashSelect((rtk_uint32 *)pAlgo_bitmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficSeparate_set + * Description: + * Set the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * separateType - traffic separation setting + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_LA_HASHMASK - invalid hash mask + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType) +{ + rtk_api_ret_t retVal; + rtk_uint32 enabled; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if(separateType >= SEPARATE_END) + return RT_ERR_INPUT; + + enabled = (separateType == SEPARATE_FLOOD) ? ENABLED : DISABLED; + if ((retVal = rtl8367c_setAsicTrunkingFlood(enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficSeparate_get + * Description: + * Get the traffic separation setting of a trunk group from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pSeparateType - pointer separated traffic type + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * SEPARATE_NONE: disable traffic separation + * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic + */ +rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType) +{ + rtk_api_ret_t retVal; + rtk_uint32 enabled; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if (trk_gid != RTK_WHOLE_SYSTEM) + return RT_ERR_LA_TRUNK_ID; + + if(NULL == pSeparateType) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingFlood(&enabled)) != RT_ERR_OK) + return retVal; + + *pSeparateType = (enabled == ENABLED) ? SEPARATE_FLOOD : SEPARATE_NONE; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_mode_set + * Description: + * Set the trunk mode to the specified device. + * Input: + * mode - trunk mode + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_INPUT - invalid input parameter + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(mode >= TRUNK_MODE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicTrunkingMode((rtk_uint32)mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_mode_get + * Description: + * Get the trunk mode from the specified device. + * Input: + * None + * Output: + * pMode - pointer buffer of trunk mode + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * The enum of the trunk mode as following + * - TRUNK_MODE_NORMAL + * - TRUNK_MODE_DUMB + */ +rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pMode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingMode((rtk_uint32 *)pMode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficPause_set + * Description: + * Set the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * enable - traffic pause state + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * Note: + * None. + */ +rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32)enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_trafficPause_get + * Description: + * Get the traffic pause setting of a trunk group. + * Input: + * trk_gid - trunk group id + * Output: + * pEnable - pointer of traffic pause state. + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32 *)pEnable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_hashMappingTable_set + * Description: + * Set hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * pHash2Port_array - ports associate with the hash value + * Output: + * None + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist + * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk + * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) +{ + rtk_api_ret_t retVal; + rtk_uint32 hashValue; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pHash2Port_array) + return RT_ERR_NULL_POINTER; + + if(trk_gid <= TRUNK_GROUP1) + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_setAsicTrunkingHashTable(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) + return retVal; + } + } + else + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_setAsicTrunkingHashTable1(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) + return retVal; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_hashMappingTable_get + * Description: + * Get hash value to port array in the trunk group id from the specified device. + * Input: + * trk_gid - trunk group id + * Output: + * pHash2Port_array - pointer buffer of ports associate with the hash value + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_UNIT_ID - invalid unit id + * RT_ERR_LA_TRUNK_ID - invalid trunk ID + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * Trunk group 0 & 1 shares the same hash mapping table. + * Trunk group 2 uses a independent table. + */ +rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) +{ + rtk_api_ret_t retVal; + rtk_uint32 hashValue; + rtk_uint32 hashPort; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Trunk Group Valid */ + RTK_CHK_TRUNK_GROUP_VALID(trk_gid); + + if(NULL == pHash2Port_array) + return RT_ERR_NULL_POINTER; + + if(trk_gid <= TRUNK_GROUP1) + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_getAsicTrunkingHashTable(hashValue, &hashPort)) != RT_ERR_OK) + return retVal; + + pHash2Port_array->value[hashValue] = hashPort; + } + } + else + { + for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) + { + if ((retVal = rtl8367c_getAsicTrunkingHashTable1(hashValue, &hashPort)) != RT_ERR_OK) + return retVal; + + pHash2Port_array->value[hashValue] = hashPort; + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_trunk_portQueueEmpty_get + * Description: + * Get the port mask which all queues are empty. + * Input: + * None. + * Output: + * pEmpty_portmask - pointer empty port mask + * Return: + * RT_ERR_OK + * RT_ERR_FAILED + * RT_ERR_NULL_POINTER - input parameter may be null pointer + * Note: + * None. + */ +rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEmpty_portmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicQeueuEmptyStatus(&pmask)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtk_switch_portmask_P2L_get(pmask, pEmpty_portmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/vlan.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/vlan.c new file mode 100755 index 00000000..f7480c49 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367c/vlan.c @@ -0,0 +1,2124 @@ +/* + * Copyright (C) 2013 Realtek Semiconductor Corp. + * All Rights Reserved. + * + * Unless you and Realtek execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2, + * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + * + * $Revision: 76306 $ + * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ + * + * Purpose : RTK switch high-level API for RTL8367/RTL8367C + * Feature : Here is a list of all functions and variables in VLAN module. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef enum vlan_mbrCfgType_e +{ + MBRCFG_UNUSED = 0, + MBRCFG_USED_BY_VLAN, + MBRCFG_END +}vlan_mbrCfgType_t; + +static rtk_vlan_t vlan_mbrCfgVid[RTL8367C_CVIDXNO]; +static vlan_mbrCfgType_t vlan_mbrCfgUsage[RTL8367C_CVIDXNO]; + +/* Function Name: + * rtk_vlan_init + * Description: + * Initialize VLAN. + * Input: + * None + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * Note: + * VLAN is disabled by default. User has to call this API to enable VLAN before + * using it. And It will set a default VLAN(vid 1) including all ports and set + * all ports PVID to the default VLAN. + */ +rtk_api_ret_t rtk_vlan_init(void) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Clean Database */ + memset(vlan_mbrCfgVid, 0x00, sizeof(rtk_vlan_t) * RTL8367C_CVIDXNO); + memset(vlan_mbrCfgUsage, 0x00, sizeof(vlan_mbrCfgType_t) * RTL8367C_CVIDXNO); + + /* clean 32 VLAN member configuration */ + for (i = 0; i <= RTL8367C_CVIDXMAX; i++) + { + vlanMC.evid = 0; + vlanMC.mbr = 0; + vlanMC.fid_msti = 0; + vlanMC.envlanpol = 0; + vlanMC.meteridx = 0; + vlanMC.vbpen = 0; + vlanMC.vbpri = 0; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(i, &vlanMC)) != RT_ERR_OK) + return retVal; + } + + /* Set a default VLAN with vid 1 to 4K table for all ports */ + memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); + vlan4K.vid = 1; + vlan4K.mbr = RTK_PHY_PORTMASK_ALL; + vlan4K.untag = RTK_PHY_PORTMASK_ALL; + vlan4K.fid_msti = 0; + if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + /* Also set the default VLAN to 32 member configuration index 0 */ + memset(&vlanMC, 0, sizeof(rtl8367c_vlanconfiguser)); + vlanMC.evid = 1; + vlanMC.mbr = RTK_PHY_PORTMASK_ALL; + vlanMC.fid_msti = 0; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(0, &vlanMC)) != RT_ERR_OK) + return retVal; + + /* Set all ports PVID to default VLAN and tag-mode to original */ + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((retVal = rtl8367c_setAsicVlanPortBasedVID(i, 0, 0)) != RT_ERR_OK) + return retVal; + if ((retVal = rtl8367c_setAsicVlanEgressTagMode(i, EG_TAG_MODE_ORI)) != RT_ERR_OK) + return retVal; + } + + /* Updata Databse */ + vlan_mbrCfgUsage[0] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[0] = 1; + + /* Enable Ingress filter */ + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((retVal = rtl8367c_setAsicVlanIngressFilter(i, ENABLED)) != RT_ERR_OK) + return retVal; + } + + /* enable VLAN */ + if ((retVal = rtl8367c_setAsicVlanFilter(ENABLED)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_set + * Description: + * Set a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * pVlanCfg - VLAN Configuration + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_L2_FID - Invalid FID. + * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtk_uint32 phyUntagPmask; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 idx; + rtk_uint32 empty_index = 0xffff; + rtk_uint32 update_evid = 0; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~8191 */ + if (vid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pVlanCfg) + return RT_ERR_NULL_POINTER; + + /* Check port mask valid */ + RTK_CHK_PORTMASK_VALID(&(pVlanCfg->mbr)); + + if (vid <= RTL8367C_VIDMAX) + { + /* Check untag port mask valid */ + RTK_CHK_PORTMASK_VALID(&(pVlanCfg->untag)); + } + + /* IVL_EN */ + if(pVlanCfg->ivl_en >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* fid must be 0~15 */ + if(pVlanCfg->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + /* Policing */ + if(pVlanCfg->envlanpol >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* Meter ID */ + if(pVlanCfg->meteridx > RTK_MAX_METER_ID) + return RT_ERR_INPUT; + + /* VLAN based priority */ + if(pVlanCfg->vbpen >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* Priority */ + if(pVlanCfg->vbpri > RTL8367C_PRIMAX) + return RT_ERR_INPUT; + + /* Get physical port mask */ + if(rtk_switch_portmask_L2P_get(&(pVlanCfg->mbr), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_L2P_get(&(pVlanCfg->untag), &phyUntagPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if (vid <= RTL8367C_VIDMAX) + { + /* update 4K table */ + memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); + vlan4K.vid = vid; + + vlan4K.mbr = (phyMbrPmask & 0xFFFF); + vlan4K.untag = (phyUntagPmask & 0xFFFF); + + vlan4K.ivl_svl = pVlanCfg->ivl_en; + vlan4K.fid_msti = pVlanCfg->fid_msti; + vlan4K.envlanpol = pVlanCfg->envlanpol; + vlan4K.meteridx = pVlanCfg->meteridx; + vlan4K.vbpen = pVlanCfg->vbpen; + vlan4K.vbpri = pVlanCfg->vbpri; + + if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + /* Update Member configuration if exist */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! Update */ + if(phyMbrPmask == 0x00) + { + /* Member port = 0x00, delete this VLAN from Member Configuration */ + memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + /* Clear Database */ + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + /* Normal VLAN config, update to member configuration */ + vlanMC.evid = vid; + vlanMC.mbr = vlan4K.mbr; + vlanMC.fid_msti = vlan4K.fid_msti; + vlanMC.meteridx = vlan4K.meteridx; + vlanMC.envlanpol= vlan4K.envlanpol; + vlanMC.vbpen = vlan4K.vbpen; + vlanMC.vbpri = vlan4K.vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + } + + break; + } + } + } + } + else + { + /* vid > 4095 */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! Update */ + if(phyMbrPmask == 0x00) + { + /* Member port = 0x00, delete this VLAN from Member Configuration */ + memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + /* Clear Database */ + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + /* Normal VLAN config, update to member configuration */ + vlanMC.evid = vid; + vlanMC.mbr = phyMbrPmask; + vlanMC.fid_msti = pVlanCfg->fid_msti; + vlanMC.meteridx = pVlanCfg->meteridx; + vlanMC.envlanpol= pVlanCfg->envlanpol; + vlanMC.vbpen = pVlanCfg->vbpen; + vlanMC.vbpri = pVlanCfg->vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + break; + } + + update_evid = 1; + } + } + + if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) + { + if(0xffff == empty_index) + empty_index = idx; + } + } + + /* doesn't find out same EVID entry and there is empty index in member configuration */ + if( (phyMbrPmask != 0x00) && (update_evid == 0) && (empty_index != 0xFFFF) ) + { + vlanMC.evid = vid; + vlanMC.mbr = phyMbrPmask; + vlanMC.fid_msti = pVlanCfg->fid_msti; + vlanMC.meteridx = pVlanCfg->meteridx; + vlanMC.envlanpol= pVlanCfg->envlanpol; + vlanMC.vbpen = pVlanCfg->vbpen; + vlanMC.vbpri = pVlanCfg->vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_index, &vlanMC)) != RT_ERR_OK) + return retVal; + + vlan_mbrCfgUsage[empty_index] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[empty_index] = vid; + + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_get + * Description: + * Get a VLAN entry. + * Input: + * vid - VLAN ID to configure. + * Output: + * pVlanCfg - VLAN Configuration + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtk_uint32 phyUntagPmask; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 idx; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~8191 */ + if (vid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pVlanCfg) + return RT_ERR_NULL_POINTER; + + if (vid <= RTL8367C_VIDMAX) + { + vlan4K.vid = vid; + + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + phyMbrPmask = vlan4K.mbr; + phyUntagPmask = vlan4K.untag; + if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) + return RT_ERR_FAILED; + + if(rtk_switch_portmask_P2L_get(phyUntagPmask, &(pVlanCfg->untag)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pVlanCfg->ivl_en = vlan4K.ivl_svl; + pVlanCfg->fid_msti = vlan4K.fid_msti; + pVlanCfg->envlanpol = vlan4K.envlanpol; + pVlanCfg->meteridx = vlan4K.meteridx; + pVlanCfg->vbpen = vlan4K.vbpen; + pVlanCfg->vbpri = vlan4K.vbpri; + } + else + { + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + phyMbrPmask = vlanMC.mbr; + if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) + return RT_ERR_FAILED; + + pVlanCfg->untag.bits[0] = 0; + pVlanCfg->ivl_en = 0; + pVlanCfg->fid_msti = vlanMC.fid_msti; + pVlanCfg->envlanpol = vlanMC.envlanpol; + pVlanCfg->meteridx = vlanMC.meteridx; + pVlanCfg->vbpen = vlanMC.vbpen; + pVlanCfg->vbpri = vlanMC.vbpri; + } + } + } + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_egrFilterEnable_set + * Description: + * Set VLAN egress filter. + * Input: + * egrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(egrFilter >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* enable VLAN */ + if ((retVal = rtl8367c_setAsicVlanFilter((rtk_uint32)egrFilter)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_egrFilterEnable_get + * Description: + * Get VLAN egress filter. + * Input: + * pEgrFilter - Egress filtering + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter) +{ + rtk_api_ret_t retVal; + rtk_uint32 state; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEgrFilter) + return RT_ERR_NULL_POINTER; + + /* enable VLAN */ + if ((retVal = rtl8367c_getAsicVlanFilter(&state)) != RT_ERR_OK) + return retVal; + + *pEgrFilter = (rtk_enable_t)state; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_mbrCfg_set + * Description: + * Set a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * pMbrcfg - VLAN member Configuration. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Set a VLAN Member Configuration entry by index. + */ +rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtl8367c_vlanconfiguser mbrCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error check */ + if(pMbrcfg == NULL) + return RT_ERR_NULL_POINTER; + + if(idx > RTL8367C_CVIDXMAX) + return RT_ERR_INPUT; + + if(pMbrcfg->evid > RTL8367C_EVIDMAX) + return RT_ERR_INPUT; + + if(pMbrcfg->fid_msti > RTL8367C_FIDMAX) + return RT_ERR_L2_FID; + + if(pMbrcfg->envlanpol >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pMbrcfg->meteridx > RTK_MAX_METER_ID) + return RT_ERR_FILTER_METER_ID; + + if(pMbrcfg->vbpen >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if(pMbrcfg->vbpri > RTL8367C_PRIMAX) + return RT_ERR_QOS_INT_PRIORITY; + + /* Check port mask valid */ + RTK_CHK_PORTMASK_VALID(&(pMbrcfg->mbr)); + + mbrCfg.evid = pMbrcfg->evid; + mbrCfg.fid_msti = pMbrcfg->fid_msti; + mbrCfg.envlanpol = pMbrcfg->envlanpol; + mbrCfg.meteridx = pMbrcfg->meteridx; + mbrCfg.vbpen = pMbrcfg->vbpen; + mbrCfg.vbpri = pMbrcfg->vbpri; + + if(rtk_switch_portmask_L2P_get(&(pMbrcfg->mbr), &phyMbrPmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + mbrCfg.mbr = phyMbrPmask; + + if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) + return retVal; + + /* Update Database */ + if( (mbrCfg.evid == 0) && (mbrCfg.mbr == 0) ) + { + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[idx] = mbrCfg.evid; + } + + return RT_ERR_OK; + +} + +/* Function Name: + * rtk_vlan_mbrCfg_get + * Description: + * Get a VLAN Member Configuration entry by index. + * Input: + * idx - Index of VLAN Member Configuration. + * Output: + * pMbrcfg - VLAN member Configuration. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * Get a VLAN Member Configuration entry by index. + */ +rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) +{ + rtk_api_ret_t retVal; + rtk_uint32 phyMbrPmask; + rtl8367c_vlanconfiguser mbrCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Error check */ + if(pMbrcfg == NULL) + return RT_ERR_NULL_POINTER; + + if(idx > RTL8367C_CVIDXMAX) + return RT_ERR_INPUT; + + memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) + return retVal; + + pMbrcfg->evid = mbrCfg.evid; + pMbrcfg->fid_msti = mbrCfg.fid_msti; + pMbrcfg->envlanpol = mbrCfg.envlanpol; + pMbrcfg->meteridx = mbrCfg.meteridx; + pMbrcfg->vbpen = mbrCfg.vbpen; + pMbrcfg->vbpri = mbrCfg.vbpri; + + phyMbrPmask = mbrCfg.mbr; + if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pMbrcfg->mbr)) != RT_ERR_OK) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portPvid_set + * Description: + * Set port to specified VLAN ID(PVID). + * Input: + * port - Port id. + * pvid - Specified VLAN ID. + * priority - 802.1p priority for the PVID. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API is used for Port-based VLAN. The untagged frame received from the + * port will be classified to the specified VLAN and assigned to the specified priority. + */ +rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) +{ + rtk_api_ret_t retVal; + rtk_uint32 index; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + /* vid must be 0~8191 */ + if (pvid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* priority must be 0~7 */ + if (priority > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + if((retVal = rtk_vlan_checkAndCreateMbr(pvid, &index)) != RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), index, priority)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portPvid_get + * Description: + * Get VLAN ID(PVID) on specified port. + * Input: + * port - Port id. + * Output: + * pPvid - Specified VLAN ID. + * pPriority - 802.1p priority for the PVID. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get the PVID and 802.1p priority for the PVID of Port-based VLAN. + */ +rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority) +{ + rtk_api_ret_t retVal; + rtk_uint32 index, pri; + rtl8367c_vlanconfiguser mbrCfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pPvid) + return RT_ERR_NULL_POINTER; + + if(NULL == pPriority) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), &index, &pri)) != RT_ERR_OK) + return retVal; + + memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); + if ((retVal = rtl8367c_getAsicVlanMemberConfig(index, &mbrCfg)) != RT_ERR_OK) + return retVal; + + *pPvid = mbrCfg.evid; + *pPriority = pri; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_set + * Description: + * Set VLAN ingress for each port. + * Input: + * port - Port id. + * igr_filter - VLAN ingress function enable status. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number + * RT_ERR_ENABLE - Invalid enable input + * Note: + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member + * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. + */ +rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (igr_filter >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), igr_filter)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portIgrFilterEnable_get + * Description: + * Get VLAN Ingress Filter + * Input: + * port - Port id. + * Output: + * pIgr_filter - VLAN ingress function enable status. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter status. + * The status of vlan ingress filter is as following: + * - DISABLED + * - ENABLED + */ +rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pIgr_filter) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), pIgr_filter)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portAcceptFrameType_set + * Description: + * Set VLAN accept_frame_type + * Input: + * port - Port id. + * accept_frame_type - accept frame type + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. + * Note: + * The API is used for checking 802.1Q tagged frames. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (accept_frame_type >= ACCEPT_FRAME_TYPE_END) + return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; + + if ((retVal = rtl8367c_setAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), (rtl8367c_accframetype)accept_frame_type)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portAcceptFrameType_get + * Description: + * Get VLAN accept_frame_type + * Input: + * port - Port id. + * Output: + * pAccept_frame_type - accept frame type + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can Get the VLAN ingress filter. + * The accept frame type as following: + * - ACCEPT_FRAME_TYPE_ALL + * - ACCEPT_FRAME_TYPE_TAG_ONLY + * - ACCEPT_FRAME_TYPE_UNTAG_ONLY + */ +rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type) +{ + rtk_api_ret_t retVal; + rtl8367c_accframetype acc_frm_type; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pAccept_frame_type) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), &acc_frm_type)) != RT_ERR_OK) + return retVal; + + *pAccept_frame_type = (rtk_vlan_acceptFrameType_t)acc_frm_type; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_add + * Description: + * Add the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * pInfo - Protocol and port based VLAN configuration information. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * RT_ERR_VLAN_PRIORITY - Invalid priority. + * RT_ERR_TBL_FULL - Table is full. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo) +{ + rtk_api_ret_t retVal, i; + rtk_uint32 exist, empty, used, index; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + rtl8367c_provlan_frametype tmp; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pInfo) + return RT_ERR_NULL_POINTER; + + if (pInfo->proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_OUT_OF_RANGE; + + if (pInfo->frame_type >= FRAME_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + if (pInfo->cvid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if (pInfo->cpri > RTL8367C_PRIMAX) + return RT_ERR_VLAN_PRIORITY; + + exist = 0xFF; + empty = 0xFF; + for (i = RTL8367C_PROTOVLAN_GIDX_MAX; i >= 0; i--) + { + if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + tmp = pInfo->frame_type; + if (ppb_data_cfg.etherType == pInfo->proto_type && ppb_data_cfg.frameType == tmp) + { + /*Already exist*/ + exist = i; + break; + } + else if (ppb_data_cfg.etherType == 0 && ppb_data_cfg.frameType == 0) + { + /*find empty index*/ + empty = i; + } + } + + used = 0xFF; + /*No empty and exist index*/ + if (0xFF == exist && 0xFF == empty) + return RT_ERR_TBL_FULL; + else if (existframe_type; + ppb_data_cfg.etherType = pInfo->proto_type; + if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(empty, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + used = empty; + } + else + return RT_ERR_FAILED; + + if((retVal = rtk_vlan_checkAndCreateMbr(pInfo->cvid, &index)) != RT_ERR_OK) + return retVal; + + ppb_vlan_cfg.vlan_idx = index; + ppb_vlan_cfg.valid = TRUE; + ppb_vlan_cfg.priority = pInfo->cpri; + if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), used, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_get + * Description: + * Get the protocol-and-port-based vlan to the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * pInfo - Protocol and port based VLAN configuration information. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo) +{ + rtk_api_ret_t retVal; + rtk_uint32 i; + rtk_uint32 ppb_idx; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_OUT_OF_RANGE; + + if (frame_type >= FRAME_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + ppb_idx = 0; + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + + if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) + { + ppb_idx = i; + break; + } + else if (RTL8367C_PROTOVLAN_GIDX_MAX == i) + return RT_ERR_TBL_FULL; + } + + if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + if (FALSE == ppb_vlan_cfg.valid) + return RT_ERR_FAILED; + + pInfo->frame_type = frame_type; + pInfo->proto_type = proto_type; + pInfo->cvid = vlan_mbrCfgVid[ppb_vlan_cfg.vlan_idx]; + pInfo->cpri = ppb_vlan_cfg.priority; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_del + * Description: + * Delete the protocol-and-port-based vlan from the specified port of device. + * Input: + * port - Port id. + * proto_type - protocol-and-port-based vlan protocol type. + * frame_type - protocol-and-port-based vlan frame type. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * RT_ERR_TBL_FULL - Table is full. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * The frame type is shown in the following: + * - FRAME_TYPE_ETHERNET + * - FRAME_TYPE_RFC1042 + * - FRAME_TYPE_LLCOTHER + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, bUsed; + rtk_uint32 ppb_idx; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) + return RT_ERR_OUT_OF_RANGE; + + if (frame_type >= FRAME_TYPE_END) + return RT_ERR_OUT_OF_RANGE; + + ppb_idx = 0; + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + + if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) + { + ppb_idx = i; + ppb_vlan_cfg.valid = FALSE; + ppb_vlan_cfg.vlan_idx = 0; + ppb_vlan_cfg.priority = 0; + if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + } + } + + bUsed = FALSE; + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i, ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + if (TRUE == ppb_vlan_cfg.valid) + { + bUsed = TRUE; + break; + } + } + + if (FALSE == bUsed) /*No Port use this PPB Index, Delete it*/ + { + ppb_data_cfg.etherType=0; + ppb_data_cfg.frameType=0; + if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(ppb_idx, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + } + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_protoAndPortBasedVlan_delAll + * Description: + * Delete all protocol-and-port-based vlans from the specified port of device. + * Input: + * port - Port id. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_OUT_OF_RANGE - input out of range. + * Note: + * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline + * Delete all flow table protocol-and-port-based vlan entries. + */ +rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port) +{ + rtk_api_ret_t retVal; + rtk_uint32 i, j, bUsed[4]; + rtl8367c_protocolgdatacfg ppb_data_cfg; + rtl8367c_protocolvlancfg ppb_vlan_cfg; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + ppb_vlan_cfg.valid = FALSE; + ppb_vlan_cfg.vlan_idx = 0; + ppb_vlan_cfg.priority = 0; + if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), i, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + } + + bUsed[0] = FALSE; + bUsed[1] = FALSE; + bUsed[2] = FALSE; + bUsed[3] = FALSE; + RTK_SCAN_ALL_PHY_PORTMASK(i) + { + for (j = 0; j <= RTL8367C_PROTOVLAN_GIDX_MAX; j++) + { + if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i,j, &ppb_vlan_cfg)) != RT_ERR_OK) + return retVal; + + if (TRUE == ppb_vlan_cfg.valid) + { + bUsed[j] = TRUE; + } + } + } + + for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) + { + if (FALSE == bUsed[i]) /*No Port use this PPB Index, Delete it*/ + { + ppb_data_cfg.etherType=0; + ppb_data_cfg.frameType=0; + if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) + return retVal; + } + } + + + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_tagMode_set + * Description: + * Set CVLAN egress tag mode + * Input: + * port - Port id. + * tag_mode - The egress tag mode. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_ENABLE - Invalid enable input. + * Note: + * The API can set Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (tag_mode >= VLAN_TAG_MODE_END) + return RT_ERR_PORT_ID; + + if ((retVal = rtl8367c_setAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), tag_mode)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_tagMode_get + * Description: + * Get CVLAN egress tag mode + * Input: + * port - Port id. + * Output: + * pTag_mode - The egress tag mode. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * The API can get Egress tag mode. There are 4 mode for egress tag: + * - VLAN_TAG_MODE_ORIGINAL, + * - VLAN_TAG_MODE_KEEP_FORMAT, + * - VLAN_TAG_MODE_PRI. + * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, + */ +rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode) +{ + rtk_api_ret_t retVal; + rtl8367c_egtagmode mode; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pTag_mode) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), &mode)) != RT_ERR_OK) + return retVal; + + *pTag_mode = (rtk_vlan_tagMode_t)mode; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_transparent_set + * Description: + * Set VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pIgr_pmask); + + if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_transparent_get + * Description: + * Get VLAN transparent mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) + return retVal; + + if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_keep_set + * Description: + * Set VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * pIgr_pmask - Ingress Port Mask. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + RTK_CHK_PORTMASK_VALID(pIgr_pmask); + + if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + if ((retVal = rtl8367c_setAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_keep_get + * Description: + * Get VLAN egress keep mode + * Input: + * egr_port - Egress Port id. + * Output: + * pIgr_pmask - Ingress Port Mask + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port number. + * Note: + * None. + */ +rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) +{ + rtk_api_ret_t retVal; + rtk_uint32 pmask; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(egr_port); + + if(NULL == pIgr_pmask) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) + return retVal; + + if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) + return RT_ERR_FAILED; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_stg_set + * Description: + * Set spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * stg - spanning tree group instance. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_MSTI - Invalid msti parameter + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can set spanning tree group instance of the vlan to the specified device. + */ +rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg) +{ + rtk_api_ret_t retVal; + rtl8367c_user_vlan4kentry vlan4K; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + /* priority must be 0~15 */ + if (stg > RTL8367C_MSTIMAX) + return RT_ERR_MSTI; + + /* update 4K table */ + vlan4K.vid = vid; + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + vlan4K.fid_msti= stg; + if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_stg_get + * Description: + * Get spanning tree group instance of the vlan to the specified device + * Input: + * vid - Specified VLAN ID. + * Output: + * pStg - spanning tree group instance. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_VLAN_VID - Invalid VID parameter. + * Note: + * The API can get spanning tree group instance of the vlan to the specified device. + */ +rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg) +{ + rtk_api_ret_t retVal; + rtl8367c_user_vlan4kentry vlan4K; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~4095 */ + if (vid > RTL8367C_VIDMAX) + return RT_ERR_VLAN_VID; + + if(NULL == pStg) + return RT_ERR_NULL_POINTER; + + /* update 4K table */ + vlan4K.vid = vid; + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + + *pStg = vlan4K.fid_msti; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portFid_set + * Description: + * Set port-based filtering database + * Input: + * port - Port id. + * enable - ebable port-based FID + * fid - Specified filtering database. + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_L2_FID - Invalid fid. + * RT_ERR_INPUT - Invalid input parameter. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can set port-based filtering database. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (enable>=RTK_ENABLE_END) + return RT_ERR_ENABLE; + + /* fid must be 0~4095 */ + if (fid > RTK_FID_MAX) + return RT_ERR_L2_FID; + + if ((retVal = rtl8367c_setAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_setAsicPortBasedFid(rtk_switch_port_L2P_get(port), fid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_portFid_get + * Description: + * Get port-based filtering database + * Input: + * port - Port id. + * Output: + * pEnable - ebable port-based FID + * pFid - Specified filtering database. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Invalid input parameters. + * RT_ERR_PORT_ID - Invalid port ID. + * Note: + * The API can get port-based filtering database status. If the function is enabled, all input + * packets will be assigned to the port-based fid regardless vlan tag. + */ +rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if(NULL == pFid) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), pEnable))!=RT_ERR_OK) + return retVal; + + if ((retVal = rtl8367c_getAsicPortBasedFid(rtk_switch_port_L2P_get(port), pFid))!=RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_set + * Description: + * Set Untag DSCP priority assign + * Input: + * enable - state of Untag DSCP priority assign + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_ENABLE - Invalid input parameters. + * Note: + * + */ +rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_set(rtk_enable_t enable) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(enable >= RTK_ENABLE_END) + return RT_ERR_ENABLE; + + if ((retVal = rtl8367c_setAsicVlanUntagDscpPriorityEn((rtk_uint32)enable)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_UntagDscpPriorityEnable_get + * Description: + * Get Untag DSCP priority assign + * Input: + * None + * Output: + * pEnable - state of Untag DSCP priority assign + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - Null pointer + * Note: + * + */ +rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable) +{ + rtk_api_ret_t retVal; + rtk_uint32 value; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnable) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicVlanUntagDscpPriorityEn(&value)) != RT_ERR_OK) + return retVal; + + *pEnable = (rtk_enable_t)value; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stp_mstpState_set + * Description: + * Configure spanning tree state per each port. + * Input: + * port - Port id + * msti - Multiple spanning tree instance. + * stp_state - Spanning tree state for msti + * Output: + * None + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * RT_ERR_MSTP_STATE - Invalid STP state. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (msti > RTK_MAX_NUM_OF_MSTI) + return RT_ERR_MSTI; + + if (stp_state >= STP_STATE_END) + return RT_ERR_MSTP_STATE; + + if ((retVal = rtl8367c_setAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, stp_state)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_stp_mstpState_get + * Description: + * Get spanning tree state per each port. + * Input: + * port - Port id. + * msti - Multiple spanning tree instance. + * Output: + * pStp_state - Spanning tree state for msti + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_PORT_ID - Invalid port number. + * RT_ERR_MSTI - Invalid msti parameter. + * Note: + * System supports per-port multiple spanning tree state for each msti. + * There are four states supported by ASIC. + * - STP_STATE_DISABLED + * - STP_STATE_BLOCKING + * - STP_STATE_LEARNING + * - STP_STATE_FORWARDING + */ +rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* Check Port Valid */ + RTK_CHK_PORT_VALID(port); + + if (msti > RTK_MAX_NUM_OF_MSTI) + return RT_ERR_MSTI; + + if(NULL == pStp_state) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, pStp_state)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_checkAndCreateMbr + * Description: + * Check and create Member configuration and return index + * Input: + * vid - VLAN id. + * Output: + * pIndex - Member configuration index + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_VLAN_VID - Invalid VLAN ID. + * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found + * RT_ERR_TBL_FULL - Member Configuration table full + * Note: + * + */ +rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) +{ + rtk_api_ret_t retVal; + rtl8367c_user_vlan4kentry vlan4K; + rtl8367c_vlanconfiguser vlanMC; + rtk_uint32 idx; + rtk_uint32 empty_idx = 0xFFFF; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + /* vid must be 0~8191 */ + if (vid > RTL8367C_EVIDMAX) + return RT_ERR_VLAN_VID; + + /* Null pointer check */ + if(NULL == pIndex) + return RT_ERR_NULL_POINTER; + + /* Get 4K VLAN */ + if (vid <= RTL8367C_VIDMAX) + { + memset(&vlan4K, 0x00, sizeof(rtl8367c_user_vlan4kentry)); + vlan4K.vid = vid; + if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) + return retVal; + } + + /* Search exist entry */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! return index */ + *pIndex = idx; + return RT_ERR_OK; + } + } + } + + /* Not found, Read H/W Member Configuration table to update database */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) + return retVal; + + if( (vlanMC.evid == 0) && (vlanMC.mbr == 0x00)) + { + vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; + vlan_mbrCfgVid[idx] = 0; + } + else + { + vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[idx] = vlanMC.evid; + } + } + + /* Search exist entry again */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) + { + if(vlan_mbrCfgVid[idx] == vid) + { + /* Found! return index */ + *pIndex = idx; + return RT_ERR_OK; + } + } + } + + /* try to look up an empty index */ + for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) + { + if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) + { + empty_idx = idx; + break; + } + } + + if(empty_idx == 0xFFFF) + { + /* No empty index */ + return RT_ERR_TBL_FULL; + } + + if (vid > RTL8367C_VIDMAX) + { + /* > 4K, there is no 4K entry, create on member configuration directly */ + memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); + vlanMC.evid = vid; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) + return retVal; + } + else + { + /* Copy from 4K table */ + vlanMC.evid = vid; + vlanMC.mbr = vlan4K.mbr; + vlanMC.fid_msti = vlan4K.fid_msti; + vlanMC.meteridx= vlan4K.meteridx; + vlanMC.envlanpol= vlan4K.envlanpol; + vlanMC.vbpen = vlan4K.vbpen; + vlanMC.vbpri = vlan4K.vbpri; + if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) + return retVal; + } + + /* Update Database */ + vlan_mbrCfgUsage[empty_idx] = MBRCFG_USED_BY_VLAN; + vlan_mbrCfgVid[empty_idx] = vid; + + *pIndex = empty_idx; + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_reservedVidAction_set + * Description: + * Set Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * action_vid0 - Action for VID 0. + * action_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(action_vid0 >= RESVID_ACTION_END) + return RT_ERR_INPUT; + + if(action_vid4095 >= RESVID_ACTION_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setReservedVidAction((rtk_uint32)action_vid0, (rtk_uint32)action_vid4095)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_reservedVidAction_get + * Description: + * Get Action of VLAN ID = 0 & 4095 tagged packet + * Input: + * pAction_vid0 - Action for VID 0. + * pAction_vid4095 - Action for VID 4095. + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_NULL_POINTER - NULL Pointer + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(pAction_vid0 == NULL) + return RT_ERR_NULL_POINTER; + + if(pAction_vid4095 == NULL) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getReservedVidAction((rtk_uint32 *)pAction_vid0, (rtk_uint32 *)pAction_vid4095)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_set + * Description: + * Set Real keep 1p remarking feature + * Input: + * enabled - State of 1p remarking at real keep packet + * Output: + * None. + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(enabled >= RTK_ENABLE_END) + return RT_ERR_INPUT; + + if ((retVal = rtl8367c_setRealKeepRemarkEn((rtk_uint32)enabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_realKeepRemarkEnable_get + * Description: + * Get Real keep 1p remarking feature + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if(NULL == pEnabled) + return RT_ERR_NULL_POINTER; + + if ((retVal = rtl8367c_getRealKeepRemarkEn((rtk_uint32 *)pEnabled)) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + +/* Function Name: + * rtk_vlan_reset + * Description: + * Reset VLAN + * Input: + * None. + * Output: + * pEnabled - State of 1p remarking at real keep packet + * Return: + * RT_ERR_OK - OK + * RT_ERR_FAILED - Failed + * RT_ERR_SMI - SMI access error + * RT_ERR_INPUT - Error Input + * Note: + * + */ +rtk_api_ret_t rtk_vlan_reset(void) +{ + rtk_api_ret_t retVal; + + /* Check initialization state */ + RTK_CHK_INIT_STATE(); + + if ((retVal = rtl8367c_resetVlan()) != RT_ERR_OK) + return retVal; + + return RT_ERR_OK; +} + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s.c new file mode 100755 index 00000000..6a55631d --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s.c @@ -0,0 +1,580 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +//include from rtl8367c dir +#include "./rtl8367c/include/rtk_switch.h" +#include "./rtl8367c/include/vlan.h" +#include "./rtl8367c/include/stat.h" +#include "./rtl8367c/include/port.h" + +#define RTL8367C_SW_CPU_PORT 6 + + //RTL8367C_PHY_PORT_NUM + ext0 + ext1 +#define RTL8367C_NUM_PORTS 7 +#define RTL8367C_NUM_VIDS 4096 + +struct rtl8367_priv { + struct switch_dev swdev; + bool global_vlan_enable; +}; + +struct rtl8367_mib_counter { + const char *name; +}; + +struct rtl8367_vlan_info { + unsigned short vid; + unsigned int untag; + unsigned int member; + unsigned char fid; +}; + +struct rtl8367_priv rtl8367_priv_data; + +unsigned int rtl8367c_port_id[RTL8367C_NUM_PORTS]={0,1,2,3,4,EXT_PORT1,EXT_PORT0}; + +void (*rtl8367_switch_reset_func)(void)=NULL; + +static struct rtl8367_mib_counter rtl8367c_mib_counters[] = { + {"ifInOctets"}, + {"dot3StatsFCSErrors"}, + {"dot3StatsSymbolErrors"}, + {"dot3InPauseFrames"}, + {"dot3ControlInUnknownOpcodes"}, + {"etherStatsFragments"}, + {"etherStatsJabbers"}, + {"ifInUcastPkts"}, + {"etherStatsDropEvents"}, + {"etherStatsOctets"}, + {"etherStatsUndersizePkts"}, + {"etherStatsOversizePkts"}, + {"etherStatsPkts64Octets"}, + {"etherStatsPkts65to127Octets"}, + {"etherStatsPkts128to255Octets"}, + {"etherStatsPkts256to511Octets"}, + {"etherStatsPkts512to1023Octets"}, + {"etherStatsPkts1024toMaxOctets"}, + {"etherStatsMcastPkts"}, + {"etherStatsBcastPkts"}, + {"ifOutOctets"}, + {"dot3StatsSingleCollisionFrames"}, + {"dot3StatsMultipleCollisionFrames"}, + {"dot3StatsDeferredTransmissions"}, + {"dot3StatsLateCollisions"}, + {"etherStatsCollisions"}, + {"dot3StatsExcessiveCollisions"}, + {"dot3OutPauseFrames"}, + {"dot1dBasePortDelayExceededDiscards"}, + {"dot1dTpPortInDiscards"}, + {"ifOutUcastPkts"}, + {"ifOutMulticastPkts"}, + {"ifOutBrocastPkts"}, + {"outOampduPkts"}, + {"inOampduPkts"}, + {"pktgenPkts"}, + {"inMldChecksumError"}, + {"inIgmpChecksumError"}, + {"inMldSpecificQuery"}, + {"inMldGeneralQuery"}, + {"inIgmpSpecificQuery"}, + {"inIgmpGeneralQuery"}, + {"inMldLeaves"}, + {"inIgmpLeaves"}, + {"inIgmpJoinsSuccess"}, + {"inIgmpJoinsFail"}, + {"inMldJoinsSuccess"}, + {"inMldJoinsFail"}, + {"inReportSuppressionDrop"}, + {"inLeaveSuppressionDrop"}, + {"outIgmpReports"}, + {"outIgmpLeaves"}, + {"outIgmpGeneralQuery"}, + {"outIgmpSpecificQuery"}, + {"outMldReports"}, + {"outMldLeaves"}, + {"outMldGeneralQuery"}, + {"outMldSpecificQuery"}, + {"inKnownMulticastPkts"}, + {"ifInMulticastPkts"}, + {"ifInBroadcastPkts"}, + {"ifOutDiscards"} +}; + +/*rtl8367c proprietary switch API wrapper */ +static inline unsigned int rtl8367c_sw_to_phy_port(int port) +{ + return rtl8367c_port_id[port]; +} + +static inline unsigned int rtl8367c_portmask_phy_to_sw(rtk_portmask_t phy_portmask) +{ + int i; + for (i = 0; i < RTL8367C_NUM_PORTS; i++) { + if(RTK_PORTMASK_IS_PORT_SET(phy_portmask,rtl8367c_sw_to_phy_port(i))) { + RTK_PORTMASK_PORT_CLEAR(phy_portmask,rtl8367c_sw_to_phy_port(i)); + RTK_PORTMASK_PORT_SET(phy_portmask,i); + } + + } + return (unsigned int)phy_portmask.bits[0]; +} + +static int rtl8367c_reset_mibs(void) +{ + return rtk_stat_global_reset(); +} + +static int rtl8367c_reset_port_mibs(int port) +{ + + return rtk_stat_port_reset(rtl8367c_sw_to_phy_port(port)); +} + +static int rtl8367c_get_mibs_num(void) +{ + return ARRAY_SIZE(rtl8367c_mib_counters); +} + +static const char *rtl8367c_get_mib_name(int idx) +{ + + return rtl8367c_mib_counters[idx].name; +} + +static int rtl8367c_get_port_mib_counter(int idx, int port, unsigned long long *counter) +{ + return rtk_stat_port_get(rtl8367c_sw_to_phy_port(port), idx, counter); +} + +static int rtl8367c_is_vlan_valid(unsigned int vlan) +{ + unsigned max = RTL8367C_NUM_VIDS; + + if (vlan == 0 || vlan >= max) + return 0; + + return 1; +} + +static int rtl8367c_get_vlan( unsigned short vid, struct rtl8367_vlan_info *vlan) +{ + rtk_vlan_cfg_t vlan_cfg; + + memset(vlan, '\0', sizeof(struct rtl8367_vlan_info)); + + if (vid >= RTL8367C_NUM_VIDS) + return -EINVAL; + + if(rtk_vlan_get(vid,&vlan_cfg)) + return -EINVAL; + + vlan->vid = vid; + vlan->member = rtl8367c_portmask_phy_to_sw(vlan_cfg.mbr); + vlan->untag = rtl8367c_portmask_phy_to_sw(vlan_cfg.untag); + vlan->fid = vlan_cfg.fid_msti; + + return 0; +} + +static int rtl8367c_set_vlan( unsigned short vid, u32 mbr, u32 untag, u8 fid) +{ + rtk_vlan_cfg_t vlan_cfg; + int i; + + memset(&vlan_cfg, 0x00, sizeof(rtk_vlan_cfg_t)); + + for (i = 0; i < RTL8367C_NUM_PORTS; i++) { + if (mbr & (1 << i)) { + RTK_PORTMASK_PORT_SET(vlan_cfg.mbr, rtl8367c_sw_to_phy_port(i)); + if(untag & (1 << i)) + RTK_PORTMASK_PORT_SET(vlan_cfg.untag, rtl8367c_sw_to_phy_port(i)); + } + } + vlan_cfg.fid_msti=fid; + vlan_cfg.ivl_en = 1; + return rtk_vlan_set(vid, &vlan_cfg); +} + + +static int rtl8367c_get_pvid( int port, int *pvid) +{ + u32 prio=0; + + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + return rtk_vlan_portPvid_get(rtl8367c_sw_to_phy_port(port),pvid,&prio); +} + + +static int rtl8367c_set_pvid( int port, int pvid) +{ + u32 prio=0; + + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + return rtk_vlan_portPvid_set(rtl8367c_sw_to_phy_port(port),pvid,prio); +} + +static int rtl8367c_get_port_link(int port, int *link, int *speed, int *duplex) +{ + + if(rtk_port_phyStatus_get(rtl8367c_sw_to_phy_port(port),(rtk_port_linkStatus_t *)link, + (rtk_port_speed_t *)speed,(rtk_port_duplex_t *)duplex)) + return -EINVAL; + + return 0; +} + +/*common rtl8367 swconfig entry API*/ + +static int +rtl8367_sw_set_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); + + priv->global_vlan_enable = val->value.i ; + + return 0; +} + +static int +rtl8367_sw_get_vlan_enable(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); + + val->value.i = priv->global_vlan_enable; + + return 0; +} + +static int rtl8367_sw_reset_mibs(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + return rtl8367c_reset_mibs(); +} + + +static int rtl8367_sw_reset_port_mibs(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int port; + + port = val->port_vlan; + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + return rtl8367c_reset_port_mibs(port); +} + +static int rtl8367_sw_get_port_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int i, len = 0; + unsigned long long counter = 0; + static char mib_buf[4096]; + + if (val->port_vlan >= RTL8367C_NUM_PORTS) + return -EINVAL; + + len += snprintf(mib_buf + len, sizeof(mib_buf) - len, + "Port %d MIB counters\n", + val->port_vlan); + + for (i = 0; i port_vlan, + &counter)) + len += snprintf(mib_buf + len, sizeof(mib_buf) - len, + "%llu\n", counter); + else + len += snprintf(mib_buf + len, sizeof(mib_buf) - len, + "%s\n", "N/A"); + } + + val->value.s = mib_buf; + val->len = len; + return 0; +} + + +static int rtl8367_sw_get_vlan_info(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int i; + u32 len = 0; + struct rtl8367_vlan_info vlan; + static char vlan_buf[256]; + int err; + + if (!rtl8367c_is_vlan_valid(val->port_vlan)) + return -EINVAL; + + memset(vlan_buf, '\0', sizeof(vlan_buf)); + + err = rtl8367c_get_vlan(val->port_vlan, &vlan); + if (err) + return err; + + len += snprintf(vlan_buf + len, sizeof(vlan_buf) - len, + "VLAN %d: Ports: '", vlan.vid); + + for (i = 0; i value.s = vlan_buf; + val->len = len; + + return 0; +} + + +static int rtl8367_sw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct switch_port *port; + struct rtl8367_vlan_info vlan; + int i; + + if (!rtl8367c_is_vlan_valid(val->port_vlan)) + return -EINVAL; + + if(rtl8367c_get_vlan(val->port_vlan, &vlan)) + return -EINVAL; + + port = &val->value.ports[0]; + val->len = 0; + for (i = 0; i id = i; + port->flags = (vlan.untag & BIT(i)) ? + 0 : BIT(SWITCH_PORT_FLAG_TAGGED); + val->len++; + port++; + } + return 0; +} + + +static int rtl8367_sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct switch_port *port; + u32 member = 0; + u32 untag = 0; + u8 fid=0; + int err; + int i; + + if (!rtl8367c_is_vlan_valid(val->port_vlan)) + return -EINVAL; + + port = &val->value.ports[0]; + for (i = 0; i < val->len; i++, port++) { + int pvid = 0; + member |= BIT(port->id); + + if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) + untag |= BIT(port->id); + + /* + * To ensure that we have a valid MC entry for this VLAN, + * initialize the port VLAN ID here. + */ + err = rtl8367c_get_pvid(port->id, &pvid); + if (err < 0) + return err; + if (pvid == 0) { + err = rtl8367c_set_pvid(port->id, val->port_vlan); + if (err < 0) + return err; + } + } + + //pr_info("[%s] vid=%d , mem=%x,untag=%x,fid=%d \n",__func__,val->port_vlan,member,untag,fid); + + return rtl8367c_set_vlan(val->port_vlan, member, untag, fid); + +} + + +static int rtl8367_sw_get_port_pvid(struct switch_dev *dev, int port, int *val) +{ + return rtl8367c_get_pvid(port, val); +} + + +static int rtl8367_sw_set_port_pvid(struct switch_dev *dev, int port, int val) +{ + return rtl8367c_set_pvid(port, val); +} + + +static int rtl8367_sw_reset_switch(struct switch_dev *dev) +{ + if(rtl8367_switch_reset_func) + (*rtl8367_switch_reset_func)(); + else + printk("rest switch is not supported\n"); + + return 0; +} + +static int rtl8367_sw_get_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ + int speed; + + if (port >= RTL8367C_NUM_PORTS) + return -EINVAL; + + if(rtl8367c_get_port_link(port,(int *)&link->link,(int *)&speed,(int *)&link->duplex)) + return -EINVAL; + + if (!link->link) + return 0; + + switch (speed) { + case 0: + link->speed = SWITCH_PORT_SPEED_10; + break; + case 1: + link->speed = SWITCH_PORT_SPEED_100; + break; + case 2: + link->speed = SWITCH_PORT_SPEED_1000; + break; + default: + link->speed = SWITCH_PORT_SPEED_UNKNOWN; + break; + } + + return 0; +} + + +static struct switch_attr rtl8367_globals[] = { + { + .type = SWITCH_TYPE_INT, + .name = "enable_vlan", + .description = "Enable VLAN mode", + .set = rtl8367_sw_set_vlan_enable, + .get = rtl8367_sw_get_vlan_enable, + .max = 1, + }, { + .type = SWITCH_TYPE_NOVAL, + .name = "reset_mibs", + .description = "Reset all MIB counters", + .set = rtl8367_sw_reset_mibs, + } +}; + +static struct switch_attr rtl8367_port[] = { + { + .type = SWITCH_TYPE_NOVAL, + .name = "reset_mib", + .description = "Reset single port MIB counters", + .set = rtl8367_sw_reset_port_mibs, + }, { + .type = SWITCH_TYPE_STRING, + .name = "mib", + .description = "Get MIB counters for port", + //.max = 33, + .set = NULL, + .get = rtl8367_sw_get_port_mib, + }, +}; + +static struct switch_attr rtl8367_vlan[] = { + { + .type = SWITCH_TYPE_STRING, + .name = "info", + .description = "Get vlan information", + .max = 1, + .set = NULL, + .get = rtl8367_sw_get_vlan_info, + }, +}; + +static const struct switch_dev_ops rtl8367_sw_ops = { + .attr_global = { + .attr = rtl8367_globals, + .n_attr = ARRAY_SIZE(rtl8367_globals), + }, + .attr_port = { + .attr = rtl8367_port, + .n_attr = ARRAY_SIZE(rtl8367_port), + }, + .attr_vlan = { + .attr = rtl8367_vlan, + .n_attr = ARRAY_SIZE(rtl8367_vlan), + }, + + .get_vlan_ports = rtl8367_sw_get_vlan_ports, + .set_vlan_ports = rtl8367_sw_set_vlan_ports, + .get_port_pvid = rtl8367_sw_get_port_pvid, + .set_port_pvid = rtl8367_sw_set_port_pvid, + .reset_switch = rtl8367_sw_reset_switch, + .get_port_link = rtl8367_sw_get_port_link, +}; + +int rtl8367s_swconfig_init(void (*reset_func)(void)) +{ + struct rtl8367_priv *priv = &rtl8367_priv_data; + struct switch_dev *dev=&priv->swdev; + int err=0; + + rtl8367_switch_reset_func = reset_func ; + + memset(priv, 0, sizeof(struct rtl8367_priv)); + priv->global_vlan_enable =0; + + dev->name = "RTL8367C"; + dev->cpu_port = RTL8367C_SW_CPU_PORT; + dev->ports = RTL8367C_NUM_PORTS; + dev->vlans = RTL8367C_NUM_VIDS; + dev->ops = &rtl8367_sw_ops; + dev->alias = "RTL8367C"; + err = register_switch(dev, NULL); + + pr_info("[%s]\n",__func__); + + return err; +} diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_dbg.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_dbg.c new file mode 100755 index 00000000..ec866797 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_dbg.c @@ -0,0 +1,655 @@ +#include +#include +#include +#include +#include + +#include "./rtl8367c/include/rtk_switch.h" +#include "./rtl8367c/include/port.h" +#include "./rtl8367c/include/vlan.h" +#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" +#include "./rtl8367c/include/stat.h" +#include "./rtl8367c/include/l2.h" +#include "./rtl8367c/include/smi.h" +#include "./rtl8367c/include/mirror.h" +#include "./rtl8367c/include/igmp.h" +#include "./rtl8367c/include/leaky.h" + +static struct proc_dir_entry *proc_reg_dir; +static struct proc_dir_entry *proc_esw_cnt; +static struct proc_dir_entry *proc_vlan_cnt; +static struct proc_dir_entry *proc_mac_tbl; +static struct proc_dir_entry *proc_reg; +static struct proc_dir_entry *proc_phyreg; +static struct proc_dir_entry *proc_mirror; +static struct proc_dir_entry *proc_igmp; + +#define PROCREG_ESW_CNT "esw_cnt" +#define PROCREG_VLAN "vlan" +#define PROCREG_MAC_TBL "mac_tbl" +#define PROCREG_REG "reg" +#define PROCREG_PHYREG "phyreg" +#define PROCREG_MIRROR "mirror" +#define PROCREG_IGMP "igmp" +#define PROCREG_DIR "rtk_gsw" + +#define RTK_SW_VID_RANGE 16 + +static void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) +{ + rtk_port_t port; + rtk_stat_counter_t Cntr; + + for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + + for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { + rtk_stat_port_get(port, cntr_idx, &Cntr); + printk("%8llu", Cntr); + } + + printk("\n"); +} +static void rtk_hal_dump_mib(void) +{ + + printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", + "Port2", "Port3", "Port4", "Port16", "Port17"); + /* Get TX Unicast Pkts */ + printk("TX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfOutUcastPkts); + /* Get TX Multicast Pkts */ + printk("TX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfOutMulticastPkts); + /* Get TX BroadCast Pkts */ + printk("TX BroadCast Pkts:"); + rtk_dump_mib_type(STAT_IfOutBroadcastPkts); + /* Get TX Collisions */ + /* Get TX Puase Frames */ + printk("TX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3OutPauseFrames); + /* Get TX Drop Events */ + /* Get RX Unicast Pkts */ + printk("RX Unicast Pkts :"); + rtk_dump_mib_type(STAT_IfInUcastPkts); + /* Get RX Multicast Pkts */ + printk("RX Multicast Pkts:"); + rtk_dump_mib_type(STAT_IfInMulticastPkts); + /* Get RX Broadcast Pkts */ + printk("RX Broadcast Pkts:"); + rtk_dump_mib_type(STAT_IfInBroadcastPkts); + /* Get RX FCS Erros */ + printk("RX FCS Errors :"); + rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); + /* Get RX Undersize Pkts */ + printk("RX Undersize Pkts:"); + rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); + /* Get RX Discard Pkts */ + printk("RX Discard Pkts :"); + rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); + /* Get RX Fragments */ + printk("RX Fragments :"); + rtk_dump_mib_type(STAT_EtherStatsFragments); + /* Get RX Oversize Pkts */ + printk("RX Oversize Pkts :"); + rtk_dump_mib_type(STAT_EtherOversizeStats); + /* Get RX Jabbers */ + printk("RX Jabbers :"); + rtk_dump_mib_type(STAT_EtherStatsJabbers); + /* Get RX Pause Frames */ + printk("RX Pause Frames :"); + rtk_dump_mib_type(STAT_Dot3InPauseFrames); + /* clear MIB */ + rtk_stat_global_reset(); + +} + +static int rtk_hal_dump_vlan(void) +{ + rtk_vlan_cfg_t vlan; + int i; + + printk("vid portmap\n"); + for (i = 0; i < RTK_SW_VID_RANGE; i++) { + rtk_vlan_get(i, &vlan); + printk("%3d ", i); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT1) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT2) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT3) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + UTP_PORT4) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT0) ? '1' : '-'); + printk("%c", + RTK_PORTMASK_IS_PORT_SET(vlan.mbr, + EXT_PORT1) ? '1' : '-'); + printk("\n"); + } + + return 0; +} + +static void rtk_hal_dump_table(void) +{ + rtk_uint32 i; + rtk_uint32 address = 0; + rtk_l2_ucastAddr_t l2_data; + rtk_l2_ipMcastAddr_t ipMcastAddr; + rtk_l2_age_time_t age_timout; + + rtk_l2_aging_get(&age_timout); + printk("Mac table age timeout =%d\n",(unsigned int)age_timout); + + printk("hash port(0:17) fid vid mac-address\n"); + while (1) { + if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { + break; + } else { + printk("%03x ", l2_data.address); + for (i = 0; i < 5; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + for (i = 16; i < 18; i++) + if ( l2_data.port == i) + printk("1"); + else + printk("-"); + + printk(" %2d", l2_data.fid); + printk(" %4d", l2_data.cvid); + printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], + l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], + l2_data.mac.octet[4], l2_data.mac.octet[5]); + address ++; + } + } + + address = 0; + while (1) { + if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { + break; + } else { + printk("%03x ", ipMcastAddr.address); + for (i = 0; i < 5; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + for (i = 16; i < 18; i++) + printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); + printk(" "); + printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); + address ++; + } + } +} + +static void rtk_hal_clear_table(void) +{ + rtk_api_ret_t ret; + + ret = rtk_l2_table_clear(); + if (ret != RT_ERR_OK) + printk("rtk_l2_table_clear failed\n"); +} + +static void rtk_hal_read_reg(unsigned int reg_addr) +{ + ret_t retVal; + unsigned int reg_val; + + retVal = smi_read(reg_addr, ®_val); + + if(retVal != RT_ERR_OK) + printk("switch reg read failed\n"); + else + printk("reg0x%x = 0x%x\n", reg_addr, reg_val); +} + +static void rtk_hal_write_reg(unsigned int reg_addr , unsigned int reg_val) +{ + ret_t retVal; + + retVal = smi_write(reg_addr, reg_val); + + if(retVal != RT_ERR_OK) + printk("switch reg write failed\n"); + else + printk("write switch reg0x%x 0x%x success\n", reg_addr, reg_val); +} + +static void rtk_hal_get_phy_reg(unsigned int port ,unsigned int reg_addr ) +{ + ret_t retVal; + rtk_port_phy_data_t Data; + + retVal = rtk_port_phyReg_get(port, reg_addr, &Data); + if (retVal == RT_ERR_OK) + printk("Get: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, Data); + else + printk("read phy reg failed\n"); +} + +static void rtk_hal_set_phy_reg(unsigned int port ,unsigned int reg_addr,unsigned int reg_val) +{ + ret_t retVal; + + retVal = rtk_port_phyReg_set(port, reg_addr, reg_val); + if (retVal == RT_ERR_OK) + printk("Set: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, reg_val); + else + printk("write phy reg failed\n"); +} + +static void rtk_hal_set_port_mirror(unsigned int port ,unsigned int rx_port_map,unsigned int tx_port_map) +{ + rtk_portmask_t rx_portmask; + rtk_portmask_t tx_portmask; + rtk_api_ret_t ret; + int i; + + rtk_mirror_portIso_set(ENABLED); + RTK_PORTMASK_CLEAR(rx_portmask); + RTK_PORTMASK_CLEAR(tx_portmask); + + for (i = 0; i < 5; i++) + if (rx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(rx_portmask, i); + + for (i = 0; i < 2; i++) + if (rx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); + + RTK_PORTMASK_CLEAR(tx_portmask); + + for (i = 0; i < 5; i++) + if (tx_port_map & (1 << i)) + RTK_PORTMASK_PORT_SET(tx_portmask, i); + + for (i = 0; i < 2; i++) + if (tx_port_map & (1 << (i + 5))) + RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); + + ret = rtk_mirror_portBased_set(port, &rx_portmask, &tx_portmask); + + if (!ret) + printk("rtk_mirror_portBased_set success\n"); + +} + +static void rtk_hal_enable_igmpsnoop(int hw_on) +{ + rtk_api_ret_t ret; + rtk_portmask_t pmask; + + ret = rtk_igmp_init(); + if (hw_on == 1) { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + ret |= rtk_igmp_static_router_port_set(&pmask); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); + ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); + /* drop unknown multicast packets*/ + /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ + } else { + RTK_PORTMASK_CLEAR(pmask); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); + RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); + ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); + + ret |= rtk_igmp_static_router_port_set(&pmask); + } + + if(ret != RT_ERR_OK) + printk("enable switch igmpsnoop failed\n"); + +} + +static void rtk_hal_disable_igmpsnoop(void) +{ + if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) + printk("Disable IGMP SNOOPING failed\n"); +} + +static ssize_t mac_tbl_write(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + rtk_hal_clear_table(); + + return count; +} + + +static ssize_t phyreg_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[64]; + unsigned int port; + unsigned int offset; + unsigned int val; + + memset(buf, 0, 64); + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + + if(buf[0] == 'w') { + + if(sscanf(buf, "w %d %x %x", &port,&offset,&val) == -1) + return -EFAULT; + else + rtk_hal_set_phy_reg(port,offset,val); + + } else { + + if(sscanf(buf, "r %d %x",&port, &offset) == -1) + return -EFAULT; + else + rtk_hal_get_phy_reg(port,offset); + } + + return count; +} + +static ssize_t reg_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[64]; + unsigned int offset; + unsigned int val; + + memset(buf, 0, 64); + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + + if(buf[0] == 'w') { + + if(sscanf(buf, "w %x %x", &offset,&val) == -1) + return -EFAULT; + else + rtk_hal_write_reg(offset,val); + + } else { + + if(sscanf(buf, "r %x", &offset) == -1) + return -EFAULT; + else + rtk_hal_read_reg(offset); + } + + return count; +} + +static ssize_t mirror_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[64]; + unsigned int port; + unsigned int tx_map,rx_map; + + memset(buf, 0, 64); + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if(sscanf(buf, "%d %x %x", &port,&rx_map,&tx_map) == -1) + return -EFAULT; + else + rtk_hal_set_port_mirror(port,rx_map,tx_map); + + return count; +} + + +static ssize_t igmp_ops(struct file *file, + const char __user *buffer, size_t count, + loff_t *data) +{ + char buf[8]; + unsigned int ops; + + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + if(sscanf(buf, "%d", &ops) == -1) + return -EFAULT; + + if(ops == 0) + rtk_hal_disable_igmpsnoop(); + else if (ops == 1) + rtk_hal_enable_igmpsnoop(0); + else //hw igmp + rtk_hal_enable_igmpsnoop(1); + + return count; +} + + +static int esw_cnt_read(struct seq_file *seq, void *v) +{ + rtk_hal_dump_mib(); + return 0; +} + +static int vlan_read(struct seq_file *seq, void *v) +{ + rtk_hal_dump_vlan(); + return 0; +} + +static int mac_tbl_read(struct seq_file *seq, void *v) +{ + rtk_hal_dump_table(); + return 0; +} + +static int reg_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int phyreg_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int mirror_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int igmp_show(struct seq_file *seq, void *v) +{ + return 0; +} + +static int switch_count_open(struct inode *inode, struct file *file) +{ + return single_open(file, esw_cnt_read, 0); +} + +static int switch_vlan_open(struct inode *inode, struct file *file) +{ + return single_open(file, vlan_read, 0); +} + +static int mac_tbl_open(struct inode *inode, struct file *file) +{ + return single_open(file, mac_tbl_read, 0); +} + +static int reg_open(struct inode *inode, struct file *file) +{ + return single_open(file, reg_show, 0); +} + +static int phyreg_open(struct inode *inode, struct file *file) +{ + return single_open(file, phyreg_show, 0); +} + +static int mirror_open(struct inode *inode, struct file *file) +{ + return single_open(file, mirror_show, 0); +} + +static int igmp_open(struct inode *inode, struct file *file) +{ + return single_open(file, igmp_show, 0); +} + + +static const struct file_operations switch_count_fops = { + .owner = THIS_MODULE, + .open = switch_count_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release +}; + +static const struct file_operations switch_vlan_fops = { + .owner = THIS_MODULE, + .open = switch_vlan_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release +}; + +static const struct file_operations mac_tbl_fops = { + .owner = THIS_MODULE, + .open = mac_tbl_open, + .read = seq_read, + .llseek = seq_lseek, + .write = mac_tbl_write, + .release = single_release +}; + +static const struct file_operations reg_fops = { + .owner = THIS_MODULE, + .open = reg_open, + .read = seq_read, + .llseek = seq_lseek, + .write = reg_ops, + .release = single_release +}; + +static const struct file_operations phyreg_fops = { + .owner = THIS_MODULE, + .open = phyreg_open, + .read = seq_read, + .llseek = seq_lseek, + .write = phyreg_ops, + .release = single_release +}; + +static const struct file_operations mirror_fops = { + .owner = THIS_MODULE, + .open = mirror_open, + .read = seq_read, + .llseek = seq_lseek, + .write = mirror_ops, + .release = single_release +}; + +static const struct file_operations igmp_fops = { + .owner = THIS_MODULE, + .open = igmp_open, + .read = seq_read, + .llseek = seq_lseek, + .write = igmp_ops, + .release = single_release +}; + +int gsw_debug_proc_init(void) +{ + + if (!proc_reg_dir) + proc_reg_dir = proc_mkdir(PROCREG_DIR, NULL); + + proc_esw_cnt = + proc_create(PROCREG_ESW_CNT, 0, proc_reg_dir, &switch_count_fops); + + if (!proc_esw_cnt) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT); + + proc_vlan_cnt = + proc_create(PROCREG_VLAN, 0, proc_reg_dir, &switch_vlan_fops); + + if (!proc_vlan_cnt) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_VLAN); + + proc_mac_tbl = + proc_create(PROCREG_MAC_TBL, 0, proc_reg_dir, &mac_tbl_fops); + + if (!proc_mac_tbl) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MAC_TBL); + + proc_reg = + proc_create(PROCREG_REG, 0, proc_reg_dir, ®_fops); + + if (!proc_reg) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_REG); + + proc_phyreg = + proc_create(PROCREG_PHYREG, 0, proc_reg_dir, &phyreg_fops); + + if (!proc_phyreg) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_PHYREG); + + proc_mirror = + proc_create(PROCREG_MIRROR, 0, proc_reg_dir, &mirror_fops); + + if (!proc_mirror) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MIRROR); + + proc_igmp = + proc_create(PROCREG_IGMP, 0, proc_reg_dir, &igmp_fops); + + if (!proc_igmp) + pr_err("!! FAIL to create %s PROC !!\n", PROCREG_IGMP); + + return 0; +} + +void gsw_debug_proc_exit(void) +{ + if (proc_esw_cnt) + remove_proc_entry(PROCREG_ESW_CNT, proc_reg_dir); +} + + diff --git a/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_mdio.c b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_mdio.c new file mode 100755 index 00000000..ae958e89 --- /dev/null +++ b/root/target/linux/mediatek/files-5.4/drivers/net/phy/rtk/rtl8367s_mdio.c @@ -0,0 +1,312 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "./rtl8367c/include/rtk_switch.h" +#include "./rtl8367c/include/port.h" +#include "./rtl8367c/include/vlan.h" +#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" + +struct rtk_gsw { + struct device *dev; + struct mii_bus *bus; + int reset_pin; +}; + +static struct rtk_gsw *_gsw; + +extern int gsw_debug_proc_init(void); +extern void gsw_debug_proc_exit(void); + +#ifdef CONFIG_SWCONFIG +extern int rtl8367s_swconfig_init( void (*reset_func)(void) ); +#endif + +/*mii_mgr_read/mii_mgr_write is the callback API for rtl8367 driver*/ +unsigned int mii_mgr_read(unsigned int phy_addr,unsigned int phy_register,unsigned int *read_data) +{ + struct mii_bus *bus = _gsw->bus; + + mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); + + *read_data = bus->read(bus, phy_addr, phy_register); + + mutex_unlock(&bus->mdio_lock); + + return 0; +} + +unsigned int mii_mgr_write(unsigned int phy_addr,unsigned int phy_register,unsigned int write_data) +{ + struct mii_bus *bus = _gsw->bus; + + mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); + + bus->write(bus, phy_addr, phy_register, write_data); + + mutex_unlock(&bus->mdio_lock); + + return 0; +} + +static int rtl8367s_hw_reset(void) +{ + struct rtk_gsw *gsw = _gsw; + int ret; + + if (gsw->reset_pin < 0) + return 0; + + ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mediatek,reset-pin"); + + if (ret) + printk("fail to devm_gpio_request\n"); + + gpio_direction_output(gsw->reset_pin, 0); + + usleep_range(1000, 1100); + + gpio_set_value(gsw->reset_pin, 1); + + mdelay(500); + + devm_gpio_free(gsw->dev, gsw->reset_pin); + + return 0; + +} + +static int rtl8367s_vlan_config(int want_at_p0) +{ + rtk_vlan_cfg_t vlan1, vlan2; + + /* Set LAN/WAN VLAN partition */ + memset(&vlan1, 0x00, sizeof(rtk_vlan_cfg_t)); + + RTK_PORTMASK_PORT_SET(vlan1.mbr, EXT_PORT0); + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT1); + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT2); + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT3); + RTK_PORTMASK_PORT_SET(vlan1.untag, EXT_PORT0); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT1); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT2); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT3); + + if (want_at_p0) { + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT4); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT4); + } else { + RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT0); + RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT0); + } + + vlan1.ivl_en = 1; + + rtk_vlan_set(1, &vlan1); + + memset(&vlan2, 0x00, sizeof(rtk_vlan_cfg_t)); + + RTK_PORTMASK_PORT_SET(vlan2.mbr, EXT_PORT1); + RTK_PORTMASK_PORT_SET(vlan2.untag, EXT_PORT1); + + if (want_at_p0) { + RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT0); + RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT0); + } else { + RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT4); + RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT4); + } + + vlan2.ivl_en = 1; + rtk_vlan_set(2, &vlan2); + + rtk_vlan_portPvid_set(EXT_PORT0, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT1, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT2, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT3, 1, 0); + rtk_vlan_portPvid_set(EXT_PORT1, 2, 0); + + if (want_at_p0) { + rtk_vlan_portPvid_set(UTP_PORT0, 2, 0); + rtk_vlan_portPvid_set(UTP_PORT4, 1, 0); + } else { + rtk_vlan_portPvid_set(UTP_PORT0, 1, 0); + rtk_vlan_portPvid_set(UTP_PORT4, 2, 0); + } + + return 0; +} + +static int rtl8367s_hw_init(void) +{ + + rtl8367s_hw_reset(); + + if(rtk_switch_init()) + return -1; + + mdelay(500); + + if (rtk_vlan_reset()) + return -1; + + if (rtk_vlan_init()) + return -1; + + return 0; +} + +static void set_rtl8367s_sgmii(void) +{ + rtk_port_mac_ability_t mac_cfg; + rtk_mode_ext_t mode; + + mode = MODE_EXT_HSGMII; + mac_cfg.forcemode = MAC_FORCE; + mac_cfg.speed = PORT_SPEED_2500M; + mac_cfg.duplex = PORT_FULL_DUPLEX; + mac_cfg.link = PORT_LINKUP; + mac_cfg.nway = DISABLED; + mac_cfg.txpause = ENABLED; + mac_cfg.rxpause = ENABLED; + rtk_port_macForceLinkExt_set(EXT_PORT0, mode, &mac_cfg); + rtk_port_sgmiiNway_set(EXT_PORT0, DISABLED); + rtk_port_phyEnableAll_set(ENABLED); + +} + +static void set_rtl8367s_rgmii(void) +{ + rtk_port_mac_ability_t mac_cfg; + rtk_mode_ext_t mode; + + mode = MODE_EXT_RGMII; + mac_cfg.forcemode = MAC_FORCE; + mac_cfg.speed = PORT_SPEED_1000M; + mac_cfg.duplex = PORT_FULL_DUPLEX; + mac_cfg.link = PORT_LINKUP; + mac_cfg.nway = DISABLED; + mac_cfg.txpause = ENABLED; + mac_cfg.rxpause = ENABLED; + rtk_port_macForceLinkExt_set(EXT_PORT1, mode, &mac_cfg); + rtk_port_rgmiiDelayExt_set(EXT_PORT1, 1, 3); + rtk_port_phyEnableAll_set(ENABLED); + +} + +void init_gsw(void) +{ + rtl8367s_hw_init(); + set_rtl8367s_sgmii(); + set_rtl8367s_rgmii(); +} + +// bleow are platform driver +static const struct of_device_id rtk_gsw_match[] = { + { .compatible = "mediatek,rtk-gsw" }, + {}, +}; + +MODULE_DEVICE_TABLE(of, rtk_gsw_match); + +static int rtk_gsw_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device_node *mdio; + struct mii_bus *mdio_bus; + struct rtk_gsw *gsw; + const char *pm; + + mdio = of_parse_phandle(np, "mediatek,mdio", 0); + + if (!mdio) + return -EINVAL; + + mdio_bus = of_mdio_find_bus(mdio); + + if (!mdio_bus) + return -EPROBE_DEFER; + + gsw = devm_kzalloc(&pdev->dev, sizeof(struct rtk_gsw), GFP_KERNEL); + + if (!gsw) + return -ENOMEM; + + gsw->dev = &pdev->dev; + + gsw->bus = mdio_bus; + + gsw->reset_pin = of_get_named_gpio(np, "mediatek,reset-pin", 0); + + _gsw = gsw; + + init_gsw(); + + //init default vlan or init swocnfig + if(!of_property_read_string(pdev->dev.of_node, + "mediatek,port_map", &pm)) { + + if (!strcasecmp(pm, "wllll")) + rtl8367s_vlan_config(1); + else + rtl8367s_vlan_config(0); + + } else { +#ifdef CONFIG_SWCONFIG + rtl8367s_swconfig_init(&init_gsw); +#else + rtl8367s_vlan_config(0); +#endif + } + + gsw_debug_proc_init(); + + platform_set_drvdata(pdev, gsw); + + return 0; + +} + +static int rtk_gsw_remove(struct platform_device *pdev) +{ + platform_set_drvdata(pdev, NULL); + gsw_debug_proc_exit(); + + return 0; +} + +static struct platform_driver gsw_driver = { + .probe = rtk_gsw_probe, + .remove = rtk_gsw_remove, + .driver = { + .name = "rtk-gsw", + .owner = THIS_MODULE, + .of_match_table = rtk_gsw_match, + }, +}; + +module_platform_driver(gsw_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mark Lee "); +MODULE_DESCRIPTION("rtl8367c switch driver for MT7622"); + diff --git a/root/target/linux/mediatek/image/mt7622.mk b/root/target/linux/mediatek/image/mt7622.mk new file mode 100755 index 00000000..4d325e64 --- /dev/null +++ b/root/target/linux/mediatek/image/mt7622.mk @@ -0,0 +1,290 @@ +DTS_DIR := $(DTS_DIR)/mediatek + +ifdef CONFIG_LINUX_5_4 + KERNEL_LOADADDR := 0x44080000 +else + KERNEL_LOADADDR := 0x44000000 +endif + +define Image/Prepare + # For UBI we want only one extra block + rm -f $(KDIR)/ubi_mark + echo -ne '\xde\xad\xc0\xde' > $(KDIR)/ubi_mark +endef + +define Build/append-image + cp "$(BIN_DIR)/$(IMG_PREFIX)-$(DEVICE_NAME)-$(1)" "$@.stripmeta" + fwtool -s /dev/null -t "$@.stripmeta" || : + fwtool -i /dev/null -t "$@.stripmeta" || : + dd if="$@.stripmeta" >> "$@" + rm "$@.stripmeta" +endef + +define Build/append-image-stage + cp "$(BIN_DIR)/$(IMG_PREFIX)-$(DEVICE_NAME)-$(1)" "$@.stripmeta" + fwtool -s /dev/null -t "$@.stripmeta" || : + fwtool -i /dev/null -t "$@.stripmeta" || : + dd if="$@.stripmeta" of="$(STAGING_DIR_IMAGE)/$(BOARD)$(if $(SUBTARGET),-$(SUBTARGET))-$(DEVICE_NAME)-$(1)" + dd if="$@.stripmeta" >> "$@" + rm "$@.stripmeta" +endef + +define Build/buffalo-kernel-trx + $(eval magic=$(word 1,$(1))) + $(eval dummy=$(word 2,$(1))) + $(eval kern_size=$(if $(KERNEL_SIZE),$(KERNEL_SIZE),0x400000)) + + $(if $(dummy),touch $(dummy)) + $(STAGING_DIR_HOST)/bin/otrx create $@.new \ + $(if $(magic),-M $(magic),) \ + -f $@ \ + $(if $(dummy),\ + -a 0x20000 \ + -b $$(( $(subst k, * 1024,$(kern_size)) )) \ + -f $(dummy),) + mv $@.new $@ +endef + +define Build/bl2 + cat $(STAGING_DIR_IMAGE)/mt7622-$1-bl2.img >> $@ +endef + +define Build/bl31-uboot + cat $(STAGING_DIR_IMAGE)/mt7622_$1-u-boot.fip >> $@ +endef + +define Build/mt7622-gpt + cp $@ $@.tmp 2>/dev/null || true + ptgen -g -o $@.tmp -a 1 -l 1024 \ + $(if $(findstring sdmmc,$1), \ + -H \ + -t 0x83 -N bl2 -r -p 512k@512k \ + ) \ + -t 0xef -N fip -r -p 2M@2M \ + -t 0x83 -N ubootenv -r -p 1M@4M \ + -N recovery -r -p 32M@6M \ + $(if $(findstring sdmmc,$1), \ + -N install -r -p 7M@38M \ + -t 0x2e -N production -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)M@45M \ + ) \ + $(if $(findstring emmc,$1), \ + -t 0x2e -N production -p $(CONFIG_TARGET_ROOTFS_PARTSIZE)M@40M \ + ) + cat $@.tmp >> $@ + rm $@.tmp +# 208 +# 976 +endef + +define Build/trx-nand + # kernel: always use 4 MiB (-28 B or TRX header) to allow upgrades even + # if it grows up between releases + # root: UBI with one extra block containing UBI mark to trigger erasing + # rest of partition + $(STAGING_DIR_HOST)/bin/otrx create $@.new \ + -M 0x32504844 \ + -f $(IMAGE_KERNEL) -a 0x20000 -b 0x400000 \ + -f $@ \ + -A $(KDIR)/ubi_mark -a 0x20000 + mv $@.new $@ +endef + +define Device/bananapi_bpi-r64 + DEVICE_VENDOR := Bananapi + DEVICE_MODEL := BPi-R64 + DEVICE_DTS := mt7622-bananapi-bpi-r64 + DEVICE_DTS_OVERLAY := mt7622-bananapi-bpi-r64-pcie1 mt7622-bananapi-bpi-r64-sata + DEVICE_PACKAGES := kmod-ata-ahci-mtk kmod-btmtkuart kmod-usb3 e2fsprogs mkf2fs f2fsck + ARTIFACTS := emmc-preloader.bin emmc-bl31-uboot.fip sdcard.img.gz snand-preloader.bin snand-bl31-uboot.fip + IMAGES := sysupgrade.itb + KERNEL_INITRAMFS_SUFFIX := -recovery.itb + ARTIFACT/emmc-preloader.bin := bl2 emmc-2ddr + ARTIFACT/emmc-bl31-uboot.fip := bl31-uboot bananapi_bpi-r64-emmc + ARTIFACT/snand-preloader.bin := bl2 snand-2ddr + ARTIFACT/snand-bl31-uboot.fip := bl31-uboot bananapi_bpi-r64-snand + ARTIFACT/sdcard.img.gz := mt7622-gpt sdmmc |\ + pad-to 512k | bl2 sdmmc-2ddr |\ + pad-to 2048k | bl31-uboot bananapi_bpi-r64-sdmmc |\ + pad-to 6144k | append-image-stage initramfs-recovery.itb |\ + pad-to 38912k | mt7622-gpt emmc |\ + pad-to 39424k | bl2 emmc-2ddr |\ + pad-to 40960k | bl31-uboot bananapi_bpi-r64-emmc |\ + pad-to 43008k | bl2 snand-2ddr |\ + pad-to 43520k | bl31-uboot bananapi_bpi-r64-snand |\ + pad-to 46080k | append-image squashfs-sysupgrade.itb | gzip + KERNEL := kernel-bin | gzip + KERNEL_INITRAMFS := kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb with-initrd | pad-to 128k + IMAGE/sysupgrade.itb := append-kernel | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb external-static-with-rootfs | append-metadata +endef +TARGET_DEVICES += bananapi_bpi-r64 + +define Device/buffalo_wsr-2533dhp2 + DEVICE_VENDOR := Buffalo + DEVICE_MODEL := WSR-2533DHP2 + DEVICE_DTS := mt7622-buffalo-wsr-2533dhp2 + DEVICE_DTS_DIR := ../dts + IMAGE_SIZE := 59392k + KERNEL_SIZE := 4096k + BLOCKSIZE := 128k + PAGESIZE := 2048 + SUBPAGESIZE := 512 + UBINIZE_OPTS := -E 5 + BUFFALO_TAG_PLATFORM := MTK + BUFFALO_TAG_VERSION := 9.99 + BUFFALO_TAG_MINOR := 9.99 + IMAGES += factory.bin factory-uboot.bin + KERNEL_INITRAMFS := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | \ + buffalo-kernel-trx + IMAGE/factory.bin := append-ubi | trx-nand | \ + buffalo-enc WSR-2533DHP2 $$(BUFFALO_TAG_VERSION) -l | \ + buffalo-tag-dhp WSR-2533DHP2 JP JP | buffalo-enc-tag -l | buffalo-dhp-image + IMAGE/factory-uboot.bin := append-ubi | trx-nand + IMAGE/sysupgrade.bin := append-kernel | \ + buffalo-kernel-trx 0x32504844 $(KDIR)/tmp/$$(DEVICE_NAME).null | \ + sysupgrade-tar kernel=$$$$@ | append-metadata + DEVICE_PACKAGES := swconfig +endef +TARGET_DEVICES += buffalo_wsr-2533dhp2 + +define Device/elecom_wrc-2533gent + DEVICE_VENDOR := Elecom + DEVICE_MODEL := WRC-2533GENT + DEVICE_DTS := mt7622-elecom-wrc-2533gent + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-btmtkuart kmod-usb3 swconfig +endef +TARGET_DEVICES += elecom_wrc-2533gent + +define Device/linksys_e8450 + DEVICE_VENDOR := Linksys + DEVICE_MODEL := E8450 + DEVICE_ALT0_VENDOR := Belkin + DEVICE_ALT0_MODEL := RT3200 + DEVICE_DTS := mt7622-linksys-e8450 + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-mt7915e kmod-usb3 +endef +TARGET_DEVICES += linksys_e8450 + +define Device/linksys_e8450-ubi + DEVICE_VENDOR := Linksys + DEVICE_MODEL := E8450 + DEVICE_VARIANT := UBI + DEVICE_ALT0_VENDOR := Belkin + DEVICE_ALT0_MODEL := RT3200 + DEVICE_ALT0_VARIANT := UBI + DEVICE_DTS := mt7622-linksys-e8450-ubi + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-mt7915e kmod-usb3 + UBINIZE_OPTS := -E 5 + BLOCKSIZE := 128k + PAGESIZE := 2048 + UBOOTENV_IN_UBI := 1 + KERNEL_IN_UBI := 1 + KERNEL := kernel-bin | gzip +# recovery can also be used with stock firmware web-ui, hence the padding... + KERNEL_INITRAMFS := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 128k + KERNEL_INITRAMFS_SUFFIX := -recovery.itb + IMAGES := sysupgrade.itb + IMAGE/sysupgrade.itb := append-kernel | fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb external-static-with-rootfs | append-metadata + ARTIFACTS := preloader.bin bl31-uboot.fip + ARTIFACT/preloader.bin := bl2 snand-1ddr + ARTIFACT/bl31-uboot.fip := bl31-uboot linksys_e8450 +endef +TARGET_DEVICES += linksys_e8450-ubi + +define Device/mediatek_mt7622-rfb1 + DEVICE_VENDOR := MediaTek + DEVICE_MODEL := MTK7622 rfb1 AP + DEVICE_DTS := mt7622-rfb1 + DEVICE_PACKAGES := kmod-ata-ahci-mtk kmod-btmtkuart kmod-usb3 +endef +TARGET_DEVICES += mediatek_mt7622-rfb1 + +define Device/mediatek_mt7622-rfb1-ubi + DEVICE_VENDOR := MediaTek + DEVICE_MODEL := MTK7622 rfb1 AP (UBI) + DEVICE_DTS := mt7622-rfb1-ubi + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-ata-ahci-mtk kmod-btmtkuart kmod-usb3 + BOARD_NAME := mediatek,mt7622-rfb1-ubi + UBINIZE_OPTS := -E 5 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 4194304 + IMAGE_SIZE := 32768k + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \ + check-size $$$$(IMAGE_SIZE) + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +endef +TARGET_DEVICES += mediatek_mt7622-rfb1-ubi + +define Device/ruijie_rg-ew3200gx-pro + DEVICE_VENDOR := Ruijie + DEVICE_MODEL := RG-EW3200GX PRO + DEVICE_DTS := mt7622-ruijie-rg-ew3200gx-pro + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-mt7915e +endef +TARGET_DEVICES += ruijie_rg-ew3200gx-pro + +define Device/totolink_a8000ru + DEVICE_VENDOR := TOTOLINK + DEVICE_MODEL := A8000RU + DEVICE_DTS := mt7622-totolink-a8000ru + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := swconfig + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +endef +TARGET_DEVICES += totolink_a8000ru + +define Device/ubnt_unifi-6-lr + DEVICE_VENDOR := Ubiquiti + DEVICE_MODEL := UniFi 6 LR + DEVICE_DTS_CONFIG := config@1 + DEVICE_DTS := mt7622-ubnt-unifi-6-lr + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-mt7915e kmod-leds-ubnt-ledbar +endef +TARGET_DEVICES += ubnt_unifi-6-lr + +define Device/ubnt_unifi-6-lr-ubootmod + DEVICE_VENDOR := Ubiquiti + DEVICE_MODEL := UniFi 6 LR + DEVICE_VARIANT := U-Boot mod + DEVICE_DTS := mt7622-ubnt-unifi-6-lr-ubootmod + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-mt7915e kmod-leds-ubnt-ledbar + KERNEL := kernel-bin | lzma + KERNEL_INITRAMFS_SUFFIX := -recovery.itb + KERNEL_INITRAMFS := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k + IMAGES := sysupgrade.itb + IMAGE/sysupgrade.itb := append-kernel | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb external-static-with-rootfs | pad-rootfs | append-metadata + ARTIFACTS := preloader.bin bl31-uboot.fip + ARTIFACT/preloader.bin := bl2 nor-2ddr + ARTIFACT/bl31-uboot.fip := bl31-uboot ubnt_unifi-6-lr +endef +TARGET_DEVICES += ubnt_unifi-6-lr-ubootmod + +define Device/xiaomi_redmi-router-ax6s + DEVICE_VENDOR := Xiaomi + DEVICE_MODEL := Redmi Router AX6S + DEVICE_ALT0_VENDOR := Xiaomi + DEVICE_ALT0_MODEL := Router AX3200 + DEVICE_DTS := mt7622-xiaomi-redmi-router-ax6s + DEVICE_DTS_DIR := ../dts + BOARD_NAME := xiaomi,redmi-router-ax6s + DEVICE_PACKAGES := kmod-mt7915e + UBINIZE_OPTS := -E 5 + IMAGES += factory.bin + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 4096k + KERNEL_INITRAMFS_SUFFIX := -recovery.itb + IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +endef +TARGET_DEVICES += xiaomi_redmi-router-ax6s diff --git a/root/target/linux/mediatek/modules.mk b/root/target/linux/mediatek/modules.mk new file mode 100755 index 00000000..eb81afe2 --- /dev/null +++ b/root/target/linux/mediatek/modules.mk @@ -0,0 +1,51 @@ +define KernelPackage/ata-ahci-mtk + TITLE:=Mediatek AHCI Serial ATA support + KCONFIG:=CONFIG_AHCI_MTK + FILES:= \ + $(LINUX_DIR)/drivers/ata/ahci_mtk.ko \ + $(LINUX_DIR)/drivers/ata/libahci_platform.ko + AUTOLOAD:=$(call AutoLoad,40,libahci libahci_platform ahci_mtk,1) + $(call AddDepends/ata) + DEPENDS+=@(TARGET_mediatek_mt7622||TARGET_mediatek_mt7623) +endef + +define KernelPackage/ata-ahci-mtk/description + Mediatek AHCI Serial ATA host controllers +endef + +$(eval $(call KernelPackage,ata-ahci-mtk)) + +define KernelPackage/sdhci-mtk + SUBMENU:=Other modules + TITLE:=Mediatek SDHCI driver + DEPENDS:=@TARGET_mediatek_mt7622 +kmod-sdhci + KCONFIG:=CONFIG_MMC_MTK + FILES:= \ + $(LINUX_DIR)/drivers/mmc/host/mtk-sd.ko + AUTOLOAD:=$(call AutoProbe,mtk-sd,1) +endef + +$(eval $(call KernelPackage,sdhci-mtk)) + +define KernelPackage/crypto-hw-mtk + TITLE:= MediaTek's Crypto Engine module + DEPENDS:=@TARGET_mediatek + KCONFIG:= \ + CONFIG_CRYPTO_HW=y \ + CONFIG_CRYPTO_AES=y \ + CONFIG_CRYPTO_AEAD=y \ + CONFIG_CRYPTO_SHA1=y \ + CONFIG_CRYPTO_SHA256=y \ + CONFIG_CRYPTO_SHA512=y \ + CONFIG_CRYPTO_HMAC=y \ + CONFIG_CRYPTO_DEV_MEDIATEK + FILES:=$(LINUX_DIR)/drivers/crypto/mediatek/mtk-crypto.ko + AUTOLOAD:=$(call AutoLoad,90,mtk-crypto) + $(call AddDepends/crypto) +endef + +define KernelPackage/crypto-hw-mtk/description + MediaTek's EIP97 Cryptographic Engine driver. +endef + +$(eval $(call KernelPackage,crypto-hw-mtk)) diff --git a/root/target/linux/mediatek/mt7622/config-5.14 b/root/target/linux/mediatek/mt7622/config-5.14 new file mode 100755 index 00000000..bf40fe39 --- /dev/null +++ b/root/target/linux/mediatek/mt7622/config-5.14 @@ -0,0 +1,465 @@ +CONFIG_64BIT=y +# CONFIG_AHCI_MTK is not set +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_STACKWALK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM64=y +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_CNP is not set +# CONFIG_ARM64_ERRATUM_1165522 is not set +# CONFIG_ARM64_ERRATUM_1286807 is not set +# CONFIG_ARM64_ERRATUM_1418040 is not set +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_MODULE_PLTS=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_PA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +# CONFIG_ARM64_PTR_AUTH is not set +# CONFIG_ARM64_SVE is not set +# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_ARM64_VA_BITS=39 +CONFIG_ARM64_VA_BITS_39=y +# CONFIG_ARMV8_DEPRECATED is not set +CONFIG_ARM_AMBA=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_GIC_V3_ITS_PCI=y +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PMU=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ATA=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2712=y +# CONFIG_COMMON_CLK_MT2712_BDPSYS is not set +# CONFIG_COMMON_CLK_MT2712_IMGSYS is not set +# CONFIG_COMMON_CLK_MT2712_JPGDECSYS is not set +# CONFIG_COMMON_CLK_MT2712_MFGCFG is not set +# CONFIG_COMMON_CLK_MT2712_MMSYS is not set +# CONFIG_COMMON_CLK_MT2712_VDECSYS is not set +# CONFIG_COMMON_CLK_MT2712_VENCSYS is not set +# CONFIG_COMMON_CLK_MT6779 is not set +# CONFIG_COMMON_CLK_MT6797 is not set +CONFIG_COMMON_CLK_MT7622=y +CONFIG_COMMON_CLK_MT7622_AUDSYS=y +CONFIG_COMMON_CLK_MT7622_ETHSYS=y +CONFIG_COMMON_CLK_MT7622_HIFSYS=y +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8183=y +# CONFIG_COMMON_CLK_MT8183_AUDIOSYS is not set +# CONFIG_COMMON_CLK_MT8183_CAMSYS is not set +# CONFIG_COMMON_CLK_MT8183_IMGSYS is not set +# CONFIG_COMMON_CLK_MT8183_IPU_ADL is not set +# CONFIG_COMMON_CLK_MT8183_IPU_CONN is not set +# CONFIG_COMMON_CLK_MT8183_IPU_CORE0 is not set +# CONFIG_COMMON_CLK_MT8183_IPU_CORE1 is not set +# CONFIG_COMMON_CLK_MT8183_MFGCFG is not set +# CONFIG_COMMON_CLK_MT8183_MMSYS is not set +# CONFIG_COMMON_CLK_MT8183_VDECSYS is not set +# CONFIG_COMMON_CLK_MT8183_VENCSYS is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_THERMAL=y +CONFIG_CRC16=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KPP=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_MISC=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DIMLIB=y +CONFIG_DMADEVICES=y +CONFIG_DMATEST=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_ENGINE_RAID=y +CONFIG_DMA_OF=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DTC=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_EXT4_FS=y +CONFIG_F2FS_FS=y +CONFIG_FIT_PARTITION=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FRAME_POINTER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +# CONFIG_FUJITSU_ERRATUM_010001 is not set +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GLOB=y +CONFIG_GPIOLIB=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HOLES_IN_ZONE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MT65XX=y +CONFIG_ICPLUS_PHY=y +CONFIG_IIO=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_JUMP_LABEL=y +# CONFIG_KEYBOARD_MTK_PMIC is not set +CONFIG_LEDS_UBNT_LEDBAR=y +CONFIG_LIBFDT=y +CONFIG_LLD_VERSION=0 +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_MTK=y +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_MTK=y +CONFIG_MTD_NAND_MTK_BMT=y +CONFIG_MTD_PARSER_TRX=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +# CONFIG_MTK_CMDQ is not set +# CONFIG_MTK_CQDMA is not set +CONFIG_MTK_EFUSE=y +CONFIG_MTK_HSDMA=y +CONFIG_MTK_INFRACFG=y +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_SPI_NAND=y +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +# CONFIG_MTK_UART_APDMA is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_VENDOR_MEDIATEK=y +CONFIG_NLS=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=2 +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PARTITION_PERCPU=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEFAULT is not set +CONFIG_PCIEASPM_PERFORMANCE=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DEBUG=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_EVENTS=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_MT2712 is not set +# CONFIG_PINCTRL_MT6765 is not set +# CONFIG_PINCTRL_MT6797 is not set +CONFIG_PINCTRL_MT7622=y +# CONFIG_PINCTRL_MT8173 is not set +# CONFIG_PINCTRL_MT8183 is not set +CONFIG_PINCTRL_MT8516=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PINCTRL_MTK_V2=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_OPP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_SUPPLY=y +CONFIG_PRINTK_TIME=y +CONFIG_PSTORE=y +# CONFIG_PSTORE_842_COMPRESS is not set +# CONFIG_PSTORE_BLK is not set +CONFIG_PSTORE_COMPRESS=y +CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_DEFLATE_COMPRESS=y +CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y +# CONFIG_PSTORE_LZ4HC_COMPRESS is not set +# CONFIG_PSTORE_LZ4_COMPRESS is not set +# CONFIG_PSTORE_LZO_COMPRESS is not set +CONFIG_PSTORE_PMSG=y +CONFIG_PSTORE_RAM=y +# CONFIG_PSTORE_ZSTD_COMPRESS is not set +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +# CONFIG_RAVE_SP_CORE is not set +CONFIG_REALTEK_PHY=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MT6380=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MT7622=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTL8367S_GSW=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SCSI=y +# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SGL_ALLOC=y +CONFIG_SG_POOL=y +CONFIG_SMP=y +# CONFIG_SND_SOC_MT6359 is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +CONFIG_SPI_MTK_NOR=y +CONFIG_SPI_MTK_SNFI=y +CONFIG_SRCU=y +CONFIG_SWCONFIG=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_EMULATION=y +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +# CONFIG_UCLAMP_TASK is not set +# CONFIG_UNMAP_KERNEL_AT_EL0 is not set +CONFIG_USB=y +CONFIG_USB_COMMON=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +# CONFIG_USB_XHCI_PLATFORM is not set +CONFIG_VMAP_STACK=y +CONFIG_WATCHDOG_CORE=y +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV=y +# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set +CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m +CONFIG_WATCHDOG_SYSFS=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA32=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/root/target/linux/mediatek/mt7622/config-5.4 b/root/target/linux/mediatek/mt7622/config-5.4 new file mode 100755 index 00000000..60dd7019 --- /dev/null +++ b/root/target/linux/mediatek/mt7622/config-5.4 @@ -0,0 +1,476 @@ +CONFIG_64BIT=y +CONFIG_AHCI_MTK=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM64=y +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_CNP is not set +CONFIG_ARM64_CONT_SHIFT=4 +# CONFIG_ARM64_ERRATUM_1165522 is not set +# CONFIG_ARM64_ERRATUM_1286807 is not set +# CONFIG_ARM64_ERRATUM_1418040 is not set +CONFIG_ARM64_ERRATUM_1542419=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_MODULE_PLTS=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_PA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +# CONFIG_ARM64_PTR_AUTH is not set +CONFIG_ARM64_SSBD=y +# CONFIG_ARM64_SVE is not set +# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_ARM64_VA_BITS=39 +CONFIG_ARM64_VA_BITS_39=y +# CONFIG_ARMV8_DEPRECATED is not set +CONFIG_ARM_AMBA=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_GIC_V3_ITS_PCI=y +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PMU=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ATA=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2712=y +# CONFIG_COMMON_CLK_MT2712_BDPSYS is not set +# CONFIG_COMMON_CLK_MT2712_IMGSYS is not set +# CONFIG_COMMON_CLK_MT2712_JPGDECSYS is not set +# CONFIG_COMMON_CLK_MT2712_MFGCFG is not set +# CONFIG_COMMON_CLK_MT2712_MMSYS is not set +# CONFIG_COMMON_CLK_MT2712_VDECSYS is not set +# CONFIG_COMMON_CLK_MT2712_VENCSYS is not set +# CONFIG_COMMON_CLK_MT6779 is not set +# CONFIG_COMMON_CLK_MT6797 is not set +CONFIG_COMMON_CLK_MT7622=y +CONFIG_COMMON_CLK_MT7622_AUDSYS=y +CONFIG_COMMON_CLK_MT7622_ETHSYS=y +CONFIG_COMMON_CLK_MT7622_HIFSYS=y +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8183=y +# CONFIG_COMMON_CLK_MT8183_AUDIOSYS is not set +# CONFIG_COMMON_CLK_MT8183_CAMSYS is not set +# CONFIG_COMMON_CLK_MT8183_IMGSYS is not set +# CONFIG_COMMON_CLK_MT8183_IPU_ADL is not set +# CONFIG_COMMON_CLK_MT8183_IPU_CONN is not set +# CONFIG_COMMON_CLK_MT8183_IPU_CORE0 is not set +# CONFIG_COMMON_CLK_MT8183_IPU_CORE1 is not set +# CONFIG_COMMON_CLK_MT8183_MFGCFG is not set +# CONFIG_COMMON_CLK_MT8183_MMSYS is not set +# CONFIG_COMMON_CLK_MT8183_VDECSYS is not set +# CONFIG_COMMON_CLK_MT8183_VENCSYS is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_THERMAL=y +CONFIG_CRC16=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +# CONFIG_CRYPTO_BLAKE2S is not set +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CURVE25519 is not set +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KPP=y +CONFIG_CRYPTO_KPP2=y +# CONFIG_CRYPTO_LIB_BLAKE2S is not set +# CONFIG_CRYPTO_LIB_CHACHA is not set +# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set +# CONFIG_CRYPTO_LIB_CURVE25519 is not set +# CONFIG_CRYPTO_LIB_POLY1305 is not set +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_MISC=y +CONFIG_DEFAULT_MPTCP_PM="fullmesh" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DIMLIB=y +CONFIG_DMADEVICES=y +CONFIG_DMATEST=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_ENGINE_RAID=y +CONFIG_DMA_OF=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DRM_RCAR_WRITEBACK=y +CONFIG_DTC=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_EDAC_SUPPORT=y +# CONFIG_EFI_PARTITION is not set +CONFIG_EINT_MTK=y +CONFIG_EXT4_FS=y +CONFIG_F2FS_FS=y +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_FIT_PARTITION is not set +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FRAME_POINTER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +# CONFIG_FUJITSU_ERRATUM_010001 is not set +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GLOB=y +CONFIG_GPIOLIB=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HOLES_IN_ZONE=y +CONFIG_HZ=250 +CONFIG_HZ_250=y +CONFIG_ICPLUS_PHY=y +CONFIG_IIO=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_IONIC is not set +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_JUMP_LABEL=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +# CONFIG_MIKROTIK is not set +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_MTK=y +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_MODULES_USE_ELF_RELA=y +# CONFIG_MT753X_GSW is not set +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_MTK=y +CONFIG_MTD_NAND_MTK_BMT=y +CONFIG_MTD_RAW_NAND=y +# CONFIG_MTD_ROUTERBOOT_PARTS is not set +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPLIT_BCM63XX_FW is not set +# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set +# CONFIG_MTD_SPLIT_ELF_FW is not set +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +# CONFIG_MTK_CMDQ is not set +# CONFIG_MTK_CQDMA is not set +CONFIG_MTK_EFUSE=y +CONFIG_MTK_HSDMA=y +CONFIG_MTK_INFRACFG=y +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +# CONFIG_MTK_UART_APDMA is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +# CONFIG_NET_DSA_TAG_RTL4_A is not set +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_VENDOR_MEDIATEK=y +CONFIG_NLS=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=2 +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +# CONFIG_OCTEONTX2_AF is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PARTITION_PERCPU=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +# CONFIG_PCIEASPM_DEFAULT is not set +CONFIG_PCIEASPM_PERFORMANCE=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +CONFIG_PCIEPORTBUS=y +# CONFIG_PCIE_AL is not set +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DEBUG=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_EVENTS=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_MT2712 is not set +# CONFIG_PINCTRL_MT6765 is not set +# CONFIG_PINCTRL_MT6797 is not set +CONFIG_PINCTRL_MT7622=y +# CONFIG_PINCTRL_MT8173 is not set +# CONFIG_PINCTRL_MT8183 is not set +CONFIG_PINCTRL_MT8516=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_OPP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_SUPPLY=y +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +# CONFIG_RAVE_SP_CORE is not set +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_REALTEK_PHY=y +CONFIG_REFCOUNT_FULL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MT6380=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MT7622=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTL8367S_GSW=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SCSI=y +# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SGL_ALLOC=y +CONFIG_SG_POOL=y +CONFIG_SMP=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +CONFIG_SPI_MTK_NOR=y +CONFIG_SPI_MTK_SNFI=y +CONFIG_SRCU=y +CONFIG_SWCONFIG=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +# CONFIG_TCP_CONG_BBR2 is not set +# CONFIG_TCP_CONG_NANQINLANG is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_EMULATION=y +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_ZSTD=y +# CONFIG_UCLAMP_TASK is not set +# CONFIG_UNMAP_KERNEL_AT_EL0 is not set +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +# CONFIG_USB_XHCI_PLATFORM is not set +CONFIG_VMAP_STACK=y +CONFIG_WATCHDOG_CORE=y +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV=y +# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set +CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m +CONFIG_WATCHDOG_SYSFS=y +# CONFIG_WIREGUARD is not set +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA32=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/root/target/linux/mediatek/mt7622/target.mk b/root/target/linux/mediatek/mt7622/target.mk new file mode 100755 index 00000000..5403bf5f --- /dev/null +++ b/root/target/linux/mediatek/mt7622/target.mk @@ -0,0 +1,10 @@ +ARCH:=aarch64 +SUBTARGET:=mt7622 +BOARDNAME:=MT7622 +CPU_TYPE:=cortex-a53 +DEFAULT_PACKAGES += kmod-mt7615e kmod-mt7615-firmware wpad-basic-wolfssl blockdev uboot-envtools +KERNELNAME:=Image dtbs + +define Target/Description + Build firmware images for MediaTek MT7622 ARM based boards. +endef diff --git a/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network b/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network new file mode 100755 index 00000000..a162e373 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network @@ -0,0 +1,36 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +mediatek_setup_interfaces() +{ + local board="$1" + + case $board in + bananapi,bpi-r2|\ + unielec,u7623-02-emmc-512m) + ucidef_set_interfaces_lan_wan "wan1 wan2 wan3 wan4" "lan" + ;; + esac +} + +mediatek_setup_macs() +{ + local board="$1" + + case $board in + unielec,u7623-02-emmc-512m) + ucidef_set_interface_macaddr "lan" "$(cat /sys/class/net/lan/address)" + ;; + esac +} + +board_config_update +board=$(board_name) +mediatek_setup_interfaces $board +mediatek_setup_macs $board +board_config_flush + +exit 0 diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac new file mode 100755 index 00000000..8141c3db --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac @@ -0,0 +1,47 @@ +#!/bin/sh +# Copyright (C) 2018 OpenWrt.org + +RECOVERY_PART=/dev/mmcblk0p1 + +preinit_set_mac_address() { + local mac + + . /lib/functions.sh + . /lib/functions/system.sh + + case $(board_name) in + unielec,u7623-02-emmc-512m) + if [ -b $RECOVERY_PART ]; then + insmod nls_cp437 + insmod nls_iso8859-1 + insmod fat + insmod vfat + mkdir -p /tmp/recovery + mount -o rw,noatime $RECOVERY_PART /tmp/recovery + + if [ -f "/tmp/recovery/mac_addr" ]; + then + mac=$(cat /tmp/recovery/mac_addr) + else + mac=$(cat /sys/class/net/eth0/address) + echo "$mac" > /tmp/recovery/mac_addr + fi + + sync + umount /tmp/recovery + rm -rf /tmp/recovery + fi + + ip link set dev lan address $mac 2> /dev/null + + mac=$(macaddr_add $mac 1) + + ip link set dev wan1 address $mac 2>/dev/null + ip link set dev wan2 address $mac 2>/dev/null + ip link set dev wan3 address $mac 2>/dev/null + ip link set dev wan4 address $mac 2>/dev/null + ;; + esac +} + +boot_hook_add preinit_main preinit_set_mac_address diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config new file mode 100755 index 00000000..4be18114 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (C) 2012-2015 OpenWrt.org + +move_config() { + local partdev + + . /lib/upgrade/common.sh + + if export_bootdevice && export_partdevice partdev -1; then + if mount -t vfat -o rw,noatime "/dev/$partdev" /mnt; then + if [ -f /mnt/sysupgrade.tgz ]; then + mv -f /mnt/sysupgrade.tgz / + fi + umount /mnt + fi + fi +} + +boot_hook_add preinit_mount_root move_config diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh b/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh new file mode 100755 index 00000000..f117f98c --- /dev/null +++ b/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh @@ -0,0 +1,154 @@ +platform_do_upgrade() { + local board=$(board_name) + + case "$board" in + unielec,u7623-02-emmc-512m) + #Keep the persisten random mac address (if it exists) + mkdir -p /tmp/recovery + mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery + [ -f "/tmp/recovery/mac_addr" ] && \ + mv -f /tmp/recovery/mac_addr /tmp/ + umount /tmp/recovery + + #1310720 is the offset in bytes from the start of eMMC and to + #the location of the kernel (2560 512 byte sectors) + get_image "$1" | dd of=/dev/mmcblk0 bs=1310720 seek=1 conv=fsync + + mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery + [ -f "/tmp/mac_addr" ] && mv -f /tmp/mac_addr /tmp/recovery + sync + umount /tmp/recovery + ;; + bananapi,bpi-r2) + local diskdev partdev diff + + export_bootdevice && export_partdevice diskdev -2 || { + echo "Unable to determine upgrade device" + return 1 + } + + sync + + if [ "$SAVE_PARTITIONS" = "1" ]; then + get_partitions "/dev/$diskdev" bootdisk + + #extract the boot sector from the image + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b + + get_partitions /tmp/image.bs image + + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + else + diff=1 + fi + + if [ -n "$diff" ]; then + get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync + + # Separate removal and addtion is necessary; otherwise, partition 1 + # will be missing if it overlaps with the old partition 2 + partx -d - "/dev/$diskdev" + partx -a - "/dev/$diskdev" + + return 0 + fi + + #write uboot image + get_image "$@" | dd of="$diskdev" bs=1024 skip=320 seek=320 count=700 conv=fsync + #iterate over each partition from the image and write it to the boot disk + while read part start size; do + part="$(($part - 2))" + if export_partdevice partdev $part; then + echo "Writing image to /dev/$partdev..." + get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync + else + echo "Unable to find partition $part device, skipped." + fi + done < /tmp/partmap.image + + #copy partition uuid + echo "Writing new UUID to /dev/$diskdev..." + get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync + ;; + *) + default_do_upgrade "$1" + ;; + esac +} + +PART_NAME=firmware + +platform_check_image() { + local board=$(board_name) + local magic="$(get_magic_long "$1")" + + [ "$#" -gt 1 ] && return 1 + + case "$board" in + unielec,u7623-02-emmc-512m) + [ "$magic" != "27051956" ] && { + echo "Invalid image type." + return 1 + } + return 0 + ;; + bananapi,bpi-r2) + local diskdev partdev diff + + export_bootdevice && export_partdevice diskdev -2 || { + echo "Unable to determine upgrade device" + return 1 + } + + get_partitions "/dev/$diskdev" bootdisk + + #extract the boot sector from the image + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null + + get_partitions /tmp/image.bs image + + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + + rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image + + if [ -n "$diff" ]; then + echo "Partition layout has changed. Full image will be written." + ask_bool 0 "Abort" && exit 1 + return 0 + fi + ;; + *) + echo "Sysupgrade is not supported on your board yet." + return 1 + ;; + esac + + return 0 +} + +platform_copy_config_emmc() { + mkdir -p /recovery + mount -o rw,noatime /dev/mmcblk0p1 /recovery + cp -af "$UPGRADE_BACKUP" "/recovery/$BACKUP_FILE" + sync + umount /recovery +} + +platform_copy_config() { + case "$(board_name)" in + unielec,u7623-02-emmc-512m) + platform_copy_config_emmc + ;; + bananapi,bpi-r2) + local partdev + + if export_partdevice partdev -1; then + mount -t vfat -o rw,noatime "/dev/$partdev" /mnt + cp -af "$CONF_TAR" /mnt/ + umount /mnt + fi + ;; + esac +} diff --git a/root/target/linux/mediatek/mt7623/config-4.14 b/root/target/linux/mediatek/mt7623/config-4.14 new file mode 100755 index 00000000..07f6b76d --- /dev/null +++ b/root/target/linux/mediatek/mt7623/config-4.14 @@ -0,0 +1,570 @@ +# CONFIG_AIO is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_MULTI_CPU_AUTO is not set +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +# CONFIG_ARCH_WANTS_THP_SWAP is not set +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND=y +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +# CONFIG_ARM_LPAE is not set +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ATAGS=y +CONFIG_ATAGS_PROC=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_NONE is not set +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_CFG80211=m +CONFIG_CFG80211_CRDA_SUPPORT=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +# CONFIG_CFG80211_WEXT is not set +CONFIG_CLEANCACHE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 vmalloc=256M" +CONFIG_CMDLINE_EXTEND=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2701=y +CONFIG_COMMON_CLK_MT2701_BDPSYS=y +CONFIG_COMMON_CLK_MT2701_ETHSYS=y +CONFIG_COMMON_CLK_MT2701_HIFSYS=y +CONFIG_COMMON_CLK_MT2701_IMGSYS=y +CONFIG_COMMON_CLK_MT2701_MMSYS=y +CONFIG_COMMON_CLK_MT2701_VDECSYS=y +# CONFIG_COMMON_CLK_MT7622 is not set +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMPACTION=y +CONFIG_COREDUMP=y +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRASH_CORE=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_MEDIATEK=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_MT6589_UART0=y +# CONFIG_DEBUG_MT8127_UART0 is not set +# CONFIG_DEBUG_MT8135_UART3 is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_UART_8250=y +# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set +CONFIG_DEBUG_UART_8250_SHIFT=2 +# CONFIG_DEBUG_UART_8250_WORD is not set +CONFIG_DEBUG_UART_PHYS=0x11004000 +CONFIG_DEBUG_UART_VIRT=0xf1004000 +CONFIG_DEBUG_UNCOMPRESS=y +# CONFIG_DEBUG_USER is not set +CONFIG_DEFAULT_DUMMY=y +CONFIG_DEFAULT_SCHEDULER=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +# CONFIG_DMA_NOOP_OPS is not set +CONFIG_DMA_OF=y +# CONFIG_DMA_VIRT_OPS is not set +# CONFIG_DRM_LIB_RANDOM is not set +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_ELF_CORE=y +CONFIG_EXPORTFS=y +CONFIG_EXT4_FS=y +# CONFIG_F2FS_CHECK_FS is not set +CONFIG_F2FS_FS=y +# CONFIG_F2FS_FS_SECURITY is not set +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_STAT_FS=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FREEZER=y +CONFIG_FS_MBCACHE=y +CONFIG_FUTEX_PI=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +# CONFIG_GPS is not set +# CONFIG_GRO_CELLS is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_HAVE_ARM_SMCCC=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SMP=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +# CONFIG_HIGHMEM is not set +# CONFIG_HIGHPTE is not set +CONFIG_HOTPLUG_CPU=y +CONFIG_HWMON=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_HZ_PERIODIC=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MT65XX=y +CONFIG_ICPLUS_PHY=y +CONFIG_IIO=y +# CONFIG_IIO_BUFFER is not set +# CONFIG_IIO_TRIGGER is not set +CONFIG_INITRAMFS_COMPRESSION="" +# CONFIG_INITRAMFS_FORCE is not set +CONFIG_INITRAMFS_ROOT_GID=1000 +CONFIG_INITRAMFS_ROOT_UID=1000 +CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt" +CONFIG_IOMMU_HELPER=y +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +CONFIG_KEXEC=y +CONFIG_KEXEC_CORE=y +CONFIG_LDISC_AUTOLOAD=y +CONFIG_LEDS_MT6323=y +CONFIG_LIBFDT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +CONFIG_MACH_MT7623=y +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_GPIO=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MFD_CORE=y +CONFIG_MFD_MT6397=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MPTCP_BINDER is not set +# CONFIG_MPTCP_FULLMESH is not set +# CONFIG_MPTCP_NDIFFPORTS is not set +# CONFIG_MPTCP_REDUNDANT is not set +# CONFIG_MPTCP_ROUNDROBIN is not set +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_MT81xx_NOR=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_MTK=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTK_BTIF=y +CONFIG_MTK_COMBO=y +# CONFIG_MTK_COMBO_BT is not set +CONFIG_MTK_COMBO_CHIP="CONSYS_7623" +# CONFIG_MTK_COMBO_CHIP_CONSYS_6572 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_6580 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_6582 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_6592 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_6735 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_6752 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_6755 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_6797 is not set +CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y +# CONFIG_MTK_COMBO_CHIP_CONSYS_8127 is not set +# CONFIG_MTK_COMBO_CHIP_CONSYS_8163 is not set +# CONFIG_MTK_COMBO_CHIP_MT6620 is not set +# CONFIG_MTK_COMBO_CHIP_MT6628 is not set +# CONFIG_MTK_COMBO_CHIP_MT6630 is not set +# CONFIG_MTK_COMBO_COMM is not set +# CONFIG_MTK_COMBO_BT_HCI is not set +CONFIG_MTK_COMBO_PLAT_PATH="" +CONFIG_MTK_COMBO_WIFI=m +# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set +CONFIG_MTK_DHCPV6C_WIFI=y +CONFIG_MTK_EFUSE=y +# CONFIG_MTK_GPS_SUPPORT is not set +# CONFIG_MTK_HSDMA is not set +CONFIG_MTK_INFRACFG=y +# CONFIG_MTK_IOMMU is not set +# CONFIG_MTK_IOMMU_V1 is not set +CONFIG_MTK_PASSPOINT_R1_SUPPORT=y +CONFIG_MTK_PASSPOINT_R2_SUPPORT=y +CONFIG_MTK_PLATFORM="mt7623" +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +CONFIG_MTK_WAPI_SUPPORT=y +CONFIG_MTK_WIFI_MCC_SUPPORT=y +CONFIG_MULTI_IRQ_HANDLER=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_HNAT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NL80211_TESTMODE=y +CONFIG_NLS=y +CONFIG_NO_BOOTMEM=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_ADDRESS_PCI=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PGTABLE_MAPPING=y +CONFIG_PHYLIB=y +CONFIG_PHY_MTK_TPHY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT2701=y +CONFIG_PINCTRL_MT6397=y +CONFIG_PINCTRL_MTK=y +CONFIG_PM=y +CONFIG_PM_CLK=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_EXPERT is not set +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6380 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_RTC_DRV_MT7622 is not set +CONFIG_RTC_I2C_AND_SPI=y +# CONFIG_RTL8723BS is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_SCHED_INFO is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MT65XX=y +CONFIG_SPMI=y +CONFIG_SRCU=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASKS_RCU=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +CONFIG_THIN_ARCHIVES=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_MTU3 is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_OF=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +CONFIG_XPS=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSMALLOC=y +# CONFIG_ZSMALLOC_STAT is not set \ No newline at end of file diff --git a/root/target/linux/mediatek/mt7623/config-4.19 b/root/target/linux/mediatek/mt7623/config-4.19 new file mode 100755 index 00000000..c162f5c0 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/config-4.19 @@ -0,0 +1,555 @@ +# CONFIG_AIO is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_ARCH_AXXIA is not set +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_ARCH_HAS_KCOV=y +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_ARCH_HAS_PHYS_TO_DMA=y +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND=y +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_LPAE=y +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ASN1=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +# CONFIG_BCM84881_PHY is not set +CONFIG_BLK_MQ_PCI=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CLEANCACHE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CLZ_TAB=y +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 vmalloc=256M" +CONFIG_CMDLINE_EXTEND=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2701=y +CONFIG_COMMON_CLK_MT2701_AUDSYS=y +CONFIG_COMMON_CLK_MT2701_BDPSYS=y +CONFIG_COMMON_CLK_MT2701_ETHSYS=y +CONFIG_COMMON_CLK_MT2701_G3DSYS=y +CONFIG_COMMON_CLK_MT2701_HIFSYS=y +CONFIG_COMMON_CLK_MT2701_IMGSYS=y +CONFIG_COMMON_CLK_MT2701_MMSYS=y +CONFIG_COMMON_CLK_MT2701_VDECSYS=y +# CONFIG_COMMON_CLK_MT7622 is not set +CONFIG_COMMON_CLK_MT7629=y +# CONFIG_COMMON_CLK_MT7629_ETHSYS is not set +# CONFIG_COMMON_CLK_MT7629_HIFSYS is not set +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COREDUMP=y +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRASH_CORE=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_MT6589_UART0=y +# CONFIG_DEBUG_MT8127_UART0 is not set +# CONFIG_DEBUG_MT8135_UART3 is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_UART_8250=y +# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set +CONFIG_DEBUG_UART_8250_SHIFT=2 +# CONFIG_DEBUG_UART_8250_WORD is not set +CONFIG_DEBUG_UART_PHYS=0x11004000 +CONFIG_DEBUG_UART_VIRT=0xf1004000 +CONFIG_DEBUG_UNCOMPRESS=y +# CONFIG_DEBUG_USER is not set +CONFIG_DEFAULT_NETLINK=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_ELF_CORE=y +CONFIG_EXT4_FS=y +# CONFIG_F2FS_CHECK_FS is not set +CONFIG_F2FS_FS=y +# CONFIG_F2FS_FS_SECURITY is not set +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_STAT_FS=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FREEZER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +# CONFIG_GPS is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_HARDEN_BRANCH_PREDICTOR is not set +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_GUP=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_RCU_TABLE_FREE=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_SMP=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HOTPLUG_CPU=y +# CONFIG_HUGETLBFS is not set +CONFIG_HWMON=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_HZ_PERIODIC=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MT65XX=y +CONFIG_ICPLUS_PHY=y +CONFIG_IIO=y +# CONFIG_IIO_BUFFER is not set +# CONFIG_IIO_TRIGGER is not set +CONFIG_INITRAMFS_COMPRESSION="" +# CONFIG_INITRAMFS_FORCE is not set +CONFIG_INITRAMFS_ROOT_GID=1000 +CONFIG_INITRAMFS_ROOT_UID=1000 +CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt" +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +CONFIG_KEXEC=y +CONFIG_KEXEC_CORE=y +CONFIG_KEYS=y +CONFIG_LEDS_MT6323=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +CONFIG_MACH_MT7623=y +CONFIG_MACH_MT7629=y +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_GPIO=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_CORE=y +CONFIG_MFD_MT6397=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MPILIB=y +# CONFIG_MPTCP_BINDER is not set +# CONFIG_MPTCP_FULLMESH is not set +# CONFIG_MPTCP_NDIFFPORTS is not set +# CONFIG_MPTCP_REDUNDANT is not set +# CONFIG_MPTCP_ROUNDROBIN is not set +# CONFIG_MT753X_GSW is not set +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_MT81xx_NOR=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_MTK=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +# CONFIG_MTK_BTIF is not set +# CONFIG_MTK_COMBO is not set +# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set +# CONFIG_MTK_DHCPV6C_WIFI is not set +CONFIG_MTK_EFUSE=y +# CONFIG_MTK_GPS_SUPPORT is not set +# CONFIG_MTK_HSDMA is not set +CONFIG_MTK_INFRACFG=y +# CONFIG_MTK_IOMMU is not set +# CONFIG_MTK_IOMMU_V1 is not set +CONFIG_MTK_PLATFORM="mt7623" +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_LEGACY=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NLS=y +CONFIG_NO_BOOTMEM=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +# CONFIG_PCI_V3_SEMI is not set +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_PGTABLE_MAPPING=y +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT2701=y +CONFIG_PINCTRL_MT6397=y +CONFIG_PINCTRL_MT7623=y +CONFIG_PINCTRL_MT7629=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PLUGIN_HOSTCC="g++" +CONFIG_PM=y +CONFIG_PM_CLK=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_EXPERT is not set +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_REFCOUNT_FULL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6380 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_RTC_DRV_MT7622 is not set +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SFP is not set +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +# CONFIG_SPI_MTK_SNFI is not set +CONFIG_SPMI=y +# CONFIG_SPS30 is not set +CONFIG_SRCU=y +CONFIG_STREAM_PARSER=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_TASKS_RCU=y +# CONFIG_TCP_CONG_NANQINLANG is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WIRELESS is not set +# CONFIG_WLAN is not set +CONFIG_XPS=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSMALLOC=y +# CONFIG_ZSMALLOC_STAT is not set diff --git a/root/target/linux/mediatek/mt7623/config-5.14 b/root/target/linux/mediatek/mt7623/config-5.14 new file mode 100755 index 00000000..8c5c6c6e --- /dev/null +++ b/root/target/linux/mediatek/mt7623/config-5.14 @@ -0,0 +1,634 @@ +# CONFIG_AIO is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_ATAG_DTB_COMPAT is not set +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 +CONFIG_ARM_DMA_USE_IOMMU=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_BACKLIGHT_LED=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_CMDLINE_PARSER=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CLEANCACHE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2701=y +CONFIG_COMMON_CLK_MT2701_AUDSYS=y +CONFIG_COMMON_CLK_MT2701_BDPSYS=y +CONFIG_COMMON_CLK_MT2701_ETHSYS=y +CONFIG_COMMON_CLK_MT2701_G3DSYS=y +CONFIG_COMMON_CLK_MT2701_HIFSYS=y +CONFIG_COMMON_CLK_MT2701_IMGSYS=y +CONFIG_COMMON_CLK_MT2701_MMSYS=y +CONFIG_COMMON_CLK_MT2701_VDECSYS=y +# CONFIG_COMMON_CLK_MT7622 is not set +# CONFIG_COMMON_CLK_MT7629 is not set +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_COREDUMP=y +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_MEDIATEK=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_MISC=y +CONFIG_DEBUG_MT6589_UART0=y +# CONFIG_DEBUG_MT8127_UART0 is not set +# CONFIG_DEBUG_MT8135_UART3 is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_UART_8250=y +CONFIG_DEBUG_UART_8250_SHIFT=2 +CONFIG_DEBUG_UART_PHYS=0x11004000 +CONFIG_DEBUG_UART_VIRT=0xf1004000 +CONFIG_DEBUG_UNCOMPRESS=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +# CONFIG_DEVFREQ_GOV_USERSPACE is not set +# CONFIG_DEVFREQ_THERMAL is not set +CONFIG_DIMLIB=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DRM=y +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=100 +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_LIMA=y +CONFIG_DRM_LVDS_CODEC=y +CONFIG_DRM_MEDIATEK=y +CONFIG_DRM_MEDIATEK_HDMI=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_PANEL=y +# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set +# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set +# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set +CONFIG_DRM_PANEL_BRIDGE=y +# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set +# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set +# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set +# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set +# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=y +# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set +# CONFIG_DRM_PANEL_SONY_ACX424AKP is not set +# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set +CONFIG_DRM_SCHED=y +CONFIG_DRM_SIMPLE_BRIDGE=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FONT_SUPPORT=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_ELF_CORE=y +CONFIG_EXT4_FS=y +CONFIG_EXTCON=y +CONFIG_F2FS_FS=y +CONFIG_FB=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CMDLINE=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_SYS_IMAGEBLIT=y +CONFIG_FIT_PARTITION=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FREEZER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FW_CACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_GPIOLIB=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HDMI=y +CONFIG_HID=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HOTPLUG_CPU=y +CONFIG_HW_CONSOLE=y +CONFIG_HWMON=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HID=y +CONFIG_I2C_MT65XX=y +CONFIG_ICPLUS_PHY=y +CONFIG_IIO=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_IOMMU_API=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_IO_PGTABLE=y +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADC is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_FSIA6B is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_PSXPAD_SPI is not set +# CONFIG_JOYSTICK_PXRC is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_JOYSTICK_WALKERA0701 is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +CONFIG_KALLSYMS=y +CONFIG_KCMP=y +CONFIG_KEYBOARD_MTK_PMIC=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=y +CONFIG_LEDS_MT6323=y +# CONFIG_LEDS_UBNT_LEDBAR is not set +CONFIG_LIBFDT=y +CONFIG_LLD_VERSION=0 +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +CONFIG_MACH_MT7623=y +# CONFIG_MACH_MT7629 is not set +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAILBOX=y +# CONFIG_MAILBOX_TEST is not set +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_GPIO=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MEMORY=y +CONFIG_MFD_CORE=y +# CONFIG_MFD_HI6421_SPMI is not set +CONFIG_MFD_MT6397=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_CYAPA is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_NAND_MTK_BMT is not set +# CONFIG_MTD_PARSER_TRX is not set +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTK_CMDQ=y +CONFIG_MTK_CMDQ_MBOX=y +CONFIG_MTK_CQDMA=y +CONFIG_MTK_EFUSE=y +# CONFIG_MTK_HSDMA is not set +CONFIG_MTK_INFRACFG=y +CONFIG_MTK_IOMMU=y +CONFIG_MTK_IOMMU_V1=y +CONFIG_MTK_MMSYS=y +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_SMI=y +# CONFIG_MTK_SPI_NAND is not set +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +# CONFIG_MTK_UART_APDMA is not set +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEON=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NLS=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +# CONFIG_NVMEM_SPMI_SDAM is not set +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IOMMU=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHY_MTK_HDMI=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT2701=y +CONFIG_PINCTRL_MT6397=y +CONFIG_PINCTRL_MT7623=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PINCTRL_MTK_V2=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_DEVFREQ=y +# CONFIG_PM_DEVFREQ_EVENT is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_MT6323 is not set +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PREEMPT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6358 is not set +# CONFIG_REGULATOR_MT6380 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_QCOM_LABIBB is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +# CONFIG_REGULATOR_QCOM_USB_VBUS is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_RTC_DRV_MT7622 is not set +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y +# CONFIG_RTL8367S_GSW is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +# CONFIG_SND_SOC_MT6359 is not set +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +# CONFIG_SPI_MTK_NOR is not set +CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +CONFIG_SRCU=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYNC_FILE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_TABLET_SERIAL_WACOM4 is not set +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_USB_PEGASUS is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TOUCHSCREEN_EDT_FT5X06=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +# CONFIG_UACCE is not set +CONFIG_UBIFS_FS=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_UNWINDER_ARM=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_ETH is not set +CONFIG_USB_F_ACM=y +CONFIG_USB_F_ECM=y +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GPIO_VBUS=y +CONFIG_USB_G_MULTI=y +CONFIG_USB_G_MULTI_CDC=y +# CONFIG_USB_G_MULTI_RNDIS is not set +CONFIG_USB_HID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_INVENTRA_DMA=y +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_MUSB_DUAL_ROLE=y +# CONFIG_USB_MUSB_GADGET is not set +CONFIG_USB_MUSB_HDRC=y +# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_MUSB_MEDIATEK=y +CONFIG_USB_OTG=y +CONFIG_USB_PHY=y +CONFIG_USB_ROLE_SWITCH=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_U_ETHER=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/root/target/linux/mediatek/mt7623/config-5.15 b/root/target/linux/mediatek/mt7623/config-5.15 new file mode 100755 index 00000000..11d2a931 --- /dev/null +++ b/root/target/linux/mediatek/mt7623/config-5.15 @@ -0,0 +1,637 @@ +# CONFIG_AIO is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_ATAG_DTB_COMPAT is not set +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 +CONFIG_ARM_DMA_USE_IOMMU=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_BACKLIGHT_LED=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_CMDLINE_PARSER=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CLEANCACHE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2701=y +CONFIG_COMMON_CLK_MT2701_AUDSYS=y +CONFIG_COMMON_CLK_MT2701_BDPSYS=y +CONFIG_COMMON_CLK_MT2701_ETHSYS=y +CONFIG_COMMON_CLK_MT2701_G3DSYS=y +CONFIG_COMMON_CLK_MT2701_HIFSYS=y +CONFIG_COMMON_CLK_MT2701_IMGSYS=y +CONFIG_COMMON_CLK_MT2701_MMSYS=y +CONFIG_COMMON_CLK_MT2701_VDECSYS=y +# CONFIG_COMMON_CLK_MT7622 is not set +# CONFIG_COMMON_CLK_MT7629 is not set +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_COREDUMP=y +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_MEDIATEK=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_MISC=y +CONFIG_DEBUG_MT6589_UART0=y +# CONFIG_DEBUG_MT8127_UART0 is not set +# CONFIG_DEBUG_MT8135_UART3 is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_UART_8250=y +CONFIG_DEBUG_UART_8250_SHIFT=2 +CONFIG_DEBUG_UART_PHYS=0x11004000 +CONFIG_DEBUG_UART_VIRT=0xf1004000 +CONFIG_DEBUG_UNCOMPRESS=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +# CONFIG_DEVFREQ_GOV_USERSPACE is not set +# CONFIG_DEVFREQ_THERMAL is not set +CONFIG_DIMLIB=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DRM=y +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=100 +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_LIMA=y +CONFIG_DRM_LVDS_CODEC=y +CONFIG_DRM_MEDIATEK=y +CONFIG_DRM_MEDIATEK_HDMI=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_PANEL=y +# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set +# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set +# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set +CONFIG_DRM_PANEL_BRIDGE=y +# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set +# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set +# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set +# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set +# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=y +# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set +# CONFIG_DRM_PANEL_SONY_ACX424AKP is not set +# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set +CONFIG_DRM_SCHED=y +CONFIG_DRM_SIMPLE_BRIDGE=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FONT_SUPPORT=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_ELF_CORE=y +CONFIG_EXT4_FS=y +CONFIG_EXTCON=y +CONFIG_F2FS_FS=y +CONFIG_FB=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CMDLINE=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_SYS_IMAGEBLIT=y +CONFIG_FIT_PARTITION=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FREEZER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FW_CACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_GPIOLIB=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HDMI=y +CONFIG_HID=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HOTPLUG_CPU=y +CONFIG_HW_CONSOLE=y +CONFIG_HWMON=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HID=y +CONFIG_I2C_MT65XX=y +CONFIG_ICPLUS_PHY=y +CONFIG_IIO=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set +CONFIG_IOMMU_IO_PGTABLE=y +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADC is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_FSIA6B is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_PSXPAD_SPI is not set +# CONFIG_JOYSTICK_PXRC is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_JOYSTICK_WALKERA0701 is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +CONFIG_KALLSYMS=y +CONFIG_KCMP=y +CONFIG_KEYBOARD_MTK_PMIC=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=y +CONFIG_LEDS_MT6323=y +# CONFIG_LEDS_UBNT_LEDBAR is not set +CONFIG_LIBFDT=y +CONFIG_LLD_VERSION=0 +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +CONFIG_MACH_MT7623=y +# CONFIG_MACH_MT7629 is not set +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAILBOX=y +# CONFIG_MAILBOX_TEST is not set +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_GPIO=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MEMORY=y +CONFIG_MFD_CORE=y +# CONFIG_MFD_HI6421_SPMI is not set +CONFIG_MFD_MT6397=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_CYAPA is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_NAND_MTK_BMT is not set +# CONFIG_MTD_PARSER_TRX is not set +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTK_CMDQ=y +CONFIG_MTK_CMDQ_MBOX=y +CONFIG_MTK_CQDMA=y +CONFIG_MTK_EFUSE=y +# CONFIG_MTK_HSDMA is not set +CONFIG_MTK_INFRACFG=y +CONFIG_MTK_IOMMU=y +CONFIG_MTK_IOMMU_V1=y +CONFIG_MTK_MMSYS=y +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_SCPSYS_PM_DOMAINS=y +CONFIG_MTK_SMI=y +# CONFIG_MTK_SPI_NAND is not set +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +# CONFIG_MTK_UART_APDMA is not set +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEON=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NLS=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +# CONFIG_NVMEM_SPMI_SDAM is not set +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IOMMU=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHY_MTK_HDMI=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT2701=y +CONFIG_PINCTRL_MT6397=y +CONFIG_PINCTRL_MT7623=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PINCTRL_MTK_V2=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_DEVFREQ=y +# CONFIG_PM_DEVFREQ_EVENT is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_MT6323 is not set +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PREEMPT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6358 is not set +# CONFIG_REGULATOR_MT6380 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_QCOM_LABIBB is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +# CONFIG_REGULATOR_QCOM_USB_VBUS is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_RTC_DRV_MT7622 is not set +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y +# CONFIG_RTL8367S_GSW is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +# CONFIG_SND_SOC_MT6359 is not set +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +# CONFIG_SPI_MTK_NOR is not set +CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +CONFIG_SRCU=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYNC_FILE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_TABLET_SERIAL_WACOM4 is not set +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_USB_PEGASUS is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TOUCHSCREEN_EDT_FT5X06=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +# CONFIG_UACCE is not set +CONFIG_UBIFS_FS=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_UNWINDER_ARM=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_ETH is not set +CONFIG_USB_F_ACM=y +CONFIG_USB_F_ECM=y +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GPIO_VBUS=y +CONFIG_USB_G_MULTI=y +CONFIG_USB_G_MULTI_CDC=y +# CONFIG_USB_G_MULTI_RNDIS is not set +CONFIG_USB_HID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_INVENTRA_DMA=y +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_MUSB_DUAL_ROLE=y +# CONFIG_USB_MUSB_GADGET is not set +CONFIG_USB_MUSB_HDRC=y +# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_MUSB_MEDIATEK=y +CONFIG_USB_OTG=y +CONFIG_USB_PHY=y +CONFIG_USB_ROLE_SWITCH=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_U_ETHER=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/root/target/linux/mediatek/mt7623/config-5.4 b/root/target/linux/mediatek/mt7623/config-5.4 new file mode 100755 index 00000000..6e1ff28b --- /dev/null +++ b/root/target/linux/mediatek/mt7623/config-5.4 @@ -0,0 +1,561 @@ +# CONFIG_AIO is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_HAS_BINFMT_FLAT=y +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_ARCH_HAS_KCOV=y +CONFIG_ARCH_HAS_KEEPINITRD=y +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_ARCH_HAS_PHYS_TO_DMA=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_ARCH_MILBEAUT is not set +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +# CONFIG_ARCH_RDA is not set +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_ATAG_DTB_COMPAT is not set +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +# CONFIG_ARM_ERRATA_814220 is not set +# CONFIG_ARM_ERRATA_857271 is not set +# CONFIG_ARM_ERRATA_857272 is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +# CONFIG_ARM_LPAE is not set +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CC_CAN_LINK=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y +CONFIG_CLEANCACHE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2701=y +# CONFIG_COMMON_CLK_MT2701_AUDSYS is not set +CONFIG_COMMON_CLK_MT2701_BDPSYS=y +CONFIG_COMMON_CLK_MT2701_ETHSYS=y +# CONFIG_COMMON_CLK_MT2701_G3DSYS is not set +CONFIG_COMMON_CLK_MT2701_HIFSYS=y +CONFIG_COMMON_CLK_MT2701_IMGSYS=y +CONFIG_COMMON_CLK_MT2701_MMSYS=y +CONFIG_COMMON_CLK_MT2701_VDECSYS=y +# CONFIG_COMMON_CLK_MT7622 is not set +# CONFIG_COMMON_CLK_MT7629 is not set +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_COREDUMP=y +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_MEDIATEK=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_MISC=y +CONFIG_DEBUG_MT6589_UART0=y +# CONFIG_DEBUG_MT8127_UART0 is not set +# CONFIG_DEBUG_MT8135_UART3 is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_UART_8250=y +# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set +CONFIG_DEBUG_UART_8250_SHIFT=2 +# CONFIG_DEBUG_UART_8250_WORD is not set +CONFIG_DEBUG_UART_PHYS=0x11004000 +CONFIG_DEBUG_UART_VIRT=0xf1004000 +CONFIG_DEBUG_UNCOMPRESS=y +# CONFIG_DEBUG_USER is not set +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_REMAP=y +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_ELF_CORE=y +# CONFIG_ENERGY_MODEL is not set +CONFIG_EXT4_FS=y +# CONFIG_F2FS_CHECK_FS is not set +CONFIG_F2FS_FS=y +# CONFIG_F2FS_FS_SECURITY is not set +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_STAT_FS=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FREEZER=y +# CONFIG_FSL_QDMA is not set +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HABANA_AI is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_COPY_THREAD_TLS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PCI=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_SMP=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HOTPLUG_CPU=y +CONFIG_HWMON=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MT65XX=y +# CONFIG_I2C_NVIDIA_GPU is not set +CONFIG_ICPLUS_PHY=y +# CONFIG_IGC is not set +CONFIG_IIO=y +# CONFIG_IIO_BUFFER is not set +# CONFIG_IIO_TRIGGER is not set +CONFIG_INITRAMFS_COMPRESSION="" +CONFIG_INITRAMFS_ROOT_GID=1000 +CONFIG_INITRAMFS_ROOT_UID=1000 +CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt" +CONFIG_INIT_STACK_NONE=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +CONFIG_LEDS_MT6323=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +CONFIG_MACH_MT7623=y +# CONFIG_MACH_MT7629 is not set +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_GPIO=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_CORE=y +CONFIG_MFD_MT6397=y +# CONFIG_MFD_STPMIC1 is not set +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +# CONFIG_MISC_ALCOR_PCI is not set +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MT753X_GSW is not set +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +# CONFIG_MTK_CMDQ is not set +# CONFIG_MTK_CQDMA is not set +CONFIG_MTK_EFUSE=y +# CONFIG_MTK_HSDMA is not set +CONFIG_MTK_INFRACFG=y +# CONFIG_MTK_IOMMU is not set +# CONFIG_MTK_IOMMU_V1 is not set +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +# CONFIG_MTK_UART_APDMA is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +# CONFIG_NET_DSA_TAG_QCA is not set +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SWITCHDEV=y +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NLS=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +# CONFIG_PCI_MESON is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +# CONFIG_PCI_V3_SEMI is not set +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT2701=y +CONFIG_PINCTRL_MT6397=y +CONFIG_PINCTRL_MT7623=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PM=y +CONFIG_PM_CLK=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PREEMPT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +# CONFIG_QCOM_SPMI_ADC5 is not set +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_EXPERT is not set +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_REFCOUNT_FULL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6380 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_RTC_DRV_MT7622 is not set +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +CONFIG_SPMI=y +CONFIG_SRCU=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASKS_RCU=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +# CONFIG_TI_CPSW_PHY_SEL is not set +CONFIG_TREE_SRCU=y +# CONFIG_TRUSTED_FOUNDATIONS is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_ZSTD=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_UNWINDER_ARM=y +# CONFIG_UNWINDER_FRAME_POINTER is not set +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch new file mode 100755 index 00000000..517b5be6 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch @@ -0,0 +1,23 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2018-12-26 16:53:06.778501203 +0100 ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2018-12-26 16:55:46.280213376 +0100 +@@ -22,6 +22,7 @@ + }; + + memory { +- reg = <0 0x80000000 0 0x20000000>; ++ device_type = "memory"; ++ reg = <0 0x80000000 0 0x80000000>; + }; + +@@ -115,11 +116,6 @@ + }; + }; + +- memory@80000000 { +- device_type = "memory"; +- reg = <0 0x80000000 0 0x40000000>; +- }; +- + mt7530: switch@0 { + compatible = "mediatek,mt7530"; + }; diff --git a/root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch new file mode 100755 index 00000000..ef9b4a79 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch @@ -0,0 +1,27 @@ +Index: linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +=================================================================== +--- linux-4.14.51.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -87,19 +87,19 @@ + + blue { + label = "bpi-r2:pio:blue"; +- gpios = <&pio 241 GPIO_ACTIVE_HIGH>; ++ gpios = <&pio 240 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + green { + label = "bpi-r2:pio:green"; +- gpios = <&pio 240 GPIO_ACTIVE_HIGH>; ++ gpios = <&pio 241 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + red { + label = "bpi-r2:pio:red"; +- gpios = <&pio 239 GPIO_ACTIVE_HIGH>; ++ gpios = <&pio 239 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; diff --git a/root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch new file mode 100755 index 00000000..f202cae7 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch @@ -0,0 +1,48 @@ +Index: linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +=================================================================== +--- linux-4.14.51.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -266,6 +266,28 @@ + vqmmc-supply = <&mt6323_vio18_reg>; + }; + ++&pcie { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_default>; ++ status = "okay"; ++ ++ pcie@0,0 { ++ status = "okay"; ++ }; ++ ++ pcie@1,0 { ++ status = "okay"; ++ }; ++}; ++ ++&pcie0_phy { ++ status = "okay"; ++}; ++ ++&pcie1_phy { ++ status = "okay"; ++}; ++ + &pio { + cir_pins_a:cir@0 { + pins_cir { +@@ -433,6 +455,14 @@ + }; + }; + ++ pcie_default: pcie_pin_default { ++ pins_cmd_dat { ++ pinmux = , ++ ; ++ bias-disable; ++ }; ++ }; ++ + pwm_pins_a: pwm@0 { + pins_pwm { + pinmux = , diff --git a/root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch new file mode 100755 index 00000000..7c30af0a --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch @@ -0,0 +1,22 @@ +Index: linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +=================================================================== +--- linux-4.14.51.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -141,7 +141,7 @@ + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; +- phy-mode = "rgmii"; ++ phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; +@@ -206,7 +206,7 @@ + reg = <5>; + label = "cpu"; + ethernet = <&gmac1>; +- phy-mode = "rgmii"; ++ phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; diff --git a/root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch b/root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch new file mode 100755 index 00000000..25dca71f --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch @@ -0,0 +1,217327 @@ +From e6b369a5ade19206db433b46d0102ae000b87e99 Mon Sep 17 00:00:00 2001 +From: frank +Date: Wed, 20 Dec 2017 22:36:53 +0100 +Subject: [PATCH] merge mt6625l wifi driver + +--- + arch/arm/boot/dts/mt7623.dtsi | 48 + + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 263 + + drivers/misc/Kconfig | 1 + + drivers/misc/Makefile | 2 + + drivers/misc/mediatek/Kconfig | 11 + + drivers/misc/mediatek/Makefile | 19 + + drivers/misc/mediatek/btif/Kconfig | 4 + + drivers/misc/mediatek/btif/Makefile | 33 + + drivers/misc/mediatek/btif/common/Makefile | 31 + + .../misc/mediatek/btif/common/btif_dma_plat.c | 1436 ++ + drivers/misc/mediatek/btif/common/btif_plat.c | 1396 ++ + .../misc/mediatek/btif/common/inc/mtk_btif.h | 370 + + .../mediatek/btif/common/inc/mtk_btif_exp.h | 280 + + drivers/misc/mediatek/btif/common/mtk_btif.c | 3472 +++++ + .../misc/mediatek/btif/common/mtk_btif_exp.c | 786 ++ + .../btif/common/plat_inc/btif_dma_priv.h | 164 + + .../btif/common/plat_inc/btif_dma_pub.h | 197 + + .../mediatek/btif/common/plat_inc/btif_priv.h | 105 + + .../mediatek/btif/common/plat_inc/btif_pub.h | 237 + + .../btif/common/plat_inc/plat_common.h | 307 + + drivers/misc/mediatek/connectivity/Kconfig | 298 + + drivers/misc/mediatek/connectivity/Makefile | 41 + + .../mediatek/connectivity/common/Makefile | 23 + + .../common/common_detect/Makefile | 47 + + .../common/common_detect/drv_init/Makefile | 22 + + .../common_detect/drv_init/ant_drv_init.c | 38 + + .../drv_init/bluetooth_drv_init.c | 35 + + .../common_detect/drv_init/common_drv_init.c | 103 + + .../common_detect/drv_init/conn_drv_init.c | 80 + + .../common_detect/drv_init/fm_drv_init.c | 33 + + .../common_detect/drv_init/gps_drv_init.c | 35 + + .../common_detect/drv_init/inc/ant_drv_init.h | 20 + + .../drv_init/inc/bluetooth_drv_init.h | 20 + + .../drv_init/inc/common_drv_init.h | 31 + + .../drv_init/inc/conn_drv_init.h | 18 + + .../common_detect/drv_init/inc/fm_drv_init.h | 20 + + .../common_detect/drv_init/inc/gps_drv_init.h | 19 + + .../drv_init/inc/wlan_drv_init.h | 30 + + .../common_detect/drv_init/wlan_drv_init.c | 74 + + .../common/common_detect/mtk_wcn_stub_alps.c | 605 + + .../common/common_detect/sdio_detect.c | 269 + + .../common/common_detect/sdio_detect.h | 43 + + .../common/common_detect/wmt_detect.c | 380 + + .../common/common_detect/wmt_detect.h | 114 + + .../common/common_detect/wmt_detect_pwr.c | 232 + + .../common/common_detect/wmt_detect_pwr.h | 29 + + .../common/common_detect/wmt_gpio.c | 371 + + .../common/common_detect/wmt_gpio.h | 103 + + .../common/common_detect/wmt_stp_exp.c | 480 + + .../common/common_detect/wmt_stp_exp.h | 610 + + .../connectivity/common/conn_soc/Makefile | 65 + + .../common/conn_soc/core/Makefile | 22 + + .../common/conn_soc/core/btm_core.c | 1376 ++ + .../common/conn_soc/core/dbg_core.c | 13 + + .../common/conn_soc/core/include/btm_core.h | 133 + + .../common/conn_soc/core/include/dbg_core.h | 69 + + .../common/conn_soc/core/include/psm_core.h | 251 + + .../common/conn_soc/core/include/stp_core.h | 629 + + .../common/conn_soc/core/include/stp_wmt.h | 89 + + .../common/conn_soc/core/include/wmt_conf.h | 74 + + .../common/conn_soc/core/include/wmt_core.h | 428 + + .../common/conn_soc/core/include/wmt_ctrl.h | 120 + + .../common/conn_soc/core/include/wmt_func.h | 140 + + .../common/conn_soc/core/include/wmt_ic.h | 122 + + .../common/conn_soc/core/include/wmt_lib.h | 300 + + .../common/conn_soc/core/psm_core.c | 1889 +++ + .../common/conn_soc/core/stp_core.c | 3358 +++++ + .../common/conn_soc/core/wmt_conf.c | 529 + + .../common/conn_soc/core/wmt_core.c | 2521 ++++ + .../common/conn_soc/core/wmt_ctrl.c | 1019 ++ + .../common/conn_soc/core/wmt_func.c | 713 + + .../common/conn_soc/core/wmt_ic_soc.c | 2452 ++++ + .../common/conn_soc/core/wmt_lib.c | 1938 +++ + .../common/conn_soc/include/stp_exp.h | 252 + + .../common/conn_soc/include/wmt.h | 19 + + .../common/conn_soc/include/wmt_exp.h | 329 + + .../common/conn_soc/include/wmt_plat.h | 295 + + .../common/conn_soc/linux/Makefile | 6 + + .../conn_soc/linux/include/bgw_desense.h | 74 + + .../common/conn_soc/linux/include/osal.h | 348 + + .../conn_soc/linux/include/osal_typedef.h | 90 + + .../common/conn_soc/linux/include/wmt_idc.h | 97 + + .../common/conn_soc/linux/pri/Makefile | 21 + + .../conn_soc/linux/pri/include/stp_btif.h | 31 + + .../conn_soc/linux/pri/include/stp_dbg.h | 316 + + .../conn_soc/linux/pri/include/wmt_dev.h | 71 + + .../common/conn_soc/linux/pri/stp_btif.c | 279 + + .../common/conn_soc/linux/pri/stp_dbg.c | 2060 +++ + .../common/conn_soc/linux/pri/stp_exp.c | 279 + + .../common/conn_soc/linux/pri/wmt_dev.c | 2566 ++++ + .../common/conn_soc/linux/pri/wmt_exp.c | 610 + + .../common/conn_soc/linux/pub/Makefile | 27 + + .../common/conn_soc/linux/pub/bgw_desense.c | 153 + + .../common/conn_soc/linux/pub/osal.c | 1210 ++ + .../common/conn_soc/linux/pub/stp_chrdev_bt.c | 899 ++ + .../conn_soc/linux/pub/wmt_chrdev_wifi.c | 668 + + .../common/conn_soc/linux/pub/wmt_idc.c | 307 + + .../common/conn_soc/mt7623/Makefile | 25 + + .../mt7623/include/mtk_wcn_consys_hw.h | 287 + + .../conn_soc/mt7623/mtk_wcn_consys_hw.c | 737 ++ + .../common/conn_soc/mt7623/wmt_plat_alps.c | 1071 ++ + .../misc/mediatek/connectivity/wlan/Makefile | 8 + + .../mediatek/connectivity/wlan/gen2/Makefile | 237 + + .../connectivity/wlan/gen2/common/debug.c | 165 + + .../connectivity/wlan/gen2/common/dump.c | 345 + + .../connectivity/wlan/gen2/common/wlan_bow.c | 3442 +++++ + .../connectivity/wlan/gen2/common/wlan_lib.c | 6240 +++++++++ + .../connectivity/wlan/gen2/common/wlan_oid.c | 11050 ++++++++++++++++ + .../connectivity/wlan/gen2/common/wlan_p2p.c | 1654 +++ + .../wlan/gen2/include/CFG_Wifi_File.h | 238 + + .../connectivity/wlan/gen2/include/config.h | 1628 +++ + .../connectivity/wlan/gen2/include/debug.h | 466 + + .../connectivity/wlan/gen2/include/link.h | 368 + + .../wlan/gen2/include/mgmt/aa_fsm.h | 188 + + .../wlan/gen2/include/mgmt/ais_fsm.h | 573 + + .../wlan/gen2/include/mgmt/assoc.h | 112 + + .../wlan/gen2/include/mgmt/auth.h | 125 + + .../wlan/gen2/include/mgmt/bow_fsm.h | 184 + + .../connectivity/wlan/gen2/include/mgmt/bss.h | 265 + + .../connectivity/wlan/gen2/include/mgmt/cnm.h | 258 + + .../wlan/gen2/include/mgmt/cnm_mem.h | 1164 ++ + .../wlan/gen2/include/mgmt/cnm_scan.h | 169 + + .../wlan/gen2/include/mgmt/cnm_timer.h | 235 + + .../wlan/gen2/include/mgmt/hem_mbox.h | 446 + + .../wlan/gen2/include/mgmt/hs20.h | 148 + + .../connectivity/wlan/gen2/include/mgmt/mib.h | 153 + + .../wlan/gen2/include/mgmt/p2p_assoc.h | 55 + + .../wlan/gen2/include/mgmt/p2p_bss.h | 56 + + .../wlan/gen2/include/mgmt/p2p_fsm.h | 2190 +++ + .../wlan/gen2/include/mgmt/p2p_func.h | 155 + + .../wlan/gen2/include/mgmt/p2p_ie.h | 156 + + .../wlan/gen2/include/mgmt/p2p_rlm.h | 74 + + .../wlan/gen2/include/mgmt/p2p_rlm_obss.h | 64 + + .../wlan/gen2/include/mgmt/p2p_scan.h | 81 + + .../wlan/gen2/include/mgmt/p2p_state.h | 43 + + .../wlan/gen2/include/mgmt/privacy.h | 230 + + .../wlan/gen2/include/mgmt/rate.h | 93 + + .../connectivity/wlan/gen2/include/mgmt/rlm.h | 396 + + .../wlan/gen2/include/mgmt/rlm_domain.h | 557 + + .../wlan/gen2/include/mgmt/rlm_obss.h | 150 + + .../wlan/gen2/include/mgmt/rlm_protection.h | 122 + + .../wlan/gen2/include/mgmt/rlm_txpwr_init.h | 1213 ++ + .../wlan/gen2/include/mgmt/roaming_fsm.h | 171 + + .../connectivity/wlan/gen2/include/mgmt/rsn.h | 271 + + .../wlan/gen2/include/mgmt/scan.h | 988 ++ + .../wlan/gen2/include/mgmt/sec_fsm.h | 233 + + .../wlan/gen2/include/mgmt/stats.h | 368 + + .../wlan/gen2/include/mgmt/swcr.h | 187 + + .../wlan/gen2/include/mgmt/tdls.h | 262 + + .../wlan/gen2/include/mgmt/wapi.h | 104 + + .../wlan/gen2/include/mgmt/wlan_typedef.h | 87 + + .../connectivity/wlan/gen2/include/mgmt/wnm.h | 95 + + .../wlan/gen2/include/nic/adapter.h | 1506 +++ + .../connectivity/wlan/gen2/include/nic/bow.h | 322 + + .../wlan/gen2/include/nic/cmd_buf.h | 150 + + .../connectivity/wlan/gen2/include/nic/hal.h | 618 + + .../wlan/gen2/include/nic/hif_rx.h | 220 + + .../wlan/gen2/include/nic/hif_tx.h | 214 + + .../connectivity/wlan/gen2/include/nic/mac.h | 2323 ++++ + .../wlan/gen2/include/nic/mtreg.h | 272 + + .../connectivity/wlan/gen2/include/nic/nic.h | 498 + + .../wlan/gen2/include/nic/nic_rx.h | 420 + + .../wlan/gen2/include/nic/nic_tx.h | 642 + + .../connectivity/wlan/gen2/include/nic/p2p.h | 192 + + .../wlan/gen2/include/nic/p2p_cmd_buf.h | 83 + + .../wlan/gen2/include/nic/p2p_mac.h | 207 + + .../wlan/gen2/include/nic/p2p_nic.h | 62 + + .../wlan/gen2/include/nic/p2p_nic_cmd_event.h | 70 + + .../wlan/gen2/include/nic/que_mgt.h | 971 ++ + .../wlan/gen2/include/nic/wlan_def.h | 1010 ++ + .../wlan/gen2/include/nic_cmd_event.h | 2290 ++++ + .../wlan/gen2/include/nic_init_cmd_event.h | 177 + + .../wlan/gen2/include/p2p_precomp.h | 201 + + .../wlan/gen2/include/p2p_typedef.h | 165 + + .../connectivity/wlan/gen2/include/precomp.h | 388 + + .../connectivity/wlan/gen2/include/pwr_mgt.h | 141 + + .../connectivity/wlan/gen2/include/queue.h | 195 + + .../connectivity/wlan/gen2/include/rftest.h | 294 + + .../wlan/gen2/include/tdls_extr.h | 427 + + .../connectivity/wlan/gen2/include/typedef.h | 244 + + .../connectivity/wlan/gen2/include/wlan_bow.h | 352 + + .../connectivity/wlan/gen2/include/wlan_lib.h | 1001 ++ + .../connectivity/wlan/gen2/include/wlan_oid.h | 1715 +++ + .../connectivity/wlan/gen2/include/wlan_p2p.h | 307 + + .../connectivity/wlan/gen2/mgmt/aaa_fsm.c | 1303 ++ + .../connectivity/wlan/gen2/mgmt/ais_fsm.c | 5039 +++++++ + .../connectivity/wlan/gen2/mgmt/assoc.c | 1932 +++ + .../connectivity/wlan/gen2/mgmt/auth.c | 1211 ++ + .../connectivity/wlan/gen2/mgmt/bss.c | 2521 ++++ + .../connectivity/wlan/gen2/mgmt/cnm.c | 738 ++ + .../connectivity/wlan/gen2/mgmt/cnm_mem.c | 1236 ++ + .../connectivity/wlan/gen2/mgmt/cnm_timer.c | 482 + + .../connectivity/wlan/gen2/mgmt/hem_mbox.c | 816 ++ + .../connectivity/wlan/gen2/mgmt/hs20.c | 498 + + .../connectivity/wlan/gen2/mgmt/mib.c | 111 + + .../connectivity/wlan/gen2/mgmt/p2p_assoc.c | 87 + + .../connectivity/wlan/gen2/mgmt/p2p_bss.c | 58 + + .../connectivity/wlan/gen2/mgmt/p2p_fsm.c | 3139 +++++ + .../connectivity/wlan/gen2/mgmt/p2p_func.c | 3796 ++++++ + .../connectivity/wlan/gen2/mgmt/p2p_ie.c | 612 + + .../connectivity/wlan/gen2/mgmt/p2p_rlm.c | 905 ++ + .../wlan/gen2/mgmt/p2p_rlm_obss.c | 313 + + .../connectivity/wlan/gen2/mgmt/p2p_scan.c | 756 ++ + .../connectivity/wlan/gen2/mgmt/p2p_state.c | 466 + + .../connectivity/wlan/gen2/mgmt/privacy.c | 915 ++ + .../connectivity/wlan/gen2/mgmt/rate.c | 497 + + .../connectivity/wlan/gen2/mgmt/rlm.c | 1858 +++ + .../connectivity/wlan/gen2/mgmt/rlm_domain.c | 1791 +++ + .../connectivity/wlan/gen2/mgmt/rlm_obss.c | 436 + + .../wlan/gen2/mgmt/rlm_protection.c | 105 + + .../connectivity/wlan/gen2/mgmt/roaming_fsm.c | 539 + + .../connectivity/wlan/gen2/mgmt/rsn.c | 2533 ++++ + .../connectivity/wlan/gen2/mgmt/saa_fsm.c | 1788 +++ + .../connectivity/wlan/gen2/mgmt/scan.c | 3103 +++++ + .../connectivity/wlan/gen2/mgmt/scan_fsm.c | 2136 +++ + .../connectivity/wlan/gen2/mgmt/sec_fsm.c | 1112 ++ + .../connectivity/wlan/gen2/mgmt/stats.c | 1342 ++ + .../connectivity/wlan/gen2/mgmt/swcr.c | 1170 ++ + .../connectivity/wlan/gen2/mgmt/tdls.c | 5199 ++++++++ + .../connectivity/wlan/gen2/mgmt/tdls_com.c | 741 ++ + .../connectivity/wlan/gen2/mgmt/wapi.c | 491 + + .../connectivity/wlan/gen2/mgmt/wnm.c | 301 + + .../connectivity/wlan/gen2/nic/cmd_buf.c | 254 + + .../mediatek/connectivity/wlan/gen2/nic/nic.c | 4062 ++++++ + .../wlan/gen2/nic/nic_cmd_event.c | 1636 +++ + .../connectivity/wlan/gen2/nic/nic_pwr_mgt.c | 669 + + .../connectivity/wlan/gen2/nic/nic_rx.c | 3782 ++++++ + .../connectivity/wlan/gen2/nic/nic_tx.c | 2350 ++++ + .../connectivity/wlan/gen2/nic/p2p_nic.c | 192 + + .../connectivity/wlan/gen2/nic/que_mgt.c | 5038 +++++++ + .../connectivity/wlan/gen2/os/linux/gl_bow.c | 1177 ++ + .../wlan/gen2/os/linux/gl_cfg80211.c | 3110 +++++ + .../connectivity/wlan/gen2/os/linux/gl_init.c | 3501 +++++ + .../connectivity/wlan/gen2/os/linux/gl_kal.c | 4801 +++++++ + .../connectivity/wlan/gen2/os/linux/gl_p2p.c | 4671 +++++++ + .../wlan/gen2/os/linux/gl_p2p_cfg80211.c | 1935 +++ + .../wlan/gen2/os/linux/gl_p2p_init.c | 433 + + .../wlan/gen2/os/linux/gl_p2p_kal.c | 1314 ++ + .../connectivity/wlan/gen2/os/linux/gl_proc.c | 1020 ++ + .../connectivity/wlan/gen2/os/linux/gl_rst.c | 228 + + .../wlan/gen2/os/linux/gl_vendor.c | 1220 ++ + .../connectivity/wlan/gen2/os/linux/gl_wext.c | 4158 ++++++ + .../wlan/gen2/os/linux/gl_wext_priv.c | 3142 +++++ + .../wlan/gen2/os/linux/hif/ahb/ahb.c | 1643 +++ + .../wlan/gen2/os/linux/hif/ahb/arm.c | 31 + + .../wlan/gen2/os/linux/hif/ahb/include/hif.h | 340 + + .../gen2/os/linux/hif/ahb/include/hif_gdma.h | 154 + + .../gen2/os/linux/hif/ahb/include/hif_pdma.h | 141 + + .../os/linux/hif/ahb/include/mtk_porting.h | 91 + + .../gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c | 480 + + .../wlan/gen2/os/linux/include/gl_cfg80211.h | 341 + + .../wlan/gen2/os/linux/include/gl_kal.h | 1565 +++ + .../wlan/gen2/os/linux/include/gl_os.h | 1270 ++ + .../wlan/gen2/os/linux/include/gl_p2p_ioctl.h | 743 ++ + .../wlan/gen2/os/linux/include/gl_p2p_kal.h | 243 + + .../wlan/gen2/os/linux/include/gl_p2p_os.h | 242 + + .../wlan/gen2/os/linux/include/gl_rst.h | 133 + + .../wlan/gen2/os/linux/include/gl_sec.h | 21 + + .../wlan/gen2/os/linux/include/gl_typedef.h | 298 + + .../wlan/gen2/os/linux/include/gl_vendor.h | 619 + + .../wlan/gen2/os/linux/include/gl_wext.h | 357 + + .../wlan/gen2/os/linux/include/gl_wext_priv.h | 402 + + .../wlan/gen2/os/linux/platform.c | 542 + + .../connectivity/wlan/gen2/os/version.h | 190 + + drivers/misc/mediatek/include/mt-plat/aee.h | 284 + + .../misc/mediatek/include/mt-plat/mrdump.h | 204 + + .../mt-plat/mt7622/include/mach/mtk_thermal.h | 295 + + .../mt8127/include/mach/mt_freqhopping.h | 159 + + .../mt8127/include/mach/mt_spm_mtcmos.h | 37 + + .../mt8127/include/mach/mtk_boot_share_page.h | 40 + + .../mt-plat/mt8127/include/mach/mtk_thermal.h | 301 + + .../misc/mediatek/include/mt-plat/mt_sched.h | 34 + + .../misc/mediatek/include/mt-plat/mtk_io.h | 23 + + .../misc/mediatek/include/mt-plat/mtk_lpae.h | 62 + + .../include/mt-plat/mtk_mdm_monitor.h | 42 + + .../include/mt-plat/mtk_platform_debug.h | 28 + + .../include/mt-plat/mtk_ram_console.h | 162 + + .../misc/mediatek/include/mt-plat/mtk_rtc.h | 85 + + .../include/mt-plat/mtk_thermal_ext_control.h | 69 + + .../include/mt-plat/mtk_thermal_monitor.h | 102 + + .../include/mt-plat/mtk_thermal_platform.h | 114 + + .../include/mt-plat/mtk_thermal_trace.h | 47 + + .../include/mt-plat/mtk_thermal_typedefs.h | 241 + + .../include/mt-plat/mtk_wcn_cmb_stub.h | 185 + + .../misc/mediatek/include/mt-plat/rt-regmap.h | 291 + + .../mediatek/include/mt-plat/sync_write.h | 88 + + .../misc/mediatek/include/mt-plat/wakelock.h | 67 + + drivers/soc/mediatek/mtk-pmic-wrap.c | 16 + + drivers/watchdog/mtk_wdt.c | 363 +- + include/linux/wakelock.h | 67 + + include/net/cfg80211.h | 2 +- + include/net/genetlink.h | 45 + + include/soc/mediatek/pmic_wrap.h | 19 + + include/uapi/linux/genetlink.h | 1 + + 294 files changed, 214777 insertions(+), 12 deletions(-) + create mode 100644 drivers/misc/mediatek/Kconfig + create mode 100644 drivers/misc/mediatek/Makefile + create mode 100644 drivers/misc/mediatek/btif/Kconfig + create mode 100644 drivers/misc/mediatek/btif/Makefile + create mode 100644 drivers/misc/mediatek/btif/common/Makefile + create mode 100644 drivers/misc/mediatek/btif/common/btif_dma_plat.c + create mode 100644 drivers/misc/mediatek/btif/common/btif_plat.c + create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif.h + create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h + create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif.c + create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif_exp.c + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/plat_common.h + create mode 100644 drivers/misc/mediatek/connectivity/Kconfig + create mode 100644 drivers/misc/mediatek/connectivity/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/aee.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mrdump.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt_sched.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_io.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_lpae.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_rtc.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/rt-regmap.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/sync_write.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/wakelock.h + create mode 100644 include/linux/wakelock.h + create mode 100644 include/soc/mediatek/pmic_wrap.h + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 5361d48a2240..bdfd22bbf7fd 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -263,6 +263,8 @@ + compatible = "mediatek,mt7623-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x100>; ++ interrupts = ; ++ #reset-cells = <1>; + }; + + timer: timer@10008000 { +@@ -486,6 +488,29 @@ + nvmem-cell-names = "calibration-data"; + }; + ++ btif_tx: btif_tx@11000780 { ++ compatible = "mediatek,btif_tx"; ++ reg = <0 0x11000780 0 0x80>; ++ interrupts = ; ++ status = "okay"; ++ }; ++ ++ btif_rx: btif_rx@11000800 { ++ compatible = "mediatek,btif_rx"; ++ reg = <0 0x11000800 0 0x80>; ++ interrupts = ; ++ status = "okay"; ++ }; ++ ++ btif: btif@1100c000 { ++ compatible = "mediatek,btif"; ++ reg = <0 0x1100c000 0 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_BTIF>, <&pericfg CLK_PERI_AP_DMA>; ++ clock-names = "btifc", "apdmac"; ++ status = "okay"; ++ }; ++ + nandc: nfi@1100d000 { + compatible = "mediatek,mt7623-nfc", + "mediatek,mt2701-nfc"; +@@ -660,6 +685,29 @@ + status = "disabled"; + }; + ++ consys: consys@18070000 { ++ compatible = "mediatek,mt7623-consys"; ++ reg = <0 0x18070000 0 0x0200>, /*CONN_MCU_CONFIG_BASE */ ++ <0 0x10001000 0 0x1600>; /*TOPCKGEN_BASE */ ++ clocks = <&infracfg CLK_INFRA_CONNMCU>; ++ clock-names = "consysbus"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_CONN>; ++ interrupts = , /* BGF_EINT */ ++ ; /* WDT_EINT */ ++ resets = <&watchdog MT2701_TOPRGU_CONN_MCU_RST>; ++ reset-names = "connsys"; ++ status="disabled"; ++ }; ++ ++ wifi:wifi@180f0000 { ++ compatible = "mediatek,mt7623-wifi", ++ "mediatek,wifi"; ++ reg = <0 0x180f0000 0 0x005c>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_AP_DMA>; ++ clock-names = "wifi-dma"; ++ }; ++ + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 9ea67ea28a47..0f4c356ebaec 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -57,6 +57,18 @@ + }; + }; + ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ consys-reserve-memory { ++ compatible = "mediatek,consys-reserve-memory"; ++ no-map; ++ size = <0 0x100000>; ++ alignment = <0 0x100000>; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; +@@ -439,6 +451,24 @@ + ; + }; + }; ++ ++ consys_pins_default: consys_pins_default { ++ adie { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ bias-disable; ++ }; ++ }; + }; + + &pwm { +@@ -472,9 +502,239 @@ + default-state = "off"; + }; + }; ++ ++ mt6323regulator: mt6323regulator{ ++ compatible = "mediatek,mt6323-regulator"; ++ ++ mt6323_vproc_reg: buck_vproc{ ++ regulator-name = "vproc"; ++ regulator-min-microvolt = < 700000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vsys_reg: buck_vsys{ ++ regulator-name = "vsys"; ++ regulator-min-microvolt = <1400000>; ++ regulator-max-microvolt = <2987500>; ++ regulator-ramp-delay = <25000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vpa_reg: buck_vpa{ ++ regulator-name = "vpa"; ++ regulator-min-microvolt = < 500000>; ++ regulator-max-microvolt = <3650000>; ++ }; ++ ++ mt6323_vtcxo_reg: ldo_vtcxo{ ++ regulator-name = "vtcxo"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-enable-ramp-delay = <90>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vcn28_reg: ldo_vcn28{ ++ regulator-name = "vcn28"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-enable-ramp-delay = <185>; ++ }; ++ ++ mt6323_vcn33_bt_reg: ldo_vcn33_bt{ ++ regulator-name = "vcn33_bt"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3600000>; ++ regulator-enable-ramp-delay = <185>; ++ }; ++ ++ mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{ ++ regulator-name = "vcn33_wifi"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3600000>; ++ regulator-enable-ramp-delay = <185>; ++ }; ++ ++ mt6323_va_reg: ldo_va{ ++ regulator-name = "va"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-enable-ramp-delay = <216>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vcama_reg: ldo_vcama{ ++ regulator-name = "vcama"; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vio28_reg: ldo_vio28{ ++ regulator-name = "vio28"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-enable-ramp-delay = <216>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vusb_reg: ldo_vusb{ ++ regulator-name = "vusb"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <216>; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vmc_reg: ldo_vmc{ ++ regulator-name = "vmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <36>; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vmch_reg: ldo_vmch{ ++ regulator-name = "vmch"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <36>; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vemc3v3_reg: ldo_vemc3v3{ ++ regulator-name = "vemc3v3"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <36>; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vgp1_reg: ldo_vgp1{ ++ regulator-name = "vgp1"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vgp2_reg: ldo_vgp2{ ++ regulator-name = "vgp2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vgp3_reg: ldo_vgp3{ ++ regulator-name = "vgp3"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vcn18_reg: ldo_vcn18{ ++ regulator-name = "vcn18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vsim1_reg: ldo_vsim1{ ++ regulator-name = "vsim1"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vsim2_reg: ldo_vsim2{ ++ regulator-name = "vsim2"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vrtc_reg: ldo_vrtc{ ++ regulator-name = "vrtc"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vcamaf_reg: ldo_vcamaf{ ++ regulator-name = "vcamaf"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vibr_reg: ldo_vibr{ ++ regulator-name = "vibr"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <36>; ++ }; ++ ++ mt6323_vrf18_reg: ldo_vrf18{ ++ regulator-name = "vrf18"; ++ regulator-min-microvolt = <1825000>; ++ regulator-max-microvolt = <1825000>; ++ regulator-enable-ramp-delay = <187>; ++ }; ++ ++ mt6323_vm_reg: ldo_vm{ ++ regulator-name = "vm"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-enable-ramp-delay = <216>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vio18_reg: ldo_vio18{ ++ regulator-name = "vio18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-enable-ramp-delay = <216>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ mt6323_vcamd_reg: ldo_vcamd{ ++ regulator-name = "vcamd"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ ++ mt6323_vcamio_reg: ldo_vcamio{ ++ regulator-name = "vcamio"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-enable-ramp-delay = <216>; ++ }; ++ }; ++ + }; + }; + ++&consys { ++ mediatek,pwrap-regmap = <&pwrap>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&consys_pins_default>; ++ vcn18-supply = <&mt6323_vcn18_reg>; ++ vcn28-supply = <&mt6323_vcn28_reg>; ++ vcn33_bt-supply = <&mt6323_vcn33_bt_reg>; ++ vcn33_wifi-supply = <&mt6323_vcn33_wifi_reg>; ++ status = "okay"; ++}; ++ + &spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins_a>; +@@ -515,3 +775,6 @@ + status = "okay"; + }; + ++&watchdog { ++ status = "okay"; ++}; +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 8136dc7e863d..11ef310bd1c7 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -518,4 +518,5 @@ source "drivers/misc/mic/Kconfig" + source "drivers/misc/genwqe/Kconfig" + source "drivers/misc/echo/Kconfig" + source "drivers/misc/cxl/Kconfig" ++source "drivers/misc/mediatek/Kconfig" + endmenu +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index ad0e64fdba34..c25aa08d17f5 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -74,3 +74,5 @@ OBJCOPYFLAGS_lkdtm_rodata_objcopy.o := \ + targets += lkdtm_rodata.o lkdtm_rodata_objcopy.o + $(obj)/lkdtm_rodata_objcopy.o: $(obj)/lkdtm_rodata.o FORCE + $(call if_changed,objcopy) ++ ++obj-$(CONFIG_MTK_COMBO) += mediatek/ +diff --git a/drivers/misc/mediatek/Kconfig b/drivers/misc/mediatek/Kconfig +new file mode 100644 +index 000000000000..4829a6598c7a +--- /dev/null ++++ b/drivers/misc/mediatek/Kconfig +@@ -0,0 +1,11 @@ ++menu "Mediatek Peripherals " ++ ++config MTK_PLATFORM ++ string "MTK platform name" ++source "drivers/misc/mediatek/btif/Kconfig" ++ ++menu "Modem & Connectivity related configs" ++source "drivers/misc/mediatek/connectivity/Kconfig" ++endmenu ++ ++endmenu # CONN +diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile +new file mode 100644 +index 000000000000..5e7f06db38f2 +--- /dev/null ++++ b/drivers/misc/mediatek/Makefile +@@ -0,0 +1,19 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++#$(call all-subdir-src-or-makefile) ++subdir-ccflags-y += -Werror ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ ++ ++obj-$(CONFIG_MTK_COMBO) += connectivity/ ++obj-$(CONFIG_MTK_BTIF) += btif/ +diff --git a/drivers/misc/mediatek/btif/Kconfig b/drivers/misc/mediatek/btif/Kconfig +new file mode 100644 +index 000000000000..908898bd95c3 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/Kconfig +@@ -0,0 +1,4 @@ ++config MTK_BTIF ++ tristate"MediaTek BTIF Driver" ++ help ++ MTK connectivity BTIF driver for A/D die +diff --git a/drivers/misc/mediatek/btif/Makefile b/drivers/misc/mediatek/btif/Makefile +new file mode 100644 +index 000000000000..2be3ab66f426 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/Makefile +@@ -0,0 +1,33 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++# BTIF driver for AD DIE ++# If KERNELRELEASE is defined, we've been invoked from the ++# kernel build system and can use its language. ++ifneq ($(KERNELRELEASE),) ++ #subdir-ccflags-y can be used in 2.6.34 in the future ++ MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) ++ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include ++ subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/include/mach ++ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat ++ ++ obj-y += common/ ++ ++# Otherwise we were called directly from the command ++# line; invoke the kernel build system. ++else ++ KERNELDIR ?= /lib/modules/$(shell uname -r)/build ++ PWD := $(shell pwd) ++default: ++ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ++endif +diff --git a/drivers/misc/mediatek/btif/common/Makefile b/drivers/misc/mediatek/btif/common/Makefile +new file mode 100644 +index 000000000000..61e9d4ea9e89 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/Makefile +@@ -0,0 +1,31 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++# BTIF driver for AD DIE ++# If KERNELRELEASE is defined, we've been invoked from the ++# kernel build system and can use its language. ++ifneq ($(KERNELRELEASE),) ++ ccflags-y += -I$(src)/inc ++ ccflags-y += -I$(src)/plat_inc ++ ++ obj-y += btif.o ++ btif-y := mtk_btif.o mtk_btif_exp.o btif_dma_plat.o btif_plat.o ++ ++# Otherwise we were called directly from the command ++# line; invoke the kernel build system. ++else ++ KERNELDIR ?= /lib/modules/$(shell uname -r)/build ++ PWD := $(shell pwd) ++default: ++ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ++endif +diff --git a/drivers/misc/mediatek/btif/common/btif_dma_plat.c b/drivers/misc/mediatek/btif/common/btif_dma_plat.c +new file mode 100644 +index 000000000000..58be46927953 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/btif_dma_plat.c +@@ -0,0 +1,1436 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF-DMA" ++ ++#include "btif_dma_priv.h" ++ ++#define DMA_USER_ID "btif_driver" ++ ++/************************************Global variable***********************************/ ++ ++static MTK_BTIF_DMA_VFIFO mtk_tx_dma_vfifo = { ++ .vfifo = { ++ .p_vir_addr = NULL, ++ .phy_addr = 0, ++ .vfifo_size = TX_DMA_VFF_SIZE, ++ .thre = DMA_TX_THRE(TX_DMA_VFF_SIZE), ++ }, ++ .wpt = 0, ++ .last_wpt_wrap = 0, ++ .rpt = 0, ++ .last_rpt_wrap = 0, ++}; ++ ++static MTK_BTIF_IRQ_STR mtk_btif_tx_dma_irq = { ++ .name = "mtk btif tx dma irq", ++ .is_irq_sup = true, ++ .reg_flag = false, ++#ifdef CONFIG_OF ++ .irq_flags = IRQF_TRIGGER_NONE, ++#else ++ .irq_id = MT_DMA_BTIF_TX_IRQ_ID, ++ .sens_type = IRQ_SENS_LVL, ++ .lvl_type = IRQ_LVL_LOW, ++#endif ++ .p_irq_handler = NULL, ++}; ++ ++static MTK_BTIF_DMA_VFIFO mtk_rx_dma_vfifo = { ++ .vfifo = { ++ .p_vir_addr = NULL, ++ .phy_addr = 0, ++ .vfifo_size = RX_DMA_VFF_SIZE, ++ .thre = DMA_RX_THRE(RX_DMA_VFF_SIZE), ++ }, ++ ++ .wpt = 0, ++ .last_wpt_wrap = 0, ++ .rpt = 0, ++ .last_rpt_wrap = 0, ++}; ++ ++static MTK_BTIF_IRQ_STR mtk_btif_rx_dma_irq = { ++ .name = "mtk btif rx dma irq", ++ .is_irq_sup = true, ++ .reg_flag = false, ++#ifdef CONFIG_OF ++ .irq_flags = IRQF_TRIGGER_NONE, ++#else ++ .irq_id = MT_DMA_BTIF_RX_IRQ_ID, ++ .sens_type = IRQ_SENS_LVL, ++ .lvl_type = IRQ_LVL_LOW, ++#endif ++ .p_irq_handler = NULL, ++}; ++ ++static MTK_DMA_INFO_STR mtk_btif_tx_dma = { ++#ifndef CONFIG_OF ++ .base = AP_DMA_BASE + BTIF_TX_DMA_OFFSET, ++#endif ++ .dir = DMA_DIR_TX, ++ .p_irq = &mtk_btif_tx_dma_irq, ++ .p_vfifo = &(mtk_tx_dma_vfifo.vfifo), ++}; ++ ++static MTK_DMA_INFO_STR mtk_btif_rx_dma = { ++#ifndef CONFIG_OF ++ .base = AP_DMA_BASE + BTIF_RX_DMA_OFFSET, ++#endif ++ .dir = DMA_DIR_RX, ++ .p_irq = &mtk_btif_rx_dma_irq, ++ .p_vfifo = &(mtk_rx_dma_vfifo.vfifo), ++}; ++ ++static spinlock_t g_clk_cg_spinlock; /*dma clock's spinlock */ ++ ++/************************************Function declearation***********************************/ ++static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info); ++static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info); ++static int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_DMA_CTRL ctrl_id); ++static int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_DMA_CTRL ctrl_id); ++static int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); ++static int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); ++static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag); ++static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag); ++static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info); ++static int _btif_dma_dump_dbg_reg(void); ++static void hal_btif_tx_dma_vff_set_for_4g(void); ++static void hal_btif_rx_dma_vff_set_for_4g(void); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ier_ctrl ++* DESCRIPTION ++* BTIF Tx DMA's interrupt enable/disable ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* enable [IN] control if tx interrupt enabled or not ++* dma_dir [IN] DMA's direction ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_receive_data ++* DESCRIPTION ++* receive data from btif module in DMA polling mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++static int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, ++ const unsigned int max_len); ++ ++/************************************Function***********************************/ ++#endif ++ ++#ifdef CONFIG_OF ++static void hal_dma_set_default_setting(ENUM_DMA_DIR dma_dir) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = {0, 0, 0}; ++ unsigned int phy_base; ++ ++ if (dma_dir == DMA_DIR_RX) { ++ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_rx"); ++ if (node) { ++ mtk_btif_rx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); ++ /*fixme, be compitable arch 64bits*/ ++ mtk_btif_rx_dma.base = (unsigned long)of_iomap(node, 0); ++ BTIF_INFO_FUNC("get rx_dma irq(%d),register base(0x%lx)\n", ++ mtk_btif_rx_dma.p_irq->irq_id, mtk_btif_rx_dma.base); ++ } else { ++ BTIF_ERR_FUNC("get rx_dma device node fail\n"); ++ } ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); ++ } else { ++ mtk_btif_rx_dma.p_irq->irq_flags = irq_info[2]; ++ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", ++ mtk_btif_rx_dma.p_irq->irq_flags); ++ } ++ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { ++ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", ++ dma_dir); ++ } else { ++ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", ++ dma_dir, (unsigned int)phy_base); ++ } ++ } else if (dma_dir == DMA_DIR_TX) { ++ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_tx"); ++ if (node) { ++ mtk_btif_tx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); ++ /*fixme, be compitable arch 64bits*/ ++ mtk_btif_tx_dma.base = (unsigned long)of_iomap(node, 0); ++ BTIF_INFO_FUNC("get tx_dma irq(%d),register base(0x%lx)\n", ++ mtk_btif_tx_dma.p_irq->irq_id, mtk_btif_tx_dma.base); ++ } else { ++ BTIF_ERR_FUNC("get tx_dma device node fail\n"); ++ } ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); ++ } else { ++ mtk_btif_tx_dma.p_irq->irq_flags = irq_info[2]; ++ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", ++ mtk_btif_tx_dma.p_irq->irq_flags); ++ } ++ ++ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { ++ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", ++ dma_dir); ++ } else { ++ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", ++ dma_dir, (unsigned int)phy_base); ++ } ++ } ++ ++} ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_info_get ++* DESCRIPTION ++* get btif tx dma channel's information ++* PARAMETERS ++* dma_dir [IN] DMA's direction ++* RETURNS ++* pointer to btif dma's information structure ++*****************************************************************************/ ++P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir) ++{ ++ P_MTK_DMA_INFO_STR p_dma_info = NULL; ++ ++ BTIF_TRC_FUNC(); ++#ifdef CONFIG_OF ++ hal_dma_set_default_setting(dma_dir); ++#endif ++ if (dma_dir == DMA_DIR_RX) ++ /*Rx DMA*/ ++ p_dma_info = &mtk_btif_rx_dma; ++ else if (dma_dir == DMA_DIR_TX) ++ /*Tx DMA*/ ++ p_dma_info = &mtk_btif_tx_dma; ++ else ++ /*print error log*/ ++ BTIF_ERR_FUNC("invalid DMA dir (%d)\n", dma_dir); ++ spin_lock_init(&g_clk_cg_spinlock); ++ BTIF_TRC_FUNC(); ++ return p_dma_info; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of DMA module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag) ++{ ++/*In MTK DMA BTIF channel, there's only one global CG on AP_DMA, no sub channel's CG bit*/ ++/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ ++ int i_ret = 0; ++ unsigned long irq_flag = 0; ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ static atomic_t s_clk_ref = ATOMIC_INIT(0); ++#else ++ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; ++#endif ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_CTL ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++ if (flag == CLK_OUT_ENABLE) { ++ if (atomic_inc_return(&s_clk_ref) == 1) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); ++ i_ret = clk_enable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++ if (atomic_dec_return(&s_clk_ref) == 0) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif_apdma) calling\n"); ++ clk_disable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ ++#else ++ ++ if (status == flag) { ++ i_ret = 0; ++ BTIF_DBG_FUNC("dma clock already %s\n", ++ CLK_OUT_ENABLE == ++ status ? "enabled" : "disabled"); ++ } else { ++ if (flag == CLK_OUT_ENABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); ++ i_ret = clk_enable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable_unprepare(clk_btif_apdma) calling\n"); ++ clk_disable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ } ++#endif ++ ++#else ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++#else ++ ++ status = flag; ++#endif ++ ++ i_ret = 0; ++#endif ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#else ++ ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++ BTIF_DBG_FUNC("DMA's clock is %s\n", (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) ? "off" : "on"); ++#endif ++ return i_ret; ++} ++ ++int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ int i_ret = 0; ++ unsigned int dat = 0; ++ unsigned long base = p_dma_info->base; ++ unsigned long addr_h = 0; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ ++ if (p_dma_info->dir == DMA_DIR_RX) { ++ /*Rx DMA*/ ++ /*do hardware reset*/ ++ /* BTIF_SET_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ ++ /* BTIF_CLR_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ ++ BTIF_SET_BIT(RX_DMA_RST(base), DMA_WARM_RST); ++ do { ++ dat = BTIF_READ32(RX_DMA_EN(base)); ++ } while (0x01 & dat); ++ /*write vfifo base address to VFF_ADDR*/ ++ btif_reg_sync_writel(p_vfifo->phy_addr, RX_DMA_VFF_ADDR(base)); ++ if (enable_4G()) ++ hal_btif_rx_dma_vff_set_for_4g(); ++ else { ++ addr_h = p_vfifo->phy_addr >> 16; ++ addr_h = addr_h >> 16; ++ btif_reg_sync_writel(addr_h, RX_DMA_VFF_ADDR_H(base)); ++ } ++ /*write vfifo length to VFF_LEN*/ ++ btif_reg_sync_writel(p_vfifo->vfifo_size, RX_DMA_VFF_LEN(base)); ++ /*write wpt to VFF_WPT*/ ++ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, ++ RX_DMA_VFF_WPT(base)); ++ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, ++ RX_DMA_VFF_RPT(base)); ++ /*write vff_thre to VFF_THRESHOLD*/ ++ btif_reg_sync_writel(p_vfifo->thre, RX_DMA_VFF_THRE(base)); ++ /*clear Rx DMA's interrupt status*/ ++ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), ++ RX_DMA_INT_DONE | RX_DMA_INT_THRE); ++ ++ /*enable Rx IER by default*/ ++ btif_rx_dma_ier_ctrl(p_dma_info, true); ++ } else { ++/*Tx DMA*/ ++/*do hardware reset*/ ++/* BTIF_SET_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ ++/* BTIF_CLR_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ ++ BTIF_SET_BIT(TX_DMA_RST(base), DMA_WARM_RST); ++ do { ++ dat = BTIF_READ32(TX_DMA_EN(base)); ++ } while (0x01 & dat); ++/*write vfifo base address to VFF_ADDR*/ ++ btif_reg_sync_writel(p_vfifo->phy_addr, TX_DMA_VFF_ADDR(base)); ++ if (enable_4G()) ++ hal_btif_tx_dma_vff_set_for_4g(); ++ else { ++ addr_h = p_vfifo->phy_addr >> 16; ++ addr_h = addr_h >> 16; ++ btif_reg_sync_writel(addr_h, TX_DMA_VFF_ADDR_H(base)); ++ } ++/*write vfifo length to VFF_LEN*/ ++ btif_reg_sync_writel(p_vfifo->vfifo_size, TX_DMA_VFF_LEN(base)); ++/*write wpt to VFF_WPT*/ ++ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, ++ TX_DMA_VFF_WPT(base)); ++ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, ++ TX_DMA_VFF_RPT(base)); ++/*write vff_thre to VFF_THRESHOLD*/ ++ btif_reg_sync_writel(p_vfifo->thre, TX_DMA_VFF_THRE(base)); ++ ++ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); ++ ++ hal_btif_dma_ier_ctrl(p_dma_info, false); ++ } ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ctrl ++* DESCRIPTION ++* enable/disable Tx DMA channel ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* ctrl_id [IN] enable/disable ID ++* RETURNS ++* 0 means success; negative means fail ++*****************************************************************************/ ++int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) ++{ ++ unsigned int i_ret = -1; ++ ENUM_DMA_DIR dir = p_dma_info->dir; ++ ++ if (dir == DMA_DIR_RX) ++ i_ret = btif_rx_dma_ctrl(p_dma_info, ctrl_id); ++ else if (dir == DMA_DIR_TX) ++ i_ret = btif_tx_dma_ctrl(p_dma_info, ctrl_id); ++ else { ++ /*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid dma ctrl id (%d)\n", ctrl_id); ++ i_ret = ERR_INVALID_PAR; ++ } ++ return i_ret; ++} ++ ++int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ dma_rx_buf_write rx_cb) ++{ ++ if (p_dma_info->rx_cb != NULL) { ++ BTIF_DBG_FUNC ++ ("rx_cb already registered, replace (0x%p) with (0x%p)\n", ++ p_dma_info->rx_cb, rx_cb); ++ } ++ p_dma_info->rx_cb = rx_cb; ++ return 0; ++} ++ ++int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int dat; ++ ++ BTIF_TRC_FUNC(); ++ if (ctrl_id == DMA_CTRL_DISABLE) { ++ /*if write 0 to EN bit, DMA will be stopped imediately*/ ++ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ ++ /*BTIF_CLR_BIT(TX_DMA_EN(base), DMA_EN_BIT);*/ ++ BTIF_SET_BIT(TX_DMA_STOP(base), DMA_STOP_BIT); ++ do { ++ dat = BTIF_READ32(TX_DMA_STOP(base)); ++ } while (0x1 & dat); ++ BTIF_DBG_FUNC("BTIF Tx DMA disabled,EN(0x%x),STOP(0x%x)\n", ++ BTIF_READ32(TX_DMA_EN(base)), BTIF_READ32(TX_DMA_STOP(base))); ++ i_ret = 0; ++ } else if (ctrl_id == DMA_CTRL_ENABLE) { ++ BTIF_SET_BIT(TX_DMA_EN(base), DMA_EN_BIT); ++ BTIF_DBG_FUNC("BTIF Tx DMA enabled\n"); ++ i_ret = 0; ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); ++ i_ret = ERR_INVALID_PAR; ++ } ++ BTIF_TRC_FUNC(); ++ return i_ret; ++} ++ ++int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int dat; ++ ++ BTIF_TRC_FUNC(); ++ ++ if (ctrl_id == DMA_CTRL_DISABLE) { ++ /*if write 0 to EN bit, DMA will be stopped imediately*/ ++ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ ++ /*BTIF_CLR_BIT(RX_DMA_EN(base), DMA_EN_BIT);*/ ++ BTIF_SET_BIT(RX_DMA_STOP(base), DMA_STOP_BIT); ++ do { ++ dat = BTIF_READ32(RX_DMA_STOP(base)); ++ } while (0x1 & dat); ++ BTIF_DBG_FUNC("BTIF Rx DMA disabled,EN(0x%x),STOP(0x%x)\n", ++ BTIF_READ32(RX_DMA_EN(base)), BTIF_READ32(RX_DMA_STOP(base))); ++ i_ret = 0; ++ } else if (ctrl_id == DMA_CTRL_ENABLE) { ++ BTIF_SET_BIT(RX_DMA_EN(base), DMA_EN_BIT); ++ BTIF_DBG_FUNC("BTIF Rx DMA enabled\n"); ++ i_ret = 0; ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); ++ i_ret = ERR_INVALID_PAR; ++ } ++ BTIF_TRC_FUNC(); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_vfifo_reset ++* DESCRIPTION ++* reset tx virtual fifo information, except memory information ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ unsigned int i_ret = -1; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ ++ BTIF_TRC_FUNC(); ++ p_mtk_dma_vfifo->rpt = 0; ++ p_mtk_dma_vfifo->last_rpt_wrap = 0; ++ p_mtk_dma_vfifo->wpt = 0; ++ p_mtk_dma_vfifo->last_wpt_wrap = 0; ++ BTIF_TRC_FUNC(); ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ier_ctrl ++* DESCRIPTION ++* BTIF Tx DMA's interrupt enable/disable ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* enable [IN] control if tx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) ++{ ++ unsigned int i_ret = -1; ++ ENUM_DMA_DIR dir = p_dma_info->dir; ++ ++ if (dir == DMA_DIR_RX) { ++ i_ret = btif_rx_dma_ier_ctrl(p_dma_info, en); ++ } else if (dir == DMA_DIR_TX) { ++ i_ret = btif_tx_dma_ier_ctrl(p_dma_info, en); ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid DMA dma dir (%d)\n", dir); ++ i_ret = ERR_INVALID_PAR; ++ } ++ ++ return i_ret; ++} ++ ++int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ ++ BTIF_TRC_FUNC(); ++ if (!en) { ++ BTIF_CLR_BIT(RX_DMA_INT_EN(base), ++ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); ++ } else { ++ BTIF_SET_BIT(RX_DMA_INT_EN(base), ++ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); ++ } ++ i_ret = 0; ++ BTIF_TRC_FUNC(); ++ ++ return i_ret; ++} ++ ++int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ ++ BTIF_TRC_FUNC(); ++ if (!en) ++ BTIF_CLR_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); ++ else ++ BTIF_SET_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); ++ i_ret = 0; ++ BTIF_TRC_FUNC(); ++ ++ return i_ret; ++} ++ ++static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ int tx_irq_done = 0; ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++/*if we enable this clock reference couner, just return , because when enter IRQ handler, DMA's clock will be opened*/ ++ tx_irq_done = 1; ++#else ++ unsigned long flag = 0; ++ unsigned long base = p_dma_info->base; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); ++ tx_irq_done = ((BTIF_READ32(TX_DMA_INT_FLAG(base)) & TX_DMA_INT_FLAG_MASK) == 0) ? 1 : 0; ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++#endif ++ return tx_irq_done; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_irq_handler ++* DESCRIPTION ++* lower level tx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++#define MAX_CONTINIOUS_TIMES 512 ++ unsigned int i_ret = -1; ++ unsigned int valid_size = 0; ++ unsigned int vff_len = 0; ++ unsigned int left_len = 0; ++ unsigned long base = p_dma_info->base; ++ static int flush_irq_counter; ++ static struct timeval start_timer; ++ static struct timeval end_timer; ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); ++ ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ BTIF_ERR_FUNC ++ ("%s: clock is off before irq status clear done!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*check if Tx VFF Left Size equal to VFIFO size or not*/ ++ vff_len = BTIF_READ32(TX_DMA_VFF_LEN(base)); ++ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); ++ left_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); ++ if (flush_irq_counter == 0) ++ do_gettimeofday(&start_timer); ++ if ((valid_size > 0) && (valid_size < 8)) { ++ i_ret = _tx_dma_flush(p_dma_info); ++ flush_irq_counter++; ++ if (flush_irq_counter >= MAX_CONTINIOUS_TIMES) { ++ do_gettimeofday(&end_timer); ++/* ++ * when btif tx fifo cannot accept any data and counts of bytes left in tx vfifo < 8 for a while ++ * we assume that btif cannot send data for a long time ++ * in order not to generate interrupt continiously, which may effect system's performance. ++ * we clear tx flag and disable btif tx interrupt ++ */ ++/*clear interrupt flag*/ ++ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), ++ TX_DMA_INT_FLAG_MASK); ++/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ ++ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); ++ BTIF_ERR_FUNC ++ ("**********************ERROR, ERROR, ERROR**************************\n"); ++ BTIF_ERR_FUNC ++ ("BTIF Tx IRQ happened %d times (continiously), between %d.%d and %d.%d\n", ++ MAX_CONTINIOUS_TIMES, start_timer.tv_sec, ++ start_timer.tv_usec, end_timer.tv_usec, ++ end_timer.tv_usec); ++ } ++ } else if (vff_len == left_len) { ++ flush_irq_counter = 0; ++/*clear interrupt flag*/ ++ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); ++/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ ++ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); ++ } else { ++#if 0 ++ BTIF_ERR_FUNC ++ ("**********************WARNING**************************\n"); ++ BTIF_ERR_FUNC("invalid irq condition, dump register\n"); ++ hal_dma_dump_reg(p_dma_info, REG_TX_DMA_ALL); ++#endif ++ BTIF_DBG_FUNC ++ ("superious IRQ occurs, vff_len(%d), valid_size(%d), left_len(%d)\n", ++ vff_len, valid_size, left_len); ++ } ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_send_data ++* DESCRIPTION ++* send data through btif in DMA mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, ++ const unsigned char *p_buf, const unsigned int buf_len) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ unsigned int len_to_send = buf_len; ++ unsigned int ava_len = 0; ++ unsigned int wpt = 0; ++ unsigned int last_wpt_wrap = 0; ++ unsigned int vff_size = 0; ++ unsigned char *p_data = (unsigned char *)p_buf; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ ++ BTIF_TRC_FUNC(); ++ if ((p_buf == NULL) || (buf_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid parameters, p_buf:0x%p, buf_len:%d\n", ++ p_buf, buf_len); ++ return i_ret; ++ } ++/*check if tx dma in flush operation? if yes, should wait until DMA finish flush operation*/ ++/*currently uplayer logic will make sure this pre-condition*/ ++/*disable Tx IER, in case Tx irq happens, flush bit may be set in irq handler*/ ++ btif_tx_dma_ier_ctrl(p_dma_info, false); ++ ++ vff_size = p_mtk_vfifo->vfifo.vfifo_size; ++ ava_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); ++ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_MASK; ++ last_wpt_wrap = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_WRAP; ++ ++/* ++ * copy data to vFIFO, Note: ava_len should always large than buf_len, ++ * otherwise common logic layer will not call hal_dma_send_data ++ */ ++ if (buf_len > ava_len) { ++ BTIF_ERR_FUNC ++ ("length to send:(%d) < length available(%d), abnormal!!!---!!!\n", ++ buf_len, ava_len); ++ WARN_ON(buf_len > ava_len); /* this will cause kernel panic */ ++ } ++ ++ len_to_send = buf_len < ava_len ? buf_len : ava_len; ++ if (len_to_send + wpt >= vff_size) { ++ unsigned int tail_len = vff_size - wpt; ++ ++ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), p_data, tail_len); ++ p_data += tail_len; ++ memcpy(p_mtk_vfifo->vfifo.p_vir_addr, ++ p_data, len_to_send - tail_len); ++/*make sure all data write to memory area tx vfifo locates*/ ++ mb(); ++ ++/*calculate WPT*/ ++ wpt = wpt + len_to_send - vff_size; ++ last_wpt_wrap ^= DMA_WPT_WRAP; ++ } else { ++ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), ++ p_data, len_to_send); ++/*make sure all data write to memory area tx vfifo locates*/ ++ mb(); ++ ++/*calculate WPT*/ ++ wpt += len_to_send; ++ } ++ p_mtk_vfifo->wpt = wpt; ++ p_mtk_vfifo->last_wpt_wrap = last_wpt_wrap; ++ ++/*make sure tx dma is allowed(tx flush bit is not set) to use before update WPT*/ ++ if (hal_dma_is_tx_allow(p_dma_info)) { ++ /*make sure tx dma enabled*/ ++ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); ++ ++ /*update WTP to Tx DMA controller's control register*/ ++ btif_reg_sync_writel(wpt | last_wpt_wrap, TX_DMA_VFF_WPT(base)); ++ ++ if ((BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) < 8) && ++ (BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) > 0)) { ++ /* ++ * 0 < valid size in Tx vFIFO < 8 && TX Flush is not in process? ++ * if yes, set flush bit to DMA ++ */ ++ _tx_dma_flush(p_dma_info); ++ } ++ i_ret = len_to_send; ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("Tx DMA flush operation is in process, this case should never happen,", ++ "please check if tx operation is allowed before call this API\n"); ++/*if flush operation is in process , we will return 0*/ ++ i_ret = 0; ++ } ++ ++/*Enable Tx IER*/ ++ btif_tx_dma_ier_ctrl(p_dma_info, true); ++ ++ BTIF_TRC_FUNC(); ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ bool b_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); ++ unsigned int inter_size = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); ++ unsigned int tx_done = is_tx_dma_irq_finish_done(p_dma_info); ++ ++/* ++ * only when virtual FIFO valid size and Tx channel internal buffer size are both becomes to be 0, ++ * we can identify tx operation finished ++ * confirmed with DE. ++ */ ++ if ((valid_size == 0) && (inter_size == 0) && (tx_done == 1)) { ++ b_ret = true; ++ BTIF_DBG_FUNC("DMA tx finished.\n"); ++ } else { ++ BTIF_DBG_FUNC ++ ("DMA tx is in process. vfifo valid size(%d), dma internal size (%d), tx_done(%d)\n", ++ valid_size, inter_size, tx_done); ++ b_ret = false; ++ } ++ ++ return b_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_get_ava_room ++* DESCRIPTION ++* get tx available room ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* available room size ++*****************************************************************************/ ++int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ ++/*read vFIFO's left size*/ ++ i_ret = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); ++ BTIF_DBG_FUNC("DMA tx ava room (%d).\n", i_ret); ++ if (i_ret == 0) ++ BTIF_INFO_FUNC("DMA tx vfifo is full.\n"); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_allow ++* DESCRIPTION ++* is tx operation allowed by DMA ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) ++#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) ++ ++ bool b_ret = false; ++ unsigned int wait_us = 8 / MIN_TX_MB; /*only ava length */ ++/*see if flush operation is in process*/ ++ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; ++ if (!b_ret) { ++ usleep_range(wait_us, 2 * wait_us); ++ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; ++ } ++ if (!b_ret) ++ BTIF_WARN_FUNC("btif tx dma is not allowed\n"); ++/*after Tx flush operation finished, HW will set DMA_EN back to 0 and stop DMA*/ ++ return b_ret; ++} ++ ++ ++/***************************************************************************** ++* FUNCTION ++* hal_rx_dma_irq_handler ++* DESCRIPTION ++* lower level rx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++ int i_ret = -1; ++ unsigned int valid_len = 0; ++ unsigned int wpt_wrap = 0; ++ unsigned int rpt_wrap = 0; ++ unsigned int wpt = 0; ++ unsigned int rpt = 0; ++ unsigned int tail_len = 0; ++ unsigned int real_len = 0; ++ unsigned long base = p_dma_info->base; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ dma_rx_buf_write rx_cb = p_dma_info->rx_cb; ++ unsigned char *p_vff_buf = NULL; ++ unsigned char *vff_base = p_vfifo->p_vir_addr; ++ unsigned int vff_size = p_vfifo->vfifo_size; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*disable DMA Rx IER*/ ++ hal_btif_dma_ier_ctrl(p_dma_info, false); ++ ++/*clear Rx DMA's interrupt status*/ ++ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), RX_DMA_INT_DONE | RX_DMA_INT_THRE); ++ ++ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); ++ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); ++ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); ++ if ((valid_len == 0) && (rpt == wpt)) { ++ BTIF_DBG_FUNC ++ ("rx interrupt, no data available in Rx DMA, wpt(0x%08x), rpt(0x%08x)\n", ++ rpt, wpt); ++ } ++ ++ i_ret = 0; ++ ++ while ((valid_len > 0) || (rpt != wpt)) { ++ rpt_wrap = rpt & DMA_RPT_WRAP; ++ wpt_wrap = wpt & DMA_WPT_WRAP; ++ rpt &= DMA_RPT_MASK; ++ wpt &= DMA_WPT_MASK; ++ ++/*calcaute length of available data in vFIFO*/ ++ if (wpt_wrap != p_mtk_vfifo->last_wpt_wrap) ++ real_len = wpt + vff_size - rpt; ++ else ++ real_len = wpt - rpt; ++ ++ if (rx_cb != NULL) { ++ tail_len = vff_size - rpt; ++ p_vff_buf = vff_base + rpt; ++ if (tail_len >= real_len) { ++ (*rx_cb) (p_dma_info, p_vff_buf, real_len); ++ } else { ++ (*rx_cb) (p_dma_info, p_vff_buf, tail_len); ++ p_vff_buf = vff_base; ++ (*rx_cb) (p_dma_info, p_vff_buf, real_len - ++ tail_len); ++ } ++ i_ret += real_len; ++ } else ++ BTIF_ERR_FUNC("no rx_cb found, please check your init process\n"); ++ mb(); ++ rpt += real_len; ++ if (rpt >= vff_size) { ++ /*read wrap bit should be revert*/ ++ rpt_wrap ^= DMA_RPT_WRAP; ++ rpt %= vff_size; ++ } ++ rpt |= rpt_wrap; ++/*record wpt, last_wpt_wrap, rpt, last_rpt_wrap*/ ++ p_mtk_vfifo->wpt = wpt; ++ p_mtk_vfifo->last_wpt_wrap = wpt_wrap; ++ ++ p_mtk_vfifo->rpt = rpt; ++ p_mtk_vfifo->last_rpt_wrap = rpt_wrap; ++ ++/*update rpt information to DMA controller*/ ++ btif_reg_sync_writel(rpt, RX_DMA_VFF_RPT(base)); ++ ++/*get vff valid size again and check if rx data is processed completely*/ ++ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); ++ ++ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); ++ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); ++ } ++ ++/*enable DMA Rx IER*/ ++ hal_btif_dma_ier_ctrl(p_dma_info, true); ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ ++ return i_ret; ++} ++ ++static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag) ++{ ++ int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int int_flag = 0; ++ unsigned int enable = 0; ++ unsigned int stop = 0; ++ unsigned int flush = 0; ++ unsigned int wpt = 0; ++ unsigned int rpt = 0; ++ unsigned int int_buf = 0; ++ unsigned int valid_size = 0; ++ /*unsigned long irq_flag = 0;*/ ++ ++#if defined(CONFIG_MTK_CLKMGR) ++ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++ int_flag = BTIF_READ32(TX_DMA_INT_FLAG(base)); ++ enable = BTIF_READ32(TX_DMA_EN(base)); ++ stop = BTIF_READ32(TX_DMA_STOP(base)); ++ flush = BTIF_READ32(TX_DMA_FLUSH(base)); ++ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)); ++ rpt = BTIF_READ32(TX_DMA_VFF_RPT(base)); ++ int_buf = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); ++ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ ++ BTIF_INFO_FUNC("DMA's clock is on\n"); ++ BTIF_INFO_FUNC("Tx DMA's base address: 0x%lx\n", base); ++ ++ if (flag == REG_TX_DMA_ALL) { ++ BTIF_INFO_FUNC("TX_EN(:0x%x\n", enable); ++ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); ++ BTIF_INFO_FUNC("TX_STOP:0x%x\n", stop); ++ BTIF_INFO_FUNC("TX_FLUSH:0x%x\n", flush); ++ BTIF_INFO_FUNC("TX_WPT:0x%x\n", wpt); ++ BTIF_INFO_FUNC("TX_RPT:0x%x\n", rpt); ++ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); ++ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); ++ BTIF_INFO_FUNC("INT_EN:0x%x\n", ++ BTIF_READ32(TX_DMA_INT_EN(base))); ++ BTIF_INFO_FUNC("TX_RST:0x%x\n", BTIF_READ32(TX_DMA_RST(base))); ++ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_ADDR(base))); ++ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_LEN(base))); ++ BTIF_INFO_FUNC("TX_THRE:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_THRE(base))); ++ BTIF_INFO_FUNC("W_INT_BUF_SIZE:0x%x\n", ++ BTIF_READ32(TX_DMA_W_INT_BUF_SIZE(base))); ++ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base))); ++ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", ++ BTIF_READ32(TX_DMA_DEBUG_STATUS(base))); ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC("unknown flag:%d\n", flag); ++ } ++ BTIF_INFO_FUNC("tx dma %s\n", (enable & DMA_EN_BIT) && ++ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); ++ BTIF_INFO_FUNC("data in tx dma is %s sent by HW\n", ++ ((wpt == rpt) && ++ (int_buf == 0)) ? "completely" : "not completely"); ++ ++ return i_ret; ++} ++ ++static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag) ++{ ++ int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int int_flag = 0; ++ unsigned int enable = 0; ++ unsigned int stop = 0; ++ unsigned int flush = 0; ++ unsigned int wpt = 0; ++ unsigned int rpt = 0; ++ unsigned int int_buf = 0; ++ unsigned int valid_size = 0; ++ /*unsigned long irq_flag = 0;*/ ++#if defined(CONFIG_MTK_CLKMGR) ++ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++ BTIF_INFO_FUNC("dump DMA status register\n"); ++ _btif_dma_dump_dbg_reg(); ++ ++ int_flag = BTIF_READ32(RX_DMA_INT_FLAG(base)); ++ enable = BTIF_READ32(RX_DMA_EN(base)); ++ stop = BTIF_READ32(RX_DMA_STOP(base)); ++ flush = BTIF_READ32(RX_DMA_FLUSH(base)); ++ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); ++ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); ++ int_buf = BTIF_READ32(RX_DMA_INT_BUF_SIZE(base)); ++ valid_size = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ ++ BTIF_INFO_FUNC("DMA's clock is on\n"); ++ BTIF_INFO_FUNC("Rx DMA's base address: 0x%lx\n", base); ++ ++ if (flag == REG_RX_DMA_ALL) { ++ BTIF_INFO_FUNC("RX_EN(:0x%x\n", enable); ++ BTIF_INFO_FUNC("RX_STOP:0x%x\n", stop); ++ BTIF_INFO_FUNC("RX_FLUSH:0x%x\n", flush); ++ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); ++ BTIF_INFO_FUNC("RX_WPT:0x%x\n", wpt); ++ BTIF_INFO_FUNC("RX_RPT:0x%x\n", rpt); ++ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); ++ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); ++ BTIF_INFO_FUNC("INT_EN:0x%x\n", ++ BTIF_READ32(RX_DMA_INT_EN(base))); ++ BTIF_INFO_FUNC("RX_RST:0x%x\n", BTIF_READ32(RX_DMA_RST(base))); ++ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_ADDR(base))); ++ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_LEN(base))); ++ BTIF_INFO_FUNC("RX_THRE:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_THRE(base))); ++ BTIF_INFO_FUNC("RX_FLOW_CTRL_THRE:0x%x\n", ++ BTIF_READ32(RX_DMA_FLOW_CTRL_THRE(base))); ++ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_LEFT_SIZE(base))); ++ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", ++ BTIF_READ32(RX_DMA_DEBUG_STATUS(base))); ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC("unknown flag:%d\n", flag); ++ } ++ BTIF_INFO_FUNC("rx dma %s\n", (enable & DMA_EN_BIT) && ++ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); ++ BTIF_INFO_FUNC("data in rx dma is %s by driver\n", ++ ((wpt == rpt) && ++ (int_buf == 0)) ? "received" : "not received"); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag) ++{ ++ unsigned int i_ret = -1; ++ ++ if (p_dma_info->dir == DMA_DIR_TX) ++ i_ret = hal_tx_dma_dump_reg(p_dma_info, flag); ++ else if (p_dma_info->dir == DMA_DIR_RX) ++ i_ret = hal_rx_dma_dump_reg(p_dma_info, flag); ++ else ++ BTIF_WARN_FUNC("unknown dir:%d\n", p_dma_info->dir); ++ ++ return i_ret; ++} ++ ++static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int stop = BTIF_READ32(TX_DMA_STOP(base)); ++ ++/*in MTK DMA BTIF channel we cannot set STOP and FLUSH bit at the same time*/ ++ if ((stop && DMA_STOP_BIT) != 0) ++ BTIF_ERR_FUNC("BTIF's DMA in stop state, omit flush operation\n"); ++ else { ++ BTIF_DBG_FUNC("flush tx dma\n"); ++ BTIF_SET_BIT(TX_DMA_FLUSH(base), DMA_FLUSH_BIT); ++ i_ret = 0; ++ } ++ return i_ret; ++} ++ ++static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ bool b_ret = true; ++ unsigned long base = p_dma_info->base; ++ ++/*see if flush operation is in process*/ ++ b_ret = ((DMA_FLUSH_BIT & BTIF_READ32(TX_DMA_FLUSH(base))) != 0) ? true : false; ++ ++ return b_ret; ++} ++ ++int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("op id: %d\n", opid); ++ switch (opid) { ++ case BTIF_PM_DPIDLE_EN: ++ i_ret = 0; ++ break; ++ case BTIF_PM_DPIDLE_DIS: ++ i_ret = 0; ++ break; ++ case BTIF_PM_SUSPEND: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESUME: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESTORE_NOIRQ:{ ++ unsigned int flag = 0; ++ P_MTK_BTIF_IRQ_STR p_irq = p_dma_info->p_irq; ++ ++#ifdef CONFIG_OF ++ flag = p_irq->irq_flags; ++#else ++ switch (p_irq->sens_type) { ++ case IRQ_SENS_EDGE: ++ if (p_irq->edge_type == IRQ_EDGE_FALL) ++ flag = IRQF_TRIGGER_FALLING; ++ else if (p_irq->edge_type == IRQ_EDGE_RAISE) ++ flag = IRQF_TRIGGER_RISING; ++ else if (p_irq->edge_type == IRQ_EDGE_BOTH) ++ flag = IRQF_TRIGGER_RISING | ++ IRQF_TRIGGER_FALLING; ++ else ++ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ ++ break; ++ case IRQ_SENS_LVL: ++ if (p_irq->lvl_type == IRQ_LVL_LOW) ++ flag = IRQF_TRIGGER_LOW; ++ else if (p_irq->lvl_type == IRQ_LVL_HIGH) ++ flag = IRQF_TRIGGER_HIGH; ++ else ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ default: ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ } ++#endif ++/* irq_set_irq_type(p_irq->irq_id, flag); */ ++ i_ret = 0; ++ } ++ i_ret = 0; ++ break; ++ default: ++ i_ret = ERR_INVALID_PAR; ++ break; ++ } ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_receive_data ++* DESCRIPTION ++* receive data from btif module in DMA polling mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++ unsigned int i_ret = -1; ++ ++ return i_ret; ++} ++#endif ++ ++int _btif_dma_dump_dbg_reg(void) ++{ ++#if 0 ++ static MTK_BTIF_DMA_REG_DMP_DBG g_dma_dbg_regs[] = { ++ {0x10201180, 0x0}, ++ {0x10201184, 0x0}, ++ {0x10201188, 0x0}, ++ {0x1020118C, 0x0}, ++ {0x10201190, 0x0}, ++ {0x1000320C, 0x0}, ++ {0x10003210, 0x0}, ++ {0x10003214, 0x0}, ++ }; ++ ++ int i = 0; ++ char *addr1 = NULL; ++ char *addr2 = NULL; ++ ++ int array_num = ARRAY_SIZE(g_dma_dbg_regs) ++ ++ addr1 = ioremap(g_dma_dbg_regs[0].reg_addr, 0x20); ++ if (addr1) { ++ for (i = 0; i < 5; i++) ++ g_dma_dbg_regs[i].reg_val = *(volatile unsigned int*)(addr1 + i*4); ++ iounmap(addr1); ++ } ++ ++ addr2 = ioremap(g_dma_dbg_regs[5].reg_addr, 0x10); ++ if (addr2) { ++ g_dma_dbg_regs[5].reg_val = *(volatile unsigned int*)(addr2); ++ g_dma_dbg_regs[6].reg_val = *(volatile unsigned int*)(addr2+4); ++ g_dma_dbg_regs[7].reg_val = *(volatile unsigned int*)(addr2+8); ++ iounmap(addr2); ++ } ++ ++ for (i = 0; i < array_num; i++) ++ BTIF_INFO_FUNC("-<0x%lx, 0x%08x>\n", g_dma_dbg_regs[i].reg_addr, g_dma_dbg_regs[i].reg_val); ++#endif ++ return 0; ++} ++ ++static void hal_btif_tx_dma_vff_set_for_4g(void) ++{ ++ BTIF_DBG_FUNC("Set btif tx_vff_addr bit29\n"); ++ BTIF_SET_BIT(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), DMA_VFF_BIT29_OFFSET); ++ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), ++ BTIF_READ32(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base))); ++} ++static void hal_btif_rx_dma_vff_set_for_4g(void) ++{ ++ BTIF_DBG_FUNC("Set btif rx_vff_addr bit29\n"); ++ BTIF_SET_BIT(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), DMA_VFF_BIT29_OFFSET); ++ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), ++ BTIF_READ32(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base))); ++} ++ +diff --git a/drivers/misc/mediatek/btif/common/btif_plat.c b/drivers/misc/mediatek/btif/common/btif_plat.c +new file mode 100644 +index 000000000000..baf2a0b6d0c8 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/btif_plat.c +@@ -0,0 +1,1396 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF" ++ ++#define NEW_TX_HANDLING_SUPPORT 1 ++ ++#include "btif_pub.h" ++#include "btif_priv.h" ++ ++#define BTIF_USER_ID "btif_driver" ++ ++static spinlock_t g_clk_cg_spinlock; /*BTIF clock's spinlock */ ++ ++/*-----------------------------BTIF Module Clock and Power Control Defination------------------*/ ++ ++MTK_BTIF_IRQ_STR mtk_btif_irq = { ++ .name = "mtk btif irq", ++ .is_irq_sup = true, ++ .reg_flag = false, ++#ifdef CONFIG_OF ++ .irq_flags = IRQF_TRIGGER_NONE, ++#else ++ .irq_id = MT_BTIF_IRQ_ID, ++ .sens_type = IRQ_SENS_LVL, ++ .lvl_type = IRQ_LVL_LOW, ++#endif ++ .p_irq_handler = NULL, ++}; ++ ++/* ++ * will call clock manager's API export by WCP to control BTIF's clock, ++ * but we may need to access these registers in case of btif clock control logic is wrong in clock manager ++ */ ++ ++MTK_BTIF_INFO_STR mtk_btif = { ++#ifndef CONFIG_OF ++ .base = MTK_BTIF_REG_BASE, ++#endif ++ .p_irq = &mtk_btif_irq, ++ .tx_fifo_size = BTIF_TX_FIFO_SIZE, ++ .rx_fifo_size = BTIF_RX_FIFO_SIZE, ++ .tx_tri_lvl = BTIF_TX_FIFO_THRE, ++ .rx_tri_lvl = BTIF_RX_FIFO_THRE, ++ .rx_data_len = 0, ++ .p_tx_fifo = NULL, ++}; ++#if !(NEW_TX_HANDLING_SUPPORT) ++static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); ++#endif ++ ++static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, ++ const unsigned int max_len); ++static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_ier_ctrl ++* DESCRIPTION ++* BTIF Rx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if rx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_ier_ctrl ++* DESCRIPTION ++* BTIF Tx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if tx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++static int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* _btif_receive_data ++* DESCRIPTION ++* receive data from btif module in FIFO polling mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++static int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len); ++static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count); ++#endif ++ ++static int btif_dump_array(char *string, char *p_buf, int len) ++{ ++ unsigned int idx = 0; ++ unsigned char str[30]; ++ unsigned char *p_str; ++ ++ pr_debug("========dump %s start ========\n", string, len); ++ p_str = &str[0]; ++ for (idx = 0; idx < len; idx++, p_buf++) { ++ sprintf(p_str, "%02x ", *p_buf); ++ p_str += 3; ++ if (7 == (idx % 8)) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ p_str = &str[0]; ++ } ++ } ++ if (len % 8) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ } ++ pr_debug("========dump %s end========\n", string); ++ return 0; ++} ++ ++#if NEW_TX_HANDLING_SUPPORT ++static int _btif_tx_fifo_init(P_MTK_BTIF_INFO_STR p_btif_info) ++{ ++ int i_ret = -1; ++ ++ spin_lock_init(&(p_btif_info->tx_fifo_spinlock)); ++ ++ if (p_btif_info->p_tx_fifo == NULL) { ++ p_btif_info->p_tx_fifo = kzalloc(sizeof(struct kfifo), ++ GFP_ATOMIC); ++ if (p_btif_info->p_tx_fifo == NULL) { ++ i_ret = -ENOMEM; ++ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); ++ goto ret; ++ } ++ ++ i_ret = kfifo_alloc(p_btif_info->p_tx_fifo, ++ BTIF_HAL_TX_FIFO_SIZE, GFP_ATOMIC); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); ++ i_ret = -ENOMEM; ++ goto ret; ++ } ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC ++ ("p_btif_info->p_tx_fifo is already init p_btif_info->p_tx_fifo(0x%p)\n", ++ p_btif_info->p_tx_fifo); ++ i_ret = 0; ++ } ++ret: ++ return i_ret; ++} ++ ++static int _get_btif_tx_fifo_room(P_MTK_BTIF_INFO_STR p_btif_info) ++{ ++ int i_ret = 0; ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(p_btif_info->tx_fifo_spinlock), flag); ++ if (p_btif_info->p_tx_fifo == NULL) ++ i_ret = 0; ++ else ++ i_ret = kfifo_avail(p_btif_info->p_tx_fifo); ++ spin_unlock_irqrestore(&(p_btif_info->tx_fifo_spinlock), flag); ++ BTIF_DBG_FUNC("tx kfifo:0x%p, available room:%d\n", p_btif_info->p_tx_fifo, i_ret); ++ return i_ret; ++} ++ ++static int _btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif_info) ++{ ++ int i_ret = 0; ++ ++ if (p_btif_info->p_tx_fifo != NULL) ++ kfifo_reset(p_btif_info->p_tx_fifo); ++ return i_ret; ++} ++ ++#endif ++ ++#ifdef CONFIG_OF ++static void _btif_set_default_setting(void) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = {0, 0, 0}; ++ unsigned int phy_base; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,btif"); ++ if (node) { ++ mtk_btif.p_irq->irq_id = irq_of_parse_and_map(node, 0); ++ /*fixme, be compitable arch 64bits*/ ++ mtk_btif.base = (unsigned long)of_iomap(node, 0); ++ BTIF_INFO_FUNC("get btif irq(%d),register base(0x%lx)\n", ++ mtk_btif.p_irq->irq_id, mtk_btif.base); ++ } else { ++ BTIF_ERR_FUNC("get btif device node fail\n"); ++ } ++ ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); ++ } else { ++ mtk_btif.p_irq->irq_flags = irq_info[2]; ++ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", mtk_btif.p_irq->irq_flags); ++ } ++ ++ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) ++ BTIF_ERR_FUNC("get register phy base from DTS fail\n"); ++ else ++ BTIF_INFO_FUNC("get register phy base(0x%x)\n", (unsigned int)phy_base); ++} ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_info_get ++* DESCRIPTION ++* get btif's information included base address , irq related information ++* PARAMETERS ++* RETURNS ++* BTIF's information ++*****************************************************************************/ ++P_MTK_BTIF_INFO_STR hal_btif_info_get(void) ++{ ++#if NEW_TX_HANDLING_SUPPORT ++ int i_ret = 0; ++/*tx fifo and fifo lock init*/ ++ i_ret = _btif_tx_fifo_init(&mtk_btif); ++ if (i_ret == 0) ++ BTIF_INFO_FUNC("_btif_tx_fifo_init succeed\n"); ++ else ++ BTIF_ERR_FUNC("_btif_tx_fifo_init failed, i_ret:%d\n", i_ret); ++ ++#endif ++ ++#ifdef CONFIG_OF ++ _btif_set_default_setting(); ++#endif ++ ++ spin_lock_init(&g_clk_cg_spinlock); ++ ++ return &mtk_btif; ++} ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_get_and_prepare ++* DESCRIPTION ++* get clock from device tree and prepare for enable/disable control ++* PARAMETERS ++* pdev device pointer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++#if !defined(CONFIG_MTK_CLKMGR) ++int hal_btif_clk_get_and_prepare(struct platform_device *pdev) ++{ ++ int i_ret = -1; ++ ++ clk_btif = devm_clk_get(&pdev->dev, "btifc"); ++ if (IS_ERR(clk_btif)) { ++ BTIF_ERR_FUNC("[CCF]cannot get clk_btif clock.\n"); ++ return PTR_ERR(clk_btif); ++ } ++ BTIF_ERR_FUNC("[CCF]clk_btif=%p\n", clk_btif); ++ clk_btif_apdma = devm_clk_get(&pdev->dev, "apdmac"); ++ if (IS_ERR(clk_btif_apdma)) { ++ BTIF_ERR_FUNC("[CCF]cannot get clk_btif_apdma clock.\n"); ++ return PTR_ERR(clk_btif_apdma); ++ } ++ BTIF_ERR_FUNC("[CCF]clk_btif_apdma=%p\n", clk_btif_apdma); ++ ++ i_ret = clk_prepare(clk_btif); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("clk_prepare clk_btif failed! ret:%d\n", i_ret); ++ return i_ret; ++ } ++ ++ i_ret = clk_prepare(clk_btif_apdma); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("clk_prepare clk_btif_apdma failed! ret:%d\n", i_ret); ++ return i_ret; ++ } ++ return i_ret; ++} ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_unprepare ++* DESCRIPTION ++* unprepare btif clock and apdma clock ++* PARAMETERS ++* none ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_unprepare(void) ++{ ++ clk_unprepare(clk_btif); ++ clk_unprepare(clk_btif_apdma); ++ return 0; ++} ++#endif ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of BTIF module ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag) ++{ ++/*In MTK BTIF, there's only one global CG on AP_DMA, no sub channel's CG bit*/ ++/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ ++ int i_ret = 0; ++ unsigned long irq_flag = 0; ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ static atomic_t s_clk_ref = ATOMIC_INIT(0); ++#else ++ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; ++#endif ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_CTL ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++ if (flag == CLK_OUT_ENABLE) { ++ if (atomic_inc_return(&s_clk_ref) == 1) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); ++ i_ret = clk_enable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++ if (atomic_dec_return(&s_clk_ref) == 0) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); ++ clk_disable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ ++#else ++ ++ if (status == flag) { ++ i_ret = 0; ++ BTIF_DBG_FUNC("btif clock already %s\n", ++ CLK_OUT_ENABLE == ++ status ? "enabled" : "disabled"); ++ } else { ++ if (flag == CLK_OUT_ENABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); ++ i_ret = clk_enable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); ++ clk_disable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ } ++#endif ++ ++#else ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++#else ++ ++ status = flag; ++#endif ++ ++ i_ret = 0; ++#endif ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#else ++ ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++ BTIF_DBG_FUNC("BTIF's clock is %s\n", (clock_is_on(MTK_BTIF_CG_BIT) == 0) ? "off" : "on"); ++#endif ++ return i_ret; ++} ++ ++static int btif_new_handshake_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool enable) ++{ ++ unsigned long base = p_btif->base; ++ ++ if (enable == true) ++ BTIF_SET_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); ++ else ++ BTIF_CLR_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); ++ return true; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_hw_init ++* DESCRIPTION ++* BTIF hardware init ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++#if NEW_TX_HANDLING_SUPPORT ++ _btif_tx_fifo_reset(p_btif); ++#endif ++ ++/*set to normal mode*/ ++ btif_reg_sync_writel(BTIF_FAKELCR_NORMAL_MODE, BTIF_FAKELCR(base)); ++/*set to newhandshake mode*/ ++ btif_new_handshake_ctrl(p_btif, true); ++/*No need to access: enable sleep mode*/ ++/*No need to access: set Rx timeout count*/ ++/*set Tx threshold*/ ++/*set Rx threshold*/ ++/*disable internal loopback test*/ ++ ++/*set Rx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++/*clear Rx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++/*set Tx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++/*clear Tx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++ ++ btif_reg_sync_writel(BTIF_TRI_LVL_TX(p_btif->tx_tri_lvl) ++ | BTIF_TRI_LVL_RX(p_btif->rx_tri_lvl) ++ | BTIF_TRI_LOOP_DIS, BTIF_TRI_LVL(base)); ++ hal_btif_loopback_ctrl(p_btif, false); ++/*disable BTIF Tx DMA mode*/ ++ hal_btif_tx_mode_ctrl(p_btif, false); ++/*disable BTIF Rx DMA mode*/ ++ hal_btif_rx_mode_ctrl(p_btif, false); ++/*auto reset*/ ++ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_AUTORST_EN); ++/*disable Tx IER*/ ++ hal_btif_tx_ier_ctrl(p_btif, false); ++/*enable Rx IER by default*/ ++ hal_btif_rx_ier_ctrl(p_btif, true); ++ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_ier_ctrl ++* DESCRIPTION ++* BTIF Rx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if rx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_RXFEN); ++ else ++ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_RXFEN); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_ier_ctrl ++* DESCRIPTION ++* BTIF Tx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if tx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_TXEEN); ++ else ++ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_TXEEN); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++ i_ret = 0; ++ ++ return i_ret; ++} ++ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++ ++/***************************************************************************** ++* FUNCTION ++* _btif_receive_data ++* DESCRIPTION ++* receive data from btif module in FIFO polling mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ ++/*check parameter valid or not*/ ++ if ((p_buf == NULL) || (max_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ return i_ret; ++ } ++ i_ret = btif_rx_irq_handler(p_btif, p_buf, max_len); ++ ++ return i_ret; ++} ++ ++int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); ++ else ++ BTIF_SET_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ unsigned int value = 0; ++ ++/*read BTIF_TRI_LVL*/ ++ value = BTIF_READ32(BTIF_TRI_LVL(base)); ++/*clear Tx threshold bits*/ ++ value &= (~BTIF_TRI_LVL_TX_MASK); ++/*set tx threshold bits*/ ++ value |= BTIF_TRI_LVL_TX(BTIF_TX_FIFO_THRE); ++/*write back to BTIF_TRI_LVL*/ ++ btif_reg_sync_writel(value, BTIF_TRI_LVL(base)); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_rx_fifo_reset ++* DESCRIPTION ++* reset BTIF's rx fifo ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* ec [IN] control if loopback mode is enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int btif_rx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++/*set Rx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++ ++/*clear Rx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_tx_fifo_reset ++* DESCRIPTION ++* reset BTIF's tx fifo ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++/*set Tx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++ ++/*clear Tx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_loopback_ctrl ++* DESCRIPTION ++* BTIF Tx/Rx loopback mode set, this operation can only be done after set BTIF to normal mode ++* PARAMETERS ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); ++ else ++ BTIF_SET_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_handler ++* DESCRIPTION ++* lower level interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success; negative means fail; positive means rx data length ++*****************************************************************************/ ++int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ unsigned int iir = 0; ++ unsigned int rx_len = 0; ++ unsigned long base = p_btif->base; ++ ++#if 0 ++/*check parameter valid or not*/ ++ if ((p_buf == NULL) || (max_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ return i_ret; ++ } ++#endif ++ unsigned long irq_flag = 0; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); ++ ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*read interrupt identifier register*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ ++/*is rx interrupt exist?*/ ++#if 0 ++ while ((iir & BTIF_IIR_RX) && (rx_len < max_len)) { ++ rx_len += ++ btif_rx_irq_handler(p_btif, (p_buf + rx_len), ++ (max_len - rx_len)); ++ ++/*update IIR*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ } ++#endif ++ ++ while (iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) { ++ rx_len += btif_rx_irq_handler(p_btif, p_buf, max_len); ++ ++/*update IIR*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ } ++ ++/*is tx interrupt exist?*/ ++ if (iir & BTIF_IIR_TX_EMPTY) ++ i_ret = btif_tx_irq_handler(p_btif); ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ ++ i_ret = rx_len != 0 ? rx_len : i_ret; ++ return i_ret; ++} ++ ++int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, btif_rx_buf_write rx_cb) ++{ ++ if (p_btif_info->rx_cb != NULL) ++ BTIF_DBG_FUNC("rx_cb already registered, replace (0x%p) with (0x%p)\n", ++ p_btif_info->rx_cb, rx_cb); ++ p_btif_info->rx_cb = rx_cb; ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_rx_irq_handler ++* DESCRIPTION ++* lower level rx interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* positive means length of rx data , negative means fail ++*****************************************************************************/ ++static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = 0; ++ unsigned int iir = 0; ++ unsigned int rx_len = 0; ++ unsigned long base = p_btif_info->base; ++ unsigned char rx_buf[256]; ++ unsigned int local_buf_len = 256; ++ btif_rx_buf_write rx_cb = p_btif_info->rx_cb; ++ unsigned int total_len = 0; ++ ++/*read interrupt identifier register*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ while ((iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) && ++ (rx_len < local_buf_len)) { ++ rx_buf[rx_len] = BTIF_READ8(base); ++ rx_len++; ++/*need to consult CC Hwang for advice */ ++/* ++ * whether we need to do memory barrier here ++ * Ans: no ++ */ ++/* ++ * whether we need to d memory barrier when call BTIF_SET_BIT or BTIF_CLR_BIT ++ * Ans: no ++ */ ++ if (rx_len == local_buf_len) { ++ if (rx_cb) ++ (*rx_cb) (p_btif_info, rx_buf, rx_len); ++ rx_len = 0; ++ total_len += rx_len; ++ } ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ } ++ total_len += rx_len; ++ if (rx_len && rx_cb) ++ (*rx_cb) (p_btif_info, rx_buf, rx_len); ++ ++/* ++ * make sure all data write back to memory, mb or dsb? ++ * need to consult CC Hwang for advice ++ * Ans: no need here ++ */ ++ i_ret = total_len; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_tx_irq_handler ++* DESCRIPTION ++* lower level tx interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif) ++{ ++ int i_ret = -1; ++ ++#if NEW_TX_HANDLING_SUPPORT ++ int how_many = 0; ++ unsigned int lsr; ++ unsigned int ava_len = 0; ++ unsigned long base = p_btif->base; ++ char local_buf[BTIF_TX_FIFO_SIZE]; ++ char *p_data = local_buf; ++ unsigned long flag = 0; ++ ++ struct kfifo *p_tx_fifo = p_btif->p_tx_fifo; ++ ++/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ ++ if (lsr & BTIF_LSR_TEMT_BIT) ++ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE; ++ else if (lsr & BTIF_LSR_THRE_BIT) ++ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; ++ else { ++ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ ++ ava_len = 0; ++ goto ret; ++ } ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); ++ how_many = kfifo_out(p_tx_fifo, local_buf, ava_len); ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); ++ BTIF_DBG_FUNC("BTIF tx size %d done, left:%d\n", how_many, ++ kfifo_avail(p_tx_fifo)); ++ while (how_many--) ++ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); ++ ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); ++/*clear Tx enable flag if necessary*/ ++ if (kfifo_is_empty(p_tx_fifo)) { ++ hal_btif_tx_ier_ctrl(p_btif, false); ++ BTIF_DBG_FUNC("BTIF tx FIFO is empty\n"); ++ } ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); ++ret: ++#else ++/*clear Tx enable flag*/ ++ hal_btif_tx_ier_ctrl(p_btif, false); ++#endif ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_mode_ctrl ++* DESCRIPTION ++* set BTIF tx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (mode == BTIF_MODE_DMA) ++ /*set to DMA mode*/ ++ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); ++ else ++ /*set to PIO mode*/ ++ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); ++ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_mode_ctrl ++* DESCRIPTION ++* set BTIF rx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (mode == BTIF_MODE_DMA) ++ /*set to DMA mode*/ ++ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); ++ else ++ /*set to PIO mode*/ ++ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); ++ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_send_data ++* DESCRIPTION ++* send data through btif in FIFO mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* positive means number of data sent; 0 means no data put to FIFO; negative means error happens ++*****************************************************************************/ ++int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, ++ const unsigned char *p_buf, const unsigned int buf_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ ++ unsigned int ava_len = 0; ++ unsigned int sent_len = 0; ++ ++#if !(NEW_TX_HANDLING_SUPPORT) ++ unsigned long base = p_btif->base; ++ unsigned int lsr = 0; ++ unsigned int left_len = 0; ++ unsigned char *p_data = (unsigned char *)p_buf; ++#endif ++ ++/*check parameter valid or not*/ ++ if ((p_buf == NULL) || (buf_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ return i_ret; ++ } ++#if NEW_TX_HANDLING_SUPPORT ++ ava_len = _get_btif_tx_fifo_room(p_btif); ++ sent_len = buf_len <= ava_len ? buf_len : ava_len; ++ if (sent_len > 0) { ++ int enqueue_len = 0; ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); ++ enqueue_len = kfifo_in(p_btif->p_tx_fifo, ++ (unsigned char *)p_buf, sent_len); ++ if (sent_len != enqueue_len) { ++ BTIF_ERR_FUNC("target tx len:%d, len sent:%d\n", ++ sent_len, enqueue_len); ++ } ++ i_ret = enqueue_len; ++ mb(); ++/*enable BTIF Tx IRQ*/ ++ hal_btif_tx_ier_ctrl(p_btif, true); ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); ++ BTIF_DBG_FUNC("enqueue len:%d\n", enqueue_len); ++ } else { ++ i_ret = 0; ++ } ++#else ++ while ((_btif_is_tx_allow(p_btif)) && (sent_len < buf_len)) { ++ /*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ ++ if (lsr & BTIF_LSR_TEMT_BIT) ++ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE; ++ else if (lsr & BTIF_LSR_THRE_BIT) ++ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; ++ else { ++ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ ++ ava_len = 0; ++ break; ++ } ++ ++ left_len = buf_len - sent_len; ++/*ava_len will be real length will write to BTIF THR*/ ++ ava_len = ava_len > left_len ? left_len : ava_len; ++/*update sent length valud after this operation*/ ++ sent_len += ava_len; ++/* ++ * whether we need memory barrier here? ++ * Ans: No, no memory ordering issue exist, ++ * CPU will make sure logically right ++ */ ++ while (ava_len--) ++ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); ++ ++ } ++/* while ((hal_btif_is_tx_allow()) && (sent_len < buf_len)); */ ++ ++ i_ret = sent_len; ++ ++/*enable BTIF Tx IRQ*/ ++ hal_btif_tx_ier_ctrl(p_btif, true); ++#endif ++ return i_ret; ++} ++ ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_raise_wak_sig ++* DESCRIPTION ++* raise wakeup signal to counterpart ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { ++ BTIF_ERR_FUNC("%s: clock is off before send wakeup signal!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*write 0 to BTIF_WAK to pull ap_wakeup_consyss low */ ++ BTIF_CLR_BIT(BTIF_WAK(base), BTIF_WAK_BIT); ++ ++/*wait for a period for longer than 1/32k period, here we use 40us*/ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ usleep_range(128, 160); ++/* ++ * according to linux/documentation/timers/timers-how-to, we choose usleep_range ++ * SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms): * Use usleep_range ++ */ ++/*write 1 to pull ap_wakeup_consyss high*/ ++ BTIF_SET_BIT(BTIF_WAK(base), BTIF_WAK_BIT); ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ int idx = 0; ++ /*unsigned long irq_flag = 0;*/ ++ unsigned long base = p_btif->base; ++ unsigned char reg_map[0xE0 / 4] = { 0 }; ++ unsigned int lsr = 0x0; ++ unsigned int dma_en = 0; ++ ++ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ dma_en = BTIF_READ32(BTIF_DMA_EN(base)); ++ /* ++ * here we omit 1st register which is THR/RBR register to avoid ++ * Rx data read by this debug information accidently ++ */ ++ for (idx = 1; idx < sizeof(reg_map); idx++) ++ reg_map[idx] = BTIF_READ8(p_btif->base + (4 * idx)); ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_INFO_FUNC("BTIF's clock is on\n"); ++ BTIF_INFO_FUNC("base address: 0x%lx\n", base); ++ switch (flag) { ++ case REG_BTIF_ALL: ++#if 0 ++ BTIF_INFO_FUNC("BTIF_IER:0x%x\n", BTIF_READ32(BTIF_IER(base))); ++ BTIF_INFO_FUNC("BTIF_IIR:0x%x\n", BTIF_READ32(BTIF_IIR(base))); ++ BTIF_INFO_FUNC("BTIF_FAKELCR:0x%x\n", ++ BTIF_READ32(BTIF_FAKELCR(base))); ++ BTIF_INFO_FUNC("BTIF_LSR:0x%x\n", BTIF_READ32(BTIF_LSR(base))); ++ BTIF_INFO_FUNC("BTIF_SLEEP_EN:0x%x\n", ++ BTIF_READ32(BTIF_SLEEP_EN(base))); ++ BTIF_INFO_FUNC("BTIF_DMA_EN:0x%x\n", ++ BTIF_READ32(BTIF_DMA_EN(base))); ++ BTIF_INFO_FUNC("BTIF_RTOCNT:0x%x\n", ++ BTIF_READ32(BTIF_RTOCNT(base))); ++ BTIF_INFO_FUNC("BTIF_TRI_LVL:0x%x\n", ++ BTIF_READ32(BTIF_TRI_LVL(base))); ++ BTIF_INFO_FUNC("BTIF_WAT_TIME:0x%x\n", ++ BTIF_READ32(BTIF_WAT_TIME(base))); ++ BTIF_INFO_FUNC("BTIF_HANDSHAKE:0x%x\n", ++ BTIF_READ32(BTIF_HANDSHAKE(base))); ++#endif ++ btif_dump_array("BTIF register", reg_map, sizeof(reg_map)); ++ break; ++ default: ++ break; ++ } ++ ++ BTIF_INFO_FUNC("Tx DMA %s\n", ++ (dma_en & BTIF_DMA_EN_TX) ? "enabled" : "disabled"); ++ BTIF_INFO_FUNC("Rx DMA %s\n", ++ (dma_en & BTIF_DMA_EN_RX) ? "enabled" : "disabled"); ++ ++ BTIF_INFO_FUNC("Rx data is %s\n", ++ (lsr & BTIF_LSR_DR_BIT) ? "not empty" : "empty"); ++ BTIF_INFO_FUNC("Tx data is %s\n", ++ (lsr & BTIF_LSR_TEMT_BIT) ? "empty" : "not empty"); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ bool b_ret = false; ++ unsigned int lsr = 0; ++ unsigned long flags = 0; ++ unsigned long base = p_btif->base; ++ unsigned int tx_empty = 0; ++ unsigned int rx_dr = 0; ++ unsigned int tx_irq_disable = 0; ++ ++/* ++ * 3 conditions allow clock to be disable ++ * 1. if TEMT is set or not ++ * 2. if DR is set or not ++ * 3. Tx IRQ is disabled or not ++ */ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ tx_empty = lsr & BTIF_LSR_TEMT_BIT; ++ rx_dr = lsr & BTIF_LSR_DR_BIT; ++ tx_irq_disable = BTIF_READ32(BTIF_IER(base)) & BTIF_IER_TXEEN; ++ ++ b_ret = ++ (tx_empty && (tx_irq_disable == 0) && (rx_dr == 0)) ? true : false; ++ if (!b_ret) { ++ BTIF_DBG_FUNC ++ ("BTIF flag, tx_empty:%d, rx_dr:%d, tx_irq_disable:%d\n", ++ tx_empty, rx_dr, tx_irq_disable); ++ } ++#if NEW_TX_HANDLING_SUPPORT ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); ++/*clear Tx enable flag if necessary*/ ++ if (!(kfifo_is_empty(p_btif->p_tx_fifo))) { ++ BTIF_DBG_FUNC("BTIF tx FIFO is not empty\n"); ++ b_ret = false; ++ } ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); ++#endif ++ return b_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_allow ++* DESCRIPTION ++* whether tx is allowed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) ++{ ++#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) ++#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) ++ ++/*Chaozhong: To be implement*/ ++ bool b_ret = false; ++ ++#if NEW_TX_HANDLING_SUPPORT ++ unsigned long flags = 0; ++ ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); ++/*clear Tx enable flag if necessary*/ ++ if (kfifo_is_full(p_btif->p_tx_fifo)) { ++ BTIF_WARN_FUNC("BTIF tx FIFO is full\n"); ++ b_ret = false; ++ } else { ++ b_ret = true; ++ } ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); ++#else ++ unsigned int lsr = 0; ++ unsigned long base = p_btif->base; ++ unsigned int wait_us = (BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE) / MIN_TX_MB; /*only ava length */ ++ ++/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ ++ if (!(lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT))) { ++ BTIF_DBG_FUNC("wait for %d ~ %d us\n", wait_us, 3 * wait_us); ++/* usleep_range(wait_us, 3 * 10 * wait_us); */ ++ usleep_range(wait_us, 3 * wait_us); ++ } ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; ++ if (!b_ret) ++ BTIF_DBG_FUNC(" tx is not allowed for the moment\n"); ++ else ++ BTIF_DBG_FUNC(" tx is allowed\n"); ++#endif ++ return b_ret; ++} ++ ++#if !(NEW_TX_HANDLING_SUPPORT) ++ ++static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ bool b_ret = false; ++ unsigned long base = p_btif->base; ++ unsigned int lsr = 0; ++ ++/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; ++ return b_ret; ++} ++#endif ++ ++int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif_info, MTK_BTIF_PM_OPID opid) ++{ ++ int i_ret = -1; ++ ++ BTIF_DBG_FUNC("op id: %d\n", opid); ++ switch (opid) { ++ case BTIF_PM_DPIDLE_EN: ++ i_ret = 0; ++ break; ++ case BTIF_PM_DPIDLE_DIS: ++ i_ret = 0; ++ break; ++ case BTIF_PM_SUSPEND: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESUME: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESTORE_NOIRQ:{ ++ unsigned int flag = 0; ++ P_MTK_BTIF_IRQ_STR p_irq = p_btif_info->p_irq; ++ ++#ifdef CONFIG_OF ++ flag = p_irq->irq_flags; ++#else ++ switch (p_irq->sens_type) { ++ case IRQ_SENS_EDGE: ++ if (p_irq->edge_type == IRQ_EDGE_FALL) ++ flag = IRQF_TRIGGER_FALLING; ++ else if (p_irq->edge_type == IRQ_EDGE_RAISE) ++ flag = IRQF_TRIGGER_RISING; ++ else if (p_irq->edge_type == IRQ_EDGE_BOTH) ++ flag = IRQF_TRIGGER_RISING | ++ IRQF_TRIGGER_FALLING; ++ else ++ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ ++ break; ++ case IRQ_SENS_LVL: ++ if (p_irq->lvl_type == IRQ_LVL_LOW) ++ flag = IRQF_TRIGGER_LOW; ++ else if (p_irq->lvl_type == IRQ_LVL_HIGH) ++ flag = IRQF_TRIGGER_HIGH; ++ else ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ default: ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ } ++#endif ++/* irq_set_irq_type(p_irq->irq_id, flag); */ ++ i_ret = 0; ++ } ++ break; ++ default: ++ i_ret = ERR_INVALID_PAR; ++ break; ++ } ++ ++ return i_ret; ++} ++void mtk_btif_read_cpu_sw_rst_debug_plat(void) ++{ ++#define CONSYS_AP2CONN_WAKEUP_OFFSET 0x00000064 ++ BTIF_WARN_FUNC("+CONSYS_AP2CONN_WAKEUP_OFFSET(0x%x)\n", ++ BTIF_READ32(mtk_btif.base + CONSYS_AP2CONN_WAKEUP_OFFSET)); ++} ++ +diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h +new file mode 100644 +index 000000000000..5e2f5a9857d9 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h +@@ -0,0 +1,370 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_BTIF_H_ ++#define __MTK_BTIF_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* gettimeofday */ ++#include ++ ++#include "btif_pub.h" ++#include "btif_dma_pub.h" ++#include "mtk_btif_exp.h" ++ ++#define BTIF_PORT_NR 1 ++#define BTIF_USER_NAME_MAX_LEN 32 ++ ++/*-------------Register Defination Start ---------------*/ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) ++#define BTIF_RX_BUFFER_SIZE (1024 * 32) ++#else ++#define BTIF_RX_BUFFER_SIZE (1024 * 64) ++#endif ++#define BTIF_TX_FIFO_SIZE (1024 * 4) ++ ++/*------------Register Defination End ----------------*/ ++ ++/*------------BTIF Module Clock and Power Control Defination---------------*/ ++typedef enum _ENUM_BTIF_RX_TYPE_ { ++ BTIF_IRQ_CTX = 0, ++ BTIF_TASKLET_CTX = BTIF_IRQ_CTX + 1, ++ BTIF_THREAD_CTX = BTIF_TASKLET_CTX + 1, ++ BTIF_WQ_CTX = BTIF_THREAD_CTX + 1, ++ BTIF_RX_TYPE_MAX, ++} ENUM_BTIF_RX_TYPE; ++ ++typedef enum _ENUM_BTIF_TX_TYPE_ { ++ BTIF_TX_USER_CTX = 0, ++ BTIF_TX_SINGLE_CTX = BTIF_TX_USER_CTX + 1, ++ BTIF_TX_TYPE_MAX, ++} ENUM_BTIF_TX_TYPE; ++ ++typedef enum _ENUM_BTIF_STATE_ { ++ B_S_OFF = 0, ++ B_S_SUSPEND = B_S_OFF + 1, ++ B_S_DPIDLE = B_S_SUSPEND + 1, ++ B_S_ON = B_S_DPIDLE + 1, ++ B_S_MAX, ++} ENUM_BTIF_STATE; ++ ++#define ENABLE_BTIF_RX_DMA 1 ++#define ENABLE_BTIF_TX_DMA 1 ++ ++#if ENABLE_BTIF_TX_DMA ++#define BTIF_TX_MODE BTIF_MODE_DMA ++#else ++#define BTIF_TX_MODE BTIF_MODE_PIO ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++#define BTIF_RX_MODE BTIF_MODE_DMA ++#else ++#define BTIF_RX_MODE BTIF_MODE_PIO ++#endif ++ ++#define BTIF_RX_BTM_CTX BTIF_THREAD_CTX/*BTIF_WQ_CTX*//* BTIF_TASKLET_CTX */ ++/* ++ * -- cannot be used because , ++ * mtk_wcn_stp_parser data will call *(stp_if_tx) to send ack, ++ * in which context sleepable lock or usleep operation may be used, ++ * these operation is not allowed in tasklet, may cause schedule_bug ++ */ ++ ++#define BTIF_TX_CTX BTIF_TX_USER_CTX /* BTIF_TX_SINGLE_CTX */ ++ ++#define ENABLE_BTIF_RX_THREAD_RT_SCHED 0 ++#define MAX_BTIF_RXD_TIME_REC 3 ++ ++/*Structure Defination*/ ++ ++/*-----------------BTIF setting--------------*/ ++typedef struct _mtk_btif_setting_ { ++ ENUM_BTIF_MODE tx_mode; /*BTIF Tx Mode Setting */ ++ ENUM_BTIF_MODE rx_mode; /*BTIF Tx Mode Setting */ ++ ENUM_BTIF_RX_TYPE rx_type; /*rx handle type */ ++ ENUM_BTIF_TX_TYPE tx_type; /*tx type */ ++} mtk_btif_setting, *p_mtk_btif_setting; ++/*---------------------------------------------------------------------------*/ ++ ++#if 0 ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_register_ { ++ unsigned int iir; /*Interrupt Identification Register */ ++ unsigned int lsr; /*Line Status Register */ ++ unsigned int fake_lcr; /*Fake Lcr Regiseter */ ++ unsigned int fifo_ctrl; /*FIFO Control Register */ ++ unsigned int ier; /*Interrupt Enable Register */ ++ unsigned int sleep_en; /*Sleep Enable Register */ ++ unsigned int rto_counter; /*Rx Timeout Counter Register */ ++ unsigned int dma_en; /*DMA Enalbe Register */ ++ unsigned int tri_lvl; /*Tx/Rx Trigger Level Register */ ++ unsigned int wat_time; /*Async Wait Time Register */ ++ unsigned int handshake; /*New HandShake Mode Register */ ++ unsigned int sleep_wak; /*Sleep Wakeup Reigster */ ++} mtk_btif_register, *p_mtk_btif_register; ++/*---------------------------------------------------------------------------*/ ++ ++#endif ++ ++typedef struct _btif_buf_str_ { ++ unsigned int size; ++ unsigned char *p_buf; ++ /* ++ * For Tx: next Tx data pointer to FIFO; ++ * For Rx: next read data pointer from BTIF user ++ */ ++ unsigned int rd_idx; ++ /* ++ * For Tx: next Tx data pointer from BTIF user; ++ * For Rx: next write data(from FIFO) pointer ++ */ ++ unsigned int wr_idx; ++} btif_buf_str, *p_btif_buf_str; ++ ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_dma_ { ++ /*p_mtk_btif*/ void *p_btif; ++ /*BTIF pointer to which DMA belongs */ ++ ++#if 0 ++ unsigned int channel; /*DMA's channel */ ++#endif ++ ++ ENUM_BTIF_DIR dir; /*DMA's direction: */ ++ bool enable; /*DMA enable or disable flag */ ++ ++ P_MTK_DMA_INFO_STR p_dma_info; /*DMA's IRQ information */ ++ ++#if 0 ++ mtk_dma_register register; /*DMA's register */ ++#endif ++ ++ spinlock_t iolock; /*io lock for DMA channel */ ++ atomic_t entry; /* entry count */ ++} mtk_btif_dma, *p_mtk_btif_dma; ++ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) ++#define BTIF_LOG_ENTRY_NUM 10 ++#else ++#define BTIF_LOG_ENTRY_NUM 30 ++#endif ++ ++#define BTIF_LOG_SZ 1536 ++ ++typedef void (*MTK_BTIF_RX_NOTIFY) (void); ++ ++typedef struct _btif_log_buf_t_ { ++ unsigned int len; ++ struct timeval timer; ++ unsigned char buffer[BTIF_LOG_SZ]; ++} BTIF_LOG_BUF_T, *P_BTIF_LOG_BUF_T; ++ ++typedef struct _btif_log_queue_t_ { ++ ENUM_BTIF_DIR dir; ++ bool enable; ++ bool output_flag; ++ unsigned int in; ++ unsigned int out; ++ unsigned int size; ++ spinlock_t lock; ++ P_BTIF_LOG_BUF_T p_queue[BTIF_LOG_ENTRY_NUM]; ++} BTIF_LOG_QUEUE_T, *P_BTIF_LOG_QUEUE_T; ++ ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_ { ++ unsigned int open_counter; /*open counter */ ++ bool enable; /*BTIF module enable flag */ ++ bool lpbk_flag; /*BTIF module enable flag */ ++#if 0 ++ unsigned long base; /* BTIF controller base address */ ++#endif ++ ++ ENUM_BTIF_STATE state; /*BTIF state mechanism */ ++ struct mutex state_mtx; /*lock to BTIF state mechanism's state change */ ++ struct mutex ops_mtx; /*lock to BTIF's open and close */ ++ ++#if 0 ++ mtk_btif_register register; /*BTIF registers */ ++#endif ++ ++ ENUM_BTIF_MODE tx_mode; /* BTIF Tx channel mode */ ++ ENUM_BTIF_MODE rx_mode; /* BTIF Rx channel mode */ ++ struct mutex tx_mtx; /*lock to BTIF's tx process */ ++/*rx handling */ ++ ENUM_BTIF_RX_TYPE btm_type; /*BTIF Rx bottom half context */ ++/*tx handling*/ ++ ENUM_BTIF_TX_TYPE tx_ctx; /*BTIF tx context */ ++/* unsigned char rx_buf[BTIF_RX_BUFFER_SIZE]; */ ++ btif_buf_str btif_buf; ++ spinlock_t rx_irq_spinlock; /*lock for rx irq handling */ ++ ++/*rx workqueue information*/ ++ /*lock to BTIF's rx bottom half when kernel thread is used */ ++ struct mutex rx_mtx; ++ struct workqueue_struct *p_rx_wq; ++ struct work_struct rx_work; ++ ++ struct workqueue_struct *p_tx_wq; ++ struct work_struct tx_work; ++ struct kfifo *p_tx_fifo; ++ ++/*rx tasklet information*/ ++ struct tasklet_struct rx_tasklet; ++ /*lock to BTIF's rx bottom half when tasklet is used */ ++ spinlock_t rx_tasklet_spinlock; ++ ++/*rx thread information*/ ++ struct task_struct *p_task; ++ struct completion rx_comp; ++ ++ mtk_btif_setting *setting; /*BTIF setting */ ++ ++ p_mtk_btif_dma p_tx_dma; /*BTIF Tx channel DMA */ ++ p_mtk_btif_dma p_rx_dma; /*BTIF Rx channel DMA */ ++ ++ MTK_WCN_BTIF_RX_CB rx_cb; /*Rx callback function */ ++ MTK_BTIF_RX_NOTIFY rx_notify; ++ ++ P_MTK_BTIF_INFO_STR p_btif_info; /*BTIF's information */ ++ ++/*Log Tx data to buffer*/ ++ BTIF_LOG_QUEUE_T tx_log; ++ ++/*Log Rx data to buffer*/ ++ BTIF_LOG_QUEUE_T rx_log; ++ ++/* struct list_head *p_user_list; */ ++ struct list_head user_list; ++/* get btif dev pointer*/ ++ void *private_data; ++} mtk_btif, *p_mtk_btif; ++/*---------------------------------------------------------------------------*/ ++ ++/*---------------------------------------------------------------------------*/ ++#if 0 ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_dma_register_ { ++ unsigned int int_flag; /*Tx offset:0x0 Rx offset:0x0 */ ++ unsigned int int_enable; /*Tx offset:0x4 Rx offset:0x4 */ ++ unsigned int dma_enable; /*Tx offset:0x8 Rx offset:0x8 */ ++ unsigned int dma_reset; /*Tx offset:0xc Rx offset:0xc */ ++ unsigned int dma_stop; /*Tx offset:0x10 Rx offset:0x10 */ ++ unsigned int dma_flush; /*Tx offset:0x14 Rx offset:0x14 */ ++ unsigned int vff_addr; /*Tx offset:0x1c Rx offset:0x1c */ ++ unsigned int vff_len; /*Tx offset:0x24 Rx offset:0x24 */ ++ unsigned int vff_thr; /*Tx offset:0x28 Rx offset:0x28 */ ++ unsigned int vff_wpt; /*Tx offset:0x2c Rx offset:0x2c */ ++ unsigned int vff_rpt; /*Tx offset:0x30 Rx offset:0x30 */ ++ unsigned int rx_fc_thr; /*Tx:No this register Rx offset:0x34 */ ++ unsigned int int_buf_size; /*Tx offset:0x38 Rx offset:0x38 */ ++ unsigned int vff_valid_size; /*Tx offset:0x3c Rx offset:0x3c */ ++ unsigned int vff_left_size; /*Tx offset:0x40 Rx offset:0x40 */ ++ unsigned int debug_status; /*Tx offset:0x50 Rx offset:0x50 */ ++} mtk_dma_register, *p_mtk_dma_register; ++/*---------------------------------------------------------------------------*/ ++#endif ++ ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_user_ { ++ bool enable; /*register its state */ ++ struct list_head entry; /*btif_user's bi-direction list table */ ++ /*BTIF's user, static allocation */ ++ char u_name[BTIF_USER_NAME_MAX_LEN]; ++ unsigned long u_id; ++ p_mtk_btif p_btif; ++} mtk_btif_user, *p_mtk_btif_user; ++ ++/*---------------------------------------------------------------------------*/ ++#define BBS_PTR(ptr, idx) ((ptr->p_buf) + idx) ++ ++#define BBS_SIZE(ptr) ((ptr)->size) ++#define BBS_MASK(ptr) (BBS_SIZE(ptr) - 1) ++#define BBS_COUNT(ptr) ((ptr)->wr_idx >= (ptr)->rd_idx ? (ptr)->wr_idx - \ ++(ptr)->rd_idx : BBS_SIZE(ptr) - \ ++((ptr)->rd_idx - (ptr)->wr_idx)) ++#define BBS_COUNT_CUR(ptr, wr_idx) (wr_idx >= (ptr)->rd_idx ? wr_idx - \ ++(ptr)->rd_idx : BBS_SIZE(ptr) - \ ++((ptr)->rd_idx - wr_idx)) ++ ++#define BBS_LEFT(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) ++ ++#define BBS_AVL_SIZE(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) ++#define BBS_FULL(ptr) (BBS_COUNT(ptr) - BBS_SIZE(ptr)) ++#define BBS_EMPTY(ptr) ((ptr)->wr_idx == (ptr)->rd_idx) ++#define BBS_WRITE_MOVE_NEXT(ptr) ((ptr)->wr_idx = \ ++((ptr)->wr_idx + 1) & BBS_MASK(ptr)) ++#define BBS_READ_MOVE_NEXT(ptr) ((ptr)->rd_idx = \ ++((ptr)->rd_idx + 1) & BBS_MASK(ptr)) ++ ++#define BBS_INIT(ptr) \ ++{ \ ++(ptr)->rd_idx = (ptr)->wr_idx = 0; \ ++(ptr)->size = BTIF_RX_BUFFER_SIZE; \ ++} ++ ++ ++#define BTIF_MUTEX_UNLOCK(x) mutex_unlock(x) ++ ++extern mtk_btif g_btif[]; ++ ++int btif_open(p_mtk_btif p_btif); ++int btif_close(p_mtk_btif p_btif); ++int btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++int btif_enter_dpidle(p_mtk_btif p_btif); ++int btif_exit_dpidle(p_mtk_btif p_btif); ++int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb); ++ ++/*for test purpose*/ ++int _btif_suspend(p_mtk_btif p_btif); ++int _btif_resume(p_mtk_btif p_btif); ++int _btif_restore_noirq(p_mtk_btif p_btif); ++ ++int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); ++int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, ++ int len); ++int btif_dump_data(char *p_buf, int len); ++int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_init(p_mtk_btif p_btif); ++int btif_dump_reg(p_mtk_btif p_btif); ++int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify); ++int btif_raise_wak_signal(p_mtk_btif p_btif); ++int btif_clock_ctrl(p_mtk_btif p_btif, int en); ++bool btif_parser_wmt_evt(p_mtk_btif p_btif, ++ const char *sub_str, ++ unsigned int sub_len); ++void mtk_btif_read_cpu_sw_rst_debug(void); ++ ++#endif /*__MTK_BTIF_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h +new file mode 100644 +index 000000000000..3752644fe0aa +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h +@@ -0,0 +1,280 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_BTIF_EXP_H_ ++#define _MTK_BTIF_EXP_H_ ++ ++/*--------------marco defination---------------*/ ++#define BTIF_MAX_LEN_PER_PKT 2048 ++#define BTIF_RXD_BE_BLOCKED_DETECT 1 ++/*--------------Enum Defination---------------*/ ++typedef enum _ENUM_BTIF_DPIDLE_ { ++ BTIF_DPIDLE_DISABLE = 0, ++ BTIF_DPIDLE_ENABLE = BTIF_DPIDLE_DISABLE + 1, ++ BTIF_DPIDLE_MAX, ++} ENUM_BTIF_DPIDLE_CTRL; ++ ++typedef enum _ENUM_BTIF_LPBK_MODE_ { ++ BTIF_LPBK_DISABLE = 0, ++ BTIF_LPBK_ENABLE = BTIF_LPBK_DISABLE + 1, ++ BTIF_LPBK_MAX, ++} ENUM_BTIF_LPBK_MODE; ++ ++typedef enum _ENUM_BTIF_DBG_ID_ { ++ BTIF_DISABLE_LOGGER = 0, ++ BTIF_ENABLE_LOGGER = BTIF_DISABLE_LOGGER + 1, ++ BTIF_DUMP_LOG = BTIF_ENABLE_LOGGER + 1, ++ BTIF_CLR_LOG = BTIF_DUMP_LOG + 1, ++ BTIF_DUMP_BTIF_REG = BTIF_CLR_LOG + 1, ++ BTIF_ENABLE_RT_LOG = BTIF_DUMP_BTIF_REG + 1, ++ BTIF_DISABLE_RT_LOG = BTIF_ENABLE_RT_LOG + 1, ++ BTIF_DBG_MAX, ++} ENUM_BTIF_DBG_ID; ++ ++typedef enum _ENUM_BTIF_OP_ERROR_CODE_ { ++ E_BTIF_AGAIN = 0, ++ E_BTIF_FAIL = -1, ++ E_BTIF_BAD_POINTER = -2, ++ E_BTIF_NO_SPACE = -3, ++ E_BTIF_INTR = -4, ++ E_BTIF_INVAL_PARAM = -5, ++ E_BTIF_ALREADY_OPEN = -6, ++ E_BTIF_NOT_OPEN = -7, ++ E_BTIF_INVAL_STATE = -8, ++} ENUM_BTIF_OP_ERROR_CODE; ++ ++/*--------------End of Enum Defination---------------*/ ++ ++/*--------------Type Definition---------------*/ ++ ++typedef int (*MTK_WCN_BTIF_RX_CB) (const unsigned char *p_buf, ++ unsigned int len); ++ ++/*--------------End of Type Definition---------------*/ ++ ++/*--------------Normal Mode API declearation---------------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_open ++* DESCRIPTION ++* open BTIF interface, will do BTIF module HW and SW initialization ++* PARAMETERS ++* p_owner [IN] pointer to owner who call this API, ++* currently there are 2 owner ("stp" or "btif_tester") ++* may use this module ++* user's id string must be less than 32 bytes ++* for "stp", BTIF will call rx callback function to route rx data to STP module ++* for "stp_tester", BTIF will save rx data ++* and wait for native process to access ++* p_id [IN] BTIF's user id will be put to this address ++* RETURNS ++* int 0 = succeed; others = fail, for detailed information, ++* please see ENUM_BTIF_OP_ERROR_CODE ++* if open success, value p_id will be the only identifier for ++* user to access BTIF's other operations ++* including read/write/dpidle_ctrl/rx_cb_retister ++* this user id is only an identifier used for owner identification ++*****************************************************************************/ ++int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id); ++//EXPORT_SYMBOL(mtk_wcn_btif_open) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_close ++* DESCRIPTION ++* close BTIF interface, will do BTIF module HW and SW de-initialization ++* once this API is called, p_btif should never be used by BTIF's user again ++* PARAMETERS ++* u_id [IN] BTIF's user id ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_close(unsigned long u_id); ++//EXPORT_SYMBOL(mtk_wcn_btif_close) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_write ++* DESCRIPTION ++* send data throuth BTIF module ++* there's no internal buffer to cache STP data in BTIF driver, ++* if in DMA mode ++* btif driver will check if there's enough space ++* in vFIFO for data to send in DMA mode ++* if yes, put data to vFIFO and return corresponding data length to caller ++* if no, corresponding error code will be returned to called ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN] pointer to target data to send ++* len [IN] data length (should be less than 2014 bytes per STP package) ++* ++* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller ++* if btif driver detected that no space is available in Tx FIFO, ++* will return E_BTIF_NO_SPACE, ++* mostly something is wrong with BTIF or consys when this ++* return value is returned ++* RETURNS ++* int positive: data length send through BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++* E_BTIF_AGAIN (0) will be returned to caller if btif does not have ++* enough vFIFO to send data, when caller get 0, ++* he should wait for a moment (5~10ms maybe) and ++* try a few times (maybe 10~20) ++* if still get E_BTIF_AGAIN, should call BTIF's debug API and ++* dump BTIF driver and BTIF/DMA register information to kernel log ++* for debug ++* E_BTIF_BAD_POINTER will be returned to caller if btif is not ++* opened successfully before call this API ++* E_BTIF_INVAL_PARAM will be returned if parameter is not valid ++ ++*****************************************************************************/ ++int mtk_wcn_btif_write(unsigned long u_id, ++ const unsigned char *p_buf, unsigned int len); ++//EXPORT_SYMBOL(mtk_wcn_btif_write) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_read ++* DESCRIPTION ++* read data from BTIF module ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN/OUT] pointer to buffer where rx data will be put ++* max_len [IN] max buffer length ++* RETURNS ++* int positive: data length read from BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_read(unsigned long u_id, ++ unsigned char *p_buf, unsigned int max_len); ++//EXPORT_SYMBOL(mtk_wcn_btif_read) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_dpidle_ctrl ++* DESCRIPTION ++* control if BTIF module allow system enter deepidle state or not ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL ++* RETURNS ++* int always return 0 ++*****************************************************************************/ ++int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_rx_cb_register ++* DESCRIPTION ++* register rx callback function to BTIF module by btif user ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* rx_cb [IN] pointer to stp rx handler callback function, ++* should be comply with MTK_WCN_BTIF_RX_CB ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_wakeup_consys ++* DESCRIPTION ++* once sleep command is sent to con sys, ++* should call this API before send wakeup command to ++* make con sys aware host want to send data to consys ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_wakeup_consys(unsigned long u_id); ++ ++/*--------------End of Normal Mode API declearation----------------*/ ++ ++/*--------------Debug Purpose API declearation----------------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_loopback_ctrl ++* DESCRIPTION ++* enable/disable BTIF internal loopback function, ++* when this function is enabled, ++* data send to btif will be received by btif itself ++* only for debug purpose, should never use this function in normal mode ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* enable [IN] loopback mode control flag, enable or disable, ++* shou be one of ENUM_BTIF_LPBK_MODE ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable); ++//EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_logger_ctrl ++* DESCRIPTION ++* control BTIF logger function's behavior ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* flag [IN] should be one of ENUM_BTIF_DBG_ID ++* BTIF_DISABLE_LOGGER - disable btif logger ++* BTIF_ENABLE_LOGGER - enable btif logger ++* BTIF_DUMP_LOG - dump log logged by btif ++* BTIF_CLR_LOG - clear btif log buffer ++* BTIF_DUMP_BTIF_REG - dump btif controller's register ++* BTIF_DUMP_DMA_REG - dump DMA controller's register ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, ++* please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag); ++//EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); ++/*-----------End of Debug Purpose API declearation------------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_parser_wmt_evt ++* DESCRIPTION ++* parser wmt sleep/wakeup evt in btif bbs buffer for debug ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* sub_str [IN] the str to be parsered ++* str_len [IN] the length of sub_str ++* RETURNS ++* bool true = succeed; ++* false = fail; ++*****************************************************************************/ ++bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, ++ const char *sub_str, unsigned int str_len); ++ ++int mtk_btif_exp_open_test(void); ++int mtk_btif_exp_close_test(void); ++int mtk_btif_exp_write_test(void); ++int mtk_btif_exp_suspend_test(void); ++int mtk_btif_exp_resume_test(void); ++int mtk_btif_exp_enter_dpidle_test(void); ++int mtk_btif_exp_exit_dpidle_test(void); ++int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int loop); ++int mtk_btif_exp_log_debug_test(int flag); ++int mtk_btif_exp_restore_noirq_test(void); ++int btif_wakeup_consys_no_id(void); ++int mtk_btif_exp_clock_ctrl(int en); ++#if BTIF_RXD_BE_BLOCKED_DETECT ++int mtk_btif_rxd_be_blocked_flag_get(void); ++#endif ++void mtk_btif_read_cpu_sw_rst_debug_exp(void); ++#endif /*_MTK_BTIF_EXP_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/mtk_btif.c b/drivers/misc/mediatek/btif/common/mtk_btif.c +new file mode 100644 +index 000000000000..5deb64ef3e56 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/mtk_btif.c +@@ -0,0 +1,3472 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/*-----------linux system header files----------------*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*#include */ ++/*-----------driver own header files----------------*/ ++#ifdef CONFIG_COMPAT ++#include ++#endif ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF" ++ ++#define BTIF_CDEV_SUPPORT 1 ++ ++#include "btif_pub.h" ++#include "btif_dma_pub.h" ++#include "mtk_btif_exp.h" ++#include "mtk_btif.h" ++ ++/*-----------static function declearation----------------*/ ++static int mtk_btif_probe(struct platform_device *pdev); ++static int mtk_btif_remove(struct platform_device *pdev); ++static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state); ++static int mtk_btif_resume(struct platform_device *pdev); ++static int mtk_btif_drv_resume(struct device *dev); ++static int mtk_btif_drv_suspend(struct device *pdev); ++ ++static int mtk_btif_restore_noirq(struct device *device); ++static int btif_file_open(struct inode *pinode, struct file *pfile); ++static int btif_file_release(struct inode *pinode, struct file *pfile); ++static ssize_t btif_file_read(struct file *pfile, ++ char __user *buf, size_t count, loff_t *f_ops); ++static unsigned int btif_poll(struct file *filp, poll_table *wait); ++static int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, ++ mtk_btif_irq_handler irq_handler, void *data); ++static int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data); ++static int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en); ++static int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en); ++static irqreturn_t btif_irq_handler(int irq, void *data); ++static unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++ ++static irqreturn_t btif_tx_dma_irq_handler(int irq, void *data); ++static irqreturn_t btif_rx_dma_irq_handler(int irq, void *data); ++ ++static unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++static int _btif_controller_tx_setup(p_mtk_btif p_btif); ++static int _btif_controller_tx_free(p_mtk_btif p_btif); ++static int _btif_controller_rx_setup(p_mtk_btif p_btif); ++static int _btif_controller_rx_free(p_mtk_btif p_btif); ++static int _btif_tx_pio_setup(p_mtk_btif p_btif); ++static int _btif_rx_pio_setup(p_mtk_btif p_btif); ++static int _btif_rx_dma_setup(p_mtk_btif p_btif); ++static int _btif_rx_dma_free(p_mtk_btif p_btif); ++static int _btif_tx_dma_setup(p_mtk_btif p_btif); ++static int _btif_tx_dma_free(p_mtk_btif p_btif); ++static int _btif_controller_setup(p_mtk_btif p_btif); ++static int _btif_controller_free(p_mtk_btif p_btif); ++ ++static int _btif_pio_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++static int _btif_dma_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++ ++static unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len); ++static unsigned int btif_bbs_read(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len); ++static unsigned int btif_bbs_write(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len); ++static void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs); ++static int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len); ++static int _btif_rx_btm_deinit(p_mtk_btif p_btif); ++static int _btif_rx_btm_sched(p_mtk_btif p_btif); ++static int _btif_rx_btm_init(p_mtk_btif p_btif); ++static void btif_rx_tasklet(unsigned long func_data); ++static void btif_rx_worker(struct work_struct *p_work); ++static int btif_rx_thread(void *p_data); ++static int btif_rx_data_consummer(p_mtk_btif p_btif); ++ ++static int _btif_tx_ctx_init(p_mtk_btif p_btif); ++static int _btif_tx_ctx_deinit(p_mtk_btif p_btif); ++static void btif_tx_worker(struct work_struct *p_work); ++ ++static int _btif_state_deinit(p_mtk_btif p_btif); ++static int _btif_state_release(p_mtk_btif p_btif); ++static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif); ++static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state); ++static int _btif_state_hold(p_mtk_btif p_btif); ++static int _btif_state_init(p_mtk_btif p_btif); ++ ++static int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ++ ENUM_BTIF_DPIDLE_CTRL en_flag); ++static int _btif_enter_dpidle(p_mtk_btif p_btif); ++static int _btif_exit_dpidle(p_mtk_btif p_btif); ++static int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif); ++static int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif); ++static int _btif_enter_dpidle_from_on(p_mtk_btif p_btif); ++static int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif); ++ ++#if ENABLE_BTIF_TX_DMA ++static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma); ++static int _btif_vfifo_init(p_mtk_btif_dma p_dma); ++#endif ++ ++static bool _btif_is_tx_complete(p_mtk_btif p_btif); ++static int _btif_init(p_mtk_btif p_btif); ++static int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); ++static int btif_rx_dma_mode_set(int en); ++static int btif_tx_dma_mode_set(int en); ++ ++static int _btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++ ++/*-----------end of static function declearation----------------*/ ++ ++static const char *g_state[B_S_MAX] = { ++ "OFF", ++ "SUSPEND", ++ "DPIDLE", ++ "ON", ++}; ++ ++/*-----------BTIF setting--------------*/ ++mtk_btif_setting g_btif_setting[BTIF_PORT_NR] = { ++ { ++ .tx_mode = BTIF_TX_MODE, ++ .rx_mode = BTIF_RX_MODE, ++ .rx_type = BTIF_RX_BTM_CTX, ++ .tx_type = BTIF_TX_CTX, ++ }, ++}; ++ ++mtk_btif g_btif[BTIF_PORT_NR] = { ++ { ++ .open_counter = 0, ++ .state = B_S_OFF, ++ .setting = &g_btif_setting[0], ++ .p_tx_dma = NULL, ++ .p_rx_dma = NULL, ++ .rx_cb = NULL, ++ .p_btif_info = NULL, ++ }, ++}; ++ ++mtk_btif_dma g_dma[BTIF_PORT_NR][BTIF_DIR_MAX] = { ++ { ++ { ++ .p_btif = NULL, ++ .dir = BTIF_TX, ++ .p_dma_info = NULL, ++ .entry = ATOMIC_INIT(0), ++ }, ++ { ++ .p_btif = NULL, ++ .dir = BTIF_RX, ++ .p_dma_info = NULL, ++ .entry = ATOMIC_INIT(0), ++ }, ++ }, ++}; ++ ++#define G_MAX_PKG_LEN (7 * 1024) ++static int g_max_pkg_len = G_MAX_PKG_LEN; /*DMA vFIFO is set to 8 * 1024, we set this to 7/8 * vFIFO size*/ ++static int g_max_pding_data_size = BTIF_RX_BUFFER_SIZE * 3 / 4; ++ ++ ++static int mtk_btif_dbg_lvl = BTIF_LOG_ERR; ++ ++#if BTIF_RXD_BE_BLOCKED_DETECT ++static struct timeval btif_rxd_time_stamp[MAX_BTIF_RXD_TIME_REC]; ++#endif ++/*-----------Platform bus related structures----------------*/ ++#define DRV_NAME "mtk_btif" ++ ++#ifdef CONFIG_OF ++const struct of_device_id apbtif_of_ids[] = { ++ { .compatible = "mediatek,btif", }, ++ {} ++}; ++#endif ++ ++const struct dev_pm_ops mtk_btif_drv_pm_ops = { ++ .restore_noirq = mtk_btif_restore_noirq, ++ .suspend = mtk_btif_drv_suspend, ++ .resume = mtk_btif_drv_resume, ++}; ++ ++struct platform_driver mtk_btif_dev_drv = { ++ .probe = mtk_btif_probe, ++ .remove = mtk_btif_remove, ++#ifdef CONFIG_PM ++ .suspend = mtk_btif_suspend, ++ .resume = mtk_btif_resume, ++#endif ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++#ifdef CONFIG_PM ++ .pm = &mtk_btif_drv_pm_ops, ++#endif ++#ifdef CONFIG_OF ++ .of_match_table = apbtif_of_ids, ++#endif ++ } ++}; ++ ++#define BTIF_STATE_RELEASE(x) _btif_state_release(x) ++ ++/*-----------End of Platform bus related structures----------------*/ ++ ++/*-----------platform bus related operation APIs----------------*/ ++ ++static int mtk_btif_probe(struct platform_device *pdev) ++{ ++/*Chaozhong: ToDo: to be implement*/ ++/*register IRQ for BTIF and Tx Rx DMA and disable them by default*/ ++ BTIF_INFO_FUNC("DO BTIF PROBE\n"); ++ platform_set_drvdata(pdev, &g_btif[0]); ++ g_btif[0].private_data = (struct device *)&pdev->dev; ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ hal_btif_clk_get_and_prepare(pdev); ++#endif ++ ++ return 0; ++} ++ ++static int mtk_btif_remove(struct platform_device *pdev) ++{ ++/*Chaozhong: ToDo: to be implement*/ ++ BTIF_INFO_FUNC("DO BTIF REMOVE\n"); ++ platform_set_drvdata(pdev, NULL); ++ g_btif[0].private_data = NULL; ++ return 0; ++} ++ ++int _btif_suspend(p_mtk_btif p_btif) ++{ ++ int i_ret; ++ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ if (p_btif != NULL) { ++ if (!(p_btif->enable)) ++ i_ret = 0; ++ else { ++ if (_btif_state_get(p_btif) == B_S_ON) { ++ BTIF_ERR_FUNC("BTIF in ON state,", ++ "there are data need to be send or recev,suspend fail\n"); ++ i_ret = -1; ++ } else { ++ /* ++ * before disable BTIF controller and DMA controller ++ * we need to set BTIF to ON state ++ */ ++ i_ret = _btif_exit_dpidle(p_btif); ++ if (i_ret == 0) { ++ i_ret += _btif_controller_free(p_btif); ++ i_ret = _btif_controller_tx_free(p_btif); ++ i_ret += _btif_controller_rx_free(p_btif); ++ } ++ if (i_ret != 0) { ++ BTIF_INFO_FUNC("failed\n"); ++ /*Chaozhong: what if failed*/ ++ } else { ++ BTIF_INFO_FUNC("succeed\n"); ++ i_ret = _btif_state_set(p_btif, B_S_SUSPEND); ++ if (i_ret && _btif_init(p_btif)) { ++ /*Chaozhong:BTIF re-init failed? what to do*/ ++ i_ret = _btif_state_set(p_btif, B_S_OFF); ++ } ++ } ++ } ++ } ++ } else ++ i_ret = -1; ++ BTIF_STATE_RELEASE(p_btif); ++ ++ return i_ret; ++} ++ ++ ++static int mtk_btif_drv_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ pm_message_t state = PMSG_SUSPEND; ++ ++ return mtk_btif_suspend(pdev, state); ++} ++ ++static int mtk_btif_drv_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ ++ return mtk_btif_resume(pdev); ++} ++ ++static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = NULL; ++ ++/*Chaozhong: ToDo: to be implement*/ ++ BTIF_DBG_FUNC("++\n"); ++ p_btif = platform_get_drvdata(pdev); ++ i_ret = _btif_suspend(p_btif); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++int _btif_restore_noirq(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*BTIF IRQ restore no irq*/ ++ i_ret = hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_RESTORE_NOIRQ); ++ if (i_ret == 0) { ++ BTIF_INFO_FUNC("BTIF HW IRQ restore succeed\n"); ++ } else { ++ BTIF_INFO_FUNC("BTIF HW IRQ restore failed, i_ret:%d\n", i_ret); ++ return i_ret; ++ } ++/*BTIF DMA restore no irq*/ ++ if (p_btif->tx_mode & BTIF_MODE_DMA) { ++ i_ret = hal_dma_pm_ops(p_btif->p_tx_dma->p_dma_info, ++ BTIF_PM_RESTORE_NOIRQ); ++ if (i_ret == 0) { ++ BTIF_INFO_FUNC("BTIF Tx DMA IRQ restore succeed\n"); ++ } else { ++ BTIF_INFO_FUNC ++ ("BTIF Tx DMA IRQ restore failed, i_ret:%d\n", ++ i_ret); ++ return i_ret; ++ } ++ } ++ if (p_btif->rx_mode & BTIF_MODE_DMA) { ++ i_ret = hal_dma_pm_ops(p_btif->p_rx_dma->p_dma_info, ++ BTIF_PM_RESTORE_NOIRQ); ++ if (i_ret == 0) { ++ BTIF_INFO_FUNC("BTIF Rx DMA IRQ restore succeed\n"); ++ } else { ++ BTIF_INFO_FUNC ++ ("BTIF Rx DMA IRQ restore failed, i_ret:%d\n", ++ i_ret); ++ return i_ret; ++ } ++ } ++ return i_ret; ++} ++ ++static int mtk_btif_restore_noirq(struct device *dev) ++{ ++ int i_ret = 0; ++ struct platform_device *pdev = to_platform_device(dev); ++ p_mtk_btif p_btif = platform_get_drvdata(pdev); ++ ++ BTIF_INFO_FUNC("++\n"); ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ if (p_btif->enable) ++ BTIF_ERR_FUNC("!!!-----------------!BTIF is not closed before IPOH shutdown!!!---------------!\n"); ++ WARN_ON(p_btif->enable); ++ ++ i_ret = _btif_restore_noirq(p_btif); ++ BTIF_STATE_RELEASE(p_btif); ++ BTIF_INFO_FUNC("--\n"); ++ return 0; ++} ++ ++int _btif_resume(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ENUM_BTIF_STATE state = B_S_MAX; ++ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ if (p_btif != NULL) { ++ state = _btif_state_get(p_btif); ++ if (!(p_btif->enable)) ++ i_ret = 0; ++ else if (state == B_S_SUSPEND) ++ i_ret = _btif_enter_dpidle(p_btif); ++ else ++ BTIF_INFO_FUNC ++ ("BTIF state: %s before resume, do nothing\n", g_state[state]); ++ } else ++ i_ret = -1; ++ BTIF_STATE_RELEASE(p_btif); ++ ++ return i_ret; ++} ++ ++static int mtk_btif_resume(struct platform_device *pdev) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = NULL; ++/*Chaozhong: ToDo: to be implement*/ ++ BTIF_DBG_FUNC("++\n"); ++ p_btif = platform_get_drvdata(pdev); ++ i_ret = _btif_resume(p_btif); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return 0; ++} ++ ++/*-----------device node----------------*/ ++#if BTIF_CDEV_SUPPORT ++ ++dev_t btif_dev; ++struct class *p_btif_class; ++struct device *p_btif_dev; ++const char *p_btif_dev_name = "btif"; ++static struct semaphore wr_mtx; ++static struct semaphore rd_mtx; ++unsigned char wr_buf[2048]; ++unsigned char rd_buf[2048]; ++static int rx_notify_flag; ++static DECLARE_WAIT_QUEUE_HEAD(btif_wq); ++static int btif_file_open(struct inode *pinode, struct file *pfile); ++static int btif_file_release(struct inode *pinode, struct file *pfile); ++static ssize_t btif_file_read(struct file *pfile, ++ char __user *buf, size_t count, loff_t *f_ops); ++ ++static ssize_t btif_file_write(struct file *filp, ++ const char __user *buf, size_t count, loff_t *f_pos); ++static long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, ++ unsigned long arg); ++#ifdef CONFIG_COMPAT ++static long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); ++#endif ++static struct cdev btif_dev_c; ++static wait_queue_head_t btif_read_inq; /* read queues */ ++ ++const struct file_operations mtk_btif_fops = { ++ .owner = THIS_MODULE, ++ .open = btif_file_open, ++ .release = btif_file_release, ++ .read = btif_file_read, ++ .write = btif_file_write, ++ .unlocked_ioctl = btif_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = btif_compat_ioctl, ++#endif ++ .poll = btif_poll, ++}; ++ ++static int btif_chrdev_init(void) ++{ ++ int i_ret; ++ ++ int i_err; ++ ++ /* alloc device number dynamically */ ++ i_ret = alloc_chrdev_region(&btif_dev, 0, 1, p_btif_dev_name); ++ if (i_ret) { ++ BTIF_ERR_FUNC("devuce number allocation failed, i_ret:%d\n", ++ i_ret); ++ } else { ++ BTIF_INFO_FUNC("devuce number allocation succeed\n"); ++ } ++ cdev_init(&btif_dev_c, &mtk_btif_fops); ++ btif_dev_c.owner = THIS_MODULE; ++ i_err = cdev_add(&btif_dev_c, btif_dev, 1); ++ if (i_err) { ++ BTIF_ERR_FUNC("error add btif dev to kernel, error code:%d\n", ++ i_err); ++ unregister_chrdev_region(btif_dev, 1); ++ btif_dev = 0; ++ return -1; ++ } ++ BTIF_INFO_FUNC("add btif dev to kernel succeed\n"); ++ ++ p_btif_class = class_create(THIS_MODULE, p_btif_dev_name); ++ if (IS_ERR(p_btif_class)) { ++ BTIF_ERR_FUNC("error happened when doing class_create\n"); ++ unregister_chrdev_region(btif_dev, 1); ++ btif_dev = 0; ++ return -2; ++ } ++ BTIF_INFO_FUNC("create class for btif succeed\n"); ++ ++ p_btif_dev = device_create(p_btif_class, ++ NULL, btif_dev, 0, p_btif_dev_name); ++ if (IS_ERR(p_btif_dev)) { ++ BTIF_ERR_FUNC("error happened when doing device_create\n"); ++ class_destroy(p_btif_class); ++ p_btif_class = NULL; ++ unregister_chrdev_region(btif_dev, 1); ++ btif_dev = 0; ++ return -3; ++ } ++ BTIF_INFO_FUNC("create device for btif succeed\n"); ++ ++ return 0; ++} ++ ++void btif_rx_notify_cb(void) ++{ ++ BTIF_DBG_FUNC("++\n"); ++ rx_notify_flag = 1; ++ wake_up(&btif_wq); ++ wake_up_interruptible(&btif_read_inq); ++ BTIF_DBG_FUNC("--\n"); ++} ++ ++unsigned int btif_poll(struct file *filp, poll_table *wait) ++{ ++ unsigned int mask = 0; ++ unsigned int ava_len = 0; ++/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ ++ unsigned int wr_idx = g_btif[0].btif_buf.wr_idx; ++ ++/* BTIF_Rx_IRQ_Disable(); */ ++ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); ++ BTIF_INFO_FUNC("++\n"); ++ if (ava_len == 0) { ++ poll_wait(filp, &btif_read_inq, wait); ++ wr_idx = g_btif[0].btif_buf.wr_idx; ++ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); ++/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ ++ if (ava_len) ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ } else { ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ } ++/*make for writable*/ ++ mask |= POLLOUT | POLLWRNORM; /* writable */ ++ BTIF_INFO_FUNC("--, mask:%d\n", mask); ++ return mask; ++} ++ ++static int _btif_file_open(void) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ BTIF_INFO_FUNC("++\n"); ++ ++/*Chaozhong: ToDo: to be implement*/ ++ i_ret = btif_open(p_btif); ++ if ((i_ret != 0) && (i_ret != E_BTIF_ALREADY_OPEN)) { ++ BTIF_ERR_FUNC("btif_open failed, error code:%d\n", i_ret); ++ } else { ++ BTIF_INFO_FUNC("btif_open succeed\n"); ++ i_ret = 0; ++ } ++/*semaphore for read and write operation init*/ ++ sema_init(&wr_mtx, 1); ++ sema_init(&rd_mtx, 1); ++ ++/*buffer for read and write init*/ ++ memset(wr_buf, 0, sizeof(wr_buf)); ++ memset(rd_buf, 0, sizeof(rd_buf)); ++ init_waitqueue_head(&(btif_read_inq)); ++ btif_rx_notify_reg(p_btif, btif_rx_notify_cb); ++ BTIF_INFO_FUNC("--\n"); ++ return i_ret; ++} ++ ++static int _btif_file_close(void) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("++\n"); ++/*Chaozhong: ToDo: to be implement*/ ++ i_ret = btif_close(&g_btif[0]); ++ if (i_ret != 0) ++ BTIF_ERR_FUNC("btif_close failed, error code:%d\n", i_ret); ++ else ++ BTIF_INFO_FUNC("btif_close succeed\n"); ++ ++ BTIF_INFO_FUNC("--\n"); ++ return i_ret; ++} ++ ++static int btif_file_open(struct inode *pinode, struct file *pfile) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("pid:%d\n", current->pid); ++ i_ret = 0; ++ return i_ret; ++} ++ ++static int btif_file_release(struct inode *pinode, struct file *pfile) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("pid:%d\n", current->pid); ++ i_ret = 0; ++ return i_ret; ++} ++ ++static ssize_t btif_file_read(struct file *pfile, ++ char __user *buf, size_t count, loff_t *f_ops) ++{ ++ int i_ret = 0; ++ int rd_len = 0; ++ ++ BTIF_INFO_FUNC("++\n"); ++ down(&rd_mtx); ++ rd_len = btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); ++ while (rd_len == 0) { ++ if (pfile->f_flags & O_NONBLOCK) ++ break; ++ ++ wait_event(btif_wq, rx_notify_flag != 0); ++ rx_notify_flag = 0; ++ rd_len = ++ btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, ++ sizeof(rd_buf)); ++ } ++ ++ if (rd_len == 0) ++ i_ret = 0; ++ else if ((rd_len > 0) && (copy_to_user(buf, rd_buf, rd_len) == 0)) ++ i_ret = rd_len; ++ else ++ i_ret = -EFAULT; ++ ++ up(&rd_mtx); ++ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++ssize_t btif_file_write(struct file *filp, ++ const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ int i_ret = 0; ++ int copy_size = 0; ++ ++ copy_size = count > sizeof(wr_buf) ? sizeof(wr_buf) : count; ++ ++ BTIF_INFO_FUNC("++\n"); ++ down(&wr_mtx); ++ if (copy_from_user(&wr_buf[0], &buf[0], copy_size)) ++ i_ret = -EFAULT; ++ else ++ i_ret = btif_send_data(&g_btif[0], wr_buf, copy_size); ++ ++ up(&wr_mtx); ++ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); ++ ++ return i_ret; ++} ++#ifdef CONFIG_COMPAT ++long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ BTIF_INFO_FUNC("cmd[0x%x]\n", cmd); ++ ret = btif_unlocked_ioctl(filp, cmd, arg); ++ return ret; ++} ++#endif ++long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++#define BTIF_IOC_MAGIC 0xb0 ++#define BTIF_IOCTL_OPEN _IOW(BTIF_IOC_MAGIC, 1, int) ++#define BTIF_IOCTL_CLOSE _IOW(BTIF_IOC_MAGIC, 2, int) ++#define BTIF_IOCTL_LPBK_CTRL _IOWR(BTIF_IOC_MAGIC, 3, int) ++#define BTIF_IOCTL_LOG_FUNC_CTRL _IOWR(BTIF_IOC_MAGIC, 4, int) ++#define BTIF_IOCTL_RT_LOG_CTRL _IOWR(BTIF_IOC_MAGIC, 5, int) ++#define BTIF_IOCTL_LOG_DUMP _IOWR(BTIF_IOC_MAGIC, 6, int) ++#define BTIF_IOCTL_REG_DUMP _IOWR(BTIF_IOC_MAGIC, 7, int) ++#define BTIF_IOCTL_DMA_CTRL _IOWR(BTIF_IOC_MAGIC, 8, int) ++ ++ long ret = 0; ++/* unsigned char p_buf[NAME_MAX + 1]; */ ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ BTIF_INFO_FUNC("++\n"); ++ BTIF_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); ++ ++ switch (cmd) { ++ case BTIF_IOCTL_OPEN: ++ ret = _btif_file_open(); ++ break; ++ case BTIF_IOCTL_CLOSE: ++ ret = _btif_file_close(); ++ break; ++ case BTIF_IOCTL_LPBK_CTRL: ++ ret = btif_lpbk_ctrl(p_btif, arg == 0 ? 0 : 1); ++ break; ++ case BTIF_IOCTL_LOG_FUNC_CTRL: ++ if (arg == 0) { ++ ret += btif_log_buf_disable(&p_btif->tx_log); ++ ret += btif_log_buf_disable(&p_btif->rx_log); ++ } else { ++ ret += btif_log_buf_enable(&p_btif->tx_log); ++ ret += btif_log_buf_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_IOCTL_RT_LOG_CTRL: ++ if (arg == 0) { ++ ret += btif_log_output_disable(&p_btif->tx_log); ++ ret += btif_log_output_disable(&p_btif->rx_log); ++ } else { ++ ret += btif_log_output_enable(&p_btif->tx_log); ++ ret += btif_log_output_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_IOCTL_LOG_DUMP: ++ ++ ret += btif_log_buf_dmp_out(&p_btif->tx_log); ++ ret += btif_log_buf_dmp_out(&p_btif->rx_log); ++ break; ++ case BTIF_IOCTL_REG_DUMP: ++ ret += btif_dump_reg(p_btif); ++ break; ++ case BTIF_IOCTL_DMA_CTRL: ++ if (arg == 0) { ++ ret += btif_tx_dma_mode_set(0); ++ ret += btif_rx_dma_mode_set(0); ++ } else { ++ ret += btif_tx_dma_mode_set(1); ++ ret += btif_rx_dma_mode_set(1); ++ } ++ break; ++ default: ++ BTIF_INFO_FUNC("unknown cmd(%d)\n", cmd); ++ ret = -2; ++ break; ++ } ++ BTIF_INFO_FUNC("--\n"); ++ return ret; ++} ++ ++#endif ++ ++/*-----------device property----------------*/ ++//static ssize_t driver_flag_read(struct device_driver *drv, char *buf) ++static ssize_t flag_show(struct device_driver *drv, char *buf) ++{ ++ return sprintf(buf, "btif driver debug level:%d\n", mtk_btif_dbg_lvl); ++} ++ ++//static ssize_t driver_flag_set(struct device_driver *drv, ++static ssize_t flag_store(struct device_driver *drv, ++ const char *buffer, size_t count) ++{ ++ char buf[256]; ++ char *p_buf; ++ unsigned long len = count; ++ long x = 0; ++ long y = 0; ++ long z = 0; ++ int result = 0; ++ char *p_token = NULL; ++ char *p_delimiter = " \t"; ++ ++ BTIF_INFO_FUNC("buffer = %s, count = %zd\n", buffer, count); ++ if (len >= sizeof(buf)) { ++ BTIF_ERR_FUNC("input handling fail!\n"); ++ len = sizeof(buf) - 1; ++ return -1; ++ } ++ ++ memcpy(buf, buffer, sizeof(buf)); ++ p_buf = buf; ++ ++ p_token = strsep(&p_buf, p_delimiter); ++ if (p_token != NULL) { ++ result = kstrtol(p_token, 16, &x); ++ BTIF_INFO_FUNC("x = 0x%08x\n\r", x); ++ } else ++ x = 0; ++/* x = (NULL != p_token) ? kstrtol(p_token, 16, NULL) : 0;*/ ++ ++ p_token = strsep(&p_buf, "\t\n "); ++ if (p_token != NULL) { ++ result = kstrtol(p_token, 16, &y); ++ BTIF_INFO_FUNC("y = 0x%08x\n\r", y); ++ } else ++ y = 0; ++ ++ p_token = strsep(&p_buf, "\t\n "); ++ if (p_token != NULL) ++ result = kstrtol(p_token, 16, &z); ++ else ++ z = 0; ++ ++ BTIF_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); ++ ++ switch (x) { ++ case 1: ++ mtk_btif_exp_open_test(); ++ break; ++ case 2: ++ mtk_btif_exp_close_test(); ++ break; ++ case 3: ++ mtk_btif_exp_write_test(); ++ break; ++ case 4: ++ mtk_btif_exp_enter_dpidle_test(); ++ break; ++ case 5: ++ mtk_btif_exp_exit_dpidle_test(); ++ break; ++ case 6: ++ mtk_btif_exp_suspend_test(); ++ break; ++ case 7: ++ mtk_btif_exp_resume_test(); ++ break; ++ case 8: ++ if (y > BTIF_LOG_LOUD) ++ mtk_btif_dbg_lvl = BTIF_LOG_LOUD; ++ else if (y < BTIF_LOG_ERR) ++ mtk_btif_dbg_lvl = BTIF_LOG_WARN; ++ else ++ mtk_btif_dbg_lvl = y; ++ BTIF_ERR_FUNC("mtk_btif_dbg_lvl set to %d\n", mtk_btif_dbg_lvl); ++ break; ++ case 9: ++ mtk_btif_exp_open_test(); ++ mtk_btif_exp_write_test(); ++ mtk_btif_exp_close_test(); ++ break; ++ case 0xa: ++ mtk_btif_exp_log_debug_test(y); ++ break; ++ case 0xb: ++ btif_tx_dma_mode_set(1); ++ btif_rx_dma_mode_set(1); ++ break; ++ case 0xc: ++ btif_tx_dma_mode_set(0); ++ btif_rx_dma_mode_set(0); ++ break; ++ case 0xd: ++ mtk_btif_exp_restore_noirq_test(); ++ break; ++ case 0xe: ++ btif_wakeup_consys_no_id(); ++ break; ++ case 0xf: ++ mtk_btif_exp_clock_ctrl(y); ++ break; ++ case 0x10: ++ y = y > G_MAX_PKG_LEN ? G_MAX_PKG_LEN : y; ++ y = y < 1024 ? 1024 : y; ++ BTIF_INFO_FUNC("g_max_pkg_len is set to %d\n", y); ++ g_max_pkg_len = y; ++ break; ++ case 0x11: ++ y = y > BTIF_RX_BUFFER_SIZE ? BTIF_RX_BUFFER_SIZE : y; ++ y = y < 1024 ? 1024 : y; ++ BTIF_INFO_FUNC("g_max_pding_data_size is set to %d\n", y); ++ g_max_pding_data_size = y; ++ break; ++ default: ++ mtk_btif_exp_open_test(); ++ mtk_btif_exp_write_stress_test(3030, 1); ++ mtk_btif_exp_close_test(); ++ BTIF_WARN_FUNC("not supported.\n"); ++ break; ++ } ++ ++ return count; ++} ++ ++//FWU: driver_ATTR dropped in 4.14 ++//static DRIVER_ATTR(flag, S_IRUGO | S_IWUSR, driver_flag_read, driver_flag_set); ++static DRIVER_ATTR_RW(flag); ++ ++/*-----------End of platform bus related operation APIs------------*/ ++ ++/*-----------------------platform driver ----------------*/ ++ ++int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, ++ mtk_btif_irq_handler irq_handler, void *data) ++{ ++ int i_ret = -1; ++ unsigned int irq_id; ++ unsigned int flag; ++ ++ if ((p_irq == NULL) || (irq_handler == NULL)) ++ return E_BTIF_INVAL_PARAM; ++ ++ if (!(p_irq->is_irq_sup)) { ++ BTIF_WARN_FUNC("%s is not supported\n", p_irq->name); ++ return 0; ++ } ++ ++ irq_id = p_irq->irq_id; ++ ++#ifdef CONFIG_OF ++ flag = p_irq->irq_flags; ++#else ++ switch (p_irq->sens_type) { ++ case IRQ_SENS_EDGE: ++ if (p_irq->edge_type == IRQ_EDGE_FALL) ++ flag = IRQF_TRIGGER_FALLING; ++ else if (p_irq->edge_type == IRQ_EDGE_RAISE) ++ flag = IRQF_TRIGGER_RISING; ++ else if (p_irq->edge_type == IRQ_EDGE_BOTH) ++ flag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; ++ else ++ /*make this as default type */ ++ flag = IRQF_TRIGGER_FALLING; ++ break; ++ case IRQ_SENS_LVL: ++ if (p_irq->lvl_type == IRQ_LVL_LOW) ++ flag = IRQF_TRIGGER_LOW; ++ else if (p_irq->lvl_type == IRQ_LVL_HIGH) ++ flag = IRQF_TRIGGER_HIGH; ++ else ++ /*make this as default type */ ++ flag = IRQF_TRIGGER_LOW; ++ break; ++ default: ++ /*make this as default type */ ++ flag = IRQF_TRIGGER_LOW; ++ break; ++ } ++#endif ++ ++ p_irq->p_irq_handler = irq_handler; ++ i_ret = request_irq(irq_id, ++ (irq_handler_t) irq_handler, ++ flag, p_irq->name, data); ++ if (i_ret) ++ return i_ret; ++ ++ p_irq->reg_flag = true; ++ return 0; ++} ++ ++int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data) ++{ ++ int i_ret = 0; ++ unsigned int eint_num = p_irq->irq_id; ++ ++ if ((p_irq->is_irq_sup) && (p_irq->reg_flag)) { ++ _btif_irq_ctrl(p_irq, false); ++ free_irq(eint_num, data); ++ p_irq->reg_flag = false; ++ } ++/*do nothing for this operation*/ ++ return i_ret; ++} ++ ++int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en) ++{ ++ unsigned int eint_num = p_irq->irq_id; ++ ++ if (en) ++ enable_irq(eint_num); ++ else ++ disable_irq_nosync(eint_num); ++ ++ return 0; ++} ++ ++int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en) ++{ ++ unsigned int eint_num = p_irq->irq_id; ++ ++ if (en) ++ enable_irq(eint_num); ++ else ++ disable_irq(eint_num); ++ ++ return 0; ++} ++ ++ ++irqreturn_t btif_irq_handler(int irq, void *data) ++{ ++/*search BTIF? just use index 0*/ ++/*Chaozhong: do we need lock here?*/ ++ ++ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ ++ ++ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); ++ ++ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, false); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++#endif ++ ++ hal_btif_irq_handler(p_btif->p_btif_info, NULL, 0); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++#endif ++ ++ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, true); ++ _btif_rx_btm_sched(p_btif); ++ ++ BTIF_DBG_FUNC("--\n"); ++ return IRQ_HANDLED; ++} ++ ++irqreturn_t btif_tx_dma_irq_handler(int irq, void *data) ++{ ++/*search BTIF? just use index 0*/ ++ ++ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ ++ p_mtk_btif_dma p_tx_dma = p_btif->p_tx_dma; ++ P_MTK_DMA_INFO_STR p_dma_info = p_tx_dma->p_dma_info; ++ ++ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); ++ _btif_irq_ctrl(p_dma_info->p_irq, false); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); ++#endif ++ ++ hal_tx_dma_irq_handler(p_dma_info); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++#endif ++ _btif_irq_ctrl(p_dma_info->p_irq, true); ++ BTIF_DBG_FUNC("--\n"); ++ return IRQ_HANDLED; ++} ++ ++irqreturn_t btif_rx_dma_irq_handler(int irq, void *data) ++{ ++/*search BTIF? just use index 0*/ ++ ++ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ ++ p_mtk_btif_dma p_rx_dma = p_btif->p_rx_dma; ++ P_MTK_DMA_INFO_STR p_rx_dma_info = p_rx_dma->p_dma_info; ++ ++ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); ++ ++ _btif_irq_ctrl(p_rx_dma_info->p_irq, false); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_ENABLE); ++#endif ++ ++ hal_rx_dma_irq_handler(p_rx_dma_info, NULL, 0); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_DISABLE); ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++#endif ++ ++ _btif_irq_ctrl(p_rx_dma_info->p_irq, true); ++ ++ _btif_rx_btm_sched(p_btif); ++ ++ BTIF_DBG_FUNC("--\n"); ++ ++ return IRQ_HANDLED; ++} ++ ++unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, ++ unsigned int buf_len) ++{ ++ unsigned int index = 0; ++ p_mtk_btif p_btif = &(g_btif[index]); ++ ++#if 0 ++ _btif_dump_memory("", p_buf, buf_len); ++#endif ++ ++ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); ++/*save DMA Rx packet here*/ ++ if (buf_len > 0) ++ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); ++ ++ return 0; ++} ++ ++unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, ++ unsigned int buf_len) ++{ ++ unsigned int index = 0; ++ p_mtk_btif p_btif = &(g_btif[index]); ++ ++#if 0 ++ _btif_dump_memory("", p_buf, buf_len); ++#endif ++ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); ++ ++/*save PIO Rx packet here*/ ++ if (buf_len > 0) ++ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); ++ ++ return 0; ++} ++ ++bool btif_parser_wmt_evt(p_mtk_btif p_btif, ++ const char *sub_str, ++ unsigned int str_len) ++{ ++ unsigned int data_cnt = 0; ++ unsigned int copy_cnt = 0; ++ char *local_buf = NULL; ++ bool b_ret = false; ++ p_btif_buf_str p_bbs = &(p_btif->btif_buf); ++ unsigned int wr_idx = p_bbs->wr_idx; ++ unsigned int rd_idx = p_bbs->rd_idx; ++ ++ data_cnt = copy_cnt = BBS_COUNT(p_bbs); ++ ++ if (data_cnt < str_len) { ++ BTIF_WARN_FUNC("there is not enough data for parser,need(%d),have(%d)\n", str_len, data_cnt); ++ return false; ++ } ++ BTIF_INFO_FUNC("data count in bbs buffer:%d,wr_idx(%d),rd_idx(%d)\n", data_cnt, wr_idx, rd_idx); ++ local_buf = vmalloc((data_cnt + 3) & ~0x3UL); ++ if (!local_buf) { ++ BTIF_WARN_FUNC("vmalloc memory fail\n"); ++ return false; ++ } ++ ++ if (wr_idx >= rd_idx) { ++ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), copy_cnt); ++ } else { ++ unsigned int tail_len = BBS_SIZE(p_bbs) - rd_idx; ++ ++ BTIF_INFO_FUNC("tail_Len(%d)\n", tail_len); ++ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), tail_len); ++ memcpy(local_buf + tail_len, BBS_PTR(p_bbs, 0), copy_cnt - tail_len); ++ } ++ ++ do { ++ int i = 0; ++ int j = 0; ++ int k = 0; ++ int d = 0; ++ ++ BTIF_INFO_FUNC("sub_str_len:%d\n", str_len); ++ for (i = 0; i < copy_cnt; i++) { ++ BTIF_DBG_FUNC("i:%d\n", i); ++ k = i; ++ while (1) { ++ if ((j >= str_len) || (k >= copy_cnt) || (sub_str[j++] != local_buf[k++])) ++ break; ++ } ++ ++ if (j == str_len) { ++ for (d = i; d < (str_len + i); d++) ++ BTIF_INFO_FUNC("0x%2x", local_buf[d]); ++ BTIF_INFO_FUNC("find sub str index:%d\n", i); ++ b_ret = true; ++ break; ++ } ++ if (j < str_len) ++ j = 0; ++ } ++ ++ } while (0); ++ ++ vfree(local_buf); ++ return b_ret; ++} ++int _btif_controller_tx_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_tx_dma_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_tx_dma_setup failed,i_ret(%d),", ++ "set tx to PIO mode\n", i_ret); ++ i_ret = _btif_tx_pio_setup(p_btif); ++ } ++ } else ++/*enable Tx PIO mode*/ ++ i_ret = _btif_tx_pio_setup(p_btif); ++ ++ return i_ret; ++} ++ ++int _btif_controller_tx_free(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_tx_dma_free(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_tx_dma_free failed, i_ret(%d)\n", ++ i_ret); ++ } ++ } else { ++/*do nothing for Tx PIO mode*/ ++ } ++ return i_ret; ++} ++ ++int _btif_controller_rx_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_rx_dma_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_tx_dma_setup failed, i_ret(%d),", ++ "set tx to PIO mode\n", i_ret); ++ i_ret = _btif_rx_pio_setup(p_btif); ++ } ++ } else { ++/*enable Tx PIO mode*/ ++ i_ret = _btif_rx_pio_setup(p_btif); ++ } ++ return i_ret; ++} ++ ++int _btif_controller_rx_free(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_rx_dma_free(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_rx_dma_free failed, i_ret(%d)\n", ++ i_ret); ++ } ++ } else { ++/*do nothing for Rx PIO mode*/ ++ } ++ return i_ret; ++} ++ ++int _btif_tx_pio_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ++/*set Tx to PIO mode*/ ++ p_btif->tx_mode = BTIF_MODE_PIO; ++/*enable Tx PIO mode*/ ++ i_ret = hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); ++ return i_ret; ++} ++ ++int _btif_rx_pio_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; ++ ++ p_btif->rx_mode = BTIF_MODE_PIO; ++/*Enable Rx IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, true); ++/*enable Rx PIO mode*/ ++ i_ret = hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); ++ return i_ret; ++} ++ ++int _btif_rx_dma_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = NULL; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = NULL; ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; ++ ++ p_btif_info = p_btif->p_btif_info; ++ p_btif_irq = p_dma_info->p_irq; ++ ++/*vFIFO reset*/ ++ hal_btif_vfifo_reset(p_dma_info); ++ ++ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d),", ++ "set rx to pio mode\n", i_ret); ++/*DMA control failed set Rx to PIO mode*/ ++ return _btif_rx_pio_setup(p_btif); ++ } ++/*hardware init*/ ++ hal_btif_dma_hw_init(p_dma_info); ++ ++ hal_btif_dma_rx_cb_reg(p_dma_info, ++ (dma_rx_buf_write) btif_dma_rx_data_receiver); ++ ++/*DMA controller enable*/ ++ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", ++ "set rx to pio mode\n", i_ret); ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++/*DMA control failed set Rx to PIO mode*/ ++ i_ret = _btif_rx_pio_setup(p_btif); ++ } else { ++/*enable Rx DMA mode*/ ++ hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); ++ ++/*DMA Rx IRQ register*/ ++ _btif_irq_reg(p_btif_irq, btif_rx_dma_irq_handler, p_btif); ++#if 0 ++/*Enable DMA Rx IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, true); ++#endif ++ BTIF_DBG_FUNC("succeed\n"); ++ } ++ return i_ret; ++} ++ ++int _btif_rx_dma_free(p_mtk_btif p_btif) ++{ ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; ++ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_rx_dma->p_dma_info->p_irq; ++ ++ hal_btif_dma_rx_cb_reg(p_dma_info, (dma_rx_buf_write) NULL); ++ _btif_irq_free(p_irq, p_btif); ++/*disable BTIF Rx DMA channel*/ ++ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); ++/*disable clock output*/ ++ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++} ++ ++int _btif_tx_dma_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = p_dma_info->p_irq; ++ ++/*vFIFO reset*/ ++ hal_btif_vfifo_reset(p_dma_info); ++ ++ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d)\n", ++ i_ret); ++ return i_ret; ++ } ++/*DMA controller setup*/ ++ hal_btif_dma_hw_init(p_dma_info); ++ ++/*DMA HW Enable*/ ++ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", ++ "set tx to pio mode\n", i_ret); ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++#endif ++ ++ _btif_tx_pio_setup(p_btif); ++ } else { ++ hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); ++/*DMA Tx IRQ register*/ ++ _btif_irq_reg(p_btif_irq, btif_tx_dma_irq_handler, p_btif); ++#if 0 ++/*disable DMA Tx IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, false); ++#endif ++ ++ BTIF_DBG_FUNC("succeed\n"); ++ } ++ return i_ret; ++} ++ ++int _btif_tx_dma_free(p_mtk_btif p_btif) ++{ ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; ++ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_tx_dma->p_dma_info->p_irq; ++ ++ _btif_irq_free(p_irq, p_btif); ++/*disable BTIF Tx DMA channel*/ ++ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); ++/*disable clock output*/ ++ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++} ++ ++int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) ++{ ++ int i_ret = -1; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++#if 0 ++ state = _btif_state_get(p_btif); ++ if (p_btif->enable && B_S_ON == state) ++ i_ret = _btif_lpbk_ctrl(p_btif, flag); ++ else ++ i_ret = E_BTIF_INVAL_STATE; ++#endif ++ i_ret = _btif_exit_dpidle(p_btif); ++ if (i_ret == 0) ++ i_ret = _btif_lpbk_ctrl(p_btif, flag); ++ else ++ i_ret = E_BTIF_INVAL_STATE; ++ ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) ++{ ++ int i_ret = -1; ++ ++ if (flag) { ++ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, true); ++ BTIF_DBG_FUNC("loopback function enabled\n"); ++ } else { ++ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, false); ++ BTIF_DBG_FUNC("loopback function disabled\n"); ++ } ++ if (i_ret == 0) ++ p_btif->lpbk_flag = flag; ++ ++ return i_ret; ++} ++ ++int btif_clock_ctrl(p_mtk_btif p_btif, int en) ++{ ++ int i_ret = 0; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ENUM_CLOCK_CTRL ctrl_flag = en == 0 ? CLK_OUT_DISABLE : CLK_OUT_ENABLE; ++ ++ i_ret = hal_btif_clk_ctrl(p_btif_info, ctrl_flag); ++ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ctrl_flag); ++ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ctrl_flag); ++ ++ return i_ret; ++} ++ ++int _btif_controller_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; ++ ++/*BTIF rx buffer init*/ ++/* memset(p_btif->rx_buf, 0, BTIF_RX_BUFFER_SIZE); */ ++ BBS_INIT(&(p_btif->btif_buf)); ++/************************************************/ ++ hal_btif_rx_cb_reg(p_btif_info, ++ (btif_rx_buf_write) btif_pio_rx_data_receiver); ++ ++ i_ret = hal_btif_clk_ctrl(p_btif_info, CLK_OUT_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_clk_ctrl failed, i_ret(%d)\n", i_ret); ++ return i_ret; ++ } ++/*BTIF controller init*/ ++ i_ret = hal_btif_hw_init(p_btif_info); ++ if (i_ret) { ++ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); ++ BTIF_ERR_FUNC("hal_btif_hw_init failed, i_ret(%d)\n", i_ret); ++ return i_ret; ++ } ++ _btif_lpbk_ctrl(p_btif, p_btif->lpbk_flag); ++/*BTIF IRQ register*/ ++ i_ret = _btif_irq_reg(p_btif_irq, btif_irq_handler, p_btif); ++ if (i_ret) { ++ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); ++ ++ BTIF_ERR_FUNC("_btif_irq_reg failed, i_ret(%d)\n", i_ret); ++ return i_ret; ++ } ++ ++/*disable IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, false); ++ i_ret = 0; ++ BTIF_DBG_FUNC("succeed\n"); ++ return i_ret; ++} ++ ++int _btif_controller_free(p_mtk_btif p_btif) ++{ ++/*No need to set BTIF to PIO mode, only enable BTIF CG*/ ++ hal_btif_rx_cb_reg(p_btif->p_btif_info, (btif_rx_buf_write) NULL); ++ _btif_irq_free(p_btif->p_btif_info->p_irq, p_btif); ++ return hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++} ++ ++int _btif_init(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ i_ret = _btif_controller_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_controller_init failed, i_ret(%d)\n", ++ i_ret); ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++ } ++ ++ i_ret = _btif_controller_tx_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", ++ i_ret); ++ _btif_controller_free(p_btif); ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++ } ++ ++ i_ret = _btif_controller_rx_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", ++ i_ret); ++ _btif_controller_tx_free(p_btif); ++ _btif_controller_free(p_btif); ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++ } ++ return i_ret; ++} ++ ++int btif_open(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->enable) ++ return E_BTIF_ALREADY_OPEN; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++/*disable deepidle*/ ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); ++ ++ i_ret = _btif_init(p_btif); ++ if (i_ret == 0) { ++ /*set BTIF's enable flag*/ ++ p_btif->enable = true; ++ _btif_state_set(p_btif, B_S_ON); ++ } else { ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ } ++ btif_log_buf_reset(&p_btif->tx_log); ++ btif_log_buf_reset(&p_btif->rx_log); ++ ++ BTIF_STATE_RELEASE(p_btif); ++ ++ BTIF_DBG_FUNC("BTIF's Tx Mode:%d, Rx Mode(%d)\n", ++ p_btif->tx_mode, p_btif->rx_mode); ++ return i_ret; ++} ++ ++int btif_close(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ if (!(p_btif->enable)) ++ return E_BTIF_NOT_OPEN; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++/*always set state back to B_S_ON before do close operation*/ ++ _btif_exit_dpidle(p_btif); ++/*set BTIF's state to disable state*/ ++ p_btif->enable = false; ++ ++ _btif_controller_free(p_btif); ++ _btif_controller_tx_free(p_btif); ++ _btif_controller_rx_free(p_btif); ++ ++/*reset BTIF's rx_cb function*/ ++ p_btif->rx_cb = NULL; ++ p_btif->rx_notify = NULL; ++ p_btif->lpbk_flag = false; ++ ++/*set state mechine to B_S_OFF*/ ++ _btif_state_set(p_btif, B_S_OFF); ++ ++ btif_log_buf_disable(&p_btif->tx_log); ++ btif_log_buf_disable(&p_btif->rx_log); ++ ++ BTIF_STATE_RELEASE(p_btif); ++ ++ return i_ret; ++} ++ ++int _btif_exit_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ENUM_BTIF_STATE state = B_S_MAX; ++ ++ state = _btif_state_get(p_btif); ++ switch (state) { ++ case B_S_DPIDLE: ++ i_ret = _btif_exit_dpidle_from_dpidle(p_btif); ++ break; ++ case B_S_SUSPEND: ++/*in suspend state, need to do reinit of btif*/ ++ i_ret = _btif_exit_dpidle_from_sus(p_btif); ++ break; ++ case B_S_OFF: ++ i_ret = _btif_init(p_btif); ++ break; ++ case B_S_ON: ++ i_ret = 0; /* for btif_close case */ ++ break; ++ default: ++ i_ret = E_BTIF_INVAL_PARAM; ++ BTIF_INFO_FUNC("invalid state change:%d->\n", state, B_S_ON); ++ break; ++ } ++ ++ if (i_ret == 0) ++ i_ret = _btif_state_set(p_btif, B_S_ON); ++ return i_ret; ++} ++ ++int btif_exit_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ i_ret = _btif_exit_dpidle(p_btif); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int _btif_enter_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ENUM_BTIF_STATE state = B_S_MAX; ++ ++ state = _btif_state_get(p_btif); ++ if (state == B_S_ON) { ++ i_ret = _btif_enter_dpidle_from_on(p_btif); ++ } else if (state == B_S_SUSPEND) { ++ /*do reinit and enter deepidle*/ ++ i_ret = _btif_enter_dpidle_from_sus(p_btif); ++ } else if (state == B_S_DPIDLE) { ++ /*do nothing*/ ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC("operation is not allowed, current state:%d\n", ++ state); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++/*anyway, set to B_S_DPIDLE state*/ ++ if (i_ret == 0) ++ i_ret = _btif_state_set(p_btif, B_S_DPIDLE); ++ return i_ret; ++} ++ ++int btif_enter_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ i_ret = _btif_enter_dpidle(p_btif); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*in dpidle state, only need to open related clock*/ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ /*enable BTIF Tx DMA's clock*/ ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ++ CLK_OUT_ENABLE); ++ } ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ /*enable BTIF Rx DMA's clock*/ ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ++ CLK_OUT_ENABLE); ++ } ++/*enable BTIF's clock*/ ++ i_ret += hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++ ++ if (i_ret != 0) ++ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif) ++{ ++/*in suspend state, need to do driver re-init*/ ++ ++ int i_ret = _btif_init(p_btif); ++ ++ return i_ret; ++} ++ ++int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif) ++{ ++/*do driiver reinit*/ ++ int i_ret = _btif_init(p_btif); ++ ++ if (i_ret == 0) ++ i_ret = _btif_enter_dpidle_from_on(p_btif); ++ return i_ret; ++} ++ ++int _btif_enter_dpidle_from_on(p_mtk_btif p_btif) ++{ ++#define MAX_WAIT_TIME_MS 5000 ++/* ++ * this max wait time cannot exceed 12s, ++ * because dpm will monitor each device's ++ * resume/suspend process by start up a watch dog timer of 12s ++ * incase of one driver's suspend/resume process block other device's suspend/resume ++ */ ++ int i_ret = 0; ++ unsigned int retry = 0; ++ unsigned int wait_period = 1; ++ unsigned int max_retry = MAX_WAIT_TIME_MS / wait_period; ++ struct timeval timer_start; ++ struct timeval timer_now; ++ ++ do_gettimeofday(&timer_start); ++ ++ while ((!_btif_is_tx_complete(p_btif)) && (retry < max_retry)) { ++ do_gettimeofday(&timer_now); ++ if ((MAX_WAIT_TIME_MS/1000) <= (timer_now.tv_sec - timer_start.tv_sec)) { ++ BTIF_WARN_FUNC("max retry timer expired, timer_start.tv_sec:%d, timer_now.tv_sec:%d,", ++ "retry:%d\n", timer_start.tv_sec, timer_now.tv_sec, retry); ++ break; ++ } ++ msleep(wait_period); ++ retry++; ++ } ++ ++ if (retry < max_retry) { ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ /*disable BTIF Tx DMA's clock*/ ++ i_ret += ++ hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ } ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ /*disable BTIF Rx DMA's clock*/ ++ i_ret += ++ hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ } ++/*disable BTIF's clock*/ ++ i_ret += ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++ ++ if (i_ret) ++ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); ++ } else ++ i_ret = -1; ++ ++ return i_ret; ++} ++ ++int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++/*call WCP's API to control deepidle's enable/disable*/ ++ if (en_flag == BTIF_DPIDLE_DISABLE) ++ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_DIS); ++ else ++ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_EN); ++ ++ return 0; ++} ++ ++int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ if (p_btif->rx_cb) { ++ BTIF_WARN_FUNC ++ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", ++ p_btif->rx_cb, rx_cb); ++ } ++ p_btif->rx_cb = rx_cb; ++ ++ return 0; ++} ++ ++int btif_raise_wak_signal(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++#endif ++ ++ i_ret = hal_btif_raise_wak_sig(p_btif_info); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); ++#endif ++ return i_ret; ++} ++ ++bool _btif_is_tx_complete(p_mtk_btif p_btif) ++{ ++ bool b_ret = false; ++ ENUM_BTIF_MODE tx_mode = p_btif->tx_mode; ++ ++/* ++ * make sure BTIF tx finished in PIO mode ++ * make sure BTIF tx finished and DMA tx finished in DMA mode ++ */ ++ if (tx_mode == BTIF_MODE_DMA) { ++ b_ret = hal_dma_is_tx_complete(p_btif->p_tx_dma->p_dma_info); ++ if (b_ret == false) { ++ BTIF_DBG_FUNC("Tx DMA is not finished\n"); ++ return b_ret; ++ } ++ } ++ ++ b_ret = hal_btif_is_tx_complete(p_btif->p_btif_info); ++ if (b_ret == false) { ++ BTIF_DBG_FUNC("BTIF Tx is not finished\n"); ++ return b_ret; ++ } ++ b_ret = true; ++ return b_ret; ++} ++ ++/*--------------------------------Functions-------------------------------------------*/ ++ ++#if ENABLE_BTIF_TX_DMA ++static int _btif_vfifo_init(p_mtk_btif_dma p_dma) ++{ ++ P_DMA_VFIFO p_vfifo = NULL; ++ struct device *dev = NULL; ++ p_mtk_btif p_btif = NULL; ++ ++ if (p_dma == NULL) { ++ BTIF_ERR_FUNC("p_dma is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ p_btif = (p_mtk_btif)p_dma->p_btif; ++ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ dev = (struct device *)p_btif->private_data; ++ if (dev == NULL) ++ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); ++ ++ p_vfifo = p_dma->p_dma_info->p_vfifo; ++ if (p_vfifo->p_vir_addr != NULL) { ++ BTIF_ERR_FUNC ++ ("BTIF vFIFO memory already allocated, do nothing\n"); ++ return E_BTIF_BAD_POINTER; ++ } ++ ++/*vFIFO memory allocation*/ ++ p_vfifo->p_vir_addr = dma_zalloc_coherent(dev, ++ p_vfifo->vfifo_size, ++ &p_vfifo->phy_addr, GFP_DMA | GFP_DMA32); ++ if (p_vfifo->p_vir_addr == NULL) { ++ BTIF_ERR_FUNC("alloc vFIFO memory for BTIF failed\n"); ++ return E_BTIF_FAIL; ++ } ++ ++ if (sizeof(dma_addr_t) == sizeof(unsigned long long)) ++ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch64,vir addr:0x%p,", ++ "phy addr:0x%llx\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); ++ else ++ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch32,vir addr:0x%p,", ++ "phy addr:0x%08x\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); ++ ++ return 0; ++} ++#endif ++#if ENABLE_BTIF_TX_DMA ++static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma) ++{ ++ P_DMA_VFIFO p_vfifo = NULL; ++ struct device *dev = NULL; ++ p_mtk_btif p_btif = NULL; ++ ++ if (p_dma == NULL) { ++ BTIF_ERR_FUNC("p_dma is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ ++ p_btif = (p_mtk_btif)p_dma->p_btif; ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ dev = (struct device *)p_btif->private_data; ++ if (dev == NULL) ++ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); ++ ++ p_vfifo = p_dma->p_dma_info->p_vfifo; ++ ++/*free DMA memory if allocated successfully before*/ ++ if (p_vfifo->p_vir_addr != NULL) { ++ dma_free_coherent(dev, ++ p_vfifo->vfifo_size, ++ p_vfifo->p_vir_addr, p_vfifo->phy_addr); ++ p_vfifo->p_vir_addr = NULL; ++ } ++ ++ return 0; ++} ++#endif ++ ++static int _btif_state_init(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ p_btif->state = B_S_OFF; ++ mutex_init(&(p_btif->state_mtx)); ++ ++ return 0; ++} ++ ++static int _btif_state_hold(p_mtk_btif p_btif) ++{ ++ return mutex_lock_killable(&(p_btif->state_mtx)); ++} ++ ++static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state) ++{ ++/*chaozhong: To do: need to finished state mechine here*/ ++ int i_ret = 0; ++ int ori_state = p_btif->state; ++ ++ if (ori_state == state) { ++ BTIF_INFO_FUNC("already in %s state\n", g_state[state]); ++ return i_ret; ++ } ++ if ((state >= B_S_OFF) && (state < B_S_MAX)) { ++ BTIF_DBG_FUNC("%s->%s request\n", g_state[ori_state], ++ g_state[state]); ++ if (state == B_S_ON) ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); ++ switch (ori_state) { ++ case B_S_ON: ++/*B_S_ON can only be switched to B_S_OFF, B_S_SUSPEND and B_S_DPIDLE*/ ++/*B_S_ON->B_S_OFF : do nothing here*/ ++/* ++ * B_S_ON->B_S_DPLE : disable clock backup ++ * BTIF and DMA controller's register if necessary ++ */ ++ if (state == B_S_DPIDLE) { ++ /*clock controlled id done in _btif_enter_dpidle*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_OFF) { ++ /*clock controlled is done in btif_close*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_SUSPEND) { ++ /*clock controlled is done in btif_close*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ break; ++ case B_S_DPIDLE: ++/*B_S_DPIDLE can only be switched to B_S_ON and B_S_SUSPEND*/ ++/*B_S_DPIDLE-> B_S_ON: do nothing for this moment*/ ++/* ++ * B_S_DPIDLE-> B_S_SUSPEND: ++ * disable clock backup BTIF and DMA controller's register if necessary ++ */ ++ if (state == B_S_ON) { ++ /*clock controlled id done in _btif_exit_dpidle*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_SUSPEND) { ++ /*clock controlled is done in _btif_exit_dpidle*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ break; ++ ++ case B_S_SUSPEND: ++/*B_S_SUSPEND can be switched to B_S_IDLE and B_S_ON*/ ++/*reinit BTIF controller and DMA controller*/ ++ if (state == B_S_DPIDLE) { ++ /* ++ * system call resume API, do resume operation, ++ * change to deepidle state ++ */ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_ON) { ++ /* ++ * when stp want to send data before ++ * system do resume operation ++ */ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ break; ++ ++ case B_S_OFF:{ ++/*B_S_OFF can only be switched to B_S_ON*/ ++ if (state == B_S_ON) { ++ /*clock controlled is done in btif_open*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ } ++ break; ++ default: ++/*no this possibility*/ ++ BTIF_ERR_FUNC ++ ("state change request is not allowed, this should never happen\n"); ++ break; ++ } ++ ++ if (state != B_S_ON) ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ ++ } else { ++ i_ret = E_BTIF_INVAL_PARAM; ++ BTIF_ERR_FUNC("invalid state:%d, do nothing\n", state); ++ } ++ return i_ret; ++} ++ ++static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif) ++{ ++ return p_btif->state; ++} ++ ++static int _btif_state_release(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ BTIF_MUTEX_UNLOCK(&(p_btif->state_mtx)); ++ return i_ret; ++} ++ ++static int _btif_state_deinit(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ p_btif->state = B_S_OFF; ++ mutex_destroy(&(p_btif->state_mtx)); ++ ++ return 0; ++} ++ ++static int btif_rx_data_consummer(p_mtk_btif p_btif) ++{ ++ unsigned int length = 0; ++ unsigned char *p_buf = NULL; ++/*get BTIF rx buffer's information*/ ++ p_btif_buf_str p_bbs = &(p_btif->btif_buf); ++/* ++ * wr_idx of btif_buf may be modified in IRQ handler, ++ * in order not to be effected by case in which irq interrupt this operation, ++ * we record wr_idx here ++ */ ++ unsigned int wr_idx = p_bbs->wr_idx; ++ ++ length = BBS_COUNT_CUR(p_bbs, wr_idx); ++ ++/*make sure length of rx buffer data > 0*/ ++ do { ++ if (length > 0) { ++ /* ++ * check if rx_cb empty or not, if registered , ++ * call user's rx callback to handle these data ++ */ ++ if (p_btif->rx_cb) { ++ if (p_bbs->rd_idx <= wr_idx) { ++ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); ++ /* p_buf = &(p_bbs->buf[p_bbs->rd_idx]); */ ++ /* length = BBS_COUNT(p_bbs); */ ++ length = (wr_idx >= (p_bbs)->rd_idx) ? ++ (wr_idx - (p_bbs)->rd_idx) : ++ BBS_SIZE(p_bbs) - ++ ((p_bbs)->rd_idx - wr_idx); ++ if (p_btif->rx_cb) ++ (*(p_btif->rx_cb)) (p_buf, length); ++ else ++ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); ++ /*update rx data read index*/ ++ p_bbs->rd_idx = wr_idx; ++ } else { ++ unsigned int len_tail = ++ BBS_SIZE(p_bbs) - (p_bbs)->rd_idx; ++ /*p_buf = &(p_bbs->buf[p_bbs->->rd_idx]);*/ ++ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); ++ if (p_btif->rx_cb) ++ (*(p_btif->rx_cb)) (p_buf, len_tail); ++ else ++ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); ++ length = BBS_COUNT_CUR(p_bbs, wr_idx); ++ length -= len_tail; ++ /*p_buf = &(p_bbs->buf[0]);*/ ++ p_buf = BBS_PTR(p_bbs, 0); ++ if (p_btif->rx_cb) ++ (*(p_btif->rx_cb)) (p_buf, length); ++ else ++ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); ++ /*update rx data read index*/ ++ p_bbs->rd_idx = wr_idx; ++ } ++ } else if (p_btif->rx_notify != NULL) { ++ (*p_btif->rx_notify) (); ++ } else { ++ BTIF_WARN_FUNC ++ ("p_btif:0x%p, both rx_notify and rx_cb are NULL\n", ++ p_btif); ++ break; ++ } ++ } else { ++ BTIF_DBG_FUNC("length:%d\n", length); ++ break; ++ } ++ wr_idx = p_bbs->wr_idx; ++ length = BBS_COUNT_CUR(p_bbs, wr_idx); ++ } while (1); ++ return length; ++} ++ ++#if BTIF_RXD_BE_BLOCKED_DETECT ++static int mtk_btif_rxd_be_blocked_by_timer(void) ++{ ++ int ret = 0; ++ int counter = 0; ++ unsigned int i; ++ struct timeval now; ++ int time_gap[MAX_BTIF_RXD_TIME_REC]; ++ ++ do_gettimeofday(&now); ++ ++ for (i = 0; i < MAX_BTIF_RXD_TIME_REC; i++) { ++ BTIF_INFO_FUNC("btif_rxd_time_stamp[%d]=%d.%d\n", i, ++ btif_rxd_time_stamp[i].tv_sec, btif_rxd_time_stamp[i].tv_usec); ++ if (now.tv_sec >= btif_rxd_time_stamp[i].tv_sec) { ++ time_gap[i] = now.tv_sec - btif_rxd_time_stamp[i].tv_sec; ++ time_gap[i] *= 1000000; /*second*/ ++ if (now.tv_usec >= btif_rxd_time_stamp[i].tv_usec) ++ time_gap[i] += now.tv_usec - btif_rxd_time_stamp[i].tv_usec; ++ else ++ time_gap[i] += 1000000 - now.tv_usec + btif_rxd_time_stamp[i].tv_usec; ++ ++ if (time_gap[i] > 1000000) ++ counter++; ++ BTIF_INFO_FUNC("time_gap[%d]=%d,counter:%d\n", i, time_gap[i], counter); ++ } else { ++ time_gap[i] = 0; ++ BTIF_ERR_FUNC("abnormal case now:%d < time_stamp[%d]:%d\n", now.tv_sec, ++ i, btif_rxd_time_stamp[i].tv_usec); ++ } ++ } ++ if (counter > (MAX_BTIF_RXD_TIME_REC - 2)) ++ ret = 1; ++ return ret; ++} ++static int mtk_btif_rxd_be_blocked_by_data(void) ++{ ++ unsigned int out_index = 0; ++ unsigned int in_index = 0; ++ unsigned int dump_size = 0; ++ unsigned int len = 0; ++ unsigned long flags; ++ unsigned int sync_pkt_n = 0; ++ P_BTIF_LOG_BUF_T p_log_buf = NULL; ++ P_BTIF_LOG_QUEUE_T p_log_que = NULL; ++ p_mtk_btif p_btif = &(g_btif[0]); ++ ++ p_log_que = &p_btif->rx_log; ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ in_index = p_log_que->in; ++ dump_size = p_log_que->size; ++ out_index = p_log_que->size >= ++ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - ++ p_log_que->size + ++ in_index) % BTIF_LOG_ENTRY_NUM; ++ if (dump_size != 0) { ++ while (dump_size--) { ++ p_log_buf = p_log_que->p_queue[0] + out_index; ++ len = p_log_buf->len; ++ if (len > BTIF_LOG_SZ) ++ len = BTIF_LOG_SZ; ++ if ((0x7f == *(p_log_buf->buffer)) && (0x7f == *(p_log_buf->buffer + 1))) { ++ sync_pkt_n++; ++ BTIF_INFO_FUNC("tx pkt_count:%d is sync pkt\n", out_index); ++ } ++ out_index++; ++ out_index %= BTIF_LOG_ENTRY_NUM; ++ } ++ } ++ if (sync_pkt_n == 0) ++ BTIF_ERR_FUNC("there is no sync pkt in BTIF buffer\n"); ++ else ++ BTIF_ERR_FUNC("there are %d sync pkt in BTIF buffer\n", sync_pkt_n); ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ return sync_pkt_n; ++} ++ ++int mtk_btif_rxd_be_blocked_flag_get(void) ++{ ++ int ret = 0; ++ int condition1 = 0, condition2 = 0; ++ ++ condition1 = mtk_btif_rxd_be_blocked_by_timer(); ++ condition2 = mtk_btif_rxd_be_blocked_by_data(); ++ if (condition1 && condition2) { ++ BTIF_ERR_FUNC("btif_rxd thread be blocked too long!\n"); ++ ret = 1; ++ } ++ return ret; ++} ++#endif ++static int btif_rx_thread(void *p_data) ++{ ++#if BTIF_RXD_BE_BLOCKED_DETECT ++ unsigned int i = 0; ++#endif ++ p_mtk_btif p_btif = (p_mtk_btif)p_data; ++ ++ ++ while (1) { ++ wait_for_completion_interruptible(&p_btif->rx_comp); ++ ++ if (kthread_should_stop()) { ++ BTIF_WARN_FUNC("btif rx thread stoping ...\n"); ++ break; ++ } ++#ifdef BTIF_RXD_BE_BLOCKED_DETECT ++ do_gettimeofday(&btif_rxd_time_stamp[i]); ++ i++; ++ if (i >= MAX_BTIF_RXD_TIME_REC) ++ i = 0; ++#endif ++ btif_rx_data_consummer(p_btif); ++ } ++ return 0; ++} ++ ++static void btif_rx_worker(struct work_struct *p_work) ++{ ++/*get mtk_btif's pointer*/ ++ p_mtk_btif p_btif = container_of(p_work, mtk_btif, rx_work); ++ ++ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); ++/*lock rx_mutex*/ ++ ++ if (mutex_lock_killable(&(p_btif->rx_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return; ++ } ++ btif_rx_data_consummer(p_btif); ++ BTIF_MUTEX_UNLOCK(&(p_btif->rx_mtx)); ++} ++ ++static void btif_tx_worker(struct work_struct *p_work) ++{ ++ int i_ret = 0; ++ int leng_sent = 0; ++/*tx fifo out*/ ++ int how_much_get = 0; ++ unsigned char local_buf[384]; ++ ++/*get mtk_btif's pointer*/ ++ p_mtk_btif p_btif = container_of(p_work, mtk_btif, tx_work); ++ ++ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); ++ ++ if (mutex_lock_killable(&(p_btif->tx_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return; ++ } ++ how_much_get = ++ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); ++ do { ++ while (leng_sent < how_much_get) { ++ i_ret = _btif_send_data(p_btif, ++ local_buf + leng_sent, ++ how_much_get - leng_sent); ++ if (i_ret > 0) { ++ leng_sent += i_ret; ++ } else if (i_ret == 0) { ++ BTIF_WARN_FUNC ++ ("_btif_send_data return 0, retry\n"); ++ } else { ++ BTIF_WARN_FUNC ++ ("btif send data fail,reset tx fifo, i_ret(%d)\n", ++ i_ret); ++ kfifo_reset(p_btif->p_tx_fifo); ++ break; ++ } ++ } ++ how_much_get = ++ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); ++ leng_sent = 0; ++ } while (how_much_get > 0); ++ BTIF_MUTEX_UNLOCK(&(p_btif->tx_mtx)); ++} ++ ++static void btif_rx_tasklet(unsigned long func_data) ++{ ++ unsigned long flags; ++/*get mtk_btif's pointer*/ ++ p_mtk_btif p_btif = (p_mtk_btif) func_data; ++ ++ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); ++/*lock rx_spinlock*/ ++ spin_lock_irqsave(&p_btif->rx_tasklet_spinlock, flags); ++ btif_rx_data_consummer(p_btif); ++ spin_unlock_irqrestore(&p_btif->rx_tasklet_spinlock, flags); ++} ++ ++static int _btif_tx_ctx_init(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ p_btif->p_tx_wq = create_singlethread_workqueue("btif_txd"); ++ ++ if (!(p_btif->p_tx_wq)) { ++ BTIF_ERR_FUNC ++ ("create_singlethread_workqueue for tx thread fail\n"); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ mutex_init(&(p_btif->tx_mtx)); ++/* init btif tx work */ ++ INIT_WORK(&(p_btif->tx_work), btif_tx_worker); ++ BTIF_INFO_FUNC("btif_tx_worker init succeed\n"); ++ ++ p_btif->p_tx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); ++ if (p_btif->p_tx_fifo == NULL) { ++ i_ret = -ENOMEM; ++ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); ++ goto btm_init_err; ++ } ++ ++ i_ret = kfifo_alloc(p_btif->p_tx_fifo, ++ BTIF_TX_FIFO_SIZE, GFP_ATOMIC); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ } else if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { ++ BTIF_INFO_FUNC ++ ("nothing is done when btif tx in user's thread\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported tx context type:%d\n", ++ p_btif->tx_ctx); ++ goto btm_init_err; ++ } ++ ++ BTIF_INFO_FUNC("succeed\n"); ++ ++ i_ret = 0; ++ return i_ret; ++btm_init_err: ++ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ if (p_btif->p_tx_wq) { ++ destroy_workqueue(p_btif->p_tx_wq); ++ p_btif->p_tx_wq = NULL; ++ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); ++ } ++ kfree(p_btif->p_tx_fifo); ++ } ++ return i_ret; ++} ++ ++static int _btif_tx_ctx_deinit(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ if (p_btif->p_tx_wq) { ++ destroy_workqueue(p_btif->p_tx_wq); ++ p_btif->p_tx_wq = NULL; ++ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); ++ } ++ if (p_btif->p_tx_fifo) { ++ kfifo_free(p_btif->p_tx_fifo); ++ kfree(p_btif->p_tx_fifo); ++ p_btif->p_tx_fifo = NULL; ++ } ++ } ++ return i_ret; ++} ++ ++static int _btif_rx_btm_init(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ init_completion(&p_btif->rx_comp); ++ ++ /*create kernel thread for later rx data handle*/ ++ p_btif->p_task = kthread_create(btif_rx_thread, p_btif, "btif_rxd"); ++ if (p_btif->p_task == NULL) { ++ BTIF_ERR_FUNC("kthread_create fail\n"); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ ++#if ENABLE_BTIF_RX_THREAD_RT_SCHED ++ { ++ int i_ret = -1; ++ int policy = SCHED_FIFO; ++ struct sched_param param; ++ ++ param.sched_priority = MAX_RT_PRIO - 20; ++ i_ret = sched_setscheduler(p_btif->p_task, policy, ¶m); ++ if (i_ret != 0) ++ BTIF_WARN_FUNC("set RT to btif_rxd workqueue failed\n"); ++ else ++ BTIF_INFO_FUNC("set RT to btif_rxd workqueue succeed\n"); ++ } ++#endif ++ ++ wake_up_process(p_btif->p_task); ++ BTIF_INFO_FUNC("btif_rxd start to work!\n"); ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ p_btif->p_rx_wq = create_singlethread_workqueue("btif_rxwq"); ++ if (!(p_btif->p_rx_wq)) { ++ BTIF_ERR_FUNC("create_singlethread_workqueue fail\n"); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ mutex_init(&(p_btif->rx_mtx)); ++ /* init btif rx work */ ++ INIT_WORK(&(p_btif->rx_work), btif_rx_worker); ++ BTIF_INFO_FUNC("btif_rx_worker init succeed\n"); ++ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { ++ /*init rx tasklet*/ ++ tasklet_init(&(p_btif->rx_tasklet), btif_rx_tasklet, ++ (unsigned long)p_btif); ++ spin_lock_init(&(p_btif->rx_tasklet_spinlock)); ++ BTIF_INFO_FUNC("btif_rx_tasklet init succeed\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported rx context type:%d\n", ++ p_btif->btm_type); ++ } ++ ++/*spinlock init*/ ++ spin_lock_init(&(p_btif->rx_irq_spinlock)); ++ BTIF_INFO_FUNC("rx_spin_lock init succeed\n"); ++ ++ i_ret = 0; ++ return i_ret; ++btm_init_err: ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ /*do nothing*/ ++ BTIF_INFO_FUNC("failed\n"); ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ if (p_btif->p_rx_wq) { ++ destroy_workqueue(p_btif->p_rx_wq); ++ p_btif->p_rx_wq = NULL; ++ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); ++ } ++ } ++ return i_ret; ++} ++ ++static int _btif_rx_btm_sched(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ complete(&p_btif->rx_comp); ++ BTIF_DBG_FUNC("schedule btif_rx_thread\n"); ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ queue_work(p_btif->p_rx_wq, &(p_btif->rx_work)); ++ BTIF_DBG_FUNC("schedule btif_rx_worker\n"); ++ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { ++ /*schedule it!*/ ++ tasklet_schedule(&(p_btif->rx_tasklet)); ++ BTIF_DBG_FUNC("schedule btif_rx_tasklet\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported rx context type:%d\n", ++ p_btif->btm_type); ++ } ++ ++ return 0; ++} ++ ++static int _btif_rx_btm_deinit(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ if (p_btif->p_task != NULL) { ++ BTIF_INFO_FUNC("signaling btif rx thread to stop ...\n"); ++ kthread_stop(p_btif->p_task); ++ } ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ if (p_btif->p_rx_wq) { ++ cancel_work_sync(&(p_btif->rx_work)); ++ BTIF_INFO_FUNC("btif_rx_worker cancelled\n"); ++ destroy_workqueue(p_btif->p_rx_wq); ++ p_btif->p_rx_wq = NULL; ++ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); ++ } ++ mutex_destroy(&(p_btif->rx_mtx)); ++ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { ++ tasklet_kill(&(p_btif->rx_tasklet)); ++ BTIF_INFO_FUNC("rx_tasklet killed\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported rx context type:%d\n", ++ p_btif->btm_type); ++ } ++ ++ spin_lock_init(&(p_btif->rx_irq_spinlock)); ++ ++ return 0; ++} ++ ++ ++void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs) ++{ ++ BTIF_INFO_FUNC ++ ("%s UBS:0x%p\n Size:0x%p\n read:0x%08x\n write:0x%08x\n", ++ p_str, p_bbs, p_bbs->size, p_bbs->rd_idx, p_bbs->wr_idx); ++} ++ ++unsigned int btif_bbs_write(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len) ++{ ++/*in IRQ context, so read operation won't interrupt this operation*/ ++ ++ unsigned int wr_len = 0; ++ ++ unsigned int emp_len = BBS_LEFT(p_bbs); ++ unsigned int ava_len = emp_len - 1; ++ p_mtk_btif p_btif = container_of(p_bbs, mtk_btif, btif_buf); ++ ++ if (ava_len <= 0) { ++ BTIF_ERR_FUNC ++ ("no empty space left for write, (%d)ava_len, (%d)to write\n", ++ ava_len, buf_len); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ return 0; ++ } ++ ++ if (ava_len < buf_len) { ++ BTIF_ERR_FUNC("BTIF overrun, (%d)empty, (%d)needed\n", ++ emp_len, buf_len); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ _btif_dump_memory("", p_buf, buf_len); ++ } ++ ++ if (buf_len >= g_max_pkg_len) { ++ BTIF_WARN_FUNC("buf_len too long, (%d)ava_len, (%d)to write\n", ++ ava_len, buf_len); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ _btif_dump_memory("", p_buf, buf_len); ++ } ++ ++ wr_len = min(buf_len, ava_len); ++ btif_bbs_wr_direct(p_bbs, p_buf, wr_len); ++ ++ if (BBS_COUNT(p_bbs) >= g_max_pding_data_size) { ++ BTIF_WARN_FUNC("Rx buf_len too long, size(%d)\n", ++ BBS_COUNT(p_bbs)); ++ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ _btif_dump_memory("", p_buf, buf_len); ++ BBS_INIT(p_bbs); ++ } ++ ++ return wr_len; ++} ++ ++unsigned int btif_bbs_read(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int rd_len = 0; ++ unsigned int ava_len = 0; ++ unsigned int wr_idx = p_bbs->wr_idx; ++ ++ ava_len = BBS_COUNT_CUR(p_bbs, wr_idx); ++ if (ava_len >= 4096) { ++ BTIF_WARN_FUNC("ava_len too long, size(%d)\n", ava_len); ++ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); ++ } ++ if (ava_len != 0) { ++ if (buf_len >= ava_len) { ++ rd_len = ava_len; ++ if (wr_idx >= (p_bbs)->rd_idx) { ++ memcpy(p_buf, BBS_PTR(p_bbs, ++ p_bbs->rd_idx), ++ ava_len); ++ (p_bbs)->rd_idx = wr_idx; ++ } else { ++ unsigned int tail_len = BBS_SIZE(p_bbs) - ++ (p_bbs)->rd_idx; ++ memcpy(p_buf, BBS_PTR(p_bbs, ++ p_bbs->rd_idx), ++ tail_len); ++ memcpy(p_buf + tail_len, BBS_PTR(p_bbs, ++ 0), ava_len - tail_len); ++ (p_bbs)->rd_idx = wr_idx; ++ } ++ } else { ++ rd_len = buf_len; ++ if (wr_idx >= (p_bbs)->rd_idx) { ++ memcpy(p_buf, BBS_PTR(p_bbs, ++ p_bbs->rd_idx), ++ rd_len); ++ (p_bbs)->rd_idx = (p_bbs)->rd_idx + rd_len; ++ } else { ++ unsigned int tail_len = BBS_SIZE(p_bbs) - ++ (p_bbs)->rd_idx; ++ if (tail_len >= rd_len) { ++ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), ++ rd_len); ++ (p_bbs)->rd_idx = ++ ((p_bbs)->rd_idx + rd_len) & (BBS_MASK(p_bbs)); ++ } else { ++ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), tail_len); ++ memcpy(p_buf + tail_len, ++ (p_bbs)->p_buf, rd_len - tail_len); ++ (p_bbs)->rd_idx = rd_len - tail_len; ++ } ++ } ++ } ++ } ++ mb(); ++ return rd_len; ++} ++ ++unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int tail_len = 0; ++ unsigned int l = 0; ++ unsigned int tmp_wr_idx = p_bbs->wr_idx; ++ ++ tail_len = BBS_SIZE(p_bbs) - (tmp_wr_idx & BBS_MASK(p_bbs)); ++ ++ l = min(tail_len, buf_len); ++ ++ memcpy((p_bbs->p_buf) + (tmp_wr_idx & BBS_MASK(p_bbs)), p_buf, l); ++ memcpy(p_bbs->p_buf, p_buf + l, buf_len - l); ++ ++ mb(); ++ ++ tmp_wr_idx += buf_len; ++ tmp_wr_idx &= BBS_MASK(p_bbs); ++ p_bbs->wr_idx = tmp_wr_idx; ++ ++ mb(); ++ return buf_len; ++} ++ ++int _btif_dma_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int i_ret = 0; ++ unsigned int retry = 0; ++ unsigned int max_tx_retry = 10; ++ ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; ++ ++ _btif_irq_ctrl_sync(p_dma_info->p_irq, false); ++ do { ++ /*wait until tx is allowed*/ ++ while (!hal_dma_is_tx_allow(p_dma_info) && ++ (retry < max_tx_retry)) { ++ retry++; ++ if (retry >= max_tx_retry) { ++ BTIF_ERR_FUNC("wait for tx allowed timeout\n"); ++ break; ++ } ++ } ++ if (retry >= max_tx_retry) ++ break; ++ ++ if (buf_len <= hal_dma_get_ava_room(p_dma_info)) ++ i_ret = hal_dma_send_data(p_dma_info, p_buf, buf_len); ++ else ++ i_ret = 0; ++ } while (0); ++ _btif_irq_ctrl_sync(p_dma_info->p_irq, true); ++ return i_ret; ++} ++ ++int _btif_pio_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int i_ret = 0; ++ unsigned int sent_len = 0; ++ unsigned int retry = 0; ++ unsigned int max_tx_retry = 10; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ++ while ((sent_len < buf_len)) { ++ if (hal_btif_is_tx_allow(p_btif_info)) { ++ i_ret = hal_btif_send_data(p_btif_info, ++ p_buf + sent_len, ++ buf_len - sent_len); ++ if (i_ret > 0) { ++ sent_len += i_ret; ++ BTIF_DBG_FUNC("lent sent:%d, total sent:%d\n", ++ i_ret, sent_len); ++ retry = 0; ++ } ++ } ++ if ((++retry > max_tx_retry) || (i_ret < 0)) { ++ BTIF_INFO_FUNC("exceed retry times limit :%d\n", retry); ++ break; ++ } ++ } ++ i_ret = sent_len; ++ return i_ret; ++} ++ ++int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int idx = 0; ++ ++ pr_debug("%s:, length:%d\n", str, buf_len); ++ for (idx = 0; idx < buf_len;) { ++ pr_debug("%02x ", p_buf[idx]); ++ idx++; ++ if (idx % 8 == 0) ++ pr_debug("\n"); ++ } ++ return 0; ++} ++ ++int btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ int i_ret = 0; ++ ++ if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { ++ i_ret = _btif_send_data(p_btif, p_buf, buf_len); ++ } else if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ int length = 0; ++/*tx fifo in*/ ++ length = kfifo_in(p_btif->p_tx_fifo, ++ (unsigned char *)p_buf, buf_len); ++ if (length == buf_len) { ++ queue_work(p_btif->p_tx_wq, &(p_btif->tx_work)); ++ BTIF_DBG_FUNC("schedule btif_tx_worker\n"); ++ i_ret = length; ++ } else { ++ i_ret = 0; ++ BTIF_ERR_FUNC("fifo in failed, target len(%d),in len(%d),", ++ "don't schedule btif_tx_worker\n", buf_len, length); ++ } ++ } else { ++ BTIF_ERR_FUNC("invalid btif tx context:%d\n", p_btif->tx_ctx); ++ i_ret = 0; ++ } ++ ++ return i_ret; ++} ++ ++int _btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ int i_ret = 0; ++ unsigned int state = 0; ++ ++/*make sure BTIF in ON state before doing tx operation*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ state = _btif_state_get(p_btif); ++ ++ if (state != B_S_ON) ++ i_ret = _btif_exit_dpidle(p_btif); ++ ++ if (i_ret != 0) { ++ i_ret = E_BTIF_INVAL_STATE; ++ } else if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ ++ i_ret = _btif_dma_write(p_btif, p_buf, buf_len); ++ } else if (p_btif->tx_mode == BTIF_MODE_PIO) { ++ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ ++ i_ret = _btif_pio_write(p_btif, p_buf, buf_len); ++ } else { ++ BTIF_ERR_FUNC("invalid tx mode:%d\n", p_btif->tx_mode); ++ i_ret = 0; ++ } ++ ++/*save Tx packet here*/ ++ if (i_ret > 0) ++ btif_log_buf_dmp_in(&p_btif->tx_log, p_buf, i_ret); ++ ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int btif_dump_reg(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ unsigned int ori_state = 0; ++ ++/*make sure BTIF in ON state before doing tx operation*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ ori_state = _btif_state_get(p_btif); ++ ++ if (ori_state == B_S_OFF) { ++ i_ret = E_BTIF_INVAL_STATE; ++ BTIF_ERR_FUNC ++ ("BTIF in OFF state, ", ++ "should no need to dump register, ", ++ "please check wmt's operation is okay or not.\n"); ++ goto dmp_reg_err; ++ } ++ ++ if ((ori_state != B_S_ON) && (ori_state < B_S_MAX)) { ++ BTIF_ERR_FUNC("BTIF's original state is %s, not B_S_ON\n", g_state[ori_state]); ++ BTIF_ERR_FUNC("!!!!---<<>>---!!!"); ++ i_ret = _btif_exit_dpidle(p_btif); ++ } ++ ++ if (i_ret != 0) { ++ i_ret = E_BTIF_INVAL_STATE; ++ BTIF_ERR_FUNC("switch to B_S_ON failed\n"); ++ goto dmp_reg_err; ++ } ++ ++/*dump BTIF register*/ ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ ++/*dump BTIF Tx DMA channel register if in DMA mode*/ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) ++ hal_dma_dump_reg(p_btif->p_tx_dma->p_dma_info, REG_TX_DMA_ALL); ++ else ++ BTIF_INFO_FUNC("BTIF Tx in PIO mode,no need to dump Tx DMA's register\n"); ++ ++/*dump BTIF Rx DMA channel register if in DMA mode*/ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ else ++ BTIF_INFO_FUNC("BTIF Rx in PIO mode,no need to dump Rx DMA's register\n"); ++ ++ switch (ori_state) { ++ case B_S_SUSPEND: ++/*return to dpidle state*/ ++/* break; */ ++ case B_S_DPIDLE: ++/*return to dpidle state*/ ++ _btif_enter_dpidle(p_btif); ++ break; ++ case B_S_ON: ++/*nothing needs to be done*/ ++ break; ++ default: ++ break; ++ } ++ ++dmp_reg_err: ++ ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify) ++{ ++ if (p_btif->rx_notify) { ++ BTIF_WARN_FUNC ++ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", ++ p_btif->rx_notify, rx_notify); ++ } ++ p_btif->rx_notify = rx_notify; ++ ++ return 0; ++} ++ ++int btif_dump_data(char *p_buf, int len) ++{ ++ unsigned int idx = 0; ++ unsigned char str[30]; ++ unsigned char *p_str; ++ ++ p_str = &str[0]; ++ for (idx = 0; idx < len; idx++, p_buf++) { ++ sprintf(p_str, "%02x ", *p_buf); ++ p_str += 3; ++ if (7 == (idx % 8)) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ p_str = &str[0]; ++ } ++ } ++ if (len % 8) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ } ++ return 0; ++} ++ ++int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, ++ int len) ++{ ++ P_BTIF_LOG_BUF_T p_log_buf = NULL; ++ char *dir = NULL; ++ struct timeval *p_timer = NULL; ++ unsigned long flags; ++ bool output_flag = false; ++ ++ BTIF_DBG_FUNC("++\n"); ++ ++ if ((p_log_que == NULL) || (p_buf == NULL) || (len == 0)) { ++ BTIF_ERR_FUNC("invalid parameter, p_log_que(0x%x), buf(0x%x), ", ++ "len(%d)\n", p_log_que, p_buf, len); ++ return 0; ++ } ++ if (!(p_log_que->enable)) ++ return 0; ++ ++ dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; ++ output_flag = p_log_que->output_flag; ++ ++ spin_lock_irqsave(&(p_log_que->lock), flags); ++ ++/*get next log buffer for record usage*/ ++ p_log_buf = p_log_que->p_queue[0] + p_log_que->in; ++ p_timer = &p_log_buf->timer; ++ ++/*log time stamp*/ ++ do_gettimeofday(p_timer); ++ ++/*record data information including length and content*/ ++ p_log_buf->len = len; ++ memcpy(p_log_buf->buffer, p_buf, len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len); ++ ++/*update log queue size information*/ ++ p_log_que->size++; ++ p_log_que->size = p_log_que->size > ++ BTIF_LOG_ENTRY_NUM ? BTIF_LOG_ENTRY_NUM : p_log_que->size; ++ ++/*update log queue index information*/ ++ p_log_que->in++; ++ p_log_que->in %= BTIF_LOG_ENTRY_NUM; ++ ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ ++/*check if log dynamic output function is enabled or not*/ ++ if (output_flag) { ++ pr_debug("BTIF-DBG, dir:%s, %d.%ds len:%d\n", ++ dir, (int)p_timer->tv_sec, (int)p_timer->tv_usec, len); ++/*output buffer content*/ ++ btif_dump_data((char *)p_buf, len); ++ } ++ BTIF_DBG_FUNC("--\n"); ++ ++ return 0; ++} ++ ++int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ P_BTIF_LOG_BUF_T p_log_buf = NULL; ++ unsigned int out_index = 0; ++ unsigned int in_index = 0; ++ unsigned int dump_size = 0; ++ unsigned char *p_buf = NULL; ++ unsigned int len = 0; ++ unsigned int pkt_count = 0; ++ unsigned char *p_dir = NULL; ++ struct timeval *p_timer = NULL; ++ unsigned long flags; ++ ++#if 0 /* no matter enable or not, we allowed output */ ++ if (!(p_log_que->enable)) ++ return; ++#endif ++ BTIF_DBG_FUNC("++\n"); ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ in_index = p_log_que->in; ++ dump_size = p_log_que->size; ++ out_index = p_log_que->size >= ++ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - ++ p_log_que->size + ++ in_index) % BTIF_LOG_ENTRY_NUM; ++ p_dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; ++ ++ BTIF_INFO_FUNC("btif %s log buffer size:%d\n", p_dir, dump_size); ++ ++ if (dump_size != 0) { ++ while (dump_size--) { ++ p_log_buf = p_log_que->p_queue[0] + out_index; ++ ++ len = p_log_buf->len; ++ p_buf = p_log_buf->buffer; ++ p_timer = &p_log_buf->timer; ++ ++ len = len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len; ++ ++ BTIF_INFO_FUNC("dir:%s, pkt_count:%d, %d.%ds len:%d\n", ++ p_dir, ++ pkt_count++, ++ (int)p_timer->tv_sec, ++ (int)p_timer->tv_usec, len); ++/*output buffer content*/ ++ btif_dump_data(p_log_buf->buffer, len); ++ out_index++; ++ out_index %= BTIF_LOG_ENTRY_NUM; ++ } ++ } ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_DBG_FUNC("--\n"); ++ ++ return 0; ++} ++ ++int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->enable = true; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("enable %s log function\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->enable = false; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("disable %s log function\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->output_flag = true; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("%s log rt output enabled\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->output_flag = false; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("%s log rt output disabled\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ ++/*tx log buffer init*/ ++ p_log_que->in = 0; ++ p_log_que->out = 0; ++ p_log_que->size = 0; ++ p_log_que->enable = true; ++ memset((p_log_que->p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); ++ ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_DBG_FUNC("reset %s log buffer\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_buf_init(p_mtk_btif p_btif) ++{ ++/*tx log buffer init*/ ++ p_btif->tx_log.dir = BTIF_TX; ++ p_btif->tx_log.in = 0; ++ p_btif->tx_log.out = 0; ++ p_btif->tx_log.size = 0; ++ p_btif->tx_log.output_flag = false; ++ p_btif->tx_log.enable = true; ++ spin_lock_init(&(p_btif->tx_log.lock)); ++ BTIF_DBG_FUNC("tx_log.p_queue:0x%p\n", p_btif->tx_log.p_queue[0]); ++ memset((p_btif->tx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); ++ ++/*rx log buffer init*/ ++ p_btif->rx_log.dir = BTIF_RX; ++ p_btif->rx_log.in = 0; ++ p_btif->rx_log.out = 0; ++ p_btif->rx_log.size = 0; ++ p_btif->rx_log.output_flag = false; ++ p_btif->rx_log.enable = true; ++ spin_lock_init(&(p_btif->rx_log.lock)); ++ BTIF_DBG_FUNC("rx_log.p_queue:0x%p\n", p_btif->rx_log.p_queue[0]); ++ memset((p_btif->rx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); ++ ++ return 0; ++} ++ ++int btif_tx_dma_mode_set(int en) ++{ ++ int index = 0; ++ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; ++ ++ for (index = 0; index < BTIF_PORT_NR; index++) ++ g_btif[index].tx_mode = mode; ++ ++ return 0; ++} ++ ++int btif_rx_dma_mode_set(int en) ++{ ++ int index = 0; ++ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; ++ ++ for (index = 0; index < BTIF_PORT_NR; index++) ++ g_btif[index].rx_mode = mode; ++ ++ return 0; ++} ++ ++static int BTIF_init(void) ++{ ++ int i_ret = -1; ++ int index = 0; ++ p_mtk_btif_dma p_tx_dma = NULL; ++ p_mtk_btif_dma p_rx_dma = NULL; ++ unsigned char *p_btif_buffer = NULL; ++ unsigned char *p_tx_queue = NULL; ++ unsigned char *p_rx_queue = NULL; ++ ++ BTIF_DBG_FUNC("++\n"); ++ ++/*Platform Driver initialization*/ ++ i_ret = platform_driver_register(&mtk_btif_dev_drv); ++ if (i_ret) { ++ BTIF_ERR_FUNC("BTIF platform driver registered failed, ret(%d)\n", i_ret); ++ goto err_exit1; ++ } ++ ++ i_ret = driver_create_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); ++ if (i_ret) ++ BTIF_ERR_FUNC("BTIF pdriver_create_file failed, ret(%d)\n", i_ret); ++ ++/*SW init*/ ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ p_btif_buffer = kmalloc(BTIF_RX_BUFFER_SIZE, GFP_ATOMIC); ++ if (!p_btif_buffer) { ++ BTIF_ERR_FUNC("p_btif_buffer kmalloc memory fail\n"); ++ return -1; ++ } ++ BTIF_INFO_FUNC("p_btif_buffer get memory 0x%p\n", p_btif_buffer); ++ p_tx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); ++ if (!p_tx_queue) { ++ BTIF_ERR_FUNC("p_tx_queue kmalloc memory fail\n"); ++ kfree(p_btif_buffer); ++ return -1; ++ } ++ BTIF_INFO_FUNC("p_tx_queue get memory 0x%p\n", p_tx_queue); ++ p_rx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); ++ if (!p_rx_queue) { ++ BTIF_ERR_FUNC("p_rx_queue kmalloc memory fail\n"); ++ kfree(p_btif_buffer); ++ kfree(p_tx_queue); ++ return -1; ++ } ++ BTIF_INFO_FUNC("p_rx_queue get memory 0x%p\n", p_rx_queue); ++ ++ INIT_LIST_HEAD(&(g_btif[index].user_list)); ++ BBS_INIT(&(g_btif[index].btif_buf)); ++ g_btif[index].enable = false; ++ g_btif[index].open_counter = 0; ++ g_btif[index].setting = &g_btif_setting[index]; ++ g_btif[index].p_btif_info = hal_btif_info_get(); ++ g_btif[index].tx_mode = g_btif_setting[index].tx_mode; ++ g_btif[index].rx_mode = g_btif_setting[index].rx_mode; ++ g_btif[index].btm_type = g_btif_setting[index].rx_type; ++ g_btif[index].tx_ctx = g_btif_setting[index].tx_type; ++ g_btif[index].lpbk_flag = false; ++ g_btif[index].rx_cb = NULL; ++ g_btif[index].rx_notify = NULL; ++ g_btif[index].btif_buf.p_buf = p_btif_buffer; ++ g_btif[index].tx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_tx_queue; ++ g_btif[index].rx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_rx_queue; ++ btif_log_buf_init(&g_btif[index]); ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++/*enable BTIF clock gating by default*/ ++ i_ret = hal_btif_clk_ctrl(g_btif[index].p_btif_info, ++ CLK_OUT_DISABLE); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF controller CG failed\n"); ++ goto err_exit2; ++ } ++#endif ++ ++/* ++ * viftual FIFO memory must be physical continious, ++ * because DMA will access it directly without MMU ++ */ ++#if ENABLE_BTIF_TX_DMA ++ p_tx_dma = &g_dma[index][BTIF_TX]; ++ g_btif[index].p_tx_dma = p_tx_dma; ++ p_tx_dma->dir = BTIF_TX; ++ p_tx_dma->p_btif = &(g_btif[index]); ++ ++/*DMA Tx vFIFO initialization*/ ++ p_tx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_TX); ++/*spinlock init*/ ++ spin_lock_init(&(p_tx_dma->iolock)); ++/*entry setup*/ ++ atomic_set(&(p_tx_dma->entry), 0); ++/*vFIFO initialization*/ ++ i_ret = _btif_vfifo_init(p_tx_dma); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Tx vFIFO allocation failed\n"); ++ goto err_exit2; ++ } ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++/*enable BTIF Tx DMA channel's clock gating by default*/ ++ i_ret = hal_btif_dma_clk_ctrl(p_tx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Tx DMA's CG failed\n"); ++ goto err_exit2; ++ } ++#endif ++ ++#else ++ g_btif[index].p_tx_dma = NULL; ++/*force tx mode to DMA no matter what it is in default setting*/ ++ g_btif[index].tx_mode = BTIF_MODE_PIO; ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++ p_rx_dma = &g_dma[index][BTIF_RX]; ++ g_btif[index].p_rx_dma = p_rx_dma; ++ p_rx_dma->p_btif = &(g_btif[index]); ++ p_rx_dma->dir = BTIF_RX; ++ ++/*DMA Tx vFIFO initialization*/ ++ p_rx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_RX); ++/*spinlock init*/ ++ spin_lock_init(&(p_rx_dma->iolock)); ++/*entry setup*/ ++ atomic_set(&(p_rx_dma->entry), 0); ++/*vFIFO initialization*/ ++ i_ret = _btif_vfifo_init(p_rx_dma); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Rx vFIFO allocation failed\n"); ++ goto err_exit2; ++ } ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++/*enable BTIF Tx DMA channel's clock gating by default*/ ++ i_ret = hal_btif_dma_clk_ctrl(p_rx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Rx DMA's CG failed\n"); ++ goto err_exit2; ++ } ++#endif ++ ++#else ++ g_btif[index].p_rx_dma = NULL; ++/*force rx mode to DMA no matter what it is in default setting*/ ++ g_btif[index].rx_mode = BTIF_MODE_PIO; ++ ++#endif ++/*PM state mechine initialization*/ ++ i_ret = _btif_state_init(&(g_btif[index])); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF state mechanism init failed\n"); ++ goto err_exit2; ++ } ++ ++/*Rx bottom half initialization*/ ++ i_ret = _btif_rx_btm_init(&(g_btif[index])); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Rx btm init failed\n"); ++ goto err_exit3; ++ } ++ i_ret = _btif_tx_ctx_init(&(g_btif[index])); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Tx context init failed\n"); ++ goto err_exit4; ++ } ++/*Character Device initialization*/ ++/*Chaozhong: ToDo: to be initialized*/ ++ ++ mutex_init(&g_btif[index].ops_mtx); ++ } ++ ++/*Debug purpose initialization*/ ++ ++#if BTIF_CDEV_SUPPORT ++ btif_chrdev_init(); ++#endif ++ ++ return 0; ++ ++err_exit4: ++ for (index = 0; index < BTIF_PORT_NR; index++) ++ _btif_tx_ctx_deinit(&(g_btif[index])); ++ ++err_exit3: ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ _btif_rx_btm_deinit(&(g_btif[index])); ++ ++ _btif_state_deinit(&(g_btif[index])); ++ } ++ ++err_exit2: ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ p_tx_dma = &g_dma[index][BTIF_TX]; ++ p_rx_dma = &g_dma[index][BTIF_RX]; ++#if ENABLE_BTIF_TX_DMA ++ _btif_vfifo_deinit(p_tx_dma); ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++ _btif_vfifo_deinit(p_rx_dma); ++#endif ++ g_btif[index].open_counter = 0; ++ g_btif[index].enable = false; ++ } ++ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); ++ platform_driver_unregister(&mtk_btif_dev_drv); ++ ++err_exit1: ++ i_ret = -1; ++ BTIF_DBG_FUNC("--\n"); ++ return i_ret; ++} ++ ++static void BTIF_exit(void) ++{ ++ unsigned int index = 0; ++ p_mtk_btif_dma p_tx_dma = NULL; ++ p_mtk_btif_dma p_rx_dma = NULL; ++ ++ BTIF_DBG_FUNC("++\n"); ++ ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ g_btif[index].open_counter = 0; ++ g_btif[index].enable = false; ++ p_tx_dma = &g_dma[index][BTIF_TX]; ++ p_rx_dma = &g_dma[index][BTIF_RX]; ++#if ENABLE_BTIF_TX_DMA ++ _btif_vfifo_deinit(p_tx_dma); ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++ _btif_vfifo_deinit(p_rx_dma); ++#endif ++ _btif_state_deinit(&(g_btif[index])); ++ ++ _btif_rx_btm_deinit(&(g_btif[index])); ++ ++ mutex_destroy(&g_btif[index].ops_mtx); ++ } ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ hal_btif_clk_unprepare(); ++#endif ++ ++ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); ++ platform_driver_unregister(&mtk_btif_dev_drv); ++ BTIF_DBG_FUNC("--\n"); ++} ++ ++int mtk_btif_hal_get_log_lvl(void) ++{ ++ return mtk_btif_dbg_lvl; ++} ++ ++void mtk_btif_read_cpu_sw_rst_debug(void) ++{ ++ mtk_btif_read_cpu_sw_rst_debug_plat(); ++} ++ ++/*---------------------------------------------------------------------------*/ ++ ++module_init(BTIF_init); ++module_exit(BTIF_exit); ++ ++/*---------------------------------------------------------------------------*/ ++ ++MODULE_AUTHOR("MBJ/WCN/SE/SS1/Chaozhong.Liang"); ++MODULE_DESCRIPTION("MTK BTIF Driver$1.0$"); ++MODULE_LICENSE("GPL"); ++ ++/*---------------------------------------------------------------------------*/ +diff --git a/drivers/misc/mediatek/btif/common/mtk_btif_exp.c b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c +new file mode 100644 +index 000000000000..c0df44558357 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c +@@ -0,0 +1,786 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF-EXP" ++ ++/*#include "mtk_btif_exp.h"*/ ++#include "mtk_btif.h" ++ ++/*---------------------------------Function----------------------------------*/ ++ ++p_mtk_btif btif_exp_srh_id(unsigned long u_id) ++{ ++ int index = 0; ++ p_mtk_btif p_btif = NULL; ++ struct list_head *p_list = NULL; ++ struct list_head *tmp = NULL; ++ p_mtk_btif_user p_user = NULL; ++ ++ for (index = 0; (index < BTIF_PORT_NR) && (p_btif == NULL); index++) { ++ p_list = &(g_btif[index].user_list); ++ list_for_each(tmp, p_list) { ++ p_user = container_of(tmp, mtk_btif_user, entry); ++ if (u_id == p_user->u_id) { ++ p_btif = p_user->p_btif; ++ BTIF_DBG_FUNC ++ ("BTIF's user id(0x%p), p_btif(0x%p)\n", ++ p_user->u_id, p_btif); ++ break; ++ } ++ } ++ } ++ if (p_btif == NULL) { ++ BTIF_INFO_FUNC ++ ("no btif structure found for BTIF's user id(0x%lx)\n", ++ u_id); ++ } ++ return p_btif; ++} ++ ++/*-----Normal Mode API declearation-------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_open ++* DESCRIPTION ++* open BTIF interface, will do BTIF module HW and SW initialization ++* PARAMETERS ++* p_owner [IN] pointer to owner who call this API, ++* currently there are 2 owner ("stp" or "btif_tester") ++* may use this module ++* for "stp", BTIF will call rx callback function to route rx data to STP module ++* for "stp_tester", BTIF will save rx data and wait for native process to access ++* p_id [IN] BTIF's user id will be put to this address ++* RETURNS ++* int 0 = BTIF module initialization fail; negative = BTIF module initialization success ++* if open success, value p_id will be the only identifier ++* for user to access BTIF's other operations ++* including read/write/dpidle_ctrl/rx_cb_retister ++* this user id is only an identifier used for owner identification ++*****************************************************************************/ ++int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id) ++{ ++ int i_ret = -1; ++ unsigned int index = 0; ++ p_mtk_btif_user p_new_user = NULL; ++ p_mtk_btif p_btif = &g_btif[index]; ++ struct list_head *p_user_list = &(p_btif->user_list); ++ ++ BTIF_DBG_FUNC("++"); ++ BTIF_DBG_FUNC("p_btif(0x%p)\n", p_btif); ++ ++ if (mutex_lock_killable(&(p_btif->ops_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return E_BTIF_INTR; ++ } ++ if ((p_owner == NULL) || (p_id == NULL)) { ++ if (p_id) ++ *p_id = 0; ++ BTIF_ERR_FUNC("parameter invalid, p_owner(0x%p), p_id(0x%p)\n", ++ p_owner, p_id); ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++/*check if btif is already opened or not, if yes, just return fail*/ ++ if (!list_empty(p_user_list)) { ++ struct list_head *pos; ++ p_mtk_btif_user p_user; ++ ++ BTIF_ERR_FUNC("BTIF's user list is not empty\n"); ++ list_for_each(pos, p_user_list) { ++ p_user = container_of(pos, mtk_btif_user, entry); ++ BTIF_INFO_FUNC("BTIF's user id(0x%lx), name(%s)\n", ++ p_user->u_id, p_user->u_name); ++ } ++/*leave p_id alone*/ ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ return E_BTIF_ALREADY_OPEN; ++ } ++ p_new_user = vmalloc(sizeof(mtk_btif_user)); ++ ++ if (p_new_user != NULL) { ++ INIT_LIST_HEAD(&(p_new_user->entry)); ++ p_new_user->enable = false; ++ p_new_user->p_btif = p_btif; ++ p_new_user->u_id = (unsigned long)p_new_user; ++ strncpy(p_new_user->u_name, p_owner, sizeof(p_new_user->u_name) - 1); ++ p_new_user->u_name[sizeof(p_new_user->u_name) - 1] = '\0'; ++ BTIF_DBG_FUNC("owner name:%s, recorded name:%s\n", ++ p_owner, p_new_user->u_name); ++ ++ i_ret = btif_open(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); ++ *p_id = 0; ++/*free btif new user's structure*/ ++ vfree(p_new_user); ++ p_new_user = NULL; ++ } else { ++ BTIF_INFO_FUNC("btif_open succeed\n"); ++ *p_id = p_new_user->u_id; ++/*mark enable flag to true*/ ++ p_new_user->enable = true; ++/*add to uer lsit*/ ++ list_add_tail(&(p_new_user->entry), p_user_list); ++ } ++ } else { ++ *p_id = 0; ++ i_ret = -ENOMEM; ++ BTIF_ERR_FUNC("allocate memory for mtk_btif_user failed\n"); ++ } ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ BTIF_DBG_FUNC("--"); ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_open); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_close ++* DESCRIPTION ++* close BTIF interface, will do BTIF module HW and SW de-initialization ++* once this API is called, p_btif should never be used by BTIF's user again ++* PARAMETERS ++* u_id [IN] BTIF's user id ++* RETURNS ++* int 0 = succeed; ++* others = fail, ++* for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_close(unsigned long u_id) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ struct list_head *pos = NULL; ++ struct list_head *p_user_list = NULL; ++ ++ BTIF_DBG_FUNC("++"); ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ if (mutex_lock_killable(&(p_btif->ops_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return E_BTIF_INTR; ++ } ++ p_user_list = &(p_btif->user_list); ++ list_for_each(pos, p_user_list) { ++ p_mtk_btif_user p_user = ++ container_of(pos, mtk_btif_user, entry); ++ ++ if (p_user->u_id == u_id) { ++ BTIF_INFO_FUNC ++ ("user who's id is 0x%lx deleted from user list\n", ++ u_id); ++ list_del(pos); ++ vfree(p_user); ++ i_ret = btif_close(p_btif); ++ if (i_ret) ++ BTIF_WARN_FUNC("BTIF close failed"); ++ break; ++ } ++ } ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ BTIF_DBG_FUNC("--"); ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_close); ++ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_write ++* DESCRIPTION ++* send data throuth BTIF module ++* there's no internal buffer to cache STP data in BTIF driver, ++* if in DMA mode ++* btif driver will check if there's enough space in vFIFO for data to send in DMA mode ++* if yes, put data to vFIFO and return corresponding data length to caller ++* if no, corresponding error code will be returned to called ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN] pointer to target data to send ++* len [IN] data length (should be less than 2014 bytes per STP package) ++* ++* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller ++* if btif driver detected that no space is available in Tx FIFO, ++* will return E_BTIF_NO_SPACE, mostly something is wrong with BTIF or ++* consys when this return value is returned ++* RETURNS ++* int positive: data length send through BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++* E_BTIF_AGAIN (0) will be returned to caller ++* if btif does not have enough vFIFO to send data, ++* when caller get 0, he should wait for a moment ++* (5~10ms maybe) and try a few times (maybe 10~20) ++* if still get E_BTIF_AGAIN, ++* should call BTIF's debug API and dump BTIF driver ++* and BTIF/DMA register information to kernel log for debug ++* E_BTIF_BAD_POINTER will be returned to caller ++* if btif is not opened successfully before call this API ++* E_BTIF_INVAL_PARAM will be returned if parameter is not valid ++ ++*****************************************************************************/ ++int mtk_wcn_btif_write(unsigned long u_id, ++ const unsigned char *p_buf, unsigned int len) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ BTIF_DBG_FUNC("++"); ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ if (p_buf == NULL) { ++ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); ++ return E_BTIF_INVAL_PARAM; ++ } ++ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { ++ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ i_ret = btif_send_data(p_btif, p_buf, len); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_write); ++ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_read ++* DESCRIPTION ++* read data from BTIF module ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN/OUT] pointer to buffer where rx data will be put ++* max_len [IN] max buffer length ++* RETURNS ++* int positive: data length read from BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_read(unsigned long u_id, ++ unsigned char *p_buf, unsigned int max_len) ++{ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_dpidle_ctrl ++* DESCRIPTION ++* control if BTIF module allow system enter deepidle state or not ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL ++* RETURNS ++* int always return 0 ++*****************************************************************************/ ++int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ if (en_flag == BTIF_DPIDLE_DISABLE) ++ i_ret = btif_exit_dpidle(p_btif); ++ else ++ i_ret = btif_enter_dpidle(p_btif); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_dpidle_ctrl); ++ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_rx_cb_register ++* DESCRIPTION ++* register rx callback function to BTIF module by btif user ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* rx_cb [IN] pointer to stp rx handler callback function, ++* should be comply with MTK_WCN_BTIF_RX_CB ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, ++* please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ i_ret = btif_rx_cb_reg(p_btif, rx_cb); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_rx_cb_register); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_wakeup_consys ++* DESCRIPTION ++* once sleep command is sent to con sys, ++* should call this API before send wakeup command ++* to make con sys aware host want to send data to consys ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* RETURNS ++* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_wakeup_consys(unsigned long u_id) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ ++ i_ret = btif_raise_wak_signal(p_btif); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_wakeup_consys); ++ ++ ++/***************End of Normal Mode API declearation**********/ ++ ++/***************Debug Purpose API declearation**********/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_loopback_ctrl ++* DESCRIPTION ++* enable/disable BTIF internal loopback function, ++* when this function is enabled data send to btif ++* will be received by btif itself ++* only for debug purpose, should never use this function in normal mode ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* enable [IN] loopback mode control flag, enable or disable, ++* shou be one of ENUM_BTIF_LPBK_MODE ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ i_ret = ++ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_logger_ctrl ++* DESCRIPTION ++* control BTIF logger function's behavior ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* flag [IN] should be one of ENUM_BTIF_DBG_ID ++* BTIF_DISABLE_LOGGER - disable btif logger ++* BTIF_ENABLE_LOGGER - enable btif logger ++* BTIF_DUMP_LOG - dump log logged by btif ++* BTIF_CLR_LOG - clear btif log buffer ++* BTIF_DUMP_BTIF_REG - dump btif controller's register ++* BTIF_DUMP_DMA_REG - dump DMA controller's register ++* RETURNS ++* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ i_ret = 0; ++ switch (flag) { ++ case BTIF_DISABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("disable btif log function for both Tx and Rx\n"); ++ btif_log_buf_disable(&p_btif->tx_log); ++ btif_log_buf_disable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_ENABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("enable btif log function for both Tx and Rx\n"); ++ btif_log_buf_enable(&p_btif->tx_log); ++ btif_log_buf_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_LOG:{ ++ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); ++ btif_log_buf_dmp_out(&p_btif->tx_log); ++ btif_log_buf_dmp_out(&p_btif->rx_log); ++ } ++ break; ++ ++ case BTIF_CLR_LOG:{ ++ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); ++ btif_log_buf_reset(&p_btif->tx_log); ++ btif_log_buf_reset(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_BTIF_REG: ++ /*TBD*/ btif_dump_reg(p_btif); ++ break; ++ case BTIF_ENABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("enable btif real time log for both Tx and Rx\n"); ++ btif_log_output_enable(&p_btif->tx_log); ++ btif_log_output_enable(&p_btif->rx_log); ++ break; ++ case BTIF_DISABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("disable btif real time log for both Tx and Rx\n"); ++ btif_log_output_disable(&p_btif->tx_log); ++ btif_log_output_disable(&p_btif->rx_log); ++ break; ++ default: ++ BTIF_INFO_FUNC("not supported flag:%d\n", flag); ++ i_ret = -2; ++ break; ++ } ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); ++ ++bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, ++ const char *sub_str, unsigned int str_len) ++{ ++ bool b_ret = false; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ b_ret = btif_parser_wmt_evt(p_btif, sub_str, str_len); ++ BTIF_INFO_FUNC("parser wmt evt %s\n", b_ret ? "ok" : "fail"); ++ ++ return b_ret; ++} ++ ++/**********End of Debug Purpose API declearation**********/ ++ ++int btif_open_no_id(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = btif_open(p_btif); ++ ++ if (i_ret) ++ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); ++ else ++ BTIF_INFO_FUNC("btif_open succeed\n"); ++ ++ return i_ret; ++} ++ ++int btif_close_no_id(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = btif_close(p_btif); ++ ++ if (i_ret) ++ BTIF_ERR_FUNC("btif_close failed, i_ret(%d)\n", i_ret); ++ else ++ BTIF_INFO_FUNC("btif_close succeed\n"); ++ return i_ret; ++} ++ ++int btif_write_no_id(const unsigned char *p_buf, unsigned int len) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ BTIF_DBG_FUNC("++"); ++ ++ if (p_buf == NULL) { ++ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); ++ return E_BTIF_INVAL_PARAM; ++ } ++ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { ++ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ i_ret = btif_send_data(p_btif, p_buf, len); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++int btif_dpidle_ctrl_no_id(ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ if (en_flag == BTIF_DPIDLE_DISABLE) ++ i_ret = btif_exit_dpidle(p_btif); ++ else ++ i_ret = btif_enter_dpidle(p_btif); ++ ++ return i_ret; ++} ++ ++int btif_wakeup_consys_no_id(void) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ ++ i_ret = btif_raise_wak_signal(p_btif); ++ ++ return i_ret; ++} ++ ++int btif_loopback_ctrl_no_id(ENUM_BTIF_LPBK_MODE enable) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = ++ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); ++ ++ return i_ret; ++} ++ ++int btif_dbg_ctrl_no_id(ENUM_BTIF_DBG_ID flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = 0; ++ switch (flag) { ++ case BTIF_DISABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("disable btif log function for both Tx and Rx\n"); ++ btif_log_buf_disable(&p_btif->tx_log); ++ btif_log_buf_disable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_ENABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("enable btif log function for both Tx and Rx\n"); ++ btif_log_buf_enable(&p_btif->tx_log); ++ btif_log_buf_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_LOG:{ ++ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); ++ btif_log_buf_dmp_out(&p_btif->tx_log); ++ btif_log_buf_dmp_out(&p_btif->rx_log); ++ } ++ break; ++ ++ case BTIF_CLR_LOG:{ ++ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); ++ btif_log_buf_reset(&p_btif->tx_log); ++ btif_log_buf_reset(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_BTIF_REG: ++ /*TBD*/ btif_dump_reg(p_btif); ++ break; ++ case BTIF_ENABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("enable btif real time log for both Tx and Rx\n"); ++ btif_log_output_enable(&p_btif->tx_log); ++ btif_log_output_enable(&p_btif->rx_log); ++ break; ++ case BTIF_DISABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("disable btif real time log for both Tx and Rx\n"); ++ btif_log_output_disable(&p_btif->tx_log); ++ btif_log_output_disable(&p_btif->rx_log); ++ break; ++ default: ++ BTIF_INFO_FUNC("not supported flag:%d\n", flag); ++ i_ret = -2; ++ break; ++ } ++ ++ return i_ret; ++} ++ ++int mtk_btif_exp_open_test(void) ++{ ++ int i_ret = 0; ++ ++ i_ret = btif_open_no_id(); ++ if (i_ret < 0) { ++ BTIF_INFO_FUNC("mtk_wcn_btif_open failed\n"); ++ return -1; ++ } ++ ++ BTIF_INFO_FUNC("mtk_wcn_btif_open succeed\n"); ++ ++ return i_ret; ++} ++ ++int mtk_btif_exp_close_test(void) ++{ ++ int i_ret = 0; ++ ++ i_ret = btif_close_no_id(); ++ if (i_ret < 0) { ++ BTIF_INFO_FUNC("mtk_wcn_btif_close failed\n"); ++ return -1; ++ } ++ ++ BTIF_INFO_FUNC("mtk_wcn_btif_close succeed\n"); ++ ++ return i_ret; ++} ++ ++int mtk_btif_exp_write_test(void) ++{ ++ return mtk_btif_exp_write_stress_test(100, 10); ++} ++ ++int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int max_loop) ++{ ++#define BUF_LEN 1024 ++ int i_ret = 0; ++ int idx = 0; ++ int buf_len = length > BUF_LEN ? BUF_LEN : length; ++ int loop = max_loop > 1000000 ? 1000000 : max_loop; ++ unsigned char *buffer; ++ ++ buffer = kmalloc(BUF_LEN, GFP_KERNEL); ++ if (!buffer) { ++ BTIF_ERR_FUNC("btif tester kmalloc failed\n"); ++ return -1; ++ } ++ ++ for (idx = 0; idx < buf_len; idx++) ++ /* btif_stress_test_buf[idx] = BUF_LEN -idx; */ ++ *(buffer + idx) = idx % 255; ++ i_ret = btif_loopback_ctrl_no_id(BTIF_LPBK_ENABLE); ++ BTIF_INFO_FUNC("mtk_wcn_btif_loopback_ctrl returned %d\n", i_ret); ++ while (loop--) { ++ i_ret = btif_write_no_id(buffer, buf_len); ++ BTIF_INFO_FUNC("mtk_wcn_btif_write left loop:%d, i_ret:%d\n", ++ loop, i_ret); ++ if (i_ret != buf_len) { ++ BTIF_INFO_FUNC ++ ("mtk_wcn_btif_write failed, target len %d, sent len: %d\n", ++ buf_len, i_ret); ++ break; ++ } ++ buf_len--; ++ if (buf_len <= 0) ++ buf_len = length > BUF_LEN ? BUF_LEN : length; ++ } ++ kfree(buffer); ++ return i_ret; ++} ++ ++int mtk_btif_exp_suspend_test(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = _btif_suspend(p_btif); ++ return i_ret; ++} ++ ++int mtk_btif_exp_restore_noirq_test(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = _btif_restore_noirq(p_btif); ++ return i_ret; ++} ++ ++int mtk_btif_exp_clock_ctrl(int en) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = btif_clock_ctrl(p_btif, en); ++ return i_ret; ++} ++ ++int mtk_btif_exp_resume_test(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = _btif_resume(p_btif); ++ return i_ret; ++} ++ ++int mtk_btif_exp_enter_dpidle_test(void) ++{ ++ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_ENABLE); ++} ++ ++int mtk_btif_exp_exit_dpidle_test(void) ++{ ++ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_DISABLE); ++} ++ ++int mtk_btif_exp_log_debug_test(int flag) ++{ ++ int i_ret = 0; ++ ++ i_ret = btif_dbg_ctrl_no_id(flag); ++ return i_ret; ++} ++ ++void mtk_btif_read_cpu_sw_rst_debug_exp(void) ++{ ++ mtk_btif_read_cpu_sw_rst_debug(); ++} ++ ++/************End of Function**********/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h +new file mode 100644 +index 000000000000..97756f684ab4 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h +@@ -0,0 +1,164 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIF_DMA_H_ ++#define __HAL_BTIF_DMA_H_ ++ ++#include ++#include "btif_dma_pub.h" ++ ++#if defined(CONFIG_MTK_CLKMGR) ++#if defined(CONFIG_ARCH_MT6580) ++#define MTK_BTIF_APDMA_CLK_CG MT_CG_APDMA_SW_CG ++#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) ++#define MTK_BTIF_APDMA_CLK_CG MT_CG_PERI_APDMA ++#endif ++#else ++extern struct clk *clk_btif_apdma; /*btif apdma clock*/ ++#endif /* !defined(CONFIG_MTK_CLKMGR) */ ++ ++#define TX_DMA_VFF_SIZE (1024 * 8) /*Tx vFIFO Len must be 8 Byte allignment */ ++#define RX_DMA_VFF_SIZE (1024 * 8) /*Rx vFIFO Len must be 8 Byte allignment */ ++ ++#define DMA_TX_THRE(n) (n - 7) /*Tx Trigger Level */ ++#define DMA_RX_THRE(n) ((n) * 3 / 4) /*Rx Trigger Level */ ++ ++/**********************************Hardware related defination**************************/ ++#ifndef CONFIG_OF ++/*DMA channel's offset refer to AP_DMA's base address*/ ++#define BTIF_TX_DMA_OFFSET 0x880 ++#define BTIF_RX_DMA_OFFSET 0x900 ++#endif ++ ++/*Register Address Mapping*/ ++#define DMA_INT_FLAG_OFFSET 0x00 ++#define DMA_INT_EN_OFFSET 0x04 ++#define DMA_EN_OFFSET 0x08 ++#define DMA_RST_OFFSET 0x0C ++#define DMA_STOP_OFFSET 0x10 ++#define DMA_FLUSH_OFFSET 0x14 ++ ++#define DMA_BASE_OFFSET 0x1C ++#define DMA_LEN_OFFSET 0x24 ++ ++#define DMA_THRE_OFFSET 0x28 ++#define DMA_WPT_OFFSET 0x2C ++#define DMA_RPT_OFFSET 0x30 ++#define DMA_VALID_OFFSET 0x3C ++#define DMA_LEFT_OFFSET 0x40 ++#define DMA_VFF_BIT29_OFFSET 0x01 ++ ++#define TX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Tx Virtual FIFO Interrupt Flag Register */ ++#define TX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Tx Virtual FIFO Interrupt Enable Register */ ++#define TX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET)/*BTIF Tx Virtual FIFO Enable Register */ ++#define TX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET)/*BTIF Tx Virtual FIFO Reset Register */ ++#define TX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET)/*BTIF Tx Virtual FIFO STOP Register */ ++#define TX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET)/*BTIF Tx Virtual FIFO Flush Register */ ++#define TX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Tx Virtual FIFO Base Address Register */ ++#define TX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Tx Virtual FIFO Length Register */ ++#define TX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Tx Virtual FIFO Threshold Register */ ++#define TX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Tx Virtual FIFO Write Pointer Register */ ++#define TX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Tx Virtual FIFO Read Pointer Register */ ++#define TX_DMA_W_INT_BUF_SIZE(base) (unsigned long)(base + 0x34) ++/*BTIF Tx Virtual FIFO Internal Tx Write Buffer Size Register */ ++#define TX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) ++/*BTIF Tx Virtual FIFO Internal Tx Buffer Size Register */ ++ ++#define TX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Tx Virtual FIFO Valid Size Register */ ++#define TX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Tx Virtual FIFO Left Size Register */ ++#define TX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Tx Virtual FIFO Debug Status Register */ ++#define TX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Tx Virtual FIFO Base High Address Register */ ++ ++/*Rx Register Address Mapping*/ ++#define RX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Rx Virtual FIFO Interrupt Flag Register */ ++#define RX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Rx Virtual FIFO Interrupt Enable Register */ ++#define RX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET) /*BTIF Rx Virtual FIFO Enable Register */ ++#define RX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET) /*BTIF Rx Virtual FIFO Reset Register */ ++#define RX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET) /*BTIF Rx Virtual FIFO Stop Register */ ++#define RX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET) /*BTIF Rx Virtual FIFO Flush Register */ ++#define RX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Rx Virtual FIFO Base Address Register */ ++#define RX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Rx Virtual FIFO Length Register */ ++#define RX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Rx Virtual FIFO Threshold Register */ ++#define RX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Rx Virtual FIFO Write Pointer Register */ ++#define RX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Rx Virtual FIFO Read Pointer Register */ ++#define RX_DMA_FLOW_CTRL_THRE(base) (unsigned long)(base + 0x34) /*BTIF Rx Virtual FIFO Flow Control Register */ ++#define RX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) /*BTIF Rx Virtual FIFO Internal Buffer Register */ ++#define RX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Rx Virtual FIFO Valid Size Register */ ++#define RX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Rx Virtual FIFO Left Size Register */ ++#define RX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Rx Virtual FIFO Debug Status Register */ ++#define RX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Rx Virtual FIFO Base High Address Register */ ++ ++#define DMA_EN_BIT (0x1) ++#define DMA_STOP_BIT (0x1) ++#define DMA_RST_BIT (0x1) ++#define DMA_FLUSH_BIT (0x1) ++ ++#define DMA_WARM_RST (0x1 << 0) ++#define DMA_HARD_RST (0x1 << 1) ++ ++#define DMA_WPT_MASK (0x0000FFFF) ++#define DMA_WPT_WRAP (0x00010000) ++ ++#define DMA_RPT_MASK (0x0000FFFF) ++#define DMA_RPT_WRAP (0x00010000) ++ ++/*APDMA BTIF Tx Reg Ctrl Bit*/ ++#define TX_DMA_INT_FLAG_MASK (0x1) ++ ++#define TX_DMA_INTEN_BIT (0x1) ++ ++#define TX_DMA_ADDR_MASK (0xFFFFFFF8) ++#define TX_DMA_LEN_MASK (0x0000FFF8) ++ ++#define TX_DMA_THRE_MASK (0x0000FFFF) ++ ++#define TX_DMA_W_INT_BUF_MASK (0x000000FF) ++ ++#define TX_DMA_VFF_VALID_MASK (0x0000FFFF) ++#define TX_DMA_VFF_LEFT_MASK (0x0000FFFF) ++ ++/*APDMA BTIF Rx Reg Ctrl Bit*/ ++#define RX_DMA_INT_THRE (0x1 << 0) ++#define RX_DMA_INT_DONE (0x1 << 1) ++ ++#define RX_DMA_INT_THRE_EN (0x1 << 0) ++#define RX_DMA_INT_DONE_EN (0x1 << 1) ++ ++#define RX_DMA_ADDR_MASK (0xFFFFFFF8) ++#define RX_DMA_LEN_MASK (0x0000FFF8) ++ ++#define RX_DMA_THRE_MASK (0x0000FFFF) ++ ++#define RX_DMA_FLOW_CTRL_THRE_MASK (0x000000FF) ++ ++#define RX_DMA_INT_BUF_SIZE_MASK (0x0000001F) ++ ++#define RX_DMA_VFF_VALID_MASK (0x0000001F) ++ ++#define RX_DMA_VFF_LEFT_MASK (0x0000FFFF) ++ ++typedef struct _MTK_BTIF_DMA_VFIFO_ { ++ DMA_VFIFO vfifo; ++ unsigned int wpt; /*DMA's write pointer, which is maintained by SW for Tx DMA and HW for Rx DMA */ ++ unsigned int last_wpt_wrap; /*last wrap bit for wpt */ ++ unsigned int rpt; /*DMA's read pointer, which is maintained by HW for Tx DMA and SW for Rx DMA */ ++ unsigned int last_rpt_wrap; /*last wrap bit for rpt */ ++} MTK_BTIF_DMA_VFIFO, *P_MTK_BTIF_DMA_VFIFO; ++ ++/*for DMA debug purpose*/ ++typedef struct _MTK_BTIF_DMA_REG_DMP_DBG_ { ++ unsigned long reg_addr; ++ unsigned int reg_val; ++} MTK_BTIF_DMA_REG_DMP_DBG, *P_MTK_BTIF_DMA_REG_DMP_DBG; ++ ++#endif /*__HAL_BTIF_DMA_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h +new file mode 100644 +index 000000000000..0773f2ce387a +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h +@@ -0,0 +1,197 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIFD_DMA_PUB_H_ ++#define __HAL_BTIFD_DMA_PUB_H_ ++ ++#include ++ ++#include "plat_common.h" ++ ++typedef enum _ENUM_DMA_CTRL_ { ++ DMA_CTRL_DISABLE = 0, ++ DMA_CTRL_ENABLE = DMA_CTRL_DISABLE + 1, ++ DMA_CTRL_BOTH, ++} ENUM_DMA_CTRL; ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_info_get ++* DESCRIPTION ++* get btif tx dma channel's information ++* PARAMETERS ++* dma_dir [IN] DMA's direction ++* RETURNS ++* pointer to btif dma's information structure ++*****************************************************************************/ ++P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dma_hw_init ++* DESCRIPTION ++* control clock output enable/disable of DMA module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of DMA module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ctrl ++* DESCRIPTION ++* enable/disable Tx DMA channel ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* ctrl_id [IN] enable/disable ID ++* dma_dir [IN] DMA's direction ++* RETURNS ++* 0 means success; negative means fail ++*****************************************************************************/ ++int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dma_rx_cb_reg ++* DESCRIPTION ++* register rx callback function to dma module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* rx_cb [IN] function pointer to btif ++* RETURNS ++* 0 means success; negative means fail ++*****************************************************************************/ ++int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ dma_rx_buf_write rx_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_vfifo_reset ++* DESCRIPTION ++* reset tx virtual fifo information, except memory information ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* dma_dir [IN] DMA's direction ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_irq_handler ++* DESCRIPTION ++* lower level tx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_send_data ++* DESCRIPTION ++* send data through btif in DMA mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, ++ const unsigned char *p_buf, const unsigned int buf_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_get_ava_room ++* DESCRIPTION ++* get tx available room ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* available room size ++*****************************************************************************/ ++int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_allow ++* DESCRIPTION ++* is tx operation allowed by DMA ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_rx_dma_irq_handler ++* DESCRIPTION ++* lower level rx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, const unsigned int max_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag); ++ ++int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid); ++ ++#endif /*__HAL_BTIFD_DMA_PUB_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h +new file mode 100644 +index 000000000000..51fe58a82b49 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIF_H_ ++#define __HAL_BTIF_H_ ++ ++#ifndef CONFIG_OF ++#define MTK_BTIF_REG_BASE BTIF_BASE ++#endif ++ ++#if defined(CONFIG_MTK_CLKMGR) ++#if defined(CONFIG_ARCH_MT6580) ++#define MTK_BTIF_CG_BIT MT_CG_BTIF_SW_CG ++#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) ++#define MTK_BTIF_CG_BIT MT_CG_PERI_BTIF ++#endif ++#else ++struct clk *clk_btif_apdma; /*btif apdma clock*/ ++struct clk *clk_btif; /*btif clock*/ ++#endif /* !defined(CONFIG_MTK_CLKMGR) */ ++ ++#define BTIF_RBR(base) (unsigned long)(base + 0x0) /*RX Buffer Register: read only */ ++#define BTIF_THR(base) (unsigned long)(base + 0x0) /*Rx Holding Register: write only */ ++#define BTIF_IER(base) (unsigned long)(base + 0x4) /*Interrupt Enable Register: read/write */ ++#define BTIF_IIR(base) (unsigned long)(base + 0x8) /*Interrupt Identification Register: read only */ ++#define BTIF_FIFOCTRL(base) (unsigned long)(base + 0x8) /*FIFO Control Register: write only */ ++#define BTIF_FAKELCR(base) (unsigned long)(base + 0xC) /*FAKE LCR Register: read/write */ ++#define BTIF_LSR(base) (unsigned long)(base + 0x14) /*Line Status Register: read only */ ++#define BTIF_SLEEP_EN(base) (unsigned long)(base + 0x48) /*Sleep Enable Register: read/write */ ++#define BTIF_DMA_EN(base) (unsigned long)(base + 0x4C) /*DMA Enable Register: read/write */ ++#define BTIF_RTOCNT(base) (unsigned long)(base + 0x54) /*Rx Timeout Count Register: read/write */ ++#define BTIF_TRI_LVL(base) (unsigned long)(base + 0x60) /*Tx/Rx Trigger Level Control Register: read/write */ ++#define BTIF_WAK(base) (unsigned long)(base + 0x64) /*BTIF module wakeup Register: write only */ ++#define BTIF_WAT_TIME(base) (unsigned long)(base + 0x68) /*BTIF ASYNC Wait Time Control Register: read/write */ ++#define BTIF_HANDSHAKE(base) (unsigned long)(base + 0x6C) /*BTIF New Handshake Control Register: read/write */ ++ ++/*BTIF_IER bits*/ ++#define BTIF_IER_TXEEN (0x1 << 1) /*1: Tx holding register is empty */ ++#define BTIF_IER_RXFEN (0x1 << 0) /*1: Rx buffer contains data */ ++ ++/*BTIF_IIR bits*/ ++#define BTIF_IIR_NINT (0x1 << 0) /*No INT Pending */ ++#define BTIF_IIR_TX_EMPTY (0x1 << 1) /*Tx Holding Register empty */ ++#define BTIF_IIR_RX (0x1 << 2) /*Rx data received */ ++#define BTIF_IIR_RX_TIMEOUT (0x11 << 2) /*Rx data received */ ++ ++/*BTIF_LSR bits*/ ++#define BTIF_LSR_DR_BIT (0x1 << 0) ++#define BTIF_LSR_THRE_BIT (0x1 << 5) ++#define BTIF_LSR_TEMT_BIT (0x1 << 6) ++ ++/*BTIF_FIFOCTRL bits*/ ++#define BTIF_FIFOCTRL_CLR_TX (0x1 << 2) /*Clear Tx FIRO */ ++#define BTIF_FIFOCTRL_CLR_RX (0x1 << 1) /*Clear Rx FIRO */ ++ ++/*BTIF_FAKELCR bits*/ ++#define BTIF_FAKELCR_NORMAL_MODE 0x0 ++ ++/*BTIF_SLEEP_EN bits*/ ++#define BTIF_SLEEP_EN_BIT (0x1 << 0) /*enable Sleep mode */ ++#define BTIF_SLEEP_DIS_BIT (0x0) /*disable sleep mode */ ++ ++/*BTIF_DMA_EN bits*/ ++#define BTIF_DMA_EN_RX (0x1 << 0) /*Enable Rx DMA */ ++#define BTIF_DMA_EN_TX (0x1 << 1) /*Enable Tx DMA */ ++#define BTIF_DMA_EN_AUTORST_EN (0x1 << 2) /*1: timeout counter will be auto reset */ ++#define BTIF_DMA_EN_AUTORST_DIS (0x0 << 2) /* ++ * 0: after Rx timeout happens, ++ * SW shall reset the interrupt by reading BTIF 0x4C ++ */ ++ ++/*BTIF_TRI_LVL bits*/ ++#define BTIF_TRI_LVL_TX_MASK ((0xf) << 0) ++#define BTIF_TRI_LVL_RX_MASK ((0x7) << 4) ++ ++#define BTIF_TRI_LVL_TX(x) ((x & 0xf) << 0) ++#define BTIF_TRI_LVL_RX(x) ((x & 0x7) << 4) ++ ++#define BTIF_TRI_LOOP_EN (0x1 << 7) ++#define BTIF_TRI_LOOP_DIS (0x0 << 7) ++ ++/*BTIF_WAK bits*/ ++#define BTIF_WAK_BIT (0x1 << 0) ++ ++/*BTIF_HANDSHAKE bits*/ ++#define BTIF_HANDSHAKE_EN_HANDSHAKE 1 ++#define BTIF_HANDSHAKE_DIS_HANDSHAKE 0 ++ ++#define BTIF_TX_FIFO_SIZE 16 ++#define BTIF_RX_FIFO_SIZE 8 ++ ++#define BTIF_TX_FIFO_THRE (BTIF_TX_FIFO_SIZE / 2) ++#define BTIF_RX_FIFO_THRE 0x1 /* 0x5 */ ++ ++#endif /*__HAL_BTIF_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h +new file mode 100644 +index 000000000000..1555d5a50c38 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h +@@ -0,0 +1,237 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIF_PUB_H_ ++#define __HAL_BTIF_PUB_H_ ++ ++#include "plat_common.h" ++ ++/*Enum Defination*/ ++/*BTIF Mode Enum */ ++typedef enum _ENUM_BTIF_MODE_ { ++ BTIF_MODE_PIO = 0, ++ BTIF_MODE_DMA = BTIF_MODE_PIO + 1, ++ BTIF_MODE_MAX, ++} ENUM_BTIF_MODE; ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_info_get ++* DESCRIPTION ++* get btif's information included base address , irq related information ++* PARAMETERS ++* RETURNS ++* BTIF's information ++*****************************************************************************/ ++P_MTK_BTIF_INFO_STR hal_btif_info_get(void); ++ ++#if 0 /*included in hal_btif_info_get */ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_get_irq ++* DESCRIPTION ++* get BTIF module's IRQ information ++* PARAMETERS ++* RETURNS ++* pointer to BTIF's irq structure ++*****************************************************************************/ ++P_MTK_BTIF_IRQ_STR hal_btif_get_irq(void); ++#endif ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_get_and_prepare ++* DESCRIPTION ++* get clock from device tree and prepare for enable/disable control ++* PARAMETERS ++* pdev device pointer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_get_and_prepare(struct platform_device *pdev); ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_unprepare ++* DESCRIPTION ++* unprepare btif clock and apdma clock ++* PARAMETERS ++* none ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_unprepare(void); ++#endif ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of BTIF module ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_hw_init ++* DESCRIPTION ++* BTIF module init, after this step, BTIF should enable to do tx/rx with PIO ++* mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_cb_reg ++* DESCRIPTION ++* BTIF rx callback register API ++* PARAMETERS ++* p_btif_info [IN] pointer to BTIF's information ++* rx_cb [IN] rx callback function ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, ++ btif_rx_buf_write rx_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_loopback_ctrl ++* DESCRIPTION ++* BTIF Tx/Rx loopback mode set, this operation can only be done ++* after set BTIF to normal mode ++* PARAMETERS ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_handler ++* DESCRIPTION ++* lower level interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success; negative means fail; positive means rx data length ++*****************************************************************************/ ++int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_mode_ctrl ++* DESCRIPTION ++* set BTIF tx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_mode_ctrl ++* DESCRIPTION ++* set BTIF rx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_send_data ++* DESCRIPTION ++* send data through btif in FIFO mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* positive means number of data sent; ++* 0 means no data put to FIFO; ++* negative means error happens ++*****************************************************************************/ ++int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, ++ const unsigned char *p_buf, const unsigned int buf_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_raise_wak_sig ++* DESCRIPTION ++* raise wakeup signal to counterpart ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_allow ++* DESCRIPTION ++* whether tx is allowed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); ++ ++int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif, MTK_BTIF_PM_OPID opid); ++ ++void mtk_btif_read_cpu_sw_rst_debug_plat(void); ++ ++#endif /*__HAL_BTIF_PUB_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h +new file mode 100644 +index 000000000000..2a1462cb32ff +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h +@@ -0,0 +1,307 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_PUB_H_ ++#define __HAL_PUB_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++#include ++#else ++#include ++#include ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++#include ++ ++extern int mtk_btif_hal_get_log_lvl(void); ++ ++#define MTK_BTIF_MARK_UNUSED_API ++ ++typedef irq_handler_t mtk_btif_irq_handler; ++ ++#define MTK_BTIF_ENABLE_CLK_CTL 1 ++#define MTK_BTIF_ENABLE_CLK_REF_COUNTER 1 ++ ++#define DBG_LOG_STR_SIZE 256 ++ ++/*Log defination*/ ++static int hal_log_print(const char *str, ...) ++{ ++ va_list args; ++ char temp_sring[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(temp_sring, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_err("%s", temp_sring); ++ ++ return 0; ++} ++ ++#define BTIF_LOG_LOUD 4 ++#define BTIF_LOG_DBG 3 ++#define BTIF_LOG_INFO 2 ++#define BTIF_LOG_WARN 1 ++#define BTIF_LOG_ERR 0 ++ ++#ifndef DFT_TAG ++#define DFT_TAG "[BTIF-DFT]" ++#endif ++ ++#define BTIF_LOUD_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_LOUD) \ ++ hal_log_print(DFT_TAG "[L]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_INFO_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_INFO)\ ++ hal_log_print(DFT_TAG "[I]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_WARN_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_WARN)\ ++ hal_log_print(DFT_TAG "[W]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_ERR_FUNC(fmt, arg ...)\ ++do {\ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_ERR)\ ++ hal_log_print(DFT_TAG "[E]%s(%d):" fmt,\ ++ __func__, __LINE__, ## arg);\ ++} while (0) ++ ++#define BTIF_DBG_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ ++ hal_log_print(DFT_TAG "[D]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_TRC_FUNC(f) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ ++ hal_log_print(DFT_TAG "<%s> <%d>\n", \ ++ __func__, __LINE__); \ ++} while (0) ++ ++/*-----------------------------------Enum Defination--------------------------------*/ ++/*IRQ sensetive type */ ++typedef enum _ENUM_IRQ_SENS_TYPE_ { ++ IRQ_SENS_EDGE = 0, ++ IRQ_SENS_LVL = IRQ_SENS_EDGE + 1, ++ IRQ_SENS_TYPE_MAX ++} ENUM_IRQ_SENS_TYPE; ++ ++/*IRQ level trigger type */ ++typedef enum _ENUM_IRQ_LVL_TYPE_ { ++ IRQ_LVL_LOW = 0, ++ IRQ_LVL_HIGH = IRQ_LVL_LOW + 1, ++ IRQ_LVL_MAX ++} ENUM_IRQ_LVL; ++ ++/*IRQ edge trigger type */ ++typedef enum _ENUM_IRQ_EDGE_TYPE_ { ++ IRQ_EDGE_FALL = 0, ++ IRQ_EDGE_RAISE = IRQ_EDGE_FALL + 1, ++ IRQ_EDGE_BOTH = IRQ_EDGE_RAISE + 1, ++ IRQ_EDGE_MAX ++} ENUM_IRQ_EDGE; ++ ++typedef enum _ENUM_CLOCK_CTRL_ { ++ CLK_OUT_DISABLE = 0, ++ CLK_OUT_ENABLE = CLK_OUT_DISABLE + 1, ++ CLK_OUT_MAX ++} ENUM_CLOCK_CTRL; ++ ++/*Error No. table */ ++typedef enum _ENUM_ERROR_CODE_ { ++ ERR_NO_ERROR = 0, ++ ERR_INVALID_PAR = ERR_NO_ERROR - 1, ++ ERR_MAX = ERR_INVALID_PAR - 1, ++} ENUM_ERROR_CODE; ++ ++typedef enum _ENUM_BTIF_DIR_ { ++ BTIF_TX = 0, ++ BTIF_RX = BTIF_TX + 1, ++ BTIF_DIR_MAX, ++} ENUM_BTIF_DIR; ++ ++typedef enum _ENUM_DMA_DIR_ { ++ DMA_DIR_RX = 0, ++ DMA_DIR_TX = DMA_DIR_RX + 1, ++ DMA_DIR_BOTH, ++} ENUM_DMA_DIR; ++ ++typedef enum _ENUM_BTIF_REG_ID_ { ++ REG_IIR = 0, /*Interrupt Identification Register */ ++ REG_LSR = 1, /*Line Status Register */ ++ REG_FAKE_LCR = 2, /*Fake Lcr Regiseter */ ++ REG_FIFO_CTRL = 3, /*FIFO Control Register */ ++ REG_IER = 4, /*Interrupt Enable Register */ ++ REG_SLEEP_EN = 5, /*Sleep Enable Register */ ++ REG_RTO_COUNTER = 6, /*Rx Timeout Counter Register */ ++ REG_DMA_EN = 7, /*DMA Enalbe Register */ ++ REG_TRIG_LVL = 8, /*Tx/Rx Trigger Level Register */ ++ REG_WAT_TIME = 9, /*Async Wait Time Register */ ++ REG_HANDSHAKE = 10, /*New HandShake Mode Register */ ++ REG_SLP_WAK = 11, /*Sleep Wakeup Reigster */ ++ REG_BTIF_ALL = 12, /*all btif controller's registers */ ++ REG_TX_DMA_ALL = 13, ++ REG_RX_DMA_ALL = 14, ++ REG_MAX ++} ENUM_BTIF_REG_ID; ++ ++typedef enum _MTK_BTIF_PM_OPID_ { ++ BTIF_PM_DPIDLE_EN, ++ BTIF_PM_DPIDLE_DIS, ++ BTIF_PM_SUSPEND, ++ BTIF_PM_RESUME, ++ BTIF_PM_RESTORE_NOIRQ, ++} MTK_BTIF_PM_OPID; ++ ++#define BTIF_HAL_TX_FIFO_SIZE (1024 * 4) ++ ++/*-----------------------------------Enum Defination End--------------------------------*/ ++ ++/*****************************structure definition***************************/ ++/*IRQ related information*/ ++typedef struct _MTK_BTIF_IRQ_STR_ { ++ const char *name; ++ bool is_irq_sup; ++ unsigned int irq_id; ++#ifdef CONFIG_OF ++ unsigned int irq_flags; ++#else ++ ENUM_IRQ_SENS_TYPE sens_type; ++ union { ++ ENUM_IRQ_LVL lvl_type; ++ ENUM_IRQ_EDGE edge_type; ++ }; ++#endif ++ bool reg_flag; ++ irq_handler_t p_irq_handler; ++} MTK_BTIF_IRQ_STR, *P_MTK_BTIF_IRQ_STR; ++ ++typedef struct _DMA_VFIFO_ { ++ /*[Driver Access] vFIFO memory'svirtual address */ ++ unsigned char *p_vir_addr; ++ /*[HW Access] dma handle , physically address, set to DMA's HW Register */ ++ dma_addr_t phy_addr; ++ /*DMA's vFIFO size */ ++ unsigned int vfifo_size; ++ /*DMA's threshold value */ ++ unsigned int thre; ++} DMA_VFIFO, *P_DMA_VFIFO; ++ ++typedef unsigned int (*dma_rx_buf_write) (void *p_dma_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++typedef unsigned int (*btif_rx_buf_write) (void *p_btif_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++ ++/*DMA related information*/ ++typedef struct _MTK_DMA_INFO_STR_ { ++ unsigned long base; ++ ENUM_DMA_DIR dir; ++ P_MTK_BTIF_IRQ_STR p_irq; ++ dma_rx_buf_write rx_cb; ++ P_DMA_VFIFO p_vfifo; ++} MTK_DMA_INFO_STR, *P_MTK_DMA_INFO_STR; ++ ++/*DMA related information*/ ++typedef struct _MTK_BTIF_INFO_STR_ { ++ unsigned long base; /*base address */ ++ P_MTK_BTIF_IRQ_STR p_irq; /*irq related information */ ++ ++ unsigned int tx_fifo_size; /*BTIF tx FIFO size */ ++ unsigned int rx_fifo_size; /*BTIF rx FIFO size */ ++ ++ unsigned int tx_tri_lvl; /*BTIFtx trigger level in FIFO mode */ ++ unsigned int rx_tri_lvl; /*BTIFrx trigger level in FIFO mode */ ++ ++ unsigned int clk_gat_addr; /*clock gating address */ ++ unsigned int set_bit; /*enable clock gating bit */ ++ unsigned int clr_bit; /*clear clock gating bit */ ++ ++ unsigned int rx_data_len; /*rx data length */ ++ ++ btif_rx_buf_write rx_cb; ++ ++ struct kfifo *p_tx_fifo; /*tx fifo */ ++ spinlock_t tx_fifo_spinlock; /*tx fifo spinlock */ ++} MTK_BTIF_INFO_STR, *P_MTK_BTIF_INFO_STR; ++ ++/**********End of Structure Definition***********/ ++ ++/***********register operation***********/ ++#ifdef __KERNEL__ ++/*byte write <1 byte> */ ++#define btif_reg_sync_writeb(v, a) mt_reg_sync_writeb(v, a) ++/*word write <2 byte> */ ++#define btif_reg_sync_writew(v, a) mt_reg_sync_writew(v, a) ++/*long write <4 byte> */ ++#define btif_reg_sync_writel(v, a) mt_reg_sync_writel(v, a) ++#else ++/*byte write <1 byte> */ ++#define btif_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) ++/*word write <2 byte> */ ++#define btif_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) ++/*long write <4 byte> */ ++#define btif_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) ++#endif ++#define BTIF_READ8(REG) __raw_readb((unsigned char *)(REG)) ++#define BTIF_READ16(REG) __raw_readw((unsigned short *)(REG)) ++#define BTIF_READ32(REG) __raw_readl((unsigned int *)(REG)) ++ ++#define BTIF_SET_BIT(REG, BITVAL) do { \ ++*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL)); \ ++mb(); /**/ \ ++} \ ++while (0) ++#define BTIF_CLR_BIT(REG, BITVAL) do { \ ++(*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL)); \ ++mb(); /**/\ ++} \ ++while (0) ++ ++/***********end of register operation *********/ ++ ++#endif /*__HAL_PUB_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/Kconfig b/drivers/misc/mediatek/connectivity/Kconfig +new file mode 100644 +index 000000000000..aa4c3e6f71c9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/Kconfig +@@ -0,0 +1,298 @@ ++config MTK_COMBO ++ tristate "MediaTek Connectivity Combo Chip Support" ++ help ++ MTK connectivity combo chip driver for MT66xx ++ ++# ++# MTK Combo Chip Selection ++# ++ ++choice ++ prompt "Select Chip" ++ depends on MTK_COMBO ++ ++config MTK_COMBO_CHIP_MT6620 ++ bool "MT6620" ++ help ++ this config is used to decided combo chip version ++ in current platform ++ is ++ MT6620 ++ ++config MTK_COMBO_CHIP_MT6628 ++ bool "MT6628" ++ help ++ this config is used to decided combo chip version ++ in current platform ++ is ++ MT6628 ++ ++config MTK_COMBO_CHIP_MT6630 ++ bool "MT6630" ++ help ++ this config is used to decided combo chip version ++ in current platform ++ is ++ MT6630 ++ ++config MTK_COMBO_CHIP_CONSYS_6572 ++ bool "CONSYS_6572" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6572 ++ ++config MTK_COMBO_CHIP_CONSYS_6582 ++ bool "CONSYS_6582" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6582 ++ ++config MTK_COMBO_CHIP_CONSYS_8127 ++ bool "CONSYS_8127" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6572 ++ ++config MTK_COMBO_CHIP_CONSYS_7623 ++ bool "CONSYS_7623" ++ help ++ this config is used to decide SOC consys version ++ in current platform is MT7623 and prepare proper ++ system services like radio power on/off and firmware ++ download for the Bluetotoh and Wifi. ++ ++ ++config MTK_COMBO_CHIP_CONSYS_6752 ++ bool "CONSYS_6752" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6752 ++ ++config MTK_COMBO_CHIP_CONSYS_6592 ++ bool "CONSYS_6592" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6592 ++ ++config MTK_COMBO_CHIP_CONSYS_8163 ++ bool "CONSYS_8163" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT8163 ++ ++config MTK_COMBO_CHIP_CONSYS_6735 ++ bool "CONSYS_6735" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6735 ++ ++config MTK_COMBO_CHIP_CONSYS_6755 ++ bool "CONSYS_6755" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6755 ++ ++config MTK_COMBO_CHIP_CONSYS_6580 ++ bool "CONSYS_6580" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6580 ++ ++config MTK_COMBO_CHIP_CONSYS_6797 ++ bool "CONSYS_6797" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6797 ++endchoice ++ ++config MTK_COMBO_CHIP ++ string ++ default "MT6620" if MTK_COMBO_CHIP_MT6620 ++ default "MT6628" if MTK_COMBO_CHIP_MT6628 ++ default "MT6630" if MTK_COMBO_CHIP_MT6630 ++ default "CONSYS_6572" if MTK_COMBO_CHIP_CONSYS_6572 ++ default "CONSYS_6582" if MTK_COMBO_CHIP_CONSYS_6582 ++ default "CONSYS_8127" if MTK_COMBO_CHIP_CONSYS_8127 ++ default "CONSYS_7623" if MTK_COMBO_CHIP_CONSYS_7623 ++ default "CONSYS_6752" if MTK_COMBO_CHIP_CONSYS_6752 ++ default "CONSYS_6755" if MTK_COMBO_CHIP_CONSYS_6755 ++ default "CONSYS_6592" if MTK_COMBO_CHIP_CONSYS_6592 ++ default "CONSYS_8163" if MTK_COMBO_CHIP_CONSYS_8163 ++ default "CONSYS_6735" if MTK_COMBO_CHIP_CONSYS_6735 ++ default "CONSYS_6580" if MTK_COMBO_CHIP_CONSYS_6580 ++ default "CONSYS_6797" if MTK_COMBO_CHIP_CONSYS_6797 ++ help ++ this feature is used to identify combo chip version or SOC chip ++ consys version. ++ ++# ++# Target Platform Selection ++# ++config MTK_COMBO_PLAT_PATH ++ string "Platform folder name" ++ depends on MTK_COMBO ++ default "sample" if MTK_COMBO_PLAT_SAMPLE ++ help ++ Specify platform folder under common driver platform folder: ++ mtk_wcn_combo/common/platform/* ++ ++# ++# MTK COMBO Chip Configuration ++# ++config MTK_COMBO_COMM ++ depends on MTK_COMBO ++ tristate "MediaTek Combo Chip Common part driver" ++ help ++ MediaTek combo chip common part driver ++ ++#config MTK_COMBO_COMM_PS ++# depends on MTK_COMBO_COMM ++# bool "Enable PS support" ++# default n ++# help ++# Enable PS support of common UART interface ++ ++config MTK_COMBO_COMM_UART ++ depends on MTK_COMBO_COMM ++ tristate "Common interface UART" ++ help ++ Use UART for common part interface type ++ ++config MTK_COMBO_COMM_SDIO ++ depends on MTK_COMBO_COMM ++ tristate "Common interface SDIO" ++ help ++ Use SDIO for common part interface type ++ ++config MTK_COMBO_COMM_NPWR ++ depends on MTK_COMBO_COMM ++ bool "Enable NPWR support" ++ default n ++ help ++ Enable NPWR support of new power on swquence ++ ++config MTK_COMBO_COMM_APO ++ depends on MTK_COMBO_COMM ++ bool "Enable always power on support" ++ #default y ++ help ++ Enable chip will always power on ++ ++config MTK_COMBO_BT ++ tristate "MediaTek Combo Chip BT driver" ++ depends on MTK_COMBO ++ select MTK_BTIF ++ help ++ MTK BT /dev/stpbt driver for Bluedroid ++ ++config MTK_COMBO_BT_HCI ++ tristate "MediaTek Combo Chip BlueZ driver" ++ depends on BT && MTK_COMBO ++ select MTK_BTIF ++ help ++ MTK BT driver for BlueZ ++ ++config MTK_COMBO_WIFI ++ tristate "MediaTek combo chip Wi-Fi support" ++ depends on MTK_COMBO ++ select MTK_BTIF ++ select WIRELESS_EXT ++ select WEXT_PRIV ++ ++config MTK_WAPI_SUPPORT ++ bool "MTK_WAPI_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ #default y ++ help ++ if it is set to TRUE: Support WAPI (WLAN Authentication and ++ Privacy Infrastructure) ++ ++config MTK_PASSPOINT_R1_SUPPORT ++ bool "MTK_PASSPOINT_R1_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ help ++ Support Passpoint R1 (Hotspot 2.0 R1) ++ ++config MTK_PASSPOINT_R2_SUPPORT ++ bool "MTK_PASSPOINT_R2_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ help ++ Support Passpoint R2 ++ ++config MTK_WIFI_MCC_SUPPORT ++ bool "MTK_WIFI_MCC_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ #default y ++ help ++ if it is set to TRUE, wlan will support Multi-Channel Concurrency, ++ otherwise, only support Single Channel Concurrency ++ ++config MTK_DHCPV6C_WIFI ++ bool "MTK_DHCPV6C_WIFI" ++ help ++ no: disable this feature ++ ++config MTK_CONN_LTE_IDC_SUPPORT ++ bool "MediaTek CONN LTE IDC support" ++ select MTK_CONN_MD ++ #default y ++ help ++ This option enables CONN LTE IDC support ++ ++menuconfig GPS ++ tristate "GPS drivers" ++ #default y ++ ---help--- ++ Say Y here for supporting GPS. ++ ++if GPS ++config MTK_GPS ++ tristate "MediaTek GPS driver" ++ #default y ++ ---help--- ++ MTK GPS driver ++ To switch gps nmea port driver. ++ Set "yes" to turn on. ++ Set "no" to turn off. ++endif # GPS ++ ++config MTK_GPS_SUPPORT ++ tristate "MediaTek GPS driver" ++ select MTK_GPS ++ help ++ to switch GPS feature on the platform. ++ Set "yes" to turn on and set "no" ++ (with MTK_AGPS_APP=no at the same time) ++ to turn off. ++ ++config MTK_GPS_REGISTER_SETTING ++ tristate "MediaTek GPS Register Setting" ++ depends on MTK_COMBO_GPS ++ help ++ GPS register settings. ++ ++config MTK_GPS_EMI ++ tristate "MediaTek GPS EMI Driver" ++ depends on MTK_COMBO_GPS ++ help ++ GPS EMI driver is for MNL OFFLOAD feature. +diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile +new file mode 100644 +index 000000000000..0947788d189a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/Makefile +@@ -0,0 +1,41 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++# Connectivity combo driver ++# If KERNELRELEASE is defined, we've been invoked from the ++# kernel build system and can use its language. ++ifneq ($(KERNELRELEASE),) ++subdir-ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE ++ifeq ($(CONFIG_ARM64), y) ++subdir-ccflags-y += -D CONFIG_MTK_WCN_ARM64 ++endif ++ ++ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) ++ subdir-ccflags-y += -D WMT_IDC_SUPPORT=1 ++else ++ subdir-ccflags-y += -D WMT_IDC_SUPPORT=0 ++endif ++ subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++ obj-y += common/ ++ obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/ ++ obj-n := dummy.o ++ ++# Otherwise we were called directly from the command line; ++# invoke the kernel build system. ++else ++ KERNELDIR ?= /lib/modules/$(shell uname -r)/build ++ PWD := $(shell pwd) ++default: ++ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/Makefile b/drivers/misc/mediatek/connectivity/common/Makefile +new file mode 100644 +index 000000000000..622b74430e13 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/Makefile +@@ -0,0 +1,23 @@ ++subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include ++subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat ++ ++#ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) ++# obj-y += combo/ ++#endif ++#ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) ++# subdir-ccflags-y += -D MT6628 ++# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT ++# obj-y += combo/ ++#endif ++#ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) ++# subdir-ccflags-y += -D MT6630 ++#ifneq ($(CONFIG_ARCH_MT2601),y) ++# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT ++#endif ++# obj-y += combo/ ++#endif ++ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++ obj-y += conn_soc/ ++endif ++ ++obj-y += common_detect/ +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile +new file mode 100644 +index 000000000000..8d7dc690affd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile +@@ -0,0 +1,47 @@ ++subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/dct/dct ++subdir-ccflags-y += -DWMT_PLAT_ALPS=1 ++ ++COMBO_CHIP_SUPPORT := false ++ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) ++ COMBO_CHIP_SUPPORT := true ++endif ++ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) ++ COMBO_CHIP_SUPPORT := true ++endif ++ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) ++ COMBO_CHIP_SUPPORT := true ++endif ++ifeq ($(COMBO_CHIP_SUPPORT), true) ++ subdir-ccflags-y += -D MTK_WCN_COMBO_CHIP_SUPPORT ++ ccflags-y += -I$(src)/../combo/linux/include ++endif ++ ++ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++ subdir-ccflags-y += -D MTK_WCN_SOC_CHIP_SUPPORT ++ ccflags-y += -I$(src)/../conn_soc/linux/include ++endif ++ ++ ++ifeq ($(CONFIG_MTK_COMBO),y) ++ ccflags-y += -I$(src)/drv_init/inc ++ obj-y += mtk_wcn_stub_alps.o ++ obj-y += wmt_stp_exp.o ++ obj-y += wmt_gpio.o ++ ++ obj-y += wmt_detect.o ++ obj-y += sdio_detect.o ++ obj-y += wmt_detect_pwr.o ++ ++ obj-y += drv_init/ ++endif ++ ++ifeq ($(CONFIG_MTK_COMBO),m) ++ obj-y += mtk_wcn_stub_alps.o ++ obj-y += wmt_stp_exp.o ++ obj-y += wmt_gpio.o ++ ++ obj-$(CONFIG_MTK_COMBO) += mtk_wmt_detect.o ++ mtk_wmt_detect-objs := wmt_detect.o ++ mtk_wmt_detect-objs += sdio_detect.o ++ mtk_wmt_detect-objs += wmt_detect_pwr.o ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +new file mode 100644 +index 000000000000..bb84384b9a24 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +@@ -0,0 +1,22 @@ ++ifeq ($(CONFIG_MTK_COMBO),y) ++ ccflags-y += -I$(src)/inc/ ++ ccflags-y += -I$(src)/../ ++ ++ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) ++ ccflags-y += -D MTK_WCN_WLAN_GEN3 ++endif ++ifneq ($(filter "CONSYS_6797",$(CONFIG_MTK_COMBO_CHIP)),) ++ ccflags-y += -D MTK_WCN_WLAN_GEN3 ++else ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++ ccflags-y += -D MTK_WCN_WLAN_GEN2 ++endif ++ ++ obj-y += conn_drv_init.o ++ obj-y += common_drv_init.o ++ obj-y += bluetooth_drv_init.o ++ obj-y += gps_drv_init.o ++ obj-y += fm_drv_init.o ++ obj-y += wlan_drv_init.o ++ obj-($(CONFIG_MTK_COMBO_ANT)) += ant_drv_init.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c +new file mode 100644 +index 000000000000..aa453f9397a4 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c +@@ -0,0 +1,38 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[ANT-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "ant_drv_init.h" ++ ++int do_ant_drv_init(int chip_id) ++{ ++ int i_ret = -1; ++ ++ WMT_DETECT_INFO_FUNC("start to do ANT driver init\n"); ++ switch (chip_id) { ++ case 0x6630: ++ case 0x6797: ++ i_ret = mtk_wcn_stpant_drv_init(); ++ WMT_DETECT_INFO_FUNC("finish ANT driver init, i_ret:%d\n", i_ret); ++ break; ++ default: ++ WMT_DETECT_ERR_FUNC("chipid is not 6630,ANT is not supported!\n"); ++ } ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c +new file mode 100644 +index 000000000000..47b055433443 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c +@@ -0,0 +1,35 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[BT-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "bluetooth_drv_init.h" ++ ++int do_bluetooth_drv_init(int chip_id) ++{ ++ int i_ret = -1; ++ ++#if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI) ++ WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n"); ++ i_ret = mtk_wcn_stpbt_drv_init(); ++ WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret); ++#else ++ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n"); ++#endif ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c +new file mode 100644 +index 000000000000..f9c332ea266b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c +@@ -0,0 +1,103 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "common_drv_init.h" ++ ++static int do_combo_common_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ int i_ret_tmp = 0; ++ ++ WMT_DETECT_DBG_FUNC("start to do combo driver init, chipid:0x%08x\n", chip_id); ++ ++ /* HIF-SDIO driver init */ ++ i_ret_tmp = mtk_wcn_hif_sdio_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("HIF-SDIO driver init, i_ret:%d\n", i_ret); ++ ++ /* WMT driver init */ ++ i_ret_tmp = mtk_wcn_combo_common_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); ++ ++ /* STP-UART driver init */ ++ i_ret_tmp = mtk_wcn_stp_uart_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("STP-UART driver init, i_ret:%d\n", i_ret); ++ ++ /* STP-SDIO driver init */ ++ i_ret_tmp = mtk_wcn_stp_sdio_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("STP-SDIO driver init, i_ret:%d\n", i_ret); ++ ++#else ++ i_ret = -1; ++ WMT_DETECT_ERR_FUNC("COMBO chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); ++#endif ++ WMT_DETECT_DBG_FUNC("finish combo driver init\n"); ++ return i_ret; ++} ++ ++static int do_soc_common_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++#ifdef MTK_WCN_SOC_CHIP_SUPPORT ++ int i_ret_tmp = 0; ++ ++ WMT_DETECT_DBG_FUNC("start to do soc common driver init, chipid:0x%08x\n", chip_id); ++ ++ /* WMT driver init */ ++ i_ret_tmp = mtk_wcn_soc_common_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); ++ ++#else ++ i_ret = -1; ++ WMT_DETECT_ERR_FUNC("SOC chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); ++#endif ++ ++ WMT_DETECT_DBG_FUNC("TBD........\n"); ++ return i_ret; ++} ++ ++int do_common_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++ WMT_DETECT_INFO_FUNC("start to do common driver init, chipid:0x%08x\n", chip_id); ++ ++ switch (chip_id) { ++ case 0x6620: ++ case 0x6628: ++ case 0x6630: ++ i_ret = do_combo_common_drv_init(chip_id); ++ break; ++ default: ++ i_ret = do_soc_common_drv_init(chip_id); ++ break; ++ } ++ ++ WMT_DETECT_INFO_FUNC("finish common driver init\n"); ++ ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c +new file mode 100644 +index 000000000000..8112d2a1d95e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c +@@ -0,0 +1,80 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WCN-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "conn_drv_init.h" ++#include "common_drv_init.h" ++#include "fm_drv_init.h" ++#include "wlan_drv_init.h" ++#include "bluetooth_drv_init.h" ++#include "gps_drv_init.h" ++#include "ant_drv_init.h" ++ ++int __weak do_wlan_drv_init(int chip_id) ++{ ++ WMT_DETECT_ERR_FUNC("Can not find wlan module for chip: %d !\n", chip_id); ++ return 0; ++} ++ ++int __weak do_ant_drv_init(int chip_id) ++{ ++ WMT_DETECT_DBG_FUNC("Chip: %d can not support ANT !\n", chip_id); ++ return 0; ++} ++ ++int do_connectivity_driver_init(int chip_id) ++{ ++ int i_ret = 0; ++ int tmp_ret = 0; ++ ++ tmp_ret = do_common_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) { ++ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); ++ WMT_DETECT_ERR_FUNC("abort connectivity driver init, because common part is not ready\n"); ++ return i_ret; ++ } ++ ++ tmp_ret = do_bluetooth_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_gps_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_fm_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do fm module init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_wlan_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do wlan module init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_ant_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do ANT module init failed, ret:%d\n", tmp_ret); ++ ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c +new file mode 100644 +index 000000000000..069c1cf13bba +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c +@@ -0,0 +1,33 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[FM-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "fm_drv_init.h" ++ ++int do_fm_drv_init(int chip_id) ++{ ++ WMT_DETECT_INFO_FUNC("start to do fm module init\n"); ++ ++#ifdef CONFIG_MTK_FMRADIO ++ mtk_wcn_fm_init(); ++#endif ++ ++ WMT_DETECT_INFO_FUNC("finish fm module init\n"); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c +new file mode 100644 +index 000000000000..6da1d70a3ca6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c +@@ -0,0 +1,35 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[GPS-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "gps_drv_init.h" ++ ++int do_gps_drv_init(int chip_id) ++{ ++ int i_ret = -1; ++#ifdef CONFIG_MTK_COMBO_GPS ++ WMT_DETECT_INFO_FUNC("start to do gps driver init\n"); ++ i_ret = mtk_wcn_stpgps_drv_init(); ++ WMT_DETECT_INFO_FUNC("finish gps driver init, i_ret:%d\n", i_ret); ++#else ++ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_GPS is not defined\n"); ++#endif ++ return i_ret; ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h +new file mode 100644 +index 000000000000..4a436a236290 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h +@@ -0,0 +1,20 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _ANT_DRIVER_INIT_H_ ++#define _ANT_DRIVER_INIT_H_ ++ ++extern int do_ant_drv_init(int chip_id); ++extern int mtk_wcn_stpant_drv_init(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h +new file mode 100644 +index 000000000000..8a847d361fc8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h +@@ -0,0 +1,20 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _BLUETOOTH_DRIVER_INIT_H_ ++#define _BLUETOOTH_DRIVER_INIT_H_ ++ ++extern int do_bluetooth_drv_init(int chip_id); ++extern int mtk_wcn_stpbt_drv_init(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h +new file mode 100644 +index 000000000000..ea01bd633c3c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h +@@ -0,0 +1,31 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _COMMON_DRV_INIT_H_ ++#define _COMMON_DRV_INIT_H_ ++extern int do_common_drv_init(int chip_id); ++ ++/*defined in common part driver*/ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++extern int mtk_wcn_combo_common_drv_init(void); ++extern int mtk_wcn_hif_sdio_drv_init(void); ++extern int mtk_wcn_stp_uart_drv_init(void); ++extern int mtk_wcn_stp_sdio_drv_init(void); ++#endif ++ ++#ifdef MTK_WCN_SOC_CHIP_SUPPORT ++extern int mtk_wcn_soc_common_drv_init(void); ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h +new file mode 100644 +index 000000000000..971193eade9e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h +@@ -0,0 +1,18 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _CONNECTIVITY_DRV_INIT_H_ ++#define _CONNECTIVITY_DRV_INIT_H_ ++extern int do_connectivity_driver_init(int chip_id); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h +new file mode 100644 +index 000000000000..f6ea30addc5d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h +@@ -0,0 +1,20 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _FM_DRV_INIT_H_ ++#define _FM_DRV_INIT_H_ ++extern int do_fm_drv_init(int chip_id); ++extern int mtk_wcn_fm_init(void); ++extern void mtk_wcn_fm_exit(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h +new file mode 100644 +index 000000000000..006ce072c53b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h +@@ -0,0 +1,19 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _GPS_DRIVER_INIT_H_ ++#define _GPS_DRIVER_INIT_H_ ++extern int do_gps_drv_init(int chip_id); ++extern int mtk_wcn_stpgps_drv_init(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h +new file mode 100644 +index 000000000000..cb71b50bf950 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h +@@ -0,0 +1,30 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WLAN_DRV_INIT_H_ ++#define _WLAN_DRV_INIT_H_ ++ ++ ++extern int do_wlan_drv_init(int chip_id); ++ ++extern int mtk_wcn_wmt_wifi_init(void); ++ ++#ifdef MTK_WCN_WLAN_GEN2 ++extern int mtk_wcn_wlan_gen2_init(void); ++#endif ++#ifdef MTK_WCN_WLAN_GEN3 ++extern int mtk_wcn_wlan_gen3_init(void); ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +new file mode 100644 +index 000000000000..5b0d039a4a42 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +@@ -0,0 +1,74 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WLAN-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "wlan_drv_init.h" ++ ++ ++int do_wlan_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++#ifdef CONFIG_MTK_COMBO_WIFI ++ int ret = 0; ++ ++ WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); ++ ++ /* WMT-WIFI char dev init */ ++ ret = mtk_wcn_wmt_wifi_init(); ++ WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); ++ i_ret += ret; ++ ++ switch (chip_id) { ++ case 0x6630: ++ case 0x6797: ++#ifdef MTK_WCN_WLAN_GEN3 ++ /* WLAN driver init */ ++ ret = mtk_wcn_wlan_gen3_init(); ++ WMT_DETECT_INFO_FUNC("WLAN-GEN3 driver init, ret:%d\n", ret); ++ i_ret += ret; ++#else ++ WMT_DETECT_ERR_FUNC("WLAN-GEN3 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); ++ i_ret = -1; ++#endif ++ break; ++ ++ default: ++#ifdef MTK_WCN_WLAN_GEN2 ++ /* WLAN driver init */ ++ ret = mtk_wcn_wlan_gen2_init(); ++ WMT_DETECT_INFO_FUNC("WLAN-GEN2 driver init, ret:%d\n", ret); ++ i_ret += ret; ++#else ++ WMT_DETECT_ERR_FUNC("WLAN-GEN2 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); ++ i_ret = -1; ++#endif ++ break; ++ } ++ ++ WMT_DETECT_INFO_FUNC("finish wlan module init\n"); ++ ++#else ++ ++ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); ++ ++#endif ++ ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c +new file mode 100644 +index 000000000000..fa8d437686f2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c +@@ -0,0 +1,605 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define CMB_STUB_DBG_LOG 3 ++#define CMB_STUB_INFO_LOG 2 ++#define CMB_STUB_WARN_LOG 1 ++ ++int gCmbStubLogLevel = CMB_STUB_INFO_LOG; ++ ++#define CMB_STUB_LOG_INFO(fmt, arg...) \ ++do { \ ++ if (gCmbStubLogLevel >= CMB_STUB_INFO_LOG) \ ++ pr_warn(fmt, ##arg); \ ++} while (0) ++#define CMB_STUB_LOG_WARN(fmt, arg...) \ ++do { \ ++ if (gCmbStubLogLevel >= CMB_STUB_WARN_LOG) \ ++ pr_warn(fmt, ##arg); \ ++} while (0) ++#define CMB_STUB_LOG_DBG(fmt, arg...) \ ++do { \ ++ if (gCmbStubLogLevel >= CMB_STUB_DBG_LOG) \ ++ pr_debug(fmt, ##arg); \ ++} while (0) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "wmt_detect.h" ++ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 ++#endif ++ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++struct work_struct *g_sdio_1v_autok_wk = NULL; ++#endif ++int gConnectivityChipId = -1; ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++/* ++* current used uart port name, default is "ttyMT2", ++* will be changed when wmt driver init ++*/ ++char *wmt_uart_port_desc = "ttyMT2"; ++EXPORT_SYMBOL(wmt_uart_port_desc); ++#endif ++ ++static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data); ++static void mtk_wcn_cmb_sdio_enable_eirq(void); ++static void mtk_wcn_cmb_sdio_disable_eirq(void); ++static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data); ++ ++struct sdio_ops mt_sdio_ops[4] = { ++ {NULL, NULL, NULL, NULL}, ++ {NULL, NULL, NULL, NULL}, ++ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, ++ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm}, ++ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, ++ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm} ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb; ++static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb; ++static wmt_thermal_query_cb cmb_stub_thermal_ctrl_cb; ++static CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0; ++static wmt_deep_idle_ctrl_cb cmb_stub_deep_idle_ctrl_cb; ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++static wmt_get_drv_status cmb_stub_drv_status_ctrl_cb; ++#endif ++static wmt_func_do_reset cmb_stub_do_reset_cb; ++/* A temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X. ++ * This is used for ALPS backward compatible ONLY!!! Remove this table, related ++ * functions, and type definition after modifying other kernel built-in modules, ++ * such as AUDIO. [FixMe][GeorgeKuo] ++ */ ++#if 0 ++static CMB_STUB_AIF_X audio2aif[] = { ++ [COMBO_AUDIO_STATE_0] = CMB_STUB_AIF_0, ++ [COMBO_AUDIO_STATE_1] = CMB_STUB_AIF_1, ++ [COMBO_AUDIO_STATE_2] = CMB_STUB_AIF_2, ++ [COMBO_AUDIO_STATE_3] = CMB_STUB_AIF_3, ++}; ++#endif ++static msdc_sdio_irq_handler_t mtk_wcn_cmb_sdio_eirq_handler; ++static atomic_t sdio_claim_irq_enable_flag; ++static atomic_t irq_enable_flag; ++static pm_callback_t mtk_wcn_cmb_sdio_pm_cb; ++static void *mtk_wcn_cmb_sdio_pm_data; ++static void *mtk_wcn_cmb_sdio_eirq_data; ++ ++static u32 wifi_irq = 0xffffffff; ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++static void mtk_wcn_cmb_stub_1v_autok_work(struct work_struct *work) ++{ ++ CMB_STUB_LOG_WARN("++enter++\n"); ++ mtk_wcn_cmb_stub_func_ctrl(11, 1); ++ mtk_wcn_cmb_stub_func_ctrl(11, 0); ++ CMB_STUB_LOG_WARN("--exit--\n"); ++} ++ ++/*! ++ * \brief A function for Getting current driver status:on/off ++ * ++ * \param driver type:0/bt,1/fm,2/gps,3/wifi,11/autok->run wmt turn on/off wifi flow ++ * ++ * \retval 0/off,2/on,-1/null pointer ++ */ ++static int mtk_wcn_cmb_stub_drv_status(unsigned int type) ++{ ++ int ret = -1; ++ ++ if (cmb_stub_drv_status_ctrl_cb) ++ ret = (*cmb_stub_drv_status_ctrl_cb) (type); ++ else ++ CMB_STUB_LOG_WARN("cmb_stub_drv_status_ctrl_cb is NULL\n"); ++ return ret; ++} ++ ++/*! ++ * \brief A 1v AutoK function for kernel DVFS driver calling when screen off ++ * ++ * \param void ++ * ++ * \retval int,mt6630 state:0/off,1/power on,2/func on, -1/null ++ */ ++int mtk_wcn_cmb_stub_1vautok_for_dvfs(void) ++{ ++ int wmt_status; ++ ++ CMB_STUB_LOG_WARN("DVFS driver call sdio 1v autok\n"); ++ ++ wmt_status = mtk_wcn_cmb_stub_drv_status(4); ++ CMB_STUB_LOG_WARN("current mt6630 status is %d\n", wmt_status); ++ if (0 == wmt_status) { ++ if (g_sdio_1v_autok_wk) ++ schedule_work(g_sdio_1v_autok_wk); ++ else ++ CMB_STUB_LOG_WARN("g_sdio_1v_autok_wk is NULL\n"); ++ } else if ((2 == wmt_status) || (1 == wmt_status)) { ++ CMB_STUB_LOG_WARN("mt6630 is on state,skip AUTOK\n"); ++ } else { ++ CMB_STUB_LOG_WARN("mt6630 is unknown state(%d)\n", wmt_status); ++ } ++ ++ return wmt_status; ++ ++} ++#endif ++/*! ++ * \brief A registration function for WMT-PLAT to register itself to CMB-STUB. ++ * ++ * An MTK-WCN-CMB-STUB registration function provided to WMT-PLAT to register ++ * itself and related callback functions when driver being loaded into kernel. ++ * ++ * \param p_stub_cb a pointer carrying CMB_STUB_CB information ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid parameters ++ */ ++int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb) ++{ ++ if ((!p_stub_cb) ++ || (p_stub_cb->size != sizeof(CMB_STUB_CB))) { ++ CMB_STUB_LOG_WARN("[cmb_stub] invalid p_stub_cb:0x%p size(%d)\n", ++ p_stub_cb, (p_stub_cb) ? p_stub_cb->size : 0); ++ return -1; ++ } ++ ++ CMB_STUB_LOG_DBG("[cmb_stub] registered, p_stub_cb:0x%p size(%d)\n", p_stub_cb, p_stub_cb->size); ++ ++ cmb_stub_aif_ctrl_cb = p_stub_cb->aif_ctrl_cb; ++ cmb_stub_func_ctrl_cb = p_stub_cb->func_ctrl_cb; ++ cmb_stub_thermal_ctrl_cb = p_stub_cb->thermal_query_cb; ++ cmb_stub_deep_idle_ctrl_cb = p_stub_cb->deep_idle_ctrl_cb; ++ cmb_stub_do_reset_cb = p_stub_cb->wmt_do_reset_cb; ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ cmb_stub_drv_status_ctrl_cb = p_stub_cb->get_drv_status_cb; ++ g_sdio_1v_autok_wk = vmalloc(sizeof(struct work_struct)); ++ if (!g_sdio_1v_autok_wk) ++ CMB_STUB_LOG_WARN("vmalloc work_struct(%zd) fail\n", sizeof(struct work_struct)); ++ else ++ INIT_WORK(g_sdio_1v_autok_wk, mtk_wcn_cmb_stub_1v_autok_work); ++ ++#endif ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_reg); ++/*! ++ * \brief A unregistration function for WMT-PLAT to unregister from CMB-STUB. ++ * ++ * An MTK-WCN-CMB-STUB unregistration function provided to WMT-PLAT to ++ * unregister itself and clear callback function references. ++ * ++ * \retval 0 operation success ++ */ ++int mtk_wcn_cmb_stub_unreg(void) ++{ ++ cmb_stub_aif_ctrl_cb = NULL; ++ cmb_stub_func_ctrl_cb = NULL; ++ cmb_stub_thermal_ctrl_cb = NULL; ++ cmb_stub_deep_idle_ctrl_cb = NULL; ++ cmb_stub_do_reset_cb = NULL; ++ CMB_STUB_LOG_INFO("[cmb_stub] unregistered\n"); /* KERN_DEBUG */ ++ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ if (g_sdio_1v_autok_wk) { ++ vfree(g_sdio_1v_autok_wk); ++ g_sdio_1v_autok_wk = NULL; ++ } ++#endif ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_unreg); ++ ++/* stub functions for kernel to control audio path pin mux */ ++int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) ++{ ++ int ret; ++ ++ if ((CMB_STUB_AIF_MAX <= state) ++ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { ++ ++ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl invalid (%d, %d)\n", state, ctrl); ++ return -1; ++ } ++ ++ /* avoid the early interrupt before we register the eirq_handler */ ++ if (cmb_stub_aif_ctrl_cb) { ++ ret = (*cmb_stub_aif_ctrl_cb) (state, ctrl); ++ CMB_STUB_LOG_INFO("[cmb_stub] aif_ctrl_cb state(%d->%d) ctrl(%d) ret(%d)\n", ++ cmb_stub_aif_stat, state, ctrl, ret); /* KERN_DEBUG */ ++ ++ cmb_stub_aif_stat = state; ++ } else { ++ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl_cb null\n"); ++ ret = -2; ++ } ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_aif_ctrl); ++ ++/* Use a temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X ++ * for ALPS backward compatible ONLY!!! Remove this table, related functions, ++ * and type definition after modifying other kernel built-in modules, such as ++ * AUDIO. [FixMe][GeorgeKuo] ++ */ ++ ++void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on) ++{ ++ if (cmb_stub_func_ctrl_cb) ++ (*cmb_stub_func_ctrl_cb) (type, on); ++ else ++ CMB_STUB_LOG_WARN("[cmb_stub] func_ctrl_cb null\n"); ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_func_ctrl); ++ ++int mtk_wcn_cmb_stub_query_ctrl(void) ++{ ++ signed long temp = 0; ++ ++ if (cmb_stub_thermal_ctrl_cb) ++ temp = (*cmb_stub_thermal_ctrl_cb) (); ++ else ++ CMB_STUB_LOG_WARN("[cmb_stub] thermal_ctrl_cb null\n"); ++ ++ return temp; ++} ++ ++/*platform-related APIs*/ ++/* void clr_device_working_ability(UINT32 clockId, MT6573_STATE state); */ ++/* void set_device_working_ability(UINT32 clockId, MT6573_STATE state); */ ++ ++static int _mt_combo_plt_do_deep_idle(COMBO_IF src, int enter) ++{ ++ int ret = -1; ++ ++#if 0 ++ if (src != COMBO_IF_UART && src != COMBO_IF_MSDC && src != COMBO_IF_BTIF) { ++ CMB_STUB_LOG_WARN("src = %d is error\n", src); ++ return ret; ++ } ++ if (src >= 0 && src < COMBO_IF_MAX) ++ CMB_STUB_LOG_INFO("src = %s, to enter deep idle? %d\n", combo_if_name[src], enter); ++#endif ++ /*TODO: For Common SDIO configuration, we need to do some judgement between STP and WIFI ++ to decide if the msdc will enter deep idle safely */ ++ ++ switch (src) { ++ case COMBO_IF_UART: ++ if (enter == 0) { ++ /* clr_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ ++ /* disable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++#if 0 ++ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 0); ++ if (ret < 0) ++ CMB_STUB_LOG_WARN("[CMB] %s exit deep idle failed\n", wmt_uart_port_desc); ++#endif ++#endif ++ } else { ++ /* set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ ++ /* enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++#if 0 ++ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 1); ++ if (ret < 0) ++ CMB_STUB_LOG_WARN("[CMB] %s enter deep idle failed\n", wmt_uart_port_desc); ++#endif ++#endif ++ } ++ ret = 0; ++ break; ++ ++ case COMBO_IF_MSDC: ++ if (enter == 0) { ++ /* for common sdio hif */ ++ /* clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ ++ } else { ++ /* for common sdio hif */ ++ /* set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ ++ } ++ ret = 0; ++ break; ++ ++ case COMBO_IF_BTIF: ++ if (cmb_stub_deep_idle_ctrl_cb) ++ ret = (*cmb_stub_deep_idle_ctrl_cb) (enter); ++ else ++ CMB_STUB_LOG_WARN("NULL function pointer\n"); ++ ++ if (ret) ++ CMB_STUB_LOG_WARN("%s deep idle fail(%d)\n", enter == 1 ? "enter" : "exit", ret); ++ else ++ CMB_STUB_LOG_DBG("%s deep idle ok(%d)\n", enter == 1 ? "enter" : "exit", ret); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++int mt_combo_plt_enter_deep_idle(COMBO_IF src) ++{ ++ /* return 0; */ ++ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ ++ return _mt_combo_plt_do_deep_idle(src, 1); ++} ++EXPORT_SYMBOL(mt_combo_plt_enter_deep_idle); ++ ++int mt_combo_plt_exit_deep_idle(COMBO_IF src) ++{ ++ /* return 0; */ ++ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ ++ return _mt_combo_plt_do_deep_idle(src, 0); ++} ++EXPORT_SYMBOL(mt_combo_plt_exit_deep_idle); ++ ++int mtk_wcn_wmt_chipid_query(void) ++{ ++ return gConnectivityChipId; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query); ++ ++void mtk_wcn_wmt_set_chipid(int chipid) ++{ ++ CMB_STUB_LOG_INFO("set current consys chipid (0x%x)\n", chipid); ++ gConnectivityChipId = chipid; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_set_chipid); ++ ++int mtk_wcn_cmb_stub_do_reset(unsigned int type) ++{ ++ if (cmb_stub_do_reset_cb) ++ return (*cmb_stub_do_reset_cb) (type); ++ else ++ return -1; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_do_reset); ++ ++static void mtk_wcn_cmb_sdio_enable_eirq(void) ++{ ++ if (atomic_read(&irq_enable_flag)) ++ CMB_STUB_LOG_DBG("wifi eint has been enabled\n"); ++ else { ++ atomic_set(&irq_enable_flag, 1); ++ if (wifi_irq != 0xfffffff) { ++ enable_irq(wifi_irq); ++ CMB_STUB_LOG_DBG(" enable WIFI EINT irq %d !!\n", wifi_irq); ++ } ++ } ++} ++ ++static void mtk_wcn_cmb_sdio_disable_eirq(void) ++{ ++ if (!atomic_read(&irq_enable_flag)) ++ CMB_STUB_LOG_DBG("wifi eint has been disabled!\n"); ++ else { ++ if (wifi_irq != 0xfffffff) { ++ disable_irq_nosync(wifi_irq); ++ CMB_STUB_LOG_DBG("disable WIFI EINT irq %d !!\n", wifi_irq); ++ } ++ atomic_set(&irq_enable_flag, 0); ++ } ++} ++ ++irqreturn_t mtk_wcn_cmb_sdio_eirq_handler_stub(int irq, void *data) ++{ ++ if ((NULL != mtk_wcn_cmb_sdio_eirq_handler)&&(0 != atomic_read(&sdio_claim_irq_enable_flag))) ++ mtk_wcn_cmb_sdio_eirq_handler(mtk_wcn_cmb_sdio_eirq_data); ++ return IRQ_HANDLED; ++} ++ ++static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data) ++{ ++ struct device_node *node; ++ int ret = -EINVAL; ++#if 0 ++ unsigned int gpio_wifi_eint_pin; ++#endif ++ ++ CMB_STUB_LOG_INFO("enter %s\n", __func__); ++ mtk_wcn_sdio_irq_flag_set(0); ++ atomic_set(&irq_enable_flag, 0); ++ mtk_wcn_cmb_sdio_eirq_data = data; ++ mtk_wcn_cmb_sdio_eirq_handler = irq_handler; ++ ++ node = (struct device_node *)of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); ++ if (node) { ++#if 0 ++ gpio_wifi_eint_pin = of_get_gpio(node, 5); ++ CMB_STUB_LOG_INFO("WIFI EINT pin %d !!\n", gpio_wifi_eint_pin); ++ wifi_irq = gpio_to_irq(gpio_wifi_eint_pin); ++#else ++ wifi_irq = irq_of_parse_and_map(node, 0);/* get wifi eint num */ ++#endif ++#if 1 ++ ret = request_irq(wifi_irq, mtk_wcn_cmb_sdio_eirq_handler_stub, IRQF_TRIGGER_LOW, ++ "WIFI-eint", NULL); ++ CMB_STUB_LOG_DBG("WIFI EINT irq %d !!\n", wifi_irq); ++#endif ++ ++ if (ret) ++ CMB_STUB_LOG_WARN("WIFI EINT IRQ LINE NOT AVAILABLE!!\n"); ++ else ++ mtk_wcn_cmb_sdio_disable_eirq();/*not ,chip state is power off*/ ++ } else ++ CMB_STUB_LOG_WARN("[%s] can't find connectivity compatible node\n", __func__); ++ ++ CMB_STUB_LOG_INFO("exit %s\n", __func__); ++} ++ ++static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data) ++{ ++ CMB_STUB_LOG_DBG("mtk_wcn_cmb_sdio_register_pm (0x%p, 0x%p)\n", pm_cb, data); ++ /* register pm change callback */ ++ mtk_wcn_cmb_sdio_pm_cb = pm_cb; ++ mtk_wcn_cmb_sdio_pm_data = data; ++} ++ ++static void mtk_wcn_cmb_sdio_on(int sdio_port_num) ++{ ++ pm_message_t state = {.event = PM_EVENT_USER_RESUME }; ++ ++ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_on (%d)\n", sdio_port_num); ++ ++ /* 1. disable sdio eirq */ ++ mtk_wcn_cmb_sdio_disable_eirq(); ++ ++ /* 2. call sd callback */ ++ if (mtk_wcn_cmb_sdio_pm_cb) { ++ /* pr_warn("mtk_wcn_cmb_sdio_pm_cb(PM_EVENT_USER_RESUME, 0x%p, 0x%p)\n", ++ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ ++ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); ++ } else ++ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_on no sd callback!!\n"); ++} ++ ++static void mtk_wcn_cmb_sdio_off(int sdio_port_num) ++{ ++ pm_message_t state = {.event = PM_EVENT_USER_SUSPEND }; ++ ++ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_off (%d)\n", sdio_port_num); ++ ++ /* 1. call sd callback */ ++ if (mtk_wcn_cmb_sdio_pm_cb) { ++ /* pr_warn("mtk_wcn_cmb_sdio_off(PM_EVENT_USER_SUSPEND, 0x%p, 0x%p)\n", ++ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ ++ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); ++ } else ++ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_off no sd callback!!\n"); ++ ++ /* 2. disable sdio eirq */ ++ mtk_wcn_cmb_sdio_disable_eirq(); ++} ++ ++int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on) ++{ ++ CMB_STUB_LOG_DBG("mt_mtk_wcn_cmb_sdio_ctrl (%d, %d)\n", sdio_port_num, on); ++ if (on) { ++#if 1 ++ CMB_STUB_LOG_DBG("board_sdio_ctrl force off before on\n"); ++ mtk_wcn_cmb_sdio_off(sdio_port_num); ++#else ++ CMB_STUB_LOG_WARN("skip sdio off before on\n"); ++#endif ++ /* off -> on */ ++ mtk_wcn_cmb_sdio_on(sdio_port_num); ++ if (wifi_irq != 0xfffffff) ++ irq_set_irq_wake(wifi_irq, 1); ++ else ++ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); ++ } else { ++ if (wifi_irq != 0xfffffff) ++ irq_set_irq_wake(wifi_irq, 0); ++ else ++ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); ++ /* on -> off */ ++ mtk_wcn_cmb_sdio_off(sdio_port_num); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(board_sdio_ctrl); ++ ++int mtk_wcn_sdio_irq_flag_set(int flag) ++{ ++ if (0 != flag) ++ atomic_set(&sdio_claim_irq_enable_flag, 1); ++ else ++ atomic_set(&sdio_claim_irq_enable_flag, 0); ++ ++ CMB_STUB_LOG_DBG("sdio_claim_irq_enable_flag:%d\n", atomic_read(&sdio_claim_irq_enable_flag)); ++ ++ return atomic_read(&sdio_claim_irq_enable_flag); ++} ++EXPORT_SYMBOL(mtk_wcn_sdio_irq_flag_set); +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c +new file mode 100644 +index 000000000000..7ac5ac73ef5d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c +@@ -0,0 +1,269 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[SDIO-DETECT]" ++ ++#include "wmt_detect.h" ++ ++#if MTK_HIF_SDIO_AUTOK_ENABLED ++#include ++#endif ++ ++unsigned int gComboChipId = -1; ++struct sdio_func *g_func = NULL; ++ ++MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = { ++ /* MT6620 *//* Not an SDIO standard class device */ ++ {{SDIO_DEVICE(0x037A, 0x020A)}, 0x6620}, /* SDIO1:FUNC1:WIFI */ ++ {{SDIO_DEVICE(0x037A, 0x020B)}, 0x6620}, /* SDIO2:FUNC1:BT+FM+GPS */ ++ {{SDIO_DEVICE(0x037A, 0x020C)}, 0x6620}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ ++ ++ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {{SDIO_DEVICE(0x037A, 0x6628)}, 0x6628}, ++ ++ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {{SDIO_DEVICE(0x037A, 0x6630)}, 0x6630}, ++ ++}; ++ ++/* Supported SDIO device table */ ++static const struct sdio_device_id mtk_sdio_id_tbl[] = { ++ /* MT6618 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x018A)}, /* SDIO1:WIFI */ ++ {SDIO_DEVICE(0x037A, 0x018B)}, /* SDIO2:FUNC1:BT+FM */ ++ {SDIO_DEVICE(0x037A, 0x018C)}, /* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */ ++ ++ /* MT6619 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x6619)}, /* SDIO2:FUNC1:BT+FM+GPS */ ++ ++ /* MT6620 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x020A)}, /* SDIO1:FUNC1:WIFI */ ++ {SDIO_DEVICE(0x037A, 0x020B)}, /* SDIO2:FUNC1:BT+FM+GPS */ ++ {SDIO_DEVICE(0x037A, 0x020C)}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ ++ ++ /* MT5921 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x5921)}, ++ ++ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {SDIO_DEVICE(0x037A, 0x6628)}, ++ ++ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {SDIO_DEVICE(0x037A, 0x6630)}, ++ { /* end: all zeroes */ }, ++}; ++ ++static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id); ++ ++static void sdio_detect_remove(struct sdio_func *func); ++ ++static struct sdio_driver mtk_sdio_client_drv = { ++ .name = "mtk_sdio_client", /* MTK SDIO Client Driver */ ++ .id_table = mtk_sdio_id_tbl, /* all supported struct sdio_device_id table */ ++ .probe = sdio_detect_probe, ++ .remove = sdio_detect_remove, ++}; ++ ++static int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id); ++ ++int hif_sdio_is_chipid_valid(int chipId) ++{ ++ int index = -1; ++ ++ int left = 0; ++ int middle = 0; ++ int right = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]) - 1; ++ ++ if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId)) ++ return index; ++ ++ middle = (left + right) / 2; ++ ++ while (left <= right) { ++ if (chipId > gChipInfoArray[middle].chipId) { ++ left = middle + 1; ++ } else if (chipId < gChipInfoArray[middle].chipId) { ++ right = middle - 1; ++ } else { ++ index = middle; ++ break; ++ } ++ middle = (left + right) / 2; ++ } ++ ++ if (0 > index) ++ WMT_DETECT_ERR_FUNC("no supported chipid found\n"); ++ else ++ WMT_DETECT_INFO_FUNC("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId); ++ ++ return index; ++} ++ ++int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id) ++{ ++ int maxIndex = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]); ++ int index = 0; ++ struct sdio_device_id *localId = NULL; ++ int chipId = -1; ++ ++ for (index = 0; index < maxIndex; index++) { ++ localId = &(gChipInfoArray[index].deviceId); ++ if ((localId->vendor == id->vendor) && (localId->device == id->device)) { ++ chipId = gChipInfoArray[index].chipId; ++ WMT_DETECT_INFO_FUNC ++ ("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index, ++ localId->vendor, localId->device, chipId); ++ gComboChipId = chipId; ++ mtk_wcn_wmt_set_chipid(gComboChipId); ++ break; ++ } ++ } ++ if (0 > chipId) { ++ WMT_DETECT_ERR_FUNC("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor, ++ id->device); ++ } ++ ++ return chipId; ++} ++ ++int sdio_detect_query_chipid(int waitFlag) ++{ ++ unsigned int timeSlotMs = 200; ++ unsigned int maxTimeSlot = 15; ++ unsigned int counter = 0; ++ /* gComboChipId = 0x6628; */ ++ if (0 == waitFlag) ++ return gComboChipId; ++ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) ++ return gComboChipId; ++ ++ while (counter < maxTimeSlot) { ++ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) ++ break; ++ msleep(timeSlotMs); ++ counter++; ++ } ++ ++ return gComboChipId; ++} ++ ++int sdio_detect_do_autok(int chipId) ++{ ++ int i_ret = 0; ++ ++#if MTK_HIF_SDIO_AUTOK_ENABLED ++#if 0 ++ BOOTMODE boot_mode; ++ ++ boot_mode = get_boot_mode(); ++ ++ if (boot_mode == META_BOOT) { ++ WMT_DETECT_INFO_FUNC("omit autok in meta mode\n"); ++ return 0; ++ } ++#endif ++ if (0x6630 == chipId) { ++#ifdef CONFIG_SDIOAUTOK_SUPPORT ++ if (NULL != g_func) { ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready++\n"); ++ i_ret = wait_sdio_autok_ready(g_func->card->host); ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready--\n"); ++ if (0 == i_ret) { ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return success\n"); ++ } else { ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return fail, i_ret:%d\n", i_ret); ++ gComboChipId = -1; ++ } ++ } else { ++ WMT_DETECT_INFO_FUNC("g_func NULL, omit autok\n"); ++ } ++#else ++ i_ret = 0; ++ WMT_DETECT_INFO_FUNC("MTK_SDIOAUTOK_SUPPORT not defined\n"); ++#endif ++ } else { ++ WMT_DETECT_INFO_FUNC("MT%x does not support SDIO3.0 autoK is not needed\n", chipId); ++ } ++#else ++ i_ret = 0; ++ WMT_DETECT_INFO_FUNC("MTK_HIF_SDIO_AUTOK_ENABLED is not defined\n"); ++#endif ++ return i_ret; ++} ++ ++/*! ++ * \brief hif_sdio probe function ++ * ++ * hif_sdio probe function called by mmc driver when any matched SDIO function ++ * is detected by it. ++ * ++ * \param func ++ * \param id ++ * ++ * \retval 0 register successfully ++ * \retval < 0 list error code here ++ */ ++static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id) ++{ ++ int chipId = 0; ++ ++ WMT_DETECT_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); ++ chipId = hif_sdio_match_chipid_by_dev_id(id); ++ ++ if ((0x6630 == chipId) && (1 == func->num)) { ++ int ret = 0; ++ ++ g_func = func; ++ WMT_DETECT_INFO_FUNC("autok function detected, func:0x%p\n", g_func); ++ ++ sdio_claim_host(func); ++ ret = sdio_enable_func(func); ++ sdio_release_host(func); ++ if (ret) ++ WMT_DETECT_ERR_FUNC("sdio_enable_func failed!\n"); ++ } ++ ++ return 0; ++} ++ ++static void sdio_detect_remove(struct sdio_func *func) ++{ ++ if (g_func == func) { ++ sdio_claim_host(func); ++ sdio_disable_func(func); ++ sdio_release_host(func); ++ g_func = NULL; ++ } ++ WMT_DETECT_INFO_FUNC("do sdio remove\n"); ++} ++ ++int sdio_detect_init(void) ++{ ++ int ret = -1; ++ /* register to mmc driver */ ++ ret = sdio_register_driver(&mtk_sdio_client_drv); ++ WMT_DETECT_INFO_FUNC("sdio_register_driver() ret=%d\n", ret); ++ return 0; ++} ++ ++int sdio_detect_exit(void) ++{ ++ g_func = NULL; ++ /* register to mmc driver */ ++ sdio_unregister_driver(&mtk_sdio_client_drv); ++ WMT_DETECT_INFO_FUNC("sdio_unregister_driver\n"); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h +new file mode 100644 +index 000000000000..3a0bff9def1b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h +@@ -0,0 +1,43 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _SDIO_DETECT_H_ ++#define _SDIO_DETECT_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_SDIOAUTOK_SUPPORT ++#define MTK_HIF_SDIO_AUTOK_ENABLED 1 ++extern int wait_sdio_autok_ready(void *); ++#else ++#define MTK_HIF_SDIO_AUTOK_ENABLED 0 ++#endif ++ ++typedef struct _MTK_WCN_HIF_SDIO_CHIP_INFO_ { ++ struct sdio_device_id deviceId; ++ unsigned int chipId; ++} MTK_WCN_HIF_SDIO_CHIP_INFO, *P_MTK_WCN_HIF_SDIO_CHIP_INFO; ++ ++extern int sdio_detect_exit(void); ++extern int sdio_detect_init(void); ++extern int sdio_detect_query_chipid(int waitFlag); ++extern int hif_sdio_is_chipid_valid(int chipId); ++ ++extern int sdio_detect_do_autok(int chipId); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c +new file mode 100644 +index 000000000000..487852df8f20 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c +@@ -0,0 +1,380 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-DETECT]" ++ ++#include "wmt_detect.h" ++#include "wmt_gpio.h" ++ ++#if MTK_WCN_REMOVE_KO ++#include "conn_drv_init.h" ++#endif ++#ifdef CONFIG_COMPAT ++#include ++#endif ++ ++#define WMT_DETECT_MAJOR 154 ++#define WMT_DETECT_DEV_NUM 1 ++#define WMT_DETECT_DRVIER_NAME "mtk_wcn_detect" ++#define WMT_DETECT_DEVICE_NAME "wmtdetect" ++ ++struct class *pDetectClass = NULL; ++struct device *pDetectDev = NULL; ++static int gWmtDetectMajor = WMT_DETECT_MAJOR; ++static struct cdev gWmtDetectCdev; ++unsigned int gWmtDetectDbgLvl = WMT_DETECT_LOG_INFO; ++ ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++inline unsigned int wmt_plat_get_soc_chipid(void) ++{ ++ WMT_DETECT_INFO_FUNC("no soc chip supported, due to MTK_WCN_SOC_CHIP_SUPPORT is not set.\n"); ++ return -1; ++} ++#endif ++ ++static int wmt_detect_open(struct inode *inode, struct file *file) ++{ ++ WMT_DETECT_INFO_FUNC("open major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ++ return 0; ++} ++ ++static int wmt_detect_close(struct inode *inode, struct file *file) ++{ ++ WMT_DETECT_INFO_FUNC("close major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ++ return 0; ++} ++ ++static ssize_t wmt_detect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ WMT_DETECT_INFO_FUNC(" ++\n"); ++ WMT_DETECT_INFO_FUNC(" --\n"); ++ ++ return 0; ++} ++ ++ssize_t wmt_detect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ WMT_DETECT_INFO_FUNC(" ++\n"); ++ WMT_DETECT_INFO_FUNC(" --\n"); ++ ++ return 0; ++} ++ ++static long wmt_detect_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ int retval = 0; ++ ++ WMT_DETECT_INFO_FUNC("cmd (%d),arg(%ld)\n", cmd, arg); ++ ++ switch (cmd) { ++ case COMBO_IOCTL_GET_CHIP_ID: ++ /*just get chipid from sdio-detect module */ ++ /*check if external combo chip exists or not */ ++ /*if yes, just return combo chip id */ ++ /*if no, get soc chipid */ ++ retval = mtk_wcn_wmt_chipid_query(); ++ break; ++ ++ case COMBO_IOCTL_SET_CHIP_ID: ++ mtk_wcn_wmt_set_chipid(arg); ++ ++ break; ++ ++ case COMBO_IOCTL_EXT_CHIP_PWR_ON: ++ retval = wmt_detect_ext_chip_pwr_on(); ++ break; ++ ++ case COMBO_IOCTL_EXT_CHIP_DETECT: ++ retval = wmt_detect_ext_chip_detect(); ++ break; ++ ++ case COMBO_IOCTL_EXT_CHIP_PWR_OFF: ++ retval = wmt_detect_ext_chip_pwr_off(); ++ break; ++ ++ case COMBO_IOCTL_DO_SDIO_AUDOK: ++ retval = sdio_detect_do_autok(arg); ++ break; ++ ++ case COMBO_IOCTL_GET_SOC_CHIP_ID: ++ retval = wmt_plat_get_soc_chipid(); ++ /*get soc chipid by HAL interface */ ++ break; ++ ++ case COMBO_IOCTL_MODULE_CLEANUP: ++#if (MTK_WCN_REMOVE_KO) ++ /*deinit SDIO-DETECT module */ ++ retval = sdio_detect_exit(); ++#else ++ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); ++#endif ++ break; ++ ++ case COMBO_IOCTL_DO_MODULE_INIT: ++#if (MTK_WCN_REMOVE_KO) ++ /*deinit SDIO-DETECT module */ ++ retval = do_connectivity_driver_init(arg); ++#else ++ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); ++#endif ++ break; ++ ++ default: ++ WMT_DETECT_WARN_FUNC("unknown cmd (%d)\n", cmd); ++ retval = 0; ++ break; ++ } ++ return retval; ++} ++#ifdef CONFIG_COMPAT ++static long WMT_compat_detect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ WMT_DETECT_INFO_FUNC("cmd (%d)\n", cmd); ++ ret = wmt_detect_unlocked_ioctl(filp, cmd, arg); ++ return ret; ++} ++#endif ++const struct file_operations gWmtDetectFops = { ++ .open = wmt_detect_open, ++ .release = wmt_detect_close, ++ .read = wmt_detect_read, ++ .write = wmt_detect_write, ++ .unlocked_ioctl = wmt_detect_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = WMT_compat_detect_ioctl, ++#endif ++}; ++ ++int wmt_detect_ext_chip_pwr_on(void) ++{ ++ /*pre power on external chip */ ++ /* wmt_plat_pwr_ctrl(FUNC_ON); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ WMT_DETECT_INFO_FUNC("++\n"); ++ if (0 != wmt_detect_chip_pwr_ctrl(1)) ++ return -1; ++ if (0 != wmt_detect_sdio_pwr_ctrl(1)) ++ return -2; ++ return 0; ++#else ++ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); ++ return -1; ++#endif ++} ++ ++int wmt_detect_ext_chip_pwr_off(void) ++{ ++ /*pre power off external chip */ ++ /* wmt_plat_pwr_ctrl(FUNC_OFF); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ WMT_DETECT_INFO_FUNC("--\n"); ++ wmt_detect_sdio_pwr_ctrl(0); ++ return wmt_detect_chip_pwr_ctrl(0); ++#else ++ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); ++ return 0; ++#endif ++} ++ ++int wmt_detect_ext_chip_detect(void) ++{ ++ int iRet = -1; ++ unsigned int chipId = -1; ++ /*if there is no external combo chip, return -1 */ ++ int bgfEintStatus = -1; ++ ++ WMT_DETECT_INFO_FUNC("++\n"); ++ /*wait for a stable time */ ++ msleep(20); ++ ++ /*read BGF_EINT_PIN status */ ++ bgfEintStatus = wmt_detect_read_ext_cmb_status(); ++ ++ if (0 == bgfEintStatus) { ++ /*external chip does not exist */ ++ WMT_DETECT_INFO_FUNC("external combo chip not detected\n"); ++ } else if (1 == bgfEintStatus) { ++ /*combo chip exists */ ++ WMT_DETECT_INFO_FUNC("external combo chip detected\n"); ++ ++ /*detect chipid by sdio_detect module */ ++ chipId = sdio_detect_query_chipid(1); ++ if (0 <= hif_sdio_is_chipid_valid(chipId)) ++ WMT_DETECT_INFO_FUNC("valid external combo chip id (0x%x)\n", chipId); ++ else ++ WMT_DETECT_INFO_FUNC("invalid external combo chip id (0x%x)\n", chipId); ++ iRet = 0; ++ } else { ++ /*Error exists */ ++ WMT_DETECT_ERR_FUNC("error happens when detecting combo chip\n"); ++ } ++ WMT_DETECT_INFO_FUNC("--\n"); ++ /*return 0 */ ++ return iRet; ++ /*todo: if there is external combo chip, power on chip return 0 */ ++} ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++static int wmt_detect_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ WMT_DETECT_ERR_FUNC("platform name: %s\n", pdev->name); ++ ret = wmt_gpio_init(pdev); ++ if (-1 == ret) ++ WMT_DETECT_ERR_FUNC("gpio init fail ret:%d\n", ret); ++ return ret; ++} ++ ++static int wmt_detect_remove(struct platform_device *pdev) ++{ ++ wmt_gpio_deinit(); ++ return 0; ++} ++#endif ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++static struct of_device_id wmt_detect_match[] = { ++ { .compatible = "mediatek,connectivity-combo", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, wmt_detect_match); ++ ++static struct platform_driver wmt_detect_driver = { ++ .probe = wmt_detect_probe, ++ .remove = wmt_detect_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "mediatek,connectivity-combo", ++ .of_match_table = wmt_detect_match, ++ }, ++}; ++#endif ++ ++/*module_platform_driver(wmt_detect_driver);*/ ++static int wmt_detect_driver_init(void) ++{ ++ dev_t devID = MKDEV(gWmtDetectMajor, 0); ++ int cdevErr = -1; ++ int ret = -1; ++ ++ ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME); ++ if (ret) { ++ WMT_DETECT_ERR_FUNC("fail to register chrdev\n"); ++ return ret; ++ } ++ ++ cdev_init(&gWmtDetectCdev, &gWmtDetectFops); ++ gWmtDetectCdev.owner = THIS_MODULE; ++ ++ cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM); ++ if (cdevErr) { ++ WMT_DETECT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); ++ goto err1; ++ } ++ ++ pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME); ++ if (IS_ERR(pDetectClass)) { ++ WMT_DETECT_ERR_FUNC("class create fail, error code(%ld)\n", PTR_ERR(pDetectClass)); ++ goto err1; ++ } ++ ++ pDetectDev = device_create(pDetectClass, NULL, devID, NULL, WMT_DETECT_DEVICE_NAME); ++ if (IS_ERR(pDetectDev)) { ++ WMT_DETECT_ERR_FUNC("device create fail, error code(%ld)\n", PTR_ERR(pDetectDev)); ++ goto err2; ++ } ++ ++ WMT_DETECT_INFO_FUNC("driver(major %d) installed success\n", gWmtDetectMajor); ++ ++ /*init SDIO-DETECT module */ ++ sdio_detect_init(); ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ ret = platform_driver_register(&wmt_detect_driver); ++ if (ret) ++ WMT_DETECT_ERR_FUNC("platform driver register fail ret:%d\n", ret); ++#endif ++ ++ return 0; ++ ++err2: ++ ++ if (pDetectClass) { ++ class_destroy(pDetectClass); ++ pDetectClass = NULL; ++ } ++ ++err1: ++ ++ if (cdevErr == 0) ++ cdev_del(&gWmtDetectCdev); ++ ++ if (ret == 0) { ++ unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM); ++ gWmtDetectMajor = -1; ++ } ++ ++ WMT_DETECT_ERR_FUNC("fail\n"); ++ ++ return -1; ++} ++ ++static void wmt_detect_driver_exit(void) ++{ ++ dev_t dev = MKDEV(gWmtDetectMajor, 0); ++ ++ if (pDetectDev) { ++ device_destroy(pDetectClass, dev); ++ pDetectDev = NULL; ++ } ++ ++ if (pDetectClass) { ++ class_destroy(pDetectClass); ++ pDetectClass = NULL; ++ } ++ ++ cdev_del(&gWmtDetectCdev); ++ unregister_chrdev_region(dev, WMT_DETECT_DEV_NUM); ++ ++#if !(MTK_WCN_REMOVE_KO) ++/*deinit SDIO-DETECT module*/ ++ sdio_detect_exit(); ++#endif ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ platform_driver_unregister(&wmt_detect_driver); ++#endif ++ ++ WMT_DETECT_INFO_FUNC("done\n"); ++} ++ ++module_init(wmt_detect_driver_init); ++module_exit(wmt_detect_driver_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Zhiguo.Niu & Chaozhong.Liang @ MBJ/WCNSE/SS1"); ++ ++module_param(gWmtDetectMajor, uint, 0); +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h +new file mode 100644 +index 000000000000..7e152bfd39ec +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h +@@ -0,0 +1,114 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_DETECT_H_ ++#define _WMT_DETECT_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++#define MTK_WCN_REMOVE_KO 1 ++#else ++#define MTK_WCN_REMOVE_KO 0 ++#endif ++ ++#include "sdio_detect.h" ++#include "wmt_detect_pwr.h" ++#include ++ ++#define WMT_DETECT_LOG_LOUD 4 ++#define WMT_DETECT_LOG_DBG 3 ++#define WMT_DETECT_LOG_INFO 2 ++#define WMT_DETECT_LOG_WARN 1 ++#define WMT_DETECT_LOG_ERR 0 ++ ++extern unsigned int gWmtDetectDbgLvl; ++ ++#define WMT_DETECT_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_LOUD) \ ++ pr_debug(DFT_TAG"[L]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_DETECT_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_DBG) \ ++ pr_debug(DFT_TAG"[D]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_DETECT_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_INFO) \ ++ pr_err(DFT_TAG"[I]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_DETECT_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_WARN) \ ++ pr_warn(DFT_TAG"[W]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define WMT_DETECT_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_ERR) \ ++ pr_err(DFT_TAG"[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++ ++#define WMT_IOC_MAGIC 'w' ++#define COMBO_IOCTL_GET_CHIP_ID _IOR(WMT_IOC_MAGIC, 0, int) ++#define COMBO_IOCTL_SET_CHIP_ID _IOW(WMT_IOC_MAGIC, 1, int) ++#define COMBO_IOCTL_EXT_CHIP_DETECT _IOR(WMT_IOC_MAGIC, 2, int) ++#define COMBO_IOCTL_GET_SOC_CHIP_ID _IOR(WMT_IOC_MAGIC, 3, int) ++#define COMBO_IOCTL_DO_MODULE_INIT _IOR(WMT_IOC_MAGIC, 4, int) ++#define COMBO_IOCTL_MODULE_CLEANUP _IOR(WMT_IOC_MAGIC, 5, int) ++#define COMBO_IOCTL_EXT_CHIP_PWR_ON _IOR(WMT_IOC_MAGIC, 6, int) ++#define COMBO_IOCTL_EXT_CHIP_PWR_OFF _IOR(WMT_IOC_MAGIC, 7, int) ++#define COMBO_IOCTL_DO_SDIO_AUDOK _IOR(WMT_IOC_MAGIC, 8, int) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++********************************************************************************/ ++extern int wmt_detect_ext_chip_detect(void); ++extern int wmt_detect_ext_chip_pwr_on(void); ++extern int wmt_detect_ext_chip_pwr_off(void); ++ ++#ifdef MTK_WCN_SOC_CHIP_SUPPORT ++extern unsigned int wmt_plat_get_soc_chipid(void); ++#endif ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver ++ * ++ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" ++ * @ enable - "1", enable deep idle; "0", disable deep idle ++ * ++ * Return 0 if success, else -1 ++ */ ++extern unsigned int mtk_uart_pdn_enable(char *port, int enable); ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c +new file mode 100644 +index 000000000000..1dcb7ed358bc +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c +@@ -0,0 +1,232 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-DETECT]" ++ ++#include "wmt_detect.h" ++#include "wmt_gpio.h" ++ ++#define INVALID_PIN_ID (0xFFFFFFFF) ++ ++/*copied form WMT module*/ ++static int wmt_detect_dump_pin_conf(void) ++{ ++ WMT_DETECT_DBG_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n"); ++ ++ WMT_DETECT_INFO_FUNC("LDO(GPIO%d), PMU(GPIO%d), PMUV28(GPIO%d)\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num); ++ ++ WMT_DETECT_INFO_FUNC("RST(GPIO%d), BGF_EINT(GPIO%d), BGF_EINT_NUM(%d)\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num, ++ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num)); ++ ++ WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d), WIFI_EINT_NUM(%d)\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num, ++ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)); ++ ++ WMT_DETECT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration ends<=\n"); ++ ++ return 0; ++} ++ ++int _wmt_detect_output_low(unsigned int id) ++{ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0); ++ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", ++ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); ++ } ++ ++ return 0; ++} ++ ++int _wmt_detect_output_high(unsigned int id) ++{ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1); ++ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", ++ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); ++ } ++ ++ return 0; ++} ++ ++int _wmt_detect_read_gpio_input(unsigned int id) ++{ ++ int retval = 0; ++ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { ++ retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num); ++ WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n", ++ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval); ++ } ++ ++ return retval; ++} ++ ++/*This power on sequence must support all combo chip's basic power on sequence ++ * 1. LDO control is a must, if external LDO exist ++ * 2. PMU control is a must ++ * 3. RST control is a must ++ * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup ++ * 5. RTC32k clock control is a must ++ * */ ++static int wmt_detect_chip_pwr_on(void) ++{ ++ int retval = -1; ++ /*setting validiation check*/ ++ if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) || ++ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) || ++ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) { ++ WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num); ++ ++ return retval; ++ } ++ /*set LDO/PMU/RST to output 0, no pull*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]); ++ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); ++ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); ++ ++#if 0 ++ _wmt_detect_output_high(GPIO_WIFI_EINT_PIN); ++#endif ++ ++ /*pull high LDO*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) ++ _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN); ++ /*sleep for LDO stable time*/ ++ msleep(MAX_LDO_STABLE_TIME); ++ ++ /*export RTC clock, sleep for RTC stable time*/ ++ rtc_gpio_enable_32k(RTC_GPIO_USER_GPS); ++ msleep(MAX_RTC_STABLE_TIME); ++ /*PMU output low, RST output low, to make chip power off completely*/ ++ /*always done*/ ++ /*sleep for power off stable time*/ ++ msleep(MAX_OFF_STABLE_TIME); ++ /*PMU output high, and sleep for reset stable time*/ ++ _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN); ++#ifdef CONFIG_MTK_COMBO_COMM_NPWR ++ if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) && ++ (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) { ++ msleep(20); ++ _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN); ++ ++ msleep(20); ++ _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN); ++ ++ msleep(20); ++ _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN); ++ ++ msleep(20); ++ _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN); ++ ++ msleep(20); ++ } ++#endif ++ msleep(MAX_RST_STABLE_TIME); ++ /*RST output high, and sleep for power on stable time */ ++ _wmt_detect_output_high(GPIO_COMBO_RST_PIN); ++ msleep(MAX_ON_STABLE_TIME); ++ ++ retval = 0; ++ return retval; ++} ++ ++static int wmt_detect_chip_pwr_off(void) ++{ ++ ++ /*set RST pin to input low status*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); ++ /*set RST pin to input low status*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); ++ /*set PMU pin to input low status*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); ++ return 0; ++} ++ ++int wmt_detect_read_ext_cmb_status(void) ++{ ++ int retval = 0; ++ /*read WIFI_EINT pin status*/ ++ if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) { ++ retval = 0; ++ WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n"); ++ } else { ++ retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN); ++ WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval); ++ } ++ return retval; ++} ++ ++int wmt_detect_chip_pwr_ctrl(int on) ++{ ++ int retval = -1; ++ ++ if (0 == on) { ++ /*power off combo chip */ ++ retval = wmt_detect_chip_pwr_off(); ++ } else { ++ wmt_detect_dump_pin_conf(); ++ /*power on combo chip */ ++ retval = wmt_detect_chip_pwr_on(); ++ } ++ return retval; ++} ++ ++int wmt_detect_sdio_pwr_ctrl(int on) ++{ ++ int retval = -1; ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ if (0 == on) { ++ /*power off SDIO slot */ ++ retval = board_sdio_ctrl(1, 0); ++ } else { ++ /*power on SDIO slot */ ++ retval = board_sdio_ctrl(1, 1); ++ } ++#else ++ WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n"); ++#endif ++ return retval; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h +new file mode 100644 +index 000000000000..32e661520fd0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h +@@ -0,0 +1,29 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef __WMT_DETECT_PWR_H_ ++#define __WMT_DETECT_PWR_H_ ++ ++#define MAX_RTC_STABLE_TIME 100 ++#define MAX_LDO_STABLE_TIME 100 ++#define MAX_RST_STABLE_TIME 30 ++#define MAX_OFF_STABLE_TIME 10 ++#define MAX_ON_STABLE_TIME 30 ++ ++extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); ++extern int wmt_detect_chip_pwr_ctrl(int on); ++extern int wmt_detect_sdio_pwr_ctrl(int on); ++extern int wmt_detect_read_ext_cmb_status(void); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c +new file mode 100644 +index 000000000000..3a79e1e9d15a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c +@@ -0,0 +1,371 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include "wmt_gpio.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX] = {{"gpio_ldo_en_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_ldo_en_in_pulldown", ++ ""}, ++ {"gpio_pmuv28_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_pmuv28_in_pulldown", ++ ""}, ++ {"gpio_pmu_en_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_pmu_en_in_pulldown", ++ ""}, ++ {"gpio_rst_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_bgf_eint_in_pulldown", ++ "gpio_bgf_eint_in_pullup"}, ++ {"", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_wifi_eint_in_pull_dis", ++ "", ++ "gpio_wifi_eint_in_pullup"}, ++ {"", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_all_eint_in_pulldown", ++ "gpio_all_eint_in_pullup"}, ++ {"gpio_urxd_uart_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_urxd_gpio_in_pull_dis", ++ "", ++ "gpio_urxd_gpio_in_pullup"}, ++ {"gpio_utxd_uart_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daiclk_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daipcmin_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daipcmout_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daisync_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_i2s_ck_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_i2s_ws_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_i2s_dat_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_gps_sync_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_gps_lna_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""} ++}; ++ ++const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX] = {"gpio_combo_ldo_en_pin", ++ "gpio_combo_pmuv28_en_pin", ++ "gpio_combo_pmu_en_pin", ++ "gpio_combo_rst_pin", ++ "gpio_combo_bgf_eint_pin", ++ "gpio_wifi_eint_pin", ++ "gpio_all_eint_pin", ++ "gpio_combo_urxd_pin", ++ "gpio_combo_utxd_pin", ++ "gpio_pcm_daiclk_pin", ++ "gpio_pcm_daipcmin_pin", ++ "gpio_pcm_daipcmout_pin", ++ "gpio_pcm_daisync_pin", ++ "gpio_combo_i2s_ck_pin", ++ "gpio_combo_i2s_ws_pin", ++ "gpio_combo_i2s_dat_pin", ++ "gpio_gps_sync_pin", ++ "gpio_gps_lna_pin"}; ++ ++GPIO_CTRL_INFO gpio_ctrl_info; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_gpio_init(struct platform_device *pdev) ++{ ++ INT32 iret = 0; ++ UINT32 i, j; ++ struct device_node *node; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); ++ if (!node) { ++ for (i = 0; i < GPIO_PIN_ID_MAX; i++) ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; ++ pr_err("wmt_gpio:can't find device tree node!\n"); ++ iret = -1; ++ goto err; ++ } ++ ++ gpio_ctrl_info.pinctrl_info = devm_pinctrl_get(&pdev->dev); ++ if (gpio_ctrl_info.pinctrl_info) { ++ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = of_get_named_gpio(node, ++ gpio_pin_name[i], 0); ++ if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num < 0) ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { ++ for (j = 0; j < GPIO_STATE_MAX; j++) { ++ if (0 != strlen(gpio_state_name[i][j])) { ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = ++ pinctrl_lookup_state(gpio_ctrl_info.pinctrl_info, ++ gpio_state_name[i][j]); ++ } else ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; ++ } ++ } ++ } ++ ++ pr_err("wmt_gpio: gpio init start!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, ++ 0); ++ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN out to 0: %d!\n", ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); ++ } ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, ++ 0); ++ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN out to 0: %d!\n", ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); ++ } ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); ++ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ pr_err("wmt_gpio: gpio init done!\n"); ++ } else { ++ pr_err("wmt_gpio:can't find pinctrl dev!\n"); ++ iret = -1; ++ } ++err: ++ return iret; ++} ++ ++INT32 wmt_gpio_deinit(VOID) ++{ ++ INT32 iret = 0; ++ UINT32 i; ++ UINT32 j; ++ ++ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { ++ for (j = 0; j < GPIO_STATE_MAX; j++) { ++ if (0 != strlen(gpio_state_name[i][j])) ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; ++ } ++ } ++ } ++ if (gpio_ctrl_info.pinctrl_info) { ++ devm_pinctrl_put(gpio_ctrl_info.pinctrl_info); ++ gpio_ctrl_info.pinctrl_info = NULL; ++ } ++ ++ return iret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h +new file mode 100644 +index 000000000000..cd935bfddd99 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h +@@ -0,0 +1,103 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_GPIO_H_ ++#define _WMT_GPIO_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "osal.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define DEFAULT_PIN_ID (0xffffffff) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_GPIO_PIN_ID { ++ GPIO_COMBO_LDO_EN_PIN = 0, ++ GPIO_COMBO_PMUV28_EN_PIN, ++ GPIO_COMBO_PMU_EN_PIN, ++ GPIO_COMBO_RST_PIN, ++ GPIO_COMBO_BGF_EINT_PIN, ++ GPIO_WIFI_EINT_PIN, ++ GPIO_COMBO_ALL_EINT_PIN, ++ GPIO_COMBO_URXD_PIN, ++ GPIO_COMBO_UTXD_PIN, ++ GPIO_PCM_DAICLK_PIN, ++ GPIO_PCM_DAIPCMIN_PIN, ++ GPIO_PCM_DAIPCMOUT_PIN, ++ GPIO_PCM_DAISYNC_PIN, ++ GPIO_COMBO_I2S_CK_PIN, ++ GPIO_COMBO_I2S_WS_PIN, ++ GPIO_COMBO_I2S_DAT_PIN, ++ GPIO_GPS_SYNC_PIN, ++ GPIO_GPS_LNA_PIN, ++ GPIO_PIN_ID_MAX ++} ENUM_GPIO_PIN_ID, *P_ENUM_GPIO_PIN_ID; ++ ++typedef enum _ENUM_GPIO_STATE_ID { ++ GPIO_PULL_DIS = 0, ++ GPIO_PULL_DOWN, ++ GPIO_PULL_UP, ++ GPIO_OUT_LOW, ++ GPIO_OUT_HIGH, ++ GPIO_IN_DIS, ++ GPIO_IN_EN, ++ GPIO_IN_PULL_DIS, ++ GPIO_IN_PULLDOWN, ++ GPIO_IN_PULLUP, ++ GPIO_STATE_MAX, ++} ENUM_GPIO_STATE_ID, *P_ENUM_GPIO_STATE_ID; ++ ++typedef struct _GPIO_CTRL_STATE { ++ INT32 gpio_num; ++ struct pinctrl_state *gpio_state[GPIO_STATE_MAX]; ++} GPIO_CTRL_STATE, *P_GPIO_CTRL_STATE; ++ ++typedef struct _GPIO_CTRL_INFO { ++ struct pinctrl *pinctrl_info; ++ GPIO_CTRL_STATE gpio_ctrl_state[GPIO_PIN_ID_MAX]; ++} GPIO_CTRL_INFO, *P_GPIO_CTRL_INFO; ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX]; ++extern const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX]; ++extern GPIO_CTRL_INFO gpio_ctrl_info; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_gpio_init(struct platform_device *pdev); ++ ++INT32 wmt_gpio_deinit(VOID); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c +new file mode 100644 +index 000000000000..4fc3144b3ba6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c +@@ -0,0 +1,480 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include "osal_typedef.h" ++#include "wmt_stp_exp.h" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-STP-EXP]" ++ ++#define WMT_STP_EXP_INFO_FUNC(fmt, arg...) pr_debug(DFT_TAG "[I]%s: " fmt, __func__ , ##arg) ++#define WMT_STP_EXP_WARN_FUNC(fmt, arg...) pr_warn(DFT_TAG "[W]%s: " fmt, __func__ , ##arg) ++#define WMT_STP_EXP_ERR_FUNC(fmt, arg...) pr_err(DFT_TAG "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++/*STP exp*/ ++MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_f = NULL; ++MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_raw_f = NULL; ++MTK_WCN_STP_PARSER_DATA mtk_wcn_stp_parser_data_f = NULL; ++MTK_WCN_STP_RECV_DATA mtk_wcn_stp_receive_data_f = NULL; ++MTK_WCN_STP_IS_RXQ_EMPTY mtk_wcn_stp_is_rxqueue_empty_f = NULL; ++MTK_WCN_STP_IS_RDY mtk_wcn_stp_is_ready_f = NULL; ++MTK_WCN_STP_SET_BLUEZ mtk_wcn_stp_set_bluez_f = NULL; ++MTK_WCN_STP_REG_IF_TX mtk_wcn_stp_if_tx_f = NULL; ++MTK_WCN_STP_REG_IF_RX mtk_wcn_stp_if_rx_f = NULL; ++MTK_WCN_STP_REG_EVENT_CB mtk_wcn_stp_reg_event_cb_f = NULL; ++MTK_WCN_STP_RGE_TX_EVENT_CB mtk_wcn_stp_reg_tx_event_cb_f = NULL; ++MTK_WCN_STP_COREDUMP_START_GET mtk_wcn_stp_coredump_start_get_f = NULL; ++ ++/*WMT exp*/ ++MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_on_f = NULL; ++MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_off_f = NULL; ++MTK_WCN_WMT_THERM_CTRL mtk_wcn_wmt_therm_ctrl_f = NULL; ++MTK_WCN_WMT_HWVER_GET mtk_wcn_wmt_hwver_get_f = NULL; ++MTK_WCN_WMT_DSNS_CTRL mtk_wcn_wmt_dsns_ctrl_f = NULL; ++MTK_WCN_WMT_MSGCB_REG mtk_wcn_wmt_msgcb_reg_f = NULL; ++MTK_WCN_WMT_MSGCB_UNREG mtk_wcn_wmt_msgcb_unreg_f = NULL; ++MTK_WCN_WMT_SDIO_OP_REG mtk_wcn_wmt_sdio_op_reg_f = NULL; ++MTK_WCN_WMT_SDIO_HOST_AWAKE mtk_wcn_wmt_sdio_host_awake_f = NULL; ++MTK_WCN_WMT_ASSERT mtk_wcn_wmt_assert_f = NULL; ++MTK_WCN_WMT_ASSERT_TIMEOUT mtk_wcn_wmt_assert_timeout_f = NULL; ++MTK_WCN_WMT_IC_INFO_GET mtk_wcn_wmt_ic_info_get_f = NULL; ++MTK_WCN_WMT_PSM_CTRL mtk_wcn_wmt_psm_ctrl_f = NULL; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb) ++{ ++ WMT_STP_EXP_INFO_FUNC("call stp exp cb reg\n"); ++ ++ mtk_wcn_stp_send_data_f = pStpExpCb->stp_send_data_cb; ++ mtk_wcn_stp_send_data_raw_f = pStpExpCb->stp_send_data_raw_cb; ++ mtk_wcn_stp_parser_data_f = pStpExpCb->stp_parser_data_cb; ++ mtk_wcn_stp_receive_data_f = pStpExpCb->stp_receive_data_cb; ++ mtk_wcn_stp_is_rxqueue_empty_f = pStpExpCb->stp_is_rxqueue_empty_cb; ++ mtk_wcn_stp_is_ready_f = pStpExpCb->stp_is_ready_cb; ++ mtk_wcn_stp_set_bluez_f = pStpExpCb->stp_set_bluez_cb; ++ mtk_wcn_stp_if_tx_f = pStpExpCb->stp_if_tx_cb; ++ mtk_wcn_stp_if_rx_f = pStpExpCb->stp_if_rx_cb; ++ mtk_wcn_stp_reg_event_cb_f = pStpExpCb->stp_reg_event_cb; ++ mtk_wcn_stp_reg_tx_event_cb_f = pStpExpCb->stp_reg_tx_event_cb; ++ mtk_wcn_stp_coredump_start_get_f = pStpExpCb->stp_coredump_start_get_cb; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_reg); ++ ++UINT32 mtk_wcn_stp_exp_cb_unreg(VOID) ++{ ++ WMT_STP_EXP_INFO_FUNC("call stp exp cb unreg\n"); ++ ++ mtk_wcn_stp_send_data_f = NULL; ++ mtk_wcn_stp_send_data_raw_f = NULL; ++ mtk_wcn_stp_parser_data_f = NULL; ++ mtk_wcn_stp_receive_data_f = NULL; ++ mtk_wcn_stp_is_rxqueue_empty_f = NULL; ++ mtk_wcn_stp_is_ready_f = NULL; ++ mtk_wcn_stp_set_bluez_f = NULL; ++ mtk_wcn_stp_if_tx_f = NULL; ++ mtk_wcn_stp_if_rx_f = NULL; ++ mtk_wcn_stp_reg_event_cb_f = NULL; ++ mtk_wcn_stp_reg_tx_event_cb_f = NULL; ++ mtk_wcn_stp_coredump_start_get_f = NULL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_unreg); ++ ++INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_send_data_f) { ++ ret = (*mtk_wcn_stp_send_data_f) (buffer, length, type); ++ /* WMT_STP_EXP_INFO_FUNC("mtk_wcn_stp_send_data_f send data(%d)\n",ret); */ ++ } else { ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_f cb is null\n"); ++ } ++ ++ return ret; ++ ++} ++EXPORT_SYMBOL(mtk_wcn_stp_send_data); ++ ++INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_send_data_raw_f) ++ ret = (*mtk_wcn_stp_send_data_raw_f) (buffer, length, type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_raw_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); ++ ++INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_parser_data_f) ++ ret = (*mtk_wcn_stp_parser_data_f) (buffer, length); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_parser_data_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_parser_data); ++ ++INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_receive_data_f) ++ ret = (*mtk_wcn_stp_receive_data_f) (buffer, length, type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_receive_data_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_receive_data); ++ ++MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_stp_is_rxqueue_empty_f) ++ ret = (*mtk_wcn_stp_is_rxqueue_empty_f) (type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_rxqueue_empty_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); ++ ++MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_stp_is_ready_f) ++ ret = (*mtk_wcn_stp_is_ready_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_ready_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_is_ready); ++ ++void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags) ++{ ++ ++ if (mtk_wcn_stp_set_bluez_f) ++ (*mtk_wcn_stp_set_bluez_f) (flags); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_set_bluez_f cb is null\n"); ++ ++} ++EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); ++ ++INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_if_tx_f) ++ ret = (*mtk_wcn_stp_if_tx_f) (stp_if, func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_tx_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); ++ ++INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_if_rx_f) ++ ret = (*mtk_wcn_stp_if_rx_f) (func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_rx_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); ++ ++INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_reg_event_cb_f) ++ ret = (*mtk_wcn_stp_reg_event_cb_f) (type, func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_event_cb_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); ++ ++INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_reg_tx_event_cb_f) ++ ret = (*mtk_wcn_stp_reg_tx_event_cb_f) (type, func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_tx_event_cb_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); ++ ++INT32 mtk_wcn_stp_coredump_start_get(VOID) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_coredump_start_get_f) ++ ret = (*mtk_wcn_stp_coredump_start_get_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_coredump_start_get_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_coredump_start_get); ++ ++UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb) ++{ ++ WMT_STP_EXP_INFO_FUNC("call wmt exp cb reg\n"); ++ ++ mtk_wcn_wmt_func_on_f = pWmtExpCb->wmt_func_on_cb; ++ mtk_wcn_wmt_func_off_f = pWmtExpCb->wmt_func_off_cb; ++ mtk_wcn_wmt_therm_ctrl_f = pWmtExpCb->wmt_therm_ctrl_cb; ++ mtk_wcn_wmt_hwver_get_f = pWmtExpCb->wmt_hwver_get_cb; ++ mtk_wcn_wmt_dsns_ctrl_f = pWmtExpCb->wmt_dsns_ctrl_cb; ++ mtk_wcn_wmt_msgcb_reg_f = pWmtExpCb->wmt_msgcb_reg_cb; ++ mtk_wcn_wmt_msgcb_unreg_f = pWmtExpCb->wmt_msgcb_unreg_cb; ++ mtk_wcn_wmt_sdio_op_reg_f = pWmtExpCb->wmt_sdio_op_reg_cb; ++ mtk_wcn_wmt_sdio_host_awake_f = pWmtExpCb->wmt_sdio_host_awake_cb; ++ mtk_wcn_wmt_assert_f = pWmtExpCb->wmt_assert_cb; ++ mtk_wcn_wmt_assert_timeout_f = pWmtExpCb->wmt_assert_timeout_cb; ++ mtk_wcn_wmt_ic_info_get_f = pWmtExpCb->wmt_ic_info_get_cb; ++ mtk_wcn_wmt_psm_ctrl_f = pWmtExpCb->wmt_psm_ctrl_cb; ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_reg); ++ ++UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID) ++{ ++ WMT_STP_EXP_INFO_FUNC("call wmt exp cb unreg\n"); ++ ++ mtk_wcn_wmt_func_on_f = NULL; ++ mtk_wcn_wmt_func_off_f = NULL; ++ mtk_wcn_wmt_therm_ctrl_f = NULL; ++ mtk_wcn_wmt_hwver_get_f = NULL; ++ mtk_wcn_wmt_dsns_ctrl_f = NULL; ++ mtk_wcn_wmt_msgcb_reg_f = NULL; ++ mtk_wcn_wmt_msgcb_unreg_f = NULL; ++ mtk_wcn_wmt_sdio_op_reg_f = NULL; ++ mtk_wcn_wmt_sdio_host_awake_f = NULL; ++ mtk_wcn_wmt_assert_f = NULL; ++ mtk_wcn_wmt_assert_timeout_f = NULL; ++ mtk_wcn_wmt_ic_info_get_f = NULL; ++ mtk_wcn_wmt_psm_ctrl_f = NULL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_unreg); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_func_off_f) ++ ret = (*mtk_wcn_wmt_func_off_f) (type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_off_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_func_off); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_func_on_f) { ++ ret = (*mtk_wcn_wmt_func_on_f) (type); ++ WMT_STP_EXP_INFO_FUNC("mtk_wcn_wmt_func_on_f type(%d)\n", type); ++ } else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_on_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_func_on); ++ ++INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_wmt_therm_ctrl_f) ++ ret = (*mtk_wcn_wmt_therm_ctrl_f) (eType); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_therm_ctrl_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); ++ ++ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) ++{ ++ ENUM_WMTHWVER_TYPE_T ret = WMTHWVER_INVALID; ++ ++ if (mtk_wcn_wmt_hwver_get_f) ++ ret = (*mtk_wcn_wmt_hwver_get_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_hwver_get_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_dsns_ctrl_f) ++ ret = (*mtk_wcn_wmt_dsns_ctrl_f) (eType); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_dsns_ctrl_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); ++ ++INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++{ ++ INT32 ret = 0; ++ ++ if (mtk_wcn_wmt_msgcb_reg_f) ++ ret = (*mtk_wcn_wmt_msgcb_reg_f) (eType, pCb); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_reg_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); ++ ++INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++{ ++ INT32 ret = 0; ++ ++ if (mtk_wcn_wmt_msgcb_unreg_f) ++ ret = (*mtk_wcn_wmt_msgcb_unreg_f) (eType); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_unreg_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); ++ ++INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_wmt_sdio_op_reg_f) ++ ret = (*mtk_wcn_wmt_sdio_op_reg_f) (own_cb); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_op_reg_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); ++ ++INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_wmt_sdio_host_awake_f) ++ ret = (*mtk_wcn_wmt_sdio_host_awake_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_host_awake_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_assert_f) ++ ret = (*mtk_wcn_wmt_assert_f) (type, reason); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_assert); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_assert_timeout_f) ++ ret = (*mtk_wcn_wmt_assert_timeout_f)(type, reason, timeout); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_timeout_f cb is null\n"); ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_assert_timeout); ++ ++UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type) ++{ ++ UINT32 ret = 0; ++ ++ if (mtk_wcn_wmt_ic_info_get_f) ++ ret = (*mtk_wcn_wmt_ic_info_get_f) (type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_ic_info_get_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_ic_info_get); ++ ++INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag) ++{ ++ UINT32 ret = 0; ++ ++ if (mtk_wcn_wmt_psm_ctrl_f) ++ ret = (*mtk_wcn_wmt_psm_ctrl_f)(flag); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_psm_ctrl_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_psm_ctrl); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h +new file mode 100644 +index 000000000000..1c3dc8965298 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h +@@ -0,0 +1,610 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_STP_EXP_H_ ++#define _WMT_STP_EXP_H_ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "osal_typedef.h" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 ++#endif ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++#if (WMT_IDC_SUPPORT) ++#define CFG_WMT_LTE_COEX_HANDLING 1 ++#define CFG_WMT_LTE_ENABLE_MSGID_MAPPING 0 ++#else ++#define CFG_WMT_LTE_COEX_HANDLING 0 ++#endif ++ ++/*from stp_exp.h*/ ++#define BT_TASK_INDX (0) ++#define FM_TASK_INDX (1) ++#define GPS_TASK_INDX (2) ++#define WIFI_TASK_INDX (3) ++#define WMT_TASK_INDX (4) ++#define STP_TASK_INDX (5) ++#define INFO_TASK_INDX (6) ++#define ANT_TASK_INDX (7) ++#if CFG_WMT_LTE_COEX_HANDLING ++#define COEX_TASK_INDX (8) ++#define MTKSTP_MAX_TASK_NUM (9) ++#else ++#define MTKSTP_MAX_TASK_NUM (8) ++#endif ++ ++#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ ++/*end from stp_exp.h*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++********************************************************************************/ ++ ++/*moved from stp_exp.h*/ ++typedef void (*MTK_WCN_STP_EVENT_CB) (void); ++typedef INT32(*MTK_WCN_STP_IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); ++/* export for HIF driver */ ++typedef void (*MTK_WCN_STP_IF_RX) (const PUINT8 data, INT32 size); ++ ++typedef enum { ++ STP_UART_IF_TX = 0, ++ STP_SDIO_IF_TX = 1, ++ STP_BTIF_IF_TX = 2, ++ STP_MAX_IF_TX ++} ENUM_STP_TX_IF_TYPE; ++ ++/*end moved from stp_exp.h*/ ++ ++typedef INT32(*MTK_WCN_STP_SEND_DATA) (const PUINT8 buffer, const UINT32 length, const UINT8 type); ++typedef INT32(*MTK_WCN_STP_PARSER_DATA) (PUINT8 buffer, UINT32 length); ++typedef INT32(*MTK_WCN_STP_RECV_DATA) (PUINT8 buffer, UINT32 length, UINT8 type); ++typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RXQ_EMPTY) (UINT8 type); ++typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RDY) (VOID); ++typedef VOID(*MTK_WCN_STP_SET_BLUEZ) (MTK_WCN_BOOL flags); ++typedef INT32(*MTK_WCN_STP_REG_IF_TX) (ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++typedef INT32(*MTK_WCN_STP_REG_IF_RX) (MTK_WCN_STP_IF_RX func); ++typedef INT32(*MTK_WCN_STP_REG_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); ++typedef INT32(*MTK_WCN_STP_RGE_TX_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); ++typedef INT32(*MTK_WCN_STP_COREDUMP_START_GET)(VOID); ++ ++typedef struct _MTK_WCN_STP_EXP_CB_INFO_ { ++ MTK_WCN_STP_SEND_DATA stp_send_data_cb; ++ MTK_WCN_STP_SEND_DATA stp_send_data_raw_cb; ++ MTK_WCN_STP_PARSER_DATA stp_parser_data_cb; ++ MTK_WCN_STP_RECV_DATA stp_receive_data_cb; ++ MTK_WCN_STP_IS_RXQ_EMPTY stp_is_rxqueue_empty_cb; ++ MTK_WCN_STP_IS_RDY stp_is_ready_cb; ++ MTK_WCN_STP_SET_BLUEZ stp_set_bluez_cb; ++ MTK_WCN_STP_REG_IF_TX stp_if_tx_cb; ++ MTK_WCN_STP_REG_IF_RX stp_if_rx_cb; ++ MTK_WCN_STP_REG_EVENT_CB stp_reg_event_cb; ++ MTK_WCN_STP_RGE_TX_EVENT_CB stp_reg_tx_event_cb; ++ MTK_WCN_STP_COREDUMP_START_GET stp_coredump_start_get_cb; ++} MTK_WCN_STP_EXP_CB_INFO, *P_MTK_WCN_STP_EXP_CB_INFO; ++ ++/*moved from wmt_exp.h*/ ++ ++typedef enum _ENUM_WMTDRV_TYPE_T { ++ WMTDRV_TYPE_BT = 0, ++ WMTDRV_TYPE_FM = 1, ++ WMTDRV_TYPE_GPS = 2, ++ WMTDRV_TYPE_WIFI = 3, ++ WMTDRV_TYPE_WMT = 4, ++ WMTDRV_TYPE_ANT = 5, ++ WMTDRV_TYPE_STP = 6, ++ WMTDRV_TYPE_SDIO1 = 7, ++ WMTDRV_TYPE_SDIO2 = 8, ++ WMTDRV_TYPE_LPBK = 9, ++ WMTDRV_TYPE_COREDUMP = 10, ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ WMTDRV_TYPE_AUTOK = 11, ++#endif ++ WMTDRV_TYPE_MAX ++} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; ++ ++typedef enum _ENUM_WMTDSNS_TYPE_T { ++ WMTDSNS_FM_DISABLE = 0, ++ WMTDSNS_FM_ENABLE = 1, ++ WMTDSNS_FM_GPS_DISABLE = 2, ++ WMTDSNS_FM_GPS_ENABLE = 3, ++ WMTDSNS_MAX ++} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; ++ ++typedef enum _ENUM_WMTHWVER_TYPE_T { ++ WMTHWVER_E1 = 0x0, ++ WMTHWVER_E2 = 0x1, ++ WMTHWVER_E3 = 0x2, ++ WMTHWVER_E4 = 0x3, ++ WMTHWVER_E5 = 0x4, ++ WMTHWVER_E6 = 0x5, ++ WMTHWVER_E7 = 0x6, ++ WMTHWVER_MAX, ++ WMTHWVER_INVALID = 0xff ++} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; ++ ++typedef enum _ENUM_WMTTHERM_TYPE_T { ++ WMTTHERM_ZERO = 0, ++ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, ++ WMTTHERM_READ = WMTTHERM_ENABLE + 1, ++ WMTTHERM_DISABLE = WMTTHERM_READ + 1, ++ WMTTHERM_MAX ++} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; ++ ++typedef enum _ENUM_WMTMSG_TYPE_T { ++ WMTMSG_TYPE_POWER_ON = 0, ++ WMTMSG_TYPE_POWER_OFF = 1, ++ WMTMSG_TYPE_RESET = 2, ++ WMTMSG_TYPE_STP_RDY = 3, ++ WMTMSG_TYPE_HW_FUNC_ON = 4, ++ WMTMSG_TYPE_MAX ++} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; ++ ++typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ ++ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ ++ ENUM_WMTMSG_TYPE_T, /* Message type */ ++ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client ++ can't touch this buffer after this function return. */ ++ UINT32 /* Buffer size in unit of byte */ ++); ++ ++typedef enum _SDIO_PS_OP { ++ OWN_SET = 0, ++ OWN_CLR = 1, ++ OWN_STATE = 2, ++} SDIO_PS_OP; ++ ++typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); ++ ++typedef enum _ENUM_WMTCHIN_TYPE_T { ++ WMTCHIN_CHIPID = 0x0, ++ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, ++ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, ++ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, ++ WMTCHIN_MAX, ++ ++} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; ++ ++/*end moved from wmt_exp.h*/ ++ ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_FUNC_CTRL) (ENUM_WMTDRV_TYPE_T type); ++typedef INT8(*MTK_WCN_WMT_THERM_CTRL) (ENUM_WMTTHERM_TYPE_T eType); ++typedef ENUM_WMTHWVER_TYPE_T(*MTK_WCN_WMT_HWVER_GET) (VOID); ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_DSNS_CTRL) (ENUM_WMTDSNS_TYPE_T eType); ++typedef INT32(*MTK_WCN_WMT_MSGCB_REG) (ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++typedef INT32(*MTK_WCN_WMT_MSGCB_UNREG) (ENUM_WMTDRV_TYPE_T eType); ++typedef INT32(*MTK_WCN_WMT_SDIO_OP_REG) (PF_WMT_SDIO_PSOP own_cb); ++typedef INT32(*MTK_WCN_WMT_SDIO_HOST_AWAKE) (VOID); ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT) (ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT_TIMEOUT)(ENUM_WMTDRV_TYPE_T type, ++ UINT32 reason, INT32 timeout); ++typedef UINT32(*MTK_WCN_WMT_IC_INFO_GET) (ENUM_WMT_CHIPINFO_TYPE_T type); ++typedef INT32 (*MTK_WCN_WMT_PSM_CTRL)(MTK_WCN_BOOL flag); ++ ++typedef struct _MTK_WCN_WMT_EXP_CB_INFO_ { ++ MTK_WCN_WMT_FUNC_CTRL wmt_func_on_cb; ++ MTK_WCN_WMT_FUNC_CTRL wmt_func_off_cb; ++ MTK_WCN_WMT_THERM_CTRL wmt_therm_ctrl_cb; ++ MTK_WCN_WMT_HWVER_GET wmt_hwver_get_cb; ++ MTK_WCN_WMT_DSNS_CTRL wmt_dsns_ctrl_cb; ++ MTK_WCN_WMT_MSGCB_REG wmt_msgcb_reg_cb; ++ MTK_WCN_WMT_MSGCB_UNREG wmt_msgcb_unreg_cb; ++ MTK_WCN_WMT_SDIO_OP_REG wmt_sdio_op_reg_cb; ++ MTK_WCN_WMT_SDIO_HOST_AWAKE wmt_sdio_host_awake_cb; ++ MTK_WCN_WMT_ASSERT wmt_assert_cb; ++ MTK_WCN_WMT_ASSERT_TIMEOUT wmt_assert_timeout_cb; ++ MTK_WCN_WMT_IC_INFO_GET wmt_ic_info_get_cb; ++ MTK_WCN_WMT_PSM_CTRL wmt_psm_ctrl_cb; ++} MTK_WCN_WMT_EXP_CB_INFO, *P_MTK_WCN_WMT_EXP_CB_INFO; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*exp for WMT/STP register callback*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_exp_cb_reg ++* DESCRIPTION ++* stp driver reigster exp symbols ++* PARAMETERS ++* pStpExpCb [IN] stp callback structure pointer ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_exp_cb_unreg ++* DESCRIPTION ++* stp driver unreigster exp symbols ++* PARAMETERS ++* VOID ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_stp_exp_cb_unreg(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_exp_cb_reg ++* DESCRIPTION ++* WMT driver reigster exp symbols ++* PARAMETERS ++* pStpExpCb [IN] wmt callback structure pointer ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_exp_cb_unreg ++* DESCRIPTION ++* wmt driver unreigster exp symbols ++* PARAMETERS ++* VOID ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID); ++ ++/*stp exp symbols*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data ++* DESCRIPTION ++* subfunction send data through STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data_raw ++* DESCRIPTION ++* subfunction send data through STP without seq/ack ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_parser_data ++* DESCRIPTION ++* push data to serial transport protocol parser engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_receive_data ++* DESCRIPTION ++* receive data from serial protocol engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* INT32 >= 0: size of data received; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_rxqueue_empty ++* DESCRIPTION ++* Is certain rx queue empty? ++* PARAMETERS ++* type [IN] subfunction type ++* RETURNS ++* INT32 0: queue is NOT empyt; !0: queue is empty ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_enable ++* DESCRIPTION ++* Is STP ready? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:ready, FALSE:not ready ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); ++ ++/***************************************************************************** ++* FUNCTION ++* set_bluetooth_rx_interface ++* DESCRIPTION ++* Set bluetooth rx interface ++* PARAMETERS ++* rx interface type ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_tx ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_rx ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_event_cb ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_tx_event_cb ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_get ++* DESCRIPTION ++* get coredump flag is set or not ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32: 0:coredump flag is not set , 1: coredump flag is set ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_coredump_start_get(VOID); ++ ++/*wmt exp symbols*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_func_off ++* DESCRIPTION ++* wmt turn off subsystem ++* PARAMETERS ++* type [IN] subsystem type ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_func_on ++* DESCRIPTION ++* wmt turn on subsystem ++* PARAMETERS ++* type [IN] subsystem type ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_therm_ctrl ++* DESCRIPTION ++* query chip temperature by WMT CMD ++* PARAMETERS ++* eType [IN] thermal ctrl type ++* RETURNS ++* >=0: chip temperature; 0xff:error ++*****************************************************************************/ ++extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_hwver_get ++* DESCRIPTION ++* get chip hardware version ++* PARAMETERS ++* VOID ++* RETURNS ++* >=0: chip hw version; 0xff:error ++*****************************************************************************/ ++extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_ic_info_get ++* DESCRIPTION ++* get chip hardware version or f/w version ++* PARAMETERS ++* type : which kind of information is needed ++* RETURNS ++* f/w version or hw version information ++*****************************************************************************/ ++extern UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_dsns_ctrl ++* DESCRIPTION ++* fm dsns cmd ctrl ++* PARAMETERS ++* eType [IN] fm dsns ctrl type ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_msgcb_reg ++* DESCRIPTION ++* used for subsystem register chip reset callback for received wmt reset msg. ++* PARAMETERS ++* eType [IN] subsystem type ++* pCb [IN] rst callback ++* RETURNS ++* 1: OK; 0:error ++*****************************************************************************/ ++extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_msgcb_unreg ++* DESCRIPTION ++* used for subsystem unregister chip reset callback for received wmt reset msg. ++* PARAMETERS ++* eType [IN] subsystem type ++* RETURNS ++* 1: OK; 0:error ++*****************************************************************************/ ++extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_wmt_sdio_op_reg ++* DESCRIPTION ++* used to register callback for set sdio ownership. ++* PARAMETERS ++* own_cb [IN] set owner ship callback ++* RETURNS ++* always return 0; ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_wmt_sdio_host_awake ++* DESCRIPTION ++* handing host awake when link is stp sdio? ++* PARAMETERS ++* VOID ++* RETURNS ++* always return 0; ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_assert ++* DESCRIPTION ++* host trigger firmware assert ++* PARAMETERS ++* type [IN] subsystem driver type ++* reason [IN] trigger assert reason ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++ ++/***************************************************************************** ++ * * FUNCTION ++ * * mtk_wcn_wmt_assert_timeout ++ * * DESCRIPTION ++ * * host trigger firmware assert ++ * * PARAMETERS ++ * * type [IN] subsystem driver type ++ * * reason [IN] trigger assert reason ++ * * timeout [IN] trigger assert timeout data ++ * * RETURNS ++ * * MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++ * *****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, ++ UINT32 reason, INT32 timeout); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_psm_ctrl ++* DESCRIPTION ++* disable/enable psm ++* PARAMETERS ++* flag [IN] disable:0, enable:1 ++* RETURNS ++* always return 0; ++*****************************************************************************/ ++extern INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag); ++ ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile +new file mode 100644 +index 000000000000..286bfd4bfed3 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile +@@ -0,0 +1,65 @@ ++subdir-ccflags-y += \ ++ -I$(src)/linux/include \ ++ -I$(src)/linux/pri/include \ ++ -I$(src)/core/include \ ++ -I$(src)/include \ ++ -I$(src)/../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/btif/common/inc ++ ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/ ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM) ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs/ ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/conn_md/include ++ ++EXT_FLAG=_soc ++COMMON_SRC_PATH := $(src) ++COMMON_OBJ_PATH := $(src) ++ ++ifeq ($(CONFIG_ARCH_MT6580), y) ++subdir-ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33 ++endif ++ ++ifeq ($(CONFIG_MTK_COMBO), m) ++# WMT DRIVER ++obj-$(CONFIG_MTK_COMBO) += mtk_stp_wmt$(EXT_FLAG).o ++# WMT DRIVER-core part ++mtk_stp_wmt$(EXT_FLAG)-objs := core/wmt_core.o core/wmt_ctrl.o core/wmt_func.o core/wmt_ic_soc.o core/wmt_lib.o core/wmt_conf.o ++ ++ ++# WMT DRIVER-linux private part ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/wmt_dev.o linux/pri/wmt_exp.o ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_btif.o ++ ++ ++# WMT DRIVER-OSAL ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pub/osal.o linux/pub/bgw_desense.o ++# WMT DRIVER-platform implementation ++# ccflags-y += -D WMT_PLAT_ALPS ++# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/wmt_plat_alps.o ++ ++# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/mtk_wcn_consys_hw.o ++ ++ ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_exp.o core/stp_core.o core/psm_core.o core/btm_core.o linux/pri/stp_dbg.o ++ ++# WMT stub part (built-in kernel image) ++# obj-y += platform/alps/mtk_wcn_consys_stub_alps.o ++ ++ ++ ++obj-$(CONFIG_MTK_COMBO_BT) += mtk_stp_bt$(EXT_FLAG).o ++mtk_stp_bt$(EXT_FLAG)-objs := linux/pub/stp_chrdev_bt.o ++ ++ ++obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi$(EXT_FLAG).o ++mtk_wmt_wifi$(EXT_FLAG)-objs := linux/pub/wmt_chrdev_wifi.o ++ ++endif ++ ++ifeq ($(CONFIG_MTK_COMBO), y) ++# subdir-ccflags-y += -D WMT_PLAT_ALPS ++obj-y += core/ ++obj-y += linux/ ++#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/ ++obj-y += mt7623/ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile +new file mode 100644 +index 000000000000..9df71b9e163e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile +@@ -0,0 +1,22 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++ccflags-y += \ ++ -I$(src)/../linux/include \ ++ -I$(src)/../linux/pri/include \ ++ -I$(src)/../core/include \ ++ -I$(src)/../include \ ++ -I$(src)/../../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ ++ ++obj-y += wmt_core.o \ ++ wmt_ctrl.o \ ++ wmt_func.o \ ++ wmt_ic_soc.o \ ++ wmt_lib.o \ ++ wmt_conf.o \ ++ btm_core.o \ ++ dbg_core.o \ ++ psm_core.o \ ++ stp_core.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c +new file mode 100644 +index 000000000000..4946b682d826 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c +@@ -0,0 +1,1376 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_dbg.h" ++#include "stp_core.h" ++#include "btm_core.h" ++#include "wmt_plat.h" ++ ++#define PFX_BTM "[STP-BTM] " ++#define STP_BTM_LOG_LOUD 4 ++#define STP_BTM_LOG_DBG 3 ++#define STP_BTM_LOG_INFO 2 ++#define STP_BTM_LOG_WARN 1 ++#define STP_BTM_LOG_ERR 0 ++ ++INT32 gBtmDbgLevel = STP_BTM_LOG_INFO; ++ ++#define STP_BTM_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_LOUD) \ ++ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ ++ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_INFO) \ ++ pr_debug(PFX_BTM "[I]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_WARN) \ ++ pr_warn(PFX_BTM "[W]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_ERR) \ ++ pr_err(PFX_BTM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define STP_BTM_TRC_FUNC(f) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ ++ pr_debug(PFX_BTM "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++#define ASSERT(expr) ++ ++MTKSTP_BTM_T stp_btm_i; ++MTKSTP_BTM_T *stp_btm = &stp_btm_i; ++ ++const char *g_btm_op_name[] = { ++ "STP_OPID_BTM_RETRY", ++ "STP_OPID_BTM_RST", ++ "STP_OPID_BTM_DBG_DUMP", ++ "STP_OPID_BTM_DUMP_TIMEOUT", ++ "STP_OPID_BTM_POLL_CPUPCR", ++ "STP_OPID_BTM_PAGED_DUMP", ++ "STP_OPID_BTM_FULL_DUMP", ++ "STP_OPID_BTM_PAGED_TRACE", ++ "STP_OPID_BTM_FORCE_FW_ASSERT", ++#if CFG_WMT_LTE_COEX_HANDLING ++ "STP_OPID_BTM_WMT_LTE_COEX", ++#endif ++ "STP_OPID_BTM_EXIT" ++}; ++ ++#if 0 ++static char *_stp_pkt_type(int type) ++{ ++ ++ static char s[10]; ++ ++ switch (type) { ++ case WMT_TASK_INDX: ++ osal_memcpy(s, "WMT", strlen("WMT") + 1); ++ break; ++ case BT_TASK_INDX: ++ osal_memcpy(s, "BT", strlen("BT") + 1); ++ break; ++ case GPS_TASK_INDX: ++ osal_memcpy(s, "GPS", strlen("GPS") + 1); ++ break; ++ case FM_TASK_INDX: ++ osal_memcpy(s, "FM", strlen("FM") + 1); ++ break; ++ default: ++ osal_memcpy(s, "UNKNOWN", strlen("UNKNOWN") + 1); ++ break; ++ } ++ ++ return s; ++} ++#endif ++ ++static INT32 _stp_btm_put_dump_to_nl(void) ++{ ++#define NUM_FETCH_ENTRY 8 ++ ++ static UINT8 buf[2048]; ++ static UINT8 tmp[2048]; ++ ++ UINT32 buf_len; ++ STP_PACKET_T *pkt; ++ STP_DBG_HDR_T *hdr; ++ INT32 len; ++ INT32 remain = 0, index = 0; ++ INT32 retry = 0, rc = 0, nl_retry = 0; ++ ++ STP_BTM_INFO_FUNC("Enter..\n"); ++ ++ index = 0; ++ tmp[index++] = '['; ++ tmp[index++] = 'M'; ++ tmp[index++] = ']'; ++ ++ do { ++ index = 3; ++ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); ++ if (buf_len > 0) { ++ pkt = (STP_PACKET_T *) buf; ++ hdr = &pkt->hdr; ++ len = pkt->hdr.len; ++ osal_memcpy(&tmp[index], &len, 2); ++ index += 2; ++ if (hdr->dbg_type == STP_DBG_FW_DMP) { ++ osal_memcpy(&tmp[index], pkt->raw, len); ++ ++ if (len <= 1500) { ++ /* pr_warn("\n%s\n+++\n", tmp); */ ++ /* pr_warn("send coredump len:%d\n", len); */ ++ /* pr_warn("send coredump:%s\n", tmp); */ ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); ++ ++ while (rc) { ++ nl_retry++; ++ if (nl_retry > 1000) ++ break; ++ STP_BTM_WARN_FUNC ++ ("**dump send fails, and retry again.**\n"); ++ osal_sleep_ms(3); ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); ++ if (!rc) ++ STP_BTM_WARN_FUNC("****retry again ok!**\n"); ++ } ++ /* schedule(); */ ++ } else { ++ STP_BTM_INFO_FUNC("dump entry length is over long\n"); ++ BUG_ON(0); ++ } ++ retry = 0; ++ } ++ } else { ++ retry++; ++ osal_sleep_ms(100); ++ } ++ } while ((remain > 0) || (retry < 2)); ++ ++ STP_BTM_INFO_FUNC("Exit..\n"); ++ return 0; ++} ++ ++#define SUB_PKT_SIZE 1024 ++#define SUB_PKT_HEADER 5 /*'[M]',3Bytes; len,2Bytes*/ ++ ++INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len) ++{ ++ static UINT8 tmp[SUB_PKT_SIZE + SUB_PKT_HEADER]; ++ ++ INT32 remain = dump_len, index = 0; ++ INT32 rc = 0, nl_retry = 0; ++ INT32 len; ++ INT32 offset = 0; ++ ++ STP_BTM_INFO_FUNC("Enter..\n"); ++ ++ if (dump_len > 0) { ++ index = 0; ++ tmp[index++] = '['; ++ tmp[index++] = 'M'; ++ tmp[index++] = ']'; ++ ++ do { ++ index = 3; ++ if (remain >= SUB_PKT_SIZE) ++ len = SUB_PKT_SIZE; ++ else ++ len = remain; ++ remain -= len; ++ ++ osal_memcpy(&tmp[index], &len, 2); ++ index += 2; ++ osal_memcpy(&tmp[index], data_buf + offset, len); ++ offset += len; ++ STP_BTM_DBG_FUNC ++ ("send %d remain %d\n", len, remain); ++ ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); ++ while (rc) { ++ nl_retry++; ++ if (nl_retry > 1000) ++ break; ++ STP_BTM_WARN_FUNC ++ ("**dump send fails, and retry again.**\n"); ++ osal_sleep_ms(3); ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); ++ if (!rc) { ++ STP_BTM_WARN_FUNC ++ ("****retry again ok!**\n"); ++ } ++ } ++ /* schedule(); */ ++ } while (remain > 0); ++ } else ++ STP_BTM_INFO_FUNC("dump entry length is 0\n"); ++ ++ STP_BTM_INFO_FUNC("Exit..\n"); ++ return 0; ++} ++ ++static INT32 _stp_btm_put_dump_to_aee(void) ++{ ++ static UINT8 buf[2048]; ++ static UINT8 tmp[2048]; ++ ++ UINT32 buf_len; ++ STP_PACKET_T *pkt; ++ STP_DBG_HDR_T *hdr; ++ INT32 remain = 0; ++ INT32 retry = 0; ++ INT32 ret = 0; ++ ++ STP_BTM_INFO_FUNC("Enter..\n"); ++ ++ do { ++ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); ++ if (buf_len > 0) { ++ pkt = (STP_PACKET_T *) buf; ++ hdr = &pkt->hdr; ++ if (hdr->dbg_type == STP_DBG_FW_DMP) { ++ memcpy(&tmp[0], pkt->raw, pkt->hdr.len); ++ ++ if (pkt->hdr.len <= 1500) { ++ tmp[pkt->hdr.len] = '\n'; ++ tmp[pkt->hdr.len + 1] = '\0'; ++ ++ ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0); ++ } else { ++ STP_BTM_INFO_FUNC("dump entry length is over long\n"); ++ BUG_ON(0); ++ } ++ retry = 0; ++ } ++ } else { ++ retry++; ++ msleep(100); ++ } ++ } while ((remain > 0) || (retry < 2)); ++ ++ STP_BTM_INFO_FUNC("Exit..\n"); ++ return ret; ++} ++ ++#if 0 ++INT32 _stp_trigger_firmware_assert_via_emi(VOID) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ INT32 status = -1; ++ INT32 i = 0, j = 0; ++ ++ do { ++ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); ++ if (!p_virtual_addr) { ++ STP_BTM_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); ++ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); ++#if 1 ++ /* wait for firmware assert */ ++ osal_sleep_ms(50); ++ /* if firmware is not assert self, host driver helps it. */ ++ do { ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ status = 0; ++ break; ++ } ++ ++ mtk_wcn_stp_wakeup_consys(); ++ STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i); ++ stp_dbg_poll_cpupcr(5, 1, 1); ++ osal_sleep_ms(5); ++ ++ i++; ++ if (i > 20) { ++ i = 0; ++ break; ++ } ++ } while (1); ++#endif ++ ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ status = 0; ++ break; ++ } ++ ++ j++; ++ if (j > 8) { ++ j = 0; ++ break; ++ } ++ } while (1); ++ ++ return status; ++} ++#else ++INT32 _stp_trigger_firmware_assert_via_emi(VOID) ++{ ++ INT32 status = -1; ++ INT32 j = 0; ++ ++ wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); ++ ++ do { ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ status = 0; ++ break; ++ } ++ ++ stp_dbg_poll_cpupcr(5, 1, 1); ++ stp_dbg_poll_dmaregs(5, 1); ++ j++; ++ STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); ++ osal_sleep_ms(20); ++ if (j > 49) { /* wait for 1 second */ ++ stp_dbg_set_fw_info("host trigger fw assert timeout", ++ osal_strlen("host trigger fw assert timeout"), ++ STP_HOST_TRIGGER_ASSERT_TIMEOUT); ++ wcn_core_dump_timeout(); /* trigger collect SYS_FTRACE */ ++ break; ++ } ++ } while (1); ++ ++ return status; ++} ++#endif ++ ++#define COMBO_DUMP2AEE ++#if 1 ++#define STP_DBG_PAGED_DUMP_BUFFER_SIZE (32*1024*sizeof(char)) ++UINT8 g_paged_dump_buffer[STP_DBG_PAGED_DUMP_BUFFER_SIZE] = { 0 }; ++ ++#define STP_DBG_PAGED_TRACE_SIZE (2048*sizeof(char)) ++UINT8 g_paged_trace_buffer[STP_DBG_PAGED_TRACE_SIZE] = { 0 }; ++ ++UINT32 g_paged_dump_len = 0; ++UINT32 g_paged_trace_len = 0; ++VOID _stp_dump_emi_dump_buffer(UINT8 *buffer, UINT32 len) ++{ ++ UINT32 i = 0; ++ ++ if (len > 16) ++ len = 16; ++ for (i = 0; i < len; i++) { ++ if (i % 16 == 0 && i != 0) ++ pr_cont("\n "); ++ ++ if (buffer[i] == ']' || buffer[i] == '[' || buffer[i] == ',') ++ pr_cont("%c", buffer[i]); ++ else ++ pr_cont("0x%02x ", buffer[i]); ++ } ++} ++#endif ++static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) ++{ ++ INT32 ret = -1; ++ INT32 dump_sink = 1; /* core dump target, 0: aee; 1: netlink */ ++ INT32 Ret = 0; ++ static UINT32 counter; ++ UINT32 full_dump_left = STP_FULL_DUMP_TIME; ++ UINT32 page_counter = 0; ++ UINT32 packet_num = STP_PAGED_DUMP_TIME_LIMIT/100; ++ UINT32 dump_num = 0; ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ P_CONSYS_EMI_ADDR_INFO p_ecsi; ++ ++ p_ecsi = wmt_plat_get_emi_phy_add(); ++ osal_assert(p_ecsi); ++ if (NULL == pStpOp) ++ return -1; ++ ++ switch (pStpOp->opId) { ++ case STP_OPID_BTM_EXIT: ++ /* TODO: clean all up? */ ++ ret = 0; ++ break; ++ ++ /*tx timeout retry */ ++ case STP_OPID_BTM_RETRY: ++ stp_do_tx_timeout(); ++ ret = 0; ++ ++ break; ++ ++ /*whole chip reset */ ++ case STP_OPID_BTM_RST: ++ STP_BTM_INFO_FUNC("whole chip reset start!\n"); ++ STP_BTM_INFO_FUNC("....+\n"); ++ if (stp_btm->wmt_notify) { ++ stp_btm->wmt_notify(BTM_RST_OP); ++ ret = 0; ++ } else { ++ STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); ++ ret = -1; ++ } ++ ++ STP_BTM_INFO_FUNC("whole chip reset end!\n"); ++ ++ break; ++ ++ case STP_OPID_BTM_DBG_DUMP: ++ /*Notify the wmt to get dump data */ ++ STP_BTM_DBG_FUNC("wmt dmp notification\n"); ++ dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1); ++ ++ if (dump_sink == 0) ++ _stp_btm_put_dump_to_aee(); ++ else if (dump_sink == 1) ++ _stp_btm_put_dump_to_nl(); ++ else ++ STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink); ++ ++ break; ++ ++ case STP_OPID_BTM_DUMP_TIMEOUT: ++ /* Flush dump data, and reset compressor */ ++ STP_BTM_INFO_FUNC("Flush dump data\n"); ++ wcn_core_dump_flush(0, MTK_WCN_BOOL_TRUE); ++ break; ++ ++ case STP_OPID_BTM_POLL_CPUPCR: ++ do { ++ UINT32 times; ++ UINT32 sleep; ++ ++ times = pStpOp->au4OpData[0]; ++ sleep = pStpOp->au4OpData[1]; ++ ++ ret = stp_dbg_poll_cpupcr(times, sleep, 0); ++ ret += stp_dbg_poll_dmaregs(times, sleep); ++ } while (0); ++ break; ++ ++ case STP_OPID_BTM_PAGED_DUMP: ++ g_paged_dump_len = 0; ++ issue_type = STP_FW_ASSERT_ISSUE; ++ /*packet number depend on dump_num get from register:0xf0080044 ,support jade*/ ++ wcn_core_dump_deinit_gcoredump(); ++ dump_num = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_page_dump_num); ++ if (dump_num != 0) { ++ packet_num = dump_num; ++ STP_BTM_WARN_FUNC("get consys dump num packet_num(%d)\n", packet_num); ++ } else { ++ STP_BTM_ERR_FUNC("can not get consys dump num and default num is 35\n"); ++ } ++ Ret = wcn_core_dump_init_gcoredump(packet_num, STP_CORE_DUMP_TIMEOUT); ++ if (Ret) { ++ STP_BTM_ERR_FUNC("core dump init fail\n"); ++ break; ++ } ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ page_counter = 0; ++ do { ++ UINT32 loop_cnt1 = 0; ++ UINT32 loop_cnt2 = 0; ++ ENUM_HOST_DUMP_STATE host_state; ++ ENUM_CHIP_DUMP_STATE chip_state; ++ UINT32 dump_phy_addr = 0; ++ UINT8 *dump_vir_addr = NULL; ++ UINT32 dump_len = 0; ++ UINT32 isEnd = 0; ++ ++ host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_state); ++ if (STP_HOST_DUMP_NOT_START == host_state) { ++ counter++; ++ STP_BTM_INFO_FUNC("counter(%d)\n", counter); ++ osal_sleep_ms(100); ++ } else { ++ counter = 0; ++ } ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_PUT_DONE == chip_state) { ++ STP_BTM_INFO_FUNC("chip put done\n"); ++ break; ++ } ++ STP_BTM_INFO_FUNC("waiting chip put done\n"); ++ STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state); ++ loop_cnt1++; ++ osal_sleep_ms(5); ++ ++ if (loop_cnt1 > 10) ++ goto paged_dump_end; ++ ++ } ++ ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); ++ ++ dump_phy_addr = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); ++ ++ if (!dump_phy_addr) { ++ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); ++ ret = -1; ++ break; ++ } ++ ++ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); ++ if (!dump_vir_addr) { ++ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); ++ ret = -2; ++ break; ++ } ++ dump_len = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); ++ STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n", ++ dump_phy_addr, dump_vir_addr, dump_len); ++ ++ /*move dump info according to dump_addr & dump_len */ ++#if 1 ++ osal_memcpy(&g_paged_dump_buffer[0], dump_vir_addr, dump_len); ++ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], dump_len); ++ ++ if (0 == page_counter) { /* do fw assert infor paser in first paged dump */ ++ if (1 == stp_dbg_get_host_trigger_assert()) ++ issue_type = STP_HOST_TRIGGER_FW_ASSERT; ++ ++ ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0], 512, issue_type); ++ if (ret) { ++ STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n", ret); ++ stp_dbg_set_fw_info("Fw Warm reset", osal_strlen("Fw Warm reset"), ++ STP_FW_WARM_RST_ISSUE); ++ } ++ } ++ ++ if (dump_len <= 32 * 1024) { ++ pr_err("g_coredump_mode: %d!\n", g_coredump_mode); ++ if (1 == g_coredump_mode) ++ ret = stp_dbg_aee_send(&g_paged_dump_buffer[0], dump_len, 0); ++ else if (2 == g_coredump_mode) ++ ret = _stp_btm_put_emi_dump_to_nl(&g_paged_dump_buffer[0], dump_len); ++ else{ ++ STP_BTM_INFO_FUNC("coredump is disabled!\n"); ++ return 0; ++ } ++ if (ret == 0) ++ STP_BTM_INFO_FUNC("aee send ok!\n"); ++ else if (ret == 1) ++ STP_BTM_INFO_FUNC("aee send fisish!\n"); ++ else ++ STP_BTM_ERR_FUNC("aee send error!\n"); ++ } else ++ STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n", dump_len); ++ ++ g_paged_dump_len += dump_len; ++ STP_BTM_INFO_FUNC("dump len update(%d)\n", g_paged_dump_len); ++#endif ++ wmt_plat_update_host_sync_num(); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); ++ ++ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); ++ ++ page_counter++; ++ STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n", page_counter); ++ ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_END == chip_state) { ++ STP_BTM_INFO_FUNC("chip put end\n"); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); ++ break; ++ } ++ STP_BTM_INFO_FUNC("waiting chip put end\n"); ++ ++ loop_cnt2++; ++ osal_sleep_ms(10); ++ ++ if (loop_cnt2 > 10) ++ goto paged_dump_end; ++ } ++ ++paged_dump_end: ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ ++ if (counter > packet_num) { ++ isEnd = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_paded_dump_end); ++ ++ if (isEnd) { ++ STP_BTM_INFO_FUNC("paged dump end\n"); ++ ++ STP_BTM_INFO_FUNC("\n\n paged dump print ++\n\n"); ++ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], g_paged_dump_len); ++ STP_BTM_INFO_FUNC("\n\n paged dump print --\n\n"); ++ STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d\n\n", ++ g_paged_dump_len, page_counter); ++ counter = 0; ++ ret = 0; ++ } else { ++ STP_BTM_ERR_FUNC("paged dump fail\n"); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ stp_dbg_poll_cpupcr(5, 5, 0); ++ stp_dbg_poll_dmaregs(5, 1); ++ counter = 0; ++ ret = -1; ++ } ++ break; ++ } ++ ++ } while (1); ++ ++ break; ++ ++ case STP_OPID_BTM_FULL_DUMP: ++ ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ do { ++ UINT32 loop_cnt1 = 0; ++ UINT32 loop_cnt2 = 0; ++ ENUM_CHIP_DUMP_STATE chip_state; ++ UINT32 dump_phy_addr = 0; ++ UINT8 *dump_vir_addr = NULL; ++ UINT32 dump_len = 0; ++ UINT32 isFail = 0; ++ ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_PUT_DONE == chip_state) ++ break; ++ ++ loop_cnt1++; ++ osal_sleep_ms(10); ++ ++ if (loop_cnt1 > 10) { ++ isFail = 1; ++ goto full_dump_end; ++ } ++ } ++ ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); ++ ++ dump_phy_addr = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); ++ if (!dump_phy_addr) { ++ STP_BTM_ERR_FUNC("get phy dump address fail\n"); ++ ret = -1; ++ break; ++ } ++ ++ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); ++ if (!dump_vir_addr) { ++ STP_BTM_ERR_FUNC("get vir dump address fail\n"); ++ ret = -2; ++ break; ++ } ++ dump_len = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); ++ /*move dump info according to dump_addr & dump_len */ ++ wmt_plat_update_host_sync_num(); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); ++ ++ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); ++ ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_END == chip_state) { ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); ++ break; ++ } ++ loop_cnt2++; ++ osal_sleep_ms(10); ++ ++ if (loop_cnt2 > 10) { ++ isFail = 1; ++ goto full_dump_end; ++ } ++ } ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++full_dump_end: ++ if (isFail) { ++ STP_BTM_ERR_FUNC("full dump fail\n"); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ ret = -1; ++ break; ++ } ++ } while (--full_dump_left > 0); ++ if (0 == full_dump_left) { ++ STP_BTM_INFO_FUNC("full dump end\n"); ++ ret = 0; ++ } ++ break; ++ case STP_OPID_BTM_PAGED_TRACE: ++ g_paged_trace_len = 0; ++ do { ++ UINT32 ctrl_val = 0; ++ UINT32 loop_cnt1 = 0; ++ UINT32 buffer_start = 0; ++ UINT32 buffer_idx = 0; ++ UINT8 *dump_vir_addr = NULL; ++ ++ while (loop_cnt1 < 10) { ++ ctrl_val = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state); ++ if (0x8 == ctrl_val) ++ break; ++ osal_sleep_ms(10); ++ loop_cnt1++; ++ } ++ ++ if (loop_cnt1 >= 10) { ++ STP_BTM_ERR_FUNC("polling CTRL STATE fail\n"); ++ ret = -1; ++ break; ++ } ++ ++ buffer_start = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_start); ++ buffer_idx = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_idx); ++ /* buffer_len = buffer_idx - buffer_start; */ ++ g_paged_trace_len = buffer_idx; ++ STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n", buffer_start, buffer_idx); ++ dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_ecsi->emi_phy_addr); ++ if (!dump_vir_addr) { ++ STP_BTM_ERR_FUNC("get vir dump address fail\n"); ++ ret = -2; ++ break; ++ } ++ osal_memcpy(&g_paged_trace_buffer[0], dump_vir_addr, ++ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE); ++ /*moving paged trace according to buffer_start & buffer_len */ ++ do { ++ int i = 0; ++ int dump_len = 0; ++ ++ dump_len = ++ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE; ++ pr_warn("\n\n -- paged trace hex output --\n\n"); ++ for (i = 0; i < dump_len; i++) { ++ if (i % 16 == 0) ++ pr_cont("\n"); ++ ++ pr_cont("%02x ", g_paged_trace_buffer[i]); ++ } ++ pr_warn("\n\n -- paged trace ascii output --\n\n"); ++ for (i = 0; i < dump_len; i++) { ++ if (i % 64 == 0) ++ pr_cont("\n"); ++ pr_cont("%c", g_paged_trace_buffer[i]); ++ } ++ } while (0); ++ /*move parser fw assert infor to paged dump in the one paged dump */ ++ /* ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type); */ ++ ret = 0; ++ ++ } while (0); ++ mtk_wcn_stp_ctx_restore(); ++ break; ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ case STP_OPID_BTM_WMT_LTE_COEX: ++ ret = wmt_idc_msg_to_lte_handing(); ++ break; ++#endif ++ default: ++ ret = -1; ++ break; ++ } ++ ++ return ret; ++} ++ ++static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ) ++{ ++ P_OSAL_OP pOp; ++ /* INT32 ret = 0; */ ++ ++ if (!pOpQ) { ++ STP_BTM_WARN_FUNC("!pOpQ\n"); ++ return NULL; ++ } ++ ++ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ /* acquire lock success */ ++ RB_GET(pOpQ, pOp); ++ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ ++ if (!pOp) ++ STP_BTM_WARN_FUNC("RB_GET fail\n"); ++ ++ return pOp; ++} ++ ++static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) ++{ ++ INT32 ret; ++ ++ if (!pOpQ || !pOp) { ++ STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); ++ return 0; /* ;MTK_WCN_BOOL_FALSE; */ ++ } ++ ++ ret = 0; ++ ++ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ /* acquire lock success */ ++ if (!RB_FULL(pOpQ)) ++ RB_PUT(pOpQ, pOp); ++ else ++ ret = -1; ++ ++ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ ++ if (ret) { ++ STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", ++ pOpQ, ++ RB_COUNT(pOpQ), ++ &stp_btm->rFreeOpQ, ++ &stp_btm->rActiveOpQ); ++ return 0; ++ } ++ /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ ++ return 1; ++ ++} ++ ++P_OSAL_OP _stp_btm_get_free_op(MTKSTP_BTM_T *stp_btm) ++{ ++ P_OSAL_OP pOp; ++ ++ if (stp_btm) { ++ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ); ++ if (pOp) ++ osal_memset(&pOp->op, 0, sizeof(pOp->op)); ++ ++ return pOp; ++ } else ++ return NULL; ++} ++ ++INT32 _stp_btm_put_act_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) ++{ ++ INT32 bRet = 0; ++ INT32 bCleanup = 0; ++ long wait_ret = -1; ++ ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ if (!stp_btm || !pOp) { ++ STP_BTM_ERR_FUNC("Input NULL pointer\n"); ++ return bRet; ++ } ++ do { ++ pSignal = &pOp->signal; ++ ++ if (pSignal->timeoutValue) { ++ pOp->result = -9; ++ osal_signal_init(&pOp->signal); ++ } ++ ++ /* put to active Q */ ++ bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp); ++ if (0 == bRet) { ++ STP_BTM_WARN_FUNC("put active queue fail\n"); ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ break; ++ } ++ ++ /* wake up wmtd */ ++ osal_trigger_event(&stp_btm->STPd_event); ++ ++ if (pSignal->timeoutValue == 0) { ++ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ ++ /* clean it in wmtd */ ++ break; ++ } ++ ++ /* wait result, clean it here */ ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ ++ /* check result */ ++ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); ++ ++ STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret); ++ if (!wait_ret) { ++ STP_BTM_ERR_FUNC("wait completion timeout\n"); ++ /* TODO: how to handle it? retry? */ ++ } else { ++ if (pOp->result) ++ STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); ++ ++ bRet = (pOp->result) ? 0 : 1; ++ } ++ } while (0); ++ ++ if (bCleanup) { ++ /* put Op back to freeQ */ ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); ++ } ++ bRet = (pOp->result) ? 0 : 1; ++ return bRet; ++} ++ ++static INT32 _stp_btm_wait_for_msg(void *pvData) ++{ ++ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; ++ ++ return (!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd); ++} ++ ++static INT32 _stp_btm_proc(void *pvData) ++{ ++ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; ++ P_OSAL_OP pOp; ++ INT32 id; ++ INT32 result; ++ ++ if (!stp_btm) { ++ STP_BTM_WARN_FUNC("!stp_btm\n"); ++ return -1; ++ } ++ ++ for (;;) { ++ pOp = NULL; ++ ++ osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm); ++ ++ if (osal_thread_should_stop(&stp_btm->BTMd)) { ++ STP_BTM_INFO_FUNC("should stop now...\n"); ++ /* TODO: clean up active opQ */ ++ break; ++ } ++ ++ /* get Op from activeQ */ ++ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); ++ ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); ++ continue; ++ } ++ ++ id = osal_op_get_id(pOp); ++ ++ STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", ++ id, (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), ++ RB_COUNT(&stp_btm->rActiveOpQ)); ++ ++ if (id >= STP_OPID_BTM_NUM) { ++ STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id); ++ result = -1; ++ goto handler_done; ++ } ++ ++ result = _stp_btm_handler(stp_btm, &pOp->op); ++ ++handler_done: ++ ++ if (result) { ++ STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, ++ (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), ++ result); ++ } ++ ++ if (osal_op_is_wait_for_signal(pOp)) { ++ osal_op_raise_signal(pOp, result); ++ } else { ++ /* put Op back to freeQ */ ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); ++ } ++ ++ if (STP_OPID_BTM_EXIT == id) { ++ break; ++ } else if (STP_OPID_BTM_RST == id) { ++ /* prevent multi reset case */ ++ stp_btm_reset_btm_wq(stp_btm); ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ } ++ } ++ ++ STP_BTM_INFO_FUNC("exits\n"); ++ ++ return 0; ++}; ++ ++static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_RST; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_RETRY; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (!stp_btm) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_DUMP_TIMEOUT; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_dump_type(MTKSTP_BTM_T *stp_btm, ENUM_STP_BTM_OPID_T opid) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = opid; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ INT32 retval; ++#if 0 ++ UINT32 dump_type; ++ UINT8 *virtual_addr = NULL; ++#endif ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++#if 1 /* Paged dump */ ++ STP_BTM_INFO_FUNC("paged dump start++\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); ++ if (retval) ++ STP_BTM_ERR_FUNC("paged dump fail\n"); ++#else ++ virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR); ++ if (!virtual_addr) { ++ STP_BTM_ERR_FUNC("get dump type virtual addr fail\n"); ++ return -1; ++ } ++ dump_type = CONSYS_REG_READ(virtual_addr); ++ STP_BTM_INFO_FUNC("dump type:%08x\n", dump_type); ++ ++ if ((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff)) { ++ STP_BTM_INFO_FUNC("do paged dump\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); ++ if (retval) { ++ STP_BTM_ERR_FUNC("paged dump fail,do full dump\n"); ++ _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); ++ } ++ } else if ((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff)) { ++ STP_BTM_INFO_FUNC("do full dump\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); ++ } else { ++ STP_BTM_INFO_FUNC("do normal dump\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DBG_DUMP); ++ } ++#endif ++ ++ return retval; ++} ++ ++static inline INT32 _stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_POLL_CPUPCR; ++ pOp->signal.timeoutValue = 0; ++ pOp->op.au4OpData[0] = times; ++ pOp->op.au4OpData[1] = sleep; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_PAGED_TRACE; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) ++{ ++ INT32 ret = -1; ++ ++ ret = _stp_trigger_firmware_assert_via_emi(); ++ ++ return ret; ++ ++} ++ ++INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_wmt_rst_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_stp_retry_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_coredump_timeout_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_wmt_dmp_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_wmt_trace_wq(stp_btm); ++} ++ ++INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) ++{ ++ return _stp_notify_btm_poll_cpupcr(stp_btm, times, sleep); ++} ++ ++INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en) ++{ ++ return stp_dbg_poll_cuppcr_ctrl(en); ++} ++ ++INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) ++{ ++ INT32 ret = -1; ++#if BTIF_RXD_BE_BLOCKED_DETECT ++ if (is_btif_rxd_be_blocked()) ++ ret = wcn_btif_rxd_blocked_collect_ftrace(); /* trigger collect SYS_FTRACE */ ++ else ++#endif ++ ret = _stp_btm_do_fw_assert_via_emi(stp_btm); ++ return ret; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ ++static inline INT32 _stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_WMT_LTE_COEX; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_notify_btm_handle_wmt_lte_coex(stp_btm); ++} ++ ++#endif ++MTKSTP_BTM_T *stp_btm_init(void) ++{ ++ INT32 i = 0x0; ++ INT32 ret = -1; ++ ++ osal_unsleepable_lock_init(&stp_btm->wq_spinlock); ++ osal_event_init(&stp_btm->STPd_event); ++ stp_btm->wmt_notify = wmt_lib_btm_cb; ++ ++ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); ++ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); ++ ++ /* Put all to free Q */ ++ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(stp_btm->arQue[i].signal)); ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); ++ } ++ ++ /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving */ ++ stp_btm->BTMd.pThreadData = (VOID *) stp_btm; ++ stp_btm->BTMd.pThreadFunc = (VOID *) _stp_btm_proc; ++ osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME, osal_strlen(BTM_THREAD_NAME)); ++ ++ ret = osal_thread_create(&stp_btm->BTMd); ++ if (ret < 0) { ++ STP_BTM_ERR_FUNC("osal_thread_create fail...\n"); ++ goto ERR_EXIT1; ++ } ++ ++ /* Start STPd thread */ ++ ret = osal_thread_run(&stp_btm->BTMd); ++ if (ret < 0) { ++ STP_BTM_ERR_FUNC("osal_thread_run FAILS\n"); ++ goto ERR_EXIT1; ++ } ++ ++ return stp_btm; ++ ++ERR_EXIT1: ++ ++ return NULL; ++ ++} ++ ++INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ INT32 ret = -1; ++ ++ STP_BTM_INFO_FUNC("btm deinit\n"); ++ ++ if (!stp_btm) ++ return STP_BTM_OPERATION_FAIL; ++ ++ ret = osal_thread_destroy(&stp_btm->BTMd); ++ if (ret < 0) { ++ STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n"); ++ return STP_BTM_OPERATION_FAIL; ++ } ++ ++ return STP_BTM_OPERATION_SUCCESS; ++} ++ ++INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ UINT32 i = 0; ++ ++ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); ++ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); ++ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ /* Put all to free Q */ ++ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(stp_btm->arQue[i].signal)); ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); ++ } ++ ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c +new file mode 100644 +index 000000000000..246448b38b31 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c +@@ -0,0 +1,13 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h +new file mode 100644 +index 000000000000..9a429b4af1e3 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h +@@ -0,0 +1,133 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _BTM_CORE_H ++#define _BTM_CORE_H ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_wmt.h" ++#include "wmt_plat.h" ++#include "wmt_idc.h" ++#include "mtk_btif_exp.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define STP_BTM_OPERATION_FAIL (-1) ++#define STP_BTM_OPERATION_SUCCESS (0) ++ ++#define STP_BTM_OP_BUF_SIZE (64) ++ ++#define BTM_THREAD_NAME "mtk_stp_btm" ++ ++#define STP_PAGED_DUMP_TIME_LIMIT 3500 ++#define STP_FULL_DUMP_TIME 3 ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_STP_BTM_OPID_T { ++ STP_OPID_BTM_RETRY = 0x0, ++ STP_OPID_BTM_RST = 0x1, ++ STP_OPID_BTM_DBG_DUMP = 0x2, ++ STP_OPID_BTM_DUMP_TIMEOUT = 0x3, ++ STP_OPID_BTM_POLL_CPUPCR = 0x4, ++ STP_OPID_BTM_PAGED_DUMP = 0x5, ++ STP_OPID_BTM_FULL_DUMP = 0x6, ++ STP_OPID_BTM_PAGED_TRACE = 0x7, ++ STP_OPID_BTM_FORCE_FW_ASSERT = 0x8, ++#if CFG_WMT_LTE_COEX_HANDLING ++ STP_OPID_BTM_WMT_LTE_COEX = 0x9, ++#endif ++ STP_OPID_BTM_EXIT, ++ STP_OPID_BTM_NUM ++} ENUM_STP_BTM_OPID_T, *P_ENUM_STP_BTM_OPID_T; ++ ++typedef OSAL_OP_DAT STP_BTM_OP; ++typedef P_OSAL_OP_DAT P_STP_BTM_OP; ++ ++typedef struct mtk_stp_btm { ++ OSAL_THREAD BTMd; /* main thread (wmtd) handle */ ++ OSAL_EVENT STPd_event; ++ OSAL_UNSLEEPABLE_LOCK wq_spinlock; ++ ++ OSAL_OP_Q rFreeOpQ; /* free op queue */ ++ OSAL_OP_Q rActiveOpQ; /* active op queue */ ++ OSAL_OP arQue[STP_BTM_OP_BUF_SIZE]; /* real op instances */ ++ ++ /*wmt_notify */ ++ INT32 (*wmt_notify)(MTKSTP_BTM_WMT_OP_T); ++} MTKSTP_BTM_T; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep); ++INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en); ++INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm); ++INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm); ++INT32 wcn_psm_flag_trigger_collect_ftrace(void); ++#if BTIF_RXD_BE_BLOCKED_DETECT ++INT32 wcn_btif_rxd_blocked_collect_ftrace(void); ++MTK_WCN_BOOL is_btif_rxd_be_blocked(void); ++#endif ++MTKSTP_BTM_T *stp_btm_init(void); ++extern unsigned int g_coredump_mode; ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h +new file mode 100644 +index 000000000000..d8c6ebe9c4b0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h +@@ -0,0 +1,69 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _DBG_CORE_H ++#define _DBG_CORE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h +new file mode 100644 +index 000000000000..fe92f25e92c1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h +@@ -0,0 +1,251 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _PSM_CORE_H ++#define _PSM_CORE_H ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_wmt.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define PFX_PSM "[STP-PSM] " ++#define STP_PSM_LOG_LOUD 4 ++#define STP_PSM_LOG_DBG 3 ++#define STP_PSM_LOG_INFO 2 ++#define STP_PSM_LOG_WARN 1 ++#define STP_PSM_LOG_ERR 0 ++ ++#define ASSERT(expr) ++#define STP_PSM_FIFO_SIZE 0x2000 /* 8kbytes */ ++#define STP_PSM_TX_SIZE 0x800 /* 2kbytes */ ++ ++#define STP_PSM_OPERATION_FAIL (-1) ++#define STP_PSM_OPERATION_SUCCESS (0) ++ ++#define STP_PSM_PACKET_SIZE_MAX (2000) ++ ++#define PSM_HANDLING 127 ++ ++#define STP_PSM_WMT_PS_TASK_HANDLING_TIME 30 /* 20 milli-seconds */ ++#define STP_PSM_IDLE_TIME_SLEEP 30 /* temporary for stress testing */ ++#define STP_PSM_IDLE_TIME_SLEEP_1000 1000 /* for high speed transmission e.g. BT OPP*/ ++#define STP_PSM_SDIO_IDLE_TIME_SLEEP 100 /* temporary for SDIO stress testing */ ++#define STP_PSM_WAIT_EVENT_TIMEOUT 6000 ++#if 0 ++#define STP_PSM_WMT_EVENT_SLEEP_EN (0x1UL << 0) ++#define STP_PSM_WMT_EVENT_WAKEUP_EN (0x1UL << 1) ++#define STP_PSM_BLOCK_DATA_EN (0x1UL << 2) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (0x1UL << 3) ++#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (0x1UL << 4) ++#define STP_PSM_RESET_EN (0x1UL << 5) ++#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (0x1UL << 6) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (0x1UL << 7) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (0x1UL << 8) ++#endif ++ ++#define STP_PSM_WMT_EVENT_SLEEP_EN (0) ++#define STP_PSM_WMT_EVENT_WAKEUP_EN (1) ++#define STP_PSM_BLOCK_DATA_EN (2) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (3) ++#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (4) ++#define STP_PSM_RESET_EN (5) ++#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (6) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (7) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (8) ++ ++#define STP_PSM_DBG_SIZE (16) ++ ++/* OP command ring buffer : must be power of 2 */ ++#define STP_OP_BUF_SIZE (16) ++ ++#define PSM_THREAD_NAME "mtk_stp_psm" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum { ++ ACT = 0, ++ ACT_INACT, ++ INACT, ++ INACT_ACT, ++ STP_PSM_MAX_STATE, ++} MTKSTP_PSM_STATE_T; ++ ++typedef enum _ENUM_STP_OPID_T { ++ STP_OPID_PSM_SLEEP = 0, ++ STP_OPID_PSM_WAKEUP, ++ STP_OPID_PSM_HOST_AWAKE, ++ STP_OPID_PSM_EXIT, ++ STP_OPID_PSM_NUM, ++ STP_OPID_PSM_INALID = STP_OPID_PSM_NUM, ++} ENUM_STP_OPID_T, *P_ENUM_STP_OPID_T; ++ ++typedef enum { ++ MON = 0, ++ UNMON, ++} MTKSTP_PSM_MONSTATE_T; ++ ++typedef INT32(*wmt_notify_t) (MTKSTP_PSM_ACTION_T action); ++typedef INT32(*stp_tx_cb_t) (unsigned char *buffer, UINT32 length, UINT8 type); ++ ++typedef OSAL_OP_DAT STP_OP; ++typedef P_OSAL_OP_DAT P_STP_OP; ++ ++typedef struct mtk_stp_psm { ++ OSAL_THREAD PSMd; /* main thread (wmtd) handle */ ++ OSAL_EVENT STPd_event; ++ ++ OSAL_OP_Q rFreeOpQ; /* free op queue */ ++ OSAL_OP_Q rActiveOpQ; /* active op queue */ ++ OSAL_OP arQue[STP_OP_BUF_SIZE]; /* real op instances */ ++ ++ /* OSAL_OP current_active_op; */ ++ /* P_OSAL_OP current_active_op; */ ++ UINT32 last_active_opId; ++ MTKSTP_PSM_STATE_T work_state; /*working state */ ++ OSAL_BIT_OP_VAR flag; ++ ++ /* in normal cases, sleep op is always enabled; ++ * but in error cases, we can't execute sleep cmd, ++ * Eg: FW assert, core dump ++ */ ++ INT32 sleep_en; ++ ++/* OSAL_UNSLEEPABLE_LOCK flagSpinlock; */ ++ INT32 idle_time_to_sleep; ++ OSAL_WAKE_LOCK wake_lock; ++ OSAL_TIMER psm_timer; /*monitor if active */ ++ OSAL_EVENT wait_wmt_q; ++ OSAL_FIFO hold_fifo; ++ OSAL_SLEEPABLE_LOCK hold_fifo_spinlock_global; ++ OSAL_UNSLEEPABLE_LOCK wq_spinlock; ++ OSAL_SLEEPABLE_LOCK stp_psm_lock; ++ INT32 (*wmt_notify)(MTKSTP_PSM_ACTION_T action); ++ INT32 (*stp_tx_cb)(unsigned char *buffer, UINT32 length, UINT8 type); ++ ++ MTK_WCN_BOOL (*is_wmt_quick_ps_support)(VOID); ++ UINT8 out_buf[STP_PSM_TX_SIZE]; ++} MTKSTP_PSM_T; ++ ++typedef struct { ++ UINT32 prev_flag; ++ UINT32 cur_flag; ++ UINT32 line_num; ++ UINT32 package_no; ++ UINT32 sec; ++ UINT32 usec; ++ UINT32 pid; ++} STP_PSM_ENTRY_T; ++ ++typedef struct stp_psm_record { ++ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; ++ UINT32 in; ++ UINT32 out; ++ UINT32 size; ++ OSAL_UNSLEEPABLE_LOCK lock; ++} STP_PSM_RECORD_T; ++ ++typedef struct stp_psm_opid_record { ++ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; ++ UINT32 in; ++ UINT32 out; ++ UINT32 size; ++ OSAL_UNSLEEPABLE_LOCK lock; ++} STP_PSM_OPID_RECORD, *P_STP_PSM_OPID_RECORD; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#define PSM_USE_COUNT_PACKAGE 0 ++ ++#if PSM_USE_COUNT_PACKAGE ++#define MTK_COMBO_PSM_RX_TH_DEFAULT (1600) ++#define MTK_COMBO_PSM_TX_TH_DEFAULT (300) ++INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir); ++#else ++#define SAMPLE_DURATION 1 /*1 second */ ++#define RTX_SPEED_THRESHOLD 50000 /*50KB/s */ ++INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*stp-psm external function*/ ++INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); ++INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm); ++ ++INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type); ++INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep); ++struct mtk_stp_psm *stp_psm_init(void); ++INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm); ++MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel); ++INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state); ++MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID); ++ ++INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h +new file mode 100644 +index 000000000000..eaa5ce773e33 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h +@@ -0,0 +1,629 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _STP_CORE_H ++#define _STP_CORE_H ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_exp.h" ++#include "psm_core.h" ++#include "btm_core.h" ++#include "stp_btif.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CFG_STP_CORE_CTX_SPIN_LOCK (0) ++ ++#define WMT_LTE_COEX_FLAG (0x16) ++ ++/*configure using SPINLOCK or just mutex for STP-CORE tx*/ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define CONFIG_POWER_SAVING_SUPPORT ++ ++#ifdef PFX ++#undef PFX ++#endif ++#define PFX "[STP] " ++ ++#define STP_LOG_DBG 4 ++#define STP_LOG_PKHEAD 3 ++#define STP_LOG_INFO 2 ++#define STP_LOG_WARN 1 ++#define STP_LOG_ERR 0 ++ ++extern unsigned int gStpDbgLvl; ++ ++#define STP_DBG_FUNC(fmt, arg...)\ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_DBG) \ ++ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_INFO) \ ++ osal_dbg_print(PFX "%s:[I] " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_WARN) \ ++ osal_warn_print(PFX "%s:[W] " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_ERR) \ ++ osal_err_print(PFX "%s:[E] " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_TRC_FUNC(f) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_DBG) \ ++ osal_dbg_print(PFX "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++#define STP_DUMP_PACKET_HEAD(a, b, c) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_PKHEAD) \ ++ stp_dump_data(a, b, c); \ ++} while (0) ++#define STP_TRACE_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_DBG) \ ++ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++ ++#define STP_MODE_BIT(x) (0x1UL << x) ++#define MTKSTP_UART_FULL_MODE STP_MODE_BIT(0) ++#define MTKSTP_UART_MAND_MODE STP_MODE_BIT(1) ++#define MTKSTP_BTIF_FULL_MODE STP_MODE_BIT(2) ++#define MTKSTP_BTIF_MAND_MODE STP_MODE_BIT(3) ++#define MTKSTP_SDIO_MODE STP_MODE_BIT(4) ++ ++#define MTKSTP_BUFFER_SIZE (16384) ++ ++/*To check function driver's status by the the interface*/ ++/*Operation definition*/ ++#define OP_FUNCTION_ACTIVE 0 ++ ++/*Driver's status*/ ++#define STATUS_OP_INVALID 0 ++#define STATUS_FUNCTION_INVALID 1 ++ ++#define STATUS_FUNCTION_ACTIVE 31 ++#define STATUS_FUNCTION_INACTIVE 32 ++ ++#define MTKSTP_CRC_SIZE (2) ++#define MTKSTP_HEADER_SIZE (4) ++#define MTKSTP_SEQ_SIZE (8) ++ ++/*#define MTKSTP_WINSIZE (4)*/ ++#define MTKSTP_WINSIZE (7) ++#define MTKSTP_TX_TIMEOUT (180) /*TODO: Baudrate to decide this */ ++#define MTKSTP_RETRY_LIMIT (10) ++ ++#define INDEX_INC(idx) \ ++{ \ ++ idx++; \ ++ idx &= 0x7; \ ++} ++ ++#define INDEX_DEC(idx) \ ++{ \ ++ idx--; \ ++ idx &= 0x7; \ ++} ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef INT32(*IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); ++/* event/signal */ ++typedef INT32(*EVENT_SET) (UINT8 function_type); ++typedef INT32(*EVENT_TX_RESUME) (UINT8 winspace); ++typedef INT32(*FUNCTION_STATUS) (UINT8 type, UINT8 op); ++typedef INT32(*WMT_NOTIFY_FUNC_T) (UINT32 action); ++typedef INT32(*BTM_NOTIFY_WMT_FUNC_T) (INT32); ++ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++typedef OSAL_UNSLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; ++#else ++typedef OSAL_SLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; ++#endif ++ ++typedef struct { ++ /* common interface */ ++ IF_TX cb_if_tx; ++ /* event/signal */ ++ EVENT_SET cb_event_set; ++ EVENT_TX_RESUME cb_event_tx_resume; ++ FUNCTION_STATUS cb_check_funciton_status; ++} mtkstp_callback; ++ ++typedef enum { ++ MTKSTP_SYNC = 0, ++ MTKSTP_SEQ, ++ MTKSTP_ACK, ++ MTKSTP_NAK, ++ MTKSTP_TYPE, ++ MTKSTP_LENGTH, ++ MTKSTP_CHECKSUM, ++ MTKSTP_DATA, ++ MTKSTP_CRC1, ++ MTKSTP_CRC2, ++ MTKSTP_RESYNC1, ++ MTKSTP_RESYNC2, ++ MTKSTP_RESYNC3, ++ MTKSTP_RESYNC4, ++ MTKSTP_FW_MSG, ++} mtkstp_parser_state; ++ ++typedef struct { ++ mtkstp_parser_state state; ++ UINT8 seq; ++ UINT8 ack; ++ UINT8 nak; ++ UINT8 type; ++ UINT16 length; ++ UINT8 checksum; ++ UINT16 crc; ++#if 1 ++ UINT8 wmtsubtype; ++#endif ++} mtkstp_parser_context_struct; ++ ++typedef struct { ++ UINT8 txseq; /* last tx pkt's seq + 1 */ ++ UINT8 txack; /* last tx pkt's ack */ ++ UINT8 rxack; /* last rx pkt's ack */ ++ UINT8 winspace; /* current sliding window size */ ++ UINT8 expected_rxseq; /* last rx pkt's seq + 1 */ ++ UINT8 retry_times; ++} mtkstp_sequence_context_struct; ++ ++typedef struct { ++ /* MTK_WCN_MUTEX mtx; */ ++ OSAL_UNSLEEPABLE_LOCK mtx; ++ UINT8 buffer[MTKSTP_BUFFER_SIZE]; ++ UINT32 read_p; ++ UINT32 write_p; ++} mtkstp_ring_buffer_struct; ++ ++typedef struct { ++ UINT8 inband_rst_set; ++ UINT32 rx_counter; /* size of current processing pkt in rx_buf[] */ ++ UINT8 rx_buf[MTKSTP_BUFFER_SIZE]; /* input buffer of STP, room for current processing pkt */ ++ UINT32 tx_read; /* read ptr of tx_buf[] */ ++ UINT32 tx_write; /* write ptr of tx_buf[] */ ++ UINT8 tx_buf[MTKSTP_BUFFER_SIZE]; /* output buffer of STP */ ++ UINT32 tx_start_addr[MTKSTP_SEQ_SIZE]; /* ptr of each pkt in tx_buf[] */ ++ UINT32 tx_length[MTKSTP_SEQ_SIZE]; /* length of each pkt in tx_buf[] */ ++ mtkstp_ring_buffer_struct ring[MTKSTP_MAX_TASK_NUM]; /* ring buffers for each function driver */ ++ mtkstp_parser_context_struct parser; /* current rx pkt's content */ ++ mtkstp_sequence_context_struct sequence; /* state machine's current status */ ++ /* MTK_WCN_MUTEX stp_mutex; */ ++ /* OSAL_UNSLEEPABLE_LOCK stp_mutex; */ ++ STP_CTX_LOCK stp_mutex; ++ /* MTK_WCN_TIMER tx_timer; // timer for tx timeout handling */ ++ OSAL_TIMER tx_timer; ++ ++ MTKSTP_PSM_T *psm; ++ MTKSTP_BTM_T *btm; ++ UINT8 f_enable; /* default disabled */ ++ UINT8 f_ready; /* default non-ready */ ++ UINT8 f_pending_type; ++ UINT8 f_coredump; /*block tx flag, for now, only when f/w assert happens, we will set this bit on */ ++ UINT8 en_coredump; ++ /* Flag to identify Blueztooth is Bluez/or MTK Stack */ ++ MTK_WCN_BOOL f_bluez; ++ MTK_WCN_BOOL f_dbg_en; ++ MTK_WCN_BOOL f_autorst_en; ++ ++ /* Flag to identify STP by SDIO or UART */ ++ UINT32 f_mode; ++ ++ /* Flag to indicate the last WMT CLOSE */ ++ UINT32 f_wmt_last_close; ++ ++ /* Flag to indicate evt err has triggered assert or not */ ++ UINT32 f_evt_err_assert; ++} mtkstp_context_struct; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_init ++* DESCRIPTION ++* init STP kernel ++* PARAMETERS ++* cb_func [IN] function pointers of system APIs ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_deinit ++* DESCRIPTION ++* deinit STP kernel ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_deinit(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_enable ++* DESCRIPTION ++* enable/disable STP ++* PARAMETERS ++* value [IN] 0 = disable, others = enable ++* RETURNS ++* INT32 0 = success, others = error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_enable(INT32 value); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_ready ++* DESCRIPTION ++* ready/non-ready STP ++* PARAMETERS ++* value [IN] 0 = non-ready, others = ready ++* RETURNS ++* INT32 0 = success, others = error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_ready(INT32 value); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_ctrl ++* DESCRIPTION ++* set f/w assert flag in STP context ++* PARAMETERS ++* value [IN] 0=assert end, others=assert begins ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_get ++* DESCRIPTION ++* get f/w assert flag in STP context ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0= f/w assert flag is not set, others=f/w assert flag is set ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_coredump_start_get(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data_raw ++* DESCRIPTION ++* send raw data to common interface, bypass STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 length transmitted ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_set_sdio_mode ++* DESCRIPTION ++* Set stp for SDIO mode ++* PARAMETERS ++* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_mode(UINT32 sdio_flag); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_fullset_mode ++* DESCRIPTION ++* Is stp use UART Fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:UART Fullset, FALSE:UART Fullset ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_mand_mode ++* DESCRIPTION ++* Is stp use UART Mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:UART Mandatory, FALSE:UART Mandatory ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void); ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_fullset_mode ++* DESCRIPTION ++* Is stp use BTIF Fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Fullset, FALSE:BTIF Fullset ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_mand_mode ++* DESCRIPTION ++* Is stp use BTIF Mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Mandatory, FALSE:BTIF Mandatory ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_sdio_mode ++* DESCRIPTION ++* Is stp use SDIO mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To sync to oringnal stp state with f/w stp ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_inband_reset(void); ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To send testing command to chip ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_test_cmd(INT32 no); ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To control STP debugging mechanism ++* PARAMETERS ++* func_no: function control, func_op: dumpping filer, func_param: dumpping parameter ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_debug_ctrl(INT32 func_no, INT32 func_op, INT32 func_param); ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_flush ++* DESCRIPTION ++* flush all stp context ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_flush_context(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_rx_queue ++* DESCRIPTION ++* flush all stp rx queue ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_flush_rx_queue(UINT32 type); ++ ++/***************************************************************************** ++* FUNCTION ++* set stp debugging mdoe ++* DESCRIPTION ++* set stp debugging mdoe ++* PARAMETERS ++* dbg_mode: switch to dbg mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode); ++ ++/***************************************************************************** ++* FUNCTION ++* set stp auto reset mdoe ++* DESCRIPTION ++* set stp auto reset mdoe ++* PARAMETERS ++* auto_rst: switch to auto reset mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst); ++ ++/*stp_psm support*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_notify_stp ++* DESCRIPTION ++* WMT notification to STP that power saving job is done or not ++* PARAMETERS ++* ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_notify_stp(const UINT32 action); ++ ++extern int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_enabla ++* DESCRIPTION ++* enable STP PSM ++* PARAMETERS ++* int idle_time_to_sleep: IDLE time to sleep ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_enable(int idle_time_to_sleep); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_disable ++* DESCRIPTION ++* disable STP PSM ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_disable(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_reset ++* DESCRIPTION ++* reset STP PSM (used on whole chip reset) ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_reset(void); ++extern void stp_do_tx_timeout(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_btm_get_dmp ++* DESCRIPTION ++* get stp dump related information ++* PARAMETERS ++* buffer: dump placement, len: dump size ++* RETURNS ++* 0: Success Negative Value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_btm_get_dmp(char *buf, int *len); ++ ++extern int mtk_wcn_stp_dbg_enable(void); ++ ++extern int mtk_wcn_stp_dbg_disable(void); ++ ++extern void mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type); ++ ++extern int mtk_wcn_sys_if_rx(UINT8 *data, INT32 size); ++ ++extern MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel); ++ ++extern INT32 mtk_wcn_stp_dbg_dump_package(VOID); ++ ++extern int stp_drv_init(void); ++ ++extern void stp_drv_exit(void); ++ ++extern INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on); ++ ++extern INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on); ++ ++extern INT32 mtk_wcn_stp_coredump_flag_get(VOID); ++extern INT32 mtk_wcn_stp_notify_sleep_for_thermal(void); ++ ++extern INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value); ++ ++/*stp btif API declared*/ ++extern INT32 mtk_wcn_stp_open_btif(VOID); ++extern INT32 mtk_wcn_stp_close_btif(VOID); ++extern INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb); ++extern INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len); ++extern INT32 mtk_wcn_stp_wakeup_consys(VOID); ++extern INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); ++extern INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); ++extern INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag); ++extern VOID mtk_wcn_stp_ctx_save(VOID); ++extern VOID mtk_wcn_stp_ctx_restore(VOID); ++extern INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(VOID); ++extern VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value); ++extern UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(VOID); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _STP_CORE_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h +new file mode 100644 +index 000000000000..94b3d8a597ac +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h +@@ -0,0 +1,89 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _STP_WMT_H ++#define _STP_WMT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum { ++ BTM_RST_OP = 0, ++ BTM_DMP_OP = 1, ++ BTM_GET_AEE_SUPPORT_FLAG = 2, ++ BTM_MAX_OP, ++} MTKSTP_BTM_WMT_OP_T; ++ ++typedef enum { ++ SLEEP = 0, ++ HOST_AWAKE, ++ WAKEUP, ++ EIRQ, ++ ROLL_BACK, ++ STP_PSM_MAX_ACTION ++} MTKSTP_PSM_ACTION_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++extern MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op); ++ ++extern INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action); ++extern MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _STP_WMT_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h +new file mode 100644 +index 000000000000..4c64b6b5e65b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h +@@ -0,0 +1,74 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_CONF_H_ ++#define _WMT_CONF_H_ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define CUST_CFG_WMT "WMT_SOC.cfg" ++#define CUST_CFG_WMT_PREFIX "/system/etc/firmware/" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_conf_read_file(VOID); ++P_WMT_GEN_CONF wmt_conf_get_cfg(VOID); ++INT32 wmt_conf_set_cfg_file(const char *name); ++ ++#endif /* _WMT_CONF_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h +new file mode 100644 +index 000000000000..cca52a15cc98 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h +@@ -0,0 +1,428 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_CORE_H_ ++#define _WMT_CORE_H_ ++ ++#include "osal.h" ++#include "wmt_ctrl.h" ++#include "wmt_exp.h" ++#include "wmt_plat.h" ++/* TODO: [GeorgeKuo][FixMe] remove temporarily */ ++/* for AIF state definition */ ++/* #include "mtk_wcn_cmb_stub.h" */ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++#define CFG_CORE_MT6620_SUPPORT 0 /* whether MT6620 is supported or not */ ++ ++#define CFG_CORE_MT6628_SUPPORT 0 /* whether MT6628 is supported or not */ ++ ++#define CFG_CORE_SOC_SUPPORT 1 ++ ++/* TODO:[ChangeFeature][George] move this definition outside so that wmt_dev can remove wmt_core.h inclusion. */ ++#define defaultPatchName "mt66xx_patch_hdr.bin" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define BCNT_PATCH_BUF_HEADROOM (8) ++ ++#define DWCNT_HIF_CONF (4) ++#define DWCNT_STRAP_CONF (4) ++#define DWCNT_RESERVED (8) ++#define DWCNT_CTRL_DATA (16) ++ ++#if 0 /* TODO: [obsolete][GeorgeKuo]: remove ubsolete definitions */ ++#define WMT_SET (1) ++#define WMT_QUERY (0) ++#define WMT_PKT_FMT_RAW (1) ++#define WMT_PKT_FMT_STP (0) ++#endif ++ ++#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE) ++#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE) ++ ++#define WMT_HDR_LEN (4) /* header length */ ++#define WMT_STS_LEN (1) /* status length */ ++#define WMT_FLAG_LEN (1) ++#define WMT_HIF_UART_INFO_LEN (4) ++#define WMT_FUNC_CTRL_PARAM_LEN (1) ++ ++#define WMT_DEFAULT_BAUD_RATE (115200) ++ ++#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_WMT_FM_T { ++ WMT_FM_INVALID = 0, ++ WMT_FM_I2C = 1, ++ WMT_FM_COMM = 2, ++ WMT_FM_MAX ++} ENUM_WMT_FM_T, *P_ENUM_WMT_FM_T; ++ ++typedef enum _ENUM_WMT_HIF_T { ++ WMT_HIF_UART = 0, ++ WMT_HIF_SDIO = 1, ++ WMT_HIF_BTIF = 2, ++ WMT_HIF_MAX ++} ENUM_WMT_HIF_T, *P_ENUM_WMT_HIF_T; ++ ++#if 0 /* [George] moved to wmt_exp.h for hif_sdio's use */ ++typedef enum { ++ WMT_SDIO_SLOT_INVALID = 0, ++ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ ++ WMT_SDIO_SLOT_SDIO2 = 2, ++ WMT_SDIO_SLOT_MAX ++} WMT_SDIO_SLOT_NUM; ++ ++typedef enum { ++ WMT_SDIO_FUNC_STP = 0, ++ WMT_SDIO_FUNC_WIFI = 1, ++ WMT_SDIO_FUNC_MAX ++} WMT_SDIO_FUNC_TYPE; ++#endif ++ ++typedef enum _ENUM_WMT_OPID_T { ++ WMT_OPID_HIF_CONF = 0, ++ WMT_OPID_PWR_ON = 1, ++ WMT_OPID_PWR_OFF = 2, ++ WMT_OPID_FUNC_ON = 3, ++ WMT_OPID_FUNC_OFF = 4, ++ WMT_OPID_REG_RW = 5, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ ++ WMT_OPID_EXIT = 6, ++ WMT_OPID_PWR_SV = 7, ++ WMT_OPID_DSNS = 8, ++ WMT_OPID_LPBK = 9, ++ WMT_OPID_CMD_TEST = 10, ++ WMT_OPID_HW_RST = 11, ++ WMT_OPID_SW_RST = 12, ++ WMT_OPID_BAUD_RST = 13, ++ WMT_OPID_STP_RST = 14, ++ WMT_OPID_THERM_CTRL = 15, ++ WMT_OPID_EFUSE_RW = 16, ++ WMT_OPID_GPIO_CTRL = 17, ++ WMT_OPID_FW_COREDMP = 18, ++ WMT_OPID_GPIO_STATE = 19, ++ WMT_OPID_BGW_DS = 20, ++ WMT_OPID_SET_MCU_CLK = 21, ++ WMT_OPID_ADIE_LPBK_TEST = 22, ++#if CFG_WMT_LTE_COEX_HANDLING ++ WMT_OPID_IDC_MSG_HANDLING = 23, ++#endif ++#ifdef CONFIG_MTK_COMBO_ANT ++ WMT_OPID_ANT_RAM_DOWN = 24, ++ WMT_OPID_ANT_RAM_STA_GET = 25, ++#endif ++ WMT_OPID_MAX ++} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T; ++ ++typedef OSAL_OP_DAT WMT_OP; ++typedef P_OSAL_OP_DAT P_WMT_OP; ++ ++typedef struct _WMT_HIF_CONF { ++ UINT32 hifType; /* HIF Type */ ++ UINT32 au4HifConf[DWCNT_HIF_CONF]; /* HIF Config */ ++ UINT32 au4StrapConf[DWCNT_STRAP_CONF]; /* Strap Config */ ++} WMT_HIF_CONF, *P_WMT_HIF_CONF; ++ ++typedef INT32(*WMT_OPID_FUNC) (P_WMT_OP); ++ ++typedef struct _WMT_GEN_CONF { ++ UINT8 cfgExist; ++ ++ UINT8 coex_wmt_ant_mode; ++ UINT8 coex_wmt_ext_component; ++ UINT8 coex_wmt_wifi_time_ctl; ++ UINT8 coex_wmt_ext_pta_dev_on; ++ /*mt6592 and LTE coex filter mode setting */ ++ UINT8 coex_wmt_filter_mode; ++ ++ UINT8 coex_bt_rssi_upper_limit; ++ UINT8 coex_bt_rssi_mid_limit; ++ UINT8 coex_bt_rssi_lower_limit; ++ UINT8 coex_bt_pwr_high; ++ UINT8 coex_bt_pwr_mid; ++ UINT8 coex_bt_pwr_low; ++ ++ UINT8 coex_wifi_rssi_upper_limit; ++ UINT8 coex_wifi_rssi_mid_limit; ++ UINT8 coex_wifi_rssi_lower_limit; ++ UINT8 coex_wifi_pwr_high; ++ UINT8 coex_wifi_pwr_mid; ++ UINT8 coex_wifi_pwr_low; ++ ++ UINT8 coex_ext_pta_hi_tx_tag; ++ UINT8 coex_ext_pta_hi_rx_tag; ++ UINT8 coex_ext_pta_lo_tx_tag; ++ UINT8 coex_ext_pta_lo_rx_tag; ++ UINT16 coex_ext_pta_sample_t1; ++ UINT16 coex_ext_pta_sample_t2; ++ UINT8 coex_ext_pta_wifi_bt_con_trx; ++ ++ UINT32 coex_misc_ext_pta_on; ++ UINT32 coex_misc_ext_feature_set; ++ /*GPS LNA setting */ ++ UINT8 wmt_gps_lna_pin; ++ UINT8 wmt_gps_lna_enable; ++ /*Power on sequence */ ++ UINT8 pwr_on_rtc_slot; ++ UINT8 pwr_on_ldo_slot; ++ UINT8 pwr_on_rst_slot; ++ UINT8 pwr_on_off_slot; ++ UINT8 pwr_on_on_slot; ++ UINT8 co_clock_flag; ++ ++ /* Combo chip side SDIO driving setting */ ++ UINT32 sdio_driving_cfg; ++ ++} WMT_GEN_CONF, *P_WMT_GEN_CONF; ++ ++typedef enum _ENUM_DRV_STS_ { ++#if 0 ++ DRV_STS_INVALID = 0, ++ DRV_STS_UNREG = 1, /* Initial State */ ++#endif ++ DRV_STS_POWER_OFF = 0, /* initial state */ ++ DRV_STS_POWER_ON = 1, /* powered on, only WMT */ ++ DRV_STS_FUNC_ON = 2, /* FUNC ON */ ++ DRV_STS_MAX ++} ENUM_DRV_STS, *P_ENUM_DRV_STS; ++ ++typedef enum _WMT_IC_PIN_ID_ { ++ WMT_IC_PIN_AUDIO = 0, ++ WMT_IC_PIN_EEDI = 1, ++ WMT_IC_PIN_EEDO = 2, ++ WMT_IC_PIN_GSYNC = 3, ++ WMT_IC_PIN_MAX ++} WMT_IC_PIN_ID, *P_WMT_IC_PIN_ID; ++ ++typedef enum _WMT_IC_PIN_STATE_ { ++ WMT_IC_PIN_EN = 0, ++ WMT_IC_PIN_DIS = 1, ++ WMT_IC_AIF_0 = 2, /* = CMB_STUB_AIF_0, */ ++ WMT_IC_AIF_1 = 3, /* = CMB_STUB_AIF_1, */ ++ WMT_IC_AIF_2 = 4, /* = CMB_STUB_AIF_2, */ ++ WMT_IC_AIF_3 = 5, /* = CMB_STUB_AIF_3, */ ++ WMT_IC_PIN_MUX = 6, ++ WMT_IC_PIN_GPIO = 7, ++ WMT_IC_PIN_GPIO_HIGH = 8, ++ WMT_IC_PIN_GPIO_LOW = 9, ++ WMT_IC_PIN_STATE_MAX ++} WMT_IC_PIN_STATE, *P_WMT_IC_PIN_STATE; ++ ++typedef enum _WMT_CO_CLOCK_ { ++ WMT_CO_CLOCK_DIS = 0, ++ WMT_CO_CLOCK_EN = 1, ++ WMT_CO_CLOCK_MAX ++} WMT_CO_CLOCK, *P_WMT_CO_CLOCK; ++ ++typedef INT32(*SW_INIT) (P_WMT_HIF_CONF pWmtHifConf); ++typedef INT32(*SW_DEINIT) (P_WMT_HIF_CONF pWmtHifConf); ++typedef INT32(*IC_PIN_CTRL) (WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); ++typedef INT32(*IC_VER_CHECK) (VOID); ++typedef INT32(*CO_CLOCK_CTRL) (WMT_CO_CLOCK on); ++typedef MTK_WCN_BOOL(*IS_QUICK_SLEEP_SUPPORT) (VOID); ++typedef MTK_WCN_BOOL(*IS_AEE_DUMP_SUPPORT) (VOID); ++ ++typedef struct _WMT_IC_OPS_ { ++ UINT32 icId; ++ SW_INIT sw_init; ++ SW_DEINIT sw_deinit; ++ IC_PIN_CTRL ic_pin_ctrl; ++ IC_VER_CHECK ic_ver_check; ++ CO_CLOCK_CTRL co_clock_ctrl; ++ IS_QUICK_SLEEP_SUPPORT is_quick_sleep; ++ IS_AEE_DUMP_SUPPORT is_aee_dump_support; ++} WMT_IC_OPS, *P_WMT_IC_OPS; ++ ++typedef struct _WMT_CTX_ { ++ ENUM_DRV_STS eDrvStatus[WMTDRV_TYPE_MAX]; /* Controlled driver status */ ++ UINT32 wmtInfoBit; /* valid info bit */ ++ WMT_HIF_CONF wmtHifConf; /* HIF information */ ++ ++ /* Pointer to WMT_IC_OPS. Shall be assigned to a correct table in stp_init ++ * if and only if getting chip id successfully. hwver and fwver are kept in ++ * WMT-IC module only. ++ */ ++ P_WMT_IC_OPS p_ic_ops; ++} WMT_CTX, *P_WMT_CTX; ++ ++/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ ++/* Using this struct relies on compiler's implementation and pack() settings */ ++typedef struct _WMT_PKT_ { ++ UINT8 eType; /* PKT_TYPE_* */ ++ UINT8 eOpCode; /* OPCODE_* */ ++ UINT16 u2SduLen; /* 2 bytes length, little endian */ ++ UINT8 aucParam[32]; ++} WMT_PKT, *P_WMT_PKT; ++ ++/* WMT Packet Format */ ++typedef enum _ENUM_PKT_TYPE { ++ PKT_TYPE_INVALID = 0, ++ PKT_TYPE_CMD = 1, ++ PKT_TYPE_EVENT = 2, ++ _PKT_TYPE_MAX ++} ENUM_PKT_TYPE, *P_ENUM_PKT_TYPE; ++ ++typedef enum _ENUM_OPCODE { ++ OPCODE_INVALID = 0, ++ OPCODE_PATCH = 1, ++ OPCODE_TEST = 2, ++ OPCODE_WAKEUP = 3, ++ OPCODE_HIF = 4, ++ OPCODE_STRAP_CONF = 5, ++ OPCODE_FUNC_CTRL = 6, ++ OPCODE_RESET = 7, ++ OPCODE_INT = 8, ++ OPCODE_MAX ++} ENUM_OPCODE, *P_ENUM_OPCODE; ++ ++typedef enum { ++ WMT_STP_CONF_EN = 0, ++ WMT_STP_CONF_RDY = 1, ++ WMT_STP_CONF_MODE = 2, ++ WMT_STP_CONF_MAX ++} WMT_STP_CONF_TYPE; ++ ++struct init_script { ++ UINT8 *cmd; ++ UINT32 cmdSz; ++ UINT8 *evt; ++ UINT32 evtSz; ++ UINT8 *str; ++}; ++ ++typedef struct _WMT_PATCH { ++ UINT8 ucDateTime[16]; ++ UINT8 ucPLat[4]; ++ UINT16 u2HwVer; ++ UINT16 u2SwVer; ++ UINT32 u4PatchVer; ++} WMT_PATCH, *P_WMT_PATCH; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if CFG_CORE_MT6620_SUPPORT ++extern WMT_IC_OPS wmt_ic_ops_mt6620; ++#endif ++ ++#if CFG_CORE_MT6628_SUPPORT ++extern WMT_IC_OPS wmt_ic_ops_mt6628; ++#endif ++ ++#if CFG_CORE_SOC_SUPPORT ++extern WMT_IC_OPS wmt_ic_ops_soc; ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern INT32 wmt_core_init(VOID); ++extern INT32 wmt_core_deinit(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmtd ++* DESCRIPTION ++* deinit STP kernel ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++extern INT32 wmt_core_opid(P_WMT_OP pWmtOp); ++ ++extern INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2); ++ ++extern INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn); ++ ++extern INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask); ++ ++extern VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len); ++ ++extern MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer); ++ ++extern INT32 wmt_core_init_script(struct init_script *script, INT32 count); ++ ++extern INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize); ++ ++extern INT32 wmt_core_tx(const PUINT8 pData, UINT32 size, PUINT32 writtenSize, MTK_WCN_BOOL bRawFlag); ++extern MTK_WCN_BOOL wmt_core_is_quick_ps_support(void); ++ ++extern MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void); ++ ++#if CFG_CORE_INTERNAL_TXRX ++extern INT32 wmt_core_lpbk_do_stp_init(void); ++extern INT32 wmt_core_lpbk_do_stp_deinit(void); ++#endif ++ ++extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state); ++#if CFG_WMT_LTE_COEX_HANDLING ++extern VOID wmt_core_set_flag_for_test(UINT32 enable); ++extern UINT32 wmt_core_get_flag_for_test(VOID); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static _osal_inline_ MTK_WCN_BOOL wmt_core_ic_ops_check(P_WMT_IC_OPS p_ops) ++{ ++ if (!p_ops) ++ return MTK_WCN_BOOL_FALSE; ++ ++ if ((NULL == p_ops->sw_init) ++ || (NULL == p_ops->sw_deinit) ++ || (NULL == p_ops->ic_ver_check) ++ || (NULL == p_ops->ic_pin_ctrl)) ++ return MTK_WCN_BOOL_FALSE; ++ else ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++#endif /* _WMT_CORE_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h +new file mode 100644 +index 000000000000..0ff3d6058c39 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h +@@ -0,0 +1,120 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_CTRL_H_ ++#define _WMT_CTRL_H_ ++ ++#include "osal.h" ++#include "wmt_stp_exp.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define DWCNT_CTRL_DATA (16) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _WMT_CTRL_DATA_ { ++ SIZE_T ctrlId; ++ SIZE_T au4CtrlData[DWCNT_CTRL_DATA]; ++} WMT_CTRL_DATA, *P_WMT_CTRL_DATA; ++ ++typedef enum _ENUM_WMT_CTRL_T { ++ WMT_CTRL_HW_PWR_OFF = 0, /* whole chip power off */ ++ WMT_CTRL_HW_PWR_ON = 1, /* whole chip power on */ ++ WMT_CTRL_HW_RST = 2, /* whole chip rst */ ++ WMT_CTRL_STP_CLOSE = 3, ++ WMT_CTRL_STP_OPEN = 4, ++ WMT_CTRL_STP_CONF = 5, ++ WMT_CTRL_FREE_PATCH = 6, ++ WMT_CTRL_GET_PATCH = 7, ++ WMT_CTRL_GET_PATCH_NAME = 8, ++ WMT_CTRL_HWIDVER_SET = 9, /* TODO: rename this and add chip id information in addition to chip version */ ++ WMT_CTRL_STP_RST = 10, ++ WMT_CTRL_GET_WMT_CONF = 11, ++ WMT_CTRL_TX = 12, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ ++ WMT_CTRL_RX = 13, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ ++ WMT_CTRL_RX_FLUSH = 14, /* [FixMe][SeanWang]: to be removed by Sean's stp integration */ ++ WMT_CTRL_GPS_SYNC_SET = 15, ++ WMT_CTRL_GPS_LNA_SET = 16, ++ WMT_CTRL_PATCH_SEARCH = 17, ++ WMT_CTRL_CRYSTAL_TRIMING_GET = 18, ++ WMT_CTRL_CRYSTAL_TRIMING_PUT = 19, ++ WMT_CTRL_HW_STATE_DUMP = 20, ++ WMT_CTRL_GET_PATCH_NUM = 21, ++ WMT_CTRL_GET_PATCH_INFO = 22, ++ WMT_CTRL_SOC_PALDO_CTRL = 23, ++ WMT_CTRL_SOC_WAKEUP_CONSYS = 24, ++ WMT_CTRL_SET_STP_DBG_INFO = 25, ++ WMT_CTRL_BGW_DESENSE_CTRL = 26, ++ WMT_CTRL_EVT_ERR_TRG_ASSERT = 27, ++#if CFG_WMT_LTE_COEX_HANDLING ++ WMT_CTRL_GET_TDM_REQ_ANTSEL = 28, ++#endif ++ WMT_CTRL_EVT_PARSER = 29, ++ WMT_CTRL_MAX ++} ENUM_WMT_CTRL_T, *P_ENUM_WMT_CTRL_T; ++ ++typedef INT32(*WMT_CTRL_FUNC) (P_WMT_CTRL_DATA); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData); ++ ++extern INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_CTRL_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h +new file mode 100644 +index 000000000000..d586f442e7ef +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h +@@ -0,0 +1,140 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_FUNC_H_ ++#define _WMT_FUNC_H_ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_core.h" ++#include "wmt_plat.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_HCI_DRIVER) || defined(CONFIG_MTK_COMBO_BT) */ ++#define CFG_FUNC_BT_SUPPORT 1 ++#else ++#define CFG_FUNC_BT_SUPPORT 0 ++#endif ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_FM) */ ++#define CFG_FUNC_FM_SUPPORT 1 ++#else ++#define CFG_FUNC_FM_SUPPORT 0 ++#endif ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_GPS) */ ++#define CFG_FUNC_GPS_SUPPORT 1 ++#else ++#define CFG_FUNC_GPS_SUPPORT 0 ++#endif ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_WIFI) */ ++#define CFG_FUNC_WIFI_SUPPORT 1 ++#else ++#define CFG_FUNC_WIFI_SUPPORT 0 ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef INT32(*SUBSYS_FUNC_ON) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++typedef INT32(*SUBSYS_FUNC_OFF) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++typedef struct _WMT_FUNC_OPS_ { ++ SUBSYS_FUNC_ON func_on; ++ SUBSYS_FUNC_OFF func_off; ++} WMT_FUNC_OPS, *P_WMT_FUNC_OPS; ++ ++typedef struct _CMB_PIN_CTRL_REG_ { ++ UINT32 regAddr; ++ UINT32 regValue; ++ UINT32 regMask; ++ ++} CMB_PIN_CTRL_REG, *P_CMB_PIN_CTRL_REG; ++ ++typedef struct _CMB_PIN_CTRL_ { ++ UINT32 pinId; ++ UINT32 regNum; ++ P_CMB_PIN_CTRL_REG pFuncOnArray; ++ P_CMB_PIN_CTRL_REG pFuncOffArray; ++ ++} CMB_PIN_CTRL, *P_CMB_PIN_CTRL; ++ ++typedef enum _ENUM_CMP_PIN_ID_ { ++ CMB_PIN_EEDI_ID = 0, ++ CMB_PIN_EEDO_ID = 1, ++ CMB_PIN_GSYNC_ID = 2, ++} ENUM_CMP_PIN_ID, *P_ENUM_CMP_PIN_ID; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if CFG_FUNC_BT_SUPPORT ++extern WMT_FUNC_OPS wmt_func_bt_ops; ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++extern WMT_FUNC_OPS wmt_func_fm_ops; ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++extern WMT_FUNC_OPS wmt_func_gps_ops; ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++extern WMT_FUNC_OPS wmt_func_wifi_ops; ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_FUNC_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h +new file mode 100644 +index 000000000000..901becfdb92f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h +@@ -0,0 +1,122 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_IC_H_ ++#define _WMT_IC_H_ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "wmt_core.h" ++#include "wmt_exp.h" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define WMT_IC_NAME_MT6620 "MT6620" ++#define WMT_IC_NAME_MT6628 "MT6628" ++#define WMT_IC_NAME_DEFAULT "SOC_CONSYS" ++ ++#define WMT_IC_VER_E1 "E1" ++#define WMT_IC_VER_E2 "E2" ++#define WMT_IC_VER_E3 "E3" ++#define WMT_IC_VER_E4 "E4" ++#define WMT_IC_VER_E5 "E5" ++#define WMT_IC_VER_E6 "E6" ++ ++#define WMT_IC_PATCH_DUMMY_EXT "_ex" ++#define WMT_IC_PATCH_NO_EXT "" ++#define WMT_IC_PATCH_E1_EXT "_e1" ++#define WMT_IC_PATCH_E2_EXT "_e2" ++#define WMT_IC_PATCH_E3_EXT "_e3" ++#define WMT_IC_PATCH_E4_EXT "_e4" ++#define WMT_IC_PATCH_E5_EXT "_e5" ++#define WMT_IC_PATCH_E6_EXT "_e6" ++ ++#define WMT_IC_PATCH_TAIL "_hdr.bin" ++ ++#define WMT_IC_INVALID_CHIP_ID 0xFFFF ++ ++#define MAJORNUM(x) (x & 0x00F0) ++#define MINORNUM(x) (x & 0x000F) ++ ++/******************************************************************************* ++* R E G I S T E R M A P ++******************************************************************************** ++*/ ++/* General definition used for ALL/UNKNOWN CHIPS */ ++/* Now MT6620 uses these definitions */ ++#define GEN_CONFG_BASE (0x80000000UL) ++#define GEN_HVR (GEN_CONFG_BASE + 0x0UL) /* HW_VER */ ++#define GEN_FVR (GEN_CONFG_BASE + 0x4UL) /* FW_VER */ ++#define GEN_VER_MASK (0x0000FFFFUL) /* HW_VER and FW_VER valid bits mask */ ++#define GEN_HCR (GEN_CONFG_BASE + 0x8UL) /* HW_CODE, chip id */ ++#define GEN_HCR_MASK (0x0000FFFFUL) /* HW_CODE valid bits mask */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _WMT_IC_INFO_S { ++ UINT32 u4HwVer; /* u4HwId */ ++ PUINT8 cChipName; ++ PUINT8 cChipVersion; ++ PUINT8 cPatchNameExt; ++ MTK_WCN_BOOL bPsmSupport; ++ MTK_WCN_BOOL bWorkWithoutPatch; ++ ENUM_WMTHWVER_TYPE_T eWmtHwVer; ++} WMT_IC_INFO_S, *P_WMT_IC_INFO_S; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_IC_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h +new file mode 100644 +index 000000000000..b0c05cf3a252 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h +@@ -0,0 +1,300 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_LIB_H_ ++#define _WMT_LIB_H_ ++ ++#include "osal.h" ++#include "wmt_core.h" ++#include "wmt_exp.h" ++#include ++#include "stp_wmt.h" ++#include "wmt_plat.h" ++#include "wmt_idc.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define WMT_OP_BUF_SIZE (16) ++ ++typedef enum _ENUM_WMTRSTRET_TYPE_T { ++ WMTRSTRET_SUCCESS = 0x0, ++ WMTRSTRET_FAIL = 0x1, ++ WMTRSTRET_ONGOING = 0x2, ++ WMTRSTRET_MAX ++} ENUM_WMTRSTRET_TYPE_T, *P_ENUM_WMTRSTRET_TYPE_T; ++ ++/* ++3(retry times) * 180 (STP retry time out) +++ 10 (firmware process time) + ++10 (transmit time) + ++10 (uart process -> WMT response pool) + ++230 (others) ++*/ ++#define WMT_LIB_RX_TIMEOUT 20000 /*800-->cover v1.2phone BT function on time (~830ms) */ ++/* ++open wifi during wifi power on procedure ++(because wlan is insert to system after mtk_hif_sdio module, ++so wifi card is not registered to hif module ++when mtk_wcn_wmt_func_on is called by wifi through rfkill) ++*/ ++#define MAX_WIFI_ON_TIME 55000 ++ ++#define WMT_PWRON_RTY_DFT 2 ++#define MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT (WMT_PWRON_RTY_DFT * WMT_LIB_RX_TIMEOUT) ++#define MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY WMT_LIB_RX_TIMEOUT /*each WMT command */ ++#define MAX_FUNC_ON_TIME \ ++ (MAX_WIFI_ON_TIME + MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT + MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY * 3) ++ ++#define MAX_EACH_FUNC_OFF (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ ++#define MAX_FUNC_OFF_TIME (MAX_EACH_FUNC_OFF * 4) ++ ++#define MAX_EACH_WMT_CMD (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ ++ ++#define MAX_GPIO_CTRL_TIME (2000) /* [FixMe][GeorgeKuo] a temp value */ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* AIF FLAG definition */ ++/* bit(0): share pin or not */ ++#define WMT_LIB_AIF_FLAG_MASK (0x1UL) ++#define WMT_LIB_AIF_FLAG_SHARE (0x1UL << 0) ++#define WMT_LIB_AIF_FLAG_SEPARATE (0x0UL << 0) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* bit field offset definition */ ++typedef enum { ++ WMT_STAT_PWR = 0, /* is powered on */ ++ WMT_STAT_STP_REG = 1, /* is STP driver registered: */ ++ WMT_STAT_STP_OPEN = 2, /* is STP opened: default FALSE */ ++ WMT_STAT_STP_EN = 3, /* is STP enabled: default FALSE */ ++ WMT_STAT_STP_RDY = 4, /* is STP ready for client: default FALSE */ ++ WMT_STAT_RX = 5, /* is rx data available */ ++ WMT_STAT_CMD = 6, /* is cmd string to be read */ ++ WMT_STAT_RST_ON = 7, ++ WMT_STAT_MAX ++} WMT_STAT; ++ ++typedef enum _ENUM_WMTRSTSRC_TYPE_T { ++ WMTRSTSRC_RESET_BT = 0x0, ++ WMTRSTSRC_RESET_FM = 0x1, ++ WMTRSTSRC_RESET_GPS = 0x2, ++ WMTRSTSRC_RESET_WIFI = 0x3, ++ WMTRSTSRC_RESET_STP = 0x4, ++ WMTRSTSRC_RESET_TEST = 0x5, ++ WMTRSTSRC_RESET_MAX ++} ENUM_WMTRSTSRC_TYPE_T, *P_ENUM_WMTRSTSRC_TYPE_T; ++ ++typedef struct { ++ PF_WMT_CB fDrvRst[4]; ++} WMT_FDRV_CB, *P_WMT_FDRV_CB; ++ ++typedef struct { ++ UINT32 dowloadSeq; ++ UINT8 addRess[4]; ++ UINT8 patchName[256]; ++} WMT_PATCH_INFO, *P_WMT_PATCH_INFO; ++ ++/* OS independent wrapper for WMT_OP */ ++typedef struct _DEV_WMT_ { ++ ++ OSAL_SLEEPABLE_LOCK psm_lock; ++ OSAL_SLEEPABLE_LOCK idc_lock; ++ /* WMTd thread information */ ++ /* struct task_struct *pWmtd; */ ++ OSAL_THREAD thread; /* main thread (wmtd) handle */ ++ /* wait_queue_head_t rWmtdWq; */ ++ OSAL_EVENT rWmtdWq; /*WMTd command wait queue */ ++ /* ULONG state; */ ++ OSAL_BIT_OP_VAR state; /* bit field of WMT_STAT */ ++ ++ /* STP context information */ ++ /* wait_queue_head_t rWmtRxWq; */ ++ OSAL_EVENT rWmtRxWq; /* STP Rx wait queue */ ++ /* WMT_STP_FUNC rStpFunc; */ ++ WMT_FDRV_CB rFdrvCb; /* STP functions */ ++ ++ /* WMT Configurations */ ++ WMT_HIF_CONF rWmtHifConf; ++ WMT_GEN_CONF rWmtGenConf; ++ ++ /* Patch information */ ++ UINT8 cPatchName[NAME_MAX + 1]; ++ UINT8 cFullPatchName[NAME_MAX + 1]; ++ UINT32 patchNum; ++ ++ const osal_firmware *pPatch; ++ ++ UINT8 cWmtcfgName[NAME_MAX + 1]; ++ const osal_firmware *pWmtCfg; ++ ++ const osal_firmware *pNvram; ++ ++ /* Current used UART port description */ ++ INT8 cUartName[NAME_MAX + 1]; ++ ++ OSAL_OP_Q rFreeOpQ; /* free op queue */ ++ OSAL_OP_Q rActiveOpQ; /* active op queue */ ++ OSAL_OP arQue[WMT_OP_BUF_SIZE]; /* real op instances */ ++ P_OSAL_OP pCurOP; /* current op */ ++ ++ /* cmd str buffer */ ++ UINT8 cCmd[NAME_MAX + 1]; ++ INT32 cmdResult; ++ /* struct completion cmd_comp; */ ++ /* wait_queue_head_t cmd_wq; */ ++ OSAL_SIGNAL cmdResp; /* read command queues */ ++ OSAL_EVENT cmdReq; ++ ++ /* WMT loopback Thread Information */ ++ /* WMT_CMB_VER combo_ver; */ ++ /* P_WMT_CMB_CHIP_INFO_S pChipInfo; */ ++ UINT32 chip_id; ++ UINT32 hw_ver; ++ UINT32 fw_ver; ++ /* TODO: [FixMe][GeorgeKuo] remove this translated version code in the */ ++ /* future. Just return the above 3 info to querist */ ++ ENUM_WMTHWVER_TYPE_T eWmtHwVer; ++ ++ P_WMT_PATCH_INFO pWmtPatchInfo; ++} DEV_WMT, *P_DEV_WMT; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern DEV_WMT gDevWmt; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++extern INT32 wmt_lib_init(VOID); ++extern INT32 wmt_lib_deinit(VOID); ++extern INT32 wmt_lib_tx(PUINT8 data, UINT32 size, PUINT32 writtenSize); ++extern INT32 wmt_lib_tx_raw(PUINT8 data, UINT32 size, PUINT32 writtenSize); ++extern INT32 wmt_lib_rx(PUINT8 buff, UINT32 buffLen, PUINT32 readSize); ++extern VOID wmt_lib_flush_rx(VOID); ++ ++#if CFG_WMT_PS_SUPPORT ++extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime); ++extern INT32 wmt_lib_ps_init(VOID); ++extern INT32 wmt_lib_ps_deinit(VOID); ++extern INT32 wmt_lib_ps_enable(VOID); ++extern INT32 wmt_lib_ps_ctrl(UINT32 state); ++ ++extern INT32 wmt_lib_ps_disable(VOID); ++extern VOID wmt_lib_ps_irq_cb(VOID); ++#endif ++extern VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb); ++ ++/* LXOP functions: */ ++extern P_OSAL_OP wmt_lib_get_free_op(VOID); ++extern INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp); ++extern MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp); ++ ++/* extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); */ ++extern UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T type); ++ ++extern MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID); ++extern MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID); ++extern INT32 wmt_lib_trigger_cmd_signal(INT32 result); ++extern PUINT8 wmt_lib_get_cmd(VOID); ++extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID); ++extern INT32 wmt_lib_set_patch_name(PUINT8 cPatchName); ++extern INT32 wmt_lib_set_hif(unsigned long hifconf); ++extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID); ++extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID); ++ ++/* GeorgeKuo: replace set_chip_gpio() with more specific ones */ ++#if 0 /* moved to wmt_exp.h */ ++extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ ++#endif ++extern INT32 wmt_lib_host_awake_get(VOID); ++extern INT32 wmt_lib_host_awake_put(VOID); ++extern UINT32 wmt_lib_dbg_level_set(UINT32 level); ++ ++extern INT32 wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++ ++extern INT32 wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src); ++MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst); ++MTK_WCN_BOOL wmt_lib_hw_rst(VOID); ++INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); ++INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); ++ ++extern INT32 DISABLE_PSM_MONITOR(void); ++extern VOID ENABLE_PSM_MONITOR(void); ++extern INT32 wmt_lib_notify_stp_sleep(void); ++extern void wmt_lib_psm_lock_release(void); ++extern INT32 wmt_lib_psm_lock_aquire(void); ++extern VOID wmt_lib_idc_lock_release(VOID); ++extern INT32 wmt_lib_idc_lock_aquire(VOID); ++extern INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value); ++ ++extern VOID wmt_lib_set_patch_num(UINT32 num); ++extern VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo); ++extern INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp); ++extern P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev); ++extern PUINT8 wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, PUINT8 buff, UINT32 len); ++extern INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee); ++extern PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 len); ++extern INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl); ++extern UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en); ++extern INT8 wmt_lib_co_clock_get(VOID); ++extern UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver); ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++extern MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor); ++#endif ++#if CFG_WMT_PS_SUPPORT ++extern UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en); ++#endif ++#if CONSYS_ENALBE_SET_JTAG ++extern UINT32 wmt_lib_jtag_flag_set(UINT32 en); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_LIB_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c +new file mode 100644 +index 000000000000..f37da4761009 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c +@@ -0,0 +1,1889 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "psm_core.h" ++#include "stp_core.h" ++#include ++ ++INT32 gPsmDbgLevel = STP_PSM_LOG_INFO; ++MTKSTP_PSM_T stp_psm_i; ++MTKSTP_PSM_T *stp_psm = &stp_psm_i; ++ ++STP_PSM_RECORD_T *g_stp_psm_dbg = NULL; ++static UINT32 g_record_num; ++ ++P_STP_PSM_OPID_RECORD g_stp_psm_opid_dbg = NULL; ++static UINT32 g_opid_record_num; ++ ++#define STP_PSM_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) \ ++ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ ++ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_INFO) \ ++ pr_debug(PFX_PSM "[I]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_WARN) \ ++ pr_warn(PFX_PSM "[W]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_ERR) \ ++ pr_err(PFX_PSM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define STP_PSM_TRC_FUNC(f) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ ++ pr_debug(PFX_PSM "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); ++static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); ++static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); ++static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num); ++static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg); ++ ++static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num); ++static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg); ++ ++static const char *g_psm_state[STP_PSM_MAX_STATE] = { ++ "ACT", ++ "ACT_INACT", ++ "INACT", ++ "INACT_ACT" ++}; ++ ++static const char *g_psm_action[STP_PSM_MAX_ACTION] = { ++ "SLEEP", ++ "HOST_AWAKE", ++ "WAKEUP", ++ "EIRQ", ++ "ROLL_BACK" ++}; ++ ++static const char *g_psm_op_name[STP_OPID_PSM_NUM] = { ++ "STP_OPID_PSM_SLEEP", ++ "STP_OPID_PSM_WAKEUP", ++ "STP_OPID_PSM_HOST_AWAKE", ++ "STP_OPID_PSM_EXIT" ++}; ++ ++static int _stp_psm_release_data(MTKSTP_PSM_T *stp_psm); ++ ++static inline int _stp_psm_get_state(MTKSTP_PSM_T *stp_psm); ++ ++static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ); ++ ++static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ); ++static MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID); ++ ++MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel) ++{ ++ if (dbglevel <= 4) { ++ gPsmDbgLevel = dbglevel; ++ STP_PSM_INFO_FUNC("gPsmDbgLevel = %d\n", gPsmDbgLevel); ++ return true; ++ } ++ STP_PSM_INFO_FUNC("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel); ++ ++ return false; ++} ++ ++static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp) ++{ ++ INT32 ret = -1; ++ ++ /* if (NULL == pStpOp) */ ++ /* { */ ++ /* return -1; */ ++ /* } */ ++ ret = _stp_psm_thread_lock_aquire(stp_psm); ++ if (ret) { ++ STP_PSM_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); ++ return ret; ++ } ++ ++ switch (pStpOp->opId) { ++ case STP_OPID_PSM_EXIT: ++ /* TODO: clean all up? */ ++ ret = 0; ++ break; ++ ++ case STP_OPID_PSM_SLEEP: ++ if (stp_psm_check_sleep_enable(stp_psm) > 0) ++ ret = _stp_psm_notify_wmt(stp_psm, SLEEP); ++ else ++ STP_PSM_INFO_FUNC("cancel sleep request\n"); ++ ++ break; ++ ++ case STP_OPID_PSM_WAKEUP: ++ ret = _stp_psm_notify_wmt(stp_psm, WAKEUP); ++ break; ++ ++ case STP_OPID_PSM_HOST_AWAKE: ++ ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE); ++ break; ++ ++ default: ++ STP_PSM_ERR_FUNC("invalid operation id (%d)\n", pStpOp->opId); ++ ret = -1; ++ break; ++ } ++ _stp_psm_thread_lock_release(stp_psm); ++ return ret; ++} ++ ++static P_OSAL_OP _stp_psm_get_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ) ++{ ++ P_OSAL_OP pOp; ++ ++ if (!pOpQ) { ++ STP_PSM_WARN_FUNC("pOpQ == NULL\n"); ++ return NULL; ++ } ++ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ /* acquire lock success */ ++ RB_GET(pOpQ, pOp); ++ ++ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) { ++ /* stp_psm->current_active_op = pOp; */ ++ stp_psm->last_active_opId = pOp->op.opId; ++ } ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ ++ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) ++ STP_PSM_DBG_FUNC("last_active_opId(%d)\n", stp_psm->last_active_opId); ++ ++ if (!pOp) ++ STP_PSM_WARN_FUNC("RB_GET fail\n"); ++ ++ return pOp; ++} ++ ++static INT32 _stp_psm_dump_active_q(P_OSAL_OP_Q pOpQ) ++{ ++ UINT32 read_idx; ++ UINT32 write_idx; ++ UINT32 opId; ++ ++ if (pOpQ == &stp_psm->rActiveOpQ) { ++ read_idx = stp_psm->rActiveOpQ.read; ++ write_idx = stp_psm->rActiveOpQ.write; ++ ++ STP_PSM_DBG_FUNC("Active op list:++\n"); ++ while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ))) { ++ opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId; ++ if (opId < STP_OPID_PSM_NUM) ++ STP_PSM_DBG_FUNC("%s\n", g_psm_op_name[opId]); ++ else ++ STP_PSM_WARN_FUNC("Unknown OP Id\n"); ++ ++ ++read_idx; ++ } ++ STP_PSM_DBG_FUNC("Active op list:--\n"); ++ } else { ++ STP_PSM_DBG_FUNC("%s: not active queue, dont dump\n", __func__); ++ } ++ ++ return 0; ++} ++ ++static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ) ++{ ++ unsigned int opId = 0; ++ unsigned int prev_opId = 0; ++ ++ /* if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op)) */ ++ if ((pOpQ == &stp_psm->rActiveOpQ) && (STP_OPID_PSM_INALID != stp_psm->last_active_opId)) { ++ opId = pOp->op.opId; ++ ++ if (opId == STP_OPID_PSM_SLEEP) { ++ if (RB_EMPTY(pOpQ)) { ++ /* prev_opId = stp_psm->current_active_op->op.opId; */ ++ prev_opId = stp_psm->last_active_opId; ++ } else { ++ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; ++ } ++ ++ if (prev_opId == STP_OPID_PSM_SLEEP) { ++ STP_PSM_DBG_FUNC("redundant sleep opId found\n"); ++ return 1; ++ } else { ++ return 0; ++ } ++ } else { ++ if (RB_EMPTY(pOpQ)) { ++ /* prev_opId = stp_psm->current_active_op->op.opId; */ ++ prev_opId = stp_psm->last_active_opId; ++ } else { ++ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; ++ } ++ ++ if (((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_WAKEUP)) || ++ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_WAKEUP)) || ++ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) || ++ ((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) ++ ) { ++ STP_PSM_DBG_FUNC("redundant opId found, opId(%d), preOpid(%d)\n", opId, prev_opId); ++ return 1; ++ } else { ++ return 0; ++ } ++ } ++ } else { ++ return 0; ++ } ++ ++} ++ ++static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ) ++{ ++ unsigned int prev_opId = 0; ++ unsigned int prev_prev_opId = 0; ++ ++ P_OSAL_OP pOp; ++ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; ++ ++ if (pOpQ == &stp_psm->rActiveOpQ) { ++ /* sleep , wakeup | sleep, --> null | sleep (x) */ ++ /* wakeup , sleep , wakeup | sleep --> wakeup | sleep (v) */ ++ /* sleep , wakeup , sleep | wakeup --> sleep | wakeup (v) */ ++ /* xxx, sleep | sleep --> xxx, sleep (v) */ ++ /* xxx, wakeup | wakeup --> xxx, wakeup (v) */ ++ /* xxx, awake | awake --> xxx, awake (v) --> should never happen */ ++ while (RB_COUNT(pOpQ) > 2) { ++ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; ++ prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId; ++ ++ if ((prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_WAKEUP) || ++ (prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) || ++ (prev_opId == STP_OPID_PSM_WAKEUP && prev_prev_opId == STP_OPID_PSM_SLEEP) || ++ (prev_opId == STP_OPID_PSM_HOST_AWAKE && prev_prev_opId == STP_OPID_PSM_SLEEP) ++ ) { ++ RB_GET(pOpQ, pOp); ++ RB_PUT(pFreeOpQ, pOp); ++ RB_GET(pOpQ, pOp); ++ RB_PUT(pFreeOpQ, pOp); ++ } else if (prev_opId == prev_prev_opId) { ++ RB_GET(pOpQ, pOp); ++ STP_PSM_DBG_FUNC("redundant opId(%d) found, remove it\n", pOp->op.opId); ++ RB_PUT(pFreeOpQ, pOp); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static INT32 _stp_psm_put_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) ++{ ++ INT32 ret; ++ ++ /* if (!pOpQ || !pOp) */ ++ /* { */ ++ /* STP_PSM_WARN_FUNC("pOpQ = 0x%p, pLxOp = 0x%p\n", pOpQ, pOp); */ ++ /* return 0; */ ++ /* } */ ++ ret = 0; ++ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ /* acquire lock success */ ++ if (pOpQ == &stp_psm->rActiveOpQ) { ++ if (!_stp_psm_is_redundant_active_op(pOp, pOpQ)) { ++ /* acquire lock success */ ++ if (!RB_FULL(pOpQ)) { ++ RB_PUT(pOpQ, pOp); ++ STP_PSM_DBG_FUNC("opId(%d) enqueue\n", pOp->op.opId); ++ } else { ++ STP_PSM_INFO_FUNC("************ Active Queue Full ************\n"); ++ ret = -1; ++ } ++ ++ _stp_psm_clean_up_redundant_active_op(pOpQ); ++ } else { ++ /*redundant opId, mark ret as success */ ++ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; ++ ++ if (!RB_FULL(pFreeOpQ)) ++ RB_PUT(pFreeOpQ, pOp); ++ else ++ osal_assert(!RB_FULL(pFreeOpQ)); ++ ++ ret = 0; ++ } ++ } else { ++ if (!RB_FULL(pOpQ)) ++ RB_PUT(pOpQ, pOp); ++ else ++ ret = -1; ++ ++ } ++ ++ if (pOpQ == &stp_psm->rActiveOpQ) ++ _stp_psm_dump_active_q(&stp_psm->rActiveOpQ); ++ ++ ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ STP_PSM_DBG_FUNC("stp_psm do unlock,active queue? (%s)\n", (pOpQ == &stp_psm->rActiveOpQ) ? "y" : "n"); ++ ++ if (ret) { ++ STP_PSM_WARN_FUNC("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n", RB_COUNT(pOpQ), RB_SIZE(pOpQ)); ++ return 0; ++ } else ++ return 1; ++ ++} ++ ++P_OSAL_OP _stp_psm_get_free_op(MTKSTP_PSM_T *stp_psm) ++{ ++ P_OSAL_OP pOp; ++ ++ if (stp_psm) { ++ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ); ++ if (pOp) ++ osal_memset(&pOp->op, 0, sizeof(pOp->op)); ++ ++ return pOp; ++ } else ++ return NULL; ++ ++} ++ ++INT32 _stp_psm_put_act_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP pOp) ++{ ++ INT32 bRet = 0; /* MTK_WCN_BOOL_FALSE; */ ++ INT32 bCleanup = 0; /* MTK_WCN_BOOL_FALSE; */ ++ INT32 wait_ret = -1; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ do { ++ if (!stp_psm || !pOp) { ++ STP_PSM_ERR_FUNC("stp_psm = %p, pOp = %p\n", stp_psm, pOp); ++ break; ++ } ++ ++ pSignal = &pOp->signal; ++ ++ if (pSignal->timeoutValue) { ++ pOp->result = -9; ++ osal_signal_init(&pOp->signal); ++ } ++ ++ /* put to active Q */ ++ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp); ++ ++ if (0 == bRet) { ++ STP_PSM_WARN_FUNC("+++++++++++ Put op Active queue Fail\n"); ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ break; ++ } ++ _stp_psm_opid_dbg_dmp_in(g_stp_psm_opid_dbg, pOp->op.opId, __LINE__); ++ ++ /* wake up wmtd */ ++ osal_trigger_event(&stp_psm->STPd_event); ++ ++ if (pSignal->timeoutValue == 0) { ++ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ ++ /* clean it in wmtd */ ++ break; ++ } ++ ++ /* wait result, clean it here */ ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ ++ /* check result */ ++ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); ++ STP_PSM_DBG_FUNC("wait completion:%d\n", wait_ret); ++ if (!wait_ret) { ++ STP_PSM_ERR_FUNC("wait completion timeout\n"); ++ /* TODO: how to handle it? retry? */ ++ } else { ++ if (pOp->result) ++ STP_PSM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); ++ /* op completes, check result */ ++ bRet = (pOp->result) ? 0 : 1; ++ } ++ } while (0); ++ ++ if (bCleanup) { ++ /* put Op back to freeQ */ ++ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp); ++ if (bRet == 0) ++ STP_PSM_WARN_FUNC("+++++++++++ Put op active free fail, maybe disable/enable psm\n"); ++ } ++ ++ return bRet; ++} ++ ++static INT32 _stp_psm_wait_for_msg(void *pvData) ++{ ++ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; ++ ++ STP_PSM_DBG_FUNC("%s: stp_psm->rActiveOpQ = %d\n", __func__, RB_COUNT(&stp_psm->rActiveOpQ)); ++ ++ return (!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd); ++} ++ ++static INT32 _stp_psm_proc(void *pvData) ++{ ++ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; ++ P_OSAL_OP pOp; ++ UINT32 id; ++ INT32 result; ++ ++ if (!stp_psm) { ++ STP_PSM_WARN_FUNC("!stp_psm\n"); ++ return -1; ++ } ++/* STP_PSM_INFO_FUNC("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d]\n", */ ++/* stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio); */ ++ ++ for (;;) { ++ ++ pOp = NULL; ++ ++ osal_wait_for_event(&stp_psm->STPd_event, _stp_psm_wait_for_msg, (void *)stp_psm); ++ ++ /* we set reset flag when calling stp_reset after cleanup all op. */ ++ if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_RESET_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } ++ if (osal_thread_should_stop(&stp_psm->PSMd)) { ++ STP_PSM_INFO_FUNC("should stop now...\n"); ++ /* TODO: clean up active opQ */ ++ break; ++ } ++ ++ /* get Op from activeQ */ ++ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n"); ++ continue; ++ } ++ ++ id = osal_op_get_id(pOp); ++ ++ if (id >= STP_OPID_PSM_NUM) { ++ STP_PSM_WARN_FUNC("abnormal opid id: 0x%x\n", id); ++ result = -1; ++ goto handler_done; ++ } ++ ++ result = _stp_psm_handler(stp_psm, &pOp->op); ++ ++handler_done: ++ ++ if (result) { ++ STP_PSM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, ++ (id >= 4) ? ("???") : (g_psm_op_name[id]), result); ++ } ++ ++ if (osal_op_is_wait_for_signal(pOp)) ++ osal_op_raise_signal(pOp, result); ++ else { ++ /* put Op back to freeQ */ ++ if (_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0) ++ STP_PSM_WARN_FUNC("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n"); ++ } ++ ++ if (STP_OPID_PSM_EXIT == id) ++ break; ++ } ++ STP_PSM_INFO_FUNC("exits\n"); ++ ++ return 0; ++}; ++ ++static inline INT32 _stp_psm_get_time(void) ++{ ++ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) ++ osal_printtimeofday(">>>"); ++ ++ return 0; ++} ++ ++static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (stp_psm->work_state < STP_PSM_MAX_STATE) ++ return stp_psm->work_state; ++ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); ++ ++ return STP_PSM_OPERATION_FAIL; ++} ++ ++static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_STATE_T state) ++{ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (stp_psm->work_state < STP_PSM_MAX_STATE) { ++ _stp_psm_get_time(); ++ /* STP_PSM_INFO_FUNC("work_state = %s --> %s\n", ++ * g_psm_state[stp_psm->work_state], g_psm_state[state]); ++ */ ++ ++ stp_psm->work_state = state; ++ if (stp_psm->work_state != ACT) { ++ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ osal_set_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ } ++ } else ++ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); ++ ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { ++ STP_PSM_DBG_FUNC("STP-PSM DISABLE, DONT restart monitor!\n\r"); ++ return STP_PSM_OPERATION_SUCCESS; ++ } ++ ++ STP_PSM_LOUD_FUNC("start monitor\n"); ++ osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_DBG_FUNC("stop monitor\n"); ++ osal_timer_stop_sync(&stp_psm->psm_timer); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++INT32 _stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) ++{ ++ INT32 available_space = 0; ++ INT32 needed_space = 0; ++ UINT8 delimiter[] = { 0xbb, 0xbb }; ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ available_space = STP_PSM_FIFO_SIZE - osal_fifo_len(&stp_psm->hold_fifo); ++ needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2; ++ ++ /* STP_PSM_INFO_FUNC("*******FIFO Available(%d), Need(%d)\n", available_space, needed_space); */ ++ ++ if (available_space < needed_space) { ++ STP_PSM_ERR_FUNC("FIFO Available!! Reset FIFO\n"); ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ } ++ /* type */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); ++ /* length */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); ++ /* buffer */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) buffer, len); ++ /* delimiter */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); ++ ++ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ return len; ++ ++} ++ ++INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) ++{ ++ return osal_fifo_len(&stp_psm->hold_fifo); ++} ++ ++INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ INT32 i = 20; /*Max buffered packet number */ ++ INT32 ret = 0; ++ UINT8 type = 0; ++ UINT32 len = 0; ++ UINT8 delimiter[2]; ++ ++ /* STP_PSM_ERR_FUNC("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo)); */ ++ while (osal_fifo_len(&stp_psm->hold_fifo) && i > 0) { ++ /* acquire spinlock */ ++ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); ++ ++ if (len > STP_PSM_PACKET_SIZE_MAX) { ++ STP_PSM_ERR_FUNC("***psm packet's length too Long!****\n"); ++ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); ++ } else { ++ osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE); ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) stp_psm->out_buf, len); ++ } ++ ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); ++ ++ if (delimiter[0] == 0xbb && delimiter[1] == 0xbb) { ++ /* osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32); */ ++ stp_send_data_no_ps(stp_psm->out_buf, len, type); ++ } else { ++ STP_PSM_ERR_FUNC("***psm packet fifo parsing fail****\n"); ++ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); ++ ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ } ++ i--; ++ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ } ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ pOp = _stp_psm_get_free_op(stp_psm); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = STP_OPID_PSM_HOST_AWAKE; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_psm_put_act_op(stp_psm, pOp); ++ ++ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ ++ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ pOp = _stp_psm_get_free_op(stp_psm); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = STP_OPID_PSM_WAKEUP; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_psm_put_act_op(stp_psm, pOp); ++ if (0 == bRet) { ++ STP_PSM_WARN_FUNC("OPID(%d) type(%zd) bRet(%s)\n\n", ++ pOp->op.opId, pOp->op.au4OpData[0], "fail"); ++ } ++ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS); ++ ++ return retval; ++} ++ ++static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag)) ++ return 0; ++#if PSM_USE_COUNT_PACKAGE ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag)) ++ return 0; ++#endif ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) ++ return 0; ++ ++ pOp = _stp_psm_get_free_op(stp_psm); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = STP_OPID_PSM_SLEEP; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_psm_put_act_op(stp_psm, pOp); ++ ++ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ ++ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 1; ++ ++ return retval; ++} ++ ++/*internal function*/ ++ ++static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 i = 0; ++ P_OSAL_OP_Q pOpQ; ++ P_OSAL_OP pOp; ++ ++ STP_PSM_DBG_FUNC("PSM MODE RESET=============================>\n\r"); ++ ++ STP_PSM_DBG_FUNC("_stp_psm_reset\n"); ++ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_unlock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ ++ /* --> disable psm <--// */ ++ stp_psm->flag.data = 0; ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ _stp_psm_stop_monitor(stp_psm); ++ ++ /* --> prepare the op list <--// */ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); ++ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); ++ ++ /* stp_psm->current_active_op = NULL; */ ++ stp_psm->last_active_opId = STP_OPID_PSM_INALID; ++ ++ pOpQ = &stp_psm->rFreeOpQ; ++ for (i = 0; i < STP_OP_BUF_SIZE; i++) { ++ if (!RB_FULL(pOpQ)) { ++ pOp = &stp_psm->arQue[i]; ++ RB_PUT(pOpQ, pOp); ++ } ++ } ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ ++ /* --> clean up interal data structure<--// */ ++ _stp_psm_set_state(stp_psm, ACT); ++ ++ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ /* --> stop psm thread wait <--// */ ++ osal_set_bit(STP_PSM_RESET_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ ++ STP_PSM_DBG_FUNC("PSM MODE RESET<============================\n\r"); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static INT32 _stp_psm_wait_wmt_event(void *pvData) ++{ ++ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; ++ ++ STP_PSM_DBG_FUNC("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data); ++ ++ return (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) || ++ (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) || ++ (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) || ++ (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)); ++} ++ ++static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ INT32 retval = 0; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ osal_wait_for_event_timeout(&stp_psm->wait_wmt_q, _stp_psm_wait_wmt_event, (void *)stp_psm); ++ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ /* STP send data here: STP enqueue data to psm buffer. */ ++ _stp_psm_release_data(stp_psm); ++ /* STP send data here: STP enqueue data to psm buffer. We release packet by the next one. */ ++ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* STP send data here: STP sends data directly without PSM. */ ++ _stp_psm_set_state(stp_psm, ACT); ++/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ ++ if (stp_psm_is_quick_ps_support()) ++ stp_psm_notify_wmt_sleep(stp_psm); ++ else ++ _stp_psm_start_monitor(stp_psm); ++ } else if (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ _stp_psm_set_state(stp_psm, INACT); ++ ++ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle++\n"); ++ mt_combo_plt_enter_deep_idle(COMBO_IF_BTIF); ++ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle--\n"); ++ ++ STP_PSM_DBG_FUNC("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_unlock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ } else if (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ if (_stp_psm_get_state(stp_psm) == ACT_INACT) { ++ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ _stp_psm_release_data(stp_psm); ++ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ _stp_psm_set_state(stp_psm, ACT); ++ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ } else if (_stp_psm_get_state(stp_psm) == INACT_ACT) { ++ _stp_psm_set_state(stp_psm, INACT); ++ STP_PSM_INFO_FUNC("[WARNING]PSM state rollback due too wakeup fail\n"); ++ } ++ } else if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } else { ++ STP_PSM_ERR_FUNC("flag = %ld<== Abnormal flag be set!!\n\r", stp_psm->flag.data); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ wcn_psm_flag_trigger_collect_ftrace(); /* trigger collect SYS_FTRACE */ ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ } ++ retval = STP_PSM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) ++{ ++ ++ INT32 retval = 0; ++ ++ if (action == EIRQ) { ++ STP_PSM_DBG_FUNC("Call _stp_psm_notify_wmt_host_awake_wq\n\r"); ++ ++ _stp_psm_notify_wmt_host_awake_wq(stp_psm); ++ ++ return STP_PSM_OPERATION_FAIL; ++ } ++ ++ if ((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0)) { ++ STP_PSM_DBG_FUNC("state = %s, action=%s\n\r", g_psm_state[_stp_psm_get_state(stp_psm)], ++ g_psm_action[action]); ++ } ++ /* If STP trigger WAKEUP and SLEEP, to do the job below */ ++ switch (_stp_psm_get_state(stp_psm)) { ++ /* stp trigger */ ++ case ACT_INACT: ++ ++ if (action == SLEEP) { ++ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, ready to INACT\n\r", g_psm_action[action]); ++ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_set_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else if (action == ROLL_BACK) { ++ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, back to ACT\n\r", g_psm_action[action]); ++ /* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */ ++ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else { ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, ACT_INACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ } ++ break; ++ /* stp trigger */ ++ ++ case INACT_ACT: ++ ++ if (action == WAKEUP) { ++ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); ++ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else if (action == HOST_AWAKE) { ++ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); ++ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else if (action == ROLL_BACK) { ++ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, back to INACT\n\r", g_psm_action[action]); ++ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else { ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, INACT_ACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ } ++ break; ++ ++ case INACT: ++ ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, INACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = -1; ++ ++ break; ++ ++ case ACT: ++ ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, ACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ ++ break; ++ ++ default: ++ ++ /*invalid */ ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, Invalid state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ ++ break; ++ } ++ ++ return retval; ++ ++} ++ ++static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ switch (_stp_psm_get_state(stp_psm)) { ++ case ACT: ++ ++ if (action == SLEEP) { ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { ++ STP_PSM_ERR_FUNC("psm monitor disabled, can't do sleep op\n"); ++ return STP_PSM_OPERATION_FAIL; ++ } ++ ++ _stp_psm_set_state(stp_psm, ACT_INACT); ++ ++ _stp_psm_release_data(stp_psm); ++ ++ if (stp_psm->wmt_notify) { ++ stp_psm->wmt_notify(SLEEP); ++ _stp_psm_wait_wmt_event_wq(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ } else if (action == WAKEUP || action == HOST_AWAKE) { ++ STP_PSM_INFO_FUNC("In ACT state, dont do WAKEUP/HOST_AWAKE again\n"); ++ _stp_psm_release_data(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ ret = STP_PSM_OPERATION_FAIL; ++ ++ } ++ ++ break; ++ ++ case INACT: ++ ++ if (action == WAKEUP) { ++ _stp_psm_set_state(stp_psm, INACT_ACT); ++ ++ if (stp_psm->wmt_notify) { ++ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_lock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); ++ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); ++ ++ stp_psm->wmt_notify(WAKEUP); ++ _stp_psm_wait_wmt_event_wq(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ } else if (action == HOST_AWAKE) { ++ _stp_psm_set_state(stp_psm, INACT_ACT); ++ ++ if (stp_psm->wmt_notify) { ++ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)\n", ++ osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_lock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)#\n", ++ osal_wake_lock_count(&stp_psm->wake_lock)); ++ ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); ++ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); ++ ++ stp_psm->wmt_notify(HOST_AWAKE); ++ _stp_psm_wait_wmt_event_wq(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ } else if (action == SLEEP) { ++ STP_PSM_INFO_FUNC("In INACT state, dont do SLEEP again\n"); ++ } else { ++ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ ++ break; ++ ++ default: ++ ++ /*invalid */ ++ STP_PSM_ERR_FUNC("invalid state, the case should not happen\n"); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ ret = STP_PSM_OPERATION_FAIL; ++ ++ break; ++ } ++ return ret; ++} ++ ++static inline void _stp_psm_stp_is_idle(unsigned long data) ++{ ++ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) data; ++ ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { ++ STP_PSM_DBG_FUNC("STP-PSM DISABLE!\n"); ++ return; ++ } ++ ++ if (1 == _stp_psm_notify_wmt_sleep_wq(stp_psm)) ++ STP_PSM_INFO_FUNC("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep); ++} ++ ++static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_INFO_FUNC("init monitor\n"); ++ ++ stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle; ++ stp_psm->psm_timer.timeroutHandlerData = (unsigned long)stp_psm; ++ osal_timer_create(&stp_psm->psm_timer); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_INFO_FUNC("deinit monitor\n"); ++ ++ osal_timer_stop_sync(&stp_psm->psm_timer); ++ ++ return 0; ++} ++ ++static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 iRet = -1; ++ ++/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ ++ if (osal_test_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag)) ++ iRet = 1; ++ else ++ iRet = 0; ++ ++/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ return iRet; ++} ++ ++static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) ++ return 1; ++ else ++ return 0; ++} ++ ++static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) ++{ ++ ++#define POLL_WAIT 20 /* 200 */ ++#define POLL_WAIT_TIME 2000 ++ ++ INT32 i = 0; ++ INT32 limit = POLL_WAIT_TIME / POLL_WAIT; ++ ++ while (_stp_psm_get_state(stp_psm) != state && i < limit) { ++ osal_sleep_ms(POLL_WAIT); ++ i++; ++ STP_PSM_INFO_FUNC("STP is waiting state for %s, i=%d, state = %d\n", g_psm_state[state], i, ++ _stp_psm_get_state(stp_psm)); ++ } ++ ++ if (i == limit) { ++ STP_PSM_WARN_FUNC("-Wait for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); ++ _stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg); ++ return STP_PSM_OPERATION_FAIL; ++ } ++ STP_PSM_DBG_FUNC("+Total waits for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); ++ /* _stp_psm_dbg_out_printk(g_stp_psm_opid_dbg); */ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ INT32 ret = 0; ++ INT32 retry = 10; ++ P_OSAL_OP_Q pOpQ; ++ P_OSAL_OP pOp; ++ ++ STP_PSM_LOUD_FUNC("*** Do Force Wakeup!***\n\r"); ++ ++ /* <1>If timer is active, we will stop it. */ ++ _stp_psm_stop_monitor(stp_psm); ++ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ ++ pOpQ = &stp_psm->rFreeOpQ; ++ ++ while (!RB_EMPTY(&stp_psm->rActiveOpQ)) { ++ RB_GET(&stp_psm->rActiveOpQ, pOp); ++ if (NULL != pOp && !RB_FULL(pOpQ)) { ++ STP_PSM_DBG_FUNC("opid = %d\n", pOp->op.opId); ++ RB_PUT(pOpQ, pOp); ++ } else { ++ STP_PSM_ERR_FUNC("clear up active queue fail, freeQ full\n"); ++ } ++ } ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ /* <5>We issue wakeup request into op queue. and wait for active. */ ++ do { ++ ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm); ++ ++ if (ret == STP_PSM_OPERATION_SUCCESS) { ++ ret = _stp_psm_do_wait(stp_psm, ACT); ++ ++ /* STP_PSM_INFO_FUNC("<< wait ret = %d, num of activeQ = %d\n", ++ * ret, RB_COUNT(&stp_psm->rActiveOpQ)); ++ */ ++ if (ret == STP_PSM_OPERATION_SUCCESS) ++ break; ++ } else ++ STP_PSM_ERR_FUNC("_stp_psm_notify_wmt_wakeup_wq fail!!\n"); ++ ++ /* STP_PSM_INFO_FUNC("retry = %d\n", retry); */ ++ retry--; ++ ++ if (retry == 0) ++ break; ++ } while (1); ++ ++ if (retry == 0) ++ return STP_PSM_OPERATION_FAIL; ++ else ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_DBG_FUNC("PSM Disable start\n\r"); ++ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ ret = _stp_psm_do_wakeup(stp_psm); ++ if (ret == STP_PSM_OPERATION_SUCCESS) ++ STP_PSM_DBG_FUNC("PSM Disable Success\n"); ++ else ++ STP_PSM_ERR_FUNC("***PSM Disable Fail***\n"); ++ ++ return ret; ++} ++ ++static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) ++{ ++ INT32 ret = STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_LOUD_FUNC("PSM Enable start\n\r"); ++ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ ++ ret = _stp_psm_do_wakeup(stp_psm); ++ if (ret == STP_PSM_OPERATION_SUCCESS) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ stp_psm->idle_time_to_sleep = idle_time_to_sleep; ++ ++ if (osal_wake_lock_count(&stp_psm->wake_lock) == 0) { ++ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_lock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ } ++ ++ _stp_psm_start_monitor(stp_psm); ++ ++ STP_PSM_DBG_FUNC("PSM Enable succeed\n\r"); ++ } else ++ STP_PSM_ERR_FUNC("***PSM Enable Fail***\n"); ++ ++ return ret; ++} ++ ++INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) ++{ ++ return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock); ++} ++ ++INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) ++{ ++ osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock); ++ return 0; ++} ++ ++MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID) ++{ ++ if (stp_psm->is_wmt_quick_ps_support) ++ return (*(stp_psm->is_wmt_quick_ps_support)) (); ++ ++ STP_PSM_DBG_FUNC("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r"); ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID) ++{ ++ return _stp_psm_is_quick_ps_support(); ++} ++ ++#if PSM_USE_COUNT_PACKAGE ++int stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, int dir) ++{ ++ ++ /* easy the variable maintain beween stp tx, rx thread. */ ++ /* so we create variable for tx, rx respectively. */ ++ ++ static int tx_cnt; ++ static int rx_cnt; ++ static int is_tx_first = 1; ++ static int is_rx_first = 1; ++ static unsigned long tx_end_time; ++ static unsigned long rx_end_time; ++ ++ /* */ ++ /* BT A2DP TX CNT = 220, RX CNT = 843 */ ++ /* BT FTP Transferring TX CNT = 574, RX CNT = 2233 (1228~1588) */ ++ /* BT FTP Receiving TX CNT = 204, RX CNT = 3301 (2072~2515) */ ++ /* BT OPP Tx TX_CNT= 330, RX CNT = 1300~1800 */ ++ /* BT OPP Rx TX_CNT= (109~157), RX CNT = 1681~2436 */ ++ if (dir == 0) { /* tx */ ++ ++ tx_cnt++; ++ ++ if (((long)jiffies - (long)tx_end_time >= 0) || (is_tx_first)) { ++ tx_end_time = jiffies + (3 * HZ); ++ STP_PSM_INFO_FUNC("tx cnt = %d in the previous 3 sec\n", tx_cnt); ++ /* if(tx_cnt > 400)//for high traffic , not to do sleep. */ ++ if (tx_cnt > 300) { ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ stp_psm_start_monitor(stp_psm); ++ } else { ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } ++ tx_cnt = 0; ++ if (is_tx_first) ++ is_tx_first = 0; ++ } ++ } else { ++ rx_cnt++; ++ ++ if (((long)jiffies - (long)rx_end_time >= 0) || (is_rx_first)) { ++ rx_end_time = jiffies + (3 * HZ); ++ STP_PSM_INFO_FUNC("rx cnt = %d in the previous 3 sec\n", rx_cnt); ++ ++ /* if(rx_cnt > 2000)//for high traffic , not to do sleep. */ ++ if (rx_cnt > 1200) { /* for high traffic , not to do sleep. */ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ stp_psm_start_monitor(stp_psm); ++ } else { ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } ++ rx_cnt = 0; ++ if (is_rx_first) ++ is_rx_first = 0; ++ } ++ } ++ ++ return 0; ++} ++ ++#else ++static struct timeval tv_now, tv_end; ++static INT32 sample_start; ++static INT32 tx_sum_len; ++static INT32 rx_sum_len; ++ ++INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length) ++{ ++ if (sample_start) { ++ if (dir) ++ rx_sum_len += length; ++ else ++ tx_sum_len += length; ++ ++ do_gettimeofday(&tv_now); ++ /* STP_PSM_INFO_FUNC("tv_now:%d.%d tv_end:%d.%d\n", ++ * tv_now.tv_sec,tv_now.tv_usec,tv_end.tv_sec,tv_end.tv_usec); ++ */ ++ if (((tv_now.tv_sec == tv_end.tv_sec) && (tv_now.tv_usec > tv_end.tv_usec)) || ++ (tv_now.tv_sec > tv_end.tv_sec)) { ++ STP_PSM_INFO_FUNC("STP speed rx:%d tx:%d\n", rx_sum_len, tx_sum_len); ++ if ((rx_sum_len + tx_sum_len) > RTX_SPEED_THRESHOLD) { ++ /* STP_PSM_INFO_FUNC("High speed,Disable monitor\n"); */ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP_1000; ++ stp_psm_start_monitor(stp_psm); ++ } else { ++ /* STP_PSM_INFO_FUNC("Low speed,Enable monitor\n"); */ ++ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ } ++ sample_start = 0; ++ rx_sum_len = 0; ++ tx_sum_len = 0; ++ } ++ } else { ++ sample_start = 1; ++ do_gettimeofday(&tv_now); ++ tv_end = tv_now; ++ tv_end.tv_sec += SAMPLE_DURATION; ++ } ++ ++ return 0; ++} ++#endif ++ ++/*external function for WMT module to do sleep/wakeup*/ ++INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) ++{ ++ return _stp_psm_set_state(stp_psm, state); ++} ++ ++INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_thread_lock_aquire(stp_psm); ++} ++ ++INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_thread_lock_release(stp_psm); ++} ++ ++INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_do_wakeup(stp_psm); ++} ++ ++INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) ++{ ++ ++ return _stp_psm_notify_stp(stp_psm, action); ++} ++ ++INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_notify_wmt_wakeup_wq(stp_psm); ++} ++ ++int stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ return _stp_psm_notify_wmt_sleep_wq(stp_psm); ++} ++ ++INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_start_monitor(stp_psm); ++} ++ ++INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_is_to_block_traffic(stp_psm); ++} ++ ++INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_is_disable(stp_psm); ++} ++ ++INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_has_pending_data(stp_psm); ++} ++ ++INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_release_data(stp_psm); ++} ++ ++INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) ++{ ++ return _stp_psm_hold_data(stp_psm, buffer, len, type); ++} ++ ++INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_disable(stp_psm); ++} ++ ++INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) ++{ ++ return _stp_psm_enable(stp_psm, idle_time_to_sleep); ++} ++ ++INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm) ++{ ++ stp_psm_set_sleep_enable(stp_psm); ++ ++ return _stp_psm_reset(stp_psm); ++} ++ ++INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_notify_wmt_sleep_wq(stp_psm); ++} ++ ++INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm) { ++ stp_psm->sleep_en = 1; ++ STP_PSM_DBG_FUNC("\n"); ++ ret = 0; ++ } else { ++ STP_PSM_INFO_FUNC("Null pointer\n"); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm) { ++ stp_psm->sleep_en = 0; ++ STP_PSM_DBG_FUNC("\n"); ++ ret = 0; ++ } else { ++ STP_PSM_INFO_FUNC("Null pointer\n"); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++/* stp_psm_check_sleep_enable - to check if sleep cmd is enabled or not ++ * @ stp_psm - pointer of psm ++ * ++ * return 1 if sleep is enabled; else return 0 if disabled; else error code ++ */ ++INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm) { ++ ret = stp_psm->sleep_en; ++ STP_PSM_DBG_FUNC("%s\n", ret ? "enabled" : "disabled"); ++ } else { ++ STP_PSM_INFO_FUNC("Null pointer\n"); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num) ++{ ++ INT32 index = 0; ++ struct timeval now; ++ ++ if (stp_psm_dbg) { ++ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); ++ do_gettimeofday(&now); ++ index = stp_psm_dbg->in - 1; ++ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; ++ STP_PSM_DBG_FUNC("index(%d)\n", index); ++ stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag = stp_psm_dbg->queue[index].cur_flag; ++ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag = flag; ++ stp_psm_dbg->queue[stp_psm_dbg->in].line_num = line_num; ++ stp_psm_dbg->queue[stp_psm_dbg->in].package_no = g_record_num++; ++ stp_psm_dbg->queue[stp_psm_dbg->in].sec = now.tv_sec; ++ stp_psm_dbg->queue[stp_psm_dbg->in].usec = now.tv_usec; ++ stp_psm_dbg->size++; ++ STP_PSM_DBG_FUNC("pre_Flag = %d, cur_flag = %d\n", stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag, ++ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag); ++ stp_psm_dbg->size = (stp_psm_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : stp_psm_dbg->size; ++ stp_psm_dbg->in = (stp_psm_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (stp_psm_dbg->in + 1); ++ STP_PSM_DBG_FUNC("record size = %d, in = %d num = %d\n", stp_psm_dbg->size, stp_psm_dbg->in, line_num); ++ ++ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); ++ } ++ return 0; ++} ++ ++static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg) ++{ ++ ++ UINT32 dumpSize = 0; ++ UINT32 inIndex = 0; ++ UINT32 outIndex = 0; ++ ++ if (!stp_psm_dbg) { ++ STP_PSM_ERR_FUNC("NULL g_stp_psm_dbg reference\n"); ++ return -1; ++ } ++ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); ++ ++ inIndex = stp_psm_dbg->in; ++ dumpSize = stp_psm_dbg->size; ++ if (STP_PSM_DBG_SIZE == dumpSize) ++ outIndex = inIndex; ++ else ++ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; ++ ++ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); ++ while (dumpSize > 0) { ++ ++ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d)\n", ++ stp_psm_dbg->queue[outIndex].sec, ++ stp_psm_dbg->queue[outIndex].usec, ++ stp_psm_dbg->queue[outIndex].package_no, ++ stp_psm_dbg->queue[outIndex].prev_flag, ++ stp_psm_dbg->queue[outIndex].cur_flag, stp_psm_dbg->queue[outIndex].line_num); ++ ++ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); ++ dumpSize--; ++ ++ } ++ ++ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); ++ ++ return 0; ++} ++ ++static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num) ++{ ++ INT32 index = 0; ++ struct timeval now; ++ ++ if (p_opid_dbg) { ++ osal_lock_unsleepable_lock(&p_opid_dbg->lock); ++ do_gettimeofday(&now); ++ index = p_opid_dbg->in - 1; ++ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; ++ STP_PSM_DBG_FUNC("index(%d)\n", index); ++ p_opid_dbg->queue[p_opid_dbg->in].prev_flag = p_opid_dbg->queue[index].cur_flag; ++ p_opid_dbg->queue[p_opid_dbg->in].cur_flag = opid; ++ p_opid_dbg->queue[p_opid_dbg->in].line_num = line_num; ++ p_opid_dbg->queue[p_opid_dbg->in].package_no = g_opid_record_num++; ++ p_opid_dbg->queue[p_opid_dbg->in].sec = now.tv_sec; ++ p_opid_dbg->queue[p_opid_dbg->in].usec = now.tv_usec; ++ p_opid_dbg->queue[p_opid_dbg->in].pid = current->pid; ++ p_opid_dbg->size++; ++ STP_PSM_DBG_FUNC("pre_opid = %d, cur_opid = %d\n", p_opid_dbg->queue[p_opid_dbg->in].prev_flag, ++ p_opid_dbg->queue[p_opid_dbg->in].cur_flag); ++ p_opid_dbg->size = (p_opid_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : p_opid_dbg->size; ++ p_opid_dbg->in = (p_opid_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (p_opid_dbg->in + 1); ++ STP_PSM_DBG_FUNC("opid record size = %d, in = %d num = %d\n", p_opid_dbg->size, p_opid_dbg->in, ++ line_num); ++ ++ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); ++ } ++ return 0; ++ ++} ++ ++static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg) ++{ ++ UINT32 dumpSize = 0; ++ UINT32 inIndex = 0; ++ UINT32 outIndex = 0; ++ ++ if (!p_opid_dbg) { ++ STP_PSM_ERR_FUNC("NULL p_opid_dbg reference\n"); ++ return -1; ++ } ++ osal_lock_unsleepable_lock(&p_opid_dbg->lock); ++ ++ inIndex = p_opid_dbg->in; ++ dumpSize = p_opid_dbg->size; ++ if (STP_PSM_DBG_SIZE == dumpSize) ++ outIndex = inIndex; ++ else ++ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; ++ ++ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); ++ while (dumpSize > 0) { ++ ++ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d) pid(%d)\n", ++ p_opid_dbg->queue[outIndex].sec, ++ p_opid_dbg->queue[outIndex].usec, ++ p_opid_dbg->queue[outIndex].package_no, ++ p_opid_dbg->queue[outIndex].prev_flag, ++ p_opid_dbg->queue[outIndex].cur_flag, ++ p_opid_dbg->queue[outIndex].line_num, p_opid_dbg->queue[outIndex].pid); ++ ++ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); ++ dumpSize--; ++ ++ } ++ ++ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); ++ ++ return 0; ++ ++} ++ ++MTKSTP_PSM_T *stp_psm_init(void) ++{ ++ INT32 err = 0; ++ INT32 i = 0; ++ INT32 ret = -1; ++ ++ STP_PSM_INFO_FUNC("psm init\n"); ++ ++ stp_psm->work_state = ACT; ++ stp_psm->wmt_notify = wmt_lib_ps_stp_cb; ++ stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support; ++ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; ++ stp_psm->flag.data = 0; ++ stp_psm->stp_tx_cb = NULL; ++ stp_psm_set_sleep_enable(stp_psm); ++ ++ ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("FIFO INIT FAILS\n"); ++ goto ERR_EXIT4; ++ } ++ ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ osal_sleepable_lock_init(&stp_psm->hold_fifo_spinlock_global); ++ osal_unsleepable_lock_init(&stp_psm->wq_spinlock); ++ osal_sleepable_lock_init(&stp_psm->stp_psm_lock); ++ ++/* osal_unsleepable_lock_init(&stp_psm->flagSpinlock); */ ++ ++ osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6); ++ osal_wake_lock_init(&stp_psm->wake_lock); ++ ++ osal_event_init(&stp_psm->STPd_event); ++ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); ++ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); ++ /* Put all to free Q */ ++ for (i = 0; i < STP_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(stp_psm->arQue[i].signal)); ++ _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i])); ++ } ++ /* stp_psm->current_active_op = NULL; */ ++ stp_psm->last_active_opId = STP_OPID_PSM_INALID; ++ /*Generate BTM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake */ ++ stp_psm->PSMd.pThreadData = (VOID *) stp_psm; ++ stp_psm->PSMd.pThreadFunc = (VOID *) _stp_psm_proc; ++ osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME)); ++ ++ ret = osal_thread_create(&stp_psm->PSMd); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("osal_thread_create fail...\n"); ++ goto ERR_EXIT5; ++ } ++ /* init_waitqueue_head(&stp_psm->wait_wmt_q); */ ++ stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT; ++ osal_event_init(&stp_psm->wait_wmt_q); ++ ++ err = _stp_psm_init_monitor(stp_psm); ++ if (err) { ++ STP_PSM_ERR_FUNC("__stp_psm_init ERROR\n"); ++ goto ERR_EXIT6; ++ } ++ /* Start STPd thread */ ++ ret = osal_thread_run(&stp_psm->PSMd); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("osal_thread_run FAILS\n"); ++ goto ERR_EXIT6; ++ } ++ /* psm disable in default */ ++ _stp_psm_disable(stp_psm); ++ ++ g_stp_psm_dbg = (STP_PSM_RECORD_T *) osal_malloc(osal_sizeof(STP_PSM_RECORD_T)); ++ if (!g_stp_psm_dbg) { ++ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); ++ return NULL; ++ } ++ osal_memset(g_stp_psm_dbg, 0, osal_sizeof(STP_PSM_RECORD_T)); ++ osal_unsleepable_lock_init(&g_stp_psm_dbg->lock); ++ ++ g_stp_psm_opid_dbg = (STP_PSM_OPID_RECORD *) osal_malloc(osal_sizeof(STP_PSM_OPID_RECORD)); ++ if (!g_stp_psm_opid_dbg) { ++ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); ++ return NULL; ++ } ++ osal_memset(g_stp_psm_opid_dbg, 0, osal_sizeof(STP_PSM_OPID_RECORD)); ++ osal_unsleepable_lock_init(&g_stp_psm_opid_dbg->lock); ++ ++ return stp_psm; ++ ++ERR_EXIT6: ++ ++ ret = osal_thread_destroy(&stp_psm->PSMd); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); ++ goto ERR_EXIT5; ++ } ++ERR_EXIT5: ++ osal_fifo_deinit(&stp_psm->hold_fifo); ++ERR_EXIT4: ++ ++ return NULL; ++} ++ ++INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = -1; ++ ++ STP_PSM_INFO_FUNC("psm deinit\n"); ++ ++ if (g_stp_psm_dbg) { ++ osal_unsleepable_lock_deinit(&g_stp_psm_dbg->lock); ++ osal_free(g_stp_psm_dbg); ++ g_stp_psm_dbg = NULL; ++ } ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ ret = osal_thread_destroy(&stp_psm->PSMd); ++ if (ret < 0) ++ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); ++ ++ ret = _stp_psm_deinit_monitor(stp_psm); ++ if (ret < 0) ++ STP_PSM_ERR_FUNC("_stp_psm_deinit_monitor ERROR\n"); ++ ++ osal_wake_lock_deinit(&stp_psm->wake_lock); ++ osal_fifo_deinit(&stp_psm->hold_fifo); ++ osal_sleepable_lock_deinit(&stp_psm->hold_fifo_spinlock_global); ++ osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock); ++ osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock); ++/* osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock); */ ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c +new file mode 100644 +index 000000000000..046af2a58e69 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c +@@ -0,0 +1,3358 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include "osal_typedef.h" ++#include "stp_core.h" ++#include "psm_core.h" ++#include "btm_core.h" ++#include "stp_dbg.h" ++#include "stp_btif.h" ++ ++#define PFX "[STP] " ++#define STP_LOG_DBG 4 ++#define STP_LOG_PKHEAD 3 ++#define STP_LOG_INFO 2 ++#define STP_LOG_WARN 1 ++#define STP_LOG_ERR 0 ++ ++#define STP_DEL_SIZE 2 /* STP delimiter length */ ++ ++UINT32 gStpDbgLvl = STP_LOG_INFO; ++unsigned int g_coredump_mode = 0; ++#define REMOVE_USELESS_LOG 1 ++ ++#define STP_POLL_CPUPCR_NUM 16 ++#define STP_POLL_CPUPCR_DELAY 10 ++#define STP_RETRY_OPTIMIZE 0 ++ ++/* global variables */ ++static const UINT8 stp_delimiter[STP_DEL_SIZE] = { 0x55, 0x55 }; ++ ++static INT32 fgEnableNak; /* 0=enable NAK; 1=disable NAK */ ++static INT32 fgEnableDelimiter; /* 0=disable Delimiter; 1=enable Delimiter */ ++#if STP_RETRY_OPTIMIZE ++static UINT32 g_retry_times; ++#endif ++/* common interface */ ++static IF_TX sys_if_tx; ++/* event/signal */ ++static EVENT_SET sys_event_set; ++static EVENT_TX_RESUME sys_event_tx_resume; ++static FUNCTION_STATUS sys_check_function_status; ++/* kernel lib */ ++/* int g_block_tx = 0; */ ++static mtkstp_context_struct stp_core_ctx = { 0 }; ++ ++#define STP_PSM_CORE(x) ((x).psm) ++#define STP_SET_PSM_CORE(x, v) ((x).psm = (v)) ++ ++#define STP_BTM_CORE(x) ((x).btm) ++#define STP_SET_BTM_CORE(x, v) ((x).btm = (v)) ++ ++#define STP_IS_ENABLE(x) ((x).f_enable != 0) ++#define STP_NOT_ENABLE(x) ((x).f_enable == 0) ++#define STP_SET_ENABLE(x, v) ((x).f_enable = (v)) ++ ++#define STP_IS_READY(x) ((x).f_ready != 0) ++#define STP_NOT_READY(x) ((x).f_ready == 0) ++#define STP_SET_READY(x, v) ((x).f_ready = (v)) ++ ++#define STP_PENDING_TYPE(x) ((x).f_pending_type) ++#define STP_SET_PENDING_TYPE(x, v) ((x).f_pending_type = (v)) ++ ++#define STP_BLUE_ANGEL (0) ++#define STP_BLUE_Z (1) ++#define STP_BT_STK(x) ((x).f_bluez) ++#define STP_BT_STK_IS_BLUEZ(x) ((x).f_bluez == (STP_BLUE_Z)) ++#define STP_SET_BT_STK(x, v) ((x).f_bluez = (v)) ++ ++#define STP_IS_ENABLE_DBG(x) ((x).f_dbg_en != 0) ++#define STP_NOT_ENABLE_DBG(x) ((x).f_dbg_en == 0) ++#define STP_SET_ENABLE_DBG(x, v) ((x).f_dbg_en = (v)) ++ ++#define STP_IS_ENABLE_RST(x) ((x).f_autorst_en != 0) ++#define STP_NOT_ENABLE_RST(x) ((x).f_autorst_en == 0) ++#define STP_SET_ENABLE_RST(x, v) ((x).f_autorst_en = (v)) ++ ++#define STP_SUPPORT_PROTOCOL(x) ((x).f_mode) ++#define STP_SET_SUPPORT_PROTOCOL(x, v) ((x).f_mode = (v)) ++ ++#define STP_FW_COREDUMP_FLAG(x) ((x).f_coredump) ++#define STP_SET_FW_COREDUMP_FLAG(x, v) ((x).f_coredump = (v)) ++#define STP_ENABLE_FW_COREDUMP(x, v) ((x).en_coredump = (v)) ++#define STP_ENABLE_FW_COREDUMP_FLAG(x) ((x).en_coredump) ++ ++#define STP_WMT_LAST_CLOSE(x) ((x).f_wmt_last_close) ++#define STP_SET_WMT_LAST_CLOSE(x, v) ((x).f_wmt_last_close = (v)) ++ ++#define STP_EVT_ERR_ASSERT(x) ((x).f_evt_err_assert) ++#define STP_SET_EVT_ERR_ASSERT(x, v) ((x).f_evt_err_assert = (v)) ++ ++/*[PatchNeed]Need to calculate the timeout value*/ ++static UINT32 mtkstp_tx_timeout = MTKSTP_TX_TIMEOUT; ++static mtkstp_parser_state prev_state = -1; ++ ++#define CONFIG_DEBUG_STP_TRAFFIC_SUPPORT ++#ifdef CONFIG_DEBUG_STP_TRAFFIC_SUPPORT ++static MTKSTP_DBG_T *g_mtkstp_dbg; ++#endif ++static VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len); ++static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc); ++static VOID stp_update_tx_queue(UINT32 txseq); ++static VOID stp_rest_ctx_state(VOID); ++static VOID stp_change_rx_state(mtkstp_parser_state next); ++static void stp_tx_timeout_handler(unsigned long data); ++static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len); ++static VOID stp_dump_tx_queue(UINT32 txseq); ++static INT32 stp_is_apply_powersaving(VOID); ++/*static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type);*/ ++static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length); ++static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length); ++static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type); ++static VOID stp_send_tx_queue(UINT32 txseq); ++static VOID stp_send_ack(UINT8 txAck, UINT8 nak); ++static INT32 stp_process_rxack(VOID); ++static VOID stp_process_packet(VOID); ++ ++/*private functions*/ ++ ++static INT32 stp_ctx_lock_init(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_unsleepable_lock_init(&((pctx)->stp_mutex)); ++#else ++ osal_sleepable_lock_init(&((pctx)->stp_mutex)); ++ return 0; ++#endif ++} ++ ++static INT32 stp_ctx_lock_deinit(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_unsleepable_lock_deinit(&((pctx)->stp_mutex)); ++#else ++ return osal_sleepable_lock_deinit(&((pctx)->stp_mutex)); ++#endif ++} ++ ++static INT32 stp_ctx_lock(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_lock_unsleepable_lock(&((pctx)->stp_mutex)); ++#else ++ return osal_lock_sleepable_lock(&((pctx)->stp_mutex)); ++#endif ++} ++ ++static INT32 stp_ctx_unlock(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_unlock_unsleepable_lock(&((pctx)->stp_mutex)); ++#else ++ return osal_unlock_sleepable_lock(&((pctx)->stp_mutex)); ++#endif ++} ++ ++MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel) ++{ ++ if (dbglevel <= 4) { ++ gStpDbgLvl = dbglevel; ++ STP_INFO_FUNC("gStpDbgLvl = %d\n", gStpDbgLvl); ++ return MTK_WCN_BOOL_TRUE; ++ } ++ STP_INFO_FUNC("invalid stp debug level. gStpDbgLvl = %d\n", gStpDbgLvl); ++ ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++#if !(REMOVE_USELESS_LOG) ++static UINT8 *stp_type_to_dbg_string(UINT32 type) ++{ ++ UINT8 *type_name = NULL; ++ ++ if (type == BT_TASK_INDX) ++ type_name = "< BT>"; ++ else if (type == GPS_TASK_INDX) ++ type_name = ""; ++ else if (type == WMT_TASK_INDX) ++ type_name = ""; ++ else if (type == FM_TASK_INDX) ++ type_name = "< FM>"; ++ else if (type == ANT_TASK_INDX) ++ type_name = ""; ++ ++ return type_name; ++} ++#endif ++#if 0 ++/***************************************************************************** ++* FUNCTION ++* crc16 ++* DESCRIPTION ++* Compute the CRC-16 for the data buffer ++* PARAMETERS ++* crc [IN] previous CRC value ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* the updated CRC value ++*****************************************************************************/ ++static UINT16 crc16(const UINT8 *buffer, const UINT32 length) ++{ ++ UINT32 crc, i; ++ ++ /* FIXME: Add STP checksum feature */ ++ crc = 0; ++ for (i = 0; i < length; i++, buffer++) ++ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; ++ ++ return crc; ++} ++ ++#endif ++ ++VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len) ++{ ++ ++#ifndef CONFIG_LOG_STP_INTERNAL ++ return; ++#endif ++ ++ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { ++ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_PKT, type, /* type */ ++ txAck, /* ack */ ++ seq, /* seq */ ++ crc, /* crc */ ++ dir, /* dir */ ++ len, /* len */ ++ pBuf); /* body */ ++ } else { ++ STP_DBG_FUNC("stp_dbg not enabled"); ++ } ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_check_crc ++* DESCRIPTION ++* check the check sum of packet payload ++* PARAMETERS ++* pdata [IN] the data want to check ++* length [IN] the length of pdata ++* crc [IN] the crc of pdata ++* RETURNS ++* KAL_TRUE crc is ok ++* KAL_FALSE crc is wrong ++*****************************************************************************/ ++static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc) ++{ ++ /*----------------------------------------------------------------*/ ++ /* Local Variables */ ++ /*----------------------------------------------------------------*/ ++ UINT16 checksum; ++ ++ /*----------------------------------------------------------------*/ ++ /* Code Body */ ++ /*----------------------------------------------------------------*/ ++ ++ /* FIXME: Add STP feature: check or skip crc */ ++ ++ checksum = osal_crc16(buffer, length); ++ if (checksum == crc) ++ return MTK_WCN_BOOL_TRUE; ++ ++ STP_ERR_FUNC("CRC fail, length = %d, rx = %x, calc = %x \r\n", length, crc, checksum); ++ return MTK_WCN_BOOL_FALSE; ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_update_tx_queue ++* DESCRIPTION ++* update packet's ACK field ++* PARAMETERS ++* txseq [IN] index of the tx packet which we want to update ++* RETURNS ++* void ++*****************************************************************************/ ++static void stp_update_tx_queue(UINT32 txseq) ++{ ++ INT32 tx_read, i; ++ UINT8 checksum = 0; ++ ++ tx_read = stp_core_ctx.tx_start_addr[txseq]; ++ stp_core_ctx.tx_buf[tx_read] &= 0xf8; ++ stp_core_ctx.tx_buf[tx_read] |= stp_core_ctx.sequence.txack; ++ ++ for (i = 0; i < 3; i++) { ++ checksum += stp_core_ctx.tx_buf[tx_read]; ++ tx_read++; ++ if (tx_read >= MTKSTP_BUFFER_SIZE) ++ tx_read -= MTKSTP_BUFFER_SIZE; ++ ++ } ++ ++ stp_core_ctx.tx_buf[tx_read] = checksum; ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_rest_ctx_state ++* DESCRIPTION ++* Reset stp context state variables only. Mutex and timer resources are not touched. ++* ++* PARAMETERS ++* void ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_rest_ctx_state(VOID) ++{ ++ INT32 i; ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ stp_core_ctx.rx_counter = 0; ++ ++ /*reset rx buffer pointer */ ++ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) { ++ stp_core_ctx.ring[i].read_p = 0; ++ stp_core_ctx.ring[i].write_p = 0; ++ } ++ ++ /*reset tx buffer pointer */ ++ stp_core_ctx.tx_write = 0; ++ stp_core_ctx.tx_read = 0; ++ ++ /*reset STP protocol context */ ++ stp_core_ctx.parser.state = MTKSTP_SYNC; ++ stp_core_ctx.sequence.txseq = 0; ++ stp_core_ctx.sequence.txack = 7; ++ stp_core_ctx.sequence.rxack = 7; ++ stp_core_ctx.sequence.winspace = MTKSTP_WINSIZE; ++ stp_core_ctx.sequence.expected_rxseq = 0; ++ stp_core_ctx.sequence.retry_times = 0; ++ stp_core_ctx.inband_rst_set = 0; ++ ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_change_rx_state ++* DESCRIPTION ++* change the rx fsm of STP to "next" ++* PARAMETERS ++* next [IN] the next state of rx fsm ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_change_rx_state(mtkstp_parser_state next) ++{ ++ prev_state = stp_core_ctx.parser.state; ++ stp_core_ctx.parser.state = next; ++ ++} ++ ++/* static void stp_tx_timeout_handler(void){ */ ++static void stp_tx_timeout_handler(unsigned long data) ++{ ++ STP_WARN_FUNC("call retry btm retry wq ...\n"); ++ /*shorten the softirq lattency */ ++ stp_btm_notify_stp_retry_wq(STP_BTM_CORE(stp_core_ctx)); ++ STP_WARN_FUNC("call retry btm retry wq ...#\n"); ++} ++ ++VOID stp_do_tx_timeout(VOID) ++{ ++ UINT32 seq; ++ UINT32 ret; ++ INT32 iRet; ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ UINT8 resync[4]; ++ ++ STP_WARN_FUNC("==============================================================================\n"); ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++#if STP_RETRY_OPTIMIZE ++ if ((g_retry_times != 0) && (stp_core_ctx.sequence.retry_times == 0)) { ++ STP_INFO_FUNC("STP TX timeout has been recoveryed by resend,record_retry_time(%d)\n", g_retry_times); ++ g_retry_times = 0; ++ stp_ctx_unlock(&stp_core_ctx); ++ return; ++ } ++#endif ++ if (stp_core_ctx.sequence.retry_times > (MTKSTP_RETRY_LIMIT)) { ++ STP_INFO_FUNC("STP retry times(%d) have reached retry limit,stop it\n", ++ stp_core_ctx.sequence.retry_times); ++ stp_ctx_unlock(&stp_core_ctx); ++ return; ++ } ++#if STP_RETRY_OPTIMIZE ++ else ++ STP_DBG_FUNC("current TX timeout package has not received ACK yet,retry_times(%d)\n", ++ g_retry_times); ++#endif ++ /*polling cpupcr when no ack occurs at first retry */ ++ stp_notify_btm_poll_cpupcr(STP_BTM_CORE(stp_core_ctx), STP_POLL_CPUPCR_NUM, STP_POLL_CPUPCR_DELAY); ++ ++ seq = stp_core_ctx.sequence.rxack; ++ INDEX_INC(seq); ++ ++ if (seq != stp_core_ctx.sequence.txseq) { ++ osal_memset(&resync[0], 127, 4); ++ (*sys_if_tx) (&resync[0], 4, &ret); ++ if (ret != 4) { ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler: send resync fail\n"); ++ osal_assert(0); ++ } ++ ++ do { ++ STP_WARN_FUNC("[stp.ctx]*rxack (=last rx ack) = %d\n\r", stp_core_ctx.sequence.rxack); ++ STP_WARN_FUNC("[stp.ctx]txack (=last rx seq)= %d\n\r", stp_core_ctx.sequence.txack); ++ STP_WARN_FUNC("[stp.ctx]*txseq (=next tx seq)= %d\n\r", stp_core_ctx.sequence.txseq); ++ STP_WARN_FUNC("Resend STP packet from %d -> %d\n\r", seq, ++ (stp_core_ctx.sequence.txseq <= 0) ? (7) : (stp_core_ctx.sequence.txseq - 1)); ++ stp_dump_tx_queue(seq); ++ ++ stp_send_tx_queue(seq); ++ INDEX_INC(seq); ++ } while (seq != stp_core_ctx.sequence.txseq); ++ ++ } ++ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ ++ if (stp_core_ctx.sequence.winspace == MTKSTP_WINSIZE) { ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); ++ } else { ++ stp_core_ctx.sequence.retry_times++; ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler, retry = %d\n", stp_core_ctx.sequence.retry_times); ++#if STP_RETRY_OPTIMIZE ++ g_retry_times = stp_core_ctx.sequence.retry_times; ++#endif ++ /*If retry too much, try to recover STP by return back to initializatin state */ ++ /*And not to retry again */ ++ if (stp_core_ctx.sequence.retry_times > MTKSTP_RETRY_LIMIT) { ++#if STP_RETRY_OPTIMIZE ++ g_retry_times = 0; ++#endif ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ stp_ctx_unlock(&stp_core_ctx); ++ ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); ++ ++ STP_ERR_FUNC("TX retry limit = %d\n", MTKSTP_RETRY_LIMIT); ++ osal_assert(0); ++ mtk_wcn_stp_dbg_dump_package(); ++ ++ /*Whole Chip Reset Procedure Invoke */ ++ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ ++ ++ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); ++ stp_dbg_set_host_assert_info(4, 36, 1); ++ STP_INFO_FUNC("**STP NoAck trigger firmware assert**\n"); ++ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); ++ ++ if (iRet) { ++ STP_ERR_FUNC("host tigger fw assert fail(%d), do noack handle flow\n", iRet); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ issue_type = STP_FW_NOACK_ISSUE; ++ iRet = stp_dbg_set_fw_info("STP NoAck", osal_strlen("STP NoAck"), issue_type); ++ ++ osal_dbg_assert_aee("[SOC_CONNSYS]NoAck", ++ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n F/W has NO any RESPONSE. Please check F/W status first\n"); ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) { ++ STP_SET_READY(stp_core_ctx, 0); ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ } ++ } else { ++ STP_INFO_FUNC("do trigger assert & chip reset in wmt\n"); ++ } ++ return; ++ } ++ } ++ ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ STP_WARN_FUNC("==============================================================================#\n"); ++} ++ ++static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len) ++{ ++ osal_buffer_dump(buf, title, len, 32); ++} ++ ++/***************************************************************************** ++ * FUNCTION ++ * stp_tx_timeout_handler ++ * DESCRIPTION ++ * tx timeout handler, send resync & retransmitt ++ * PARAMETERS ++ * void ++ * RETURNS ++ * void ++ *****************************************************************************/ ++static VOID stp_dump_tx_queue(UINT32 txseq) ++{ ++ INT32 tx_read, tx_length, last_len; ++ ++ tx_read = stp_core_ctx.tx_start_addr[txseq]; ++ tx_length = stp_core_ctx.tx_length[txseq]; ++ ++ STP_ERR_FUNC("tx_seq=%d ..", txseq); ++ ++ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { ++ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q", (tx_length >= 8) ? (8) : (tx_length)); ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - tx_read; ++ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q_0", (last_len >= 8) ? (8) : (last_len)); ++ stp_dump_data(&stp_core_ctx.tx_buf[0], "tx_q_0", ++ ((tx_length - last_len) ? (8) : (tx_length - last_len))); ++ } ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_is_apply_powersaving ++* DESCRIPTION ++* Check if STP support power saving mode. ++* PARAMETERS ++* ++* RETURNS ++* True: support power saving False: not support power saving ++*****************************************************************************/ ++static INT32 stp_is_apply_powersaving(VOID) ++{ ++ ++ if (STP_IS_READY(stp_core_ctx) && !stp_psm_is_disable(STP_PSM_CORE(stp_core_ctx))) { ++ /* osal_dbg_print("apply power saving\n"); */ ++ return MTK_WCN_BOOL_TRUE; ++ } ++ if (mtk_wcn_stp_is_sdio_mode()) ++ return MTK_WCN_BOOL_FALSE; ++ ++ STP_DBG_FUNC("not apply power saving\n"); ++ return MTK_WCN_BOOL_FALSE; ++} ++#if 0 ++/***************************************************************************** ++* FUNCTION ++* stp_is_privileges_cmd ++* DESCRIPTION ++* Check if the data is privilege command ++* PARAMETERS ++* ++* RETURNS ++* True/False ++*****************************************************************************/ ++static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type) ++{ ++ typedef struct privileges_cmd { ++ UINT32 length; ++ UINT8 type; ++ UINT8 buf[7]; /* MAX length of target command is only 5 currently */ ++ } p_cmd_t; ++ ++ p_cmd_t p_cmd_table[] = { ++ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x01} }, /* sleep command */ ++ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x02} }, /* host_awake command */ ++ }; ++ ++ UINT32 i; ++ UINT32 size = sizeof(p_cmd_table) / sizeof(p_cmd_table[0]); ++ ++ for (i = 0; i < size; i++) { ++ if (type != p_cmd_table[i].type) ++ continue; ++ ++ if (length != p_cmd_table[i].length) ++ continue; ++ ++ if (osal_memcmp(p_cmd_table[i].buf, buffer, length)) ++ continue; ++ ++ /* matched entry is found */ ++ STP_DBG_FUNC("It's p_cmd_t\n"); ++ return MTK_WCN_BOOL_TRUE; ++ } ++ ++ return MTK_WCN_BOOL_FALSE; ++} ++#endif ++/***************************************************************************** ++* FUNCTION ++* tx_queue_room_available ++* DESCRIPTION ++* check room if available, ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length) ++{ ++ UINT32 roomLeft; ++ ++ /* ++ Get available space of TX Queue ++ */ ++ if (stp_core_ctx.tx_read <= stp_core_ctx.tx_write) ++ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write + stp_core_ctx.tx_read - 1; ++ else ++ roomLeft = stp_core_ctx.tx_read - stp_core_ctx.tx_write - 1; ++ ++ if (roomLeft < length) { ++ STP_ERR_FUNC("%s: tx queue room shortage\n", __func__); ++ return MTK_WCN_BOOL_FALSE; ++ } else ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_add_to_tx_queue ++* DESCRIPTION ++* put data to tx queue ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length) ++{ ++ UINT32 last_len; ++ ++ /* Get available space of TX Queue */ ++ if (length + stp_core_ctx.tx_write < MTKSTP_BUFFER_SIZE) { ++ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, length); ++ stp_core_ctx.tx_write += length; ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write; ++ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, last_len); ++ osal_memcpy(stp_core_ctx.tx_buf, buffer + last_len, length - last_len); ++ ++ stp_core_ctx.tx_write = length - last_len; ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_add_to_rx_queue ++* DESCRIPTION ++* put data to corresponding task's rx queue and notify corresponding task ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] corresponding task index ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type) ++{ ++ UINT32 roomLeft, last_len; ++ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ if (stp_core_ctx.ring[type].read_p <= stp_core_ctx.ring[type].write_p) ++ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p + stp_core_ctx.ring[type].read_p - 1; ++ else ++ roomLeft = stp_core_ctx.ring[type].read_p - stp_core_ctx.ring[type].write_p - 1; ++ ++ if (roomLeft < length) { ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ STP_ERR_FUNC("Queue is full !!!, type = %d\n", type); ++ osal_assert(0); ++ return -1; ++ } ++ ++ if (length + stp_core_ctx.ring[type].write_p < MTKSTP_BUFFER_SIZE) { ++ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, length); ++ stp_core_ctx.ring[type].write_p += length; ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p; ++ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, last_len); ++ osal_memcpy(stp_core_ctx.ring[type].buffer, buffer + last_len, length - last_len); ++ stp_core_ctx.ring[type].write_p = length - last_len; ++ } ++ ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_tx_queue ++* DESCRIPTION ++* send data in tx buffer to common interface ++* PARAMETERS ++* txseq [IN] sequence number of outgoing packet in tx buffer ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_send_tx_queue(UINT32 txseq) ++{ ++ UINT32 ret; ++ INT32 tx_read, tx_length, last_len; ++ ++ tx_read = stp_core_ctx.tx_start_addr[txseq]; ++ tx_length = stp_core_ctx.tx_length[txseq]; ++ ++ stp_update_tx_queue(txseq); ++ ++ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { ++ ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], tx_length, &ret); ++ ++ if (ret != tx_length) { ++ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length, ret); ++ osal_assert(0); ++ } ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - tx_read; ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], last_len, &ret); ++ ++ if (ret != last_len) { ++ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", last_len, ret); ++ osal_assert(0); ++ } ++ ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], tx_length - last_len, &ret); ++ ++ if (ret != tx_length - last_len) { ++ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length - last_len, ret); ++ osal_assert(0); ++ } ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_ack ++* DESCRIPTION ++* send ack packet to the peer ++* PARAMETERS ++* txAck [IN] Ack number ++* nak [IN] 0 = ack; !0 = NAK ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_send_ack(UINT8 txAck, UINT8 nak) ++{ ++ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE]; ++ UINT32 ret; ++ INT32 iStatus; ++ ++ mtkstp_header[0] = 0x80 + (0 << 3) + txAck; /* stp_core_ctx.sequence.txack; */ ++ ++ if (fgEnableNak == 0) ++ mtkstp_header[1] = 0x00; /* disable NAK */ ++ else ++ mtkstp_header[1] = ((nak == 0) ? 0x00 : 0x80); ++ ++ mtkstp_header[2] = 0; ++ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; ++ ++ stp_dbg_pkt_log(STP_TASK_INDX, txAck, 0, 0, PKT_DIR_TX, NULL, 0); ++ ++ if (fgEnableDelimiter == 1) { ++ iStatus = (*sys_if_tx) ((PUINT8) &stp_delimiter[0], STP_DEL_SIZE, &ret); ++ STP_DUMP_PACKET_HEAD((PUINT8) &stp_delimiter[0], "tx del", STP_DEL_SIZE); ++ if (ret != STP_DEL_SIZE) { ++ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", STP_DEL_SIZE, ret, iStatus); ++ osal_assert(0); ++ } ++ } ++ ++ iStatus = (*sys_if_tx) (&mtkstp_header[0], MTKSTP_HEADER_SIZE, &ret); ++ ++ if (ret != MTKSTP_HEADER_SIZE) { ++ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", MTKSTP_HEADER_SIZE, ret, iStatus); ++ osal_assert(0); ++ } ++ ++} ++ ++INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type) ++{ ++ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; ++ UINT8 *p_tx_buf = NULL; ++ UINT16 crc; ++ INT32 ret = 0; ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ /*Only WMT can set raw data */ ++ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { ++ /* no op */ ++ /* NULL; */ ++ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { ++ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ ++ /* NULL; */ ++ } ++ /* STP over SDIO */ ++ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++ osal_printtimeofday("[ STP][SDIO][ B][W]"); ++ ++ mtkstp_header[0] = 0x80; ++ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); ++ mtkstp_header[2] = (length) & 0xff; ++ mtkstp_header[3] = 0x00; ++ ++ p_tx_buf = &stp_core_ctx.tx_buf[0]; ++ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); ++ p_tx_buf += MTKSTP_HEADER_SIZE; ++ ++ osal_memcpy(p_tx_buf, buffer, length); ++ p_tx_buf += length; ++ ++ temp[0] = 0x00; ++ temp[1] = 0x00; ++ osal_memcpy(p_tx_buf, temp, 2); ++ stp_dbg_pkt_log(type, ++ stp_core_ctx.sequence.txack, ++ stp_core_ctx.sequence.txseq, 0, PKT_DIR_TX, buffer, length); ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); ++ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { ++ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); ++ osal_assert(0); ++ ret = 0; ++ } else { ++ ret = (INT32) length; ++ } ++ ++ osal_printtimeofday("[ STP][SDIO][ E][W]"); ++ } ++ /* STP over BTIF OR UART */ ++ else if ((mtk_wcn_stp_is_btif_fullset_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++ ++ if ((stp_core_ctx.sequence.winspace > 0) && ++ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { ++ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; ++ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); ++ mtkstp_header[2] = length & 0xff; ++ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; ++ ++ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; ++ ++ if (fgEnableDelimiter == 1) { ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; ++ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); ++ } ++ ++ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); ++ ++ /*Make Payload */ ++ stp_add_to_tx_queue(buffer, length); ++ ++ /*Make CRC */ ++ crc = osal_crc16(buffer, length); ++ temp[0] = crc & 0xff; ++ temp[1] = (crc & 0xff00) >> 8; ++ stp_add_to_tx_queue(temp, 2); ++ ++ stp_dbg_pkt_log(type, ++ stp_core_ctx.sequence.txack, ++ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); ++ ++ /*Kick to UART */ ++ stp_send_tx_queue(stp_core_ctx.sequence.txseq); ++ INDEX_INC(stp_core_ctx.sequence.txseq); ++ stp_core_ctx.sequence.winspace--; ++ ++ /*Setup the Retry Timer */ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ else ++ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); ++ ++ ret = (INT32) length; ++ } else { ++ /* No winspace to send. Let caller retry */ ++ STP_ERR_FUNC("%s: There is no winspace/txqueue to send !!!\n", __func__); ++ ret = 0; ++ } ++ } ++ ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ ++ return ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_process_rxack ++* DESCRIPTION ++* process ack packet ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++static INT32 stp_process_rxack(VOID) ++{ ++ INT32 j, k; ++ UINT8 rxack; ++ INT32 fgResult = (-1); ++ ++ if (stp_core_ctx.sequence.rxack != stp_core_ctx.parser.ack) { ++ j = k = 0; ++ rxack = stp_core_ctx.sequence.rxack; ++ INDEX_INC(rxack); ++ while (rxack != stp_core_ctx.sequence.txseq) { ++ j++; ++ if (rxack == stp_core_ctx.parser.ack) { ++ k = 1; ++ break; ++ } ++ INDEX_INC(rxack); ++ } ++ if (k == 1) { ++ stp_core_ctx.sequence.rxack = stp_core_ctx.parser.ack; ++ stp_core_ctx.tx_read = stp_core_ctx.tx_start_addr[rxack] + stp_core_ctx.tx_length[rxack]; ++ if (stp_core_ctx.tx_read >= MTKSTP_BUFFER_SIZE) ++ stp_core_ctx.tx_read -= MTKSTP_BUFFER_SIZE; ++ ++ stp_core_ctx.sequence.winspace += j; ++ stp_core_ctx.sequence.retry_times = 0; ++ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ ++ fgResult = 0; ++ } ++ } ++ ++ return fgResult; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_process_packet ++* DESCRIPTION ++* process STP packet ++* PARAMETERS ++* void ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_process_packet(VOID) ++{ ++ INT32 fgTriggerResume = (-1); ++ UINT8 txAck = 0; ++ static INT32 fgRxOk; ++ MTK_WCN_BOOL b; ++ MTK_WCN_BOOL is_function_active = 0; ++ static INT32 stp_process_packet_fail_count; ++ INT32 iRet = -1; ++ ++ stp_dbg_pkt_log(stp_core_ctx.parser.type, ++ stp_core_ctx.parser.ack, ++ stp_core_ctx.parser.seq, ++ stp_core_ctx.parser.crc, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.parser.length); ++ /*Optimization */ ++ /*If bluez, direct send packet to hci_core not through RX buffer! */ ++ if ((stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) && ++ (stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { ++ /*Indicate packet to hci_stp */ ++ STP_DBG_FUNC("Send Packet to BT_SUBFUCTION, len = %d\n", stp_core_ctx.rx_counter); ++ ++ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); ++ if (b) ++ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ /*Process rx ack */ ++ fgTriggerResume = stp_process_rxack(); ++ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; ++ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); ++ txAck = stp_core_ctx.sequence.txack; ++ ++ /*Send ack back */ ++ stp_send_ack(txAck, 0); ++ ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ fgRxOk = 0; ++ } ++ /* sequence matches expected, enqueue packet */ ++ else if (stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) { ++ is_function_active = ++ ((*sys_check_function_status) (stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) == ++ STATUS_FUNCTION_ACTIVE); ++ /*If type is valid and function works, then try to enqueue */ ++ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && (is_function_active == MTK_WCN_BOOL_TRUE)) { ++ if (stp_core_ctx.parser.type == BT_TASK_INDX) { ++ static const UINT8 rst_buf[7] = { 0x04, 0x0e, 0x04, 0x01, 0x3, 0xc, 0x00 }; ++ ++ if (!osal_strncmp(stp_core_ctx.rx_buf, rst_buf, 7)) ++ osal_printtimeofday("############ BT Rest end <--"); ++ } ++ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ fgTriggerResume = stp_process_rxack(); ++ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; ++ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); ++ ++ /*Send tx ack */ ++ txAck = stp_core_ctx.sequence.txack; ++ stp_send_ack(txAck, 0); ++ ++ stp_ctx_unlock(&stp_core_ctx); ++#if CFG_WMT_LTE_COEX_HANDLING ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++ fgRxOk = ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, COEX_TASK_INDX); ++ } else { ++ fgRxOk = ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ } ++#else ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++ STP_WARN_FUNC("BT/WIFI & LTE coex in non-LTE projects,drop it...\n"); ++ } else { ++ fgRxOk = ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ } ++#endif ++ } else { ++ if (is_function_active == MTK_WCN_BOOL_FALSE) { ++ STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n", ++ stp_core_ctx.parser.type); ++ fgRxOk = 0; /*drop packet */ ++ } else { ++ STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n", ++ stp_core_ctx.parser.type); ++ fgRxOk = 0; /*drop packet */ ++ } ++ stp_ctx_lock(&stp_core_ctx); ++ ++ fgTriggerResume = stp_process_rxack(); ++ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; ++ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); ++ ++ /*Send tx ack */ ++ txAck = stp_core_ctx.sequence.txack; ++ stp_send_ack(txAck, 0); ++ ++ stp_ctx_unlock(&stp_core_ctx); ++ } ++ ++ /* enqueue successfully */ ++ if (fgRxOk == 0) { ++ stp_process_packet_fail_count = 0; ++ /*notify corresponding subfunction of incoming data */ ++#if CFG_WMT_LTE_COEX_HANDLING ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++#if 1 ++ STP_DBG_FUNC ++ ("WMT/LTE package:[0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x]\n", ++ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], stp_core_ctx.rx_buf[2], ++ stp_core_ctx.rx_buf[3], stp_core_ctx.rx_buf[4], stp_core_ctx.rx_buf[5], ++ stp_core_ctx.rx_buf[6], stp_core_ctx.rx_buf[7]); ++#endif ++ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#else ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++ STP_WARN_FUNC("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); ++ } else { ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#endif ++ } else { ++ stp_process_packet_fail_count++; ++ /*Queue is full */ ++ if (stp_core_ctx.parser.type == GPS_TASK_INDX) { ++ /*Clear Rx Queue if GPS */ ++ mtk_wcn_stp_flush_rx_queue(GPS_TASK_INDX); ++ } else { ++ /*notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++ /*enqueue fail, don't send ack and wait for peer retry */ ++ STP_ERR_FUNC("Enqueue to Rx queue fail, maybe function %d queue is full\n", ++ stp_core_ctx.parser.type); ++ } ++ } ++ /*sequence not match && previous packet enqueue successfully, send the previous ACK */ ++ else if (fgRxOk == 0) { ++ STP_ERR_FUNC("mtkstp_process_packet: expected_rxseq = %d, parser.seq = %d\n", ++ stp_core_ctx.sequence.expected_rxseq, stp_core_ctx.parser.seq); ++ stp_process_packet_fail_count++; ++ ++ stp_ctx_lock(&stp_core_ctx); ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ txAck = stp_core_ctx.sequence.txack; ++ stp_send_ack(txAck, 1); ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ STP_ERR_FUNC ++ ("sequence not match && previous packet enqueue successfully, send the previous ACK (ack no =%d)\n", ++ txAck); ++ } ++ /*sequence not match && previous packet enqueue failed, do nothing, make the other side timeout */ ++ else { ++ stp_process_packet_fail_count++; ++ STP_ERR_FUNC ++ ("sequence not match && previous packet enqueue failed, do nothing, make the other side timeout\n"); ++ } ++ ++ if (fgTriggerResume == 0) { ++ /*[PatchNeed]Just Notificaiton, not blocking call */ ++ /* notify adaptation layer for possible tx resume mechanism */ ++ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); ++ } ++ ++ if (stp_process_packet_fail_count > MTKSTP_RETRY_LIMIT) { ++ stp_process_packet_fail_count = 0; ++ STP_ERR_FUNC("The process packet fail count > 10 lastly\n\r, whole chip reset\n\r"); ++ mtk_wcn_stp_dbg_dump_package(); ++ /*Whole Chip Reset Procedure Invoke */ ++ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ ++ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); ++ stp_dbg_set_host_assert_info(4, 37, 1); ++ STP_INFO_FUNC("**Ack Miss trigger firmware assert**\n"); ++ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); ++ if (iRet) { ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ /* (*sys_dbg_assert_aee)("[MT662x]Ack Miss", "**STP Ack Miss**\n Ack Miss.\n"); */ ++ osal_dbg_assert_aee("[SOC_CONSYS]Ack Miss", ++ "**[WCN_ISSUE_INFO]STP Ack Miss**\n Ack Miss.\n"); ++ ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) { ++ STP_SET_READY(stp_core_ctx, 0); ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ } ++ } ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_init ++* DESCRIPTION ++* init STP kernel ++* PARAMETERS ++* cb_func [IN] function pointers of system APIs ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func) ++{ ++ INT32 ret = 0; ++ INT32 i = 0; ++ ++ /* Function pointer to point to the currently used transmission interface ++ */ ++ sys_if_tx = cb_func->cb_if_tx; ++ ++ /* Used to inform the function driver has received the corresponding type of information */ ++ sys_event_set = cb_func->cb_event_set; ++ ++ /* Used to inform the function driver can continue to send information and ++ STP has resources to deal with ++ */ ++ sys_event_tx_resume = cb_func->cb_event_tx_resume; ++ ++ /* STP driver determines whether the function is enable. If not enable and ++ STP has received the kind of information, and STP have the right to put it away. ++ */ ++ sys_check_function_status = cb_func->cb_check_funciton_status; ++ ++ /* osal_unsleepable_lock_init(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock_init(&stp_core_ctx); ++ /* Setup timer to be used to check if f/w receive the data in the specific time ++ interval after being sent ++ */ ++ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) ++ osal_unsleepable_lock_init(&stp_core_ctx.ring[i].mtx); ++ ++ stp_core_ctx.tx_timer.timeoutHandler = stp_tx_timeout_handler; ++ stp_core_ctx.tx_timer.timeroutHandlerData = 0; ++ osal_timer_create(&stp_core_ctx.tx_timer); ++ ++ STP_SET_BT_STK(stp_core_ctx, 0); ++ STP_SET_ENABLE(stp_core_ctx, 0); ++ STP_SET_ENABLE_DBG(stp_core_ctx, 0); ++ STP_SET_ENABLE_RST(stp_core_ctx, 0); ++ STP_SET_PENDING_TYPE(stp_core_ctx, 0); ++ STP_SET_READY(stp_core_ctx, 0); ++ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, 0); ++ STP_SET_PSM_CORE(stp_core_ctx, stp_psm_init()); ++ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, 0); ++ STP_ENABLE_FW_COREDUMP(stp_core_ctx, 0); ++ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, 0); ++ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, 0); ++ ++ if (!STP_PSM_CORE(stp_core_ctx)) { ++ ret = (-3); ++ goto ERROR; ++ } ++ ++ STP_SET_BTM_CORE(stp_core_ctx, stp_btm_init()); ++ if (!STP_BTM_CORE(stp_core_ctx)) { ++ STP_ERR_FUNC("STP_BTM_CORE(stp_core_ctx) initialization fail!\n"); ++ ret = (-3); ++ goto ERROR; ++ } ++ ++ if (STP_BTM_CORE(stp_core_ctx) != NULL) ++ g_mtkstp_dbg = stp_dbg_init(STP_BTM_CORE(stp_core_ctx)); ++ else ++ g_mtkstp_dbg = stp_dbg_init(NULL); ++ ++ if (!g_mtkstp_dbg) { ++ STP_ERR_FUNC("g_mtkstp_dbg initialization fail!\n"); ++ ret = (-3); ++ goto ERROR; ++ } ++ STP_SET_ENABLE_RST(stp_core_ctx, 1); ++#ifdef CONFIG_LOG_STP_INTERNAL ++ mtk_wcn_stp_dbg_enable(); ++#else ++ mtk_wcn_stp_dbg_enable(); ++#endif ++ goto RETURN; ++ ++ERROR: ++ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); ++ ++RETURN: ++ return ret; ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_deinit ++* DESCRIPTION ++* deinit STP kernel ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++INT32 mtk_wcn_stp_deinit(void) ++{ ++ UINT32 i = 0; ++ ++ sys_if_tx = NULL; ++ sys_event_set = NULL; ++ sys_event_tx_resume = NULL; ++ sys_check_function_status = NULL; ++ ++ stp_dbg_deinit(g_mtkstp_dbg); ++ stp_btm_deinit(STP_BTM_CORE(stp_core_ctx)); ++ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); ++ ++ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) ++ osal_unsleepable_lock_deinit(&stp_core_ctx.ring[i].mtx); ++ ++ stp_ctx_lock_deinit(&stp_core_ctx); ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_btm_get_dmp ++* DESCRIPTION ++* get stp dump related information ++* PARAMETERS ++* buffer: dump placement, len: dump size ++* RETURNS ++* 0: Success Negative Value: Fail ++*****************************************************************************/ ++ ++int mtk_wcn_stp_btm_get_dmp(char *buf, int *len) ++{ ++ return stp_dbg_dmp_out(g_mtkstp_dbg, buf, len); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_notify_stp ++* DESCRIPTION ++* WMT notification to STP that power saving job is done or not ++* PARAMETERS ++* ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++int mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action) ++{ ++ return stp_psm_notify_stp(STP_PSM_CORE(stp_core_ctx), action); ++} ++ ++int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state) ++{ ++ return stp_psm_set_state(STP_PSM_CORE(stp_core_ctx), state); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_enable ++* DESCRIPTION ++* enable STP sleep/wakeup support ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep) ++{ ++#if 0 ++ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { ++ if (mtk_wcn_stp_is_ready()) ++ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ } ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); ++ return 0; ++ } ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ ++#else ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); ++ return 0; ++ } ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++#endif ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_disable ++* DESCRIPTION ++* disable STP sleep/wakeup support ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_psm_disable(VOID) ++{ ++#if 0 ++ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { ++ if (mtk_wcn_stp_is_ready()) ++ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ } ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ return 0; ++ } ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ ++#else ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ return 0; ++ } ++ STP_DBG_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return 0; ++ ++#endif ++} ++ ++extern INT32 mtk_wcn_stp_psm_reset(VOID) ++{ ++ return stp_psm_reset(STP_PSM_CORE(stp_core_ctx)); ++} ++ ++extern INT32 mtk_wcn_stp_dbg_disable(VOID) ++{ ++ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { ++ STP_DBG_FUNC("STP dbg mode is turned off\n"); ++ STP_SET_ENABLE_DBG(stp_core_ctx, 0); ++ stp_dbg_disable(g_mtkstp_dbg); ++ } else { ++ STP_WARN_FUNC("STP dbg mode has been turned off\n"); ++ } ++ ++ return 0; ++} ++ ++extern INT32 mtk_wcn_stp_dbg_enable(VOID) ++{ ++ if (STP_NOT_ENABLE_DBG(stp_core_ctx)) { ++ STP_DBG_FUNC("STP dbg mode is turned on\n"); ++ STP_SET_ENABLE_DBG(stp_core_ctx, 1); ++ stp_dbg_enable(g_mtkstp_dbg); ++ } else { ++ STP_WARN_FUNC("STP dbg mode has been turned on\n"); ++ } ++ ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on) ++{ ++ stp_dbg_log_ctrl(on); ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on) ++{ ++ STP_ENABLE_FW_COREDUMP(stp_core_ctx, on); ++ STP_INFO_FUNC("coredump function mode: %d.\n", on); ++ g_coredump_mode = on; ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_coredump_flag_get(VOID) ++{ ++ return STP_ENABLE_FW_COREDUMP_FLAG(stp_core_ctx); ++} ++ ++static INT32 stp_parser_data_in_mand_mode(UINT32 length, UINT8 *p_data) ++{ ++ UINT8 padding_len = 0; ++ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ ++ MTK_WCN_BOOL is_function_active = 0; ++ INT32 i = length; ++ ++ while (i > 0) { ++ switch (stp_core_ctx.parser.state) { ++ case MTKSTP_SYNC: /* b'10 */ ++ /* if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) */ ++ /* if(*p_data == 0x80) */ ++ if ((*p_data & 0x80) == 0x80) { ++ /* STP_DBG_FUNC("[STP] STP Packet Start =========>\n"); */ ++ if (*p_data != 0x80) ++ STP_WARN_FUNC("SDIO not 0x80!!(0x%x)\n", *p_data); ++ ++ if (i >= 4) { ++#if !(REMOVE_USELESS_LOG) ++ /*print header, when get the full STP header */ ++ UINT32 type = (*(p_data + 1) & 0x70) >> 4; ++ UINT8 *type_name = ""; ++ ++ type_name = stp_type_to_dbg_string(type); ++ STP_DBG_FUNC( ++ "STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", ++ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), ++ type_name, ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), ++ (*p_data & 0x38) >> 3, *p_data & 0x07); ++#endif ++ } else { ++ STP_WARN_FUNC("STP Rx: discard due to i < 4 (%d)\n", i); ++ } ++ ++ /* STP_DBG_FUNC("[STP] sync->nak\n"); */ ++ stp_change_rx_state(MTKSTP_NAK); ++ stp_core_ctx.rx_counter++; ++ } else { ++ STP_WARN_FUNC("sync to sync!!(0x%x)\n", *p_data); ++ stp_change_rx_state(MTKSTP_SYNC); ++ } ++ break; ++ ++ case MTKSTP_NAK: ++ /* STP_DBG_FUNC("[STP] nak->length\n"); */ ++ stp_change_rx_state(MTKSTP_LENGTH); ++ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; ++ if (stp_core_ctx.parser.type <= MTKSTP_MAX_TASK_NUM) { ++ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; ++ stp_core_ctx.rx_counter++; ++ } else { ++ STP_WARN_FUNC("nak to sync\n"); ++ stp_change_rx_state(MTKSTP_SYNC); ++ } ++ break; ++ ++ case MTKSTP_LENGTH: ++ /* STP_DBG_FUNC("[STP] length -> checksum\n"); */ ++ stp_change_rx_state(MTKSTP_CHECKSUM); ++ stp_core_ctx.parser.length += *p_data; ++ ++ /*Valid length checking */ ++ if (stp_core_ctx.parser.length < 2000) { ++ stp_core_ctx.rx_counter++; ++ } else { ++ STP_WARN_FUNC("The length of STP packet is not valid !!! length = %d\n", ++ stp_core_ctx.parser.length); ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ /* return -1; */ ++ } ++ ++ break; ++ ++ case MTKSTP_CHECKSUM: ++ ++ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || ++ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { ++ stp_change_rx_state(MTKSTP_FW_MSG); ++ stp_core_ctx.rx_counter = 0; ++ i -= 1; ++ if (i != 0) ++ p_data += 1; ++ ++ continue; ++ } ++ ++ if (stp_core_ctx.parser.length == 0) { ++ STP_WARN_FUNC("checksum to sync\n"); ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ } else { ++ /* STP_DBG_FUNC("[STP] checksum->data\n"); */ ++ stp_change_rx_state(MTKSTP_DATA); ++ stp_core_ctx.rx_counter = 0; ++ } ++ break; ++ ++ case MTKSTP_DATA: ++ ++ /* block copy instead of byte copy */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ osal_assert(0); ++ } ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ if (i >= remain_length) { ++ /*boundary checking */ ++ if (stp_core_ctx.rx_counter + remain_length >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC("Abnormal!! Memory operation over boundary!!\n"); ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ return -1; ++ } ++ ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ stp_core_ctx.parser.state = MTKSTP_CRC1; ++ continue; ++ ++ } else { /* only copy by data length */ ++ ++ /*fixed klocwork insight issue */ ++ /*boundary checking */ ++ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC("Abnormal!! Memory operation over boundary 2!!\n"); ++ stp_core_ctx.rx_counter = 0; ++ return -1; ++ } ++ ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); ++ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ ++ i = 0; ++ p_data += i; ++ continue; ++ } ++ break; ++ ++ case MTKSTP_CRC1: ++ stp_change_rx_state(MTKSTP_CRC2); ++ break; ++ ++ case MTKSTP_CRC2: ++#if 1 ++ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { ++ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; ++ STP_DBG_FUNC("wmt sub type (0x%x)\n", stp_core_ctx.parser.wmtsubtype); ++ } ++#endif ++ /*SDIO mode do it. */ ++ if (mtk_wcn_stp_is_sdio_mode()) { ++ /*STP packet 4-bytes alignment */ ++ /*Discard padding bytes , otherwise make parser state machine disorder */ ++ if (i <= 4) { ++ /*STP_DBG_FUNC("STP last block padding %d bytes\n", i-1); */ ++ p_data += (i - 1); ++ i -= (i - 1); ++ } else { ++ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; ++ p_data += padding_len; ++ i -= padding_len; ++ /*STP_DBG_FUNC("STP Agg padding %d bytes\n", padding_len); */ ++ } ++ } ++ stp_dbg_pkt_log(stp_core_ctx.parser.type, ++ 0, 0, 0, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); ++ if ((stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { ++ int b; ++ ++ /*Indicate packet to hci_stp */ ++ if (gStpDbgLvl >= STP_LOG_DBG) { ++ stp_dump_data(stp_core_ctx.rx_buf, "indicate_to_bt_core", ++ stp_core_ctx.rx_counter); ++ } ++ ++ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); ++ if (b) ++ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); ++ ++ } else { ++ ++ is_function_active = ( ++ (*sys_check_function_status)(stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) ++ == STATUS_FUNCTION_ACTIVE); ++ ++ /*check type and function if active? */ ++ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) ++ && (is_function_active == MTK_WCN_BOOL_TRUE)) { ++#if CFG_WMT_LTE_COEX_HANDLING ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) ++ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { ++ STP_INFO_FUNC("wmt/lte coex package!\n"); ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, ++ stp_core_ctx.rx_counter, COEX_TASK_INDX); ++ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, ++ stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ ++ /*notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#else ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) ++ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { ++ STP_WARN_FUNC ++ ("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); ++ } else { ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, ++ stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ ++ /*notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#endif ++ } else { ++ if (is_function_active == MTK_WCN_BOOL_FALSE) { ++ STP_ERR_FUNC ++ ("function type = %d is inactive, so no en-queue to rx\n", ++ stp_core_ctx.parser.type); ++ } else { ++ STP_ERR_FUNC ++ ("mtkstp_process_packet: type = %x, the type is invalid\n", ++ stp_core_ctx.parser.type); ++ } ++ } ++ } ++ ++ /* STP_DBG_FUNC("[STP] crc2->sync\n"); */ ++ /* STP_DBG_FUNC("[STP] STP Packet End <=========\n"); */ ++ stp_core_ctx.rx_counter = 0; ++ stp_change_rx_state(MTKSTP_SYNC); ++ ++ break; ++ ++ case MTKSTP_FW_MSG: ++ ++ /*f/w assert and exception information */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ } ++ ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ ++ if (i >= remain_length) { ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; ++ /*Trace32 Dump */ ++ if (stp_core_ctx.parser.type == STP_TASK_INDX) { ++ /* g_block_tx = 1; */ ++ mtk_wcn_stp_coredump_start_ctrl(1); ++ pr_debug("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); ++ /*use paged dump or full dump */ ++ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); ++#if 0 ++ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_DMP /*STP_DBG_FW_ASSERT */ , 5, ++ 0, 0, 0, 0, ++ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); ++#endif ++ } ++ ++ /*discard CRC */ ++ /* we will discard antoher CRC on the outer switch procedure. */ ++ if (i >= 1) { ++ STP_INFO_FUNC("crc discard.. i = %d\n", i); ++ i -= 1; ++ if (i > 0) ++ p_data += 1; ++ ++ } ++ ++ /*STP packet 4-bytes alignment */ ++ /*Discard padding bytes , otherwise make parser state machine disorder */ ++ if (i <= 4) { ++ STP_INFO_FUNC ++ ("\n[STP]FW_EVENT========= block padding %d bytes =========\n", ++ i - 1); ++ p_data += (i - 1); ++ i -= (i - 1); ++ } else { ++ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; ++ p_data += padding_len; ++ i -= padding_len; ++ STP_INFO_FUNC ++ ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n", ++ padding_len); ++ } ++ stp_change_rx_state(MTKSTP_SYNC); ++ ++ } else { /* only copy by data length */ ++ ++ STP_ERR_FUNC("raw data doesn't contain full stp packet!!\n"); ++ } ++ break; ++ default: ++ break; ++ } ++ p_data++; ++ i--; ++ } ++ ++ return 0; ++} ++ ++static INT32 stp_parser_data_in_full_mode(UINT32 length, UINT8 *p_data) ++{ ++ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ ++ INT32 i = length; ++ ++ while (i > 0) { ++ switch (stp_core_ctx.parser.state) { ++ ++ case MTKSTP_RESYNC1: /* RESYNC must be 4 _continuous_ 0x7f */ ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_RESYNC2); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_RESYNC2: ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_RESYNC3); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_RESYNC3: ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_RESYNC4); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_RESYNC4: ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_SYNC); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_SYNC: /* b'10 */ ++ STP_DUMP_PACKET_HEAD(p_data, "rx (uart):", length > 4 ? 4 : length); ++ if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) { ++ stp_change_rx_state(MTKSTP_NAK); ++ stp_core_ctx.parser.seq = (*p_data & 0x38) >> 3; ++ stp_core_ctx.parser.ack = *p_data & 0x07; ++ stp_core_ctx.rx_buf[0] = *p_data; ++ /* Geoge FIXME: WHY comment the following line? */ ++ /* stp_core_ctx.rx_counter++; */ ++ ++ if (i >= 4 && gStpDbgLvl >= STP_LOG_DBG) { ++ /*print header, when get the full STP header */ ++#if !(REMOVE_USELESS_LOG) ++ int type = (*(p_data + 1) & 0x70) >> 4; ++ char *type_name = ""; ++ ++ type_name = stp_type_to_dbg_string(type); ++ ++ STP_DBG_FUNC ++ ("STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", ++ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), type_name, ++ ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), ++ (*p_data & 0x38) >> 3, *p_data & 0x07); ++#endif ++ } else { ++ STP_DBG_FUNC("STP Rx: discard due to i < 4\n"); ++ } ++ } else if ((*p_data == 0x7f) && (prev_state == MTKSTP_RESYNC4)) { ++ /* if this 0x7f is continuous to resync pattern */ ++ /* skip this continuous 0x7f, remain current & prev state */ ++ osal_assert(0); ++ STP_ERR_FUNC("MTKSTP_SYNC: continuous resync pattern, buff = %x\n", *p_data); ++ } else if (*p_data == 0x7f) { /* a start of 0x7f, maybe this is resync pattern */ ++ stp_change_rx_state(MTKSTP_RESYNC2); ++ osal_assert(0); ++ STP_ERR_FUNC("MTKSTP_SYNC: go to MTKSTP_RESYNC2, buff = %x\n", *p_data); ++ } else if (*p_data == 0x55) { /* STP delimiter */ ++ /* do nothing for delimiter */ ++ } else { /* unexpected, go to resync1 */ ++ osal_assert(0); ++ STP_ERR_FUNC("MTKSTP_SYNC: unexpected data, buff = %x\n", *p_data); ++ } ++ break; ++ ++ case MTKSTP_NAK: ++ /* (*sys_dbg_print)("MTKSTP_NAK : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ ++ if (fgEnableNak == 0) ++ stp_core_ctx.parser.nak = 0; /* disable NAK */ ++ else ++ stp_core_ctx.parser.nak = (*p_data & 0x80) >> 7; ++ ++ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; ++ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; ++ stp_core_ctx.rx_buf[1] = *p_data; ++ /* Geoge FIXME: WHY comment the following line? */ ++ /*stp_core_ctx.rx_counter++; */ ++ if (stp_core_ctx.parser.nak) ++ STP_ERR_FUNC("MTKSTP_NAK TRUE: mtk_wcn_stp_parser_data, buff = %x\n", *p_data); ++ ++ if (stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) ++ stp_change_rx_state(MTKSTP_LENGTH); ++ else ++ stp_change_rx_state(MTKSTP_SYNC); ++ break; ++ ++ case MTKSTP_LENGTH: ++ /* (*sys_dbg_print)("MTKSTP_LENGTH : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ ++ stp_change_rx_state(MTKSTP_CHECKSUM); ++ stp_core_ctx.parser.length += *p_data; ++ ++ /*Valid length checking */ ++ if (stp_core_ctx.parser.length > 2048) { ++ STP_ERR_FUNC("The length of STP packet is not valid !!! length = %d\n", ++ stp_core_ctx.parser.length); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ STP_TRACE_FUNC("--\n"); ++ return -1; ++ } ++ ++ stp_core_ctx.rx_buf[2] = *p_data; ++ /* Geoge FIXME: WHY comment the following line? */ ++ /*stp_core_ctx.rx_counter++; */ ++ break; ++ ++ case MTKSTP_CHECKSUM: ++ /* (*sys_dbg_print)("MTKSTP_CHECKSUM : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ ++ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || ++ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { ++ stp_change_rx_state(MTKSTP_FW_MSG); ++ stp_core_ctx.rx_counter = 0; ++ i -= 1; ++ if (i != 0) ++ p_data += 1; ++ ++ continue; ++ } ++ ++ if (((stp_core_ctx.rx_buf[0] + ++ stp_core_ctx.rx_buf[1] + stp_core_ctx.rx_buf[2]) & 0xff) == *p_data) { ++ /* header only packet */ ++ if (stp_core_ctx.parser.length == 0) { ++ INT32 fgTriggerResume = (-1); ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ if (stp_core_ctx.inband_rst_set == 0) { ++ stp_dbg_pkt_log(STP_TASK_INDX, ++ stp_core_ctx.parser.ack, ++ stp_core_ctx.parser.seq, ++ 5, /* STP type id */ ++ PKT_DIR_RX, ++ NULL, ++ 0); ++ fgTriggerResume = stp_process_rxack(); ++ } else { ++ STP_WARN_FUNC ++ ("Now it's inband reset process and drop ACK packet.\n"); ++ } ++ ++ if (fgTriggerResume == 0) { ++ /* notify adaptation layer for ++ * possible tx resume mechanism ++ */ ++ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); ++ } ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ } else { ++ stp_change_rx_state(MTKSTP_DATA); ++ stp_core_ctx.rx_counter = 0; ++ } ++ } else { ++ STP_ERR_FUNC("The checksum of header is error !!! %02x %02x %02x %02x\n", ++ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], ++ stp_core_ctx.rx_buf[2], *p_data); ++ /* George FIXME: error handling mechanism shall be refined */ ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ ++ /* since checksum error is usually related to interface ++ * buffer overflow, so we just let timeout mechanism to ++ * handle such error. ++ */ ++ STP_TRACE_FUNC("--\n"); ++ /* return and purge COMM port */ ++ return -1; ++ /*stp_send_ack(1); NAK mechanism is removed */ ++ } ++ break; ++ ++ case MTKSTP_DATA: ++#if 0 ++ if (stp_core_ctx.rx_counter < stp_core_ctx.parser.length) { ++ stp_core_ctx.rx_buf[stp_core_ctx.rx_counter] = *p_data; ++ stp_core_ctx.rx_counter++; ++ } ++ if (stp_core_ctx.rx_counter == stp_core_ctx.parser.length) ++ stp_change_rx_state(MTKSTP_CRC1); ++#else ++ /* block copy instead of byte copy */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ osal_assert(0); ++ } ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ if (i >= remain_length) { ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ stp_core_ctx.parser.state = MTKSTP_CRC1; ++ continue; ++ } else { /* only copy by data length */ ++ ++ /*fixed klocwork insight issue */ ++ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC ++ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ STP_TRACE_FUNC("--\n"); ++ return -1; ++ } ++ ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); ++ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ ++ i = 0; ++ p_data += i; ++ continue; ++ } ++#endif ++ break; ++ ++ case MTKSTP_CRC1: ++ stp_change_rx_state(MTKSTP_CRC2); ++ stp_core_ctx.parser.crc = *p_data; ++ break; ++ case MTKSTP_CRC2: ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.parser.crc += (*p_data) << 8; ++#if 1 ++ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { ++ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; ++ STP_DBG_FUNC("wmt sub type is (0x%x)\n", stp_core_ctx.parser.wmtsubtype); ++ } ++#endif ++ if (stp_check_crc(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, stp_core_ctx.parser.crc) ++ == MTK_WCN_BOOL_TRUE) { ++ if (stp_core_ctx.inband_rst_set == 0) ++ stp_process_packet(); ++ else ++ STP_WARN_FUNC("Now it's inband reset process and drop packet.\n"); ++ } else { ++ STP_ERR_FUNC("The CRC of packet is error !!!\n"); ++ /* George FIXME: error handling mechanism shall be refined */ ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ ++ /* since checksum error is usually related to interface ++ * buffer overflow, so we just let timeout mechanism to ++ * handle such error. ++ */ ++ STP_TRACE_FUNC("--\n"); ++ /* return and purge COMM port */ ++ return -1; ++ /*stp_send_ack(1); NAK mechanism is removed */ ++ } ++ break; ++ ++ case MTKSTP_FW_MSG: ++#if CFG_WMT_DUMP_INT_STATUS ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ if (STP_IS_READY(stp_core_ctx)) ++ mtk_wcn_stp_dbg_dump_package(); ++ ++ STP_SET_READY(stp_core_ctx, 0); ++ /*stp inband reset */ ++ if (stp_core_ctx.parser.type == STP_TASK_INDX && ++ stp_core_ctx.parser.seq == 0 && ++ stp_core_ctx.parser.ack == 0 && ++ stp_core_ctx.parser.length == 0 && stp_core_ctx.inband_rst_set == 1) { ++ STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r"); ++ stp_rest_ctx_state(); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.inband_rst_set = 0; ++ /* STP_INFO_FUNC("Restart STP Timer\n\r"); */ ++ /* (*sys_timer_start)(stp_core_ctx.tx_timer, ++ * mtkstp_tx_timeout, ++ * (MTK_WCN_TIMER_CB)stp_tx_timeout_handler, ++ * NULL); ++ */ ++ STP_TRACE_FUNC("--\n"); ++ return 0; ++ } ++ ++ /*f/w assert and exception information */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ osal_assert(0); ++ } ++ ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ if (i >= remain_length) { ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ stp_change_rx_state(MTKSTP_SYNC); ++ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; ++ /* STP_ERR_FUNC("%s [%d]\n", stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); */ ++#if 0 ++ if ((stp_core_ctx.rx_counter == 1) && (stp_core_ctx.rx_buf[0] == 0xFF)) { ++ /* For MT6620, enable/disable coredump function is controlled by ++ * firmware for the moment, we need to set coredump enable flag ++ * to be 1 after see firmware send a pariticallar character(0xff) ++ * before any coredump packet is sent ++ */ ++ mtk_wcn_stp_coredump_flag_ctrl(1); ++ } ++#endif ++ /*Trace32 Dump */ ++ if (STP_IS_ENABLE_DBG(stp_core_ctx) && ++ (stp_core_ctx.parser.type == STP_TASK_INDX)) { ++ if (0 != stp_core_ctx.rx_counter) { ++ STP_SET_READY(stp_core_ctx, 0); ++ mtk_wcn_stp_ctx_save(); ++ STP_INFO_FUNC("++ start to read paged dump and paged trace ++\n"); ++ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); ++ stp_btm_notify_wmt_trace_wq(stp_core_ctx.btm); ++ STP_INFO_FUNC("++ start to read paged dump and paged trace --\n"); ++ ++ } ++ STP_INFO_FUNC("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); ++ } ++ ++ /*Runtime FW Log */ ++ else if (STP_IS_ENABLE_DBG(stp_core_ctx) ++ && (stp_core_ctx.parser.type == INFO_TASK_INDX)) { ++ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0, ++ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); ++ mtk_wcn_stp_dbg_dump_package(); ++ } ++ /*Normal mode: whole chip reset */ ++ else { ++ /*Aee Kernel Warning Message Shown First */ ++ /* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */ ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ mtk_wcn_stp_dbg_dump_package(); ++ ++ osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf); ++ /*Whole Chip Reset Procedure Invoke */ ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) { ++ STP_SET_READY(stp_core_ctx, 0); ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ STP_INFO_FUNC ++ ("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ } ++ /*discard CRC */ ++ if (i >= 2) { ++ STP_DBG_FUNC("crc discard.. i = %d\n", i); ++ i -= 2; ++ if (i > 0) ++ p_data += 2; ++ } ++ continue; ++ } else { /* only copy by data length */ ++ ++ /*fixed klocwork insight issue */ ++ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC ++ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ return -1; ++ } ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); ++ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ ++ i = 0; ++ p_data += i; ++ continue; ++ } ++ ++ break; ++ default: ++ break; ++ } ++ p_data++; ++ i--; ++ } ++ ++ return 0; ++} ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_parser_data ++* DESCRIPTION ++* push data to serial transport protocol parser engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* int 0 = success; -1 = crc/checksum error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++int _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) ++#else ++int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) ++#endif ++{ ++ /*----------------------------------------------------------------*/ ++ /* Local Variables */ ++ /*----------------------------------------------------------------*/ ++ INT32 i; ++ UINT8 *p_data; ++ INT32 ret = 0; ++#ifdef DEBUG_DUMP_PACKET_HEAD ++ static UINT32 counter; ++ ++ STP_TRACE_FUNC("++, rx (cnt=%d,len=%d)\n", ++counter, length); ++#endif ++ ++#if 0 ++#ifdef CONFIG_POWER_SAVING_SUPPORT ++ if (stp_is_apply_powersaving()) { ++ /* If now chip is awake, to restart monitor! */ ++ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { ++ STP_DBG_FUNC("To restart moinotr when rx\n\r"); ++ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); ++ } ++ } ++#endif ++#endif ++ ++ /*----------------------------------------------------------------*/ ++ /* Code Body */ ++ /*----------------------------------------------------------------*/ ++ /* George FIXME: WHY or HOW can we reduct the locked region? */ ++ /*flags = (*sys_mutex_lock)(stp_core_ctx.stp_mutex); */ ++ i = length; ++ p_data = (UINT8 *) buffer; ++ ++/* stp_dump_data(buffer, "rx queue", length); */ ++ ++ /*STP is not enabled and only WMT can use Raw data path */ ++ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == STP_PENDING_TYPE(stp_core_ctx)) { ++ /* route to task who send command */ ++ stp_add_to_rx_queue(buffer, length, STP_PENDING_TYPE(stp_core_ctx)); ++ ++ /* mike: notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (STP_PENDING_TYPE(stp_core_ctx)); ++ } ++ /* STP over SDIO */ ++ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++#if !(REMOVE_USELESS_LOG) ++ if (gStpDbgLvl >= STP_LOG_DBG) ++ stp_dump_data(buffer, "sdio parser_in", length); ++#endif ++ /* STP_DBG_FUNC("sdio stp parser data length = %d\n", length); */ ++ ret = stp_parser_data_in_mand_mode(i, p_data); ++ } ++ /* STP over UART */ ++ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) ++ ret = stp_parser_data_in_full_mode(i, p_data); ++ ++ /* George FIXME: WHY or HOW can we reduct the locked region? */ ++ /*(*sys_mutex_unlock)(stp_core_ctx.stp_mutex, flags); */ ++ STP_TRACE_FUNC("--\n"); ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_parser_data); ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_enable ++* DESCRIPTION ++* enable/disable STP ++* PARAMETERS ++* value [IN] 0=disable, others=enable ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++INT32 mtk_wcn_stp_enable(INT32 value) ++{ ++ STP_DBG_FUNC("%s: set the current enable = (%d)\n", __func__, value); ++ ++ stp_rest_ctx_state(); ++ STP_SET_ENABLE(stp_core_ctx, value); ++ if (!value) { ++ mtk_wcn_stp_psm_reset(); ++ } else { ++/* g_block_tx = 0; */ ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ } ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_dbg_dump_package(VOID) ++{ ++ if (STP_NOT_ENABLE(stp_core_ctx)) { ++ STP_INFO_FUNC("STP dbg mode is off\n"); ++ ++ } else { ++ STP_INFO_FUNC("STP dbg mode is on\n"); ++ /* if (0 == g_block_tx) */ ++ if (0 == mtk_wcn_stp_coredump_start_get()) { ++ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); ++ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); ++ stp_dbg_dmp_printk(g_mtkstp_dbg); ++ } else { ++ STP_INFO_FUNC("assert start flag is set, disable packet dump function\n"); ++ } ++ } ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_ready ++* DESCRIPTION ++* ready/un-ready STP ++* PARAMETERS ++* value [IN] 0=un-ready, others=ready ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++INT32 mtk_wcn_stp_ready(INT32 value) ++{ ++ STP_DBG_FUNC("set ready (%d)\n", value); ++ ++ STP_SET_READY(stp_core_ctx, value); ++ /*if whole chip reset, reset the debuggine mode */ ++#ifndef CONFIG_LOG_STP_INTERNAL ++ /* mtk_wcn_stp_dbg_disable(); */ ++#endif ++ ++ if (stp_is_apply_powersaving()) { ++ STP_INFO_FUNC("Restart the stp-psm monitor !!\n"); ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ } ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_ctrl ++* DESCRIPTION ++* set f/w assert flag in STP context ++* PARAMETERS ++* value [IN] 0=assert end, others=assert begins ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value) ++{ ++ STP_DBG_FUNC("set f/w assert (%d)\n", value); ++ ++ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, value); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_get ++* DESCRIPTION ++* get f/w assert flag in STP context ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0= f/w assert flag is not set, others=f/w assert flag is set ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_coredump_start_get(VOID) ++#else ++INT32 mtk_wcn_stp_coredump_start_get(VOID) ++#endif ++{ ++ return STP_FW_COREDUMP_FLAG(stp_core_ctx); ++} ++ ++/* mtk_wcn_stp_set_wmt_last_close -- set the state of link(UART or SDIO) ++ * @ value - 1, link already be closed; 0, link is open ++ * ++ * Return 0 if success; else error code ++ */ ++INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value) ++{ ++ STP_INFO_FUNC("set wmt_last_close flag (%d)\n", value); ++ ++ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, value); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data ++* DESCRIPTION ++* subfunction send data through STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 > 0: length transmitted; = 0: error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#else ++INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#endif ++{ ++ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; ++ UINT8 *p_tx_buf = NULL; ++ UINT16 crc; ++ INT32 ret = 0; ++ MTK_WCN_BOOL is_quick_enable = MTK_WCN_BOOL_TRUE; ++ ++ /* osal_buffer_dump(buffer,"tx", length, 32); */ ++ ++ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { ++ STP_ERR_FUNC("WMT lats close,should not have tx request!\n"); ++ return length; ++ } ++ /* if(g_block_tx) */ ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ STP_ERR_FUNC("STP fw coredump start flag set...\n"); ++ return length; ++ } ++#ifdef CONFIG_POWER_SAVING_SUPPORT ++ is_quick_enable = stp_psm_is_quick_ps_support(); ++ STP_DBG_FUNC("is quick sleep enable:%s\n", is_quick_enable ? "yes" : "no"); ++ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { ++ if (type != WMT_TASK_INDX) { ++#if PSM_USE_COUNT_PACKAGE ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0); ++#else ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0, length); ++#endif ++ } ++ /* if(stp_is_apply_powersaving()) */ ++ { ++ if (type == WMT_TASK_INDX) ++ goto DONT_MONITOR; ++ /*-----------------------------STP_PSM_Lock----------------------------------------*/ ++ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); ++ if (ret) { ++ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); ++ return ret; ++ } ++ ++ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { ++ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { ++ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); ++ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); ++ } ++ } else { ++ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); ++ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); ++ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ return ret; ++ } ++ } ++ } else { ++ /* if(stp_is_apply_powersaving()) */ ++ { ++ if (type == WMT_TASK_INDX) ++ goto DONT_MONITOR; ++ /* If now chip is awake, to restart monitor! */ ++ /* STP_INFO_FUNC("check if block traffic !!\n"); */ ++ /*-----------------------------STP_PSM_Lock----------------------------------------*/ ++ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); ++ if (ret) { ++ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); ++ return ret; ++ } ++ ++ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { ++ /* STP_INFO_FUNC("not to block !!\n"); */ ++ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { ++ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); ++ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); ++ } ++ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); ++ } else { ++ /* STP_INFO_FUNC("to block !!\n"); */ ++ ++ /* STP_INFO_FUNC("*****hold data in psm queue data length = %d\n", ++ * length); ++ */ ++ /* stp_dump_data(buffer, "Hold in psm queue", length); */ ++ /* hold datas */ ++ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); ++ /* wmt notification */ ++ STP_INFO_FUNC("#####Type = %d, to inform WMT to wakeup chip, ret = %d:0x%2x,0x%2x\n", ++ type, ret, *buffer, *(buffer + 1)); ++ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); ++ /* STP_INFO_FUNC("*********Type = %d, to inform WMT to wakeup chip>end\n", type); */ ++ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ return ret; ++ } ++ } ++ } ++DONT_MONITOR: ++#endif ++ if (type == BT_TASK_INDX) { ++ static const UINT8 rst_buf[4] = { 0x01, 0x03, 0x0c, 0x00 }; ++ ++ if (!osal_strncmp(buffer, rst_buf, 4)) ++ osal_printtimeofday("############ BT Rest start -->"); ++ } ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ /*Only WMT can set raw data */ ++ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { ++ /* no-op */ ++ /* NULL; */ ++ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { ++ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ ++ /* NULL; */ ++ } ++ /* STP over SDIO */ ++ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++ ++ /* osal_printtimeofday("[ STP][SDIO][ B][W]"); */ ++ ++ mtkstp_header[0] = 0x80; ++ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); ++ mtkstp_header[2] = (length) & 0xff; ++ mtkstp_header[3] = 0x00; ++ ++ /* HEADER */ ++ p_tx_buf = &stp_core_ctx.tx_buf[0]; ++ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); ++ p_tx_buf += MTKSTP_HEADER_SIZE; ++ ++ /* PAYLOAD */ ++ osal_memcpy(p_tx_buf, buffer, length); ++ p_tx_buf += length; ++ ++ /* CRC */ ++ temp[0] = 0x00; ++ temp[1] = 0x00; ++ osal_memcpy(p_tx_buf, temp, 2); ++ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length); ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); ++ ++ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { ++ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); ++ osal_assert(0); ++ ret = 0; ++ } else { ++ ret = (INT32) length; ++ } ++ ++ /* osal_printtimeofday("[ STP][SDIO][ E][W]"); */ ++ } ++ /* STP over UART */ ++ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) { ++ ++ /* osal_printtimeofday("[ STP][UART][ B][W]"); */ ++ /* STP_INFO_FUNC("Write byte %d\n", length); */ ++ ++ if ((stp_core_ctx.sequence.winspace > 0) && ++ (stp_core_ctx.inband_rst_set == 0) && ++ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { ++ /*Make Header */ ++ /* (*sys_dbg_print)("mtk_wcn_stp_send_data 1, txseq = %d, winspace = %d", ++ * stp_core_ctx.sequence.txseq, stp_core_ctx.sequence.winspace); ++ */ ++ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; ++ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); ++ mtkstp_header[2] = length & 0xff; ++ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; ++ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; ++ if (fgEnableDelimiter == 1) { ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; ++ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); ++ } ++ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); ++ ++ /*Make Payload */ ++ stp_add_to_tx_queue(buffer, length); ++ ++ /*Make CRC */ ++ crc = osal_crc16(buffer, length); ++ temp[0] = crc & 0xff; ++ temp[1] = (crc & 0xff00) >> 8; ++ stp_add_to_tx_queue(temp, 2); ++ stp_dbg_pkt_log(type, ++ stp_core_ctx.sequence.txack, ++ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); ++ ++ /*Kick to UART */ ++ stp_send_tx_queue(stp_core_ctx.sequence.txseq); ++ ++ INDEX_INC(stp_core_ctx.sequence.txseq); ++ stp_core_ctx.sequence.winspace--; ++ ++ /*Setup the Retry Timer */ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ else ++ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); ++ ++ ret = (INT32) length; ++ } else { ++ /* ++ No winspace to send. Let caller retry ++ */ ++ if (stp_core_ctx.inband_rst_set == 1) ++ STP_WARN_FUNC("Now it's inband reset process and drop sent packet.\n"); ++ else ++ STP_ERR_FUNC("There is no winspace/txqueue to send !!!\n"); ++ ++ ret = 0; ++ } ++ ++ /* osal_printtimeofday("[ STP][UART][ E][W]"); */ ++ } ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ ++#ifdef CONFIG_POWER_SAVING_SUPPORT ++ ++ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { ++ if (type != WMT_TASK_INDX) { ++ stp_psm_notify_wmt_sleep(STP_PSM_CORE(stp_core_ctx)); ++ /*-----------------------STP_PSM_UnLock-------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ } ++ } else { ++ /* if(stp_is_apply_powersaving()) */ ++ /* { */ ++ if (type != WMT_TASK_INDX) { ++ ++ /*--------------------STP_PSM_UnLock--------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ } ++ /* } */ ++ } ++#endif ++ ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_send_data); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data_raw ++* DESCRIPTION ++* send raw data to common interface, bypass STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#else ++INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#endif ++{ ++ UINT32 written = 0; ++ INT32 ret = 0; ++ ++ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { ++ STP_ERR_FUNC("WMT lats close,should not have tx request!"); ++ return length; ++ } ++ ++ STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d, data = %x %x %x %x %x %x ", type, buffer[0], buffer[1], ++ buffer[2], buffer[3], buffer[4], buffer[5]); ++ STP_SET_PENDING_TYPE(stp_core_ctx, type); /* remember tx type, forward following rx to this type */ ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, 1); ++ (*sys_if_tx) (&buffer[0], length, &written); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ ++ if (written == 0) ++ stp_dump_data(&buffer[0], "tx raw failed:", length); ++ ++ if (written == length) ++ ret = (INT32) written; ++ else ++ ret = (-1); ++ ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_receive_data ++* DESCRIPTION ++* receive data from serial protocol engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: size of data received; < 0: error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) ++#else ++INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) ++#endif ++{ ++ /* GeorgeKuo modify: reduce "if" branch */ ++ UINT16 copyLen = 0; ++ UINT16 tailLen = 0; ++ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ while (stp_core_ctx.ring[type].read_p != stp_core_ctx.ring[type].write_p) { ++ /* GeorgeKuo modify: reduce if branch */ ++ if (stp_core_ctx.ring[type].write_p > stp_core_ctx.ring[type].read_p) { ++ copyLen = stp_core_ctx.ring[type].write_p - stp_core_ctx.ring[type].read_p; ++ if (copyLen > length) ++ copyLen = length; ++ ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, copyLen); ++ stp_core_ctx.ring[type].read_p += copyLen; ++ } else { ++ tailLen = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].read_p; ++ if (tailLen > length) { /* exclude equal case to skip wrap check */ ++ copyLen = length; ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, ++ copyLen); ++ stp_core_ctx.ring[type].read_p += copyLen; ++ } else { ++ /* part 1: copy tailLen */ ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, ++ tailLen); ++ ++ buffer += tailLen; /* update buffer offset */ ++ ++ /* part 2: check if head length is enough */ ++ copyLen = length - tailLen; ++ copyLen = ++ (stp_core_ctx.ring[type].write_p < ++ copyLen) ? stp_core_ctx.ring[type].write_p : copyLen; ++ ++ if (copyLen) ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + 0, copyLen); ++ ++ /* Update read_p final position */ ++ stp_core_ctx.ring[type].read_p = copyLen; ++ ++ /* update return length: head + tail */ ++ copyLen += tailLen; ++ } ++ } ++ break; ++ } ++ ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ if ((MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) && (type != WMT_TASK_INDX)) { ++#if PSM_USE_COUNT_PACKAGE ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1); ++#else ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1, copyLen); ++#endif ++ } ++ ++ return copyLen; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_receive_data); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_rxqueue_empty ++* DESCRIPTION ++* Is certain rx queue empty? ++* PARAMETERS ++* type [IN] subfunction type ++* RETURNS ++* INT32 0: queue is NOT empyt; !0: queue is empty ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_is_rxqueue_empty(UINT8 type) ++#else ++INT32 mtk_wcn_stp_is_rxqueue_empty(UINT8 type) ++#endif ++{ ++ INT32 ret; ++ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ if (stp_core_ctx.ring[type].read_p == stp_core_ctx.ring[type].write_p) ++ ret = 1; /* queue is empty */ ++ else ++ ret = 0; /* queue is not empty */ ++ ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_set_sdio_mode ++* DESCRIPTION ++* Set stp for SDIO mode ++* PARAMETERS ++* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) ++* RETURNS ++* void ++*****************************************************************************/ ++ ++void mtk_wcn_stp_set_mode(UINT32 mode) ++{ ++ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, mode); ++ ++ STP_DBG_FUNC("STP_SUPPORT_PROTOCOL = %08x\n", STP_SUPPORT_PROTOCOL(stp_core_ctx)); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_fullset_mode ++* DESCRIPTION ++* Is stp use UART fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:Uart Fullset mode, FALSE:Not UART Fullset mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void) ++{ ++ /* ++ bit 0: uart fullset mode ++ bit 1: uart mandatory mode ++ bit 2: sdio mode ++ */ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_FULL_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_mand_mode ++* DESCRIPTION ++* Is stp use UART mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:Uart Mandatory mode, FALSE:Not UART Mandotary mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void) ++{ ++ /* ++ bit 0: uart fullset mode ++ bit 1: uart mandatory mode ++ bit 2: sdio mode ++ */ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_MAND_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_fullset_mode ++* DESCRIPTION ++* Is stp use BTIF fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Fullset mode, FALSE:Not BTIF Fullset mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void) ++{ ++ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_FULL_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_mand_mode ++* DESCRIPTION ++* Is stp use BTIF mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Mandatory mode, FALSE:Not BTIF Mandotary mode ++*****************************************************************************/ ++ ++MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void) ++{ ++ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_MAND_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_sdio_mode ++* DESCRIPTION ++* Is stp use SDIO mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void) ++{ ++ /* ++ bit 0: uart fullset mode ++ bit 1: uart mandatory mode ++ bit 2: sdio mode ++ */ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_SDIO_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To sync to oringnal stp state with f/w stp ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++void mtk_wcn_stp_inband_reset(void) ++{ ++ UINT8 inband_reset_packet[64]; ++ UINT32 txseq = 0; ++ UINT32 txack = 0; ++ UINT32 crc = 0; ++ UINT32 ret = 0; ++ UINT32 reset_payload_len = 0; ++ ++ /*512 bytes */ ++ UINT8 reset_payload[] = { ++ 0xc0, 0x01, 0xc0, 0xde, 0x3e, 0xd1, 0xa7, 0xef ++ }; ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ /*RESYNC*/ inband_reset_packet[0] = 0x7f; ++ inband_reset_packet[1] = 0x7f; ++ inband_reset_packet[2] = 0x7f; ++ inband_reset_packet[3] = 0x7f; ++ inband_reset_packet[4] = 0x7f; ++ inband_reset_packet[5] = 0x7f; ++ inband_reset_packet[6] = 0x7f; ++ inband_reset_packet[7] = 0x7f; ++ ++ /*header */ ++ reset_payload_len = sizeof(reset_payload) / sizeof(reset_payload[0]); ++ inband_reset_packet[8] = 0x80 + (txseq << 3) + txack; ++ inband_reset_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); ++ inband_reset_packet[10] = reset_payload_len & 0xff; ++ inband_reset_packet[11] = (inband_reset_packet[8] + inband_reset_packet[9] + inband_reset_packet[10]) & 0xff; ++ ++ /*payload */ ++ osal_memcpy(&inband_reset_packet[12], reset_payload, reset_payload_len); ++ ++ /*crc */ ++ crc = osal_crc16(&reset_payload[0], reset_payload_len); ++ inband_reset_packet[12 + reset_payload_len] = crc & 0xff; ++ inband_reset_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; ++ ++ (*sys_if_tx) (&inband_reset_packet[0], 14 + reset_payload_len, &ret); ++ ++ if (ret != (14 + reset_payload_len)) ++ STP_ERR_FUNC("Inband sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ret); ++ ++ stp_core_ctx.inband_rst_set = 1; ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++} ++ ++void mtk_wcn_stp_debug_ctrl(INT32 op, INT32 filter, INT32 filter_param) ++{ ++ /*nothing at now*/ ++} ++ ++void mtk_wcn_stp_test_cmd(INT32 cmd_no) ++{ ++ UINT8 test_packet[64]; ++ UINT32 txseq = 0; ++ UINT32 txack = 0; ++ UINT32 crc = 0; ++ UINT32 ret = 0; ++ UINT32 reset_payload_len = 0; ++ ++ UINT8 test_payload[] = { ++ 0xAA, 0xAA, 0xC0, 0xDE, 0x3E, 0xD1, 0xA7, 0xEF ++ }; ++/* */ ++/* select your test command by cmd_no */ ++/* */ ++ if (cmd_no == 0) { ++ /* to test new command to chip */ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ /*RESYNC*/ test_packet[0] = 0x7f; ++ test_packet[1] = 0x7f; ++ test_packet[2] = 0x7f; ++ test_packet[3] = 0x7f; ++ test_packet[4] = 0x7f; ++ test_packet[5] = 0x7f; ++ test_packet[6] = 0x7f; ++ test_packet[7] = 0x7f; ++ ++ /*header */ ++ reset_payload_len = sizeof(test_payload) / sizeof(test_payload[0]); ++ test_packet[8] = 0x80 + (txseq << 3) + txack; ++ test_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); ++ test_packet[10] = reset_payload_len & 0xff; ++ test_packet[11] = (test_packet[8] + test_packet[9] + test_packet[10]) & 0xff; ++ ++ /*payload */ ++ osal_memcpy(&test_packet[12], test_payload, reset_payload_len); ++ ++ /*crc */ ++ crc = osal_crc16(&test_payload[0], reset_payload_len); ++ test_packet[12 + reset_payload_len] = crc & 0xff; ++ test_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; ++ ++ (*sys_if_tx) (&test_packet[0], 14 + reset_payload_len, &ret); ++ if (ret != (14 + reset_payload_len)) { ++ STP_ERR_FUNC("stp test sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ++ ret); ++ } ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_flush_context ++* DESCRIPTION ++* Flush STP Context ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++void mtk_wcn_stp_flush_context(void) ++{ ++ stp_rest_ctx_state(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_flush_rx_queue ++* DESCRIPTION ++* Flush STP Rx Queue ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++ ++void mtk_wcn_stp_flush_rx_queue(UINT32 type) ++{ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ if (type < MTKSTP_MAX_TASK_NUM) { ++ stp_core_ctx.ring[type].read_p = 0; ++ stp_core_ctx.ring[type].write_p = 0; ++ } ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_enable ++* DESCRIPTION ++* STP is ready? ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void) ++#else ++MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) ++#endif ++{ ++ return STP_IS_READY(stp_core_ctx); ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_is_ready); ++#endif ++/***************************************************************************** ++* FUNCTION ++* set_bluetooth_rx_interface ++* DESCRIPTION ++* Set bluetooth rx interface ++* PARAMETERS ++* rx interface type ++* RETURNS ++* void ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) ++#else ++void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) ++#endif ++{ ++ /* g_mtkstp_bluez_flag = bluez_flag; */ ++ STP_SET_BT_STK(stp_core_ctx, bluez_flag); ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); ++#endif ++/***************************************************************************** ++* FUNCTION ++* set stp debugging mdoe ++* DESCRIPTION ++* set stp debugging mdoe ++* PARAMETERS ++* dbg_mode: switch to dbg mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode) ++{ ++ STP_SET_ENABLE_DBG(stp_core_ctx, dbg_mode); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* set stp auto reset mdoe ++* DESCRIPTION ++* set stp auto reset mdoe ++* PARAMETERS ++* auto_rst: switch to auto reset mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst) ++{ ++ STP_SET_ENABLE_RST(stp_core_ctx, auto_rst); ++} ++ ++INT32 mtk_wcn_stp_notify_sleep_for_thermal(void) ++{ ++ return stp_psm_sleep_for_thermal(STP_PSM_CORE(stp_core_ctx)); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_open_btif ++* DESCRIPTION ++* init btif hw & sw by owner stp ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_open_btif(VOID) ++{ ++ return mtk_wcn_consys_stp_btif_open(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_open_close ++* DESCRIPTION ++* close btif hw & sw by owner stp ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_close_btif(VOID) ++{ ++ return mtk_wcn_consys_stp_btif_close(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_rx_cb_register ++* DESCRIPTION ++* register stp rx cb to btif ++* PARAMETERS ++* MTK_WCN_BTIF_RX_CB stp rx handle function ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ return mtk_wcn_consys_stp_btif_rx_cb_register(rx_cb); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_tx ++* DESCRIPTION ++* send stp package by btif ++* PARAMETERS ++* pBuf:package buffer pointer,len:package length ++* written_len:package written length ++* RETURNS ++* INT32 package length-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len) ++{ ++ INT32 iRet = -1; ++ ++ iRet = mtk_wcn_consys_stp_btif_tx(pBuf, len, written_len); ++ return iRet; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_wakeup_consys ++* DESCRIPTION ++* STP wakeup consys by btif ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_wakeup_consys(VOID) ++{ ++ /*log wakeup int for debug */ ++ stp_dbg_pkt_log(7, 0, 0, 0, PKT_DIR_TX, NULL, 0); ++ return mtk_wcn_consys_stp_btif_wakeup(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_dpidle_ctrl ++* DESCRIPTION ++* decide AP enter or exit deep idle ++* PARAMETERS ++* en_flag:1,enter,0,exit ++* RETURNS ++* always 0 ++*****************************************************************************/ ++INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ mtk_wcn_consys_stp_btif_dpidle_ctrl(en_flag); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_lpbk_ctrl ++* DESCRIPTION ++* enable stp internal lpbk test or not ++* PARAMETERS ++* mode:1,enable,0,disabel ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) ++{ ++ return mtk_wcn_consys_stp_btif_lpbk_ctrl(mode); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_logger_ctrl ++* DESCRIPTION ++* dump btif buffer or register status when No ACK or assert occurs ++* PARAMETERS ++* flag:see enum value in ENUM_BTIF_DBG_ID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag) ++{ ++ return mtk_wcn_consys_stp_btif_logger_ctrl(flag); ++} ++ ++VOID mtk_wcn_stp_ctx_save(void) ++{ ++ STP_INFO_FUNC("start ++\n"); ++ mtk_wcn_stp_coredump_start_ctrl(1); ++ stp_psm_set_sleep_disable(stp_core_ctx.psm); ++ STP_INFO_FUNC("exit --\n"); ++} ++ ++VOID mtk_wcn_stp_ctx_restore(void) ++{ ++ STP_INFO_FUNC("start ++\n"); ++ stp_psm_set_sleep_enable(stp_core_ctx.psm); ++ stp_btm_reset_btm_wq(STP_BTM_CORE(stp_core_ctx)); ++ ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ else ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++#if STP_RETRY_OPTIMIZE ++ g_retry_times = 0; ++#endif ++ STP_INFO_FUNC("exit --\n"); ++} ++ ++INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(void) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_coredump_start_get() != 0) { ++ STP_INFO_FUNC("firmware assert has been triggered\n"); ++ return 0; ++ } ++ ++ ret = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); ++ if (ret) { ++ STP_ERR_FUNC("evt err trigger assert fail,do chip reset to recovery\n"); ++ ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ else ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ ++ return ret; ++} ++ ++VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value) ++{ ++ STP_INFO_FUNC("set evt err tigger assert flag to %d\n", value); ++ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, value); ++} ++ ++UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(void) ++{ ++ return STP_EVT_ERR_ASSERT(stp_core_ctx); ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c +new file mode 100644 +index 000000000000..3009bd26df41 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c +@@ -0,0 +1,529 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CONF]" ++ ++#include "osal_typedef.h" ++/* #include "osal.h" */ ++#include "wmt_lib.h" ++#include "wmt_dev.h" ++#include "wmt_conf.h" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++struct parse_data { ++ PINT8 name; ++ INT32 (*parser)(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 value); ++ PINT8 (*writer)(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ /*PINT8 param1, *param2, *param3; */ ++ /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */ ++ PINT8 param1; ++ PINT8 param2; ++ PINT8 param3; ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); ++ ++static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ ++static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); ++ ++static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ ++static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); ++ ++static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ ++static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal); ++ ++static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size); ++ ++#define OFFSET(v) ((void *) &((P_DEV_WMT) 0)->v) ++ ++#define CHAR(f) \ ++{ \ ++ #f, \ ++ wmt_conf_parse_char, \ ++ wmt_conf_write_char, \ ++ OFFSET(rWmtGenConf.f), \ ++ NULL, \ ++ NULL \ ++} ++/* #define CHAR(f) _CHAR(f), NULL, NULL} */ ++ ++#define SHORT(f) \ ++{ \ ++ #f, \ ++ wmt_conf_parse_short, \ ++ wmt_conf_write_short, \ ++ OFFSET(rWmtGenConf.f), \ ++ NULL, \ ++ NULL \ ++} ++/* #define SHORT(f) _SHORT(f), NULL, NULL */ ++ ++#define INT(f) \ ++{ \ ++ #f, \ ++ wmt_conf_parse_int, \ ++ wmt_conf_write_int, \ ++ OFFSET(rWmtGenConf.f), \ ++ NULL, \ ++ NULL \ ++} ++/* #define INT(f) _INT(f), NULL, NULL */ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static const struct parse_data wmtcfg_fields[] = { ++ CHAR(coex_wmt_ant_mode), ++ CHAR(coex_wmt_ext_component), ++ CHAR(coex_wmt_wifi_time_ctl), ++ CHAR(coex_wmt_ext_pta_dev_on), ++ CHAR(coex_wmt_filter_mode), ++ ++ CHAR(coex_bt_rssi_upper_limit), ++ CHAR(coex_bt_rssi_mid_limit), ++ CHAR(coex_bt_rssi_lower_limit), ++ CHAR(coex_bt_pwr_high), ++ CHAR(coex_bt_pwr_mid), ++ CHAR(coex_bt_pwr_low), ++ ++ CHAR(coex_wifi_rssi_upper_limit), ++ CHAR(coex_wifi_rssi_mid_limit), ++ CHAR(coex_wifi_rssi_lower_limit), ++ CHAR(coex_wifi_pwr_high), ++ CHAR(coex_wifi_pwr_mid), ++ CHAR(coex_wifi_pwr_low), ++ ++ CHAR(coex_ext_pta_hi_tx_tag), ++ CHAR(coex_ext_pta_hi_rx_tag), ++ CHAR(coex_ext_pta_lo_tx_tag), ++ CHAR(coex_ext_pta_lo_rx_tag), ++ SHORT(coex_ext_pta_sample_t1), ++ SHORT(coex_ext_pta_sample_t2), ++ CHAR(coex_ext_pta_wifi_bt_con_trx), ++ ++ INT(coex_misc_ext_pta_on), ++ INT(coex_misc_ext_feature_set), ++ ++ CHAR(wmt_gps_lna_pin), ++ CHAR(wmt_gps_lna_enable), ++ ++ CHAR(pwr_on_rtc_slot), ++ CHAR(pwr_on_ldo_slot), ++ CHAR(pwr_on_rst_slot), ++ CHAR(pwr_on_off_slot), ++ CHAR(pwr_on_on_slot), ++ CHAR(co_clock_flag), ++ ++ INT(sdio_driving_cfg), ++ ++}; ++ ++#define NUM_WMTCFG_FIELDS (osal_sizeof(wmtcfg_fields) / osal_sizeof(wmtcfg_fields[0])) ++ ++static int wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) ++{ ++ PINT8 dst; ++ long res; ++ int ret; ++ ++ dst = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { ++ ret = osal_strtol(pos + 2, 16, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); ++ } else { ++ ret = osal_strtol(pos, 10, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); ++ } ++ return 0; ++} ++ ++static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data) ++{ ++ PINT8 src; ++ INT32 res; ++ PINT8 value; ++ ++ src = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ value = osal_malloc(20); ++ if (value == NULL) ++ return NULL; ++ res = osal_snprintf(value, 20, "0x%x", *src); ++ if (res < 0 || res >= 20) { ++ osal_free(value); ++ return NULL; ++ } ++ value[20 - 1] = '\0'; ++ return value; ++} ++ ++static int wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) ++{ ++ PUINT16 dst; ++ long res; ++ int ret; ++ ++ dst = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ ++ ++ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { ++ ret = osal_strtol(pos + 2, 16, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); ++ } else { ++ ret = osal_strtol(pos, 10, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); ++ } ++ ++ return 0; ++} ++ ++static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data) ++{ ++ PINT16 src; ++ INT32 res; ++ PINT8 value; ++ ++ /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */ ++ src = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ value = osal_malloc(20); ++ if (value == NULL) ++ return NULL; ++ res = osal_snprintf(value, 20, "0x%x", *src); ++ if (res < 0 || res >= 20) { ++ osal_free(value); ++ return NULL; ++ } ++ value[20 - 1] = '\0'; ++ return value; ++} ++ ++static int wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) ++{ ++ PUINT32 dst; ++ long res; ++ int ret; ++ ++ dst = (PINT32) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ ++ ++ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { ++ ret = osal_strtol(pos + 2, 16, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); ++ } else { ++ ret = osal_strtol(pos, 10, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); ++ } ++ ++ return 0; ++} ++ ++static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data) ++{ ++ PINT32 src; ++ INT32 res; ++ PINT8 value; ++ ++ src = (PUINT32) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ value = osal_malloc(20); ++ if (value == NULL) ++ return NULL; ++ res = osal_snprintf(value, 20, "0x%x", *src); ++ if (res < 0 || res >= 20) { ++ osal_free(value); ++ return NULL; ++ } ++ value[20 - 1] = '\0'; ++ return value; ++} ++ ++static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal) ++{ ++ int i = 0; ++ int ret = 0; ++ ++ /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */ ++ ++ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { ++ const struct parse_data *field = &wmtcfg_fields[i]; ++ ++ if (osal_strcmp(pKey, field->name) != 0) ++ continue; ++ if (field->parser(pWmtDev, field, pVal)) { ++ WMT_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal); ++ ret = -1; ++ } ++ break; ++ } ++ if (i == NUM_WMTCFG_FIELDS) { ++ WMT_ERR_FUNC("unknown field '%s'.\n", pKey); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size) ++{ ++ PINT8 pch; ++ PINT8 pBuf; ++ PINT8 pLine; ++ PINT8 pKey; ++ PINT8 pVal; ++ PINT8 pPos; ++ INT32 ret = 0; ++ INT32 i = 0; ++ PINT8 pa = NULL; ++ ++ pBuf = osal_malloc(size); ++ if (!pBuf) ++ return -1; ++ ++ osal_memcpy(pBuf, pInBuf, size); ++ pBuf[size] = '\0'; ++ ++ pch = pBuf; ++ /* pch is to be updated by strsep(). Keep pBuf unchanged!! */ ++ ++#if 0 ++ { ++ PINT8 buf_ptr = pBuf; ++ INT32 k = 0; ++ ++ WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size); ++ for (k = 0; k < size; k++) { ++ /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */ ++ WMT_INFO_FUNC("%c", buf_ptr[k]); ++ } ++ WMT_INFO_FUNC("--end\n"); ++ } ++#endif ++ ++ while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) { ++ /* pch is updated to the end of pLine by strsep() and updated to '\0' */ ++ /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */ ++ /* parse each line */ ++ ++ /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */ ++ ++ if (!*pLine) ++ continue; ++ ++ pVal = osal_strchr(pLine, '='); ++ if (!pVal) { ++ WMT_WARN_FUNC("mal-format cfg string(%s)\n", pLine); ++ continue; ++ } ++ ++ /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */ ++ *pVal = '\0'; /* replace '=' with '\0' to get key */ ++ /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */ ++ pKey = pLine; ++ ++ if ((pVal - pBuf) < size) ++ pVal++; ++ ++ /*key handling */ ++ pPos = pKey; ++ /*skip space characeter */ ++ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*key head */ ++ pKey = pPos; ++ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*key tail */ ++ (*pPos) = '\0'; ++ ++ /*value handling */ ++ pPos = pVal; ++ /*skip space characeter */ ++ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*value head */ ++ pVal = pPos; ++ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*value tail */ ++ (*pPos) = '\0'; ++ ++ /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */ ++ ret = wmt_conf_parse_pair(pWmtDev, pKey, pVal); ++ WMT_DBG_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret); ++ if (ret) ++ WMT_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret); ++ } ++ ++ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { ++ const struct parse_data *field = &wmtcfg_fields[i]; ++ ++ pa = field->writer(pWmtDev, field); ++ if (pa) { ++ WMT_DBG_FUNC("#%d(%s)=>%s\n", i, field->name, pa); ++ osal_free(pa); ++ } else { ++ WMT_ERR_FUNC("failed to parse '%s'.\n", field->name); ++ } ++ } ++ osal_free(pBuf); ++ return 0; ++} ++ ++INT32 wmt_conf_set_cfg_file(const char *name) ++{ ++ if (NULL == name) { ++ WMT_ERR_FUNC("name is NULL\n"); ++ return -1; ++ } ++ if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) { ++ WMT_ERR_FUNC("name is too long, length=%d, expect to < %d\n", osal_strlen(name), ++ osal_sizeof(gDevWmt.cWmtcfgName)); ++ return -2; ++ } ++ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); ++ osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name); ++ WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0])); ++ ++ return 0; ++} ++ ++INT32 wmt_conf_read_file(VOID) ++{ ++ INT32 ret = -1; ++ ++ osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf)); ++ osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg)); ++ ++#if 1 ++ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); ++ ++ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_PREFIX, osal_sizeof(CUST_CFG_WMT_PREFIX)); ++ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT, osal_sizeof(CUST_CFG_WMT)); ++#endif ++ ++ if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) { ++ WMT_ERR_FUNC("empty Wmtcfg name\n"); ++ osal_assert(0); ++ return ret; ++ } ++ WMT_DBG_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0])); ++ if (0 == wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg, 0)) { ++ /*get full name patch success */ ++ WMT_DBG_FUNC("get full file name(%s) buf(0x%p) size(%d)\n", ++ &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size); ++ ++ if (0 == wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size)) { ++ /*config file exists */ ++ gDevWmt.rWmtGenConf.cfgExist = 1; ++ ++ WMT_DBG_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf); ++ ret = 0; ++ } else { ++ WMT_ERR_FUNC("wmt conf parsing fail\n"); ++ osal_assert(0); ++ ret = -1; ++ } ++ wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg); ++/* ++ if (gDevWmt.pWmtCfg) ++ { ++ if (gDevWmt.pWmtCfg->data) ++ { ++ osal_free(gDevWmt.pWmtCfg->data); ++ } ++ osal_free(gDevWmt.pWmtCfg); ++ gDevWmt.pWmtCfg = 0; ++ } ++*/ ++ return ret; ++ } ++ WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0])); ++ osal_assert(0); ++ ++ gDevWmt.rWmtGenConf.cfgExist = 0; ++ return ret; ++} ++ ++P_WMT_GEN_CONF wmt_conf_get_cfg(VOID) ++{ ++ if (0 == gDevWmt.rWmtGenConf.cfgExist) ++ return NULL; ++ ++ return &gDevWmt.rWmtGenConf; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c +new file mode 100644 +index 000000000000..cca6729d53a0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c +@@ -0,0 +1,2521 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CORE]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include "wmt_lib.h" ++#include "wmt_core.h" ++#include "wmt_ctrl.h" ++#include "wmt_ic.h" ++#include "wmt_conf.h" ++ ++#include "wmt_func.h" ++#include "stp_core.h" ++#include "psm_core.h" ++ ++ ++P_WMT_FUNC_OPS gpWmtFuncOps[4] = { ++#if CFG_FUNC_BT_SUPPORT ++ [0] = &wmt_func_bt_ops, ++#else ++ [0] = NULL, ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++ [1] = &wmt_func_fm_ops, ++#else ++ [1] = NULL, ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++ [2] = &wmt_func_gps_ops, ++#else ++ [2] = NULL, ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++ [3] = &wmt_func_wifi_ops, ++#else ++ [3] = NULL, ++#endif ++ ++}; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting? ++*move to wmt_ic_6620 temporarily. ++*/ ++/* BT Port 2 Feature. */ ++/* #define CFG_WMT_BT_PORT2 (1) */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++static WMT_CTX gMtkWmtCtx; ++static UINT8 gLpbkBuf[1024+5] = { 0 }; ++#ifdef CONFIG_MTK_COMBO_ANT ++static UINT8 gAntBuf[1024] = { 0 }; ++#define CFG_CHECK_WMT_RESULT (1) ++#endif ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp); ++static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp); ++static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp); ++static INT32 opfunc_func_on(P_WMT_OP pWmtOp); ++static INT32 opfunc_func_off(P_WMT_OP pWmtOp); ++static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp); ++static INT32 opfunc_exit(P_WMT_OP pWmtOp); ++static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp); ++static INT32 opfunc_dsns(P_WMT_OP pWmtOp); ++static INT32 opfunc_lpbk(P_WMT_OP pWmtOp); ++static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp); ++static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp); ++static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp); ++static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp); ++static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); ++static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp); ++static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); ++static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp); ++static INT32 opfunc_pin_state(P_WMT_OP pWmtOp); ++static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp); ++static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp); ++static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp); ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp); ++#endif ++#ifdef CONFIG_MTK_COMBO_ANT ++static INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp); ++static INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp); ++#endif ++static VOID wmt_core_dump_func_state(PINT8 pSource); ++static INT32 wmt_core_stp_init(VOID); ++static INT32 wmt_core_stp_deinit(VOID); ++static INT32 wmt_core_hw_check(VOID); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static const UINT8 WMT_SLEEP_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x01 }; ++static const UINT8 WMT_SLEEP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; ++ ++static const UINT8 WMT_HOST_AWAKE_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x02 }; ++static const UINT8 WMT_HOST_AWAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; ++ ++static const UINT8 WMT_WAKEUP_CMD[] = { 0xFF }; ++static const UINT8 WMT_WAKEUP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; ++ ++static UINT8 WMT_THERM_CMD[] = { 0x01, 0x11, 0x01, 0x00, ++ 0x00 /*thermal sensor operation */ ++}; ++static UINT8 WMT_THERM_CTRL_EVT[] = { 0x02, 0x11, 0x01, 0x00, 0x00 }; ++static UINT8 WMT_THERM_READ_EVT[] = { 0x02, 0x11, 0x02, 0x00, 0x00, 0x00 }; ++ ++static UINT8 WMT_EFUSE_CMD[] = { 0x01, 0x0D, 0x08, 0x00, ++ 0x01, /*[4]operation, 0:init, 1:write 2:read */ ++ 0x01, /*[5]Number of register setting */ ++ 0xAA, 0xAA, /*[6-7]Address */ ++ 0xBB, 0xBB, 0xBB, 0xBB /*[8-11] Value */ ++}; ++ ++static UINT8 WMT_EFUSE_EVT[] = { 0x02, 0x0D, 0x08, 0x00, ++ 0xAA, /*[4]operation, 0:init, 1:write 2:read */ ++ 0xBB, /*[5]Number of register setting */ ++ 0xCC, 0xCC, /*[6-7]Address */ ++ 0xDD, 0xDD, 0xDD, 0xDD /*[8-11] Value */ ++}; ++ ++static UINT8 WMT_DSNS_CMD[] = { 0x01, 0x0E, 0x02, 0x00, 0x01, ++ 0x00 /*desnse type */ ++}; ++static UINT8 WMT_DSNS_EVT[] = { 0x02, 0x0E, 0x01, 0x00, 0x00 }; ++ ++/* TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT */ ++static UINT8 WMT_SET_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x00 /*op: w(1) & r(2) */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*res */ ++ , 0x01 /*1 register */ ++ , 0x00, 0x00, 0x00, 0x00 /* addr */ ++ , 0x00, 0x00, 0x00, 0x00 /* value */ ++ , 0xFF, 0xFF, 0xFF, 0xFF /*mask */ ++}; ++ ++static UINT8 WMT_SET_REG_WR_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 register */ ++ /* , 0x00, 0x00, 0x00, 0x00 */ /* addr */ ++ /* , 0x00, 0x00, 0x00, 0x00 */ /* value */ ++}; ++ ++static UINT8 WMT_SET_REG_RD_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 register */ ++ , 0x00, 0x00, 0x00, 0x00 /* addr */ ++ , 0x00, 0x00, 0x00, 0x00 /* value */ ++}; ++ ++#ifdef CONFIG_MTK_COMBO_ANT ++static UINT8 WMT_ANT_RAM_STA_GET_CMD[] = { 0x01, 0x06, 0x02, 0x00, 0x05, 0x02 ++}; ++ ++static UINT8 WMT_ANT_RAM_STA_GET_EVT[] = { 0x02, 0x06, 0x03, 0x00 /*length */ ++ , 0x05, 0x02, 0x00 /*S: result */ ++}; ++ ++static UINT8 WMT_ANT_RAM_DWN_CMD[] = { 0x01, 0x15, 0x00, 0x00, 0x01 ++}; ++ ++static UINT8 WMT_ANT_RAM_DWN_EVT[] = { 0x02, 0x15, 0x01, 0x00 /*length */ ++ , 0x00 ++}; ++#endif ++ ++/* GeorgeKuo: Use designated initializers described in ++ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html ++ */ ++ ++static const WMT_OPID_FUNC wmt_core_opfunc[] = { ++ [WMT_OPID_HIF_CONF] = opfunc_hif_conf, ++ [WMT_OPID_PWR_ON] = opfunc_pwr_on, ++ [WMT_OPID_PWR_OFF] = opfunc_pwr_off, ++ [WMT_OPID_FUNC_ON] = opfunc_func_on, ++ [WMT_OPID_FUNC_OFF] = opfunc_func_off, ++ [WMT_OPID_REG_RW] = opfunc_reg_rw, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ ++ [WMT_OPID_EXIT] = opfunc_exit, ++ [WMT_OPID_PWR_SV] = opfunc_pwr_sv, ++ [WMT_OPID_DSNS] = opfunc_dsns, ++ [WMT_OPID_LPBK] = opfunc_lpbk, ++ [WMT_OPID_CMD_TEST] = opfunc_cmd_test, ++ [WMT_OPID_HW_RST] = opfunc_hw_rst, ++ [WMT_OPID_SW_RST] = opfunc_sw_rst, ++ [WMT_OPID_STP_RST] = opfunc_stp_rst, ++ [WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl, ++ [WMT_OPID_EFUSE_RW] = opfunc_efuse_rw, ++ [WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl, ++ [WMT_OPID_GPIO_STATE] = opfunc_pin_state, ++ [WMT_OPID_BGW_DS] = opfunc_bgw_ds, ++ [WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk, ++ [WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test, ++#if CFG_WMT_LTE_COEX_HANDLING ++ [WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling, ++#endif ++#ifdef CONFIG_MTK_COMBO_ANT ++ [WMT_OPID_ANT_RAM_DOWN] = opfunc_ant_ram_down, ++ [WMT_OPID_ANT_RAM_STA_GET] = opfunc_ant_ram_stat_get, ++#endif ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_core_init(VOID) ++{ ++ INT32 i = 0; ++ ++ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); ++ /* gMtkWmtCtx.p_ops is cleared to NULL */ ++ ++ /* default FUNC_OFF state */ ++ for (i = 0; i < WMTDRV_TYPE_MAX; ++i) { ++ /* WinMo is default to DRV_STS_UNREG; */ ++ gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF; ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_core_deinit(VOID) ++{ ++ /* return to init state */ ++ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); ++ /* gMtkWmtCtx.p_ops is cleared to NULL */ ++ return 0; ++} ++ ++/* TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not...... */ ++/* parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer. */ ++INT32 wmt_core_tx(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) ++{ ++ INT32 iRet; ++#if 0 /* Test using direct function call instead of wmt_ctrl() interface */ ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_TX; ++ ctrlData.au4CtrlData[0] = (UINT32) pData; ++ ctrlData.au4CtrlData[1] = size; ++ ctrlData.au4CtrlData[2] = (UINT32) writtenSize; ++ ctrlData.au4CtrlData[3] = bRawFlag; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_TX, iRet:%d\n", iRet); ++ /* (*sys_dbg_assert)(0, __FILE__, __LINE__); */ ++ osal_assert(0); ++ } ++#endif ++ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); ++ if (0 == *writtenSize) { ++ INT32 retry_times = 0; ++ INT32 max_retry_times = 3; ++ INT32 retry_delay_ms = 360; ++ ++ WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n", ++ *writtenSize); ++ while ((0 == *writtenSize) && (retry_times < max_retry_times)) { ++ WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms); ++ osal_sleep_ms(retry_delay_ms); ++ ++ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); ++ retry_times++; ++ } ++ } ++ return iRet; ++} ++ ++INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize) ++{ ++ INT32 iRet; ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_RX; ++ ctrlData.au4CtrlData[0] = (SIZE_T) pBuf; ++ ctrlData.au4CtrlData[1] = bufLen; ++ ctrlData.au4CtrlData[2] = (SIZE_T) readSize; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet); ++ mtk_wcn_stp_dbg_dump_package(); ++ osal_assert(0); ++ } ++ return iRet; ++} ++ ++INT32 wmt_core_rx_flush(UINT32 type) ++{ ++ INT32 iRet; ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_RX_FLUSH; ++ ctrlData.au4CtrlData[0] = (UINT32) type; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet); ++ osal_assert(0); ++ } ++ return iRet; ++} ++ ++INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn) ++{ ++ INT32 iRet = 0; ++ UINT32 u4WmtCmdPduLen; ++ UINT32 u4WmtEventPduLen; ++ UINT32 u4ReadSize; ++ UINT32 u4WrittenSize; ++ WMT_PKT rWmtPktCmd; ++ WMT_PKT rWmtPktEvent; ++ MTK_WCN_BOOL fgFail; ++ ++ /* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ ++ /* Using this struct relies on compiler's implementation and pack() settings */ ++ osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd)); ++ osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent)); ++ ++ rWmtPktCmd.eType = (UINT8) PKT_TYPE_CMD; ++ rWmtPktCmd.eOpCode = (UINT8) OPCODE_FUNC_CTRL; ++ ++ /* Flag field: driver type */ ++ rWmtPktCmd.aucParam[0] = (UINT8) type; ++ /* Parameter field: ON/OFF */ ++ rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0; ++ rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN; /* (2) */ ++ ++ /* WMT Header + WMT SDU */ ++ u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen; /* (6) */ ++ u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN; /* (5) */ ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++/* iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize); */ ++ iRet = wmt_core_tx((PUINT8) &rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, MTK_WCN_BOOL_FALSE); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed\n"); ++ break; ++ } ++ ++ iRet = wmt_core_rx((PUINT8) &rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_rx failed\n"); ++ break; ++ } ++ ++ /* Error Checking */ ++ if (PKT_TYPE_EVENT != rWmtPktEvent.eType) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n", ++ rWmtPktEvent.eType); ++ break; ++ } ++ ++ if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) { ++ WMT_ERR_FUNC ++ ("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n", ++ rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode); ++ break; ++ } ++ ++ if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) { ++ WMT_ERR_FUNC ++ ("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n", ++ u4WmtEventPduLen, rWmtPktEvent.u2SduLen); ++ break; ++ } ++ /* Status field of event check */ ++ if (0 != rWmtPktEvent.aucParam[0]) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", rWmtPktEvent.aucParam[0]); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ } while (0); ++ ++ if (MTK_WCN_BOOL_FALSE == fgFail) { ++ /* WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n"); */ ++ return 0; ++ } ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]); ++ return -3; ++} ++ ++INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp) ++{ ++ UINT32 opId; ++ INT32 ret; ++ ++ opId = pWmtOp->opId; ++ ++ if (wmt_core_opfunc[opId]) { ++ ret = (*(wmt_core_opfunc[opId])) (pWmtOp); /*wmtCoreOpidHandlerPack[].opHandler */ ++ return ret; ++ } ++ WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId); ++ return -2; ++ ++} ++ ++INT32 wmt_core_opid(P_WMT_OP pWmtOp) ++{ ++ ++ /*sanity check */ ++ if (NULL == pWmtOp) { ++ WMT_ERR_FUNC("null pWmtOP\n"); ++ /*print some message with error info */ ++ return -1; ++ } ++ ++ if (WMT_OPID_MAX <= pWmtOp->opId) { ++ WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId); ++ return -2; ++ } ++ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ ++ return wmt_core_opid_handler(pWmtOp); ++} ++ ++INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2) ++{ ++ INT32 iRet = -1; ++ WMT_CTRL_DATA ctrlData; ++ SIZE_T val1 = (pPa1) ? *pPa1 : 0; ++ SIZE_T val2 = (pPa2) ? *pPa2 : 0; ++ ++ ctrlData.ctrlId = (SIZE_T) ctrId; ++ ctrlData.au4CtrlData[0] = val1; ++ ctrlData.au4CtrlData[1] = val2; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%d), value(%d) iRet:(%d)\n", ctrId, val1, ++ val2, iRet); ++ osal_assert(0); ++ } else { ++ if (pPa1) ++ *pPa1 = ctrlData.au4CtrlData[0]; ++ if (pPa2) ++ *pPa2 = ctrlData.au4CtrlData[1]; ++ } ++ return iRet; ++} ++ ++VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len) ++{ ++ PUINT8 ptr = pData; ++ INT32 k = 0; ++ ++ WMT_INFO_FUNC("%s len=%d\n", pTitle, len); ++ for (k = 0; k < len; k++) { ++ if (k % 16 == 0) ++ WMT_INFO_FUNC("\n"); ++ WMT_INFO_FUNC("0x%02x ", *ptr); ++ ptr++; ++ } ++ WMT_INFO_FUNC("--end\n"); ++} ++ ++/*! ++ * \brief An WMT-CORE function to support read, write, and read after write to ++ * an internal register. ++ * ++ * Detailed description. ++ * ++ * \param isWrite 1 for write, 0 for read ++ * \param offset of register to be written or read ++ * \param pVal a pointer to the 32-bit value to be writtern or read ++ * \param mask a 32-bit mask to be applied for the read or write operation ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid parameters ++ * \retval -2 tx cmd fail ++ * \retval -3 rx event fail ++ * \retval -4 read check error ++ */ ++INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask) ++{ ++ INT32 iRet; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2; /* w:1, r:2 */ ++ osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4); /* offset */ ++ osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4); /* [2] is var addr */ ++ osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4); /* mask */ ++ ++ /* send command */ ++ iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if ((iRet) || (u4Res != sizeof(WMT_SET_REG_CMD))) { ++ WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %d)\n", iRet, u4Res, sizeof(WMT_SET_REG_CMD)); ++ return -2; ++ } ++ ++ /* receive event */ ++ evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT); ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if ((iRet) || (u4Res != evtLen)) { ++ WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen); ++ return -3; ++ } ++ ++ if (!isWrite) { ++ UINT32 rxEvtAddr; ++ UINT32 txCmdAddr; ++ ++ osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4); ++ osal_memcpy(&rxEvtAddr, &evtBuf[8], 4); ++ ++ /* check read result */ ++ if (txCmdAddr != rxEvtAddr) { ++ WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, txCmdAddr); ++ return -4; ++ } ++ WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr); ++ ++ osal_memcpy(pVal, &evtBuf[12], 4); ++ } ++ ++ /* no error here just return 0 */ ++ return 0; ++} ++ ++INT32 wmt_core_init_script(struct init_script *script, INT32 count) ++{ ++ UINT8 evtBuf[256]; ++ UINT32 u4Res; ++ INT32 i = 0; ++ INT32 iRet; ++ ++ for (i = 0; i < count; i++) { ++ WMT_DBG_FUNC("WMT-CORE: init_script operation %s start\n", script[i].str); ++ /* CMD */ ++ /* iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res); */ ++ iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != script[i].cmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", script[i].str, iRet, u4Res, ++ script[i].cmdSz); ++ break; ++ } ++ /* EVENT BUF */ ++ osal_memset(evtBuf, 0, sizeof(evtBuf)); ++ iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res); ++ if (iRet || (u4Res != script[i].evtSz)) { ++ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", script[i].str, iRet, ++ u4Res, script[i].evtSz); ++ mtk_wcn_stp_dbg_dump_package(); ++ break; ++ } ++ /* RESULT */ ++ if (0x14 != evtBuf[1]) { /* workaround RF calibration data EVT,do not care this EVT */ ++ if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) { ++ WMT_ERR_FUNC("WMT-CORE:compare %s result error\n", script[i].str); ++ WMT_ERR_FUNC ++ ("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], script[i].evtSz, ++ script[i].evt[0], script[i].evt[1], script[i].evt[2], script[i].evt[3], ++ script[i].evt[4]); ++ mtk_wcn_stp_dbg_dump_package(); ++ break; ++ } ++ } ++ WMT_DBG_FUNC("init_script operation %s ok\n", script[i].str); ++ } ++ ++ return (i == count) ? 0 : -1; ++} ++ ++static INT32 wmt_core_stp_init(VOID) ++{ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ UINT8 co_clock_type; ++ P_WMT_CTX pctx = &gMtkWmtCtx; ++ P_WMT_GEN_CONF pWmtGenConf = NULL; ++ ++ wmt_conf_read_file(); ++ pWmtGenConf = wmt_conf_get_cfg(); ++ if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) { ++ WMT_ERR_FUNC("WMT-CORE: no hif info!\n"); ++ osal_assert(0); ++ return -1; ++ } ++ /* 4 <1> open stp */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); ++ return -2; ++ } ++ /* 4 <1.5> disable and un-ready stp */ ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WMT_STP_CONF_RDY; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ++ /* 4 <2> set mode and enable */ ++ if (WMT_HIF_BTIF == pctx->wmtHifConf.hifType) { ++ ctrlPa1 = WMT_STP_CONF_MODE; ++ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ } ++ ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 1; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); ++ return -3; ++ } ++ /* TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips??? */ ++ ++ iRet = wmt_core_hw_check(); ++ if (iRet) { ++ WMT_ERR_FUNC("hw_check fail:%d\n", iRet); ++ return -4; ++ } ++ /* mtkWmtCtx.p_ic_ops is identified and checked ok */ ++ if ((NULL != pctx->p_ic_ops->co_clock_ctrl) && (pWmtGenConf != NULL)) { ++ co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f); ++ (*(pctx->p_ic_ops->co_clock_ctrl)) (co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN); ++ } else { ++ WMT_WARN_FUNC("pctx->p_ic_ops->co_clock_ctrl(0x%x), pWmtGenConf(0x%x)\n", pctx->p_ic_ops->co_clock_ctrl, ++ pWmtGenConf); ++ } ++ osal_assert(NULL != pctx->p_ic_ops->sw_init); ++ if (NULL != pctx->p_ic_ops->sw_init) { ++ iRet = (*(pctx->p_ic_ops->sw_init)) (&pctx->wmtHifConf); ++ } else { ++ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); ++ return -5; ++ } ++ if (iRet) { ++ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet); ++ return -6; ++ } ++ /* 4 <10> set stp ready */ ++ ctrlPa1 = WMT_STP_CONF_RDY; ++ ctrlPa2 = 1; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ++ return iRet; ++} ++ ++static INT32 wmt_core_stp_deinit(VOID) ++{ ++ INT32 iRet; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ WMT_DBG_FUNC(" start\n"); ++ ++ if (NULL == gMtkWmtCtx.p_ic_ops) { ++ WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n"); ++ goto deinit_ic_ops_done; ++ } ++ if (NULL != gMtkWmtCtx.p_ic_ops->sw_deinit) { ++ iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit)) (&gMtkWmtCtx.wmtHifConf); ++ /* unbind WMT-IC */ ++ gMtkWmtCtx.p_ic_ops = NULL; ++ } else { ++ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); ++ } ++ ++deinit_ic_ops_done: ++ ++ /* 4 <1> un-ready, disable, and close stp. */ ++ ctrlPa1 = WMT_STP_CONF_RDY; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); ++ ++ if (iRet) ++ WMT_WARN_FUNC("end with fail:%d\n", iRet); ++ ++ return iRet; ++} ++ ++static VOID wmt_core_dump_func_state(PINT8 pSource) ++{ ++ WMT_WARN_FUNC("[%s]status(b:%d f:%d g:%d w:%d lpbk:%d coredump:%d wmt:%d stp:%d)\n", ++ (pSource == NULL ? (PINT8) "CORE" : pSource), ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] ++ ); ++ return; ++ ++} ++ ++MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer) ++{ ++ if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) { ++ /*major no. does not match */ ++ WMT_ERR_FUNC("WMT-CORE: chip version(0x%d) does not match patch version(0x%d)\n", u4HwVer, u4PatchVer); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++static INT32 wmt_core_hw_check(VOID) ++{ ++ UINT32 chipid; ++ P_WMT_IC_OPS p_ops; ++ INT32 iret; ++ ++ /* 1. get chip id */ ++ chipid = 0; ++ WMT_LOUD_FUNC("before read hwcode (chip id)\n"); ++ iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK); /* read 0x80000008 */ ++ if (iret) { ++ WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret); ++ return -2; ++ } ++ WMT_DBG_FUNC("get hwcode (chip id) (0x%x)\n", chipid); ++ ++ /* TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id */ ++ switch (chipid) { ++#if CFG_CORE_MT6620_SUPPORT ++ case 0x6620: ++ p_ops = &wmt_ic_ops_mt6620; ++ break; ++#endif ++#if CFG_CORE_MT6628_SUPPORT ++ case 0x6628: ++ p_ops = &wmt_ic_ops_mt6628; ++ break; ++#endif ++#if CFG_CORE_SOC_SUPPORT ++ case 0x6572: ++ case 0x6582: ++ case 0x6592: ++ case 0x8127: ++ case 0x6571: ++ case 0x6752: ++ case 0x0279: ++ case 0x0326: ++ case 0x0321: ++ case 0x0335: ++ case 0x0337: ++ case 0x8163: ++ case 0x6580: ++ p_ops = &wmt_ic_ops_soc; ++ break; ++#endif ++ default: ++ p_ops = (P_WMT_IC_OPS) NULL; ++#if CFG_CORE_SOC_SUPPORT ++ if (0x7f90 == chipid - 0x600) { ++ p_ops = &wmt_ic_ops_soc; ++ chipid -= 0xf6d; ++ } ++#endif ++ break; ++ } ++ ++ if (NULL == p_ops) { ++ WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid); ++ return -3; ++ } else if (MTK_WCN_BOOL_FALSE == wmt_core_ic_ops_check(p_ops)) { ++ WMT_ERR_FUNC ++ ("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", ++ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); ++ return -4; ++ } ++ WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", ++ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); ++ ++ wmt_ic_ops_soc.icId = chipid; ++ WMT_DBG_FUNC("wmt_ic_ops_soc.icId(0x%x)\n", wmt_ic_ops_soc.icId); ++ iret = p_ops->ic_ver_check(); ++ if (iret) { ++ WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret); ++ return -5; ++ } ++ ++ WMT_DBG_FUNC("chip id(0x%x) ver_check ok\n", chipid); ++ gMtkWmtCtx.p_ic_ops = p_ops; ++ return 0; ++} ++ ++static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp) ++{ ++ if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) { ++ WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n"); ++ return -1; ++ } ++ ++ if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) { ++ WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. overwrite! old (%d), new(%d))\n", ++ gMtkWmtCtx.wmtHifConf.hifType, pWmtOp->au4OpData[0]); ++ } else { ++ gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT; ++ WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n"); ++ } ++ ++ osal_memcpy(&gMtkWmtCtx.wmtHifConf, &pWmtOp->au4OpData[0], osal_sizeof(gMtkWmtCtx.wmtHifConf)); ++ return 0; ++ ++} ++ ++static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ INT32 retry = WMT_PWRON_RTY_DFT; ++ ++ if (DRV_STS_POWER_OFF != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n", ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); ++ osal_assert(0); ++ return -1; ++ } ++ /* TODO: [FixMe][GeorgeKuo]: clarify the following is reqiured or not! */ ++ if (pWmtOp->u4InfoBit & WMT_OP_HIF_BIT) ++ opfunc_hif_conf(pWmtOp); ++ ++pwr_on_rty: ++ /* power on control */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); ++ if (0 == retry--) { ++ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); ++ goto pwr_on_rty; ++ } ++ return -1; ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ ++ /* init stp */ ++ iRet = wmt_core_stp_init(); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet); ++ osal_assert(0); ++ ++ /* deinit stp */ ++ iRet = wmt_core_stp_deinit(); ++ iRet = opfunc_pwr_off(pWmtOp); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: opfunc_pwr_off fail during pwr_on retry\n"); ++ ++ if (0 < retry--) { ++ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); ++ goto pwr_on_rty; ++ } ++ iRet = -2; ++ return iRet; ++ } ++ ++ WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n"); ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; ++ ++ /* What to do when state is changed from POWER_OFF to POWER_ON? ++ * 1. STP driver does s/w reset ++ * 2. UART does 0xFF wake up ++ * 3. SDIO does re-init command(changed to trigger by host) ++ */ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n", ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); ++ osal_assert(0); ++ return -1; ++ } ++ if (MTK_WCN_BOOL_FALSE == g_pwr_off_flag) { ++ WMT_WARN_FUNC("CONNSYS power off be disabled, maybe need trigger core dump!\n"); ++ osal_assert(0); ++ return -2; ++ } ++ ++ /* wmt and stp are initialized successfully */ ++ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ iRet = wmt_core_stp_deinit(); ++ if (iRet) { ++ WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet); ++ /*should let run to power down chip */ ++ } ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ ++ /* power off control */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet); ++ WMT_WARN_FUNC("HW_PWR_OFF ok\n"); ++ ++ /*anyway, set to POWER_OFF state */ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; ++ return iRet; ++ ++} ++ ++static INT32 opfunc_func_on(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = -1; ++ INT32 iPwrOffRet = -1; ++ UINT32 drvType; ++ ++ drvType = pWmtOp->au4OpData[0]; ++ ++ /* Check abnormal type */ ++ if (WMTDRV_TYPE_COREDUMP < drvType) { ++ WMT_ERR_FUNC("abnormal Fun(%d)\n", drvType); ++ osal_assert(0); ++ return -1; ++ } ++ ++ /* Check abnormal state */ ++ if ((DRV_STS_POWER_OFF > gMtkWmtCtx.eDrvStatus[drvType]) ++ || (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType])) { ++ WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n", drvType, gMtkWmtCtx.eDrvStatus[drvType]); ++ osal_assert(0); ++ return -2; ++ } ++ ++ /* check if func already on */ ++ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[drvType]) { ++ WMT_WARN_FUNC("func(%d) already on\n", drvType); ++ return 0; ++ } ++ /*enable power off flag, if flag=0, power off connsys will not be executed */ ++ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); ++ /* check if chip power on is needed */ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ iRet = opfunc_pwr_on(pWmtOp); ++ ++ if (iRet) { ++ WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet); ++ osal_assert(0); ++ ++ /* check all sub-func and do power off */ ++ return -3; ++ } ++ } ++ ++ if (WMTDRV_TYPE_WMT > drvType) { ++ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_on) { ++ iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); ++ if (0 != iRet) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ else ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; ++ } else { ++ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); ++ iRet = -5; ++ } ++ } else { ++ if (WMTDRV_TYPE_LPBK == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; ++ else if (WMTDRV_TYPE_COREDUMP == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; ++ iRet = 0; ++ } ++ ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet); ++ osal_assert(0); ++ /* FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary? */ ++ /* check all sub-func and do power off */ ++ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { ++ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); ++ mtk_wcn_wmt_system_state_reset(); ++ ++ iPwrOffRet = opfunc_pwr_off(pWmtOp); ++ if (iPwrOffRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iPwrOffRet, ++ drvType); ++ osal_assert(0); ++ } ++ } ++ return iRet; ++ } ++ ++ wmt_core_dump_func_state("AF FUNC ON"); ++ ++ return 0; ++} ++ ++static INT32 opfunc_func_off(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 drvType; ++ ++ drvType = pWmtOp->au4OpData[0]; ++ /* Check abnormal type */ ++ if (WMTDRV_TYPE_COREDUMP < drvType) { ++ WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off\n", drvType); ++ osal_assert(0); ++ return -1; ++ } ++ ++ /* Check abnormal state */ ++ if (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) { ++ WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off\n", ++ drvType, gMtkWmtCtx.eDrvStatus[drvType]); ++ osal_assert(0); ++ return -2; ++ } ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[drvType]) { ++ WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n", ++ drvType, gMtkWmtCtx.eDrvStatus[drvType]); ++ /* needs to check 4 subsystem's state? */ ++ return 0; ++ } else if (WMTDRV_TYPE_WMT > drvType) { ++ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_off) { ++ iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); ++ } else { ++ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); ++ iRet = -3; ++ } ++ } else { ++ if (WMTDRV_TYPE_LPBK == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ else if (WMTDRV_TYPE_COREDUMP == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ iRet = 0; ++ } ++ ++ /* shall we put device state to POWER_OFF state when fail? */ ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet); ++ osal_assert(0); ++ /* no matter subsystem function control fail or not, ++ *chip should be powered off when no subsystem is active ++ */ ++ /* return iRet; */ ++ } ++ ++ /* check all sub-func and do power off */ ++ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { ++ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); ++ ++ iRet = opfunc_pwr_off(pWmtOp); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iRet, drvType); ++ osal_assert(0); ++ } ++ } ++ ++ wmt_core_dump_func_state("AF FUNC OFF"); ++ return iRet; ++} ++ ++/* TODO:[ChangeFeature][George] is this OP obsoleted? */ ++static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp) ++{ ++ INT32 iret; ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("reg_rw when WMT is powered off\n"); ++ return -1; ++ } ++ iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0], ++ pWmtOp->au4OpData[1], (PUINT32) pWmtOp->au4OpData[2], pWmtOp->au4OpData[3]); ++ ++ return iret; ++} ++ ++static INT32 opfunc_exit(P_WMT_OP pWmtOp) ++{ ++ /* TODO: [FixMe][George] is ok to leave this function empty??? */ ++ WMT_WARN_FUNC("EMPTY FUNCTION\n"); ++ return 0; ++} ++ ++static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp) ++{ ++ INT32 ret = -1; ++ UINT32 u4_result = 0; ++ UINT32 evt_len; ++ UINT8 evt_buf[16] = { 0 }; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ typedef INT32(*STP_PSM_CB) (INT32); ++ STP_PSM_CB psm_cb = NULL; ++ ++ if (SLEEP == pWmtOp->au4OpData[0]) { ++ WMT_DBG_FUNC("**** Send sleep command\n"); ++ /* mtk_wcn_stp_set_psm_state(ACT_INACT); */ ++ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ ++ ret = wmt_core_tx((PUINT8) &WMT_SLEEP_CMD[0], sizeof(WMT_SLEEP_CMD), &u4_result, 0); ++ if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) { ++ WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, ++ sizeof(WMT_SLEEP_CMD)); ++ goto pwr_sv_done; ++ } ++ ++ evt_len = sizeof(WMT_SLEEP_EVT); ++ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); ++ if (ret || (u4_result != evt_len)) { ++ unsigned long type = WMTDRV_TYPE_WMT; ++ unsigned long reason = 33; ++ unsigned long ctrlpa = 1; ++ ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); ++ mtk_wcn_stp_dbg_dump_package(); ++ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); ++ if (!ret) { /* parser ok */ ++ reason = 38; /* host schedule issue reason code */ ++ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); ++ } ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); ++ goto pwr_sv_done; ++ } ++ ++ if (osal_memcmp(evt_buf, WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n"); ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ u4_result, ++ evt_buf[0], ++ evt_buf[1], ++ evt_buf[2], ++ evt_buf[3], ++ evt_buf[4], ++ evt_buf[5]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_SLEEP_EVT), ++ WMT_SLEEP_EVT[0], ++ WMT_SLEEP_EVT[1], ++ WMT_SLEEP_EVT[2], ++ WMT_SLEEP_EVT[3], ++ WMT_SLEEP_EVT[4], ++ WMT_SLEEP_EVT[5]); ++ mtk_wcn_stp_dbg_dump_package(); ++ goto pwr_sv_done; ++ } else { ++ WMT_DBG_FUNC("Send sleep command OK!\n"); ++ } ++ } else if (pWmtOp->au4OpData[0] == WAKEUP) { ++ WMT_DBG_FUNC("wakeup connsys by btif"); ++ ++ ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS, &ctrlPa1, &ctrlPa2); ++ if (ret) { ++ WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)", ret); ++ goto pwr_sv_done; ++ } ++#if 0 ++ WMT_DBG_FUNC("**** Send wakeup command\n"); ++ ret = wmt_core_tx(WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1); ++ ++ if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD))) { ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, ++ sizeof(WMT_WAKEUP_CMD)); ++ goto pwr_sv_done; ++ } ++#endif ++ evt_len = sizeof(WMT_WAKEUP_EVT); ++ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); ++ if (ret || (u4_result != evt_len)) { ++ unsigned long type = WMTDRV_TYPE_WMT; ++ unsigned long reason = 34; ++ unsigned long ctrlpa = 2; ++ ++ WMT_ERR_FUNC("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); ++ mtk_wcn_stp_dbg_dump_package(); ++ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); ++ if (!ret) { /* parser ok */ ++ reason = 39; /* host schedule issue reason code */ ++ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); ++ } ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); ++ goto pwr_sv_done; ++ } ++ ++ if (osal_memcmp(evt_buf, WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n"); ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ u4_result, ++ evt_buf[0], ++ evt_buf[1], ++ evt_buf[2], ++ evt_buf[3], ++ evt_buf[4], ++ evt_buf[5]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_WAKEUP_EVT), ++ WMT_WAKEUP_EVT[0], ++ WMT_WAKEUP_EVT[1], ++ WMT_WAKEUP_EVT[2], ++ WMT_WAKEUP_EVT[3], ++ WMT_WAKEUP_EVT[4], ++ WMT_WAKEUP_EVT[5]); ++ mtk_wcn_stp_dbg_dump_package(); ++ goto pwr_sv_done; ++ } else { ++ WMT_DBG_FUNC("Send wakeup command OK!\n"); ++ } ++ } else if (pWmtOp->au4OpData[0] == HOST_AWAKE) { ++ ++ WMT_DBG_FUNC("**** Send host awake command\n"); ++ ++ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; ++ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ ++ ret = wmt_core_tx((PUINT8) WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), &u4_result, 0); ++ if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD))) { ++ WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, ++ sizeof(WMT_HOST_AWAKE_CMD)); ++ goto pwr_sv_done; ++ } ++ ++ evt_len = sizeof(WMT_HOST_AWAKE_EVT); ++ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); ++ if (ret || (u4_result != evt_len)) { ++ unsigned long type = WMTDRV_TYPE_WMT; ++ unsigned long reason = 35; ++ unsigned long ctrlpa = 3; ++ ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: read HOST_AWAKE_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); ++ mtk_wcn_stp_dbg_dump_package(); ++ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); ++ if (!ret) { /* parser ok */ ++ reason = 40; /* host schedule issue reason code */ ++ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); ++ } ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); ++ goto pwr_sv_done; ++ } ++ ++ if (osal_memcmp(evt_buf, WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n"); ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ u4_result, ++ evt_buf[0], ++ evt_buf[1], ++ evt_buf[2], ++ evt_buf[3], ++ evt_buf[4], ++ evt_buf[5]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_HOST_AWAKE_EVT), ++ WMT_HOST_AWAKE_EVT[0], ++ WMT_HOST_AWAKE_EVT[1], ++ WMT_HOST_AWAKE_EVT[2], ++ WMT_HOST_AWAKE_EVT[3], ++ WMT_HOST_AWAKE_EVT[4], ++ WMT_HOST_AWAKE_EVT[5]); ++ mtk_wcn_stp_dbg_dump_package(); ++ /* goto pwr_sv_done; */ ++ } else { ++ WMT_DBG_FUNC("Send host awake command OK!\n"); ++ } ++ } ++pwr_sv_done: ++ ++ if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) { ++ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; ++ WMT_DBG_FUNC("Do STP-CB! %d %p / %p\n", pWmtOp->au4OpData[0], (PVOID) pWmtOp->au4OpData[1], ++ (PVOID) psm_cb); ++ if (NULL != psm_cb) { ++ psm_cb(pWmtOp->au4OpData[0]); ++ } else { ++ WMT_ERR_FUNC("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n", ++ psm_cb); ++ } ++ } ++ ++ return ret; ++} ++ ++static INT32 opfunc_dsns(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ WMT_DSNS_CMD[4] = (UINT8) pWmtOp->au4OpData[0]; ++ WMT_DSNS_CMD[5] = (UINT8) pWmtOp->au4OpData[1]; ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) { ++ WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, ++ osal_sizeof(WMT_DSNS_CMD)); ++ return iRet; ++ } ++ ++ evtLen = osal_sizeof(WMT_DSNS_EVT); ++ ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if (iRet || (u4Res != evtLen)) { ++ WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); ++ mtk_wcn_stp_dbg_dump_package(); ++ return iRet; ++ } ++ ++ if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) { ++ WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n"); ++ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], ++ osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2], ++ WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]); ++ } else { ++ WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n"); ++ } ++ ++ return iRet; ++} ++ ++#if CFG_CORE_INTERNAL_TXRX ++INT32 wmt_core_lpbk_do_stp_init(void) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); ++ return -1; ++ } ++ ++ ctrlPa1 = WMT_STP_CONF_MODE; ++ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 1; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); ++ return -2; ++ } ++} ++ ++INT32 wmt_core_lpbk_do_stp_deinit(void) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++#endif ++static INT32 opfunc_lpbk(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet; ++ UINT32 u4WrittenSize = 0; ++ UINT32 u4ReadSize = 0; ++ UINT32 buf_length = 0; ++ UINT32 *pbuffer = NULL; ++ UINT16 len_in_cmd; ++ ++ /* UINT32 offset; */ ++ UINT8 WMT_TEST_LPBK_CMD[] = { 0x1, 0x2, 0x0, 0x0, 0x7 }; ++ UINT8 WMT_TEST_LPBK_EVT[] = { 0x2, 0x2, 0x0, 0x0, 0x0 }; ++ ++ /* UINT8 lpbk_buf[1024 + 5] = {0}; */ ++ MTK_WCN_BOOL fgFail; ++ ++ buf_length = pWmtOp->au4OpData[0]; /* packet length */ ++ pbuffer = (VOID *) pWmtOp->au4OpData[1]; /* packet buffer pointer */ ++ WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk\n"); ++ ++#if 0 ++ osal_memcpy(&WMT_TEST_LPBK_EVT[0], &WMT_TEST_LPBK_CMD[0], osal_sizeof(WMT_TEST_LPBK_CMD)); ++#endif ++#if !CFG_CORE_INTERNAL_TXRX ++ /*check if WMTDRV_TYPE_LPBK function is already on */ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] ++ || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) { ++ WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n"); ++ osal_assert(0); ++ return -2; ++ } ++#endif ++ /*package loopback for STP */ ++ ++ /* init buffer */ ++ osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf)); ++ ++ len_in_cmd = buf_length + 1; /* add flag field */ ++ ++ osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2); ++ osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2); ++ ++ /* wmt cmd */ ++ osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD)); ++ osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length); ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ /*send packet through STP */ ++ ++ /* iRet = (*kal_stp_tx)( ++ *(PUINT8)gLpbkBuf, ++ *osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length, ++ *&u4WrittenSize); ++ */ ++ iRet = wmt_core_tx((PUINT8) gLpbkBuf, ++ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length), ++ &u4WrittenSize, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet) { ++ WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed\n"); ++ break; ++ } ++ WMT_INFO_FUNC("opfunc_lpbk wmt_core_tx OK\n"); ++ ++ /*receive firmware response from STP */ ++ iRet = wmt_core_rx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), &u4ReadSize); ++ if (iRet) { ++ WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed\n"); ++ break; ++ } ++ WMT_INFO_FUNC("opfunc_lpbk wmt_core_rx OK\n"); ++ /*check if loopback response ok or not */ ++ if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) { ++ WMT_ERR_FUNC("lpbk event read size wrong(%d, %d)\n", u4ReadSize, ++ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); ++ break; ++ } ++ WMT_INFO_FUNC("lpbk event read size right(%d, %d)\n", u4ReadSize, ++ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); ++ ++ if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) { ++ WMT_ERR_FUNC("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x]\n", ++ (INT32) u4ReadSize, gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], gLpbkBuf[4] ++ ); ++ break; ++ } ++ pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT); ++ osal_memcpy((VOID *) pWmtOp->au4OpData[1], gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length); ++ fgFail = MTK_WCN_BOOL_FALSE; ++ } while (0); ++ /*return result */ ++ /* WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d\n", fgFail); */ ++ return fgFail; ++ ++} ++ ++static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = 0; ++ UINT32 cmdNo = 0; ++ UINT32 cmdNoPa = 0; ++ ++ UINT8 tstCmd[64]; ++ UINT8 tstEvt[64]; ++ UINT8 tstEvtTmp[64]; ++ UINT32 u4Res; ++ SIZE_T tstCmdSz = 0; ++ SIZE_T tstEvtSz = 0; ++ ++ UINT8 *pRes = NULL; ++ UINT32 resBufRoom = 0; ++ /*test command list */ ++ /*1 */ ++ UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; ++ UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ UINT8 WMT_NOACK_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0A }; ++ UINT8 WMT_NOACK_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ UINT8 WMT_WARNRST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0B }; ++ UINT8 WMT_WARNRST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ UINT8 WMT_FWLOGTST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0C }; ++ UINT8 WMT_FWLOGTST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ ++ UINT8 WMT_EXCEPTION_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x09 }; ++ UINT8 WMT_EXCEPTION_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ /*2 */ ++ UINT8 WMT_COEXDBG_CMD[] = { 0x01, 0x10, 0x02, 0x00, ++ 0x08, ++ 0xAA /*Debugging Parameter */ ++ }; ++ UINT8 WMT_COEXDBG_1_EVT[] = { 0x02, 0x10, 0x05, 0x00, ++ 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA /*event content */ ++ }; ++ UINT8 WMT_COEXDBG_2_EVT[] = { 0x02, 0x10, 0x07, 0x00, ++ 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB /*event content */ ++ }; ++ UINT8 WMT_COEXDBG_3_EVT[] = { 0x02, 0x10, 0x0B, 0x00, ++ 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB /*event content */ ++ }; ++ /*test command list -end */ ++ ++ cmdNo = pWmtOp->au4OpData[0]; ++ ++ WMT_INFO_FUNC("Send Test command %d!\n", cmdNo); ++ if (cmdNo == 0) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send Assert command !\n"); ++ tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); ++ tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); ++ osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); ++ } else if (cmdNo == 1) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send Exception command !\n"); ++ tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD); ++ tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT); ++ osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz); ++ } else if (cmdNo == 2) { ++ cmdNoPa = pWmtOp->au4OpData[1]; ++ pRes = (PUINT8) pWmtOp->au4OpData[2]; ++ resBufRoom = pWmtOp->au4OpData[3]; ++ if (cmdNoPa <= 0xf) { ++ WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa); ++ tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD); ++ osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz); ++ if (tstCmdSz > 5) ++ tstCmd[5] = cmdNoPa; ++ ++ /*setup the expected event length */ ++ if (cmdNoPa <= 0x4) { ++ tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT); ++ osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz); ++ } else if (cmdNoPa == 0x5) { ++ tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT); ++ osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz); ++ } else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) { ++ tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT); ++ osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz); ++ } else { ++ ++ } ++ } else { ++ WMT_ERR_FUNC("cmdNoPa is wrong\n"); ++ return iRet; ++ } ++ } else if (cmdNo == 3) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send No Ack command !\n"); ++ tstCmdSz = osal_sizeof(WMT_NOACK_CMD); ++ tstEvtSz = osal_sizeof(WMT_NOACK_EVT); ++ osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz); ++ } else if (cmdNo == 4) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send Warm reset command !\n"); ++ tstCmdSz = osal_sizeof(WMT_WARNRST_CMD); ++ tstEvtSz = osal_sizeof(WMT_WARNRST_EVT); ++ osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz); ++ } else if (cmdNo == 5) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send f/w log test command !\n"); ++ tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD); ++ tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT); ++ osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz); ++ } ++ ++ else { ++ /*Placed youer test WMT command here, easiler to integrate and test with F/W side */ ++ } ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != tstCmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, tstCmdSz); ++ return -1; ++ } ++ ++ if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) { ++ WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n"); ++ return 0; ++ } ++ ++ iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res); ++ ++ /*Event Post Handling */ ++ if (cmdNo == 2) { ++ WMT_INFO_FUNC("#=========================================================#\n"); ++ WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa); ++ if (tstEvtSz > 5) { ++ wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5); ++ } else { ++ /* error log */ ++ WMT_ERR_FUNC("error coex debugging event\n"); ++ } ++ /*put response to buffer for shell to read */ ++ if (pRes != NULL && resBufRoom > 0) { ++ pWmtOp->au4OpData[3] = resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5; ++ osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]); ++ } else ++ pWmtOp->au4OpData[3] = 0; ++ WMT_INFO_FUNC("#=========================================================#\n"); ++ } ++ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ wmt_core_dump_func_state("BE HW RST"); ++ /*-->Reset WMT data structure*/ ++ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; */ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF; ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF; ++ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; */ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] = DRV_STS_POWER_OFF; ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF; ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF; ++ /*enable power off flag, if flag=0, power off connsys will not be executed */ ++ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); ++ /* if wmt is poweroff, we need poweron chip first */ ++ /* Zhiguo : this action also needed in BTIF interface to avoid KE */ ++#if 1 ++ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n"); ++ /* power on control */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); ++ return -1; ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ } ++#endif ++ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON) { ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); ++ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; ++ } ++ ++ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) { ++ ++ if (NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI] && NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off) { ++ iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet); ++ ++ /* check all sub-func and do power off */ ++ } else { ++ WMT_INFO_FUNC("wmt core: turn off WIFI func ok!!\n"); ++ } ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; ++ } ++#if 0 ++ /*<4>Power off Combo chip */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet); ++ WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet); ++#endif ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; ++ ++ /*-->PesetCombo chip*/ ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet); ++ WMT_WARN_FUNC("WMT-CORE: -->[HW RST] ok\n"); ++ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ ++ /* 4 close stp */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ if (iRet == -2) { ++ WMT_INFO_FUNC("WMT-CORE:stp should have be closed\n"); ++ return 0; ++ } ++ WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n"); ++ return -1; ++ } ++ ++ wmt_core_dump_func_state("AF HW RST"); ++ return iRet; ++ ++} ++ ++static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = 0; ++ ++ iRet = wmt_core_stp_init(); ++ if (!iRet) ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; ++ return iRet; ++} ++ ++static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp) ++{ ++ ++ return 0; ++} ++ ++static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ WMT_THERM_CMD[4] = pWmtOp->au4OpData[0]; /*CMD type, refer to ENUM_WMTTHERM_TYPE_T */ ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) { ++ WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, ++ osal_sizeof(WMT_THERM_CMD)); ++ return iRet; ++ } ++ ++ evtLen = 16; ++ ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT)))) { ++ WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d, %d)\n", iRet, u4Res, ++ evtLen); ++ mtk_wcn_stp_dbg_dump_package(); ++ return iRet; ++ } ++ if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT)) { ++ if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) { ++ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n"); ++ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], ++ osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], WMT_THERM_CTRL_EVT[1], ++ WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], WMT_THERM_CTRL_EVT[4]); ++ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE; /*will return to function driver */ ++ mtk_wcn_stp_dbg_dump_package(); ++ } else { ++ WMT_DBG_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n"); ++ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE; /*will return to function driver */ ++ } ++ } else { ++ /*no need to judge the real thermal value */ ++ if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != 0) { ++ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n"); ++ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5], ++ osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], WMT_THERM_READ_EVT[1], ++ WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]); ++ pWmtOp->au4OpData[1] = 0xFF; /*will return to function driver */ ++ mtk_wcn_stp_dbg_dump_package(); ++ } else { ++ WMT_DBG_FUNC("Send WMT_THERM_READ_CMD command OK!\n"); ++ pWmtOp->au4OpData[1] = evtBuf[5]; /*will return to function driver */ ++ } ++ } ++ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n"); ++ return -1; ++ } ++ ++ WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2; /* w:2, r:1 */ ++ osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8) &pWmtOp->au4OpData[1], 2); /* address */ ++ osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32) pWmtOp->au4OpData[2], 4); /* value */ ++ ++ wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD)); ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) { ++ WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, ++ osal_sizeof(WMT_EFUSE_CMD)); ++ return iRet; ++ } ++ ++ evtLen = (pWmtOp->au4OpData[0]) ? osal_sizeof(WMT_EFUSE_EVT) : osal_sizeof(WMT_EFUSE_EVT); ++ ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if (iRet || (u4Res != evtLen)) ++ WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); ++ wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf)); ++ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = -1; ++ WMT_IC_PIN_ID id; ++ WMT_IC_PIN_STATE stat; ++ UINT32 flag; ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n"); ++ return -1; ++ } ++ ++ if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) { ++ WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n"); ++ return -1; ++ } ++ ++ id = pWmtOp->au4OpData[0]; ++ stat = pWmtOp->au4OpData[1]; ++ flag = pWmtOp->au4OpData[2]; ++ ++ WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id, stat, flag); ++ ++ iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl)) (id, stat, flag); ++ ++ return iRet; ++} ++ ++MTK_WCN_BOOL wmt_core_is_quick_ps_support(void) ++{ ++ P_WMT_CTX pctx = &gMtkWmtCtx; ++ ++ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_quick_sleep)) ++ return (*(pctx->p_ic_ops->is_quick_sleep)) (); ++ ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void) ++{ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_WMT_CTX pctx = &gMtkWmtCtx; ++ ++ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_aee_dump_support)) ++ bRet = (*(pctx->p_ic_ops->is_aee_dump_support)) (); ++ else ++ bRet = MTK_WCN_BOOL_FALSE; ++ ++ return bRet; ++} ++ ++INT32 opfunc_pin_state(P_WMT_OP pWmtOp) ++{ ++ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ UINT32 iRet = 0; ++ ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2); ++ return iRet; ++} ++ ++static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = -1; ++ UINT32 u4WrittenSize = 0; ++ UINT32 u4ReadSize = 0; ++ UINT32 buf_len = 0; ++ UINT8 *buffer = NULL; ++ UINT8 evt_buffer[8] = { 0 }; ++ MTK_WCN_BOOL fgFail; ++ ++ UINT8 WMT_BGW_DESENSE_CMD[] = { ++ 0x01, 0x0e, 0x0f, 0x00, ++ 0x02, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00 ++ }; ++ UINT8 WMT_BGW_DESENSE_EVT[] = { 0x02, 0x0e, 0x01, 0x00, 0x00 }; ++ ++ buf_len = pWmtOp->au4OpData[0]; ++ buffer = (PUINT8) pWmtOp->au4OpData[1]; ++ ++ osal_memcpy(&WMT_BGW_DESENSE_CMD[5], buffer, buf_len); ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ iRet = ++ wmt_core_tx(&WMT_BGW_DESENSE_CMD[0], osal_sizeof(WMT_BGW_DESENSE_CMD), &u4WrittenSize, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))) { ++ WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); ++ break; ++ } ++ ++ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_BGW_DESENSE_EVT), &u4ReadSize); ++ if (iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))) { ++ WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize); ++ break; ++ } ++ ++ if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) { ++ WMT_ERR_FUNC ++ ("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", ++ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4]); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ ++ return fgFail; ++} ++ ++static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp) ++{ ++ UINT32 kind = 0; ++ INT32 iRet = -1; ++ UINT32 u4WrittenSize = 0; ++ UINT32 u4ReadSize = 0; ++ UINT8 evt_buffer[12] = { 0 }; ++ MTK_WCN_BOOL fgFail; ++ PUINT8 set_mcu_clk_str[] = { ++ "Enable MCU PLL", ++ "SET MCU CLK to 26M", ++ "SET MCU CLK to 37M", ++ "SET MCU CLK to 64M", ++ "SET MCU CLK to 69M", ++ "SET MCU CLK to 104M", ++ "SET MCU CLK to 118.857M", ++ "SET MCU CLK to 138.67M", ++ "Disable MCU PLL" ++ }; ++ UINT8 WMT_SET_MCU_CLK_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++ }; ++ UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++ UINT8 WMT_EN_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00 }; /* enable pll clk */ ++ UINT8 WMT_26_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x00, 0x4d, 0x84, 0x00 }; /* set 26M */ ++ UINT8 WMT_37_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1e, 0x4d, 0x84, 0x00 }; /* set 37.8M */ ++ UINT8 WMT_64_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1d, 0x4d, 0x84, 0x00 }; /* set 64M */ ++ UINT8 WMT_69_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1c, 0x4d, 0x84, 0x00 }; /* set 69M */ ++ UINT8 WMT_104_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5b, 0x4d, 0x84, 0x00 }; /* set 104M */ ++ UINT8 WMT_108_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5a, 0x4d, 0x84, 0x00 }; /* set 118.857M */ ++ UINT8 WMT_138_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x59, 0x4d, 0x84, 0x00 }; /* set 138.67M */ ++ UINT8 WMT_DIS_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 }; /* disable pll clk */ ++ ++ kind = pWmtOp->au4OpData[0]; ++ WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]); ++ ++ switch (kind) { ++ case 0: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_EN_MCU_CLK_CMD[0], osal_sizeof(WMT_EN_MCU_CLK_CMD)); ++ break; ++ case 1: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_26_MCU_CLK_CMD[0], osal_sizeof(WMT_26_MCU_CLK_CMD)); ++ break; ++ case 2: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_37_MCU_CLK_CMD[0], osal_sizeof(WMT_37_MCU_CLK_CMD)); ++ break; ++ case 3: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_64_MCU_CLK_CMD[0], osal_sizeof(WMT_64_MCU_CLK_CMD)); ++ break; ++ case 4: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_69_MCU_CLK_CMD[0], osal_sizeof(WMT_69_MCU_CLK_CMD)); ++ break; ++ case 5: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_104_MCU_CLK_CMD[0], osal_sizeof(WMT_104_MCU_CLK_CMD)); ++ break; ++ case 6: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_108_MCU_CLK_CMD[0], osal_sizeof(WMT_108_MCU_CLK_CMD)); ++ break; ++ case 7: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_138_MCU_CLK_CMD[0], osal_sizeof(WMT_138_MCU_CLK_CMD)); ++ break; ++ case 8: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_DIS_MCU_CLK_CMD[0], osal_sizeof(WMT_DIS_MCU_CLK_CMD)); ++ break; ++ default: ++ WMT_ERR_FUNC("unknown kind\n"); ++ break; ++ } ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ iRet = ++ wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { ++ WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); ++ break; ++ } ++ ++ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); ++ if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { ++ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); ++ break; ++ } ++ ++ if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { ++ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", ++ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4], ++ evt_buffer[5], evt_buffer[6], evt_buffer[7]); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ ++ if (MTK_WCN_BOOL_FALSE == fgFail) ++ WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]); ++ ++ WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]); ++ ++ return fgFail; ++} ++ ++static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp) ++{ ++ UINT8 *buffer = NULL; ++ MTK_WCN_BOOL fgFail; ++ UINT32 u4Res; ++ UINT32 aDieChipid = 0; ++ UINT8 soc_adie_chipid_cmd[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; ++ UINT8 soc_adie_chipid_evt[] = { 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ UINT8 evtbuf[20]; ++ INT32 iRet = -1; ++ ++ buffer = (PUINT8) pWmtOp->au4OpData[1]; ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ /* read A die chipid by wmt cmd */ ++ iRet = ++ wmt_core_tx((PUINT8) &soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, osal_sizeof(soc_adie_chipid_evt), &u4Res); ++ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); ++ osal_memcpy(buffer, &evtbuf[u4Res - 2], 2); ++ pWmtOp->au4OpData[0] = 2; ++ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ ++ return fgFail; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp) ++{ ++ MTK_WCN_BOOL fgFail; ++ UINT32 u4Res; ++ UINT8 host_lte_btwf_coex_cmd[] = { 0x01, 0x10, 0x00, 0x00, 0x00 }; ++ UINT8 host_lte_btwf_coex_evt[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ UINT8 *pTxBuf = NULL; ++ UINT8 evtbuf[8] = { 0 }; ++ INT32 iRet = -1; ++ UINT16 msg_len = 0; ++ UINT32 total_len = 0; ++ UINT32 index = 0; ++ UINT8 *msg_local_buffer = NULL; ++ ++ msg_local_buffer = kmalloc(1300, GFP_KERNEL); ++ if (!msg_local_buffer) { ++ WMT_ERR_FUNC("msg_local_buffer kmalloc memory fail\n"); ++ return 0; ++ } ++ ++ pTxBuf = (UINT8 *) pWmtOp->au4OpData[0]; ++ if (NULL == pTxBuf) { ++ WMT_ERR_FUNC("idc msg buffer is NULL\n"); ++ return -1; ++ } ++ iRet = wmt_lib_idc_lock_aquire(); ++ if (iRet) { ++ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", iRet); ++ return iRet; ++ } ++ osal_memcpy(&msg_len, &pTxBuf[0], osal_sizeof(msg_len)); ++ if (msg_len > 1200) { ++ wmt_lib_idc_lock_release(); ++ WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len); ++ return -2; ++ } ++ msg_len += 1; /*flag byte */ ++ ++ osal_memcpy(&host_lte_btwf_coex_cmd[2], &msg_len, 2); ++ host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff); ++ osal_memcpy(&msg_local_buffer[0], &host_lte_btwf_coex_cmd[0], osal_sizeof(host_lte_btwf_coex_cmd)); ++ osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)], ++ &pTxBuf[osal_sizeof(msg_len)], msg_len - 1); ++ ++ wmt_lib_idc_lock_release(); ++ total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1; ++ ++ WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n", msg_len - 1, ++ total_len); ++ WMT_DBG_FUNC("wmt_core:idc msg payload:\n"); ++ ++ for (index = 0; index < total_len; index++) ++ WMT_DBG_FUNC("0x%02x ", msg_local_buffer[index]); ++ ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ /* read A die chipid by wmt cmd */ ++ iRet = wmt_core_tx((PUINT8) &msg_local_buffer[0], total_len, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != total_len)) { ++ WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, osal_sizeof(host_lte_btwf_coex_evt), &u4Res); ++ if (iRet || (u4Res != osal_sizeof(host_lte_btwf_coex_evt))) { ++ WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ kfree(msg_local_buffer); ++ return fgFail; ++} ++#endif ++ ++VOID wmt_core_set_coredump_state(ENUM_DRV_STS state) ++{ ++ WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n", state); ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state; ++} ++#ifdef CONFIG_MTK_COMBO_ANT ++INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = 0; ++ size_t ctrlPa1 = pWmtOp->au4OpData[0]; ++ UINT32 ctrlPa2 = pWmtOp->au4OpData[1]; ++ PUINT8 pbuf = (PUINT8) ctrlPa1; ++ UINT32 fragSeq = 0; ++ UINT16 fragSize = 0; ++ UINT16 wmtCmdLen; ++ UINT16 wmtPktLen; ++ UINT32 u4Res = 0; ++ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_DWN_EVT)]; ++#if 1 ++ UINT32 ctrlPa3 = pWmtOp->au4OpData[2]; ++ ++ do { ++ fragSize = ctrlPa2; ++ fragSeq = ctrlPa3; ++ gAntBuf[5] = fragSeq; ++ ++ ++ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_DWN_CMD) + 1; ++ ++ /*WMT command length cal */ ++ wmtCmdLen = wmtPktLen - 4; ++#if 0 ++ WMT_ANT_RAM_DWN_CMD[2] = wmtCmdLen & 0xFF; ++ WMT_ANT_RAM_DWN_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; ++#else ++ osal_memcpy(&WMT_ANT_RAM_DWN_CMD[2], &wmtCmdLen, 2); ++#endif ++ ++ ++ ++ WMT_ANT_RAM_DWN_CMD[4] = 1; /*RAM CODE download */ ++ ++ osal_memcpy(gAntBuf, WMT_ANT_RAM_DWN_CMD, sizeof(WMT_ANT_RAM_DWN_CMD)); ++ ++ /*copy ram code content to global buffer */ ++ osal_memcpy(&gAntBuf[osal_sizeof(WMT_ANT_RAM_DWN_CMD) + 1], pbuf, fragSize); ++ ++ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != wmtPktLen)) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ wmtPktLen, u4Res, iRet); ++ iRet = -4; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, wmtPktLen, u4Res); ++ ++ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); ++ ++ WMT_ANT_RAM_DWN_EVT[4] = 0; /*download result; 0 */ ++ ++ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_DWN_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_DWN_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) fail(%d)\n", ++ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res, iRet); ++ iRet = -5; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_DWN_EVT, sizeof(WMT_ANT_RAM_DWN_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_DWN_EVT result error\n"); ++ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], ++ antEvtBuf[4], sizeof(WMT_ANT_RAM_DWN_EVT), WMT_ANT_RAM_DWN_EVT[0], ++ WMT_ANT_RAM_DWN_EVT[1], WMT_ANT_RAM_DWN_EVT[2], WMT_ANT_RAM_DWN_EVT[3], ++ WMT_ANT_RAM_DWN_EVT[4]); ++ iRet = -6; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) ok\n", ++ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res); ++ ++ } while (0); ++#else ++ UINT32 patchSize = ctrlPa2; ++ UINT32 patchSizePerFrag = 1000; ++ UINT32 offset; ++ UINT32 fragNum = 0; ++ /*cal patch fragNum */ ++ fragNum = (patchSize + patchSizePerFrag - 1) / patchSizePerFrag; ++ if (2 >= fragNum) { ++ WMT_WARN_FUNC("ANT ramcode size(%d) too short\n", patchSize); ++ return -1; ++ } ++ ++ while (fragSeq < fragNum) { ++ /*update fragNum */ ++ fragSeq++; ++ ++ if (1 == fragSeq) { ++ fragSize = patchSizePerFrag; ++ /*first package */ ++ gAntBuf[5] = 1; /*RAM CODE start */ ++ } else if (fragNum == fragSeq) { ++ /*last package */ ++ fragSize = patchSizePerFrag; ++ gAntBuf[5] = 3; /*RAM CODE end */ ++ } else { ++ /*middle package */ ++ fragSize = patchSize - ((fragNum - 1) * patchSizePerFrag); ++ gAntBuf[5] = 2; /*RAM CODE confinue */ ++ } ++ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_OP_CMD) + 1; ++ ++ /*WMT command length cal */ ++ wmtCmdLen = wmtPktLen - 4; ++ ++ WMT_ANT_RAM_OP_CMD[2] = wmtCmdLen & 0xFF; ++ WMT_ANT_RAM_OP_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; ++ ++ WMT_ANT_RAM_OP_CMD[4] = 1; /*RAM CODE download */ ++ ++ osal_memcpy(gAntBuf, WMT_ANT_RAM_OP_CMD, sizeof(WMT_ANT_RAM_OP_CMD)); ++ ++ /*copy ram code content to global buffer */ ++ osal_memcpy(&gAntBuf[6], pbuf, fragSize); ++ ++ /*update offset */ ++ offset += fragSize; ++ pbuf += offset; ++ ++ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != wmtPktLen)) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ wmtPktLen, u4Res, iRet); ++ iRet = -4; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, wmtPktLen, u4Res); ++ ++ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); ++ ++ WMT_SET_RAM_OP_EVT[4] = 0; /*download result; 0 */ ++ ++ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_SET_RAM_OP_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_SET_RAM_OP_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) fail(%d)\n", ++ sizeof(WMT_SET_RAM_OP_EVT), u4Res, iRet); ++ iRet = -5; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(antEvtBuf, WMT_SET_RAM_OP_EVT, sizeof(WMT_SET_RAM_OP_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_SET_RAM_OP_EVT result error\n"); ++ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], ++ antEvtBuf[4], sizeof(WMT_SET_RAM_OP_EVT), WMT_SET_RAM_OP_EVT[0], ++ WMT_SET_RAM_OP_EVT[1], WMT_SET_RAM_OP_EVT[2], WMT_SET_RAM_OP_EVT[3], ++ WMT_SET_RAM_OP_EVT[4]); ++ iRet = -6; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) ok\n", ++ sizeof(WMT_SET_RAM_OP_EVT), u4Res); ++ ++ ++ } ++ if (fragSeq != fragNum) ++ iRet = -7; ++#endif ++ return iRet; ++} ++ ++ ++INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = 0; ++ UINT32 u4Res = 0; ++ UINT32 wmtPktLen = osal_sizeof(WMT_ANT_RAM_STA_GET_CMD); ++ UINT32 u4AntRamStatus = 0; ++ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_STA_GET_EVT)]; ++ ++ ++ iRet = wmt_core_tx(WMT_ANT_RAM_STA_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != wmtPktLen)) { ++ WMT_ERR_FUNC ++ ("wmt_core: write wmt and ramcode status query command failed, (%d, %d), iRet(%d)\n", ++ wmtPktLen, u4Res, iRet); ++ iRet = -4; ++ return iRet; ++ } ++ ++ ++ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_STA_GET_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_STA_GET_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_STA_GET_EVT length(%zu, %d) fail(%d)\n", ++ sizeof(WMT_ANT_RAM_STA_GET_EVT), u4Res, iRet); ++ iRet = -5; ++ return iRet; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_STA_GET_EVT, sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1) != ++ 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_STA_GET_EVT result error\n"); ++ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], antEvtBuf[4], ++ sizeof(WMT_ANT_RAM_STA_GET_EVT), WMT_ANT_RAM_STA_GET_EVT[0], ++ WMT_ANT_RAM_STA_GET_EVT[1], WMT_ANT_RAM_STA_GET_EVT[2], ++ WMT_ANT_RAM_STA_GET_EVT[3], WMT_ANT_RAM_STA_GET_EVT[4]); ++ iRet = -6; ++ return iRet; ++ } ++#endif ++ if (0 == iRet) { ++ u4AntRamStatus = antEvtBuf[sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1]; ++ pWmtOp->au4OpData[2] = u4AntRamStatus; ++ WMT_INFO_FUNC("ANT ram code %s\n", ++ 1 == u4AntRamStatus ? "exist already" : "not exist"); ++ } ++ return iRet; ++} ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++/*TEST CODE*/ ++static UINT32 g_open_wmt_lte_flag; ++VOID wmt_core_set_flag_for_test(UINT32 enable) ++{ ++ WMT_INFO_FUNC("%s wmt_lte_flag\n", enable ? "enable" : "disable"); ++ g_open_wmt_lte_flag = enable; ++} ++ ++UINT32 wmt_core_get_flag_for_test(VOID) ++{ ++ return g_open_wmt_lte_flag; ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c +new file mode 100644 +index 000000000000..fa603c208e59 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c +@@ -0,0 +1,1019 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CTRL]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "osal.h" ++ ++#include "wmt_ctrl.h" ++#include "wmt_core.h" ++#include "wmt_ic.h" ++#include "wmt_lib.h" ++#include "wmt_dev.h" ++#include "wmt_plat.h" ++#include "stp_core.h" ++#include "stp_dbg.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* moved to wmt_ctrl.h */ ++/*static INT32 wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/ ++ ++static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value); ++ ++static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA); ++#if 0 ++static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA); ++#endif ++static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData); ++static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData); ++static INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData); ++static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData); ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA); ++#endif ++ ++static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA); ++ ++static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData); ++ ++static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData); ++ ++static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData); ++ ++/* TODO: [FixMe][GeorgeKuo]: remove unused function */ ++/*static INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* GeorgeKuo: Use designated initializers described in ++ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html ++ */ ++static const WMT_CTRL_FUNC wmt_ctrl_func[] = { ++ [WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off, ++ [WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on, ++ [WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst, ++ [WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close, ++ [WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open, ++ [WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf, ++ [WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch, ++ [WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch, ++ [WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name, ++ [WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set, ++ [WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst, ++ [WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf, ++ [WMT_CTRL_TX] = wmt_ctrl_tx, ++ [WMT_CTRL_RX] = wmt_ctrl_rx, ++ [WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush, ++ [WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set, ++ [WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set, ++ [WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search, ++ [WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get, ++ [WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put, ++ [WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show, ++ [WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num, ++ [WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info, ++ [WMT_CTRL_SOC_PALDO_CTRL] = wmt_ctrl_soc_paldo_ctrl, ++ [WMT_CTRL_SOC_WAKEUP_CONSYS] = wmt_ctrl_soc_wakeup_consys, ++ [WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info, ++ [WMT_CTRL_BGW_DESENSE_CTRL] = wmt_ctrl_bgw_desense_ctrl, ++ [WMT_CTRL_EVT_ERR_TRG_ASSERT] = wmt_ctrl_evt_err_trg_assert, ++#if CFG_WMT_LTE_COEX_HANDLING ++ [WMT_CTRL_GET_TDM_REQ_ANTSEL] = wmt_ctrl_get_tdm_req_antsel, ++#endif ++ [WMT_CTRL_EVT_PARSER] = wmt_ctrl_evt_parser, ++ [WMT_CTRL_MAX] = wmt_ctrl_others, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 ctrlId; ++ ++ if (NULL == pWmtCtrlData) { ++ osal_assert(0); ++ return -1; ++ } ++ ++ ctrlId = pWmtCtrlData->ctrlId; ++ /*1sanity check, including wmtCtrlId */ ++ if ((NULL == pWmtCtrlData) ++ || (WMT_CTRL_MAX <= ctrlId)) ++ /* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */ ++ { ++ osal_assert(NULL != pWmtCtrlData); ++ osal_assert(WMT_CTRL_MAX > ctrlId); ++ /* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */ ++ return -2; ++ } ++ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ ++ if (wmt_ctrl_func[ctrlId]) { ++ /*call servicd handling API */ ++ return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData); /* serviceHandlerPack[ctrlId].serviceHandler */ ++ } ++ osal_assert(NULL != wmt_ctrl_func[ctrlId]); ++ return -3; ++ ++} ++ ++INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */) ++{ ++ UINT8 *pData = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ UINT32 size = pWmtCtrlData->au4CtrlData[1]; ++ PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; ++ MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3]; ++ ++ return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); ++} ++ ++INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 readLen; ++ long waitRet = -1; ++ PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ UINT32 buffLen = pWmtCtrlData->au4CtrlData[1]; ++ PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; ++ ++ if (readSize) ++ *readSize = 0; ++ ++ /* sanity check */ ++ if (!buffLen) { ++ WMT_WARN_FUNC("buffLen = 0\n"); ++ osal_assert(buffLen); ++ return 0; ++ } ++#if 0 ++ if (!pDev) { ++ WMT_WARN_FUNC("gpDevWmt = NULL\n"); ++ osal_assert(pDev); ++ return -1; ++ } ++#endif ++ ++ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { ++ WMT_WARN_FUNC("state(0x%lx)\n", pDev->state); ++ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); ++ return -2; ++ } ++ ++ /* sanity ok, proceeding rx operation */ ++ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ ++ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); ++ ++ while (readLen == 0) { /* got nothing, wait for STP's signal */ ++ WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n"); ++ /* iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state)); */ ++ /* waitRet = wait_event_interruptible_timeout( ++ * pDev->rWmtRxWq, ++ * osal_test_bit(WMT_STAT_RX, &pdev->state), ++ * msecs_to_jiffies(WMT_LIB_RX_TIMEOUT)); ++ */ ++ pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT; ++ /* waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX); */ ++ waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq); ++ ++ WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n"); ++ ++ if (0 == waitRet) { ++ WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d)\n", ++ jiffies, pDev->rWmtRxWq.timeoutValue); ++ return -1; ++ } else if (waitRet < 0) { ++ WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet); ++ return waitRet; ++ } ++ WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet); ++ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ ++ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); ++ ++ if (0 == readLen) ++ WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet); ++ ++ } ++ ++ if (readSize) ++ *readSize = readLen; ++ ++ return 0; ++ ++} ++ ++INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet; ++ ++ if (NULL != writtenSize) ++ *writtenSize = 0; ++ ++ /* sanity check */ ++ if (0 == size) { ++ WMT_WARN_FUNC("size to tx is 0\n"); ++ osal_assert(size); ++ return -1; ++ } ++ ++ /* if STP is not enabled yet, can't use this function. Use tx_raw instead */ ++ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) || !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) { ++ WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state); ++ osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state)); ++ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); ++ return -2; ++ } ++ ++ /* sanity ok, proceeding tx operation */ ++ /*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */ ++ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); ++ if (bRawFlag) ++ iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX); ++ else ++ iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX); ++ ++ if (iRet != size) { ++ WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet); ++ osal_assert(iRet == size); ++ } ++ ++ if (writtenSize) ++ *writtenSize = iRet; ++ ++ return 0; ++ ++} ++ ++INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 type = pWmtCtrlData->au4CtrlData[0]; ++ ++ WMT_INFO_FUNC("flush rx %d queue\n", type); ++ mtk_wcn_stp_flush_rx_queue(type); ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iret; ++ ++/*psm should be disabled before wmt_ic_deinit*/ ++ P_DEV_WMT pDev = &gDevWmt; ++ ++ if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) { ++ WMT_DBG_FUNC("on->off\n"); ++ iret = wmt_plat_pwr_ctrl(FUNC_OFF); ++ } else { ++ WMT_WARN_FUNC("already off\n"); ++ iret = 0; ++ } ++ ++ return iret; ++} ++ ++INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iret; ++ /*psm should be enabled right after wmt_ic_init */ ++ P_DEV_WMT pDev = &gDevWmt; ++ if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) { ++ WMT_WARN_FUNC("already on\n"); ++ iret = 0; ++ } else { ++ WMT_DBG_FUNC("off->on\n"); ++ iret = wmt_plat_pwr_ctrl(FUNC_ON); ++ } ++ ++ return iret; ++} ++ ++INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const UINT8 *pCmdStr) ++{ ++ INT32 waitRet = -1; ++ P_OSAL_SIGNAL pCmdSignal; ++ P_OSAL_EVENT pCmdReq; ++ ++ if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) { ++ WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd); ++ return -1; ++ } ++ ++ /* indicate baud rate change to user space app */ ++#if 0 ++ INIT_COMPLETION(pWmtDev->cmd_comp); ++ pWmtDev->cmd_result = -1; ++ strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); ++ pWmtDev->cCmd[NAME_MAX] = '\0'; ++ wake_up_interruptible(&pWmtDev->cmd_wq); ++#endif ++ ++ pCmdSignal = &pWmtDev->cmdResp; ++ osal_signal_init(pCmdSignal); ++ pCmdSignal->timeoutValue = 2000; ++ osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); ++ pWmtDev->cCmd[NAME_MAX] = '\0'; ++ ++ pCmdReq = &pWmtDev->cmdReq; ++ ++ osal_trigger_event(&pWmtDev->cmdReq); ++ WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr); ++ ++/* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */ ++ waitRet = osal_wait_for_signal_timeout(pCmdSignal); ++ WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet); ++ if (0 == waitRet) { ++ WMT_ERR_FUNC("wait signal timeout\n"); ++ return -2; ++ } ++ ++ WMT_DBG_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult); ++ ++ return pWmtDev->cmdResult; ++} ++ ++INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ wmt_plat_pwr_ctrl(FUNC_RST); ++ return 0; ++} ++ ++INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ wmt_plat_pwr_ctrl(FUNC_STAT); ++ return 0; ++} ++ ++INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet = 0; ++ /* un-register to STP-core for rx */ ++ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL); /* mtk_wcn_stp_register_event_cb */ ++ if (iRet) { ++ WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ /*un-register rxcb to btif */ ++ iRet = mtk_wcn_stp_rxcb_register(NULL); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_unregister fail(%d)\n", iRet); ++ return -2; ++ } ++ ++ iRet = mtk_wcn_stp_close_btif(); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_close_btif fail(%d)\n", iRet); ++ return -3; ++ } ++ osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state); ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet; ++ ++ iRet = mtk_wcn_stp_open_btif(); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_open_btif fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ /*register stp rx call back to btif */ ++ iRet = mtk_wcn_stp_rxcb_register((MTK_WCN_BTIF_RX_CB) mtk_wcn_stp_parser_data); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_register fail(%d)\n", iRet); ++ return -2; ++ } ++ /* register to STP-core for rx */ ++ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb); ++ if (iRet) { ++ WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet); ++ return -3; ++ } ++ ++ osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state); ++ ++#if 0 ++ iRet = mtk_wcn_stp_lpbk_ctrl(1); ++#endif ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet; ++ UINT8 cmdStr[NAME_MAX + 1] = { 0 }; ++ ++ osal_snprintf(cmdStr, NAME_MAX, "srh_patch"); ++ iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); ++ if (iRet) { ++ WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); ++ return -1; ++ } ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ pWmtCtrlData->au4CtrlData[0] = pDev->patchNum; ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ UINT32 downLoadSeq = 0; ++ P_WMT_PATCH_INFO pPatchinfo = NULL; ++ PUINT8 pNbuf = NULL; ++ PUINT8 pAbuf = NULL; ++ ++ downLoadSeq = pWmtCtrlData->au4CtrlData[0]; ++ WMT_DBG_FUNC("download seq is %d\n", downLoadSeq); ++ ++ pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1; ++ pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1]; ++ pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2]; ++ if (pPatchinfo) { ++ osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName)); ++ osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess)); ++ WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1], pAbuf[2], pAbuf[3]); ++ } else { ++ WMT_ERR_FUNC("NULL patchinfo pointer\n"); ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0; ++ ENUM_PALDO_TYPE ept = pWmtCtrlData->au4CtrlData[0]; ++ ENUM_PALDO_OP epo = pWmtCtrlData->au4CtrlData[1]; ++ ++ WMT_DBG_FUNC("ept(%d),epo(%d)\n", ept, epo); ++ iRet = wmt_plat_soc_paldo_ctrl(ept, epo); ++ if (iRet) { ++ if (PMIC_CHIPID_PALDO == ept) { ++ /* special handling for PMIC CHIPID */ ++ pWmtCtrlData->au4CtrlData[2] = iRet; ++ } else { ++ /* for other PA handling */ ++ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0; ++ ++ iRet = mtk_wcn_stp_wakeup_consys(); ++ if (iRet) ++ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value) ++{ ++ INT32 iRet = -1; ++ ++ switch (type) { ++ case WMT_STP_CONF_EN: ++ iRet = mtk_wcn_stp_enable(value); ++ break; ++ ++ case WMT_STP_CONF_RDY: ++ iRet = mtk_wcn_stp_ready(value); ++ break; ++ ++ case WMT_STP_CONF_MODE: ++ mtk_wcn_stp_set_mode(value); ++ iRet = 0; ++ break; ++ ++ default: ++ WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value); ++ break; ++ } ++ return iRet; ++} ++ ++INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ UINT32 type; ++ UINT32 value; ++ ++ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { ++ WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n"); ++ return -1; ++ } ++ ++ type = pWmtCtrlData->au4CtrlData[0]; ++ value = pWmtCtrlData->au4CtrlData[1]; ++ iRet = wmt_ctrl_stp_conf_ex(type, value); ++ ++ if (!iRet) { ++ if (WMT_STP_CONF_EN == type) { ++ if (value) { ++ osal_set_bit(WMT_STAT_STP_EN, &pDev->state); ++ WMT_DBG_FUNC("enable STP\n"); ++ } else { ++ osal_clear_bit(WMT_STAT_STP_EN, &pDev->state); ++ WMT_DBG_FUNC("disable STP\n"); ++ } ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0]; ++ ++ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); ++ if (NULL != gDevWmt.pPatch) ++ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch)); ++ ++ WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); ++ if (patchSeq == gDevWmt.patchNum) { ++ WMT_DBG_FUNC("the %d patch has been download\n", patchSeq); ++ wmt_dev_patch_info_free(); ++ } ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ ++ osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName)); ++ return 0; ++} ++ ++INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); ++ if (NULL != gDevWmt.pNvram) ++ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram)); ++ ++ WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(0x%08x)\n", gDevWmt.pNvram); ++ return 0; ++} ++ ++INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0x0; ++ PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1]; ++ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; ++ ++ osal_firmware *pNvram = NULL; ++ ++ if ((NULL == pFileName) || (NULL == pSize)) { ++ WMT_ERR_FUNC("parameter error, pFileName(0x%08x), pSize(0x%08x)\n", pFileName, pSize); ++ iRet = -1; ++ return iRet; ++ } ++ if (0 == wmt_dev_patch_get(pFileName, &pNvram, 0)) { ++ *ppBuf = (PUINT8) (pNvram)->data; ++ *pSize = (pNvram)->size; ++ gDevWmt.pNvram = pNvram; ++ return 0; ++ } ++ return -1; ++ ++} ++ ++INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT8 *pFullPatchName = NULL; ++ UINT8 *pDefPatchName = NULL; ++ PUINT8 *ppBuf = (PUINT8 *) pWmtCtrlData->au4CtrlData[2]; ++ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3]; ++ ++ osal_firmware *pPatch = NULL; ++ ++ pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1]; ++ WMT_DBG_FUNC("BF get patch, pPatch(0x%08x)\n", pPatch); ++ if ((NULL != pFullPatchName) ++ && (0 == wmt_dev_patch_get(pFullPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { ++ /*get full name patch success */ ++ WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%d)\n", ++ pFullPatchName, (pPatch)->data, (pPatch)->size); ++ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); ++ *ppBuf = (PUINT8) (pPatch)->data; ++ *pSize = (pPatch)->size; ++ gDevWmt.pPatch = pPatch; ++ return 0; ++ } ++ ++ pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ if ((NULL != pDefPatchName) ++ && (0 == wmt_dev_patch_get(pDefPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { ++ WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%d)\n", ++ pDefPatchName, (pPatch)->data, (pPatch)->size); ++ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); ++ /*get full name patch success */ ++ *ppBuf = (PUINT8) (pPatch)->data; ++ *pSize = (pPatch)->size; ++ gDevWmt.pPatch = pPatch; ++ return 0; ++ } ++ return -1; ++ ++} ++ ++/*do not need contol uart because B/G/F send/receive data by BTIF*/ ++#if 0 ++INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ char cmdStr[NAME_MAX + 1] = { 0 }; ++ UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0]; ++ UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1]; ++ ++ WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl); ++ ++ if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) { ++ osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl); ++ iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr); ++ if (iRet) { ++ WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) fail(%d)\n", ++ u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet); ++ } else { ++ WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n", u4Baudrate, u4FlowCtrl); ++ } ++ } else { ++ WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n"); ++ } ++ return iRet; ++} ++#endif ++/*do not need control SDIO because wifi send/receive data by sdio*/ ++#if 0 ++INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0; ++ UINT32 statBit = WMT_STAT_SDIO1_ON; ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0]; ++ ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1]; ++ ++ if ((WMT_SDIO_SLOT_INVALID == sdioSlotNum) ++ || (WMT_SDIO_SLOT_MAX <= sdioSlotNum)) { ++ WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum); ++ return -1; ++ } ++ ++ WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState); ++ ++ if (WMT_SDIO_SLOT_SDIO2 == sdioSlotNum) ++ statBit = WMT_STAT_SDIO2_ON; ++ ++ if (funcState) { ++ if (osal_test_and_set_bit(statBit, &pDev->state)) { ++ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum); ++ /* still return 0 */ ++ iRet = 0; ++ } else { ++ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON); ++ } ++ } else { ++ if (osal_test_and_clear_bit(statBit, &pDev->state)) { ++ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF); ++ } else { ++ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum); ++ /* still return 0 */ ++ iRet = 0; ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ UINT32 statBit = WMT_STAT_SDIO_WIFI_ON; ++ INT32 retry = 10; ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0]; ++ UINT32 u4On = pWmtCtrlData->au4CtrlData[1]; ++ ++ if (WMT_SDIO_FUNC_MAX <= sdioFuncType) { ++ WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType); ++ return -1; ++ } ++ ++ if (WMT_SDIO_FUNC_STP == sdioFuncType) ++ statBit = WMT_STAT_SDIO_STP_ON; ++ ++ if (u4On) { ++ if (osal_test_bit(statBit, &pDev->state)) { ++ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType); ++ iRet = 0; ++ } else { ++ while (retry-- > 0 && iRet != 0) { ++ if (iRet) { ++ /* sleep 150ms before sdio slot ON ready */ ++ osal_sleep_ms(150); ++ } ++ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE); ++ if (HIF_SDIO_ERR_NOT_PROBED == iRet) { ++ /* not probed case, retry */ ++ continue; ++ } else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet) { ++ /* For WiFi, client not reg yet, no need to retry, ++ *WiFi function can work any time when wlan.ko ++ *is insert into system ++ */ ++ iRet = 0; ++ } else { ++ /* other fail cases, stop */ ++ break; ++ } ++ } ++ if (!retry || iRet) { ++ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n", ++ sdioFuncType, iRet, retry); ++ } else { ++ osal_set_bit(statBit, &pDev->state); ++ } ++ } ++ } else { ++ if (osal_test_bit(statBit, &pDev->state)) { ++ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE); ++ if (iRet) ++ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", sdioFuncType, iRet); ++ /*any way, set to OFF state */ ++ osal_clear_bit(statBit, &pDev->state); ++ } else { ++ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType); ++ iRet = 0; ++ } ++ } ++ ++ return iRet; ++} ++#endif ++ ++ ++INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ /* input sanity check is done in wmt_ctrl() */ ++ pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16; ++ pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF; ++ pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF; ++ ++ /* TODO: [FixMe][GeorgeKuo] remove translated ENUM_WMTHWVER_TYPE_T in the future!!! */ ++ /* Only use hw_ver read from hw. */ ++ pDev->eWmtHwVer = (ENUM_WMTHWVER_TYPE_T) (pWmtCtrlData->au4CtrlData[1] & 0xFFFF0000) >> 16; ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT8 *pRomVer = NULL; ++ P_WMT_PATCH pPatch = NULL; ++ UINT32 chipID = 0; ++ ++ chipID = pWmtCtrlData->au4CtrlData[0]; ++ pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]); ++ pPatch = (P_WMT_PATCH) (pWmtCtrlData->au4CtrlData[2]); ++ if (!pRomVer) { ++ WMT_ERR_FUNC("pRomVer null pointer\n"); ++ return -1; ++ } ++ if (!pPatch) { ++ WMT_ERR_FUNC("pPatch null pointer\n"); ++ return -2; ++ } ++ WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer, pPatch->ucDateTime, ++ pPatch->ucPLat); ++ return stp_dbg_set_version_info(chipID, pRomVer, &(pPatch->ucDateTime[0]), &(pPatch->ucPLat[0])); ++} ++ ++static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 cmd = pWmtCtrlData->au4CtrlData[0]; ++ ++ WMT_INFO_FUNC("wmt-ctrl:send native cmd(%d)\n", cmd); ++ wmt_dev_send_cmd_to_daemon(cmd); ++ ++ return 0; ++} ++ ++static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ ++ ENUM_WMTDRV_TYPE_T drv_type; ++ UINT32 reason = 0; ++ ++ drv_type = pWmtCtrlData->au4CtrlData[0]; ++ reason = pWmtCtrlData->au4CtrlData[1]; ++ WMT_WARN_FUNC("wmt-ctrl:drv_type(%d),reason(%d)\n", drv_type, reason); ++ ++ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); ++ wmt_lib_set_host_assert_info(drv_type, reason, 1); ++ ++ iRet = mtk_wcn_stp_wmt_evt_err_trg_assert(); ++ if (iRet) ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ } else { ++ /* maybe assert triggered by stp noack*/ ++ WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n"); ++ } ++ return 0; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 antsel_index = wmt_plat_get_tdm_antsel_index(); ++ ++ if (0 <= antsel_index) ++ pWmtCtrlData->au4CtrlData[0] = antsel_index; ++ else ++ pWmtCtrlData->au4CtrlData[0] = 0xff; ++ ++ WMT_INFO_FUNC("get tdm req antsel index is %d\n", antsel_index); ++ ++ return 0; ++} ++#endif ++ ++static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 ret = -1; ++ UINT32 evt_idx = (UINT32) pWmtCtrlData->au4CtrlData[0]; ++ UINT8 *p_buf = NULL; ++ ++ static UINT8 sleep_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; ++ static UINT8 wakeup_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; ++ static UINT8 hostawake_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; ++ static UINT8 *evt_array[] = { sleep_evt, wakeup_evt, hostawake_evt }; ++ ++ p_buf = evt_array[evt_idx - 1]; ++ ++ WMT_INFO_FUNC("evt index:%d,p_buf:%p\n", evt_idx, p_buf); ++ ++ ret = mtk_wcn_consys_stp_btif_parser_wmt_evt(p_buf, 6); ++ if (ret == 1) { ++ WMT_INFO_FUNC("parser wmt evt from BTIF buf is OK\n"); ++ return 0; ++ } ++ WMT_ERR_FUNC("parser wmt evt from BTIF buf fail(%d)\n", ret); ++ return -1; ++} ++ ++static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData) ++{ ++ INT32 iret; ++ ++ WMT_INFO_FUNC("ctrl GPS_SYNC(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); ++ iret = wmt_plat_gpio_ctrl(PIN_GPS_SYNC, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); ++ ++ if (iret) { ++ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", ++ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX, iret); ++ } ++ ++ return 0; ++} ++ ++static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData) ++{ ++ INT32 iret; ++ ++ WMT_INFO_FUNC("ctrl GPS_LNA(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); ++ iret = wmt_plat_gpio_ctrl(PIN_GPS_LNA, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); ++ ++ if (iret) { ++ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", ++ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret); ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ pWmtCtrlData->au4CtrlData[0] = (SIZE_T) &pDev->rWmtGenConf; ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId); ++ return -1; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c +new file mode 100644 +index 000000000000..d42d572c9292 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c +@@ -0,0 +1,713 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-FUNC]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include "wmt_func.h" ++#include "wmt_lib.h" ++#include "wmt_core.h" ++#include "wmt_exp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if CFG_FUNC_BT_SUPPORT ++ ++static INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_bt_ops = { ++ /* BT subsystem function on/off */ ++ .func_on = wmt_func_bt_on, ++ .func_off = wmt_func_bt_off ++}; ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++ ++static INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_fm_ops = { ++ /* FM subsystem function on/off */ ++ .func_on = wmt_func_fm_on, ++ .func_off = wmt_func_fm_off ++}; ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++ ++static INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_gps_ops = { ++ /* GPS subsystem function on/off */ ++ .func_on = wmt_func_gps_on, ++ .func_off = wmt_func_gps_off ++}; ++ ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++static INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_wifi_ops = { ++ /* Wi-Fi subsystem function on/off */ ++ .func_on = wmt_func_wifi_on, ++ .func_off = wmt_func_wifi_off ++}; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if CFG_FUNC_GPS_SUPPORT ++CMB_PIN_CTRL_REG eediPinOhRegs[] = { ++ { ++ /* pull down ctrl register */ ++ .regAddr = 0x80050020, ++ .regValue = ~(0x1 << 5), ++ .regMask = 0x00000020, ++ }, ++ { ++ /* pull up ctrl register */ ++ .regAddr = 0x80050000, ++ .regValue = 0x1 << 5, ++ .regMask = 0x00000020, ++ }, ++ { ++ /* iomode ctrl register */ ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 0, ++ .regMask = 0x00000007, ++ }, ++ { ++ /* output high/low ctrl register */ ++ .regAddr = 0x80050040, ++ .regValue = 0x1 << 5, ++ .regMask = 0x00000020, ++ } ++ ++}; ++ ++CMB_PIN_CTRL_REG eediPinOlRegs[] = { ++ { ++ .regAddr = 0x80050020, ++ .regValue = 0x1 << 5, ++ .regMask = 0x00000020UL, ++ }, ++ { ++ .regAddr = 0x80050000, ++ .regValue = ~(0x1 << 5), ++ .regMask = 0x00000020, ++ }, ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 0, ++ .regMask = 0x00000007, ++ }, ++ { ++ .regAddr = 0x80050040, ++ .regValue = ~(0x1 << 5), ++ .regMask = 0x00000020, ++ } ++}; ++ ++CMB_PIN_CTRL_REG eedoPinOhRegs[] = { ++ { ++ .regAddr = 0x80050020, ++ .regValue = ~(0x1 << 7), ++ .regMask = 0x00000080UL, ++ }, ++ { ++ .regAddr = 0x80050000, ++ .regValue = 0x1 << 7, ++ .regMask = 0x00000080UL, ++ }, ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 12, ++ .regMask = 0x00007000UL, ++ }, ++ { ++ .regAddr = 0x80050040, ++ .regValue = 0x1 << 7, ++ .regMask = 0x00000080, ++ } ++}; ++ ++CMB_PIN_CTRL_REG eedoPinOlRegs[] = { ++ { ++ .regAddr = 0x80050020, ++ .regValue = 0x1 << 7, ++ .regMask = 0x00000080, ++ }, ++ { ++ .regAddr = 0x80050000, ++ .regValue = ~(0x1 << 7), ++ .regMask = 0x00000080, ++ }, ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 12, ++ .regMask = 0x00007000, ++ }, ++ { ++ .regAddr = 0x80050040, ++ .regValue = ~(0x1 << 7), ++ .regMask = 0x00000080, ++ } ++ ++}; ++ ++CMB_PIN_CTRL_REG gsyncPinOnRegs[] = { ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x3 << 20, ++ .regMask = 0x7 << 20, ++ } ++ ++}; ++ ++CMB_PIN_CTRL_REG gsyncPinOffRegs[] = { ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x0 << 20, ++ .regMask = 0x7 << 20, ++ } ++}; ++ ++/* templete usage for GPIO control */ ++CMB_PIN_CTRL gCmbPinCtrl[3] = { ++ { ++ .pinId = CMB_PIN_EEDI_ID, ++ .regNum = 4, ++ .pFuncOnArray = eediPinOhRegs, ++ .pFuncOffArray = eediPinOlRegs, ++ }, ++ { ++ .pinId = CMB_PIN_EEDO_ID, ++ .regNum = 4, ++ .pFuncOnArray = eedoPinOhRegs, ++ .pFuncOffArray = eedoPinOlRegs, ++ }, ++ { ++ .pinId = CMB_PIN_GSYNC_ID, ++ .regNum = 1, ++ .pFuncOnArray = gsyncPinOnRegs, ++ .pFuncOffArray = gsyncPinOffRegs, ++ } ++}; ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#if CFG_FUNC_BT_SUPPORT ++ ++INT32 _osal_inline_ wmt_func_bt_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ /*only need to send turn BT subsystem wmt command */ ++ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++} ++ ++INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_bt_ctrl(FUNC_ON); */ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_ON; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); ++ return -1; ++ } ++ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_on) failed(%d)\n", iRet); ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ++ /*do coredump when bt on fail */ ++ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); ++ ctrlPa1 = WMTDRV_TYPE_BT; ++ ctrlPa2 = 32; ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); ++ return -2; ++ } ++ osal_set_bit(WMT_BT_ON, &gBtWifiGpsState); ++ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { ++ /* send msg to GPS native for sending de-sense CMD */ ++ ctrlPa1 = 1; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ return 0; ++} ++ ++INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_bt_ctrl(FUNC_OFF); */ ++ INT32 iRet1 = -1; ++ INT32 iRet2 = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ iRet1 = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE); ++ if (iRet1) ++ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_off) failed(%d)\n", iRet1); ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet2 = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ if (iRet2) ++ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl(bt_off) failed(%d)\n", iRet2); ++ ++ if (iRet1 + iRet2) { ++ /*do coredump when bt off fail */ ++ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); ++ ctrlPa1 = WMTDRV_TYPE_BT; ++ ctrlPa2 = 32; ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); ++ return -1; ++ } ++ ++ osal_clear_bit(WMT_BT_ON, &gBtWifiGpsState); ++ if ((!osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for stopping send de-sense CMD */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ return 0; ++} ++ ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++ ++INT32 _osal_inline_ wmt_func_gps_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ /*send turn GPS subsystem wmt command */ ++ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_GPS, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++} ++ ++INT32 wmt_func_gps_pre_ctrl(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf, ENUM_FUNC_STATE funcStatus) ++{ ++ UINT32 i = 0; ++ INT32 iRet = 0; ++ UINT32 regAddr = 0; ++ UINT32 regValue = 0; ++ UINT32 regMask = 0; ++ UINT32 regNum = 0; ++ P_CMB_PIN_CTRL_REG pReg; ++ P_CMB_PIN_CTRL pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; ++ WMT_CTRL_DATA ctrlData; ++ WMT_IC_PIN_ID wmtIcPinId = WMT_IC_PIN_MAX; ++ /* sanity check */ ++ if (FUNC_ON != funcStatus && FUNC_OFF != funcStatus) { ++ WMT_ERR_FUNC("invalid funcStatus(%d)\n", funcStatus); ++ return -1; ++ } ++ /* turn on GPS sync function on both side */ ++ ctrlData.ctrlId = WMT_CTRL_GPS_SYNC_SET; ++ ctrlData.au4CtrlData[0] = (FUNC_ON == funcStatus) ? 1 : 0; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /*we suppose this would never print */ ++ WMT_ERR_FUNC("ctrl GPS_SYNC_SET(%d) fail, ret(%d)\n", funcStatus, iRet); ++ /* TODO:[FixMe][George] error handling? */ ++ return -2; ++ } ++ WMT_INFO_FUNC("ctrl GPS_SYNC_SET(%d) ok\n", funcStatus); ++ ++ ++ if ((NULL == pOps->ic_pin_ctrl) || ++ (0 > pOps->ic_pin_ctrl( ++ WMT_IC_PIN_GSYNC, ++ FUNC_ON == funcStatus ? WMT_IC_PIN_MUX : WMT_IC_PIN_GPIO, ++ 1))) { /*WMT_IC_PIN_GSYNC */ ++ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; ++ regNum = pCmbPinCtrl->regNum; ++ for (i = 0; i < regNum; i++) { ++ if (FUNC_ON == funcStatus) ++ pReg = &pCmbPinCtrl->pFuncOnArray[i]; ++ else ++ pReg = &pCmbPinCtrl->pFuncOffArray[i]; ++ ++ regAddr = pReg->regAddr; ++ regValue = pReg->regValue; ++ regMask = pReg->regMask; ++ ++ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); ++ if (iRet) { ++ WMT_ERR_FUNC("set reg for GPS_SYNC function fail(%d)\n", iRet); ++ /* TODO:[FixMe][Chaozhong] error handling? */ ++ return -2; ++ } ++ ++ } ++ } else { ++ WMT_INFO_FUNC("set reg for GPS_SYNC function okay by chip ic_pin_ctrl\n"); ++ } ++ WMT_INFO_FUNC("ctrl combo chip gps sync function succeed\n"); ++ /* turn on GPS lna ctrl function */ ++ if (NULL != pConf) { ++ if (0 == pConf->wmt_gps_lna_enable) { ++ ++ WMT_INFO_FUNC("host pin used for gps lna\n"); ++ /* host LNA ctrl pin needed */ ++ ctrlData.ctrlId = WMT_CTRL_GPS_LNA_SET; ++ ctrlData.au4CtrlData[0] = FUNC_ON == funcStatus ? 1 : 0; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /*we suppose this would never print */ ++ WMT_ERR_FUNC("ctrl host GPS_LNA output high fail, ret(%d)\n", iRet); ++ /* TODO:[FixMe][Chaozhong] error handling? */ ++ return -3; ++ } ++ WMT_INFO_FUNC("ctrl host gps lna function succeed\n"); ++ } else { ++ WMT_INFO_FUNC("combo chip pin(%s) used for gps lna\n", ++ 0 == pConf->wmt_gps_lna_pin ? "EEDI" : "EEDO"); ++ wmtIcPinId = 0 == pConf->wmt_gps_lna_pin ? WMT_IC_PIN_EEDI : WMT_IC_PIN_EEDO; ++ if ((NULL == pOps->ic_pin_ctrl) || ++ (0 > pOps->ic_pin_ctrl( ++ wmtIcPinId, ++ FUNC_ON == funcStatus ? WMT_IC_PIN_GPIO_HIGH : WMT_IC_PIN_GPIO_LOW, ++ 1))) { /*WMT_IC_PIN_GSYNC */ ++ if (0 == pConf->wmt_gps_lna_pin) { ++ /* EEDI needed */ ++ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDI_ID]; ++ } else if (1 == pConf->wmt_gps_lna_pin) { ++ /* EEDO needed */ ++ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDO_ID]; ++ } ++ regNum = pCmbPinCtrl->regNum; ++ for (i = 0; i < regNum; i++) { ++ if (FUNC_ON == funcStatus) ++ pReg = &pCmbPinCtrl->pFuncOnArray[i]; ++ else ++ pReg = &pCmbPinCtrl->pFuncOffArray[i]; ++ regAddr = pReg->regAddr; ++ regValue = pReg->regValue; ++ regMask = pReg->regMask; ++ ++ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); ++ if (iRet) { ++ WMT_ERR_FUNC("set reg for GPS_LNA function fail(%d)\n", iRet); ++ /* TODO:[FixMe][Chaozhong] error handling? */ ++ return -3; ++ } ++ } ++ WMT_INFO_FUNC("ctrl combo chip gps lna succeed\n"); ++ } else { ++ WMT_INFO_FUNC("set reg for GPS_LNA function okay by chip ic_pin_ctrl\n"); ++ } ++ } ++ } ++ return 0; ++ ++} ++ ++INT32 wmt_func_gps_pre_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_ON); ++} ++ ++INT32 wmt_func_gps_pre_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ ++ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_OFF); ++} ++ ++INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ ++ if (!osal_test_bit(WMT_FM_ON, &gGpsFmState)) { ++ ctrlPa1 = GPS_PALDO; ++ ctrlPa2 = PALDO_ON; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else { ++ WMT_INFO_FUNC("LDO VCN28 has been turn on by FM\n"); ++ } ++ } ++ ++ iRet = wmt_func_gps_pre_on(pOps, pConf); ++ if (0 == iRet) { ++ iRet = wmt_func_gps_ctrl(FUNC_ON); ++ if (!iRet) { ++ osal_set_bit(WMT_GPS_ON, &gBtWifiGpsState); ++ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) ++ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for sending de-sense CMD */ ++ ctrlPa1 = 1; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ ++ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) /* use SOC external LNA */ ++ osal_set_bit(WMT_GPS_ON, &gGpsFmState); ++ } ++ } ++ return iRet; ++} ++ ++INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ iRet = wmt_func_gps_pre_off(pOps, pConf); ++ if (0 == iRet) { ++ iRet = wmt_func_gps_ctrl(FUNC_OFF); ++ if (!iRet) { ++ osal_clear_bit(WMT_GPS_ON, &gBtWifiGpsState); ++ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) ++ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for stop sending de-sense CMD */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ } ++ } ++ ++ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ ++ if (osal_test_bit(WMT_FM_ON, &gGpsFmState)) ++ WMT_INFO_FUNC("FM is still on, do not turn off LDO VCN28\n"); ++ else { ++ ctrlPa1 = GPS_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ ++ osal_clear_bit(WMT_GPS_ON, &gGpsFmState); ++ } ++ ++ return iRet; ++ ++} ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++ ++INT32 _osal_inline_ wmt_func_fm_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ /*only need to send turn FM subsystem wmt command */ ++ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++} ++ ++INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_fm_ctrl(FUNC_ON); */ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ INT32 iRet = -1; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ if (co_clock_type) { ++ if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { ++ ctrlPa1 = FM_PALDO; ++ ctrlPa2 = PALDO_ON; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else { ++ WMT_INFO_FUNC("LDO VCN28 has been turn on by GPS\n"); ++ } ++ } ++ ++ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE); ++ if (!iRet) { ++ if (co_clock_type) ++ osal_set_bit(WMT_FM_ON, &gGpsFmState); ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_fm_ctrl(FUNC_OFF); */ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ INT32 iRet = -1; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE); ++ ++ if (co_clock_type) { ++ if (osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { ++ WMT_INFO_FUNC("GPS is still on, do not turn off LDO VCN28\n"); ++ } else { ++ ctrlPa1 = FM_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ ++ osal_clear_bit(WMT_FM_ON, &gGpsFmState); ++ } ++ ++ return iRet; ++} ++ ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++ ++/*in soc, wmt turn on wifi directly, no not need operate SDIO*/ ++#if 0 ++INT32 wmt_func_wifi_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = WMT_SDIO_FUNC_WIFI; ++ unsigned long ctrlPa2 = (FUNC_ON == funcState) ? 1 : 0; /* turn on Wi-Fi driver */ ++ ++ iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-FUNC: turn on WIFI function fail (%d)", iRet); ++ return -1; ++ } ++ return 0; ++} ++#endif ++ ++INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ int iRet = 0; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ if (NULL != mtk_wcn_wlan_probe) { ++ ++ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan probe\n"); ++ iRet = (*mtk_wcn_wlan_probe) (); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan probe fail(%d)\n", iRet); ++ iRet = -1; ++ } else { ++ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan probe ok\n"); ++ } ++ } else { ++ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_probe\n"); ++ gWifiProbed = 1; ++ iRet = -2; ++ } ++ ++ if (!iRet) { ++ osal_set_bit(WMT_WIFI_ON, &gBtWifiGpsState); ++ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { ++ /* send msg to GPS native for sending de-sense CMD */ ++ ctrlPa1 = 1; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ } ++ return iRet; ++#if 0 ++ return wmt_func_wifi_ctrl(FUNC_ON); ++#endif ++} ++ ++INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ int iRet = 0; ++ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ if (NULL != mtk_wcn_wlan_remove) { ++ ++ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan remove\n"); ++ iRet = (*mtk_wcn_wlan_remove) (); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan remove fail(%d)\n", iRet); ++ iRet = -1; ++ } else { ++ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan remove ok\n"); ++ } ++ } else { ++ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_remove\n"); ++ iRet = -2; ++ } ++ ++ if (!iRet) { ++ osal_clear_bit(WMT_WIFI_ON, &gBtWifiGpsState); ++ if ((!osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for stopping send de-sense CMD */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ } ++ return iRet; ++#if 0 ++ return wmt_func_wifi_ctrl(FUNC_OFF); ++#endif ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c +new file mode 100644 +index 000000000000..c07052bce8e6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c +@@ -0,0 +1,2452 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-IC]" ++#define CFG_IC_SOC 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "wmt_ic.h" ++#include "wmt_core.h" ++#include "wmt_lib.h" ++#include "stp_core.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define DEFAULT_PATCH_FRAG_SIZE (1000) ++#define WMT_PATCH_FRAG_1ST (0x1) ++#define WMT_PATCH_FRAG_MID (0x2) ++#define WMT_PATCH_FRAG_LAST (0x3) ++ ++#define CFG_CHECK_WMT_RESULT (1) ++/* BT Port 2 Feature. this command does not need ++ * after coex command is downconfirmed by LC, ++ */ ++#define CFG_WMT_BT_PORT2 (0) ++ ++#define CFG_SET_OPT_REG (0) ++#define CFG_WMT_I2S_DBGUART_SUPPORT (0) ++#define CFG_SET_OPT_REG_SWLA (0) ++#define CFG_SET_OPT_REG_MCUCLK (0) ++#define CFG_SET_OPT_REG_MCUIRQ (0) ++ ++#define CFG_SUBSYS_COEX_NEED 0 ++ ++#define CFG_WMT_COREDUMP_ENABLE 0 ++ ++#define CFG_WMT_MULTI_PATCH (1) ++ ++#define CFG_WMT_CRYSTAL_TIMING_SET (0) ++ ++#define CFG_WMT_SDIO_DRIVING_SET (0) ++ ++#define CFG_WMT_UART_HIF_USE (0) ++ ++#define CFG_WMT_WIFI_5G_SUPPORT (1) ++ ++#define CFG_WMT_PATCH_DL_OPTM (1) ++#if CFG_WMT_LTE_COEX_HANDLING ++#define CFG_WMT_FILTER_MODE_SETTING (1) ++#else ++#define CFG_WMT_FILTER_MODE_SETTING (0) ++#endif ++#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT (0) ++ ++#define CFG_WMT_POWER_ON_DLM (1) ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static UINT8 gFullPatchName[NAME_MAX + 1]; ++static const WMT_IC_INFO_S *gp_soc_info; ++static WMT_PATCH gp_soc_patch_info; ++static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; ++#if 0 ++static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; ++static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; ++ ++static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; ++static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; ++#endif ++ ++#if CFG_WMT_UART_HIF_USE ++static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; ++static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; ++static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; ++static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; ++static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; ++static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; ++static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; ++#endif ++static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; ++static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_QUERY_STP_EVT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; ++static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; ++static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; ++static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; ++ ++#if CFG_WMT_BT_PORT2 ++static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; ++static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++#endif ++ ++/*soc patial patch address cmd & evt need firmware owner provide*/ ++#if CFG_WMT_MULTI_PATCH ++static UINT8 WMT_PATCH_ADDRESS_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x3c, 0x02, 0x09, 0x02, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0xc4, 0x04, 0x09, 0x02, ++ 0x00, 0x3f, 0x00, 0x01, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++#endif ++ ++/*coex cmd/evt++*/ ++static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; ++static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++#if CFG_SUBSYS_COEX_NEED ++static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, ++ 0x00, 0x02, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA ++}; ++static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, ++ 0x00, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA ++}; ++static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, ++ 0x00, 0x04, ++ 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE ++}; ++static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, ++ 0x00, 0x05, ++ 0xAA, 0xAA, 0xAA, 0xAA, ++ 0xBB, 0xBB, 0xBB, 0xBB ++}; ++static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++#endif ++ ++/*coex cmd/evt--*/ ++static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; ++static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; ++static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; ++static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; ++ ++#if 0 ++static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; ++static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; ++#endif ++ ++#if 0 ++/* to enable dump feature */ ++static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 }; ++static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 }; ++ ++/* to get system stack dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++ ++/* to get task and system stack dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++ ++/* to get bt related memory dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A }; ++static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++#endif ++/* to get full dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; ++static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_CORE_START_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x1, 0x00, 0x01 }; ++static UINT8 WMT_CORE_START_RF_CALIBRATION_EVT[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x01 }; ++ ++#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) ++static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x78, 0x00, 0x05, 0x80 /*addr:0x80050078 */ ++ , 0x00, 0x00, 0x11, 0x01 /*value:0x11010000 */ ++ , 0x00, 0x00, 0x77, 0x07 /*mask:0x07770000 */ ++}; ++ ++static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++ ++static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x74, 0x00, 0x05, 0x80 /*addr:0x80050074 */ ++ , 0x44, 0x44, 0x00, 0x00 /*value:0x11010000 */ ++ , 0x77, 0x77, 0x00, 0x00 /*mask:0x07770000 */ ++}; ++ ++static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++ ++static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0xA0, 0x00, 0x05, 0x80 /*addr:0x80050074 */ ++ , 0x04, 0x00, 0x00, 0x00 /*value:0x11010000 */ ++ , 0x04, 0x00, 0x00, 0x00 /*mask:0x07770000 */ ++}; ++ ++static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++#endif ++ ++#if !(CFG_IC_SOC) /* For MT6628 no need to set ALLEINT registers, done in f/w */ ++/* enable all interrupt */ ++static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ ++ , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ ++ , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ ++}; ++ ++static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++ ++#endif ++ ++#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ ++static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++ , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ ++ , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ ++ , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ ++ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ ++ , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ ++ , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ ++}; ++ ++static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++}; ++#endif ++ ++#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ ++static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 4 registers */ ++ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ ++ , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ ++ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ ++ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ ++ , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ ++ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ ++ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ ++ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ ++ , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ ++ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ ++ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ ++ , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ ++}; ++ ++static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /* S: 0 */ ++ , 0x00 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 4 registers */ ++}; ++#endif ++ ++#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ ++static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++ , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ ++ , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ ++ , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ ++ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ ++ , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ ++ , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ ++}; ++ ++static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++}; ++#endif ++ ++#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ ++#if 1 /* Ray */ ++static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 4 registers */ ++ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ ++ , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ ++ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ ++ /* cirq_int_n */ ++ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ ++ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ ++ , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ ++ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ ++ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ ++ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ ++ /* 1. ARM irq_b, monitor flag 0 */ ++ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ ++ , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ ++ , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ ++}; ++ ++static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /* S: 0 */ ++ , 0x00 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 5 registers */ ++}; ++#elif 0 /* KC */ ++static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x05 /* 5 registers */ ++ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ ++ , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ ++ , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ ++ /* 1. ARM irq_b, monitor flag 0 */ ++ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ ++ , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ ++ , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ ++ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ ++ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ ++ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ ++ /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ ++ , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ ++ , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ ++ , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ ++ , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ ++ , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ ++ , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ ++}; ++ ++static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /* S: 0 */ ++ , 0x00 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x05 /* 5 registers */ ++}; ++#endif ++#endif ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; ++static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; ++ ++static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; ++#endif ++ ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++static UINT8 WMT_GET_EFUSE_VCN33_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x04, 0x00 }; ++static UINT8 WMT_GET_EFUSE_VCN33_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x04, 0x00 }; ++#endif ++ ++/* set sdio driving */ ++#if CFG_WMT_SDIO_DRIVING_SET ++static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ ++ , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ ++ , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ ++}; ++ ++static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++#endif ++ ++#if CFG_WMT_WIFI_5G_SUPPORT ++static UINT8 WMT_GET_SOC_ADIE_CHIPID_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; ++static UINT8 WMT_GET_SOC_ADIE_CHIPID_EVT[] = { ++ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, ++ 0x00, 0x00, 0x00, 0x00, 0x00 ++}; ++static UINT8 WMT_GET_SOC_6625_L_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x20, 0x01 }; ++static UINT8 WMT_GET_SOC_6625_L_EVT[] = { ++ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x20, ++ 0x01, 0x00, 0x00, 0x00, 0x00 ++}; ++#endif ++ ++#if CFG_WMT_PATCH_DL_OPTM ++static UINT8 WMT_SET_MCU_CLK_EN_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x34, 0x03, 0x00, 0x80, ++ 0x00, 0x00, 0x01, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_EN_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_SET_MCU_CLK_138_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, ++ 0x59, 0x4d, 0x84, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_138_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_SET_MCU_CLK_26_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, ++ 0x00, 0x4d, 0x84, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_26_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_SET_MCU_CLK_DIS_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x34, 0x03, 0x00, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_DIS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++/*only for 6797,enable high clock frequency*/ ++/*CLK EN*/ ++static UINT8 WMT_SET_MCU_CLK_EN_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x10, ++ 0x00, 0x00, 0x00, 0x10 ++}; ++/*RATIO SET*/ ++static UINT8 WMT_SET_MCU_RATIO_SET_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, ++ 0xc0, 0x00, 0x00, 0x00 ++}; ++/*DIV SET*/ ++static UINT8 WMT_SET_MCU_DIV_SET_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x18, 0x11, 0x02, 0x80, 0x07, 0x00, 0x00, 0x00, ++ 0x3f, 0x00, 0x00, 0x00 ++}; ++/*HCLK SET*/ ++static UINT8 WMT_SET_MCU_HCLK_SET_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x00, 0x11, 0x02, 0x81, 0x04, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x00, 0x00 ++}; ++ ++/*Change clock to 26MHz*/ ++/*HCLK DIS*/ ++static UINT8 WMT_SET_MCU_HCLK_DIS_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x00, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x00, 0x00 ++}; ++/*RATIO DIS*/ ++static UINT8 WMT_SET_MCU_RATIO_DIS_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, ++ 0xc0, 0x00, 0x00, 0x00 ++}; ++/*CLK DIS*/ ++static UINT8 WMT_SET_MCU_CLK_DIS_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x10 ++}; ++ ++static UINT8 WMT_SET_MCU_CLK_EVT_6797[] = { ++ 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 ++}; ++ ++#endif ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = {0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00}; ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, ++ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, ++ 0x01, 0x0e, 0x0e, 0x0e, 0x00, 0x0a, 0x0c, 0x0e, ++ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, ++ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xd4, ++ 0x09, 0xe3, 0x09, 0x5a, 0x0a, 0x14, 0x09, 0x2d, ++ 0x09, 0x46, 0x09, 0x60, 0x09, 0xd3, 0x09, 0xe2, ++ 0x09, 0x59, 0x0a, 0x8B, 0x0a}; ++static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; ++static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; ++ ++#if 0 ++static UINT8 WMT_COEX_SPLIT_FILTER_CMD_TEST[] = { ++ 0x01, 0x10, 0x19, 0x00, 0x0F, 0x00, 0x00, 0x00, ++ 0x00, 0x6c, 0x09, 0x8a, 0x09, 0x8a, 0x09, 0x9e, ++ 0x09, 0x01, 0x07, 0x07, 0x0b, 0x07, 0x07, 0x00, ++ 0x32, 0x27, 0x4e, 0x27, 0x32 ++}; ++ ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x07, 0x07, 0x07, 0x54, 0x54, 0x00, 0x00, ++ 0x00, 0x50, 0x50, 0x50, 0x54, 0x54, 0x39, 0x39, ++ 0x39, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x01, 0x01, ++ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x0a, ++ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00 ++}; ++ ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, ++ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, ++ 0x09, 0xf6, 0x09, 0x0f, 0xaf, 0x14, 0x09, 0x2d, ++ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, ++ 0x09, 0x0d, 0x0a, 0x27, 0x0a ++}; ++static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; ++static UINT8 WMT_COEX_EXT_COMPONENT_CMD_TEST[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x7f, 0x03 }; ++#endif ++ ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_0[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, ++ 0x00, 0x63, 0x63, 0x63, 0x63, 0x3c, 0x3c, 0x3c, ++ 0x3c, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, ++ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, 0x0b, ++ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00 ++}; ++ ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, ++ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, ++ 0x09, 0xf6, 0x09, 0x0f, 0x0a, 0x14, 0x09, 0x2d, ++ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, ++ 0x09, 0x0d, 0x0a, 0x27, 0x0a ++}; ++static UINT8 WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x14, 0x00 }; ++static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; ++static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_6752[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, ++ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, ++ 0x01, 0x0E, 0x0E, 0x0E, 0x00, 0x0A, 0x0C, 0x0E, ++ 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00 ++}; ++ ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xFC, 0x08, 0x15, ++ 0x09, 0x2E, 0x09, 0x47, 0x09, 0xC4, 0x09, 0xD4, ++ 0x09, 0xE3, 0x09, 0x5A, 0x0A, 0x14, 0x09, 0x2D, ++ 0x09, 0x46, 0x09, 0x60, 0x09, 0xD3, 0x09, 0xE2, ++ 0x09, 0x59, 0x0A, 0x8B, 0x0A ++}; ++#endif ++ ++#if CFG_WMT_POWER_ON_DLM ++static UINT8 WMT_POWER_CTRL_DLM_CMD1[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x60, 0x00, 0x10, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x0f, 0x00, 0x00 ++}; ++ ++static UINT8 WMT_POWER_CTRL_DLM_CMD2[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x60, 0x00, 0x10, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xf0, 0x00, 0x00, 0x00 ++}; ++ ++static UINT8 WMT_POWER_CTRL_DLM_CMD3[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x60, 0x00, 0x10, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x08, 0x00, 0x00, 0x00 ++}; ++static UINT8 WMT_POWER_CTRL_DLM_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++#endif ++ ++#if (!CFG_IC_SOC) ++ ++/* stp sdio init scripts */ ++static struct init_script init_table_1_1[] = { ++ /* table_1_1 is only applied to common SDIO interface */ ++ INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), ++ /* applied to MT6628 ? */ ++ INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), ++}; ++ ++#endif ++ ++static struct init_script init_table_1_2[] = { ++ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), ++}; ++ ++#if CFG_WMT_UART_HIF_USE ++static struct init_script init_table_2[] = { ++ INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), ++}; ++#endif ++ ++static struct init_script init_table_3[] = { ++ INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), ++#if CFG_WMT_BT_PORT2 ++ INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), ++#endif ++}; ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static struct init_script set_crystal_timing_script[] = { ++ INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, "set crystal trim value"), ++}; ++ ++static struct init_script get_crystal_timing_script[] = { ++ INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, "get crystal trim value"), ++}; ++#endif ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++static struct init_script get_efuse_vcn33_script[] = { ++ INIT_CMD(WMT_GET_EFUSE_VCN33_CMD, WMT_GET_EFUSE_VCN33_EVT, "get efuse vcn33 value"), ++}; ++#endif ++ ++static struct init_script init_table_4[] = { ++ INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), ++}; ++ ++static struct init_script init_table_5[] = { ++ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT, "query stp"), ++}; ++ ++static struct init_script init_table_5_1[] = { ++ INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), ++}; ++ ++static struct init_script init_table_6[] = { ++ INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), ++}; ++ ++static struct init_script calibration_table[] = { ++ INIT_CMD(WMT_CORE_START_RF_CALIBRATION_CMD, WMT_CORE_START_RF_CALIBRATION_EVT, "start RF calibration data"), ++}; ++ ++#if CFG_WMT_PATCH_DL_OPTM ++static struct init_script set_mcuclk_table_1[] = { ++ INIT_CMD(WMT_SET_MCU_CLK_EN_CMD, WMT_SET_MCU_CLK_EN_EVT, "enable set mcu clk"), ++ INIT_CMD(WMT_SET_MCU_CLK_138_CMD, WMT_SET_MCU_CLK_138_EVT, "set mcu clk to 138.67MH"), ++}; ++ ++static struct init_script set_mcuclk_table_2[] = { ++ INIT_CMD(WMT_SET_MCU_CLK_26_CMD, WMT_SET_MCU_CLK_26_EVT, "set mcu clk to 26MH"), ++ INIT_CMD(WMT_SET_MCU_CLK_DIS_CMD, WMT_SET_MCU_CLK_DIS_EVT, "disable set mcu clk"), ++}; ++ ++static struct init_script set_mcuclk_table_3[] = { ++ INIT_CMD(WMT_SET_MCU_CLK_EN_6797, WMT_SET_MCU_CLK_EVT_6797, "enable set mcu clk"), ++ INIT_CMD(WMT_SET_MCU_RATIO_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu ratio set"), ++ INIT_CMD(WMT_SET_MCU_DIV_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu div set"), ++ INIT_CMD(WMT_SET_MCU_HCLK_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "set mcu clk to hclk"), ++}; ++static struct init_script set_mcuclk_table_4[] = { ++ INIT_CMD(WMT_SET_MCU_HCLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu hclk"), ++ INIT_CMD(WMT_SET_MCU_RATIO_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu ratio set"), ++ INIT_CMD(WMT_SET_MCU_CLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu clk set"), ++}; ++ ++#endif ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static struct init_script set_wifi_lte_coex_table_1[] = { ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), ++ INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"), ++}; ++ ++static struct init_script set_wifi_lte_coex_table_2[] = { ++ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), ++ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), ++ INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), ++}; ++ ++static struct init_script set_wifi_lte_coex_table_0[] = { ++#if 0 ++ INIT_CMD(WMT_COEX_SPLIT_FILTER_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex split filter"), ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), ++ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte channel unsafe"), ++ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi coex ext component"), ++#endif ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte coex filter spec"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte freq idx"), ++}; ++ ++static struct init_script get_tdm_req_antsel_num_table[] = { ++ INIT_CMD(WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD, WMT_COEX_SPLIT_MODE_EVT, "get tdm req antsel num"), ++}; ++#endif ++ ++#if CFG_SET_OPT_REG ++static struct init_script set_registers[] = { ++ /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ ++ /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ ++#if CFG_WMT_I2S_DBGUART_SUPPORT ++ INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), ++#endif ++#if CFG_SET_OPT_REG_SWLA ++ INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), ++#endif ++#if CFG_SET_OPT_REG_MCUCLK ++ INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), ++#endif ++#if CFG_SET_OPT_REG_MCUIRQ ++ INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), ++#endif ++}; ++#endif ++ ++static struct init_script coex_table[] = { ++ INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), ++ ++#if CFG_SUBSYS_COEX_NEED ++/* no need in MT6628 */ ++ INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), ++ INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), ++ INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), ++ INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), ++#endif ++}; ++ ++static struct init_script osc_type_table[] = { ++ INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), ++}; ++ ++#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) ++static struct init_script merge_pcm_table[] = { ++ INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"), ++ INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"), ++ INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"), ++}; ++#endif ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++static struct init_script sdio_driving_table[] = { ++ INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), ++}; ++#endif ++ ++#if CFG_WMT_POWER_ON_DLM ++static struct init_script wmt_power_on_dlm_table[] = { ++ INIT_CMD(WMT_POWER_CTRL_DLM_CMD1, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd1"), ++ INIT_CMD(WMT_POWER_CTRL_DLM_CMD2, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd2"), ++ INIT_CMD(WMT_POWER_CTRL_DLM_CMD3, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd3") ++}; ++#endif ++ ++/* SOC Chip Version and Info Table */ ++static const WMT_IC_INFO_S mtk_wcn_soc_info_table[] = { ++ { ++ .u4HwVer = 0x8A00, ++ .cChipName = WMT_IC_NAME_DEFAULT, ++ .cChipVersion = WMT_IC_VER_E1, ++ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, ++ /* need to refine? */ ++ .eWmtHwVer = WMTHWVER_E1, ++ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, ++ .bPsmSupport = MTK_WCN_BOOL_TRUE, ++ }, ++ { ++ .u4HwVer = 0x8A01, ++ .cChipName = WMT_IC_NAME_DEFAULT, ++ .cChipVersion = WMT_IC_VER_E2, ++ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, ++ .eWmtHwVer = WMTHWVER_E2, ++ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, ++ .bPsmSupport = MTK_WCN_BOOL_TRUE, ++ }, ++ { ++ .u4HwVer = 0x8B01, ++ .cChipName = WMT_IC_NAME_DEFAULT, ++ .cChipVersion = WMT_IC_VER_E3, ++ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, ++ .eWmtHwVer = WMTHWVER_E3, ++ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, ++ .bPsmSupport = MTK_WCN_BOOL_TRUE, ++ } ++}; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf); ++ ++static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); ++ ++static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); ++ ++static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); ++ ++static INT32 mtk_wcn_soc_ver_check(VOID); ++ ++static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver); ++ ++static INT32 wmt_stp_init_coex(VOID); ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static INT32 wmt_stp_wifi_lte_coex(VOID); ++#endif ++ ++#if CFG_WMT_MULTI_PATCH ++static INT32 mtk_wcn_soc_patch_dwn(UINT32 index); ++static INT32 mtk_wcn_soc_patch_info_prepare(VOID); ++#else ++static INT32 mtk_wcn_soc_patch_dwn(VOID); ++#endif ++ ++static INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on); ++static WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID); ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static INT32 mtk_wcn_soc_crystal_triming_set(VOID); ++#endif ++ ++static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID); ++ ++static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID); ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++static INT32 mtk_wcn_soc_set_sdio_driving(void); ++#endif ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* SOC Operation Function Table */ ++WMT_IC_OPS wmt_ic_ops_soc = { ++ .icId = 0x0000, /* soc may have mt6572/82/71/83,but they have the same sw init flow */ ++ .sw_init = mtk_wcn_soc_sw_init, ++ .sw_deinit = mtk_wcn_soc_sw_deinit, ++ .ic_pin_ctrl = mtk_wcn_soc_pin_ctrl, ++ .ic_ver_check = mtk_wcn_soc_ver_check, ++ .co_clock_ctrl = mtk_wcn_soc_co_clock_ctrl, ++ .is_quick_sleep = mtk_wcn_soc_quick_sleep_flag_get, ++ .is_aee_dump_support = mtk_wcn_soc_aee_dump_flag_get, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf) ++{ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ UINT32 hw_ver; ++ WMT_CTRL_DATA ctrlData; ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++ UINT32 efuse_d3_vcn33 = 2; /*default voltage is 3.5V*/ ++#endif ++#if CFG_WMT_MULTI_PATCH ++ UINT32 patch_num = 0; ++ UINT32 patch_index = 0; ++#endif ++#if CFG_WMT_WIFI_5G_SUPPORT ++ UINT32 dDieChipid = 0; ++ UINT32 aDieChipid = 0; ++ UINT8 evtbuf[20]; ++ UINT32 u4Res; ++ UINT32 pmicChipid = 0; ++#endif ++ WMT_DBG_FUNC(" start\n"); ++ ++ osal_assert(NULL != gp_soc_info); ++ if ((NULL == gp_soc_info) ++ || (NULL == pWmtHifConf) ++ ) { ++ WMT_ERR_FUNC("null pointers: gp_soc_info(0x%p), pWmtHifConf(0x%p)\n", gp_soc_info, pWmtHifConf); ++ return -1; ++ } ++ ++ hw_ver = gp_soc_info->u4HwVer; ++ ++ /* 4 <3.2> start init for BTIF */ ++ if (WMT_HIF_BTIF == pWmtHifConf->hifType) { ++ /* 1. Query chip STP default options (TEST-ONLY) */ ++ /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ ++ iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); ++ osal_assert(0); ++ return -2; ++ } ++ /* 2. Set chip STP options */ ++ iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); ++ return -3; ++ } ++ ++ /* 3. Enable host full mode */ ++ ctrlPa1 = WMT_STP_CONF_MODE; ++ ctrlPa2 = MTKSTP_BTIF_FULL_MODE; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 1; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("enable host STP-BTIF-FULL mode fail(%d)\n", iRet); ++ return -4; ++ } ++ WMT_DBG_FUNC("enable host STP-BTIF-FULL mode\n"); ++ /*4. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ ++ osal_sleep_ms(10); ++ /* 5. Query chip STP options (TEST-ONLY) */ ++ iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); ++ return -5; ++ } ++ } ++#if CFG_WMT_POWER_ON_DLM ++ iRet = wmt_core_init_script(wmt_power_on_dlm_table, osal_array_size(wmt_power_on_dlm_table)); ++ if (iRet) ++ WMT_ERR_FUNC("wmt_power_on_dlm_table fail(%d)\n", iRet); ++ WMT_DBG_FUNC("wmt_power_on_dlm_table ok\n"); ++#endif ++ /* 6. download patch */ ++#if CFG_WMT_MULTI_PATCH ++ /* 6.1 Let launcher to search patch info */ ++ iRet = mtk_wcn_soc_patch_info_prepare(); ++ if (iRet) { ++ WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); ++ return -6; ++ } ++ ++ /* 6.2 Read patch number */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); ++ patch_num = ctrlPa1; ++ WMT_DBG_FUNC("patch total num = [%d]\n", patch_num); ++ ++#if CFG_WMT_PATCH_DL_OPTM ++ if (0x0279 == wmt_ic_ops_soc.icId) { ++ iRet = wmt_core_init_script(set_mcuclk_table_3, osal_array_size(set_mcuclk_table_3)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_3 fail(%d)\n", iRet); ++ } else { ++ iRet = wmt_core_init_script(set_mcuclk_table_1, osal_array_size(set_mcuclk_table_1)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_1 fail(%d)\n", iRet); ++ } ++#endif ++ /* 6.3 Multi-patch Patch download */ ++ for (patch_index = 0; patch_index < patch_num; patch_index++) { ++ iRet = mtk_wcn_soc_patch_dwn(patch_index); ++ if (iRet) { ++ WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); ++ return -7; ++ } ++ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); ++ return -8; ++ } ++ } ++ ++#if CFG_WMT_PATCH_DL_OPTM ++ if (0x0279 == wmt_ic_ops_soc.icId) { ++ iRet = wmt_core_init_script(set_mcuclk_table_4, osal_array_size(set_mcuclk_table_4)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_4 fail(%d)\n", iRet); ++ } else { ++ iRet = wmt_core_init_script(set_mcuclk_table_2, osal_array_size(set_mcuclk_table_2)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_2 fail(%d)\n", iRet); ++ } ++#endif ++ ++#else ++ /* 6.3 Patch download */ ++ iRet = mtk_wcn_soc_patch_dwn(); ++ /* If patch download fail, we just ignore this error and let chip init process goes on */ ++ if (iRet) ++ WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); ++ ++ /* 6.4. WMT Reset command */ ++ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); ++ return -8; ++ } ++#endif ++ ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++ /*get CrystalTiming value before set it */ ++ iRet = wmt_core_tx(get_efuse_vcn33_script[0].cmd, get_efuse_vcn33_script[0].cmdSz, &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != get_efuse_vcn33_script[0].cmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", ++ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].cmdSz); ++ } ++ /* EVENT BUF */ ++ osal_memset(get_efuse_vcn33_script[0].evt, 0, get_efuse_vcn33_script[0].evtSz); ++ iRet = wmt_core_rx(get_efuse_vcn33_script[0].evt, get_efuse_vcn33_script[0].evtSz, &u4Res); ++ if (iRet || (u4Res != get_efuse_vcn33_script[0].evtSz)) { ++ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", ++ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].evtSz); ++ mtk_wcn_stp_dbg_dump_package(); ++ } ++ efuse_d3_vcn33 = WMT_GET_EFUSE_VCN33_EVT[5] & 0x03; ++ WMT_INFO_FUNC("Read efuse to set PMIC voltage:(%d)\n", efuse_d3_vcn33); ++ wmt_set_pmic_voltage(efuse_d3_vcn33); ++#endif ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++ if ((0x6580 == wmt_ic_ops_soc.icId) || ++ (0x8163 == wmt_ic_ops_soc.icId) || ++ (0x6752 == wmt_ic_ops_soc.icId) || ++ (0x6582 == wmt_ic_ops_soc.icId) || ++ (0x6592 == wmt_ic_ops_soc.icId) || ++ (0x0279 == wmt_ic_ops_soc.icId) || ++ (0x0326 == wmt_ic_ops_soc.icId) || ++ (0x0321 == wmt_ic_ops_soc.icId) || (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { ++ wmt_stp_wifi_lte_coex(); ++ WMT_DBG_FUNC("wmt_stp_wifi_lte_coex done!\n"); ++ } ++ if ((0x6582 == wmt_ic_ops_soc.icId) || (0x6592 == wmt_ic_ops_soc.icId)) { ++ /*get gpio tdm req antsel number */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_GET_TDM_REQ_ANTSEL, &ctrlPa1, &ctrlPa2); ++ WMT_INFO_FUNC("get GPIO TDM REQ ANTSEL number(%d)\n", ctrlPa1); ++ /*set gpio tdm req antsel number to firmware */ ++ WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[5] = ctrlPa1; ++ iRet = wmt_core_init_script(get_tdm_req_antsel_num_table, ++ osal_array_size(get_tdm_req_antsel_num_table)); ++ if (iRet) ++ WMT_ERR_FUNC("get_tdm_req_antsel_num_table fail(%d)\n", iRet); ++ } ++#endif ++ /* 7. start RF calibration data */ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_ON; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WIFI_PALDO; ++ ctrlPa2 = PALDO_ON; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ++ iRet = wmt_core_init_script(calibration_table, osal_array_size(calibration_table)); ++ if (iRet) { ++ /* pwrap_read(0x0210,&ctrlPa1); */ ++ /* pwrap_read(0x0212,&ctrlPa2); */ ++ WMT_ERR_FUNC("power status: 210:(%d),212:(%d)!\n", ctrlPa1, ctrlPa2); ++ WMT_ERR_FUNC("calibration_table fail(%d)\n", iRet); ++ return -9; ++ } ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WIFI_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ++ iRet = wmt_stp_init_coex(); ++ if (iRet) { ++ WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); ++ return -10; ++ } ++ WMT_DBG_FUNC("init_coex ok\n"); ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++ mtk_wcn_soc_crystal_triming_set(); ++#endif ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++ mtk_wcn_soc_set_sdio_driving(); ++#endif ++ ++ if (WMT_CO_CLOCK_EN == mtk_wcn_soc_co_clock_get()) { ++ WMT_INFO_FUNC("co-clock enabled.\n"); ++ ++ iRet = wmt_core_init_script(osc_type_table, osal_array_size(osc_type_table)); ++ if (iRet) { ++ WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); ++ return -11; ++ } ++ } else { ++ WMT_WARN_FUNC("co-clock disabled.\n"); ++ } ++#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) ++ iRet = wmt_core_init_script(merge_pcm_table, osal_array_size(merge_pcm_table)); ++ if (iRet) { ++ WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); ++ return -12; ++ } ++#endif ++ ++ /* 15. Set FM strap */ ++ WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; ++ WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; ++ iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", pWmtHifConf->au4StrapConf[0], iRet); ++ return -13; ++ } ++ WMT_DBG_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); ++ ++#if CFG_SET_OPT_REG /*set registers */ ++ iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); ++ if (iRet) { ++ WMT_ERR_FUNC("set_registers fail(%d)", iRet); ++ return -14; ++ } ++#endif ++ ++#if CFG_WMT_COREDUMP_ENABLE ++ /*Open Core Dump Function @QC begin */ ++ mtk_wcn_stp_coredump_flag_ctrl(1); ++#endif ++ if (0 != mtk_wcn_stp_coredump_flag_get()) { ++ iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); ++ return -15; ++ } ++ WMT_DBG_FUNC("enable soc_consys firmware coredump\n"); ++ } else { ++ WMT_DBG_FUNC("disable soc_consys firmware coredump\n"); ++ } ++ ++#if CFG_WMT_WIFI_5G_SUPPORT ++ dDieChipid = wmt_ic_ops_soc.icId; ++ WMT_DBG_FUNC("current SOC chipid is 0x%x\n", dDieChipid); ++ if (0x6592 == dDieChipid) { ++ /* read A die chipid by wmt cmd */ ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_GET_SOC_ADIE_CHIPID_CMD[0], sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); ++ return -16; ++ } ++ osal_memset(evtbuf, 0, sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); ++ return -17; ++ } ++ ++ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); ++ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); ++ ++ if (0x6625 == aDieChipid) { ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_GET_SOC_6625_L_CMD[0], sizeof(WMT_GET_SOC_6625_L_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_CMD))) ++ WMT_ERR_FUNC("wmt_core:read A die efuse CMD fail(%d),size(%d)\n", iRet, u4Res); ++ osal_memset(evtbuf, 0, sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_6625_L_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_EVT))) ++ WMT_ERR_FUNC("wmt_core:read A die efuse EVT fail(%d),size(%d)\n", iRet, u4Res); ++ ++ WMT_INFO_FUNC("read SOC Adie Efuse(0x120) value:0x%2x,0x%2x,0x%2x,0x%2x -> %s\n", ++ evtbuf[u4Res - 4], evtbuf[u4Res - 3], evtbuf[u4Res - 2], evtbuf[u4Res - 1], ++ evtbuf[u4Res - 2] == 0x31 ? "MT6625L" : "MT6625"); ++ } ++ /* get PMIC chipid */ ++ ++ ctrlData.ctrlId = WMT_CTRL_SOC_PALDO_CTRL; ++ ctrlData.au4CtrlData[0] = PMIC_CHIPID_PALDO; ++ ctrlData.au4CtrlData[1] = 0; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet < 0) { ++ WMT_ERR_FUNC("wmt_core: read PMIC chipid fail(%d)\n", iRet); ++ return -18; ++ } ++ pmicChipid = ctrlData.au4CtrlData[2]; ++ WMT_INFO_FUNC("current PMIC chipid(0x%x)\n", pmicChipid); ++ ++ /* MT6625 & MT6322, write 1 to 0x0414[12] */ ++ /* MT6625 & MT6323, assert */ ++ /* MT6627 & (MT6322 or MT6323),write 0 to 0x0414[12] */ ++ ++ switch (aDieChipid) { ++ case 0x6625: ++ if (0x6322 == pmicChipid) { ++ WMT_INFO_FUNC("wmt-core:enable wifi 5G support\n"); ++ ctrlPa1 = WIFI_5G_PALDO; ++ ctrlPa2 = PALDO_ON; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else if (0x6323 == pmicChipid) { ++ osal_assert(0); ++ } else { ++ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); ++ } ++ break; ++ case 0x6627: ++ if ((0x6322 == pmicChipid) || (0x6323 == pmicChipid)) { ++ WMT_INFO_FUNC("wmt-core: disable wifi 5G support\n"); ++ ctrlPa1 = WIFI_5G_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else { ++ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); ++ } ++ break; ++ default: ++ WMT_WARN_FUNC("wmt-core: unknown A die chipid(0x%x)\n", aDieChipid); ++ break; ++ } ++ } ++#endif ++ ++#if 1 ++ ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; ++ ctrlData.au4CtrlData[0] = wmt_ic_ops_soc.icId; ++ ctrlData.au4CtrlData[1] = (SIZE_T) gp_soc_info->cChipVersion; ++ ctrlData.au4CtrlData[2] = (SIZE_T) &gp_soc_patch_info; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); ++ return -19; ++ } ++#endif ++ ++#if CFG_WMT_PS_SUPPORT ++ osal_assert(NULL != gp_soc_info); ++ if (NULL != gp_soc_info) { ++ if (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport) ++ wmt_lib_ps_enable(); ++ else ++ wmt_lib_ps_disable(); ++ } ++#endif ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) ++{ ++ WMT_DBG_FUNC(" start\n"); ++ ++#if CFG_WMT_PS_SUPPORT ++ osal_assert(NULL != gp_soc_info); ++ if ((NULL != gp_soc_info) ++ && (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport)) { ++ wmt_lib_ps_disable(); ++ } ++#endif ++ ++ gp_soc_info = NULL; ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) ++{ ++ INT32 ret = -1; ++ UINT32 val; ++ ++ if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { ++ WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); ++#if 0 ++ switch (state) { ++ case WMT_IC_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ val = 0x00000770; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_1: ++ /* BT_PCM_ON & FM line in/out */ ++ val = 0x00000700; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_2: ++ /* BT_PCM_OFF & FM I2S */ ++ val = 0x00000710; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ default: ++ WMT_ERR_FUNC("unsupported state (%d)\n", state); ++ ret = -1; ++ break; ++ } ++#else ++ WMT_WARN_FUNC("TBD!!"); ++ ret = 0; ++#endif ++ } else { ++ /*PCM & I2S separate */ ++ WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); ++#if 0 ++ switch (state) { ++ case WMT_IC_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ val = 0x00000770; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_1: ++ /* BT_PCM_ON & FM line in/out */ ++ val = 0x00000700; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_2: ++ /* BT_PCM_OFF & FM I2S */ ++ val = 0x00000070; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ ++ break; ++ case WMT_IC_AIF_3: ++ val = 0x00000000; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ ++ break; ++ default: ++ WMT_ERR_FUNC("unsupported state (%d)\n", state); ++ ret = -1; ++ break; ++ } ++#else ++ switch (state) { ++ case WMT_IC_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ ret = 0; ++ break; ++ case WMT_IC_AIF_1: ++ /* BT_PCM_ON & FM line in/out */ ++ ret = 0; ++ break; ++ ++ case WMT_IC_AIF_2: ++ /* BT_PCM_OFF & FM I2S */ ++ val = 0x01110000; ++ ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); ++ ++ break; ++ case WMT_IC_AIF_3: ++ ret = 0; ++ break; ++ ++ default: ++ WMT_ERR_FUNC("unsupported state (%d)\n", state); ++ ret = -1; ++ break; ++ } ++#endif ++ } ++ ++ if (!ret) ++ WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); ++ WMT_INFO_FUNC("new state(%d) ok\n", state); ++ ++ return ret; ++} ++ ++static INT32 mtk_wcn_soc_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) ++{ ++ INT32 iRet = -1; ++ UINT32 uVal = 0; ++ ++ /* mt6797 can not access reg:0x80050078 and no need to do GPS SYNC */ ++ if (0x0279 != wmt_ic_ops_soc.icId) { ++ if (WMT_IC_PIN_MUX == state) ++ uVal = 0x1 << 28; ++ else ++ uVal = 0x5 << 28; ++ iRet = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28); ++ if (iRet) ++ WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet); ++ } else ++ WMT_INFO_FUNC("This chip no need to sync GPS and MODEM!\n"); ++ ++ /* anyway, we return 0 */ ++ return 0; ++} ++ ++static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) ++{ ++ INT32 ret; ++ ++ WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); ++ ++ ret = -1; ++ switch (id) { ++ case WMT_IC_PIN_AUDIO: ++ ret = mtk_wcn_soc_aif_ctrl(state, flag); ++ break; ++ ++ case WMT_IC_PIN_EEDI: ++ WMT_WARN_FUNC("TBD!!"); ++ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ ++ ret = 0; ++ break; ++ ++ case WMT_IC_PIN_EEDO: ++ WMT_WARN_FUNC("TBD!!"); ++ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ ++ ret = 0; ++ break; ++ case WMT_IC_PIN_GSYNC: ++ ret = mtk_wcn_soc_gps_sync_ctrl(state, flag); ++ break; ++ default: ++ break; ++ } ++ WMT_INFO_FUNC("ret = (%d)\n", ret); ++ ++ return ret; ++} ++ ++INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on) ++{ ++ INT32 iRet = 0; ++ ++ if ((WMT_CO_CLOCK_DIS <= on) && (WMT_CO_CLOCK_MAX > on)) { ++ gCoClockEn = on; ++ } else { ++ WMT_DBG_FUNC("0x%x: error parameter:%d\n", wmt_ic_ops_soc.icId, on); ++ iRet = -1; ++ } ++ WMT_DBG_FUNC("0x%x: Co-clock %s\n", wmt_ic_ops_soc.icId, ++ (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled"); ++ ++ return iRet; ++} ++ ++static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID) ++{ ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID) ++{ ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID) ++{ ++ return gCoClockEn; ++} ++ ++static INT32 mtk_wcn_soc_ver_check(VOID) ++{ ++ UINT32 hw_ver; ++ UINT32 fw_ver; ++ INT32 iret; ++ const WMT_IC_INFO_S *p_info; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ ++ WMT_LOUD_FUNC("0x%x: before read hw_ver (hw version)\n", wmt_ic_ops_soc.icId); ++ iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); ++ if (iret) { ++ WMT_ERR_FUNC("0x%x: read hw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); ++ return -2; ++ } ++ WMT_WARN_FUNC("0x%x: read hw_ver (hw version) (0x%x)\n", wmt_ic_ops_soc.icId, hw_ver); ++ ++ WMT_LOUD_FUNC("0x%x: before fw_ver (rom version)\n", wmt_ic_ops_soc.icId); ++ wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); ++ if (iret) { ++ WMT_ERR_FUNC("0x%x: read fw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); ++ return -2; ++ } ++ WMT_WARN_FUNC("0x%x: read fw_ver (rom version) (0x%x)\n", wmt_ic_ops_soc.icId, fw_ver); ++ ++ p_info = mtk_wcn_soc_find_wmt_ic_info(hw_ver); ++ if (NULL == p_info) { ++ WMT_ERR_FUNC("0x%x: hw_ver(0x%x) find wmt ic info fail\n", wmt_ic_ops_soc.icId); ++ return -3; ++ } ++ WMT_WARN_FUNC("0x%x: ic info: %s.%s (0x%x/0x%x, WMTHWVER:%d, patch_ext:%s)\n", ++ wmt_ic_ops_soc.icId, p_info->cChipName, p_info->cChipVersion, ++ hw_ver, fw_ver, p_info->eWmtHwVer, p_info->cPatchNameExt); ++ ++ /* hw id & version */ ++ ctrlPa1 = (wmt_ic_ops_soc.icId << 16) | (hw_ver & 0x0000FFFF); ++ /* translated hw version & fw rom version */ ++ ctrlPa2 = ((UINT32) (p_info->eWmtHwVer) << 16) | (fw_ver & 0x0000FFFF); ++ ++ iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); ++ if (iret) ++ WMT_WARN_FUNC("0x%x: WMT_CTRL_HWIDVER_SET fail(%d)\n", wmt_ic_ops_soc.icId, iret); ++ ++ gp_soc_info = p_info; ++ return 0; ++} ++ ++static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver) ++{ ++ /* match chipversion with u4HwVer item in mtk_wcn_soc_info_table */ ++ const UINT32 size = osal_array_size(mtk_wcn_soc_info_table); ++ INT32 index = 0; ++ ++ /* George: reverse the search order to favor newer version products ++ * TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() ++ * is changed correctly in the future!! ++ * Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. ++ */ ++ index = size - 1; ++ /* full match */ ++ while ((0 <= index) && (hw_ver != mtk_wcn_soc_info_table[index].u4HwVer)) ++ --index; ++ if (0 <= index) { ++ WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); ++ return &mtk_wcn_soc_info_table[index]; ++ } ++ ++ WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); ++ ++ /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR ++ * NUM only can help us support future minor hw ECO, or fab switch, etc. ++ * FULL matching eliminate such flexibility and software package have to be ++ * updated EACH TIME even when minor hw ECO or fab switch!!! ++ */ ++ /* George: reverse the search order to favor newer version products */ ++ index = size - 1; ++ /* major num match */ ++ while ((0 <= index) && ++ (MAJORNUM(hw_ver) != MAJORNUM(mtk_wcn_soc_info_table[index].u4HwVer))) { ++ --index; ++ } ++ if (0 <= index) { ++ WMT_DBG_FUNC("0x%x: found ic info for hw_ver(0x%x) by major num! index:%d\n", ++ wmt_ic_ops_soc.icId, hw_ver, index); ++ return &mtk_wcn_soc_info_table[index]; ++ } ++ ++ WMT_ERR_FUNC("0x%x: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", ++ wmt_ic_ops_soc.icId, hw_ver); ++ WMT_ERR_FUNC("Set default chip version: E1!\n"); ++ return &mtk_wcn_soc_info_table[0]; ++} ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static INT32 wmt_stp_wifi_lte_coex(VOID) ++{ ++ INT32 iRet; ++ unsigned long addr; ++ WMT_GEN_CONF *pWmtGenConf; ++ ++ /*Get wmt config */ ++ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); ++ if (iRet) { ++ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); ++ return -2; ++ } ++ WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); ++ ++ pWmtGenConf = (P_WMT_GEN_CONF) addr; ++ ++ /*Check if WMT.cfg exists */ ++ if (pWmtGenConf->cfgExist == 0) { ++ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); ++ /*if WMT.cfg not existed, still return success and adopt the default value */ ++ return 0; ++ } ++ ++ osal_sleep_ms(5); ++ ++ if (pWmtGenConf->coex_wmt_filter_mode == 0) { ++ if ((0x6752 == wmt_ic_ops_soc.icId) || ++ (0x6580 == wmt_ic_ops_soc.icId) || ++ (0x8163 == wmt_ic_ops_soc.icId) || ++ (0x0326 == wmt_ic_ops_soc.icId) || ++ (0x0321 == wmt_ic_ops_soc.icId) || ++ (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { ++ iRet = ++ wmt_core_init_script(set_wifi_lte_coex_table_1, osal_array_size(set_wifi_lte_coex_table_1)); ++ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_1 %s(%d)\n", iRet ? "fail" : "ok", iRet); ++ } else if (0x0279 == wmt_ic_ops_soc.icId) { ++ /* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/ ++ if (pWmtGenConf->coex_wmt_ext_component) { ++ WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); ++ set_wifi_lte_coex_table_2[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; ++ } ++ iRet = ++ wmt_core_init_script(set_wifi_lte_coex_table_2, osal_array_size(set_wifi_lte_coex_table_2)); ++ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_2 %s(%d)\n", iRet ? "fail" : "ok", iRet); ++ } else { ++ iRet = ++ wmt_core_init_script(set_wifi_lte_coex_table_0, osal_array_size(set_wifi_lte_coex_table_0)); ++ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 %s(%d)\n", iRet ? "fail" : "ok", iRet); ++ } ++ } ++ ++ return iRet; ++} ++#endif ++ ++static INT32 wmt_stp_init_coex(VOID) ++{ ++ INT32 iRet; ++ unsigned long addr; ++ WMT_GEN_CONF *pWmtGenConf; ++ ++#define COEX_WMT 0 ++ ++#if CFG_SUBSYS_COEX_NEED ++ /* no need for MT6628 */ ++#define COEX_BT 1 ++#define COEX_WIFI 2 ++#define COEX_PTA 3 ++#define COEX_MISC 4 ++#endif ++ /*Get wmt config */ ++ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); ++ if (iRet) { ++ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); ++ return -2; ++ } ++ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); ++ ++ pWmtGenConf = (P_WMT_GEN_CONF) addr; ++ ++ /*Check if WMT.cfg exists */ ++ if (pWmtGenConf->cfgExist == 0) { ++ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); ++ /*if WMT.cfg not existed, still return success and adopt the default value */ ++ return 0; ++ } ++ ++ /*Dump the coex-related info */ ++ WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode); ++#if CFG_SUBSYS_COEX_NEED ++ WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_bt_rssi_upper_limit, ++ pWmtGenConf->coex_bt_rssi_mid_limit, ++ pWmtGenConf->coex_bt_rssi_lower_limit, ++ pWmtGenConf->coex_bt_pwr_high, pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); ++ WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_wifi_rssi_upper_limit, ++ pWmtGenConf->coex_wifi_rssi_mid_limit, ++ pWmtGenConf->coex_wifi_rssi_lower_limit, ++ pWmtGenConf->coex_wifi_pwr_high, pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); ++ WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_ext_pta_hi_tx_tag, ++ pWmtGenConf->coex_ext_pta_hi_rx_tag, ++ pWmtGenConf->coex_ext_pta_lo_tx_tag, ++ pWmtGenConf->coex_ext_pta_lo_rx_tag, ++ pWmtGenConf->coex_ext_pta_sample_t1, ++ pWmtGenConf->coex_ext_pta_sample_t2, pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); ++ WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); ++#endif ++ ++ /*command adjustion due to WMT.cfg */ ++ coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); ++ ++#if CFG_SUBSYS_COEX_NEED ++ coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; ++ coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; ++ coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; ++ coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; ++ coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; ++ coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); ++ ++ coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; ++ coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; ++ coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; ++ coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; ++ coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; ++ coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], ++ coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); ++ ++ coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; ++ coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; ++ coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; ++ coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; ++ coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); ++ coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); ++ coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); ++ coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); ++ coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); ++ ++ osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, ++ sizeof(pWmtGenConf->coex_misc_ext_pta_on)); ++ osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, ++ sizeof(pWmtGenConf->coex_misc_ext_feature_set)); ++ ++ wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, coex_table[COEX_MISC].cmdSz); ++#endif ++ ++ iRet = wmt_core_init_script(coex_table, sizeof(coex_table) / sizeof(coex_table[0])); ++ ++ return iRet; ++} ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++static INT32 mtk_wcn_soc_set_sdio_driving(void) ++{ ++ INT32 ret = 0; ++ ++ unsigned long addr; ++ WMT_GEN_CONF *pWmtGenConf; ++ UINT32 drv_val = 0; ++ ++ /*Get wmt config */ ++ ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); ++ if (ret) { ++ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); ++ return -1; ++ } ++ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); ++ ++ pWmtGenConf = (P_WMT_GEN_CONF) addr; ++ ++ /*Check if WMT.cfg exists */ ++ if (pWmtGenConf->cfgExist == 0) { ++ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); ++ /*if WMT.cfg not existed, still return success and adopt the default value */ ++ return 0; ++ } ++ ++ drv_val = pWmtGenConf->sdio_driving_cfg; ++ ++ /*Dump the sdio driving related info */ ++ WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); ++ ++ sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ ++ sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ ++ sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ ++ ++ ret = wmt_core_init_script(sdio_driving_table, sizeof(sdio_driving_table) / sizeof(sdio_driving_table[0])); ++ ++ return ret; ++} ++#endif ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static INT32 mtk_wcn_soc_crystal_triming_set(VOID) ++{ ++ INT32 iRet = 0; ++ PUINT8 pbuf = NULL; ++ UINT32 bufLen = 0; ++ WMT_CTRL_DATA ctrlData; ++ UINT32 uCryTimOffset = 0x6D; ++ MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ INT8 cCrystalTimingOffset = 0x0; ++ UINT8 cCrystalTiming = 0x0; ++ INT32 iCrystalTiming = 0x0; ++ MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; ++ UINT32 u4Res; ++ ++ bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ /**/ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; ++ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; ++ ctrlData.au4CtrlData[1] = (UINT32) &pbuf; ++ ctrlData.au4CtrlData[2] = (UINT32) &bufLen; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (0 != iRet) { ++ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", wmt_ic_ops_soc.icId, iRet); ++ bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; ++ cCrystalTimingOffset = 0x0; ++ cCrystalTiming = 0x0; ++ iRet = -1; ++ } else { ++ WMT_DBG_FUNC("0x%x: nvram pBuf(0x%08x), bufLen(%d)\n", wmt_ic_ops_soc.icId, pbuf, bufLen); ++ if (bufLen < (uCryTimOffset + 1)) { ++ WMT_ERR_FUNC("0x%x: nvram len(%d) too short, crystalTimging value offset(%d)\n", ++ wmt_ic_ops_soc.icId, bufLen, uCryTimOffset); ++ bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; ++ cCrystalTimingOffset = 0x0; ++ cCrystalTiming = 0x0; ++ } else { ++ bIsNvramExist = MTK_WCN_BOOL_TRUE; ++ cCrystalTimingOffset = *(pbuf + uCryTimOffset); ++ if (cCrystalTimingOffset & 0x80) { ++ bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; ++ cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; ++ } ++ WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", cCrystalTimingOffset, ++ bIsCrysTrimEnabled); ++ } ++ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; ++ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; ++ iRet = wmt_ctrl(&ctrlData); ++ if (0 != iRet) { ++ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", wmt_ic_ops_soc.icId, iRet); ++ iRet = -2; ++ } else { ++ WMT_DBG_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n", wmt_ic_ops_soc.icId); ++ } ++ } ++ if ((MTK_WCN_BOOL_TRUE == bIsNvramExist) && (MTK_WCN_BOOL_TRUE == bIsCrysTrimEnabled)) { ++ /*get CrystalTiming value before set it */ ++ iRet = ++ wmt_core_tx(get_crystal_timing_script[0].cmd, get_crystal_timing_script[0].cmdSz, &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", ++ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].cmdSz); ++ iRet = -3; ++ goto done; ++ } ++ /* EVENT BUF */ ++ osal_memset(get_crystal_timing_script[0].evt, 0, get_crystal_timing_script[0].evtSz); ++ iRet = wmt_core_rx(get_crystal_timing_script[0].evt, get_crystal_timing_script[0].evtSz, &u4Res); ++ if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { ++ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", ++ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].evtSz); ++ mtk_wcn_stp_dbg_dump_package(); ++ iRet = -4; ++ goto done; ++ } ++ ++ iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; ++ if (cCrystalTimingOffset & 0x40) { ++ /*nagative offset value */ ++ iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; ++ } else { ++ iCrystalTiming += cCrystalTimingOffset; ++ } ++ WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); ++ cCrystalTiming = iCrystalTiming > 0x7f ? 0x7f : iCrystalTiming; ++ cCrystalTiming = iCrystalTiming < 0 ? 0 : iCrystalTiming; ++ WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); ++ /* set_crystal_timing_script */ ++ WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; ++ WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; ++ ++ iRet = wmt_core_init_script(set_crystal_timing_script, osal_array_size(set_crystal_timing_script)); ++ if (iRet) { ++ WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); ++ iRet = -5; ++ } else { ++ WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", WMT_SET_CRYSTAL_TRIMING_CMD[5]); ++ iRet = ++ wmt_core_init_script(get_crystal_timing_script, osal_array_size(get_crystal_timing_script)); ++ if (iRet) { ++ WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); ++ iRet = -6; ++ } else { ++ WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", ++ WMT_GET_CRYSTAL_TRIMING_EVT[5]); ++ iRet = 0x0; ++ } ++ } ++ } ++done: ++ return iRet; ++} ++#endif ++ ++#if CFG_WMT_MULTI_PATCH ++static INT32 mtk_wcn_soc_patch_info_prepare(VOID) ++{ ++ INT32 iRet = -1; ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; ++ iRet = wmt_ctrl(&ctrlData); ++ ++ return iRet; ++} ++ ++static INT32 mtk_wcn_soc_patch_dwn(UINT32 index) ++{ ++ INT32 iRet = -1; ++ P_WMT_PATCH patchHdr; ++ PUINT8 pbuf; ++ UINT32 patchSize; ++ UINT32 fragSeq; ++ UINT32 fragNum; ++ UINT16 fragSize = 0; ++ UINT16 cmdLen; ++ UINT32 offset; ++ UINT32 u4Res; ++ UINT8 evtBuf[8]; ++ UINT8 addressevtBuf[12]; ++ UINT8 addressByte[4]; ++ PINT8 cDataTime = NULL; ++ /*PINT8 cPlat = NULL; */ ++ UINT16 u2HwVer = 0; ++ UINT16 u2SwVer = 0; ++ UINT32 u4PatchVer = 0; ++ UINT32 patchSizePerFrag = 0; ++ WMT_CTRL_DATA ctrlData; ++ ++ /*1.check hardware information */ ++ if (NULL == gp_soc_info) { ++ WMT_ERR_FUNC("null gp_soc_info!\n"); ++ return -1; ++ } ++ ++ osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); ++ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; ++ ctrlData.au4CtrlData[0] = index + 1; ++ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; ++ ctrlData.au4CtrlData[2] = (SIZE_T) &addressByte; ++ iRet = wmt_ctrl(&ctrlData); ++ WMT_DBG_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); ++ ++ /* <2.2> read patch content */ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; ++ ctrlData.au4CtrlData[0] = (SIZE_T) NULL; ++ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; ++ ctrlData.au4CtrlData[2] = (SIZE_T) &pbuf; ++ ctrlData.au4CtrlData[3] = (SIZE_T) &patchSize; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); ++ iRet -= 1; ++ goto done; ++ } ++ ++ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ ++ pbuf += BCNT_PATCH_BUF_HEADROOM; ++ /* patch file with header: ++ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| ++ */ ++ patchHdr = (P_WMT_PATCH) pbuf; ++ /* check patch file information */ ++ ++ cDataTime = patchHdr->ucDateTime; ++ u2HwVer = patchHdr->u2HwVer; ++ u2SwVer = patchHdr->u2SwVer; ++ u4PatchVer = patchHdr->u4PatchVer; ++ /*cPlat = &patchHdr->ucPLat[0]; */ ++ ++ cDataTime[15] = '\0'; ++ if (index == 0) { ++ WMT_DBG_FUNC("===========================================\n"); ++ WMT_INFO_FUNC("[Patch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", ++ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), ++ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), ++ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); ++ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], ++ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("===========================================\n"); ++ } ++ ++ /* remove patch header: ++ * |<-patch body: X Bytes (X=patchSize)--->| ++ */ ++ patchSize -= sizeof(WMT_PATCH); ++ pbuf += sizeof(WMT_PATCH); ++ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; ++ /* reserve 1st patch cmd space before patch body ++ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| ++ */ ++ /* gp_soc_patch_info = patchHdr; */ ++ osal_memcpy(&gp_soc_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); ++ pbuf -= sizeof(WMT_PATCH_CMD); ++ ++ fragNum = patchSize / patchSizePerFrag; ++ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; ++ ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ ++ /*send wmt part patch address command */ ++ if (0x6752 == wmt_ic_ops_soc.icId || ++ 0x8127 == wmt_ic_ops_soc.icId || ++ 0x7623 == wmt_ic_ops_soc.icId || ++ 0x6571 == wmt_ic_ops_soc.icId || ++ 0x0326 == wmt_ic_ops_soc.icId || ++ 0x0321 == wmt_ic_ops_soc.icId || ++ 0x0335 == wmt_ic_ops_soc.icId || ++ 0x0337 == wmt_ic_ops_soc.icId || 0x8163 == wmt_ic_ops_soc.icId || 0x6580 == wmt_ic_ops_soc.icId) { ++ /* MT6571 patch RAM base */ ++ WMT_PATCH_ADDRESS_CMD[8] = 0x40; ++ WMT_PATCH_P_ADDRESS_CMD[8] = 0xc8; ++ } ++ /*send wmt part patch address command */ ++ if (0x0279 == wmt_ic_ops_soc.icId) { ++ /* MT6797 patch RAM base */ ++ WMT_PATCH_ADDRESS_CMD[8] = 0x08; ++ WMT_PATCH_ADDRESS_CMD[9] = 0x05; ++ WMT_PATCH_P_ADDRESS_CMD[8] = 0x2c; ++ WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b; ++ } ++ ++ /*send wmt part patch address command */ ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { ++ WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); ++ iRet -= 1; ++ goto done; ++ } ++ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); ++ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { ++ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); ++ iRet -= 1; ++ goto done; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); ++ iRet -= 1; ++ goto done; ++ } ++#endif ++ ++ /*send part patch address command */ ++ osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); ++ WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", ++ WMT_PATCH_P_ADDRESS_CMD[12], ++ WMT_PATCH_P_ADDRESS_CMD[13], WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { ++ WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); ++ iRet -= 1; ++ goto done; ++ } ++ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); ++ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { ++ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); ++ iRet -= 1; ++ goto done; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", index); ++ iRet -= 1; ++ goto done; ++ } ++#endif ++ ++ /* send all fragments */ ++ offset = sizeof(WMT_PATCH_CMD); ++ fragSeq = 0; ++ while (fragSeq < fragNum) { ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ if (fragSeq == (fragNum - 1)) { ++ /* last fragment */ ++ fragSize = patchSize - fragSeq * patchSizePerFrag; ++ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; ++ } else { ++ fragSize = patchSizePerFrag; ++ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; ++ } ++ /* update length field in CMD:flag+frag */ ++ cmdLen = 1 + fragSize; ++ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); ++ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ ++ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); ++ ++ /* iRet = ++ *(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), ++ *&u4Res); ++ */ ++ iRet = ++ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), ++ &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); ++ ++ osal_memset(evtBuf, 0, sizeof(evtBuf)); ++ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ ++ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), ++ u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, ++ evtBuf[0], ++ evtBuf[1], ++ evtBuf[2], ++ evtBuf[3], ++ evtBuf[4]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_PATCH_EVT), ++ WMT_PATCH_EVT[0], ++ WMT_PATCH_EVT[1], ++ WMT_PATCH_EVT[2], ++ WMT_PATCH_EVT[3], ++ WMT_PATCH_EVT[4]); ++ iRet -= 1; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); ++ offset += patchSizePerFrag; ++ ++fragSeq; ++ } ++ ++ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", ++ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); ++ ++ if (fragSeq != fragNum) ++ iRet -= 1; ++done: ++ /* WMT_CTRL_FREE_PATCH always return 0 */ ++ /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ ++ ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; ++ ctrlData.au4CtrlData[0] = index + 1; ++ wmt_ctrl(&ctrlData); ++ ++ return iRet; ++} ++ ++#else ++static INT32 mtk_wcn_soc_patch_dwn(VOID) ++{ ++ INT32 iRet = -1; ++ P_WMT_PATCH patchHdr; ++ PUINT8 pbuf; ++ UINT32 patchSize; ++ UINT32 fragSeq; ++ UINT32 fragNum; ++ UINT16 fragSize = 0; ++ UINT16 cmdLen; ++ UINT32 offset; ++ UINT32 u4Res; ++ UINT8 evtBuf[8]; ++ PINT8 cDataTime = NULL; ++ /*PINT8 cPlat = NULL; */ ++ UINT16 u2HwVer = 0; ++ UINT16 u2SwVer = 0; ++ UINT32 u4PatchVer = 0; ++ UINT32 patchSizePerFrag = 0; ++ WMT_CTRL_DATA ctrlData; ++ ++ /*1.check hardware information */ ++ if (NULL == gp_soc_info) { ++ WMT_ERR_FUNC("null gp_soc_info!\n"); ++ return -1; ++ } ++ /* <2> search patch and read patch content */ ++ /* <2.1> search patch */ ++ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; ++ iRet = wmt_ctrl(&ctrlData); ++ if (0 == iRet) { ++ /* patch with correct Hw Ver Major Num found */ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; ++ ctrlData.au4CtrlData[0] = (UINT32) &gFullPatchName; ++ iRet = wmt_ctrl(&ctrlData); ++ ++ WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); ++ /* <2.2> read patch content */ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; ++ ctrlData.au4CtrlData[0] = (UINT32) NULL; ++ ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName; ++ ++ } else { ++ iRet -= 1; ++ return iRet; ++ } ++ ctrlData.au4CtrlData[2] = (UINT32) &pbuf; ++ ctrlData.au4CtrlData[3] = (UINT32) &patchSize; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); ++ iRet -= 1; ++ goto done; ++ } ++ ++ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ ++ pbuf += BCNT_PATCH_BUF_HEADROOM; ++ /* patch file with header: ++ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| ++ */ ++ patchHdr = (P_WMT_PATCH) pbuf; ++ /* check patch file information */ ++ ++ cDataTime = patchHdr->ucDateTime; ++ u2HwVer = patchHdr->u2HwVer; ++ u2SwVer = patchHdr->u2SwVer; ++ u4PatchVer = patchHdr->u4PatchVer; ++ /*cPlat = &patchHdr->ucPLat[0]; */ ++ ++ cDataTime[15] = '\0'; ++ WMT_DBG_FUNC("===========================================\n"); ++ WMT_INFO_FUNC("[ConsysPatch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", ++ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), ++ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), ++ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); ++ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], ++ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("===========================================\n"); ++ ++ /* remove patch header: ++ * |<-patch body: X Bytes (X=patchSize)--->| ++ */ ++ patchSize -= sizeof(WMT_PATCH); ++ pbuf += sizeof(WMT_PATCH); ++ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; ++ /* reserve 1st patch cmd space before patch body ++ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| ++ */ ++ pbuf -= sizeof(WMT_PATCH_CMD); ++ ++ fragNum = patchSize / patchSizePerFrag; ++ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; ++ ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ ++ /* send all fragments */ ++ offset = sizeof(WMT_PATCH_CMD); ++ fragSeq = 0; ++ while (fragSeq < fragNum) { ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ if (fragSeq == (fragNum - 1)) { ++ /* last fragment */ ++ fragSize = patchSize - fragSeq * patchSizePerFrag; ++ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; ++ } else { ++ fragSize = patchSizePerFrag; ++ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; ++ } ++ /* update length field in CMD:flag+frag */ ++ cmdLen = 1 + fragSize; ++ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); ++ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ ++ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); ++ ++ /* iRet = ++ * (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), ++ * &u4Res); ++ */ ++ iRet = ++ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); ++ ++ osal_memset(evtBuf, 0, sizeof(evtBuf)); ++ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ ++ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), ++ u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, ++ evtBuf[0], ++ evtBuf[1], ++ evtBuf[2], ++ evtBuf[3], ++ evtBuf[4]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_PATCH_EVT), ++ WMT_PATCH_EVT[0], ++ WMT_PATCH_EVT[1], ++ WMT_PATCH_EVT[2], ++ WMT_PATCH_EVT[3], ++ WMT_PATCH_EVT[4]); ++ iRet -= 1; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); ++ offset += patchSizePerFrag; ++ ++fragSeq; ++ } ++ ++ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", ++ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); ++ ++ if (fragSeq != fragNum) ++ iRet -= 1; ++done: ++ /* WMT_CTRL_FREE_PATCH always return 0 */ ++ wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); ++ ++ return iRet; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c +new file mode 100644 +index 000000000000..747ed64af2d2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c +@@ -0,0 +1,1938 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-LIB]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include "wmt_dev.h" ++#include "wmt_lib.h" ++#include "wmt_conf.h" ++#include "wmt_core.h" ++#include "wmt_plat.h" ++ ++#include "stp_core.h" ++#include "btm_core.h" ++#include "psm_core.h" ++#include "stp_dbg.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* A table for translation: CMB_STUB_AIF_X=>WMT_IC_PIN_STATE */ ++static const WMT_IC_PIN_STATE cmb_aif2pin_stat[] = { ++ [CMB_STUB_AIF_0] = WMT_IC_AIF_0, ++ [CMB_STUB_AIF_1] = WMT_IC_AIF_1, ++ [CMB_STUB_AIF_2] = WMT_IC_AIF_2, ++ [CMB_STUB_AIF_3] = WMT_IC_AIF_3, ++}; ++ ++#if CFG_WMT_PS_SUPPORT ++static UINT32 gPsIdleTime = STP_PSM_IDLE_TIME_SLEEP; ++static UINT32 gPsEnable = 1; ++static PF_WMT_SDIO_PSOP sdio_own_ctrl; ++#endif ++ ++#define WMT_STP_CPUPCR_BUF_SIZE 6144 ++static UINT8 g_cpupcr_buf[WMT_STP_CPUPCR_BUF_SIZE] = { 0 }; ++ ++static UINT32 g_quick_sleep_ctrl = 1; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++DEV_WMT gDevWmt; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#if CFG_WMT_PS_SUPPORT ++static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action); ++static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID); ++static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID); ++static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID); ++static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action); ++#endif ++ ++static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pLxOp); ++ ++static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ); ++ ++static INT32 wmtd_thread(PVOID pvData); ++ ++static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag); ++static MTK_WCN_BOOL wmt_lib_hw_state_show(VOID); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_lib_idc_lock_aquire(VOID) ++{ ++ return osal_lock_sleepable_lock(&gDevWmt.idc_lock); ++} ++ ++VOID wmt_lib_idc_lock_release(VOID) ++{ ++ osal_unlock_sleepable_lock(&gDevWmt.idc_lock); ++} ++INT32 wmt_lib_psm_lock_aquire(void) ++{ ++ return osal_lock_sleepable_lock(&gDevWmt.psm_lock); ++} ++ ++void wmt_lib_psm_lock_release(void) ++{ ++ osal_unlock_sleepable_lock(&gDevWmt.psm_lock); ++} ++ ++INT32 DISABLE_PSM_MONITOR(void) ++{ ++ INT32 ret = 0; ++ ++ /* osal_lock_sleepable_lock(&gDevWmt.psm_lock); */ ++ ret = wmt_lib_psm_lock_aquire(); ++ if (ret) { ++ WMT_ERR_FUNC("--->lock psm_lock failed, ret=%d\n", ret); ++ return ret; ++ } ++#if CFG_WMT_PS_SUPPORT ++ ret = wmt_lib_ps_disable(); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_lib_ps_disable fail, ret=%d\n", ret); ++ wmt_lib_psm_lock_release(); ++ } ++#endif ++ ++ return ret; ++} ++ ++void ENABLE_PSM_MONITOR(void) ++{ ++#if CFG_WMT_PS_SUPPORT ++ wmt_lib_ps_enable(); ++#endif ++ /* osal_unlock_sleepable_lock(&gDevWmt.psm_lock); */ ++ wmt_lib_psm_lock_release(); ++} ++ ++INT32 wmt_lib_init(VOID) ++{ ++ INT32 iRet; ++ UINT32 i; ++ P_DEV_WMT pDevWmt; ++ P_OSAL_THREAD pThraed; ++ ++ /* create->init->start */ ++ /* 1. create: static allocation with zero initialization */ ++ pDevWmt = &gDevWmt; ++ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); ++ ++ iRet = wmt_conf_read_file(); ++ if (iRet) { ++ WMT_ERR_FUNC("read wmt config file fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ pThraed = &gDevWmt.thread; ++ ++ /* Create mtk_wmtd thread */ ++ osal_strncpy(pThraed->threadName, "mtk_wmtd", sizeof(pThraed->threadName)); ++ pThraed->pThreadData = (VOID *) pDevWmt; ++ pThraed->pThreadFunc = (VOID *) wmtd_thread; ++ iRet = osal_thread_create(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThraed, iRet); ++ return -2; ++ } ++ ++ /* 2. initialize */ ++ /* Initialize wmt_core */ ++ ++ iRet = wmt_core_init(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core_init() fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ /* Initialize WMTd Thread Information: Thread */ ++ osal_event_init(&pDevWmt->rWmtdWq); ++ osal_sleepable_lock_init(&pDevWmt->psm_lock); ++ osal_sleepable_lock_init(&pDevWmt->idc_lock); ++ osal_sleepable_lock_init(&pDevWmt->rActiveOpQ.sLock); ++ osal_sleepable_lock_init(&pDevWmt->rFreeOpQ.sLock); ++ pDevWmt->state.data = 0; ++ ++ /* Initialize op queue */ ++ RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); ++ RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); ++ /* Put all to free Q */ ++ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(pDevWmt->arQue[i].signal)); ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); ++ } ++ ++ /* initialize stp resources */ ++ osal_event_init(&pDevWmt->rWmtRxWq); ++ ++ /*function driver callback */ ++ for (i = 0; i < WMTDRV_TYPE_WIFI; i++) ++ pDevWmt->rFdrvCb.fDrvRst[i] = NULL; ++ ++ pDevWmt->hw_ver = WMTHWVER_MAX; ++ WMT_INFO_FUNC("***********Init, hw->ver = %x\n", pDevWmt->hw_ver); ++ ++ /* TODO:[FixMe][GeorgeKuo]: wmt_lib_conf_init */ ++ /* initialize default configurations */ ++ /* i4Result = wmt_lib_conf_init(VOID); */ ++ /* WMT_WARN_FUNC("wmt_drv_conf_init(%d)\n", i4Result); */ ++ ++ osal_signal_init(&pDevWmt->cmdResp); ++ osal_event_init(&pDevWmt->cmdReq); ++ ++ /* initialize platform resources */ ++ if (0 != gDevWmt.rWmtGenConf.cfgExist) ++ iRet = wmt_plat_init(gDevWmt.rWmtGenConf.co_clock_flag & 0x0f); ++ else ++ iRet = wmt_plat_init(0); ++ ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_plat_init() fail(%d)\n", iRet); ++ return -3; ++ } ++#if CFG_WMT_PS_SUPPORT ++ iRet = wmt_lib_ps_init(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_lib_ps_init() fail(%d)\n", iRet); ++ return -4; ++ } ++#endif ++ ++ /* 3. start: start running mtk_wmtd */ ++ iRet = osal_thread_run(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThraed, iRet); ++ return -5; ++ } ++ ++ /*4. register irq callback to WMT-PLAT */ ++ wmt_plat_irq_cb_reg(wmt_lib_ps_irq_cb); ++ ++ /*5. register audio if control callback to WMT-PLAT */ ++ wmt_plat_aif_cb_reg(wmt_lib_set_aif); ++ ++ /*6. register function control callback to WMT-PLAT */ ++ wmt_plat_func_ctrl_cb_reg(mtk_wcn_wmt_func_ctrl_for_plat); ++ ++ wmt_plat_deep_idle_ctrl_cb_reg(mtk_wcn_consys_stp_btif_dpidle_ctrl); ++ /*7 reset gps/bt state */ ++ ++ mtk_wcn_wmt_system_state_reset(); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_wmt_exp_init(); ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ wmt_idc_init(); ++#endif ++ WMT_DBG_FUNC("init success\n"); ++ return 0; ++} ++ ++INT32 wmt_lib_deinit(VOID) ++{ ++ INT32 iRet; ++ P_DEV_WMT pDevWmt; ++ P_OSAL_THREAD pThraed; ++ INT32 i; ++ INT32 iResult; ++ ++ pDevWmt = &gDevWmt; ++ pThraed = &gDevWmt.thread; ++ iResult = 0; ++ ++ /* stop->deinit->destroy */ ++ ++ /* 1. stop: stop running mtk_wmtd */ ++ iRet = osal_thread_stop(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); ++ iResult += 1; ++ } ++ ++ /* 2. deinit: */ ++ ++#if CFG_WMT_PS_SUPPORT ++ iRet = wmt_lib_ps_deinit(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_lib_ps_deinit fail(%d)\n", iRet); ++ iResult += 2; ++ } ++#endif ++ ++ iRet = wmt_plat_deinit(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_plat_deinit fail(%d)\n", iRet); ++ iResult += 4; ++ } ++ ++ osal_event_deinit(&pDevWmt->cmdReq); ++ osal_signal_deinit(&pDevWmt->cmdResp); ++ ++ /* de-initialize stp resources */ ++ osal_event_deinit(&pDevWmt->rWmtRxWq); ++ ++ for (i = 0; i < WMT_OP_BUF_SIZE; i++) ++ osal_signal_deinit(&(pDevWmt->arQue[i].signal)); ++ ++ ++ osal_sleepable_lock_deinit(&pDevWmt->rFreeOpQ.sLock); ++ osal_sleepable_lock_deinit(&pDevWmt->rActiveOpQ.sLock); ++ osal_sleepable_lock_deinit(&pDevWmt->idc_lock); ++ osal_sleepable_lock_deinit(&pDevWmt->psm_lock); ++ osal_event_deinit(&pDevWmt->rWmtdWq); ++ ++ iRet = wmt_core_deinit(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core_deinit fail(%d)\n", iRet); ++ iResult += 8; ++ } ++ ++ /* 3. destroy */ ++ iRet = osal_thread_destroy(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); ++ iResult += 16; ++ } ++ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_wmt_exp_deinit(); ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ wmt_idc_deinit(); ++#endif ++ ++ return iResult; ++} ++ ++VOID wmt_lib_flush_rx(VOID) ++{ ++ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); ++} ++ ++INT32 wmt_lib_trigger_cmd_signal(INT32 result) ++{ ++ P_OSAL_SIGNAL pSignal = &gDevWmt.cmdResp; ++ ++ gDevWmt.cmdResult = result; ++ osal_raise_signal(pSignal); ++ WMT_DBG_FUNC("wakeup cmdResp\n"); ++ return 0; ++} ++ ++P_OSAL_EVENT wmt_lib_get_cmd_event(VOID) ++{ ++ return &gDevWmt.cmdReq; ++} ++ ++INT32 wmt_lib_set_patch_name(PUINT8 cPatchName) ++{ ++ osal_strncpy(gDevWmt.cPatchName, cPatchName, NAME_MAX); ++ return 0; ++} ++ ++INT32 wmt_lib_set_hif(unsigned long hifconf) ++{ ++ UINT32 val; ++ P_WMT_HIF_CONF pHif = &gDevWmt.rWmtHifConf; ++ ++ val = hifconf & 0xF; ++ if (STP_UART_FULL == val) { ++ pHif->hifType = WMT_HIF_UART; ++ val = (hifconf >> 8); ++ pHif->au4HifConf[0] = val; ++ pHif->au4HifConf[1] = val; ++ mtk_wcn_stp_set_if_tx_type(STP_UART_IF_TX); ++ } else if (STP_SDIO == val) { ++ pHif->hifType = WMT_HIF_SDIO; ++ mtk_wcn_stp_set_if_tx_type(STP_SDIO_IF_TX); ++ } else if (STP_BTIF_FULL == val) { ++ pHif->hifType = WMT_HIF_BTIF; ++ mtk_wcn_stp_set_if_tx_type(STP_BTIF_IF_TX); ++ } else { ++ WMT_WARN_FUNC("invalid stp mode: %u\n", val); ++ mtk_wcn_stp_set_if_tx_type(STP_MAX_IF_TX); ++ return -1; ++ } ++ ++ val = (hifconf & 0xF0) >> 4; ++ if (WMT_FM_COMM == val) { ++ pHif->au4StrapConf[0] = WMT_FM_COMM; ++ } else if (WMT_FM_I2C == val) { ++ pHif->au4StrapConf[0] = WMT_FM_I2C; ++ } else { ++ WMT_WARN_FUNC("invalid fm mode: %u\n", val); ++ return -2; ++ } ++ ++ WMT_WARN_FUNC("new hifType: %d, fm:%d\n", pHif->hifType, pHif->au4StrapConf[0]); ++ return 0; ++} ++ ++P_WMT_HIF_CONF wmt_lib_get_hif(VOID) ++{ ++ return &gDevWmt.rWmtHifConf; ++} ++ ++PUINT8 wmt_lib_get_cmd(VOID) ++{ ++ if (osal_test_and_clear_bit(WMT_STAT_CMD, &gDevWmt.state)) ++ return gDevWmt.cCmd; ++ ++ return NULL; ++} ++ ++MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID) ++{ ++ return osal_test_bit(WMT_STAT_CMD, &gDevWmt.state) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; ++} ++ ++#if CFG_WMT_PS_SUPPORT ++INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime) ++{ ++ gPsIdleTime = psIdleTime; ++ return gPsIdleTime; ++} ++ ++INT32 wmt_lib_ps_ctrl(UINT32 state) ++{ ++ if (0 == state) { ++ wmt_lib_ps_disable(); ++ gPsEnable = 0; ++ } else { ++ gPsEnable = 1; ++ wmt_lib_ps_enable(); ++ } ++ return 0; ++} ++ ++INT32 wmt_lib_ps_enable(VOID) ++{ ++ if (gPsEnable) ++ mtk_wcn_stp_psm_enable(gPsIdleTime); ++ ++ return 0; ++} ++ ++INT32 wmt_lib_ps_disable(VOID) ++{ ++ if (gPsEnable) ++ return mtk_wcn_stp_psm_disable(); ++ ++ return 0; ++} ++ ++INT32 wmt_lib_ps_init(VOID) ++{ ++ /* mtk_wcn_stp_psm_register_wmt_cb(wmt_lib_ps_stp_cb); */ ++ return 0; ++} ++ ++INT32 wmt_lib_ps_deinit(VOID) ++{ ++ /* mtk_wcn_stp_psm_unregister_wmt_cb(); */ ++ return 0; ++} ++ ++static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action) ++{ ++ P_OSAL_OP lxop; ++ MTK_WCN_BOOL bRet; ++ UINT32 u4Wait; ++ P_OSAL_SIGNAL pSignal; ++ ++ lxop = wmt_lib_get_free_op(); ++ if (!lxop) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ pSignal = &lxop->signal; ++ pSignal->timeoutValue = 0; ++ lxop->op.opId = WMT_OPID_PWR_SV; ++ lxop->op.au4OpData[0] = action; ++ lxop->op.au4OpData[1] = (SIZE_T) mtk_wcn_stp_psm_notify_stp; ++ u4Wait = 0; ++ bRet = wmt_lib_put_act_op(lxop); ++ return bRet; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor) ++{ ++ P_OSAL_OP lxop; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ INT32 ret = 0; ++ UINT16 msg_len = 0; ++ static UINT8 msg_local_buffer[1300]; ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; ++#endif ++ WMT_DBG_FUNC("idc_infor from conn_md is 0x%p\n", idc_infor); ++ ret = wmt_lib_idc_lock_aquire(); ++ if (ret) { ++ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", ret); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ msg_len = idc_infor->local_para_ptr->msg_len - osal_sizeof(local_para_struct); ++ osal_memcpy(&msg_local_buffer[0], &msg_len, osal_sizeof(msg_len)); ++ osal_memcpy(&msg_local_buffer[osal_sizeof(msg_len)], ++ &(idc_infor->local_para_ptr->data[0]), msg_len - 1); ++ wmt_lib_idc_lock_release(); ++ lxop = wmt_lib_get_free_op(); ++ if (!lxop) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ pSignal = &lxop->signal; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ lxop->op.opId = WMT_OPID_IDC_MSG_HANDLING; ++ lxop->op.au4OpData[0] = (size_t) msg_local_buffer; ++ /*msg opcode fill rule is still not clrear,need scott comment */ ++ /***********************************************************/ ++ WMT_DBG_FUNC("ilm msg id is (0x%08x)\n", idc_infor->msg_id); ++ ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ switch (idc_infor->msg_id) { ++ case IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_PARA; ++ break; ++ case IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_FREQ; ++ break; ++ case IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_WIFI_MAX_POWER; ++ break; ++ case IPC_MSG_ID_EL1_LTE_TX_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_INDICATION; ++ break; ++ case IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS; ++ break; ++ default: ++ unknown_msgid = MTK_WCN_BOOL_TRUE; ++ break; ++ } ++ ++ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(lxop); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(lxop); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); ++ else ++ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", lxop->op.opId, lxop->op.au4OpData[1]); ++ } else { ++ bRet = MTK_WCN_BOOL_FALSE; ++ wmt_lib_put_op_to_free_queue(lxop); ++ WMT_ERR_FUNC("unknown msgid from LTE(%d)\n", idc_infor->msg_id); ++ } ++#else ++ if ((idc_infor->msg_id >= IPC_EL1_MSG_ID_BEGIN) ++ && (idc_infor->msg_id <= IPC_EL1_MSG_ID_BEGIN + IPC_EL1_MSG_ID_RANGE)) { ++ lxop->op.au4OpData[1] = idc_infor->msg_id - IPC_EL1_MSG_ID_BEGIN + LTE_MSG_ID_OFFSET - 1; ++ ++ WMT_DBG_FUNC("LTE->CONN:(0x%x->0x%zx)\n", idc_infor->msg_id, lxop->op.au4OpData[1]); ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(lxop); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(lxop); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); ++ } else { ++ WMT_DBG_FUNC("wmt_lib_handle_idc_msg OPID(%d) type(%d) ok\n", ++ lxop->op.opId, lxop->op.au4OpData[1]); ++ } ++ } else { ++ wmt_lib_put_op_to_free_queue(lxop); ++ WMT_ERR_FUNC("msgid(%d) out of range,wmt drop it!\n", idc_infor->msg_id); ++ } ++#endif ++ ++ return bRet; ++} ++#endif ++ ++static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID) ++{ ++ return wmt_lib_ps_action(SLEEP); ++} ++ ++static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID) ++{ ++ return wmt_lib_ps_action(WAKEUP); ++} ++ ++static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID) ++{ ++#if 1 ++ return wmt_lib_ps_action(WAKEUP); ++#else ++ return wmt_lib_ps_action(HOST_AWAKE); ++#endif ++} ++ ++/* extern int g_block_tx; */ ++static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action) ++{ ++ INT32 ret; ++ ++ ret = 0; /* TODO:[FixMe][George] initial value or compile warning? */ ++ /* if(g_block_tx && (action == SLEEP)) */ ++ if ((0 != mtk_wcn_stp_coredump_start_get()) && (action == SLEEP)) { ++ mtk_wcn_stp_psm_notify_stp(SLEEP); ++ return ret; ++ } ++ ++ /*MT662x Not Ready */ ++ if (!mtk_wcn_stp_is_ready()) { ++ WMT_DBG_FUNC("MT662x Not Ready, Dont Send Sleep/Wakeup Command\n"); ++ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); ++ return 0; ++ } ++ ++ if (SLEEP == action) { ++ WMT_DBG_FUNC("send op-----------> sleep job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ ret = wmt_lib_ps_do_sleep(); ++ WMT_DBG_FUNC("enable host eirq\n"); ++ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_EN); ++#if CFG_WMT_DUMP_INT_STATUS ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ } else { ++ /* ret = mtk_wcn_stp_sdio_do_own_set(); */ ++ if (sdio_own_ctrl) { ++ ret = (*sdio_own_ctrl) (OWN_SET); ++ } else { ++ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); ++ ret = -1; ++ } ++ ++ if (!ret) { ++ mtk_wcn_stp_psm_notify_stp(SLEEP); ++ } else if (ret == -2) { ++ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); ++ WMT_WARN_FUNC("===[SDIO-PS] rollback due to tx busy===%%\n"); ++ } else { ++ mtk_wcn_stp_psm_notify_stp(SLEEP); ++ WMT_ERR_FUNC("===[SDIO-PS] set own fails!===%%\n"); ++ } ++ } ++ ++ WMT_DBG_FUNC("send op<---------- sleep job\n"); ++ } else if (WAKEUP == action) { ++ WMT_DBG_FUNC("send op --------> wake job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ WMT_DBG_FUNC("disable host eirq\n"); ++#if CFG_WMT_DUMP_INT_STATUS ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ ret = wmt_lib_ps_do_wakeup(); ++ } else { ++ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ ++ ++ if (sdio_own_ctrl) { ++ ret = (*sdio_own_ctrl) (OWN_CLR); ++ } else { ++ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); ++ ret = -1; ++ } ++ ++ if (!ret) { ++ mtk_wcn_stp_psm_notify_stp(WAKEUP); ++ } else { ++ mtk_wcn_stp_psm_notify_stp(WAKEUP); ++ WMT_ERR_FUNC("===[SDIO-PS] set own back fails!===%%\n"); ++ } ++ } ++ ++ WMT_DBG_FUNC("send op<---------- wake job\n"); ++ } else if (HOST_AWAKE == action) { ++ WMT_DBG_FUNC("send op-----------> host awake job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ WMT_DBG_FUNC("disable host eirq\n"); ++ /* IRQ already disabled */ ++ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ ++#if 0 ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ ret = wmt_lib_ps_do_host_awake(); ++ } else { ++ WMT_DBG_FUNC("[SDIO-PS] SDIO host awake! ####\n"); ++ ++ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ ++ ++ if (sdio_own_ctrl) { ++ ret = (*sdio_own_ctrl) (OWN_CLR); ++ } else { ++ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); ++ ret = -1; ++ } ++ ++ /* Here we set ret to 0 directly */ ++ ret = 0; ++ if (!ret) { ++ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); ++ } else { ++ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); ++ WMT_ERR_FUNC("===[SDIO-PS]set own back fails!===%%\n"); ++ } ++ } ++ ++ WMT_DBG_FUNC("send op<----------- host awake job\n"); ++ } else if (EIRQ == action) { ++ WMT_DBG_FUNC("send op -------------> eirq job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ WMT_DBG_FUNC("disable host eirq\n"); ++ /* Disable interrupt */ ++ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ ++ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); ++ } else { ++ WMT_ERR_FUNC("[SDIO-PS]sdio own-back eirq!######\n"); ++ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); ++ } ++ ++ WMT_DBG_FUNC("send op<----------- eirq job\n"); ++ } ++ ++ return ret; ++} ++#endif /* end of CFG_WMT_PS_SUPPORT */ ++ ++INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action) ++{ ++#if CFG_WMT_PS_SUPPORT ++ return wmt_lib_ps_handler(action); ++#else ++ WMT_WARN_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); ++ return 0; ++#endif ++} ++ ++MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID) ++{ ++ if ((g_quick_sleep_ctrl) && (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_TRUE)) ++ return wmt_core_is_quick_ps_support(); ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++VOID wmt_lib_ps_irq_cb(VOID) ++{ ++#if CFG_WMT_PS_SUPPORT ++ wmt_lib_ps_handler(EIRQ); ++#else ++ WMT_DBG_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); ++ return; ++#endif ++} ++ ++VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb) ++{ ++#if CFG_WMT_PS_SUPPORT ++ sdio_own_ctrl = own_cb; ++#endif ++} ++ ++UINT32 wmt_lib_wait_event_checker(P_OSAL_THREAD pThread) ++{ ++ P_DEV_WMT pDevWmt; ++ ++ if (pThread) { ++ pDevWmt = (P_DEV_WMT) (pThread->pThreadData); ++ return !RB_EMPTY(&pDevWmt->rActiveOpQ); ++ } ++ WMT_ERR_FUNC("pThread(NULL)\n"); ++ return 0; ++} ++ ++static INT32 wmtd_thread(void *pvData) ++{ ++ P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData; ++ P_OSAL_EVENT pEvent = NULL; ++ P_OSAL_OP pOp; ++ INT32 iResult; ++ ++ if (NULL == pWmtDev) { ++ WMT_ERR_FUNC("pWmtDev(NULL)\n"); ++ return -1; ++ } ++ WMT_INFO_FUNC("wmtd thread starts\n"); ++ ++ pEvent = &(pWmtDev->rWmtdWq); ++ ++ for (;;) { ++ pOp = NULL; ++ pEvent->timeoutValue = 0; ++/* osal_thread_wait_for_event(&pWmtDev->thread, pEvent);*/ ++ osal_thread_wait_for_event(&pWmtDev->thread, pEvent, wmt_lib_wait_event_checker); ++ ++ if (osal_thread_should_stop(&pWmtDev->thread)) { ++ WMT_INFO_FUNC("wmtd thread should stop now...\n"); ++ /* TODO: clean up active opQ */ ++ break; ++ } ++ ++ /* get Op from activeQ */ ++ pOp = wmt_lib_get_op(&pWmtDev->rActiveOpQ); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_lxop activeQ fail\n"); ++ continue; ++ } ++#if 0 /* wmt_core_opid_handler will do sanity check on opId, so no usage here */ ++ id = lxop_get_opid(pLxOp); ++ if (id >= WMT_OPID_MAX) { ++ WMT_WARN_FUNC("abnormal opid id: 0x%x\n", id); ++ iResult = -1; ++ goto handlerDone; ++ } ++#endif ++ ++ if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) { ++ /* when whole chip reset, only HW RST and SW RST cmd can execute */ ++ if ((pOp->op.opId == WMT_OPID_HW_RST) || (pOp->op.opId == WMT_OPID_SW_RST) ++ || (pOp->op.opId == WMT_OPID_GPIO_STATE)) { ++ iResult = wmt_core_opid(&pOp->op); ++ } else { ++ iResult = -2; ++ WMT_WARN_FUNC("Whole chip resetting, opid (%d) failed, iRet(%d)\n", pOp->op.opId, ++ iResult); ++ } ++ } else { ++ wmt_lib_set_current_op(pWmtDev, pOp); ++ iResult = wmt_core_opid(&pOp->op); ++ wmt_lib_set_current_op(pWmtDev, NULL); ++ } ++ ++ if (iResult) ++ WMT_WARN_FUNC("opid (%d) failed, iRet(%d)\n", pOp->op.opId, iResult); ++ ++ if (osal_op_is_wait_for_signal(pOp)) { ++ osal_op_raise_signal(pOp, iResult); ++ } else { ++ /* put Op back to freeQ */ ++ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); ++ } ++ ++ if (WMT_OPID_EXIT == pOp->op.opId) { ++ WMT_INFO_FUNC("wmtd thread received exit signal\n"); ++ break; ++ } ++ } ++ ++ WMT_INFO_FUNC("wmtd thread exits succeed\n"); ++ ++ return 0; ++}; ++ ++static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) ++{ ++ INT32 iRet; ++ ++ if (!pOpQ || !pOp) { ++ WMT_WARN_FUNC("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", pOpQ, pOp); ++ osal_assert(pOpQ); ++ osal_assert(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); ++ if (iRet) { ++ WMT_WARN_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); ++ return MTK_WCN_BOOL_FALSE; ++ } ++#if 0 ++ if (pOpQ == &gDevWmt.rFreeOpQ) ++ WMT_INFO_FUNC("current wmt free queue count is(%d),opid(%d)\n", RB_COUNT(pOpQ), pOp->op.opId); ++#endif ++ /* acquire lock success */ ++ if (!RB_FULL(pOpQ)) ++ RB_PUT(pOpQ, pOp); ++ else ++ iRet = -1; ++ ++ osal_unlock_sleepable_lock(&pOpQ->sLock); ++ ++ if (iRet) { ++ WMT_WARN_FUNC("RB_FULL(0x%p)\n", pOpQ); ++ return MTK_WCN_BOOL_FALSE; ++ } else { ++ return MTK_WCN_BOOL_TRUE; ++ } ++} ++ ++static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ) ++{ ++ P_OSAL_OP pOp; ++ INT32 iRet; ++ ++ if (NULL == pOpQ) { ++ WMT_ERR_FUNC("pOpQ = NULL\n"); ++ osal_assert(pOpQ); ++ return NULL; ++ } ++ ++ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); ++ return NULL; ++ } ++ ++ /* acquire lock success */ ++ RB_GET(pOpQ, pOp); ++ osal_unlock_sleepable_lock(&pOpQ->sLock); ++ ++ if (NULL == pOp) { ++ WMT_WARN_FUNC("RB_GET return NULL\n"); ++ osal_assert(pOp); ++ } ++ ++ return pOp; ++} ++ ++INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (MTK_WCN_BOOL_FALSE == wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp)) ++ return -1; ++ else ++ return 0; ++} ++ ++P_OSAL_OP wmt_lib_get_free_op(VOID) ++{ ++ P_OSAL_OP pOp = NULL; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ ++ osal_assert(pDevWmt); ++ ++ pOp = wmt_lib_get_op(&pDevWmt->rFreeOpQ); ++ if (pOp) ++ osal_memset(&pOp->op, 0, osal_sizeof(pOp->op)); ++ return pOp; ++} ++ ++MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ MTK_WCN_BOOL bCleanup = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal = NULL; ++ long waitRet = -1; ++ P_OSAL_THREAD pThread; ++ ++ osal_assert(pWmtDev); ++ osal_assert(pOp); ++ ++ do { ++ if (!pWmtDev || !pOp) { ++ WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp); ++ break; ++ } ++ if ((0 != mtk_wcn_stp_coredump_start_get()) && ++ (WMT_OPID_HW_RST != pOp->op.opId) && ++ (WMT_OPID_SW_RST != pOp->op.opId) && (WMT_OPID_GPIO_STATE != pOp->op.opId)) { ++ bCleanup = MTK_WCN_BOOL_TRUE; ++ WMT_WARN_FUNC("block tx flag is set\n"); ++ break; ++ } ++ pSignal = &pOp->signal; ++/* pOp->u4WaitMs = u4WaitMs; */ ++ if (pSignal->timeoutValue) { ++ pOp->result = -9; ++ osal_signal_init(pSignal); ++ } ++ ++ /* put to active Q */ ++ bRet = wmt_lib_put_op(&pWmtDev->rActiveOpQ, pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("put to active queue fail\n"); ++ bCleanup = MTK_WCN_BOOL_TRUE; ++ break; ++ } ++ ++ /* wake up wmtd */ ++ /* wake_up_interruptible(&pWmtDev->rWmtdWq); */ ++ osal_trigger_event(&pWmtDev->rWmtdWq); ++ ++ if (0 == pSignal->timeoutValue) { ++ bRet = MTK_WCN_BOOL_TRUE; ++ /* clean it in wmtd */ ++ break; ++ } ++ /* wait result, clean it here */ ++ bCleanup = MTK_WCN_BOOL_TRUE; ++ ++ /* check result */ ++ /* wait_ret = wait_for_completion_interruptible_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ ++ /* wait_ret = wait_for_completion_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ ++ waitRet = osal_wait_for_signal_timeout(pSignal); ++ WMT_DBG_FUNC("osal_wait_for_signal_timeout:%ld\n", waitRet); ++ ++ /* if (unlikely(!wait_ret)) { */ ++ if (0 == waitRet) { ++ pThread = &gDevWmt.thread; ++ WMT_ERR_FUNC ++ ("wait completion timeout, opId(%d), show wmtd_thread stack!\n", pOp->op.opId); ++ /* TODO: how to handle it? retry? */ ++ wcn_wmtd_timeout_collect_ftrace(); /* trigger collect SYS_FTRACE */ ++ osal_thread_show_stack(pThread); ++ } else { ++ if (pOp->result) ++ WMT_WARN_FUNC("opId(%d) result:%d\n", pOp->op.opId, pOp->result); ++ } ++ /* op completes, check result */ ++ bRet = (pOp->result) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; ++ } while (0); ++ ++ if (bCleanup) { ++ /* put Op back to freeQ */ ++ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); ++ } ++ ++ return bRet; ++} ++ ++/* TODO:[ChangeFeature][George] is this function obsoleted? */ ++#if 0 ++INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) ++{ ++ P_WMT_LXOP lxop; ++ MTK_WCN_BOOL bRet; ++ PUINT32 plv = NULL; ++ UINT32 pbuf[2]; ++ P_OSAL_EVENT pSignal = NULL; ++ ++ if (!pvalue) { ++ WMT_WARN_FUNC("!pvalue\n"); ++ return -1; ++ } ++ lxop = wmt_lib_get_free_lxop(); ++ if (!lxop) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ ++ return -1; ++ } ++ ++ plv = (PUINT32) (((UINT32) pbuf + 0x3) & ~0x3UL); ++ *plv = *pvalue; ++ pSignal = &lxop->signal; ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%d) offset(0x%x) value(0x%x) mask(0x%x)\n", isWrite, offset, *pvalue, mask); ++ ++ lxop->op.opId = WMT_OPID_REG_RW; ++ lxop->op.au4OpData[0] = isWrite; ++ lxop->op.au4OpData[1] = offset; ++ lxop->op.au4OpData[2] = (UINT32) plv; ++ lxop->op.au4OpData[3] = mask; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ DISABLE_PSM_MONITOR(); ++ bRet = wmt_lib_put_act_lxop(lxop); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE != bRet) { ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", ++ isWrite, offset, *plv, mask); ++ if (!isWrite) ++ *pvalue = *plv; ++ } else { ++ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", ++ isWrite, offset, *plv, mask, bRet); ++ } ++ ++ return bRet; ++} ++#endif ++ ++/* TODO:[ChangeFeature][George] is this function obsoleted? */ ++#if 0 ++static VOID wmt_lib_clear_chip_id(VOID) ++{ ++/* ++ gDevWmt.pChipInfo = NULL; ++*/ ++ gDevWmt.hw_ver = WMTHWVER_INVALID; ++} ++#endif ++ ++/* TODO: [FixMe][GeorgeKuo]: change this API to report real chip id, hw_ver, and */ ++/* fw_ver instead of WMT-translated WMTHWVER */ ++ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver(VOID) ++{ ++/* ++ P_WMT_CMB_CHIP_INFO_S pChipInfo = NULL; ++ P_DEV_WMT pWmtDev = gpDevWmt; ++ pChipInfo = wmt_lib_get_chip_info(pWmtDev); ++ return pChipInfo != NULL ? pChipInfo->eHwVersion : WMTHWVER_INVALID; ++ */ ++ return gDevWmt.eWmtHwVer; ++} ++ ++UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T index) ++{ ++ if (WMTCHIN_CHIPID == index) ++ return gDevWmt.chip_id; ++ else if (WMTCHIN_HWVER == index) ++ return gDevWmt.hw_ver; ++ else if (WMTCHIN_MAPPINGHWVER == index) ++ return gDevWmt.eWmtHwVer; ++ else if (WMTCHIN_FWVER == index) ++ return gDevWmt.fw_ver; ++ ++ return 0; ++ ++} ++ ++PUINT8 wmt_lib_def_patch_name(VOID) ++{ ++ WMT_INFO_FUNC("wmt-lib: use default patch name (%s)\n", gDevWmt.cPatchName); ++ return gDevWmt.cPatchName; ++} ++ ++MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID) ++{ ++ MTK_WCN_BOOL bIsSupportTherm = MTK_WCN_BOOL_TRUE; ++ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ ++ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) ++ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { ++ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); ++ bIsSupportTherm = MTK_WCN_BOOL_FALSE; ++ } ++ if (!mtk_wcn_stp_is_ready()) { ++ WMT_ERR_FUNC("thermal command can not be send: STP is not ready\n"); ++ bIsSupportTherm = MTK_WCN_BOOL_FALSE; ++ } ++ ++ return bIsSupportTherm; ++} ++ ++MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID) ++{ ++ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ ++ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) ++ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { ++ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++/*! ++ * \brief Update combo chip pin settings (GPIO) ++ * ++ * An internal library function to support various settings for chip GPIO. It is ++ * updated in a grouping way: configure all required pins in a single call. ++ * ++ * \param id desired pin ID to be controlled ++ * \param stat desired pin states to be set ++ * \param flag supplementary options for this operation ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid id ++ * \retval -2 invalid stat ++ * \retval < 0 error for operation fail ++ */ ++static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ /* input sanity check */ ++ if (WMT_IC_PIN_MAX <= id) { ++ WMT_ERR_FUNC("invalid ic pin id(%d)\n", id); ++ return -1; ++ } ++ if (WMT_IC_PIN_STATE_MAX <= stat) { ++ WMT_ERR_FUNC("invalid ic pin state (%d)\n", stat); ++ return -2; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_GPIO_CTRL (ic pin id:%d, stat:%d, flag:0x%x)\n", id, stat, flag); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_GPIO_CTRL; ++ pOp->op.au4OpData[0] = id; ++ pOp->op.au4OpData[1] = stat; ++ pOp->op.au4OpData[2] = flag; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("PIN_ID(%d) PIN_STATE(%d) flag(%d) fail\n", id, stat, flag); ++ else ++ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ return 0; ++} ++ ++INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT32 value; ++ P_OSAL_SIGNAL pSignal; ++ ++ if (!pvalue) { ++ WMT_WARN_FUNC("!pvalue\n"); ++ return -1; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; ++ } ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ value = *pvalue; ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", isWrite, offset, *pvalue, mask); ++ pOp->op.opId = WMT_OPID_REG_RW; ++ pOp->op.au4OpData[0] = isWrite; ++ pOp->op.au4OpData[1] = offset; ++ pOp->op.au4OpData[2] = (SIZE_T)&value; ++ pOp->op.au4OpData[3] = mask; ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE != bRet) { ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", ++ isWrite, offset, value, mask); ++ if (!isWrite) ++ *pvalue = value; ++ ++ return 0; ++ } ++ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", ++ isWrite, offset, value, mask, bRet); ++ return -1; ++} ++ ++INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT32 value; ++ P_OSAL_SIGNAL pSignal; ++ ++ if (!pvalue) { ++ WMT_WARN_FUNC("!pvalue\n"); ++ return -1; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; ++ } ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ value = *pvalue; ++ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", ++ isWrite, offset, *pvalue, mask); ++ pOp->op.opId = WMT_OPID_EFUSE_RW; ++ pOp->op.au4OpData[0] = isWrite; ++ pOp->op.au4OpData[1] = offset; ++ pOp->op.au4OpData[2] = (SIZE_T)&value; ++ pOp->op.au4OpData[3] = mask; ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE != bRet) { ++ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", ++ isWrite, offset, value, mask); ++ if (!isWrite) ++ *pvalue = value; ++ ++ return 0; ++ } ++ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", ++ isWrite, offset, value, mask, bRet); ++ return -1; ++ ++} ++ ++/*! ++ * \brief update combo chip AUDIO Interface (AIF) settings ++ * ++ * A library function to support updating chip AUDIO pin settings. A group of ++ * pins is updated as a whole. ++ * ++ * \param aif desired audio interface state to use ++ * \param flag whether audio pin is shared or not ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid aif ++ * \retval < 0 error for invalid parameters or operation fail ++ */ ++INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share) ++{ ++ if (CMB_STUB_AIF_MAX <= aif) { ++ WMT_ERR_FUNC("invalid aif (%d)\n", aif); ++ return -1; ++ } ++ WMT_DBG_FUNC("call pin_ctrl for aif:%d, share:%d\n", aif, (MTK_WCN_BOOL_TRUE == share) ? 1 : 0); ++ /* Translate CMB_STUB_AIF_X into WMT_IC_PIN_STATE by array */ ++ return wmt_lib_pin_ctrl(WMT_IC_PIN_AUDIO, ++ cmb_aif2pin_stat[aif], ++ (MTK_WCN_BOOL_TRUE == share) ? WMT_LIB_AIF_FLAG_SHARE : WMT_LIB_AIF_FLAG_SEPARATE); ++} ++ ++INT32 wmt_lib_host_awake_get(VOID) ++{ ++ return wmt_plat_wake_lock_ctrl(WL_OP_GET); ++} ++ ++INT32 wmt_lib_host_awake_put(VOID) ++{ ++ return wmt_plat_wake_lock_ctrl(WL_OP_PUT); ++} ++ ++MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op) ++{ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ ++ if (op == BTM_RST_OP) { ++ /* high priority, not to enqueue into the queue of wmtd */ ++ WMT_INFO_FUNC("Invoke whole chip reset from stp_btm!!!\n"); ++ wmt_lib_cmb_rst(WMTRSTSRC_RESET_STP); ++ bRet = MTK_WCN_BOOL_TRUE; ++ } else if (op == BTM_DMP_OP) { ++ ++ WMT_WARN_FUNC("TBD!!!\n"); ++ } else if (op == BTM_GET_AEE_SUPPORT_FLAG) { ++ bRet = wmt_core_get_aee_dump_flag(); ++ } ++ return bRet; ++} ++ ++MTK_WCN_BOOL wmt_cdev_rstmsg_snd(ENUM_WMTRSTMSG_TYPE_T msg) ++{ ++ ++ INT32 i = 0; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ PUINT8 drv_name[] = { ++ "DRV_TYPE_BT", ++ "DRV_TYPE_FM", ++ "DRV_TYPE_GPS", ++ "DRV_TYPE_WIFI" ++ }; ++ ++ for (i = 0; i <= WMTDRV_TYPE_WIFI; i++) { ++ /* <1> check if reset callback is registered */ ++ if (pDevWmt->rFdrvCb.fDrvRst[i]) { ++ /* <2> send the msg to this subfucntion */ ++ /*src, dst, msg_type, msg_data, msg_size */ ++ pDevWmt->rFdrvCb.fDrvRst[i] (WMTDRV_TYPE_WMT, i, WMTMSG_TYPE_RESET, &msg, ++ sizeof(ENUM_WMTRSTMSG_TYPE_T)); ++ WMT_INFO_FUNC("type = %s, msg sent\n", drv_name[i]); ++ } else { ++ WMT_DBG_FUNC("type = %s, unregistered\n", drv_name[i]); ++ } ++ } ++ ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++VOID wmt_lib_state_init(VOID) ++{ ++ /* UINT32 i = 0; */ ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ P_OSAL_OP pOp; ++ ++ /* Initialize op queue */ ++ /* RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); */ ++ /* RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); */ ++ ++ while (!RB_EMPTY(&pDevWmt->rActiveOpQ)) { ++#if 0 ++ osal_signal_init(&(pOp->signal)); ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); ++#endif ++ pOp = wmt_lib_get_op(&pDevWmt->rActiveOpQ); ++ if (pOp) { ++ if (osal_op_is_wait_for_signal(pOp)) ++ osal_op_raise_signal(pOp, -1); ++ else ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); ++ } ++ } ++ ++ /* Put all to free Q */ ++ /* ++ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(pDevWmt->arQue[i].signal)); ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); ++ } */ ++} ++ ++#if 0 ++INT32 wmt_lib_sdio_ctrl(UINT32 on) ++{ ++ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_SDIO_CTRL\n"); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_SDIO_CTRL; ++ pOp->op.au4OpData[0] = on; ++ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_SDIO_CTRL failed\n"); ++ return -1; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_SDIO_CTRL)ok\n"); ++ ++ return 0; ++} ++#endif ++ ++MTK_WCN_BOOL wmt_lib_hw_state_show(VOID) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_HW_STATE_SHOW\n"); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_GPIO_STATE; ++ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_HW_STATE_SHOW failed\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_HW_STATE_SHOW)ok\n"); ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++MTK_WCN_BOOL wmt_lib_hw_rst(VOID) ++{ ++ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ ++ wmt_lib_state_init(); ++ ++ osal_clear_bit(WMT_STAT_STP_REG, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_STP_OPEN, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_STP_EN, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_STP_RDY, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_RX, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_CMD, &pDevWmt->state); ++ ++ /*Before do hardware reset, we show GPIO state to check if others modified our pin state accidentially */ ++ wmt_lib_hw_state_show(); ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_HW_RST\n"); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_HW_RST; ++ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_HW_RST failed\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_HW_RST)ok\n"); ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst) ++{ ++ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ /* <1> wmt state reset */ ++ wmt_lib_state_init(); ++ ++ /* <2> Reset STP data structure */ ++ WMT_DBG_FUNC("Cleanup STP context\n"); ++ mtk_wcn_stp_flush_context(); ++ /* <3> Reset STP-PSM data structure */ ++ WMT_DBG_FUNC("Cleanup STP-PSM context\n"); ++ mtk_wcn_stp_psm_reset(); ++ ++ /* <4> do sw reset in wmt-core */ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_SW_RST\n"); ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = MAX_FUNC_ON_TIME; ++ ++ pOp->op.opId = WMT_OPID_SW_RST; ++ pOp->op.au4OpData[0] = baudRst; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_SW_RST failed\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_SW_RST)ok\n"); ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src) ++{ ++#define RETRYTIMES 10 ++ MTK_WCN_BOOL bRet; ++ ENUM_WMTRSTRET_TYPE_T retval = WMTRSTRET_MAX; ++ ENUM_WMTRSTMSG_TYPE_T rstMsg = WMTRSTMSG_RESET_MAX; ++ INT32 retries = RETRYTIMES; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ P_OSAL_OP pOp; ++ PUINT8 srcName[] = { "WMTRSTSRC_RESET_BT", ++ "WMTRSTSRC_RESET_FM", ++ "WMTRSTSRC_RESET_GPS", ++ "WMTRSTSRC_RESET_WIFI", ++ "WMTRSTSRC_RESET_STP", ++ "WMTRSTSRC_RESET_TEST" ++ }; ++ ++ if (src < WMTRSTSRC_RESET_MAX) ++ WMT_INFO_FUNC("reset source = %s\n", srcName[src]); ++ ++ if (WMTRSTSRC_RESET_TEST == src) { ++ pOp = wmt_lib_get_current_op(pDevWmt); ++ if (pOp && ((WMT_OPID_FUNC_ON == pOp->op.opId) ++ || (WMT_OPID_FUNC_OFF == pOp->op.opId))) { ++ WMT_INFO_FUNC("can't do reset by test src when func on/off\n"); ++ return -1; ++ } ++ } ++ /* <1> Consider the multi-context combo_rst case. */ ++ if (osal_test_and_set_bit(WMT_STAT_RST_ON, &pDevWmt->state)) { ++ retval = WMTRSTRET_ONGOING; ++ goto rstDone; ++ } ++ /* <2> Block all STP request */ ++ mtk_wcn_stp_enable(0); ++ ++ /* <3> RESET_START notification */ ++ bRet = wmt_cdev_rstmsg_snd(WMTRSTMSG_RESET_START); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); ++ retval = WMTRSTRET_FAIL; ++ goto rstDone; ++ } ++ /* wakeup blocked opid */ ++ pOp = wmt_lib_get_current_op(pDevWmt); ++ if (osal_op_is_wait_for_signal(pOp)) ++ osal_op_raise_signal(pOp, -1); ++ ++ /* wakeup blocked cmd */ ++ wmt_dev_rx_event_cb(); ++ ++ /* <4> retry until reset flow successful */ ++ while (retries > 0) { ++ /* <4.1> reset combo hw */ ++ bRet = wmt_lib_hw_rst(); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_hw_rst!\n"); ++ retries--; ++ continue; ++ } ++ /* <4.2> reset driver/combo sw */ ++ bRet = wmt_lib_sw_rst(1); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_sw_rst!\n"); ++ retries--; ++ continue; ++ } ++ break; ++ } ++ ++ osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state); ++ ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ rstMsg = WMTRSTMSG_RESET_END_FAIL; ++ WMT_WARN_FUNC("[whole chip reset] fail! retries = %d\n", RETRYTIMES - retries); ++ } else { ++ rstMsg = WMTRSTMSG_RESET_END; ++ WMT_INFO_FUNC("[whole chip reset] ok! retries = %d\n", RETRYTIMES - retries); ++ } ++ ++ /* <5> RESET_END notification */ ++ bRet = wmt_cdev_rstmsg_snd(rstMsg); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); ++ retval = WMTRSTRET_FAIL; ++ } else { ++ retval = WMTRSTMSG_RESET_END == rstMsg ? WMTRSTRET_SUCCESS : WMTRSTRET_FAIL; ++ } ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++rstDone: ++ if (osal_test_and_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state)) ++ WMT_WARN_FUNC("[whole chip reset] retval = %d\n", retval); ++ ++ return retval; ++} ++ ++MTK_WCN_BOOL wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++{ ++ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { ++ WMT_DBG_FUNC("reg ok!\n"); ++ pWmtDev->rFdrvCb.fDrvRst[eType] = pCb; ++ bRet = MTK_WCN_BOOL_TRUE; ++ } else { ++ WMT_WARN_FUNC("reg fail!\n"); ++ } ++ ++ return bRet; ++} ++ ++MTK_WCN_BOOL wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++{ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { ++ WMT_DBG_FUNC("unreg ok!\n"); ++ pWmtDev->rFdrvCb.fDrvRst[eType] = NULL; ++ bRet = MTK_WCN_BOOL_TRUE; ++ } else { ++ WMT_WARN_FUNC("unreg fail!\n"); ++ } ++ ++ return bRet; ++} ++ ++UINT32 wmt_lib_dbg_level_set(UINT32 level) ++{ ++ gWmtDbgLvl = level > WMT_LOG_LOUD ? WMT_LOG_LOUD : level; ++ return 0; ++} ++ ++INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value) ++{ ++ return mtk_wcn_stp_set_wmt_last_close(value); ++} ++ ++INT32 wmt_lib_notify_stp_sleep(void) ++{ ++ INT32 iRet = 0x0; ++ ++ iRet = wmt_lib_psm_lock_aquire(); ++ if (iRet) { ++ WMT_ERR_FUNC("--->lock psm_lock failed, iRet=%d\n", iRet); ++ return iRet; ++ } ++ ++ iRet = mtk_wcn_stp_notify_sleep_for_thermal(); ++ wmt_lib_psm_lock_release(); ++ ++ return iRet; ++} ++ ++VOID wmt_lib_set_patch_num(UINT32 num) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ pWmtDev->patchNum = num; ++} ++ ++VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (pPatchinfo) ++ pWmtDev->pWmtPatchInfo = pPatchinfo; ++ ++} ++ ++INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp) ++{ ++ if (pWmtDev) { ++ pWmtDev->pCurOP = pOp; ++ WMT_DBG_FUNC("pOp=0x%p\n", pOp); ++ return 0; ++ } ++ WMT_ERR_FUNC("Invalid pointer\n"); ++ return -1; ++} ++ ++P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev) ++{ ++ if (pWmtDev) ++ return pWmtDev->pCurOP; ++ ++ WMT_ERR_FUNC("Invalid pointer\n"); ++ return NULL; ++} ++ ++UINT8 *wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, UINT8 *buf, UINT32 len) ++{ ++ UINT8 *pAddr = NULL; ++ UINT32 sublen1 = 0; ++ UINT32 sublen2 = 0; ++ P_CONSYS_EMI_ADDR_INFO p_consys_info; ++ ++ p_consys_info = wmt_plat_get_emi_phy_add(); ++ osal_assert(p_consys_info); ++ ++ if (section == 0) { ++ pAddr = wmt_plat_get_emi_virt_add(0x0); ++ if (len > 1024) ++ len = 1024; ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); ++ osal_memcpy(&buf[0], pAddr, len); ++ } ++ } else { ++ if (offset >= 0x7fff) ++ offset = 0x0; ++ ++ if (offset + len > 32768) { ++ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get part1 EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("part1 vir addr(0x%p)\n", pAddr); ++ sublen1 = 0x7fff - offset; ++ osal_memcpy(&buf[0], pAddr, sublen1); ++ } ++ pAddr = wmt_plat_get_emi_virt_add(p_consys_info->paged_trace_off); ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get part2 EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("part2 vir addr(0x%p)\n", pAddr); ++ sublen2 = len - sublen1; ++ osal_memcpy(&buf[sublen1], pAddr, sublen2); ++ } ++ } else { ++ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); ++ osal_memcpy(&buf[0], pAddr, len); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee) ++{ ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ ++ issue_type = STP_DBG_PROC_TEST; ++ ++ stp_dbg_poll_cpupcr(count, sleep, 1); ++ ++ if (toAee) { ++ stp_dbg_set_fw_info("STP ProcTest", osal_strlen("STP ProcTest"), issue_type); ++ osal_dbg_assert_aee("[SOC_CONSYS]ProcTest", ++ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n Polling CPUPCR for FW debug usage\n"); ++ } else { ++ WMT_INFO_FUNC("wmt_lib:do not pass cpupcr to AEE\n"); ++ } ++ return 0; ++} ++ ++UINT8 *wmt_lib_get_cpupcr_xml_format(UINT32 *len) ++{ ++ PUINT8 temp; ++ UINT32 i = 0; ++ ++ osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE); ++ temp = g_cpupcr_buf; ++ stp_dbg_cpupcr_infor_format(&temp, len); ++ ++ pr_debug("print xml buffer,len(%d):\n\n", *len); ++ for (i = 0; i < *len; i++) ++ pr_cont("%c", g_cpupcr_buf[i]); ++ ++ return &g_cpupcr_buf[0]; ++} ++ ++UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en) ++{ ++ return stp_dbg_set_host_assert_info(type, reason, en); ++} ++ ++INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl) ++{ ++ wmt_plat_thermal_ctrl_cb_reg(thermal_ctrl); ++ return 0; ++} ++ ++INT8 wmt_lib_co_clock_get(void) ++{ ++ if (gDevWmt.rWmtGenConf.cfgExist) ++ return gDevWmt.rWmtGenConf.co_clock_flag; ++ else ++ return -1; ++} ++ ++#if CFG_WMT_PS_SUPPORT ++UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en) ++{ ++ WMT_WARN_FUNC("%s quick sleep mode\n", en ? "enable" : "disable"); ++ g_quick_sleep_ctrl = en; ++ return 0; ++} ++#endif ++ ++#if CONSYS_ENALBE_SET_JTAG ++UINT32 wmt_lib_jtag_flag_set(UINT32 en) ++{ ++ return wmt_plat_jtag_flag_ctrl(en); ++} ++#endif ++ ++UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver) ++{ ++ return stp_dbg_set_wifiver(wifiver); ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h +new file mode 100644 +index 000000000000..b1b5285638f9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h +@@ -0,0 +1,252 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _STP_EXP_H_ ++#define _STP_EXP_H_ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_stp_exp.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++#define BT_TASK_INDX (0) ++#define FM_TASK_INDX (1) ++#define GPS_TASK_INDX (2) ++#define WIFI_TASK_INDX (3) ++#define WMT_TASK_INDX (4) ++#define STP_TASK_INDX (5) ++#define INFO_TASK_INDX (6) ++#define ANT_TASK_INDX (7) ++#if CFG_WMT_LTE_COEX_HANDLING ++#define COEX_TASK_INDX (8) ++#define MTKSTP_MAX_TASK_NUM (9) ++#else ++#define MTKSTP_MAX_TASK_NUM (8) ++#endif ++ ++#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ ++ ++#define STP_EXP_HID_API_EXPORT 0 ++ ++#else ++ ++#define STP_EXP_HID_API_EXPORT 1 ++ ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++typedef void (*MTK_WCN_STP_EVENT_CB) (void); ++typedef INT32 (*MTK_WCN_STP_IF_TX) (const UINT8 *data, const UINT32 size, UINT32 *written_size); ++/* export for HIF driver */ ++typedef void (*MTK_WCN_STP_IF_RX) (const UINT8 *data, INT32 size); ++ ++typedef enum { ++ STP_UART_IF_TX = 0, ++ STP_SDIO_IF_TX = 1, ++ STP_BTIF_IF_TX = 2, ++ STP_MAX_IF_TX ++} ENUM_STP_TX_IF_TYPE; ++#endif ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_receive_data ++* DESCRIPTION ++* receive data from serial protocol engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* INT32 >= 0: size of data received; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data ++* DESCRIPTION ++* subfunction send data through STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_rxqueue_empty ++* DESCRIPTION ++* Is certain rx queue empty? ++* PARAMETERS ++* type [IN] subfunction type ++* RETURNS ++* INT32 0: queue is NOT empyt; !0: queue is empty ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_enable ++* DESCRIPTION ++* Is STP ready? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:ready, FALSE:not ready ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_parser_data ++* DESCRIPTION ++* push data to serial transport protocol parser engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++extern int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); ++ ++/***************************************************************************** ++* FUNCTION ++* set_bluetooth_rx_interface ++* DESCRIPTION ++* Set bluetooth rx interface ++* PARAMETERS ++* rx interface type ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_tx_event_cb ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_tx_event_cb(int type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_event_cb ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_event_cb(int type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_tx ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_rx ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#else ++extern INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); ++extern INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++extern INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++extern MTK_WCN_BOOL _mtk_wcn_stp_is_rxqueue_empty(UINT8 type); ++extern MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void); ++extern INT32 _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); ++extern void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); ++extern INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++extern INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++extern INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++extern INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); ++extern INT32 _mtk_wcn_stp_coredump_start_get(VOID); ++ ++#endif ++ ++#endif /* _WMT_EXP_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h +new file mode 100644 +index 000000000000..6d10c3ff2659 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h +@@ -0,0 +1,19 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _MTKWMT_H_ ++#define _MTKWMT_H_ ++#include "wmt_core.h" ++ ++#endif /*_MTKWMT_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h +new file mode 100644 +index 000000000000..06238e07879f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h +@@ -0,0 +1,329 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_EXP_H_ ++#define _WMT_EXP_H_ ++ ++#include ++#include "osal.h" ++#include "wmt_plat.h" ++#include "wmt_stp_exp.h" ++/* not to reference to internal wmt */ ++/* #include "wmt_core.h" */ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#if 1 /* moved from wmt_lib.h */ ++#ifndef DFT_TAG ++#define DFT_TAG "[WMT-DFT]" ++#endif ++ ++#define WMT_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_LOUD) \ ++ osal_dbg_print(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_INFO) \ ++ osal_dbg_print(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_WARN) \ ++ osal_warn_print(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_ERR) \ ++ osal_err_print(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define WMT_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_DBG) \ ++ osal_dbg_print(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_TRC_FUNC(f) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_DBG) \ ++ osal_dbg_print(DFT_TAG "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#if 1 /* moved from wmt_lib.h */ ++extern UINT32 gWmtDbgLvl; ++#endif ++extern OSAL_BIT_OP_VAR gBtWifiGpsState; ++extern OSAL_BIT_OP_VAR gGpsFmState; ++extern UINT32 gWifiProbed; ++extern MTK_WCN_BOOL g_pwr_off_flag; ++extern UINT32 g_IsNeedDoChipReset; ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#if 1 /* moved from wmt_lib.h */ ++#define WMT_LOG_LOUD 4 ++#define WMT_LOG_DBG 3 ++#define WMT_LOG_INFO 2 ++#define WMT_LOG_WARN 1 ++#define WMT_LOG_ERR 0 ++#endif ++#define CFG_CORE_INTERNAL_TXRX 0 /*just do TX/RX in host side */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++typedef enum _ENUM_WMTDRV_TYPE_T { ++ WMTDRV_TYPE_BT = 0, ++ WMTDRV_TYPE_FM = 1, ++ WMTDRV_TYPE_GPS = 2, ++ WMTDRV_TYPE_WIFI = 3, ++ WMTDRV_TYPE_WMT = 4, ++ WMTDRV_TYPE_STP = 5, ++ WMTDRV_TYPE_LPBK = 6, ++ WMTDRV_TYPE_COREDUMP = 7, ++ WMTDRV_TYPE_MAX ++} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; ++ ++/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ ++/* TODO: how do we extend for new chip and newer revision? */ ++/* TODO: This way is hard to extend */ ++typedef enum _ENUM_WMTHWVER_TYPE_T { ++ WMTHWVER_E1 = 0x0, ++ WMTHWVER_E2 = 0x1, ++ WMTHWVER_E3 = 0x2, ++ WMTHWVER_E4 = 0x3, ++ WMTHWVER_E5 = 0x4, ++ WMTHWVER_E6 = 0x5, ++ WMTHWVER_MAX, ++ WMTHWVER_INVALID = 0xff ++} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; ++ ++typedef enum _ENUM_WMTDSNS_TYPE_T { ++ WMTDSNS_FM_DISABLE = 0, ++ WMTDSNS_FM_ENABLE = 1, ++ WMTDSNS_FM_GPS_DISABLE = 2, ++ WMTDSNS_FM_GPS_ENABLE = 3, ++ WMTDSNS_MAX ++} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; ++ ++typedef enum _ENUM_WMTTHERM_TYPE_T { ++ WMTTHERM_ZERO = 0, ++ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, ++ WMTTHERM_READ = WMTTHERM_ENABLE + 1, ++ WMTTHERM_DISABLE = WMTTHERM_READ + 1, ++ WMTTHERM_MAX ++} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; ++ ++typedef enum _ENUM_WMTMSG_TYPE_T { ++ WMTMSG_TYPE_POWER_ON = 0, ++ WMTMSG_TYPE_POWER_OFF = 1, ++ WMTMSG_TYPE_RESET = 2, ++ WMTMSG_TYPE_STP_RDY = 3, ++ WMTMSG_TYPE_HW_FUNC_ON = 4, ++ WMTMSG_TYPE_MAX ++} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; ++ ++typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ ++ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ ++ ENUM_WMTMSG_TYPE_T, /* Message type */ ++ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client ++ can't touch this buffer after this function return. */ ++ UINT32 /* Buffer size in unit of byte */ ++); ++ ++typedef enum _SDIO_PS_OP { ++ OWN_SET = 0, ++ OWN_CLR = 1, ++ OWN_STATE = 2, ++} SDIO_PS_OP; ++ ++typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); ++ ++typedef enum _ENUM_WMTCHIN_TYPE_T { ++ WMTCHIN_CHIPID = 0x0, ++ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, ++ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, ++ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, ++ WMTCHIN_MAX, ++ ++} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; ++ ++#endif ++ ++typedef enum _ENUM_WMTRSTMSG_TYPE_T { ++ WMTRSTMSG_RESET_START = 0x0, ++ WMTRSTMSG_RESET_END = 0x1, ++ WMTRSTMSG_RESET_END_FAIL = 0x2, ++ WMTRSTMSG_RESET_MAX, ++ WMTRSTMSG_RESET_INVALID = 0xff ++} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; ++ ++typedef enum _ENUM_BT_GPS_ONOFF_STATE_T { ++ WMT_BT_ON = 0, ++ WMT_GPS_ON = 1, ++ WMT_WIFI_ON = 2, ++ WMT_FM_ON = 3, ++ WMT_BT_GPS_STATE_MAX, ++ WMT_BT_GPS_STATE_INVALID = 0xff ++} ENUM_BT_GPS_ONOFF_STATE_T, *P_ENUM_BT_GPS_ONOFF_STATE_T; ++ ++#if 1 /* moved from wmt_core.h */ ++typedef enum { ++ WMT_SDIO_SLOT_INVALID = 0, ++ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ ++ WMT_SDIO_SLOT_SDIO2 = 2, ++ WMT_SDIO_SLOT_MAX ++} WMT_SDIO_SLOT_NUM; ++ ++typedef enum { ++ WMT_SDIO_FUNC_STP = 0, ++ WMT_SDIO_FUNC_WIFI = 1, ++ WMT_SDIO_FUNC_MAX ++} WMT_SDIO_FUNC_TYPE; ++#endif ++ ++typedef INT32(*wmt_wlan_probe_cb) (VOID); ++typedef INT32(*wmt_wlan_remove_cb) (VOID); ++typedef INT32(*wmt_wlan_bus_cnt_get_cb) (VOID); ++typedef INT32(*wmt_wlan_bus_cnt_clr_cb) (VOID); ++ ++typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { ++ wmt_wlan_probe_cb wlan_probe_cb; ++ wmt_wlan_remove_cb wlan_remove_cb; ++ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; ++ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; ++} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; ++ ++#ifdef CONFIG_MTK_COMBO_ANT ++typedef enum _ENUM_WMT_ANT_RAM_CTRL_T { ++ WMT_ANT_RAM_GET_STATUS = 0, ++ WMT_ANT_RAM_DOWNLOAD = WMT_ANT_RAM_GET_STATUS + 1, ++ WMT_ANT_RAM_CTRL_MAX ++} ENUM_WMT_ANT_RAM_CTRL, *P_ENUM_WMT_ANT_RAM_CTRL; ++ ++typedef enum _ENUM_WMT_ANT_RAM_SEQ_T { ++ WMT_ANT_RAM_START_PKT = 1, ++ WMT_ANT_RAM_CONTINUE_PKT = WMT_ANT_RAM_START_PKT + 1, ++ WMT_ANT_RAM_END_PKT = WMT_ANT_RAM_CONTINUE_PKT + 1, ++ WMT_ANT_RAM_SEQ_MAX ++} ENUM_WMT_ANT_RAM_SEQ, *P_ENUM_WMT_ANT_RAM_SEQ; ++ ++typedef enum _ENUM_WMT_ANT_RAM_STATUS_T { ++ WMT_ANT_RAM_NOT_EXIST = 0, ++ WMT_ANT_RAM_EXIST = WMT_ANT_RAM_NOT_EXIST + 1, ++ WMT_ANT_RAM_DOWN_OK = WMT_ANT_RAM_EXIST + 1, ++ WMT_ANT_RAM_DOWN_FAIL = WMT_ANT_RAM_DOWN_OK + 1, ++ WMT_ANT_RAM_PARA_ERR = WMT_ANT_RAM_DOWN_FAIL + 1, ++ WMT_ANT_RAM_OP_ERR = WMT_ANT_RAM_PARA_ERR + 1, ++ WMT_ANT_RAM_MAX ++} ENUM_WMT_ANT_RAM_STATUS, *P_ENUM_WMT_ANT_RAM_STATUS; ++#endif ++ ++extern INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); ++extern INT32 mtk_wcn_wmt_wlan_unreg(VOID); ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern wmt_wlan_probe_cb mtk_wcn_wlan_probe; ++extern wmt_wlan_remove_cb mtk_wcn_wlan_remove; ++extern wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt; ++extern wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*subsystem function ctrl APIs*/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++#define WMT_EXP_HID_API_EXPORT 0 ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++ ++extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++ ++extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++ ++extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); ++ ++extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); ++/* ++return value: ++enable/disable thermal sensor function: true(1)/false(0) ++read thermal sensor function: thermal value ++ ++*/ ++extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); ++ ++extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); ++ ++#else ++#define WMT_EXP_HID_API_EXPORT 1 ++#endif ++ ++#ifdef CONFIG_MTK_COMBO_ANT ++extern ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, ++ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq); ++#endif ++extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ ++extern VOID wmt_lib_ps_irq_cb(VOID); ++ ++extern VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type); ++ ++extern INT32 mtk_wcn_wmt_system_state_reset(VOID); ++extern MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value); ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++extern VOID mtk_wcn_wmt_exp_init(VOID); ++extern VOID mtk_wcn_wmt_exp_deinit(VOID); ++#endif ++extern INT8 mtk_wcn_wmt_co_clock_flag_get(VOID); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_EXP_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h +new file mode 100644 +index 000000000000..075496cac54f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h +@@ -0,0 +1,295 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_PLAT_H_ ++#define _WMT_PLAT_H_ ++#include "osal_typedef.h" ++#include "stp_exp.h" ++#include ++ ++/* #include "mtk_wcn_consys_hw.h" */ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if 1 /* moved from wmt_exp.h */ ++#ifndef DFT_TAG ++#define DFT_TAG "[WMT-DFT]" ++#endif ++ ++#define WMT_PLAT_LOG_LOUD 4 ++#define WMT_PLAT_LOG_DBG 3 ++#define WMT_PLAT_LOG_INFO 2 ++#define WMT_PLAT_LOG_WARN 1 ++#define WMT_PLAT_LOG_ERR 0 ++ ++extern UINT32 wmtPlatLogLvl; ++ ++#define WMT_PLAT_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_LOUD) \ ++ pr_debug(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_PLAT_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_INFO) \ ++ pr_debug(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_PLAT_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_WARN) \ ++ pr_warn(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_PLAT_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_ERR) \ ++ pr_err(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define WMT_PLAT_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_DBG) \ ++ pr_debug(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++ ++#endif ++ ++#define CFG_WMT_PS_SUPPORT 1 /* moved from wmt_exp.h */ ++ ++#define CFG_WMT_DUMP_INT_STATUS 0 ++#define CONSYS_ENALBE_SET_JTAG 1 ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_FUNC_STATE_ { ++ FUNC_ON = 0, ++ FUNC_OFF = 1, ++ FUNC_RST = 2, ++ FUNC_STAT = 3, ++ FUNC_CTRL_MAX, ++} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE; ++ ++typedef enum _ENUM_PIN_ID_ { ++ PIN_BGF_EINT = 0, ++ PIN_I2S_GRP = 1, ++ PIN_GPS_SYNC = 2, ++ PIN_GPS_LNA = 3, ++#if CFG_WMT_LTE_COEX_HANDLING ++ PIN_TDM_REQ = 4, ++#endif ++ PIN_ID_MAX ++} ENUM_PIN_ID, *P_ENUM_PIN_ID; ++ ++typedef enum _ENUM_PIN_STATE_ { ++ PIN_STA_INIT = 0, ++ PIN_STA_OUT_L = 1, ++ PIN_STA_OUT_H = 2, ++ PIN_STA_IN_L = 3, ++ PIN_STA_MUX = 4, ++ PIN_STA_EINT_EN = 5, ++ PIN_STA_EINT_DIS = 6, ++ PIN_STA_DEINIT = 7, ++ PIN_STA_SHOW = 8, ++ PIN_STA_MAX ++} ENUM_PIN_STATE, *P_ENUM_PIN_STATE; ++ ++typedef enum _CMB_IF_TYPE_ { ++ CMB_IF_UART = 0, ++ CMB_IF_WIFI_SDIO = 1, ++ CMB_IF_BGF_SDIO = 2, ++ CMB_IF_BGWF_SDIO = 3, ++ CMB_IF_TYPE_MAX ++} CMB_IF_TYPE, *P_CMB_IF_TYPE; ++ ++typedef INT32(*fp_set_pin) (ENUM_PIN_STATE); ++ ++typedef enum _ENUM_WL_OP_ { ++ WL_OP_GET = 0, ++ WL_OP_PUT = 1, ++ WL_OP_MAX ++} ENUM_WL_OP, *P_ENUM_WL_OP; ++ ++typedef enum _ENUM_PALDO_TYPE_ { ++ BT_PALDO = 0, ++ WIFI_PALDO = 1, ++ FM_PALDO = 2, ++ GPS_PALDO = 3, ++ PMIC_CHIPID_PALDO = 4, ++ WIFI_5G_PALDO = 5, ++ PALDO_TYPE_MAX ++} ENUM_PALDO_TYPE, *P_ENUM_PALDO_TYPE; ++ ++typedef enum _ENUM_PALDO_OP_ { ++ PALDO_OFF = 0, ++ PALDO_ON = 1, ++ PALDO_OP_MAX ++} ENUM_PALDO_OP, *P_ENUM_PALDO_OP; ++ ++typedef enum _ENUM_HOST_DUMP_STATE_T { ++ STP_HOST_DUMP_NOT_START = 0, ++ STP_HOST_DUMP_GET = 1, ++ STP_HOST_DUMP_GET_DONE = 2, ++ STP_HOST_DUMP_END = 3, ++ STP_HOST_DUMP_MAX ++} ENUM_HOST_DUMP_STATE, *P_ENUM_HOST_DUMP_STATE_T; ++ ++typedef enum _ENUM_FORCE_TRG_ASSERT_T { ++ STP_FORCE_TRG_ASSERT_EMI = 0, ++ STP_FORCE_TRG_ASSERT_DEBUG_PIN = 1, ++ STP_FORCE_TRG_ASSERT_MAX = 2 ++} ENUM_FORCE_TRG_ASSERT_T, *P_ENUM_FORCE_TRG_ASSERT_T; ++ ++typedef enum _ENUM_CHIP_DUMP_STATE_T { ++ STP_CHIP_DUMP_NOT_START = 0, ++ STP_CHIP_DUMP_PUT = 1, ++ STP_CHIP_DUMP_PUT_DONE = 2, ++ STP_CHIP_DUMP_END = 3, ++ STP_CHIP_DUMP_MAX ++} ENUM_CHIP_DUMP_STATE, *P_ENUM_CHIP_DUMP_STATE_T; ++ ++typedef struct _EMI_CTRL_STATE_OFFSET_ { ++ UINT32 emi_apmem_ctrl_state; ++ UINT32 emi_apmem_ctrl_host_sync_state; ++ UINT32 emi_apmem_ctrl_host_sync_num; ++ UINT32 emi_apmem_ctrl_chip_sync_state; ++ UINT32 emi_apmem_ctrl_chip_sync_num; ++ UINT32 emi_apmem_ctrl_chip_sync_addr; ++ UINT32 emi_apmem_ctrl_chip_sync_len; ++ UINT32 emi_apmem_ctrl_chip_print_buff_start; ++ UINT32 emi_apmem_ctrl_chip_print_buff_len; ++ UINT32 emi_apmem_ctrl_chip_print_buff_idx; ++ UINT32 emi_apmem_ctrl_chip_int_status; ++ UINT32 emi_apmem_ctrl_chip_paded_dump_end; ++ UINT32 emi_apmem_ctrl_host_outband_assert_w1; ++ UINT32 emi_apmem_ctrl_chip_page_dump_num; ++} EMI_CTRL_STATE_OFFSET, *P_EMI_CTRL_STATE_OFFSET; ++ ++typedef struct _BGF_IRQ_BALANCE_ { ++ UINT32 counter; ++ unsigned long flags; ++ spinlock_t lock; ++} BGF_IRQ_BALANCE, *P_BGF_IRQ_BALANCE; ++ ++typedef struct _CONSYS_EMI_ADDR_INFO_ { ++ UINT32 emi_phy_addr; ++ UINT32 paged_trace_off; ++ UINT32 paged_dump_off; ++ UINT32 full_dump_off; ++ P_EMI_CTRL_STATE_OFFSET p_ecso; ++} CONSYS_EMI_ADDR_INFO, *P_CONSYS_EMI_ADDR_INFO; ++ ++typedef struct _GPIO_TDM_REQ_INFO_ { ++ UINT32 ant_sel_index; ++ UINT32 gpio_number; ++ UINT32 cr_address; ++} GPIO_TDM_REQ_INFO, *P_GPIO_TDM_REQ_INFO; ++ ++typedef VOID(*irq_cb) (VOID); ++typedef INT32(*device_audio_if_cb) (CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); ++typedef VOID(*func_ctrl_cb) (UINT32 on, UINT32 type); ++typedef long (*thermal_query_ctrl_cb) (VOID); ++typedef INT32(*deep_idle_ctrl_cb) (UINT32); ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern UINT32 gWmtDbgLvl; ++extern struct device *wmt_dev; ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++extern INT32 wmt_set_pmic_voltage(UINT32 level); ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++INT32 wmt_plat_init(UINT32 co_clock_type); ++ ++INT32 wmt_plat_deinit(VOID); ++ ++INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state); ++ ++INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); ++ ++INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); ++ ++INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId); ++ ++INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); ++ ++VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb); ++VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb); ++VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl); ++VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl); ++VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl); ++ ++INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo); ++UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset); ++#if CONSYS_ENALBE_SET_JTAG ++UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en); ++#endif ++#if CFG_WMT_DUMP_INT_STATUS ++VOID wmt_plat_BGF_irq_dump_status(VOID); ++MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID); ++#endif ++P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID); ++UINT32 wmt_plat_read_cpupcr(VOID); ++UINT32 wmt_plat_read_dmaregs(UINT32); ++INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state); ++UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type); ++INT32 wmt_plat_update_host_sync_num(VOID); ++INT32 wmt_plat_get_dump_info(UINT32 offset); ++UINT32 wmt_plat_get_soc_chipid(VOID); ++INT32 wmt_plat_set_dbg_mode(UINT32 flag); ++VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf); ++#if CFG_WMT_LTE_COEX_HANDLING ++INT32 wmt_plat_get_tdm_antsel_index(VOID); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_PLAT_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile +new file mode 100644 +index 000000000000..905207118938 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile +@@ -0,0 +1,6 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++obj-y += pub/ ++obj-y += pri/ ++ ++endif +\ No newline at end of file +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h +new file mode 100644 +index 000000000000..95d1ab02a9fa +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h +@@ -0,0 +1,74 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef __BGW_DESENSE_H_ ++#define __BGW_DESENSE_H_ ++ ++#ifdef MSG ++#undef MSG ++#endif ++ ++#ifdef ERR ++#undef ERR ++#endif ++ ++#define PFX1 "[BWG] " ++#define MSG(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) ++#define ERR(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) ++ ++#ifdef NETLINK_TEST ++#undef NETLINK_TEST ++#endif ++ ++#define NETLINK_TEST 17 ++ ++#ifdef MAX_NL_MSG_LEN ++#undef MAX_NL_MSG_LEN ++#endif ++ ++#define MAX_NL_MSG_LEN 1024 ++ ++ ++#ifdef ON ++#undef ON ++#endif ++#ifdef OFF ++#undef OFF ++#endif ++#ifdef ACK ++#undef ACK ++#endif ++ ++#define ON 1 ++#define OFF 0 ++#define ACK 2 ++ ++/* ++used send command to native process ++ ++parameter: command could be macro ON: enable co-exist; OFF: disable co-exist; ++ACK: after get native process init message send ACK ++ ++*/ ++extern void send_command_to_daemon(const int command); ++ ++/* ++before use kernel socket, please call init socket first ++return value: 0: ok; -1: fail ++*/ ++extern int bgw_init_socket(void); ++ ++extern void bgw_destroy_netlink_kernel(void); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h +new file mode 100644 +index 000000000000..493a4dd16f23 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h +@@ -0,0 +1,348 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _OSAL_H_ ++#define _OSAL_H_ ++ ++#include ++#include ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define OS_BIT_OPS_SUPPORT 1 ++ ++#define _osal_inline_ inline ++ ++#define MAX_THREAD_NAME_LEN 16 ++#define MAX_WAKE_LOCK_NAME_LEN 16 ++#define OSAL_OP_BUF_SIZE 64 ++ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) ++#define OSAL_OP_DATA_SIZE 8 ++#else ++#define OSAL_OP_DATA_SIZE 32 ++#endif ++ ++#define DBG_LOG_STR_SIZE 256 ++ ++#define osal_sizeof(x) sizeof(x) ++ ++#define osal_array_size(x) (sizeof(x)/sizeof(x[0])) ++ ++#ifndef NAME_MAX ++#define NAME_MAX 256 ++#endif ++ ++#define WMT_OP_BIT(x) (0x1UL << x) ++#define WMT_OP_HIF_BIT WMT_OP_BIT(0) ++ ++#define RB_SIZE(prb) ((prb)->size) ++#define RB_MASK(prb) (RB_SIZE(prb) - 1) ++#define RB_COUNT(prb) ((prb)->write - (prb)->read) ++#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) ++#define RB_EMPTY(prb) ((prb)->write == (prb)->read) ++ ++#define RB_INIT(prb, qsize) \ ++do { \ ++ (prb)->read = (prb)->write = 0; \ ++ (prb)->size = (qsize); \ ++} while (0) ++ ++#define RB_PUT(prb, value) \ ++do { \ ++ if (!RB_FULL(prb)) { \ ++ (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ ++ ++((prb)->write); \ ++ } \ ++ else { \ ++ osal_assert(!RB_FULL(prb)); \ ++ } \ ++} while (0) ++ ++#define RB_GET(prb, value) \ ++do { \ ++ if (!RB_EMPTY(prb)) { \ ++ value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ ++ ++((prb)->read); \ ++ if (RB_EMPTY(prb)) { \ ++ (prb)->read = (prb)->write = 0; \ ++ } \ ++ } \ ++ else { \ ++ value = NULL; \ ++ osal_assert(!RB_EMPTY(prb)); \ ++ } \ ++} while (0) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef VOID(*P_TIMEOUT_HANDLER) (unsigned long); ++typedef INT32(*P_COND) (VOID *); ++ ++typedef struct _OSAL_TIMER_ { ++ struct timer_list timer; ++ P_TIMEOUT_HANDLER timeoutHandler; ++ unsigned long timeroutHandlerData; ++} OSAL_TIMER, *P_OSAL_TIMER; ++ ++typedef struct _OSAL_UNSLEEPABLE_LOCK_ { ++ spinlock_t lock; ++ unsigned long flag; ++} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; ++ ++typedef struct _OSAL_SLEEPABLE_LOCK_ { ++ struct mutex lock; ++} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; ++ ++typedef struct _OSAL_SIGNAL_ { ++ struct completion comp; ++ UINT32 timeoutValue; ++} OSAL_SIGNAL, *P_OSAL_SIGNAL; ++ ++typedef struct _OSAL_EVENT_ { ++ wait_queue_head_t waitQueue; ++/* VOID *pWaitQueueData; */ ++ UINT32 timeoutValue; ++ INT32 waitFlag; ++ ++} OSAL_EVENT, *P_OSAL_EVENT; ++ ++typedef struct _OSAL_THREAD_ { ++ struct task_struct *pThread; ++ VOID *pThreadFunc; ++ VOID *pThreadData; ++ char threadName[MAX_THREAD_NAME_LEN]; ++} OSAL_THREAD, *P_OSAL_THREAD; ++ ++typedef struct _OSAL_FIFO_ { ++ /*fifo definition */ ++ VOID *pFifoBody; ++ spinlock_t fifoSpinlock; ++ /*fifo operations */ ++ INT32 (*FifoInit)(struct _OSAL_FIFO_ *pFifo, UINT8 *buf, UINT32); ++ INT32 (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoReset)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoSz)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoLen)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const VOID *buf, UINT32 len); ++ INT32 (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, UINT32 len); ++} OSAL_FIFO, *P_OSAL_FIFO; ++ ++typedef struct firmware osal_firmware; ++ ++typedef struct _OSAL_OP_DAT { ++ UINT32 opId; /* Event ID */ ++ UINT32 u4InfoBit; /* Reserved */ ++ SIZE_T au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ ++} OSAL_OP_DAT, *P_OSAL_OP_DAT; ++ ++typedef struct _OSAL_LXOP_ { ++ OSAL_OP_DAT op; ++ OSAL_SIGNAL signal; ++ INT32 result; ++} OSAL_OP, *P_OSAL_OP; ++ ++typedef struct _OSAL_LXOP_Q { ++ OSAL_SLEEPABLE_LOCK sLock; ++ UINT32 write; ++ UINT32 read; ++ UINT32 size; ++ P_OSAL_OP queue[OSAL_OP_BUF_SIZE]; ++} OSAL_OP_Q, *P_OSAL_OP_Q; ++ ++typedef struct _OSAL_WAKE_LOCK_ { ++ #ifdef CONFIG_PM_WAKELOCKS ++ struct wakeup_source wake_lock; ++ #else ++ struct wake_lock wake_lock; ++ #endif ++ UINT8 name[MAX_WAKE_LOCK_NAME_LEN]; ++} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK; ++#if 1 ++typedef struct _OSAL_BIT_OP_VAR_ { ++ unsigned long data; ++ OSAL_UNSLEEPABLE_LOCK opLock; ++} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; ++#else ++#define OSAL_BIT_OP_VAR unsigned long ++#define P_OSAL_BIT_OP_VAR unsigned long * ++ ++#endif ++typedef UINT32(*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread); ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern UINT32 osal_strlen(const char *str); ++extern INT32 osal_strcmp(const char *dst, const char *src); ++extern INT32 osal_strncmp(const char *dst, const char *src, UINT32 len); ++extern char *osal_strcpy(char *dst, const char *src); ++extern char *osal_strncpy(char *dst, const char *src, UINT32 len); ++extern char *osal_strcat(char *dst, const char *src); ++extern char *osal_strncat(char *dst, const char *src, UINT32 len); ++extern char *osal_strchr(const char *str, UINT8 c); ++extern char *osal_strsep(char **str, const char *c); ++extern int osal_strtol(const char *str, UINT32 adecimal, long *res); ++extern INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...); ++extern char *osal_strstr(char *str1, const char *str2); ++ ++extern INT32 osal_err_print(const char *str, ...); ++extern INT32 osal_dbg_print(const char *str, ...); ++extern INT32 osal_warn_print(const char *str, ...); ++ ++extern INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line); ++extern INT32 osal_sprintf(char *str, const char *format, ...); ++extern VOID *osal_malloc(UINT32 size); ++extern VOID osal_free(const VOID *dst); ++extern VOID *osal_memset(VOID *buf, INT32 i, UINT32 len); ++extern VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len); ++extern INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len); ++ ++extern INT32 osal_sleep_ms(UINT32 ms); ++extern INT32 osal_udelay(UINT32 us); ++extern INT32 osal_timer_create(P_OSAL_TIMER); ++extern INT32 osal_timer_start(P_OSAL_TIMER, UINT32); ++extern INT32 osal_timer_stop(P_OSAL_TIMER); ++extern INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer); ++extern INT32 osal_timer_modify(P_OSAL_TIMER, UINT32); ++extern INT32 osal_timer_delete(P_OSAL_TIMER); ++ ++extern INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size); ++extern VOID osal_fifo_deinit(P_OSAL_FIFO pFifo); ++extern INT32 osal_fifo_reset(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); ++extern UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); ++extern UINT32 osal_fifo_len(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo); ++ ++extern INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_lock(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK plock); ++ ++#if defined(CONFIG_PROVE_LOCKING) ++#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); } ++#else ++extern INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK); ++#endif ++extern INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); ++extern INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); ++extern INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK); ++ ++#if defined(CONFIG_PROVE_LOCKING) ++#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); } ++#else ++extern INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK); ++#endif ++extern INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); ++extern INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); ++extern INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK); ++ ++extern INT32 osal_signal_init(P_OSAL_SIGNAL); ++extern INT32 osal_wait_for_signal(P_OSAL_SIGNAL); ++extern INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL); ++extern INT32 osal_raise_signal(P_OSAL_SIGNAL); ++extern INT32 osal_signal_deinit(P_OSAL_SIGNAL); ++ ++extern INT32 osal_event_init(P_OSAL_EVENT); ++extern INT32 osal_wait_for_event(P_OSAL_EVENT, P_COND, void *); ++extern INT32 osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void *); ++extern INT32 osal_trigger_event(P_OSAL_EVENT); ++ ++extern INT32 osal_event_deinit(P_OSAL_EVENT); ++ ++extern INT32 osal_thread_create(P_OSAL_THREAD); ++extern INT32 osal_thread_run(P_OSAL_THREAD); ++extern INT32 osal_thread_should_stop(P_OSAL_THREAD); ++extern INT32 osal_thread_stop(P_OSAL_THREAD); ++/*extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/ ++extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER); ++/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/ ++extern INT32 osal_thread_destroy(P_OSAL_THREAD); ++ ++extern INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++ ++extern INT32 osal_dbg_assert_aee(const char *module, const char *detail_description); ++extern INT32 osal_gettimeofday(PINT32 sec, PINT32 usec); ++extern INT32 osal_printtimeofday(const PUINT8 prefix); ++ ++extern VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, UINT32 len, UINT32 limit); ++ ++extern UINT32 osal_op_get_id(P_OSAL_OP pOp); ++extern MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp); ++extern VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result); ++extern VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result); ++extern UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length); ++extern VOID osal_thread_show_stack(P_OSAL_THREAD pThread); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#define osal_assert(condition) \ ++do { \ ++ if (!(condition)) \ ++ osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition); \ ++} while (0) ++ ++#endif /* _OSAL_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h +new file mode 100644 +index 000000000000..b3a9c57e062d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h +@@ -0,0 +1,90 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _OSAL_TYPEDEF_H_ ++#define _OSAL_TYPEDEF_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_EARLYSUSPEND ++#include ++#else ++#include ++#endif ++#include ++#include ++#ifdef WMT_PLAT_ALPS ++#include ++#endif ++#include ++#ifdef CONFIG_PM_WAKELOCKS ++#include ++#else ++#include ++#endif ++#include ++ ++#ifndef _TYPEDEFS_H /*fix redifine */ ++typedef char INT8; ++#endif ++ ++typedef void VOID, *PVOID, **PPVOID; ++typedef char *PINT8, **PPINT8; ++typedef short INT16, *PINT16, **PPINT16; ++typedef int INT32, *PINT32, **PPINT32; ++typedef long long INT64, *PINT64, **PPINT64; ++ ++typedef unsigned char UINT8, *PUINT8, **PPUINT8; ++typedef unsigned short UINT16, *PUINT16, **PPUINT16; ++typedef unsigned int UINT32, *PUINT32, **PPUINT32; ++typedef unsigned long long UINT64, *PUINT64, **PPUINT64; ++ ++typedef size_t SIZE_T; ++ ++typedef int MTK_WCN_BOOL; ++#ifndef MTK_WCN_BOOL_TRUE ++#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) ++#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) ++#endif ++ ++#endif /*_OSAL_TYPEDEF_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h +new file mode 100644 +index 000000000000..17be778484c1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h +@@ -0,0 +1,97 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_IDC_H_ ++#define _WMT_IDC_H_ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_stp_exp.h" ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ ++#include "wmt_stp_exp.h" ++#include "conn_md_exp.h" ++ ++#define LTE_IDC_BUFFER_MAX_SIZE 1024 ++/*comment from firmware owner,max pckage num is 5,but should not happened*/ ++#define WMT_IDC_RX_MAX_LEN 384 ++#define LTE_MSG_ID_OFFSET 0x30 ++ ++typedef enum { ++ WMT_IDC_TX_OPCODE_MIN = 0, ++ WMT_IDC_TX_OPCODE_LTE_PARA = 0x0a, ++ WMT_IDC_TX_OPCODE_LTE_FREQ = 0x0b, ++ WMT_IDC_TX_OPCODE_WIFI_MAX_POWER = 0x0c, ++ WMT_IDC_TX_OPCODE_DEBUG_MONITOR = 0x0e, ++ WMT_IDC_TX_OPCODE_SPLIT_FILTER = 0x0f, ++ WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS = 0x16, ++ WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION = 0x17, ++ WMT_IDC_TX_OPCODE_LTE_INDICATION = 0x20, ++ WMT_IDC_TX_OPCODE_MAX ++} WMT_IDC_TX_OPCODE; ++ ++typedef enum { ++ WMT_IDC_RX_OPCODE_BTWF_DEF_PARA = 0x0, ++ WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN = 0x1, ++ /* WMT_IDC_RX_OPCODE_TDM_REQ = 0x10, */ ++ WMT_IDC_RX_OPCODE_DEBUG_MONITOR = 0x02, ++ WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE = 0x03, ++ WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND = 0x04, ++ WMT_IDC_RX_OPCODE_UART_PIN_SEL = 0x05, ++ WMT_IDC_RX_OPCODE_MAX ++} WMT_IDC_RX_OPCODE; ++ ++#if (CFG_WMT_LTE_ENABLE_MSGID_MAPPING == 0) ++typedef enum { ++ IPC_L4C_MSG_ID_INVALID = IPC_L4C_MSG_ID_BEGIN, ++ IPC_L4C_MSG_ID_END, ++ IPC_EL1_MSG_ID_INVALID = IPC_EL1_MSG_ID_BEGIN, ++ /* below are EL1 IPC messages sent from AP */ ++ IPC_MSG_ID_EL1_LTE_TX_ALLOW_IND, ++ IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND, ++ IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND, ++ IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND, ++ IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND, ++ ++ /* below are EL1 messages sent to AP */ ++ IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, ++ IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, ++ IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, ++ IPC_MSG_ID_EL1_LTE_TX_IND, ++ IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND, ++ IPC_MSG_ID_EL1_PIN_TYPE_IND, ++ IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND, ++ IPC_MSG_ID_EL1_DUMMY13_IND, ++ IPC_MSG_ID_EL1_DUMMY14_IND, ++ IPC_MSG_ID_EL1_DUMMY15_IND, ++ IPC_EL1_MSG_ID_END, ++} IPC_MSG_ID_CODE; ++#endif ++ ++typedef struct _MTK_WCN_WMT_IDC_INFO_ { ++ ipc_ilm_t iit; ++ CONN_MD_BRIDGE_OPS ops; ++ UINT8 buffer[LTE_IDC_BUFFER_MAX_SIZE]; ++} MTK_WCN_WMT_IDC_INFO, *P_MTK_WCN_WMT_IDC_INFO; ++ ++extern INT32 wmt_idc_init(VOID); ++extern INT32 wmt_idc_deinit(VOID); ++extern INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm); ++extern INT32 wmt_idc_msg_to_lte_handing(VOID); ++extern UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len); ++ ++#endif /* endif CFG_WMT_LTE_COEX_HANDLING */ ++ ++#endif /* _WMT_IDC_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile +new file mode 100644 +index 000000000000..ff0f0b0aefda +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile +@@ -0,0 +1,21 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++ccflags-y += \ ++ -I$(src)/../../linux/include \ ++ -I$(src)/../../linux/pri/include \ ++ -I$(src)/../../core/include \ ++ -I$(src)/../../include \ ++ -I$(src)/../include \ ++ -I$(src)/../../../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ ++ -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach ++ ++ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 ++ ++obj-y += stp_btif.o \ ++ stp_dbg.o \ ++ stp_exp.o \ ++ wmt_dev.o \ ++ wmt_exp.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h +new file mode 100644 +index 000000000000..3730fbba6928 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h +@@ -0,0 +1,31 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _STP_BTIF_H_ ++#define _STP_BTIF_H_ ++ ++#include "osal_typedef.h" ++#include "mtk_btif_exp.h" ++ ++extern INT32 mtk_wcn_consys_stp_btif_open(VOID); ++extern INT32 mtk_wcn_consys_stp_btif_close(VOID); ++extern INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb); ++extern INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len); ++extern INT32 mtk_wcn_consys_stp_btif_wakeup(VOID); ++extern INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); ++extern INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); ++extern INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag); ++extern MTK_WCN_BOOL mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h +new file mode 100644 +index 000000000000..de5684a16853 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h +@@ -0,0 +1,316 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _STP_DEBUG_H_ ++#define _STP_DEBUG_H_ ++ ++#include ++#include "osal.h" ++ ++#define CONFIG_LOG_STP_INTERNAL ++ ++#if 1 /* #ifndef CONFIG_LOG_STP_INTERNAL */ ++#define STP_PKT_SZ 16 ++#define STP_DMP_SZ 2048 ++#define STP_PKT_NO 2048 ++ ++#define STP_DBG_LOG_ENTRY_NUM 60 ++#define STP_DBG_LOG_ENTRY_SZ 64 ++ ++#else ++ ++#define STP_PKT_SZ 16 ++#define STP_DMP_SZ 16 ++#define STP_PKT_NO 16 ++ ++#define STP_DBG_LOG_ENTRY_NUM 28 ++#define STP_DBG_LOG_ENTRY_SZ 64 ++ ++#endif ++ ++typedef enum { ++ STP_DBG_EN = 0, ++ STP_DBG_PKT = 1, ++ STP_DBG_DR = 2, ++ STP_DBG_FW_ASSERT = 3, ++ STP_DBG_FW_LOG = 4, ++ STP_DBG_FW_DMP = 5, ++ STP_DBG_MAX ++} STP_DBG_OP_T; ++ ++typedef enum { ++ STP_DBG_PKT_FIL_ALL = 0, ++ STP_DBG_PKT_FIL_BT = 1, ++ STP_DBG_PKT_FIL_GPS = 2, ++ STP_DBG_PKT_FIL_FM = 3, ++ STP_DBG_PKT_FIL_WMT = 4, ++ STP_DBG_PKT_FIL_MAX ++} STP_DBG_PKT_FIL_T; ++ ++static char *const gStpDbgType[] = { ++ "< BT>", ++ "< FM>", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "" ++}; ++ ++typedef enum { ++ STP_DBG_DR_MAX = 0, ++} STP_DBG_DR_FIL_T; ++ ++typedef enum { ++ STP_DBG_FW_MAX = 0, ++} STP_DBG_FW_FIL_T; ++ ++typedef enum { ++ PKT_DIR_RX = 0, ++ PKT_DIR_TX ++} STP_DBG_PKT_DIR_T; ++ ++/*simple log system ++*/ ++ ++typedef struct { ++ /*type: 0. pkt trace 1. fw info ++ * 2. assert info 3. trace32 dump . ++ * -1. linked to the the previous ++ */ ++ int id; ++ int len; ++ char buffer[STP_DBG_LOG_ENTRY_SZ]; ++} MTKSTP_LOG_ENTRY_T; ++ ++typedef struct log_sys { ++ MTKSTP_LOG_ENTRY_T queue[STP_DBG_LOG_ENTRY_NUM]; ++ unsigned int size; ++ unsigned int in; ++ unsigned int out; ++ spinlock_t lock; ++} MTKSTP_LOG_SYS_T; ++/*--*/ ++ ++typedef struct stp_dbg_pkt_hdr { ++ /* packet information */ ++ unsigned int sec; ++ unsigned int usec; ++ unsigned int dbg_type; ++ unsigned int dmy; ++ unsigned int no; ++ unsigned int dir; ++ ++ /* packet content */ ++ unsigned int type; ++ unsigned int len; ++ unsigned int ack; ++ unsigned int seq; ++ unsigned int chs; ++ unsigned int crc; ++} STP_DBG_HDR_T; ++ ++typedef struct stp_dbg_pkt { ++ struct stp_dbg_pkt_hdr hdr; ++ unsigned char raw[STP_DMP_SZ]; ++} STP_PACKET_T; ++ ++typedef struct mtkstp_dbg_t { ++ /*log_sys */ ++ int pkt_trace_no; ++ void *btm; ++ int is_enable; ++ MTKSTP_LOG_SYS_T *logsys; ++} MTKSTP_DBG_T; ++ ++/* extern void aed_combo_exception(const int *, int, const int *, int, const char *); */ ++ ++#define STP_CORE_DUMP_TIMEOUT (5*60*1000) /* default 5minutes */ ++#define STP_OJB_NAME_SZ 20 ++#define STP_CORE_DUMP_INFO_SZ 500 ++#define STP_CORE_DUMP_INIT_SIZE 1 ++typedef enum wcn_compress_algorithm_t { ++ GZIP = 0, ++ BZIP2 = 1, ++ RAR = 2, ++ LMA = 3, ++ MAX ++} WCN_COMPRESS_ALG_T; ++ ++typedef INT32 (*COMPRESS_HANDLER) (void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, ++ INT32 finish); ++typedef struct wcn_compressor_t { ++ /* current object name */ ++ UINT8 name[STP_OJB_NAME_SZ + 1]; ++ ++ /* buffer for raw data, named L1 */ ++ PUINT8 L1_buf; ++ INT32 L1_buf_sz; ++ INT32 L1_pos; ++ ++ /* target buffer, named L2 */ ++ PUINT8 L2_buf; ++ INT32 L2_buf_sz; ++ INT32 L2_pos; ++ ++ /* compress state */ ++ UINT8 f_done; ++ UINT16 reserved; ++ UINT32 uncomp_size; ++ UINT32 crc32; ++ ++ /* compress algorithm */ ++ UINT8 f_compress_en; ++ WCN_COMPRESS_ALG_T compress_type; ++ void *worker; ++ COMPRESS_HANDLER handler; ++} WCN_COMPRESSOR_T, *P_WCN_COMPRESSOR_T; ++ ++P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz); ++INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T compressor); ++INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T compressor, PUINT8 buf, INT32 len, INT32 finish); ++INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T compressor, PUINT8 *pbuf, PINT32 len); ++INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T compressor, UINT8 enable, WCN_COMPRESS_ALG_T type); ++ ++typedef enum core_dump_state_t { ++ CORE_DUMP_INIT = 0, ++ CORE_DUMP_DOING, ++ CORE_DUMP_TIMEOUT, ++ CORE_DUMP_DONE, ++ CORE_DUMP_MAX ++} CORE_DUMP_STA; ++ ++typedef struct core_dump_t { ++ /* compress dump data and buffered */ ++ P_WCN_COMPRESSOR_T compressor; ++ ++ /* timer for monitor timeout */ ++ OSAL_TIMER dmp_timer; ++ UINT32 timeout; ++ ++ OSAL_SLEEPABLE_LOCK dmp_lock; ++ ++ /* state machine for core dump flow */ ++ CORE_DUMP_STA sm; ++ ++ /* dump info */ ++ INT8 info[STP_CORE_DUMP_INFO_SZ + 1]; ++} WCN_CORE_DUMP_T, *P_WCN_CORE_DUMP_T; ++ ++typedef enum _ENUM_STP_FW_ISSUE_TYPE_ { ++ STP_FW_ISSUE_TYPE_INVALID = 0x0, ++ STP_FW_ASSERT_ISSUE = 0x1, ++ STP_FW_NOACK_ISSUE = 0x2, ++ STP_FW_WARM_RST_ISSUE = 0x3, ++ STP_DBG_PROC_TEST = 0x4, ++ STP_HOST_TRIGGER_FW_ASSERT = 0x5, ++ STP_HOST_TRIGGER_ASSERT_TIMEOUT = 0x6, ++ STP_FW_ISSUE_TYPE_MAX ++} ENUM_STP_FW_ISSUE_TYPE, *P_ENUM_STP_FW_ISSUE_TYPE; ++ ++/* this was added for support dmareg's issue */ ++typedef enum _ENUM_DMA_ISSUE_TYPE_ { ++ CONNSYS_CLK_GATE_STATUS = 0x00, ++ CONSYS_EMI_STATUS, ++ SYSRAM1, ++ SYSRAM2, ++ SYSRAM3, ++ DMA_REGS_MAX ++} ENUM_DMA_ISSUE_TYPE; ++#define STP_PATCH_TIME_SIZE 12 ++#define STP_DBG_CPUPCR_NUM 512 ++#define STP_DBG_DMAREGS_NUM 16 ++#define STP_PATCH_BRANCH_SZIE 8 ++#define STP_ASSERT_INFO_SIZE 64 ++#define STP_DBG_ROM_VER_SIZE 4 ++#define STP_ASSERT_TYPE_SIZE 32 ++ ++typedef struct stp_dbg_host_assert_t { ++ UINT32 drv_type; ++ UINT32 reason; ++ UINT32 assert_from_host; ++} STP_DBG_HOST_ASSERT_T, *P_STP_DBG_HOST_ASSERT_T; ++ ++typedef struct stp_dbg_cpupcr_t { ++ UINT32 chipId; ++ UINT8 romVer[STP_DBG_ROM_VER_SIZE]; ++ UINT8 patchVer[STP_PATCH_TIME_SIZE]; ++ UINT8 branchVer[STP_PATCH_BRANCH_SZIE]; ++ UINT32 wifiVer; ++ UINT32 count; ++ UINT32 stop_flag; ++ UINT32 buffer[STP_DBG_CPUPCR_NUM]; ++ UINT8 assert_info[STP_ASSERT_INFO_SIZE]; ++ UINT32 fwTaskId; ++ UINT32 fwRrq; ++ UINT32 fwIsr; ++ STP_DBG_HOST_ASSERT_T host_assert_info; ++ UINT8 assert_type[STP_ASSERT_TYPE_SIZE]; ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ OSAL_SLEEPABLE_LOCK lock; ++} STP_DBG_CPUPCR_T, *P_STP_DBG_CPUPCR_T; ++ ++typedef struct stp_dbg_dmaregs_t { ++ UINT32 count; ++ UINT32 dmaIssue[DMA_REGS_MAX][STP_DBG_DMAREGS_NUM]; ++ OSAL_SLEEPABLE_LOCK lock; ++} STP_DBG_DMAREGS_T, *P_STP_DBG_DMAREGS_T; ++ ++typedef enum _ENUM_ASSERT_INFO_PARSER_TYPE_ { ++ STP_DBG_ASSERT_INFO = 0x0, ++ STP_DBG_FW_TASK_ID = 0x1, ++ STP_DBG_FW_ISR = 0x2, ++ STP_DBG_FW_IRQ = 0x3, ++ STP_DBG_ASSERT_TYPE = 0x4, ++ STP_DBG_PARSER_TYPE_MAX ++} ENUM_ASSERT_INFO_PARSER_TYPE, *P_ENUM_ASSERT_INFO_PARSER_TYPE; ++ ++P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout); ++INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp); ++INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len); ++INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 len); ++INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout); ++INT32 wcn_core_dump_timeout(void); ++INT32 wcn_wmtd_timeout_collect_ftrace(void); ++ ++extern INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout); ++extern INT32 wcn_core_dump_deinit_gcoredump(VOID); ++extern INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL is_coredump_timeout); ++extern int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg); ++extern int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg); ++extern MTKSTP_DBG_T *stp_dbg_init(void *); ++extern int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg); ++extern int stp_dbg_dmp_out_ex(char *buf, int *len); ++extern int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len); ++extern int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg); ++extern char stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len); ++ ++extern INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd); ++extern INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len); ++extern int ++stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, ++ int dbg_type, int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body); ++extern int stp_dbg_log_ctrl(unsigned int on); ++extern INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); ++extern INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep); ++extern INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en); ++extern INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer, ++ PUINT8 pPatchBrh); ++extern INT32 stp_dbg_set_wifiver(UINT32 wifiver); ++extern INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 len); ++extern INT32 stp_dbg_set_fw_info(PUINT8 assert_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type); ++extern INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en); ++extern UINT32 stp_dbg_get_host_trigger_assert(VOID); ++#endif /* end of _STP_DEBUG_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h +new file mode 100644 +index 000000000000..5788eb355549 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h +@@ -0,0 +1,71 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_DEV_H_ ++#define _WMT_DEV_H_ ++ ++#include "osal.h" ++ ++#define STP_UART_FULL 0x01 ++#define STP_UART_MAND 0x02 ++#define STP_BTIF_FULL 0x03 ++#define STP_SDIO 0x04 ++ ++#define CFG_WMT_DBG_SUPPORT 1 /* support wmt_dbg or not */ ++#define CFG_WMT_PROC_FOR_AEE 1 ++ ++extern VOID wmt_dev_rx_event_cb(VOID); ++extern INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent); ++extern INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf); ++extern INT32 wmt_dev_patch_put(osal_firmware **ppPatch); ++extern VOID wmt_dev_patch_info_free(VOID); ++extern VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd); ++extern MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID); ++ ++#if CFG_WMT_DBG_SUPPORT ++typedef struct _COEX_BUF { ++ UINT8 buffer[128]; ++ INT32 availSize; ++} COEX_BUF, *P_COEX_BUF; ++ ++typedef enum _ENUM_CMD_TYPE_T { ++ WMTDRV_CMD_ASSERT = 0, ++ WMTDRV_CMD_EXCEPTION = 1, ++ WMTDRV_CMD_COEXDBG_00 = 2, ++ WMTDRV_CMD_COEXDBG_01 = 3, ++ WMTDRV_CMD_COEXDBG_02 = 4, ++ WMTDRV_CMD_COEXDBG_03 = 5, ++ WMTDRV_CMD_COEXDBG_04 = 6, ++ WMTDRV_CMD_COEXDBG_05 = 7, ++ WMTDRV_CMD_COEXDBG_06 = 8, ++ WMTDRV_CMD_COEXDBG_07 = 9, ++ WMTDRV_CMD_COEXDBG_08 = 10, ++ WMTDRV_CMD_COEXDBG_09 = 11, ++ WMTDRV_CMD_COEXDBG_10 = 12, ++ WMTDRV_CMD_COEXDBG_11 = 13, ++ WMTDRV_CMD_COEXDBG_12 = 14, ++ WMTDRV_CMD_COEXDBG_13 = 15, ++ WMTDRV_CMD_COEXDBG_14 = 16, ++ WMTDRV_CMD_COEXDBG_15 = 17, ++ WMTDRV_CMD_NOACK_TEST = 18, ++ WMTDRV_CMD_WARNRST_TEST = 19, ++ WMTDRV_CMD_FWTRACE_TEST = 20, ++ WMTDRV_CMD_MAX ++} ENUM_WMTDRV_CMD_T, *P_ENUM_WMTDRV_CMD_T; ++ ++#endif ++ ++typedef INT32(*WMT_DEV_DBG_FUNC) (INT32 par1, INT32 par2, INT32 par3); ++ ++#endif /*_WMT_DEV_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c +new file mode 100644 +index 000000000000..76debb4674f9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c +@@ -0,0 +1,279 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*file: stp_btif, mainly control stp & btif interaction*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[STP-BTIF]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "wmt_exp.h" ++#include "stp_exp.h" ++#include "stp_btif.h" ++ ++#include ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define BTIF_OWNER_NAME "CONSYS_STP" ++ ++#define STP_MAX_PACKAGE_ALLOWED (2000) ++ ++#define STP_BTIF_TX_RTY_LMT (10) ++#define STP_BTIF_TX_RTY_DLY (5) ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++unsigned long stpBtifId = 0; ++unsigned long *pBtifRef = &stpBtifId; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++INT32 mtk_wcn_consys_stp_btif_open(VOID) ++{ ++ INT32 iRet = -1; ++ ++ iRet = mtk_wcn_btif_open(BTIF_OWNER_NAME, pBtifRef); ++ if (iRet) { ++ WMT_WARN_FUNC("STP open btif fail(%d)\n", iRet); ++ return -1; ++ } ++ WMT_DBG_FUNC("STP open bitf OK\n"); ++ ++ mtk_wcn_stp_register_if_tx(STP_BTIF_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_consys_stp_btif_tx); ++ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_close(VOID) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_close(stpBtifId); ++ if (iRet) { ++ WMT_WARN_FUNC("STP close btif fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ stpBtifId = 0; ++ WMT_DBG_FUNC("STP close btif OK\n"); ++ } ++ } ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference\n!"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_rx_cb_register(stpBtifId, rx_cb); ++ if (iRet) { ++ WMT_WARN_FUNC("STP register rxcb to btif fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_DBG_FUNC("STP register rxcb to btif OK\n"); ++ } ++ } ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len) ++{ ++ INT32 retry_left = STP_BTIF_TX_RTY_LMT; ++ INT32 wr_count = 0; ++ INT32 written = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ return -1; ++ } ++ ++ if (len == 0) { ++ *written_len = 0; ++ WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf); ++ return 0; ++ } ++ ++ *written_len = 0; ++ ++ if (len > STP_MAX_PACKAGE_ALLOWED) { ++ WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm); ++ return -2; ++ } ++ wr_count = mtk_wcn_btif_write(stpBtifId, pBuf, len); ++ ++ if (wr_count < 0) { ++ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count); ++ *written_len = 0; ++ return -3; ++ } ++ if (wr_count == len) { ++ /*perfect case */ ++ *written_len = wr_count; ++ return wr_count; ++ } ++ ++ while ((retry_left--) && (wr_count < len)) { ++ osal_sleep_ms(STP_BTIF_TX_RTY_DLY); ++ written = mtk_wcn_btif_write(stpBtifId, pBuf + wr_count, len - wr_count); ++ if (written < 0) { ++ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written); ++ break; ++ } ++ wr_count += written; ++ } ++ ++ if (wr_count == len) { ++ WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left); ++ /*recovered case */ ++ *written_len = wr_count; ++ return wr_count; ++ } ++ ++ WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n", ++ len, wr_count, retry_left, current->pid, current->comm); ++ *written_len = 0; ++ return -wr_count; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_rx(UINT8 *pBuf, UINT32 len) ++{ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_wakeup(VOID) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_wakeup_consys(stpBtifId); ++ if (iRet) { ++ WMT_WARN_FUNC("STP btif wakeup consys fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_DBG_FUNC("STP btif wakeup consys ok\n"); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ mtk_wcn_btif_dpidle_ctrl(stpBtifId, en_flag); ++ WMT_DBG_FUNC("stp btif dpidle ctrl done,en_flag(%d)\n", en_flag); ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_loopback_ctrl(stpBtifId, mode); ++ if (iRet) { ++ WMT_WARN_FUNC("STP btif lpbk ctrl fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_INFO_FUNC("stp btif lpbk ctrl ok,mode(%d)\n", mode); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_dbg_ctrl(stpBtifId, flag); ++ if (iRet) { ++ WMT_WARN_FUNC("STP btif log dbg ctrl fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_INFO_FUNC("stp btif log dbg ctrl ok,flag(%d)\n", flag); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len) ++{ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ return -1; ++ } else { ++ return (INT32) mtk_wcn_btif_parser_wmt_evt(stpBtifId, str, len); ++ } ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c +new file mode 100644 +index 000000000000..fd8e9a97a0b8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c +@@ -0,0 +1,2060 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include /* GFP_KERNEL */ ++#include /* init_timer, add_time, del_timer_sync */ ++#include /* gettimeofday */ ++#include ++#include /* kzalloc */ ++#include /* task's status */ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "osal_typedef.h" ++#include "stp_dbg.h" ++/* #include "stp_btm.h" */ ++#include "btm_core.h" ++#include "wmt_plat.h" ++ ++#define PFX_STP_DBG "[STPDbg]" ++#define STP_DBG_LOG_LOUD 4 ++#define STP_DBG_LOG_DBG 3 ++#define STP_DBG_LOG_INFO 2 ++#define STP_DBG_LOG_WARN 1 ++#define STP_DBG_LOG_ERR 0 ++ ++unsigned int gStpDbgDbgLevel = STP_DBG_LOG_INFO; ++unsigned int gStpDbgLogOut = 0; ++ ++#define STP_DBG_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_LOUD) \ ++ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ ++ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_INFO) \ ++ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_WARN) \ ++ pr_warn(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_ERR) \ ++ pr_err(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_TRC_FUNC(f) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ ++ pr_debug(PFX_STP_DBG "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++MTKSTP_DBG_T *g_stp_dbg = NULL; ++ ++#define STP_DBG_FAMILY_NAME "STP_DBG" ++#define MAX_BIND_PROCESS (4) ++#ifdef WMT_PLAT_ALPS ++#define STP_DBG_AEE_EXP_API (1) ++#else ++#define STP_DBG_AEE_EXP_API (0) ++#endif ++enum { ++ __STP_DBG_ATTR_INVALID, ++ STP_DBG_ATTR_MSG, ++ __STP_DBG_ATTR_MAX, ++}; ++#define STP_DBG_ATTR_MAX (__STP_DBG_ATTR_MAX - 1) ++ ++enum { ++ __STP_DBG_COMMAND_INVALID, ++ STP_DBG_COMMAND_BIND, ++ STP_DBG_COMMAND_RESET, ++ __STP_DBG_COMMAND_MAX, ++}; ++#define MTK_WIFI_COMMAND_MAX (__STP_DBG_COMMAND_MAX - 1) ++ ++static struct genl_family stp_dbg_gnl_family = { ++ .id = GENL_ID_GENERATE, ++ .hdrsize = 0, ++ .name = STP_DBG_FAMILY_NAME, ++ .version = 1, ++ .maxattr = STP_DBG_ATTR_MAX, ++}; ++ ++static void stp_dbg_nl_init(void); ++static void stp_dbg_nl_deinit(void); ++static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info); ++static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info); ++ ++/* attribute policy */ ++static struct nla_policy stp_dbg_genl_policy[STP_DBG_ATTR_MAX + 1] = { ++ [STP_DBG_ATTR_MSG] = {.type = NLA_NUL_STRING}, ++}; ++ ++/* operation definition */ ++#if 0 ++static struct genl_ops stp_dbg_gnl_ops_bind = { ++ .cmd = STP_DBG_COMMAND_BIND, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_bind, ++ .dumpit = NULL, ++}; ++ ++static struct genl_ops stp_dbg_gnl_ops_reset = { ++ .cmd = STP_DBG_COMMAND_RESET, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_reset, ++ .dumpit = NULL, ++}; ++#endif ++static struct genl_ops stp_dbg_gnl_ops_array[] = { ++ { ++ .cmd = STP_DBG_COMMAND_BIND, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_bind, ++ .dumpit = NULL, ++ }, ++ { ++ .cmd = STP_DBG_COMMAND_RESET, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_reset, ++ .dumpit = NULL, ++ }, ++}; ++ ++#if 0 ++#define E2S(x) #x ++static char *dmaRegsStr[] = { ++ E2S(CONNSYS_CLK_GATE_STATUS), ++ E2S(CONSYS_EMI_STATUS), ++ E2S(SYSRAM1), ++ E2S(SYSRAM2), ++ E2S(SYSRAM3) ++}; ++#endif ++static unsigned int stp_dbg_seqnum; ++static int num_bind_process; ++static pid_t bind_pid[MAX_BIND_PROCESS]; ++ ++static P_WCN_CORE_DUMP_T g_core_dump; ++ ++static P_STP_DBG_CPUPCR_T g_stp_dbg_cpupcr; ++ ++/* just show in log at present */ ++static P_STP_DBG_DMAREGS_T g_stp_dbg_dmaregs; ++ ++/* core_dump_timeout_handler - handler of coredump timeout ++ * @ data - core dump object's pointer ++ * ++ * No return value ++ */ ++static void core_dump_timeout_handler(unsigned long data) ++{ ++ P_WCN_CORE_DUMP_T dmp = (P_WCN_CORE_DUMP_T) data; ++ ++ STP_DBG_INFO_FUNC(" start\n"); ++ ++ stp_btm_notify_coredump_timeout_wq(g_stp_dbg->btm); ++ ++ STP_DBG_INFO_FUNC(" end\n"); ++ ++ if (dmp) ++ dmp->sm = CORE_DUMP_TIMEOUT; ++} ++ ++/* wcn_core_dump_init - create core dump sys ++ * @ timeout - core dump time out value ++ * ++ * Return object pointer if success, else NULL ++ */ ++P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout) ++{ ++#define KBYTES (1024*sizeof(char)) ++#define L1_BUF_SIZE (32*KBYTES) ++ ++ P_WCN_CORE_DUMP_T core_dmp = NULL; ++ ++ core_dmp = (P_WCN_CORE_DUMP_T) osal_malloc(sizeof(WCN_CORE_DUMP_T)); ++ if (!core_dmp) { ++ STP_DBG_ERR_FUNC("alloc mem failed!\n"); ++ goto fail; ++ } ++ ++ osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T)); ++ ++ core_dmp->compressor = wcn_compressor_init("core_dump_compressor", L1_BUF_SIZE, 18*packet_num*KBYTES); ++ if (!core_dmp->compressor) { ++ STP_DBG_ERR_FUNC("create compressor failed!\n"); ++ goto fail; ++ } ++ wcn_compressor_reset(core_dmp->compressor, 1, GZIP); ++ ++ core_dmp->dmp_timer.timeoutHandler = core_dump_timeout_handler; ++ core_dmp->dmp_timer.timeroutHandlerData = (unsigned long)core_dmp; ++ osal_timer_create(&core_dmp->dmp_timer); ++ core_dmp->timeout = timeout; ++ ++ osal_sleepable_lock_init(&core_dmp->dmp_lock); ++ ++ core_dmp->sm = CORE_DUMP_INIT; ++ STP_DBG_INFO_FUNC("create coredump object OK!\n"); ++ ++ return core_dmp; ++ ++fail: ++ if (core_dmp && core_dmp->compressor) { ++ wcn_compressor_deinit(core_dmp->compressor); ++ core_dmp->compressor = NULL; ++ } ++ if (core_dmp) ++ osal_free(core_dmp); ++ ++ return NULL; ++} ++INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout) ++{ ++ INT32 Ret = 0; ++ ++ g_core_dump = wcn_core_dump_init(packet_num, timeout); ++ if (g_core_dump == NULL) ++ Ret = -1; ++ return Ret; ++} ++ ++/* wcn_core_dump_deinit - destroy core dump object ++ * @ dmp - pointer of object ++ * ++ * Retunr 0 if success, else error code ++ */ ++INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp) ++{ ++ if (dmp && dmp->compressor) { ++ wcn_compressor_deinit(dmp->compressor); ++ dmp->compressor = NULL; ++ } ++ ++ if (dmp) { ++ osal_sleepable_lock_deinit(&dmp->dmp_lock); ++ osal_timer_stop(&dmp->dmp_timer); ++ osal_free(dmp); ++ } ++ ++ return 0; ++} ++ ++INT32 wcn_core_dump_deinit_gcoredump(VOID) ++{ ++ wcn_core_dump_deinit(g_core_dump); ++ return 0; ++} ++ ++static INT32 wcn_core_dump_check_end(PUINT8 buf, INT32 len) ++{ ++ if (strnstr(buf, "coredump end", len)) ++ return 1; ++ else ++ return 0; ++} ++ ++/* wcn_core_dump_in - add a packet to compressor buffer ++ * @ dmp - pointer of object ++ * @ buf - input buffer ++ * @ len - data length ++ * ++ * Retunr 0 if success; return 1 if find end string; else error code ++ */ ++INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) ++{ ++ INT32 ret = 0; ++ INT32 tmp; ++ ++#define INFO_HEAD ";SOC_CONSYS FW CORE, " ++ ++ if ((!dmp) || (!buf)) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); ++ if (ret) { ++ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); ++ return ret; ++ } ++ ++ switch (dmp->sm) { ++ case CORE_DUMP_INIT: ++ wcn_compressor_reset(dmp->compressor, 1, GZIP); ++ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); ++ ++ /* first package, copy to info buffer */ ++ osal_strcpy(&dmp->info[0], INFO_HEAD); ++ ++ if (NULL == (strnstr(buf, "", 32))) { ++ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw warm reset exception...", ++ osal_strlen("Fw warm reset exception...")); ++ dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw warm reset exception...") + 1] = '\0'; ++ } else { ++ char *pStr = buf; ++ char *pDtr = NULL; ++ ++ pDtr = osal_strchr(pStr, '-'); ++ if (NULL != pDtr) { ++ tmp = pDtr - pStr; ++ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); ++ dmp->info[osal_strlen(dmp->info) + 1] = '\0'; ++ } else { ++ tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); ++ tmp = (len > tmp) ? tmp : len; ++ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); ++ dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0'; ++ } ++ ++ } ++ /* show coredump start info on UI */ ++ /* osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); */ ++#if STP_DBG_AEE_EXP_API ++ aee_kernel_dal_show("SOC_CONSYS coredump start ....\n"); ++#endif ++ /* parsing data, and check end srting */ ++ ret = wcn_core_dump_check_end(buf, len); ++ if (ret == 1) { ++ STP_DBG_INFO_FUNC("core dump end!\n"); ++ dmp->sm = CORE_DUMP_DONE; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } else { ++ dmp->sm = CORE_DUMP_DOING; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } ++ break; ++ ++ case CORE_DUMP_DOING: ++ /* parsing data, and check end srting */ ++ ret = wcn_core_dump_check_end(buf, len); ++ if (ret == 1) { ++ STP_DBG_INFO_FUNC("core dump end!\n"); ++ dmp->sm = CORE_DUMP_DONE; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } else { ++ dmp->sm = CORE_DUMP_DOING; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } ++ break; ++ ++ case CORE_DUMP_DONE: ++ wcn_compressor_reset(dmp->compressor, 1, GZIP); ++ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ dmp->sm = CORE_DUMP_DOING; ++ break; ++ ++ case CORE_DUMP_TIMEOUT: ++ break; ++ default: ++ break; ++ } ++ ++ osal_unlock_sleepable_lock(&dmp->dmp_lock); ++ ++ return ret; ++} ++ ++/* wcn_core_dump_out - get compressed data from compressor buffer ++ * @ dmp - pointer of object ++ * @ pbuf - target buffer's pointer ++ * @ len - data length ++ * ++ * Retunr 0 if success; else error code ++ */ ++INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 plen) ++{ ++ INT32 ret = 0; ++ ++ if ((!dmp) || (!pbuf) || (!plen)) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); ++ if (ret) { ++ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); ++ return ret; ++ } ++ ++ ret = wcn_compressor_out(dmp->compressor, pbuf, plen); ++ ++ osal_unlock_sleepable_lock(&dmp->dmp_lock); ++ ++ return ret; ++} ++ ++/* wcn_core_dump_reset - reset core dump sys ++ * @ dmp - pointer of object ++ * @ timeout - core dump time out value ++ * ++ * Retunr 0 if success, else error code ++ */ ++INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout) ++{ ++ if (!dmp) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ dmp->sm = CORE_DUMP_INIT; ++ dmp->timeout = timeout; ++ osal_timer_stop(&dmp->dmp_timer); ++ wcn_compressor_reset(dmp->compressor, 1, GZIP); ++ osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1); ++ ++ wcn_core_dump_deinit(dmp); ++ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); ++ ++ return 0; ++} ++ ++/* wcn_wmtd_timeout_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define WMTD_TIMEOUT_INFO_HEAD "Wait wmtd complation timeout ,just collect SYS_FTRACE to DB" ++INT32 wcn_wmtd_timeout_collect_ftrace(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Wait wmtd complation timeout"; ++ len = osal_strlen("Wait wmtd complation timeout"); ++ osal_strcpy(&g_core_dump->info[0], WMTD_TIMEOUT_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++/* wcn_psm_flag_trigger_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define PSM_ABNORMAL_FLAG_INFO_HEAD "Abnormal PSM flag be set ,just collect SYS_FTRACE to DB" ++INT32 wcn_psm_flag_trigger_collect_ftrace(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Abnormal PSM flag be set"; ++ len = osal_strlen("Abnormal PSM flag be set"); ++ osal_strcpy(&g_core_dump->info[0], PSM_ABNORMAL_FLAG_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++#if BTIF_RXD_BE_BLOCKED_DETECT ++MTK_WCN_BOOL is_btif_rxd_be_blocked(void) ++{ ++ MTK_WCN_BOOL flag = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_btif_rxd_be_blocked_flag_get()) ++ flag = MTK_WCN_BOOL_TRUE; ++ return flag; ++} ++/* wcn_btif_rxd_blocked_collect_ftrace - btif rxd be blocked,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define BTIF_RXD_BLOCKED_INFO_HEAD "Btif_rxd thread be blocked too long,just collect SYS_FTRACE to DB" ++INT32 wcn_btif_rxd_blocked_collect_ftrace(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Btif_rxd thread be blocked too long"; ++ len = osal_strlen("Btif_rxd thread be blocked too long"); ++ osal_strcpy(&g_core_dump->info[0], BTIF_RXD_BLOCKED_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++#endif ++/* wcn_core_dump_timeout - wait for FW assert info timeout ,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define TIMEOUT_INFO_HEAD "Trigger assert timeout ,just collect SYS_FTRACE to DB" ++INT32 wcn_core_dump_timeout(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Trigger assert timeout"; ++ len = osal_strlen("Trigger assert timeout"); ++ osal_strcpy(&g_core_dump->info[0], TIMEOUT_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++ ++#define ENABLE_F_TRACE 0 ++/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys ++ * ++ * Retunr 0 if success, else error code ++ */ ++INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout) ++{ ++ PUINT8 pbuf = NULL; ++ INT32 len = 0; ++ ++ if (!g_core_dump) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ wcn_core_dump_out(g_core_dump, &pbuf, &len); ++ STP_DBG_INFO_FUNC("buf 0x%zx, len %d\n", (SIZE_T) pbuf, len); ++#ifdef WMT_PLAT_ALPS ++ /* show coredump end info on UI */ ++ /* osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); */ ++#if STP_DBG_AEE_EXP_API ++ if (coredump_is_timeout) ++ aee_kernel_dal_show("++ SOC_CONSYS coredump tiemout ,pass received coredump to AEE ++\n"); ++ else ++ aee_kernel_dal_show("++ SOC_CONSYS coredump get successfully ++\n"); ++ /* call AEE driver API */ ++#if ENABLE_F_TRACE ++ aed_combo_exception_api(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info, DB_OPT_FTRACE); ++#else ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ ++#endif ++ ++#endif // WMT_PLAT_ALPS ++ ++ /* reset */ ++ wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); ++ ++ return 0; ++} ++ ++static INT32 wcn_gzip_compressor(void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, ++ INT32 finish) ++{ ++ INT32 ret = 0; ++ z_stream *stream = NULL; ++ INT32 tmp = *out_sz; ++ ++ STP_DBG_INFO_FUNC("need to compressor :buf 0x%zx, size %d\n", (SIZE_T) in_buf, in_sz); ++ STP_DBG_INFO_FUNC("before compressor,avalible buf: 0x%zx, size %d\n", (SIZE_T) out_buf, tmp); ++ ++ stream = (z_stream *) worker; ++ if (!stream) { ++ STP_DBG_ERR_FUNC("invalid workspace!\n"); ++ return -1; ++ } ++ ++ if (in_sz > 0) { ++#if 0 ++ ret = zlib_deflateReset(stream); ++ if (ret != Z_OK) { ++ STP_DBG_ERR_FUNC("reset failed!\n"); ++ return -2; ++ } ++#endif ++ ++ stream->next_in = in_buf; ++ stream->avail_in = in_sz; ++ stream->next_out = out_buf; ++ stream->avail_out = tmp; ++ ++ zlib_deflate(stream, Z_FULL_FLUSH); ++ ++ if (finish) { ++ while (1) { ++ int val = zlib_deflate(stream, Z_FINISH); ++ ++ if (val == Z_OK) ++ continue; ++ else if (val == Z_STREAM_END) ++ break; ++ STP_DBG_ERR_FUNC("finish operation failed %d\n", val); ++ return -3; ++ } ++ } ++ ++ *out_sz = tmp - stream->avail_out; ++ } ++ ++ STP_DBG_INFO_FUNC("after compressor,avalible buf: 0x%zx, compress rate %d -> %d\n", (SIZE_T) out_buf, in_sz, ++ *out_sz); ++ ++ return ret; ++} ++ ++/* wcn_compressor_init - create a compressor and do init ++ * @ name - compressor's name ++ * @ L1_buf_sz - L1 buffer size ++ * @ L2_buf_sz - L2 buffer size ++ * ++ * Retunr object's pointer if success, else NULL ++ */ ++P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz) ++{ ++ z_stream *pstream = NULL; ++ P_WCN_COMPRESSOR_T compress = NULL; ++ ++ compress = (P_WCN_COMPRESSOR_T) osal_malloc(sizeof(WCN_COMPRESSOR_T)); ++ if (!compress) { ++ STP_DBG_ERR_FUNC("alloc compressor failed!\n"); ++ goto fail; ++ } ++ ++ osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T)); ++ osal_memcpy(compress->name, name, STP_OJB_NAME_SZ); ++ ++ compress->f_compress_en = 0; ++ compress->compress_type = GZIP; ++ ++ if (compress->compress_type == GZIP) { ++ compress->worker = osal_malloc(sizeof(z_stream)); ++ if (!compress->worker) { ++ STP_DBG_ERR_FUNC("alloc stream failed!\n"); ++ goto fail; ++ } ++ pstream = (z_stream *) compress->worker; ++ ++ pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); ++ if (!pstream->workspace) { ++ STP_DBG_ERR_FUNC("alloc workspace failed!\n"); ++ goto fail; ++ } ++ zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ++ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); ++ } ++ ++ compress->handler = wcn_gzip_compressor; ++ compress->L1_buf_sz = L1_buf_sz; ++ compress->L2_buf_sz = L2_buf_sz; ++ compress->L1_pos = 0; ++ compress->L2_pos = 0; ++ compress->uncomp_size = 0; ++ compress->crc32 = 0xffffffffUL; ++ ++ compress->L1_buf = osal_malloc(compress->L1_buf_sz); ++ if (!compress->L1_buf) { ++ STP_DBG_ERR_FUNC("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz); ++ goto fail; ++ } ++ ++ compress->L2_buf = osal_malloc(compress->L2_buf_sz); ++ if (!compress->L2_buf) { ++ STP_DBG_ERR_FUNC("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz); ++ goto fail; ++ } ++ ++ STP_DBG_INFO_FUNC("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz); ++ return compress; ++ ++fail: ++ if (compress) { ++ if (compress->L2_buf) { ++ osal_free(compress->L2_buf); ++ compress->L2_buf = NULL; ++ } ++ ++ if (compress->L1_buf) { ++ osal_free(compress->L1_buf); ++ compress->L1_buf = NULL; ++ } ++ ++ if (compress->worker) { ++ pstream = (z_stream *) compress->worker; ++ if ((compress->compress_type == GZIP) && pstream->workspace) { ++ zlib_deflateEnd(pstream); ++ osal_free(pstream->workspace); ++ } ++ osal_free(compress->worker); ++ compress->worker = NULL; ++ } ++ ++ if (compress->worker) { ++ osal_free(compress->worker); ++ compress->worker = NULL; ++ } ++ ++ osal_free(compress); ++ compress = NULL; ++ } ++ ++ STP_DBG_ERR_FUNC("init failed!\n"); ++ ++ return NULL; ++} ++ ++/* wcn_compressor_deinit - distroy a compressor ++ * @ cprs - compressor's pointer ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T cprs) ++{ ++ z_stream *pstream = NULL; ++ ++ if (cprs) { ++ if (cprs->L2_buf) { ++ osal_free(cprs->L2_buf); ++ cprs->L2_buf = NULL; ++ } ++ ++ if (cprs->L1_buf) { ++ osal_free(cprs->L1_buf); ++ cprs->L1_buf = NULL; ++ } ++ ++ if (cprs->worker) { ++ pstream = (z_stream *) cprs->worker; ++ if ((cprs->compress_type == GZIP) && pstream->workspace) { ++ zlib_deflateEnd(pstream); ++ osal_free(pstream->workspace); ++ } ++ osal_free(cprs->worker); ++ cprs->worker = NULL; ++ } ++ ++ cprs->handler = NULL; ++ ++ osal_free(cprs); ++ } ++ ++ STP_DBG_INFO_FUNC("destroy OK\n"); ++ ++ return 0; ++} ++ ++/* wcn_compressor_in - put in a raw data, and compress L1 buffer if need ++ * @ cprs - compressor's pointer ++ * @ buf - raw data buffer ++ * @ len - raw data length ++ * @ finish - core dump finish or not, 1: finished; 0: not finish ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, INT32 finish) ++{ ++ INT32 tmp_len = 0; ++ INT32 ret = 0; ++ ++ if (!cprs) { ++ STP_DBG_ERR_FUNC("invalid para!\n"); ++ return -1; ++ } ++ ++ cprs->uncomp_size += len; ++ ++ /* check L1 buf valid space */ ++ if (len > (cprs->L1_buf_sz - cprs->L1_pos)) { ++ STP_DBG_INFO_FUNC("L1 buffer full\n"); ++ ++ if (cprs->f_compress_en && cprs->handler) { ++ /* need compress */ ++ /* compress L1 buffer, and put result to L2 buffer */ ++ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; ++ ret = ++ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], ++ &tmp_len, finish); ++ if (!ret) { ++ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); ++ cprs->L2_pos += tmp_len; ++ if (cprs->L2_pos > cprs->L2_buf_sz) ++ STP_DBG_ERR_FUNC("coredump size too large(%d), L2 buf overflow\n", ++ cprs->L2_pos); ++ ++ if (finish) { ++ /* Add 8 byte suffix ++ === ++ 32 bits UNCOMPRESS SIZE ++ 32 bits CRC ++ */ ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; ++ cprs->L2_pos += 8; ++ } ++ STP_DBG_INFO_FUNC("compress OK!\n"); ++ } else ++ STP_DBG_ERR_FUNC("compress error!\n"); ++ } else { ++ /* no need compress */ ++ /* Flush L1 buffer to L2 buffer */ ++ STP_DBG_INFO_FUNC("No need do compress, Put to L2 buf\n"); ++ ++ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; ++ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; ++ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); ++ cprs->L2_pos += tmp_len; ++ } ++ ++ /* reset L1 buf pos */ ++ cprs->L1_pos = 0; ++ ++ /* put curren data to L1 buf */ ++ if (len > cprs->L1_buf_sz) { ++ STP_DBG_ERR_FUNC("len=%d, too long err!\n", len); ++ } else { ++ STP_DBG_INFO_FUNC("L1 Flushed, and Put %d bytes to L1 buf\n", len); ++ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); ++ cprs->L1_pos += len; ++ } ++ } else { ++ /* put to L1 buffer */ ++ STP_DBG_INFO_FUNC("Put %d bytes to L1 buf\n", len); ++ ++ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); ++ cprs->L1_pos += len; ++ } ++ ++ return ret; ++} ++ ++/* wcn_compressor_out - get the result data from L2 buffer ++ * @ cprs - compressor's pointer ++ * @ pbuf - point to L2 buffer ++ * @ plen - out len ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T cprs, PUINT8 *pbuf, PINT32 plen) ++{ ++ INT32 ret = 0; ++ INT32 tmp_len = 0; ++ ++ if ((!cprs) || (!pbuf) || (!plen)) { ++ STP_DBG_ERR_FUNC("invalid para!\n"); ++ return -1; ++ } ++ /* check if there's L1 data need flush to L2 buffer */ ++ if (cprs->L1_pos > 0) { ++ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; ++ ++ if (cprs->f_compress_en && cprs->handler) { ++ /* need compress */ ++ ret = ++ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], ++ &tmp_len, 1); ++ ++ if (!ret) { ++ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); ++ cprs->L2_pos += tmp_len; ++ ++ /* Add 8 byte suffix ++ === ++ 32 bits UNCOMPRESS SIZE ++ 32 bits CRC ++ */ ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; ++ cprs->L2_pos += 8; ++ ++ STP_DBG_INFO_FUNC("compress OK!\n"); ++ } else { ++ STP_DBG_ERR_FUNC("compress error!\n"); ++ } ++ } else { ++ /* no need compress */ ++ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; ++ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); ++ cprs->L2_pos += tmp_len; ++ } ++ ++ cprs->L1_pos = 0; ++ } ++ ++ *pbuf = cprs->L2_buf; ++ *plen = cprs->L2_pos; ++ ++ STP_DBG_INFO_FUNC("0x%zx, len %d\n", (SIZE_T)*pbuf, *plen); ++ ++ return 0; ++} ++ ++/* wcn_compressor_reset - reset compressor ++ * @ cprs - compressor's pointer ++ * @ enable - enable/disable compress ++ * @ type - compress algorithm ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type) ++{ ++ if (!cprs) { ++ STP_DBG_ERR_FUNC("invalid para!\n"); ++ return -1; ++ } ++ ++ cprs->f_compress_en = enable; ++ /* cprs->f_compress_en = 0; // disable compress for test */ ++ cprs->compress_type = type; ++ cprs->L1_pos = 0; ++ cprs->L2_pos = 0; ++ cprs->uncomp_size = 0; ++ cprs->crc32 = 0xffffffffUL; ++ ++ /* zlib_deflateEnd((z_stream*)cprs->worker); */ ++ ++ STP_DBG_INFO_FUNC("OK! compress algorithm %d\n", type); ++ ++ return 0; ++} ++ ++static void stp_dbg_dump_data(unsigned char *pBuf, char *title, int len) ++{ ++ int k = 0; ++ ++ pr_debug(" %s-len:%d\n", title, len); ++ ++ for (k = 0; k < len; k++) { ++ if (k % 16 == 0 && k != 0) ++ pr_cont("\n "); ++ pr_cont("0x%02x ", pBuf[k]); ++ } ++ pr_debug("--end\n"); ++} ++ ++static int _stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) ++{ ++ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ stp_dbg->pkt_trace_no = 0; ++ stp_dbg->is_enable = 1; ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++static int _stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) ++{ ++ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ stp_dbg->pkt_trace_no = 0; ++ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); ++ stp_dbg->is_enable = 0; ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++static int _stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) ++{ ++ unsigned long flags; ++ STP_DBG_HDR_T *pHdr = NULL; ++ char *pBuf = NULL; ++ unsigned int length = 0; ++ unsigned int internalFlag = stp_dbg->logsys->size < STP_DBG_LOG_ENTRY_NUM; ++ /* #ifdef CONFIG_LOG_STP_INTERNAL */ ++ /* Here we record log in this circle buffer, if buffer is full , ++ select to overlap earlier log, logic should be okay */ ++ internalFlag = 1; ++ /* #endif */ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ ++ if (internalFlag) { ++ stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0; ++ stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len; ++ memset(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), ++ 0, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); ++ memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), ++ buf, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); ++ ++ stp_dbg->logsys->size++; ++ stp_dbg->logsys->size = ++ (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size; ++ ++ if (0 != gStpDbgLogOut) { ++ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]); ++ pBuf = (char *)&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]) + sizeof(STP_DBG_HDR_T); ++ length = stp_dbg->logsys->queue[stp_dbg->logsys->in].len - sizeof(STP_DBG_HDR_T); ++ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", ++ pHdr->sec, ++ pHdr->usec, ++ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", ++ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); ++ if (0 < length) ++ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", length); ++ } ++ stp_dbg->logsys->in = ++ (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->in + 1); ++ STP_DBG_DBG_FUNC("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in); ++ } else { ++ STP_DBG_WARN_FUNC("logsys FULL!\n"); ++ } ++ ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++int stp_gdb_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg) ++{ ++ int retval = 0; ++/* #ifndef CONFIG_LOG_STP_INTERNAL */ ++ ++ if (stp_dbg->btm != NULL) ++ retval += stp_btm_notify_wmt_dmp_wq((MTKSTP_BTM_T *) stp_dbg->btm); ++/* #endif */ ++ ++ return retval; ++} ++ ++int stp_dbg_log_ctrl(unsigned int on) ++{ ++ if (on != 0) { ++ gStpDbgLogOut = 1; ++ pr_debug("STP-DBG: enable pkt log dump out.\n"); ++ } else { ++ gStpDbgLogOut = 0; ++ pr_debug("STP-DBG: disable pkt log dump out.\n"); ++ } ++ return 0; ++} ++ ++int stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) ++{ ++ return _stp_dbg_dmp_in(stp_dbg, buf, len); ++} ++ ++int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg) ++{ ++#define MAX_DMP_NUM 80 ++ unsigned long flags; ++ char *pBuf = NULL; ++ int len = 0; ++ STP_DBG_HDR_T *pHdr = NULL; ++ UINT32 dumpSize = 0; ++ UINT32 inIndex = 0; ++ UINT32 outIndex = 0; ++ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ /* Not to dequeue from loging system */ ++ inIndex = stp_dbg->logsys->in; ++ dumpSize = stp_dbg->logsys->size; ++ if (STP_DBG_LOG_ENTRY_NUM == dumpSize) ++ outIndex = inIndex; ++ else ++ outIndex = ((inIndex + STP_DBG_LOG_ENTRY_NUM) - dumpSize) % STP_DBG_LOG_ENTRY_NUM; ++ ++ if (dumpSize > MAX_DMP_NUM) { ++ ++ outIndex += (dumpSize - MAX_DMP_NUM); ++ outIndex %= STP_DBG_LOG_ENTRY_NUM; ++ dumpSize = MAX_DMP_NUM; ++ ++ } ++ STP_DBG_INFO_FUNC("loged packet size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); ++ while (dumpSize > 0) { ++ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[outIndex].buffer[0]); ++ pBuf = &(stp_dbg->logsys->queue[outIndex].buffer[0]) + sizeof(STP_DBG_HDR_T); ++ len = stp_dbg->logsys->queue[outIndex].len - sizeof(STP_DBG_HDR_T); ++ len = len > STP_PKT_SZ ? STP_PKT_SZ : len; ++ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", ++ pHdr->sec, ++ pHdr->usec, ++ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", ++ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); ++ ++ if (0 < len) ++ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len); ++ outIndex = (outIndex >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (outIndex + 1); ++ dumpSize--; ++ ++ } ++ ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++int stp_dbg_dmp_out_ex(char *buf, int *len) ++{ ++ return stp_dbg_dmp_out(g_stp_dbg, buf, len); ++} ++ ++int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len) ++{ ++ ++ unsigned long flags; ++ int remaining = 0; ++ *len = 0; ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ ++ if (stp_dbg->logsys->size > 0) { ++ memcpy(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]), ++ stp_dbg->logsys->queue[stp_dbg->logsys->out].len); ++ ++ (*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len; ++ stp_dbg->logsys->out = ++ (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->out + 1); ++ stp_dbg->logsys->size--; ++ ++ STP_DBG_DBG_FUNC("logsys size = %d, out = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->out); ++ } else { ++ STP_DBG_LOUD_FUNC("logsys EMPTY!\n"); ++ } ++ ++ remaining = (stp_dbg->logsys->size == 0) ? (0) : (1); ++ ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return remaining; ++} ++ ++static int stp_dbg_fill_hdr(struct stp_dbg_pkt_hdr *hdr, int type, int ack, int seq, int crc, int dir, int len, ++ int dbg_type) ++{ ++ ++ struct timeval now; ++ ++ if (!hdr) { ++ STP_DBG_ERR_FUNC("function invalid\n"); ++ return -EINVAL; ++ } ++ do_gettimeofday(&now); ++ hdr->dbg_type = dbg_type; ++ hdr->ack = ack; ++ hdr->seq = seq; ++ hdr->sec = now.tv_sec; ++ hdr->usec = now.tv_usec; ++ hdr->crc = crc; ++ hdr->dir = dir; /* rx */ ++ hdr->dmy = 0xffffffff; ++ hdr->len = len; ++ hdr->type = type; ++ return 0; ++ ++} ++ ++static int stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, struct stp_dbg_pkt_hdr *hdr, const unsigned char *body) ++{ ++ /* fix the frame size large issues. */ ++ static struct stp_dbg_pkt stp_pkt; ++ uint32_t hdr_sz = sizeof(struct stp_dbg_pkt_hdr); ++ uint32_t body_sz = 0; ++ ++ BUG_ON(!stp_dbg); ++ ++ if (hdr->dbg_type == STP_DBG_PKT) ++ body_sz = (hdr->len <= STP_PKT_SZ) ? (hdr->len) : (STP_PKT_SZ); ++ else ++ body_sz = (hdr->len <= STP_DMP_SZ) ? (hdr->len) : (STP_DMP_SZ); ++ ++ hdr->no = stp_dbg->pkt_trace_no++; ++ memcpy((uint8_t *) &stp_pkt.hdr, (uint8_t *) hdr, hdr_sz); ++ if (body != NULL) ++ memcpy((uint8_t *) &stp_pkt.raw[0], body, body_sz); ++ ++ _stp_dbg_dmp_in(stp_dbg, (char *)&stp_pkt, hdr_sz + body_sz); ++ /* Only FW DMP MSG should inform BTM-CORE to dump packet to native process */ ++ if (hdr->dbg_type == STP_DBG_FW_DMP) ++ stp_gdb_notify_btm_dmp_wq(stp_dbg); ++ ++ return 0; ++} ++ ++int stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, int dbg_type, ++ int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body) ++{ ++ ++ struct stp_dbg_pkt_hdr hdr; ++ ++ if (stp_dbg->is_enable == 0) { ++ /*dbg is disable,and not to log */ ++ } else { ++ hdr.no = 0; ++ hdr.chs = 0; ++ stp_dbg_fill_hdr(&hdr, ++ (int)type, (int)ack_no, (int)seq_no, (int)crc, (int)dir, (int)len, (int)dbg_type); ++ ++ stp_dbg_add_pkt(stp_dbg, &hdr, body); ++ } ++ ++ return 0; ++} ++ ++int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) ++{ ++ return _stp_dbg_enable(stp_dbg); ++} ++ ++int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) ++{ ++ return _stp_dbg_disable(stp_dbg); ++} ++ ++static void stp_dbg_nl_init(void) ++{ ++#if 0 ++ if (genl_register_family(&stp_dbg_gnl_family) != 0) { ++ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); ++ } else { ++ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0) ++ STP_DBG_ERR_FUNC("%s(): BIND operation registration fail\n", __func__); ++ ++ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0) ++ STP_DBG_ERR_FUNC("%s(): RESET operation registration fail\n", __func__); ++ ++ } ++#endif ++ if (genl_register_family_with_ops(&stp_dbg_gnl_family, stp_dbg_gnl_ops_array) != 0) ++ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); ++} ++ ++static void stp_dbg_nl_deinit(void) ++{ ++ genl_unregister_family(&stp_dbg_gnl_family); ++} ++ ++static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct nlattr *na; ++ char *mydata; ++ ++ if (info == NULL) ++ goto out; ++ ++ STP_DBG_INFO_FUNC("%s():->\n", __func__); ++ ++ na = info->attrs[STP_DBG_ATTR_MSG]; ++ ++ if (na) ++ mydata = (char *)nla_data(na); ++ ++ if (num_bind_process < MAX_BIND_PROCESS) { ++ bind_pid[num_bind_process] = info->snd_portid; ++ num_bind_process++; ++ STP_DBG_INFO_FUNC("%s():-> pid = %d\n", __func__, info->snd_portid); ++ } else { ++ STP_DBG_ERR_FUNC("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); ++ } ++ ++out: ++ return 0; ++} ++ ++static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info) ++{ ++ STP_DBG_ERR_FUNC("%s(): should not be invoked\n", __func__); ++ ++ return 0; ++} ++ ++INT8 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len) ++{ ++ struct sk_buff *skb = NULL; ++ void *msg_head = NULL; ++ int rc = -1; ++ int i; ++ ++ if (num_bind_process == 0) { ++ /* no listening process */ ++ STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__); ++ return 0; ++ } ++ ++ for (i = 0; i < num_bind_process; i++) { ++ skb = genlmsg_new(2048, GFP_KERNEL); ++ ++ if (skb) { ++ msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd); ++ if (msg_head == NULL) { ++ nlmsg_free(skb); ++ STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__); ++ return -1; ++ } ++ ++ rc = nla_put(skb, STP_DBG_ATTR_MSG, len, aucMsg); ++ if (rc != 0) { ++ nlmsg_free(skb); ++ STP_DBG_ERR_FUNC("%s(): nla_put_string fail...%d\n", __func__, rc); ++ return -1; ++ } ++ ++ /* finalize the message */ ++ genlmsg_end(skb, msg_head); ++ ++ /* sending message */ ++ rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); ++ if (rc != 0) { ++ STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__); ++ return -1; ++ } ++ } else { ++ STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd) ++{ ++ INT32 ret = 0; ++ ++ /* buffered to compressor */ ++ ret = wcn_core_dump_in(g_core_dump, aucMsg, len); ++ if (ret == 1) ++ wcn_core_dump_flush(0, MTK_WCN_BOOL_FALSE); ++ ++ return ret; ++} ++ ++UINT8 *_stp_dbg_id_to_task(UINT32 id) ++{ ++ UINT8 *taskStr[] = { ++ "Task_WMT", ++ "Task_BT", ++ "Task_Wifi", ++ "Task_Tst", ++ "Task_FM", ++ "Task_Idle", ++ "Task_DrvStp", ++ "Task_DrvBtif", ++ "Task_NatBt" ++ }; ++ return taskStr[id]; ++} ++ ++INT32 _stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type) ++{ ++ char *pStr = NULL; ++ char *pDtr = NULL; ++ char *pTemp = NULL; ++ char *pTemp2 = NULL; ++ char tempBuf[64] = { 0 }; ++ UINT32 len = 0; ++ long res; ++ INT32 ret; ++ ++ PUINT8 parser_sub_string[] = { ++ " ", ++ "id=", ++ "isr=", ++ "irq=", ++ "rc=" ++ }; ++ ++ if (!str) { ++ STP_DBG_ERR_FUNC("NULL string source\n"); ++ return -1; ++ } ++ ++ if (!g_stp_dbg_cpupcr) { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -2; ++ } ++ ++ pStr = str; ++ STP_DBG_DBG_FUNC("source infor:%s\n", pStr); ++ switch (type) { ++ case STP_DBG_ASSERT_INFO: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ' '); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@")); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len); ++ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_'; ++ ++ pTemp = osal_strchr(pDtr, '#'); ++ pTemp += 1; ++ ++ pTemp2 = osal_strchr(pTemp, ' '); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, pTemp2 - pTemp); ++ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0'; ++ STP_DBG_INFO_FUNC("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]); ++ break; ++ case STP_DBG_FW_TASK_ID: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ' '); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); ++ return -4; ++ } ++ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("fw task id :%x\n", (UINT32)res); ++ break; ++ case STP_DBG_FW_ISR: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ','); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw isr id fail(%d)\n", ret); ++ return -4; ++ } ++ g_stp_dbg_cpupcr->fwIsr = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("fw isr str:%x\n", (UINT32)res); ++ break; ++ case STP_DBG_FW_IRQ: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ','); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw irq id fail(%d)\n", ret); ++ return -4; ++ } ++ g_stp_dbg_cpupcr->fwRrq = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("fw irq value:%x\n", (UINT32)res); ++ break; ++ case STP_DBG_ASSERT_TYPE: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ','); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ++ if (0 == osal_memcmp(tempBuf, "*", len)) ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", osal_strlen("general assert")); ++ if (0 == osal_memcmp(tempBuf, "Watch Dog Timeout", len)) ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt")); ++ if (0 == osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL"))) { ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len); ++ ++ pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL("); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen("RB_FULL("); ++ pTemp = osal_strchr(pDtr, ')'); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(RB_FULL()\n"); ++ return -4; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); ++ return -5; ++ } ++ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("update fw task id :%x\n", (UINT32)res); ++ } ++ ++ STP_DBG_INFO_FUNC("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type); ++ break; ++ default: ++ STP_DBG_ERR_FUNC("unknown parser type\n"); ++ break; ++ } ++ ++ return 0; ++} ++ ++P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID) ++{ ++ P_STP_DBG_CPUPCR_T pSdCpupcr = NULL; ++ ++ pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T)); ++ if (!pSdCpupcr) { ++ STP_DBG_ERR_FUNC("stp dbg cpupcr allocate memory fail!\n"); ++ return NULL; ++ } ++ ++ osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T)); ++ ++ osal_sleepable_lock_init(&pSdCpupcr->lock); ++ ++ return pSdCpupcr; ++} ++ ++P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID) ++{ ++ P_STP_DBG_DMAREGS_T pDmaRegs = NULL; ++ ++ pDmaRegs = (P_STP_DBG_DMAREGS_T) osal_malloc(osal_sizeof(STP_DBG_DMAREGS_T)); ++ if (!pDmaRegs) { ++ STP_DBG_ERR_FUNC("stp dbg dmareg allocate memory fail!\n"); ++ return NULL; ++ } ++ ++ osal_memset(pDmaRegs, 0, osal_sizeof(STP_DBG_DMAREGS_T)); ++ ++ osal_sleepable_lock_init(&pDmaRegs->lock); ++ ++ return pDmaRegs; ++} ++ ++VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr) ++{ ++ if (pCpupcr) { ++ osal_sleepable_lock_deinit(&pCpupcr->lock); ++ osal_free(pCpupcr); ++ pCpupcr = NULL; ++ } ++} ++ ++VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs) ++{ ++ if (pDmaRegs) { ++ osal_sleepable_lock_deinit(&pDmaRegs->lock); ++ osal_free(pDmaRegs); ++ pDmaRegs = NULL; ++ } ++} ++ ++INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd) ++{ ++ INT32 i = 0; ++ ++ if (!g_stp_dbg_cpupcr) { ++ STP_DBG_ERR_FUNC("NULL reference pointer\n"); ++ return -1; ++ } ++ ++ if (!cmd) { ++ if (g_stp_dbg_cpupcr->count + times > STP_DBG_CPUPCR_NUM) ++ times = STP_DBG_CPUPCR_NUM - g_stp_dbg_cpupcr->count; ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ for (i = 0; i < times; i++) { ++ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); ++ /* osal_memcpy( ++ * &g_stp_dbg_cpupcr->buffer[i], ++ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), ++ * osal_sizeof(UINT32)); ++ */ ++ g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count + i] = wmt_plat_read_cpupcr(); ++ osal_sleep_ms(sleep); ++ } ++ g_stp_dbg_cpupcr->count += times; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_INFO_FUNC("stp-dbg: for proc test polling cpupcr\n"); ++ if (times > STP_DBG_CPUPCR_NUM) ++ times = STP_DBG_CPUPCR_NUM; ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->count = 0; ++ for (i = 0; i < times; i++) { ++ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); ++ /* osal_memcpy( ++ * &g_stp_dbg_cpupcr->buffer[i], ++ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), ++ * osal_sizeof(UINT32)); ++ */ ++ g_stp_dbg_cpupcr->buffer[i] = wmt_plat_read_cpupcr(); ++ osal_sleep_ms(sleep); ++ } ++ g_stp_dbg_cpupcr->count = times; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ } ++ return 0; ++} ++ ++INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep) ++{ ++#if 0 ++ INT32 i = 0; ++ ++ if (!g_stp_dbg_dmaregs) { ++ STP_DBG_ERR_FUNC("NULL reference pointer\n"); ++ return -1; ++ } ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_dmaregs->lock); ++ ++ if (g_stp_dbg_dmaregs->count + times > STP_DBG_DMAREGS_NUM) { ++ if (g_stp_dbg_dmaregs->count > STP_DBG_DMAREGS_NUM) { ++ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count:%d must less than STP_DBG_DMAREGS_NUM:%d\n", ++ g_stp_dbg_dmaregs->count, STP_DBG_DMAREGS_NUM); ++ g_stp_dbg_dmaregs->count = 0; ++ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count be set default value 0\n"); ++ } ++ times = STP_DBG_DMAREGS_NUM - g_stp_dbg_dmaregs->count; ++ } ++ if (times > STP_DBG_DMAREGS_NUM) { ++ STP_DBG_ERR_FUNC("times overflow, set default value:0\n"); ++ times = 0; ++ } ++ STP_DBG_WARN_FUNC("---------Now Polling DMA relative Regs -------------\n"); ++ for (i = 0; i < times; i++) { ++ INT32 k = 0; ++ ++ for (; k < DMA_REGS_MAX; k++) { ++ STP_DBG_WARN_FUNC("times:%d,i:%d reg: %s, regs:%08x\n", times, i, dmaRegsStr[k], ++ wmt_plat_read_dmaregs(k)); ++ /* g_stp_dbg_dmaregs->dmaIssue[k][g_stp_dbg_dmaregs->count + i] = wmt_plat_read_dmaregs(k); */ ++ } ++ osal_sleep_ms(sleep); ++ } ++ STP_DBG_WARN_FUNC("---------Polling DMA relative Regs End-------------\n"); ++ g_stp_dbg_dmaregs->count += times; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_dmaregs->lock); ++#else ++ return 0; ++#endif ++} ++ ++INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en) ++{ ++ ++ STP_DBG_INFO_FUNC("%s polling cpupcr\n", en == 0 ? "start" : "stop"); ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->stop_flag = en; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ return 0; ++} ++ ++INT32 stp_dbg_set_version_info(UINT32 chipid, UINT8 *pRomVer, UINT8 *pPatchVer, UINT8 *pPatchBrh) ++{ ++ if (g_stp_dbg_cpupcr) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->chipId = chipid; ++ ++ if (pRomVer) ++ osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2); ++ if (pPatchVer) ++ osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8); ++ if (pPatchBrh) ++ osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4); ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ STP_DBG_INFO_FUNC("chipid(0x%x),romver(%s),patchver(%s),branchver(%s)\n", g_stp_dbg_cpupcr->chipId, ++ &g_stp_dbg_cpupcr->romVer[0], &g_stp_dbg_cpupcr->patchVer[0], &g_stp_dbg_cpupcr->branchVer[0]); ++ return 0; ++} ++INT32 stp_dbg_set_wifiver(UINT32 wifiver) ++{ ++ if (g_stp_dbg_cpupcr) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->wifiVer = wifiver; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ STP_DBG_INFO_FUNC("wifiver(%x)\n", g_stp_dbg_cpupcr->wifiVer); ++ return 0; ++} ++ ++INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en) ++{ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = en; ++ g_stp_dbg_cpupcr->host_assert_info.drv_type = drv_type; ++ g_stp_dbg_cpupcr->host_assert_info.reason = reason; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ return 0; ++} ++ ++UINT32 stp_dbg_get_host_trigger_assert(VOID) ++{ ++ return g_stp_dbg_cpupcr->host_assert_info.assert_from_host; ++} ++ ++INT32 stp_dbg_set_fw_info(UINT8 *issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type) ++{ ++ ENUM_ASSERT_INFO_PARSER_TYPE type_index; ++ PUINT8 tempbuf = NULL; ++ UINT32 i = 0; ++ INT32 iRet = 0; ++ ++ if (NULL == issue_info) { ++ STP_DBG_ERR_FUNC("null issue infor\n"); ++ return -1; ++ } ++ STP_DBG_INFO_FUNC("issue type(%d)\n", issue_type); ++ g_stp_dbg_cpupcr->issue_type = issue_type; ++ osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE); ++ ++ /*print patch version when assert happened */ ++ STP_DBG_INFO_FUNC("=======================================\n"); ++ STP_DBG_INFO_FUNC("[consys patch]patch version:%s\n", g_stp_dbg_cpupcr->patchVer); ++ STP_DBG_INFO_FUNC("[consys patch]ALPS branch:%s\n", g_stp_dbg_cpupcr->branchVer); ++ STP_DBG_INFO_FUNC("=======================================\n"); ++ ++ if ((STP_FW_ASSERT_ISSUE == issue_type) || ++ (STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { ++ if ((STP_FW_ASSERT_ISSUE == issue_type) || (STP_HOST_TRIGGER_FW_ASSERT == issue_type)) { ++ tempbuf = osal_malloc(len + 1); ++ if (!tempbuf) ++ return -2; ++ ++ osal_memcpy(&tempbuf[0], issue_info, len); ++ ++ for (i = 0; i < len; i++) { ++ if (tempbuf[i] == '\0') ++ tempbuf[i] = '?'; ++ } ++ ++ tempbuf[len] = '\0'; ++ ++ for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; type_index++) ++ iRet += _stp_dbg_parser_assert_str(&tempbuf[0], type_index); ++ ++ if (iRet) ++ STP_DBG_ERR_FUNC("passert assert infor fail(%d)\n", iRet); ++ ++ } ++ if ((STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { ++ switch (g_stp_dbg_cpupcr->host_assert_info.drv_type) { ++ case 0: ++ STP_DBG_INFO_FUNC("BT trigger assert\n"); ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ if (31 != g_stp_dbg_cpupcr->host_assert_info.reason) ++ /*BT firmware trigger assert */ ++ { ++ g_stp_dbg_cpupcr->fwTaskId = 1; ++ ++ } else ++ /*BT stack trigger assert */ ++ { ++ g_stp_dbg_cpupcr->fwTaskId = 8; ++ } ++ ++ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; ++ /* g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; */ ++ /* g_stp_dbg_cpupcr->host_assert_info.reason = 0; */ ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ break; ++ case 4: ++ STP_DBG_INFO_FUNC("WMT trigger assert\n"); ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ if (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type) ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ ++ if ((38 == g_stp_dbg_cpupcr->host_assert_info.reason) || ++ (39 == g_stp_dbg_cpupcr->host_assert_info.reason) || ++ (40 == g_stp_dbg_cpupcr->host_assert_info.reason)) ++ g_stp_dbg_cpupcr->fwTaskId = 6; /* HOST schedule reason trigger */ ++ else ++ g_stp_dbg_cpupcr->fwTaskId = 0; /* Must be firmware reason */ ++ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ break; ++ default: ++ break; ++ } ++ ++ } ++ osal_free(tempbuf); ++ } else if (STP_FW_NOACK_ISSUE == issue_type) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ g_stp_dbg_cpupcr->fwTaskId = 6; ++ g_stp_dbg_cpupcr->fwRrq = 0; ++ g_stp_dbg_cpupcr->fwIsr = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else if (STP_DBG_PROC_TEST == issue_type) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ g_stp_dbg_cpupcr->fwTaskId = 0; ++ g_stp_dbg_cpupcr->fwRrq = 0; ++ g_stp_dbg_cpupcr->fwIsr = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else if (STP_FW_WARM_RST_ISSUE == issue_type) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ g_stp_dbg_cpupcr->fwTaskId = 0; ++ g_stp_dbg_cpupcr->fwRrq = 0; ++ g_stp_dbg_cpupcr->fwIsr = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_ERR_FUNC("invalid issue type(%d)\n", issue_type); ++ return -3; ++ } ++ ++ return iRet; ++} ++ ++INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 str_len) ++{ ++ UINT32 len = 0; ++ UINT32 i = 0; ++ ++ if (!g_stp_dbg_cpupcr) { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ ++ /*format common information about issue */ ++ len = osal_sprintf(*buf, "
\n\t"); ++ len += osal_sprintf(*buf + len, "\n\t\tMT%x\n\t\n\t", g_stp_dbg_cpupcr->chipId); ++ len += osal_sprintf(*buf + len, "\n\t\t"); ++ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->romVer); ++ if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", strlen("ALPS")))) ++ len += osal_sprintf(*buf + len, "Internal Dev\n\t\t", g_stp_dbg_cpupcr->branchVer); ++ else ++ len += osal_sprintf(*buf + len, "W%sMP\n\t\t", g_stp_dbg_cpupcr->branchVer); ++ ++ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->patchVer); ++ ++ if (0 == g_stp_dbg_cpupcr->wifiVer) ++ len += osal_sprintf(*buf + len, "NULL\n\t"); ++ else ++ len += osal_sprintf(*buf + len, "0x%X.%X\n\t", ++ (UINT8)((g_stp_dbg_cpupcr->wifiVer & 0xFF00)>>8), (UINT8)(g_stp_dbg_cpupcr->wifiVer & 0xFF)); ++ ++ len += osal_sprintf(*buf + len, "\n\t"); ++ ++ /*format issue information: no ack, assert */ ++ len += osal_sprintf(*buf + len, "\n\t\t\n\t\t\t"); ++ if ((STP_FW_NOACK_ISSUE == g_stp_dbg_cpupcr->issue_type) || ++ (STP_DBG_PROC_TEST == g_stp_dbg_cpupcr->issue_type) || ++ (STP_FW_WARM_RST_ISSUE == g_stp_dbg_cpupcr->issue_type)) { ++ len += ++ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", ++ g_stp_dbg_cpupcr->assert_info); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); ++ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t"); ++ len += ++ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", ++ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); ++ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); ++ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } else if ((STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) || ++ (STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || ++ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { ++ len += ++ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", ++ g_stp_dbg_cpupcr->assert_info); ++ len += osal_sprintf(*buf + len, "%s\n\t\t\n\t\n\t", g_stp_dbg_cpupcr->assert_type); ++ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t"); ++ len += ++ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", ++ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); ++ if (32 == g_stp_dbg_cpupcr->host_assert_info.reason || 33 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 34 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 35 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 36 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 37 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 38 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 39 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 40 == g_stp_dbg_cpupcr->host_assert_info.reason) { ++ /*handling wmt turn on/off bt cmd has ack but no evt issue */ ++ /*one of both the irqx and irs is nULL, then use task to find MOF */ ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } else { ++ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); ++ } ++ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); ++ ++ if (STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) { ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } ++ ++ if ((STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || ++ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { ++ len += ++ osal_sprintf(*buf + len, "%d\n\t\t\t", ++ g_stp_dbg_cpupcr->host_assert_info.drv_type); ++ len += ++ osal_sprintf(*buf + len, "%d\n\t\t\t", ++ g_stp_dbg_cpupcr->host_assert_info.reason); ++ } ++ } else { ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\t\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); ++ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "\n\t\t\tNULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } ++ ++ len += osal_sprintf(*buf + len, ""); ++ STP_DBG_INFO_FUNC("stp-dbg:sub len1 for debug(%d)\n", len); ++ ++ if (!g_stp_dbg_cpupcr->count) ++ len += osal_sprintf(*buf + len, "NULL"); ++ else { ++ for (i = 0; i < g_stp_dbg_cpupcr->count; i++) ++ len += osal_sprintf(*buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]); ++ } ++ STP_DBG_INFO_FUNC("stp-dbg:sub len2 for debug(%d)\n", len); ++ len += osal_sprintf(*buf + len, "\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n
\n"); ++ STP_DBG_INFO_FUNC("buffer len[%d]\n", len); ++ /* STP_DBG_INFO_FUNC("Format infor:\n%s\n",*buf); */ ++ *str_len = len; ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); ++ g_stp_dbg_cpupcr->count = 0; ++ g_stp_dbg_cpupcr->host_assert_info.reason = 0; ++ g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ return 0; ++ ++} ++ ++MTKSTP_DBG_T *stp_dbg_init(void *btm_half) ++{ ++ ++ MTKSTP_DBG_T *stp_dbg = NULL; ++ ++ STP_DBG_INFO_FUNC("stp-dbg init\n"); ++ ++ stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL); ++ if (stp_dbg == NULL) ++ goto ERR_EXIT1; ++ if (IS_ERR(stp_dbg)) { ++ STP_DBG_ERR_FUNC("-ENOMEM\n"); ++ goto ERR_EXIT1; ++ } ++ ++ stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T)); ++ if (stp_dbg->logsys == NULL) ++ goto ERR_EXIT2; ++ if (IS_ERR(stp_dbg->logsys)) { ++ STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n"); ++ goto ERR_EXIT2; ++ } ++ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); ++ spin_lock_init(&(stp_dbg->logsys->lock)); ++ stp_dbg->pkt_trace_no = 0; ++ stp_dbg->is_enable = 0; ++ g_stp_dbg = stp_dbg; ++ ++ if (btm_half != NULL) ++ stp_dbg->btm = btm_half; ++ else ++ stp_dbg->btm = NULL; ++ ++ ++ /* bind to netlink */ ++ stp_dbg_nl_init(); ++ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); ++ g_stp_dbg_cpupcr = stp_dbg_cpupcr_init(); ++ g_stp_dbg_dmaregs = stp_dbg_dmaregs_init(); ++ ++ return stp_dbg; ++ ++ERR_EXIT2: ++ kfree(stp_dbg); ++ return NULL; ++ ++ERR_EXIT1: ++ kfree(stp_dbg); ++ return NULL; ++} ++ ++int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg) ++{ ++ ++ STP_DBG_INFO_FUNC("stp-dbg deinit\n"); ++ ++ wcn_core_dump_deinit(g_core_dump); ++ ++ stp_dbg_cpupcr_deinit(g_stp_dbg_cpupcr); ++ stp_dbg_dmaregs_deinit(g_stp_dbg_dmaregs); ++ /* unbind with netlink */ ++ stp_dbg_nl_deinit(); ++ ++ if (stp_dbg->logsys) ++ vfree(stp_dbg->logsys); ++ ++ kfree(stp_dbg); ++ ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c +new file mode 100644 +index 000000000000..f7f4aff010d4 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c +@@ -0,0 +1,279 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include /* udelay() */ ++ ++#include ++ ++ ++#include "osal_typedef.h" ++#include "stp_core.h" ++#include "stp_exp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static MTK_WCN_STP_IF_TX stp_uart_if_tx; ++static MTK_WCN_STP_IF_TX stp_sdio_if_tx; ++static MTK_WCN_STP_IF_TX stp_btif_if_tx; ++static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX; ++static MTK_WCN_STP_IF_RX stp_if_rx; ++static MTK_WCN_STP_EVENT_CB event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; ++static MTK_WCN_STP_EVENT_CB tx_event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++INT32 mtk_wcn_sys_if_rx(UINT8 *data, INT32 size) ++{ ++ if (stp_if_rx == 0x0) ++ return -1; ++ ++ (*stp_if_rx) (data, size); ++ return 0; ++} ++ ++static INT32 mtk_wcn_sys_if_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) ++{ ++ ++ if (STP_UART_IF_TX == g_stp_if_type) ++ return stp_uart_if_tx != NULL ? (*stp_uart_if_tx) (data, size, written_size) : -1; ++ else if (STP_SDIO_IF_TX == g_stp_if_type) ++ return stp_sdio_if_tx != NULL ? (*stp_sdio_if_tx) (data, size, written_size) : -1; ++ else if (STP_BTIF_IF_TX == g_stp_if_type) ++ return stp_btif_if_tx != NULL ? (*stp_btif_if_tx) (data, size, written_size) : -1; ++ /*if (g_stp_if_type >= STP_MAX_IF_TX) *//* George: remove ALWAYS TRUE condition */ ++ return -1; ++} ++ ++static INT32 mtk_wcn_sys_event_set(UINT8 function_type) ++{ ++ if ((function_type < MTKSTP_MAX_TASK_NUM) && (event_callback_tbl[function_type] != 0x0)) { ++ (*event_callback_tbl[function_type]) (); ++ } else { ++ /* FIXME: error handling */ ++ pr_err("[%s] STP set event fail. It seems the function is not active.\n", __func__); ++ } ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_sys_event_tx_resume(UINT8 winspace) ++{ ++ int type = 0; ++ ++ for (type = 0; type < MTKSTP_MAX_TASK_NUM; type++) { ++ if (tx_event_callback_tbl[type]) ++ tx_event_callback_tbl[type] (); ++ } ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_sys_check_function_status(UINT8 type, UINT8 op) ++{ ++ ++ /* op == FUNCTION_ACTIVE, to check if funciton[type] is active ? */ ++ if (!(type < MTKSTP_MAX_TASK_NUM)) ++ return STATUS_FUNCTION_INVALID; ++ ++ if (op == OP_FUNCTION_ACTIVE) { ++ if (event_callback_tbl[type] != 0x0) ++ return STATUS_FUNCTION_ACTIVE; ++ else ++ return STATUS_FUNCTION_INACTIVE; ++ ++ } ++ /* you can define more operation here ..., to queury function's status/information */ ++ ++ return STATUS_OP_INVALID; ++} ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) ++#else ++INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) ++#endif ++{ ++ stp_if_rx = func; ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); ++#endif ++ ++VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type) ++{ ++ static const char * const ifType[] = { ++ "UART", ++ "SDIO", ++ "BTIF", ++ "UNKNOWN" ++ }; ++ g_stp_if_type = stp_if_type; ++ pr_debug("[%s] set STP_IF_TX to %s.\n", __func__, ifType[stp_if_type]); ++} ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) ++#else ++INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) ++#endif ++{ ++ if (STP_UART_IF_TX == stp_if) { ++ stp_uart_if_tx = func; ++ } else if (STP_SDIO_IF_TX == stp_if) { ++ stp_sdio_if_tx = func; ++ } else if (STP_BTIF_IF_TX == stp_if) { ++ stp_btif_if_tx = func; ++ } else { ++ pr_debug("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); ++ return -1; ++ } ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); ++#endif ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#else ++INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#endif ++{ ++ if (type < MTKSTP_MAX_TASK_NUM) { ++ event_callback_tbl[type] = func; ++ ++ /*clear rx queue */ ++ pr_debug("Flush type = %d Rx Queue\n", type); ++ mtk_wcn_stp_flush_rx_queue(type); ++ } ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); ++#endif ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#else ++INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#endif ++{ ++ if (type < MTKSTP_MAX_TASK_NUM) ++ tx_event_callback_tbl[type] = func; ++ else ++ BUG_ON(0); ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); ++#endif ++ ++INT32 stp_drv_init(VOID) ++{ ++ INT32 ret = 0; ++ ++ mtkstp_callback cb = { ++ .cb_if_tx = mtk_wcn_sys_if_tx, ++ .cb_event_set = mtk_wcn_sys_event_set, ++ .cb_event_tx_resume = mtk_wcn_sys_event_tx_resume, ++ .cb_check_funciton_status = mtk_wcn_sys_check_function_status ++ }; ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ MTK_WCN_STP_EXP_CB_INFO stpExpCb = { ++ .stp_send_data_cb = _mtk_wcn_stp_send_data, ++ .stp_send_data_raw_cb = _mtk_wcn_stp_send_data_raw, ++ .stp_parser_data_cb = _mtk_wcn_stp_parser_data, ++ .stp_receive_data_cb = _mtk_wcn_stp_receive_data, ++ .stp_is_rxqueue_empty_cb = _mtk_wcn_stp_is_rxqueue_empty, ++ .stp_is_ready_cb = _mtk_wcn_stp_is_ready, ++ .stp_set_bluez_cb = _mtk_wcn_stp_set_bluez, ++ .stp_if_tx_cb = _mtk_wcn_stp_register_if_tx, ++ .stp_if_rx_cb = _mtk_wcn_stp_register_if_rx, ++ .stp_reg_event_cb = _mtk_wcn_stp_register_event_cb, ++ .stp_reg_tx_event_cb = _mtk_wcn_stp_register_tx_event_cb, ++ .stp_coredump_start_get_cb = _mtk_wcn_stp_coredump_start_get, ++ }; ++#endif ++ ++ ret = mtk_wcn_stp_init(&cb); ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_stp_exp_cb_reg(&stpExpCb); ++#endif ++ return ret; ++} ++ ++VOID stp_drv_exit(VOID) ++{ ++ mtk_wcn_stp_deinit(); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_stp_exp_cb_unreg(); ++#endif ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c +new file mode 100644 +index 000000000000..f70c88796f09 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c +@@ -0,0 +1,2566 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief brief description ++ ++ Detailed descriptions here. ++ ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-DEV]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_dev.h" ++#include "wmt_core.h" ++#include "wmt_exp.h" ++#include "wmt_lib.h" ++#include "wmt_conf.h" ++#include "psm_core.h" ++#include "stp_core.h" ++#include "stp_exp.h" ++#include "bgw_desense.h" ++#include ++#include "wmt_idc.h" ++#ifdef CONFIG_COMPAT ++#include ++#endif ++#if WMT_CREATE_NODE_DYNAMIC ++#include ++#endif ++#define BUF_LEN_MAX 384 ++#include ++#ifdef CONFIG_COMPAT ++#define COMPAT_WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t) ++#endif ++ ++#define WMT_IOC_MAGIC 0xa0 ++#define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, char*) ++#define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC, 5, int) ++#define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC, 6, int) ++#define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC, 7, int) ++#define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, char*) ++#define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC, 12, int) ++#define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC, 13, int) ++#define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC, 14, int) ++#define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, char*) ++#define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*) ++#define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*) ++#define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int) ++#define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int) ++#define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int) ++#define WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, char*) ++#define WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, char*) ++#define WMT_IOCTL_FW_DBGLOG_CTRL _IOR(WMT_IOC_MAGIC, 29, int) ++#define WMT_IOCTL_DYNAMIC_DUMP_CTRL _IOR(WMT_IOC_MAGIC, 30, char*) ++ ++#define MTK_WMT_VERSION "SOC Consys WMT Driver - v1.0" ++#define MTK_WMT_DATE "2013/01/20" ++#define WMT_DEV_MAJOR 190 /* never used number */ ++#define WMT_DEV_NUM 1 ++#define WMT_DEV_INIT_TO_MS (2 * 1000) ++#define DYNAMIC_DUMP_BUF 109 ++ ++#if CFG_WMT_DBG_SUPPORT ++#define WMT_DBG_PROCNAME "driver/wmt_dbg" ++#endif ++ ++#define WMT_DRIVER_NAME "mtk_stp_wmt" ++ ++P_OSAL_EVENT gpRxEvent = NULL; ++ ++UINT32 u4RxFlag = 0x0; ++static atomic_t gRxCount = ATOMIC_INIT(0); ++ ++/* Linux UINT8 device */ ++static int gWmtMajor = WMT_DEV_MAJOR; ++static struct cdev gWmtCdev; ++static atomic_t gWmtRefCnt = ATOMIC_INIT(0); ++/* WMT driver information */ ++static UINT8 gLpbkBuf[1024+5] = { 0 }; ++ ++static UINT32 gLpbkBufLog; /* George LPBK debug */ ++static INT32 gWmtInitDone; ++static wait_queue_head_t gWmtInitWq; ++ ++P_WMT_PATCH_INFO pPatchInfo = NULL; ++UINT32 pAtchNum = 0; ++ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) ++#define WMT_EMI_DEBUG_BUF_SIZE (8*1024) ++#else ++#define WMT_EMI_DEBUG_BUF_SIZE (32*1024) ++#endif ++ ++static UINT8 gEmiBuf[WMT_EMI_DEBUG_BUF_SIZE]; ++UINT8 *buf_emi; ++ ++#if CFG_WMT_PROC_FOR_AEE ++static struct proc_dir_entry *gWmtAeeEntry; ++#define WMT_AEE_PROCNAME "driver/wmt_aee" ++#define WMT_PROC_AEE_SIZE 3072 ++static UINT32 g_buf_len; ++static UINT8 *pBuf; ++#endif ++ ++#if WMT_CREATE_NODE_DYNAMIC ++struct class *wmt_class = NULL; ++struct device *wmt_dev = NULL; ++#endif ++ ++#if CFG_WMT_DBG_SUPPORT ++static struct proc_dir_entry *gWmtDbgEntry; ++COEX_BUF gCoexBuf; ++ ++static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd); ++static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3); ++ ++#if CFG_CORE_INTERNAL_TXRX ++static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3); ++#endif ++static INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3); ++#if CONSYS_ENALBE_SET_JTAG ++static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3); ++#endif ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3); ++#endif ++#endif ++static void wmt_dbg_fwinfor_print_buff(UINT32 len) ++{ ++ UINT32 i = 0; ++ UINT32 idx = 0; ++ ++ for (i = 0; i < len; i++) { ++ buf_emi[idx] = gEmiBuf[i]; ++ if (gEmiBuf[i] == '\n') { ++ pr_cont("%s", buf_emi); ++ osal_memset(buf_emi, 0, BUF_LEN_MAX); ++ idx = 0; ++ } else { ++ idx++; ++ } ++ if (idx == BUF_LEN_MAX-1) { ++ buf_emi[idx] = '\0'; ++ pr_cont("%s", buf_emi); ++ osal_memset(buf_emi, 0, BUF_LEN_MAX); ++ idx = 0; ++ } ++ } ++} ++ ++/*LCM on/off ctrl for wmt varabile*/ ++static struct work_struct gPwrOnOffWork; ++UINT32 g_es_lr_flag_for_quick_sleep = 1; /* for ctrl quick sleep flag */ ++UINT32 g_es_lr_flag_for_lpbk_onoff = 0; /* for ctrl lpbk on off */ ++OSAL_SLEEPABLE_LOCK g_es_lr_lock; ++ ++#ifdef CONFIG_EARLYSUSPEND ++ ++static void wmt_dev_early_suspend(struct early_suspend *h) ++{ ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 1; ++ g_es_lr_flag_for_lpbk_onoff = 0; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n"); ++ ++ schedule_work(&gPwrOnOffWork); ++} ++ ++static void wmt_dev_late_resume(struct early_suspend *h) ++{ ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 0; ++ g_es_lr_flag_for_lpbk_onoff = 1; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n"); ++ ++ schedule_work(&gPwrOnOffWork); ++ ++} ++ ++struct early_suspend wmt_early_suspend_handler = { ++ .suspend = wmt_dev_early_suspend, ++ .resume = wmt_dev_late_resume, ++}; ++ ++#else ++ ++static struct notifier_block wmt_fb_notifier; ++static int wmt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) ++{ ++ struct fb_event *evdata = data; ++ INT32 blank; ++ ++ WMT_DBG_FUNC("wmt_fb_notifier_callback\n"); ++ ++ /* If we aren't interested in this event, skip it immediately ... */ ++ if (event != FB_EVENT_BLANK) ++ return 0; ++ ++ blank = *(INT32 *)evdata->data; ++ WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank); ++ ++ switch (blank) { ++ case FB_BLANK_UNBLANK: ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 0; ++ g_es_lr_flag_for_lpbk_onoff = 1; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n"); ++ schedule_work(&gPwrOnOffWork); ++ break; ++ case FB_BLANK_POWERDOWN: ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 1; ++ g_es_lr_flag_for_lpbk_onoff = 0; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n"); ++ schedule_work(&gPwrOnOffWork); ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static void wmt_pwr_on_off_handler(struct work_struct *work) ++{ ++ INT32 retryCounter = 1; ++ ++ WMT_DBG_FUNC("wmt_pwr_on_off_handler start to run\n"); ++ ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ ++ if (g_es_lr_flag_for_lpbk_onoff) { ++ do { ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) { ++ WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter); ++ retryCounter--; ++ osal_sleep_ms(1000); ++ } else { ++ WMT_INFO_FUNC("WMT turn on LPBK suceed\n"); ++ break; ++ } ++ } while (retryCounter > 0); ++ } else { ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) ++ WMT_WARN_FUNC("WMT turn off LPBK fail\n"); ++ else ++ WMT_DBG_FUNC("WMT turn off LPBK suceed\n"); ++ ++ } ++ ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ ++} ++ ++ ++MTK_WCN_BOOL wmt_dev_get_early_suspend_state(void) ++{ ++ MTK_WCN_BOOL bRet = (0 == g_es_lr_flag_for_quick_sleep) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; ++ /* WMT_INFO_FUNC("bRet:%d\n", bRet); */ ++ return bRet; ++} ++ ++#if CFG_WMT_DBG_SUPPORT ++ ++static const WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] = { ++ [0] = wmt_dbg_psm_ctrl, ++ [1] = wmt_dbg_quick_sleep_ctrl, ++ [2] = wmt_dbg_dsns_ctrl, ++ [3] = wmt_dbg_hwver_get, ++ [4] = wmt_dbg_assert_test, ++ [5] = wmt_dbg_inband_rst, ++ [6] = wmt_dbg_chip_rst, ++ [7] = wmt_dbg_func_ctrl, ++ [8] = wmt_dbg_raed_chipid, ++ [9] = wmt_dbg_wmt_dbg_level, ++ [0xa] = wmt_dbg_stp_dbg_level, ++ [0xb] = wmt_dbg_reg_read, ++ [0xc] = wmt_dbg_reg_write, ++ [0xd] = wmt_dbg_coex_test, ++ [0xe] = wmt_dbg_rst_ctrl, ++ [0xf] = wmt_dbg_ut_test, ++ [0x10] = wmt_dbg_efuse_read, ++ [0x11] = wmt_dbg_efuse_write, ++ [0x12] = wmt_dbg_sdio_ctrl, ++ [0x13] = wmt_dbg_stp_dbg_ctrl, ++ [0x14] = wmt_dbg_stp_dbg_log_ctrl, ++ [0x15] = wmt_dbg_wmt_assert_ctrl, ++ [0x16] = wmt_dbg_fwinfor_from_emi, ++ [0x17] = wmt_dbg_set_mcu_clock, ++ [0x18] = wmt_dbg_poll_cpupcr, ++ [0x19] = wmt_dbg_jtag_flag_ctrl, ++#if CFG_WMT_LTE_COEX_HANDLING ++ [0x20] = wmt_dbg_lte_coex_test, ++#endif ++}; ++ ++INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++#if CFG_WMT_PS_SUPPORT ++ if (0 == par2) { ++ wmt_lib_ps_ctrl(0); ++ WMT_INFO_FUNC("disable PSM\n"); ++ } else { ++ par2 = (1 > par2 || 20000 < par2) ? STP_PSM_IDLE_TIME_SLEEP : par2; ++ wmt_lib_ps_set_idle_time(par2); ++ wmt_lib_ps_ctrl(1); ++ WMT_WARN_FUNC("enable PSM, idle to sleep time = %d ms\n", par2); ++ } ++#else ++ WMT_INFO_FUNC("WMT PS not supported\n"); ++#endif ++ return 0; ++} ++ ++INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++#if CFG_WMT_PS_SUPPORT ++ UINT32 en_flag = par2; ++ ++ wmt_lib_quick_sleep_ctrl(en_flag); ++#else ++ WMT_WARN_FUNC("WMT PS not supported\n"); ++#endif ++ return 0; ++} ++ ++INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2) { ++ WMT_INFO_FUNC("DSNS type (%d)\n", par2); ++ mtk_wcn_wmt_dsns_ctrl(par2); ++ } else { ++ WMT_WARN_FUNC("invalid DSNS type\n"); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("query chip version\n"); ++ mtk_wcn_wmt_hwver_get(); ++ return 0; ++} ++ ++INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (0 == par3) { ++ /* par2 = 0: send assert command */ ++ /* par2 != 0: send exception command */ ++ return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1); ++ } else if (1 == par3) { ++ /* send noack command */ ++ return wmt_dbg_cmd_test_api(18); ++ } else if (2 == par3) { ++ /* warn reset test */ ++ return wmt_dbg_cmd_test_api(19); ++ } else if (3 == par3) { ++ /* firmware trace test */ ++ return wmt_dbg_cmd_test_api(20); ++ } ++ { ++ INT32 sec = 8; ++ INT32 times = 0; ++ ++ times = par3; ++ do { ++ WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n"); ++ wmt_dbg_cmd_test_api(0); ++ osal_sleep_ms(sec * 1000); ++ } while (--times); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd) ++{ ++ ++ P_OSAL_OP pOp = NULL; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ ++ pOp->op.opId = WMT_OPID_CMD_TEST; ++ ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ /*this test command should be run with usb cable connected, so no host awake is needed */ ++ /* wmt_lib_host_awake_get(); */ ++ switch (cmd) { ++ case WMTDRV_CMD_ASSERT: ++ pOp->op.au4OpData[0] = 0; ++ break; ++ case WMTDRV_CMD_EXCEPTION: ++ pOp->op.au4OpData[0] = 1; ++ break; ++ case WMTDRV_CMD_NOACK_TEST: ++ pOp->op.au4OpData[0] = 3; ++ break; ++ case WMTDRV_CMD_WARNRST_TEST: ++ pOp->op.au4OpData[0] = 4; ++ break; ++ case WMTDRV_CMD_FWTRACE_TEST: ++ pOp->op.au4OpData[0] = 5; ++ break; ++ default: ++ if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd) { ++ pOp->op.au4OpData[0] = 2; ++ pOp->op.au4OpData[1] = cmd - 2; ++ } else { ++ pOp->op.au4OpData[0] = 0xff; ++ pOp->op.au4OpData[1] = 0xff; ++ } ++ pOp->op.au4OpData[2] = (SIZE_T) gCoexBuf.buffer; ++ pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer); ++ break; ++ } ++ WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]); ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if ((cmd != WMTDRV_CMD_ASSERT) && ++ (cmd != WMTDRV_CMD_EXCEPTION) && ++ (cmd != WMTDRV_CMD_NOACK_TEST) && (cmd != WMTDRV_CMD_WARNRST_TEST) && (cmd != WMTDRV_CMD_FWTRACE_TEST)) { ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ gCoexBuf.availSize = 0; ++ } else { ++ gCoexBuf.availSize = pOp->op.au4OpData[3]; ++ WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize); ++ } ++ } ++ /* wmt_lib_host_awake_put(); */ ++ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", ++ pOp->op.opId, ++ pOp->op.au4OpData[0], ++ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); ++ ++ return 0; ++} ++ ++INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (0 == par2) { ++ WMT_INFO_FUNC("inband reset test!!\n"); ++ mtk_wcn_stp_inband_reset(); ++ } else { ++ WMT_INFO_FUNC("STP context reset in host side!!\n"); ++ mtk_wcn_stp_flush_context(); ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (0 == par2) { ++ if (mtk_wcn_stp_is_ready()) { ++ WMT_INFO_FUNC("whole chip reset test\n"); ++ wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST); ++ } else { ++ WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n"); ++ } ++ } else if (1 == par2) { ++ WMT_INFO_FUNC("chip hardware reset test\n"); ++ wmt_lib_hw_rst(); ++ } else { ++ WMT_INFO_FUNC("chip software reset test\n"); ++ wmt_lib_sw_rst(1); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2) { ++ if (0 == par3) { ++ WMT_INFO_FUNC("function off test, type(%d)\n", par2); ++ mtk_wcn_wmt_func_off(par2); ++ } else { ++ WMT_INFO_FUNC("function on test, type(%d)\n", par2); ++ mtk_wcn_wmt_func_on(par2); ++ } ++ } else { ++ WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER)); ++ return 0; ++} ++ ++INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3) ++{ ++ par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO; ++ wmt_lib_dbg_level_set(par2); ++ WMT_INFO_FUNC("set wmt log level to %d\n", par2); ++ return 0; ++} ++ ++INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3) ++{ ++ par2 = (0 <= par2 && 4 >= par2) ? par2 : 2; ++ mtk_wcn_stp_dbg_level(par2); ++ WMT_INFO_FUNC("set stp log level to %d\n", par2); ++ return 0; ++ ++} ++ ++INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->register address */ ++ /* par3-->register mask */ ++ UINT32 value = 0x0; ++ UINT32 iRet = -1; ++#if 0 ++ DISABLE_PSM_MONITOR(); ++ iRet = wmt_core_reg_rw_raw(0, par2, &value, par3); ++ ENABLE_PSM_MONITOR(); ++#endif ++ iRet = wmt_lib_reg_rw(0, par2, &value, par3); ++ WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); ++ return 0; ++} ++ ++INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->register address */ ++ /* par3-->value to set */ ++ UINT32 iRet = -1; ++#if 0 ++ DISABLE_PSM_MONITOR(); ++ iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff); ++ ENABLE_PSM_MONITOR(); ++#endif ++ iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff); ++ WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed"); ++ return 0; ++} ++ ++INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->efuse address */ ++ /* par3-->register mask */ ++ UINT32 value = 0x0; ++ UINT32 iRet = -1; ++ ++ iRet = wmt_lib_efuse_rw(0, par2, &value, par3); ++ WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); ++ return 0; ++} ++ ++INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->efuse address */ ++ /* par3-->value to set */ ++ UINT32 iRet = -1; ++ ++ iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff); ++ WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed"); ++ return 0; ++} ++ ++INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++/*remove sdio card detect/remove control because of btif is used*/ ++#if 0 ++ INT32 iRet = -1; ++ ++ iRet = wmt_lib_sdio_ctrl(0 != par2 ? 1 : 0); ++ WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed"); ++#endif ++ return 0; ++} ++ ++INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (1 < par2) { ++ mtk_wcn_stp_dbg_dump_package(); ++ return 0; ++ } ++ WMT_INFO_FUNC("%s stp debug function\n", 0 == par2 ? "disable" : "enable"); ++ if (0 == par2) ++ mtk_wcn_stp_dbg_disable(); ++ else if (1 == par2) ++ mtk_wcn_stp_dbg_enable(); ++ ++ return 0; ++} ++ ++INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ mtk_wcn_stp_dbg_log_ctrl(0 != par2 ? 1 : 0); ++ return 0; ++} ++ ++INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ mtk_wcn_stp_coredump_flag_ctrl(0 != par2 ? 1 : 0); ++ return 0; ++} ++ ++INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 offset = 0; ++ UINT32 len = 0; ++ UINT32 *pAddr = NULL; ++ UINT32 cur_idx_pagedtrace; ++ static UINT32 prev_idx_pagedtrace; ++ MTK_WCN_BOOL isBreak = MTK_WCN_BOOL_TRUE; ++ ++ offset = par2; ++ len = par3; ++ ++ buf_emi = kmalloc(sizeof(UINT8) * BUF_LEN_MAX, GFP_KERNEL); ++ if (!buf_emi) { ++ WMT_ERR_FUNC("buf kmalloc memory fail\n"); ++ return 0; ++ } ++ osal_memset(buf_emi, 0, BUF_LEN_MAX); ++ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); ++ wmt_lib_get_fwinfor_from_emi(0, offset, &gEmiBuf[0], 0x100); ++ ++ if (offset == 1) { ++ do { ++ pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24); ++ cur_idx_pagedtrace = *pAddr; ++ ++ if (cur_idx_pagedtrace > prev_idx_pagedtrace) { ++ len = cur_idx_pagedtrace - prev_idx_pagedtrace; ++ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); ++ wmt_dbg_fwinfor_print_buff(len); ++ prev_idx_pagedtrace = cur_idx_pagedtrace; ++ } ++ ++ if (cur_idx_pagedtrace < prev_idx_pagedtrace) { ++ if (prev_idx_pagedtrace >= 0x8000) { ++ pr_debug("++ prev_idx_pagedtrace invalid ...++\n\\n"); ++ prev_idx_pagedtrace = 0x8000 - 1; ++ continue; ++ } ++ ++ len = 0x8000 - prev_idx_pagedtrace - 1; ++ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); ++ pr_debug("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ ++ len = cur_idx_pagedtrace; ++ wmt_lib_get_fwinfor_from_emi(1, 0x0, &gEmiBuf[0], len); ++ pr_debug("\n\n -- CONNSYS paged trace ascii output (end) --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ prev_idx_pagedtrace = cur_idx_pagedtrace; ++ } ++ msleep(100); ++ } while (isBreak); ++ } ++ ++ pr_debug("\n\n -- control word --\n\n"); ++ wmt_dbg_fwinfor_print_buff(256); ++ if (len > 1024 * 4) ++ len = 1024 * 4; ++ ++ WMT_WARN_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n", offset, len); ++ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); ++ wmt_lib_get_fwinfor_from_emi(1, offset, &gEmiBuf[0], len); ++ ++ pr_debug("\n\n -- paged trace hex output --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ pr_debug("\n\n -- paged trace ascii output --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ kfree(buf_emi); ++ return 0; ++} ++ ++INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("coexistance test cmd!!\n"); ++ return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00); ++} ++ ++INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("%s audo rst\n", 0 == par2 ? "disable" : "enable"); ++ mtk_wcn_stp_set_auto_rst(0 == par2 ? 0 : 1); ++ return 0; ++} ++ ++INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ ++ INT32 i = 0; ++ INT32 j = 0; ++ INT32 iRet = 0; ++ ++ i = 20; ++ while ((i--) > 0) { ++ WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i); ++ j = 10; ++ while ((j--) > 0) { ++ WMT_INFO_FUNC("#### BT On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### GPS On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### FM On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### WIFI On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### BT Off .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### GPS Off ....(%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### FM Off .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### WIFI Off ....(%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ } ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ } ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ WMT_INFO_FUNC("#### UT FAIL!!\n"); ++ else ++ WMT_INFO_FUNC("#### UT PASS!!\n"); ++ ++ return iRet; ++} ++ ++#if CFG_CORE_INTERNAL_TXRX ++ ++struct lpbk_package { ++ long payload_length; ++ unsigned char out_payload[2048]; ++ unsigned char in_payload[2048]; ++}; ++ ++static INT32 wmt_internal_loopback(INT32 count, INT32 max) ++{ ++ int ret = 0; ++ int loop; ++ int offset; ++ struct lpbk_package lpbk_buffer; ++ P_OSAL_OP pOp; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ for (loop = 0; loop < count; loop++) { ++ /* <1> init buffer */ ++ osal_memset((void *)&lpbk_buffer, 0, sizeof(struct lpbk_package)); ++ lpbk_buffer.payload_length = max; ++ for (offset = 0; offset < max; offset++) ++ lpbk_buffer.out_payload[offset] = (offset + 1) /*for test use: begin from 1 */ & 0xFF; ++ ++ ++ memcpy(&gLpbkBuf[0], &lpbk_buffer.out_payload[0], max); ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ ret = -1; ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_LPBK; ++ pOp->op.au4OpData[0] = lpbk_buffer.payload_length; /* packet length */ ++ pOp->op.au4OpData[1] = (UINT32) &gLpbkBuf[0]; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ ret = -2; ++ } ++ ++ ret = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == ret) { ++ WMT_WARN_FUNC("OPID(%d) type(%d)fail\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ret = -3; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ memcpy(&lpbk_buffer.in_payload[0], &gLpbkBuf[0], max); ++ ++ ret = pOp->op.au4OpData[0]; ++ /*<3> compare result */ ++ if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) { ++ WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __func__); ++ ret = -4; ++ break; ++ } ++ WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld)\n", __func__, loop, ++ lpbk_buffer.payload_length); ++ ++ } ++ ++ if (loop != count) ++ WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max); ++ ++ ++ return ret; ++} ++ ++INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 count; ++ UINT32 length; ++ ++ count = par1; ++ length = par2; ++ ++ WMT_INFO_FUNC("count[%d],length[%d]\n", count, length); ++ ++ wmt_core_lpbk_do_stp_init(); ++ ++ wmt_internal_loopback(count, length); ++ ++ wmt_core_lpbk_do_stp_deinit(); ++ return 0; ++} ++#endif ++ ++static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3) ++{ ++ int ret = 0; ++ P_OSAL_OP pOp; ++ P_OSAL_SIGNAL pSignal = NULL; ++ UINT32 kind = 0; ++ ++ kind = par2; ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_SET_MCU_CLK; ++ pOp->op.au4OpData[0] = kind; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ WMT_INFO_FUNC("OPID(%d) kind(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) kind(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -2; ++ } ++ ++ ret = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == ret) { ++ WMT_WARN_FUNC("OPID(%d) kind(%d)fail(%d)\n", pOp->op.opId, pOp->op.au4OpData[0], ret); ++ return -3; ++ } ++ WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ return ret; ++} ++ ++static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 count = 0; ++ UINT16 sleep = 0; ++ UINT16 toAee = 0; ++ ++ count = par2; ++ sleep = (par3 & 0xF0) >> 4; ++ toAee = (par3 & 0x0F); ++ ++ WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n", count, sleep, toAee); ++ wmt_lib_poll_cpupcr(count, sleep, toAee); ++ ++ return 0; ++} ++ ++#if CONSYS_ENALBE_SET_JTAG ++static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 en_flag = par2; ++ ++ wmt_lib_jtag_flag_set(en_flag); ++ return 0; ++} ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode, UINT32 msg_len) ++{ ++ ipc_ilm_t ilm; ++ local_para_struct *p_buf_str; ++ INT32 i = 0; ++ INT32 iRet = -1; ++ ++ WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n", opcode, msg_len); ++ p_buf_str = osal_malloc(osal_sizeof(local_para_struct) + msg_len); ++ if (NULL == p_buf_str) { ++ WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n"); ++ return -1; ++ } ++ p_buf_str->msg_len = msg_len; ++ for (i = 0; i < msg_len; i++) ++ p_buf_str->data[i] = i; ++ ++ ilm.local_para_ptr = p_buf_str; ++ ilm.msg_id = opcode; ++ ++ iRet = wmt_lib_handle_idc_msg(&ilm); ++ osal_free(p_buf_str); ++ return iRet; ++ ++} ++ ++static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT8 *local_buffer = NULL; ++ UINT32 handle_len; ++ INT32 iRet = -1; ++ static UINT8 wmt_to_lte_test_evt1[] = { 0x02, 0x16, 0x0d, 0x00, ++ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, ++ 0xa, 0xb ++ }; ++ static UINT8 wmt_to_lte_test_evt2[] = { 0x02, 0x16, 0x09, 0x00, ++ 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ++ }; ++ static UINT8 wmt_to_lte_test_evt3[] = { 0x02, 0x16, 0x02, 0x00, ++ 0x02, 0xff ++ }; ++ static UINT8 wmt_to_lte_test_evt4[] = { 0x02, 0x16, 0x0d, 0x00, ++ 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, ++ 0xa, 0xb ++ }; ++ ++ local_buffer = kmalloc(512, GFP_KERNEL); ++ if (!local_buffer) { ++ WMT_ERR_FUNC("local_buffer kmalloc memory fail\n"); ++ return 0; ++ } ++ ++ if (par2 == 1) { ++ handle_len = ++ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); ++ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1)) { ++ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", ++ handle_len, osal_sizeof(wmt_to_lte_test_evt1)); ++ } else { ++ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 2) { ++ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); ++ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], ++ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); ++ ++ handle_len = ++ wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], ++ osal_sizeof(wmt_to_lte_test_evt1) + ++ osal_sizeof(wmt_to_lte_test_evt2)); ++ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)) { ++ WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", ++ handle_len, osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)); ++ } else { ++ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 3) { ++ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); ++ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], ++ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); ++ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)], ++ &wmt_to_lte_test_evt3[0], osal_sizeof(wmt_to_lte_test_evt3)); ++ ++ handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], osal_sizeof(wmt_to_lte_test_evt1) + ++ osal_sizeof(wmt_to_lte_test_evt2) + ++ osal_sizeof(wmt_to_lte_test_evt3)); ++ if (handle_len != ++ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + ++ osal_sizeof(wmt_to_lte_test_evt3)) { ++ WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", handle_len, ++ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + ++ osal_sizeof(wmt_to_lte_test_evt3)); ++ } else { ++ WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 4) { ++ handle_len = ++ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt4[0], osal_sizeof(wmt_to_lte_test_evt4)); ++ if (handle_len != osal_sizeof(wmt_to_lte_test_evt4)) { ++ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", ++ handle_len, osal_sizeof(wmt_to_lte_test_evt4)); ++ } else { ++ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 5) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 6) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 7) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 8) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 9) { ++ if (par3 > 0) ++ wmt_core_set_flag_for_test(1); ++ else ++ wmt_core_set_flag_for_test(0); ++ } ++ return 0; ++ kfree(local_buffer); ++} ++#endif ++ ++static ssize_t wmt_dev_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ ++ INT32 retval = 0; ++ INT32 i_ret = 0; ++ PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; ++ ++ if (*f_pos > 0) { ++ retval = 0; ++ } else { ++ /*len = sprintf(page, "%d\n", g_psm_enable); */ ++ if (gCoexBuf.availSize <= 0) { ++ WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"); ++ retval = osal_strlen(warn_msg) + 1; ++ if (count < retval) ++ retval = count; ++ ++ i_ret = copy_to_user(buf, warn_msg, retval); ++ if (i_ret) { ++ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ } else { ++ INT32 i = 0; ++ INT32 len = 0; ++ INT8 msg_info[128]; ++ INT32 max_num = 0; ++ /*we do not check page buffer, because there are only ++ * 100 bytes in g_coex_buf, no reason page buffer is not ++ * enough, a bomb is placed here on unexpected condition ++ */ ++ ++ WMT_INFO_FUNC("%d bytes available\n", gCoexBuf.availSize); ++ max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) - 1) / 5; ++ ++ if (max_num > gCoexBuf.availSize) ++ max_num = gCoexBuf.availSize; ++ else ++ WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num); ++ ++ ++ for (i = 0; i < max_num; i++) ++ len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]); ++ ++ ++ len += osal_sprintf(msg_info + len, "\n"); ++ retval = len; ++ ++ i_ret = copy_to_user(buf, msg_info, retval); ++ if (i_ret) { ++ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ ++ } ++ } ++ gCoexBuf.availSize = 0; ++err_exit: ++ ++ return retval; ++} ++ ++static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) ++{ ++ INT8 buf[256]; ++ PINT8 pBuf; ++ ssize_t len = count; ++ INT32 x = 0, y = 0, z = 0; ++ PINT8 pToken = NULL; ++ PINT8 pDelimiter = " \t"; ++ long res; ++ INT32 ret; ++ ++ WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); ++ if (len >= osal_sizeof(buf)) { ++ WMT_ERR_FUNC("input handling fail!\n"); ++ len = osal_sizeof(buf) - 1; ++ return -1; ++ } ++ ++ if (copy_from_user(buf, buffer, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ WMT_INFO_FUNC("write parameter data = %s\n\r", buf); ++ ++ pBuf = buf; ++ pToken = osal_strsep(&pBuf, pDelimiter); ++ ++ if (pToken != NULL) { ++ ret = osal_strtol(pToken, 16, &res); ++ if (ret) { ++ WMT_ERR_FUNC("get x fail(%d)\n", ret); ++ x = 0; ++ } ++ x = res; ++ } else { ++ x = 0; ++ } ++ ++ pToken = osal_strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ ret = osal_strtol(pToken, 16, &res); ++ if (ret) { ++ WMT_ERR_FUNC("get y fail(%d)\n", ret); ++ y = 0; ++ } ++ y = res; ++ WMT_INFO_FUNC("y = 0x%08x\n\r", y); ++ } else { ++ y = 3000; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ y = 0x80000000; ++ ++ } ++ ++ pToken = osal_strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ ret = osal_strtol(pToken, 16, &res); ++ if (ret) { ++ WMT_ERR_FUNC("get z fail(%d)\n", ret); ++ z = 0; ++ } ++ z = res; ++ } else { ++ z = 10; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ z = 0xffffffff; ++ ++ } ++ ++ WMT_WARN_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); ++ ++ if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x]) ++ (*wmt_dev_dbg_func[x]) (x, y, z); ++ else ++ WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x); ++ ++ return len; ++} ++ ++INT32 wmt_dev_dbg_setup(VOID) ++{ ++ static const struct file_operations wmt_dbg_fops = { ++ .owner = THIS_MODULE, ++ .read = wmt_dev_dbg_read, ++ .write = wmt_dev_dbg_write, ++ }; ++ gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops); ++ if (gWmtDbgEntry == NULL) { ++ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); ++ return -1; ++ } ++ return 0; ++} ++ ++INT32 wmt_dev_dbg_remove(VOID) ++{ ++ if (NULL != gWmtDbgEntry) ++ remove_proc_entry(WMT_DBG_PROCNAME, NULL); ++ ++#if CFG_WMT_PS_SUPPORT ++ wmt_lib_ps_deinit(); ++#endif ++ return 0; ++} ++#endif ++ ++#if CFG_WMT_PROC_FOR_AEE ++ ++static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 retval = 0; ++ UINT32 len = 0; ++ ++ WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos); ++ ++ if (0 == *f_pos) { ++ pBuf = wmt_lib_get_cpupcr_xml_format(&len); ++ g_buf_len = len; ++ WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len); ++ } ++ ++ if (g_buf_len >= count) { ++ ++ retval = copy_to_user(buf, pBuf, count); ++ if (retval) { ++ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ ++ *f_pos += count; ++ g_buf_len -= count; ++ pBuf += count; ++ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); ++ ++ retval = count; ++ } else if (0 != g_buf_len) { ++ ++ retval = copy_to_user(buf, pBuf, g_buf_len); ++ if (retval) { ++ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ ++ *f_pos += g_buf_len; ++ len = g_buf_len; ++ g_buf_len = 0; ++ pBuf += len; ++ retval = len; ++ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); ++ } else { ++ WMT_INFO_FUNC("wmt_dev: no data available for aee\n"); ++ retval = 0; ++ } ++err_exit: ++ return retval; ++} ++ ++static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ WMT_TRC_FUNC(); ++ return 0; ++} ++ ++INT32 wmt_dev_proc_for_aee_setup(VOID) ++{ ++ static const struct file_operations wmt_aee_fops = { ++ .owner = THIS_MODULE, ++ .read = wmt_dev_proc_for_aee_read, ++ .write = wmt_dev_proc_for_aee_write, ++ }; ++ ++ gWmtDbgEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops); ++ if (gWmtDbgEntry == NULL) { ++ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_dev_proc_for_aee_remove(VOID) ++{ ++ if (NULL != gWmtAeeEntry) ++ remove_proc_entry(WMT_AEE_PROCNAME, NULL); ++ ++ return 0; ++} ++#endif ++ ++VOID wmt_dev_rx_event_cb(VOID) ++{ ++ u4RxFlag = 1; ++ atomic_inc(&gRxCount); ++ if (NULL != gpRxEvent) { ++ /* u4RxFlag = 1; */ ++ /* atomic_inc(&gRxCount); */ ++ wake_up_interruptible(&gpRxEvent->waitQueue); ++ } else { ++ /* WMT_ERR_FUNC("null gpRxEvent, flush rx!\n"); */ ++ /* wmt_lib_flush_rx(); */ ++ } ++} ++ ++INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent) ++{ ++ ++ UINT32 ms = pEvent->timeoutValue; ++ long lRet = 0; ++ ++ gpRxEvent = pEvent; ++ if (0 != ms) ++ lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, msecs_to_jiffies(ms)); ++ else ++ lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0); ++ ++ u4RxFlag = 0; ++/* gpRxEvent = NULL; */ ++ if (atomic_dec_return(&gRxCount)) { ++ WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount)); ++ atomic_set(&gRxCount, 0); ++ } ++ ++ return lRet; ++} ++ ++INT32 wmt_dev_read_file(PUINT8 pName, const PPUINT8 ppBufPtr, INT32 offset, INT32 padSzBuf) ++{ ++ INT32 iRet = -1; ++ struct file *fd; ++ /* ssize_t iRet; */ ++ INT32 file_len; ++ INT32 read_len; ++ PVOID pBuf; ++ mm_segment_t fs; ++ ++ /* struct cred *cred = get_task_cred(current); */ ++ //const struct cred *cred = get_current_cred(); ++ ++ if (!ppBufPtr) { ++ WMT_ERR_FUNC("invalid ppBufptr!\n"); ++ return -1; ++ } ++ *ppBufPtr = NULL; ++ ++ fd = filp_open(pName, O_RDONLY, 0); ++ if (IS_ERR(fd)) { ++ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); ++ return -2; ++ } ++ ++ if(fd->f_op == NULL) { ++ printk(KERN_ERR "invalid file op \r\n"); ++ return -3; ++ } ++ ++#if 0 ++ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { ++ WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d, %d)\n", fd, PTR_ERR(fd), cred->fsuid, cred->fsgid); ++ if (IS_ERR(fd)) ++ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); ++ return -1; ++ } ++#endif ++ file_len = fd->f_path.dentry->d_inode->i_size; ++ file_len = fd->f_op->llseek(fd, 0, 2); ++ fd->f_op->llseek(fd, 0, 0); ++ pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL); ++ if (!pBuf) { ++ WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32) ((file_len + 3) & ~0x3UL)); ++ goto read_file_done; ++ } ++ ++ do { ++ if (fd->f_pos != offset) { ++ if (fd->f_op->llseek) { ++ if (fd->f_op->llseek(fd, offset, 0) != offset) { ++ WMT_ERR_FUNC("failed to seek!!\n"); ++ goto read_file_done; ++ } ++ } else { ++ fd->f_pos = offset; ++ } ++ } ++ ++ fs=get_fs(); ++ read_len = vfs_read(fd, pBuf + padSzBuf, file_len, &fd->f_pos); ++ set_fs(fs); ++ if (read_len != file_len) ++ WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len); ++ ++ } while (false); ++ ++ iRet = 0; ++ *ppBufPtr = pBuf; ++ ++read_file_done: ++ if (iRet) { ++ if (pBuf) ++ vfree(pBuf); ++ ++ } ++ ++ filp_close(fd, NULL); ++ ++ return (iRet) ? iRet : read_len; ++} ++ ++/* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */ ++INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf) ++{ ++ INT32 iRet = -1; ++ osal_firmware *pfw; ++ uid_t orig_uid; ++ gid_t orig_gid; ++ ++ /* struct cred *cred = get_task_cred(current); */ ++ struct cred *cred = (struct cred *)get_current_cred(); ++ ++ mm_segment_t orig_fs = get_fs(); ++ ++ if (*ppPatch) { ++ WMT_WARN_FUNC("f/w patch already exists\n"); ++ if ((*ppPatch)->data) ++ vfree((*ppPatch)->data); ++ ++ kfree(*ppPatch); ++ *ppPatch = NULL; ++ } ++ ++ if (!osal_strlen(pPatchName)) { ++ WMT_ERR_FUNC("empty f/w name\n"); ++ osal_assert((osal_strlen(pPatchName) > 0)); ++ return -1; ++ } ++ ++ pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL */ GFP_ATOMIC); ++ if (!pfw) { ++ WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware)); ++ return -2; ++ } ++ ++ orig_uid = cred->fsuid.val; ++ orig_gid = cred->fsgid.val; ++ cred->fsuid.val = cred->fsgid.val = 0; ++ ++ set_fs(get_ds()); ++ ++ /* load patch file from fs */ ++ iRet = wmt_dev_read_file(pPatchName, (const PPUINT8)&pfw->data, 0, padSzBuf); ++ set_fs(orig_fs); ++ ++ cred->fsuid.val = orig_uid; ++ cred->fsgid.val = orig_gid; ++ ++ ++ if (iRet > 0) { ++ pfw->size = iRet; ++ *ppPatch = pfw; ++ WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data); ++ return 0; ++ } ++ kfree(pfw); ++ *ppPatch = NULL; ++ WMT_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet); ++ return -1; ++} ++ ++INT32 wmt_dev_patch_put(osal_firmware **ppPatch) ++{ ++ if (NULL != *ppPatch) { ++ if ((*ppPatch)->data) ++ vfree((*ppPatch)->data); ++ ++ kfree(*ppPatch); ++ *ppPatch = NULL; ++ } ++ return 0; ++} ++ ++VOID wmt_dev_patch_info_free(VOID) ++{ ++ ++ kfree(pPatchInfo); ++ pPatchInfo = NULL; ++ ++} ++ ++MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName) ++{ ++ struct file *fd = NULL; ++ /* ssize_t iRet; */ ++ INT32 fileLen = -1; ++ const struct cred *cred = get_current_cred(); ++ ++ if (pFileName == NULL) { ++ WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) { ++ WMT_ERR_FUNC("invalid file name(%s)\n", pFileName); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ /* struct cred *cred = get_task_cred(current); */ ++ ++ fd = filp_open(pFileName, O_RDONLY, 0); ++ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { ++ WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd, cred->fsuid, cred->fsgid); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ fileLen = fd->f_path.dentry->d_inode->i_size; ++ filp_close(fd, NULL); ++ fd = NULL; ++ if (fileLen <= 0) { ++ WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen); ++ return true; ++ ++} ++ ++/* static unsigned long count_last_access_sdio = 0; */ ++static unsigned long count_last_access_btif; ++static unsigned long jiffies_last_poll; ++ ++#if 0 ++static INT32 wmt_dev_tra_sdio_update(void) ++{ ++ count_last_access_sdio += 1; ++ /* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */ ++ ++ return 0; ++} ++#endif ++ ++extern INT32 wmt_dev_tra_bitf_update(void) ++{ ++ count_last_access_btif += 1; ++ /* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */ ++ ++ return 0; ++} ++ ++static UINT32 wmt_dev_tra_ahb_poll(void) ++{ ++#define TIME_THRESHOLD_TO_TEMP_QUERY 3000 ++#define COUNT_THRESHOLD_TO_TEMP_QUERY 200 ++ ++ unsigned long ahb_during_count = 0; ++ unsigned long poll_during_time = 0; ++ ++ /* if (jiffies > jiffies_last_poll) */ ++ if (time_after(jiffies, jiffies_last_poll)) ++ poll_during_time = jiffies - jiffies_last_poll; ++ else ++ poll_during_time = 0xffffffff; ++ ++ ++ WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n", jiffies_to_msecs(0xffffffff)); ++ ++ if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { ++ WMT_DBG_FUNC("**poll_during_time = %lu < %lu, not to query\n", ++ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY); ++ return -1; ++ } ++ /* ahb_during_count = count_last_access_sdio; */ ++ if (NULL == mtk_wcn_wlan_bus_tx_cnt) { ++ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n"); ++ return -1; ++ } ++ ahb_during_count = (*mtk_wcn_wlan_bus_tx_cnt) (); ++ ++ if (ahb_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) { ++ WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n", ++ ahb_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY); ++ return -2; ++ } ++ ++ if (NULL == mtk_wcn_wlan_bus_tx_cnt_clr) { ++ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n"); ++ return -3; ++ } ++ (*mtk_wcn_wlan_bus_tx_cnt_clr) (); ++ /* count_last_access_sdio = 0; */ ++ jiffies_last_poll = jiffies; ++ ++ WMT_INFO_FUNC("**poll_during_time = %lu > %lu, ahb_during_count = %lu > %lu, query\n", ++ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY, ++ jiffies_to_msecs(ahb_during_count), COUNT_THRESHOLD_TO_TEMP_QUERY); ++ ++ return 0; ++} ++ ++long wmt_dev_tm_temp_query(void) ++{ ++#define HISTORY_NUM 5 ++#define TEMP_THRESHOLD 65 ++#define REFRESH_TIME 300 /* sec */ ++ ++ static INT32 temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */ ++ static INT32 idx_temp_table; ++ static struct timeval query_time, now_time; ++ ++ INT8 query_cond = 0; ++ INT32 current_temp = 0; ++ INT32 index = 0; ++ long return_temp = 0; ++ /* Query condition 1: */ ++ /* If we have the high temperature records on the past, we continue to query/monitor */ ++ /* the real temperature until cooling */ ++ for (index = 0; index < HISTORY_NUM; index++) { ++ if (temp_table[index] >= TEMP_THRESHOLD) { ++ query_cond = 1; ++ WMT_DBG_FUNC("temperature table is still initial value, we should query temp temperature..\n"); ++ } ++ } ++ ++ do_gettimeofday(&now_time); ++#if 1 ++ /* Query condition 2: */ ++ /* Moniter the ahb bus activity to decide if we have the need to query temperature. */ ++ if (!query_cond) { ++ if (wmt_dev_tra_ahb_poll() == 0) { ++ query_cond = 1; ++ WMT_INFO_FUNC("ahb traffic , we must query temperature..\n"); ++ } else { ++ WMT_DBG_FUNC("ahb idle traffic ....\n"); ++ } ++ ++ /* only WIFI tx power might make temperature varies largely */ ++#if 0 ++ if (!query_cond) { ++ last_access_time = wmt_dev_tra_uart_poll(); ++ if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { ++ query_cond = 1; ++ WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); ++ } else { ++ WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n"); ++ } ++ } ++#endif ++ } ++#endif ++ /* Query condition 3: */ ++ /* If the query time exceeds the a certain of period, refresh temp table. */ ++ /* */ ++ if (!query_cond) { ++ /* time overflow, we refresh temp table again for simplicity! */ ++ if ((now_time.tv_sec < query_time.tv_sec) || ++ ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { ++ query_cond = 1; ++ ++ WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n", ++ REFRESH_TIME); ++ for (index = 0; index < HISTORY_NUM; index++) ++ temp_table[index] = 99; ++ ++ } ++ } ++ ++ if (query_cond) { ++ /* update the temperature record */ ++ mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); ++ current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); ++ mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); ++ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; ++ temp_table[idx_temp_table] = current_temp; ++ do_gettimeofday(&query_time); ++ ++ WMT_INFO_FUNC("[Thermal] current_temp = 0x%x\n", (current_temp & 0xFF)); ++ } else { ++ current_temp = temp_table[idx_temp_table]; ++ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; ++ temp_table[idx_temp_table] = current_temp; ++ } ++ ++ /* */ ++ /* Dump information */ ++ /* */ ++ WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table); ++ WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec, ++ query_time.tv_sec, REFRESH_TIME); ++ ++ WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n", ++ temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]); ++ ++ return_temp = ((current_temp & 0x80) == 0x0) ? current_temp : (-1) * (current_temp & 0x7f); ++ ++ return return_temp; ++} ++ ++ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 iRet = 0; ++ UINT8 wrBuf[NAME_MAX + 1] = { 0 }; ++ INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX; ++ ++ WMT_LOUD_FUNC("count:%d copySize:%d\n", count, copySize); ++ ++ if (copySize > 0) { ++ if (copy_from_user(wrBuf, buf, copySize)) { ++ iRet = -EFAULT; ++ goto write_done; ++ } ++ iRet = copySize; ++ wrBuf[NAME_MAX] = '\0'; ++ ++ if (!strncasecmp(wrBuf, "ok", NAME_MAX)) { ++ WMT_DBG_FUNC("resp str ok\n"); ++ /* pWmtDevCtx->cmd_result = 0; */ ++ wmt_lib_trigger_cmd_signal(0); ++ } else { ++ WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf); ++ /* pWmtDevCtx->cmd_result = -1; */ ++ wmt_lib_trigger_cmd_signal(-1); ++ } ++ /* complete(&pWmtDevCtx->cmd_comp); */ ++ ++ } ++ ++write_done: ++ return iRet; ++} ++ ++ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 iRet = 0; ++ PUINT8 pCmd = NULL; ++ UINT32 cmdLen = 0; ++ ++ pCmd = wmt_lib_get_cmd(); ++ ++ if (pCmd != NULL) { ++ cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX; ++ WMT_DBG_FUNC("cmd str(%s)\n", pCmd); ++ if (copy_to_user(buf, pCmd, cmdLen)) ++ iRet = -EFAULT; ++ else ++ iRet = cmdLen; ++ ++ } ++#if 0 ++ if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) { ++ iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX; ++ /* we got something from STP driver */ ++ WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf); ++ if (copy_to_user(buf, localBuf, iRet)) { ++ iRet = -EFAULT; ++ goto read_done; ++ } ++ } ++#endif ++ return iRet; ++} ++ ++unsigned int WMT_poll(struct file *filp, poll_table *wait) ++{ ++ UINT32 mask = 0; ++ P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event(); ++ ++ poll_wait(filp, &pEvent->waitQueue, wait); ++ /* empty let select sleep */ ++ if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status()) ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ ++#if 0 ++ if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ ++#endif ++ mask |= POLLOUT | POLLWRNORM; /* writable */ ++ return mask; ++} ++ ++/* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */ ++long WMT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ ++ INT32 iRet = 0; ++ UINT8 *pBuffer = NULL; ++ ++ WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); ++ switch (cmd) { ++ case WMT_IOCTL_SET_PATCH_NAME: /* patch location */ ++ { ++ ++ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); ++ if (!pBuffer) { ++ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); ++ return 0; ++ } ++ if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) { ++ iRet = -EFAULT; ++ kfree(pBuffer); ++ break; ++ } ++ pBuffer[NAME_MAX] = '\0'; ++ wmt_lib_set_patch_name(pBuffer); ++ kfree(pBuffer); ++ } ++ break; ++ ++ case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */ ++ ++ /* set hif conf */ ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal = NULL; ++ P_WMT_HIF_CONF pHif = NULL; ++ ++ iRet = wmt_lib_set_hif(arg); ++ if (0 != iRet) { ++ WMT_INFO_FUNC("wmt_lib_set_hif fail\n"); ++ break; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_INFO_FUNC("get_free_lxop fail\n"); ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_HIF_CONF; ++ ++ pHif = wmt_lib_get_hif(); ++ ++ osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF)); ++ pOp->op.u4InfoBit = WMT_OP_HIF_BIT; ++ pSignal->timeoutValue = 0; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet); ++ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */ ++ ++ do { ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ ++ if (arg & 0x80000000) ++ bRet = mtk_wcn_wmt_func_on(arg & 0xF); ++ else ++ bRet = mtk_wcn_wmt_func_off(arg & 0xF); ++ ++ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_LPBK_POWER_CTRL: ++ /*switch Loopback function on/off ++ arg: bit0 = 1:turn loopback function on ++ bit0 = 0:turn loopback function off ++ */ ++ do { ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ ++ if (arg & 0x01) ++ bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); ++ else ++ bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); ++ ++ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_LPBK_TEST: ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT32 u4Wait; ++ /* UINT8 lpbk_buf[1024] = {0}; */ ++ UINT32 effectiveLen = 0; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) { ++ iRet = -EFAULT; ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ break; ++ } ++ if (effectiveLen > sizeof(gLpbkBuf)) { ++ iRet = -EFAULT; ++ WMT_ERR_FUNC("length is too long\n"); ++ break; ++ } ++ WMT_DBG_FUNC("len = %d\n", effectiveLen); ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ iRet = -EFAULT; ++ break; ++ } ++ u4Wait = 2000; ++ if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) { ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ iRet = -EFAULT; ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_LPBK; ++ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ ++ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; /* packet buffer pointer */ ++ memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4); ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", ++ pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n", ++ pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog); ++ iRet = -1; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ iRet = pOp->op.au4OpData[0]; ++ if (copy_to_user((void *)arg + sizeof(SIZE_T) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) { ++ iRet = -EFAULT; ++ break; ++ } ++ ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_ADIE_LPBK_TEST: ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ iRet = -EFAULT; ++ break; ++ } ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST; ++ pOp->op.au4OpData[0] = 0; ++ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d)abort\n", pOp->op.opId); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); ++ iRet = -1; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ iRet = pOp->op.au4OpData[0]; ++ if (copy_to_user((void *)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) { ++ iRet = -EFAULT; ++ break; ++ } ++ ++ } while (0); ++ ++ break; ++ ++ case 10: ++ { ++ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); ++ if (!pBuffer) { ++ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); ++ return 0; ++ } ++ wmt_lib_host_awake_get(); ++ mtk_wcn_stp_coredump_start_ctrl(1); ++ osal_strcpy(pBuffer, "MT662x f/w coredump start-"); ++ if (copy_from_user ++ (pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) { ++ /* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */ ++ WMT_ERR_FUNC("copy assert string failed\n"); ++ } ++ pBuffer[NAME_MAX] = '\0'; ++ osal_dbg_assert_aee(pBuffer, pBuffer); ++ kfree(pBuffer); ++ } ++ break; ++ case 11: ++ { ++ osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); ++ wmt_lib_host_awake_put(); ++ } ++ break; ++ ++ case WMT_IOCTL_GET_CHIP_INFO: ++ { ++ if (0 == arg) ++ return wmt_lib_get_icinfo(WMTCHIN_CHIPID); ++ else if (1 == arg) ++ return wmt_lib_get_icinfo(WMTCHIN_HWVER); ++ else if (2 == arg) ++ return wmt_lib_get_icinfo(WMTCHIN_FWVER); ++ ++ } ++ break; ++ ++ case WMT_IOCTL_SET_LAUNCHER_KILL:{ ++ if (1 == arg) { ++ WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n"); ++ wmt_lib_set_stp_wmt_last_close(1); ++ } else { ++ wmt_lib_set_stp_wmt_last_close(0); ++ } ++ ++ } ++ break; ++ ++ case WMT_IOCTL_SET_PATCH_NUM:{ ++ pAtchNum = arg; ++ WMT_DBG_FUNC(" get patch num from launcher = %d\n", pAtchNum); ++ wmt_lib_set_patch_num(pAtchNum); ++ pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC); ++ if (!pPatchInfo) { ++ WMT_ERR_FUNC("allocate memory fail!\n"); ++ break; ++ } ++ } ++ break; ++ ++ case WMT_IOCTL_SET_PATCH_INFO:{ ++ WMT_PATCH_INFO wMtPatchInfo; ++ P_WMT_PATCH_INFO pTemp = NULL; ++ UINT32 dWloadSeq; ++ static UINT32 counter; ++ ++ if (!pPatchInfo) { ++ WMT_ERR_FUNC("NULL patch info pointer\n"); ++ break; ++ } ++ ++ if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) { ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ iRet = -EFAULT; ++ break; ++ } ++ ++ dWloadSeq = wMtPatchInfo.dowloadSeq; ++ WMT_DBG_FUNC( ++ "patch dl seq %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n", ++ dWloadSeq, wMtPatchInfo.patchName, ++ wMtPatchInfo.addRess[0], ++ wMtPatchInfo.addRess[1], ++ wMtPatchInfo.addRess[2], ++ wMtPatchInfo.addRess[3]); ++ osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo, sizeof(WMT_PATCH_INFO)); ++ pTemp = pPatchInfo + dWloadSeq - 1; ++ if (++counter == pAtchNum) { ++ wmt_lib_set_patch_info(pPatchInfo); ++ counter = 0; ++ } ++ } ++ break; ++ ++ case WMT_IOCTL_WMT_COREDUMP_CTRL: ++ mtk_wcn_stp_coredump_flag_ctrl(arg); ++ break; ++ case WMT_IOCTL_WMT_QUERY_CHIPID: ++ { ++ iRet = mtk_wcn_wmt_chipid_query(); ++ WMT_WARN_FUNC("chipid = 0x%x\n", iRet); ++ } ++ break; ++ case WMT_IOCTL_SEND_BGW_DS_CMD: ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT8 desense_buf[14] = { 0 }; ++ UINT32 effectiveLen = 14; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ iRet = -EFAULT; ++ break; ++ } ++ if (copy_from_user(&desense_buf[0], (void *)arg, effectiveLen)) { ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ iRet = -EFAULT; ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_BGW_DS; ++ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ ++ pOp->op.au4OpData[1] = (SIZE_T) &desense_buf[0]; /* packet buffer pointer */ ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,opid(%d) abort\n", pOp->op.opId); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); ++ iRet = -1; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ iRet = pOp->op.au4OpData[0]; ++ ++ } while (0); ++ ++ break; ++ case WMT_IOCTL_FW_DBGLOG_CTRL: ++ { ++ iRet = wmt_plat_set_dbg_mode(arg); ++ if (iRet == 0) ++ wmt_dbg_fwinfor_from_emi(0, 1, 0); ++ } ++ break; ++ case WMT_IOCTL_DYNAMIC_DUMP_CTRL: ++ { ++ UINT32 i = 0, j = 0, k = 0; ++ UINT8 *pBuf = NULL; ++ UINT32 int_buf[10]; ++ char Buffer[10][11]; ++ ++ pBuf = kmalloc(DYNAMIC_DUMP_BUF + 1, GFP_KERNEL); ++ if (!pBuf) { ++ WMT_ERR_FUNC("pBuf kmalloc memory fail\n"); ++ return 0; ++ } ++ if (copy_from_user(pBuf, (void *)arg, DYNAMIC_DUMP_BUF)) { ++ iRet = -EFAULT; ++ kfree(pBuf); ++ break; ++ } ++ pBuf[DYNAMIC_DUMP_BUF] = '\0'; ++ WMT_INFO_FUNC("get dynamic dump data from property(%s)\n", pBuf); ++ memset(Buffer, 0, 10*11); ++ for (i = 0; i < DYNAMIC_DUMP_BUF; i++) { ++ if (pBuf[i] == '/') { ++ k = 0; ++ j++; ++ } else { ++ Buffer[j][k] = pBuf[i]; ++ k++; ++ } ++ } ++ for (j = 0; j < 10; j++) { ++ iRet = kstrtou32(Buffer[j], 0, &int_buf[j]); ++ if (iRet) { ++ WMT_ERR_FUNC("string convert fail(%d)\n", iRet); ++ break; ++ } ++ WMT_INFO_FUNC("dynamic dump data buf[%d]:(0x%x)\n", j, int_buf[j]); ++ } ++ wmt_plat_set_dynamic_dumpmem(int_buf); ++ kfree(pBuf); ++ } ++ break; ++ default: ++ iRet = -EINVAL; ++ WMT_WARN_FUNC("unknown cmd (%d)\n", cmd); ++ break; ++ } ++ ++ return iRet; ++} ++#ifdef CONFIG_COMPAT ++long WMT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ WMT_INFO_FUNC("cmd[0x%x]\n", cmd); ++ switch (cmd) { ++ case COMPAT_WMT_IOCTL_SET_PATCH_NAME: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_LPBK_TEST: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_SET_PATCH_INFO: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_PORT_NAME: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_WMT_CFG_NAME: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SEND_BGW_DS_CMD, (unsigned long)compat_ptr(arg)); ++ break; ++ default: { ++ ret = WMT_unlocked_ioctl(filp, cmd, arg); ++ break; ++ } ++ } ++ return ret; ++} ++#endif ++static int WMT_open(struct inode *inode, struct file *file) ++{ ++ long ret; ++ ++ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ret = wait_event_timeout(gWmtInitWq, gWmtInitDone != 0, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); ++ if (!ret) { ++ WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n", ++ WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); ++ return -EIO; ++ } ++ ++ if (atomic_inc_return(&gWmtRefCnt) == 1) ++ WMT_INFO_FUNC("1st call\n"); ++ ++ return 0; ++} ++ ++static int WMT_close(struct inode *inode, struct file *file) ++{ ++ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ++ if (atomic_dec_return(&gWmtRefCnt) == 0) ++ WMT_INFO_FUNC("last call\n"); ++ ++ return 0; ++} ++ ++const struct file_operations gWmtFops = { ++ .open = WMT_open, ++ .release = WMT_close, ++ .read = WMT_read, ++ .write = WMT_write, ++/* .ioctl = WMT_ioctl, */ ++ .unlocked_ioctl = WMT_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = WMT_compat_ioctl, ++#endif ++ .poll = WMT_poll, ++}; ++ ++void wmt_dev_bgw_desense_init(VOID) ++{ ++ bgw_init_socket(); ++} ++ ++void wmt_dev_bgw_desense_deinit(VOID) ++{ ++ bgw_destroy_netlink_kernel(); ++} ++ ++void wmt_dev_send_cmd_to_daemon(UINT32 cmd) ++{ ++ send_command_to_daemon(cmd); ++} ++ ++static int WMT_init(void) ++{ ++ dev_t devID = MKDEV(gWmtMajor, 0); ++ INT32 cdevErr = -1; ++ INT32 ret = -1; ++ ++ WMT_INFO_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE); ++ /* Prepare a UINT8 device */ ++ /*static allocate chrdev */ ++ gWmtInitDone = 0; ++ init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq); ++ stp_drv_init(); ++ ++ ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME); ++ if (ret) { ++ WMT_ERR_FUNC("fail to register chrdev\n"); ++ return ret; ++ } ++ cdev_init(&gWmtCdev, &gWmtFops); ++ gWmtCdev.owner = THIS_MODULE; ++ cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM); ++ if (cdevErr) { ++ WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); ++ goto error; ++ } ++ WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor); ++#if WMT_CREATE_NODE_DYNAMIC ++ wmt_class = class_create(THIS_MODULE, "stpwmt"); ++ if (IS_ERR(wmt_class)) ++ goto error; ++ wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt"); ++ if (IS_ERR(wmt_dev)) ++ goto error; ++#endif ++ ++#if 0 ++ pWmtDevCtx = wmt_drv_create(); ++ if (!pWmtDevCtx) { ++ WMT_ERR_FUNC("wmt_drv_create() fails\n"); ++ goto error; ++ } ++ ret = wmt_drv_init(pWmtDevCtx); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret); ++ goto error; ++ } ++ WMT_INFO_FUNC("stp_btmcb_reg\n"); ++ wmt_cdev_btmcb_reg(); ++ ret = wmt_drv_start(pWmtDevCtx); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret); ++ goto error; ++ } ++#endif ++ ret = wmt_lib_init(); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret); ++ goto error; ++ } ++#if CFG_WMT_DBG_SUPPORT ++ wmt_dev_dbg_setup(); ++#endif ++ ++#if CFG_WMT_PROC_FOR_AEE ++ wmt_dev_proc_for_aee_setup(); ++#endif ++ ++ WMT_INFO_FUNC("wmt_dev register thermal cb\n"); ++ wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query); ++ wmt_dev_bgw_desense_init(); ++ gWmtInitDone = 1; ++ wake_up(&gWmtInitWq); ++ osal_sleepable_lock_init(&g_es_lr_lock); ++ INIT_WORK(&gPwrOnOffWork, wmt_pwr_on_off_handler); ++#ifdef CONFIG_EARLYSUSPEND ++ register_early_suspend(&wmt_early_suspend_handler); ++ WMT_INFO_FUNC("register_early_suspend finished\n"); ++#else ++ wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback; ++ ret = fb_register_client(&wmt_fb_notifier); ++ if (ret) ++ WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret); ++ else ++ WMT_INFO_FUNC("wmt register fb_notifier OK!\n"); ++#endif ++ WMT_INFO_FUNC("success\n"); ++ return 0; ++ ++error: ++ wmt_lib_deinit(); ++#if CFG_WMT_DBG_SUPPORT ++ wmt_dev_dbg_remove(); ++#endif ++#if WMT_CREATE_NODE_DYNAMIC ++ if (!(IS_ERR(wmt_dev))) ++ device_destroy(wmt_class, devID); ++ if (!(IS_ERR(wmt_class))) { ++ class_destroy(wmt_class); ++ wmt_class = NULL; ++ } ++#endif ++ ++ if (cdevErr == 0) ++ cdev_del(&gWmtCdev); ++ ++ if (ret == 0) { ++ unregister_chrdev_region(devID, WMT_DEV_NUM); ++ gWmtMajor = -1; ++ } ++ ++ WMT_ERR_FUNC("fail\n"); ++ ++ return -1; ++} ++ ++static void WMT_exit(void) ++{ ++ dev_t dev = MKDEV(gWmtMajor, 0); ++ ++ osal_sleepable_lock_deinit(&g_es_lr_lock); ++#ifdef CONFIG_EARLYSUSPEND ++ unregister_early_suspend(&wmt_early_suspend_handler); ++ WMT_INFO_FUNC("unregister_early_suspend finished\n"); ++#else ++ fb_unregister_client(&wmt_fb_notifier); ++#endif ++ ++ wmt_dev_bgw_desense_deinit(); ++ ++ wmt_lib_register_thermal_ctrl_cb(NULL); ++ ++ wmt_lib_deinit(); ++ ++#if CFG_WMT_DBG_SUPPORT ++ wmt_dev_dbg_remove(); ++#endif ++ ++#if CFG_WMT_PROC_FOR_AEE ++ wmt_dev_proc_for_aee_remove(); ++#endif ++#if WMT_CREATE_NODE_DYNAMIC ++ if (wmt_dev) { ++ device_destroy(wmt_class, dev); ++ wmt_dev = NULL; ++ } ++ if (wmt_class) { ++ class_destroy(wmt_class); ++ wmt_class = NULL; ++ } ++#endif ++ cdev_del(&gWmtCdev); ++ unregister_chrdev_region(dev, WMT_DEV_NUM); ++ gWmtMajor = -1; ++ ++ stp_drv_exit(); ++ ++ WMT_INFO_FUNC("done\n"); ++} ++ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++ ++int mtk_wcn_soc_common_drv_init(void) ++{ ++ return WMT_init(); ++ ++} ++EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init); ++void mtk_wcn_soc_common_drv_exit(void) ++{ ++ return WMT_exit(); ++} ++EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit); ++ ++#else ++module_init(WMT_init); ++module_exit(WMT_exit); ++#endif ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("MediaTek Inc WCN"); ++MODULE_DESCRIPTION("MTK WCN combo driver for WMT function"); ++ ++module_param(gWmtMajor, uint, 0); +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c +new file mode 100644 +index 000000000000..9f2192d9a3e5 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c +@@ -0,0 +1,610 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-EXP]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include ++#include ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++wmt_wlan_probe_cb mtk_wcn_wlan_probe = NULL; ++wmt_wlan_remove_cb mtk_wcn_wlan_remove = NULL; ++wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt = NULL; ++wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr = NULL; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++OSAL_BIT_OP_VAR gBtWifiGpsState; ++OSAL_BIT_OP_VAR gGpsFmState; ++UINT32 gWifiProbed = 0; ++UINT32 gWmtDbgLvl = WMT_LOG_DBG; ++MTK_WCN_BOOL g_pwr_off_flag = MTK_WCN_BOOL_TRUE; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ ++ pOp->op.opId = opId; ++ pOp->op.au4OpData[0] = type; ++ if (WMTDRV_TYPE_WIFI == type) ++ pSignal->timeoutValue = 4000; ++ /*donot block system server/init/netd from longer than 5s, in case of ANR happens*/ ++ else ++ pSignal->timeoutValue = (WMT_OPID_FUNC_ON == pOp->op.opId) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME; ++ ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ /*do not check return value, we will do this either way */ ++ wmt_lib_host_awake_get(); ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ wmt_lib_host_awake_put(); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ wmt_lib_host_awake_put(); ++ ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ else ++ WMT_WARN_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ return bRet; ++} ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) ++#endif ++{ ++ MTK_WCN_BOOL ret; ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday("############ BT OFF ====>"); ++ ++ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF); ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday("############ BT OFF <===="); ++ ++ return ret; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_func_off); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) ++#endif ++{ ++ MTK_WCN_BOOL ret; ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday("############ BT ON ====>"); ++ ++ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON); ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday(" ############BT ON <===="); ++ ++ return ret; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_func_on); ++#endif ++ ++VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type) ++{ ++ if (on) ++ mtk_wcn_wmt_func_on(type); ++ else ++ mtk_wcn_wmt_func_off(type); ++} ++ ++/* ++return value: ++enable/disable thermal sensor function: true(1)/false(0) ++read thermal sensor function:thermal value ++ ++*/ ++#if WMT_EXP_HID_API_EXPORT ++INT8 _mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) ++#else ++INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) ++#endif ++{ ++ P_OSAL_OP pOp; ++ P_WMT_OP pOpData; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ /*parameter validation check */ ++ if (WMTTHERM_MAX < eType || WMTTHERM_ENABLE > eType) { ++ WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ /*check if chip support thermal control function or not */ ++ bRet = wmt_lib_is_therm_ctrl_support(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_ERR_FUNC("thermal ctrl function not supported\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ pOpData = &pOp->op; ++ pOpData->opId = WMT_OPID_THERM_CTRL; ++ /*parameter fill */ ++ pOpData->au4OpData[0] = eType; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); ++ /*0xFF means read error occurs */ ++ /*will return to function driver */ ++ pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE; ++ } else { ++ WMT_INFO_FUNC("OPID(%d) type(%d) return(%d) ok\n\n", ++ pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]); ++ } ++ /*return value will be put to lxop->op.au4OpData[1] */ ++ WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08x)\n", eType, pOpData->au4OpData[1]); ++ return (INT8) pOpData->au4OpData[1]; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++ENUM_WMTHWVER_TYPE_T _mtk_wcn_wmt_hwver_get(VOID) ++#else ++ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) ++#endif ++{ ++ /* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ ++ /* TODO: how do we extend for new chip and newer revision? */ ++ /* TODO: This way is hard to extend */ ++ return wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER); ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) ++#endif ++{ ++ P_OSAL_OP pOp; ++ P_WMT_OP pOpData; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ if (WMTDSNS_MAX <= eType) { ++ WMT_ERR_FUNC("invalid desense control command (%d)\n", eType); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ /*check if chip support thermal control function or not */ ++ bRet = wmt_lib_is_dsns_ctrl_support(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_ERR_FUNC("thermal ctrl function not supported\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ pOpData = &pOp->op; ++ pOpData->opId = WMT_OPID_DSNS; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ /*parameter fill */ ++ if ((WMTDSNS_FM_DISABLE <= eType) && (WMTDSNS_FM_GPS_ENABLE >= eType)) { ++ pOpData->au4OpData[0] = WMTDRV_TYPE_FM; ++ pOpData->au4OpData[1] = eType; ++ } ++ ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); ++ else ++ WMT_INFO_FUNC("OPID(%d) type(%d) ok\n\n", pOpData->opId, pOpData->au4OpData[0]); ++ ++ return bRet; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++#else ++INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++#endif ++{ ++ return (INT32) wmt_lib_msgcb_reg(eType, pCb); ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++#else ++INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++#endif ++{ ++ return (INT32) wmt_lib_msgcb_unreg(eType); ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) ++#else ++INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) ++#endif ++{ ++ wmt_lib_ps_set_sdio_psop(own_cb); ++ return 0; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_wmt_sdio_host_awake(VOID) ++#else ++INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) ++#endif ++{ ++ wmt_lib_ps_irq_cb(); ++ return 0; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) ++#endif ++{ ++ P_OSAL_OP pOp = NULL; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ wmt_lib_set_host_assert_info(type, reason, 1); ++ ++ pSignal = &pOp->signal; ++ ++ pOp->op.opId = WMT_OPID_CMD_TEST; ++ ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ /*this test command should be run with usb cable connected, so no host awake is needed */ ++ /* wmt_lib_host_awake_get(); */ ++ pOp->op.au4OpData[0] = 0; ++ ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,assert flow abort\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ /* wmt_lib_host_awake_put(); */ ++ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", ++ pOp->op.opId, ++ pOp->op.au4OpData[0], ++ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); ++ ++ return bRet; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_assert); ++#endif ++ ++INT8 mtk_wcn_wmt_co_clock_flag_get(void) ++{ ++ return wmt_lib_co_clock_get(); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_co_clock_flag_get); ++ ++INT32 mtk_wcn_wmt_system_state_reset(void) ++{ ++ osal_memset(&gBtWifiGpsState, 0, osal_sizeof(gBtWifiGpsState)); ++ osal_memset(&gGpsFmState, 0, osal_sizeof(gGpsFmState)); ++ ++ return 0; ++} ++ ++INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo) ++{ ++ INT32 iRet = -1; ++ ++ if (!pWmtWlanCbInfo) { ++ WMT_ERR_FUNC("wlan cb info in null!\n"); ++ return -1; ++ } ++ ++ WMT_INFO_FUNC("wmt wlan cb register\n"); ++ mtk_wcn_wlan_probe = pWmtWlanCbInfo->wlan_probe_cb; ++ mtk_wcn_wlan_remove = pWmtWlanCbInfo->wlan_remove_cb; ++ mtk_wcn_wlan_bus_tx_cnt = pWmtWlanCbInfo->wlan_bus_cnt_get_cb; ++ mtk_wcn_wlan_bus_tx_cnt_clr = pWmtWlanCbInfo->wlan_bus_cnt_clr_cb; ++ ++ if (gWifiProbed) { ++ WMT_INFO_FUNC("wlan has been done power on,call probe directly\n"); ++ iRet = (*mtk_wcn_wlan_probe) (); ++ if (!iRet) { ++ WMT_INFO_FUNC("call wlan probe OK when do wlan register to wmt\n"); ++ gWifiProbed = 0; ++ } else { ++ WMT_ERR_FUNC("call wlan probe fail(%d) when do wlan register to wmt\n", iRet); ++ return -2; ++ } ++ } ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wlan_reg); ++ ++INT32 mtk_wcn_wmt_wlan_unreg(void) ++{ ++ WMT_INFO_FUNC("wmt wlan cb unregister\n"); ++ mtk_wcn_wlan_probe = NULL; ++ mtk_wcn_wlan_remove = NULL; ++ mtk_wcn_wlan_bus_tx_cnt = NULL; ++ mtk_wcn_wlan_bus_tx_cnt_clr = NULL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wlan_unreg); ++ ++MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value) ++{ ++ g_pwr_off_flag = value; ++ if (g_pwr_off_flag) ++ WMT_DBG_FUNC("enable connsys power off flag\n"); ++ else ++ WMT_INFO_FUNC("disable connsys power off, maybe need trigger coredump!\n"); ++ return g_pwr_off_flag; ++} ++EXPORT_SYMBOL(mtk_wcn_set_connsys_power_off_flag); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++VOID mtk_wcn_wmt_exp_init(void) ++{ ++ MTK_WCN_WMT_EXP_CB_INFO wmtExpCb = { ++ ++ .wmt_func_on_cb = _mtk_wcn_wmt_func_on, ++ .wmt_func_off_cb = _mtk_wcn_wmt_func_off, ++ .wmt_therm_ctrl_cb = _mtk_wcn_wmt_therm_ctrl, ++ .wmt_hwver_get_cb = _mtk_wcn_wmt_hwver_get, ++ .wmt_dsns_ctrl_cb = _mtk_wcn_wmt_dsns_ctrl, ++ .wmt_msgcb_reg_cb = _mtk_wcn_wmt_msgcb_reg, ++ .wmt_msgcb_unreg_cb = _mtk_wcn_wmt_msgcb_unreg, ++ .wmt_sdio_op_reg_cb = _mtk_wcn_stp_wmt_sdio_op_reg, ++ .wmt_sdio_host_awake_cb = _mtk_wcn_stp_wmt_sdio_host_awake, ++ .wmt_assert_cb = _mtk_wcn_wmt_assert ++ }; ++ ++ mtk_wcn_wmt_exp_cb_reg(&wmtExpCb); ++} ++ ++VOID mtk_wcn_wmt_exp_deinit(void) ++{ ++ mtk_wcn_wmt_exp_cb_unreg(); ++} ++#ifdef CONFIG_MTK_COMBO_ANT ++/* ++ ctrlId: get ram code status opId or ram code download opId ++ pBuf: pointer to ANT ram code ++ length: total length of ANT ram code ++*/ ++ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, ++ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq) ++{ ++ ENUM_WMT_ANT_RAM_STATUS eRet = 0; ++ P_OSAL_OP pOp = NULL; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ ++ /*1. parameter validation check */ ++ /*for WMT_ANT_RAM_GET_STATUS, ignore pBuf and length */ ++ /*for WMT_ANT_RAM_DOWNLOAD, ++ pBuf must not be NULL, kernel space memory pointer ++ length must be large than 0 */ ++ ++ if ((WMT_ANT_RAM_GET_STATUS > ctrlId) || (WMT_ANT_RAM_CTRL_MAX <= ctrlId)) { ++ WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); ++ eRet = WMT_ANT_RAM_PARA_ERR; ++ return eRet; ++ } ++ ++ if ((WMT_ANT_RAM_DOWNLOAD == ctrlId) && ++ ((NULL == pBuf) || ++ (0 >= length) || ++ (1000 < length) || (seq >= WMT_ANT_RAM_SEQ_MAX) || (seq < WMT_ANT_RAM_START_PKT))) { ++ eRet = WMT_ANT_RAM_PARA_ERR; ++ WMT_ERR_FUNC ++ ("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x),seq(%d) .\n", ++ ctrlId, pBuf, length, seq); ++ return eRet; ++ } ++ /*get WMT opId */ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_DBG_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = ++ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD; ++ ++ pOp->op.opId = ++ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? WMT_OPID_ANT_RAM_DOWN : WMT_OPID_ANT_RAM_STA_GET; ++ pOp->op.au4OpData[0] = (size_t) pBuf; ++ pOp->op.au4OpData[1] = length; ++ pOp->op.au4OpData[2] = seq; ++ ++ ++ /*disable PSM monitor */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ /*wakeup wmtd thread */ ++ bRet = wmt_lib_put_act_op(pOp); ++ ++ /*enable PSM monitor */ ++ ENABLE_PSM_MONITOR(); ++ ++ WMT_DBG_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n", ++ pOp->op.opId, ++ bRet, ++ pOp->op.au4OpData[2], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); ++ ++ /*check return value and return result */ ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ eRet = WMT_ANT_RAM_OP_ERR; ++ } else { ++ eRet = (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? ++ WMT_ANT_RAM_DOWN_OK : ++ ((1 == pOp->op.au4OpData[2]) ? WMT_ANT_RAM_EXIST : WMT_ANT_RAM_NOT_EXIST); ++ } ++ ++ return eRet; ++ ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_ant_ram_ctrl); ++#endif ++ ++#endif ++VOID mtk_wcn_wmt_set_wifi_ver(UINT32 Value) ++{ ++ wmt_lib_soc_set_wifiver(Value); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_set_wifi_ver); +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +new file mode 100644 +index 000000000000..eb37baf87b02 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +@@ -0,0 +1,27 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++ccflags-y += \ ++ -I$(src)/../../linux/include \ ++ -I$(src)/../../linux/pri/include \ ++ -I$(src)/../../core/include \ ++ -I$(src)/../../include \ ++ -I$(src)/../include \ ++ -I$(src)/../../../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach \ ++ -DMTK_BT_HCI=1 ++ ++ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 ++ ++ifeq ($(CONFIG_MTK_TC1_FEATURE), y) ++ ccflags-y += -DCFG_TC1_FEATURE=1 ++else ++ ccflags-y += -DCFG_TC1_FEATURE=0 ++endif ++ ++obj-y += osal.o \ ++ bgw_desense.o \ ++ wmt_idc.o ++obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o ++obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c +new file mode 100644 +index 000000000000..11e45aa13087 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c +@@ -0,0 +1,153 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include "bgw_desense.h" ++ ++static struct sock *g_nl_sk; ++/* static struct sockaddr_nl src_addr, des_addr; */ ++/* static struct iovec iov; */ ++static int pid; ++/* static struct msghdr msg; */ ++ ++void bgw_destroy_netlink_kernel(void) ++{ ++ if (g_nl_sk != NULL) { ++ /* sock_release(g_nl_sk->sk_socket); */ ++ netlink_kernel_release(g_nl_sk); ++ MSG("release socket\n"); ++ return; ++ } ++ ERR("no socket yet\n"); ++} ++ ++void send_command_to_daemon(const int command /*struct sk_buff *skb */) ++{ ++/* ++ struct iphdr *iph; ++ struct ethhdr *ehdr; ++ */ ++ struct nlmsghdr *nlh; ++ struct sk_buff *nl_skb; ++ int res; ++ ++ MSG("here we will send command to native daemon\n"); ++/* if(skb == NULL) ++ { ++ ERR("invalid sk_buff\n"); ++ return; ++ } ++*/ ++ if (!g_nl_sk) { ++ ERR("invalid socket\n"); ++ return; ++ } ++ if (pid == 0) { ++ ERR("invalid native process pid\n"); ++ return; ++ } ++ /*alloc data buffer for sending to native */ ++ /*malloc data space at least 1500 bytes, which is ethernet data length */ ++ nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC); ++ if (nl_skb == NULL) { ++ ERR("malloc skb error\n"); ++ return; ++ } ++ MSG("malloc data space done\n"); ++ /* ++ ehdr = eth_hdr(skb); ++ iph = ip_hdr(skb); ++ */ ++ ++/* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */ ++ nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0); ++ if (nlh == NULL) { ++ MSG("nlh is NULL\n"); ++ kfree_skb(nl_skb); ++ return; ++ } ++ NETLINK_CB(nl_skb).portid = 0; ++ ++/* memcpy(NLMSG_DATA(nlh), ACK, 5); */ ++ *(char *)NLMSG_DATA(nlh) = command; ++ res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT); ++ if (res == 0) { ++ MSG("send to user space process error\n"); ++ return; ++ } ++ ERR("send to user space process done, data length = %d\n", res); ++} ++ ++static void nl_data_handler(struct sk_buff *__skb) ++{ ++ struct sk_buff *skb; ++ struct nlmsghdr *nlh; ++ int i; ++ int len; ++ char str[128]; ++ ++ MSG("we got netlink message\n"); ++ len = NLMSG_SPACE(MAX_NL_MSG_LEN); ++ skb = skb_get(__skb); ++ if (skb == NULL) ++ ERR("skb_get return NULL"); ++ if (skb->len >= NLMSG_SPACE(0)) { /*presume there is 5byte payload at leaset */ ++ MSG("length is enough\n"); ++ nlh = nlmsg_hdr(skb); /* point to data which include in skb */ ++ memcpy(str, NLMSG_DATA(nlh), sizeof(str)); ++ for (i = 0; i < 3; i++) ++ MSG("str[%d = %c]", i, str[i]); ++ MSG("str[0] = %d, str[1] = %d, str[2] = %d\n", str[0], str[1], str[2]); ++ if (str[0] == 'B' && str[1] == 'G' && str[2] == 'W') { ++ MSG("got native daemon init command, record it's pid\n"); ++ pid = nlh->nlmsg_pid; /*record the native process PID */ ++ MSG("native daemon pid is %d\n", pid); ++ } else { ++ ERR("this is not BGW message, ignore it\n"); ++ return; ++ } ++ } else { ++ ERR("not engouth data length\n"); ++ return; ++ } ++ ++ kfree_skb(skb); ++ ++ send_command_to_daemon(ACK); ++} ++ ++int bgw_init_socket(void) ++{ ++ struct netlink_kernel_cfg cfg; ++ ++ memset(&cfg, 0, sizeof(cfg)); ++ cfg.input = nl_data_handler; ++ ++ g_nl_sk = __netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg); ++ ++ if (g_nl_sk == NULL) { ++ ERR("netlink_kernel_create error\n"); ++ return -1; ++ } ++ MSG("netlink_kernel_create ok\n"); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c +new file mode 100644 +index 000000000000..4ebbd51c0259 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c +@@ -0,0 +1,1210 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "osal.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ ++static UINT16 const crc16_table[256] = { ++ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, ++ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, ++ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, ++ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, ++ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, ++ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, ++ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, ++ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, ++ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, ++ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, ++ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, ++ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, ++ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, ++ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, ++ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, ++ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, ++ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, ++ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, ++ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, ++ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, ++ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, ++ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, ++ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, ++ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, ++ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, ++ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, ++ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, ++ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, ++ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, ++ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, ++ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, ++ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 ++}; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*string operations*/ ++_osal_inline_ UINT32 osal_strlen(const char *str) ++{ ++ return strlen(str); ++} ++ ++_osal_inline_ INT32 osal_strcmp(const char *dst, const char *src) ++{ ++ return strcmp(dst, src); ++} ++ ++_osal_inline_ INT32 osal_strncmp(const char *dst, const char *src, UINT32 len) ++{ ++ return strncmp(dst, src, len); ++} ++ ++_osal_inline_ char *osal_strcpy(char *dst, const char *src) ++{ ++ return strcpy(dst, src); ++} ++ ++_osal_inline_ char *osal_strncpy(char *dst, const char *src, UINT32 len) ++{ ++ return strncpy(dst, src, len); ++} ++ ++_osal_inline_ char *osal_strcat(char *dst, const char *src) ++{ ++ return strcat(dst, src); ++} ++ ++_osal_inline_ char *osal_strncat(char *dst, const char *src, UINT32 len) ++{ ++ return strncat(dst, src, len); ++} ++ ++_osal_inline_ char *osal_strchr(const char *str, UINT8 c) ++{ ++ return strchr(str, c); ++} ++ ++_osal_inline_ char *osal_strsep(char **str, const char *c) ++{ ++ return strsep(str, c); ++} ++ ++_osal_inline_ int osal_strtol(const char *str, UINT32 adecimal, long *res) ++{ ++ return kstrtol(str, adecimal, res); ++} ++ ++_osal_inline_ char *osal_strstr(char *str1, const char *str2) ++{ ++ return strstr(str1, str2); ++} ++ ++INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...) ++{ ++ INT32 iRet = 0; ++ va_list args; ++ ++ /*va_start(args, fmt); */ ++ va_start(args, fmt); ++ /*iRet = snprintf(buf, len, fmt, args); */ ++ iRet = vsnprintf(buf, len, fmt, args); ++ va_end(args); ++ ++ return iRet; ++} ++ ++INT32 osal_err_print(const char *str, ...) ++{ ++ va_list args; ++ char tempString[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_err("%s", tempString); ++ ++ return 0; ++} ++ ++INT32 osal_dbg_print(const char *str, ...) ++{ ++ va_list args; ++ char tempString[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_debug("%s", tempString); ++ ++ return 0; ++} ++ ++INT32 osal_warn_print(const char *str, ...) ++{ ++ va_list args; ++ char tempString[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_warn("%s", tempString); ++ ++ return 0; ++} ++ ++INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line) ++{ ++ if (!expr) { ++ pr_warn("%s (%d)\n", file, line); ++ /*BUG_ON(!expr); */ ++#ifdef CFG_COMMON_GPIO_DBG_PIN ++/* package this part */ ++ mt_set_gpio_out(GPIO70, GPIO_OUT_ZERO); ++ pr_warn("toggle GPIO70\n"); ++ udelay(10); ++ mt_set_gpio_out(GPIO70, GPIO_OUT_ONE); ++#endif ++ return 1; ++ } ++ return 0; ++ ++} ++ ++INT32 osal_dbg_assert_aee(const char *module, const char *detail_description) ++{ ++ osal_err_print("[WMT-ASSERT]" "[E][Module]:%s, [INFO]%s\n", module, detail_description); ++ ++#ifdef WMT_PLAT_ALPS ++ /* aee_kernel_warning(module,detail_description); */ ++ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_WCN_ISSUE_INFO, module, detail_description); ++#endif ++ return 0; ++} ++ ++INT32 osal_sprintf(char *str, const char *format, ...) ++{ ++ INT32 iRet = 0; ++ va_list args; ++ ++ va_start(args, format); ++ iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args); ++ va_end(args); ++ ++ return iRet; ++} ++ ++_osal_inline_ VOID *osal_malloc(UINT32 size) ++{ ++ return vmalloc(size); ++} ++ ++_osal_inline_ VOID osal_free(const VOID *dst) ++{ ++ vfree(dst); ++} ++ ++_osal_inline_ VOID *osal_memset(VOID *buf, INT32 i, UINT32 len) ++{ ++ return memset(buf, i, len); ++} ++ ++_osal_inline_ VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len) ++{ ++#ifdef CONFIG_MTK_WCN_ARM64 ++ char *tmp; ++ const char *s; ++ size_t i; ++ ++ tmp = dst; ++ s = src; ++ for (i = 0; i < len; i++) ++ tmp[i] = s[i]; ++ ++ return dst; ++ ++#else ++ return memcpy(dst, src, len); ++#endif ++} ++ ++_osal_inline_ INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len) ++{ ++ return memcmp(buf1, buf2, len); ++} ++ ++_osal_inline_ UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length) ++{ ++ UINT16 crc = 0; ++ UINT32 i = 0; ++ ++ /* FIXME: Add STP checksum feature */ ++ crc = 0; ++ for (i = 0; i < length; i++, buffer++) ++ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; ++ ++ return crc; ++} ++ ++_osal_inline_ VOID osal_thread_show_stack(P_OSAL_THREAD pThread) ++{ ++ return show_stack(pThread->pThread, NULL); ++} ++ ++/* ++ *OSAL layer Thread Opeartion related APIs ++ * ++ * ++*/ ++_osal_inline_ INT32 osal_thread_create(P_OSAL_THREAD pThread) ++{ ++ pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName); ++ if (NULL == pThread->pThread) ++ return -1; ++ ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_thread_run(P_OSAL_THREAD pThread) ++{ ++ if (pThread->pThread) { ++ wake_up_process(pThread->pThread); ++ return 0; ++ } else { ++ return -1; ++ } ++} ++ ++_osal_inline_ INT32 osal_thread_stop(P_OSAL_THREAD pThread) ++{ ++ INT32 iRet; ++ ++ if ((pThread) && (pThread->pThread)) { ++ iRet = kthread_stop(pThread->pThread); ++ /* pThread->pThread = NULL; */ ++ return iRet; ++ } ++ return -1; ++} ++ ++_osal_inline_ INT32 osal_thread_should_stop(P_OSAL_THREAD pThread) ++{ ++ if ((pThread) && (pThread->pThread)) ++ return kthread_should_stop(); ++ else ++ return 1; ++ ++} ++ ++_osal_inline_ INT32 ++osal_thread_wait_for_event(P_OSAL_THREAD pThread, P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker) ++{ ++ /* P_DEV_WMT pDevWmt;*/ ++ ++ if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) { ++ /* pDevWmt = (P_DEV_WMT)(pThread->pThreadData);*/ ++ return wait_event_interruptible(pEvent->waitQueue, (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) || */ ++ osal_thread_should_stop(pThread) ++ || (*pChecker) (pThread))); ++ } ++ return -1; ++} ++ ++_osal_inline_ INT32 osal_thread_destroy(P_OSAL_THREAD pThread) ++{ ++ if (pThread && (pThread->pThread)) { ++ kthread_stop(pThread->pThread); ++ pThread->pThread = NULL; ++ } ++ return 0; ++} ++ ++/* ++ *OSAL layer Signal Opeartion related APIs ++ *initialization ++ *wait for signal ++ *wait for signal timerout ++ *raise signal ++ *destroy a signal ++ * ++*/ ++ ++_osal_inline_ INT32 osal_signal_init(P_OSAL_SIGNAL pSignal) ++{ ++ if (pSignal) { ++ init_completion(&pSignal->comp); ++ return 0; ++ } else { ++ return -1; ++ } ++} ++ ++_osal_inline_ INT32 osal_wait_for_signal(P_OSAL_SIGNAL pSignal) ++{ ++ if (pSignal) { ++ wait_for_completion_interruptible(&pSignal->comp); ++ return 0; ++ } else { ++ return -1; ++ } ++} ++ ++_osal_inline_ INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal) ++{ ++ /* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */ ++ /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. ++ * Avoid using *interruptible" version in order to complete our jobs, such ++ * as function off gracefully. ++ */ ++ return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); ++} ++ ++_osal_inline_ INT32 osal_raise_signal(P_OSAL_SIGNAL pSignal) ++{ ++ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ ++ complete(&pSignal->comp); ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_signal_deinit(P_OSAL_SIGNAL pSignal) ++{ ++ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ ++ pSignal->timeoutValue = 0; ++ return 0; ++} ++ ++/* ++ *OSAL layer Event Opeartion related APIs ++ *initialization ++ *wait for signal ++ *wait for signal timerout ++ *raise signal ++ *destroy a signal ++ * ++*/ ++ ++INT32 osal_event_init(P_OSAL_EVENT pEvent) ++{ ++ init_waitqueue_head(&pEvent->waitQueue); ++ ++ return 0; ++} ++ ++INT32 osal_wait_for_event(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) ++{ ++ return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa)); ++} ++ ++INT32 osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) ++{ ++ return wait_event_interruptible_timeout(pEvent->waitQueue, condition(cond_pa), ++ msecs_to_jiffies(pEvent->timeoutValue)); ++} ++ ++INT32 osal_trigger_event(P_OSAL_EVENT pEvent) ++{ ++ INT32 ret = 0; ++ ++ wake_up_interruptible(&pEvent->waitQueue); ++ return ret; ++} ++ ++INT32 osal_event_deinit(P_OSAL_EVENT pEvent) ++{ ++ return 0; ++} ++ ++_osal_inline_ long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) ++{ ++ UINT32 ms = pEvent->timeoutValue; ++ ++ if (ms != 0) { ++ return wait_event_interruptible_timeout(pEvent->waitQueue, test_bit(bitOffset, pState), ++ msecs_to_jiffies(ms)); ++ } else { ++ return wait_event_interruptible(pEvent->waitQueue, test_bit(bitOffset, pState)); ++ } ++ ++} ++ ++_osal_inline_ long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) ++{ ++ UINT32 ms = pEvent->timeoutValue; ++ ++ if (ms != 0) { ++ return wait_event_interruptible_timeout(pEvent->waitQueue, !test_bit(bitOffset, pState), ++ msecs_to_jiffies(ms)); ++ } else { ++ return wait_event_interruptible(pEvent->waitQueue, !test_bit(bitOffset, pState)); ++ } ++ ++} ++ ++/* ++ *bit test and set/clear operations APIs ++ * ++ * ++*/ ++#if OS_BIT_OPS_SUPPORT ++#define osal_bit_op_lock(x) ++#define osal_bit_op_unlock(x) ++#else ++ ++_osal_inline_ INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) ++{ ++ ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) ++{ ++ ++ return 0; ++} ++#endif ++_osal_inline_ INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ osal_bit_op_lock(&(pData->opLock)); ++ clear_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ osal_bit_op_lock(&(pData->opLock)); ++ set_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ UINT32 iRet = 0; ++ ++ osal_bit_op_lock(&(pData->opLock)); ++ iRet = test_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return iRet; ++} ++ ++_osal_inline_ INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ UINT32 iRet = 0; ++ ++ osal_bit_op_lock(&(pData->opLock)); ++ iRet = test_and_clear_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return iRet; ++ ++} ++ ++_osal_inline_ INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ UINT32 iRet = 0; ++ ++ osal_bit_op_lock(&(pData->opLock)); ++ iRet = test_and_set_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return iRet; ++} ++ ++/* ++ *tiemr operations APIs ++ *create ++ *stop ++ * modify ++ *create ++ *delete ++ * ++*/ ++ ++INT32 osal_timer_create(P_OSAL_TIMER pTimer) ++{ ++ struct timer_list *timer = &pTimer->timer; ++ ++ init_timer(timer); ++ timer->function = pTimer->timeoutHandler; ++ timer->data = (unsigned long)pTimer->timeroutHandlerData; ++ return 0; ++} ++ ++INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms) ++{ ++ ++ struct timer_list *timer = &pTimer->timer; ++ ++ timer->expires = jiffies + (ms / (1000 / HZ)); ++ add_timer(timer); ++ return 0; ++} ++ ++INT32 osal_timer_stop(P_OSAL_TIMER pTimer) ++{ ++ struct timer_list *timer = &pTimer->timer; ++ ++ del_timer(timer); ++ return 0; ++} ++ ++INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer) ++{ ++ struct timer_list *timer = &pTimer->timer; ++ ++ del_timer_sync(timer); ++ return 0; ++} ++ ++INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms) ++{ ++ ++ mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ)); ++ return 0; ++} ++ ++INT32 _osal_fifo_init(OSAL_FIFO *pFifo, UINT8 *buf, UINT32 size) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = -1; ++ ++ if (!pFifo) { ++ pr_err("pFifo must be !NULL\n"); ++ return -1; ++ } ++ if (pFifo->pFifoBody) { ++ pr_err("pFifo->pFifoBody must be NULL\n"); ++ pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody); ++ return -1; ++ } ++ fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); ++ if (!buf) { ++ /*fifo's buffer is not ready, we allocate automatically */ ++ ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC); ++ } else { ++ if (is_power_of_2(size)) { ++ kfifo_init(fifo, buf, size); ++ ret = 0; ++ } else { ++ kfifo_free(fifo); ++ fifo = NULL; ++ ret = -1; ++ } ++ } ++ ++ pFifo->pFifoBody = fifo; ++ return (ret < 0) ? (-1) : (0); ++} ++ ++INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ kfifo_free(fifo); ++ ++ return 0; ++} ++ ++INT32 _osal_fifo_size(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_size(fifo); ++ ++ return ret; ++} ++ ++/*returns unused bytes in fifo*/ ++INT32 _osal_fifo_avail_size(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_avail(fifo); ++ ++ return ret; ++} ++ ++/*returns used bytes in fifo*/ ++INT32 _osal_fifo_len(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_len(fifo); ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_is_empty(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_is_empty(fifo); ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_is_full(fifo); ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_data_in(OSAL_FIFO *pFifo, const VOID *buf, UINT32 len) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) { ++ ret = kfifo_in(fifo, buf, len); ++ } else { ++ pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n", ++ __func__, len, _osal_fifo_avail_size(pFifo), buf); ++ ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, UINT32 len) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo && buf && (len <= _osal_fifo_len(pFifo))) { ++ ret = kfifo_out(fifo, buf, len); ++ } else { ++ pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n", ++ __func__, len, _osal_fifo_len(pFifo), buf); ++ ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_reset(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ kfifo_reset(fifo); ++ ++ return 0; ++} ++ ++INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size) ++{ ++ if (!pFifo) { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ pFifo->FifoInit = _osal_fifo_init; ++ pFifo->FifoDeInit = _osal_fifo_deinit; ++ pFifo->FifoSz = _osal_fifo_size; ++ pFifo->FifoAvailSz = _osal_fifo_avail_size; ++ pFifo->FifoLen = _osal_fifo_len; ++ pFifo->FifoIsEmpty = _osal_fifo_is_empty; ++ pFifo->FifoIsFull = _osal_fifo_is_full; ++ pFifo->FifoDataIn = _osal_fifo_data_in; ++ pFifo->FifoDataOut = _osal_fifo_data_out; ++ pFifo->FifoReset = _osal_fifo_reset; ++ ++ if (NULL != pFifo->pFifoBody) { ++ pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__); ++ pFifo->FifoDeInit(pFifo->pFifoBody); ++ pFifo->pFifoBody = NULL; ++ } ++ ++ pFifo->FifoInit(pFifo, buffer, size); ++ ++ return 0; ++} ++ ++VOID osal_fifo_deinit(P_OSAL_FIFO pFifo) ++{ ++ if (pFifo) ++ pFifo->FifoDeInit(pFifo); ++ else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ return; ++ } ++ kfree(pFifo->pFifoBody); ++} ++ ++INT32 osal_fifo_reset(P_OSAL_FIFO pFifo) ++{ ++ INT32 ret = -1; ++ ++ if (pFifo) { ++ ret = pFifo->FifoReset(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = -1; ++ } ++ return ret; ++} ++ ++UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoDataIn(pFifo, buffer, size); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoDataOut(pFifo, buffer, size); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_len(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoLen(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoSz(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoAvailSz(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoIsEmpty(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoIsFull(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ return ret; ++} ++ ++INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ wakeup_source_init(&pLock->wake_lock, pLock->name); ++ #else ++ wake_lock_init(&pLock->wake_lock, WAKE_LOCK_SUSPEND, pLock->name); ++ #endif ++ return 0; ++} ++ ++INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ wakeup_source_trash(&pLock->wake_lock); ++ #else ++ wake_lock_destroy(&pLock->wake_lock); ++ #endif ++ return 0; ++} ++ ++INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_stay_awake(&pLock->wake_lock); ++ #else ++ wake_lock(&pLock->wake_lock); ++ #endif ++ ++ return 0; ++} ++ ++INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_relax(&pLock->wake_lock); ++ #else ++ wake_unlock(&pLock->wake_lock); ++ #endif ++ ++ return 0; ++ ++} ++ ++INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock) ++{ ++ INT32 count = 0; ++ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ count = pLock->wake_lock.active; ++ #else ++ count = wake_lock_active(&pLock->wake_lock); ++ #endif ++ return count; ++} ++ ++/* ++ *sleepable lock operations APIs ++ *init ++ *lock ++ *unlock ++ *destroy ++ * ++*/ ++ ++#if !defined(CONFIG_PROVE_LOCKING) ++INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ spin_lock_init(&(pUSL->lock)); ++ return 0; ++} ++#endif ++ ++INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ spin_lock_irqsave(&(pUSL->lock), pUSL->flag); ++ return 0; ++} ++ ++INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); ++ return 0; ++} ++ ++INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ return 0; ++} ++ ++/* ++ *unsleepable operations APIs ++ *init ++ *lock ++ *unlock ++ *destroy ++ ++ * ++*/ ++ ++#if !defined(CONFIG_PROVE_LOCKING) ++INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ mutex_init(&pSL->lock); ++ return 0; ++} ++#endif ++ ++INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ return mutex_lock_killable(&pSL->lock); ++} ++ ++INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ mutex_unlock(&pSL->lock); ++ return 0; ++} ++ ++INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ mutex_destroy(&pSL->lock); ++ return 0; ++} ++ ++INT32 osal_sleep_ms(UINT32 ms) ++{ ++ msleep(ms); ++ return 0; ++} ++ ++INT32 osal_udelay(UINT32 us) ++{ ++ udelay(us); ++ return 0; ++} ++ ++INT32 osal_gettimeofday(PINT32 sec, PINT32 usec) ++{ ++ INT32 ret = 0; ++ struct timeval now; ++ ++ do_gettimeofday(&now); ++ ++ if (sec != NULL) ++ *sec = now.tv_sec; ++ else ++ ret = -1; ++ ++ if (usec != NULL) ++ *usec = now.tv_usec; ++ else ++ ret = -1; ++ ++ return ret; ++} ++ ++INT32 osal_printtimeofday(const PUINT8 prefix) ++{ ++ INT32 ret; ++ INT32 sec; ++ INT32 usec; ++ ++ ret = osal_gettimeofday(&sec, &usec); ++ ret += osal_dbg_print("%s>sec=%d, usec=%d\n", prefix, sec, usec); ++ ++ return ret; ++} ++ ++VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, const UINT32 len, const UINT32 limit) ++{ ++ INT32 k; ++ UINT32 dump_len; ++ ++ pr_warn("start of dump>[%s] len=%d, limit=%d,", title, len, limit); ++ ++ dump_len = ((0 != limit) && (len > limit)) ? limit : len; ++#if 0 ++ if (limit != 0) ++ len = (len > limit) ? (limit) : (len); ++ ++#endif ++ ++ for (k = 0; k < dump_len; k++) { ++ if ((k != 0) && (k % 16 == 0)) ++ pr_cont("\n"); ++ pr_cont("0x%02x ", buf[k]); ++ } ++ pr_warn("op.opId : 0xFFFFFFFF; ++} ++ ++MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp) ++{ ++ return (pOp && pOp->signal.timeoutValue) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; ++} ++ ++VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result) ++{ ++ if (pOp) { ++ pOp->result = result; ++ osal_raise_signal(&pOp->signal); ++ } ++} ++ ++VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result) ++{ ++ if (pOp) ++ pOp->result = result; ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c +new file mode 100644 +index 000000000000..190fa3944d80 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c +@@ -0,0 +1,899 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if WMT_CREATE_NODE_DYNAMIC ++#include ++#endif ++#include ++ ++#include "osal_typedef.h" ++#include "stp_exp.h" ++#include "wmt_exp.h" ++ ++MODULE_LICENSE("Dual BSD/GPL"); ++ ++#ifdef MTK_BT_HCI ++#define MTK_BT_DEBUG 0 ++#include ++#include ++#endif ++ ++ ++#define BT_DRIVER_NAME "mtk_stp_BT_chrdev" ++#define BT_DEV_MAJOR 192 /* Never used number */ ++ ++#define PFX "[MTK-BT] " ++#define BT_LOG_DBG 3 ++#define BT_LOG_INFO 2 ++#define BT_LOG_WARN 1 ++#define BT_LOG_ERR 0 ++ ++#define COMBO_IOC_MAGIC 0xb0 ++#define COMBO_IOCTL_FW_ASSERT _IOWR(COMBO_IOC_MAGIC, 0, int) ++#define COMBO_IOCTL_BT_IC_HW_VER _IOWR(COMBO_IOC_MAGIC, 1, void*) ++#define COMBO_IOCTL_BT_IC_FW_VER _IOWR(COMBO_IOC_MAGIC, 2, void*) ++#define COMBO_IOC_BT_HWVER _IOWR(COMBO_IOC_MAGIC, 3, void*) ++ ++static UINT32 gDbgLevel = BT_LOG_INFO; ++ ++#define BT_DBG_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_DBG) \ ++ pr_debug(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++#define BT_INFO_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_INFO) \ ++ pr_warn(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++#define BT_WARN_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_WARN) \ ++ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++#define BT_ERR_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_ERR) \ ++ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++ ++#define VERSION "1.0" ++ ++#ifdef MTK_BT_HCI ++ ++#define NUM_REASSEMBLY 32 ++struct mtk_hci { ++ struct hci_dev *hdev; ++ struct work_struct work; ++ struct sk_buff_head txq; ++ struct sk_buff *reassembly[NUM_REASSEMBLY]; ++}; ++ ++static struct mtk_hci mtk_hci; ++ ++#endif ++ ++#if WMT_CREATE_NODE_DYNAMIC ++struct class *stpbt_class = NULL; ++struct device *stpbt_dev = NULL; ++#endif ++ ++static INT32 BT_devs = 1; /* Device count */ ++static INT32 BT_major = BT_DEV_MAJOR; /* Dynamic allocation */ ++module_param(BT_major, uint, 0); ++static struct cdev BT_cdev; ++ ++#define BT_BUFFER_SIZE 2048 ++static UINT8 i_buf[BT_BUFFER_SIZE]; /* Input buffer of read() */ ++static UINT8 o_buf[BT_BUFFER_SIZE]; /* Output buffer of write() */ ++ ++static struct semaphore wr_mtx, rd_mtx; ++/* Wait queue for poll and read */ ++static wait_queue_head_t inq; ++static DECLARE_WAIT_QUEUE_HEAD(BT_wq); ++static INT32 flag; ++/* Reset flag for whole chip reset senario */ ++static volatile INT32 rstflag; ++ ++#ifdef MTK_BT_HCI ++static int hci_reassembly(struct hci_dev *hdev, int type, void *data, ++ int count, __u8 index) ++{ ++ int len = 0; ++ int hlen = 0; ++ int offset = 0; ++ int remain = count; ++ struct sk_buff *skb; ++ struct bt_skb_cb *scb; ++ u16 opcode = 0; ++ unsigned char *pdata = data; ++ ++ struct mtk_hci *info = NULL; ++ struct hci_event_hdr *ehdr = NULL; ++ struct hci_ev_cmd_complete *ev = NULL; ++ struct hci_rp_read_local_ext_features *ext = NULL; ++ ++ info = hci_get_drvdata(hdev); ++ if ( NULL == info ) { ++ printk(KERN_ERR "mtk_bt_hci: invalid info point\n"); ++ return 0; ++ } ++ ++ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || ++ index >= NUM_REASSEMBLY) ++ return -EILSEQ; ++ ++ skb = info->reassembly[index]; ++ ++ if (!skb) { ++ switch (type) { ++ case HCI_ACLDATA_PKT: ++ len = HCI_MAX_FRAME_SIZE; ++ hlen = HCI_ACL_HDR_SIZE; ++ break; ++ case HCI_EVENT_PKT: ++ len = HCI_MAX_EVENT_SIZE; ++ hlen = HCI_EVENT_HDR_SIZE; ++ break; ++ case HCI_SCODATA_PKT: ++ len = HCI_MAX_SCO_SIZE; ++ hlen = HCI_SCO_HDR_SIZE; ++ break; ++ } ++ ++ skb = bt_skb_alloc(len, GFP_ATOMIC); ++ if (!skb) ++ return -ENOMEM; ++ ++ scb = (void *) skb->cb; ++ scb->expect = hlen; ++ scb->pkt_type = type; ++ ++ info->reassembly[index] = skb; ++ } ++ ++ while (count) { ++ scb = (void *) skb->cb; ++ len = min_t(uint, scb->expect, count); ++ ++ /* ++ * Workaround for MT7623+MT6625 BT: the max page in response of cmd READ_LOCAL_EXT_FEATURES ++ * should be 1, instead of 2, so changing it to 1 here ++ */ ++ ++ if (HCI_EVENT_PKT == type) ++ { ++ ehdr = (void *)pdata; ++ offset = sizeof(struct hci_event_hdr); ++ if ( HCI_EV_CMD_COMPLETE == ehdr->evt) ++ { ++ ev = (struct hci_ev_cmd_complete *)&pdata[offset]; ++ ++ offset += sizeof(struct hci_ev_cmd_complete); ++ ++ opcode = __le16_to_cpu(ev->opcode); ++ if(HCI_OP_READ_LOCAL_EXT_FEATURES == opcode) { ++ ext = (struct hci_rp_read_local_ext_features *) &pdata[offset]; ++ if( !ext->status && ext->max_page >= 2) { ++ pr_info("%s: this workaround is applied for mediatek BT\n", __func__); ++ ext->max_page = 1; ++ } ++ } ++ ++ } ++ } ++ ++ memcpy(skb_put(skb, len), data, len); ++ ++ count -= len; ++ data += len; ++ scb->expect -= len; ++ remain = count; ++ ++ switch (type) { ++ case HCI_EVENT_PKT: ++ if (skb->len == HCI_EVENT_HDR_SIZE) { ++ struct hci_event_hdr *h = hci_event_hdr(skb); ++ ++ scb->expect = h->plen; ++ ++ if (skb_tailroom(skb) < scb->expect) { ++ kfree_skb(skb); ++ info->reassembly[index] = NULL; ++ return -ENOMEM; ++ } ++ } ++ ++ break; ++ ++ case HCI_ACLDATA_PKT: ++ if (skb->len == HCI_ACL_HDR_SIZE) { ++ struct hci_acl_hdr *h = hci_acl_hdr(skb); ++ ++ scb->expect = __le16_to_cpu(h->dlen); ++ ++ if (skb_tailroom(skb) < scb->expect) { ++ kfree_skb(skb); ++ info->reassembly[index] = NULL; ++ return -ENOMEM; ++ } ++ } ++ break; ++ ++ case HCI_SCODATA_PKT: ++ if (skb->len == HCI_SCO_HDR_SIZE) { ++ struct hci_sco_hdr *h = hci_sco_hdr(skb); ++ ++ scb->expect = h->dlen; ++ ++ if (skb_tailroom(skb) < scb->expect) { ++ kfree_skb(skb); ++ info->reassembly[index] = NULL; ++ return -ENOMEM; ++ } ++ } ++ break; ++ } ++ ++ if (scb->expect == 0) { ++ /* Complete frame */ ++ ++ bt_cb(skb)->pkt_type = type; ++ hci_recv_frame(hdev, skb); ++ ++ info->reassembly[index] = NULL; ++ return remain; ++ } ++ } ++ ++ return remain; ++} ++ ++int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) ++{ ++ int rem = 0; ++ ++ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ++ return -EILSEQ; ++ ++ while (count) { ++ rem = hci_reassembly(hdev, type, data, count, type - 1); ++ if (rem < 0) ++ return rem; ++ ++ data += (count - rem); ++ count = rem; ++ } ++ ++ return rem; ++} ++#endif ++ ++#ifdef MTK_BT_HCI ++void ++hex_dump(char *prefix, char *p, int len) ++{ ++ int i; ++ ++ pr_err("%s ", prefix); ++ for (i = 0; i < len; i++) ++ pr_err("%02x ", (*p++ & 0xff)); ++ pr_err("\n"); ++} ++ ++static int ++mtk_bt_hci_open(struct hci_dev *hdev) ++{ ++ int err = 0; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ err = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); ++ if (err != MTK_WCN_BOOL_TRUE) { ++ pr_err("%s func on failed with %d\n", __func__, err); ++ return -ENODEV; ++ } ++ ++ set_bit(HCI_RUNNING, &hdev->flags); ++ ++ mtk_wcn_stp_set_bluez(1); ++ ++ return 0; ++} ++ ++static int ++mtk_bt_hci_close(struct hci_dev *hdev) ++{ ++ int err = 0; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ mtk_wcn_stp_set_bluez(0); ++ ++ clear_bit(HCI_RUNNING, &hdev->flags); ++ ++ err = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); ++ if (err != MTK_WCN_BOOL_TRUE) { ++ pr_err("%s func off failed with %d\n", __func__, err); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static void ++mtk_bt_hci_work(struct work_struct *work) ++{ ++ int err; ++ struct sk_buff *skb; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ while ((skb = skb_dequeue(&mtk_hci.txq))) { ++ skb_push(skb, 1); ++ skb->data[0] = bt_cb(skb)->pkt_type; ++ ++#if MTK_BT_DEBUG == 1 ++ hex_dump(">>", skb->data, skb->len); ++#endif ++ ++ err = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX); ++ if (err < 0) { ++ pr_err("%s err=%d\n", __func__, err); ++ mtk_hci.hdev->stat.err_tx++; ++ skb_queue_head(&mtk_hci.txq, skb); ++ break; ++ } ++ ++ mtk_hci.hdev->stat.byte_tx += skb->len; ++ kfree_skb(skb); ++ } ++} ++ ++static int ++mtk_bt_hci_send(struct hci_dev *hdev, struct sk_buff *skb) ++{ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ if (mtk_hci.hdev && !test_bit(HCI_RUNNING, &mtk_hci.hdev->flags)) ++ return -EBUSY; ++ ++ switch (bt_cb(skb)->pkt_type) { ++ case HCI_COMMAND_PKT: ++ mtk_hci.hdev->stat.cmd_tx++; ++ break; ++ ++ case HCI_ACLDATA_PKT: ++ mtk_hci.hdev->stat.acl_tx++; ++ break; ++ ++ case HCI_SCODATA_PKT: ++ mtk_hci.hdev->stat.sco_tx++; ++ break; ++ ++ default: ++ return -EILSEQ; ++ } ++ ++ skb_queue_tail(&mtk_hci.txq, skb); ++ schedule_work(&mtk_hci.work); ++ ++ return 0; ++} ++ ++static int ++mtk_bt_hci_flush(struct hci_dev *hdev) ++{ ++ pr_err("%s: todo\n", __func__); ++ ++ return 0; ++} ++ ++static void ++mtk_bt_hci_receive(const PUINT8 data, INT32 size) ++{ ++ int err; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++ hex_dump("<<", data, size); ++#endif ++ ++ err = hci_recv_fragment(mtk_hci.hdev, data[0], (void *)&data[1], size - 1); ++ if (err < 0) ++ pr_err("%s: hci_recv_fragment failed with %d\n", __func__, err); ++ ++ if (mtk_hci.hdev) ++ mtk_hci.hdev->stat.byte_rx += size - 1; ++} ++ ++static void ++mtk_bt_hci_notify(struct hci_dev *hdev, unsigned int evt) ++{ ++ static const char * const notify_str[] = { ++ "null", ++ "HCI_NOTIFY_CONN_ADD", ++ "HCI_NOTIFY_CONN_DEL", ++ "HCI_NOTIFY_VOICE_SETTING" ++ }; ++ ++ if (evt > HCI_NOTIFY_VOICE_SETTING) ++ pr_info("%s event=0x%x\n", __func__, evt); ++ else ++ pr_info("%s event(%d)=%s\n", __func__, evt, notify_str[evt]); ++} ++#endif ++ ++#ifdef MTK_BT_HCI ++ ++int mtk_bt_hci_init(void) ++{ ++ INT32 hci_err = 0; ++ ++ mtk_hci.hdev = hci_alloc_dev(); ++ if (!(mtk_hci.hdev)) { ++ mtk_hci.hdev = NULL; ++ BT_ERR_FUNC("%s hci_alloc_dev failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ mtk_hci.hdev->bus = HCI_SDIO; ++ mtk_hci.hdev->open = mtk_bt_hci_open; ++ mtk_hci.hdev->close = mtk_bt_hci_close; ++ mtk_hci.hdev->send = mtk_bt_hci_send; ++ mtk_hci.hdev->flush = mtk_bt_hci_flush; ++ mtk_hci.hdev->notify = mtk_bt_hci_notify; ++ SET_HCIDEV_DEV(mtk_hci.hdev, stpbt_dev); ++ ++ hci_set_drvdata(mtk_hci.hdev, &mtk_hci); ++ ++ mtk_wcn_stp_register_if_rx(mtk_bt_hci_receive); ++ ++ hci_err = hci_register_dev(mtk_hci.hdev); ++ if (hci_err) { ++ BT_ERR_FUNC("%s hci_register_dev failed with %d\n", __func__, hci_err); ++ hci_free_dev(mtk_hci.hdev); ++ mtk_hci.hdev = NULL; ++ return hci_err; ++ } ++ ++ skb_queue_head_init(&mtk_hci.txq); ++ INIT_WORK(&mtk_hci.work, mtk_bt_hci_work); ++ ++ return 0; ++} ++#endif ++ ++ ++static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, ++ ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz) ++{ ++ /* ++ Handle whole chip reset messages ++ */ ++ ENUM_WMTRSTMSG_TYPE_T rst_msg; ++ ++ if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) { ++ memcpy((PINT8)&rst_msg, (PINT8)buf, sz); ++ BT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src, ++ dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); ++ if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT) ++ && (type == WMTMSG_TYPE_RESET)) { ++ if (rst_msg == WMTRSTMSG_RESET_START) { ++ BT_INFO_FUNC("BT reset start!\n"); ++ rstflag = 1; ++ wake_up_interruptible(&inq); ++ ++ } else if (rst_msg == WMTRSTMSG_RESET_END) { ++ BT_INFO_FUNC("BT reset end!\n"); ++ rstflag = 2; ++ wake_up_interruptible(&inq); ++ } ++ } ++ } else { ++ /* Invalid message format */ ++ BT_WARN_FUNC("Invalid message format!\n"); ++ } ++} ++ ++VOID BT_event_cb(VOID) ++{ ++ BT_DBG_FUNC("BT_event_cb()\n"); ++ ++ flag = 1; ++ ++ /* ++ * Finally, wake up any reader blocked in poll or read ++ */ ++ wake_up_interruptible(&inq); ++ wake_up(&BT_wq); ++} ++ ++unsigned int BT_poll(struct file *filp, poll_table *wait) ++{ ++ UINT32 mask = 0; ++ ++/* down(&wr_mtx); */ ++ /* ++ * The buffer is circular; it is considered full ++ * if "wp" is right behind "rp". "left" is 0 if the ++ * buffer is empty, and it is "1" if it is completely full. ++ */ ++ if (mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX)) { ++ poll_wait(filp, &inq, wait); ++ ++ if (!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) || rstflag) ++ /* BT Rx queue has valid data, or whole chip reset occurs */ ++ mask |= POLLIN | POLLRDNORM; /* Readable */ ++ } else { ++ mask |= POLLIN | POLLRDNORM; /* Readable */ ++ } ++ ++ /* Do we need condition here? */ ++ mask |= POLLOUT | POLLWRNORM; /* Writable */ ++/* up(&wr_mtx); */ ++ return mask; ++} ++ ++ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 retval = 0; ++ INT32 write_size; ++ INT32 written = 0; ++ ++ down(&wr_mtx); ++ ++ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); ++ if (rstflag) { ++ if (rstflag == 1) { /* Reset start */ ++ retval = -88; ++ BT_INFO_FUNC("%s: detect whole chip reset start\n", __func__); ++ } else if (rstflag == 2) { /* Reset end */ ++ retval = -99; ++ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); ++ } ++ goto OUT; ++ } ++ ++ if (count > 0) { ++ if (count < BT_BUFFER_SIZE) { ++ write_size = count; ++ } else { ++ write_size = BT_BUFFER_SIZE; ++ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); ++ } ++ ++ if (copy_from_user(&o_buf[0], &buf[0], write_size)) { ++ retval = -EFAULT; ++ goto OUT; ++ } ++ ++ written = mtk_wcn_stp_send_data(&o_buf[0], write_size, BT_TASK_INDX); ++ if (0 == written) { ++ retval = -ENOSPC; ++ /* No space is available, native program should not call BT_write with no delay */ ++ BT_ERR_FUNC ++ ("Packet length %zd, sent length %d, retval = %d\n", ++ count, written, retval); ++ } else { ++ retval = written; ++ } ++ ++ } else { ++ retval = -EFAULT; ++ BT_ERR_FUNC("Packet length %zd is not allowed, retval = %d\n", count, retval); ++ } ++ ++OUT: ++ up(&wr_mtx); ++ return retval; ++} ++ ++ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ static int chip_reset_count; ++ INT32 retval = 0; ++ ++ down(&rd_mtx); ++ ++ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); ++ if (rstflag) { ++ if (rstflag == 1) { /* Reset start */ ++ retval = -88; ++ if ((chip_reset_count%500) == 0) ++ BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count); ++ chip_reset_count++; ++ } else if (rstflag == 2) { /* Reset end */ ++ retval = -99; ++ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); ++ chip_reset_count = 0; ++ } ++ goto OUT; ++ } ++ ++ if (count > BT_BUFFER_SIZE) { ++ count = BT_BUFFER_SIZE; ++ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); ++ } ++ ++ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); ++ ++ while (retval == 0) { /* Got nothing, wait for STP's signal */ ++ /* ++ * If nonblocking mode, return directly. ++ * O_NONBLOCK is specified during open() ++ */ ++ if (filp->f_flags & O_NONBLOCK) { ++ BT_DBG_FUNC("Non-blocking BT_read\n"); ++ retval = -EAGAIN; ++ goto OUT; ++ } ++ ++ BT_DBG_FUNC("%s: wait_event 1\n", __func__); ++ wait_event(BT_wq, flag != 0); ++ BT_DBG_FUNC("%s: wait_event 2\n", __func__); ++ flag = 0; ++ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); ++ BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval); ++ } ++ ++ /* Got something from STP driver */ ++ if (copy_to_user(buf, i_buf, retval)) { ++ retval = -EFAULT; ++ goto OUT; ++ } ++ ++OUT: ++ up(&rd_mtx); ++ BT_DBG_FUNC("%s: retval = %d\n", __func__, retval); ++ return retval; ++} ++ ++/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ ++long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ INT32 retval = 0; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE; ++ ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; ++ ++ BT_DBG_FUNC("%s: cmd: 0x%x\n", __func__, cmd); ++ ++ switch (cmd) { ++ case COMBO_IOC_BT_HWVER: ++ /* Get combo HW version */ ++ hw_ver_sym = mtk_wcn_wmt_hwver_get(); ++ BT_INFO_FUNC("%s: HW version = %d, sizeof(hw_ver_sym) = %zd\n", ++ __func__, hw_ver_sym, sizeof(hw_ver_sym)); ++ if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) ++ retval = -EFAULT; ++ break; ++ ++ case COMBO_IOCTL_FW_ASSERT: ++ /* Trigger FW assert for debug */ ++ BT_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg); ++ bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg); ++ if (bRet == MTK_WCN_BOOL_TRUE) { ++ BT_INFO_FUNC("Host trigger FW assert succeed\n"); ++ retval = 0; ++ } else { ++ BT_ERR_FUNC("Host trigger FW assert Failed\n"); ++ retval = (-EBUSY); ++ } ++ break; ++ case COMBO_IOCTL_BT_IC_HW_VER: ++ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); ++ break; ++ case COMBO_IOCTL_BT_IC_FW_VER: ++ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); ++ break; ++ default: ++ retval = -EFAULT; ++ BT_ERR_FUNC("Unknown cmd (%d)\n", cmd); ++ break; ++ } ++ ++ return retval; ++} ++ ++long BT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ return BT_unlocked_ioctl(filp, cmd, arg); ++} ++ ++static int BT_open(struct inode *inode, struct file *file) ++{ ++ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); ++ ++ /* Turn on BT */ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) { ++ BT_WARN_FUNC("WMT turn on BT fail!\n"); ++ return -ENODEV; ++ } ++ ++ BT_INFO_FUNC("WMT turn on BT OK!\n"); ++ rstflag = 0; ++ ++ if (mtk_wcn_stp_is_ready()) { ++ ++ mtk_wcn_stp_set_bluez(0); ++ ++ BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n"); ++ BT_INFO_FUNC("STP is ready!\n"); ++ ++ BT_DBG_FUNC("Register BT event callback!\n"); ++ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb); ++ } else { ++ BT_ERR_FUNC("STP is not ready\n"); ++ mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); ++ return -ENODEV; ++ } ++ ++ BT_DBG_FUNC("Register BT reset callback!\n"); ++ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb); ++ ++ /* init_MUTEX(&wr_mtx); */ ++ sema_init(&wr_mtx, 1); ++ /* init_MUTEX(&rd_mtx); */ ++ sema_init(&rd_mtx, 1); ++ BT_INFO_FUNC("%s: finish\n", __func__); ++ ++ return 0; ++} ++ ++static int BT_close(struct inode *inode, struct file *file) ++{ ++ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); ++ rstflag = 0; ++ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT); ++ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); ++ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) { ++ BT_ERR_FUNC("WMT turn off BT fail!\n"); ++ return -EIO; /* Mostly, native program will not check this return value. */ ++ } ++ ++ BT_INFO_FUNC("WMT turn off BT OK!\n"); ++ ++ return 0; ++} ++ ++const struct file_operations BT_fops = { ++ .open = BT_open, ++ .release = BT_close, ++ .read = BT_read, ++ .write = BT_write, ++ /* .ioctl = BT_ioctl, */ ++ .unlocked_ioctl = BT_unlocked_ioctl, ++ .compat_ioctl = BT_compat_ioctl, ++ .poll = BT_poll ++}; ++ ++ ++ ++static int BT_init(void) ++{ ++ dev_t dev = MKDEV(BT_major, 0); ++ INT32 alloc_ret = 0; ++ INT32 cdev_err = 0; ++ ++ /* Static allocate char device */ ++ alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME); ++ if (alloc_ret) { ++ BT_ERR_FUNC("%s: Failed to register char device\n", __func__); ++ return alloc_ret; ++ } ++ ++ cdev_init(&BT_cdev, &BT_fops); ++ BT_cdev.owner = THIS_MODULE; ++ ++ cdev_err = cdev_add(&BT_cdev, dev, BT_devs); ++ if (cdev_err) ++ goto error; ++ ++#if WMT_CREATE_NODE_DYNAMIC ++ stpbt_class = class_create(THIS_MODULE, "stpbt"); ++ if (IS_ERR(stpbt_class)) ++ goto error; ++ stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt"); ++ if (IS_ERR(stpbt_dev)) ++ goto error; ++#endif ++ ++ BT_INFO_FUNC("%s driver(major %d) installed\n", BT_DRIVER_NAME, BT_major); ++ ++ /* Init wait queue */ ++ init_waitqueue_head(&(inq)); ++ ++#ifdef MTK_BT_HCI ++ mtk_bt_hci_init(); ++#endif ++ ++ return 0; ++ ++error: ++#if WMT_CREATE_NODE_DYNAMIC ++ if (!IS_ERR(stpbt_dev)) ++ device_destroy(stpbt_class, dev); ++ if (!IS_ERR(stpbt_class)) { ++ class_destroy(stpbt_class); ++ stpbt_class = NULL; ++ } ++#endif ++ if (cdev_err == 0) ++ cdev_del(&BT_cdev); ++ ++ if (alloc_ret == 0) ++ unregister_chrdev_region(dev, BT_devs); ++ ++ return -1; ++} ++ ++static void BT_exit(void) ++{ ++ dev_t dev = MKDEV(BT_major, 0); ++ ++#if WMT_CREATE_NODE_DYNAMIC ++ if (stpbt_dev) { ++ device_destroy(stpbt_class, dev); ++ stpbt_dev = NULL; ++ } ++ if (stpbt_class) { ++ class_destroy(stpbt_class); ++ stpbt_class = NULL; ++ } ++#endif ++ ++ cdev_del(&BT_cdev); ++ unregister_chrdev_region(dev, BT_devs); ++ ++ BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME); ++} ++ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++ ++int mtk_wcn_stpbt_drv_init(void) ++{ ++ return BT_init(); ++} ++EXPORT_SYMBOL(mtk_wcn_stpbt_drv_init); ++ ++void mtk_wcn_stpbt_drv_exit(void) ++{ ++ return BT_exit(); ++} ++EXPORT_SYMBOL(mtk_wcn_stpbt_drv_exit); ++ ++#else ++ ++module_init(BT_init); ++module_exit(BT_exit); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +new file mode 100644 +index 000000000000..c43bec5f7452 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +@@ -0,0 +1,668 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "wmt_exp.h" ++#include "stp_exp.h" ++ ++MODULE_LICENSE("Dual BSD/GPL"); ++ ++#define WIFI_DRIVER_NAME "mtk_wmt_WIFI_chrdev" ++#define WIFI_DEV_MAJOR 155 ++ ++#define PFX "[MTK-WIFI] " ++#define WIFI_LOG_DBG 3 ++#define WIFI_LOG_INFO 2 ++#define WIFI_LOG_WARN 1 ++#define WIFI_LOG_ERR 0 ++ ++UINT32 gDbgLevel = WIFI_LOG_DBG; ++ ++#define WIFI_DBG_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_INFO_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_INFO) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_WARN_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_WARN) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_ERR_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_ERR) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_TRC_FUNC(f)\ ++ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "<%s> <%d>\n", __func__, __LINE__); } while (0) ++ ++#define VERSION "1.0" ++ ++#define WLAN_IFACE_NAME "wlan0" ++#if CFG_TC1_FEATURE ++#define LEGACY_IFACE_NAME "legacy0" ++#endif ++ ++enum { ++ WLAN_MODE_HALT, ++ WLAN_MODE_AP, ++ WLAN_MODE_STA_P2P, ++ WLAN_MODE_MAX ++}; ++static INT32 wlan_mode = WLAN_MODE_HALT; ++static INT32 powered; ++static INT8 *ifname = WLAN_IFACE_NAME; ++#if CFG_TC1_FEATURE ++volatile INT32 wlan_if_changed = 0; ++EXPORT_SYMBOL(wlan_if_changed); ++#endif ++ ++typedef enum _ENUM_RESET_STATUS_T { ++ RESET_FAIL, ++ RESET_SUCCESS ++} ENUM_RESET_STATUS_T; ++ ++/* ++ * enable = 1, mode = 0 => init P2P network ++ * enable = 1, mode = 1 => init Soft AP network ++ * enable = 0 => uninit P2P/AP network ++ */ ++typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { ++ UINT32 u4Enable; ++ UINT32 u4Mode; ++} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; ++typedef INT32(*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); ++ ++static set_p2p_mode pf_set_p2p_mode; ++VOID register_set_p2p_mode_handler(set_p2p_mode handler) ++{ ++ WIFI_INFO_FUNC("(pid %d) register set p2p mode handler %p\n", current->pid, handler); ++ pf_set_p2p_mode = handler; ++} ++EXPORT_SYMBOL(register_set_p2p_mode_handler); ++ ++/* For dynamical debug level setting */ ++/* copy of debug.h in wlan driver */ ++#define DBG_CLASS_ERROR BIT(0) ++#define DBG_CLASS_WARN BIT(1) ++#define DBG_CLASS_STATE BIT(2) ++#define DBG_CLASS_EVENT BIT(3) ++#define DBG_CLASS_TRACE BIT(4) ++#define DBG_CLASS_INFO BIT(5) ++#define DBG_CLASS_LOUD BIT(6) ++#define DBG_CLASS_TEMP BIT(7) ++#define DBG_CLASS_MASK BITS(0, 7) ++ ++typedef enum _ENUM_DBG_MODULE_T { ++ DBG_INIT_IDX = 0, /* For driver initial */ ++ DBG_HAL_IDX, /* For HAL(HW) Layer */ ++ DBG_INTR_IDX, /* For Interrupt */ ++ DBG_REQ_IDX, ++ DBG_TX_IDX, ++ DBG_RX_IDX, ++ DBG_RFTEST_IDX, /* For RF test mode */ ++ DBG_EMU_IDX, /* Developer specific */ ++ ++ DBG_SW1_IDX, /* Developer specific */ ++ DBG_SW2_IDX, /* Developer specific */ ++ DBG_SW3_IDX, /* Developer specific */ ++ DBG_SW4_IDX, /* Developer specific */ ++ ++ DBG_HEM_IDX, /* HEM */ ++ DBG_AIS_IDX, /* AIS */ ++ DBG_RLM_IDX, /* RLM */ ++ DBG_MEM_IDX, /* RLM */ ++ DBG_CNM_IDX, /* CNM */ ++ DBG_RSN_IDX, /* RSN */ ++ DBG_BSS_IDX, /* BSS */ ++ DBG_SCN_IDX, /* SCN */ ++ DBG_SAA_IDX, /* SAA */ ++ DBG_AAA_IDX, /* AAA */ ++ DBG_P2P_IDX, /* P2P */ ++ DBG_QM_IDX, /* QUE_MGT */ ++ DBG_SEC_IDX, /* SEC */ ++ DBG_BOW_IDX, /* BOW */ ++ DBG_WAPI_IDX, /* WAPI */ ++ DBG_ROAMING_IDX, /* ROAMING */ ++ ++ DBG_MODULE_NUM /* Notice the XLOG check */ ++} ENUM_DBG_MODULE_T; ++/* end */ ++typedef VOID(*set_dbg_level) (UINT8 modules[DBG_MODULE_NUM]); ++ ++UINT8 wlan_dbg_level[DBG_MODULE_NUM]; ++static set_dbg_level pf_set_dbg_level; ++VOID register_set_dbg_level_handler(set_dbg_level handler) ++{ ++ pf_set_dbg_level = handler; ++} ++EXPORT_SYMBOL(register_set_dbg_level_handler); ++ ++static INT32 WIFI_devs = 1; ++static INT32 WIFI_major = WIFI_DEV_MAJOR; ++module_param(WIFI_major, uint, 0); ++static struct cdev WIFI_cdev; ++volatile INT32 retflag = 0; ++static struct semaphore wr_mtx; ++ ++#define WMT_CHECK_DO_CHIP_RESET() \ ++do { \ ++ if (g_IsNeedDoChipReset) { \ ++ g_IsNeedDoChipReset = 0; \ ++ WIFI_ERR_FUNC("Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ ++ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); \ ++ } \ ++} while (0) ++ ++/******************************************************************* ++ * WHOLE CHIP RESET PROCEDURE: ++ * ++ * WMTRSTMSG_RESET_START callback ++ * -> wlanRemove ++ * -> WMTRSTMSG_RESET_END callback ++ * ++ ******************************************************************* ++*/ ++/*-----------------------------------------------------------------*/ ++/* ++ * Receiving RESET_START message ++ */ ++/*-----------------------------------------------------------------*/ ++INT32 wifi_reset_start(VOID) ++{ ++ struct net_device *netdev = NULL; ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ ++ down(&wr_mtx); ++ ++ if (powered == 1) { ++ netdev = dev_get_by_name(&init_net, ifname); ++ if (netdev == NULL) { ++ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); ++ } else { ++ p2pmode.u4Enable = 0; ++ p2pmode.u4Mode = 0; ++ ++ if (pf_set_p2p_mode) { ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) ++ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); ++ else ++ WIFI_INFO_FUNC("Turn off p2p/ap mode"); ++ } ++ dev_put(netdev); ++ netdev = NULL; ++ } ++ } else { ++ /* WIFI is off before whole chip reset, do nothing */ ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(wifi_reset_start); ++ ++/*-----------------------------------------------------------------*/ ++/* ++ * Receiving RESET_END/RESET_END_FAIL message ++ */ ++/*-----------------------------------------------------------------*/ ++INT32 wifi_reset_end(ENUM_RESET_STATUS_T status) ++{ ++ struct net_device *netdev = NULL; ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ INT32 wait_cnt = 0; ++ INT32 ret = -1; ++ ++ if (status == RESET_FAIL) { ++ /* whole chip reset fail, donot recover WIFI */ ++ ret = 0; ++ up(&wr_mtx); ++ } else if (status == RESET_SUCCESS) { ++ WIFI_WARN_FUNC("WIFI state recovering...\n"); ++ ++ if (powered == 1) { ++ /* WIFI is on before whole chip reset, reopen it now */ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); ++ goto done; ++ } else { ++ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); ++ } ++ ++ if (pf_set_p2p_mode == NULL) { ++ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); ++ goto done; ++ } ++ ++ netdev = dev_get_by_name(&init_net, ifname); ++ while (netdev == NULL && wait_cnt < 10) { ++ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); ++ msleep(300); ++ wait_cnt++; ++ netdev = dev_get_by_name(&init_net, ifname); ++ } ++ if (wait_cnt >= 10) { ++ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); ++ goto done; ++ } ++ ++ if (wlan_mode == WLAN_MODE_STA_P2P) { ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 0; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P); ++ ret = 0; ++ } ++ } else if (wlan_mode == WLAN_MODE_AP) { ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 1; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP); ++ ret = 0; ++ } ++ } ++done: ++ if (netdev != NULL) ++ dev_put(netdev); ++ } else { ++ /* WIFI is off before whole chip reset, do nothing */ ++ ret = 0; ++ } ++ up(&wr_mtx); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(wifi_reset_end); ++ ++static int WIFI_open(struct inode *inode, struct file *file) ++{ ++ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); ++ ++ return 0; ++} ++ ++static int WIFI_close(struct inode *inode, struct file *file) ++{ ++ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); ++ retflag = 0; ++ ++ return 0; ++} ++ ++ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 retval = -EIO; ++ INT8 local[12] = { 0 }; ++ struct net_device *netdev = NULL; ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ INT32 wait_cnt = 0; ++ ++ down(&wr_mtx); ++ if (count <= 0) { ++ WIFI_ERR_FUNC("WIFI_write invalid param\n"); ++ goto done; ++ } ++ ++ if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { ++ local[11] = 0; ++ WIFI_INFO_FUNC("WIFI_write %s\n", local); ++ ++ if (local[0] == '0') { ++ if (powered == 0) { ++ WIFI_INFO_FUNC("WIFI is already power off!\n"); ++ retval = count; ++ wlan_mode = WLAN_MODE_HALT; ++ goto done; ++ } ++ ++ netdev = dev_get_by_name(&init_net, ifname); ++ if (netdev == NULL) { ++ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); ++ } else { ++ p2pmode.u4Enable = 0; ++ p2pmode.u4Mode = 0; ++ ++ if (pf_set_p2p_mode) { ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); ++ } else { ++ WIFI_INFO_FUNC("Turn off p2p/ap mode"); ++ wlan_mode = WLAN_MODE_HALT; ++ } ++ } ++ dev_put(netdev); ++ netdev = NULL; ++ } ++ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); ++ WMT_CHECK_DO_CHIP_RESET(); ++ } else { ++ WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); ++ powered = 0; ++ retval = count; ++ wlan_mode = WLAN_MODE_HALT; ++#if CFG_TC1_FEATURE ++ ifname = WLAN_IFACE_NAME; ++ wlan_if_changed = 0; ++#endif ++ } ++ } else if (local[0] == '1') { ++ if (powered == 1) { ++ WIFI_INFO_FUNC("WIFI is already power on!\n"); ++ retval = count; ++ goto done; ++ } ++ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); ++ WMT_CHECK_DO_CHIP_RESET(); ++ } else { ++ powered = 1; ++ retval = count; ++ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); ++ wlan_mode = WLAN_MODE_HALT; ++ } ++ } else if (local[0] == 'D') { ++ INT32 k = 0; ++ /* ++ * 0: no debug ++ * 1: common debug output ++ * 2: more detials ++ * 3: verbose ++ */ ++ switch (local[1]) { ++ case '0': ++ for (k = 0; k < DBG_MODULE_NUM; k++) ++ wlan_dbg_level[k] = 0; ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ case '1': ++ for (k = 0; k < DBG_MODULE_NUM; k++) { ++ wlan_dbg_level[k] = DBG_CLASS_ERROR | ++ DBG_CLASS_WARN | ++ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; ++ } ++ wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); ++ wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); ++ wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); ++ wlan_dbg_level[DBG_INTR_IDX] = 0; ++ wlan_dbg_level[DBG_MEM_IDX] = 0; ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ case '2': ++ for (k = 0; k < DBG_MODULE_NUM; k++) { ++ wlan_dbg_level[k] = DBG_CLASS_ERROR | ++ DBG_CLASS_WARN | ++ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; ++ } ++ wlan_dbg_level[DBG_INTR_IDX] = 0; ++ wlan_dbg_level[DBG_MEM_IDX] = 0; ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ case '3': ++ for (k = 0; k < DBG_MODULE_NUM; k++) { ++ wlan_dbg_level[k] = DBG_CLASS_ERROR | ++ DBG_CLASS_WARN | ++ DBG_CLASS_STATE | ++ DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD; ++ } ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ default: ++ break; ++ } ++ } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { ++ if (powered == 0) { ++ /* If WIFI is off, turn on WIFI first */ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); ++ WMT_CHECK_DO_CHIP_RESET(); ++ goto done; ++ } else { ++ powered = 1; ++ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); ++ wlan_mode = WLAN_MODE_HALT; ++ } ++ } ++ ++ if (pf_set_p2p_mode == NULL) { ++ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); ++ goto done; ++ } ++ ++ netdev = dev_get_by_name(&init_net, ifname); ++ while (netdev == NULL && wait_cnt < 10) { ++ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); ++ msleep(300); ++ wait_cnt++; ++ netdev = dev_get_by_name(&init_net, ifname); ++ } ++ if (wait_cnt >= 10) { ++ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); ++ goto done; ++ } ++ ++ if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) || ++ (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))) { ++ WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode); ++ retval = count; ++ goto done; ++ } ++ ++ if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || ++ (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) { ++ p2pmode.u4Enable = 0; ++ p2pmode.u4Mode = 0; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); ++ goto done; ++ } ++ } ++ ++ if (local[0] == 'S' || local[0] == 'P') { ++#if CFG_TC1_FEATURE ++ /* Restore NIC name to wlan0 */ ++ rtnl_lock(); ++ if (strcmp(ifname, WLAN_IFACE_NAME) != 0) { ++ if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0) { ++ WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME); ++ rtnl_unlock(); ++ goto done; ++ } else { ++ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, ++ WLAN_IFACE_NAME); ++ ifname = WLAN_IFACE_NAME; ++ wlan_if_changed = 0; ++ } ++ } ++ rtnl_unlock(); ++#endif ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 0; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); ++ wlan_mode = WLAN_MODE_STA_P2P; ++ retval = count; ++ } ++ } else if (local[0] == 'A') { ++#if CFG_TC1_FEATURE ++ /* Change NIC name to legacy0, since wlan0 is used for AP */ ++ rtnl_lock(); ++ if (strcmp(ifname, LEGACY_IFACE_NAME) != 0) { ++ if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0) { ++ WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME); ++ rtnl_unlock(); ++ goto done; ++ } else { ++ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, ++ LEGACY_IFACE_NAME); ++ ifname = LEGACY_IFACE_NAME; ++ wlan_if_changed = 1; ++ } ++ } ++ rtnl_unlock(); ++#endif ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 1; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); ++ wlan_mode = WLAN_MODE_AP; ++ retval = count; ++ } ++ } ++ dev_put(netdev); ++ netdev = NULL; ++ } ++ } ++done: ++ if (netdev != NULL) ++ dev_put(netdev); ++ ++ up(&wr_mtx); ++ return retval; ++} ++ ++const struct file_operations WIFI_fops = { ++ .open = WIFI_open, ++ .release = WIFI_close, ++ .write = WIFI_write, ++}; ++ ++#if WMT_CREATE_NODE_DYNAMIC ++struct class *wmtwifi_class = NULL; ++#endif ++ ++static int WIFI_init(void) ++{ ++ dev_t dev = MKDEV(WIFI_major, 0); ++ INT32 alloc_ret = 0; ++ INT32 cdev_err = 0; ++#if WMT_CREATE_NODE_DYNAMIC ++ struct device *wmtwifi_dev = NULL; ++#endif ++ ++ /* static allocate chrdev */ ++ alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME); ++ if (alloc_ret) { ++ WIFI_ERR_FUNC("Fail to register chrdev\n"); ++ return alloc_ret; ++ } ++ ++ cdev_init(&WIFI_cdev, &WIFI_fops); ++ WIFI_cdev.owner = THIS_MODULE; ++ ++ cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs); ++ if (cdev_err) ++ goto error; ++ ++#if WMT_CREATE_NODE_DYNAMIC /* mknod replace */ ++ wmtwifi_class = class_create(THIS_MODULE, "wmtWifi"); ++ if (IS_ERR(wmtwifi_class)) ++ goto error; ++ wmtwifi_dev = device_create(wmtwifi_class, NULL, dev, NULL, "wmtWifi"); ++ if (wmtwifi_dev == NULL) ++ goto error; ++ if (IS_ERR(wmtwifi_dev)) ++ goto error; ++#endif ++ ++ sema_init(&wr_mtx, 1); ++ ++ WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major); ++ retflag = 0; ++ wlan_mode = WLAN_MODE_HALT; ++ pf_set_p2p_mode = NULL; ++ ++ return 0; ++ ++error: ++#if WMT_CREATE_NODE_DYNAMIC ++ if (!IS_ERR(wmtwifi_dev)) ++ device_destroy(wmtwifi_class, dev); ++ if (!IS_ERR(wmtwifi_class)) { ++ class_destroy(wmtwifi_class); ++ wmtwifi_class = NULL; ++ } ++#endif ++ ++ if (cdev_err == 0) ++ cdev_del(&WIFI_cdev); ++ ++ if (alloc_ret == 0) ++ unregister_chrdev_region(dev, WIFI_devs); ++ ++ return -1; ++} ++ ++static void WIFI_exit(void) ++{ ++ dev_t dev = MKDEV(WIFI_major, 0); ++ ++ retflag = 0; ++ ++#if WMT_CREATE_NODE_DYNAMIC ++ device_destroy(wmtwifi_class, dev); ++ class_destroy(wmtwifi_class); ++ wmtwifi_class = NULL; ++#endif ++ ++ cdev_del(&WIFI_cdev); ++ unregister_chrdev_region(dev, WIFI_devs); ++ ++ WIFI_INFO_FUNC("%s driver removed.\n", WIFI_DRIVER_NAME); ++} ++ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++ ++INT32 mtk_wcn_wmt_wifi_init(VOID) ++{ ++ return WIFI_init(); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wifi_init); ++ ++VOID mtk_wcn_wmt_wifi_exit(VOID) ++{ ++ return WIFI_exit(); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wifi_exit); ++ ++#else ++ ++module_init(WIFI_init); ++module_exit(WIFI_exit); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c +new file mode 100644 +index 000000000000..641e516f603d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c +@@ -0,0 +1,307 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include "osal_typedef.h" ++#include "wmt_idc.h" ++#include "wmt_lib.h" ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ ++MTK_WCN_WMT_IDC_INFO gWmtIdcInfo; ++ ++INT32 wmt_idc_init(VOID) ++{ ++ INT32 iRet; ++ ++ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); ++ gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT; ++ gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1; ++ gWmtIdcInfo.iit.sap_id = 0; ++ gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing; ++ ++ iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops); ++ if (iRet) { ++ WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet); ++ return -1; ++ } ++ /* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */ ++ return 0; ++ ++} ++ ++INT32 wmt_idc_deinit(VOID) ++{ ++ INT32 iRet; ++ ++ iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id); ++ if (iRet) ++ WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet); ++ ++ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); ++ ++ return 0; ++} ++ ++INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm) ++{ ++ MTK_WCN_BOOL bRet; ++ ++ if (NULL == ilm) { ++ WMT_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ if (mtk_wcn_stp_is_ready()) { ++ bRet = wmt_lib_handle_idc_msg(ilm); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_ERR_FUNC("wmt handing idc msg fail\n"); ++ return -2; ++ } ++ } else { ++ WMT_INFO_FUNC("Received LTE msg,but STP is not ready,drop it!\n"); ++ } ++ return 0; ++} ++ ++VOID wmt_idc_dump_debug_msg(UINT8 *str, UINT8 *p_buf, UINT32 buf_len) ++{ ++ UINT32 idx = 0; ++ ++ WMT_DBG_FUNC("%s:, length:%d\n", str, buf_len); ++ ++ WMT_DBG_FUNC("ASCII output:\n"); ++ ++ for (idx = 0; idx < buf_len;) { ++ WMT_DBG_FUNC("%c", p_buf[idx]); ++ idx++; ++ if (0 == idx % 16) ++ WMT_DBG_FUNC("\n"); ++ } ++ ++ WMT_DBG_FUNC("HEX output:\n"); ++ ++ for (idx = 0; idx < buf_len;) { ++ WMT_DBG_FUNC("%02x ", p_buf[idx]); ++ idx++; ++ if (0 == idx % 16) ++ WMT_DBG_FUNC("\n"); ++ } ++} ++ ++INT32 wmt_idc_msg_to_lte_handing(VOID) ++{ ++ UINT32 readlen = 0; ++ local_para_struct *p_lps = NULL; ++ UINT8 *p_data = NULL; ++ UINT8 opcode = 0; ++ UINT16 msg_len = 0; ++ UINT32 handle_len = 0; ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; ++#endif ++ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); ++ if (readlen == 0) { ++ osal_sleep_ms(5); ++ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); ++ } ++ ++ if (readlen > 0) { ++ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); ++ wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen); ++ p_data = &gWmtIdcInfo.buffer[0]; ++ ++ while (handle_len < readlen) { ++ p_data += 2; /*omit direction & opcode 2 bytes */ ++ osal_memcpy(&msg_len, p_data, 2); ++ msg_len -= 1; /*flag byte */ ++ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); ++ ++ p_data += 2; /*length: 2 bytes */ ++ ++ /*how to handle flag(msg type) need to Scott comment */ ++ /************************************************/ ++ ++ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) ++ /*do not need transfer to LTE */ ++ { ++ p_data += 1; /*flag : 1 byte */ ++ /*need to handle these debug message */ ++ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); ++ } else ++ /*need to transfer to LTE */ ++ { ++ p_lps = ++ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + ++ osal_sizeof(UINT8) * msg_len); ++ if (NULL == p_lps) { ++ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); ++ return -1; ++ } ++ ++ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); ++ ++ opcode = *p_data; ++ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); ++ ++ p_data += 1; /*flag : 1 byte */ ++ osal_memcpy(p_lps->data, p_data, msg_len); ++ ++ gWmtIdcInfo.iit.local_para_ptr = p_lps; ++ ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ switch (opcode) { ++ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_UART_PIN_SEL: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND; ++ break; ++ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ ++ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ ++ /* break; */ ++ default: ++ unknown_msgid = MTK_WCN_BOOL_TRUE; ++ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); ++ break; ++ } ++ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { ++ /*handling flag value in wmt cmd */ ++ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); ++ } ++#else ++ if (opcode >= LTE_MSG_ID_OFFSET) { ++ gWmtIdcInfo.iit.msg_id = opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1; ++ /*handling flag value in wmt cmd */ ++ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); ++ WMT_DBG_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, gWmtIdcInfo.iit.msg_id); ++ } else { ++ WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", opcode); ++ } ++#endif ++ osal_free(p_lps); ++ } ++ ++ p_data += msg_len; /*point to next package header */ ++ ++ handle_len += (msg_len + 5); ++ } ++ ++ } else { ++ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); ++ } ++ ++ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); ++ ++ return 0; ++} ++ ++UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len) ++{ ++ UINT32 readlen = len; ++ local_para_struct *p_lps = NULL; ++ UINT8 *p_data = NULL; ++ UINT8 opcode = 0; ++ UINT16 msg_len = 0; ++ UINT32 handle_len = 0; ++ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; ++ ++ osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len); ++ ++ if (readlen > 0) { ++ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); ++ p_data = &gWmtIdcInfo.buffer[0]; ++ ++ while (handle_len < readlen) { ++ p_data += 2; /*omit direction & opcode 2 bytes */ ++ osal_memcpy(&msg_len, p_data, 2); ++ msg_len -= 1; /*flag byte */ ++ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); ++ ++ p_data += 2; /*length: 2 bytes */ ++ ++ /*how to handle flag(msg type) need to Scott comment */ ++ /************************************************/ ++ ++ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) ++ /*do not need transfer to LTE */ ++ { ++ p_data += 1; /*flag : 1 byte */ ++ /*need to handle these debug message */ ++ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); ++ } else ++ /*need to transfer to LTE */ ++ { ++ p_lps = ++ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + ++ osal_sizeof(UINT8) * msg_len); ++ if (NULL == p_lps) { ++ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); ++ return -1; ++ } ++ ++ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); ++ ++ opcode = *p_data; ++ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); ++ ++ p_data += 1; /*flag : 1 byte */ ++ osal_memcpy(p_lps->data, p_data, msg_len); ++ ++ gWmtIdcInfo.iit.local_para_ptr = p_lps; ++ ++ switch (opcode) { ++ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; ++ break; ++ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ ++ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ ++ /* break; */ ++ default: ++ unknown_msgid = MTK_WCN_BOOL_TRUE; ++ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); ++ break; ++ } ++ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { ++ /*handling flag value in wmt cmd */ ++ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); ++ } ++ osal_free(p_lps); ++ } ++ ++ p_data += msg_len; /*point to next package header */ ++ ++ handle_len += (msg_len + 5); ++ } ++ ++ } else { ++ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); ++ } ++ ++ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); ++ ++ return handle_len; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile +new file mode 100644 +index 000000000000..c201e8291b8e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile +@@ -0,0 +1,25 @@ ++# WMT HAL driver for MT7623 ++ ++ccflags-y += \ ++ -I$(src)/include \ ++ -I$(src)/../linux/include \ ++ -I$(src)/../include \ ++ -I$(src)/../../common_detect ++ ++ ifeq ($(CONFIG_MTK_CLKMGR),y) ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach ++ endif ++ #ifeq ($(CONFIG_MTK_EMI_MPU),y) ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach ++ #endif ++ ++subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) ++ subdir-ccflags-y += -DWMT_IDC_SUPPORT=1 ++else ++ subdir-ccflags-y += -DWMT_IDC_SUPPORT=0 ++endif ++ ++obj-y += mtk_wcn_consys_hw.o ++obj-y += wmt_plat_alps.o +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h +new file mode 100644 +index 000000000000..94d6af9d0b3e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h +@@ -0,0 +1,287 @@ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _MTK_WCN_CONSYS_HW_H_ ++#define _MTK_WCN_CONSYS_HW_H_ ++ ++#include ++/*#include */ ++#include "wmt_plat.h" ++ ++/*device tree mode*/ ++#ifdef CONFIG_OF ++/* #if 1 */ ++#include ++#include ++#include ++#include ++#endif ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CONSYS_BT_WIFI_SHARE_V33 0 ++#define CONSYS_PMIC_CTRL_ENABLE 1 ++#define CONSYS_PMIC_CTRL_UPMU 1 ++#define CONSYS_EMI_MPU_SETTING 0 ++#define CONSYS_AHB_CLK_MAGEMENT 1 ++#define CONSYS_USE_PLATFORM_WRITE 1 ++#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 ++#define CONSYS_CLOCK_BUF_CTRL 0 ++#if defined(CONFIG_MTK_LEGACY) ++#define CONFIG_MTK_PMIC_LEGACY 0 ++#endif ++#define CONFIG_RESET_CONTROL 1 ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/*tag start:new platform need to make sure these define */ ++#define PLATFORM_SOC_CHIP 0x7623 ++/*tag end*/ ++ ++#ifdef CONFIG_OF ++ ++struct CONSYS_BASE_ADDRESS { ++ SIZE_T mcu_base; ++ SIZE_T ap_rgu_base; ++ SIZE_T topckgen_base; ++ SIZE_T spm_base; ++}; ++ ++/*TOPCKGEN_BASE*/ ++#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 ++#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 ++#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 ++#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000800 ++#define CONSYS_EMI_MAPPING_OFFSET 0x00000310 ++/*AP_RGU_BASE*/ ++#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 ++/*SPM_BASE*/ ++#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 ++#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000280 ++#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000060c ++#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000610 ++/*CONN_MCU_CONFIG_BASE*/ ++#define CONSYS_CHIP_ID_OFFSET 0x00000008 ++#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 ++#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 ++#define CONSYS_CPUPCR_OFFSET 0x00000160 ++/*AXI bus*/ ++ ++#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x1220 ++#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x0228 ++#endif ++ ++#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile UINT32*)(REG)) |= ((UINT32)(BITVAL))) ++#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile UINT32*)(REG)) &= ~((UINT32)(BITVAL))) ++#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\ ++ UINT32 val = (*(volatile UINT32*)(REG)); \ ++ val &= ~((UINT32)(BITVAL)); \ ++ val |= ((UINT32)(KEY)); \ ++ (*(volatile UINT32*)(REG)) = val;\ ++} ++#define CONSYS_REG_READ(addr) (*((volatile UINT32*)(addr))) ++#if CONSYS_USE_PLATFORM_WRITE ++#define CONSYS_REG_WRITE(addr, data) mt_reg_sync_writel(data, addr) ++#else ++#define CONSYS_REG_WRITE(addr, data) (*((volatile UINT32*)(addr)) = (UINT32)(data)) ++#endif ++ ++/*tag start: connsys register base address (hard code, no use) */ ++#define AP_RGU_BASE 0xF0007000 ++#define TOPCKGEN_BASE 0xF0000000 ++#define SPM_BASE 0xF0006000 ++#define CONN_MCU_CONFIG_BASE 0xF8070000 ++/*GIC Interrupt ID*/ ++#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 237 ++/*tag end*/ ++ ++/*connsys register offset define(hard code mode)*/ ++#if 1 ++ /*top clock gating control register */ ++#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) ++#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) ++#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) ++ ++ /*SPM clock gating control register */ ++#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) ++#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) ++#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) ++#endif ++ ++#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) ++#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x00000280) ++#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x0000060c) ++#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000610) ++ ++#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) ++#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) ++#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) ++#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) ++#define CONSYS_AFE_REG (CONN_TOP_CR_BASE + 0x00002000) ++#define CONSYS_AFE_REG_DIG_RCK_01 (CONSYS_AFE_REG + 0x00000010) ++#define CONSYS_AFE_REG_WBG_PLL_02 (CONSYS_AFE_REG + 0x00000028) ++#define CONSYS_AFE_REG_WBG_WB_TX_01 (CONSYS_AFE_REG + 0x0000003c) ++#define CONSYS_AFE_REG_DIG_RCK_01_VALUE (0x174b0160) ++#define CONSYS_AFE_REG_WBG_PLL_02_VALUE (0x844083fe) ++#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x7fc39a20) ++ ++#define CONSYS_TOPAXI_PROT_EN (TOPCKGEN_BASE + 0x0220) ++#define CONSYS_TOPAXI_PROT_STA1 (TOPCKGEN_BASE + 0x0228) ++#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14) | (0x1<<15)) /* bit 13, 14, 15 */ ++/*CONSYS_CPU_SW_RST_REG*/ ++#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) ++#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) ++ ++/*CONSYS_TOP1_PWR_CTRL_REG*/ ++#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) ++#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) ++#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) ++#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) ++#define CONSYS_CLK_CTRL_BIT (0x1 << 4) ++#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) ++ ++/*CONSYS_PWR_CONN_ACK_REG*/ ++#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) ++ ++/*CONSYS_PWR_CONN_ACK_S_REG*/ ++#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) ++ ++/*CONSYS_WD_SYS_RST_REG*/ ++#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) ++#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) ++ ++/*CONSYS_MCU_CFG_ACR_REG*/ ++#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) ++ ++/* EMI part mapping & ctrl*/ ++#define KBYTE (1024*sizeof(char)) ++#define CONSYS_EMI_AP_PHY_OFFSET (0x80000) ++#define CONSYS_EMI_AP_PHY_BASE (0x80080000) ++#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) ++#define CONSYS_EMI_MEM_SIZE (343*KBYTE) /*coredump space , 343K is enough */ ++#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) ++#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) ++#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) ++ ++/*cpupcr*/ ++#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) ++/*emi mapping*/ ++#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + 0x1310) ++ ++/*control app2cnn_osc_en*/ ++#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) ++#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 16) ++#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 17) ++ ++/*paged dump address start*/ ++#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) ++#define CONSYS_PAGED_DUMP_SIZE (32*KBYTE) ++ ++/*full dump address start*/ ++#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) ++#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) ++#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) ++#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) ++#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) ++#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) ++ ++/*force fw assert pattern*/ ++#define EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1 (0x19b30bb1) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_EMI_CTRL_STATE_OFFSET_ { ++ EXP_APMEM_CTRL_STATE = 0x0, ++ EXP_APMEM_CTRL_HOST_SYNC_STATE = 0x4, ++ EXP_APMEM_CTRL_HOST_SYNC_NUM = 0x8, ++ EXP_APMEM_CTRL_CHIP_SYNC_STATE = 0xc, ++ EXP_APMEM_CTRL_CHIP_SYNC_NUM = 0x10, ++ EXP_APMEM_CTRL_CHIP_SYNC_ADDR = 0x14, ++ EXP_APMEM_CTRL_CHIP_SYNC_LEN = 0x18, ++ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START = 0x1c, ++ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN = 0x20, ++ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX = 0x24, ++ EXP_APMEM_CTRL_CHIP_INT_STATUS = 0x28, ++ EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END = 0x2c, ++ EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 = 0x30, ++ EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP = 0x48, ++ EXP_APMEM_CTRL_MAX ++} ENUM_EMI_CTRL_STATE_OFFSET, *P_ENUM_EMI_CTRL_STATE_OFFSET; ++ ++#if CONSYS_BT_WIFI_SHARE_V33 ++typedef struct _BT_WIFI_V33_STATUS_ { ++ UINT32 counter; ++ UINT32 flags; ++ spinlock_t lock; ++} BT_WIFI_V33_STATUS; ++ ++#endif ++ ++typedef enum _CONSYS_GPS_CO_CLOCK_TYPE_ { ++ GPS_TCXO_TYPE = 0, ++ GPS_CO_TSX_TYPE = 1, ++ GPS_CO_DCXO_TYPE = 2, ++ GPS_CO_VCTCXO_TYPE = 3, ++ GPS_CO_CLOCK_TYPE_MAX ++} CONSYS_GPS_CO_CLOCK_TYPE, *P_CONSYS_GPS_CO_CLOCK_TYPE; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern struct CONSYS_BASE_ADDRESS conn_reg; ++#if CONSYS_BT_WIFI_SHARE_V33 ++extern BT_WIFI_V33_STATUS gBtWifiV33; ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++extern INT32 mtk_wcn_consys_hw_init(VOID); ++extern INT32 mtk_wcn_consys_hw_deinit(VOID); ++extern INT32 mtk_wcn_consys_hw_pwr_off(VOID); ++extern INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type); ++extern INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type); ++extern INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable); ++extern INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable); ++extern INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable); ++extern INT32 mtk_wcn_consys_hw_state_show(VOID); ++extern UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset); ++#if CONSYS_ENALBE_SET_JTAG ++extern UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en); ++#endif ++extern UINT32 mtk_wcn_consys_soc_chipid(VOID); ++#if !defined(CONFIG_MTK_GPIO_LEGACY) ++extern struct pinctrl *mtk_wcn_consys_get_pinctrl(VOID); ++#endif ++extern INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 buf); ++#endif /* _MTK_WCN_CMB_HW_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +new file mode 100644 +index 000000000000..191f7312f897 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +@@ -0,0 +1,737 @@ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CONSYS-HW]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include "osal_typedef.h" ++#include "mtk_wcn_consys_hw.h" ++#include ++#include ++#include ++#if CONSYS_EMI_MPU_SETTING ++#include ++#endif ++ ++#include ++#ifdef CONFIG_MTK_HIBERNATION ++#include ++#endif ++ ++#include ++ ++#if CONSYS_CLOCK_BUF_CTRL ++#include ++#endif ++ ++#include ++#include ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static INT32 mtk_wmt_probe(struct platform_device *pdev); ++static INT32 mtk_wmt_remove(struct platform_device *pdev); ++ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++struct CONSYS_BASE_ADDRESS conn_reg; ++static phys_addr_t gConEmiPhyBase; ++static UINT8 __iomem *pEmibaseaddr; ++static struct clk *clk_infra_conn_main; /*ctrl infra_connmcu_bus clk */ ++static struct platform_device *my_pdev; ++static struct reset_control *rstc; ++static struct regulator *reg_VCN18; ++static struct regulator *reg_VCN28; ++static struct regulator *reg_VCN33_BT; ++static struct regulator *reg_VCN33_WIFI; ++static struct pinctrl *consys_pinctrl; ++static struct pinctrl *mt6625_spi_pinctrl; ++static struct pinctrl_state *mt6625_spi_default; ++static struct regmap *pmic_regmap; ++#define DYNAMIC_DUMP_GROUP_NUM 5 ++ ++static const struct of_device_id apwmt_of_ids[] = { ++ {.compatible = "mediatek,mt7623-consys",} ++}; ++MODULE_DEVICE_TABLE(of, apwmt_of_ids); ++ ++static struct platform_driver mtk_wmt_dev_drv = { ++ .probe = mtk_wmt_probe, ++ .remove = mtk_wmt_remove, ++ .driver = { ++ .name = "mt7623consys", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(apwmt_of_ids), ++ }, ++}; ++ ++static INT32 mtk_wmt_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct device_node *node = NULL; ++ ++ pm_runtime_enable(&pdev->dev); ++ my_pdev = pdev; ++ mt6625_spi_pinctrl = devm_pinctrl_get(&pdev->dev); ++ if (IS_ERR(mt6625_spi_pinctrl)) { ++ ret = PTR_ERR(mt6625_spi_pinctrl); ++ WMT_PLAT_ERR_FUNC("Wmt cannot find pinctrl!\n"); ++ goto set_pin_exit; ++ } ++ mt6625_spi_default = pinctrl_lookup_state(mt6625_spi_pinctrl, "consys_pins_default"); ++ if (IS_ERR(mt6625_spi_default)) { ++ ret = PTR_ERR(mt6625_spi_default); ++ WMT_PLAT_ERR_FUNC("Wmt Cannot find pinctrl default!\n"); ++ goto set_pin_exit; ++ } ++ pinctrl_select_state(mt6625_spi_pinctrl, mt6625_spi_default); ++set_pin_exit: ++ ++ node = of_parse_phandle(pdev->dev.of_node, "mediatek,pwrap-regmap", 0); ++ if (node) { ++ pmic_regmap = pwrap_node_to_regmap(node); ++ if (IS_ERR(pmic_regmap)) ++ goto set_pmic_wrap_exit; ++ } else { ++ WMT_PLAT_ERR_FUNC("Pwrap node has not register regmap.\n"); ++ goto set_pmic_wrap_exit; ++ } ++set_pmic_wrap_exit: ++ ++ clk_infra_conn_main = devm_clk_get(&pdev->dev, "consysbus"); ++ if (IS_ERR(clk_infra_conn_main)) { ++ WMT_PLAT_ERR_FUNC("sean debug [CCF]cannot get clk_infra_conn_main clock.\n"); ++ return PTR_ERR(clk_infra_conn_main); ++ } ++ WMT_PLAT_DBG_FUNC("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); ++ ++ reg_VCN18 = devm_regulator_get(&pdev->dev, "vcn18"); ++ if (IS_ERR(reg_VCN18)) { ++ ret = PTR_ERR(reg_VCN18); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN_1V8 fail, ret=%d\n", ret); ++ } ++ reg_VCN28 = devm_regulator_get(&pdev->dev, "vcn28"); ++ if (IS_ERR(reg_VCN28)) { ++ ret = PTR_ERR(reg_VCN28); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN_2V8 fail, ret=%d\n", ret); ++ } ++ reg_VCN33_BT = devm_regulator_get(&pdev->dev, "vcn33_bt"); ++ if (IS_ERR(reg_VCN33_BT)) { ++ ret = PTR_ERR(reg_VCN33_BT); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_BT fail, ret=%d\n", ret); ++ } ++ reg_VCN33_WIFI = devm_regulator_get(&pdev->dev, "vcn33_wifi"); ++ if (IS_ERR(reg_VCN33_WIFI)) { ++ ret = PTR_ERR(reg_VCN33_WIFI); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_WIFI fail, ret=%d\n", ret); ++ } ++ ++ rstc = devm_reset_control_get(&pdev->dev, "connsys"); ++ if (IS_ERR(rstc)) { ++ ret = PTR_ERR(rstc); ++ WMT_PLAT_ERR_FUNC("CanNot get consys reset. ret=%d\n", ret); ++ return PTR_ERR(rstc); ++ } ++ ++ consys_pinctrl = devm_pinctrl_get(&pdev->dev); ++ if (IS_ERR(consys_pinctrl)) { ++ ret = PTR_ERR(consys_pinctrl); ++ WMT_PLAT_ERR_FUNC("CanNot find consys pinctrl. ret=%d\n", ret); ++ return PTR_ERR(consys_pinctrl); ++ } ++ return 0; ++} ++ ++static INT32 mtk_wmt_remove(struct platform_device *pdev) ++{ ++ pm_runtime_disable(&pdev->dev); ++ ++ return 0; ++} ++ ++VOID mtk_wcn_consys_power_on(VOID) ++{ ++ INT32 iRet = -1; ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ iRet = pm_runtime_get_sync(&my_pdev->dev); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("pm_runtime_get_sync() fail(%d)\n", iRet); ++ else ++ WMT_PLAT_INFO_FUNC("pm_runtime_get_sync() CONSYS ok\n"); ++ ++ iRet = device_init_wakeup(&my_pdev->dev, true); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("device_init_wakeup(true) fail.\n"); ++ else ++ WMT_PLAT_INFO_FUNC("device_init_wakeup(true) CONSYS ok\n"); ++} ++ ++VOID mtk_wcn_consys_power_off(VOID) ++{ ++ INT32 iRet = -1; ++ ++ iRet = pm_runtime_put_sync(&my_pdev->dev); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("pm_runtime_put_sync() fail.\n"); ++ else ++ WMT_PLAT_INFO_FUNC("pm_runtime_put_sync() CONSYS ok\n"); ++ ++ iRet = device_init_wakeup(&my_pdev->dev, false); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("device_init_wakeup(false) fail.\n"); ++ else ++ WMT_PLAT_INFO_FUNC("device_init_wakeup(false) CONSYS ok\n"); ++} ++ ++INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_type) ++{ ++ UINT32 retry = 10; ++ UINT32 consysHwChipId = 0; ++ ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),start\n", on); ++ if (on) { ++ WMT_PLAT_DBG_FUNC("++\n"); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ /*need PMIC driver provide new API protocol */ ++ /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ ++ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ /* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */ ++ if (reg_VCN18) { ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ regulator_set_voltage(reg_VCN18, 1800000, 1800000); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (regulator_enable(reg_VCN18)) ++ WMT_PLAT_ERR_FUNC("enable VCN18 fail\n"); ++ else ++ WMT_PLAT_DBG_FUNC("enable VCN18 ok\n"); ++ } ++ udelay(150); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (co_clock_type) { ++ /*step0,clk buf ctrl */ ++ WMT_PLAT_INFO_FUNC("co clock type(%d),turn on clk buf\n", co_clock_type); ++#if CONSYS_CLOCK_BUF_CTRL ++ clk_buf_ctrl(CLK_BUF_CONN, 1); ++#endif ++ /*if co-clock mode: */ ++ /*2.set VCN28 to SW control mode (with PMIC_WRAP API) */ ++ /*turn on VCN28 LDO only when FMSYS is activated" */ ++ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ ++ } else { ++ /*if NOT co-clock: */ ++ /*2.1.switch VCN28 to HW control mode (with PMIC_WRAP API) */ ++ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x1 << 14);/*V28*/ ++ /*2.2.turn on VCN28 LDO (with PMIC_WRAP API)" */ ++ /*fix vcn28 not balance warning */ ++ if (reg_VCN28) { ++ regulator_set_voltage(reg_VCN28, 2800000, 2800000); ++ if (regulator_enable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("enable VCN_2V8 fail!\n"); ++ else ++ WMT_PLAT_DBG_FUNC("enable VCN_2V8 ok\n"); ++ } ++ } ++ ++ /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ reset_control_reset(rstc); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ mtk_wcn_consys_power_on(); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ /*11.26M is ready now, delay 10us for mem_pd de-assert */ ++ udelay(10); ++ /*enable AP bus clock : connmcu_bus_pd API: enable_clock() ++?? */ ++ clk_prepare_enable(clk_infra_conn_main); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ WMT_PLAT_DBG_FUNC("[CCF]enable clk_infra_conn_main\n"); ++ /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ ++ while (retry-- > 0) { ++ consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET) - 0xf6d; ++ ++ if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { ++ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); ++ break; ++ } ++ if ((consysHwChipId == 0x8163) || (consysHwChipId == 0x8127) || (consysHwChipId == 0x7623)) { ++ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); ++ break; ++ } ++ ++ WMT_PLAT_ERR_FUNC("Read CONSYS chipId(0x%08x)", consysHwChipId); ++ msleep(20); ++ } ++ ++ if ((0 == retry) || (0 == consysHwChipId)) ++ WMT_PLAT_ERR_FUNC("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); ++ ++ msleep(40); ++ ++ } else { ++ ++ clk_disable_unprepare(clk_infra_conn_main); ++ WMT_PLAT_DBG_FUNC("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n"); ++ mtk_wcn_consys_power_off(); ++ ++ if (co_clock_type) { ++ /*VCN28 has been turned off by GPS OR FM */ ++#if CONSYS_CLOCK_BUF_CTRL ++ clk_buf_ctrl(CLK_BUF_CONN, 0); ++#endif ++ } else { ++ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ ++ /*turn off VCN28 LDO (with PMIC_WRAP API)" */ ++ if (reg_VCN28) { ++ if (regulator_disable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("disable VCN_2V8 fail!\n"); ++ else ++ WMT_PLAT_DBG_FUNC("disable VCN_2V8 ok\n"); ++ } ++ } ++ ++ /*AP power off MT6625L VCN_1V8 LDO */ ++ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); ++ if (reg_VCN18) { ++ if (regulator_disable(reg_VCN18)) ++ WMT_PLAT_ERR_FUNC("disable VCN_1V8 fail!\n"); ++ else ++ WMT_PLAT_DBG_FUNC("disable VCN_1V8 ok\n"); ++ } ++ ++ } ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),finish\n", on); ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_gpio_ctrl(UINT32 on) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), start\n", on); ++ ++ if (on) { ++ ++ /* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */ ++ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); */ ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT); ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ registered and disabled\n"); ++ ++ } else { ++ ++ /* set bgf eint/all eint to deinit state, namely input low state */ ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); ++ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ unregistered and disabled\n"); ++ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); */ ++ } ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), finish\n", on); ++ return iRet; ++ ++} ++ ++INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, start\n"); ++ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); ++ iRet += mtk_wcn_consys_hw_gpio_ctrl(1); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, finish(%d)\n", iRet); ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_hw_pwr_off(VOID) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, start\n"); ++ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(0, 0); ++ iRet += mtk_wcn_consys_hw_gpio_ctrl(0); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, finish(%d)\n", iRet); ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst start, eirq should be disabled before this step\n"); ++ ++ /*1. do whole hw power off flow */ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type); ++ ++ /*2. do whole hw power on flow */ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst finish, eirq should be enabled after this step\n"); ++ return iRet; ++} ++ ++#if CONSYS_BT_WIFI_SHARE_V33 ++INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) ++{ ++ /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ ++ if (enable) { ++ if (1 == gBtWifiV33.counter) { ++ gBtWifiV33.counter++; ++ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); ++ } else if (2 == gBtWifiV33.counter) { ++ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); ++ } else { ++#if CONSYS_PMIC_CTRL_ENABLE ++ /*do BT PMIC on,depenency PMIC API ready */ ++ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ ++ /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ ++ hwPowerOn(MT6323_POWER_LDO_VCN33, VOL_3300, "wcn_drv"); ++ upmu_set_vcn33_on_ctrl_bt(1); ++#endif ++ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 on\n"); ++ gBtWifiV33.counter++; ++ } ++ ++ } else { ++ if (1 == gBtWifiV33.counter) { ++ /*do BT PMIC off */ ++ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ ++#if CONSYS_PMIC_CTRL_ENABLE ++ upmu_set_vcn33_on_ctrl_bt(0); ++ hwPowerDown(MT6323_POWER_LDO_VCN33, "wcn_drv"); ++#endif ++ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 off\n"); ++ gBtWifiV33.counter--; ++ } else if (2 == gBtWifiV33.counter) { ++ gBtWifiV33.counter--; ++ WMT_PLAT_DBG_FUNC("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); ++ } else { ++ WMT_PLAT_DBG_FUNC("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); ++ } ++ ++ } ++ /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) ++{ ++ mtk_wcn_consys_hw_bt_paldo_ctrl(enable); ++ return 0; ++} ++ ++#else ++INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) ++{ ++ ++ if (enable) { ++ /*do BT PMIC on,depenency PMIC API ready */ ++ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ ++ if (reg_VCN33_BT) { ++ regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); ++ if (regulator_enable(reg_VCN33_BT)) ++ WMT_PLAT_ERR_FUNC("WMT do BT PMIC on fail!\n"); ++ } ++ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x1 << 5);/*BT*/ ++ WMT_PLAT_INFO_FUNC("WMT do BT PMIC on\n"); ++ } else { ++ /*do BT PMIC off */ ++ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ ++ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x0 << 5);/*BT*/ ++ if (reg_VCN33_BT) ++ if (regulator_disable(reg_VCN33_BT)) ++ WMT_PLAT_ERR_FUNC("WMT do BT PMIC off fail!\n"); ++ WMT_PLAT_INFO_FUNC("WMT do BT PMIC off\n"); ++ } ++ ++ return 0; ++ ++} ++ ++INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) ++{ ++ ++ if (enable) { ++ /*do WIFI PMIC on,depenency PMIC API ready */ ++ /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ ++ if (reg_VCN33_WIFI) { ++ regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); ++ if (regulator_enable(reg_VCN33_WIFI)) ++ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC on fail!\n"); ++ else ++ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on !\n"); ++ } ++ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x1 << 14);/*WIFI*/ ++ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on\n"); ++ } else { ++ /*do WIFI PMIC off */ ++ /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ ++ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x0 << 14);/*WIFI*/ ++ if (reg_VCN33_WIFI) ++ if (regulator_disable(reg_VCN33_WIFI)) ++ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC off fail!\n"); ++ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC off\n"); ++ } ++ ++ return 0; ++} ++ ++#endif ++INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) ++{ ++ if (enable) { ++ /*in co-clock mode,need to turn on vcn28 when fm on */ ++ if (reg_VCN28) { ++ regulator_set_voltage(reg_VCN28, 2800000, 2800000); ++ if (regulator_enable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC on fail!\n"); ++ } ++ WMT_PLAT_INFO_FUNC("turn on vcn28 for fm/gps usage in co-clock mode\n"); ++ } else { ++ /*in co-clock mode,need to turn off vcn28 when fm off */ ++ if (reg_VCN28) ++ if (regulator_disable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC off fail!\n"); ++ WMT_PLAT_INFO_FUNC("turn off vcn28 for fm/gps usage in co-clock mode\n"); ++ } ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_state_show(VOID) ++{ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_restore(struct device *device) ++{ ++ UINT32 addrPhy = 0; ++ ++ if (gConEmiPhyBase) { ++ ++#if CONSYS_EMI_MPU_SETTING ++ /*set MPU for EMI share Memory */ ++ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); ++ ++#if 0 ++ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, ++ gConEmiPhyBase + SZ_1M, ++ 5, ++ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); ++ ++ ++#else ++ WMT_PLAT_WARN_FUNC("not define platform config\n"); ++#endif ++ ++#endif ++ /*consys to ap emi remapping register:10001310, cal remapping address */ ++ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; ++ ++ /*enable consys to ap emi remapping bit12 */ ++ addrPhy = addrPhy | 0x1000; ++ ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); ++ ++#if 1 ++ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); ++#else ++ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); ++#endif ++ if (pEmibaseaddr) { ++ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); ++ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); ++ } else { ++ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); ++ } ++ } else { ++ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); ++ } ++ ++ return 0; ++} ++ ++/*Reserved memory by device tree!*/ ++int reserve_memory_consys_fn(struct reserved_mem *rmem) ++{ ++ WMT_PLAT_WARN_FUNC(" name: %s, base: 0x%llx, size: 0x%llx\n", rmem->name, ++ (unsigned long long)rmem->base, (unsigned long long)rmem->size); ++ gConEmiPhyBase = rmem->base; ++ return 0; ++} ++ ++RESERVEDMEM_OF_DECLARE(reserve_memory_test, "mediatek,consys-reserve-memory", reserve_memory_consys_fn); ++ ++ ++INT32 mtk_wcn_consys_hw_init(void) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 addrPhy = 0; ++ INT32 i = 0; ++ struct device_node *node = NULL; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); ++ if (node) { ++ /* registers base address */ ++ conn_reg.mcu_base = (SIZE_T) of_iomap(node, i); ++ WMT_PLAT_DBG_FUNC("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); ++ i++; ++ ++ conn_reg.topckgen_base = (SIZE_T) of_iomap(node, i); ++ WMT_PLAT_DBG_FUNC("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); ++ i++; ++ } else { ++ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); ++ return iRet; ++ } ++ if (gConEmiPhyBase) { ++#if CONSYS_EMI_MPU_SETTING ++ /*set MPU for EMI share Memory */ ++ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); ++ ++#if 0 ++ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, ++ gConEmiPhyBase + SZ_1M, ++ 5, ++ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); ++#else ++ WMT_PLAT_WARN_FUNC("not define platform config\n"); ++#endif ++ ++#endif ++ WMT_PLAT_DBG_FUNC("get consys start phy address(0x%zx)\n", (SIZE_T) gConEmiPhyBase); ++ ++ /*consys to ap emi remapping register:10001310, cal remapping address */ ++ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; ++ ++ /*enable consys to ap emi remapping bit12 */ ++ addrPhy = addrPhy | 0x1000; ++ ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump(0x%08x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); ++ ++#if 1 ++ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); ++#else ++ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); ++#endif ++ /* pEmibaseaddr = ioremap_nocache(0x80090400,270*KBYTE); */ ++ if (pEmibaseaddr) { ++ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); ++ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); ++ iRet = 0; ++ } else { ++ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); ++ } ++ } else { ++ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); ++ } ++#ifdef CONFIG_MTK_HIBERNATION ++ WMT_PLAT_INFO_FUNC("register connsys restore cb for complying with IPOH function\n"); ++ register_swsusp_restore_noirq_func(ID_M_CONNSYS, mtk_wcn_consys_hw_restore, NULL); ++#endif ++ iRet = platform_driver_register(&mtk_wmt_dev_drv); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("WMT platform driver registered failed(%d)\n", iRet); ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_hw_deinit(void) ++{ ++ if (pEmibaseaddr) { ++ iounmap(pEmibaseaddr); ++ pEmibaseaddr = NULL; ++ } ++#ifdef CONFIG_MTK_HIBERNATION ++ unregister_swsusp_restore_noirq_func(ID_M_CONNSYS); ++#endif ++ ++ platform_driver_unregister(&mtk_wmt_dev_drv); ++ return 0; ++} ++ ++UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset) ++{ ++ UINT8 *p_virtual_addr = NULL; ++ ++ if (!pEmibaseaddr) { ++ WMT_PLAT_ERR_FUNC("EMI base address is NULL\n"); ++ return NULL; ++ } ++ WMT_PLAT_DBG_FUNC("ctrl_state_offset(%08x)\n", ctrl_state_offset); ++ p_virtual_addr = pEmibaseaddr + ctrl_state_offset; ++ ++ return p_virtual_addr; ++} ++ ++UINT32 mtk_wcn_consys_soc_chipid(void) ++{ ++ return PLATFORM_SOC_CHIP; ++} ++ ++struct pinctrl *mtk_wcn_consys_get_pinctrl() ++{ ++ return consys_pinctrl; ++} ++INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 str_buf) ++{ ++ PUINT8 vir_addr = NULL; ++ ++ vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP); ++ if (!vir_addr) { ++ WMT_PLAT_ERR_FUNC("get vir address fail\n"); ++ return -2; ++ } ++ memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8); ++ WMT_PLAT_INFO_FUNC("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c +new file mode 100644 +index 000000000000..3a3be8308f6a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c +@@ -0,0 +1,1071 @@ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-PLAT]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++ ++/* ALPS header files */ ++/*#include */ ++/*#include */ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++#include ++#endif ++#include ++ ++/* MTK_WCN_COMBO header files */ ++#include "osal_typedef.h" ++#include "mtk_wcn_consys_hw.h" ++#include "stp_dbg.h" ++ ++#define CFG_WMT_WAKELOCK_SUPPORT 1 ++ ++#ifdef CONFIG_MTK_MT6306_SUPPORT ++#define MTK_WCN_MT6306_IS_READY 1 ++#else ++#define MTK_WCN_MT6306_IS_READY 0 ++#endif ++ ++#if MTK_WCN_MT6306_IS_READY ++#include ++ ++#ifdef GPIO_GPS_LNA_PIN ++#undef GPIO_GPS_LNA_PIN ++#endif ++ ++#define GPIO_GPS_LNA_PIN GPIO7 ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { ++ .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, ++ .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, ++ .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, ++ .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, ++ .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, ++ .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, ++ .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, ++ .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, ++ .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, ++ .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, ++ .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, ++ .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, ++ .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, ++}; ++ ++CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { ++ .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, ++ .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, ++ .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, ++ .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, ++ .p_ecso = &mtk_wcn_emi_state_off, ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static VOID wmt_plat_bgf_eirq_cb(VOID); ++ ++static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state); ++static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state); ++static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state); ++static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state); ++ ++static INT32 wmt_plat_dump_pin_conf(VOID); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++UINT32 gCoClockFlag = 0; ++BGF_IRQ_BALANCE gbgfIrqBle; ++UINT32 wmtPlatLogLvl = WMT_PLAT_LOG_DBG; ++#if CONSYS_BT_WIFI_SHARE_V33 ++BT_WIFI_V33_STATUS gBtWifiV33; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if CFG_WMT_WAKELOCK_SUPPORT ++static struct mutex gOsSLock; ++#ifdef CONFIG_PM_WAKELOCKS ++static struct wakeup_source wmtWakeLock; ++#else ++static struct wake_lock wmtWakeLock; ++#endif ++#endif ++ ++irq_cb wmt_plat_bgf_irq_cb = NULL; ++device_audio_if_cb wmt_plat_audio_if_cb = NULL; ++func_ctrl_cb wmt_plat_func_ctrl_cb = NULL; ++thermal_query_ctrl_cb wmt_plat_thermal_query_ctrl_cb = NULL; ++deep_idle_ctrl_cb wmt_plat_deep_idle_ctrl_cb = NULL; ++ ++static const fp_set_pin gfp_set_pin_table[] = { ++ [PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl, ++ [PIN_I2S_GRP] = wmt_plat_i2s_ctrl, ++ [PIN_GPS_SYNC] = wmt_plat_gps_sync_ctrl, ++ [PIN_GPS_LNA] = wmt_plat_gps_lna_ctrl, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*! ++ * \brief audio control callback function for CMB_STUB on ALPS ++ * ++ * A platform function required for dynamic binding with CMB_STUB on ALPS. ++ * ++ * \param state desired audio interface state to use ++ * \param flag audio interface control options ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid parameters ++ * \retval < 0 error for operation fail ++ */ ++INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) ++{ ++ INT32 iRet = 0; ++ UINT32 pinShare = 0; ++ ++ /* input sanity check */ ++ if ((CMB_STUB_AIF_MAX <= state) ++ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { ++ return -1; ++ } ++ ++ iRet = 0; ++ ++ /* set host side first */ ++ switch (state) { ++ case CMB_STUB_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); ++ break; ++ ++ case CMB_STUB_AIF_1: ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); ++ break; ++ ++ case CMB_STUB_AIF_2: ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); ++ break; ++ ++ case CMB_STUB_AIF_3: ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); ++ break; ++ ++ default: ++ /* FIXME: move to cust folder? */ ++ WMT_PLAT_ERR_FUNC("invalid state [%d]\n", state); ++ iRet = -1; ++ break; ++ } ++ ++ if (CMB_STUB_AIF_CTRL_EN == ctrl) { ++ WMT_PLAT_INFO_FUNC("call chip aif setting\n"); ++ /* need to control chip side GPIO */ ++ if (NULL != wmt_plat_audio_if_cb) { ++ iRet += (*wmt_plat_audio_if_cb) (state, (pinShare) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++ } else { ++ WMT_PLAT_WARN_FUNC("wmt_plat_audio_if_cb is not registered\n"); ++ iRet -= 1; ++ } ++ ++ } else { ++ WMT_PLAT_INFO_FUNC("skip chip aif setting\n"); ++ } ++ ++ return iRet; ++ ++} ++ ++static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on) ++{ ++ if (wmt_plat_func_ctrl_cb) ++ (*wmt_plat_func_ctrl_cb) (on, type); ++} ++ ++static long wmt_plat_thermal_ctrl(VOID) ++{ ++ long temp = 0; ++ ++ if (wmt_plat_thermal_query_ctrl_cb) ++ temp = (*wmt_plat_thermal_query_ctrl_cb) (); ++ ++ return temp; ++} ++ ++static INT32 wmt_plat_deep_idle_ctrl(UINT32 dpilde_ctrl) ++{ ++ INT32 iRet = -1; ++ ++ if (wmt_plat_deep_idle_ctrl_cb) ++ iRet = (*wmt_plat_deep_idle_ctrl_cb) (dpilde_ctrl); ++ ++ return iRet; ++} ++ ++static VOID wmt_plat_bgf_eirq_cb(VOID) ++{ ++#if CFG_WMT_PS_SUPPORT ++/* #error "need to disable EINT here" */ ++ /* wmt_lib_ps_irq_cb(); */ ++ if (NULL != wmt_plat_bgf_irq_cb) ++ (*(wmt_plat_bgf_irq_cb)) (); ++ else ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: wmt_plat_bgf_irq_cb not registered\n"); ++#else ++ return; ++#endif ++ ++} ++ ++irqreturn_t wmt_plat_bgf_irq_isr(INT32 i, VOID *arg) ++{ ++#if CFG_WMT_PS_SUPPORT ++ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ wmt_plat_bgf_eirq_cb(); ++#else ++ WMT_PLAT_INFO_FUNC("skip irq handing because psm is disable"); ++#endif ++ return IRQ_HANDLED; ++} ++ ++VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb) ++{ ++ wmt_plat_bgf_irq_cb = bgf_irq_cb; ++} ++EXPORT_SYMBOL(wmt_plat_irq_cb_reg); ++ ++VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb) ++{ ++ wmt_plat_audio_if_cb = aif_ctrl_cb; ++} ++EXPORT_SYMBOL(wmt_plat_aif_cb_reg); ++ ++VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl) ++{ ++ wmt_plat_func_ctrl_cb = subsys_func_ctrl; ++} ++EXPORT_SYMBOL(wmt_plat_func_ctrl_cb_reg); ++ ++VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl) ++{ ++ wmt_plat_thermal_query_ctrl_cb = thermal_query_ctrl; ++} ++EXPORT_SYMBOL(wmt_plat_thermal_ctrl_cb_reg); ++ ++VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl) ++{ ++ wmt_plat_deep_idle_ctrl_cb = deep_idle_ctrl; ++} ++EXPORT_SYMBOL(wmt_plat_deep_idle_ctrl_cb_reg); ++ ++UINT32 wmt_plat_soc_co_clock_flag_get(VOID) ++{ ++ return gCoClockFlag; ++} ++ ++static UINT32 wmt_plat_soc_co_clock_flag_set(UINT32 flag) ++{ ++ gCoClockFlag = flag; ++ return 0; ++} ++ ++INT32 wmt_plat_init(UINT32 co_clock_type) ++{ ++ CMB_STUB_CB stub_cb; ++ INT32 iret; ++ /*init wmt function ctrl wakelock if wake lock is supported by host platform */ ++ ++ wmt_plat_soc_co_clock_flag_set(co_clock_type); ++ ++ stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; ++ stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; ++ stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl; ++ stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl; ++ stub_cb.size = sizeof(stub_cb); ++ ++ /* register to cmb_stub */ ++ iret = mtk_wcn_cmb_stub_reg(&stub_cb); ++#ifdef CFG_WMT_WAKELOCK_SUPPORT ++#ifdef CONFIG_PM_WAKELOCKS ++ wakeup_source_init(&wmtWakeLock, "wmtFuncCtrl"); ++#else ++ wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl"); ++#endif ++ mutex_init(&gOsSLock); ++#endif ++ ++#if CONSYS_BT_WIFI_SHARE_V33 ++ gBtWifiV33.counter = 0; ++ spin_lock_init(&gBtWifiV33.lock); ++#endif ++ ++ iret += mtk_wcn_consys_hw_init(); ++ ++ spin_lock_init(&gbgfIrqBle.lock); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_init); ++ ++INT32 wmt_plat_deinit(VOID) ++{ ++ INT32 iret = 0; ++ /* 2. unreg to cmb_stub */ ++ iret = mtk_wcn_cmb_stub_unreg(); ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling wmt wakelock deinit\n",__FUNCTION__,__LINE__); ++ /*3. wmt wakelock deinit */ ++#ifdef CFG_WMT_WAKELOCK_SUPPORT ++#ifdef CONFIG_PM_WAKELOCKS ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling wakeup_source_trash\n",__FUNCTION__,__LINE__); ++ wakeup_source_trash(&wmtWakeLock); ++#else ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling wake lock destroy %d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); ++//destroy calls wakeup_source_trash with &lock->ws ++printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock:%d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); ++printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock->ws: %d\n",__FUNCTION__,__LINE__,(int)&(wmtWakeLock.ws)); ++ wake_lock_destroy(&wmtWakeLock); ++#endif ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling mutex_destroy\n",__FUNCTION__,__LINE__); ++ mutex_destroy(&gOsSLock); ++ WMT_PLAT_DBG_FUNC("destroy wmtWakeLock\n"); ++#endif ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling consys hw deinit\n",__FUNCTION__,__LINE__); ++ ++ iret += mtk_wcn_consys_hw_deinit(); ++ ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_deinit); ++ ++static INT32 wmt_plat_dump_pin_conf(VOID) ++{ ++ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration start<=\n"); ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++ ++#ifdef GPIO_COMBO_BGF_EINT_PIN ++ WMT_PLAT_DBG_FUNC("BGF_EINT(GPIO%d)\n", GPIO_COMBO_BGF_EINT_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("BGF_EINT(not defined)\n"); ++#endif ++ ++#ifdef CUST_EINT_COMBO_BGF_NUM ++ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(%d)\n", CUST_EINT_COMBO_BGF_NUM); ++#else ++ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(not defined)\n"); ++#endif ++ ++#ifdef GPIO_COMBO_URXD_PIN ++ WMT_PLAT_DBG_FUNC("UART_RX(GPIO%d)\n", GPIO_COMBO_URXD_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("UART_RX(not defined)\n"); ++#endif ++#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) ++#ifdef GPIO_COMBO_I2S_CK_PIN ++ WMT_PLAT_DBG_FUNC("I2S_CK(GPIO%d)\n", GPIO_COMBO_I2S_CK_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("I2S_CK(not defined)\n"); ++#endif ++#ifdef GPIO_COMBO_I2S_WS_PIN ++ WMT_PLAT_DBG_FUNC("I2S_WS(GPIO%d)\n", GPIO_COMBO_I2S_WS_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("I2S_WS(not defined)\n"); ++#endif ++#ifdef GPIO_COMBO_I2S_DAT_PIN ++ WMT_PLAT_DBG_FUNC("I2S_DAT(GPIO%d)\n", GPIO_COMBO_I2S_DAT_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("I2S_DAT(not defined)\n"); ++#endif ++#else /* FM_ANALOG_INPUT || FM_ANALOG_OUTPUT */ ++ WMT_PLAT_DBG_FUNC("FM digital mode is not set, no need for I2S GPIOs\n"); ++#endif ++#ifdef GPIO_GPS_SYNC_PIN ++ WMT_PLAT_DBG_FUNC("GPS_SYNC(GPIO%d)\n", GPIO_GPS_SYNC_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("GPS_SYNC(not defined)\n"); ++#endif ++ ++#ifdef GPIO_GPS_LNA_PIN ++ WMT_PLAT_INFO_FUNC("GPS_LNA(GPIO%d)\n", GPIO_GPS_LNA_PIN); ++#else ++ WMT_PLAT_INFO_FUNC("GPS_LNA(not defined)\n"); ++#endif ++ ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n"); ++ return 0; ++} ++ ++INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state) ++{ ++ INT32 ret = -1; ++ ++ switch (state) { ++ case FUNC_ON: ++ /* TODO:[ChangeFeature][George] always output this or by request throuth /proc or sysfs? */ ++ wmt_plat_dump_pin_conf(); ++ ret = mtk_wcn_consys_hw_pwr_on(gCoClockFlag); ++ break; ++ ++ case FUNC_OFF: ++ ret = mtk_wcn_consys_hw_pwr_off(); ++ break; ++ ++ case FUNC_RST: ++ ret = mtk_wcn_consys_hw_rst(gCoClockFlag); ++ break; ++ case FUNC_STAT: ++ ret = mtk_wcn_consys_hw_state_show(); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state); ++ break; ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(wmt_plat_pwr_ctrl); ++ ++INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) ++{ ++#ifdef CONFIG_OF ++ struct device_node *node; ++ unsigned int irq_info[3] = { 0, 0, 0 }; ++#endif ++ INT32 iret = -EINVAL; ++ static INT32 bgf_irq_num = -1; ++ static UINT32 bgf_irq_flag; ++ /* TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls */ ++ ++ if ((PIN_STA_INIT != state) ++ && (PIN_STA_DEINIT != state) ++ && (PIN_STA_EINT_EN != state) ++ && (PIN_STA_EINT_DIS != state)) { ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id); ++ return -1; ++ } ++ ++ switch (id) { ++ case PIN_BGF_EINT: ++ ++ if (PIN_STA_INIT == state) { ++#ifdef CONFIG_OF ++ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); ++ if (node) { ++ bgf_irq_num = irq_of_parse_and_map(node, 0); ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ WMT_PLAT_ERR_FUNC("get irq flags from DTS fail!!\n"); ++ return iret; ++ } ++ bgf_irq_flag = irq_info[2]; ++ WMT_PLAT_INFO_FUNC("get irq id(%d) and irq trigger flag(%d) from DT\n", bgf_irq_num, ++ bgf_irq_flag); ++ } else { ++ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); ++ return iret; ++ } ++#else ++ bgf_irq_num = MT_CONN2AP_BTIF_WAKEUP_IRQ_ID; ++ bgf_irq_flag = IRQF_TRIGGER_LOW; ++#endif ++ iret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, bgf_irq_flag, "BTIF_WAKEUP_IRQ", NULL); ++ if (iret) { ++ WMT_PLAT_ERR_FUNC("request_irq fail,irq_no(%d),iret(%d)\n", bgf_irq_num, iret); ++ return iret; ++ } ++ gbgfIrqBle.counter = 1; ++ ++ } else if (PIN_STA_EINT_EN == state) { ++ ++ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ if (gbgfIrqBle.counter) { ++ WMT_PLAT_DBG_FUNC("BGF INT has been enabled,counter(%d)\n", gbgfIrqBle.counter); ++ } else { ++ enable_irq(bgf_irq_num); ++ gbgfIrqBle.counter++; ++ } ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (en)\n"); ++ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ } else if (PIN_STA_EINT_DIS == state) { ++ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ if (!gbgfIrqBle.counter) { ++ WMT_PLAT_INFO_FUNC("BGF INT has been disabled,counter(%d)\n", gbgfIrqBle.counter); ++ } else { ++ disable_irq_nosync(bgf_irq_num); ++ gbgfIrqBle.counter--; ++ } ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (dis)\n"); ++ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ } else { ++ free_irq(bgf_irq_num, NULL); ++ /* de-init: nothing to do in ALPS, such as un-registration... */ ++ } ++ iret = 0; ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id); ++ iret = -1; ++ break; ++ } ++ ++ return iret; ++} ++EXPORT_SYMBOL(wmt_plat_eirq_ctrl); ++ ++INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) ++{ ++ if ((PIN_ID_MAX > id) ++ && (PIN_STA_MAX > state)) { ++ ++ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ ++ if (gfp_set_pin_table[id]) ++ return (*(gfp_set_pin_table[id])) (state); /* .handler */ ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id); ++ return -2; ++ } ++ return -1; ++} ++EXPORT_SYMBOL(wmt_plat_gpio_ctrl); ++ ++INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state) ++{ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++#ifdef GPIO_COMBO_BGF_EINT_PIN ++ switch (state) { ++ case PIN_STA_INIT: ++ /*set to gpio input low, pull down enable */ ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); ++ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); ++ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd)\n"); ++ break; ++ ++ case PIN_STA_MUX: ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); ++ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_UP); ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_EINT); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt mux (eint)\n"); ++ break; ++ ++ case PIN_STA_IN_L: ++ case PIN_STA_DEINIT: ++ /*set to gpio input low, pull down enable */ ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); ++ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); ++ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd)\n"); ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state); ++ break; ++ } ++#else ++ WMT_PLAT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n"); ++#endif ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ return 0; ++} ++ ++static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state) ++{ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++ ++#ifdef GPIO_GPS_SYNC_PIN ++#ifndef GPIO_GPS_SYNC_PIN_M_GPS_SYNC ++#ifdef GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC ++#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC ++#else ++#ifdef GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC ++#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC ++#endif ++#endif ++#endif ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_GPS_SYNC_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_GPS_SYNC_PIN, GPIO_OUT_ZERO); ++ break; ++ ++ case PIN_STA_MUX: ++ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPS_SYNC); ++ break; ++ ++ default: ++ break; ++ } ++#endif ++ ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ return 0; ++} ++ ++#if MTK_WCN_MT6306_IS_READY ++/* MT6306 GPIO7 is GPIO_GPS_LNA_EN, for K2 common phone pin modification */ ++static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) ++{ ++#ifdef GPIO_GPS_LNA_PIN ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ WMT_PLAT_ERR_FUNC("Gps LNA pin ctrl %d!\n", state); ++ mt6306_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); ++ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ case PIN_STA_OUT_H: ++ WMT_PLAT_ERR_FUNC("Gps LNA pin output high!\n"); ++ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); ++ break; ++ case PIN_STA_OUT_L: ++ WMT_PLAT_ERR_FUNC("Gps LNA pin output low!\n"); ++ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); ++ break; ++ } ++ return 0; ++#else ++ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); ++ return 0; ++#endif ++} ++#else ++ ++static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) ++{ ++#if !defined(CONFIG_MTK_GPIO_LEGACY) ++ static struct pinctrl_state *gps_lna_init; ++ static struct pinctrl_state *gps_lna_oh; ++ static struct pinctrl_state *gps_lna_ol; ++ static struct pinctrl *consys_pinctrl; ++ ++ WMT_PLAT_DBG_FUNC("ENTER++\n"); ++ consys_pinctrl = mtk_wcn_consys_get_pinctrl(); ++ if (NULL == consys_pinctrl) { ++ WMT_PLAT_ERR_FUNC("get consys pinctrl fail\n"); ++ return -1; ++ } ++ ++ gps_lna_init = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_init"); ++ if (NULL == gps_lna_init) { ++ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin init state!\n"); ++ return -2; ++ } ++ ++ gps_lna_oh = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_oh"); ++ if (NULL == gps_lna_oh) { ++ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin oh state!\n"); ++ return -3; ++ } ++ ++ gps_lna_ol = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_ol"); ++ if (NULL == gps_lna_ol) { ++ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin ol state!\n"); ++ return -4; ++ } ++ ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ pinctrl_select_state(consys_pinctrl, gps_lna_init); ++ WMT_PLAT_INFO_FUNC("set gps lna to init\n"); ++ break; ++ case PIN_STA_OUT_H: ++ pinctrl_select_state(consys_pinctrl, gps_lna_oh); ++ WMT_PLAT_INFO_FUNC("set gps lna to oh\n"); ++ break; ++ case PIN_STA_OUT_L: ++ pinctrl_select_state(consys_pinctrl, gps_lna_ol); ++ WMT_PLAT_INFO_FUNC("set gps lna to ol\n"); ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); ++ break; ++ } ++ return 0; ++#else ++#ifdef GPIO_GPS_LNA_PIN ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ mt_set_gpio_pull_enable(GPIO_GPS_LNA_PIN, GPIO_PULL_DISABLE); ++ mt_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_mode(GPIO_GPS_LNA_PIN, GPIO_GPS_LNA_PIN_M_GPIO); ++ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ case PIN_STA_OUT_H: ++ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); ++ break; ++ case PIN_STA_OUT_L: ++ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); ++ break; ++ } ++ return 0; ++#else ++ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); ++ return 0; ++#endif ++#endif /* !defined(CONFIG_MTK_GPIO_LEGACY) */ ++} ++#endif ++ ++INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state) ++{ ++ /* TODO: [NewFeature][GeorgeKuo]: GPIO_I2Sx is changed according to different project. */ ++ /* TODO: provide a translation table in board_custom.h for different ALPS project customization. */ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++ ++#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) ++#if defined(GPIO_COMBO_I2S_CK_PIN) ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_MUX: ++ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_I2S0_CK); ++ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_I2S0_WS); ++ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_I2S0_DAT); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n"); ++ break; ++ case PIN_STA_IN_L: ++ case PIN_STA_DEINIT: ++ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_I2S_CK_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_COMBO_I2S_CK_PIN, GPIO_OUT_ZERO); ++ ++ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_I2S_WS_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_COMBO_I2S_WS_PIN, GPIO_OUT_ZERO); ++ ++ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_I2S_DAT_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_COMBO_I2S_DAT_PIN, GPIO_OUT_ZERO); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n"); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", state); ++ break; ++ } ++#else ++ WMT_PLAT_ERR_FUNC("[MT6620]Error:FM digital mode set, but no I2S GPIOs defined\n"); ++#endif ++#else ++ WMT_PLAT_INFO_FUNC ++ ("[MT6620]warnning:FM digital mode is not set, no I2S GPIO settings should be modified by combo driver\n"); ++#endif ++ ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ return 0; ++} ++ ++INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId) ++{ ++#ifdef CFG_WMT_WAKELOCK_SUPPORT ++ static INT32 counter; ++ INT32 status; ++ INT32 ret = 0; ++ ++ ret = mutex_lock_killable(&gOsSLock); ++ if (ret) { ++ WMT_PLAT_ERR_FUNC("--->lock gOsSLock failed, ret=%d\n", ret); ++ return ret; ++ } ++ ++ if (WL_OP_GET == opId) ++ ++counter; ++ else if (WL_OP_PUT == opId) ++ --counter; ++ ++ mutex_unlock(&gOsSLock); ++ if (WL_OP_GET == opId && counter == 1) { ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_stay_awake(&wmtWakeLock); ++ status = wmtWakeLock.active; ++ #else ++ wake_lock(&wmtWakeLock); ++ status = wake_lock_active(&wmtWakeLock); ++ #endif ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", status, counter); ++ ++ } else if (WL_OP_PUT == opId && counter == 0) { ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_relax(&wmtWakeLock); ++ status = wmtWakeLock.active; ++ #else ++ wake_unlock(&wmtWakeLock); ++ status = wake_lock_active(&wmtWakeLock); ++ #endif ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", status, counter); ++ } else { ++ #ifdef CONFIG_PM_WAKELOCKS ++ status = wmtWakeLock.active; ++ #else ++ status = wake_lock_active(&wmtWakeLock); ++ #endif ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", status, counter); ++ } ++ return 0; ++#else ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: host awake function is not supported.\n"); ++ return 0; ++ ++#endif ++} ++EXPORT_SYMBOL(wmt_plat_wake_lock_ctrl); ++ ++INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo) ++{ ++ INT32 iRet = 0; ++ ++ switch (ePt) { ++ ++ case BT_PALDO: ++ iRet = mtk_wcn_consys_hw_bt_paldo_ctrl(ePo); ++ break; ++ case WIFI_PALDO: ++ iRet = mtk_wcn_consys_hw_wifi_paldo_ctrl(ePo); ++ break; ++ case FM_PALDO: ++ case GPS_PALDO: ++ iRet = mtk_wcn_consys_hw_vcn28_ctrl(ePo); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid type(%d) in palod_ctrl\n", ePt); ++ break; ++ } ++ return iRet; ++} ++EXPORT_SYMBOL(wmt_plat_soc_paldo_ctrl); ++ ++UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset) ++{ ++ return mtk_wcn_consys_emi_virt_addr_get(offset); ++} ++EXPORT_SYMBOL(wmt_plat_get_emi_virt_add); ++ ++P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID) ++{ ++ return &mtk_wcn_emi_addr_info; ++} ++EXPORT_SYMBOL(wmt_plat_get_emi_phy_add); ++ ++#if CONSYS_ENALBE_SET_JTAG ++UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en) ++{ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_jtag_flag_ctrl); ++#endif ++ ++#if CFG_WMT_DUMP_INT_STATUS ++VOID wmt_plat_BGF_irq_dump_status(VOID) ++{ ++ WMT_PLAT_INFO_FUNC("this function is null in MT8127\n"); ++} ++EXPORT_SYMBOL(wmt_plat_BGF_irq_dump_status); ++ ++MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID) ++{ ++ return MTK_WCN_BOOL_FALSE; ++} ++EXPORT_SYMBOL(wmt_plat_dump_BGF_irq_status); ++#endif ++ ++UINT32 wmt_plat_read_cpupcr(void) ++{ ++ return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); ++} ++EXPORT_SYMBOL(wmt_plat_read_cpupcr); ++ ++UINT32 wmt_plat_read_dmaregs(UINT32 type) ++{ ++ return 0; ++#if 0 ++ switch (type) { ++ case CONNSYS_CLK_GATE_STATUS: ++ return CONSYS_REG_READ(CONNSYS_CLK_GATE_STATUS_REG); ++ case CONSYS_EMI_STATUS: ++ return CONSYS_REG_READ(CONSYS_EMI_STATUS_REG); ++ case SYSRAM1: ++ return CONSYS_REG_READ(SYSRAM1_REG); ++ case SYSRAM2: ++ return CONSYS_REG_READ(SYSRAM2_REG); ++ case SYSRAM3: ++ return CONSYS_REG_READ(SYSRAM3_REG); ++ default: ++ return 0; ++ } ++#endif ++} ++ ++INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_STATE); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ CONSYS_REG_WRITE(p_virtual_addr, state); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_set_host_dump_state); ++ ++UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ ++ switch (type) { ++ case STP_FORCE_TRG_ASSERT_EMI: ++ ++ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); ++ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); ++ break; ++ case STP_FORCE_TRG_ASSERT_DEBUG_PIN: ++ ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + ++ CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); ++ WMT_PLAT_INFO_FUNC("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); ++ usleep_range(64, 96); ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + ++ CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); ++ WMT_PLAT_INFO_FUNC("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); ++ ++ break; ++ default: ++ WMT_PLAT_ERR_FUNC("unknown force trigger assert type\n"); ++ break; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_force_trigger_assert); ++ ++INT32 wmt_plat_update_host_sync_num(VOID) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ UINT32 sync_num = 0; ++ ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_NUM); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ sync_num = CONSYS_REG_READ(p_virtual_addr); ++ CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_update_host_sync_num); ++ ++INT32 wmt_plat_get_dump_info(UINT32 offset) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ ++ p_virtual_addr = wmt_plat_get_emi_virt_add(offset); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ WMT_PLAT_INFO_FUNC("connsys_reg_read (0x%x), (0x%p), (0x%x)\n", CONSYS_REG_READ(p_virtual_addr), p_virtual_addr, ++ offset); ++ return CONSYS_REG_READ(p_virtual_addr); ++} ++EXPORT_SYMBOL(wmt_plat_get_dump_info); ++ ++UINT32 wmt_plat_get_soc_chipid(void) ++{ ++ UINT32 chipId = mtk_wcn_consys_soc_chipid(); ++ ++ WMT_PLAT_INFO_FUNC("current SOC chip:0x%x\n", chipId); ++ return chipId; ++} ++EXPORT_SYMBOL(wmt_plat_get_soc_chipid); ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++INT32 wmt_plat_get_tdm_antsel_index(VOID) ++{ ++ WMT_PLAT_INFO_FUNC("not support LTE in this platform\n"); ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_get_tdm_antsel_index); ++#endif ++INT32 wmt_plat_set_dbg_mode(UINT32 flag) ++{ ++ return -1; ++} ++VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf) ++{ ++ mtk_wcn_consys_set_dynamic_dump(buf); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/Makefile b/drivers/misc/mediatek/connectivity/wlan/Makefile +new file mode 100644 +index 000000000000..36ce26810912 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/Makefile +@@ -0,0 +1,8 @@ ++ifeq ($(CONFIG_MTK_COMBO_WIFI),y) ++ subdir-ccflags-y += -D MTK_WCN_BUILT_IN_DRIVER ++endif ++ ++ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++$(warning include gen2) ++ obj-y += gen2/ ++endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile +new file mode 100644 +index 000000000000..09e4d66436a0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile +@@ -0,0 +1,237 @@ ++# --------------------------------------------------- ++# Compile Options ++# --------------------------------------------------- ++ccflags-y += -DLINUX -DMT6628 ++ ++ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=1 ++ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1 ++ccflags-y += -DCFG_P2P_LEGACY_COEX_REVISE=1 ++ccflags-y += -DARP_MONITER_ENABLE=1 ++ ++ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) ++ ccflags-y += -DCFG_SUPPORT_WAPI=1 ++else ++ ccflags-y += -DCFG_SUPPORT_WAPI=0 ++endif ++ ++ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y) ++ ccflags-y += -DCFG_SUPPORT_MCC=1 ++else ++ ccflags-y += -DCFG_SUPPORT_MCC=0 ++endif ++ ++ifeq ($(CONFIG_HAVE_XLOG_FEATURE), y) ++ ccflags-y += -DCFG_SUPPORT_XLOG=1 ++else ++ ccflags-y += -DCFG_SUPPORT_XLOG=0 ++endif ++ ++ifeq ($(CONFIG_MTK_AEE_FEATURE), y) ++ ccflags-y += -DCFG_SUPPORT_AEE=1 ++else ++ ccflags-y += -DCFG_SUPPORT_AEE=0 ++endif ++ ++#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y) ++# ccflags-y += -D_HIF_SDIO=1 ++#endif ++ ++ifeq ($(CONFIG_MTK_PASSPOINT_R1_SUPPORT), y) ++ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=1 ++ ccflags-y += -DCFG_HS20_DEBUG=1 ++ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1 ++else ++ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=0 ++ ccflags-y += -DCFG_HS20_DEBUG=0 ++ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0 ++endif ++ ++MTK_MET_PROFILING_SUPPORT = no ++ifeq ($(MTK_MET_PROFILING_SUPPORT), yes) ++ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=1 ++else ++ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=0 ++endif ++ ++ifeq ($(CONFIG_MTK_TC1_FEATURE), y) ++ifeq ($(CONFIG_MTK_GPT_SCHEME_SUPPORT), y) ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/gpt ++else ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/pmt ++endif ++ ccflags-y += -DCFG_TC1_FEATURE=1 ++ ccflags-y += -DCFG_SUPPORT_CFG_FILE=1 ++else ++ ccflags-y += -DCFG_TC1_FEATURE=0 ++endif ++ ++MTK_SRAM_SIZE_OPTION=0 ++ifeq ($(CONFIG_ARCH_MT6755), y) ++ MTK_SRAM_SIZE_OPTION=2 ++endif ++ifeq ($(CONFIG_ARCH_MT6735), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT6735M), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT6753), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT6580), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT8163), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ccflags-y += -DCFG_SRAM_SIZE_OPTION=$(MTK_SRAM_SIZE_OPTION) ++ ++ifeq ($(strip $(TRUSTONIC_TEE_SUPPORT)),yes) ++ifeq ($(strip $(MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT)),yes) ++ ccflags-y += -DTRUSTONIC_TEE_SUPPORT ++ ccflags-y += -DMTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT ++endif ++endif ++ ++ccflags-y += -D_HIF_SDIO=1 ++ ++ccflags-y += -DDBG=0 ++ccflags-y += -I$(src)/os -I$(src)/os/linux/include -I$(src)/os/linux/hif/ahb/include ++ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt ++ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include ++ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/ ++ ++MODULE_NAME := wlan_gen2 ++obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o ++#obj-m += $(MODULE_NAME).o if CONFIG_MTK_COMBO_WIFI=m ==> obj-m means ko module, not build in obj-y ++ ++# --------------------------------------------------- ++# Directory List ++# --------------------------------------------------- ++COMMON_DIR := common/ ++OS_DIR := os/linux/ ++HIF_DIR := os/linux/hif/ahb/ ++NIC_DIR := nic/ ++MGMT_DIR := mgmt/ ++DMA_DIR := ../../../../platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/wifi/ ++PLAT_DIR := os/linux/plat/$(MTK_PLATFORM)/ ++HIF_AHB_PDMA := $(HIF_DIR)$(MTK_PLATFORM)/ ++#$(call lc,$(MTK_PLATFORM)) ++ ++ ++# --------------------------------------------------- ++# Objects List ++# --------------------------------------------------- ++ ++COMMON_OBJS := $(COMMON_DIR)dump.o \ ++ $(COMMON_DIR)wlan_lib.o \ ++ $(COMMON_DIR)wlan_oid.o \ ++ $(COMMON_DIR)wlan_bow.o \ ++ $(COMMON_DIR)debug.o ++ ++NIC_OBJS := $(NIC_DIR)nic.o \ ++ $(NIC_DIR)nic_tx.o \ ++ $(NIC_DIR)nic_rx.o \ ++ $(NIC_DIR)nic_pwr_mgt.o \ ++ $(NIC_DIR)cmd_buf.o \ ++ $(NIC_DIR)que_mgt.o \ ++ $(NIC_DIR)nic_cmd_event.o ++ ++OS_OBJS := $(OS_DIR)gl_init.o \ ++ $(OS_DIR)gl_kal.o \ ++ $(OS_DIR)gl_bow.o \ ++ $(OS_DIR)gl_wext.o \ ++ $(OS_DIR)gl_wext_priv.o \ ++ $(OS_DIR)gl_rst.o \ ++ $(OS_DIR)gl_cfg80211.o \ ++ $(OS_DIR)gl_vendor.o \ ++ $(OS_DIR)platform.o \ ++ $(OS_DIR)gl_proc.o ++ ++MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \ ++ $(MGMT_DIR)aaa_fsm.o \ ++ $(MGMT_DIR)assoc.o \ ++ $(MGMT_DIR)auth.o \ ++ $(MGMT_DIR)bss.o \ ++ $(MGMT_DIR)cnm.o \ ++ $(MGMT_DIR)cnm_timer.o \ ++ $(MGMT_DIR)cnm_mem.o \ ++ $(MGMT_DIR)hem_mbox.o \ ++ $(MGMT_DIR)mib.o \ ++ $(MGMT_DIR)privacy.o \ ++ $(MGMT_DIR)rate.o \ ++ $(MGMT_DIR)rlm.o \ ++ $(MGMT_DIR)rlm_domain.o \ ++ $(MGMT_DIR)rlm_obss.o \ ++ $(MGMT_DIR)rlm_protection.o \ ++ $(MGMT_DIR)rsn.o \ ++ $(MGMT_DIR)saa_fsm.o \ ++ $(MGMT_DIR)scan.o \ ++ $(MGMT_DIR)scan_fsm.o \ ++ $(MGMT_DIR)sec_fsm.o \ ++ $(MGMT_DIR)swcr.o \ ++ $(MGMT_DIR)swcr.o \ ++ $(MGMT_DIR)roaming_fsm.o \ ++ $(MGMT_DIR)hs20.o ++ ++# --------------------------------------------------- ++# TDLS Objects List ++# --------------------------------------------------- ++MGMT_OBJS += $(MGMT_DIR)tdls.o \ ++ $(MGMT_DIR)tdls_com.o ++ ++# --------------------------------------------------- ++# STATS Objects List ++# --------------------------------------------------- ++MGMT_OBJS += $(MGMT_DIR)stats.o ++ ++# --------------------------------------------------- ++# P2P Objects List ++# --------------------------------------------------- ++ ++COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o ++ ++NIC_OBJS += $(NIC_DIR)p2p_nic.o ++ ++OS_OBJS += $(OS_DIR)gl_p2p.o \ ++ $(OS_DIR)gl_p2p_cfg80211.o \ ++ $(OS_DIR)gl_p2p_init.o \ ++ $(OS_DIR)gl_p2p_kal.o ++ ++MGMT_OBJS += $(MGMT_DIR)p2p_assoc.o \ ++ $(MGMT_DIR)p2p_bss.o \ ++ $(MGMT_DIR)p2p_fsm.o \ ++ $(MGMT_DIR)p2p_func.o \ ++ $(MGMT_DIR)p2p_rlm.o \ ++ $(MGMT_DIR)p2p_rlm_obss.o \ ++ $(MGMT_DIR)p2p_scan.o \ ++ $(MGMT_DIR)p2p_ie.o \ ++ $(MGMT_DIR)p2p_state.o ++ ++ ++ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) ++MGMT_OBJS += $(MGMT_DIR)wapi.o ++endif ++ ++ifeq ($(WLAN_PROC), y) ++OS_OBJS += gl_proc.o ++endif ++ ++$(warning $(CONFIG_MACH_MT7623)) ++ ++ifeq ($(CONFIG_MACH_MT7623), y) ++HIF_AHB_PDMA = $(HIF_DIR)mt8127/ ++endif ++HIF_OBJS := $(HIF_DIR)arm.o \ ++ $(HIF_DIR)ahb.o \ ++ $(HIF_AHB_PDMA)ahb_pdma.o ++ifeq ($(CONFIG_ARCH_MT6755), y) ++PLAT_OBJS := $(PLAT_DIR)plat_priv.o ++$(MODULE_NAME)-objs += $(PLAT_OBJS) ++endif ++$(MODULE_NAME)-objs += $(COMMON_OBJS) ++$(MODULE_NAME)-objs += $(NIC_OBJS) ++$(MODULE_NAME)-objs += $(OS_OBJS) ++$(MODULE_NAME)-objs += $(HIF_OBJS) ++$(MODULE_NAME)-objs += $(MGMT_OBJS) ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c +new file mode 100644 +index 000000000000..e31e0b86d231 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c +@@ -0,0 +1,165 @@ ++#include "precomp.h" ++#include "gl_kal.h" ++ ++struct COMMAND { ++ UINT_8 ucCID; ++ BOOLEAN fgSetQuery; ++ BOOLEAN fgNeedResp; ++ UINT_8 ucCmdSeqNum; ++}; ++ ++struct SECURITY_FRAME { ++ UINT_16 u2EthType; ++ UINT_16 u2Reserved; ++}; ++ ++struct MGMT_FRAME { ++ UINT_16 u2FrameCtl; ++ UINT_16 u2DurationID; ++}; ++ ++struct TC_RES_RELEASE_ENTRY { ++ UINT_64 u8RelaseTime; ++ UINT_32 u4RelCID; ++ UINT_8 ucTc4RelCnt; ++ UINT_8 ucAvailableTc4; ++}; ++ ++struct CMD_TRACE_ENTRY { ++ UINT_64 u8TxTime; ++ COMMAND_TYPE eCmdType; ++ union { ++ struct COMMAND rCmd; ++ struct SECURITY_FRAME rSecFrame; ++ struct MGMT_FRAME rMgmtFrame; ++ } u; ++}; ++ ++#define TC_RELEASE_TRACE_BUF_MAX_NUM 100 ++#define TXED_CMD_TRACE_BUF_MAX_NUM 100 ++ ++static struct TC_RES_RELEASE_ENTRY *gprTcReleaseTraceBuffer; ++static struct CMD_TRACE_ENTRY *gprCmdTraceEntry; ++VOID wlanDebugInit(VOID) ++{ ++ /* debug for command/tc4 resource begin */ ++ gprTcReleaseTraceBuffer = ++ kalMemAlloc(TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY), PHY_MEM_TYPE); ++ kalMemZero(gprTcReleaseTraceBuffer, TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); ++ gprCmdTraceEntry = kalMemAlloc(TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY), PHY_MEM_TYPE); ++ kalMemZero(gprCmdTraceEntry, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); ++ /* debug for command/tc4 resource end */ ++} ++ ++VOID wlanDebugUninit(VOID) ++{ ++ /* debug for command/tc4 resource begin */ ++ kalMemFree(gprTcReleaseTraceBuffer, PHY_MEM_TYPE, ++ TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); ++ kalMemFree(gprCmdTraceEntry, PHY_MEM_TYPE, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); ++ /* debug for command/tc4 resource end */ ++} ++ ++VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd) ++{ ++ static UINT_16 u2CurEntry; ++ struct CMD_TRACE_ENTRY *prCurCmd = &gprCmdTraceEntry[u2CurEntry]; ++ ++ prCurCmd->u8TxTime = sched_clock(); ++ prCurCmd->eCmdType = prCmd->eCmdType; ++ if (prCmd->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ P_WLAN_MAC_MGMT_HEADER_T prMgmt = (P_WLAN_MAC_MGMT_HEADER_T)((P_MSDU_INFO_T)prCmd->prPacket)->prPacket; ++ ++ prCurCmd->u.rMgmtFrame.u2FrameCtl = prMgmt->u2FrameCtrl; ++ prCurCmd->u.rMgmtFrame.u2DurationID = prMgmt->u2Duration; ++ } else if (prCmd->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { ++ PUINT_8 pucPkt = (PUINT_8)((struct sk_buff *)prCmd->prPacket)->data; ++ ++ prCurCmd->u.rSecFrame.u2EthType = ++ (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); ++ } else { ++ prCurCmd->u.rCmd.ucCID = prCmd->ucCID; ++ prCurCmd->u.rCmd.ucCmdSeqNum = prCmd->ucCmdSeqNum; ++ prCurCmd->u.rCmd.fgNeedResp = prCmd->fgNeedResp; ++ prCurCmd->u.rCmd.fgSetQuery = prCmd->fgSetQuery; ++ } ++ u2CurEntry++; ++ if (u2CurEntry == TC_RELEASE_TRACE_BUF_MAX_NUM) ++ u2CurEntry = 0; ++} ++ ++VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable) ++{ ++ static UINT_16 u2CurEntry; ++ struct TC_RES_RELEASE_ENTRY *prCurBuf = &gprTcReleaseTraceBuffer[u2CurEntry]; ++ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &prCurBuf->u4RelCID); ++ prCurBuf->u8RelaseTime = sched_clock(); ++ prCurBuf->ucTc4RelCnt = aucTxRlsCnt[TC4_INDEX]; ++ prCurBuf->ucAvailableTc4 = ucAvailable; ++ u2CurEntry++; ++ if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM) ++ u2CurEntry = 0; ++} ++ ++VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen) ++{ ++ UINT_16 i = 0; ++ struct CMD_TRACE_ENTRY *prCmd = gprCmdTraceEntry; ++ struct TC_RES_RELEASE_ENTRY *prTcRel = gprTcReleaseTraceBuffer; ++ ++ if (pucBuf) { ++ int bufLen = 0; ++ ++ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/2; i++) { ++ bufLen = snprintf(pucBuf, maxLen, ++ "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", ++ i*2, prCmd[i*2].u8TxTime, prCmd[i*2].eCmdType, *(PUINT_32)(&prCmd[i*2].u.rCmd.ucCID), ++ i*2+1, prCmd[i*2+1].u8TxTime, prCmd[i*2+1].eCmdType, ++ *(PUINT_32)(&prCmd[i*2+1].u.rCmd.ucCID)); ++ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) ++ break; ++ pucBuf += bufLen; ++ maxLen -= bufLen; ++ } ++ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/2; i++) { ++ bufLen = snprintf(pucBuf, maxLen, ++ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d CID %08x\n", ++ i*2, prTcRel[i*2].u8RelaseTime, prTcRel[i*2].ucTc4RelCnt, prTcRel[i*2].ucAvailableTc4, ++ prTcRel[i*2].u4RelCID, ++ i*2+1, prTcRel[i*2+1].u8RelaseTime, prTcRel[i*2+1].ucTc4RelCnt, ++ prTcRel[i*2+1].ucAvailableTc4, prTcRel[i*2+1].u4RelCID); ++ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) ++ break; ++ pucBuf += bufLen; ++ maxLen -= bufLen; ++ } ++ return; ++ } ++ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/4; i++) { ++ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x; ", ++ i*4, prCmd[i*4].u8TxTime, prCmd[i*4].eCmdType, ++ *(PUINT_32)(&prCmd[i*4].u.rCmd.ucCID), ++ i*4+1, prCmd[i*4+1].u8TxTime, prCmd[i*4+1].eCmdType, ++ *(PUINT_32)(&prCmd[i*4+1].u.rCmd.ucCID)); ++ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", ++ i*4+2, prCmd[i*4+2].u8TxTime, prCmd[i*4+2].eCmdType, ++ *(PUINT_32)(&prCmd[i*4+2].u.rCmd.ucCID), ++ i*4+3, prCmd[i*4+3].u8TxTime, prCmd[i*4+3].eCmdType, ++ *(PUINT_32)(&prCmd[i*4+3].u.rCmd.ucCID)); ++ } ++ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/4; i++) { ++ LOG_FUNC( ++ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x;", ++ i*4, prTcRel[i*4].u8RelaseTime, prTcRel[i*4].ucTc4RelCnt, ++ prTcRel[i*4].ucAvailableTc4, prTcRel[i*4].u4RelCID, ++ i*4+1, prTcRel[i*4+1].u8RelaseTime, prTcRel[i*4+1].ucTc4RelCnt, ++ prTcRel[i*4+1].ucAvailableTc4, prTcRel[i*4+1].u4RelCID); ++ LOG_FUNC( ++ " %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x\n", ++ i*4+2, prTcRel[i*4+2].u8RelaseTime, prTcRel[i*4+2].ucTc4RelCnt, ++ prTcRel[i*4+2].ucAvailableTc4, prTcRel[i*4+2].u4RelCID, ++ i*4+3, prTcRel[i*4+3].u8RelaseTime, prTcRel[i*4+3].ucTc4RelCnt, ++ prTcRel[i*4+3].ucAvailableTc4, prTcRel[i*4+3].u4RelCID); ++ } ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c +new file mode 100644 +index 000000000000..486ba239f16a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c +@@ -0,0 +1,345 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/dump.c#1 ++*/ ++ ++/*! \file "dump.c" ++ \brief Provide memory dump function for debugging. ++ ++ Provide memory dump function for debugging. ++*/ ++ ++/* ++** Log: dump.c ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Using the new XLOG define for dum Memory. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Add dumpMemory8 at XLOG support. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 19:58:51 GMT mtk01426 ++** Init develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dump a segment of memory in bytes. ++* ++* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. ++* \param[in] u4Length Length of the memory to be dumped. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length) ++{ ++ ASSERT(pucStartAddr); ++ ++ LOG_FUNC("DUMP8 ADDRESS: %p, Length: %u\n", pucStartAddr, u4Length); ++ ++ while (u4Length > 0) { ++ if (u4Length >= 16) { ++ LOG_FUNC( ++ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], pucStartAddr[8], ++ pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], pucStartAddr[12], pucStartAddr[13], ++ pucStartAddr[14], pucStartAddr[15]); ++ u4Length -= 16; ++ pucStartAddr += 16; ++ } else { ++ switch (u4Length) { ++ case 1: ++ LOG_FUNC("(%p) %02x\n", pucStartAddr, pucStartAddr[0]); ++ break; ++ case 2: ++ LOG_FUNC("(%p) %02x %02x\n", pucStartAddr, pucStartAddr[0], pucStartAddr[1]); ++ break; ++ case 3: ++ LOG_FUNC("(%p) %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2]); ++ break; ++ case 4: ++ LOG_FUNC("(%p) %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3]); ++ break; ++ case 5: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4]); ++ break; ++ case 6: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5]); ++ break; ++ case 7: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6]); ++ break; ++ case 8: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7]); ++ break; ++ case 9: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8]); ++ break; ++ case 10: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9]); ++ break; ++ case 11: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10]); ++ break; ++ case 12: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11]); ++ break; ++ case 13: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], ++ pucStartAddr[12]); ++ break; ++ case 14: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], ++ pucStartAddr[12], pucStartAddr[13]); ++ break; ++ case 15: ++ LOG_FUNC( ++ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], ++ pucStartAddr[12], pucStartAddr[13], pucStartAddr[14]); ++ break; ++ /* ++ default: ++ break; ++ */ ++ } ++ u4Length = 0; ++ } ++ } ++ ++ LOG_FUNC("\n"); ++ ++} /* end of dumpMemory8() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dump a segment of memory in double words. ++* ++* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. ++* \param[in] u4Length Length of the memory to be dumped. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length) ++{ ++ PUINT_8 pucAddr; ++ ++ ASSERT(pu4StartAddr); ++ ++ LOG_FUNC("DUMP32 ADDRESS: %p, Length: %u\n", pu4StartAddr, u4Length); ++ ++ if (IS_NOT_ALIGN_4((ULONG) pu4StartAddr)) { ++ UINT_32 u4ProtrudeLen = sizeof(UINT_32) - ((ULONG) pu4StartAddr % 4); ++ ++ u4ProtrudeLen = ((u4Length < u4ProtrudeLen) ? u4Length : u4ProtrudeLen); ++ LOG_FUNC("pu4StartAddr is not at DW boundary.\n"); ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ ++ switch (u4ProtrudeLen) { ++ case 1: ++ LOG_FUNC("(%p) %02x------\n", pu4StartAddr, pucAddr[0]); ++ break; ++ case 2: ++ LOG_FUNC("(%p) %02x%02x----\n", pu4StartAddr, pucAddr[1], pucAddr[0]); ++ break; ++ case 3: ++ LOG_FUNC("(%p) %02x%02x%02x--\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ default: ++ break; ++ } ++ ++ u4Length -= u4ProtrudeLen; ++ pu4StartAddr = (PUINT_32) ((ULONG) pu4StartAddr + u4ProtrudeLen); ++ } ++ ++ while (u4Length > 0) { ++ if (u4Length >= 16) { ++ LOG_FUNC("(%p) %08x %08x %08x %08x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pu4StartAddr[3]); ++ pu4StartAddr += 4; ++ u4Length -= 16; ++ } else { ++ switch (u4Length) { ++ case 1: ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ LOG_FUNC("(%p) ------%02x\n", pu4StartAddr, pucAddr[0]); ++ break; ++ case 2: ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ LOG_FUNC("(%p) ----%02x%02x\n", pu4StartAddr, pucAddr[1], pucAddr[0]); ++ break; ++ case 3: ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ LOG_FUNC("(%p) --%02x%02x%02x\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 4: ++ LOG_FUNC("(%p) %08x\n", pu4StartAddr, pu4StartAddr[0]); ++ break; ++ case 5: ++ pucAddr = (PUINT_8) &pu4StartAddr[1]; ++ LOG_FUNC("(%p) %08x ------%02x\n", pu4StartAddr, pu4StartAddr[0], pucAddr[0]); ++ break; ++ case 6: ++ pucAddr = (PUINT_8) &pu4StartAddr[1]; ++ LOG_FUNC("(%p) %08x ----%02x%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pucAddr[1], pucAddr[0]); ++ break; ++ case 7: ++ pucAddr = (PUINT_8) &pu4StartAddr[1]; ++ LOG_FUNC("(%p) %08x --%02x%02x%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 8: ++ LOG_FUNC("(%p) %08x %08x\n", pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1]); ++ break; ++ case 9: ++ pucAddr = (PUINT_8) &pu4StartAddr[2]; ++ LOG_FUNC("(%p) %08x %08x ------%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[0]); ++ break; ++ case 10: ++ pucAddr = (PUINT_8) &pu4StartAddr[2]; ++ LOG_FUNC("(%p) %08x %08x ----%02x%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[1], pucAddr[0]); ++ break; ++ case 11: ++ pucAddr = (PUINT_8) &pu4StartAddr[2]; ++ LOG_FUNC("(%p) %08x %08x --%02x%02x%02x\n", ++ pu4StartAddr, ++ pu4StartAddr[0], pu4StartAddr[1], pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 12: ++ LOG_FUNC("(%p) %08x %08x %08x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2]); ++ break; ++ case 13: ++ pucAddr = (PUINT_8) &pu4StartAddr[3]; ++ LOG_FUNC("(%p) %08x %08x %08x ------%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[0]); ++ break; ++ case 14: ++ pucAddr = (PUINT_8) &pu4StartAddr[3]; ++ LOG_FUNC("(%p) %08x %08x %08x ----%02x%02x\n", ++ pu4StartAddr, ++ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 15: ++ pucAddr = (PUINT_8) &pu4StartAddr[3]; ++ LOG_FUNC("(%p) %08x %08x %08x --%02x%02x%02x\n", ++ pu4StartAddr, ++ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], ++ pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ /* ++ default: ++ break; ++ */ ++ } ++ u4Length = 0; ++ } ++ } ++ ++} /* end of dumpMemory32() */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c +new file mode 100644 +index 000000000000..21bd849827e1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c +@@ -0,0 +1,3442 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_bow.c#1 ++*/ ++ ++/*! \file wlan_bow.c ++ \brief This file contains the 802.11 PAL commands processing routines for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_bow.c ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW for 5GHz band. ++ * ++ * 01 09 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * [ALPS00110632] [Rose][LCA42][Cross Feature][Bluetooth]The "KE" pops up after the device reboots automatically.(once) ++ * ++ * Fix bow link disconnected event dereference. ++ * ++ * 09 29 2011 cm.chang ++ * NULL ++ * Change the function prototype of rlmDomainGetChnlList() ++ * ++ * 07 06 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Improve BoW connection establishment speed. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 21 2011 terry.wu ++ * NULL ++ * Fix BoW KE. ++ * ++ * 06 20 2011 terry.wu ++ * NULL ++ * Add BoW Rate Limitation. ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * Add BoW 11N support. ++ * ++ * 06 07 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * aware more compile options. ++ * ++ * 05 25 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW Cancel Scan Request and Turn On deactive network function. ++ * ++ * 05 23 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add some BoW error handling. ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * . ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Only reply probe response to its peer or mached SSID for BoW AP. ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW SAA retry and disable disconnect event when AAA fail . ++ * ++ * 05 21 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Protect BoW connection establishment. ++ * ++ * 05 17 2011 terry.wu ++ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting ++ * Send deauth while disconnecting BoW link. ++ * ++ * 05 17 2011 terry.wu ++ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue ++ * Fix wrong StaRec state of BoW . ++ * ++ * 05 06 2011 terry.wu ++ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue ++ * Fix BoW Multiple Physical Link connect/disconnect issue. ++ * ++ * 05 03 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix prAssocRspSwRfb casting. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 12 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add WMM IE for BOW initiator data. ++ * ++ * 04 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. ++ * ++ * 04 09 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link connection event procedure and change skb length check to 1512 bytes. ++ * ++ * 03 28 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Simplify link disconnected routine, remove link disconnected other routine. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add new feature - multiple physical link support. ++ * ++ * 02 22 2011 wh.su ++ * [WCXRP00000486] [MT6620 Wi-Fi][BOW] Fixed the bow send frame but not encrypted issue ++ * fixed the BOW packet sending without encrypted issue. ++ * ++ * 02 21 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix BOW link disconnection bug. ++ * ++ * 02 16 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting. ++ * ++ * 02 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW channel granted function. ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 ++ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 ++ * with BOW and P2P enabled as default ++ * ++ * 02 08 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. ++ * Update BOW get MAC status, remove returning event for AIS network type. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW Activity Report structure and bug fix. ++ * ++ * 01 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW to support multiple physical link. ++ * ++ * 12 08 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support concurrent networks. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 11 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix BoW timer assert issue. ++ * ++ * 10 18 2010 chinghwa.yu ++ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size ++ * Fix for event returnning Band. ++ * ++ * 10 18 2010 chinghwa.yu ++ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size ++ * Fix wrong BoW event size. ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced ++ * by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 16 2010 chinghwa.yu ++ * NULL ++ * Fix bowResponderScanDone error when prBssDesc is NULL. ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Add bowRunEventAAAComplete. ++ * ++ * 09 14 2010 cp.wu ++ * NULL ++ * indicate correct AIS network information for PAL. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Initialize nicActivateNetwork(prAdapter as soon as bow is starting.. ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add NULL OID implementation for WOL-related OIDs. ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * 1) all BT physical handles shares the same RSSI/Link Quality. ++ * 2) simplify BT command composing ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * 2) command sequence number is now increased atomically ++ * * 3) private data could be hold and taken use for other purpose ++** ++*/ ++ ++/****************************************************************************** ++* C O M P I L E R F L A G S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************* ++*/ ++#include "precomp.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++/****************************************************************************** ++* C O N S T A N T S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* D A T A T Y P E S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P U B L I C D A T A ++******************************************************************************* ++*/ ++ ++static UINT_32 g_u4LinkCount; ++static UINT_32 g_u4Beaconing; ++static BOW_TABLE_T arBowTable[CFG_BOW_PHYSICAL_LINK_NUM]; ++ ++/****************************************************************************** ++* P R I V A T E D A T A ++******************************************************************************* ++*/ ++ ++const BOW_CMD_T arBowCmdTable[] = { ++ {BOW_CMD_ID_GET_MAC_STATUS, bowCmdGetMacStatus}, ++ {BOW_CMD_ID_SETUP_CONNECTION, bowCmdSetupConnection}, ++ {BOW_CMD_ID_DESTROY_CONNECTION, bowCmdDestroyConnection}, ++ {BOW_CMD_ID_SET_PTK, bowCmdSetPTK}, ++ {BOW_CMD_ID_READ_RSSI, bowCmdReadRSSI}, ++ {BOW_CMD_ID_READ_LINK_QUALITY, bowCmdReadLinkQuality}, ++ {BOW_CMD_ID_SHORT_RANGE_MODE, bowCmdShortRangeMode}, ++ {BOW_CMD_ID_GET_CHANNEL_LIST, bowCmdGetChannelList}, ++}; ++ ++/****************************************************************************** ++* M A C R O S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N S ++******************************************************************************* ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command packet generation utility ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucCID Command ID ++* \param[in] fgSetQuery Set or Query ++* \param[in] fgNeedResp Need for response ++* \param[in] pfCmdDoneHandler Function pointer when command is done ++* \param[in] u4SetQueryInfoLen The length of the set/query buffer ++* \param[in] pucInfoBuffer Pointer to set/query buffer ++* ++* ++* \retval WLAN_STATUS_PENDING ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucCID, ++ IN BOOLEAN fgSetQuery, ++ IN BOOLEAN fgNeedResp, ++ IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ IN UINT_32 u4SetQueryInfoLen, IN PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); ++ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_BOW_INDEX; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); ++ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; ++ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = ucCID; ++ prCmdInfo->fgSetQuery = fgSetQuery; ++ prCmdInfo->fgNeedResp = fgNeedResp; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; ++ prCmdInfo->pvInformationBuffer = NULL; ++ prCmdInfo->u4InformationBufferLength = 0; ++ prCmdInfo->u4PrivateData = (UINT_32) ucSeqNumber; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) ++ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dispatch command coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ WLAN_STATUS retval = WLAN_STATUS_FAILURE; ++ UINT_16 i; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < sizeof(arBowCmdTable) / sizeof(BOW_CMD_T); i++) { ++ if ((arBowCmdTable[i].uCmdID == prCmd->rHeader.ucCommandId) && arBowCmdTable[i].pfCmdHandle) { ++ retval = arBowCmdTable[i].pfCmdHandle(prAdapter, prCmd); ++ break; ++ } ++ } ++ ++ return retval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_GET_MAC_STATUS ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_MAC_STATUS prMacStatus; ++ UINT_8 idx = 0; ++ UINT_8 ucPrimaryChannel; ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eBssSCO; ++ UINT_8 ucNumOfChannel = 0; /* MAX_BOW_NUMBER_OF_CHANNEL; */ ++ ++ RF_CHANNEL_INFO_T aucChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; ++ ++ ASSERT(prAdapter); ++ ++ /* 3 <1> If LinkCount != 0 -> OK (optional) */ ++ ++ eBand = BAND_2G4; ++ eBssSCO = CHNL_EXT_SCN; ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return WLAN_STATUS_FAILURE; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_MAC_STATUS; ++ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_MAC_STATUS); ++ ++ /* fill event body */ ++ prMacStatus = (P_BOW_MAC_STATUS) (prEvent->aucPayload); ++ kalMemZero(prMacStatus, sizeof(BOW_MAC_STATUS)); ++ ++ /* 3 <2> Call CNM to decide if BOW available. */ ++ if (cnmBowIsPermitted(prAdapter)) ++ prMacStatus->ucAvailability = TRUE; ++ else ++ prMacStatus->ucAvailability = FALSE; ++ ++ memcpy(prMacStatus->aucMacAddr, prAdapter->rWifiVar.aucDeviceAddress, PARAM_MAC_ADDR_LEN); ++ ++ if (cnmPreferredChannel(prAdapter, &eBand, &ucPrimaryChannel, &eBssSCO)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "bowCmdGetMacStatus, Get preferred channel.\n"); ++#endif ++ ++ prMacStatus->ucNumOfChannel = 1; ++ prMacStatus->arChannelList[0].ucChannelBand = eBand; ++ prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel; ++ } else { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, ++ "bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel); ++#endif ++ ++ rlmDomainGetChnlList(prAdapter, BAND_2G4, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_2G4, ++ &ucNumOfChannel, aucChannelList); ++ ++ if (ucNumOfChannel > 0) { ++ for (idx = 0; idx < ucNumOfChannel; idx++) { ++ prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand; ++ prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum; ++ } ++ ++ prMacStatus->ucNumOfChannel = ucNumOfChannel; ++ } ++ ++ rlmDomainGetChnlList(prAdapter, BAND_5G, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_5G, ++ &ucNumOfChannel, aucChannelList); ++ ++ if (ucNumOfChannel > 0) { ++ for (idx = 0; idx < ucNumOfChannel; idx++) { ++ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelBand = ++ aucChannelList[idx].eBand; ++ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelNum = ++ aucChannelList[idx].ucChannelNum; ++ } ++ ++ prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel; ++ ++ } ++ } ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, ++ "ucNumOfChannel,eBand,aucChannelList,%x,%x,%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ ucNumOfChannel, aucChannelList[0].eBand, aucChannelList[0].ucChannelNum, aucChannelList[1].ucChannelNum, ++ aucChannelList[2].ucChannelNum, aucChannelList[3].ucChannelNum, aucChannelList[4].ucChannelNum, ++ aucChannelList[5].ucChannelNum, aucChannelList[6].ucChannelNum, aucChannelList[7].ucChannelNum, ++ aucChannelList[8].ucChannelNum, aucChannelList[9].ucChannelNum, aucChannelList[10].ucChannelNum, ++ aucChannelList[11].ucChannelNum, aucChannelList[12].ucChannelNum, aucChannelList[13].ucChannelNum, ++ aucChannelList[14].ucChannelNum, aucChannelList[15].ucChannelNum, aucChannelList[16].ucChannelNum, ++ aucChannelList[17].ucChannelNum)); ++ ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->ucNumOfChannel, eBand, %x, %x.\n", ++ prMacStatus->ucNumOfChannel, prMacStatus->arChannelList[0].ucChannelBand); ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->arChannelList, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ prMacStatus->arChannelList[0].ucChannelNum, prMacStatus->arChannelList[1].ucChannelNum, ++ prMacStatus->arChannelList[2].ucChannelNum, prMacStatus->arChannelList[3].ucChannelNum, ++ prMacStatus->arChannelList[4].ucChannelNum, prMacStatus->arChannelList[5].ucChannelNum, ++ prMacStatus->arChannelList[6].ucChannelNum, prMacStatus->arChannelList[7].ucChannelNum, ++ prMacStatus->arChannelList[8].ucChannelNum, prMacStatus->arChannelList[9].ucChannelNum, ++ prMacStatus->arChannelList[10].ucChannelNum, prMacStatus->arChannelList[11].ucChannelNum, ++ prMacStatus->arChannelList[12].ucChannelNum, prMacStatus->arChannelList[13].ucChannelNum, ++ prMacStatus->arChannelList[14].ucChannelNum, prMacStatus->arChannelList[15].ucChannelNum, ++ prMacStatus->arChannelList[16].ucChannelNum, prMacStatus->arChannelList[17].ucChannelNum)); ++ ++ DBGLOG(BOW, TRACE, "prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel); ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand); ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum); ++ DBGLOG(BOW, TRACE, "prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability); ++ DBGLOG(BOW, TRACE, "prMacStatus->aucMacAddr, %x:%x:%x:%x:%x:%x.\n", ++ prMacStatus->aucMacAddr[0], ++ prMacStatus->aucMacAddr[1], ++ prMacStatus->aucMacAddr[2], ++ prMacStatus->aucMacAddr[3], prMacStatus->aucMacAddr[4], prMacStatus->aucMacAddr[5])); ++#endif ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS))); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_SETUP_CONNECTION ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_SETUP_CONNECTION prBowSetupConnection; ++ CMD_BT_OVER_WIFI rCmdBtOverWifi; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ BOW_TABLE_T rBowTable; ++ ++ UINT_8 ucBowTableIdx = 0; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBowSetupConnection = (P_BOW_SETUP_CONNECTION) &(prCmd->aucPayload[0]); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SETUP_CONNECTION)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ /* 3 <1> If ucLinkCount >= 4 -> Fail. */ ++ if (g_u4LinkCount >= CFG_BOW_PHYSICAL_LINK_NUM) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* 3 <2> Call CNM, check if BOW is available. */ ++ if (!cnmBowIsPermitted(prAdapter)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* 3 <3> Lookup BOW Table, if Peer MAC address exist and valid -> Fail. */ ++ if (bowCheckBowTableIfVaild(prAdapter, prBowSetupConnection->aucPeerAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (EQUAL_MAC_ADDR(prBowSetupConnection->aucPeerAddress, prAdapter->rWifiVar.aucDeviceAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* fill CMD_BT_OVER_WIFI */ ++ rCmdBtOverWifi.ucAction = BOW_SETUP_CMD; ++ rCmdBtOverWifi.ucChannelNum = prBowSetupConnection->ucChannelNum; ++ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowSetupConnection->aucPeerAddress); ++ rCmdBtOverWifi.u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; ++ rCmdBtOverWifi.ucTimeoutDiscovery = prBowSetupConnection->ucTimeoutDiscovery; ++ rCmdBtOverWifi.ucTimeoutInactivity = prBowSetupConnection->ucTimeoutInactivity; ++ rCmdBtOverWifi.ucRole = prBowSetupConnection->ucRole; ++ rCmdBtOverWifi.PAL_Capabilities = prBowSetupConnection->ucPAL_Capabilities; ++ rCmdBtOverWifi.cMaxTxPower = prBowSetupConnection->cMaxTxPower; ++ ++ if (prBowSetupConnection->ucChannelNum > 14) ++ rCmdBtOverWifi.ucChannelBand = BAND_5G; ++ else ++ rCmdBtOverWifi.ucChannelBand = BAND_2G4; ++ ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowSetupConnection->aucPeerAddress); ++ ++#if CFG_BOW_PHYSICAL_LINK_NUM > 1 ++ /*Channel check for supporting multiple physical link */ ++ if (g_u4LinkCount > 0) { ++ if (prBowSetupConnection->ucChannelNum != prBowFsmInfo->ucPrimaryChannel) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ } ++#endif ++ ++ prBowFsmInfo->ucPrimaryChannel = prBowSetupConnection->ucChannelNum; ++ prBowFsmInfo->eBand = rCmdBtOverWifi.ucChannelBand; ++ prBowFsmInfo->u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; ++ prBowFsmInfo->ucRole = prBowSetupConnection->ucRole; ++ ++ if (prBowSetupConnection->ucPAL_Capabilities > 0) ++ prBowFsmInfo->fgSupportQoS = TRUE; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdSetupConnection.\n"); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Peer address - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], ++ rCmdBtOverWifi.rPeerAddr[1], ++ rCmdBtOverWifi.rPeerAddr[2], ++ rCmdBtOverWifi.rPeerAddr[3], rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower); ++#endif ++ ++ /* 3 <4> Get a free BOW entry, mark as Valid, fill in Peer MAC address, LinkCount += 1, state == Starting. */ ++ if (!bowGetBowTableFreeEntry(prAdapter, &ucBowTableIdx)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ prBowFsmInfo->prTargetBssDesc = NULL; ++ ++ kalMemZero(&rBowTable, sizeof(BOW_TABLE_T)); ++ ++ COPY_MAC_ADDR(rBowTable.aucPeerAddress, prBowSetupConnection->aucPeerAddress); ++ /* owTable.eState = BOW_DEVICE_STATE_ACQUIRING_CHANNEL; */ ++ rBowTable.fgIsValid = TRUE; ++ rBowTable.ucAcquireID = prBowFsmInfo->ucSeqNumOfChReq; ++ /* rBowTable.ucRole = prBowSetupConnection->ucRole; */ ++ /* rBowTable.ucChannelNum = prBowSetupConnection->ucChannelNum; */ ++ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); ++ ++ kalSetBowRole(prAdapter->prGlueInfo, rCmdBtOverWifi.ucRole, prBowSetupConnection->aucPeerAddress); ++ ++ GLUE_INC_REF_CNT(g_u4LinkCount); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ if (g_u4LinkCount == 1) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStarting, cnmTimerInitTimer.\n"); ++ DBGLOG(BOW, EVENT, "prBowFsmInfo->u2BeaconInterval, %d.\n", prBowFsmInfo->u2BeaconInterval); ++#endif ++ cnmTimerInitTimer(prAdapter, ++ &prBowFsmInfo->rStartingBeaconTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) bowSendBeacon, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prBowFsmInfo->rChGrantedTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) bowChGrantedTimeout, (ULONG) NULL); ++ ++ /* Reset Global Variable */ ++ g_u4Beaconing = 0; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdSetupConnection, g_u4LinkCount, %x.\n", g_u4LinkCount); ++ DBGLOG(BOW, EVENT, "kalInitBowDevice, bow0\n"); ++#endif ++#if CFG_BOW_SEPARATE_DATA_PATH ++ kalInitBowDevice(prAdapter->prGlueInfo, BOWDEVNAME); ++#endif ++ ++ /*Active BoW Network */ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ } ++ ++ if (rCmdBtOverWifi.ucRole == BOW_INITIATOR) { ++ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, ++ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); ++ bowRequestCh(prAdapter); ++ } else { ++ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); ++ bowResponderScan(prAdapter); ++ } ++ ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_DESTROY_CONNECTION ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_DESTROY_CONNECTION prBowDestroyConnection; ++ CMD_BT_OVER_WIFI rCmdBtOverWifi; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++#if CFG_BOW_TEST ++ UINT_8 ucIdx; ++#endif ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /* 3 <1> If LinkCount == 0 ->Fail (Optional) */ ++ if (g_u4LinkCount == 0) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_DESTROY_CONNECTION)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ /* 3 <2> Lookup BOW table, check if is not exist (Valid and Peer MAC address) -> Fail */ ++ prBowDestroyConnection = (P_BOW_DESTROY_CONNECTION) &(prCmd->aucPayload[0]); ++ ++ if (!bowCheckBowTableIfVaild(prAdapter, prBowDestroyConnection->aucPeerAddress)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdDestroyConnection, bowCheckIfVaild, not accepted.\n"); ++#endif ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowCmdDestroyConnection, destroy Peer address - %x:%x:%x:%x:%x:%x.\n", ++ prBowDestroyConnection->aucPeerAddress[0], prBowDestroyConnection->aucPeerAddress[1], ++ prBowDestroyConnection->aucPeerAddress[2], prBowDestroyConnection->aucPeerAddress[3], ++ prBowDestroyConnection->aucPeerAddress[4], prBowDestroyConnection->aucPeerAddress[5])); ++#endif ++ ++ /* fill CMD_BT_OVER_WIFI */ ++ rCmdBtOverWifi.ucAction = 2; ++ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowDestroyConnection->aucPeerAddress); ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowDestroyConnection->aucPeerAddress); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowCmdDestroyConnection, rCmdBtOverWifi.rPeerAddr - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], ++ rCmdBtOverWifi.rPeerAddr[1], rCmdBtOverWifi.rPeerAddr[2], rCmdBtOverWifi.rPeerAddr[3], ++ rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); ++#endif ++ ++#if CFG_BOW_TEST ++ for (ucIdx = 0; ucIdx < 11; ucIdx++) { ++ DBGLOG(BOW, EVENT, ++ "BoW receiving PAL packet delta time vs packet number -- %d ms vs %x.\n", ucIdx, ++ g_arBowRevPalPacketTime[ucIdx]); ++ } ++#endif ++ ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, ++ sizeof(CMD_BT_OVER_WIFI), ++ (PUINT_8)&rCmdBtOverWifi, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_SET_PTK ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_SET_PTK prBowSetPTK; ++ CMD_802_11_KEY rCmdKey; ++ ++ ASSERT(prAdapter); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SET_PTK)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prBowSetPTK = (P_BOW_SET_PTK) &(prCmd->aucPayload[0]); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prBowSetPTK->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowSetPTK->aucPeerAddress[0], ++ prBowSetPTK->aucPeerAddress[1], ++ prBowSetPTK->aucPeerAddress[2], ++ prBowSetPTK->aucPeerAddress[3], ++ prBowSetPTK->aucPeerAddress[4], prBowSetPTK->aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "rCmdKey.ucIsAuthenticator, %x.\n", kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress)); ++#endif ++ ++ if (!bowCheckBowTableIfVaild(prAdapter, prBowSetPTK->aucPeerAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (bowGetBowTableState(prAdapter, prBowSetPTK->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); ++ ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* fill CMD_802_11_KEY */ ++ rCmdKey.ucAddRemove = 1; /* add */ ++ rCmdKey.ucTxKey = 1; ++ rCmdKey.ucKeyType = 1; ++ rCmdKey.ucIsAuthenticator = kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress); ++ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prBowSetPTK->aucPeerAddress); ++ rCmdKey.ucNetType = NETWORK_TYPE_BOW_INDEX; /* BT Over Wi-Fi */ ++ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ ++ rCmdKey.ucKeyId = 0; ++ rCmdKey.ucKeyLen = 16; /* AES = 128bit */ ++ kalMemCopy(rCmdKey.aucKeyMaterial, prBowSetPTK->aucTemporalKey, 16); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prBowSetPTK->aucTemporalKey, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ prBowSetPTK->aucTemporalKey[0], ++ prBowSetPTK->aucTemporalKey[1], ++ prBowSetPTK->aucTemporalKey[2], ++ prBowSetPTK->aucTemporalKey[3], ++ prBowSetPTK->aucTemporalKey[4], ++ prBowSetPTK->aucTemporalKey[5], ++ prBowSetPTK->aucTemporalKey[6], ++ prBowSetPTK->aucTemporalKey[7], ++ prBowSetPTK->aucTemporalKey[8], ++ prBowSetPTK->aucTemporalKey[9], ++ prBowSetPTK->aucTemporalKey[10], ++ prBowSetPTK->aucTemporalKey[11], ++ prBowSetPTK->aucTemporalKey[12], ++ prBowSetPTK->aucTemporalKey[13], ++ prBowSetPTK->aucTemporalKey[14], prBowSetPTK->aucTemporalKey[15])); ++ ++ DBGLOG(BOW, EVENT, "rCmdKey.aucKeyMaterial, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ rCmdKey.aucKeyMaterial[0], ++ rCmdKey.aucKeyMaterial[1], ++ rCmdKey.aucKeyMaterial[2], ++ rCmdKey.aucKeyMaterial[3], ++ rCmdKey.aucKeyMaterial[4], ++ rCmdKey.aucKeyMaterial[5], ++ rCmdKey.aucKeyMaterial[6], ++ rCmdKey.aucKeyMaterial[7], ++ rCmdKey.aucKeyMaterial[8], ++ rCmdKey.aucKeyMaterial[9], ++ rCmdKey.aucKeyMaterial[10], ++ rCmdKey.aucKeyMaterial[11], ++ rCmdKey.aucKeyMaterial[12], ++ rCmdKey.aucKeyMaterial[13], rCmdKey.aucKeyMaterial[14], rCmdKey.aucKeyMaterial[15])); ++#endif ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_ADD_REMOVE_KEY, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventSetCommon, ++ wlanbowCmdTimeoutHandler, ++ sizeof(CMD_802_11_KEY), (PUINT_8)&rCmdKey, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_READ_RSSI ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_READ_RSSI prBowReadRSSI; ++ ++ ASSERT(prAdapter); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_READ_RSSI)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prBowReadRSSI = (P_BOW_READ_RSSI) &(prCmd->aucPayload[0]); ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ wlanbowCmdEventReadRssi, ++ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_READ_LINK_QUALITY ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_READ_LINK_QUALITY prBowReadLinkQuality; ++ ++ ASSERT(prAdapter); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(P_BOW_READ_LINK_QUALITY)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prBowReadLinkQuality = (P_BOW_READ_LINK_QUALITY) &(prCmd->aucPayload[0]); ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ wlanbowCmdEventReadLinkQuality, ++ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_SHORT_RANGE_MODE ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_SHORT_RANGE_MODE prBowShortRangeMode; ++ CMD_TX_PWR_T rTxPwrParam; ++ ++ ASSERT(prAdapter); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode.\n"); ++#endif ++ ++ prBowShortRangeMode = (P_BOW_SHORT_RANGE_MODE) &(prCmd->aucPayload[0]); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SHORT_RANGE_MODE)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (!bowCheckBowTableIfVaild(prAdapter, prBowShortRangeMode->aucPeerAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (bowGetBowTableState(prAdapter, prBowShortRangeMode->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prBowShortRangeMode->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowShortRangeMode->aucPeerAddress[0], ++ prBowShortRangeMode->aucPeerAddress[1], ++ prBowShortRangeMode->aucPeerAddress[2], ++ prBowShortRangeMode->aucPeerAddress[3], ++ prBowShortRangeMode->aucPeerAddress[4], prBowShortRangeMode->aucPeerAddress[5])); ++#endif ++ ++ rTxPwrParam.cTxPwr2G4Cck = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4OFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4OFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4OFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4OFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4OFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4HT20_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4HT40_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr5GOFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr5GHT20_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ ++ if (nicUpdateTxPower(prAdapter, &rTxPwrParam) == WLAN_STATUS_SUCCESS) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode, %x.\n", WLAN_STATUS_SUCCESS); ++#endif ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); ++ return WLAN_STATUS_SUCCESS; ++ } ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_GET_CHANNEL_LIST ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ ASSERT(prAdapter); ++ ++ /* not supported yet */ ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is generic command done handler ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ ++ ASSERT(prAdapter); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ ++ prBowCmdStatus->ucStatus = ucEventBuf; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is generic command done handler ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ ++ ASSERT(prAdapter); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ ++ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_LINK_CONNECTED prBowLinkConnected; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); ++ ++ /* fill event body */ ++ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prEvent->aucPayload); ++ kalMemZero(prBowLinkConnected, sizeof(BOW_LINK_CONNECTED)); ++ prBowLinkConnected->rChannel.ucChannelNum = prBssInfo->ucPrimaryChannel; ++ prBowLinkConnected->rChannel.ucChannelBand = prBssInfo->eBand; ++ COPY_MAC_ADDR(prBowLinkConnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); ++ DBGLOG(BOW, EVENT, ++ "prBowLinkConnected->rChannel.ucChannelNum, 0x%x\n", prBowLinkConnected->rChannel.ucChannelNum); ++ DBGLOG(BOW, EVENT, ++ "prBowLinkConnected->rChannel.ucChannelBand, 0x%x\n", prBowLinkConnected->rChannel.ucChannelBand); ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkConnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkConnected, prBowLinkConnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowLinkConnected->aucPeerAddress[0], prBowLinkConnected->aucPeerAddress[1], ++ prBowLinkConnected->aucPeerAddress[2], prBowLinkConnected->aucPeerAddress[3], ++ prBowLinkConnected->aucPeerAddress[4], prBowLinkConnected->aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkConnected, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ /*Indicate Event to PAL */ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED))); ++ ++ /*Release channel if granted */ ++ if (prBowFsmInfo->fgIsChannelGranted) { ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); ++ /* bowReleaseCh(prAdapter); */ ++ /*Requested, not granted yet */ ++ } else if (prBowFsmInfo->fgIsChannelRequested) { ++ prBowFsmInfo->fgIsChannelRequested = FALSE; ++ } ++ ++ /* set to connected status */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTED); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ BOW_TABLE_T rBowTable; ++ UINT_8 ucBowTableIdx; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ BOOLEAN fgSendDeauth = FALSE; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { ++ /*do nothing */ ++ return; ++ } ++ /*Cancel scan */ ++ else if (eFsmState == BOW_DEVICE_STATE_SCANNING && !(prBowFsmInfo->fgIsChannelRequested)) { ++ bowResponderCancelScan(prAdapter, FALSE); ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_DISCONNECTING); ++ return; ++ } ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; ++ if ((prCmdInfo->u4PrivateData)) ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ else ++ prEvent->rHeader.ucSeqNumber = 0; ++ ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); ++ ++ /* fill event body */ ++ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prEvent->aucPayload); ++ kalMemZero(prBowLinkDisconnected, sizeof(BOW_LINK_DISCONNECTED)); ++ prBowLinkDisconnected->ucReason = 0x0; ++ COPY_MAC_ADDR(prBowLinkDisconnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); ++ ++ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkDisconnected, prBowLinkDisconnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowLinkDisconnected->aucPeerAddress[0], prBowLinkDisconnected->aucPeerAddress[1], ++ prBowLinkDisconnected->aucPeerAddress[2], prBowLinkDisconnected->aucPeerAddress[3], ++ prBowLinkDisconnected->aucPeerAddress[4], prBowLinkDisconnected->aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ /*Indicate BoW event to PAL */ ++#if 0 ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); ++#endif ++ ++ /* set to disconnected status */ ++ prBowFsmInfo->prTargetStaRec = ++ cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_BOW_INDEX, prBowLinkDisconnected->aucPeerAddress); ++ if (!(prBowFsmInfo->prTargetStaRec)) { ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); ++ ASSERT(FALSE); ++ return; ++ } ++ ++ /*Release channel if granted */ ++ if (prBowFsmInfo->fgIsChannelGranted) { ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); ++ bowReleaseCh(prAdapter); ++ /*Requested, not granted yet */ ++ } else if (prBowFsmInfo->fgIsChannelRequested) { ++ prBowFsmInfo->fgIsChannelRequested = FALSE; ++ /* bowReleaseCh(prAdapter); */ ++ } ++#if 1 ++ /*Send Deauth to connected peer */ ++ if (eFsmState == BOW_DEVICE_STATE_CONNECTED && (prBowFsmInfo->prTargetStaRec->ucStaState == STA_STATE_3)) { ++ fgSendDeauth = TRUE; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkDisconnected, bowGetBowTableState, %x.\n", ++ bowGetBowTableState(prAdapter, prBowLinkDisconnected->aucPeerAddress)); ++#endif ++ authSendDeauthFrame(prAdapter, ++ prBowFsmInfo->prTargetStaRec, ++ (P_SW_RFB_T) NULL, ++ REASON_CODE_DEAUTH_LEAVING_BSS, (PFN_TX_DONE_HANDLER) bowDisconnectLink); ++ } ++#endif ++ ++#if 0 ++ /* 3 <3>Stop this link; flush Tx; ++ * send deAuthentication -> abort. SAA, AAA. need to check BOW table state == Connected. ++ */ ++ if (prAdapter->prGlueInfo->i4TxPendingFrameNum > 0) ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* flush pending security frames */ ++ if (prAdapter->prGlueInfo->i4TxPendingSecurityFrameNum > 0) ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++#endif ++ ++ /*Update BoW table */ ++ bowGetBowTableEntryByPeerAddress(prAdapter, prBowLinkDisconnected->aucPeerAddress, &ucBowTableIdx); ++ rBowTable.fgIsValid = FALSE; ++ rBowTable.eState = BOW_DEVICE_STATE_DISCONNECTED; ++ kalMemZero(rBowTable.aucPeerAddress, sizeof(rBowTable.aucPeerAddress)); ++ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); ++ ++ /*Indicate BoW event to PAL */ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); ++ ++ /*Decrease link count */ ++ GLUE_DEC_REF_CNT(g_u4LinkCount); ++ ++ /*If no need to send deauth, DO disconnect now */ ++ /*If need to send deauth, DO disconnect at deauth Tx done */ ++ if (!fgSendDeauth) ++ bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_BT_OVER_WIFI prCmdBtOverWifi; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /* restore original command for rPeerAddr */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prCmdBtOverWifi = (P_CMD_BT_OVER_WIFI) (prWifiCmd->aucBuffer); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; ++ ++ /*Indicate BoW event to PAL */ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++ ++ /* set to starting status */ ++ kalSetBowState(prAdapter->prGlueInfo, BOW_DEVICE_STATE_STARTING, prCmdBtOverWifi->rPeerAddr); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is the command done handler for BOW_CMD_ID_READ_LINK_QUALITY ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_AMPC_EVENT prEvent; ++ P_BOW_LINK_QUALITY prBowLinkQuality; ++ ++ ASSERT(prAdapter); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_QUALITY; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_QUALITY); ++ ++ /* fill event body */ ++ prBowLinkQuality = (P_BOW_LINK_QUALITY) (prEvent->aucPayload); ++ kalMemZero(prBowLinkQuality, sizeof(BOW_LINK_QUALITY)); ++ prBowLinkQuality->ucLinkQuality = (UINT_8) prLinkQuality->cLinkQuality; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is the command done handler for BOW_CMD_ID_READ_RSSI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_AMPC_EVENT prEvent; ++ P_BOW_RSSI prBowRssi; ++ ++ ASSERT(prAdapter); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_RSSI; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_RSSI); ++ ++ /* fill event body */ ++ prBowRssi = (P_BOW_RSSI) (prEvent->aucPayload); ++ kalMemZero(prBowRssi, sizeof(BOW_RSSI)); ++ prBowRssi->cRssi = (INT_8) prLinkQuality->cRssi; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is the default command timeout handler ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ ++ ASSERT(prAdapter); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ ++ prBowCmdStatus->ucStatus = BOWCMD_STATUS_TIMEOUT; /* timeout */ ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++ ++} ++ ++VOID bowStopping(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBowBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStoping.\n"); ++ DBGLOG(BOW, EVENT, "bowStoping, SSID %s.\n", prBowBssInfo->aucSSID); ++ DBGLOG(BOW, EVENT, "bowStoping, prBowBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", ++ prBowBssInfo->aucBSSID[0], ++ prBowBssInfo->aucBSSID[1], ++ prBowBssInfo->aucBSSID[2], ++ prBowBssInfo->aucBSSID[3], prBowBssInfo->aucBSSID[4], prBowBssInfo->aucBSSID[5])); ++ DBGLOG(BOW, EVENT, "bowStoping, prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", ++ prBowBssInfo->aucOwnMacAddr[0], ++ prBowBssInfo->aucOwnMacAddr[1], ++ prBowBssInfo->aucOwnMacAddr[2], ++ prBowBssInfo->aucOwnMacAddr[3], ++ prBowBssInfo->aucOwnMacAddr[4], prBowBssInfo->aucOwnMacAddr[5])); ++ DBGLOG(BOW, EVENT, "bowStoping, prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", ++ prAdapter->rWifiVar.aucDeviceAddress[0], ++ prAdapter->rWifiVar.aucDeviceAddress[1], ++ prAdapter->rWifiVar.aucDeviceAddress[2], ++ prAdapter->rWifiVar.aucDeviceAddress[3], ++ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); ++ DBGLOG(BOW, EVENT, "bowStopping, g_u4LinkCount, %x.\n", g_u4LinkCount); ++ DBGLOG(BOW, EVENT, "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ kalPrint("BoW Stoping,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); ++#endif ++ ++ if (g_u4LinkCount == 0) { ++ /*Stop beaconing */ ++ GLUE_DEC_REF_CNT(g_u4Beaconing); ++ ++ /*Deactive BoW network */ ++ /* prBowBssInfo->fgIsNetActive = FALSE; */ ++ /* prBowBssInfo->fgIsBeaconActivated = FALSE; */ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ /*temp solution for FW hal_pwr_mgt.c#3037 ASSERT */ ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ } ++ ++} ++ ++VOID bowStarting(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (g_u4LinkCount == 1) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "BoW Starting.\n"); ++ DBGLOG(BOW, EVENT, "BoW channel granted.\n"); ++#endif ++ ++#if 0 ++ /*Active BoW Network */ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#endif ++ ++ /* 3 <1> Update BSS_INFO_T per Network Basis */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBssInfo->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prBssInfo->eCurrentOPMode = OP_MODE_BOW; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress); ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); ++ prBssInfo->ucSSIDLen = BOW_SSID_LEN; ++ bowAssignSsid(prBssInfo->aucSSID, prBssInfo->aucOwnMacAddr); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "SSID %s.\n", prBssInfo->aucSSID); ++ DBGLOG(BOW, EVENT, "prBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", ++ prBssInfo->aucBSSID[0], ++ prBssInfo->aucBSSID[1], ++ prBssInfo->aucBSSID[2], ++ prBssInfo->aucBSSID[3], prBssInfo->aucBSSID[4], prBssInfo->aucBSSID[5])); ++ DBGLOG(BOW, EVENT, "prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", ++ prBssInfo->aucOwnMacAddr[0], ++ prBssInfo->aucOwnMacAddr[1], ++ prBssInfo->aucOwnMacAddr[2], ++ prBssInfo->aucOwnMacAddr[3], ++ prBssInfo->aucOwnMacAddr[4], prBssInfo->aucOwnMacAddr[5])); ++ DBGLOG(BOW, EVENT, "prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", ++ prAdapter->rWifiVar.aucDeviceAddress[0], ++ prAdapter->rWifiVar.aucDeviceAddress[1], ++ prAdapter->rWifiVar.aucDeviceAddress[2], ++ prAdapter->rWifiVar.aucDeviceAddress[3], ++ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); ++#endif ++ ++ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ ++ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prBssInfo->u2AssocId = 0; ++ ++ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ ++ prBssInfo->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; ++ if (prBowFsmInfo->eBand == BAND_2G4) ++ prBssInfo->eBand = BAND_2G4; ++ else ++ prBssInfo->eBand = BAND_5G; ++ ++#if CFG_BOW_SUPPORT_11N ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; ++ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prBssInfo->u2OperationalRateSet = ++ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); ++ ++#else ++ if (prBssInfo->eBand == BAND_2G4) { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; ++ ++ /* RATE_SET_ERP; */ ++ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; ++ prBssInfo->u2OperationalRateSet = RATE_SET_ERP; ++ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; ++ } else { ++ /* Depend on eBand */ ++ /* prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; */ ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ /* prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; */ ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; ++ ++ /* RATE_SET_ERP; */ ++ /* prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; */ ++ /* prBssInfo->u2OperationalRateSet = RATE_SET_ERP; */ ++ ++ /* RATE_SET_ERP; */ ++ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM; ++ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; ++ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; ++ } ++ ++#endif ++ prBssInfo->fgErpProtectMode = FALSE; ++ ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prBssInfo->u2BeaconInterval = prBowFsmInfo->u2BeaconInterval; ++ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; ++ prBssInfo->u2ATIMWindow = 0; ++ prBssInfo->ucBeaconTimeoutCount = 0; ++ if (prBowFsmInfo->fgSupportQoS) { ++ prAdapter->rWifiVar.fgSupportQoS = TRUE; ++ prBssInfo->fgIsQBSS = TRUE; ++ } ++ /* 3 <2> Update BSS_INFO_T common part */ ++#if CFG_SUPPORT_AAA ++ bssInitForAP(prAdapter, prBssInfo, TRUE); ++ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#endif /* CFG_SUPPORT_AAA */ ++ prBssInfo->fgIsNetActive = TRUE; ++ prBssInfo->fgIsBeaconActivated = TRUE; ++ ++ /* 3 <3> Set MAC HW */ ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BOW_BSS_INFO_INIT(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], ++ prBowFsmInfo->aucPeerAddress[5])); ++#endif ++ ++ /* 4 <3.1> use command packets to inform firmware */ ++ rlmBssInitForAPandIbss(prAdapter, prBssInfo); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /* 4 <3.2> Update AdHoc PM parameter */ ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /* 4 <3.1> Reset HW TSF Update Mode and Beacon Mode */ ++ ++ /* 4 <3.2> Setup BSSID */ ++ /* TODO: rxmSetRxFilterBSSID0 */ ++/* rxmSetRxFilterBSSID0(prBssInfo->ucHwBssidId, prBssInfo->aucBSSID); */ ++ ++ /* 4 <3.3> Setup RX Filter to accept Probe Request */ ++ /* TODO: f get/set RX filter. */ ++ ++#if 0 ++ { ++ UINT_32 u4RxFilter; ++ ++ if (halMacRxGetRxFilters(&u4RxFilter) == HAL_STATUS_SUCCESS) { ++ ++ u4RxFilter &= ~BIT(RXFILTER_DROP_PROBE_REQ); ++ ++ halMacRxSetRxFilters(u4RxFilter); ++ } ++ } ++#endif ++ } ++ ++ /*Update BoW Table */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_STARTING); ++ ++#if CFG_BOW_TEST ++ kalPrint("BoW Starting,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); ++ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ /*Start beaconing */ ++ if (g_u4Beaconing < 1) { ++ GLUE_INC_REF_CNT(g_u4Beaconing); ++ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); ++ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); ++ } ++#if 0 ++ /*Responder: Start to scan Initiator */ ++ if (prBowFsmInfo->ucRole == BOW_RESPONDER) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStarting responder, start scan result searching.\n"); ++#endif ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); ++ bowReleaseCh(prAdapter); ++ bowResponderScan(prAdapter); ++ } ++ /*Initiator: Request channel, wait for responder */ ++ else { ++ /* Todo:: Nothing*/ ++ /* bowRequestCh(prAdapter); */ ++ } ++#endif ++ ++} ++ ++VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 puOwnMacAddr) ++{ ++ UINT_8 i; ++ UINT_8 aucSSID[] = BOW_WILDCARD_SSID; ++ ++ kalMemCopy(pucSsid, aucSSID, BOW_WILDCARD_SSID_LEN); ++ ++ for (i = 0; i < 6; i++) { ++ pucSsid[(3 * i) + 3] = 0x2D; ++ if ((*(puOwnMacAddr + i) >> 4) < 0xA) ++ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x30; ++ else ++ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x57; ++ ++ if ((*(puOwnMacAddr + i) & 0x0F) < 0xA) ++ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x30; ++ else ++ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x57; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ BOOLEAN fgReplyProbeResp = FALSE; ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu4ControlFlags); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++#if 0 /* CFG_BOW_TEST */ ++ DBGLOG(BOW, EVENT, "bowValidateProbeReq.\n"); ++#endif ++ ++ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_SSID == IE_ID(pucIE)) { ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_SSID == IE_ID(pucIE)) { ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* 4 <2> Check network conditions */ ++ /*If BoW AP is beaconing */ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW && g_u4Beaconing > 0) { ++ ++ /*Check the probe requset sender is our peer */ ++ if (bowCheckBowTableIfVaild(prAdapter, prMgtHdr->aucSrcAddr)) ++ fgReplyProbeResp = TRUE; ++ /*Check the probe request target SSID is our SSID */ ++ else if ((prIeSsid) && ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength)) ++ fgReplyProbeResp = TRUE; ++ else ++ fgReplyProbeResp = FALSE; ++ } ++ ++ return fgReplyProbeResp; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if ((g_u4Beaconing != 0) && (g_u4LinkCount > 0) && (g_u4LinkCount < CFG_BOW_PHYSICAL_LINK_NUM)) { ++ /* Send beacon */ ++ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); ++ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); ++ } ++#if CFG_BOW_TEST ++ else ++ kalPrint("BoW Send Beacon,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderScan(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_SCN_SCAN_REQ prScanReqMsg; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowResponderScan.\n"); ++ kalPrint("BOW SCAN [REQ:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq + 1); ++#endif ++ ++ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); ++ ++ if (!prScanReqMsg) { ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ return; ++ } ++ ++ /*Fill scan message */ ++ prScanReqMsg->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_REQ; ++ prScanReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfScanReq; ++ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_BOW_INDEX; ++ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ prScanReqMsg->ucSSIDLength = BOW_SSID_LEN; ++ bowAssignSsid(prScanReqMsg->aucSSID, prBowFsmInfo->aucPeerAddress); ++ prScanReqMsg->ucChannelListNum = 1; ++ ++ if (prBowFsmInfo->eBand == BAND_2G4) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; ++ prScanReqMsg->arChnlInfoList[0].eBand = BAND_2G4; ++ } else { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; ++ prScanReqMsg->arChnlInfoList[0].eBand = BAND_5G; ++ } ++ ++ prScanReqMsg->arChnlInfoList[0].ucChannelNum = prBowFsmInfo->ucPrimaryChannel; ++ prScanReqMsg->u2IELen = 0; ++ ++ /*Send scan message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); ++ ++ /*Change state to SCANNING */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); ++ ++ /* prBowFsmInfo->fgTryScan = FALSE; */ /* Will enable background sleep for infrastructure */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_DESC_T prBssDesc; ++ UINT_8 ucSeqNumOfCompMsg; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ENUM_SCAN_STATUS eScanStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ ASSERT(prScanDoneMsg->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX); ++ ++ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; ++ eScanStatus = prScanDoneMsg->eScanStatus; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowResponderScanDone.\n"); ++ kalPrint("BOW SCAN [DONE:%d]\n", ucSeqNumOfCompMsg); ++#endif ++ ++ if (eScanStatus == SCAN_STATUS_CANCELLED) { ++#if CFG_BOW_TEST ++ kalPrint("BOW SCAN [CANCELLED:%d]\n", ucSeqNumOfCompMsg); ++#endif ++ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTING) { ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ } ++ return; ++ } else if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { ++ /* bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); */ ++ return; ++ } else if (ucSeqNumOfCompMsg != prBowFsmInfo->ucSeqNumOfScanReq) { ++ DBGLOG(BOW, EVENT, "Sequence no. of BOW Responder scan done is not matched.\n"); ++ return; ++ } ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prBowFsmInfo->aucPeerAddress); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "End scan result searching.\n"); ++#endif ++ ++ /* Initiator is FOUND */ ++ if (prBssDesc != NULL) { ++ /* (prBssDesc->aucBSSID != NULL)) */ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Search Bow Peer address - %x:%x:%x:%x:%x:%x.\n", prBssDesc->aucBSSID[0], ++ prBssDesc->aucBSSID[1], ++ prBssDesc->aucBSSID[2], ++ prBssDesc->aucBSSID[3], prBssDesc->aucBSSID[4], prBssDesc->aucBSSID[5]); ++ DBGLOG(BOW, EVENT, "Starting to join initiator.\n"); ++#endif ++ /*Set target BssDesc */ ++ prBowFsmInfo->prTargetBssDesc = prBssDesc; ++ /*Request channel to do JOIN */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, ++ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); ++ bowRequestCh(prAdapter); ++ } ++ /*Initiator is NOT FOUND */ ++ else { ++ /*Scan again, until PAL timeout */ ++ bowResponderScan(prAdapter); ++#if 0 ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++#endif ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Function for cancelling scan request. There is another option to extend channel privilige ++* for another purpose. ++* ++* @param fgIsChannelExtention - Keep the channel previlege, but can cancel scan timer. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention) ++{ ++ ++ P_MSG_SCN_SCAN_CANCEL prScanCancel = (P_MSG_SCN_SCAN_CANCEL) NULL; ++ P_BOW_FSM_INFO_T prBowFsmInfo = (P_BOW_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("bowResponderCancelScan()"); ++ ++ do { ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (TRUE) { ++#if CFG_BOW_TEST ++ kalPrint("BOW SCAN [CANCEL:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq); ++#endif ++ /* There is a channel privilege on hand. */ ++ ++ DBGLOG(P2P, TRACE, "BOW Cancel Scan\n"); ++ ++ prScanCancel = ++ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancel) { ++ /* Buffer not enough, can not cancel scan request. */ ++ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prScanCancel->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_CANCEL; ++ prScanCancel->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prScanCancel->ucSeqNum = prBowFsmInfo->ucSeqNumOfScanReq; ++#if CFG_ENABLE_WIFI_DIRECT ++ prScanCancel->fgIsChannelExt = fgIsChannelExtention; ++#endif ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancel, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ } while (FALSE); ++ ++} /* bowResponderCancelScan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialization of JOIN STATE ++* ++* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_MSG_JOIN_REQ_T prJoinReqMsg; ++ ++ ASSERT(prBssDesc); ++ ASSERT(prAdapter); ++ ++ DBGLOG(BOW, EVENT, "Starting bowResponderJoin.\n"); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> We are going to connect to this BSS. */ ++ prBssDesc->fgIsConnecting = TRUE; ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTING); ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ /*Support First JOIN and retry */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_BOW_AP, NETWORK_TYPE_BOW_INDEX, prBssDesc); ++ if (!prStaRec) ++ return; ++ ++ prBowFsmInfo->prTargetStaRec = prStaRec; ++ ++ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ ++ prStaRec->fgIsReAssoc = FALSE; ++ prBowFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; ++ ++ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ ++ if (prBowFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { ++ ++ DBGLOG(BOW, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); ++ prBowFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else { ++ ASSERT(0); ++ } ++ ++ /* 4 <4.1> sync. to firmware domain */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy */ ++ if (prBssDesc->ucSSIDLen) { ++ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prBssDesc->aucSSID); ++ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prConnSettings->aucSSID); ++#endif ++ } ++ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ return; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_BOW_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ prBssInfo->prStaRecOfAP = prStaRec; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prStaRec->eStaType, %x.\n", prStaRec->eStaType); ++ DBGLOG(BOW, INFO, "BoW trigger SAA [%pM]\n", prStaRec->aucMacAddr); ++#endif ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Join Complete Event from SAA FSM for BOW FSM ++* ++* @param[in] prMsgHdr Message of Join Complete of SAA FSM. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_JOIN_COMP_T prJoinCompMsg; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prAssocRspSwRfb; ++ P_BSS_INFO_T prBssInfo; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; ++ prStaRec = prJoinCompMsg->prStaRec; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete.\n"); ++ DBGLOG(BOW, EVENT, "bowfsmRunEventJoinComplete ptr check\n"); ++ DBGLOG(BOW, EVENT, "prMsgHdr %x\n", prMsgHdr); ++ DBGLOG(BOW, EVENT, "prAdapter %x\n", prAdapter); ++ DBGLOG(BOW, EVENT, "prBowFsmInfo %x\n", prBowFsmInfo); ++ DBGLOG(BOW, EVENT, "prStaRec %x\n", prStaRec); ++#endif ++ ++ ASSERT(prStaRec); ++ ASSERT(prBowFsmInfo); ++ ++ /* Check SEQ NUM */ ++ if (prJoinCompMsg->ucSeqNum == prBowFsmInfo->ucSeqNumOfReqMsg) { ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); ++ ++ /* 4 <1> JOIN was successful */ ++ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { ++ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - ++ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - ++ WLAN_MAC_MGMT_HEADER_LEN)); ++ pucIE = prAssocRspFrame->aucInfoElem; ++ ++ prStaRec->eStaType = STA_TYPE_BOW_AP; ++ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; ++#if CFG_BOW_RATE_LIMITATION ++ /* 4 <1.2>Update Rate Set */ ++ /*Limit Rate Set to 24M, 48M, 54M */ ++ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); ++ /*If peer cannot support the above rate set, fix on the available highest rate */ ++ if (prStaRec->u2DesiredNonHTRateSet == 0) { ++ UINT_8 ucHighestRateIndex; ++ ++ if (rateGetHighestRateIndexFromRateSet ++ (prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) { ++ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); ++ } ++ } ++#endif ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ /* 4 <1.2> Update HT information and set channel */ ++ /* Record HT related parameters in rStaRec and rBssInfo ++ * Note: it shall be called before nicUpdateBss() ++ */ ++#if CFG_BOW_SUPPORT_11N ++ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++#endif ++ ++ /* 4 <1.3> Update BSS_INFO_T */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Finish bowUpdateBssInfoForJOIN.\n"); ++#endif ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowFsmRunEventJoinComplete, qmActivateStaRec.\n"); ++#endif ++ ++ /* 4 <1.7> Set the Next State of BOW FSM */ ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ } ++ /* 4 <2> JOIN was not successful */ ++ else { ++ /*Retry */ ++ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); ++#if 0 ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++#endif ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete -- Join failed.\n"); ++ DBGLOG(BOW, INFO, "BoW trigger SAA REJOIN\n"); ++#endif ++ } ++ } ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Media State to HOST ++* ++* @param[in] eConnectionState Current Media State ++* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN BOOLEAN fgDelayIndication) ++{ ++ EVENT_CONNECTION_STATUS rEventConnStatus; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prBssInfo; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /* NOTE(Kevin): Move following line to bowChangeMediaState() macro per CM's request. */ ++ /* prBowBssInfo->eConnectionState = eConnectionState; */ ++ ++ /* For indicating the Disconnect Event only if current media state is ++ * disconnected and we didn't do indication yet. ++ */ ++ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ if (prBssInfo->eConnectionStateIndicated == eConnectionState) ++ return; ++ } ++ ++ if (!fgDelayIndication) { ++ /* 4 <0> Cancel Delay Timer */ ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rIndicationOfDisconnectTimer); ++ ++ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ ++ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; ++ ++ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; ++ rEventConnStatus.u2AID = prBssInfo->u2AssocId; ++ rEventConnStatus.u2ATIMWindow = 0; ++ } else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; ++ rEventConnStatus.u2AID = 0; ++ rEventConnStatus.u2ATIMWindow = prBssInfo->u2ATIMWindow; ++ } else { ++ ASSERT(0); ++ } ++ ++ COPY_SSID(rEventConnStatus.aucSsid, ++ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prBssInfo->aucBSSID); ++ ++ rEventConnStatus.u2BeaconPeriod = prBssInfo->u2BeaconInterval; ++ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prBssInfo->ucPrimaryChannel); ++ ++ switch (prBssInfo->ucNonHTBasicPhyType) { ++ case PHY_TYPE_HR_DSSS_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ ++ case PHY_TYPE_ERP_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; ++ break; ++ ++ case PHY_TYPE_OFDM_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; ++ break; ++ ++ default: ++ ASSERT(0); ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ } ++ } else { ++#if CFG_PRIVACY_MIGRATION ++ /* Clear the pmkid cache while media disconnect */ ++ secClearPmkid(prAdapter); ++#endif ++ ++ rEventConnStatus.ucReasonOfDisconnect = prBssInfo->ucReasonOfDisconnect; ++ ++ } ++ ++ /* 4 <2> Indication */ ++ nicMediaStateChange(prAdapter, NETWORK_TYPE_BOW_INDEX, &rEventConnStatus); ++ prBssInfo->eConnectionStateIndicated = eConnectionState; ++ } else { ++ /* NOTE: Only delay the Indication of Disconnect Event */ ++ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ DBGLOG(BOW, INFO, "Postpone the indication of Disconnect for %d seconds\n", ++ prConnSettings->ucDelayTimeOfDisconnectEvent); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prBowFsmInfo->rIndicationOfDisconnectTimer, ++ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Tx Fail of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowRunEventAAATxFail , bssRemoveStaRecFromClientList.\n"); ++ DBGLOG(BOW, INFO, "BoW AAA TxFail, target state %d\n", prStaRec->ucStaState + 1); ++#endif ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Successful Completion of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ ASSERT(prStaRec); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowRunEventAAAComplete, cnmStaRecChangeState, STA_STATE_3.\n"); ++ DBGLOG(BOW, INFO, "BoW AAA complete [%pM]\n", prStaRec->aucMacAddr); ++#endif ++ ++ /*Update BssInfo to connected */ ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /*Update StaRec to State3 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ /*Connected */ ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, FALSE, wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle RxDeauth ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBowBssInfo; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ if (!IS_STA_IN_BOW(prStaRec)) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ ++ eFsmState = bowGetBowTableState(prAdapter, prStaRec->aucMacAddr); ++ ++ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { ++ /*do nothing */ ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (prStaRec->ucStaState > STA_STATE_1) { ++ ++ if (STA_STATE_3 == prStaRec->ucStaState) { ++ /* P_MSG_AIS_ABORT_T prAisAbortMsg; */ ++ ++ /* NOTE(Kevin): Change state immediately to avoid starvation of ++ * MSG buffer because of too many deauth frames before changing ++ * the STA state. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++ ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); ++ ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ return WLAN_STATUS_NOT_ACCEPTED; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function handle BoW Link disconnect. ++* ++* \param[in] pMsduInfo Pointer to the Msdu Info ++* \param[in] rStatus The Tx done status ++* ++* \return - ++* ++* \note after receive deauth frame, callback function call this ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /*Free target StaRec */ ++ if (prMsduInfo) ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ else ++ prStaRec = prBowFsmInfo->prTargetStaRec; ++ ++ if (prStaRec) ++ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ kalPrint("bowDisconnectLink\n"); ++ /*No one connected */ ++ if (g_u4LinkCount == 0 && g_u4Beaconing != 0) { ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer); ++ bowStopping(prAdapter); ++ kalPrint("bowStopping\n"); ++ /*Restore TxPower from Short range mode */ ++#if CFG_SUPPORT_NVRAM && 0 ++ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); ++#endif ++ /*Uninit BoW Interface */ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ kalUninitBowDevice(prAdapter->prGlueInfo); ++#endif ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Assoc Req Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Assoc Resp ++* @retval FALSE Don't reply the Assoc Resp ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAssocResp = FALSE; ++ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; ++ OS_SYSTIME rCurrentTime; ++ static OS_SYSTIME rLastRejectAssocTime; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prAssocReqFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", ++ prAssocReqFrame->aucSrcAddr[0], ++ prAssocReqFrame->aucSrcAddr[1], ++ prAssocReqFrame->aucSrcAddr[2], ++ prAssocReqFrame->aucSrcAddr[3], ++ prAssocReqFrame->aucSrcAddr[4], prAssocReqFrame->aucSrcAddr[5])); ++#endif ++ ++ /*Assoc Accept */ ++ while (EQUAL_MAC_ADDR(prAssocReqFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAssocReq, return wlanbowCmdEventLinkConnected.\n"); ++#endif ++ /*Update StaRec */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ (UINT_8) NETWORK_TYPE_BOW_INDEX, prAssocReqFrame->aucSrcAddr); ++ if (!prStaRec) ++ break; ++ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; ++ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; ++ ++#if CFG_BOW_RATE_LIMITATION ++ /*Limit Rate Set to 24M, 48M, 54M */ ++ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); ++ /*If peer cannot support the above rate set, fix on the available highest rate */ ++ if (prStaRec->u2DesiredNonHTRateSet == 0) { ++ UINT_8 ucHighestRateIndex; ++ ++ if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) ++ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); ++ else { ++ /*If no available rate is found, DECLINE the association */ ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++ } ++#endif ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ ++ /*Undpate BssInfo to FW */ ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /*reply successful */ ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ fgReplyAssocResp = TRUE; ++ break; ++ } ++ ++ /*Reject Assoc */ ++ if (*pu2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ /*Reply Assoc with reject every 5s */ ++ rCurrentTime = kalGetTimeTick(); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAssocTime, MSEC_TO_SYSTIME(5000)) || ++ rLastRejectAssocTime == 0) { ++ fgReplyAssocResp = TRUE; ++ rLastRejectAssocTime = rCurrentTime; ++ } ++ } ++ ++ return fgReplyAssocResp; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Auth Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Auth ++* @retval FALSE Don't reply the Auth ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++bowValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAuth = FALSE; ++ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; ++ OS_SYSTIME rCurrentTime; ++ static OS_SYSTIME rLastRejectAuthTime; ++ ++ /* TODO(Kevin): Call BoW functions to check .. ++ 1. Check we are BoW now. ++ 2. Check we can accept connection from thsi peer ++ 3. Check Black List here. ++ */ ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prAuthFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", ++ prAuthFrame->aucSrcAddr[0], ++ prAuthFrame->aucSrcAddr[1], ++ prAuthFrame->aucSrcAddr[2], ++ prAuthFrame->aucSrcAddr[3], prAuthFrame->aucSrcAddr[4], prAuthFrame->aucSrcAddr[5])); ++#endif ++ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX, prAuthFrame->aucSrcAddr); ++ if (!prStaRec) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecAlloc.\n"); ++#endif ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX); ++ ++ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for ++ * exhausted case and do removal of unused STA_RECORD_T. ++ */ ++ if (!prStaRec) ++ return fgReplyAuth; ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++ prBowBssInfo->prStaRecOfAP = prStaRec; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecChangeState.\n"); ++#endif ++ } else { ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucIndex, %x.\n", prStaRec->ucIndex); ++#endif ++ bssRemoveStaRecFromClientList(prAdapter, prBowBssInfo, prStaRec); ++ } ++ ++ if (EQUAL_MAC_ADDR(prAuthFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { ++ ++ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->eStaType, %x.\n", prStaRec->eStaType); ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucNetTypeIndex, %x.\n", prStaRec->ucNetTypeIndex); ++#endif ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ prStaRec->ucJoinFailureCount = 0; ++ *pprStaRec = prStaRec; ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ fgReplyAuth = TRUE; ++ } else { ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ /*Reply auth with reject every 5s */ ++ rCurrentTime = kalGetTimeTick(); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAuthTime, MSEC_TO_SYSTIME(5000)) || ++ rLastRejectAuthTime == 0) { ++ fgReplyAuth = TRUE; ++ rLastRejectAuthTime = rCurrentTime; ++ } ++ } ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, fgReplyAuth, %x.\n", fgReplyAuth); ++#endif ++ return fgReplyAuth; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is invoked when CNM granted channel privilege ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prBowBssInfo; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_CH_GRANT_T prMsgChGrant; ++ UINT_8 ucTokenID; ++ UINT_32 u4GrantInterval; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; ++ ucTokenID = prMsgChGrant->ucTokenID; ++ u4GrantInterval = prMsgChGrant->u4GrantInterval; ++ ++ /* 1. free message */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ prBowFsmInfo->fgIsChannelGranted = TRUE; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Entering bowRunEventChGrant.\n"); ++#endif ++ ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ /*Release channel */ ++ if ((!prBowFsmInfo->fgIsChannelRequested) || ++ (prBowFsmInfo->ucSeqNumOfChReq != ucTokenID) || ++ (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) || (eFsmState == BOW_DEVICE_STATE_DISCONNECTING)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW Channel [GIVE UP:%d]\n", ucTokenID); ++ DBGLOG(BOW, INFO, "[Requested:%d][ucSeqNumOfChReq:%d][eFsmState:%d]\n", ++ prBowFsmInfo->fgIsChannelRequested, prBowFsmInfo->ucSeqNumOfChReq, eFsmState); ++#endif ++ bowReleaseCh(prAdapter); ++ return; ++ } ++ ++ /* 2. channel privilege has been approved */ ++ prBowFsmInfo->u4ChGrantedInterval = u4GrantInterval; ++ ++#if 0 ++ cnmTimerStartTimer(prAdapter, ++ &prBowFsmInfo->rChGrantedTimer, ++ prBowFsmInfo->u4ChGrantedInterval - BOW_JOIN_CH_GRANT_THRESHOLD); ++#else ++ cnmTimerStartTimer(prAdapter, ++ &prBowFsmInfo->rChGrantedTimer, BOW_JOIN_CH_REQUEST_INTERVAL - BOW_JOIN_CH_GRANT_THRESHOLD); ++#endif ++ ++ /* 3.2 set local variable to indicate join timer is ticking */ ++ prBowFsmInfo->fgIsInfraChannelFinished = FALSE; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW Channel [GRANTED:%d].\n", ucTokenID); ++#endif ++ ++ if (eFsmState == BOW_DEVICE_STATE_ACQUIRING_CHANNEL) { ++ bowStarting(prAdapter); ++ bowReleaseCh(prAdapter); ++ if (prBowFsmInfo->ucRole == BOW_RESPONDER) ++ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); ++ } else { ++ /*update bssinfo */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ bowReleaseCh(prAdapter); ++ } ++ ++} /* end of aisFsmRunEventChGrant() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform CNM for channel privilege requesting ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowRequestCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_CH_REQ_T prMsgChReq; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (prBowFsmInfo->fgIsChannelGranted == FALSE) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW channel [REQUEST:%d], %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq + 1, ++ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); ++#endif ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ return; ++ } ++ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prMsgChReq->ucTokenID = ++prBowFsmInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++#if 0 ++ prMsgChReq->u4MaxInterval = BOW_JOIN_CH_REQUEST_INTERVAL; ++#else ++ prMsgChReq->u4MaxInterval = 1; ++#endif ++ /* prBowFsmInfo->prTargetBssDesc->ucChannelNum; */ ++ prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; ++ /* prBowFsmInfo->prTargetBssDesc->eSco; */ ++ prMsgChReq->eRfSco = CHNL_EXT_SCN; ++ /* prBowFsmInfo->prTargetBssDesc->eBand; */ ++ prMsgChReq->eRfBand = prBowFsmInfo->eBand; ++ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prBowFsmInfo->aucPeerAddress); ++ ++ prBowFsmInfo->fgIsChannelRequested = TRUE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform BOW that channel privilege is granted ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowReleaseCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_CH_ABORT_T prMsgChAbort; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (prBowFsmInfo->fgIsChannelGranted != FALSE || prBowFsmInfo->fgIsChannelRequested != FALSE) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW channel [RELEASE:%d] %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq, ++ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); ++#endif ++ ++ prBowFsmInfo->fgIsChannelRequested = FALSE; ++ prBowFsmInfo->fgIsChannelGranted = FALSE; ++ ++ /* 1. return channel privilege to CNM immediately */ ++ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); ++ if (!prMsgChAbort) { ++ ASSERT(0); /* Can't release Channel to CNM */ ++ return; ++ } ++ ++ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; ++ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prMsgChAbort->ucTokenID = prBowFsmInfo->ucSeqNumOfChReq; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); ++ } ++ ++} /* end of aisFsmReleaseCh() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW Channel [TIMEOUT]\n"); ++#endif ++#if 1 ++ /* bowReleaseCh(prAdapter); */ ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ /*If connecting is not completed, request CH again */ ++ if ((eFsmState == BOW_DEVICE_STATE_CONNECTING) || (eFsmState == BOW_DEVICE_STATE_STARTING)) ++ bowRequestCh(prAdapter); ++#endif ++} ++ ++BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucBowTableIdx = 0; ++ CMD_INFO_T rCmdInfo; ++ ++ ASSERT(prAdapter); ++ ++ kalMemZero(&rCmdInfo, sizeof(CMD_INFO_T)); ++ ++ while (ucBowTableIdx < CFG_BOW_PHYSICAL_LINK_NUM) { ++ if (arBowTable[ucBowTableIdx].fgIsValid) { ++ COPY_MAC_ADDR(prAdapter->rWifiVar.rBowFsmInfo.aucPeerAddress, ++ arBowTable[ucBowTableIdx].aucPeerAddress); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowNotifyAllLinkDisconnected, arBowTable[%x].aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ ucBowTableIdx, arBowTable[ucBowTableIdx].aucPeerAddress[0], ++ arBowTable[ucBowTableIdx].aucPeerAddress[1], ++ arBowTable[ucBowTableIdx].aucPeerAddress[2], ++ arBowTable[ucBowTableIdx].aucPeerAddress[3], ++ arBowTable[ucBowTableIdx].aucPeerAddress[4], ++ arBowTable[ucBowTableIdx].aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "bowNotifyAllLinkDisconnected, arBowTable[%x].fgIsValid, %x.\n", ucBowTableIdx, ++ arBowTable[ucBowTableIdx].fgIsValid); ++#endif ++#if 1 ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++#else ++ wlanbowCmdEventLinkDisconnected(prAdapter, &rCmdInfo, NULL); ++#endif ++ } ++ ++ ucBowTableIdx += 1; ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer ++* ++* \param[in] ++* prGlueInfo ++* rPeerAddr ++* \return ++* ENUM_BOW_DEVICE_STATE ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], ++ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], ++ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, ++ arBowTable[idx].fgIsValid); ++ ++#endif ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ return TRUE; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ return FALSE; ++} ++ ++BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable) ++{ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ if (arBowTable[ucBowTableIdx].fgIsValid) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowGetBowTableContent, arBowTable[idx].fgIsValid, %x, %x.\n", ucBowTableIdx, ++ arBowTable[ucBowTableIdx].fgIsValid); ++ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[ucBowTableIdx].eState); ++#endif ++ prBowTable = &(arBowTable[ucBowTableIdx]); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return TRUE; ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return FALSE; ++} ++ ++BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable) ++{ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ COPY_MAC_ADDR(arBowTable[ucBowTableIdx].aucPeerAddress, prBowTable->aucPeerAddress); ++ arBowTable[ucBowTableIdx].eState = prBowTable->eState; ++ arBowTable[ucBowTableIdx].fgIsValid = prBowTable->fgIsValid; ++ arBowTable[ucBowTableIdx].ucAcquireID = prBowTable->ucAcquireID; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ kalSetBowState(prAdapter->prGlueInfo, prBowTable->eState, prBowTable->aucPeerAddress); ++ /* kalSetBowRole(prAdapter->prGlueInfo, prBowTable->ucRole, prBowTable->aucPeerAddress); */ ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "SET State [%d]\n", arBowTable[ucBowTableIdx].eState); ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[ucBowTableIdx].fgIsValid, %x, %x.\n", ucBowTableIdx, ++ arBowTable[ucBowTableIdx].fgIsValid); ++#endif ++ ++ return TRUE; ++ ++} ++ ++BOOLEAN ++bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], ++ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], ++ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, ++ arBowTable[idx].fgIsValid); ++#endif ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ *pucBowTableIdx = idx; ++ ++ return TRUE; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return FALSE; ++} ++ ++BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (!arBowTable[idx].fgIsValid) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowGetBowTableFreeEntry, arBowTable[idx].fgIsValid, %x, %x.\n", idx, ++ arBowTable[idx].fgIsValid); ++#endif ++ *pucBowTableIdx = idx; ++ arBowTable[idx].fgIsValid = TRUE; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return TRUE; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return FALSE; ++} ++ ++ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowGetState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "bowGetState, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ arBowTable[idx].aucPeerAddress[0], ++ arBowTable[idx].aucPeerAddress[1], ++ arBowTable[idx].aucPeerAddress[2], ++ arBowTable[idx].aucPeerAddress[3], ++ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "bowGetState, arBowTable[idx].fgIsValid, %x, %x.\n", idx, arBowTable[idx].fgIsValid); ++ DBGLOG(BOW, EVENT, ++ "bowGetState, arBowTable[idx].eState;, %x, %x.\n", idx, arBowTable[idx].eState); ++ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[idx].eState); ++#endif ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return arBowTable[idx].eState; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return BOW_DEVICE_STATE_DISCONNECTED; ++} ++ ++BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState) ++{ ++ UINT_8 ucBowTableIdx; ++ ++ if (bowGetBowTableEntryByPeerAddress(prAdapter, aucPeerAddress, &ucBowTableIdx)) { ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ arBowTable[ucBowTableIdx].eState = eState; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "SET State [%d]\n", eState); ++#endif ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ kalSetBowState(prAdapter->prGlueInfo, eState, aucPeerAddress); ++ return TRUE; ++ } ++ return FALSE; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c +new file mode 100644 +index 000000000000..1c59f861047e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c +@@ -0,0 +1,6240 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_lib.c#2 ++*/ ++/*! \file wlan_lib.c ++ \brief Internal driver stack will export the required procedures here for GLUE Layer. ++ ++ This file contains all routines which are exported from MediaTek 802.11 Wireless ++ LAN driver stack to GLUE Layer. ++*/ ++ ++/* ++** Log: wlan_lib.c ++** ++** 08 15 2012 eason.tsai ++** [ALPS00338170] [Need Patch] [Volunteer Patch] modify build warning ++** fix build waring for codechange ++ * ++ * 07 13 2012 cp.wu ++ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for termination ++ * after SDIO error has happened ++ * [driver domain] add force reset by host-to-device interrupt mechanism ++ * ++ * 06 11 2012 cp.wu ++ * [WCXRP00001252] [MT6620 Wi-Fi][Driver] Add debug message while encountering firmware response timeout ++ * output message while timeout event occurs ++ * ++ * 06 11 2012 eason.tsai ++ * NULL ++ * change from binay to hex code ++ * ++ * 06 08 2012 eason.tsai ++ * NULL ++ * Nvram context covert from 6620 to 6628 for old 6620 meta tool ++ * ++ * 05 11 2012 cp.wu ++ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience ++ * show MAC address & source while initiliazation ++ * ++ * 03 29 2012 eason.tsai ++ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define ++ * add conditional define. ++ * ++ * 03 04 2012 eason.tsai ++ * NULL ++ * modify the cal fail report code. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 cp.wu ++ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band ++ * configuration with corresponding network configuration correct scan result removing policy. ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with ++ * corresponding network configuration add wlanSetPreferBandByNetwork() for glue layer to invoke ++ * for setting preferred band configuration corresponding to network type. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 11 28 2011 cp.wu ++ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment ++ * when returining to ROM code ++ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware ++ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not ++ * ++ * 11 14 2011 cm.chang ++ * [WCXRP00001104] [All Wi-Fi][FW] Show init process by HW mail-box register ++ * Show FW initial ID when timeout to wait for ready bit ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 10 18 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * when powering off, always clear pending interrupts, then wait for RDY to be de-asserted ++ * ++ * 10 14 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * shorten the packet length for firmware download if no more than 2048 bytes. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 10 03 2011 cp.wu ++ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware downloading aggregated path. ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 09 20 2011 cp.wu ++ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized ++ * 1. always show error message for SDIO bus errors. ++ * 2. reset bus error flag when re-initialization ++ * ++ * 08 26 2011 cm.chang ++ * [WCXRP00000952] [MT5931 Wi-Fi][FW] Handshake with BWCS before DPD/TX power calibration ++ * Fix compiling error for WinXP MT5931 driver ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS Sync ready for WinXP. ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add DFS switch. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 19 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * escape from normal path if any error is occurred. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a ++ * disconnecting device issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 24 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * if there is no valid address in chip, generate a new one from driver domain instead of firmware domain ++ * due to sufficient randomness ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * disable whole-chip resetting mechanism due to the need of further ECO to work as expected. ++ * ++ * 05 31 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * changed to use non-zero checking for valid bit in NVRAM content ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain ++ * pass PHY_PARAM in NVRAM from driver to firmware. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * correct assertion. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 05 11 2011 cm.chang ++ * [WCXRP00000717] [MT5931 Wi-Fi][Driver] Handle wrong NVRAM content about AP bandwidth setting ++ * . ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * change delay from 100ms to 120ms upon DE's suggestion. ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add delay after whole-chip resetting for MT5931 E1 ASIC. ++ * ++ * 04 22 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space ++ * process for RESET_START and RESET_END events skip power-off handshaking when RESET indication is received. ++ * ++ * 04 22 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * . ++ * ++ * 04 18 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * 1) add API for glue layer to query ACPI state ++ * 2) Windows glue should not access to hardware after switched into D3 state ++ * ++ * 04 15 2011 cp.wu ++ * [WCXRP00000654] [MT6620 Wi-Fi][Driver] Add loop termination criterion for wlanAdapterStop(). ++ * add loop termination criteria for wlanAdapterStop(). ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing ++ * frame dropping cases for TC4 path ++ * 1. add nicTxGetResource() API for QM to make decisions. ++ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. ++ * ++ * 04 06 2011 cp.wu ++ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure ++ * happend inside wlanAdapterStart invoke nicReleaseAdapterMemory() as failure handling in case ++ * wlanAdapterStart() failed unexpectedly ++ * ++ * 03 29 2011 wh.su ++ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error ++ * fixed the kclocwork error. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically ++ * continuous memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 02 25 2011 cp.wu ++ * [WCXRP00000496] [MT5931][Driver] Apply host-triggered chip reset before initializing firmware download procedures ++ * apply host-triggered chip reset mechanism before initializing firmware download procedures. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 16 2011 cm.chang ++ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism ++ * . ++ * ++ * 02 01 2011 george.huang ++ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers ++ * init variable for CTIA. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Support current measure mode, assigned by registry (XP only). ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer when the ++ * corresponding BSS is disconnected due to beacon timeout remove from scanning result when the BSS ++ * is disconnected due to beacon timeout. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ++ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous ++ * and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * while being unloaded, clear all pending interrupt then set LP-own to firmware ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay ++ * to avoid blocking to system scheduling change to use msleep() and shorten waiting interval ++ * to reduce blocking to other task while Wi-Fi driver is being loaded ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 22 2010 eddie.chen ++ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry ++ * Remove controling auto rate from initial setting. The initial setting is defined by FW code. ++ * ++ * 12 15 2010 cp.wu ++ * NULL ++ * sync. with ALPS code by enabling interrupt just before leaving wlanAdapterStart() ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in ++ * Change Param name for invitation connection. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 03 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * 1) use 8 buffers for MT5931 which is equipped with less memory ++ * 2) modify MT5931 debug level to TRACE when download is successful ++ * ++ * 11 02 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * for MT5931, adapter initialization is done *after* firmware is downloaded. ++ * ++ * 11 02 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * correct MT5931 firmware download procedure: ++ * MT5931 will download firmware first then acquire LP-OWN ++ * ++ * 11 02 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * 1) update MT5931 firmware encryption tool. (using 64-bytes unit) ++ * 2) update MT5931 firmware download procedure ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying ++ * current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function ++ * for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add option for enable/disable TX PWR gain adjustment (default: off) ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 15 2010 cp.wu ++ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A ++ * bugfix: always reset pointer to IEbuf to zero when keeping scanning result for the connected AP ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced ++ * by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate unused variables which lead gcc to argue ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with ++ * AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 13 2010 cp.wu ++ * NULL ++ * acquire & release power control in oid handing wrapper. ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * move IE to buffer head when the IE pointer is not pointed at head. ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add AT GO test configure mode under WinXP. ++ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cp.wu ++ * NULL ++ * 1) initialize variable for enabling short premable/short time slot. ++ * 2) add compile option for disabling online scan ++ * ++ * 08 13 2010 cp.wu ++ * NULL ++ * correction issue: desired phy type not initialized as ABGN mode. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 10 2010 cm.chang ++ * NULL ++ * Support EEPROM read/write in RF test mode ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 13 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Reduce unnecessary type casting ++ * ++ * 07 13 2010 cp.wu ++ * ++ * use multiple queues to keep 1x/MMPDU/CMD's strict order even when there is incoming 1x frames. ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent ++ * network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) for event packet, no need to fill RFB. ++ * 2) when wlanAdapterStart() failed, no need to initialize state machines ++ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan uninitialization procedure ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * initialize mbox & ais_fsm in wlanAdapterStart() ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * simplify timer usage. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 28 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * disable interrupt then send power control command packet. ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) when stopping adapter, wait til RDY bit has been cleaerd. ++ * 2) set TASK_OFFLOAD as driver-core OIDs ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add CFG_STARTUP_DEBUG for debugging starting up issue. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * roll-back to rev.60. ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove redundant firmware image unloading ++ * 2) use compile-time macros to separate logic related to accquiring own ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always set fw-own before driver is unloaded. ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * 2) command sequence number is now increased atomically ++ * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * are done in adapter layer. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * ePowerCtrl is not necessary as a glue variable. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add timeout check in the kalOidComplete ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * 2) add 2 kal API for later integration ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) eliminate unused definitions ++ * 2) ready bit will be polled for limited iteration ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * kalOidComplete is not necessary in linux ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use pass-in prRegInfo instead of accessing prGlueInfo directly ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use WIFI_TCM_ALWAYS_ON as firmware image ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding none-glue code portability ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding non-glue code portability ++ * ++ * 03 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve non-glue code portability ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * firmware download load address & start address are now configured from config.h ++ * due to the different configurations on FPGA and ASIC ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * only send CMD_NIC_POWER_CTRL in wlanAdapterStop() when card is not removed and is not in D3 state ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always send CMD_NIC_POWER_CTRL packet when nic is being halted ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++* 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when starting adapter, read local adminsitrated address from registry and send to firmware via CMD_BASIC_CONFIG. ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 03 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add command/event definitions for initial states ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added code for QM_TEST_MODE ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct function name .. ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * separate wlanProcesQueuePacket() into 2 APIs upon request ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct wlanAdapterStart ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. add logic for firmware download ++ * 2. firmware image filename and start/load address are now retrieved from registry ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * 2) firmware image length is now retrieved via NdisFileOpen ++ * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * 4) nicRxWaitResponse() revised ++ * 5) another set of TQ counter default value is added for fw-download state ++ * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * 2. follow MSDN defined behavior when associates to another AP ++ * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * wlanoidSetFrequency is now implemented by RF test command. ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * QueryRssi is no longer w/o hardware access, it is now implemented by command/event handling loop ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. clear prPendingCmdInfo properly ++ * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. ++ * ++ * 01 28 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * allow MCR read/write OIDs in RF test mode ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) implement timeout mechanism when OID is pending for longer than 1 second ++ * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * 2. block TX/ordinary OID when RF test mode is engaged ++ * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * 4. correct some HAL implementation ++ * ++ * 01 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer ++** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-12-10 16:54:36 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-12-09 20:04:59 GMT mtk02752 ++** only report as connected when CFG_HIF_EMULATION_TEST is set to 1 ++** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-12-08 17:39:41 GMT mtk02752 ++** wlanoidRftestQueryAutoTest could be executed without touching hardware ++** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-12-03 16:10:26 GMT mtk01461 ++** Add debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-02 22:05:33 GMT mtk02752 ++** kalOidComplete() will decrease i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-01 23:02:36 GMT mtk02752 ++** remove unnecessary spinlock ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-01 22:50:38 GMT mtk02752 ++** use TC4 for command, maintein i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-27 12:45:34 GMT mtk02752 ++** prCmdInfo should be freed when invoking wlanReleasePendingOid() to clear pending oid ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-24 19:55:51 GMT mtk02752 ++** wlanSendPacket & wlanRetransmitOfPendingFrames is only used in old data path ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-23 17:59:55 GMT mtk02752 ++** clear prPendingOID inside wlanSendCommand() when the OID didn't need to be replied. ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-23 14:45:29 GMT mtk02752 ++** add another version of wlanSendCommand() for command-sending only without blocking for response ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-17 22:40:44 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 10:14:56 GMT mtk01084 ++** modify place to invoke wlanIst ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-10-30 18:17:07 GMT mtk01084 ++** fix compiler warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-10-29 19:46:15 GMT mtk01084 ++** invoke interrupt process routine ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-10-13 21:58:24 GMT mtk01084 ++** modify for new HW architecture ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-09-09 17:26:01 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-05-20 12:21:27 GMT mtk01461 ++** Add SeqNum check when process Event Packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-05-19 10:38:44 GMT mtk01461 ++** Add wlanReleasePendingOid() for mpReset() if there is a pending OID and no available TX resource to send it. ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-04-29 15:41:34 GMT mtk01461 ++** Add handle of EVENT of CMD Result in wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-04-22 09:11:23 GMT mtk01461 ++** Fix wlanSendCommand() for Driver Domain CR ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-04-21 09:33:56 GMT mtk01461 ++** Update wlanSendCommand() for Driver Domain Response and handle Event Packet, ++** wlanQuery/SetInformation() for enqueue CMD_INFO_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-17 20:00:08 GMT mtk01461 ++** Update wlanImageSectionDownload for optimized CMD process ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-14 20:50:51 GMT mtk01426 ++** Fixed compile error ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-13 16:38:40 GMT mtk01084 ++** add wifi start function ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-13 14:26:44 GMT mtk01084 ++** modify a parameter about FW download length ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-10 21:53:42 GMT mtk01461 ++** Update wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-08 16:51:04 GMT mtk01084 ++** Update for the image download part ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-01 10:32:47 GMT mtk01461 ++** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-03-23 21:44:13 GMT mtk01461 ++** Refine TC assignment for WmmAssoc flag ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 16:51:57 GMT mtk01084 ++** modify the input argument of caller to RECLAIM_POWER_CONTROL_TO_PM() ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:27:13 GMT mtk01461 ++** Add reference code of FW Image Download ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:37 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:08 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 16:28:45 GMT mtk01426 ++** Init develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++#include "mgmt/ais_fsm.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* 6.1.1.2 Interpretation of priority parameter in MAC service primitives */ ++/* Static convert the Priority Parameter/TID(User Priority/TS Identifier) to Traffic Class */ ++const UINT_8 aucPriorityParam2TC[] = { ++ TC1_INDEX, ++ TC0_INDEX, ++ TC0_INDEX, ++ TC1_INDEX, ++ TC2_INDEX, ++ TC2_INDEX, ++ TC3_INDEX, ++ TC3_INDEX ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _CODE_MAPPING_T { ++ UINT_32 u4RegisterValue; ++ INT_32 i4TxpowerOffset; ++} CODE_MAPPING_T, *P_CODE_MAPPING_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++BOOLEAN fgIsBusAccessFailed = FALSE; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define SIGNED_EXTEND(n, _sValue) \ ++ (((_sValue) & BIT((n)-1)) ? ((_sValue) | BITS(n, 31)) : \ ++ ((_sValue) & ~BITS(n, 31))) ++ ++/* TODO: Check */ ++/* OID set handlers without the need to access HW register */ ++PFN_OID_HANDLER_FUNC apfnOidSetHandlerWOHwAccess[] = { ++ wlanoidSetChannel, ++ wlanoidSetBeaconInterval, ++ wlanoidSetAtimWindow, ++ wlanoidSetFrequency, ++}; ++ ++/* TODO: Check */ ++/* OID query handlers without the need to access HW register */ ++PFN_OID_HANDLER_FUNC apfnOidQueryHandlerWOHwAccess[] = { ++ wlanoidQueryBssid, ++ wlanoidQuerySsid, ++ wlanoidQueryInfrastructureMode, ++ wlanoidQueryAuthMode, ++ wlanoidQueryEncryptionStatus, ++ wlanoidQueryPmkid, ++ wlanoidQueryNetworkTypeInUse, ++ wlanoidQueryBssidList, ++ wlanoidQueryAcpiDevicePowerState, ++ wlanoidQuerySupportedRates, ++ wlanoidQueryDesiredRates, ++ wlanoidQuery802dot11PowerSaveProfile, ++ wlanoidQueryBeaconInterval, ++ wlanoidQueryAtimWindow, ++ wlanoidQueryFrequency, ++}; ++ ++/* OID set handlers allowed in RF test mode */ ++PFN_OID_HANDLER_FUNC apfnOidSetHandlerAllowedInRFTest[] = { ++ wlanoidRftestSetTestMode, ++ wlanoidRftestSetAbortTestMode, ++ wlanoidRftestSetAutoTest, ++ wlanoidSetMcrWrite, ++ wlanoidSetEepromWrite ++}; ++ ++/* OID query handlers allowed in RF test mode */ ++PFN_OID_HANDLER_FUNC apfnOidQueryHandlerAllowedInRFTest[] = { ++ wlanoidRftestQueryAutoTest, ++ wlanoidQueryMcrRead, ++ wlanoidQueryEepromRead ++} ++ ++; ++ ++PFN_OID_HANDLER_FUNC apfnOidWOTimeoutCheck[] = { ++ wlanoidRftestSetTestMode, ++ wlanoidRftestSetAbortTestMode, ++ wlanoidSetAcpiDevicePowerState, ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if 0 /* no use */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is a private routine, which is used to check if HW access is needed ++* for the OID query/ set handlers. ++* ++* \param[IN] pfnOidHandler Pointer to the OID handler. ++* \param[IN] fgSetInfo It is a Set information handler. ++* ++* \retval TRUE This function needs HW access ++* \retval FALSE This function does not need HW access ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) ++{ ++ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOHwAccess; ++ UINT_32 i; ++ UINT_32 u4NumOfElem; ++ ++ if (fgSetInfo) { ++ apfnOidHandlerWOHwAccess = apfnOidSetHandlerWOHwAccess; ++ u4NumOfElem = sizeof(apfnOidSetHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); ++ } else { ++ apfnOidHandlerWOHwAccess = apfnOidQueryHandlerWOHwAccess; ++ u4NumOfElem = sizeof(apfnOidQueryHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); ++ } ++ ++ for (i = 0; i < u4NumOfElem; i++) { ++ if (apfnOidHandlerWOHwAccess[i] == pfnOidHandler) ++ return FALSE; ++ } ++ ++ return TRUE; ++} /* wlanIsHandlerNeedHwAccess */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set flag for later handling card ++* ejected event. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++* ++* \note When surprised removal happens, Glue layer should invoke this ++* function to notify WPDD not to do any hw access. ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanCardEjected(IN P_ADAPTER_T prAdapter) ++{ ++ DEBUGFUNC("wlanCardEjected"); ++ /* INITLOG(("\n")); */ ++ ++ ASSERT(prAdapter); ++ ++ /* mark that the card is being ejected, NDIS will shut us down soon */ ++ nicTxRelease(prAdapter); ++ ++} /* wlanCardEjected */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Create adapter object ++* ++* \param prAdapter This routine is call to allocate the driver software objects. ++* If fails, return NULL. ++* \retval NULL If it fails, NULL is returned. ++* \retval NOT NULL If the adapter was initialized successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_ADAPTER_T prAdpater = (P_ADAPTER_T) NULL; ++ ++ DEBUGFUNC("wlanAdapterCreate"); ++ ++ do { ++ prAdpater = (P_ADAPTER_T) kalMemAlloc(sizeof(ADAPTER_T), VIR_MEM_TYPE); ++ ++ if (!prAdpater) { ++ DBGLOG(INIT, ERROR, "Allocate ADAPTER memory ==> FAILED\n"); ++ break; ++ } ++ ++ kalMemZero(prAdpater, sizeof(ADAPTER_T)); ++ prAdpater->prGlueInfo = prGlueInfo; ++ ++ } while (FALSE); ++ ++ return prAdpater; ++} /* wlanAdapterCreate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Destroy adapter object ++* ++* \param prAdapter This routine is call to destroy the driver software objects. ++* If fails, return NULL. ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter) ++{ ++ ++ if (!prAdapter) ++ return; ++ ++ kalMemFree(prAdapter, VIR_MEM_TYPE, sizeof(ADAPTER_T)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Initialize the adapter. The sequence is ++* 1. Disable interrupt ++* 2. Read adapter configuration from EEPROM and registry, verify chip ID. ++* 3. Create NIC Tx/Rx resource. ++* 4. Initialize the chip ++* 5. Initialize the protocol ++* 6. Enable Interrupt ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanAdapterStart(IN P_ADAPTER_T prAdapter, ++ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_32 i, u4Value = 0; ++ UINT_32 u4WHISR = 0; ++ UINT_8 aucTxCount[8]; ++#if CFG_ENABLE_FW_DOWNLOAD ++ UINT_32 u4FwLoadAddr, u4ImgSecSize; ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ UINT_32 j; ++ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; ++ BOOLEAN fgValidHead; ++ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); ++#endif ++#endif ++ enum Adapter_Start_Fail_Reason { ++ ALLOC_ADAPTER_MEM_FAIL, ++ DRIVER_OWN_FAIL, ++ INIT_ADAPTER_FAIL, ++ RAM_CODE_DOWNLOAD_FAIL, ++ WAIT_FIRMWARE_READY_FAIL, ++ FAIL_REASON_MAX ++ } eFailReason; ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanAdapterStart"); ++ ++ eFailReason = FAIL_REASON_MAX; ++ /* 4 <0> Reset variables in ADAPTER_T */ ++ prAdapter->fgIsFwOwn = TRUE; ++ prAdapter->fgIsEnterD3ReqIssued = FALSE; ++ ++ QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); ++ ++ /* Initialize rWlanInfo */ ++ kalMemSet(&(prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); ++ ++ /* 4 <0.1> reset fgIsBusAccessFailed */ ++ fgIsBusAccessFailed = FALSE; ++ prAdapter->ulSuspendFlag = 0; ++ ++ do { ++ u4Status = nicAllocateAdapterMemory(prAdapter); ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "nicAllocateAdapterMemory Error!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = ALLOC_ADAPTER_MEM_FAIL; ++ break; ++ } ++ ++ prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; ++ ++ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Acquiring LP-OWN %d\n", fgIsResetting); ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++#if !CFG_ENABLE_FULL_PM ++ nicpmSetDriverOwn(prAdapter); ++#endif ++ ++ if (prAdapter->fgIsFwOwn == TRUE) { ++ DBGLOG(INIT, ERROR, "nicpmSetDriverOwn() failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = DRIVER_OWN_FAIL; ++ break; ++ } ++ /* 4 <1> Initialize the Adapter */ ++ u4Status = nicInitializeAdapter(prAdapter); ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "nicInitializeAdapter failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = INIT_ADAPTER_FAIL; ++ break; ++ } ++ ++ /* init wake lock before interrupt enable and tx thread */ ++ KAL_WAKE_LOCK_INIT(prAdapter, &prAdapter->rTxThreadWakeLock, "WLAN TX THREAD"); ++ ++ /* 4 <2> Initialize System Service (MGMT Memory pool and STA_REC) */ ++ nicInitSystemService(prAdapter); ++ ++ /* 4 <3> Initialize Tx */ ++ nicTxInitialize(prAdapter); ++ wlanDefTxPowerCfg(prAdapter); ++ ++ /* 4 <4> Initialize Rx */ ++ nicRxInitialize(prAdapter); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ if (pvFwImageMapFile == NULL) { ++ DBGLOG(INIT, ERROR, "No Firmware found!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = RAM_CODE_DOWNLOAD_FAIL; ++ break; ++ } ++ ++ /* 1. disable interrupt, download is done by polling mode only */ ++ nicDisableInterrupt(prAdapter); ++ ++ /* 2. Initialize Tx Resource to fw download state */ ++ nicTxInitResetResource(prAdapter); ++ ++ /* 3. FW download here */ ++ u4FwLoadAddr = prRegInfo->u4LoadAddress; ++ ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ /* 3a. parse file header for decision of divided firmware download or not */ ++ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; ++ ++ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && ++ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, ++ u4FwImageFileLength - u4CRCOffset)) { ++ fgValidHead = TRUE; ++ } else { ++ fgValidHead = FALSE; ++ } ++ ++ /* 3b. engage divided firmware downloading */ ++ if (fgValidHead == TRUE) { ++ DBGLOG(INIT, TRACE, "wlanAdapterStart(): fgValidHead == TRUE\n"); ++ ++ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { ++ ++#if CFG_START_ADDRESS_IS_1ST_SECTION_ADDR ++ if (i == 0) { ++ prRegInfo->u4StartAddress = prFwHead->arSection[i].u4DestAddr; ++ DBGLOG(INIT, TRACE, ++ "wlanAdapterStart(): FW start address 0x%08x\n", ++ prRegInfo->u4StartAddress); ++ } ++#endif ++ ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ prFwHead->arSection[i].u4DestAddr, ++ prFwHead->arSection[i].u4Length, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ prFwHead->arSection[i].u4DestAddr + j, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset + j) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, ++ "Firmware scatter download failed %d!\n", (int)i); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ ++ /* escape from loop if any pending error occurs */ ++ if (u4Status == WLAN_STATUS_FAILURE) ++ break; ++ } ++ } else ++#endif ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ u4FwLoadAddr, ++ u4FwImageFileLength, ++ (PUINT_8) pvFwImageMapFile) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (i = 0; i < u4FwImageFileLength; i += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImageFileLength) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = u4FwImageFileLength - i; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ u4FwLoadAddr + i, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + i) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ eFailReason = RAM_CODE_DOWNLOAD_FAIL; ++ break; ++ } ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ ++ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++#endif ++ ++ /* 4. send Wi-Fi Start command */ ++ DBGLOG(INIT, INFO, " send Wi-Fi Start command\n"); ++#if CFG_OVERRIDE_FW_START_ADDRESS ++ wlanConfigWifiFunc(prAdapter, TRUE, prRegInfo->u4StartAddress); ++#else ++ wlanConfigWifiFunc(prAdapter, FALSE, 0); ++#endif ++#endif ++ ++ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); ++ /* 4 <5> check Wi-Fi FW asserts ready bit */ ++ i = 0; ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ DBGLOG(INIT, TRACE, "Ready bit asserted\n"); ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = WAIT_FIRMWARE_READY_FAIL; ++ break; ++ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { ++ UINT_32 u4MailBox0; ++ ++ nicGetMailbox(prAdapter, 0, &u4MailBox0); ++ DBGLOG(INIT, ERROR, "Waiting for Ready bit: Timeout, ID=%u\n", ++ (u4MailBox0 & 0x0000FFFF)); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = WAIT_FIRMWARE_READY_FAIL; ++ break; ++ } ++ i++; ++ kalMsleep(10); ++ } ++ ++ if (u4Status == WLAN_STATUS_SUCCESS) { ++ /* 1. reset interrupt status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ ++ /* 2. reset TX Resource for normal operation */ ++ nicTxResetResource(prAdapter); ++ ++ /* 3. query for permanent address by polling */ ++ wlanQueryPermanentAddress(prAdapter); ++ ++#if (CFG_SUPPORT_NIC_CAPABILITY == 1) ++ /* 4. query for NIC capability */ ++ wlanQueryNicCapability(prAdapter); ++#endif ++ /* 4.1 query for compiler flags */ ++ wlanQueryCompileFlags(prAdapter); ++ ++ /* 5. Override network address */ ++ wlanUpdateNetworkAddress(prAdapter); ++ ++ /* 6. indicate disconnection as default status */ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ } ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ eFailReason = WAIT_FIRMWARE_READY_FAIL; ++ break; ++ } ++ ++ /* OID timeout timer initialize */ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rOidTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) wlanReleasePendingOid, (ULONG) NULL); ++ ++ /* Return Indicated Rfb list timer */ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rReturnIndicatedRfbListTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) wlanReturnIndicatedPacketsTimeOut, (ULONG) NULL); ++ ++ /* Power state initialization */ ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ prAdapter->rAcpiState = ACPI_STATE_D0; ++ ++ /* Online scan option */ ++ if (prRegInfo->fgDisOnlineScan == 0) ++ prAdapter->fgEnOnlineScan = TRUE; ++ else ++ prAdapter->fgEnOnlineScan = FALSE; ++ ++ /* Beacon lost detection option */ ++ if (prRegInfo->fgDisBcnLostDetection != 0) ++ prAdapter->fgDisBcnLostDetection = TRUE; ++ ++ /* Load compile time constant */ ++ prAdapter->rWlanInfo.u2BeaconPeriod = CFG_INIT_ADHOC_BEACON_INTERVAL; ++ prAdapter->rWlanInfo.u2AtimWindow = CFG_INIT_ADHOC_ATIM_WINDOW; ++ ++#if 1 /* set PM parameters */ ++ prAdapter->fgEnArpFilter = prRegInfo->fgEnArpFilter; ++ prAdapter->u4PsCurrentMeasureEn = prRegInfo->u4PsCurrentMeasureEn; ++ ++ prAdapter->u4UapsdAcBmp = prRegInfo->u4UapsdAcBmp; ++ ++ prAdapter->u4MaxSpLen = prRegInfo->u4MaxSpLen; ++ ++ DBGLOG(INIT, TRACE, "[1] fgEnArpFilter:0x%x, u4UapsdAcBmp:0x%x, u4MaxSpLen:0x%x", ++ prAdapter->fgEnArpFilter, prAdapter->u4UapsdAcBmp, prAdapter->u4MaxSpLen); ++ ++ prAdapter->fgEnCtiaPowerMode = FALSE; ++ ++#if CFG_SUPPORT_DBG_POWERMODE ++ prAdapter->fgEnDbgPowerMode = FALSE; ++#endif ++ ++#endif ++ ++ /* MGMT Initialization */ ++ nicInitMGMT(prAdapter, prRegInfo); ++ ++ /* Enable WZC Disassociation */ ++ prAdapter->rWifiVar.fgSupportWZCDisassociation = TRUE; ++ ++ /* Apply Rate Setting */ ++ if ((ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate) < FIXED_RATE_NUM) ++ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate); ++ else ++ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; ++ ++ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) { ++ /* Enable Auto (Long/Short) Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; ++ } else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) ++ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) { ++ /* Force Short Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; ++ } else { ++ /* Force Long Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; ++ } ++ ++ /* Disable Hidden SSID Join */ ++ prAdapter->rWifiVar.fgEnableJoinToHiddenSSID = FALSE; ++ ++ /* Enable Short Slot Time */ ++ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable = TRUE; ++ ++ /* configure available PHY type set */ ++ nicSetAvailablePhyTypeSet(prAdapter); ++ ++#if 1 /* set PM parameters */ ++ { ++#if CFG_SUPPORT_PWR_MGT ++ prAdapter->u4PowerMode = prRegInfo->u4PowerMode; ++ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucNetTypeIndex = ++ NETWORK_TYPE_P2P_INDEX; ++ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile = ENUM_PSP_FAST_SWITCH; ++#else ++ prAdapter->u4PowerMode = ENUM_PSP_CONTINUOUS_ACTIVE; ++#endif ++ ++ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, /* FIXIT */ ++ prAdapter->u4PowerMode, FALSE); ++ } ++ ++#endif ++ ++#if CFG_SUPPORT_NVRAM ++ /* load manufacture data */ ++ wlanLoadManufactureData(prAdapter, prRegInfo); ++#endif ++ ++#ifdef CONFIG_MTK_TC1_FEATURE /* 1 //keep alive packet time change from default 30secs to 20secs. //TC01// */ ++ { ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ ++ rCmdSwCtrl.u4Id = 0x90100000; ++ rCmdSwCtrl.u4Data = 30; ++ DBGLOG(INIT, TRACE, "wlanAdapterStart Keepaliveapcket 0x%x, %d\n", ++ rCmdSwCtrl.u4Id, rCmdSwCtrl.u4Data); ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8) (&rCmdSwCtrl), NULL, 0); ++ } ++#endif ++ ++#if 0 ++ /* Update Auto rate parameters in FW */ ++ nicRlmArUpdateParms(prAdapter, ++ prRegInfo->u4ArSysParam0, ++ prRegInfo->u4ArSysParam1, prRegInfo->u4ArSysParam2, prRegInfo->u4ArSysParam3); ++#endif ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ /* clock gating workaround */ ++ prAdapter->fgIsClockGatingEnabled = FALSE; ++#endif ++ ++ } while (FALSE); ++ ++ if (u4Status == WLAN_STATUS_SUCCESS) { ++ /* restore to hardware default */ ++ HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter); ++ HAL_SET_MAILBOX_READ_CLEAR(prAdapter, FALSE); ++ ++ /* Enable interrupt */ ++ nicEnableInterrupt(prAdapter); ++ ++ } else { ++ /* release allocated memory */ ++ switch (eFailReason) { ++ case WAIT_FIRMWARE_READY_FAIL: ++ DBGLOG(INIT, ERROR, "Wait firmware ready fail, FailReason: %d\n", ++ eFailReason); ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Wait firmware ready fail!]", __func__); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ nicRxUninitialize(prAdapter); ++ nicTxRelease(prAdapter); ++ /* System Service Uninitialization */ ++ nicUninitSystemService(prAdapter); ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case RAM_CODE_DOWNLOAD_FAIL: ++ DBGLOG(INIT, ERROR, "Ram code download fail, FailReason: %d\n", ++ eFailReason); ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Ram code download fail!]", __func__); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ nicRxUninitialize(prAdapter); ++ nicTxRelease(prAdapter); ++ /* System Service Uninitialization */ ++ nicUninitSystemService(prAdapter); ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case INIT_ADAPTER_FAIL: ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case DRIVER_OWN_FAIL: ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case ALLOC_ADAPTER_MEM_FAIL: ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return u4Status; ++} /* wlanAdapterStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Uninitialize the adapter ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4Value = 0; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ ++ /* MGMT - unitialization */ ++ nicUninitMGMT(prAdapter); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D0 && ++#if (CFG_CHIP_RESET_SUPPORT == 1) ++ kalIsResetting() == FALSE && ++#endif ++ kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { ++ ++ /* 0. Disable interrupt, this can be done without Driver own */ ++ nicDisableInterrupt(prAdapter); ++ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* 1. Set CMD to FW to tell WIFI to stop (enter power off state) */ ++ /* the command must be issue to firmware even in wlanRemove() */ ++ if (prAdapter->fgIsFwOwn == FALSE && wlanSendNicPowerCtrlCmd(prAdapter, 1) == WLAN_STATUS_SUCCESS) { ++ /* 2. Clear pending interrupt */ ++ i = 0; ++ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { ++ i++; ++ }; ++ ++ /* 3. Wait til RDY bit has been cleaerd */ ++ i = 0; ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if ((u4Value & WCIR_WLAN_READY) == 0) ++ break; ++ else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE ++ || fgIsBusAccessFailed == TRUE || i >= CFG_RESPONSE_POLLING_TIMEOUT) { ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Read WCIR_WLAN_READY fail!]", __func__); ++ break; ++ } ++ i++; ++ kalMsleep(10); ++ } ++ } ++ ++ /* 4. Set Onwership to F/W */ ++ nicpmSetFWOwn(prAdapter, FALSE); ++ ++#if CFG_FORCE_RESET_UNDER_BUS_ERROR ++ if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == TRUE) { ++ /* force acquire firmware own */ ++ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ ++ /* delay for 10ms */ ++ kalMdelay(10); ++ ++ /* force firmware reset via software interrupt */ ++ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WSICR, WSICR_H2D_SW_INT_SET); ++ ++ /* force release firmware own */ ++ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); ++ } ++#endif ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ } ++ ++ nicRxUninitialize(prAdapter); ++ ++ nicTxRelease(prAdapter); ++ ++ /* System Service Uninitialization */ ++ nicUninitSystemService(prAdapter); ++ ++ nicReleaseAdapterMemory(prAdapter); ++ ++#if defined(_HIF_SPI) ++ /* Note: restore the SPI Mode Select from 32 bit to default */ ++ nicRestoreSpiDefMode(prAdapter); ++#endif ++ ++ return u4Status; ++} /* wlanAdapterStop */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by ISR (interrupt). ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \retval TRUE: NIC's interrupt ++* \retval FALSE: Not NIC's interrupt ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl) ++{ ++ ASSERT(prAdapter); ++ ++ if (fgGlobalIntrCtrl) { ++ nicDisableInterrupt(prAdapter); ++ ++ /* wlanIST(prAdapter); */ ++ } ++ ++ return TRUE; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by IST (task_let). ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanIST(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* wake up CONNSYS */ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* handle interrupts */ ++ nicProcessIST(prAdapter); ++ ++ /* re-enable HIF interrupts */ ++ nicEnableInterrupt(prAdapter); ++ ++ /* CONNSYS can decide to sleep */ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will check command queue to find out if any could be dequeued ++* and/or send to HIF to MT6620 ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param prCmdQue Pointer of Command Queue (in Glue Layer) ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue) ++{ ++ WLAN_STATUS rStatus; ++ QUE_T rTempCmdQue, rMergeCmdQue, rStandInCmdQue; ++ P_QUE_T prTempCmdQue, prMergeCmdQue, prStandInCmdQue; ++ P_QUE_ENTRY_T prQueueEntry; ++ P_CMD_INFO_T prCmdInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ ENUM_FRAME_ACTION_T eFrameAction = FRAME_ACTION_DROP_PKT; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(prCmdQue); ++ ++ /* init */ ++ prTempCmdQue = &rTempCmdQue; ++ prMergeCmdQue = &rMergeCmdQue; ++ prStandInCmdQue = &rStandInCmdQue; ++ ++ QUEUE_INITIALIZE(prTempCmdQue); ++ QUEUE_INITIALIZE(prMergeCmdQue); ++ QUEUE_INITIALIZE(prStandInCmdQue); ++ ++ /* 4 <1> Move whole list of CMD_INFO to the temp queue */ ++ /* copy all commands to prTempCmdQue and empty prCmdQue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ ++ /* 4 <2> Dequeue from head and check it is able to be sent */ ++ /* remove the first one */ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ /* check how to handle the command: drop, queue, or tx */ ++ switch (prCmdInfo->eCmdType) { ++ case COMMAND_TYPE_GENERAL_IOCTL: ++ case COMMAND_TYPE_NETWORK_IOCTL: ++ /* command packet will be always sent */ ++ eFrameAction = FRAME_ACTION_TX_PKT; ++ break; ++ ++ case COMMAND_TYPE_SECURITY_FRAME: ++ /* inquire with QM */ ++ eFrameAction = qmGetFrameAction(prAdapter, ++ prCmdInfo->eNetworkType, ++ prCmdInfo->ucStaRecIndex, NULL, FRAME_TYPE_802_1X); ++ break; ++ ++ case COMMAND_TYPE_MANAGEMENT_FRAME: ++ /* inquire with QM */ ++ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); ++ ++ eFrameAction = qmGetFrameAction(prAdapter, ++ prMsduInfo->ucNetworkType, ++ prMsduInfo->ucStaRecIndex, prMsduInfo, FRAME_TYPE_MMPDU); ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++ /* 4 <3> handling upon dequeue result */ ++ if (eFrameAction == FRAME_ACTION_DROP_PKT) { ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) ++ DBGLOG(TX, WARN, "Drop Security frame seqNo=%d\n", ++ prCmdInfo->ucCmdSeqNum); ++ wlanReleaseCommand(prAdapter, prCmdInfo); ++ } else if (eFrameAction == FRAME_ACTION_QUEUE_PKT) { ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) ++ DBGLOG(TX, INFO, "Queue Security frame seqNo=%d\n", ++ prCmdInfo->ucCmdSeqNum); ++ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); ++ } else if (eFrameAction == FRAME_ACTION_TX_PKT) { ++ /* 4 <4> Send the command */ ++ rStatus = wlanSendCommand(prAdapter, prCmdInfo); ++ ++ if (rStatus == WLAN_STATUS_RESOURCES) { ++ /* no more TC4 resource for further transmission */ ++ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); ++ DBGLOG(TX, EVENT, "No TC4 resource to send cmd, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", ++ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, ++ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); ++ break; ++ } else if (rStatus == WLAN_STATUS_PENDING) { ++ /* command packet which needs further handling upon response */ ++ /* i.e. we need to wait for FW's response */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ QUEUE_INSERT_TAIL(&(prAdapter->rPendingCmdQueue), prQueueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ } else { ++ /* send success or fail */ ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ /* send success */ ++ if (prCmdInfo->pfCmdDoneHandler) { ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, ++ prCmdInfo->pucInfoBuffer); ++ } ++ } else { ++ /* send fail */ ++ if (prCmdInfo->fgIsOid) { ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, ++ prCmdInfo->u4SetInfoLen, rStatus); ++ } ++ DBGLOG(TX, WARN, "Send CMD, status=%u, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", ++ rStatus, prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, ++ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); ++ } ++ ++ /* free the command memory */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ } else { ++ ++ /* impossible, wrong eFrameAction */ ++ ASSERT(0); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ /* 4 <3> Merge back to original queue */ ++ /* 4 <3.1> Merge prMergeCmdQue & prTempCmdQue */ ++ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prTempCmdQue); ++ ++ /* 4 <3.2> Move prCmdQue to prStandInQue, due to prCmdQue might differ due to incoming 802.1X frames */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ ++ /* ??? here, prCmdQue shall be empty, why QUEUE_MOVE_ALL ??? */ ++ QUEUE_MOVE_ALL(prStandInCmdQue, prCmdQue); ++ ++ /* 4 <3.3> concatenate prStandInQue to prMergeCmdQue */ ++ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prStandInCmdQue); ++ ++ /* 4 <3.4> then move prMergeCmdQue to prCmdQue */ ++ QUEUE_MOVE_ALL(prCmdQue, prMergeCmdQue); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanProcessCommandQueue() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will take CMD_INFO_T which carry some information of ++* incoming OID and notify the NIC_TX to send CMD. ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param prCmdInfo Pointer of P_CMD_INFO_T ++* ++* \retval WLAN_STATUS_SUCCESS : CMD was written to HIF and be freed(CMD Done) immediately. ++* \retval WLAN_STATUS_RESOURCE : No resource for current command, need to wait for previous ++* frame finishing their transmission. ++* \retval WLAN_STATUS_FAILURE : Get failure while access HIF or been rejected. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ UINT_8 ucTC; /* "Traffic Class" SW(Driver) resource classification */ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ BOOLEAN pfgIsSecOrMgmt = FALSE; ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* init */ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* DbgPrint("wlanSendCommand()\n"); */ ++ /* */ ++ /* */ ++#if DBG && 0 ++ LOG_FUNC("wlanSendCommand()\n"); ++ LOG_FUNC("CmdType %u NetworkType %u StaRecIndex %u Oid %u CID 0x%x SetQuery %u NeedResp %u CmdSeqNum %u\n", ++ prCmdInfo->eCmdType, ++ prCmdInfo->eNetworkType, ++ prCmdInfo->ucStaRecIndex, ++ prCmdInfo->fgIsOid, ++ prCmdInfo->ucCID, prCmdInfo->fgSetQuery, prCmdInfo->fgNeedResp, prCmdInfo->ucCmdSeqNum); ++#endif ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ ++ do { ++ /* <0> card removal check */ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ rStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ /* <1> Normal case of sending CMD Packet */ ++ if (!prCmdInfo->fgDriverDomainMCR) { ++ /* <1.1> Assign Traffic Class(TC) = TC4. */ ++ ucTC = TC4_INDEX; ++ ++ if ((prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) || ++ (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME)) ++ pfgIsSecOrMgmt = TRUE; ++ ++ /* <1.2> Check if pending packet or resource was exhausted */ ++ rStatus = nicTxAcquireResource(prAdapter, ucTC, pfgIsSecOrMgmt); ++ if (rStatus == WLAN_STATUS_RESOURCES) { ++ DbgPrint("NO Resource:%d\n", ucTC); ++ break; ++ } ++ /* <1.3> Forward CMD_INFO_T to NIC Layer */ ++ rStatus = nicTxCmd(prAdapter, prCmdInfo, ucTC); ++ ++ /* <1.4> Set Pending in response to Query Command/Need Response */ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) ++ rStatus = WLAN_STATUS_PENDING; ++ } ++ } ++ /* <2> "Special case" for access Driver Domain MCR */ ++ else { ++ ++ P_CMD_ACCESS_REG prCmdAccessReg; ++ ++ prCmdAccessReg = (P_CMD_ACCESS_REG) (prCmdInfo->pucInfoBuffer + CMD_HDR_SIZE); ++ ++ if (prCmdInfo->fgSetQuery) { ++ /* address is in DWORD unit */ ++ HAL_MCR_WR(prAdapter, (prCmdAccessReg->u4Address & BITS(2, 31)), ++ prCmdAccessReg->u4Data); ++ } else { ++ P_CMD_ACCESS_REG prEventAccessReg; ++ UINT_32 u4Address; ++ ++ u4Address = prCmdAccessReg->u4Address; ++ prEventAccessReg = (P_CMD_ACCESS_REG) prCmdInfo->pucInfoBuffer; ++ prEventAccessReg->u4Address = u4Address; ++ /* address is in DWORD unit */ ++ HAL_MCR_RD(prAdapter, prEventAccessReg->u4Address & BITS(2, 31), ++ &prEventAccessReg->u4Data); ++ } ++ } ++ ++ } while (FALSE); ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ nicEnableClockGating(prAdapter); ++#endif ++ ++ return rStatus; ++} /* end of wlanSendCommand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This function will release thd CMD_INFO upon its attribution ++ * ++ * \param prAdapter Pointer of Adapter Data Structure ++ * \param prCmdInfo Pointer of CMD_INFO_T ++ * ++ * \return (none) ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ switch (prCmdInfo->eCmdType) { ++ case COMMAND_TYPE_GENERAL_IOCTL: ++ case COMMAND_TYPE_NETWORK_IOCTL: ++ if (prCmdInfo->fgIsOid) { ++ /* for OID command, we need to do complete() to wake up kalIoctl() */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_FAILURE); ++ } ++ break; ++ ++ case COMMAND_TYPE_SECURITY_FRAME: ++ /* free packets in kalSecurityFrameSendComplete() */ ++ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); ++ break; ++ ++ case COMMAND_TYPE_MANAGEMENT_FRAME: ++ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; ++ ++ /* invoke callbacks */ ++ if (prMsduInfo->pfTxDoneHandler != NULL) ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); ++ ++ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ break; ++ ++ default: ++ /* impossible, shall not be here */ ++ ASSERT(0); ++ break; ++ } ++ ++ /* free command buffer and return the command header to command pool */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++} /* end of wlanReleaseCommand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will search the CMD Queue to look for the pending OID and ++* compelete it immediately when system request a reset. ++* ++* \param prAdapter ointer of Adapter Data Structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("wlanReleasePendingOid"); ++ ++ ASSERT(prAdapter); ++ ++ DBGLOG(OID, ERROR, "OID Timeout! Releasing pending OIDs ..\n"); ++ ++ do { ++ /* 1: Handle OID commands in pending queue */ ++ /* Clear Pending OID in prAdapter->rPendingCmdQueue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ /* move all pending commands to prTempCmdQue and empty prCmdQue */ ++ prCmdQue = &prAdapter->rPendingCmdQueue; ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ /* get first pending command */ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->fgIsOid) { ++ if (prCmdInfo->pfCmdTimeoutHandler) { ++ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); ++ } else { ++ /* send complete() to wake up kalIoctl() */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++ } ++ ++ /* free command memory */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } else { ++ /* nothing to do so re-queue it to prCmdQue */ ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ /* 2: Clear pending OID staying in command queue */ ++ kalOidCmdClearance(prAdapter->prGlueInfo); ++ ++ /* 3: Do complete(), do we need this? because we have completed in kalOidComplete */ ++ kalOidClearance(prAdapter->prGlueInfo); ++ ++ } while (FALSE); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will search the CMD Queue to look for the pending CMD/OID for specific ++* NETWORK TYPE and compelete it immediately when system request a reset. ++* ++* \param prAdapter ointer of Adapter Data Structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ /* only free commands from the network interface, AIS, P2P, or BOW */ ++ ++ do { ++ /* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ prCmdQue = &prAdapter->rPendingCmdQueue; ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ DBGLOG(P2P, TRACE, "Pending CMD for Network Type:%d\n", prCmdInfo->eNetworkType); ++ ++ if (prCmdInfo->eNetworkType == eNetworkType) { ++ if (prCmdInfo->pfCmdTimeoutHandler) { ++ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); ++ } else ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ } while (FALSE); ++ ++} /* wlanReleasePendingCMDbyNetwork */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return the packet buffer and reallocate one to the RFB ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param pvPacket Pointer of returned packet ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("wlanReturnPacket"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ /* free the packet */ ++ if (pvPacket) { ++ kalPacketFree(prAdapter->prGlueInfo, pvPacket); ++ RX_ADD_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT, 1); ++#if CFG_NATIVE_802_11 ++ if (GLUE_TEST_FLAG(prAdapter->prGlueInfo, GLUE_FLAG_HALT)) { ++ /*Todo:: nothing*/ ++ /*Todo:: nothing*/ ++ } ++#endif ++ } ++ ++ /* free the packet control block */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ if (!prSwRfb) { ++ ASSERT(0); ++ return; ++ } ++ ++ if (nicRxSetupRFB(prAdapter, prSwRfb)) { ++ ASSERT(0); ++ /* return; // Don't return here or it would lost SwRfb --kc */ ++ if (!timerPendingTimer(&prAdapter->rReturnIndicatedRfbListTimer)) { ++ DBGLOG(RX, WARN, ++ "wlanReturnPacket, Start ReturnIndicatedRfbList Timer (%ds)\n", ++ RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); ++ cnmTimerStartTimer(prAdapter, &prAdapter->rReturnIndicatedRfbListTimer, ++ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); ++ } ++ } ++ nicRxReturnRFB(prAdapter, prSwRfb); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return the indicated packet buffer and reallocate one to the RFB ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param pvPacket Pointer of returned packet ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_QUE_T prQueList; ++ ++ DEBUGFUNC("wlanReturnIndicatedPacketsTimeOut"); ++ DBGLOG(RX, WARN, "wlanReturnIndicatedPacketsTimeOut"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ prQueList = &prRxCtrl->rIndicatedRfbList; ++ DBGLOG(RX, WARN, "IndicatedRfbList num = %u\n", (unsigned int)prQueList->u4NumElem); ++ ++ while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rIndicatedRfbList)) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (nicRxSetupRFB(prAdapter, prSwRfb)) { ++ status = WLAN_STATUS_RESOURCES; ++ ASSERT(0); ++ } ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ if (status == WLAN_STATUS_RESOURCES) ++ break; ++ } ++ if (status == WLAN_STATUS_RESOURCES) { ++ DBGLOG(RX, WARN, "Start ReturnIndicatedRfbList Timer (%ds)\n", RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); ++ /* restart timer */ ++ cnmTimerStartTimer(prAdapter, ++ &prAdapter->rReturnIndicatedRfbListTimer, ++ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a required function that returns information about ++* the capabilities and status of the driver and/or its network adapter. ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] pfnOidQryHandler Function pointer for the OID query handler. ++* \param[IN] pvInfoBuf Points to a buffer for return the query information. ++* \param[IN] u4QueryBufferLen Specifies the number of bytes at pvInfoBuf. ++* \param[OUT] pu4QueryInfoLen Points to the number of bytes it written or is needed. ++* ++* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanQueryInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfnOidQryHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen) ++{ ++ WLAN_STATUS status = WLAN_STATUS_FAILURE; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QryInfoLen); ++ ++ /* ignore any OID request after connected, under PS current measurement mode */ ++ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for ++ * blocking OIDs during current measurement ++ */ ++ if (prAdapter->u4PsCurrentMeasureEn && ++ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) ++ return WLAN_STATUS_SUCCESS; ++#if 1 ++ /* most OID handler will just queue a command packet */ ++ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); ++#else ++ if (wlanIsHandlerNeedHwAccess(pfnOidQryHandler, FALSE)) { ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* Reset sleepy state */ ++ if (prAdapter->fgWiFiInSleepyState == TRUE) ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ ++ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ } else ++ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); ++#endif ++ ++ return status; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a required function that allows bound protocol drivers, ++* or NDIS, to request changes in the state information that the miniport ++* maintains for particular object identifiers, such as changes in multicast ++* addresses. ++* ++* \param[IN] prAdapter Pointer to the Glue info structure. ++* \param[IN] pfnOidSetHandler Points to the OID set handlers. ++* \param[IN] pvInfoBuf Points to a buffer containing the OID-specific data for the set. ++* \param[IN] u4InfoBufLen Specifies the number of bytes at prSetBuffer. ++* \param[OUT] pu4SetInfoLen Points to the number of bytes it read or is needed. ++* ++* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanSetInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfnOidSetHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status = WLAN_STATUS_FAILURE; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* ignore any OID request after connected, under PS current measurement mode */ ++ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking ++ * OIDs during current measurement ++ */ ++ if (prAdapter->u4PsCurrentMeasureEn && ++ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) ++ return WLAN_STATUS_SUCCESS; ++#if 1 ++ /* most OID handler will just queue a command packet ++ * for power state transition OIDs, handler will acquire power control by itself ++ */ ++ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); ++#else ++ if (wlanIsHandlerNeedHwAccess(pfnOidSetHandler, TRUE)) { ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* Reset sleepy state */ ++ if (prAdapter->fgWiFiInSleepyState == TRUE) ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ ++ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ } else { ++ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); ++ } ++#endif ++ ++ return status; ++} ++ ++#if CFG_SUPPORT_WAPI ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a used to query driver's config wapi mode or not ++* ++* \param[IN] prAdapter Pointer to the Glue info structure. ++* ++* \retval TRUE for use wapi mode ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->rWifiVar.rConnSettings.fgWapiMode; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to set RX filter to Promiscuous Mode. ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] fgEnablePromiscuousMode Enable/ disable RX Promiscuous Mode. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode) ++{ ++ ASSERT(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to set RX filter to allow to receive ++* broadcast address packets. ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast) ++{ ++ ASSERT(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to send out CMD_NIC_POWER_CTRL command packet ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] ucPowerMode refer to CMD/EVENT document ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode) ++{ ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucTC, ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* 1. Prepare CMD */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL))); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* 2.1 increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* 2.2 Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL)); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_NIC_POWER_CTRL; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_NIC_POWER_CTRL); ++ ++ /* 2.3 Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ kalMemZero(prWifiCmd->aucBuffer, sizeof(CMD_NIC_POWER_CTRL)); ++ ((P_CMD_NIC_POWER_CTRL) (prWifiCmd->aucBuffer))->ucPowerMode = ucPowerMode; ++ ++ /* 3. Issue CMD for entering specific power mode */ ++ ucTC = TC4_INDEX; ++ ++ while (1) { ++ /* 3.0 Removal check */ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ /* 3.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ ++ /* wait and poll tx resource */ ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ continue; ++ } ++ /* 3.2 Send CMD Info Packet */ ++ if (nicTxCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Fail to transmit CMD_NIC_POWER_CTRL command\n"); ++ status = WLAN_STATUS_FAILURE; ++ } ++ ++ break; ++ }; ++ ++ /* 4. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ /* 5. Add flag */ ++ if (ucPowerMode == 1) ++ prAdapter->fgIsEnterD3ReqIssued = TRUE; ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to check if it is RF test mode and ++* the OID is allowed to be called or not ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) ++{ ++ PFN_OID_HANDLER_FUNC *apfnOidHandlerAllowedInRFTest; ++ UINT_32 i; ++ UINT_32 u4NumOfElem; ++ ++ if (fgSetInfo) { ++ apfnOidHandlerAllowedInRFTest = apfnOidSetHandlerAllowedInRFTest; ++ u4NumOfElem = sizeof(apfnOidSetHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); ++ } else { ++ apfnOidHandlerAllowedInRFTest = apfnOidQueryHandlerAllowedInRFTest; ++ u4NumOfElem = sizeof(apfnOidQueryHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); ++ } ++ ++ for (i = 0; i < u4NumOfElem; i++) { ++ if (apfnOidHandlerAllowedInRFTest[i] == pfnOidHandler) ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to download FW image in an aggregated way ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) ++{ ++#if defined(MT6620) || defined(MT6628) ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; ++ UINT_8 ucTC, ucCmdSeqNum; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_32 u4PktCnt, u4Offset, u4Length; ++ UINT_32 u4TotalLength; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucImgSecBuf); ++ ++ pucOutputBuf = prAdapter->rTxCtrl.pucTxCoalescingBufPtr; ++ ++ DEBUGFUNC("wlanImageSectionDownloadAggregated"); ++ ++ if (u4ImgSecSize == 0) ++ return WLAN_STATUS_SUCCESS; ++ /* 1. Allocate CMD Info Packet and Pre-fill Headers */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, ++ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + ++ CMD_PKT_SIZE_FOR_IMAGE); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + CMD_PKT_SIZE_FOR_IMAGE; ++ ++ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->ucEtherTypeOffset = 0; ++ prInitHifTxHeader->ucCSflags = 0; ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; ++ ++ /* 4. Setup CMD_DOWNLOAD_BUF */ ++ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); ++ prInitCmdDownloadBuf->u4DataMode = 0 ++#if CFG_ENABLE_FW_ENCRYPTION ++ | DOWNLOAD_BUF_ENCRYPTION_MODE ++#endif ++ ; ++ ++ /* 5.0 reset loop control variable */ ++ u4TotalLength = 0; ++ u4Offset = u4PktCnt = 0; ++ ++ /* 5.1 main loop for maximize transmission count per access */ ++ while (u4Offset < u4ImgSecSize) { ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_SUCCESS) { ++ /* 5.1.1 calculate u4Length */ ++ if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < u4ImgSecSize) ++ u4Length = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4Length = u4ImgSecSize - u4Offset; ++ ++ /* 5.1.1 increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ /* 5.1.2 update HIF TX hardware header */ ++ prInitHifTxHeader->u2TxByteCount = ++ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4Length); ++ ++ /* 5.1.3 fill command header */ ++ prInitCmdDownloadBuf->u4Address = u4DestAddr + u4Offset; ++ prInitCmdDownloadBuf->u4Length = u4Length; ++ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf + u4Offset, u4Length); ++ ++ /* 5.1.4.1 copy header to coalescing buffer */ ++ kalMemCopy(pucOutputBuf + u4TotalLength, ++ (PVOID) prCmdInfo->pucInfoBuffer, ++ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF)); ++ ++ /* 5.1.4.2 copy payload to coalescing buffer */ ++ kalMemCopy(pucOutputBuf + u4TotalLength + sizeof(INIT_HIF_TX_HEADER_T) + ++ sizeof(INIT_CMD_DOWNLOAD_BUF), pucImgSecBuf + u4Offset, u4Length); ++ ++ /* 5.1.4.3 update length and other variables */ ++ u4TotalLength += ++ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4Length); ++ u4Offset += u4Length; ++ u4PktCnt++; ++ ++ if (u4Offset < u4ImgSecSize) ++ continue; ++ } else if (u4PktCnt == 0) { ++ /* no resource, so get some back */ ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ } ++ ++ if (u4PktCnt != 0) { ++ /* start transmission */ ++ HAL_WRITE_TX_PORT(prAdapter, ++ 0, ++ u4TotalLength, (PUINT_8) pucOutputBuf, prAdapter->u4CoalescingBufCachedSize); ++ ++ /* reset varaibles */ ++ u4PktCnt = 0; ++ u4TotalLength = 0; ++ } ++ } ++ ++ /* 8. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++ ++#else ++#error "Only MT6620/MT6628/MT6582 supports firmware download in an aggregated way" ++ ++ return WLAN_STATUS_FAILURE; ++ ++#endif ++} ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to download FW image. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; ++ UINT_8 ucTC, ucCmdSeqNum; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucImgSecBuf); ++ ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE); ++ ++ DEBUGFUNC("wlanImageSectionDownload"); ++ ++ if (u4ImgSecSize == 0) ++ return WLAN_STATUS_SUCCESS; ++ /* 1. Allocate CMD Info Packet and its Buffer. */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, ++ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4ImgSecSize); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4ImgSecSize; ++ ++ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* 4. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ /* 5. Setup CMD_DOWNLOAD_BUF */ ++ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); ++ prInitCmdDownloadBuf->u4Address = u4DestAddr; ++ prInitCmdDownloadBuf->u4Length = u4ImgSecSize; ++ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf, u4ImgSecSize); ++ ++ prInitCmdDownloadBuf->u4DataMode = 0 ++#if CFG_ENABLE_FW_DOWNLOAD_ACK ++ | DOWNLOAD_BUF_ACK_OPTION /* ACK needed */ ++#endif ++#if CFG_ENABLE_FW_ENCRYPTION ++ | DOWNLOAD_BUF_ENCRYPTION_MODE ++#endif ++ ; ++ ++ kalMemCopy(prInitCmdDownloadBuf->aucBuffer, pucImgSecBuf, u4ImgSecSize); ++ ++ /* 6. Send FW_Download command */ ++ while (1) { ++ /* 6.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ continue; ++ } ++ /* 6.2 Send CMD Info Packet */ ++ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); ++ } ++ ++ break; ++ }; ++ ++#if CFG_ENABLE_FW_DOWNLOAD_ACK ++ /* 7. Wait for INIT_EVENT_ID_CMD_RESULT */ ++ u4Status = wlanImageSectionDownloadStatus(prAdapter, ucCmdSeqNum); ++#endif ++ ++ /* 8. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++} ++ ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to confirm previously firmware download is done without error ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR)]; ++ UINT_32 u4RxPktLength; ++ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; ++ P_INIT_EVENT_PENDING_ERROR prEventPendingError; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_8 ucTC, ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanImageQueryStatus"); ++ ++ /* 1. Allocate CMD Info Packet and it Buffer. */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ kalMemZero(prCmdInfo, sizeof(INIT_HIF_TX_HEADER_T)); ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T); ++ ++ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* 4. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_QUERY_PENDING_ERROR; ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ /* 5. Send command */ ++ while (1) { ++ /* 5.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ continue; ++ } ++ /* 5.2 Send CMD Info Packet */ ++ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); ++ } ++ ++ break; ++ }; ++ ++ /* 6. Wait for INIT_EVENT_ID_PENDING_ERROR */ ++ do { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else if (nicRxWaitResponse(prAdapter, ++ 0, ++ aucBuffer, ++ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR), ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; ++ ++ /* EID / SeqNum check */ ++ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_PENDING_ERROR) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ prEventPendingError = ++ (P_INIT_EVENT_PENDING_ERROR) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); ++ if (prEventPendingError->ucStatus != 0) { /* 0 for download success */ ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ u4Status = WLAN_STATUS_SUCCESS; ++ } ++ } ++ } ++ } while (FALSE); ++ ++ /* 7. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++} ++ ++#else ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to confirm the status of ++* previously downloaded firmware scatter ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ucCmdSeqNum Sequence number of previous firmware scatter ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum) ++{ ++ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT)]; ++ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; ++ P_INIT_EVENT_CMD_RESULT prEventCmdResult; ++ UINT_32 u4RxPktLength; ++ WLAN_STATUS u4Status; ++ ++ ASSERT(prAdapter); ++ ++ do { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ DBGLOG(INIT, ERROR, "kalIsCardRemoved or fgIsBusAccessFailed\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } else if (nicRxWaitResponse(prAdapter, ++ 0, ++ aucBuffer, ++ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT),/* 4B + 4B */ ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "nicRxWaitResponse fail\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; ++ ++ /* EID / SeqNum check */ ++ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT) { ++ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Check EID error!]", __func__); ++ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { ++ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucSeqNum != ucCmdSeqNum\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Check SeqNum error!]", __func__); ++ } else { ++ prEventCmdResult = ++ (P_INIT_EVENT_CMD_RESULT) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); ++ if (prEventCmdResult->ucStatus != 0) { /* 0 for download success */ ++ /* ++ 0: success ++ 1: rejected by invalid param ++ 2: rejected by incorrect CRC ++ 3: rejected by decryption failure ++ 4: unknown CMD ++ */ ++ DBGLOG(INIT, ERROR, "Read Response status error = %d\n", ++ prEventCmdResult->ucStatus); ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ u4Status = WLAN_STATUS_SUCCESS; ++ } ++ } ++ } ++ } while (FALSE); ++ ++ return u4Status; ++} ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to start FW normal operation. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ P_INIT_CMD_WIFI_START prInitCmdWifiStart; ++ UINT_8 ucTC, ucCmdSeqNum; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanConfigWifiFunc"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer. */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ kalMemZero(prCmdInfo->pucInfoBuffer, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START); ++ ++ /* 2. Always use TC0 */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* 4. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_WIFI_START; ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ prInitCmdWifiStart = (P_INIT_CMD_WIFI_START) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); ++ prInitCmdWifiStart->u4Override = (fgEnable == TRUE ? 1 : 0); ++ prInitCmdWifiStart->u4Address = u4StartAddress; ++ ++ /* 5. Seend WIFI start command */ ++ while (1) { ++ /* 5.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ ++ /* wait and poll tx resource */ ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ ++ continue; ++ } ++ /* 5.2 Send CMD Info Packet */ ++ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to transmit WIFI start command\n"); ++ } ++ ++ break; ++ }; ++ ++ /* 6. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate CRC32 checksum ++* ++* @param buf Pointer to the data. ++* @param len data length ++* ++* @return crc32 value ++*/ ++/*----------------------------------------------------------------------------*/ ++static const UINT_32 crc32_ccitt_table[256] = { ++ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, ++ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, ++ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, ++ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, ++ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, ++ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, ++ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, ++ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, ++ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, ++ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, ++ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, ++ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, ++ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, ++ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, ++ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, ++ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, ++ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, ++ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, ++ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, ++ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, ++ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, ++ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, ++ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, ++ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, ++ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, ++ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, ++ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, ++ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, ++ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, ++ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, ++ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, ++ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, ++ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, ++ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, ++ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, ++ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, ++ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, ++ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, ++ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, ++ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, ++ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, ++ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, ++ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, ++ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, ++ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, ++ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, ++ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, ++ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, ++ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, ++ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, ++ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, ++ 0x2d02ef8d ++ }; ++ ++UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len) ++{ ++ UINT_32 i, crc32 = 0xFFFFFFFF; ++ ++ for (i = 0; i < len; i++) ++ crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8); ++ ++ return ~crc32; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to process queued RX packets ++* ++* @param prAdapter Pointer to the Adapter structure. ++* prSwRfbListHead Pointer to head of RX packets link list ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) ++{ ++ P_SW_RFB_T prSwRfb, prNextSwRfb; ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfbListHead); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ prSwRfb = prSwRfbListHead; ++ ++ do { ++ /* save next first */ ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); ++ ++ switch (prSwRfb->eDst) { ++ case RX_PKT_DESTINATION_HOST: ++ /* to host */ ++ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_FORWARD: ++ /* need ot forward */ ++ nicRxProcessForwardPkt(prAdapter, prSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: ++ /* to host and forward */ ++ nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_NULL: ++ /* free it */ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ break; ++ ++ default: ++ break; ++ } ++ ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4DequeuedCnt++; ++#endif ++ ++ /* check next queued packet */ ++ prSwRfb = prNextSwRfb; ++ } while (prSwRfb); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to purge queued TX packets ++* by indicating failure to OS and returned to free list ++* ++* @param prAdapter Pointer to the Adapter structure. ++* prMsduInfoListHead Pointer to head of TX packets link list ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfoListHead); ++ ++ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); ++ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if the OID handler needs timeout ++* ++* @param prAdapter Pointer to the Adapter structure. ++* pfnOidHandler Pointer to the OID handler ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler) ++{ ++ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOTimeoutCheck; ++ UINT_32 i; ++ UINT_32 u4NumOfElem; ++ ++ apfnOidHandlerWOTimeoutCheck = apfnOidWOTimeoutCheck; ++ u4NumOfElem = sizeof(apfnOidWOTimeoutCheck) / sizeof(PFN_OID_HANDLER_FUNC); ++ ++ /* skip some OID timeout checks ? */ ++ for (i = 0; i < u4NumOfElem; i++) { ++ if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler) ++ return FALSE; ++ } ++ ++ /* set timer if need timeout check */ ++ /* cnmTimerStartTimer(prAdapter, */ ++ /* &(prAdapter->rOidTimeoutTimer), */ ++ /* 1000); */ ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rOidTimeoutTimer), 2000); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to clear any pending OID timeout check ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rOidTimeoutTimer)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update network address in firmware domain ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return WLAN_STATUS_FAILURE The request could not be processed ++* WLAN_STATUS_PENDING The request has been queued for later processing ++* WLAN_STATUS_SUCCESS The request has been processed ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter) ++{ ++ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ PARAM_MAC_ADDRESS rMacAddr = {0}; ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_BASIC_CONFIG prCmdBasicConfig; ++ UINT_32 u4SysTime; ++ ++ DEBUGFUNC("wlanUpdateNetworkAddress"); ++ ++ ASSERT(prAdapter); ++ ++ if (kalRetrieveNetworkAddress(prAdapter->prGlueInfo, &rMacAddr) == FALSE || IS_BMCAST_MAC_ADDR(rMacAddr) ++ || EQUAL_MAC_ADDR(aucZeroMacAddr, rMacAddr)) { ++ /* eFUSE has a valid address, don't do anything */ ++ if (prAdapter->fgIsEmbbededMacAddrValid == TRUE) { ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, INFO, "Using embedded MAC address"); ++#endif ++ return WLAN_STATUS_SUCCESS; ++ } ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, TRACE, "Using dynamically generated MAC address"); ++#endif ++ /* dynamic generate */ ++ u4SysTime = kalGetTimeTick(); ++ ++ rMacAddr[0] = 0x00; ++ rMacAddr[1] = 0x08; ++ rMacAddr[2] = 0x22; ++ ++ kalMemCopy(&rMacAddr[3], &u4SysTime, 3); ++ } else { ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, INFO, "Using host-supplied MAC address"); ++#endif ++ } ++ ++ /* allocate command memory */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* configure CMD_BASIC_CONFIG */ ++ prCmdBasicConfig = (P_CMD_BASIC_CONFIG) (prWifiCmd->aucBuffer); ++ kalMemCopy(&(prCmdBasicConfig->rMyMacAddr), &rMacAddr, PARAM_MAC_ADDR_LEN); ++ prCmdBasicConfig->ucNative80211 = 0; ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum = 0; ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum = 0; ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(2); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(1); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(0); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(2); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(1); ++ ++ if (prAdapter->u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(0); ++#endif ++ ++ /* send the command to FW */ ++ if (wlanSendCommand(prAdapter, prCmdInfo) == WLAN_STATUS_RESOURCES) { ++ ++ /* backup the command to wait response */ ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryAddress; ++ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ return WLAN_STATUS_PENDING; ++ } ++ /* send ok without response */ ++ nicCmdEventQueryAddress(prAdapter, prCmdInfo, (PUINT_8) prCmdBasicConfig); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if the device is in RF test mode ++* ++* @param pfnOidHandler Pointer to the OID handler ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->fgTestMode; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to identify 802.1x and Bluetooth-over-Wi-Fi ++* security frames, and queued into command queue for strict ordering ++* due to 802.1x frames before add-key OIDs are not to be encrypted ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prPacket Pointer of native packet ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket) ++{ ++ UINT_8 ucPriorityParam; ++ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; ++ BOOLEAN fgIs1x = FALSE; ++ BOOLEAN fgIsPAL = FALSE; ++ UINT_32 u4PacketLen; ++ ULONG u4SysTime; ++ UINT_8 ucNetworkType; ++ P_CMD_INFO_T prCmdInfo; ++ UINT_8 ucCmdSeqNo = 0; ++ ++ /* 1x data packets */ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prPacket); ++ ++ /* retrieve some information for packet classification */ ++ if (kalQoSFrameClassifierAndPacketInfo(prAdapter->prGlueInfo, ++ prPacket, ++ &ucPriorityParam, ++ &u4PacketLen, ++ aucEthDestAddr, ++ &fgIs1x, ++ &fgIsPAL, ++ &ucNetworkType, ++ &ucCmdSeqNo) == TRUE) { ++ /* almost TRUE except frame length < 14B */ ++ ++ if (fgIs1x == FALSE) ++ return FALSE; ++ ++ /* get a free command entry */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ if (prCmdInfo) { ++ P_STA_RECORD_T prStaRec; ++ ++ /* fill arrival time */ ++ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); ++ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); ++ ++ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); ++ ++ prCmdInfo->eCmdType = COMMAND_TYPE_SECURITY_FRAME; ++ prCmdInfo->u2InfoBufLen = (UINT_16) u4PacketLen; ++ prCmdInfo->pucInfoBuffer = NULL; ++ prCmdInfo->prPacket = prPacket; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNo; ++#if 0 ++ prCmdInfo->ucStaRecIndex = qmGetStaRecIdx(prAdapter, ++ aucEthDestAddr, ++ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType); ++#endif ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType, ++ aucEthDestAddr); ++ if (prStaRec) ++ prCmdInfo->ucStaRecIndex = prStaRec->ucIndex; ++ else ++ prCmdInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; ++ ++ prCmdInfo->eNetworkType = (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType; ++ prCmdInfo->pfCmdDoneHandler = wlanSecurityFrameTxDone; ++ prCmdInfo->pfCmdTimeoutHandler = wlanSecurityFrameTxTimeout; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ ++ /* ++ queue the 1x packet and we will send the packet to CONNSYS by ++ using command queue ++ */ ++ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* TRUE: means we have already handled it in the function */ ++ return TRUE; ++ } ++ ++ /* no memory, why assert ? can skip the packet ? */ ++ ASSERT(0); ++ return FALSE; ++ } ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi ++* security frames has been sent to firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prCmdInfo Pointer of CMD_INFO_T ++* @param pucEventBuf meaningless, only for API compatibility ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->eNetworkType == NETWORK_TYPE_AIS_INDEX && ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure) { ++ ++ /* AIS counter measure so change RSN FSM to SEND_DEAUTH state */ ++ P_STA_RECORD_T prSta = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); ++ ++ if (prSta) { ++ kalMsleep(10); ++ secFsmEventEapolTxDone(prAdapter, prSta, TX_RESULT_SUCCESS); ++ } ++ } ++ ++ /* free the packet */ ++ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_SUCCESS); ++ DBGLOG(TX, INFO, "Security frame tx done, SeqNum: %d\n", prCmdInfo->ucCmdSeqNum); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi ++* security frames has failed sending to firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prCmdInfo Pointer of CMD_INFO_T ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* free the packet */ ++ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called before AIS is starting a new scan ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter) ++{ ++ BOOLEAN fgKeepCurrOne = FALSE; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ /* clear scanning result except current one */ ++ /* copy current one to prAdapter->rWlanInfo.arScanResult[0] */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { ++ fgKeepCurrOne = TRUE; ++ ++ if (i != 0) { ++ /* copy structure */ ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[0]), ++ &(prAdapter->rWlanInfo.arScanResult[i]), ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ } ++ ++ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { ++ if (prAdapter->rWlanInfo.apucScanResultIEs[i] != ++ &(prAdapter->rWlanInfo.aucScanIEBuf[0])) { ++ /* move IEs to head */ ++ kalMemCopy(prAdapter->rWlanInfo.aucScanIEBuf, ++ prAdapter->rWlanInfo.apucScanResultIEs[i], ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength); ++ } ++ /* modify IE pointer */ ++ prAdapter->rWlanInfo.apucScanResultIEs[0] = ++ &(prAdapter->rWlanInfo.aucScanIEBuf[0]); ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[0] = NULL; ++ } ++ ++ break; ++ } ++ } ++ } ++ ++ if (fgKeepCurrOne == TRUE) { ++ prAdapter->rWlanInfo.u4ScanResultNum = 1; ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage = ALIGN_4(prAdapter->rWlanInfo.arScanResult[0].u4IELength); ++ } else { ++ prAdapter->rWlanInfo.u4ScanResultNum = 0; ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage = 0; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when AIS received a beacon timeout event ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param arBSSID MAC address of the specified BSS ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID) ++{ ++ UINT_32 i, j, u4IELength = 0, u4IEMoveLength; ++ PUINT_8 pucIEPtr; ++ ++ ASSERT(prAdapter); ++ ++ /* clear the scanning result for arBSSID */ ++ i = 0; ++ while (1) { ++ if (i >= prAdapter->rWlanInfo.u4ScanResultNum) ++ break; ++ ++ if (EQUAL_MAC_ADDR(arBSSID, prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { ++ ++ /* backup current IE length */ ++ u4IELength = ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4IELength); ++ pucIEPtr = prAdapter->rWlanInfo.apucScanResultIEs[i]; ++ ++ /* removed from middle */ ++ for (j = i + 1; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[j - 1]), ++ &(prAdapter->rWlanInfo.arScanResult[j]), ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[j - 1] = ++ prAdapter->rWlanInfo.apucScanResultIEs[j]; ++ } ++ ++ prAdapter->rWlanInfo.u4ScanResultNum--; ++ ++ /* remove IE buffer if needed := move rest of IE buffer */ ++ if (u4IELength > 0) { ++ u4IEMoveLength = prAdapter->rWlanInfo.u4ScanIEBufferUsage - ++ (((ULONG) pucIEPtr) + (ULONG) u4IELength - ++ ((ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])))); ++ ++ kalMemCopy(pucIEPtr, pucIEPtr + u4IELength, u4IEMoveLength); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4IELength; ++ ++ /* correction of pointers to IE buffer */ ++ for (j = 0; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { ++ if (prAdapter->rWlanInfo.apucScanResultIEs[j] > pucIEPtr) { ++ prAdapter->rWlanInfo.apucScanResultIEs[j] = ++ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[j]) - ++ u4IELength); ++ } ++ } ++ } ++ } ++ ++ i++; ++ } ++ ++} ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter) ++{ ++#if 0 ++ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; ++ ++ prMsgFuncSwitch = ++ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ if (!prMsgFuncSwitch) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prMsgFuncSwitch->fgIsFuncOn = TRUE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ ++} ++ ++VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter) ++{ ++ ++ P_MSG_P2P_CONNECTION_REQUEST_T prMsgConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; ++ ++ prMsgConnReq = ++ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ if (!prMsgConnReq) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prMsgConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; ++ ++ /*=====Param Modified for test=====*/ ++ COPY_MAC_ADDR(prMsgConnReq->aucDeviceID, aucTargetDeviceID); ++ prMsgConnReq->fgIsTobeGO = TRUE; ++ prMsgConnReq->fgIsPersistentGroup = FALSE; ++ ++ /*=====Param Modified for test=====*/ ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgConnReq, MSG_SEND_METHOD_BUF); ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve permanent address from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_EVENT_BASIC_CONFIG prEventBasicConfig; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanQueryPermanentAddress"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* send the command */ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ /* wait for response */ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG), /* 8B + 12B */ ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ if (prEvent->ucEID != EVENT_ID_BASIC_CONFIG) ++ return WLAN_STATUS_FAILURE; ++ ++ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (prEvent->aucBuffer); ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, &(prEventBasicConfig->rMyMacAddr)); ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, &(prEventBasicConfig->rMyMacAddr)); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve NIC capability from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_32 u4FwIDVersion = 0; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_EVENT_NIC_CAPABILITY prEventNicCapability; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanQueryNicCapability"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY)); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = 0; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* send the command */ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ /* wait for FW response */ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY), ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY) ++ return WLAN_STATUS_FAILURE; ++ ++ prEventNicCapability = (P_EVENT_NIC_CAPABILITY) (prEvent->aucBuffer); ++ ++ prAdapter->rVerInfo.u2FwProductID = prEventNicCapability->u2ProductID; ++ prAdapter->rVerInfo.u2FwOwnVersion = prEventNicCapability->u2FwVersion; ++ prAdapter->rVerInfo.u2FwPeerVersion = prEventNicCapability->u2DriverVersion; ++ prAdapter->fgIsHw5GBandDisabled = (BOOLEAN) prEventNicCapability->ucHw5GBandDisabled; ++ prAdapter->fgIsEepromUsed = (BOOLEAN) prEventNicCapability->ucEepromUsed; ++ prAdapter->fgIsEfuseValid = (BOOLEAN) prEventNicCapability->ucEfuseValid; ++ prAdapter->fgIsEmbbededMacAddrValid = (BOOLEAN) prEventNicCapability->ucMacAddrValid; ++ ++ u4FwIDVersion = (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); ++ mtk_wcn_wmt_set_wifi_ver(u4FwIDVersion); ++#if (CFG_SUPPORT_TDLS == 1) ++ if (prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_TDLS)) ++ prAdapter->fgTdlsIsSup = TRUE; ++ DBGLOG(TDLS, TRACE, " support flag: 0x%x\n", prEventNicCapability->ucFeatureSet); ++#else ++ prAdapter->fgTdlsIsSup = 0; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ if (!(prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_5G_SUPPORT))) ++ prAdapter->fgEnable5GBand = FALSE; /* firmware does not support */ ++ ++#if CFG_ENABLE_CAL_LOG ++ DBGLOG(INIT, LOUD, " RF CAL FAIL = (%d),BB CAL FAIL = (%d)\n", ++ prEventNicCapability->ucRfCalFail, prEventNicCapability->ucBbCalFail); ++#endif ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve NIC capability from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanQueryDebugCode"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE; ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_GET_DEBUG_CODE; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = 0; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* send the command */ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve compiler flag from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryCompileFlag(IN P_ADAPTER_T prAdapter, IN UINT_32 u4QueryID, OUT PUINT_32 pu4CompilerFlag) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_CMD_SW_DBG_CTRL_T prCmdNicCompileFlag, prEventNicCompileFlag; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC(__func__); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T)); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_SW_DBG_CTRL; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = 0; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* Fill up SW CR */ ++ prCmdNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prWifiCmd->aucBuffer); ++ ++ prCmdNicCompileFlag->u4Id = u4QueryID; ++ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T), ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ if (prEvent->ucEID != EVENT_ID_SW_DBG_CTRL) ++ return WLAN_STATUS_FAILURE; ++ ++ prEventNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prEvent->aucBuffer); ++ ++ *pu4CompilerFlag = prEventNicCompileFlag->u4Data; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter) ++{ ++ wlanQueryCompileFlag(prAdapter, 0xA0240000, &prAdapter->u4FwCompileFlag0); ++ wlanQueryCompileFlag(prAdapter, 0xA0240001, &prAdapter->u4FwCompileFlag1); ++ ++ DBGLOG(INIT, TRACE, ++ "Compile Flags: 0x%08x 0x%08x\n", prAdapter->u4FwCompileFlag0, prAdapter->u4FwCompileFlag1); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if defined(MT6628) ++static INT_32 wlanChangeCodeWord(INT_32 au4Input) ++{ ++ ++ UINT_16 i; ++#if TXPWR_USE_PDSLOPE ++ CODE_MAPPING_T arCodeTable[] = { ++ {0X100, -40}, ++ {0X104, -35}, ++ {0X128, -30}, ++ {0X14C, -25}, ++ {0X170, -20}, ++ {0X194, -15}, ++ {0X1B8, -10}, ++ {0X1DC, -5}, ++ {0, 0}, ++ {0X24, 5}, ++ {0X48, 10}, ++ {0X6C, 15}, ++ {0X90, 20}, ++ {0XB4, 25}, ++ {0XD8, 30}, ++ {0XFC, 35}, ++ {0XFF, 40}, ++ ++ }; ++#else ++ CODE_MAPPING_T arCodeTable[] = { ++ {0X100, 0x80}, ++ {0X104, 0x80}, ++ {0X128, 0x80}, ++ {0X14C, 0x80}, ++ {0X170, 0x80}, ++ {0X194, 0x94}, ++ {0X1B8, 0XB8}, ++ {0X1DC, 0xDC}, ++ {0, 0}, ++ {0X24, 0x24}, ++ {0X48, 0x48}, ++ {0X6C, 0x6c}, ++ {0X90, 0x7F}, ++ {0XB4, 0x7F}, ++ {0XD8, 0x7F}, ++ {0XFC, 0x7F}, ++ {0XFF, 0x7F}, ++ ++ }; ++#endif ++ ++ for (i = 0; i < sizeof(arCodeTable) / sizeof(CODE_MAPPING_T); i++) { ++ ++ if (arCodeTable[i].u4RegisterValue == au4Input) ++ return arCodeTable[i].i4TxpowerOffset; ++ } ++ ++ return 0; ++} ++#endif ++ ++#if TXPWR_USE_PDSLOPE ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_CMD_ACCESS_REG prCmdMcrQuery; ++ ++ ASSERT(prAdapter); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_ACCESS_REG; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_ACCESS_REG); ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ kalMemCopy(prWifiCmd->aucBuffer, prMcrRdInfo, sizeof(CMD_ACCESS_REG)); ++ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG), &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ ++ if (prEvent->ucEID != EVENT_ID_ACCESS_REG) ++ return WLAN_STATUS_FAILURE; ++ ++ prCmdMcrQuery = (P_CMD_ACCESS_REG) (prEvent->aucBuffer); ++ prMcrRdInfo->u4McrOffset = prCmdMcrQuery->u4Address; ++ prMcrRdInfo->u4McrData = prCmdMcrQuery->u4Data; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++static INT_32 wlanIntRound(INT_32 au4Input) ++{ ++ ++ if (au4Input >= 0) { ++ if ((au4Input % 10) == 5) { ++ au4Input = au4Input + 5; ++ return au4Input; ++ } ++ } ++ ++ if (au4Input < 0) { ++ if ((au4Input % 10) == -5) { ++ au4Input = au4Input - 5; ++ return au4Input; ++ } ++ } ++ ++ return au4Input; ++} ++ ++static INT_32 wlanCal6628EfuseForm(IN P_ADAPTER_T prAdapter, INT_32 au4Input) ++{ ++ ++ PARAM_MCR_RW_STRUCT_T rMcrRdInfo; ++ INT_32 au4PdSlope, au4TxPwrOffset, au4TxPwrOffset_Round; ++ INT_8 auTxPwrOffset_Round; ++ ++ rMcrRdInfo.u4McrOffset = 0x60205c68; ++ rMcrRdInfo.u4McrData = 0; ++ au4TxPwrOffset = au4Input; ++ wlanQueryPdMcr(prAdapter, &rMcrRdInfo); ++ ++ au4PdSlope = (rMcrRdInfo.u4McrData) & BITS(0, 6); ++ au4TxPwrOffset_Round = wlanIntRound((au4TxPwrOffset * au4PdSlope)) / 10; ++ ++ au4TxPwrOffset_Round = -au4TxPwrOffset_Round; ++ ++ if (au4TxPwrOffset_Round < -128) ++ au4TxPwrOffset_Round = 128; ++ else if (au4TxPwrOffset_Round < 0) ++ au4TxPwrOffset_Round += 256; ++ else if (au4TxPwrOffset_Round > 127) ++ au4TxPwrOffset_Round = 127; ++ ++ auTxPwrOffset_Round = (UINT8) au4TxPwrOffset_Round; ++ ++ return au4TxPwrOffset_Round; ++} ++ ++#endif ++ ++#if defined(MT6628) ++static VOID wlanChangeNvram6620to6628(PUINT_8 pucEFUSE) ++{ ++ ++#define EFUSE_CH_OFFSET1_L_MASK_6620 BITS(0, 8) ++#define EFUSE_CH_OFFSET1_L_SHIFT_6620 0 ++#define EFUSE_CH_OFFSET1_M_MASK_6620 BITS(9, 17) ++#define EFUSE_CH_OFFSET1_M_SHIFT_6620 9 ++#define EFUSE_CH_OFFSET1_H_MASK_6620 BITS(18, 26) ++#define EFUSE_CH_OFFSET1_H_SHIFT_6620 18 ++#define EFUSE_CH_OFFSET1_VLD_MASK_6620 BIT(27) ++#define EFUSE_CH_OFFSET1_VLD_SHIFT_6620 27 ++ ++#define EFUSE_CH_OFFSET1_L_MASK_5931 BITS(0, 7) ++#define EFUSE_CH_OFFSET1_L_SHIFT_5931 0 ++#define EFUSE_CH_OFFSET1_M_MASK_5931 BITS(8, 15) ++#define EFUSE_CH_OFFSET1_M_SHIFT_5931 8 ++#define EFUSE_CH_OFFSET1_H_MASK_5931 BITS(16, 23) ++#define EFUSE_CH_OFFSET1_H_SHIFT_5931 16 ++#define EFUSE_CH_OFFSET1_VLD_MASK_5931 BIT(24) ++#define EFUSE_CH_OFFSET1_VLD_SHIFT_5931 24 ++#define EFUSE_ALL_CH_OFFSET1_MASK_5931 BITS(25, 27) ++#define EFUSE_ALL_CH_OFFSET1_SHIFT_5931 25 ++ ++ INT_32 au4ChOffset; ++ INT_16 au2ChOffsetL, au2ChOffsetM, au2ChOffsetH; ++ ++ au4ChOffset = *(UINT_32 *) (pucEFUSE + 72); ++ ++ if ((au4ChOffset & EFUSE_CH_OFFSET1_VLD_MASK_6620) && ((*(UINT_32 *) (pucEFUSE + 28)) == 0)) { ++ ++ au2ChOffsetL = ((au4ChOffset & EFUSE_CH_OFFSET1_L_MASK_6620) >> EFUSE_CH_OFFSET1_L_SHIFT_6620); ++ ++ au2ChOffsetM = ((au4ChOffset & EFUSE_CH_OFFSET1_M_MASK_6620) >> EFUSE_CH_OFFSET1_M_SHIFT_6620); ++ ++ au2ChOffsetH = ((au4ChOffset & EFUSE_CH_OFFSET1_H_MASK_6620) >> EFUSE_CH_OFFSET1_H_SHIFT_6620); ++ ++ au2ChOffsetL = wlanChangeCodeWord(au2ChOffsetL); ++ au2ChOffsetM = wlanChangeCodeWord(au2ChOffsetM); ++ au2ChOffsetH = wlanChangeCodeWord(au2ChOffsetH); ++ ++ au4ChOffset = 0; ++ au4ChOffset |= *(UINT_32 *) (pucEFUSE + 72) ++ >> (EFUSE_CH_OFFSET1_VLD_SHIFT_6620 - ++ EFUSE_CH_OFFSET1_VLD_SHIFT_5931) & EFUSE_CH_OFFSET1_VLD_MASK_5931; ++ ++ au4ChOffset |= ++ ((((UINT_32) au2ChOffsetL) << EFUSE_CH_OFFSET1_L_SHIFT_5931) & EFUSE_CH_OFFSET1_L_MASK_5931); ++ au4ChOffset |= ++ ((((UINT_32) au2ChOffsetM) << EFUSE_CH_OFFSET1_M_SHIFT_5931) & EFUSE_CH_OFFSET1_M_MASK_5931); ++ au4ChOffset |= ++ ((((UINT_32) au2ChOffsetH) << EFUSE_CH_OFFSET1_H_SHIFT_5931) & EFUSE_CH_OFFSET1_H_MASK_5931); ++ ++ *((INT_32 *) ((pucEFUSE + 28))) = au4ChOffset; ++ ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to load manufacture data from NVRAM ++* if available and valid ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prRegInfo Pointer of REG_INFO_T ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) ++{ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ CMD_RDD_CH_T rRddParam; ++#endif ++ ++ ASSERT(prAdapter); ++ ++ /* 1. Version Check */ ++ kalGetConfigurationVersion(prAdapter->prGlueInfo, ++ &(prAdapter->rVerInfo.u2Part1CfgOwnVersion), ++ &(prAdapter->rVerInfo.u2Part1CfgPeerVersion), ++ &(prAdapter->rVerInfo.u2Part2CfgOwnVersion), ++ &(prAdapter->rVerInfo.u2Part2CfgPeerVersion)); ++ ++#if (CFG_SW_NVRAM_VERSION_CHECK == 1) ++ if (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion ++ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION ++ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION) { ++ return WLAN_STATUS_FAILURE; ++ } ++#endif ++ ++ /* MT6620 E1/E2 would be ignored directly */ ++ if (prAdapter->rVerInfo.u2Part1CfgOwnVersion == 0x0001) { ++ prRegInfo->ucTxPwrValid = 1; ++ } else { ++ /* 2. Load TX power gain parameters if valid */ ++ if (prRegInfo->ucTxPwrValid != 0) { ++ /* send to F/W */ ++ nicUpdateTxPower(prAdapter, (P_CMD_TX_PWR_T) (&(prRegInfo->rTxPwr))); ++ } ++ } ++ ++ /* Workaround for supporting 5G */ ++ prRegInfo->ucEnable5GBand = 1; ++ prRegInfo->ucSupport5GBand = 1; ++ ++ /* 3. Check if needs to support 5GHz */ ++ /* if(prRegInfo->ucEnable5GBand) { // Frank workaround */ ++ if (1) { ++ /* check if it is disabled by hardware */ ++ if (prAdapter->fgIsHw5GBandDisabled || prRegInfo->ucSupport5GBand == 0) ++ prAdapter->fgEnable5GBand = FALSE; ++ else ++ prAdapter->fgEnable5GBand = TRUE; ++ } else ++ prAdapter->fgEnable5GBand = FALSE; ++ /* Workaround for supporting 5G */ ++ prAdapter->fgEnable5GBand = TRUE; ++/* ++ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d)\n", ++ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled); ++*/ ++ /* 4. Send EFUSE data */ ++#if defined(MT6628) ++ wlanChangeNvram6620to6628(prRegInfo->aucEFUSE); ++#endif ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PHY_PARAM, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_PHY_PARAM_T), (PUINT_8) (prRegInfo->aucEFUSE), NULL, 0); ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ rRddParam.ucRddTestMode = (UINT_8) prRegInfo->u4RddTestMode; ++ rRddParam.ucRddShutCh = (UINT_8) prRegInfo->u4RddShutFreq; ++ rRddParam.ucRddStartCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStartFreq); ++ rRddParam.ucRddStopCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStopFreq); ++ rRddParam.ucRddDfs = (UINT_8) prRegInfo->u4RddDfs; ++ prAdapter->ucRddStatus = 0; ++ nicUpdateRddTestMode(prAdapter, (P_CMD_RDD_CH_T) (&rRddParam)); ++#endif ++ ++ /* 5. Get 16-bits Country Code and Bandwidth */ ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode = ++ (((UINT_16) prRegInfo->au2CountryCode[0]) << 8) | (((UINT_16) prRegInfo->au2CountryCode[1]) & BITS(0, 7)); ++ ++ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d) CountryCode(0x%x 0x%x)\n", ++ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled, ++ prRegInfo->au2CountryCode[0], prRegInfo->au2CountryCode[1]); ++ ++#if 0 /* Bandwidth control will be controlled by GUI. 20110930 ++ * So ignore the setting from registry/NVRAM ++ */ ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = ++ prRegInfo->uc2G4BwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; ++ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = ++ prRegInfo->uc5GBwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; ++#endif ++ ++ /* 6. Set domain and channel information to chip */ ++ rlmDomainSendCmd(prAdapter, FALSE); ++ /* Update supported channel list in channel table */ ++ wlanUpdateChannelTable(prAdapter->prGlueInfo); ++ ++ /* 7. Set band edge tx power if available */ ++ if (prRegInfo->fg2G4BandEdgePwrUsed) { ++ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; ++ ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK = prRegInfo->cBandEdgeMaxPwrCCK; ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 = prRegInfo->cBandEdgeMaxPwrOFDM20; ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 = prRegInfo->cBandEdgeMaxPwrOFDM40; ++ ++ DBGLOG(INIT, TRACE, "NVRAM 2G Bandedge CCK(%d) HT20(%d)HT40(%d)\n", ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK, ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_EDGE_TXPWR_LIMIT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); ++ } ++ /* 8. set 5G band edge tx power if available (add for 6625) */ ++ if (prAdapter->fgEnable5GBand) { ++#define NVRAM_5G_TX_BANDEDGE_VALID_OFFSET 10 ++#define NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET 11 ++#define NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET 12 ++ ++ if (prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_VALID_OFFSET]) { ++ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; ++ ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 ++ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET]; ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 ++ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET]; ++ ++ DBGLOG(INIT, TRACE, "NVRAM 5G Bandedge HT20(%d)HT40(%d)\n", ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); ++ } ++ } ++ /* 9. set RSSI compensation */ ++ /* DBGLOG(INIT, INFO, ("[frank] RSSI valid(%d) 2G(%d) 5G(%d)", ++ prRegInfo->fgRssiCompensationValidbit, ++ prRegInfo->uc2GRssiCompensation, ++ prRegInfo->uc5GRssiCompensation)); */ ++ if (prRegInfo->fgRssiCompensationValidbit) { ++ CMD_RSSI_COMPENSATE_T rCmdRssiCompensate; ++ ++ rCmdRssiCompensate.uc2GRssiCompensation = prRegInfo->uc2GRssiCompensation; ++ rCmdRssiCompensate.uc5GRssiCompensation = prRegInfo->uc5GRssiCompensation; ++ ++ DBGLOG(INIT, LOUD, "NVRAM RSSI Comp. 2G(%d)5G(%d)\n", ++ rCmdRssiCompensate.uc2GRssiCompensation, rCmdRssiCompensate.uc5GRssiCompensation); ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RSSI_COMPENSATE, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_RSSI_COMPENSATE_T), (PUINT_8)&rCmdRssiCompensate, NULL, 0); ++ } ++ /* 10. notify FW Band Support 5G */ ++ if (prAdapter->fgEnable5GBand) { ++ CMD_BAND_SUPPORT_T rCmdBandSupport; ++ ++ rCmdBandSupport.uc5GBandSupport = TRUE; ++ DBGLOG(INIT, TRACE, "NVRAM 5G BandSupport\n"); ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BAND_SUPPORT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_BAND_SUPPORT_T), (PUINT_8)&rCmdBandSupport, NULL, 0); ++ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check ++* Media Stream Mode is set to non-default value or not, ++* and clear to default value if above criteria is met ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return TRUE ++* The media stream mode was non-default value and has been reset ++* FALSE ++* The media stream mode is default value ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode != 0) { ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; ++ ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if any pending timer has expired ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* check timer status */ ++ cnmTimerDoTimeOutCheck(prAdapter); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if any pending mailbox message ++* to be handled ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { /* MBOX_ID_TOTAL_NUM = 1 */ ++ mboxRcvAllMsg(prAdapter, (ENUM_MBOX_ID_T) i); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to enqueue a single TX packet into CORE ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* prNativePacket Pointer of Native Packet ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_RESOURCES ++* WLAN_STATUS_INVALID_PACKET ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* get a free packet header */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ if (prMsduInfo == NULL) ++ return WLAN_STATUS_RESOURCES; ++ ++ prMsduInfo->eSrc = TX_PACKET_OS; ++ ++ if (nicTxFillMsduInfo(prAdapter, prMsduInfo, prNativePacket) == FALSE) { ++ /* packet is not extractable */ ++ ++ /* fill fails */ ++ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_INVALID_PACKET); ++ ++ nicTxReturnMsduInfo(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_INVALID_PACKET; ++ } ++ /* enqueue to QM */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to flush pending TX packets in CORE ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return nicTxFlush(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief this function sends pending MSDU_INFO_T to MT6620 ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param pfgHwAccess Pointer for tracking LP-OWN status ++* ++* @retval WLAN_STATUS_SUCCESS Reset is done successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ ASSERT(pfgHwAccess); ++ ++ /* <1> dequeue packets by txDequeuTxPackets() */ ++ /* Note: prMsduInfo is a packet list queue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prMsduInfo = qmDequeueTxPackets(prAdapter, &prTxCtrl->rTc); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ if (prMsduInfo != NULL) { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { ++ /* <2> Acquire LP-OWN if necessary */ ++ if (*pfgHwAccess == FALSE) { ++ *pfgHwAccess = TRUE; ++ ++ wlanAcquirePowerControl(prAdapter); ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ /* <3> send packet"s" to HIF */ ++ nicTxMsduInfoList(prAdapter, prMsduInfo); ++ ++ /* <4> update TC by txAdjustTcQuotas() */ ++ nicTxAdjustTcq(prAdapter); ++ } else ++ wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); /* free the packet */ ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ nicEnableClockGating(prAdapter); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to acquire power control from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* do driver own */ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* Reset sleepy state *//* no use */ ++ if (prAdapter->fgWiFiInSleepyState == TRUE) ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to release power control to firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* do FW own */ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to report currently pending TX frames count ++* (command packets are not included) ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return number of pending TX frames ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ UINT_32 u4Num; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* number in prTxQueue + number in RX forward */ ++ u4Num = kalGetTxPendingFrameCount(prAdapter->prGlueInfo) + (UINT_32) (prTxCtrl->i4PendingFwdFrameCount); ++ ++ return u4Num; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to report current ACPI state ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return ACPI_STATE_D0 Normal Operation Mode ++* ACPI_STATE_D3 Suspend Mode ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->rAcpiState; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to update current ACPI state only ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param ePowerState ACPI_STATE_D0 Normal Operation Mode ++* ACPI_STATE_D3 Suspend Mode ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState) ++{ ++ ASSERT(prAdapter); ++ ASSERT(ePowerState <= ACPI_STATE_D3); ++ ++ prAdapter->rAcpiState = ePowerState; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to query ECO version from HIFSYS CR ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return zero Unable to retrieve ECO version information ++* non-zero ECO version (1-based) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ if (nicVerifyChipID(prAdapter) == TRUE) ++ return prAdapter->ucRevID + 1; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to setting the default Tx Power configuration ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return zero Unable to retrieve ECO version information ++* non-zero ECO version (1-based) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 i; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ P_SET_TXPWR_CTRL_T prTxpwr; ++ ++ ASSERT(prGlueInfo); ++ ++ prTxpwr = &prGlueInfo->rTxPwr; ++ ++ prTxpwr->c2GLegacyStaPwrOffset = 0; ++ prTxpwr->c2GHotspotPwrOffset = 0; ++ prTxpwr->c2GP2pPwrOffset = 0; ++ prTxpwr->c2GBowPwrOffset = 0; ++ prTxpwr->c5GLegacyStaPwrOffset = 0; ++ prTxpwr->c5GHotspotPwrOffset = 0; ++ prTxpwr->c5GP2pPwrOffset = 0; ++ prTxpwr->c5GBowPwrOffset = 0; ++ prTxpwr->ucConcurrencePolicy = 0; ++ for (i = 0; i < 3; i++) ++ prTxpwr->acReserved1[i] = 0; ++ ++ for (i = 0; i < 14; i++) ++ prTxpwr->acTxPwrLimit2G[i] = 63; ++ ++ for (i = 0; i < 4; i++) ++ prTxpwr->acTxPwrLimit5G[i] = 63; ++ ++ for (i = 0; i < 2; i++) ++ prTxpwr->acReserved2[i] = 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* set preferred band configuration corresponding to network type ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param eBand Given band ++* @param eNetTypeIndex Given Network Type ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eBand <= BAND_NUM); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ /* 1. set prefer band according to network type */ ++ prAdapter->aePreferBand[eNetTypeIndex] = eBand; ++ ++ /* 2. remove buffered BSS descriptors correspondingly */ ++ if (eBand == BAND_2G4) ++ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_5G, eNetTypeIndex); ++ else if (eBand == BAND_5G) ++ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_2G4, eNetTypeIndex); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* get channel information corresponding to specified network type ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param eNetTypeIndex Given Network Type ++* ++* @return channel number ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ return prBssInfo->ucPrimaryChannel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* get BSS descriptor information corresponding to specified network type ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param eNetTypeIndex Given Network Type ++* ++* @return pointer to BSS_DESC_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ switch (eNetTypeIndex) { ++ case NETWORK_TYPE_AIS_INDEX: ++ return prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; ++ ++ case NETWORK_TYPE_P2P_INDEX: ++ return NULL; ++ ++ case NETWORK_TYPE_BOW_INDEX: ++ return prAdapter->rWifiVar.rBowFsmInfo.prTargetBssDesc; ++ ++ default: ++ return NULL; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* check unconfigured system properties and generate related message on ++* scan list to notify users ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter) ++{ ++#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1) ++ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ const UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ BOOLEAN fgIsConfExist = TRUE; ++ BOOLEAN fgGenErrMsg = FALSE; ++ P_REG_INFO_T prRegInfo = NULL; ++ P_WLAN_BEACON_FRAME_T prBeacon = NULL; ++ P_IE_SSID_T prSsid = NULL; ++ UINT_32 u4ErrCode = 0; ++ UINT_8 aucErrMsg[32]; ++ PARAM_SSID_T rSsid; ++ PARAM_802_11_CONFIG_T rConfiguration; ++ PARAM_RATES_EX rSupportedRates; ++#endif ++ ++ DEBUGFUNC("wlanCheckSystemConfiguration"); ++ ++ ASSERT(prAdapter); ++ ++#if (CFG_NVRAM_EXISTENCE_CHECK == 1) ++ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) { ++ fgIsConfExist = FALSE; ++ fgGenErrMsg = TRUE; ++ } ++#endif ++ ++#if (CFG_SW_NVRAM_VERSION_CHECK == 1) ++ prRegInfo = kalGetConfiguration(prAdapter->prGlueInfo); ++ ++ if (fgIsConfExist == TRUE && (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion ++ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION ++ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion ++ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ || prAdapter->fgIsPowerLimitTableValid == FALSE ++#endif ++ || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && ++ (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) ++ || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) ++ || prRegInfo->ucTxPwrValid == 0)) ++ fgGenErrMsg = TRUE; ++#endif ++ ++ if (fgGenErrMsg == TRUE) { ++ prBeacon = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); ++ if (!prBeacon) { ++ ASSERT(FALSE); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* initialization */ ++ kalMemZero(prBeacon, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); ++ ++ /* prBeacon initialization */ ++ prBeacon->u2FrameCtrl = MAC_FRAME_BEACON; ++ COPY_MAC_ADDR(prBeacon->aucDestAddr, aucBCAddr); ++ COPY_MAC_ADDR(prBeacon->aucSrcAddr, aucZeroMacAddr); ++ COPY_MAC_ADDR(prBeacon->aucBSSID, aucZeroMacAddr); ++ prBeacon->u2BeaconInterval = 100; ++ prBeacon->u2CapInfo = CAP_INFO_ESS; ++ ++ /* prSSID initialization */ ++ prSsid = (P_IE_SSID_T) (&prBeacon->aucInfoElem[0]); ++ prSsid->ucId = ELEM_ID_SSID; ++ ++ /* rConfiguration initialization */ ++ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); ++ rConfiguration.u4BeaconPeriod = 100; ++ rConfiguration.u4ATIMWindow = 1; ++ rConfiguration.u4DSConfig = 2412; ++ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); ++ ++ /* rSupportedRates initialization */ ++ kalMemZero(rSupportedRates, sizeof(PARAM_RATES_EX)); ++ } ++#if (CFG_NVRAM_EXISTENCE_CHECK == 1) ++#define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01" ++ if ((kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) && (prBeacon) && (prSsid)) { ++ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBeacon, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + prSsid->ucLength, ++ 1, 0); ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); ++ nicAddScanResult(prAdapter, ++ prBeacon->aucBSSID, ++ &rSsid, ++ 0, ++ 0, ++ PARAM_NETWORK_TYPE_FH, ++ &rConfiguration, ++ NET_TYPE_INFRA, ++ rSupportedRates, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + prSsid->ucLength - ++ WLAN_MAC_MGMT_HEADER_LEN, (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); ++ } ++#endif ++ ++#if (CFG_SW_NVRAM_VERSION_CHECK == 1) ++#define VER_ERR_MSG "NVRAM WARNING: Err = 0x%02X" ++ if ((fgIsConfExist == TRUE) && (prBeacon) && (prSsid)) { ++ if ((CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion ++ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION ++ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion ++ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION)) ++ u4ErrCode |= NVRAM_ERROR_VERSION_MISMATCH; ++ ++ if (prRegInfo->ucTxPwrValid == 0) ++ u4ErrCode |= NVRAM_ERROR_INVALID_TXPWR; ++ ++ if (prAdapter->fgIsEmbbededMacAddrValid == FALSE && (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) ++ || EQUAL_MAC_ADDR(aucZeroMacAddr, ++ prRegInfo->aucMacAddr))) ++ u4ErrCode |= NVRAM_ERROR_INVALID_MAC_ADDR; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ if (prAdapter->fgIsPowerLimitTableValid == FALSE) ++ u4ErrCode |= NVRAM_POWER_LIMIT_TABLE_INVALID; ++#endif ++ if (u4ErrCode != 0) { ++ sprintf(aucErrMsg, VER_ERR_MSG, (unsigned int)u4ErrCode); ++ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, aucErrMsg, strlen(aucErrMsg)); ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBeacon, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + ++ prSsid->ucLength, 1, 0); ++ ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); ++ nicAddScanResult(prAdapter, ++ prBeacon->aucBSSID, ++ &rSsid, ++ 0, ++ 0, ++ PARAM_NETWORK_TYPE_FH, ++ &rConfiguration, ++ NET_TYPE_INFRA, ++ rSupportedRates, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + ++ prSsid->ucLength - WLAN_MAC_MGMT_HEADER_LEN, ++ (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); ++ } ++ } ++#endif ++ ++ if (fgGenErrMsg == TRUE) ++ cnmMemFree(prAdapter, prBeacon); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++ P_STA_RECORD_T prStaRec, prTempStaRec; ++ P_PARAM_GET_STA_STATISTICS prQueryStaStatistics; ++ UINT_8 ucStaRecIdx; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ CMD_GET_STA_STATISTICS_T rQueryCmdStaStatistics; ++ UINT_8 ucIdx; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ do { ++ ASSERT(pvQueryBuffer); ++ ++ /* 4 1. Sanity test */ ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ if (u4QueryBufferLen < sizeof(PARAM_GET_STA_STA_STATISTICS)) { ++ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); ++ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++ ++ prQueryStaStatistics = (P_PARAM_GET_STA_STATISTICS) pvQueryBuffer; ++ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); ++ ++ /* 4 5. Get driver global QM counter */ ++ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { ++ prQueryStaStatistics->au4TcAverageQueLen[ucIdx] = prQM->au4AverageQueLen[ucIdx]; ++ prQueryStaStatistics->au4TcCurrentQueLen[ucIdx] = prQM->au4CurrentTcResource[ucIdx]; ++ } ++ ++ /* 4 2. Get StaRec by MAC address */ ++ prStaRec = NULL; ++ ++ for (ucStaRecIdx = 0; ucStaRecIdx < CFG_NUM_OF_STA_RECORD; ucStaRecIdx++) { ++ prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]); ++ if (prTempStaRec->fgIsValid && prTempStaRec->fgIsInUse) { ++ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prQueryStaStatistics->aucMacAddr)) { ++ prStaRec = prTempStaRec; ++ break; ++ } ++ } ++ } ++ ++ if (!prStaRec) { ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ prQueryStaStatistics->u4Flag |= BIT(0); ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ /* 4 3. Get driver statistics */ ++ DBGLOG(TX, INFO, "skbToDriver %lld, skbFreed: %lld\n", ++ prAdapter->prGlueInfo->u8SkbToDriver, ++ prAdapter->prGlueInfo->u8SkbFreed); ++ prAdapter->prGlueInfo->u8SkbFreed = 0; ++ prAdapter->prGlueInfo->u8SkbToDriver = 0; ++ ++ prQueryStaStatistics->u4TxTotalCount = prStaRec->u4TotalTxPktsNumber; ++ prQueryStaStatistics->u4TxExceedThresholdCount = prStaRec->u4ThresholdCounter; ++ prQueryStaStatistics->u4TxMaxTime = prStaRec->u4MaxTxPktsTime; ++ prQueryStaStatistics->u4TxMaxHifTime = prStaRec->u4MaxTxPktsHifTime; ++ if (prStaRec->u4TotalTxPktsNumber) { ++ prQueryStaStatistics->u4TxAverageProcessTime = ++ (prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber); ++ prQueryStaStatistics->u4TxAverageHifTime = ++ (prStaRec->u4TotalTxPktsHifTime / prStaRec->u4TotalTxPktsNumber); ++ } else ++ prQueryStaStatistics->u4TxAverageProcessTime = 0; ++ ++ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { ++ prQueryStaStatistics->au4TcResourceEmptyCount[ucIdx] = ++ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx]; ++ /* Reset */ ++ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx] = 0; ++ prQueryStaStatistics->au4TcResourceBackCount[ucIdx] = ++ prQM->au4QmTcResourceBackCounter[ucIdx]; ++ prQM->au4QmTcResourceBackCounter[ucIdx] = 0; ++ ++ prQueryStaStatistics->au4DequeueNoTcResource[ucIdx] = ++ prQM->au4DequeueNoTcResourceCounter[ucIdx]; ++ prQM->au4DequeueNoTcResourceCounter[ucIdx] = 0; ++ prQueryStaStatistics->au4TcResourceUsedCount[ucIdx] = ++ prQM->au4ResourceUsedCounter[ucIdx]; ++ prQM->au4ResourceUsedCounter[ucIdx] = 0; ++ prQueryStaStatistics->au4TcResourceWantedCount[ucIdx] = ++ prQM->au4ResourceWantedCounter[ucIdx]; ++ prQM->au4ResourceWantedCounter[ucIdx] = 0; ++ } ++ ++ prQueryStaStatistics->u4EnqueueCounter = prQM->u4EnqeueuCounter; ++ prQueryStaStatistics->u4DequeueCounter = prQM->u4DequeueCounter; ++ prQueryStaStatistics->u4EnqueueStaCounter = prStaRec->u4EnqeueuCounter; ++ prQueryStaStatistics->u4DequeueStaCounter = prStaRec->u4DeqeueuCounter; ++ ++ prQueryStaStatistics->IsrCnt = prGlueInfo->IsrCnt - prGlueInfo->IsrPreCnt; ++ prQueryStaStatistics->IsrPassCnt = prGlueInfo->IsrPassCnt - prGlueInfo->IsrPrePassCnt; ++ prQueryStaStatistics->TaskIsrCnt = prGlueInfo->TaskIsrCnt - prGlueInfo->TaskPreIsrCnt; ++ ++ prQueryStaStatistics->IsrAbnormalCnt = prGlueInfo->IsrAbnormalCnt; ++ prQueryStaStatistics->IsrSoftWareCnt = prGlueInfo->IsrSoftWareCnt; ++ prQueryStaStatistics->IsrRxCnt = prGlueInfo->IsrRxCnt; ++ prQueryStaStatistics->IsrTxCnt = prGlueInfo->IsrTxCnt; ++ ++ /* 4 4.1 Reset statistics */ ++ prStaRec->u4ThresholdCounter = 0; ++ prStaRec->u4TotalTxPktsNumber = 0; ++ prStaRec->u4TotalTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsHifTime = 0; ++ ++ prStaRec->u4EnqeueuCounter = 0; ++ prStaRec->u4DeqeueuCounter = 0; ++ ++ prQM->u4EnqeueuCounter = 0; ++ prQM->u4DequeueCounter = 0; ++ ++ prGlueInfo->IsrPreCnt = prGlueInfo->IsrCnt; ++ prGlueInfo->IsrPrePassCnt = prGlueInfo->IsrPassCnt; ++ prGlueInfo->TaskPreIsrCnt = prGlueInfo->TaskIsrCnt; ++ prGlueInfo->IsrAbnormalCnt = 0; ++ prGlueInfo->IsrSoftWareCnt = 0; ++ prGlueInfo->IsrRxCnt = 0; ++ prGlueInfo->IsrTxCnt = 0; ++#endif ++ ++ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) ++ prQueryStaStatistics->au4TcQueLen[ucIdx] = prStaRec->arTxQueue[ucIdx].u4NumElem; ++ ++ rResult = WLAN_STATUS_SUCCESS; ++ ++ /* 4 6. Ensure FW supports get station link status */ ++ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { ++ ++ rQueryCmdStaStatistics.ucIndex = prStaRec->ucIndex; ++ COPY_MAC_ADDR(rQueryCmdStaStatistics.aucMacAddr, prQueryStaStatistics->aucMacAddr); ++ rQueryCmdStaStatistics.ucReadClear = TRUE; ++ ++ rResult = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STA_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryStaStatistics, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_GET_STA_STATISTICS_T), ++ (PUINT_8)&rQueryCmdStaStatistics, ++ pvQueryBuffer, u4QueryBufferLen); ++ ++ prQueryStaStatistics->u4Flag |= BIT(1); ++ } else { ++ rResult = WLAN_STATUS_NOT_SUPPORTED; ++ } ++ ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pVersion */ ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++/* 4 Auto Channel Selection */ ++WLAN_STATUS ++wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++ /* P_PARAM_GET_CHN_LOAD prQueryChnLoad; */ ++ P_PARAM_GET_LTE_MODE prLteMode; ++ CMD_GET_LTE_SAFE_CHN_T rQuery_LTE_SAFE_CHN; ++ ++ DBGLOG(P2P, INFO, "[Auto Channel]wlanoidQueryACSChannelList\n"); ++ do { ++ ASSERT(pvQueryBuffer); ++ ++ /* 4 1. Sanity test */ ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ prLteMode = (P_PARAM_GET_LTE_MODE) pvQueryBuffer; ++ ++ /* 4 3. Ensure FW supports get station link status */ ++#if 0 ++ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++ rCmdAccessReg.u4Address = 0xFFFFFFFF; ++ rCmdAccessReg.u4Data = ELEM_RM_TYPE_ACS_CHN; ++ ++ rResult = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ TRUE, ++ TRUE, ++ /* The handler to receive firmware notification */ ++ nicCmdEventQueryChannelLoad, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8)&rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); ++ ++ prQueryChnLoad->u4Flag |= BIT(1); ++ } else { ++ rResult = WLAN_STATUS_NOT_SUPPORTED; ++ } ++#endif ++ /* 4 4.Avoid LTE Channels */ ++ prLteMode->u4Flags &= BIT(0); ++ /*if(prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) */ { ++ ++ rResult = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LTE_CHN, ++ FALSE, ++ TRUE, ++ /* Query ID */ ++ TRUE, ++ /* The handler to receive firmware notification */ ++ nicCmdEventQueryLTESafeChn, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_GET_LTE_SAFE_CHN_T), ++ (PUINT_8)&rQuery_LTE_SAFE_CHN, ++ pvQueryBuffer, u4QueryBufferLen); ++ ++ DBGLOG(P2P, INFO, "[Auto Channel] Get LTE Channels\n"); ++ prLteMode->u4Flags |= BIT(1); ++ } ++ ++ /* 4 5. Calc the value */ ++ ++ DBGLOG(P2P, INFO, "[Auto Channel] Candidated Channels\n"); ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pVersion */ ++#endif ++#if CFG_SUPPORT_CFG_FILE ++ ++P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_32 i; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ASSERT(pucKey); ++ ++ prWlanCfgEntry = NULL; ++ ++ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { ++ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; ++ if (prWlanCfgEntry->aucKey[0] != '\0') { ++ DBGLOG(INIT, LOUD, "compare key %s saved key %s\n", pucKey, prWlanCfgEntry->aucKey); ++ if (kalStrniCmp(pucKey, prWlanCfgEntry->aucKey, WLAN_CFG_KEY_LEN_MAX - 1) == 0) ++ return prWlanCfgEntry; ++ } ++ } ++ ++ DBGLOG(INIT, LOUD, "wifi config there is no entry \'%s\'\n", pucKey); ++ return NULL; ++ ++} ++ ++WLAN_STATUS wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ASSERT(pucValue); ++ ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ kalStrnCpy(pucValue, prWlanCfgEntry->aucValue, WLAN_CFG_VALUE_LEN_MAX - 1); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (pucValueDef) ++ kalStrnCpy(pucValue, pucValueDef, WLAN_CFG_VALUE_LEN_MAX - 1); ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef) ++{ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_32 u4Value; ++ INT_32 u4Ret; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ++ u4Value = u4ValueDef; ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ u4Ret = kalkStrtou32(prWlanCfgEntry->aucValue, 0, &u4Value); ++ if (u4Ret) ++ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue u4Ret=%u\n", u4Ret); ++ /* u4Value = kalStrtoul(prWlanCfgEntry->aucValue, NULL, 0); */ ++ } ++ ++ return u4Value; ++} ++ ++INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef) ++{ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ INT_32 i4Value; ++ INT_32 i4Ret; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ++ i4Value = i4ValueDef; ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ i4Ret = kalkStrtos32(prWlanCfgEntry->aucValue, 0, &i4Value); ++ /* i4Ret = kalStrtol(prWlanCfgEntry->aucValue, NULL, 0); */ ++ if (i4Ret) ++ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue i4Ret=%u\n\r", i4Ret); ++ } ++ ++ return i4Value; ++} ++ ++WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_32 u4EntryIndex; ++ UINT_32 i; ++ UINT_8 ucExist; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ASSERT(prWlanCfg); ++ ASSERT(pucKey); ++ ++ /* Find the exist */ ++ ucExist = 0; ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (!prWlanCfgEntry) { ++ /* Find the empty */ ++ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { ++ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; ++ if (prWlanCfgEntry->aucKey[0] == '\0') ++ break; ++ } ++ ++ u4EntryIndex = i; ++ if (u4EntryIndex < WLAN_CFG_ENTRY_NUM_MAX) { ++ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[u4EntryIndex]; ++ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); ++ } else { ++ prWlanCfgEntry = NULL; ++ DBGLOG(INIT, ERROR, "wifi config there is no empty entry\n"); ++ } ++ } /* !prWlanCfgEntry */ ++ else ++ ucExist = 1; ++ ++ if (prWlanCfgEntry) { ++ if (ucExist == 0) { ++ kalStrnCpy(prWlanCfgEntry->aucKey, pucKey, WLAN_CFG_KEY_LEN_MAX - 1); ++ prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0'; ++ } ++ ++ if (pucValue && pucValue[0] != '\0') { ++ kalStrnCpy(prWlanCfgEntry->aucValue, pucValue, WLAN_CFG_VALUE_LEN_MAX - 1); ++ prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = '\0'; ++ ++ if (ucExist) { ++ if (prWlanCfgEntry->pfSetCb) ++ prWlanCfgEntry->pfSetCb(prAdapter, ++ prWlanCfgEntry->aucKey, ++ prWlanCfgEntry->aucValue, prWlanCfgEntry->pPrivate, 0); ++ } ++ } else { ++ /* Call the pfSetCb if value is empty ? */ ++ /* remove the entry if value is empty */ ++ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); ++ } ++ ++ } ++ /* prWlanCfgEntry */ ++ if (prWlanCfgEntry) { ++ DBGLOG(INIT, LOUD, "Set wifi config exist %u \'%s\' \'%s\'\n", ++ ucExist, prWlanCfgEntry->aucKey, prWlanCfgEntry->aucValue); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (pucKey) ++ DBGLOG(INIT, ERROR, "Set wifi config error key \'%s\'\n", pucKey); ++ if (pucValue) ++ DBGLOG(INIT, ERROR, "Set wifi config error value \'%s\'\n", pucValue); ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++WLAN_STATUS ++wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ASSERT(prWlanCfg); ++ ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ prWlanCfgEntry->pfSetCb = pfSetCb; ++ prWlanCfgEntry->pPrivate = pPrivate; ++ } ++ ++ if (prWlanCfgEntry) ++ return WLAN_STATUS_SUCCESS; ++ else ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value) ++{ ++ ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_8 aucBuf[WLAN_CFG_VALUE_LEN_MAX]; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ++ kalMemZero(aucBuf, sizeof(aucBuf)); ++ ++ kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", (unsigned int)u4Value); ++ ++ return wlanCfgSet(prAdapter, pucKey, aucBuf, 0); ++} ++ ++enum { ++ STATE_EOF = 0, ++ STATE_TEXT = 1, ++ STATE_NEWLINE = 2 ++}; ++ ++struct WLAN_CFG_PARSE_STATE_S { ++ CHAR *ptr; ++ CHAR *text; ++ INT_32 nexttoken; ++ UINT_32 maxSize; ++}; ++ ++INT_32 wlanCfgFindNextToken(struct WLAN_CFG_PARSE_STATE_S *state) ++{ ++ CHAR *x = state->ptr; ++ CHAR *s; ++ ++ if (state->nexttoken) { ++ INT_32 t = state->nexttoken; ++ ++ state->nexttoken = 0; ++ return t; ++ } ++ ++ for (;;) { ++ switch (*x) { ++ case 0: ++ state->ptr = x; ++ return STATE_EOF; ++ case '\n': ++ x++; ++ state->ptr = x; ++ return STATE_NEWLINE; ++ case ' ': ++ case '\t': ++ case '\r': ++ x++; ++ continue; ++ case '#': ++ while (*x && (*x != '\n')) ++ x++; ++ if (*x == '\n') { ++ state->ptr = x + 1; ++ return STATE_NEWLINE; ++ } ++ state->ptr = x; ++ return STATE_EOF; ++ default: ++ goto text; ++ } ++ } ++ ++textdone: ++ state->ptr = x; ++ *s = 0; ++ return STATE_TEXT; ++text: ++ state->text = s = x; ++textresume: ++ for (;;) { ++ switch (*x) { ++ case 0: ++ goto textdone; ++ case ' ': ++ case '\t': ++ case '\r': ++ x++; ++ goto textdone; ++ case '\n': ++ state->nexttoken = STATE_NEWLINE; ++ x++; ++ goto textdone; ++ case '"': ++ x++; ++ for (;;) { ++ switch (*x) { ++ case 0: ++ /* unterminated quoted thing */ ++ state->ptr = x; ++ return STATE_EOF; ++ case '"': ++ x++; ++ goto textresume; ++ default: ++ *s++ = *x++; ++ } ++ } ++ break; ++ case '\\': ++ x++; ++ switch (*x) { ++ case 0: ++ goto textdone; ++ case 'n': ++ *s++ = '\n'; ++ break; ++ case 'r': ++ *s++ = '\r'; ++ break; ++ case 't': ++ *s++ = '\t'; ++ break; ++ case '\\': ++ *s++ = '\\'; ++ break; ++ case '\r': ++ /* \ -> line continuation */ ++ if (x[1] != '\n') { ++ x++; ++ continue; ++ } ++ case '\n': ++ /* \ -> line continuation */ ++ x++; ++ /* eat any extra whitespace */ ++ while ((*x == ' ') || (*x == '\t')) ++ x++; ++ continue; ++ default: ++ /* unknown escape -- just copy */ ++ *s++ = *x++; ++ } ++ continue; ++ default: ++ *s++ = *x++; ++ } ++ } ++ return STATE_EOF; ++} ++ ++WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]) ++{ ++ struct WLAN_CFG_PARSE_STATE_S state; ++ CHAR **args; ++ INT_32 nargs; ++ ++ if (cmdLine == NULL || argc == NULL || argv == NULL) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ args = argv; ++ nargs = 0; ++ state.ptr = cmdLine; ++ state.nexttoken = 0; ++ state.maxSize = 0; ++ ++ if (kalStrnLen(cmdLine, 512) >= 512) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ for (;;) { ++ switch (wlanCfgFindNextToken(&state)) { ++ case STATE_EOF: ++ goto exit; ++ case STATE_NEWLINE: ++ goto exit; ++ case STATE_TEXT: ++ if (nargs < WLAN_CFG_ARGV_MAX) ++ args[nargs++] = state.text; ++ break; ++ } ++ } ++ ++exit: ++ *argc = nargs; ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanCfgParseAddEntry(IN P_ADAPTER_T prAdapter, ++ PUINT_8 pucKeyHead, PUINT_8 pucKeyTail, PUINT_8 pucValueHead, PUINT_8 pucValueTail) ++{ ++ ++ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; ++ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++ UINT_32 u4Len; ++ ++ kalMemZero(aucKey, sizeof(aucKey)); ++ kalMemZero(aucValue, sizeof(aucValue)); ++ ++ if ((pucKeyHead == NULL) ++ || (pucValueHead == NULL) ++ ) ++ return WLAN_STATUS_FAILURE; ++ ++ if (pucKeyTail) { ++ if (pucKeyHead > pucKeyTail) ++ return WLAN_STATUS_FAILURE; ++ u4Len = pucKeyTail - pucKeyHead + 1; ++ } else ++ u4Len = kalStrnLen(pucKeyHead, WLAN_CFG_KEY_LEN_MAX - 1); ++ ++ if (u4Len >= WLAN_CFG_KEY_LEN_MAX) ++ u4Len = WLAN_CFG_KEY_LEN_MAX - 1; ++ ++ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) ++ kalStrnCpy(aucKey, pucKeyHead, u4Len); ++ else ++ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); ++ ++ if (pucValueTail) { ++ if (pucValueHead > pucValueTail) ++ return WLAN_STATUS_FAILURE; ++ u4Len = pucValueTail - pucValueHead + 1; ++ } else ++ u4Len = kalStrnLen(pucValueHead, WLAN_CFG_VALUE_LEN_MAX - 1); ++ ++ if (u4Len >= WLAN_CFG_VALUE_LEN_MAX) ++ u4Len = WLAN_CFG_VALUE_LEN_MAX - 1; ++ ++ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) ++ kalStrnCpy(aucValue, pucValueHead, u4Len); ++ else ++ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); ++ ++ return wlanCfgSet(prAdapter, aucKey, aucValue, 0); ++} ++ ++enum { ++ WAIT_KEY_HEAD = 0, ++ WAIT_KEY_TAIL, ++ WAIT_VALUE_HEAD, ++ WAIT_VALUE_TAIL, ++ WAIT_COMMENT_TAIL ++}; ++ ++WLAN_STATUS wlanCfgParse(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen) ++{ ++ ++ struct WLAN_CFG_PARSE_STATE_S state; ++ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; ++ CHAR **args; ++ INT_32 nargs; ++ ++ if (pucConfigBuf == NULL) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ if (kalStrnLen(pucConfigBuf, 4000) >= 4000) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ if (u4ConfigBufLen == 0) ++ return WLAN_STATUS_FAILURE; ++ args = apcArgv; ++ nargs = 0; ++ state.ptr = pucConfigBuf; ++ state.nexttoken = 0; ++ state.maxSize = u4ConfigBufLen; ++ ++ for (;;) { ++ switch (wlanCfgFindNextToken(&state)) { ++ case STATE_EOF: ++ if (nargs > 1) ++ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); ++ goto exit; ++ case STATE_NEWLINE: ++ if (nargs > 1) ++ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); ++ nargs = 0; ++ break; ++ case STATE_TEXT: ++ if (nargs < WLAN_CFG_ARGV_MAX) ++ args[nargs++] = state.text; ++ break; ++ } ++ } ++ ++exit: ++ return WLAN_STATUS_SUCCESS; ++ ++#if 0 ++ /* Old version */ ++ UINT_32 i; ++ UINT_8 c; ++ PUINT_8 pbuf; ++ UINT_8 ucState; ++ PUINT_8 pucKeyTail = NULL; ++ PUINT_8 pucKeyHead = NULL; ++ PUINT_8 pucValueHead = NULL; ++ PUINT_8 pucValueTail = NULL; ++ ++ ucState = WAIT_KEY_HEAD; ++ pbuf = pucConfigBuf; ++ ++ for (i = 0; i < u4ConfigBufLen; i++) { ++ c = pbuf[i]; ++ if (c == '\r' || c == '\n') { ++ ++ if (ucState == WAIT_VALUE_TAIL) { ++ /* Entry found */ ++ if (pucValueHead) ++ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, ++ pucValueHead, pucValueTail); ++ } ++ ucState = WAIT_KEY_HEAD; ++ pucKeyTail = NULL; ++ pucKeyHead = NULL; ++ pucValueHead = NULL; ++ pucValueTail = NULL; ++ ++ } else if (c == '=') { ++ if (ucState == WAIT_KEY_TAIL) { ++ pucKeyTail = &pbuf[i - 1]; ++ ucState = WAIT_VALUE_HEAD; ++ } ++ } else if (c == ' ' || c == '\t') { ++ if (ucState == WAIT_KEY_HEAD) ++ ; ++ else if (ucState == WAIT_KEY_TAIL) { ++ pucKeyTail = &pbuf[i - 1]; ++ ucState = WAIT_VALUE_HEAD; ++ } ++ } else { ++ ++ if (c == '#') { ++ /* comments */ ++ if (ucState == WAIT_KEY_HEAD) ++ ucState = WAIT_COMMENT_TAIL; ++ else if (ucState == WAIT_VALUE_TAIL) ++ pucValueTail = &pbuf[i]; ++ ++ } else { ++ if (ucState == WAIT_KEY_HEAD) { ++ pucKeyHead = &pbuf[i]; ++ pucKeyTail = &pbuf[i]; ++ ucState = WAIT_KEY_TAIL; ++ } else if (ucState == WAIT_VALUE_HEAD) { ++ pucValueHead = &pbuf[i]; ++ pucValueTail = &pbuf[i]; ++ ucState = WAIT_VALUE_TAIL; ++ } else if (ucState == WAIT_VALUE_TAIL) ++ pucValueTail = &pbuf[i]; ++ } ++ } ++ ++ } /* for */ ++ ++ if (ucState == WAIT_VALUE_TAIL) { ++ /* Entry found */ ++ if (pucValueTail) ++ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, pucValueHead, pucValueTail); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++#endif ++ ++#if CFG_SUPPORT_CFG_FILE ++WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags) ++{ ++ P_WLAN_CFG_T prWlanCfg; ++ /* P_WLAN_CFG_ENTRY_T prWlanCfgEntry; */ ++ prAdapter->prWlanCfg = &prAdapter->rWlanCfg; ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ kalMemZero(prWlanCfg, sizeof(WLAN_CFG_T)); ++ ASSERT(prWlanCfg); ++ prWlanCfg->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX; ++ prWlanCfg->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX; ++ prWlanCfg->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX; ++#if 0 ++ DBGLOG(INIT, INFO, "Init wifi config len %u max entry %u\n", u4ConfigBufLen, prWlanCfg->u4WlanCfgEntryNumMax); ++#endif ++ /* self test */ ++ wlanCfgSet(prAdapter, "ConfigValid", "0x123", 0); ++ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 0x123) ++ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); ++ wlanCfgSet(prAdapter, "ConfigValid", "1", 0); ++ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 1) ++ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); ++#if 0 /* soc chip didn't support these parameters now */ ++ /* Add initil config */ ++ /* use g,wlan,p2p,ap as prefix */ ++ /* Don't set cb here , overwrite by another api */ ++ wlanCfgSet(prAdapter, "TxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "RxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "RxBeamformee", "1", 0); ++ wlanCfgSet(prAdapter, "RoamTh1", "100", 0); ++ wlanCfgSet(prAdapter, "RoamTh2", "150", 0); ++ wlanCfgSet(prAdapter, "wlanRxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "apRxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "p2pRxLdpc", "1", 0); ++#endif ++ /* Parse the pucConfigBuff */ ++ ++ if (pucConfigBuf && (u4ConfigBufLen > 0)) ++ wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to initialize WLAN feature options ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanCfgApply(IN P_ADAPTER_T prAdapter) ++{ ++#define STR2BYTE(s) (((((PUINT_8)s)[0]-'0')*10)+(((PUINT_8)s)[1]-'0')) ++ CHAR aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; ++ P_REG_INFO_T prRegInfo = &prAdapter->prGlueInfo->rRegInfo; ++ P_TX_PWR_PARAM_T prTxPwr = &prRegInfo->rTxPwr; ++ ++ kalMemZero(aucValue, sizeof(aucValue)); ++ DBGLOG(INIT, LOUD, "CFG_FILE: Apply Config File\n"); ++ /* Apply COUNTRY Config */ ++ if (wlanCfgGet(prAdapter, "country", aucValue, "", 0) == WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Found Country Key, Value=%s\n", aucValue); ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode = ++ (((UINT_16) aucValue[0]) << 8) | ((UINT_16) aucValue[1]); ++ prRegInfo->au2CountryCode[0] = aucValue[0]; ++ prRegInfo->au2CountryCode[1] = aucValue[1]; ++ } ++ prWifiVar->ucApWpsMode = (UINT_8) wlanCfgGetUint32(prAdapter, "ApWpsMode", 0); ++ prWifiVar->ucCert11nMode = (UINT_8)wlanCfgGetUint32(prAdapter, "Cert11nMode", 0); ++ DBGLOG(INIT, LOUD, "CFG_FILE: ucApWpsMode = %u, ucCert11nMode = %u\n", ++ prWifiVar->ucApWpsMode, prWifiVar->ucCert11nMode); ++ if (prWifiVar->ucCert11nMode == 1) ++ nicWriteMcr(prAdapter, 0x11111115 , 1); ++ ++ if (wlanCfgGet(prAdapter, "5G_support", aucValue, "", 0) == WLAN_STATUS_SUCCESS) ++ prRegInfo->ucSupport5GBand = (*aucValue == 'y') ? 1 : 0; ++ if (wlanCfgGet(prAdapter, "TxPower2G4CCK", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 2) { ++ prTxPwr->cTxPwr2G4Cck = STR2BYTE(aucValue); ++ DBGLOG(INIT, LOUD, "2.4G cck=%d\n", prTxPwr->cTxPwr2G4Cck); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower2G4OFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS && ++ kalStrLen(aucValue) == 10) { ++ prTxPwr->cTxPwr2G4OFDM_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr2G4OFDM_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr2G4OFDM_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr2G4OFDM_48Mbps = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr2G4OFDM_54Mbps = STR2BYTE(aucValue + 8); ++ DBGLOG(INIT, LOUD, "2.4G OFDM=%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr2G4OFDM_BPSK, prTxPwr->cTxPwr2G4OFDM_QPSK, ++ prTxPwr->cTxPwr2G4OFDM_16QAM, prTxPwr->cTxPwr2G4OFDM_48Mbps, ++ prTxPwr->cTxPwr2G4OFDM_54Mbps); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower2G4HT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS && ++ kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr2G4HT20_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr2G4HT20_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr2G4HT20_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr2G4HT20_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr2G4HT20_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr2G4HT20_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "2.4G HT20=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr2G4HT20_BPSK, prTxPwr->cTxPwr2G4HT20_QPSK, ++ prTxPwr->cTxPwr2G4HT20_16QAM, prTxPwr->cTxPwr2G4HT20_MCS5, ++ prTxPwr->cTxPwr2G4HT20_MCS6, prTxPwr->cTxPwr2G4HT20_MCS7); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower2G4HT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS && ++ kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr2G4HT40_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr2G4HT40_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr2G4HT40_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr2G4HT40_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr2G4HT40_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr2G4HT40_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "2.4G HT40=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr2G4HT40_BPSK, prTxPwr->cTxPwr2G4HT40_QPSK, ++ prTxPwr->cTxPwr2G4HT40_16QAM, prTxPwr->cTxPwr2G4HT40_MCS5, ++ prTxPwr->cTxPwr2G4HT40_MCS6, prTxPwr->cTxPwr2G4HT40_MCS7); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower5GOFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 10) { ++ prTxPwr->cTxPwr5GOFDM_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr5GOFDM_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr5GOFDM_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr5GOFDM_48Mbps = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr5GOFDM_54Mbps = STR2BYTE(aucValue + 8); ++ DBGLOG(INIT, LOUD, "5G OFDM=%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr5GOFDM_BPSK, prTxPwr->cTxPwr5GOFDM_QPSK, ++ prTxPwr->cTxPwr5GOFDM_16QAM, prTxPwr->cTxPwr5GOFDM_48Mbps, ++ prTxPwr->cTxPwr5GOFDM_54Mbps); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower5GHT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr5GHT20_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr5GHT20_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr5GHT20_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr5GHT20_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr5GHT20_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr5GHT20_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "5G HT20=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr5GHT20_BPSK, prTxPwr->cTxPwr5GHT20_QPSK, ++ prTxPwr->cTxPwr5GHT20_16QAM, prTxPwr->cTxPwr5GHT20_MCS5, prTxPwr->cTxPwr5GHT20_MCS6, ++ prTxPwr->cTxPwr5GHT20_MCS7); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower5GHT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr5GHT40_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr5GHT40_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr5GHT40_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr5GHT40_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr5GHT40_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr5GHT40_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "5G HT40=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr5GHT40_BPSK, prTxPwr->cTxPwr5GHT40_QPSK, ++ prTxPwr->cTxPwr5GHT40_16QAM, prTxPwr->cTxPwr5GHT40_MCS5, prTxPwr->cTxPwr5GHT40_MCS6, ++ prTxPwr->cTxPwr5GHT40_MCS7); ++ } ++ /* TODO: Apply other Config */ ++} ++#endif /* CFG_SUPPORT_CFG_FILE */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c +new file mode 100644 +index 000000000000..993ff061ed20 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c +@@ -0,0 +1,11050 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_oid.c#5 ++*/ ++ ++/*! \file wlanoid.c ++ \brief This file contains the WLAN OID processing routines of Windows driver for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_oid.c ++** ++** 09 05 2013 cp.wu ++** isolate logic regarding roaming & reassociation ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 09 02 2013 cp.wu ++** add path to handle reassociation request ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 06 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * using the wlanSendSetQueryCmd to set the tx power control cmd. ++ * ++ * 01 06 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * change the set tx power cmd name. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 12 20 2011 cp.wu ++ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information ++ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO ++ * to expose version information ++ * ++ * 12 05 2011 cp.wu ++ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path ++ * add CONNECT_BY_BSSID policy ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to ++ * asynchronous approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state ++ * without join timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 11 21 2011 cp.wu ++ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing ++ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer ++ * add more checking for such cases ++ * ++ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. ++ * add some tweaking to protect such cases because that net device has become invalid. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters of bb and ar for xlog. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 11 09 2011 george.huang ++ * [WCXRP00000871] [MT6620 Wi-Fi][FW] Include additional wakeup condition, which is by ++ * consequent DTIM unicast indication add XLOG for Set PS mode entry ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 11 02 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add RDD certification features. ++ * ++ * 10 21 2011 eddie.chen ++ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout ++ * Add switch to ignore the STA aging timeout. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 15 2011 tsaiyuan.hsu ++ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA ++ * correct fifo full control from query to set operation for CTIA. ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 17 2011 tsaiyuan.hsu ++ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA ++ * add system config for CTIA. ++ * ++ * 08 15 2011 george.huang ++ * [MT6620 Wi-Fi][FW] handle TSF drift for connection detection ++ * . ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 11 2011 wh.su ++ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, ++ * for customer not enable WAPI ++ * For make sure wapi initial value is set. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 05 02 2011 eddie.chen ++ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control ++ * Fix compile warning. ++ * ++ * 04 29 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * . ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * add more debug message ++ * ++ * 04 26 2011 eddie.chen ++ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control ++ * Add rx path profiling. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 03 31 2011 puff.wen ++ * NULL ++ * . ++ * ++ * 03 29 2011 puff.wen ++ * NULL ++ * Add chennel switch for stress test ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning ++ * surpress klock warning with code path rewritten ++ * ++ * 03 24 2011 wh.su ++ * [WCXRP00000595] [MT6620 Wi-Fi][Driver] at CTIA indicate disconnect to make the ps profile can apply ++ * use disconnect event instead of ais abort for CTIA testing. ++ * ++ * 03 23 2011 george.huang ++ * [WCXRP00000586] [MT6620 Wi-Fi][FW] Modify for blocking absence request right after connected ++ * revise for CTIA power mode setting ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 17 2011 yarco.yang ++ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage ++ * . ++ * ++ * 03 15 2011 george.huang ++ * [WCXRP00000557] [MT6620 Wi-Fi] Support current consumption test mode commands ++ * Support current consumption measurement mode command ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 04 2011 cp.wu ++ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection ++ * surpress compile warning occurred when compiled by GNU compiler collection. ++ * ++ * 03 03 2011 wh.su ++ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue ++ * fixed the enter ctia test mode issue. ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Update sigma CAPI for U-APSD setting ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Support UAPSD/OppPS/NoA parameter setting ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as ++ * initial RSSI right after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting ++ * Support CTIA power mode setting. ++ * ++ * 01 26 2011 wh.su ++ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux ++ * adding the SW cmd ioctl support, use set/get structure ioctl. ++ * ++ * 01 25 2011 cp.wu ++ * [WCXRP00000394] [MT6620 Wi-Fi][Driver] Count space needed for generating error message in ++ * scanning list into buffer size checking ++ * when doing size prechecking, check illegal MAC address as well ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * Add Stress test ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * check if allow to switch to IBSS mode via concurrent module before setting to IBSS mode ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000342] [MT6620 Wi-Fi][Driver] show error code in scanning list when MAC address is not ++ * correctly configured in NVRAM ++ * show error code 0x10 when MAC address in NVRAM is not configured correctly. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations ++ * to ease physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 28 2010 george.huang ++ * [WCXRP00000232] [MT5931 Wi-Fi][FW] Modifications for updated HW power on sequence and related design ++ * support WMM-PS U-APSD AC assignment. ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 16 2010 cp.wu ++ * [WCXRP00000268] [MT6620 Wi-Fi][Driver] correction for WHQL failed items ++ * correction for OID_802_11_NETWORK_TYPES_SUPPORTED handlers ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork ++ * suppress warning reported by Klockwork. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 30 2010 cp.wu ++ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 ++ * . ++ * ++ * 11 26 2010 cp.wu ++ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only ++ * with necessary data field checking ++ * 1. NVRAM error is now treated as warning only, thus normal operation is still available ++ * but extra scan result used to indicate user is attached ++ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown ++ * ++ * 11 25 2010 cp.wu ++ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM ++ * add scanning with specified SSID facility to AIS-FSM ++ * ++ * 11 21 2010 wh.su ++ * [WCXRP00000192] [MT6620 Wi-Fi][Driver] Fixed fail trying to build connection with Security ++ * AP while enable WAPI message check ++ * Not set the wapi mode while the wapi assoc info set non-wapi ie. ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value ++ * fixed the.pmkid value mismatch issue ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying ++ * current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 22 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * dos2unix conversion. ++ * ++ * 10 20 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * use OID_CUSTOM_TEST_MODE as indication for driver reset ++ * by dropping pending TX packets ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android complete ++ * implementation of Android NVRAM access ++ * ++ * 10 06 2010 yuche.tsai ++ * NULL ++ * Update SLT 5G Test Channel Set. ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 06 2010 yuche.tsai ++ * NULL ++ * Update For SLT 5G Test Channel Selection Rule. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form ++ * Query buffer size needs to be enlarged due to result is filled in 4-bytes alignment boundary ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and ++ * replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form ++ * Extend result length to multiples of 4-bytes ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate unused variables which lead gcc to argue ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Update SLT due to API change of SCAN module. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * Androi/Linux: return current operating channel information ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * 1) initialize for correct parameter even for disassociation. ++ * 2) AIS-FSM should have a limit on trials to build connection ++ * ++ * 09 03 2010 yuche.tsai ++ * NULL ++ * Refine SLT IO control handler. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 30 2010 chinglan.wang ++ * NULL ++ * Modify the rescan condition. ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 27 2010 chinglan.wang ++ * NULL ++ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cp.wu ++ * NULL ++ * 1) initialize variable for enabling short premable/short time slot. ++ * 2) add compile option for disabling online scan ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * . ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * update params defined in CMD_SET_NETWORK_ADDRESS_LIST ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * fix for check build WHQL testing: ++ * 1) do not assert query buffer if indicated buffer length is zero ++ * 2) sdio.c has bugs which cause freeing same pointer twice ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 08 04 2010 george.huang ++ * NULL ++ * handle change PS mode OID/ CMD ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * bypass u4FuncData for RF-Test query request as well. ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 26 2010 cp.wu ++ * ++ * re-commit code logic being overwriten. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one ++ * 2) refine disconnection behaviour when issued during BG-SCAN process ++ * ++ * 07 19 2010 wh.su ++ * ++ * modify the auth and encry status variable. ++ * ++ * 07 16 2010 cp.wu ++ * ++ * remove work-around in case SCN is not available. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. ++ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add SCN compilation option. ++ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement SCAN-REQUEST oid as mailbox message dispatching. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * adding the compiling flag for oid pmkid. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move timer callback to glue layer. ++ * ++ * 05 28 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * simplify cmd packet sending for RF test and MCR access OIDs ++ * ++ * 05 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * disable radio even when STA is not associated. ++ * ++ * 05 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct 2 OID behaviour to meet WHQL requirement. ++ * ++ * 05 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) Modify set mac address code ++ * 2) remove power management macro ++ * ++ * 05 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct BSSID_LIST oid when radio if turned off. ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll ++ * 2) correct address list parsing ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * disable wlanoidSetNetworkAddress() temporally. ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * some OIDs should be DRIVER_CORE instead of GLUE_EXTENSION ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. ++ * 2) finish statistics OIDs ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change OID behavior to meet WHQL requirement. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement Wakeup-on-LAN except firmware integration part ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct wlanoidSet802dot11PowerSaveProfile implementation. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) enable CMD/EVENT ver 0.9 definition. ++ * 2) abandon use of ENUM_MEDIA_STATE ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_DISASSOCIATE handling. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add dissassocation support for wpa supplicant ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct return value. ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add NULL OID implementation for WOL-related OIDs. ++ * ++ * 05 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * for disassociation, still use parameter with current setting. ++ * ++ * 05 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * for disassociation, generate a WZC-compatible invalid SSID. ++ * ++ * 05 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * associate to illegal SSID when handling OID_802_11_DISASSOCIATE ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * reserve field of privacy filter and RTS threshold setting. ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support ++ * enable RX filter OID ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add ioctl of power management ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * 2) command sequence number is now increased atomically ++ * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_CONFIGURATION query for infrastructure mode. ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) remove unused spin lock declaration ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * are done in adapter layer. ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)improve none-glue code portability ++ * (2) disable set Multicast address during atomic context ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * ePowerCtrl is not necessary as a glue variable. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * statistics information OIDs are now handled by querying from firmware domain ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve glue code portability ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * the frequency is used for adhoc connection only ++ * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list ++ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result ++ * ++ * 03 19 2010 wh.su ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * adding the check for pass WHQL test item. ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++* 03 16 2010 wh.su ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * fixed some whql pre-test fail case. ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. ++ * ++ * 02 24 2010 wh.su ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * Don't needed to check the auth mode, WHQL testing not specific at auth wpa2. ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * do not check SSID validity anymore. ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * 2. follow MSDN defined behavior when associates to another AP ++ * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move ucCmdSeqNum as instance variable ++ * ++ * 02 04 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when OID_CUSTOM_OID_INTERFACE_VERSION is queried, do modify connection states ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) implement timeout mechanism when OID is pending for longer than 1 second ++ * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * 4. correct some HAL implementation ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * OID_802_11_RSSI, ++ * OID_802_11_RSSI_TRIGGER, ++ * OID_802_11_STATISTICS, ++ * OID_802_11_DISASSOCIATE, ++ * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * do not fill ucJoinOnly currently ++ * ++ * 01 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * enable to connect to ad-hoc network ++ * ++ * 01 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * .implement Set/Query BeaconInterval/AtimWindow ++ * ++ * 01 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * .Set/Get AT Info is not blocked even when driver is not in fg test mode ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * and result is retrieved by get ATInfo instead ++ * 2) add 4 counter for recording aggregation statistics ++ * ++ * 12 28 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate redundant variables for connection_state ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-16 22:13:36 GMT mtk02752 ++** change hard-coded MAC address to match with FW (temporally) ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-10 16:49:50 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-08 17:38:49 GMT mtk02752 ++** + add OID for RF test ++** * MCR RD/WR are modified to match with cmd/event definition ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-12-08 11:32:20 GMT mtk02752 ++** add skeleton for RF test implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-12-03 16:43:24 GMT mtk01461 ++** Modify query SCAN list oid by adding prEventScanResult ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-03 16:39:27 GMT mtk01461 ++** Sync CMD data structure in set ssid oid ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-03 16:28:22 GMT mtk01461 ++** Add invalid check of set SSID oid and fix query scan list oid ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-30 17:33:08 GMT mtk02752 ++** implement wlanoidSetInfrastructureMode/wlanoidQueryInfrastructureMode ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-30 10:53:49 GMT mtk02752 ++** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-30 09:22:48 GMT mtk02752 ++** correct wifi cmd length mismatch ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-25 21:34:33 GMT mtk02752 ++** sync EVENT_SCAN_RESULT_T with firmware ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 21:03:27 GMT mtk02752 ++** implement wlanoidQueryBssidList() ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-25 18:17:17 GMT mtk02752 ++** refine GL_WLAN_INFO_T for buffering scan result ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-23 20:28:51 GMT mtk02752 ++** some OID will be set to WLAN_STATUS_PENDING until it is sent via wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-23 17:56:36 GMT mtk02752 ++** implement wlanoidSetBssidListScan(), wlanoidSetBssid() and wlanoidSetSsid() ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-13 17:20:53 GMT mtk02752 ++** add Set BSSID/SSID path but disabled temporally due to FW is not ready yet ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 12:28:58 GMT mtk02752 ++** add wlanoidSetBssidListScan -> cmd_info path ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-09 22:48:07 GMT mtk01084 ++** modify test cases entry ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-04 14:10:58 GMT mtk01084 ++** add new test interfaces ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-30 18:17:10 GMT mtk01084 ++** fix compiler warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:46:26 GMT mtk01084 ++** add test functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:07:56 GMT mtk01084 ++** include new file ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:29 GMT mtk01084 ++** modify for new HW architecture ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-02 13:48:49 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-09-09 17:26:04 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-21 12:09:50 GMT mtk01461 ++** Update for MCR Write OID ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:35:18 GMT mtk01461 ++** Update wlanoidQueryMcrRead() for composing CMD_INFO_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 18:09:51 GMT mtk01426 ++** Remove kalIndicateStatusAndComplete() in wlanoidQueryOidInterfaceVersion() ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-14 15:51:50 GMT mtk01426 ++** Add MCR read/write support ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:40 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:06:31 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/****************************************************************************** ++* C O M P I L E R F L A G S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************* ++*/ ++#include "precomp.h" ++#include "mgmt/rsn.h" ++ ++#include ++ ++/****************************************************************************** ++* C O N S T A N T S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* D A T A T Y P E S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P U B L I C D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P R I V A T E D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* M A C R O S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N S ++******************************************************************************* ++*/ ++#if CFG_ENABLE_STATISTICS_BUFFERING ++static BOOLEAN IsBufferedStatisticsUsable(P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsStatValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= CFG_STATISTICS_VALID_CYCLE) ++ return TRUE; ++ else ++ return FALSE; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the supported physical layer network ++* type that can be used by the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ UINT_32 u4NumItem = 0; ++ ENUM_PARAM_NETWORK_TYPE_T eSupportedNetworks[PARAM_NETWORK_TYPE_NUM]; ++ PPARAM_NETWORK_TYPE_LIST prSupported; ++ ++ /* The array of all physical layer network subtypes that the driver supports. */ ++ ++ DEBUGFUNC("wlanoidQueryNetworkTypesSupported"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ /* Init. */ ++ for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; u4NumItem++) ++ eSupportedNetworks[u4NumItem] = 0; ++ ++ u4NumItem = 0; ++ ++ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS; ++ u4NumItem++; ++ ++ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24; ++ u4NumItem++; ++ ++ *pu4QueryInfoLen = ++ (UINT_32) OFFSET_OF(PARAM_NETWORK_TYPE_LIST, eNetworkType) + ++ (u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prSupported = (PPARAM_NETWORK_TYPE_LIST) pvQueryBuffer; ++ prSupported->NumberOfItems = u4NumItem; ++ kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); ++ ++ DBGLOG(OID, TRACE, "NDIS supported network type list: %u\n", prSupported->NumberOfItems); ++ DBGLOG_MEM8(OID, TRACE, prSupported, *pu4QueryInfoLen); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryNetworkTypesSupported */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current physical layer network ++* type used by the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ /* TODO: need to check the OID handler content again!! */ ++ ++ ENUM_PARAM_NETWORK_TYPE_T rCurrentNetworkTypeInUse = PARAM_NETWORK_TYPE_OFDM24; ++ ++ DEBUGFUNC("wlanoidQueryNetworkTypeInUse"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) ++ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkType); ++ else ++ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkTypeInUse); ++ ++ *(P_ENUM_PARAM_NETWORK_TYPE_T) pvQueryBuffer = rCurrentNetworkTypeInUse; ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ ++ DBGLOG(OID, TRACE, "Network type in use: %d\n", rCurrentNetworkTypeInUse); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryNetworkTypeInUse */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the physical layer network type used ++* by the driver. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns the ++* amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted. ++* \retval WLAN_STATUS_INVALID_DATA The given network type is not in the ++* supported list. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ /* TODO: need to check the OID handler content again!! */ ++ ++ ENUM_PARAM_NETWORK_TYPE_T eNewNetworkType; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidSetNetworkTypeInUse"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ eNewNetworkType = *(P_ENUM_PARAM_NETWORK_TYPE_T) pvSetBuffer; ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ ++ DBGLOG(OID, INFO, "New network type: %d mode\n", eNewNetworkType); ++ ++ switch (eNewNetworkType) { ++ ++ case PARAM_NETWORK_TYPE_DS: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ ++ case PARAM_NETWORK_TYPE_OFDM5: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; ++ break; ++ ++ case PARAM_NETWORK_TYPE_OFDM24: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; ++ break; ++ ++ case PARAM_NETWORK_TYPE_AUTOMODE: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_AUTOMODE; ++ break; ++ ++ case PARAM_NETWORK_TYPE_FH: ++ DBGLOG(OID, INFO, "Not support network type: %d\n", eNewNetworkType); ++ rStatus = WLAN_STATUS_NOT_SUPPORTED; ++ break; ++ ++ default: ++ DBGLOG(OID, INFO, "Unknown network type: %d\n", eNewNetworkType); ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ /* Verify if we support the new network type. */ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(OID, WARN, "Unknown network type: %d\n", eNewNetworkType); ++ ++ return rStatus; ++} /* wlanoidSetNetworkTypeInUse */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current BSSID. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidQueryBssid"); ++ ++ ASSERT(prAdapter); ++ ++ if (u4QueryBufferLen < MAC_ADDR_LEN) { ++ ASSERT(pu4QueryInfoLen); ++ *pu4QueryInfoLen = MAC_ADDR_LEN; ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) ++ kalMemCopy(pvQueryBuffer, prAdapter->rWlanInfo.rCurrBssId.arMacAddress, MAC_ADDR_LEN); ++ else if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS) { ++ PARAM_MAC_ADDRESS aucTemp; /*!< BSSID */ ++ ++ COPY_MAC_ADDR(aucTemp, prAdapter->rWlanInfo.rCurrBssId.arMacAddress); ++ aucTemp[0] &= ~BIT(0); ++ aucTemp[1] |= BIT(1); ++ COPY_MAC_ADDR(pvQueryBuffer, aucTemp); ++ } else ++ rStatus = WLAN_STATUS_ADAPTER_NOT_READY; ++ ++ *pu4QueryInfoLen = MAC_ADDR_LEN; ++ return rStatus; ++} /* wlanoidQueryBssid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the list of all BSSIDs detected by ++* the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 i, u4BssidListExLen; ++ P_PARAM_BSSID_LIST_EX_T prList; ++ P_PARAM_BSSID_EX_T prBssidEx; ++ PUINT_8 cp; ++ ++ DEBUGFUNC("wlanoidQueryBssidList"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) { ++ ASSERT(pvQueryBuffer); ++ ++ if (!pvQueryBuffer) ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ u4BssidListExLen = 0; ++ ++ if (prAdapter->fgIsRadioOff == FALSE) { ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) ++ u4BssidListExLen += ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4Length); ++ } ++ ++ if (u4BssidListExLen) ++ u4BssidListExLen += 4; /* u4NumberOfItems. */ ++ else ++ u4BssidListExLen = sizeof(PARAM_BSSID_LIST_EX_T); ++ ++ *pu4QueryInfoLen = u4BssidListExLen; ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* Clear the buffer */ ++ kalMemZero(pvQueryBuffer, u4BssidListExLen); ++ ++ prList = (P_PARAM_BSSID_LIST_EX_T) pvQueryBuffer; ++ cp = (PUINT_8) &prList->arBssid[0]; ++ ++ if (prAdapter->fgIsRadioOff == FALSE && prAdapter->rWlanInfo.u4ScanResultNum > 0) { ++ /* fill up for each entry */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ prBssidEx = (P_PARAM_BSSID_EX_T) cp; ++ ++ /* copy structure */ ++ kalMemCopy(prBssidEx, ++ &(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /*For WHQL test, Rssi should be in range -10 ~ -200 dBm */ ++ if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ ++ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { ++ /* copy IEs */ ++ kalMemCopy(prBssidEx->aucIEs, ++ prAdapter->rWlanInfo.apucScanResultIEs[i], ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength); ++ } ++ /* 4-bytes alignement */ ++ prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length); ++ ++ cp += prBssidEx->u4Length; ++ prList->u4NumberOfItems++; ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryBssidList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to perform ++* scanning. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_SSID_T prSsid; ++ PARAM_SSID_T rSsid; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidSetBssidListScan()"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = 0; ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(OID, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ DBGLOG(OID, TRACE, "Scan\n"); ++ ++ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, u4SetBufferLen); ++ prSsid = &rSsid; ++ } else { ++ prSsid = NULL; ++ } ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { ++ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); ++ } else { ++ /* reject the scan request */ ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else { ++ /* reject the scan request */ ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else ++#endif ++ { ++ if (prAdapter->fgEnOnlineScan == TRUE) { ++ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); ++ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); ++ } else { ++ /* reject the scan request */ ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ return rStatus; ++} /* wlanoidSetBssidListScan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to perform ++* scanning with attaching information elements(IEs) specified from user space ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_SCAN_REQUEST_EXT_T prScanRequest; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_PARAM_SSID_T prSsid; ++ PUINT_8 pucIe; ++ UINT_32 u4IeLength; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_8 ucScanTime = AIS_SCN_DONE_TIMEOUT_SEC; ++ ++ DEBUGFUNC("wlanoidSetBssidListScanExt()"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, ERROR, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (prAdapter->fgTestMode) { ++ DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)) { ++ DBGLOG(OID, ERROR, "u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(OID, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ DBGLOG(OID, TRACE, "ScanEx\n"); ++ ++ /* clear old scan backup results if exists */ ++ { ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); ++ prBssDesc->u2RawLength = 0; ++ } ++ } ++ } ++ ++ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { ++ prScanRequest = (P_PARAM_SCAN_REQUEST_EXT_T) pvSetBuffer; ++ prSsid = &(prScanRequest->rSsid); ++ pucIe = prScanRequest->pucIE; ++ u4IeLength = prScanRequest->u4IELength; ++ } else { ++ prScanRequest = NULL; ++ prSsid = NULL; ++ pucIe = NULL; ++ u4IeLength = 0; ++ } ++ ++/* P_AIS_FSM_INFO_T prAisFsmInfo; */ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++/* #if CFG_SUPPORT_WFD */ ++#if 0 ++ if ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.ucWfdEnable) && ++ ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == ++ PARAM_MEDIA_STATE_CONNECTED) { ++ DBGLOG(OID, TRACE, "Twice the Scan Time for WFD\n"); ++ ucScanTime *= 2; ++ } ++ } ++#endif /* CFG_SUPPORT_WFD */ ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer, SEC_TO_MSEC(ucScanTime)); ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { ++ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); ++ } else { ++ /* reject the scan request */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else { ++ /* reject the scan request */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else ++#endif ++ { ++ if (prAdapter->fgEnOnlineScan == TRUE) { ++ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); ++ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); ++ } else { ++ /* reject the scan request */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ rStatus = WLAN_STATUS_FAILURE; ++ DBGLOG(OID, WARN, "ScanEx fail %d!\n", prAdapter->fgEnOnlineScan); ++ } ++ } ++ ++ return rStatus; ++} /* wlanoidSetBssidListScanWithIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine will initiate the join procedure to attempt to associate ++* with the specified BSSID. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_UINT_8 pAddr; ++ UINT_32 i; ++ INT_32 i4Idx = -1; ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ UINT_8 ucReasonOfDisconnect; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = MAC_ADDR_LEN; ++ if (u4SetBufferLen != MAC_ADDR_LEN) { ++ *pu4SetInfoLen = MAC_ADDR_LEN; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ pAddr = (P_UINT_8) pvSetBuffer; ++ ++ /* re-association check */ ++ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) { ++ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); ++ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; ++ } else { ++ DBGLOG(OID, TRACE, "DisByBssid\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ } ++ } else { ++ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ } ++ ++ /* check if any scanned result matchs with the BSSID */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { ++ i4Idx = (INT_32) i; ++ break; ++ } ++ } ++ ++ /* prepare message to AIS */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS ++ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { ++ /* IBSS *//* beacon period */ ++ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; ++ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; ++ } ++ ++ /* Set Connection Request Issued Flag */ ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; ++ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_BSSID; ++ ++ /* Send AIS Abort Message */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect; ++ ++ /* Update the information to CONNECTION_SETTINGS_T */ ++ prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0; ++ prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0'; ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr); ++ ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) ++ prAisAbortMsg->fgDelayIndication = TRUE; ++ else ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ DBGLOG(OID, INFO, "SetBssid\n"); ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetBssid() */ ++ ++WLAN_STATUS ++wlanoidSetConnect(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_CONNECT_T pParamConn; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_32 i; ++ /*INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;*/ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ BOOLEAN fgIsValidSsid = TRUE; ++ BOOLEAN fgEqualSsid = FALSE; ++ BOOLEAN fgEqualBssid = FALSE; ++ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* MSDN: ++ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE ++ */ ++ if (prAdapter->fgIsRadioOff == TRUE) ++ prAdapter->fgIsRadioOff = FALSE; ++ ++ if (u4SetBufferLen != sizeof(PARAM_CONNECT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ else if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ ++ pParamConn = (P_PARAM_CONNECT_T) pvSetBuffer; ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ ++ if (pParamConn->u4SsidLen > 32) { ++ cnmMemFree(prAdapter, prAisAbortMsg); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (!pParamConn->pucBssid && !pParamConn->pucSsid) { ++ cnmMemFree(prAdapter, prAisAbortMsg); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ kalMemZero(prConnSettings->aucSSID, sizeof(prConnSettings->aucSSID)); ++ kalMemZero(prConnSettings->aucBSSID, sizeof(prConnSettings->aucBSSID)); ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; ++ prConnSettings->fgIsConnByBssidIssued = FALSE; ++ ++ if (pParamConn->pucSsid) { ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ COPY_SSID(prConnSettings->aucSSID, ++ prConnSettings->ucSSIDLen, pParamConn->pucSsid, (UINT_8) pParamConn->u4SsidLen); ++ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, ++ pParamConn->pucSsid, pParamConn->u4SsidLen)) ++ fgEqualSsid = TRUE; ++ } ++ if (pParamConn->pucBssid) { ++ if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) { ++ prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID; ++ prConnSettings->fgIsConnByBssidIssued = TRUE; ++ COPY_MAC_ADDR(prConnSettings->aucBSSID, pParamConn->pucBssid); ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pParamConn->pucBssid)) ++ fgEqualBssid = TRUE; ++ } else ++ DBGLOG(OID, TRACE, "wrong bssid %pM to connect\n", pParamConn->pucBssid); ++ } else ++ DBGLOG(OID, TRACE, "No Bssid set\n"); ++ prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq; ++ ++ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ ++ /* re-association check */ ++ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (fgEqualSsid) { ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_ROAMING; ++ if (fgEqualBssid) { ++ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; ++ } ++ } else { ++ DBGLOG(OID, TRACE, "DisBySsid\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ } ++ } else ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++#if 0 ++ /* check if any scanned result matchs with the SSID */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; ++ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; ++ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; ++ ++ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, pParamConn->u4SsidLen) && ++ i4RSSI >= i4MaxRSSI) { ++ i4Idx = (INT_32) i; ++ i4MaxRSSI = i4RSSI; ++ } ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { ++ i4Idx = (INT_32) i; ++ break; ++ } ++ } ++#endif ++ /* prepare message to AIS */ ++ if (prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { ++ /* IBSS *//* beacon period */ ++ prConnSettings->u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; ++ prConnSettings->u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; ++ } ++ ++ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { ++ if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) { ++ fgIsValidSsid = FALSE; ++ ++ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { ++ if (pParamConn->pucSsid) { ++ if (!((0 < pParamConn->pucSsid[i]) && (pParamConn->pucSsid[i] <= 0x1F))) { ++ fgIsValidSsid = TRUE; ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ /* Set Connection Request Issued Flag */ ++ if (fgIsValidSsid) ++ prConnSettings->fgIsConnReqIssued = TRUE; ++ else ++ prConnSettings->fgIsConnReqIssued = FALSE; ++ ++ if (fgEqualSsid || fgEqualBssid) ++ prAisAbortMsg->fgDelayIndication = TRUE; ++ else ++ /* Update the information to CONNECTION_SETTINGS_T */ ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ DBGLOG(OID, INFO, "ssid %s, bssid %pM, conn policy %d, disc reason %d\n", ++ prConnSettings->aucSSID, prConnSettings->aucBSSID, ++ prConnSettings->eConnectionPolicy, prAisAbortMsg->ucReasonOfDisconnect); ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine will initiate the join procedure to attempt ++* to associate with the new SSID. If the previous scanning ++* result is aged, we will scan the channels at first. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_SSID_T pParamSsid; ++ UINT_32 i; ++ INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN; ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ BOOLEAN fgIsValidSsid = TRUE; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* MSDN: ++ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE ++ */ ++ if (prAdapter->fgIsRadioOff == TRUE) ++ prAdapter->fgIsRadioOff = FALSE; ++ ++ if (u4SetBufferLen < sizeof(PARAM_SSID_T) || u4SetBufferLen > sizeof(PARAM_SSID_T)) { ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ pParamSsid = (P_PARAM_SSID_T) pvSetBuffer; ++ ++ if (pParamSsid->u4SsidLen > 32) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ ++ /* re-association check */ ++ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, ++ pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { ++ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); ++ } else { ++ DBGLOG(OID, TRACE, "DisBySsid\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ } ++ } ++ /* check if any scanned result matchs with the SSID */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; ++ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; ++ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; ++ ++ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, pParamSsid->u4SsidLen) && ++ i4RSSI >= i4MaxRSSI) { ++ i4Idx = (INT_32) i; ++ i4MaxRSSI = i4RSSI; ++ } ++ } ++ ++ /* prepare message to AIS */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS ++ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { ++ /* IBSS *//* beacon period */ ++ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; ++ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; ++ } ++ ++ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { ++ if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) { ++ fgIsValidSsid = FALSE; ++ ++ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { ++ if (!((0 < pParamSsid->aucSsid[i]) && (pParamSsid->aucSsid[i] <= 0x1F))) { ++ fgIsValidSsid = TRUE; ++ break; ++ } ++ } ++ } ++ } ++ ++ /* Set Connection Request Issued Flag */ ++ if (fgIsValidSsid) { ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; ++ ++ if (pParamSsid->u4SsidLen) { ++ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ } else { ++ /* wildcard SSID */ ++ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_ANY; ++ } ++ } else { ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ } ++ ++ /* Send AIS Abort Message */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ ++ COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, ++ prAdapter->rWifiVar.rConnSettings.ucSSIDLen, pParamSsid->aucSsid, (UINT_8) pParamSsid->u4SsidLen); ++ ++ prAdapter->rWifiVar.rConnSettings.u4FreqInKHz = pParamSsid->u4CenterFreq; ++ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { ++ prAisAbortMsg->fgDelayIndication = TRUE; ++ } else { ++ /* Update the information to CONNECTION_SETTINGS_T */ ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ } ++ DBGLOG(SCN, INFO, "SSID %s\n", prAdapter->rWifiVar.rConnSettings.aucSSID); ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wlanoidSetSsid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the currently associated SSID. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_SSID_T prAssociatedSsid; ++ ++ DEBUGFUNC("wlanoidQuerySsid"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_SSID_T); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prAssociatedSsid = (P_PARAM_SSID_T) pvQueryBuffer; ++ ++ kalMemZero(prAssociatedSsid->aucSsid, sizeof(prAssociatedSsid->aucSsid)); ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ prAssociatedSsid->u4SsidLen = prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen; ++ ++ if (prAssociatedSsid->u4SsidLen) { ++ kalMemCopy(prAssociatedSsid->aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, prAssociatedSsid->u4SsidLen); ++ } ++ } else { ++ prAssociatedSsid->u4SsidLen = 0; ++ ++ DBGLOG(OID, TRACE, "Null SSID\n"); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQuerySsid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current 802.11 network type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryInfrastructureMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eOPMode; ++ ++ /* ++ ** According to OID_802_11_INFRASTRUCTURE_MODE ++ ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE, ++ ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned. ++ */ ++#if DBG ++ switch (*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer) { ++ case NET_TYPE_IBSS: ++ DBGLOG(OID, INFO, "IBSS mode\n"); ++ break; ++ case NET_TYPE_INFRA: ++ DBGLOG(OID, INFO, "Infrastructure mode\n"); ++ break; ++ default: ++ DBGLOG(OID, INFO, "Automatic mode\n"); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryInfrastructureMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set mode to infrastructure or ++* IBSS, or automatic switch between the two. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid ++* length of the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ ++ DEBUGFUNC("wlanoidSetInfrastructureMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ eOpMode = *(P_ENUM_PARAM_OP_MODE_T) pvSetBuffer; ++ /* Verify the new infrastructure mode. */ ++ if (eOpMode >= NET_TYPE_NUM) { ++ DBGLOG(OID, TRACE, "Invalid mode value %d\n", eOpMode); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* check if possible to switch to AdHoc mode */ ++ if (eOpMode == NET_TYPE_IBSS || eOpMode == NET_TYPE_DEDICATED_IBSS) { ++ if (cnmAisIbssIsPermitted(prAdapter) == FALSE) { ++ DBGLOG(OID, TRACE, "Mode value %d unallowed\n", eOpMode); ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ /* Save the new infrastructure mode setting. */ ++ prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode; ++ ++ /* Clean up the Tx key flag */ ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; ++ ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; ++#if CFG_SUPPORT_WAPI ++ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; ++ kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42); ++#endif ++ ++#if CFG_SUPPORT_802_11W ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = FALSE; ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++ kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200); ++ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INFRASTRUCTURE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, nicOidCmdTimeoutCommon, 0, NULL, pvSetBuffer, u4SetBufferLen); ++ ++} /* wlanoidSetInfrastructureMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current 802.11 authentication ++* mode. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryAuthMode"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eAuthMode; ++ ++#if DBG ++ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer) { ++ case AUTH_MODE_OPEN: ++ DBGLOG(OID, INFO, "Current auth mode: Open\n"); ++ break; ++ ++ case AUTH_MODE_SHARED: ++ DBGLOG(OID, INFO, "Current auth mode: Shared\n"); ++ break; ++ ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(OID, INFO, "Current auth mode: Auto-switch\n"); ++ break; ++ ++ case AUTH_MODE_WPA: ++ DBGLOG(OID, INFO, "Current auth mode: WPA\n"); ++ break; ++ ++ case AUTH_MODE_WPA_PSK: ++ DBGLOG(OID, INFO, "Current auth mode: WPA PSK\n"); ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ DBGLOG(OID, INFO, "Current auth mode: WPA None\n"); ++ break; ++ ++ case AUTH_MODE_WPA2: ++ DBGLOG(OID, INFO, "Current auth mode: WPA2\n"); ++ break; ++ ++ case AUTH_MODE_WPA2_PSK: ++ DBGLOG(OID, INFO, "Current auth mode: WPA2 PSK\n"); ++ break; ++ ++ default: ++ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); ++ break; ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryAuthMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the IEEE 802.11 authentication mode ++* to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 i, u4AkmSuite; ++ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; ++ ++ DEBUGFUNC("wlanoidSetAuthMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* RF Test */ ++ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ ++ /* return WLAN_STATUS_SUCCESS; */ ++ /* } */ ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ /* Check if the new authentication mode is valid. */ ++ if (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer >= AUTH_MODE_NUM) { ++ DBGLOG(OID, TRACE, "Invalid auth mode %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer) { ++ case AUTH_MODE_WPA: ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA2: ++ case AUTH_MODE_WPA2_PSK: ++ /* infrastructure mode only */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_INFRA) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ /* ad hoc mode only */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_IBSS) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Save the new authentication mode. */ ++ prAdapter->rWifiVar.rConnSettings.eAuthMode = *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer; ++ ++#if DBG ++ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { ++ case AUTH_MODE_OPEN: ++ DBGLOG(RSN, TRACE, "New auth mode: open\n"); ++ break; ++ ++ case AUTH_MODE_SHARED: ++ DBGLOG(RSN, TRACE, "New auth mode: shared\n"); ++ break; ++ ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n"); ++ break; ++ ++ case AUTH_MODE_WPA: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA\n"); ++ break; ++ ++ case AUTH_MODE_WPA_PSK: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n"); ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA None\n"); ++ break; ++ ++ case AUTH_MODE_WPA2: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA2\n"); ++ break; ++ ++ case AUTH_MODE_WPA2_PSK: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n"); ++ break; ++ ++ default: ++ DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", prAdapter->rWifiVar.rConnSettings.eAuthMode); ++ } ++#endif ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA) { ++ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { ++ case AUTH_MODE_WPA: ++ u4AkmSuite = WPA_AKM_SUITE_802_1X; ++ break; ++ ++ case AUTH_MODE_WPA_PSK: ++ u4AkmSuite = WPA_AKM_SUITE_PSK; ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ u4AkmSuite = WPA_AKM_SUITE_NONE; ++ break; ++ ++ case AUTH_MODE_WPA2: ++ u4AkmSuite = RSN_AKM_SUITE_802_1X; ++ break; ++ ++ case AUTH_MODE_WPA2_PSK: ++ u4AkmSuite = RSN_AKM_SUITE_PSK; ++ break; ++ ++ default: ++ u4AkmSuite = 0; ++ } ++ } else { ++ u4AkmSuite = 0; ++ } ++ ++ /* Enable the specific AKM suite only. */ ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { ++ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; ++ ++ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite) ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE; ++#if CFG_SUPPORT_802_11W ++ if (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) { ++ if ((u4AkmSuite == RSN_AKM_SUITE_PSK) && ++ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_PSK_SHA256) { ++ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n"); ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; ++ ++ } ++ if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) && ++ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_802_1X_SHA256) { ++ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n"); ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; ++ } ++ } ++#endif ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetAuthMode */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current 802.11 privacy filter ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryPrivacyFilter"); ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer = prAdapter->rWlanInfo.ePrivacyFilter; ++ ++#if DBG ++ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer) { ++ case PRIVACY_FILTER_ACCEPT_ALL: ++ DBGLOG(OID, INFO, "Current privacy mode: open mode\n"); ++ break; ++ ++ case PRIVACY_FILTER_8021xWEP: ++ DBGLOG(OID, INFO, "Current privacy mode: filtering mode\n"); ++ break; ++ ++ default: ++ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryPrivacyFilter */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the IEEE 802.11 privacy filter ++* to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DEBUGFUNC("wlanoidSetPrivacyFilter"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ /* Check if the new authentication mode is valid. */ ++ if (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer >= PRIVACY_FILTER_NUM) { ++ DBGLOG(OID, TRACE, "Invalid privacy filter %d\n", *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer) { ++ default: ++ break; ++ } ++ ++ /* Save the new authentication mode. */ ++ prAdapter->rWlanInfo.ePrivacyFilter = *(ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetPrivacyFilter */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to reload the available default settings for ++* the specified type field. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; ++ UINT_32 u4Len; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanoidSetReloadDefaults"); ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = sizeof(PARAM_RELOAD_DEFAULTS); ++ ++ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ ++ /* return WLAN_STATUS_SUCCESS; */ ++ /* } */ ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ /* Verify the available reload options and reload the settings. */ ++ switch (*(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer) { ++ case ENUM_RELOAD_WEP_KEYS: ++ /* Reload available default WEP keys from the permanent ++ storage. */ ++ prAdapter->rWifiVar.rConnSettings.eAuthMode = AUTH_MODE_OPEN; ++ /* ENUM_ENCRYPTION_DISABLED; */ ++ prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; ++ { ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_802_11_KEY prCmdKey; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_802_11_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 0; /* Remove */ ++ prCmdKey->ucKeyId = 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & 0x000000ff); */ ++ kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, MAC_ADDR_LEN); ++ ++ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); ++ ++ prCmdKey->ucKeyType = 0; ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++ } ++ ++ break; ++ ++ default: ++ DBGLOG(OID, TRACE, "Invalid reload option %d\n", *(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer); ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */ ++ eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE; ++ wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, sizeof(eNetworkType), &u4Len); ++ ++ return rStatus; ++} /* wlanoidSetReloadDefaults */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a WEP key to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++#ifdef LINUX ++UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; ++UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++#endif ++WLAN_STATUS ++wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#ifndef LINUX ++ UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++#endif ++ P_PARAM_WEP_T prNewWepKey; ++ P_PARAM_KEY_T prParamKey = (P_PARAM_KEY_T) keyBuffer; ++ UINT_32 u4KeyId, u4SetLen; ++ ++ DEBUGFUNC("wlanoidSetAddWep"); ++ ++ ASSERT(prAdapter); ++ ++ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); ++ ++ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)) { ++ ASSERT(pu4SetInfoLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prNewWepKey = (P_PARAM_WEP_T) pvSetBuffer; ++ ++ /* Verify the total buffer for minimum length. */ ++ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial) + prNewWepKey->u4KeyLength) { ++ DBGLOG(OID, WARN, "Invalid total buffer length (%d) than minimum length (%d)\n", ++ (UINT_8) u4SetBufferLen, (UINT_8) OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)); ++ ++ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Verify the key structure length. */ ++ if (prNewWepKey->u4Length > u4SetBufferLen) { ++ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewWepKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Verify the key material length for maximum key material length:16 */ ++ if (prNewWepKey->u4KeyLength > 16 /* LEGACY_KEY_MAX_LEN */) { ++ DBGLOG(OID, WARN, "Invalid key material length (%d) greater than maximum key material length (16)\n", ++ (UINT_8) prNewWepKey->u4KeyLength); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, 29) /* WEP_KEY_ID_FIELD */; ++ ++ /* Verify whether key index is valid or not, current version ++ driver support only 4 global WEP keys setting by this OID */ ++ if (u4KeyId > MAX_KEY_NUM - 1) { ++ DBGLOG(OID, ERROR, "Error, invalid WEP key ID: %d\n", (UINT_8) u4KeyId); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ prParamKey->u4KeyIndex = u4KeyId; ++ ++ /* Transmit key */ ++ if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY) ++ prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY; ++ ++ /* Per client key */ ++ if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY) ++ prParamKey->u4KeyIndex |= IS_UNICAST_KEY; ++ ++ prParamKey->u4KeyLength = prNewWepKey->u4KeyLength; ++ ++ kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN); ++ ++ kalMemCopy(prParamKey->aucKeyMaterial, prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength); ++ ++ prParamKey->u4Length = OFFSET_OF(PARAM_KEY_T, aucKeyMaterial) + prNewWepKey->u4KeyLength; ++ ++ wlanoidSetAddKey(prAdapter, (PVOID) prParamKey, prParamKey->u4Length, &u4SetLen); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetAddWep */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to remove the WEP key ++* at the specified key index. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 u4KeyId, u4SetLen; ++ PARAM_REMOVE_KEY_T rRemoveKey; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ ++ DEBUGFUNC("wlanoidSetRemoveWep"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_KEY_INDEX); ++ ++ if (u4SetBufferLen < sizeof(PARAM_KEY_INDEX)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ u4KeyId = *(PUINT_32) pvSetBuffer; ++ ++ /* Dump PARAM_WEP content. */ ++ DBGLOG(OID, INFO, "Set: Dump PARAM_KEY_INDEX content\n"); ++ DBGLOG(OID, INFO, "Index : 0x%08x\n", u4KeyId); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (u4KeyId & IS_TRANSMIT_KEY) { ++ /* Bit 31 should not be set */ ++ DBGLOG(OID, ERROR, "Invalid WEP key index: 0x%08x\n", u4KeyId); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ u4KeyId &= BITS(0, 7); ++ ++ /* Verify whether key index is valid or not. Current version ++ driver support only 4 global WEP keys. */ ++ if (u4KeyId > MAX_KEY_NUM - 1) { ++ DBGLOG(OID, ERROR, "invalid WEP key ID %u\n", u4KeyId); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); ++ rRemoveKey.u4KeyIndex = *(PUINT_32) pvSetBuffer; ++ ++ kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN); ++ ++ wlanoidSetRemoveKey(prAdapter, (PVOID)&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T), &u4SetLen); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetRemoveWep */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a key to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_PARAM_KEY_T prNewKey; ++ P_CMD_802_11_KEY prCmdKey; ++ UINT_8 ucCmdSeqNum; ++ ++#if 0 ++ DEBUGFUNC("wlanoidSetAddKey"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++#endif ++ ++ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; ++ ++#if 0 ++ /* Verify the key structure length. */ ++ if (prNewKey->u4Length > u4SetBufferLen) { ++ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ /* Verify the key material length for key material buffer */ ++ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { ++ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Exception check */ ++ if (prNewKey->u4KeyIndex & 0x0fffff00) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || ++ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { ++ if (((prNewKey->u4KeyIndex & 0xff) != 0) || ++ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) ++ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) ++ && (prNewKey->arBSSID[5] == 0xff))) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++#endif ++ ++ /* Dump PARAM_KEY content. */ ++ DBGLOG(OID, TRACE, "Set: PARAM_KEY Length: 0x%08x, Key Index: 0x%08x, Key Length: 0x%08x\n", ++ prNewKey->u4Length, prNewKey->u4KeyIndex, prNewKey->u4KeyLength); ++ DBGLOG(OID, TRACE, "BSSID:\n"); ++ DBGLOG_MEM8(OID, TRACE, prNewKey->arBSSID, sizeof(PARAM_MAC_ADDRESS)); ++ DBGLOG(OID, TRACE, "Key RSC:\n"); ++ DBGLOG_MEM8(OID, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC)); ++ DBGLOG(OID, TRACE, "Key Material:\n"); ++ DBGLOG_MEM8(OID, TRACE, prNewKey->aucKeyMaterial, prNewKey->u4KeyLength); ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { ++ /* Todo:: Store the legacy wep key for OID_802_11_RELOAD_DEFAULTS */ ++ /* Todo:: Nothing */ ++ } ++ ++ if (prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = TRUE; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(OID, TRACE, "ucCmdSeqNum = %d\n", ucCmdSeqNum); ++ ++ /* compose CMD_802_11_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = fgIsOid; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetBufferLen; ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 1; /* Add */ ++ ++ prCmdKey->ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; ++ prCmdKey->ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; ++ prCmdKey->ucIsAuthenticator = ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) ? 1 : 0; ++ ++ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->arBSSID, MAC_ADDR_LEN); ++ ++ prCmdKey->ucNetType = 0; /* AIS */ ++ ++ prCmdKey->ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); ++ ++ /* Note: adjust the key length for WPA-None */ ++ prCmdKey->ucKeyLen = (UINT_8) prNewKey->u4KeyLength; ++ ++ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen); ++ ++ if (prNewKey->u4KeyLength == 5) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40; ++ } else if (prNewKey->u4KeyLength == 13) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104; ++ } else if (prNewKey->u4KeyLength == 16) { ++ if ((ucAlgorithmId != CIPHER_SUITE_CCMP) && ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA)) ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128; ++ else { ++#if CFG_SUPPORT_802_11W ++ if (prCmdKey->ucKeyId >= 4) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_BIP; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ prAisSpecBssInfo->fgBipKeyInstalled = TRUE; ++ } else ++#endif ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; ++ if (rsnCheckPmkidCandicate(prAdapter)) { ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ DBGLOG(RSN, TRACE, ++ "Add key: Prepare a timer to indicate candidate PMKID Candidate\n"); ++ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); ++ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, ++ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); ++ } ++ } ++ } else if (prNewKey->u4KeyLength == 32) { ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; ++ else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; ++ prCmdKey->ucKeyLen = CCMP_KEY_LEN; ++ } ++ } else ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; ++ } ++ ++ DBGLOG(RSN, TRACE, "prCmdKey->ucAlgorithmId=%d, key len=%d\n", ++ prCmdKey->ucAlgorithmId, (UINT32) prNewKey->u4KeyLength); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} ++ ++WLAN_STATUS ++wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_KEY_T prNewKey; ++ ++ DEBUGFUNC("wlanoidSetAddKey"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; ++ ++ /* Verify the key structure length. */ ++ if (prNewKey->u4Length > u4SetBufferLen) { ++ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ /* Verify the key material length for key material buffer */ ++ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { ++ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Exception check */ ++ if (prNewKey->u4KeyIndex & 0x0fffff00) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { ++ if (((prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN) && ++ (prNewKey->u4KeyIndex & 0xff) != 0) || ++ EQUAL_MAC_ADDR(prNewKey->arBSSID, "\xff\xff\xff\xff\xff\xff")) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ } else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || ++ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* ++ supplicant will set key before updating station & enabling the link so we need to ++ backup the key information and set key when link is enabled ++ */ ++ if (TdlsexKeyHandle(prAdapter, prNewKey) == TDLS_STATUS_SUCCESS) ++ return WLAN_STATUS_SUCCESS; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ return _wlanoidSetAddKey(prAdapter, pvSetBuffer, u4SetBufferLen, TRUE, CIPHER_SUITE_NONE, pu4SetInfoLen); ++} /* wlanoidSetAddKey */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to remove the key at ++* the specified key index. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_PARAM_REMOVE_KEY_T prRemovedKey; ++ P_CMD_802_11_KEY prCmdKey; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanoidSetRemoveKey"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; ++ ++ /* Dump PARAM_REMOVE_KEY content. */ ++ DBGLOG(OID, TRACE, "Set: Dump PARAM_REMOVE_KEY content\n"); ++ DBGLOG(OID, TRACE, "Length : 0x%08x\n", prRemovedKey->u4Length); ++ DBGLOG(OID, TRACE, "Key Index : 0x%08x\n", prRemovedKey->u4KeyIndex); ++ DBGLOG(OID, TRACE, "BSSID:\n"); ++ DBGLOG_MEM8(OID, TRACE, prRemovedKey->arBSSID, MAC_ADDR_LEN); ++ ++ /* Check bit 31: this bit should always 0 */ ++ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { ++ /* Bit 31 should not be set */ ++ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Check bits 8 ~ 29 should always be 0 */ ++ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { ++ /* Bit 31 should not be set */ ++ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Clean up the Tx key flag */ ++ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_802_11_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 0; /* Remove */ ++ prCmdKey->ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); ++ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); ++ ++#if CFG_SUPPORT_802_11W ++ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM + 2); ++#else ++ /* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */ ++#endif ++ ++ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) ++ prCmdKey->ucKeyType = 1; ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetRemoveKey */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current encryption status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ BOOLEAN fgTransmitKeyAvailable = TRUE; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus = 0; ++ ++ DEBUGFUNC("wlanoidQueryEncryptionStatus"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); ++ ++ fgTransmitKeyAvailable = prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist; ++ ++ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { ++ case ENUM_ENCRYPTION3_ENABLED: ++ if (fgTransmitKeyAvailable) ++ eEncStatus = ENUM_ENCRYPTION3_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT; ++ break; ++ ++ case ENUM_ENCRYPTION2_ENABLED: ++ if (fgTransmitKeyAvailable) { ++ eEncStatus = ENUM_ENCRYPTION2_ENABLED; ++ break; ++ } ++ eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT; ++ break; ++ ++ case ENUM_ENCRYPTION1_ENABLED: ++ if (fgTransmitKeyAvailable) ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; ++ break; ++ ++ case ENUM_ENCRYPTION_DISABLED: ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ break; ++ ++ default: ++ DBGLOG(OID, ERROR, "Unknown Encryption Status Setting:%d\n", ++ prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ } ++ ++#if DBG ++ DBGLOG(OID, INFO, ++ "Encryption status: %d Return:%d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus); ++#endif ++ ++ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvQueryBuffer = eEncStatus; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryEncryptionStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the encryption status to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_NOT_SUPPORTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEewEncrypt; ++ ++ DEBUGFUNC("wlanoidSetEncryptionStatus"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); ++ ++ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ ++ /* return WLAN_STATUS_SUCCESS; */ ++ /* } */ ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ eEewEncrypt = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; ++ DBGLOG(OID, TRACE, "ENCRYPTION_STATUS %d\n", eEewEncrypt); ++ ++ switch (eEewEncrypt) { ++ case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */ ++ DBGLOG(RSN, TRACE, "Disable Encryption\n"); ++ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); ++ break; ++ ++ case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */ ++ DBGLOG(RSN, TRACE, "Enable Encryption1\n"); ++ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); ++ break; ++ ++ case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */ ++ secSetCipherSuite(prAdapter, ++ CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP); ++ DBGLOG(RSN, TRACE, "Enable Encryption2\n"); ++ break; ++ ++ case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */ ++ secSetCipherSuite(prAdapter, ++ CIPHER_FLAG_WEP40 | ++ CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP); ++ DBGLOG(RSN, TRACE, "Enable Encryption3\n"); ++ break; ++ ++ default: ++ DBGLOG(RSN, WARN, "Unacceptible encryption status: %d\n", ++ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer); ++ ++ rStatus = WLAN_STATUS_NOT_SUPPORTED; ++ } ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ /* Save the new encryption status. */ ++ prAdapter->rWifiVar.rConnSettings.eEncStatus = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; ++ ++ DBGLOG(RSN, TRACE, "wlanoidSetEncryptionStatus to %d\n", ++ prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ } ++ ++ return rStatus; ++} /* wlanoidSetEncryptionStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to test the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_802_11_TEST_T prTest; ++ PVOID pvTestData; ++ PVOID pvStatusBuffer; ++ UINT_32 u4StatusBufferSize; ++ ++ DEBUGFUNC("wlanoidSetTest"); ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ prTest = (P_PARAM_802_11_TEST_T) pvSetBuffer; ++ ++ DBGLOG(OID, TRACE, "Test - Type %u\n", prTest->u4Type); ++ ++ switch (prTest->u4Type) { ++ case 1: /* Type 1: generate an authentication event */ ++ pvTestData = (PVOID) &prTest->u.AuthenticationEvent; ++ pvStatusBuffer = (PVOID) prAdapter->aucIndicationEventBuffer; ++ u4StatusBufferSize = prTest->u4Length - 8; ++ if (u4StatusBufferSize > sizeof(PARAM_AUTH_EVENT_T)) { ++ DBGLOG(OID, TRACE, "prTest->u4Length error %u\n", u4StatusBufferSize); ++ ASSERT(FALSE); ++ } ++ break; ++ ++ case 2: /* Type 2: generate an RSSI status indication */ ++ pvTestData = (PVOID) &prTest->u.RssiTrigger; ++ pvStatusBuffer = (PVOID) &prAdapter->rWlanInfo.rCurrBssId.rRssi; ++ u4StatusBufferSize = sizeof(PARAM_RSSI); ++ break; ++ ++ default: ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ ASSERT(u4StatusBufferSize <= 180); ++ if (u4StatusBufferSize > 180) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* Get the contents of the StatusBuffer from the test structure. */ ++ kalMemCopy(pvStatusBuffer, pvTestData, u4StatusBufferSize); ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, pvStatusBuffer, u4StatusBufferSize); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetTest */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the driver's WPA2 status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CAPABILITY_T prCap; ++ P_PARAM_AUTH_ENCRYPTION_T prAuthenticationEncryptionSupported; ++ ++ DEBUGFUNC("wlanoidQueryCapability"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = 4 * sizeof(UINT_32) + 14 * sizeof(PARAM_AUTH_ENCRYPTION_T); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prCap = (P_PARAM_CAPABILITY_T) pvQueryBuffer; ++ ++ prCap->u4Length = *pu4QueryInfoLen; ++ prCap->u4Version = 2; /* WPA2 */ ++ prCap->u4NoOfPMKIDs = CFG_MAX_PMKID_CACHE; ++ prCap->u4NoOfAuthEncryptPairsSupported = 14; ++ ++ prAuthenticationEncryptionSupported = &prCap->arAuthenticationEncryptionSupported[0]; ++ ++ /* fill 14 entries of supported settings */ ++ prAuthenticationEncryptionSupported[0].eAuthModeSupported = AUTH_MODE_OPEN; ++ ++ prAuthenticationEncryptionSupported[0].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; ++ ++ prAuthenticationEncryptionSupported[1].eAuthModeSupported = AUTH_MODE_OPEN; ++ prAuthenticationEncryptionSupported[1].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; ++ ++ prAuthenticationEncryptionSupported[2].eAuthModeSupported = AUTH_MODE_SHARED; ++ prAuthenticationEncryptionSupported[2].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; ++ ++ prAuthenticationEncryptionSupported[3].eAuthModeSupported = AUTH_MODE_SHARED; ++ prAuthenticationEncryptionSupported[3].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; ++ ++ prAuthenticationEncryptionSupported[4].eAuthModeSupported = AUTH_MODE_WPA; ++ prAuthenticationEncryptionSupported[4].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[5].eAuthModeSupported = AUTH_MODE_WPA; ++ prAuthenticationEncryptionSupported[5].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[6].eAuthModeSupported = AUTH_MODE_WPA_PSK; ++ prAuthenticationEncryptionSupported[6].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[7].eAuthModeSupported = AUTH_MODE_WPA_PSK; ++ prAuthenticationEncryptionSupported[7].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[8].eAuthModeSupported = AUTH_MODE_WPA_NONE; ++ prAuthenticationEncryptionSupported[8].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[9].eAuthModeSupported = AUTH_MODE_WPA_NONE; ++ prAuthenticationEncryptionSupported[9].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[10].eAuthModeSupported = AUTH_MODE_WPA2; ++ prAuthenticationEncryptionSupported[10].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[11].eAuthModeSupported = AUTH_MODE_WPA2; ++ prAuthenticationEncryptionSupported[11].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[12].eAuthModeSupported = AUTH_MODE_WPA2_PSK; ++ prAuthenticationEncryptionSupported[12].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[13].eAuthModeSupported = AUTH_MODE_WPA2_PSK; ++ prAuthenticationEncryptionSupported[13].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryCapability */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the PMKID in the PMK cache. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ UINT_32 i; ++ P_PARAM_PMKID_T prPmkid; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("wlanoidQueryPmkid"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ *pu4QueryInfoLen = OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo) + ++ prAisSpecBssInfo->u4PmkidCacheCount * sizeof(PARAM_BSSID_INFO_T); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prPmkid = (P_PARAM_PMKID_T) pvQueryBuffer; ++ ++ prPmkid->u4Length = *pu4QueryInfoLen; ++ prPmkid->u4BSSIDInfoCount = prAisSpecBssInfo->u4PmkidCacheCount; ++ ++ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { ++ kalMemCopy(prPmkid->arBSSIDInfo[i].arBSSID, ++ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, sizeof(PARAM_MAC_ADDRESS)); ++ kalMemCopy(prPmkid->arBSSIDInfo[i].arPMKID, ++ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryPmkid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the PMKID to the PMK cache in the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 i, j; ++ P_PARAM_PMKID_T prPmkid; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("wlanoidSetPmkid"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* It's possibble BSSIDInfoCount is zero, because OS wishes to clean PMKID */ ++ if (u4SetBufferLen < OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ ASSERT(pvSetBuffer); ++ prPmkid = (P_PARAM_PMKID_T) pvSetBuffer; ++ ++ if (u4SetBufferLen < ++ ((prPmkid->u4BSSIDInfoCount * sizeof(PARAM_BSSID_INFO_T)) + OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo))) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ DBGLOG(OID, TRACE, "Count %u\n", prPmkid->u4BSSIDInfoCount); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ /* This OID replace everything in the PMKID cache. */ ++ if (prPmkid->u4BSSIDInfoCount == 0) { ++ prAisSpecBssInfo->u4PmkidCacheCount = 0; ++ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); ++ } ++ if ((prAisSpecBssInfo->u4PmkidCacheCount + prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)) { ++ prAisSpecBssInfo->u4PmkidCacheCount = 0; ++ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); ++ } ++ ++ /* ++ The driver can only clear its PMKID cache whenever it make a media disconnect ++ indication. Otherwise, it must change the PMKID cache only when set through this OID. ++ */ ++#if CFG_RSN_MIGRATION ++ for (i = 0; i < prPmkid->u4BSSIDInfoCount; i++) { ++ /* Search for desired BSSID. If desired BSSID is found, ++ then set the PMKID */ ++ if (!rsnSearchPmkidEntry(prAdapter, (PUINT_8) prPmkid->arBSSIDInfo[i].arBSSID, &j)) { ++ /* No entry found for the specified BSSID, so add one entry */ ++ if (prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE - 1) { ++ j = prAisSpecBssInfo->u4PmkidCacheCount; ++ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, ++ prPmkid->arBSSIDInfo[i].arBSSID, sizeof(PARAM_MAC_ADDRESS)); ++ prAisSpecBssInfo->u4PmkidCacheCount++; ++ } else { ++ j = CFG_MAX_PMKID_CACHE; ++ } ++ } ++ ++ if (j < CFG_MAX_PMKID_CACHE) { ++ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID, ++ prPmkid->arBSSIDInfo[i].arPMKID, sizeof(PARAM_PMKID_VALUE)); ++ DBGLOG(RSN, TRACE, "Add BSSID %pM idx=%d PMKID value %pM\n", ++ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID), (UINT_32) j, ++ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID)); ++ prAisSpecBssInfo->arPmkidCache[j].fgPmkidExist = TRUE; ++ } ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetPmkid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the set of supported data rates that ++* the radio is capable of running ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query ++* \param[in] u4QueryBufferLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number ++* of bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ PARAM_RATES eRate = { ++ /* BSSBasicRateSet for 802.11n Non-HT rates */ ++ 0x8C, /* 6M */ ++ 0x92, /* 9M */ ++ 0x98, /* 12M */ ++ 0xA4, /* 18M */ ++ 0xB0, /* 24M */ ++ 0xC8, /* 36M */ ++ 0xE0, /* 48M */ ++ 0xEC /* 54M */ ++ }; ++ ++ DEBUGFUNC("wlanoidQuerySupportedRates"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ kalMemCopy(pvQueryBuffer, (PVOID) &eRate, sizeof(PARAM_RATES)); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQuerySupportedRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current desired rates. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryDesiredRates"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ kalMemCopy(pvQueryBuffer, (PVOID) &(prAdapter->rWlanInfo.eDesiredRates), sizeof(PARAM_RATES)); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wlanoidQueryDesiredRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to Set the desired rates. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 i; ++ ++ DEBUGFUNC("wlanoidSetDesiredRates"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(PARAM_RATES)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = sizeof(PARAM_RATES); ++ ++ if (u4SetBufferLen < sizeof(PARAM_RATES)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ kalMemCopy((PVOID) &(prAdapter->rWlanInfo.eDesiredRates), pvSetBuffer, sizeof(PARAM_RATES)); ++ ++ prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = PARAM_MAX_LEN_RATES; ++ for (i = 0; i < PARAM_MAX_LEN_RATES; i++) ++ prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = (UINT_16) (prAdapter->rWlanInfo.eDesiredRates[i]); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_LINK_ATTRIB, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_LINK_ATTRIB), ++ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); ++ ++} /* end of wlanoidSetDesiredRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the maximum frame size in bytes, ++* not including the header. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryMaxFrameSize"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - ETHERNET_HEADER_SZ; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryMaxFrameSize */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the maximum total packet length ++* in bytes. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryMaxTotalSize"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryMaxTotalSize */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the vendor ID of the NIC. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++#if DBG ++ PUINT_8 cp; ++#endif ++ DEBUGFUNC("wlanoidQueryVendorId"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3); ++ *((PUINT_8) pvQueryBuffer + 3) = 1; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++#if DBG ++ cp = (PUINT_8) pvQueryBuffer; ++ DBGLOG(OID, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], cp[1], cp[2], cp[3]); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryVendorId */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current RSSI value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call failed due to invalid length of ++* the query buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRssi"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (prAdapter->fgIsLinkQualityValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { ++ PARAM_RSSI rRssi; ++ ++ rRssi = (PARAM_RSSI) prAdapter->rLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ ++ ++ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ ++ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); ++ return WLAN_STATUS_SUCCESS; ++ } ++#ifdef LINUX ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, ++ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); ++#else ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++#endif ++} /* end of wlanoidQueryRssi() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current RSSI trigger value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call failed due to invalid length of ++* the query buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRssiTrigger"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_NONE) ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ *(PARAM_RSSI *) pvQueryBuffer = prAdapter->rWlanInfo.rRssiTriggerValue; ++ DBGLOG(OID, INFO, "RSSI trigger: %d dBm\n", *(PARAM_RSSI *) pvQueryBuffer); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryRssiTrigger */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a trigger value of the RSSI event. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns the ++* amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PARAM_RSSI rRssiTriggerValue; ++ ++ DEBUGFUNC("wlanoidSetRssiTrigger"); ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_RSSI); ++ rRssiTriggerValue = *(PARAM_RSSI *) pvSetBuffer; ++ ++ if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM) ++ return ++ /* Save the RSSI trigger value to the Adapter structure */ ++ prAdapter->rWlanInfo.rRssiTriggerValue = rRssiTriggerValue; ++ ++ /* If the RSSI trigger value is equal to the current RSSI value, the ++ * indication triggers immediately. We need to indicate the protocol ++ * that an RSSI status indication event triggers. */ ++ if (rRssiTriggerValue == (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) &prAdapter->rWlanInfo.rRssiTriggerValue, sizeof(PARAM_RSSI)); ++ } else if (rRssiTriggerValue < (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_GREATER; ++ else if (rRssiTriggerValue > (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_LESS; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetRssiTrigger */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a suggested value for the number of ++* bytes of received packet data that will be indicated to the protocol ++* driver. We just accept the set and ignore this value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ DEBUGFUNC("wlanoidSetCurrentLookahead"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) { ++ *pu4SetInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetCurrentLookahead */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames that the driver ++* receives but does not indicate to the protocols due to errors. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvError"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvError, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvError */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the number of frames that the NIC ++* cannot receive due to lack of NIC receive buffer space. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS If success; ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvNoBuffer"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) 0; /* @FIXME */ ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) 0; /* @FIXME */ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvNoBuffer, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvNoBuffer */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the number of frames that the NIC ++* received and it is CRC error. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS If success; ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvCrcError"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvCrcError, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvCrcError */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the current 802.11 statistics. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; ++ ++ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; ++ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; ++ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; ++ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; ++ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; ++ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; ++ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; ++ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; ++ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; ++ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; ++ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; ++ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; ++ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; ++ prStatistics->rTKIPICVErrors.QuadPart = 0; ++ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; ++ prStatistics->rTKIPReplays.QuadPart = 0; ++ prStatistics->rCCMPFormatErrors.QuadPart = 0; ++ prStatistics->rCCMPReplays.QuadPart = 0; ++ prStatistics->rCCMPDecryptErrors.QuadPart = 0; ++ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; ++ prStatistics->rWEPUndecryptableCount.QuadPart = 0; ++ prStatistics->rWEPICVErrorCount.QuadPart = 0; ++ prStatistics->rDecryptSuccessCount.QuadPart = 0; ++ prStatistics->rDecryptFailureCount.QuadPart = 0; ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS_PL, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryStatistics, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryStatistics */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the current 802.11 statistics. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryStatistics"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; ++ ++ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; ++ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; ++ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; ++ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; ++ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; ++ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; ++ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; ++ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; ++ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; ++ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; ++ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; ++ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; ++ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; ++ prStatistics->rTKIPICVErrors.QuadPart = 0; ++ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; ++ prStatistics->rTKIPReplays.QuadPart = 0; ++ prStatistics->rCCMPFormatErrors.QuadPart = 0; ++ prStatistics->rCCMPReplays.QuadPart = 0; ++ prStatistics->rCCMPDecryptErrors.QuadPart = 0; ++ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; ++ prStatistics->rWEPUndecryptableCount.QuadPart = 0; ++ prStatistics->rWEPICVErrorCount.QuadPart = 0; ++ prStatistics->rDecryptSuccessCount.QuadPart = 0; ++ prStatistics->rDecryptFailureCount.QuadPart = 0; ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryStatistics, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryStatistics */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query current media streaming status. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryMediaStreamMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *(P_ENUM_MEDIA_STREAM_MODE) pvQueryBuffer = ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryMediaStreamMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to enter media streaming mode or exit media streaming mode ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ENUM_MEDIA_STREAM_MODE eStreamMode; ++ ++ DEBUGFUNC("wlanoidSetMediaStreamMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(ENUM_MEDIA_STREAM_MODE)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); ++ ++ eStreamMode = *(P_ENUM_MEDIA_STREAM_MODE) pvSetBuffer; ++ ++ if (eStreamMode == ENUM_MEDIA_STREAM_OFF) ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; ++ else ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_LINK_ATTRIB, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetMediaStreamMode, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_LINK_ATTRIB), ++ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); ++} /* wlanoidSetMediaStreamMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the permanent MAC address of the NIC. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryPermanentAddr"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < MAC_ADDR_LEN) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ COPY_MAC_ADDR(pvQueryBuffer, prAdapter->rWifiVar.aucPermanentAddress); ++ *pu4QueryInfoLen = MAC_ADDR_LEN; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryPermanentAddr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the MAC address the NIC is currently using. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ CMD_BASIC_CONFIG rCmdBasicConfig; ++ ++ DEBUGFUNC("wlanoidQueryCurrentAddr"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < MAC_ADDR_LEN) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BASIC_CONFIG, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryAddress, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_BASIC_CONFIG), ++ (PUINT_8) &rCmdBasicConfig, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryCurrentAddr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query NIC link speed. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryLinkSpeed"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (prAdapter->fgIsLinkRateValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { ++ *(PUINT_32) pvQueryBuffer = prAdapter->rLinkQuality.u2LinkSpeed * 5000; /* change to unit of 100bps */ ++ return WLAN_STATUS_SUCCESS; ++ } else { ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkSpeed, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ } ++} /* end of wlanoidQueryLinkSpeed() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query MCR value. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++ DEBUGFUNC("wlanoidQueryMcrRead"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvQueryBuffer; ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++#if CFG_SUPPORT_SWCR ++ if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) { ++ swCrReadWriteCmd(prAdapter, ++ SWCR_READ, ++ (UINT_16) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), &prMcrRdInfo->u4McrData); ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif /* CFG_SUPPORT_SWCR */ ++ ++ /* Check if access F/W Domain MCR (due to WiFiSYS is placed from 0x6000-0000 */ ++ if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) { ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = 0; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryMcrRead, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); ++ } else { ++ HAL_MCR_RD(prAdapter, prMcrRdInfo->u4McrOffset & BITS(2, 31), /* address is in DWORD unit */ ++ &prMcrRdInfo->u4McrData); ++ ++ DBGLOG(OID, TRACE, "MCR Read: Offset = %#08x, Data = %#08x\n", ++ prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); ++ return WLAN_STATUS_SUCCESS; ++ } ++} /* end of wlanoidQueryMcrRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write MCR and enable specific function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrWrInfo; ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++#if CFG_STRESS_TEST_SUPPORT ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); ++ P_STA_RECORD_T prStaRec = prBssInfo->prStaRecOfAP; ++ UINT_32 u4McrOffset, u4McrData; ++#endif ++ ++ DEBUGFUNC("wlanoidSetMcrWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prMcrWrInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvSetBuffer; ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++ /* 0xFFFE reserved for FW */ ++ ++ /* -- Puff Stress Test Begin */ ++#if CFG_STRESS_TEST_SUPPORT ++ ++ /* 0xFFFFFFFE for Control Rate */ ++ if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) { ++ if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM && prMcrWrInfo->u4McrData > 0) ++ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prMcrWrInfo->u4McrData); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n"); ++ DBGLOG(OID, TRACE, ++ "[Stress Test] Rate is Changed to index %d...\n", prAdapter->rWifiVar.eRateSetting); ++ } ++ /* 0xFFFFFFFD for Switch Channel */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) { ++ if (prMcrWrInfo->u4McrData <= 11 && prMcrWrInfo->u4McrData >= 1) ++ prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData; ++ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); ++ DBGLOG(OID, TRACE, "[Stress Test] Channel is switched to %d ...\n", prBssInfo->ucPrimaryChannel); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* 0xFFFFFFFFC for Control RF Band and SCO */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) { ++ /* Band */ ++ if (prMcrWrInfo->u4McrData & 0x80000000) { ++ /* prBssInfo->eBand = BAND_5G; */ ++ /* prBssInfo->ucPrimaryChannel = 52; // Bond to Channel 52 */ ++ } else { ++ prBssInfo->eBand = BAND_2G4; ++ prBssInfo->ucPrimaryChannel = 8; /* Bond to Channel 6 */ ++ } ++ ++ /* Bandwidth */ ++ if (prMcrWrInfo->u4McrData & 0x00010000) { ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ ++ if (prMcrWrInfo->u4McrData == 0x00010002) { ++ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* U20 */ ++ prBssInfo->ucPrimaryChannel += 2; ++ } else if (prMcrWrInfo->u4McrData == 0x00010001) { ++ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* L20 */ ++ prBssInfo->ucPrimaryChannel -= 2; ++ } else { ++ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* 40 */ ++ } ++ } ++ ++ if (prMcrWrInfo->u4McrData & 0x00000000) { ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; ++ prBssInfo->eBssSCO = CHNL_EXT_SCN; ++ } ++ rlmBssInitForAPandIbss(prAdapter, prBssInfo); ++ } ++ /* 0xFFFFFFFB for HT Capability */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) { ++ /* Enable HT Capability */ ++ if (prMcrWrInfo->u4McrData & 0x00000001) { ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; ++ DEBUGFUNC("[Stress Test]Enable HT capability...\n"); ++ } else { ++ prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF); ++ DEBUGFUNC("[Stress Test]Disable HT capability...\n"); ++ } ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ } ++ /* 0xFFFFFFFA for Enable Random Rx Reset */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_RANDOM_RX_RESET_EN, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ /* 0xFFFFFFF9 for Disable Random Rx Reset */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_RANDOM_RX_RESET_DE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ /* 0xFFFFFFF8 for Enable SAPP */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SAPP_EN, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ /* 0xFFFFFFF7 for Disable SAPP */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SAPP_DE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ ++ else ++#endif ++ /* -- Puff Stress Test End */ ++ ++ /* Check if access F/W Domain MCR */ ++ if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) { ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++#if CFG_SUPPORT_SWCR ++ if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) { ++ swCrReadWriteCmd(prAdapter, ++ SWCR_WRITE, ++ (UINT_16) (prMcrWrInfo->u4McrOffset & BITS(0, 15)), &prMcrWrInfo->u4McrData); ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif /* CFG_SUPPORT_SWCR */ ++ ++#if 1 ++ /* low power test special command */ ++ if (prMcrWrInfo->u4McrOffset == 0x11111110) { ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ /* DbgPrint("Enter test mode\n"); */ ++ prAdapter->fgTestMode = TRUE; ++ return rStatus; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111111) { ++ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ ++ ++ nicpmSetAcpiPowerD3(prAdapter); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111112) { ++ ++ /* DbgPrint("LP enter sleep\n"); */ ++ ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++#endif ++ ++#if 1 ++ /* low power test special command */ ++ if (prMcrWrInfo->u4McrOffset == 0x11111110) { ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ /* DbgPrint("Enter test mode\n"); */ ++ prAdapter->fgTestMode = TRUE; ++ return rStatus; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111111) { ++ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ ++ ++ nicpmSetAcpiPowerD3(prAdapter); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111112) { ++ ++ /* DbgPrint("LP enter sleep\n"); */ ++ ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++#endif ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } else { ++ HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, 31)), /* address is in DWORD unit */ ++ prMcrWrInfo->u4McrData); ++ ++ DBGLOG(OID, TRACE, "MCR Write: Offset = %#08x, Data = %#08x\n", ++ prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++} /* wlanoidSetMcrWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query SW CTRL ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; ++ WLAN_STATUS rWlanStatus; ++ UINT_16 u2Id, u2SubId; ++ UINT_32 u4Data; ++ ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ ++ DEBUGFUNC("wlanoidQuerySwCtrlRead"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvQueryBuffer; ++ ++ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); ++ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); ++ u4Data = 0; ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ switch (u2Id) { ++ /* 0x9000 - 0x9EFF reserved for FW */ ++ /* 0xFFFE reserved for FW */ ++ ++#if CFG_SUPPORT_SWCR ++ case 0x9F00: ++ swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */ , ++ (UINT_16) u2SubId, &u4Data); ++ break; ++#endif /* CFG_SUPPORT_SWCR */ ++ ++ case 0xFFFF: ++ { ++ u4Data = 0x5AA56620; ++ } ++ break; ++ ++ case 0x9000: ++ default: ++ { ++ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; ++ rCmdSwCtrl.u4Data = 0; ++ rWlanStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQuerySwCtrlRead, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_SW_DBG_CTRL_T), ++ (PUINT_8) &rCmdSwCtrl, pvQueryBuffer, u4QueryBufferLen); ++ } ++ } /* switch(u2Id) */ ++ ++ prSwCtrlInfo->u4Data = u4Data; ++ ++ return rWlanStatus; ++ ++} ++ ++ /* end of wlanoidQuerySwCtrlRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write SW CTRL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ WLAN_STATUS rWlanStatus; ++ UINT_16 u2Id, u2SubId; ++ UINT_32 u4Data; ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ P_GLUE_INFO_T prGlueInfo; ++ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; ++#endif ++ ++ DEBUGFUNC("wlanoidSetSwCtrlWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ prGlueInfo = prAdapter->prGlueInfo; ++#endif ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvSetBuffer; ++ ++ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); ++ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); ++ u4Data = prSwCtrlInfo->u4Data; ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ switch (u2Id) { ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++ /* 0xFFFE reserved for FW */ ++ ++#if CFG_SUPPORT_SWCR ++ case 0x9F00: ++ swCrReadWriteCmd(prAdapter, SWCR_WRITE, (UINT_16) u2SubId, &u4Data); ++ break; ++#endif /* CFG_SUPPORT_SWCR */ ++ ++ case 0x1000: ++ if (u2SubId == 0x8000) { ++ /* CTIA power save mode setting (code: 0x10008000) */ ++ prAdapter->u4CtiaPowerMode = u4Data; ++ prAdapter->fgEnCtiaPowerMode = TRUE; ++ ++ /* */ ++ { ++ PARAM_POWER_MODE ePowerMode; ++ ++ if (prAdapter->u4CtiaPowerMode == 0) ++ /* force to keep in CAM mode */ ++ ePowerMode = Param_PowerModeCAM; ++ else if (prAdapter->u4CtiaPowerMode == 1) ++ ePowerMode = Param_PowerModeMAX_PSP; ++ else ++ ePowerMode = Param_PowerModeFast_PSP; ++ ++ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); ++ } ++ } ++ break; ++ case 0x1001: ++ if (u2SubId == 0x0) ++ prAdapter->fgEnOnlineScan = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x1) ++ prAdapter->fgDisBcnLostDetection = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x2) ++ prAdapter->rWifiVar.fgSupportUAPSD = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x3) { ++ prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15); ++ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpDeliveryAC = ++ (UINT_8) prAdapter->u4UapsdAcBmp; ++ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpTriggerAC = ++ (UINT_8) prAdapter->u4UapsdAcBmp; ++ } else if (u2SubId == 0x4) ++ prAdapter->fgDisStaAgingTimeoutDetection = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x5) ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = (UINT_8) u4Data; ++ else if (u2SubId == 0x0100) ++ prAdapter->rWifiVar.u8SupportRxGf = (UINT_8) u4Data; ++ else if (u2SubId == 0x0101) { ++ prAdapter->rWifiVar.u8SupportRxSgi20 = (UINT_8) u4Data; ++ prAdapter->rWifiVar.u8SupportRxSgi40 = (UINT_8) u4Data; ++ } else if (u2SubId == 0x0102) ++ prAdapter->rWifiVar.u8SupportRxSTBC = (UINT_8) u4Data; ++ break; ++ ++#if CFG_SUPPORT_SWCR ++ case 0x1002: ++ if (u2SubId == 0x0) { ++ if (u4Data) ++ u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT); ++ swCrFrameCheckEnable(prAdapter, u4Data); ++ } else if (u2SubId == 0x1) { ++ BOOLEAN fgIsEnable; ++ UINT_8 ucType; ++ UINT_32 u4Timeout; ++ ++ fgIsEnable = (BOOLEAN) (u4Data & 0xff); ++ ucType = 0; /* ((u4Data>>4) & 0xf); */ ++ u4Timeout = ((u4Data >> 8) & 0xff); ++ swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, u4Timeout); ++ } ++ break; ++#endif ++ ++#if CFG_SUPPORT_802_11W ++ case 0x2000: ++ DBGLOG(RSN, TRACE, "802.11w test 0x%x\n", u2SubId); ++ if (u2SubId == 0x0) ++ rsnStartSaQuery(prAdapter); ++ if (u2SubId == 0x1) ++ rsnStopSaQuery(prAdapter); ++ if (u2SubId == 0x2) ++ rsnSaQueryRequest(prAdapter, NULL); ++ if (u2SubId == 0x3) { ++ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); ++ ++ authSendDeauthFrame(prAdapter, prBssInfo->prStaRecOfAP, NULL, 7, NULL); ++ } ++ /* wext_set_mode */ ++ /* ++ if (u2SubId == 0x3) { ++ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_DISABLED; ++ } ++ if (u2SubId == 0x4) { ++ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL; ++ } ++ if (u2SubId == 0x5) { ++ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_REQUIRED; ++ } ++ */ ++ break; ++#endif ++ case 0xFFFF: ++ { ++/* CMD_ACCESS_REG rCmdAccessReg; */ ++#if 1 /* CFG_MT6573_SMT_TEST */ ++ if (u2SubId == 0x0123) { ++ ++ DBGLOG(HAL, TRACE, "set smt fixed rate: %u\n", u4Data); ++ ++ if ((ENUM_REGISTRY_FIXED_RATE_T) (u4Data) < FIXED_RATE_NUM) ++ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (u4Data); ++ else ++ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; ++ ++ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) ++ /* Enable Auto (Long/Short) Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; ++ else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) ++ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) ++ /* Force Short Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; ++ else ++ /* Force Long Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; ++ ++ /* abort to re-connect */ ++#if 1 ++ DBGLOG(OID, TRACE, "DisBySwC\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++#else ++ aisBssBeaconTimeout(prAdapter); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++ ++ } else if (u2SubId == 0x1234) { ++ /* 1. Disable On-Lin Scan */ ++ /* 3. Disable FIFO FULL no ack */ ++ /* 4. Disable Roaming */ ++ /* Disalbe auto tx power */ ++ /* 2. Keep at CAM mode */ ++ /* 5. Disable Beacon Timeout Detection */ ++ rWlanStatus = nicEnterCtiaMode(prAdapter, TRUE, TRUE); ++ } else if (u2SubId == 0x1235) { ++ /* 1. Enaable On-Lin Scan */ ++ /* 3. Enable FIFO FULL no ack */ ++ /* 4. Enable Roaming */ ++ /* Enable auto tx power */ ++ /* 2. Keep at Fast PS */ ++ /* 5. Enable Beacon Timeout Detection */ ++ rWlanStatus = nicEnterCtiaMode(prAdapter, FALSE, TRUE); ++ } ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ else if (u2SubId == 0x1240) { ++ DBGLOG(P2P, TRACE, "Disable Hotspot Optimization!\n"); ++ ++ arHotspotOptimizationCfg.fgHotspotOptimizationEn = FALSE; ++ arHotspotOptimizationCfg.u4Level = 0; ++ wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ NULL, ++ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), ++ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); ++ } else if (u2SubId == 0x1241) { ++ DBGLOG(P2P, TRACE, "Enable Hotspot Optimization!\n"); ++ ++ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; ++ arHotspotOptimizationCfg.u4Level = 5; ++ wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ NULL, ++ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), ++ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); ++ } ++#endif /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ ++ else if (u2SubId == 0x1250) { ++ DBGLOG(OID, TRACE, "LTE_COEX: SW SET DUAL BAND\n"); ++ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_NULL; ++ } else if (u2SubId == 0x1251) { ++ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 2.4G BAND\n"); ++ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_2G4; ++ } else if (u2SubId == 0x1252) { ++ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 5G BAND\n"); ++ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_5G; ++ } ++#endif ++ } ++ break; ++ ++ case 0x9000: ++ default: ++ { ++ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; ++ rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data; ++ rWlanStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_SW_DBG_CTRL_T), ++ (PUINT_8) &rCmdSwCtrl, pvSetBuffer, u4SetBufferLen); ++ } ++ } /* switch(u2Id) */ ++ ++ return rWlanStatus; ++} ++ ++ /* wlanoidSetSwCtrlWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query EEPROM value. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; ++ CMD_ACCESS_EEPROM rCmdAccessEeprom; ++ ++ DEBUGFUNC("wlanoidQueryEepromRead"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvQueryBuffer; ++ ++ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); ++ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_EEPROM, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryEepromRead, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_EEPROM), ++ (PUINT_8) &rCmdAccessEeprom, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryEepromRead */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write EEPROM value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; ++ CMD_ACCESS_EEPROM rCmdAccessEeprom; ++ ++ DEBUGFUNC("wlanoidSetEepromWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); ++ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; ++ rCmdAccessEeprom.u2Data = prEepromRwInfo->u2EepromData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_EEPROM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_EEPROM), ++ (PUINT_8) &rCmdAccessEeprom, pvSetBuffer, u4SetBufferLen); ++ ++} /* wlanoidSetEepromWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of the successfully transmitted ++* packets. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitOk"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitOk, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryXmitOk */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of the successfully received ++* packets. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvOk"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvOk, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvOk */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames that the driver ++* fails to transmit. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitError"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitError, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryXmitError */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames successfully ++* transmitted after exactly one collision. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitOneCollision"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) ++ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - ++ prAdapter->rStatStruct.rRetryCount.QuadPart); ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) ++ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - ++ prAdapter->rStatStruct.rRetryCount.QuadPart); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitOneCollision, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryXmitOneCollision */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames successfully ++* transmitted after more than one collision. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitMoreCollisions"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitMoreCollisions, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++} /* wlanoidQueryXmitMoreCollisions */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames ++* not transmitted due to excessive collisions. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitMaxCollisions"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitMaxCollisions, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++} /* wlanoidQueryXmitMaxCollisions */ ++ ++#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00006620 /* for WPDWifi DLL */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current the OID interface version, ++* which is the interface between the application and driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryOidInterfaceVersion"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *(PUINT_32) pvQueryBuffer = MTK_CUSTOM_OID_INTERFACE_VERSION; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ DBGLOG(OID, WARN, "Custom OID interface version: %#08X\n", *(PUINT_32) pvQueryBuffer); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryOidInterfaceVersion */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current Multicast Address List. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++#ifndef LINUX ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_MAC_MCAST_ADDR, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryMcastAddr, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++#else ++ return WLAN_STATUS_SUCCESS; ++#endif ++} /* end of wlanoidQueryMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Multicast Address List. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_8 ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Caller should provide this information */ ++ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* The data must be a multiple of the Ethernet address size. */ ++ if ((u4SetBufferLen % MAC_ADDR_LEN)) { ++ DBGLOG(OID, WARN, "Invalid MC list length %u\n", u4SetBufferLen); ++ ++ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; ++ ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* Verify if we can support so many multicast addresses. */ ++ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { ++ DBGLOG(OID, WARN, "Too many MC addresses\n"); ++ ++ return WLAN_STATUS_MULTICAST_FULL; ++ } ++ ++ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && ++ * pvSetBuffer == NULL to clear exist Multicast List. ++ */ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; ++ rCmdMacMcastAddr.ucNetTypeIndex = ucNetTypeIndex; ++ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_MAC_MCAST_ADDR, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_MAC_MCAST_ADDR), ++ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); ++} /* end of wlanoidSetMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Packet Filter. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_NOT_SUPPORTED ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 u4NewPacketFilter; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) { ++ *pu4SetInfoLen = sizeof(UINT_32); ++ DBGLOG(OID, INFO, "iput buffer is too small"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ASSERT(pvSetBuffer); ++ ++ /* Set the new packet filter. */ ++ u4NewPacketFilter = *(PUINT_32) pvSetBuffer; ++ ++ DBGLOG(OID, TRACE, "New packet filter: %#08x\n", u4NewPacketFilter); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ do { ++ /* Verify the bits of the new packet filter. If any bits are set that ++ we don't support, leave. */ ++ if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) { ++ rStatus = WLAN_STATUS_NOT_SUPPORTED; ++ break; ++ } ++#if DBG ++ /* Need to enable or disable promiscuous support depending on the new ++ filter. */ ++ if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS) ++ DBGLOG(OID, TRACE, "Enable promiscuous mode\n"); ++ else ++ DBGLOG(OID, TRACE, "Disable promiscuous mode\n"); ++ ++ if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) ++ DBGLOG(OID, TRACE, "Enable all-multicast mode\n"); ++ else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) ++ DBGLOG(OID, TRACE, "Enable multicast\n"); ++ else ++ DBGLOG(OID, TRACE, "Disable multicast\n"); ++ ++ if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) ++ DBGLOG(OID, TRACE, "Enable Broadcast\n"); ++ else ++ DBGLOG(OID, TRACE, "Disable Broadcast\n"); ++#endif ++ } while (FALSE); ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ /* Store the packet filter */ ++ ++ prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK; ++ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RX_FILTER, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(UINT_32), ++ (PUINT_8) &prAdapter->u4OsPacketFilter, pvSetBuffer, u4SetBufferLen); ++ } else { ++ return rStatus; ++ } ++} /* wlanoidSetCurrentPacketFilter */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current packet filter. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryCurrentPacketFilter"); ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen >= sizeof(UINT_32)) { ++ ASSERT(pvQueryBuffer); ++ *(PUINT_32) pvQueryBuffer = prAdapter->u4OsPacketFilter; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryCurrentPacketFilter */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query ACPI device power state. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++#if DBG ++ PPARAM_DEVICE_POWER_STATE prPowerState; ++#endif ++ ++ DEBUGFUNC("wlanoidQueryAcpiDevicePowerState"); ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); ++ ++#if DBG ++ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvQueryBuffer; ++ switch (*prPowerState) { ++ case ParamDeviceStateD0: ++ DBGLOG(OID, INFO, "Query Power State: D0\n"); ++ break; ++ case ParamDeviceStateD1: ++ DBGLOG(OID, INFO, "Query Power State: D1\n"); ++ break; ++ case ParamDeviceStateD2: ++ DBGLOG(OID, INFO, "Query Power State: D2\n"); ++ break; ++ case ParamDeviceStateD3: ++ DBGLOG(OID, INFO, "Query Power State: D3\n"); ++ break; ++ default: ++ break; ++ } ++#endif ++ ++ /* Since we will disconnect the newwork, therefore we do not ++ need to check queue empty */ ++ *(PPARAM_DEVICE_POWER_STATE) pvQueryBuffer = ParamDeviceStateD3; ++ /* WARNLOG(("Ready to transition to D3\n")); */ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* pwrmgtQueryPower */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set ACPI device power state. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PPARAM_DEVICE_POWER_STATE prPowerState; ++ BOOLEAN fgRetValue = TRUE; ++ ++ DEBUGFUNC("wlanoidSetAcpiDevicePowerState"); ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); ++ ++ ASSERT(pvSetBuffer); ++ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvSetBuffer; ++ switch (*prPowerState) { ++ case ParamDeviceStateD0: ++ DBGLOG(OID, INFO, "Set Power State: D0\n"); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD0); ++ fgRetValue = nicpmSetAcpiPowerD0(prAdapter); ++ break; ++ case ParamDeviceStateD1: ++ DBGLOG(OID, INFO, "Set Power State: D1\n"); ++ /* no break here */ ++ case ParamDeviceStateD2: ++ DBGLOG(OID, INFO, "Set Power State: D2\n"); ++ /* no break here */ ++ case ParamDeviceStateD3: ++ DBGLOG(OID, INFO, "Set Power State: D3\n"); ++ fgRetValue = nicpmSetAcpiPowerD3(prAdapter); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); ++ break; ++ default: ++ break; ++ } ++ ++ if (fgRetValue == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ else ++ return WLAN_STATUS_FAILURE; ++} /* end of wlanoidSetAcpiDevicePowerState() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current fragmentation threshold. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryFragThreshold"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ DBGLOG(OID, LOUD, "\n"); ++ ++#if CFG_TX_FRAGMENT ++ ++ return WLAN_STATUS_SUCCESS; ++ ++#else ++ ++ return WLAN_STATUS_NOT_SUPPORTED; ++#endif /* CFG_TX_FRAGMENT */ ++ ++} /* end of wlanoidQueryFragThreshold() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a new fragmentation threshold to the ++* driver. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#if CFG_TX_FRAGMENT ++ ++ return WLAN_STATUS_SUCCESS; ++ ++#else ++ ++ return WLAN_STATUS_NOT_SUPPORTED; ++#endif /* CFG_TX_FRAGMENT */ ++ ++} /* end of wlanoidSetFragThreshold() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current RTS threshold. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRtsThreshold"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ DBGLOG(OID, LOUD, "\n"); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { ++ *pu4QueryInfoLen = sizeof(PARAM_RTS_THRESHOLD); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ *((PARAM_RTS_THRESHOLD *) pvQueryBuffer) = prAdapter->rWlanInfo.eRtsThreshold; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryRtsThreshold */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a new RTS threshold to the driver. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PARAM_RTS_THRESHOLD *prRtsThreshold; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_RTS_THRESHOLD); ++ if (u4SetBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prRtsThreshold = (PARAM_RTS_THRESHOLD *) pvSetBuffer; ++ *prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetRtsThreshold */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to turn radio off. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ ++ DEBUGFUNC("wlanoidSetDisassociate"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 0; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ /* prepare message to AIS */ ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ ++ /* Send AIS Abort Message */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ /* indicate for disconnection */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ DBGLOG(OID, INFO, "DisconnectByOid\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, 0); ++ } ++#if !defined(LINUX) ++ prAdapter->fgIsRadioOff = TRUE; ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetDisassociate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query the power save profile. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen != 0) { ++ ASSERT(pvQueryBuffer); ++ ++/* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE)(prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); */ ++ *(PPARAM_POWER_MODE) pvQueryBuffer = ++ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_AIS_INDEX].ucPsProfile); ++ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); ++ ++ /* hack for CTIA power mode setting function */ ++ if (prAdapter->fgEnCtiaPowerMode) { ++ /* set to non-zero value (to prevent MMI query 0, before it intends to set 0, */ ++ /* which will skip its following state machine) */ ++ *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) 2; ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the power save profile. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status; ++ PARAM_POWER_MODE ePowerMode; ++ ++ DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); ++ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { ++ /* WARNLOG(("Invalid power mode %d\n", */ ++ /* *(PPARAM_POWER_MODE) pvSetBuffer)); */ ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; ++ ++ if (prAdapter->fgEnCtiaPowerMode) { ++ if (ePowerMode == Param_PowerModeCAM) ++ ; ++ else { ++ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ ++ ++ if (prAdapter->u4CtiaPowerMode == 0) ++ /* force to keep in CAM mode */ ++ ePowerMode = Param_PowerModeCAM; ++ else if (prAdapter->u4CtiaPowerMode == 1) ++ ePowerMode = Param_PowerModeMAX_PSP; ++ else if (prAdapter->u4CtiaPowerMode == 2) ++ ePowerMode = Param_PowerModeFast_PSP; ++ } ++ } ++ ++ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); ++ ++ switch (ePowerMode) { ++ case Param_PowerModeCAM: ++ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to CAM (%d)\n", ePowerMode); ++ break; ++ case Param_PowerModeMAX_PSP: ++ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to MAX PS (%d)\n", ePowerMode); ++ break; ++ case Param_PowerModeFast_PSP: ++ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to FAST PS (%d)\n", ePowerMode); ++ break; ++ default: ++ DBGLOG(OID, INFO, "invalid Wi-Fi PS mode setting (%d)\n", ePowerMode); ++ break; ++ } ++ ++ return status; ++ ++} /* end of wlanoidSetAcpiDevicePowerStateMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current status of AdHoc Mode. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQueryAdHocMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set AdHoc Mode. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetAdHocMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query RF frequency. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryFrequency"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) { ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ *(PUINT_32) pvQueryBuffer = ++ nicChannelNum2Freq(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].ucPrimaryChannel); ++ } else { ++ *(PUINT_32) pvQueryBuffer = 0; ++ } ++ } else { ++ *(PUINT_32) pvQueryBuffer = nicChannelNum2Freq(prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQueryFrequency() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set RF frequency by User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4FreqInKHz; ++ ++ DEBUGFUNC("wlanoidSetFrequency"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ pu4FreqInKHz = (PUINT_32) pvSetBuffer; ++ ++ prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(*pu4FreqInKHz); ++ prAdapter->rWifiVar.rConnSettings.eAdHocBand = *pu4FreqInKHz < 5000000 ? BAND_2G4 : BAND_5G; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetFrequency() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set 802.11 channel of the radio frequency. ++* This is a proprietary function call to Lunux currently. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetChannel(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(0); /* // */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the Beacon Interval from User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryBeaconInterval"); ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) ++ *(PUINT_32) pvQueryBuffer = prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod; ++ else ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; ++ } else { ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) ++ *(PUINT_32) pvQueryBuffer = 0; ++ else ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQueryBeaconInterval() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the Beacon Interval to User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4BeaconInterval; ++ ++ DEBUGFUNC("wlanoidSetBeaconInterval"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ pu4BeaconInterval = (PUINT_32) pvSetBuffer; ++ ++ if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) { ++ DBGLOG(OID, TRACE, "Invalid Beacon Interval = %u\n", *pu4BeaconInterval); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ prAdapter->rWlanInfo.u2BeaconPeriod = (UINT_16) *pu4BeaconInterval; ++ ++ DBGLOG(OID, INFO, "Set beacon interval: %d\n", prAdapter->rWlanInfo.u2BeaconPeriod); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetBeaconInterval() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the ATIM window from User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryAtimWindow"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) ++ *(PUINT_32) pvQueryBuffer = 0; ++ else ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2AtimWindow; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wlanoidQueryAtimWindow() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the ATIM window to User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4AtimWindow; ++ ++ DEBUGFUNC("wlanoidSetAtimWindow"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ pu4AtimWindow = (PUINT_32) pvSetBuffer; ++ ++ prAdapter->rWlanInfo.u2AtimWindow = (UINT_16) *pu4AtimWindow; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetAtimWindow() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to Set the MAC address which is currently used by the NIC. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(0); /* // */ ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetCurrentAddr() */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setting the checksum offload function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 i, u4CSUMFlags; ++ CMD_BASIC_CONFIG rCmdBasicConfig; ++ ++ DEBUGFUNC("wlanoidSetCSUMOffload"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ u4CSUMFlags = *(PUINT_32) pvSetBuffer; ++ ++ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); ++ ++ for (i = 0; i < 6; i++) { /* set to broadcast address for not-specified */ ++ rCmdBasicConfig.rMyMacAddr[i] = 0xff; ++ } ++ ++ rCmdBasicConfig.ucNative80211 = 0; /* @FIXME: for Vista */ ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) ++ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) ++ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) ++ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) ++ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) ++ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1); ++ ++ if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) ++ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0); ++ ++ prAdapter->u4CSUMFlags = u4CSUMFlags; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BASIC_CONFIG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_BASIC_CONFIG), (PUINT_8) &rCmdBasicConfig, pvSetBuffer, u4SetBufferLen); ++} ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setting the IP address for pattern search function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 i, j; ++ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; ++ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; ++ P_PARAM_NETWORK_ADDRESS prNetworkAddress; ++ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; ++ UINT_32 u4IpAddressCount, u4CmdSize; ++ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ UINT_32 u4IpV4AddrListSize; ++ P_BSS_INFO_T prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++#endif ++ ++ DEBUGFUNC("wlanoidSetNetworkAddress"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 4; ++ ++ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ *pu4SetInfoLen = 0; ++ u4IpAddressCount = 0; ++ ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ u4IpAddressCount++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ /* construct payload of command packet */ ++ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + ++ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; ++ if (u4IpAddressCount == 0) ++ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); ++ ++ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); ++ ++ if (prCmdNetworkAddressList == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ u4IpV4AddrListSize = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + ++ (u4IpAddressCount * sizeof(IPV4_NETWORK_ADDRESS)); ++ if (prBssInfo->prIpV4NetAddrList) ++ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); ++ prBssInfo->prIpV4NetAddrList = (P_IPV4_NETWORK_ADDRESS_LIST) kalMemAlloc(u4IpV4AddrListSize, VIR_MEM_TYPE); ++ if (prBssInfo->prIpV4NetAddrList == NULL) { ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return WLAN_STATUS_FAILURE; ++ } ++ prBssInfo->prIpV4NetAddrList->ucAddrCount = (UINT_8) u4IpAddressCount; ++#endif ++ ++ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ ++ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ ++ /* only to set IP address to FW once ARP filter is enabled */ ++ if (prAdapter->fgEnArpFilter) { ++ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ ++ DBGLOG(OID, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); ++ ++ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; ++ ++ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ kalMemCopy(prBssInfo->prIpV4NetAddrList->arNetAddr[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++#endif ++ ++ j++; ++ ++ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; ++ DBGLOG(OID, INFO, ++ "prNetAddrIp->in_addr:%d:%d:%d:%d\n", pucBuf[0], pucBuf[1], pucBuf[2], ++ pucBuf[3]); ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ } ++ ++ } else { ++ prCmdNetworkAddressList->ucAddressCount = 0; ++ } ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_IP_ADDRESS, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetIpAddress, ++ nicOidCmdTimeoutCommon, ++ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); ++ ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set driver to switch into RF test mode ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, ++* should be NULL ++* \param[in] u4SetBufferLen The length of the set buffer, should be 0 ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_DATA ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus; ++ CMD_TEST_CTRL_T rCmdTestCtrl; ++ ++ DEBUGFUNC("wlanoidRftestSetTestMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen == 0) { ++ if (prAdapter->fgTestMode == FALSE) { ++ /* switch to RF Test mode */ ++ rCmdTestCtrl.ucAction = 0; /* Switch mode */ ++ rCmdTestCtrl.u.u4OpMode = 1; /* RF test mode */ ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TEST_MODE, ++ TRUE, ++ TRUE, ++ TRUE, ++ nicCmdEventEnterRfTest, ++ nicOidCmdEnterRFTestTimeout, ++ sizeof(CMD_TEST_CTRL_T), ++ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); ++ } else { ++ /* already in test mode .. */ ++ rStatus = WLAN_STATUS_SUCCESS; ++ } ++ } else { ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ } ++ DBGLOG(OID, INFO, "Enter TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", ++ u4SetBufferLen, prAdapter->fgTestMode, rStatus); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set driver to switch into normal operation mode from RF test mode ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* should be NULL ++* \param[in] u4SetBufferLen The length of the set buffer, should be 0 ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_DATA ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus; ++ CMD_TEST_CTRL_T rCmdTestCtrl; ++ ++ DEBUGFUNC("wlanoidRftestSetTestMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen == 0) { ++ if (prAdapter->fgTestMode == TRUE) { ++ /* switch to normal mode */ ++ rCmdTestCtrl.ucAction = 0; /* Switch mode */ ++ rCmdTestCtrl.u.u4OpMode = 0; /* normal mode */ ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TEST_MODE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventLeaveRfTest, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_TEST_CTRL_T), ++ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); ++ } else { ++ /* already in normal mode .. */ ++ rStatus = WLAN_STATUS_SUCCESS; ++ } ++ } else { ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ } ++ DBGLOG(OID, INFO, "Abort TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", ++ u4SetBufferLen, prAdapter->fgTestMode, rStatus); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief query for RF test parameter ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* \retval WLAN_STATUS_NOT_SUPPORTED ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidRftestQueryAutoTest"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); ++ ++ if (u4QueryBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { ++ DBGLOG(OID, ERROR, "Invalid data. QueryBufferLen: %u.\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvQueryBuffer; ++ rStatus = rftestQueryATInfo(prAdapter, ++ prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData, pvQueryBuffer, u4QueryBufferLen); ++ ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set RF test parameter ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidRftestSetAutoTest"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); ++ ++ if (u4SetBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { ++ DBGLOG(OID, ERROR, "Invalid data. SetBufferLen: %u.\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvSetBuffer; ++ rStatus = rftestSetATInfo(prAdapter, prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData); ++ ++ return rStatus; ++} ++ ++/* RF test OID set handler */ ++WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_TEST_CTRL_T pCmdTestCtrl; ++ UINT_8 ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_TEST_MODE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pvInformationBuffer = NULL; ++ prCmdInfo->u4InformationBufferLength = 0; ++ ++ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); ++ pCmdTestCtrl->ucAction = 1; /* Set ATInfo */ ++ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; ++ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prAdapter->prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} ++ ++WLAN_STATUS ++rftestQueryATInfo(IN P_ADAPTER_T prAdapter, ++ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_TEST_CTRL_T pCmdTestCtrl; ++ UINT_8 ucCmdSeqNum; ++ P_EVENT_TEST_STATUS prTestStatus; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) { ++ /* driver implementation */ ++ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; ++ ++ prTestStatus->rATInfo.u4FuncData = ++ (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); ++ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); ++ ++ return WLAN_STATUS_SUCCESS; ++ } else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) { ++ /* driver implementation */ ++ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; ++ ++ prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION; ++ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_TEST_MODE; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pvInformationBuffer = pvQueryBuffer; ++ prCmdInfo->u4InformationBufferLength = u4QueryBufferLen; ++ ++ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); ++ pCmdTestCtrl->ucAction = 2; /* Get ATInfo */ ++ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; ++ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prAdapter->prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} ++ ++WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen) ++{ ++ CMD_TEST_CTRL_T rCmdTestCtrl; ++ ++ ASSERT(prAdapter); ++ ++ rCmdTestCtrl.ucAction = 5; /* Set Channel Frequency */ ++ rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TEST_MODE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, sizeof(CMD_TEST_CTRL_T), (PUINT_8) &rCmdTestCtrl, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command packet generation utility ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucCID Command ID ++* \param[in] fgSetQuery Set or Query ++* \param[in] fgNeedResp Need for response ++* \param[in] pfCmdDoneHandler Function pointer when command is done ++* \param[in] u4SetQueryInfoLen The length of the set/query buffer ++* \param[in] pucInfoBuffer Pointer to set/query buffer ++* ++* ++* \retval WLAN_STATUS_PENDING ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); ++ ++ DEBUGFUNC("wlanSendSetQueryCmd"); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(OID, TRACE, "ucCmdSeqNum =%d, ucCID =%d\n", ucCmdSeqNum, ucCID); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); ++ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; ++ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; ++ prCmdInfo->fgIsOid = fgIsOid; ++ prCmdInfo->ucCID = ucCID; ++ prCmdInfo->fgSetQuery = fgSetQuery; ++ prCmdInfo->fgNeedResp = fgNeedResp; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; ++ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) ++ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++#if CFG_SUPPORT_WAPI ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WAPI ui to set wapi mode, which is needed to info the the driver ++* to operation at WAPI mode while driver initialize. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ DEBUGFUNC("wlanoidSetWapiMode"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ /* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi assoc ie at the check point */ ++ /* The Adapter Connection setting fgUseWapi will cleat whil oid set mode (infra), */ ++ /* And set fgUseWapi True while set wapi assoc ie */ ++ /* policay selection, add key all depend on this flag, */ ++ /* The fgUseWapi may remove later */ ++ if (*(PUINT_32) pvSetBuffer) ++ prAdapter->fgUseWapi = TRUE; ++ else ++ prAdapter->fgUseWapi = FALSE; ++ ++#if 0 ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + 4)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4; ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_WAPI_MODE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetBufferLen; ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ cp = (PUINT_8) (prWifiCmd->aucBuffer); ++ ++ kalMemCopy(cp, (PUINT_8) pvSetBuffer, 4); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++#else ++ return WLAN_STATUS_SUCCESS; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WAPI to set the assoc info, which is needed to add to ++* Association request frame while join WAPI AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_WAPI_INFO_ELEM_T prWapiInfo; ++ PUINT_8 cp; ++ UINT_16 u2AuthSuiteCount = 0; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_32 u4AuthKeyMgtSuite = 0; ++ UINT_32 u4PairSuite = 0; ++ UINT_32 u4GroupSuite = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DEBUGFUNC("wlanoidSetWapiAssocInfo"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ if (u4SetBufferLen < 20 /* From EID to Group cipher */) { ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; ++ DBGLOG(SEC, INFO, "fgWapiMode = FALSE due to u4SetBufferLen %u < 20!\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = TRUE; ++ ++ /* if (prWapiInfo->ucElemId != ELEM_ID_WAPI) */ ++ /* DBGLOG(SEC, TRACE, ("Not WAPI IE ?!\n")); */ ++ ++ /* if (prWapiInfo->ucLength < 18) */ ++ /* return WLAN_STATUS_INVALID_LENGTH; */ ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ prWapiInfo = (P_WAPI_INFO_ELEM_T) pvSetBuffer; ++ ++ if (prWapiInfo->ucElemId != ELEM_ID_WAPI) { ++ DBGLOG(SEC, INFO, "Not WAPI IE ?! u4SetBufferLen = %u\n", u4SetBufferLen); ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (prWapiInfo->ucLength < 18) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* Skip Version check */ ++ cp = (PUINT_8) &prWapiInfo->u2AuthKeyMgtSuiteCount; ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ ++ if (u2AuthSuiteCount > 1) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ cp = (PUINT_8) &prWapiInfo->aucAuthKeyMgtSuite1[0]; ++ WLAN_GET_FIELD_32(cp, &u4AuthKeyMgtSuite); ++ ++ DBGLOG(SEC, TRACE, "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n", ++ u2AuthSuiteCount, ++ (UCHAR) (u4AuthKeyMgtSuite & 0x000000FF), ++ (UCHAR) ((u4AuthKeyMgtSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4AuthKeyMgtSuite >> 16) & 0x000000FF), ++ (UCHAR) ((u4AuthKeyMgtSuite >> 24) & 0x000000FF)); ++ ++ if (u4AuthKeyMgtSuite != WAPI_AKM_SUITE_802_1X && u4AuthKeyMgtSuite != WAPI_AKM_SUITE_PSK) ++ ASSERT(FALSE); ++ ++ cp += 4; ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ if (u2PairSuiteCount > 1) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ cp += 2; ++ WLAN_GET_FIELD_32(cp, &u4PairSuite); ++ DBGLOG(SEC, TRACE, "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ u2PairSuiteCount, ++ (UCHAR) (u4PairSuite & 0x000000FF), ++ (UCHAR) ((u4PairSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4PairSuite >> 16) & 0x000000FF), (UCHAR) ((u4PairSuite >> 24) & 0x000000FF)); ++ ++ if (u4PairSuite != WAPI_CIPHER_SUITE_WPI) ++ ASSERT(FALSE); ++ ++ cp += 4; ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ DBGLOG(SEC, TRACE, "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n", ++ (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (u4GroupSuite != WAPI_CIPHER_SUITE_WPI) ++ ASSERT(FALSE); ++ ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite = u4AuthKeyMgtSuite; ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher = u4PairSuite; ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher = u4GroupSuite; ++ ++ kalMemCopy(prAdapter->prGlueInfo->aucWapiAssocInfoIEs, pvSetBuffer, u4SetBufferLen); ++ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = (UINT_16) u4SetBufferLen; ++ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the wpi key to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_PARAM_WPI_KEY_T prNewKey; ++ P_CMD_802_11_KEY prCmdKey; ++ PUINT_8 pc; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanoidSetWapiKey"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prNewKey = (P_PARAM_WPI_KEY_T) pvSetBuffer; ++ ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) pvSetBuffer, 560); ++ pc = (PUINT_8) pvSetBuffer; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* Exception check */ ++ if (prNewKey->ucKeyID != 0x1 || prNewKey->ucKeyID != 0x0) { ++ prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0); ++ /* DBGLOG(SEC, INFO, ("Invalid WAPI key ID (%d)\r\n", prNewKey->ucKeyID)); */ ++ } ++ ++ /* Dump P_PARAM_WPI_KEY_T content. */ ++ DBGLOG(OID, TRACE, "Set: Dump P_PARAM_WPI_KEY_T content\r\n"); ++ DBGLOG(OID, TRACE, "TYPE : %d\r\n", prNewKey->eKeyType); ++ DBGLOG(OID, TRACE, "Direction : %d\r\n", prNewKey->eDirection); ++ DBGLOG(OID, TRACE, "KeyID : %d\r\n", prNewKey->ucKeyID); ++ DBGLOG(OID, TRACE, "AddressIndex:\r\n"); ++ DBGLOG_MEM8(OID, TRACE, prNewKey->aucAddrIndex, 12); ++ prNewKey->u4LenWPIEK = 16; ++ ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPIEK, (UINT_8) prNewKey->u4LenWPIEK); ++ prNewKey->u4LenWPICK = 16; ++ ++ DBGLOG(OID, TRACE, "CK Key(%d):\r\n", (UINT_8) prNewKey->u4LenWPICK); ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPICK, (UINT_8) prNewKey->u4LenWPICK); ++ DBGLOG(OID, TRACE, "PN:\r\n"); ++ if (prNewKey->eKeyType == 0) { ++ prNewKey->aucPN[0] = 0x5c; ++ prNewKey->aucPN[1] = 0x36; ++ prNewKey->aucPN[2] = 0x5c; ++ prNewKey->aucPN[3] = 0x36; ++ prNewKey->aucPN[4] = 0x5c; ++ prNewKey->aucPN[5] = 0x36; ++ prNewKey->aucPN[6] = 0x5c; ++ prNewKey->aucPN[7] = 0x36; ++ prNewKey->aucPN[8] = 0x5c; ++ prNewKey->aucPN[9] = 0x36; ++ prNewKey->aucPN[10] = 0x5c; ++ prNewKey->aucPN[11] = 0x36; ++ prNewKey->aucPN[12] = 0x5c; ++ prNewKey->aucPN[13] = 0x36; ++ prNewKey->aucPN[14] = 0x5c; ++ prNewKey->aucPN[15] = 0x36; ++ } ++ ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucPN, 16); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetBufferLen)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetBufferLen; ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 1; /* Add */ ++ ++ if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) { ++ prCmdKey->ucTxKey = 1; ++ prCmdKey->ucKeyType = 1; ++ } ++ ++ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->aucAddrIndex, MAC_ADDR_LEN); ++ ++ prCmdKey->ucNetType = 0; /* AIS */ ++ ++ prCmdKey->ucKeyId = prNewKey->ucKeyID; ++ ++ prCmdKey->ucKeyLen = 32; ++ ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI; ++ ++ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucWPIEK, 16); ++ ++ kalMemCopy(prCmdKey->aucKeyMaterial + 16, (PUINT_8) prNewKey->aucWPICK, 16); ++ ++ kalMemCopy(prCmdKey->aucKeyRsc, (PUINT_8) prNewKey->aucPN, 16); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetAddKey */ ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WSC to set the assoc info, which is needed to add to ++* Association request frame while join WPS AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DEBUGFUNC("wlanoidSetWSCAssocInfo"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ kalMemCopy(prAdapter->prGlueInfo->aucWSCAssocInfoIE, pvSetBuffer, u4SetBufferLen); ++ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = (UINT_16) u4SetBufferLen; ++ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++#endif ++ ++#if CFG_ENABLE_WAKEUP_ON_LAN ++WLAN_STATUS ++wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_PM_PACKET_PATTERN prPacketPattern; ++ ++ DEBUGFUNC("wlanoidSetAddWakeupPattern"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); ++ ++ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; ++ ++ /* FIXME: ++ * Send the struct to firmware */ ++ ++ return WLAN_STATUS_FAILURE; ++} ++ ++WLAN_STATUS ++wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_PM_PACKET_PATTERN prPacketPattern; ++ ++ DEBUGFUNC("wlanoidSetAddWakeupPattern"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); ++ ++ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; ++ ++ /* FIXME: ++ * Send the struct to firmware */ ++ ++ return WLAN_STATUS_FAILURE; ++} ++ ++WLAN_STATUS ++wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ PUINT_32 pu4WakeupEventEnable; ++ ++ DEBUGFUNC("wlanoidQueryEnableWakeup"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ pu4WakeupEventEnable = (PUINT_32) pvQueryBuffer; ++ ++ *pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4WakeupEventEnable; ++ ++ DEBUGFUNC("wlanoidSetEnableWakup"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ pu4WakeupEventEnable = (PUINT_32) pvSetBuffer; ++ prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable; ++ ++ /* FIXME: ++ * Send Command Event for setting wakeup-pattern / Magic Packet to firmware ++ * */ ++ ++ return WLAN_STATUS_FAILURE; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to configure PS related settings for WMM-PS test. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T prWmmPsTestInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ CMD_SET_WMM_PS_TEST_STRUCT_T rSetWmmPsTestParam; ++ UINT_16 u2CmdBufLen; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("wlanoidSetWiFiWmmPsTest"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T); ++ ++ prWmmPsTestInfo = (P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T) pvSetBuffer; ++ ++ rSetWmmPsTestParam.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ rSetWmmPsTestParam.bmfgApsdEnAc = prWmmPsTestInfo->bmfgApsdEnAc; ++ rSetWmmPsTestParam.ucIsEnterPsAtOnce = prWmmPsTestInfo->ucIsEnterPsAtOnce; ++ rSetWmmPsTestParam.ucIsDisableUcTrigger = prWmmPsTestInfo->ucIsDisableUcTrigger; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[rSetWmmPsTestParam.ucNetTypeIndex]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ prPmProfSetupInfo->ucBmpDeliveryAC = (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3); ++ prPmProfSetupInfo->ucBmpTriggerAC = rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3); ++ ++ u2CmdBufLen = sizeof(CMD_SET_WMM_PS_TEST_STRUCT_T); ++ ++#if 0 ++ /* it will apply the disable trig or not immediately */ ++ if (prPmInfo->ucWmmPsDisableUcPoll && prPmInfo->ucWmmPsConnWithTrig) ++ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); */ ++ else ++ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); */ ++#endif ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_WMM_PS_TEST_PARMS, TRUE, FALSE, TRUE, NULL, /* TODO? */ ++ NULL, u2CmdBufLen, (PUINT_8) &rSetWmmPsTestParam, NULL, 0); ++ ++ return rStatus; ++} /* wlanoidSetWiFiWmmPsTest */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to configure enable/disable TX A-MPDU feature. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ CMD_TX_AMPDU_T rTxAmpdu; ++ UINT_16 u2CmdBufLen; ++ PBOOLEAN pfgEnable; ++ ++ DEBUGFUNC("wlanoidSetTxAmpdu"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(BOOLEAN); ++ ++ pfgEnable = (PBOOLEAN) pvSetBuffer; ++ ++ rTxAmpdu.fgEnable = *pfgEnable; ++ ++ u2CmdBufLen = sizeof(CMD_TX_AMPDU_T); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TX_AMPDU, ++ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rTxAmpdu, NULL, 0); ++ ++ return rStatus; ++} /* wlanoidSetTxAmpdu */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to configure reject/accept ADDBA Request. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ CMD_ADDBA_REJECT_T rAddbaReject; ++ UINT_16 u2CmdBufLen; ++ PBOOLEAN pfgEnable; ++ ++ DEBUGFUNC("wlanoidSetAddbaReject"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(BOOLEAN); ++ ++ pfgEnable = (PBOOLEAN) pvSetBuffer; ++ ++ rAddbaReject.fgEnable = *pfgEnable; ++ ++ u2CmdBufLen = sizeof(CMD_ADDBA_REJECT_T); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ADDBA_REJECT, ++ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rAddbaReject, NULL, 0); ++ ++ return rStatus; ++} /* wlanoidSetAddbaReject */ ++ ++#if CFG_SLT_SUPPORT ++ ++WLAN_STATUS ++wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; ++ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; ++ ++ DEBUGFUNC("wlanoidQuerySLTStatus"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvQueryBuffer); ++ ++ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvQueryBuffer; ++ ++ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); ++ ++ switch (prMtkSltInfo->rSltFuncIdx) { ++ case ENUM_MTK_SLT_FUNC_LP_SET: ++ { ++ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); ++ ++ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt; ++ } ++ break; ++ default: ++ /* TBD... */ ++ break; ++ } ++ ++ return rWlanStatus; ++} /* wlanoidQuerySLTStatus */ ++ ++WLAN_STATUS ++wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; ++ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; ++ ++ /* 1. Action: Update or Initial Set ++ * 2. Role. ++ * 3. Target MAC address. ++ * 4. RF BW & Rate Settings ++ */ ++ ++ DEBUGFUNC("wlanoidUpdateSLTMode"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvSetBuffer; ++ ++ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ switch (prMtkSltInfo->rSltFuncIdx) { ++ case ENUM_MTK_SLT_FUNC_INITIAL: /* Initialize */ ++ { ++ P_PARAM_MTK_SLT_INITIAL_STRUCT_T prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_INITIAL_STRUCT_T)); ++ ++ prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ if (prSltInfo->prPseudoStaRec != NULL) { ++ /* The driver has been initialized. */ ++ prSltInfo->prPseudoStaRec = NULL; ++ } ++ ++ prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc(prAdapter, ++ BSS_TYPE_IBSS, ++ prMtkSltInit->aucTargetMacAddr, ++ prMtkSltInit->aucTargetMacAddr); ++ ++ prSltInfo->u2SiteID = prMtkSltInit->u2SiteID; ++ ++ /* Bandwidth 2.4G: Channel 1~14 ++ * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64, ++ * *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, ++ * 149, 153, *157, 161, ++ * 184, 188, 192, 196, 200, 204, 208, 212, *216 ++ */ ++ prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5; ++ ++ switch (prSltInfo->ucChannel2G4) { ++ case 1: ++ prSltInfo->ucChannel5G = 36; ++ break; ++ case 6: ++ prSltInfo->ucChannel5G = 52; ++ break; ++ case 11: ++ prSltInfo->ucChannel5G = 104; ++ break; ++ case 16: ++ prSltInfo->ucChannel2G4 = 14; ++ prSltInfo->ucChannel5G = 161; ++ break; ++ default: ++ ASSERT(FALSE); ++ } ++ ++ if (prSltInfo->prPseudoBssDesc == NULL) { ++ do { ++ prSltInfo->prPseudoBssDesc = scanAllocateBssDesc(prAdapter); ++ ++ if (prSltInfo->prPseudoBssDesc == NULL) { ++ rWlanStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ prBssDesc = prSltInfo->prPseudoBssDesc; ++ } while (FALSE); ++ } else { ++ prBssDesc = prSltInfo->prPseudoBssDesc; ++ } ++ ++ if (prBssDesc) { ++ prBssDesc->eBSSType = BSS_TYPE_IBSS; ++ ++ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prMtkSltInit->aucTargetMacAddr); ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); ++ ++ prBssDesc->u2BeaconInterval = 100; ++ prBssDesc->u2ATIMWindow = 0; ++ prBssDesc->ucDTIMPeriod = 1; ++ ++ prBssDesc->u2IELength = 0; ++ ++ prBssDesc->fgIsERPPresent = TRUE; ++ prBssDesc->fgIsHTPresent = TRUE; ++ ++ prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX); ++ prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX); ++ prBssDesc->fgIsUnknownBssBasicRate = FALSE; ++ ++ prBssDesc->fgIsLargerTSF = TRUE; ++ ++ prBssDesc->eBand = BAND_2G4; ++ ++ prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4; ++ ++ prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN; ++ ++ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); ++ } ++ } ++ break; ++ case ENUM_MTK_SLT_FUNC_RATE_SET: /* Update RF Settings. */ ++ if (prSltInfo->prPseudoStaRec == NULL) { ++ rWlanStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++ P_PARAM_MTK_SLT_TR_TEST_STRUCT_T prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_TR_TEST_STRUCT_T)); ++ ++ prStaRec = prSltInfo->prPseudoStaRec; ++ prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { ++ prBssInfo->eBand = BAND_5G; ++ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel5G; ++ } ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM24) { ++ prBssInfo->eBand = BAND_2G4; ++ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel2G4; ++ } ++ ++ if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) { ++ /* RF 40 */ ++ /* It would controls RFBW capability in WTBL. */ ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ /* This controls RF BW, RF BW would be 40 only if */ ++ /* 1. PHY_TYPE_BIT_HT is TRUE. */ ++ /* 2. SCO is SCA/SCB. */ ++ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ ++ /* U20/L20 Control. */ ++ switch (prTRSetting->u4FixedRate & 0xC000) { ++ case FIXED_EXT_CHNL_U20: ++ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* +2 */ ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) ++ prBssInfo->ucPrimaryChannel += 2; ++ else { ++ /* For channel 1, testing L20 at channel 8. */ ++ if (prBssInfo->ucPrimaryChannel < 5) ++ prBssInfo->ucPrimaryChannel = 8; ++ } ++ break; ++ case FIXED_EXT_CHNL_L20: ++ default: /* 40M */ ++ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* -2 */ ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { ++ prBssInfo->ucPrimaryChannel -= 2; ++ } else { ++ /* For channel 11 / 14. testing U20 at channel 3. */ ++ if (prBssInfo->ucPrimaryChannel > 10) ++ prBssInfo->ucPrimaryChannel = 3; ++ } ++ break; ++ } ++ } else { ++ /* RF 20 */ ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; ++ prBssInfo->eBssSCO = CHNL_EXT_SCN; ++ } ++ ++ prBssInfo->fgErpProtectMode = FALSE; ++ prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; ++ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; ++ ++ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); ++ ++ prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++ ++ switch (prTRSetting->u4FixedRate & 0xFF) { ++ case RATE_OFDM_54M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_54M_INDEX); ++ break; ++ case RATE_OFDM_48M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_48M_INDEX); ++ break; ++ case RATE_OFDM_36M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); ++ break; ++ case RATE_OFDM_24M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_24M_INDEX); ++ break; ++ case RATE_OFDM_6M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_6M_INDEX); ++ break; ++ case RATE_CCK_11M_LONG: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_11M_INDEX); ++ break; ++ case RATE_CCK_1M_LONG: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_1M_INDEX); ++ break; ++ case RATE_GF_MCS_0: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; ++ break; ++ case RATE_MM_MCS_7: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; ++#if 0 /* Only for Current Measurement Mode. */ ++ prStaRec->u2HtCapInfo |= (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++#endif ++ break; ++ case RATE_GF_MCS_7: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; ++ break; ++ default: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); ++ break; ++ } ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ break; ++ case ENUM_MTK_SLT_FUNC_LP_SET: /* Reset LP Test Result. */ ++ { ++ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); ++ ++ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ if (prSltInfo->prPseudoBssDesc == NULL) { ++ /* Please initial SLT Mode first. */ ++ break; ++ } ++ prBssDesc = prSltInfo->prPseudoBssDesc; ++ ++ switch (prLpSetting->rLpTestMode) { ++ case ENUM_MTK_LP_TEST_NORMAL: ++ /* In normal mode, we would use target MAC address to be the BSSID. */ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); ++ prSltInfo->fgIsDUT = FALSE; ++ break; ++ case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE: ++ /* 1. Lower AIFS of BCN queue. ++ * 2. Fixed Random Number tobe 0. ++ */ ++ prSltInfo->fgIsDUT = FALSE; ++ /* In LP test mode, we would use MAC address of Golden Sample to be the BSSID. */ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); ++ break; ++ case ENUM_MTK_LP_TEST_DUT: ++ /* 1. Enter Sleep Mode. ++ * 2. Fix random number a large value & enlarge AIFN of BCN queue. ++ */ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssDesc->aucSrcAddr); ++ prSltInfo->u4BeaconReceiveCnt = 0; ++ prSltInfo->fgIsDUT = TRUE; ++ break; ++ } ++ ++ } ++ ++ break; ++ default: ++ break; ++ } ++ ++ return WLAN_STATUS_FAILURE; ++ ++ return rWlanStatus; ++} /* wlanoidUpdateSLTMode */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query NVRAM value. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; ++ UINT_16 u2Data; ++ BOOLEAN fgStatus; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidQueryNvramRead"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvQueryBuffer; ++ ++ if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_READ) { ++ /* change to byte offset */ ++ fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, ++ prNvramRwInfo->ucEepromIndex << 1, ++ &u2Data); ++ ++ if (fgStatus) { ++ prNvramRwInfo->u2EepromData = u2Data; ++ DBGLOG(OID, INFO, "NVRAM Read: index=%#X, data=%#02X\r\n", ++ prNvramRwInfo->ucEepromIndex, u2Data); ++ } else { ++ DBGLOG(OID, ERROR, "NVRAM Read Failed: index=%#x.\r\n", prNvramRwInfo->ucEepromIndex); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_GETSIZE) { ++ prNvramRwInfo->u2EepromData = CFG_FILE_WIFI_REC_SIZE; ++ DBGLOG(OID, INFO, "EEPROM size =%d\r\n", prNvramRwInfo->u2EepromData); ++ } ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ return rStatus; ++} /* wlanoidQueryNvramRead */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write NVRAM value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; ++ BOOLEAN fgStatus; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidSetNvramWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvSetBuffer; ++ ++ /* change to byte offset */ ++ fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, ++ prNvramRwInfo->ucEepromIndex << 1, ++ prNvramRwInfo->u2EepromData); ++ ++ if (fgStatus == FALSE) { ++ DBGLOG(OID, ERROR, "NVRAM Write Failed.\r\n"); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ ++ return rStatus; ++} /* wlanoidSetNvramWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get the config data source type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ ASSERT(prAdapter); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_CFG_SRC_TYPE_T); ++ ++ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) ++ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_NVRAM; ++ else ++ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_EEPROM; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get the config data source type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ ASSERT(prAdapter); ++ ++ *pu4QueryInfoLen = sizeof(P_ENUM_EEPROM_TYPE_T); ++ ++#if CFG_SUPPORT_NIC_CAPABILITY ++ if (prAdapter->fgIsEepromUsed == TRUE) ++ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_PRESENT; ++ else ++ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; ++#else ++ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get the config data source type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_8 pucCountry; ++ UINT_16 u2CountryCode; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(u4SetBufferLen == 2); ++ ++ *pu4SetInfoLen = 2; ++ ++ pucCountry = pvSetBuffer; ++ u2CountryCode = (((UINT_16) pucCountry[0]) << 8) | ((UINT_16) pucCountry[1]); ++ ++ /* previous country code == FF : ignore country code, current country code == FE : resume */ ++ if (prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup == COUNTRY_CODE_FF) { ++ if (u2CountryCode != COUNTRY_CODE_FE) { ++ DBGLOG(OID, INFO, "Skip country code cmd (0x%04x)\n", u2CountryCode); ++ return WLAN_STATUS_SUCCESS; ++ } ++ DBGLOG(OID, INFO, "Resume handle country code cmd (0x%04x)\n", u2CountryCode); ++ } ++ ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode = u2CountryCode; ++ prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ DBGLOG(OID, LOUD, "u2CountryCodeBakup=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup); ++ ++ /* Force to re-search country code in country domains */ ++ prAdapter->prDomainInfo = NULL; ++ rlmDomainSendCmd(prAdapter, TRUE); ++ ++ /* Update supported channel list in channel table based on current country domain */ ++ wlanUpdateChannelTable(prAdapter->prGlueInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if 0 ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; ++ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; ++ ++ DEBUGFUNC("wlanoidSetNoaParam"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); ++ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; ++ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; ++ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); ++} ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; ++ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; ++ ++ DEBUGFUNC("wlanoidSetOppPsParam"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_OPPPS_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); ++} ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; ++ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("wlanoidSetUApsdParam"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ ++ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; ++ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; ++ ++ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; ++ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; ++ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; ++ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; ++ prPmProfSetupInfo->ucBmpDeliveryAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ prPmProfSetupInfo->ucBmpTriggerAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ ++ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; ++ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_UAPSD_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set BT profile or BT information and the ++* driver will set the built-in PTA configuration into chip. ++* ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ++ P_PTA_IPC_T prPtaIpc; ++ ++ DEBUGFUNC("wlanoidSetBT.\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PTA_IPC_T); ++ if (u4SetBufferLen != sizeof(PTA_IPC_T)) { ++ WARNLOG(("Invalid length %u\n", u4SetBufferLen)); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail to set BT profile because of ACPI_D3\n"); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ prPtaIpc = (P_PTA_IPC_T) pvSetBuffer; ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(OID, INFO, ++ "BCM BWCS CMD: BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", ++ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], ++ prPtaIpc->u.aucBTPParams[3]; ++ ++#endif ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BWCS, ++ TRUE, FALSE, FALSE, NULL, NULL, sizeof(PTA_IPC_T), (PUINT_8) prPtaIpc, NULL, 0); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current BT profile and BTCR values ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBT(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++/* P_PARAM_PTA_IPC_T prPtaIpc; */ ++/* UINT_32 u4QueryBuffLen; */ ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PTA_IPC_T); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen != sizeof(PTA_IPC_T)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ ASSERT(pvQueryBuffer); ++/* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */ ++/* prPtaIpc->ucCmd = BT_CMD_PROFILE; */ ++/* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */ ++/* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if 0 ++WLAN_STATUS ++wlanoidQueryBtSingleAntenna(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PTA_INFO_T prPtaInfo; ++ PUINT_32 pu4SingleAntenna; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen != sizeof(UINT_32)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ ASSERT(pvQueryBuffer); ++ ++ prPtaInfo = &prAdapter->rPtaInfo; ++ pu4SingleAntenna = (PUINT_32) pvQueryBuffer; ++ ++ if (prPtaInfo->fgSingleAntenna) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 1\r\n")); */ ++ *pu4SingleAntenna = 1; ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 0\r\n")); */ ++ *pu4SingleAntenna = 0; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidSetBtSingleAntenna(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ++ PUINT_32 pu4SingleAntenna; ++ UINT_32 u4SingleAntenna; ++ P_PTA_INFO_T prPtaInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ prPtaInfo = &prAdapter->rPtaInfo; ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ if (u4SetBufferLen != sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) ++ return WLAN_STATUS_SUCCESS; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail to set antenna because of ACPI_D3\n"); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ pu4SingleAntenna = (PUINT_32) pvSetBuffer; ++ u4SingleAntenna = *pu4SingleAntenna; ++ ++ if (u4SingleAntenna == 0) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 0\r\n")); */ ++ prPtaInfo->fgSingleAntenna = FALSE; ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 1\r\n")); */ ++ prPtaInfo->fgSingleAntenna = TRUE; ++ } ++ ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++WLAN_STATUS ++wlanoidQueryPta(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PTA_INFO_T prPtaInfo; ++ PUINT_32 pu4Pta; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen != sizeof(UINT_32)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ ASSERT(pvQueryBuffer); ++ ++ prPtaInfo = &prAdapter->rPtaInfo; ++ pu4Pta = (PUINT_32) pvQueryBuffer; ++ ++ if (prPtaInfo->fgEnabled) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */ ++ *pu4Pta = 1; ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */ ++ *pu4Pta = 0; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidSetPta(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4PtaCtrl; ++ UINT_32 u4PtaCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ if (u4SetBufferLen != sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) ++ return WLAN_STATUS_SUCCESS; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail to set BT setting because of ACPI_D3\n"); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ pu4PtaCtrl = (PUINT_32) pvSetBuffer; ++ u4PtaCtrl = *pu4PtaCtrl; ++ ++ if (u4PtaCtrl == 0) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); */ ++ nicPtaSetFunc(prAdapter, FALSE); ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); */ ++ nicPtaSetFunc(prAdapter, TRUE); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++#endif ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Tx power profile. ++* ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ /* P_SET_TXPWR_CTRL_T pTxPwr = (P_SET_TXPWR_CTRL_T)pvSetBuffer; */ ++ /* UINT_32 i; */ ++ WLAN_STATUS rStatus; ++ ++ DEBUGFUNC("wlanoidSetTxPower"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ++#if 0 ++ DBGLOG(OID, INFO, "c2GLegacyStaPwrOffset=%d\n", pTxPwr->c2GLegacyStaPwrOffset); ++ DBGLOG(OID, INFO, "c2GHotspotPwrOffset=%d\n", pTxPwr->c2GHotspotPwrOffset); ++ DBGLOG(OID, INFO, "c2GP2pPwrOffset=%d\n", pTxPwr->c2GP2pPwrOffset); ++ DBGLOG(OID, INFO, "c2GBowPwrOffset=%d\n", pTxPwr->c2GBowPwrOffset); ++ DBGLOG(OID, INFO, "c5GLegacyStaPwrOffset=%d\n", pTxPwr->c5GLegacyStaPwrOffset); ++ DBGLOG(OID, INFO, "c5GHotspotPwrOffset=%d\n", pTxPwr->c5GHotspotPwrOffset); ++ DBGLOG(OID, INFO, "c5GP2pPwrOffset=%d\n", pTxPwr->c5GP2pPwrOffset); ++ DBGLOG(OID, INFO, "c5GBowPwrOffset=%d\n", pTxPwr->c5GBowPwrOffset); ++ DBGLOG(OID, INFO, "ucConcurrencePolicy=%d\n", pTxPwr->ucConcurrencePolicy); ++ ++ for (i = 0; i < 14; i++) ++ DBGLOG(OID, INFO, "acTxPwrLimit2G[%d]=%d\n", i, pTxPwr->acTxPwrLimit2G[i]); ++ ++ for (i = 0; i < 4; i++) ++ DBGLOG(OID, INFO, "acTxPwrLimit5G[%d]=%d\n", i, pTxPwr->acTxPwrLimit5G[i]); ++#endif ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_TXPWR_CTRL, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ TRUE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ u4SetBufferLen, /* u4SetQueryInfoLen */ ++ (PUINT_8) pvSetBuffer, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ return rStatus; ++ ++} ++ ++WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) ++{ ++ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; ++ P_CMD_DUMP_MEM prCmdDumpMem; ++ CMD_DUMP_MEM rCmdDumpMem; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; ++ ++ UINT_32 u4RemainLeng = 0; ++ UINT_32 u4CurAddr = 0; ++ UINT_8 ucFragNum = 0; ++ ++ prCmdDumpMem = &rCmdDumpMem; ++ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; ++ ++ u4RemainLeng = prMemDumpInfo->u4RemainLength; ++ u4CurAddr = prMemDumpInfo->u4Address + prMemDumpInfo->u4Length; ++ ucFragNum = prMemDumpInfo->ucFragNum + 1; ++ ++ /* Query. If request length is larger than max length, do it as ping pong. ++ * Send a command and wait for a event. Send next command while the event is received. ++ * ++ */ ++ do { ++ UINT_32 u4CurLeng = 0; ++ ++ if (u4RemainLeng > u4MemSize) { ++ u4CurLeng = u4MemSize; ++ u4RemainLeng -= u4MemSize; ++ } else { ++ u4CurLeng = u4RemainLeng; ++ u4RemainLeng = 0; ++ } ++ ++ prCmdDumpMem->u4Address = u4CurAddr; ++ prCmdDumpMem->u4Length = u4CurLeng; ++ prCmdDumpMem->u4RemainLength = u4RemainLeng; ++ prCmdDumpMem->ucFragNum = ucFragNum; ++ ++ DBGLOG(OID, TRACE, "[%d] 0x%X, len %u, remain len %u\n", ++ ucFragNum, ++ prCmdDumpMem->u4Address, prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_DUMP_MEM, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryMemDump, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_DUMP_MEM), ++ (PUINT_8) prCmdDumpMem, pvQueryBuffer, u4QueryBufferLen); ++ ++ } while (FALSE); ++ ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dump memory. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; ++ ++ DEBUGFUNC("wlanoidQueryMemDump"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; ++ DBGLOG(OID, TRACE, "Dump 0x%X, len %u\n", prMemDumpInfo->u4Address, prMemDumpInfo->u4Length); ++ ++ prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length; ++ prMemDumpInfo->u4Length = 0; ++ prMemDumpInfo->ucFragNum = 0; ++ ++ return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* end of wlanoidQueryMcrRead() */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the p2p mode. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_PARAM_CUSTOM_P2P_SET_STRUCT_T prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) NULL; ++ /* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T)NULL; */ ++ DEBUGFUNC("wlanoidSetP2pMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T); ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) pvSetBuffer; ++ ++ DBGLOG(P2P, INFO, "Set P2P enable %p [%u] mode[%u]\n", prSetP2P, prSetP2P->u4Enable, prSetP2P->u4Mode); ++ ++ /* ++ * enable = 1, mode = 0 => init P2P network ++ * enable = 1, mode = 1 => init Soft AP network ++ * enable = 0 => uninit P2P/AP network ++ */ ++ ++ if (prSetP2P->u4Enable) { ++ p2pSetMode((prSetP2P->u4Mode == 1) ? TRUE : FALSE); ++ ++ if (p2pLaunch(prAdapter->prGlueInfo)) ++ ASSERT(prAdapter->fgIsP2PRegistered); ++ ++ } else { ++ DBGLOG(P2P, TRACE, "prAdapter->fgIsP2PRegistered = %d\n", prAdapter->fgIsP2PRegistered); ++ ++ if (prAdapter->fgIsP2PRegistered) { ++ DBGLOG(P2P, INFO, "p2pRemove\n"); ++ p2pRemove(prAdapter->prGlueInfo); ++ } ++ ++ } ++ ++#if 0 ++ prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_NETDEV_REGISTER_T))); ++ ++ if (prP2pNetdevRegMsg == NULL) { ++ ASSERT(FALSE); ++ status = WLAN_STATUS_RESOURCES; ++ return status; ++ } ++ ++ prP2pNetdevRegMsg->rMsgHdr.eMsgId = MID_MNY_P2P_NET_DEV_REGISTER; ++ prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? TRUE : FALSE; ++ prP2pNetdevRegMsg->ucMode = (UINT_8) prSetP2P->u4Mode; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF); ++#endif ++ ++ return status; ++} ++#endif ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query build date code information from firmware ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ CMD_GET_BUILD_DATE_CODE rCmdGetBuildDateCode; ++ ++ DEBUGFUNC("wlanoidQueryBuildDateCode"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_8) * 16; ++ ++ if (u4QueryBufferLen < sizeof(UINT_8) * 16) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_BUILD_DATE_CODE, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventBuildDateCode, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_GET_BUILD_DATE_CODE), ++ (PUINT_8) &rCmdGetBuildDateCode, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* end of wlanoidQueryBuildDateCode() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query BSS info from firmware ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ EVENT_AIS_BSS_INFO_T rCmdBSSInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); ++ ++ if (u4QueryBufferLen < sizeof(EVENT_AIS_BSS_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ kalMemZero(&rCmdBSSInfo, sizeof(EVENT_AIS_BSS_INFO_T)); ++ /* ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_BSS_INFO, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventGetBSSInfo, ++ nicOidCmdTimeoutCommon, ++ sizeof(P_EVENT_AIS_BSS_INFO_T), ++ (PUINT_8) &rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); ++ */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_BSS_INFO, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventGetBSSInfo, ++ nicOidCmdTimeoutCommon, ++ sizeof(EVENT_AIS_BSS_INFO_T), ++ (PUINT_8) & rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); ++ ++ return rStatus; ++} /* wlanoidSetWiFiWmmPsTest */ ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ ++#define CMD_WLS_BATCHING "WLS_BATCHING" ++ ++#define BATCHING_SET "SET" ++#define BATCHING_GET "GET" ++#define BATCHING_STOP "STOP" ++ ++#define PARAM_SCANFREQ "SCANFREQ" ++#define PARAM_MSCAN "MSCAN" ++#define PARAM_BESTN "BESTN" ++#define PARAM_CHANNEL "CHANNEL" ++#define PARAM_RTT "RTT" ++ ++WLAN_STATUS ++batchSetCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4WritenLen) ++{ ++ P_CHANNEL_INFO_T prRfChannelInfo; ++ CMD_BATCH_REQ_T rCmdBatchReq; ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ PCHAR head, p, p2; ++ UINT_32 tokens; ++ INT_32 scanfreq, mscan, bestn, rtt; ++ ++ DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", (PCHAR) pvSetBuffer, (UINT_32) u4SetBufferLen); ++ ++ if (!pu4WritenLen) ++ return -EINVAL; ++ *pu4WritenLen = 0; ++ ++ if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) { ++ DBGLOG(SCN, TRACE, "[BATCH] invalid len %u\n", (UINT_32) u4SetBufferLen); ++ return -EINVAL; ++ } ++ ++ head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1; ++ kalMemSet(&rCmdBatchReq, 0, sizeof(CMD_BATCH_REQ_T)); ++ ++ if (!kalStrnCmp(head, BATCHING_SET, kalStrLen(BATCHING_SET))) { ++ ++ DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n"); ++ ++ head += kalStrLen(BATCHING_SET) + 1; ++ ++ /* SCANFREQ, MSCAN, BESTN */ ++ tokens = kalSScanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", &scanfreq, &mscan, &bestn); ++ if (tokens != 3) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, SCANFREQ=%d MSCAN=%d BESTN=%d\n", ++ (UINT_32) tokens, scanfreq, mscan, bestn); ++ return -EINVAL; ++ } ++ /* RTT */ ++ p = kalStrStr(head, PARAM_RTT); ++ if (!p) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", head); ++ return -EINVAL; ++ } ++ tokens = kalSScanf(p, "RTT=%d", &rtt); ++ if (tokens != 1) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, rtt=%d\n", (UINT_32) tokens, rtt); ++ return -EINVAL; ++ } ++ /* CHANNEL */ ++ p = kalStrStr(head, PARAM_CHANNEL); ++ if (!p) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n"); ++ return -EINVAL; ++ } ++ head = p; ++ p = kalStrChr(head, '>'); ++ if (!p) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n"); ++ return -EINVAL; ++ } ++ /* else { ++ *p = '.'; // remove '>' because sscanf can not parse <%s> ++ }*/ ++ /*tokens = kalSScanf(head, "CHANNEL=<%s", c_channel); ++ if (tokens != 1) { ++ DBGLOG(SCN, TRACE, ("[BATCH] Parse fail: tokens=%d, CHANNEL=<%s>\n", ++ tokens, c_channel)); ++ return -EINVAL; ++ } */ ++ rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED; ++ rCmdBatchReq.ucChannelListNum = 0; ++ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; ++ p = head + kalStrLen(PARAM_CHANNEL) + 2; /* c_channel; */ ++ while ((p2 = kalStrSep((char **)&p, ",")) != NULL) { ++ if (p2 == NULL || *p2 == 0) ++ break; ++ if (*p2 == '\0') ++ continue; ++ if (*p2 == 'A') { ++ rCmdBatchReq.ucChannelType = ++ rCmdBatchReq.ucChannelType == ++ SCAN_CHANNEL_2G4 ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G; ++ } else if (*p2 == 'B') { ++ rCmdBatchReq.ucChannelType = ++ rCmdBatchReq.ucChannelType == ++ SCAN_CHANNEL_5G ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4; ++ } else { ++ ++ /* Translate Freq from MHz to channel number. */ ++ prRfChannelInfo->ucChannelNum = kalStrtol(p2, NULL, 0); ++ DBGLOG(SCN, TRACE, "Scanning Channel:%u, freq: %d\n", ++ (UINT_32) prRfChannelInfo->ucChannelNum, ++ (UINT_32) nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); ++ prRfChannelInfo->ucBand = prRfChannelInfo->ucChannelNum < 15 ? BAND_2G4 : BAND_5G; ++ ++ rCmdBatchReq.ucChannelListNum++; ++ if (rCmdBatchReq.ucChannelListNum >= 32) ++ break; ++ prRfChannelInfo++; ++ } ++ } ++ ++ /* set channel for test */ ++#if 0 ++ rCmdBatchReq.ucChannelType = 4; /* SCAN_CHANNEL_SPECIFIED; */ ++ rCmdBatchReq.ucChannelListNum = 0; ++ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; ++ for (i = 1; i <= 14; i++) { ++ ++ /* filter out some */ ++ if (i == 1 || i == 5 || i == 11) ++ continue; ++ ++ /* Translate Freq from MHz to channel number. */ ++ prRfChannelInfo->ucChannelNum = i; ++ DBGLOG(SCN, TRACE, "Scanning Channel:%d, freq: %d\n", ++ prRfChannelInfo->ucChannelNum, ++ nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); ++ prRfChannelInfo->ucBand = BAND_2G4; ++ ++ rCmdBatchReq.ucChannelListNum++; ++ prRfChannelInfo++; ++ } ++#endif ++#if 0 ++ rCmdBatchReq.ucChannelType = 0; /* SCAN_CHANNEL_FULL; */ ++#endif ++ ++ rCmdBatchReq.u4Scanfreq = scanfreq; ++ rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? CFG_BATCH_MAX_MSCAN : mscan; ++ rCmdBatchReq.ucBestn = bestn; ++ rCmdBatchReq.ucRtt = rtt; ++ DBGLOG(SCN, TRACE, "[BATCH] SCANFREQ=%u MSCAN=%u BESTN=%u RTT=%u\n", ++ (UINT_32) rCmdBatchReq.u4Scanfreq, ++ (UINT_32) rCmdBatchReq.ucMScan, ++ (UINT_32) rCmdBatchReq.ucBestn, (UINT_32) rCmdBatchReq.ucRtt; ++ ++ if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) { ++ DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n", ++ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? "FULL" : ++ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all"); ++ } else { ++ DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n"); ++ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; ++ for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; tokens++) { ++ DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n", ++ prRfChannelInfo->ucBand == BAND_2G4 ? "2.4G" : "5G", ++ prRfChannelInfo->ucChannelNum); ++ prRfChannelInfo++; ++ } ++ } ++ ++ rCmdBatchReq.ucSeqNum = 1; ++ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START; ++ ++ *pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", rCmdBatchReq.ucMScan); ++ ++ } else if (!kalStrnCmp(head, BATCHING_STOP, kalStrLen(BATCHING_STOP))) { ++ ++ DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n"); ++ ++ rCmdBatchReq.ucSeqNum = 1; ++ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP; ++ } else { ++ return -EINVAL; ++ } ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BATCH_REQ, ++ TRUE, FALSE, TRUE, NULL, NULL, sizeof(CMD_BATCH_REQ_T), (PUINT_8) &rCmdBatchReq, NULL, 0); ++ ++ /* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */ ++ /* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */ ++ ++ return rStatus; ++} ++ ++WLAN_STATUS ++batchGetCmd(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ CMD_BATCH_REQ_T rCmdBatchReq; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_EVENT_BATCH_RESULT_T prEventBatchResult; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pvQueryBuffer; ++ ++ DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%u) XXX\n", (UINT_32) prEventBatchResult->ucScanCount); ++ ++ *pu4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); ++ ++ rCmdBatchReq.ucSeqNum = 2; ++ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT; ++ rCmdBatchReq.ucMScan = prEventBatchResult->ucScanCount; /* Get which round result */ ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BATCH_REQ, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventBatchScanResult, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_BATCH_REQ_T), ++ (PUINT_8) &rCmdBatchReq, (PVOID) pvQueryBuffer, u4QueryBufferLen); ++ ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, pu4SetInfoLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ return batchGetCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen, pu4QueryInfoLen); ++ ++} /* end of wlanoidQueryBatchScanResult() */ ++ ++#endif /* CFG_SUPPORT_BATCH_SCAN */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request starting of schedule scan ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; ++ ++ DEBUGFUNC("wlanoidSetStartSchedScan()"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen != sizeof(PARAM_SCHED_SCAN_REQUEST)) { ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ return WLAN_STATUS_INVALID_DATA; ++ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED && ++ prAdapter->fgEnOnlineScan == FALSE) { ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) pvSetBuffer; ++ ++ if (scnFsmSchedScanRequest(prAdapter, ++ (UINT_8) (prSchedScanRequest->u4SsidNum), ++ prSchedScanRequest->arSsid, ++ prSchedScanRequest->u4IELength, ++ prSchedScanRequest->pucIE, prSchedScanRequest->u2ScanInterval) == TRUE) { ++ return WLAN_STATUS_SUCCESS; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request termination of schedule scan ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(prAdapter); ++ ++ /* ask SCN module to stop scan request */ ++ if (scnFsmSchedScanStopRequest(prAdapter) == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ else ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a periodically scan action ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_CMD_SET_PSCAN_ENABLE prCmdPscnAction; ++ P_SCAN_INFO_T prScanInfo; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ DBGLOG(SCN, TRACE, "wlanoidSetGSCNAction\n"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (u4SetBufferLen != sizeof(CMD_SET_PSCAN_ENABLE)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ else if (pvSetBuffer == NULL) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prCmdPscnAction = (P_CMD_SET_PSCAN_ENABLE) pvSetBuffer; ++ ++ if (prCmdPscnAction->ucPscanAct == ENABLE) { ++#if 0 ++ DBGLOG(OID, INFO, "set PCSN ENABLE\n"); ++ if (scnFsmPSCNAction(prAdapter, (UINT_8) (prCmdPscnAction->ucPscanAct)) == TRUE) { ++ ++ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); ++ return WLAN_STATUS_PENDING; ++ } ++ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); ++ return WLAN_STATUS_FAILURE; ++ ++#endif ++ scnPSCNFsm(prAdapter, PSCN_SCANNING, NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, TRUE); ++ } else if (prCmdPscnAction->ucPscanAct == DISABLE) { ++#if 0 ++ DBGLOG(OID, INFO, "disable PCSN\n"); ++ scnFsmPSCNAction(prAdapter, (UINT_8) DISABLE); ++ ++ DBGLOG(OID, TRACE, "set new PCSN\n"); ++ scnCombineParamsIntoPSCN(prAdapter, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE); ++ ++ DBGLOG(OID, INFO, "ENABLE or disable PCSN\n"); ++ if (!prScanInfo->fgPscnOnnning) { ++ DBGLOG(OID, INFO, "ENABLE PCSN\n"); ++ scnFsmPSCNAction(prAdapter, ENABLE); ++ } else { ++ DBGLOG(OID, INFO, "All PCSN is disabled...\n"); ++ } ++#endif ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE, FALSE); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a periodically scan action ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam; ++ /*UINT_8 i, j = 0;*/ ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam v1\n"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { ++ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(P_PARAM_WIFI_GSCAN_CMD_PARAMS))\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prCmdGscnParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; ++ /* KC-XXX memcpy(prCmdGscnParam, */ ++ /* (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer, */ ++ /* sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS) ); */ ++ DBGLOG(SCN, INFO, ++ "prCmdGscnParam : base_period[%u], max_ap_per_scan[%u] num_buckets[%u], report_threshold[%u]\n", ++ prCmdGscnParam->base_period, prCmdGscnParam->max_ap_per_scan, prCmdGscnParam->num_buckets, ++ prCmdGscnParam->report_threshold); ++#if 0 ++ for (i = 0; i < prCmdGscnParam->num_buckets; i++) { ++ ++ DBGLOG(OID, INFO, ++ "prCmdGscnParam->buckets : band[%u], bucket[%u] num_buckets[%u], period[%u] report_events[%u]\n", ++ prCmdGscnParam->buckets[i].band, prCmdGscnParam->buckets[i].bucket, ++ prCmdGscnParam->buckets[i].num_channels, prCmdGscnParam->buckets[i].period, ++ prCmdGscnParam->buckets[i].report_events)); ++ DBGLOG(OID, INFO, "prCmdGscnParam->buckets[%d] has channel: ", i); ++ for (j = 0; j < prCmdGscnParam->buckets[i].num_channels; j++) ++ DBGLOG(OID, INFO, " %d, ", prCmdGscnParam->buckets[i].channels[j].channel); ++ DBGLOG(OID, INFO, "\n"); ++ } ++#endif ++ if (scnSetGSCNParam(prAdapter, prCmdGscnParam) == TRUE) { ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); ++ return WLAN_STATUS_PENDING; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set configure gscan PARAMs ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS ++wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnScnConfigParam; ++ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; ++ ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAConfig v1\n"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { ++ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer\n"); ++ prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; ++ memcpy(prCmdGscnScnConfigParam, (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer, ++ sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam assign prCmdGscnScnConfig\n"); ++ rCmdGscnScnConfig.u4BufferThreshold = prCmdGscnScnConfigParam->report_threshold; ++ rCmdGscnScnConfig.ucNumApPerScn = prCmdGscnScnConfigParam->max_ap_per_scan; ++ rCmdGscnScnConfig.u4NumScnToCache = prCmdGscnScnConfigParam->num_scans; ++ DBGLOG(SCN, INFO, " report_threshold %d report_threshold %d num_scans %d\n", ++ rCmdGscnScnConfig.u4BufferThreshold, ++ rCmdGscnScnConfig.ucNumApPerScn, rCmdGscnScnConfig.u4NumScnToCache); ++ if (scnFsmSetGSCNConfig(prAdapter, &rCmdGscnScnConfig) == TRUE) { ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); ++ return WLAN_STATUS_PENDING; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get a gscan result ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS prGetGscnScnResultParm; ++ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; ++ ++ DEBUGFUNC("wlanoidGetGSCNResult()"); ++ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult v1\n"); ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS)) { ++ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prGetGscnScnResultParm = (P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) pvSetBuffer; ++ /* memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultParm, sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) ); */ ++ ++ rGetGscnScnResultCmd.u4Num = prGetGscnScnResultParm->get_num; ++ rGetGscnScnResultCmd.ucFlush = prGetGscnScnResultParm->flush; ++ rGetGscnScnResultCmd.ucVersion = PSCAN_VERSION; ++ kalMemZero(rGetGscnScnResultCmd.aucReserved, sizeof(rGetGscnScnResultCmd.aucReserved)); ++ ++ if (scnFsmGetGSCNResult(prAdapter, &rGetGscnScnResultCmd) == TRUE) { ++ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult --->scnFsmGetGSCNResult\n"); ++ return WLAN_STATUS_PENDING; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++ ++} ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by HS2.0 to set the assoc info, which is needed to add to ++* Association request frame while join HS2.0 AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_IE_HS20_INDICATION_T prHS20IndicationIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DEBUGFUNC("wlanoidSetHS20AssocInfo"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pvSetBuffer; ++ ++ prAdapter->prGlueInfo->ucHotspotConfig = prHS20IndicationIe->ucHotspotConfig; ++ prAdapter->prGlueInfo->fgConnectHS20AP = TRUE; ++ ++ DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen); ++ ++ kalMemCopy(prAdapter->prGlueInfo->aucHS20AssocInfoIE, pvSetBuffer, u4SetBufferLen); ++ prAdapter->prGlueInfo->u2HS20AssocInfoIELen = (UINT_16) u4SetBufferLen; ++ DBGLOG(SEC, TRACE, "HS20 Assoc Info IE sz %u\n", u4SetBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WSC to set the assoc info, which is needed to add to ++* Association request frame while join WPS AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#if 0 ++ P_HS20_INFO_T prHS20Info = NULL; ++ P_IE_INTERWORKING_T prInterWorkingIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ ++ DEBUGFUNC("wlanoidSetInterworkingInfo"); ++ DBGLOG(OID, TRACE, "\r\n"); ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ prInterWorkingIe = (P_IE_INTERWORKING_T) pvSetBuffer; ++ ++ prHS20Info->ucAccessNetworkOptions = prInterWorkingIe->ucAccNetOpt; ++ prHS20Info->ucVenueGroup = prInterWorkingIe->ucVenueGroup; ++ prHS20Info->ucVenueType = prInterWorkingIe->ucVenueType; ++ COPY_MAC_ADDR(prHS20Info->aucHESSID, prInterWorkingIe->aucHESSID); ++ ++ DBGLOG(SEC, TRACE, "IW IE sz %ld\n", u4SetBufferLen); ++#endif ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WSC to set the Roaming Consortium IE info, which is needed to ++* add to Association request frame while join WPS AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#if 0 ++ P_HS20_INFO_T prHS20Info = NULL; ++ P_PARAM_HS20_ROAMING_CONSORTIUM_INFO prRCInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ ++ /* DEBUGFUNC("wlanoidSetRoamingConsortiumInfo"); */ ++ /* DBGLOG(HS2, TRACE, ("\r\n")); */ ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ prRCInfo = (P_PARAM_HS20_ROAMING_CONSORTIUM_INFO) pvSetBuffer; ++ ++ kalMemCopy(&(prHS20Info->rRCInfo), prRCInfo, sizeof(PARAM_HS20_ROAMING_CONSORTIUM_INFO)); ++ ++ /* DBGLOG(HS2, TRACE, ("RoamingConsortium IE sz %ld\n", u4SetBufferLen)); */ ++#endif ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set_bssid_pool ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (u4SetBufferLen < sizeof(PARAM_HS20_SET_BSSID_POOL)) { ++ *pu4SetInfoLen = sizeof(PARAM_HS20_SET_BSSID_POOL); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, NETWORK_TYPE_AIS_INDEX); ++ ++ return rWlanStatus; ++} /* end of wlanoidSendHS20GASRequest() */ ++ ++#endif ++ ++#if CFG_SUPPORT_ROAMING_ENC ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the MAC address the NIC is currently using. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_ROAMING_INFO_T *prCmdRoamingInfo; ++ ++ DEBUGFUNC("wlanoidSetRoamingInfo"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(CMD_ROAMING_INFO_T); ++ ++ if (u4SetBufferLen < sizeof(CMD_ROAMING_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prCmdRoamingInfo = (CMD_ROAMING_INFO_T *) pvSetBuffer; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_ROAMING_INFO, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ROAMING_INFO_T), (PUINT_8) prCmdRoamingInfo, NULL, 0); ++} ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set chip ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T prChipConfigInfo; ++ CMD_CHIP_CONFIG_T rCmdChipConfig; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE); ++ DEBUGFUNC("wlanoidSetChipConfig"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prChipConfigInfo = (P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T) pvSetBuffer; ++ kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); ++ ++ rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; ++ rCmdChipConfig.ucType = prChipConfigInfo->ucType; ++ rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; ++ rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; ++ if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { ++ DBGLOG(OID, INFO, "Chip config Msg Size %u is not valid (set)\n", rCmdChipConfig.u2MsgSize); ++ rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; ++ } ++ kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, rCmdChipConfig.u2MsgSize); ++ ++ DBGLOG(OID, TRACE, "rCmdChipConfig.aucCmd=%s\n", rCmdChipConfig.aucCmd); ++#if 1 ++ rWlanStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_CHIP_CONFIG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CHIP_CONFIG_T), ++ (PUINT_8) &rCmdChipConfig, pvSetBuffer, u4SetBufferLen); ++#endif ++ return rWlanStatus; ++} /* wlanoidSetChipConfig */ ++ ++WLAN_STATUS ++wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_CMD_WFD_DEBUG_MODE_INFO_T prCmdWfdDebugModeInfo; ++ ++ DEBUGFUNC("wlanoidSetWFDDebugMode"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(CMD_WFD_DEBUG_MODE_INFO_T); ++ ++ if (u4SetBufferLen < sizeof(CMD_WFD_DEBUG_MODE_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prCmdWfdDebugModeInfo = (CMD_WFD_DEBUG_MODE_INFO_T *) pvSetBuffer; ++ ++ DBGLOG(OID, INFO, "New WFD Debug: %d mode and period=0x%x\n", prCmdWfdDebugModeInfo->ucDebugMode, ++ prCmdWfdDebugModeInfo->u2PeriodInteval); ++ ++ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode = (UINT_8) prCmdWfdDebugModeInfo->ucDebugMode; ++ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.u2WfdSNShowPeiroid = ++ (UINT_16) prCmdWfdDebugModeInfo->u2PeriodInteval; ++ ++ return WLAN_STATUS_SUCCESS; ++} /*wlanoidSetWfdDebugMode */ ++ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the MAC address the NIC is currently using. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTxRateInfo( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_RLM_INFO_T *prCmdTxRInfo; ++ ++ DEBUGFUNC("wlanoidSetTxRateInfo"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(CMD_RLM_INFO_T); ++ ++ if (u4SetBufferLen < sizeof(CMD_RLM_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prCmdTxRInfo = (CMD_RLM_INFO_T *)pvSetBuffer; ++ ++ DBGLOG(OID, INFO, " command = %u %u %u %u %d %u %u\n", ++ prCmdTxRInfo->u4Version, ++ prCmdTxRInfo->fgIsErrRatioEnhanceApplied, ++ prCmdTxRInfo->ucErrRatio2LimitMinRate, ++ prCmdTxRInfo->ucMinLegacyRateIdx, ++ prCmdTxRInfo->cMinRssiThreshold, ++ prCmdTxRInfo->fgIsRtsApplied, ++ prCmdTxRInfo->ucRecoverTime)); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TX_AR_ERR_CONFIG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_RLM_INFO_T), ++ (PUINT_8)prCmdTxRInfo, ++ NULL, ++ 0 ++ ); ++} ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ ++WLAN_STATUS ++wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WIFI_SYSTEM_SUSPEND_CMD_T rSuspendCmd; ++ ++ if (!prAdapter || !pvSetBuffer) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ rSuspendCmd.fgIsSystemSuspend = *(PBOOLEAN)pvSetBuffer; ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_SYSTEM_SUSPEND, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(BOOLEAN), ++ (PUINT_8)&rSuspendCmd, ++ NULL, ++ 0); ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c +new file mode 100644 +index 000000000000..7ca7ee48922e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c +@@ -0,0 +1,1654 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/common/wlan_p2p.c#8 ++*/ ++ ++/*! \file wlan_bow.c ++ \brief This file contains the Wi-Fi Direct commands processing routines for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_p2p.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 24 2011 yuche.tsai ++ * NULL ++ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Update RSSI link quality of P2P Network query method. (Bug fix) ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support ++ * for service discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix Multicast Issue of P2P. ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * Support P2P ARP filter setting on early suspend/ late resume ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 17 2011 wh.su ++ * [WCXRP00000571] [MT6620 Wi-Fi] [Driver] Not check the p2p role during set key ++ * Skip the p2p role for adding broadcast key issue. ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * fixed compiling error while enable dbg. ++ * ++ * 03 08 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format ++ * issue[WCXRP00000509] [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. ++ * . ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 03 02 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix SD Request Query Length issue. ++ * ++ * 03 02 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Service Discovery Request. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Wlan OID related function. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Related wlanoid function. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Indication Related code. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Function. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ioctl implementations for P2P Service Discovery ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ++ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous ++ * and physically-continuous type to ease slab system pressure ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add subroutines for P2P to set multicast list. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * . ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * support wlanoidSetP2pPowerSaveProfile() in P2P ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * Support wlanoidSetNetworkAddress() for P2P ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++** ++*/ ++ ++/****************************************************************************** ++* C O M P I L E R F L A G S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************* ++*/ ++#include "precomp.h" ++#include "gl_p2p_ioctl.h" ++ ++/****************************************************************************** ++* C O N S T A N T S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* D A T A T Y P E S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P U B L I C D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P R I V A T E D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* M A C R O S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N S ++******************************************************************************* ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command packet generation utility ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucCID Command ID ++* \param[in] fgSetQuery Set or Query ++* \param[in] fgNeedResp Need for response ++* \param[in] pfCmdDoneHandler Function pointer when command is done ++* \param[in] u4SetQueryInfoLen The length of the set/query buffer ++* \param[in] pucInfoBuffer Pointer to set/query buffer ++* ++* ++* \retval WLAN_STATUS_PENDING ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ASSERT(prGlueInfo); ++ ++ DEBUGFUNC("wlanoidSendSetQueryP2PCmd"); ++ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); ++ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(P2P, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_P2P_INDEX; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); ++ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; ++ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; ++ prCmdInfo->fgIsOid = fgIsOid; ++ prCmdInfo->ucCID = ucCID; ++ prCmdInfo->fgSetQuery = fgSetQuery; ++ prCmdInfo->fgNeedResp = fgNeedResp; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; ++ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) ++ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a key to Wi-Fi Direct driver ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_802_11_KEY rCmdKey; ++ P_PARAM_KEY_T prNewKey; ++ ++ DEBUGFUNC("wlanoidSetAddP2PKey"); ++ DBGLOG(REQ, INFO, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; ++ ++ /* Verify the key structure length. */ ++ if (prNewKey->u4Length > u4SetBufferLen) { ++ DBGLOG(REQ, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ /* Verify the key material length for key material buffer */ ++ else if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { ++ DBGLOG(REQ, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ /* Exception check */ ++ else if (prNewKey->u4KeyIndex & 0x0fffff00) ++ return WLAN_STATUS_INVALID_DATA; ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) { ++ return WLAN_STATUS_INVALID_DATA; ++ } else if (!(prNewKey->u4KeyLength == CCMP_KEY_LEN) && !(prNewKey->u4KeyLength == TKIP_KEY_LEN)) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { ++ if (((prNewKey->u4KeyIndex & 0xff) != 0) || ++ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) ++ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) ++ && (prNewKey->arBSSID[5] == 0xff))) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* fill CMD_802_11_KEY */ ++ kalMemZero(&rCmdKey, sizeof(CMD_802_11_KEY)); ++ rCmdKey.ucAddRemove = 1; /* add */ ++ rCmdKey.ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; ++ rCmdKey.ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; ++ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ ++ rCmdKey.ucIsAuthenticator = 0; ++ } else { /* group owner */ ++ rCmdKey.ucIsAuthenticator = 1; ++ } ++ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prNewKey->arBSSID); ++ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; ++ if (prNewKey->u4KeyLength == CCMP_KEY_LEN) ++ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ ++ else if (prNewKey->u4KeyLength == TKIP_KEY_LEN) ++ rCmdKey.ucAlgorithmId = CIPHER_SUITE_TKIP; /* TKIP */ ++ rCmdKey.ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); ++ rCmdKey.ucKeyLen = (UINT_8) prNewKey->u4KeyLength; ++ kalMemCopy(rCmdKey.aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, rCmdKey.ucKeyLen); ++ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_ADD_REMOVE_KEY, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ NULL, ++ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request Wi-Fi Direct driver to remove keys ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_802_11_KEY rCmdKey; ++ P_PARAM_REMOVE_KEY_T prRemovedKey; ++ ++ DEBUGFUNC("wlanoidSetRemoveP2PKey"); ++ ASSERT(prAdapter); ++ ++ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; ++ ++ /* Check bit 31: this bit should always 0 */ ++ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { ++ /* Bit 31 should not be set */ ++ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Check bits 8 ~ 29 should always be 0 */ ++ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { ++ /* Bit 31 should not be set */ ++ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* There should not be any key operation for P2P Device */ ++ if (kalP2PGetRole(prAdapter->prGlueInfo) == 0) ++ ; /* return WLAN_STATUS_NOT_ACCEPTED; */ ++ ++ kalMemZero((PUINT_8) &rCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ rCmdKey.ucAddRemove = 0; /* remove */ ++ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ ++ rCmdKey.ucIsAuthenticator = 0; ++ } else { /* group owner */ ++ rCmdKey.ucIsAuthenticator = 1; ++ } ++ kalMemCopy(rCmdKey.aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); ++ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; ++ rCmdKey.ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); ++ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_ADD_REMOVE_KEY, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ NULL, ++ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setting the IP address for pattern search function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 i, j; ++ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; ++ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; ++ P_PARAM_NETWORK_ADDRESS prNetworkAddress; ++ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; ++ UINT_32 u4IpAddressCount, u4CmdSize; ++ ++ DEBUGFUNC("wlanoidSetP2pNetworkAddress"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 4; ++ ++ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ *pu4SetInfoLen = 0; ++ u4IpAddressCount = 0; ++ ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ u4IpAddressCount++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ /* construct payload of command packet */ ++ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + ++ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; ++ ++ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); ++ ++ if (prCmdNetworkAddressList == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ ++ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; ++ ++ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++ ++ j++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_IP_ADDRESS, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetIpAddress, ++ nicOidCmdTimeoutCommon, ++ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); ++ ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query the power save profile. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryP2pPowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen != 0) { ++ ASSERT(pvQueryBuffer); ++ ++ *(PPARAM_POWER_MODE) pvQueryBuffer = ++ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile); ++ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the power save profile. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status; ++ PARAM_POWER_MODE ePowerMode; ++ ++ DEBUGFUNC("wlanoidSetP2pPowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); ++ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { ++ DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { ++ WARNLOG(("Invalid power mode %d\n", *(PPARAM_POWER_MODE) pvSetBuffer)); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; ++ ++ if (prAdapter->fgEnCtiaPowerMode) { ++ if (ePowerMode == Param_PowerModeCAM) { ++ /*Todo:: Nothing*/ ++ /*Todo:: Nothing*/ ++ } else { ++ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ ++ ++ if (prAdapter->u4CtiaPowerMode == 0) { ++ /* force to keep in CAM mode */ ++ ePowerMode = Param_PowerModeCAM; ++ } else if (prAdapter->u4CtiaPowerMode == 1) { ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else if (prAdapter->u4CtiaPowerMode == 2) { ++ ePowerMode = Param_PowerModeFast_PSP; ++ } ++ } ++ } ++ ++ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_P2P_INDEX, ePowerMode, TRUE); ++ return status; ++} /* end of wlanoidSetP2pPowerSaveProfile() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the power save profile. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 i, j; ++ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; ++ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; ++ P_PARAM_NETWORK_ADDRESS prNetworkAddress; ++ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; ++ UINT_32 u4IpAddressCount, u4CmdSize; ++ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; ++ ++ DEBUGFUNC("wlanoidSetP2pSetNetworkAddress"); ++ DBGLOG(P2P, TRACE, "\n"); ++ DBGLOG(P2P, INFO, "wlanoidSetP2pSetNetworkAddress (%d)\n", (INT_16) u4SetBufferLen); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 4; ++ ++ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ *pu4SetInfoLen = 0; ++ u4IpAddressCount = 0; ++ ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ u4IpAddressCount++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ /* construct payload of command packet */ ++ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + ++ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; ++ ++ if (u4IpAddressCount == 0) ++ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); ++ ++ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); ++ ++ if (prCmdNetworkAddressList == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ ++ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ ++ /* only to set IP address to FW once ARP filter is enabled */ ++ if (prAdapter->fgEnArpFilter) { ++ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ ++ DBGLOG(P2P, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); ++ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; ++ ++ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++ ++ j++; ++ ++ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; ++ DBGLOG(P2P, INFO, "prNetAddrIp->in_addr:%d:%d:%d:%d\n", ++ (UINT_8) pucBuf[0], (UINT_8) pucBuf[1], ++ (UINT_8) pucBuf[2], (UINT_8) pucBuf[3]); ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ } ++ ++ } else { ++ prCmdNetworkAddressList->ucAddressCount = 0; ++ } ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_IP_ADDRESS, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetIpAddress, ++ nicOidCmdTimeoutCommon, ++ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); ++ ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return rStatus; ++} /* end of wlanoidSetP2pSetNetworkAddress() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Multicast Address List. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* The data must be a multiple of the Ethernet address size. */ ++ if ((u4SetBufferLen % MAC_ADDR_LEN)) { ++ DBGLOG(REQ, WARN, "Invalid MC list length %u\n", u4SetBufferLen); ++ ++ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; ++ ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* Verify if we can support so many multicast addresses. */ ++ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { ++ DBGLOG(REQ, WARN, "Too many MC addresses\n"); ++ ++ return WLAN_STATUS_MULTICAST_FULL; ++ } ++ ++ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && ++ * pvSetBuffer == NULL to clear exist Multicast List. ++ */ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(REQ, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; ++ rCmdMacMcastAddr.ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); ++ ++ /* This CMD response is no need to complete the OID. Or the event would unsync. */ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, CMD_ID_MAC_MCAST_ADDR, TRUE, FALSE, FALSE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_MAC_MCAST_ADDR), ++ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); ++ ++} /* end of wlanoidSetP2PMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send GAS frame for P2P Service Discovery Request ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_REQUEST)) { ++ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_REQUEST); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++/* rWlanStatus = p2pFsmRunEventSDRequest(prAdapter, (P_PARAM_P2P_SEND_SD_REQUEST)pvSetBuffer); */ ++ ++ return rWlanStatus; ++} /* end of wlanoidSendP2PSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send GAS frame for P2P Service Discovery Response ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_RESPONSE)) { ++ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_RESPONSE); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++/* rWlanStatus = p2pFsmRunEventSDResponse(prAdapter, (P_PARAM_P2P_SEND_SD_RESPONSE)pvSetBuffer); */ ++ ++ return rWlanStatus; ++} /* end of wlanoidGetP2PSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get GAS frame for P2P Service Discovery Request ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ /*PUINT_8 pucPacketBuffer = NULL, pucTA = NULL;*/ ++/* PUINT_8 pucChannelNum = NULL; */ ++ /*PUINT_16 pu2PacketLength = NULL;*/ ++ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ ++ /*UINT_8 ucVersionNum = 0;*/ ++/* UINT_8 ucChannelNum = 0, ucSeqNum = 0; */ ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_REQUEST)) { ++ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_REQUEST); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ DBGLOG(P2P, TRACE, "Get Service Discovery Request\n"); ++#if 0 ++ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); ++ if (ucVersionNum == 0) { ++ P_PARAM_P2P_GET_SD_REQUEST prP2pGetSdReq = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; ++ ++ pucPacketBuffer = prP2pGetSdReq->aucPacketContent; ++ pu2PacketLength = &prP2pGetSdReq->u2PacketLength; ++ pucTA = &prP2pGetSdReq->rTransmitterAddr; ++ } else { ++ P_PARAM_P2P_GET_SD_REQUEST_EX prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST_EX) NULL; ++ ++ prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; ++ pucPacketBuffer = prP2pGetSdReqEx->aucPacketContent; ++ pu2PacketLength = &prP2pGetSdReqEx->u2PacketLength; ++ pucTA = &prP2pGetSdReqEx->rTransmitterAddr; ++ pucChannelNum = &prP2pGetSdReqEx->ucChannelNum; ++ ucSeqNum = prP2pGetSdReqEx->ucSeqNum; ++ } ++ ++ rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, ++ pucPacketBuffer, ++ (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_REQUEST)), ++ (PUINT_32) pu2PacketLength, pucChannelNum, ucSeqNum); ++#else ++ *pu4QueryInfoLen = 0; ++ return rWlanStatus; ++#endif ++ /* ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketBuffer; ++ ++ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); ++ ++ if (pu4QueryInfoLen) { ++ if (ucVersionNum == 0) ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST) + (*pu2PacketLength)); ++ else ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST_EX) + (*pu2PacketLength)); ++ ++ } ++ ++ return rWlanStatus; ++ */ ++} /* end of wlanoidGetP2PSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get GAS frame for P2P Service Discovery Response ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ ++ /* UINT_8 ucSeqNum = 0, */ ++ /*UINT_8 ucVersionNum = 0;*/ ++ /*PUINT_8 pucPacketContent = (PUINT_8) NULL, pucTA = (PUINT_8) NULL;*/ ++ /*PUINT_16 pu2PacketLength = (PUINT_16) NULL;*/ ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_RESPONSE)) { ++ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_RESPONSE); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ DBGLOG(P2P, TRACE, "Get Service Discovery Response\n"); ++ ++#if 0 ++ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); ++ if (ucVersionNum == 0) { ++ P_PARAM_P2P_GET_SD_RESPONSE prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_RESPONSE) NULL; ++ ++ prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; ++ pucPacketContent = prP2pGetSdRsp->aucPacketContent; ++ pucTA = &prP2pGetSdRsp->rTransmitterAddr; ++ pu2PacketLength = &prP2pGetSdRsp->u2PacketLength; ++ } else { ++ P_PARAM_P2P_GET_SD_RESPONSE_EX prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) NULL; ++ ++ prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) pvQueryBuffer; ++ pucPacketContent = prP2pGetSdRspEx->aucPacketContent; ++ pucTA = &prP2pGetSdRspEx->rTransmitterAddr; ++ pu2PacketLength = &prP2pGetSdRspEx->u2PacketLength; ++ ucSeqNum = prP2pGetSdRspEx->ucSeqNum; ++ } ++ ++/* rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, */ ++/* pucPacketContent, */ ++/* (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_RESPONSE)), */ ++/* (PUINT_32)pu2PacketLength, */ ++/* NULL, */ ++/* ucSeqNum); */ ++#else ++ *pu4QueryInfoLen = 0; ++ return rWlanStatus; ++#endif ++ /* ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketContent; ++ ++ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); ++ ++ if (pu4QueryInfoLen) { ++ if (ucVersionNum == 0) ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE) + *pu2PacketLength); ++ else ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE_EX) + *pu2PacketLength); ++ } ++ ++ return rWlanStatus; ++ */ ++} /* end of wlanoidGetP2PSDResponse() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to terminate P2P Service Discovery Phase ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_P2P_TERMINATE_SD_PHASE prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) NULL; ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ ++ do { ++ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) ++ break; ++ ++ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) ++ break; ++ ++ if (u4SetBufferLen < sizeof(PARAM_P2P_TERMINATE_SD_PHASE)) { ++ *pu4SetInfoLen = sizeof(PARAM_P2P_TERMINATE_SD_PHASE); ++ rWlanStatus = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++ ++ prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) pvSetBuffer; ++ ++ if (EQUAL_MAC_ADDR(prP2pTerminateSD->rPeerAddr, aucNullAddr)) { ++ DBGLOG(P2P, TRACE, "Service Discovery Version 2.0\n"); ++/* p2pFuncSetVersionNumOfSD(prAdapter, 2); */ ++ } ++ /* rWlanStatus = p2pFsmRunEventSDAbort(prAdapter); */ ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* end of wlanoidSetP2PTerminateSDPhase() */ ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SEC_CHECK, ++ FALSE, ++ TRUE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ u4SetBufferLen, (PUINT_8) pvSetBuffer, pvSetBuffer, u4SetBufferLen); ++ ++} /* end of wlanoidSetSecCheckRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ /* P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL; */ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen > 256) ++ u4QueryBufferLen = 256; ++ ++ *pu4QueryInfoLen = u4QueryBufferLen; ++ ++#if DBG ++ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); ++#endif ++ kalMemCopy((PUINT_8) (pvQueryBuffer + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer)), ++ prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); ++ ++ return rWlanStatus; ++} /* end of wlanoidGetSecCheckResponse() */ ++#endif ++ ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; ++ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; ++ ++ DEBUGFUNC("wlanoidSetNoaParam"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); ++ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; ++ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; ++ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; ++ ++#if 0 ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); ++#else ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); ++ ++#endif ++ ++} ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; ++ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; ++ ++ DEBUGFUNC("wlanoidSetOppPsParam"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; ++ ++#if 0 ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_OPPPS_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); ++#else ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); ++ ++#endif ++ ++} ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; ++ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("wlanoidSetUApsdParam"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ ++ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; ++ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; ++ ++ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; ++ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; ++ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; ++ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; ++ prPmProfSetupInfo->ucBmpDeliveryAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ prPmProfSetupInfo->ucBmpTriggerAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ ++ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; ++ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; ++ ++#if 0 ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_UAPSD_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); ++#else ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_UAPSD_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); ++ ++#endif ++} ++ ++WLAN_STATUS ++wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++/* PUINT_8 pucOpChnl = (PUINT_8)pvQueryBuffer; */ ++ ++ do { ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ if (u4QueryBufferLen < sizeof(UINT_8)) { ++ *pu4QueryInfoLen = sizeof(UINT_8); ++ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++#if 0 ++ if (!p2pFuncGetCurrentOpChnl(prAdapter, pucOpChnl)) { ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++#else ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++#endif ++ /* ++ *pu4QueryInfoLen = sizeof(UINT_8); ++ rResult = WLAN_STATUS_SUCCESS; ++ */ ++ ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pOpChannel */ ++ ++WLAN_STATUS ++wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++/* PUINT_8 pucVersionNum = (PUINT_8)pvQueryBuffer; */ ++ ++ do { ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ if (u4QueryBufferLen < sizeof(UINT_8)) { ++ *pu4QueryInfoLen = sizeof(UINT_8); ++ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pVersion */ ++ ++WLAN_STATUS ++wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++ UINT_8 ucVersionNum; ++ ++ do { ++ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) { ++ ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) { ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ *pu4SetInfoLen = sizeof(UINT_8); ++ ++ if (u4SetBufferLen < sizeof(UINT_8)) { ++ rResult = WLAN_STATUS_INVALID_LENGTH; ++ break; ++ } ++ ++ ucVersionNum = *((PUINT_8) pvSetBuffer); ++ ++ rResult = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidSetP2pSupplicantVersion */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the WPS mode. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status; ++ UINT_32 u4IsWPSmode = 0; ++ ++ DEBUGFUNC("wlanoidSetP2pWPSmode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (pvSetBuffer) ++ u4IsWPSmode = *(PUINT_32) pvSetBuffer; ++ else ++ u4IsWPSmode = 0; ++ ++ if (u4IsWPSmode) ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 1; ++ else ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 0; ++ ++ status = nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ return status; ++} /* end of wlanoidSetP2pWPSmode() */ ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++WLAN_STATUS ++wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryP2pRssi"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ if (prAdapter->fgIsP2pLinkQualityValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { ++ PARAM_RSSI rRssi; ++ ++ rRssi = (PARAM_RSSI) prAdapter->rP2pLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ ++ ++ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ ++ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); ++ return WLAN_STATUS_SUCCESS; ++ } ++#ifdef LINUX ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, ++ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); ++#else ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++#endif ++} /* wlanoidQueryP2pRssi */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h +new file mode 100644 +index 000000000000..89de18c89c1c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h +@@ -0,0 +1,238 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/CFG_Wifi_File.h#1 ++*/ ++ ++/*! \file CFG_Wifi_File.h ++ \brief Collection of NVRAM structure used for YuSu project ++ ++ In this file we collect all compiler flags and detail the driver behavior if ++ enable/disable such switch or adjust numeric parameters. ++*/ ++ ++/* ++** Log: CFG_Wifi_File.h ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 08 09 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * update NVRAM data structure definition. ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition ++ * follow-up for CMD_5G_PWR_OFFSET_T definition change ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++*/ ++ ++#ifndef _CFG_WIFI_FILE_H ++#define _CFG_WIFI_FILE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++/* duplicated from nic_cmd_event.h to avoid header dependency */ ++typedef struct _TX_PWR_PARAM_T { ++ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ ++ INT_8 acReserved[3]; /* form MT6628 acReserved[0]=cTxPwr2G4Dsss */ ++ INT_8 cTxPwr2G4OFDM_BPSK; ++ INT_8 cTxPwr2G4OFDM_QPSK; ++ INT_8 cTxPwr2G4OFDM_16QAM; ++ INT_8 cTxPwr2G4OFDM_Reserved; ++ INT_8 cTxPwr2G4OFDM_48Mbps; ++ INT_8 cTxPwr2G4OFDM_54Mbps; ++ ++ INT_8 cTxPwr2G4HT20_BPSK; ++ INT_8 cTxPwr2G4HT20_QPSK; ++ INT_8 cTxPwr2G4HT20_16QAM; ++ INT_8 cTxPwr2G4HT20_MCS5; ++ INT_8 cTxPwr2G4HT20_MCS6; ++ INT_8 cTxPwr2G4HT20_MCS7; ++ ++ INT_8 cTxPwr2G4HT40_BPSK; ++ INT_8 cTxPwr2G4HT40_QPSK; ++ INT_8 cTxPwr2G4HT40_16QAM; ++ INT_8 cTxPwr2G4HT40_MCS5; ++ INT_8 cTxPwr2G4HT40_MCS6; ++ INT_8 cTxPwr2G4HT40_MCS7; ++ ++ INT_8 cTxPwr5GOFDM_BPSK; ++ INT_8 cTxPwr5GOFDM_QPSK; ++ INT_8 cTxPwr5GOFDM_16QAM; ++ INT_8 cTxPwr5GOFDM_Reserved; ++ INT_8 cTxPwr5GOFDM_48Mbps; ++ INT_8 cTxPwr5GOFDM_54Mbps; ++ ++ INT_8 cTxPwr5GHT20_BPSK; ++ INT_8 cTxPwr5GHT20_QPSK; ++ INT_8 cTxPwr5GHT20_16QAM; ++ INT_8 cTxPwr5GHT20_MCS5; ++ INT_8 cTxPwr5GHT20_MCS6; ++ INT_8 cTxPwr5GHT20_MCS7; ++ ++ INT_8 cTxPwr5GHT40_BPSK; ++ INT_8 cTxPwr5GHT40_QPSK; ++ INT_8 cTxPwr5GHT40_16QAM; ++ INT_8 cTxPwr5GHT40_MCS5; ++ INT_8 cTxPwr5GHT40_MCS6; ++ INT_8 cTxPwr5GHT40_MCS7; ++} TX_PWR_PARAM_T, *P_TX_PWR_PARAM_T; ++ ++typedef struct _PWR_5G_OFFSET_T { ++ INT_8 cOffsetBand0; /* 4.915-4.980G */ ++ INT_8 cOffsetBand1; /* 5.000-5.080G */ ++ INT_8 cOffsetBand2; /* 5.160-5.180G */ ++ INT_8 cOffsetBand3; /* 5.200-5.280G */ ++ INT_8 cOffsetBand4; /* 5.300-5.340G */ ++ INT_8 cOffsetBand5; /* 5.500-5.580G */ ++ INT_8 cOffsetBand6; /* 5.600-5.680G */ ++ INT_8 cOffsetBand7; /* 5.700-5.825G */ ++} PWR_5G_OFFSET_T, *P_PWR_5G_OFFSET_T; ++ ++typedef struct _PWR_PARAM_T { ++ UINT_32 au4Data[28]; ++ UINT_32 u4RefValue1; ++ UINT_32 u4RefValue2; ++} PWR_PARAM_T, *P_PWR_PARAM_T; ++ ++typedef struct _MT6620_CFG_PARAM_STRUCT { ++ /* 256 bytes of MP data */ ++ UINT_16 u2Part1OwnVersion; ++ UINT_16 u2Part1PeerVersion; ++ UINT_8 aucMacAddress[6]; ++ UINT_8 aucCountryCode[2]; ++ TX_PWR_PARAM_T rTxPwr; ++ UINT_8 aucEFUSE[144]; ++ UINT_8 ucTxPwrValid; ++ UINT_8 ucSupport5GBand; ++ UINT_8 fg2G4BandEdgePwrUsed; ++ INT_8 cBandEdgeMaxPwrCCK; ++ INT_8 cBandEdgeMaxPwrOFDM20; ++ INT_8 cBandEdgeMaxPwrOFDM40; ++ ++ UINT_8 ucRegChannelListMap; ++ UINT_8 ucRegChannelListIndex; ++ UINT_8 aucRegSubbandInfo[36]; ++ ++ UINT_8 aucReserved2[256 - 240]; ++ ++ /* 256 bytes of function data */ ++ UINT_16 u2Part2OwnVersion; ++ UINT_16 u2Part2PeerVersion; ++ UINT_8 uc2G4BwFixed20M; ++ UINT_8 uc5GBwFixed20M; ++ UINT_8 ucEnable5GBand; ++ UINT_8 aucPreTailReserved; ++ UINT_8 uc2GRssiCompensation; ++ UINT_8 uc5GRssiCompensation; ++ UINT_8 fgRssiCompensationValidbit; ++ UINT_8 ucRxAntennanumber; ++ UINT_8 aucTailReserved[256 - 12]; ++} MT6620_CFG_PARAM_STRUCT, *P_MT6620_CFG_PARAM_STRUCT, WIFI_CFG_PARAM_STRUCT, *P_WIFI_CFG_PARAM_STRUCT; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifndef DATA_STRUCT_INSPECTING_ASSERT ++#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ ++{ \ ++ switch (0) {case 0: case (expr): default:; } \ ++} ++#endif ++ ++#define CFG_FILE_WIFI_REC_SIZE sizeof(WIFI_CFG_PARAM_STRUCT) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* We don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this to guarantee the same member order in different structures ++ * to simply handling effort in some functions. ++ */ ++static inline VOID nvramOffsetCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion) == 256); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(WIFI_CFG_PARAM_STRUCT) == 512); ++ ++ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) & 0x0001) == 0); ++ ++ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) & 0x0001) == 0); ++} ++#endif ++ ++#endif /* _CFG_WIFI_FILE_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h +new file mode 100644 +index 000000000000..a52053d5752d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h +@@ -0,0 +1,1628 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/config.h#2 ++*/ ++ ++/*! \file "config.h" ++ \brief This file includes the various configurable parameters for customers ++ ++ This file ncludes the configurable parameters except the parameters indicate the turning-on/off of some features ++*/ ++ ++/* ++** Log: config.h ++ * ++ * 07 13 2012 cp.wu ++ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for ++ * termination after SDIO error has happened ++ * [driver domain] add force reset by host-to-device interrupt mechanism ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 06 05 2012 tsaiyuan.hsu ++ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" ++ * resolve build waring for "WNM_UNIT_TEST not defined".. ++ * ++ * 06 04 2012 cp.wu ++ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development ++ * discussed with WH, privacy bit in associate response is not necessary to be checked, ++ * and identified as association failure when mismatching with beacon/probe response ++ * ++ * 05 11 2012 cp.wu ++ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience ++ * show MAC address & source while initiliazation ++ * ++ * 04 20 2012 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * correct macro ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ * ++ * 03 29 2012 eason.tsai ++ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define ++ * add conditional define. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Enable CFG80211 Support. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 11 23 2011 cp.wu ++ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection ++ * add compile option to disable beacon content change detection. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 10 28 2011 cp.wu ++ * [MT6620 Wi-Fi][Win32 Driver] Enable 5GHz support as default ++ * enable 5GHz as default for DaVinci trunk and V2.1 driver release . ++ * ++ * 10 18 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * surpress compiler warning for MT6628 build ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * enable divided firmware downloading. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 10 03 2011 cp.wu ++ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware downloading aggregated path. ++ * ++ * 09 28 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * enlarge window size only by 4. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. ++ * ++ * 08 12 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. ++ * ++ * 08 09 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS definition for MT6620. ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Refine compile flag. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Add wifi direct connection enhancement method I, II & VI. ++ * ++ * 06 24 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * increase RX buffer number to have a 2:1 ping-pong ratio ++ * ++ * 06 23 2011 eddie.chen ++ * [WCXRP00000810] [MT5931][DRV/FW] Adjust TxRx Buffer number and Rx buffer size ++ * 1. Different TX RX buffer ++ * 2. Enlarge RX buffer and increase the number 8->11 ++ * 3. Separate the WINSZIE and RX buffer number ++ * 4. Fix RX maximum size in MAC ++ * ++ * 06 20 2011 terry.wu ++ * NULL ++ * Add BoW Rate Limitation. ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * . ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * Add BoW 11N support. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Add compile flag for persistent group support. ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Limit AIS to fixed channel same with BOW ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * Enable RX STBC capability ++ * ++ * 04 11 2011 george.huang ++ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF ++ * . ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 04 08 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. correction: RX aggregation is not limited to SDIO but for all host interface options ++ * 2. add forward declarations for DBG-only symbols ++ * ++ * 04 06 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port ++ * 2. update perm_addr as well for MAC address ++ * 3. not calling check_mem_region() anymore for eHPI ++ * 4. correct MSC_CS macro for 0-based notation ++ * ++ * 04 01 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface ++ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR ++ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with ++ * user space process for RESET_START and RESET_END events ++ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 18 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the Anti_piracy check at driver . ++ * ++ * 03 17 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * enable roaming feature. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one ++ * to reduce physically continuous memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 03 01 2011 george.huang ++ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames ++ * Fix compile issue ++ * ++ * 02 25 2011 george.huang ++ * [WCXRP00000497] [MT6620 Wi-Fi][FW] Change default UAPSD AC assignment ++ * Assign all AC default to be U-APSD enabled. ++ * ++ * 02 14 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * Let the privacy check at hotspot mode default enable. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 02 08 2011 cp.wu ++ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number ++ * change version number to v1.2.0.0 for preparing v1.2 software package release. ++ * ++ * 02 01 2011 yarco.yang ++ * [WCXRP00000417] [MT6620 Driver] Change CFG_HANDLE_IST_IN_SDIO_CALLBACK from 1 to 0 for Interoperability ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 19 2011 wh.su ++ * [WCXRP00000370] [MT6620 Wi-Fi][Driver] Disable Rx RDG for workaround pre-N ccmp issue ++ * Not announce support Rx RDG for wokaround pre-N ccmp construct AAD issue.. ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * Add Stress test ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause ++ * hardware header translation needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW only for Linux. ++ * ++ * 01 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Enable BOW and 4 physical links. ++ * ++ * 01 08 2011 yuche.tsai ++ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, ++ * but the SSID length is still invalid. ++ * Modify CFG_SLT_SUPPORT default value. ++ * ++ * 01 08 2011 yuche.tsai ++ * [WCXRP00000341] [MT6620][SLT] Create Branch for SLT SW. ++ * Update configure flag. ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 15 2010 yuche.tsai ++ * NULL ++ * Update SLT Descriptor number configure in driver. ++ * ++ * 12 13 2010 chinglan.wang ++ * NULL ++ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. ++ * ++ * 11 23 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB ++ * Enable PM function by default ++ * ++ * 11 15 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * use config.mk WAPI config define. ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * use the config.mk define. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add option for enable/disable TX PWR gain adjustment (default: off) ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function ++ * enable the WAPI compiling flag as default ++ * ++ * 10 19 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android ++ * Add a define CFG_TEST_ANDROID_DIRECT_GO compiling flag ++ * ++ * 10 08 2010 cm.chang ++ * NULL ++ * Remove unused compiling flags (TX_RDG and TX_SGI) ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 05 2010 yarco.yang ++ * [WCXRP00000082] [MT6620 Wi-Fi][Driver]High throughput performance tuning ++ * Change CFG_IST_LOOP_COUNT from 2 to 1 to reduce unnecessary SDIO bus access ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE ++ * ++ * 09 20 2010 cm.chang ++ * NULL ++ * Disable RX STBC by BB HEC based on MT6620E1_PHY_BUG v05.docx ++ * ++ * 09 17 2010 chinglan.wang ++ * NULL ++ * Add performance test option ++ * ++ * 09 10 2010 chinglan.wang ++ * NULL ++ * Modify for Software Migration Phase 2.10 for E2 FPGA ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a CFG for max common IE buffer size. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * restore configuration as before. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 chinglan.wang ++ * NULL ++ * Enable the MT6620_FPGA_BWCS value. ++ * ++ * 08 30 2010 chinglan.wang ++ * NULL ++ * Disable the FW encryption. ++ * ++ * 08 27 2010 chinglan.wang ++ * NULL ++ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add AT GO test configure mode under WinXP. ++ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add option for enabling AIS 5GHz scan ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cp.wu ++ * NULL ++ * 1) initialize variable for enabling short premable/short time slot. ++ * 2) add compile option for disabling online scan ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Disable BOW Test. ++ * ++ * 08 23 2010 jeffrey.chang ++ * NULL ++ * fix config.h typo ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 21 2010 jeffrey.chang ++ * NULL ++ * 1) add sdio two setting ++ * 2) bug fix of sdio glue ++ * ++ * 08 09 2010 wh.su ++ * NULL ++ * let the firmware download default enabled. ++ * ++ * 08 07 2010 wh.su ++ * NULL ++ * adding the privacy related code for P2P network ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Add a configure flag for P2P unitest. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) enable Ad-Hoc ++ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Add for SLT support. ++ * ++ * 07 16 2010 cp.wu ++ * ++ * remove work-around in case SCN is not available. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor ++ * underflow under concurrent network operation ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * for first connection, if connecting failed do not enter into scan state. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add SCN compilation option. ++ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * set default compiling flag for security disable. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add config option for cfg80211. ++ * ++ * 05 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * set ATIMwindow default value to zero. ++ * ++ * 05 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add option for FPGA_BWCS & FPGA_V5 ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) enable CMD/EVENT ver 0.9 definition. ++ * 2) abandon use of ENUM_MEDIA_STATE ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add CFG_STARTUP_DEBUG for debugging starting up issue. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change firmware name to WIFI_RAM_CODE. ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * disable bt-over-wifi configuration, turn it on after firmware finished implementation ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * re-enable power management ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * enable TCP/IP checksum offloading by default. ++ * ++ * 04 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * set CFG_ENABLE_FULL_PM to 1 as default to ++ * 1) acquire own before hardware access ++ * 2) set own back after hardware access ++ * ++ * 04 15 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * change firmware name ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver ++ * disable RX-enhanced response temporally, it seems the CQ is not resolved yet. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver ++ * re-enable RX enhanced mode as WPD00003827 is resolved. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * turn off RX_ENHANCE mode by default. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) eliminate unused definitions ++ * * 2) ready bit will be polled for limited iteration ++ * ++ * 04 02 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * firmware download: Linux uses different firmware path ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use WIFI_TCM_ALWAYS_ON as firmware image ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * firmware download load address & start address are now configured from config.h ++ * * due to the different configurations on FPGA and ASIC ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add options for full PM support. ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * turn on FW-DOWNLOAD as default for release. ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * build up basic data structure and definitions to support BT-over-WiFi ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 05 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * change CFG_NUM_OF_QM_RX_PKT_NUM to 120 ++ * ++ * 03 04 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * . ++ * ++ * 03 04 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * increase RX buffer number to avoid RX buffer starvation. ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Changed the number of STA_RECs to 20 ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. add logic for firmware download ++ * * 2. firmware image filename and start/load address are now retrieved from registry ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * and result is retrieved by get ATInfo instead ++ * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-16 22:12:28 GMT mtk02752 ++** enable interrupt enhanced response, TX/RX Aggregation as default ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:38:43 GMT mtk02752 ++** eliminate compile options which are obsolete or for emulation purpose ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 13:56:26 GMT MTK02468 ++** Added RX buffer reordering configurations ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-12-04 12:09:09 GMT mtk02752 ++** once enhanced intr/rx response is taken, RX must be access in aggregated basis ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 17:54:50 GMT mtk02752 ++** correct a typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:47 GMT mtk01084 ++** add defines ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:33:37 GMT mtk02752 ++** add coalescing buffer definition for SD1_SD3_DATAPATH_INTEGRATION ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 20:32:40 GMT mtk02752 ++** add CFG_TX_MAX_PKT_NUM for limiting queued TX packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 13:34:44 GMT mtk02752 ++** add SD1_SD3_DATAPATH_INTEGRATION define for source control ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 13:54:11 GMT mtk01084 ++** enable INT enhance mode by default ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-30 18:17:14 GMT mtk01084 ++** add new define ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-10-29 19:47:36 GMT mtk01084 ++** not use HIF loopback mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-13 21:58:33 GMT mtk01084 ++** update for new macro define ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-09-09 17:26:08 GMT mtk01084 ++** add CFG_TEST_WITH_MT5921 ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:02:30 GMT mtk01426 ++** Update CFG_RX_COALESCING_BUFFER_SIZE ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-21 09:35:51 GMT mtk01461 ++** Add CFG_TX_DBG_MGT_BUF to debug MGMT Buffer depth ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:52:21 GMT mtk01426 ++** Add OOB_DATA_PRE_FIXED_LEN define ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-08 16:51:08 GMT mtk01084 ++** update for FW download part ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:33:37 GMT mtk01461 ++** Add SW pre test flag CFG_HIF_LOOPBACK_PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 00:29:18 GMT mtk01461 ++** Fix CFG_COALESCING_BUFFER_SIZE if enable the CFG_TX_FRAGMENT ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-18 20:58:34 GMT mtk01426 ++** Add CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-17 20:17:36 GMT mtk01426 ++** Add CMD/Response related configure ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:21 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:21 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _CONFIG_H ++#define _CONFIG_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#ifdef MT6620 ++#undef MT6620 ++#endif ++ ++#ifndef MT6628 ++#define MT6628 ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* 2 Flags for OS capability */ ++ ++#define MTK_WCN_SINGLE_MODULE 0 /* 1: without WMT */ ++ ++#ifdef LINUX ++#ifdef CONFIG_X86 ++#define MTK_WCN_HIF_SDIO 0 ++#else ++#define MTK_WCN_HIF_SDIO 0 /* samp */ ++#endif ++#else ++#define MTK_WCN_HIF_SDIO 0 ++#endif ++ ++#if (CFG_SUPPORT_AEE == 1) ++#define CFG_ENABLE_AEE_MSG 1 ++#else ++#define CFG_ENABLE_AEE_MSG 0 ++#endif ++ ++#if CFG_ENABLE_AEE_MSG ++#include ++#endif ++ ++/* 2 Flags for Driver Features */ ++#define CFG_TX_FRAGMENT 1 /*!< 1: Enable TX fragmentation ++ 0: Disable */ ++#define CFG_SUPPORT_PERFORMANCE_TEST 0 /*Only for performance Test */ ++ ++#define CFG_COUNTRY_CODE NULL /* "US" */ ++ ++#ifndef LINUX ++#define CFG_FW_FILENAME L"WIFI_RAM_CODE" ++#define CFG_FW_FILENAME_E6 L"WIFI_RAM_CODE_E6" ++#else ++#define CFG_FW_FILENAME "WIFI_RAM_CODE" ++#endif ++#ifndef LINUX ++#define CFG_SUPPORT_CFG_FILE 0 ++#else ++#define CFG_SUPPORT_CFG_FILE 1 ++#endif ++ ++#define CFG_SUPPORT_CE_FCC_TXPWR_LIMIT 0 /* Support CE FCC Tx Power limit */ ++ ++#define CFG_SUPPORT_802_11D 1 /*!< 1(default): Enable 802.11d ++ 0: Disable */ ++ ++#define CFG_SUPPORT_RRM 0 /* Radio Reasource Measurement (802.11k) */ ++#define CFG_SUPPORT_DFS 1 /* DFS (802.11h) */ ++ ++#if (CFG_SUPPORT_DFS == 1) /* Add by Enlai */ ++#define CFG_SUPPORT_QUIET 1 /* Quiet (802.11h) */ ++#define CFG_SUPPORT_SPEC_MGMT 1 /* Spectrum Management (802.11h): TPC and DFS */ ++#else ++#define CFG_SUPPORT_QUIET 0 /* Quiet (802.11h) */ ++#define CFG_SUPPORT_SPEC_MGMT 0 /* Spectrum Management (802.11h): TPC and DFS */ ++#endif ++ ++#define CFG_SUPPORT_RX_RDG 0 /* 11n feature. RX RDG capability */ ++#define CFG_SUPPORT_MFB 0 /* 802.11n MCS Feedback responder */ ++#define CFG_SUPPORT_RX_STBC 1 /* 802.11n RX STBC (1SS) */ ++#define CFG_SUPPORT_RX_SGI 1 /* 802.11n RX short GI for both 20M and 40M BW */ ++#define CFG_SUPPORT_RX_HT_GF 1 /* 802.11n RX HT green-field capability */ ++ ++#define CFG_SUPPORT_ROAMING_ENC 0 /* enahnced roaming */ ++ ++#define CFG_SUPPORT_TDLS 1 /* IEEE802.11z TDLS */ ++#define CFG_SUPPORT_TDLS_DBG 0 /* TDLS debug */ ++#define CFG_SUPPORT_STATISTICS 1 ++#define CFG_SUPPORT_DBG_POWERMODE 1 /* for debugging power always active mode */ ++ ++#define CFG_SUPPORT_GSCN 1 ++ ++#define CFG_SUPPORT_TXR_ENC 0 /* enhanced tx rate switch */ ++ ++#define CFG_SUPPORT_PERSIST_NETDEV 0 /* create NETDEV when system bootup */ ++ ++#define CFG_FORCE_USE_20BW 1 ++/*------------------------------------------------------------------------------ ++ * SLT Option ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SLT_SUPPORT 0 ++ ++#define MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE 0 ++ ++#if defined(MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE) ++#define CFG_AUTO_CHANNEL_SEL_SUPPORT 1 ++#else ++#define CFG_AUTO_CHANNEL_SEL_SUPPORT 0 ++#endif ++ ++#ifdef NDIS60_MINIPORT ++#define CFG_NATIVE_802_11 1 ++ ++#define CFG_TX_MAX_PKT_SIZE 2304 ++#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 /* !< 1: Enable TCP/IP header checksum offload ++ 0: Disable */ ++#define CFG_TCP_IP_CHKSUM_OFFLOAD 0 ++#define CFG_WHQL_DOT11_STATISTICS 1 ++#define CFG_WHQL_ADD_REMOVE_KEY 1 ++#define CFG_WHQL_CUSTOM_IE 1 ++#define CFG_WHQL_SAFE_MODE_ENABLED 1 ++ ++#else ++#define CFG_TCP_IP_CHKSUM_OFFLOAD 1 /* !< 1: Enable TCP/IP header checksum offload ++ 0: Disable */ ++#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 ++#define CFG_TX_MAX_PKT_SIZE 1600 ++#define CFG_NATIVE_802_11 0 ++#endif ++ ++/* 2 Flags for Driver Parameters */ ++/*------------------------------------------------------------------------------ ++ * Flags for EHPI Interface in Colibri Platform ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_EHPI_FASTER_BUS_TIMING 0 /*!< 1: Do workaround for faster bus timing ++ 0(default): Disable */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags for HIFSYS Interface ++ *------------------------------------------------------------------------------ ++ */ ++#ifdef _lint ++#define _HIF_SDIO 0 /* samp */ ++#endif ++ ++#define CFG_SDIO_INTR_ENHANCE 1 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode ++ 0: Disable */ ++#define CFG_SDIO_RX_ENHANCE 0 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode ++ 0: Disable */ ++#define CFG_SDIO_TX_AGG 1 /*!< 1: Enable SDIO TX enhance ++ mode(Multiple frames in single BLOCK CMD) ++ 0(default): Disable */ ++ ++#define CFG_SDIO_RX_AGG 1 /*!< 1: Enable SDIO RX enhance ++ mode(Multiple frames in single BLOCK CMD) ++ 0(default): Disable */ ++ ++#if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0) ++#error "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1" ++#elif (CFG_SDIO_INTR_ENHANCE == 1 || CFG_SDIO_RX_ENHANCE == 1) && (CFG_SDIO_RX_AGG == 0) ++#error "CFG_SDIO_RX_AGG should be 1 once CFG_SDIO_INTR_ENHANCE and/or CFG_SDIO_RX_ENHANCE equals to 1" ++#endif ++ ++#define CFG_SDIO_MAX_RX_AGG_NUM 0 /*!< 1: Setting the maximum RX aggregation number ++ 0(default): no limited */ ++ ++#ifdef WINDOWS_CE ++#define CFG_SDIO_PATHRU_MODE 1 /*!< 1: Support pass through (PATHRU) mode ++ 0: Disable */ ++#else ++#define CFG_SDIO_PATHRU_MODE 0 /*!< 0: Always disable if WINDOWS_CE is not defined */ ++#endif ++ ++#define CFG_MAX_RX_ENHANCE_LOOP_COUNT 3 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Integration ++ *------------------------------------------------------------------------------ ++ */ ++#if defined(MT6620) ++#define MT6620_FPGA_BWCS 0 ++#define MT6620_FPGA_V5 0 ++ ++#if (MT6620_FPGA_BWCS == 1) && (MT6620_FPGA_V5 == 1) ++#error ++#endif ++ ++#if (MTK_WCN_HIF_SDIO == 1) ++#define CFG_MULTI_ECOVER_SUPPORT 1 ++#elif !defined(LINUX) ++#define CFG_MULTI_ECOVER_SUPPORT 1 ++#else ++#define CFG_MULTI_ECOVER_SUPPORT 0 ++#endif ++ ++#define CFG_ENABLE_CAL_LOG 0 ++#define CFG_REPORT_RFBB_VERSION 0 ++ ++#elif defined(MT6628) ++ ++#define CFG_MULTI_ECOVER_SUPPORT 0 ++ ++#define CFG_ENABLE_CAL_LOG 1 ++#define CFG_REPORT_RFBB_VERSION 1 ++ ++#endif ++ ++#define CFG_CHIP_RESET_SUPPORT 1 ++ ++#if defined(MT6628) ++#define CFG_EMBED_FIRMWARE_BUILD_DATE_CODE 1 ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * Flags for workaround ++ *------------------------------------------------------------------------------ ++ */ ++#if defined(MT6620) && (MT6620_FPGA_BWCS == 0) && (MT6620_FPGA_V5 == 0) ++#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 ++#else ++#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 ++#endif ++ ++/* SPM issue: suspend current is higher than deep idle */ ++#define CFG_SPM_WORKAROUND_FOR_HOTSPOT 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags for driver version ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_DRV_OWN_VERSION \ ++ ((UINT_16)((NIC_DRIVER_MAJOR_VERSION << 8) | (NIC_DRIVER_MINOR_VERSION))) ++#define CFG_DRV_PEER_VERSION ((UINT_16)0x0000) ++ ++/*------------------------------------------------------------------------------ ++ * Flags for TX path which are OS dependent ++ *------------------------------------------------------------------------------ ++ */ ++/*! NOTE(Kevin): If the Network buffer is non-scatter-gather like structure(without ++ * NETIF_F_FRAGLIST in LINUX), then we can set CFG_TX_BUFFER_IS_SCATTER_LIST to "0" ++ * for zero copy TX packets. ++ * For scatter-gather like structure, we set "1", driver will do copy frame to ++ * internal coalescing buffer before write it to FIFO. ++ */ ++#if defined(LINUX) ++#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 /*!< 1: Do frame copy before write to TX FIFO. ++ Used when Network buffer is scatter-gather. ++ 0(default): Do not copy frame */ ++#else /* WINDOWS/WINCE */ ++#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 ++#endif /* LINUX */ ++ ++#if CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST ++#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE * NIC_TX_BUFF_SUM) ++#else ++#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE) ++#endif /* CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for TX path ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*! Maximum number of SW TX packet queue */ ++#define CFG_TX_MAX_PKT_NUM 512 /* 256 must >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * 2; ++ or wmm will fail when queue is full */ ++ ++/*! Maximum number of SW TX CMD packet buffer */ ++#define CFG_TX_MAX_CMD_PKT_NUM 32 ++ ++/*! Maximum number of associated STAs */ ++#define CFG_NUM_OF_STA_RECORD 20 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for RX path ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*! Max. descriptor number - sync. with firmware */ ++#if CFG_SLT_SUPPORT ++#define CFG_NUM_OF_RX0_HIF_DESC 42 ++#else ++#define CFG_NUM_OF_RX0_HIF_DESC 16 ++#endif ++#define CFG_NUM_OF_RX1_HIF_DESC 2 ++ ++/*! Max. buffer hold by QM */ ++#define CFG_NUM_OF_QM_RX_PKT_NUM 120 ++ ++/*! Maximum number of SW RX packet buffer */ ++#define CFG_RX_MAX_PKT_NUM ((CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC) * 3 \ ++ + CFG_NUM_OF_QM_RX_PKT_NUM) ++ ++#define CFG_RX_REORDER_Q_THRESHOLD 8 ++ ++#ifndef LINUX ++#define CFG_RX_RETAINED_PKT_THRESHOLD \ ++ (CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC + CFG_NUM_OF_QM_RX_PKT_NUM) ++#else ++#define CFG_RX_RETAINED_PKT_THRESHOLD 0 ++#endif ++ ++/*! Maximum RX packet size, if exceed this value, drop incoming packet */ ++/* 7.2.3 Maganement frames */ ++#define CFG_RX_MAX_PKT_SIZE (28 + 2312 + 12 /*HIF_RX_HEADER_T*/) /* TODO: it should be ++ 4096 under emulation mode */ ++ ++/*! Minimum RX packet size, if lower than this value, drop incoming packet */ ++#define CFG_RX_MIN_PKT_SIZE 10 /*!< 802.11 Control Frame is 10 bytes */ ++ ++#if CFG_SDIO_RX_AGG ++ /* extra size for CS_STATUS and enhanced response */ ++#define CFG_RX_COALESCING_BUFFER_SIZE ((CFG_NUM_OF_RX0_HIF_DESC + 1) \ ++ * CFG_RX_MAX_PKT_SIZE) ++#else ++#define CFG_RX_COALESCING_BUFFER_SIZE (CFG_RX_MAX_PKT_SIZE) ++#endif ++ ++/*! RX BA capability */ ++#define CFG_NUM_OF_RX_BA_AGREEMENTS 8 ++#define CFG_RX_BA_MAX_WINSIZE 16 ++#define CFG_RX_BA_INC_SIZE 4 ++#define CFG_RX_MAX_BA_TID_NUM 8 ++#define CFG_RX_REORDERING_ENABLED 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for CMD/RESPONSE ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_RESPONSE_POLLING_TIMEOUT 512 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Protocol Stack ++ *------------------------------------------------------------------------------ ++ */ ++/*! Maximum number of BSS in the SCAN list */ ++#define CFG_MAX_NUM_BSS_LIST 64 ++ ++#define CFG_MAX_COMMON_IE_BUF_LEN ((1500 * CFG_MAX_NUM_BSS_LIST) / 3) ++ ++/*! Maximum size of Header buffer of each SCAN record */ ++#define CFG_RAW_BUFFER_SIZE 1024 ++ ++/*! Maximum size of IE buffer of each SCAN record */ ++#define CFG_IE_BUFFER_SIZE 512 ++ ++/*! Maximum number of STA records */ ++#define CFG_MAX_NUM_STA_RECORD 32 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Power management ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_FULL_PM 1 ++#define CFG_ENABLE_WAKEUP_ON_LAN 0 ++#if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || \ ++ defined(CONFIG_ARCH_MT6753) || defined(CONFIG_ARCH_MT6580) ++#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 1 /* debug which packet wake up host */ ++#else ++#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 0 /* debug which packet wake up host */ ++#endif ++#define CFG_INIT_POWER_SAVE_PROF ENUM_PSP_FAST_SWITCH ++ ++#define CFG_INIT_ENABLE_PATTERN_FILTER_ARP 0 ++ ++#define CFG_INIT_UAPSD_AC_BMP 0 /* (BIT(3) | BIT(2) | BIT(1) | BIT(0)) */ ++ ++/* #define CFG_SUPPORT_WAPI 0 */ ++#define CFG_SUPPORT_WPS 1 ++#define CFG_SUPPORT_WPS2 1 ++ ++/*------------------------------------------------------------------------------ ++ * 802.11i RSN Pre-authentication PMKID cahce maximun number ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_MAX_PMKID_CACHE 16 /*!< max number of PMKID cache ++ 16(default) : The Max PMKID cache */ ++/*------------------------------------------------------------------------------ ++ * Auto Channel Selection Maximun Channel Number ++ *------------------------------------------------------------------------------ ++ */ ++ ++#define MAX_AUTO_CHAL_NUM 23 /* Ch1~Ch14,Ch36,Ch40,Ch44, ++ Ch48,Ch149,Ch153,Ch157,Ch161 */ ++/*------------------------------------------------------------------------------ ++ * FAST SCAN ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_FAST_SCAN 0 ++#define CFG_CN_SUPPORT_CLASS121 0 /* Add Class 121, 5470-5725MHz, support for China domain */ ++#if CFG_ENABLE_FAST_SCAN ++ #define CFG_FAST_SCAN_DWELL_TIME 40 ++ #define CFG_FAST_SCAN_REG_DOMAIN_DEF_IDX 10 ++#endif ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Ad-Hoc ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_INIT_ADHOC_FREQ (2462000) ++#define CFG_INIT_ADHOC_MODE AD_HOC_MODE_MIXED_11BG ++#define CFG_INIT_ADHOC_BEACON_INTERVAL (100) ++#define CFG_INIT_ADHOC_ATIM_WINDOW (0) ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Maximum Scan SSID number ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SCAN_SSID_MAX_NUM (4) ++#define CFG_SCAN_SSID_MATCH_MAX_NUM (16) ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Load Setup Default ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags for enable 802.11A Band setting ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Interrupt Process ++ *------------------------------------------------------------------------------ ++ */ ++#if defined(_HIF_SDIO) && defined(WINDOWS_CE) ++#define CFG_IST_LOOP_COUNT 8 ++#else ++#define CFG_IST_LOOP_COUNT 8 ++#endif /* _HIF_SDIO */ ++ ++#define CFG_INT_WRITE_CLEAR 0 ++ ++#if defined(LINUX) ++#define CFG_DBG_GPIO_PINS 0 /* if 1, use MT6516 GPIO pin to log TX behavior */ ++#endif ++ ++/* 2 Flags for Driver Debug Options */ ++/*------------------------------------------------------------------------------ ++ * Flags of TX Debug Option. NOTE(Kevin): Confirm with SA before modifying following flags. ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_DBG_MGT_BUF 1 /*!< 1: Debug statistics usage of MGMT Buffer ++ 0: Disable */ ++ ++#define CFG_HIF_STATISTICS 0 ++ ++#define CFG_HIF_RX_STARVATION_WARNING 0 ++ ++#define CFG_STARTUP_DEBUG 0 ++ ++#define CFG_RX_PKTS_DUMP 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Firmware Download Option. ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_FW_DOWNLOAD 1 ++ ++#define CFG_ENABLE_FW_DOWNLOAD_ACK 1 ++#define CFG_ENABLE_FW_ENCRYPTION 1 ++ ++#if defined(MT6628) ++#define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION 0 ++#define CFG_ENABLE_FW_DIVIDED_DOWNLOAD 1 ++#endif ++ ++#if defined(MT6620) ++#if MT6620_FPGA_BWCS ++#define CFG_FW_LOAD_ADDRESS 0x10014000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 0 ++#define CFG_FW_START_ADDRESS 0x10014001 ++#elif MT6620_FPGA_V5 ++#define CFG_FW_LOAD_ADDRESS 0x10008000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 0 ++#define CFG_FW_START_ADDRESS 0x10008001 ++#else ++#define CFG_FW_LOAD_ADDRESS 0x10008000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 0 ++#define CFG_FW_START_ADDRESS 0x10008001 ++#endif ++#elif defined(MT6628) ++#define CFG_FW_LOAD_ADDRESS 0x00060000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 1 ++#define CFG_FW_START_ADDRESS 0x00060000 ++#define CFG_START_ADDRESS_IS_1ST_SECTION_ADDR 1 ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Bluetooth-over-WiFi (BT 3.0 + HS) support ++ *------------------------------------------------------------------------------ ++ */ ++ ++#ifdef LINUX ++#ifdef CONFIG_X86 ++#define CFG_ENABLE_BT_OVER_WIFI 0 ++#else ++#define CFG_ENABLE_BT_OVER_WIFI 1 ++#endif ++#else ++#define CFG_ENABLE_BT_OVER_WIFI 0 ++#endif ++ ++#define CFG_BOW_SEPARATE_DATA_PATH 1 ++ ++#define CFG_BOW_PHYSICAL_LINK_NUM 4 ++ ++#define CFG_BOW_TEST 0 ++ ++#define CFG_BOW_LIMIT_AIS_CHNL 1 ++ ++#define CFG_BOW_SUPPORT_11N 0 ++ ++#define CFG_BOW_RATE_LIMITATION 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Wi-Fi Direct support ++ *------------------------------------------------------------------------------ ++ */ ++#ifdef LINUX ++#ifdef CONFIG_X86 ++#define CFG_ENABLE_WIFI_DIRECT 0 ++#define CFG_SUPPORT_802_11W 0 ++#else ++#define CFG_ENABLE_WIFI_DIRECT 1 ++#define CFG_SUPPORT_802_11W 0 /*!< 0(default): Disable 802.11W */ ++#endif ++#else ++#define CFG_ENABLE_WIFI_DIRECT 0 ++#define CFG_SUPPORT_802_11W 0 /* Not support at WinXP */ ++#endif ++ ++#define CFG_SUPPORT_PERSISTENT_GROUP 0 ++ ++#define CFG_TEST_WIFI_DIRECT_GO 0 ++ ++#define CFG_TEST_ANDROID_DIRECT_GO 0 ++ ++#define CFG_UNITEST_P2P 0 ++ ++/* ++ * Enable cfg80211 option after Android 2.2(Froyo) is suggested, ++ * cfg80211 on linux 2.6.29 is not mature yet ++ */ ++#define CFG_ENABLE_WIFI_DIRECT_CFG_80211 1 ++ ++#define CFG_SUPPORT_HOTSPOT_OPTIMIZATION 1 ++#define CFG_HOTSPOT_OPTIMIZATION_BEACON_INTERVAL 300 ++#define CFG_HOTSPOT_OPTIMIZATION_DTIM 1 ++ ++/*------------------------------------------------------------------------------ ++ * Configuration Flags (Linux Only) ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_EXT_CONFIG 0 ++ ++/*------------------------------------------------------------------------------ ++ * Statistics Buffering Mechanism ++ *------------------------------------------------------------------------------ ++ */ ++#if CFG_SUPPORT_PERFORMANCE_TEST ++#define CFG_ENABLE_STATISTICS_BUFFERING 1 ++#else ++#define CFG_ENABLE_STATISTICS_BUFFERING 0 ++#endif ++#define CFG_STATISTICS_VALID_CYCLE 2000 ++#define CFG_LINK_QUALITY_VALID_PERIOD 5000 ++ ++/*------------------------------------------------------------------------------ ++ * Migration Option ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_ADHOC 0 ++#define CFG_SUPPORT_AAA 1 ++ ++#define CFG_SUPPORT_BCM 0 ++#define CFG_SUPPORT_BCM_BWCS 0 ++#define CFG_SUPPORT_BCM_BWCS_DEBUG 0 ++ ++#define CFG_SUPPORT_RDD_TEST_MODE 0 ++ ++#define CFG_SUPPORT_PWR_MGT 1 ++ ++#define CFG_RSN_MIGRATION 1 ++ ++#define CFG_PRIVACY_MIGRATION 1 ++ ++#define CFG_ENABLE_HOTSPOT_PRIVACY_CHECK 1 ++ ++#define CFG_MGMT_FRAME_HANDLING 1 ++ ++#define CFG_MGMT_HW_ACCESS_REPLACEMENT 0 ++ ++#if CFG_SUPPORT_PERFORMANCE_TEST ++ ++#else ++ ++#endif ++ ++#define CFG_SUPPORT_AIS_5GHZ 1 ++#define CFG_SUPPORT_BEACON_CHANGE_DETECTION 0 ++ ++/*------------------------------------------------------------------------------ ++ * Option for NVRAM and Version Checking ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_NVRAM 1 ++#define CFG_NVRAM_EXISTENCE_CHECK 1 ++#define CFG_SW_NVRAM_VERSION_CHECK 1 ++#define CFG_SUPPORT_NIC_CAPABILITY 1 ++ ++/*------------------------------------------------------------------------------ ++ * CONFIG_TITLE : Stress Test Option ++ * OWNER : Puff Wen ++ * Description : For stress test only. DO NOT enable it while normal operation ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_STRESS_TEST_SUPPORT 0 ++ ++/*------------------------------------------------------------------------------ ++ * Flags for LINT ++ *------------------------------------------------------------------------------ ++ */ ++#define LINT_SAVE_AND_DISABLE /*lint -save -e* */ ++ ++#define LINT_RESTORE /*lint -restore */ ++ ++#define LINT_EXT_HEADER_BEGIN LINT_SAVE_AND_DISABLE ++ ++#define LINT_EXT_HEADER_END LINT_RESTORE ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Features ++ *------------------------------------------------------------------------------ ++ */ ++ ++#define CFG_SUPPORT_QOS 1 /* Enable/disable QoS TX, AMPDU */ ++#define CFG_SUPPORT_AMPDU_TX 1 ++#define CFG_SUPPORT_AMPDU_RX 1 ++#define CFG_SUPPORT_TSPEC 0 /* Enable/disable TS-related Action frames handling */ ++#define CFG_SUPPORT_UAPSD 1 ++#define CFG_SUPPORT_UL_PSMP 0 ++ ++#define CFG_SUPPORT_ROAMING 1 /* Roaming System */ ++#define CFG_SUPPORT_SWCR 1 ++ ++#define CFG_SUPPORT_ANTI_PIRACY 1 ++ ++#define CFG_SUPPORT_OSC_SETTING 1 ++ ++#define CFG_SUPPORT_P2P_RSSI_QUERY 0 ++ ++#define CFG_SHOW_MACADDR_SOURCE 1 ++ ++#define CFG_SUPPORT_802_11V 0 /* Support 802.11v Wireless Network Management */ ++#define CFG_SUPPORT_802_11V_TIMING_MEASUREMENT 0 ++#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (CFG_SUPPORT_802_11V == 0) ++#error "CFG_SUPPORT_802_11V should be 1 once CFG_SUPPORT_802_11V_TIMING_MEASUREMENT equals to 1" ++#endif ++#if (CFG_SUPPORT_802_11V == 0) ++#define WNM_UNIT_TEST 0 ++#endif ++ ++#define CFG_DRIVER_COMPOSE_ASSOC_REQ 1 ++ ++#define CFG_STRICT_CHECK_CAPINFO_PRIVACY 0 ++ ++#define CFG_SUPPORT_WFD 1 ++ ++#define CFG_SUPPORT_WFD_COMPOSE_IE 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Packet Lifetime Profiling Mechanism ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_PKT_LIFETIME_PROFILE 1 ++ ++#define CFG_ENABLE_PER_STA_STATISTICS 1 ++ ++#define CFG_PRINT_RTP_PROFILE 0 /* If want to enable WFD Debug, please change it to 1. */ ++#define CFG_PRINT_RTP_SN_SKIP 0 ++ ++#define CFG_SUPPORT_PWR_LIMIT_COUNTRY 1 ++/*------------------------------------------------------------------------------ ++ * Flags of bus error tolerance ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_FORCE_RESET_UNDER_BUS_ERROR 0 ++ ++/*------------------------------------------------------------------------------ ++ * Build Date Code Integration ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_BUILD_DATE_CODE 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags for prepare the FW compile flag ++ *------------------------------------------------------------------------------ ++ */ ++#define COMPILE_FLAG0_GET_STA_LINK_STATUS (1<<0) ++#define COMPILE_FLAG0_WFD_ENHANCEMENT_PROTECT (1<<1) ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Batch Scan SUPPORT ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_BATCH_SCAN 0 ++#define CFG_BATCH_MAX_MSCAN 2 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Channel Environment SUPPORT ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_GET_CH_ENV 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of THERMO_THROTTLING SUPPORT ++ *------------------------------------------------------------------------------ ++ */ ++ ++#define CFG_SUPPORT_THERMO_THROTTLING 1 ++#define WLAN_INCLUDE_PROC 1 ++ ++#define CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE 1 ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _CONFIG_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h +new file mode 100644 +index 000000000000..af586063c21a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h +@@ -0,0 +1,466 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/debug.h#1 ++*/ ++ ++/*! \file debug.h ++ \brief Definition of SW debugging level. ++ ++ In this file, it describes the definition of various SW debugging levels and ++ assert functions. ++*/ ++ ++/* ++** Log: debug.h ++ * ++ * 12 16 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * fixed the Windows DDK free build compiling error. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Using the new XLOG define for dum Memory. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Add dumpMemory8 at XLOG support. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 07 2011 wh.su ++ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! ++ * . ++ * ++ * 09 23 2010 cp.wu ++ * NULL ++ * add BOW index for debugging message and passing compilation ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add one more debug moduel for P2P. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add debug module index for cnm and ais. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add CFG_STARTUP_DEBUG for debugging starting up issue. ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-29 19:47:50 GMT mtk01084 ++** add emu category ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-17 18:12:04 GMT mtk01426 ++** Don't use dynamic memory allocate for debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:29 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _DEBUG_H ++#define _DEBUG_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#ifndef BUILD_QA_DBG ++#define BUILD_QA_DBG 0 ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++extern UINT_8 aucDebugModule[]; ++extern UINT_32 u4DebugModule; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Define debug category (class): ++ * (1) ERROR (2) WARN (3) STATE (4) EVENT (5) TRACE (6) INFO (7) LOUD (8) TEMP ++ */ ++#define DBG_CLASS_ERROR BIT(0) ++#define DBG_CLASS_WARN BIT(1) ++#define DBG_CLASS_STATE BIT(2) ++#define DBG_CLASS_EVENT BIT(3) ++#define DBG_CLASS_TRACE BIT(4) ++#define DBG_CLASS_INFO BIT(5) ++#define DBG_CLASS_LOUD BIT(6) ++#define DBG_CLASS_TEMP BIT(7) ++#define DBG_CLASS_MASK BITS(0, 7) ++ ++#if defined(LINUX) ++#define DBG_PRINTF_64BIT_DEC "lld" ++ ++#else /* Windows */ ++#define DBG_PRINTF_64BIT_DEC "I64d" ++ ++#endif ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Define debug module index */ ++typedef enum _ENUM_DBG_MODULE_T { ++ DBG_INIT_IDX = 0, /* For driver initial */ ++ DBG_HAL_IDX, /* For HAL(HW) Layer */ ++ DBG_INTR_IDX, /* For Interrupt */ ++ DBG_REQ_IDX, ++ DBG_TX_IDX, ++ DBG_RX_IDX, ++ DBG_RFTEST_IDX, /* For RF test mode */ ++ DBG_EMU_IDX, /* Developer specific */ ++ ++ DBG_SW1_IDX, /* Developer specific */ ++ DBG_SW2_IDX, /* Developer specific */ ++ DBG_SW3_IDX, /* Developer specific */ ++ DBG_SW4_IDX, /* Developer specific */ ++ ++ DBG_HEM_IDX, /* HEM */ ++ DBG_AIS_IDX, /* AIS */ ++ DBG_RLM_IDX, /* RLM */ ++ DBG_MEM_IDX, /* RLM */ ++ DBG_CNM_IDX, /* CNM */ ++ DBG_RSN_IDX, /* RSN */ ++ DBG_BSS_IDX, /* BSS */ ++ DBG_SCN_IDX, /* SCN */ ++ DBG_SAA_IDX, /* SAA */ ++ DBG_AAA_IDX, /* AAA */ ++ DBG_P2P_IDX, /* P2P */ ++ DBG_QM_IDX, /* QUE_MGT */ ++ DBG_SEC_IDX, /* SEC */ ++ DBG_BOW_IDX, /* BOW */ ++ DBG_WAPI_IDX, /* WAPI */ ++ DBG_ROAMING_IDX, /* ROAMING */ ++ DBG_TDLS_IDX, /* TDLS *//* CFG_SUPPORT_TDLS */ ++ DBG_OID_IDX, ++ DBG_NIC_IDX, ++ ++ DBG_MODULE_NUM /* Notice the XLOG check */ ++} ENUM_DBG_MODULE_T; ++ ++/* XLOG */ ++/* #define XLOG_DBG_MODULE_IDX 28 */ /* DBG_MODULE_NUM */ ++/* #if (XLOG_DBG_MODULE_IDX != XLOG_DBG_MODULE_IDX) */ ++/* #error "Please modify the DBG_MODULE_NUM and make sure this include at XLOG" */ ++/* #endif */ ++ ++/* Define who owns developer specific index */ ++#define DBG_YARCO_IDX DBG_SW1_IDX ++#define DBG_KEVIN_IDX DBG_SW2_IDX ++#define DBG_CMC_IDX DBG_SW3_IDX ++#define DBG_GEORGE_IDX DBG_SW4_IDX ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Debug print format string for the OS system time */ ++#define OS_SYSTIME_DBG_FORMAT "0x%08x" ++ ++/* Debug print argument for the OS system time */ ++#define OS_SYSTIME_DBG_ARGUMENT(systime) (systime) ++ ++/* Debug print format string for the MAC Address */ ++#define MACSTR "%pM" ++/* "%02x:%02x:%02x:%02x:%02x:%02x" */ ++ ++/* Debug print argument for the MAC Address */ ++#define MAC2STR(a) a ++/* ((PUINT_8)a)[0], ((PUINT_8)a)[1], ((PUINT_8)a)[2], ((PUINT_8)a)[3], ((PUINT_8)a)[4], ((PUINT_8)a)[5] */ ++ ++/* The pre-defined format to dump the value of a varaible with its name shown. */ ++#define DUMPVAR(variable, format) (#variable " = " format "\n", variable) ++ ++/* The pre-defined format to dump the MAC type value with its name shown. */ ++#define DUMPMACADDR(addr) (#addr " = %pM\n", (addr)) ++ ++/* Basiclly, we just do renaming of KAL functions although they should ++ * be defined as "Nothing to do" if DBG=0. But in some compiler, the macro ++ * syntax does not support #define LOG_FUNC(x,...) ++ * ++ * A caller shall not invoke these three macros when DBG=0. ++ */ ++ ++/*LOG_FUNC("[wlan]%s:(" #_Module " " #_Class ") "_Fmt, __func__, ##__VA_ARGS__);*/ ++ ++#define LOG_FUNC kalPrint ++ ++#if defined(LINUX) ++#define DBGLOG(_Module, _Class, _Fmt, ...) \ ++ do { \ ++ if ((aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) == 0) \ ++ break; \ ++ LOG_FUNC("%s:(" #_Module " " #_Class ")"_Fmt, __func__, ##__VA_ARGS__); \ ++ } while (0) ++#else ++#define DBGLOG(_Module, _Class, _Fmt) ++#endif ++ ++#if DBG ++ ++#define TMP_BUF_LEN 256 ++#define TMP_WBUF_LEN (TMP_BUF_LEN * 2) ++ ++extern PINT_16 g_wbuf_p; ++extern PINT_8 g_buf_p; ++ ++ /* If __FUNCTION__ is already defined by compiler, we just use it. */ ++#if defined(__func__) ++#define DEBUGFUNC(_Func) ++#else ++#define DEBUGFUNC(_Func) \ ++ static const char __func__[] = _Func ++#endif ++ ++#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \ ++ { \ ++ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ ++ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ ++ dumpMemory8((PUINT_8) (_StartAddr), (UINT_32) (_Length)); \ ++ } \ ++ } ++ ++#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) \ ++ { \ ++ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ ++ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ ++ dumpMemory32((PUINT_32) (_StartAddr), (UINT_32) (_Length)); \ ++ } \ ++ } ++ /*lint -restore */ ++ ++ /*lint -save -e961 use of '#undef' is discouraged */ ++#undef ASSERT ++ /*lint -restore */ ++ ++#ifdef _lint ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp)) { \ ++ do {} while (1); \ ++ } \ ++ } ++#else ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ ++ kalBreakPoint(); \ ++ } \ ++ } ++#endif /* _lint */ ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ ++ LOG_FUNC _fmt; \ ++ kalBreakPoint(); \ ++ } \ ++ } ++ ++#define DISP_STRING(_str) _str ++ ++#else /* !DBG */ ++ ++#define DEBUGFUNC(_Func) ++#define INITLOG(_Fmt) ++#define ERRORLOG(_Fmt) ++#define WARNLOG(_Fmt) ++ ++#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) ++#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) ++ ++#undef ASSERT ++ ++#if BUILD_QA_DBG ++#if defined(LINUX) /* For debugging in Linux w/o GDB */ ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ ++ kalBreakPoint(); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ ++ LOG_FUNC _fmt; \ ++ kalBreakPoint(); \ ++ } \ ++ } ++#else ++#ifdef WINDOWS_CE ++#define UNICODE_TEXT(_msg) TEXT(_msg) ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ TCHAR rUbuf[256]; \ ++ kalBreakPoint(); \ ++ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ ++ UNICODE_TEXT(__FILE__), \ ++ __LINE__, \ ++ UNICODE_TEXT(#_exp)); \ ++ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ TCHAR rUbuf[256]; \ ++ kalBreakPoint(); \ ++ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ ++ UNICODE_TEXT(__FILE__), \ ++ __LINE__, \ ++ UNICODE_TEXT(#_exp)); \ ++ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ ++ } \ ++ } ++#else ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ kalBreakPoint(); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ kalBreakPoint(); \ ++ } \ ++ } ++#endif /* WINDOWS_CE */ ++#endif /* LINUX */ ++#else ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ ++ LOG_FUNC _fmt; \ ++ } \ ++ } ++#endif /* BUILD_QA_DBG */ ++ ++#define DISP_STRING(_str) "" ++ ++#endif /* DBG */ ++ ++#if CFG_STARTUP_DEBUG ++#if defined(LINUX) ++#define DBGPRINTF kalPrint ++#else ++#define DBGPRINTF DbgPrint ++#endif ++#else ++#define DBGPRINTF(...) ++#endif ++ ++/* The following macro is used for debugging packed structures. */ ++#ifndef DATA_STRUCT_INSPECTING_ASSERT ++#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ ++{ \ ++ switch (0) {case 0: case (expr): default:; } \ ++} ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length); ++ ++VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length); ++ ++VOID wlanDebugInit(VOID); ++VOID wlanDebugUninit(VOID); ++VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable); ++VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd); ++VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _DEBUG_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h +new file mode 100644 +index 000000000000..108860c80e2d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h +@@ -0,0 +1,368 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1 ++*/ ++ ++/*! \file link.h ++ \brief Definition for simple doubly linked list operations. ++ ++ In this file we define the simple doubly linked list data structure and its ++ operation MACROs and INLINE functions. ++*/ ++ ++/* ++** Log: link.h ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * [WPD00003833] [MT6620 and MT5931] Driver migration ++ * . ++ * ++ * ++ * ++ * ++ * May 4 2009 mtk01084 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * add WIFI to BORA source control ++** \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461 ++** Update driver to fix lint warning ++** \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461 ++** Add macro for checking valid list ++** \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461 ++** Add LINK_IS_INVALID macro ++** Revision 1.1.1.1 2007/06/22 08:09:05 MTK01461 ++** no message ++** ++*/ ++ ++#ifndef _LINK_H ++#define _LINK_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* May cause page fault & unalignment issue (data abort) */ ++#define INVALID_LINK_POISON1 ((VOID *) 0x00100101) ++/* Used to verify that nonbody uses non-initialized link entries. */ ++#define INVALID_LINK_POISON2 ((VOID *) 0x00100201) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Simple Doubly Linked List Structures - Entry Part */ ++typedef struct _LINK_ENTRY_T { ++ struct _LINK_ENTRY_T *prNext, *prPrev; ++} LINK_ENTRY_T, *P_LINK_ENTRY_T; ++ ++/* Simple Doubly Linked List Structures - List Part */ ++typedef struct _LINK_T { ++ P_LINK_ENTRY_T prNext; ++ P_LINK_ENTRY_T prPrev; ++ UINT_32 u4NumElem; ++} LINK_T, *P_LINK_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#if 0 /* No one use it, temporarily mark it for [Lint - Info 773] */ ++#define LINK_ADDR(rLink) { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 } ++ ++#define LINK_DECLARATION(rLink) \ ++ struct _LINK_T rLink = LINK_ADDR(rLink) ++#endif ++ ++#define LINK_INITIALIZE(prLink) \ ++ do { \ ++ ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \ ++ ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \ ++ ((P_LINK_T)(prLink))->u4NumElem = 0; \ ++ } while (0) ++ ++#define LINK_ENTRY_INITIALIZE(prEntry) \ ++ do { \ ++ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \ ++ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \ ++ } while (0) ++ ++#define LINK_ENTRY_INVALID(prEntry) \ ++ do { \ ++ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \ ++ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \ ++ } while (0) ++ ++#define LINK_IS_EMPTY(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink)) ++ ++/* NOTE: We should do memory zero before any LINK been initiated, so we can check ++ * if it is valid before parsing the LINK. ++ */ ++#define LINK_IS_INVALID(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL) ++ ++#define LINK_IS_VALID(prLink) (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL) ++ ++#define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member) ++ ++/* Insert an entry into a link list's head */ ++#define LINK_INSERT_HEAD(prLink, prEntry) \ ++ { \ ++ linkAdd(prEntry, prLink); \ ++ ((prLink)->u4NumElem)++; \ ++ } ++ ++/* Append an entry into a link list's tail */ ++#define LINK_INSERT_TAIL(prLink, prEntry) \ ++ { \ ++ linkAddTail(prEntry, prLink); \ ++ ((prLink)->u4NumElem)++; \ ++ } ++ ++/* Peek head entry, but keep still in link list */ ++#define LINK_PEEK_HEAD(prLink, _type, _member) \ ++ ( \ ++ LINK_IS_EMPTY(prLink) ? \ ++ NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \ ++ ) ++ ++/* Peek tail entry, but keep still in link list */ ++#define LINK_PEEK_TAIL(prLink, _type, _member) \ ++ ( \ ++ LINK_IS_EMPTY(prLink) ? \ ++ NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \ ++ ) ++ ++/* Get first entry from a link list */ ++/* NOTE: We assume the link entry located at the beginning of "prEntry Type", ++ * so that we can cast the link entry to other data type without doubts. ++ * And this macro also decrease the total entry count at the same time. ++ */ ++#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \ ++ { \ ++ ASSERT(prLink); \ ++ if (LINK_IS_EMPTY(prLink)) { \ ++ prEntry = (_P_TYPE)NULL; \ ++ } \ ++ else { \ ++ prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \ ++ linkDel((P_LINK_ENTRY_T)prEntry); \ ++ ((prLink)->u4NumElem)--; \ ++ } \ ++ } ++ ++/* Assume the link entry located at the beginning of prEntry Type. ++ * And also decrease the total entry count. ++ */ ++#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \ ++ { \ ++ ASSERT(prLink); \ ++ ASSERT(prEntry); \ ++ linkDel((P_LINK_ENTRY_T)prEntry); \ ++ ((prLink)->u4NumElem)--; \ ++ } ++ ++/* Iterate over a link list */ ++#define LINK_FOR_EACH(prEntry, prLink) \ ++ for (prEntry = (prLink)->prNext; \ ++ prEntry != (P_LINK_ENTRY_T)(prLink); \ ++ prEntry = (P_LINK_ENTRY_T)prEntry->prNext) ++ ++/* Iterate over a link list backwards */ ++#define LINK_FOR_EACH_PREV(prEntry, prLink) \ ++ for (prEntry = (prLink)->prPrev; \ ++ prEntry != (P_LINK_ENTRY_T)(prLink); \ ++ prEntry = (P_LINK_ENTRY_T)prEntry->prPrev) ++ ++/* Iterate over a link list safe against removal of link entry */ ++#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \ ++ for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \ ++ prEntry != (P_LINK_ENTRY_T)(prLink); \ ++ prEntry = prNextEntry, prNextEntry = prEntry->prNext) ++ ++/* Iterate over a link list of given type */ ++#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \ ++ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \ ++ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ ++ prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember)) ++ ++/* Iterate backwards over a link list of given type */ ++#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \ ++ for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \ ++ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ ++ prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember)) ++ ++/* Iterate over a link list of given type safe against removal of link entry */ ++#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \ ++ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \ ++ prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \ ++ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ ++ prObj = prNextObj, \ ++ prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is only for internal link list manipulation. ++* ++* \param[in] prNew Pointer of new link head ++* \param[in] prPrev Pointer of previous link head ++* \param[in] prNext Pointer of next link head ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID __linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) ++{ ++ prNext->prPrev = prNew; ++ prNew->prNext = prNext; ++ prNew->prPrev = prPrev; ++ prPrev->prNext = prNew; ++ ++} /* end of __linkAdd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will add a new entry after the specified link head. ++* ++* \param[in] prNew New entry to be added ++* \param[in] prHead Specified link head to add it after ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) ++{ ++ __linkAdd(prNew, (P_LINK_ENTRY_T) prLink, prLink->prNext); ++ ++} /* end of linkAdd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will add a new entry before the specified link head. ++* ++* \param[in] prNew New entry to be added ++* \param[in] prHead Specified link head to add it before ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkAddTail(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) ++{ ++ __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T) prLink); ++ ++} /* end of linkAddTail() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is only for internal link list manipulation. ++* ++* \param[in] prPrev Pointer of previous link head ++* \param[in] prNext Pointer of next link head ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID __linkDel(IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) ++{ ++ prNext->prPrev = prPrev; ++ prPrev->prNext = prNext; ++ ++} /* end of __linkDel() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will delete a specified entry from link list. ++* NOTE: the entry is in an initial state. ++* ++* \param prEntry Specified link head(entry) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkDel(IN P_LINK_ENTRY_T prEntry) ++{ ++ __linkDel(prEntry->prPrev, prEntry->prNext); ++ ++ LINK_ENTRY_INITIALIZE(prEntry); ++ ++} /* end of linkDel() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will delete a specified entry from link list and then add it ++* after the specified link head. ++* ++* \param[in] prEntry Specified link head(entry) ++* \param[in] prOtherHead Another link head to add it after ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkMove(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) ++{ ++ __linkDel(prEntry->prPrev, prEntry->prNext); ++ linkAdd(prEntry, prLink); ++ ++} /* end of linkMove() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will delete a specified entry from link list and then add it ++* before the specified link head. ++* ++* \param[in] prEntry Specified link head(entry) ++* \param[in] prOtherHead Another link head to add it before ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkMoveTail(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) ++{ ++ __linkDel(prEntry->prPrev, prEntry->prNext); ++ linkAddTail(prEntry, prLink); ++ ++} /* end of linkMoveTail() */ ++ ++#endif /* _LINK_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h +new file mode 100644 +index 000000000000..fd83c79ffe10 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h +@@ -0,0 +1,188 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/aa_fsm.h#1 ++*/ ++ ++/*! \file aa_fsm.h ++ \brief Declaration of functions and finite state machine for SAA/AAA Module. ++ ++ Declaration of functions and finite state machine for SAA/AAA Module. ++*/ ++ ++/* ++** Log: aa_fsm.h ++ * ++ * 10 13 2011 cp.wu ++ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS ++ * 1. short join failure count limit to 2 ++ * 2. treat join timeout as kind of join failure as well ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _AA_FSM_H ++#define _AA_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Retry interval for retransmiting authentication-request MMPDU. */ ++#define TX_AUTHENTICATION_RETRY_TIMEOUT_TU 100 /* TU. */ ++ ++/* Retry interval for retransmiting association-request MMPDU. */ ++#define TX_ASSOCIATION_RETRY_TIMEOUT_TU 100 /* TU. */ ++ ++/* Wait for a response to a transmitted authentication-request MMPDU. */ ++#define DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ ++ ++/* Wait for a response to a transmitted association-request MMPDU. */ ++#define DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ ++ ++/* The maximum time to wait for JOIN process complete. */ ++#define JOIN_FAILURE_TIMEOUT_BEACON_INTERVAL 20 /* Beacon Interval, 20 * 100TU = 2 sec. */ ++ ++/* Retry interval for next JOIN request. */ ++#define JOIN_RETRY_INTERVAL_SEC 10 /* Seconds */ ++ ++/* Maximum Retry Count for accept a JOIN request. */ ++#define JOIN_MAX_RETRY_FAILURE_COUNT 2 /* Times */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_AA_STATE_T { ++ AA_STATE_IDLE = 0, ++ SAA_STATE_SEND_AUTH1, ++ SAA_STATE_WAIT_AUTH2, ++ SAA_STATE_SEND_AUTH3, ++ SAA_STATE_WAIT_AUTH4, ++ SAA_STATE_SEND_ASSOC1, ++ SAA_STATE_WAIT_ASSOC2, ++ AAA_STATE_SEND_AUTH2, ++ AAA_STATE_SEND_AUTH4, /* We may not use, because P2P GO didn't support WEP and 11r */ ++ AAA_STATE_SEND_ASSOC2, ++ AA_STATE_RESOURCE, /* A state for debugging the case of out of msg buffer. */ ++ AA_STATE_NUM ++} ENUM_AA_STATE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in saa_fsm.c */ ++/*----------------------------------------------------------------------------*/ ++VOID ++saaFsmSteps(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb); ++ ++WLAN_STATUS ++saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, ++ WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb); ++ ++VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++WLAN_STATUS ++saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines in aaa_fsm.c */ ++/*----------------------------------------------------------------------------*/ ++VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _AA_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h +new file mode 100644 +index 000000000000..b771bdacf2c6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h +@@ -0,0 +1,573 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/ais_fsm.h#1 ++*/ ++ ++/*! \file ais_fsm.h ++ \brief Declaration of functions and finite state machine for AIS Module. ++ ++ Declaration of functions and finite state machine for AIS Module. ++*/ ++ ++/* ++** Log: ais_fsm.h ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition ++ * from synchronous to asynchronous approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS ++ * is in Normal TR state without join timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 04 25 2011 cp.wu ++ * [WCXRP00000676] [MT6620 Wi-Fi][Driver] AIS to reduce request channel period from 5 seconds to 2 seconds ++ * channel interval for joining is shortened to 2 seconds to avoid interruption of concurrent operating network. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 02 22 2011 cp.wu ++ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with ++ * a queue-based approach to improve response time for scanning request ++ * handle SCAN and RECONNECT with a FIFO approach. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 14 2011 cp.wu ++ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent ++ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. ++ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. ++ * ++ * 11 25 2010 cp.wu ++ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM ++ * add scanning with specified SSID facility to AIS-FSM ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * 1) initialize for correct parameter even for disassociation. ++ * 2) AIS-FSM should have a limit on trials to build connection ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, RLM/CNM will handle ++ * the channel switching when BSS information is updated ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, ++ * just pend it til 5-sec. period finishes ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet ++ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * separate AIS-FSM states into different cases of channel request. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Refine AIS-FSM by divided into more states ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 23 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * reduce the background ssid idle time min and max value ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * and will send Null frame to diagnose connection ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Support dynamic channel selection ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Media disconnect indication and related postpone functions ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aisFsmRunEventJoinComplete() ++ * ++ * Nov 25 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Virtual CMD & RESP for testing CMD PATH ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * add aisFsmInitializeConnectionSettings() ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_MGMT_FSM for aisFsmTest() ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function prototype of aisFsmInit() ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _AIS_FSM_H ++#define _AIS_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define AIS_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ ++#define AIS_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ ++ ++#define AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4 2 /* 2.4G scan need about 0.5s, so delay 2s to reconnect is enough */ ++#define AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND 5 /* 2.4G scan need about 3.3s, so delay 5s to reconnect is enough */ ++ ++#define AIS_IBSS_ALONE_TIMEOUT_SEC 20 /* seconds */ ++ ++#define AIS_BEACON_TIMEOUT_COUNT_ADHOC 30 ++#define AIS_BEACON_TIMEOUT_COUNT_INFRA 10 ++#define AIS_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ ++ ++#define AIS_BEACON_MAX_TIMEOUT_TU 100 ++#define AIS_BEACON_MIN_TIMEOUT_TU 5 ++#define AIS_BEACON_MAX_TIMEOUT_VALID TRUE ++#define AIS_BEACON_MIN_TIMEOUT_VALID TRUE ++ ++#define AIS_BMC_MAX_TIMEOUT_TU 100 ++#define AIS_BMC_MIN_TIMEOUT_TU 5 ++#define AIS_BMC_MAX_TIMEOUT_VALID TRUE ++#define AIS_BMC_MIN_TIMEOUT_VALID TRUE ++ ++#define AIS_JOIN_CH_GRANT_THRESHOLD 10 ++#define AIS_JOIN_CH_REQUEST_INTERVAL 3000 ++ ++#define AIS_SCN_DONE_TIMEOUT_SEC 30 /* 15 for 2.4G + 5G */ /* 5 */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_AIS_STATE_T { ++ AIS_STATE_IDLE = 0, ++ AIS_STATE_SEARCH, ++ AIS_STATE_SCAN, ++ AIS_STATE_ONLINE_SCAN, ++ AIS_STATE_LOOKING_FOR, ++ AIS_STATE_WAIT_FOR_NEXT_SCAN, ++ AIS_STATE_REQ_CHANNEL_JOIN, ++ AIS_STATE_JOIN, ++ AIS_STATE_IBSS_ALONE, ++ AIS_STATE_IBSS_MERGE, ++ AIS_STATE_NORMAL_TR, ++ AIS_STATE_DISCONNECTING, ++ AIS_STATE_REQ_REMAIN_ON_CHANNEL, ++ AIS_STATE_REMAIN_ON_CHANNEL, ++ AIS_STATE_NUM ++} ENUM_AIS_STATE_T; ++ ++typedef struct _MSG_AIS_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucReasonOfDisconnect; ++ BOOLEAN fgDelayIndication; ++} MSG_AIS_ABORT_T, *P_MSG_AIS_ABORT_T; ++ ++typedef struct _MSG_AIS_IBSS_PEER_FOUND_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ BOOLEAN fgIsMergeIn; /* TRUE: Merge In, FALSE: Merge Out */ ++ P_STA_RECORD_T prStaRec; ++} MSG_AIS_IBSS_PEER_FOUND_T, *P_MSG_AIS_IBSS_PEER_FOUND_T; ++ ++typedef enum _ENUM_AIS_REQUEST_TYPE_T { ++ AIS_REQUEST_SCAN, ++ AIS_REQUEST_RECONNECT, ++ AIS_REQUEST_ROAMING_SEARCH, ++ AIS_REQUEST_ROAMING_CONNECT, ++ AIS_REQUEST_REMAIN_ON_CHANNEL, ++ AIS_REQUEST_NUM ++} ENUM_AIS_REQUEST_TYPE_T; ++ ++typedef struct _AIS_REQ_HDR_T { ++ LINK_ENTRY_T rLinkEntry; ++ ENUM_AIS_REQUEST_TYPE_T eReqType; ++} AIS_REQ_HDR_T, *P_AIS_REQ_HDR_T; ++ ++typedef struct _AIS_REQ_CHNL_INFO { ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eSco; ++ UINT_8 ucChannelNum; ++ UINT_32 u4DurationMs; ++ UINT_64 u8Cookie; ++} AIS_REQ_CHNL_INFO, *P_AIS_REQ_CHNL_INFO; ++ ++typedef struct _AIS_MGMT_TX_REQ_INFO_T { ++ BOOLEAN fgIsMgmtTxRequested; ++ P_MSDU_INFO_T prMgmtTxMsdu; ++ UINT_64 u8Cookie; ++} AIS_MGMT_TX_REQ_INFO_T, *P_AIS_MGMT_TX_REQ_INFO_T; ++ ++typedef struct _AIS_FSM_INFO_T { ++ ENUM_AIS_STATE_T ePreviousState; ++ ENUM_AIS_STATE_T eCurrentState; ++ ++ BOOLEAN fgTryScan; ++ ++ BOOLEAN fgIsInfraChannelFinished; ++ BOOLEAN fgIsChannelRequested; ++ BOOLEAN fgIsChannelGranted; ++ ++#if CFG_SUPPORT_ROAMING ++ BOOLEAN fgIsRoamingScanPending; ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ ++ ++ P_BSS_DESC_T prTargetBssDesc; /* For destination */ ++ ++ P_STA_RECORD_T prTargetStaRec; /* For JOIN Abort */ ++ ++ UINT_32 u4SleepInterval; ++ ++ TIMER_T rBGScanTimer; ++ ++ TIMER_T rIbssAloneTimer; ++ ++ TIMER_T rIndicationOfDisconnectTimer; ++ ++ TIMER_T rJoinTimeoutTimer; ++ ++ TIMER_T rChannelTimeoutTimer; ++ ++ TIMER_T rScanDoneTimer; ++ ++ TIMER_T rDeauthDoneTimer; ++ ++ UINT_8 ucSeqNumOfReqMsg; ++ UINT_8 ucSeqNumOfChReq; ++ UINT_8 ucSeqNumOfScanReq; ++ ++ UINT_32 u4ChGrantedInterval; ++ ++ UINT_8 ucConnTrialCount; ++ ++ UINT_8 ucScanSSIDLen; ++ UINT_8 aucScanSSID[ELEM_MAX_LEN_SSID]; ++ ++ UINT_32 u4ScanIELength; ++ UINT_8 aucScanIEBuf[MAX_IE_LENGTH]; ++ ++ /* Pending Request List */ ++ LINK_T rPendingReqList; ++ ++ /* Join Request Timestamp */ ++ OS_SYSTIME rJoinReqTime; ++ ++ /* for cfg80211 REMAIN_ON_CHANNEL support */ ++ AIS_REQ_CHNL_INFO rChReqInfo; ++ ++ /* Mgmt tx related. */ ++ AIS_MGMT_TX_REQ_INFO_T rMgmtTxInfo; ++ ++ /* Packet filter for AIS module. */ ++ UINT_32 u4AisPacketFilter; ++ ++} AIS_FSM_INFO_T, *P_AIS_FSM_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define aisChangeMediaState(_prAdapter, _eNewMediaState) \ ++ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState = (_eNewMediaState)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); ++ ++VOID aisFsmInit(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmUninit(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication); ++ ++VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter); ++#if 0 ++VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState); ++#endif ++VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++/*----------------------------------------------------------------------------*/ ++/* Handling for Ad-Hoc Network */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++/*----------------------------------------------------------------------------*/ ++/* Handling of Incoming Mailbox Message from CNM */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++/*----------------------------------------------------------------------------*/ ++/* Generating Outgoing Mailbox Message to CNM */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Event Indication */ ++/*----------------------------------------------------------------------------*/ ++VOID ++aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); ++ ++VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb); ++ ++VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter); ++ ++VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++WLAN_STATUS ++aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Disconnection Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication); ++ ++/*----------------------------------------------------------------------------*/ ++/* Event Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter); ++ ++VOID aisBssSecurityChanged(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++#if CFG_SUPPORT_ROAMING ++VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan); ++ ++ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec); ++ ++VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); ++#endif /*CFG_SUPPORT_ROAMING */ ++ ++/*----------------------------------------------------------------------------*/ ++/* Timeout Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID/IOCTL Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength); ++ ++/*----------------------------------------------------------------------------*/ ++/* Internal State Checking */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove); ++ ++P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType); ++ ++VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); ++ ++VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) ++VOID aisTest(VOID); ++#endif /* CFG_TEST_MGMT_FSM */ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _AIS_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h +new file mode 100644 +index 000000000000..70b32bca102b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h +@@ -0,0 +1,112 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/assoc.h#1 ++*/ ++ ++/*! \file assoc.h ++ \brief This file contains the ASSOC REQ/RESP of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: assoc.h ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add assocCheckTxReAssocRespFrame() proto type for P2P usage. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++*/ ++ ++#ifndef _ASSOC_H ++#define _ASSOC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in assoc.c */ ++/*----------------------------------------------------------------------------*/ ++UINT_16 assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++WLAN_STATUS ++assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode); ++ ++WLAN_STATUS ++assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); ++ ++WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _ASSOC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h +new file mode 100644 +index 000000000000..4f76f03324dd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h +@@ -0,0 +1,125 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/auth.h#1 ++*/ ++ ++/*! \file auth.h ++ \brief This file contains the authentication REQ/RESP of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: auth.h ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++*/ ++ ++#ifndef _AUTH_H ++#define _AUTH_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in auth.c */ ++/*----------------------------------------------------------------------------*/ ++VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo); ++ ++#if !CFG_SUPPORT_AAA ++WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum); ++#else ++WLAN_STATUS ++authSendAuthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode); ++#endif /* CFG_SUPPORT_AAA */ ++ ++WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum); ++ ++WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode); ++ ++VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr); ++ ++WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++authSendDeauthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); ++ ++WLAN_STATUS ++authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN UINT_8 aucExpectedBSSID[], ++ IN UINT_16 u2ExpectedAuthAlgNum, ++ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _AUTH_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h +new file mode 100644 +index 000000000000..5995d133a6cd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h +@@ -0,0 +1,184 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/bow_fsm.h#1 ++*/ ++ ++/*! \file bow_fsm.h ++ \brief Declaration of functions and finite state machine for BOW Module. ++ ++ Declaration of functions and finite state machine for BOW Module. ++*/ ++ ++/* ++** Log: bow_fsm.h ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Submit missing BoW header files. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 02 16 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add channel previledge into _BOW_FSM_INFO_T. ++ * ++ * 09 16 2010 chinghwa.yu ++ * NULL ++ * update bowChangeMediaState. ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ */ ++ ++#ifndef _BOW_FSM_H ++#define _BOW_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define BOW_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ ++#define BOW_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ ++ ++#define BOW_DELAY_TIME_OF_DISCONNECT_SEC 10 ++ ++#define BOW_BEACON_TIMEOUT_COUNT_STARTING 10 ++#define BOW_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ ++ ++#define BOW_BEACON_MAX_TIMEOUT_TU 100 ++#define BOW_BEACON_MIN_TIMEOUT_TU 5 ++#define BOW_BEACON_MAX_TIMEOUT_VALID TRUE ++#define BOW_BEACON_MIN_TIMEOUT_VALID TRUE ++ ++#define BOW_BMC_MAX_TIMEOUT_TU 100 ++#define BOW_BMC_MIN_TIMEOUT_TU 5 ++#define BOW_BMC_MAX_TIMEOUT_VALID TRUE ++#define BOW_BMC_MIN_TIMEOUT_VALID TRUE ++ ++#define BOW_JOIN_CH_GRANT_THRESHOLD 10 ++#define BOW_JOIN_CH_REQUEST_INTERVAL 2000 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_BOW_STATE_T { ++ BOW_STATE_IDLE = 0, ++ BOW_STATE_SEARCH, ++ BOW_STATE_SCAN, ++ BOW_STATE_ONLINE_SCAN, ++ BOW_STATE_LOOKING_FOR, ++ BOW_STATE_WAIT_FOR_NEXT_SCAN, ++ BOW_STATE_REQ_CHANNEL_JOIN, ++ BOW_STATE_REQ_CHANNEL_ALONE, ++ BOW_STATE_REQ_CHANNEL_MERGE, ++ BOW_STATE_JOIN, ++ BOW_STATE_IBSS_ALONE, ++ BOW_STATE_IBSS_MERGE, ++ BOW_STATE_NORMAL_TR, ++ BOW_STATE_NUM ++} ENUM_BOW_STATE_T; ++ ++typedef struct _BOW_FSM_INFO_T { ++ ENUM_BOW_STATE_T ePreviousState; ++ ENUM_BOW_STATE_T eCurrentState; ++ ++ BOOLEAN fgTryScan; ++ ++ /* Channel Privilege */ ++ ++ BOOLEAN fgIsInfraChannelFinished; ++ BOOLEAN fgIsChannelRequested; ++ BOOLEAN fgIsChannelGranted; ++ BOOLEAN fgIsScanPending; ++ UINT_32 u4ChGrantedInterval; ++ ++ UINT_8 ucPrimaryChannel; ++ ENUM_BAND_T eBand; ++ UINT_16 u2BeaconInterval; ++ ++ ENUM_BOW_STATE_T eReturnState; /* Return state after current activity finished or abort. */ ++ ENUM_BOW_STATE_T eForwardState; /* Step to next state if ACTION frame is TX successfully. */ ++ ++ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ ++ ++ P_STA_RECORD_T prTargetStaRec; ++ P_BSS_DESC_T prTargetBssDesc; /* For destination */ ++ ++ UINT_8 aucPeerAddress[6]; ++ ++ UINT_8 ucRole; ++ ++ BOOLEAN fgSupportQoS; ++ ++ BOOLEAN fgIsRsponseProbe; /* Indicate if BOW can response probe request frame. */ ++ ++ /* Sequence number of requested message. */ ++ UINT_8 ucSeqNumOfChReq; ++ UINT_8 ucSeqNumOfReqMsg; ++ UINT_8 ucSeqNumOfScnMsg; ++ UINT_8 ucSeqNumOfScanReq; ++ ++ UINT_8 ucSeqNumOfCancelMsg; ++ ++ UINT_8 ucDialogToken; ++ ++ /* Timer */ ++ TIMER_T rStartingBeaconTimer; /* For device discovery time of each discovery request from user. */ ++ TIMER_T rStartingDiscoveryTimer; ++ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ ++ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ ++ TIMER_T rIndicationOfDisconnectTimer; ++ TIMER_T rChGrantedTimer; ++ ++ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ ++ ++} BOW_FSM_INFO_T, *P_BOW_FSM_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define bowChangeMediaState(_prAdapter, _eNewMediaState) \ ++ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].eConnectionState = (_eNewMediaState)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h +new file mode 100644 +index 000000000000..0597132b970e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h +@@ -0,0 +1,265 @@ ++/* ++** Id: @(#) bss.h ++*/ ++ ++/*! \file "bss.h" ++ \brief In this file we define the function prototype used in BSS/IBSS. ++ ++ The file contains the function declarations and defines for used in BSS/IBSS. ++*/ ++ ++/* ++** Log: bss.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * Add code to send beacon and probe response WSC IE at Auto GO. ++ * ++ * 02 23 2011 eddie.chen ++ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap ++ * Fix parsing WMM INFO and bmp delivery bitmap definition. ++ * ++ * 01 31 2011 george.huang ++ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers ++ * Extend TIM PVB, from 2 to 3 octets. ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for ++ * initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Update bssProcessProbeRequest() and bssSendBeaconProbeResponse() declarations ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * when IBSS is being merged-in, send command packet to PM for connected indication ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add CTRL FLAGS for Probe Response. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Remove unused typedef. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix file merge error ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * * and will send Null frame to diagnose connection ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add DTIM count update while TX Beacon ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++#ifndef _BSS_H ++#define _BSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* NOTE(Kevin): change define for george */ ++/* #define MAX_LEN_TIM_PARTIAL_BMP (((MAX_ASSOC_ID + 1) + 7) / 8) */ /* Required bits = (MAX_ASSOC_ID + 1) */ ++#define MAX_LEN_TIM_PARTIAL_BMP ((CFG_STA_REC_NUM + 7) / 8) ++/* reserve length greater than maximum size of STA_REC */ /* obsoleted: Assume we only use AID:1~15 */ ++ ++/* CTRL FLAGS for Probe Response */ ++#define BSS_PROBE_RESP_USE_P2P_DEV_ADDR BIT(0) ++#define BSS_PROBE_RESP_INCLUDE_P2P_IE BIT(1) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define bssAssignAssocID(_prStaRec) ((_prStaRec)->ucIndex + 1) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines for all Operation Modes */ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T ++bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_STA_TYPE_T eStaType, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc); ++ ++VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec); ++ ++VOID ++bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP); ++ ++WLAN_STATUS ++bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++WLAN_STATUS ++bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for both IBSS(AdHoc) and BSS(AP) */ ++/*----------------------------------------------------------------------------*/ ++VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID ++bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr); ++ ++VOID ++bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN PUINT_8 pucDestAddr, ++ IN PUINT_8 pucOwnMACAddress, ++ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo); ++ ++WLAN_STATUS ++bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags); ++ ++WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); ++ ++VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); ++ ++VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for IBSS(AdHoc) only */ ++/*----------------------------------------------------------------------------*/ ++VOID ++ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI); ++ ++WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); ++ ++WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for BSS(AP) only */ ++/*----------------------------------------------------------------------------*/ ++VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate); ++ ++VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId); ++ ++P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr); ++ ++/*link function to p2p module for txBcnIETable*/ ++ ++/* WMM-2.2.2 WMM ACI to AC coding */ ++typedef enum _ENUM_ACI_T { ++ ACI_BE = 0, ++ ACI_BK = 1, ++ ACI_VI = 2, ++ ACI_VO = 3, ++ ACI_NUM ++} ENUM_ACI_T, *P_ENUM_ACI_T; ++ ++typedef enum _ENUM_AC_PRIORITY_T { ++ AC_BK_PRIORITY = 0, ++ AC_BE_PRIORITY, ++ AC_VI_PRIORITY, ++ AC_VO_PRIORITY ++} ENUM_AC_PRIORITY_T, *P_ENUM_AC_PRIORITY_T; ++ ++#endif /* _BSS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h +new file mode 100644 +index 000000000000..81b16b588867 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h +@@ -0,0 +1,258 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm.h#1 ++*/ ++ ++/*! \file "cnm.h" ++ \brief ++*/ ++ ++/* ++** Log: cnm.h ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Provide function to decide if BSS can be activated or not ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 13 2010 cm.chang ++ * ++ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Need bandwidth info when requesting channel privilege ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add a new function to send abort message ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support partial part about cmd basic configuration ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add prototype of cnmFsmEventInit() ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_H ++#define _CNM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_CH_REQ_TYPE_T { ++ CH_REQ_TYPE_JOIN, ++ CH_REQ_TYPE_P2P_LISTEN, ++ ++ CH_REQ_TYPE_NUM ++} ENUM_CH_REQ_TYPE_T, *P_ENUM_CH_REQ_TYPE_T; ++ ++typedef struct _MSG_CH_REQ_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucPrimaryChannel; ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ENUM_CH_REQ_TYPE_T eReqType; ++ UINT_32 u4MaxInterval; /* In unit of ms */ ++ UINT_8 aucBSSID[6]; ++ UINT_8 aucReserved[2]; ++} MSG_CH_REQ_T, *P_MSG_CH_REQ_T; ++ ++typedef struct _MSG_CH_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++} MSG_CH_ABORT_T, *P_MSG_CH_ABORT_T; ++ ++typedef struct _MSG_CH_GRANT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucPrimaryChannel; ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ENUM_CH_REQ_TYPE_T eReqType; ++ UINT_32 u4GrantInterval; /* In unit of ms */ ++} MSG_CH_GRANT_T, *P_MSG_CH_GRANT_T; ++ ++typedef struct _MSG_CH_REOCVER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucPrimaryChannel; ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ENUM_CH_REQ_TYPE_T eReqType; ++} MSG_CH_RECOVER_T, *P_MSG_CH_RECOVER_T; ++ ++typedef struct _CNM_INFO_T { ++ UINT_32 u4Reserved; ++} CNM_INFO_T, *P_CNM_INFO_T; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/* Moved from p2p_fsm.h */ ++typedef struct _DEVICE_TYPE_T { ++ UINT_16 u2CategoryId; /* Category ID */ ++ UINT_8 aucOui[4]; /* OUI */ ++ UINT_16 u2SubCategoryId; /* Sub Category ID */ ++} __KAL_ATTRIB_PACKED__ DEVICE_TYPE_T, *P_DEVICE_TYPE_T; ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID cnmInit(P_ADAPTER_T prAdapter); ++ ++VOID cnmUninit(P_ADAPTER_T prAdapter); ++ ++VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent); ++ ++BOOLEAN ++cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO); ++ ++BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); ++ ++VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); ++#if CFG_P2P_LEGACY_COEX_REVISE ++BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* We don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this to guarantee the same member order in different structures ++ * to simply handling effort in some functions. ++ */ ++static inline VOID cnmMsgDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == 0); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == OFFSET_OF(MSG_CH_RECOVER_T, rMsgHdr)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucNetTypeIndex) == ++ OFFSET_OF(MSG_CH_RECOVER_T, ucNetTypeIndex)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucTokenID) == OFFSET_OF(MSG_CH_RECOVER_T, ucTokenID)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucPrimaryChannel) == ++ OFFSET_OF(MSG_CH_RECOVER_T, ucPrimaryChannel)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfSco) == OFFSET_OF(MSG_CH_RECOVER_T, eRfSco)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfBand) == OFFSET_OF(MSG_CH_RECOVER_T, eRfBand)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eReqType) == OFFSET_OF(MSG_CH_RECOVER_T, eReqType)); ++ ++} ++#endif /* _lint */ ++ ++#endif /* _CNM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h +new file mode 100644 +index 000000000000..c8f25b1b29a9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h +@@ -0,0 +1,1164 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_mem.h#1 ++*/ ++ ++/*! \file "cnm_mem.h" ++ \brief In this file we define the structure of the control unit of ++ packet buffer and MGT/MSG Memory Buffer. ++*/ ++ ++/* ++** Log: cnm_mem.h ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Resize the Secondary Device Type array when WiFi Direct is enabled. ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the protected while at P2P start GO, and skip some security check . ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 11 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add per STA flow control when STA is in PS mode ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 29 2010 cm.chang ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for ++ * initial TX rate selection of auto-rate algorithm ++ * Sync RCPI of STA_REC to FW as reference of initial TX rate ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD ++ * when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 12 2010 cp.wu ++ * ++ * SAA will take a record for tracking request sequence number. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support state of STA record change from 1 to 1 ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error for P2P related defination. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P related fields. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [BORA00000678] [MT6620]WiFi LP integration ++ * 1. add u8TimeStamp in MSDU_INFO ++ * 2. move fgIsRxTSFUpdated/fgIsTxTSFUpdated from static to BSS_INFO ++ * 3. add new member for supporting PM in STA_RECORD, which is for AP PS mode ++ * ++ * 05 31 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support checking of duplicated buffer free ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set ++ * ++ * 05 19 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fixed MAC RX Desc be overwritten issue ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 05 10 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support Rx header translation for A-MSDU subframe ++ * ++ * 05 07 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * add more sanity check about setting timer ++ * ++ * 04 29 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * modify the compiling flag for RAM usage ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Modified some MQM-related data structures (SN counter, TX/RX BA table) ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Added new TX/RX BA tables in STA_REC ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 04 09 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * [BORA00000644] WiFi phase 4 integration ++ * Added per-TID SN cache in STA_REC ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support power control ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 11 2010 yuche.tsai ++ * [BORA00000343][MT6620] Emulation For TX ++ * . ++ * ++ * 03 05 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove Emulation definition ++ * ++ * 03 04 2010 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * eliminate HIF_EMULATION in cnm_mem.h ++ * ++ * 03 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add cnmStaRecChangeState() declaration. ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove compiling warning for some emulation flags ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * To store field AMPDU Parameters in STA_REC ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsWmmSupported in STA_RECORD_T. ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsUapsdSupported in STA_RECORD_T ++ * ++ * 02 13 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added arTspecTable in STA_REC for TSPEC management ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable mgmt buffer debug by default ++ * ++ * 02 12 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added BUFFER_SOURCE_BCN ++ * ++ * 02 10 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Renamed MSDU_INFO.ucFixedRateIndex as MSDU_INFO.ucFixedRateCode ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 02 02 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added SN info in MSDU_INFO_T ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h ++ * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem ++ * 3) use cnmMemAlloc() instead to allocate SRAM buffer ++ * ++ * 12 31 2009 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1) surpress debug message emitted from hal_hif.c ++ * 2) add two set of field for recording buffer process time ++ * ++ * 12 31 2009 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1. move wifi task initialization from wifi_task.c(rom) to wifi_init.c (TCM) for integrating F/W download later ++ * * * * * 2. WIFI_Event_Dispatcher() prototype changed to return to suspend mode from normal operation mode ++ * * * * * 2. HIF emulation logic revised ++ * ++ * 12 29 2009 yuche.tsai ++ * [BORA00000343][MT6620] Emulation For TX ++ * .Using global buffer declaring by SD1 instead of using another one. ++ * ++ * 12 25 2009 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) ++ * * MQM: BA handling ++ * * TXM: Macros updates ++ * * RXM: Macros/Duplicate Removal updates ++ * ++ * 12 24 2009 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * 12 23 2009 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * allocating SRAM for emulation purpose by ruducing MEM_BANK3_BUF_SZ ++ * ++ * 12 21 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove individual DATA_BUF_BLOCK_NUM definition for emulation compiling flagsu1rwduu`wvpghlqg|fh+fmdkb ++ * ++ * 12 21 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support several data buffer banks. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * .For new FPGA memory size ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * 12 17 2009 george.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 17 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Modified the DATA_BLOCK_SIZE from 1620 to 2048 ++ * ++ * Dec 16 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_SEC_EMULATION flag ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add HT cap to sta record ++ * ++ * Dec 9 2009 mtk02752 ++ * [BORA00000368] Integrate HIF part into BORA ++ * add cnmDataPktFree() for emulation loopback purpose ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * add the buffer for key handshake 1x and cmd key order issue ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * move the tx call back function proto type to typedef.h ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add cnmGetStaRecByAddress() and modify variable in STA_RECORD_T ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * rename the port block flag ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add variables to STA_RECORD_T for assoc/auth ++ * ++ * Nov 23 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Fixed the value of STA_WAIT_QUEUE_NUM (from 7 to 5) ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Removed u2FrameLength from SW_RFB ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Fixed indenting ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Updated MSDU_INFO and SW_RFB ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * update the variable for security ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * remove the variable to make the compiler ok ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * add the variable for security module ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo in define of MSG_BUF_BLOCK_SIZE ++ * ++ * Nov 13 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Let typedef STA_REC_T precede typedef MSDU_INFO_T and SW_RFB_T ++ * ++ * Nov 13 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Modified MSDU_INFO and STA_REC for TXM and MQM ++ * ++ * Nov 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename STA_REC_T to STA_RECORD_T and add ucIndex member ++ * ++ * Nov 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Make sure ucBufferSource the same offset in MSDU_INFO and SW_RFB ++ * ++ * Nov 6 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Nov 5 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update comment ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add draft content of MSDU_INFO_T and SW_RFB_T ++ * ++ * Oct 30 2009 mtk01084 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * Oct 21 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_RX_EMULATION flag ++ * ++ * Oct 20 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 9 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added field ucTC to MSDU_INFO_T and field pucHifRxPacket to SW_RFB_T ++ * ++ * Oct 8 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_MEM_H ++#define _CNM_MEM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#ifndef POWER_OF_2 ++#define POWER_OF_2(n) BIT(n) ++#endif ++ ++/* Size of a basic management buffer block in power of 2 */ ++#define MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2 7 /* 7 to the power of 2 = 128 */ ++#define MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2 5 /* 5 to the power of 2 = 32 */ ++ ++/* Size of a basic management buffer block */ ++#define MGT_BUF_BLOCK_SIZE POWER_OF_2(MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++#define MSG_BUF_BLOCK_SIZE POWER_OF_2(MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++ ++/* Total size of (n) basic management buffer blocks */ ++#define MGT_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++#define MSG_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++ ++/* Number of management buffer block */ ++#define MAX_NUM_OF_BUF_BLOCKS 32 /* Range: 1~32 */ ++ ++/* Size of overall management frame buffer */ ++#define MGT_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MGT_BUF_BLOCK_SIZE) ++#define MSG_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MSG_BUF_BLOCK_SIZE) ++ ++/* STA_REC related definitions */ ++#define STA_REC_INDEX_BMCAST 0xFF ++#define STA_REC_INDEX_NOT_FOUND 0xFE ++#define STA_WAIT_QUEUE_NUM 5 /* Number of SW queues in each STA_REC: AC0~AC4 */ ++#define SC_CACHE_INDEX_NUM 5 /* Number of SC caches in each STA_REC: AC0~AC4 */ ++ ++/* P2P related definitions */ ++#ifdef CFG_ENABLE_WIFI_DIRECT ++/* Moved from p2p_fsm.h */ ++#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ ++#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if ((MAX_NUM_OF_BUF_BLOCKS > 32) || (MAX_NUM_OF_BUF_BLOCKS <= 0)) ++#error > #define MAX_NUM_OF_MGT_BUF_BLOCKS : Out of boundary ! ++#elif MAX_NUM_OF_BUF_BLOCKS > 16 ++typedef UINT_32 BUF_BITMAP; ++#elif MAX_NUM_OF_BUF_BLOCKS > 8 ++typedef UINT_16 BUF_BITMAP; ++#else ++typedef UINT_8 BUF_BITMAP; ++#endif /* MAX_NUM_OF_MGT_BUF_BLOCKS */ ++ ++/* Control variable of TX management memory pool */ ++typedef struct _BUF_INFO_T { ++ PUINT_8 pucBuf; ++ ++#if CFG_DBG_MGT_BUF ++ UINT_32 u4AllocCount; ++ UINT_32 u4FreeCount; ++ UINT_32 u4AllocNullCount; ++#endif /* CFG_DBG_MGT_BUF */ ++ ++ BUF_BITMAP rFreeBlocksBitmap; ++ UINT_8 aucAllocatedBlockNum[MAX_NUM_OF_BUF_BLOCKS]; ++} BUF_INFO_T, *P_BUF_INFO_T; ++ ++/* Wi-Fi divides RAM into three types ++ * MSG: Mailbox message (Small size) ++ * BUF: HW DMA buffers (HIF/MAC) ++ */ ++typedef enum _ENUM_RAM_TYPE_T { ++ RAM_TYPE_MSG = 0, ++ RAM_TYPE_BUF ++} ENUM_RAM_TYPE_T, P_ENUM_RAM_TYPE_T; ++ ++typedef enum _ENUM_BUFFER_SOURCE_T { ++ BUFFER_SOURCE_HIF_TX0 = 0, ++ BUFFER_SOURCE_HIF_TX1, ++ BUFFER_SOURCE_MAC_RX, ++ BUFFER_SOURCE_MNG, ++ BUFFER_SOURCE_BCN, ++ BUFFER_SOURCE_NUM ++} ENUM_BUFFER_SOURCE_T, *P_ENUM_BUFFER_SOURCE_T; ++ ++typedef enum _ENUM_SEC_STATE_T { ++ SEC_STATE_INIT, ++ SEC_STATE_INITIATOR_PORT_BLOCKED, ++ SEC_STATE_RESPONDER_PORT_BLOCKED, ++ SEC_STATE_CHECK_OK, ++ SEC_STATE_SEND_EAPOL, ++ SEC_STATE_SEND_DEAUTH, ++ SEC_STATE_COUNTERMEASURE, ++ SEC_STATE_NUM ++} ENUM_SEC_STATE_T; ++ ++typedef struct _TSPEC_ENTRY_T { ++ UINT_8 ucStatus; ++ UINT_8 ucToken; /* Dialog Token in ADDTS_REQ or ADDTS_RSP */ ++ UINT_16 u2MediumTime; ++ UINT_32 u4TsInfo; ++ /* PARAM_QOS_TS_INFO rParamTsInfo; */ ++ /* Add other retained QoS parameters below */ ++} TSPEC_ENTRY_T, *P_TSPEC_ENTRY_T, TSPEC_TABLE_ENTRY_T, *P_TSPEC_TABLE_ENTRY_T; ++ ++typedef struct _SEC_INFO_T { ++ ++ ENUM_SEC_STATE_T ePreviousState; ++ ENUM_SEC_STATE_T eCurrentState; ++ ++ BOOLEAN fg2nd1xSend; ++ BOOLEAN fgKeyStored; ++ ++ UINT_8 aucStoredKey[64]; ++ ++ BOOLEAN fgAllowOnly1x; ++} SEC_INFO_T, *P_SEC_INFO_T; ++ ++#define MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS 3 ++ ++#define UPDATE_BSS_RSSI_INTERVAL_SEC 3 /* Seconds */ ++ ++/* Fragment information structure */ ++typedef struct _FRAG_INFO_T { ++ UINT_16 u2NextFragSeqCtrl; ++ PUINT_8 pucNextFragStart; ++ P_SW_RFB_T pr1stFrag; ++ OS_SYSTIME rReceiveLifetimeLimit; /* The receive time of 1st fragment */ ++} FRAG_INFO_T, *P_FRAG_INFO_T; ++ ++typedef struct _STAT_CNT_INFO_FW_T { ++ UINT32 u4NumOfTx; /* number of packets sent from host */ ++ UINT32 u4NumOfTxOK; /* number of packets sent to air OK */ ++ UINT32 u4NumOfTxRetry; /* number of packets sent to air RETRY */ ++ UINT32 u4TxDoneAirTimeMax; /* maximum tx done air time */ ++ ++ UINT32 u4NumOfPtiRspTxOk; /* number of PTI RSP sent to air OK */ ++ UINT32 u4NumOfPtiRspTxErr; /* number of PTI RSP sent to air ERROR */ ++ ++ UINT32 u4NumOfTxErr; /* number of packets sent to air ERROR */ ++ ++ UINT32 u4NumOfRx; /* number of received packets */ ++ UINT32 u4NumOfPtiRspRx; /* number of PTI RSP rcv */ ++ ++#define STAT_CNT_INFO_TX_ERR_FLUSHED 0x00000001 ++#define STAT_CNT_INFO_TX_ERR_AGE_TIMEOUT 0x00000002 ++#define STAT_CNT_INFO_TX_ERR_MPDU 0x00000004 ++#define STAT_CNT_INFO_TX_ERR_RTS 0x00000010 ++#define STAT_CNT_INFO_TX_ERR_LIFETIME 0x00000020 ++#define STAT_CNT_INFO_TX_ERR_UNKNOWN 0x80000000 ++ UINT32 u4TxErrBitmap; /* TX error type */ ++ ++#define STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM 10 /* TX OK history */ ++ UINT8 aucTxRateOkHis[STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM][2]; ++ UINT32 u4TxRateOkHisId; ++ ++#define STAT_CNT_INFO_MAX_RATE_ID (32) /* MCS0 ~ MCS31 */ ++ UINT32 aucTxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; ++ UINT32 aucRxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; ++ ++ UINT8 aucStateHis[100][3]; /* State history */ ++ UINT32 u4StateHisId; /* history ID */ ++} STAT_CNT_INFO_FW_T; ++ ++typedef struct _STAT_CNT_INFO_DRV_T { ++ ++ UINT32 u4NumOfTxFromOs; /* number of packets sent from OS */ ++ UINT32 u4NumOfTxQueFull; /* number of packets dropped due to queue full */ ++ UINT32 u4NumOfTxToFw; /* number of packets sent to firmware */ ++ ++ STAT_CNT_INFO_FW_T rFw; ++} STAT_CNT_INFO_DRV_T; ++ ++/* Define STA record structure */ ++struct _STA_RECORD_T { ++ LINK_ENTRY_T rLinkEntry; ++ UINT_8 ucIndex; /* Not modify it except initializing */ ++ ++ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; /* MAC address */ ++ ++ /* SAA/AAA */ ++ ENUM_AA_STATE_T eAuthAssocState; /* Store STATE Value used in SAA/AAA */ ++ UINT_8 ucAuthAssocReqSeqNum; ++ ++ ENUM_STA_TYPE_T eStaType; /* Indicate the role of this STA in ++ * the network (for example, P2P GO) ++ */ ++ ++ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ ++ ++ UINT_8 ucStaState; /* STATE_1,2,3 */ ++ ++ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer ++ * (may deduced from received BSS_DESC_T) ++ */ ++ UINT_8 ucDesiredPhyTypeSet; /* The match result by AND operation of peer's ++ * PhyTypeSet and ours. ++ */ ++ BOOLEAN fgHasBasicPhyType; /* A flag to indicate a Basic Phy Type which ++ * is used to generate some Phy Attribute IE ++ * (e.g. capability, MIB) during association. ++ */ ++ UINT_8 ucNonHTBasicPhyType; /* The Basic Phy Type chosen among the ++ * ucDesiredPhyTypeSet. ++ */ ++ ++ UINT_16 u2CapInfo; /* For Infra Mode, to store Capability Info. from Association Resp(SAA). ++ * For AP Mode, to store Capability Info. from Association Req(AAA). ++ */ ++ UINT_16 u2AssocId; /* For Infra Mode, to store AID from Association Resp(SAA). ++ * For AP Mode, to store the Assigned AID(AAA). ++ */ ++ ++ UINT_16 u2ListenInterval; /* Listen Interval from STA(AAA) */ ++ ++ UINT_16 u2DesiredNonHTRateSet; /* Our Current Desired Rate Set after ++ * match with STA's Operational Rate Set ++ */ ++ ++ UINT_16 u2OperationalRateSet; /* Operational Rate Set of peer BSS */ ++ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of peer BSS */ ++ ++ BOOLEAN fgIsMerging; /* For IBSS Mode, to indicate that Merge is ongoing */ ++ ++ BOOLEAN fgDiagnoseConnection; /* For Infra/AP Mode, to diagnose the Connection with ++ * this peer by sending ProbeReq/Null frame */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* 802.11n HT capabilities when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) is true */ ++ /* They have the same definition with fields of information element */ ++ /*------------------------------------------------------------------------------------------*/ ++ UINT_8 ucMcsSet; /* MCS0~7 rate set of peer BSS */ ++ BOOLEAN fgSupMcs32; /* MCS32 is supported by peer BSS */ ++ UINT_16 u2HtCapInfo; /* HT cap info field by HT cap IE */ ++ UINT_8 ucAmpduParam; /* Field A-MPDU Parameters in HT cap IE */ ++ UINT_16 u2HtExtendedCap; /* HT extended cap field by HT cap IE */ ++ UINT_32 u4TxBeamformingCap; /* TX beamforming cap field by HT cap IE */ ++ UINT_8 ucAselCap; /* ASEL cap field by HT cap IE */ ++ ++ UINT_8 ucRCPI; /* RCPI of peer */ ++ ++ UINT_8 ucDTIMPeriod; /* Target BSS's DTIM Period, we use this ++ * value for setup Listen Interval ++ * TODO(Kevin): TBD ++ */ ++ UINT_8 ucAuthAlgNum; /* For Infra/AP Mode, the Auth Algorithm Num used in Authentication(SAA/AAA) */ ++ BOOLEAN fgIsReAssoc; /* For Infra/AP Mode, to indicate ReAssoc Frame was in used(SAA/AAA) */ ++ ++ UINT_8 ucTxAuthAssocRetryCount; /* For Infra Mode, the Retry Count of TX Auth/Assod Frame(SAA) */ ++ UINT_8 ucTxAuthAssocRetryLimit; /* For Infra Mode, the Retry Limit of TX Auth/Assod Frame(SAA) */ ++ ++ UINT_16 u2StatusCode; /* Status of Auth/Assoc Req */ ++ UINT_16 u2ReasonCode; /* Reason that been Deauth/Disassoc */ ++ ++ P_IE_CHALLENGE_TEXT_T prChallengeText; /* Point to an allocated buffer for storing Challenge Text ++ * for Shared Key Authentication ++ */ ++ ++ TIMER_T rTxReqDoneOrRxRespTimer; /* For Infra Mode, a timer used to send a timeout event ++ * while waiting for TX request done or RX response. ++ */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* Power Management related fields (for STA/ AP/ P2P/ BOW power saving mode) */ ++ /*------------------------------------------------------------------------------------------*/ ++ BOOLEAN fgSetPwrMgtBit; /* For Infra Mode, to indicate that outgoing frame need toggle ++ * the Pwr Mgt Bit in its Frame Control Field. ++ */ ++ ++ BOOLEAN fgIsInPS; /* For AP Mode, to indicate the client PS state(PM). ++ * TRUE: In PS Mode; FALSE: In Active Mode. */ ++ ++ BOOLEAN fgIsInPsPollSP; /* For Infra Mode, to indicate we've sent a PS POLL to AP and start ++ * the PS_POLL Service Period(LP) ++ */ ++ ++ BOOLEAN fgIsInTriggerSP; /* For Infra Mode, to indicate we've sent a Trigger Frame to AP and start ++ * the Delivery Service Period(LP) ++ */ ++ ++ UINT_8 ucBmpDeliveryAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ ++ ++ UINT_8 ucBmpTriggerAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ ++ ++ UINT_8 ucUapsdSp; /* Max SP length */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ ++ BOOLEAN fgIsRtsEnabled; ++ ++ OS_SYSTIME rUpdateTime; /* (4) System Timestamp of Successful TX and RX */ ++ ++ OS_SYSTIME rLastJoinTime; /* (4) System Timestamp of latest JOIN process */ ++ ++ UINT_8 ucJoinFailureCount; /* Retry Count of JOIN process */ ++ ++ LINK_T arStaWaitQueue[STA_WAIT_QUEUE_NUM]; /* For TXM to defer pkt forwarding to MAC TX DMA */ ++ ++ UINT_16 au2CachedSeqCtrl[TID_NUM + 1]; /* Duplicate removal for HT STA on a per-TID basis ++ * ("+1" is for MMPDU and non-QoS) ++ */ ++ ++#if 0 ++ /* RXM */ ++ P_RX_BA_ENTRY_T aprRxBaTable[TID_NUM]; ++ ++ /* TXM */ ++ P_TX_BA_ENTRY_T aprTxBaTable[TID_NUM]; ++#endif ++ ++ FRAG_INFO_T rFragInfo[MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS]; ++ ++ SEC_INFO_T rSecInfo; /* The security state machine */ ++ ++ BOOLEAN fgPortBlock; /* The 802.1x Port Control flag */ ++ ++ BOOLEAN fgTransmitKeyExist; /* Unicast key exist for this STA */ ++ ++ UINT_8 ucWTEntry; ++ ++ BOOLEAN fgTxAmpduEn; /* Enable TX AMPDU for this Peer */ ++ BOOLEAN fgRxAmpduEn; /* Enable RX AMPDU for this Peer */ ++ ++ PUINT_8 pucAssocReqIe; ++ UINT_16 u2AssocReqIeLen; ++ /*------------------------------------------------------------------------------------------*/ ++ /* WMM/QoS related fields */ ++ /*------------------------------------------------------------------------------------------*/ ++ BOOLEAN fgIsQoS; /* If the STA is associated as a QSTA or QAP (for TX/RX) */ ++ BOOLEAN fgIsWmmSupported; /* If the peer supports WMM, set to TRUE (for association) */ ++ BOOLEAN fgIsUapsdSupported; /* Set according to the scan result (for association) */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* P2P related fields */ ++ /*------------------------------------------------------------------------------------------*/ ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_8 u2DevNameLen; ++ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; ++ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ ++ UINT_16 u2ConfigMethods; ++ ++ UINT_8 ucDeviceCap; ++ ++ UINT_8 ucSecondaryDevTypeCount; ++ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; ++ ++ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT]; ++#endif /* CFG_SUPPORT_P2P */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* QM related fields */ ++ /*------------------------------------------------------------------------------------------*/ ++ ++ UINT_8 ucFreeQuota; /* Per Sta flow controal. Valid when fgIsInPS is TRUE. ++ Change it for per Queue flow control */ ++ /* UINT_8 aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES]; */ /* used in future */ ++ UINT_8 ucFreeQuotaForDelivery; ++ UINT_8 ucFreeQuotaForNonDelivery; ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE && CFG_ENABLE_PER_STA_STATISTICS ++ UINT_32 u4TotalTxPktsNumber; ++ UINT_32 u4TotalTxPktsTime; ++ UINT_32 u4TotalTxPktsHifTime; ++ ++ UINT_32 u4MaxTxPktsTime; ++ UINT_32 u4MaxTxPktsHifTime; ++ ++ UINT_32 u4ThresholdCounter; ++ UINT_32 u4EnqeueuCounter; ++ UINT_32 u4DeqeueuCounter; ++ UINT_32 u4PrevIntCount; ++ UINT_32 u4ThisIntCount; ++ UINT_32 u4NoTcResource; ++#endif ++ ++#if 1 ++ /*------------------------------------------------------------------------------------------*/ ++ /* To be removed, this is to make que_mgt compilation success only */ ++ /*------------------------------------------------------------------------------------------*/ ++ /* When this STA_REC is in use, set to TRUE. */ ++ BOOLEAN fgIsValid; ++ ++ /* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ ++ QUE_T arTxQueue[NUM_OF_PER_STA_TX_QUEUES]; ++ ++ /* When this STA is in PS Mode, set to TRUE. */ ++ /* BOOLEAN fgIsPS; */ ++ ++ /* When this STA enters Power-Saving, FW will notify the driver with a Session ID */ ++ UINT_8 ucPsSessionID; ++ ++ BOOLEAN fgIsAp; ++ ++ /* Reorder Parameter reference table */ ++ P_RX_BA_ENTRY_T aprRxReorderParamRefTbl[CFG_RX_MAX_BA_TID_NUM]; ++#endif ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++ TIMINGMSMT_PARAM_T rWNMTimingMsmt; ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ ++ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ ++ ++ BOOLEAN flgTdlsIsInitiator; /* TRUE: the peer is the initiator */ ++ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ ++ BOOLEAN fgTdlsInSecurityMode; /* TRUE: security mode */ ++ PARAM_KEY_T rTdlsKeyTemp; /* temp to queue the key information */ ++ ++#define TDLS_SETUP_TIMEOUT_SEC 5 /* unit: second */ ++ OS_SYSTIME rTdlsSetupStartTime; /* time when link setup is started */ ++ ++ OS_SYSTIME rTdlsTxQuotaEmptyTime; /* time when TX quota is 0 */ ++ ++ STAT_CNT_INFO_DRV_T rTdlsStatistics; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#if (CFG_SUPPORT_STATISTICS == 1) ++#define STATS_ENV_TIMEOUT_SEC 10 /* unit: second */ ++ OS_SYSTIME rStatsEnvTxPeriodLastTime; ++ ++#define STATS_ENV_TX_CNT_REPORT_TRIGGER 2500 /* 6Mbps */ ++#define STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC 5 /* unit: second */ ++ OS_SYSTIME rStatsEnvTxLastTime; ++ UINT32 u4StatsEnvTxCnt; ++ ++ UINT32 u4NumOfNoTxQuota; ++ ++ UINT32 u4RxReorderFallAheadCnt; ++ UINT32 u4RxReorderFallBehindCnt; ++ UINT32 u4RxReorderHoleCnt; ++ UINT32 u4RxReorderHoleTimeoutCnt; ++ ++ UINT32 u4StatsRxPassToOsCnt; ++ ++ /* delay from HIF to pass to OS: us */ ++#define STATS_STAY_INT_BYTE_THRESHOLD 500 ++ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; ++ ++ UINT8 ucStatsGenDisplayCnt; ++#endif /* CFG_SUPPORT_STATISTICS */ ++}; ++ ++#if 0 ++/* use nic_tx.h instead */ ++/* MSDU_INFO and SW_RFB structure */ ++typedef struct _MSDU_INFO_T { ++ ++ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ ++ ++ LINK_ENTRY_T rLinkEntry; ++ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ ++ ++ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ ++ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ ++ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ ++ UINT_8 ucTID; /* Traffic Identification */ ++ ++ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ ++ UINT_8 ucMacHeaderLength; ++ UINT_16 u2PayloadLength; ++ PUINT_8 pucMacHeader; /* 802.11 header */ ++ PUINT_8 pucPayload; /* 802.11 payload */ ++ ++ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ ++ P_STA_RECORD_T prStaRec; ++ ++#if CFG_PROFILE_BUFFER_TRACING ++ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; ++ UINT_32 rActivityTime[2]; ++#endif ++#if DBG && CFG_BUFFER_FREE_CHK ++ BOOLEAN fgBufferInSource; ++#endif ++ ++ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ ++ ++ /* 4 -----------------------Non-Common ------------------------- */ ++ /* TODO: move flags to ucControlFlag */ ++ ++ BOOLEAN fgIs1xFrame; /* Set to TRUE for 802.1x frame */ ++ ++ /* TXM: For TX Done handling, callback function & parameter (5) */ ++ BOOLEAN fgIsTxFailed; /* Set to TRUE if transmission failure */ ++ ++ PFN_TX_DONE_HANDLER pfTxDoneHandler; ++ ++ UINT_64 u8TimeStamp; /* record the TX timestamp */ ++ ++ /* TXM: For PS forwarding control (per-STA flow control) */ ++ UINT_8 ucPsForwardingType; /* Delivery-enabled, non-delivery-enabled, non-PS */ ++ UINT_8 ucPsSessionID; /* The Power Save session id for PS forwarding control */ ++ ++ /* TXM: For MAC TX DMA operations */ ++ UINT_8 ucMacTxQueIdx; /* MAC TX queue: AC0-AC6, BCM, or BCN */ ++ BOOLEAN fgNoAck; /* Set to true if Ack is not required for this packet */ ++ BOOLEAN fgBIP; /* Set to true if BIP is used for this packet */ ++ UINT_8 ucFragTotalCount; ++ UINT_8 ucFragFinishedCount; ++ UINT_16 u2FragThreshold; /* Fragmentation threshold without WLAN Header & FCS */ ++ BOOLEAN fgFixedRate; /* If a fixed rate is used, set to TRUE. */ ++ UINT_8 ucFixedRateCode; /* The rate code copied to MAC TX Desc */ ++ UINT_8 ucFixedRateRetryLimit; /* The retry limit when a fixed rate is used */ ++ BOOLEAN fgIsBmcQueueEnd; /* Set to true if this packet is the end of BMC */ ++ ++ /* TXM: For flushing ACL frames */ ++ UINT_16 u2PalLLH; /* 802.11 PAL LLH */ ++ /* UINT_16 u2LLH; */ ++ UINT_16 u2ACLSeq; /* u2LLH+u2ACLSeq for AM HCI flush ACL frame */ ++ ++ /* TXM for retransmitting a flushed packet */ ++ BOOLEAN fgIsSnAssigned; ++ UINT_16 u2SequenceNumber; /* To remember the Sequence Control field of this MPDU */ ++ ++} MSDU_INFO_T, *P_MSDU_INFO_T; ++#endif ++ ++#if 0 ++/* nic_rx.h */ ++typedef struct _SW_RFB_T { ++ ++ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ ++ ++ LINK_ENTRY_T rLinkEntry; ++ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ ++ ++ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ ++ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ ++ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ ++ UINT_8 ucTID; /* Traffic Identification */ ++ ++ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ ++ UINT_8 ucMacHeaderLength; ++ UINT_16 u2PayloadLength; ++ PUINT_8 pucMacHeader; /* 802.11 header */ ++ PUINT_8 pucPayload; /* 802.11 payload */ ++ ++ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ ++ P_STA_RECORD_T prStaRec; ++ ++#if CFG_PROFILE_BUFFER_TRACING ++ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; ++ UINT_32 rActivityTime[2]; ++#endif ++#if DBG && CFG_BUFFER_FREE_CHK ++ BOOLEAN fgBufferInSource; ++#endif ++ ++ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ ++ ++ /* 4 -----------------------Non-Common ------------------------- */ ++ ++ /* For composing the HIF RX Header (TODO: move flags to ucControlFlag) */ ++ PUINT_8 pucHifRxPacket; /* Pointer to the Response packet to HIF RX0 or RX1 */ ++ UINT_16 u2HifRxPacketLength; ++ UINT_8 ucHeaderOffset; ++ UINT_8 ucHifRxPortIndex; ++ ++ UINT_16 u2SequenceControl; ++ BOOLEAN fgIsA4Frame; /* (For MAC RX packet parsing) set to TRUE if 4 addresses are present */ ++ BOOLEAN fgIsBAR; ++ BOOLEAN fgIsQoSData; ++ BOOLEAN fgIsAmsduSubframe; /* Set to TRUE for A-MSDU Subframe */ ++ ++ /* For HIF RX DMA Desc */ ++ BOOLEAN fgTUChecksumCheckRequired; ++ BOOLEAN fgIPChecksumCheckRequired; ++ UINT_8 ucEtherTypeOffset; ++ ++} SW_RFB_T, *P_SW_RFB_T; ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++P_MSDU_INFO_T cnmMgtPktAlloc(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); ++ ++VOID cnmMgtPktFree(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID cnmMemInit(IN P_ADAPTER_T prAdapter); ++ ++PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length); ++ ++VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory); ++ ++VOID cnmStaRecInit(IN P_ADAPTER_T prAdapter); ++ ++VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter); ++ ++P_STA_RECORD_T cnmStaRecAlloc(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex); ++ ++VOID cnmStaRecFree(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSyncToChip); ++ ++VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip); ++ ++P_STA_RECORD_T cnmGetStaRecByIndex(IN P_ADAPTER_T prAdapter, IN UINT_8 ucIndex); ++ ++P_STA_RECORD_T cnmGetStaRecByAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex, IN UINT_8 aucPeerMACAddress[]); ++ ++VOID cnmStaRecResetStatus(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++VOID cnmStaRecChangeState(IN P_ADAPTER_T prAdapter, IN OUT P_STA_RECORD_T prStaRec, IN UINT_8 ucNewState); ++ ++P_STA_RECORD_T ++cnmStaTheTypeGet(P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this for porting driver to different RTOS. ++ */ ++static inline VOID cnmMemDataTypeCheck(VOID) ++{ ++#if 0 ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == 0); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == OFFSET_OF(SW_RFB_T, rLinkEntry)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucBuffer) == OFFSET_OF(SW_RFB_T, pucBuffer)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucBufferSource) == OFFSET_OF(SW_RFB_T, ucBufferSource)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucMacHeader) == OFFSET_OF(SW_RFB_T, pucMacHeader)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucMacHeaderLength) == ++ OFFSET_OF(SW_RFB_T, ucMacHeaderLength)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucPayload) == OFFSET_OF(SW_RFB_T, pucPayload)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, u2PayloadLength) == OFFSET_OF(SW_RFB_T, u2PayloadLength)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, prStaRec) == OFFSET_OF(SW_RFB_T, prStaRec)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucNetworkTypeIndex) == ++ OFFSET_OF(SW_RFB_T, ucNetworkTypeIndex)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTID) == OFFSET_OF(SW_RFB_T, ucTID)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgIs802_11Frame) == OFFSET_OF(SW_RFB_T, fgIs802_11Frame)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucControlFlag) == OFFSET_OF(SW_RFB_T, ucControlFlag)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rArrivalTime) == OFFSET_OF(SW_RFB_T, rArrivalTime)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTC) == OFFSET_OF(SW_RFB_T, ucTC)); ++ ++#if CFG_PROFILE_BUFFER_TRACING ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, eActivity[0]) == OFFSET_OF(SW_RFB_T, eActivity[0])); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rActivityTime[0]) == ++ OFFSET_OF(SW_RFB_T, rActivityTime[0])); ++#endif ++ ++#if DBG && CFG_BUFFER_FREE_CHK ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgBufferInSource) == ++ OFFSET_OF(SW_RFB_T, fgBufferInSource)); ++#endif ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(STA_RECORD_T, rLinkEntry) == 0); ++ ++ return; ++#endif ++} ++#endif /* _lint */ ++ ++#endif /* _CNM_MEM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h +new file mode 100644 +index 000000000000..cc5d0fa1adfc +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h +@@ -0,0 +1,169 @@ ++/* ++** Id: @(#) ++*/ ++ ++/*! \file "cnm_scan.h" ++ \brief ++ ++*/ ++ ++/* ++** Log: cnm_scan.h ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * remove unused definitions. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function prototype of cnmScanInit() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_SCAN_H ++#define _CNM_SCAN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define SCN_CHANNEL_DWELL_TIME_MIN_MSEC 12 ++#define SCN_CHANNEL_DWELL_TIME_EXT_MSEC 98 ++ ++#define SCN_TOTAL_PROBEREQ_NUM_FOR_FULL 3 ++#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_FULL 1 ++ ++#define SCN_TOTAL_PROBEREQ_NUM_FOR_PARTIAL 2 ++#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_PARTIAL 1 ++ ++#define SCN_INTERLACED_CHANNEL_GROUPS_NUM 3 /* Used by partial scan */ ++ ++#define SCN_PARTIAL_SCAN_NUM 3 ++ ++#define SCN_PARTIAL_SCAN_IDLE_MSEC 100 ++ ++#define MAXIMUM_OPERATION_CHANNEL_LIST 46 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* The type of Scan Source */ ++typedef enum _ENUM_SCN_REQ_SOURCE_T { ++ SCN_REQ_SOURCE_HEM = 0, ++ SCN_REQ_SOURCE_NET_FSM, ++ SCN_REQ_SOURCE_ROAMING, /* ROAMING Module is independent of AIS FSM */ ++ SCN_REQ_SOURCE_OBSS, /* 2.4G OBSS scan */ ++ SCN_REQ_SOURCE_NUM ++} ENUM_SCN_REQ_SOURCE_T, *P_ENUM_SCN_REQ_SOURCE_T; ++ ++typedef enum _ENUM_SCAN_PROFILE_T { ++ SCAN_PROFILE_FULL = 0, ++ SCAN_PROFILE_PARTIAL, ++ SCAN_PROFILE_VOIP, ++ SCAN_PROFILE_FULL_2G4, ++ SCAN_PROFILE_NUM ++} ENUM_SCAN_PROFILE_T, *P_ENUM_SCAN_PROFILE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if 0 ++VOID cnmScanInit(VOID); ++ ++VOID cnmScanRunEventScanRequest(IN P_MSG_HDR_T prMsgHdr); ++ ++BOOLEAN cnmScanRunEventScanAbort(IN P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmScanProfileSelection(VOID); ++ ++VOID cnmScanProcessStart(VOID); ++ ++VOID cnmScanProcessStop(VOID); ++ ++VOID cnmScanRunEventReqAISAbsDone(IN P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmScanRunEventCancelAISAbsDone(IN P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmScanPartialScanTimeout(UINT_32 u4Param); ++ ++VOID cnmScanRunEventScnFsmComplete(IN P_MSG_HDR_T prMsgHdr); ++#endif ++ ++#endif /* _CNM_SCAN_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h +new file mode 100644 +index 000000000000..a2ed9cd02fed +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h +@@ -0,0 +1,235 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_timer.h#1 ++*/ ++ ++/*! \file cnm_timer.h ++ \brief Declaration of timer obj and related timer macro for setup time out ++ event. ++ ++ In this file we declare the timer object and provide several macro for ++ Protocol functional blocks to setup their own time out event. ++*/ ++ ++/* ++** Log: cnm_timer.h ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Return timer token back to COS when entering wait off state ++ * ++ * 01 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb ++ * ++ * 01 06 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix system time is 32KHz instead of 1ms ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * add the copy time function ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix LINT warnning ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_TIMER_H ++#define _CNM_TIMER_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#undef MSEC_PER_SEC ++#define MSEC_PER_SEC 1000 ++#undef USEC_PER_MSEC ++#define USEC_PER_MSEC 1000 ++#define USEC_PER_TU 1024 /* microsecond */ ++ ++#define MSEC_PER_MIN (60 * MSEC_PER_SEC) ++ ++#define MGMT_MAX_TIMEOUT_INTERVAL ((UINT_32)0x7fffffff) ++ ++#define WAKE_LOCK_MAX_TIME 5 /* Unit: sec */ ++ ++/* If WAKE_LOCK_MAX_TIME is too large, the whole system may always keep awake ++ * because of periodic timer of OBSS scanning ++ */ ++#if (WAKE_LOCK_MAX_TIME >= OBSS_SCAN_MIN_INTERVAL) ++#error WAKE_LOCK_MAX_TIME is too large ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef VOID(*PFN_MGMT_TIMEOUT_FUNC) (P_ADAPTER_T, ULONG); ++ ++typedef struct _TIMER_T { ++ LINK_ENTRY_T rLinkEntry; ++ OS_SYSTIME rExpiredSysTime; ++ UINT_16 u2Minutes; ++ UINT_16 u2Reserved; ++ ULONG ulData; ++ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; ++} TIMER_T, *P_TIMER_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Check if time "a" is before time "b" */ ++/* In 32-bit variable, 0x00000001~0x7fffffff -> positive number, ++ * 0x80000000~0xffffffff -> negative number ++ */ ++#define TIME_BEFORE_64bit(a, b) (a < b) ++ ++#define TIME_BEFORE(a, b) ((UINT_32)((UINT_32)(a) - (UINT_32)(b)) > 0x7fffffff) ++ ++/* #define TIME_BEFORE(a,b) ((INT_32)((INT_32)(b) - (INT_32)(a)) > 0) ++ * may cause UNexpect result between Free build and Check build for WinCE ++ */ ++ ++#define TIME_AFTER(a, b) TIME_BEFORE(b, a) ++ ++#define SYSTIME_TO_SEC(_systime) ((_systime) / KAL_HZ) ++#define SEC_TO_SYSTIME(_sec) ((_sec) * KAL_HZ) ++ ++/* The macros to convert second & millisecond */ ++#define MSEC_TO_SEC(_msec) ((_msec) / MSEC_PER_SEC) ++#define SEC_TO_MSEC(_sec) ((UINT_32)(_sec) * MSEC_PER_SEC) ++ ++/* The macros to convert millisecond & microsecond */ ++#define USEC_TO_MSEC(_usec) ((_usec) / USEC_PER_MSEC) ++#define MSEC_TO_USEC(_msec) ((UINT_32)(_msec) * USEC_PER_MSEC) ++ ++/* The macros to convert TU & microsecond, TU & millisecond */ ++#define TU_TO_USEC(_tu) ((_tu) * USEC_PER_TU) ++#define TU_TO_MSEC(_tu) USEC_TO_MSEC(TU_TO_USEC(_tu)) ++ ++/* The macros to convert TU & & OS system time, round up by 0.5 */ ++#define TU_TO_SYSTIME(_tu) MSEC_TO_SYSTIME(TU_TO_MSEC(_tu)) ++#define SYSTIME_TO_TU(_systime) \ ++ ((SYSTIME_TO_USEC(_systime) + ((USEC_PER_TU / 2) - 1)) / USEC_PER_TU) ++ ++/* The macros to convert OS system time & microsecond */ ++#define SYSTIME_TO_USEC(_systime) (SYSTIME_TO_MSEC(_systime) * USEC_PER_MSEC) ++ ++/* The macro to get the current OS system time */ ++#define GET_CURRENT_SYSTIME(_systime_p) {*(_systime_p) = kalGetTimeTick(); } ++ ++/* The macro to copy the system time */ ++#define COPY_SYSTIME(_destTime, _srcTime) {(_destTime) = (_srcTime); } ++ ++/* The macro to get the system time difference between t1 and t2 (t1 - t2) */ ++/* #define GET_SYSTIME_DIFFERENCE(_time1, _time2, _diffTime) \ ++ (_diffTime) = (_time1) - (_time2) */ ++ ++/* The macro to check for the expiration, if TRUE means _currentTime >= _expirationTime */ ++#define CHECK_FOR_EXPIRATION(_currentTime, _expirationTime) \ ++ (((UINT_32)(_currentTime) - (UINT_32)(_expirationTime)) <= 0x7fffffffUL) ++ ++/* The macro to check for the timeout */ ++#define CHECK_FOR_TIMEOUT(_currentTime, _timeoutStartingTime, _timeout) \ ++ CHECK_FOR_EXPIRATION((_currentTime), ((_timeoutStartingTime) + (_timeout))) ++ ++/* The macro to set the expiration time with a specified timeout *//* Watch out for round up. */ ++#define SET_EXPIRATION_TIME(_expirationTime, _timeout) \ ++ { \ ++ GET_CURRENT_SYSTIME(&(_expirationTime)); \ ++ (_expirationTime) += (OS_SYSTIME)(_timeout); \ ++ } ++ ++#define timerRenewTimer(adapter, tmr, interval) \ ++ timerStartTimer(adapter, tmr, interval, (tmr)->function, (tmr)->data) ++ ++#define MGMT_INIT_TIMER(_adapter_p, _timer, _callbackFunc) \ ++ timerInitTimer(_adapter_p, &(_timer), (ULONG)(_callbackFunc)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter); ++ ++VOID ++cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData); ++ ++VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer); ++ ++VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs); ++ ++VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++static inline INT_32 timerPendingTimer(IN P_TIMER_T prTimer) ++{ ++ ASSERT(prTimer); ++ ++ return prTimer->rLinkEntry.prNext != NULL; ++} ++ ++#endif /* _CNM_TIMER_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h +new file mode 100644 +index 000000000000..868de4a6c40a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h +@@ -0,0 +1,446 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/hem_mbox.h#2 ++*/ ++ ++/*! \file hem_mbox.h ++ \brief ++ ++*/ ++ ++/* ++** Log: hem_mbox.h ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for ++ * more than one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID ++ * support as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. ++ * cnm_timer[WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Add invitation support. ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * eliminate unused parameters for SAA-FSM ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Remove unused message ID ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some message ID for P2P FSM under provisioning phase. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add Message Event ID for P2P Module. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Check-in P2P Device Discovery Feature. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * remove unused mailbox message definitions. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * message table should not be commented out by compilation option without modifying header file ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_QOS_ACTION_FRAME ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Develop partial DPD code ++ * ++ * 02 11 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added MID_RXM_MQM_QOS_ACTION_FRAME for RXM to indicate QoS Action frames to MQM ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename the parameter of mboxDummy() ++ * ++ * Dec 2 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove Dummy MSG ID ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add JOIN REQ related MSG ID ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add AIS ABORT MSG ID ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add SCN MSG IDs ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _HEM_MBOX_H ++#define _HEM_MBOX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Message IDs */ ++typedef enum _ENUM_MSG_ID_T { ++ MID_MNY_CNM_CH_REQ, /* MANY notify CNM to obtain channel privilege */ ++ MID_MNY_CNM_CH_ABORT, /* MANY notify CNM to abort/release channel privilege */ ++ ++ MID_CNM_AIS_CH_GRANT, /* CNM notify AIS for indicating channel granted */ ++ MID_CNM_P2P_CH_GRANT, /* CNM notify P2P for indicating channel granted */ ++ MID_CNM_BOW_CH_GRANT, /* CNM notify BOW for indicating channel granted */ ++ ++ /*--------------------------------------------------*/ ++ /* SCN Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_AIS_SCN_SCAN_REQ, /* AIS notify SCN for starting scan */ ++ MID_AIS_SCN_SCAN_REQ_V2, /* AIS notify SCN for starting scan with multiple SSID support */ ++ MID_AIS_SCN_SCAN_CANCEL, /* AIS notify SCN for cancelling scan */ ++ MID_P2P_SCN_SCAN_REQ, /* P2P notify SCN for starting scan */ ++ MID_P2P_SCN_SCAN_REQ_V2, /* P2P notify SCN for starting scan with multiple SSID support */ ++ MID_P2P_SCN_SCAN_CANCEL, /* P2P notify SCN for cancelling scan */ ++ MID_BOW_SCN_SCAN_REQ, /* BOW notify SCN for starting scan */ ++ MID_BOW_SCN_SCAN_REQ_V2, /* BOW notify SCN for starting scan with multiple SSID support */ ++ MID_BOW_SCN_SCAN_CANCEL, /* BOW notify SCN for cancelling scan */ ++ MID_RLM_SCN_SCAN_REQ, /* RLM notify SCN for starting scan (OBSS-SCAN) */ ++ MID_RLM_SCN_SCAN_REQ_V2, /* RLM notify SCN for starting scan (OBSS-SCAN) with multiple SSID support */ ++ MID_RLM_SCN_SCAN_CANCEL, /* RLM notify SCN for cancelling scan (OBSS-SCAN) */ ++ MID_SCN_AIS_SCAN_DONE, /* SCN notify AIS for scan completion */ ++ MID_SCN_P2P_SCAN_DONE, /* SCN notify P2P for scan completion */ ++ MID_SCN_BOW_SCAN_DONE, /* SCN notify BOW for scan completion */ ++ MID_SCN_RLM_SCAN_DONE, /* SCN notify RLM for scan completion (OBSS-SCAN) */ ++ ++ /*--------------------------------------------------*/ ++ /* AIS Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_OID_AIS_FSM_JOIN_REQ, /* OID/IOCTL notify AIS for join */ ++ MID_OID_AIS_FSM_ABORT, /* OID/IOCTL notify AIS for abort */ ++ MID_AIS_SAA_FSM_START, /* AIS notify SAA for Starting authentication/association fsm */ ++ MID_AIS_SAA_FSM_ABORT, /* AIS notify SAA for Aborting authentication/association fsm */ ++ MID_SAA_AIS_JOIN_COMPLETE, /* SAA notify AIS for indicating join complete */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /*--------------------------------------------------*/ ++ /* BOW Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_BOW_SAA_FSM_START, /* BOW notify SAA for Starting authentication/association fsm */ ++ MID_BOW_SAA_FSM_ABORT, /* BOW notify SAA for Aborting authentication/association fsm */ ++ MID_SAA_BOW_JOIN_COMPLETE, /* SAA notify BOW for indicating join complete */ ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /*--------------------------------------------------*/ ++ /* P2P Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_P2P_SAA_FSM_START, /* P2P notify SAA for Starting authentication/association fsm */ ++ MID_P2P_SAA_FSM_ABORT, /* P2P notify SAA for Aborting authentication/association fsm */ ++ MID_SAA_P2P_JOIN_COMPLETE, /* SAA notify P2P for indicating join complete */ ++ ++ MID_MNY_P2P_FUN_SWITCH, /* Enable P2P FSM. */ ++ MID_MNY_P2P_DEVICE_DISCOVERY, /* Start device discovery. */ ++ MID_MNY_P2P_CONNECTION_REQ, /* Connection request. */ ++ MID_MNY_P2P_CONNECTION_ABORT, /* Abort connection request, P2P FSM return to IDLE. */ ++ MID_MNY_P2P_BEACON_UPDATE, ++ MID_MNY_P2P_STOP_AP, ++ MID_MNY_P2P_CHNL_REQ, ++ MID_MNY_P2P_CHNL_ABORT, ++ MID_MNY_P2P_MGMT_TX, ++ MID_MNY_P2P_GROUP_DISSOLVE, ++ MID_MNY_P2P_MGMT_FRAME_REGISTER, ++ MID_MNY_P2P_NET_DEV_REGISTER, ++ MID_MNY_P2P_START_AP, ++ MID_MNY_P2P_MGMT_FRAME_UPDATE, ++ MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, ++#if CFG_SUPPORT_WFD ++ MID_MNY_P2P_WFD_CFG_UPDATE, ++#endif ++#endif ++ ++#if CFG_SUPPORT_ADHOC ++ MID_SCN_AIS_FOUND_IBSS, /* SCN notify AIS that an IBSS Peer has been found and can merge into */ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ MID_SAA_AIS_FSM_ABORT, /* SAA notify AIS for indicating deauthentication/disassociation */ ++ ++ /*--------------------------------------------------*/ ++ /* AIS MGMT-TX Support */ ++ /*--------------------------------------------------*/ ++ MID_MNY_AIS_REMAIN_ON_CHANNEL, ++ MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, ++ MID_MNY_AIS_MGMT_TX, ++ ++ MID_TOTAL_NUM ++} ENUM_MSG_ID_T, *P_ENUM_MSG_ID_T; ++ ++/* Message header of inter-components */ ++struct _MSG_HDR_T { ++ LINK_ENTRY_T rLinkEntry; ++ ENUM_MSG_ID_T eMsgId; ++}; ++ ++typedef VOID(*PFN_MSG_HNDL_FUNC) (P_ADAPTER_T, P_MSG_HDR_T); ++ ++typedef struct _MSG_HNDL_ENTRY { ++ ENUM_MSG_ID_T eMsgId; ++ PFN_MSG_HNDL_FUNC pfMsgHndl; ++} MSG_HNDL_ENTRY_T, *P_MSG_HNDL_ENTRY_T; ++ ++typedef enum _EUNM_MSG_SEND_METHOD_T { ++ MSG_SEND_METHOD_BUF = 0, /* Message is put in the queue and will be ++ executed when mailbox is checked. */ ++ MSG_SEND_METHOD_UNBUF /* The handler function is called immediately ++ in the same context of the sender */ ++} EUNM_MSG_SEND_METHOD_T, *P_EUNM_MSG_SEND_METHOD_T; ++ ++typedef enum _ENUM_MBOX_ID_T { ++ MBOX_ID_0 = 0, ++ MBOX_ID_TOTAL_NUM ++} ENUM_MBOX_ID_T, *P_ENUM_MBOX_ID_T; ++ ++/* Define Mailbox structure */ ++typedef struct _MBOX_T { ++ LINK_T rLinkHead; ++} MBOX_T, *P_MBOX_T; ++ ++typedef struct _MSG_SAA_FSM_START_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ P_STA_RECORD_T prStaRec; ++} MSG_SAA_FSM_START_T, *P_MSG_SAA_FSM_START_T; ++ ++typedef struct _MSG_SAA_FSM_COMP_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ WLAN_STATUS rJoinStatus; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prSwRfb; ++} MSG_SAA_FSM_COMP_T, *P_MSG_SAA_FSM_COMP_T; ++ ++typedef struct _MSG_SAA_FSM_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ P_STA_RECORD_T prStaRec; ++} MSG_SAA_FSM_ABORT_T, *P_MSG_SAA_FSM_ABORT_T; ++ ++typedef struct _MSG_CONNECTION_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++} MSG_CONNECTION_ABORT_T, *P_MSG_CONNECTION_ABORT_T; ++ ++typedef struct _MSG_REMAIN_ON_CHANNEL_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eSco; ++ UINT_8 ucChannelNum; ++ UINT_32 u4DurationMs; ++ UINT_64 u8Cookie; ++} MSG_REMAIN_ON_CHANNEL_T, *P_MSG_REMAIN_ON_CHANNEL_T; ++ ++typedef struct _MSG_CANCEL_REMAIN_ON_CHANNEL_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_64 u8Cookie; ++} MSG_CANCEL_REMAIN_ON_CHANNEL_T, *P_MSG_CANCEL_REMAIN_ON_CHANNEL_T; ++ ++typedef struct _MSG_MGMT_TX_REQUEST_T { ++ MSG_HDR_T rMsgHdr; ++ P_MSDU_INFO_T prMgmtMsduInfo; ++ UINT_64 u8Cookie; /* For indication. */ ++ BOOLEAN fgNoneCckRate; ++ BOOLEAN fgIsWaitRsp; ++} MSG_MGMT_TX_REQUEST_T, *P_MSG_MGMT_TX_REQUEST_T; ++ ++/* specific message data types */ ++typedef MSG_SAA_FSM_START_T MSG_JOIN_REQ_T, *P_MSG_JOIN_REQ_T; ++typedef MSG_SAA_FSM_COMP_T MSG_JOIN_COMP_T, *P_MSG_JOIN_COMP_T; ++typedef MSG_SAA_FSM_ABORT_T MSG_JOIN_ABORT_T, *P_MSG_JOIN_ABORT_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); ++ ++VOID ++mboxSendMsg(IN P_ADAPTER_T prAdapter, ++ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod); ++ ++VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); ++ ++VOID mboxInitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID mboxDestroy(IN P_ADAPTER_T prAdapter); ++ ++VOID mboxDummy(IN P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _HEM_MBOX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h +new file mode 100644 +index 000000000000..88b99222133f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h +@@ -0,0 +1,148 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/include/mgmt/hs20.h#2 ++*/ ++ ++/*! \file hs20.h ++ \brief This file contains the function declaration for hs20.c. ++*/ ++ ++/* ++** Log: ++ * ++ */ ++ ++#ifndef _HS20_H ++#define _HS20_H ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define BSSID_POOL_MAX_SIZE 8 ++#define HS20_SIGMA_SCAN_RESULT_TIMEOUT 30 /* sec */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++/*For GTK Frame Filter*/ ++typedef struct _IPV4_NETWORK_ADDRESS_LIST { ++ UINT_8 ucAddrCount; ++ IPV4_NETWORK_ADDRESS arNetAddr[1]; ++} IPV4_NETWORK_ADDRESS_LIST, *P_IPV4_NETWORK_ADDRESS_LIST; ++#endif ++ ++/* Entry of BSSID Pool - For SIGMA Test */ ++typedef struct _BSSID_ENTRY_T { ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++} BSSID_ENTRY_T, P_HS20_BSSID_POOL_ENTRY_T; ++ ++struct _HS20_INFO_T { ++ ++ /*Hotspot 2.0 Information */ ++ UINT_8 aucHESSID[MAC_ADDR_LEN]; ++ UINT_8 ucAccessNetworkOptions; ++ UINT_8 ucVenueGroup; /* VenueInfo - Group */ ++ UINT_8 ucVenueType; ++ UINT_8 ucHotspotConfig; ++ ++ /*Roaming Consortium Information */ ++ /* PARAM_HS20_ROAMING_CONSORTIUM_INFO rRCInfo; */ ++ ++ /*Hotspot 2.0 dummy AP Info */ ++ ++ /*Time Advertisement Information */ ++ /* UINT_32 u4UTCOffsetTime; */ ++ /* UINT_8 aucTimeZone[ELEM_MAX_LEN_TIME_ZONE]; */ ++ /* UINT_8 ucLenTimeZone; */ ++ ++ /* For SIGMA Test */ ++ /* BSSID Pool */ ++ BSSID_ENTRY_T arBssidPool[BSSID_POOL_MAX_SIZE]; ++ UINT_8 ucNumBssidPoolEntry; ++ BOOLEAN fgIsHS2SigmaMode; ++ ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/*For GTK Frame Filter*/ ++#if DBG ++#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ ++ { \ ++ UINT_32 u4Size = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + \ ++ (((_prAddrList)->ucAddrCount) * sizeof(IPV4_NETWORK_ADDRESS)); \ ++ kalMemFree((_prAddrList), VIR_MEM_TYPE, u4Size); \ ++ (_prAddrList) = NULL; \ ++ } ++#else ++#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ ++ { \ ++ kalMemFree((_prAddrList), VIR_MEM_TYPE, 0); \ ++ (_prAddrList) = NULL; \ ++ } ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); ++ ++VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); ++ ++UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID); ++ ++WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE); ++ ++BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); ++ ++BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); ++#endif ++ ++BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); ++ ++BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); ++ ++WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); ++ ++#endif ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h +new file mode 100644 +index 000000000000..cb89fd8793ee +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h +@@ -0,0 +1,153 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/mib.h#1 ++*/ ++ ++/*! \file mib.h ++ \brief This file contains the IEEE 802.11 family related MIB definition ++ for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: mib.h ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _MIB_H ++#define _MIB_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Entry in SMT AuthenticationAlgorithms Table: dot11AuthenticationAlgorithmsEntry */ ++typedef struct _DOT11_AUTHENTICATION_ALGORITHMS_ENTRY { ++ BOOLEAN dot11AuthenticationAlgorithmsEnable; /* dot11AuthenticationAlgorithmsEntry 3 */ ++} DOT11_AUTHENTICATION_ALGORITHMS_ENTRY, *P_DOT11_AUTHENTICATION_ALGORITHMS_ENTRY; ++ ++/* Entry in SMT dot11RSNAConfigPairwiseCiphersTalbe Table: dot11RSNAConfigPairwiseCiphersEntry */ ++typedef struct _DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY { ++ UINT_32 dot11RSNAConfigPairwiseCipher; /* dot11RSNAConfigPairwiseCiphersEntry 2 */ ++ BOOLEAN dot11RSNAConfigPairwiseCipherEnabled; /* dot11RSNAConfigPairwiseCiphersEntry 3 */ ++} DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY, *P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY; ++ ++/* Entry in SMT dot11RSNAConfigAuthenticationSuitesTalbe Table: dot11RSNAConfigAuthenticationSuitesEntry */ ++typedef struct _DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY { ++ UINT_32 dot11RSNAConfigAuthenticationSuite; /* dot11RSNAConfigAuthenticationSuitesEntry 2 */ ++ BOOLEAN dot11RSNAConfigAuthenticationSuiteEnabled; /* dot11RSNAConfigAuthenticationSuitesEntry 3 */ ++} DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY, *P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY; ++ ++/* ----- IEEE 802.11 MIB Major sections ----- */ ++typedef struct _IEEE_802_11_MIB_T { ++ /* dot11PrivacyTable (dot11smt 5) */ ++ UINT_8 dot11WEPDefaultKeyID; /* dot11PrivacyEntry 2 */ ++ BOOLEAN dot11TranmitKeyAvailable; ++ UINT_32 dot11WEPICVErrorCount; /* dot11PrivacyEntry 5 */ ++ UINT_32 dot11WEPExcludedCount; /* dot11PrivacyEntry 6 */ ++ ++ /* dot11RSNAConfigTable (dot11smt 8) */ ++ UINT_32 dot11RSNAConfigGroupCipher; /* dot11RSNAConfigEntry 4 */ ++ ++ /* dot11RSNAConfigPairwiseCiphersTable (dot11smt 9) */ ++ DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY dot11RSNAConfigPairwiseCiphersTable[MAX_NUM_SUPPORTED_CIPHER_SUITES]; ++ ++ /* dot11RSNAConfigAuthenticationSuitesTable (dot11smt 10) */ ++ DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY ++ dot11RSNAConfigAuthenticationSuitesTable[MAX_NUM_SUPPORTED_AKM_SUITES]; ++ ++#if 0 /* SUPPORT_WAPI */ ++ BOOLEAN fgWapiKeyInstalled; ++ PARAM_WPI_KEY_T rWapiPairwiseKey[2]; ++ BOOLEAN fgPairwiseKeyUsed[2]; ++ UINT_8 ucWpiActivedPWKey; /* Must be 0 or 1, by wapi spec */ ++ PARAM_WPI_KEY_T rWapiGroupKey[2]; ++ BOOLEAN fgGroupKeyUsed[2]; ++#endif ++} IEEE_802_11_MIB_T, *P_IEEE_802_11_MIB_T; ++ ++/* ------------------ IEEE 802.11 non HT PHY characteristics ---------------- */ ++typedef const struct _NON_HT_PHY_ATTRIBUTE_T { ++ UINT_16 u2SupportedRateSet; ++ ++ BOOLEAN fgIsShortPreambleOptionImplemented; ++ ++ BOOLEAN fgIsShortSlotTimeOptionImplemented; ++ ++} NON_HT_PHY_ATTRIBUTE_T, *P_NON_HT_PHY_ATTRIBUTE_T; ++ ++typedef const struct _NON_HT_ADHOC_MODE_ATTRIBUTE_T { ++ ++ ENUM_PHY_TYPE_INDEX_T ePhyTypeIndex; ++ ++ UINT_16 u2BSSBasicRateSet; ++ ++} NON_HT_ADHOC_MODE_ATTRIBUTE_T, *P_NON_HT_ADHOC_MODE_ATTRIBUTE_T; ++ ++typedef NON_HT_ADHOC_MODE_ATTRIBUTE_T NON_HT_AP_MODE_ATTRIBUTE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[]; ++extern NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[]; ++extern NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[]; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _MIB_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h +new file mode 100644 +index 000000000000..11145c31dbfa +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h +@@ -0,0 +1,55 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_assoc.h#1 ++*/ ++ ++/*! \file p2p_assoc.h ++ \brief This file contains the Wi-Fi Direct ASSOC REQ/RESP of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++#ifndef _P2P_ASSOC_H ++#define _P2P_ASSOC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h +new file mode 100644 +index 000000000000..869d7bf0ee61 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h +@@ -0,0 +1,56 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_bss.h#2 ++*/ ++ ++/*! \file "p2p_bss.h" ++ \brief In this file we define the function prototype used in p2p BSS/IBSS. ++ ++ The file contains the function declarations and defines for used in BSS/IBSS. ++*/ ++ ++#ifndef _P2P_BSS_H ++#define _P2P_BSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++UINT_32 p2pGetTxProbRspIeTableSize(VOID); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h +new file mode 100644 +index 000000000000..2541e1d2883e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h +@@ -0,0 +1,2190 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_fsm.h#23 ++*/ ++ ++/*! \file p2p_fsm.h ++ \brief Declaration of functions and finite state machine for P2P Module. ++ ++ Declaration of functions and finite state machine for P2P Module. ++*/ ++ ++/* ++** Log: p2p_fsm.h ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** Fix compile error. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 18 2012 yuche.tsai ++ * NULL ++ * add one file. ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Resolve class 3 error issue under AP mode. ++ * ++ * data frame may TX before Assoc Response TX. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix default device name issue. ++ * ++ * 11 09 2011 yuche.tsai ++ * [WCXRP00001093] [Need Patch][Volunteer Patch] Service Discovery 2.0 state transition issue. ++ * Fix SD2.0 issue which may cause KE. (Monkey test) ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version ++ * query & set support for service discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 09 01 2011 yuche.tsai ++ * NULL ++ * Fix channel stay interval. ++ * Sync channel stay interval & channel request interval under AP mode.. ++ * ++ * 08 30 2011 yuche.tsai ++ * [WCXRP00000953] [Volunteer Patch][Driver] Hot Spot Channel ASSERT issue. ++ * Fix hot spot FW assert issue when under concurrent case. (DBG enable only) ++ * ++ * 08 16 2011 cp.wu ++ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence ++ * auto channel decision for 2.4GHz hot spot mode ++ * ++ * 08 16 2011 yuche.tsai ++ * NULL ++ * Fix scan policy for Active LISTEN scan. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, ++ * TX deauth to a disconnecting device issue. ++ * Support TX Deauth Issue. ++ * ++ * 07 26 2011 yuche.tsai ++ * [WCXRP00000875] [Volunteer Patch][WiFi Direct][Driver] MT6620 IOT issue with realtek test bed solution. ++ * Turn off persistent group support for V2.0 release. ++ * ++ * 07 18 2011 yuche.tsai ++ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. ++ * Fix compile error. ++ * ++ * 07 18 2011 yuche.tsai ++ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. ++ * Fix MT6620 WiFi Direct IOT Issue with BCM solution. ++ * ++ * 07 11 2011 yuche.tsai ++ * [WCXRP00000845] [Volunteer Patch][WiFi Direct] WiFi Direct Device Connection Robustness ++ * Enhance Connection Robustness. ++ * ++ * 07 08 2011 yuche.tsai ++ * [WCXRP00000841] [Volunteer Patch][WiFi Direct] Group Owner Setting. ++ * Update GO configure parameter. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Disable enhancement II for debugging. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Refine compile flag. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Add wifi direct connection enhancement method I, II & VI. ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. ++ * Fix connection indication twice issue. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Fix RX SD request under AP mode issue. ++ * ++ * 05 04 2011 yuche.tsai ++ * NULL ++ * Support partial persistent group function. ++ * ++ * 04 20 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Improve some error handleing. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * 1.Shorten the LISTEN interval. ++ * 2. Fix IF address issue when we are GO ++ * 3. Fix LISTEN channel issue. ++ * ++ * 03 21 2011 yuche.tsai ++ * NULL ++ * Change P2P Connection Request Flow. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow ++ * Modify connection flow after Group Formation Complete, or device connect to a GO. ++ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix some configure method issue. ++ * ++ * 03 10 2011 yuche.tsai ++ * NULL ++ * Add P2P API. ++ * ++ * 03 07 2011 yuche.tsai ++ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. ++ * . ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation ++ * Update channel issue when doing GO formation.. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Related wlanoid function. ++ * ++ * 02 18 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * fixed the ioctl setting that index not map to spec defined config method. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue ++ * Fix WSC IE BE format issue. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * append the WSC IE config method attribute at provision discovery request. ++ * ++ * 02 11 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add two function prototype. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Support Disassoc & Deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++ ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Indication Related code. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add Support for MLME deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Fix Client Limit Issue. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++ ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Function. ++ * ++ * 01 25 2011 terry.wu ++ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter ++ * Add a new module parameter to indicate current runnig mode, P2P or AP. ++ * ++ * 01 19 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Null NOA attribute setting when no related parameters. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify some behavior of AP mode. ++ * ++ * 12 22 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix Compile Error. ++ * ++ * 12 15 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Refine Connection Flow. ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. ++ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client ++ * by checking the P2P IE in assoc req frame. ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation. ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation & Provision Discovery. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ ++ * ++ * 11 29 2010 yuche.tsai ++ * NULL ++ * Update P2P related function for INVITATION & PROVISION DISCOVERY. ++ * ++ * 11 26 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Update P2P PS for NOA function. ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update Code for Invitation Related Function. ++ * ++ * 11 17 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] ++ * Set the Tx lowest rate at wlan table for normal operation ++ * fixed some ASSERT check. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * fixed compiling error while enable p2p. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at WinXP. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add connection abort message event prototype. ++ * ++ * 08 20 2010 kevin.huang ++ * NULL ++ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Fix P2P Intended Interface Address Bug. ++ * Extend GO Nego Timeout Time. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Extend Listen Interval default value & remove deprecated variable. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add function prototype for join complete. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some function proto type for P2P FSM under provisioning phase.. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Change P2P data structure for supporting ++ * 1. P2P Device discovery. ++ * 2. P2P Group Negotiation. ++ * 3. P2P JOIN ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Check-in P2P Device Discovery Feature. ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Update P2P FSM header file. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * P2P/RSN/WAPI IEs need to be declared with compact structure. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Update P2P FSM header file. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix some P2P function prototype. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * First draft for migration P2P FSM from FW to Driver. ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Rename CFG flag for P2P ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify parameter of p2pStartGO ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add Wi-Fi Direct SSID and P2P GO Test Mode ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++#ifndef _P2P_FSM_H ++#define _P2P_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CID52_53_54 0 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_P2P_STATE_T { ++ P2P_STATE_IDLE = 0, ++ P2P_STATE_SCAN, ++ P2P_STATE_AP_CHANNEL_DETECT, ++ P2P_STATE_REQING_CHANNEL, ++ P2P_STATE_CHNL_ON_HAND, /* Requesting Channel to Send Specific Frame. */ ++ P2P_STATE_GC_JOIN, /* Sending Specific Frame. May extending channel by other event. */ ++ P2P_STATE_NUM ++} ENUM_P2P_STATE_T, *P_ENUM_P2P_STATE_T; ++ ++enum _ENUM_P2P_DEV_EXT_LISTEN_T { ++ P2P_DEV_NOT_EXT_LISTEN, ++ P2P_DEV_EXT_LISTEN_ING, ++ P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT, ++ P2P_DEV_EXT_LISTEN_NUM ++}; ++ ++typedef enum _ENUM_CHANNEL_REQ_TYPE_T { ++ CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL, ++ CHANNEL_REQ_TYPE_GC_JOIN_REQ, ++ CHANNEL_REQ_TYPE_GO_START_BSS ++} ENUM_CHANNEL_REQ_TYPE_T, *P_ENUM_CHANNEL_REQ_TYPE_T; ++ ++typedef enum _ENUM_BUFFER_TYPE_T { ++ ENUM_FRAME_TYPE_EXTRA_IE_BEACON, ++ ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP, ++ ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP, ++ ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE, ++ ENUM_FRAME_TYPE_BEACON_TEMPLATE, ++ ENUM_FRAME_IE_NUM ++} ENUM_BUFFER_TYPE_T, *P_ENUM_BUFFER_TYPE_T; ++ ++typedef enum _ENUM_HIDDEN_SSID_TYPE_T { ++ ENUM_HIDDEN_SSID_NONE, ++ ENUM_HIDDEN_SSID_LEN, ++ ENUM_HIDDEN_SSID_ZERO_CONTENT, ++ ENUM_HIDDEN_SSID_NUM ++} ENUM_HIDDEN_SSID_TYPE_T, *P_ENUM_HIDDEN_SSID_TYPE_T; ++ ++typedef struct _P2P_SSID_STRUCT_T { ++ UINT_8 aucSsid[32]; ++ UINT_8 ucSsidLen; ++} P2P_SSID_STRUCT_T, *P_P2P_SSID_STRUCT_T; ++ ++typedef struct _P2P_STATION_INFO_T { ++ UINT_32 u4InactiveTime; ++ UINT_32 u4RxBytes; /* TODO: */ ++ UINT_32 u4TxBytes; /* TODO: */ ++ UINT_32 u4RxPackets; /* TODO: */ ++ UINT_32 u4TxPackets; /* TODO: */ ++ /* TODO: Add more for requirement. */ ++} P2P_STATION_INFO_T, *P_P2P_STATION_INFO_T; ++ ++typedef struct _AP_CRYPTO_SETTINGS_T { ++ UINT_32 u4WpaVersion; ++ UINT_32 u4CipherGroup; ++ INT_32 i4NumOfCiphers; ++ UINT_32 aucCiphersPairwise[5]; ++ INT_32 i4NumOfAkmSuites; ++ UINT_32 aucAkmSuites[2]; ++ BOOLEAN fgIsControlPort; ++ UINT_16 u2ControlPortBE; ++ BOOLEAN fgIsControlPortEncrypt; ++} AP_CRYPTO_SETTINGS_T, *P_AP_CRYPTO_SETTINGS_T; ++ ++/*-------------------- P2P FSM ACTION STRUCT ---------------------*/ ++typedef struct _P2P_CHNL_REQ_INFO_T { ++ BOOLEAN fgIsChannelRequested; ++ UINT_8 ucSeqNumOfChReq; ++ UINT_64 u8Cookie; ++ UINT_8 ucReqChnlNum; ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eChnlSco; ++ UINT_32 u4MaxInterval; ++ ENUM_CHANNEL_REQ_TYPE_T eChannelReqType; ++ ++ UINT_8 ucOriChnlNum; ++ ENUM_BAND_T eOriBand; ++ ENUM_CHNL_EXT_T eOriChnlSco; ++ UINT_32 NFC_BEAM; /*NFC Beam + Indication */ ++} P2P_CHNL_REQ_INFO_T, *P_P2P_CHNL_REQ_INFO_T; ++ ++typedef struct _P2P_SCAN_REQ_INFO_T { ++ ENUM_SCAN_TYPE_T eScanType; ++ ENUM_SCAN_CHANNEL eChannelSet; ++ UINT_16 u2PassiveDewellTime; ++ UINT_8 ucSeqNumOfScnMsg; ++ BOOLEAN fgIsAbort; ++ BOOLEAN fgIsScanRequest; ++ UINT_8 ucNumChannelList; ++ RF_CHANNEL_INFO_T arScanChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_32 u4BufLength; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++ P2P_SSID_STRUCT_T rSsidStruct; /* Currently we can only take one SSID scan request */ ++ BOOLEAN fgIsGOInitialDone; ++} P2P_SCAN_REQ_INFO_T, *P_P2P_SCAN_REQ_INFO_T; ++ ++typedef struct _P2P_CONNECTION_REQ_INFO_T { ++ ++ BOOLEAN fgIsConnRequest; ++ P2P_SSID_STRUCT_T rSsidStruct; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ /* For ASSOC Req. */ ++ UINT_32 u4BufLength; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++} P2P_CONNECTION_REQ_INFO_T, *P_P2P_CONNECTION_REQ_INFO_T; ++ ++typedef struct _P2P_MGMT_TX_REQ_INFO_T { ++ BOOLEAN fgIsMgmtTxRequested; ++ P_MSDU_INFO_T prMgmtTxMsdu; ++ UINT_64 u8Cookie; ++} P2P_MGMT_TX_REQ_INFO_T, *P_P2P_MGMT_TX_REQ_INFO_T; ++ ++struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T { ++ MSG_HDR_T rMsgHdr; ++ UINT_32 wait; /* interval supplicant expected to stay in listen interval */ ++}; ++ ++typedef struct _P2P_BEACON_UPDATE_INFO_T { ++ PUINT_8 pucBcnHdr; ++ UINT_32 u4BcnHdrLen; ++ PUINT_8 pucBcnBody; ++ UINT_32 u4BcnBodyLen; ++} P2P_BEACON_UPDATE_INFO_T, *P_P2P_BEACON_UPDATE_INFO_T; ++ ++typedef struct _P2P_PROBE_RSP_UPDATE_INFO_T { ++ P_MSDU_INFO_T prProbeRspMsduTemplate; ++} P2P_PROBE_RSP_UPDATE_INFO_T, *P_P2P_PROBE_RSP_UPDATE_INFO_T; ++ ++typedef struct _P2P_ASSOC_RSP_UPDATE_INFO_T { ++ PUINT_8 pucAssocRspExtIE; ++ UINT_16 u2AssocIELen; ++} P2P_ASSOC_RSP_UPDATE_INFO_T, *P_P2P_ASSOC_RSP_UPDATE_INFO_T; ++ ++typedef struct _P2P_JOIN_INFO_T { ++ UINT_32 ucSeqNumOfReqMsg; ++ UINT_8 ucAvailableAuthTypes; ++ P_STA_RECORD_T prTargetStaRec; ++ P2P_SSID_STRUCT_T rSsidStruct; ++ BOOLEAN fgIsJoinComplete; ++ /* For ASSOC Rsp. */ ++ UINT_32 u4BufLength; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++} P2P_JOIN_INFO_T, *P_P2P_JOIN_INFO_T; ++ ++#if CFG_SUPPORT_WFD ++ ++#define WFD_FLAGS_DEV_INFO_VALID BIT(0) /* 1. WFD_DEV_INFO, 2. WFD_CTRL_PORT, 3. WFD_MAT_TP. */ ++#define WFD_FLAGS_SINK_INFO_VALID BIT(1) /* 1. WFD_SINK_STATUS, 2. WFD_SINK_MAC. */ ++#define WFD_FLAGS_ASSOC_MAC_VALID BIT(2) /* 1. WFD_ASSOC_MAC. */ ++#define WFD_FLAGS_EXT_CAPABILITY_VALID BIT(3) /* 1. WFD_EXTEND_CAPABILITY. */ ++ ++struct _WFD_CFG_SETTINGS_T { ++ UINT_32 u4WfdCmdType; ++ UINT_8 ucWfdEnable; ++ UINT_8 ucWfdCoupleSinkStatus; ++ UINT_8 ucWfdSessionAvailable; /* 0: NA 1:Set 2:Clear */ ++ UINT_8 ucWfdSigmaMode; ++ UINT_16 u2WfdDevInfo; ++ UINT_16 u2WfdControlPort; ++ UINT_16 u2WfdMaximumTp; ++ UINT_16 u2WfdExtendCap; ++ UINT_8 aucWfdCoupleSinkAddress[MAC_ADDR_LEN]; ++ UINT_8 aucWfdAssociatedBssid[MAC_ADDR_LEN]; ++ UINT_8 aucWfdVideoIp[4]; ++ UINT_8 aucWfdAudioIp[4]; ++ UINT_16 u2WfdVideoPort; ++ UINT_16 u2WfdAudioPort; ++ UINT_32 u4WfdFlag; ++ UINT_32 u4WfdPolicy; ++ UINT_32 u4WfdState; ++ UINT_8 aucWfdSessionInformationIE[24 * 8]; ++ UINT_16 u2WfdSessionInformationIELen; ++ UINT_8 aucReserved1[2]; ++ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; ++ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; ++ UINT_32 u4WfdAdvancedFlag; ++ /* Group 1 64 bytes */ ++ UINT_8 aucWfdLocalIp[4]; ++ UINT_16 u2WfdLifetimeAc2; /* Unit is 2 TU */ ++ UINT_16 u2WfdLifetimeAc3; /* Unit is 2 TU */ ++ UINT_16 u2WfdCounterThreshold; /* Unit is ms */ ++ UINT_8 aucReverved2[54]; ++ /* Group 2 64 bytes */ ++ UINT_8 aucReverved3[64]; ++ /* Group 3 64 bytes */ ++ UINT_8 aucReverved4[64]; ++ ++}; ++ ++struct _WFD_DBG_CFG_SETTINGS_T { ++ UINT_8 ucWfdDebugMode; ++ UINT_16 u2WfdSNShowPeiroid; ++ UINT_8 Reserved; ++ ++}; ++ ++#endif ++ ++struct _P2P_FSM_INFO_T { ++ /* State related. */ ++ ENUM_P2P_STATE_T ePreviousState; ++ ENUM_P2P_STATE_T eCurrentState; ++ ++ /* Channel related. */ ++ P2P_CHNL_REQ_INFO_T rChnlReqInfo; ++ ++ /* Scan related. */ ++ P2P_SCAN_REQ_INFO_T rScanReqInfo; ++ ++ /* Connection related. */ ++ P2P_CONNECTION_REQ_INFO_T rConnReqInfo; ++ ++ /* Mgmt tx related. */ ++ P2P_MGMT_TX_REQ_INFO_T rMgmtTxInfo; ++ ++ /* Beacon related. */ ++ P2P_BEACON_UPDATE_INFO_T rBcnContentInfo; ++ ++ /* Probe Response related. */ ++ P2P_PROBE_RSP_UPDATE_INFO_T rProbeRspContentInfo; ++ ++ /* Assoc Rsp related. */ ++ P2P_ASSOC_RSP_UPDATE_INFO_T rAssocRspContentInfo; ++ ++ /* GC Join related. */ ++ P2P_JOIN_INFO_T rJoinInfo; ++ ++ /* FSM Timer */ ++/* TIMER_T rP2pFsmTimeoutTimer; */ ++ ++ /* GC Target BSS. */ ++ P_BSS_DESC_T prTargetBss; ++ ++ /* GC Connection Request. */ ++ BOOLEAN fgIsConnectionRequested; ++ ++ BOOLEAN fgIsApMode; ++ ++ /* Channel grant interval. */ ++ UINT_32 u4GrantInterval; ++ ++ /* Packet filter for P2P module. */ ++ UINT_32 u4P2pPacketFilter; ++ ++ /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Prepare for use vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ ++ /* Msg event queue. */ ++ LINK_T rMsgEventQueue; ++ ++#if CFG_SUPPORT_WFD ++ WFD_CFG_SETTINGS_T rWfdConfigureSettings; ++ WFD_DBG_CFG_SETTINGS_T rWfdDebugSetting; ++#endif ++ ++ BOOLEAN fgIsWPSMode; ++ ++ enum _ENUM_P2P_DEV_EXT_LISTEN_T eListenExted; ++}; ++ ++/*---------------- Messages -------------------*/ ++typedef struct _MSG_P2P_SCAN_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ P_P2P_SSID_STRUCT_T prSSID; ++ INT_32 i4SsidNum; ++ UINT_32 u4NumChannel; ++ PUINT_8 pucIEBuf; ++ UINT_32 u4IELen; ++ BOOLEAN fgIsAbort; ++ RF_CHANNEL_INFO_T arChannelListInfo[1]; ++} MSG_P2P_SCAN_REQUEST_T, *P_MSG_P2P_SCAN_REQUEST_T; ++ ++typedef struct _MSG_P2P_CHNL_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_64 u8Cookie; ++ UINT_32 u4Duration; ++ ENUM_CHNL_EXT_T eChnlSco; ++ RF_CHANNEL_INFO_T rChannelInfo; ++} MSG_P2P_CHNL_REQUEST_T, *P_MSG_P2P_CHNL_REQUEST_T; ++ ++typedef struct _MSG_P2P_CHNL_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_64 u8Cookie; ++} MSG_P2P_CHNL_ABORT_T, *P_MSG_P2P_CHNL_ABORT_T; ++ ++typedef struct _MSG_P2P_CONNECTION_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ P2P_SSID_STRUCT_T rSsid; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ ENUM_CHNL_EXT_T eChnlSco; ++ RF_CHANNEL_INFO_T rChannelInfo; ++ UINT_32 u4IELen; ++ UINT_8 aucIEBuf[1]; ++ /* TODO: Auth Type, OPEN, SHARED, FT, EAP... */ ++} MSG_P2P_CONNECTION_REQUEST_T, *P_MSG_P2P_CONNECTION_REQUEST_T; ++ ++typedef struct _MSG_P2P_CONNECTION_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member. */ ++ UINT_8 aucTargetID[MAC_ADDR_LEN]; ++ UINT_16 u2ReasonCode; ++ BOOLEAN fgSendDeauth; ++} MSG_P2P_CONNECTION_ABORT_T, *P_MSG_P2P_CONNECTION_ABORT_T; ++ ++typedef struct _MSG_P2P_MGMT_TX_REQUEST_T { ++ MSG_HDR_T rMsgHdr; ++ P_MSDU_INFO_T prMgmtMsduInfo; ++ UINT_64 u8Cookie; /* For indication. */ ++ BOOLEAN fgNoneCckRate; ++ BOOLEAN fgIsWaitRsp; ++} MSG_P2P_MGMT_TX_REQUEST_T, *P_MSG_P2P_MGMT_TX_REQUEST_T; ++ ++typedef struct _MSG_P2P_START_AP_T { ++ MSG_HDR_T rMsgHdr; ++ UINT_32 u4DtimPeriod; ++ UINT_32 u4BcnInterval; ++ UINT_8 aucSsid[32]; ++ UINT_16 u2SsidLen; ++ UINT_8 ucHiddenSsidType; ++ BOOLEAN fgIsPrivacy; ++ AP_CRYPTO_SETTINGS_T rEncryptionSettings; ++ INT_32 i4InactiveTimeout; ++} MSG_P2P_START_AP_T, *P_MSG_P2P_START_AP_T; ++ ++typedef struct _MSG_P2P_BEACON_UPDATE_T { ++ MSG_HDR_T rMsgHdr; ++ UINT_32 u4BcnHdrLen; ++ UINT_32 u4BcnBodyLen; ++ PUINT_8 pucBcnHdr; ++ PUINT_8 pucBcnBody; ++ UINT_8 aucBuffer[1]; /* Header & Body are put here. */ ++} MSG_P2P_BEACON_UPDATE_T, *P_MSG_P2P_BEACON_UPDATE_T; ++ ++typedef struct _MSG_P2P_MGMT_FRAME_UPDATE_T { ++ MSG_HDR_T rMsgHdr; ++ ENUM_BUFFER_TYPE_T eBufferType; ++ UINT_32 u4BufferLen; ++ UINT_8 aucBuffer[1]; ++} MSG_P2P_MGMT_FRAME_UPDATE_T, *P_MSG_P2P_MGMT_FRAME_UPDATE_T; ++ ++typedef struct _MSG_P2P_SWITCH_OP_MODE_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ ENUM_OP_MODE_T eOpMode; ++} MSG_P2P_SWITCH_OP_MODE_T, *P_MSG_P2P_SWITCH_OP_MODE_T; ++ ++typedef struct _MSG_P2P_MGMT_FRAME_REGISTER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_16 u2FrameType; ++ BOOLEAN fgIsRegister; ++} MSG_P2P_MGMT_FRAME_REGISTER_T, *P_MSG_P2P_MGMT_FRAME_REGISTER_T; ++ ++typedef struct _MSG_P2P_NETDEV_REGISTER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ BOOLEAN fgIsEnable; ++ UINT_8 ucMode; ++} MSG_P2P_NETDEV_REGISTER_T, *P_MSG_P2P_NETDEV_REGISTER_T; ++ ++#if CFG_SUPPORT_WFD ++typedef struct _MSG_WFD_CONFIG_SETTINGS_CHANGED_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings; ++} MSG_WFD_CONFIG_SETTINGS_CHANGED_T, *P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T; ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++WLAN_STATUS ++p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++#if CFG_SUPPORT_WFD ++VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++#endif ++ ++#if 0 ++/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ ++#endif ++ ++/* 3 --------------- WFA P2P DEFAULT PARAMETERS --------------- */ ++#define P2P_WILDCARD_SSID "DIRECT-" ++#define P2P_WILDCARD_SSID_LEN 7 ++#define P2P_GROUP_ID_LEN 9 ++ ++#define P2P_DRIVER_VERSION 2 /* Update when needed. */ ++ ++#define P2P_DEFAULT_DEV_NAME "Wireless Client" ++#define P2P_DEFAULT_DEV_NAME_LEN 15 ++#define P2P_DEFAULT_PRIMARY_CATEGORY_ID 10 ++#define P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID 5 ++#define P2P_DEFAULT_CONFIG_METHOD \ ++ (WPS_ATTRI_CFG_METHOD_PUSH_BUTTON | WPS_ATTRI_CFG_METHOD_KEYPAD | WPS_ATTRI_CFG_METHOD_DISPLAY) ++#define P2P_DEFAULT_LISTEN_CHANNEL 1 ++ ++#define P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT 0 /* NOTE(Kevin): Shall <= 16 */ ++#define P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT 13 ++ ++#define P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE 51 /* Contains 6 sub-band. */ ++ ++#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ ++ ++#define P2P_MAXIMUM_CLIENT_COUNT 8 ++#define P2P_MAXIMUM_NOA_COUNT 8 ++ ++#define P2P_MAXIMUM_ATTRIBUTE_LEN 251 ++ ++#define P2P_CTWINDOW_DEFAULT 25 /* in TU=(1024usec) */ ++ ++#define P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE 768 ++ ++/* P2P 3.1.2.1.3 - Find Phase */ ++#define P2P_MAX_DISCOVERABLE_INTERVAL 8 /* 3 */ ++#define P2P_MIN_DISCOVERABLE_INTERVAL 5 /* 1 */ ++ ++#define P2P_LISTEN_SCAN_UNIT 100 /* MS */ ++ ++/* FSM Time Related constrain. */ ++#define P2P_SERACH_STATE_PERIOD_MS 1000 /* Deprecated. */ ++ ++#define P2P_GO_CHANNEL_STAY_INTERVAL 1000 ++ ++#define P2P_GO_NEGO_TIMEOUT_MS 500 ++#define P2P_CONNECTION_TIMEOUT_SEC 120 ++ ++#define P2P_INVITAION_TIMEOUT_MS 500 /* Timeout Wait Invitation Resonse. */ ++#define P2P_PROVISION_DISCOVERY_TIMEOUT_MS 500 /* Timeout Wait Provision Discovery Resonse. */ ++ ++/* 3 --------------- WFA P2P IE --------------- */ ++/* P2P 4.1.1 - P2P IE format */ ++#define P2P_OUI_TYPE_LEN 4 ++#define P2P_IE_OUI_HDR (ELEM_HDR_LEN + P2P_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, ++ aucP2PAttributes[0]) */ ++ ++/* P2P 4.1.1 - General P2P Attribute */ ++#define P2P_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ ++#define P2P_ATTRI_LEN_NOTICE_OF_ABSENCE (P2P_ATTRI_HDR_LEN + 2) /* 5 */ ++ ++/* P2P 4.1.1 - P2P Attribute ID definitions */ ++#define P2P_ATTRI_ID_STATUS 0 ++#define P2P_ATTRI_ID_REASON_CODE 1 ++#define P2P_ATTRI_ID_P2P_CAPABILITY 2 ++#define P2P_ATTRI_ID_P2P_DEV_ID 3 ++#define P2P_ATTRI_ID_GO_INTENT 4 ++#define P2P_ATTRI_ID_CFG_TIMEOUT 5 ++#define P2P_ATTRI_ID_LISTEN_CHANNEL 6 ++#define P2P_ATTRI_ID_P2P_GROUP_BSSID 7 ++#define P2P_ATTRI_ID_EXT_LISTEN_TIMING 8 ++#define P2P_ATTRI_ID_INTENDED_P2P_IF_ADDR 9 ++#define P2P_ATTRI_ID_P2P_MANAGEABILITY 10 ++#define P2P_ATTRI_ID_CHANNEL_LIST 11 ++#define P2P_ATTRI_ID_NOTICE_OF_ABSENCE 12 ++#define P2P_ATTRI_ID_P2P_DEV_INFO 13 ++#define P2P_ATTRI_ID_P2P_GROUP_INFO 14 ++#define P2P_ATTRI_ID_P2P_GROUP_ID 15 ++#define P2P_ATTRI_ID_P2P_INTERFACE 16 ++#define P2P_ATTRI_ID_OPERATING_CHANNEL 17 ++#define P2P_ATTRI_ID_INVITATION_FLAG 18 ++#define P2P_ATTRI_ID_VENDOR_SPECIFIC 221 ++ ++/* Maximum Length of P2P Attributes */ ++#define P2P_ATTRI_MAX_LEN_STATUS 1 /* 0 */ ++#define P2P_ATTRI_MAX_LEN_REASON_CODE 1 /* 1 */ ++#define P2P_ATTRI_MAX_LEN_P2P_CAPABILITY 2 /* 2 */ ++#define P2P_ATTRI_MAX_LEN_P2P_DEV_ID 6 /* 3 */ ++#define P2P_ATTRI_MAX_LEN_GO_INTENT 1 /* 4 */ ++#define P2P_ATTRI_MAX_LEN_CFG_TIMEOUT 2 /* 5 */ ++#if CID52_53_54 ++#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ ++#else ++#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ ++#endif ++#define P2P_ATTRI_MAX_LEN_P2P_GROUP_BSSID 6 /* 7 */ ++#define P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING 4 /* 8 */ ++#define P2P_ATTRI_MAX_LEN_INTENDED_P2P_IF_ADDR 6 /* 9 */ ++#define P2P_ATTRI_MAX_LEN_P2P_MANAGEABILITY 1 /* 10 */ ++/* #define P2P_ATTRI_MAX_LEN_CHANNEL_LIST 3 + (n* (2 + num_of_ch)) */ /* 11 */ ++#define P2P_ATTRI_LEN_CHANNEL_LIST 3 /* 11 */ ++#define P2P_ATTRI_LEN_CHANNEL_ENTRY 2 /* 11 */ ++ ++/* #define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE 2 + (n* (13)) */ /* 12 */ ++#define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE (2 + (P2P_MAXIMUM_NOA_COUNT*(13))) /* 12 */ ++ ++#define P2P_ATTRI_MAX_LEN_P2P_DEV_INFO (17 + (8 * (8)) + 36) /* 13 */ ++/* #define P2P_ATTRI_MAX_LEN_P2P_GROUP_INFO n* (25 + (m* (8)) + 32) */ /* 14 */ ++#define P2P_ATTRI_MAX_LEN_P2P_GROUP_ID 38 /* 15 */ ++#define P2P_ATTRI_MAX_LEN_P2P_INTERFACE 253 /* 7 + 6* [0~41] */ /* 16 */ ++#if CID52_53_54 ++#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ ++#else ++#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ ++#endif ++#define P2P_ATTRI_MAX_LEN_INVITATION_FLAGS 1 /* 18 */ ++ ++/* P2P 4.1.2 - P2P Status definitions */ ++#define P2P_STATUS_SUCCESS 0 ++#define P2P_STATUS_FAIL_INFO_IS_CURRENTLY_UNAVAILABLE 1 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 2 ++#define P2P_STATUS_FAIL_LIMIT_REACHED 3 ++#define P2P_STATUS_FAIL_INVALID_PARAM 4 ++#define P2P_STATUS_FAIL_UNABLE_ACCOMMODATE_REQ 5 ++#define P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR 6 ++#define P2P_STATUS_FAIL_NO_COMMON_CHANNELS 7 ++#define P2P_STATUS_FAIL_UNKNOWN_P2P_GROUP 8 ++#define P2P_STATUS_FAIL_SAME_INTENT_VALUE_15 9 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVISION_METHOD 10 ++#define P2P_STATUS_FAIL_REJECTED_BY_USER 11 ++ ++/* P2P 4.1.3 - P2P Minor Reason Code definitions */ ++#define P2P_REASON_SUCCESS 0 ++#define P2P_REASON_DISASSOCIATED_DUE_CROSS_CONNECTION 1 ++#define P2P_REASON_DISASSOCIATED_DUE_UNMANAGEABLE 2 ++#define P2P_REASON_DISASSOCIATED_DUE_NO_P2P_COEXIST_PARAM 3 ++#define P2P_REASON_DISASSOCIATED_DUE_MANAGEABLE 4 ++ ++/* P2P 4.1.4 - Device Capability Bitmap definitions */ ++#define P2P_DEV_CAPABILITY_SERVICE_DISCOVERY BIT(0) ++#define P2P_DEV_CAPABILITY_CLIENT_DISCOVERABILITY BIT(1) ++#define P2P_DEV_CAPABILITY_CONCURRENT_OPERATION BIT(2) ++#define P2P_DEV_CAPABILITY_P2P_INFRA_MANAGED BIT(3) ++#define P2P_DEV_CAPABILITY_P2P_DEVICE_LIMIT BIT(4) ++#define P2P_DEV_CAPABILITY_P2P_INVITATION_PROCEDURE BIT(5) ++ ++/* P2P 4.1.4 - Group Capability Bitmap definitions */ ++#define P2P_GROUP_CAPABILITY_P2P_GROUP_OWNER BIT(0) ++#define P2P_GROUP_CAPABILITY_PERSISTENT_P2P_GROUP BIT(1) ++#define P2P_GROUP_CAPABILITY_P2P_GROUP_LIMIT BIT(2) ++#define P2P_GROUP_CAPABILITY_INTRA_BSS_DISTRIBUTION BIT(3) ++#define P2P_GROUP_CAPABILITY_CROSS_CONNECTION BIT(4) ++#define P2P_GROUP_CAPABILITY_PERSISTENT_RECONNECT BIT(5) ++#define P2P_GROUP_CAPABILITY_GROUP_FORMATION BIT(6) ++ ++/* P2P 4.1.6 - GO Intent field definitions */ ++#define P2P_GO_INTENT_TIE_BREAKER_FIELD BIT(0) ++#define P2P_GO_INTENT_VALUE_MASK BITS(1, 7) ++#define P2P_GO_INTENT_VALUE_OFFSET 1 ++ ++/* P2P 4.1.12 - Manageability Bitmap definitions */ ++#define P2P_DEVICE_MANAGEMENT BIT(0) ++ ++/* P2P 4.1.14 - CTWindow and OppPS Parameters definitions */ ++#define P2P_CTW_OPPPS_PARAM_OPPPS_FIELD BIT(7) ++#define P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK BITS(0, 6) ++ ++#define ELEM_MAX_LEN_P2P_FOR_PROBE_REQ \ ++ (P2P_OUI_TYPE_LEN + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_ID) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL)) ++ ++#define ELEM_MAX_LEN_P2P_FOR_ASSOC_REQ \ ++ (P2P_OUI_TYPE_LEN + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_INFO)) ++ ++/* P2P 4.1.16 - P2P Client Infor Descriptor */ ++#define P2P_CLIENT_INFO_DESC_HDR_LEN 1 /* Length(1 octets) */ ++ ++/* P2P 4.1.20 - P2P Invitation Flags Attribute*/ ++#define P2P_INVITATION_FLAGS_INVITATION_TYPE BIT(0) ++#define P2P_INVITATION_TYPE_INVITATION 0 ++#define P2P_INVITATION_TYPE_REINVOKE 1 ++/* 3 --------------- WPS Data Element Definitions --------------- */ ++/* P2P 4.2.2 - General WSC Attribute */ ++#define WSC_ATTRI_HDR_LEN 4 /* ID(2 octet) + Length(2 octets) */ ++#define WSC_ATTRI_MAX_LEN_VERSION 1 ++#define WSC_ATTRI_MAX_LEN_DEVICE_PASSWORD_ID 2 ++#define WSC_ATTRI_LEN_CONFIG_METHOD 2 ++ ++/* WPS 11 - Data Element Definitions */ ++#define WPS_ATTRI_ID_VERSION 0x104A ++#define WPS_ATTRI_ID_CONFIGURATION_METHODS 0x1008 ++#define WPS_ATTRI_ID_DEVICE_PASSWORD 0x1012 ++#define WPS_ATTRI_ID_DEVICE_NAME 0x1011 ++#define WPS_ATTRI_ID_PRI_DEVICE_TYPE 0x1054 ++#define WPS_ATTRI_ID_SEC_DEVICE_TYPE 0x1055 ++ ++#define WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE 300 ++ ++#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ ++ ++#define WPS_ATTRI_CFG_METHOD_USBA BIT(0) ++#define WPS_ATTRI_CFG_METHOD_ETHERNET BIT(1) ++#define WPS_ATTRI_CFG_METHOD_LABEL BIT(2) ++#define WPS_ATTRI_CFG_METHOD_DISPLAY BIT(3) ++#define WPS_ATTRI_CFG_METHOD_EXT_NFC BIT(4) ++#define WPS_ATTRI_CFG_METHOD_INT_NFC BIT(5) ++#define WPS_ATTRI_CFG_METHOD_NFC_IF BIT(6) ++#define WPS_ATTRI_CFG_METHOD_PUSH_BUTTON BIT(7) ++#define WPS_ATTRI_CFG_METHOD_KEYPAD BIT(8) ++ ++#define P2P_FLAGS_PROVISION_COMPLETE 0x00000001 ++#define P2P_FLAGS_PROVISION_DISCOVERY_COMPLETE 0x00000002 ++#define P2P_FLAGS_PROVISION_DISCOVERY_WAIT_RESPONSE 0x00000004 ++#define P2P_FLAGS_PROVISION_DISCOVERY_RESPONSE_WAIT 0x00000008 ++#define P2P_FLAGS_MASK_PROVISION 0x00000017 ++#define P2P_FLAGS_MASK_PROVISION_COMPLETE 0x00000015 ++#define P2P_FLAGS_PROVISION_DISCOVERY_INDICATED 0x00000010 ++#define P2P_FLAGS_INVITATION_TOBE_GO 0x00000100 ++#define P2P_FLAGS_INVITATION_TOBE_GC 0x00000200 ++#define P2P_FLAGS_INVITATION_SUCCESS 0x00000400 ++#define P2P_FLAGS_INVITATION_WAITING_TARGET 0x00000800 ++#define P2P_FLAGS_MASK_INVITATION 0x00000F00 ++#define P2P_FLAGS_FORMATION_ON_GOING 0x00010000 ++#define P2P_FLAGS_FORMATION_LOCAL_PWID_RDY 0x00020000 ++#define P2P_FLAGS_FORMATION_TARGET_PWID_RDY 0x00040000 ++#define P2P_FLAGS_FORMATION_COMPLETE 0x00080000 ++#define P2P_FLAGS_MASK_FORMATION 0x000F0000 ++#define P2P_FLAGS_DEVICE_DISCOVER_REQ 0x00100000 ++#define P2P_FLAGS_DEVICE_DISCOVER_DONE 0x00200000 ++#define P2P_FLAGS_DEVICE_INVITATION_WAIT 0x00400000 ++#define P2P_FLAGS_DEVICE_SERVICE_DISCOVER_WAIT 0x00800000 ++#define P2P_FLAGS_MASK_DEVICE_DISCOVER 0x00F00000 ++ ++#define P2P_FLAGS_DEVICE_FORMATION_REQUEST 0x01000000 ++ ++/* MACRO for flag operation */ ++#define SET_FLAGS(_FlagsVar, _BitsToSet) \ ++ {(_FlagsVar) = ((_FlagsVar) | (_BitsToSet))} ++ ++#define TEST_FLAGS(_FlagsVar, _BitsToCheck) \ ++ (((_FlagsVar) & (_BitsToCheck)) == (_BitsToCheck)) ++ ++#define CLEAR_FLAGS(_FlagsVar, _BitsToClear) \ ++ {(_FlagsVar) &= ~(_BitsToClear)} ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_I 0 ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_II 0 ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_III 0 ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_IV 0 ++ ++#define CFG_DISABLE_DELAY_PROVISION_DISCOVERY 0 ++ ++#define CFG_CONNECTION_POLICY_2_0 0 ++ ++/* Device Password ID */ ++enum wps_dev_password_id { ++ DEV_PW_DEFAULT = 0x0000, ++ DEV_PW_USER_SPECIFIED = 0x0001, ++ DEV_PW_MACHINE_SPECIFIED = 0x0002, ++ DEV_PW_REKEY = 0x0003, ++ DEV_PW_PUSHBUTTON = 0x0004, ++ DEV_PW_REGISTRAR_SPECIFIED = 0x0005 ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack(1) ++#endif ++ ++/* 3 --------------- WFA P2P IE and Attributes --------------- */ ++ ++/* P2P 4.1.1 - P2P Information Element */ ++typedef struct _IE_P2P_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 aucP2PAttributes[1]; /* P2P Attributes */ ++} __KAL_ATTRIB_PACKED__ IE_P2P_T, *P_IE_P2P_T; ++ ++/* P2P 4.1.1 - General P2P Attribute */ ++typedef struct _P2P_ATTRIBUTE_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBody[1]; /* Body field */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRIBUTE_T, ATTRIBUTE_HDR_T, *P_P2P_ATTRIBUTE_T, *P_ATTRIBUTE_HDR_T; ++ ++/* P2P 4.1.2 - P2P Status Attribute */ ++typedef struct _P2P_ATTRI_STATUS_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucStatusCode; /* Status Code */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_STATUS_T, *P_P2P_ATTRI_STATUS_T; ++ ++/* P2P 4.1.3 - P2P Minor Reason Code Attribute */ ++typedef struct _P2P_ATTRI_REASON_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucMinorReasonCode; /* Minor Reason Code */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_REASON_T, *P_P2P_ATTRI_REASON_T; ++ ++/* P2P 4.1.4 - P2P Capability Attribute */ ++typedef struct _P2P_ATTRI_CAPABILITY_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ ++ UINT_8 ucGroupCap; /* Group Capability Bitmap */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CAPABILITY_T, *P_P2P_ATTRI_CAPABILITY_T; ++ ++/* P2P 4.1.5 - P2P Device ID Attribute */ ++typedef struct _P2P_ATTRI_DEV_ID_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_ID_T, *P_P2P_ATTRI_DEV_ID_T; ++ ++/* P2P 4.1.6 - Group Owner Intent Attribute */ ++typedef struct _P2P_ATTRI_GO_INTENT_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucGOIntent; /* Group Owner Intent */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GO_INTENT_T, *P_P2P_ATTRI_GO_INTENT_T; ++ ++/* P2P 4.1.7 - Configuration Timeout Attribute */ ++typedef struct _P2P_ATTRI_CFG_TIMEOUT_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucGOCfgTimeout; /* GO Configuration Timeout */ ++ UINT_8 ucClientCfgTimeout; /* Client Configuration Timeout */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CFG_TIMEOUT_T, *P_P2P_ATTRI_CFG_TIMEOUT_T; ++ ++/* P2P 4.1.8 - Listen Channel Attribute */ ++typedef struct _P2P_ATTRI_LISTEN_CHANNEL_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucCountryString[3]; /* Country String */ ++ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ ++ UINT_8 ucChannelNumber; /* Channel Number */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_LISTEN_CHANNEL_T, *P_P2P_ATTRI_LISTEN_CHANNEL_T; ++ ++/* P2P 4.1.9 - P2P Group BSSID Attribute */ ++typedef struct _P2P_ATTRI_GROUP_BSSID_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBssid[MAC_ADDR_LEN]; /* P2P Group BSSID */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_BSSID_T, *P_P2P_ATTRI_GROUP_BSSID_T; ++ ++/* P2P 4.1.10 - Extended Listen Timing Attribute */ ++typedef struct _P2P_ATTRI_EXT_LISTEN_TIMING_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_16 u2AvailPeriod; /* Availability Period */ ++ UINT_16 u2AvailInterval; /* Availability Interval */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_EXT_LISTEN_TIMING_T, *P_P2P_ATTRI_EXT_LISTEN_TIMING_T; ++ ++/* P2P 4.1.11 - Intended P2P Interface Address Attribute */ ++typedef struct _P2P_ATTRI_INTENDED_IF_ADDR_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTENDED_IF_ADDR_T, *P_P2P_ATTRI_INTENDED_IF_ADDR_T; ++ ++/* P2P 4.1.12 - P2P Manageability Attribute */ ++typedef struct _P2P_ATTRI_MANAGEABILITY_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucManageability; /* P2P Manageability Bitmap */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_MANAGEABILITY_T, *P_P2P_ATTRI_MANAGEABILITY_T; ++ ++/* P2P 4.1.13 - Channel List Attribute */ ++typedef struct _P2P_ATTRI_CHANNEL_LIST_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucCountryString[3]; /* Country String */ ++ UINT_8 aucChannelEntry[1]; /* Channel Entry List */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CHANNEL_T, *P_P2P_ATTRI_CHANNEL_T; ++ ++typedef struct _CHANNEL_ENTRY_FIELD_T { ++ UINT_8 ucRegulatoryClass; /* Regulatory Class */ ++ UINT_8 ucNumberOfChannels; /* Number Of Channels */ ++ UINT_8 aucChannelList[1]; /* Channel List */ ++} __KAL_ATTRIB_PACKED__ CHANNEL_ENTRY_FIELD_T, *P_CHANNEL_ENTRY_FIELD_T; ++ ++/* P2P 4.1.14 - Notice of Absence Attribute */ ++typedef struct _P2P_ATTRI_NOA_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucIndex; /* Index */ ++ UINT_8 ucCTWOppPSParam; /* CTWindow and OppPS Parameters */ ++ UINT_8 aucNoADesc[1]; /* NoA Descriptor */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_NOA_T, *P_P2P_ATTRI_NOA_T; ++ ++typedef struct _NOA_DESCRIPTOR_T { ++ UINT_8 ucCountType; /* Count/Type */ ++ UINT_32 u4Duration; /* Duration */ ++ UINT_32 u4Interval; /* Interval */ ++ UINT_32 u4StartTime; /* Start Time */ ++} __KAL_ATTRIB_PACKED__ NOA_DESCRIPTOR_T, *P_NOA_DESCRIPTOR_T; ++ ++typedef struct _P2P_ATTRI_DEV_INFO_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_16 u2ConfigMethodsBE; /* Config Method */ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ ++ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ ++ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_INFO_T, *P_P2P_ATTRI_DEV_INFO_T; ++ ++/* WPS 7.1 & 11 WPS TLV Data Format - Device Name */ ++typedef struct _DEVICE_NAME_TLV_T { ++ UINT_16 u2Id; /* WPS Attribute Type */ ++ UINT_16 u2Length; /* Data Length */ ++ UINT_8 aucName[32]; /* Device Name */ /* TODO: Fixme */ ++} __KAL_ATTRIB_PACKED__ DEVICE_NAME_TLV_T, *P_DEVICE_NAME_TLV_T; ++ ++/* P2P 4.1.16 - P2P Group Info Attribute */ ++typedef struct _P2P_CLIENT_INFO_DESC_T { ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ ++ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ ++ UINT_16 u2ConfigMethodsBE; /* Config Method */ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ ++ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ ++ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ ++} __KAL_ATTRIB_PACKED__ P2P_CLIENT_INFO_DESC_T, *P_P2P_CLIENT_INFO_DESC_T; ++ ++typedef struct _P2P_ATTRI_GROUP_INFO_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ P2P_CLIENT_INFO_DESC_T arClientDesc[1]; /* P2P Client Info Descriptors */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_INFO_T, *P_P2P_ATTRI_GROUP_INFO_T; ++ ++/* P2P 4.1.17 - P2P Group ID Attribute */ ++typedef struct _P2P_ATTRI_GROUP_ID_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_ID_T, *P_P2P_ATTRI_GROUP_ID_T; ++ ++/* P2P 4.1.18 - P2P Interface Attribute */ ++typedef struct _P2P_ATTRI_INTERFACE_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_8 ucIfAddrCount; /* P2P Interface Address Count */ ++ UINT_8 aucIfAddrList[MAC_ADDR_LEN]; /* P2P Interface Address List */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTERFACE_T, *P_P2P_ATTRI_INTERFACE_T; ++ ++/* P2P 4.1.19 - Operating Channel Attribute */ ++typedef struct _P2P_ATTRI_OPERATING_CHANNEL_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucCountryString[3]; /* Country String */ ++ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ ++ UINT_8 ucChannelNumber; /* Channel Number */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_OPERATING_CHANNEL_T, *P_P2P_ATTRI_OPERATING_CHANNEL_T; ++ ++/* P2P 4.1.20 - Invitation Flags Attribute */ ++typedef struct _P2P_ATTRI_INVITATION_FLAG_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucInviteFlagsBitmap; /* Invitation Flags Bitmap */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INVITATION_FLAG_T, *P_P2P_ATTRI_INVITATION_FLAG_T; ++ ++/* P2P 4.1.1 - General WSC Attribute */ ++typedef struct _WSC_ATTRIBUTE_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBody[1]; /* Body field */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRIBUTE_T, *P_WSC_ATTRIBUTE_T; ++ ++/* WSC 1.0 Table 28 */ ++typedef struct _WSC_ATTRI_VERSION_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucVersion; /* Version 1.0 or 1.1 */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRI_VERSION_T, *P_WSC_ATTRI_VERSION_T; ++ ++typedef struct _WSC_ATTRI_DEVICE_PASSWORD_ID_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_16 u2DevPasswordId; /* Device Password ID */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRI_DEVICE_PASSWORD_ID_T, *P_WSC_ATTRI_DEVICE_PASSWORD_ID_T; ++ ++typedef struct _WSC_ATTRI_CONFIGURATION_METHOD_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_16 u2ConfigMethods; /* Configure Methods */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRI_CONFIGURATION_METHOD_T, *P_WSC_ATTRI_CONFIGURATION_METHOD_T; ++ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack() ++#endif ++ ++/* 3 --------------- WFA P2P Attributes Handler prototype --------------- */ ++typedef UINT_32(*PFN_APPEND_ATTRI_FUNC) (P_ADAPTER_T, BOOLEAN, PUINT_16, PUINT_8, UINT_16); ++ ++typedef VOID(*PFN_HANDLE_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T); ++ ++typedef VOID(*PFN_VERIFY_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T, PUINT_16); ++ ++typedef UINT_32(*PFN_CALCULATE_VAR_ATTRI_LEN_FUNC) (P_ADAPTER_T, P_STA_RECORD_T); ++ ++typedef struct _APPEND_VAR_ATTRI_ENTRY_T { ++ UINT_16 u2EstimatedFixedAttriLen; /* For fixed length */ ++ PFN_CALCULATE_VAR_ATTRI_LEN_FUNC pfnCalculateVariableAttriLen; ++ PFN_APPEND_ATTRI_FUNC pfnAppendAttri; ++} APPEND_VAR_ATTRI_ENTRY_T, *P_APPEND_VAR_ATTRI_ENTRY_T; ++ ++typedef enum _ENUM_CONFIG_METHOD_SEL { ++ ENUM_CONFIG_METHOD_SEL_AUTO, ++ ENUM_CONFIG_METHOD_SEL_USER, ++ ENUM_CONFIG_METHOD_SEL_NUM ++} ENUM_CONFIG_METHOD_SEL, *P_ENUM_CONFIG_METHOD_SEL; ++ ++typedef enum _ENUM_P2P_FORMATION_POLICY { ++ ENUM_P2P_FORMATION_POLICY_AUTO = 0, ++ ENUM_P2P_FORMATION_POLICY_PASSIVE, /* Device would wait GO NEGO REQ instead of sending it actively. */ ++ ENUM_P2P_FORMATION_POLICY_NUM ++} ENUM_P2P_FORMATION_POLICY, P_ENUM_P2P_FORMATION_POLICY; ++ ++typedef enum _ENUM_P2P_INVITATION_POLICY { ++ ENUM_P2P_INVITATION_POLICY_USER = 0, ++ ENUM_P2P_INVITATION_POLICY_ACCEPT_FIRST, ++ ENUM_P2P_INVITATION_POLICY_DENY_ALL, ++ ENUM_P2P_INVITATION_POLICY_NUM ++} ENUM_P2P_INVITATION_POLICY, P_ENUM_P2P_INVITATION_POLICY; ++ ++/* 3 --------------- Data Structure for P2P Operation --------------- */ ++/* 3 Session for CONNECTION SETTINGS of P2P */ ++struct _P2P_CONNECTION_SETTINGS_T { ++ UINT_8 ucDevNameLen; ++ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; ++ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; ++ ++ ENUM_P2P_FORMATION_POLICY eFormationPolicy; /* Formation Policy. */ ++ ++ /*------------WSC Related Param---------------*/ ++ UINT_16 u2ConfigMethodsSupport; /* Preferred configure method. ++ * Some device may not have keypad. ++ */ ++ ENUM_CONFIG_METHOD_SEL eConfigMethodSelType; ++ UINT_16 u2TargetConfigMethod; /* Configure method selected by user or auto. */ ++ UINT_16 u2LocalConfigMethod; /* Configure method of target. */ ++ BOOLEAN fgIsPasswordIDRdy; ++ /*------------WSC Related Param---------------*/ ++ ++ UINT_8 ucClientConfigTimeout; ++ UINT_8 ucGoConfigTimeout; ++ ++ UINT_8 ucSecondaryDevTypeCount; ++#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT ++ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT]; ++#endif ++ ++#if 0 ++ UINT_8 ucRfChannelListCount; ++#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT ++ UINT_8 aucChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering ++ depends on 802.11mb Annex J. */ ++ ++#endif ++#else ++ UINT_8 ucRfChannelListSize; ++#if P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE ++ UINT_8 aucChannelEntriesField[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE]; ++#endif ++#endif ++ ++ /* Go Intent */ ++ UINT_8 ucTieBreaker; ++ UINT_8 ucGoIntent; ++ ++ /* For Device Capability */ ++ BOOLEAN fgSupportServiceDiscovery; ++ BOOLEAN fgSupportClientDiscoverability; ++ BOOLEAN fgSupportConcurrentOperation; ++ BOOLEAN fgSupportInfraManaged; ++ BOOLEAN fgSupportInvitationProcedure; ++ ++ /* For Group Capability */ ++ BOOLEAN fgSupportPersistentP2PGroup; ++ BOOLEAN fgSupportIntraBSSDistribution; ++ BOOLEAN fgSupportCrossConnection; ++ BOOLEAN fgSupportPersistentReconnect; ++ ++ BOOLEAN fgP2pGroupLimit; ++ ++ BOOLEAN fgSupportOppPS; ++ UINT_16 u2CTWindow; ++ ++ BOOLEAN fgIsScanReqIssued; ++ BOOLEAN fgIsServiceDiscoverIssued; ++ ++ /*============ Target Device Connection Settings ============*/ ++ ++ /* Discover Target Device Info. */ ++ BOOLEAN fgIsDevId; ++ BOOLEAN fgIsDevType; ++ ++ /* Encryption mode of Target Device */ ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ ++ /* SSID ++ * 1. AP Mode, this is the desired SSID user specified. ++ * 2. Client Mode, this is the target SSID to be connected to. ++ */ ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ UINT_8 ucSSIDLen; ++ ++ /* Operating channel requested. */ ++ UINT_8 ucOperatingChnl; ++ ENUM_BAND_T eBand; ++ ++ /* Linten channel requested. */ ++ UINT_8 ucListenChnl; ++ ++ /* For device discover address/type. */ ++ UINT_8 aucTargetDevAddr[MAC_ADDR_LEN]; /* P2P Device Address, for P2P Device Discovery & P2P Connection. */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ P_P2P_DEVICE_DESC_T prTargetP2pDesc; ++#endif ++ ++ UINT_8 ucLastStatus; /* P2P FSM would append status attribute according to this field. */ ++ ++#if !CFG_DISABLE_DELAY_PROVISION_DISCOVERY ++ UINT_8 ucLastDialogToken; ++ UINT_8 aucIndicateDevAddr[MAC_ADDR_LEN]; ++#endif ++ ++#if 0 ++ UINT_8 ucTargetRfChannelListCount; ++#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT ++ UINT_8 aucTargetChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering ++ depends on 802.11mb Annex J. */ ++#endif ++#endif ++ ++}; ++ ++typedef struct _NOA_TIMING_T { ++ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ ++ UINT_8 ucCount; /* Count */ ++ ++ UINT_8 aucReserved[2]; ++ ++ UINT_32 u4Duration; /* Duration */ ++ UINT_32 u4Interval; /* Interval */ ++ UINT_32 u4StartTime; /* Start Time */ ++} NOA_TIMING_T, *P_NOA_TIMING_T; ++ ++typedef enum _ENUM_P2P_IOCTL_T { ++ P2P_IOCTL_IDLE = 0, ++ P2P_IOCTL_DEV_DISCOVER, ++ P2P_IOCTL_INVITATION_REQ, ++ P2P_IOCTL_SERV_DISCOVER, ++ P2P_IOCTL_WAITING, ++ P2P_IOCTL_NUM ++} ENUM_P2P_IOCTL_T; ++ ++/*---------------- Service Discovery Related -------------------*/ ++typedef enum _ENUM_SERVICE_TX_TYPE_T { ++ ENUM_SERVICE_TX_TYPE_BY_DA, ++ ENUM_SERVICE_TX_TYPE_BY_CHNL, ++ ENUM_SERVICE_TX_TYPE_NUM ++} ENUM_SERVICE_TX_TYPE_T; ++ ++typedef struct _SERVICE_DISCOVERY_FRAME_DATA_T { ++ QUE_ENTRY_T rQueueEntry; ++ P_MSDU_INFO_T prSDFrame; ++ ENUM_SERVICE_TX_TYPE_T eServiceType; ++ UINT_8 ucSeqNum; ++ union { ++ ++ UINT_8 ucChannelNum; ++ UINT_8 aucPeerAddr[MAC_ADDR_LEN]; ++ } uTypeData; ++ BOOLEAN fgIsTxDoneIndicate; ++} SERVICE_DISCOVERY_FRAME_DATA_T, *P_SERVICE_DISCOVERY_FRAME_DATA_T; ++ ++struct _P2P_FSM_INFO_T_DEPRECATED { ++ /* P2P FSM State */ ++ ENUM_P2P_STATE_T eCurrentState; ++ ++ /* Channel */ ++ BOOLEAN fgIsChannelRequested; ++ ++ ENUM_P2P_STATE_T ePreviousState; ++ ++ ENUM_P2P_STATE_T eReturnState; /* Return state after current activity finished or abort. */ ++ ++ UINT_8 aucTargetIfAddr[PARAM_MAC_ADDR_LEN]; ++ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ ++ ++ P_STA_RECORD_T prTargetStaRec; ++ ++ BOOLEAN fgIsRsponseProbe; /* Indicate if P2P FSM can response probe request frame. */ ++ ++ /* Sequence number of requested message. */ ++ UINT_8 ucSeqNumOfReqMsg; /* Used for SAA FSM request message. */ ++ ++ /* Channel Privilege */ ++ UINT_8 ucSeqNumOfChReq; /* Used for Channel Request message. */ ++ ++ UINT_8 ucSeqNumOfScnMsg; /* Used for SCAN FSM request message. */ ++ UINT_8 ucSeqNumOfCancelMsg; ++ ++ UINT_8 ucDialogToken; ++ UINT_8 ucRxDialogToken; ++ ++ /* Timer */ ++ TIMER_T rDeviceDiscoverTimer; /* For device discovery time of each discovery request from user. */ ++ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ ++ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ ++ ++ TIMER_T rRejoinTimer; /* A timer used for Action frame timeout usage. */ ++ ++ /* Flag to indicate Provisioning */ ++ BOOLEAN fgIsConnectionRequested; ++ ++ /* Current IOCTL. */ ++ ENUM_P2P_IOCTL_T eP2pIOCTL; ++ ++ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ ++ ++ /*--------SERVICE DISCOVERY--------*/ ++ QUE_T rQueueGASRx; /* Input Request/Response. */ ++ QUE_T rQueueGASTx; /* Output Response. */ ++ P_SERVICE_DISCOVERY_FRAME_DATA_T prSDRequest; ++ UINT_8 ucVersionNum; /* GAS packet sequence number for...Action Frame? */ ++ UINT_8 ucGlobalSeqNum; /* Sequence Number of RX SD packet. */ ++ /*--------Service DISCOVERY--------*/ ++ ++ /*--------DEVICE DISCOVERY---------*/ ++ UINT_8 aucTargetGroupID[PARAM_MAC_ADDR_LEN]; ++ UINT_16 u2TargetGroupSsidLen; ++ UINT_8 aucTargetSsid[32]; ++ UINT_8 aucSearchingP2pDevice[PARAM_MAC_ADDR_LEN]; ++ UINT_8 ucDLToken; ++ /*----------------------------------*/ ++ ++ /* Indicating Peer Status. */ ++ UINT_32 u4Flags; ++ ++ /*Indicating current running mode. */ ++ BOOLEAN fgIsApMode; ++ ++ /*------------INVITATION------------*/ ++ ENUM_P2P_INVITATION_POLICY eInvitationRspPolicy; ++ /*----------------------------------*/ ++ ++}; ++ ++struct _P2P_SPECIFIC_BSS_INFO_T { ++ /* For GO(AP) Mode - Compose TIM IE */ ++ UINT_16 u2SmallestAID; ++ UINT_16 u2LargestAID; ++ UINT_8 ucBitmapCtrl; ++ /* UINT_8 aucPartialVirtualBitmap[MAX_LEN_TIM_PARTIAL_BMP]; */ ++ ++ /* For GC/GO OppPS */ ++ BOOLEAN fgEnableOppPS; ++ UINT_16 u2CTWindow; ++ ++ /* For GC/GO NOA */ ++ UINT_8 ucNoAIndex; ++ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ ++ NOA_TIMING_T arNoATiming[P2P_MAXIMUM_NOA_COUNT]; ++ ++ BOOLEAN fgIsNoaAttrExisted; ++ ++ /* For P2P Device */ ++ UINT_8 ucRegClass; /* Regulatory Class for channel. */ ++ UINT_8 ucListenChannel; /* Linten Channel only on channels 1, 6 and 11 in the 2.4 GHz. */ ++ ++ UINT_8 ucPreferredChannel; /* Operating Channel, should be one of channel list ++ in p2p connection settings. */ ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ++ /* Extended Listen Timing. */ ++ UINT_16 u2AvailabilityPeriod; ++ UINT_16 u2AvailabilityInterval; ++ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++ UINT_16 u2IELenForBCN; ++ UINT_8 aucBeaconIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++ ++/* UINT_16 u2IELenForProbeRsp; */ ++/* UINT_8 aucProbeRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; */ ++ ++ UINT_16 u2IELenForAssocRsp; ++ UINT_8 aucAssocRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++ ++#else ++ UINT_16 u2AttributeLen; ++ UINT_8 aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++ ++ UINT_16 u2WscAttributeLen; ++ UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++#endif ++ UINT_8 aucGroupID[MAC_ADDR_LEN]; ++ UINT_16 u2GroupSsidLen; ++ UINT_8 aucGroupSsid[ELEM_MAX_LEN_SSID]; ++ ++ PARAM_CUSTOM_NOA_PARAM_STRUCT_T rNoaParam; ++ PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T rOppPsParam; ++ ++ UINT_16 u2WpaIeLen; ++ UINT_8 aucWpaIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_WPA]; ++}; ++ ++typedef struct _MSG_P2P_DEVICE_DISCOVER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_32 u4DevDiscoverTime; /* 0: Infinite, 1~X: in unit of MS. */ ++ BOOLEAN fgIsSpecificType; ++#if CFG_ENABLE_WIFI_DIRECT ++ P2P_DEVICE_TYPE_T rTargetDeviceType; ++#endif ++ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN]; ++} MSG_P2P_DEVICE_DISCOVER_T, *P_MSG_P2P_DEVICE_DISCOVER_T; ++ ++typedef struct _MSG_P2P_INVITATION_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 aucDeviceID[MAC_ADDR_LEN]; /* Target Device ID to be invited. */ ++} MSG_P2P_INVITATION_REQUEST_T, *P_MSG_P2P_INVITATION_REQUEST_T; ++ ++typedef struct _MSG_P2P_FUNCTION_SWITCH_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ BOOLEAN fgIsFuncOn; ++} MSG_P2P_FUNCTION_SWITCH_T, *P_MSG_P2P_FUNCTION_SWITCH_T; ++ ++typedef struct _MSG_P2P_SERVICE_DISCOVERY_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 aucDeviceID[MAC_ADDR_LEN]; ++ BOOLEAN fgNeedTxDoneIndicate; ++ UINT_8 ucSeqNum; ++} MSG_P2P_SERVICE_DISCOVERY_REQUEST_T, *P_MSG_P2P_SERVICE_DISCOVERY_REQUEST_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define p2pChangeMediaState(_prAdapter, _eNewMediaState) \ ++do { \ ++ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState = (_eNewMediaState));\ ++ wfdChangeMediaState((_prAdapter), NETWORK_TYPE_P2P_INDEX, (_eNewMediaState)); \ ++} while (0) ++ ++#define ATTRI_ID(_fp) (((P_P2P_ATTRIBUTE_T) _fp)->ucId) ++#define ATTRI_LEN(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[0]) | \ ++ ((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[1] << 8)) ++ ++#define ATTRI_SIZE(_fp) (P2P_ATTRI_HDR_LEN + ATTRI_LEN(_fp)) ++ ++#define P2P_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ ++ (_u2Offset) += ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += ATTRI_SIZE(_pucAttriBuf))) ++ ++#define P2P_IE(_fp) ((P_IE_P2P_T) _fp) ++ ++#define WSC_ATTRI_ID(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[0] << 8) | \ ++ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[1])) ++ ++#define WSC_ATTRI_LEN(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ ++ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[1])) ++ ++#define WSC_ATTRI_SIZE(_fp) (WSC_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp)) ++ ++#define WSC_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ ++ (_u2Offset) += WSC_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WSC_ATTRI_SIZE(_pucAttriBuf))) ++ ++#define WSC_IE(_fp) ((P_IE_P2P_T) _fp) ++ ++#define WFD_ATTRI_ID(_fp) (((P_WFD_ATTRIBUTE_T) _fp)->ucElemID) ++ ++#define WFD_ATTRI_LEN(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ ++ ((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[1])) ++ ++#define WFD_ATTRI_SIZE(_fp) (WFD_ATTRI_HDR_LEN + WFD_ATTRI_LEN(_fp)) ++ ++#define WFD_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ ++ (_u2Offset) += WFD_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WFD_ATTRI_SIZE(_pucAttriBuf))) ++ ++#if DBG ++#define ASSERT_BREAK(_exp) \ ++ { \ ++ if (!(_exp)) { \ ++ ASSERT(FALSE); \ ++ break; \ ++ } \ ++ } ++ ++#else ++#define ASSERT_BREAK(_exp) ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*======P2P State======*/ ++VOID ++p2pStateInit_LISTEN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_SPECIFIC_BSS_INFO_T prSP2pBssInfo, IN UINT_8 ucListenChannel); ++ ++VOID p2pStateAbort_LISTEN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); ++ ++VOID p2pStateAbort_SEARCH_SCAN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); ++ ++VOID p2pStateAbort_GO_OPERATION(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pStateAbort_GC_OPERATION(IN P_ADAPTER_T prAdapter); ++ ++VOID ++p2pStateInit_CONFIGURATION(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecBssInfo); ++ ++VOID p2pStateAbort_CONFIGURATION(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pStateInit_JOIN(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pStateAbort_JOIN(IN P_ADAPTER_T prAdapter); ++ ++/*====== P2P Functions ======*/ ++ ++VOID p2pFuncInitGO(IN P_ADAPTER_T prAdapter); ++ ++VOID ++p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); ++ ++VOID ++p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW); ++ ++VOID p2pFuncRunEventProvisioningComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++WLAN_STATUS p2pFuncSetGroupID(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucGroupID, IN PUINT_8 pucSsid, IN UINT_8 ucSsidLen); ++ ++WLAN_STATUS ++p2pFuncSendDeviceDiscoverabilityReqFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); ++ ++WLAN_STATUS ++p2pFuncSendDeviceDiscoverabilityRspFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); ++ ++UINT_8 p2pFuncGetVersionNumOfSD(IN P_ADAPTER_T prAdapter); ++ ++/*====== P2P FSM ======*/ ++VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventDeviceDiscoveryRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventDeviceDiscoveryAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventRxGroupNegotiationReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++p2pFsmRunEventGroupNegotiationRequestTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventGroupNegotiationResponseTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventGroupNegotiationConfirmTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventProvisionDiscoveryRequestTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventProvisionDiscoveryResponseTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventInvitationRequestTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++#if 1 ++#endif ++ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/*======Mail Box Event Message=====*/ ++ ++VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventConnectionTrigger(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventP2PFunctionSwitch(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventConnectionPause(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID ++p2pIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN UINT_8 aucTargetAddr[]); ++ ++VOID p2pUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); ++ ++/*======Mail Box Event Message=====*/ ++ ++VOID p2pFsmInit(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pStartGO(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); ++ ++VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventIOReqTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); ++ ++VOID p2pFsmRunEventSearchPeriodTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); ++ ++VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG u4Param); ++ ++VOID p2pFsmRunEventRejoinTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Parm); ++ ++/*=============== P2P Function Related ================*/ ++ ++/*=============== P2P Function Related ================*/ ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++VOID p2pTest(IN P_ADAPTER_T prAdapter); ++#endif /* CFG_TEST_WIFI_DIRECT_GO */ ++ ++VOID p2pGenerateP2P_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID p2pGenerateP2P_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID ++p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pCalculateP2P_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pCalculateP2P_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pGenerateWSC_IEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID ++p2pGenerateWSC_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_16 p2pCalculateWSC_IELenForProbeReq(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++UINT_32 ++p2pCalculateWSC_IELenForProbeResp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriStatus(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriCapability(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriGoIntent(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriCfgTimeout(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriGroupBssid(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceIDForBeacon(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceIDForProbeReq(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceIDForDeviceDiscoveryReq(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriListenChannel(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriIntendP2pIfAddr(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriChannelList(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 p2pCalculateAttriLenChannelList(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriNoA(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 p2pCalculateAttriLenDeviceInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriGroupInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 p2pCalculateAttriLenGroupInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriP2pGroupID(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriOperatingChannel(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriInvitationFlag(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++VOID ++p2pGenerateWscIE(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); ++ ++UINT_32 ++p2pAppendAttriWSCConfigMethod(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriWSCVersion(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriWSCGONegReqDevPasswordId(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriWSCGONegRspDevPasswordId(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++WLAN_STATUS ++p2pGetWscAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); ++ ++WLAN_STATUS ++p2pGetAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); ++ ++VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS p2pSendProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++BOOLEAN p2pFsmRunEventRxProbeRequestFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc); ++ ++WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxGroupNegotiationRspFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxGroupNegotiationCfmFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++#if 0 /* frog */ ++BOOLEAN scanMatchFilterOfP2P(IN P_SW_RFB_T prSWRfb, IN PP_BSS_DESC_T pprBssDesc); ++#endif /* frog */ ++ ++VOID ++p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); ++ ++VOID p2pFuncCompleteIOCTL(IN P_ADAPTER_T prAdapter, IN WLAN_STATUS rWlanStatus); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this for porting driver to different RTOS. ++ */ ++static inline VOID p2pDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(IE_P2P_T) == (2 + 4 + 1)); /* all UINT_8 */ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRIBUTE_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_STATUS_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_REASON_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CAPABILITY_T) == (3 + 2)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_ID_T) == (3 + 6)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GO_INTENT_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CFG_TIMEOUT_T) == (3 + 2)); ++#if CID52_53_54 ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); ++#else ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); ++#endif ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_BSSID_T) == (3 + 6)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_EXT_LISTEN_TIMING_T) == (3 + 4)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTENDED_IF_ADDR_T) == (3 + 6)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_MANAGEABILITY_T) == (3 + 1)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CHANNEL_T) == (3 + 4)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(CHANNEL_ENTRY_FIELD_T) == 3); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_NOA_T) == (3 + 3)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(NOA_DESCRIPTOR_T) == 13); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_TYPE_T) == 8); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_INFO_T) == (3 + 6 + 2 + 8 + 1 + 8)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_NAME_TLV_T) == (4 + 32)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_CLIENT_INFO_DESC_T) == (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_INFO_T) == (3 + (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8))); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_ID_T) == (3 + 38)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTERFACE_T) == (3 + 13)); ++#if CID52_53_54 ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); ++#else ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); ++#endif ++ ++} ++#endif /* _lint */ ++ ++#endif /* _P2P_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h +new file mode 100644 +index 000000000000..1ac1770debca +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h +@@ -0,0 +1,155 @@ ++#ifndef _P2P_FUNC_H ++#define _P2P_FUNC_H ++ ++#define P2P_EXT_LISTEN_TIME_MS 600 ++#define P2P_OFF_CHNL_TX_DEFAULT_TIME_MS 1000 ++ ++VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); ++ ++VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); ++ ++VOID ++p2pFuncStartGO(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, ++ IN PUINT_8 pucSsidBuf, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP); ++ ++VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); ++ ++VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); ++ ++VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo); ++ ++BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo); ++ ++VOID ++p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); ++ ++WLAN_STATUS ++p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); ++ ++WLAN_STATUS ++p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, ++ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, ++ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen); ++ ++BOOLEAN ++p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); ++ ++BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings); ++ ++BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); ++ ++BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID ++p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen); ++ ++P_BSS_DESC_T ++p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, ++ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); ++ ++VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID ++p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, ++ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter); ++ ++VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter); ++ ++VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo); ++ ++BOOLEAN ++p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); ++ ++P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu); ++ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++UINT_32 ++p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#else ++UINT_32 ++p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++#endif ++UINT_32 ++p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_STA_RECORD_T prStaRec, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); ++ ++VOID ++p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); ++ ++UINT_32 ++p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++VOID ++p2pFuncDissolve(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); ++ ++P_IE_HDR_T ++p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore); ++ ++P_ATTRIBUTE_HDR_T ++p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID); ++ ++WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ++ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h +new file mode 100644 +index 000000000000..efb75855695f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h +@@ -0,0 +1,156 @@ ++#ifndef _P2P_IE_H ++#define _P2P_IE_H ++ ++#if CFG_SUPPORT_WFD ++ ++#define ELEM_MAX_LEN_WFD 62 /* TODO: Move to appropriate place */ ++ ++/*---------------- WFD Data Element Definitions ----------------*/ ++/* WFD 4.1.1 - WFD IE format */ ++#define WFD_OUI_TYPE_LEN 4 ++#define WFD_IE_OUI_HDR (ELEM_HDR_LEN + WFD_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, ++ aucP2PAttributes[0]) */ ++ ++/* WFD 4.1.1 - General WFD Attribute */ ++#define WFD_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ ++ ++/* WFD Attribute Code */ ++#define WFD_ATTRI_ID_DEV_INFO 0 ++#define WFD_ATTRI_ID_ASSOC_BSSID 1 ++#define WFD_ATTRI_ID_COUPLED_SINK_INFO 6 ++#define WFD_ATTRI_ID_EXT_CAPABILITY 7 ++#define WFD_ATTRI_ID_SESSION_INFO 9 ++#define WFD_ATTRI_ID_ALTER_MAC_ADDRESS 10 ++ ++/* Maximum Length of WFD Attributes */ ++#define WFD_ATTRI_MAX_LEN_DEV_INFO 6 /* 0 */ ++#define WFD_ATTRI_MAX_LEN_ASSOC_BSSID 6 /* 1 */ ++#define WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO 7 /* 6 */ ++#define WFD_ATTRI_MAX_LEN_EXT_CAPABILITY 2 /* 7 */ ++#define WFD_ATTRI_MAX_LEN_SESSION_INFO 0 /* 9 */ /* 24 * #Clients */ ++#define WFD_ATTRI_MAX_LEN_ALTER_MAC_ADDRESS 6 /* 10 */ ++ ++/* WFD 1.10 5.1.1 */ ++typedef struct _IE_WFD_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 aucWFDAttributes[1]; /* WFD Subelement */ ++} __KAL_ATTRIB_PACKED__ IE_WFD_T, *P_IE_WFD_T; ++ ++typedef struct _WFD_ATTRIBUTE_T { ++ UINT_8 ucElemID; /* Subelement ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBody[1]; /* Body field */ ++} __KAL_ATTRIB_PACKED__ WFD_ATTRIBUTE_T, *P_WFD_ATTRIBUTE_T; ++ ++typedef struct _WFD_DEVICE_INFORMATION_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_16 u2WfdDevInfo; ++ UINT_16 u2SessionMgmtCtrlPort; ++ UINT_16 u2WfdDevMaxSpeed; ++} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_IE_T, *P_WFD_DEVICE_INFORMATION_IE_T; ++ ++typedef struct _WFD_ASSOCIATED_BSSID_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WFD_ASSOCIATED_BSSID_IE_T, *P_WFD_ASSOCIATED_BSSID_IE_T; ++ ++typedef struct _WFD_COUPLE_SINK_INFORMATION_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_8 ucCoupleSinkStatusBp; ++ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WFD_COUPLE_SINK_INFORMATION_IE_T, *P_WFD_COUPLE_SINK_INFORMATION_IE_T; ++ ++typedef struct _WFD_EXTENDED_CAPABILITY_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_16 u2WfdExtCapabilityBp; ++} __KAL_ATTRIB_PACKED__ WFD_EXTENDED_CAPABILITY_IE_T, *P_WFD_EXTENDED_CAPABILITY_IE_T; ++ ++typedef struct _WFD_SESSION_INFORMATION_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ PUINT_8 pucWfdDevInfoDesc[1]; ++} __KAL_ATTRIB_PACKED__ WFD_SESSION_INFORMATION_IE_T, *P_WFD_SESSION_INFORMATION_IE_T; ++ ++typedef struct _WFD_DEVICE_INFORMATION_DESCRIPTOR_T { ++ UINT_8 ucLength; ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; ++ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; ++ UINT_16 u2WfdDevInfo; ++ UINT_16 u2WfdDevMaxSpeed; ++ UINT_8 ucCoupleSinkStatusBp; ++ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_DESCRIPTOR_T, *P_WFD_DEVICE_INFORMATION_DESCRIPTOR_T; ++ ++#endif ++ ++UINT_32 ++p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#if CFG_SUPPORT_WFD ++ ++UINT_32 ++wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForProbeResp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForAssocReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#endif ++ ++UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h +new file mode 100644 +index 000000000000..32bc14c10959 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h +@@ -0,0 +1,74 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm.h#1 ++*/ ++ ++/*! \file "rlm.h" ++ \brief ++*/ ++ ++#ifndef _P2P_RLM_H ++#define _P2P_RLM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); ++ ++VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter); ++ ++VOID ++rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, ++ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize); ++ ++UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum); ++ ++BOOLEAN ++rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucCheckChnl, ++ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel); ++ ++ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h +new file mode 100644 +index 000000000000..5b6e756f48dd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h +@@ -0,0 +1,64 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm_obss.h#1 ++*/ ++ ++/*! \file "rlm_obss.h" ++ \brief ++*/ ++ ++#ifndef _P2P_RLM_OBSS_H ++#define _P2P_RLM_OBSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); ++ ++UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h +new file mode 100644 +index 000000000000..8db6aa5c31e0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h +@@ -0,0 +1,81 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_scan.h#1 ++*/ ++ ++/*! \file "scan.h" ++ \brief ++ ++*/ ++ ++#ifndef _P2P_SCAN_H ++#define _P2P_SCAN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); ++ ++P_P2P_DEVICE_DESC_T ++scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc); ++ ++P_P2P_DEVICE_DESC_T ++scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, ++ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound); ++ ++P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum); ++ ++BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID ++scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN P_WLAN_STATUS prStatus, ++ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); ++ ++VOID scanRemoveAllP2pBssDesc(P_ADAPTER_T prAdapter); ++ ++VOID scanRemoveP2pBssDesc(P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++P_BSS_DESC_T ++scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h +new file mode 100644 +index 000000000000..8f0c4c1564a8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h +@@ -0,0 +1,43 @@ ++#ifndef _P2P_STATE_H ++#define _P2P_STATE_H ++ ++BOOLEAN ++p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState); ++ ++VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID ++p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID ++p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID ++p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID ++p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID ++p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc); ++ ++VOID ++p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h +new file mode 100644 +index 000000000000..c80430ae4eb5 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h +@@ -0,0 +1,230 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/privacy.h#1 ++*/ ++ ++/*! \file privacy.h ++ \brief This file contains the function declaration for privacy.c. ++*/ ++ ++/* ++** Log: privacy.h ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * For support the WHQL test, do the remove key code refine. ++ * ++ * Dec 10 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the cmd return type ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function declaration for auth mode and encryption status setting from build connection command ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function declaration for wapi ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the tx done callback handle function ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function declaration for mac header privacy bit setting ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the structure for parsing the EAPoL frame ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the class error function parameter ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some security function declaration ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the ap selection structure ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++#ifndef _PRIVACY_H ++#define _PRIVACY_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define MAX_KEY_NUM 4 ++#define WEP_40_LEN 5 ++#define WEP_104_LEN 13 ++#define LEGACY_KEY_MAX_LEN 16 ++#define CCMP_KEY_LEN 16 ++#define TKIP_KEY_LEN 32 ++#define MAX_KEY_LEN 32 ++#define MIC_RX_KEY_OFFSET 16 ++#define MIC_TX_KEY_OFFSET 24 ++#define MIC_KEY_LEN 8 ++ ++#define WEP_KEY_ID_FIELD BITS(0, 29) ++#define KEY_ID_FIELD BITS(0, 7) ++ ++#define IS_TRANSMIT_KEY BIT(31) ++#define IS_UNICAST_KEY BIT(30) ++#define IS_AUTHENTICATOR BIT(28) ++ ++#define CIPHER_SUITE_NONE 0 ++#define CIPHER_SUITE_WEP40 1 ++#define CIPHER_SUITE_TKIP 2 ++#define CIPHER_SUITE_TKIP_WO_MIC 3 ++#define CIPHER_SUITE_CCMP 4 ++#define CIPHER_SUITE_WEP104 5 ++#define CIPHER_SUITE_BIP 6 ++#define CIPHER_SUITE_WEP128 7 ++#define CIPHER_SUITE_WPI 8 ++ ++#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */ ++#define WPA_KEY_INFO_MIC BIT(8) ++#define WPA_KEY_INFO_SECURE BIT(9) ++ ++#define MASK_2ND_EAPOL (WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _IEEE_802_1X_HDR { ++ UINT_8 ucVersion; ++ UINT_8 ucType; ++ UINT_16 u2Length; ++ /* followed by length octets of data */ ++} IEEE_802_1X_HDR, *P_IEEE_802_1X_HDR; ++ ++typedef struct _EAPOL_KEY { ++ UINT_8 ucType; ++ /* Note: key_info, key_length, and key_data_length are unaligned */ ++ UINT_8 aucKeyInfo[2]; /* big endian */ ++ UINT_8 aucKeyLength[2]; /* big endian */ ++ UINT_8 aucReplayCounter[8]; ++ UINT_8 aucKeyNonce[16]; ++ UINT_8 aucKeyIv[16]; ++ UINT_8 aucKeyRsc[8]; ++ UINT_8 aucKeyId[8]; /* Reserved in IEEE 802.11i/RSN */ ++ UINT_8 aucKeyMic[16]; ++ UINT_8 aucKeyDataLength[2]; /* big endian */ ++ /* followed by key_data_length bytes of key_data */ ++} EAPOL_KEY, *P_EAPOL_KEY; ++ ++/* WPA2 PMKID candicate structure */ ++typedef struct _PMKID_CANDICATE_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_32 u4PreAuthFlags; ++} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; ++ ++#if 0 ++/* WPA2 PMKID cache structure */ ++typedef struct _PMKID_ENTRY_T { ++ PARAM_BSSID_INFO_T rBssidInfo; ++ BOOLEAN fgPmkidExist; ++} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx); ++ ++VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPort); ++ ++BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec); ++ ++BOOLEAN secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec); ++ ++BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); ++ ++VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags); ++ ++BOOLEAN ++secProcessEAPOL(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, ++ IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen); ++ ++VOID ++secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T pMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus); ++ ++BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec); ++ ++VOID secClearPmkid(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _PRIVACY_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h +new file mode 100644 +index 000000000000..123dbebdacaf +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h +@@ -0,0 +1,93 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rate.h#1 ++*/ ++ ++/*! \file rate.h ++ \brief This file contains the rate utility function of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: rate.h ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++*/ ++ ++#ifndef _RATE_H ++#define _RATE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in rate.c */ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, ++ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, ++ OUT PUINT_16 pu2OperationalRateSet, ++ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate); ++ ++VOID ++rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, ++ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen); ++ ++BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex); ++ ++BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RATE_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h +new file mode 100644 +index 000000000000..1af3841ecec2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h +@@ -0,0 +1,396 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm.h#2 ++*/ ++ ++/*! \file "rlm.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Refine function when rcv a 20/40M public action frame ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * Use SCO of BSS_INFO to replace user-defined setting variables ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 18 2010 cm.chang ++ * [WCXRP00000114] [MT6620 Wi-Fi] [Driver] Fix compiling warning in Linux about RLM network index checking ++ * Enum member cannot be used as compiling option decision in Linux ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX HT GF compiling option ++ * ++ * 06 02 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Roll back to remove CFG_SUPPORT_BCM_TEST. ++ * ++ * 06 01 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Update BCM Test and RW configuration. ++ * ++ * 05 31 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add some compiling options to control 11n functions ++ * ++ * 05 18 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Ad-hoc Beacon should not carry HT OP and OBSS IEs ++ * ++ * 05 17 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * MT6620 does not support L-SIG TXOP ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Different invoking order for WTBL entry of associated AP ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Move default value of HT capability to rlm.h ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * ++ * Modify the prototype of rlmRecAssocRspHtInfo() ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add several function prototypes for HT operation ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++** ++*/ ++ ++#ifndef _RLM_H ++#define _RLM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define ELEM_EXT_CAP_DEFAULT_VAL \ ++ (ELEM_EXT_CAP_20_40_COEXIST_SUPPORT /*| ELEM_EXT_CAP_PSMP_CAP*/) ++ ++#if CFG_SUPPORT_RX_STBC ++#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_1_SS ++#else ++#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_NO_SUPPORTED ++#endif ++ ++#if CFG_SUPPORT_RX_SGI ++#define FIELD_HT_CAP_INFO_SGI_20M HT_CAP_INFO_SHORT_GI_20M ++#define FIELD_HT_CAP_INFO_SGI_40M HT_CAP_INFO_SHORT_GI_40M ++#else ++#define FIELD_HT_CAP_INFO_SGI_20M 0 ++#define FIELD_HT_CAP_INFO_SGI_40M 0 ++#endif ++ ++#if CFG_SUPPORT_RX_HT_GF ++#define FIELD_HT_CAP_INFO_HT_GF HT_CAP_INFO_HT_GF ++#else ++#define FIELD_HT_CAP_INFO_HT_GF 0 ++#endif ++ ++#define HT_CAP_INFO_DEFAULT_VAL \ ++ (HT_CAP_INFO_SUP_CHNL_WIDTH | FIELD_HT_CAP_INFO_HT_GF | \ ++ FIELD_HT_CAP_INFO_SGI_20M | FIELD_HT_CAP_INFO_SGI_40M | \ ++ FIELD_HT_CAP_INFO_RX_STBC | HT_CAP_INFO_DSSS_CCK_IN_40M) ++ ++#define AMPDU_PARAM_DEFAULT_VAL \ ++ (AMPDU_PARAM_MAX_AMPDU_LEN_64K | AMPDU_PARAM_MSS_NO_RESTRICIT) ++ ++#define SUP_MCS_TX_DEFAULT_VAL \ ++ SUP_MCS_TX_SET_DEFINED /* TX defined and TX/RX equal (TBD) */ ++ ++#if CFG_SUPPORT_MFB ++#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_BOTH ++#else ++#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_NO_FB ++#endif ++ ++#if CFG_SUPPORT_RX_RDG ++#define FIELD_HT_EXT_CAP_RDR HT_EXT_CAP_RD_RESPONDER ++#else ++#define FIELD_HT_EXT_CAP_RDR 0 ++#endif ++ ++#if CFG_SUPPORT_MFB || CFG_SUPPORT_RX_RDG ++#define FIELD_HT_EXT_CAP_HTC HT_EXT_CAP_HTC_SUPPORT ++#else ++#define FIELD_HT_EXT_CAP_HTC 0 ++#endif ++ ++#define HT_EXT_CAP_DEFAULT_VAL \ ++ (HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE | \ ++ FIELD_HT_EXT_CAP_MFB | FIELD_HT_EXT_CAP_HTC | \ ++ FIELD_HT_EXT_CAP_RDR) ++ ++#define TX_BEAMFORMING_CAP_DEFAULT_VAL 0 ++#define ASEL_CAP_DEFAULT_VAL 0 ++ ++/* Define bandwidth from user setting */ ++#define CONFIG_BW_20_40M 0 ++#define CONFIG_BW_20M 1 /* 20MHz only */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* It is used for RLM module to judge if specific network is valid ++ * Note: Ad-hoc mode of AIS is not included now. (TBD) ++ */ ++#define RLM_NET_PARAM_VALID(_prBssInfo) \ ++ (IS_BSS_ACTIVE(_prBssInfo) && \ ++ ((_prBssInfo)->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || \ ++ (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT || \ ++ (_prBssInfo)->eCurrentOPMode == OP_MODE_IBSS || \ ++ RLM_NET_IS_BOW(_prBssInfo)) \ ++ ) ++ ++#define RLM_NET_IS_11N(_prBssInfo) \ ++ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11N) ++#define RLM_NET_IS_11GN(_prBssInfo) \ ++ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11GN) ++ ++/* This macro is used to sweep all 3 networks */ ++#define RLM_NET_FOR_EACH(_ucNetIdx) \ ++ for ((_ucNetIdx) = 0; \ ++ (_ucNetIdx) < NETWORK_TYPE_INDEX_NUM; \ ++ (_ucNetIdx)++) ++ ++/* This macro is used to sweep all networks excluding BOW */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /* Note: value of enum NETWORK_TYPE_BOW_INDEX is validated in ++ * rlmStuctureCheck(). ++ */ ++#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) \ ++ for ((_ucNetIdx) = 0; \ ++ (_ucNetIdx) < NETWORK_TYPE_BOW_INDEX; \ ++ (_ucNetIdx)++) ++ ++#define RLM_NET_IS_BOW(_prBssInfo) \ ++ ((_prBssInfo)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++ ++#else ++#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) RLM_NET_FOR_EACH(_ucNetIdx) ++#define RLM_NET_IS_BOW(_prBssInfo) (FALSE) ++ ++#endif /* end of CFG_ENABLE_BT_OVER_WIFI */ ++ ++/* The bandwidth modes are not used anymore. They represent if AP ++ * can use 20/40 bandwidth, not all modes. (20110411) ++ */ ++#define RLM_AP_IS_BW_40_ALLOWED(_prAdapter, _prBssInfo) \ ++ (((_prBssInfo)->eBand == BAND_2G4 && \ ++ (_prAdapter)->rWifiVar.rConnSettings.uc2G4BandwidthMode \ ++ == CONFIG_BW_20_40M) || \ ++ ((_prBssInfo)->eBand == BAND_5G && \ ++ (_prAdapter)->rWifiVar.rConnSettings.uc5GBandwidthMode \ ++ == CONFIG_BW_20_40M)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID rlmFsmEventInit(P_ADAPTER_T prAdapter); ++ ++VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter); ++ ++VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++UINT32 ++rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, ++ BOOLEAN fgShortGIDisabled, ++ UINT_8 u8SupportRxSgi20, ++ UINT_8 u8SupportRxSgi40, ++ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf); ++ ++UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme); ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE); ++#endif ++ ++VOID ++rlmTxRateEnhanceConfig( ++ P_ADAPTER_T prAdapter ++ ); ++ ++VOID ++rlmCmd( ++ P_GLUE_INFO_T prGlueInfo, ++ UINT_8 *prInBuf, ++ UINT_32 u4InBufLen ++ ); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#ifndef _lint ++static inline VOID rlmDataTypeCheck(VOID) ++{ ++#if CFG_ENABLE_BT_OVER_WIFI ++ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_AIS_INDEX < NETWORK_TYPE_BOW_INDEX); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_P2P_INDEX < NETWORK_TYPE_BOW_INDEX); ++#endif ++#endif ++ ++} ++#endif /* _lint */ ++ ++#endif /* _RLM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h +new file mode 100644 +index 000000000000..65e907041a28 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h +@@ -0,0 +1,557 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_domain.h#1 ++*/ ++ ++/*! \file "rlm_domain.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_domain.h ++ * ++ * 09 29 2011 cm.chang ++ * NULL ++ * Change the function prototype of rlmDomainGetChnlList() ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Provide legal channel function based on domain ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 01 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Provide query function about full channel list. ++ * ++ * Dec 1 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Declare public rDomainInfo ++ * ++** ++*/ ++ ++#ifndef _RLM_DOMAIN_H ++#define _RLM_DOMAIN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define MAX_SUBBAND_NUM 6 ++#define MAX_SUBBAND_NUM_5G 8 ++ ++#define COUNTRY_CODE_NULL ((UINT_16)0x0) ++ ++/* ISO/IEC 3166-1 two-character country codes */ ++ ++#define COUNTRY_CODE_AD (((UINT_16) 'A' << 8) | (UINT_16) 'D') /* Andorra */ ++#define COUNTRY_CODE_AE (((UINT_16) 'A' << 8) | (UINT_16) 'E') /* UAE */ ++#define COUNTRY_CODE_AF (((UINT_16) 'A' << 8) | (UINT_16) 'F') /* Afghanistan */ ++#define COUNTRY_CODE_AG (((UINT_16) 'A' << 8) | (UINT_16) 'G') /* Antigua & Barbuda */ ++#define COUNTRY_CODE_AI (((UINT_16) 'A' << 8) | (UINT_16) 'I') /* Anguilla */ ++#define COUNTRY_CODE_AL (((UINT_16) 'A' << 8) | (UINT_16) 'L') /* Albania */ ++#define COUNTRY_CODE_AM (((UINT_16) 'A' << 8) | (UINT_16) 'M') /* Armenia */ ++#define COUNTRY_CODE_AN (((UINT_16) 'A' << 8) | (UINT_16) 'N') /* Netherlands Antilles */ ++#define COUNTRY_CODE_AO (((UINT_16) 'A' << 8) | (UINT_16) 'O') /* Angola */ ++#define COUNTRY_CODE_AR (((UINT_16) 'A' << 8) | (UINT_16) 'R') /* Argentina */ ++#define COUNTRY_CODE_AS (((UINT_16) 'A' << 8) | (UINT_16) 'S') /* American Samoa (USA) */ ++#define COUNTRY_CODE_AT (((UINT_16) 'A' << 8) | (UINT_16) 'T') /* Austria */ ++#define COUNTRY_CODE_AU (((UINT_16) 'A' << 8) | (UINT_16) 'U') /* Australia */ ++#define COUNTRY_CODE_AW (((UINT_16) 'A' << 8) | (UINT_16) 'W') /* Aruba */ ++#define COUNTRY_CODE_AZ (((UINT_16) 'A' << 8) | (UINT_16) 'Z') /* Azerbaijan */ ++#define COUNTRY_CODE_BA (((UINT_16) 'B' << 8) | (UINT_16) 'A') /* Bosnia and Herzegovina */ ++#define COUNTRY_CODE_BB (((UINT_16) 'B' << 8) | (UINT_16) 'B') /* Barbados */ ++#define COUNTRY_CODE_BD (((UINT_16) 'B' << 8) | (UINT_16) 'D') /* Bangladesh */ ++#define COUNTRY_CODE_BE (((UINT_16) 'B' << 8) | (UINT_16) 'E') /* Belgium */ ++#define COUNTRY_CODE_BF (((UINT_16) 'B' << 8) | (UINT_16) 'F') /* Burkina Faso */ ++#define COUNTRY_CODE_BG (((UINT_16) 'B' << 8) | (UINT_16) 'G') /* Bulgaria */ ++#define COUNTRY_CODE_BH (((UINT_16) 'B' << 8) | (UINT_16) 'H') /* Bahrain */ ++#define COUNTRY_CODE_BI (((UINT_16) 'B' << 8) | (UINT_16) 'I') /* Burundi */ ++#define COUNTRY_CODE_BJ (((UINT_16) 'B' << 8) | (UINT_16) 'J') /* Benin */ ++#define COUNTRY_CODE_BM (((UINT_16) 'B' << 8) | (UINT_16) 'M') /* Bermuda */ ++#define COUNTRY_CODE_BN (((UINT_16) 'B' << 8) | (UINT_16) 'N') /* Brunei */ ++#define COUNTRY_CODE_BO (((UINT_16) 'B' << 8) | (UINT_16) 'O') /* Bolivia */ ++#define COUNTRY_CODE_BR (((UINT_16) 'B' << 8) | (UINT_16) 'R') /* Brazil */ ++#define COUNTRY_CODE_BS (((UINT_16) 'B' << 8) | (UINT_16) 'S') /* Bahamas */ ++#define COUNTRY_CODE_BT (((UINT_16) 'B' << 8) | (UINT_16) 'T') /* Bhutan */ ++#define COUNTRY_CODE_BW (((UINT_16) 'B' << 8) | (UINT_16) 'W') /* Botswana */ ++#define COUNTRY_CODE_BY (((UINT_16) 'B' << 8) | (UINT_16) 'Y') /* Belarus */ ++#define COUNTRY_CODE_BZ (((UINT_16) 'B' << 8) | (UINT_16) 'Z') /* Belize */ ++#define COUNTRY_CODE_CA (((UINT_16) 'C' << 8) | (UINT_16) 'A') /* Canada */ ++#define COUNTRY_CODE_CD (((UINT_16) 'C' << 8) | (UINT_16) 'D') /* Congo. Democratic Republic of the */ ++#define COUNTRY_CODE_CF (((UINT_16) 'C' << 8) | (UINT_16) 'F') /* Central African Republic */ ++#define COUNTRY_CODE_CG (((UINT_16) 'C' << 8) | (UINT_16) 'G') /* Congo. Republic of the */ ++#define COUNTRY_CODE_CH (((UINT_16) 'C' << 8) | (UINT_16) 'H') /* Switzerland */ ++#define COUNTRY_CODE_CI (((UINT_16) 'C' << 8) | (UINT_16) 'I') /* Cote d'lvoire */ ++#define COUNTRY_CODE_CK (((UINT_16) 'C' << 8) | (UINT_16) 'K') /* Cook Island */ ++#define COUNTRY_CODE_CL (((UINT_16) 'C' << 8) | (UINT_16) 'L') /* Chile */ ++#define COUNTRY_CODE_CM (((UINT_16) 'C' << 8) | (UINT_16) 'M') /* Cameroon */ ++#define COUNTRY_CODE_CN (((UINT_16) 'C' << 8) | (UINT_16) 'N') /* China */ ++#define COUNTRY_CODE_CO (((UINT_16) 'C' << 8) | (UINT_16) 'O') /* Columbia */ ++#define COUNTRY_CODE_CR (((UINT_16) 'C' << 8) | (UINT_16) 'R') /* Costa Rica */ ++#define COUNTRY_CODE_CU (((UINT_16) 'C' << 8) | (UINT_16) 'U') /* Cuba */ ++#define COUNTRY_CODE_CV (((UINT_16) 'C' << 8) | (UINT_16) 'V') /* Cape Verde */ ++#define COUNTRY_CODE_CX (((UINT_16) 'C' << 8) | (UINT_16) 'X') /* "Christmas Island(Australia) */ ++#define COUNTRY_CODE_CY (((UINT_16) 'C' << 8) | (UINT_16) 'Y') /* Cyprus */ ++#define COUNTRY_CODE_CZ (((UINT_16) 'C' << 8) | (UINT_16) 'Z') /* Czech */ ++#define COUNTRY_CODE_DE (((UINT_16) 'D' << 8) | (UINT_16) 'E') /* Germany */ ++#define COUNTRY_CODE_DJ (((UINT_16) 'D' << 8) | (UINT_16) 'J') /* Djibouti */ ++#define COUNTRY_CODE_DK (((UINT_16) 'D' << 8) | (UINT_16) 'K') /* Denmark */ ++#define COUNTRY_CODE_DM (((UINT_16) 'D' << 8) | (UINT_16) 'M') /* Dominica */ ++#define COUNTRY_CODE_DO (((UINT_16) 'D' << 8) | (UINT_16) 'O') /* Dominican Republic */ ++#define COUNTRY_CODE_DZ (((UINT_16) 'D' << 8) | (UINT_16) 'Z') /* Algeria */ ++#define COUNTRY_CODE_EC (((UINT_16) 'E' << 8) | (UINT_16) 'C') /* Ecuador */ ++#define COUNTRY_CODE_EE (((UINT_16) 'E' << 8) | (UINT_16) 'E') /* Estonia */ ++#define COUNTRY_CODE_EG (((UINT_16) 'E' << 8) | (UINT_16) 'G') /* Egypt */ ++#define COUNTRY_CODE_EH (((UINT_16) 'E' << 8) | (UINT_16) 'H') /* Western Sahara (Morocco) */ ++#define COUNTRY_CODE_ER (((UINT_16) 'E' << 8) | (UINT_16) 'R') /* Eritrea */ ++#define COUNTRY_CODE_ES (((UINT_16) 'E' << 8) | (UINT_16) 'S') /* Spain */ ++#define COUNTRY_CODE_ET (((UINT_16) 'E' << 8) | (UINT_16) 'T') /* Ethiopia */ ++#define COUNTRY_CODE_EU (((UINT_16) 'E' << 8) | (UINT_16) 'U') /* Europe */ ++#define COUNTRY_CODE_FI (((UINT_16) 'F' << 8) | (UINT_16) 'I') /* Finland */ ++#define COUNTRY_CODE_FJ (((UINT_16) 'F' << 8) | (UINT_16) 'J') /* Fiji */ ++#define COUNTRY_CODE_FK (((UINT_16) 'F' << 8) | (UINT_16) 'K') /* Falkland Island */ ++#define COUNTRY_CODE_FM (((UINT_16) 'F' << 8) | (UINT_16) 'M') /* Micronesia */ ++#define COUNTRY_CODE_FO (((UINT_16) 'F' << 8) | (UINT_16) 'O') /* Faroe Island */ ++#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* France */ ++#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* Wallis and Futuna (France) */ ++#define COUNTRY_CODE_GA (((UINT_16) 'G' << 8) | (UINT_16) 'A') /* Gabon */ ++#define COUNTRY_CODE_GB (((UINT_16) 'G' << 8) | (UINT_16) 'B') /* United Kingdom */ ++#define COUNTRY_CODE_GD (((UINT_16) 'G' << 8) | (UINT_16) 'D') /* Grenada */ ++#define COUNTRY_CODE_GE (((UINT_16) 'G' << 8) | (UINT_16) 'E') /* Georgia */ ++#define COUNTRY_CODE_GF (((UINT_16) 'G' << 8) | (UINT_16) 'F') /* French Guiana */ ++#define COUNTRY_CODE_GG (((UINT_16) 'G' << 8) | (UINT_16) 'G') /* Guernsey */ ++#define COUNTRY_CODE_GH (((UINT_16) 'G' << 8) | (UINT_16) 'H') /* Ghana */ ++#define COUNTRY_CODE_GI (((UINT_16) 'G' << 8) | (UINT_16) 'I') /* Gibraltar */ ++#define COUNTRY_CODE_GM (((UINT_16) 'G' << 8) | (UINT_16) 'M') /* Gambia */ ++#define COUNTRY_CODE_GN (((UINT_16) 'G' << 8) | (UINT_16) 'N') /* Guinea */ ++#define COUNTRY_CODE_GP (((UINT_16) 'G' << 8) | (UINT_16) 'P') /* Guadeloupe */ ++#define COUNTRY_CODE_GQ (((UINT_16) 'G' << 8) | (UINT_16) 'Q') /* Equatorial Guinea */ ++#define COUNTRY_CODE_GR (((UINT_16) 'G' << 8) | (UINT_16) 'R') /* Greece */ ++#define COUNTRY_CODE_GT (((UINT_16) 'G' << 8) | (UINT_16) 'T') /* Guatemala */ ++#define COUNTRY_CODE_GU (((UINT_16) 'G' << 8) | (UINT_16) 'U') /* Guam */ ++#define COUNTRY_CODE_GW (((UINT_16) 'G' << 8) | (UINT_16) 'W') /* Guinea-Bissau */ ++#define COUNTRY_CODE_GY (((UINT_16) 'G' << 8) | (UINT_16) 'Y') /* Guyana */ ++#define COUNTRY_CODE_HK (((UINT_16) 'H' << 8) | (UINT_16) 'K') /* Hong Kong */ ++#define COUNTRY_CODE_HN (((UINT_16) 'H' << 8) | (UINT_16) 'N') /* Honduras */ ++#define COUNTRY_CODE_HR (((UINT_16) 'H' << 8) | (UINT_16) 'R') /* Croatia */ ++#define COUNTRY_CODE_HT (((UINT_16) 'H' << 8) | (UINT_16) 'T') /* Haiti */ ++#define COUNTRY_CODE_HU (((UINT_16) 'H' << 8) | (UINT_16) 'U') /* Hungary */ ++#define COUNTRY_CODE_ID (((UINT_16) 'I' << 8) | (UINT_16) 'D') /* Indonesia */ ++#define COUNTRY_CODE_IE (((UINT_16) 'I' << 8) | (UINT_16) 'E') /* Ireland */ ++#define COUNTRY_CODE_IL (((UINT_16) 'I' << 8) | (UINT_16) 'L') /* Israel */ ++#define COUNTRY_CODE_IM (((UINT_16) 'I' << 8) | (UINT_16) 'M') /* Isle of Man */ ++#define COUNTRY_CODE_IN (((UINT_16) 'I' << 8) | (UINT_16) 'N') /* India */ ++#define COUNTRY_CODE_IQ (((UINT_16) 'I' << 8) | (UINT_16) 'Q') /* Iraq */ ++#define COUNTRY_CODE_IR (((UINT_16) 'I' << 8) | (UINT_16) 'R') /* Iran */ ++#define COUNTRY_CODE_IS (((UINT_16) 'I' << 8) | (UINT_16) 'S') /* Iceland */ ++#define COUNTRY_CODE_IT (((UINT_16) 'I' << 8) | (UINT_16) 'T') /* Italy */ ++#define COUNTRY_CODE_JE (((UINT_16) 'J' << 8) | (UINT_16) 'E') /* Jersey */ ++#define COUNTRY_CODE_JM (((UINT_16) 'J' << 8) | (UINT_16) 'M') /* Jameica */ ++#define COUNTRY_CODE_JO (((UINT_16) 'J' << 8) | (UINT_16) 'O') /* Jordan */ ++#define COUNTRY_CODE_JP (((UINT_16) 'J' << 8) | (UINT_16) 'P') /* Japan */ ++#define COUNTRY_CODE_KE (((UINT_16) 'K' << 8) | (UINT_16) 'E') /* Kenya */ ++#define COUNTRY_CODE_KG (((UINT_16) 'K' << 8) | (UINT_16) 'G') /* Kyrgyzstan */ ++#define COUNTRY_CODE_KH (((UINT_16) 'K' << 8) | (UINT_16) 'H') /* Cambodia */ ++#define COUNTRY_CODE_KI (((UINT_16) 'K' << 8) | (UINT_16) 'I') /* Kiribati */ ++#define COUNTRY_CODE_KM (((UINT_16) 'K' << 8) | (UINT_16) 'M') /* Comoros */ ++#define COUNTRY_CODE_KN (((UINT_16) 'K' << 8) | (UINT_16) 'N') /* Saint Kitts and Nevis */ ++#define COUNTRY_CODE_KP (((UINT_16) 'K' << 8) | (UINT_16) 'P') /* North Korea */ ++#define COUNTRY_CODE_KR (((UINT_16) 'K' << 8) | (UINT_16) 'R') /* South Korea */ ++#define COUNTRY_CODE_KW (((UINT_16) 'K' << 8) | (UINT_16) 'W') /* Kuwait */ ++#define COUNTRY_CODE_KY (((UINT_16) 'K' << 8) | (UINT_16) 'Y') /* Cayman Islands */ ++#define COUNTRY_CODE_KZ (((UINT_16) 'K' << 8) | (UINT_16) 'Z') /* Kazakhstan */ ++#define COUNTRY_CODE_LA (((UINT_16) 'L' << 8) | (UINT_16) 'A') /* Laos */ ++#define COUNTRY_CODE_LB (((UINT_16) 'L' << 8) | (UINT_16) 'B') /* Lebanon */ ++#define COUNTRY_CODE_LC (((UINT_16) 'L' << 8) | (UINT_16) 'C') /* Saint Lucia */ ++#define COUNTRY_CODE_LI (((UINT_16) 'L' << 8) | (UINT_16) 'I') /* Liechtenstein */ ++#define COUNTRY_CODE_LK (((UINT_16) 'L' << 8) | (UINT_16) 'K') /* Sri Lanka */ ++#define COUNTRY_CODE_LR (((UINT_16) 'L' << 8) | (UINT_16) 'R') /* Liberia */ ++#define COUNTRY_CODE_LS (((UINT_16) 'L' << 8) | (UINT_16) 'S') /* Lesotho */ ++#define COUNTRY_CODE_LT (((UINT_16) 'L' << 8) | (UINT_16) 'T') /* Lithuania */ ++#define COUNTRY_CODE_LU (((UINT_16) 'L' << 8) | (UINT_16) 'U') /* Luxemburg */ ++#define COUNTRY_CODE_LV (((UINT_16) 'L' << 8) | (UINT_16) 'V') /* Latvia */ ++#define COUNTRY_CODE_LY (((UINT_16) 'L' << 8) | (UINT_16) 'Y') /* Libya */ ++#define COUNTRY_CODE_MA (((UINT_16) 'M' << 8) | (UINT_16) 'A') /* Morocco */ ++#define COUNTRY_CODE_MC (((UINT_16) 'M' << 8) | (UINT_16) 'C') /* Monaco */ ++#define COUNTRY_CODE_MD (((UINT_16) 'M' << 8) | (UINT_16) 'D') /* Moldova */ ++#define COUNTRY_CODE_ME (((UINT_16) 'M' << 8) | (UINT_16) 'E') /* Montenegro */ ++#define COUNTRY_CODE_MF (((UINT_16) 'M' << 8) | (UINT_16) 'F') /* Saint Martin / Sint Marteen ++ (Added on window's list) */ ++#define COUNTRY_CODE_MG (((UINT_16) 'M' << 8) | (UINT_16) 'G') /* Madagascar */ ++#define COUNTRY_CODE_MH (((UINT_16) 'M' << 8) | (UINT_16) 'H') /* Marshall Islands */ ++#define COUNTRY_CODE_MK (((UINT_16) 'M' << 8) | (UINT_16) 'K') /* Macedonia */ ++#define COUNTRY_CODE_ML (((UINT_16) 'M' << 8) | (UINT_16) 'L') /* Mali */ ++#define COUNTRY_CODE_MM (((UINT_16) 'M' << 8) | (UINT_16) 'M') /* Myanmar */ ++#define COUNTRY_CODE_MN (((UINT_16) 'M' << 8) | (UINT_16) 'N') /* Mongolia */ ++#define COUNTRY_CODE_MO (((UINT_16) 'M' << 8) | (UINT_16) 'O') /* Macao */ ++#define COUNTRY_CODE_MP (((UINT_16) 'M' << 8) | (UINT_16) 'P') /* Northern Mariana Islands (Rota Island. ++ Saipan and Tinian Island) */ ++#define COUNTRY_CODE_MQ (((UINT_16) 'M' << 8) | (UINT_16) 'Q') /* Martinique (France) */ ++#define COUNTRY_CODE_MR (((UINT_16) 'M' << 8) | (UINT_16) 'R') /* Mauritania */ ++#define COUNTRY_CODE_MS (((UINT_16) 'M' << 8) | (UINT_16) 'S') /* Montserrat (UK) */ ++#define COUNTRY_CODE_MT (((UINT_16) 'M' << 8) | (UINT_16) 'T') /* Malta */ ++#define COUNTRY_CODE_MU (((UINT_16) 'M' << 8) | (UINT_16) 'U') /* Mauritius */ ++#define COUNTRY_CODE_MV (((UINT_16) 'M' << 8) | (UINT_16) 'V') /* Maldives */ ++#define COUNTRY_CODE_MW (((UINT_16) 'M' << 8) | (UINT_16) 'W') /* Malawi */ ++#define COUNTRY_CODE_MX (((UINT_16) 'M' << 8) | (UINT_16) 'X') /* Mexico */ ++#define COUNTRY_CODE_MY (((UINT_16) 'M' << 8) | (UINT_16) 'Y') /* Malaysia */ ++#define COUNTRY_CODE_MZ (((UINT_16) 'M' << 8) | (UINT_16) 'Z') /* Mozambique */ ++#define COUNTRY_CODE_NA (((UINT_16) 'N' << 8) | (UINT_16) 'A') /* Namibia */ ++#define COUNTRY_CODE_NC (((UINT_16) 'N' << 8) | (UINT_16) 'C') /* New Caledonia */ ++#define COUNTRY_CODE_NE (((UINT_16) 'N' << 8) | (UINT_16) 'E') /* Niger */ ++#define COUNTRY_CODE_NF (((UINT_16) 'N' << 8) | (UINT_16) 'F') /* Norfolk Island */ ++#define COUNTRY_CODE_NG (((UINT_16) 'N' << 8) | (UINT_16) 'G') /* Nigeria */ ++#define COUNTRY_CODE_NI (((UINT_16) 'N' << 8) | (UINT_16) 'I') /* Nicaragua */ ++#define COUNTRY_CODE_NL (((UINT_16) 'N' << 8) | (UINT_16) 'L') /* Netherlands */ ++#define COUNTRY_CODE_NO (((UINT_16) 'N' << 8) | (UINT_16) 'O') /* Norway */ ++#define COUNTRY_CODE_NP (((UINT_16) 'N' << 8) | (UINT_16) 'P') /* Nepal */ ++#define COUNTRY_CODE_NR (((UINT_16) 'N' << 8) | (UINT_16) 'R') /* Nauru */ ++#define COUNTRY_CODE_NU (((UINT_16) 'N' << 8) | (UINT_16) 'U') /* Niue */ ++#define COUNTRY_CODE_NZ (((UINT_16) 'N' << 8) | (UINT_16) 'Z') /* New Zealand */ ++#define COUNTRY_CODE_OM (((UINT_16) 'O' << 8) | (UINT_16) 'M') /* Oman */ ++#define COUNTRY_CODE_PA (((UINT_16) 'P' << 8) | (UINT_16) 'A') /* Panama */ ++#define COUNTRY_CODE_PE (((UINT_16) 'P' << 8) | (UINT_16) 'E') /* Peru */ ++#define COUNTRY_CODE_PF (((UINT_16) 'P' << 8) | (UINT_16) 'F') /* "French Polynesia */ ++#define COUNTRY_CODE_PG (((UINT_16) 'P' << 8) | (UINT_16) 'G') /* Papua New Guinea */ ++#define COUNTRY_CODE_PH (((UINT_16) 'P' << 8) | (UINT_16) 'H') /* Philippines */ ++#define COUNTRY_CODE_PK (((UINT_16) 'P' << 8) | (UINT_16) 'K') /* Pakistan */ ++#define COUNTRY_CODE_PL (((UINT_16) 'P' << 8) | (UINT_16) 'L') /* Poland */ ++#define COUNTRY_CODE_PM (((UINT_16) 'P' << 8) | (UINT_16) 'M') /* Saint Pierre and Miquelon */ ++#define COUNTRY_CODE_PN (((UINT_16) 'P' << 8) | (UINT_16) 'N') /* Pitcairn Islands */ ++#define COUNTRY_CODE_PR (((UINT_16) 'P' << 8) | (UINT_16) 'R') /* Puerto Rico (USA) */ ++#define COUNTRY_CODE_PS (((UINT_16) 'P' << 8) | (UINT_16) 'S') /* Palestinian Authority */ ++#define COUNTRY_CODE_PT (((UINT_16) 'P' << 8) | (UINT_16) 'T') /* Portugal */ ++#define COUNTRY_CODE_PW (((UINT_16) 'P' << 8) | (UINT_16) 'W') /* Palau */ ++#define COUNTRY_CODE_PY (((UINT_16) 'P' << 8) | (UINT_16) 'Y') /* Paraguay */ ++#define COUNTRY_CODE_QA (((UINT_16) 'Q' << 8) | (UINT_16) 'A') /* Qatar */ ++#define COUNTRY_CODE_RE (((UINT_16) 'R' << 8) | (UINT_16) 'E') /* Reunion (France) */ ++#define COUNTRY_CODE_RKS (((UINT_16) 'R' << 8) | (UINT_16) 'K') /* Kosvo (Added on window's list) */ ++#define COUNTRY_CODE_RO (((UINT_16) 'R' << 8) | (UINT_16) 'O') /* Romania */ ++#define COUNTRY_CODE_RS (((UINT_16) 'R' << 8) | (UINT_16) 'S') /* Serbia */ ++#define COUNTRY_CODE_RU (((UINT_16) 'R' << 8) | (UINT_16) 'U') /* Russia */ ++#define COUNTRY_CODE_RW (((UINT_16) 'R' << 8) | (UINT_16) 'W') /* Rwanda */ ++#define COUNTRY_CODE_SA (((UINT_16) 'S' << 8) | (UINT_16) 'A') /* Saudi Arabia */ ++#define COUNTRY_CODE_SB (((UINT_16) 'S' << 8) | (UINT_16) 'B') /* Solomon Islands */ ++#define COUNTRY_CODE_SC (((UINT_16) 'S' << 8) | (UINT_16) 'C') /* Seychelles */ ++#define COUNTRY_CODE_SD (((UINT_16) 'S' << 8) | (UINT_16) 'D') /* Sudan */ ++#define COUNTRY_CODE_SE (((UINT_16) 'S' << 8) | (UINT_16) 'E') /* Sweden */ ++#define COUNTRY_CODE_SG (((UINT_16) 'S' << 8) | (UINT_16) 'G') /* Singapole */ ++#define COUNTRY_CODE_SI (((UINT_16) 'S' << 8) | (UINT_16) 'I') /* Slovenia */ ++#define COUNTRY_CODE_SK (((UINT_16) 'S' << 8) | (UINT_16) 'K') /* Slovakia */ ++#define COUNTRY_CODE_SL (((UINT_16) 'S' << 8) | (UINT_16) 'L') /* Sierra Leone */ ++#define COUNTRY_CODE_SM (((UINT_16) 'S' << 8) | (UINT_16) 'M') /* San Marino */ ++#define COUNTRY_CODE_SN (((UINT_16) 'S' << 8) | (UINT_16) 'N') /* Senegal */ ++#define COUNTRY_CODE_SO (((UINT_16) 'S' << 8) | (UINT_16) 'O') /* Somalia */ ++#define COUNTRY_CODE_SR (((UINT_16) 'S' << 8) | (UINT_16) 'R') /* Suriname */ ++#define COUNTRY_CODE_SS (((UINT_16) 'S' << 8) | (UINT_16) 'S') /* South_Sudan */ ++#define COUNTRY_CODE_ST (((UINT_16) 'S' << 8) | (UINT_16) 'T') /* Sao Tome and Principe */ ++#define COUNTRY_CODE_SV (((UINT_16) 'S' << 8) | (UINT_16) 'V') /* El Salvador */ ++#define COUNTRY_CODE_SY (((UINT_16) 'S' << 8) | (UINT_16) 'Y') /* Syria */ ++#define COUNTRY_CODE_SZ (((UINT_16) 'S' << 8) | (UINT_16) 'Z') /* Swaziland */ ++#define COUNTRY_CODE_TC (((UINT_16) 'T' << 8) | (UINT_16) 'C') /* Turks and Caicos Islands (UK) */ ++#define COUNTRY_CODE_TD (((UINT_16) 'T' << 8) | (UINT_16) 'D') /* Chad */ ++#define COUNTRY_CODE_TF (((UINT_16) 'T' << 8) | (UINT_16) 'F') /* French Southern and Antarctic Lands */ ++#define COUNTRY_CODE_TG (((UINT_16) 'T' << 8) | (UINT_16) 'G') /* Togo */ ++#define COUNTRY_CODE_TH (((UINT_16) 'T' << 8) | (UINT_16) 'H') /* Thailand */ ++#define COUNTRY_CODE_TJ (((UINT_16) 'T' << 8) | (UINT_16) 'J') /* Tajikistan */ ++#define COUNTRY_CODE_TL (((UINT_16) 'T' << 8) | (UINT_16) 'L') /* East Timor */ ++#define COUNTRY_CODE_TM (((UINT_16) 'T' << 8) | (UINT_16) 'M') /* Turkmenistan */ ++#define COUNTRY_CODE_TN (((UINT_16) 'T' << 8) | (UINT_16) 'N') /* Tunisia */ ++#define COUNTRY_CODE_TO (((UINT_16) 'T' << 8) | (UINT_16) 'O') /* Tonga */ ++#define COUNTRY_CODE_TR (((UINT_16) 'T' << 8) | (UINT_16) 'R') /* Turkey */ ++#define COUNTRY_CODE_TT (((UINT_16) 'T' << 8) | (UINT_16) 'T') /* Trinidad and Tobago */ ++#define COUNTRY_CODE_TV (((UINT_16) 'T' << 8) | (UINT_16) 'V') /* Tuvalu */ ++#define COUNTRY_CODE_TW (((UINT_16) 'T' << 8) | (UINT_16) 'W') /* Taiwan */ ++#define COUNTRY_CODE_TZ (((UINT_16) 'T' << 8) | (UINT_16) 'Z') /* Tanzania */ ++#define COUNTRY_CODE_UA (((UINT_16) 'U' << 8) | (UINT_16) 'A') /* Ukraine */ ++#define COUNTRY_CODE_UG (((UINT_16) 'U' << 8) | (UINT_16) 'G') /* Ugnada */ ++#define COUNTRY_CODE_US (((UINT_16) 'U' << 8) | (UINT_16) 'S') /* US */ ++#define COUNTRY_CODE_UY (((UINT_16) 'U' << 8) | (UINT_16) 'Y') /* Uruguay */ ++#define COUNTRY_CODE_UZ (((UINT_16) 'U' << 8) | (UINT_16) 'Z') /* Uzbekistan */ ++#define COUNTRY_CODE_VA (((UINT_16) 'V' << 8) | (UINT_16) 'A') /* Vatican (Holy See) */ ++#define COUNTRY_CODE_VC (((UINT_16) 'V' << 8) | (UINT_16) 'C') /* Saint Vincent and the Grenadines */ ++#define COUNTRY_CODE_VE (((UINT_16) 'V' << 8) | (UINT_16) 'E') /* Venezuela */ ++#define COUNTRY_CODE_VG (((UINT_16) 'V' << 8) | (UINT_16) 'G') /* British Virgin Islands */ ++#define COUNTRY_CODE_VI (((UINT_16) 'V' << 8) | (UINT_16) 'I') /* US Virgin Islands */ ++#define COUNTRY_CODE_VN (((UINT_16) 'V' << 8) | (UINT_16) 'N') /* Vietnam */ ++#define COUNTRY_CODE_VU (((UINT_16) 'V' << 8) | (UINT_16) 'U') /* Vanuatu */ ++#define COUNTRY_CODE_WS (((UINT_16) 'W' << 8) | (UINT_16) 'S') /* Samoa */ ++#define COUNTRY_CODE_YE (((UINT_16) 'Y' << 8) | (UINT_16) 'E') /* Yemen */ ++#define COUNTRY_CODE_YT (((UINT_16) 'Y' << 8) | (UINT_16) 'T') /* Mayotte (France) */ ++#define COUNTRY_CODE_ZA (((UINT_16) 'Z' << 8) | (UINT_16) 'A') /* South Africa */ ++#define COUNTRY_CODE_ZM (((UINT_16) 'Z' << 8) | (UINT_16) 'M') /* Zambia */ ++#define COUNTRY_CODE_ZW (((UINT_16) 'Z' << 8) | (UINT_16) 'W') /* Zimbabwe */ ++ ++#define COUNTRY_CODE_DF (((UINT_16) 'D' << 8) | (UINT_16) 'F') /* Default country domain */ ++#define COUNTRY_CODE_UDF (((UINT_16) 'U' << 8) | (UINT_16) 'D') /* User defined supported channel list ++ and passive scan channel list */ ++ ++#define COUNTRY_CODE_FF (((UINT_16) 'F' << 8) | (UINT_16) 'F') /* enable open for all channel for Certification */ ++#define COUNTRY_CODE_FE (((UINT_16) 'F' << 8) | (UINT_16) 'E') /* disable open for all channel for Certification */ ++ ++/* dot11RegDomainsSupportValue */ ++#define MIB_REG_DOMAIN_FCC 0x10 /* FCC (US) */ ++#define MIB_REG_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ ++#define MIB_REG_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ ++#define MIB_REG_DOMAIN_SPAIN 0x31 /* Spain */ ++#define MIB_REG_DOMAIN_FRANCE 0x32 /* France */ ++#define MIB_REG_DOMAIN_JAPAN 0x40 /* MPHPT (Japan) */ ++#define MIB_REG_DOMAIN_OTHER 0x00 /* other */ ++ ++/*2.4G*/ ++#define BAND_2G4_LOWER_BOUND 1 ++#define BAND_2G4_UPPER_BOUND 14 ++/*5G SubBand FCC spec*/ ++#define UNII1_LOWER_BOUND 36 ++#define UNII1_UPPER_BOUND 48 ++#define UNII2A_LOWER_BOUND 52 ++#define UNII2A_UPPER_BOUND 64 ++#define UNII2C_LOWER_BOUND 100 ++#define UNII2C_UPPER_BOUND 144 ++#define UNII3_LOWER_BOUND 149 ++#define UNII3_UPPER_BOUND 173 ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++#define POWER_LIMIT_TABLE_NULL 0xFFFF ++#define MAX_TX_POWER 63 ++#define MIN_TX_POWER -64 ++#define MAX_CMD_SUPPORT_CHANNEL_NUM 64 ++ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++typedef enum _ENUM_POWER_LIMIT_T { ++ PWR_LIMIT_CCK, ++ PWR_LIMIT_20M, ++ PWR_LIMIT_40M, ++ PWR_LIMIT_80M, ++ PWR_LIMIT_160M, ++ PWR_LIMIT_NUM ++} ENUM_POWER_LIMIT_T, *P_ENUM_POWER_LIMIT_T; ++ ++#endif ++ ++typedef enum _ENUM_POWER_LIMIT_SUBBAND_T { ++ POWER_LIMIT_2G4, ++ POWER_LIMIT_UNII1, ++ POWER_LIMIT_UNII2A, ++ POWER_LIMIT_UNII2C, ++ POWER_LIMIT_UNII3, ++ POWER_LIMIT_SUBAND_NUM ++} ENUM_POWER_LIMIT_SUBBAND_T, *P_ENUM_POWER_LIMIT_SUBBAND_T; ++ ++/* Define channel offset in unit of 5MHz bandwidth */ ++typedef enum _ENUM_CHNL_SPAN_T { ++ CHNL_SPAN_5 = 1, ++ CHNL_SPAN_10 = 2, ++ CHNL_SPAN_20 = 4, ++ CHNL_SPAN_40 = 8 ++} ENUM_CHNL_SPAN_T, *P_ENUM_CHNL_SPAN_T; ++ ++/* Define BSS operating bandwidth */ ++typedef enum _ENUM_CHNL_BW_T { ++ CHNL_BW_20, ++ CHNL_BW_20_40, ++ CHNL_BW_10, ++ CHNL_BW_5 ++} ENUM_CHNL_BW_T, *P_ENUM_CHNL_BW_T; ++ ++/* In all bands, the first channel will be SCA and the second channel is SCB, ++ * then iteratively. ++ * Note the final channel will not be SCA. ++ */ ++typedef struct _DOMAIN_SUBBAND_INFO { ++ /* Note1: regulation class depends on operation bandwidth and RF band. ++ * For example: 2.4GHz, 1~13, 20MHz ==> regulation class = 81 ++ * 2.4GHz, 1~13, SCA ==> regulation class = 83 ++ * 2.4GHz, 1~13, SCB ==> regulation class = 84 ++ * Note2: TX power limit is not specified here because path loss is unknown ++ */ ++ UINT_8 ucRegClass; /* Regulation class for 20MHz */ ++ UINT_8 ucBand; /* Type: ENUM_BAND_T */ ++ UINT_8 ucChannelSpan; /* Type: ENUM_CHNL_SPAN_T */ ++ UINT_8 ucFirstChannelNum; ++ UINT_8 ucNumChannels; ++ UINT_8 fgDfs; /* Type: BOOLEAN */ ++} DOMAIN_SUBBAND_INFO, *P_DOMAIN_SUBBAND_INFO; ++ ++/* Use it as all available channel list for STA */ ++typedef struct _DOMAIN_INFO_ENTRY { ++ PUINT_16 pu2CountryGroup; ++ UINT_32 u4CountryNum; ++ ++ /* If different attributes, put them into different rSubBands. ++ * For example, DFS shall be used or not. ++ */ ++ DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM]; ++} DOMAIN_INFO_ENTRY, *P_DOMAIN_INFO_ENTRY; ++ ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++typedef struct _CHANNEL_POWER_LIMIT { ++ UINT_8 ucCentralCh; ++ INT_8 cPwrLimitCCK; ++ INT_8 cPwrLimit20; ++ INT_8 cPwrLimit40; ++ INT_8 cPwrLimit80; ++ INT_8 cPwrLimit160; ++ UINT_8 ucFlag; ++ UINT_8 aucReserved[1]; ++} CHANNEL_POWER_LIMIT, *P_CHANNEL_POWER_LIMIT; ++ ++typedef struct _COUNTRY_CHANNEL_POWER_LIMIT { ++ UINT_8 aucCountryCode[2]; ++ UINT_8 ucCountryFlag; ++ UINT_8 ucChannelNum; ++ UINT_8 aucReserved[4]; ++ CHANNEL_POWER_LIMIT rChannelPowerLimit[80]; ++} COUNTRY_CHANNEL_POWER_LIMIT, *P_COUNTRY_CHANNEL_POWER_LIMIT; ++ ++#define CHANNEL_PWR_LIMIT(_channel, _pwrLimit_cck, _pwrLimit_bw20, \ ++ _pwrLimit_bw40, _pwrLimit_bw80, _pwrLimit_bw160, _ucFlag) \ ++ { \ ++ .ucCentralCh = (_channel), \ ++ .cPwrLimitCCK = (_pwrLimit_cck), \ ++ .cPwrLimit20 = (_pwrLimit_bw20), \ ++ .cPwrLimit40 = (_pwrLimit_bw40), \ ++ .cPwrLimit80 = (_pwrLimit_bw80), \ ++ .cPwrLimit160 = (_pwrLimit_bw160), \ ++ .ucFlag = (_ucFlag), \ ++ .aucReserved = {0} \ ++} ++ ++typedef struct _COUNTRY_POWER_LIMIT_TABLE_DEFAULT { ++ UINT_8 aucCountryCode[2]; ++ /* 0: ch 1 ~14 , 1: ch 36 ~48, 2: ch 52 ~64, 3: ch 100 ~144, 4: ch 149 ~165 */ ++ INT_8 aucPwrLimitSubBand[POWER_LIMIT_SUBAND_NUM]; ++ /* bit0: cPwrLimit2G4, bit1: cPwrLimitUnii1; bit2: cPwrLimitUnii2A; ++ * bit3: cPwrLimitUnii2C; bit4: cPwrLimitUnii3; mW: 0, mW\MHz : 1 */ ++ UINT_8 ucPwrUnit; ++} COUNTRY_POWER_LIMIT_TABLE_DEFAULT, *P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT; ++ ++typedef struct _COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION { ++ UINT_8 aucCountryCode[2]; ++ UINT_8 ucCentralCh; ++ INT_8 aucPwrLimit[PWR_LIMIT_NUM]; ++} COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION, *P_COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION; ++ ++typedef struct _SUBBAND_CHANNEL_T { ++ UINT_8 ucStartCh; ++ UINT_8 ucEndCh; ++ UINT_8 ucInterval; ++ UINT_8 ucReserved; ++} SUBBAND_CHANNEL_T, *P_SUBBAND_CHANNEL_T; ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define CAL_CH_OFFSET_80M(_PRIMARY_CH, _CENTRAL_CH) \ ++ (((_PRIMARY_CH - _CENTRAL_CH) + 6) >> 2) ++ ++#define CAL_CH_OFFSET_160M(_PRIMARY_CH, _CENTRAL_CH) \ ++ (((_PRIMARY_CH - _CENTRAL_CH) + 14) >> 2) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter); ++ ++VOID ++rlmDomainGetChnlList(P_ADAPTER_T prAdapter, ++ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, ++ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList); ++ ++VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); ++ ++VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); ++ ++VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); ++ ++BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel); ++ ++UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf); ++ ++BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh); ++ ++UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++BOOLEAN rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, ++ UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend, ++ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2); ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++BOOLEAN ++rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, ++ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, ++ UINT_8 ucPwrLimitNum); ++ ++VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter); ++ ++UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode); ++ ++VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_DOMAIN_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h +new file mode 100644 +index 000000000000..7f29dba4ce06 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h +@@ -0,0 +1,150 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_obss.h#1 ++*/ ++ ++/*! \file "rlm_obss.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_obss.h ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ++ * ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Refine function when rcv a 20/40M public action frame ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 05 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process 20/40 coexistence public action frame in AP mode ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add virtual test for OBSS scan ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++#ifndef _RLM_OBSS_H ++#define _RLM_OBSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define CHNL_LIST_SZ_2G 14 ++#define CHNL_LIST_SZ_5G 14 ++ ++#define CHNL_LEVEL0 0 ++#define CHNL_LEVEL1 1 ++#define CHNL_LEVEL2 2 ++ ++#define AFFECTED_CHNL_OFFSET 5 ++ ++#define OBSS_SCAN_MIN_INTERVAL 10 /* In unit of sec */ ++ ++#define PUBLIC_ACTION_MAX_LEN 200 /* In unit of byte */ ++ ++/* P2P GO only */ ++/* Define default OBSS Scan parameters (from MIB in spec.) */ ++#define dot11OBSSScanPassiveDwell 20 ++#define dot11OBSSScanActiveDwell 10 ++#define dot11OBSSScanPassiveTotalPerChannel 200 ++#define dot11OBSSScanActiveTotalPerChannel 20 ++#define dot11BSSWidthTriggerScanInterval 300 /* Unit: sec */ ++#define dot11BSSWidthChannelTransitionDelayFactor 5 ++#define dot11OBSSScanActivityThreshold 25 ++ ++#define OBSS_20_40M_TIMEOUT (dot11BSSWidthTriggerScanInterval + 10) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* Control MAC PCO function */ ++typedef enum _ENUM_SYS_PCO_PHASE_T { ++ SYS_PCO_PHASE_DISABLED = 0, ++ SYS_PCO_PHASE_20M, ++ SYS_PCO_PHASE_40M ++} ENUM_SYS_PCO_PHASE_T, *P_ENUM_SYS_PCO_PHASE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID rlmObssInit(P_ADAPTER_T prAdapter); ++ ++VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_OBSS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h +new file mode 100644 +index 000000000000..8665e48569ba +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h +@@ -0,0 +1,122 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_protection.h#1 ++*/ ++ ++/*! \file "rlm_protection.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_protection.h ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++#ifndef _RLM_PROTECTION_H ++#define _RLM_PROTECTION_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_SYS_PROTECT_MODE_T { ++ SYS_PROTECT_MODE_NONE = 0, /* Mode 0 */ ++ SYS_PROTECT_MODE_ERP, /* Mode 1 */ ++ SYS_PROTECT_MODE_NON_HT, /* Mode 2 */ ++ SYS_PROTECT_MODE_20M, /* Mode 3 */ ++ ++ SYS_PROTECT_MODE_NUM ++} ENUM_SYS_PROTECT_MODE_T, *P_ENUM_SYS_PROTECT_MODE_T; ++ ++/* This definition follows HT Protection field of HT Operation IE */ ++typedef enum _ENUM_HT_PROTECT_MODE_T { ++ HT_PROTECT_MODE_NONE = 0, ++ HT_PROTECT_MODE_NON_MEMBER, ++ HT_PROTECT_MODE_20M, ++ HT_PROTECT_MODE_NON_HT, ++ ++ HT_PROTECT_MODE_NUM ++} ENUM_HT_PROTECT_MODE_T, *P_ENUM_HT_PROTECT_MODE_T; ++ ++typedef enum _ENUM_GF_MODE_T { ++ GF_MODE_NORMAL = 0, ++ GF_MODE_PROTECT, ++ GF_MODE_DISALLOWED, ++ ++ GF_MODE_NUM ++} ENUM_GF_MODE_T, *P_ENUM_GF_MODE_T; ++ ++typedef enum _ENUM_RIFS_MODE_T { ++ RIFS_MODE_NORMAL = 0, ++ RIFS_MODE_DISALLOWED, ++ ++ RIFS_MODE_NUM ++} ENUM_RIFS_MODE_T, *P_ENUM_RIFS_MODE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_PROTECTION_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h +new file mode 100644 +index 000000000000..d01c6e01e83f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h +@@ -0,0 +1,1213 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_txpwr_init.h#1 ++*/ ++ ++/*! \file "rlm_txpwr_init.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_txpwr_init.h ++*/ ++ ++ ++#ifndef _RLM_TXPWR_INIT_H ++#define _RLM_TXPWR_INIT_H ++ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/*Support Tx Power Range : 63~ -64 (unit : 0.5dBm)*/ ++ ++#define PWR_LIMIT_2G4_IN_MW_MHZ BIT(0) ++#define PWR_LIMIT_UNII1_IN_MW_MHZ BIT(1) ++#define PWR_LIMIT_UNII2A_IN_MW_MHZ BIT(2) ++#define PWR_LIMIT_UNII2C_IN_MW_MHZ BIT(3) ++#define PWR_LIMIT_UNII3_IN_MW_MHZ BIT(4) ++ ++#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT ++#define CE_FCC_TXPWR_LIMIT_CCK 30 /* 15 dBm */ ++#define CE_FCC_TXPWR_LIMIT_OFDM 20 /* 10 dBm */ ++#define CE_FCC_TXPWR_LIMIT_HT40 18 /* 9 dBm */ ++#endif ++ ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++COUNTRY_POWER_LIMIT_TABLE_DEFAULT g_rRlmPowerLimitDefault[] = { ++ ++ {{'A', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'Z'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'T'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'I'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'F'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'D'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'K', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'D'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'I'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'D', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'Q'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'E', 'R'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'F', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'A'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'N'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'W'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'R', 'K'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'K', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'L', 'Y'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'M', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'M', 'L'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'R'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'C'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'T'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'C'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'L'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'B'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'R'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'Z'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'V'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'V', 'U'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'Y', 'E'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'A', 'S'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'A', 'I'} ++ , {60, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'B', 'M'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'C', 'A'} ++ , {60, 46, 48, 48, 60} ++ , 0} ++ , ++ {{'K', 'Y'} ++ , {60, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'G', 'U'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'F', 'M'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'P', 'R'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'U', 'S'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'V', 'I'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'A', 'R'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'A', 'U'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'Z'} ++ , {40, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'B', 'W'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'K', 'H'} ++ , {40, 46, 46, 48, 60} ++ , 0} ++ , ++ {{'C', 'X'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'O'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'C', 'R'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'E', 'C'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'G', 'D'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'G', 'T'} ++ , {40, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'H', 'K'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'K', 'I'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'B'} ++ , {40, 46, 46, 46, 46} ++ , 0} ++ , ++ {{'L', 'R'} ++ , {60, 46, 60, 63, 63} ++ , 0} ++ , ++ {{'M', 'N'} ++ , {46, 32, 46, 46, 58} ++ , 0} ++ , ++ {{'A', 'N'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'N', 'Z'} ++ , {63, 46, 60, 48, 63} ++ , 0} ++ , ++ {{'N', 'I'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'P', 'W'} ++ , {60, 60, 60, 60, 60} ++ , 0} ++ , ++ {{'P', 'Y'} ++ , {60, 46, 46, 48, 60} ++ , 0} ++ , ++ {{'P', 'E'} ++ , {54, 46, 48, 42, 48} ++ , 0} ++ , ++ {{'P', 'H'} ++ , {40, 46, 46, 48, 48} ++ , 0} ++ , ++ {{'W', 'S'} ++ , {40, 40, 40, 40, 60} ++ , 0} ++ , ++ {{'S', 'G'} ++ , {46, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'L', 'K'} ++ , {46, 46, 46, 46, 46} ++ , 0} ++ , ++ {{'T', 'H'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'T', 'T'} ++ , {60, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'U', 'Y'} ++ , {63, 46, 46, 46, 46} ++ , 0} ++ , ++ {{'V', 'N'} ++ , {46, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'A', 'W'} ++ , {60, 46, 60, 60, 63} ++ , 0} ++ , ++ {{'L', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'A'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'A', 'E'} ++ , {40, 46, 46, 60, 46} ++ , 0} ++ , ++ {{'U', 'G'} ++ , {40, 46, 46, 48, 60} ++ , 0} ++ , ++ {{'M', 'M'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'L'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'D', 'Z'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'D'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'Y'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'V', 'G'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'G'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'V'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'H', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'Y'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'Z'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'D', 'K'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'E', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'E', 'T'} ++ , {40, 40, 40, 40, 63} ++ , 0} ++ , ++ {{'F', 'I'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'F', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'P', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'T', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'D', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'H'} ++ , {40, 34, 48, 60, 63} ++ , 0} ++ , ++ {{'G', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'P'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'H', 'U'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'Q'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'K', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'V'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'I'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'U'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'K'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'Q'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'R'} ++ , {40, 46, 46, 46, 63} ++ , 0} ++ , ++ {{'M', 'U'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'Y', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'D'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'C'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'N', 'L'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'N', 'O'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'O', 'M'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'P', 'L'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'P', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'R', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'R', 'O'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'M'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'N'} ++ , {40, 40, 40, 60, 63} ++ , 0} ++ , ++ {{'R', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'K'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'I'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'Z', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'E', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'H'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'T', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'T', 'C'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'B'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'V', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'M'} ++ , {40, 40, 40, 63, 63} ++ , 0} ++ , ++ {{'I', 'L'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'K', 'W'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'M', 'A'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'N', 'E'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'T', 'N'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'E', 'H'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'N', 'P'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'A', 'F'} ++ , {40, 46, 63, 63, 63} ++ , 0} ++ , ++ {{'A', 'G'} ++ , {40, 46, 48, 63, 54} ++ , 0} ++ , ++ {{'B', 'S'} ++ , {63, 46, 60, 63, 63} ++ , 0} ++ , ++ {{'B', 'H'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'B', 'B'} ++ , {40, 46, 48, 63, 54} ++ , 0} ++ , ++ {{'B', 'N'} ++ , {46, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'C', 'L'} ++ , {40, 44, 44, 63, 44} ++ , 0} ++ , ++ {{'C', 'N'} ++ , {40, 46, 46, 63, 54} ++ , 0} ++ , ++ {{'E', 'G'} ++ , {40, 46, 46, 63, 46} ++ , 0} ++ , ++ {{'S', 'V'} ++ , {60, 34, 48, 63, 60} ++ , 0} ++ , ++ {{'I', 'N'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'M', 'Y'} ++ , {54, 60, 60, 63, 60} ++ , 0} ++ , ++ {{'M', 'V'} ++ , {40, 46, 46, 63, 40} ++ , 0} ++ , ++ {{'P', 'A'} ++ , {60, 34, 48, 63, 60} ++ , 0} ++ , ++ {{'V', 'E'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'Z', 'M'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'J', 'O'} ++ , {40, 46, 63, 63, 46} ++ , 0} ++ , ++ {{'P', 'G'} ++ , {40, 46, 63, 63, 60} ++ , 0} ++ , ++ {{'B', 'F'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'G', 'Y'} ++ , {60, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'H', 'T'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'H', 'N'} ++ , {60, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'J', 'M'} ++ , {54, 63, 63, 63, 57} ++ , 0} ++ , ++ {{'M', 'O'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'M', 'W'} ++ , {60, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'P', 'K'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'Q', 'A'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'R', 'W'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'K', 'N'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'T', 'Z'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'I', 'D'} ++ , {46, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'N', 'G'} ++ , {40, 63, 46, 63, 60} ++ , 0} ++ , ++ {{'B', 'D'} ++ , {40, 46, 46, 60, 28} ++ , 0} ++ , ++ {{'B', 'R'} ++ , {52, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'D', 'M'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'D', 'O'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'F', 'K'} ++ , {40, 46, 46, 60, 28} ++ , 0} ++ , ++ {{'K', 'Z'} ++ , {40, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'M', 'X'} ++ , {60, 34, 48, 60, 63} ++ , 0} ++ , ++ {{'M', 'Z'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'N', 'A'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'R', 'U'} ++ , {40, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'L', 'C'} ++ , {40, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'V', 'C'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'U', 'A'} ++ , {40, 46, 46, 46, 48} ++ , 0} ++ , ++ {{'U', 'Z'} ++ , {40, 48, 48, 48, 60} ++ , 0} ++ , ++ {{'Z', 'W'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'M', 'P'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'T', 'W'} ++ , {60, 63, 34, 48, 60} ++ , 0} ++ , ++ {{'C', 'K'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'U'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'L'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'F', 'O'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'I'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'G'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'I', 'R'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'I', 'M'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'J', 'E'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'K', 'P'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'M', 'H'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'U'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'F'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'P', 'S'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'P', 'N'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'P', 'M'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'S'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'D'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'Y'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'J', 'P'} ++ , {46, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'K', 'R'} ++ , {46, 34, 46, 46, 46} ++ , PWR_LIMIT_UNII1_IN_MW_MHZ} ++ , ++ ++/*Default*/ ++ {{0, 0} ++ , {63, 63, 63, 63, 63} ++ , 0} ++}; ++ ++COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION g_rRlmPowerLimitConfiguration[] = { ++ ++ {{'A', 'I'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'A', 'Z'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'B', 'W'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'G', 'D'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'L', 'B'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'L', 'R'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'W', 'S'} ++ , 165, {40, 40, 40, 40, 40} ++ } ++ , ++ {{'V', 'N'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 1, {38, 30, 60, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 3, {60, 60, 26, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 9, {60, 60, 26, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 11, {38, 30, 60, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 36, {34, 34, 34, 34, 34} ++ } ++ , ++ {{'U', 'S'} ++ , 38, {34, 34, 34, 34, 34} ++ } ++ , ++ {{'U', 'S'} ++ , 42, {34, 34, 34, 31, 34} ++ } ++ , ++ {{'U', 'S'} ++ , 58, {48, 48, 48, 31, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 62, {48, 48, 34, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 64, {37, 37, 48, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 100, {37, 37, 48, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 102, {48, 48, 34, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 106, {48, 48, 48, 31, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 155, {60, 60, 60, 31, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 159, {60, 60, 34, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 165, {37, 37, 60, 60, 60} ++ } ++ , ++ ++/*Default*/ ++ {{0, 0} ++ , 165, {63, 63, 63, 63, 63} ++ } ++}; ++ ++#if 0 ++COUNTRY_CHANNEL_POWER_LIMIT g_rRlmCountryPowerLimitTable[] = { ++ { ++ {'A', 'O'} ++ , 0, 0, {0, 0, 0, 0} ++ , ++ { ++ CHANNEL_PWR_LIMIT(1, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(2, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(3, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(4, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(5, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(6, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(7, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(8, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(9, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(10, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(11, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(12, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(13, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(14, 40, 40, 40, 40, 40, 0), ++ ++ CHANNEL_PWR_LIMIT(36, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(38, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(40, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(42, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(44, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(46, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(48, 63, 63, 63, 63, 63, 0), ++ ++ CHANNEL_PWR_LIMIT(52, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(54, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(56, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(58, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(60, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(62, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(64, 63, 63, 63, 63, 63, 0), ++ ++ CHANNEL_PWR_LIMIT(100, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(102, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(104, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(106, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(108, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(110, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(112, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(114, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(116, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(118, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(120, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(122, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(124, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(126, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(128, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(130, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(132, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(134, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(136, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(138, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(140, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(142, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(144, 63, 63, 63, 63, 63, 0), ++ ++ CHANNEL_PWR_LIMIT(149, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(151, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(153, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(155, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(157, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(159, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(161, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(163, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(165, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(167, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(169, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(171, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(173, 63, 63, 63, 63, 63, 0) ++ } ++ } ++ , ++ { ++ /*Used to check the end of country entry */ ++ {0, 0} ++ , 0, 0, {0, 0, 0, 0} ++ , ++ { ++ /*Used to check the end of channel power limit */ ++ CHANNEL_PWR_LIMIT(ENDCH, 0, 0, 0, 0, 0, 0) ++ } ++ } /*end of CountryTable */ ++}; ++#endif ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_TXPWR_INIT_H */ ++ ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h +new file mode 100644 +index 000000000000..0df4ec3e0828 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h +@@ -0,0 +1,171 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "roaming_fsm.h" ++ \brief This file defines the FSM for Roaming MODULE. ++ ++ This file defines the FSM for Roaming MODULE. ++*/ ++ ++/* ++** Log: roaming_fsm.h ++ * ++ * 08 31 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * remove obsolete code. ++ * ++ * 08 15 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * add swcr in driver reg, 0x9fxx0000, to disable roaming . ++ * ++ * 03 16 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * remove obsolete definition and unused variables. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++*/ ++ ++#ifndef _ROAMING_FSM_H ++#define _ROAMING_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Roaming Discovery interval, SCAN result need to be updated */ ++#define ROAMING_DISCOVERY_TIMEOUT_SEC 5 /* Seconds. */ ++ ++/* #define ROAMING_NO_SWING_RCPI_STEP 5 //rcpi */ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_ROAMING_FAIL_REASON_T { ++ ROAMING_FAIL_REASON_CONNLIMIT = 0, ++ ROAMING_FAIL_REASON_NOCANDIDATE, ++ ROAMING_FAIL_REASON_NUM ++} ENUM_ROAMING_FAIL_REASON_T; ++ ++/* events of roaming between driver and firmware */ ++typedef enum _ENUM_ROAMING_EVENT_T { ++ ROAMING_EVENT_START = 0, ++ ROAMING_EVENT_DISCOVERY, ++ ROAMING_EVENT_ROAM, ++ ROAMING_EVENT_FAIL, ++ ROAMING_EVENT_ABORT, ++ ROAMING_EVENT_NUM ++} ENUM_ROAMING_EVENT_T; ++ ++#define ROAMING_EVENT_REASON_TX_ERR BIT(0) ++#define ROAMING_EVENT_REASON_RCPI BIT(1) ++ ++typedef struct _ROAMING_PARAM_T { ++ UINT_16 u2Event; ++ UINT_16 u2Data; ++ UINT_16 u2Reason; ++} ROAMING_PARAM_T, *P_ROAMING_PARAM_T; ++ ++ /**/ typedef enum _ENUM_ROAMING_STATE_T { ++ ROAMING_STATE_IDLE = 0, ++ ROAMING_STATE_DECISION, ++ ROAMING_STATE_DISCOVERY, ++ ROAMING_STATE_ROAM, ++ ROAMING_STATE_NUM ++} ENUM_ROAMING_STATE_T; ++ ++typedef struct _ROAMING_INFO_T { ++ BOOLEAN fgIsEnableRoaming; ++ ++ ENUM_ROAMING_STATE_T eCurrentState; ++ ++ OS_SYSTIME rRoamingDiscoveryUpdateTime; ++ ++#define ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX 2 ++ UINT_32 RoamingEntryTimeoutSkipCount; ++ ++} ROAMING_INFO_T, *P_ROAMING_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if CFG_SUPPORT_ROAMING ++#define IS_ROAMING_ACTIVE(prAdapter) \ ++ (prAdapter->rWifiVar.rRoamingInfo.eCurrentState == ROAMING_STATE_ROAM) ++#else ++#define IS_ROAMING_ACTIVE(prAdapter) FALSE ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID roamingFsmInit(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); ++ ++VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState); ++ ++VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); ++ ++VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Reason); ++ ++VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _ROAMING_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h +new file mode 100644 +index 000000000000..20ab14251f65 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h +@@ -0,0 +1,271 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rsn.h#1 ++*/ ++ ++/*! \file rsn.h ++ \brief The wpa/rsn related define, macro and structure are described here. ++*/ ++ ++/* ++** Log: rsn.h ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 wh.su ++ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h ++ * and let the sw structure not align at byte ++ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, ++ * Notice needed update P2P.ko. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value ++ * fixed the.pmkid value mismatch issue ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * add a kal function for set cipher. ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 30 2010 wh.su ++ * NULL ++ * remove non-used code. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, and modify ++ * the security related callback function prototype. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function prototype for generate wap/rsn ie ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function input parameter ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some event function declaration ++ * ++ * Nov 26 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * move the internal data structure for pmkid to rsn.h ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the port control and class error function ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the pmkid candidate ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++#ifndef _RSN_H ++#define _RSN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* ----- Definitions for Cipher Suite Selectors ----- */ ++#define RSN_CIPHER_SUITE_USE_GROUP_KEY 0x00AC0F00 ++#define RSN_CIPHER_SUITE_WEP40 0x01AC0F00 ++#define RSN_CIPHER_SUITE_TKIP 0x02AC0F00 ++#define RSN_CIPHER_SUITE_CCMP 0x04AC0F00 ++#define RSN_CIPHER_SUITE_WEP104 0x05AC0F00 ++#if CFG_SUPPORT_802_11W ++#define RSN_CIPHER_SUITE_AES_128_CMAC 0x06AC0F00 ++#endif ++ ++#define WPA_CIPHER_SUITE_NONE 0x00F25000 ++#define WPA_CIPHER_SUITE_WEP40 0x01F25000 ++#define WPA_CIPHER_SUITE_TKIP 0x02F25000 ++#define WPA_CIPHER_SUITE_CCMP 0x04F25000 ++#define WPA_CIPHER_SUITE_WEP104 0x05F25000 ++ ++/* ----- Definitions for Authentication and Key Management Suite Selectors ----- */ ++#define RSN_AKM_SUITE_NONE 0x00AC0F00 ++#define RSN_AKM_SUITE_802_1X 0x01AC0F00 ++#define RSN_AKM_SUITE_PSK 0x02AC0F00 ++#if CFG_SUPPORT_802_11W ++#define RSN_AKM_SUITE_802_1X_SHA256 0x05AC0F00 ++#define RSN_AKM_SUITE_PSK_SHA256 0x06AC0F00 ++#endif ++ ++#define WPA_AKM_SUITE_NONE 0x00F25000 ++#define WPA_AKM_SUITE_802_1X 0x01F25000 ++#define WPA_AKM_SUITE_PSK 0x02F25000 ++ ++#define ELEM_ID_RSN_LEN_FIXED 20 /* The RSN IE len for associate request */ ++ ++#define ELEM_ID_WPA_LEN_FIXED 22 /* The RSN IE len for associate request */ ++ ++#define MASK_RSNIE_CAP_PREAUTH BIT(0) ++ ++#define GET_SELECTOR_TYPE(x) ((UINT_8)(((x) >> 24) & 0x000000FF)) ++#define SET_SELECTOR_TYPE(x, y) {x = (((x) & 0x00FFFFFF) | (((UINT_32)(y) << 24) & 0xFF000000))} ++ ++#define AUTH_CIPHER_CCMP 0x00000008 ++ ++/* Cihpher suite flags */ ++#define CIPHER_FLAG_NONE 0x00000000 ++#define CIPHER_FLAG_WEP40 0x00000001 /* BIT 1 */ ++#define CIPHER_FLAG_TKIP 0x00000002 /* BIT 2 */ ++#define CIPHER_FLAG_CCMP 0x00000008 /* BIT 4 */ ++#define CIPHER_FLAG_WEP104 0x00000010 /* BIT 5 */ ++#define CIPHER_FLAG_WEP128 0x00000020 /* BIT 6 */ ++ ++#define WAIT_TIME_IND_PMKID_CANDICATE_SEC 6 /* seconds */ ++#define TKIP_COUNTERMEASURE_SEC 60 /* seconds */ ++ ++#if CFG_SUPPORT_802_11W ++#define RSN_AUTH_MFP_DISABLED 0 /* MFP disabled */ ++#define RSN_AUTH_MFP_OPTIONAL 1 /* MFP optional */ ++#define RSN_AUTH_MFP_REQUIRED 2 /* MFP required */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* Flags for PMKID Candidate list structure */ ++#define EVENT_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 ++ ++#define CONTROL_FLAG_UC_MGMT_NO_ENC BIT(5) ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define RSN_IE(fp) ((P_RSN_INFO_ELEM_T) fp) ++#define WPA_IE(fp) ((P_WPA_INFO_ELEM_T) fp) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo); ++ ++BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo); ++ ++BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index); ++ ++BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index); ++ ++BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); ++ ++VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++BOOLEAN ++rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion); ++ ++BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo); ++ ++#if CFG_SUPPORT_AAA ++void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode); ++#endif ++ ++VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType); ++ ++VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex); ++ ++BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter); ++ ++VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); ++ ++VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter); ++ ++VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); ++#if CFG_SUPPORT_WPS2 ++VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++#endif ++ ++#if CFG_SUPPORT_802_11W ++UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter); ++ ++void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter); ++ ++void rsnStartSaQuery(IN P_ADAPTER_T prAdapter); ++ ++void rsnStopSaQuery(IN P_ADAPTER_T prAdapter); ++ ++void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype); ++#endif ++BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RSN_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h +new file mode 100644 +index 000000000000..c08b2244be6c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h +@@ -0,0 +1,988 @@ ++/* ++** Id: @(#) ++*/ ++ ++/*! \file "scan.h" ++ \brief ++ ++*/ ++ ++/* ++** Log: scan.h ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration ++ * with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting ++ * preferred band configuration corresponding to network type. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID ++ * in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID ++ * support as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings ++ * to work around some tricky AP which use space character as hidden SSID ++ * allow to have a single BSSID with multiple SSID to be presented in scanning result ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module ++ * with structure miss-align pointer issue ++ * always pre-allio WAPI related structure for align p2p module. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix compile error. ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add a functio prototype to find p2p descriptor of a bss descriptor directly. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add function prototype for return channel. ++ * modify data structure for scan specific device ID or TYPE. (Move from P2P Connection Settings to Scan Param) ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Check-in P2P Device Discovery Feature. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add a option for channel time extension in scan abort command. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Scan status "FIND" is used for P2P FSM find state. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * SCN module is now able to handle multiple concurrent scanning requests ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * pass band with channel number information as scan parameter ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * remove timer in DRV-SCN. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, other request ++ * will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan uninitialization procedure ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P related field in SCAN_PARAM_T. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 13 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * ++ * Add new HW CH macro support ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify scanBuildProbeReqFrameCommonIEs() to support P2P SCAN ++ * ++ * 02 23 2010 wh.su ++ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver ++ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * Simplify the process of Beacon during SCAN and remove redundant variable in PRE_BSS_DESC_T ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding variable for wapi ap ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * remove non-used secuirty variavle ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Refine data structure of BSS_DESC_T and PRE_BSS_DESC_T ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add eNetType to rScanParam and revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add ucAvailablePhyTypeSet to BSS_DESC_T ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aucSrcAddress to SCAN_PARAM_T for P2P's Device Address ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the security related variable ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the security ie filed for scan parsing ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add scanSearchBssDescByPolicy() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function declarations of scan_fsm.c ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add scan.h to source control ++** ++*/ ++ ++#ifndef _SCAN_H ++#define _SCAN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "gl_vendor.h" ++ ++/* TDLS test purpose */ ++extern BOOLEAN flgTdlsTestExtCapElm; ++extern UINT8 aucTdlsTestExtCapElm[]; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/*! Maximum buffer size of SCAN list */ ++#define SCN_MAX_BUFFER_SIZE (CFG_MAX_NUM_BSS_LIST * ALIGN_4(sizeof(BSS_DESC_T))) ++ ++#define SCN_RM_POLICY_EXCLUDE_CONNECTED BIT(0) /* Remove SCAN result except the connected one. */ ++#define SCN_RM_POLICY_TIMEOUT BIT(1) /* Remove the timeout one */ ++#define SCN_RM_POLICY_OLDEST_HIDDEN BIT(2) /* Remove the oldest one with hidden ssid */ ++#define SCN_RM_POLICY_SMART_WEAKEST BIT(3) /* If there are more than half BSS which has the ++ * same ssid as connection setting, remove the ++ * weakest one from them ++ * Else remove the weakest one. ++ */ ++#define SCN_RM_POLICY_ENTIRE BIT(4) /* Remove entire SCAN result */ ++ ++#define SCN_BSS_DESC_SAME_SSID_THRESHOLD 3 /* This is used by POLICY SMART WEAKEST, ++ * If exceed this value, remove weakest BSS_DESC_T ++ * with same SSID first in large network. ++ */ ++ ++/* the scan time in WFD mode + 2.4G/5G is about 9s so we need to enlarge the value */ ++#define SCN_BSS_DESC_REMOVE_TIMEOUT_SEC 15 /* Second. */ ++ /* This is used by POLICY TIMEOUT, ++ * If exceed this value, remove timeout BSS_DESC_T. ++ */ ++ ++#define SCN_PROBE_DELAY_MSEC 0 ++ ++#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC 5 /* Second. */ ++ ++#define SCN_NLO_NETWORK_CHANNEL_NUM (4) ++ ++/*----------------------------------------------------------------------------*/ ++/* MSG_SCN_SCAN_REQ */ ++/*----------------------------------------------------------------------------*/ ++#define SCAN_REQ_SSID_WILDCARD BIT(0) ++#define SCAN_REQ_SSID_P2P_WILDCARD BIT(1) ++#define SCAN_REQ_SSID_SPECIFIED BIT(2) ++ ++/*----------------------------------------------------------------------------*/ ++/* Support Multiple SSID SCAN */ ++/*----------------------------------------------------------------------------*/ ++#define SCN_SSID_MAX_NUM CFG_SCAN_SSID_MAX_NUM ++#define SCN_SSID_MATCH_MAX_NUM CFG_SCAN_SSID_MATCH_MAX_NUM ++ ++#define SWC_NUM_BSSID_THRESHOLD_DEFAULT 8 ++#define SWC_RSSI_WINDSIZE_DEFAULT 8 ++#define LOST_AP_WINDOW 16 ++#define MAX_CHANNEL_NUM_PER_BUCKETS 8 ++ ++#define SCN_BSS_JOIN_FAIL_THRESOLD 4 ++#define SCN_BSS_JOIN_FAIL_CNT_RESET_SEC 15 ++#define SCN_BSS_JOIN_FAIL_RESET_STEP 2 ++ ++#if CFG_SUPPORT_BATCH_SCAN ++/*----------------------------------------------------------------------------*/ ++/* SCAN_BATCH_REQ */ ++/*----------------------------------------------------------------------------*/ ++#define SCAN_BATCH_REQ_START BIT(0) ++#define SCAN_BATCH_REQ_STOP BIT(1) ++#define SCAN_BATCH_REQ_RESULT BIT(2) ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_SCAN_TYPE_T { ++ SCAN_TYPE_PASSIVE_SCAN = 0, ++ SCAN_TYPE_ACTIVE_SCAN, ++ SCAN_TYPE_NUM ++} ENUM_SCAN_TYPE_T, *P_ENUM_SCAN_TYPE_T; ++ ++typedef enum _ENUM_SCAN_STATE_T { ++ SCAN_STATE_IDLE = 0, ++ SCAN_STATE_SCANNING, ++ SCAN_STATE_NUM ++} ENUM_SCAN_STATE_T; ++ ++typedef enum _ENUM_SCAN_CHANNEL_T { ++ SCAN_CHANNEL_FULL = 0, ++ SCAN_CHANNEL_2G4, ++ SCAN_CHANNEL_5G, ++ SCAN_CHANNEL_P2P_SOCIAL, ++ SCAN_CHANNEL_SPECIFIED, ++ SCAN_CHANNEL_NUM ++} ENUM_SCAN_CHANNEL, *P_ENUM_SCAN_CHANNEL; ++ ++typedef struct _MSG_SCN_FSM_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_32 u4Dummy; ++} MSG_SCN_FSM_T, *P_MSG_SCN_FSM_T; ++ ++typedef enum _ENUM_PSCAN_STATE_T { ++ PSCN_IDLE = 1, ++ PSCN_SCANNING, ++ PSCN_RESET, ++ PSCAN_STATE_T_NUM ++} ENUM_PSCAN_STATE_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* BSS Descriptors */ ++/*----------------------------------------------------------------------------*/ ++struct _BSS_DESC_T { ++ LINK_ENTRY_T rLinkEntry; ++ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ ++ ++ BOOLEAN fgIsConnecting; /* If we are going to connect to this BSS ++ * (JOIN or ROAMING to another BSS), don't ++ * remove this record from BSS List. ++ */ ++ BOOLEAN fgIsConnected; /* If we have connected to this BSS (NORMAL_TR), ++ * don't removed this record from BSS list. ++ */ ++ ++ BOOLEAN fgIsHiddenSSID; /* When this flag is TRUE, means the SSID ++ * of this BSS is not known yet. ++ */ ++ UINT_8 ucSSIDLen; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ ++ OS_SYSTIME rUpdateTime; ++ ++ ENUM_BSS_TYPE_T eBSSType; ++ ++ UINT_16 u2CapInfo; ++ ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2ATIMWindow; ++ ++ UINT_16 u2OperationalRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ ++ BOOLEAN fgIsERPPresent; ++ BOOLEAN fgIsHTPresent; ++ ++ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this BSS */ ++ ++ UINT_8 ucChannelNum; ++ ++ ENUM_CHNL_EXT_T eSco; /* Record bandwidth for association process ++ Some AP will send association resp by 40MHz BW */ ++ ENUM_BAND_T eBand; ++ ++ UINT_8 ucDTIMPeriod; ++ ++ BOOLEAN fgIsLargerTSF; /* This BSS's TimeStamp is larger than us(TCL == 1 in RX_STATUS_T) */ ++ ++ UINT_8 ucRCPI; ++ ++ UINT_8 ucWmmFlag; /* A flag to indicate this BSS's WMM capability */ ++ ++ /*! \brief The srbiter Search State will matched the scan result, ++ and saved the selected cipher and akm, and report the score, ++ for arbiter join state, join module will carry this target BSS ++ to rsn generate ie function, for gen wpa/rsn ie */ ++ UINT_32 u4RsnSelectedGroupCipher; ++ UINT_32 u4RsnSelectedPairwiseCipher; ++ UINT_32 u4RsnSelectedAKMSuite; ++ ++ UINT_16 u2RsnCap; ++ ++ RSN_INFO_T rRSNInfo; ++ RSN_INFO_T rWPAInfo; ++#if 1 /* CFG_SUPPORT_WAPI */ ++ WAPI_INFO_T rIEWAPI; ++ BOOLEAN fgIEWAPI; ++#endif ++ BOOLEAN fgIERSN; ++ BOOLEAN fgIEWPA; ++ ++ /*! \brief RSN parameters selected for connection */ ++ /*! \brief The Select score for final AP selection, ++ 0, no sec, 1,2,3 group cipher is WEP, TKIP, CCMP */ ++ UINT_8 ucEncLevel; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsP2PPresent; ++ BOOLEAN fgIsP2PReport; /* TRUE: report to upper layer */ ++ P_P2P_DEVICE_DESC_T prP2pDesc; ++ ++ UINT_8 aucIntendIfAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ ++/* UINT_8 ucDevCapabilityBitmap; */ /* Device Capability Attribute. (P2P_DEV_CAPABILITY_XXXX) */ ++/* UINT_8 ucGroupCapabilityBitmap; */ /* Group Capability Attribute. (P2P_GROUP_CAPABILITY_XXXX) */ ++ ++ LINK_T rP2pDeviceList; ++ ++/* P_LINK_T prP2pDeviceList; */ ++ ++ /* For ++ * 1. P2P Capability. ++ * 2. P2P Device ID. ( in aucSrcAddr[] ) ++ * 3. NOA (TODO:) ++ * 4. Extend Listen Timing. (Probe Rsp) (TODO:) ++ * 5. P2P Device Info. (Probe Rsp) ++ * 6. P2P Group Info. (Probe Rsp) ++ */ ++#endif ++ ++ BOOLEAN fgIsIEOverflow; /* The received IE length exceed the maximum IE buffer size */ ++ UINT_16 u2RawLength; /* The byte count of aucRawBuf[] */ ++ UINT_16 u2IELength; /* The byte count of aucIEBuf[] */ ++ ++ ULARGE_INTEGER u8TimeStamp; /* Place u8TimeStamp before aucIEBuf[1] to force DW align */ ++ UINT_8 aucRawBuf[CFG_RAW_BUFFER_SIZE]; ++ UINT_8 aucIEBuf[CFG_IE_BUFFER_SIZE]; ++ UINT_8 ucJoinFailureCount; ++ OS_SYSTIME rJoinFailTime; ++}; ++ ++typedef struct _SCAN_PARAM_T { /* Used by SCAN FSM */ ++ /* Active or Passive */ ++ ENUM_SCAN_TYPE_T eScanType; ++ ++ /* Network Type */ ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ ++ /* Specified SSID Type */ ++ UINT_8 ucSSIDType; ++ UINT_8 ucSSIDNum; ++ ++ /* Length of Specified SSID */ ++ UINT_8 ucSpecifiedSSIDLen[SCN_SSID_MAX_NUM]; ++ ++ /* Specified SSID */ ++ UINT_8 aucSpecifiedSSID[SCN_SSID_MAX_NUM][ELEM_MAX_LEN_SSID]; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgFindSpecificDev; /* P2P: Discovery Protocol */ ++ UINT_8 aucDiscoverDevAddr[MAC_ADDR_LEN]; ++ BOOLEAN fgIsDevType; ++ P2P_DEVICE_TYPE_T rDiscoverDevType; ++ ++ UINT_16 u2PassiveListenInterval; ++ /* TODO: Find Specific Device Type. */ ++#endif /* CFG_SUPPORT_P2P */ ++ ++ BOOLEAN fgIsObssScan; ++ BOOLEAN fgIsScanV2; ++ ++ /* Run time flags */ ++ UINT_16 u2ProbeDelayTime; ++ ++ /* channel information */ ++ ENUM_SCAN_CHANNEL eScanChannel; ++ UINT_8 ucChannelListNum; ++ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ ++ /* Feedback information */ ++ UINT_8 ucSeqNum; ++ ++ /* Information Element */ ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++ ++} SCAN_PARAM_T, *P_SCAN_PARAM_T; ++ ++typedef struct _NLO_PARAM_T { /* Used by SCAN FSM */ ++ SCAN_PARAM_T rScanParam; ++ ++ /* NLO */ ++ BOOLEAN fgStopAfterIndication; ++ UINT_8 ucFastScanIteration; ++ UINT_16 u2FastScanPeriod; ++ UINT_16 u2SlowScanPeriod; ++ ++ /* Match SSID */ ++ UINT_8 ucMatchSSIDNum; ++ UINT_8 ucMatchSSIDLen[SCN_SSID_MATCH_MAX_NUM]; ++ UINT_8 aucMatchSSID[SCN_SSID_MATCH_MAX_NUM][ELEM_MAX_LEN_SSID]; ++ ++ UINT_8 aucCipherAlgo[SCN_SSID_MATCH_MAX_NUM]; ++ UINT_16 au2AuthAlgo[SCN_SSID_MATCH_MAX_NUM]; ++ UINT_8 aucChannelHint[SCN_SSID_MATCH_MAX_NUM][SCN_NLO_NETWORK_CHANNEL_NUM]; ++ P_BSS_DESC_T aprPendingBssDescToInd[SCN_SSID_MATCH_MAX_NUM]; ++} NLO_PARAM_T, *P_NLO_PARAM_T; ++ ++#if 1 ++ ++typedef struct _GSCN_CHANNEL_INFO_T { ++ UINT_8 ucBand; ++ UINT_8 ucChannel; /* frequency */ ++ UINT_8 ucPassive; /* 0 => active, 1 => passive scan; ignored for DFS */ ++ UINT_8 aucReserved[1]; ++ ++ UINT_32 u4DwellTimeMs; /* dwell time hint */ ++ /* Add channel class */ ++} GSCN_CHANNEL_INFO_T, *P_GSCN_CHANNEL_INFO_T; ++ ++typedef struct _GSCAN_CHANNEL_BUCKET_T { ++ ++ UINT_16 u2BucketIndex; /* bucket index, 0 based */ ++ UINT_8 ucBucketFreqMultiple; /* desired period, in millisecond; ++ * if this is too low, the firmware should choose to generate ++ * results as fast as it can instead of failing the command */ ++ /* report_events semantics - ++ * 0 => report only when scan history is % full ++ * 1 => same as 0 + report a scan completion event after scanning this bucket ++ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL ++ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to ++ supplicant as well (optional) . */ ++ UINT_8 ucReportFlag; ++ UINT_8 ucNumChannels; ++ UINT_8 aucReserved[3]; ++ WIFI_BAND eBand; /* when UNSPECIFIED, use channel list */ ++ GSCN_CHANNEL_INFO_T arChannelList[GSCAN_MAX_CHANNELS]; /* channels to scan; these may include DFS channels */ ++} GSCAN_CHANNEL_BUCKET_T, *P_GSCAN_CHANNEL_BUCKET_T; ++ ++typedef struct _CMD_GSCN_REQ_T { ++ UINT_8 ucFlags; ++ UINT_8 ucNumScnToCache; ++ UINT_8 aucReserved[2]; ++ UINT_32 u4BufferThreshold; ++ UINT_32 u4BasePeriod; /* base timer period in ms */ ++ UINT_32 u4NumBuckets; ++ UINT_32 u4MaxApPerScan; /* number of APs to store in each scan in the */ ++ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ ++ ++ GSCAN_CHANNEL_BUCKET_T arChannelBucket[GSCAN_MAX_BUCKETS]; ++} CMD_GSCN_REQ_T, *P_CMD_GSCN_REQ_T; ++ ++#endif ++ ++typedef struct _CMD_GSCN_SCN_COFIG_T { ++ UINT_8 ucNumApPerScn; /* GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN */ ++ UINT_32 u4NumScnToCache; /* GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE */ ++ UINT_32 u4BufferThreshold; /* GSCAN_ATTRIBUTE_REPORT_THRESHOLD */ ++} CMD_GSCN_SCN_COFIG_T, *P_CMD_GSCN_SCN_COFIG_T; ++ ++typedef struct _CMD_GET_GSCAN_RESULT { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[2]; ++ UINT_8 ucFlush; ++ UINT_32 u4Num; ++} CMD_GET_GSCAN_RESULT_T, *P_CMD_GET_GSCAN_RESULT_T; ++ ++typedef struct _CMD_BATCH_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucCmd; /* Start/ Stop */ ++ UINT_8 ucMScan; /* an integer number of scans per batch */ ++ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ ++ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd like ++ approximate distance reported */ ++ UINT_8 ucChannel; /* channels */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ ++ CHANNEL_INFO_T arChannelList[32]; /* channels */ ++} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; ++ ++typedef struct _PSCN_PARAM_T { ++ UINT_8 ucVersion; ++ CMD_NLO_REQ rCurrentCmdNloReq; ++ CMD_BATCH_REQ_T rCurrentCmdBatchReq; ++ CMD_GSCN_REQ_T rCurrentCmdGscnReq; ++ BOOLEAN fgNLOScnEnable; ++ BOOLEAN fgBatchScnEnable; ++ BOOLEAN fgGScnEnable; ++ UINT_32 u4BasePeriod; /* GSCAN_ATTRIBUTE_BASE_PERIOD */ ++} PSCN_PARAM_T, *P_PSCN_PARAM_T; ++ ++typedef struct _SCAN_INFO_T { ++ ENUM_SCAN_STATE_T eCurrentState; /* Store the STATE variable of SCAN FSM */ ++ ++ OS_SYSTIME rLastScanCompletedTime; ++ ++ SCAN_PARAM_T rScanParam; ++ NLO_PARAM_T rNloParam; ++ ++ UINT_32 u4NumOfBssDesc; ++ ++ UINT_8 aucScanBuffer[SCN_MAX_BUFFER_SIZE]; ++ ++ LINK_T rBSSDescList; ++ ++ LINK_T rFreeBSSDescList; ++ ++ LINK_T rPendingMsgList; ++ ++ /* Sparse Channel Detection */ ++ BOOLEAN fgIsSparseChannelValid; ++ RF_CHANNEL_INFO_T rSparseChannel; ++ ++ /* NLO scanning state tracking */ ++ BOOLEAN fgNloScanning; ++ BOOLEAN fgPscnOnnning; ++ BOOLEAN fgGScnConfigSet; ++ BOOLEAN fgGScnParamSet; ++ P_PSCN_PARAM_T prPscnParam; ++ ENUM_PSCAN_STATE_T eCurrentPSCNState; ++ ++} SCAN_INFO_T, *P_SCAN_INFO_T; ++ ++/* Incoming Mailbox Messages */ ++typedef struct _MSG_SCN_SCAN_REQ_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ ENUM_SCAN_TYPE_T eScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDLength; ++ UINT_8 aucSSID[PARAM_MAX_LEN_SSID]; ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ ++#endif ++ ENUM_SCAN_CHANNEL eScanChannel; ++ UINT_8 ucChannelListNum; ++ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} MSG_SCN_SCAN_REQ, *P_MSG_SCN_SCAN_REQ; ++ ++typedef struct _MSG_SCN_SCAN_REQ_V2_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ ENUM_SCAN_TYPE_T eScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDNum; ++ P_PARAM_SSID_T prSsid; ++ UINT_16 u2ProbeDelay; ++ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ ++ ENUM_SCAN_CHANNEL eScanChannel; ++ UINT_8 ucChannelListNum; ++ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} MSG_SCN_SCAN_REQ_V2, *P_MSG_SCN_SCAN_REQ_V2; ++ ++typedef struct _MSG_SCN_SCAN_CANCEL_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsChannelExt; ++#endif ++} MSG_SCN_SCAN_CANCEL, *P_MSG_SCN_SCAN_CANCEL; ++ ++/* Outgoing Mailbox Messages */ ++typedef enum _ENUM_SCAN_STATUS_T { ++ SCAN_STATUS_DONE = 0, ++ SCAN_STATUS_CANCELLED, ++ SCAN_STATUS_FAIL, ++ SCAN_STATUS_BUSY, ++ SCAN_STATUS_NUM ++} ENUM_SCAN_STATUS, *P_ENUM_SCAN_STATUS; ++ ++typedef struct _MSG_SCN_SCAN_DONE_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ ENUM_SCAN_STATUS eScanStatus; ++} MSG_SCN_SCAN_DONE, *P_MSG_SCN_SCAN_DONE; ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++typedef enum { ++ AGPS_PHY_A, ++ AGPS_PHY_B, ++ AGPS_PHY_G, ++} AP_PHY_TYPE; ++ ++typedef struct _AGPS_AP_INFO_T { ++ UINT_8 aucBSSID[6]; ++ INT_16 i2ApRssi; /* -127..128 */ ++ UINT_16 u2Channel; /* 0..256 */ ++ AP_PHY_TYPE ePhyType; ++} AGPS_AP_INFO_T, *P_AGPS_AP_INFO_T; ++ ++typedef struct _AGPS_AP_LIST_T { ++ UINT_8 ucNum; ++ AGPS_AP_INFO_T arApInfo[32]; ++} AGPS_AP_LIST_T, *P_AGPS_AP_LIST_T; ++#endif ++ ++typedef struct _CMD_SET_PSCAN_PARAM { ++ UINT_8 ucVersion; ++ CMD_NLO_REQ rCmdNloReq; ++ CMD_BATCH_REQ_T rCmdBatchReq; ++ CMD_GSCN_REQ_T rCmdGscnReq; ++ BOOLEAN fgNLOScnEnable; ++ BOOLEAN fgBatchScnEnable; ++ BOOLEAN fgGScnEnable; ++ UINT_32 u4BasePeriod; ++} CMD_SET_PSCAN_PARAM, *P_CMD_SET_PSCAN_PARAM; ++ ++typedef struct _CMD_SET_PSCAN_ADD_HOTLIST_BSSID { ++ UINT_8 aucMacAddr[6]; ++ UINT_8 ucFlags; ++ UINT_8 aucReserved[5]; ++} CMD_SET_PSCAN_ADD_HOTLIST_BSSID, *P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID; ++ ++typedef struct _CMD_SET_PSCAN_ADD_SWC_BSSID { ++ INT_32 i4RssiLowThreshold; ++ INT_32 i4RssiHighThreshold; ++ UINT_8 aucMacAddr[6]; ++ UINT_8 aucReserved[6]; ++} CMD_SET_PSCAN_ADD_SWC_BSSID, *P_CMD_SET_PSCAN_ADD_SWC_BSSID; ++ ++typedef struct _CMD_SET_PSCAN_MAC_ADDR { ++ UINT_8 ucVersion; ++ UINT_8 ucFlags; ++ UINT_8 aucMacAddr[6]; ++ UINT_8 aucReserved[8]; ++} CMD_SET_PSCAN_MAC_ADDR, *P_CMD_SET_PSCAN_MAC_ADDR; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in scan.c */ ++/*----------------------------------------------------------------------------*/ ++VOID scnInit(IN P_ADAPTER_T prAdapter); ++ ++VOID scnUninit(IN P_ADAPTER_T prAdapter); ++ ++/* BSS-DESC Search */ ++P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++ ++P_BSS_DESC_T ++scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); ++ ++P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]); ++ ++P_BSS_DESC_T ++scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++#endif ++ ++/* BSS-DESC Search - Alternative */ ++P_BSS_DESC_T ++scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]); ++ ++P_BSS_DESC_T ++scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, ++ IN UINT_8 aucBSSID[], ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); ++ ++/* BSS-DESC Allocation */ ++P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter); ++ ++/* BSS-DESC Removal */ ++VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy); ++ ++VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++ ++VOID ++scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/* BSS-DESC State Change */ ++VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++ ++#if 0 ++/* BSS-DESC Insertion */ ++P_BSS_DESC_T scanAddToInternalScanResult(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb, IN P_BSS_DESC_T prBssDesc); ++#endif ++ ++/* BSS-DESC Insertion - ALTERNATIVE */ ++P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); ++ ++VOID ++scanBuildProbeReqFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, ++ IN PUINT_8 pucDesiredSsid, IN UINT_32 u4DesiredSsidLen, IN UINT_16 u2SupportedRateSet); ++ ++WLAN_STATUS scanSendProbeReqFrames(IN P_ADAPTER_T prAdapter, IN P_SCAN_PARAM_T prScanParam); ++ ++VOID scanUpdateBssDescForSearch(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); ++ ++VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines in scan_fsm.c */ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState); ++ ++/*----------------------------------------------------------------------------*/ ++/* Command Routines */ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter); ++ ++VOID scnSendScanReq(IN P_ADAPTER_T prAdapter); ++ ++VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter); ++ ++VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* RX Event Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone); ++ ++VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg); ++ ++VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg); ++ ++VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Generation */ ++/*----------------------------------------------------------------------------*/ ++VOID ++scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Query for sparse channel */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID/IOCTL Handling */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSsidNum, ++ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval); ++ ++BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct); ++ ++BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); ++ ++BOOLEAN scnFsmGSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); ++ ++#if 0 ++ ++BOOLEAN scnFsmGSCNSetRssiSignificatn(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); ++#endif ++ ++BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId); ++ ++BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr); ++ ++#if 1 /* CFG_SUPPORT_GSCN_NONSYNC_BROADCOM */ ++BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam); ++ ++#else ++BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_REQ_T prCmdGscnParam); ++ ++#endif ++ ++BOOLEAN ++scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_NLO_REQ prCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN); ++ ++BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig); ++ ++BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd); ++ ++VOID ++scnPSCNFsm(IN P_ADAPTER_T prAdapter, ++ ENUM_PSCAN_STATE_T eNextPSCNState, ++ IN P_CMD_NLO_REQ prCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN); ++ ++#endif /* _SCAN_H */ ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h +new file mode 100644 +index 000000000000..c6c468e06c4a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h +@@ -0,0 +1,233 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/sec_fsm.h#1 ++*/ ++ ++/*! \file sec_fsm.h ++ \brief Declaration of functions and finite state machine for SECURITY Module. ++ ++ Function declaration for privacy.c and SEC_STATE for SECURITY FSM. ++*/ ++ ++/* ++** Log: sec_fsm.h ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 20 2010 wh.su ++ * NULL ++ * adding the eapol callback setting. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 03 04 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Code refine, and remove non-used code. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, and modify the security ++ * related callback function prototype. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * fixed the deauth Tx done callback parameter ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the reference function declaration ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * delete non-used code ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function prototype ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function declaration ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the security variable ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** \main\maintrunk.MT5921\14 2009-04-06 15:35:47 GMT mtk01088 ++** add the variable to set the disable AP selection for privacy check, for wps open networking. ++** \main\maintrunk.MT5921\13 2008-11-19 11:46:01 GMT mtk01088 ++** rename some variable with pre-fix to avoid the misunderstanding ++** \main\maintrunk.MT5921\12 2008-08-28 20:37:11 GMT mtk01088 ++** remove non-used code ++** ++** \main\maintrunk.MT5921\11 2008-03-18 09:51:52 GMT mtk01088 ++** Add function declaration for timer to indicate pmkid candidate ++** \main\maintrunk.MT5921\10 2008-02-29 15:12:08 GMT mtk01088 ++** add variable for sw port control ++** \main\maintrunk.MT5921\9 2008-02-29 12:37:30 GMT mtk01088 ++** rename the security related function declaration ++** \main\maintrunk.MT5921\8 2007-12-27 13:59:08 GMT mtk01088 ++** adjust the wlan table and sec fsm init timing ++** \main\maintrunk.MT5921\7 2007-11-20 10:39:49 GMT mtk01088 ++** add function timer for wait EAPoL Error timeout ++** \main\maintrunk.MT5921\6 2007-11-06 20:39:08 GMT mtk01088 ++** rename the counter measure timer ++** \main\maintrunk.MT5921\5 2007-11-06 20:14:31 GMT mtk01088 ++** add a abort function ++** Revision 1.5 2007/07/16 02:33:42 MTK01088 ++** change the ENUM declaration structure prefix from r to e ++** ++** Revision 1.4 2007/07/09 06:23:10 MTK01088 ++** update ++** ++** Revision 1.3 2007/07/04 10:09:04 MTK01088 ++** adjust the state for security fsm ++** change function name ++** ++** Revision 1.2 2007/07/03 08:13:22 MTK01088 ++** change the sec fsm state ++** add the event for sec fsm ++** ++** Revision 1.1 2007/06/27 06:20:35 MTK01088 ++** add the sec fsm header file ++** ++** ++*/ ++#ifndef _SEC_FSM_H ++#define _SEC_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* TKIP CounterMeasure interval for Rejoin to Network. */ ++#define COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC 60 ++ ++/* Timeout to wait the EAPoL Error Report frame Send out. */ ++#define EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC 1 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef UINT_32 SEC_STATUS, *P_SEC_STATUS; ++ ++#if 0 ++/* WPA2 PMKID candicate structure */ ++typedef struct _PMKID_CANDICATE_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; /* MAC address */ ++ UINT_32 u4PreAuthFlags; ++} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; ++#endif ++ ++typedef SEC_STATUS(*PFN_SEC_FSM_STATE_HANDLER) (VOID); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define SEC_STATE_TRANSITION_FLAG fgIsTransition ++#define SEC_NEXT_STATE_VAR eNextState ++ ++#define SEC_STATE_TRANSITION(prAdapter, prSta, eFromState, eToState) \ ++ { secFsmTrans_ ## eFromState ## _to_ ## eToState(prAdapter, prSta); \ ++ SEC_NEXT_STATE_VAR = SEC_STATE_ ## eToState; \ ++ SEC_STATE_TRANSITION_FLAG = (BOOLEAN)TRUE; \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*--------------------------------------------------------------*/ ++/* Routines to handle the sec check */ ++/*--------------------------------------------------------------*/ ++/***** Routines in sec_fsm.c *****/ ++VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID ++secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); ++ ++VOID ++secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _SEC_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h +new file mode 100644 +index 000000000000..1c0f9a76e119 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h +@@ -0,0 +1,368 @@ ++/* ++** Id: stats.h#1 ++*/ ++ ++/*! \file stats.h ++ \brief This file includes statistics support. ++*/ ++ ++/* ++** Log: stats.h ++ * ++ * 07 17 2014 samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++extern UINT_64 u8DrvOwnStart, u8DrvOwnEnd; ++extern UINT32 u4DrvOwnMax; ++extern BOOLEAN fgIsUnderSuspend; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* Command to TDLS core module */ ++typedef enum _STATS_CMD_CORE_ID { ++ STATS_CORE_CMD_ENV_REQUEST = 0x00 ++} STATS_CMD_CORE_ID; ++ ++typedef enum _STATS_EVENT_HOST_ID { ++ STATS_HOST_EVENT_ENV_REPORT = 0x00, ++ STATS_HOST_EVENT_RX_DROP ++} STATS_EVENT_HOST_ID; ++ ++#define CFG_ARP BIT(0) ++#define CFG_DNS BIT(1) ++#define CFG_TCP BIT(2) ++#define CFG_UDP BIT(3) ++#define CFG_EAPOL BIT(4) ++#define CFG_DHCP BIT(5) ++#define CFG_ICMP BIT(6) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _STATS_CMD_CORE_T { ++ ++ UINT32 u4Command; /* STATS_CMD_CORE_ID */ ++ ++ UINT8 ucStaRecIdx; ++ UINT8 ucReserved[3]; ++ ++ UINT32 u4Reserved[4]; ++ ++#define STATS_CMD_CORE_RESERVED_SIZE 50 ++ union { ++ UINT8 Reserved[STATS_CMD_CORE_RESERVED_SIZE]; ++ } Content; ++ ++} STATS_CMD_CORE_T; ++ ++typedef struct _STATS_INFO_ENV_T { ++ ++ BOOLEAN fgIsUsed; /* TRUE: used */ ++ ++ /* ------------------- TX ------------------- */ ++ BOOLEAN fgTxIsRtsUsed; /* TRUE: we use RTS/CTS currently */ ++ BOOLEAN fgTxIsRtsEverUsed; /* TRUE: we ever use RTS/CTS */ ++ BOOLEAN fgTxIsCtsSelfUsed; /* TRUE: we use CTS-self */ ++ ++#define STATS_INFO_TX_PARAM_HW_BW40_OFFSET 0 ++#define STATS_INFO_TX_PARAM_HW_SHORT_GI20_OFFSET 1 ++#define STATS_INFO_TX_PARAM_HW_SHORT_GI40_OFFSET 2 ++#define STATS_INFO_TX_PARAM_USE_BW40_OFFSET 3 ++#define STATS_INFO_TX_PARAM_USE_SHORT_GI_OFFSET 4 ++#define STATS_INFO_TX_PARAM_NO_ACK_OFFSET 5 ++ UINT_8 ucTxParam; ++ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucReserved1[2]; ++ ++ UINT32 u4TxDataCntAll; /* total tx count from host */ ++ UINT32 u4TxDataCntOK; /* total tx ok count to air */ ++ UINT32 u4TxDataCntErr; /* total tx err count to air */ ++ ++ /* WLAN_STATUS_BUFFER_RETAINED ~ WLAN_STATUS_PACKET_LIFETIME_ERROR */ ++ UINT32 u4TxDataCntErrType[6]; /* total tx err count for different type to air */ ++ ++ UINT_8 ucTxRate1NonHTMax; ++ UINT_8 ucTxRate1HTMax; ++ UINT32 u4TxRateCntNonHT[16]; /* tx done rate */ ++ UINT32 u4TxRateCntHT[16]; /* tx done rate */ ++ ++ UINT_8 ucTxAggBitmap; /* TX BA sessions TID0 ~ TID7 */ ++ UINT_8 ucTxPeerAggMaxSize; ++ ++ /* ------------------- RX ------------------- */ ++ BOOLEAN fgRxIsRtsUsed; /* TRUE: peer uses RTS/CTS currently */ ++ BOOLEAN fgRxIsRtsEverUsed; /* TRUE: peer ever uses RTS/CTS */ ++ ++ UINT_8 ucRcvRcpi; ++ UINT_8 ucHwChanNum; ++ BOOLEAN fgRxIsShortGI; ++ UINT_8 ucReserved2[1]; ++ ++ UINT32 u4RxDataCntAll; /* total rx count from peer */ ++ UINT32 u4RxDataCntErr; /* total rx err count */ ++ UINT32 u4RxRateCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ ++ ++ UINT_8 ucRxAggBitmap; /* RX BA sessions TID0 ~ TID7 */ ++ UINT_8 ucRxAggMaxSize; ++ ++#define STATS_INFO_PHY_MODE_CCK 0 ++#define STATS_INFO_PHY_MODE_OFDM 1 ++#define STATS_INFO_PHY_MODE_HT 2 ++#define STATS_INFO_PHY_MODE_VHT 3 ++ UINT_8 ucBssSupPhyMode; /* CCK, OFDM, HT, or VHT BSS */ ++ ++ UINT_8 ucVersion; /* the version of statistics info environment */ ++ ++ /* ------------------- Delay ------------------- */ ++#define STATS_AIR_DELAY_INT 500 /* 500 byte */ ++ ++ /* delay in firmware from host to MAC */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxH2M[3], u4StayIntMinH2M[3], u4StayIntAvgH2M[3]; ++ ++ /* delay in firmware from MAC to TX done */ ++ /* unit: 32us, for 500B, 1000B, max */ ++ UINT32 u4AirDelayMax[3], u4AirDelayMin[3], u4AirDelayAvg[3]; ++ ++ /* delay in firmware from host to TX done */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMax[3], u4StayIntMin[3], u4StayIntAvg[3]; ++ UINT32 u4StayIntMaxSysTime[3]; ++ ++ /* delay in firmware from driver to TX done */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxD2T[3], u4StayIntMinD2T[3], u4StayIntAvgD2T[3]; ++ ++ /* delay count in firmware from host to TX done */ ++ /* u4StayIntByConst: divide 4 fix partitions to count each delay in firmware */ ++#define STATS_STAY_INT_CONST 1 /* 1ms */ ++#define STATS_STAY_INT_CONST_2 5 ++#define STATS_STAY_INT_CONST_3 10 ++#define STATS_STAY_INT_CONST_4 15 ++#define STATS_STAY_INT_CONST_NUM 4 ++ UINT32 u4StayIntByConst[STATS_STAY_INT_CONST_NUM]; ++ ++ /* ++ u4StayIntMaxPast: past maximum delay in firmware ++ u4StayIntCnt[]: divide 4 partitions to count each delay in firmware ++ */ ++#define STATS_STAY_INT_NUM 4 ++ UINT32 u4StayIntMaxPast; ++ UINT32 u4StayIntCnt[STATS_STAY_INT_NUM + 1]; ++ ++ /* delay count in firmware from driver to HIF */ ++ /* u4StayIntD2HByConst: divide 4 fix partitions to count each delay in firmware */ ++#define STATS_STAY_INT_D2H_CONST 10 /* 10ms */ ++#define STATS_STAY_INT_D2H_CONST_2 20 ++#define STATS_STAY_INT_D2H_CONST_3 30 ++#define STATS_STAY_INT_D2H_CONST_4 40 ++#define STATS_STAY_INT_D2H_CONST_NUM 4 ++ UINT32 u4StayIntD2HByConst[STATS_STAY_INT_D2H_CONST_NUM]; ++ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; ++ ++ /* ------------------- Others ------------------- */ ++ UINT32 u4NumOfChanChange; /* total channel change count */ ++ UINT32 u4NumOfRetryCnt; /* total TX retry count */ ++ UINT32 u4RxFifoFullCnt; /* counter of the number of the packets which ++ pass RFCR but are dropped due to FIFO full. */ ++ UINT32 u4PsIntMax; /* maximum time from ps to active */ ++ UINT_8 ucNumOfPsChange; /* peer power save change count */ ++ UINT_8 ucReserved3[3]; ++ ++ UINT32 u4ReportSysTime; /* firmware system time */ ++ UINT32 u4RxDataCntOk; /* total rx count to hif */ ++ ++ /* V4 */ ++ UINT32 u4RxRateRetryCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ ++ UINT32 au4ChanIdleCnt[10]; /* past Channel idle count in unit of slot */ ++ ++ /* V5 */ ++ UINT32 u4BtContUseTime; /* the air time that BT continuous occypy */ ++ ++ /* V6 */ ++ UINT32 u4LastTxOkTime; /* last time we tx ok to the station */ ++ ++ /* V7 */ ++ UINT_8 ucBtWfCoexGrantCnt[8]; /* [0]:WF Rx Grant Cnt[1]: WF Tx Grant Cnt[2]: WF Grant with Priority1 */ ++ /* [4]:BT Rx Grant Cnt[5]: BT Tx Grant Cnt[6]: BT Grant with Priority1 */ ++ ++ /* V8 */ ++ UINT_32 u4RxMacFreeDescCnt[6]; ++ UINT_32 u4RxHifFreeDescCnt[6]; ++ ++ /* V9 */ ++#define STATS_MAX_RX_DROP_TYPE 20 ++ UINT32 u4NumOfRxDrop[STATS_MAX_RX_DROP_TYPE]; ++ ++ /* V10 */ ++ UINT_32 u4NumOfTxDone; /* number of all packets (data/man/ctrl) tx done */ ++ UINT_32 u4NumOfTxDoneFixRate; /* number of done rate = 0 */ ++ UINT_32 u4NumOfTxDoneErrRate; /* number of error done rate */ ++ UINT_32 u4NumOfNullTxDone; /* number of null tx done */ ++ UINT_32 u4NumOfQoSNullTxDone; /* number of QoS-null tx done */ ++ ++ /* V11 */ ++ /* delay in firmware from HIF RX to HIF RX Done */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxHR2HRD[3], u4StayIntMinHR2HRD[3], u4StayIntAvgHR2HRD[3]; ++ ++ /* V12 */ ++ UINT32 u4AirDelayTotal; /* agg all the air delay */ ++ ++ /* V13 */ ++ UINT32 u4CurrChnlInfo; /* add current channel information */ ++ ++ UINT_8 ucReserved_rate[4]; /* the field must be the last one */ ++} STATS_INFO_ENV_T; ++ ++/******************************************************************************* ++* M A C R O D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#if (CFG_SUPPORT_STATISTICS == 1) ++ ++#define STATS_ENV_REPORT_DETECT statsEnvReportDetect ++ ++#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) \ ++{ \ ++ (__StaRec__)->u4RxReorderFallAheadCnt++; \ ++} ++ ++#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) \ ++{ \ ++ (__StaRec__)->u4RxReorderFallBehindCnt++; \ ++} ++ ++#define STATS_RX_REORDER_HOLE_INC(__StaRec__) \ ++{ \ ++ (__StaRec__)->u4RxReorderHoleCnt++; \ ++} ++ ++#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) \ ++{ \ ++ if ((__IsTimeout__) == TRUE) \ ++ (__StaRec__)->u4RxReorderHoleTimeoutCnt++; \ ++} ++ ++#define STATS_RX_ARRIVE_TIME_RECORD(__SwRfb__) \ ++{ \ ++ (__SwRfb__)->rRxTime = StatsEnvTimeGet(); \ ++} ++ ++#define STATS_RX_PASS2OS_INC StatsEnvRxDone ++ ++#define STATS_RX_PKT_INFO_DISPLAY StatsRxPktInfoDisplay ++ ++#define STATS_TX_TIME_ARRIVE(__Skb__) \ ++do { \ ++ UINT_64 __SysTime; \ ++ __SysTime = StatsEnvTimeGet(); /* us */ \ ++ GLUE_SET_PKT_XTIME(__Skb__, __SysTime); \ ++} while (FALSE) ++ ++#define STATS_TX_TIME_TO_HIF StatsEnvTxTime2Hif ++ ++#define STATS_TX_PKT_CALLBACK StatsTxPktCallBack ++#define STATS_TX_PKT_DONE_INFO_DISPLAY StatsTxPktDoneInfoDisplay ++ ++#define STATS_DRIVER_OWN_RESET() \ ++{ \ ++ u4DrvOwnMax = 0; \ ++} ++#define STATS_DRIVER_OWN_START_RECORD() \ ++{ \ ++ u8DrvOwnStart = StatsEnvTimeGet(); \ ++} ++#define STATS_DRIVER_OWN_END_RECORD() \ ++{ \ ++ u8DrvOwnEnd = StatsEnvTimeGet(); \ ++} ++#define STATS_DRIVER_OWN_STOP() \ ++do { \ ++ UINT32 __Diff; \ ++ __Diff = (UINT32)(u8DrvOwnEnd - u8DrvOwnStart); \ ++ if (__Diff > u4DrvOwnMax) \ ++ u4DrvOwnMax = __Diff; \ ++} while (FALSE) ++ ++#else ++ ++#define STATS_ENV_REPORT_DETECT(__Adapter__, __StaRecIndex__) ++ ++#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) ++#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) ++#define STATS_RX_REORDER_HOLE_INC(__StaRec__) ++#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) ++#define STATS_RX_PASS2OS_INC(__StaRec__, __SwRfb__) ++#define STATS_RX_PKT_INFO_DISPLAY(__Pkt__) ++ ++#define STATS_TX_TIME_ARRIVE(__Skb__) ++#define STATS_TX_TIME_TO_HIF(__MsduInfo__, __HwTxHeader__) ++#define STATS_TX_PKT_CALLBACK(__Pkt__, __fgIsNeedAck__) ++#define STATS_TX_PKT_DONE_INFO_DISPLAY(__Adapter__, __Event__) ++ ++#define STATS_DRIVER_OWN_RESET() ++#define STATS_DRIVER_OWN_START_RECORD() ++#define STATS_DRIVER_OWN_END_RECORD() ++#define STATS_DRIVER_OWN_STOP() ++#endif /* CFG_SUPPORT_STATISTICS */ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex); ++ ++VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb); ++ ++UINT_64 StatsEnvTimeGet(VOID); ++ ++VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader); ++ ++VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++VOID StatsRxPktInfoDisplay(UINT_8 *pPkt); ++ ++VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo); ++ ++VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf); ++ ++VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet); ++ ++UINT_16 StatsGetCfgTxDone(VOID); ++ ++/* End of stats.h */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h +new file mode 100644 +index 000000000000..50c4b558c2cd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h +@@ -0,0 +1,187 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/swcr.h#1 ++*/ ++ ++/*! \file "swcr.h" ++ \brief ++*/ ++ ++/* ++ * ++ */ ++ ++#ifndef _SWCR_H ++#define _SWCR_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "nic_cmd_event.h" ++ ++#if 0 ++extern SWCR_MAP_ENTRY_T g_arRlmArSwCrMap[]; ++#endif ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define SWCR_VAR(x) ((VOID *)&x) ++#define SWCR_FUNC(x) ((VOID *)x) ++ ++#define SWCR_T_FUNC BIT(7) ++ ++#define SWCR_L_32 3 ++#define SWCR_L_16 2 ++#define SWCR_L_8 1 ++ ++#define SWCR_READ 0 ++#define SWCR_WRITE 1 ++ ++#define SWCR_MAP_NUM(x) (sizeof(x)/sizeof(x[0])) ++ ++#define SWCR_CR_NUM 7 ++ ++#define SWCR_GET_RW_INDEX(action, rw, index) \ ++do { \ ++ index = action & 0x7F; \ ++ rw = action >> 7; \ ++} while (0) ++ ++extern UINT_32 g_au4SwCr[]; /*: 0: command other: data */ ++ ++typedef VOID(*PFN_SWCR_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); ++typedef VOID(*PFN_CMD_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++ ++typedef struct _SWCR_MAP_ENTRY_T { ++ UINT_16 u2Type; ++ PVOID u4Addr; ++} SWCR_MAP_ENTRY_T, *P_SWCR_MAP_ENTRY_T; ++ ++typedef struct _SWCR_MOD_MAP_ENTRY_T { ++ UINT_8 ucMapNum; ++ P_SWCR_MAP_ENTRY_T prSwCrMap; ++} SWCR_MOD_MAP_ENTRY_T, *P_SWCR_MOD_MAP_ENTRY_T; ++ ++typedef enum _ENUM_SWCR_DBG_TYPE_T { ++ SWCR_DBG_TYPE_ALL = 0, ++ SWCR_DBG_TYPE_TXRX, ++ SWCR_DBG_TYPE_RX_RATES, ++ SWCR_DBG_TYPE_PS, ++ SWCR_DBG_TYPE_NUM ++} ENUM_SWCR_DBG_TYPE_T; ++ ++typedef enum _ENUM_SWCR_DBG_ALL_T { ++ SWCR_DBG_ALL_TX_CNT = 0, ++ SWCR_DBG_ALL_TX_BCN_CNT, ++ SWCR_DBG_ALL_TX_FAILED_CNT, ++ SWCR_DBG_ALL_TX_RETRY_CNT, ++ SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT, ++ SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT, ++ SWCR_DBG_ALL_TX_MGNT_DROP_CNT, ++ SWCR_DBG_ALL_TX_ERROR_CNT, ++ ++ SWCR_DBG_ALL_RX_CNT, ++ SWCR_DBG_ALL_RX_DROP_CNT, ++ SWCR_DBG_ALL_RX_DUP_DROP_CNT, ++ SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT, ++ ++ SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT, ++ ++ SWCR_DBG_ALL_RX_FCSERR_CNT, ++ SWCR_DBG_ALL_RX_FIFOFULL_CNT, ++ SWCR_DBG_ALL_RX_PFDROP_CNT, ++ ++ SWCR_DBG_ALL_PWR_PS_POLL_CNT, ++ SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT, ++ SWCR_DBG_ALL_PWR_BCN_IND_CNT, ++ SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT, ++ SWCR_DBG_ALL_PWR_PM_STATE0, ++ SWCR_DBG_ALL_PWR_PM_STATE1, ++ SWCR_DBG_ALL_PWR_CUR_PS_PROF0, ++ SWCR_DBG_ALL_PWR_CUR_PS_PROF1, ++ ++ SWCR_DBG_ALL_AR_STA0_RATE, ++ SWCR_DBG_ALL_AR_STA0_BWGI, ++ SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI, ++ ++ SWCR_DBG_ALL_ROAMING_ENABLE, ++ SWCR_DBG_ALL_ROAMING_ROAM_CNT, ++ SWCR_DBG_ALL_ROAMING_INT_CNT, ++ ++ SWCR_DBG_ALL_BB_RX_MDRDY_CNT, ++ SWCR_DBG_ALL_BB_RX_FCSERR_CNT, ++ SWCR_DBG_ALL_BB_CCK_PD_CNT, ++ SWCR_DBG_ALL_BB_OFDM_PD_CNT, ++ SWCR_DBG_ALL_BB_CCK_SFDERR_CNT, ++ SWCR_DBG_ALL_BB_CCK_SIGERR_CNT, ++ SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT, ++ SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT, ++ ++ SWCR_DBG_ALL_NUM ++} ENUM_SWCR_DBG_ALL_T; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++void testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); ++ ++/* Support Debug */ ++VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl); ++VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); ++ ++/* Debug Support */ ++VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType); ++VOID swCrDebugInit(P_ADAPTER_T prAdapter); ++VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout); ++VOID swCrDebugUninit(P_ADAPTER_T prAdapter); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h +new file mode 100644 +index 000000000000..3b6991131d05 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h +@@ -0,0 +1,262 @@ ++/* ++** Id: include/tdls.h#1 ++*/ ++ ++/*! \file "tdls.h" ++ \brief This file contains the internal used in TDLS modules ++ for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: tdls.h ++ * ++ * 11 18 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ * ++ ** ++ */ ++ ++#ifndef _TDLS_H ++#define _TDLS_H ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define TDLS_CFG_CMD_TEST 1 ++#define TDLS_CFG_HT_SUP 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); ++extern BOOLEAN flgTdlsTestExtCapElm; ++extern UINT8 aucTdlsTestExtCapElm[]; ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++typedef struct _TDLS_LINK_HIS_OTHERS_T { ++ BOOLEAN fgIsHt; /* TRUE: HT device */ ++ ++} TDLS_LINK_HIS_OTHERS_T; ++ ++/* command */ ++typedef enum _TDLS_CMD_ID { ++ TDLS_CMD_TEST_TX_FRAME = 0x00, ++ TDLS_CMD_TEST_RCV_FRAME = 0x01, ++ TDLS_CMD_TEST_PEER_ADD = 0x02, ++ TDLS_CMD_TEST_PEER_UPDATE = 0x03, ++ TDLS_CMD_TEST_DATA_FRAME = 0x04, ++ TDLS_CMD_TEST_RCV_NULL = 0x05, ++ TDLS_CMD_MIB_UPDATE = 0x06, ++ TDLS_CMD_TEST_SKIP_TX_FAIL = 0x07, ++ TDLS_CMD_UAPSD_CONF = 0x08, ++ TDLS_CMD_CH_SW_CONF = 0x09, ++ TDLS_CMD_TEST_SKIP_KEEP_ALIVE = 0x0a, ++ TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT = 0x0b, ++ TDLS_CMD_TEST_TX_TDLS_FRAME = 0x0c, ++ TDLS_CMD_TEST_PROHIBIT_SET_IN_AP = 0x0d, ++ TDLS_CMD_TEST_SCAN_DISABLE = 0x0e, ++ TDLS_CMD_TEST_DATA_FRAME_CONT = 0x0f, ++ TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP = 0x10, ++ TDLS_CMD_SETUP_CONF = 0x11, ++ TDLS_CMD_INFO = 0x12, ++ TDLS_CMD_TEST_DELAY = 0x13, ++ TDLS_CMD_KEY_INFO = 0x14, ++ TDLS_CMD_TEST_PTI_TX_FAIL = 0x15 ++} TDLS_CMD_ID; ++ ++typedef enum _TDLS_EVENT_HOST_ID { ++ TDLS_HOST_EVENT_TEAR_DOWN = 0x00, /* TDLS_EVENT_HOST_SUBID_TEAR_DOWN */ ++ TDLS_HOST_EVENT_TX_DONE, ++ TDLS_HOST_EVENT_FME_STATUS, /* TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME */ ++ TDLS_HOST_EVENT_STATISTICS ++} TDLS_EVENT_HOST_ID; ++ ++typedef enum _TDLS_EVENT_HOST_SUBID_TEAR_DOWN { ++ TDLS_HOST_EVENT_TD_PTI_TIMEOUT = 0x00, ++ TDLS_HOST_EVENT_TD_AGE_TIMEOUT, ++ TDLS_HOST_EVENT_TD_PTI_SEND_FAIL, ++ TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL, ++ TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX, ++ TDLS_HOST_EVENT_TD_NON_STATE3, ++ TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN ++} TDLS_EVENT_HOST_SUBID_TEAR_DOWN; ++ ++typedef enum _TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME { ++ TDLS_HOST_EVENT_SF_BA, ++ TDLS_HOST_EVENT_SF_BA_OK, ++ TDLS_HOST_EVENT_SF_BA_DECLINE, ++ TDLS_HOST_EVENT_SF_BA_PEER, ++ TDLS_HOST_EVENT_SF_BA_RSP_OK, ++ TDLS_HOST_EVENT_SF_BA_RSP_DECLINE ++} TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME; ++ ++/* payload specific type in the LLC/SNAP header */ ++#define TDLS_FRM_PAYLOAD_TYPE 2 ++ ++#define TDLS_FRM_CATEGORY 12 ++ ++typedef enum _TDLS_FRM_ACTION_ID { ++ TDLS_FRM_ACTION_SETUP_REQ = 0x00, ++ TDLS_FRM_ACTION_SETUP_RSP, ++ TDLS_FRM_ACTION_CONFIRM, ++ TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_FRM_ACTION_PTI, ++ TDLS_FRM_ACTION_CHAN_SWITCH_REQ, ++ TDLS_FRM_ACTION_CHAN_SWITCH_RSP, ++ TDLS_FRM_ACTION_PEER_PSM_REQ, ++ TDLS_FRM_ACTION_PEER_PSM_RSP, ++ TDLS_FRM_ACTION_PTI_RSP, /* 0x09 */ ++ TDLS_FRM_ACTION_DISCOVERY_REQ, ++ ++ TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT = 0x30, ++ ++ TDLS_FRM_DATA_TEST_DATA = 0x80 ++} TDLS_FRM_ACTION_ID; ++ ++#define TDLS_FRM_ACTION_DISCOVERY_RESPONSE 14 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* 7.3.2.62 Link Identifier element */ ++#define ELEM_ID_LINK_IDENTIFIER 101 ++#define ELEM_LEN_LINK_IDENTIFIER 18 ++ ++typedef struct _IE_LINK_IDENTIFIER_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aBSSID[6]; ++ UINT_8 aInitiator[6]; ++ UINT_8 aResponder[6]; ++} __KAL_ATTRIB_PACKED__ IE_LINK_IDENTIFIER_T; ++ ++#define TDLS_LINK_IDENTIFIER_IE(__ie__) ((IE_LINK_IDENTIFIER_T *)(__ie__)) ++ ++/* test command use */ ++typedef struct _PARAM_CUSTOM_TDLS_CMD_STRUCT_T { ++ ++ UINT_8 ucFmeType; /* TDLS_FRM_ACTION_ID */ ++ ++ UINT_8 ucToken; ++ UINT_16 u2Cap; ++ ++ /* bit0: TDLS, bit1: Peer U-APSD Buffer, bit2: Channel Switching */ ++#define TDLS_EX_CAP_PEER_UAPSD BIT(0) ++#define TDLS_EX_CAP_CHAN_SWITCH BIT(1) ++#define TDLS_EX_CAP_TDLS BIT(2) ++ UINT_8 ucExCap; ++ ++ UINT_8 arSupRate[4]; ++ UINT_8 arSupChan[4]; ++ ++ UINT_32 u4Timeout; ++ ++#define TDLS_FME_MAC_ADDR_LEN 6 ++ UINT_8 arRspAddr[TDLS_FME_MAC_ADDR_LEN]; ++ UINT_8 arBssid[TDLS_FME_MAC_ADDR_LEN]; ++ ++/* ++ Linux Kernel-3.10 ++ struct station_parameters { ++ const u8 *supported_rates; ++ struct net_device *vlan; ++ u32 sta_flags_mask, sta_flags_set; ++ u32 sta_modify_mask; ++ int listen_interval; ++ u16 aid; ++ u8 supported_rates_len; ++ u8 plink_action; ++ u8 plink_state; ++ const struct ieee80211_ht_cap *ht_capa; ++ const struct ieee80211_vht_cap *vht_capa; ++ u8 uapsd_queues; ++ u8 max_sp; ++ enum nl80211_mesh_power_mode local_pm; ++ u16 capability; ++ const u8 *ext_capab; ++ u8 ext_capab_len; ++ }; ++*/ ++ struct ieee80211_ht_cap rHtCapa; ++ struct ieee80211_vht_cap rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ ++ struct station_parameters rPeerInfo; ++ ++} PARAM_CUSTOM_TDLS_CMD_STRUCT_T; ++ ++typedef struct _TDLS_MGMT_TX_INFO { ++ UINT8 aucPeer[6]; ++ UINT8 ucActionCode; ++ UINT8 ucDialogToken; ++ UINT16 u2StatusCode; ++ UINT32 u4SecBufLen; ++ UINT8 aucSecBuf[1000]; ++} TDLS_MGMT_TX_INFO; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* check any TDLS link */ ++#define TDLS_IS_NO_LINK_GOING(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt == 0) ++ ++/* increase TDLS link count */ ++#define TDLS_LINK_INCREASE(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt++) ++ ++/* decrease TDLS link count */ ++#define TDLS_LINK_DECREASE(__GlueInfo__) \ ++do { \ ++ if ((__GlueInfo__)->rTdlsLink.cLinkCnt > 0) \ ++ (__GlueInfo__)->rTdlsLink.cLinkCnt--; \ ++} while (0) ++ ++/* get TDLS link count */ ++#define TDLS_LINK_COUNT(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt) ++ ++/* reset TDLS link count */ ++#define TDLS_LINK_COUNT_RESET(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt = 0) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* Note: these functions are used only in tdls module, not other modules */ ++UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt); ++ ++TDLS_STATUS ++TdlsDataFrameSend(ADAPTER_T *prAdapter, ++ STA_RECORD_T *prStaRec, ++ UINT_8 *pPeerMac, ++ UINT_8 ucActionCode, ++ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#endif /* _TDLS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h +new file mode 100644 +index 000000000000..12c9359f2e8f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h +@@ -0,0 +1,104 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wapi.h#1 ++*/ ++ ++/*! \file wapi.h ++ \brief The wapi related define, macro and structure are described here. ++*/ ++ ++/* ++** Log: wapi.h ++ * ++ * 07 20 2010 wh.su ++ * ++ * . ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the wapi function name and adding the generate wapi ie function ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some wapi structure define ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** \main\maintrunk.MT5921\1 2009-10-09 17:06:29 GMT mtk01088 ++** ++*/ ++ ++#ifndef _WAPI_H ++#define _WAPI_H ++ ++#if CFG_SUPPORT_WAPI ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define WAPI_CIPHER_SUITE_WPI 0x01721400 /* WPI_SMS4 */ ++#define WAPI_AKM_SUITE_802_1X 0x01721400 /* WAI */ ++#define WAPI_AKM_SUITE_PSK 0x02721400 /* WAI_PSK */ ++ ++#define ELEM_ID_WAPI 68 /* WAPI IE */ ++ ++#define WAPI_IE(fp) ((P_WAPI_INFO_ELEM_T) fp) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo); ++ ++BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); ++ ++/* BOOLEAN */ ++/* wapiUpdateTxKeyIdx ( */ ++/* IN P_STA_RECORD_T prStaRec, */ ++/* IN UINT_8 ucWlanIdx */ ++/* ); */ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif ++#endif /* _WAPI_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h +new file mode 100644 +index 000000000000..5dc969f1cc05 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h +@@ -0,0 +1,87 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wlan_typedef.h#1 ++*/ ++ ++/*! \file wlan_typedef.h ++ \brief Declaration of data type and return values of internal protocol stack. ++ ++ In this file we declare the data type and return values which will be exported ++ to all MGMT Protocol Stack. ++*/ ++ ++/* ++** Log: wlan_typedef.h ++*/ ++ ++#ifndef _WLAN_TYPEDEF_H ++#define _WLAN_TYPEDEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Type definition for BSS_INFO_T structure, to describe the attributes used in a ++ * common BSS. ++ */ ++typedef struct _BSS_INFO_T BSS_INFO_T, *P_BSS_INFO_T; ++ ++typedef BSS_INFO_T AIS_BSS_INFO_T, *P_AIS_BSS_INFO_T; ++typedef BSS_INFO_T P2P_BSS_INFO_T, *P_P2P_BSS_INFO_T; ++typedef BSS_INFO_T BOW_BSS_INFO_T, *P_BOW_BSS_INFO_T; ++ ++typedef struct _AIS_SPECIFIC_BSS_INFO_T AIS_SPECIFIC_BSS_INFO_T, *P_AIS_SPECIFIC_BSS_INFO_T; ++typedef struct _P2P_SPECIFIC_BSS_INFO_T P2P_SPECIFIC_BSS_INFO_T, *P_P2P_SPECIFIC_BSS_INFO_T; ++typedef struct _BOW_SPECIFIC_BSS_INFO_T BOW_SPECIFIC_BSS_INFO_T, *P_BOW_SPECIFIC_BSS_INFO_T; ++/* CFG_SUPPORT_WFD */ ++typedef struct _WFD_CFG_SETTINGS_T WFD_CFG_SETTINGS_T, *P_WFD_CFG_SETTINGS_T; ++ ++typedef struct _WFD_DBG_CFG_SETTINGS_T WFD_DBG_CFG_SETTINGS_T, *P_WFD_DBG_CFG_SETTINGS_T; ++ ++/* BSS related structures */ ++/* Type definition for BSS_DESC_T structure, to describe parameter sets of a particular BSS */ ++typedef struct _BSS_DESC_T BSS_DESC_T, *P_BSS_DESC_T, **PP_BSS_DESC_T; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++typedef struct _HS20_INFO_T HS20_INFO_T, *P_HS20_INFO_T; ++#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _WLAN_TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h +new file mode 100644 +index 000000000000..09bc0b5d5151 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h +@@ -0,0 +1,95 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/mgmt/wnm.h#1 ++*/ ++ ++/*! \file wnm.h ++ \brief This file contains the IEEE 802.11 family related 802.11v network management ++ for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wnm.h ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * ++*/ ++ ++#ifndef _WNM_H ++#define _WNM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _TIMINGMSMT_PARAM_T { ++ BOOLEAN fgInitiator; ++ UINT_8 ucTrigger; ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ ++ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ ++ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ ++} TIMINGMSMT_PARAM_T, *P_TIMINGMSMT_PARAM_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++WLAN_STATUS ++wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID ++wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA); ++ ++#define WNM_UNIT_TEST 1 ++ ++#if WNM_UNIT_TEST ++VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WNM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h +new file mode 100644 +index 000000000000..d34f2c9c36a8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h +@@ -0,0 +1,1506 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/adapter.h#3 ++*/ ++ ++/*! \file adapter.h ++ \brief Definition of internal data structure for driver manipulation. ++ ++ In this file we define the internal data structure - ADAPTER_T which stands ++ for MiniPort ADAPTER(From Windows point of view) or stands for Network ADAPTER. ++*/ ++ ++/* ++** Log: adapter.h ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have ++** connected to AP previously,one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration ++ * with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration ++ * corresponding to network type. ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Resolve inorder issue under AP mode. ++ * ++ * data frame may TX before assoc response frame. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 10 21 2011 eddie.chen ++ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout ++ * Add switch to ignore the STA aging timeout. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Remove ERP member in adapter structure ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * Action frame callback for GO Device Discoverability Req. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support for WiFi Direct Network. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically ++ * continuous memory shortage after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce ++ * physically continuous memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 10 2011 yuche.tsai ++ * [WCXRP00000533] [Volunteer Patch][MT6620][Driver] Provide a P2P function API for Legacy WiFi to query AP mode. ++ * Provide an API for Legacy WiFi to query the operation mode.. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * Add code to send beacon and probe response WSC IE at Auto GO. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as ++ * initial RSSI right after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid ++ * using a uninitialized MAC-RX RCPI. ++ * ++ * 02 21 2011 terry.wu ++ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P ++ * Clean P2P scan list while removing P2P. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 16 2011 cm.chang ++ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism ++ * . ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add RX deauthentication & disassociation process under Hot-Spot mode. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module ++ * with structure miss-align pointer issue ++ * always pre-allio WAPI related structure for align p2p module. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to ++ * target station for AAA module. ++ * Provide disconnect function for AAA module. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting ++ * Support CTIA power mode setting. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Support current measure mode, assigned by registry (XP only). ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add WMM parameter for broadcast. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add CWMin CWMax for AP to generate IE. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a common IE buffer in P2P INFO structure. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * restore configuration as before. ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add an intend mode for BSS info. ++ * It is used to let P2P BSS Info to know which OP Mode it is going to become. ++ * ++ * 08 04 2010 george.huang ++ * NULL ++ * handle change PS mode OID/ CMD ++ * ++ * 08 02 2010 cp.wu ++ * NULL ++ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Remove BSS info which is redonedent in Wifi Var.. ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P FSM Info in adapter. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P related field, additional include p2p_fsm.h if p2p is enabled. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change OID behavior to meet WHQL requirement. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement Wakeup-on-LAN except firmware integration part ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * reserve field of privacy filter and RTS threshold setting. ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * are done in adapter layer. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * * * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move ucCmdSeqNum as instance variable ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * 4. correct some HAL implementation ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * and result is retrieved by get ATInfo instead ++ * * * 2) add 4 counter for recording aggregation statistics ++ * ++ * 12 28 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate redundant variables for connection_state ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-16 18:02:03 GMT mtk02752 ++** add external reference to avoid compilation error ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:40:26 GMT mtk02752 ++** eliminate unused member ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-08 17:36:08 GMT mtk02752 ++** add RF test data members into P_ADAPTER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:45 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-28 10:29:57 GMT mtk01461 ++** Add read WTSR for SDIO_STATUS_ENHANCE mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:37:35 GMT mtk01461 ++** Add prPendingCmdInfoOfOID for temporarily saving the CMD_INFO_T before en-queue to rCmdQueue ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:57:51 GMT mtk01461 ++** Add MGMT Buffer Info ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:34:12 GMT mtk01461 ++** Add SW pre test CFG_HIF_LOOPBACK_PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:41:48 GMT mtk01461 ++** Add fgIsWmmAssoc flag for TC assignment ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:51 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:51:52 GMT mtk01426 ++** Add #if CFG_SDIO_RX_ENHANCE related data structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:17 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _ADAPTER_H ++#define _ADAPTER_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++#include "hs20.h" ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _ENHANCE_MODE_DATA_STRUCT_T SDIO_CTRL_T, *P_SDIO_CTRL_T; ++ ++typedef struct _WLAN_INFO_T { ++ PARAM_BSSID_EX_T rCurrBssId; ++ ++ /* Scan Result */ ++ PARAM_BSSID_EX_T arScanResult[CFG_MAX_NUM_BSS_LIST]; ++ PUINT_8 apucScanResultIEs[CFG_MAX_NUM_BSS_LIST]; ++ UINT_32 u4ScanResultNum; ++ ++ /* IE pool for Scanning Result */ ++ UINT_8 aucScanIEBuf[CFG_MAX_COMMON_IE_BUF_LEN]; ++ UINT_32 u4ScanIEBufferUsage; ++ ++ OS_SYSTIME u4SysTime; ++ ++ /* connection parameter (for Ad-Hoc) */ ++ UINT_16 u2BeaconPeriod; ++ UINT_16 u2AtimWindow; ++ ++ PARAM_RATES eDesiredRates; ++ CMD_LINK_ATTRIB eLinkAttr; ++/* CMD_PS_PROFILE_T ePowerSaveMode; */ ++ CMD_PS_PROFILE_T arPowerSaveMode[NETWORK_TYPE_INDEX_NUM]; ++ ++ /* trigger parameter */ ++ ENUM_RSSI_TRIGGER_TYPE eRssiTriggerType; ++ PARAM_RSSI rRssiTriggerValue; ++ ++ /* Privacy Filter */ ++ ENUM_PARAM_PRIVACY_FILTER_T ePrivacyFilter; ++ ++ /* RTS Threshold */ ++ PARAM_RTS_THRESHOLD eRtsThreshold; ++ ++ /* Network Type */ ++ UINT_8 ucNetworkType; ++ ++ /* Network Type In Use */ ++ UINT_8 ucNetworkTypeInUse; ++ ++} WLAN_INFO_T, *P_WLAN_INFO_T; ++ ++/* Session for CONNECTION SETTINGS */ ++typedef struct _CONNECTION_SETTINGS_T { ++ ++ UINT_8 aucMacAddress[MAC_ADDR_LEN]; ++ ++ UINT_8 ucDelayTimeOfDisconnectEvent; ++ ++ BOOLEAN fgIsConnByBssidIssued; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ ++ BOOLEAN fgIsConnReqIssued; ++ BOOLEAN fgIsDisconnectedByNonRequest; ++ ++ UINT_8 ucSSIDLen; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ ++ ENUM_PARAM_OP_MODE_T eOPMode; ++ ++ ENUM_PARAM_CONNECTION_POLICY_T eConnectionPolicy; ++ ++ ENUM_PARAM_AD_HOC_MODE_T eAdHocMode; ++ ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ++ BOOLEAN fgIsScanReqIssued; ++ ++ /* MIB attributes */ ++ UINT_16 u2BeaconPeriod; ++ ++ UINT_16 u2RTSThreshold; /* User desired setting */ ++ ++ UINT_16 u2DesiredNonHTRateSet; /* User desired setting */ ++ ++ UINT_8 ucAdHocChannelNum; /* For AdHoc */ ++ ++ ENUM_BAND_T eAdHocBand; /* For AdHoc */ ++ ++ UINT_32 u4FreqInKHz; /* Center frequency */ ++ ++ /* ATIM windows using for IBSS power saving function */ ++ UINT_16 u2AtimWindow; ++ ++ /* Features */ ++ BOOLEAN fgIsEnableRoaming; ++ ++ BOOLEAN fgIsAdHocQoSEnable; ++ ++ ENUM_PARAM_PHY_CONFIG_T eDesiredPhyConfig; ++ ++ /* Used for AP mode for desired channel and bandwidth */ ++ UINT_16 u2CountryCode; ++ UINT_16 u2CountryCodeBakup; ++ UINT_8 uc2G4BandwidthMode; /* 20/40M or 20M only */ ++ UINT_8 uc5GBandwidthMode; /* 20/40M or 20M only */ ++ ++ BOOLEAN fgTxShortGIDisabled; ++ BOOLEAN fgRxShortGIDisabled; ++ ++#if CFG_SUPPORT_802_11D ++ BOOLEAN fgMultiDomainCapabilityEnabled; ++#endif /* CFG_SUPPORT_802_11D */ ++ ++#if 1 /* CFG_SUPPORT_WAPI */ ++ BOOLEAN fgWapiMode; ++ UINT_32 u4WapiSelectedGroupCipher; ++ UINT_32 u4WapiSelectedPairwiseCipher; ++ UINT_32 u4WapiSelectedAKMSuite; ++#endif ++ ++ /* CR1486, CR1640 */ ++ /* for WPS, disable the privacy check for AP selection policy */ ++ BOOLEAN fgPrivacyCheckDisable; ++ ++ /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ ++ UINT_8 bmfgApsdEnAc; ++ ++ /* for RSN info store, when upper layer set rsn info */ ++ RSN_INFO_T rRsnInfo; ++ ++} CONNECTION_SETTINGS_T, *P_CONNECTION_SETTINGS_T; ++ ++struct _BSS_INFO_T { ++ ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ ++ ENUM_PARAM_MEDIA_STATE_T eConnectionStateIndicated; /* The Media State that report to HOST */ ++ ++ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ ++#if CFG_ENABLE_WIFI_DIRECT ++ ENUM_OP_MODE_T eIntendOPMode; ++#endif ++ ++ BOOLEAN fgIsNetActive; /* TRUE if this network has been activated */ ++ ++ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ ++ ++ UINT_8 ucReasonOfDisconnect; /* Used by media state indication */ ++ ++ UINT_8 ucSSIDLen; /* Length of SSID */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ENUM_HIDDEN_SSID_TYPE_T eHiddenSsidType; /* For Hidden SSID usage. */ ++#endif ++ ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID used in this BSS */ ++ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* The BSSID of the associated BSS */ ++ ++ UINT_8 aucOwnMacAddr[MAC_ADDR_LEN]; /* Owned MAC Address used in this BSS */ ++ ++ P_STA_RECORD_T prStaRecOfAP; /* For Infra Mode, and valid only if ++ * eConnectionState == MEDIA_STATE_CONNECTED ++ */ ++ LINK_T rStaRecOfClientList; /* For IBSS/AP Mode, all known STAs in current BSS */ ++ ++ UINT_16 u2CapInfo; /* Change Detection */ ++ ++ UINT_16 u2BeaconInterval; /* The Beacon Interval of this BSS */ ++ ++ UINT_16 u2ATIMWindow; /* For IBSS Mode */ ++ ++ UINT_16 u2AssocId; /* For Infra Mode, it is the Assoc ID assigned by AP. ++ */ ++ ++ UINT_8 ucDTIMPeriod; /* For Infra/AP Mode */ ++ ++ UINT_8 ucDTIMCount; /* For AP Mode, it is the DTIM value we should carried in ++ * the Beacon of next TBTT. ++ */ ++ ++ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer ++ * (This is deduced from received BSS_DESC_T) ++ */ ++ ++ UINT_8 ucNonHTBasicPhyType; /* The Basic PHY Type Index, used to setup Phy Capability */ ++ ++ UINT_8 ucConfigAdHocAPMode; /* The configuration of AdHoc/AP Mode. e.g. 11g or 11b */ ++ ++ UINT_8 ucBeaconTimeoutCount; /* For Infra/AP Mode, it is a threshold of Beacon Lost Count to ++ confirm connection was lost */ ++ ++ BOOLEAN fgHoldSameBssidForIBSS; /* For IBSS Mode, to keep use same BSSID to extend the life cycle of an IBSS */ ++ ++ BOOLEAN fgIsBeaconActivated; /* For AP/IBSS Mode, it is used to indicate that Beacon is sending */ ++ ++ P_MSDU_INFO_T prBeacon; /* For AP/IBSS Mode - Beacon Frame */ ++ ++ BOOLEAN fgIsIBSSMaster; /* For IBSS Mode - To indicate that we can reply ProbeResp Frame. ++ In current TBTT interval */ ++ ++ BOOLEAN fgIsShortPreambleAllowed; /* From Capability Info. of AssocResp Frame ++ AND of Beacon/ProbeResp Frame */ ++ BOOLEAN fgUseShortPreamble; /* Short Preamble is enabled in current BSS. */ ++ BOOLEAN fgUseShortSlotTime; /* Short Slot Time is enabled in current BSS. */ ++ ++ UINT_16 u2OperationalRateSet; /* Operational Rate Set of current BSS */ ++ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of current BSS */ ++ ++ UINT_8 ucAllSupportedRatesLen; /* Used for composing Beacon Frame in AdHoc or AP Mode */ ++ UINT_8 aucAllSupportedRates[RATE_NUM]; ++ ++ UINT_8 ucAssocClientCnt; /* TODO(Kevin): Number of associated clients */ ++ ++ BOOLEAN fgIsProtection; ++ BOOLEAN fgIsQBSS; /* fgIsWmmBSS; *//* For Infra/AP/IBSS Mode, it is used to indicate if we support WMM in ++ * current BSS. */ ++ BOOLEAN fgIsNetAbsent; /* TRUE: BSS is absent, FALSE: BSS is present */ ++ ++ UINT_32 u4RsnSelectedGroupCipher; ++ UINT_32 u4RsnSelectedPairwiseCipher; ++ UINT_32 u4RsnSelectedAKMSuite; ++ UINT_16 u2RsnSelectedCapInfo; ++ ++ /*------------------------------------------------------------------------*/ ++ /* Power Management related information */ ++ /*------------------------------------------------------------------------*/ ++ PM_PROFILE_SETUP_INFO_T rPmProfSetupInfo; ++ ++ /*------------------------------------------------------------------------*/ ++ /* WMM/QoS related information */ ++ /*------------------------------------------------------------------------*/ ++ UINT_8 ucWmmParamSetCount; /* Used to detect the change of EDCA parameters. For AP mode, ++ the value is used in WMM IE */ ++ ++ AC_QUE_PARMS_T arACQueParms[WMM_AC_INDEX_NUM]; ++ ++ UINT_8 aucCWminLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWminLog2 */ ++ UINT_8 aucCWmaxLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWmaxLog2 */ ++ AC_QUE_PARMS_T arACQueParmsForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the value */ ++ ++ /*------------------------------------------------------------------------*/ ++ /* 802.11n HT operation IE when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) */ ++ /* is true. They have the same definition with fields of */ ++ /* information element (CM) */ ++ /*------------------------------------------------------------------------*/ ++ ENUM_BAND_T eBand; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucHtOpInfo1; ++ UINT_16 u2HtOpInfo2; ++ UINT_16 u2HtOpInfo3; ++ ++ /*------------------------------------------------------------------------*/ ++ /* Required protection modes (CM) */ ++ /*------------------------------------------------------------------------*/ ++ BOOLEAN fgErpProtectMode; ++ ENUM_HT_PROTECT_MODE_T eHtProtectMode; ++ ENUM_GF_MODE_T eGfOperationMode; ++ ENUM_RIFS_MODE_T eRifsOperationMode; ++ ++ BOOLEAN fgObssErpProtectMode; /* GO only */ ++ ENUM_HT_PROTECT_MODE_T eObssHtProtectMode; /* GO only */ ++ ENUM_GF_MODE_T eObssGfOperationMode; /* GO only */ ++ BOOLEAN fgObssRifsOperationMode; /* GO only */ ++ ++ /*------------------------------------------------------------------------*/ ++ /* OBSS to decide if 20/40M bandwidth is permitted. */ ++ /* The first member indicates the following channel list length. */ ++ /*------------------------------------------------------------------------*/ ++ BOOLEAN fgAssoc40mBwAllowed; ++ BOOLEAN fg40mBwAllowed; ++ ENUM_CHNL_EXT_T eBssSCO; /* Real setting for HW ++ * 20/40M AP mode will always set 40M, ++ * but its OP IE can be changed. ++ */ ++ UINT_8 auc2G_20mReqChnlList[CHNL_LIST_SZ_2G + 1]; ++ UINT_8 auc2G_NonHtChnlList[CHNL_LIST_SZ_2G + 1]; ++ UINT_8 auc2G_PriChnlList[CHNL_LIST_SZ_2G + 1]; ++ UINT_8 auc2G_SecChnlList[CHNL_LIST_SZ_2G + 1]; ++ ++ UINT_8 auc5G_20mReqChnlList[CHNL_LIST_SZ_5G + 1]; ++ UINT_8 auc5G_NonHtChnlList[CHNL_LIST_SZ_5G + 1]; ++ UINT_8 auc5G_PriChnlList[CHNL_LIST_SZ_5G + 1]; ++ UINT_8 auc5G_SecChnlList[CHNL_LIST_SZ_5G + 1]; ++ ++ TIMER_T rObssScanTimer; ++ UINT_16 u2ObssScanInterval; /* in unit of sec */ ++ ++ BOOLEAN fgObssActionForcedTo20M; /* GO only */ ++ BOOLEAN fgObssBeaconForcedTo20M; /* GO only */ ++ ++ /*------------------------------------------------------------------------*/ ++ /* HW Related Fields (Kevin) */ ++ /*------------------------------------------------------------------------*/ ++ UINT_8 ucHwDefaultFixedRateCode; /* The default rate code copied to MAC TX Desc */ ++ UINT_16 u2HwLPWakeupGuardTimeUsec; ++ ++ UINT_8 ucBssFreeQuota; /* The value is updated from FW */ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ P_IPV4_NETWORK_ADDRESS_LIST prIpV4NetAddrList; ++#endif ++ UINT_16 u2DeauthReason; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ ++ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ ++#endif /* CFG_SUPPORT_TDLS */ ++}; ++ ++struct _AIS_SPECIFIC_BSS_INFO_T { ++ UINT_8 ucRoamingAuthTypes; /* This value indicate the roaming type used in AIS_JOIN */ ++ ++ BOOLEAN fgIsIBSSActive; ++ ++ /*! \brief Global flag to let arbiter stay at standby and not connect to any network */ ++ BOOLEAN fgCounterMeasure; ++ UINT_8 ucWEPDefaultKeyID; ++ BOOLEAN fgTransmitKeyExist; /* Legacy wep Transmit key exist or not */ ++ ++ /* While Do CounterMeasure procedure, check the EAPoL Error report have send out */ ++ BOOLEAN fgCheckEAPoLTxDone; ++ ++ UINT_32 u4RsnaLastMICFailTime; ++ ++ /* Stored the current bss wpa rsn cap filed, used for roaming policy */ ++ /* UINT_16 u2RsnCap; */ ++ TIMER_T rPreauthenticationTimer; ++ ++ /* By the flow chart of 802.11i, ++ wait 60 sec before associating to same AP ++ or roaming to a new AP ++ or sending data in IBSS, ++ keep a timer for handle the 60 sec counterMeasure */ ++ TIMER_T rRsnaBlockTrafficTimer; ++ TIMER_T rRsnaEAPoLReportTimeoutTimer; ++ ++ /* For Keep the Tx/Rx Mic key for TKIP SW Calculate Mic */ ++ /* This is only one for AIS/AP */ ++ UINT_8 aucTxMicKey[8]; ++ UINT_8 aucRxMicKey[8]; ++ ++ /* Buffer for WPA2 PMKID */ ++ /* The PMKID cache lifetime is expire by media_disconnect_indication */ ++ UINT_32 u4PmkidCandicateCount; ++ PMKID_CANDICATE_T arPmkidCandicate[CFG_MAX_PMKID_CACHE]; ++ UINT_32 u4PmkidCacheCount; ++ PMKID_ENTRY_T arPmkidCache[CFG_MAX_PMKID_CACHE]; ++ BOOLEAN fgIndicatePMKID; ++#if CFG_SUPPORT_802_11W ++ BOOLEAN fgMgmtProtection; ++ UINT_32 u4SaQueryStart; ++ UINT_32 u4SaQueryCount; ++ UINT_8 ucSaQueryTimedOut; ++ PUINT_8 pucSaQueryTransId; ++ TIMER_T rSaQueryTimer; ++ BOOLEAN fgBipKeyInstalled; ++#endif ++}; ++ ++struct _BOW_SPECIFIC_BSS_INFO_T { ++ UINT_16 u2Reserved; /* Reserved for Data Type Check */ ++}; ++ ++#if CFG_SLT_SUPPORT ++typedef struct _SLT_INFO_T { ++ ++ P_BSS_DESC_T prPseudoBssDesc; ++ UINT_16 u2SiteID; ++ UINT_8 ucChannel2G4; ++ UINT_8 ucChannel5G; ++ BOOLEAN fgIsDUT; ++ UINT_32 u4BeaconReceiveCnt; ++ /* ///////Deprecated///////// */ ++ P_STA_RECORD_T prPseudoStaRec; ++} SLT_INFO_T, *P_SLT_INFO_T; ++#endif ++ ++/* Major member variables for WiFi FW operation. ++ Variables within this region will be ready for access after WIFI function is enabled. ++*/ ++typedef struct _WIFI_VAR_T { ++ BOOLEAN fgIsRadioOff; ++ ++ BOOLEAN fgIsEnterD3ReqIssued; ++ ++ BOOLEAN fgDebugCmdResp; ++ ++ CONNECTION_SETTINGS_T rConnSettings; ++ ++ SCAN_INFO_T rScanInfo; ++ ++#if CFG_SUPPORT_ROAMING ++ ROAMING_INFO_T rRoamingInfo; ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ AIS_FSM_INFO_T rAisFsmInfo; ++ ++ ENUM_PWR_STATE_T aePwrState[NETWORK_TYPE_INDEX_NUM]; ++ ++ BSS_INFO_T arBssInfo[NETWORK_TYPE_INDEX_NUM]; ++ ++ AIS_SPECIFIC_BSS_INFO_T rAisSpecificBssInfo; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings; ++ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo; ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ BOW_SPECIFIC_BSS_INFO_T rBowSpecificBssInfo; ++ BOW_FSM_INFO_T rBowFsmInfo; ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ DEAUTH_INFO_T arDeauthInfo[MAX_DEAUTH_INFO_COUNT]; ++ ++ /* Current Wi-Fi Settings and Flags */ ++ UINT_8 aucPermanentAddress[MAC_ADDR_LEN]; ++ UINT_8 aucMacAddress[MAC_ADDR_LEN]; ++ UINT_8 aucDeviceAddress[MAC_ADDR_LEN]; ++ UINT_8 aucInterfaceAddress[MAC_ADDR_LEN]; ++ ++ UINT_8 ucAvailablePhyTypeSet; ++ ++ ENUM_PHY_TYPE_INDEX_T eNonHTBasicPhyType2G4; /* Basic Phy Type used by SCN according ++ * to the set of Available PHY Types ++ */ ++ ++ ENUM_PARAM_PREAMBLE_TYPE_T ePreambleType; ++ ENUM_REGISTRY_FIXED_RATE_T eRateSetting; ++ ++ BOOLEAN fgIsShortSlotTimeOptionEnable; ++ /* User desired setting, but will honor the capability of AP */ ++ ++ BOOLEAN fgEnableJoinToHiddenSSID; ++ BOOLEAN fgSupportWZCDisassociation; ++ ++ BOOLEAN fgSupportQoS; ++ BOOLEAN fgSupportAmpduTx; ++ BOOLEAN fgSupportAmpduRx; ++ BOOLEAN fgSupportTspec; ++ BOOLEAN fgSupportUAPSD; ++ BOOLEAN fgSupportULPSMP; ++ UINT_8 u8SupportRxSgi20; /* 0: default 1: enable 2:disble */ ++ UINT_8 u8SupportRxSgi40; ++ UINT_8 u8SupportRxGf; ++ UINT_8 u8SupportRxSTBC; ++#if CFG_SUPPORT_CFG_FILE ++ UINT_8 ucApWpsMode; ++ UINT_8 ucCert11nMode; ++#endif ++#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT ++ UINT_8 ucCeFccTxPwrLimit; ++ UINT_8 ucCeFccTxPwrLimitCck; ++ UINT_8 ucCeFccTxPwrLimitOfdmHt20; ++ UINT_8 ucCeFccTxPwrLimitHt40; ++#endif ++ ++#if CFG_SLT_SUPPORT ++ SLT_INFO_T rSltInfo; ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ HS20_INFO_T rHS20Info; ++#endif ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ PARAM_GET_CHN_LOAD rChnLoadInfo; ++#endif ++ ++} WIFI_VAR_T, *P_WIFI_VAR_T; /* end of _WIFI_VAR_T */ ++ ++/* cnm_timer module */ ++typedef struct { ++ LINK_T rLinkHead; ++ OS_SYSTIME rNextExpiredSysTime; ++ KAL_WAKE_LOCK_T rWakeLock; ++ BOOLEAN fgWakeLocked; ++} ROOT_TIMER, *P_ROOT_TIMER; ++ ++/* FW/DRV/NVRAM version information */ ++typedef struct { ++ ++ /* NVRAM or Registry */ ++ UINT_16 u2Part1CfgOwnVersion; ++ UINT_16 u2Part1CfgPeerVersion; ++ UINT_16 u2Part2CfgOwnVersion; ++ UINT_16 u2Part2CfgPeerVersion; ++ ++ /* Firmware */ ++ UINT_16 u2FwProductID; ++ UINT_16 u2FwOwnVersion; ++ UINT_16 u2FwPeerVersion; ++ ++} WIFI_VER_INFO_T, *P_WIFI_VER_INFO_T; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/* ++* p2p function pointer structure ++*/ ++ ++typedef struct _P2P_FUNCTION_LINKER { ++ P2P_REMOVE prP2pRemove; ++/* NIC_P2P_MEDIA_STATE_CHANGE prNicP2pMediaStateChange; */ ++/* SCAN_UPDATE_P2P_DEVICE_DESC prScanUpdateP2pDeviceDesc; */ ++/* P2P_FSM_RUN_EVENT_RX_PROBE_RESPONSE_FRAME prP2pFsmRunEventRxProbeResponseFrame; */ ++ P2P_GENERATE_P2P_IE prP2pGenerateWSC_IEForBeacon; ++/* P2P_CALCULATE_WSC_IE_LEN_FOR_PROBE_RSP prP2pCalculateWSC_IELenForProbeRsp; */ ++/* P2P_GENERATE_WSC_IE_FOR_PROBE_RSP prP2pGenerateWSC_IEForProbeRsp; */ ++/* SCAN_REMOVE_P2P_BSS_DESC prScanRemoveP2pBssDesc; */ ++/* P2P_HANDLE_SEC_CHECK_RSP prP2pHandleSecCheckRsp; */ ++ P2P_NET_REGISTER prP2pNetRegister; ++ P2P_NET_UNREGISTER prP2pNetUnregister; ++ P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocReq; /* All IEs generated from supplicant. */ ++ P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocReq; /* All IEs generated from supplicant. */ ++} P2P_FUNCTION_LINKER, *P_P2P_FUNCTION_LINKER; ++ ++#endif ++ ++/* ++ *State Machine: ++ *-->STOP: Turn on/off WiFi ++ *-->DISABLE: Screen was off (wlanHandleSystemSuspend) ++ *-->ENABLE: Screen was on (wlanHandleSystemResume) ++ *----->clear DISABLE ++ *-->RUNNING: Screen was on && Tx/Rx was ongoing (wlanHardStartXmit/kalRxIndicatePkts) ++*/ ++struct GL_PER_MON_T { ++ TIMER_T rPerfMonTimer; ++ ULONG ulPerfMonFlag; ++ ULONG ulLastTxBytes; ++ ULONG ulLastRxBytes; ++ ULONG ulP2PLastTxBytes; ++ ULONG ulP2PLastRxBytes; ++ /*in bps*/ ++ ULONG ulThroughput; ++ /*in ms*/ ++ UINT32 u4UpdatePeriod; ++ UINT32 u4TarPerfLevel; ++ UINT32 u4CurrPerfLevel; ++}; ++ ++/* ++ * Major ADAPTER structure ++ * Major data structure for driver operation ++ */ ++struct _ADAPTER_T { ++ UINT_8 ucRevID; ++ ++ UINT_16 u2NicOpChnlNum; ++ ++ BOOLEAN fgIsEnableWMM; ++ BOOLEAN fgIsWmmAssoc; /* This flag is used to indicate that WMM is enable in current BSS */ ++ ++ UINT_32 u4OsPacketFilter; /* packet filter used by OS */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ UINT_32 u4CSUMFlags; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ ENUM_BAND_T aePreferBand[NETWORK_TYPE_INDEX_NUM]; ++ ++ /* ADAPTER flags */ ++ UINT_32 u4Flags; ++ UINT_32 u4HwFlags; ++ ++ BOOLEAN fgIsRadioOff; ++ ++ BOOLEAN fgIsEnterD3ReqIssued; ++ ++ UINT_8 aucMacAddress[MAC_ADDR_LEN]; ++ ++ ENUM_PHY_TYPE_INDEX_T eCurrentPhyType; /* Current selection basing on the set of Available PHY Types */ ++ ++#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG ++ UINT_32 u4CoalescingBufCachedSize; ++ PUINT_8 pucCoalescingBufCached; ++#endif /* CFG_COALESCING_BUFFER_SIZE */ ++ ++ /* Buffer for CMD_INFO_T, Mgt packet and mailbox message */ ++ BUF_INFO_T rMgtBufInfo; ++ BUF_INFO_T rMsgBufInfo; ++ PUINT_8 pucMgtBufCached; ++ UINT_32 u4MgtBufCachedSize; ++ UINT_8 aucMsgBuf[MSG_BUFFER_SIZE]; ++#if CFG_DBG_MGT_BUF ++ UINT_32 u4MemAllocDynamicCount; /* Debug only */ ++ UINT_32 u4MemFreeDynamicCount; /* Debug only */ ++#endif ++ ++ STA_RECORD_T arStaRec[CFG_STA_REC_NUM]; ++ ++ /* Element for TX PATH */ ++ TX_CTRL_T rTxCtrl; ++ QUE_T rFreeCmdList; ++ CMD_INFO_T arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM]; ++ ++ /* Element for RX PATH */ ++ RX_CTRL_T rRxCtrl; ++ ++ P_SDIO_CTRL_T prSDIOCtrl; ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ /* Element for MT6620 E1 HIFSYS workaround */ ++ BOOLEAN fgIsClockGatingEnabled; ++#endif ++ ++ /* Buffer for Authentication Event */ ++ /* Move to glue layer and refine the kal function */ ++ /* Reference to rsnGeneratePmkidIndication function at rsn.c */ ++ UINT_8 aucIndicationEventBuffer[(CFG_MAX_PMKID_CACHE * 20) + 8]; ++ ++ UINT_32 u4IntStatus; ++ ++ ENUM_ACPI_STATE_T rAcpiState; ++ ++ BOOLEAN fgIsIntEnable; ++ BOOLEAN fgIsIntEnableWithLPOwnSet; ++ ++ BOOLEAN fgIsFwOwn; ++ BOOLEAN fgWiFiInSleepyState; ++ ++ UINT_32 u4PwrCtrlBlockCnt; ++ ++ QUE_T rPendingCmdQueue; ++ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ UINT_8 ucCmdSeqNum; ++ UINT_8 ucTxSeqNum; ++ ++#if 1 /* CFG_SUPPORT_WAPI */ ++ BOOLEAN fgUseWapi; ++#endif ++ ++ /* RF Test flags */ ++ BOOLEAN fgTestMode; ++ ++ /* WLAN Info for DRIVER_CORE OID query */ ++ WLAN_INFO_T rWlanInfo; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsP2PRegistered; ++ ENUM_NET_REG_STATE_T rP2PNetRegState; ++ BOOLEAN fgIsWlanLaunched; ++ P_P2P_INFO_T prP2pInfo; ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ OS_SYSTIME rP2pLinkQualityUpdateTime; ++ BOOLEAN fgIsP2pLinkQualityValid; ++ EVENT_LINK_QUALITY rP2pLinkQuality; ++#endif ++ ++ /* FSM Timer */ ++ TIMER_T rP2pFsmTimeoutTimer; ++#endif ++ ++ /* Online Scan Option */ ++ BOOLEAN fgEnOnlineScan; ++ ++ /* Online Scan Option */ ++ BOOLEAN fgDisBcnLostDetection; ++ ++ /* MAC address */ ++ PARAM_MAC_ADDRESS rMyMacAddr; ++ ++ /* Wake-up Event for WOL */ ++ UINT_32 u4WakeupEventEnable; ++ ++ /* Event Buffering */ ++ EVENT_STATISTICS rStatStruct; ++ OS_SYSTIME rStatUpdateTime; ++ BOOLEAN fgIsStatValid; ++ ++ EVENT_LINK_QUALITY rLinkQuality; ++ OS_SYSTIME rLinkQualityUpdateTime; ++ BOOLEAN fgIsLinkQualityValid; ++ OS_SYSTIME rLinkRateUpdateTime; ++ BOOLEAN fgIsLinkRateValid; ++ ++ /* WIFI_VAR_T */ ++ WIFI_VAR_T rWifiVar; ++ ++ /* MTK WLAN NIC driver IEEE 802.11 MIB */ ++ IEEE_802_11_MIB_T rMib; ++ ++ /* Mailboxs for inter-module communication */ ++ MBOX_T arMbox[MBOX_ID_TOTAL_NUM]; ++ ++ /* Timers for OID Pending Handling */ ++ TIMER_T rOidTimeoutTimer; ++ ++ TIMER_T rReturnIndicatedRfbListTimer; ++ ++ /* Root Timer for cnm_timer module */ ++ ROOT_TIMER rRootTimer; ++ ++ /* RLM maintenance */ ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_SYS_PROTECT_MODE_T eSysProtectMode; ++ ENUM_GF_MODE_T eSysHtGfMode; ++ ENUM_RIFS_MODE_T eSysTxRifsMode; ++ ENUM_SYS_PCO_PHASE_T eSysPcoPhase; ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++ /* QM */ ++ QUE_MGT_T rQM; ++ ++ CNM_INFO_T rCnmInfo; ++ ++ UINT_32 u4PowerMode; ++ ++ UINT_32 u4CtiaPowerMode; ++ BOOLEAN fgEnCtiaPowerMode; ++ ++ UINT_32 fgEnArpFilter; ++ ++ UINT_32 u4UapsdAcBmp; ++ ++ UINT_32 u4MaxSpLen; ++ ++ UINT_32 u4PsCurrentMeasureEn; ++ ++ /* Version Information */ ++ WIFI_VER_INFO_T rVerInfo; ++ ++ /* 5GHz support (from F/W) */ ++ BOOLEAN fgIsHw5GBandDisabled; ++ BOOLEAN fgEnable5GBand; ++ BOOLEAN fgIsEepromUsed; ++ BOOLEAN fgIsEfuseValid; ++ BOOLEAN fgIsEmbbededMacAddrValid; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ BOOLEAN fgIsPowerLimitTableValid; ++#endif ++ ++ /* Packet Forwarding Tracking */ ++ INT_32 i4PendingFwdFrameCount; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ UINT_8 ucRddStatus; ++#endif ++ ++ BOOLEAN fgDisStaAgingTimeoutDetection; ++#if CFG_SUPPORT_CFG_FILE ++ P_WLAN_CFG_T prWlanCfg; ++ WLAN_CFG_T rWlanCfg; ++#endif ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ KAL_WAKE_LOCK_T rApWakeLock; ++#endif ++ UINT_32 u4FwCompileFlag0; ++ UINT_32 u4FwCompileFlag1; ++ KAL_WAKE_LOCK_T rTxThreadWakeLock; ++ KAL_WAKE_LOCK_T rAhbIsrWakeLock; ++ ++#if CFG_SUPPORT_ROAMING_ENC ++ BOOLEAN fgIsRoamingEncEnabled; ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ BOOLEAN fgTdlsIsSup; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ UINT_8 ucScanTime; ++ ++#if CFG_SUPPORT_DBG_POWERMODE ++ BOOLEAN fgEnDbgPowerMode; /* dbg privilege power mode, always keep in active */ ++#endif ++ ++ UINT_32 u4AirDelayTotal; /* dbg privilege power mode, always keep in active */ ++ ULONG ulSuspendFlag; ++ struct GL_PER_MON_T rPerMonitor; ++}; /* end of _ADAPTER_T */ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) ++#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for BSS_INFO_T - Flag of Net Active */ ++/*----------------------------------------------------------------------------*/ ++#define IS_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ (_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive) ++#define IS_BSS_ACTIVE(_prBssInfo) ((_prBssInfo)->fgIsNetActive) ++ ++#define IS_AIS_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_AIS_INDEX) ++#define IS_P2P_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_P2P_INDEX) ++#define IS_BOW_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_BOW_INDEX) ++ ++#define SET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = TRUE; } ++ ++#define UNSET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = FALSE; } ++ ++#define BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ ++ { UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; \ ++ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ ++ \ ++ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; \ ++ _prBssInfo->fgIsNetActive = FALSE; \ ++ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ ++ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ ++ COPY_MAC_ADDR(_prBssInfo->aucBSSID, _aucZeroMacAddr); \ ++ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ ++ _prBssInfo->fgIsBeaconActivated = FALSE; \ ++ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ ++ _prBssInfo->fgIsNetAbsent = FALSE; \ ++ } ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#define BOW_BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ ++ { \ ++ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ ++ \ ++ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eCurrentOPMode = OP_MODE_BOW; \ ++ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ ++ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ ++ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ ++ _prBssInfo->fgIsBeaconActivated = TRUE; \ ++ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ ++ _prBssInfo->fgIsNetAbsent = FALSE; \ ++ } ++#endif ++ ++#define PERF_MON_DISABLE_BIT_OFF (0) ++#define PERF_MON_STOP_BIT_OFF (1) ++#define PERF_MON_RUNNING_BIT_OFF (2) ++ ++#define THROUGHPUT_L1_THRESHOLD (20*1024*1024) ++#define THROUGHPUT_L2_THRESHOLD (60*1024*1024) ++#define THROUGHPUT_L3_THRESHOLD (135*1024*1024) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for Power State */ ++/*----------------------------------------------------------------------------*/ ++#define SET_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_IDLE; } ++ ++#define SET_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_ACTIVE; } ++ ++#define SET_NET_PWR_STATE_PS(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_PS; } ++ ++#define IS_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_ACTIVE) ++ ++#define IS_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ ++ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_IDLE) ++ ++#define IS_SCN_PWR_STATE_ACTIVE(_prAdapter) \ ++ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_ACTIVE) ++ ++#define IS_SCN_PWR_STATE_IDLE(_prAdapter) \ ++ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_IDLE) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _ADAPTER_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h +new file mode 100644 +index 000000000000..6c4c1b76622b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h +@@ -0,0 +1,322 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/bow.h#1 ++*/ ++ ++/* ++** Log: bow.h ++ * ++ * 01 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW for 5GHz band. ++ * ++ * 05 25 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW Cancel Scan Request and Turn On deactive network function. ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Submit missing BoW header files. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW structure. ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 ++ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 ++ * with BOW and P2P enabled as default ++ * ++ * 02 08 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. ++ * Update BOW get MAC status, remove returning event for AIS network type. ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add Activity Report definition. ++ * ++ * 10 18 2010 chinghwa.yu ++ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size ++ * Fix wrong BoW event size. ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * 1) all BT physical handles shares the same RSSI/Link Quality. ++ * 2) simplify BT command composing ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * basic implementation for EVENT_BT_OVER_WIFI ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * sync. with design document for interface change. ++ * ++ * 04 02 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * Wi-Fi driver no longer needs to implement 802.11 PAL, thus replaced by wrapping command/event definitions ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * correct typo. ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * update for all command/event needed to be supported by 802.11 PAL. ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * build up basic data structure and definitions to support BT-over-WiFi ++ * ++*/ ++ ++#ifndef _BOW_H_ ++#define _BOW_H_ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define BOWDEVNAME "bow0" ++ ++#define MAX_BOW_NUMBER_OF_CHANNEL_2G4 14 ++#define MAX_BOW_NUMBER_OF_CHANNEL_5G 4 ++/* (MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) */ ++#define MAX_BOW_NUMBER_OF_CHANNEL 18 ++ ++#define MAX_ACTIVITY_REPORT 2 ++#define MAX_ACTIVITY_REPROT_TIME 660 ++ ++#define ACTIVITY_REPORT_STATUS_SUCCESS 0 ++#define ACTIVITY_REPORT_STATUS_FAILURE 1 ++#define ACTIVITY_REPORT_STATUS_TIME_INVALID 2 ++#define ACTIVITY_REPORT_STATUS_OTHERS 3 ++ ++#define ACTIVITY_REPORT_SCHEDULE_UNKNOWN 0 /* Does not know the schedule of the interference */ ++#define ACTIVITY_REPORT_SCHEDULE_KNOWN 1 ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _BT_OVER_WIFI_COMMAND_HEADER_T { ++ UINT_8 ucCommandId; ++ UINT_8 ucSeqNumber; ++ UINT_16 u2PayloadLength; ++} AMPC_COMMAND_HEADER_T, *P_AMPC_COMMAND_HEADER_T; ++ ++typedef struct _BT_OVER_WIFI_COMMAND { ++ AMPC_COMMAND_HEADER_T rHeader; ++ UINT_8 aucPayload[0]; ++} AMPC_COMMAND, *P_AMPC_COMMAND; ++ ++typedef struct _BT_OVER_WIFI_EVENT_HEADER_T { ++ UINT_8 ucEventId; ++ UINT_8 ucSeqNumber; ++ UINT_16 u2PayloadLength; ++} AMPC_EVENT_HEADER_T, *P_AMPC_EVENT_HEADER_T; ++ ++typedef struct _BT_OVER_WIFI_EVENT { ++ AMPC_EVENT_HEADER_T rHeader; ++ UINT_8 aucPayload[0]; ++} AMPC_EVENT, *P_AMPC_EVENT; ++ ++typedef struct _CHANNEL_DESC_T { ++ UINT_8 ucChannelBand; ++ UINT_8 ucChannelNum; ++} CHANNEL_DESC, P_CHANNEL_DESC; ++ ++/* Command Structures */ ++typedef struct _BOW_SETUP_CONNECTION { ++/* Fixed to 2.4G */ ++ UINT_8 ucChannelNum; ++ UINT_8 ucReserved1; ++ UINT_8 aucPeerAddress[6]; ++ UINT_16 u2BeaconInterval; ++ UINT_8 ucTimeoutDiscovery; ++ UINT_8 ucTimeoutInactivity; ++ UINT_8 ucRole; ++ UINT_8 ucPAL_Capabilities; ++ INT_8 cMaxTxPower; ++ UINT_8 ucReserved2; ++ ++/* Pending, for future BOW 5G supporting. */ ++/* UINT_8 aucPeerAddress[6]; ++ UINT_16 u2BeaconInterval; ++ UINT_8 ucTimeoutDiscovery; ++ UINT_8 ucTimeoutInactivity; ++ UINT_8 ucRole; ++ UINT_8 ucPAL_Capabilities; ++ INT_8 cMaxTxPower; ++ UINT_8 ucChannelListNum; ++ CHANNEL_DESC arChannelList[1]; ++*/ ++} BOW_SETUP_CONNECTION, *P_BOW_SETUP_CONNECTION; ++ ++typedef struct _BOW_DESTROY_CONNECTION { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++} BOW_DESTROY_CONNECTION, *P_BOW_DESTROY_CONNECTION; ++ ++typedef struct _BOW_SET_PTK { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++ UINT_8 aucTemporalKey[16]; ++} BOW_SET_PTK, *P_BOW_SET_PTK; ++ ++typedef struct _BOW_READ_RSSI { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++} BOW_READ_RSSI, *P_BOW_READ_RSSI; ++ ++typedef struct _BOW_READ_LINK_QUALITY { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++} BOW_READ_LINK_QUALITY, *P_BOW_READ_LINK_QUALITY; ++ ++typedef struct _BOW_SHORT_RANGE_MODE { ++ UINT_8 aucPeerAddress[6]; ++ INT_8 cTxPower; ++ UINT_8 ucReserved; ++} BOW_SHORT_RANGE_MODE, *P_BOW_SHORT_RANGE_MODE; ++ ++/* Event Structures */ ++typedef struct _BOW_COMMAND_STATUS { ++ UINT_8 ucStatus; ++ UINT_8 ucReserved[3]; ++} BOW_COMMAND_STATUS, *P_BOW_COMMAND_STATUS; ++ ++typedef struct _BOW_MAC_STATUS { ++ UINT_8 aucMacAddr[6]; ++ UINT_8 ucAvailability; ++ UINT_8 ucNumOfChannel; ++ CHANNEL_DESC arChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; ++} BOW_MAC_STATUS, *P_BOW_MAC_STATUS; ++ ++typedef struct _BOW_LINK_CONNECTED { ++ CHANNEL_DESC rChannel; ++ UINT_8 aucReserved; ++ UINT_8 aucPeerAddress[6]; ++} BOW_LINK_CONNECTED, *P_BOW_LINK_CONNECTED; ++ ++typedef struct _BOW_LINK_DISCONNECTED { ++ UINT_8 ucReason; ++ UINT_8 aucReserved; ++ UINT_8 aucPeerAddress[6]; ++} BOW_LINK_DISCONNECTED, *P_BOW_LINK_DISCONNECTED; ++ ++typedef struct _BOW_RSSI { ++ INT_8 cRssi; ++ UINT_8 aucReserved[3]; ++} BOW_RSSI, *P_BOW_RSSI; ++ ++typedef struct _BOW_LINK_QUALITY { ++ UINT_8 ucLinkQuality; ++ UINT_8 aucReserved[3]; ++} BOW_LINK_QUALITY, *P_BOW_LINK_QUALITY; ++ ++typedef enum _ENUM_BOW_CMD_ID_T { ++ BOW_CMD_ID_GET_MAC_STATUS = 1, ++ BOW_CMD_ID_SETUP_CONNECTION, ++ BOW_CMD_ID_DESTROY_CONNECTION, ++ BOW_CMD_ID_SET_PTK, ++ BOW_CMD_ID_READ_RSSI, ++ BOW_CMD_ID_READ_LINK_QUALITY, ++ BOW_CMD_ID_SHORT_RANGE_MODE, ++ BOW_CMD_ID_GET_CHANNEL_LIST, ++} ENUM_BOW_CMD_ID_T, *P_ENUM_BOW_CMD_ID_T; ++ ++typedef enum _ENUM_BOW_EVENT_ID_T { ++ BOW_EVENT_ID_COMMAND_STATUS = 1, ++ BOW_EVENT_ID_MAC_STATUS, ++ BOW_EVENT_ID_LINK_CONNECTED, ++ BOW_EVENT_ID_LINK_DISCONNECTED, ++ BOW_EVENT_ID_RSSI, ++ BOW_EVENT_ID_LINK_QUALITY, ++ BOW_EVENT_ID_CHANNEL_LIST, ++ BOW_EVENT_ID_CHANNEL_SELECTED, ++} ENUM_BOW_EVENT_ID_T, *P_ENUM_BOW_EVENT_ID_T; ++ ++typedef enum _ENUM_BOW_DEVICE_STATE { ++ BOW_DEVICE_STATE_DISCONNECTED = 0, ++ BOW_DEVICE_STATE_DISCONNECTING, ++ BOW_DEVICE_STATE_ACQUIRING_CHANNEL, ++ BOW_DEVICE_STATE_STARTING, ++ BOW_DEVICE_STATE_SCANNING, ++ BOW_DEVICE_STATE_CONNECTING, ++ BOW_DEVICE_STATE_CONNECTED, ++ BOW_DEVICE_STATE_NUM ++} ENUM_BOW_DEVICE_STATE, *P_ENUM_BOW_DEVICE_STATE; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#endif /*_BOW_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h +new file mode 100644 +index 000000000000..c1ecb303b877 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h +@@ -0,0 +1,150 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "cmd_buf.h" ++ \brief In this file we define the structure for Command Packet. ++ ++ In this file we define the structure for Command Packet and the control unit ++ of MGMT Memory Pool. ++*/ ++ ++/* ++** Log: cmd_buf.h ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow ++ * under concurrent network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Enable change log ++*/ ++ ++#ifndef _CMD_BUF_H ++#define _CMD_BUF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _COMMAND_TYPE { ++ COMMAND_TYPE_GENERAL_IOCTL, ++ COMMAND_TYPE_NETWORK_IOCTL, ++ COMMAND_TYPE_SECURITY_FRAME, ++ COMMAND_TYPE_MANAGEMENT_FRAME, ++ COMMAND_TYPE_NUM ++} COMMAND_TYPE, *P_COMMAND_TYPE; ++ ++typedef VOID(*PFN_CMD_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++typedef VOID(*PFN_CMD_TIMEOUT_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++struct _CMD_INFO_T { ++ QUE_ENTRY_T rQueEntry; ++ ++ COMMAND_TYPE eCmdType; ++ ++ UINT_16 u2InfoBufLen; /* This is actual CMD buffer length */ ++ PUINT_8 pucInfoBuffer; /* May pointer to structure in prAdapter */ ++ P_NATIVE_PACKET prPacket; /* only valid when it's a security frame */ ++ ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkType; ++ UINT_8 ucStaRecIndex; /* only valid when it's a security frame */ ++ ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler; ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler; ++ ++ BOOLEAN fgIsOid; /* Used to check if we need indicate */ ++ ++ UINT_8 ucCID; ++ BOOLEAN fgSetQuery; ++ BOOLEAN fgNeedResp; ++ BOOLEAN fgDriverDomainMCR; /* Access Driver Domain MCR, for CMD_ID_ACCESS_REG only */ ++ UINT_8 ucCmdSeqNum; ++ UINT_32 u4SetInfoLen; /* Indicate how many byte we read for Set OID */ ++ ++ /* information indicating by OID/ioctl */ ++ PVOID pvInformationBuffer; ++ UINT_32 u4InformationBufferLength; ++ ++ /* private data */ ++ UINT_32 u4PrivateData; ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter); ++ ++P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); ++ ++VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for CMDs */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); ++VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _CMD_BUF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h +new file mode 100644 +index 000000000000..0fdb9dcadeef +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h +@@ -0,0 +1,618 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hal.h#1 ++*/ ++ ++/*! \file "hal.h" ++ \brief The declaration of hal functions ++ ++ N/A ++*/ ++ ++/* ++** Log: hal.h ++ * ++ * 04 01 2011 tsaiyuan.hsu ++ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues ++ * fix the klocwork issues, 57500, 57501, 57502 and 57503. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change zero-padding for TX port access to HAL. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * 4. correct some HAL implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-16 18:02:26 GMT mtk02752 ++** include precomp.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:16 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 13:54:15 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-11 10:36:01 GMT mtk01084 ++** modify HAL functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-09 22:56:28 GMT mtk01084 ++** modify HW access routines ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:50:09 GMT mtk01084 ++** add new macro HAL_TX_PORT_WR ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:08:10 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:50 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-05-18 14:28:10 GMT mtk01084 ++** fix issue in HAL_DRIVER_OWN_BY_SDIO_CMD52() ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-11 17:26:33 GMT mtk01084 ++** modify the bit definition to check driver own status ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:30:22 GMT mtk01461 ++** Fix typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:50:34 GMT mtk01461 ++** Redefine HAL_PORT_RD/WR macro for SW pre test ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-24 09:46:49 GMT mtk01084 ++** fix LINT error ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 16:53:38 GMT mtk01084 ++** add HAL_DRIVER_OWN_BY_SDIO_CMD52() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:53:13 GMT mtk01426 ++** Fixed lint warn ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:20 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _HAL_H ++#define _HAL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* Macros for flag operations for the Adapter structure */ ++#define HAL_SET_FLAG(_M, _F) ((_M)->u4HwFlags |= (_F)) ++#define HAL_CLEAR_FLAG(_M, _F) ((_M)->u4HwFlags &= ~(_F)) ++#define HAL_TEST_FLAG(_M, _F) ((_M)->u4HwFlags & (_F)) ++#define HAL_TEST_FLAGS(_M, _F) (((_M)->u4HwFlags & (_F)) == (_F)) ++ ++#if defined(_HIF_SDIO) ++#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ ++do { \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ /* DBGLOG(HAL, ERROR, ("HAL_MCR_RD access fail! 0x%x: 0x%x\n", */ \ ++ /* (UINT32)_u4Offset, (UINT32)*_pu4Value)); */ \ ++ } \ ++ } else { \ ++ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_RD access! 0x%x\n", (UINT32)_u4Offset)); */ \ ++ } \ ++} while (0) ++ ++#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ ++do { \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ /* DBGLOG(HAL, ERROR, ("HAL_MCR_WR access fail! 0x%x: 0x%x\n", */ \ ++ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ ++ } \ ++ } else { \ ++ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_WR access! 0x%x: 0x%x\n", */ \ ++ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ ++ } \ ++} while (0) ++ ++#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ /*fgResult = FALSE; */\ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "HAL_PORT_RD access fail! 0x%x\n", _u4Port); \ ++ } \ ++ else { \ ++ /*fgResult = TRUE;*/ } \ ++ } else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_PORT_RD access! 0x%x\n", _u4Port); \ ++ } \ ++} ++ ++#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ /*fgResult = FALSE; */\ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "HAL_PORT_WR access fail! 0x%x\n", _u4Port); \ ++ } \ ++ else { \ ++ /*fgResult = TRUE;*/ } \ ++ } else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_PORT_WR access! 0x%x\n", _u4Port); \ ++ } \ ++} ++ ++#if 0 /* only for SDIO */ ++#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf) == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "HAL_BYTE_WR access fail! 0x%x\n", _u4Port); \ ++ } \ ++ else { \ ++ /* Todo:: Nothing*/ \ ++ } \ ++ } \ ++ else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_BYTE_WR access! 0x%x\n", _u4Port); \ ++ } \ ++} ++#endif ++ ++#define HAL_DRIVER_OWN_BY_SDIO_CMD52(_prAdapter, _pfgDriverIsOwnReady) \ ++{ \ ++ UINT_8 ucBuf = BIT(1); \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevReadAfterWriteWithSdioCmd52(_prAdapter->prGlueInfo, MCR_WHLPCR_BYTE1, &ucBuf, 1) \ ++ == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "kalDevReadAfterWriteWithSdioCmd52 access fail!\n"); \ ++ } \ ++ else { \ ++ *_pfgDriverIsOwnReady = (ucBuf & BIT(0)) ? TRUE : FALSE; \ ++ } \ ++ } else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_DRIVER_OWN_BY_SDIO_CMD52 access!\n"); \ ++ } \ ++} ++ ++#else /* #if defined(_HIF_SDIO) */ ++#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#if 0 /* only for SDIO */ ++#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf); \ ++} ++#endif ++ ++#endif /* #if defined(_HIF_SDIO) */ ++ ++#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \ ++{ \ ++ ASSERT(u4PortId < 2); \ ++ HAL_PORT_RD(prAdapter, \ ++ ((u4PortId == 0) ? MCR_WRDR0 : MCR_WRDR1), \ ++ u4Len, \ ++ pvBuf, \ ++ _u4ValidBufSize/*temp!!*//*4Kbyte*/); \ ++} ++ ++#define HAL_WRITE_TX_PORT(_prAdapter, _ucTxPortIdx, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ ASSERT(_ucTxPortIdx < 2); \ ++ if ((_u4ValidBufSize - _u4Len) >= sizeof(UINT_32)) { \ ++ /* fill with single dword of zero as TX-aggregation termination */ \ ++ *(PUINT_32) (&((_pucBuf)[ALIGN_4(_u4Len)])) = 0; \ ++ } \ ++ HAL_PORT_WR(_prAdapter, \ ++ (_ucTxPortIdx == 0) ? MCR_WTDR0 : MCR_WTDR1, \ ++ _u4Len, \ ++ _pucBuf, \ ++ _u4ValidBufSize/*temp!!*//*4KByte*/); \ ++} ++ ++/* The macro to read the given MCR several times to check if the wait ++ condition come true. */ ++#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, _waitCondition, _waitDelay, _waitCount, _status) \ ++{ \ ++ UINT_32 count; \ ++ (_status) = FALSE; \ ++ for (count = 0; count < (_waitCount); count++) { \ ++ HAL_MCR_RD((_pAdapter), (_offset), (_pReadValue)); \ ++ if ((_waitCondition)) { \ ++ (_status) = TRUE; \ ++ break; \ ++ } \ ++ kalUdelay((_waitDelay)); \ ++ } \ ++} ++ ++/* The macro to write 1 to a R/S bit and read it several times to check if the ++ command is done */ ++#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, _busyMask, _waitDelay, _waitCount, _status) \ ++{ \ ++ UINT_32 u4Temp; \ ++ UINT_32 u4Count = _waitCount; \ ++ (_status) = FALSE; \ ++ HAL_MCR_WR((_pAdapter), (_offset), (_writeValue)); \ ++ do { \ ++ kalUdelay((_waitDelay)); \ ++ HAL_MCR_RD((_pAdapter), (_offset), &u4Temp); \ ++ if (!(u4Temp & (_busyMask))) { \ ++ (_status) = TRUE; \ ++ break; \ ++ } \ ++ u4Count--; \ ++ } while (u4Count); \ ++} ++ ++#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WCIR, \ ++ &u4Value); \ ++ *pu2ChipId = (UINT_16)(u4Value & WCIR_CHIP_ID); \ ++ *pu2Version = (UINT_16)(u4Value & WCIR_REVISION_ID) >> 16; \ ++} ++ ++#define HAL_WAIT_WIFI_FUNC_READY(_prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ UINT_32 i; \ ++ for (i = 0; i < 100; i++) { \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WCIR, \ ++ &u4Value); \ ++ if (u4Value & WCIR_WLAN_READY) { \ ++ break; \ ++ } \ ++ NdisMSleep(10); \ ++ } \ ++} ++ ++#define HAL_INTR_DISABLE(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_INT_EN_CLR) ++ ++#define HAL_INTR_ENABLE(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_INT_EN_SET) ++ ++#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ (WHLPCR_INT_EN_SET | WHLPCR_FW_OWN_REQ_SET)) ++ ++#define HAL_LP_OWN_SET(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_FW_OWN_REQ_SET) ++ ++#define HAL_LP_OWN_CLR_OK(_prAdapter, _pfgResult) \ ++{ \ ++ UINT_32 i; \ ++ UINT_32 u4RegValue; \ ++ UINT_32 u4LoopCnt = 2048 / 8; \ ++ *_pfgResult = TRUE; \ ++ /* Software get LP ownership */ \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_FW_OWN_REQ_CLR) \ ++ for (i = 0; i < u4LoopCnt; i++) { \ ++ HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ ++ if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ ++ break; \ ++ } \ ++ else { \ ++ kalUdelay(8); \ ++ } \ ++ } \ ++ if (i == u4LoopCnt) { \ ++ *_pfgResult = FALSE; \ ++ /*ERRORLOG(("LP cannot be own back (%ld)", u4LoopCnt));*/ \ ++ /* check the time of LP instructions need to perform from Sleep to On */ \ ++ /*ASSERT(0); */ \ ++ } \ ++} ++ ++#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) \ ++{ \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WASR, \ ++ pu4AbnormalReason); \ ++} ++ ++#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHCR, \ ++ u4Value & ~WHCR_RX_ENHANCE_MODE_EN); \ ++} ++ ++#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHCR, \ ++ u4Value | WHCR_RX_ENHANCE_MODE_EN); \ ++} ++ ++#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) \ ++{ \ ++ UINT_32 u4Value, ucNum; \ ++ ucNum = ((_ucNumOfRxLen >= 16) ? 0 : _ucNumOfRxLen); \ ++ u4Value = 0; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ u4Value &= ~WHCR_MAX_HIF_RX_LEN_NUM; \ ++ u4Value |= ((((UINT_32)ucNum) << 4) & WHCR_MAX_HIF_RX_LEN_NUM); \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHCR, \ ++ u4Value); \ ++} ++ ++#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(prAdapter, \ ++ MCR_WHCR, \ ++ u4Value & ~WHCR_W_INT_CLR_CTRL); \ ++ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = TRUE;\ ++} ++ ++#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(prAdapter, \ ++ MCR_WHCR, \ ++ u4Value | WHCR_W_INT_CLR_CTRL); \ ++ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = FALSE;\ ++} ++ ++/* Note: enhance mode structure may also carried inside the buffer, ++ if the length of the buffer is long enough */ ++#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) \ ++ HAL_PORT_RD(prAdapter, \ ++ MCR_WHISR, \ ++ length, \ ++ pvBuf, \ ++ length) ++ ++#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, aucTxReleaseCount) \ ++{ \ ++ PUINT_32 pu4Value = (PUINT_32)aucTxReleaseCount; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WTSR0, \ ++ &pu4Value[0]); \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WTSR1, \ ++ &pu4Value[1]); \ ++} ++ ++#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) \ ++{ \ ++ UINT_32 u4Value; \ ++ u4Value = 0; \ ++ HAL_MCR_RD(prAdapter, \ ++ MCR_WRPLR, \ ++ &u4Value); \ ++ *pu2Rx0Len = (UINT_16)u4Value; \ ++ *pu2Rx1Len = (UINT_16)(u4Value >> 16); \ ++} ++ ++#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, u2Len, pu4Status) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvBuf; \ ++ *pu4Status = pu4Buf[0]; \ ++} ++ ++#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4BufOut, u4LenBufOut) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ ++ ASSERT(u4LenBufOut >= 8); \ ++ pu4BufOut[0] = pu4Buf[1]; \ ++ pu4BufOut[1] = pu4Buf[2]; \ ++} ++ ++#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ ++ ASSERT((sizeof(au2Rx0Len) / sizeof(UINT_16)) >= 16); \ ++ ASSERT((sizeof(au2Rx1Len) / sizeof(UINT_16)) >= 16); \ ++ *pu2Rx0Num = (UINT_16)pu4Buf[3]; \ ++ *pu2Rx1Num = (UINT_16)(pu4Buf[3] >> 16); \ ++ kalMemCopy(au2Rx0Len, &pu4Buf[4], 8); \ ++ kalMemCopy(au2Rx1Len, &pu4Buf[12], 8); \ ++} ++ ++#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4Mailbox0, pu4Mailbox1) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ ++ *pu4Mailbox0 = (UINT_16)pu4Buf[21]; \ ++ *pu4Mailbox1 = (UINT_16)pu4Buf[22]; \ ++} ++ ++#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & WHISR_TX_DONE_INT) ? TRUE : FALSE) ++ ++#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & (WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)) ? TRUE : FALSE) ++ ++#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & WHISR_ABNORMAL_INT) ? TRUE : FALSE) ++ ++#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & WHISR_FW_OWN_BACK_INT) ? TRUE : FALSE) ++ ++#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) \ ++{ \ ++ ASSERT(u4MboxId < 2); \ ++ HAL_MCR_WR(prAdapter, \ ++ ((u4MboxId == 0) ? MCR_H2DSM0R : MCR_H2DSM1R), \ ++ u4Data); \ ++} ++ ++#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) \ ++{ \ ++ ASSERT(u4MboxId < 2); \ ++ HAL_MCR_RD(prAdapter, \ ++ ((u4MboxId == 0) ? MCR_D2HRM0R : MCR_D2HRM1R), \ ++ pu4Data); \ ++} ++ ++#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);\ ++ HAL_MCR_WR(prAdapter, MCR_WHCR, \ ++ (fgEnableReadClear) ? \ ++ (u4Value | WHCR_W_MAILBOX_RD_CLR_EN) : \ ++ (u4Value & ~WHCR_W_MAILBOX_RD_CLR_EN)); \ ++ prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\ ++} ++ ++#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _HAL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h +new file mode 100644 +index 000000000000..b9aa154b097e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h +@@ -0,0 +1,220 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_rx.h#1 ++*/ ++ ++/*! \file "hif_rx.h" ++ \brief Provide HIF RX Header Information between F/W and Driver ++ ++ N/A ++*/ ++ ++/* ++** Log: hif_rx.h ++ * ++ * 09 01 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * follow-ups for HIF_RX_HEADER_T update: ++ * 1) add TCL ++ * 2) add RCPI ++ * 3) add ChannelNumber ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:44:00 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-09 13:59:20 GMT MTK02468 ++** Added HIF_RX_HDR parsing macros ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 19:54:54 GMT mtk02752 ++** adopt HIF_RX_HEADER_T in new data path ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-29 19:51:19 GMT mtk01084 ++** modify FW/ driver interface ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:33:58 GMT mtk01461 ++** Add define of HW_APPENED_LEN ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:51:02 GMT mtk01461 ++** Rename ENUM_HIF_RX_PKT_TYPE_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 12:05:03 GMT mtk01426 ++** Remove __KAL_ATTRIB_PACKED__ and add hifDataTypeCheck() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:18:52 GMT mtk01426 ++** Add comment to HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:23 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _HIF_RX_H ++#define _HIF_RX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/*! HIF_RX_HEADER_T */ ++/* DW 0, Byte 1 */ ++#define HIF_RX_HDR_PACKET_TYPE_MASK BITS(0, 1) ++#define HIF_RX_HDR_SEC_MODE_MASK BITS(2, 5) ++#define HIF_RX_HDR_SEC_MODE_OFFSET 2 ++ ++/* DW 1, Byte 0 */ ++#define HIF_RX_HDR_HEADER_LEN BITS(2, 7) ++#define HIF_RX_HDR_HEADER_LEN_OFFSET 2 ++#define HIF_RX_HDR_HEADER_OFFSET_MASK BITS(0, 1) ++ ++/* DW 1, Byte 1 */ ++#define HIF_RX_HDR_80211_HEADER_FORMAT BIT(0) ++#define HIF_RX_HDR_DO_REORDER BIT(1) ++#define HIF_RX_HDR_PAL BIT(2) ++#define HIF_RX_HDR_TCL BIT(3) ++#define HIF_RX_HDR_NETWORK_IDX_MASK BITS(4, 7) ++#define HIF_RX_HDR_NETWORK_IDX_OFFSET 4 ++ ++/* DW 1, Byte 2, 3 */ ++#define HIF_RX_HDR_SEQ_NO_MASK BITS(0, 11) ++#define HIF_RX_HDR_TID_MASK BITS(12, 14) ++#define HIF_RX_HDR_TID_OFFSET 12 ++#define HIF_RX_HDR_BAR_FRAME BIT(15) ++ ++#define HIF_RX_HDR_FLAG_AMP_WDS BIT(0) ++#define HIF_RX_HDR_FLAG_802_11_FORMAT BIT(1) ++#define HIF_RX_HDR_FLAG_BAR_FRAME BIT(2) ++#define HIF_RX_HDR_FLAG_DO_REORDERING BIT(3) ++#define HIF_RX_HDR_FLAG_CTRL_WARPPER_FRAME BIT(4) ++ ++#define HIF_RX_HW_APPENDED_LEN 4 ++ ++/* For DW 2, Byte 3 - ucHwChannelNum */ ++#define HW_CHNL_NUM_MAX_2G4 14 ++#define HW_CHNL_NUM_MAX_4G_5G (255 - HW_CHNL_NUM_MAX_2G4) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _HIF_RX_HEADER_T { ++ UINT_16 u2PacketLen; ++ UINT_16 u2PacketType; ++ UINT_8 ucHerderLenOffset; ++ UINT_8 uc80211_Reorder_PAL_TCL; ++ UINT_16 u2SeqNoTid; ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucRcpi; ++ UINT_8 ucHwChannelNum; ++ UINT_8 ucReserved; ++} HIF_RX_HEADER_T, *P_HIF_RX_HEADER_T; ++ ++typedef enum _ENUM_HIF_RX_PKT_TYPE_T { ++ HIF_RX_PKT_TYPE_DATA = 0, ++ HIF_RX_PKT_TYPE_EVENT, ++ HIF_RX_PKT_TYPE_TX_LOOPBACK, ++ HIF_RX_PKT_TYPE_MANAGEMENT, ++ HIF_RX_PKT_TYPE_NUM ++} ENUM_HIF_RX_PKT_TYPE_T, *P_ENUM_HIF_RX_PKT_TYPE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define HIF_RX_HDR_SIZE sizeof(HIF_RX_HEADER_T) ++ ++#define HIF_RX_HDR_GET_80211_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_80211_HEADER_FORMAT) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_REORDER_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_DO_REORDER) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_PAL_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_PAL) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_TCL_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_TCL) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_NETWORK_IDX(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_NETWORK_IDX_MASK)\ ++ >> HIF_RX_HDR_NETWORK_IDX_OFFSET) ++ ++#define HIF_RX_HDR_GET_SEC_MODE(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->u2PacketType) & HIF_RX_HDR_SEC_MODE_MASK) >> HIF_RX_HDR_SEC_MODE_OFFSET) ++ ++#define HIF_RX_HDR_GET_TID(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_TID_MASK)\ ++ >> HIF_RX_HDR_TID_OFFSET) ++#define HIF_RX_HDR_GET_SN(_prHifRxHdr) \ ++ (((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_SEQ_NO_MASK) ++#define HIF_RX_HDR_GET_BAR_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_BAR_FRAME) ? TRUE : FALSE)) ++ ++#define HIF_RX_HDR_GET_CHNL_NUM(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->ucHwChannelNum) > HW_CHNL_NUM_MAX_4G_5G) ? \ ++ (((_prHifRxHdr)->ucHwChannelNum) - HW_CHNL_NUM_MAX_4G_5G) : \ ++ ((_prHifRxHdr)->ucHwChannelNum)) ++ ++/* To do: support more bands other than 2.4G and 5G */ ++#define HIF_RX_HDR_GET_RF_BAND(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->ucHwChannelNum) <= HW_CHNL_NUM_MAX_2G4) ? \ ++ BAND_2G4 : BAND_5G) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static inline VOID hifDataTypeCheck(VOID); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this for porting driver to different RTOS. ++ */ ++static inline VOID hifDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_RX_HEADER_T) == 12); ++ ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h +new file mode 100644 +index 000000000000..17252f2c7760 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h +@@ -0,0 +1,214 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_tx.h#1 ++*/ ++ ++/* ++** Log: hif_tx.h ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill extra information for revised HIF_TX_HEADER. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate ++ * 2) add packet type for indicating management frames ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++ * ++ * 01 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:40 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-24 19:55:11 GMT mtk02752 ++** adopt HIF_TX_HEADER_T in new data path ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-23 17:54:13 GMT mtk02752 ++** CMD_HDR_SIZE = (sizeof(WIFI_CMD_T)) to follow up CM's CMD/EVENT documentation ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-17 22:41:10 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-17 17:34:07 GMT mtk02752 ++** remove HIF_TX_BUFF_COUNT_TC0 (move to nic_tx.h) ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-17 12:14:12 GMT mtk02752 ++** add initial value for HIF_TX_BUFF_COUNT_TC5 ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-13 13:54:18 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-04 14:11:14 GMT mtk01084 ++** modify SW TX data format ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-29 19:51:53 GMT mtk01084 ++** modify FW/ driver interface ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-20 12:22:46 GMT mtk01461 ++** Add SeqNum field to CMD Header ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:40:52 GMT mtk01461 ++** Update the Log Sign ++*/ ++ ++#ifndef _HIF_TX_H ++#define _HIF_TX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Maximum buffer size for individual HIF TCQ Buffer */ ++#define HIF_TX_BUFF_MAX_SIZE 1552 /* Reserved field was not included */ ++ ++/* Maximum buffer count for individual HIF TCQ */ ++#define HIF_TX_BUFF_COUNT_TC0 3 ++#define HIF_TX_BUFF_COUNT_TC1 3 ++#define HIF_TX_BUFF_COUNT_TC2 3 ++#define HIF_TX_BUFF_COUNT_TC3 3 ++#define HIF_TX_BUFF_COUNT_TC4 2 ++ ++#define TX_HDR_SIZE sizeof(HIF_TX_HEADER_T) ++ ++#define CMD_HDR_SIZE sizeof(WIFI_CMD_T) ++ ++#define CMD_PKT_SIZE_FOR_IMAGE 2048 /* !< 2048 Bytes CMD payload buffer */ ++ ++/*! NIC_HIF_TX_HEADER_T */ ++/* DW 0, Byte 0,1 */ ++#define HIF_TX_HDR_TX_BYTE_COUNT_MASK BITS(0, 11) ++#define HIF_TX_HDR_USER_PRIORITY_OFFSET 12 ++ ++/* DW 0, Byte 2 */ ++#define HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK BITS(0, 7) ++ ++/* DW 0, Byte 3 */ ++#define HIF_TX_HDR_IP_CSUM BIT(0) ++#define HIF_TX_HDR_TCP_CSUM BIT(1) ++#define HIF_TX_HDR_RESOURCE_MASK BITS(2, 5) ++#define HIF_TX_HDR_RESOURCE_OFFSET 2 ++#define HIF_TX_HDR_PACKET_TYPE_MASK BITS(6, 7) ++#define HIF_TX_HDR_PACKET_TYPE_OFFSET 6 ++ ++/* DW 1, Byte 0 */ ++#define HIF_TX_HDR_WLAN_HEADER_LEN_MASK BITS(0, 5) ++ ++/* DW 1, Byte 1 */ ++#define HIF_TX_HDR_FORMAT_ID_MASK BITS(0, 2) ++#define HIF_TX_HDR_NETWORK_TYPE_MASK BITS(4, 5) ++#define HIF_TX_HDR_NETWORK_TYPE_OFFSET 4 ++#define HIF_TX_HDR_FLAG_1X_FRAME_MASK BIT(6) ++#define HIF_TX_HDR_FLAG_1X_FRAME_OFFSET 6 ++#define HIF_TX_HDR_FLAG_802_11_FORMAT_MASK BIT(7) ++#define HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET 7 ++ ++/* DW2, Byte 3 */ ++#define HIF_TX_HDR_PS_FORWARDING_TYPE_MASK BITS(0, 1) ++#define HIF_TX_HDR_PS_SESSION_ID_MASK BITS(2, 4) ++#define HIF_TX_HDR_PS_SESSION_ID_OFFSET 2 ++#define HIF_TX_HDR_BURST_END_MASK BIT(5) ++#define HIF_TX_HDR_BURST_END_OFFSET 5 ++ ++/* DW3, Byte 1 */ ++#define HIF_TX_HDR_NEED_ACK BIT(0) ++#define HIF_TX_HDR_BIP BIT(1) ++#define HIF_TX_HDR_BASIC_RATE BIT(2) ++#define HIF_TX_HDR_NEED_TX_DONE_STATUS BIT(3) ++#define HIF_TX_HDR_RTS BIT(4) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _HIF_HW_TX_HEADER_T { ++ UINT_16 u2TxByteCount; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucCSflags; ++ UINT_8 aucBuffer[0]; ++} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T; ++ ++typedef struct _HIF_TX_HEADER_T { ++ UINT_16 u2TxByteCount_UserPriority; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucResource_PktType_CSflags; ++ UINT_8 ucWlanHeaderLength; ++ UINT_8 ucPktFormtId_Flags; ++ UINT_16 u2LLH; /* for BOW */ ++ UINT_16 u2SeqNo; /* for BOW */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucForwardingType_SessionID_Reserved; ++ UINT_8 ucPacketSeqNo; ++ UINT_8 ucAck_BIP_BasicRate; ++ UINT_8 aucReserved[2]; ++} HIF_TX_HEADER_T, *P_HIF_TX_HEADER_T; ++ ++typedef enum _ENUM_HIF_TX_PKT_TYPE_T { ++ HIF_TX_PKT_TYPE_DATA = 0, ++ HIF_TX_PKT_TYPE_CMD, ++ HIF_TX_PKT_TYPE_HIF_LOOPBACK, ++ HIF_TX_PKT_TYPE_MANAGEMENT, ++ HIF_TX_PKT_TYPE_NUM ++} ENUM_HIF_TX_PKT_TYPE_T, *P_ENUM_HIF_TX_PKT_TYPE_T; ++ ++typedef enum _ENUM_HIF_OOB_CTRL_PKT_TYPE_T { ++ HIF_OOB_CTRL_PKT_TYPE_LOOPBACK = 1, ++ HIF_OOB_CTRL_PKT_TYP_NUM ++} ENUM_HIF_OOB_CTRL_PKT_TYPE_T, *P_ENUM_HIF_OOB_CTRL_PKT_TYPE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define TFCB_FRAME_PAD_TO_DW(u2Length) ALIGN_4(u2Length) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ */ ++static inline VOID hif_txDataTypeCheck(VOID); ++ ++static inline VOID hif_txDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_TX_HEADER_T) == 16); ++ ++} ++ ++#endif /*_HIF_TX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h +new file mode 100644 +index 000000000000..ff38d30c3cf2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h +@@ -0,0 +1,2323 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/mac.h#1 ++*/ ++ ++/*! \file "mac.h" ++ \brief Brief description. ++ ++ Detail description. ++*/ ++ ++/* ++** Log: mac.h ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 wh.su ++ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h ++ * and let the sw structure not align at byte ++ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, ++ * Notice needed update P2P.ko. ++ * ++ * 05 06 2011 wh.su ++ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send ++ * the wrong beacon make driver got incorrect support rate set ++ * Add the length check before access the ie length filed. ++ * ++ * 05 06 2011 wh.su ++ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send ++ * the wrong beacon make driver got incorrect support rate set ++ * adding the length check before processing next ie.. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discover ability support. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Some action frame define is not belong to P2P. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Add some service discovery MAC define, phase I. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork ++ * suppress warning reported by Klockwork. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * revert to previous revision. (this file is not necessary to be changed) ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * 1. Add P2P MAC define. ++ * 2. Add scan device found event ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add WFA specific OUI. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P IE ID & Vendor OUI TYPE for P2P. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge MAC.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added OFFSET_BAR_SSC_SN ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:00:24 GMT MTK02468 ++** Added offsets and masks for the BA Parameter Set filed ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:26 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _MAC_H ++#define _MAC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* 3 --------------- Constants for Ethernet/802.11 MAC --------------- */ ++/* MAC Address */ ++#define MAC_ADDR_LEN 6 ++ ++#define MAC_ADDR_LOCAL_ADMIN BIT(1) ++ ++#define ETH_P_IPV4 0x0800 ++#define ETH_P_IPX 0x8137 /* Novell IPX */ ++#define ETH_P_AARP 0x80F3 /* AppleTalk Address Resolution Protocol (AARP) */ ++#define ETH_P_IPV6 0x86DD ++ ++#define IP_VERSION_4 4 ++#define IP_VERSION_6 6 ++ ++#define IP_PROTOCOL_TCP 6 ++#define IP_PROTOCOL_UDP 17 ++ ++#define IPV4_HDR_IP_IDENTIFICATION_OFFSET 4 ++#define IPV4_HDR_IP_PROTOCOL_OFFSET 9 ++#define IPV4_HDR_IP_CSUM_OFFSET 10 ++#define IPV4_HDR_IP_SRC_ADDR_OFFSET 12 ++#define IPV4_HDR_IP_DST_ADDR_OFFSET 16 ++ ++#define IPV6_HDR_IP_PROTOCOL_OFFSET 6 ++#define IPV6_HDR_IP_SRC_ADDR_OFFSET 8 ++#define IPV6_HDR_IP_DST_ADDR_OFFSET 24 ++#define IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET 32 ++#define IPV6_HDR_IP_DST_ADDR_MAC_LOW_OFFSET 37 ++#define IPV6_PROTOCOL_ICMPV6 0x3A ++#define IPV6_ADDR_LEN 16 ++#define IPV6_HDR_LEN 40 ++ ++#define ARP_OPERATION_OFFSET 6 ++#define ARP_SNEDER_MAC_OFFSET 8 ++#define ARP_SENDER_IP_OFFSET 14 ++#define ARP_TARGET_MAC_OFFSET 18 ++#define ARP_TARGET_IP_OFFSET 24 ++#define ARP_OPERATION_REQUEST 0x0001 ++#define ARP_OPERATION_RESPONSE 0x0002 ++ ++#define ICMPV6_TYPE_OFFSET 0 ++#define ICMPV6_FLAG_OFFSET 4 ++#define ICMPV6_TARGET_ADDR_OFFSET 8 ++#define ICMPV6_TARGET_LL_ADDR_TYPE_OFFSET 24 ++#define ICMPV6_TARGET_LL_ADDR_LEN_OFFSET 25 ++#define ICMPV6_TARGET_LL_ADDR_TA_OFFSET 26 ++ ++#define ICMPV6_FLAG_ROUTER_BIT BIT(7) ++#define ICMPV6_FLAG_SOLICITED_BIT BIT(6) ++#define ICMPV6_FLAG_OVERWRITE_BIT BIT(5) ++#define ICMPV6_TYPE_NEIGHBOR_SOLICITATION 0x87 ++#define ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 ++ ++#define TCP_HDR_TCP_CSUM_OFFSET 16 ++#define UDP_HDR_UDP_CSUM_OFFSET 6 ++ ++#define LLC_LEN 8 /* LLC(3) + SNAP(3) + EtherType(2) */ ++ ++#define NULL_MAC_ADDR {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} ++#define BC_MAC_ADDR {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} ++ ++/* Ethernet Frame Field Size, in byte */ ++#define ETHER_HEADER_LEN 14 ++#define ETHER_TYPE_LEN 2 ++#define ETHER_MIN_PKT_SZ 60 ++#define ETHER_MAX_PKT_SZ 1514 ++ ++/* IEEE 802.11 WLAN Frame Field Size, in byte */ ++#define WLAN_MAC_HEADER_LEN 24 /* Address 4 excluded */ ++#define WLAN_MAC_HEADER_A4_LEN 30 /* Address 4 included */ ++#define WLAN_MAC_HEADER_QOS_LEN 26 /* QoS Control included */ ++#define WLAN_MAC_HEADER_QOS_HTC_LEN 30 /* QoS Control and HTC included */ ++#define WLAN_MAC_HEADER_A4_QOS_LEN 32 /* Address 4 and QoS Control included */ ++#define WLAN_MAC_HEADER_A4_QOS_HTC_LEN 36 /* Address 4, QoS Control and HTC included */ ++#define WLAN_MAC_MGMT_HEADER_LEN 24 /* Address 4 excluded */ ++#define WLAN_MAC_MGMT_HEADER_HTC_LEN 28 /* HTC included */ ++ ++#define QOS_CTRL_LEN 2 ++#define HT_CTRL_LEN 4 ++ ++#define WLAN_MAC_CTS_ACK_LEN (WLAN_MAC_CTS_ACK_FRAME_HEADER_LEN + FCS_LEN) ++ ++/* 6.2.1.1.2 Semantics of the service primitive */ ++#define MSDU_MAX_LENGTH 2304 ++ ++/* 7.1.3.3.3 Broadcast BSSID */ ++#define BC_BSSID BC_MAC_ADDR ++ ++/* 7.1.3.7 FCS field */ ++#define FCS_LEN 4 ++ ++/* 7.3.1.6 Listen Interval field */ ++#define DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD 2 /* In unit of AP's DTIM interval, */ ++#define DEFAULT_LISTEN_INTERVAL 10 ++ ++/* 7.3.2.1 Broadcast(Wildcard) SSID */ ++#define BC_SSID "" ++#define BC_SSID_LEN 0 ++ ++/* 7.3.2.2 Data Rate Value */ ++#define RATE_1M 2 /* 1M in unit of 500kb/s */ ++#define RATE_2M 4 /* 2M */ ++#define RATE_5_5M 11 /* 5.5M */ ++#define RATE_11M 22 /* 11M */ ++#define RATE_22M 44 /* 22M */ ++#define RATE_33M 66 /* 33M */ ++#define RATE_6M 12 /* 6M */ ++#define RATE_9M 18 /* 9M */ ++#define RATE_12M 24 /* 12M */ ++#define RATE_18M 36 /* 18M */ ++#define RATE_24M 48 /* 24M */ ++#define RATE_36M 72 /* 36M */ ++#define RATE_48M 96 /* 48M */ ++#define RATE_54M 108 /* 54M */ ++/* 7.3.2.14 BSS membership selector */ ++#define RATE_HT_PHY 127 /* BSS Selector - Clause 20. HT PHY */ ++#define RATE_MASK BITS(0, 6) /* mask bits for the rate */ ++#define RATE_BASIC_BIT BIT(7) /* mask bit for the rate belonging to the BSSBasicRateSet */ ++ ++/* 8.3.2.2 TKIP MPDU formats */ ++#define TKIP_MIC_LEN 8 ++ ++/* 9.2.10 DIFS */ ++#define DIFS 2 /* 2 x aSlotTime */ ++ ++/* 11.3 STA Authentication and Association */ ++#define STA_STATE_1 0 /* Accept Class 1 frames */ ++#define STA_STATE_2 1 /* Accept Class 1 & 2 frames */ ++#define STA_STATE_3 2 /* Accept Class 1,2 & 3 frames */ ++ ++/* 15.4.8.5 802.11k RCPI-dBm mapping*/ ++#define NDBM_LOW_BOUND_FOR_RCPI 110 ++#define RCPI_LOW_BOUND 0 ++#define RCPI_HIGH_BOUND 220 ++#define RCPI_MEASUREMENT_NOT_AVAILABLE 255 ++ ++/* PHY characteristics */ ++/* 17.4.4/18.3.3/19.8.4 Slot Time (aSlotTime) */ ++#define SLOT_TIME_LONG 20 /* Long Slot Time */ ++#define SLOT_TIME_SHORT 9 /* Short Slot Time */ ++ ++#define SLOT_TIME_HR_DSSS SLOT_TIME_LONG /* 802.11b aSlotTime */ ++#define SLOT_TIME_OFDM SLOT_TIME_SHORT /* 802.11a aSlotTime(20M Spacing) */ ++#define SLOT_TIME_OFDM_10M_SPACING 13 /* 802.11a aSlotTime(10M Spacing) */ ++#define SLOT_TIME_ERP_LONG SLOT_TIME_LONG /* 802.11g aSlotTime(Long) */ ++#define SLOT_TIME_ERP_SHORT SLOT_TIME_SHORT /* 802.11g aSlotTime(Short) */ ++ ++/* 17.4.4/18.3.3/19.8.4 Contention Window (aCWmin & aCWmax) */ ++#define CWMIN_OFDM 15 /* 802.11a aCWmin */ ++#define CWMAX_OFDM 1023 /* 802.11a aCWmax */ ++ ++#define CWMIN_HR_DSSS 31 /* 802.11b aCWmin */ ++#define CWMAX_HR_DSSS 1023 /* 802.11b aCWmax */ ++ ++#define CWMIN_ERP_0 31 /* 802.11g aCWmin(0) - for only have 1/2/5/11Mbps Rates */ ++#define CWMIN_ERP_1 15 /* 802.11g aCWmin(1) */ ++#define CWMAX_ERP 1023 /* 802.11g aCWmax */ ++ ++/* Short Inter-Frame Space (aSIFSTime) */ ++/* 15.3.3 802.11b aSIFSTime */ ++#define SIFS_TIME_HR_DSSS 10 ++/* 17.4.4 802.11a aSIFSTime */ ++#define SIFS_TIME_OFDM 16 ++/* 19.8.4 802.11g aSIFSTime */ ++#define SIFS_TIME_ERP 10 ++ ++/* 15.4.6.2 Number of operating channels */ ++#define CH_1 0x1 ++#define CH_2 0x2 ++#define CH_3 0x3 ++#define CH_4 0x4 ++#define CH_5 0x5 ++#define CH_6 0x6 ++#define CH_7 0x7 ++#define CH_8 0x8 ++#define CH_9 0x9 ++#define CH_10 0xa ++#define CH_11 0xb ++#define CH_12 0xc ++#define CH_13 0xd ++#define CH_14 0xe ++ ++#define MAXIMUM_OPERATION_CHANNEL_LIST 46 ++ ++/* 3 --------------- IEEE 802.11 PICS --------------- */ ++/* Annex D - dot11OperationEntry 2 */ ++#define DOT11_RTS_THRESHOLD_MIN 0 ++#define DOT11_RTS_THRESHOLD_MAX 2347 /* from Windows DDK */ ++/* #define DOT11_RTS_THRESHOLD_MAX 3000 // from Annex D */ ++ ++#define DOT11_RTS_THRESHOLD_DEFAULT \ ++ DOT11_RTS_THRESHOLD_MAX ++ ++/* Annex D - dot11OperationEntry 5 */ ++#define DOT11_FRAGMENTATION_THRESHOLD_MIN 256 ++#define DOT11_FRAGMENTATION_THRESHOLD_MAX 2346 /* from Windows DDK */ ++/* #define DOT11_FRAGMENTATION_THRESHOLD_MAX 3000 // from Annex D */ ++ ++#define DOT11_FRAGMENTATION_THRESHOLD_DEFAULT \ ++ DOT11_FRAGMENTATION_THRESHOLD_MAX ++ ++/* Annex D - dot11OperationEntry 6 */ ++#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MIN 1 ++#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MAX 0xFFFFffff ++#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_DEFAULT 4095 /* 802.11 define 512 */ ++ /* MT5921 only aceept N <= 4095 */ ++ ++/* Annex D - dot11OperationEntry 7 */ ++#define DOT11_RECEIVE_LIFETIME_TU_MIN 1 ++#define DOT11_RECEIVE_LIFETIME_TU_MAX 0xFFFFffff ++#define DOT11_RECEIVE_LIFETIME_TU_DEFAULT 4096 /* 802.11 define 512 */ ++ ++/* Annex D - dot11StationConfigEntry 12 */ ++#define DOT11_BEACON_PERIOD_MIN 1 /* TU. */ ++#define DOT11_BEACON_PERIOD_MAX 0xffff /* TU. */ ++#define DOT11_BEACON_PERIOD_DEFAULT 100 /* TU. */ ++ ++/* Annex D - dot11StationConfigEntry 13 */ ++#define DOT11_DTIM_PERIOD_MIN 1 /* TU. */ ++#define DOT11_DTIM_PERIOD_MAX 255 /* TU. */ ++#define DOT11_DTIM_PERIOD_DEFAULT 1 /* TU. */ ++ ++/* Annex D - dot11RegDomainsSupportValue */ ++#define REGULATION_DOMAIN_FCC 0x10 /* FCC (US) */ ++#define REGULATION_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ ++#define REGULATION_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ ++#define REGULATION_DOMAIN_SPAIN 0x31 /* Spain */ ++#define REGULATION_DOMAIN_FRANCE 0x32 /* France */ ++#define REGULATION_DOMAIN_JAPAN 0x40 /* MKK (Japan) */ ++#define REGULATION_DOMAIN_CHINA 0x50 /* China */ ++#define REGULATION_DOMAIN_OTHER 0x00 /* Other */ ++ ++/* 3 --------------- IEEE 802.11 MAC header fields --------------- */ ++/* 7.1.3.1 Masks for the subfields in the Frame Control field */ ++#define MASK_FC_PROTOCOL_VER BITS(0, 1) ++#define MASK_FC_TYPE BITS(2, 3) ++#define MASK_FC_SUBTYPE BITS(4, 7) ++#define MASK_FC_SUBTYPE_QOS_DATA BIT(7) ++#define MASK_FC_TO_DS BIT(8) ++#define MASK_FC_FROM_DS BIT(9) ++#define MASK_FC_MORE_FRAG BIT(10) ++#define MASK_FC_RETRY BIT(11) ++#define MASK_FC_PWR_MGT BIT(12) ++#define MASK_FC_MORE_DATA BIT(13) ++#define MASK_FC_PROTECTED_FRAME BIT(14) ++#define MASK_FC_ORDER BIT(15) ++ ++#define MASK_FRAME_TYPE (MASK_FC_TYPE | MASK_FC_SUBTYPE) ++#define MASK_TO_DS_FROM_DS (MASK_FC_TO_DS | MASK_FC_FROM_DS) ++ ++#define MAX_NUM_OF_FC_SUBTYPES 16 ++#define OFFSET_OF_FC_SUBTYPE 4 ++ ++/* 7.1.3.1.2 MAC frame types and subtypes */ ++#define MAC_FRAME_TYPE_MGT 0 ++#define MAC_FRAME_TYPE_CTRL BIT(2) ++#define MAC_FRAME_TYPE_DATA BIT(3) ++#define MAC_FRAME_TYPE_QOS_DATA (MAC_FRAME_TYPE_DATA | MASK_FC_SUBTYPE_QOS_DATA) ++ ++#define MAC_FRAME_ASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0000) ++#define MAC_FRAME_ASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0010) ++#define MAC_FRAME_REASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0020) ++#define MAC_FRAME_REASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0030) ++#define MAC_FRAME_PROBE_REQ (MAC_FRAME_TYPE_MGT | 0x0040) ++#define MAC_FRAME_PROBE_RSP (MAC_FRAME_TYPE_MGT | 0x0050) ++#define MAC_FRAME_BEACON (MAC_FRAME_TYPE_MGT | 0x0080) ++#define MAC_FRAME_ATIM (MAC_FRAME_TYPE_MGT | 0x0090) ++#define MAC_FRAME_DISASSOC (MAC_FRAME_TYPE_MGT | 0x00A0) ++#define MAC_FRAME_AUTH (MAC_FRAME_TYPE_MGT | 0x00B0) ++#define MAC_FRAME_DEAUTH (MAC_FRAME_TYPE_MGT | 0x00C0) ++#define MAC_FRAME_ACTION (MAC_FRAME_TYPE_MGT | 0x00D0) ++#define MAC_FRAME_ACTION_NO_ACK (MAC_FRAME_TYPE_MGT | 0x00E0) ++ ++#define MAC_FRAME_CONTRL_WRAPPER (MAC_FRAME_TYPE_CTRL | 0x0070) ++#define MAC_FRAME_BLOCK_ACK_REQ (MAC_FRAME_TYPE_CTRL | 0x0080) ++#define MAC_FRAME_BLOCK_ACK (MAC_FRAME_TYPE_CTRL | 0x0090) ++#define MAC_FRAME_PS_POLL (MAC_FRAME_TYPE_CTRL | 0x00A0) ++#define MAC_FRAME_RTS (MAC_FRAME_TYPE_CTRL | 0x00B0) ++#define MAC_FRAME_CTS (MAC_FRAME_TYPE_CTRL | 0x00C0) ++#define MAC_FRAME_ACK (MAC_FRAME_TYPE_CTRL | 0x00D0) ++#define MAC_FRAME_CF_END (MAC_FRAME_TYPE_CTRL | 0x00E0) ++#define MAC_FRAME_CF_END_CF_ACK (MAC_FRAME_TYPE_CTRL | 0x00F0) ++ ++#define MAC_FRAME_DATA (MAC_FRAME_TYPE_DATA | 0x0000) ++#define MAC_FRAME_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0010) ++#define MAC_FRAME_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0020) ++#define MAC_FRAME_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0030) ++#define MAC_FRAME_NULL (MAC_FRAME_TYPE_DATA | 0x0040) ++#define MAC_FRAME_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0050) ++#define MAC_FRAME_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0060) ++#define MAC_FRAME_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0070) ++#define MAC_FRAME_QOS_DATA (MAC_FRAME_TYPE_DATA | 0x0080) ++#define MAC_FRAME_QOS_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0090) ++#define MAC_FRAME_QOS_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00A0) ++#define MAC_FRAME_QOS_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00B0) ++#define MAC_FRAME_QOS_NULL (MAC_FRAME_TYPE_DATA | 0x00C0) ++#define MAC_FRAME_QOS_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00E0) ++#define MAC_FRAME_QOS_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00F0) ++ ++/* 7.1.3.2 Mask for the AID value in the Duration/ID field */ ++#define MASK_DI_DURATION BITS(0, 14) ++#define MASK_DI_AID BITS(0, 13) ++#define MASK_DI_AID_MSB BITS(14, 15) ++#define MASK_DI_CFP_FIXED_VALUE BIT(15) ++ ++/* 7.1.3.4 Masks for the subfields in the Sequence Control field */ ++#define MASK_SC_SEQ_NUM BITS(4, 15) ++#define MASK_SC_SEQ_NUM_OFFSET 4 ++#define MASK_SC_FRAG_NUM BITS(0, 3) ++#define INVALID_SEQ_CTRL_NUM 0x000F /* According to 6.2.1.1.2 ++ * FRAG_NUM won't equal to 15 ++ */ ++ ++/* 7.1.3.5 QoS Control field */ ++#define TID_NUM 16 ++#define TID_MASK BITS(0, 3) ++#define EOSP BIT(4) ++#define ACK_POLICY BITS(5, 6) ++#define A_MSDU_PRESENT BIT(7) ++ ++#define MASK_QC_TID BITS(0, 3) ++#define MASK_QC_EOSP BIT(4) ++#define MASK_QC_EOSP_OFFSET 4 ++#define MASK_QC_ACK_POLICY BITS(5, 6) ++#define MASK_QC_ACK_POLICY_OFFSET 5 ++#define MASK_QC_A_MSDU_PRESENT BIT(7) ++ ++/* 7.1.3.5a HT Control field */ ++#define HT_CTRL_LINK_ADAPTATION_CTRL BITS(0, 15) ++#define HT_CTRL_CALIBRATION_POSITION BITS(16, 17) ++#define HT_CTRL_CALIBRATION_SEQUENCE BITS(18, 19) ++#define HT_CTRL_CSI_STEERING BITS(22, 23) ++#define HT_CTRL_NDP_ANNOUNCEMENT BIT(24) ++#define HT_CTRL_AC_CONSTRAINT BIT(30) ++#define HT_CTRL_RDG_MORE_PPDU BIT(31) ++ ++#define LINK_ADAPTATION_CTRL_TRQ BIT(1) ++#define LINK_ADAPTATION_CTRL_MAI_MRQ BIT(2) ++#define LINK_ADAPTATION_CTRL_MAI_MSI BITS(3, 5) ++#define LINK_ADAPTATION_CTRL_MFSI BITS(6, 8) ++#define LINK_ADAPTATION_CTRL_MFB_ASELC_CMD BITS(9, 11) ++#define LINK_ADAPTATION_CTRL_MFB_ASELC_DATA BITS(12, 15) ++ ++/* 7.1.3.5.3 Ack Policy subfield*/ ++#define ACK_POLICY_NORMAL_ACK_IMPLICIT_BA_REQ 0 ++#define ACK_POLICY_NO_ACK 1 ++#define ACK_POLICY_NO_EXPLICIT_ACK_PSMP_ACK 2 ++#define ACK_POLICY_BA 3 ++ ++/* 7.1.3.7 FCS field */ ++#define FCS_LEN 4 ++ ++/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ ++#define PSPOLL_FRAME_LEN 16 /* w/o FCS */ ++ ++/* 7.2.7.1 BAR */ ++#define OFFSET_BAR_SSC_SN 4 ++ ++/* 8.3.2.2 TKIP MPDU formats */ ++#define TKIP_MIC_LEN 8 ++ ++/* 2009.11.30 mtk02468: Moved these definitions to the right place */ ++#if 0 ++/* Block Ack Parameter Set field */ ++#define BA_PARM_BA_POLICY BIT(1) ++#define BA_PARM_TID BITS(2, 5) ++#define BA_PARM_BUFFER_SIZE BITS(6, 15) ++#endif ++ ++#define BA_POLICY_IMMEDIATE BIT(1) ++ ++/* Block Ack Starting Sequence Control field */ ++#define BA_START_SEQ_CTL_FRAG_NUM BITS(0, 3) ++#define BA_START_SEQ_CTL_SSN BITS(4, 15) ++ ++/* BAR Control field */ ++#define BAR_CONTROL_NO_ACK_POLICY BIT(0) ++#define BAR_CONTROL_MULTI_TID BIT(1) ++#define BAR_CONTROL_COMPRESSED_BA BIT(2) ++#define BAR_CONTROL_TID_INFO BITS(12, 15) ++#define BAR_CONTROL_TID_INFO_OFFSET 12 ++ ++/* TID Value */ ++#define BAR_INFO_TID_VALUE BITS(12, 15) ++ ++#define BAR_COMPRESSED_VARIANT_FRAME_LEN (16 + 4) ++ ++/* 3 --------------- IEEE 802.11 frame body fields --------------- */ ++/* 3 Management frame body components (I): Fixed Fields. */ ++/* 7.3.1.1 Authentication Algorithm Number field */ ++#define AUTH_ALGORITHM_NUM_FIELD_LEN 2 ++ ++#define AUTH_ALGORITHM_NUM_OPEN_SYSTEM 0 /* Open System */ ++#define AUTH_ALGORITHM_NUM_SHARED_KEY 1 /* Shared Key */ ++#define AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION 2 /* Fast BSS Transition */ ++ ++/* 7.3.1.2 Authentication Transaction Sequence Number field */ ++#define AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN 2 ++#define AUTH_TRANSACTION_SEQ_1 1 ++#define AUTH_TRANSACTION_SEQ_2 2 ++#define AUTH_TRANSACTION_SEQ_3 3 ++#define AUTH_TRANSACTION_SEQ_4 4 ++ ++/* 7.3.1.3 Beacon Interval field */ ++#define BEACON_INTERVAL_FIELD_LEN 2 ++ ++/* 7.3.1.4 Capability Information field */ ++#define CAP_INFO_FIELD_LEN 2 ++#define CAP_INFO_ESS BIT(0) ++#define CAP_INFO_IBSS BIT(1) ++#define CAP_INFO_BSS_TYPE (CAP_INFO_ESS | CAP_INFO_IBSS) ++#define CAP_INFO_CF_POLLABLE BIT(2) ++#define CAP_INFO_CF_POLL_REQ BIT(3) ++#define CAP_INFO_CF (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) ++#define CAP_INFO_PRIVACY BIT(4) ++#define CAP_INFO_SHORT_PREAMBLE BIT(5) ++#define CAP_INFO_PBCC BIT(6) ++#define CAP_INFO_CH_AGILITY BIT(7) ++#define CAP_INFO_SPEC_MGT BIT(8) ++#define CAP_INFO_QOS BIT(9) ++#define CAP_INFO_SHORT_SLOT_TIME BIT(10) ++#define CAP_INFO_APSD BIT(11) ++#define CAP_INFO_RESERVED BIT(12) ++#define CAP_INFO_DSSS_OFDM BIT(13) ++#define CAP_INFO_DELAYED_BLOCK_ACK BIT(14) ++#define CAP_INFO_IMM_BLOCK_ACK BIT(15) ++/* STA usage of CF-Pollable and CF-Poll Request subfields */ ++/* STA: not CF-Pollable */ ++#define CAP_CF_STA_NOT_POLLABLE 0x0000 ++/* STA: CF-Pollable, not requesting on the CF-Polling list */ ++#define CAP_CF_STA_NOT_ON_LIST CAP_INFO_CF_POLL_REQ ++/* STA: CF-Pollable, requesting on the CF-Polling list */ ++#define CAP_CF_STA_ON_LIST CAP_INFO_CF_POLLABLE ++/* STA: CF-Pollable, requesting never to be polled */ ++#define CAP_CF_STA_NEVER_POLLED (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) ++ ++/* AP usage of CF-Pollable and CF-Poll Request subfields */ ++/* AP: No point coordinator (PC) */ ++#define CAP_CF_AP_NO_PC 0x0000 ++/* AP: PC at AP for delivery only (no polling) */ ++#define CAP_CF_AP_DELIVERY_ONLY CAP_INFO_CF_POLL_REQ ++/* AP: PC at AP for delivery and polling */ ++#define CAP_CF_AP_DELIVERY_POLLING CAP_INFO_CF_POLLABLE ++ ++/* 7.3.1.5 Current AP Address field */ ++#define CURR_AP_ADDR_FIELD_LEN MAC_ADDR_LEN ++ ++/* 7.3.1.6 Listen Interval field */ ++#define LISTEN_INTERVAL_FIELD_LEN 2 ++ ++/* 7.3.1.7 Reason Code field */ ++#define REASON_CODE_FIELD_LEN 2 ++ ++#define REASON_CODE_RESERVED 0 /* Reseved */ ++#define REASON_CODE_UNSPECIFIED 1 /* Unspecified reason */ ++#define REASON_CODE_PREV_AUTH_INVALID 2 /* Previous auth no longer valid */ ++#define REASON_CODE_DEAUTH_LEAVING_BSS 3 /* Deauth because sending STA is leaving BSS */ ++#define REASON_CODE_DISASSOC_INACTIVITY 4 /* Disassoc due to inactivity */ ++#define REASON_CODE_DISASSOC_AP_OVERLOAD 5 /* Disassoc because AP is unable to handle all assoc STAs */ ++#define REASON_CODE_CLASS_2_ERR 6 /* Class 2 frame rx from nonauth STA */ ++#define REASON_CODE_CLASS_3_ERR 7 /* Class 3 frame rx from nonassoc STA */ ++#define REASON_CODE_DISASSOC_LEAVING_BSS 8 /* Disassoc because sending STA is leaving BSS */ ++#define REASON_CODE_ASSOC_BEFORE_AUTH 9 /* STA requesting (re)assoc is not auth with responding STA */ ++#define REASON_CODE_DISASSOC_PWR_CAP_UNACCEPTABLE 10 /* Disassoc because the info in Power Capability is ++ unacceptable */ ++#define REASON_CODE_DISASSOC_SUP_CHS_UNACCEPTABLE 11 /* Disassoc because the info in Supported Channels is ++ unacceptable */ ++#define REASON_CODE_INVALID_INFO_ELEM 13 /* Invalid information element */ ++#define REASON_CODE_MIC_FAILURE 14 /* MIC failure */ ++#define REASON_CODE_4_WAY_HANDSHAKE_TIMEOUT 15 /* 4-way handshake timeout */ ++#define REASON_CODE_GROUP_KEY_UPDATE_TIMEOUT 16 /* Group key update timeout */ ++#define REASON_CODE_DIFFERENT_INFO_ELEM 17 /* Info element in 4-way handshake different from ++ (Re-)associate request/Probe response/Beacon */ ++#define REASON_CODE_MULTICAST_CIPHER_NOT_VALID 18 /* Multicast Cipher is not valid */ ++#define REASON_CODE_UNICAST_CIPHER_NOT_VALID 19 /* Unicast Cipher is not valid */ ++#define REASON_CODE_AKMP_NOT_VALID 20 /* AKMP is not valid */ ++#define REASON_CODE_UNSUPPORTED_RSNE_VERSION 21 /* Unsupported RSNE version */ ++#define REASON_CODE_INVALID_RSNE_CAPABILITIES 22 /* Invalid RSNE Capabilities */ ++#define REASON_CODE_IEEE_802_1X_AUTH_FAILED 23 /* IEEE 802.1X Authentication failed */ ++#define REASON_CODE_CIPHER_REJECT_SEC_POLICY 24 /* Cipher suite rejected because of the security policy */ ++#define REASON_CODE_DISASSOC_UNSPECIFIED_QOS 32 /* Disassoc for unspecified, QoS-related reason */ ++#define REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH 33 /* Disassoc because QAP lacks sufficient bandwidth ++ for this QSTA */ ++#define REASON_CODE_DISASSOC_ACK_LOST_POOR_CHANNEL 34 /* Disassoc because of too many ACKs lost for AP transmissions ++ and/or poor channel conditions */ ++#define REASON_CODE_DISASSOC_TX_OUTSIDE_TXOP_LIMIT 35 /* Disassoc because QSTA is transmitting outside the limits of ++ its TXOPs */ ++#define REASON_CODE_PEER_WHILE_LEAVING 36 /* QSTA is leaving the QBSS or resetting */ ++#define REASON_CODE_PEER_REFUSE_DLP 37 /* Peer does not want to use this mechanism */ ++#define REASON_CODE_PEER_SETUP_REQUIRED 38 /* Frames received but a setup is reqired */ ++#define REASON_CODE_PEER_TIME_OUT 39 /* Time out */ ++#define REASON_CODE_PEER_CIPHER_UNSUPPORTED 45 /* Peer does not support the requested cipher suite */ ++#define REASON_CODE_BEACON_TIMEOUT 100 /* for beacon timeout, defined by mediatek */ ++#define REASON_CODE_BSS_SECURITY_CHANGE 101 /* for BSS security change, defined by mediatek */ ++/* 7.3.1.8 AID field */ ++#define AID_FIELD_LEN 2 ++#define AID_MASK BITS(0, 13) ++#define AID_MSB BITS(14, 15) ++#define AID_MIN_VALUE 1 ++#define AID_MAX_VALUE 2007 ++ ++/* 7.3.1.9 Status Code field */ ++#define STATUS_CODE_FIELD_LEN 2 ++ ++#define STATUS_CODE_RESERVED 0 /* Reserved - Used by TX Auth */ ++#define STATUS_CODE_SUCCESSFUL 0 /* Successful */ ++#define STATUS_CODE_UNSPECIFIED_FAILURE 1 /* Unspecified failure */ ++#define STATUS_CODE_CAP_NOT_SUPPORTED 10 /* Cannot support all requested cap in the Cap Info field */ ++#define STATUS_CODE_REASSOC_DENIED_WITHOUT_ASSOC 11 /* Reassoc denied due to inability to confirm that ++ assoc exists */ ++#define STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD 12 /* Assoc denied due to reason outside the scope of this std. */ ++#define STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED 13 /* Responding STA does not support the specified ++ auth algorithm */ ++#define STATUS_CODE_AUTH_OUT_OF_SEQ 14 /* Rx an auth frame with auth transaction seq num ++ out of expected seq */ ++#define STATUS_CODE_AUTH_REJECTED_CHAL_FAIL 15 /* Auth rejected because of challenge failure */ ++#define STATUS_CODE_AUTH_REJECTED_TIMEOUT 16 /* Auth rejected due to timeout waiting for next frame ++ in sequence */ ++#define STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD 17 /* Assoc denied because AP is unable to handle additional ++ assoc STAs */ ++#define STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED 18 /* Assoc denied due to requesting STA not supporting ++ all of basic rates */ ++#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_PREAMBLE 19 /* Assoc denied due to requesting STA not supporting short ++ preamble */ ++#define STATUS_CODE_ASSOC_DENIED_NO_PBCC 20 /* Assoc denied due to requesting STA not supporting PBCC */ ++#define STATUS_CODE_ASSOC_DENIED_NO_CH_AGILITY 21 /* Assoc denied due to requesting STA not supporting channel ++ agility */ ++#define STATUS_CODE_ASSOC_REJECTED_NO_SPEC_MGT 22 /* Assoc rejected because Spectrum Mgt capability is required */ ++#define STATUS_CODE_ASSOC_REJECTED_PWR_CAP 23 /* Assoc rejected because the info in Power Capability ++ is unacceptable */ ++#define STATUS_CODE_ASSOC_REJECTED_SUP_CHS 24 /* Assoc rejected because the info in Supported Channels ++ is unacceptable */ ++#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 /* Assoc denied due to requesting STA not supporting ++ short slot time */ ++#define STATUS_CODE_ASSOC_DENIED_NO_DSSS_OFDM 26 /* Assoc denied due to requesting STA not supporting ++ DSSS-OFDM */ ++#if CFG_SUPPORT_802_11W ++#define STATUS_CODE_ASSOC_REJECTED_TEMPORARILY 30 /* IEEE 802.11w, Assoc denied due to the SA query */ ++#define STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 /* IEEE 802.11w, Assoc denied due to the MFP select ++ policy */ ++#endif ++#define STATUS_CODE_UNSPECIFIED_QOS_FAILURE 32 /* Unspecified, QoS-related failure */ ++#define STATUS_CODE_ASSOC_DENIED_BANDWIDTH 33 /* Assoc denied due to insufficient bandwidth to handle another ++ QSTA */ ++#define STATUS_CODE_ASSOC_DENIED_POOR_CHANNEL 34 /* Assoc denied due to excessive frame loss rates and/or poor ++ channel conditions */ ++#define STATUS_CODE_ASSOC_DENIED_NO_QOS_FACILITY 35 /* Assoc denied due to requesting STA not supporting QoS ++ facility */ ++#define STATUS_CODE_REQ_DECLINED 37 /* Request has been declined */ ++#define STATUS_CODE_REQ_INVALID_PARAMETER_VALUE 38 /* Request has not been successful as one or more parameters ++ have invalid values */ ++#define STATUS_CODE_REQ_NOT_HONORED_TSPEC 39 /* TS not created because request cannot be honored. ++ Suggested TSPEC provided. */ ++#define STATUS_CODE_INVALID_INFO_ELEMENT 40 /* Invalid information element */ ++#define STATUS_CODE_INVALID_GROUP_CIPHER 41 /* Invalid group cipher */ ++#define STATUS_CODE_INVALID_PAIRWISE_CIPHER 42 /* Invalid pairwise cipher */ ++#define STATUS_CODE_INVALID_AKMP 43 /* Invalid AKMP */ ++#define STATUS_CODE_UNSUPPORTED_RSN_IE_VERSION 44 /* Unsupported RSN information element version */ ++#define STATUS_CODE_INVALID_RSN_IE_CAP 45 /* Invalid RSN information element capabilities */ ++#define STATUS_CODE_CIPHER_SUITE_REJECTED 46 /* Cipher suite rejected because of security policy */ ++#define STATUS_CODE_REQ_NOT_HONORED_TS_DELAY 47 /* TS not created because request cannot be honored. ++ Attempt to create a TS later. */ ++#define STATUS_CODE_DIRECT_LINK_NOT_ALLOWED 48 /* Direct Link is not allowed in the BSS by policy */ ++#define STATUS_CODE_DESTINATION_STA_NOT_PRESENT 49 /* Destination STA is not present within this QBSS */ ++#define STATUS_CODE_DESTINATION_STA_NOT_QSTA 50 /* Destination STA is not a QSTA */ ++#define STATUS_CODE_ASSOC_DENIED_LARGE_LIS_INTERVAL 51 /* Association denied because the ListenInterval is too large */ ++ ++/* proprietary definition of reserved field of Status Code */ ++#define STATUS_CODE_JOIN_FAILURE 0xFFF0 /* Join failure */ ++#define STATUS_CODE_JOIN_TIMEOUT 0xFFF1 /* Join timeout */ ++#define STATUS_CODE_AUTH_TIMEOUT 0xFFF2 /* Authentication timeout */ ++#define STATUS_CODE_ASSOC_TIMEOUT 0xFFF3 /* (Re)Association timeout */ ++#define STATUS_CODE_CCX_CCKM_REASSOC_FAILURE 0xFFF4 /* CCX CCKM reassociation failure */ ++ ++/* 7.3.1.10 Timestamp field */ ++#define TIMESTAMP_FIELD_LEN 8 ++ ++/* 7.3.1.11 Category of Action field */ ++#define CATEGORY_SPEC_MGT 0 ++#define CATEGORY_QOS_ACTION 1 /* QoS action */ ++#define CATEGORY_DLS_ACTION 2 /* Direct Link Protocol (DLP) action */ ++#define CATEGORY_BLOCK_ACK_ACTION 3 /* Block ack action */ ++#define CATEGORY_PUBLIC_ACTION 4 /* Public action */ ++#define CATEGORY_RM_ACTION 5 /* Radio measurement action */ ++#define CATEGORY_HT_ACTION 7 ++#if CFG_SUPPORT_802_11W ++#define CATEGORY_SA_QUERT_ACTION 8 ++#endif ++#define CATEGORY_WNM_ACTION 10 /* 802.11v Wireless Network Management */ ++#define CATEGORY_UNPROTECTED_WNM_ACTION 11 /* 802.11v Wireless Network Management */ ++#define CATEGORY_WME_MGT_NOTIFICATION 17 /* WME management notification */ ++#define CATEGORY_VENDOR_SPECIFIC_ACTION 127 ++ ++/* 7.3.1.14 Block Ack Parameter Set field */ ++#define BA_PARAM_SET_ACK_POLICY_MASK BIT(1) ++#define BA_PARAM_SET_ACK_POLICY_MASK_OFFSET 1 ++#define BA_PARAM_SET_TID_MASK BITS(2, 5) ++#define BA_PARAM_SET_TID_MASK_OFFSET 2 ++#define BA_PARAM_SET_BUFFER_SIZE_MASK BITS(6, 15) ++#define BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET 6 ++ ++#define BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA 1 ++#define BA_PARAM_SET_ACK_POLICY_DELAYED_BA 0 ++ ++/* 3 Management frame body components (II): Information Elements. */ ++/* 7.3.2 Element IDs of information elements */ ++#define ELEM_HDR_LEN 2 ++ ++#define ELEM_ID_SSID 0 /* SSID */ ++#define ELEM_ID_SUP_RATES 1 /* Supported rates */ ++#define ELEM_ID_FH_PARAM_SET 2 /* FH parameter set */ ++#define ELEM_ID_DS_PARAM_SET 3 /* DS parameter set */ ++#define ELEM_ID_CF_PARAM_SET 4 /* CF parameter set */ ++#define ELEM_ID_TIM 5 /* TIM */ ++#define ELEM_ID_IBSS_PARAM_SET 6 /* IBSS parameter set */ ++#define ELEM_ID_COUNTRY_INFO 7 /* Country information */ ++#define ELEM_ID_HOPPING_PATTERN_PARAM 8 /* Hopping pattern parameters */ ++#define ELEM_ID_HOPPING_PATTERN_TABLE 9 /* Hopping pattern table */ ++#define ELEM_ID_REQUEST 10 /* Request */ ++#define ELEM_ID_BSS_LOAD 11 /* BSS load */ ++#define ELEM_ID_EDCA_PARAM_SET 12 /* EDCA parameter set */ ++#define ELEM_ID_TSPEC 13 /* Traffic specification (TSPEC) */ ++#define ELEM_ID_TCLAS 14 /* Traffic classification (TCLAS) */ ++#define ELEM_ID_SCHEDULE 15 /* Schedule */ ++#define ELEM_ID_CHALLENGE_TEXT 16 /* Challenge text */ ++ ++#define ELEM_ID_PWR_CONSTRAINT 32 /* Power constraint */ ++#define ELEM_ID_PWR_CAP 33 /* Power capability */ ++#define ELEM_ID_TPC_REQ 34 /* TPC request */ ++#define ELEM_ID_TPC_REPORT 35 /* TPC report */ ++#define ELEM_ID_SUP_CHS 36 /* Supported channels */ ++#define ELEM_ID_CH_SW_ANNOUNCEMENT 37 /* Channel switch announcement */ ++#define ELEM_ID_MEASUREMENT_REQ 38 /* Measurement request */ ++#define ELEM_ID_MEASUREMENT_REPORT 39 /* Measurement report */ ++#define ELEM_ID_QUIET 40 /* Quiet */ ++#define ELEM_ID_IBSS_DFS 41 /* IBSS DFS */ ++#define ELEM_ID_ERP_INFO 42 /* ERP information */ ++#define ELEM_ID_TS_DELAY 43 /* TS delay */ ++#define ELEM_ID_TCLAS_PROCESSING 44 /* TCLAS processing */ ++#define ELEM_ID_HT_CAP 45 /* HT Capabilities subelement */ ++#define ELEM_ID_QOS_CAP 46 /* QoS capability */ ++#define ELEM_ID_RSN 48 /* RSN IE */ ++#define ELEM_ID_EXTENDED_SUP_RATES 50 /* Extended supported rates */ ++#define ELEM_ID_TIMEOUT_INTERVAL 56 /* 802.11w SA Timeout interval */ ++#define ELEM_ID_SUP_OPERATING_CLASS 59 /* Supported Operating Classes */ ++#define ELEM_ID_HT_OP 61 /* HT Operation */ ++#define ELEM_ID_SCO 62 /* Secondary Channel Offset */ ++#define ELEM_ID_RRM_ENABLED_CAP 70 /* Radio Resource Management Enabled Capabilities */ ++#define ELEM_ID_20_40_BSS_COEXISTENCE 72 /* 20/40 BSS Coexistence */ ++#define ELEM_ID_20_40_INTOLERANT_CHNL_REPORT 73 /* 20/40 BSS Intolerant Channel Report */ ++#define ELEM_ID_OBSS_SCAN_PARAMS 74 /* Overlapping BSS Scan Parameters */ ++#define ELEM_ID_INTERWORKING 107 /* Interworking with External Network */ ++#define ELEM_ID_ADVERTISEMENT_PROTOCOL 108 /* Advertisement Protocol */ ++#define ELEM_ID_ROAMING_CONSORTIUM 111 /* Roaming Consortium */ ++#define ELEM_ID_EXTENDED_CAP 127 /* Extended capabilities */ ++ ++#define ELEM_ID_VENDOR 221 /* Vendor specific IE */ ++#define ELEM_ID_WPA ELEM_ID_VENDOR /* WPA IE */ ++#define ELEM_ID_WMM ELEM_ID_VENDOR /* WMM IE */ ++#define ELEM_ID_P2P ELEM_ID_VENDOR /* WiFi Direct */ ++#define ELEM_ID_WFD ELEM_ID_VENDOR /* WiFi Direct */ ++#define ELEM_ID_WSC ELEM_ID_VENDOR /* WSC IE */ ++ ++#define ELEM_ID_RESERVED 255 /* Reserved */ ++ ++/* 7.3.2.1 SSID element */ ++#define ELEM_MAX_LEN_SSID 32 ++ ++/* 7.3.2.2 Supported Rates */ ++#define ELEM_MAX_LEN_SUP_RATES 8 ++ ++/* 7.3.2.4 DS Parameter Set */ ++#define ELEM_MAX_LEN_DS_PARAMETER_SET 1 ++ ++/* 7.3.2.5 CF Parameter Set */ ++#define ELEM_CF_PARM_LEN 8 ++ ++/* 7.3.2.6 TIM */ ++#define ELEM_MIX_LEN_TIM 4 ++#define ELEM_MAX_LEN_TIM 254 ++ ++/* 7.3.2.7 IBSS Parameter Set element */ ++#define ELEM_MAX_LEN_IBSS_PARAMETER_SET 2 ++ ++/* 7.3.2.8 Challenge Text element */ ++#define ELEM_MIN_LEN_CHALLENGE_TEXT 1 ++#define ELEM_MAX_LEN_CHALLENGE_TEXT 253 ++ ++/* 7.3.2.9 Country Information element */ ++/* Country IE should contain at least 3-bytes country code string and one subband triplet. */ ++#define ELEM_MIN_LEN_COUNTRY_INFO 6 ++ ++#define ELEM_ID_COUNTRY_INFO_TRIPLET_LEN_FIXED 3 ++#define ELEM_ID_COUNTRY_INFO_SUBBAND_TRIPLET_LEN_FIXED 3 ++#define ELEM_ID_COUNTRY_INFO_REGULATORY_TRIPLET_LEN_FIXED 3 ++ ++/* 7.3.2.13 ERP Information element */ ++#define ELEM_MAX_LEN_ERP 1 ++/* -- bits in the ERP Information element */ ++#define ERP_INFO_NON_ERP_PRESENT BIT(0) /* NonERP_Present bit */ ++#define ERP_INFO_USE_PROTECTION BIT(1) /* Use_Protection bit */ ++#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) /* Barker_Preamble_Mode bit */ ++ ++/* 7.3.2.14 Extended Supported Rates */ ++#define ELEM_MAX_LEN_EXTENDED_SUP_RATES 255 ++ ++#if CFG_SUPPORT_DFS ++/* 7.3.2.19 Supported Channels element */ ++#define ELEM_MAX_LEN_SUPPORTED_CHANNELS 7 ++#endif ++ ++/* 7.3.2.21 Measurement Request element */ ++#define ELEM_RM_TYPE_BASIC_REQ 0 ++#define ELEM_RM_TYPE_CCA_REQ 1 ++#define ELEM_RM_TYPE_RPI_HISTOGRAM_REQ 2 ++#define ELEM_RM_TYPE_CHNL_LOAD_REQ 3 ++#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REQ 4 ++#define ELEM_RM_TYPE_BEACON_REQ 5 ++#define ELEM_RM_TYPE_FRAME_REQ 6 ++#define ELEM_RM_TYPE_STA_STATISTICS_REQ 7 ++#define ELEM_RM_TYPE_LCI_REQ 8 ++#define ELEM_RM_TYPE_TS_REQ 9 ++#define ELEM_RM_TYPE_MEASURE_PAUSE_REQ 255 ++ ++/* 7.3.2.22 Measurement Report element */ ++#define ELEM_RM_TYPE_BASIC_REPORT 0 ++#define ELEM_RM_TYPE_CCA_REPORT 1 ++#define ELEM_RM_TYPE_RPI_HISTOGRAM_REPORT 2 ++#define ELEM_RM_TYPE_CHNL_LOAD_REPORT 3 ++#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REPORT 4 ++#define ELEM_RM_TYPE_BEACON_REPORT 5 ++#define ELEM_RM_TYPE_FRAME_REPORT 6 ++#define ELEM_RM_TYPE_STA_STATISTICS_REPORT 7 ++#define ELEM_RM_TYPE_LCI_REPORT 8 ++#define ELEM_RM_TYPE_TS_REPORT 9 ++/*Auto Channel Selection*/ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++#define ELEM_RM_TYPE_ACS_CHN 1 ++#define ELEM_RM_TYPE_LTE_CHN 2 ++#endif ++ ++/* 7.3.2.25 RSN information element */ ++#define ELEM_MAX_LEN_WPA 34 /* one pairwise, one AKM suite, one PMKID */ ++#define ELEM_MAX_LEN_RSN 38 /* one pairwise, one AKM suite, one PMKID */ ++#define ELEM_MAX_LEN_WAPI 38 /* one pairwise, one AKM suite, one BKID */ ++#define ELEM_MAX_LEN_WSC 200 /* one pairwise, one AKM suite, one BKID */ ++ ++#if CFG_SUPPORT_802_11W ++#define ELEM_WPA_CAP_MFPR BIT(6) ++#define ELEM_WPA_CAP_MFPC BIT(7) ++#endif ++ ++/* 7.3.2.27 Extended Capabilities information element */ ++#define ELEM_EXT_CAP_20_40_COEXIST_SUPPORT BIT(0) ++#define ELEM_EXT_CAP_PSMP_CAP BIT(4) ++#define ELEM_EXT_CAP_SERVICE_INTERVAL_GRANULARITY BIT(5) ++#define ELEM_EXT_CAP_SCHEDULE_PSMP BIT(6) ++ ++#define ELEM_EXT_CAP_BSS_TRANSITION_BIT 19 ++#define ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT 27 ++#define ELEM_EXT_CAP_INTERWORKING_BIT 31 ++#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT 46 ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++#define ELEM_MAX_LEN_EXT_CAP (6) ++#else ++#define ELEM_MAX_LEN_EXT_CAP (3 - ELEM_HDR_LEN) ++#endif ++ ++/* 7.3.2.30 TSPEC element */ ++#define TS_INFO_TRAFFIC_TYPE_MASK BIT(0) /* WMM: 0 (Asynchronous TS of low-duty cycles) */ ++#define TS_INFO_TID_OFFSET 1 ++#define TS_INFO_TID_MASK BITS(1, 4) ++#define TS_INFO_DIRECTION_OFFSET 5 ++#define TS_INFO_DIRECTION_MASK BITS(5, 6) ++#define TS_INFO_ACCESS_POLICY_OFFSET 7 ++#define TS_INFO_ACCESS_POLICY_MASK BITS(7, 8) ++#define TS_INFO_AGGREGATION_MASK BIT(9) /* WMM: 0 */ ++#define TS_INFO_APSD_MASK BIT(10) ++#define TS_INFO_UP_OFFSET 11 ++#define TS_INFO_UP_MASK BITS(11, 13) ++#define TS_INFO_ACK_POLICY_OFFSET 14 ++#define TS_INFO_ACK_POLICY_MASK BITS(14, 15) ++#define TS_INFO_SCHEDULE_MASK 16 ++ ++/* 7.3.2.56 HT capabilities element */ ++#define ELEM_MAX_LEN_HT_CAP (28 - ELEM_HDR_LEN) /* sizeof(IE_HT_CAP_T)-2 */ ++ ++/* 7.3.2.56.2 HT capabilities Info field */ ++#define HT_CAP_INFO_LDPC_CAP BIT(0) ++#define HT_CAP_INFO_SUP_CHNL_WIDTH BIT(1) ++#define HT_CAP_INFO_SM_POWER_SAVE BITS(2, 3) ++#define HT_CAP_INFO_HT_GF BIT(4) ++#define HT_CAP_INFO_SHORT_GI_20M BIT(5) ++#define HT_CAP_INFO_SHORT_GI_40M BIT(6) ++#define HT_CAP_INFO_TX_STBC BIT(7) ++#define HT_CAP_INFO_RX_STBC BITS(8, 9) ++#define HT_CAP_INFO_HT_DELAYED_BA BIT(10) ++#define HT_CAP_INFO_MAX_AMSDU_LEN BIT(11) ++#define HT_CAP_INFO_DSSS_CCK_IN_40M BIT(12) ++#define HT_CAP_INFO_40M_INTOLERANT BIT(14) ++#define HT_CAP_INFO_LSIG_TXOP_SUPPORT BIT(15) ++ ++#define HT_CAP_INFO_RX_STBC_NO_SUPPORTED 0 ++#define HT_CAP_INFO_RX_STBC_1_SS BIT(8) ++#define HT_CAP_INFO_RX_STBC_2_SS BIT(9) ++#define HT_CAP_INFO_RX_STBC_3_SS HT_CAP_INFO_RX_STBC ++ ++/* 7.3.2.56.3 A-MPDU Parameters field */ ++#define AMPDU_PARAM_MAX_AMPDU_LEN_EXP BITS(0, 1) ++#define AMPDU_PARAM_MIN_START_SPACING BITS(2, 4) ++ ++#define AMPDU_PARAM_MAX_AMPDU_LEN_8K 0 ++#define AMPDU_PARAM_MAX_AMPDU_LEN_16K BIT(0) ++#define AMPDU_PARAM_MAX_AMPDU_LEN_32K BIT(1) ++#define AMPDU_PARAM_MAX_AMPDU_LEN_64K BITS(0, 1) ++ ++#define AMPDU_PARAM_MSS_NO_RESTRICIT 0 ++#define AMPDU_PARAM_MSS_1_4_US BIT(2) ++#define AMPDU_PARAM_MSS_1_2_US BIT(3) ++#define AMPDU_PARAM_MSS_1_US BITS(2, 3) ++#define AMPDU_PARAM_MSS_2_US BIT(4) ++#define AMPDU_PARAM_MSS_4_US (BIT(4) | BIT(2)) ++#define AMPDU_PARAM_MSS_8_US (BIT(4) | BIT(3)) ++#define AMPDU_PARAM_MSS_16_US BITS(2, 4) ++ ++/* 7.3.2.56.4 Supported MCS Set field (TX rate: octects 12~15) */ ++#define SUP_MCS_TX_SET_DEFINED BIT(0) ++#define SUP_MCS_TX_RX_SET_NOT_EQUAL BIT(1) ++#define SUP_MCS_TX_MAX_NUM_SS BITS(2, 3) ++#define SUP_MCS_TX_UNEQUAL_MODULATION BIT(4) ++ ++#define SUP_MCS_TX_MAX_NUM_1_SS 0 ++#define SUP_MCS_TX_MAX_NUM_2_SS BIT(2) ++#define SUP_MCS_TX_MAX_NUM_3_SS BIT(3) ++#define SUP_MCS_TX_MAX_NUM_4_SS BITS(2, 3) ++ ++#define SUP_MCS_RX_BITMASK_OCTET_NUM 10 ++#define SUP_MCS_RX_DEFAULT_HIGHEST_RATE 0 /* Not specify */ ++ ++/* 7.3.2.56.5 HT Extended Capabilities field */ ++#define HT_EXT_CAP_PCO BIT(0) ++#define HT_EXT_CAP_PCO_TRANSITION_TIME BITS(1, 2) ++#define HT_EXT_CAP_MCS_FEEDBACK BITS(8, 9) ++#define HT_EXT_CAP_HTC_SUPPORT BIT(10) ++#define HT_EXT_CAP_RD_RESPONDER BIT(11) ++ ++#define HT_EXT_CAP_PCO_TRANS_TIME_NONE 0 ++#define HT_EXT_CAP_PCO_TRANS_TIME_400US BIT(1) ++#define HT_EXT_CAP_PCO_TRANS_TIME_1_5MS BIT(2) ++#define HT_EXT_CAP_PCO_TRANS_TIME_5MS BITS(1, 2) ++ ++#define HT_EXT_CAP_MCS_FEEDBACK_NO_FB 0 ++#define HT_EXT_CAP_MCS_FEEDBACK_UNSOLICITED BIT(9) ++#define HT_EXT_CAP_MCS_FEEDBACK_BOTH BITS(8, 9) ++ ++/* 7.3.2.56.6 Transmit Beamforming Capabilities field */ ++ ++/* 7.3.2.56.7 Antenna Selection Capability field */ ++#define ASEL_CAP_CAPABLE BIT(0) ++#define ASEL_CAP_CSI_FB_BY_TX_ASEL_CAPABLE BIT(1) ++#define ASEL_CAP_ANT_INDICES_FB_BY_TX_ASEL_CAPABLE BIT(2) ++#define ASEL_CAP_EXPLICIT_CSI_FB_CAPABLE BIT(3) ++#define ASEL_CAP_ANT_INDICES_CAPABLE BIT(4) ++#define ASEL_CAP_RX_ASEL_CAPABLE BIT(5) ++#define ASEL_CAP_TX_SOUNDING_CAPABLE BIT(6) ++ ++/* 7.3.2.57 HT Operation element */ ++#define ELEM_MAX_LEN_HT_OP (24 - ELEM_HDR_LEN) /* sizeof(IE_HT_OP_T)-2 */ ++ ++#define HT_OP_INFO1_SCO BITS(0, 1) ++#define HT_OP_INFO1_STA_CHNL_WIDTH BIT(2) ++#define HT_OP_INFO1_RIFS_MODE BIT(3) ++ ++#define HT_OP_INFO2_HT_PROTECTION BITS(0, 1) ++#define HT_OP_INFO2_NON_GF_HT_STA_PRESENT BIT(2) ++#define HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT BIT(4) ++ ++#define HT_OP_INFO3_DUAL_BEACON BIT(6) ++#define HT_OP_INFO3_DUAL_CTS_PROTECTION BIT(7) ++#define HT_OP_INFO3_STBC_BEACON BIT(8) ++#define HT_OP_INFO3_LSIG_TXOP_FULL_SUPPORT BIT(9) ++#define HT_OP_INFO3_PCO_ACTIVE BIT(10) ++#define HT_OP_INFO3_PCO_PHASE BIT(11) ++ ++/* 7.3.2.59 OBSS Scan Parameter element */ ++#define ELEM_MAX_LEN_OBSS_SCAN (16 - ELEM_HDR_LEN) ++ ++/* 7.3.2.60 20/40 BSS Coexistence element */ ++#define ELEM_MAX_LEN_20_40_BSS_COEXIST (3 - ELEM_HDR_LEN) ++ ++#define BSS_COEXIST_INFO_REQ BIT(0) ++#define BSS_COEXIST_40M_INTOLERANT BIT(1) ++#define BSS_COEXIST_20M_REQ BIT(2) ++#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ BIT(3) ++#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_GRANT BIT(4) ++ ++/* 802.11u 7.3.2.92 Interworking IE */ ++#define ELEM_MAX_LEN_INTERWORKING (11 - ELEM_HDR_LEN) ++ ++/* 802.11u 7.3.2.93 Advertisement Protocol IE */ ++#define ELEM_MAX_LEN_ADV_PROTOCOL (4 - ELEM_HDR_LEN) ++ ++/* 802.11u 7.3.2.96 Roaming Consortium IE */ ++#define ELEM_MAX_LEN_ROAMING_CONSORTIUM (19 - ELEM_HDR_LEN) ++ ++#define IW_IE_LENGTH_ANO 1 ++#define IW_IE_LENGTH_ANO_VENUE 3 ++#define IW_IE_LENGTH_ANO_HESSID 7 ++#define IW_IE_LENGTH_ANO_VENUE_HESSID 9 ++ ++/* 3 Management frame body components (III): 7.4 Action frame format details. */ ++/* 7.4.1 Spectrum Measurement Action frame details */ ++#define ACTION_MEASUREMENT_REQ 0 /* Spectrum measurement request */ ++#define ACTION_MEASUREMENT_REPORT 1 /* Spectrum measurement report */ ++#define ACTION_TPC_REQ 2 /* TPC request */ ++#define ACTION_TPC_REPORT 3 /* TPC report */ ++#define ACTION_CHNL_SWITCH 4 /* Channel Switch Announcement */ ++ ++/* 7.4.2 QoS Action frame details */ ++#define ACTION_ADDTS_REQ 0 /* ADDTS request */ ++#define ACTION_ADDTS_RSP 1 /* ADDTS response */ ++#define ACTION_DELTS 2 /* DELTS */ ++#define ACTION_SCHEDULE 3 /* Schedule */ ++ ++#define ACTION_ADDTS_REQ_FRAME_LEN (24+3+63) /* WMM TSPEC IE: 63 */ ++#define ACTION_ADDTS_RSP_FRAME_LEN (24+4+63) /* WMM Status Code: 1; WMM TSPEC IE: 63 */ ++ ++/* 7.4.3 DLS Action frame details */ ++#define ACTION_DLS_REQ 0 /* DLS request */ ++#define ACTION_DLS_RSP 1 /* DLS response */ ++#define ACTION_DLS_TEARDOWN 2 /* DLS teardown */ ++ ++/* 7.4.4 Block ack Action frame details */ ++#define ACTION_ADDBA_REQ 0 /* ADDBA request */ ++#define ACTION_ADDBA_RSP 1 /* ADDBA response */ ++#define ACTION_DELBA 2 /* DELBA */ ++ ++#define ACTION_ADDBA_REQ_FRAME_LEN (24+9) ++#define ACTION_ADDBA_RSP_FRAME_LEN (24+9) ++ ++#define ACTION_DELBA_INITIATOR_MASK BIT(11) ++#define ACTION_DELBA_TID_MASK BITS(12, 15) ++#define ACTION_DELBA_TID_OFFSET 12 ++#define ACTION_DELBA_FRAME_LEN (24+6) ++ ++/* 7.4.6 Radio Measurement Action frame details */ ++#define ACTION_RM_REQ 0 /* Radio measurement request */ ++#define ACTION_RM_REPORT 1 /* Radio measurement report */ ++#define ACTION_LM_REQ 2 /* Link measurement request */ ++#define ACTION_LM_REPORT 3 /* Link measurement report */ ++#define ACTION_NEIGHBOR_REPORT_REQ 4 /* Neighbor report request */ ++#define ACTION_NEIGHBOR_REPORT_RSP 5 /* Neighbor report response */ ++ ++/* 7.4.7 Public Action frame details */ ++#define ACTION_PUBLIC_20_40_COEXIST 0 /* 20/40 BSS coexistence */ ++ ++#if CFG_SUPPORT_802_11W ++/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ ++#define ACTION_SA_QUERY_REQUEST 0 ++#define ACTION_SA_QUERY_RESPONSE 1 ++ ++#define ACTION_SA_QUERY_TR_ID_LEN 2 ++ ++/* Timeout Interval Type */ ++#define ACTION_SA_TIMEOUT_REASSOC_DEADLINE 1 ++#define ACTION_SA_TIMEOUT_KEY_LIFETIME 2 ++#define ACTION_SA_TIMEOUT_ASSOC_COMEBACK 3 ++#endif ++ ++/* 7.4.10.1 HT action frame details */ ++#define ACTION_HT_NOTIFY_CHANNEL_WIDTH 0 /* Notify Channel Width */ ++#define ACTION_HT_SM_POWER_SAVE 1 /* SM Power Save */ ++#define ACTION_HT_PSMP 2 /* PSMP */ ++#define ACTION_HT_SET_PCO_PHASE 3 /* Set PCO Phase */ ++#define ACTION_HT_CSI 4 /* CSI */ ++#define ACTION_HT_NON_COMPRESSED_BEAMFORM 5 /* Non-compressed Beamforming */ ++#define ACTION_HT_COMPRESSED_BEAMFORM 6 /* Compressed Beamforming */ ++#define ACTION_HT_ANT_SEL_INDICES_FB 7 /* Antenna Selection Indices Feedback */ ++ ++/* 802.11v Wireless Network Management */ ++#define ACTION_WNM_TIMING_MEASUREMENT_REQUEST 27 ++ ++#define ACTION_UNPROTECTED_WNM_TIM 0 ++#define ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT 1 ++ ++#define ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN 12 ++ ++/* 3 --------------- WFA frame body fields --------------- */ ++#define VENDOR_OUI_WFA { 0x00, 0x50, 0xF2 } ++#define VENDOR_OUI_WFA_SPECIFIC { 0x50, 0x6F, 0x9A } ++#define VENDOR_OUI_TYPE_WPA 1 ++#define VENDOR_OUI_TYPE_WMM 2 ++#define VENDOR_OUI_TYPE_WPS 4 ++#define VENDOR_OUI_TYPE_P2P 9 ++#define VENDOR_OUI_TYPE_WFD 10 ++#define VENDOR_OUI_TYPE_HS20 16 ++ ++#define VENDOR_OUI_TYPE_LEN 4 /* Length of OUI and Type */ ++ ++/* VERSION(2 octets for WPA) / SUBTYPE(1 octet)-VERSION(1 octet) fields for WMM in WFA IE */ ++#define VERSION_WPA 0x0001 /* Little Endian Format */ ++#define VENDOR_OUI_SUBTYPE_VERSION_WMM_INFO 0x0100 ++#define VENDOR_OUI_SUBTYPE_VERSION_WMM_PARAM 0x0101 ++ ++/* SUBTYPE(1 octet) for WMM */ ++#define VENDOR_OUI_SUBTYPE_WMM_INFO 0x00 /* WMM Spec version 1.1 */ ++#define VENDOR_OUI_SUBTYPE_WMM_PARAM 0x01 ++#define VENDOR_OUI_SUBTYPE_WMM_TSPEC 0x02 ++ ++/* VERSION(1 octet) for WMM */ ++#define VERSION_WMM 0x01 /* WMM Spec version 1.1 */ ++ ++/* WMM-2.1.6 QoS Control Field */ ++#define WMM_QC_UP_MASK BITS(0, 2) ++#define WMM_QC_EOSP BIT(4) ++#define WMM_QC_ACK_POLICY_MASK BITS(5, 6) ++#define WMM_QC_ACK_POLICY_OFFSET 5 ++#define WMM_QC_ACK_POLICY_ACKNOWLEDGE 0 ++#define WMM_QC_ACK_POLICY_NOT_ACKNOWLEDGE (1 << WMM_QC_ACK_POLICY_OFFSET) ++ ++/* WMM-2.2.1 WMM Information Element */ ++#define ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE 6 ++ ++/* HOTSPOT 2.0 Indication IE*/ ++#define ELEM_MAX_LEN_HS20_INDICATION 5 ++#define ELEM_MIN_LEN_HS20_INDICATION 4 ++ ++/* Hotspot Configuration*/ ++#define ELEM_HS_CONFIG_DGAF_DISABLED_MASK BIT(0) /* Downstream Group-Addressed Forwarding */ ++ ++/* 3 Control frame body */ ++/* 7.2.1.7 BlockAckReq */ ++#define CTRL_BAR_BAR_CONTROL_OFFSET 16 ++#define CTRL_BAR_BAR_INFORMATION_OFFSET 18 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack(1) ++#endif ++ ++typedef struct _LLC_SNAP_HEADER_T { ++ UINT_8 ucDSAP; ++ UINT_8 ucSSAP; ++ UINT_8 ucControl; ++ UINT_8 aucCode[3]; ++ UINT_16 u2Type; ++} __KAL_ATTRIB_PACKED__ LLC_SNAP_HEADER_T, *P_LLC_SNAP_HEADER_T; ++ ++/* 3 MAC Header. */ ++/* Ethernet Frame Header */ ++typedef struct _ETH_FRAME_HEADER_T { ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; ++ UINT_16 u2TypeLen; ++} __KAL_ATTRIB_PACKED__ ETH_FRAME_HEADER_T, *P_ETH_FRAME_HEADER_T; ++ ++/* Ethernet Frame Structure */ ++typedef struct _ETH_FRAME_T { ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; ++ UINT_16 u2TypeLen; ++ UINT_8 aucData[1]; ++} __KAL_ATTRIB_PACKED__ ETH_FRAME_T, *P_ETH_FRAME_T; ++ ++/* IEEE 802.11 WLAN Frame Structure */ ++/* WLAN MAC Header (without Address 4 and QoS Control fields) */ ++typedef struct _WLAN_MAC_HEADER_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_T, *P_WLAN_MAC_HEADER_T; ++ ++/* WLAN MAC Header (QoS Control fields included) */ ++typedef struct _WLAN_MAC_HEADER_QOS_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_16 u2QosCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_QOS_T, *P_WLAN_MAC_HEADER_QOS_T; ++ ++/* WLAN MAC Header (HT Control fields included) */ ++typedef struct _WLAN_MAC_HEADER_HT_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_16 u2QosCtrl; ++ UINT_32 u4HtCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_HT_T, *P_WLAN_MAC_HEADER_HT_T; ++ ++/* WLAN MAC Header (Address 4 included) */ ++typedef struct _WLAN_MAC_HEADER_A4_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_8 aucAddr4[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_T, *P_WLAN_MAC_HEADER_A4_T; ++ ++/* WLAN MAC Header (Address 4 and QoS Control fields included) */ ++typedef struct _WLAN_MAC_HEADER_A4_QOS_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_8 aucAddr4[MAC_ADDR_LEN]; ++ UINT_16 u2QosCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_QOS_T, *P_WLAN_MAC_HEADER_A4_QOS_T; ++ ++typedef struct _WLAN_MAC_HEADER_A4_HT_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_8 aucAddr4[MAC_ADDR_LEN]; ++ UINT_16 u2QosCtrl; ++ UINT_32 u4HtCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_HT_T, *P_WLAN_MAC_HEADER_A4_HT_T; ++ ++/* 7.2.3 WLAN MAC Header for Management Frame - MMPDU */ ++typedef struct _WLAN_MAC_MGMT_HEADER_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2Duration; ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_T, *P_WLAN_MAC_MGMT_HEADER_T; ++ ++/* WLAN MAC Header for Management Frame (HT Control fields included) */ ++typedef struct _WLAN_MAC_MGMT_HEADER_HT_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_32 u4HtCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_HT_T, *P_WLAN_MAC_MGMT_HEADER_HT_T; ++ ++/* 3 WLAN CONTROL Frame */ ++/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ ++typedef struct _CTRL_PSPOLL_FRAME_T { ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2AID; /* AID */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_8 aucTA[MAC_ADDR_LEN]; /* TA */ ++} __KAL_ATTRIB_PACKED__ CTRL_PSPOLL_FRAME_T, *P_CTRL_PSPOLL_FRAME_T; ++ ++/* BAR */ ++typedef struct _CTRL_BAR_FRAME_T { ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* RA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* TA */ ++ UINT_16 u2BarControl; ++ UINT_8 aucBarInfo[2]; /* Variable size */ ++} __KAL_ATTRIB_PACKED__ CTRL_BAR_FRAME_T, *P_CTRL_BAR_FRAME_T; ++ ++/* 3 WLAN Management Frame. */ ++/* 7.2.3.1 WLAN Management Frame - Beacon Frame */ ++typedef struct _WLAN_BEACON_FRAME_T { ++ /* Beacon header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Beacon frame body */ ++ UINT_32 au4Timestamp[2]; /* Timestamp */ ++ UINT_16 u2BeaconInterval; /* Beacon Interval */ ++ UINT_16 u2CapInfo; /* Capability */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ ++} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_T, *P_WLAN_BEACON_FRAME_T; ++ ++typedef struct _WLAN_BEACON_FRAME_BODY_T { ++ /* Beacon frame body */ ++ UINT_32 au4Timestamp[2]; /* Timestamp */ ++ UINT_16 u2BeaconInterval; /* Beacon Interval */ ++ UINT_16 u2CapInfo; /* Capability */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ ++} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_BODY_T, *P_WLAN_BEACON_FRAME_BODY_T; ++ ++/* 7.2.3.3 WLAN Management Frame - Disassociation Frame */ ++typedef struct _WLAN_DISASSOC_FRAME_T { ++ /* Authentication MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Disassociation frame body */ ++ UINT_16 u2ReasonCode; /* Reason code */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ ++} __KAL_ATTRIB_PACKED__ WLAN_DISASSOC_FRAME_T, *P_WLAN_DISASSOC_FRAME_T; ++ ++/* 7.2.3.4 WLAN Management Frame - Association Request frame */ ++typedef struct _WLAN_ASSOC_REQ_FRAME_T { ++ /* Association Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Association Request frame body */ ++ UINT_16 u2CapInfo; /* Capability information */ ++ UINT_16 u2ListenInterval; /* Listen interval */ ++ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ ++} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_REQ_FRAME_T, *P_WLAN_ASSOC_REQ_FRAME_T; ++ ++/* 7.2.3.5 WLAN Management Frame - Association Response frame */ ++typedef struct _WLAN_ASSOC_RSP_FRAME_T { ++ /* Association Response MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Association Response frame body */ ++ UINT_16 u2CapInfo; /* Capability information */ ++ UINT_16 u2StatusCode; /* Status code */ ++ UINT_16 u2AssocId; /* Association ID */ ++ UINT_8 aucInfoElem[1]; /* Information elements, such as ++ supported rates, and etc. */ ++} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_RSP_FRAME_T, *P_WLAN_ASSOC_RSP_FRAME_T; ++ ++/* 7.2.3.6 WLAN Management Frame - Reassociation Request frame */ ++typedef struct _WLAN_REASSOC_REQ_FRAME_T { ++ /* Reassociation Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Reassociation Request frame body */ ++ UINT_16 u2CapInfo; /* Capability information */ ++ UINT_16 u2ListenInterval; /* Listen interval */ ++ UINT_8 aucCurrentAPAddr[MAC_ADDR_LEN]; /* Current AP address */ ++ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ ++} __KAL_ATTRIB_PACKED__ WLAN_REASSOC_REQ_FRAME_T, *P_WLAN_REASSOC_REQ_FRAME_T; ++ ++/* 7.2.3.7 WLAN Management Frame - Reassociation Response frame ++ (the same as Association Response frame) */ ++typedef WLAN_ASSOC_RSP_FRAME_T WLAN_REASSOC_RSP_FRAME_T, *P_WLAN_REASSOC_RSP_FRAME_T; ++ ++/* 7.2.3.9 WLAN Management Frame - Probe Response Frame */ ++typedef WLAN_BEACON_FRAME_T WLAN_PROBE_RSP_FRAME_T, *P_WLAN_PROBE_RSP_FRAME_T; ++ ++/* 7.2.3.10 WLAN Management Frame - Authentication Frame */ ++typedef struct _WLAN_AUTH_FRAME_T { ++ /* Authentication MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Authentication frame body */ ++ UINT_16 u2AuthAlgNum; /* Authentication algorithm number */ ++ UINT_16 u2AuthTransSeqNo; /* Authentication transaction sequence number */ ++ UINT_16 u2StatusCode; /* Status code */ ++ UINT_8 aucInfoElem[1]; /* Various IEs for Fast BSS Transition */ ++} __KAL_ATTRIB_PACKED__ WLAN_AUTH_FRAME_T, *P_WLAN_AUTH_FRAME_T; ++ ++/* 7.2.3.11 WLAN Management Frame - Deauthentication Frame */ ++typedef struct _WLAN_DEAUTH_FRAME_T { ++ /* Authentication MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Deauthentication frame body */ ++ UINT_16 u2ReasonCode; /* Reason code */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ ++} __KAL_ATTRIB_PACKED__ WLAN_DEAUTH_FRAME_T, *P_WLAN_DEAUTH_FRAME_T; ++ ++/* 3 Information Elements. */ ++/* 7.3.2 Generic element format */ ++typedef struct _IE_HDR_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucInfo[1]; ++} __KAL_ATTRIB_PACKED__ IE_HDR_T, *P_IE_HDR_T; ++ ++/* 7.3.2.1 SSID element */ ++typedef struct _IE_SSID_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++} __KAL_ATTRIB_PACKED__ IE_SSID_T, *P_IE_SSID_T; ++ ++/* 7.3.2.2 Supported Rates element */ ++typedef struct _IE_SUPPORTED_RATE_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucSupportedRates[ELEM_MAX_LEN_SUP_RATES]; ++} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_RATE_T, *P_IE_SUPPORTED_RATE_T; ++ ++/* 7.3.2.4 DS Parameter Set element */ ++typedef struct _IE_DS_PARAM_SET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCurrChnl; ++} __KAL_ATTRIB_PACKED__ IE_DS_PARAM_SET_T, *P_IE_DS_PARAM_SET_T; ++ ++/* 7.3.2.5 CF Parameter Set element */ ++typedef struct _IE_CF_PARAM_SET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCFPCount; ++ UINT_8 ucCFPPeriod; ++ UINT_16 u2CFPMaxDur; ++ UINT_16 u2DurRemaining; ++} __KAL_ATTRIB_PACKED__ IE_CF_PARAM_SET_T, *P_IE_CF_PARAM_SET_T; ++ ++/* 7.3.2.6 TIM */ ++typedef struct _IE_TIM_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucDTIMCount; ++ UINT_8 ucDTIMPeriod; ++ UINT_8 ucBitmapControl; ++ UINT_8 aucPartialVirtualMap[1]; ++} __KAL_ATTRIB_PACKED__ IE_TIM_T, *P_IE_TIM_T; ++ ++/* 7.3.2.7 IBSS Parameter Set element */ ++typedef struct _IE_IBSS_PARAM_SET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_16 u2ATIMWindow; ++} __KAL_ATTRIB_PACKED__ IE_IBSS_PARAM_SET_T, *P_IE_IBSS_PARAM_SET_T; ++ ++/* 7.3.2.8 Challenge Text element */ ++typedef struct _IE_CHALLENGE_TEXT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucChallengeText[ELEM_MAX_LEN_CHALLENGE_TEXT]; ++} __KAL_ATTRIB_PACKED__ IE_CHALLENGE_TEXT_T, *P_IE_CHALLENGE_TEXT_T; ++ ++/* 7.3.2.9 Country information element */ ++#if CFG_SUPPORT_802_11D ++/*! \brief COUNTRY_INFO_TRIPLET is defined for the COUNTRY_INFO_ELEM structure. */ ++typedef struct _COUNTRY_INFO_TRIPLET_T { ++ UINT_8 ucParam1; /*!< If param1 >= 201, this triplet is referred to as ++ Regulatory Triplet in 802_11J. */ ++ UINT_8 ucParam2; ++ UINT_8 ucParam3; ++} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_TRIPLET_T, *P_COUNTRY_INFO_TRIPLET_T; ++ ++typedef struct _COUNTRY_INFO_SUBBAND_TRIPLET_T { ++ UINT_8 ucFirstChnlNum; /*!< First Channel Number */ ++ UINT_8 ucNumOfChnl; /*!< Number of Channels */ ++ INT_8 cMaxTxPwrLv; /*!< Maximum Transmit Power Level */ ++} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_SUBBAND_TRIPLET_T, *P_COUNTRY_INFO_SUBBAND_TRIPLET_T; ++ ++typedef struct _COUNTRY_INFO_REGULATORY_TRIPLET_T { ++ UINT_8 ucRegExtId; /*!< Regulatory Extension Identifier, should ++ be greater than or equal to 201 */ ++ UINT_8 ucRegClass; /*!< Regulatory Class */ ++ UINT_8 ucCoverageClass; /*!< Coverage Class, unsigned 1-octet value 0~31 ++ , 32~255 reserved */ ++} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_REGULATORY_TRIPLET_T, *P_COUNTRY_INFO_REGULATORY_TRIPLET_T; ++ ++typedef struct _IE_COUNTRY_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCountryStr[3]; ++ COUNTRY_INFO_SUBBAND_TRIPLET_T arCountryStr[1]; ++} __KAL_ATTRIB_PACKED__ IE_COUNTRY_T, *P_IE_COUNTRY_T; ++#endif /* CFG_SUPPORT_802_11D */ ++ ++/* 7.3.2.13 ERP element */ ++typedef struct _IE_ERP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucERP; ++} __KAL_ATTRIB_PACKED__ IE_ERP_T, *P_IE_ERP_T; ++ ++/* 7.3.2.14 Extended Supported Rates element */ ++typedef struct _IE_EXT_SUPPORTED_RATE_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucExtSupportedRates[ELEM_MAX_LEN_EXTENDED_SUP_RATES]; ++} __KAL_ATTRIB_PACKED__ IE_EXT_SUPPORTED_RATE_T, *P_IE_EXT_SUPPORTED_RATE_T; ++ ++/* 7.3.2.15 Power Constraint element */ ++typedef struct _IE_POWER_CONSTRAINT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucLocalPowerConstraint; /* Unit: dBm */ ++} __KAL_ATTRIB_PACKED__ IE_POWER_CONSTRAINT_T, *P_IE_POWER_CONSTRAINT_T; ++ ++/* 7.3.2.16 Power Capability element */ ++typedef struct _IE_POWER_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ INT_8 cMinTxPowerCap; /* Unit: dBm */ ++ INT_8 cMaxTxPowerCap; /* Unit: dBm */ ++} __KAL_ATTRIB_PACKED__ IE_POWER_CAP_T, *P_IE_POWER_CAP_T; ++ ++/* 7.3.2.17 TPC request element */ ++typedef struct _IE_TPC_REQ_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++} __KAL_ATTRIB_PACKED__ IE_TPC_REQ_T, *P_IE_TPC_REQ_T; ++ ++/* 7.3.2.18 TPC report element */ ++typedef struct _IE_TPC_REPORT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ INT_8 cTxPower; /* Unit: dBm */ ++ INT_8 cLinkMargin; /* Unit: dB */ ++} __KAL_ATTRIB_PACKED__ IE_TPC_REPORT_T, *P_IE_TPC_REPORT_T; ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++/* 7.3.2.19 Supported Channels element*/ ++typedef struct _IE_SUPPORTED_CHANNELS_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucChannelNum[ELEM_MAX_LEN_SUPPORTED_CHANNELS * 2]; ++} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_CHANNELS_T, *P_IE_SUPPORTED_CHANNELS_T; ++ ++/* 7.3.2.20 Channel Switch Announcement element*/ ++typedef struct _IE_CHANNEL_SWITCH_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucChannelSwitchMode; ++ UINT_8 ucNewChannelNum; ++ UINT_8 ucChannelSwitchCount; ++} __KAL_ATTRIB_PACKED__ IE_CHANNEL_SWITCH_T, *P_IE_CHANNEL_SWITCH_T; ++#endif ++ ++/* 7.3.2.21 Measurement Request element */ ++typedef struct _IE_MEASUREMENT_REQ_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucToken; ++ UINT_8 ucRequestMode; ++ UINT_8 ucMeasurementType; ++ UINT_8 aucRequestFields[1]; ++} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REQ_T, *P_IE_MEASUREMENT_REQ_T; ++ ++typedef struct _SM_BASIC_REQ_T { ++ UINT_8 ucChannel; ++ UINT_32 au4StartTime[2]; ++ UINT_16 u2Duration; ++} __KAL_ATTRIB_PACKED__ SM_BASIC_REQ_T, *P_SM_BASIC_REQ_T; ++ ++/* SM_COMMON_REQ_T is not specified in Spec. Use it as common structure of SM */ ++typedef SM_BASIC_REQ_T SM_REQ_COMMON_T, *P_SM_REQ_COMMON_T; ++typedef SM_BASIC_REQ_T SM_CCA_REQ_T, *P_SM_CCA_REQ_T; ++typedef SM_BASIC_REQ_T SM_RPI_HISTOGRAM_REQ_T, *P_SM_RPI_HISTOGRAM_REQ_T; ++ ++typedef struct _RM_CHNL_LOAD_REQ_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REQ_T, *P_RM_CHNL_LOAD_REQ_T; ++ ++typedef RM_CHNL_LOAD_REQ_T RM_NOISE_HISTOGRAM_REQ_T, *P_RM_NOISE_HISTOGRAM_REQ_T; ++ ++typedef struct _RM_BCN_REQ_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 ucMeasurementMode; ++ UINT_8 aucBssid[6]; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_BCN_REQ_T, *P_RM_BCN_REQ_T; ++ ++typedef struct _RM_FRAME_REQ_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 ucFrameReqType; ++ UINT_8 aucMacAddr[6]; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_FRAME_REQ_T, *P_RM_FRAME_REQ_T; ++ ++typedef struct _RM_STA_STATS_REQ_T { ++ UINT_8 aucPeerMacAddr[6]; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 ucGroupID; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_STA_STATS_REQ_T, *P_RM_STA_STATS_REQ_T; ++ ++typedef struct _RM_LCI_REQ_T { ++ UINT_8 ucLocationSubject; ++ UINT_8 ucLatitudeResolution; ++ UINT_8 ucLongitudeResolution; ++ UINT_8 ucAltitudeResolution; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_LCI_REQ_T, *P_RM_LCI_REQ_T; ++ ++typedef struct _RM_TS_MEASURE_REQ_T { ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 aucPeerStaAddr[6]; ++ UINT_8 ucTrafficID; ++ UINT_8 ucBin0Range; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_TS_MEASURE_REQ_T, *P_RM_TS_MEASURE_REQ_T; ++ ++typedef struct _RM_MEASURE_PAUSE_REQ_T { ++ UINT_16 u2PauseTime; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_MEASURE_PAUSE_REQ_T, *P_RM_MEASURE_PAUSE_REQ_T; ++ ++/* 7.3.2.22 Measurement Report element */ ++typedef struct _IE_MEASUREMENT_REPORT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucToken; ++ UINT_8 ucReportMode; ++ UINT_8 ucMeasurementType; ++ UINT_8 aucReportFields[1]; ++} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REPORT_T, *P_IE_MEASUREMENT_REPORT_T; ++ ++typedef struct _SM_BASIC_REPORT_T { ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucMap; ++} __KAL_ATTRIB_PACKED__ SM_BASIC_REPORT_T, *P_SM_BASIC_REPORT_T; ++ ++typedef struct _SM_CCA_REPORT_T { ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucCcaBusyFraction; ++} __KAL_ATTRIB_PACKED__ SM_CCA_REPORT_T, *P_SM_CCA_REPORT_T; ++ ++typedef struct _SM_RPI_REPORT_T { ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 aucRPI[8]; ++} __KAL_ATTRIB_PACKED__ SM_RPI_REPORT_T, *P_SM_RPI_REPORT_T; ++ ++typedef struct _RM_CHNL_LOAD_REPORT_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucChnlLoad; ++} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REPORT_T, *P_RM_CHNL_LOAD_REPORT_T; ++ ++typedef struct _RM_IPI_REPORT_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucAntennaId; ++ INT_8 cANPI; ++ UINT_8 aucIPI[11]; ++} __KAL_ATTRIB_PACKED__ RM_IPI_REPORT_T, *P_RM_IPI_REPORT_T; ++ ++/* 7.3.2.23 Quiet element */ ++typedef struct _IE_QUIET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCount; ++ UINT_8 ucPeriod; ++ UINT_16 u2Duration; ++ UINT_16 u2Offset; ++} __KAL_ATTRIB_PACKED__ IE_QUIET_T, *P_IE_QUIET_T; ++ ++/* 7.3.2.27 Extended Capabilities element */ ++typedef struct _IE_EXT_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCapabilities[5]; ++} __KAL_ATTRIB_PACKED__ IE_EXT_CAP_T, *P_EXT_CAP_T; ++ ++/* 7.3.2.27 hs20 Extended Capabilities element */ ++typedef struct _IE_HS20_EXT_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCapabilities[6]; ++} __KAL_ATTRIB_PACKED__ IE_HS20_EXT_CAP_T, *P_HS20_EXT_CAP_T; ++ ++ ++/* 7.3.2.27 Extended Capabilities element */ ++typedef struct _IE_RRM_ENABLED_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCap[5]; ++} __KAL_ATTRIB_PACKED__ IE_RRM_ENABLED_CAP_T, *P_IE_RRM_ENABLED_CAP_T; ++ ++/* 7.3.2.51 Timeout Interval element (TIE) */ ++typedef struct _IE_TIMEOUT_INTERVAL_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++#define IE_TIMEOUT_INTERVAL_TYPE_RESERVED 0 ++#define IE_TIMEOUT_INTERVAL_TYPE_REASSOC 1 ++#define IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME 2 ++#define IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK 3 ++ UINT_8 ucType; ++ UINT_32 u4Value; ++} __KAL_ATTRIB_PACKED__ IE_TIMEOUT_INTERVAL_T; ++ ++/* 7.3.2.56 HT Capabilities element */ ++typedef struct _SUP_MCS_SET_FIELD { ++ UINT_8 aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM]; ++ UINT_16 u2RxHighestSupportedRate; ++ UINT_32 u4TxRateInfo; ++} __KAL_ATTRIB_PACKED__ SUP_MCS_SET_FIELD, *P_SUP_MCS_SET_FIELD; ++ ++typedef struct _IE_HT_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_16 u2HtCapInfo; ++ UINT_8 ucAmpduParam; ++ SUP_MCS_SET_FIELD rSupMcsSet; ++ UINT_16 u2HtExtendedCap; ++ UINT_32 u4TxBeamformingCap; ++ UINT_8 ucAselCap; ++} __KAL_ATTRIB_PACKED__ IE_HT_CAP_T, *P_IE_HT_CAP_T; ++ ++/* 7.3.2.57 HT Operation element */ ++typedef struct _IE_HT_OP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucInfo1; ++ UINT_16 u2Info2; ++ UINT_16 u2Info3; ++ UINT_8 aucBasicMcsSet[16]; ++} __KAL_ATTRIB_PACKED__ IE_HT_OP_T, *P_IE_HT_OP_T; ++ ++/* 7.3.2.25 RSN Information element format */ ++typedef struct _RSN_INFO_ELEM_T { ++ UCHAR ucElemId; ++ UCHAR ucLength; ++ UINT_16 u2Version; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_16 u2PairwiseKeyCipherSuiteCount; ++ UCHAR aucPairwiseKeyCipherSuite1[4]; ++} __KAL_ATTRIB_PACKED__ RSN_INFO_ELEM_T, *P_RSN_INFO_ELEM_T; ++ ++/* 7.3.2.26 WPA Information element format */ ++typedef struct _WPA_INFO_ELEM_T { ++ UCHAR ucElemId; ++ UCHAR ucLength; ++ UCHAR aucOui[3]; ++ UCHAR ucOuiType; ++ UINT_16 u2Version; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_16 u2PairwiseKeyCipherSuiteCount; ++ UCHAR aucPairwiseKeyCipherSuite1[4]; ++} __KAL_ATTRIB_PACKED__ WPA_INFO_ELEM_T, *P_WPA_INFO_ELEM_T; ++ ++/* 7.3.2.58 20/40 BSS Intolerant Channel Report element */ ++typedef struct _IE_INTOLERANT_CHNL_REPORT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucRegulatoryClass; ++ UINT_8 aucChannelList[1]; ++} __KAL_ATTRIB_PACKED__ IE_INTOLERANT_CHNL_REPORT_T, *P_IE_INTOLERANT_CHNL_REPORT_T; ++ ++/* 7.3.2.59 OBSS Scan Parameters element */ ++typedef struct _IE_OBSS_SCAN_PARAM_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_16 u2ScanPassiveDwell; ++ UINT_16 u2ScanActiveDwell; ++ UINT_16 u2TriggerScanInterval; ++ UINT_16 u2ScanPassiveTotalPerChnl; ++ UINT_16 u2ScanActiveTotalPerChnl; ++ UINT_16 u2WidthTransDelayFactor; ++ UINT_16 u2ScanActivityThres; ++} __KAL_ATTRIB_PACKED__ IE_OBSS_SCAN_PARAM_T, *P_IE_OBSS_SCAN_PARAM_T; ++ ++/* 7.3.2.60 20/40 BSS Coexistence element */ ++typedef struct _IE_20_40_COEXIST_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucData; ++} __KAL_ATTRIB_PACKED__ IE_20_40_COEXIST_T, *P_IE_20_40_COEXIST_T; ++ ++/* 7.3.2.60 20/40 BSS Coexistence element */ ++typedef struct _IE_SUP_OPERATING_CLASS_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCur; ++ UINT_8 ucSup[255]; ++} __KAL_ATTRIB_PACKED__ IE_SUP_OPERATING_CLASS_T, *P_IE_SUP_OPERATING_CLASS_T; ++ ++/* 3 7.4 Action Frame. */ ++/* 7.4 Action frame format */ ++typedef struct _WLAN_ACTION_FRAME { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucActionDetails[1]; /* Action details */ ++} __KAL_ATTRIB_PACKED__ WLAN_ACTION_FRAME, *P_WLAN_ACTION_FRAME; ++ ++/* 7.4.1.1 Spectrum Measurement Request frame format */ ++typedef struct _ACTION_SM_REQ_FRAME { ++ /* ADDTS Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 aucInfoElem[1]; /* Information elements */ ++} __KAL_ATTRIB_PACKED__ ACTION_SM_REQ_FRAME, *P_ACTION_SM_REQ_FRAME; ++ ++/* 7.4.1.2 Spectrum Measurement Report frame format */ ++typedef ACTION_SM_REQ_FRAME ACTION_SM_REPORT_FRAME, *P_ACTION_SM_REPORT_FRAME; ++ ++/* 7.4.1.5 Channel Switch Announcement frame format */ ++typedef struct _ACTION_CHANNEL_SWITCH_FRAME { ++ /* ADDTS Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 aucInfoElem[5]; /* Information elements */ ++} __KAL_ATTRIB_PACKED__ _ACTION_CHANNEL_SWITCH_FRAME, *P_ACTION_CHANNEL_SWITCH_FRAME; ++ ++/* 7.4.2.1 ADDTS Request frame format */ ++typedef struct _ACTION_ADDTS_REQ_FRAME { ++ /* ADDTS Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 aucInfoElem[1]; /* Information elements, such as ++ TS Delay, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_REQ_FRAME, *P_ACTION_ADDTS_REQ_FRAME; ++ ++/* 7.4.2.2 ADDTS Response frame format */ ++typedef struct _ACTION_ADDTS_RSP_FRAME { ++ /* ADDTS Response MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Response frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 ucStatusCode; /* WMM Status Code is of one byte */ ++ UINT_8 aucInfoElem[1]; /* Information elements, such as ++ TS Delay, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_RSP_FRAME, *P_ACTION_ADDTS_RSP_FRAME; ++ ++/* 7.4.2.3 DELTS frame format */ ++typedef struct _ACTION_DELTS_FRAME { ++ /* DELTS MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* DELTS frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 aucTsInfo[3]; /* TS Info */ ++} __KAL_ATTRIB_PACKED__ ACTION_DELTS_FRAME, *P_ACTION_DELTS_FRAME; ++ ++/* 7.4.4.1 ADDBA Request frame format */ ++typedef struct _ACTION_ADDBA_REQ_FRAME_T { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ ++ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ ++ UINT_8 aucBATimeoutValue[2]; ++ UINT_8 aucBAStartSeqCtrl[2]; /* SSN */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_FRAME_T, *P_ACTION_ADDBA_REQ_FRAME_T; ++ ++typedef struct _ACTION_ADDBA_REQ_BODY_T { ++ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ ++ UINT_16 u2BATimeoutValue; ++ UINT_16 u2BAStartSeqCtrl; /* SSN */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_BODY_T, *P_ACTION_ADDBA_REQ_BODY_T; ++ ++/* 7.4.4.2 ADDBA Response frame format */ ++typedef struct _ACTION_ADDBA_RSP_FRAME_T { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ ++ UINT_8 aucStatusCode[2]; ++ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ ++ UINT_8 aucBATimeoutValue[2]; ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_FRAME_T, *P_ACTION_ADDBA_RSP_FRAME_T; ++ ++typedef struct _ACTION_ADDBA_RSP_BODY_T { ++ UINT_16 u2StatusCode; ++ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ ++ UINT_16 u2BATimeoutValue; ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_BODY_T, *P_ACTION_ADDBA_RSP_BODY_T; ++ ++/* 7.4.4.3 DELBA frame format */ ++typedef struct _ACTION_DELBA_FRAME_T { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_16 u2DelBaParameterSet; /* Bit 11 Initiator, Bits 12-15 TID */ ++ UINT_16 u2ReasonCode; /* 7.3.1.7 */ ++} __KAL_ATTRIB_PACKED__ ACTION_DELBA_FRAME_T, *P_ACTION_DELBA_FRAME_T; ++ ++/* 7.4.6.1 Radio Measurement Request frame format */ ++typedef struct _ACTION_RM_REQ_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Radio Measurement Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_16 u2Repetitions; /* Number of repetitions */ ++ UINT_8 aucInfoElem[1]; /* Measurement Request elements, such as ++ channel load request, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_RM_REQ_FRAME, *P_ACTION_RM_REQ_FRAME; ++ ++/* 7.4.6.2 Radio Measurement Report frame format */ ++typedef struct _ACTION_RM_REPORT_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Radio Measurement Report frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 aucInfoElem[1]; /* Measurement Report elements, such as ++ channel load report, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_RM_REPORT_FRAME, *P_ACTION_RM_REPORT_FRAME; ++ ++/* 7.4.7.1a 20/40 BSS Coexistence Management frame format */ ++typedef struct _ACTION_20_40_COEXIST_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* BSS Coexistence Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ ++ IE_20_40_COEXIST_T rBssCoexist; /* 20/40 BSS coexistence element */ ++ IE_INTOLERANT_CHNL_REPORT_T rChnlReport; /* Intolerant channel report */ ++ ++} __KAL_ATTRIB_PACKED__ ACTION_20_40_COEXIST_FRAME, *P_ACTION_20_40_COEXIST_FRAME; ++ ++#if CFG_SUPPORT_802_11W ++/* 7.4.9 SA Query Management frame format */ ++typedef struct _ACTION_SA_QUERY_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* BSS Coexistence Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ ++ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; /* Transaction id */ ++ ++} __KAL_ATTRIB_PACKED__ ACTION_SA_QUERY_FRAME, *P_ACTION_SA_QUERY_FRAME; ++#endif ++ ++/* 7.4.10 Notify Channel Width Management frame format */ ++typedef struct _ACTION_NOTIFY_CHNL_WIDTH_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* BSS Coexistence Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucChannelWidth; /* Channel Width */ ++} __KAL_ATTRIB_PACKED__ ACTION_NOTIFY_CHNL_WIDTH_FRAME, *P_ACTION_NOTIFY_CHNL_WIDTH_FRAME; ++ ++/* 802.11v Wireless Network Management: Timing Measurement Request */ ++typedef struct _ACTION_WNM_TIMING_MEAS_REQ_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Timing Measurement Request Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucTrigger; /* Trigger */ ++} __KAL_ATTRIB_PACKED__ ACTION_WNM_TIMING_MEAS_REQ_FRAME, *P_ACTION_WNM_TIMING_MEAS_REQ_FRAME; ++ ++/* 802.11v Wireless Network Management: Timing Measurement */ ++typedef struct _ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Timing Measurement Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ ++ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ ++ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ ++ UINT_8 ucMaxToDErr; /* Maximum of ToD Error [10ns] */ ++ UINT_8 ucMaxToAErr; /* Maximum of ToA Error [10ns] */ ++} __KAL_ATTRIB_PACKED__ ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME, *P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME; ++ ++/* 3 Information Elements from WFA. */ ++typedef struct _IE_WFA_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucOui[3]; ++ UINT_8 ucOuiType; ++ UINT_8 aucOuiSubTypeVersion[2]; ++ /*!< Please be noted. WPA defines a 16 bit field version ++ instead of one subtype field and one version field */ ++} __KAL_ATTRIB_PACKED__ IE_WFA_T, *P_IE_WFA_T; ++ ++/* HS20 3.1 - HS 2.0 Indication Information Element */ ++typedef struct _IE_HS20_INDICATION_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucType; /* Type */ ++ UINT_8 ucHotspotConfig; /* Hotspot Configuration */ ++} __KAL_ATTRIB_PACKED__ IE_HS20_INDICATION_T, *P_IE_HS20_INDICATION_T; ++ ++/* WAPI Information element format */ ++typedef struct _WAPI_INFO_ELEM_T { ++ UCHAR ucElemId; ++ UCHAR ucLength; ++ UINT_16 u2Version; ++ UINT_16 u2AuthKeyMgtSuiteCount; ++ UCHAR aucAuthKeyMgtSuite1[4]; ++} __KAL_ATTRIB_PACKED__ WAPI_INFO_ELEM_T, *P_WAPI_INFO_ELEM_T; ++ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack() ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Convert the ECWmin(max) to CWmin(max) */ ++#define ECW_TO_CW(_ECW) ((1 << (_ECW)) - 1) ++ ++/* Convert the RCPI to dBm */ ++#define RCPI_TO_dBm(_rcpi) \ ++ ((PARAM_RSSI)(((_rcpi) > RCPI_HIGH_BOUND ? RCPI_HIGH_BOUND : (_rcpi)) >> 1) - NDBM_LOW_BOUND_FOR_RCPI) ++ ++/* Convert the dBm to RCPI */ ++#define dBm_TO_RCPI(_dbm) \ ++ (RCPI)(((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) > RCPI_HIGH_BOUND) ? RCPI_HIGH_BOUND : \ ++ ((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) < RCPI_LOW_BOUND ? RCPI_LOW_BOUND : \ ++ (((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1))) ++ ++/* Convert an unsigned char pointer to an information element pointer */ ++#define IE_ID(fp) (((P_IE_HDR_T) fp)->ucId) ++#define IE_LEN(fp) (((P_IE_HDR_T) fp)->ucLength) ++#define IE_SIZE(fp) (ELEM_HDR_LEN + IE_LEN(fp)) ++ ++#define SSID_IE(fp) ((P_IE_SSID_T) fp) ++ ++#define SUP_RATES_IE(fp) ((P_IE_SUPPORTED_RATE_T) fp) ++ ++#define DS_PARAM_IE(fp) ((P_IE_DS_PARAM_SET_T) fp) ++ ++#define TIM_IE(fp) ((P_IE_TIM_T) fp) ++ ++#define IBSS_PARAM_IE(fp) ((P_IE_IBSS_PARAM_SET_T) fp) ++ ++#define ERP_INFO_IE(fp) ((P_IE_ERP_T) fp) ++ ++#define EXT_SUP_RATES_IE(fp) ((P_IE_EXT_SUPPORTED_RATE_T) fp) ++ ++#define WFA_IE(fp) ((P_IE_WFA_T) fp) ++ ++#if CFG_SUPPORT_802_11D ++#define COUNTRY_IE(fp) ((P_IE_COUNTRY_T) fp) ++#endif ++ ++#define EXT_CAP_IE(fp) ((P_EXT_CAP_T) fp) ++ ++#define HT_CAP_IE(fp) ((P_IE_HT_CAP_T) fp) ++ ++#define HT_OP_IE(fp) ((P_IE_HT_OP_T) fp) ++ ++#define OBSS_SCAN_PARAM_IE(fp) ((P_IE_OBSS_SCAN_PARAM_T) fp) ++ ++#define BSS_20_40_COEXIST_IE(fp) ((P_IE_20_40_COEXIST_T) fp) ++ ++#define SUP_OPERATING_CLASS_IE(fp) ((P_IE_SUP_OPERATING_CLASS_T) fp) ++ ++#define QUIET_IE(fp) ((P_IE_QUIET_T) fp) ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++#define SUPPORTED_CHANNELS_IE(fp) ((P_IE_SUPPORTED_CHANNELS_T)fp) ++#endif ++ ++#define TIMEOUT_INTERVAL_IE(fp) ((IE_TIMEOUT_INTERVAL_T *)fp) ++ ++/* The macro to check if the MAC address is B/MCAST Address */ ++#define IS_BMCAST_MAC_ADDR(_pucDestAddr) \ ++ ((BOOLEAN) (((PUINT_8)(_pucDestAddr))[0] & BIT(0))) ++ ++/* The macro to check if the MAC address is UCAST Address */ ++#define IS_UCAST_MAC_ADDR(_pucDestAddr) \ ++ ((BOOLEAN) !(((PUINT_8)(_pucDestAddr))[0] & BIT(0))) ++ ++/* The macro to copy the MAC address */ ++#define COPY_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ ++ kalMemCopy(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN) ++ ++/* The macro to check if two MAC addresses are equal */ ++#define EQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ ++ (!kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) ++ ++/* The macro to check if two MAC addresses are not equal */ ++#define UNEQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ ++ (kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) ++ ++/* The macro to check whether two SSIDs are equal */ ++#define EQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ ++ ((ucSsidLen1 <= ELEM_MAX_LEN_SSID) && \ ++ (ucSsidLen2 <= ELEM_MAX_LEN_SSID) && \ ++ ((ucSsidLen1) == (ucSsidLen2)) && \ ++ !kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) ++ ++/* The macro to check whether two SSIDs are equal */ ++#define UNEQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ ++ ((ucSsidLen1 > ELEM_MAX_LEN_SSID) || \ ++ (ucSsidLen2 > ELEM_MAX_LEN_SSID) || \ ++ ((ucSsidLen1) != (ucSsidLen2)) || \ ++ kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) ++ ++/* The macro to copy the SSID, the length of pucDestSsid should have at least 32 bytes */ ++#define COPY_SSID(pucDestSsid, ucDestSsidLen, pucSrcSsid, ucSrcSsidLen) \ ++ do { \ ++ ucDestSsidLen = ucSrcSsidLen; \ ++ if (ucSrcSsidLen) { \ ++ ASSERT(ucSrcSsidLen <= ELEM_MAX_LEN_SSID); \ ++ kalMemCopy(pucDestSsid, \ ++ pucSrcSsid, \ ++ ((ucSrcSsidLen > ELEM_MAX_LEN_SSID) ? ELEM_MAX_LEN_SSID : ucSrcSsidLen)); \ ++ } \ ++ } while (FALSE) ++ ++/* The macro to copy the IE */ ++#define COPY_IE(pucDestIE, pucSrcIE) \ ++ do { \ ++ kalMemCopy((PUINT_8)pucDestIE, \ ++ (PUINT_8)pucSrcIE,\ ++ IE_SIZE(pucSrcIE)); \ ++ } while (FALSE) ++ ++#define IE_FOR_EACH(_pucIEsBuf, _u2IEsBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0;\ ++ ((((_u2Offset) + 2) <= (_u2IEsBufLen)) && (((_u2Offset) + IE_SIZE(_pucIEsBuf)) <= (_u2IEsBufLen))); \ ++ (_u2Offset) += IE_SIZE(_pucIEsBuf), (_pucIEsBuf) += IE_SIZE(_pucIEsBuf)) ++ ++#define SET_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ ++ do { \ ++ if ((_ucBit) < ((_ucFieldLength) * 8)) { \ ++ PUINT_8 aucExtCap = (PUINT_8)(_aucField); \ ++ ((aucExtCap)[(_ucBit) / 8]) |= BIT((_ucBit) % 8); \ ++ } \ ++ } while (FALSE) ++ ++#define TEST_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ ++ ((((_ucFieldLength) * 8) > (_ucBit)) && (((_aucField)[(_ucBit) / 8]) & BIT((_ucBit) % 8))) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _MAC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h +new file mode 100644 +index 000000000000..583923aed010 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h +@@ -0,0 +1,272 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/nic/mtreg.h#2 ++*/ ++ ++/*! \file "mtreg.h" ++ \brief The common register definition of mt5931 ++ ++ N/A ++*/ ++ ++/* ++** Log: mtreg.h ++ * ++ * 01 28 2013 samp.lin ++ * [WCXRP00000851] [MT6582 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6582-specific definitions. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 07 13 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add initial version for MT6628 driver support. ++ * ++*/ ++ ++#ifndef _MTREG_H ++#define _MTREG_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/* 1 MT6628 MCR Definition */ ++ ++/* 2 Host Interface */ ++ ++/* 4 CHIP ID Register */ ++#define MCR_WCIR 0x0000 ++ ++/* 4 HIF Low Power Control Register */ ++#define MCR_WHLPCR 0x0004 ++ ++/* 4 Control Status Register */ ++#define MCR_WSDIOCSR 0x0008 ++#define MCR_WSPICSR 0x0008 ++ ++/* 4 HIF Control Register */ ++#define MCR_WHCR 0x000C ++ ++/* 4 HIF Interrupt Status Register */ ++#define MCR_WHISR 0x0010 ++ ++/* 4 HIF Interrupt Enable Register */ ++#define MCR_WHIER 0x0014 ++ ++/* 4 Abnormal Status Register */ ++#define MCR_WASR 0x0018 ++ ++/* 4 WLAN Software Interrupt Control Register */ ++#define MCR_WSICR 0x001C ++ ++/* 4 WLAN TX Status Register */ ++#define MCR_WTSR0 0x0020 ++ ++/* 4 WLAN TX Status Register */ ++#define MCR_WTSR1 0x0024 ++ ++/* 4 WLAN TX Data Register 0 */ ++#define MCR_WTDR0 0x0028 ++ ++/* 4 WLAN TX Data Register 1 */ ++#define MCR_WTDR1 0x002C ++ ++/* 4 WLAN RX Data Register 0 */ ++#define MCR_WRDR0 0x0030 ++ ++/* 4 WLAN RX Data Register 1 */ ++#define MCR_WRDR1 0x0034 ++ ++/* 4 Host to Device Send Mailbox 0 Register */ ++#define MCR_H2DSM0R 0x0038 ++ ++/* 4 Host to Device Send Mailbox 1 Register */ ++#define MCR_H2DSM1R 0x003c ++ ++/* 4 Device to Host Receive Mailbox 0 Register */ ++#define MCR_D2HRM0R 0x0040 ++ ++/* 4 Device to Host Receive Mailbox 1 Register */ ++#define MCR_D2HRM1R 0x0044 ++ ++/* 4 Device to Host Receive Mailbox 2 Register */ ++#define MCR_D2HRM2R 0x0048 ++ ++/* 4 WLAN RX Packet Length Register */ ++#define MCR_WRPLR 0x0050 ++ ++/* 4 HSIF Transaction Count Register */ ++#define MCR_HSTCR 0x0058 ++ ++/* #if CFG_SDIO_INTR_ENHANCE */ ++typedef struct _ENHANCE_MODE_DATA_STRUCT_T { ++ UINT_32 u4WHISR; ++ union { ++ struct { ++ UINT_8 ucTQ0Cnt; ++ UINT_8 ucTQ1Cnt; ++ UINT_8 ucTQ2Cnt; ++ UINT_8 ucTQ3Cnt; ++ UINT_8 ucTQ4Cnt; ++ UINT_8 ucTQ5Cnt; ++ UINT_16 u2Rsrv; ++ } u; ++ UINT_32 au4WTSR[2]; ++ } rTxInfo; ++ union { ++ struct { ++ UINT_16 u2NumValidRx0Len; ++ UINT_16 u2NumValidRx1Len; ++ UINT_16 au2Rx0Len[16]; ++ UINT_16 au2Rx1Len[16]; ++ } u; ++ UINT_32 au4RxStatusRaw[17]; ++ } rRxInfo; ++ UINT_32 u4RcvMailbox0; ++ UINT_32 u4RcvMailbox1; ++} ENHANCE_MODE_DATA_STRUCT_T, *P_ENHANCE_MODE_DATA_STRUCT_T; ++/* #endif */ /* ENHANCE_MODE_DATA_STRUCT_T */ ++ ++/* 2 Definition in each register */ ++/* 3 WCIR 0x0000 */ ++#define WCIR_WLAN_READY BIT(21) ++#define WCIR_POR_INDICATOR BIT(20) ++#define WCIR_REVISION_ID BITS(16, 19) ++#define WCIR_CHIP_ID BITS(0, 15) ++ ++#define MTK_CHIP_REV_72 0x00006572 ++#define MTK_CHIP_REV_82 0x00006582 ++#define MTK_CHIP_REV_92 0x00006592 ++#define MTK_CHIP_MP_REVERSION_ID 0x0 ++ ++/* 3 WHLPCR 0x0004 */ ++#define WHLPCR_FW_OWN_REQ_CLR BIT(9) ++#define WHLPCR_FW_OWN_REQ_SET BIT(8) ++#define WHLPCR_IS_DRIVER_OWN BIT(8) ++#define WHLPCR_INT_EN_CLR BIT(1) ++#define WHLPCR_INT_EN_SET BIT(0) ++ ++/* 3 WSDIOCSR 0x0008 */ ++#define WSDIOCSR_SDIO_RE_INIT_EN BIT(0) ++ ++/* 3 WSPICSR 0x0008 */ ++#define WCSR_SPI_MODE_SEL BITS(3, 4) ++#define WCSR_SPI_ENDIAN_BIG BIT(2) ++#define WCSR_SPI_INT_OUT_MODE BIT(1) ++#define WCSR_SPI_DATA_OUT_MODE BIT(0) ++ ++/* 3 WHCR 0x000C */ ++#define WHCR_RX_ENHANCE_MODE_EN BIT(16) ++#define WHCR_MAX_HIF_RX_LEN_NUM BITS(4, 7) ++#define WHCR_W_MAILBOX_RD_CLR_EN BIT(2) ++#define WHCR_W_INT_CLR_CTRL BIT(1) ++#define WHCR_MCU_DBG_EN BIT(0) ++#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM 4 ++ ++/* 3 WHISR 0x0010 */ ++#define WHISR_D2H_SW_INT BITS(8, 31) ++#define WHISR_D2H_SW_ASSERT_INFO_INT BIT(31) ++#define WHISR_FW_OWN_BACK_INT BIT(4) ++#define WHISR_ABNORMAL_INT BIT(3) ++#define WHISR_RX1_DONE_INT BIT(2) ++#define WHISR_RX0_DONE_INT BIT(1) ++#define WHISR_TX_DONE_INT BIT(0) ++ ++/* 3 WHIER 0x0014 */ ++#define WHIER_D2H_SW_INT BITS(8, 31) ++#define WHIER_FW_OWN_BACK_INT_EN BIT(4) ++#define WHIER_ABNORMAL_INT_EN BIT(3) ++#define WHIER_RX1_DONE_INT_EN BIT(2) ++#define WHIER_RX0_DONE_INT_EN BIT(1) ++#define WHIER_TX_DONE_INT_EN BIT(0) ++#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \ ++ WHIER_RX1_DONE_INT_EN | \ ++ WHIER_TX_DONE_INT_EN | \ ++ WHIER_ABNORMAL_INT_EN | \ ++ WHIER_D2H_SW_INT \ ++ ) ++ ++/* 3 WASR 0x0018 */ ++#define WASR_FW_OWN_INVALID_ACCESS BIT(4) ++#define WASR_RX1_UNDER_FLOW BIT(3) ++#define WASR_RX0_UNDER_FLOW BIT(2) ++#define WASR_TX1_OVER_FLOW BIT(1) ++#define WASR_TX0_OVER_FLOW BIT(0) ++ ++/* 3 WSICR 0x001C */ ++#define WSICR_H2D_SW_INT_SET BITS(16, 31) ++ ++/* 3 WRPLR 0x0050 */ ++#define WRPLR_RX1_PACKET_LENGTH BITS(16, 31) ++#define WRPLR_RX0_PACKET_LENGTH BITS(0, 15) ++ ++/* 3 HSTCR 0x0058 */ ++#define HSTCR_AFF_BURST_LEN BITS(24, 25) ++#define HSTCR_AFF_BURST_LEN_OFFSET 24 ++#define HSTCR_TRANS_TARGET BITS(20, 22) ++#define HSTCR_TRANS_TARGET_OFFSET 20 ++#define HSTCR_HSIF_TRANS_CNT BITS(2, 19) ++#define HSTCR_HSIF_TRANS_CNT_OFFSET 2 ++ ++/* HSTCR_TRANS_TARGET */ ++typedef enum _eTransTarget { ++ TRANS_TARGET_TXD0 = 0, ++ TRANS_TARGET_TXD1, ++ TRANS_TARGET_RXD0, ++ TRANS_TARGET_RXD1, ++ TRANS_TARGET_WHISR, ++ NUM_TRANS_TARGET ++} E_TRANS_TARGET_T; ++ ++typedef enum _E_AFF_BURST_LEN { ++ BURST_1_DW = 0, ++ BURST_4_DW, ++ BURST_8_DW, ++ BURST_RSV, ++ NUM_AFF_BURST_LEN ++} E_AFF_BURST_LEN; ++ ++#endif /* _MTREG_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h +new file mode 100644 +index 000000000000..c059b707aee8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h +@@ -0,0 +1,498 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic.h#1 ++*/ ++ ++/*! \file "nic.h" ++ \brief The declaration of nic functions ++ ++ Detail description. ++*/ ++ ++/* ++** Log: nic.h ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. ++ * If disconnect the AP and flush all the data frame in the TX queue, WPS ++ * cannot do the 4-way handshake to connect to the AP.. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 04 11 2011 yuche.tsai ++ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. ++ * Fix kernel panic issue when MMPDU of P2P is pending in driver. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right ++ * after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * add HT (802.11n) fixed rate support. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced ++ * by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test ++ * with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * STA-REC is maintained by CNM only. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement TX_DONE callback path. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add channel frequency <-> number conversion ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always process TX interrupt first then RX interrupt. ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-10-13 21:58:58 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-24 21:12:55 GMT mtk01104 ++** Add function prototype nicRestoreSpiDefMode() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:54 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:32 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _NIC_H ++#define _NIC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++struct _REG_ENTRY_T { ++ UINT_32 u4Offset; ++ UINT_32 u4Value; ++}; ++ ++struct _TABLE_ENTRY_T { ++ P_REG_ENTRY_T pu4TablePtr; ++ UINT_16 u2Size; ++}; ++ ++/*! INT status to event map */ ++typedef struct _INT_EVENT_MAP_T { ++ UINT_32 u4Int; ++ UINT_32 u4Event; ++} INT_EVENT_MAP_T, *P_INT_EVENT_MAP_T; ++ ++enum ENUM_INT_EVENT_T { ++ INT_EVENT_ABNORMAL, ++ INT_EVENT_SW_INT, ++ INT_EVENT_TX, ++ INT_EVENT_RX, ++ INT_EVENT_NUM ++}; ++ ++typedef enum _ENUM_IE_UPD_METHOD_T { ++ IE_UPD_METHOD_UPDATE_RANDOM, ++ IE_UPD_METHOD_UPDATE_ALL, ++ IE_UPD_METHOD_DELETE_ALL, ++} ENUM_IE_UPD_METHOD_T, *P_ENUM_IE_UPD_METHOD_T; ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern BOOLEAN fgIsResetting; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in nic.c */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter); ++ ++VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter); ++ ++VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus); ++ ++WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter); ++ ++VOID nicMCRInit(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter); ++ ++#if CFG_SDIO_INTR_ENHANCE ++VOID nicSDIOInit(IN P_ADAPTER_T prAdapter); ++ ++VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus); ++#endif ++ ++BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter); ++ ++VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt); ++ ++BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter); ++ ++#if defined(_HIF_SPI) ++void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter); ++#endif ++ ++VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data); ++ ++VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data); ++ ++VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap); ++ ++P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); ++ ++P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); ++ ++P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx); ++ ++VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); ++ ++UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter); ++ ++UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter); ++ ++/* Media State Change */ ++WLAN_STATUS ++nicMediaStateChange(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); ++ ++/* Utility function for channel number conversion */ ++UINT_32 nicChannelNum2Freq(IN UINT_32 u4ChannelNum); ++ ++UINT_32 nicFreq2ChannelNum(IN UINT_32 u4FreqInKHz); ++ ++/* firmware command wrapper */ ++ /* NETWORK (WIFISYS) */ ++WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++ /* BSS-INFO */ ++WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++ /* BSS-INFO Indication (PM) */ ++WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++ /* Beacon Template Update */ ++WLAN_STATUS ++nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, ++ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen); ++ ++WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam); ++ ++/*----------------------------------------------------------------------------*/ ++/* Calibration Control */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam); ++ ++WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset); ++ ++WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult); ++ ++/*----------------------------------------------------------------------------*/ ++/* PHY configuration */ ++/*----------------------------------------------------------------------------*/ ++VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* MGMT and System Service Control */ ++/*----------------------------------------------------------------------------*/ ++VOID nicInitSystemService(IN P_ADAPTER_T prAdapter); ++ ++VOID nicResetSystemService(IN P_ADAPTER_T prAdapter); ++ ++VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter); ++ ++VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); ++ ++VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent); ++ ++WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent); ++/*----------------------------------------------------------------------------*/ ++/* Scan Result Processing */ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicAddScanResult(IN P_ADAPTER_T prAdapter, ++ IN PARAM_MAC_ADDRESS rMacAddr, ++ IN P_PARAM_SSID_T prSsid, ++ IN UINT_32 u4Privacy, ++ IN PARAM_RSSI rRssi, ++ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, ++ IN P_PARAM_802_11_CONFIG_T prConfiguration, ++ IN ENUM_PARAM_OP_MODE_T eOpMode, ++ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf); ++ ++VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx); ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++/*----------------------------------------------------------------------------*/ ++/* Workaround Control */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* Fixed Rate Hacking */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicUpdateRateParams(IN P_ADAPTER_T prAdapter, ++ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, ++ IN PUINT_8 pucDesiredPhyTypeSet, ++ IN PUINT_16 pu2DesiredNonHTRateSet, ++ IN PUINT_16 pu2BSSBasicRateSet, ++ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 u2HtCapInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Write registers */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value); ++ ++/*----------------------------------------------------------------------------*/ ++/* Update auto rate */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4ArSysParam0, ++ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3); ++ ++/*----------------------------------------------------------------------------*/ ++/* Enable/Disable Roaming */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming); ++ ++VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Link Quality Updating */ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality); ++ ++VOID ++nicUpdateRSSI(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); ++ ++VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed); ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam); ++#endif ++ ++#endif /* _NIC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h +new file mode 100644 +index 000000000000..86e2c84b07ff +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h +@@ -0,0 +1,420 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_rx.h#1 ++*/ ++ ++/*! \file "nic_rx.h" ++ \brief The declaration of the nic rx functions ++ ++*/ ++ ++/* ++** Log: nic_rx.h ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add delay after whole-chip resetting for MT5931 E1 ASIC. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode ++ * and stop ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Change prototype of API of adding P2P device to scan result. ++ * Additional IE buffer is saved. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Modify data structure for P2P Scan result. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * newly added P2P API should be declared in header file. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * 4) nicRxWaitResponse() revised ++ * * 5) another set of TQ counter default value is added for fw-download state ++ * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * and result is retrieved by get ATInfo instead ++ * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:49:09 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 14:02:37 GMT MTK02468 ++** Added ucStaRecIdx in SW_RFB_T and HALF_SEQ_NO_COUNT definition (to replace HALF_SEQ_NO_CNOUT) ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-27 11:07:54 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 18:18:09 GMT mtk02752 ++** modify nicRxAddScanResult() ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-24 22:42:22 GMT mtk02752 ++** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-24 19:57:06 GMT mtk02752 ++** adopt P_HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 21:43:04 GMT mtk02752 ++** correct ENUM_RX_PKT_DESTINATION_T definitions ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 15:28:25 GMT mtk02752 ++** add ucQueuedPacketNum for indicating how many packet are queued by RX reordering buffer/forwarding path ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 15:05:01 GMT mtk02752 ++** add eTC for SW_RFB_T and structure RX_MAILBOX ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 21:16:57 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-13 16:59:30 GMT mtk02752 ++** add handler for event packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-13 13:45:50 GMT mtk02752 ++** add port param for nicRxEnhanceReadBuffer() ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-11 10:12:31 GMT mtk02752 ++** nicSDIOReadIntStatus() always read sizeof(ENHANCE_MODE_DATA_STRUCT_T) for int response, ++** thus the number should be set to 0(:=16) instead of 10 ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-29 19:53:32 GMT mtk01084 ++** modify structure naming ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-23 16:08:23 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:01 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-20 12:23:33 GMT mtk01461 ++** Add u4MaxEventBufferLen parameter to nicRxWaitResponse() ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-18 21:00:48 GMT mtk01426 ++** Update SDIO_MAXIMUM_RX_STATUS value ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:36:15 GMT mtk01461 ++** Remove unused define - SDIO_MAXIMUM_TX_STATUS ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:17 GMT mtk01461 ++** Add function for HIF_LOOPBACK_PRE_TEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:56:19 GMT mtk01426 ++** Add to support CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:19:56 GMT mtk01426 ++** Add nicRxWaitResponse function proto type ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:35 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _NIC_RX_H ++#define _NIC_RX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern P_SW_RFB_T g_arGscnResultsTempBuffer[]; ++extern UINT_8 g_GscanResultsTempBufferIndex; ++extern UINT_8 g_arGscanResultsIndicateNumber[]; ++extern UINT_8 g_GetResultsBufferedCnt; ++extern UINT_8 g_GetResultsCmdCnt; ++extern void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define MAX_SEQ_NO 4095 ++#define MAX_SEQ_NO_COUNT 4096 ++#define HALF_SEQ_NO_CNOUT 2048 ++ ++#define HALF_SEQ_NO_COUNT 2048 ++ ++#define MT6620_FIXED_WIN_SIZE 64 ++#define CFG_RX_MAX_BA_ENTRY 4 ++#define CFG_RX_MAX_BA_TID_NUM 8 ++ ++#define RX_STATUS_FLAG_MORE_PACKET BIT(30) ++#define RX_STATUS_CHKSUM_MASK BITS(0, 10) ++ ++#define RX_RFB_LEN_FIELD_LEN 4 ++#define RX_HEADER_OFFSET 2 ++ ++#define RX_RETURN_INDICATED_RFB_TIMEOUT_SEC 3 ++ ++#if defined(_HIF_SDIO) && defined(WINDOWS_DDK) ++/*! On XP, maximum Tx+Rx Statue <= 64-4(HISR)*/ ++#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ ++#else ++#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_RX_STATISTIC_COUNTER_T { ++ RX_MPDU_TOTAL_COUNT = 0, ++ RX_SIZE_ERR_DROP_COUNT, ++ ++ RX_DATA_INDICATION_COUNT, ++ RX_DATA_RETURNED_COUNT, ++ RX_DATA_RETAINED_COUNT, ++ ++ RX_DROP_TOTAL_COUNT, ++ RX_TYPE_ERR_DROP_COUNT, ++ RX_CLASS_ERR_DROP_COUNT, ++ RX_DST_NULL_DROP_COUNT, ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++ RX_CSUM_TCP_FAILED_COUNT, ++ RX_CSUM_UDP_FAILED_COUNT, ++ RX_CSUM_IP_FAILED_COUNT, ++ RX_CSUM_TCP_SUCCESS_COUNT, ++ RX_CSUM_UDP_SUCCESS_COUNT, ++ RX_CSUM_IP_SUCCESS_COUNT, ++ RX_CSUM_UNKNOWN_L4_PKT_COUNT, ++ RX_CSUM_UNKNOWN_L3_PKT_COUNT, ++ RX_IP_V6_PKT_CCOUNT, ++#endif ++ RX_STATISTIC_COUNTER_NUM ++} ENUM_RX_STATISTIC_COUNTER_T; ++ ++typedef enum _ENUM_RX_PKT_DESTINATION_T { ++ RX_PKT_DESTINATION_HOST, /* to OS */ ++ RX_PKT_DESTINATION_FORWARD, /* to TX queue for forward, AP mode */ ++ RX_PKT_DESTINATION_HOST_WITH_FORWARD, /* to both TX and OS, AP mode broadcast packet */ ++ RX_PKT_DESTINATION_NULL, /* packet to be freed */ ++ RX_PKT_DESTINATION_NUM ++} ENUM_RX_PKT_DESTINATION_T; ++ ++struct _SW_RFB_T { ++ QUE_ENTRY_T rQueEntry; ++ PVOID pvPacket; /*!< ptr to rx Packet Descriptor */ ++ PUINT_8 pucRecvBuff; /*!< ptr to receive data buffer */ ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_32 u4HifRxHdrFlag; ++ PVOID pvHeader; ++ UINT_16 u2PacketLen; ++ UINT_16 u2HeaderLen; ++ UINT_16 u2SSN; ++ UINT_8 ucTid; ++ UINT_8 ucWlanIdx; ++ UINT_8 ucPacketType; ++ UINT_8 ucStaRecIdx; ++ ++ ENUM_CSUM_RESULT_T aeCSUM[CSUM_TYPE_NUM]; ++ ENUM_RX_PKT_DESTINATION_T eDst; ++ ENUM_TRAFFIC_CLASS_INDEX_T eTC; /* only valid when eDst == FORWARD */ ++ ++ UINT_64 rRxTime; ++}; ++ ++/*! RX configuration type structure */ ++typedef struct _RX_CTRL_T { ++ UINT_32 u4RxCachedSize; ++ PUINT_8 pucRxCached; ++ QUE_T rFreeSwRfbList; ++ QUE_T rReceivedRfbList; ++ QUE_T rIndicatedRfbList; ++ ++#if CFG_SDIO_RX_AGG ++ PUINT_8 pucRxCoalescingBufPtr; ++#endif ++ ++ PVOID apvIndPacket[CFG_RX_MAX_PKT_NUM]; ++ PVOID apvRetainedPacket[CFG_RX_MAX_PKT_NUM]; ++ ++ UINT_8 ucNumIndPacket; ++ UINT_8 ucNumRetainedPacket; ++ UINT_64 au8Statistics[RX_STATISTIC_COUNTER_NUM]; /*!< RX Counters */ ++ ++#if CFG_HIF_STATISTICS ++ UINT_32 u4TotalRxAccessNum; ++ UINT_32 u4TotalRxPacketNum; ++#endif ++ ++#if CFG_HIF_RX_STARVATION_WARNING ++ UINT_32 u4QueuedCnt; ++ UINT_32 u4DequeuedCnt; ++#endif ++ ++#if CFG_RX_PKTS_DUMP ++ UINT_32 u4RxPktsDumpTypeMask; ++#endif ++ ++} RX_CTRL_T, *P_RX_CTRL_T; ++ ++typedef struct _RX_MAILBOX_T { ++ UINT_32 u4RxMailbox[2]; /* for Device-to-Host Mailbox */ ++} RX_MAILBOX_T, *P_RX_MAILBOX_T; ++ ++typedef WLAN_STATUS(*PROCESS_RX_MGT_FUNCTION) (P_ADAPTER_T, P_SW_RFB_T); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define RX_INC_CNT(prRxCtrl, eCounter) \ ++ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]++; } ++ ++#define RX_ADD_CNT(prRxCtrl, eCounter, u8Amount) \ ++ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter] += (UINT_64)u8Amount; } ++ ++#define RX_GET_CNT(prRxCtrl, eCounter) \ ++ (((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]) ++ ++#define RX_RESET_ALL_CNTS(prRxCtrl) \ ++ {kalMemZero(&prRxCtrl->au8Statistics[0], sizeof(prRxCtrl->au8Statistics)); } ++ ++#define RX_STATUS_TEST_MORE_FLAG(flag) \ ++ ((BOOLEAN)((flag & RX_STATUS_FLAG_MORE_PACKET) ? TRUE : FALSE)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID nicRxInitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter); ++ ++#if !CFG_SDIO_INTR_ENHANCE ++VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++#else ++VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++#if CFG_SDIO_RX_AGG ++VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter); ++#endif ++ ++WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); ++ ++VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); ++ ++VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus); ++ ++VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]); ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); ++ ++VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); ++ ++WLAN_STATUS ++nicRxWaitResponse(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length); ++ ++VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++#endif /* _NIC_RX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h +new file mode 100644 +index 000000000000..e516468fcb16 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h +@@ -0,0 +1,642 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 ++*/ ++ ++/*! \file nic_tx.h ++ \brief Functions that provide TX operation in NIC's point of view. ++ ++ This file provides TX functions which are responsible for both Hardware and ++ Software Resource Management and keep their Synchronization. ++ ++*/ ++ ++/* ++** Log: nic_tx.h ++ * ++ * 11 18 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add log counter for tx ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add TX_DONE status detail information. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing ++ * frame dropping cases for TC4 path ++ * 1. add nicTxGetResource() API for QM to make decisions. ++ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 02 16 2011 cp.wu ++ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking ++ * available count and modify behavior ++ * 1. add new API: nicTxGetFreeCmdCount() ++ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 12 15 2010 yuche.tsai ++ * NULL ++ * Update SLT Descriptor number configure in driver. ++ * ++ * 11 16 2010 yarco.yang ++ * [WCXRP00000177] [MT5931 F/W] Performance tuning for 1st connection ++ * Update TX buffer count ++ * ++ * 11 03 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * 1) use 8 buffers for MT5931 which is equipped with less memory ++ * 2) modify MT5931 debug level to TRACE when download is successful ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * API added: nicTxPendingPackets(), for simplifying porting layer ++ * ++ * 07 26 2010 cp.wu ++ * ++ * change TC4 initial value from 2 to 4. ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under ++ * concurrent network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add MGMT Packet type for HIF_TX_HEADER ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * TX descriptors are now allocated once for reducing allocation overhead ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate ++ * 2) add packet type for indicating management frames ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add TX_PACKET_MGMT to indicate the frame is coming from management modules ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * * ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 02 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Redistributed the initial TC resources for normal operation ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * 4) nicRxWaitResponse() revised ++ * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * 4. correct some HAL implementation ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * and result is retrieved by get ATInfo instead ++ * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:53:28 GMT mtk02752 ++** remove unused API ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-27 11:08:00 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-24 19:56:49 GMT mtk02752 ++** remove redundant eTC ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 22:01:08 GMT mtk02468 ++** Added MSDU_INFO fields for composing HIF TX header ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:51 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:35:05 GMT mtk02752 ++** + nicTxMsduInfoList() for sending MsduInfoList ++** + NIC_TX_BUFF_COUNT_TC[0~5] ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-17 11:07:00 GMT mtk02752 ++** add nicTxAdjustTcq() API ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 22:28:30 GMT mtk02752 ++** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 21:44:50 GMT mtk02752 ++** + nicTxReturnMsduInfo() ++** + nicTxFillMsduInfo() ++** + rFreeMsduInfoList field in TX_CTRL ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-16 18:00:43 GMT mtk02752 ++** use P_PACKET_INFO_T for prPacket to avoid inventing another new structure for packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-16 15:28:49 GMT mtk02752 ++** add ucQueuedPacketNum for indicating how many packets are queued by per STA/AC queue ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-16 10:52:01 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-14 23:39:24 GMT mtk02752 ++** interface structure redefine ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-13 21:17:03 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-29 19:53:10 GMT mtk01084 ++** remove strange code by Frog ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:04 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-02 13:53:03 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:36:50 GMT mtk01461 ++** Add declaration of nicTxReleaseResource() ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:58:39 GMT mtk01461 ++** Move CMD_INFO_T related define and function to cmd_buf.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:53 GMT mtk01461 ++** Add function for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:33:27 GMT mtk01461 ++** Define constants for TX PATH and add nicTxPollingResource ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:32 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:38 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _NIC_TX_H ++#define _NIC_TX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define NIC_TX_RESOURCE_POLLING_TIMEOUT 256 ++#define NIC_TX_RESOURCE_POLLING_DELAY_MSEC 50 ++ ++/* Maximum buffer count for individual HIF TCQ */ ++ ++#if defined(MT6620) ++#if CFG_SLT_SUPPORT ++ /* 20101215 mtk01725 Redistributed the initial TC resources for SLT operation */ ++#define NIC_TX_BUFF_COUNT_TC0 0 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 16 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 0 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 0 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 0 /* First connection: 0 */ ++#else ++ /* 20100302 mtk02468 Redistributed the initial TC resources for normal operation */ ++#define NIC_TX_BUFF_COUNT_TC0 6 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 8 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 8 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 8 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 2 /* First connection: 0 */ ++#endif ++#elif defined(MT6628) ++#if (CFG_SRAM_SIZE_OPTION == 0) ++#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 20 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ ++#elif (CFG_SRAM_SIZE_OPTION == 1) ++#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 36 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ ++#elif (CFG_SRAM_SIZE_OPTION == 2) ++#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 48 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ ++#else ++#error "> Set TX_BUFF_COUNT_TC error!" ++#endif ++#endif ++ ++#define NIC_TX_BUFF_SUM (NIC_TX_BUFF_COUNT_TC0 + \ ++ NIC_TX_BUFF_COUNT_TC1 + \ ++ NIC_TX_BUFF_COUNT_TC2 + \ ++ NIC_TX_BUFF_COUNT_TC3 + \ ++ NIC_TX_BUFF_COUNT_TC4 + \ ++ NIC_TX_BUFF_COUNT_TC5) ++#if CFG_ENABLE_FW_DOWNLOAD ++ ++#define NIC_TX_INIT_BUFF_COUNT_TC0 8 ++#define NIC_TX_INIT_BUFF_COUNT_TC1 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC2 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC3 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC4 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC5 0 ++ ++#define NIC_TX_INIT_BUFF_SUM (NIC_TX_INIT_BUFF_COUNT_TC0 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC1 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC2 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC3 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC4 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC5) ++ ++#endif ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++#define NIC_TX_TIME_THRESHOLD 100 /* in unit of ms */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* 3 Session for TX QUEUES */ ++/* The definition in this ENUM is used to categorize packet's Traffic Class according ++ * to the their TID(User Priority). ++ * In order to achieve QoS goal, a particular TC should not block the process of ++ * another packet with different TC. ++ * In current design we will have 5 categories(TCs) of SW resource. ++ */ ++typedef enum _ENUM_TRAFFIC_CLASS_INDEX_T { ++ TC0_INDEX = 0, /* HIF TX0: AC0 packets */ ++ TC1_INDEX, /* HIF TX0: AC1 packets & non-QoS packets */ ++ TC2_INDEX, /* HIF TX0: AC2 packets */ ++ TC3_INDEX, /* HIF TX0: AC3 packets */ ++ TC4_INDEX, /* HIF TX1: Command packets or 802.1x packets */ ++ TC5_INDEX, /* HIF TX0: BMCAST packets */ ++ TC_NUM /* Maximum number of Traffic Classes. */ ++} ENUM_TRAFFIC_CLASS_INDEX_T; ++ ++typedef enum _ENUM_TX_STATISTIC_COUNTER_T { ++ TX_MPDU_TOTAL_COUNT = 0, ++ TX_INACTIVE_BSS_DROP, ++ TX_INACTIVE_STA_DROP, ++ TX_FORWARD_OVERFLOW_DROP, ++ TX_AP_BORADCAST_DROP, ++ TX_STATISTIC_COUNTER_NUM ++} ENUM_TX_STATISTIC_COUNTER_T; ++ ++typedef struct _TX_TCQ_STATUS_T { ++ UINT_8 aucFreeBufferCount[TC_NUM]; ++ UINT_8 aucMaxNumOfBuffer[TC_NUM]; ++} TX_TCQ_STATUS_T, *P_TX_TCQ_STATUS_T; ++ ++typedef struct _TX_TCQ_ADJUST_T { ++ INT_8 acVariation[TC_NUM]; ++} TX_TCQ_ADJUST_T, *P_TX_TCQ_ADJUST_T; ++ ++typedef struct _TX_CTRL_T { ++ UINT_32 u4TxCachedSize; ++ PUINT_8 pucTxCached; ++ ++/* Elements below is classified according to TC (Traffic Class) value. */ ++ ++ TX_TCQ_STATUS_T rTc; ++ ++ PUINT_8 pucTxCoalescingBufPtr; ++ ++ QUE_T rFreeMsduInfoList; ++ ++ /* Management Frame Tracking */ ++ /* number of management frames to be sent */ ++ INT_32 i4TxMgmtPendingNum; ++ ++ /* to tracking management frames need TX done callback */ ++ QUE_T rTxMgmtTxingQueue; ++ ++#if CFG_HIF_STATISTICS ++ UINT_32 u4TotalTxAccessNum; ++ UINT_32 u4TotalTxPacketNum; ++#endif ++ UINT_32 au4Statistics[TX_STATISTIC_COUNTER_NUM]; ++ ++ /* Number to track forwarding frames */ ++ INT_32 i4PendingFwdFrameCount; ++ ++} TX_CTRL_T, *P_TX_CTRL_T; ++ ++typedef enum _ENUM_TX_PACKET_SRC_T { ++ TX_PACKET_OS, ++ TX_PACKET_OS_OID, ++ TX_PACKET_FORWARDING, ++ TX_PACKET_MGMT, ++ TX_PACKET_NUM ++} ENUM_TX_PACKET_SRC_T; ++ ++typedef enum _ENUM_HIF_TX_PACKET_TYPE_T { ++ HIF_TX_PACKET_TYPE_DATA = 0, ++ HIF_TX_PACKET_TYPE_COMMAND, ++ HIF_TX_PACKET_TYPE_HIF_LB, ++ HIF_TX_PACKET_TYPE_MGMT ++} ENUM_HIF_TX_PACKET_TYPE_T, *P_ENUM_HIF_TX_PACKET_TYPE_T; ++ ++typedef enum _ENUM_TX_RESULT_CODE_T { ++ TX_RESULT_SUCCESS = 0, ++ TX_RESULT_LIFE_TIMEOUT, ++ TX_RESULT_RTS_ERROR, ++ TX_RESULT_MPDU_ERROR, ++ TX_RESULT_AGING_TIMEOUT, ++ TX_RESULT_FLUSHED, ++ TX_RESULT_DROPPED_IN_DRIVER = 32, ++ TX_RESULT_NUM ++} ENUM_TX_RESULT_CODE_T, *P_ENUM_TX_RESULT_CODE_T; ++ ++struct _WLAN_CFG_ENTRY_T { ++ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; ++ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++ WLAN_CFG_SET_CB pfSetCb; ++ PVOID pPrivate; ++ UINT_32 u4Flags; ++}; ++ ++struct _WLAN_CFG_T { ++ UINT_32 u4WlanCfgEntryNumMax; ++ UINT_32 u4WlanCfgKeyLenMax; ++ UINT_32 u4WlanCfgValueLenMax; ++ WLAN_CFG_ENTRY_T arWlanCfgBuf[WLAN_CFG_ENTRY_NUM_MAX]; ++}; ++ ++/* TX Call Back Function */ ++typedef WLAN_STATUS(*PFN_TX_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++typedef struct _PKT_PROFILE_T { ++ BOOLEAN fgIsValid; ++#if CFG_PRINT_RTP_PROFILE ++ BOOLEAN fgIsPrinted; ++ UINT_16 u2IpSn; ++ UINT_16 u2RtpSn; ++ UINT_8 ucTcxFreeCount; ++#endif ++ OS_SYSTIME rHardXmitArrivalTimestamp; ++ OS_SYSTIME rEnqueueTimestamp; ++ OS_SYSTIME rDequeueTimestamp; ++ OS_SYSTIME rHifTxDoneTimestamp; ++} PKT_PROFILE_T, *P_PKT_PROFILE_T; ++#endif ++ ++/* TX transactions could be divided into 4 kinds: ++ * ++ * 1) 802.1X / Bluetooth-over-Wi-Fi Security Frames ++ * [CMD_INFO_T] - [prPacket] - in skb or NDIS_PACKET form ++ * ++ * 2) MMPDU ++ * [CMD_INFO_T] - [prPacket] - [MSDU_INFO_T] - [prPacket] - direct buffer for frame body ++ * ++ * 3) Command Packets ++ * [CMD_INFO_T] - [pucInfoBuffer] - direct buffer for content of command packet ++ * ++ * 4) Normal data frame ++ * [MSDU_INFO_T] - [prPacket] - in skb or NDIS_PACKET form ++ */ ++ ++/* PS_FORWARDING_TYPE_NON_PS means that the receiving STA is in Active Mode ++* from the perspective of host driver (maybe not synchronized with FW --> SN is needed) ++*/ ++ ++struct _MSDU_INFO_T { ++ QUE_ENTRY_T rQueEntry; ++ P_NATIVE_PACKET prPacket; ++ ++ ENUM_TX_PACKET_SRC_T eSrc; /* specify OS/FORWARD packet */ ++ UINT_8 ucUserPriority; ++ ++ /* For composing HIF TX header */ ++ UINT_8 ucTC; /* Traffic Class: 0~4 (HIF TX0), 5 (HIF TX1) */ ++ UINT_8 ucPacketType; /* 0: Data, 1: Command, 2: HIF Loopback 3: Management Frame */ ++ UINT_8 ucStaRecIndex; ++ UINT_8 ucNetworkType; /* See ENUM_NETWORK_TYPE_T */ ++ UINT_8 ucFormatID; /* 0: MAUI, Linux, Windows NDIS 5.1 */ ++ BOOLEAN fgIs802_1x; /* TRUE: 802.1x frame */ ++ BOOLEAN fgIs802_11; /* TRUE: 802.11 header is present */ ++ UINT_16 u2PalLLH; /* PAL Logical Link Header (for BOW network) */ ++ UINT_16 u2AclSN; /* ACL Sequence Number (for BOW network) */ ++ UINT_8 ucPsForwardingType; /* See ENUM_PS_FORWARDING_TYPE_T */ ++ UINT_8 ucPsSessionID; /* PS Session ID specified by the FW for the STA */ ++ BOOLEAN fgIsBurstEnd; /* TRUE means this is the last packet of the burst for (STA, TID) */ ++ BOOLEAN fgIsBIP; /* Management Frame Protection */ ++ BOOLEAN fgIsBasicRate; /* Force Basic Rate Transmission */ ++ ++ /* flattened from PACKET_INFO_T */ ++ UINT_8 ucMacHeaderLength; ++ UINT_8 ucLlcLength; /* w/o EtherType */ ++ UINT_16 u2FrameLength; ++ UINT_8 aucEthDestAddr[MAC_ADDR_LEN]; /* Ethernet Destination Address */ ++ ++ /* for TX done tracking */ ++ UINT_8 ucTxSeqNum; ++ PFN_TX_DONE_HANDLER pfTxDoneHandler; ++ BOOLEAN fgNeedTxDoneStatus; ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ PKT_PROFILE_T rPktProfile; ++#endif ++ COMMAND_TYPE eCmdType; ++ UINT_8 ucCID; ++ UINT_32 u4InqueTime; ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define TX_INC_CNT(prTxCtrl, eCounter) \ ++ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]++; } ++ ++#define TX_ADD_CNT(prTxCtrl, eCounter, u8Amount) \ ++ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter] += (UINT_32)u8Amount; } ++ ++#define TX_GET_CNT(prTxCtrl, eCounter) \ ++ (((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]) ++ ++#define TX_RESET_ALL_CNTS(prTxCtrl) \ ++ {kalMemZero(&prTxCtrl->au4Statistics[0], sizeof(prTxCtrl->au4Statistics)); } ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++#define PRINT_PKT_PROFILE(_pkt_profile, _note) \ ++{ \ ++ if (!(_pkt_profile)->fgIsPrinted) { \ ++ DBGLOG(TX, TRACE, "X[%u] E[%u] D[%u] HD[%u] B[%d] RTP[%d] %s\n", \ ++ (UINT_32)((_pkt_profile)->rHardXmitArrivalTimestamp), \ ++ (UINT_32)((_pkt_profile)->rEnqueueTimestamp), \ ++ (UINT_32)((_pkt_profile)->rDequeueTimestamp), \ ++ (UINT_32)((_pkt_profile)->rHifTxDoneTimestamp), \ ++ (UINT_8)((_pkt_profile)->ucTcxFreeCount), \ ++ (UINT_16)((_pkt_profile)->u2RtpSn), \ ++ (_note)); \ ++ (_pkt_profile)->fgIsPrinted = TRUE; \ ++ } \ ++} ++ ++#define CHK_PROFILES_DELTA(_pkt1, _pkt2, _delta) \ ++ (CHECK_FOR_TIMEOUT((_pkt1)->rHardXmitArrivalTimestamp, (_pkt2)->rHardXmitArrivalTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt1)->rEnqueueTimestamp, (_pkt2)->rEnqueueTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt1)->rDequeueTimestamp, (_pkt2)->rDequeueTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt1)->rHifTxDoneTimestamp, (_pkt2)->rHifTxDoneTimestamp, (_delta))) ++ ++#define CHK_PROFILE_DELTA(_pkt, _delta) \ ++ (CHECK_FOR_TIMEOUT((_pkt)->rEnqueueTimestamp, (_pkt)->rHardXmitArrivalTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt)->rDequeueTimestamp, (_pkt)->rEnqueueTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt)->rHifTxDoneTimestamp, (_pkt)->rDequeueTimestamp, (_delta))) ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID nicTxInitialize(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt); ++ ++WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); ++ ++BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_8 *aucTxRlsCnt); ++ ++WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter); ++ ++UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); ++ ++WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue); ++ ++WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); ++ ++VOID nicTxRelease(IN P_ADAPTER_T prAdapter); ++ ++VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prNdisPacket); ++ ++WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); ++ ++WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter); ++#endif ++ ++WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _NIC_TX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h +new file mode 100644 +index 000000000000..d518aaf10eb5 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h +@@ -0,0 +1,192 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p.h#3 ++*/ ++ ++/* ++** Log: p2p.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * p2p interface revised to be sync. with HAL ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add parameter to control: ++ * 1) auto group owner ++ * 2) P2P-PS parameter (CTWindow, NoA descriptors) ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * correct WPS Device Password ID definition. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement get scan result. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * ++*/ ++ ++#ifndef _P2P_H ++#define _P2P_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* refer to 'Config Methods' in WPS */ ++#define WPS_CONFIG_USBA 0x0001 ++#define WPS_CONFIG_ETHERNET 0x0002 ++#define WPS_CONFIG_LABEL 0x0004 ++#define WPS_CONFIG_DISPLAY 0x0008 ++#define WPS_CONFIG_EXT_NFC 0x0010 ++#define WPS_CONFIG_INT_NFC 0x0020 ++#define WPS_CONFIG_NFC 0x0040 ++#define WPS_CONFIG_PBC 0x0080 ++#define WPS_CONFIG_KEYPAD 0x0100 ++ ++/* refer to 'Device Password ID' in WPS */ ++#define WPS_DEV_PASSWORD_ID_PIN 0x0000 ++#define WPS_DEV_PASSWORD_ID_USER 0x0001 ++#define WPS_DEV_PASSWORD_ID_MACHINE 0x0002 ++#define WPS_DEV_PASSWORD_ID_REKEY 0x0003 ++#define WPS_DEV_PASSWORD_ID_PUSHBUTTON 0x0004 ++#define WPS_DEV_PASSWORD_ID_REGISTRAR 0x0005 ++ ++#define P2P_DEVICE_TYPE_NUM 2 ++#define P2P_DEVICE_NAME_LENGTH 32 ++#define P2P_NETWORK_NUM 8 ++#define P2P_MEMBER_NUM 8 ++ ++#define P2P_WILDCARD_SSID "DIRECT-" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++struct _P2P_INFO_T { ++ UINT_32 u4DeviceNum; ++ EVENT_P2P_DEV_DISCOVER_RESULT_T arP2pDiscoverResult[CFG_MAX_NUM_BSS_LIST]; ++ PUINT_8 pucCurrIePtr; ++ UINT_8 aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]; /* A common pool for IE of all scan results. */ ++}; ++ ++typedef enum { ++ ENUM_P2P_PEER_GROUP, ++ ENUM_P2P_PEER_DEVICE, ++ ENUM_P2P_PEER_NUM ++} ENUM_P2P_PEER_TYPE, *P_ENUM_P2P_PEER_TYPE; ++ ++typedef struct _P2P_DEVICE_INFO { ++ UINT_8 aucDevAddr[PARAM_MAC_ADDR_LEN]; ++ UINT_8 aucIfAddr[PARAM_MAC_ADDR_LEN]; ++ UINT_8 ucDevCapabilityBitmap; ++ INT_32 i4ConfigMethod; ++ UINT_8 aucPrimaryDeviceType[8]; ++ UINT_8 aucSecondaryDeviceType[8]; ++ UINT_8 aucDeviceName[P2P_DEVICE_NAME_LENGTH]; ++} P2P_DEVICE_INFO, *P_P2P_DEVICE_INFO; ++ ++typedef struct _P2P_GROUP_INFO { ++ PARAM_SSID_T rGroupID; ++ P2P_DEVICE_INFO rGroupOwnerInfo; ++ UINT_8 ucMemberNum; ++ P2P_DEVICE_INFO arMemberInfo[P2P_MEMBER_NUM]; ++} P2P_GROUP_INFO, *P_P2P_GROUP_INFO; ++ ++typedef struct _P2P_NETWORK_INFO { ++ ENUM_P2P_PEER_TYPE eNodeType; ++ ++ union { ++ P2P_GROUP_INFO rGroupInfo; ++ P2P_DEVICE_INFO rDeviceInfo; ++ } node; ++ ++} P2P_NETWORK_INFO, *P_P2P_NETWORK_INFO; ++ ++typedef struct _P2P_NETWORK_LIST { ++ UINT_8 ucNetworkNum; ++ P2P_NETWORK_INFO rP2PNetworkInfo[P2P_NETWORK_NUM]; ++} P2P_NETWORK_LIST, *P_P2P_NETWORK_LIST; ++ ++typedef struct _P2P_DISCONNECT_INFO { ++ UINT_8 ucRole; ++ UINT_8 ucRsv[3]; ++} P2P_DISCONNECT_INFO, *P_P2P_DISCONNECT_INFO; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#endif /*_P2P_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h +new file mode 100644 +index 000000000000..7f7a92584c7c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h +@@ -0,0 +1,83 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "p2p_cmd_buf.h" ++ \brief In this file we define the structure for Command Packet. ++ ++ In this file we define the structure for Command Packet and the control unit ++ of MGMT Memory Pool. ++*/ ++ ++/* ++** Log: p2p_cmd_buf.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++*/ ++ ++#ifndef _P2P_CMD_BUF_H ++#define _P2P_CMD_BUF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*--------------------------------------------------------------*/ ++/* Firmware Command Packer */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); ++ ++#endif /* _P2P_CMD_BUF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h +new file mode 100644 +index 000000000000..76115dabe1a1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h +@@ -0,0 +1,207 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_mac.h#2 ++*/ ++ ++/*! \file "p2p_mac.h" ++ \brief Brief description. ++ ++ Detail description. ++*/ ++ ++#ifndef _P2P_MAC_H ++#define _P2P_MAC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define ACTION_PUBLIC_WIFI_DIRECT 9 ++#define ACTION_GAS_INITIAL_REQUEST 10 ++#define ACTION_GAS_INITIAL_RESPONSE 11 ++#define ACTION_GAS_COMEBACK_REQUEST 12 ++#define ACTION_GAS_COMEBACK_RESPONSE 13 ++ ++/* P2P 4.2.8.1 - P2P Public Action Frame Type. */ ++#define P2P_PUBLIC_ACTION_GO_NEGO_REQ 0 ++#define P2P_PUBLIC_ACTION_GO_NEGO_RSP 1 ++#define P2P_PUBLIC_ACTION_GO_NEGO_CFM 2 ++#define P2P_PUBLIC_ACTION_INVITATION_REQ 3 ++#define P2P_PUBLIC_ACTION_INVITATION_RSP 4 ++#define P2P_PUBLIC_ACTION_DEV_DISCOVER_REQ 5 ++#define P2P_PUBLIC_ACTION_DEV_DISCOVER_RSP 6 ++#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_REQ 7 ++#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_RSP 8 ++ ++/* P2P 4.2.9.1 - P2P Action Frame Type */ ++#define P2P_ACTION_NOTICE_OF_ABSENCE 0 ++#define P2P_ACTION_P2P_PRESENCE_REQ 1 ++#define P2P_ACTION_P2P_PRESENCE_RSP 2 ++#define P2P_ACTION_GO_DISCOVER_REQ 3 ++ ++#define P2P_PUBLIC_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+8) ++#define P2P_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+7) ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/* P2P 4.2.8.2 P2P Public Action Frame Format */ ++typedef struct _P2P_PUBLIC_ACTION_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ ++ UINT_8 ucOuiType; /* 0x09 */ ++ UINT_8 ucOuiSubtype; /* GO Nego Req/Rsp/Cfm, P2P Invittion Req/Rsp, Device Discoverability Req/Rsp */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_8 aucInfoElem[1]; /* P2P IE, WSC IE. */ ++} __KAL_ATTRIB_PACKED__ P2P_PUBLIC_ACTION_FRAME_T, *P_P2P_PUBLIC_ACTION_FRAME_T; ++ ++/* P2P 4.2.9.1 - General Action Frame Format. */ ++typedef struct _P2P_ACTION_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Action Frame Body */ ++ UINT_8 ucCategory; /* 0x7F */ ++ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ ++ UINT_8 ucOuiType; /* 0x09 */ ++ UINT_8 ucOuiSubtype; /* */ ++ UINT_8 ucDialogToken; ++ UINT_8 aucInfoElem[1]; ++} __KAL_ATTRIB_PACKED__ P2P_ACTION_FRAME_T, *P_P2P_ACTION_FRAME_T; ++ ++/* P2P C.1 GAS Public Action Initial Request Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T; ++ ++/* P2P C.2 GAS Public Action Initial Response Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_16 u2StatusCode; /* Initial Response. */ ++ UINT_16 u2ComebackDelay; /* Initial Response. *//* In unit of TU. */ ++ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T; ++ ++/* P2P C.3-1 GAS Public Action Comeback Request Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T; ++ ++/* P2P C.3-2 GAS Public Action Comeback Response Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_16 u2StatusCode; /* Comeback Response. */ ++ UINT_8 ucFragmentID; /*Comeback Response. */ ++ UINT_16 u2ComebackDelay; /* Comeback Response. */ ++ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T; ++ ++typedef struct _P2P_SD_VENDER_SPECIFIC_CONTENT_T { ++ /* Service Discovery Vendor-specific Content. */ ++ UINT_8 ucOuiSubtype; /* 0x09 */ ++ UINT_16 u2ServiceUpdateIndicator; ++ UINT_8 aucServiceTLV[1]; ++} __KAL_ATTRIB_PACKED__ P2P_SD_VENDER_SPECIFIC_CONTENT_T, *P_P2P_SD_VENDER_SPECIFIC_CONTENT_T; ++ ++typedef struct _P2P_SERVICE_REQUEST_TLV_T { ++ UINT_16 u2Length; ++ UINT_8 ucServiceProtocolType; ++ UINT_8 ucServiceTransID; ++ UINT_8 aucQueryData[1]; ++} __KAL_ATTRIB_PACKED__ P2P_SERVICE_REQUEST_TLV_T, *P_P2P_SERVICE_REQUEST_TLV_T; ++ ++typedef struct _P2P_SERVICE_RESPONSE_TLV_T { ++ UINT_16 u2Length; ++ UINT_8 ucServiceProtocolType; ++ UINT_8 ucServiceTransID; ++ UINT_8 ucStatusCode; ++ UINT_8 aucResponseData[1]; ++} __KAL_ATTRIB_PACKED__ P2P_SERVICE_RESPONSE_TLV_T, *P_P2P_SERVICE_RESPONSE_TLV_T; ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h +new file mode 100644 +index 000000000000..0a87bd457a92 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h +@@ -0,0 +1,62 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic.h#1 ++*/ ++ ++/*! \file "p2p_nic.h" ++ \brief The declaration of nic functions ++ ++ Detail description. ++*/ ++ ++#ifndef _P2P_NIC_H ++#define _P2P_NIC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID ++nicP2pMediaStateChange(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); ++ ++VOID ++nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, ++ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h +new file mode 100644 +index 000000000000..cea77414ce35 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h +@@ -0,0 +1,70 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic_cmd_event.h#1 ++*/ ++ ++/*! \file p2p_nic_cmd_event.h ++ \brief ++*/ ++ ++#ifndef _P2P_NIC_CMD_EVENT_H ++#define _P2P_NIC_CMD_EVENT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++typedef struct _EVENT_P2P_DEV_DISCOVER_RESULT_T { ++/* UINT_8 aucCommunicateAddr[MAC_ADDR_LEN]; // Deprecated. */ ++ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ ++ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Device Address. */ ++ UINT_8 ucDeviceCapabilityBitmap; ++ UINT_8 ucGroupCapabilityBitmap; ++ UINT_16 u2ConfigMethod; /* Configure Method. */ ++ P2P_DEVICE_TYPE_T rPriDevType; ++ UINT_8 ucSecDevTypeNum; ++ P2P_DEVICE_TYPE_T arSecDevType[2]; ++ UINT_16 u2NameLength; ++ UINT_8 aucName[32]; ++ PUINT_8 pucIeBuf; ++ UINT_16 u2IELength; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ /* TODO: Service Information or PasswordID valid? */ ++} EVENT_P2P_DEV_DISCOVER_RESULT_T, *P_EVENT_P2P_DEV_DISCOVER_RESULT_T; ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h +new file mode 100644 +index 000000000000..dbfb90d94ee4 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h +@@ -0,0 +1,971 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/que_mgt.h#1 ++*/ ++ ++/*! \file "que_mgt.h" ++ \brief TX/RX queues management header file ++ ++ The main tasks of queue management include TC-based HIF TX flow control, ++ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save ++ forwarding control, RX packet reordering, and RX BA agreement management. ++*/ ++ ++/* ++** Log: que_mgt.h ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 07 26 2011 eddie.chen ++ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter ++ * API for query the RX reorder queued packets counter. ++ * ++ * 06 14 2011 eddie.chen ++ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 ++ * Change the parameter for WMM pass. ++ * ++ * 05 31 2011 eddie.chen ++ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 ++ * Fix the QM quota in MT5931. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 04 14 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Check the SW RFB free. Fix the compile warning.. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW ++ * Fix wmm parameters in beacon for BOW. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 01 12 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * 1) Check Bss if support QoS before adding WMMIE ++ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 07 22 2010 george.huang ++ * ++ * Update fgIsQoS information in BSS INFO by CMD ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 13 2010 yarco.yang ++ * ++ * [WPD00003849] ++ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 30 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled adaptive TC resource control ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 19 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * By default enabling dynamic STA_REC activation and decactivation ++ * ++ * 03 17 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) ++ * ++ * 03 11 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Fixed buffer leak when processing BAR frames ++ * ++ * 02 25 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled multi-STA TX path with fairness ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled dynamically activating and deactivating STA_RECs ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added code for dynamic activating and deactivating STA_RECs. ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:04:53 GMT MTK02468 ++** Added RX buffer reordering function prototypes ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-02 22:08:44 GMT MTK02468 ++** Added macro QM_INIT_STA_REC for initialize a STA_REC ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 21:58:43 GMT mtk02468 ++** Initial version ++** ++*/ ++ ++#ifndef _QUE_MGT_H ++#define _QUE_MGT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* Queue Manager Features */ ++/* 1: Indicate the last TX packet to the FW for each burst */ ++#define QM_BURST_END_INFO_ENABLED 1 ++/* 1: To fairly share TX resource among active STAs */ ++#define QM_FORWARDING_FAIRNESS 1 ++/* 1: To adaptively adjust resource for each TC */ ++#define QM_ADAPTIVE_TC_RESOURCE_CTRL 1 ++/* 1: To print TC resource adjustment results */ ++#define QM_PRINT_TC_RESOURCE_CTRL 0 ++/* 1: If pkt with SSN is missing, auto advance the RX reordering window */ ++#define QM_RX_WIN_SSN_AUTO_ADVANCING 1 ++/* 1: Indicate the packets falling behind to OS before the frame with SSN is received */ ++#define QM_RX_INIT_FALL_BEHIND_PASS 1 ++/* 1: Count times of TC resource empty happened */ ++#define QM_TC_RESOURCE_EMPTY_COUNTER 1 ++/* Parameters */ ++ ++/* ++ In TDLS or AP mode, peer maybe enter "sleep mode". ++ ++ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, ++ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets ++ u4TimeToAdjustTcResource = 3, ++ then we will adjust TC resouce for VI or VO. ++ ++ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, ++ we will to wait about 12 seconds to collect 180 packets. ++ but the test time is only 20 seconds. ++*/ ++#define QM_INIT_TIME_TO_UPDATE_QUE_LEN 60 /* p: Update queue lengths when p TX packets are enqueued */ ++#define QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN 5 ++ ++#define QM_INIT_TIME_TO_ADJUST_TC_RSC 3 /* s: Adjust the TC resource every s updates of queue lengths */ ++#define QM_QUE_LEN_MOVING_AVE_FACTOR 3 /* Factor for Que Len averaging */ ++ ++#define QM_MIN_RESERVED_TC0_RESOURCE 1 ++#define QM_MIN_RESERVED_TC1_RESOURCE 1 ++#define QM_MIN_RESERVED_TC2_RESOURCE 1 ++#define QM_MIN_RESERVED_TC3_RESOURCE 1 ++#define QM_MIN_RESERVED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ ++#define QM_MIN_RESERVED_TC5_RESOURCE 1 ++ ++#if defined(MT6620) ++ ++#define QM_GUARANTEED_TC0_RESOURCE 4 ++#define QM_GUARANTEED_TC1_RESOURCE 4 ++#define QM_GUARANTEED_TC2_RESOURCE 9 ++#define QM_GUARANTEED_TC3_RESOURCE 11 ++#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ ++#define QM_GUARANTEED_TC5_RESOURCE 4 ++ ++#elif defined(MT6628) ++ ++#define QM_GUARANTEED_TC0_RESOURCE 4 ++#define QM_GUARANTEED_TC1_RESOURCE 4 ++#define QM_GUARANTEED_TC2_RESOURCE 6 ++#define QM_GUARANTEED_TC3_RESOURCE 6 ++#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ ++#define QM_GUARANTEED_TC5_RESOURCE 4 ++ ++#else ++#error ++#endif ++ ++#define QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY 0 ++ ++#define QM_TOTAL_TC_RESOURCE (\ ++ NIC_TX_BUFF_COUNT_TC0 + NIC_TX_BUFF_COUNT_TC1 +\ ++ NIC_TX_BUFF_COUNT_TC2 + NIC_TX_BUFF_COUNT_TC3 +\ ++ NIC_TX_BUFF_COUNT_TC5) ++#define QM_AVERAGE_TC_RESOURCE 6 ++ ++/* Note: QM_INITIAL_RESIDUAL_TC_RESOURCE shall not be less than 0 */ ++/* for 6628: QM_TOTAL_TC_RESOURCE = 28, RESIDUAL = 4 4 6 6 2 4 = 26 */ ++#define QM_INITIAL_RESIDUAL_TC_RESOURCE (QM_TOTAL_TC_RESOURCE - \ ++ (QM_GUARANTEED_TC0_RESOURCE +\ ++ QM_GUARANTEED_TC1_RESOURCE +\ ++ QM_GUARANTEED_TC2_RESOURCE +\ ++ QM_GUARANTEED_TC3_RESOURCE +\ ++ QM_GUARANTEED_TC5_RESOURCE \ ++ )) ++ ++/* Hard-coded network type for Phase 3: NETWORK_TYPE_AIS/P2P/BOW */ ++#define QM_OPERATING_NETWORK_TYPE NETWORK_TYPE_AIS ++ ++#define QM_TEST_MODE 0 ++#define QM_TEST_TRIGGER_TX_COUNT 50 ++#define QM_TEST_STA_REC_DETERMINATION 0 ++#define QM_TEST_STA_REC_DEACTIVATION 0 ++#define QM_TEST_FAIR_FORWARDING 0 ++ ++#define QM_DEBUG_COUNTER 0 ++ ++/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ ++/* Per-Type Queues: [0] BMCAST */ ++#define NUM_OF_PER_STA_TX_QUEUES 5 ++#define NUM_OF_PER_TYPE_TX_QUEUES 1 ++ ++/* These two constants are also used for FW to verify the STA_REC index */ ++#define STA_REC_INDEX_BMCAST 0xFF ++#define STA_REC_INDEX_NOT_FOUND 0xFE ++ ++/* TX Queue Index */ ++#define TX_QUEUE_INDEX_BMCAST 0 ++#define TX_QUEUE_INDEX_NO_STA_REC 0 ++#define TX_QUEUE_INDEX_AC0 0 ++#define TX_QUEUE_INDEX_AC1 1 ++#define TX_QUEUE_INDEX_AC2 2 ++#define TX_QUEUE_INDEX_AC3 3 ++#define TX_QUEUE_INDEX_802_1X 4 ++#define TX_QUEUE_INDEX_NON_QOS 1 ++ ++/* 1 WMM-related */ ++/* WMM FLAGS */ ++#define WMM_FLAG_SUPPORT_WMM BIT(0) ++#define WMM_FLAG_SUPPORT_WMMSA BIT(1) ++#define WMM_FLAG_AC_PARAM_PRESENT BIT(2) ++#define WMM_FLAG_SUPPORT_UAPSD BIT(3) ++ ++/* WMM Admission Control Mandatory FLAGS */ ++#define ACM_FLAG_ADM_NOT_REQUIRED 0 ++#define ACM_FLAG_ADM_GRANTED BIT(0) ++#define ACM_FLAG_ADM_REQUIRED BIT(1) ++ ++/* WMM Power Saving FLAGS */ ++#define AC_FLAG_TRIGGER_ENABLED BIT(1) ++#define AC_FLAG_DELIVERY_ENABLED BIT(2) ++ ++/* WMM-2.2.1 WMM Information Element */ ++#define ELEM_MAX_LEN_WMM_INFO 7 ++ ++/* WMM-2.2.2 WMM Parameter Element */ ++#define ELEM_MAX_LEN_WMM_PARAM 24 ++ ++/* WMM-2.2.1 WMM QoS Info field */ ++#define WMM_QOS_INFO_PARAM_SET_CNT BITS(0, 3) /* Sent by AP */ ++#define WMM_QOS_INFO_UAPSD BIT(7) ++ ++#define WMM_QOS_INFO_VO_UAPSD BIT(0) /* Sent by non-AP STA */ ++#define WMM_QOS_INFO_VI_UAPSD BIT(1) ++#define WMM_QOS_INFO_BK_UAPSD BIT(2) ++#define WMM_QOS_INFO_BE_UAPSD BIT(3) ++#define WMM_QOS_INFO_MAX_SP_LEN_MASK BITS(5, 6) ++#define WMM_QOS_INFO_MAX_SP_ALL 0 ++#define WMM_QOS_INFO_MAX_SP_2 BIT(5) ++#define WMM_QOS_INFO_MAX_SP_4 BIT(6) ++#define WMM_QOS_INFO_MAX_SP_6 BITS(5, 6) ++ ++/* -- definitions for Max SP length field */ ++#define WMM_MAX_SP_LENGTH_ALL 0 ++#define WMM_MAX_SP_LENGTH_2 2 ++#define WMM_MAX_SP_LENGTH_4 4 ++#define WMM_MAX_SP_LENGTH_6 6 ++ ++/* WMM-2.2.2 WMM ACI/AIFSN field */ ++/* -- subfields in the ACI/AIFSN field */ ++#define WMM_ACIAIFSN_AIFSN BITS(0, 3) ++#define WMM_ACIAIFSN_ACM BIT(4) ++#define WMM_ACIAIFSN_ACI BITS(5, 6) ++#define WMM_ACIAIFSN_ACI_OFFSET 5 ++ ++/* -- definitions for ACI field */ ++#define WMM_ACI_AC_BE 0 ++#define WMM_ACI_AC_BK BIT(5) ++#define WMM_ACI_AC_VI BIT(6) ++#define WMM_ACI_AC_VO BITS(5, 6) ++ ++#define WMM_ACI(_AC) (_AC << WMM_ACIAIFSN_ACI_OFFSET) ++ ++/* -- definitions for ECWmin/ECWmax field */ ++#define WMM_ECW_WMIN_MASK BITS(0, 3) ++#define WMM_ECW_WMAX_MASK BITS(4, 7) ++#define WMM_ECW_WMAX_OFFSET 4 ++ ++#define TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME 0 /* Unit: 64 us */ ++ ++#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS (1000) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++enum { ++ QM_DBG_CNT_00 = 0, ++ QM_DBG_CNT_01, ++ QM_DBG_CNT_02, ++ QM_DBG_CNT_03, ++ QM_DBG_CNT_04, ++ QM_DBG_CNT_05, ++ QM_DBG_CNT_06, ++ QM_DBG_CNT_07, ++ QM_DBG_CNT_08, ++ QM_DBG_CNT_09, ++ QM_DBG_CNT_10, ++ QM_DBG_CNT_11, ++ QM_DBG_CNT_12, ++ QM_DBG_CNT_13, ++ QM_DBG_CNT_14, ++ QM_DBG_CNT_15, ++ QM_DBG_CNT_16, ++ QM_DBG_CNT_17, ++ QM_DBG_CNT_18, ++ QM_DBG_CNT_19, ++ QM_DBG_CNT_20, ++ QM_DBG_CNT_21, ++ QM_DBG_CNT_22, ++ QM_DBG_CNT_23, ++ QM_DBG_CNT_24, ++ QM_DBG_CNT_25, ++ QM_DBG_CNT_26, ++ QM_DBG_CNT_27, ++ QM_DBG_CNT_28, ++ QM_DBG_CNT_29, ++ QM_DBG_CNT_30, ++ QM_DBG_CNT_31, ++ QM_DBG_CNT_NUM ++}; ++ ++/* Used for MAC TX */ ++typedef enum _ENUM_MAC_TX_QUEUE_INDEX_T { ++ MAC_TX_QUEUE_AC0_INDEX = 0, ++ MAC_TX_QUEUE_AC1_INDEX, ++ MAC_TX_QUEUE_AC2_INDEX, ++ MAC_TX_QUEUE_AC3_INDEX, ++ MAC_TX_QUEUE_AC4_INDEX, ++ MAC_TX_QUEUE_AC5_INDEX, ++ MAC_TX_QUEUE_AC6_INDEX, ++ MAC_TX_QUEUE_BCN_INDEX, ++ MAC_TX_QUEUE_BMC_INDEX, ++ MAC_TX_QUEUE_NUM ++} ENUM_MAC_TX_QUEUE_INDEX_T; ++ ++typedef struct _RX_BA_ENTRY_T { ++ BOOLEAN fgIsValid; ++ QUE_T rReOrderQue; ++ UINT_16 u2WinStart; ++ UINT_16 u2WinEnd; ++ UINT_16 u2WinSize; ++ ++ /* For identifying the RX BA agreement */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucTid; ++ ++ BOOLEAN fgIsWaitingForPktWithSsn; ++ ++ /* UINT_8 ucTxBufferSize; */ ++ /* BOOL fgIsAcConstrain; */ ++ /* BOOL fgIsBaEnabled; */ ++} RX_BA_ENTRY_T, *P_RX_BA_ENTRY_T; ++ ++/* The mailbox message (could be used for Host-To-Device or Device-To-Host Mailbox) */ ++typedef struct _MAILBOX_MSG_T { ++ UINT_32 u4Msg[2]; /* [0]: D2HRM0R or H2DRM0R, [1]: D2HRM1R or H2DRM1R */ ++} MAILBOX_MSG_T, *P_MAILBOX_MSG_T; ++ ++/* Used for adaptively adjusting TC resources */ ++typedef struct _TC_RESOURCE_CTRL_T { ++ /* TC0, TC1, TC2, TC3, TC5 */ ++ UINT_32 au4AverageQueLen[TC_NUM - 1]; ++} TC_RESOURCE_CTRL_T, *P_TC_RESOURCE_CTRL_T; ++ ++typedef struct _QUE_MGT_T { /* Queue Management Control Info */ ++ ++ /* Per-Type Queues: [0] BMCAST or UNKNOWN-STA packets */ ++ QUE_T arTxQueue[NUM_OF_PER_TYPE_TX_QUEUES]; ++ ++#if 0 ++ /* For TX Scheduling */ ++ UINT_8 arRemainingTxOppt[NUM_OF_PER_STA_TX_QUEUES]; ++ UINT_8 arCurrentTxStaIndex[NUM_OF_PER_STA_TX_QUEUES]; ++ ++#endif ++ ++ /* Reordering Queue Parameters */ ++ RX_BA_ENTRY_T arRxBaTable[CFG_NUM_OF_RX_BA_AGREEMENTS]; ++ ++ /* Current number of activated RX BA agreements <= CFG_NUM_OF_RX_BA_AGREEMENTS */ ++ UINT_8 ucRxBaCount; ++ ++#if QM_TEST_MODE ++ UINT_32 u4PktCount; ++ P_ADAPTER_T prAdapter; ++ ++#if QM_TEST_FAIR_FORWARDING ++ UINT_32 u4CurrentStaRecIndexToEnqueue; ++#endif ++ ++#endif ++ ++#if QM_FORWARDING_FAIRNESS ++ /* The current TX count for a STA with respect to a TC index */ ++ UINT_32 au4ForwardCount[NUM_OF_PER_STA_TX_QUEUES]; ++ ++ /* The current serving STA with respect to a TC index */ ++ UINT_32 au4HeadStaRecIndex[NUM_OF_PER_STA_TX_QUEUES]; ++#endif ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ UINT_32 au4AverageQueLen[TC_NUM]; ++ UINT_32 au4CurrentTcResource[TC_NUM]; ++ UINT_32 au4MinReservedTcResource[TC_NUM]; /* The minimum amount of resource no matter busy or idle */ ++ UINT_32 au4GuaranteedTcResource[TC_NUM]; /* The minimum amount of resource when extremely busy */ ++ ++ UINT_32 u4TimeToAdjustTcResource; ++ UINT_32 u4TimeToUpdateQueLen; ++ UINT_32 u4TxNumOfVi, u4TxNumOfVo; /* number of VI/VO packets */ ++ ++ /* Set to TRUE if the last TC adjustment has not been completely applied (i.e., waiting more TX-Done events ++ to align the TC quotas to the TC resource assignment) */ ++ BOOLEAN fgTcResourcePostAnnealing; ++ ++#endif ++ ++#if QM_DEBUG_COUNTER ++ UINT_32 au4QmDebugCounters[QM_DBG_CNT_NUM]; ++#endif ++#if QM_TC_RESOURCE_EMPTY_COUNTER ++ UINT_32 au4QmTcResourceEmptyCounter[NET_TYPE_NUM][TC_NUM]; ++ UINT_32 au4QmTcResourceBackCounter[TC_NUM]; ++ UINT_32 au4DequeueNoTcResourceCounter[TC_NUM]; ++ ++ UINT_32 au4ResourceUsedCounter[TC_NUM]; ++ ++ UINT_32 au4ResourceWantedCounter[TC_NUM]; ++ ++ UINT_32 u4EnqeueuCounter; ++ UINT_32 u4DequeueCounter; ++#endif ++} QUE_MGT_T, *P_QUE_MGT_T; ++ ++typedef struct _EVENT_RX_ADDBA_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Fields not present in the received ADDBA_REQ */ ++ UINT_8 ucStaRecIdx; ++ ++ /* Fields that are present in the received ADDBA_REQ */ ++ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ ++ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ ++ UINT_16 u2BATimeoutValue; ++ UINT_16 u2BAStartSeqCtrl; /* SSN */ ++ ++} EVENT_RX_ADDBA_T, *P_EVENT_RX_ADDBA_T; ++ ++typedef struct _EVENT_RX_DELBA_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Fields not present in the received ADDBA_REQ */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucTid; ++} EVENT_RX_DELBA_T, *P_EVENT_RX_DELBA_T; ++ ++typedef struct _EVENT_BSS_ABSENCE_PRESENCE_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Event Body */ ++ UINT_8 ucNetTypeIdx; ++ BOOLEAN fgIsAbsent; ++ UINT_8 ucBssFreeQuota; ++ UINT_8 aucReserved[1]; ++} EVENT_BSS_ABSENCE_PRESENCE_T, *P_EVENT_BSS_ABSENCE_PRESENCE_T; ++ ++typedef struct _EVENT_STA_CHANGE_PS_MODE_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Event Body */ ++ UINT_8 ucStaRecIdx; ++ BOOLEAN fgIsInPs; ++ UINT_8 ucUpdateMode; ++ UINT_8 ucFreeQuota; ++} EVENT_STA_CHANGE_PS_MODE_T, *P_EVENT_STA_CHANGE_PS_MODE_T; ++ ++/* The free quota is used by PS only now */ ++/* The event may be used by per STA flow conttrol in general */ ++typedef struct _EVENT_STA_UPDATE_FREE_QUOTA_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Event Body */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucUpdateMode; ++ UINT_8 ucFreeQuota; ++ UINT_8 aucReserved[1]; ++} EVENT_STA_UPDATE_FREE_QUOTA_T, *P_EVENT_STA_UPDATE_FREE_QUOTA_T; ++ ++/* WMM-2.2.1 WMM Information Element */ ++typedef struct _IE_WMM_INFO_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ UINT_8 ucQosInfo; /* QoS Info field */ ++ UINT_8 ucDummy[3]; /* Dummy for pack */ ++} IE_WMM_INFO_T, *P_IE_WMM_INFO_T; ++ ++/* WMM-2.2.2 WMM Parameter Element */ ++typedef struct _IE_WMM_PARAM_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ ++ /* IE Body */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ ++ /* WMM IE Body */ ++ UINT_8 ucQosInfo; /* QoS Info field */ ++ UINT_8 ucReserved; ++ ++ /* AC Parameters */ ++ UINT_8 ucAciAifsn_BE; ++ UINT_8 ucEcw_BE; ++ UINT_8 aucTxopLimit_BE[2]; ++ ++ UINT_8 ucAciAifsn_BG; ++ UINT_8 ucEcw_BG; ++ UINT_8 aucTxopLimit_BG[2]; ++ ++ UINT_8 ucAciAifsn_VI; ++ UINT_8 ucEcw_VI; ++ UINT_8 aucTxopLimit_VI[2]; ++ ++ UINT_8 ucAciAifsn_VO; ++ UINT_8 ucEcw_VO; ++ UINT_8 aucTxopLimit_VO[2]; ++ ++} IE_WMM_PARAM_T, *P_IE_WMM_PARAM_T; ++ ++typedef struct _IE_WMM_TSPEC_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ /* WMM TSPEC body */ ++ UINT_8 aucTsInfo[3]; /* TS Info */ ++ UINT_8 aucTspecBodyPart[1]; /* Note: Utilize PARAM_QOS_TSPEC to fill (memory copy) */ ++} IE_WMM_TSPEC_T, *P_IE_WMM_TSPEC_T; ++ ++typedef struct _IE_WMM_HDR_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ UINT_8 aucBody[1]; /* IE body */ ++} IE_WMM_HDR_T, *P_IE_WMM_HDR_T; ++ ++typedef struct _AC_QUE_PARMS_T { ++ UINT_16 u2CWmin; /*!< CWmin */ ++ UINT_16 u2CWmax; /*!< CWmax */ ++ UINT_16 u2TxopLimit; /*!< TXOP limit */ ++ UINT_16 u2Aifsn; /*!< AIFSN */ ++ UINT_8 ucGuradTime; /*!< GuardTime for STOP/FLUSH. */ ++ BOOLEAN fgIsACMSet; ++} AC_QUE_PARMS_T, *P_AC_QUE_PARMS_T; ++ ++/* WMM ACI (AC index) */ ++typedef enum _ENUM_WMM_ACI_T { ++ WMM_AC_BE_INDEX = 0, ++ WMM_AC_BK_INDEX, ++ WMM_AC_VI_INDEX, ++ WMM_AC_VO_INDEX, ++ WMM_AC_INDEX_NUM ++} ENUM_WMM_ACI_T, *P_ENUM_WMM_ACI_T; ++ ++/* Used for CMD Queue Operation */ ++typedef enum _ENUM_FRAME_ACTION_T { ++ FRAME_ACTION_DROP_PKT = 0, ++ FRAME_ACTION_QUEUE_PKT, ++ FRAME_ACTION_TX_PKT, ++ FRAME_ACTION_NUM ++} ENUM_FRAME_ACTION_T; ++ ++typedef enum _ENUM_FRAME_TYPE_IN_CMD_Q_T { ++ FRAME_TYPE_802_1X = 0, ++ FRAME_TYPE_MMPDU, ++ FRAME_TYPE_NUM ++} ENUM_FRAME_TYPE_IN_CMD_Q_T; ++ ++typedef enum _ENUM_FREE_QUOTA_MODET_T { ++ FREE_QUOTA_UPDATE_MODE_INIT = 0, ++ FREE_QUOTA_UPDATE_MODE_OVERWRITE, ++ FREE_QUOTA_UPDATE_MODE_INCREASE, ++ FREE_QUOTA_UPDATE_MODE_DECREASE ++} ENUM_FREE_QUOTA_MODET_T, *P_ENUM_FREE_QUOTA_MODET_T; ++ ++typedef struct _CMD_UPDATE_WMM_PARMS_T { ++ AC_QUE_PARMS_T arACQueParms[AC_NUM]; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 fgIsQBSS; ++ UINT_8 aucReserved[2]; ++} CMD_UPDATE_WMM_PARMS_T, *P_CMD_UPDATE_WMM_PARMS_T; ++ ++typedef struct _CMD_TX_AMPDU_T { ++ BOOLEAN fgEnable; ++ UINT_8 aucReserved[3]; ++} CMD_TX_AMPDU_T, *P_CMD_TX_AMPDU_T; ++ ++typedef struct _CMD_ADDBA_REJECT { ++ BOOLEAN fgEnable; ++ UINT_8 aucReserved[3]; ++} CMD_ADDBA_REJECT_T, *P_CMD_ADDBA_REJECT_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define QM_TX_SET_NEXT_MSDU_INFO(_prMsduInfoPreceding, _prMsduInfoNext) \ ++ ((((_prMsduInfoPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prMsduInfoNext)) ++ ++#define QM_TX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ ++ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) ++ ++#define QM_TX_GET_NEXT_MSDU_INFO(_prMsduInfo) \ ++ ((P_MSDU_INFO_T)(((_prMsduInfo)->rQueEntry).prNext)) ++ ++#define QM_RX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ ++ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) ++ ++#define QM_RX_GET_NEXT_SW_RFB(_prSwRfb) \ ++ ((P_SW_RFB_T)(((_prSwRfb)->rQueEntry).prNext)) ++ ++#if 0 ++#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ ++ ((((_ucIndex) != STA_REC_INDEX_BMCAST) && ((_ucIndex) != STA_REC_INDEX_NOT_FOUND)) ?\ ++ &(_prAdapter->arStaRec[_ucIndex]) : NULL) ++#endif ++ ++#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ ++ cnmGetStaRecByIndex(_prAdapter, _ucIndex) ++ ++#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(\ ++ _prMsduInfo,\ ++ _ucTC,\ ++ _ucPacketType,\ ++ _ucFormatID,\ ++ _fgIs802_1x,\ ++ _fgIs802_11,\ ++ _u2PalLLH,\ ++ _u2AclSN,\ ++ _ucPsForwardingType,\ ++ _ucPsSessionID\ ++ ) \ ++{\ ++ ASSERT(_prMsduInfo);\ ++ (_prMsduInfo)->ucTC = (_ucTC);\ ++ (_prMsduInfo)->ucPacketType = (_ucPacketType);\ ++ (_prMsduInfo)->ucFormatID = (_ucFormatID);\ ++ (_prMsduInfo)->fgIs802_1x = (_fgIs802_1x);\ ++ (_prMsduInfo)->fgIs802_11 = (_fgIs802_11);\ ++ (_prMsduInfo)->u2PalLLH = (_u2PalLLH);\ ++ (_prMsduInfo)->u2AclSN = (_u2AclSN);\ ++ (_prMsduInfo)->ucPsForwardingType = (_ucPsForwardingType);\ ++ (_prMsduInfo)->ucPsSessionID = (_ucPsSessionID);\ ++ (_prMsduInfo)->fgIsBurstEnd = (FALSE);\ ++} ++ ++#define QM_INIT_STA_REC(\ ++ _prStaRec,\ ++ _fgIsValid,\ ++ _fgIsQoS,\ ++ _pucMacAddr\ ++ )\ ++{\ ++ ASSERT(_prStaRec);\ ++ (_prStaRec)->fgIsValid = (_fgIsValid);\ ++ (_prStaRec)->fgIsQoS = (_fgIsQoS);\ ++ (_prStaRec)->fgIsInPS = FALSE; \ ++ (_prStaRec)->ucPsSessionID = 0xFF;\ ++ COPY_MAC_ADDR((_prStaRec)->aucMacAddr, (_pucMacAddr));\ ++} ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++#define QM_GET_TX_QUEUE_LEN(_prAdapter, _u4QueIdx) \ ++ ((_prAdapter->rQM.au4AverageQueLen[(_u4QueIdx)] >> QM_QUE_LEN_MOVING_AVE_FACTOR)) ++#endif ++ ++#define WMM_IE_OUI_TYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiType) ++#define WMM_IE_OUI_SUBTYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiSubtype) ++#define WMM_IE_OUI(fp) (((P_IE_WMM_HDR_T)(fp))->aucOui) ++ ++#if QM_DEBUG_COUNTER ++#define QM_DBG_CNT_INC(_prQM, _index) { (_prQM)->au4QmDebugCounters[(_index)]++; } ++#else ++#define QM_DBG_CNT_INC(_prQM, _index) {} ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Queue Management and STA_REC Initialization */ ++/*----------------------------------------------------------------------------*/ ++ ++VOID qmInit(IN P_ADAPTER_T prAdapter); ++ ++#if QM_TEST_MODE ++VOID qmTestCases(IN P_ADAPTER_T prAdapter); ++#endif ++ ++VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); ++ ++/*----------------------------------------------------------------------------*/ ++/* TX-Related Queue Management */ ++/*----------------------------------------------------------------------------*/ ++ ++P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter); ++ ++P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); ++ ++P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus); ++ ++VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus); ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter); ++ ++VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* RX-Related Queue Management */ ++/*----------------------------------------------------------------------------*/ ++ ++VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter); ++ ++P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter); ++ ++P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); ++ ++VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); ++ ++VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); ++ ++VOID ++qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); ++ ++VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); ++ ++BOOLEAN ++qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout); ++ ++VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); ++ ++VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg); ++ ++BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater); ++ ++VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid); ++ ++BOOLEAN ++qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize); ++ ++VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost); ++ ++VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); ++ ++VOID ++mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride); ++ ++VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams); ++ ++VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec); ++ ++/* Utility function: for deciding STA-REC index */ ++UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); ++ ++UINT_32 ++mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, ++ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf); ++ ++VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode); ++ ++VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++ENUM_FRAME_ACTION_T ++qmGetFrameAction(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, ++ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType); ++ ++VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); ++ ++VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID ++qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone); ++ ++VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter); ++ ++#if ARP_MONITER_ENABLE ++VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++VOID qmResetArpDetect(VOID); ++VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _QUE_MGT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h +new file mode 100644 +index 000000000000..2804b0387f5f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h +@@ -0,0 +1,1010 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/wlan_def.h#1 ++*/ ++ ++/*! \file "wlan_def.h" ++ \brief This file includes the basic definition of WLAN ++ ++*/ ++ ++/* ++** Log: wlan_def.h ++** ++** 09 02 2013 cp.wu ++** add path to handle reassociation request ++ * ++ * 12 05 2011 cp.wu ++ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path ++ * add CONNECT_BY_BSSID policy ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 wh.su ++ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h and let the sw ++ * structure not align at byte ++ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, ++ * Notice needed update P2P.ko. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Resize the Secondary Device Type array when WiFi Direct is enabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Add new station type MACRO. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 11 2010 kevin.huang ++ * [WCXRP00000068] [MT6620 Wi-Fi][Driver][FW] Fix STA RECORD sync issue and remove unused code ++ * Update ENUM_STA_ROLE_INDEX_T by using a fixed base value ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Update OP_MODE_BOW and include bow_fsm.h. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Change P2P Descriptor List to a pointer and allocate it dynamically to avoid structure corrupt by BssDescriptor free. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add a pointer in BSS Descriptor for P2P Descriptor. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add an Interface in BSS Descriptor. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Modify data structure for P2P Scan result. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add an operation mode for P2P device. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * P2P/RSN/WAPI IEs need to be declared with compact structure. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly ++ * dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P present boolean flag in BSS & Pre-BSS descriptor. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * move bss related data types to wlan_def.h to avoid recursive dependency. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:40 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _WLAN_DEF_H ++#define _WLAN_DEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* disconnect reason */ ++#define DISCONNECT_REASON_CODE_RESERVED 0 ++#define DISCONNECT_REASON_CODE_RADIO_LOST 1 ++#define DISCONNECT_REASON_CODE_DEAUTHENTICATED 2 ++#define DISCONNECT_REASON_CODE_DISASSOCIATED 3 ++#define DISCONNECT_REASON_CODE_NEW_CONNECTION 4 ++#define DISCONNECT_REASON_CODE_REASSOCIATION 5 ++#define DISCONNECT_REASON_CODE_ROAMING 6 ++ ++/* The rate definitions */ ++#define TX_MODE_CCK 0x00 ++#define TX_MODE_OFDM 0x40 ++#define TX_MODE_HT_MM 0x80 ++#define TX_MODE_HT_GF 0xC0 ++ ++#define RATE_CCK_SHORT_PREAMBLE 0x10 ++#define RATE_OFDM 0x20 ++ ++#define PHY_RATE_1M 0x0 ++#define PHY_RATE_2M 0x1 ++#define PHY_RATE_5_5M 0x2 ++#define PHY_RATE_11M 0x3 ++#define PHY_RATE_6M 0xB ++#define PHY_RATE_9M 0xF ++#define PHY_RATE_12M 0xA ++#define PHY_RATE_18M 0xE ++#define PHY_RATE_24M 0x9 ++#define PHY_RATE_36M 0xD ++#define PHY_RATE_48M 0x8 ++#define PHY_RATE_54M 0xC ++#define PHY_RATE_MCS0 0x0 ++#define PHY_RATE_MCS1 0x1 ++#define PHY_RATE_MCS2 0x2 ++#define PHY_RATE_MCS3 0x3 ++#define PHY_RATE_MCS4 0x4 ++#define PHY_RATE_MCS5 0x5 ++#define PHY_RATE_MCS6 0x6 ++#define PHY_RATE_MCS7 0x7 ++#define PHY_RATE_MCS32 0x20 ++ ++#define RATE_CCK_1M_LONG (TX_MODE_CCK | PHY_RATE_1M) ++#define RATE_CCK_2M_LONG (TX_MODE_CCK | PHY_RATE_2M) ++#define RATE_CCK_5_5M_LONG (TX_MODE_CCK | PHY_RATE_5_5M) ++#define RATE_CCK_11M_LONG (TX_MODE_CCK | PHY_RATE_11M) ++#define RATE_CCK_2M_SHORT (TX_MODE_CCK | PHY_RATE_2M | RATE_CCK_SHORT_PREAMBLE) ++#define RATE_CCK_5_5M_SHORT (TX_MODE_CCK | PHY_RATE_5_5M | RATE_CCK_SHORT_PREAMBLE) ++#define RATE_CCK_11M_SHORT (TX_MODE_CCK | PHY_RATE_11M | RATE_CCK_SHORT_PREAMBLE) ++#define RATE_OFDM_6M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_6M) ++#define RATE_OFDM_9M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_9M) ++#define RATE_OFDM_12M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_12M) ++#define RATE_OFDM_18M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_18M) ++#define RATE_OFDM_24M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_24M) ++#define RATE_OFDM_36M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_36M) ++#define RATE_OFDM_48M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_48M) ++#define RATE_OFDM_54M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_54M) ++ ++#define RATE_MM_MCS_0 (TX_MODE_HT_MM | PHY_RATE_MCS0) ++#define RATE_MM_MCS_1 (TX_MODE_HT_MM | PHY_RATE_MCS1) ++#define RATE_MM_MCS_2 (TX_MODE_HT_MM | PHY_RATE_MCS2) ++#define RATE_MM_MCS_3 (TX_MODE_HT_MM | PHY_RATE_MCS3) ++#define RATE_MM_MCS_4 (TX_MODE_HT_MM | PHY_RATE_MCS4) ++#define RATE_MM_MCS_5 (TX_MODE_HT_MM | PHY_RATE_MCS5) ++#define RATE_MM_MCS_6 (TX_MODE_HT_MM | PHY_RATE_MCS6) ++#define RATE_MM_MCS_7 (TX_MODE_HT_MM | PHY_RATE_MCS7) ++#define RATE_MM_MCS_32 (TX_MODE_HT_MM | PHY_RATE_MCS32) ++ ++#define RATE_GF_MCS_0 (TX_MODE_HT_GF | PHY_RATE_MCS0) ++#define RATE_GF_MCS_1 (TX_MODE_HT_GF | PHY_RATE_MCS1) ++#define RATE_GF_MCS_2 (TX_MODE_HT_GF | PHY_RATE_MCS2) ++#define RATE_GF_MCS_3 (TX_MODE_HT_GF | PHY_RATE_MCS3) ++#define RATE_GF_MCS_4 (TX_MODE_HT_GF | PHY_RATE_MCS4) ++#define RATE_GF_MCS_5 (TX_MODE_HT_GF | PHY_RATE_MCS5) ++#define RATE_GF_MCS_6 (TX_MODE_HT_GF | PHY_RATE_MCS6) ++#define RATE_GF_MCS_7 (TX_MODE_HT_GF | PHY_RATE_MCS7) ++#define RATE_GF_MCS_32 (TX_MODE_HT_GF | PHY_RATE_MCS32) ++ ++#define RATE_TX_MODE_MASK BITS(6, 7) ++#define RATE_TX_MODE_OFFSET 6 ++#define RATE_CODE_GET_TX_MODE(_ucRateCode) ((_ucRateCode & RATE_TX_MODE_MASK) >> RATE_TX_MODE_OFFSET) ++#define RATE_PHY_RATE_MASK BITS(0, 5) ++#define RATE_PHY_RATE_OFFSET 0 ++#define RATE_CODE_GET_PHY_RATE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_MASK) >> RATE_PHY_RATE_OFFSET) ++#define RATE_PHY_RATE_SHORT_PREAMBLE BIT(4) ++#define RATE_CODE_IS_SHORT_PREAMBLE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_SHORT_PREAMBLE)?TRUE:FALSE) ++ ++#define CHNL_LIST_SZ_2G 14 ++#define CHNL_LIST_SZ_5G 14 ++ ++/*! CNM(STA_RECORD_T) related definition */ ++#define CFG_STA_REC_NUM 20 ++ ++/* PHY TYPE bit definitions */ ++#define PHY_TYPE_BIT_HR_DSSS BIT(PHY_TYPE_HR_DSSS_INDEX) /* HR/DSSS PHY (clause 18) */ ++#define PHY_TYPE_BIT_ERP BIT(PHY_TYPE_ERP_INDEX) /* ERP PHY (clause 19) */ ++#define PHY_TYPE_BIT_OFDM BIT(PHY_TYPE_OFDM_INDEX) /* OFDM 5 GHz PHY (clause 17) */ ++#define PHY_TYPE_BIT_HT BIT(PHY_TYPE_HT_INDEX) /* HT PHY (clause 20) */ ++ ++/* PHY TYPE set definitions */ ++#define PHY_TYPE_SET_802_11ABGN (PHY_TYPE_BIT_OFDM | \ ++ PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11BGN (PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11GN (PHY_TYPE_BIT_ERP | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11AN (PHY_TYPE_BIT_OFDM | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11ABG (PHY_TYPE_BIT_OFDM | \ ++ PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP) ++ ++#define PHY_TYPE_SET_802_11BG (PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP) ++ ++#define PHY_TYPE_SET_802_11A (PHY_TYPE_BIT_OFDM) ++ ++#define PHY_TYPE_SET_802_11G (PHY_TYPE_BIT_ERP) ++ ++#define PHY_TYPE_SET_802_11B (PHY_TYPE_BIT_HR_DSSS) ++ ++#define PHY_TYPE_SET_802_11N (PHY_TYPE_BIT_HT) ++ ++/* Rate set bit definitions */ ++#define RATE_SET_BIT_1M BIT(RATE_1M_INDEX) /* Bit 0: 1M */ ++#define RATE_SET_BIT_2M BIT(RATE_2M_INDEX) /* Bit 1: 2M */ ++#define RATE_SET_BIT_5_5M BIT(RATE_5_5M_INDEX) /* Bit 2: 5.5M */ ++#define RATE_SET_BIT_11M BIT(RATE_11M_INDEX) /* Bit 3: 11M */ ++#define RATE_SET_BIT_22M BIT(RATE_22M_INDEX) /* Bit 4: 22M */ ++#define RATE_SET_BIT_33M BIT(RATE_33M_INDEX) /* Bit 5: 33M */ ++#define RATE_SET_BIT_6M BIT(RATE_6M_INDEX) /* Bit 6: 6M */ ++#define RATE_SET_BIT_9M BIT(RATE_9M_INDEX) /* Bit 7: 9M */ ++#define RATE_SET_BIT_12M BIT(RATE_12M_INDEX) /* Bit 8: 12M */ ++#define RATE_SET_BIT_18M BIT(RATE_18M_INDEX) /* Bit 9: 18M */ ++#define RATE_SET_BIT_24M BIT(RATE_24M_INDEX) /* Bit 10: 24M */ ++#define RATE_SET_BIT_36M BIT(RATE_36M_INDEX) /* Bit 11: 36M */ ++#define RATE_SET_BIT_48M BIT(RATE_48M_INDEX) /* Bit 12: 48M */ ++#define RATE_SET_BIT_54M BIT(RATE_54M_INDEX) /* Bit 13: 54M */ ++#define RATE_SET_BIT_HT_PHY BIT(RATE_HT_PHY_INDEX) /* Bit 14: BSS Selector */ ++ ++/* Rate set definitions */ ++#define RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M) ++ ++#define RATE_SET_ERP (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_18M | \ ++ RATE_SET_BIT_24M | \ ++ RATE_SET_BIT_36M | \ ++ RATE_SET_BIT_48M | \ ++ RATE_SET_BIT_54M) ++ ++#define RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_18M | \ ++ RATE_SET_BIT_24M | \ ++ RATE_SET_BIT_36M | \ ++ RATE_SET_BIT_48M | \ ++ RATE_SET_BIT_54M) ++ ++#define RATE_SET_OFDM (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_18M | \ ++ RATE_SET_BIT_24M | \ ++ RATE_SET_BIT_36M | \ ++ RATE_SET_BIT_48M | \ ++ RATE_SET_BIT_54M) ++ ++#define RATE_SET_HT (RATE_SET_ERP) ++/* #define RATE_SET_HT (RATE_SET_ERP | RATE_SET_BIT_HT_PHY) *//* NOTE(Kevin): TBD */ ++ ++#define RATE_SET_ALL_ABG RATE_SET_ERP ++ ++#define BASIC_RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M) ++ ++#define BASIC_RATE_SET_HR_DSSS_ERP (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M) ++ ++#define BASIC_RATE_SET_ERP (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define BASIC_RATE_SET_OFDM (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define BASIC_RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define INITIAL_RATE_SET_RCPI_100 RATE_SET_ALL_ABG ++ ++#define INITIAL_RATE_SET_RCPI_80 (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define INITIAL_RATE_SET_RCPI_60 (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M) ++ ++#define INITIAL_RATE_SET(_rcpi) (INITIAL_RATE_SET_ ## _rcpi) ++ ++#define RCPI_100 100 /* -60 dBm */ ++#define RCPI_80 80 /* -70 dBm */ ++#define RCPI_60 60 /* -80 dBm */ ++ ++/* The number of RCPI records used to calculate their average value */ ++#define MAX_NUM_RCPI_RECORDS 10 ++ ++/* The number of RCPI records used to calculate their average value */ ++#define NO_RCPI_RECORDS -128 ++#define MAX_RCPI_DBM 0 ++#define MIN_RCPI_DBM -100 ++ ++#define MAC_TX_RESERVED_FIELD 0 /* NOTE(Kevin): Should defined in tx.h */ ++ ++#define MAX_ASSOC_ID (CFG_STA_REC_NUM) /* Available AID: 1 ~ 20(STA_REC_NUM) */ ++ ++#define MAX_DEAUTH_INFO_COUNT 4 /* NOTE(Kevin): Used in auth.c */ ++#define MIN_DEAUTH_INTERVAL_MSEC 500 /* The minimum interval if continuously send Deauth Frame */ ++ ++/* Authentication Type */ ++#define AUTH_TYPE_OPEN_SYSTEM BIT(AUTH_ALGORITHM_NUM_OPEN_SYSTEM) ++#define AUTH_TYPE_SHARED_KEY BIT(AUTH_ALGORITHM_NUM_SHARED_KEY) ++#define AUTH_TYPE_FAST_BSS_TRANSITION BIT(AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) ++ ++/* Authentication Retry Limit */ ++#define TX_AUTH_ASSOCI_RETRY_LIMIT 2 ++#define TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING 1 ++ ++/* WMM-2.2.1 WMM Information Element */ ++#define ELEM_MAX_LEN_WMM_INFO 7 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef UINT_16 PHY_TYPE, *P_PHY_TYPE; ++typedef UINT_8 RCPI, *P_RCPI; ++typedef UINT_8 ALC_VAL, *P_ALC_VAL; ++ ++typedef enum _ENUM_HW_BSSID_T { ++ BSSID_0 = 0, ++ BSSID_1, ++ BSSID_NUM ++} ENUM_HW_BSSID_T; ++ ++typedef enum _ENUM_HW_MAC_ADDR_T { ++ MAC_ADDR_0 = 0, ++ MAC_ADDR_1, ++ MAC_ADDR_NUM ++} ENUM_HW_MAC_ADDR_T; ++ ++typedef enum _ENUM_HW_OP_MODE_T { ++ HW_OP_MODE_STA = 0, ++ HW_OP_MODE_AP, ++ HW_OP_MODE_ADHOC, ++ HW_OP_MODE_NUM ++} ENUM_HW_OP_MODE_T; ++ ++typedef enum _ENUM_TSF_T { ++ ENUM_LOCAL_TSF_0, ++ ENUM_LOCAL_TSF_1, ++ ENUM_LOCAL_TSF_NUM ++} ENUM_LOCAL_TSF_T, *P_ENUM_LOCAL_TSF_T; ++ ++typedef enum _HAL_TS_HW_UPDATE_MODE { ++ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME, ++ HAL_TSF_HW_UPDATE_BY_TICK_ONLY, ++ HAL_TSF_HW_UPDATE_BY_RECEIVED_FRAME_ONLY, ++ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME_AD_HOC ++} HAL_TSF_HW_UPDATE_MODE; ++ ++typedef enum _ENUM_AC_T { ++ AC0 = 0, ++ AC1, ++ AC2, ++ AC3, ++ AC_NUM ++} ENUM_AC_T, *P_ENUM_AC_T; ++ ++/* The Type of Network been activated */ ++typedef enum _ENUM_NETWORK_TYPE_INDEX_T { ++ NETWORK_TYPE_AIS_INDEX = 0, ++ NETWORK_TYPE_P2P_INDEX, ++ NETWORK_TYPE_BOW_INDEX, ++ NETWORK_TYPE_INDEX_NUM ++} ENUM_NETWORK_TYPE_INDEX_T; ++ ++/* The Type of STA Type. */ ++typedef enum _ENUM_STA_TYPE_INDEX_T { ++ STA_TYPE_LEGACY_INDEX = 0, ++ STA_TYPE_P2P_INDEX, ++ STA_TYPE_BOW_INDEX, ++ STA_TYPE_INDEX_NUM ++} ENUM_STA_TYPE_INDEX_T; ++ ++#define STA_ROLE_BASE_INDEX 4 ++ ++typedef enum _ENUM_STA_ROLE_INDEX_T { ++ STA_ROLE_ADHOC_INDEX = STA_ROLE_BASE_INDEX, /* 4 */ ++ STA_ROLE_CLIENT_INDEX, ++ STA_ROLE_AP_INDEX, ++ STA_ROLE_TDLS_INDEX, ++ STA_ROLE_DLS_INDEX /* Note: need to extend P_CMD_UPDATE_STA_RECORD_T */ ++} ENUM_STA_ROLE_INDEX_T; ++ ++/* The Power State of a specific Network */ ++typedef enum _ENUM_PWR_STATE_T { ++ PWR_STATE_IDLE = 0, ++ PWR_STATE_ACTIVE, ++ PWR_STATE_PS, ++ PWR_STATE_NUM ++} ENUM_PWR_STATE_T; ++ ++typedef enum _ENUM_PHY_TYPE_INDEX_T { ++ /* PHY_TYPE_DSSS_INDEX, *//* DSSS PHY (clause 15) -- Not used anymore */ ++ PHY_TYPE_HR_DSSS_INDEX = 0, /* HR/DSSS PHY (clause 18) */ ++ PHY_TYPE_ERP_INDEX, /* ERP PHY (clause 19) */ ++ PHY_TYPE_ERP_P2P_INDEX, /* ERP PHY (clause 19) w/o HR/DSSS */ ++ PHY_TYPE_OFDM_INDEX, /* OFDM 5 GHz PHY (clause 17) */ ++ PHY_TYPE_HT_INDEX, /* HT PHY (clause 20) */ ++ PHY_TYPE_INDEX_NUM /* 5 */ ++} ENUM_PHY_TYPE_INDEX_T, *P_ENUM_PHY_TYPE_INDEX_T; ++ ++typedef enum _ENUM_ACPI_STATE_T { ++ ACPI_STATE_D0 = 0, ++ ACPI_STATE_D1, ++ ACPI_STATE_D2, ++ ACPI_STATE_D3 ++} ENUM_ACPI_STATE_T; ++ ++/* The operation mode of a specific Network */ ++typedef enum _ENUM_OP_MODE_T { ++ OP_MODE_INFRASTRUCTURE = 0, /* Infrastructure/GC */ ++ OP_MODE_IBSS, /* AdHoc */ ++ OP_MODE_ACCESS_POINT, /* For GO */ ++ OP_MODE_P2P_DEVICE, /* P2P Device */ ++ OP_MODE_BOW, ++ OP_MODE_NUM ++} ENUM_OP_MODE_T, *P_ENUM_OP_MODE_T; ++ ++typedef enum _ENUM_CHNL_EXT_T { ++ CHNL_EXT_SCN = 0, ++ CHNL_EXT_SCA = 1, ++ CHNL_EXT_RES = 2, ++ CHNL_EXT_SCB = 3 ++} ENUM_CHNL_EXT_T, *P_ENUM_CHNL_EXT_T; ++ ++/* This starting freq of the band is unit of kHz */ ++typedef enum _ENUM_BAND_T { ++ BAND_NULL, ++ BAND_2G4, ++ BAND_5G, ++ BAND_NUM ++} ENUM_BAND_T, *P_ENUM_BAND_T; ++ ++/* Provide supported channel list to other components in array format */ ++typedef struct _RF_CHANNEL_INFO_T { ++ ENUM_BAND_T eBand; ++ UINT_8 ucChannelNum; ++} RF_CHANNEL_INFO_T, *P_RF_CHANNEL_INFO_T; ++ ++typedef enum _ENUM_RATE_INDEX_T { ++ RATE_1M_INDEX = 0, /* 1M */ ++ RATE_2M_INDEX, /* 2M */ ++ RATE_5_5M_INDEX, /* 5.5M */ ++ RATE_11M_INDEX, /* 11M */ ++ RATE_22M_INDEX, /* 22M */ ++ RATE_33M_INDEX, /* 33M */ ++ RATE_6M_INDEX, /* 6M */ ++ RATE_9M_INDEX, /* 9M */ ++ RATE_12M_INDEX, /* 12M */ ++ RATE_18M_INDEX, /* 18M */ ++ RATE_24M_INDEX, /* 24M */ ++ RATE_36M_INDEX, /* 36M */ ++ RATE_48M_INDEX, /* 48M */ ++ RATE_54M_INDEX, /* 54M */ ++ RATE_HT_PHY_INDEX, /* BSS Selector - HT PHY */ ++ RATE_NUM /* 15 */ ++} ENUM_RATE_INDEX_T, *P_ENUM_RATE_INDEX_T; ++ ++typedef enum _ENUM_HT_RATE_INDEX_T { ++ HT_RATE_MCS0_INDEX = 0, ++ HT_RATE_MCS1_INDEX, ++ HT_RATE_MCS2_INDEX, ++ HT_RATE_MCS3_INDEX, ++ HT_RATE_MCS4_INDEX, ++ HT_RATE_MCS5_INDEX, ++ HT_RATE_MCS6_INDEX, ++ HT_RATE_MCS7_INDEX, ++ HT_RATE_MCS32_INDEX, ++ HT_RATE_NUM /* 9 */ ++} ENUM_HT_RATE_INDEX_T, *P_ENUM_HT_RATE_INDEX_T; ++ ++typedef enum _ENUM_PREMABLE_OPTION_T { ++ PREAMBLE_DEFAULT_LONG_NONE = 0, /* LONG for PHY_TYPE_HR_DSSS, NONE for PHY_TYPE_OFDM */ ++ PREAMBLE_OPTION_SHORT, /* SHORT mandatory for PHY_TYPE_ERP, SHORT option for PHY_TYPE_HR_DSSS */ ++ PREAMBLE_HT_MIXED_MODE, ++ PREAMBLE_HT_GREEN_FIELD, ++ PREAMBLE_OPTION_NUM ++} ENUM_PREMABLE_OPTION_T, *P_ENUM_PREMABLE_OPTION_T; ++ ++typedef enum _ENUM_CHANNEL_WIDTH_T { ++ CW_20_40MHZ = 0, ++ CW_80MHZ = 1, ++ CW_160MHZ = 2, ++ CW_80P80MHZ = 3 ++} ENUM_CHANNEL_WIDTH_T, *P_ENUM_CHANNEL_WIDTH_P; ++ ++typedef enum _ENUM_MODULATION_SYSTEM_T { ++ MODULATION_SYSTEM_CCK = 0, ++ MODULATION_SYSTEM_OFDM, ++ MODULATION_SYSTEM_HT20, ++ MODULATION_SYSTEM_HT40, ++ MODULATION_SYSTEM_NUM ++} ENUM_MODULATION_SYSTEM_T, *P_ENUM_MODULATION_SYSTEM_T; ++ ++typedef enum _ENUM_MODULATION_TYPE_T { ++ MODULATION_TYPE_CCK_BPSK = 0, ++ MODULATION_TYPE_QPSK, ++ MODULATION_TYPE_16QAM, ++ MODULATION_TYPE_64QAM, ++ MODULATION_TYPE_NUM ++} ENUM_MODULATION_TYPE_T, *P_ENUM_MODULATION_TYPE_T; ++ ++typedef enum _ENUM_PS_FORWARDING_TYPE_T { ++ PS_FORWARDING_TYPE_NON_PS = 0, ++ PS_FORWARDING_TYPE_DELIVERY_ENABLED, ++ PS_FORWARDING_TYPE_NON_DELIVERY_ENABLED, ++ PS_FORWARDING_MORE_DATA_ENABLED, ++ PS_FORWARDING_TYPE_NUM ++} ENUM_PS_FORWARDING_TYPE_T, *P_ENUM_PS_FORWARDING_TYPE_T; ++ ++typedef struct _DEAUTH_INFO_T { ++ UINT_8 aucRxAddr[MAC_ADDR_LEN]; ++ OS_SYSTIME rLastSendTime; ++} DEAUTH_INFO_T, *P_DEAUTH_INFO_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* Information Element (IE) handlers */ ++/*----------------------------------------------------------------------------*/ ++typedef VOID(*PFN_APPEND_IE_FUNC) (P_ADAPTER_T, P_MSDU_INFO_T); ++typedef VOID(*PFN_HANDLE_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T); ++typedef VOID(*PFN_VERIFY_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T, PUINT_16); ++typedef UINT_32(*PFN_CALCULATE_VAR_IE_LEN_FUNC) (P_ADAPTER_T, ENUM_NETWORK_TYPE_INDEX_T, P_STA_RECORD_T); ++ ++typedef struct _APPEND_IE_ENTRY_T { ++ UINT_16 u2EstimatedIELen; ++ PFN_APPEND_IE_FUNC pfnAppendIE; ++} APPEND_IE_ENTRY_T, *P_APPEND_IE_ENTRY_T; ++ ++typedef struct _APPEND_VAR_IE_ENTRY_T { ++ UINT_16 u2EstimatedFixedIELen; /* For Fixed Length */ ++ PFN_CALCULATE_VAR_IE_LEN_FUNC pfnCalculateVariableIELen; ++ PFN_APPEND_IE_FUNC pfnAppendIE; ++} APPEND_VAR_IE_ENTRY_T, *P_APPEND_VAR_IE_ENTRY_T; ++ ++typedef struct _HANDLE_IE_ENTRY_T { ++ UINT_8 ucElemID; ++ PFN_HANDLE_IE_FUNC pfnHandleIE; ++} HANDLE_IE_ENTRY_T, *P_HANDLE_IE_ENTRY_T; ++ ++typedef struct _VERIFY_IE_ENTRY_T { ++ UINT_8 ucElemID; ++ PFN_VERIFY_IE_FUNC pfnVarifyIE; ++} VERIFY_IE_ENTRY_T, *P_VERIFY_IE_ENTRY_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* Parameters of User Configuration */ ++/*----------------------------------------------------------------------------*/ ++typedef enum _ENUM_PARAM_CONNECTION_POLICY_T { ++ CONNECT_BY_SSID_BEST_RSSI = 0, ++ CONNECT_BY_SSID_GOOD_RSSI_MIN_CH_LOAD, ++ CONNECT_BY_SSID_ANY, /* NOTE(Kevin): Needed by WHQL */ ++ CONNECT_BY_BSSID, ++ CONNECT_BY_CUSTOMIZED_RULE /* NOTE(Kevin): TBD */ ++} ENUM_PARAM_CONNECTION_POLICY_T, *P_ENUM_PARAM_CONNECTION_POLICY_T; ++ ++typedef enum _ENUM_PARAM_PREAMBLE_TYPE_T { ++ PREAMBLE_TYPE_LONG = 0, ++ PREAMBLE_TYPE_SHORT, ++ PREAMBLE_TYPE_AUTO /*!< Try preamble short first, if fail tray preamble long. */ ++} ENUM_PARAM_PREAMBLE_TYPE_T, *P_ENUM_PARAM_PREAMBLE_TYPE_T; ++ ++/* This is enum defined for user to select a phy config listed in combo box */ ++typedef enum _ENUM_PARAM_PHY_CONFIG_T { ++ /*!< Can associated with 802.11abg AP but without n capability, Scan dual band. */ ++ PHY_CONFIG_802_11ABG = 0, ++ PHY_CONFIG_802_11BG, /*!< Can associated with 802_11bg AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11G, /*!< Can associated with 802_11g only AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11A, /*!< Can associated with 802_11a only AP, Scan single band and not report 2.4G BSSs. */ ++ PHY_CONFIG_802_11B, /*!< Can associated with 802_11b only AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11ABGN, /*!< Can associated with 802.11abgn AP, Scan dual band. */ ++ PHY_CONFIG_802_11BGN, /*!< Can associated with 802_11bgn AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11AN, /*!< Can associated with 802_11an AP, Scan single band and not report 2.4G BSSs. */ ++ PHY_CONFIG_802_11GN, /*!< Can associated with 802_11gn AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_NUM /* 9 */ ++} ENUM_PARAM_PHY_CONFIG_T, *P_ENUM_PARAM_PHY_CONFIG_T; ++ ++/* This is enum defined for user to select an AP Mode */ ++typedef enum _ENUM_PARAM_AP_MODE_T { ++ AP_MODE_11B = 0, /*!< Create 11b BSS if we support 802.11abg/802.11bg. */ ++ AP_MODE_MIXED_11BG, /*!< Create 11bg mixed BSS if we support 802.11abg/802.11bg/802.11g. */ ++ AP_MODE_11G, /*!< Create 11g only BSS if we support 802.11abg/802.11bg/802.11g. */ ++ AP_MODE_11G_P2P, /*!< Create 11g only BSS for P2P if we support 802.11abg/802.11bg/802.11g. */ ++ AP_MODE_11A, /*!< Create 11a only BSS if we support 802.11abg. */ ++ AP_MODE_NUM /* 4 */ ++} ENUM_PARAM_AP_MODE_T, *P_ENUM_PARAM_AP_MODE_T; ++ ++/* Masks for determining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ ++#define NETWORK_TYPE_AIS_MASK BIT(NETWORK_TYPE_AIS_INDEX) ++#define NETWORK_TYPE_P2P_MASK BIT(NETWORK_TYPE_P2P_INDEX) ++#define NETWORK_TYPE_BOW_MASK BIT(NETWORK_TYPE_BOW_INDEX) ++#define STA_TYPE_LEGACY_MASK BIT(STA_TYPE_LEGACY_INDEX) ++#define STA_TYPE_P2P_MASK BIT(STA_TYPE_P2P_INDEX) ++#define STA_TYPE_BOW_MASK BIT(STA_TYPE_BOW_INDEX) ++#define STA_TYPE_ADHOC_MASK BIT(STA_ROLE_ADHOC_INDEX) ++#define STA_TYPE_CLIENT_MASK BIT(STA_ROLE_CLIENT_INDEX) ++#define STA_TYPE_AP_MASK BIT(STA_ROLE_AP_INDEX) ++#define STA_TYPE_DLS_MASK BIT(STA_ROLE_DLS_INDEX) ++#define STA_TYPE_TDLS_MASK BIT(STA_ROLE_TDLS_INDEX) ++ ++/* Macros for obtaining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ ++#define IS_STA_IN_AIS(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) ++#define IS_STA_IN_P2P(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++#define IS_STA_IN_BOW(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++#define IS_STA_LEGACY_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_LEGACY_MASK) ++#define IS_STA_P2P_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_P2P_MASK) ++#define IS_STA_BOW_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_BOW_MASK) ++#define IS_ADHOC_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_ADHOC_MASK) ++#define IS_CLIENT_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_CLIENT_MASK) ++#define IS_AP_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_AP_MASK) ++#define IS_DLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_DLS_MASK) ++#define IS_TDLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_TDLS_MASK) ++ ++/* The ENUM_STA_TYPE_T accounts for ENUM_NETWORK_TYPE_T and ENUM_STA_ROLE_INDEX_T. ++ * * It is a merged version of Network Type and STA Role. ++ * */ ++typedef enum _ENUM_STA_TYPE_T { ++ STA_TYPE_LEGACY_AP = (STA_TYPE_LEGACY_MASK | STA_TYPE_AP_MASK), ++ STA_TYPE_LEGACY_CLIENT = (STA_TYPE_LEGACY_MASK | STA_TYPE_CLIENT_MASK), ++ STA_TYPE_ADHOC_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_ADHOC_MASK), ++#if CFG_ENABLE_WIFI_DIRECT ++ STA_TYPE_P2P_GO = (STA_TYPE_P2P_MASK | STA_TYPE_AP_MASK), ++ STA_TYPE_P2P_GC = (STA_TYPE_P2P_MASK | STA_TYPE_CLIENT_MASK), ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ STA_TYPE_BOW_AP = (STA_TYPE_BOW_MASK | STA_TYPE_AP_MASK), ++ STA_TYPE_BOW_CLIENT = (STA_TYPE_BOW_MASK | STA_TYPE_CLIENT_MASK), ++#endif ++ STA_TYPE_DLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_DLS_MASK), ++ STA_TYPE_TDLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_TDLS_MASK) ++} ENUM_STA_TYPE_T, *P_ENUM_STA_TYPE_T; ++ ++/* The type of BSS we discovered */ ++typedef enum _ENUM_BSS_TYPE_T { ++ BSS_TYPE_INFRASTRUCTURE = 1, ++ BSS_TYPE_IBSS, ++ BSS_TYPE_P2P_DEVICE, ++ BSS_TYPE_BOW_DEVICE, ++ BSS_TYPE_NUM ++} ENUM_BSS_TYPE_T, *P_ENUM_BSS_TYPE_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* RSN structures */ ++/*----------------------------------------------------------------------------*/ ++/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ ++/* #pragma pack(1) */ ++/* #endif */ ++ ++#define MAX_NUM_SUPPORTED_CIPHER_SUITES 8 /* max number of supported cipher suites */ ++#if CFG_SUPPORT_802_11W ++#define MAX_NUM_SUPPORTED_AKM_SUITES 8 /* max number of supported AKM suites */ ++#else ++#define MAX_NUM_SUPPORTED_AKM_SUITES 6 /* max number of supported AKM suites */ ++#endif ++ ++/* Structure of RSN Information */ ++typedef struct _RSN_INFO_T { ++ UINT_8 ucElemId; ++ UINT_16 u2Version; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_32 u4PairwiseKeyCipherSuiteCount; ++ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_CIPHER_SUITES]; ++ UINT_32 u4AuthKeyMgtSuiteCount; ++ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_AKM_SUITES]; ++ UINT_16 u2RsnCap; ++ BOOLEAN fgRsnCapPresent; ++} /*__KAL_ATTRIB_PACKED__*/ RSN_INFO_T, *P_RSN_INFO_T; ++ ++#define MAX_NUM_SUPPORTED_WAPI_AKM_SUITES 1 /* max number of supported AKM suites */ ++#define MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES 1 /* max number of supported cipher suites */ ++ ++/* Structure of WAPI Information */ ++typedef struct _WAPI_INFO_T { ++ UINT_8 ucElemId; ++ UCHAR ucLength; ++ UINT_16 u2Version; ++ UINT_32 u4AuthKeyMgtSuiteCount; ++ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_WAPI_AKM_SUITES]; ++ UINT_32 u4PairwiseKeyCipherSuiteCount; ++ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES]; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_16 u2WapiCap; ++ UINT_16 u2Bkid; ++ UINT_8 aucBkid[1][16]; ++} /* __KAL_ATTRIB_PACKED__ */ WAPI_INFO_T, *P_WAPI_INFO_T; ++ ++/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ ++/* #pragma pack() */ ++/* #endif */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++typedef struct _P2P_DEVICE_TYPE_T { ++ UINT_16 u2CategoryID; ++ UINT_16 u2SubCategoryID; ++} P2P_DEVICE_TYPE_T, *P_P2P_DEVICE_TYPE_T; ++ ++typedef struct _P2P_DEVICE_DESC_T { ++ LINK_ENTRY_T rLinkEntry; ++ BOOLEAN fgDevInfoValid; ++ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ ++ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Interface Address. */ ++ UINT_8 ucDeviceCapabilityBitmap; ++ UINT_8 ucGroupCapabilityBitmap; ++ UINT_16 u2ConfigMethod; /* Configure Method support. */ ++ P2P_DEVICE_TYPE_T rPriDevType; ++ UINT_8 ucSecDevTypeNum; ++ P2P_DEVICE_TYPE_T arSecDevType[8]; /* Reference to P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT */ ++ UINT_16 u2NameLength; ++ UINT_8 aucName[32]; /* Reference to WPS_ATTRI_MAX_LEN_DEVICE_NAME */ ++ /* TODO: Service Information or PasswordID valid? */ ++} P2P_DEVICE_DESC_T, *P_P2P_DEVICE_DESC_T; ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static const UINT_8 aucRateIndex2RateCode[PREAMBLE_OPTION_NUM][RATE_NUM] = { ++ { /* Long Preamble */ ++ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ ++ RATE_CCK_2M_LONG, /* RATE_2M_INDEX */ ++ RATE_CCK_5_5M_LONG, /* RATE_5_5M_INDEX */ ++ RATE_CCK_11M_LONG, /* RATE_11M_INDEX */ ++ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ ++ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ ++ RATE_OFDM_6M, /* RATE_6M_INDEX */ ++ RATE_OFDM_9M, /* RATE_9M_INDEX */ ++ RATE_OFDM_12M, /* RATE_12M_INDEX */ ++ RATE_OFDM_18M, /* RATE_18M_INDEX */ ++ RATE_OFDM_24M, /* RATE_24M_INDEX */ ++ RATE_OFDM_36M, /* RATE_36M_INDEX */ ++ RATE_OFDM_48M, /* RATE_48M_INDEX */ ++ RATE_OFDM_54M, /* RATE_54M_INDEX */ ++ }, ++ { /* Short Preamble */ ++ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ ++ RATE_CCK_2M_SHORT, /* RATE_2M_INDEX */ ++ RATE_CCK_5_5M_SHORT, /* RATE_5_5M_INDEX */ ++ RATE_CCK_11M_SHORT, /* RATE_11M_INDEX */ ++ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ ++ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ ++ RATE_OFDM_6M, /* RATE_6M_INDEX */ ++ RATE_OFDM_9M, /* RATE_9M_INDEX */ ++ RATE_OFDM_12M, /* RATE_12M_INDEX */ ++ RATE_OFDM_18M, /* RATE_18M_INDEX */ ++ RATE_OFDM_24M, /* RATE_24M_INDEX */ ++ RATE_OFDM_36M, /* RATE_36M_INDEX */ ++ RATE_OFDM_48M, /* RATE_48M_INDEX */ ++ RATE_OFDM_54M, /* RATE_54M_INDEX */ ++ }, ++ { /* Mixed Mode(Option) */ ++ RATE_MM_MCS_0, /* RATE_MCS0_INDEX, */ ++ RATE_MM_MCS_1, /* RATE_MCS1_INDEX, */ ++ RATE_MM_MCS_2, /* RATE_MCS2_INDEX, */ ++ RATE_MM_MCS_3, /* RATE_MCS3_INDEX, */ ++ RATE_MM_MCS_4, /* RATE_MCS4_INDEX, */ ++ RATE_MM_MCS_5, /* RATE_MCS5_INDEX, */ ++ RATE_MM_MCS_6, /* RATE_MCS6_INDEX, */ ++ RATE_MM_MCS_7, /* RATE_MCS7_INDEX, */ ++ RATE_MM_MCS_32 /* RATE_MCS32_INDEX, */ ++ }, ++ { /* Green Field(Option) */ ++ RATE_GF_MCS_0, /* RATE_MCS0_INDEX, */ ++ RATE_GF_MCS_1, /* RATE_MCS1_INDEX, */ ++ RATE_GF_MCS_2, /* RATE_MCS2_INDEX, */ ++ RATE_GF_MCS_3, /* RATE_MCS3_INDEX, */ ++ RATE_GF_MCS_4, /* RATE_MCS4_INDEX, */ ++ RATE_GF_MCS_5, /* RATE_MCS5_INDEX, */ ++ RATE_GF_MCS_6, /* RATE_MCS6_INDEX, */ ++ RATE_GF_MCS_7, /* RATE_MCS7_INDEX, */ ++ RATE_GF_MCS_32 /* RATE_MCS32_INDEX, */ ++ } ++}; ++ ++static const UINT_8 aucRateTableSize[PREAMBLE_OPTION_NUM] = { ++ RATE_HT_PHY_INDEX, ++ RATE_HT_PHY_INDEX, ++ HT_RATE_NUM, ++ HT_RATE_NUM ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Macros to get and set the wireless LAN frame fields those are 16/32 bits in ++ length. */ ++#define WLAN_GET_FIELD_16(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0]) | ((UINT_16) __cp[1] << 8); \ ++ } ++ ++#define WLAN_GET_FIELD_BE16(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0] << 8) | ((UINT_16) __cp[1]); \ ++ } ++ ++#define WLAN_GET_FIELD_32(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_32)(_value_p) = ((UINT_32) __cp[0]) | ((UINT_32) __cp[1] << 8) | \ ++ ((UINT_32) __cp[2] << 16) | ((UINT_32) __cp[3] << 24); \ ++ } ++ ++#define WLAN_GET_FIELD_64(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_64)(_value_p) = \ ++ ((UINT_64) __cp[0]) | ((UINT_64) __cp[1] << 8) | \ ++ ((UINT_64) __cp[2] << 16) | ((UINT_64) __cp[3] << 24) | \ ++ ((UINT_64) __cp[4] << 32) | ((UINT_64) __cp[5] << 40) | \ ++ ((UINT_64) __cp[6] << 48) | ((UINT_64) __cp[7] << 56); \ ++ } ++ ++#define WLAN_SET_FIELD_16(_memAddr_p, _value) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ __cp[0] = (UINT_8) (_value); \ ++ __cp[1] = (UINT_8) ((_value) >> 8); \ ++ } ++ ++#define WLAN_SET_FIELD_BE16(_memAddr_p, _value) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ __cp[0] = (UINT_8) ((_value) >> 8); \ ++ __cp[1] = (UINT_8) (_value); \ ++ } ++ ++#define WLAN_SET_FIELD_32(_memAddr_p, _value) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ __cp[0] = (UINT_8) (_value); \ ++ __cp[1] = (UINT_8) ((_value) >> 8); \ ++ __cp[2] = (UINT_8) ((_value) >> 16); \ ++ __cp[3] = (UINT_8) ((_value) >> 24); \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WLAN_DEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h +new file mode 100644 +index 000000000000..aba2e040c194 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h +@@ -0,0 +1,2290 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_cmd_event.h#1 ++*/ ++ ++/*! \file "nic_cmd_event.h" ++ \brief This file contains the declairation file of the WLAN OID processing routines ++ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: nic_cmd_event.h ++ * ++ * 03 29 2012 eason.tsai ++ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define ++ * add conditional define. ++ * ++ * 03 04 2012 eason.tsai ++ * NULL ++ * modify the cal fail report code. ++ * ++ * 01 06 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * redefine the CMD_ID_SET_TXPWR_CTRL value. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 11 30 2011 cm.chang ++ * [WCXRP00001128] [MT5931 Wi-Fi][FW] Update BB/RF setting based on RF doc v0.7 for LGE spec ++ * 1. Add a new CMD for driver to set device mode ++ * 2. Update calibration parameters ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add TX_DONE status detail information. ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 10 26 2011 cp.wu ++ * [WCXRP00001065] [MT6620 Wi-Fi][MT5931][FW][DRV] Adding parameter for controlling ++ * minimum channel dwell time for scanning ++ * add interface for control minimum channel dwell time for scanning. ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * New CMD definition about RLM parameters ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add DFS switch. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 08 09 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * add osc stable time command structure ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than ++ * one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID ++ * support as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 31 2011 chinglan.wang ++ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. ++ * . ++ * ++ * 03 18 2011 cm.chang ++ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command ++ * As CR title ++ * ++ * 03 17 2011 yarco.yang ++ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage ++ * . ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Support UAPSD/OppPS/NoA parameter setting ++ * ++ * 02 16 2011 cm.chang ++ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism ++ * . ++ * ++ * 02 10 2011 cp.wu ++ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers ++ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Update cmd format of BSS INFO, always sync OwnMac to FW no matter P2P is enabled or not.. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * Add Stress test ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * Sync HT operation element information from host to FW ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 29 2010 cm.chang ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for ++ * initial TX rate selection of auto-rate algorithm ++ * Sync RCPI of STA_REC to FW as reference of initial TX rate ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition ++ * follow-up for CMD_5G_PWR_OFFSET_T definition change ++ * ++ * 10 20 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * use OID_CUSTOM_TEST_MODE as indication for driver reset ++ * by dropping pending TX packets ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 15 2010 cm.chang ++ * NULL ++ * Add new CMD for TX power, 5G power offset and power parameters ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a pointer in P2P SCAN RESULT structure. This pointer ++ * is pointed to a IE buffer for this P2p device. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * add new CMD ID definition ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add a field in BSS INFO cmd to change interface address for P2P. (switching between Device Addr & Interface Addr) ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add interface address indication when indicate connection status. ++ * It is requested by supplicant to do 4 way handshake. ++ * ++ * 08 07 2010 wh.su ++ * NULL ++ * adding the privacy related code for P2P network ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Change data structure for P2P Device scan result, all channel time for scan command. ++ * ++ * 08 04 2010 george.huang ++ * NULL ++ * handle change PS mode OID/ CMD ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add P2P Device Found Event. ++ * Channel extension option in scan abort command. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 20 2010 george.huang ++ * ++ * DWORD align for the CMD data structure ++ * ++ * 07 20 2010 cp.wu ++ * ++ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * pass band with channel number information as scan parameter ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 09 2010 cp.wu ++ * ++ * reorder members of CMD_SET_BSS_INFO. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * update prStaRecOfAP with BSS-INFO. ++ * ++ * 07 07 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support state of STA record change from 1 to 1 ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 28 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add BSS/STA_REC commands for integration. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add TX Done Event handle entry ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_DISASSOCIATE handling. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * sync statistics data structure definition with firmware implementation ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * statistics information OIDs are now handled by querying from firmware domain ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * * the frequency is used for adhoc connection only ++ * * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list ++ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 15 2010 kevin.huang ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * Add event for activate STA_RECORD_T ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 02 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c ++ * 'cause it involves OS dependent data structure handling ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * 4. correct some HAL implementation ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * OID_802_11_RSSI, ++ * * * OID_802_11_RSSI_TRIGGER, ++ * * * OID_802_11_STATISTICS, ++ * * * OID_802_11_DISASSOCIATE, ++ * * * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-12-11 18:35:07 GMT mtk02752 ++** add CMD added in CMD/EVEN document v0.8 ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-12-10 16:39:37 GMT mtk02752 ++** eliminate unused definitions ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-12-10 09:55:11 GMT mtk02752 ++** command ID/event ID revised ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-09 13:57:37 GMT MTK02468 ++** Added event ids (EVENT_ID_RX_ADDBA and EVENT_ID_RX_DELBA) ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-08 17:35:39 GMT mtk02752 ++** + add event ID for EVENT_ID_TEST_STATUS (rf test) ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-12-07 23:01:09 GMT mtk02752 ++** add data structure for RF_TEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-12-03 16:22:56 GMT mtk01461 ++** Modify the element - i4RSSI in EVENT of SCAN RESULT ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-30 10:54:44 GMT mtk02752 ++** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T, while 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-26 10:16:58 GMT mtk02752 ++** resync EVENT_CONNECTION_STATUS ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-25 21:34:01 GMT mtk02752 ++** sync. EVENT_SCAN_RESULT_T with firmware ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-25 21:03:48 GMT mtk02752 ++** refine MGMT_FRAME ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-25 18:17:47 GMT mtk02752 ++** refine GL_WLAN_INFO_T for buffering scan result and presume max. ie length = 600 bytes ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 22:41:20 GMT mtk02752 ++** add EVENT_SCAN_RESULT_T definition ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-11-23 20:29:16 GMT mtk02752 ++** fix typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-11-23 14:46:01 GMT mtk02752 ++** add new command/event structure upon CM@SD1's documentation ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-13 15:13:40 GMT mtk02752 ++** add command definition for CMD_BUILD_CONNECTION and EVENT_CONNECTION_STATUS ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-20 12:22:22 GMT mtk01461 ++** Add SeqNum field to Event Header ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:11 GMT mtk01461 ++** Update structure of HIF_EVENT_HEADER_T and EVENT_HDR_SIZE ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 12:10:36 GMT mtk01461 ++** Add Common Set CMD Callback for MCR Write and other Set OID ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:17 GMT mtk01461 ++** Command Done Handler ++*/ ++#ifndef _NIC_CMD_EVENT_H ++#define _NIC_CMD_EVENT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define CMD_STATUS_SUCCESS 0 ++#define CMD_STATUS_REJECTED 1 ++#define CMD_STATUS_UNKNOWN 2 ++ ++#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) ++ ++#define MAX_IE_LENGTH (600) ++#define MAX_WSC_IE_LENGTH (400) ++ ++/* Action field in structure CMD_CH_PRIVILEGE_T */ ++#define CMD_CH_ACTION_REQ 0 ++#define CMD_CH_ACTION_ABORT 1 ++ ++/* Status field in structure EVENT_CH_PRIVILEGE_T */ ++#define EVENT_CH_STATUS_GRANT 0 ++ ++#define SCN_PSCAN_SWC_RSSI_WIN_MAX 75 ++#define SCN_PSCAN_SWC_MAX_NUM 8 ++#define SCN_PSCAN_HOTLIST_REPORT_MAX_NUM 8 ++ ++typedef enum _ENUM_CMD_ID_T { ++ CMD_ID_TEST_MODE = 1, /* 0x01 (Set) */ ++ CMD_ID_RESET_REQUEST, /* 0x02 (Set) */ ++ CMD_ID_BUILD_CONNECTION, /* 0x03 (Set) */ ++ CMD_ID_SCAN_REQ_V2, /* 0x04 (Set) */ ++ CMD_ID_NIC_POWER_CTRL, /* 0x05 (Set) */ ++ CMD_ID_POWER_SAVE_MODE, /* 0x06 (Set) */ ++ CMD_ID_LINK_ATTRIB, /* 0x07 (Set) */ ++ CMD_ID_ADD_REMOVE_KEY, /* 0x08 (Set) */ ++ CMD_ID_DEFAULT_KEY_ID, /* 0x09 (Set) */ ++ CMD_ID_INFRASTRUCTURE, /* 0x0a (Set) */ ++ CMD_ID_SET_RX_FILTER, /* 0x0b (Set) */ ++ CMD_ID_DOWNLOAD_BUF, /* 0x0c (Set) */ ++ CMD_ID_WIFI_START, /* 0x0d (Set) */ ++ CMD_ID_CMD_BT_OVER_WIFI, /* 0x0e (Set) */ ++ CMD_ID_SET_MEDIA_CHANGE_DELAY_TIME, /* 0x0f (Set) */ ++ CMD_ID_SEND_ADDBA_RSP, /* 0x10 (Set) */ ++ CMD_ID_WAPI_MODE, /* 0x11 (Set) (obsolete) */ ++ CMD_ID_WAPI_ASSOC_INFO, /* 0x12 (Set) (obsolete) */ ++ CMD_ID_SET_DOMAIN_INFO, /* 0x13 (Set) */ ++ CMD_ID_SET_IP_ADDRESS, /* 0x14 (Set) */ ++ CMD_ID_BSS_ACTIVATE_CTRL, /* 0x15 (Set) */ ++ CMD_ID_SET_BSS_INFO, /* 0x16 (Set) */ ++ CMD_ID_UPDATE_STA_RECORD, /* 0x17 (Set) */ ++ CMD_ID_REMOVE_STA_RECORD, /* 0x18 (Set) */ ++ CMD_ID_INDICATE_PM_BSS_CREATED, /* 0x19 (Set) */ ++ CMD_ID_INDICATE_PM_BSS_CONNECTED, /* 0x1a (Set) */ ++ CMD_ID_INDICATE_PM_BSS_ABORT, /* 0x1b (Set) */ ++ CMD_ID_UPDATE_BEACON_CONTENT, /* 0x1c (Set) */ ++ CMD_ID_SET_BSS_RLM_PARAM, /* 0x1d (Set) */ ++ CMD_ID_SCAN_REQ, /* 0x1e (Set) */ ++ CMD_ID_SCAN_CANCEL, /* 0x1f (Set) */ ++ CMD_ID_CH_PRIVILEGE, /* 0x20 (Set) */ ++ CMD_ID_UPDATE_WMM_PARMS, /* 0x21 (Set) */ ++ CMD_ID_SET_WMM_PS_TEST_PARMS, /* 0x22 (Set) */ ++ CMD_ID_TX_AMPDU, /* 0x23 (Set) */ ++ CMD_ID_ADDBA_REJECT, /* 0x24 (Set) */ ++ CMD_ID_SET_PS_PROFILE_ADV, /* 0x25 (Set) */ ++ CMD_ID_SET_RAW_PATTERN, /* 0x26 (Set) */ ++ CMD_ID_CONFIG_PATTERN_FUNC, /* 0x27 (Set) */ ++ CMD_ID_SET_TX_PWR, /* 0x28 (Set) */ ++ CMD_ID_SET_5G_PWR_OFFSET, /* 0x29 (Set) */ ++ CMD_ID_SET_PWR_PARAM, /* 0x2A (Set) */ ++ CMD_ID_P2P_ABORT, /* 0x2B (Set) */ ++#if CFG_STRESS_TEST_SUPPORT ++ CMD_ID_RANDOM_RX_RESET_EN = 0x2C, /* 0x2C (Set ) */ ++ CMD_ID_RANDOM_RX_RESET_DE = 0x2D, /* 0x2D (Set ) */ ++ CMD_ID_SAPP_EN = 0x2E, /* 0x2E (Set ) */ ++ CMD_ID_SAPP_DE = 0x2F, /* 0x2F (Set ) */ ++#endif ++ CMD_ID_ROAMING_TRANSIT = 0x30, /* 0x30 (Set) */ ++ CMD_ID_SET_PHY_PARAM, /* 0x31 (Set) */ ++ CMD_ID_SET_NOA_PARAM, /* 0x32 (Set) */ ++ CMD_ID_SET_OPPPS_PARAM, /* 0x33 (Set) */ ++ CMD_ID_SET_UAPSD_PARAM, /* 0x34 (Set) */ ++ CMD_ID_SET_SIGMA_STA_SLEEP, /* 0x35 (Set) */ ++ CMD_ID_SET_EDGE_TXPWR_LIMIT, /* 0x36 (Set) */ ++ CMD_ID_SET_DEVICE_MODE, /* 0x37 (Set) */ ++ CMD_ID_SET_TXPWR_CTRL, /* 0x38 (Set) */ ++ CMD_ID_SET_AUTOPWR_CTRL, /* 0x39 (Set) */ ++ CMD_ID_SET_WFD_CTRL, /* 0x3A (Set) */ ++ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, /* 0x3B (Set) */ ++ CMD_ID_SET_RSSI_COMPENSATE, /* 0x3C (Set) */ ++ CMD_ID_SET_BAND_SUPPORT = 0x3D, /* 0x3D (Set) */ ++ CMD_ID_SET_NLO_REQ, /* 0x3E (Set) */ ++ CMD_ID_SET_NLO_CANCEL, /* 0x3F (Set) */ ++ CMD_ID_SET_BATCH_REQ, /* 0x40 (Set) */ ++ CMD_ID_SET_WOWLAN, /* 0x41 (Set) */ /*CFG_SUPPORT_WOWLAN */ ++ CMD_ID_GET_PSCAN_CAPABILITY = 0x42, /* 0x42 (Set) */ ++ CMD_ID_SET_PSCN_ENABLE = 0x43, /* 0x43 (Set) */ ++ CMD_ID_SET_PSCAN_PARAM = 0x44, /* 0x44 (Set) */ ++ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID = 0x45, /* 0x45 (Set) */ ++ CMD_ID_SET_PSCN_ADD_SW_BSSID = 0x46, /* 0x46 (Set) */ ++ CMD_ID_SET_PSCN_MAC_ADDR = 0x47, /* 0x47 (Set) */ ++ CMD_ID_GET_GSCN_SCN_RESULT = 0x48, /* 0x48 (Get) */ ++ CMD_ID_SET_COUNTRY_POWER_LIMIT = 0x4A, /* 0x4A (Set) */ ++ CMD_ID_SET_SYSTEM_SUSPEND = 0x60, /* 0x60 (Set) */ ++ CMD_ID_GET_NIC_CAPABILITY = 0x80, /* 0x80 (Query) */ ++ CMD_ID_GET_LINK_QUALITY, /* 0x81 (Query) */ ++ CMD_ID_GET_STATISTICS, /* 0x82 (Query) */ ++ CMD_ID_GET_CONNECTION_STATUS, /* 0x83 (Query) */ ++ CMD_ID_GET_ASSOC_INFO, /* 0x84 (Query) (obsolete) */ ++ CMD_ID_GET_STA_STATISTICS = 0x85, /* 0x85 (Query) */ ++ CMD_ID_GET_DEBUG_CODE = 0x86, /* 0x86 (Query) */ ++ CMD_ID_GET_LTE_CHN = 0x87, /* 0x87 (Query) */ ++ CMD_ID_GET_CHN_LOADING = 0x88, /* 0x88 (Query) */ ++ CMD_ID_GET_STATISTICS_PL = 0x89, /* 0x87 (Query) */ ++ CMD_ID_BASIC_CONFIG = 0xc1, /* 0xc1 (Set / Query) */ ++ CMD_ID_ACCESS_REG, /* 0xc2 (Set / Query) */ ++ CMD_ID_MAC_MCAST_ADDR, /* 0xc3 (Set / Query) */ ++ CMD_ID_802_11_PMKID, /* 0xc4 (Set / Query) */ ++ CMD_ID_ACCESS_EEPROM, /* 0xc5 (Set / Query) */ ++ CMD_ID_SW_DBG_CTRL, /* 0xc6 (Set / Query) */ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ CMD_ID_SEC_CHECK, /* 0xc7 (Set / Query) */ ++#endif ++ CMD_ID_DUMP_MEM, /* 0xc8 (Query) */ ++ ++ CMD_ID_CHIP_CONFIG = 0xCA, /* 0xca (Set / Query) */ ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ CMD_ID_SET_RDD_CH = 0xE1, ++#endif ++ ++ CMD_ID_SET_BWCS = 0xF1, ++ CMD_ID_SET_ROAMING_INFO = 0xF3, ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++ CMD_ID_GET_BUILD_DATE_CODE = 0xF8, ++#endif ++ CMD_ID_GET_BSS_INFO = 0xF9, ++#if 1 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION = 0xFA, /* 0xFA (Set) */ ++#endif ++ ++ CMD_ID_TDLS_CORE = 0xFC, ++ CMD_ID_STATS = 0xFD, ++ CMD_ID_TX_AR_ERR_CONFIG = 0xFF ++} ENUM_CMD_ID_T, *P_ENUM_CMD_ID_T; ++ ++typedef enum _ENUM_EVENT_ID_T { ++ EVENT_ID_CMD_RESULT = 1, /* 0x01 (Query) */ ++ EVENT_ID_NIC_CAPABILITY, /* 0x02 (Query) */ ++ EVENT_ID_CONNECTION_STATUS, /* 0x03 (Query / Unsolicited) (obsolete) */ ++ EVENT_ID_SCAN_RESULT, /* 0x04 (Query / Unsolicited) (obselete) */ ++ EVENT_ID_LINK_QUALITY, /* 0x05 (Query / Unsolicited) */ ++ EVENT_ID_STATISTICS, /* 0x06 (Query) */ ++ EVENT_ID_MIC_ERR_INFO, /* 0x07 (Unsolicited) */ ++ EVENT_ID_ASSOC_INFO, /* 0x08 (Query - CMD_ID_GET_ASSOC_INFO) */ ++ EVENT_ID_BASIC_CONFIG, /* 0x09 (Query - CMD_ID_BASIC_CONFIG) */ ++ EVENT_ID_ACCESS_REG, /* 0x0a (Query - CMD_ID_ACCESS_REG) */ ++ EVENT_ID_MAC_MCAST_ADDR, /* 0x0b (Query - CMD_ID_MAC_MCAST_ADDR) */ ++ EVENT_ID_802_11_PMKID, /* 0x0c (Query - CMD_ID_802_11_PMKID) */ ++ EVENT_ID_ACCESS_EEPROM, /* 0x0d (Query - CMD_ID_ACCESS_EEPROM) */ ++ EVENT_ID_SLEEPY_NOTIFY, /* 0x0e (Query) */ ++ EVENT_ID_BT_OVER_WIFI, /* 0x0f (Unsolicited) */ ++ EVENT_ID_TEST_STATUS, /* 0x10 (Query - CMD_ID_TEST_MODE) */ ++ EVENT_ID_RX_ADDBA, /* 0x11 (Unsolicited) (obsolete) */ ++ EVENT_ID_RX_DELBA, /* 0x12 (Unsolicited) (obsolete) */ ++ EVENT_ID_ACTIVATE_STA_REC_T, /* 0x13 (Unsolicited) */ ++ EVENT_ID_DEACTIVATE_STA_REC_T, /* 0x14 (Unsolicited) */ ++ EVENT_ID_SCAN_DONE, /* 0x15 (Unsoiicited) */ ++ EVENT_ID_RX_FLUSH, /* 0x16 (Unsolicited) */ ++ EVENT_ID_TX_DONE, /* 0x17 (Unsolicited) */ ++ EVENT_ID_CH_PRIVILEGE, /* 0x18 (Unsolicited) */ ++ EVENT_ID_BSS_ABSENCE_PRESENCE = 0x19, /* 0x19 (Unsolicited) */ ++ EVENT_ID_STA_CHANGE_PS_MODE, /* 0x1A (Unsolicited) */ ++ EVENT_ID_BSS_BEACON_TIMEOUT, /* 0x1B (Unsolicited) */ ++ EVENT_ID_UPDATE_NOA_PARAMS, /* 0x1C (Unsolicited) */ ++ EVENT_ID_AP_OBSS_STATUS, /* 0x1D (Unsolicited) */ ++ EVENT_ID_STA_UPDATE_FREE_QUOTA, /* 0x1E (Unsolicited) */ ++ EVENT_ID_SW_DBG_CTRL, /* 0x1F (Query - CMD_ID_SW_DBG_CTRL) */ ++ EVENT_ID_ROAMING_STATUS, /* 0x20 (Unsolicited) */ ++ EVENT_ID_STA_AGING_TIMEOUT, /* 0x21 (Unsolicited) */ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ EVENT_ID_SEC_CHECK_RSP, /* 0x22 (Unsolicited) */ ++#endif ++ EVENT_ID_SEND_DEAUTH, /* 0x23 (Unsolicited) */ ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ EVENT_ID_UPDATE_RDD_STATUS, /* 0x24 (Unsolicited) */ ++#endif ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ EVENT_ID_UPDATE_BWCS_STATUS = 0x25, /* 0x25 (Unsolicited) */ ++ EVENT_ID_UPDATE_BCM_DEBUG, /* 0x26 (Unsolicited) */ ++#endif ++ EVENT_ID_RX_ERR, ++ EVENT_ID_DUMP_MEM, ++ EVENT_ID_STA_STATISTICS = 0x29, /* 0x29 (Query ) */ ++ EVENT_ID_STA_STATISTICS_UPDATE, /* 0x2A (Unsolicited) */ ++ EVENT_ID_NLO_DONE = 0x2b, ++ ++ EVENT_ID_GSCAN_CAPABILITY = 0x30, ++ EVENT_ID_GSCAN_SCAN_COMPLETE = 0x31, ++ EVENT_ID_GSCAN_FULL_RESULT = 0x32, ++ EVENT_ID_GSCAN_SIGNIFICANT_CHANGE = 0x33, ++ EVENT_ID_GSCAN_GEOFENCE_FOUND = 0x34, ++ EVENT_ID_GSCAN_SCAN_AVAILABLE = 0x35, ++ EVENT_ID_GSCAN_RESULT = 0x36, ++ EVENT_ID_BATCH_RESULT = 0x37, ++ ++ EVENT_ID_TDLS = 0x80, ++ EVENT_ID_STATS_ENV = 0x81, ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++ EVENT_ID_BUILD_DATE_CODE = 0xF8, ++#endif ++ EVENT_ID_GET_AIS_BSS_INFO = 0xF9, ++ EVENT_ID_DEBUG_CODE = 0xFB, ++ EVENT_ID_RFTEST_READY = 0xFC, /* 0xFC */ ++ EVENT_ID_TX_DONE_STATUS = 0xFD, ++ EVENT_ID_FW_LOG_ENV = 0xFE, /* 0xFE, FW real time debug log */ ++} ENUM_EVENT_ID_T, *P_ENUM_EVENT_ID_T; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifndef LINUX ++typedef UINT_8 CMD_STATUS; ++#endif ++ ++typedef struct _EVENT_TX_DONE_STATUS_T { ++ UINT_8 ucPacketSeq; ++ UINT_8 ucStatus; ++ UINT_16 u2SequenceNumber; ++ UINT_32 au4Reserved1; ++ UINT_32 au4Reserved2; ++ UINT_32 au4Reserved3; ++ UINT_32 u4PktBufInfo; ++ UINT_8 aucPktBuf[200]; ++} EVENT_TX_DONE_STATUS_T, *P_EVENT_TX_DONE_STATUS_T; ++ ++/* for Event Packet (via HIF-RX) */ ++ /* following CM's documentation v0.7 */ ++typedef struct _WIFI_CMD_T { ++ UINT_16 u2TxByteCount_UserPriority; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucResource_PktType_CSflags; ++ UINT_8 ucCID; ++ UINT_8 ucSetQuery; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2; ++ ++ UINT_8 aucBuffer[0]; ++} WIFI_CMD_T, *P_WIFI_CMD_T; ++ ++/* for Command Packet (via HIF-TX) */ ++ /* following CM's documentation v0.7 */ ++typedef struct _WIFI_EVENT_T { ++ UINT_16 u2PacketLen; ++ UINT_16 u2PacketType; ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ UINT_8 aucBuffer[0]; ++} WIFI_EVENT_T, *P_WIFI_EVENT_T; ++ ++/* CMD_ID_TEST_MODE */ ++typedef struct _CMD_TEST_CTRL_T { ++ UINT_8 ucAction; ++ UINT_8 aucReserved[3]; ++ union { ++ UINT_32 u4OpMode; ++ UINT_32 u4ChannelFreq; ++ PARAM_MTK_WIFI_TEST_STRUCT_T rRfATInfo; ++ } u; ++} CMD_TEST_CTRL_T, *P_CMD_TEST_CTRL_T; ++ ++/* EVENT_TEST_STATUS */ ++typedef struct _PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T { ++ UINT_32 u4PktSentStatus; ++ UINT_32 u4PktSentCount; ++ UINT_16 u2AvgAlc; ++ UINT_8 ucCckGainControl; ++ UINT_8 ucOfdmGainControl; ++} PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T { ++ UINT_32 u4IntRxOk; /*!< number of packets that Rx ok from interrupt */ ++ UINT_32 u4IntCrcErr; /*!< number of packets that CRC error from interrupt */ ++ UINT_32 u4IntShort; /*!< number of packets that is short preamble from interrupt */ ++ UINT_32 u4IntLong; /*!< number of packets that is long preamble from interrupt */ ++ UINT_32 u4PauRxPktCount; /*!< number of packets that Rx ok from PAU */ ++ UINT_32 u4PauCrcErrCount; /*!< number of packets that CRC error from PAU */ ++ UINT_32 u4PauRxFifoFullCount; /*!< number of packets that is short preamble from PAU */ ++ UINT_32 u4PauCCACount; /*!< CCA rising edge count */ ++} PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T; ++ ++typedef union _EVENT_TEST_STATUS { ++ PARAM_MTK_WIFI_TEST_STRUCT_T rATInfo; ++/* PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T rTxStatus; */ ++/* PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T rRxStatus; */ ++} EVENT_TEST_STATUS, *P_EVENT_TEST_STATUS; ++ ++/* CMD_BUILD_CONNECTION */ ++typedef struct _CMD_BUILD_CONNECTION { ++ UINT_8 ucInfraMode; ++ UINT_8 ucAuthMode; ++ UINT_8 ucEncryptStatus; ++ UINT_8 ucSsidLen; ++ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; ++ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; ++ ++ /* Ad-hoc mode */ ++ UINT_16 u2BeaconPeriod; ++ UINT_16 u2ATIMWindow; ++ UINT_8 ucJoinOnly; ++ UINT_8 ucReserved; ++ UINT_32 u4FreqInKHz; ++ ++ /* for faster connection */ ++ UINT_8 aucScanResult[0]; ++} CMD_BUILD_CONNECTION, *P_CMD_BUILD_CONNECTION; ++ ++/* CMD_ADD_REMOVE_KEY */ ++typedef struct _CMD_802_11_KEY { ++ UINT_8 ucAddRemove; ++ UINT_8 ucTxKey; ++ UINT_8 ucKeyType; ++ UINT_8 ucIsAuthenticator; ++ UINT_8 aucPeerAddr[6]; ++ UINT_8 ucNetType; ++ UINT_8 ucAlgorithmId; ++ UINT_8 ucKeyId; ++ UINT_8 ucKeyLen; ++ UINT_8 aucReverved[2]; ++ UINT_8 aucKeyMaterial[32]; ++ UINT_8 aucKeyRsc[16]; ++} CMD_802_11_KEY, *P_CMD_802_11_KEY; ++ ++/* WPA2 PMKID cache structure */ ++typedef struct _PMKID_ENTRY_T { ++ PARAM_BSSID_INFO_T rBssidInfo; ++ BOOLEAN fgPmkidExist; ++} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; ++ ++typedef struct _CMD_802_11_PMKID { ++ ULONG u4BSSIDInfoCount; ++ P_PMKID_ENTRY_T arPMKIDInfo[1]; ++} CMD_802_11_PMKID, *P_CMD_802_11_PMKID; ++ ++/* CMD_BASIC_CONFIG */ ++typedef struct _CMD_CSUM_OFFLOAD { ++ UINT_16 u2RxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ ++ UINT_16 u2TxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ ++} CMD_CSUM_OFFLOAD, *P_CMD_CSUM_OFFLOAD; ++ ++typedef struct _CMD_BASIC_CONFIG { ++ PARAM_MAC_ADDRESS rMyMacAddr; ++ UINT_8 ucNative80211; ++ UINT_8 aucReserved[1]; ++ ++ CMD_CSUM_OFFLOAD rCsumOffload; ++} CMD_BASIC_CONFIG, *P_CMD_BASIC_CONFIG, EVENT_BASIC_CONFIG, *P_EVENT_BASIC_CONFIG; ++ ++/* CMD_MAC_MCAST_ADDR */ ++typedef struct _CMD_MAC_MCAST_ADDR { ++ UINT_32 u4NumOfGroupAddr; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[3]; ++ PARAM_MAC_ADDRESS arAddress[MAX_NUM_GROUP_ADDR]; ++} CMD_MAC_MCAST_ADDR, *P_CMD_MAC_MCAST_ADDR, EVENT_MAC_MCAST_ADDR, *P_EVENT_MAC_MCAST_ADDR; ++ ++/* CMD_ACCESS_EEPROM */ ++typedef struct _CMD_ACCESS_EEPROM { ++ UINT_16 u2Offset; ++ UINT_16 u2Data; ++} CMD_ACCESS_EEPROM, *P_CMD_ACCESS_EEPROM, EVENT_ACCESS_EEPROM, *P_EVENT_ACCESS_EEPROM; ++ ++typedef struct _CMD_CUSTOM_NOA_PARAM_STRUCT_T { ++ UINT_32 u4NoaDurationMs; ++ UINT_32 u4NoaIntervalMs; ++ UINT_32 u4NoaCount; ++} CMD_CUSTOM_NOA_PARAM_STRUCT_T, *P_CMD_CUSTOM_NOA_PARAM_STRUCT_T; ++ ++typedef struct _CMD_CUSTOM_OPPPS_PARAM_STRUCT_T { ++ UINT_32 u4CTwindowMs; ++} CMD_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_CMD_CUSTOM_OPPPS_PARAM_STRUCT_T; ++ ++typedef struct _CMD_CUSTOM_UAPSD_PARAM_STRUCT_T { ++ UINT_8 fgEnAPSD; ++ UINT_8 fgEnAPSD_AcBe; ++ UINT_8 fgEnAPSD_AcBk; ++ UINT_8 fgEnAPSD_AcVo; ++ UINT_8 fgEnAPSD_AcVi; ++ UINT_8 ucMaxSpLen; ++ UINT_8 aucResv[2]; ++} CMD_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_CMD_CUSTOM_UAPSD_PARAM_STRUCT_T; ++ ++/* EVENT_CONNECTION_STATUS */ ++typedef struct _EVENT_CONNECTION_STATUS { ++ UINT_8 ucMediaStatus; ++ UINT_8 ucReasonOfDisconnect; ++ ++ UINT_8 ucInfraMode; ++ UINT_8 ucSsidLen; ++ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; ++ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; ++ UINT_8 ucAuthenMode; ++ UINT_8 ucEncryptStatus; ++ UINT_16 u2BeaconPeriod; ++ UINT_16 u2AID; ++ UINT_16 u2ATIMWindow; ++ UINT_8 ucNetworkType; ++ UINT_8 aucReserved[1]; ++ UINT_32 u4FreqInKHz; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_8 aucInterfaceAddr[PARAM_MAC_ADDR_LEN]; ++#endif ++ ++} EVENT_CONNECTION_STATUS, *P_EVENT_CONNECTION_STATUS; ++ ++/* EVENT_NIC_CAPABILITY */ ++typedef struct _EVENT_NIC_CAPABILITY { ++ UINT_16 u2ProductID; ++ UINT_16 u2FwVersion; ++ UINT_16 u2DriverVersion; ++ UINT_8 ucHw5GBandDisabled; ++ UINT_8 ucEepromUsed; ++ UINT_8 ucEfuseValid; ++ UINT_8 ucMacAddrValid; ++#if CFG_REPORT_RFBB_VERSION ++ UINT_8 ucRfVersion; ++ UINT_8 ucPhyVersion; ++#endif ++#if CFG_ENABLE_CAL_LOG ++ UINT_8 ucRfCalFail; ++ UINT_8 ucBbCalFail; ++#endif ++ ++#define FEATURE_SET_OFFSET_TDLS 0 ++#define FEATURE_SET_OFFSET_5G_SUPPORT 1 ++ UINT_8 ucFeatureSet; /* bit0: TDLS */ ++ ++ UINT_8 aucReserved[1]; ++#if CFG_EMBED_FIRMWARE_BUILD_DATE_CODE ++ UINT_8 aucDateCode[16]; ++#endif ++} EVENT_NIC_CAPABILITY, *P_EVENT_NIC_CAPABILITY; ++ ++/* modified version of WLAN_BEACON_FRAME_BODY_T for simplier buffering */ ++typedef struct _WLAN_BEACON_FRAME_BODY_T_LOCAL { ++ /* Beacon frame body */ ++ UINT_32 au4Timestamp[2]; /* Timestamp */ ++ UINT_16 u2BeaconInterval; /* Beacon Interval */ ++ UINT_16 u2CapInfo; /* Capability */ ++ UINT_8 aucInfoElem[MAX_IE_LENGTH]; /* Various IEs, start from SSID */ ++ UINT_16 u2IELength; /* This field is *NOT* carried by F/W but caculated by nic_rx */ ++} WLAN_BEACON_FRAME_BODY_T_LOCAL, *P_WLAN_BEACON_FRAME_BODY_T_LOCAL; ++ ++/* EVENT_SCAN_RESULT */ ++typedef struct _EVENT_SCAN_RESULT_T { ++ INT_32 i4RSSI; ++ UINT_32 u4LinkQuality; ++ UINT_32 u4DSConfig; /* Center frequency */ ++ UINT_32 u4DomainInfo; /* Require CM opinion */ ++ UINT_32 u4Reserved; ++ UINT_8 ucNetworkType; ++ UINT_8 ucOpMode; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; ++ WLAN_BEACON_FRAME_BODY_T_LOCAL rBeaconFrameBody; ++} EVENT_SCAN_RESULT_T, *P_EVENT_SCAN_RESULT_T; ++ ++/* event of tkip mic error */ ++typedef struct _EVENT_MIC_ERR_INFO { ++ UINT_32 u4Flags; ++} EVENT_MIC_ERR_INFO, *P_EVENT_MIC_ERR_INFO; ++ ++typedef struct _EVENT_PMKID_CANDIDATE_LIST_T { ++ UINT_32 u4Version; /*!< Version */ ++ UINT_32 u4NumCandidates; /*!< How many candidates follow */ ++ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; ++} EVENT_PMKID_CANDIDATE_LIST_T, *P_EVENT_PMKID_CANDIDATE_LIST_T; ++ ++typedef struct _EVENT_CMD_RESULT { ++ UINT_8 ucCmdID; ++ UINT_8 ucStatus; ++ UINT_8 aucReserved[2]; ++} EVENT_CMD_RESULT, *P_EVENT_CMD_RESULT; ++ ++/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ ++typedef struct _CMD_ACCESS_REG { ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++} CMD_ACCESS_REG, *P_CMD_ACCESS_REG; ++ ++/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++typedef struct _CMD_ACCESS_CHN_LOAD { ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++ UINT_16 u2Channel; ++ UINT_8 aucReserved[2]; ++} CMD_ACCESS_CHN_LOAD, *P_ACCESS_CHN_LOAD; ++ ++#endif ++/* CMD_DUMP_MEMORY */ ++typedef struct _CMD_DUMP_MEM { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4RemainLength; ++ UINT_8 ucFragNum; ++} CMD_DUMP_MEM, *P_CMD_DUMP_MEM; ++ ++typedef struct _EVENT_DUMP_MEM_T { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4RemainLength; ++ UINT_8 ucFragNum; ++ UINT_8 aucBuffer[1]; ++} EVENT_DUMP_MEM_T, *P_EVENT_DUMP_MEM_T; ++ ++typedef struct _CMD_SW_DBG_CTRL_T { ++ UINT_32 u4Id; ++ UINT_32 u4Data; ++ /* Debug Support */ ++ UINT_32 u4DebugCnt[64]; ++} CMD_SW_DBG_CTRL_T, *P_CMD_SW_DBG_CTRL_T; ++ ++/* CMD_ID_LINK_ATTRIB */ ++typedef struct _CMD_LINK_ATTRIB { ++ INT_8 cRssiTrigger; ++ UINT_8 ucDesiredRateLen; ++ UINT_16 u2DesiredRate[32]; ++ UINT_8 ucMediaStreamMode; ++ UINT_8 aucReserved[1]; ++} CMD_LINK_ATTRIB, *P_CMD_LINK_ATTRIB; ++ ++/* CMD_ID_NIC_POWER_CTRL */ ++typedef struct _CMD_NIC_POWER_CTRL { ++ UINT_8 ucPowerMode; ++ UINT_8 aucReserved[3]; ++} CMD_NIC_POWER_CTRL, *P_CMD_NIC_POWER_CTRL; ++ ++/* CMD_ID_POWER_SAVE_MODE */ ++typedef struct _CMD_PS_PROFILE_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucPsProfile; ++ UINT_8 aucReserved[2]; ++} CMD_PS_PROFILE_T, *P_CMD_PS_PROFILE_T; ++ ++/* EVENT_LINK_QUALITY */ ++typedef struct _EVENT_LINK_QUALITY { ++ INT_8 cRssi; ++ INT_8 cLinkQuality; ++ UINT_16 u2LinkSpeed; ++ UINT_8 ucMediumBusyPercentage; ++} EVENT_LINK_QUALITY, *P_EVENT_LINK_QUALITY; ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++/* EVENT_LINK_QUALITY */ ++typedef struct _EVENT_LINK_QUALITY_EX { ++ INT_8 cRssi; ++ INT_8 cLinkQuality; ++ UINT_16 u2LinkSpeed; ++ UINT_8 ucMediumBusyPercentage; ++ UINT_8 ucIsLQ0Rdy; ++ INT_8 cRssiP2P; /* For P2P Network. */ ++ INT_8 cLinkQualityP2P; ++ UINT_16 u2LinkSpeedP2P; ++ UINT_8 ucMediumBusyPercentageP2P; ++ UINT_8 ucIsLQ1Rdy; ++} EVENT_LINK_QUALITY_EX, *P_EVENT_LINK_QUALITY_EX; ++#endif ++ ++/* EVENT_ID_STATISTICS */ ++typedef struct _EVENT_STATISTICS { ++ LARGE_INTEGER rTransmittedFragmentCount; ++ LARGE_INTEGER rMulticastTransmittedFrameCount; ++ LARGE_INTEGER rFailedCount; ++ LARGE_INTEGER rRetryCount; ++ LARGE_INTEGER rMultipleRetryCount; ++ LARGE_INTEGER rRTSSuccessCount; ++ LARGE_INTEGER rRTSFailureCount; ++ LARGE_INTEGER rACKFailureCount; ++ LARGE_INTEGER rFrameDuplicateCount; ++ LARGE_INTEGER rReceivedFragmentCount; ++ LARGE_INTEGER rMulticastReceivedFrameCount; ++ LARGE_INTEGER rFCSErrorCount; ++} EVENT_STATISTICS, *P_EVENT_STATISTICS; ++ ++/* EVENT_ID_FW_SLEEPY_NOTIFY */ ++typedef struct _EVENT_SLEEPY_NOTIFY { ++ UINT_8 ucSleepyState; ++ UINT_8 aucReserved[3]; ++} EVENT_SLEEPY_NOTIFY, *P_EVENT_SLEEPY_NOTIFY; ++ ++typedef struct _EVENT_ACTIVATE_STA_REC_T { ++ UINT_8 aucMacAddr[6]; ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucNetworkTypeIndex; ++ BOOLEAN fgIsQoS; ++ BOOLEAN fgIsAP; ++ UINT_8 aucReserved[2]; ++} EVENT_ACTIVATE_STA_REC_T, *P_EVENT_ACTIVATE_STA_REC_T; ++ ++typedef struct _EVENT_DEACTIVATE_STA_REC_T { ++ UINT_8 ucStaRecIdx; ++ UINT_8 aucReserved[3]; ++} EVENT_DEACTIVATE_STA_REC_T, *P_EVENT_DEACTIVATE_STA_REC_T; ++ ++/* CMD_BT_OVER_WIFI */ ++typedef struct _CMD_BT_OVER_WIFI { ++ UINT_8 ucAction; /* 0: query, 1: setup, 2: destroy */ ++ UINT_8 ucChannelNum; ++ PARAM_MAC_ADDRESS rPeerAddr; ++ UINT_16 u2BeaconInterval; ++ UINT_8 ucTimeoutDiscovery; ++ UINT_8 ucTimeoutInactivity; ++ UINT_8 ucRole; ++ UINT_8 PAL_Capabilities; ++ UINT_8 cMaxTxPower; ++ UINT_8 ucChannelBand; ++ UINT_8 ucReserved[1]; ++} CMD_BT_OVER_WIFI, *P_CMD_BT_OVER_WIFI; ++ ++/* EVENT_BT_OVER_WIFI */ ++typedef struct _EVENT_BT_OVER_WIFI { ++ UINT_8 ucLinkStatus; ++ UINT_8 ucSelectedChannel; ++ INT_8 cRSSI; ++ UINT_8 ucReserved[1]; ++} EVENT_BT_OVER_WIFI, *P_EVENT_BT_OVER_WIFI; ++ ++/* Same with DOMAIN_SUBBAND_INFO */ ++typedef struct _CMD_SUBBAND_INFO { ++ UINT_8 ucRegClass; ++ UINT_8 ucBand; ++ UINT_8 ucChannelSpan; ++ UINT_8 ucFirstChannelNum; ++ UINT_8 ucNumChannels; ++ UINT_8 aucReserved[3]; ++} CMD_SUBBAND_INFO, *P_CMD_SUBBAND_INFO; ++ ++/* CMD_SET_DOMAIN_INFO */ ++typedef struct _CMD_SET_DOMAIN_INFO_T { ++ UINT_16 u2CountryCode; ++ UINT_16 u2IsSetPassiveScan; /* 0: set channel domain; 1: set passive scan channel domain */ ++ CMD_SUBBAND_INFO rSubBand[6]; ++ ++ UINT_8 uc2G4Bandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ ++ UINT_8 uc5GBandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ ++ UINT_8 aucReserved[2]; ++} CMD_SET_DOMAIN_INFO_T, *P_CMD_SET_DOMAIN_INFO_T; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++/* CMD_SET_PWR_LIMIT_TABLE */ ++typedef struct _CMD_CHANNEL_POWER_LIMIT { ++ UINT_8 ucCentralCh; ++ INT_8 cPwrLimitCCK; ++ INT_8 cPwrLimit20; ++ INT_8 cPwrLimit40; ++ INT_8 cPwrLimit80; ++ INT_8 cPwrLimit160; ++ UINT_8 ucFlag; ++ UINT_8 aucReserved[1]; ++} CMD_CHANNEL_POWER_LIMIT, *P_CMD_CHANNEL_POWER_LIMIT; ++ ++typedef struct _CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T { ++ UINT_16 u2CountryCode; ++ UINT_8 ucCountryFlag; ++ UINT_8 ucNum; ++ UINT_8 aucReserved[4]; ++ CMD_CHANNEL_POWER_LIMIT rChannelPowerLimit[1]; ++} CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T, *P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T; ++ ++#endif ++ ++/* CMD_SET_IP_ADDRESS */ ++typedef struct _IPV4_NETWORK_ADDRESS { ++ UINT_8 aucIpAddr[4]; ++} IPV4_NETWORK_ADDRESS, *P_IPV4_NETWORK_ADDRESS; ++ ++typedef struct _CMD_SET_NETWORK_ADDRESS_LIST { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucAddressCount; ++ UINT_8 ucReserved[2]; ++ IPV4_NETWORK_ADDRESS arNetAddress[1]; ++} CMD_SET_NETWORK_ADDRESS_LIST, *P_CMD_SET_NETWORK_ADDRESS_LIST; ++ ++typedef struct _PATTERN_DESCRIPTION { ++ UINT_8 fgCheckBcA1; ++ UINT_8 fgCheckMcA1; ++ UINT_8 ePatternHeader; ++ UINT_8 fgAndOp; ++ UINT_8 fgNotOp; ++ UINT_8 ucPatternMask; ++ UINT_16 ucPatternOffset; ++ UINT_8 aucPattern[8]; ++} PATTERN_DESCRIPTION, *P_PATTERN_DESCRIPTION; ++ ++typedef struct _CMD_RAW_PATTERN_CONFIGURATION_T { ++ PATTERN_DESCRIPTION arPatternDesc[4]; ++} CMD_RAW_PATTERN_CONFIGURATION_T, *P_CMD_RAW_PATTERN_CONFIGURATION_T; ++ ++typedef struct _CMD_PATTERN_FUNC_CONFIG { ++ BOOLEAN fgBcA1En; ++ BOOLEAN fgMcA1En; ++ BOOLEAN fgBcA1MatchDrop; ++ BOOLEAN fgMcA1MatchDrop; ++} CMD_PATTERN_FUNC_CONFIG, *P_CMD_PATTERN_FUNC_CONFIG; ++ ++typedef struct _EVENT_TX_DONE_T { ++ UINT_8 ucPacketSeq; ++ UINT_8 ucStatus; ++ UINT_16 u2SequenceNumber; ++ UINT_32 au4Reserved1; ++ UINT_32 au4Reserved2; ++ UINT_32 au4Reserved3; ++} EVENT_TX_DONE_T, *P_EVENT_TX_DONE_T; ++ ++typedef struct _CMD_BSS_ACTIVATE_CTRL { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucActive; ++ UINT_8 aucReserved[2]; ++} CMD_BSS_ACTIVATE_CTRL, *P_CMD_BSS_ACTIVATE_CTRL; ++ ++typedef struct _CMD_SET_BSS_RLM_PARAM_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucRfBand; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucRfSco; ++ UINT_8 ucErpProtectMode; ++ UINT_8 ucHtProtectMode; ++ UINT_8 ucGfOperationMode; ++ UINT_8 ucTxRifsMode; ++ UINT_16 u2HtOpInfo3; ++ UINT_16 u2HtOpInfo2; ++ UINT_8 ucHtOpInfo1; ++ UINT_8 ucUseShortPreamble; ++ UINT_8 ucUseShortSlotTime; ++ UINT_8 ucCheckId; /* Fixed value: 0x72 */ ++} CMD_SET_BSS_RLM_PARAM_T, *P_CMD_SET_BSS_RLM_PARAM_T; ++ ++typedef struct _CMD_SET_BSS_INFO { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucConnectionState; ++ UINT_8 ucCurrentOPMode; ++ UINT_8 ucSSIDLen; ++ UINT_8 aucSSID[32]; ++ UINT_8 aucBSSID[6]; ++ UINT_8 ucIsQBSS; ++ UINT_8 ucReserved1; ++ UINT_16 u2OperationalRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ UINT_8 ucStaRecIdxOfAP; ++ UINT_8 ucReserved2; ++ UINT_8 ucReserved3; ++ UINT_8 ucNonHTBasicPhyType; /* For Slot Time and CWmin */ ++ UINT_8 ucAuthMode; ++ UINT_8 ucEncStatus; ++ UINT_8 ucPhyTypeSet; ++ UINT_8 aucOwnMac[6]; ++ UINT_8 fgWapiMode; ++ UINT_8 fgIsApMode; ++ UINT_8 fgHiddenSsidMode; ++ CMD_SET_BSS_RLM_PARAM_T rBssRlmParam; ++} CMD_SET_BSS_INFO, *P_CMD_SET_BSS_INFO; ++ ++typedef struct _CMD_UPDATE_STA_RECORD_T { ++ UINT_8 ucIndex; ++ UINT_8 ucStaType; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ UINT_16 u2AssocId; ++ UINT_16 u2ListenInterval; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucDesiredPhyTypeSet; ++ UINT_16 u2DesiredNonHTRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ UINT_8 ucIsQoS; ++ UINT_8 ucIsUapsdSupported; ++ UINT_8 ucStaState; ++ UINT_8 ucMcsSet; ++ UINT_8 ucSupMcs32; ++ UINT_8 ucAmpduParam; ++ UINT_16 u2HtCapInfo; ++ UINT_16 u2HtExtendedCap; ++ UINT_32 u4TxBeamformingCap; ++ UINT_8 ucAselCap; ++ UINT_8 ucRCPI; ++ UINT_8 ucNeedResp; ++ UINT_8 ucUapsdAc; /* b0~3: Trigger enabled, b4~7: Delivery enabled */ ++ UINT_8 ucUapsdSp; /* 0: all, 1: max 2, 2: max 4, 3: max 6 */ ++ UINT_8 aucReserved[3]; ++ /* TBD */ ++} CMD_UPDATE_STA_RECORD_T, *P_CMD_UPDATE_STA_RECORD_T; ++ ++typedef struct _CMD_REMOVE_STA_RECORD_T { ++ UINT_8 ucIndex; ++ UINT_8 ucReserved; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++} CMD_REMOVE_STA_RECORD_T, *P_CMD_REMOVE_STA_RECORD_T; ++ ++typedef struct _CMD_INDICATE_PM_BSS_CREATED_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucDtimPeriod; ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2AtimWindow; ++ UINT_8 aucReserved[2]; ++} CMD_INDICATE_PM_BSS_CREATED, *P_CMD_INDICATE_PM_BSS_CREATED; ++ ++typedef struct _CMD_INDICATE_PM_BSS_CONNECTED_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucDtimPeriod; ++ UINT_16 u2AssocId; ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2AtimWindow; ++ UINT_8 fgIsUapsdConnection; ++ UINT_8 ucBmpDeliveryAC; ++ UINT_8 ucBmpTriggerAC; ++ UINT_8 aucReserved[1]; ++} CMD_INDICATE_PM_BSS_CONNECTED, *P_CMD_INDICATE_PM_BSS_CONNECTED; ++ ++typedef struct _CMD_INDICATE_PM_BSS_ABORT { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[3]; ++} CMD_INDICATE_PM_BSS_ABORT, *P_CMD_INDICATE_PM_BSS_ABORT; ++ ++typedef struct _CMD_BEACON_TEMPLATE_UPDATE { ++ UINT_8 ucUpdateMethod; /* 0: update randomly, ++ * 1: update all, ++ * 2: delete all (1 and 2 will update directly without search) ++ */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[2]; ++ UINT_16 u2Capability; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_BEACON_TEMPLATE_UPDATE, *P_CMD_BEACON_TEMPLATE_UPDATE; ++ ++typedef struct _CMD_SET_WMM_PS_TEST_STRUCT_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ ++ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ ++ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ ++} CMD_SET_WMM_PS_TEST_STRUCT_T, *P_CMD_SET_WMM_PS_TEST_STRUCT_T; ++ ++/* Definition for CHANNEL_INFO.ucBand: ++ * 0: Reserved ++ * 1: BAND_2G4 ++ * 2: BAND_5G ++ * Others: Reserved ++ */ ++typedef struct _CHANNEL_INFO_T { ++ UINT_8 ucBand; ++ UINT_8 ucChannelNum; ++} CHANNEL_INFO_T, *P_CHANNEL_INFO_T; ++ ++typedef struct _CMD_SCAN_REQ_EXT_CH_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDLength; ++ UINT_8 aucReserved[1]; ++ UINT_16 u2ChannelMinDwellTime; ++ UINT_8 aucSSID[32]; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ_EXT_CH, *P_CMD_SCAN_REQ_EXT_CH; ++ ++typedef struct _CMD_SCAN_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDLength; ++ UINT_8 aucReserved[1]; ++ UINT_16 u2ChannelMinDwellTime; ++ UINT_8 aucSSID[32]; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[32]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ, *P_CMD_SCAN_REQ; ++ ++typedef struct _CMD_SCAN_REQ_V2_EXT_CH_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; ++ PARAM_SSID_T arSSID[4]; ++ UINT_16 u2ProbeDelayTime; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ_V2_EXT_CH, *P_CMD_SCAN_REQ_V2_EXT_CH; ++ ++typedef struct _CMD_SCAN_REQ_V2_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; ++ PARAM_SSID_T arSSID[4]; ++ UINT_16 u2ProbeDelayTime; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[32]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ_V2, *P_CMD_SCAN_REQ_V2; ++ ++typedef struct _CMD_SCAN_CANCEL_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucIsExtChannel; /* For P2P channel extension. */ ++ UINT_8 aucReserved[2]; ++} CMD_SCAN_CANCEL, *P_CMD_SCAN_CANCEL; ++ ++typedef struct _EVENT_SCAN_DONE_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucSparseChannelValid; ++ CHANNEL_INFO_T rSparseChannel; ++} EVENT_SCAN_DONE, *P_EVENT_SCAN_DONE; ++ ++#if CFG_SUPPORT_GET_CH_ENV ++typedef struct _CH_ENV_T { ++ UINT_8 ucChNum; ++ UINT_8 ucApNum; ++} CH_ENV_T, *P_CH_ENV_T; ++#endif ++ ++#if 0 /* CFG_SUPPORT_BATCH_SCAN */ ++typedef struct _CMD_BATCH_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucCmd; /* Start/ Stop */ ++ UINT_8 ucMScan; /* an integer number of scans per batch */ ++ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ ++ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd ++ like approximate distance reported */ ++ UINT_8 ucChannel; /* channels */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ ++ CHANNEL_INFO_T arChannelList[32]; /* channels */ ++} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; ++ ++typedef struct _EVENT_BATCH_RESULT_ENTRY_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ UINT_8 ucSSIDLen; ++ INT_8 cRssi; ++ UINT_32 ucFreq; ++ UINT_32 u4Age; ++ UINT_32 u4Dist; ++ UINT_32 u4Distsd; ++} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; ++ ++typedef struct _EVENT_BATCH_RESULT_T { ++ UINT_8 ucScanCount; ++ UINT_8 aucReserved[3]; ++ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ ++} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; ++#endif ++ ++typedef struct _CMD_CH_PRIVILEGE_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucAction; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucRfSco; ++ UINT_8 ucRfBand; ++ UINT_8 ucReqType; ++ UINT_8 ucReserved; ++ UINT_32 u4MaxInterval; /* In unit of ms */ ++ UINT_8 aucBSSID[6]; ++ UINT_8 aucReserved[2]; ++} CMD_CH_PRIVILEGE_T, *P_CMD_CH_PRIVILEGE_T; ++ ++typedef struct _CMD_TX_PWR_T { ++ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ ++#if defined(MT6620) ++ INT_8 acReserved[3]; ++#elif defined(MT6628) ++ INT_8 cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ ++ INT_8 acReserved[2]; ++#else ++#error "No valid definition!" ++#endif ++ ++ INT_8 cTxPwr2G4OFDM_BPSK; ++ INT_8 cTxPwr2G4OFDM_QPSK; ++ INT_8 cTxPwr2G4OFDM_16QAM; ++ INT_8 cTxPwr2G4OFDM_Reserved; ++ INT_8 cTxPwr2G4OFDM_48Mbps; ++ INT_8 cTxPwr2G4OFDM_54Mbps; ++ ++ INT_8 cTxPwr2G4HT20_BPSK; ++ INT_8 cTxPwr2G4HT20_QPSK; ++ INT_8 cTxPwr2G4HT20_16QAM; ++ INT_8 cTxPwr2G4HT20_MCS5; ++ INT_8 cTxPwr2G4HT20_MCS6; ++ INT_8 cTxPwr2G4HT20_MCS7; ++ ++ INT_8 cTxPwr2G4HT40_BPSK; ++ INT_8 cTxPwr2G4HT40_QPSK; ++ INT_8 cTxPwr2G4HT40_16QAM; ++ INT_8 cTxPwr2G4HT40_MCS5; ++ INT_8 cTxPwr2G4HT40_MCS6; ++ INT_8 cTxPwr2G4HT40_MCS7; ++ ++ INT_8 cTxPwr5GOFDM_BPSK; ++ INT_8 cTxPwr5GOFDM_QPSK; ++ INT_8 cTxPwr5GOFDM_16QAM; ++ INT_8 cTxPwr5GOFDM_Reserved; ++ INT_8 cTxPwr5GOFDM_48Mbps; ++ INT_8 cTxPwr5GOFDM_54Mbps; ++ ++ INT_8 cTxPwr5GHT20_BPSK; ++ INT_8 cTxPwr5GHT20_QPSK; ++ INT_8 cTxPwr5GHT20_16QAM; ++ INT_8 cTxPwr5GHT20_MCS5; ++ INT_8 cTxPwr5GHT20_MCS6; ++ INT_8 cTxPwr5GHT20_MCS7; ++ ++ INT_8 cTxPwr5GHT40_BPSK; ++ INT_8 cTxPwr5GHT40_QPSK; ++ INT_8 cTxPwr5GHT40_16QAM; ++ INT_8 cTxPwr5GHT40_MCS5; ++ INT_8 cTxPwr5GHT40_MCS6; ++ INT_8 cTxPwr5GHT40_MCS7; ++} CMD_TX_PWR_T, *P_CMD_TX_PWR_T; ++ ++typedef struct _CMD_5G_PWR_OFFSET_T { ++ INT_8 cOffsetBand0; /* 4.915-4.980G */ ++ INT_8 cOffsetBand1; /* 5.000-5.080G */ ++ INT_8 cOffsetBand2; /* 5.160-5.180G */ ++ INT_8 cOffsetBand3; /* 5.200-5.280G */ ++ INT_8 cOffsetBand4; /* 5.300-5.340G */ ++ INT_8 cOffsetBand5; /* 5.500-5.580G */ ++ INT_8 cOffsetBand6; /* 5.600-5.680G */ ++ INT_8 cOffsetBand7; /* 5.700-5.825G */ ++} CMD_5G_PWR_OFFSET_T, *P_CMD_5G_PWR_OFFSET_T; ++ ++typedef struct _CMD_PWR_PARAM_T { ++ UINT_32 au4Data[28]; ++ UINT_32 u4RefValue1; ++ UINT_32 u4RefValue2; ++} CMD_PWR_PARAM_T, *P_CMD_PWR_PARAM_T; ++ ++typedef struct _CMD_PHY_PARAM_T { ++ UINT_8 aucData[144]; /* eFuse content */ ++} CMD_PHY_PARAM_T, *P_CMD_PHY_PARAM_T; ++ ++typedef struct _CMD_AUTO_POWER_PARAM_T { ++ UINT_8 ucType; /* 0: Disable 1: Enalbe 0x10: Change parameters */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[2]; ++ UINT_8 aucLevelRcpiTh[3]; ++ UINT_8 aucReserved2[1]; ++ INT_8 aicLevelPowerOffset[3]; /* signed, in unit of 0.5dBm */ ++ UINT_8 aucReserved3[1]; ++ UINT_8 aucReserved4[8]; ++} CMD_AUTO_POWER_PARAM_T, *P_CMD_AUTO_POWER_PARAM_T; ++ ++typedef struct _EVENT_CH_PRIVILEGE_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucStatus; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucRfSco; ++ UINT_8 ucRfBand; ++ UINT_8 ucReqType; ++ UINT_8 ucReserved; ++ UINT_32 u4GrantInterval; /* In unit of ms */ ++} EVENT_CH_PRIVILEGE_T, *P_EVENT_CH_PRIVILEGE_T; ++ ++typedef enum _ENUM_BEACON_TIMEOUT_TYPE_T { ++ BEACON_TIMEOUT_LOST_BEACON = 0, ++ BEACON_TIMEOUT_AGE, ++ BEACON_TIMEOUT_CONNECT, ++ BEACON_TIMEOUT_BEACON_INTERVAL, ++ BEACON_TIMEOUT_ABORT, ++ BEACON_TIMEOUT_TX_ERROR, ++ BEACON_TIMEOUT_TYPE_NUM ++} ENUM_BEACON_TIMEOUT_TYPE_T, *P_ENUM_BEACON_TIMEOUT_TYPE_T; ++ ++typedef struct _EVENT_BSS_BEACON_TIMEOUT_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucReason; /* ENUM_BEACON_TIMEOUT_TYPE_T */ ++ UINT_8 aucReserved[2]; ++} EVENT_BSS_BEACON_TIMEOUT_T, *P_EVENT_BSS_BEACON_TIMEOUT_T; ++ ++typedef struct _EVENT_STA_AGING_TIMEOUT_T { ++ UINT_8 ucStaRecIdx; ++ UINT_8 aucReserved[3]; ++} EVENT_STA_AGING_TIMEOUT_T, *P_EVENT_STA_AGING_TIMEOUT_T; ++ ++typedef struct _EVENT_NOA_TIMING_T { ++ UINT_8 fgIsInUse; /* Indicate if this entry is in use or not */ ++ UINT_8 ucCount; /* Count */ ++ UINT_8 aucReserved[2]; ++ ++ UINT_32 u4Duration; /* Duration */ ++ UINT_32 u4Interval; /* Interval */ ++ UINT_32 u4StartTime; /* Start Time */ ++} EVENT_NOA_TIMING_T, *P_EVENT_NOA_TIMING_T; ++ ++typedef struct _EVENT_UPDATE_NOA_PARAMS_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[2]; ++ UINT_8 fgEnableOppPS; ++ UINT_16 u2CTWindow; ++ ++ UINT_8 ucNoAIndex; ++ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ ++ EVENT_NOA_TIMING_T arEventNoaTiming[8 /*P2P_MAXIMUM_NOA_COUNT */]; ++} EVENT_UPDATE_NOA_PARAMS_T, *P_EVENT_UPDATE_NOA_PARAMS_T; ++ ++typedef struct _EVENT_AP_OBSS_STATUS_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucObssErpProtectMode; ++ UINT_8 ucObssHtProtectMode; ++ UINT_8 ucObssGfOperationMode; ++ UINT_8 ucObssRifsOperationMode; ++ UINT_8 ucObssBeaconForcedTo20M; ++ UINT_8 aucReserved[2]; ++} EVENT_AP_OBSS_STATUS_T, *P_EVENT_AP_OBSS_STATUS_T; ++ ++typedef struct _CMD_EDGE_TXPWR_LIMIT_T { ++ INT_8 cBandEdgeMaxPwrCCK; ++ INT_8 cBandEdgeMaxPwrOFDM20; ++ INT_8 cBandEdgeMaxPwrOFDM40; ++ INT_8 cReserved; ++} CMD_EDGE_TXPWR_LIMIT_T, *P_CMD_EDGE_TXPWR_LIMIT_T; ++ ++typedef struct _CMD_RSSI_COMPENSATE_T { ++ UINT_8 uc2GRssiCompensation; ++ UINT_8 uc5GRssiCompensation; ++ UINT_8 ucRssiCompensationValidbit; ++ UINT_8 cReserved; ++} CMD_RSSI_COMPENSATE_T, *P_CMD_RSSI_COMPENSATE_T; ++ ++typedef struct _CMD_BAND_SUPPORT_T { ++ UINT_8 uc5GBandSupport; ++ UINT_8 cReserved[3]; ++} CMD_BAND_SUPPORT_T, *P_CMD_BAND_SUPPORT_T; ++ ++typedef struct _CMD_TX_PWR_CE_T { ++ INT_8 cTxPwrCckLmt; /* signed, in unit of 0.5dBm */ ++ INT_8 cTxPwrOfdmLmt; /* signed, in unit of 0.5dBm */ ++ INT_8 cTxPwrHt20Lmt; ++ INT_8 cTxPwrHt40Lmt; ++} CMD_TX_PWR_CE_T, *P_CMD_TX_PWR_CE_T; ++ ++typedef struct _CMD_SET_DEVICE_MODE_T { ++ UINT_16 u2ChipID; ++ UINT_16 u2Mode; ++} CMD_SET_DEVICE_MODE_T, *P_CMD_SET_DEVICE_MODE_T; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++typedef struct _CMD_RDD_CH_T { ++ UINT_8 ucRddTestMode; ++ UINT_8 ucRddShutCh; ++ UINT_8 ucRddStartCh; ++ UINT_8 ucRddStopCh; ++ UINT_8 ucRddDfs; ++ UINT_8 ucReserved; ++ UINT_8 ucReserved1; ++ UINT_8 ucReserved2; ++} CMD_RDD_CH_T, *P_CMD_RDD_CH_T; ++ ++typedef struct _EVENT_RDD_STATUS_T { ++ UINT_8 ucRddStatus; ++ UINT_8 aucReserved[3]; ++} EVENT_RDD_STATUS_T, *P_EVENT_RDD_STATUS_T; ++#endif ++ ++typedef struct _EVENT_AIS_BSS_INFO_T { ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ ++ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ ++ BOOLEAN fgIsNetActive; /* TRUE if this network has been actived */ ++ UINT_8 ucReserved[3]; ++} EVENT_AIS_BSS_INFO_T, *P_EVENT_AIS_BSS_INFO_T; ++ ++typedef struct _CMD_SET_TXPWR_CTRL_T { ++ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c2GHotspotPwrOffset; ++ INT_8 c2GP2pPwrOffset; ++ INT_8 c2GBowPwrOffset; ++ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c5GHotspotPwrOffset; ++ INT_8 c5GP2pPwrOffset; ++ INT_8 c5GBowPwrOffset; ++ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence ++ in the same channel ++ 0: Highest power has priority ++ 1: Lowest power has priority */ ++ INT_8 acReserved1[3]; /* Must be zero */ ++ ++ /* Power limit by channel for all data rates */ ++ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ ++ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ ++ INT_8 acReserved2[2]; /* Must be zero */ ++} CMD_SET_TXPWR_CTRL_T, *P_CMD_SET_TXPWR_CTRL_T; ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++typedef struct _CMD_GET_BUILD_DATE_CODE { ++ UINT_8 aucReserved[4]; ++} CMD_GET_BUILD_DATE_CODE, *P_CMD_GET_BUILD_DATE_CODE; ++ ++typedef struct _EVENT_BUILD_DATE_CODE { ++ UINT_8 aucDateCode[16]; ++} EVENT_BUILD_DATE_CODE, *P_EVENT_BUILD_DATE_CODE; ++#endif ++ ++typedef struct _CMD_GET_STA_STATISTICS_T { ++ UINT_8 ucIndex; ++ UINT_8 ucFlags; ++ UINT_8 ucReadClear; ++ UINT_8 aucReserved0[1]; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ UINT_8 aucReserved1[2]; ++ UINT_8 aucReserved2[16]; ++} CMD_GET_STA_STATISTICS_T, *P_CMD_GET_STA_STATISTICS_T; ++ ++/* CFG_SUPPORT_WFD */ ++typedef struct _EVENT_STA_STATISTICS_T { ++ /* Event header */ ++ /* UINT_16 u2Length; */ ++ /* UINT_16 u2Reserved1; *//* Must be filled with 0x0001 (EVENT Packet) */ ++ /* UINT_8 ucEID; */ ++ /* UINT_8 ucSeqNum; */ ++ /* UINT_8 aucReserved2[2]; */ ++ ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucNetworkTypeIndex; ++ UINT_8 ucWTEntry; ++ UINT_8 aucReserved4[1]; ++ ++ UINT_8 ucMacAddr[MAC_ADDR_LEN]; ++ UINT_8 ucPer; /* base: 128 */ ++ UINT_8 ucRcpi; ++ ++ UINT_32 u4PhyMode; /* SGI BW */ ++ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ ++ UINT_8 ucLinkQuality; ++ UINT_8 ucLinkReserved; ++ ++ UINT_32 u4TxCount; ++ UINT_32 u4TxFailCount; ++ UINT_32 u4TxLifeTimeoutCount; ++ UINT_32 u4TxDoneAirTime; ++ ++ UINT_8 aucReserved[64]; ++} EVENT_STA_STATISTICS_T, *P_EVENT_STA_STATISTICS_T; ++ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++typedef struct _CMD_HOTSPOT_OPTIMIZATION_CONFIG { ++ UINT_32 fgHotspotOptimizationEn; ++ UINT_32 u4Level; ++} CMD_HOTSPOT_OPTIMIZATION_CONFIG, *P_HOTSPOT_OPTIMIZATION_CONFIG; ++#endif ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++/* 4 Auto Channel Selection */ ++ ++typedef struct _CMD_GET_CHN_LOAD_T { ++ UINT_8 ucIndex; ++ UINT_8 ucFlags; ++ UINT_8 ucReadClear; ++ UINT_8 aucReserved0[1]; ++ ++ UINT_8 ucChannel; ++ UINT_16 u2ChannelLoad; ++ UINT_8 aucReserved1[1]; ++ UINT_8 aucReserved2[16]; ++} CMD_GET_CHN_LOAD_T, *P_CMD_GET_CHN_LOAD_T; ++/* 4 Auto Channel Selection */ ++ ++typedef struct _EVENT_CHN_LOAD_T { ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ UINT_8 ucChannel; ++ UINT_16 u2ChannelLoad; ++ UINT_8 aucReserved4[1]; ++ ++ UINT_8 aucReserved[64]; ++ ++} EVENT_CHN_LOAD_T, *P_EVENT_CHN_LOAD_T; ++typedef struct _CMD_GET_LTE_SAFE_CHN_T { ++ UINT_8 ucIndex; ++ UINT_8 ucFlags; ++ UINT_8 aucReserved0[2]; ++ ++ UINT_8 aucReserved2[16]; ++} CMD_GET_LTE_SAFE_CHN_T, *P_CMD_GET_LTE_SAFE_CHN_T; ++ ++typedef struct _EVENT_LTE_MODE_T { ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ LTE_SAFE_CH_INFO_T rLteSafeChn; ++ UINT_8 aucReserved4[3]; ++ ++ UINT_8 aucReserved[4]; ++ ++} EVENT_LTE_MODE_T, *P_EVENT_LTE_MODE_T; ++#endif ++typedef struct _CMD_ROAMING_INFO_T { ++ UINT_32 fgIsFastRoamingApplied; ++ UINT_32 Reserved[9]; ++} CMD_ROAMING_INFO_T; ++ ++typedef struct _CMD_WFD_DEBUG_MODE_INFO_T { ++ UINT_8 ucDebugMode; ++ UINT_16 u2PeriodInteval; ++ UINT_8 Reserved; ++} CMD_WFD_DEBUG_MODE_INFO_T, *P_CMD_WFD_DEBUG_MODE_INFO_T; ++ ++typedef struct _EVENT_FW_LOG_T { ++ UINT_8 fileName[64]; ++ UINT_32 lineNo; ++ UINT_32 WifiUpTime; ++ UINT_8 log[896]; /* total size is aucBuffer in WIFI_EVENT_T */ ++} EVENT_FW_LOG_T, *P_EVENT_FW_LOG_T; ++ ++typedef enum _ENUM_NLO_CIPHER_ALGORITHM { ++ NLO_CIPHER_ALGO_NONE = 0x00, ++ NLO_CIPHER_ALGO_WEP40 = 0x01, ++ NLO_CIPHER_ALGO_TKIP = 0x02, ++ NLO_CIPHER_ALGO_CCMP = 0x04, ++ NLO_CIPHER_ALGO_WEP104 = 0x05, ++ NLO_CIPHER_ALGO_WPA_USE_GROUP = 0x100, ++ NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100, ++ NLO_CIPHER_ALGO_WEP = 0x101, ++} ENUM_NLO_CIPHER_ALGORITHM, *P_ENUM_NLO_CIPHER_ALGORITHM; ++ ++typedef enum _ENUM_NLO_AUTH_ALGORITHM { ++ NLO_AUTH_ALGO_80211_OPEN = 1, ++ NLO_AUTH_ALGO_80211_SHARED_KEY = 2, ++ NLO_AUTH_ALGO_WPA = 3, ++ NLO_AUTH_ALGO_WPA_PSK = 4, ++ NLO_AUTH_ALGO_WPA_NONE = 5, ++ NLO_AUTH_ALGO_RSNA = 6, ++ NLO_AUTH_ALGO_RSNA_PSK = 7, ++} ENUM_NLO_AUTH_ALGORITHM, *P_ENUM_NLO_AUTH_ALGORITHM; ++ ++typedef struct _NLO_NETWORK { ++ UINT_8 ucNumChannelHint[4]; ++ UINT_8 ucSSIDLength; ++ UINT_8 ucCipherAlgo; ++ UINT_16 u2AuthAlgo; ++ UINT_8 aucSSID[32]; ++} NLO_NETWORK, *P_NLO_NETWORK; ++ ++typedef struct _CMD_NLO_REQ { ++ UINT_8 ucSeqNum; ++ UINT_8 ucBssIndex; ++ UINT_8 ucNetworkType; ++ UINT_8 fgStopAfterIndication; ++ UINT_8 ucFastScanIteration; ++ UINT_16 u2FastScanPeriod; ++ UINT_16 u2SlowScanPeriod; ++ UINT_8 ucEntryNum; ++ UINT_8 ucReserved; ++ UINT_16 u2IELen; ++ NLO_NETWORK arNetworkList[16]; ++ UINT_8 aucIE[0]; ++ UINT_8 ucScanType; ++} CMD_NLO_REQ, *P_CMD_NLO_REQ; ++ ++typedef struct _CMD_NLO_CANCEL_T { ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved[3]; ++} CMD_NLO_CANCEL, *P_CMD_NLO_CANCEL; ++ ++typedef struct _EVENT_NLO_DONE_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucStatus; ++ UINT_8 aucReserved[2]; ++} EVENT_NLO_DONE_T, *P_EVENT_NLO_DONE_T; ++ ++typedef struct _EVENT_GSCAN_CAPABILITY_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4MaxScanCacheSize; ++ UINT_32 u4MaxScanBuckets; ++ UINT_32 u4MaxApCachePerScan; ++ UINT_32 u4MaxRssiSampleSize; ++ UINT_32 u4MaxScanReportingThreshold; ++ UINT_32 u4MaxHotlistAps; ++ UINT_32 u4MaxSignificantWifiChangeAps; ++ UINT_32 au4Reserved[4]; ++} EVENT_GSCAN_CAPABILITY_T, *P_EVENT_GSCAN_CAPABILITY_T; ++ ++typedef struct _EVENT_GSCAN_SCAN_AVAILABLE_T { ++ UINT_16 u2Num; ++ UINT_8 aucReserved[2]; ++} EVENT_GSCAN_SCAN_AVAILABLE_T, *P_EVENT_GSCAN_SCAN_AVAILABLE_T; ++ ++typedef struct _EVENT_GSCAN_SCAN_COMPLETE_T { ++ UINT_8 ucScanState; ++ UINT_8 aucReserved[3]; ++} EVENT_GSCAN_SCAN_COMPLETE_T, *P_EVENT_GSCAN_SCAN_COMPLETE_T; ++ ++typedef struct WIFI_GSCAN_RESULT { ++ UINT_64 u8Ts; /* Time of discovery */ ++ UINT_8 arSsid[ELEM_MAX_LEN_SSID + 1]; /* null terminated */ ++ UINT_8 arMacAddr[6]; /* BSSID */ ++ UINT_32 u4Channel; /* channel frequency in MHz */ ++ INT_32 i4Rssi; /* in db */ ++ UINT_64 u8Rtt; /* in nanoseconds */ ++ UINT_64 u8RttSd; /* standard deviation in rtt */ ++ UINT_16 u2BeaconPeriod; /* units are Kusec */ ++ UINT_16 u2Capability; /* Capability information */ ++ UINT_32 u4IeLength; /* byte length of Information Elements */ ++ UINT_8 ucIeData[1]; /* IE data to follow */ ++} WIFI_GSCAN_RESULT_T, *P_WIFI_GSCAN_RESULT_T; ++ ++typedef struct _EVENT_GSCAN_RESULT_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ UINT_16 u2ScanId; ++ UINT_16 u2ScanFlags; ++ UINT_16 u2NumOfResults; ++ WIFI_GSCAN_RESULT_T rResult[1]; ++} EVENT_GSCAN_RESULT_T, *P_EVENT_GSCAN_RESULT_T; ++ ++typedef struct _EVENT_GSCAN_FULL_RESULT_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ WIFI_GSCAN_RESULT_T rResult; ++} EVENT_GSCAN_FULL_RESULT_T, *P_EVENT_GSCAN_FULL_RESULT_T; ++ ++typedef struct GSCAN_SWC_NET { ++ UINT_16 u2Flags; ++ UINT_16 u2Channel; ++ UINT_8 arBssid[6]; ++ INT_8 aicRssi[SCN_PSCAN_SWC_RSSI_WIN_MAX]; ++} GSCAN_SWC_NET_T, P_GSCAN_SWC_NET_T; ++ ++typedef struct _EVENT_GSCAN_SIGNIFICANT_CHANGE_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ GSCAN_SWC_NET_T arNet[SCN_PSCAN_SWC_MAX_NUM]; ++} EVENT_GSCAN_SIGNIFICANT_CHANGE_T, *P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T; ++ ++typedef struct _EVENT_GSCAN_GEOFENCE_FOUND_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ WIFI_GSCAN_RESULT_T rResult[SCN_PSCAN_HOTLIST_REPORT_MAX_NUM]; ++} EVENT_GSCAN_GEOFENCE_FOUND_T, *P_EVENT_GSCAN_GEOFENCE_FOUND_T; ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ ++#if 0 /* !CFG_SUPPORT_GSCN */ ++typedef struct _CMD_BATCH_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucCmd; /* Start/ Stop */ ++ UINT_8 ucMScan; /* an integer number of scans per batch */ ++ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ ++ UINT_8 ucRtt; /* an integer number of highest-strength AP for which ++ we'd like approximate distance reported */ ++ UINT_8 ucChannel; /* channels */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ ++ CHANNEL_INFO_T arChannelList[32]; /* channels */ ++} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; ++ ++#endif ++ ++typedef struct _EVENT_BATCH_RESULT_ENTRY_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ UINT_8 ucSSIDLen; ++ INT_8 cRssi; ++ UINT_32 ucFreq; ++ UINT_32 u4Age; ++ UINT_32 u4Dist; ++ UINT_32 u4Distsd; ++} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; ++ ++typedef struct _EVENT_BATCH_RESULT_T { ++ UINT_8 ucScanCount; ++ UINT_8 aucReserved[3]; ++ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ ++} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; ++#endif ++ ++typedef struct _CMD_RLM_INFO_T { ++ UINT_32 u4Version; ++ UINT_32 fgIsErrRatioEnhanceApplied; ++ UINT_8 ucErrRatio2LimitMinRate; ++ /* ++ 0:1M, 1:2M, 2:5.5M, 3:11M, 6:6M, 7:9M, 8:12M, 9:18M, 10:24M, 11:36M, 12:48M, 13:54M ++ */ ++ UINT_8 ucMinLegacyRateIdx; ++ INT_8 cMinRssiThreshold; ++ BOOLEAN fgIsRtsApplied; ++ UINT_8 ucRecoverTime; ++ ++ UINT_32 u4Reserved[0]; ++} CMD_RLM_INFO_T; ++ ++typedef struct _WIFI_SYSTEM_SUSPEND_CMD_T { ++ BOOLEAN fgIsSystemSuspend; ++ UINT_8 reserved[3]; ++} WIFI_SYSTEM_SUSPEND_CMD_T, *P_WIFI_SYSTEM_SUSPEND_CMD_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++/* Statistics responder */ ++VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++/* for timeout check */ ++VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++#endif ++ ++VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++/* 4 Auto Channel Selection */ ++VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++#endif ++ ++#if CFG_SUPPORT_BATCH_SCAN ++VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++#endif ++ ++VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _NIC_CMD_EVENT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h +new file mode 100644 +index 000000000000..994c589190de +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h +@@ -0,0 +1,177 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_init_cmd_event.h#1 ++*/ ++ ++/*! \file "nic_init_cmd_event.h" ++ \brief This file contains the declairation file of the WLAN initialization routines ++ for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: nic_init_cmd_event.h ++ * ++ * 09 26 2011 cp.wu ++ * [WCXRP00001011] [MT6628 Wi-Fi] Firmware Download Agent: make CRC validation as an optional feature ++ * add definition for disabling CRC32 validation (for MT6628 only) ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 03 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add command/event definitions for initial states ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++*/ ++#ifndef _NIC_INIT_CMD_EVENT_H ++#define _NIC_INIT_CMD_EVENT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define INIT_CMD_STATUS_SUCCESS 0 ++#define INIT_CMD_STATUS_REJECTED_INVALID_PARAMS 1 ++#define INIT_CMD_STATUS_REJECTED_CRC_ERROR 2 ++#define INIT_CMD_STATUS_REJECTED_DECRYPT_FAIL 3 ++#define INIT_CMD_STATUS_UNKNOWN 4 ++ ++#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) ++ ++typedef enum _ENUM_INIT_CMD_ID { ++ INIT_CMD_ID_DOWNLOAD_BUF = 1, ++ INIT_CMD_ID_WIFI_START, ++ INIT_CMD_ID_ACCESS_REG, ++ INIT_CMD_ID_QUERY_PENDING_ERROR ++} ENUM_INIT_CMD_ID, *P_ENUM_INIT_CMD_ID; ++ ++typedef enum _ENUM_INIT_EVENT_ID { ++ INIT_EVENT_ID_CMD_RESULT = 1, ++ INIT_EVENT_ID_ACCESS_REG, ++ INIT_EVENT_ID_PENDING_ERROR ++} ENUM_INIT_EVENT_ID, *P_ENUM_INIT_EVENT_ID; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef UINT_8 CMD_STATUS; ++ ++/* commands */ ++typedef struct _INIT_WIFI_CMD_T { ++ UINT_8 ucCID; ++ UINT_8 ucSeqNum; ++ UINT_16 u2Reserved; ++ UINT_8 aucBuffer[0]; ++} INIT_WIFI_CMD_T, *P_INIT_WIFI_CMD_T; ++ ++typedef struct _INIT_HIF_TX_HEADER_T { ++ UINT_16 u2TxByteCount; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucCSflags; ++ INIT_WIFI_CMD_T rInitWifiCmd; ++} INIT_HIF_TX_HEADER_T, *P_INIT_HIF_TX_HEADER_T; ++ ++#define DOWNLOAD_BUF_ENCRYPTION_MODE BIT(0) ++#define DOWNLOAD_BUF_NO_CRC_CHECKING BIT(30) ++#define DOWNLOAD_BUF_ACK_OPTION BIT(31) ++typedef struct _INIT_CMD_DOWNLOAD_BUF { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4CRC32; ++ UINT_32 u4DataMode; ++ UINT_8 aucBuffer[0]; ++} INIT_CMD_DOWNLOAD_BUF, *P_INIT_CMD_DOWNLOAD_BUF; ++ ++typedef struct _INIT_CMD_WIFI_START { ++ UINT_32 u4Override; ++ UINT_32 u4Address; ++} INIT_CMD_WIFI_START, *P_INIT_CMD_WIFI_START; ++ ++typedef struct _INIT_CMD_ACCESS_REG { ++ UINT_8 ucSetQuery; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++} INIT_CMD_ACCESS_REG, *P_INIT_CMD_ACCESS_REG; ++ ++/* Events */ ++typedef struct _INIT_WIFI_EVENT_T { ++ UINT_16 u2RxByteCount; ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucBuffer[0]; ++} INIT_WIFI_EVENT_T, *P_INIT_WIFI_EVENT_T; ++ ++typedef struct _INIT_HIF_RX_HEADER_T { ++ INIT_WIFI_EVENT_T rInitWifiEvent; ++} INIT_HIF_RX_HEADER_T, *P_INIT_HIF_RX_HEADER_T; ++ ++typedef struct _INIT_EVENT_CMD_RESULT { ++ UINT_8 ucStatus; /* 0: success */ ++ /* 1: rejected by invalid param */ ++ /* 2: rejected by incorrect CRC */ ++ /* 3: rejected by decryption failure */ ++ /* 4: unknown CMD */ ++ UINT_8 aucReserved[3]; ++} INIT_EVENT_CMD_RESULT, *P_INIT_EVENT_CMD_RESULT, INIT_EVENT_PENDING_ERROR, *P_INIT_EVENT_PENDING_ERROR; ++ ++typedef struct _INIT_EVENT_ACCESS_REG { ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++} INIT_EVENT_ACCESS_REG, *P_INIT_EVENT_ACCESS_REG; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _NIC_INIT_CMD_EVENT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h +new file mode 100644 +index 000000000000..85af819f4e62 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h +@@ -0,0 +1,201 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/p2p_precomp.h#1 ++*/ ++ ++/*! \file p2p_precomp.h ++ \brief Collection of most compiler flags for p2p driver are described here. ++ ++ In this file we collect all compiler flags and detail the p2p driver behavior if ++ enable/disable such switch or adjust numeric parameters. ++*/ ++ ++#ifndef _P2P_PRECOMP_H ++#define _P2P_PRECOMP_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" /* Include "config.h" */ ++ ++#include "gl_p2p_os.h" ++ ++#include "debug.h" ++ ++#include "link.h" ++#include "queue.h" ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++#include "wlan_typedef.h" ++ ++#include "mac.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "wlan_def.h" ++ ++#include "roaming_fsm.h" ++ ++/*------------------------------------------------------------------------------ ++ * .\include\nic ++ *------------------------------------------------------------------------------ ++ */ ++/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ ++#include "cmd_buf.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "nic_cmd_event.h" ++ ++/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ ++#include "nic.h" ++ ++#include "nic_init_cmd_event.h" ++ ++#include "hif_rx.h" ++#include "hif_tx.h" ++ ++#include "nic_tx.h" ++ ++/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ ++#include "nic_rx.h" ++ ++#include "que_mgt.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "p2p_typedef.h" ++#include "p2p_cmd_buf.h" ++#include "p2p_nic_cmd_event.h" ++#include "p2p_mac.h" ++#include "p2p_nic.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++ ++#include "hem_mbox.h" ++ ++#include "scan.h" ++#include "bss.h" ++ ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "wlan_bow.h" ++ ++#include "wlan_p2p.h" ++ ++#include "hal.h" ++ ++#if defined(MT6620) ++#include "mt6620_reg.h" ++#endif ++ ++#include "rlm.h" ++#include "rlm_domain.h" ++#include "rlm_protection.h" ++#include "rlm_obss.h" ++#include "rate.h" ++ ++#include "aa_fsm.h" ++ ++#include "cnm_timer.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#include "bow.h" ++#include "bow_fsm.h" ++#endif ++ ++#include "pwr_mgt.h" ++ ++#include "cnm.h" ++/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ ++#include "cnm_mem.h" ++#include "cnm_scan.h" ++ ++#include "p2p_rlm_obss.h" ++#include "p2p_bss.h" ++#include "p2p.h" ++/* Dependency: cnm_timer.h (TIMER_T) */ ++#include "p2p_fsm.h" ++#include "p2p_scan.h" ++#include "p2p_state.h" ++#include "p2p_func.h" ++#include "p2p_rlm.h" ++#include "p2p_assoc.h" ++#include "p2p_ie.h" ++ ++#include "privacy.h" ++ ++#include "mib.h" ++ ++#include "auth.h" ++#include "assoc.h" ++ ++#include "ais_fsm.h" ++ ++#include "adapter.h" ++ ++#include "que_mgt.h" ++#include "rftest.h" ++ ++#if CFG_RSN_MIGRATION ++#include "rsn.h" ++#include "sec_fsm.h" ++#endif ++ ++#if CFG_SUPPORT_WAPI ++#include "wapi.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * NVRAM structure ++ *------------------------------------------------------------------------------ ++ */ ++#include "CFG_Wifi_File.h" ++ ++#include "gl_p2p_kal.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /*_P2P_PRECOMP_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h +new file mode 100644 +index 000000000000..a02d391d3643 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h +@@ -0,0 +1,165 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/p2p_typedef.h#1 ++*/ ++ ++/*! \file p2p_typedef.h ++ \brief Declaration of data type and return values of internal protocol stack. ++ ++ In this file we declare the data type and return values which will be exported ++ to all MGMT Protocol Stack. ++*/ ++ ++#ifndef _P2P_TYPEDEF_H ++#define _P2P_TYPEDEF_H ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* ++* type definition of pointer to p2p structure ++*/ ++/* typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; */ ++typedef struct _P2P_INFO_T P2P_INFO_T, *P_P2P_INFO_T; ++ ++typedef struct _P2P_FSM_INFO_T P2P_FSM_INFO_T, *P_P2P_FSM_INFO_T; ++ ++typedef struct _P2P_CONNECTION_SETTINGS_T P2P_CONNECTION_SETTINGS_T, *P_P2P_CONNECTION_SETTINGS_T; ++ ++/* Type definition for function pointer to p2p function*/ ++typedef BOOLEAN(*P2P_LAUNCH) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*P2P_REMOVE) (P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsWlanLaunched); ++ ++typedef BOOLEAN(*KAL_P2P_GET_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*KAL_P2P_GET_TKIP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*KAL_P2P_GET_CCMP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*KAL_P2P_GET_WSC_MODE) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef struct net_device *(*KAL_P2P_GET_DEV_HDLR) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*KAL_P2P_SET_MULTICAST_WORK_ITEM) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*P2P_NET_REGISTER) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*P2P_NET_UNREGISTER) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*KAL_P2P_UPDATE_ASSOC_INFO) (IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, ++ IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); ++ ++typedef BOOLEAN(*P2P_VALIDATE_AUTH) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); ++ ++typedef BOOLEAN(*P2P_VALIDATE_ASSOC_REQ) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu4ControlFlags); ++ ++typedef VOID(*P2P_RUN_EVENT_AAA_TX_FAIL) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++typedef BOOLEAN(*P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM) (IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); ++ ++typedef WLAN_STATUS(*P2P_RUN_EVENT_AAA_COMPLETE) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++typedef VOID(*P2P_PROCESS_EVENT_UPDATE_NOA_PARAM) (IN P_ADAPTER_T prAdapter, ++ UINT_8 ucNetTypeIndex, ++ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); ++ ++typedef VOID(*SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN P_WLAN_STATUS prStatus, ++ IN P_BSS_DESC_T prBssDesc, ++ IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); ++ ++typedef VOID(*P2P_RX_PUBLIC_ACTION_FRAME) (P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*RLM_RSP_GENERATE_OBSS_SCAN_IE) (P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++typedef VOID(*RLM_UPDATE_BW_BY_CH_LIST_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++typedef VOID(*RLM_PROCESS_PUBLIC_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*RLM_PROCESS_HT_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*RLM_UPDATE_PARAMS_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); ++ ++typedef VOID(*RLM_HANDLE_OBSS_STATUS_EVENT_PKT) (P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); ++ ++typedef BOOLEAN(*P2P_FUNC_VALIDATE_PROBE_REQ) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++typedef VOID(*RLM_BSS_INIT_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++typedef UINT_32(*P2P_GET_PROB_RSP_IE_TABLE_SIZE) (VOID); ++ ++typedef PUINT_8(*P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES) (IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); ++ ++typedef VOID(*P2P_FUNC_DISCONNECT) (IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); ++ ++typedef VOID(*P2P_FSM_RUN_EVENT_RX_DEAUTH) (IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*P2P_FSM_RUN_EVENT_RX_DISASSOC) (IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++typedef BOOLEAN(*P2P_FUN_IS_AP_MODE) (IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++typedef VOID(*P2P_FSM_RUN_EVENT_BEACON_TIMEOUT) (IN P_ADAPTER_T prAdapter); ++ ++typedef VOID(*P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER) (IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*P2P_GENERATE_P2P_IE) (IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++typedef UINT_32(*P2P_CALCULATE_P2P_IE_LEN) (IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /*CFG_ENABLE_WIFI_DIRECT */ ++ ++#endif /* _P2P_TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h +new file mode 100644 +index 000000000000..1b7e7ede66e1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h +@@ -0,0 +1,388 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/precomp.h#2 ++*/ ++ ++/*! \file precomp.h ++ \brief Collection of most compiler flags are described here. ++ ++ In this file we collect all compiler flags and detail the driver behavior if ++ enable/disable such switch or adjust numeric parameters. ++*/ ++ ++/* ++** Log: precomp.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Fix BOW_FSM_INFO_T dependence. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * build up basic data structure and definitions to support BT-over-WiFi ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 11:30:58 GMT mtk02752 ++** add rftest.h for implementing RF test mode in driver land ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-23 22:02:00 GMT mtk02468 ++** Added que_mgt.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-13 21:58:36 GMT mtk01084 ++** update for new macro define ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:40:11 GMT mtk01461 ++** Add nic_cmd_event.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 20:00:26 GMT mtk01461 ++** Add cmd_buf.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:44 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:25 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:38 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _PRECOMP_H ++#define _PRECOMP_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" /* Include "config.h" */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "gl_p2p_os.h" ++#endif ++ ++#include "debug.h" ++ ++#include "link.h" ++#include "queue.h" ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++#include "wlan_typedef.h" ++ ++#include "mac.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "wlan_def.h" ++ ++#if CFG_SUPPORT_SWCR ++#include "swcr.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * .\include\nic ++ *------------------------------------------------------------------------------ ++ */ ++/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ ++#include "cmd_buf.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "nic_cmd_event.h" ++ ++/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ ++#include "nic.h" ++ ++#include "nic_init_cmd_event.h" ++ ++#include "hif_rx.h" ++#include "hif_tx.h" ++ ++#include "nic_tx.h" ++ ++/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ ++#include "nic_rx.h" ++ ++#include "que_mgt.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "p2p_typedef.h" ++#include "p2p_cmd_buf.h" ++#include "p2p_nic_cmd_event.h" ++#include "p2p_mac.h" ++#include "p2p_nic.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++ ++#include "hem_mbox.h" ++ ++#include "scan.h" ++#include "bss.h" ++ ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "wlan_bow.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "wlan_p2p.h" ++#endif ++ ++#include "hal.h" ++ ++#if defined(MT6620) ++#include "mt6620_reg.h" ++#elif defined(MT6628) ++/* #include "mt6628_reg.h" */ ++#include "mtreg.h" ++#endif ++ ++#include "rlm.h" ++#include "rlm_domain.h" ++#include "rlm_protection.h" ++#include "rlm_obss.h" ++#include "rate.h" ++#if CFG_SUPPORT_802_11V ++#include "wnm.h" ++#endif ++ ++#include "aa_fsm.h" ++ ++#include "cnm_timer.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#include "bow.h" ++#include "bow_fsm.h" ++#endif ++ ++#include "pwr_mgt.h" ++ ++#if (CFG_SUPPORT_STATISTICS == 1) ++#include "stats.h" ++#endif /* CFG_SUPPORT_STATISTICS */ ++ ++#include "cnm.h" ++/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ ++#include "cnm_mem.h" ++#include "cnm_scan.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "p2p_rlm_obss.h" ++#include "p2p_bss.h" ++#include "p2p.h" ++#include "p2p_fsm.h" ++#include "p2p_scan.h" ++#include "p2p_state.h" ++#include "p2p_func.h" ++#include "p2p_rlm.h" ++#include "p2p_assoc.h" ++#include "p2p_ie.h" ++#endif ++ ++#include "privacy.h" ++ ++#include "mib.h" ++ ++#include "auth.h" ++#include "assoc.h" ++ ++#if CFG_SUPPORT_ROAMING ++#include "roaming_fsm.h" ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++#include "ais_fsm.h" ++ ++#include "adapter.h" ++ ++#include "que_mgt.h" ++#include "rftest.h" ++ ++#if CFG_RSN_MIGRATION ++#include "rsn.h" ++#include "sec_fsm.h" ++#endif ++ ++#if CFG_SUPPORT_WAPI ++#include "wapi.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * NVRAM structure ++ *------------------------------------------------------------------------------ ++ */ ++#include "CFG_Wifi_File.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "gl_p2p_kal.h" ++#endif ++ ++typedef int (*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); ++typedef void (*set_dbg_level) (unsigned char modules[DBG_MODULE_NUM]); ++ ++extern void wlanRegisterNotifier(void); ++extern void wlanUnregisterNotifier(void); ++extern void register_set_p2p_mode_handler(set_p2p_mode handler); ++extern void register_set_dbg_level_handler(set_dbg_level handler); ++ ++#if CFG_TC1_FEATURE ++#define NIC_INF_NAME_IN_AP_MODE "legacy%d" ++extern volatile int wlan_if_changed; ++#endif ++extern BOOLEAN fgIsResetting; ++ ++extern UINT_8 g_aucBufIpAddr[32]; ++extern UINT_8 aucDebugModule[]; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _PRECOMP_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h +new file mode 100644 +index 000000000000..40f52dcc9d68 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h +@@ -0,0 +1,141 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/pwr_mgt.h#1 ++*/ ++ ++/*! \file "pwr_mgt.h" ++ \brief In this file we define the STATE and EVENT for Power Management FSM. ++ ++ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter ++ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail ++ description. ++*/ ++ ++/* ++** Log: pwr_mgt.h ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL ++ * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. ++ ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * firmware download load address & start address are now configured from config.h ++ * * * due to the different configurations on FPGA and ASIC ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-10 16:39:10 GMT mtk02752 ++** disable PM macros temporally ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-29 19:48:37 GMT mtk01084 ++** temp remove power management macro ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-08 16:51:11 GMT mtk01084 ++** update for power management control macro ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-03 14:59:58 GMT mtk01426 ++** Add #if CFG_HIF_LOOPBACK_PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:53:10 GMT mtk01084 ++** modify ACQUIRE_POWER_CONTROL_FROM_PM() and RECLAIM_POWER_CONTROL_TO_PM() macro ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:32:47 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:20 GMT mtk01084 ++** Initial version ++** ++*/ ++ ++#ifndef _PWR_MGT_H ++#define _PWR_MGT_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define PM_UAPSD_AC0 (BIT(0)) ++#define PM_UAPSD_AC1 (BIT(1)) ++#define PM_UAPSD_AC2 (BIT(2)) ++#define PM_UAPSD_AC3 (BIT(3)) ++ ++#define PM_UAPSD_ALL (PM_UAPSD_AC0 | PM_UAPSD_AC1 | PM_UAPSD_AC2 | PM_UAPSD_AC3) ++#define PM_UAPSD_NONE 0 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _PM_PROFILE_SETUP_INFO_T { ++ /* Profile setup */ ++ UINT_8 ucBmpDeliveryAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ ++ UINT_8 ucBmpTriggerAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ ++ ++ UINT_8 ucUapsdSp; /* Number of triggered packets in UAPSD */ ++ ++} PM_PROFILE_SETUP_INFO_T, *P_PM_PROFILE_SETUP_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if !CFG_ENABLE_FULL_PM ++#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) ++#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) ++#else ++#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) \ ++ { \ ++ if (_prAdapter->fgIsFwOwn) { \ ++ nicpmSetDriverOwn(_prAdapter); \ ++ } \ ++ /* Increase Block to Enter Low Power Semaphore count */ \ ++ GLUE_INC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ ++ } ++ ++#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) \ ++ { \ ++ ASSERT(_prAdapter->u4PwrCtrlBlockCnt != 0); \ ++ /* Decrease Block to Enter Low Power Semaphore count */ \ ++ GLUE_DEC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ ++ if (_prAdapter->fgWiFiInSleepyState && (_prAdapter->u4PwrCtrlBlockCnt == 0)) { \ ++ nicpmSetFWOwn(_prAdapter, _fgEnableGINT_in_IST); \ ++ } \ ++ } ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _PWR_MGT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h +new file mode 100644 +index 000000000000..a9e74b58a8c9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h +@@ -0,0 +1,195 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/queue.h#1 ++*/ ++ ++/*! \file queue.h ++ \brief Definition for singly queue operations. ++ ++ In this file we define the singly queue data structure and its ++ queue operation MACROs. ++*/ ++ ++/* ++** Log: queue.h ++ * ++ * 07 16 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * bugfix for SCN migration ++ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue ++ * 2) before AIS issues scan request, network(BSS) needs to be activated first ++ * 3) only invoke COPY_SSID when using specified SSID for scan ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:46 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _QUEUE_H ++#define _QUEUE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Singly Queue Structures - Entry Part */ ++typedef struct _QUE_ENTRY_T { ++ struct _QUE_ENTRY_T *prNext; ++ struct _QUE_ENTRY_T *prPrev; /* For Rx buffer reordering used only */ ++} QUE_ENTRY_T, *P_QUE_ENTRY_T; ++ ++/* Singly Queue Structures - Queue Part */ ++typedef struct _QUE_T { ++ P_QUE_ENTRY_T prHead; ++ P_QUE_ENTRY_T prTail; ++ UINT_32 u4NumElem; ++} QUE_T, *P_QUE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* ++ * To resolve compiler warning of address check -Waddress ++ * Redefine a ASSERT dedicate for queue operation ++ */ ++#if DBG ++#define QUE_ASSERT ASSERT ++#else ++#define QUE_ASSERT(_exp) ++#endif ++ ++#define QUEUE_INITIALIZE(prQueue) \ ++ { \ ++ (prQueue)->prHead = (P_QUE_ENTRY_T)NULL; \ ++ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ ++ (prQueue)->u4NumElem = 0; \ ++ } ++ ++#define QUEUE_IS_EMPTY(prQueue) (((P_QUE_T)(prQueue))->prHead == (P_QUE_ENTRY_T)NULL) ++ ++#define QUEUE_IS_NOT_EMPTY(prQueue) ((prQueue)->u4NumElem > 0) ++ ++#define QUEUE_GET_HEAD(prQueue) ((prQueue)->prHead) ++ ++#define QUEUE_GET_TAIL(prQueue) ((prQueue)->prTail) ++ ++#define QUEUE_GET_NEXT_ENTRY(prQueueEntry) ((prQueueEntry)->prNext) ++ ++#define QUEUE_INSERT_HEAD(prQueue, prQueueEntry) \ ++ { \ ++ QUE_ASSERT(prQueue); \ ++ QUE_ASSERT(prQueueEntry); \ ++ (prQueueEntry)->prNext = (prQueue)->prHead; \ ++ (prQueue)->prHead = (prQueueEntry); \ ++ if ((prQueue)->prTail == (P_QUE_ENTRY_T)NULL) { \ ++ (prQueue)->prTail = (prQueueEntry); \ ++ } \ ++ ((prQueue)->u4NumElem)++; \ ++ } ++ ++#define QUEUE_INSERT_TAIL(prQueue, prQueueEntry) \ ++ { \ ++ QUE_ASSERT(prQueue); \ ++ QUE_ASSERT(prQueueEntry); \ ++ (prQueueEntry)->prNext = (P_QUE_ENTRY_T)NULL; \ ++ if ((prQueue)->prTail) { \ ++ ((prQueue)->prTail)->prNext = (prQueueEntry); \ ++ } else { \ ++ (prQueue)->prHead = (prQueueEntry); \ ++ } \ ++ (prQueue)->prTail = (prQueueEntry); \ ++ ((prQueue)->u4NumElem)++; \ ++ } ++ ++/* NOTE: We assume the queue entry located at the beginning of "prQueueEntry Type", ++ * so that we can cast the queue entry to other data type without doubts. ++ * And this macro also decrease the total entry count at the same time. ++ */ ++#define QUEUE_REMOVE_HEAD(prQueue, prQueueEntry, _P_TYPE) \ ++ { \ ++ QUE_ASSERT(prQueue); \ ++ prQueueEntry = (_P_TYPE)((prQueue)->prHead); \ ++ if (prQueueEntry) { \ ++ (prQueue)->prHead = ((P_QUE_ENTRY_T)(prQueueEntry))->prNext; \ ++ if ((prQueue)->prHead == (P_QUE_ENTRY_T)NULL) { \ ++ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ ++ } \ ++ ((P_QUE_ENTRY_T)(prQueueEntry))->prNext = (P_QUE_ENTRY_T)NULL; \ ++ ((prQueue)->u4NumElem)--; \ ++ } \ ++ } ++ ++#define QUEUE_MOVE_ALL(prDestQueue, prSrcQueue) \ ++ { \ ++ QUE_ASSERT(prDestQueue); \ ++ QUE_ASSERT(prSrcQueue); \ ++ *(P_QUE_T)prDestQueue = *(P_QUE_T)prSrcQueue; \ ++ QUEUE_INITIALIZE(prSrcQueue); \ ++ } ++ ++#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \ ++ { \ ++ QUE_ASSERT(prDestQueue); \ ++ QUE_ASSERT(prSrcQueue); \ ++ if (prSrcQueue->u4NumElem > 0) { \ ++ if ((prDestQueue)->prTail) { \ ++ ((prDestQueue)->prTail)->prNext = (prSrcQueue)->prHead; \ ++ } else { \ ++ (prDestQueue)->prHead = (prSrcQueue)->prHead; \ ++ } \ ++ (prDestQueue)->prTail = (prSrcQueue)->prTail; \ ++ ((prDestQueue)->u4NumElem) += ((prSrcQueue)->u4NumElem); \ ++ QUEUE_INITIALIZE(prSrcQueue); \ ++ } \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _QUEUE_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h +new file mode 100644 +index 000000000000..4489e5601302 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h +@@ -0,0 +1,294 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/rftest.h#1 ++*/ ++ ++/*! \file "rftest.h" ++ \brief definitions for RF Productino test ++ ++*/ ++ ++/* ++** Log: rftest.h ++ * ++ * 12 20 2011 cp.wu ++ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information ++ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO ++ * to expose version information ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-08 17:35:11 GMT mtk02752 ++** * comment out RF test which is not supported on MT6620 ++** + API decalre for rftest ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-12-08 11:29:07 GMT mtk02752 ++** definitions for RF test mode ++** ++*/ ++#ifndef _RFTEST_H ++#define _RFTEST_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Table Version */ ++#define RF_AUTO_TEST_FUNCTION_TABLE_VERSION 0x01000001 ++ ++/* Power */ ++#define RF_AT_PARAM_POWER_MASK BITS(0, 7) ++#define RF_AT_PARAM_POWER_MAX RF_AT_PARAM_POWER_MASK ++ ++/* Rate */ ++#define RF_AT_PARAM_RATE_MCS_MASK BIT(31) ++#define RF_AT_PARAM_RATE_MASK BITS(0, 7) ++#define RF_AT_PARAM_RATE_CCK_MAX 3 ++#define RF_AT_PARAM_RATE_1M 0 ++#define RF_AT_PARAM_RATE_2M 1 ++#define RF_AT_PARAM_RATE_5_5M 2 ++#define RF_AT_PARAM_RATE_11M 3 ++#define RF_AT_PARAM_RATE_6M 4 ++#define RF_AT_PARAM_RATE_9M 5 ++#define RF_AT_PARAM_RATE_12M 6 ++#define RF_AT_PARAM_RATE_18M 7 ++#define RF_AT_PARAM_RATE_24M 8 ++#define RF_AT_PARAM_RATE_36M 9 ++#define RF_AT_PARAM_RATE_48M 10 ++#define RF_AT_PARAM_RATE_54M 11 ++ ++/* Antenna */ ++#define RF_AT_PARAM_ANTENNA_ID_MASK BITS(0, 7) ++#define RF_AT_PARAM_ANTENNA_ID_MAX 1 ++ ++/* Packet Length */ ++#define RF_AT_PARAM_TX_80211HDR_BYTE_MAX (32) ++#define RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX (2048) ++ ++#define RF_AT_PARAM_TX_PKTLEN_BYTE_DEFAULT 1024 ++#define RF_AT_PARAM_TX_PKTLEN_BYTE_MAX \ ++ ((UINT_16)(RF_AT_PARAM_TX_80211HDR_BYTE_MAX + RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX)) ++ ++/* Packet Count */ ++#define RF_AT_PARAM_TX_PKTCNT_DEFAULT 1000 ++#define RF_AT_PARAM_TX_PKTCNT_UNLIMITED 0 ++ ++/* Packet Interval */ ++#define RF_AT_PARAM_TX_PKT_INTERVAL_US_DEFAULT 50 ++ ++/* ALC */ ++#define RF_AT_PARAM_ALC_DISABLE 0 ++#define RF_AT_PARAM_ALC_ENABLE 1 ++ ++/* TXOP */ ++#define RF_AT_PARAM_TXOP_DEFAULT 0 ++#define RF_AT_PARAM_TXOPQUE_QMASK BITS(16, 31) ++#define RF_AT_PARAM_TXOPQUE_TMASK BITS(0, 15) ++#define RF_AT_PARAM_TXOPQUE_AC0 (0<<16) ++#define RF_AT_PARAM_TXOPQUE_AC1 (1<<16) ++#define RF_AT_PARAM_TXOPQUE_AC2 (2<<16) ++#define RF_AT_PARAM_TXOPQUE_AC3 (3<<16) ++#define RF_AT_PARAM_TXOPQUE_AC4 (4<<16) ++#define RF_AT_PARAM_TXOPQUE_QOFFSET 16 ++ ++/* Retry Limit */ ++#define RF_AT_PARAM_TX_RETRY_DEFAULT 0 ++#define RF_AT_PARAM_TX_RETRY_MAX 6 ++ ++/* QoS Queue */ ++#define RF_AT_PARAM_QOSQUE_AC0 0 ++#define RF_AT_PARAM_QOSQUE_AC1 1 ++#define RF_AT_PARAM_QOSQUE_AC2 2 ++#define RF_AT_PARAM_QOSQUE_AC3 3 ++#define RF_AT_PARAM_QOSQUE_AC4 4 ++#define RF_AT_PARAM_QOSQUE_DEFAULT RF_AT_PARAM_QOSQUE_AC0 ++ ++/* Bandwidth */ ++#define RF_AT_PARAM_BANDWIDTH_20MHZ 0 ++#define RF_AT_PARAM_BANDWIDTH_40MHZ 1 ++#define RF_AT_PARAM_BANDWIDTH_U20_IN_40MHZ 2 ++#define RF_AT_PARAM_BANDWIDTH_D20_IN_40MHZ 3 ++#define RF_AT_PARAM_BANDWIDTH_DEFAULT RF_AT_PARAM_BANDWIDTH_20MHZ ++ ++/* GI (Guard Interval) */ ++#define RF_AT_PARAM_GI_800NS 0 ++#define RF_AT_PARAM_GI_400NS 1 ++#define RF_AT_PARAM_GI_DEFAULT RF_AT_PARAM_GI_800NS ++ ++/* STBC */ ++#define RF_AT_PARAM_STBC_DISABLE 0 ++#define RF_AT_PARAM_STBC_ENABLE 1 ++ ++/* RIFS */ ++#define RF_AT_PARAM_RIFS_DISABLE 0 ++#define RF_AT_PARAM_RIFS_ENABLE 1 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Function ID List */ ++typedef enum _ENUM_RF_AT_FUNCID_T { ++ RF_AT_FUNCID_VERSION = 0, ++ RF_AT_FUNCID_COMMAND, ++ RF_AT_FUNCID_POWER, ++ RF_AT_FUNCID_RATE, ++ RF_AT_FUNCID_PREAMBLE, ++ RF_AT_FUNCID_ANTENNA, ++ RF_AT_FUNCID_PKTLEN, ++ RF_AT_FUNCID_PKTCNT, ++ RF_AT_FUNCID_PKTINTERVAL, ++ RF_AT_FUNCID_TEMP_COMPEN, ++ RF_AT_FUNCID_TXOPLIMIT, ++ RF_AT_FUNCID_ACKPOLICY, ++ RF_AT_FUNCID_PKTCONTENT, ++ RF_AT_FUNCID_RETRYLIMIT, ++ RF_AT_FUNCID_QUEUE, ++ RF_AT_FUNCID_BANDWIDTH, ++ RF_AT_FUNCID_GI, ++ RF_AT_FUNCID_STBC, ++ RF_AT_FUNCID_CHNL_FREQ, ++ RF_AT_FUNCID_RIFS, ++ RF_AT_FUNCID_TRSW_TYPE, ++ RF_AT_FUNCID_RF_SX_SHUTDOWN, ++ RF_AT_FUNCID_PLL_SHUTDOWN, ++ RF_AT_FUNCID_SLOW_CLK_MODE, ++ RF_AT_FUNCID_ADC_CLK_MODE, ++ RF_AT_FUNCID_MEASURE_MODE, ++ RF_AT_FUNCID_VOLT_COMPEN, ++ RF_AT_FUNCID_DPD_TX_GAIN, ++ RF_AT_FUNCID_DPD_MODE, ++ RF_AT_FUNCID_TSSI_MODE, ++ RF_AT_FUNCID_TX_GAIN_CODE, ++ RF_AT_FUNCID_TX_PWR_MODE, ++ ++ /* Query command */ ++ RF_AT_FUNCID_TXED_COUNT = 32, ++ RF_AT_FUNCID_TXOK_COUNT, ++ RF_AT_FUNCID_RXOK_COUNT, ++ RF_AT_FUNCID_RXERROR_COUNT, ++ RF_AT_FUNCID_RESULT_INFO, ++ RF_AT_FUNCID_TRX_IQ_RESULT, ++ RF_AT_FUNCID_TSSI_RESULT, ++ RF_AT_FUNCID_DPD_RESULT, ++ RF_AT_FUNCID_RXV_DUMP, ++ RF_AT_FUNCID_RX_PHY_STATIS, ++ RF_AT_FUNCID_MEASURE_RESULT, ++ RF_AT_FUNCID_TEMP_SENSOR, ++ RF_AT_FUNCID_VOLT_SENSOR, ++ RF_AT_FUNCID_READ_EFUSE, ++ RF_AT_FUNCID_RX_RSSI, ++ RF_AT_FUNCID_FW_INFO, ++ RF_AT_FUNCID_DRV_INFO, ++ ++ /* Set command */ ++ RF_AT_FUNCID_SET_DPD_RESULT = 64, ++ RF_AT_FUNCID_SET_CW_MODE, ++ RF_AT_FUNCID_SET_JAPAN_CH14_FILTER, ++ RF_AT_FUNCID_WRITE_EFUSE, ++ RF_AT_FUNCID_SET_MAC_ADDRESS ++} ENUM_RF_AT_FUNCID_T; ++ ++/* Command */ ++typedef enum _ENUM_RF_AT_COMMAND_T { ++ RF_AT_COMMAND_STOPTEST = 0, ++ RF_AT_COMMAND_STARTTX, ++ RF_AT_COMMAND_STARTRX, ++ RF_AT_COMMAND_RESET, ++ RF_AT_COMMAND_OUTPUT_POWER, /* Payload */ ++ RF_AT_COMMAND_LO_LEAKAGE, /* Local freq is renamed to Local leakage */ ++ RF_AT_COMMAND_CARRIER_SUPPR, /* OFDM (LTF/STF), CCK (PI,PI/2) */ ++ RF_AT_COMMAND_TRX_IQ_CAL, ++ RF_AT_COMMAND_TSSI_CAL, ++ RF_AT_COMMAND_DPD_CAL, ++ RF_AT_COMMAND_CW, ++ RF_AT_COMMAND_NUM ++} ENUM_RF_AT_COMMAND_T; ++ ++/* Preamble */ ++typedef enum _ENUM_RF_AT_PREAMBLE_T { ++ RF_AT_PREAMBLE_NORMAL = 0, ++ RF_AT_PREAMBLE_CCK_SHORT, ++ RF_AT_PREAMBLE_11N_MM, ++ RF_AT_PREAMBLE_11N_GF, ++ RF_AT_PREAMBLE_NUM ++} ENUM_RF_AT_PREAMBLE_T; ++ ++/* Ack Policy */ ++typedef enum _ENUM_RF_AT_ACK_POLICY_T { ++ RF_AT_ACK_POLICY_NORMAL = 0, ++ RF_AT_ACK_POLICY_NOACK, ++ RF_AT_ACK_POLICY_NOEXPLICTACK, ++ RF_AT_ACK_POLICY_BLOCKACK, ++ RF_AT_ACK_POLICY_NUM ++} ENUM_RF_AT_ACK_POLICY_T; ++ ++typedef enum _ENUM_RF_AUTOTEST_STATE_T { ++ RF_AUTOTEST_STATE_STANDBY = 0, ++ RF_AUTOTEST_STATE_TX, ++ RF_AUTOTEST_STATE_RX, ++ RF_AUTOTEST_STATE_RESET, ++ RF_AUTOTEST_STATE_OUTPUT_POWER, ++ RF_AUTOTEST_STATE_LOCA_FREQUENCY, ++ RF_AUTOTEST_STATE_CARRIER_SUPRRESION, ++ RF_AUTOTEST_STATE_NUM ++} ENUM_RF_AUTOTEST_STATE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData); ++ ++WLAN_STATUS ++rftestQueryATInfo(IN P_ADAPTER_T prAdapter, ++ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); ++ ++WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen); ++ ++#endif /* _RFTEST_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h +new file mode 100644 +index 000000000000..8ee184591fc2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h +@@ -0,0 +1,427 @@ ++/* ++** Id: include/tdls_extr.h#1 ++*/ ++ ++/*! \file "tdls_extr.h" ++ \brief This file contains the external used in other modules ++ for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: tdls_extr.h ++ * ++ * 11 18 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ * ++ ** ++ */ ++ ++#ifndef _TDLS_EXTR_H ++#define _TDLS_EXTR_H ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#define TDLS_TX_QUOTA_EMPTY_TIMEOUT 10 ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* protocol */ ++#define TDLS_FRM_PROT_TYPE 0x890d ++ ++/* TDLS uses Ethertype 89-0d frames. The UP shall be AC_VI, unless otherwise specified. */ ++#define USER_PRIORITY_TDLS 5 ++ ++/* Status code */ ++#define TDLS_STATUS WLAN_STATUS ++ ++#define TDLS_STATUS_SUCCESS WLAN_STATUS_SUCCESS ++#define TDLS_STATUS_FAILURE WLAN_STATUS_FAILURE ++#define TDLS_STATUS_INVALID_LENGTH WLAN_STATUS_INVALID_LENGTH ++#define TDLS_STATUS_RESOURCES WLAN_STATUS_RESOURCES ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#define TDLS_U32 UINT32 ++#define TDLS_U16 UINT16 ++#define TDLS_U8 UINT8 ++ ++typedef enum _TDLS_REASON_CODE { ++ TDLS_REASON_CODE_UNREACHABLE = 25, ++ TDLS_REASON_CODE_UNSPECIFIED = 26, ++ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN = 0x80, /* 128 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WIFI_OFF = 0x81, /* 129 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING = 0x82, /* 130 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT = 0x83, /* 131 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT = 0x84, /* 132 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY = 0x85, /* 133 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL = 0x86, /* 134 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL = 0x87, /* 135 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX = 0x88, /* 136 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3 = 0x89, /* 137 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY = 0x8a, /* 138 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN = 0x8b /* 139 */ ++} TDLS_REASON_CODE; ++ ++/* TDLS FSM */ ++typedef struct _TDLS_CMD_PEER_ADD_T { ++ ++ TDLS_U8 aucPeerMac[6]; ++ ++#if 0 ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ UINT_16 u2CapInfo; ++ ++ UINT_16 u2OperationalRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ ++ UINT_8 ucPhyTypeSet; ++#endif ++} TDLS_CMD_PEER_ADD_T; ++ ++typedef struct _TDLS_CMD_LINK_T { ++ ++ TDLS_U8 aucPeerMac[6]; ++ BOOLEAN fgIsEnabled; ++} TDLS_CMD_LINK_T; ++ ++typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T { ++ TDLS_U8 arRxMask[10]; ++ TDLS_U16 u2RxHighest; ++ TDLS_U8 ucTxParams; ++ TDLS_U8 Reserved[3]; ++} TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T; ++ ++typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_T { ++ TDLS_U16 u2CapInfo; ++ TDLS_U8 ucAmpduParamsInfo; ++ ++ /* 16 bytes MCS information */ ++ TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T rMCS; ++ ++ TDLS_U16 u2ExtHtCapInfo; ++ TDLS_U32 u4TxBfCapInfo; ++ TDLS_U8 ucAntennaSelInfo; ++} TDLS_CMD_PEER_UPDATE_HT_CAP_T; ++ ++typedef struct _TDLS_CMD_PEER_UPDATE_T { ++ ++ TDLS_U8 aucPeerMac[6]; ++ ++#define TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX 50 ++ TDLS_U8 aucSupChan[TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX]; ++ ++ TDLS_U16 u2StatusCode; ++ ++#define TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX 50 ++ TDLS_U8 aucSupRate[TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX]; ++ TDLS_U16 u2SupRateLen; ++ ++ TDLS_U8 UapsdBitmap; ++ TDLS_U8 UapsdMaxSp; /* MAX_SP */ ++ ++ TDLS_U16 u2Capability; ++#define TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN 5 ++ TDLS_U8 aucExtCap[TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN]; ++ TDLS_U16 u2ExtCapLen; ++ ++ TDLS_CMD_PEER_UPDATE_HT_CAP_T rHtCap; ++ BOOLEAN fgIsSupHt; ++ ++} TDLS_CMD_PEER_UPDATE_T; ++ ++/* Command to TDLS core module */ ++typedef enum _TDLS_CMD_CORE_ID { ++ TDLS_CORE_CMD_TEST_NULL_RCV = 0x00, ++ TDLS_CORE_CMD_TEST_PTI_RSP = 0x01, ++ TDLS_CORE_CMD_MIB_UPDATE = 0x02, ++ TDLS_CORE_CMD_TEST_TX_FAIL_SKIP = 0x03, ++ TDLS_CORE_CMD_UAPSD_CONF = 0x04, ++ TDLS_CORE_CMD_TEST_DATA_RCV = 0x05, ++ TDLS_CORE_CMD_TEST_PTI_REQ = 0x06, ++ TDLS_CORE_CMD_TEST_CHSW_REQ = 0x07, ++ TDLS_CORE_CMD_CHSW_CONF = 0x08, ++ TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP = 0x09, ++ TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP = 0x0a, ++ TDLS_CORE_CMD_TEST_CHSW_RSP = 0x0b, ++ TDLS_CORE_CMD_TEST_SCAN_SKIP = 0x0c, ++ TDLS_CORE_CMD_SETUP_CONF = 0x0d, ++ TDLS_CORE_CMD_TEST_TEAR_DOWN = 0x0e, ++ TDLS_CORE_CMD_KEY_INFO = 0x0f, ++ TDLS_CORE_CMD_TEST_PTI_TX_FAIL = 0x10 ++} TDLS_CMD_CORE_ID; ++ ++typedef struct _TDLS_CMD_CORE_TEST_NULL_RCV_T { ++ ++ TDLS_U32 u4PM; ++} TDLS_CMD_CORE_TEST_NULL_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T { ++ ++ TDLS_U32 u4DialogToken; ++} TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T { ++ ++ TDLS_U32 u4DialogToken; ++ TDLS_U32 u4PM; ++} TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T { ++ ++ TDLS_U32 u4ReasonCode; ++} TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T { ++ ++ TDLS_U32 u4Chan; ++ TDLS_U32 u4RegClass; ++ TDLS_U32 u4SecChanOff; ++ TDLS_U32 u4SwitchTime; ++ TDLS_U32 u4SwitchTimeout; ++} TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T { ++ ++ TDLS_U32 u4Chan; ++ TDLS_U32 u4SwitchTime; ++ TDLS_U32 u4SwitchTimeout; ++ TDLS_U32 u4StatusCode; ++} TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_DATA_RCV_T { ++ ++ TDLS_U32 u4PM; ++ TDLS_U32 u4UP; ++ TDLS_U32 u4EOSP; ++ TDLS_U32 u4IsNull; ++} TDLS_CMD_CORE_TEST_DATA_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_MIB_PARAM_UPDATE_T { ++ ++ BOOLEAN Tdlsdot11TunneledDirectLinkSetupImplemented; ++ BOOLEAN Tdlsdot11TDLSPeerUAPSDBufferSTAActivated; ++ BOOLEAN Tdlsdot11TDLSPeerPSMActivated; ++ TDLS_U16 Tdlsdot11TDLSPeerUAPSDIndicationWindow; ++ BOOLEAN Tdlsdot11TDLSChannelSwitchingActivated; ++ TDLS_U8 Tdlsdot11TDLSPeerSTAMissingAckRetryLimit; ++ TDLS_U8 Tdlsdot11TDLSResponseTimeout; ++ TDLS_U16 Tdlsdot11TDLSProbeDelay; ++ TDLS_U8 Tdlsdot11TDLSDiscoveryRequestWindow; ++ TDLS_U8 Tdlsdot11TDLSACDeterminationInterval; ++} TDLS_CMD_CORE_MIB_PARAM_UPDATE_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_UAPSD_CONFIG_T { ++ ++ BOOLEAN fgIsSpTimeoutSkip; ++ BOOLEAN fgIsPtiTimeoutSkip; ++} TDLS_CMD_CORE_UAPSD_CONFIG_T; ++ ++typedef struct _TDLS_CMD_CORE_SETUP_CONFIG_T { ++ ++ BOOLEAN fgIs2040Supported; ++} TDLS_CMD_CORE_SETUP_CONFIG_T; ++ ++typedef struct _TDLS_CMD_CORE_CHSW_CONFIG_T { ++ ++ TDLS_U8 ucNetTypeIndex; ++ BOOLEAN fgIsChSwEnabled; ++ BOOLEAN fgIsChSwStarted; ++ TDLS_U8 ucRegClass; ++ TDLS_U8 ucTargetChan; ++ TDLS_U8 ucSecChanOff; ++ BOOLEAN fgIsChSwRegular; ++} TDLS_CMD_CORE_CHSW_CONFIG_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PROHIBIT_T { ++ ++ BOOLEAN fgIsEnable; ++ BOOLEAN fgIsSet; ++} TDLS_CMD_CORE_TEST_PROHIBIT_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_SCAN_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_SCAN_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_INFO_DISPLAY_T { ++ ++ BOOLEAN fgIsToClearAllHistory; ++} TDLS_CMD_CORE_INFO_DISPLAY_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T; ++ ++typedef struct _TDLS_CMD_CORE_T { ++ ++ TDLS_U32 u4Command; /* TDLS_CMD_CORE_ID */ ++ ++ TDLS_U8 aucPeerMac[6]; ++ TDLS_U8 ucNetTypeIndex; ++ ++#define TDLS_CMD_CORE_RESERVED_SIZE 50 ++ union { ++ TDLS_CMD_CORE_TEST_NULL_RCV_T rCmdNullRcv; ++ TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T rCmdPtiReqRcv; ++ TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T rCmdPtiRspRcv; ++ TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T rCmdTearDownRcv; ++ TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T rCmdChStReqRcv; ++ TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T rCmdChStRspRcv; ++ TDLS_CMD_CORE_TEST_DATA_RCV_T rCmdDatRcv; ++ TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T rCmdTxFailSkip; ++ TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T rCmdKeepAliveSkip; ++ TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T rCmdChSwTimeoutSkip; ++ TDLS_CMD_CORE_TEST_PROHIBIT_T rCmdProhibit; ++ TDLS_CMD_CORE_TEST_SCAN_SKIP_T rCmdScanSkip; ++ TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T rCmdPtiTxFail; ++ ++ TDLS_CMD_CORE_MIB_PARAM_UPDATE_T rCmdMibUpdate; ++ TDLS_CMD_CORE_UAPSD_CONFIG_T rCmdUapsdConf; ++ TDLS_CMD_CORE_CHSW_CONFIG_T rCmdChSwConf; ++ TDLS_CMD_CORE_SETUP_CONFIG_T rCmdSetupConf; ++ TDLS_CMD_CORE_INFO_DISPLAY_T rCmdInfoDisplay; ++ TDLS_U8 Reserved[TDLS_CMD_CORE_RESERVED_SIZE]; ++ } Content; ++} TDLS_CMD_CORE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* ++ assign station record idx for the packet only when STA_STATE_3 ++ Or we will try to send data frame when the TDLS peer's state is STA_STATE_1 ++ EX: ++ 1. mtk_cfg80211_add_station: First create the STA_RECORD_T; ++ 2. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. ++ 3. mtk_cfg80211_add_station: Change state to STA_STATE_1. ++ 4. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. ++*/ ++#define TDLSEX_STA_REC_IDX_GET(__prAdapter__, __MsduInfo__) \ ++{ \ ++ STA_RECORD_T *__StaRec__; \ ++ __MsduInfo__->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; \ ++ __StaRec__ = cnmGetStaRecByAddress(__prAdapter__, \ ++ (UINT_8) NETWORK_TYPE_AIS_INDEX, \ ++ __MsduInfo__->aucEthDestAddr); \ ++ if ((__StaRec__ != NULL) && \ ++ ((__StaRec__)->ucStaState == STA_STATE_3) && \ ++ (IS_TDLS_STA(__StaRec__))) { \ ++ __MsduInfo__->ucStaRecIndex = __StaRec__->ucIndex; \ ++ } \ ++} ++ ++/* fill wiphy flag */ ++#define TDLSEX_WIPHY_FLAGS_INIT(__fgFlag__)\ ++{ \ ++ __fgFlag__ |= (WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP);\ ++} ++ ++/* assign user priority of a TDLS action frame */ ++/* ++ According to 802.11z: Setup req/resp are sent in AC_BK, otherwise we should default ++ to AC_VI. ++*/ ++#define TDLSEX_UP_ASSIGN(__UserPriority__) \ ++{ \ ++ __UserPriority__ = USER_PRIORITY_TDLS; \ ++} ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++int ++TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, u8 action_code, u8 dialog_token, ++ u16 status_code, u32 peer_capability, ++ bool initiator, const u8 *buf, size_t len); ++ ++int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, enum nl80211_tdls_operation oper); ++ ++VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE); ++ ++VOID TdlsexEventHandle(P_GLUE_INFO_T prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey); ++ ++VOID TdlsexInit(ADAPTER_T *prAdapter); ++ ++BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter); ++ ++TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++VOID ++TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode); ++ ++TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++TDLS_STATUS TdlsexPeerAdd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); ++ ++TDLS_STATUS TdlsexPeerUpdate(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); ++ ++BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt); ++ ++VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen); ++ ++TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo); ++ ++VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota); ++ ++VOID TdlsexUninit(ADAPTER_T *prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#endif /* _TDLS_EXTR_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h +new file mode 100644 +index 000000000000..7ab62dae8813 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h +@@ -0,0 +1,244 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/typedef.h#1 ++*/ ++ ++/*! \file typedef.h ++ \brief Declaration of data type and return values of internal protocol stack. ++ ++ In this file we declare the data type and return values which will be exported ++ to the GLUE Layer. ++*/ ++ ++/* ++** Log: typedef.h ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * host driver not to set FW-own when there is still pending interrupts ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move timer callback to glue layer. ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add Ethernet destination address information in packet info for TX ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:41:37 GMT mtk01461 ++** Update PACKET_INFO_INIT for TX Path ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:30:17 GMT mtk01461 ++** Add parameter in PACKET_INFO_T for HIF Loopback ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:22 GMT mtk01461 ++** Fix LINT warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:28 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:54 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _TYPEDEF_H ++#define _TYPEDEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* ieee80211.h of linux has duplicated definitions */ ++#if defined(WLAN_STATUS_SUCCESS) ++#undef WLAN_STATUS_SUCCESS ++#endif ++ ++#define WLAN_STATUS_SUCCESS ((WLAN_STATUS) 0x00000000L) ++#define WLAN_STATUS_PENDING ((WLAN_STATUS) 0x00000103L) ++#define WLAN_STATUS_NOT_ACCEPTED ((WLAN_STATUS) 0x00010003L) ++ ++#define WLAN_STATUS_MEDIA_CONNECT ((WLAN_STATUS) 0x4001000BL) ++#define WLAN_STATUS_MEDIA_DISCONNECT ((WLAN_STATUS) 0x4001000CL) ++#define WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ((WLAN_STATUS) 0x4001000DL) ++ ++#define WLAN_STATUS_MEDIA_SPECIFIC_INDICATION ((WLAN_STATUS) 0x40010012L) ++ ++#define WLAN_STATUS_SCAN_COMPLETE ((WLAN_STATUS) 0x60010001L) ++#define WLAN_STATUS_MSDU_OK ((WLAN_STATUS) 0x60010002L) ++ ++/* TODO(Kevin): double check if 0x60010001 & 0x60010002 is proprietary */ ++#define WLAN_STATUS_ROAM_OUT_FIND_BEST ((WLAN_STATUS) 0x60010101L) ++#define WLAN_STATUS_ROAM_DISCOVERY ((WLAN_STATUS) 0x60010102L) ++ ++#define WLAN_STATUS_FAILURE ((WLAN_STATUS) 0xC0000001L) ++#define WLAN_STATUS_RESOURCES ((WLAN_STATUS) 0xC000009AL) ++#define WLAN_STATUS_NOT_SUPPORTED ((WLAN_STATUS) 0xC00000BBL) ++ ++#define WLAN_STATUS_MULTICAST_FULL ((WLAN_STATUS) 0xC0010009L) ++#define WLAN_STATUS_INVALID_PACKET ((WLAN_STATUS) 0xC001000FL) ++#define WLAN_STATUS_ADAPTER_NOT_READY ((WLAN_STATUS) 0xC0010011L) ++#define WLAN_STATUS_NOT_INDICATING ((WLAN_STATUS) 0xC0010013L) ++#define WLAN_STATUS_INVALID_LENGTH ((WLAN_STATUS) 0xC0010014L) ++#define WLAN_STATUS_INVALID_DATA ((WLAN_STATUS) 0xC0010015L) ++#define WLAN_STATUS_BUFFER_TOO_SHORT ((WLAN_STATUS) 0xC0010016L) ++ ++#define WLAN_STATUS_BWCS_UPDATE ((WLAN_STATUS) 0xC0010017L) ++ ++#define WLAN_STATUS_CONNECT_INDICATION ((WLAN_STATUS) 0xC0010018L) ++ ++/* NIC status flags */ ++#define ADAPTER_FLAG_HW_ERR 0x00400000 ++ ++/* Type Length */ ++#define TL_IPV4 0x0008 ++#define TL_IPV6 0xDD86 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Type definition for GLUE_INFO structure */ ++typedef struct _GLUE_INFO_T GLUE_INFO_T, *P_GLUE_INFO_T; ++ ++/* Type definition for WLAN STATUS */ ++typedef UINT_32 WLAN_STATUS, *P_WLAN_STATUS; ++ ++/* Type definition for ADAPTER structure */ ++typedef struct _ADAPTER_T ADAPTER_T, *P_ADAPTER_T; ++ ++/* Type definition for MESSAGE HEADER structure */ ++typedef struct _MSG_HDR_T MSG_HDR_T, *P_MSG_HDR_T; ++ ++/* Type definition for WLAN configuration */ ++typedef struct _WLAN_CFG_T WLAN_CFG_T, *P_WLAN_CFG_T; ++ ++/* Type definition for WLAN configuration entry */ ++typedef struct _WLAN_CFG_ENTRY_T WLAN_CFG_ENTRY_T, *P_WLAN_CFG_ENTRY_T; ++ ++/* Type definition for WLAN configuration callback */ ++typedef WLAN_STATUS(*WLAN_CFG_SET_CB) (P_ADAPTER_T prAdapter, ++ PUINT_8 pucKey, PUINT_8 pucValue, PVOID pPrivate, UINT_32 u4Flags); ++ ++/* Type definition for Pointer to OS Native Packet */ ++typedef void *P_NATIVE_PACKET; ++ ++/* Type definition for STA_RECORD_T structure to handle the connectivity and packet reception ++ * for a particular STA. ++ */ ++typedef struct _STA_RECORD_T STA_RECORD_T, *P_STA_RECORD_T, **PP_STA_RECORD_T; ++ ++/* CMD_INFO_T is used by Glue Layer to send a cluster of Command(OID) information to ++ * the TX Path to reduce the parameters of a function call. ++ */ ++typedef struct _CMD_INFO_T CMD_INFO_T, *P_CMD_INFO_T; ++ ++/* Following typedef should be removed later, because Glue Layer should not ++ * be aware of following data type. ++ */ ++typedef struct _SW_RFB_T SW_RFB_T, *P_SW_RFB_T, **PP_SW_RFB_T; ++ ++typedef struct _MSDU_INFO_T MSDU_INFO_T, *P_MSDU_INFO_T; ++ ++typedef struct _REG_ENTRY_T REG_ENTRY_T, *P_REG_ENTRY_T; ++ ++/* IST handler definition */ ++typedef VOID(*IST_EVENT_FUNCTION) (P_ADAPTER_T); ++ ++/* Type definition for function pointer of timer handler */ ++typedef VOID(*PFN_TIMER_CALLBACK) (IN P_GLUE_INFO_T); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h +new file mode 100644 +index 000000000000..e8937166dc4f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h +@@ -0,0 +1,352 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_bow.h#1 ++*/ ++ ++/*! \file "wlan_bow.h" ++ \brief This file contains the declairations of 802.11 PAL ++ command processing routines for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_bow.h ++ * ++ * 05 25 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW Cancel Scan Request and Turn On deactive network function. ++ * ++ * 05 23 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add some BoW error handling. ++ * ++ * 05 21 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Protect BoW connection establishment. ++ * ++ * 05 17 2011 terry.wu ++ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting ++ * Send deauth while disconnecting BoW link. ++ * ++ * 05 06 2011 terry.wu ++ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue ++ * Fix BoW Multiple Physical Link connect/disconnect issue. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW table. ++ * ++ * 02 16 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update bowString and channel grant. ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW Activity Report structure and bug fix. ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Add bowRunEventAAAComplete. ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * 1) all BT physical handles shares the same RSSI/Link Quality. ++ * 2) simplify BT command composing ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++** ++*/ ++ ++#ifndef _WLAN_BOW_H ++#define _WLAN_BOW_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "nic/bow.h" ++#include "nic/cmd_buf.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++#if CFG_BOW_TEST ++extern UINT_32 g_arBowRevPalPacketTime[32]; ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define BOWCMD_STATUS_SUCCESS 0 ++#define BOWCMD_STATUS_FAILURE 1 ++#define BOWCMD_STATUS_UNACCEPTED 2 ++#define BOWCMD_STATUS_INVALID 3 ++#define BOWCMD_STATUS_TIMEOUT 4 ++ ++#define BOW_WILDCARD_SSID "AMP" ++#define BOW_WILDCARD_SSID_LEN 3 ++#define BOW_SSID_LEN 21 ++ ++ /* 0: query, 1: setup, 2: destroy */ ++#define BOW_QUERY_CMD 0 ++#define BOW_SETUP_CMD 1 ++#define BOW_DESTROY_CMD 2 ++ ++#define BOW_INITIATOR 0 ++#define BOW_RESPONDER 1 ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++typedef struct _BOW_TABLE_T { ++ UINT_8 ucAcquireID; ++ BOOLEAN fgIsValid; ++ ENUM_BOW_DEVICE_STATE eState; ++ UINT_8 aucPeerAddress[6]; ++ /* UINT_8 ucRole; */ ++ /* UINT_8 ucChannelNum; */ ++ UINT_16 u2Reserved; ++} BOW_TABLE_T, *P_BOW_TABLE_T; ++ ++typedef WLAN_STATUS(*PFN_BOW_CMD_HANDLE) (P_ADAPTER_T, P_AMPC_COMMAND); ++ ++typedef struct _BOW_CMD_T { ++ UINT_8 uCmdID; ++ PFN_BOW_CMD_HANDLE pfCmdHandle; ++} BOW_CMD_T, *P_BOW_CMD_T; ++ ++typedef struct _BOW_EVENT_ACTIVITY_REPORT_T { ++ UINT_8 ucReason; ++ UINT_8 aucReserved; ++ UINT_8 aucPeerAddress[6]; ++} BOW_EVENT_ACTIVITY_REPORT_T, *P_BOW_EVENT_ACTIVITY_REPORT_T; ++ ++/* ++ucReason: 0: success ++ 1: general failure ++ 2: too much time (> 2/3 second totally) requested for scheduling. ++ Others: reserved. ++*/ ++ ++typedef struct _BOW_EVENT_SYNC_TSF_T { ++ UINT_64 u4TsfTime; ++ UINT_32 u4TsfSysTime; ++ UINT_32 u4ScoTime; ++ UINT_32 u4ScoSysTime; ++} BOW_EVENT_SYNC_TSF_T, *P_BOW_EVENT_SYNC_TSF_T; ++ ++typedef struct _BOW_ACTIVITY_REPORT_BODY_T { ++ UINT_32 u4StartTime; ++ UINT_32 u4Duration; ++ UINT_32 u4Periodicity; ++} BOW_ACTIVITY_REPORT_BODY_T, *P_BOW_ACTIVITY_REPORT_BODY_T; ++ ++typedef struct _BOW_ACTIVITY_REPORT_T { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 ucScheduleKnown; ++ UINT_8 ucNumReports; ++ BOW_ACTIVITY_REPORT_BODY_T arBowActivityReportBody[MAX_ACTIVITY_REPORT]; ++} BOW_ACTIVITY_REPORT_T, *P_BOW_ACTIVITY_REPORT_T; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*--------------------------------------------------------------*/ ++/* Firmware Command Packer */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber); ++ ++/*--------------------------------------------------------------*/ ++/* Command Dispatcher */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++/*--------------------------------------------------------------*/ ++/* Routines to handle command */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf); ++ ++/*--------------------------------------------------------------*/ ++/* Callbacks for event indication */ ++/*--------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID bowStopping(IN P_ADAPTER_T prAdapter); ++ ++VOID bowStarting(IN P_ADAPTER_T prAdapter); ++ ++VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); ++ ++BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID bowResponderScan(IN P_ADAPTER_T prAdapter); ++ ++VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention); ++ ++VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID ++bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); ++ ++VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++BOOLEAN ++bowValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); ++ ++VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID bowRequestCh(IN P_ADAPTER_T prAdapter); ++ ++VOID bowReleaseCh(IN P_ADAPTER_T prAdapter); ++ ++VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam); ++ ++BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); ++ ++BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable); ++ ++BOOLEAN ++bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx); ++ ++BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx); ++ ++ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); ++ ++BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState); ++ ++BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif ++#endif /* _WLAN_BOW_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h +new file mode 100644 +index 000000000000..87259397a93d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h +@@ -0,0 +1,1001 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_lib.h#1 ++*/ ++ ++/*! \file "wlan_lib.h" ++ \brief The declaration of the functions of the wlanAdpater objects ++ ++ Detail description. ++*/ ++ ++/* ++** Log: wlan_lib.h ++ * ++ * 06 08 2012 eason.tsai ++ * NULL ++ * Nvram context covert from 6620 to 6628 for old 6620 meta tool ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for ++ * preferred band configuration with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for ++ * setting preferred band configuration corresponding to network type. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * eliminate win32 native data types. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 10 03 2011 cp.wu ++ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware downloading aggregated path. ++ * ++ * 09 20 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * change window registry of driver for roaming. ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add DFS switch. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, ++ * TX deauth to a disconnecting device issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 04 18 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * 1) add API for glue layer to query ACPI state ++ * 2) Windows glue should not access to hardware after switched into D3 state ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Support current measure mode, assigned by registry (XP only). ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result ++ * in OID handling layer when the corresponding BSS is disconnected due to beacon timeout ++ * remove from scanning result when the BSS is disconnected due to beacon timeout. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to ++ * disable Beacon Timeout function for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add AT GO test configure mode under WinXP. ++ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * . ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid ++ * descriptor underflow under concurrent network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * simplify timer usage. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add extra 64 adjustable parameters for CoEX scenario. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * * 2) add 2 kal API for later integration ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use WIFI_TCM_ALWAYS_ON as firmware image ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always send CMD_NIC_POWER_CTRL packet when nic is being halted ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * separate wlanProcesQueuePacket() into 2 APIs upon request ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. add logic for firmware download ++ * * * 2. firmware image filename and start/load address are now retrieved from registry ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * * 4) nicRxWaitResponse() revised ++ * * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * * 4. correct some HAL implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:39:55 GMT mtk02752 ++** eliminate unused API ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:58:41 GMT mtk01084 ++** update for new macro define ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-19 10:43:06 GMT mtk01461 ++** Add wlanReleasePendingOid() ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-13 16:38:44 GMT mtk01084 ++** add WIFI start function ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-08 16:51:14 GMT mtk01084 ++** Update for the image download part ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:57:38 GMT mtk01461 ++** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:31:02 GMT mtk01461 ++** Add declaration of FW Image download reference code ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:31 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:04 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _WLAN_LIB_H ++#define _WLAN_LIB_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "CFG_Wifi_File.h" ++#include "rlm_domain.h" ++#include "wlan_typedef.h" ++ ++ ++extern BOOLEAN fgIsResetting; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define MAX_NUM_GROUP_ADDR 32 /* max number of group addresses */ ++ ++#define TX_CS_TCP_UDP_GEN BIT(1) ++#define TX_CS_IP_GEN BIT(0) ++ ++#define CSUM_OFFLOAD_EN_TX_TCP BIT(0) ++#define CSUM_OFFLOAD_EN_TX_UDP BIT(1) ++#define CSUM_OFFLOAD_EN_TX_IP BIT(2) ++#define CSUM_OFFLOAD_EN_RX_TCP BIT(3) ++#define CSUM_OFFLOAD_EN_RX_UDP BIT(4) ++#define CSUM_OFFLOAD_EN_RX_IPv4 BIT(5) ++#define CSUM_OFFLOAD_EN_RX_IPv6 BIT(6) ++#define CSUM_OFFLOAD_EN_TX_MASK BITS(0, 2) ++#define CSUM_OFFLOAD_EN_ALL BITS(0, 6) ++ ++/* TCP, UDP, IP Checksum */ ++#define RX_CS_TYPE_UDP BIT(7) ++#define RX_CS_TYPE_TCP BIT(6) ++#define RX_CS_TYPE_IPv6 BIT(5) ++#define RX_CS_TYPE_IPv4 BIT(4) ++ ++#define RX_CS_STATUS_UDP BIT(3) ++#define RX_CS_STATUS_TCP BIT(2) ++#define RX_CS_STATUS_IP BIT(0) ++ ++#define CSUM_NOT_SUPPORTED 0x0 ++ ++#define TXPWR_USE_PDSLOPE 0 ++ ++/* NVRAM error code definitions */ ++#define NVRAM_ERROR_VERSION_MISMATCH BIT(1) ++#define NVRAM_ERROR_INVALID_TXPWR BIT(2) ++#define NVRAM_ERROR_INVALID_DPD BIT(3) ++#define NVRAM_ERROR_INVALID_MAC_ADDR BIT(4) ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++#define NVRAM_POWER_LIMIT_TABLE_INVALID BIT(5) ++#endif ++ ++#define NUM_TC_RESOURCE_TO_STATISTICS 4 ++ ++#define WLAN_CFG_ARGV_MAX 8 ++#define WLAN_CFG_ENTRY_NUM_MAX 128 ++#define WLAN_CFG_KEY_LEN_MAX 32 /* include \x00 EOL */ ++#define WLAN_CFG_VALUE_LEN_MAX 32 /* include \x00 EOL */ ++#define WLAN_CFG_FLAG_SKIP_CB BIT(0) ++#define WLAN_CFG_FILE_BUF_SIZE 2048 ++ ++#define WLAN_CFG_SET_CHIP_LEN_MAX 10 ++#define WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX 10 ++#define WLAN_CFG_SET_SW_CTRL_LEN_MAX 10 ++ ++#define WLAN_OID_TIMEOUT_THRESHOLD 2000 /* OID timeout (in ms) */ ++#define WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING 300 /* OID timeout during chip-resetting (in ms) */ ++ ++#define WLAN_OID_NO_ACK_THRESHOLD 3 ++ ++#define WLAN_TX_THREAD_TASK_PRIORITY 0 /* If not setting the priority, 0 is the default */ ++#define WLAN_TX_THREAD_TASK_NICE (-10) /* If not setting the nice, -10 is the default */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC) (IN P_ADAPTER_T prAdapter, ++ IN PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); ++ ++typedef enum _ENUM_CSUM_TYPE_T { ++ CSUM_TYPE_IPV4, ++ CSUM_TYPE_IPV6, ++ CSUM_TYPE_TCP, ++ CSUM_TYPE_UDP, ++ CSUM_TYPE_NUM ++} ENUM_CSUM_TYPE_T, *P_ENUM_CSUM_TYPE_T; ++ ++typedef enum _ENUM_CSUM_RESULT_T { ++ CSUM_RES_NONE, ++ CSUM_RES_SUCCESS, ++ CSUM_RES_FAILED, ++ CSUM_RES_NUM ++} ENUM_CSUM_RESULT_T, *P_ENUM_CSUM_RESULT_T; ++ ++typedef enum _ENUM_PHY_MODE_T { ++ ENUM_PHY_2G4_CCK, ++ ENUM_PHY_2G4_OFDM_BPSK, ++ ENUM_PHY_2G4_OFDM_QPSK, ++ ENUM_PHY_2G4_OFDM_16QAM, ++ ENUM_PHY_2G4_OFDM_48M, ++ ENUM_PHY_2G4_OFDM_54M, ++ ENUM_PHY_2G4_HT20_BPSK, ++ ENUM_PHY_2G4_HT20_QPSK, ++ ENUM_PHY_2G4_HT20_16QAM, ++ ENUM_PHY_2G4_HT20_MCS5, ++ ENUM_PHY_2G4_HT20_MCS6, ++ ENUM_PHY_2G4_HT20_MCS7, ++ ENUM_PHY_2G4_HT40_BPSK, ++ ENUM_PHY_2G4_HT40_QPSK, ++ ENUM_PHY_2G4_HT40_16QAM, ++ ENUM_PHY_2G4_HT40_MCS5, ++ ENUM_PHY_2G4_HT40_MCS6, ++ ENUM_PHY_2G4_HT40_MCS7, ++ ENUM_PHY_5G_OFDM_BPSK, ++ ENUM_PHY_5G_OFDM_QPSK, ++ ENUM_PHY_5G_OFDM_16QAM, ++ ENUM_PHY_5G_OFDM_48M, ++ ENUM_PHY_5G_OFDM_54M, ++ ENUM_PHY_5G_HT20_BPSK, ++ ENUM_PHY_5G_HT20_QPSK, ++ ENUM_PHY_5G_HT20_16QAM, ++ ENUM_PHY_5G_HT20_MCS5, ++ ENUM_PHY_5G_HT20_MCS6, ++ ENUM_PHY_5G_HT20_MCS7, ++ ENUM_PHY_5G_HT40_BPSK, ++ ENUM_PHY_5G_HT40_QPSK, ++ ENUM_PHY_5G_HT40_16QAM, ++ ENUM_PHY_5G_HT40_MCS5, ++ ENUM_PHY_5G_HT40_MCS6, ++ ENUM_PHY_5G_HT40_MCS7, ++ ENUM_PHY_MODE_NUM ++} ENUM_PHY_MODE_T, *P_ENUM_PHY_MODE_T; ++ ++typedef enum _ENUM_POWER_SAVE_POLL_MODE_T { ++ ENUM_POWER_SAVE_POLL_DISABLE, ++ ENUM_POWER_SAVE_POLL_LEGACY_NULL, ++ ENUM_POWER_SAVE_POLL_QOS_NULL, ++ ENUM_POWER_SAVE_POLL_NUM ++} ENUM_POWER_SAVE_POLL_MODE_T, *P_ENUM_POWER_SAVE_POLL_MODE_T; ++ ++typedef enum _ENUM_AC_TYPE_T { ++ ENUM_AC_TYPE_AC0, ++ ENUM_AC_TYPE_AC1, ++ ENUM_AC_TYPE_AC2, ++ ENUM_AC_TYPE_AC3, ++ ENUM_AC_TYPE_AC4, ++ ENUM_AC_TYPE_AC5, ++ ENUM_AC_TYPE_AC6, ++ ENUM_AC_TYPE_BMC, ++ ENUM_AC_TYPE_NUM ++} ENUM_AC_TYPE_T, *P_ENUM_AC_TYPE_T; ++ ++typedef enum _ENUM_ADV_AC_TYPE_T { ++ ENUM_ADV_AC_TYPE_RX_NSW, ++ ENUM_ADV_AC_TYPE_RX_PTA, ++ ENUM_ADV_AC_TYPE_RX_SP, ++ ENUM_ADV_AC_TYPE_TX_PTA, ++ ENUM_ADV_AC_TYPE_TX_RSP, ++ ENUM_ADV_AC_TYPE_NUM ++} ENUM_ADV_AC_TYPE_T, *P_ENUM_ADV_AC_TYPE_T; ++ ++typedef enum _ENUM_REG_CH_MAP_T { ++ REG_CH_MAP_COUNTRY_CODE, ++ REG_CH_MAP_TBL_IDX, ++ REG_CH_MAP_CUSTOMIZED, ++ REG_CH_MAP_NUM ++} ENUM_REG_CH_MAP_T, *P_ENUM_REG_CH_MAP_T; ++ ++#define CHIP_CONFIG_RESP_SIZE 320 ++enum { ++ CHIP_CONFIG_TYPE_WO_RESPONSE = 0x00, ++ CHIP_CONFIG_TYPE_MEM8 = 0x01, ++ CHIP_CONFIG_TYPE_MEM32 = 0x02, ++ CHIP_CONFIG_TYPE_ASCII = 0x03, ++ CHIP_CONFIG_TYPE_BINARY = 0x04, ++ CHIP_CONFIG_TYPE_DRV_PASSTHROUGH = 0x05, ++ CHIP_CONFIG_TYPE_END ++}; ++ ++typedef struct _SET_TXPWR_CTRL_T { ++ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c2GHotspotPwrOffset; ++ INT_8 c2GP2pPwrOffset; ++ INT_8 c2GBowPwrOffset; ++ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c5GHotspotPwrOffset; ++ INT_8 c5GP2pPwrOffset; ++ INT_8 c5GBowPwrOffset; ++ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence ++ in the same channel ++ 0: Highest power has priority ++ 1: Lowest power has priority */ ++ INT_8 acReserved1[3]; /* Must be zero */ ++ ++ /* Power limit by channel for all data rates */ ++ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ ++ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ ++ INT_8 acReserved2[2]; /* Must be zero */ ++} SET_TXPWR_CTRL_T, *P_SET_TXPWR_CTRL_T; ++ ++/* For storing driver initialization value from glue layer */ ++typedef struct _REG_INFO_T { ++ UINT_32 u4SdBlockSize; /* SDIO block size */ ++ UINT_32 u4SdBusWidth; /* SDIO bus width. 1 or 4 */ ++ UINT_32 u4SdClockRate; /* SDIO clock rate. (in unit of HZ) */ ++ UINT_32 u4StartAddress; /* Starting address of Wi-Fi Firmware */ ++ UINT_32 u4LoadAddress; /* Load address of Wi-Fi Firmware */ ++ UINT_16 aucFwImgFilename[65]; /* Firmware filename */ ++ UINT_16 aucFwImgFilenameE6[65]; /* Firmware filename for E6 */ ++ UINT_32 u4StartFreq; /* Start Frequency for Ad-Hoc network : in unit of KHz */ ++ UINT_32 u4AdhocMode; /* Default mode for Ad-Hoc network : ENUM_PARAM_AD_HOC_MODE_T */ ++ UINT_32 u4RddStartFreq; ++ UINT_32 u4RddStopFreq; ++ UINT_32 u4RddTestMode; ++ UINT_32 u4RddShutFreq; ++ UINT_32 u4RddDfs; ++ INT_32 i4HighRssiThreshold; ++ INT_32 i4MediumRssiThreshold; ++ INT_32 i4LowRssiThreshold; ++ INT_32 au4TxPriorityTag[ENUM_AC_TYPE_NUM]; ++ INT_32 au4RxPriorityTag[ENUM_AC_TYPE_NUM]; ++ INT_32 au4AdvPriorityTag[ENUM_ADV_AC_TYPE_NUM]; ++ UINT_32 u4FastPSPoll; ++ UINT_32 u4PTA; /* 0: disable, 1: enable */ ++ UINT_32 u4TXLimit; /* 0: disable, 1: enable */ ++ UINT_32 u4SilenceWindow; /* range: 100 - 625, unit: us */ ++ UINT_32 u4TXLimitThreshold; /* range: 250 - 1250, unit: us */ ++ UINT_32 u4PowerMode; ++ UINT_32 fgEnArpFilter; ++ UINT_32 u4PsCurrentMeasureEn; ++ UINT_32 u4UapsdAcBmp; ++ UINT_32 u4MaxSpLen; ++ UINT_32 fgDisOnlineScan; /* 0: enable online scan, non-zero: disable online scan */ ++ UINT_32 fgDisBcnLostDetection; /* 0: enable online scan, non-zero: disable online scan */ ++ UINT_32 u4FixedRate; /* 0: automatic, non-zero: fixed rate */ ++ UINT_32 u4ArSysParam0; ++ UINT_32 u4ArSysParam1; ++ UINT_32 u4ArSysParam2; ++ UINT_32 u4ArSysParam3; ++ UINT_32 fgDisRoaming; /* 0:enable roaming 1:disable */ ++ ++ /* NVRAM - MP Data -START- */ ++ UINT_8 aucMacAddr[6]; ++ UINT_16 au2CountryCode[4]; /* Country code (in ISO 3166-1 expression, ex: "US", "TW") */ ++ TX_PWR_PARAM_T rTxPwr; ++ UINT_8 aucEFUSE[144]; ++ UINT_8 ucTxPwrValid; ++ UINT_8 ucSupport5GBand; ++ UINT_8 fg2G4BandEdgePwrUsed; ++ INT_8 cBandEdgeMaxPwrCCK; ++ INT_8 cBandEdgeMaxPwrOFDM20; ++ INT_8 cBandEdgeMaxPwrOFDM40; ++ ENUM_REG_CH_MAP_T eRegChannelListMap; ++ UINT_8 ucRegChannelListIndex; ++ DOMAIN_INFO_ENTRY rDomainInfo; ++ /* NVRAM - MP Data -END- */ ++ ++ /* NVRAM - Functional Data -START- */ ++ UINT_8 uc2G4BwFixed20M; ++ UINT_8 uc5GBwFixed20M; ++ UINT_8 ucEnable5GBand; ++ UINT_8 uc2GRssiCompensation; ++ UINT_8 uc5GRssiCompensation; ++ UINT_8 fgRssiCompensationValidbit; ++ UINT_8 ucRxAntennanumber; ++ /* NVRAM - Functional Data -END- */ ++ ++} REG_INFO_T, *P_REG_INFO_T; ++ ++/* for divided firmware loading */ ++typedef struct _FWDL_SECTION_INFO_T { ++ UINT_32 u4Offset; ++ UINT_32 u4Reserved; ++ UINT_32 u4Length; ++ UINT_32 u4DestAddr; ++} FWDL_SECTION_INFO_T, *P_FWDL_SECTION_INFO_T; ++ ++typedef struct _FIRMWARE_DIVIDED_DOWNLOAD_T { ++ UINT_32 u4Signature; ++ UINT_32 u4CRC; /* CRC calculated without first 8 bytes included */ ++ UINT_32 u4NumOfEntries; ++ UINT_32 u4Reserved; ++ FWDL_SECTION_INFO_T arSection[]; ++} FIRMWARE_DIVIDED_DOWNLOAD_T, *P_FIRMWARE_DIVIDED_DOWNLOAD_T; ++ ++typedef struct _PARAM_MCR_RW_STRUCT_T { ++ UINT_32 u4McrOffset; ++ UINT_32 u4McrData; ++} PARAM_MCR_RW_STRUCT_T, *P_PARAM_MCR_RW_STRUCT_T; ++ ++typedef struct _PARAM_GET_STA_STATISTICS { ++ UINT_8 ucInvalid; ++ UINT_8 ucVersion; ++ /* Per-STA statistic */ ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ UINT_32 u4LinkScore; ++ UINT_32 u4Flag; ++ ++ /* From FW */ ++ UINT_8 ucPer; /* base: 128 */ ++ UINT_8 ucRcpi; ++ UINT_32 u4PhyMode; ++ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ ++ ++ UINT_32 u4TxFailCount; ++ UINT_32 u4TxLifeTimeoutCount; ++ UINT_32 u4TxAverageAirTime; ++ ++ /* From driver */ ++ UINT_32 u4TxTotalCount; ++ UINT_32 u4TxExceedThresholdCount; ++ UINT_32 u4TxAverageProcessTime; ++ ++ UINT_32 u4TxMaxTime; ++ UINT_32 u4TxMaxHifTime; ++ UINT_32 u4TxAverageHifTime; ++ ++ /* ++ * How many packages Enqueue/Deqeue during statistics interval ++ */ ++ UINT_32 u4EnqueueCounter; ++ UINT_32 u4DequeueCounter; ++ ++ UINT_32 u4EnqueueStaCounter; ++ UINT_32 u4DequeueStaCounter; ++ ++ UINT_32 IsrCnt; ++ UINT_32 IsrPassCnt; ++ UINT_32 TaskIsrCnt; ++ ++ UINT_32 IsrAbnormalCnt; ++ UINT_32 IsrSoftWareCnt; ++ UINT_32 IsrRxCnt; ++ UINT_32 IsrTxCnt; ++ ++ UINT_32 au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4DequeueNoTcResource[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4TcResourceBackCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ ++ UINT_32 au4TcResourceUsedCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4TcResourceWantedCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ ++ UINT_32 au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; ++ /* Global queue management statistic */ ++ UINT_32 au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; ++ ++ /* Reserved fields */ ++ UINT_8 au4Reserved[32]; ++} PARAM_GET_STA_STA_STATISTICS, *P_PARAM_GET_STA_STATISTICS; ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR { ++ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, ++ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ ++ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, ++} ENUM_TESTMODE_AVAILABLE_CHAN_ATTR; ++ ++typedef struct _LTE_SAFE_CH_INFO_T { ++ UINT_32 au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1]; ++} LTE_SAFE_CH_INFO_T, *P_CMD_LTE_SAFE_CH_INFO_T; ++ ++ /* Record Each CH Load */ ++typedef struct _PARAM_CHN_LOAD_INFO { ++ /* Per-CHN Load */ ++ UINT_32 u4Flag; ++ ++ UINT_8 ucChannel; ++ UINT_16 u2ChannelLoad; ++ UINT_8 au4Reserved[1]; ++ ++ UINT_16 u2APNum; ++ UINT_16 u2APNumTmpCountingBuf; ++ ++ /* Reserved fields */ ++ UINT_8 au4Reserved1[8]; ++} PARAM_CHN_LOAD_INFO, *P_PARAM_CHN_LOAD_INFO; ++ ++typedef struct _PARAM_GET_CHN_LOAD { ++ LTE_SAFE_CH_INFO_T rLteSafeChnList; ++ PARAM_CHN_LOAD_INFO rEachChnLoad[MAX_AUTO_CHAL_NUM]; ++ BOOLEAN fgDataReadyBit; ++ UINT_8 au4Reserved1[3]; ++} PARAM_GET_CHN_LOAD, *P_PARAM_GET_CHN_LOAD; ++ ++typedef struct _PARAM_PREFER_CHN_INFO { ++ ++ UINT_8 ucChannel; ++ UINT_16 u2APNum; ++ UINT_8 au4Reserved1[1]; ++} PARAM_PREFER_CHN_INFO, *P_PARAM_PREFER_CHN_INFO; ++ ++typedef struct _PARAM_GET_LTE_MODE { ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ LTE_SAFE_CH_INFO_T LTE_MODE; ++ UINT_8 aucReserved4[3]; ++ ++ UINT_8 aucReserved[4]; ++ ++} PARAM_GET_LTE_MODE, *P_PARAM_GET_LTE_MODE; ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define BUILD_SIGN(ch0, ch1, ch2, ch3) \ ++ ((UINT_32)(UINT_8)(ch0) | ((UINT_32)(UINT_8)(ch1) << 8) | \ ++ ((UINT_32)(UINT_8)(ch2) << 16) | ((UINT_32)(UINT_8)(ch3) << 24)) ++ ++#define MTK_WIFI_SIGNATURE BUILD_SIGN('M', 'T', 'K', 'W') ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanCardEjected(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanIST(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl); ++ ++WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue); ++ ++WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData); ++ ++VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); ++ ++VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket); ++ ++VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData); ++ ++WLAN_STATUS ++wlanQueryInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfOidQryHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen); ++ ++WLAN_STATUS ++wlanSetInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfOidSetHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanAdapterStart(IN P_ADAPTER_T prAdapter, ++ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength); ++ ++WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter); ++ ++#if CFG_SUPPORT_WAPI ++BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter); ++#endif ++ ++VOID wlanReturnRxPacket(IN PVOID pvAdapter, IN PVOID pvPacket); ++ ++VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast); ++ ++BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); ++ ++VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++WLAN_STATUS ++wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); ++#endif ++ ++WLAN_STATUS ++wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); ++ ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter); ++#else ++WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum); ++#endif ++ ++WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress); ++ ++UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len); ++ ++#endif ++ ++WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode); ++ ++BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); ++ ++WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); ++ ++WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler); ++ ++VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter); ++ ++/* Security Frame Handling */ ++BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket); ++ ++VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID/IOCTL Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID); ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* Address Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* NIC Capability Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* NIC Capability Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Compiler Flags Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* PD MCR Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, IN P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo); ++/*----------------------------------------------------------------------------*/ ++/* Loading Manufacture Data */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Media Stream Mode */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Timer Timeout Check (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Check (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* TX Pending Packets Handling (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket); ++ ++WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess); ++ ++/*----------------------------------------------------------------------------*/ ++/* Low Power Acquire/Release (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Pending Packets Number Reporting (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* ACPI state inquiry (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState); ++ ++VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* get ECO version from Revision ID register (for Win32) */ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* set preferred band configuration corresponding to network type */ ++/*----------------------------------------------------------------------------*/ ++VOID ++wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* get currently operating channel information */ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* get BSS Descriptor information */ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* check for system configuration to generate message on scan list */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* query sta statistics information from driver and firmware */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]); ++ ++P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey); ++ ++WLAN_STATUS ++wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags); ++ ++UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef); ++ ++INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef); ++ ++WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value); ++ ++WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags); ++ ++WLAN_STATUS ++wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags); ++ ++#if CFG_SUPPORT_CFG_FILE ++WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags); ++ ++VOID wlanCfgApply(IN P_ADAPTER_T prAdapter); ++#endif /* CFG_SUPPORT_CFG_FILE */ ++ ++extern VOID mtk_wcn_wmt_set_wifi_ver(UINT_32 Value); ++ ++#endif /* _WLAN_LIB_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h +new file mode 100644 +index 000000000000..45919df996e9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h +@@ -0,0 +1,1715 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_oid.h#2 ++*/ ++ ++/*! \file "wlan_oid.h" ++ \brief This file contains the declairation file of the WLAN OID processing routines ++ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_oid.h ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Support UAPSD/OppPS/NoA parameter setting ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move timer callback to glue layer. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement Wakeup-on-LAN except firmware integration part ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. ++ * ++ ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add NULL OID implementation for WOL-related OIDs. ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support ++ * enable RX filter OID ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) implement timeout mechanism when OID is pending for longer than 1 second ++ * * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * * OID_802_11_RSSI, ++ * * * * OID_802_11_RSSI_TRIGGER, ++ * * * * OID_802_11_STATISTICS, ++ * * * * OID_802_11_DISASSOCIATE, ++ * * * * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-08 11:38:11 GMT mtk02752 ++** add declares for RF test related APIs ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-24 22:41:53 GMT mtk02752 ++** remove u4SysTime, MSDN 10-second will be implemented in FW side ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 20:30:13 GMT mtk02752 ++** add u4SysTime field in PARAM_BSSID_EX_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-12 19:48:35 GMT mtk02752 ++** allow upper layer to set a packet filter with PROMISCUOUS mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:12 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _WLAN_OID_H ++#define _WLAN_OID_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#if DBG ++extern UINT_8 aucDebugModule[DBG_MODULE_NUM]; ++extern UINT_32 u4DebugModule; ++UINT_32 u4DebugModuleTemp; ++#endif /* DBG */ ++extern int sprintf(char *buf, const char *fmt, ...); ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define PARAM_MAX_LEN_SSID 32 ++ ++#define PARAM_MAC_ADDR_LEN 6 ++ ++#define ETHERNET_HEADER_SZ 14 ++#define ETHERNET_MIN_PKT_SZ 60 ++#define ETHERNET_MAX_PKT_SZ 1514 ++ ++#define PARAM_MAX_LEN_RATES 8 ++#define PARAM_MAX_LEN_RATES_EX 16 ++ ++#define PARAM_AUTH_REQUEST_REAUTH 0x01 ++#define PARAM_AUTH_REQUEST_KEYUPDATE 0x02 ++#define PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 ++#define PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E ++ ++#define PARAM_EEPROM_READ_METHOD_READ 1 ++#define PARAM_EEPROM_READ_METHOD_GETSIZE 0 ++ ++#define PARAM_WHQL_RSSI_MAX_DBM (-10) ++#define PARAM_WHQL_RSSI_MIN_DBM (-200) ++ ++#define PARAM_DEVICE_WAKE_UP_ENABLE 0x00000001 ++#define PARAM_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 ++#define PARAM_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 ++ ++#define PARAM_WAKE_UP_MAGIC_PACKET 0x00000001 ++#define PARAM_WAKE_UP_PATTERN_MATCH 0x00000002 ++#define PARAM_WAKE_UP_LINK_CHANGE 0x00000004 ++ ++/* Packet filter bit definitioin (UINT_32 bit-wise definition) */ ++#define PARAM_PACKET_FILTER_DIRECTED 0x00000001 ++#define PARAM_PACKET_FILTER_MULTICAST 0x00000002 ++#define PARAM_PACKET_FILTER_ALL_MULTICAST 0x00000004 ++#define PARAM_PACKET_FILTER_BROADCAST 0x00000008 ++#define PARAM_PACKET_FILTER_PROMISCUOUS 0x00000020 ++#define PARAM_PACKET_FILTER_ALL_LOCAL 0x00000080 ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#define PARAM_PACKET_FILTER_P2P_MASK 0xC0000000 ++#define PARAM_PACKET_FILTER_PROBE_REQ 0x80000000 ++#define PARAM_PACKET_FILTER_ACTION_FRAME 0x40000000 ++#endif ++ ++#if CFG_SLT_SUPPORT ++#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ ++ PARAM_PACKET_FILTER_MULTICAST | \ ++ PARAM_PACKET_FILTER_BROADCAST | \ ++ PARAM_PACKET_FILTER_ALL_MULTICAST) ++#else ++#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ ++ PARAM_PACKET_FILTER_MULTICAST | \ ++ PARAM_PACKET_FILTER_BROADCAST) ++#endif ++ ++#define PARAM_MEM_DUMP_MAX_SIZE 2048 ++ ++#define BT_PROFILE_PARAM_LEN 8 ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Parameters of User Configuration which match to NDIS5.1 */ ++/*----------------------------------------------------------------------------*/ ++/* NDIS_802_11_AUTHENTICATION_MODE */ ++typedef enum _ENUM_PARAM_AUTH_MODE_T { ++ AUTH_MODE_OPEN, /*!< Open system */ ++ AUTH_MODE_SHARED, /*!< Shared key */ ++ AUTH_MODE_AUTO_SWITCH, /*!< Either open system or shared key */ ++ AUTH_MODE_WPA, ++ AUTH_MODE_WPA_PSK, ++ AUTH_MODE_WPA_NONE, /*!< For Ad hoc */ ++ AUTH_MODE_WPA2, ++ AUTH_MODE_WPA2_PSK, ++ AUTH_MODE_NUM /*!< Upper bound, not real case */ ++} ENUM_PARAM_AUTH_MODE_T, *P_ENUM_PARAM_AUTH_MODE_T; ++ ++/* NDIS_802_11_ENCRYPTION_STATUS *//* Encryption types */ ++typedef enum _ENUM_WEP_STATUS_T { ++ ENUM_WEP_ENABLED, ++ ENUM_ENCRYPTION1_ENABLED = ENUM_WEP_ENABLED, ++ ENUM_WEP_DISABLED, ++ ENUM_ENCRYPTION_DISABLED = ENUM_WEP_DISABLED, ++ ENUM_WEP_KEY_ABSENT, ++ ENUM_ENCRYPTION1_KEY_ABSENT = ENUM_WEP_KEY_ABSENT, ++ ENUM_WEP_NOT_SUPPORTED, ++ ENUM_ENCRYPTION_NOT_SUPPORTED = ENUM_WEP_NOT_SUPPORTED, ++ ENUM_ENCRYPTION2_ENABLED, ++ ENUM_ENCRYPTION2_KEY_ABSENT, ++ ENUM_ENCRYPTION3_ENABLED, ++ ENUM_ENCRYPTION3_KEY_ABSENT ++} ENUM_PARAM_ENCRYPTION_STATUS_T, *P_ENUM_PARAM_ENCRYPTION_STATUS_T; ++ ++typedef UINT_8 PARAM_MAC_ADDRESS[PARAM_MAC_ADDR_LEN]; ++ ++typedef UINT_32 PARAM_KEY_INDEX; ++typedef UINT_64 PARAM_KEY_RSC; ++typedef INT_32 PARAM_RSSI; ++ ++typedef UINT_32 PARAM_FRAGMENTATION_THRESHOLD; ++typedef UINT_32 PARAM_RTS_THRESHOLD; ++ ++typedef UINT_8 PARAM_RATES[PARAM_MAX_LEN_RATES]; ++typedef UINT_8 PARAM_RATES_EX[PARAM_MAX_LEN_RATES_EX]; ++ ++typedef enum _ENUM_PARAM_PHY_TYPE_T { ++ PHY_TYPE_802_11ABG = 0, /*!< Can associated with 802.11abg AP, ++ Scan dual band. */ ++ PHY_TYPE_802_11BG, /*!< Can associated with 802_11bg AP, ++ Scan single band and not report 802_11a BSSs. */ ++ PHY_TYPE_802_11G, /*!< Can associated with 802_11g only AP, ++ Scan single band and not report 802_11ab BSSs. */ ++ PHY_TYPE_802_11A, /*!< Can associated with 802_11a only AP, ++ Scan single band and not report 802_11bg BSSs. */ ++ PHY_TYPE_802_11B, /*!< Can associated with 802_11b only AP, ++ Scan single band and not report 802_11ag BSSs. */ ++ PHY_TYPE_NUM /* 5 */ ++} ENUM_PARAM_PHY_TYPE_T, *P_ENUM_PARAM_PHY_TYPE_T; ++ ++typedef enum _ENUM_PARAM_OP_MODE_T { ++ NET_TYPE_IBSS = 0, /*!< Try to merge/establish an AdHoc, do periodic SCAN for merging. */ ++ NET_TYPE_INFRA, /*!< Try to join an Infrastructure, do periodic SCAN for joining. */ ++ NET_TYPE_AUTO_SWITCH, /*!< Try to join an Infrastructure, if fail then try to merge or ++ establish an AdHoc, do periodic SCAN for joining or merging. */ ++ NET_TYPE_DEDICATED_IBSS, /*!< Try to merge an AdHoc first, ++ if fail then establish AdHoc permanently, no more SCAN. */ ++ NET_TYPE_NUM /* 4 */ ++} ENUM_PARAM_OP_MODE_T, *P_ENUM_PARAM_OP_MODE_T; ++ ++typedef struct _PARAM_SSID_T { ++ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ ++ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; ++ UINT_32 u4CenterFreq; ++} PARAM_SSID_T, *P_PARAM_SSID_T; ++ ++typedef struct _PARAM_CONNECT_T { ++ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ ++ UINT_8 *pucSsid; ++ UINT_8 *pucBssid; ++ UINT_32 u4CenterFreq; ++} PARAM_CONNECT_T, *P_PARAM_CONNECT_T; ++ ++/* This is enum defined for user to select an AdHoc Mode */ ++typedef enum _ENUM_PARAM_AD_HOC_MODE_T { ++ AD_HOC_MODE_11B = 0, /*!< Create 11b IBSS if we support 802.11abg/802.11bg. */ ++ AD_HOC_MODE_MIXED_11BG, /*!< Create 11bg mixed IBSS if we support 802.11abg/802.11bg/802.11g. */ ++ AD_HOC_MODE_11G, /*!< Create 11g only IBSS if we support 802.11abg/802.11bg/802.11g. */ ++ AD_HOC_MODE_11A, /*!< Create 11a only IBSS if we support 802.11abg. */ ++ AD_HOC_MODE_NUM /* 4 */ ++} ENUM_PARAM_AD_HOC_MODE_T, *P_ENUM_PARAM_AD_HOC_MODE_T; ++ ++typedef enum _ENUM_PARAM_MEDIA_STATE_T { ++ PARAM_MEDIA_STATE_CONNECTED, ++ PARAM_MEDIA_STATE_DISCONNECTED, ++ PARAM_MEDIA_STATE_TO_BE_INDICATED /* for following MSDN re-association behavior */ ++} ENUM_PARAM_MEDIA_STATE_T, *P_ENUM_PARAM_MEDIA_STATE_T; ++ ++typedef enum _ENUM_PARAM_NETWORK_TYPE_T { ++ PARAM_NETWORK_TYPE_FH, ++ PARAM_NETWORK_TYPE_DS, ++ PARAM_NETWORK_TYPE_OFDM5, ++ PARAM_NETWORK_TYPE_OFDM24, ++ PARAM_NETWORK_TYPE_AUTOMODE, ++ PARAM_NETWORK_TYPE_NUM /*!< Upper bound, not real case */ ++} ENUM_PARAM_NETWORK_TYPE_T, *P_ENUM_PARAM_NETWORK_TYPE_T; ++ ++typedef struct _PARAM_NETWORK_TYPE_LIST { ++ UINT_32 NumberOfItems; /*!< At least 1 */ ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkType[1]; ++} PARAM_NETWORK_TYPE_LIST, *PPARAM_NETWORK_TYPE_LIST; ++ ++typedef enum _ENUM_PARAM_PRIVACY_FILTER_T { ++ PRIVACY_FILTER_ACCEPT_ALL, ++ PRIVACY_FILTER_8021xWEP, ++ PRIVACY_FILTER_NUM ++} ENUM_PARAM_PRIVACY_FILTER_T, *P_ENUM_PARAM_PRIVACY_FILTER_T; ++ ++typedef enum _ENUM_RELOAD_DEFAULTS { ++ ENUM_RELOAD_WEP_KEYS ++} PARAM_RELOAD_DEFAULTS, *P_PARAM_RELOAD_DEFAULTS; ++ ++typedef struct _PARAM_PM_PACKET_PATTERN { ++ UINT_32 Priority; /* Importance of the given pattern. */ ++ UINT_32 Reserved; /* Context information for transports. */ ++ UINT_32 MaskSize; /* Size in bytes of the pattern mask. */ ++ UINT_32 PatternOffset; /* Offset from beginning of this */ ++ /* structure to the pattern bytes. */ ++ UINT_32 PatternSize; /* Size in bytes of the pattern. */ ++ UINT_32 PatternFlags; /* Flags (TBD). */ ++} PARAM_PM_PACKET_PATTERN, *P_PARAM_PM_PACKET_PATTERN; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief Struct definition to indicate specific event. */ ++/*--------------------------------------------------------------*/ ++typedef enum _ENUM_STATUS_TYPE_T { ++ ENUM_STATUS_TYPE_AUTHENTICATION, ++ ENUM_STATUS_TYPE_MEDIA_STREAM_MODE, ++ ENUM_STATUS_TYPE_CANDIDATE_LIST, ++ ENUM_STATUS_TYPE_NUM /*!< Upper bound, not real case */ ++} ENUM_STATUS_TYPE_T, *P_ENUM_STATUS_TYPE_T; ++ ++typedef struct _PARAM_802_11_CONFIG_FH_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4HopPattern; /*!< Defined as 802.11 */ ++ UINT_32 u4HopSet; /*!< to one if non-802.11 */ ++ UINT_32 u4DwellTime; /*!< In unit of Kusec */ ++} PARAM_802_11_CONFIG_FH_T, *P_PARAM_802_11_CONFIG_FH_T; ++ ++typedef struct _PARAM_802_11_CONFIG_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4BeaconPeriod; /*!< In unit of Kusec */ ++ UINT_32 u4ATIMWindow; /*!< In unit of Kusec */ ++ UINT_32 u4DSConfig; /*!< Channel frequency in unit of kHz */ ++ PARAM_802_11_CONFIG_FH_T rFHConfig; ++} PARAM_802_11_CONFIG_T, *P_PARAM_802_11_CONFIG_T; ++ ++typedef struct _PARAM_STATUS_INDICATION_T { ++ ENUM_STATUS_TYPE_T eStatusType; ++} PARAM_STATUS_INDICATION_T, *P_PARAM_STATUS_INDICATION_T; ++ ++typedef struct _PARAM_AUTH_REQUEST_T { ++ UINT_32 u4Length; /*!< Length of this struct */ ++ PARAM_MAC_ADDRESS arBssid; ++ UINT_32 u4Flags; /*!< Definitions are as follows */ ++} PARAM_AUTH_REQUEST_T, *P_PARAM_AUTH_REQUEST_T; ++ ++typedef struct _PARAM_AUTH_EVENT_T { ++ PARAM_STATUS_INDICATION_T rStatus; ++ PARAM_AUTH_REQUEST_T arRequest[1]; ++} PARAM_AUTH_EVENT_T, *P_PARAM_AUTH_EVENT_T; ++ ++/*! \brief Capabilities, privacy, rssi and IEs of each BSSID */ ++typedef struct _PARAM_BSSID_EX_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ PARAM_MAC_ADDRESS arMacAddress; /*!< BSSID */ ++ UINT_8 Reserved[2]; ++ PARAM_SSID_T rSsid; /*!< SSID */ ++ UINT_32 u4Privacy; /*!< Need WEP encryption */ ++ PARAM_RSSI rRssi; /*!< in dBm */ ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkTypeInUse; ++ PARAM_802_11_CONFIG_T rConfiguration; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ PARAM_RATES_EX rSupportedRates; ++ UINT_32 u4IELength; ++ UINT_8 aucIEs[1]; ++} PARAM_BSSID_EX_T, *P_PARAM_BSSID_EX_T; ++ ++typedef struct _PARAM_BSSID_LIST_EX { ++ UINT_32 u4NumberOfItems; /*!< at least 1 */ ++ PARAM_BSSID_EX_T arBssid[1]; ++} PARAM_BSSID_LIST_EX_T, *P_PARAM_BSSID_LIST_EX_T; ++ ++typedef struct _PARAM_WEP_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< 0: pairwise key, others group keys */ ++ UINT_32 u4KeyLength; /*!< Key length in bytes */ ++ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ ++} PARAM_WEP_T, *P_PARAM_WEP_T; ++ ++/*! \brief Key mapping of BSSID */ ++typedef struct _PARAM_KEY_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< KeyID */ ++ UINT_32 u4KeyLength; /*!< Key length in bytes */ ++ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ ++ PARAM_KEY_RSC rKeyRSC; ++ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ ++} PARAM_KEY_T, *P_PARAM_KEY_T; ++ ++typedef struct _PARAM_REMOVE_KEY_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< KeyID */ ++ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ ++} PARAM_REMOVE_KEY_T, *P_PARAM_REMOVE_KEY_T; ++ ++#if CFG_SUPPORT_WAPI ++typedef enum _ENUM_KEY_TYPE { ++ ENUM_WPI_PAIRWISE_KEY = 0, ++ ENUM_WPI_GROUP_KEY ++} ENUM_KEY_TYPE; ++ ++typedef enum _ENUM_WPI_PROTECT_TYPE { ++ ENUM_WPI_NONE, ++ ENUM_WPI_RX, ++ ENUM_WPI_TX, ++ ENUM_WPI_RX_TX ++} ENUM_WPI_PROTECT_TYPE; ++ ++typedef struct _PARAM_WPI_KEY_T { ++ ENUM_KEY_TYPE eKeyType; ++ ENUM_WPI_PROTECT_TYPE eDirection; ++ UINT_8 ucKeyID; ++ UINT_8 aucRsv[3]; ++ UINT_8 aucAddrIndex[12]; ++ UINT_32 u4LenWPIEK; ++ UINT_8 aucWPIEK[256]; ++ UINT_32 u4LenWPICK; ++ UINT_8 aucWPICK[256]; ++ UINT_8 aucPN[16]; ++} PARAM_WPI_KEY_T, *P_PARAM_WPI_KEY_T; ++#endif ++ ++typedef enum _PARAM_POWER_MODE { ++ Param_PowerModeCAM, ++ Param_PowerModeMAX_PSP, ++ Param_PowerModeFast_PSP, ++#if CFG_SUPPORT_DBG_POWERMODE ++ Param_PowerModeKeepActiveOn, /* privilege mode, always active */ ++ Param_PowerModeKeepActiveOff, /* to leave privilege mode */ ++#endif ++ Param_PowerModeMax /* Upper bound, not real case */ ++} PARAM_POWER_MODE, *PPARAM_POWER_MODE; ++ ++typedef enum _PARAM_DEVICE_POWER_STATE { ++ ParamDeviceStateUnspecified = 0, ++ ParamDeviceStateD0, ++ ParamDeviceStateD1, ++ ParamDeviceStateD2, ++ ParamDeviceStateD3, ++ ParamDeviceStateMaximum ++} PARAM_DEVICE_POWER_STATE, *PPARAM_DEVICE_POWER_STATE; ++ ++#if CFG_SUPPORT_802_11D ++ ++/*! \brief The enumeration definitions for OID_IPN_MULTI_DOMAIN_CAPABILITY */ ++typedef enum _PARAM_MULTI_DOMAIN_CAPABILITY { ++ ParamMultiDomainCapDisabled, ++ ParamMultiDomainCapEnabled ++} PARAM_MULTI_DOMAIN_CAPABILITY, *P_PARAM_MULTI_DOMAIN_CAPABILITY; ++#endif ++ ++typedef struct _COUNTRY_STRING_ENTRY { ++ UINT_8 aucCountryCode[2]; ++ UINT_8 aucEnvironmentCode[2]; ++} COUNTRY_STRING_ENTRY, *P_COUNTRY_STRING_ENTRY; ++ ++/* Power management related definition and enumerations */ ++#define UAPSD_NONE 0 ++#define UAPSD_AC0 (BIT(0) | BIT(4)) ++#define UAPSD_AC1 (BIT(1) | BIT(5)) ++#define UAPSD_AC2 (BIT(2) | BIT(6)) ++#define UAPSD_AC3 (BIT(3) | BIT(7)) ++#define UAPSD_ALL (UAPSD_AC0 | UAPSD_AC1 | UAPSD_AC2 | UAPSD_AC3) ++ ++typedef enum _ENUM_POWER_SAVE_PROFILE_T { ++ ENUM_PSP_CONTINUOUS_ACTIVE = 0, ++ ENUM_PSP_CONTINUOUS_POWER_SAVE, ++ ENUM_PSP_FAST_SWITCH, ++ ENUM_PSP_NUM ++} ENUM_POWER_SAVE_PROFILE_T, *PENUM_POWER_SAVE_PROFILE_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief Set/Query testing type. */ ++/*--------------------------------------------------------------*/ ++typedef struct _PARAM_802_11_TEST_T { ++ UINT_32 u4Length; ++ UINT_32 u4Type; ++ union { ++ PARAM_AUTH_EVENT_T AuthenticationEvent; ++ PARAM_RSSI RssiTrigger; ++ } u; ++} PARAM_802_11_TEST_T, *P_PARAM_802_11_TEST_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief Set/Query authentication and encryption capability. */ ++/*--------------------------------------------------------------*/ ++typedef struct _PARAM_AUTH_ENCRYPTION_T { ++ ENUM_PARAM_AUTH_MODE_T eAuthModeSupported; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncryptStatusSupported; ++} PARAM_AUTH_ENCRYPTION_T, *P_PARAM_AUTH_ENCRYPTION_T; ++ ++typedef struct _PARAM_CAPABILITY_T { ++ UINT_32 u4Length; ++ UINT_32 u4Version; ++ UINT_32 u4NoOfPMKIDs; ++ UINT_32 u4NoOfAuthEncryptPairsSupported; ++ PARAM_AUTH_ENCRYPTION_T arAuthenticationEncryptionSupported[1]; ++} PARAM_CAPABILITY_T, *P_PARAM_CAPABILITY_T; ++ ++typedef UINT_8 PARAM_PMKID_VALUE[16]; ++ ++typedef struct _PARAM_BSSID_INFO_T { ++ PARAM_MAC_ADDRESS arBSSID; ++ PARAM_PMKID_VALUE arPMKID; ++} PARAM_BSSID_INFO_T, *P_PARAM_BSSID_INFO_T; ++ ++typedef struct _PARAM_PMKID_T { ++ UINT_32 u4Length; ++ UINT_32 u4BSSIDInfoCount; ++ PARAM_BSSID_INFO_T arBSSIDInfo[1]; ++} PARAM_PMKID_T, *P_PARAM_PMKID_T; ++ ++/*! \brief PMKID candidate lists. */ ++typedef struct _PARAM_PMKID_CANDIDATE_T { ++ PARAM_MAC_ADDRESS arBSSID; ++ UINT_32 u4Flags; ++} PARAM_PMKID_CANDIDATE_T, *P_PARAM_PMKID_CANDIDATE_T; ++ ++/* #ifdef LINUX */ ++typedef struct _PARAM_PMKID_CANDIDATE_LIST_T { ++ UINT_32 u4Version; /*!< Version */ ++ UINT_32 u4NumCandidates; /*!< How many candidates follow */ ++ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; ++} PARAM_PMKID_CANDIDATE_LIST_T, *P_PARAM_PMKID_CANDIDATE_LIST_T; ++/* #endif */ ++ ++typedef struct _PARAM_CUSTOM_MCR_RW_STRUCT_T { ++ UINT_32 u4McrOffset; ++ UINT_32 u4McrData; ++} PARAM_CUSTOM_MCR_RW_STRUCT_T, *P_PARAM_CUSTOM_MCR_RW_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_MEM_DUMP_STRUCT_T { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4RemainLength; ++ UINT_8 ucFragNum; ++} PARAM_CUSTOM_MEM_DUMP_STRUCT_T, *P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_SW_CTRL_STRUCT_T { ++ UINT_32 u4Id; ++ UINT_32 u4Data; ++} PARAM_CUSTOM_SW_CTRL_STRUCT_T, *P_PARAM_CUSTOM_SW_CTRL_STRUCT_T; ++ ++typedef struct _CMD_CHIP_CONFIG_T { ++ UINT_16 u2Id; ++ UINT_8 ucType; ++ UINT_8 ucRespType; ++ UINT_16 u2MsgSize; ++ UINT_8 aucReserved0[2]; ++ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; ++} CMD_CHIP_CONFIG_T, *P_CMD_CHIP_CONFIG_T; ++ ++typedef struct _PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T { ++ UINT_16 u2Id; ++ UINT_8 ucType; ++ UINT_8 ucRespType; ++ UINT_16 u2MsgSize; ++ UINT_8 aucReserved0[2]; ++ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; ++} PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T, *P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_KEY_CFG_STRUCT_T { ++ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; ++ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++} PARAM_CUSTOM_KEY_CFG_STRUCT_T, *P_PARAM_CUSTOM_KEY_CFG_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_EEPROM_RW_STRUCT_T { ++ UINT_8 ucEepromMethod; /* For read only read: 1, query size: 0 */ ++ UINT_8 ucEepromIndex; ++ UINT_8 reserved; ++ UINT_16 u2EepromData; ++} PARAM_CUSTOM_EEPROM_RW_STRUCT_T, *P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T, ++PARAM_CUSTOM_NVRAM_RW_STRUCT_T, *P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T { ++ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ ++ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ ++ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ ++ UINT_8 reserved; ++} PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T, *P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_NOA_PARAM_STRUCT_T { ++ UINT_32 u4NoaDurationMs; ++ UINT_32 u4NoaIntervalMs; ++ UINT_32 u4NoaCount; ++} PARAM_CUSTOM_NOA_PARAM_STRUCT_T, *P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T { ++ UINT_32 u4CTwindowMs; ++} PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T { ++ UINT_8 fgEnAPSD; ++ UINT_8 fgEnAPSD_AcBe; ++ UINT_8 fgEnAPSD_AcBk; ++ UINT_8 fgEnAPSD_AcVo; ++ UINT_8 fgEnAPSD_AcVi; ++ UINT_8 ucMaxSpLen; ++ UINT_8 aucResv[2]; ++} PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { ++ UINT_32 u4Enable; ++ UINT_32 u4Mode; ++} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; ++ ++typedef enum _ENUM_CFG_SRC_TYPE_T { ++ CFG_SRC_TYPE_EEPROM, ++ CFG_SRC_TYPE_NVRAM, ++ CFG_SRC_TYPE_UNKNOWN, ++ CFG_SRC_TYPE_NUM ++} ENUM_CFG_SRC_TYPE_T, *P_ENUM_CFG_SRC_TYPE_T; ++ ++typedef enum _ENUM_EEPROM_TYPE_T { ++ EEPROM_TYPE_NO, ++ EEPROM_TYPE_PRESENT, ++ EEPROM_TYPE_NUM ++} ENUM_EEPROM_TYPE_T, *P_ENUM_EEPROM_TYPE_T; ++ ++typedef struct _PARAM_QOS_TSINFO { ++ UINT_8 ucTrafficType; /* Traffic Type: 1 for isochronous 0 for asynchronous */ ++ UINT_8 ucTid; /* TSID: must be between 8 ~ 15 */ ++ UINT_8 ucDirection; /* direction */ ++ UINT_8 ucAccessPolicy; /* access policy */ ++ UINT_8 ucAggregation; /* aggregation */ ++ UINT_8 ucApsd; /* APSD */ ++ UINT_8 ucuserPriority; /* user priority */ ++ UINT_8 ucTsInfoAckPolicy; /* TSINFO ACK policy */ ++ UINT_8 ucSchedule; /* Schedule */ ++} PARAM_QOS_TSINFO, *P_PARAM_QOS_TSINFO; ++ ++typedef struct _PARAM_QOS_TSPEC { ++ PARAM_QOS_TSINFO rTsInfo; /* TS info field */ ++ UINT_16 u2NominalMSDUSize; /* nominal MSDU size */ ++ UINT_16 u2MaxMSDUsize; /* maximum MSDU size */ ++ UINT_32 u4MinSvcIntv; /* minimum service interval */ ++ UINT_32 u4MaxSvcIntv; /* maximum service interval */ ++ UINT_32 u4InactIntv; /* inactivity interval */ ++ UINT_32 u4SpsIntv; /* suspension interval */ ++ UINT_32 u4SvcStartTime; /* service start time */ ++ UINT_32 u4MinDataRate; /* minimum Data rate */ ++ UINT_32 u4MeanDataRate; /* mean data rate */ ++ UINT_32 u4PeakDataRate; /* peak data rate */ ++ UINT_32 u4MaxBurstSize; /* maximum burst size */ ++ UINT_32 u4DelayBound; /* delay bound */ ++ UINT_32 u4MinPHYRate; /* minimum PHY rate */ ++ UINT_16 u2Sba; /* surplus bandwidth allowance */ ++ UINT_16 u2MediumTime; /* medium time */ ++} PARAM_QOS_TSPEC, *P_PARAM_QOS_TSPEC; ++ ++typedef struct _PARAM_QOS_ADDTS_REQ_INFO { ++ PARAM_QOS_TSPEC rTspec; ++} PARAM_QOS_ADDTS_REQ_INFO, *P_PARAM_QOS_ADDTS_REQ_INFO; ++ ++typedef struct _PARAM_VOIP_CONFIG { ++ UINT_32 u4VoipTrafficInterval; /* 0: disable VOIP configuration */ ++} PARAM_VOIP_CONFIG, *P_PARAM_VOIP_CONFIG; ++ ++/*802.11 Statistics Struct*/ ++typedef struct _PARAM_802_11_STATISTICS_STRUCT_T { ++ UINT_32 u4Length; /* Length of structure */ ++ LARGE_INTEGER rTransmittedFragmentCount; ++ LARGE_INTEGER rMulticastTransmittedFrameCount; ++ LARGE_INTEGER rFailedCount; ++ LARGE_INTEGER rRetryCount; ++ LARGE_INTEGER rMultipleRetryCount; ++ LARGE_INTEGER rRTSSuccessCount; ++ LARGE_INTEGER rRTSFailureCount; ++ LARGE_INTEGER rACKFailureCount; ++ LARGE_INTEGER rFrameDuplicateCount; ++ LARGE_INTEGER rReceivedFragmentCount; ++ LARGE_INTEGER rMulticastReceivedFrameCount; ++ LARGE_INTEGER rFCSErrorCount; ++ LARGE_INTEGER rTKIPLocalMICFailures; ++ LARGE_INTEGER rTKIPICVErrors; ++ LARGE_INTEGER rTKIPCounterMeasuresInvoked; ++ LARGE_INTEGER rTKIPReplays; ++ LARGE_INTEGER rCCMPFormatErrors; ++ LARGE_INTEGER rCCMPReplays; ++ LARGE_INTEGER rCCMPDecryptErrors; ++ LARGE_INTEGER rFourWayHandshakeFailures; ++ LARGE_INTEGER rWEPUndecryptableCount; ++ LARGE_INTEGER rWEPICVErrorCount; ++ LARGE_INTEGER rDecryptSuccessCount; ++ LARGE_INTEGER rDecryptFailureCount; ++} PARAM_802_11_STATISTICS_STRUCT_T, *P_PARAM_802_11_STATISTICS_STRUCT_T; ++ ++/* Linux Network Device Statistics Struct */ ++typedef struct _PARAM_LINUX_NETDEV_STATISTICS_T { ++ UINT_32 u4RxPackets; ++ UINT_32 u4TxPackets; ++ UINT_32 u4RxBytes; ++ UINT_32 u4TxBytes; ++ UINT_32 u4RxErrors; ++ UINT_32 u4TxErrors; ++ UINT_32 u4Multicast; ++} PARAM_LINUX_NETDEV_STATISTICS_T, *P_PARAM_LINUX_NETDEV_STATISTICS_T; ++ ++typedef struct _PARAM_MTK_WIFI_TEST_STRUCT_T { ++ UINT_32 u4FuncIndex; ++ UINT_32 u4FuncData; ++} PARAM_MTK_WIFI_TEST_STRUCT_T, *P_PARAM_MTK_WIFI_TEST_STRUCT_T; ++ ++/* 802.11 Media stream constraints */ ++typedef enum _ENUM_MEDIA_STREAM_MODE { ++ ENUM_MEDIA_STREAM_OFF, ++ ENUM_MEDIA_STREAM_ON ++} ENUM_MEDIA_STREAM_MODE, *P_ENUM_MEDIA_STREAM_MODE; ++ ++/* for NDIS 5.1 Media Streaming Change */ ++typedef struct _PARAM_MEDIA_STREAMING_INDICATION { ++ PARAM_STATUS_INDICATION_T rStatus; ++ ENUM_MEDIA_STREAM_MODE eMediaStreamMode; ++} PARAM_MEDIA_STREAMING_INDICATION, *P_PARAM_MEDIA_STREAMING_INDICATION; ++ ++#define PARAM_PROTOCOL_ID_DEFAULT 0x00 ++#define PARAM_PROTOCOL_ID_TCP_IP 0x02 ++#define PARAM_PROTOCOL_ID_IPX 0x06 ++#define PARAM_PROTOCOL_ID_NBF 0x07 ++#define PARAM_PROTOCOL_ID_MAX 0x0F ++#define PARAM_PROTOCOL_ID_MASK 0x0F ++ ++/* for NDIS OID_GEN_NETWORK_LAYER_ADDRESSES */ ++typedef struct _PARAM_NETWORK_ADDRESS_IP { ++ UINT_16 sin_port; ++ UINT_32 in_addr; ++ UINT_8 sin_zero[8]; ++} PARAM_NETWORK_ADDRESS_IP, *P_PARAM_NETWORK_ADDRESS_IP; ++ ++typedef struct _PARAM_NETWORK_ADDRESS { ++ UINT_16 u2AddressLength; /* length in bytes of Address[] in this */ ++ UINT_16 u2AddressType; /* type of this address (PARAM_PROTOCOL_ID_XXX above) */ ++ UINT_8 aucAddress[1]; /* actually AddressLength bytes long */ ++} PARAM_NETWORK_ADDRESS, *P_PARAM_NETWORK_ADDRESS; ++ ++/* The following is used with OID_GEN_NETWORK_LAYER_ADDRESSES to set network layer addresses on an interface */ ++ ++typedef struct _PARAM_NETWORK_ADDRESS_LIST { ++ UINT_32 u4AddressCount; /* number of addresses following */ ++ UINT_16 u2AddressType; /* type of this address (NDIS_PROTOCOL_ID_XXX above) */ ++ PARAM_NETWORK_ADDRESS arAddress[1]; /* actually AddressCount elements long */ ++} PARAM_NETWORK_ADDRESS_LIST, *P_PARAM_NETWORK_ADDRESS_LIST; ++ ++#if CFG_SLT_SUPPORT ++ ++#define FIXED_BW_LG20 0x0000 ++#define FIXED_BW_UL20 0x2000 ++#define FIXED_BW_DL40 0x3000 ++ ++#define FIXED_EXT_CHNL_U20 0x4000 /* For AGG register. */ ++#define FIXED_EXT_CHNL_L20 0xC000 /* For AGG regsiter. */ ++ ++typedef enum _ENUM_MTK_LP_TEST_MODE_T { ++ ENUM_MTK_LP_TEST_NORMAL, ++ ENUM_MTK_LP_TEST_GOLDEN_SAMPLE, ++ ENUM_MTK_LP_TEST_DUT, ++ ENUM_MTK_LP_TEST_MODE_NUM ++} ENUM_MTK_LP_TEST_MODE_T, *P_ENUM_MTK_LP_TEST_MODE_T; ++ ++typedef enum _ENUM_MTK_SLT_FUNC_IDX_T { ++ ENUM_MTK_SLT_FUNC_DO_NOTHING, ++ ENUM_MTK_SLT_FUNC_INITIAL, ++ ENUM_MTK_SLT_FUNC_RATE_SET, ++ ENUM_MTK_SLT_FUNC_LP_SET, ++ ENUM_MTK_SLT_FUNC_NUM ++} ENUM_MTK_SLT_FUNC_IDX_T, *P_ENUM_MTK_SLT_FUNC_IDX_T; ++ ++typedef struct _PARAM_MTK_SLT_LP_TEST_STRUCT_T { ++ ENUM_MTK_LP_TEST_MODE_T rLpTestMode; ++ UINT_32 u4BcnRcvNum; ++} PARAM_MTK_SLT_LP_TEST_STRUCT_T, *P_PARAM_MTK_SLT_LP_TEST_STRUCT_T; ++ ++typedef struct _PARAM_MTK_SLT_TR_TEST_STRUCT_T { ++ ENUM_PARAM_NETWORK_TYPE_T rNetworkType; /* Network Type OFDM5G or OFDM2.4G */ ++ UINT_32 u4FixedRate; /* Fixed Rate including BW */ ++} PARAM_MTK_SLT_TR_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TR_TEST_STRUCT_T; ++ ++typedef struct _PARAM_MTK_SLT_INITIAL_STRUCT_T { ++ UINT_8 aucTargetMacAddr[PARAM_MAC_ADDR_LEN]; ++ UINT_16 u2SiteID; ++} PARAM_MTK_SLT_INITIAL_STRUCT_T, *P_PARAM_MTK_SLT_INITIAL_STRUCT_T; ++ ++typedef struct _PARAM_MTK_SLT_TEST_STRUCT_T { ++ ENUM_MTK_SLT_FUNC_IDX_T rSltFuncIdx; ++ UINT_32 u4Length; /* Length of structure, ++ including myself */ ++ UINT_32 u4FuncInfoLen; /* Include following content ++ field and myself */ ++ union { ++ PARAM_MTK_SLT_INITIAL_STRUCT_T rMtkInitTest; ++ PARAM_MTK_SLT_LP_TEST_STRUCT_T rMtkLpTest; ++ PARAM_MTK_SLT_TR_TEST_STRUCT_T rMtkTRTest; ++ } unFuncInfoContent; ++ ++} PARAM_MTK_SLT_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TEST_STRUCT_T; ++ ++#endif ++ ++/*--------------------------------------------------------------*/ ++/*! \brief For Fixed Rate Configuration (Registry) */ ++/*--------------------------------------------------------------*/ ++typedef enum _ENUM_REGISTRY_FIXED_RATE_T { ++ FIXED_RATE_NONE, ++ FIXED_RATE_1M, ++ FIXED_RATE_2M, ++ FIXED_RATE_5_5M, ++ FIXED_RATE_11M, ++ FIXED_RATE_6M, ++ FIXED_RATE_9M, ++ FIXED_RATE_12M, ++ FIXED_RATE_18M, ++ FIXED_RATE_24M, ++ FIXED_RATE_36M, ++ FIXED_RATE_48M, ++ FIXED_RATE_54M, ++ FIXED_RATE_MCS0_20M_800NS, ++ FIXED_RATE_MCS1_20M_800NS, ++ FIXED_RATE_MCS2_20M_800NS, ++ FIXED_RATE_MCS3_20M_800NS, ++ FIXED_RATE_MCS4_20M_800NS, ++ FIXED_RATE_MCS5_20M_800NS, ++ FIXED_RATE_MCS6_20M_800NS, ++ FIXED_RATE_MCS7_20M_800NS, ++ FIXED_RATE_MCS0_20M_400NS, ++ FIXED_RATE_MCS1_20M_400NS, ++ FIXED_RATE_MCS2_20M_400NS, ++ FIXED_RATE_MCS3_20M_400NS, ++ FIXED_RATE_MCS4_20M_400NS, ++ FIXED_RATE_MCS5_20M_400NS, ++ FIXED_RATE_MCS6_20M_400NS, ++ FIXED_RATE_MCS7_20M_400NS, ++ FIXED_RATE_MCS0_40M_800NS, ++ FIXED_RATE_MCS1_40M_800NS, ++ FIXED_RATE_MCS2_40M_800NS, ++ FIXED_RATE_MCS3_40M_800NS, ++ FIXED_RATE_MCS4_40M_800NS, ++ FIXED_RATE_MCS5_40M_800NS, ++ FIXED_RATE_MCS6_40M_800NS, ++ FIXED_RATE_MCS7_40M_800NS, ++ FIXED_RATE_MCS32_800NS, ++ FIXED_RATE_MCS0_40M_400NS, ++ FIXED_RATE_MCS1_40M_400NS, ++ FIXED_RATE_MCS2_40M_400NS, ++ FIXED_RATE_MCS3_40M_400NS, ++ FIXED_RATE_MCS4_40M_400NS, ++ FIXED_RATE_MCS5_40M_400NS, ++ FIXED_RATE_MCS6_40M_400NS, ++ FIXED_RATE_MCS7_40M_400NS, ++ FIXED_RATE_MCS32_400NS, ++ FIXED_RATE_NUM ++} ENUM_REGISTRY_FIXED_RATE_T, *P_ENUM_REGISTRY_FIXED_RATE_T; ++ ++typedef enum _ENUM_BT_CMD_T { ++ BT_CMD_PROFILE = 0, ++ BT_CMD_UPDATE, ++ BT_CMD_NUM ++} ENUM_BT_CMD_T; ++ ++typedef enum _ENUM_BT_PROFILE_T { ++ BT_PROFILE_CUSTOM = 0, ++ BT_PROFILE_SCO, ++ BT_PROFILE_ACL, ++ BT_PROFILE_MIXED, ++ BT_PROFILE_NO_CONNECTION, ++ BT_PROFILE_NUM ++} ENUM_BT_PROFILE_T; ++ ++typedef struct _PTA_PROFILE_T { ++ ENUM_BT_PROFILE_T eBtProfile; ++ union { ++ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; ++ /* 0: sco reserved slot time, ++ 1: sco idle slot time, ++ 2: acl throughput, ++ 3: bt tx power, ++ 4: bt rssi ++ 5: VoIP interval ++ 6: BIT(0) Use this field, BIT(1) 0 apply single/ 1 dual PTA setting. ++ */ ++ UINT_32 au4Btcr[4]; ++ } u; ++} PTA_PROFILE_T, *P_PTA_PROFILE_T; ++ ++typedef struct _PTA_IPC_T { ++ UINT_8 ucCmd; ++ UINT_8 ucLen; ++ union { ++ PTA_PROFILE_T rProfile; ++ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; ++ } u; ++} PARAM_PTA_IPC_T, *P_PARAM_PTA_IPC_T, PTA_IPC_T, *P_PTA_IPC_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief CFG80211 Scan Request Container */ ++/*--------------------------------------------------------------*/ ++ ++typedef struct _PARAM_SCAN_REQUEST_EXT_T { ++ PARAM_SSID_T rSsid; ++ UINT_32 u4IELength; ++ PUINT_8 pucIE; ++} PARAM_SCAN_REQUEST_EXT_T, *P_PARAM_SCAN_REQUEST_EXT_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief CFG80211 Scheduled Scan Request Container */ ++/*--------------------------------------------------------------*/ ++typedef struct _PARAM_SCHED_SCAN_REQUEST_T { ++ UINT_32 u4SsidNum; ++ PARAM_SSID_T arSsid[CFG_SCAN_SSID_MATCH_MAX_NUM]; ++ UINT_32 u4IELength; ++ PUINT_8 pucIE; ++ UINT_16 u2ScanInterval; /* in milliseconds */ ++} PARAM_SCHED_SCAN_REQUEST, *P_PARAM_SCHED_SCAN_REQUEST; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++typedef struct _PARAM_HS20_SET_BSSID_POOL { ++ BOOLEAN fgIsEnable; ++ UINT_8 ucNumBssidPool; ++ PARAM_MAC_ADDRESS arBSSID[8]; ++} PARAM_HS20_SET_BSSID_POOL, *P_PARAM_HS20_SET_BSSID_POOL; ++ ++#endif ++ ++typedef struct _PARAM_CUSTOM_WFD_DEBUG_STRUCT_T { ++ UINT_8 ucWFDDebugMode; /* 0: Disable ++ 1:Enable but only show inqueue skb ether SN ++ 2.show skb ether SN and the statistics of skb inqueue time */ ++ UINT_16 u2SNPeriod; /* The Ether SN Period */ ++ ++ UINT_8 reserved; ++} PARAM_CUSTOM_WFD_DEBUG_STRUCT_T, *P_PARAM_CUSTOM_WFD_DEBUG_STRUCT_T; ++ ++typedef struct _CMD_GET_PSCAN_CAPABILITY { ++/* TBD */ ++} CMD_GET_GSCAN_CAPABILITY, *P_CMD_GET_GSCAN_CAPABILITY; ++ ++typedef struct _CMD_SET_PSCAN_ENABLE { ++ UINT_8 ucPscanAct; ++ UINT_8 aucReserved[3]; ++} CMD_SET_PSCAN_ENABLE, *P_CMD_SET_PSCAN_ENABLE; ++ ++typedef enum _ENUM_PSCAN_ACT_T { ++ ENABLE, ++ DISABLE, ++ SUSPEND, ++ CLEAR ++} ENUM_PSCAN_ACT_T, *P_ENUM_PSCAN_ACT_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*--------------------------------------------------------------*/ ++/* Routines to set parameters or query information. */ ++/*--------------------------------------------------------------*/ ++/***** Routines in wlan_oid.c *****/ ++WLAN_STATUS ++wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetConnect(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if 0 ++WLAN_STATUS ++wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetChannel(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID prSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRfTestRxStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRfTestTxStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++WLAN_STATUS ++wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#ifdef LINUX ++ ++WLAN_STATUS ++wlanoidQueryStatisticsForLinux(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#endif ++ ++WLAN_STATUS ++wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++WLAN_STATUS ++wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++WLAN_STATUS ++wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++/* RF Test related APIs */ ++WLAN_STATUS ++wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if CFG_SUPPORT_WAPI ++WLAN_STATUS ++wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++WLAN_STATUS ++wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++#if CFG_ENABLE_WAKEUP_ON_LAN ++WLAN_STATUS ++wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 u4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); ++ ++#if CFG_SLT_SUPPORT ++ ++WLAN_STATUS ++wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#endif ++ ++#if 0 ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBT(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++WLAN_STATUS ++wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#endif ++ ++/* ++WLAN_STATUS ++wlanoidQueryBtSingleAntenna ( ++ IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, ++ IN UINT_32 u4QueryBufferLen, ++ OUT PUINT_32 pu4QueryInfoLen ++ ); ++ ++WLAN_STATUS ++wlanoidSetBtSingleAntenna ( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen ++ ); ++ ++WLAN_STATUS ++wlanoidSetPta ( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen ++ ); ++ ++WLAN_STATUS ++wlanoidQueryPta ( ++ IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, ++ IN UINT_32 u4QueryBufferLen, ++ OUT PUINT_32 pu4QueryInfoLen ++ ); ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++WLAN_STATUS ++wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++#if CFG_SUPPORT_BATCH_SCAN ++WLAN_STATUS ++wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++WLAN_STATUS ++wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTxRateInfo( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen ++ ); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++WLAN_STATUS ++wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++WLAN_STATUS ++wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen); ++ ++#endif /* _WLAN_OID_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h +new file mode 100644 +index 000000000000..0b558d64034d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h +@@ -0,0 +1,307 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/wlan_p2p.h#3 ++*/ ++ ++/*! \file "wlan_p2p.h" ++ \brief This file contains the declairations of Wi-Fi Direct command ++ processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_p2p.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version ++ * query & set support for service discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * Support P2P ARP filter setting on early suspend/ late resume ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add subroutines for P2P to set multicast list. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * support wlanoidSetP2pPowerSaveProfile() in P2P ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * Support wlanoidSetNetworkAddress() for P2P ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. ++ * ++ ++ * ++** ++*/ ++ ++#ifndef _WLAN_P2P_H ++#define _WLAN_P2P_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* Service Discovery */ ++typedef struct _PARAM_P2P_SEND_SD_RESPONSE { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucChannelNum; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_SEND_SD_RESPONSE, *P_PARAM_P2P_SEND_SD_RESPONSE; ++ ++typedef struct _PARAM_P2P_GET_SD_REQUEST { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_REQUEST, *P_PARAM_P2P_GET_SD_REQUEST; ++ ++typedef struct _PARAM_P2P_GET_SD_REQUEST_EX { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 ucChannelNum; /* Channel Number Where SD Request is received. */ ++ UINT_8 ucSeqNum; /* Get SD Request by sequence number. */ ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_REQUEST_EX, *P_PARAM_P2P_GET_SD_REQUEST_EX; ++ ++typedef struct _PARAM_P2P_SEND_SD_REQUEST { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucVersionNum; /* Indicate the Service Discovery Supplicant Version. */ ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_SEND_SD_REQUEST, *P_PARAM_P2P_SEND_SD_REQUEST; ++ ++/* Service Discovery 1.0. */ ++typedef struct _PARAM_P2P_GET_SD_RESPONSE { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_RESPONSE, *P_PARAM_P2P_GET_SD_RESPONSE; ++ ++/* Service Discovery 2.0. */ ++typedef struct _PARAM_P2P_GET_SD_RESPONSE_EX { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 ucSeqNum; /* Get SD Response by sequence number. */ ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_RESPONSE_EX, *P_PARAM_P2P_GET_SD_RESPONSE_EX; ++ ++typedef struct _PARAM_P2P_TERMINATE_SD_PHASE { ++ PARAM_MAC_ADDRESS rPeerAddr; ++} PARAM_P2P_TERMINATE_SD_PHASE, *P_PARAM_P2P_TERMINATE_SD_PHASE; ++ ++/*! \brief Key mapping of BSSID */ ++typedef struct _P2P_PARAM_KEY_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< KeyID */ ++ UINT_32 u4KeyLength; /*!< Key length in bytes */ ++ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ ++ PARAM_KEY_RSC rKeyRSC; ++ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ ++} P2P_PARAM_KEY_T, *P_P2P_PARAM_KEY_T; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*--------------------------------------------------------------*/ ++/* Routines to handle command */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++/*--------------------------------------------------------------*/ ++/* Service Discovery Subroutines */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 puQueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++WLAN_STATUS ++wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++WLAN_STATUS ++wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++#endif ++ ++/*--------------------------------------------------------------*/ ++/* Callbacks for event indication */ ++/*--------------------------------------------------------------*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif ++#endif /* _WLAN_P2P_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c +new file mode 100644 +index 000000000000..f2324f13280e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c +@@ -0,0 +1,1303 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/aaa_fsm.c#2 ++*/ ++ ++/*! \file "aaa_fsm.c" ++ \brief This file defines the FSM for AAA MODULE. ++ ++ This file defines the FSM for AAA MODULE. ++*/ ++ ++/* ++** Log: aaa_fsm.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 02 22 2012 yuche.tsai ++ * NULL ++ * Solve sigma test 5.1.3 issue, assoc response should have P2P IE. ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Resolve inorder issue under AP mode. ++ * ++ * data frame may TX before assoc response frame. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * Add BoW 11N support. ++ * ++ * 06 02 2011 eddie.chen ++ * [WCXRP00000759] [MT6620 Wi-Fi][DRV] Update RCPI in AAA ++ * Update RCPI when receiving Assoc request. ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 09 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link connection event procedure and change skb length check to 1512 bytes. ++ * ++ * 03 09 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * Skip to call p2pRunEventAAAComplete to avoid indicate STA connect twice. ++ * ++ * 03 04 2011 terry.wu ++ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection ++ * Remove unused variable. ++ * ++ * 02 16 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Add more check after RX assoc frame under Hot-Spot mode. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Fix Client Limit Issue. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * [On behalf of Frog] Add CFG_ENABLE_WIFI_DIRECT to p2pRunEventAAAComplete ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify AAA flow according to CM's comment. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Fix Compile warning, type cast from UINT_32 to UINT_16. ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * In P2P AT GO test mode under WinXP, we would not indicate connected event to host. ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 kevin.huang ++ * NULL ++ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() ++ * ++ * 08 17 2010 yuche.tsai ++ * NULL ++ * Fix bug while enabling P2P GO. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * modify due to P2P functino call prototype change. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * First draft for migration P2P FSM from FW to Driver. ++ * ++ * 04 02 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify CFG flags ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * add support of Driver STA_RECORD_T activation ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Event to AIS/BOW/P2P ++* ++* @param[in] rJoinStatus To indicate JOIN success or failure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prSwRfb Pointer to the SW_RFB_T ++ ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS aaaFsmSendEventJoinComplete(WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb) ++{ ++ P_MSG_SAA_JOIN_COMP_T prJoinCompMsg; ++ ++ ASSERT(prStaRec); ++ ++ prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T)); ++ if (!prJoinCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ if (IS_STA_IN_AIS(prStaRec)) ++ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; ++ else if (IS_STA_IN_P2P(prStaRec)) ++ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; ++ else if (IS_STA_IN_BOW(prStaRec)) ++ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; ++ else ++ ASSERT(0); ++ ++ prJoinCompMsg->rJoinStatus = rJoinStatus; ++ prJoinCompMsg->prStaRec = prStaRec; ++ prJoinCompMsg->prSwRfb = prSwRfb; ++ ++ mboxSendMsg(MBOX_ID_0, (P_MSG_HDR_T) prJoinCompMsg, MSG_SEND_METHOD_BUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of saaFsmSendEventJoinComplete() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Start Event to AAA FSM. ++* ++* @param[in] prMsgHdr Message of Join Request for a particular STA. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aaaFsmRunEventStart(IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SAA_JOIN_REQ_T prJoinReqMsg; ++ P_STA_RECORD_T prStaRec; ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prMsgHdr); ++ ++ prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr; ++ prStaRec = prJoinReqMsg->prStaRec; ++ ++ ASSERT(prStaRec); ++ ++ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n"); ++ ++ cnmMemFree(prMsgHdr); ++ ++ /* 4 <1> Validation of SAA Start Event */ ++ if (!IS_AP_STA(prStaRec->eStaType)) { ++ ++ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); ++ ++ /* Ignore the return value because don't care the prSwRfb */ ++ saaFsmSendEventJoinComplete(WLAN_STATUS_FAILURE, prStaRec, NULL); ++ ++ return; ++ } ++ /* 4 <2> The previous JOIN process is not completed ? */ ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ } ++ /* 4 <3> Reset Status Code and Time */ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); ++ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ if (prStaRec->prChallengeText) { ++ cnmMemFree(prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ ++ cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ prStaRec->ucStaState = STA_STATE_1; ++ ++ /* Trigger SAA MODULE */ ++ saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); ++ ++} /* end of saaFsmRunEventStart() */ ++#endif ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Auth Request Frame and then ++* trigger AAA FSM. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ UINT_16 u2StatusCode; ++ BOOLEAN fgReplyAuth = FALSE; ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ ++ ASSERT(prAdapter); ++ ++ do { ++ ++ /* 4 <1> Check P2P network conditions */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prBssInfo->fgIsNetActive) { ++ ++ /* 4 <1.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ ++ if (WLAN_STATUS_SUCCESS == ++ authProcessRxAuth1Frame(prAdapter, ++ prSwRfb, ++ prBssInfo->aucBSSID, ++ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, ++ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ /* 4 <1.2> Validate Auth Frame for Network Specific Conditions */ ++ fgReplyAuth = p2pFuncValidateAuth(prAdapter, ++ prSwRfb, &prStaRec, &u2StatusCode); ++ } else { ++ fgReplyAuth = TRUE; ++ } ++ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* 4 <2> Check BOW network conditions */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { ++ ++ /* 4 <2.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ ++ /* Check if for this BSSID */ ++ if (WLAN_STATUS_SUCCESS == ++ authProcessRxAuth1Frame(prAdapter, ++ prSwRfb, ++ prBssInfo->aucBSSID, ++ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, ++ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ ++ /* 4 <2.2> Validate Auth Frame for Network Specific Conditions */ ++ fgReplyAuth = ++ bowValidateAuth(prAdapter, prSwRfb, &prStaRec, &u2StatusCode); ++ ++ } else { ++ ++ fgReplyAuth = TRUE; ++ } ++ eNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ return; ++ } while (FALSE); ++ ++ if (prStaRec) { ++ /* update RCPI */ ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ } ++ /* 4 <3> Update STA_RECORD_T and reply Auth_2(Response to Auth_1) Frame */ ++ if (fgReplyAuth) { ++ ++ if (prStaRec) { ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++ DBGLOG(AAA, WARN, "Previous AuthAssocState (%d) != IDLE.\n", ++ prStaRec->eAuthAssocState); ++ } ++ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ } else { ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ ++ /* NOTE(Kevin): Change to STATE_1 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ prStaRec->ucAuthAlgNum = AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else { ++ /* NOTE(Kevin): We should have STA_RECORD_T if the status code was successful */ ++ ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL)); ++ } ++ ++ /* NOTE: Ignore the return status for AAA */ ++ /* 4 <4> Reply Auth */ ++ authSendAuthFrame(prAdapter, prStaRec, eNetTypeIndex, prSwRfb, AUTH_TRANSACTION_SEQ_2, u2StatusCode); ++ ++ } ++ ++} /* end of aaaFsmRunEventRxAuth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx (Re)Association Request Frame and then ++* trigger AAA FSM. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always return success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ UINT_16 u2StatusCode = STATUS_CODE_RESERVED; ++ BOOLEAN fgReplyAssocResp = FALSE; ++ ++ ASSERT(prAdapter); ++ ++ do { ++ ++ /* 4 <1> Check if we have the STA_RECORD_T for incoming Assoc Req */ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ /* We should have the corresponding Sta Record. */ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { ++ ASSERT(0); /* Only for debug phase */ ++ break; ++ } ++ ++ if (!IS_CLIENT_STA(prStaRec)) ++ break; ++ ++ if (prStaRec->ucStaState == STA_STATE_3) { ++ /* Do Reassocation */ ++ } else if ((prStaRec->ucStaState == STA_STATE_2) && ++ (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) { ++ /* Normal case */ ++ } else { ++ DBGLOG(AAA, INFO, "Previous AuthAssocState (%d) != SEND_AUTH2, ucStaState:%d.\n", ++ prStaRec->eAuthAssocState, ++ prStaRec->ucStaState); ++ /* TODO: Why assoc req event is faster than tx done of auth */ ++ if (prStaRec->eAuthAssocState != AAA_STATE_SEND_AUTH2) ++ break; ++ } ++ ++ /* update RCPI */ ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ ++ /* 4 <2> Check P2P network conditions */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prBssInfo->fgIsNetActive) { ++ ++ /* 4 <2.1> Validate Assoc Req Frame and get Status Code */ ++ /* Check if for this BSSID */ ++ if (WLAN_STATUS_SUCCESS == ++ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ /* 4 <2.2> Validate Assoc Req Frame for Network Specific Conditions */ ++ fgReplyAssocResp = p2pFuncValidateAssocReq(prAdapter, ++ prSwRfb, ++ (PUINT_16)&u2StatusCode); ++ } else { ++ fgReplyAssocResp = TRUE; ++ } ++ ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* 4 <3> Check BOW network conditions */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_STA_IN_BOW(prStaRec)) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { ++ ++ /* 4 <3.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ ++ /* Check if for this BSSID */ ++ if (WLAN_STATUS_SUCCESS == ++ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ ++ /* 4 <3.2> Validate Auth Frame for Network Specific Conditions */ ++ fgReplyAssocResp = ++ bowValidateAssocReq(prAdapter, prSwRfb, &u2StatusCode); ++ ++ } else { ++ ++ fgReplyAssocResp = TRUE; ++ } ++ ++ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ return WLAN_STATUS_SUCCESS; /* To release the SW_RFB_T */ ++ } while (FALSE); ++ ++ /* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */ ++ if (fgReplyAssocResp) { ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ ++ if ((((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) == ++ MAC_FRAME_REASSOC_REQ) { ++ ++ u2IELength = prSwRfb->u2PacketLen - ++ (UINT_16) OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]); ++ ++ pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; ++ } else { ++ u2IELength = prSwRfb->u2PacketLen - (UINT_16) OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]); ++ ++ pucIE = ((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; ++ } ++ ++ rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength); ++ ++ /* 4 <4.1> Assign Association ID */ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ if (p2pRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { ++ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); ++ /* prStaRec->eAuthAssocState = AA_STATE_IDLE; */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;/* NOTE(Kevin): for TX done */ ++ ++ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ ++ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ ++ } else { ++ /* Client List FULL. */ ++ u2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ prStaRec->u2AssocId = 0; /* Invalid Association ID */ ++ ++ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if ((IS_STA_IN_BOW(prStaRec))) { ++ /* if (bowRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { */ ++ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2; /* NOTE(Kevin): for TX done */ ++ ++ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ ++ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ ++ } ++#if 0 ++ else { ++ /* Client List FULL. */ ++ u2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ prStaRec->u2AssocId = 0; /* Invalid Association ID */ ++ ++ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } ++ } ++#endif ++#endif ++ } else { ++ prStaRec->u2AssocId = 0; /* Invalid Association ID */ ++ ++ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ /* NOTE: Ignore the return status for AAA */ ++ /* 4 <4.2> Reply Assoc Resp */ ++ assocSendReAssocRespFrame(prAdapter, prStaRec); ++ ++} ++ ++return WLAN_STATUS_SUCCESS; ++ ++} /* end of aaaFsmRunEventRxAssoc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. ++* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. ++* ++* @retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ DBGLOG(AAA, LOUD, "EVENT-TX DONE: Current Time = %lu\n", (unsigned long)kalGetTimeTick()); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { ++ DBGLOG(AAA, INFO, "EVENT-TX DONE: Invalid StaRec"); ++ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ ++ } ++ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ DBGLOG(AAA, INFO, "TX DONE status: %d, AuthAssocState: %d, SeqNo: %d\n", ++ rTxDoneStatus, prStaRec->eAuthAssocState, ++ prMsduInfo->ucTxSeqNum); ++ ++ switch (prStaRec->eAuthAssocState) { ++ case AAA_STATE_SEND_AUTH2: ++ { ++ /* Strictly check the outgoing frame is matched with current AA STATE */ ++ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_2) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { ++ if (TX_RESULT_SUCCESS == rTxDoneStatus) { ++ ++ /* NOTE(Kevin): Change to STATE_2 at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } else { ++ ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ ++ /* NOTE(Kevin): Change to STATE_1 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ p2pRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ } ++ ++ } ++ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ ++ ++ } ++ break; ++ ++ case AAA_STATE_SEND_ASSOC2: ++ { ++ /* Strictly check the outgoing frame is matched with current SAA STATE */ ++ if (assocCheckTxReAssocRespFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { ++ if (TX_RESULT_SUCCESS == rTxDoneStatus) { ++ ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ ++ /* NOTE(Kevin): Change to STATE_3 at TX Done */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ p2pRunEventAAASuccess(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++ if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventAAAComplete(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ } else { ++ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Change to STATE_2 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ p2pRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ } ++ } ++ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of aaaFsmRunEventTxDone() */ ++#endif /* CFG_SUPPORT_AAA */ ++ ++#if 0 /* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will send ABORT Event to JOIN FSM. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventAbort(IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("joinFsmRunEventAbort"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ ++ DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n"); ++ ++ /* NOTE(Kevin): when reach here, the ARB_STATE should be in ARB_STATE_JOIN. */ ++ ASSERT(prJoinInfo->prBssDesc); ++ ++ /* 4 <1> Update Flags and Elements of JOIN Module. */ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prJoinInfo->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel all JOIN relative Timer */ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer); ++ ++ /* 4 <2> Update the associated STA_RECORD_T during JOIN. */ ++ /* Get a Station Record if possible, TA == BSSID for AP */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); ++ if (prStaRec) ++ prStaRec->ucStaState = STA_STATE_1; /* Update Station Record - Class 1 Flag */ ++#if DBG ++ else ++ ASSERT(0); /* Shouldn't happened, because we already add this STA_RECORD_T at JOIN_STATE_INIT */ ++#endif /* DBG */ ++ ++ /* 4 <3> Pull back to IDLE. */ ++ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); ++ ++ /* 4 <4> If we are in Roaming, recover the settings of previous BSS. */ ++ /* NOTE: JOIN FAIL - ++ * Restore original setting from current BSS_INFO_T. ++ */ ++ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) ++ joinAdoptParametersFromCurrentBss(prAdapter); ++ ++} /* end of joinFsmRunEventAbort() */ ++#endif ++ ++/* TODO(Kevin): following code will be modified and move to AIS FSM */ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will send Join Timeout Event to JOIN FSM. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ ++ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); ++ ++ /* Get a Station Record if possible, TA == BSSID for AP */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); ++ ++ /* We have renew this Sta Record when in JOIN_STATE_INIT */ ++ ASSERT(prStaRec); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; ++ ++ /* Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prJoinInfo->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel other JOIN relative Timer */ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); ++ ++ /* Restore original setting from current BSS_INFO_T */ ++ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) ++ joinAdoptParametersFromCurrentBss(prAdapter); ++ ++ /* Pull back to IDLE */ ++ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); ++ ++ return WLAN_STATUS_FAILURE; ++ ++} /* end of joinFsmRunEventJoinTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from Peer BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ DEBUGFUNC("joinAdoptParametersFromPeerBss"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ ++ /* 4 <1> Adopt Peer BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; ++ ++ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", ++ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); ++ ++ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); ++ ++ prJoinInfo->fgIsParameterAdopted = TRUE; ++ ++} /* end of joinAdoptParametersFromPeerBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from current associated BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) ++{ ++ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ prBssInfo = &prAdapter->rBssInfo; ++ ++ /* 4 <1> Adopt current BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; ++ ++ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); ++ ++} /* end of joinAdoptParametersFromCurrentBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will update all the SW variables and HW MCR registers after ++* the association with target BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinComplete(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ P_PEER_BSS_INFO_T prPeerBssInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SUPPORT_802_11D ++ P_IE_COUNTRY_T prIECountry; ++#endif ++ ++ DEBUGFUNC("joinComplete"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ prPeerBssInfo = &prAdapter->rPeerBssInfo; ++ prBssInfo = &prAdapter->rBssInfo; ++ prConnSettings = &prAdapter->rConnSettings; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ ++ /* Remove previous AP's Connection Flags if have */ ++ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); ++ ++ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ ++ ++ if (prBssDesc->fgIsHiddenSSID) { ++ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't ++ * broadcast SSID on its Beacon Frame. ++ */ ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); ++ ++ if (prBssDesc->ucSSIDLen) ++ prBssDesc->fgIsHiddenSSID = FALSE; ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); ++ } ++/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ ++ /* 4 <2.A> PHY Type */ ++ prBssInfo->ePhyType = prBssDesc->ePhyType; ++ ++ /* 4 <2.B> BSS Type */ ++ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ ++ /* 4 <2.C> BSSID */ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); ++ ++ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); ++ ++ /* 4 <2.D> SSID */ ++ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ ++ /* 4 <2.E> Channel / Band information. */ ++ prBssInfo->eBand = prBssDesc->eBand; ++ prBssInfo->ucChnl = prBssDesc->ucChannelNum; ++ ++ /* 4 <2.F> RSN/WPA information. */ ++ secFsmRunEventStart(prAdapter); ++ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; ++ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; ++ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; ++ ++ if (secRsnKeyHandshakeEnabled()) ++ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; ++ else ++ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; ++ ++ /* 4 <2.G> Beacon interval. */ ++ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ ++ /* 4 <2.H> DTIM period. */ ++ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; ++ ++ /* 4 <2.I> ERP Information */ ++ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ ++ (prBssDesc->fgIsERPPresent)) { ++ ++ prBssInfo->fgIsERPPresent = TRUE; ++ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ ++ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ ++ prBssInfo->fgIsERPPresent = FALSE; ++ prBssInfo->ucERP = 0; ++ } ++ ++#if CFG_SUPPORT_802_11D ++ /* 4 <2.J> Country inforamtion of the associated AP */ ++ if (prConnSettings->fgMultiDomainCapabilityEnabled) { ++ DOMAIN_INFO_ENTRY rDomainInfo; ++ ++ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { ++ if (prBssDesc->prIECountry) { ++ prIECountry = prBssDesc->prIECountry; ++ ++ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); ++ ++ /* use the domain get from the BSS info */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); ++ } else { ++ /* use the domain get from the scan result */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); ++ } ++ } ++ } ++#endif ++ ++ /* 4 <2.K> Signal Power of the associated AP */ ++ prBssInfo->rRcpi = prBssDesc->rRcpi; ++ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); ++ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); ++ ++ /* 4 <2.L> Capability Field of the associated AP */ ++ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; ++ ++ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", ++ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); ++ ++/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ ++ /* 4 <3.A> Association ID */ ++ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; ++ ++ /* 4 <3.B> WMM Information */ ++ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { ++ ++ prBssInfo->fgIsWmmAssoc = TRUE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; ++ ++ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); ++ ++ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { ++ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } else { ++ kalMemCopy(&prBssInfo->rWmmInfo, ++ &prPeerBssInfo->rWmmInfo, ++ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); ++ } ++ } else { ++ prBssInfo->fgIsWmmAssoc = FALSE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; ++ ++ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } ++ ++ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ ++ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; ++ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; ++ ++ /* 4 <3.D> Short Preamble */ ++ if (prBssInfo->fgIsERPPresent) { ++ ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE FALSE(shouldn't have such case, ++ * use the AssocResp) ++ * TRUE FALSE TRUE FALSE ++ * FALSE FALSE FALSE FALSE(shouldn't have such case, ++ * use the AssocResp) ++ * FALSE FALSE TRUE FALSE ++ * TRUE TRUE FALSE TRUE(follow ERP) ++ * TRUE TRUE TRUE FALSE(follow ERP) ++ * FALSE TRUE FALSE FALSE(shouldn't have such case, ++ * and we should set to FALSE) ++ * FALSE TRUE TRUE FALSE(we should set to FALSE) ++ */ ++ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && ++ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { ++ ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ ++ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) ++ prBssInfo->fgUseShortPreamble = FALSE; ++ else ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ } else { ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE ++ * FALSE FALSE FALSE ++ * TRUE TRUE TRUE ++ * FALSE TRUE(status success) TRUE ++ * --> Honor the result of prPeerBssInfo. ++ */ ++ ++ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = ++ prPeerBssInfo->fgIsShortPreambleAllowed; ++ } ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", ++ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); ++ ++ /* 4 <3.E> Short Slot Time */ ++ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); ++ ++ nicSetSlotTime(prAdapter, ++ prBssInfo->ePhyType, ++ ((prConnSettings->fgIsShortSlotTimeOptionEnable && ++ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); ++ ++ /* 4 <3.F> Update Tx Rate for Control Frame */ ++ bssUpdateTxRateForControlFrame(prAdapter); ++ ++ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ ++ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ ++ { ++ ++ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; ++ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; ++ ++ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; ++ ++ /* Set the stable time of the associated BSS. We won't do roaming decision ++ * during the stable time. ++ */ ++ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, ++ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); ++ } ++ ++ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ ++#if CFG_TX_FRAGMENT ++ txFragInfoUpdate(prAdapter); ++#endif /* CFG_TX_FRAGMENT */ ++ ++/* 4 <4> Update STA_RECORD_T */ ++ /* Get a Station Record if possible */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); ++ ++ if (prStaRec) { ++ UINT_16 u2OperationalRateSet, u2DesiredRateSet; ++ ++ /* 4 <4.A> Desired Rate Set */ ++ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & ++ prBssInfo->u2OperationalRateSet); ++ ++ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); ++ if (u2DesiredRateSet) { ++ prStaRec->u2DesiredRateSet = u2DesiredRateSet; ++ } else { ++ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ ++ prStaRec->u2DesiredRateSet = u2OperationalRateSet; ++ } ++ ++ /* Try to set the best initial rate for this entry */ ++ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, ++ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { ++ ++ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) ++ ASSERT(0); ++ } ++ ++ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); ++ ++ /* 4 <4.B> Preamble Mode */ ++ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; ++ ++ /* 4 <4.C> QoS Flag */ ++ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; ++ } ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++/* 4 <5> Update NIC */ ++ /* 4 <5.A> Update BSSID & Operation Mode */ ++ nicSetupBSS(prAdapter, prBssInfo); ++ ++ /* 4 <5.B> Update WLAN Table. */ ++ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) ++ ASSERT(FALSE); ++ /* 4 <5.C> Update Desired Rate Set for BT. */ ++#if CFG_TX_FRAGMENT ++ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) ++ txRateSetInitForBT(prAdapter, prStaRec); ++#endif /* CFG_TX_FRAGMENT */ ++ ++ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ ++ if (prBssInfo->fgIsWmmAssoc) { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, FALSE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); ++ } else { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, TRUE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); ++ ++ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); ++ } ++ ++#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN ++ { ++ prTxCtrl->fgBlockTxDuringJoin = FALSE; ++ ++#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ ++ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxRetransmitOfSendWaitQue(prAdapter); ++ ++ if (prTxCtrl->fgIsPacketInOsSendQueue) ++ nicTxRetransmitOfOsSendQue(prAdapter); ++#if CFG_SDIO_TX_ENHANCE ++ halTxLeftClusteredMpdu(prAdapter); ++#endif /* CFG_SDIO_TX_ENHANCE */ ++ ++ } ++#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ ++ ++/* 4 <6> Setup CONNECTION flag. */ ++ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; ++ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; ++ ++ if (prJoinInfo->fgIsReAssoc) ++ prAdapter->fgBypassPortCtrlForRoaming = TRUE; ++ else ++ prAdapter->fgBypassPortCtrlForRoaming = FALSE; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); ++ ++} /* end of joinComplete() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c +new file mode 100644 +index 000000000000..7b5a49a5ba63 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c +@@ -0,0 +1,5039 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ais_fsm.c#1 ++*/ ++ ++/*! \file "aa_fsm.c" ++ \brief This file defines the FSM for SAA and AAA MODULE. ++ ++ This file defines the FSM for SAA and AAA MODULE. ++*/ ++ ++/* ++** Log: ais_fsm.c ++** ++** 09 06 2013 cp.wu ++** always paste SSID information to SAA-FSM ++** ++** 09 06 2013 cp.wu ++** add error handling when reassociation request failed to locate bss descriptor ++** ++** 09 05 2013 cp.wu ++** isolate logic regarding roaming & reassociation ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++ * ++ * 04 20 2012 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * correct macro ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with ++ * corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration ++ * corresponding to network type. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous ++ * to asynchronous approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state ++ * without join timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED ++ * cases as an explicit trigger for Android framework ++ * correct reference to BSSID field in Association-Response frame. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED ++ * cases as an explicit trigger for Android framework ++ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. ++ * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT ++ * indication to Android Wi-Fi framework ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 10 26 2011 tsaiyuan.hsu ++ * [WCXRP00001064] [MT6620 Wi-Fi][DRV]] add code with roaming awareness when disconnecting AIS network ++ * be aware roaming when disconnecting AIS network. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * STA_REC shall be NULL for Beacon's MSDU ++ * ++ * 10 13 2011 cp.wu ++ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS ++ * 1. short join failure count limit to 2 ++ * 2. treat join timeout as kind of join failure as well ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 09 20 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * change window registry of driver for roaming. ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Handle client mode about preamble type and slot time ++ * ++ * 09 08 2011 tsaiyuan.hsu ++ * [WCXRP00000972] [MT6620 Wi-Fi][DRV]] check if roaming occurs after join failure to avoid state incosistence. ++ * check if roaming occurs after join failure to avoid deactivation of network. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 16 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * EnableRoaming in registry is deprecated. ++ * ++ * 08 16 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * use registry to enable or disable roaming. ++ * ++ * 07 07 2011 cp.wu ++ * [WCXRP00000840] [MT6620 Wi-Fi][Driver][AIS] Stop timer for joining when channel is released ++ * due to join failure count exceeding limit ++ * stop timer when joining operation is failed due to try count exceeds limitation ++ * ++ * 06 28 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work ++ * around some tricky AP which use space character as hidden SSID ++ * do not handle SCAN request immediately after connected to increase the probability of receiving 1st beacon frame. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * ensure DEAUTH is always sent before establish a new connection ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * typo fix: a right brace is missed. ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * When RECONNECT request is identified as disconnected, it is necessary to check for pending scan request. ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels ++ * mark fgIsTransition as TRUE for state rolling. ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * always check for pending scan after switched into NORMAL_TR state. ++ * ++ * 06 14 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * always treat connection request at higher priority over scanning request ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * eliminate unused parameters for SAA-FSM ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state ++ * when DEAUTH frame is dropped due to bss disconnection ++ * change SCAN handling behavior when followed by a CONNECT/DISCONNECT requests by pending instead of dropping. ++ * ++ * 05 17 2011 cp.wu ++ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state ++ * when DEAUTH frame is dropped due to bss disconnection ++ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 13 2011 george.huang ++ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF ++ * remove assert ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000575] [MT6620 Wi-Fi][Driver][AIS] reduce memory usage when generating mailbox message for scan request ++ * when there is no IE needed for probe request, then request a smaller memory for mailbox message ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 16 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * remove obsolete definition and unused variables. ++ * ++ * 03 11 2011 cp.wu ++ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently ++ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel ++ * ++ * 03 09 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * avoid clearing fgIsScanReqIssued so as to add scan results. ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 04 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * reset retry conter of attemp to connect to ap after completion of join. ++ * ++ * 03 04 2011 cp.wu ++ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection ++ * surpress compile warning occurred when compiled by GNU compiler collection. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right ++ * after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 02 23 2011 cp.wu ++ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach to ++ * improve response time for scanning request ++ * when handling reconnect request, set fgTryScan as TRUE ++ * ++ * 02 22 2011 cp.wu ++ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach ++ * to improve response time for scanning request ++ * handle SCAN and RECONNECT with a FIFO approach. ++ * ++ * 02 09 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * Check if prRegInfo is null or not before initializing roaming parameters. ++ * ++ * 02 01 2011 cp.wu ++ * [WCXRP00000416] [MT6620 Wi-Fi][Driver] treat "unable to find BSS" as connection trial ++ * to prevent infinite reconnection trials ++ * treat "unable to find BSS" as connection trial to prevent infinite reconnection trials. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 14 2011 cp.wu ++ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent ++ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. ++ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. ++ * ++ * 01 11 2011 cp.wu ++ * [WCXRP00000307] [MT6620 Wi-Fi][SQA]WHQL test .2c_wlan_adhoc case fail. ++ * [IBSS] when merged in, the bss state should be updated to firmware to pass WHQL adhoc failed item ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer ++ * when the corresponding BSS is disconnected due to beacon timeout ++ * remove from scanning result when the BSS is disconnected due to beacon timeout. ++ * ++ * 01 03 2011 cp.wu ++ * [WCXRP00000337] [MT6620 Wi-FI][Driver] AIS-FSM not to invoke cnmStaRecResetStatus ++ * directly 'cause it frees all belonging STA-RECs ++ * do not invoke cnmStaRecResetStatus() directly, nicUpdateBss will do the things after bss is disconnected ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged ++ * do not need to manipulate prStaRec after indicating BSS disconnection to firmware, ++ * 'cause all STA-RECs belongs to BSS has been freed already ++ * ++ * 12 27 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * add DEBUGFUNC() macro invoking for more detailed debugging information ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 12 17 2010 cp.wu ++ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged ++ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update SLT Function for QoS Support and not be affected by fixed rate function. ++ * ++ * 11 25 2010 cp.wu ++ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM ++ * add scanning with specified SSID facility to AIS-FSM ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with ++ * Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate ++ * from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000097] [MT6620 Wi-Fi] [Driver] Fixed the P2P not setting the fgIsChannelExt value make scan not abort ++ * initial the fgIsChannelExt value. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. ++ * correct erroneous logic: specifying eBand with incompatible eSco ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000049] [MT6620 Wi-Fi][Driver] Adhoc cannot be created successfully. ++ * keep IBSS-ALONE state retrying until further instruction is received ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD ++ * when entering RF test with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 09 2010 yuche.tsai ++ * NULL ++ * Fix NULL IE Beacon issue. Sync Beacon Content to FW before enable beacon. ++ * Both in IBSS Create & IBSS Merge ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * frequency is in unit of KHz thus no need to divide 1000 once more. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * 1) initialize for correct parameter even for disassociation. ++ * 2) AIS-FSM should have a limit on trials to build connection ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add option for enabling AIS 5GHz scan ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, ++ * RLM/CNM will handle the channel switching when BSS information is updated ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * check-in missed files. ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 09 2010 cp.wu ++ * NULL ++ * reset fgIsScanReqIssued when abort request is received right after join completion. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 02 2010 cp.wu ++ * NULL ++ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * allocate on MGMT packet for IBSS beaconing. ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * [AIS-FSM] fix: when join failed, release channel privilege as well ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * reuse join-abort sub-procedure to reduce code size. ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, ++ * just pend it til 5-sec. period finishes ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet ++ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found ++ * ++ * 07 26 2010 cp.wu ++ * ++ * re-commit code logic being overwriten. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) enable Ad-Hoc ++ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * indicate scan done for linux wireless extension ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 22 2010 cp.wu ++ * ++ * 1) refine AIS-FSM indent. ++ * 2) when entering RF Test mode, flush 802.1X frames as well ++ * 3) when entering D3 state, flush 802.1X frames as well ++ * ++ * 07 21 2010 cp.wu ++ * ++ * separate AIS-FSM states into different cases of channel request. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one ++ * 2) refine disconnection behaviour when issued during BG-SCAN process ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) bugfix: do not stop timer for join after switched into normal_tr state, ++ * for providing chance for DHCP handshasking ++ * 2) modify rsnPerformPolicySelection() invoking ++ * ++ * 07 19 2010 cp.wu ++ * ++ * 1) init AIS_BSS_INFO as channel number = 1 with band = 2.4GHz ++ * 2) correct typo ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * when IBSS is being merged-in, send command packet to PM for connected indication ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 16 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * bugfix for SCN migration ++ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue ++ * 2) before AIS issues scan request, network(BSS) needs to be activated first ++ * 3) only invoke COPY_SSID when using specified SSID for scan ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * for AIS scanning, driver specifies no extra IE for probe request ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * driver no longer generates probe request frames ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * Remove CFG_MQM_MIGRATION ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Refine AIS-FSM by divided into more states ++ * ++ * 07 13 2010 cm.chang ++ * ++ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * for first connection, if connecting failed do not enter into scan state. ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * once STA-REC is allocated and updated, invoke cnmStaRecChangeState() to sync. with firmware. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * STA-REC is maintained by CNM only. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * remove unused definitions. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RLM APIs by CFG_RLM_MIGRATION. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * RSN/PRIVACY compilation flag awareness correction ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change to enqueue TX frame infinitely. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 01 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add conditionial compiling flag to choose default available bandwidth ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix compile error if CFG_CMD_EVENT_VER_009 == 0 for prEventConnStatus->ucNetworkType. ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set ++ * ++ * 05 17 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Call pmAbort() and add ucNetworkType field in EVENT_CONNECTION_STATUS ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix compile warning - define of MQM_WMM_PARSING was removed ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed the use of compiling flag MQM_WMM_PARSING ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * ++ * Fix typo ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Send Deauth for Class 3 Error and Leave Network Support ++ * ++ * 04 15 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the protected bit at cap info for ad-hoc. ++ * ++ * 04 13 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add new HW CH macro support ++ * ++ * 04 07 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Add TX Power Control RCPI function. ++ * ++ * 03 29 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * move the wlan table alloc / free to change state function. ++ * ++ * 03 25 2010 wh.su ++ * [BORA00000676][MT6620] Support the frequency setting and query at build connection / connection event ++ * modify the build connection and status event structure bu CMD_EVENT doc 0.09 draft, default is disable. ++ * ++ * 03 24 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * fixed some WHQL testing error. ++ * ++ * 03 24 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Set / Unset POWER STATE in AIS Network ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 03 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add PHY_CONFIG to change Phy Type ++ * ++ * 03 03 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Use bcmWiFiNotify to replace wifi_send_msg to pass information to BCM module. ++ * ++ * 03 03 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Remove wmt_task definition and add PTA function. ++ * ++ * 03 02 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Init TXM and MQM testing procedures in aisFsmRunEventJoinComplete() ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Modified aisUpdateBssInfo() to call TXM's functions for setting WTBL TX parameters ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * clear the pmkid cache while indicate media disconnect. ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * . ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Enabled MQM parsing WMM IEs for non-AP mode ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * use the Rx0 dor event indicate. ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Support dynamic channel selection ++ * ++ * 02 23 2010 wh.su ++ * [BORA00000621][MT6620 Wi-Fi] Add the RSSI indicate to avoid XP stalled for query rssi value ++ * Adding the RSSI event support, ++ * using the HAL function to get the rcpi value and tranlsate to RSSI and indicate to driver ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Revise data structure to share the same BSS_INFO_T for avoiding coding error ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Set max AMDPU size supported by the peer to 64 KB, ++ * removed mqmInit() and mqmTxSendAddBaReq() function calls in aisUpdateBssInfo() ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 20 2010 kevin.huang ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags ++ * ++ * 01 15 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Configured the AMPDU factor to 3 for the APu1rwduu`wvpghlqg|q`mpdkb+ilp ++ * ++ * 01 14 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Add WiFi BCM module for the 1st time. ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * Refine JOIN Complete and separate the function of Media State indication ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 10 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the sample code to update the wlan table rate, ++ * ++ * Dec 10 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Different function prototype of wifi_send_msg() ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Call rlm related function to process HT info when join complete ++ * ++ * Dec 9 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * default the acquired wlan table entry code off ++ * ++ * Dec 9 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code to acquired the wlan table entry, and a sample code to update the BA bit at table ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix the problem of prSwRfb overwrited by event packet in aisFsmRunEventJoinComplete() ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code to integrate the security related code ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove redundant declaration ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add code for JOIN init and JOIN complete ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename u4RSSI to i4RSSI ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise ENUM_MEDIA_STATE to ENUM_PARAM_MEDIA_STATE ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add fgIsScanReqIssued to CONNECTION_SETTINGS_T ++ * ++ * Nov 26 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise Virtual CMD handler due to structure changed ++ * ++ * Nov 25 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Virtual CMD & RESP for testing CMD PATH ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aisFsmInitializeConnectionSettings() ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_MGMT_FSM flag for aisFsmTest() ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define AIS_ROAMING_CONNECTION_TRIAL_LIMIT 2 ++#define AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME 80 ++ ++#define CTIA_MAGIC_SSID "ctia_test_only_*#*#3646633#*#*" ++#define CTIA_MAGIC_SSID_LEN 30 ++ ++#define AIS_JOIN_TIMEOUT 7 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugAisState[AIS_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("AIS_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("AIS_STATE_SEARCH"), ++ (PUINT_8) DISP_STRING("AIS_STATE_SCAN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_ONLINE_SCAN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_LOOKING_FOR"), ++ (PUINT_8) DISP_STRING("AIS_STATE_WAIT_FOR_NEXT_SCAN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_REQ_CHANNEL_JOIN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_JOIN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_ALONE"), ++ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_MERGE"), ++ (PUINT_8) DISP_STRING("AIS_STATE_NORMAL_TR"), ++ (PUINT_8) DISP_STRING("AIS_STATE_DISCONNECTING"), ++ (PUINT_8) DISP_STRING("AIS_STATE_REQ_REMAIN_ON_CHANNEL"), ++ (PUINT_8) DISP_STRING("AIS_STATE_REMAIN_ON_CHANNEL") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief the function is used to initialize the value of the connection settings for ++* AIS network ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_8 aucAnyBSSID[] = BC_BSSID; ++ UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ int i = 0; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* Setup default values for operation */ ++ COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr); ++ ++ if (prRegInfo) ++ prConnSettings->ucDelayTimeOfDisconnectEvent = ++ (!prAdapter->fgIsHw5GBandDisabled && prRegInfo->ucSupport5GBand) ? ++ AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND : AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; ++ else ++ prConnSettings->ucDelayTimeOfDisconnectEvent = AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; ++ ++ COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID); ++ prConnSettings->fgIsConnByBssidIssued = FALSE; ++ ++ prConnSettings->fgIsConnReqIssued = FALSE; ++ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; ++ ++ prConnSettings->ucSSIDLen = 0; ++ ++ prConnSettings->eOPMode = NET_TYPE_INFRA; ++ ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ ++ if (prRegInfo) { ++ prConnSettings->ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4StartFreq); ++ prConnSettings->eAdHocBand = prRegInfo->u4StartFreq < 5000000 ? BAND_2G4 : BAND_5G; ++ prConnSettings->eAdHocMode = (ENUM_PARAM_AD_HOC_MODE_T) (prRegInfo->u4AdhocMode); ++ } ++ ++ prConnSettings->eAuthMode = AUTH_MODE_OPEN; ++ ++ prConnSettings->eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ ++ /* MIB attributes */ ++ prConnSettings->u2BeaconPeriod = DOT11_BEACON_PERIOD_DEFAULT; ++ ++ prConnSettings->u2RTSThreshold = DOT11_RTS_THRESHOLD_DEFAULT; ++ ++ prConnSettings->u2DesiredNonHTRateSet = RATE_SET_ALL_ABG; ++ ++ /* prConnSettings->u4FreqInKHz; */ /* Center frequency */ ++ ++ /* Set U-APSD AC */ ++ prConnSettings->bmfgApsdEnAc = PM_UAPSD_NONE; ++ ++ secInit(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* Features */ ++ prConnSettings->fgIsEnableRoaming = FALSE; ++#if CFG_SUPPORT_ROAMING ++ if (prRegInfo) ++ prConnSettings->fgIsEnableRoaming = ((prRegInfo->fgDisRoaming > 0) ? (FALSE) : (TRUE)); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ prConnSettings->fgIsAdHocQoSEnable = FALSE; ++ ++ prConnSettings->eDesiredPhyConfig = PHY_CONFIG_802_11ABGN; ++ ++ /* Set default bandwidth modes */ ++ prConnSettings->uc2G4BandwidthMode = CONFIG_BW_20M; ++ prConnSettings->uc5GBandwidthMode = CONFIG_BW_20_40M; ++ ++ prConnSettings->rRsnInfo.ucElemId = 0x30; ++ prConnSettings->rRsnInfo.u2Version = 0x0001; ++ prConnSettings->rRsnInfo.u4GroupKeyCipherSuite = 0; ++ prConnSettings->rRsnInfo.u4PairwiseKeyCipherSuiteCount = 0; ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) ++ prConnSettings->rRsnInfo.au4PairwiseKeyCipherSuite[i] = 0; ++ prConnSettings->rRsnInfo.u4AuthKeyMgtSuiteCount = 0; ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) ++ prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[i] = 0; ++ prConnSettings->rRsnInfo.u2RsnCap = 0; ++ prConnSettings->rRsnInfo.fgRsnCapPresent = FALSE; ++ ++} /* end of aisFsmInitializeConnectionSettings() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief the function is used to initialize the value in AIS_FSM_INFO_T for ++* AIS FSM operation ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ucScanTimeoutTimes = 0; ++VOID aisFsmInit(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ ++ DEBUGFUNC("aisFsmInit()"); ++ DBGLOG(SW1, TRACE, "->aisFsmInit()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ ++ /* 4 <1> Initiate FSM */ ++ prAisFsmInfo->ePreviousState = AIS_STATE_IDLE; ++ prAisFsmInfo->eCurrentState = AIS_STATE_IDLE; ++ ++ prAisFsmInfo->ucAvailableAuthTypes = 0; ++ ++ prAisFsmInfo->prTargetBssDesc = (P_BSS_DESC_T) NULL; ++ ++ prAisFsmInfo->ucSeqNumOfReqMsg = 0; ++ prAisFsmInfo->ucSeqNumOfChReq = 0; ++ prAisFsmInfo->ucSeqNumOfScanReq = 0; ++ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++#if CFG_SUPPORT_ROAMING ++ prAisFsmInfo->fgIsRoamingScanPending = FALSE; ++#endif /* CFG_SUPPORT_ROAMING */ ++ prAisFsmInfo->fgIsChannelRequested = FALSE; ++ prAisFsmInfo->fgIsChannelGranted = FALSE; ++ ++ /* 4 <1.1> Initiate FSM - Timer INIT */ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rBGScanTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventBGSleepTimeOut, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rIbssAloneTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventIbssAloneTimeOut, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rIndicationOfDisconnectTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisPostponedEventOfDisconnTimeout, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rJoinTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventJoinTimeout, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rScanDoneTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventScanDoneTimeOut, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rChannelTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventChannelTimeout, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rDeauthDoneTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventDeauthTimeout, (ULONG) NULL); ++ ++ /* 4 <1.2> Initiate PWR STATE */ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); ++ ++ /* 4 <3> Initiate BSS_INFO_T - private part */ ++ /* TODO */ ++ prAisBssInfo->eBand = BAND_2G4; ++ prAisBssInfo->ucPrimaryChannel = 1; ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ ++ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ ++ prAisBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); ++ ++ if (prAisBssInfo->prBeacon) { ++ prAisBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; ++ prAisBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ ++ } else { ++ ASSERT(0); ++ } ++ ++#if 0 ++ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; ++ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; ++ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; ++#else ++ if (prAdapter->u4UapsdAcBmp == 0) { ++ prAdapter->u4UapsdAcBmp = CFG_INIT_UAPSD_AC_BMP; ++ /* ASSERT(prAdapter->u4UapsdAcBmp); */ ++ } ++ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; ++#endif ++ ++ /* request list initialization */ ++ LINK_INITIALIZE(&prAisFsmInfo->rPendingReqList); ++ ++ /* DBGPRINTF("[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", */ ++ /* prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, */ ++ /* prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, */ ++ /* prAisBssInfo->rPmProfSetupInfo.ucUapsdSp); */ ++ ++ /*reset ucScanTimeoutTimes value*/ ++ ucScanTimeoutTimes = 0; ++ ++} /* end of aisFsmInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief the function is used to uninitialize the value in AIS_FSM_INFO_T for ++* AIS FSM operation ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ ++ DEBUGFUNC("aisFsmUninit()"); ++ DBGLOG(SW1, INFO, "->aisFsmUninit()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ ++ /* 4 <1> Stop all timers */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); /* Add by Enlai */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ ++ /* 4 <2> flush pending request */ ++ aisFsmFlushRequest(prAdapter); ++ ++ /* 4 <3> Reset driver-domain BSS-INFO */ ++ if (prAisBssInfo->prBeacon) { ++ cnmMgtPktFree(prAdapter, prAisBssInfo->prBeacon); ++ prAisBssInfo->prBeacon = NULL; ++ } ++#if CFG_SUPPORT_802_11W ++ rsnStopSaQuery(prAdapter); ++#endif ++ ++} /* end of aisFsmUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialization of JOIN STATE ++* ++* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_MSG_JOIN_REQ_T prJoinReqMsg; ++ ++ DEBUGFUNC("aisFsmStateInit_JOIN()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ ASSERT(prBssDesc); ++ ++ /* 4 <1> We are going to connect to this BSS. */ ++ prBssDesc->fgIsConnecting = TRUE; ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_LEGACY_AP, NETWORK_TYPE_AIS_INDEX, prBssDesc); ++ if (prStaRec == NULL) { ++ DBGLOG(AIS, WARN, "Create station record fail\n"); ++ return; ++ } ++ ++ prAisFsmInfo->prTargetStaRec = prStaRec; ++ ++ /* 4 <2.1> sync. to firmware domain */ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ prStaRec->fgIsReAssoc = FALSE; ++ ++ switch (prConnSettings->eAuthMode) { ++ case AUTH_MODE_OPEN: /* Note: Omit break here. */ ++ case AUTH_MODE_WPA: ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA2: ++ case AUTH_MODE_WPA2_PSK: ++ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ break; ++ ++ case AUTH_MODE_SHARED: ++ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; ++ break; ++ ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(AIS, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); ++ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | AUTH_TYPE_SHARED_KEY); ++ break; ++ ++ default: ++ ASSERT(!(prConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); ++ DBGLOG(AIS, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", ++ prConnSettings->eAuthMode); ++ /* TODO(Kevin): error handling ? */ ++ return; ++ } ++ ++ /* TODO(tyhsu): Assume that Roaming Auth Type is equal to ConnSettings eAuthMode */ ++ prAisSpecificBssInfo->ucRoamingAuthTypes = prAisFsmInfo->ucAvailableAuthTypes; ++ ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; ++ ++ } else { ++ ASSERT(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE); ++ ASSERT(!prBssDesc->fgIsConnected); ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: AUTH TYPE = %d for Roaming\n", ++ prAisSpecificBssInfo->ucRoamingAuthTypes); ++ ++ prStaRec->fgIsReAssoc = TRUE; /* We do roaming while the medium is connected */ ++ ++ /* TODO(Kevin): We may call a sub function to acquire the Roaming Auth Type */ ++ prAisFsmInfo->ucAvailableAuthTypes = prAisSpecificBssInfo->ucRoamingAuthTypes; ++ ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING; ++ } ++ ++ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ ++ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); ++ ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; ++ } else { ++ ASSERT(0); ++ } ++ ++ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ ++ if (prBssDesc->ucSSIDLen) ++ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ return; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ if (1) { ++ int j; ++ P_FRAG_INFO_T prFragInfo; ++ ++ for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) { ++ prFragInfo = &prStaRec->rFragInfo[j]; ++ ++ if (prFragInfo->pr1stFrag) { ++ /* nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); */ ++ prFragInfo->pr1stFrag = (P_SW_RFB_T) NULL; ++ } ++ } ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++} /* end of aisFsmInit_JOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval TRUE We will retry JOIN ++* @retval FALSE We will not retry JOIN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_JOIN_REQ_T prJoinReqMsg; ++ ++ DEBUGFUNC("aisFsmStateInit_RetryJOIN()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* Retry other AuthType if possible */ ++ if (!prAisFsmInfo->ucAvailableAuthTypes) ++ return FALSE; ++ ++ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(AIS, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else { ++ DBGLOG(AIS, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); ++ ASSERT(0); ++ } ++ ++ prAisFsmInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ ++ ++ /* Trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ return FALSE; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++ return TRUE; ++ ++} /* end of aisFsmRetryJOIN() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief State Initialization of AIS_STATE_IBSS_ALONE ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> Check if IBSS was created before ? */ ++ if (prAisBssInfo->fgIsBeaconActivated) { ++ ++ /* 4 <2> Start IBSS Alone Timer for periodic SCAN and then SEARCH */ ++#if !CFG_SLT_SUPPORT ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); ++#endif ++ } ++ ++ aisFsmCreateIBSS(prAdapter); ++ ++} /* end of aisFsmStateInit_IBSS_ALONE() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief State Initialization of AIS_STATE_IBSS_MERGE ++* ++* @param[in] prBssDesc The pointer of BSS_DESC_T which is the IBSS we will try to merge with. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ ASSERT(prBssDesc); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> We will merge with to this BSS immediately. */ ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); ++ if (prStaRec == NULL) { ++ DBGLOG(AIS, WARN, "Create station record fail\n"); ++ return; ++ } ++ ++ prStaRec->fgIsMerging = TRUE; ++ ++ prAisFsmInfo->prTargetStaRec = prStaRec; ++ ++ /* 4 <2.1> sync. to firmware domain */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* 4 <3> IBSS-Merge */ ++ aisFsmMergeIBSS(prAdapter, prStaRec); ++ ++} /* end of aisFsmStateInit_IBSS_MERGE() */ ++ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of JOIN Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_JOIN_ABORT_T prJoinAbortMsg; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* 1. Abort JOIN process */ ++ prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); ++ if (!prJoinAbortMsg) { ++ ++ ASSERT(0); /* Can't abort SAA FSM */ ++ return; ++ } ++ ++ prJoinAbortMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_ABORT; ++ prJoinAbortMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfReqMsg; ++ prJoinAbortMsg->prStaRec = prAisFsmInfo->prTargetStaRec; ++ ++ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ /* 2. Return channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 3.1 stop join timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ ++ /* 3.2 reset local variable */ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ ++} /* end of aisFsmAbortJOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of SCAN Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* Abort JOIN process. */ ++ prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancelMsg) { ++ ++ ASSERT(0); /* Can't abort SCN FSM */ ++ return; ++ } ++ ++ prScanCancelMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_CANCEL; ++ prScanCancelMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfScanReq; ++ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ prScanCancelMsg->fgIsChannelExt = FALSE; ++#endif ++ ++ /* unbuffered message to guarantee scan is cancelled in sequence */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_UNBUF); ++ ++} /* end of aisFsmAbortSCAN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of NORMAL_TR Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ DBGLOG(AIS, TRACE, "aisFsmStateAbort_NORMAL_TR\n"); ++ ++ /* TODO(Kevin): Do abort other MGMT func */ ++ ++ /* 1. Release channel to CNM */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2.1 stop join timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ ++ /* 2.2 reset local variable */ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ ++} /* end of aisFsmAbortNORMAL_TR() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of NORMAL_TR Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* reset BSS-DESC */ ++ if (prAisFsmInfo->prTargetStaRec) { ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); ++ ++ if (prBssDesc) { ++ prBssDesc->fgIsConnected = FALSE; ++ prBssDesc->fgIsConnecting = FALSE; ++ } ++ } ++ /* release channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ ++} ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The Core FSM engine of AIS(Ad-hoc, Infra STA) ++* ++* @param[in] eNextState Enum value of next AIS STATE ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_DESC_T prBssDesc; ++ P_MSG_CH_REQ_T prMsgChReq; ++ P_MSG_SCN_SCAN_REQ prScanReqMsg; ++ P_AIS_REQ_HDR_T prAisReq; ++ ENUM_BAND_T eBand; ++ UINT_8 ucChannel; ++ UINT_16 u2ScanIELen; ++ ENUM_AIS_STATE_T eOriPreState; ++ ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("aisFsmSteps()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ eOriPreState = prAisFsmInfo->ePreviousState; ++ ++ do { ++ ++ /* Do entering Next State */ ++ prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(AIS, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugAisState[prAisFsmInfo->eCurrentState], apucDebugAisState[eNextState]); ++#else ++ DBGLOG(AIS, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, eNextState); ++#endif ++ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ ++ prAisFsmInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ ++ /* Do tasks of the State that we just entered */ ++ switch (prAisFsmInfo->eCurrentState) { ++ /* NOTE(Kevin): we don't have to rearrange the sequence of following ++ * switch case. Instead I would like to use a common lookup table of array ++ * of function pointer to speed up state search. ++ */ ++ case AIS_STATE_IDLE: ++ ++ prAisReq = aisFsmGetNextRequest(prAdapter); ++ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ ++ if (prAisReq == NULL || prAisReq->eReqType == AIS_REQUEST_RECONNECT) { ++ if (prConnSettings->fgIsConnReqIssued == TRUE && ++ prConnSettings->fgIsDisconnectedByNonRequest == FALSE) { ++ ++ prAisFsmInfo->fgTryScan = TRUE; ++ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* sync with firmware */ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* reset trial count */ ++ prAisFsmInfo->ucConnTrialCount = 0; ++ ++ eNextState = AIS_STATE_SEARCH; ++ fgIsTransition = TRUE; ++ } else { ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* sync with firmware */ ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* check for other pending request */ ++ if (prAisReq && ++ (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE)) { ++ ++ wlanClearScanningResult(prAdapter); ++ eNextState = AIS_STATE_SCAN; ++ ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ if (prAisReq) { ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } ++ } else if (prAisReq->eReqType == AIS_REQUEST_SCAN) { ++#if CFG_SUPPORT_ROAMING ++ prAisFsmInfo->fgIsRoamingScanPending = FALSE; ++#endif /* CFG_SUPPORT_ROAMING */ ++ wlanClearScanningResult(prAdapter); ++ ++ eNextState = AIS_STATE_SCAN; ++ fgIsTransition = TRUE; ++ ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } else if (prAisReq->eReqType == AIS_REQUEST_ROAMING_CONNECT ++ || prAisReq->eReqType == AIS_REQUEST_ROAMING_SEARCH) { ++ /* ignore */ ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } else if (prAisReq->eReqType == AIS_REQUEST_REMAIN_ON_CHANNEL) { ++ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; ++ fgIsTransition = TRUE; ++ ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } ++ ++ prAisFsmInfo->u4SleepInterval = AIS_BG_SCAN_INTERVAL_MIN_SEC; ++ ++ break; ++ ++ case AIS_STATE_SEARCH: ++ /* 4 <1> Search for a matched candidate and save it to prTargetBssDesc. */ ++#if CFG_SLT_SUPPORT ++ prBssDesc = prAdapter->rWifiVar.rSltInfo.prPseudoBssDesc; ++#else ++ prBssDesc = scanSearchBssDescByPolicy(prAdapter, NETWORK_TYPE_AIS_INDEX); ++#endif ++ /* every time BSS join failure count is integral multiples of SCN_BSS_JOIN_FAIL_THRESOLD, ++ we need to scan again to find if a new BSS is here in the ESS, ++ this can also avoid too frequency to retry the rejected AP */ ++ if (prAisFsmInfo->ePreviousState == AIS_STATE_LOOKING_FOR || ++ ((eOriPreState == AIS_STATE_ONLINE_SCAN || ++ eOriPreState == AIS_STATE_SCAN) && prAisFsmInfo->ePreviousState != eOriPreState)) { ++ /* if previous state is scan/online scan/looking for, don't try to scan again */ ++ } else if (prBssDesc && prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD && ++ ((prBssDesc->ucJoinFailureCount - SCN_BSS_JOIN_FAIL_THRESOLD) % ++ SCN_BSS_JOIN_FAIL_THRESOLD) == 0) ++ prBssDesc = NULL; ++ ++ /* we are under Roaming Condition. */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ if (prAisFsmInfo->ucConnTrialCount > AIS_ROAMING_CONNECTION_TRIAL_LIMIT) { ++#if CFG_SUPPORT_ROAMING ++ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_CONNLIMIT); ++#endif /* CFG_SUPPORT_ROAMING */ ++ /* reset retry count */ ++ prAisFsmInfo->ucConnTrialCount = 0; ++ ++ /* abort connection trial */ ++ prConnSettings->fgIsConnReqIssued = FALSE; ++ ++ eNextState = AIS_STATE_NORMAL_TR; ++ fgIsTransition = TRUE; ++ ++ break; ++ } ++ } ++ /* 4 <2> We are not under Roaming Condition. */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ /* 4 <2.a> If we have the matched one */ ++ if (prBssDesc) { ++ ++ /* 4 Stored the Selected BSS security cipher. ++ For later asoc req compose IE */ ++ prAisBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; ++ prAisBssInfo->u4RsnSelectedPairwiseCipher = ++ prBssDesc->u4RsnSelectedPairwiseCipher; ++ prAisBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; ++ ++ /* 4 Do STATE transition and update current Operation Mode. */ ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; ++ ++ /* Record the target BSS_DESC_T for next STATE. */ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* Transit to channel acquire */ ++ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; ++ fgIsTransition = TRUE; ++ ++ /* increase connection trial count */ ++ prAisFsmInfo->ucConnTrialCount++; ++ } ++#if CFG_SUPPORT_ADHOC ++ else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ ++ /* Record the target BSS_DESC_T for next STATE. */ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ eNextState = AIS_STATE_IBSS_MERGE; ++ fgIsTransition = TRUE; ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ else { ++ ASSERT(0); ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ fgIsTransition = TRUE; ++ } ++ } ++ /* 4 <2.b> If we don't have the matched one */ ++ else { ++ ++ /* increase connection trial count for infrastructure connection */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) ++ prAisFsmInfo->ucConnTrialCount++; ++ /* 4 Try to SCAN */ ++ if (prAisFsmInfo->fgTryScan) { ++ eNextState = AIS_STATE_LOOKING_FOR; ++ ++ fgIsTransition = TRUE; ++ break; ++ } ++ /* 4 We've do SCAN already, now wait in some STATE. */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { ++ ++ /* issue reconnect request, ++ * and retreat to idle state for scheduling */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ eNextState = AIS_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } ++#if CFG_SUPPORT_ADHOC ++ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) ++ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) ++ || (prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ prAisFsmInfo->prTargetBssDesc = NULL; ++ ++ eNextState = AIS_STATE_IBSS_ALONE; ++ fgIsTransition = TRUE; ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ else { ++ ASSERT(0); ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ fgIsTransition = TRUE; ++ } ++ } ++ } ++ /* 4 <3> We are under Roaming Condition. */ ++ else { /* prAdapter->eConnectionState == MEDIA_STATE_CONNECTED. */ ++ ++ /* 4 <3.a> This BSS_DESC_T is our AP. */ ++ /* NOTE(Kevin 2008/05/16): Following cases will go back to NORMAL_TR. ++ * CASE I: During Roaming, APP(WZC/NDISTEST) change the connection ++ * settings. That make we can NOT match the original AP, so the ++ * prBssDesc is NULL. ++ * CASE II: The same reason as CASE I. Because APP change the ++ * eOPMode to other network type in connection setting ++ * (e.g. NET_TYPE_IBSS), so the BssDesc become the IBSS node. ++ * (For CASE I/II, before WZC/NDISTEST set the OID_SSID, it will change ++ * other parameters in connection setting first. So if we do roaming ++ * at the same time, it will hit these cases.) ++ * ++ * CASE III: Normal case, we can't find other candidate to roam ++ * out, so only the current AP will be matched. ++ * ++ * CASE IV: Timestamp of the current AP might be reset ++ */ ++ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION && ++ ((!prBssDesc) || /* CASE I */ ++ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) || /* CASE II */ ++ (prBssDesc->fgIsConnected) || /* CASE III */ ++ (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID))) /* CASE IV */) { ++#if DBG ++ if ((prBssDesc) && (prBssDesc->fgIsConnected)) ++ ASSERT(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); ++#endif /* DBG */ ++ /* We already associated with it, go back to NORMAL_TR */ ++ /* TODO(Kevin): Roaming Fail */ ++#if CFG_SUPPORT_ROAMING ++ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* Retreat to NORMAL_TR state */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ fgIsTransition = TRUE; ++ break; ++ } ++ ++ /* 4 <3.b> Try to roam out for JOIN this BSS_DESC_T. */ ++ if (prBssDesc == NULL) { ++ /* increase connection trial count for infrastructure connection */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) ++ prAisFsmInfo->ucConnTrialCount++; ++ /* 4 Try to SCAN */ ++ if (prAisFsmInfo->fgTryScan) { ++ eNextState = AIS_STATE_LOOKING_FOR; ++ ++ fgIsTransition = TRUE; ++ break; ++ } ++ ++ /* 4 We've do SCAN already, now wait in some STATE. */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { ++ ++ /* issue reconnect request, and retreat to idle state ++ * for scheduling */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ eNextState = AIS_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } ++#if CFG_SUPPORT_ADHOC ++ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) ++ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) ++ || (prConnSettings->eOPMode == ++ NET_TYPE_DEDICATED_IBSS)) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ prAisFsmInfo->prTargetBssDesc = NULL; ++ ++ eNextState = AIS_STATE_IBSS_ALONE; ++ fgIsTransition = TRUE; ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ else { ++ ASSERT(0); ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ fgIsTransition = TRUE; ++ } ++ } else { ++#if DBG ++ if (prAisBssInfo->ucReasonOfDisconnect != ++ DISCONNECT_REASON_CODE_REASSOCIATION) { ++ ASSERT(UNEQUAL_MAC_ADDR ++ (prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); ++ } ++#endif /* DBG */ ++ ++ /* 4 Record the target BSS_DESC_T for next STATE. */ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* tyhsu: increase connection trial count */ ++ prAisFsmInfo->ucConnTrialCount++; ++ ++ /* Transit to channel acquire */ ++ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ break; ++ ++ case AIS_STATE_WAIT_FOR_NEXT_SCAN: ++ ++ DBGLOG(AIS, LOUD, "SCAN: Idle Begin - Current Time = %u\n", kalGetTimeTick()); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prAisFsmInfo->rBGScanTimer, SEC_TO_MSEC(prAisFsmInfo->u4SleepInterval)); ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ if (prAisFsmInfo->u4SleepInterval < AIS_BG_SCAN_INTERVAL_MAX_SEC) ++ prAisFsmInfo->u4SleepInterval <<= 1; ++ break; ++ ++ case AIS_STATE_SCAN: ++ case AIS_STATE_ONLINE_SCAN: ++ case AIS_STATE_LOOKING_FOR: ++ ++ if (!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) { ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* sync with firmware */ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ } ++ ++ /* IE length decision */ ++ if (prAisFsmInfo->u4ScanIELength > 0) { ++ u2ScanIELen = (UINT_16) prAisFsmInfo->u4ScanIELength; ++ } else { ++#if CFG_SUPPORT_WPS2 ++ u2ScanIELen = prAdapter->prGlueInfo->u2WSCIELen; ++#else ++ u2ScanIELen = 0; ++#endif ++ } ++ ++ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ OFFSET_OF(MSG_SCN_SCAN_REQ, ++ aucIE) + u2ScanIELen); ++ if (!prScanReqMsg) { ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ return; ++ } ++ ++ prScanReqMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_REQ; ++ prScanReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfScanReq; ++ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ prScanReqMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN; ++#else ++ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++#endif ++ ++#if CFG_SUPPORT_ROAMING_ENC ++ if (prAdapter->fgIsRoamingEncEnabled == TRUE) { ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR && ++ prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ prScanReqMsg->u2ChannelDwellTime = AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME; ++ } ++ } ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN ++ || prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { ++ if (prAisFsmInfo->ucScanSSIDLen == 0) { ++ /* Scan for all available SSID */ ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; ++ } else { ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ COPY_SSID(prScanReqMsg->aucSSID, ++ prScanReqMsg->ucSSIDLength, ++ prAisFsmInfo->aucScanSSID, prAisFsmInfo->ucScanSSIDLen); ++ } ++ } else { ++ /* Scan for determined SSID */ ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ COPY_SSID(prScanReqMsg->aucSSID, ++ prScanReqMsg->ucSSIDLength, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ } ++ ++ /* check if tethering is running and need to fix on specific channel */ ++ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; ++ prScanReqMsg->ucChannelListNum = 1; ++ prScanReqMsg->arChnlInfoList[0].eBand = eBand; ++ prScanReqMsg->arChnlInfoList[0].ucChannelNum = ucChannel; ++ } else { ++#if 0 ++ aisFsmSetChannelInfo(prAdapter, prScanReqMsg, prAisFsmInfo->eCurrentState); ++#endif ++ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_NULL) { ++ if (prAdapter->fgEnable5GBand == TRUE) ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ else ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_2G4) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_5G) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; ++ } else { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ ASSERT(0); ++ } ++ ++ } ++ ++ if (prAisFsmInfo->u4ScanIELength > 0) { ++ kalMemCopy(prScanReqMsg->aucIE, prAisFsmInfo->aucScanIEBuf, ++ prAisFsmInfo->u4ScanIELength); ++ } else { ++#if CFG_SUPPORT_WPS2 ++ if (prAdapter->prGlueInfo->u2WSCIELen > 0) { ++ kalMemCopy(prScanReqMsg->aucIE, &prAdapter->prGlueInfo->aucWSCIE, ++ prAdapter->prGlueInfo->u2WSCIELen); ++ } ++ } ++#endif ++ ++ prScanReqMsg->u2IELen = u2ScanIELen; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); ++ DBGLOG(AIS, TRACE, "SendSR%d\n", prScanReqMsg->ucSeqNum); ++ prAisFsmInfo->fgTryScan = FALSE; /* Will enable background sleep for infrastructure */ ++ ++ prAdapter->ucScanTime++; ++ break; ++ ++ case AIS_STATE_REQ_CHANNEL_JOIN: ++ /* send message to CNM for acquiring channel */ ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ return; ++ } ++ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++ prMsgChReq->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; ++ ++ if (prAisFsmInfo->prTargetBssDesc != NULL) { ++ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; ++ prMsgChReq->eRfSco = prAisFsmInfo->prTargetBssDesc->eSco; ++ prMsgChReq->eRfBand = prAisFsmInfo->prTargetBssDesc->eBand; ++ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prAisFsmInfo->prTargetBssDesc->aucBSSID); ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ ++ prAisFsmInfo->fgIsChannelRequested = TRUE; ++ break; ++ ++ case AIS_STATE_JOIN: ++ aisFsmStateInit_JOIN(prAdapter, prAisFsmInfo->prTargetBssDesc); ++ break; ++ ++#if CFG_SUPPORT_ADHOC ++ case AIS_STATE_IBSS_ALONE: ++ aisFsmStateInit_IBSS_ALONE(prAdapter); ++ break; ++ ++ case AIS_STATE_IBSS_MERGE: ++ aisFsmStateInit_IBSS_MERGE(prAdapter, prAisFsmInfo->prTargetBssDesc); ++ break; ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ case AIS_STATE_NORMAL_TR: ++ if (prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { ++ /* Don't do anything when rJoinTimeoutTimer is still ticking */ ++ } else { ++ /* 1. Process for pending scan */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { ++ wlanClearScanningResult(prAdapter); ++ eNextState = AIS_STATE_ONLINE_SCAN; ++ fgIsTransition = TRUE; ++ } ++ /* 2. Process for pending roaming scan */ ++ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE) == TRUE) { ++ eNextState = AIS_STATE_LOOKING_FOR; ++ fgIsTransition = TRUE; ++ } ++ /* 3. Process for pending roaming scan */ ++ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE) == TRUE) { ++ eNextState = AIS_STATE_SEARCH; ++ fgIsTransition = TRUE; ++ } else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE) == ++ TRUE) { ++ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ break; ++ ++ case AIS_STATE_DISCONNECTING: ++ /* send for deauth frame for disconnection */ ++ authSendDeauthFrame(prAdapter, ++ prAisBssInfo->prStaRecOfAP, ++ (P_SW_RFB_T) NULL, REASON_CODE_DEAUTH_LEAVING_BSS, aisDeauthXmitComplete); ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer, 100); ++ break; ++ ++ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: ++ /* send message to CNM for acquiring channel */ ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ return; ++ } ++ ++ /* zero-ize */ ++ kalMemZero(prMsgChReq, sizeof(MSG_CH_REQ_T)); ++ ++ /* filling */ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++ prMsgChReq->u4MaxInterval = prAisFsmInfo->rChReqInfo.u4DurationMs; ++ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->rChReqInfo.ucChannelNum; ++ prMsgChReq->eRfSco = prAisFsmInfo->rChReqInfo.eSco; ++ prMsgChReq->eRfBand = prAisFsmInfo->rChReqInfo.eBand; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ ++ prAisFsmInfo->fgIsChannelRequested = TRUE; ++ ++ break; ++ ++ case AIS_STATE_REMAIN_ON_CHANNEL: ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ /* sync with firmware */ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ break; ++ ++ default: ++ ASSERT(0); /* Make sure we have handle all STATEs */ ++ break; ++ ++ } ++ } while (fgIsTransition); ++ ++ return; ++ ++} /* end of aisFsmSteps() */ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState) ++{ ++ /*get scan channel infro from prAdapter->prGlueInfo->prScanRequest*/ ++ struct cfg80211_scan_request *scan_req_t = NULL; ++ struct ieee80211_channel *channel_tmp = NULL; ++ int i = 0; ++ int j = 0; ++ UINT_8 channel_num = 0; ++ UINT_8 channel_counts = 0; ++ ++ if ((prAdapter == NULL) || (ScanReqMsg == NULL)) ++ return; ++ if ((CurrentState == AIS_STATE_SCAN) || (CurrentState == AIS_STATE_ONLINE_SCAN)) { ++ if (prAdapter->prGlueInfo->prScanRequest != NULL) { ++ scan_req_t = prAdapter->prGlueInfo->prScanRequest; ++ if ((scan_req_t != NULL) && (scan_req_t->n_channels != 0) && ++ (scan_req_t->channels != NULL)) { ++ channel_counts = scan_req_t->n_channels; ++ DBGLOG(AIS, TRACE, "channel_counts=%d\n", channel_counts); ++ ++ while (j < channel_counts) { ++ channel_tmp = scan_req_t->channels[j]; ++ if (channel_tmp == NULL) ++ break; ++ ++ DBGLOG(AIS, TRACE, "set channel band=%d\n", channel_tmp->band); ++ if (channel_tmp->band >= IEEE80211_BAND_60GHZ) { ++ j++; ++ continue; ++ } ++ if (i >= MAXIMUM_OPERATION_CHANNEL_LIST) ++ break; ++ if (channel_tmp->band == IEEE80211_BAND_2GHZ) ++ ScanReqMsg->arChnlInfoList[i].eBand = BAND_2G4; ++ else if (channel_tmp->band == IEEE80211_BAND_5GHZ) ++ ScanReqMsg->arChnlInfoList[i].eBand = BAND_5G; ++ ++ DBGLOG(AIS, TRACE, "set channel channel_rer =%d\n", ++ channel_tmp->center_freq); ++ ++ channel_num = (UINT_8)nicFreq2ChannelNum( ++ channel_tmp->center_freq * 1000); ++ ++ DBGLOG(AIS, TRACE, "set channel channel_num=%d\n", ++ channel_num); ++ ScanReqMsg->arChnlInfoList[i].ucChannelNum = channel_num; ++ ++ j++; ++ i++; ++ } ++ } ++ } ++ } ++ ++ DBGLOG(AIS, INFO, "set channel i=%d\n", i); ++ if (i > 0) { ++ ScanReqMsg->ucChannelListNum = i; ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; ++ ++ return; ++ } ++ ++ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_NULL) { ++ if (prAdapter->fgEnable5GBand == TRUE) ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ else ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_2G4) { ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_5G) { ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; ++ } else { ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ ASSERT(0); ++ } ++ ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ UINT_8 ucSeqNumOfCompMsg; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("aisFsmRunEventScanDone()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ ucScanTimeoutTimes = 0; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ ASSERT(prScanDoneMsg->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX); ++ ++ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ if (ucSeqNumOfCompMsg != prAisFsmInfo->ucSeqNumOfScanReq) { ++ DBGLOG(AIS, WARN, "SEQ NO of AIS SCN DONE MSG is not matched %d %d.\n", ++ ucSeqNumOfCompMsg, prAisFsmInfo->ucSeqNumOfScanReq); ++ } else { ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_SCAN: ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ ++ /* reset scan IE buffer */ ++ prAisFsmInfo->u4ScanIELength = 0; ++ ++ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); ++ eNextState = AIS_STATE_IDLE; ++#if CFG_SUPPORT_AGPS_ASSIST ++ scanReportScanResultToAgps(prAdapter); ++#endif ++ break; ++ ++ case AIS_STATE_ONLINE_SCAN: ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ ++ /* reset scan IE buffer */ ++ prAisFsmInfo->u4ScanIELength = 0; ++ ++ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); ++#if CFG_SUPPORT_ROAMING ++ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); ++#else ++ eNextState = AIS_STATE_NORMAL_TR; ++#endif /* CFG_SUPPORT_ROAMING */ ++#if CFG_SUPPORT_AGPS_ASSIST ++ scanReportScanResultToAgps(prAdapter); ++#endif ++ break; ++ ++ case AIS_STATE_LOOKING_FOR: ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ scanReportBss2Cfg80211(prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); ++#if CFG_SUPPORT_ROAMING ++ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); ++#else ++ eNextState = AIS_STATE_SEARCH; ++#endif /* CFG_SUPPORT_ROAMING */ ++ break; ++ ++ default: ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ break; ++ ++ } ++ } ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmRunEventScanDone() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ UINT_8 ucReasonOfDisconnect; ++ BOOLEAN fgDelayIndication; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("aisFsmRunEventAbort()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> Extract information of Abort Message and then free memory. */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) prMsgHdr; ++ ucReasonOfDisconnect = prAisAbortMsg->ucReasonOfDisconnect; ++ fgDelayIndication = prAisAbortMsg->fgDelayIndication; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++#if DBG ++ DBGLOG(AIS, STATE, "EVENT-ABORT: Current State %s %d\n", ++ apucDebugAisState[prAisFsmInfo->eCurrentState], ucReasonOfDisconnect); ++#else ++ DBGLOG(AIS, STATE, "[%d] EVENT-ABORT: Current State [%d %d]\n", ++ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, ucReasonOfDisconnect); ++#endif ++ ++ GET_CURRENT_SYSTIME(&(prAisFsmInfo->rJoinReqTime)); ++ ++ /* 4 <2> clear previous pending connection request and insert new one */ ++ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DEAUTHENTICATED ++ || ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DISASSOCIATED) { ++ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; ++ } else { ++ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; ++ } ++ /* to support user space triggered roaming */ ++ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING && ++ prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && ++ prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { ++ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); ++ } else { ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_ROAMING_CONNECT); ++ } ++ return; ++ } ++ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ if (prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { ++ /* 4 <3> invoke abort handler */ ++ aisFsmStateAbort(prAdapter, ucReasonOfDisconnect, fgDelayIndication); ++ } ++ ++} /* end of aisFsmRunEventAbort() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function handles AIS-FSM abort event/command ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ucReasonOfDisconnect Reason for disonnection ++* fgDelayIndication Option to delay disconnection indication ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ BOOLEAN fgIsCheckConnected; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ fgIsCheckConnected = FALSE; ++ ++ /* 4 <1> Save information of Abort Message and then free memory. */ ++ prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect; ++ ++ /* 4 <2> Abort current job. */ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IDLE: ++ case AIS_STATE_SEARCH: ++ break; ++ ++ case AIS_STATE_WAIT_FOR_NEXT_SCAN: ++ /* Do cancel timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_SCAN: ++ /* Do abort SCAN */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* queue for later handling */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ ++ break; ++ ++ case AIS_STATE_LOOKING_FOR: ++ /* Do abort SCAN */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_REQ_CHANNEL_JOIN: ++ /* Release channel to CNM */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_JOIN: ++ /* Do abort JOIN */ ++ aisFsmStateAbort_JOIN(prAdapter); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++#if CFG_SUPPORT_ADHOC ++ case AIS_STATE_IBSS_ALONE: ++ case AIS_STATE_IBSS_MERGE: ++ aisFsmStateAbort_IBSS(prAdapter); ++ break; ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ case AIS_STATE_ONLINE_SCAN: ++ /* Do abort SCAN */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* queue for later handling */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_NORMAL_TR: ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_DISCONNECTING: ++ /* Do abort NORMAL_TR */ ++ aisFsmStateAbort_NORMAL_TR(prAdapter); ++ ++ break; ++ ++ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: ++ /* release channel */ ++ aisFsmReleaseCh(prAdapter); ++ break; ++ ++ case AIS_STATE_REMAIN_ON_CHANNEL: ++ /* 1. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2. stop channel timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (fgIsCheckConnected && (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState)) { ++ ++ /* switch into DISCONNECTING state for sending DEAUTH if necessary */ ++ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && ++ prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_NEW_CONNECTION && ++ prAisBssInfo->prStaRecOfAP && prAisBssInfo->prStaRecOfAP->fgIsInUse) { ++ aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING); ++ ++ return; ++ } ++ /* Do abort NORMAL_TR */ ++ aisFsmStateAbort_NORMAL_TR(prAdapter); ++ ++ } ++ ++ aisFsmDisconnect(prAdapter, fgDelayIndication); ++ ++ ++} /* end of aisFsmStateAbort() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Join Complete Event from SAA FSM for AIS FSM ++* ++* @param[in] prMsgHdr Message of Join Complete of SAA FSM. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_JOIN_COMP_T prJoinCompMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prAssocRspSwRfb; ++ P_BSS_INFO_T prAisBssInfo; ++ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; ++ OS_SYSTIME rCurrentTime; ++ ++ DEBUGFUNC("aisFsmRunEventJoinComplete()"); ++ ++ ASSERT(prMsgHdr); ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; ++ prStaRec = prJoinCompMsg->prStaRec; ++ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ DBGLOG(AIS, TRACE, "AISOK\n"); ++ ++ /* Check State and SEQ NUM */ ++ do { ++ if (prAisFsmInfo->eCurrentState != AIS_STATE_JOIN) ++ break; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* Check SEQ NUM */ ++ if (prJoinCompMsg->ucSeqNum == prAisFsmInfo->ucSeqNumOfReqMsg) { ++ ++ /* 4 <1> JOIN was successful */ ++ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { ++ ++ /* 1. Reset retry count */ ++ prAisFsmInfo->ucConnTrialCount = 0; ++ ++ /* Completion of roaming */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ ++#if CFG_SUPPORT_ROAMING ++ /* 2. Deactivate previous BSS */ ++ aisFsmRoamingDisconnectPrevAP(prAdapter, prStaRec); ++ ++ /* 3. Update bss based on roaming staRec */ ++ aisUpdateBssInfoForRoamingAP(prAdapter, prStaRec, prAssocRspSwRfb); ++#endif /* CFG_SUPPORT_ROAMING */ ++ } else { ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if ((prAisBssInfo->prStaRecOfAP) && ++ (prAisBssInfo->prStaRecOfAP != prStaRec) && ++ (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { ++ ++ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, ++ STA_STATE_1); ++ } ++ /* 4 <1.3> Update BSS_INFO_T */ ++ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); ++ ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ /* 4 <1.5> Update RSSI if necessary */ ++ nicUpdateRSSI(prAdapter, NETWORK_TYPE_AIS_INDEX, ++ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); ++ ++ /* 4 <1.6> Indicate Connected Event to Host immediately. */ ++ /* Require BSSID, Association ID, Beacon Interval.. */ ++ /* from AIS_BSS_INFO_T */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, ++ FALSE); ++ ++ /* add for ctia mode */ ++ if (EQUAL_SSID ++ (aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, ++ prAisBssInfo->ucSSIDLen)) { ++ nicEnterCtiaMode(prAdapter, TRUE, FALSE); ++ } ++ } ++ ++#if CFG_SUPPORT_ROAMING ++ /* if bssid is given, it means we no need fw roaming */ ++ if (prAdapter->rWifiVar.rConnSettings.eConnectionPolicy != CONNECT_BY_BSSID) ++ roamingFsmRunEventStart(prAdapter); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* 4 <1.7> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ } ++ /* 4 <2> JOIN was not successful */ ++ else { ++ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ ++ if (aisFsmStateInit_RetryJOIN(prAdapter, prStaRec) == FALSE) { ++ P_BSS_DESC_T prBssDesc; ++ ++ /* 1. Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ /* 2. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 3.1 stop join timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ ++ /* 3.2 reset local variable */ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prStaRec->aucMacAddr); ++ ++ if (prBssDesc == NULL) { ++ /* it maybe NULL when wlanRemove */ ++ /* ++ (1) UI does wifi off during SAA does auth/assoc procedure. ++ (2) We will do LINK_INITIALIZE(&prScanInfo->rBSSDescList); ++ in nicUninitMGMT(). ++ (3) We will handle prMsduInfo->pfTxDoneHandler ++ in nicTxRelease(). ++ (4) prMsduInfo->pfTxDoneHandler will point to ++ saaFsmRunEventTxDone(). ++ (5) Then jump to saaFsmSteps() -> saaFsmSendEventJoinComplete() ++ (6) Finally mboxSendMsg() -> aisFsmRunEventJoinComplete(). ++ (7) In aisFsmRunEventJoinComplete(), we will check ++ "prBssDesc = scanSearchBssDescByBssid(prAdapter, ++ prStaRec->aucMacAddr);" ++ (8) And prBssDesc will be NULL and hangs in ++ "ASSERT(prBssDesc->fgIsConnecting);" when DBG=0. ++ ASSERT(prBssDesc); ++ ASSERT(prBssDesc->fgIsConnecting); ++ */ ++ break; ++ } ++ /* ASSERT(prBssDesc); */ ++ /* ASSERT(prBssDesc->fgIsConnecting); */ ++ prBssDesc->ucJoinFailureCount++; ++ if (prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { ++ GET_CURRENT_SYSTIME(&prBssDesc->rJoinFailTime); ++ DBGLOG(AIS, INFO, ++ "Bss %pM join fail %d times,temp disable it at time:%u\n", ++ prBssDesc->aucBSSID, ++ SCN_BSS_JOIN_FAIL_THRESOLD, prBssDesc->rJoinFailTime); ++ } ++ ++ if (prBssDesc) ++ prBssDesc->fgIsConnecting = FALSE; ++ ++ /* 3.3 Free STA-REC */ ++ if (prStaRec != prAisBssInfo->prStaRecOfAP) ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++#if CFG_SUPPORT_ROAMING ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++#endif /* CFG_SUPPORT_ROAMING */ ++ } else if (CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, ++ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { ++ /* abort connection trial */ ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_CONNECT_INDICATION, NULL, 0); ++ ++ eNextState = AIS_STATE_IDLE; ++ } else { ++ /* 4.b send reconnect request */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ eNextState = AIS_STATE_IDLE; ++ } ++ } ++ } ++ } ++#if DBG ++ else ++ DBGLOG(AIS, WARN, "SEQ NO of AIS JOIN COMP MSG is not matched.\n"); ++#endif /* DBG */ ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ } while (FALSE); ++ ++ if (prAssocRspSwRfb) ++ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* end of aisFsmRunEventJoinComplete() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Grant Msg of IBSS Create which was sent by ++* CNM to indicate that channel was changed for creating IBSS. ++* ++* @param[in] prAdapter Pointer of ADAPTER_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ do { ++ /* Check State */ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_IBSS_ALONE) ++ aisUpdateBssInfoForCreateIBSS(prAdapter); ++ } while (FALSE); ++ ++} /* end of aisFsmCreateIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Grant Msg of IBSS Merge which was sent by ++* CNM to indicate that channel was changed for merging IBSS. ++* ++* @param[in] prAdapter Pointer of ADAPTER_T ++* @param[in] prStaRec Pointer of STA_RECORD_T for merge ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ do { ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IBSS_MERGE: ++ { ++ P_BSS_DESC_T prBssDesc; ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous Peers' STA_RECORD_T in Driver if have. */ ++ bssClearClientList(prAdapter, prAisBssInfo); ++ ++ /* 4 <1.3> Unmark connection flag of previous BSS_DESC_T. */ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ if (prBssDesc != NULL) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = FALSE; ++ } ++ /* 4 <1.4> Update BSS_INFO_T */ ++ aisUpdateBssInfoForMergeIBSS(prAdapter, prStaRec); ++ ++ /* 4 <1.5> Add Peers' STA_RECORD_T to Client List */ ++ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); ++ ++ /* 4 <1.6> Activate current Peer's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ prStaRec->fgIsMerging = FALSE; ++ ++ /* 4 <1.7> Enable other features */ ++ ++ /* 4 <1.8> Indicate Connected Event to Host immediately. */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); ++ ++ /* 4 <1.9> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ ++ /* 4 <1.10> Release channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ ++#if CFG_SLT_SUPPORT ++ prAdapter->rWifiVar.rSltInfo.prPseudoStaRec = prStaRec; ++#endif ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++ } while (FALSE); ++ ++} /* end of aisFsmMergeIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Notification of existing IBSS was found ++* from SCN. ++* ++* @param[in] prMsgHdr Message of Notification of an IBSS was present. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prAisBssInfo; ++ P_BSS_DESC_T prBssDesc; ++ BOOLEAN fgIsMergeIn; ++ ++ ASSERT(prMsgHdr); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) prMsgHdr; ++ ++ ASSERT(prAisIbssPeerFoundMsg->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX); ++ ++ prStaRec = prAisIbssPeerFoundMsg->prStaRec; ++ ASSERT(prStaRec); ++ ++ fgIsMergeIn = prAisIbssPeerFoundMsg->fgIsMergeIn; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IBSS_ALONE: ++ { ++ /* 4 <1> An IBSS Peer 'merged in'. */ ++ if (fgIsMergeIn) { ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Add Peers' STA_RECORD_T to Client List */ ++ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); ++ ++#if CFG_SLT_SUPPORT ++ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ if (prBssDesc != NULL) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ } else { ++ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ ++ } ++ ++ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ ++#else ++ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ if (prBssDesc != NULL) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ } else { ++ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ ++ } ++ ++ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ ++ ++#endif ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ prStaRec->fgIsMerging = FALSE; ++ ++ /* 4 <1.6> sync. to firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <1.7> Indicate Connected Event to Host immediately. */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); ++ ++ /* 4 <1.8> indicate PM for connected */ ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <1.9> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ ++ /* 4 <1.10> Release channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ } ++ /* 4 <2> We need 'merge out' to this IBSS */ ++ else { ++ ++ /* 4 <2.1> Get corresponding BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* 4 <2.2> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_IBSS_MERGE; ++ } ++ } ++ break; ++ ++ case AIS_STATE_NORMAL_TR: ++ { ++ ++ /* 4 <3> An IBSS Peer 'merged in'. */ ++ if (fgIsMergeIn) { ++ ++ /* 4 <3.1> Add Peers' STA_RECORD_T to Client List */ ++ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); ++ ++#if CFG_SLT_SUPPORT ++ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ ++#else ++ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ ++#endif ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ prStaRec->fgIsMerging = FALSE; ++ ++ } ++ /* 4 <4> We need 'merge out' to this IBSS */ ++ else { ++ ++ /* 4 <4.1> Get corresponding BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* 4 <4.2> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_IBSS_MERGE; ++ ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmRunEventFoundIBSSPeer() */ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Media State to HOST ++* ++* @param[in] eConnectionState Current Media State ++* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication) ++{ ++ EVENT_CONNECTION_STATUS rEventConnStatus; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ DEBUGFUNC("aisIndicationOfMediaStateToHost()"); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* NOTE(Kevin): Move following line to aisChangeMediaState() macro per CM's request. */ ++ /* prAisBssInfo->eConnectionState = eConnectionState; */ ++ ++ /* For indicating the Disconnect Event only if current media state is ++ * disconnected and we didn't do indication yet. ++ */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ if (prAisBssInfo->eConnectionStateIndicated == eConnectionState) ++ return; ++ } ++ ++ if (!fgDelayIndication) { ++ /* 4 <0> Cancel Delay Timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); ++ ++ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ ++ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; ++ ++ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; ++ ++ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; ++ rEventConnStatus.u2AID = prAisBssInfo->u2AssocId; ++ rEventConnStatus.u2ATIMWindow = 0; ++ } else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; ++ rEventConnStatus.u2AID = 0; ++ rEventConnStatus.u2ATIMWindow = prAisBssInfo->u2ATIMWindow; ++ } else { ++ ASSERT(0); ++ } ++ ++ COPY_SSID(rEventConnStatus.aucSsid, ++ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prAisBssInfo->aucBSSID); ++ ++ rEventConnStatus.u2BeaconPeriod = prAisBssInfo->u2BeaconInterval; ++ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prAisBssInfo->ucPrimaryChannel); ++ ++ switch (prAisBssInfo->ucNonHTBasicPhyType) { ++ case PHY_TYPE_HR_DSSS_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ ++ case PHY_TYPE_ERP_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; ++ break; ++ ++ case PHY_TYPE_OFDM_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; ++ break; ++ ++ default: ++ ASSERT(0); ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ } ++ } else { ++ /* Deactivate previous Peers' STA_RECORD_T in Driver if have. */ ++ bssClearClientList(prAdapter, prAisBssInfo); ++ ++#if CFG_PRIVACY_MIGRATION ++ /* Clear the pmkid cache while media disconnect */ ++ secClearPmkid(prAdapter); ++#endif ++ ++ rEventConnStatus.ucReasonOfDisconnect = prAisBssInfo->ucReasonOfDisconnect; ++ } ++ ++ /* 4 <2> Indication */ ++ nicMediaStateChange(prAdapter, NETWORK_TYPE_AIS_INDEX, &rEventConnStatus); ++ prAisBssInfo->eConnectionStateIndicated = eConnectionState; ++ } else { ++ /* NOTE: Only delay the Indication of Disconnect Event */ ++ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ DBGLOG(AIS, INFO, "Postpone the indication of Disconnect for %d seconds\n", ++ prConnSettings->ucDelayTimeOfDisconnectEvent); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prAisFsmInfo->rIndicationOfDisconnectTimer, ++ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); ++ } ++ ++} /* end of aisIndicationOfMediaStateToHost() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if (prAisBssInfo->prStaRecOfAP) { ++ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ ++ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ } ++ /* 4 <2> Remove pending connection request */ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); ++ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; ++ prAisBssInfo->u2DeauthReason = REASON_CODE_BEACON_TIMEOUT; ++ /* 4 <3> Indicate Disconnected Event to Host immediately. */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE); ++ ++} /* end of aisPostponedEventOfDisconnTimeout() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the association was completed. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ P_BSS_DESC_T prBssDesc; ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ ++ DEBUGFUNC("aisUpdateBssInfoForJOIN()"); ++ ++ ASSERT(prStaRec); ++ ASSERT(prAssocRspSwRfb); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; ++ ++ DBGLOG(AIS, TRACE, "Update AIS_BSS_INFO_T and apply settings to MAC\n"); ++ ++ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ /* 4 <1.3> Setup Channel, Band */ ++ prAisBssInfo->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; ++ prAisBssInfo->eBand = prAisFsmInfo->prTargetBssDesc->eBand; ++ ++ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ ++ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ ++ prAisBssInfo->prStaRecOfAP = prStaRec; ++ prAisBssInfo->u2AssocId = prStaRec->u2AssocId; ++ ++ /* 4 <2.2> Setup Capability */ ++ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ ++ ++ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) ++ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; ++ else ++ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* init the TDLS flags */ ++ prAisBssInfo->fgTdlsIsProhibited = prStaRec->fgTdlsIsProhibited; ++ prAisBssInfo->fgTdlsIsChSwProhibited = prStaRec->fgTdlsIsChSwProhibited; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ ++ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; ++ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ ++ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ ++ /* 4 <3.1> Setup BSSID */ ++ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); ++ ++ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - ++ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); ++ pucIE = prAssocRspFrame->aucInfoElem; ++ ++ /* 4 <3.2> Parse WMM and setup QBSS flag */ ++ /* Parse WMM related IEs and configure HW CRs accordingly */ ++ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ prAisBssInfo->fgIsQBSS = prStaRec->fgIsQoS; ++ ++ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAssocRspFrame->aucBSSID); ++ if (prBssDesc) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ prBssDesc->ucJoinFailureCount = 0; ++ ++ /* 4 <4.1> Setup MIB for current BSS */ ++ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ } else { ++ /* should never happen */ ++ ASSERT(0); ++ } ++ ++ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ ++ prAisBssInfo->ucDTIMPeriod = 0; ++ prAisBssInfo->u2ATIMWindow = 0; ++ ++ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; ++ ++ /* 4 <4.2> Update HT information and set channel */ ++ /* Record HT related parameters in rStaRec and rBssInfo ++ * Note: it shall be called before nicUpdateBss() ++ */ ++ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ /* 4 <4.3> Sync with firmware for BSS-INFO */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ ++ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ ++ ++} /* end of aisUpdateBssInfoForJOIN() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will create an Ad-Hoc network and start sending Beacon Frames. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ if (prAisBssInfo->fgIsBeaconActivated) ++ return; ++ /* 3 <1> Update BSS_INFO_T per Network Basis */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prAisBssInfo->u2AssocId = 0; ++ ++ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ ++ prAisBssInfo->ucPrimaryChannel = prConnSettings->ucAdHocChannelNum; ++ prAisBssInfo->eBand = prConnSettings->eAdHocBand; ++ ++ if (prAisBssInfo->eBand == BAND_2G4) { ++ /* Depend on eBand */ ++ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG; ++ } else { ++ /* Depend on eBand */ ++ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A; ++ } ++ ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prAisBssInfo->u2BeaconInterval = prConnSettings->u2BeaconPeriod; ++ prAisBssInfo->ucDTIMPeriod = 0; ++ prAisBssInfo->u2ATIMWindow = prConnSettings->u2AtimWindow; ++ ++ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; ++ ++#if CFG_PRIVACY_MIGRATION ++ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED || ++ prConnSettings->eEncStatus == ENUM_ENCRYPTION2_ENABLED || ++ prConnSettings->eEncStatus == ENUM_ENCRYPTION3_ENABLED) { ++ prAisBssInfo->fgIsProtection = TRUE; ++ } else { ++ prAisBssInfo->fgIsProtection = FALSE; ++ } ++#else ++ prAisBssInfo->fgIsProtection = FALSE; ++#endif ++ ++ /* 3 <2> Update BSS_INFO_T common part */ ++ ibssInitForAdHoc(prAdapter, prAisBssInfo); ++ ++ /* 3 <3> Set MAC HW */ ++ /* 4 <3.1> Setup channel and bandwidth */ ++ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); ++ ++ /* 4 <3.2> use command packets to inform firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <3.3> enable beaconing */ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <3.4> Update AdHoc PM parameter */ ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 3 <4> Set ACTIVE flag. */ ++ prAisBssInfo->fgIsBeaconActivated = TRUE; ++ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; ++ ++ /* 3 <5> Start IBSS Alone Timer */ ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); ++ ++ return; ++ ++} /* end of aisCreateIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the existing IBSS was found. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_DESC_T prBssDesc; ++ /* UINT_16 u2IELength; */ ++ /* PUINT_8 pucIE; */ ++ ++ ASSERT(prStaRec); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); ++ ++ if (!prAisBssInfo->fgIsBeaconActivated) { ++ ++ /* 3 <1> Update BSS_INFO_T per Network Basis */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prAisBssInfo->aucSSID, ++ prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prAisBssInfo->u2AssocId = 0; ++ } ++ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ ++ /* 4 <2.1> Setup Capability */ ++ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use Peer's Cap Info as IBSS Cap Info */ ++ ++ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) { ++ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; ++ prAisBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prAisBssInfo->fgUseShortPreamble = FALSE; ++ } ++ ++ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ ++ prAisBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ ++ prAisBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; ++ ++ if (prAisBssInfo->u2CapInfo & CAP_INFO_PRIVACY) ++ prAisBssInfo->fgIsProtection = TRUE; ++ else ++ prAisBssInfo->fgIsProtection = FALSE; ++ ++ /* 4 <2.2> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ ++ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; ++ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ ++ rateGetDataRatesFromRateSet(prAisBssInfo->u2OperationalRateSet, ++ prAisBssInfo->u2BSSBasicRateSet, ++ prAisBssInfo->aucAllSupportedRates, &prAisBssInfo->ucAllSupportedRatesLen); ++ ++ /* 3 <3> X Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ ++ ++ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ if (prBssDesc) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ ++ /* 4 <4.1> Setup BSSID */ ++ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prBssDesc->aucBSSID); ++ ++ /* 4 <4.2> Setup Channel, Band */ ++ prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; ++ prAisBssInfo->eBand = prBssDesc->eBand; ++ ++ /* 4 <4.3> Setup MIB for current BSS */ ++ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ prAisBssInfo->ucDTIMPeriod = 0; ++ prAisBssInfo->u2ATIMWindow = 0; /* TBD(Kevin) */ ++ ++ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; ++ } else { ++ /* should never happen */ ++ ASSERT(0); ++ } ++ ++ /* 3 <5> Set MAC HW */ ++ /* 4 <5.1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ ++ { ++ UINT_8 ucLowestBasicRateIndex; ++ ++ if (!rateGetLowestRateIndexFromRateSet(prAisBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) { ++ ++ if (prAisBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_OFDM) ++ ucLowestBasicRateIndex = RATE_6M_INDEX; ++ else ++ ucLowestBasicRateIndex = RATE_1M_INDEX; ++ } ++ ++ prAisBssInfo->ucHwDefaultFixedRateCode = ++ aucRateIndex2RateCode[prAisBssInfo->fgUseShortPreamble][ucLowestBasicRateIndex]; ++ } ++ ++ /* 4 <5.2> Setup channel and bandwidth */ ++ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); ++ ++ /* 4 <5.3> use command packets to inform firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <5.4> enable beaconing */ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <5.5> Update AdHoc PM parameter */ ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 3 <6> Set ACTIVE flag. */ ++ prAisBssInfo->fgIsBeaconActivated = TRUE; ++ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; ++ ++} /* end of aisUpdateBssInfoForMergeIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ BOOLEAN fgReplyProbeResp = FALSE; ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu4ControlFlags); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) prSwRfb->pvHeader + prSwRfb->u2HeaderLen; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_SSID == IE_ID(pucIE)) { ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* 4 <2> Check network conditions */ ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ ++ if ((prIeSsid) && ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, /* CURRENT SSID */ ++ prIeSsid->aucSSID, prIeSsid->ucLength))) { ++ fgReplyProbeResp = TRUE; ++ } ++ } ++ ++ return fgReplyProbeResp; ++ ++} /* end of aisValidateProbeReq() */ ++ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will modify and update necessary information to firmware ++* for disconnection handling ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* ++* @retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++#if CFG_SUPPORT_ADHOC ++ if (prAisBssInfo->fgIsBeaconActivated) { ++ nicUpdateBeaconIETemplate(prAdapter, IE_UPD_METHOD_DELETE_ALL, NETWORK_TYPE_AIS_INDEX, 0, NULL, 0); ++ ++ prAisBssInfo->fgIsBeaconActivated = FALSE; ++ } ++#endif ++ ++ rlmBssAborted(prAdapter, prAisBssInfo); ++ ++ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ ++ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { ++ /* add for ctia mode */ ++ { ++ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; ++ ++ if (EQUAL_SSID(aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) ++ nicEnterCtiaMode(prAdapter, FALSE, FALSE); ++ } ++ ++ if (prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_RADIO_LOST) { ++ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ ++ /* remove from scanning results as well */ ++ wlanClearBssInScanningResult(prAdapter, prAisBssInfo->aucBSSID); ++ ++ /* trials for re-association */ ++ if (fgDelayIndication) { ++ DBGLOG(AIS, INFO, "try to do re-association due to radio lost!\n"); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ } ++ } else { ++ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ } ++ ++ if (fgDelayIndication) { ++ if (OP_MODE_IBSS != prAisBssInfo->eCurrentOPMode) ++ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; ++ } else { ++ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; ++ } ++ } else { ++ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; ++ } ++ ++ /* 4 <4> Change Media State immediately. */ ++ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION) { ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ /* 4 <4.1> sync. with firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ } ++ ++ if (!fgDelayIndication) { ++ /* 4 <5> Deactivate previous AP's STA_RECORD_T or all Clients in Driver if have. */ ++ if (prAisBssInfo->prStaRecOfAP) { ++ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ ++ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ } ++ } ++#if CFG_SUPPORT_ROAMING ++ roamingFsmRunEventAbort(prAdapter); ++ ++ /* clear pending roaming connection request */ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* 4 <6> Indicate Disconnected Event to Host */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, fgDelayIndication); ++ ++ /* 4 <7> Trigger AIS FSM */ ++ aisFsmSteps(prAdapter, AIS_STATE_IDLE); ++ ++} /* end of aisFsmDisconnect() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of Scan done Time-Out to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 IsrCnt = 0, IsrPassCnt = 0, TaskIsrCnt = 0; ++VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++#define SCAN_DONE_TIMEOUT_TIMES_LIMIT 20 ++ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4FwCnt; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DEBUGFUNC("aisFsmRunEventScanDoneTimeOut()"); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ HifInfo = &prAdapter->prGlueInfo->rHifInfo; ++ ++ DBGLOG(AIS, WARN, "aisFsmRunEventScanDoneTimeOut Current[%d], ucScanTimeoutTimes=%d\n", ++ prAisFsmInfo->eCurrentState, ucScanTimeoutTimes); ++ DBGLOG(AIS, WARN, "Isr/task %u %u %u (0x%x)\n", prGlueInfo->IsrCnt, prGlueInfo->IsrPassCnt, ++ prGlueInfo->TaskIsrCnt, prAdapter->fgIsIntEnable); ++ ++ /* dump firmware program counter */ ++ DBGLOG(AIS, WARN, "CONNSYS FW CPUINFO:\n"); ++ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) ++ DBGLOG(AIS, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); ++ ++ ucScanTimeoutTimes++; ++ if (ucScanTimeoutTimes > SCAN_DONE_TIMEOUT_TIMES_LIMIT) { ++ kalSendAeeWarning("[Scan done timeout more than 20 times!]", __func__); ++ glDoChipReset(); ++ } ++#if 0 /* ALPS02018734: remove trigger assert */ ++ if (prAdapter->fgTestMode == FALSE) { ++ /* Titus - xxx */ ++ /* assert if and only if in normal mode */ ++ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); ++ } ++#endif ++ /* report all scanned frames to upper layer to avoid scanned frame is timeout */ ++ /* must be put before kalScanDone */ ++/* scanReportBss2Cfg80211(prAdapter,BSS_TYPE_INFRASTRUCTURE,NULL); */ ++ ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_SCAN: ++ prAisFsmInfo->u4ScanIELength = 0; ++ eNextState = AIS_STATE_IDLE; ++ break; ++ case AIS_STATE_ONLINE_SCAN: ++ /* reset scan IE buffer */ ++ prAisFsmInfo->u4ScanIELength = 0; ++#if CFG_SUPPORT_ROAMING ++ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); ++#else ++ eNextState = AIS_STATE_NORMAL_TR; ++#endif /* CFG_SUPPORT_ROAMING */ ++ break; ++ default: ++ break; ++ } ++ ++ /* try to stop scan in CONNSYS */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* wlanQueryDebugCode(prAdapter); */ /* display current SCAN FSM in FW, debug use */ ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmBGSleepTimeout() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Background Scan Time-Out" to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ ++ DEBUGFUNC("aisFsmRunEventBGSleepTimeOut()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_WAIT_FOR_NEXT_SCAN: ++ DBGLOG(AIS, LOUD, "EVENT - SCAN TIMER: Idle End - Current Time = %u\n", kalGetTimeTick()); ++ ++ eNextState = AIS_STATE_LOOKING_FOR; ++ ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Call aisFsmSteps() when we are going to change AIS STATE */ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmBGSleepTimeout() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "IBSS ALONE Time-Out" to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ ++ DEBUGFUNC("aisFsmRunEventIbssAloneTimeOut()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IBSS_ALONE: ++ ++ /* There is no one participate in our AdHoc during this TIMEOUT Interval ++ * so go back to search for a valid IBSS again. ++ */ ++ ++ DBGLOG(AIS, LOUD, "EVENT-IBSS ALONE TIMER: Start pairing\n"); ++ ++ prAisFsmInfo->fgTryScan = TRUE; ++ ++ /* abort timer */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* Pull back to SEARCH to find candidate again */ ++ eNextState = AIS_STATE_SEARCH; ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Call aisFsmSteps() when we are going to change AIS STATE */ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisIbssAloneTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Join Time-Out" to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ OS_SYSTIME rCurrentTime; ++ ++ DEBUGFUNC("aisFsmRunEventJoinTimeout()"); ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_JOIN: ++ DBGLOG(AIS, LOUD, "EVENT- JOIN TIMEOUT\n"); ++ ++ /* 1. Do abort JOIN */ ++ aisFsmStateAbort_JOIN(prAdapter); ++ ++ /* 2. Increase Join Failure Count */ ++ prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount++; ++/* For JB nl802.11 */ ++ if (prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) { ++ /* 3.1 Retreat to AIS_STATE_SEARCH state for next try */ ++ eNextState = AIS_STATE_SEARCH; ++ } else if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ } else if (!CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, ++ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { ++ /* 3.3 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ } else { ++ /* 3.4 Retreat to AIS_STATE_JOIN_FAILURE to terminate join operation */ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_CONNECT_INDICATION, NULL, 0); ++ eNextState = AIS_STATE_IDLE; ++ } ++ break; ++ ++ case AIS_STATE_NORMAL_TR: ++ /* 1. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ ++ /* 2. process if there is pending scan */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { ++ wlanClearScanningResult(prAdapter); ++ eNextState = AIS_STATE_ONLINE_SCAN; ++ } ++ ++ break; ++ ++ default: ++ /* release channel */ ++ aisFsmReleaseCh(prAdapter); ++ break; ++ ++ } ++ ++ /* Call aisFsmSteps() when we are going to change AIS STATE */ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmRunEventJoinTimeout() */ ++ ++VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ aisDeauthXmitComplete(prAdapter, NULL, TX_RESULT_LIFE_TIMEOUT); ++} ++ ++#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisTest(VOID) ++{ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_8 aucSSID[] = "pci-11n"; ++ UINT_8 ucSSIDLen = 7; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* Set Connection Request Issued Flag */ ++ prConnSettings->fgIsConnReqIssued = TRUE; ++ prConnSettings->ucSSIDLen = ucSSIDLen; ++ kalMemCopy(prConnSettings->aucSSID, aucSSID, ucSSIDLen); ++ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ return; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_HEM_AIS_FSM_ABORT; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ wifi_send_msg(INDX_WIFI, MSG_ID_WIFI_IST, 0); ++ ++} ++#endif /* CFG_TEST_MGMT_FSM */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle OID_802_11_BSSID_LIST_SCAN ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] prSsid Pointer of SSID_T if specified ++* \param[in] pucIe Pointer to buffer of extra information elements to be attached ++* \param[in] u4IeLength Length of information elements ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ DEBUGFUNC("aisFsmScanRequest()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(u4IeLength <= MAX_IE_LENGTH); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ if (!prConnSettings->fgIsScanReqIssued) { ++ prConnSettings->fgIsScanReqIssued = TRUE; ++ ++ if (prSsid == NULL) { ++ prAisFsmInfo->ucScanSSIDLen = 0; ++ } else { ++ COPY_SSID(prAisFsmInfo->aucScanSSID, ++ prAisFsmInfo->ucScanSSIDLen, prSsid->aucSsid, (UINT_8) prSsid->u4SsidLen); ++ } ++ ++ if (u4IeLength > 0 && u4IeLength <= MAX_IE_LENGTH) { ++ prAisFsmInfo->u4ScanIELength = u4IeLength; ++ kalMemCopy(prAisFsmInfo->aucScanIEBuf, pucIe, u4IeLength); ++ } else { ++ prAisFsmInfo->u4ScanIELength = 0; ++ } ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { ++ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE ++ && prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { ++ /* 802.1x might not finished yet, pend it for later handling .. */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ } else { ++ if (prAisFsmInfo->fgIsChannelGranted == TRUE) { ++ DBGLOG(AIS, WARN, ++ "Scan Request with channel granted for join operation: %d, %d", ++ prAisFsmInfo->fgIsChannelGranted, prAisFsmInfo->fgIsChannelRequested); ++ } ++ ++ /* start online scan */ ++ wlanClearScanningResult(prAdapter); ++ aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN); ++ } ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) { ++ wlanClearScanningResult(prAdapter); ++ aisFsmSteps(prAdapter, AIS_STATE_SCAN); ++ } else { ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ } ++ } else { ++ DBGLOG(AIS, WARN, "Scan Request dropped. (state: %d)\n", prAisFsmInfo->eCurrentState); ++ } ++ ++} /* end of aisFsmScanRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is invoked when CNM granted channel privilege ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_CH_GRANT_T prMsgChGrant; ++ UINT_8 ucTokenID; ++ UINT_32 u4GrantInterval; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; ++ ++ ucTokenID = prMsgChGrant->ucTokenID; ++ u4GrantInterval = prMsgChGrant->u4GrantInterval; ++ ++ /* 1. free message */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { ++ /* 2. channel privilege has been approved */ ++ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; ++ ++ /* 3. state transition to join/ibss-alone/ibss-merge */ ++ /* 3.1 set timeout timer in cases join could not be completed */ ++ cnmTimerStartTimer(prAdapter, ++ &prAisFsmInfo->rJoinTimeoutTimer, ++ prAisFsmInfo->u4ChGrantedInterval - AIS_JOIN_CH_GRANT_THRESHOLD); ++ /* 3.2 set local variable to indicate join timer is ticking */ ++ prAisFsmInfo->fgIsInfraChannelFinished = FALSE; ++ ++ /* 3.3 switch to join state */ ++ aisFsmSteps(prAdapter, AIS_STATE_JOIN); ++ ++ prAisFsmInfo->fgIsChannelGranted = TRUE; ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL && ++ prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { ++ /* 2. channel privilege has been approved */ ++ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; ++ ++ /* 3.1 set timeout timer in cases upper layer cancel_remain_on_channel never comes */ ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer, prAisFsmInfo->u4ChGrantedInterval); ++ ++ /* 3.2 switch to remain_on_channel state */ ++ aisFsmSteps(prAdapter, AIS_STATE_REMAIN_ON_CHANNEL); ++ ++ /* 3.3. indicate upper layer for channel ready */ ++ kalReadyOnChannel(prAdapter->prGlueInfo, ++ prAisFsmInfo->rChReqInfo.u8Cookie, ++ prAisFsmInfo->rChReqInfo.eBand, ++ prAisFsmInfo->rChReqInfo.eSco, ++ prAisFsmInfo->rChReqInfo.ucChannelNum, prAisFsmInfo->rChReqInfo.u4DurationMs); ++ ++ prAisFsmInfo->fgIsChannelGranted = TRUE; ++ } else { /* mismatched grant */ ++ /* 2. return channel privilege to CNM immediately */ ++ aisFsmReleaseCh(prAdapter); ++ } ++ ++} /* end of aisFsmRunEventChGrant() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform CNM that channel privilege ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_CH_ABORT_T prMsgChAbort; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ if (prAisFsmInfo->fgIsChannelGranted == TRUE || prAisFsmInfo->fgIsChannelRequested == TRUE) { ++ ++ prAisFsmInfo->fgIsChannelRequested = FALSE; ++ prAisFsmInfo->fgIsChannelGranted = FALSE; ++ ++ /* 1. return channel privilege to CNM immediately */ ++ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); ++ if (!prMsgChAbort) { ++ ASSERT(0); /* Can't release Channel to CNM */ ++ return; ++ } ++ ++ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; ++ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prMsgChAbort->ucTokenID = prAisFsmInfo->ucSeqNumOfChReq; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); ++ } ++ ++} /* end of aisFsmReleaseCh() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform AIS that corresponding beacon has not ++* been received for a while and probing is not successful ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ BOOLEAN fgDoAbortIndication = FALSE; ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> Diagnose Connection for Beacon Timeout Event */ ++ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { ++ if (OP_MODE_INFRASTRUCTURE == prAisBssInfo->eCurrentOPMode) { ++ P_STA_RECORD_T prStaRec = prAisBssInfo->prStaRecOfAP; ++ ++ if (prStaRec) ++ fgDoAbortIndication = TRUE; ++ } else if (OP_MODE_IBSS == prAisBssInfo->eCurrentOPMode) { ++ fgDoAbortIndication = TRUE; ++ } ++ } ++ /* 4 <2> invoke abort handler */ ++ if (fgDoAbortIndication) { ++#if 0 ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; ++#endif ++ ++ DBGLOG(AIS, INFO, "Beacon Timeout, Remove BSS [%pM]\n", prAisBssInfo->aucBSSID); ++ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ ++ /* ++ Note: Cannot change TRUE to FALSE; or you will suffer the problem in ++ ALPS01270257/ ALPS01804173 ++ */ ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, TRUE); ++ } ++ ++} /* end of aisBssBeaconTimeout() */ ++ ++VOID aisBssSecurityChanged(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ prAdapter->rWifiVar.rConnSettings.fgIsDisconnectedByNonRequest = TRUE; ++ prAisBssInfo->u2DeauthReason = REASON_CODE_BSS_SECURITY_CHANGE; ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_DEAUTHENTICATED, FALSE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform AIS that DEAUTH frame has been ++* sent and thus state machine could go ahead ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] prMsduInfo Pointer of MSDU_INFO_T for DEAUTH frame ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer); ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) { ++ if (rTxDoneStatus != TX_RESULT_DROPPED_IN_DRIVER) ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_NEW_CONNECTION, FALSE); ++ } else { ++ DBGLOG(AIS, WARN, "DEAUTH frame transmitted without further handling"); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of aisDeauthXmitComplete() */ ++ ++#if CFG_SUPPORT_ROAMING ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Looking for a candidate due to weak signal" to AIS FSM. ++* ++* @param[in] u4ReqScan Requesting Scan or not ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ENUM_AIS_REQUEST_TYPE_T eAisRequest; ++ ++ DBGLOG(AIS, LOUD, "aisFsmRunEventRoamingDiscovery()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* search candidates by best rssi */ ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ ++#if CFG_SUPPORT_WFD ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ /* Check WFD is running */ ++ P_BSS_INFO_T prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ if (prAdapter->fgIsP2PRegistered && ++ IS_BSS_ACTIVE(prP2pBssInfo) && ++ (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || ++ prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)) { ++ DBGLOG(ROAMING, INFO, "Handle roaming when P2P is GC or GO.\n"); ++ if (prAdapter->rWifiVar.prP2pFsmInfo) { ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ if ((prWfdCfgSettings->ucWfdEnable == 1) && ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { ++ DBGLOG(ROAMING, INFO, "WFD is running. Stop roaming.\n"); ++ roamingFsmRunEventRoam(prAdapter); ++ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); ++ return; ++ } ++ } else { ++ ASSERT(0); ++ } ++ } /* fgIsP2PRegistered */ ++ } ++#endif ++#endif ++ ++ /* results are still new */ ++ if (!u4ReqScan) { ++ roamingFsmRunEventRoam(prAdapter); ++ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; ++ } else { ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN ++ || prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { ++ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; ++ } else { ++ eAisRequest = AIS_REQUEST_ROAMING_SEARCH; ++ } ++ } ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { ++ if (eAisRequest == AIS_REQUEST_ROAMING_SEARCH) ++ aisFsmSteps(prAdapter, AIS_STATE_LOOKING_FOR); ++ else ++ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); ++ } else { ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); ++ ++ aisFsmInsertRequest(prAdapter, eAisRequest); ++ } ++ ++} /* end of aisFsmRunEventRoamingDiscovery() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update the time of ScanDone for roaming and transit to Roam state. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ ++ DBGLOG(AIS, LOUD, "->aisFsmRoamingScanResultsUpdate()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ roamingFsmScanResultsUpdate(prAdapter); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) { ++ roamingFsmRunEventRoam(prAdapter); ++ eNextState = AIS_STATE_SEARCH; ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { ++ eNextState = AIS_STATE_SEARCH; ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { ++ eNextState = AIS_STATE_NORMAL_TR; ++ } ++ ++ return eNextState; ++} /* end of aisFsmRoamingScanResultsUpdate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will modify and update necessary information to firmware ++* for disconnection of last AP before switching to roaming bss. ++* ++* @param IN prAdapter Pointer to the Adapter structure. ++* prTargetStaRec Target of StaRec of roaming ++* ++* @retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ DBGLOG(AIS, LOUD, "aisFsmRoamingDisconnectPrevAP()"); ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* Not invoke rlmBssAborted() here to avoid prAisBssInfo->fg40mBwAllowed ++ * to be reset. RLM related parameters will be reset again when handling ++ * association response in rlmProcessAssocRsp(). 20110413 ++ */ ++ /* rlmBssAborted(prAdapter, prAisBssInfo); */ ++ ++ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ ++ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) ++ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ /* 4 <4> Change Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ /* 4 <4.1> sync. with firmware */ ++ prTargetStaRec->ucNetTypeIndex = 0xff; /* Virtial NetType */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ prTargetStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Virtial NetType */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, prAisBssInfo->aucBSSID, ++ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++} /* end of aisFsmRoamingDisconnectPrevAP() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the roaming was completed. ++* ++* @param IN prAdapter Pointer to the Adapter structure. ++* prStaRec StaRec of roaming AP ++* prAssocRspSwRfb ++* ++* @retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ DBGLOG(AIS, LOUD, "aisUpdateBssInfoForRoamingAP()"); ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if ((prAisBssInfo->prStaRecOfAP) && ++ (prAisBssInfo->prStaRecOfAP != prStaRec) && (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { ++ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); ++ } ++ /* 4 <1.3> Update BSS_INFO_T */ ++ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); ++ ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ /* 4 <1.6> Indicate Connected Event to Host immediately. */ ++ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); ++ ++} /* end of aisFsmRoamingUpdateBss() */ ++ ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Check if there is any pending request and remove it (optional) ++* ++* @param prAdapter ++* eReqType ++* bRemove ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_AIS_REQ_HDR_T prPendingReqHdr, prPendingReqHdrNext; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* traverse through pending request list */ ++ LINK_FOR_EACH_ENTRY_SAFE(prPendingReqHdr, ++ prPendingReqHdrNext, &(prAisFsmInfo->rPendingReqList), rLinkEntry, AIS_REQ_HDR_T) { ++ /* check for specified type */ ++ if (prPendingReqHdr->eReqType == eReqType) { ++ /* check if need to remove */ ++ if (bRemove == TRUE) { ++ LINK_REMOVE_KNOWN_ENTRY(&(prAisFsmInfo->rPendingReqList), ++ &(prPendingReqHdr->rLinkEntry)); ++ ++ cnmMemFree(prAdapter, prPendingReqHdr); ++ } ++ ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Get next pending request ++* ++* @param prAdapter ++* ++* @return P_AIS_REQ_HDR_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_AIS_REQ_HDR_T prPendingReqHdr; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ LINK_REMOVE_HEAD(&(prAisFsmInfo->rPendingReqList), prPendingReqHdr, P_AIS_REQ_HDR_T); ++ ++ return prPendingReqHdr; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Insert a new request ++* ++* @param prAdapter ++* eReqType ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType) ++{ ++ P_AIS_REQ_HDR_T prAisReq; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ prAisReq = (P_AIS_REQ_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(AIS_REQ_HDR_T)); ++ ++ if (!prAisReq) { ++ ASSERT(0); /* Can't generate new message */ ++ return FALSE; ++ } ++ ++ prAisReq->eReqType = eReqType; ++ ++ /* attach request into pending request list */ ++ LINK_INSERT_TAIL(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Flush all pending requests ++* ++* @param prAdapter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_REQ_HDR_T prAisReq; ++ ++ ASSERT(prAdapter); ++ ++ while ((prAisReq = aisFsmGetNextRequest(prAdapter)) != NULL) ++ cnmMemFree(prAdapter, prAisReq); ++ ++} ++ ++VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_REMAIN_ON_CHANNEL_T prRemainOnChannel; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ prRemainOnChannel = (P_MSG_REMAIN_ON_CHANNEL_T) prMsgHdr; ++ ++ /* record parameters */ ++ prAisFsmInfo->rChReqInfo.eBand = prRemainOnChannel->eBand; ++ prAisFsmInfo->rChReqInfo.eSco = prRemainOnChannel->eSco; ++ prAisFsmInfo->rChReqInfo.ucChannelNum = prRemainOnChannel->ucChannelNum; ++ prAisFsmInfo->rChReqInfo.u4DurationMs = prRemainOnChannel->u4DurationMs; ++ prAisFsmInfo->rChReqInfo.u8Cookie = prRemainOnChannel->u8Cookie; ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE || prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { ++ /* transit to next state */ ++ aisFsmSteps(prAdapter, AIS_STATE_REQ_REMAIN_ON_CHANNEL); ++ } else { ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL); ++ } ++ ++ /* free messages */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prCancelRemainOnChannel; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ prCancelRemainOnChannel = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) prMsgHdr; ++ ++ /* 1. Check the cookie first */ ++ if (prCancelRemainOnChannel->u8Cookie == prAisFsmInfo->rChReqInfo.u8Cookie) { ++ ++ /* 2. release channel privilege/request */ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL) { ++ /* 2.1 elease channel */ ++ aisFsmReleaseCh(prAdapter); ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { ++ /* 2.1 release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2.2 stop channel timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ } ++ ++ /* 3. clear pending request of remain_on_channel */ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE); ++ ++ /* 4. decide which state to retreat */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); ++ else ++ aisFsmSteps(prAdapter, AIS_STATE_IDLE); ++ } ++ ++ /* 5. free message */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ /* prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); */ ++ ++ if (prAisFsmInfo == NULL) ++ break; ++ prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) prMsgHdr; ++ ++ aisFuncTxMgmtFrame(prAdapter, ++ &prAisFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* aisFsmRunEventMgmtFrameTx */ ++ ++VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { ++ /* 1. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2. stop channel timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ ++ /* 3. expiration indication to upper layer */ ++ kalRemainOnChannelExpired(prAdapter->prGlueInfo, ++ prAisFsmInfo->rChReqInfo.u8Cookie, ++ prAisFsmInfo->rChReqInfo.eBand, ++ prAisFsmInfo->rChReqInfo.eSco, prAisFsmInfo->rChReqInfo.ucChannelNum); ++ ++ /* 4. decide which state to retreat */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); ++ else ++ aisFsmSteps(prAdapter, AIS_STATE_IDLE); ++ } else { ++ DBGLOG(AIS, WARN, "Unexpected remain_on_channel timeout event\n"); ++#if DBG ++ DBGLOG(AIS, STATE, "CURRENT State: [%s]\n", apucDebugAisState[prAisFsmInfo->eCurrentState]); ++#else ++ DBGLOG(AIS, STATE, "[%d] CURRENT State: [%d]\n", DBG_AIS_IDX, prAisFsmInfo->eCurrentState); ++#endif ++ } ++ ++} ++ ++WLAN_STATUS ++aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_AIS_MGMT_TX_REQ_INFO_T) NULL; ++ BOOLEAN fgIsSuccess = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo); ++ ++ if (rTxDoneStatus != TX_RESULT_SUCCESS) { ++ DBGLOG(AIS, ERROR, "Mgmt Frame TX Fail, Status:%d.\n", rTxDoneStatus); ++ } else { ++ fgIsSuccess = TRUE; ++ /* printk("Mgmt Frame TX Done.\n"); */ ++ } ++ ++ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { ++ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ fgIsSuccess, prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); ++ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ } ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* aisFsmRunEventMgmtFrameTxDone */ ++ ++WLAN_STATUS ++aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); ++ ++ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { ++ ++ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ ++ /* Packet on driver, not done yet, drop it. */ ++ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; ++ if (prTxMsduInfo != NULL) { ++ ++ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ FALSE, ++ prTxMsduInfo->prPacket, (UINT_32) prTxMsduInfo->u2FrameLength); ++ ++ /* Leave it to TX Done handler. */ ++ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ } ++ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ ++ /* Packet transmitted, wait tx done. (cookie issue) */ ++ } ++ ++ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); ++ ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanHdr->aucAddr1); ++ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++ ++ prMgmtTxReqInfo->u8Cookie = u8Cookie; ++ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; ++ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; ++ ++ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; ++ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); ++ if (prStaRec != NULL) { ++ /* Do nothing */ ++ /* printk("Mgmt with station record: %pM .\n", prStaRec->aucMacAddr); */ ++ } ++ ++ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ ++ prMgmtTxMsdu->fgIs802_1x = FALSE; ++ prMgmtTxMsdu->fgIs802_11 = TRUE; ++ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMgmtTxMsdu->pfTxDoneHandler = aisFsmRunEventMgmtFrameTxDone; ++ prMgmtTxMsdu->fgIsBasicRate = TRUE; ++ DBGLOG(AIS, TRACE, "Mgmt seq NO. %d .\n", prMgmtTxMsdu->ucTxSeqNum); ++ ++ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* aisFuncTxMgmtFrame */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Action Frame and indicate to uppoer layer ++* if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("aisFuncValidateRxActionFrame"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ if (1 /* prAisFsmInfo->u4AisPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME */) { ++ /* Leave the action frame to wpa_supplicant. */ ++ kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* aisFuncValidateRxActionFrame */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c +new file mode 100644 +index 000000000000..f02d7c3bb5b2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c +@@ -0,0 +1,1932 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#3 ++*/ ++ ++/*! \file "assoc.c" ++ \brief This file includes the association-related functions. ++ ++ This file includes the association-related functions. ++*/ ++ ++/*\ ++** Log: assoc.c ++** ++** 07 27 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Fix wifi direct connection issue. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 06 08 2012 cp.wu ++ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development ++ * add a pair of brace for compilation success. ++ * ++ * 06 04 2012 cp.wu ++ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development ++ * discussed with WH, privacy bit in associate response is not necessary to be checked, ++ * and identified as association failure when mismatching with beacon/probe response ++ * ++ * 03 14 2012 wh.su ++ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting ++ * Add code from 2.2 ++ * ++ * 03 09 2012 terry.wu ++ * NULL ++ * Fix build error. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 yuche.tsai ++ * NULL ++ * Update Driver for wifi driect gc join IE update issue. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Fix PhyTypeSet in STA_REC in AP mode ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 19 2011 yuche.tsai ++ * NULL ++ * Fix KE when enable hot-spot & any one client connect to this hot-spot. ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 07 15 2011 terry.wu ++ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment ++ * Update workaround for Kingnet AP. ++ * ++ * 07 15 2011 terry.wu ++ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment ++ * Workaround for Kingnet 710 AP wrong AID assignment. ++ * ++ * 05 02 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning[WCXRP00000672] [MT6620 Wi-Fi][FW] ++ * Fix the PS event allocation ++ * Check STA when rx assoc. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the protected while at P2P start GO, and skip some security check . ++ * ++ * 03 14 2011 wh.su ++ * [WCXRP00000545] [MT6620 Wi-Fi] [Driver] Fixed the p2p not enable, received a assoc rsp ++ * cause the rx assoc execute a null function ++ * Modify file for avoid assert at BOW receive a assoc response frame but no p2p function. ++ * ++ * 03 08 2011 terry.wu ++ * [WCXRP00000524] [MT6620 Wi-Fi][Driver] Fix p2p assoc request containing wrong IE format ++ * Fix p2p assoc request containing wrong IE format. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add code to let the beacon and probe response for Auto GO WSC . ++ * ++ * 02 15 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Fix RX disassoc issue under Hot-spot mode. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, ++ * but if the P2P device is connected, 11b rate is not allowed. ++ * ++ * 01 11 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Update Desired Non-HT Rate Set. ++ * ++ * 12 30 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Recover the code that was coverwritted.. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add SSID IE in assoc req frame which is sent by P2P GC. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RSN IE generation by CFG_RSN_MIGRATION compilation flag. ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * revised. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update assocProcessRxAssocReqFrame() to avoid redundant SSID IE {0,0} for IOT. ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix compile warning - macro > 10 line, initial value of an array ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * * * * * * * and will send Null frame to diagnose connection ++ * ++ * 04 16 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the wpa-none for ibss beacon. ++ * ++ * 03 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove compiling warning ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 28 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * fixed the compiling warning.u1rwduu`wvpghlqg|rm+vp ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update Assoc ID for PS ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Use new constant definition ELEM_MAX_LEN_EXT_CAP ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Modify assoc req IE talbe for HT cap IE ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * update the assocComposeReAssocReqFrameHeader() and fix the u2EstimatedFrameLen in assocSendReAssocReqFrame() ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * remove some space line ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the sending disassoc frame function ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the txassocReq IE table, adding for WPA/RSN ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix eNetType not init in send AssocReq function ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Integrate the send Assoc with TXM ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code to indicate the assoc request and assoc response (now disable) ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove unused variables ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++APPEND_VAR_IE_ENTRY_T txAssocReqIETable[] = { ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmReqGenerateHtCapIE} ++ , /* 45 */ ++#if CFG_SUPPORT_WPS2 ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WSC), NULL, rsnGenerateWSCIE} ++ , /* 221 */ ++#endif ++#if CFG_RSN_MIGRATION ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} ++ , /* 48 */ ++#endif ++#if CFG_SUPPORT_WAPI ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI), NULL, wapiGenerateWAPIIE} ++ , /* 68 */ ++#endif ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_INTERWORKING), NULL, hs20GenerateInterworkingIE} ++ , /* 107 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ROAMING_CONSORTIUM), NULL, hs20GenerateRoamingConsortiumIE} ++ , /* 111 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE} ++ , /* 127 */ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HS20_INDICATION), NULL, hs20GenerateHS20IE} ++ , /* 221 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE} ++ , /* 221 */ ++#if CFG_RSN_MIGRATION ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE} ++ , /* 221 */ ++#endif ++}; ++ ++#if CFG_SUPPORT_AAA ++VERIFY_IE_ENTRY_T rxAssocReqIETable[] = { ++ {ELEM_ID_RESERVED, NULL} /* 255 */ ++}; ++ ++APPEND_VAR_IE_ENTRY_T txAssocRespIETable[] = { ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} ++ , /* 42 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} ++ , /* 45 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} ++ , /* 61 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} ++ , /* 74 */ ++ {(0), p2pFuncCalculateP2p_IELenForAssocRsp, p2pFuncGenerateP2p_IEForAssocRsp} ++ , /* 221 */ ++#if CFG_SUPPORT_WFD ++ {(0), wfdFuncCalculateWfdIELenForAssocRsp, wfdFuncGenerateWfdIEForAssocRsp} ++ , /* 221 */ ++#endif ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} ++ , /* 127 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} ++ , /* 221 */ ++ ++ {(0), p2pFuncCalculateWSC_IELenForAssocRsp, p2pFuncGenerateWSC_IEForAssocRsp} /* 221 */ ++ ++}; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose the Capability Info Field. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval Capability Info Field ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_16 ++assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ UINT_32 u4NonHTPhyType; ++ UINT_16 u2CapInfo; ++ ++ /* Set up our requested capabilities. */ ++ u2CapInfo = CAP_INFO_ESS; ++ u2CapInfo |= CAP_CF_STA_NOT_POLLABLE; ++ ++ if (prStaRec == NULL) ++ u2CapInfo |= CAP_INFO_PRIVACY; ++ else { ++ if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ++ u2CapInfo |= CAP_INFO_PRIVACY; ++ } ++ ++ /* 7.3.1.4 */ ++ if (prStaRec == NULL) { ++ if ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||/* ShortPreambleOptionEnable is TRUE */ ++ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO)) ++ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ if (prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) ++ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ } else if (prStaRec->fgHasBasicPhyType) { ++ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ if ((rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) && ++ /* Short Preamble Option Enable is TRUE */ ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) && ++ (prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { ++ ++ /* Case I: Implemented == TRUE and Short Preamble Option Enable == TRUE. ++ * Case II: Implemented == TRUE and Short Preamble == AUTO (depends on ++ * BSS_DESC_T's capability) ++ */ ++ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ } ++#if CFG_SUPPORT_SPEC_MGMT /*Add by Enlai */ ++ /* Support 802.11h */ ++ if (prStaRec->u2CapInfo & CAP_INFO_SPEC_MGT) { ++ /* ++ 1. The Power Capability element shall be present if ++ dot11SpectrumManagementRequired is true. ++ ++ 2. A STA shall set dot11SpectrumManagementRequired to TRUE before ++ associating with a BSS or IBSS in which the Spectrum Management ++ bit is set to 1 in the Capability Information field in Beacon frames ++ and Probe Response frames received from the BSS or IBSS. ++ */ ++ if (prAdapter->fgEnable5GBand == TRUE) ++ u2CapInfo |= CAP_INFO_SPEC_MGT; ++ } ++#endif ++ ++ if (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented && ++ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) { ++ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ } ++ } ++ ++ if (prStaRec) { ++ DBGLOG(SAA, LOUD, "ASSOC REQ: Compose Capability = 0x%04x for Target BSS [%pM].\n", ++ u2CapInfo, prStaRec->aucMacAddr); ++ } ++ ++ return u2CapInfo; ++ ++} /* end of assocBuildCapabilityInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for Association ++* Request Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID assocBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ PUINT_8 pucBuffer; ++ UINT_16 u2SupportedRateSet; ++ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; ++ UINT_8 ucAllSupportedRatesLen; ++ UINT_8 ucSupRatesLen; ++ UINT_8 ucExtSupRatesLen; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ if (IS_STA_IN_AIS(prStaRec)) { ++ ++ /* Fill the SSID element. */ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ ++ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of ++ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. ++ */ ++ ++ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, ++ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ pucBuffer = p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, pucBuffer); ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (IS_STA_IN_BOW(prStaRec)) { ++ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ ++ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of ++ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. ++ */ ++ ++ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, ++ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++#endif ++ else { ++ /* Do nothing */ ++ /* TODO(Kevin): For other network */ ++ } ++ ++ /* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication - ++ * SupportedRates - The set of data rates that are supported by the STA ++ * that is requesting association. ++ * Original(Portable Driver): Only send the Rates that we'll support. ++ * New: Send the Phy Rates if the result of following & operation == NULL. ++ */ ++ /* rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet & */ ++ /* rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet), */ ++ ++ if (prStaRec->fgHasBasicPhyType) { ++ UINT_32 u4NonHTPhyType; ++ ++ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ u2SupportedRateSet = (prStaRec->u2OperationalRateSet & ++ rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet); ++ ++ ASSERT(u2SupportedRateSet); ++ ++ if (!u2SupportedRateSet) ++ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; ++ ++ /* TODO(Kevin): For P2P, we shouldn't send support rate set which contains 11b rate */ ++ ++ rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen); ++ ++ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? ++ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); ++ ++ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; ++ ++ /* Fill the Supported Rates element. */ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ ++ /* Fill the Extended Supported Rates element. */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, ++ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ ++ /* 7.3.2.19 Supported Channels element */ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++ if (prAdapter->fgEnable5GBand == TRUE) { ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucLength = 8; ++ ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[0] = 36; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[1] = 4; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[2] = 52; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[3] = 4; ++/* Not China --- Start */ ++ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 100; */ ++ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 11; */ ++/* Not China --- End */ ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 149; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 4; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[6] = 165; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[7] = 1; ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++#endif ++ } ++ ++} /* end of assocBuildReAssocReqFrameCommonIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the (Re)Association Request frame header and ++* its fixed fields ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in out] pu2PayloadLen Return the length of the composed fixed fields ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocComposeReAssocReqFrameHeaderAndFF(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN OUT PUINT_16 pu2PayloadLen) ++{ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; ++ BOOLEAN fgIsReAssoc; ++ ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2CapInfo; ++ UINT_16 u2ListenInterval; ++ ++ ASSERT(prStaRec); ++ ASSERT(pucBuffer); ++ ASSERT(aucMACAddress); ++ ASSERT(pu2PayloadLen); ++ ++ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) pucBuffer; ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ ++ /* Fill the Frame Control field. */ ++ if (fgIsReAssoc) ++ u2FrameCtrl = MAC_FRAME_REASSOC_REQ; ++ else ++ u2FrameCtrl = MAC_FRAME_ASSOC_REQ; ++ WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress); ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prAssocFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); ++ ++ /* Fill the Capability Information field. */ ++ WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); ++ ++ /* Calculate the listen interval for the maximum power mode. Currently, we ++ set it to the value 2 times DTIM period. */ ++ if (prStaRec->ucDTIMPeriod) { ++ u2ListenInterval = prStaRec->ucDTIMPeriod * DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD; ++ } else { ++ DBGLOG(SAA, TRACE, "Use default listen interval\n"); ++ u2ListenInterval = DEFAULT_LISTEN_INTERVAL; ++ } ++ prStaRec->u2ListenInterval = u2ListenInterval; ++ ++ /* Fill the Listen Interval field. */ ++ WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval); ++ ++ /* 4 <3> Compose the Current AP Address field for ReAssociation Request frame. */ ++ /* Fill the Current AP Address field. */ ++ if (prStaRec->fgIsReAssoc) { ++ if (IS_STA_IN_AIS(prStaRec)) { ++ ++ P_AIS_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ P_WLAN_REASSOC_REQ_FRAME_T prReAssocFrame = (P_WLAN_REASSOC_REQ_FRAME_T) prAssocFrame; ++ ++ COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, prAisBssInfo->aucBSSID); ++ } else { ++ ASSERT(0); /* We don't support ReAssociation for other network */ ++ } ++ ++ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + CURR_AP_ADDR_FIELD_LEN); ++ } else { ++ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN); ++ } ++ ++} /* end of assocComposeReAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the (Re)Association Request frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ UINT_16 u2PayloadLen; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ BOOLEAN fgIsReAssoc; ++ UINT_32 i; ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ ++ if (fgIsReAssoc) { ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + ++ LISTEN_INTERVAL_FIELD_LEN + ++ CURR_AP_ADDR_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); ++ } else { ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + ++ LISTEN_INTERVAL_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); ++ } ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ if ((prAdapter->fgIsP2PRegistered)) { ++ u2EstimatedExtraIELen = p2pCalculate_IEForAssocReq(prAdapter, ++ prStaRec->ucNetTypeIndex, prStaRec); ++ } else { ++ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); ++ ASSERT(FALSE); ++ } ++ } else { ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { ++ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; ++ } else { ++ u2EstimatedExtraIELen += ++ (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, ++ prStaRec->ucNetTypeIndex, ++ prStaRec); ++ } ++ } ++ } ++#else ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { ++ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; ++ } else { ++ u2EstimatedExtraIELen += (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, ++ prStaRec->ucNetTypeIndex, ++ prStaRec); ++ } ++ } ++#endif ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Request.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Compose Header and Fixed Field */ ++ assocComposeReAssocReqFrameHeaderAndFF(prAdapter, ++ prStaRec, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prBssInfo->aucOwnMacAddr, &u2PayloadLen); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ ++ assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo); ++ ++ /* 4 <5> Compose IEs in MSDU_INFO_T */ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ if ((prAdapter->fgIsP2PRegistered)) { ++ p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo); ++ } else { ++ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); ++ ASSERT(FALSE); ++ } ++ } else { ++ /* Append IE */ ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].pfnAppendIE) ++ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ } ++#else ++ /* Append IE */ ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].pfnAppendIE) ++ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++#endif ++ ++ /* 4 <6> Update the (Re)association request information */ ++ if (IS_STA_IN_AIS(prStaRec)) { ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; ++ ++ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++#if CFG_RSN_MIGRATION ++ kalUpdateReAssocReqInfo(prAdapter->prGlueInfo, ++ (PUINT_8) &prAssocFrame->u2CapInfo, ++ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), ++ fgIsReAssoc); ++#endif ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; ++ ++ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, ++ (PUINT_8) &prAssocFrame->u2CapInfo, ++ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), ++ fgIsReAssoc); ++ } ++#endif ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ ++ DBGLOG(SAA, INFO, "Sending (Re)Assoc Request, network: %d seqNo: %d\n", ++ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of assocSendReAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will strictly check the TX (Re)Association Request frame for ++* SAA event handling. ++* ++* @param[in] prMsduInfo Pointer of MSDU_INFO_T ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TxFrameCtrl; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) (prMsduInfo->prPacket); ++ ASSERT(prAssocReqFrame); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl) */ ++ u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2TxFrameCtrl &= MASK_FRAME_TYPE; ++ if (prStaRec->fgIsReAssoc) { ++ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ) ++ return WLAN_STATUS_FAILURE; ++ } else { ++ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ) ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocCheckTxReAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will strictly check the TX (Re)Association Response frame for ++* AAA event handling. ++* ++* @param[in] prMsduInfo Pointer of MSDU_INFO_T ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TxFrameCtrl; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) (prMsduInfo->prPacket); ++ ASSERT(prAssocRspFrame); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl) */ ++ u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2TxFrameCtrl &= MASK_FRAME_TYPE; ++ if (prStaRec->fgIsReAssoc) { ++ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } else { ++ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocCheckTxReAssocRespFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the incoming (Re)Association Frame and take out ++* the status code. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ UINT_16 u2RxFrameCtrl; ++ UINT_16 u2RxCapInfo; ++ UINT_16 u2RxStatusCode; ++ UINT_16 u2RxAssocId; ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu2StatusCode); ++ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + ++ STATUS_CODE_FIELD_LEN + AID_FIELD_LEN)) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ DBGLOG(SAA, LOUD, "prSwRfb->u2PayloadLength = %d\n", prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* 4 <1> locate the (Re)Association Resp Frame. */ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of (Re)Association Resp Frame. */ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl); */ ++ u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2RxFrameCtrl &= MASK_FRAME_TYPE; ++ if (prStaRec->fgIsReAssoc) { ++ if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } else { ++ if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* 4 <3> Parse the Fixed Fields of (Re)Association Resp Frame Body. */ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo); */ ++ u2RxCapInfo = prAssocRspFrame->u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode); */ ++ u2RxStatusCode = prAssocRspFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* 4 <4> Check CAP_INFO */ ++ /* NOTE(Kevin): CM suggest to add MGMT workaround for those APs didn't check ++ * the CAP Privacy Bit to overcome a corner case that the Privacy Bit ++ * of our SCAN result didn't consist with AP's Association Resp. ++ */ ++ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { ++#if CFG_SUPPORT_WAPI ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { ++ /* WAPI AP allow the customer use WZC to join mode, the privacy bit is 0 */ ++ /* even at WAI & WAPI_PSK mode, but the assoc respose set the privacy bit set 1 */ ++ DBGLOG(SEC, TRACE, "Workaround the WAPI AP allow the customer to use WZC to join\n"); ++ } else ++#endif ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && 1) { ++ /* Todo:: Fixed this */ ++ } else ++#endif ++ { ++ } ++ ++#if CFG_STRICT_CHECK_CAPINFO_PRIVACY ++ if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY)) ++ u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; ++#endif ++ } ++ ++ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { ++#if CFG_RSN_MIGRATION ++ /* Update the information in the structure used to query and set ++ OID_802_11_ASSOCIATION_INFORMATION. */ ++ kalUpdateReAssocRspInfo(prAdapter->prGlueInfo, ++ (PUINT_8) &prAssocRspFrame->u2CapInfo, (UINT_32) (prSwRfb->u2PacketLen)); ++#endif ++ } ++ /* 4 <5> Update CAP_INFO and ASSOC_ID */ ++ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { ++ prStaRec->u2CapInfo = u2RxCapInfo; ++ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, &u2RxAssocId); */ ++ u2RxAssocId = prAssocRspFrame->u2AssocId; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* 20110715 Workaround for Kingnet 710 AP (Realtek 8186) ++ * This AP raises the bit 6&7 not bit 14&15 in AID field. ++ * It cause wrong AID assignment. ++ * For AID = 2 ++ * Normal case: 0xC002(1100 0000 0000 0010) => 2 ++ * Kingnet 710: 0x00C2(0000 0000 1100 0010) => 194 ++ * workaround: mask bit 6&7 for this AP ++ */ ++ if ((u2RxAssocId & BIT(6)) && (u2RxAssocId & BIT(7)) && !(u2RxAssocId & BITS(8, 15))) { ++ prStaRec->u2AssocId = u2RxAssocId & ~BITS(6, 7); ++ } else { ++ prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB; ++#if CFG_SUPPORT_802_11W ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ prBssSpecInfo->ucSaQueryTimedOut = 0; ++ } ++#endif ++ } ++ } ++#if CFG_SUPPORT_802_11W ++ if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) { ++ DBGLOG(SAA, INFO, "AP rejected due the authentication algorithm not support\n"); ++ } else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { ++ PUINT_8 pucIE, pucTime; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_TIMEOUT_INTERVAL == IE_ID(pucIE) && IE_LEN(pucIE) == 5) { ++ pucTime = ((P_IE_HDR_T) pucIE)->aucInfo; ++ if (pucTime[0] == ACTION_SA_TIMEOUT_ASSOC_COMEBACK) { ++ UINT_32 tu; ++ ++ WLAN_GET_FIELD_32(pucTime + 1, &tu); ++ DBGLOG(SAA, INFO, ++ "AP rejected association temporarily;comeback duration %u TU (%u ms)\n", ++ tu, TU_TO_MSEC(tu)); ++ if (tu > TX_ASSOCIATION_RETRY_TIMEOUT_TU) { ++ DBGLOG(SAA, INFO, "Update timer based on comeback duration\n"); ++ /* ieee80211_reschedule_timer(wpa_s, ms); */ ++ } ++ } ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ } ++#endif ++ *pu2StatusCode = u2RxStatusCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocCheckRxReAssocRspFrameStatus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will compose the Disassociation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in] u2ReasonCode The reason code of disassociation ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocComposeDisassocFrame(IN P_STA_RECORD_T prStaRec, ++ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN UINT_16 u2ReasonCode) ++{ ++ P_WLAN_DISASSOC_FRAME_T prDisAssocFrame; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(pucBuffer); ++ ASSERT(aucMACAddress); ++ ++ prDisAssocFrame = (P_WLAN_DISASSOC_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the DisAssociation frame. */ ++ /* Fill the Frame Control field. */ ++ u2FrameCtrl = MAC_FRAME_DISASSOC; ++ ++ WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl); ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress); ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prDisAssocFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's fixed field part of the Disassociation frame. */ ++ /* Fill the Reason Code field. */ ++ WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode); ++ ++} /* end of assocComposeDisassocFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Disassociation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u2ReasonCode The reason code of disassociation ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode) ++{ ++ PUINT_8 pucMacAddress; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2PayloadLen; ++ UINT_16 u2EstimatedFrameLen; ++ /* UINT_32 u4Status = WLAN_STATUS_SUCCESS; */ ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending DisAssoc.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Disassociation frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ pucMacAddress = prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].aucOwnMacAddr; ++ ++ /* Compose Header and Fixed Field */ ++ assocComposeDisassocFrame(prStaRec, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucMacAddress, u2ReasonCode); ++ ++#if CFG_SUPPORT_802_11W ++ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; ++ ++ prDisassocFrame = ++ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ DBGLOG(TX, WARN, "assocSendDisAssocFrame with protection\n"); ++ } ++#endif ++ ++ u2PayloadLen = REASON_CODE_FIELD_LEN; ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Enqueue the frame to send this (Re)Association request frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of assocSendDisAssocFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Disassociation frame ++* if the given BSSID is matched. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] aucBSSID Given BSSID ++* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) ++{ ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; ++ UINT_16 u2RxReasonCode; ++ ++ ASSERT(prSwRfb); ++ ASSERT(aucBSSID); ++ ASSERT(pu2ReasonCode); ++ ++ /* 4 <1> locate the Disassociation Frame. */ ++ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Disassociation Frame. */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Check if this Disassoc Frame is coming from Target BSSID */ ++ if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) { ++ DBGLOG(SAA, LOUD, "Ignore Disassoc Frame from other BSS [ %pM ]\n", ++ prDisassocFrame->aucSrcAddr); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ ++ WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode); ++ *pu2ReasonCode = u2RxReasonCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocProcessRxDisassocFrame() */ ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Association Req frame ++* and return a Status Code. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode Pointer to store the Status Code for carried in Association Response. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ P_RSN_INFO_ELEM_T prIeRsn = (P_RSN_INFO_ELEM_T) NULL; ++ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; ++ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; ++ PUINT_8 pucIE, pucIEStart; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ UINT_16 u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ UINT_16 u2RxFrameCtrl; ++ UINT_16 u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pu2StatusCode); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prStaRec == NULL) ++ return WLAN_STATUS_FAILURE; ++ /* 4 <1> locate the Association Req Frame. */ ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Association Req Frame. */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN)) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Check if this Disassoc Frame is coming from Target BSSID */ ++ if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID)) ++ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ ++ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2RxFrameCtrl); */ ++ u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2RxFrameCtrl &= MASK_FRAME_TYPE; ++ if (MAC_FRAME_REASSOC_REQ == u2RxFrameCtrl) { ++ prStaRec->fgIsReAssoc = TRUE; ++ ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) (OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); ++ ++ pucIEStart = pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; ++ } else { ++ prStaRec->fgIsReAssoc = FALSE; ++ ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) (OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); ++ ++ pucIEStart = pucIE = prAssocReqFrame->aucInfoElem; ++ } ++ ++ /* 4 <3> Parse the Fixed Fields of Assoc Req Frame Body. */ ++ prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo; ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) && !kalP2PGetCipher(prAdapter->prGlueInfo))) { ++ u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; ++ DBGLOG(RSN, TRACE, "STA Assoc req privacy bit check fail\n"); ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++#endif ++ ++ prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval; ++ prStaRec->ucPhyTypeSet = 0; ++ ++ /* Might be legacy client or p2p gc. */ ++ prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT; ++ ++ /* 4 <4> Parse the IE of Assoc Req Frame Body. */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if ((!prIeSsid) && /* NOTE(Kevin): Get SSID once */ ++ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ } ++ break; ++ ++ case ELEM_ID_SUP_RATES: ++ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) ++ prIeSupportedRate = SUP_RATES_IE(pucIE); ++ break; ++ ++ case ELEM_ID_EXTENDED_SUP_RATES: ++ if (!prIeExtSupportedRate) ++ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); ++ break; ++ case ELEM_ID_HT_CAP: ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; ++ kalMemCopy(&prStaRec->u2HtCapInfo, &(HT_CAP_IE(pucIE)->u2HtCapInfo), 2); ++ break; ++ case ELEM_ID_RSN: ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ prIeRsn = RSN_IE(pucIE); ++ rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode); ++ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ *pu2StatusCode = u2StatusCode; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++#endif ++ break; ++ case ELEM_ID_VENDOR: ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ if ((prAdapter->fgIsP2PRegistered)) { ++ UINT_8 ucOuiType = 0; ++ ++ p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType); ++ ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ DBGLOG(P2P, TRACE, "Target Client is a P2P group client\n"); ++ prStaRec->eStaType = STA_TYPE_P2P_GC; ++ } ++ } ++ } ++#endif ++ break; ++ default: ++ for (i = 0; i < (sizeof(rxAssocReqIETable) / sizeof(VERIFY_IE_ENTRY_T)); i++) { ++ ++ if ((IE_ID(pucIE)) == rxAssocReqIETable[i].ucElemID) { ++ rxAssocReqIETable[i].pfnVarifyIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIE, ++ &u2StatusCode); ++ ++ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ *pu2StatusCode = u2StatusCode; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++ } ++ ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* parsing for WMM related information (2010/12/21) */ ++ mqmProcessAssocReq(prAdapter, prSwRfb, pucIEStart, u2IELength); ++ ++ do { ++ if (prIeSsid) { ++ if (UNEQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, ++ prIeSsid->aucSSID, prIeSsid->ucLength)) { ++ ++ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; ++ break; ++ } ++ } else { ++ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; ++ break; ++ } ++ ++ prStaRec->u2OperationalRateSet = 0; ++ prStaRec->u2BSSBasicRateSet = 0; ++ ++ if (prIeSupportedRate || prIeExtSupportedRate) { ++ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, &prStaRec->u2OperationalRateSet, ++ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ ++ &fgIsUnknownBssBasicRate); ++ ++ if ((prBssInfo->u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) != ++ prBssInfo->u2BSSBasicRateSet) { ++ ++ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++ ++ /* Accpet the Sta, update BSSBasicRateSet from Bss */ ++ ++ prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; ++ ++ prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG); ++ ++ if (BAND_2G4 == HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr)) { ++#if 0 /* Marked by CMC 20111024 */ ++ /* check if support 11n */ ++ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { ++ ++ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; ++ ++ if ((!(u2BSSBasicRateSet & RATE_SET_OFDM)) && ++ (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS)) { ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; ++ ++ } ++ ++ } ++#else ++ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; ++ if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; ++#endif ++ } else { /* (BAND_5G == prBssDesc->eBande) */ ++#if 0 /* Marked by CMC 20111024 */ ++ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; ++ ASSERT((prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) == 0); ++#else ++ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; ++#endif ++ } ++ ++ } else { ++ ASSERT(0); ++ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ if (prIeRsn) { ++ if (!kalP2PGetCipher(prAdapter->prGlueInfo)) { ++ u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED; ++ break; ++ } ++ } else { ++ prStaRec->rSecInfo.fgAllowOnly1x = FALSE; ++ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { ++ /* Only Allow 1x */ ++ prStaRec->rSecInfo.fgAllowOnly1x = TRUE; ++ break; ++ } ++ } ++ } ++#endif ++ ++ } while (FALSE); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++#if 1 /* ICS */ ++ { ++ PUINT_8 cp = (PUINT_8) &prAssocReqFrame->u2CapInfo; ++ P_UINT_8 prNewAssocReqIe = NULL; ++ ++ if (u2IELength) { ++ prNewAssocReqIe = kalMemAlloc(u2IELength, VIR_MEM_TYPE); ++ if (NULL == prNewAssocReqIe) { ++ DBGLOG(AIS, WARN, "allocate memory for (Re)assocReqIe fail!\n"); ++ u2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ if (prStaRec->fgIsReAssoc) ++ cp += 10; ++ else ++ cp += 4; ++ if (prStaRec->pucAssocReqIe) { ++ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); ++ prStaRec->pucAssocReqIe = NULL; ++ } ++ prStaRec->u2AssocReqIeLen = u2IELength; ++ if (u2IELength) { ++ prStaRec->pucAssocReqIe = prNewAssocReqIe; /* kalMemAlloc(u2IELength, VIR_MEM_TYPE); */ ++ kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength); ++ } ++ } ++#endif ++ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8) &prAssocReqFrame->u2CapInfo, ++ u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc); ++ } ++#endif ++ ++ *pu2StatusCode = u2StatusCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocProcessRxAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for Association ++* Response Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocBuildReAssocRespFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo) ++{ ++ PUINT_8 pucBuffer; ++ P_STA_RECORD_T prStaRec; ++ UINT_8 ucSupRatesLen; ++ UINT_8 ucExtSupRatesLen; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) { ++ ++ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; ++ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; ++ } else { ++ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; ++ ucExtSupRatesLen = 0; ++ } ++ ++ /* Fill the Supported Rates element. */ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ ++ /* Fill the Extended Supported Rates element. */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, ++ &prBssInfo->aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* end of assocBuildReAssocRespFrameCommonIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the (Re)Association Response frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucBssid Given BSSID. ++* @param[in] u2CapInfo Capability Field of current BSS. ++* @param[in out] pu2PayloadLen Return the length of the composed fixed fields ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocComposeReAssocRespFrameHeaderAndFF(IN P_STA_RECORD_T prStaRec, ++ IN PUINT_8 pucBuffer, ++ IN UINT_8 aucBSSID[], IN UINT_16 u2CapInfo, IN OUT PUINT_16 pu2PayloadLen) ++{ ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ BOOLEAN fgIsReAssoc; ++ ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(prStaRec); ++ ASSERT(pucBuffer); ++ ASSERT(aucBSSID); ++ ASSERT(pu2PayloadLen); ++ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) pucBuffer; ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ ++ /* Fill the Frame Control field. */ ++ if (fgIsReAssoc) ++ u2FrameCtrl = MAC_FRAME_REASSOC_RSP; ++ else ++ u2FrameCtrl = MAC_FRAME_ASSOC_RSP; ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prAssocRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with Target MAC Address. */ ++ COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr); ++ ++ /* Fill the SA field with current BSSID. */ ++ COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID); ++ ++ /* Fill the BSSID field with current BSSID. */ ++ COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prAssocRspFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ ++ /* Fill the Capability Information field. */ ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); */ ++ prAssocRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, prStaRec->u2StatusCode); */ ++ prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, ((prStaRec->u2AssocId & AID_MASK) | AID_MSB)); */ ++ prAssocRspFrame->u2AssocId = ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); /* NOTE(Kevin): Optimized for ARM */ ++ ++ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); ++ ++} /* end of assocComposeReAssocRespFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the (Re)Association Resp frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ UINT_16 u2PayloadLen; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ BOOLEAN fgIsReAssoc; ++ UINT_32 i; ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + ++ STATUS_CODE_FIELD_LEN + ++ AID_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) { ++ u2EstimatedExtraIELen += txAssocRespIETable[i].u2EstimatedFixedIELen; ++ } else if (txAssocRespIETable[i].pfnCalculateVariableIELen != NULL) { ++ u2EstimatedExtraIELen += (UINT_16) txAssocRespIETable[i].pfnCalculateVariableIELen(prAdapter, ++ prStaRec->ucNetTypeIndex, ++ prStaRec); ++ } ++ ++ } ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(AAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Response.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex != NETWORK_TYPE_AIS_INDEX); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Compose Header and Fixed Field */ ++ assocComposeReAssocRespFrameHeaderAndFF(prStaRec, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prBssInfo->aucBSSID, prBssInfo->u2CapInfo, &u2PayloadLen); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = aaaFsmRunEventTxDone; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ ++ assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo); ++ ++ /* 4 <5> Compose IEs in MSDU_INFO_T */ ++ ++ /* Append IE */ ++ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocRespIETable[i].pfnAppendIE) ++ txAssocRespIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ ++ DBGLOG(SAA, INFO, "Sending (Re)Assoc Response, network: %d seqNo: %d\n", ++ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocSendReAssocRespFrame() */ ++#endif /* CFG_SUPPORT_AAA */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c +new file mode 100644 +index 000000000000..43b91d72bd43 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c +@@ -0,0 +1,1211 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1 ++*/ ++ ++/*! \file "auth.c" ++ \brief This file includes the authentication-related functions. ++ ++ This file includes the authentication-related functions. ++*/ ++ ++/* ++** Log: auth.c ++ * ++ * 02 13 2012 cp.wu ++ * NULL ++ * show error message only instead of raise assertion when ++ * received authentication frame is carrying illegal parameters. ++ * ++ * 11 09 2011 yuche.tsai ++ * NULL ++ * Fix a network index & station record index issue when TX deauth frame. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 yuche.tsai ++ * NULL ++ * Fix coding error. ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature. ++ * BC deauth support. ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * 1. Fix Service Disocvery Logical issue. ++ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 21 2011 terry.wu ++ * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode ++ * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Check Net is active before sending Deauth frame. ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Send Deauth for Class 3 Error and Leave Network Support ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Fix compile warning ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add debug message for abnormal authentication frame from AP ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * Fix the Debug Label ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update the authComposeAuthFrameHeader() ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the send deauth frame function ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Integrate send Auth with TXM ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++APPEND_IE_ENTRY_T txAuthIETable[] = { ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText} ++}; ++ ++HANDLE_IE_ENTRY_T rxAuthIETable[] = { ++ {ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText} ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Authentication frame header and fixed fields. ++* ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucPeerMACAddress Given Peer MAC Address. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in] u2AuthAlgNum Authentication Algorithm Number ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* @param[in] u2StatusCode Status Code ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN UINT_8 aucPeerMACAddress[], ++ IN UINT_8 aucMACAddress[], ++ IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(aucPeerMACAddress); ++ ASSERT(aucMACAddress); ++ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the Authentication frame. */ ++ /* Fill the Frame Control field. */ ++ u2FrameCtrl = MAC_FRAME_AUTH; ++ ++ /* If this frame is the third frame in the shared key authentication ++ * sequence, it shall be encrypted. ++ */ ++ if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) ++ u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prAuthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress); ++ ++ switch (u2TransactionSeqNum) { ++ case AUTH_TRANSACTION_SEQ_1: ++ case AUTH_TRANSACTION_SEQ_3: ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress); ++ break; ++ ++ case AUTH_TRANSACTION_SEQ_2: ++ case AUTH_TRANSACTION_SEQ_4: ++ ++ /* Fill the BSSID field with Current BSSID. */ ++ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress); ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ /* Clear the SEQ/FRAG_NO field. */ ++ prAuthFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ ++ /* Fill the Authentication Algorithm Number field. */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */ ++ prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Authentication Transaction Sequence Number field. */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */ ++ prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Status Code field. */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */ ++ prAuthFrame->u2StatusCode = u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++} /* end of authComposeAuthFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will append Challenge Text IE to the Authentication frame ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TransactionSeqNum; ++ ++ ASSERT(prMsduInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) ++ return; ++ ++ ASSERT(prStaRec); ++ ++ /* For Management, frame header and payload are in a continuous buffer */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket; ++ ++ WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) ++ ++ /* Only consider SEQ_3 for Challenge Text */ ++ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) && ++ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) { ++ ++ COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText); ++ } ++ ++ return; ++ ++} /* end of authAddIEChallengeText() */ ++ ++#if !CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Authenticiation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ UINT_16 u2PayloadLen; ++ UINT_32 i; ++ ++ DBGLOG(SAA, LOUD, "Send Auth Frame\n"); ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields */ ++ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ AUTH_ALGORITHM_NUM_FIELD_LEN + ++ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) ++ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Compose Header and some Fixed Fields */ ++ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prStaRec->aucMacAddr, ++ prBssInfo->aucOwnMacAddr, ++ prStaRec->ucAuthAlgNum, u2TransactionSeqNum, STATUS_CODE_RESERVED); ++ ++ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose IEs in MSDU_INFO_T */ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { ++ if (txAuthIETable[i].pfnAppendIE) ++ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Inform TXM to send this Authentication frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of authSendAuthFrame() */ ++ ++#else ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Authenticiation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authSendAuthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) ++{ ++ PUINT_8 pucReceiveAddr; ++ PUINT_8 pucTransmitAddr; ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ /*get from input parameter */ ++ /* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */ ++ PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ UINT_16 u2PayloadLen; ++ UINT_16 ucAuthAlgNum; ++ UINT_32 i; ++ ++ DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields */ ++ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ AUTH_ALGORITHM_NUM_FIELD_LEN + ++ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) ++ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ ++ if (prStaRec) { ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ pucTransmitAddr = prBssInfo->aucOwnMacAddr; ++ ++ pucReceiveAddr = prStaRec->aucMacAddr; ++ ++ ucAuthAlgNum = prStaRec->ucAuthAlgNum; ++ ++ switch (u2TransactionSeqNum) { ++ case AUTH_TRANSACTION_SEQ_1: ++ case AUTH_TRANSACTION_SEQ_3: ++ pfTxDoneHandler = saaFsmRunEventTxDone; ++ break; ++ ++ case AUTH_TRANSACTION_SEQ_2: ++ case AUTH_TRANSACTION_SEQ_4: ++ pfTxDoneHandler = aaaFsmRunEventTxDone; ++ break; ++ } ++ ++ } else { /* For Error Status Code */ ++ P_WLAN_AUTH_FRAME_T prFalseAuthFrame; ++ ++ ASSERT(prFalseAuthSwRfb); ++ prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader; ++ ++ ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL); ++ ++ pucTransmitAddr = prFalseAuthFrame->aucDestAddr; ++ ++ pucReceiveAddr = prFalseAuthFrame->aucSrcAddr; ++ ++ ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum; ++ ++ u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1); ++ } ++ ++ /* Compose Header and some Fixed Fields */ ++ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucReceiveAddr, ++ pucTransmitAddr, ucAuthAlgNum, u2TransactionSeqNum, u2StatusCode); ++ ++ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ if (prStaRec) ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ else ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; /* false Auth frame */ ++ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose IEs in MSDU_INFO_T */ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { ++ if (txAuthIETable[i].pfnAppendIE) ++ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Inform TXM to send this Authentication frame. */ ++ DBGLOG(SAA, INFO, "network: %d Send Auth Frame %d, Status Code = %d seq num %d\n", ++ eNetTypeIndex, u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum); ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of authSendAuthFrame() */ ++ ++#endif /* CFG_SUPPORT_AAA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will strictly check the TX Authentication frame for SAA/AAA event ++* handling. ++* ++* @param[in] prMsduInfo Pointer of MSDU_INFO_T ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TxFrameCtrl; ++ UINT_16 u2TxAuthAlgNum; ++ UINT_16 u2TxTransactionSeqNum; ++ ++ ASSERT(prMsduInfo); ++ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) (prMsduInfo->prPacket); ++ ASSERT(prAuthFrame); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */ ++ u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2TxFrameCtrl &= MASK_FRAME_TYPE; ++ if (u2TxFrameCtrl != MAC_FRAME_AUTH) ++ return WLAN_STATUS_FAILURE; ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */ ++ u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2TxAuthAlgNum != (UINT_16) (prStaRec->ucAuthAlgNum)) ++ return WLAN_STATUS_FAILURE; ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum) */ ++ u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2TxTransactionSeqNum != u2TransactionSeqNum) ++ return WLAN_STATUS_FAILURE; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authCheckTxAuthFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the incoming Auth Frame's Transaction Sequence ++* Number before delivering it to the corresponding SAA or AAA Module. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always not retain authentication frames ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2RxTransactionSeqNum; ++ ++ ASSERT(prSwRfb); ++ ++ /* 4 <1> locate the Authentication Frame. */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Authentication Frame. */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN + ++ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + ++ STATUS_CODE_FIELD_LEN)) { ++ ASSERT(0); ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ ++ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ switch (u2RxTransactionSeqNum) { ++ case AUTH_TRANSACTION_SEQ_2: ++ case AUTH_TRANSACTION_SEQ_4: ++ saaFsmRunEventRxAuth(prAdapter, prSwRfb); ++ break; ++ ++ case AUTH_TRANSACTION_SEQ_1: ++ case AUTH_TRANSACTION_SEQ_3: ++#if CFG_SUPPORT_AAA ++ aaaFsmRunEventRxAuth(prAdapter, prSwRfb); ++#endif /* CFG_SUPPORT_AAA */ ++ break; ++ ++ default: ++ DBGLOG(SAA, WARN, "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n", ++ u2RxTransactionSeqNum, prAuthFrame->u2StatusCode); ++ break; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authCheckRxAuthFrameTransSeq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the incoming Authentication Frame and take ++* the status code out. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2RxAuthAlgNum; ++ UINT_16 u2RxTransactionSeqNum; ++ /* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */ ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu2StatusCode); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* 4 <1> locate the Authentication Frame. */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */ ++ u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2RxAuthAlgNum != (UINT_16) prStaRec->ucAuthAlgNum) { ++ DBGLOG(SAA, WARN, "Discard Auth frame with auth type = %d, current = %d\n", ++ u2RxAuthAlgNum, prStaRec->ucAuthAlgNum); ++ *pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ ++ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2RxTransactionSeqNum != u2TransactionSeqNum) { ++ DBGLOG(SAA, WARN, "Discard Auth frame with Transaction Seq No = %d\n", u2RxTransactionSeqNum); ++ *pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* 4 <3> Get the Status code */ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */ ++ /* *pu2StatusCode = u2RxStatusCode; */ ++ *pu2StatusCode = prAuthFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authCheckRxAuthFrameStatus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Challenge Text IE from the Authentication frame ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] prIEHdr Pointer to start address of IE ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TransactionSeqNum; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prIEHdr); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return; ++ ++ /* For Management, frame header and payload are in a continuous buffer */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) */ ++ u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Only consider SEQ_2 for Challenge Text */ ++ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) && ++ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) { ++ ++ /* Free previous allocated TCM memory */ ++ if (prStaRec->prChallengeText) { ++ ASSERT(0); ++ cnmMemFree(prAdapter, prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ ++ prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)); ++ if (prStaRec->prChallengeText == NULL) ++ return; ++ ++ /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */ ++ COPY_IE(prStaRec->prChallengeText, prIEHdr); ++ } ++ ++ return; ++ ++} /* end of authAddIEChallengeText() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Authentication frame. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ PUINT_8 pucIEsBuffer; ++ UINT_16 u2IEsLen; ++ UINT_16 u2Offset; ++ UINT_8 ucIEID; ++ UINT_32 i; ++ ++ ASSERT(prSwRfb); ++ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ pucIEsBuffer = &prAuthFrame->aucInfoElem[0]; ++ u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) { ++ ucIEID = IE_ID(pucIEsBuffer); ++ ++ for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) { ++ ++ if (ucIEID == rxAuthIETable[i].ucElemID) ++ rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIEsBuffer); ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authProcessRxAuth2_Auth4Frame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Deauthentication frame ++* ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucPeerMACAddress Given Peer MAC Address. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in] u2StatusCode Status Code ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++authComposeDeauthFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN UINT_8 aucPeerMACAddress[], ++ IN UINT_8 aucMACAddress[], IN UINT_8 aucBssid[], IN UINT_16 u2ReasonCode) ++{ ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(aucPeerMACAddress); ++ ASSERT(aucMACAddress); ++ ASSERT(aucBssid); ++ ++ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the Deauthentication frame. */ ++ /* Fill the Frame Control field. */ ++ u2FrameCtrl = MAC_FRAME_DEAUTH; ++ ++ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prDeauthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress); ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prDeauthFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ ++ /* Fill the Status Code field. */ ++ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */ ++ prDeauthFrame->u2ReasonCode = u2ReasonCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++} /* end of authComposeDeauthFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Deauthenticiation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prClassErrSwRfb Pointer to the SW_RFB_T which is Class Error. ++* @param[in] u2ReasonCode A reason code to indicate why to leave BSS. ++* @param[in] pfTxDoneHandler TX Done call back function ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++* @retval WLAN_STATUS_FAILURE Didn't send Deauth frame for various reasons. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authSendDeauthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_WLAN_MAC_HEADER_A4_T prWlanMacHeader = NULL; ++ PUINT_8 pucReceiveAddr; ++ PUINT_8 pucTransmitAddr; ++ PUINT_8 pucBssid = NULL; ++ ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2RxFrameCtrl; ++ P_BSS_INFO_T prBssInfo; ++ ++ P_DEAUTH_INFO_T prDeauthInfo; ++ OS_SYSTIME rCurrentTime; ++ INT_32 i4NewEntryIndex, i; ++ UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_8 aucBMC[] = BC_MAC_ADDR; ++#endif ++ ++ /* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data ++ * frame ++ */ ++ /* 4 <1> Find the Receiver Address first. */ ++ if (prClassErrSwRfb) { ++ BOOLEAN fgIsAbleToSendDeauth = FALSE; ++ ++ prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader; ++ ++ /* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl); */ ++ u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */ ++ if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0) ++ return WLAN_STATUS_FAILURE; ++ ++ /* Check if corresponding BSS is able to send Deauth */ ++ for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]); ++ ++ if (IS_NET_ACTIVE(prAdapter, i) && ++ (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) { ++ { ++ fgIsAbleToSendDeauth = TRUE; ++ eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) i; ++ break; ++ } ++ } ++ } ++ ++ if (!fgIsAbleToSendDeauth) ++ return WLAN_STATUS_FAILURE; ++ ++ pucReceiveAddr = prWlanMacHeader->aucAddr2; ++ ++ } else if (prStaRec) { ++ ++ pucReceiveAddr = prStaRec->aucMacAddr; ++ } else { ++#if CFG_ENABLE_WIFI_DIRECT ++ pucReceiveAddr = aucBMC; ++#else ++ return WLAN_STATUS_FAILURE; ++#endif ++ } ++ ++ /* 4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC */ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ i4NewEntryIndex = -1; ++ for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) { ++ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]); ++ ++ /* For continuously sending Deauth frame, the minimum interval is ++ * MIN_DEAUTH_INTERVAL_MSEC. ++ */ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, ++ prDeauthInfo->rLastSendTime, MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) { ++ ++ i4NewEntryIndex = i; ++ } else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) && (!pfTxDoneHandler)) { ++ ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ /* 4 <3> Update information. */ ++ if (i4NewEntryIndex > 0) { ++ ++ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]); ++ ++ COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr); ++ prDeauthInfo->rLastSendTime = rCurrentTime; ++ } else { ++ /* NOTE(Kevin): for the case of AP mode, we may encounter this case ++ * if deauth all the associated clients. ++ */ ++ DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n"); ++ } ++ ++ /* 4 <4> Allocate a PKT_INFO_T for Deauthentication Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ ++ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN); ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Deauth Request.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <5> Find the Transmitter Address and BSSID. */ ++ if (prClassErrSwRfb) { ++ ++ /* The TA of Deauth is the A1 of RX frame */ ++ pucTransmitAddr = prWlanMacHeader->aucAddr1; ++ ++ switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) { ++ ++ case MASK_FC_FROM_DS: ++ /* The BSSID of Deauth is the A2 of RX frame */ ++ pucBssid = prWlanMacHeader->aucAddr2; ++ break; ++ ++ case MASK_FC_TO_DS: ++ /* The BSSID of Deauth is the A1 of RX frame */ ++ pucBssid = prWlanMacHeader->aucAddr1; ++ break; ++ ++ case MASK_TO_DS_FROM_DS: ++ /* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth ++ * to the A2 of RX frame for temporary solution. ++ */ ++ pucBssid = prWlanMacHeader->aucAddr2; ++ break; ++ ++ /* No Default */ ++ } ++ ++ } else if (prStaRec) { ++ eNetTypeIndex = prStaRec->ucNetTypeIndex; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ pucTransmitAddr = prBssInfo->aucOwnMacAddr; ++ ++ pucBssid = prBssInfo->aucBSSID; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else { ++ if (prAdapter->fgIsP2PRegistered) { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ ucStaRecIdx = STA_REC_INDEX_BMCAST; ++ ++ pucTransmitAddr = prBssInfo->aucOwnMacAddr; ++ ++ pucBssid = prBssInfo->aucBSSID; ++ ++ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ } else { ++ /* 20130122: free packet by samplin */ ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++#endif ++ ++ /* 4 <6> compose Deauthentication frame header and some fixed fields */ ++ authComposeDeauthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucReceiveAddr, pucTransmitAddr, pucBssid, u2ReasonCode); ++ ++#if CFG_SUPPORT_802_11W ++ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ ++ prDeauthFrame = ++ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ DBGLOG(TX, WARN, "authSendDeauthFrame with protection\n"); ++ } ++#endif ++ ++ /* 4 <7> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = ((prStaRec == NULL) ? ucStaRecIdx : prStaRec->ucIndex); ++ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ DBGLOG(SAA, INFO, "Sending Deauth, network: %d, seqNo %d\n", ++ eNetTypeIndex, prMsduInfo->ucTxSeqNum); ++ ++ /* 4 <8> Inform TXM to send this Deauthentication frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of authSendDeauthFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Deauthentication frame ++* if the given BSSID is matched. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] aucBSSID Given BSSID ++* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) ++{ ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ UINT_16 u2RxReasonCode; ++ ++ ASSERT(prSwRfb); ++ ASSERT(aucBSSID); ++ ASSERT(pu2ReasonCode); ++ ++ /* 4 <1> locate the Deauthentication Frame. */ ++ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Deauthentication Frame. */ ++#if 0 /* Kevin: Seems redundant */ ++ WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl) ++ u2RxFrameCtrl &= MASK_FRAME_TYPE; ++ if (u2RxFrameCtrl != MAC_FRAME_DEAUTH) ++ return WLAN_STATUS_FAILURE; ++#endif ++ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Check if this Deauth Frame is coming from Target BSSID */ ++ if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) { ++ DBGLOG(SAA, LOUD, "Ignore Deauth Frame from other BSS [ %pM ]\n", ++ prDeauthFrame->aucSrcAddr); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ ++ WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode); ++ *pu2ReasonCode = u2RxReasonCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authProcessRxDeauthFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Authentication frame. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] aucExpectedBSSID Given Expected BSSID. ++* @param[in] u2ExpectedAuthAlgNum Given Expected Authentication Algorithm Number ++* @param[in] u2ExpectedTransSeqNum Given Expected Transaction Sequence Number. ++* @param[out] pu2ReturnStatusCode Return Status Code. ++* ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++* @retval WLAN_STATUS_FAILURE The frame we will ignore. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN UINT_8 aucExpectedBSSID[], ++ IN UINT_16 u2ExpectedAuthAlgNum, ++ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ ASSERT(prSwRfb); ++ ASSERT(aucExpectedBSSID); ++ ASSERT(pu2ReturnStatusCode); ++ ++ /* 4 <1> locate the Authentication Frame. */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Check the BSSID */ ++ if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID)) ++ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ ++ /* 4 <3> Check the SA, which should not be MC/BC */ ++ if (prAuthFrame->aucSrcAddr[0] & BIT(0)) { ++ DBGLOG(P2P, WARN, "Invalid STA MAC with MC/BC bit set: %pM\n", ++ prAuthFrame->aucSrcAddr); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */ ++ if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum) ++ u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; ++ ++ if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum) ++ u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; ++ ++ *pu2ReturnStatusCode = u2ReturnStatusCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authProcessRxAuth1Frame() */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c +new file mode 100644 +index 000000000000..160779583655 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c +@@ -0,0 +1,2521 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/bss.c#3 ++*/ ++ ++/*! \file "bss.c" ++ \brief This file contains the functions for creating BSS(AP)/IBSS(AdHoc). ++ ++ This file contains the functions for BSS(AP)/IBSS(AdHoc). We may create a BSS/IBSS ++ network, or merge with exist IBSS network and sending Beacon Frame or reply ++ the Probe Response Frame for received Probe Request Frame. ++*/ ++ ++/* ++** Log: bss.c ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 14 2012 chinglan.wang ++ * NULL ++ * Fix the losing of the HT IE in assoc request.. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 08 2012 yuche.tsai ++ * NULL ++ * Fix FW assert when start Hot-Spot. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 01 20 2012 chinglan.wang ++ * 03 02 2012 terry.wu ++ * NULL ++ * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug. ++ * ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 15 2012 yuche.tsai ++ * NULL ++ * Fix wrong basic rate issue. ++ * ++ * 01 13 2012 yuche.tsai ++ * NULL ++ * WiFi Hot Spot Tethering for ICS ALPHA testing version. ++ * ++ * 11 03 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Always set short slot time to TRUE initially in AP mode ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 29 2011 eddie.chen ++ * [WCXRP00000608] [MT6620 Wi-Fi][DRV] Change wmm parameters in beacon ++ * Change wmm parameters in beacon. ++ * ++ * 03 29 2011 yuche.tsai ++ * [WCXRP00000607] [Volunteer Patch][MT6620][Driver] Coding Style Fix for klocwork scan. ++ * Fix klocwork issue. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 11 2011 chinglan.wang ++ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. ++ * . ++ * ++ * 03 03 2011 george.huang ++ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated ++ * . ++ * ++ * 03 03 2011 george.huang ++ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated ++ * modify to handle if beacon MSDU been released when BSS deactivated ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add code to let the beacon and probe response for Auto GO WSC . ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * Add code to send beacon and probe response WSC IE at Auto GO. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 12 2011 yuche.tsai ++ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. ++ * bss should create station record type according to callers input. ++ * ++ * 02 11 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * In p2p link function, check networktype before calling p2p function. ++ * ++ * 02 11 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * Modify p2p link function to avoid assert. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 25 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Fix the compile error in windows. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Add destination decision in AP mode. ++ * ++ * 01 24 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * .Fix typo and missing entry ++ * ++ * 12 30 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Fix prBssInfo->aucCWminLog to prBssInfo->aucCWminLogForBcast ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add WMM parameter for broadcast. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Before composing Beacon IE, assign network type index for msdu info, ++ * this information is needed by RLM module while composing some RLM related IE field. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Fix undefined pucDestAddr in bssUpdateBeaconContent() ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 11 2010 cp.wu ++ * NULL ++ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) ++ * 2) extending scanning result to 64 instead of 48 ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add support to RX probe response for P2P. ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) bugfix: do not stop timer for join after switched into normal_tr state, for providing chance for DHCP handshasking ++ * 2) modify rsnPerformPolicySelection() invoking ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * when IBSS is being merged-in, send command packet to PM for connected indication ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error while enable WIFI_DIRECT support. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct when ADHOC support is turned on. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fix compilation error when WIFI_DIRECT is turned on ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update bssProcessProbeRequest() to avoid redundant SSID IE {0,0} for IOT. ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set ++ * ++ * 05 18 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Ad-hoc Beacon should not carry HT OP and OBSS IEs ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Use TX MGMT Frame API for sending PS NULL frame to avoid the TX Burst Mechanism in TX FW Frame API ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Separate Beacon and ProbeResp IE array ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed the use of compiling flag MQM_WMM_PARSING ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 20 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Fix restart Beacon Timeout Func after connection diagnosis ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 04 16 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the wpa-none for ibss beacon. ++ * ++ * 04 15 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the protected bit at cap info for ad-hoc. ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Rename the CFG flags ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Update outgoing beacon's TX data rate ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add DTIM count update while TX Beacon ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify code due to define - BAND_24G and specific BSS_INFO_T was changed ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Revise data structure to share the same BSS_INFO_T for avoiding coding error ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) ++APPEND_VAR_IE_ENTRY_T txBcnIETable[] = { ++ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}, /* 221 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE}, /* 221 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++ {0, p2pFuncCalculateExtra_IELenForBeacon, p2pFuncGenerateExtra_IEForBeacon}, /* 221 */ ++#else ++ {0, p2pFuncCalculateP2p_IELenForBeacon, p2pFuncGenerateP2p_IEForBeacon}, /* 221 */ ++ {0, p2pFuncCalculateWSC_IELenForBeacon, p2pFuncGenerateWSC_IEForBeacon}, /* 221 */ ++ {0, p2pFuncCalculateP2P_IE_NoA, p2pFuncGenerateP2P_IE_NoA}, /* 221 */ ++#endif ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++}; ++ ++APPEND_VAR_IE_ENTRY_T txProbRspIETable[] = { ++ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ ++}; ++ ++#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines for all Operation Modes */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T for ++* Infrastructure or AdHoc Mode. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eStaType Assign STA Type for this STA_RECORD_T ++* @param[in] eNetTypeIndex Assign Net Type Index for this STA_RECORD_T ++* @param[in] prBssDesc Received Beacon/ProbeResp from this STA ++* ++* @retval Pointer to STA_RECORD_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T ++bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_STA_TYPE_T eStaType, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_8 ucNonHTPhyTypeSet; ++ ++ ASSERT(prBssDesc); ++ ++ /* 4 <1> Get a valid STA_RECORD_T */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); ++ if (!prStaRec) { ++ ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) eNetTypeIndex); ++ ++ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for ++ * exhausted case and do removal of unused STA_RECORD_T. ++ */ ++ ++ if (!prStaRec) { ++ ASSERT(FALSE); ++ return NULL; ++ } ++ ++ ASSERT(prStaRec); ++ ++ prStaRec->ucStaState = STA_STATE_1; ++ prStaRec->ucJoinFailureCount = 0; ++ /* TODO(Kevin): If this is an old entry, we may also reset the ucJoinFailureCount to 0. ++ */ ++ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prBssDesc->aucSrcAddr); ++ } ++ /* 4 <2> Setup STA TYPE and NETWORK */ ++ prStaRec->eStaType = eStaType; ++ ++ prStaRec->ucNetTypeIndex = eNetTypeIndex; ++ ++ /* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */ ++ prStaRec->u2CapInfo = prBssDesc->u2CapInfo; ++ ++ prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet; ++ prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet; ++ ++ prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet; ++ if (IS_STA_IN_AIS(prStaRec)) { ++ if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) || ++ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) || ++ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED) || ++ (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz))) { ++ DBGLOG(BSS, TRACE, "Ignore the HT Bit for TKIP as pairwise cipher configured!\n"); ++ prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; ++ } ++ } else { ++ DBGLOG(BSS, TRACE, "P2P skip TKIP limitation for HT Hit!\n"); ++ } ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet; ++ ++ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; ++ ++ /* Check for Target BSS's non HT Phy Types */ ++ if (ucNonHTPhyTypeSet) { ++ ++ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; ++ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; ++ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ ++ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++ prStaRec->fgHasBasicPhyType = TRUE; ++ } else { ++ /* Use mandatory for 11N only BSS */ ++ ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); ++ ++ { ++ /* TODO(Kevin): which value should we set for 11n ? ERP ? */ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++ prStaRec->fgHasBasicPhyType = FALSE; ++ } ++ ++ /* Update non HT Desired Rate Set */ ++ { ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ prStaRec->u2DesiredNonHTRateSet = ++ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); ++ } ++ ++ /* 4 <4> Update information from BSS_DESC_T to current P_STA_RECORD_T */ ++ if (IS_AP_STA(prStaRec)) { ++ /* do not need to parse IE for DTIM, ++ * which have been parsed before inserting into BSS_DESC_T ++ */ ++ if (prBssDesc->ucDTIMPeriod) ++ prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; ++ else ++ prStaRec->ucDTIMPeriod = 0; /* Means that TIM was not parsed. */ ++ } ++ /* 4 <5> Update default value */ ++ prStaRec->fgDiagnoseConnection = FALSE; ++ ++ /* 4 <6> Update default value for other Modules */ ++ /* Determine fgIsWmmSupported and fgIsUapsdSupported in STA_REC */ ++ mqmProcessScanResult(prAdapter, prBssDesc, prStaRec); ++ ++ return prStaRec; ++ ++} /* end of bssCreateStaRecFromBssDesc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Null Data frame. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] prStaRec Pointer to the STA_RECORD_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec) ++{ ++ P_WLAN_MAC_HEADER_T prNullFrame; ++ P_BSS_INFO_T prBssInfo; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ ASSERT(prBssInfo); ++ ++ prNullFrame = (P_WLAN_MAC_HEADER_T) pucBuffer; ++ ++ /* 4 <1> Decide the Frame Control Field */ ++ u2FrameCtrl = MAC_FRAME_NULL; ++ ++ if (IS_AP_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_TO_DS; ++ ++ if (prStaRec->fgSetPwrMgtBit) ++ u2FrameCtrl |= MASK_FC_PWR_MGT; ++ } else if (IS_CLIENT_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_FROM_DS; ++ } else if (IS_DLS_STA(prStaRec)) { ++ /* TODO(Kevin) */ ++ } else { ++ /* NOTE(Kevin): We won't send Null frame for IBSS */ ++ ASSERT(0); ++ return; ++ } ++ ++ /* 4 <2> Compose the Null frame */ ++ /* Fill the Frame Control field. */ ++ /* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Address 1 field with Target Peer Address. */ ++ COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr); ++ ++ /* Fill the Address 2 field with our MAC Address. */ ++ COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); ++ ++ /* Fill the Address 3 field with Target BSSID. */ ++ COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prNullFrame->u2SeqCtrl = 0; ++ ++ return; ++ ++} /* end of bssComposeNullFrameHeader() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the QoS Null Data frame. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] prStaRec Pointer to the STA_RECORD_T. ++* @param[in] ucUP User Priority. ++* @param[in] fgSetEOSP Set the EOSP bit. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP) ++{ ++ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; ++ P_BSS_INFO_T prBssInfo; ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2QosControl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ ASSERT(prBssInfo); ++ ++ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) pucBuffer; ++ ++ /* 4 <1> Decide the Frame Control Field */ ++ u2FrameCtrl = MAC_FRAME_QOS_NULL; ++ ++ if (IS_AP_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_TO_DS; ++ ++ if (prStaRec->fgSetPwrMgtBit) ++ u2FrameCtrl |= MASK_FC_PWR_MGT; ++ } else if (IS_CLIENT_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_FROM_DS; ++ } else if (IS_DLS_STA(prStaRec)) { ++ /* TODO(Kevin) */ ++ } else { ++ /* NOTE(Kevin): We won't send QoS Null frame for IBSS */ ++ ASSERT(0); ++ return; ++ } ++ ++ /* 4 <2> Compose the QoS Null frame */ ++ /* Fill the Frame Control field. */ ++ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prQoSNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Address 1 field with Target Peer Address. */ ++ COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr); ++ ++ /* Fill the Address 2 field with our MAC Address. */ ++ COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); ++ ++ /* Fill the Address 3 field with Target BSSID. */ ++ COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prQoSNullFrame->u2SeqCtrl = 0; ++ ++ u2QosControl = (UINT_16) (ucUP & WMM_QC_UP_MASK); ++ ++ if (fgSetEOSP) ++ u2QosControl |= WMM_QC_EOSP; ++ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */ ++ prQoSNullFrame->u2QosCtrl = u2QosControl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ return; ++ ++} /* end of bssComposeQoSNullFrameHeader() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send the Null Frame ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pfTxDoneHandler TX Done call back function ++* ++* @retval WLAN_STATUS_RESOURCE No available resources to send frame. ++* @retval WLAN_STATUS_SUCCESS Succe]ss. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ ++ /* Init with MGMT Header Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ ++ bssComposeNullFrame(prAdapter, (PUINT_8) ((ULONG) prMsduInfo->prPacket + MAC_TX_RESERVED_FIELD), prStaRec); ++#if 0 ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ TXM_SET_DATA_PACKET( ++ /* STA_REC ptr */ prStaRec, ++ /* MSDU_INFO ptr */ prMsduInfo, ++ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), ++ /* MAC HDR length */ WLAN_MAC_HEADER_LEN, ++ /* PAYLOAD ptr */ ++ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN), ++ /* PAYLOAD length */ 0, ++ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, ++ /* TID */ 0 /* BE: AC1 */ , ++ /* Flag 802.11 */ TRUE, ++ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , ++ /* Resource TC */ 0 /* Irrelevant */ , ++ /* Flag 802.1x */ FALSE, ++ /* TX-done callback */ pfTxDoneHandler, ++ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, ++ /* PS Session ID */ 0 /* Irrelevant */ , ++ /* Flag fixed rate */ TRUE, ++ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, ++ /* Fixed-rate retry */ BSS_DEFAULT_CONN_TEST_NULL_FRAME_RETRY_LIMIT, ++ /* PAL LLH */ 0 /* Irrelevant */ , ++ /* ACL SN */ 0 /* Irrelevant */ , ++ /* Flag No Ack */ FALSE ++ ); ++ ++ /* Terminate with a NULL pointer */ ++ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* Indicate the packet to TXM */ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ txmSendFwDataPackets(prMsduInfo); ++#endif ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssSendNullFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send the QoS Null Frame ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pfTxDoneHandler TX Done call back function ++* ++* @retval WLAN_STATUS_RESOURCE No available resources to send frame. ++* @retval WLAN_STATUS_SUCCESS Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ ++ /* Init with MGMT Header Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ ++ bssComposeQoSNullFrame(prAdapter, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prStaRec, ucUP, FALSE); ++#if 0 ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ TXM_SET_DATA_PACKET( ++ /* STA_REC ptr */ prStaRec, ++ /* MSDU_INFO ptr */ prMsduInfo, ++ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), ++ /* MAC HDR length */ WLAN_MAC_HEADER_QOS_LEN, ++ /* PAYLOAD ptr */ ++ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN), ++ /* PAYLOAD length */ 0, ++ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, ++ /* TID */ 0 /* BE: AC1 */ , ++ /* Flag 802.11 */ TRUE, ++ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , ++ /* Resource TC */ 0 /* Irrelevant */ , ++ /* Flag 802.1x */ FALSE, ++ /* TX-done callback */ pfTxDoneHandler, ++ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, ++ /* PS Session ID */ 0 /* Irrelevant */ , ++ /* Flag fixed rate */ TRUE, ++ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, ++ /* Fixed-rate retry */ TXM_DEFAULT_DATA_FRAME_RETRY_LIMIT, ++ /* PAL LLH */ 0 /* Irrelevant */ , ++ /* ACL SN */ 0 /* Irrelevant */ , ++ /* Flag No Ack */ FALSE ++ ); ++ ++ /* Terminate with a NULL pointer */ ++ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* Indicate the packet to TXM */ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ txmSendFwDataPackets(prMsduInfo); ++#endif ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssSendQoSNullFrame() */ ++ ++#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) ++/*----------------------------------------------------------------------------*/ ++/* Routines for both IBSS(AdHoc) and BSS(AP) */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate Information Elements of Extended ++* Support Rate ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ PUINT_8 pucBuffer; ++ UINT_8 ucExtSupRatesLen; ++ ++ ASSERT(prMsduInfo); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); ++ ASSERT(prBssInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ++ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; ++ else ++ ucExtSupRatesLen = 0; ++ ++ /* Fill the Extended Supported Rates element. */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, ++ &prBssInfo->aucAllSupportedRates[ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* end of bssGenerateExtSuppRate_IE() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for Beacon ++* or Probe Response Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr) ++{ ++ PUINT_8 pucBuffer; ++ UINT_8 ucSupRatesLen; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prBssInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ /* Compose the frame body of the Probe Response frame. */ ++ /* 4 <1> Fill the SSID element. */ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ if (prBssInfo->eHiddenSsidType == ENUM_HIDDEN_SSID_LEN) { ++ if ((!pucDestAddr) && /* For Beacon only */ ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { ++ SSID_IE(pucBuffer)->ucLength = 0; ++ } else { /* Probe response */ ++ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; ++ if (prBssInfo->ucSSIDLen) ++ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ } ++ } else { ++ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; ++ if (prBssInfo->ucSSIDLen) ++ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ } ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ /* 4 <2> Fill the Supported Rates element. */ ++ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ++ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; ++ else ++ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; ++ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ /* 4 <3> Fill the DS Parameter Set element. */ ++ if (prBssInfo->eBand == BAND_2G4) { ++ DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET; ++ DS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_DS_PARAMETER_SET; ++ DS_PARAM_IE(pucBuffer)->ucCurrChnl = prBssInfo->ucPrimaryChannel; ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ /* 4 <4> IBSS Parameter Set element, ID: 6 */ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET; ++ IBSS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_IBSS_PARAMETER_SET; ++ WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), prBssInfo->u2ATIMWindow); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ /* 4 <5> TIM element, ID: 5 */ ++ if ((!pucDestAddr) && /* For Beacon only. */ ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /*no fgIsP2PRegistered protect */ ++ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++#if 0 ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ UINT_8 ucBitmapControl = 0; ++ UINT_32 u4N1, u4N2; ++ ++ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); ++ ++ /* Clear existing value. */ ++ prP2pSpecificBssInfo->ucBitmapCtrl = 0; ++ kalMemZero(prP2pSpecificBssInfo->aucPartialVirtualBitmap, ++ sizeof(prP2pSpecificBssInfo->aucPartialVirtualBitmap)); ++ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ TIM_IE(pucBuffer)->ucDTIMCount = prBssInfo->ucDTIMCount; ++ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; ++ ++ /* Setup DTIM Count for next TBTT. */ ++ if (prBssInfo->ucDTIMCount == 0) { ++ /*Do nothing*/ ++ /* 3 *** pmQueryBufferedBCAST(); */ ++ } ++ /* 3 *** pmQueryBufferedPSNode(); */ ++ /* TODO(Kevin): Call PM Module here to loop all STA_RECORD_Ts and it ++ * will call bssSetTIMBitmap to toggle the Bitmap. ++ */ ++ ++ /* Set Virtual Bitmap for UCAST */ ++ u4N1 = (prP2pSpecificBssInfo->u2SmallestAID >> 4) << 1; /* Find the largest even number. */ ++ u4N2 = prP2pSpecificBssInfo->u2LargestAID >> 3; /* Find the smallest number. */ ++ ++ ASSERT(u4N2 >= u4N1); ++ ++ kalMemCopy(TIM_IE(pucBuffer)->aucPartialVirtualMap, ++ &prP2pSpecificBssInfo->aucPartialVirtualBitmap[u4N1], ((u4N2 - u4N1) + 1)); ++ ++ /* Set Virtual Bitmap for BMCAST */ ++ /* BMC bit only indicated when DTIM count == 0. */ ++ if (prBssInfo->ucDTIMCount == 0) ++ ucBitmapControl = prP2pSpecificBssInfo->ucBitmapCtrl; ++ TIM_IE(pucBuffer)->ucBitmapControl = ucBitmapControl | (UINT_8) u4N1; ++ ++ TIM_IE(pucBuffer)->ucLength = ((u4N2 - u4N1) + 4); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++#else ++ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ ++ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP); /*((u4N2 - u4N1) + 4) */ ++ /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucDTIMCount = 0; /*prBssInfo->ucDTIMCount */ ++ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; ++ /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucBitmapControl = 0; /*ucBitmapControl | (UINT_8)u4N1 */ ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ ++#endif ++ ++ } else ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ { ++ /* NOTE(Kevin): 1. AIS - Didn't Support AP Mode. ++ * 2. BOW - Didn't Support BCAST and PS. ++ */ ++ } ++ ++ } ++ ++} /* end of bssBuildBeaconProbeRespFrameCommonIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Beacon/Probe Response frame header and ++* its fixed fields. ++* ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. ++* @param[in] pucOwnMACAddress Given Our MAC Address. ++* @param[in] pucBSSID Given BSSID of the BSS. ++* @param[in] u2BeaconInterval Given Beacon Interval. ++* @param[in] u2CapInfo Given Capability Info. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN PUINT_8 pucDestAddr, ++ IN PUINT_8 pucOwnMACAddress, ++ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo) ++{ ++ P_WLAN_BEACON_FRAME_T prBcnProbRspFrame; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ UINT_16 u2FrameCtrl; ++ ++ DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF"); ++ /* DBGLOG(INIT, LOUD, ("\n")); */ ++ ++ ASSERT(pucBuffer); ++ ASSERT(pucOwnMACAddress); ++ ASSERT(pucBSSID); ++ ++ prBcnProbRspFrame = (P_WLAN_BEACON_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */ ++ /* Fill the Frame Control field. */ ++ if (pucDestAddr) { ++ u2FrameCtrl = MAC_FRAME_PROBE_RSP; ++ } else { ++ u2FrameCtrl = MAC_FRAME_BEACON; ++ pucDestAddr = aucBCAddr; ++ } ++ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */ ++ COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress); ++ ++ /* Fill the BSSID field with current BSSID. */ ++ COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prBcnProbRspFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's common fixed field part of the Beacon /ProbeResp frame. */ ++ /* MAC will update TimeStamp field */ ++ ++ /* Fill the Beacon Interval field. */ ++ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, u2BeaconInterval); */ ++ prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Capability Information field. */ ++ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */ ++ prBcnProbRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ ++ ++} /* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eNetTypeIndex Specify which network reply the Probe Response. ++* ++* @retval WLAN_STATUS_SUCCESS Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_WLAN_BEACON_FRAME_T prBcnFrame; ++ UINT_32 i; ++ ++ DEBUGFUNC("bssUpdateBeaconContent"); ++ DBGLOG(BSS, LOUD, "\n"); ++ ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */ ++ /* Allocate a MSDU_INFO_T */ ++ /* For Beacon */ ++ prMsduInfo = prBssInfo->prBeacon; ++ ++ /* beacon prMsduInfo will be NULLify once BSS deactivated, so skip if it is */ ++ if (prMsduInfo == NULL) ++ return WLAN_STATUS_SUCCESS; ++ /* 4 <2> Compose header */ ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ NULL, ++ prBssInfo->aucOwnMacAddr, ++ prBssInfo->aucBSSID, ++ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); ++ ++ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + ++ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); ++ ++ prMsduInfo->ucNetworkType = eNetTypeIndex; ++ ++ /* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */ ++ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL); ++ ++ /* 4 <4> Compose IEs in MSDU_INFO_T */ ++ ++ /* Append IE for Beacon */ ++ for (i = 0; i < sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txBcnIETable[i].pfnAppendIE) ++ txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; ++ ++ return nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ eNetTypeIndex, ++ prBssInfo->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)); ++ ++} /* end of bssUpdateBeaconContent() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to the given ++* Destination Address. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eNetTypeIndex Specify which network reply the Probe Response. ++* @param[in] pucDestAddr Pointer to the Destination Address to reply ++* @param[in] u4ControlFlags Control flags for information on Probe Response. ++* ++* @retval WLAN_STATUS_RESOURCE No available resources to send frame. ++* @retval WLAN_STATUS_SUCCESS Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedFixedIELen; ++ UINT_16 u2EstimatedExtraIELen; ++ P_APPEND_VAR_IE_ENTRY_T prIeArray = NULL; ++ UINT_32 u4IeArraySize = 0; ++ UINT_32 i; ++ ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if (!pucDestAddr) { /* For Beacon */ ++ prIeArray = &txBcnIETable[0]; ++ u4IeArraySize = sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); ++ } else { ++ prIeArray = &txProbRspIETable[0]; ++ u4IeArraySize = sizeof(txProbRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); ++ } ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */ ++ /* Allocate a MSDU_INFO_T */ ++ ++ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Fields */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ TIMESTAMP_FIELD_LEN + ++ BEACON_INTERVAL_FIELD_LEN + ++ CAP_INFO_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP)); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < u4IeArraySize; i++) { ++ u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen; ++ ++ if (u2EstimatedFixedIELen) { ++ u2EstimatedExtraIELen += u2EstimatedFixedIELen; ++ } else { ++ ASSERT(prIeArray[i].pfnCalculateVariableIELen); ++ ++ u2EstimatedExtraIELen += (UINT_16) ++ prIeArray[i].pfnCalculateVariableIELen(prAdapter, eNetTypeIndex, NULL); ++ } ++ } ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", ((!pucDestAddr) ? "Beacon" : "Probe Response")); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Beacon/Probe Response frame header and fixed fields in MSDU_INfO_T. */ ++ /* Compose Header and Fixed Field */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) { ++ if (prAdapter->fgIsP2PRegistered) { ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ++ ((ULONG) (prMsduInfo->prPacket) + ++ MAC_TX_RESERVED_FIELD), pucDestAddr, ++ prAdapter->rWifiVar.aucDeviceAddress, ++ prAdapter->rWifiVar.aucDeviceAddress, ++ DOT11_BEACON_PERIOD_DEFAULT, ++ (prBssInfo->u2CapInfo & ++ ~(CAP_INFO_ESS | CAP_INFO_IBSS))); ++ } ++ } else ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ { ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucDestAddr, prBssInfo->aucOwnMacAddr, prBssInfo->aucBSSID, ++ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); ++ } ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = 0xFF; ++ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + ++ TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose the frame body's Common IEs of the Beacon/ProbeResp frame. */ ++ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, pucDestAddr); ++ ++ /* 4 <5> Compose IEs in MSDU_INFO_T */ ++ ++ /* Append IE */ ++ for (i = 0; i < u4IeArraySize; i++) { ++ if (prIeArray[i].pfnAppendIE) ++ prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Inform TXM to send this Beacon /Probe Response frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssSendBeaconProbeResponse() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Probe Request Frame and then send ++* back the corresponding Probe Response Frame if the specified conditions ++* were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always return success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BSS_INFO_T prBssInfo; ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ UINT_8 aucBCBSSID[] = BC_BSSID; ++ BOOLEAN fgIsBcBssid; ++ BOOLEAN fgReplyProbeResp; ++ UINT_32 u4CtrlFlagsForProbeResp = 0; ++ ENUM_BAND_T eBand; ++ UINT_8 ucHwChannelNum; ++ ++ ASSERT(prSwRfb); ++ ++ /* 4 <1> Parse Probe Req and Get BSSID */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID)) ++ fgIsBcBssid = TRUE; ++ else ++ fgIsBcBssid = FALSE; ++ ++ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ ++ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { ++ ++ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) ++ continue; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if ((!fgIsBcBssid) && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) ++ continue; ++ ++ eBand = HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr); ++ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); ++ ++ if (prBssInfo->eBand != eBand) ++ continue; ++ ++ if (prBssInfo->ucPrimaryChannel != ucHwChannelNum) ++ continue; ++ ++ fgReplyProbeResp = FALSE; ++ ++ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { ++ ++#if CFG_SUPPORT_ADHOC ++ fgReplyProbeResp = aisValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); ++#endif ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex)) { ++ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { ++ /* Resource margin is enough */ ++ fgReplyProbeResp = ++ p2pFuncValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); ++ } ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) ++ fgReplyProbeResp = bowValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); ++#endif ++ ++ if (fgReplyProbeResp) { ++ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { ++ /* Resource margin is enough */ ++ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr, ++ u4CtrlFlagsForProbeResp); ++ } ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssProcessProbeRequest() */ ++ ++#if 0 /* NOTE(Kevin): condition check should move to P2P_FSM.c */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Probe Request Frame and then send ++* back the corresponding Probe Response Frame if the specified conditions ++* were matched. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always return success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; ++ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ UINT_8 aucBCBSSID[] = BC_BSSID; ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ BOOLEAN fgReplyProbeResp; ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgP2PTargetDeviceFound; ++ UINT_8 aucP2PWildcardSSID[] = P2P_WILDCARD_SSID; ++#endif ++ ++ ASSERT(prSwRfb); ++ ++ /* 4 <1> Parse Probe Req and Get SSID IE ptr */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) ((UINT_32) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); ++ ++ prIeSsid = (P_IE_SSID_T) NULL; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ ++ case ELEM_ID_SUP_RATES: ++ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. ++ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), ++ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" ++ */ ++ /* if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SUP_RATES) { */ ++ if (IE_LEN(pucIE) <= RATE_NUM) ++ prIeSupportedRate = SUP_RATES_IE(pucIE); ++ break; ++ ++ case ELEM_ID_EXTENDED_SUP_RATES: ++ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); ++ break; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* TODO: P2P IE & WCS IE parsing for P2P. */ ++ case ELEM_ID_P2P: ++ ++ break; ++#endif ++ ++ /* no default */ ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ ++ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { ++ ++ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) ++ continue; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if (UNEQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID) && ++ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) { ++ /* BSSID not Wildcard BSSID. */ ++ continue; ++ } ++ ++ fgReplyProbeResp = FALSE; ++ ++ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ ++ /* TODO(Kevin): Check if we are IBSS Master. */ ++ if (TRUE && prIeSsid) { ++ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, ++ prIeSsid->aucSSID, prIeSsid->ucLength)) { ++ fgReplyProbeResp = TRUE; ++ } ++ } ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex) { ++ ++ /* TODO(Kevin): Move following lines to p2p_fsm.c */ ++ ++ if ((prIeSsid) && ++ ((prIeSsid->ucLength == BC_SSID_LEN) || ++ (EQUAL_SSID(aucP2PWildcardSSID, ++ P2P_WILDCARD_SSID_LEN, prIeSsid->aucSSID, prIeSsid->ucLength)))) { ++ /* if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prMgtHdr->aucSrcAddr, ++ pucIE, u2IELength)) { */ ++ if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prSwRfb)) { ++ /* Extand channel request time & cancel scan request. */ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ /* TODO: RX probe request may not caused by LISTEN state. */ ++ /* TODO: It can be GO. */ ++ /* Generally speaking, cancel a non-exist scan request is fine. ++ * We can check P2P FSM here for only LISTEN state. ++ */ ++ ++ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ /* Abort JOIN process. */ ++ prScanCancelMsg = ++ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancelMsg) { ++ ASSERT(0); /* Can't abort SCN FSM */ ++ continue; ++ } ++ ++ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; ++ prScanCancelMsg->ucSeqNum = prP2pFsmInfo->ucSeqNumOfScnMsg; ++ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; ++ prScanCancelMsg->fgIsChannelExt = TRUE; ++ ++ mboxSendMsg(prAdapter, ++ MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); ++ } ++ } else { ++ /* 1. Probe Request without SSID. ++ * 2. Probe Request with SSID not Wildcard SSID & not P2P Wildcard SSID. ++ */ ++ continue; ++ } ++ ++#if 0 /* Frog */ ++ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_LISTEN) { ++ /* P2P 2.4.1 - P2P Devices shall not respond to Probe Request frames ++ which only contain 11b rates only. */ ++ if (prIeSupportedRate || prIeExtSupportedRate) { ++ UINT_16 u2OperationalRateSet, u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ ++ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, ++ &u2OperationalRateSet, ++ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ ++ &fgIsUnknownBssBasicRate); ++ ++ if (u2OperationalRateSet & ~RATE_SET_HR_DSSS) ++ continue; ++ } ++ } ++ /* TODO: Check channel time before first check point to: */ ++ /* If Target device is selected: ++ * 1. Send XXXX request frame. ++ * else ++ * 1. Send Probe Response frame. ++ */ ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ /* TODO(Kevin): During PROVISION state, can we reply Probe Response ? */ ++ ++ /* TODO(Kevin): ++ * If we are GO, accept legacy client --> accept Wildcard SSID ++ * If we are in Listen State, accept only P2P Device --> check P2P IE and WPS IE ++ */ ++ if (TRUE /* We are GO */ && prIeSsid) { ++ UINT_8 aucSSID[] = P2P_WILDCARD_SSID; ++ ++ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, ++ prIeSsid->aucSSID, prIeSsid->ucLength) || ++ EQUAL_SSID(aucSSID, P2P_WILDCARD_SSID_LEN, ++ prIeSsid->aucSSID, prIeSsid->ucLength)) { ++ fgReplyProbeResp = TRUE; ++ } ++ } ++/* else if (FALSE) { */ /* We are in Listen State */ ++/* } */ ++ ++ /* TODO(Kevin): Check P2P IE and WPS IE */ ++ } ++#endif ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) { ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ /* Do nothing */ ++ /* TODO(Kevin): TBD */ ++ } ++ } ++#endif ++ else ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ if (fgReplyProbeResp) ++ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr); ++ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssProcessProbeRequest() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to clear the client list for AdHoc or AP Mode ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prBssInfo Given related BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prPeerStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prPeerStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ cnmStaRecChangeState(prAdapter, prPeerStaRec, STA_STATE_1); ++ } ++ ++ LINK_INITIALIZE(prStaRecOfClientList); ++ } ++ ++} /* end of bssClearClientList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to Add a STA_RECORD_T to the client list for AdHoc or AP Mode ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prBssInfo Given related BSS_INFO_T. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ ++ if (prCurrStaRec == prStaRec) { ++ DBGLOG(BSS, WARN, ++ "Current Client List already contains that STA_RECORD_T[%pM]\n", ++ prStaRec->aucMacAddr); ++ return; ++ } ++ } ++ } ++ ++ LINK_INSERT_TAIL(prStaRecOfClientList, &prStaRec->rLinkEntry); ++ ++} /* end of bssAddStaRecToClientList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to Remove a STA_RECORD_T from the client list for AdHoc or AP Mode ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ ++#if 0 ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ ++ if (prCurrStaRec == prStaRec) { ++ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); ++ ++ return; ++ } ++ } ++ } ++#endif ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ if ((ULONG) prStaRec == (ULONG) prLinkEntry) { ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); ++ return; ++ } ++ } ++ } ++ ++ DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T[%pM] before removing.\n", ++ prStaRec->aucMacAddr); ++ ++} /* end of bssRemoveStaRecFromClientList() */ ++#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Get station record by Address for AP mode ++* ++* @param[in] prBssInfo Pointer to BSS_INFO_T. ++* @param[in] pucMacAddr Pointer to target mac address ++* ++* @return pointer of STA_RECORD_T if found, otherwise, return NULL ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ASSERT(pucMacAddr); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMacAddr)) ++ return prCurrStaRec; ++ } ++ } ++ return NULL; ++} ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/* Routines for IBSS(AdHoc) only */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to process Beacons from current Ad-Hoc network peers. ++* We also process Beacons from other Ad-Hoc network during SCAN. If it has ++* the same SSID and we'll decide to merge into it if it has a larger TSF. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* @param[in] prBSSDesc Pointer to the BSS Descriptor. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI) ++{ ++ P_STA_RECORD_T prStaRec = NULL; ++ ++ BOOLEAN fgIsCheckCapability = FALSE; ++ BOOLEAN fgIsCheckTSF = FALSE; ++ BOOLEAN fgIsGoingMerging = FALSE; ++ BOOLEAN fgIsSameBSSID; ++ ++ ASSERT(prBssInfo); ++ ASSERT(prBssDesc); ++ ++ /* 4 <1> Process IBSS Beacon only after we create or merge with other IBSS. */ ++ if (!prBssInfo->fgIsBeaconActivated) ++ return; ++ /* 4 <2> Get the STA_RECORD_T of TA. */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prBssDesc->aucSrcAddr); ++ ++ fgIsSameBSSID = UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID) ? FALSE : TRUE; ++ ++ /* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */ ++ if (fgIsSameBSSID) { ++ ++ /* Same BSSID: ++ * Case I. This is a new TA and it has decide to merged with us. ++ * a) If fgIsMerging == FALSE - we will send msg to notify AIS. ++ * b) If fgIsMerging == TRUE - already notify AIS. ++ * Case II. This is an old TA and we've already merged together. ++ */ ++ if (!prStaRec) { ++ ++ /* For Case I - Check this IBSS's capability first before adding this Sta Record. */ ++ fgIsCheckCapability = TRUE; ++ ++ /* If check is passed, then we perform merging with this new IBSS */ ++ fgIsGoingMerging = TRUE; ++ ++ } else { ++ ++ ASSERT((prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) && IS_ADHOC_STA(prStaRec)); ++ ++ if (prStaRec->ucStaState != STA_STATE_3) { ++ ++ if (!prStaRec->fgIsMerging) { ++ ++ /* For Case I - Check this IBSS's capability first ++ * before adding this Sta Record. */ ++ fgIsCheckCapability = TRUE; ++ ++ /* If check is passed, then we perform merging with this new IBSS */ ++ fgIsGoingMerging = TRUE; ++ } else { ++ /* For Case II - Update rExpirationTime of Sta Record */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ } ++ } else { ++ /* For Case II - Update rExpirationTime of Sta Record */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ } ++ ++ } ++ } else { ++ ++ /* Unequal BSSID: ++ * Case III. This is a new TA and we need to compare the TSF and get the winner. ++ * Case IV. This is an old TA and it merge into a new IBSS before we do the same thing. ++ * We need to compare the TSF to get the winner. ++ * Case V. This is an old TA and it restart a new IBSS. We also need to ++ * compare the TSF to get the winner. ++ */ ++ ++ /* For Case III, IV & V - We'll always check this new IBSS's capability first ++ * before merging into new IBSS. ++ */ ++ fgIsCheckCapability = TRUE; ++ ++ /* If check is passed, we need to perform TSF check to decide the major BSSID */ ++ fgIsCheckTSF = TRUE; ++ ++ /* For Case IV & V - We won't update rExpirationTime of Sta Record */ ++ } ++ ++ /* 4 <7> Check this BSS_DESC_T's capability. */ ++ if (fgIsCheckCapability) { ++ BOOLEAN fgIsCapabilityMatched = FALSE; ++ ++ do { ++ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Unsupported Phy.\n", ++ prBssDesc->aucSrcAddr); ++ ++ break; ++ } ++ ++ if (prBssDesc->fgIsUnknownBssBasicRate) { ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Unknown Basic Rate.\n", ++ prBssDesc->aucSrcAddr); ++ ++ break; ++ } ++ ++ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", ++ prBssDesc->aucSrcAddr); ++ ++ break; ++ } ++ ++ fgIsCapabilityMatched = TRUE; ++ } while (FALSE); ++ ++ if (!fgIsCapabilityMatched) { ++ ++ if (prStaRec) { ++ /* For Case II - We merge this STA_RECORD in RX Path. ++ * Case IV & V - They change their BSSID after we merge with them. ++ */ ++ ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", ++ prBssDesc->aucSrcAddr); ++ } ++ ++ return; ++ } ++ ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Peer MAC: %pM - Check capability was passed.\n", ++ prBssDesc->aucSrcAddr); ++ } ++ ++ if (fgIsCheckTSF) { ++#if CFG_SLT_SUPPORT ++ fgIsGoingMerging = TRUE; ++#else ++ if (prBssDesc->fgIsLargerTSF) ++ fgIsGoingMerging = TRUE; ++ else ++ return; ++#endif ++ } ++ ++ if (fgIsGoingMerging) { ++ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; ++ ++ /* 4 <1> We will merge with to this BSS immediately. */ ++ prBssDesc->fgIsConnecting = TRUE; ++ prBssDesc->fgIsConnected = FALSE; ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, ++ STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); ++ ++ if (!prStaRec) { ++ /* no memory ? */ ++ return; ++ } ++ ++ prStaRec->fgIsMerging = TRUE; ++ ++ /* update RCPI */ ++ prStaRec->ucRCPI = ucRCPI; ++ ++ /* 4 <3> Send Merge Msg to CNM to obtain the channel privilege. */ ++ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_IBSS_PEER_FOUND_T)); ++ ++ if (!prAisIbssPeerFoundMsg) { ++ ++ ASSERT(0); /* Can't send Merge Msg */ ++ return; ++ } ++ ++ prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS; ++ prAisIbssPeerFoundMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++ prAisIbssPeerFoundMsg->prStaRec = prStaRec; ++ ++ /* Inform AIS to do STATE TRANSITION ++ * For Case I - If AIS in IBSS_ALONE, let it jump to NORMAL_TR after we know the new member. ++ * For Case III, IV - Now this new BSSID wins the TSF, follow it. ++ */ ++ if (fgIsSameBSSID) { ++ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; ++ } else { ++#if CFG_SLT_SUPPORT ++ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; ++#else ++ prAisIbssPeerFoundMsg->fgIsMergeIn = (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE; ++#endif ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisIbssPeerFoundMsg, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++} /* end of ibssProcessMatchedBeacon() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the Capability for Ad-Hoc to decide if we are ++* able to merge with(same capability). ++* ++* @param[in] prBSSDesc Pointer to the BSS Descriptor. ++* ++* @retval WLAN_STATUS_FAILURE Can't pass the check of Capability. ++* @retval WLAN_STATUS_SUCCESS Pass the check of Capability. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ ++ ASSERT(prBssDesc); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ do { ++ /* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */ ++ if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) && ++ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) { ++ break; ++ } else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) && ++ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) { ++ break; ++ } ++ /* 4 <2> Check the Short Slot Time. */ ++#if 0 /* Do not check ShortSlotTime until Wi-Fi define such policy */ ++ if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) { ++ if (((prConnSettings->fgIsShortSlotTimeOptionEnable) && ++ !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) || ++ (!(prConnSettings->fgIsShortSlotTimeOptionEnable) && ++ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))) { ++ break; ++ } ++ } ++#endif ++ ++ /* 4 <3> Check the ATIM window setting. */ ++ if (prBssDesc->u2ATIMWindow) { ++ DBGLOG(BSS, INFO, "AdHoc PS was not supported(ATIM Window: %d)\n", prBssDesc->u2ATIMWindow); ++ break; ++ } ++#if CFG_RSN_MIGRATION ++ /* 4 <4> Check the Security setting. */ ++ if (!rsnPerformPolicySelection(prAdapter, prBssDesc)) ++ break; ++#endif ++ ++ rStatus = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rStatus; ++ ++} /* end of ibssCheckCapabilityForAdHocMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will initial the BSS_INFO_T for IBSS Mode. ++* ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) ++{ ++ UINT_8 ucLowestBasicRateIndex; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ PUINT_16 pu2BSSID = (PUINT_16) &aucBSSID[0]; ++ UINT_32 i; ++ ++ ASSERT(prBssInfo); ++ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_IBSS); ++ ++ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); ++ ++ /* 4 <2> Setup BSSID */ ++ if (!prBssInfo->fgHoldSameBssidForIBSS) { ++ ++ for (i = 0; i < sizeof(aucBSSID) / sizeof(UINT_16); i++) ++ pu2BSSID[i] = (UINT_16) (kalRandomNumber() & 0xFFFF); ++ ++ aucBSSID[0] &= ~0x01; /* 7.1.3.3.3 - The individual/group bit of the address is set to 0. */ ++ aucBSSID[0] |= 0x02; /* 7.1.3.3.3 - The universal/local bit of the address is set to 1. */ ++ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID); ++ } ++ /* 4 <3> Setup Capability - Short Preamble */ ++ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ ++ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ ++ /* 4 <4> Setup Capability - Short Slot Time */ ++ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ ++ prBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ ++ ++ /* 4 <5> Compoase Capability */ ++ prBssInfo->u2CapInfo = CAP_INFO_IBSS; ++ ++ if (prBssInfo->fgIsProtection) ++ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; ++ ++ if (prBssInfo->fgIsShortPreambleAllowed) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ ++ if (prBssInfo->fgUseShortSlotTime) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ ++ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); ++ ++ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; ++ ++} /* end of ibssInitForAdHoc() */ ++ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++#if CFG_SUPPORT_AAA ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for BSS(AP) only */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will initial the BSS_INFO_T for AP Mode. ++* ++* @param[in] prBssInfo Given related BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate) ++{ ++ UINT_8 ucLowestBasicRateIndex; ++ ++ P_AC_QUE_PARMS_T prACQueParms; ++ ++ ENUM_WMM_ACI_T eAci; ++ ++ UINT_8 auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; ++ UINT_8 auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 }; ++ UINT_8 auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 }; ++ UINT_8 auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ ++ ++ UINT_8 auCWminLog2[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; ++ UINT_8 auCWmaxLog2[WMM_AC_INDEX_NUM] = { 7, 10, 4, 3 }; ++ UINT_8 auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 }; ++ UINT_8 auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ ++ ++ DEBUGFUNC("bssInitForAP"); ++ DBGLOG(BSS, LOUD, "\n"); ++ ++ ASSERT(prBssInfo); ++ ASSERT((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || (prBssInfo->eCurrentOPMode == OP_MODE_BOW)); ++ ++#if 0 ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M; ++ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M; ++#endif ++ ++ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ if (fgIsRateUpdate) { ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); ++ } ++ /* 4 <2> Setup BSSID */ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr); ++ ++ /* 4 <3> Setup Capability - Short Preamble */ ++ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ ++ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ ++ /* 4 <4> Setup Capability - Short Slot Time */ ++ prBssInfo->fgUseShortSlotTime = TRUE; ++ ++ /* 4 <5> Compoase Capability */ ++ prBssInfo->u2CapInfo = CAP_INFO_ESS; ++ ++ if (prBssInfo->fgIsProtection) ++ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; ++ ++ if (prBssInfo->fgIsShortPreambleAllowed) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ ++ if (prBssInfo->fgUseShortSlotTime) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ ++ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); ++ ++ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; ++ ++ /* 4 <7> Fill the EDCA */ ++ ++ prACQueParms = prBssInfo->arACQueParmsForBcast; ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prACQueParms[eAci].fgIsACMSet = FALSE; ++ prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci]; ++ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1; ++ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1; ++ prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci]; ++ ++ prBssInfo->aucCWminLog2ForBcast[eAci] = auCWminLog2ForBcast[eAci]; /* used to send WMM IE */ ++ prBssInfo->aucCWmaxLog2ForBcast[eAci] = auCWmaxLog2ForBcast[eAci]; ++ ++ DBGLOG(BSS, INFO, "Bcast: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", ++ eAci, prACQueParms[eAci].fgIsACMSet, ++ prACQueParms[eAci].u2Aifsn, ++ prACQueParms[eAci].u2CWmin, ++ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); ++ ++ } ++ ++ prACQueParms = prBssInfo->arACQueParms; ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prACQueParms[eAci].fgIsACMSet = FALSE; ++ prACQueParms[eAci].u2Aifsn = auAifs[eAci]; ++ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1; ++ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1; ++ prACQueParms[eAci].u2TxopLimit = auTxop[eAci]; ++ ++ DBGLOG(BSS, INFO, "eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", ++ eAci, prACQueParms[eAci].fgIsACMSet, ++ prACQueParms[eAci].u2Aifsn, ++ prACQueParms[eAci].u2CWmin, ++ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); ++ } ++ ++ /* Note: Caller should update the EDCA setting to HW by nicQmUpdateWmmParms() it there is no AIS network */ ++ /* Note: In E2, only 4 HW queues. The the Edca parameters should be folow by AIS network */ ++ /* Note: In E3, 8 HW queues. the Wmm parameters should be updated to right queues according to BSS */ ++ ++} /* end of bssInitForAP() */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update DTIM Count ++* ++* @param[in] eNetTypeIndex Specify which network to update ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ ++ /* Setup DTIM Count for next TBTT. */ ++ if (prBssInfo->ucDTIMCount > 0) { ++ prBssInfo->ucDTIMCount--; ++ } else { ++ ++ ASSERT(prBssInfo->ucDTIMPeriod > 0); ++ ++ prBssInfo->ucDTIMCount = prBssInfo->ucDTIMPeriod - 1; ++ } ++ } ++ ++} /* end of bssUpdateDTIMIE() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to set the Virtual Bitmap in TIM Information Elements ++* ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* @param[in] u2AssocId The association id to set in Virtual Bitmap. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId) ++{ ++ ++ ASSERT(prBssInfo); ++ ++ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ ++ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); ++ ++ /* Use Association ID == 0 for BMCAST indication */ ++ if (u2AssocId == 0) { ++ ++ prP2pSpecificBssInfo->ucBitmapCtrl |= (UINT_8) BIT(0); ++ } else { ++ PUINT_8 pucPartialVirtualBitmap; ++ UINT_8 ucBitmapToSet; ++ ++ /* (u2AssocId / 8) */ ++ pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)]; ++ ucBitmapToSet = (UINT_8) BIT((u2AssocId % 8)); ++ ++ if (*pucPartialVirtualBitmap & ucBitmapToSet) { ++ /* The virtual bitmap has been set */ ++ return; ++ } ++ ++ *pucPartialVirtualBitmap |= ucBitmapToSet; ++ ++ /* Update u2SmallestAID and u2LargestAID */ ++ if ((u2AssocId < prP2pSpecificBssInfo->u2SmallestAID) || ++ (prP2pSpecificBssInfo->u2SmallestAID == 0)) { ++ prP2pSpecificBssInfo->u2SmallestAID = u2AssocId; ++ } ++ ++ if ((u2AssocId > prP2pSpecificBssInfo->u2LargestAID) || ++ (prP2pSpecificBssInfo->u2LargestAID == 0)) { ++ prP2pSpecificBssInfo->u2LargestAID = u2AssocId; ++ } ++ } ++ } ++ ++} /* end of bssSetTIMBitmap() */ ++#endif ++ ++#endif /* CFG_SUPPORT_AAA */ ++ ++VOID bssCreateStaRecFromAuth(IN P_ADAPTER_T prAdapter) ++{ ++ ++} ++ ++VOID bssUpdateStaRecFromAssocReq(IN P_ADAPTER_T prAdapter) ++{ ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c +new file mode 100644 +index 000000000000..39af02df2af2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c +@@ -0,0 +1,738 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm.c#2 ++*/ ++ ++/*! \file "cnm.c" ++ \brief Module of Concurrent Network Management ++ ++ Module of Concurrent Network Management ++*/ ++ ++/* ++** Log: cnm.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Fix possible wrong message when P2P is unregistered ++ * ++ * 11 14 2011 yuche.tsai ++ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. ++ * Fix large network type index assert in FW issue. ++ * ++ * 11 10 2011 cm.chang ++ * NULL ++ * Modify debug message for XLOG ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 11 01 2011 cm.chang ++ * [WCXRP00001077] [All Wi-Fi][Driver] Fix wrong preferred channel for AP and BOW ++ * Only check AIS channel for P2P and BOW ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Extension channel of some 5G AP will not follow regulation requirement ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 09 01 2011 cm.chang ++ * [WCXRP00000937] [MT6620 Wi-Fi][Driver][FW] cnm.c line #848 assert when doing monkey test ++ * Print message only in Linux platform for monkey testing ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Limit AIS to fixed channel same with BOW ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Check if P2P network index is Tethering AP ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel ++ * ++ * 02 17 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * When P2P registried, invoke BOW deactivate function ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Provide function to decide if BSS can be activated or not ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 10 13 2010 cm.chang ++ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. ++ * Add exception handle when cmd buffer is not available ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Fix wrong message ID for channel grant to requester ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Set 20/40M bandwidth of AP HT OP before association process ++ * ++ * 05 31 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling ++ * ++ * 05 21 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support TCP/UDP/IP Checksum offload feature ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add a new function to send abort message ++ * ++ * 04 27 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * BMC mac address shall be ignored in basic config command ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support change of MAC address by host command ++ * ++ * 04 16 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the wpa-none for ibss beacon. ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix bug for OBSS scan ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * use the Rx0 dor event indicate. ++ * ++ * 02 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support partial part about cmd basic configuration ++ * ++ * Dec 10 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove conditional compiling FPGA_V5 ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function cnmFsmEventInit() ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in CNM_INFO_T. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmInit(P_ADAPTER_T prAdapter) ++{ ++ ++} /* end of cnmInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in CNM_INFO_T. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmUninit(P_ADAPTER_T prAdapter) ++{ ++ ++} /* end of cnmUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Before handle the message from other module, it need to obtain ++* the Channel privilege from Channel Manager ++* ++* @param[in] prMsgHdr The message need to be handled. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_CH_REQ_T prMsgChReq; ++ P_CMD_CH_PRIVILEGE_T prCmdBody; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prMsgChReq = (P_MSG_CH_REQ_T) prMsgHdr; ++ ++ prCmdBody = (P_CMD_CH_PRIVILEGE_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); ++ ASSERT(prCmdBody); ++ ++ /* To do: exception handle */ ++ if (!prCmdBody) { ++ DBGLOG(CNM, ERROR, "ChReq: fail to get buf (net=%d, token=%d)\n", ++ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ DBGLOG(CNM, INFO, "ChReq net=%d token=%d b=%d c=%d s=%d\n", ++ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID, ++ prMsgChReq->eRfBand, prMsgChReq->ucPrimaryChannel, prMsgChReq->eRfSco); ++ ++ prCmdBody->ucNetTypeIndex = prMsgChReq->ucNetTypeIndex; ++ prCmdBody->ucTokenID = prMsgChReq->ucTokenID; ++ prCmdBody->ucAction = CMD_CH_ACTION_REQ; /* Request */ ++ prCmdBody->ucPrimaryChannel = prMsgChReq->ucPrimaryChannel; ++ prCmdBody->ucRfSco = (UINT_8) prMsgChReq->eRfSco; ++ prCmdBody->ucRfBand = (UINT_8) prMsgChReq->eRfBand; ++ prCmdBody->ucReqType = (UINT_8) prMsgChReq->eReqType; ++ prCmdBody->ucReserved = 0; ++ prCmdBody->u4MaxInterval = prMsgChReq->u4MaxInterval; ++ COPY_MAC_ADDR(prCmdBody->aucBSSID, prMsgChReq->aucBSSID); ++ ++ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ /* For monkey testing 20110901 */ ++ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) ++ DBGLOG(CNM, ERROR, "CNM: ChReq with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_CH_PRIVILEGE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdBody, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdBody); ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* end of cnmChMngrRequestPrivilege() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Before deliver the message to other module, it need to release ++* the Channel privilege to Channel Manager. ++* ++* @param[in] prMsgHdr The message need to be delivered ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_CH_ABORT_T prMsgChAbort; ++ P_CMD_CH_PRIVILEGE_T prCmdBody; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prMsgChAbort = (P_MSG_CH_ABORT_T) prMsgHdr; ++ ++ prCmdBody = (P_CMD_CH_PRIVILEGE_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); ++ ASSERT(prCmdBody); ++ ++ /* To do: exception handle */ ++ if (!prCmdBody) { ++ DBGLOG(CNM, ERROR, "ChAbort: fail to get buf (net=%d, token=%d)\n", ++ prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ DBGLOG(CNM, INFO, "ChAbort net=%d token=%d\n", prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); ++ ++ prCmdBody->ucNetTypeIndex = prMsgChAbort->ucNetTypeIndex; ++ prCmdBody->ucTokenID = prMsgChAbort->ucTokenID; ++ prCmdBody->ucAction = CMD_CH_ACTION_ABORT; /* Abort */ ++ ++ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ /* For monkey testing 20110901 */ ++ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) ++ DBGLOG(CNM, ERROR, "CNM: ChAbort with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_CH_PRIVILEGE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdBody, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdBody); ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* end of cnmChMngrAbortPrivilege() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_CH_PRIVILEGE_T prEventBody; ++ P_MSG_CH_GRANT_T prChResp; ++ ++ ASSERT(prAdapter); ++ ASSERT(prEvent); ++ ++ prEventBody = (P_EVENT_CH_PRIVILEGE_T) (prEvent->aucBuffer); ++ prChResp = (P_MSG_CH_GRANT_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_GRANT_T)); ++ ASSERT(prChResp); ++ ++ /* To do: exception handle */ ++ if (!prChResp) { ++ DBGLOG(CNM, ERROR, "ChGrant: fail to get buf (net=%d, token=%d)\n", ++ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID); ++ ++ return; ++ } ++ ++ DBGLOG(CNM, INFO, "ChGrant net=%d token=%d ch=%d sco=%d\n", ++ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID, ++ prEventBody->ucPrimaryChannel, prEventBody->ucRfSco); ++ ++ ASSERT(prEventBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ASSERT(prEventBody->ucStatus == EVENT_CH_STATUS_GRANT); ++ ++ /* Decide message ID based on network and response status */ ++ if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) ++ prChResp->rMsgHdr.eMsgId = MID_CNM_AIS_CH_GRANT; ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (prEventBody->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) ++ prChResp->rMsgHdr.eMsgId = MID_CNM_P2P_CH_GRANT; ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++ prChResp->rMsgHdr.eMsgId = MID_CNM_BOW_CH_GRANT; ++#endif ++ else { ++ cnmMemFree(prAdapter, prChResp); ++ return; ++ } ++ ++ prChResp->ucNetTypeIndex = prEventBody->ucNetTypeIndex; ++ prChResp->ucTokenID = prEventBody->ucTokenID; ++ prChResp->ucPrimaryChannel = prEventBody->ucPrimaryChannel; ++ prChResp->eRfSco = (ENUM_CHNL_EXT_T) prEventBody->ucRfSco; ++ prChResp->eRfBand = (ENUM_BAND_T) prEventBody->ucRfBand; ++ prChResp->eReqType = (ENUM_CH_REQ_TYPE_T) prEventBody->ucReqType; ++ prChResp->u4GrantInterval = prEventBody->u4GrantInterval; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prChResp, MSG_SEND_METHOD_BUF); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is invoked for P2P or BOW networks ++* ++* @param (none) ++* ++* @return TRUE: suggest to adopt the returned preferred channel ++* FALSE: No suggestion. Caller should adopt its preference ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBand); ++ ASSERT(pucPrimaryChannel); ++ ASSERT(prBssSCO); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ if (RLM_NET_PARAM_VALID(prBssInfo)) { ++ *prBand = prBssInfo->eBand; ++ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ *prBssSCO = prBssInfo->eBssSCO; ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: available channel is limited to return value ++* FALSE: no limited ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) ++{ ++#if CFG_ENABLE_WIFI_DIRECT || (CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL) ++ P_BSS_INFO_T prBssInfo; ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { ++ ++ ASSERT(prAdapter->fgIsP2PRegistered); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ *prBand = prBssInfo->eBand; ++ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ ++ return TRUE; ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; ++ ++ *prBand = prBssInfo->eBand; ++ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ ++ return TRUE; ++ } ++#endif ++ ++ return FALSE; ++} ++ ++#if CFG_P2P_LEGACY_COEX_REVISE ++BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) ++{ ++ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; ++ P_BSS_INFO_T prP2PBssInfo = &prWifiVar->arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && ++ (prP2PBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || ++ (prP2PBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && prP2PBssInfo->eIntendOPMode == OP_MODE_NUM))) { ++ *prBand = prP2PBssInfo->eBand; ++ *pucPrimaryChannel = prP2PBssInfo->ucPrimaryChannel; ++#if CFG_SUPPORT_MCC ++ if (nicFreq2ChannelNum(prWifiVar->rConnSettings.u4FreqInKHz * 1000) != *pucPrimaryChannel) { ++ DBGLOG(CNM, INFO, "p2p is running on Channel %d, but supplicant try to run as MCC\n", ++ *pucPrimaryChannel); ++ return FALSE; ++ } ++#endif ++ DBGLOG(CNM, INFO, "p2p is running on Channel %d, supplicant try to run as SCC\n", ++ *pucPrimaryChannel); ++ return TRUE; ++ } ++#endif ++ return FALSE; ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter) ++{ ++#if CFG_ENABLE_BT_OVER_WIFI ++ P_BSS_INFO_T prAisBssInfo, prBowBssInfo; ++ ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prBowBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; ++ ++ if (RLM_NET_PARAM_VALID(prAisBssInfo) && RLM_NET_PARAM_VALID(prBowBssInfo)) { ++ if (prAisBssInfo->eBand != prBowBssInfo->eBand || ++ prAisBssInfo->ucPrimaryChannel != prBowBssInfo->ucPrimaryChannel) { ++ ++ /* Notify BOW to do deactivation */ ++ bowNotifyAllLinkDisconnected(prAdapter); ++ } ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter) ++{ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) ++ return FALSE; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) ++ return FALSE; ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) ++ return FALSE; ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { ++ /* Notify BOW to do deactivation */ ++ bowNotifyAllLinkDisconnected(prAdapter); ++ } ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) ++ return FALSE; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) ++ return FALSE; ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 i; ++ P_BSS_DESC_T prBssDesc = NULL; ++ ++ /* Note: To support real-time decision instead of current activated-time, ++ * the STA roaming case shall be considered about synchronization ++ * problem. Another variable fgAssoc40mBwAllowed is added to ++ * represent HT capability when association ++ */ ++ for (i = 0; i < NETWORK_TYPE_INDEX_NUM; i++) { ++ if (i != (UINT_8) eNetTypeIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[i]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo) && (prBssInfo->fg40mBwAllowed || prBssInfo->fgAssoc40mBwAllowed)) ++ return FALSE; ++ } ++ } ++ ++ if (eNetTypeIdx == NETWORK_TYPE_AIS_INDEX) ++ prBssDesc = prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; ++ else if ((eNetTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->rWifiVar.prP2pFsmInfo)) ++ prBssDesc = prAdapter->rWifiVar.prP2pFsmInfo->prTargetBss; ++ if (prBssDesc) { ++#if (CFG_FORCE_USE_20BW == 1) ++ if (prBssDesc->eBand == BAND_2G4) ++ return FALSE; ++#endif ++ if (prBssDesc->eSco == CHNL_EXT_SCN) ++ return FALSE; ++ } ++ ++ return TRUE; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c +new file mode 100644 +index 000000000000..05bd0ff35f7a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c +@@ -0,0 +1,1236 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#2 ++*/ ++ ++/*! \file "cnm_mem.c" ++ \brief This file contain the management function of packet buffers and ++ generic memory alloc/free functioin for mailbox message. ++ ++ A data packet has a fixed size of buffer, but a management ++ packet can be equipped with a variable size of buffer. ++*/ ++ ++/* ++** Log: cnm_mem.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 14 2012 wh.su ++ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting ++ * Add code from 2.2 ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * initialize fgNeedResp. ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * avoid deactivating staRec when changing state from 3 to 3. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 29 2010 cm.chang ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * Sync RCPI of STA_REC to FW as reference of initial TX rate ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update SLT Function for QoS Support and not be affected by fixed rate function. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete ++ * and might leads to BSOD when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 10 13 2010 cm.chang ++ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. ++ * Add exception handle when cmd buffer is not available ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * add HT (802.11n) fixed rate support. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD ++ * when entering RF test with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 07 07 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support state of STA record change from 1 to 1 ++ * ++ * 07 05 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Fix correct structure size in cnmStaSendDeactivateCmd() ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * spin lock target revised ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change inner loop index from i to k. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 05 31 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support checking of duplicated buffer free ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the ad-hoc wpa-none send non-encrypted frame issue. ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Modified some MQM-related data structures (SN counter, TX/RX BA table) ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Added new TX/RX BA tables in STA_REC ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Notify MQM, TXM, and RXM upon disconnection . ++ * ++ * 04 26 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Call mqm, txm, rxm functions upon disconnection ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * * * * * * * * * and will send Null frame to diagnose connection ++ * ++ * 04 09 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * [BORA00000644] WiFi phase 4 integration ++ * * Added per-TID SN cache in STA_REC ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Different invoking order for WTBL entry of associated AP ++ * ++ * 03 29 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * move the wlan table alloc / free to change state function. ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support power control ++ * ++ * 03 03 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Initialize StaRec->arStaWaitQueue ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add debug message when no available pkt buffer ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k] ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsWmmSupported in STA_RECORD_T. ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsUapsdSupported in STA_RECORD_T ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * add support of Driver STA_RECORD_T activation ++ * ++ * 02 13 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added arTspecTable in STA_REC for TSPEC management ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable mgmt buffer debug by default ++ * ++ * 02 12 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added BUFFER_SOURCE_BCN ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h ++ * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem ++ * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer ++ * ++ * 12 25 2009 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) ++ * * * * * * * MQM: BA handling ++ * * * * * * * TXM: Macros updates ++ * * * * * * * RXM: Macros/Duplicate Removal updates ++ * ++ * 12 24 2009 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * 12 21 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support several data buffer banks. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * .For new FPGA memory size ++ * ++ * Dec 9 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Removed DBGPRINT ++ * ++ * Dec 9 2009 mtk02752 ++ * [BORA00000368] Integrate HIF part into BORA ++ * add cnmDataPktFree() for emulation loopback purpose ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix warning of null pointer ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T ++ * ++ * Nov 23 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Assign ucBufferSource in function cnmMgtPktAlloc() ++ * ++ * Nov 23 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added packet redispatch function calls ++ * ++ * Nov 13 2009 mtk01084 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * enable packet re-usable in current emulation driver ++ * ++ * Nov 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * 1. Add new function cnmGetStaRecByIndex() ++ * 2. Rename STA_REC_T to STA_RECORD_T ++ * ++ * Nov 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Call cnmDataPktDispatch() in cnmPktFree() ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove definition of pragma section code ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * Oct 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo ++ * ++ * Oct 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 8 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf); ++ ++static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp); ++ ++static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T cnmMgtPktAlloc(P_ADAPTER_T prAdapter, UINT_32 u4Length) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_QUE_T prQueList; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; ++ ++ /* Get a free MSDU_INFO_T */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ if (prMsduInfo) { ++ prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ ++ if (prMsduInfo->prPacket == NULL) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ prMsduInfo = NULL; ++ } ++ if (prMsduInfo) { ++ prMsduInfo->eCmdType = COMMAND_TYPE_NUM; ++ prMsduInfo->ucCID = 0xff; ++ prMsduInfo->u4InqueTime = 0; ++ prMsduInfo->ucPacketType = TX_PACKET_NUM; ++ } ++ } else { ++ P_QUE_T prTxingQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_TX_TCQ_STATUS_T pTc = (P_TX_TCQ_STATUS_T) NULL; ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ pTc = &(prAdapter->rTxCtrl.rTc); ++ ++ DBGLOG(MEM, LOUD, "++dump TxPendingMsdu=%u, Tc0=%d Tc1=%d Tc2=%d Tc3=%d, Tc4=%d Tc5=%d\n", ++ prTxingQue->u4NumElem, pTc->aucFreeBufferCount[TC0_INDEX], ++ pTc->aucFreeBufferCount[TC1_INDEX], pTc->aucFreeBufferCount[TC2_INDEX], ++ pTc->aucFreeBufferCount[TC3_INDEX], pTc->aucFreeBufferCount[TC4_INDEX], ++ pTc->aucFreeBufferCount[TC5_INDEX]); ++ ++ prQueueEntry = QUEUE_GET_HEAD(prTxingQue); ++ ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ DBGLOG(MEM, LOUD, ++ "msdu type=%u, ucid=%u, type=%d, time=%u, seq=%u, sta=%u\n", ++ prMsduInfo->ucPacketType, ++ prMsduInfo->ucCID, ++ prMsduInfo->eCmdType, ++ prMsduInfo->u4InqueTime, prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex); ++ prQueueEntry = QUEUE_GET_NEXT_ENTRY(prQueueEntry); ++ } ++ DBGLOG(MEM, LOUD, "--end dump\n"); ++ } ++ ++#if DBG ++ if (prMsduInfo == NULL) { ++ DBGLOG(MEM, WARN, "MgtDesc#=%u\n", prQueList->u4NumElem); ++ ++#if CFG_DBG_MGT_BUF ++ DBGLOG(MEM, WARN, "rMgtBufInfo: alloc#=%u, free#=%u, null#=%u\n", ++ prAdapter->rMgtBufInfo.u4AllocCount, ++ prAdapter->rMgtBufInfo.u4FreeCount, prAdapter->rMgtBufInfo.u4AllocNullCount); ++#endif ++ ++ DBGLOG(MEM, WARN, "\n"); ++ } ++#endif ++ ++ return prMsduInfo; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmMgtPktFree(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_QUE_T prQueList; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; ++ ++ ASSERT(prMsduInfo->prPacket); ++ if (prMsduInfo->prPacket) { ++ cnmMemFree(prAdapter, prMsduInfo->prPacket); ++ prMsduInfo->prPacket = NULL; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ prMsduInfo->fgIsBasicRate = FALSE; ++ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry) ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to initial the MGMT/MSG memory pool. ++* ++* \param (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmMemInit(P_ADAPTER_T prAdapter) ++{ ++ P_BUF_INFO_T prBufInfo; ++ ++ /* Initialize Management buffer pool */ ++ prBufInfo = &prAdapter->rMgtBufInfo; ++ kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo)); ++ prBufInfo->pucBuf = prAdapter->pucMgtBufCached; ++ ++ /* Setup available memory blocks. 1 indicates FREE */ ++ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); ++ ++ /* Initialize Message buffer pool */ ++ prBufInfo = &prAdapter->rMsgBufInfo; ++ kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo)); ++ prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0]; ++ ++ /* Setup available memory blocks. 1 indicates FREE */ ++ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); ++ ++ return; ++ ++} /* end of cnmMemInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Allocate MGMT/MSG memory pool. ++* ++* \param[in] eRamType Target RAM type. ++* TCM blk_sz= 16bytes, BUF blk_sz= 256bytes ++* \param[in] u4Length Length of the buffer to allocate. ++* ++* \retval !NULL Pointer to the start address of allocated memory. ++* \retval NULL Fail to allocat memory ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 u4MemAllocCnt = 0, u4MemFreeCnt = 0; ++PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length) ++{ ++ P_BUF_INFO_T prBufInfo; ++ BUF_BITMAP rRequiredBitmap; ++ UINT_32 u4BlockNum; ++ UINT_32 i, u4BlkSzInPower; ++ PVOID pvMemory; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(u4Length); ++ ++ u4MemAllocCnt++; ++ ++ if (eRamType == RAM_TYPE_MSG && u4Length <= 256) { ++ prBufInfo = &prAdapter->rMsgBufInfo; ++ u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ u4Length += (MSG_BUF_BLOCK_SIZE - 1); ++ u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); ++ } else { ++ eRamType = RAM_TYPE_BUF; ++ ++ prBufInfo = &prAdapter->rMgtBufInfo; ++ u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ u4Length += (MGT_BUF_BLOCK_SIZE - 1); ++ u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); ++ } ++ ++#if CFG_DBG_MGT_BUF ++ prBufInfo->u4AllocCount++; ++#endif ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) { ++ ++ /* Convert number of block into bit cluster */ ++ rRequiredBitmap = BITS(0, u4BlockNum - 1); ++ ++ for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) { ++ ++ /* Have available memory blocks */ ++ if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap) ++ == rRequiredBitmap) { ++ ++ /* Clear corresponding bits of allocated memory blocks */ ++ prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap; ++ ++ /* Store how many blocks be allocated */ ++ prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, ++ eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ /* Return the start address of allocated memory */ ++ return (PVOID) (prBufInfo->pucBuf + (i << u4BlkSzInPower)); ++ ++ } ++ ++ rRequiredBitmap <<= 1; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ /* cannot move the allocation between spin_lock_irqsave and spin_unlock_irqrestore */ ++#ifdef LINUX ++ pvMemory = (PVOID) kalMemAlloc(u4Length, VIR_MEM_TYPE); ++ if (pvMemory) ++ kalMemZero(pvMemory, u4Length); ++#else ++ pvMemory = (PVOID) NULL; ++#endif ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++#if CFG_DBG_MGT_BUF ++ prBufInfo->u4AllocNullCount++; ++ ++ if (pvMemory) ++ prAdapter->u4MemAllocDynamicCount++; ++#endif ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ return pvMemory; ++ ++} /* end of cnmMemAlloc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Release memory to MGT/MSG memory pool. ++* ++* \param pucMemory Start address of previous allocated memory ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory) ++{ ++ P_BUF_INFO_T prBufInfo; ++ UINT_32 u4BlockIndex; ++ BUF_BITMAP rAllocatedBlocksBitmap; ++ ENUM_RAM_TYPE_T eRamType; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvMemory); ++ if (!pvMemory) ++ return; ++ ++ u4MemFreeCnt++; ++ ++ /* Judge it belongs to which RAM type */ ++ if (((ULONG) pvMemory >= (ULONG)&prAdapter->aucMsgBuf[0]) && ++ ((ULONG) pvMemory <= (ULONG)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE - 1])) { ++ ++ prBufInfo = &prAdapter->rMsgBufInfo; ++ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) ++ >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); ++ eRamType = RAM_TYPE_MSG; ++ } else if (((ULONG) pvMemory >= (ULONG) prAdapter->pucMgtBufCached) && ++ ((ULONG) pvMemory <= ((ULONG) prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE - 1))) { ++ prBufInfo = &prAdapter->rMgtBufInfo; ++ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) ++ >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); ++ eRamType = RAM_TYPE_BUF; ++ } else { ++#ifdef LINUX ++ /* For Linux, it is supported because size is not needed */ ++ kalMemFree(pvMemory, VIR_MEM_TYPE, 0); ++#else ++ /* For Windows, it is not supported because of no size argument */ ++ ASSERT(0); ++#endif ++ ++#if CFG_DBG_MGT_BUF ++ prAdapter->u4MemFreeDynamicCount++; ++#endif ++ return; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++#if CFG_DBG_MGT_BUF ++ prBufInfo->u4FreeCount++; ++#endif ++ ++ /* Convert number of block into bit cluster */ ++ ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0); ++ ++ rAllocatedBlocksBitmap = BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1); ++ rAllocatedBlocksBitmap <<= u4BlockIndex; ++ ++ /* Clear saved block count for this memory segment */ ++ prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0; ++ ++ /* Set corresponding bit of released memory block */ ++ prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ return; ++ ++} /* end of cnmMemFree() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecInit(P_ADAPTER_T prAdapter) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ prStaRec->ucIndex = (UINT_8) i; ++ prStaRec->fgIsInUse = FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse) ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T cnmStaRecAlloc(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i, k; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (!prStaRec->fgIsInUse) { ++ /*---- Initialize STA_REC_T here ----*/ ++ kalMemZero(prStaRec, sizeof(STA_RECORD_T)); ++ prStaRec->ucIndex = (UINT_8) i; ++ prStaRec->ucNetTypeIndex = ucNetTypeIndex; ++ prStaRec->fgIsInUse = TRUE; ++ ++ if (prStaRec->pucAssocReqIe) { ++ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); ++ prStaRec->pucAssocReqIe = NULL; ++ prStaRec->u2AssocReqIeLen = 0; ++ } ++ ++ /* Initialize the SN caches for duplicate detection */ ++ for (k = 0; k < TID_NUM + 1; k++) ++ prStaRec->au2CachedSeqCtrl[k] = 0xFFFF; ++ ++ /* Initialize SW TX queues in STA_REC */ ++ for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) ++ LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]); ++ ++ /* Default enable TX/RX AMPDU */ ++ prStaRec->fgTxAmpduEn = TRUE; ++ prStaRec->fgRxAmpduEn = TRUE; ++ ++#if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE ++ prStaRec->u4TotalTxPktsNumber = 0; ++ prStaRec->u4TotalTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsTime = 0; ++#endif ++ ++ for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) ++ QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]); ++ ++ break; ++ } ++ } ++ ++ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecFree(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgSyncToChip) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ /* To do: free related resources, e.g. timers, buffers, etc */ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ prStaRec->fgTransmitKeyExist = FALSE; ++ prStaRec->fgSetPwrMgtBit = FALSE; ++ ++ if (prStaRec->pucAssocReqIe) { ++ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); ++ prStaRec->pucAssocReqIe = NULL; ++ prStaRec->u2AssocReqIeLen = 0; ++ } ++ ++ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); ++ ++ if (fgSyncToChip) ++ cnmStaSendRemoveCmd(prAdapter, prStaRec); ++ ++ prStaRec->fgIsInUse = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse && prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) ++ cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip); ++ } /* end of for loop */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T cnmGetStaRecByIndex(P_ADAPTER_T prAdapter, UINT_8 ucIndex) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ++ prStaRec = (ucIndex < CFG_STA_REC_NUM) ? &prAdapter->arStaRec[ucIndex] : NULL; ++ ++ if (prStaRec && prStaRec->fgIsInUse == FALSE) ++ prStaRec = NULL; ++ ++ return prStaRec; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Get STA_RECORD_T by Peer MAC Address(Usually TA). ++* ++* @param[in] pucPeerMacAddr Given Peer MAC Address. ++* ++* @retval Pointer to STA_RECORD_T, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T cnmGetStaRecByAddress(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex, PUINT_8 pucPeerMacAddr) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucPeerMacAddr); ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse && ++ prStaRec->ucNetTypeIndex == ucNetTypeIndex && ++ EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) { ++ break; ++ } ++ } ++ ++ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Reset the Status and Reason Code Field to 0 of all Station Records for ++* the specified Network Type ++* ++* @param[in] eNetType Specify Network Type ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecResetStatus(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE); ++ ++#if 0 ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse) { ++ if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) && IS_STA_IN_AIS(prStaRec->eStaType)) { ++ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; ++ prStaRec->ucJoinFailureCount = 0; ++ prStaRec->fgTransmitKeyExist = FALSE; ++ ++ prStaRec->fgSetPwrMgtBit = FALSE; ++ } ++ ++ /* TODO(Kevin): For P2P and BOW */ ++ } ++ } ++ ++ return; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will change the ucStaState of STA_RECORD_T and also do ++* event indication to HOST to sync the STA_RECORD_T in driver. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u4NewState New STATE to change. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecChangeState(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, UINT_8 ucNewState) ++{ ++ BOOLEAN fgNeedResp; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->fgIsInUse); ++ ++ /* Do nothing when following state transitions happen, ++ * other 6 conditions should be sync to FW, including 1-->1, 3-->3 ++ */ ++ if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) || ++ (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) { ++ prStaRec->ucStaState = ucNewState; ++ return; ++ } ++ ++ fgNeedResp = FALSE; ++ if (ucNewState == STA_STATE_3) { ++ secFsmEventStart(prAdapter, prStaRec); ++ if (ucNewState != prStaRec->ucStaState) ++ fgNeedResp = TRUE; ++ } else { ++ if (ucNewState != prStaRec->ucStaState && prStaRec->ucStaState == STA_STATE_3) ++ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); ++ fgNeedResp = FALSE; ++ } ++ prStaRec->ucStaState = ucNewState; ++ ++ cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* To do: Confirm if it is invoked here or other location, but it should ++ * be invoked after state sync of STA_REC ++ * Update system operation parameters for AP mode ++ */ ++ if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) { ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); ++ } ++#endif ++} ++ ++P_STA_RECORD_T ++cnmStaTheTypeGet(P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx) ++{ ++ P_STA_RECORD_T prStaRec = NULL; ++ UINT_16 i; ++ ++ for (i = *pu4StartIdx; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse && ++ prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex && prStaRec->eStaType == eStaType) { ++ i++; ++ break; ++ } ++ ++ prStaRec = NULL; /* reset */ ++ } /* end of for loop */ ++ ++ *pu4StartIdx = i; ++ return prStaRec; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf) ++{ ++ P_EVENT_ACTIVATE_STA_REC_T prEventContent; ++ P_STA_RECORD_T prStaRec; ++ ++ prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx); ++ ++ if (prStaRec && prStaRec->ucStaState == STA_STATE_3 && ++ !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0], MAC_ADDR_LEN)) { ++ ++ qmActivateStaRec(prAdapter, prStaRec); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp) ++{ ++ P_CMD_UPDATE_STA_RECORD_T prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->fgIsInUse); ++ ++ /* To do: come out a mechanism to limit one STA_REC sync once for AP mode ++ * to avoid buffer empty case when many STAs are associated ++ * simultaneously. ++ */ ++ ++ /* To do: how to avoid 2 times of allocated memory. Use Stack? ++ * One is here, the other is in wlanSendQueryCmd() ++ */ ++ prCmdContent = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T)); ++ ASSERT(prCmdContent); ++ ++ /* To do: exception handle */ ++ if (!prCmdContent) ++ return; ++ ++ prCmdContent->ucIndex = prStaRec->ucIndex; ++ prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType; ++ kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); ++ prCmdContent->u2AssocId = prStaRec->u2AssocId; ++ prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval; ++ prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex; ++ ++ prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet; ++ prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ prCmdContent->ucMcsSet = prStaRec->ucMcsSet; ++ prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32; ++ prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo; ++ prCmdContent->ucNeedResp = (UINT_8) fgNeedResp; ++ ++#if !CFG_SLT_SUPPORT ++ if (prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) { ++ /* override rate configuration */ ++ nicUpdateRateParams(prAdapter, ++ prAdapter->rWifiVar.eRateSetting, ++ &(prCmdContent->ucDesiredPhyTypeSet), ++ &(prCmdContent->u2DesiredNonHTRateSet), ++ &(prCmdContent->u2BSSBasicRateSet), ++ &(prCmdContent->ucMcsSet), ++ &(prCmdContent->ucSupMcs32), &(prCmdContent->u2HtCapInfo)); ++ } ++#endif ++ ++ prCmdContent->ucIsQoS = prStaRec->fgIsQoS; ++ prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported; ++ prCmdContent->ucStaState = prStaRec->ucStaState; ++ ++ prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam; ++ prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap; ++ prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap; ++ prCmdContent->ucAselCap = prStaRec->ucAselCap; ++ prCmdContent->ucRCPI = prStaRec->ucRCPI; ++ ++ prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4); ++ prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp; ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_UPDATE_STA_RECORD, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ fgNeedResp, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ fgNeedResp ? cnmStaRecHandleEventPkt : NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdContent); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) ++{ ++ CMD_REMOVE_STA_RECORD_T rCmdContent; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ rCmdContent.ucIndex = prStaRec->ucIndex; ++ kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_REMOVE_STA_RECORD, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) &rCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c +new file mode 100644 +index 000000000000..8cc9ef9078fe +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c +@@ -0,0 +1,482 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1 ++*/ ++ ++/*! \file "cnm_timer.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: cnm_timer.c ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation ++ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms ++ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support sleep notification to host ++ * ++ * 05 19 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add some checking assertions ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Return timer token back to COS when entering wait off state ++ * ++ * 01 11 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove compiling warning ++ * ++ * 01 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb ++ * ++ * 01 06 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix system time is 32KHz instead of 1ms ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Place rRootTimer.rNextExpiredSysTime = rExpiredSysTime; before set timer ++ * ++ * Oct 30 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * In cnmTimerInitialize(), just stop timer if it was already created. ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Move the external reference for Lint to precomp.h ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the time to do the time out check. ++* ++* \param[in] rTimeout Time out interval from current time. ++* ++* \retval TRUE Success. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN cnmTimerSetTimer(IN P_ADAPTER_T prAdapter, IN OS_SYSTIME rTimeout) ++{ ++ P_ROOT_TIMER prRootTimer; ++ BOOLEAN fgNeedWakeLock; ++ ++ ASSERT(prAdapter); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ kalSetTimer(prAdapter->prGlueInfo, rTimeout); ++ ++ if (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME)) { ++ fgNeedWakeLock = TRUE; ++ ++ if (!prRootTimer->fgWakeLocked) { ++ KAL_WAKE_LOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = TRUE; ++ } ++ } else { ++ fgNeedWakeLock = FALSE; ++ } ++ ++ return fgNeedWakeLock; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to initialize a root timer. ++* ++* \param[in] prAdapter ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROOT_TIMER prRootTimer; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ /* Note: glue layer have configured timer */ ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ LINK_INITIALIZE(&prRootTimer->rLinkHead); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ KAL_WAKE_LOCK_INIT(prAdapter, &prRootTimer->rWakeLock, "WLAN Timer"); ++ prRootTimer->fgWakeLocked = FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to destroy a root timer. ++* When WIFI is off, the token shall be returned back to system. ++* ++* \param[in] ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROOT_TIMER prRootTimer; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ if (prRootTimer->fgWakeLocked) { ++ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = FALSE; ++ } ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prRootTimer->rWakeLock); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ LINK_INITIALIZE(&prRootTimer->rLinkHead); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ /* Note: glue layer will be responsible for timer destruction */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to initialize a timer. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* \param[in] pfnFunc Pointer to the call back function. ++* \param[in] u4Data Parameter for call back function. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData) ++{ ++ ASSERT(prAdapter); ++ ++ ASSERT(prTimer); ++ ++#if DBG ++ /* Note: NULL function pointer is permitted for HEM POWER */ ++ if (pfFunc == NULL) ++ DBGLOG(CNM, WARN, "Init timer with NULL callback function!\n"); ++#endif ++ ++#if DBG ++ ASSERT(prAdapter->rRootTimer.rLinkHead.prNext); ++ { ++ P_LINK_T prTimerList; ++ P_LINK_ENTRY_T prLinkEntry; ++ P_TIMER_T prPendingTimer; ++ ++ prTimerList = &(prAdapter->rRootTimer.rLinkHead); ++ ++ LINK_FOR_EACH(prLinkEntry, prTimerList) { ++ prPendingTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); ++ ASSERT(prPendingTimer); ++ ASSERT(prPendingTimer != prTimer); ++ } ++ } ++#endif ++ ++ LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry); ++ ++ prTimer->pfMgmtTimeOutFunc = pfFunc; ++ prTimer->ulData = ulData; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to stop a timer. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmTimerStopTimer_impl(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN BOOLEAN fgAcquireSpinlock) ++{ ++ P_ROOT_TIMER prRootTimer; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prTimer); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ if (fgAcquireSpinlock) ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ if (timerPendingTimer(prTimer)) { ++ LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead, &prTimer->rLinkEntry); ++ ++ /* Reduce dummy timeout for power saving, especially HIF activity. ++ * If two or more timers exist and being removed timer is smallest, ++ * this dummy timeout will still happen, but it is OK. ++ */ ++ if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) { ++ kalCancelTimer(prAdapter->prGlueInfo); ++ ++ if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) { ++ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = FALSE; ++ } ++ } ++ } ++ ++ if (fgAcquireSpinlock) ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to stop a timer. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prTimer); ++ ++ cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to start a timer with wake_lock. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* \param[in] u4TimeoutMs Timeout to issue the timer and call back function ++* (unit: ms). ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs) ++{ ++ P_ROOT_TIMER prRootTimer; ++ P_LINK_T prTimerList; ++ OS_SYSTIME rExpiredSysTime, rTimeoutSystime; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prTimer); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ prTimerList = &prRootTimer->rLinkHead; ++ ++ /* If timeout interval is larger than 1 minute, the mod value is set ++ * to the timeout value first, then per minutue. ++ */ ++ if (u4TimeoutMs > MSEC_PER_MIN) { ++ ASSERT(u4TimeoutMs <= ((UINT_32) 0xFFFF * MSEC_PER_MIN)); ++ ++ prTimer->u2Minutes = (UINT_16) (u4TimeoutMs / MSEC_PER_MIN); ++ u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN); ++ if (u4TimeoutMs == 0) { ++ u4TimeoutMs = MSEC_PER_MIN; ++ prTimer->u2Minutes--; ++ } ++ } else { ++ prTimer->u2Minutes = 0; ++ } ++ ++ /* The assertion check if MSEC_TO_SYSTIME() may be overflow. */ ++ ASSERT(u4TimeoutMs < (((UINT_32) 0x80000000 - MSEC_PER_SEC) / KAL_HZ)); ++ rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs); ++ rExpiredSysTime = kalGetTimeTick() + rTimeoutSystime; ++ ++ /* If no timer pending or the fast time interval is used. */ ++ if (LINK_IS_EMPTY(prTimerList) || TIME_BEFORE(rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { ++ ++ prRootTimer->rNextExpiredSysTime = rExpiredSysTime; ++ cnmTimerSetTimer(prAdapter, rTimeoutSystime); ++ } ++ ++ /* Add this timer to checking list */ ++ prTimer->rExpiredSysTime = rExpiredSysTime; ++ ++ if (!timerPendingTimer(prTimer)) ++ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to check the timer list. ++* ++* \param[in] ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROOT_TIMER prRootTimer; ++ P_LINK_T prTimerList; ++ P_LINK_ENTRY_T prLinkEntry; ++ P_TIMER_T prTimer; ++ OS_SYSTIME rCurSysTime; ++ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; ++ ULONG ulTimeoutData; ++ BOOLEAN fgNeedWakeLock; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ /* acquire spin lock */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ prTimerList = &prRootTimer->rLinkHead; ++ ++ rCurSysTime = kalGetTimeTick(); ++ ++ /* Set the permitted max timeout value for new one */ ++ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; ++ ++ LINK_FOR_EACH(prLinkEntry, prTimerList) { ++ prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); ++ ASSERT(prTimer); ++ ++ /* Check if this entry is timeout. */ ++ if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) { ++ cnmTimerStopTimer_impl(prAdapter, prTimer, FALSE); ++ ++ pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc; ++ ulTimeoutData = prTimer->ulData; ++ ++ if (prTimer->u2Minutes > 0) { ++ prTimer->u2Minutes--; ++ prTimer->rExpiredSysTime = rCurSysTime + MSEC_TO_SYSTIME(MSEC_PER_MIN); ++ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); ++ } else if (pfMgmtTimeOutFunc) { ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ (pfMgmtTimeOutFunc) (prAdapter, ulTimeoutData); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ } ++ ++ /* Search entire list again because of nest del and add timers ++ * and current MGMT_TIMER could be volatile after stopped ++ */ ++ prLinkEntry = (P_LINK_ENTRY_T) prTimerList; ++ ++ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; ++ } else if (TIME_BEFORE(prTimer->rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { ++ prRootTimer->rNextExpiredSysTime = prTimer->rExpiredSysTime; ++ } ++ } /* end of for loop */ ++ ++ /* Setup the prNext timeout event. It is possible the timer was already ++ * set in the above timeout callback function. ++ */ ++ fgNeedWakeLock = FALSE; ++ if (!LINK_IS_EMPTY(prTimerList)) { ++ ASSERT(TIME_AFTER(prRootTimer->rNextExpiredSysTime, rCurSysTime)); ++ ++ fgNeedWakeLock = cnmTimerSetTimer(prAdapter, (OS_SYSTIME) ++ ((INT_32) prRootTimer->rNextExpiredSysTime - (INT_32) rCurSysTime)); ++ } ++ ++ if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) { ++ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = FALSE; ++ } ++ ++ /* release spin lock */ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c +new file mode 100644 +index 000000000000..c7a23eb018b6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c +@@ -0,0 +1,816 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/hem_mbox.c#3 ++*/ ++ ++/*! \file "hem_mbox.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: hem_mbox.c ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device ++** have connected to AP previously,one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 05 03 2012 cp.wu ++ * [WCXRP00001231] [MT6620 Wi-Fi][MT5931][Driver] Correct SCAN_V2 related debugging facilities within hem_mbox.c ++ * correct for debug message string table by adding missed scan_v2 related definitions. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 17 2012 yuche.tsai ++ * NULL ++ * Update mgmt frame filter setting. ++ * Please also update FW 2.1 ++ * ++ * 01 13 2012 yuche.tsai ++ * NULL ++ * WiFi Hot Spot Tethering for ICS ALPHA testing version. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Add exception handle for NULL function pointer of mailbox message ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search ++ * for more than one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support ++ * as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Add invitation support. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 29 2011 cm.chang ++ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning ++ * As CR title ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation ++ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms ++ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update bowString and channel grant. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 12 08 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support concurrent networks. ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Remove unused message ID ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add P2P Connection Abort Event Message handler. ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 yarco.yang ++ * NULL ++ * Fixed Driver ASSERT at mboxInitMsgMap() ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. ++ * Update saa_fsm for BOW. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Add CFG_ENABLE_BT_OVER_WIFI. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add debug message for newly add P2P message. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some function entry for P2P FSM under provisioning phase.. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some events to P2P Module. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Add message box event for P2P device switch on & device discovery. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * remove unused mailbox message definitions. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * message table should not be commented out by compilation option without modifying header file ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Add wifi direct scan done callback. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * change handler of MID_MNY_CNM_CONNECTION_ABORT from NULL to mboxDummy. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable currently migrated message call-backs. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix file merge error ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_QOS_ACTION_FRAME ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Develop partial DPD code ++ * ++ * 02 11 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Updated arMsgMapTable for MID_RXM_MQM_QOS_ACTION_FRAME ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * Dec 9 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add hemRunEventScanDone() to arMsgMapTable[] ++ * ++ * Dec 4 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix mboxDummy() didn't free prMsgHdr ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add saaAisJoinComplete event handler ++ * ++ * Dec 2 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Fixed the handler function name in arMsgMapTable for MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * Dec 2 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added MID_RXM_MQM_BA_ACTION_FRAME to MsgMapTable ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MSG Handler (remove dummy and add for SAA) ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aisFsmRunEventAbort() event handler ++ * ++ * Nov 11 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo ++ * ++ * Nov 10 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add more MSG_HNDL_ENTRY_T to avoid ASSERT() in mboxInitMsgMap() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add SCN message and function entry to arMsgMapTable[] ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix sorting algorithm in mboxInitMsgMap() ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugMsg[] = { ++ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_REQ"), ++ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_ABORT"), ++ (PUINT_8) DISP_STRING("MID_CNM_AIS_CH_GRANT"), ++ (PUINT_8) DISP_STRING("MID_CNM_P2P_CH_GRANT"), ++ (PUINT_8) DISP_STRING("MID_CNM_BOW_CH_GRANT"), ++ ++ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_SCN_AIS_SCAN_DONE"), ++ (PUINT_8) DISP_STRING("MID_SCN_P2P_SCAN_DONE"), ++ (PUINT_8) DISP_STRING("MID_SCN_BOW_SCAN_DONE"), ++ (PUINT_8) DISP_STRING("MID_SCN_RLM_SCAN_DONE"), ++ ++ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_JOIN_REQ"), ++ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_START"), ++ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_SAA_AIS_JOIN_COMPLETE"), ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_START"), ++ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_SAA_BOW_JOIN_COMPLETE"), ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_START"), ++ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_SAA_P2P_JOIN_COMPLETE"), ++ ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_FUN_SWITCH"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_DEVICE_DISCOVERY"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_REQ"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_ABORT"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_BEACON_UPDATE"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_STOP_AP"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_REQ"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_ABORT"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_TX"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_GROUP_DISSOLVE"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_REGISTER"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_NET_DEV_REGISTER"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_START_AP"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_UPDATE_IE_BUF"), ++#endif ++ ++#if CFG_SUPPORT_ADHOC ++ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_CREATE_IBSS_REQ"), */ ++ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_CREATE_IBSS_GRANT"), */ ++ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_MERGE_IBSS_REQ"), */ ++ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_MERGE_IBSS_GRANT"), */ ++ (PUINT_8) DISP_STRING("MID_SCN_AIS_FOUND_IBSS"), ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ (PUINT_8) DISP_STRING("MID_SAA_AIS_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_MNY_AIS_REMAIN_ON_CHANNEL"), ++ (PUINT_8) DISP_STRING("MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL"), ++ (PUINT_8) DISP_STRING("MID_MNY_AIS_MGMT_TX") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/* This message entry will be re-ordered based on the message ID order ++ * by invoking mboxInitMsgMap() ++ */ ++static MSG_HNDL_ENTRY_T arMsgMapTable[] = { ++ {MID_MNY_CNM_CH_REQ, cnmChMngrRequestPrivilege}, ++ {MID_MNY_CNM_CH_ABORT, cnmChMngrAbortPrivilege}, ++ {MID_CNM_AIS_CH_GRANT, aisFsmRunEventChGrant}, ++#if CFG_ENABLE_WIFI_DIRECT ++ {MID_CNM_P2P_CH_GRANT, p2pFsmRunEventChGrant}, /*set in gl_p2p_init.c */ ++#else ++ {MID_CNM_P2P_CH_GRANT, mboxDummy}, ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ {MID_CNM_BOW_CH_GRANT, bowRunEventChGrant}, ++#else ++ {MID_CNM_BOW_CH_GRANT, mboxDummy}, ++#endif ++ ++ /*--------------------------------------------------*/ ++ /* SCN Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ {MID_AIS_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_AIS_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_AIS_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_P2P_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_P2P_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_P2P_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_BOW_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_BOW_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_BOW_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_RLM_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_RLM_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_RLM_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_SCN_AIS_SCAN_DONE, aisFsmRunEventScanDone}, ++#if CFG_ENABLE_WIFI_DIRECT ++ {MID_SCN_P2P_SCAN_DONE, p2pFsmRunEventScanDone}, /*set in gl_p2p_init.c */ ++#else ++ {MID_SCN_P2P_SCAN_DONE, mboxDummy}, ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ {MID_SCN_BOW_SCAN_DONE, bowResponderScanDone}, ++#else ++ {MID_SCN_BOW_SCAN_DONE, mboxDummy}, ++#endif ++ {MID_SCN_RLM_SCAN_DONE, rlmObssScanDone}, ++ ++ /*--------------------------------------------------*/ ++ /* AIS Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ {MID_OID_AIS_FSM_JOIN_REQ, aisFsmRunEventAbort}, ++ {MID_OID_AIS_FSM_ABORT, aisFsmRunEventAbort}, ++ {MID_AIS_SAA_FSM_START, saaFsmRunEventStart}, ++ {MID_AIS_SAA_FSM_ABORT, saaFsmRunEventAbort}, ++ {MID_SAA_AIS_JOIN_COMPLETE, aisFsmRunEventJoinComplete}, ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /*--------------------------------------------------*/ ++ /* BOW Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ {MID_BOW_SAA_FSM_START, saaFsmRunEventStart}, ++ {MID_BOW_SAA_FSM_ABORT, saaFsmRunEventAbort}, ++ {MID_SAA_BOW_JOIN_COMPLETE, bowFsmRunEventJoinComplete}, ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT /*set in gl_p2p_init.c */ ++ {MID_P2P_SAA_FSM_START, saaFsmRunEventStart}, ++ {MID_P2P_SAA_FSM_ABORT, saaFsmRunEventAbort}, ++ {MID_SAA_P2P_JOIN_COMPLETE, p2pFsmRunEventJoinComplete}, /* TODO: p2pFsmRunEventJoinComplete */ ++ ++ {MID_MNY_P2P_FUN_SWITCH, p2pFsmRunEventSwitchOPMode}, ++ {MID_MNY_P2P_DEVICE_DISCOVERY, p2pFsmRunEventScanRequest}, ++ {MID_MNY_P2P_CONNECTION_REQ, p2pFsmRunEventConnectionRequest}, ++ {MID_MNY_P2P_CONNECTION_ABORT, p2pFsmRunEventConnectionAbort}, ++ {MID_MNY_P2P_BEACON_UPDATE, p2pFsmRunEventBeaconUpdate}, ++ {MID_MNY_P2P_STOP_AP, p2pFsmRunEventStopAP}, ++ {MID_MNY_P2P_CHNL_REQ, p2pFsmRunEventChannelRequest}, ++ {MID_MNY_P2P_CHNL_ABORT, p2pFsmRunEventChannelAbort}, ++ {MID_MNY_P2P_MGMT_TX, p2pFsmRunEventMgmtFrameTx}, ++ {MID_MNY_P2P_GROUP_DISSOLVE, p2pFsmRunEventDissolve}, ++ {MID_MNY_P2P_MGMT_FRAME_REGISTER, p2pFsmRunEventMgmtFrameRegister}, ++ {MID_MNY_P2P_NET_DEV_REGISTER, p2pFsmRunEventNetDeviceRegister}, ++ {MID_MNY_P2P_START_AP, p2pFsmRunEventStartAP}, ++ {MID_MNY_P2P_MGMT_FRAME_UPDATE, p2pFsmRunEventUpdateMgmtFrame}, ++ {MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, p2pFsmRunEventExtendListen}, ++#if CFG_SUPPORT_WFD ++ {MID_MNY_P2P_WFD_CFG_UPDATE, p2pFsmRunEventWfdSettingUpdate}, ++#endif ++ ++#endif ++ ++#if CFG_SUPPORT_ADHOC ++ {MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer}, ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ {MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort}, ++ {MID_MNY_AIS_REMAIN_ON_CHANNEL, aisFsmRunEventRemainOnChannel}, ++ {MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, aisFsmRunEventCancelRemainOnChannel}, ++ {MID_MNY_AIS_MGMT_TX, aisFsmRunEventMgmtFrameTx} ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if DBG ++#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ ++ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ ++ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ ++ DBGLOG(CNM, LOUD, "DO MSG [%d: %s]\n", prMsg->eMsgId, apucDebugMsg[prMsg->eMsgId]); \ ++ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ ++ } \ ++ else { \ ++ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ ++ cnmMemFree(prAdapter, prMsg); \ ++ } \ ++} while (0) ++#else ++#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ ++ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ ++ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ ++ DBGLOG(CNM, LOUD, "DO MSG [%d]\n", prMsg->eMsgId); \ ++ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ ++ } \ ++ else { \ ++ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ ++ cnmMemFree(prAdapter, prMsg); \ ++ } \ ++} while (0) ++#endif ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxInitMsgMap(VOID) ++{ ++ UINT_32 i, idx; ++ MSG_HNDL_ENTRY_T rTempEntry; ++ ++ ASSERT((sizeof(arMsgMapTable) / sizeof(MSG_HNDL_ENTRY_T)) == MID_TOTAL_NUM); ++ ++ for (i = 0; i < MID_TOTAL_NUM; i++) { ++ if (arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i) ++ continue; ++ for (idx = i + 1; idx < MID_TOTAL_NUM; idx++) { ++ if (arMsgMapTable[idx].eMsgId == (ENUM_MSG_ID_T) i) ++ break; ++ } ++ ASSERT(idx < MID_TOTAL_NUM); ++ if (idx >= MID_TOTAL_NUM) ++ continue; ++ ++ /* Swap target entry and current entry */ ++ rTempEntry.eMsgId = arMsgMapTable[idx].eMsgId; ++ rTempEntry.pfMsgHndl = arMsgMapTable[idx].pfMsgHndl; ++ ++ arMsgMapTable[idx].eMsgId = arMsgMapTable[i].eMsgId; ++ arMsgMapTable[idx].pfMsgHndl = arMsgMapTable[i].pfMsgHndl; ++ ++ arMsgMapTable[i].eMsgId = rTempEntry.eMsgId; ++ arMsgMapTable[i].pfMsgHndl = rTempEntry.pfMsgHndl; ++ } ++ ++ /* Verify the correctness of final message map */ ++ for (i = 0; i < MID_TOTAL_NUM; i++) { ++ ASSERT(arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i); ++ while (arMsgMapTable[i].eMsgId != (ENUM_MSG_ID_T) i) ++ ; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId) ++{ ++ P_MBOX_T prMbox; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); ++ ASSERT(prAdapter); ++ ++ prMbox = &(prAdapter->arMbox[eMboxId]); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_INITIALIZE(&prMbox->rLinkHead); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++mboxSendMsg(IN P_ADAPTER_T prAdapter, ++ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod) ++{ ++ P_MBOX_T prMbox; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); ++ ASSERT(prMsg); ++ ASSERT(prAdapter); ++ ++ prMbox = &(prAdapter->arMbox[eMboxId]); ++ ++ switch (eMethod) { ++ case MSG_SEND_METHOD_BUF: ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_INSERT_TAIL(&prMbox->rLinkHead, &prMsg->rLinkEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ ++ /* to wake up main service thread */ ++ GLUE_SET_EVENT(prAdapter->prGlueInfo); ++ ++ break; ++ ++ case MSG_SEND_METHOD_UNBUF: ++ MBOX_HNDL_MSG(prAdapter, prMsg); ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, ENUM_MBOX_ID_T eMboxId) ++{ ++ P_MBOX_T prMbox; ++ P_MSG_HDR_T prMsg; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); ++ ASSERT(prAdapter); ++ ++ prMbox = &(prAdapter->arMbox[eMboxId]); ++ ++ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ ++ ASSERT(prMsg); ++ MBOX_HNDL_MSG(prAdapter, prMsg); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ /* Initialize Mailbox */ ++ mboxInitMsgMap(); ++ ++ /* Setup/initialize each mailbox */ ++ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) ++ mboxSetup(prAdapter, i); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxDestroy(IN P_ADAPTER_T prAdapter) ++{ ++ P_MBOX_T prMbox; ++ P_MSG_HDR_T prMsg; ++ UINT_8 i; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { ++ prMbox = &(prAdapter->arMbox[i]); ++ ++ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ ++ ASSERT(prMsg); ++ cnmMemFree(prAdapter, prMsg); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is dummy function to prevent empty arMsgMapTable[] for compiling. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxDummy(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ASSERT(prAdapter); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c +new file mode 100644 +index 000000000000..7fb71a199ccf +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c +@@ -0,0 +1,498 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2 ++*/ ++ ++/*! \file "hs20.c" ++ \brief This file including the hotspot 2.0 related function. ++ ++ This file provided the macros and functions library support for the ++ protocol layer hotspot 2.0 related function. ++ ++*/ ++ ++/* ++** Log: hs20.c ++ * ++ */ ++ ++ /******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to generate Interworking IE for Probe Rsp, Bcn, Assoc Req/Rsp. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] prMsduInfo Pointer of the Msdu Info ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) ++{ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to generate Roaming Consortium IE for Probe Rsp, Bcn, Assoc Req/Rsp. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] prMsduInfo Pointer of the Msdu Info ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) ++{ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to generate HS2.0 IE for Probe Rsp, Bcn, Assoc Req/Rsp. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] prMsduInfo Pointer of the Msdu Info ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ /* ASSOC INFO IE ID: 221 :0xDD */ ++ if (prAdapter->prGlueInfo->u2HS20AssocInfoIELen) { ++ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucHS20AssocInfoIE, ++ prAdapter->prGlueInfo->u2HS20AssocInfoIELen); ++ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2HS20AssocInfoIELen; ++ } ++ ++} ++ ++VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_HS20_EXT_CAP_T prExtCap; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ /* Add Extended Capabilities IE */ ++ prExtCap = (P_HS20_EXT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; ++ else ++ prExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ ++ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); ++ ++ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); ++ ++ /* For R2 WNM-Notification */ ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); ++ } ++ kalPrint("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP); ++ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to fill up the content of Ext Cap IE bit 31. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] pucIE Pointer of the IE buffer ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) ++{ ++ P_HS20_EXT_CAP_T prExtCap; ++ ++ ASSERT(prAdapter); ++ ++ /* Add Extended Capabilities IE */ ++ prExtCap = (P_HS20_EXT_CAP_T) pucIE; ++ ++ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; ++ else ++ prExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ ++ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); ++ ++ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); ++ ++ /* For R2 WNM-Notification */ ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to fill up the content of HS2.0 IE. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] pucIE Pointer of the IE buffer ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) ++{ ++ P_IE_HS20_INDICATION_T prHS20IndicationIe; ++ /* P_HS20_INFO_T prHS20Info; */ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ ++ /* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */ ++ ++ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pucIE; ++ ++ prHS20IndicationIe->ucId = ELEM_ID_VENDOR; ++ prHS20IndicationIe->ucLength = sizeof(IE_HS20_INDICATION_T) - ELEM_HDR_LEN; ++ prHS20IndicationIe->aucOui[0] = aucWfaOui[0]; ++ prHS20IndicationIe->aucOui[1] = aucWfaOui[1]; ++ prHS20IndicationIe->aucOui[2] = aucWfaOui[2]; ++ prHS20IndicationIe->ucType = VENDOR_OUI_TYPE_HS20; ++ prHS20IndicationIe->ucHotspotConfig = 0x00; /* prHS20Info->ucHotspotConfig; */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called while calculating length of hotspot 2.0 indication IE for Probe Request. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] pucTargetBSSID Pointer of target HESSID ++* ++* \return the length of composed HS20 IE ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID) ++{ ++ UINT_32 u4IeLength; ++ ++ if (0) /* Todo:: Not HS20 STA */ ++ return 0; ++ ++ u4IeLength = ++ sizeof(IE_HS20_INDICATION_T) + /* sizeof(IE_INTERWORKING_T) */ + (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP); ++ ++ if (!pucTargetBSSID) { ++ /* Do nothing */ ++ /* u4IeLength -= MAC_ADDR_LEN; */ ++ } ++ ++ return u4IeLength; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called while composing hotspot 2.0 indication IE for Probe Request. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] pucTargetBSSID Pointer of target HESSID ++* \param[out] prIE Pointer of the IE buffer ++* ++* \return the wlan status ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE) ++{ ++ if (0) /* Todo:: Not HS20 STA */ ++ return 0; ++#if 0 ++ P_HS20_INFO_T prHS20Info; ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ ++ /* ++ * Generate 802.11u Interworking IE (107) ++ */ ++ hs20FillInterworkingIE(prAdapter, ++ prHS20Info->ucAccessNetworkOptions, ++ prHS20Info->ucVenueGroup, prHS20Info->ucVenueType, pucTargetBSSID, prIE); ++ prIE += IE_SIZE(prIE); ++#endif ++ /* ++ * Generate Ext Cap IE (127) ++ */ ++ hs20FillProreqExtCapIE(prAdapter, prIE); ++ prIE += IE_SIZE(prIE); ++ ++ /* ++ * Generate HS2.0 Indication IE (221) ++ */ ++ hs20FillHS20IE(prAdapter, prIE); ++ prIE += IE_SIZE(prIE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ PUINT_8 pucSenderIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET; ++ PUINT_8 pucTargetIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET; ++ PUINT_8 pucSenderMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SNEDER_MAC_OFFSET); ++#if CFG_HS20_DEBUG && 0 ++/* UINT_8 aucIpAllZero[4] = {0,0,0,0}; */ ++/* UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */ ++ PUINT_8 pucTargetMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET); ++#endif ++ ++#if CFG_HS20_DEBUG && 0 ++ PUINT_16 pu2ArpOper = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET); ++ ++ kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper)); ++ kalPrint("SENDER[ %pM ] [%pI4]\n", pucSenderMac, pucSenderIP); ++ kalPrint("TARGET[ %pM ] [%pI4]\n", pucTargetMac, pucTargetIP); ++#endif ++ ++ /* IsGratuitousArp */ ++ if (!kalMemCmp(pucSenderIP, pucTargetIP, 4)) { ++ kalPrint("Drop Gratuitous ARP from [ %pM ] [%pI4]\n", pucSenderMac, pucTargetIP); ++ return TRUE; ++ } ++ return FALSE; ++} ++ ++BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ PUINT_8 pucIpv6Protocol = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_PROTOCOL_OFFSET); ++ ++ /* kalPrint("pucIpv6Protocol [%02X:%02X]\n", *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); */ ++ if (*pucIpv6Protocol == IPV6_PROTOCOL_ICMPV6) { ++ PUINT_8 pucICMPv6Type = ++ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_TYPE_OFFSET); ++ /* kalPrint("pucICMPv6Type [%02X:%02X]\n", *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); */ ++ if (*pucICMPv6Type == ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT) { ++ PUINT_8 pucICMPv6Flag = ++ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_FLAG_OFFSET); ++ PUINT_8 pucSrcMAC = ((PUINT_8) prCurrSwRfb->pvHeader + MAC_ADDR_LEN); ++ ++#if CFG_HS20_DEBUG ++ kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n", ++ *pucICMPv6Flag, ++ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_ROUTER_BIT) >> 7, ++ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT) >> 6, ++ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_OVERWRITE_BIT) >> 5); ++#endif ++ if (!(*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT)) { ++ kalPrint("Drop Unsolicited Neighbor Advertisement from [%pM]\n", pucSrcMAC); ++ return TRUE; ++ } ++ } ++ } ++ ++ return FALSE; ++} ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ /* ++ P_CONNECTION_SETTINGS_T prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ PUINT_8 pucEthDestAddr = prCurrSwRfb->pvHeader; ++ */ ++ /* 3 TODO: Need to verify this function before enable it */ ++ return FALSE; ++ /* ++ if ((prConnSettings->eEncStatus != ENUM_ENCRYPTION_DISABLED) && IS_BMCAST_MAC_ADDR(pucEthDestAddr)) { ++ UINT_8 ucIdx = 0; ++ PUINT_32 prIpAddr, prPacketDA; ++ PUINT_16 pu2PktIpVer = ++ (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); ++ ++ if (*pu2PktIpVer == htons(ETH_P_IPV4)) { ++ if (!prBssInfo->prIpV4NetAddrList) ++ return FALSE; ++ for (ucIdx = 0; ucIdx < prBssInfo->prIpV4NetAddrList->ucAddrCount; ucIdx++) { ++ prIpAddr = (PUINT_32) &prBssInfo->prIpV4NetAddrList->arNetAddr[ucIdx].aucIpAddr[0]; ++ prPacketDA = ++ (PUINT_32) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ++ IPV4_HDR_IP_DST_ADDR_OFFSET); ++ ++ if (kalMemCmp(prIpAddr, prPacketDA, 4) == 0) { ++ kalPrint("Drop FORGED IPv4 packet\n"); ++ return TRUE; ++ } ++ } ++ } ++#ifdef CONFIG_IPV6 ++ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) { ++ UINT_8 aucIPv6Mac[MAC_ADDR_LEN]; ++ PUINT_8 pucIdx = ++ prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET; ++ ++ kalMemCopy(&aucIPv6Mac[0], pucIdx, 3); ++ pucIdx += 5; ++ kalMemCopy(&aucIPv6Mac[3], pucIdx, 3); ++ kalPrint("Get IPv6 frame Dst IP MAC part %pM\n", aucIPv6Mac); ++ if (EQUAL_MAC_ADDR(aucIPv6Mac, prBssInfo->aucOwnMacAddr)) { ++ kalPrint("Drop FORGED IPv6 packet\n"); ++ return TRUE; ++ } ++ } ++#endif ++ } ++ ++ return FALSE; ++ */ ++} ++#endif ++ ++BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ PUINT_16 pu2PktIpVer = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); ++ ++ /* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */ ++#if CFG_HS20_DEBUG & 0 ++ UINT_8 i = 0; ++ ++ kalPrint("==============================================="); ++ for (i = 0; i < 96; i++) { ++ if (!(i % 16)) ++ kalPrint("\n"); ++ kalPrint("%02X ", *((PUINT_8) prCurrSwRfb->pvHeader + i)); ++ } ++ kalPrint("\n"); ++#endif ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ if (hs20IsForgedGTKFrame(prAdapter, prBssInfo, prCurrSwRfb)) ++ return TRUE; ++ ++#endif ++ if (*pu2PktIpVer == htons(ETH_P_ARP)) ++ return hs20IsGratuitousArp(prAdapter, prCurrSwRfb); ++ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) ++ return hs20IsUnsolicitedNeighborAdv(prAdapter, prCurrSwRfb); ++ ++ return FALSE; ++} ++ ++BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) ++{ ++#if 1 ++ if (prAdapter->prGlueInfo->fgConnectHS20AP) ++ return TRUE; ++#else ++ PARAM_SSID_T rParamSsid; ++ P_BSS_DESC_T prBssDesc; ++ ++ rParamSsid.u4SsidLen = prBssInfo->ucSSIDLen; ++ COPY_SSID(rParamSsid.aucSsid, rParamSsid.u4SsidLen, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ ++ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, prBssInfo->aucBSSID, TRUE, &rParamSsid); ++ if (!prBssDesc) ++ return FALSE; ++ ++ if (prBssDesc->fgIsSupportHS20) { ++ if (!(prBssDesc->ucHotspotConfig & ELEM_HS_CONFIG_DGAF_DISABLED_MASK)) ++ return TRUE; ++ ++ /* Disable frame filter only if DGAF == 1 */ ++ return FALSE; ++ ++ } ++#endif ++ ++ /* For Now, always return true to run hs20 check even for legacy AP */ ++ return TRUE; ++} ++ ++WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) ++{ ++ P_PARAM_HS20_SET_BSSID_POOL prParamBssidPool = (P_PARAM_HS20_SET_BSSID_POOL) pvBuffer; ++ P_HS20_INFO_T prHS20Info; ++ UINT_8 ucIdx; ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ kalPrint("[%s]Set Bssid Pool! enable[%d] num[%d]\n", __func__, prParamBssidPool->fgIsEnable, ++ prParamBssidPool->ucNumBssidPool); ++ for (ucIdx = 0; ucIdx < prParamBssidPool->ucNumBssidPool; ucIdx++) { ++ COPY_MAC_ADDR(prHS20Info->arBssidPool[ucIdx].aucBSSID, &prParamBssidPool->arBSSID[ucIdx]); ++ kalPrint("[%s][%d][ %pM ]\n", __func__, ucIdx, (prHS20Info->arBssidPool[ucIdx].aucBSSID)); ++ } ++ prHS20Info->fgIsHS2SigmaMode = prParamBssidPool->fgIsEnable; ++ prHS20Info->ucNumBssidPoolEntry = prParamBssidPool->ucNumBssidPool; ++ ++#if 0 ++ wlanClearScanningResult(prAdapter); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c +new file mode 100644 +index 000000000000..469a48ebe9c1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c +@@ -0,0 +1,111 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/mib.c#1 ++*/ ++ ++/*! \file "mib.c" ++ \brief This file includes the mib default vale and functions. ++*/ ++ ++/* ++** Log: mib.c ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add mib.c. ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[] = { ++ {RATE_SET_HR_DSSS, TRUE, FALSE} ++ , /* For PHY_TYPE_HR_DSSS_INDEX(0) */ ++ {RATE_SET_ERP, TRUE, TRUE} ++ , /* For PHY_TYPE_ERP_INDEX(1) */ ++ {RATE_SET_ERP_P2P, TRUE, TRUE} ++ , /* For PHY_TYPE_ERP_P2P_INDEX(2) */ ++ {RATE_SET_OFDM, FALSE, FALSE} ++ , /* For PHY_TYPE_OFDM_INDEX(3) */ ++}; ++ ++NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[AD_HOC_MODE_NUM] = { ++ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} ++ , /* For AD_HOC_MODE_11B(0) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} ++ , /* For AD_HOC_MODE_MIXED_11BG(1) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} ++ , /* For AD_HOC_MODE_11G(2) */ ++ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} ++ , /* For AD_HOC_MODE_11A(3) */ ++}; ++ ++NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[AP_MODE_NUM] = { ++ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} ++ , /* For AP_MODE_11B(0) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} ++ , /* For AP_MODE_MIXED_11BG(1) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} ++ , /* For AP_MODE_11G(2) */ ++ {PHY_TYPE_ERP_P2P_INDEX, BASIC_RATE_SET_ERP_P2P} ++ , /* For AP_MODE_11G_P2P(3) */ ++ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} ++ , /* For AP_MODE_11A(4) */ ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c +new file mode 100644 +index 000000000000..cb5fbebedd49 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c +@@ -0,0 +1,87 @@ ++/* ++** Id: @(#) p2p_assoc.c@@ ++*/ ++ ++/*! \file "p2p_assoc.c" ++ \brief This file includes the Wi-Fi Direct association-related functions. ++ ++ This file includes the association-related functions. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for P2P Association ++* Request Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ /* Fill the SSID element. */ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ ++ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of ++ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. ++ */ ++ ++ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, ++ SSID_IE(pucBuffer)->ucLength, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ return pucBuffer; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c +new file mode 100644 +index 000000000000..72a20a322cee +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c +@@ -0,0 +1,58 @@ ++/* ++** Id: @(#) p2p_bss.c@@ ++*/ ++ ++/*! \file "p2p_bss.c" ++ \brief This file contains the functions for creating p2p BSS(AP). ++ ++ This file contains the functions for BSS(AP). We may create a BSS ++ network, or merge with exist IBSS network and sending Beacon Frame or reply ++ the Probe Response Frame for received Probe Request Frame. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c +new file mode 100644 +index 000000000000..f8c09e2aa9de +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c +@@ -0,0 +1,3139 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/mgmt/p2p_fsm.c#61 ++*/ ++ ++/*! \file "p2p_fsm.c" ++ \brief This file defines the FSM for P2P Module. ++ ++ This file defines the FSM for P2P Module. ++*/ ++ ++/* ++** Log: p2p_fsm.c ++** ++** 12 20 2012 yuche.tsai ++** [ALPS00410124] [Rose][Free Test][KE][rlmUpdateParamsForAP]The device reboot automatically ++** and then "Fatal/Kernel" pops up during use data service.(Once) ++** Fix possible NULL station record cause KE under AP mode. ++** May due to variable uninitial. ++** Review: http://mtksap20:8080/go?page=NewReview&reviewid=49970 ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected ++**to AP previously,one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 08 21 2012 yuche.tsai ++** NULL ++** fix disconnect indication. ++** ++** 08 16 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** Fix p2p bug find on ALPS.JB trunk. ++** ++** 07 27 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update for driver unload KE issue. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Fix the compile flag of enhancement. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000808] [Volunteer Patch][MT6620][Driver/FW] Device discoverability issue fix ++ * Change device discoverability methodology. From driver SCAN to FW lock channel. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Add wifi direct connection enhancement method I, II & VI. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000833] [Volunteer Patch][WiFi Direct][Driver] Service Discovery Frame RX Indicate Issue ++ * Fix Service Discovery Race Condition Issue. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 21 2011 yuche.tsai ++ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. ++ * Fix an issue of accepting connection of GO. ++ * ++ * 06 21 2011 yuche.tsai ++ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability ++ * Drop GAS frame when SD is not enabled. ++ * ++ * 06 20 2011 yuche.tsai ++ * NULL ++ * Fix compile error. ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. ++ * Fix connection indication twice issue. ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000795] [Volunteer Patch][MT6620][Driver] GO can not connect second device issue ++ * Solve P2P GO can not formation with second device issue. ++ * ++ * 06 14 2011 yuche.tsai ++ * NULL ++ * Change disconnect feature. ++ * ++ * 06 10 2011 yuche.tsai ++ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability[WCXRP00000776] ++ * [Need Patch][MT6620][Driver] MT6620 response probe request of P2P device with P2P IE under Hot Spot mode. ++ * 1. Dynamic enable SD capability after P2P supplicant ready. ++ * 2. Avoid response probe respone with p2p IE when under hot spot mode. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Fix RX SD request under AP mode issue. ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * eliminate unused parameters for SAA-FSM ++ * ++ * 05 26 2011 yuche.tsai ++ * [WCXRP00000745] Support accepting connection after one Group Connection Lost. ++ ++After Group Formation & lost connection, if MT6620 behave as: ++ ++1. GO: It would keep under GO state until been dissolved by supplicant. ++ ++ At this time, other P2P device can use join method to join this group. ++ ++2. GC: It would keep on searching target GO or target device until been dissolved by supplicant. ++ ++At this time, it would ignore other P2P device formation request. ++ ++-- ++ ++Modification: Make driver to accept GO NEGO REQ at this time, to let user decide to accept new connection or not. ++ ++ * [Volunteer Patch][MT6620][Driver] ++ * Driver would indicate connection request, if password ID is not ready but connection request is issued. ++ * ++ * 05 18 2011 yuche.tsai ++ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. ++ * A solution for both connection request & IO control. ++ * ++ * 05 16 2011 yuche.tsai ++ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. ++ * Fix SD request can not send out issue. ++ * ++ * 05 09 2011 terry.wu ++ * [WCXRP00000711] [MT6620 Wi-Fi][Driver] Set Initial value of StaType in StaRec for Hotspot Client ++ * Set initial value of StaType in StaRec for hotspot client. ++ * ++ * 05 04 2011 yuche.tsai ++ * [WCXRP00000697] [Volunteer Patch][MT6620][Driver] ++ * Bug fix for p2p descriptor is NULL if BSS descriptor is found first. ++ * ++ * 05 04 2011 yuche.tsai ++ * NULL ++ * Support partial persistent group function. ++ * ++ * 05 02 2011 yuche.tsai ++ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. ++ * Clear formation flag after formation timeout. ++ * ++ * 04 20 2011 yuche.tsai ++ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition ++ * when add scan & query scan result at the same time. ++ * Fix side effect while starting ATGO. ++ * ++ * 04 20 2011 yuche.tsai ++ * NULL ++ * Fix ASSERT issue in FW, side effect of last change. ++ * ++ * 04 19 2011 yuche.tsai ++ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition ++ * when add scan & query scan result at the same time. ++ * Workaround for multiple device connection, before invitation ready. ++ * ++ * 04 19 2011 yuche.tsai ++ * [WCXRP00000665] [Wifi Direct][MT6620 E4] When use Ralink's dongle to establish wifi direct connection with PBC. ++ * But 6573 always not pop accept option to establish connection. ++ * Support connection indication when GO NEGO REQ doesn't have configure method, instead it has PasswordID. ++ * ++ * 04 18 2011 yuche.tsai ++ * NULL ++ * Fix error. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Fix a connection issue. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Fix the channel issue of AP mode. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Connection flow refine for Sigma test. ++ * ++ * 04 09 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Fix Device discoverability related issue. ++ * ++ * 04 09 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Fix bug for Device Discoverability. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Fix compile error. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * ++ * 03 28 2011 yuche.tsai ++ * NULL ++ * Fix a possible issue for retry join when media status connected. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Improve some error handleing. ++ * ++ * 03 24 2011 yuche.tsai ++ * NULL ++ * Assign AID before change STA_REC state to state 3. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix Response Rate Issue when TX Auth Rsp Frame under P2P Mode. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix issue of connection to one GC. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix ASSERT issue when starting Hot-spot. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * When Target Information is not available, change to passive mode. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Fix one connection issue while using Keypad to connect a GO. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * 1. Fix two issues that may cause kernel panic. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Fix GC connect to other device issue. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * 1.Shorten the LISTEN interval. ++ * 2. Fix IF address issue when we are GO ++ * 3. Fix LISTEN channel issue. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Modify formation policy setting. ++ * ++ * 03 21 2011 yuche.tsai ++ * NULL ++ * Solve Listen State doesn't response probe response issue. ++ * ++ * 03 21 2011 yuche.tsai ++ * NULL ++ * Change P2P Connection Request Flow. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue ++ * Indicate the correct Group SSID when join on Group. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue ++ * Support the third P2P device to join GO/GC group. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000578] [Volunteer Patch][MT6620][Driver] Separate Connection Request from general IOCTL ++ * Separate connection request from general IOCTL. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow ++ * Modify connection flow after Group Formation Complete, or device connect to a GO. ++ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * When AIS is connect to an AP, Hot Spot would be enabled under fixed same channel. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Solve the Group Info IE in Probe Response incorrect issue. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Release Channel after Join Complete. ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the protected while at P2P start GO, and skip some security check . ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix local configure method issue. ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix some configure method issue. ++ * ++ * 03 14 2011 yuche.tsai ++ * NULL ++ * . ++ * ++ * 03 14 2011 yuche.tsai ++ * NULL ++ * Fix password ID issue. ++ * ++ * 03 10 2011 yuche.tsai ++ * NULL ++ * Add P2P API. ++ * ++ * 03 08 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue[WCXRP00000509] ++ * [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. ++ * . ++ * ++ * 03 07 2011 yuche.tsai ++ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. ++ * . ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 04 2011 wh.su ++ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue ++ * fixed the p2p action frame type check for device request indication. ++ * ++ * 03 02 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix Service Discovery RX packet buffer pointer. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation ++ * Update channel issue when doing GO formation.. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Related wlanoid function. ++ * ++ * 02 21 2011 yuche.tsai ++ * [WCXRP00000481] [Volunteer Patch][MT6620][FW] Scan hang under concurrent case. ++ * Fix all BE issue of WSC or P2P IE. ++ * ++ * 02 18 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * fixed the wsc config method mapping to driver used config method issue. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000479] [Volunteer Patch][MT6620][Driver] Probe Response of P2P using 11b rate. ++ * Update basic rate to FW, after P2P is initialed. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame during search ++ * phase do not contain P2P wildcard SSID. ++ * Use P2P Wildcard SSID when scan type of P2P_WILDCARD_SSID is set. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue ++ * Fix WSC IE BE format issue. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * append the WSC IE config method attribute at provision discovery request. ++ * ++ * 02 16 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * fixed the probe request send out without WSC IE issue (at P2P). ++ * ++ * 02 16 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * If two station connected to the Hot-Spot and one disconnect, FW would get into an infinite loop ++ * ++ * 02 15 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Fix re-connection issue after RX deauthentication. ++ * ++ * 02 15 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Fix conneciton issue after disconnect with AP. ++ * ++ * 02 12 2011 yuche.tsai ++ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. ++ * P2P Create Station Type according to Target BSS capability. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Support Disassoc & Deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Indication Related code. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add Support for MLME deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Fix Client Limit Issue. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect ++ * to target station for AAA module. ++ * Disconnect every station client when disolve on P2P group. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * 1. Fix Service Disocvery Logical issue. ++ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect ++ * to target station for AAA module. ++ * Workaround of disable P2P network. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue ++ * 1. Fixed SSID wrong length issue. ++ * 2. Under Hot Spot configuration, there won't be any P2P IE. ++ * 3. Under Hot Spot configuration, P2P FSM won't get into LISTEN state first. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Modify Start GO flow. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Fix desire phy type set issue. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Add desire phy type set phase I. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix P2P Disconnect Issue. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Function. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix compile error when DBG is disabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type Definition. ++ * ++ * 01 19 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Add P2P QoS Support. ++ * ++ * 01 19 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Null NOA attribute setting when no related parameters. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify AAA flow according to CM's comment. ++ * ++ * 01 13 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Resolve Channel ZERO issue. (Uninitialized default channel) ++ * ++ * 01 13 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Update P2P State Debug Message. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Fix bug when allocating message buffer. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, ++ * but if the P2P device is connected, 11b rate is not allowed. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. ++ * 2. Call cnmP2pIsPermit() before active P2P network. ++ * 3. Add channel selection support for AP mode. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix Bug of reference to NULL pointer. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify some behavior of AP mode. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix bug of wrong pointer check. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix Compile Error. ++ * ++ * 01 11 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Add station record into client list before change it state from STATE_2 to STATE_3. ++ * ++ * 01 05 2011 yuche.tsai ++ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, ++ * but the SSID length is still invalid. ++ * Specify SSID Type when issue a scan request. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations ++ * to ease physically continuous memory demands ++ * correct typo ++ * ++ * 01 05 2011 george.huang ++ * [WCXRP00000343] [MT6620 Wi-Fi] Add TSF reset path for concurrent operation ++ * modify NOA update path for preventing assertion false alarm. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations ++ * to ease physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 01 03 2011 wh.su ++ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! ++ * let the p2p ap mode acept a legacy device join. ++ * ++ * 12 22 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix Compile Error. ++ * ++ * 12 15 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Refine Connection Flow. ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in ++ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. ++ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client ++ * by checking the P2P IE in assoc req frame. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * The order of invoking nicUpdateBss() and rlm functions ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation. ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation & Provision Discovery. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Update RCIP value when RX assoc request frame. ++ * ++ * 11 29 2010 yuche.tsai ++ * NULL ++ * Update P2P related function for INVITATION & PROVISION DISCOVERY. ++ * ++ * 11 26 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Update P2P PS for NOA function. ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update Code for Invitation Related Function. ++ * ++ * 11 17 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] ++ * Set the Tx lowest rate at wlan table for normal operation ++ * fixed some ASSERT check. ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * fixed the p2p role code error. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * fixed the ASSERT check error ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 10 19 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state ++ * machine[WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android ++ * fixed the compiling error. ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android ++ * adding a code to support Direct GO with a compiling flag . ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. ++ * correct erroneous logic: specifying eBand with incompatible eSco ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * fixed the compiling error. ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at WinXP. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Reset Common IE Buffer of P2P INFO when scan request is issued. ++ * If an action frame other than public action frame is received, return direcly. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add P2P Connection Abort Event Message handler. ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 yuche.tsai ++ * NULL ++ * 1. Fix Interface Address from GO Nego Req/Rsp is not correct. ++ * 2. Fix GO mode does not change media state after station connected. ++ * 3. Fix STA don't response probe request when there is a connection request. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 20 2010 kevin.huang ++ * NULL ++ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Add Glue Layer indication. ++ * ++ * 08 17 2010 yuche.tsai ++ * NULL ++ * Fix compile warning under Linux. ++ * ++ * 08 17 2010 yuche.tsai ++ * NULL ++ * Fix some P2P FSM bug. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add random Interface Address Generation support. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Fix some P2P FSM bug. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Update P2P FSM code for GO Nego. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Join complete indication. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add two boolean in connection request. ++ * Based on these two boolean value, P2P FSM should ++ * decide to do invitation or group formation or start a GO directly. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Update P2P FSM, currently P2P Device Discovery is verified. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Update P2P FSM for group formation. ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * limit build always needs spin-lock declaration. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add P2P FSM code check in. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Update P2P FSM. ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error while enable WIFI_DIRECT support. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Update P2P Function call. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * First draft for migration P2P FSM from FW to Driver. ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Rename CFG flag for P2P ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add code to test P2P GO ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add Wi-Fi Direct SSID and P2P GO Test Mode ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify code due to BAND_24G define was changed ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Revise data structure to share the same BSS_INFO_T for avoiding coding error ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugP2pState[P2P_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("P2P_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("P2P_STATE_SCAN"), ++ (PUINT_8) DISP_STRING("P2P_STATE_AP_CHANNEL_DETECT"), ++ (PUINT_8) DISP_STRING("P2P_STATE_REQING_CHANNEL"), ++ (PUINT_8) DISP_STRING("P2P_STATE_CHNL_ON_HAND"), ++ (PUINT_8) DISP_STRING("P2P_STATE_GC_JOIN") ++}; ++ ++/*lint -restore */ ++#else ++static UINT_8 apucDebugP2pState[P2P_STATE_NUM] = { ++ P2P_STATE_IDLE, ++ P2P_STATE_SCAN, ++ P2P_STATE_AP_CHANNEL_DETECT, ++ P2P_STATE_REQING_CHANNEL, ++ P2P_STATE_CHNL_ON_HAND, ++ P2P_STATE_GC_JOIN ++}; ++ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/* p2pStateXXX : Processing P2P FSM related action. ++ * p2pFSMXXX : Control P2P FSM flow. ++ * p2pFuncXXX : Function for doing one thing. ++ */ ++VOID p2pFsmInit(IN P_ADAPTER_T prAdapter) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ ASSERT_BREAK(prP2pFsmInfo != NULL); ++ ++ LINK_INITIALIZE(&(prP2pFsmInfo->rMsgEventQueue)); ++ LINK_INITIALIZE(&(prP2pBssInfo->rStaRecOfClientList)); ++ ++ prP2pFsmInfo->eCurrentState = prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE; ++ prP2pFsmInfo->prTargetBss = NULL; ++ prP2pFsmInfo->fgIsWPSMode = 0; ++ ++ cnmTimerInitTimer(prAdapter, ++ &(prAdapter->rP2pFsmTimeoutTimer), ++ (PFN_MGMT_TIMEOUT_FUNC) p2pFsmRunEventFsmTimeout, (ULONG) prP2pFsmInfo); ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* 4 <2.1> Initiate BSS_INFO_T - Setup HW ID */ ++ prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; ++ prP2pBssInfo->ucHwDefaultFixedRateCode = RATE_OFDM_6M; ++ ++ prP2pBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prP2pBssInfo->u2BSSBasicRateSet = ++ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prP2pBssInfo->u2OperationalRateSet = ++ rNonHTPhyAttributes[prP2pBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet, ++ prP2pBssInfo->u2BSSBasicRateSet, ++ prP2pBssInfo->aucAllSupportedRates, &prP2pBssInfo->ucAllSupportedRatesLen); ++ ++ prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); ++ ++ if (prP2pBssInfo->prBeacon) { ++ prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; ++ prP2pBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ ++ prP2pBssInfo->prBeacon->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ } else { ++ /* Out of memory. */ ++ ASSERT(FALSE); ++ } ++ ++ prP2pBssInfo->eCurrentOPMode = OP_MODE_NUM; ++ ++ prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; ++ prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; ++ prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; ++ prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL; ++ prP2pBssInfo->eBand = BAND_2G4; ++ prP2pBssInfo->eBssSCO = CHNL_EXT_SCN; ++ ++ if (prAdapter->rWifiVar.fgSupportQoS) ++ prP2pBssInfo->fgIsQBSS = TRUE; ++ else ++ prP2pBssInfo->fgIsQBSS = FALSE; ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } while (FALSE); ++ ++} /* p2pFsmInit */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function is used to uninitialize the value in P2P_FSM_INFO_T for ++* P2P FSM operation ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ DEBUGFUNC("p2pFsmUninit()"); ++ DBGLOG(P2P, INFO, "->p2pFsmUninit()\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, OP_MODE_P2P_DEVICE, TRUE); ++ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM); ++ ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ wlanAcquirePowerControl(prAdapter); ++ ++ /* Release all pending CMD queue. */ ++ DBGLOG(P2P, TRACE, "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n", ++ (UINT_32) prAdapter->prGlueInfo->rCmdQueue.u4NumElem); ++ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); ++ ++ wlanReleasePowerControl(prAdapter); ++ ++ /* Release pending mgmt frame, ++ * mgmt frame may be pending by CMD without resource. ++ */ ++ kalClearMgmtFramesByNetType(prAdapter->prGlueInfo, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Clear PendingCmdQue */ ++ wlanReleasePendingCMDbyNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ if (prP2pBssInfo->prBeacon) { ++ cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); ++ prP2pBssInfo->prBeacon = NULL; ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* end of p2pFsmUninit() */ ++ ++VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ BOOLEAN fgIsTransOut = (BOOLEAN) FALSE; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (!IS_BSS_ACTIVE(prP2pBssInfo)) { ++ if (!cnmP2PIsPermitted(prAdapter)) ++ return; ++ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ fgIsTransOut = fgIsTransOut ? FALSE : TRUE; ++ ++ if (!fgIsTransOut) { ++#if DBG ++ DBGLOG(P2P, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugP2pState[prP2pFsmInfo->eCurrentState], ++ apucDebugP2pState[eNextState]); ++#else ++ DBGLOG(P2P, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_P2P_IDX, apucDebugP2pState[prP2pFsmInfo->eCurrentState], ++ apucDebugP2pState[eNextState]); ++#endif ++ ++ /* Transition into current state. */ ++ prP2pFsmInfo->ePreviousState = prP2pFsmInfo->eCurrentState; ++ prP2pFsmInfo->eCurrentState = eNextState; ++ } ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_IDLE: ++ if (fgIsTransOut) ++ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, eNextState); ++ else ++ fgIsTransOut = p2pStateInit_IDLE(prAdapter, prP2pFsmInfo, prP2pBssInfo, &eNextState); ++ break; ++ case P2P_STATE_SCAN: ++ if (fgIsTransOut) { ++ /* Scan done / scan canceled. */ ++ p2pStateAbort_SCAN(prAdapter, prP2pFsmInfo, eNextState); ++ } else { ++ /* Initial scan request. */ ++ p2pStateInit_SCAN(prAdapter, prP2pFsmInfo); ++ } ++ ++ break; ++ case P2P_STATE_AP_CHANNEL_DETECT: ++ if (fgIsTransOut) { ++ /* Scan done */ ++ /* Get sparse channel result. */ ++ p2pStateAbort_AP_CHANNEL_DETECT(prAdapter, ++ prP2pFsmInfo, prP2pSpecificBssInfo, eNextState); ++ } ++ ++ else { ++ /* Initial passive scan request. */ ++ p2pStateInit_AP_CHANNEL_DETECT(prAdapter, prP2pFsmInfo); ++ } ++ ++ break; ++ case P2P_STATE_REQING_CHANNEL: ++ if (fgIsTransOut) { ++ /* Channel on hand / Channel canceled. */ ++ p2pStateAbort_REQING_CHANNEL(prAdapter, prP2pFsmInfo, eNextState); ++ } else { ++ /* Initial channel request. */ ++ p2pFuncAcquireCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ } ++ ++ break; ++ case P2P_STATE_CHNL_ON_HAND: ++ if (fgIsTransOut) { ++ p2pStateAbort_CHNL_ON_HAND(prAdapter, prP2pFsmInfo, prP2pBssInfo, eNextState); ++ } else { ++ /* Initial channel ready. */ ++ /* Send channel ready event. */ ++ /* Start a FSM timer. */ ++ p2pStateInit_CHNL_ON_HAND(prAdapter, prP2pBssInfo, prP2pFsmInfo); ++ } ++ ++ break; ++ case P2P_STATE_GC_JOIN: ++ if (fgIsTransOut) { ++ /* Join complete / join canceled. */ ++ p2pStateAbort_GC_JOIN(prAdapter, prP2pFsmInfo, &(prP2pFsmInfo->rJoinInfo), eNextState); ++ } else { ++ if (prP2pFsmInfo->prTargetBss == NULL) { ++ ASSERT(FALSE); ++ } else { ++ /* Send request to SAA module. */ ++ p2pStateInit_GC_JOIN(prAdapter, ++ prP2pFsmInfo, ++ prP2pBssInfo, ++ &(prP2pFsmInfo->rJoinInfo), prP2pFsmInfo->prTargetBss); ++ } ++ } ++ ++ break; ++ default: ++ break; ++ } ++ ++ } while (fgIsTransOut); ++ ++} /* p2pFsmStateTransition */ ++ ++VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchOpMode = (P_MSG_P2P_SWITCH_OP_MODE_T) prMsgHdr; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwitchOpMode != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventSwitchOPMode\n"); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prSwitchOpMode->eOpMode >= OP_MODE_NUM) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ /* P2P Device / GC. */ ++ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, prSwitchOpMode->eOpMode, TRUE); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventSwitchOPMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle scan done event during Device Discovery. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) NULL; ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ /* This scan done event is either for "SCAN" phase or "SEARCH" state or "LISTEN" state. ++ * The scan done for SCAN phase & SEARCH state doesn't imply Device ++ * Discovery over. ++ */ ++ DBGLOG(P2P, TRACE, "P2P Scan Done Event\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ ++ if (prScanDoneMsg->ucSeqNum != prScanReqInfo->ucSeqNumOfScnMsg) { ++ /* Scan Done message sequence number mismatch. ++ * Ignore this event. (P2P FSM issue two scan events.) ++ */ ++ /* The scan request has been cancelled. ++ * Ignore this message. It is possible. ++ */ ++ DBGLOG(P2P, TRACE, "P2P Scan Don SeqNum:%d <-> P2P Fsm SCAN Msg:%d\n", ++ prScanDoneMsg->ucSeqNum, prScanReqInfo->ucSeqNumOfScnMsg); ++ ++ break; ++ } ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_SCAN: ++ { ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ ++ prScanReqInfo->fgIsAbort = FALSE; ++ ++ if (prConnReqInfo->fgIsConnRequest) { ++ prP2pFsmInfo->prTargetBss = p2pFuncKeepOnConnection(prAdapter, ++ &prP2pFsmInfo->rConnReqInfo, ++ &prP2pFsmInfo->rChnlReqInfo, ++ &prP2pFsmInfo->rScanReqInfo); ++ if (prP2pFsmInfo->prTargetBss == NULL) ++ eNextState = P2P_STATE_SCAN; ++ else ++ eNextState = P2P_STATE_REQING_CHANNEL; ++ } else { ++ eNextState = P2P_STATE_IDLE; ++ } ++ ++ } ++ break; ++ case P2P_STATE_AP_CHANNEL_DETECT: ++ eNextState = P2P_STATE_REQING_CHANNEL; ++ break; ++ default: ++ /* Unexpected channel scan done event without being chanceled. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prScanReqInfo->fgIsScanRequest = FALSE; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventScanDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is call when channel is granted by CNM module from FW. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_MSG_CH_GRANT_T prMsgChGrant = (P_MSG_CH_GRANT_T) NULL; ++ UINT_8 ucTokenID = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "P2P Run Event Channel Grant\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; ++ ucTokenID = prMsgChGrant->ucTokenID; ++ prP2pFsmInfo->u4GrantInterval = prMsgChGrant->u4GrantInterval; ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ if (ucTokenID == prChnlReqInfo->ucSeqNumOfChReq) { ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_REQING_CHANNEL: ++ switch (prChnlReqInfo->eChannelReqType) { ++ case CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL: ++ eNextState = P2P_STATE_CHNL_ON_HAND; ++ break; ++ case CHANNEL_REQ_TYPE_GC_JOIN_REQ: ++ eNextState = P2P_STATE_GC_JOIN; ++ break; ++ case CHANNEL_REQ_TYPE_GO_START_BSS: ++ eNextState = P2P_STATE_IDLE; ++ break; ++ default: ++ break; ++ } ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); ++ break; ++ default: ++ /* Channel is granted under unexpected state. ++ * Driver should cancel channel privileagea before leaving the states. ++ */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } else { ++ /* Channel requsted, but released. */ ++ /* ASSERT(!prChnlReqInfo->fgIsChannelRequested); */ ++ DBGLOG(P2P, TRACE, "Channel requsted, but released\n"); ++ } ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventChGrant */ ++ ++VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_MSG_P2P_CHNL_REQUEST_T prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) prMsgHdr; ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelRequest\n"); ++ ++ /* Special case of time renewing for same frequency. */ ++ if ((prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) && ++ (prChnlReqInfo->ucReqChnlNum == prP2pChnlReqMsg->rChannelInfo.ucChannelNum) && ++ (prChnlReqInfo->eBand == prP2pChnlReqMsg->rChannelInfo.eBand) && ++ (prChnlReqInfo->eChnlSco == prP2pChnlReqMsg->eChnlSco)) { ++ ++ ASSERT(prChnlReqInfo->fgIsChannelRequested == TRUE); ++ ASSERT(prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL); ++ ++ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; ++ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; ++ ++ /* Re-enter the state. */ ++ eNextState = P2P_STATE_CHNL_ON_HAND; ++ } else { ++ ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ /* Cookie can only be assign after abort.(for indication) */ ++ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; ++ prChnlReqInfo->ucReqChnlNum = prP2pChnlReqMsg->rChannelInfo.ucChannelNum; ++ prChnlReqInfo->eBand = prP2pChnlReqMsg->rChannelInfo.eBand; ++ prChnlReqInfo->eChnlSco = prP2pChnlReqMsg->eChnlSco; ++ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL; ++ ++ eNextState = P2P_STATE_REQING_CHANNEL; ++ } ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventChannelRequest */ ++ ++VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_MSG_P2P_CHNL_ABORT_T prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) NULL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) prMsgHdr; ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelAbort\n"); ++ ++ if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) && (prChnlReqInfo->fgIsChannelRequested)) { ++ ++ ASSERT((prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL || ++ (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND))); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventChannelAbort */ ++ ++VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_MSG_P2P_SCAN_REQUEST_T prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) NULL; ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ UINT_32 u4ChnlListSize = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) prMsgHdr; ++ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanRequest\n"); ++ ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ ASSERT(prScanReqInfo->fgIsScanRequest == FALSE); ++ ++ prScanReqInfo->fgIsAbort = TRUE; ++ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; ++ ++ /* Channel List */ ++ prScanReqInfo->ucNumChannelList = prP2pScanReqMsg->u4NumChannel; ++ DBGLOG(P2P, TRACE, "Scan Request Channel List Number: %d\n", prScanReqInfo->ucNumChannelList); ++ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) { ++ DBGLOG(P2P, TRACE, "Channel List Number Overloaded: %d, change to: %d\n", ++ prScanReqInfo->ucNumChannelList, MAXIMUM_OPERATION_CHANNEL_LIST); ++ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; ++ } ++ ++ u4ChnlListSize = sizeof(RF_CHANNEL_INFO_T) * prScanReqInfo->ucNumChannelList; ++ kalMemCopy(prScanReqInfo->arScanChannelList, prP2pScanReqMsg->arChannelListInfo, u4ChnlListSize); ++ ++ /* TODO: I only take the first SSID. Multiple SSID may be needed in the future. */ ++ /* SSID */ ++ if (prP2pScanReqMsg->i4SsidNum >= 1) ++ kalMemCopy(&(prScanReqInfo->rSsidStruct), prP2pScanReqMsg->prSSID, sizeof(P2P_SSID_STRUCT_T)); ++ else ++ prScanReqInfo->rSsidStruct.ucSsidLen = 0; ++ ++ /* IE Buffer */ ++ kalMemCopy(prScanReqInfo->aucIEBuf, prP2pScanReqMsg->pucIEBuf, prP2pScanReqMsg->u4IELen); ++ ++ prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventScanRequest */ ++ ++VOID p2pFsmRunEventScanAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanAbort\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ prScanReqInfo->fgIsAbort = TRUE; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventScanAbort */ ++ ++VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventAbort\n"); ++ ++ if (prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { ++ ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { ++ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ prScanReqInfo->fgIsAbort = TRUE; ++ } else if (prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL) { ++ /* 2012/08/06: frog ++ * Prevent Start GO. ++ */ ++ prP2pBssInfo->eIntendOPMode = OP_MODE_NUM; ++ } ++ /* For other state, is there any special action that should be take before leaving? */ ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } else { ++ /* P2P State IDLE. */ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ if (prChnlReqInfo->fgIsChannelRequested) ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFsmRunEventAbort */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle FSM Timeout. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) ulParam; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ DBGLOG(P2P, TRACE, "P2P FSM Timeout Event\n"); ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_IDLE: ++ { ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ if (prChnlReqInfo->fgIsChannelRequested) { ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ } else if (IS_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } ++ break; ++ ++/* case P2P_STATE_SCAN: */ ++/* break; */ ++/* case P2P_STATE_AP_CHANNEL_DETECT: */ ++/* break; */ ++/* case P2P_STATE_REQING_CHANNEL: */ ++/* break; */ ++ case P2P_STATE_CHNL_ON_HAND: ++ switch (prP2pFsmInfo->eListenExted) { ++ case P2P_DEV_NOT_EXT_LISTEN: ++ case P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT: ++ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", ++ prP2pFsmInfo->eListenExted); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; ++ break; ++ case P2P_DEV_EXT_LISTEN_ING: ++ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", ++ prP2pFsmInfo->eListenExted); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_CHNL_ON_HAND); ++ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT; ++ break; ++ default: ++ ASSERT(FALSE); ++ DBGLOG(P2P, ERROR, ++ "Current P2P State %d is unexpected for FSM timeout event.\n", ++ prP2pFsmInfo->eCurrentState); ++ } ++ break; ++/* case P2P_STATE_GC_JOIN: */ ++/* break; */ ++ default: ++ break; ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFsmRunEventFsmTimeout */ ++ ++VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_MSG_P2P_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventMgmtFrameTx\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) prMsgHdr; ++ ++ p2pFuncTxMgmtFrame(prAdapter, ++ &prP2pFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventMgmtTx */ ++ ++VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventStartAP\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) prMsgHdr; ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (prP2pStartAPMsg->u4BcnInterval) { ++ DBGLOG(P2P, TRACE, "Beacon interval updated to :%u\n", prP2pStartAPMsg->u4BcnInterval); ++ prP2pBssInfo->u2BeaconInterval = (UINT_16) prP2pStartAPMsg->u4BcnInterval; ++ } else if (prP2pBssInfo->u2BeaconInterval == 0) { ++ prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT; ++ } ++ ++ if (prP2pStartAPMsg->u4DtimPeriod) { ++ DBGLOG(P2P, TRACE, "DTIM interval updated to :%u\n", prP2pStartAPMsg->u4DtimPeriod); ++ prP2pBssInfo->ucDTIMPeriod = (UINT_8) prP2pStartAPMsg->u4DtimPeriod; ++ } else if (prP2pBssInfo->ucDTIMPeriod == 0) { ++ prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; ++ } ++ ++ if (prP2pStartAPMsg->u2SsidLen != 0) { ++ kalMemCopy(prP2pBssInfo->aucSSID, prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen); ++ kalMemCopy(prP2pSpecificBssInfo->aucGroupSsid, prP2pStartAPMsg->aucSsid, ++ prP2pStartAPMsg->u2SsidLen); ++ prP2pBssInfo->ucSSIDLen = prP2pSpecificBssInfo->u2GroupSsidLen = prP2pStartAPMsg->u2SsidLen; ++ } ++ ++ prP2pBssInfo->eHiddenSsidType = prP2pStartAPMsg->ucHiddenSsidType; ++ ++ /* TODO: JB */ ++ /* Privacy & inactive timeout. */ ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { ++ UINT_8 ucPreferedChnl = 0; ++ ENUM_BAND_T eBand = BAND_NULL; ++ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_SCAN; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prP2pFsmInfo->eCurrentState != P2P_STATE_SCAN && ++ prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ } ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; ++ DBGLOG(P2P, INFO, ++ "NFC:p2pFsmRunEventStartAP,fgIsGOInitialDone[%d]\n", ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); ++ ++ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ ++ /* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ /* Leave IDLE state. */ ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* sync with firmware */ ++ /* DBGLOG(P2P, INFO, ("Activate P2P Network.\n")); */ ++ /* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ /* Key to trigger P2P FSM to allocate channel for AP mode. */ ++ prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT; ++ ++ /* Sparse Channel to decide which channel to use. */ ++ if ((cnmPreferredChannel(prAdapter, ++ &eBand, ++ &ucPreferedChnl, ++ &eSco) == FALSE) && (prP2pConnSettings->ucOperatingChnl == 0)) { ++ /* Sparse Channel Detection using passive mode. */ ++ eNextState = P2P_STATE_AP_CHANNEL_DETECT; ++ } else { ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = ++ prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++#if 1 ++ /* 2012-01-27: frog - Channel set from upper layer is the first priority. */ ++ /* Because the channel & beacon is decided by p2p_supplicant. */ ++ if (prP2pConnSettings->ucOperatingChnl != 0) { ++ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; ++ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; ++ } ++ ++ else { ++ ASSERT(ucPreferedChnl != 0); ++ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; ++ prP2pSpecificBssInfo->eRfBand = eBand; ++ } ++#else ++ if (ucPreferedChnl) { ++ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; ++ prP2pSpecificBssInfo->eRfBand = eBand; ++ } else { ++ ASSERT(prP2pConnSettings->ucOperatingChnl != 0); ++ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; ++ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; ++ } ++ ++#endif ++ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel; ++ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; ++ ++ DBGLOG(P2P, INFO, "p2pFsmRunEventStartAP GO Scan\n"); ++ } ++ ++ /* If channel is specified, use active scan to shorten the scan time. */ ++ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, eNextState); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventStartAP */ ++ ++VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_P2P_NETDEV_REGISTER_T prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) NULL; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventNetDeviceRegister\n"); ++ ++ prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) prMsgHdr; ++ ++ if (prNetDevRegisterMsg->fgIsEnable) { ++ p2pSetMode((prNetDevRegisterMsg->ucMode == 1) ? TRUE : FALSE); ++ ++ if (p2pLaunch(prAdapter->prGlueInfo)) ++ ASSERT(prAdapter->fgIsP2PRegistered); ++ ++ } else { ++ if (prAdapter->fgIsP2PRegistered) ++ p2pRemove(prAdapter->prGlueInfo); ++ ++ } ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventNetDeviceRegister */ ++ ++VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_P2P_MGMT_FRAME_UPDATE_T prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventUpdateMgmtFrame\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) prMsgHdr; ++ ++ switch (prP2pMgmtFrameUpdateMsg->eBufferType) { ++ case ENUM_FRAME_TYPE_EXTRA_IE_BEACON: ++ break; ++ case ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP: ++ break; ++ case ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP: ++ break; ++ case ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE: ++ break; ++ case ENUM_FRAME_TYPE_BEACON_TEMPLATE: ++ break; ++ default: ++ break; ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventUpdateMgmtFrame */ ++ ++VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_BEACON_UPDATE_T prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconUpdate\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) prMsgHdr; ++ ++ p2pFuncBeaconUpdate(prAdapter, ++ prP2pBssInfo, ++ &prP2pFsmInfo->rBcnContentInfo, ++ prBcnUpdateMsg->pucBcnHdr, ++ prBcnUpdateMsg->u4BcnHdrLen, ++ prBcnUpdateMsg->pucBcnBody, prBcnUpdateMsg->u4BcnBodyLen); ++ ++ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && ++ (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { ++ /* AP is created, Beacon Update. */ ++ /* nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventBeaconUpdate */ ++ ++VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventStopAP\n"); ++ ++ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ && (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { ++ /* AP is created, Beacon Update. */ ++ ++ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); ++ ++ DBGLOG(P2P, TRACE, "Stop Beaconing\n"); ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Reset RLM related field of BSSINFO. */ ++ rlmBssAborted(prAdapter, prP2pBssInfo); ++ } ++ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ ++ /* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ /* Enter IDLE state. */ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ DBGLOG(P2P, INFO, "Re activate P2P Network.\n"); ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++#if CFG_SUPPORT_WFD ++ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); ++#endif ++ ++ /* p2pFsmRunEventAbort(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo); */ ++ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventStopAP */ ++ ++VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) prMsgHdr; ++ ++ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionRequest\n"); ++ ++ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ break; ++ ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ /* Update connection request information. */ ++ prConnReqInfo->fgIsConnRequest = TRUE; ++ COPY_MAC_ADDR(prConnReqInfo->aucBssid, prConnReqMsg->aucBssid); ++ kalMemCopy(&(prConnReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); ++ kalMemCopy(prConnReqInfo->aucIEBuf, prConnReqMsg->aucIEBuf, prConnReqMsg->u4IELen); ++ prConnReqInfo->u4BufLength = prConnReqMsg->u4IELen; ++ ++ /* Find BSS Descriptor first. */ ++ prP2pFsmInfo->prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); ++ ++ if (prP2pFsmInfo->prTargetBss == NULL) { ++ /* Update scan parameter... to scan target device. */ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest,Trigger New Scan\n"); ++ ++ prScanReqInfo->ucNumChannelList = 1; ++ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; ++ prScanReqInfo->arScanChannelList[0].ucChannelNum = prConnReqMsg->rChannelInfo.ucChannelNum; ++ kalMemCopy(&(prScanReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); ++ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ ++ prScanReqInfo->fgIsAbort = TRUE; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); ++ } else { ++ prChnlReqInfo->u8Cookie = 0; ++ prChnlReqInfo->ucReqChnlNum = prConnReqMsg->rChannelInfo.ucChannelNum; ++ prChnlReqInfo->eBand = prConnReqMsg->rChannelInfo.eBand; ++ prChnlReqInfo->eChnlSco = prConnReqMsg->eChnlSco; ++ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; ++ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest, Report the Connecting BSS Again.\n"); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_REQING_CHANNEL); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventConnectionRequest */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle Connection Request from Supplicant. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ /* P_STA_RECORD_T prTargetStaRec = (P_STA_RECORD_T)NULL; */ ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionAbort: Connection Abort.\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) prMsgHdr; ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ { ++ UINT_8 aucBCBSSID[] = BC_BSSID; ++ ++ if (!prP2pBssInfo->prStaRecOfAP) { ++ DBGLOG(P2P, TRACE, "GO's StaRec is NULL\n"); ++ break; ++ } ++ if (UNEQUAL_MAC_ADDR(prP2pBssInfo->prStaRecOfAP->aucMacAddr, prDisconnMsg->aucTargetID) ++ && UNEQUAL_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCBSSID)) { ++ DBGLOG(P2P, TRACE, ++ "Unequal MAC ADDR [ %pM : %pM ]\n", ++ prP2pBssInfo->prStaRecOfAP->aucMacAddr, ++ prDisconnMsg->aucTargetID); ++ break; ++ } ++ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, NULL, 0, 0, ++ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); ++ ++ /* Stop rejoin timer if it is started. */ ++ /* TODO: If it has. */ ++ ++ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, prDisconnMsg->fgSendDeauth, ++ prDisconnMsg->u2ReasonCode); ++ ++ /* prTargetStaRec = prP2pBssInfo->prStaRecOfAP; */ ++ ++ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). */ ++ /* hit prStaRecOfAP == NULL. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } ++ break; ++ case OP_MODE_ACCESS_POINT: ++ { ++ P_LINK_T prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ /* Search specific client device, and disconnect. */ ++ /* 1. Send deauthentication frame. */ ++ /* 2. Indication: Device disconnect. */ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; ++ ++ DBGLOG(P2P, TRACE, ++ "Disconnecting with Target ID: %pM\n", ++ prDisconnMsg->aucTargetID); ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); ++ ++ ASSERT(prCurrStaRec); ++ ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prDisconnMsg->aucTargetID)) { ++ ++ DBGLOG(P2P, TRACE, ++ "Disconnecting: %pM\n", ++ prCurrStaRec->aucMacAddr); ++ ++ /* Remove STA from client list. */ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, ++ &prCurrStaRec->rLinkEntry); ++ ++ /* Glue layer indication. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ ++ ++ /* Send deauth & do indication. */ ++ p2pFuncDisconnect(prAdapter, prCurrStaRec, prDisconnMsg->fgSendDeauth, ++ prDisconnMsg->u2ReasonCode); ++ ++ /* prTargetStaRec = prCurrStaRec; */ ++ ++ break; ++ } ++ } ++ ++ } ++ break; ++ case OP_MODE_P2P_DEVICE: ++ default: ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } while (FALSE); ++ ++ /* 20120830 moved into p2pFuncDisconnect() */ ++ /* if ((!prDisconnMsg->fgSendDeauth) && (prTargetStaRec)) { */ ++ /* cnmStaRecFree(prAdapter, prTargetStaRec, TRUE); */ ++ /* } */ ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventConnectionAbort */ ++ ++VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ++ /* TODO: */ ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventDissolve\n"); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++WLAN_STATUS ++p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ DBGLOG(P2P, INFO, "Deauth TX Done Status: %d, seqNo %d\n", ++ rTxDoneStatus, prMsduInfo->ucTxSeqNum); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (prStaRec == NULL) { ++ DBGLOG(P2P, TRACE, "Station Record NULL, Index:%d\n", prMsduInfo->ucStaRecIndex); ++ break; ++ } ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ eOriMediaStatus = prP2pBssInfo->eConnectionState; ++ /* Change station state. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* Reset Station Record Status. */ ++ p2pFuncResetStaRecStatus(prAdapter, prStaRec); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ ++ /**/ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { ++ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ } ++ ++ /* Because the eConnectionState is changed before Deauth TxDone. Dont Check eConnectionState */ ++ /* if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { */ ++ /* Update Disconnected state to FW. */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ /* } */ ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* p2pFsmRunEventDeauthTxDone */ ++ ++WLAN_STATUS ++p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_P2P_MGMT_TX_REQ_INFO_T) NULL; ++ BOOLEAN fgIsSuccess = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prMgmtTxReqInfo = &(prP2pFsmInfo->rMgmtTxInfo); ++ ++ if (rTxDoneStatus != TX_RESULT_SUCCESS) { ++ DBGLOG(P2P, INFO, "Mgmt Frame TX Fail, Status: %d, seq NO. %d, Cookie: 0x%llx\n", ++ rTxDoneStatus, prMsduInfo->ucTxSeqNum, prMgmtTxReqInfo->u8Cookie); ++ } else { ++ fgIsSuccess = TRUE; ++ DBGLOG(P2P, TRACE, "Mgmt Frame TX Done.\n"); ++ } ++ ++ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { ++ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ fgIsSuccess, ++ prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); ++ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ } ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* p2pFsmRunEventMgmtFrameTxDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called when JOIN complete message event is received from SAA. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; ++ P_MSG_JOIN_COMP_T prJoinCompMsg = (P_MSG_JOIN_COMP_T) NULL; ++ P_SW_RFB_T prAssocRspSwRfb = (P_SW_RFB_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ DBGLOG(P2P, TRACE, "P2P Join Complete\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ if (prP2pFsmInfo == NULL) { ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); ++ if (prMsgHdr == NULL) ++ return; ++ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; ++ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ prStaRec = prJoinCompMsg->prStaRec; ++ ++ /* Check SEQ NUM */ ++ if (prJoinCompMsg->ucSeqNum == prJoinInfo->ucSeqNumOfReqMsg) { ++ ASSERT(prStaRec == prJoinInfo->prTargetStaRec); ++ prJoinInfo->fgIsJoinComplete = TRUE; ++ ++ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if ((prP2pBssInfo->prStaRecOfAP) && (prP2pBssInfo->prStaRecOfAP != prStaRec)) { ++ cnmStaRecChangeState(prAdapter, prP2pBssInfo->prStaRecOfAP, ++ STA_STATE_1); ++ ++ cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ } ++ /* 4 <1.3> Update BSS_INFO_T */ ++ p2pFuncUpdateBssInfoForJOIN(prAdapter, prP2pFsmInfo->prTargetBss, prStaRec, ++ prAssocRspSwRfb); ++ ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ DBGLOG(P2P, INFO, "P2P GC Join Success\n"); ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ /* <1.5> Update RSSI if necessary */ ++ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, ++ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); ++#endif ++ ++ /* 4 <1.6> Indicate Connected Event to Host immediately. */ ++ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ ++ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, */ ++ /* prStaRec->aucMacAddr); */ ++ if (prP2pFsmInfo->prTargetBss) ++ scanReportBss2Cfg80211(prAdapter, OP_MODE_P2P_DEVICE, ++ prP2pFsmInfo->prTargetBss); ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ &prP2pFsmInfo->rConnReqInfo, ++ prJoinInfo->aucIEBuf, prJoinInfo->u4BufLength, ++ prStaRec->u2StatusCode, ++ WLAN_STATUS_MEDIA_CONNECT); ++ ++ } else { ++ /* Join Fail */ ++ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ ++ if (p2pFuncRetryJOIN(prAdapter, prStaRec, prJoinInfo) == FALSE) { ++ P_BSS_DESC_T prBssDesc; ++ ++ /* Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ prBssDesc = prP2pFsmInfo->prTargetBss; ++ ++ ASSERT(prBssDesc); ++ ASSERT(prBssDesc->fgIsConnecting); ++ ++ prBssDesc->fgIsConnecting = FALSE; ++ ++ if (prStaRec->ucJoinFailureCount >= 3) { ++ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ &prP2pFsmInfo->rConnReqInfo, ++ prJoinInfo->aucIEBuf, ++ prJoinInfo->u4BufLength, ++ prStaRec->u2StatusCode, ++ WLAN_STATUS_MEDIA_CONNECT); ++ } else { ++ /* Sometime the GO is not ready to response auth. */ ++ /* Connect it again */ ++ prP2pFsmInfo->prTargetBss = NULL; ++ } ++ DBGLOG(P2P, INFO, "P2P GC Join Failed\n"); ++ ++ } ++ ++ } ++ } ++ } ++ ++ if (prAssocRspSwRfb) ++ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); ++ ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_GC_JOIN) { ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == ++ PARAM_MEDIA_STATE_CONNECTED) { ++ /* Return to IDLE state. */ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } else { ++ /* p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); */ ++ /* one more scan */ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); ++ } ++ } ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventJoinComplete */ ++ ++VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) prMsgHdr; ++ ++ p2pFuncMgmtFrameRegister(prAdapter, ++ prMgmtFrameRegister->u2FrameType, ++ prMgmtFrameRegister->fgIsRegister, &prP2pFsmInfo->u4P2pPacketFilter); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventMgmtFrameRegister */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is call when RX deauthentication frame from the AIR. ++* If we are under STA mode, we would go back to P2P Device. ++* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ UINT_16 u2ReasonCode = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ if (prStaRec == NULL) ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ if (!prStaRec) ++ break; ++ ++ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ break; ++ ++ DBGLOG(P2P, TRACE, "RX Deauth\n"); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ if (authProcessRxDeauthFrame(prSwRfb, ++ prStaRec->aucMacAddr, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; ++ UINT_16 u2IELength = 0; ++ ++ if (prP2pBssInfo->prStaRecOfAP != prStaRec) ++ break; ++ ++ prStaRec->u2ReasonCode = u2ReasonCode; ++ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); ++ ++ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); ++ ++ /* Indicate disconnect to Host. */ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, ++ prDeauthFrame->aucInfoElem, u2IELength, u2ReasonCode, ++ WLAN_STATUS_MEDIA_DISCONNECT); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ DBGLOG(P2P, INFO, "GC RX Deauth Reason: %d\n", u2ReasonCode); ++ ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } ++ break; ++ case OP_MODE_ACCESS_POINT: ++ /* Delete client from client list. */ ++ if (authProcessRxDeauthFrame(prSwRfb, ++ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; ++ ++ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); ++ ++ ASSERT(prCurrStaRec); ++ ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { ++ ++ /* Remove STA from client list. */ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, ++ &prCurrStaRec->rLinkEntry); ++ ++ /* Indicate to Host. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ ++ ++ /* Indicate disconnect to Host. */ ++ DBGLOG(P2P, INFO, "GO RX Deauth Reason: %d\n", u2ReasonCode); ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); ++ ++ break; ++ } ++ } ++ } ++ break; ++ case OP_MODE_P2P_DEVICE: ++ default: ++ /* Findout why someone sent deauthentication frame to us. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "Deauth Reason:%d\n", u2ReasonCode); ++ ++ } while (FALSE); ++} /* p2pFsmRunEventRxDeauthentication */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is call when RX deauthentication frame from the AIR. ++* If we are under STA mode, we would go back to P2P Device. ++* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ UINT_16 u2ReasonCode = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ if (prStaRec == NULL) { ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if (prStaRec == NULL) ++ break; ++ } ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ break; ++ ++ DBGLOG(P2P, TRACE, "RX Disassoc\n"); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ if (assocProcessRxDisassocFrame(prAdapter, ++ prSwRfb, ++ prStaRec->aucMacAddr, ++ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; ++ UINT_16 u2IELength = 0; ++ ++ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); ++ ++ if (prP2pBssInfo->prStaRecOfAP != prStaRec) ++ break; ++ ++ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); ++ ++ /* Indicate disconnect to Host. */ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, ++ prDisassocFrame->aucInfoElem, ++ u2IELength, prStaRec->u2ReasonCode, ++ WLAN_STATUS_MEDIA_DISCONNECT); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ DBGLOG(P2P, INFO, "GC RX Disassoc Reason %d\n", prStaRec->u2ReasonCode); ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, prStaRec->u2ReasonCode); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } ++ break; ++ case OP_MODE_ACCESS_POINT: ++ /* Delete client from client list. */ ++ if (assocProcessRxDisassocFrame(prAdapter, ++ prSwRfb, ++ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; ++ ++ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); ++ ++ ASSERT(prCurrStaRec); ++ ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { ++ ++ /* Remove STA from client list. */ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, ++ &prCurrStaRec->rLinkEntry); ++ ++ /* Indicate to Host. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ ++ ++ /* Indicate disconnect to Host. */ ++ DBGLOG(P2P, INFO, "GO RX Disassoc Reason %d\n", u2ReasonCode); ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); ++ ++ break; ++ } ++ } ++ } ++ break; ++ case OP_MODE_P2P_DEVICE: ++ default: ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } while (FALSE); ++} /* p2pFsmRunEventRxDisassociation */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called when a probe request frame is received. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return boolean value if probe response frame is accepted & need cancel scan request. ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (prBssDesc != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ /* There is a connection request. */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ } while (FALSE); ++ ++} /* p2pFsmRunEventRxProbeResponseFrame */ ++ ++VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconTimeout: Beacon Timeout\n"); ++ ++ /* Only client mode would have beacon lost event. */ ++ ASSERT(prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE); ++ ++ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* Indicate disconnect to Host. */ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, NULL, 0, REASON_CODE_DISASSOC_INACTIVITY, ++ WLAN_STATUS_MEDIA_DISCONNECT); ++ ++ if (prP2pBssInfo->prStaRecOfAP != NULL) { ++ P_STA_RECORD_T prStaRec = prP2pBssInfo->prStaRecOfAP; ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_DISASSOC_LEAVING_BSS); ++ ++ /* 20120830 moved into p2pFuncDisconnect() */ ++ /* cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } ++ } ++ } while (FALSE); ++ ++} /* p2pFsmRunEventBeaconTimeout */ ++ ++VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = NULL; ++ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prExtListenMsg = NULL; ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prExtListenMsg = (struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *) prMsgHdr; ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ASSERT_BREAK(prP2pFsmInfo); ++ ++ if (!prExtListenMsg->wait) { ++ DBGLOG(P2P, INFO, "reset listen interval\n"); ++ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ if (prP2pFsmInfo && (prP2pFsmInfo->eListenExted == P2P_DEV_NOT_EXT_LISTEN)) { ++ DBGLOG(P2P, INFO, "try to ext listen, p2p state: %d\n", prP2pFsmInfo->eCurrentState); ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) { ++ DBGLOG(P2P, INFO, "here to ext listen interval\n"); ++ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_ING; ++ } ++ } ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++} /* p2pFsmRunEventUpdateMgmtFrame */ ++ ++#if CFG_SUPPORT_WFD ++VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; ++ WLAN_STATUS rStatus; ++ ++ DBGLOG(P2P, INFO, "p2pFsmRunEventWfdSettingUpdate\n"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL)); ++ ++ if (prMsgHdr != NULL) { ++ prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) prMsgHdr; ++ prWfdCfgSettings = prMsgWfdCfgSettings->prWfdCfgSettings; ++ } else { ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ } ++ ++ DBGLOG(P2P, INFO, "WFD Enalbe %x info %x state %x flag %x adv %x\n", ++ prWfdCfgSettings->ucWfdEnable, ++ prWfdCfgSettings->u2WfdDevInfo, ++ (UINT_32) prWfdCfgSettings->u4WfdState, ++ (UINT_32) prWfdCfgSettings->u4WfdFlag, ++ (UINT_32) prWfdCfgSettings->u4WfdAdvancedFlag); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_WFD_CTRL, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(WFD_CFG_SETTINGS_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prWfdCfgSettings, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ } while (FALSE); ++ ++ return; ++ ++} ++ ++/* p2pFsmRunEventWfdSettingUpdate */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Beacon frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (prStaRec != NULL) { ++ if (IS_STA_P2P_TYPE(prStaRec)) { ++ /* Do nothing */ ++ /* TODO: */ ++ } ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* end of p2pGenerateP2P_IEForAssocReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Probe Request frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ ASSERT(prAdapter); ++ ASSERT(pucBuf); ++ ++ /* TODO: */ ++ ++ return; ++ ++} /* end of p2pGenerateP2P_IEForProbReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to calculate P2P IE length for Beacon frame. ++* ++* @param[in] eNetTypeIndex Specify which network ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return The length of P2P IE added ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ++p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ /* TODO: */ ++ ++ return 0; ++ ++} /* end of p2pCalculateP2P_IELenForProbeReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Tx Fail of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); ++ ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_UNSPECIFIED); ++ ++ /* 20120830 moved into p2puUncDisconnect. */ ++ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ ++ ++} /* p2pRunEventAAATxFail */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Successful Completion of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ENUM_PARAM_MEDIA_STATE_T eOriMediaState; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ eOriMediaState = prP2pBssInfo->eConnectionState; ++ ++ if (prStaRec != NULL) ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ else ++ break; ++ ++ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || ++ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { ++ rStatus = WLAN_STATUS_RESOURCES; ++ break; ++ } ++ ++ bssAddStaRecToClientList(prAdapter, prP2pBssInfo, prStaRec); ++ ++ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); ++ ++ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || ++ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { ++ rStatus = WLAN_STATUS_RESOURCES; ++ break; ++ } ++ DBGLOG(P2P, INFO, "P2P GO Join Complete\n"); ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* Update Connected state to FW. */ ++ if (eOriMediaState != prP2pBssInfo->eConnectionState) ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ } while (FALSE); ++ ++ return rStatus; ++} /* p2pRunEventAAAComplete */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Successful Completion of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ /* Glue layer indication. */ ++ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, TRUE); ++ ++ } while (FALSE); ++ ++ return rStatus; ++} /* p2pRunEventAAASuccess */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_P2P_PUBLIC_ACTION_FRAME_T prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prAdapter); ++ ++ prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) prSwRfb->pvHeader; ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ DBGLOG(P2P, TRACE, "RX Public Action Frame Token:%d.\n", prPublicActionFrame->ucDialogToken); ++ ++ if (prPublicActionFrame->ucCategory != CATEGORY_PUBLIC_ACTION) ++ return rWlanStatus; ++ ++ switch (prPublicActionFrame->ucAction) { ++ case ACTION_PUBLIC_WIFI_DIRECT: ++ break; ++ case ACTION_GAS_INITIAL_REQUEST: ++ case ACTION_GAS_INITIAL_RESPONSE: ++ case ACTION_GAS_COMEBACK_REQUEST: ++ case ACTION_GAS_COMEBACK_RESPONSE: ++ break; ++ default: ++ break; ++ } ++ ++ return rWlanStatus; ++} /* p2pRxPublicActionFrame */ ++ ++WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_P2P_ACTION_FRAME_T prP2pActionFrame = (P_P2P_ACTION_FRAME_T) NULL; ++ UINT_8 aucOui[3] = VENDOR_OUI_WFA_SPECIFIC; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prP2pActionFrame = (P_P2P_ACTION_FRAME_T) prSwRfb->pvHeader; ++ ++ if (prP2pActionFrame->ucCategory != CATEGORY_VENDOR_SPECIFIC_ACTION) { ++ DBGLOG(P2P, TRACE, "RX Action Frame but not vendor specific.\n"); ++ break; ++ } ++ ++ if ((prP2pActionFrame->ucOuiType != VENDOR_OUI_TYPE_P2P) || ++ (prP2pActionFrame->aucOui[0] != aucOui[0]) || ++ (prP2pActionFrame->aucOui[1] != aucOui[1]) || (prP2pActionFrame->aucOui[2] != aucOui[2])) { ++ DBGLOG(P2P, TRACE, "RX Vendor Specific Action Frame but not P2P Type or not WFA OUI.\n"); ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pRxActionFrame */ ++ ++VOID ++p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam) ++{ ++ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ UINT_32 i; ++ BOOLEAN fgNoaAttrExisted = FALSE; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIndex]); ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ prP2pSpecificBssInfo->fgEnableOppPS = prEventUpdateNoaParam->fgEnableOppPS; ++ prP2pSpecificBssInfo->u2CTWindow = prEventUpdateNoaParam->u2CTWindow; ++ prP2pSpecificBssInfo->ucNoAIndex = prEventUpdateNoaParam->ucNoAIndex; ++ prP2pSpecificBssInfo->ucNoATimingCount = prEventUpdateNoaParam->ucNoATimingCount; ++ ++ fgNoaAttrExisted |= prP2pSpecificBssInfo->fgEnableOppPS; ++ ++ DBGLOG(P2P, INFO, "Update NoA Count=%d.\n", prEventUpdateNoaParam->ucNoATimingCount); ++ ++ ASSERT(prP2pSpecificBssInfo->ucNoATimingCount <= P2P_MAXIMUM_NOA_COUNT); ++ ++ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { ++ /* in used */ ++ prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse = prEventUpdateNoaParam->arEventNoaTiming[i].fgIsInUse; ++ /* count */ ++ prP2pSpecificBssInfo->arNoATiming[i].ucCount = prEventUpdateNoaParam->arEventNoaTiming[i].ucCount; ++ /* duration */ ++ prP2pSpecificBssInfo->arNoATiming[i].u4Duration = prEventUpdateNoaParam->arEventNoaTiming[i].u4Duration; ++ /* interval */ ++ prP2pSpecificBssInfo->arNoATiming[i].u4Interval = prEventUpdateNoaParam->arEventNoaTiming[i].u4Interval; ++ /* start time */ ++ prP2pSpecificBssInfo->arNoATiming[i].u4StartTime = ++ prEventUpdateNoaParam->arEventNoaTiming[i].u4StartTime; ++ ++ fgNoaAttrExisted |= prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse; ++ } ++ ++ prP2pSpecificBssInfo->fgIsNoaAttrExisted = fgNoaAttrExisted; ++ ++ /* update beacon content by the change */ ++ bssUpdateBeaconContent(prAdapter, ucNetTypeIndex); ++} ++ ++#endif /* CFG_ENABLE_WIFI_DIRECT */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c +new file mode 100644 +index 000000000000..586a74721b3b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c +@@ -0,0 +1,3796 @@ ++#include "precomp.h" ++#include ++ ++#ifdef __GNUC__ ++#pragma GCC diagnostic ignored "-Wformat" ++#endif ++ ++APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = { ++ {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS), NULL, p2pFuncAppendAttriStatusForAssocRsp} /* 0 */ ++ , {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING), NULL, p2pFuncAppendAttriExtListenTiming} /* 8 */ ++}; ++ ++APPEND_VAR_IE_ENTRY_T txProbeRspIETable[] = { ++ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE} /* 50 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} /* 42 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} /* 45 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} /* 61 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} /* 48 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} /* 74 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} /* 127 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE} /* 221 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Function for requesting scan. There is an option to do ACTIVE or PASSIVE scan. ++* ++* @param eScanType - Specify the scan type of the scan request. It can be an ACTIVE/PASSIVE ++* Scan. ++* eChannelSet - Specify the preferred channel set. ++* A FULL scan would request a legacy full channel normal scan.(usually ACTIVE). ++* A P2P_SOCIAL scan would scan 1+6+11 channels.(usually ACTIVE) ++* A SPECIFIC scan would only 1/6/11 channels scan. (Passive Listen/Specific Search) ++* ucChannelNum - A specific channel number. (Only when channel is specified) ++* eBand - A specific band. (Only when channel is specified) ++* ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) ++{ ++ ++ P_MSG_SCN_SCAN_REQ prScanReq = (P_MSG_SCN_SCAN_REQ) NULL; ++ /*NFC Beam + Indication */ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ BOOLEAN fgIsPureAP = FALSE; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; ++ ++ DEBUGFUNC("p2pFuncRequestScan()"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL)); ++ ++ if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) { ++ ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0); ++ DBGLOG(P2P, LOUD, ++ "P2P Scan Request Channel:%d\n", prScanReqInfo->arScanChannelList[0].ucChannelNum); ++ } ++ ++ prScanReq = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); ++ if (!prScanReq) { ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ break; ++ } ++ ++ prScanReq->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_REQ; ++ prScanReq->ucSeqNum = ++prScanReqInfo->ucSeqNumOfScnMsg; ++ prScanReq->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; ++ prScanReq->eScanType = prScanReqInfo->eScanType; ++ prScanReq->eScanChannel = prScanReqInfo->eChannelSet; ++ prScanReq->u2IELen = 0; ++ ++ /* Copy IE for Probe Request. */ ++ if (prScanReqInfo->u4BufLength > MAX_IE_LENGTH) ++ prScanReqInfo->u4BufLength = MAX_IE_LENGTH; ++ kalMemCopy(prScanReq->aucIE, prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength); ++ prScanReq->u2IELen = (UINT_16) prScanReqInfo->u4BufLength; ++ ++ prScanReq->u2ChannelDwellTime = prScanReqInfo->u2PassiveDewellTime; ++ ++ switch (prScanReqInfo->eChannelSet) { ++ case SCAN_CHANNEL_SPECIFIED: ++ { ++ UINT_32 u4Idx = 0; ++ P_RF_CHANNEL_INFO_T prDomainInfo = ++ (P_RF_CHANNEL_INFO_T) prScanReqInfo->arScanChannelList; ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ ++ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) ++ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; ++ ++ for (u4Idx = 0; u4Idx < prScanReqInfo->ucNumChannelList; u4Idx++) { ++ prScanReq->arChnlInfoList[u4Idx].ucChannelNum = prDomainInfo->ucChannelNum; ++ prScanReq->arChnlInfoList[u4Idx].eBand = prDomainInfo->eBand; ++ prDomainInfo++; ++ } ++ ++ prScanReq->ucChannelListNum = prScanReqInfo->ucNumChannelList; ++ ++ /*NFC Beam + Indication */ ++ prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; ++ if (prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_GO_START_BSS && ++ prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && ++ !fgIsPureAP) { ++ prScanReq->ucChannelListNum = 1; ++ prScanReq->arChnlInfoList[0].ucChannelNum = prChnlReqInfo->ucReqChnlNum; ++ prScanReq->arChnlInfoList[0].eBand = prChnlReqInfo->eBand; ++ ++ DBGLOG(P2P, INFO, ++ "NFC:GO Skip Scan and Only Froce on %s[%d]\n", ++ prChnlReqInfo->eBand == 1 ? "2.4G" : "5G", ++ prChnlReqInfo->ucReqChnlNum); ++ } ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ ++ } ++ break; ++ ++ case SCAN_CHANNEL_FULL: ++ { ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ } ++ break; ++ ++ case SCAN_CHANNEL_2G4: ++ { ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ } ++ break; ++ ++ case SCAN_CHANNEL_P2P_SOCIAL: ++ { ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ } ++ break; ++ default: ++ /* Currently there is no other scan channel set. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReq, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++} /* p2pFuncRequestScan */ ++ ++VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanInfo) ++{ ++ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prScanInfo != NULL)); ++ ++ if (!prScanInfo->fgIsScanRequest) ++ break; ++ ++ if (prScanInfo->ucSeqNumOfScnMsg) { ++ /* There is a channel privilege on hand. */ ++ DBGLOG(P2P, TRACE, "P2P Cancel Scan\n"); ++ ++ prScanCancelMsg = ++ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancelMsg) { ++ /* Buffer not enough, can not cancel scan request. */ ++ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; ++ prScanCancelMsg->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prScanCancelMsg->ucSeqNum = prScanInfo->ucSeqNumOfScnMsg++; ++ prScanCancelMsg->fgIsChannelExt = FALSE; ++ prScanInfo->fgIsScanRequest = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFuncCancelScan */ ++ ++VOID ++p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW) ++{ ++ if (!prAdapter) ++ return; ++ if (!prAdapter->prGlueInfo) ++ return; ++ if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT) ++ return; ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (eOpMode < OP_MODE_NUM)); ++ ++ if (prP2pBssInfo->eCurrentOPMode != eOpMode) { ++ DBGLOG(P2P, TRACE, ++ "p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", prP2pBssInfo->eCurrentOPMode, ++ eOpMode); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_ACCESS_POINT: ++ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); ++ ++ p2pFsmRunEventStopAP(prAdapter, NULL); ++ break; ++ default: ++ break; ++ } ++ ++ prP2pBssInfo->eIntendOPMode = eOpMode; ++ prP2pBssInfo->eCurrentOPMode = eOpMode; ++ switch (eOpMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to Client.\n"); ++ case OP_MODE_ACCESS_POINT: ++/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ ++/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* } */ ++ ++ /* Change interface address. */ ++ if (eOpMode == OP_MODE_ACCESS_POINT) { ++ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to AP.\n"); ++ prP2pBssInfo->ucSSIDLen = 0; ++ } ++ ++ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucInterfaceAddress); ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucInterfaceAddress); ++ ++ break; ++ case OP_MODE_P2P_DEVICE: ++ { ++ /* Change device address. */ ++ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch back to P2P Device.\n"); ++ ++/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ ++/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* } */ ++ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, ++ prAdapter->rWifiVar.aucDeviceAddress); ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); ++ ++ } ++ break; ++ default: ++/* if (IS_BSS_ACTIVE(prP2pBssInfo)) { */ ++/* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++/* nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* } */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ if (1) { ++ P2P_DISCONNECT_INFO rP2PDisInfo; ++ ++ rP2PDisInfo.ucRole = 2; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_P2P_ABORT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(P2P_DISCONNECT_INFO), (PUINT_8)&rP2PDisInfo, NULL, 0); ++ } ++ ++ DBGLOG(P2P, TRACE, ++ "The device address is changed to %pM\n", ++ prP2pBssInfo->aucOwnMacAddr); ++ DBGLOG(P2P, TRACE, "The BSSID is changed to %pM\n", prP2pBssInfo->aucBSSID); ++ ++ /* Update BSS INFO to FW. */ ++ if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFuncSwitchOPMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will start a P2P Group Owner and send Beacon Frames. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncStartGO(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, ++ IN PUINT_8 pucSsidBuf, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP) ++{ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL)); ++ ++ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); ++ ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 1; ++ DBGLOG(P2P, INFO, ++ "p2pFuncStartGO:NFC Done[%d]\n", ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); ++ /* AP mode started. */ ++ p2pFuncSwitchOPMode(prAdapter, prBssInfo, prBssInfo->eIntendOPMode, FALSE); ++ ++ prBssInfo->eIntendOPMode = OP_MODE_NUM; ++ ++ /* 4 <1.1> Assign SSID */ ++ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, pucSsidBuf, ucSsidLen); ++ ++ DBGLOG(P2P, TRACE, "GO SSID:%s\n", prBssInfo->aucSSID); ++ ++ /* 4 <1.2> Clear current AP's STA_RECORD_T and current AID */ ++ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prBssInfo->u2AssocId = 0; ++ ++ /* 4 <1.3> Setup Channel, Band and Phy Attributes */ ++ prBssInfo->ucPrimaryChannel = ucChannelNum; ++ prBssInfo->eBand = eBand; ++ prBssInfo->eBssSCO = eSco; ++ ++ DBGLOG(P2P, TRACE, "GO Channel:%d\n", ucChannelNum); ++ ++ if (prBssInfo->eBand == BAND_5G) { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN); ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; ++ } else if (fgIsPureAP) { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN); ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; ++ } else { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN); ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; ++ } ++ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ prBssInfo->u2OperationalRateSet = ++ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ if (prBssInfo->ucAllSupportedRatesLen == 0) { ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, ++ &prBssInfo->ucAllSupportedRatesLen); ++ } ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prBssInfo->u2ATIMWindow = 0; ++ prBssInfo->ucBeaconTimeoutCount = 0; ++ ++ /* 3 <2> Update BSS_INFO_T common part */ ++#if CFG_SUPPORT_AAA ++ if (!fgIsPureAP) { ++ prBssInfo->fgIsProtection = TRUE; /* Always enable protection at P2P GO */ ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); ++ } else { ++ if (kalP2PGetCipher(prAdapter->prGlueInfo)) ++ prBssInfo->fgIsProtection = TRUE; ++ } ++ ++ /* 20120106 frog: I want separate OP_Mode & Beacon TX Function. */ ++ /* p2pFuncSwitchOPMode(prAdapter, prBssInfo, OP_MODE_ACCESS_POINT, FALSE); */ ++ ++ bssInitForAP(prAdapter, prBssInfo, FALSE); ++ ++ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_P2P_INDEX); ++#endif /* CFG_SUPPORT_AAA */ ++ ++ /* 3 <3> Set MAC HW */ ++ /* 4 <3.1> Setup channel and bandwidth */ ++ rlmBssInitForAPandIbss(prAdapter, prBssInfo); ++ ++ /* 4 <3.2> Reset HW TSF Update Mode and Beacon Mode */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* 4 <3.3> Update Beacon again for network phy type confirmed. */ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++#if 0 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ ++ { ++ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; ++ ++ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; ++ arHotspotOptimizationCfg.u4Level = (0x3) << 8 | 0x5; ++ wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ NULL, ++ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), ++ (PUINT_8)&arHotspotOptimizationCfg, NULL, 0); ++ } ++#endif ++ ++ /* 4 <3.4> Setup BSSID */ ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ } while (FALSE); ++ ++} /* p2pFuncStartGO() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform CNM that channel privilege ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) ++{ ++ P_MSG_CH_ABORT_T prMsgChRelease = (P_MSG_CH_ABORT_T) NULL; ++ ++ DEBUGFUNC("p2pFuncReleaseCh()"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); ++ ++ if (!prChnlReqInfo->fgIsChannelRequested) ++ break; ++ ++ DBGLOG(P2P, TRACE, "P2P Release Channel\n"); ++ prChnlReqInfo->fgIsChannelRequested = FALSE; ++ ++ /* 1. return channel privilege to CNM immediately */ ++ prMsgChRelease = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); ++ if (!prMsgChRelease) { ++ ASSERT(0); /* Can't release Channel to CNM */ ++ break; ++ } ++ ++ prMsgChRelease->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; ++ prMsgChRelease->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prMsgChRelease->ucTokenID = prChnlReqInfo->ucSeqNumOfChReq++; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChRelease, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++} /* p2pFuncReleaseCh */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) ++{ ++ P_MSG_CH_REQ_T prMsgChReq = (P_MSG_CH_REQ_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); ++ ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ ++ /* send message to CNM for acquiring channel */ ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ break; ++ } ++ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prMsgChReq->ucTokenID = ++prChnlReqInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++ if (prChnlReqInfo->u4MaxInterval < P2P_EXT_LISTEN_TIME_MS) ++ prMsgChReq->u4MaxInterval = P2P_EXT_LISTEN_TIME_MS; ++ else ++ prMsgChReq->u4MaxInterval = prChnlReqInfo->u4MaxInterval; ++ ++ prMsgChReq->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; ++ prMsgChReq->eRfSco = prChnlReqInfo->eChnlSco; ++ prMsgChReq->eRfBand = prChnlReqInfo->eBand; ++ ++ kalMemZero(prMsgChReq->aucBSSID, MAC_ADDR_LEN); ++ ++ /* Channel request join BSSID. */ ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ ++ prChnlReqInfo->fgIsChannelRequested = TRUE; ++ ++ } while (FALSE); ++ ++} /* p2pFuncAcquireCh */ ++ ++#if 0 ++WLAN_STATUS ++p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBcnHdr, ++ IN UINT_32 u4HdrLen, ++ IN PUINT_8 pucBcnBody, IN UINT_32 u4BodyLen, IN UINT_32 u4DtimPeriod, IN UINT_32 u4BcnInterval) ++{ ++ WLAN_STATUS rResultStatus = WLAN_STATUS_INVALID_DATA; ++ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; ++ PUINT_8 pucTIMBody = (PUINT_8) NULL; ++ UINT_16 u2FrameLength = 0, UINT_16 u2OldBodyLen = 0; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prBcnMsduInfo = prP2pBssInfo->prBeacon ASSERT_BREAK(prBcnMsduInfo != NULL); ++ ++ /* TODO: Find TIM IE pointer. */ ++ prBcnFrame = prBcnMsduInfo->prPacket; ++ ++ ASSERT_BREAK(prBcnFrame != NULL); ++ ++ do { ++ /* Ori header. */ ++ UINT_16 u2IELength = 0, u2Offset = 0; ++ PUINT_8 pucIEBuf = prBcnFrame->aucInfoElem; ++ ++ u2IELength = prBcnMsduInfo->u2FrameLength - prBcnMsduInfo->ucMacHeaderLength; ++ ++ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { ++ if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) || ((IE_ID(pucIEBuf) > ELEM_ID_IBSS_PARAM_SET))) { ++ pucTIMBody = pucIEBuf; ++ break; ++ } ++ u2FrameLength += IE_SIZE(pucIEBuf); ++ } ++ ++ if (pucTIMBody == NULL) ++ pucTIMBody = pucIEBuf; ++ ++ /* Body not change. */ ++ u2OldBodyLen = (UINT_16) ((UINT_32) pucTIMBody - (UINT_32) prBcnFrame->aucInfoElem); ++ /* Move body. */ ++ kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen); ++ } while (FALSE); ++ ++ if (pucBcnHdr) { ++ kalMemCopy(prBcnMsduInfo->prPacket, pucBcnHdr, u4HdrLen); ++ pucTIMBody = (PUINT_8) ((UINT_32) prBcnMsduInfo->prPacket + u4HdrLen); ++ prBcnMsduInfo->ucMacHeaderLength = (WLAN_MAC_MGMT_HEADER_LEN + ++ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); ++ u2FrameLength = u4HdrLen; /* Header + Partial Body. */ ++ } else { ++ /* Header not change. */ ++ u2FrameLength += prBcnMsduInfo->ucMacHeaderLength; ++ } ++ ++ if (pucBcnBody) { ++ kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen); ++ u2FrameLength += (UINT_16) u4BodyLen; ++ } else { ++ kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen); ++ u2FrameLength += u2OldBodyLen; ++ } ++ ++ /* Frame Length */ ++ prBcnMsduInfo->u2FrameLength = u2FrameLength; ++ prBcnMsduInfo->fgIs802_11 = TRUE; ++ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ prP2pBssInfo->u2BeaconInterval = (UINT_16) u4BcnInterval; ++ prP2pBssInfo->ucDTIMPeriod = (UINT_8) u4DtimPeriod; ++ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; ++ prBcnMsduInfo->ucPacketType = 3; ++ rResultStatus = nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ NETWORK_TYPE_P2P_INDEX, ++ prP2pBssInfo->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ prBcnMsduInfo->u2FrameLength - ++ OFFSET_OF(WLAN_BEACON_FRAME_T, ++ aucInfoElem)); ++ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ /* AP is created, Beacon Update. */ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } while (FALSE); ++ return rResultStatus; ++} /* p2pFuncBeaconUpdate */ ++ ++#else ++WLAN_STATUS ++ p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, ++ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, ++ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen) ++{ ++WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; ++PUINT_8 pucIEBuf = (PUINT_8) NULL; ++PUINT_8 paucIEBuf = (PUINT_8) NULL;/*[MAX_IE_LENGTH]; aucIEBuf*/ ++ ++do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (prBcnUpdateInfo != NULL)); ++ ++ prBcnMsduInfo = prP2pBssInfo->prBeacon; ++ ++#if DBG ++ if (prBcnUpdateInfo->pucBcnHdr != NULL) { ++ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnHdr == ++ ((UINT_32) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD)); ++ } ++ ++ if (prBcnUpdateInfo->pucBcnBody != NULL) { ++ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnBody == ++ ((UINT_32) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen)); ++ } ++#endif ++ prBcnFrame = (P_WLAN_BEACON_FRAME_T) ((ULONG) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD); ++ ++ if (!pucNewBcnBody) { ++ /* Old body. */ ++ pucNewBcnBody = prBcnUpdateInfo->pucBcnBody; ++ ASSERT(u4NewBodyLen == 0); ++ u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen; ++ } else { ++ prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen; ++ } ++ ++ paucIEBuf = kalMemAlloc(MAX_IE_LENGTH, VIR_MEM_TYPE); ++ if (paucIEBuf == NULL) { ++ DBGLOG(P2P, TRACE, "p2p alloc paucIEBuf fail\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Temp buffer body part. */ ++ kalMemCopy(paucIEBuf, pucNewBcnBody, u4NewBodyLen); ++ ++ if (pucNewBcnHdr) { ++ kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen); ++ prBcnUpdateInfo->pucBcnHdr = (PUINT_8) prBcnFrame; ++ prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen; ++ } ++ ++ pucIEBuf = (PUINT_8) ((ULONG) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen); ++ kalMemCopy(pucIEBuf, paucIEBuf, u4NewBodyLen); ++ kalMemFree(paucIEBuf, VIR_MEM_TYPE, MAX_IE_LENGTH); ++ prBcnUpdateInfo->pucBcnBody = pucIEBuf; ++ ++ /* Frame Length */ ++ prBcnMsduInfo->u2FrameLength = (UINT_16) (prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen); ++ ++ prBcnMsduInfo->ucPacketType = 3; ++ prBcnMsduInfo->fgIs802_11 = TRUE; ++ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ ++ /* Update BSS INFO related information. */ ++ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr); ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID); ++ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; ++ ++ p2pFuncParseBeaconContent(prAdapter, ++ prP2pBssInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); ++ ++#if 1 ++ /* bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++#else ++ nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ NETWORK_TYPE_P2P_INDEX, ++ prBcnFrame->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); ++#endif ++} while (FALSE); ++ ++return rWlanStatus; ++} /* p2pFuncBeaconUpdate */ ++ ++#endif ++ ++/* TODO: We do not apply IE in deauth frame set from upper layer now. */ ++WLAN_STATUS ++p2pFuncDeauth(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucPeerMacAddr, ++ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDeauth) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; ++ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ BOOLEAN fgIsStaFound = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_ACCESS_POINT: ++ { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); ++ fgIsStaFound = TRUE; ++ break; ++ } ++ } ++ ++ } ++ break; ++ case OP_MODE_INFRASTRUCTURE: ++ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); ++ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) ++ break; ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ fgIsStaFound = TRUE; ++ break; ++ default: ++ break; ++ } ++ ++ if (fgIsStaFound) ++ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDeauth, u2ReasonCode); ++ ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncDeauth */ ++ ++/* TODO: We do not apply IE in disassoc frame set from upper layer now. */ ++WLAN_STATUS ++p2pFuncDisassoc(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucPeerMacAddr, ++ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDisassoc) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; ++ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ BOOLEAN fgIsStaFound = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_ACCESS_POINT: ++ { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); ++ fgIsStaFound = TRUE; ++ /* p2pFuncDisconnect(prAdapter, prCliStaRec, ++ * fgSendDisassoc, u2ReasonCode); */ ++ break; ++ } ++ } ++ ++ } ++ break; ++ case OP_MODE_INFRASTRUCTURE: ++ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); ++ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) ++ break; ++ /* p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); */ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ fgIsStaFound = TRUE; ++ break; ++ default: ++ break; ++ } ++ ++ if (fgIsStaFound) { ++ ++ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); ++ /* 20120830 moved into p2pFuncDisconnect(). */ ++ /* cnmStaRecFree(prAdapter, prCliStaRec, TRUE); */ ++ ++ } ++ ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncDisassoc */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) ++* 1. GC: Disconnect from AP. (Send Deauth) ++* 2. GO: Disconnect all STA ++* ++* @param[in] prAdapter Pointer to the adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncDissolve(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) ++{ ++ DEBUGFUNC("p2pFuncDissolve()"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ /* Reset station record status. */ ++ if (prP2pBssInfo->prStaRecOfAP) { ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, NULL, 0, REASON_CODE_DEAUTH_LEAVING_BSS, ++ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); ++ ++ /* 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL. */ ++ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, fgSendDeauth, u2ReasonCode); ++ } ++ ++ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). ++ * hit prStaRecOfAP == NULL. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ break; ++ case OP_MODE_ACCESS_POINT: ++ /* Under AP mode, we would net send deauthentication frame to each STA. ++ * We only stop the Beacon & let all stations timeout. ++ */ ++ { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ ++ /* Send deauth. */ ++ authSendDeauthFrame(prAdapter, ++ NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL); ++ ++ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ ++ while (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_REMOVE_HEAD(prStaRecOfClientList, prCurrStaRec, P_STA_RECORD_T); ++ ++ /* Indicate to Host. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ ++ ++ p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode); ++ ++ } ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; ++ } ++ ++ break; ++ default: ++ return; /* 20110420 -- alreay in Device Mode. */ ++ } ++ ++ /* Make the deauth frame send to FW ASAP. */ ++ wlanAcquirePowerControl(prAdapter); ++ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); ++ wlanReleasePowerControl(prAdapter); ++ ++ kalMdelay(100); ++ ++ /* Change Connection Status. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ } while (FALSE); ++ ++} /* p2pFuncDissolve */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) ++* 1. GC: Disconnect from AP. (Send Deauth) ++* 2. GO: Disconnect all STA ++* ++* @param[in] prAdapter Pointer to the adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ eOriMediaStatus = prP2pBssInfo->eConnectionState; ++ ++ /* Indicate disconnect. */ ++ /* TODO: */ ++ /* kalP2PGOStationUpdate */ ++ /* kalP2PGCIndicateConnectionStatus */ ++ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, prStaRec->aucMacAddr); */ ++ DBGLOG(P2P, INFO, "p2pFuncDisconnect, eCurrentOPMode: %d, sendDeauth: %s\n", ++ prP2pBssInfo->eCurrentOPMode, fgSendDeauth ? "True" : "False"); ++ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); ++ ++ if (fgSendDeauth) { ++ /* Send deauth. */ ++ authSendDeauthFrame(prAdapter, ++ prStaRec, ++ (P_SW_RFB_T) NULL, ++ u2ReasonCode, (PFN_TX_DONE_HANDLER) p2pFsmRunEventDeauthTxDone); ++ } else { ++ /* Change station state. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* Reset Station Record Status. */ ++ p2pFuncResetStaRecStatus(prAdapter, prStaRec); ++ ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { ++ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ } ++ ++ if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { ++ /* Update Disconnected state to FW. */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } ++ ++ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { ++ /* GO: It would stop Beacon TX. GC: Stop all BSS related PS function. */ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Reset RLM related field of BSSINFO. */ ++ rlmBssAborted(prAdapter, prP2pBssInfo); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pFuncDisconnect */ ++ ++/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ ++#define WLAN_ACTION_SPECTRUM_MGMT 0 ++#define WLAN_ACTION_QOS 1 ++#define WLAN_ACTION_DLS 2 ++#define WLAN_ACTION_BLOCK_ACK 3 ++#define WLAN_ACTION_PUBLIC 4 ++#define WLAN_ACTION_RADIO_MEASUREMENT 5 ++#define WLAN_ACTION_FT 6 ++#define WLAN_ACTION_HT 7 ++#define WLAN_ACTION_SA_QUERY 8 ++#define WLAN_ACTION_PROTECTED_DUAL 9 ++#define WLAN_ACTION_WNM 10 ++#define WLAN_ACTION_UNPROTECTED_WNM 11 ++#define WLAN_ACTION_TDLS 12 ++#define WLAN_ACTION_SELF_PROTECTED 15 ++#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ ++#define WLAN_ACTION_VENDOR_SPECIFIC 127 ++ ++/* Public action codes */ ++#define WLAN_PA_20_40_BSS_COEX 0 ++#define WLAN_PA_VENDOR_SPECIFIC 9 ++#define WLAN_PA_GAS_INITIAL_REQ 10 ++#define WLAN_PA_GAS_INITIAL_RESP 11 ++#define WLAN_PA_GAS_COMEBACK_REQ 12 ++#define WLAN_PA_GAS_COMEBACK_RESP 13 ++#define WLAN_TDLS_DISCOVERY_RESPONSE 14 ++ ++/* P2P public action frames */ ++enum p2p_action_frame_type { ++ P2P_GO_NEG_REQ = 0, ++ P2P_GO_NEG_RESP = 1, ++ P2P_GO_NEG_CONF = 2, ++ P2P_INVITATION_REQ = 3, ++ P2P_INVITATION_RESP = 4, ++ P2P_DEV_DISC_REQ = 5, ++ P2P_DEV_DISC_RESP = 6, ++ P2P_PROV_DISC_REQ = 7, ++ P2P_PROV_DISC_RESP = 8 ++}; ++ ++const char *p2p_to_string(enum p2p_action_frame_type p2p_action) ++{ ++ switch (p2p_action) { ++ case P2P_GO_NEG_REQ: ++ return "GO_NEG_REQ"; ++ case P2P_GO_NEG_RESP: ++ return "GO_NEG_RESP"; ++ case P2P_GO_NEG_CONF: ++ return "GO_NEG_CONF"; ++ case P2P_INVITATION_REQ: ++ return "INVITATION_REQ"; ++ case P2P_INVITATION_RESP: ++ return "INVITATION_RESP"; ++ case P2P_DEV_DISC_REQ: ++ return "DEV_DISC_REQ"; ++ case P2P_DEV_DISC_RESP: ++ return "DEV_DISC_RESP"; ++ case P2P_PROV_DISC_REQ: ++ return "PROV_DISC_REQ"; ++ case P2P_PROV_DISC_RESP: ++ return "PROV_DISC_RESP"; ++ } ++ ++ return "UNKNOWN P2P Public Action"; ++} ++const char *pa_to_string(int pa_action) ++{ ++ switch (pa_action) { ++ case WLAN_PA_20_40_BSS_COEX: ++ return "PA_20_40_BSS_COEX"; ++ case WLAN_PA_VENDOR_SPECIFIC: ++ return "PA_VENDOR_SPECIFIC"; ++ case WLAN_PA_GAS_INITIAL_REQ: ++ return "PA_GAS_INITIAL_REQ"; ++ case WLAN_PA_GAS_INITIAL_RESP: ++ return "PA_GAS_INITIAL_RESP"; ++ case WLAN_PA_GAS_COMEBACK_REQ: ++ return "PA_GAS_COMEBACK_REQ"; ++ case WLAN_PA_GAS_COMEBACK_RESP: ++ return "PA_GAS_COMEBACK_RESP"; ++ case WLAN_TDLS_DISCOVERY_RESPONSE: ++ return "TDLS_DISCOVERY_RESPONSE"; ++ } ++ ++ return "UNKNOWN Public Action"; ++} ++ ++const char *action_to_string(int wlan_action) ++{ ++ switch (wlan_action) { ++ case WLAN_ACTION_SPECTRUM_MGMT: ++ return "SPECTRUM_MGMT"; ++ case WLAN_ACTION_QOS: ++ return "QOS"; ++ case WLAN_ACTION_DLS: ++ return "DLS"; ++ case WLAN_ACTION_BLOCK_ACK: ++ return "BLOCK_ACK"; ++ case WLAN_ACTION_PUBLIC: ++ return "PUBLIC"; ++ case WLAN_ACTION_RADIO_MEASUREMENT: ++ return "RADIO_MEASUREMENT"; ++ case WLAN_ACTION_FT: ++ return "FT"; ++ case WLAN_ACTION_HT: ++ return "HT"; ++ case WLAN_ACTION_SA_QUERY: ++ return "SA_QUERY"; ++ case WLAN_ACTION_PROTECTED_DUAL: ++ return "PROTECTED_DUAL"; ++ case WLAN_ACTION_WNM: ++ return "WNM"; ++ case WLAN_ACTION_UNPROTECTED_WNM: ++ return "UNPROTECTED_WNM"; ++ case WLAN_ACTION_TDLS: ++ return "TDLS"; ++ case WLAN_ACTION_SELF_PROTECTED: ++ return "SELF_PROTECTED"; ++ case WLAN_ACTION_WMM: ++ return "WMM"; ++ case WLAN_ACTION_VENDOR_SPECIFIC: ++ return "VENDOR_SPECIFIC"; ++ } ++ ++ return "UNKNOWN Action Frame"; ++} ++ ++VOID p2pFuncTagActionActionP2PFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, ++ IN P_WLAN_ACTION_FRAME prActFrame, ++ IN UINT_8 ucP2pAction, IN UINT_64 u8Cookie) ++{ ++ DBGLOG(P2P, INFO, "Found P2P_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNO: %d\n", ++ p2p_to_string(ucP2pAction), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++} ++ ++VOID p2pFuncTagActionActionFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, ++ IN P_WLAN_ACTION_FRAME prActFrame, ++ IN UINT_8 ucAction, IN UINT_64 u8Cookie) ++{ ++ PUINT_8 pucVendor = NULL; ++ ++ DBGLOG(P2P, INFO, "Found WLAN_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNo: %d\n", ++ pa_to_string(ucAction), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++ ++ if (ucAction == WLAN_PA_VENDOR_SPECIFIC) { ++ pucVendor = (PUINT_8)prActFrame + 26; ++ if (*(pucVendor + 0) == 0x50 && ++ *(pucVendor + 1) == 0x6f && ++ *(pucVendor + 2) == 0x9a) { ++ if (*(pucVendor + 3) == 0x09) ++ /* found p2p IE */ ++ p2pFuncTagActionActionP2PFrame(prMgmtTxMsdu, ++ prActFrame, *(pucVendor + 4), u8Cookie); ++ else if (*(pucVendor + 3) == 0x0a) ++ /* found WFD IE */ ++ DBGLOG(P2P, INFO, "Found WFD IE, SA: %pM - DA: %pM\n", ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr); ++ else ++ DBGLOG(P2P, INFO, "Found Other vendor 0x%x, SA: %pM - DA: %pM\n", ++ *(pucVendor + 3), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr); ++ } ++ } ++} ++ ++VOID p2pFuncTagActionCategoryFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, ++ P_WLAN_ACTION_FRAME prActFrame, ++ IN UINT_8 ucCategory, ++ IN UINT_64 u8Cookie) ++{ ++ ++ UINT_8 ucAction = 0; ++ ++ DBGLOG(P2P, INFO, "Found WLAN_ACTION_%s, SA: %pM - DA: %pM, u8Cookie: 0x%llx, SeqNO: %d\n", ++ action_to_string(ucCategory), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++ ++ if (ucCategory == WLAN_ACTION_PUBLIC) { ++ ucAction = prActFrame->ucAction; ++ p2pFuncTagActionActionFrame(prMgmtTxMsdu, prActFrame, ucAction, u8Cookie); ++ ++ } ++} ++ ++/* ++ * used to debug p2p mgmt frame: ++ * GO Nego Req ++ * GO Nego Res ++ * GO Nego Confirm ++ * GO Invite Req ++ * GO Invite Res ++ * Device Discoverability Req ++ * Device Discoverability Res ++ * Provision Discovery Req ++ * Provision Discovery Res ++ */ ++ ++VOID ++p2pFuncTagMgmtFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) ++{ ++ /* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */ ++ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; ++ P_WLAN_PROBE_RSP_FRAME_T prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T)NULL; ++ UINT_16 u2TxFrameCtrl; ++ P_WLAN_ACTION_FRAME prActFrame; ++ UINT_8 ucCategory; ++ ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ /* ++ * mgmt frame MASK_FC_TYPE = 0 ++ * use MASK_FRAME_TYPE is oK for frame type/subtype judge ++ */ ++ u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; ++ ++ switch (u2TxFrameCtrl) { ++ case MAC_FRAME_PROBE_RSP: ++ ++ prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T) prWlanHdr; ++ DBGLOG(P2P, INFO, "TX Probe Response Frame, SA: %pM - DA: %pM, cookie: 0x%llx, seqNo: %d\n", ++ prProbRspHdr->aucSrcAddr, prProbRspHdr->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++ ++ break; ++ ++ case MAC_FRAME_ACTION: ++ ++ prActFrame = (P_WLAN_ACTION_FRAME)prWlanHdr; ++ ucCategory = prActFrame->ucCategory; ++ p2pFuncTagActionCategoryFrame(prMgmtTxMsdu, prActFrame, ++ ucCategory, u8Cookie); ++ ++ break; ++ default: ++ DBGLOG(P2P, INFO, "MGMT:, un-tagged frame type: 0x%x, A1: %pM, A2: %pM, A3: %pM seqNo: %d\n", ++ u2TxFrameCtrl, ++ prWlanHdr->aucAddr1, ++ prWlanHdr->aucAddr2, ++ prWlanHdr->aucAddr3, ++ prMgmtTxMsdu->ucTxSeqNum); ++ break; ++ } ++} ++ ++WLAN_STATUS ++p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ BOOLEAN fgIsProbrsp = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); ++ ++ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { ++ ++ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ ++ /* Packet on driver, not done yet, drop it. */ ++ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; ++ if (prTxMsduInfo != NULL) { ++ ++ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ FALSE, ++ prTxMsduInfo->prPacket, ++ (UINT_32) prTxMsduInfo->u2FrameLength); ++ ++ /* Leave it to TX Done handler. */ ++ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ DBGLOG(P2P, INFO, "p2pFuncTxMgmtFrame: Drop MGMT cookie: 0x%llx\n", ++ prMgmtTxReqInfo->u8Cookie); ++ } ++ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ ++ /* Packet transmitted, wait tx done. (cookie issue) */ ++ /* 20120105 frog - use another u8cookie to store this value. */ ++ } ++ ++ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); ++ ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, prWlanHdr->aucAddr1); ++ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_P2P_INDEX; ++ ++ switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) { ++ case MAC_FRAME_PROBE_RSP: ++ DBGLOG(P2P, TRACE, "p2pFuncTxMgmtFrame: TX MAC_FRAME_PROBE_RSP\n"); ++ fgIsProbrsp = TRUE; ++ prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, prMgmtTxMsdu); ++ break; ++ default: ++ break; ++ } ++ ++ prMgmtTxReqInfo->u8Cookie = u8Cookie; ++ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; ++ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; ++ ++ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; ++ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); ++ if (prStaRec != NULL) ++ DBGLOG(P2P, TRACE, "Mgmt with station record: %pM.\n", prStaRec->aucMacAddr); ++ ++ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ ++ prMgmtTxMsdu->fgIs802_1x = FALSE; ++ prMgmtTxMsdu->fgIs802_11 = TRUE; ++ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMgmtTxMsdu->pfTxDoneHandler = p2pFsmRunEventMgmtFrameTxDone; ++ prMgmtTxMsdu->fgIsBasicRate = TRUE; ++ ++ p2pFuncTagMgmtFrame(prMgmtTxMsdu, u8Cookie); ++ ++ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncTxMgmtFrame */ ++ ++VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL)); ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ prP2pConnSettings->ucOperatingChnl = prRfChannelInfo->ucChannelNum; ++ prP2pConnSettings->eBand = prRfChannelInfo->eBand; ++ ++ } while (FALSE); ++ ++} ++ ++/* p2pFuncSetChannel */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval TRUE We will retry JOIN ++* @retval FALSE We will not retry JOIN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo) ++{ ++ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; ++ BOOLEAN fgRetValue = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL) && (prJoinInfo != NULL)); ++ ++ /* Retry other AuthType if possible */ ++ if (!prJoinInfo->ucAvailableAuthTypes) ++ break; ++ ++ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(P2P, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else { ++ DBGLOG(P2P, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); ++ ASSERT(0); ++ break; ++ } ++ ++ prJoinInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ ++ ++ /* Trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ break; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++ fgRetValue = TRUE; ++ } while (FALSE); ++ ++ return fgRetValue; ++ ++} /* end of p2pFuncRetryJOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the association was completed. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ ++ DEBUGFUNC("p2pUpdateBssInfoForJOIN()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ASSERT(prAssocRspSwRfb); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; ++ ++ DBGLOG(P2P, INFO, "Update P2P_BSS_INFO_T and apply settings to MAC\n"); ++ ++ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prP2pBssInfo->aucSSID, ++ prP2pBssInfo->ucSSIDLen, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); ++ ++ if (prBssDesc == NULL) { ++ /* Target BSS NULL. */ ++ DBGLOG(P2P, TRACE, "Target BSS NULL\n"); ++ return; ++ } ++ ++ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAssocRspFrame->aucBSSID)) ++ ASSERT(FALSE); ++ /* 4 <1.3> Setup Channel, Band */ ++ prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; ++ prP2pBssInfo->eBand = prBssDesc->eBand; ++ ++ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ ++ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ ++ prP2pBssInfo->prStaRecOfAP = prStaRec; ++ prP2pBssInfo->u2AssocId = prStaRec->u2AssocId; ++ ++ /* 4 <2.2> Setup Capability */ ++ prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ ++ ++ if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) ++ prP2pBssInfo->fgIsShortPreambleAllowed = TRUE; ++ else ++ prP2pBssInfo->fgIsShortPreambleAllowed = FALSE; ++ ++ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ ++ prP2pBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ prP2pBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; ++ prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ ++ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ ++ /* 4 <3.1> Setup BSSID */ ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); ++ ++ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - ++ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); ++ pucIE = prAssocRspFrame->aucInfoElem; ++ ++ /* 4 <3.2> Parse WMM and setup QBSS flag */ ++ /* Parse WMM related IEs and configure HW CRs accordingly */ ++ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS; ++ ++ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ ++ ASSERT(prBssDesc); ++ ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ ++ /* 4 <4.1> Setup MIB for current BSS */ ++ prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ ++ prP2pBssInfo->ucDTIMPeriod = 0; ++ prP2pBssInfo->u2ATIMWindow = 0; ++ ++ prP2pBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; ++ ++ /* 4 <4.2> Update HT information and set channel */ ++ /* Record HT related parameters in rStaRec and rBssInfo ++ * Note: it shall be called before nicUpdateBss() ++ */ ++ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ /* 4 <4.3> Sync with firmware for BSS-INFO */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ ++ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ ++ ++} /* end of p2pUpdateBssInfoForJOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Auth Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Auth ++* @retval FALSE Don't reply the Auth ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAuth = TRUE; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; ++ ++ DBGLOG(P2P, INFO, "p2pValidate Authentication Frame\n"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prSwRfb != NULL) && (pprStaRec != NULL) && (pu2StatusCode != NULL)); ++ ++ /* P2P 3.2.8 */ ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ++ || (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { ++ /* We are not under AP Mode yet. */ ++ fgReplyAuth = FALSE; ++ DBGLOG(P2P, WARN, ++ "Current OP mode is not under AP mode. (%d)\n", prP2pBssInfo->eCurrentOPMode); ++ break; ++ } ++ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX, prAuthFrame->aucSrcAddr); ++ ++ if (!prStaRec) { ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX); ++ ++ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for ++ * exhausted case and do removal of unused STA_RECORD_T. ++ */ ++ /* Sent a message event to clean un-used STA_RECORD_T. */ ++ ASSERT(prStaRec); ++ if (!prStaRec) { ++ DBGLOG(AAA, INFO, "Station Limit Full. Decline a new Authentication.\n"); ++ break; ++ } ++ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); ++ ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++ ++ prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet; ++ ++ prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P; ++ ++ prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P; ++ prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN; ++ prStaRec->eStaType = STA_TYPE_P2P_GC; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } else { ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++ ++ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_STA_IN_P2P(prStaRec))) { ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ p2pFuncResetStaRecStatus(prAdapter, prStaRec); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ } ++ ++ } ++ ++ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem >= P2P_MAXIMUM_CLIENT_COUNT || ++ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { ++ /* GROUP limit full. */ ++ /* P2P 3.2.8 */ ++ DBGLOG(P2P, WARN, ++ "Group Limit Full. (%d)\n", (INT_16) prP2pBssInfo->rStaRecOfClientList.u4NumElem); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ fgReplyAuth = TRUE; ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD; ++ break; ++ } ++ /* Hotspot Blacklist */ ++ if (prAuthFrame->aucSrcAddr) { ++ if (kalP2PCmpBlackList(prAdapter->prGlueInfo, prAuthFrame->aucSrcAddr)) { ++ fgReplyAuth = TRUE; ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD; ++ return fgReplyAuth; ++ } ++ } ++ ++ /* prStaRec->eStaType = STA_TYPE_INFRA_CLIENT; */ ++ prStaRec->eStaType = STA_TYPE_P2P_GC; ++ ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ prStaRec->ucJoinFailureCount = 0; ++ ++ *pprStaRec = prStaRec; ++ ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ } while (FALSE); ++ ++ return fgReplyAuth; ++ ++} /* p2pFuncValidateAuth */ ++ ++VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ do { ++ if ((prAdapter == NULL) || (prStaRec == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; ++ prStaRec->ucJoinFailureCount = 0; ++ prStaRec->fgTransmitKeyExist = FALSE; ++ ++ prStaRec->fgSetPwrMgtBit = FALSE; ++ ++ } while (FALSE); ++ ++} /* p2pFuncResetStaRecStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function is used to initialize the value of the connection settings for ++* P2P network ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings) ++{ ++ P_DEVICE_TYPE_T prDevType; ++ UINT_8 aucDefaultDevName[] = P2P_DEFAULT_DEV_NAME; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++#if CFG_SUPPORT_CFG_FILE ++ P_WIFI_VAR_T prWifiVar = NULL; ++#endif ++ ++ ASSERT(prP2PConnSettings); ++#if CFG_SUPPORT_CFG_FILE ++ prWifiVar = &(prAdapter->rWifiVar); ++ ASSERT(prWifiVar); ++#endif ++ ++ /* Setup Default Device Name */ ++ prP2PConnSettings->ucDevNameLen = P2P_DEFAULT_DEV_NAME_LEN; ++ kalMemCopy(prP2PConnSettings->aucDevName, aucDefaultDevName, sizeof(aucDefaultDevName)); ++ ++ /* Setup Primary Device Type (Big-Endian) */ ++ prDevType = &prP2PConnSettings->rPrimaryDevTypeBE; ++ ++ prDevType->u2CategoryId = HTONS(P2P_DEFAULT_PRIMARY_CATEGORY_ID); ++ prDevType->u2SubCategoryId = HTONS(P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID); ++ ++ prDevType->aucOui[0] = aucWfaOui[0]; ++ prDevType->aucOui[1] = aucWfaOui[1]; ++ prDevType->aucOui[2] = aucWfaOui[2]; ++ prDevType->aucOui[3] = VENDOR_OUI_TYPE_WPS; ++ ++ /* Setup Secondary Device Type */ ++ prP2PConnSettings->ucSecondaryDevTypeCount = 0; ++ ++ /* Setup Default Config Method */ ++ prP2PConnSettings->eConfigMethodSelType = ENUM_CONFIG_METHOD_SEL_AUTO; ++ prP2PConnSettings->u2ConfigMethodsSupport = P2P_DEFAULT_CONFIG_METHOD; ++ prP2PConnSettings->u2TargetConfigMethod = 0; ++ prP2PConnSettings->u2LocalConfigMethod = 0; ++ prP2PConnSettings->fgIsPasswordIDRdy = FALSE; ++ ++ /* For Device Capability */ ++ prP2PConnSettings->fgSupportServiceDiscovery = FALSE; ++ prP2PConnSettings->fgSupportClientDiscoverability = TRUE; ++ prP2PConnSettings->fgSupportConcurrentOperation = TRUE; ++ prP2PConnSettings->fgSupportInfraManaged = FALSE; ++ prP2PConnSettings->fgSupportInvitationProcedure = FALSE; ++ ++ /* For Group Capability */ ++#if CFG_SUPPORT_PERSISTENT_GROUP ++ prP2PConnSettings->fgSupportPersistentP2PGroup = TRUE; ++#else ++ prP2PConnSettings->fgSupportPersistentP2PGroup = FALSE; ++#endif ++ prP2PConnSettings->fgSupportIntraBSSDistribution = TRUE; ++ prP2PConnSettings->fgSupportCrossConnection = TRUE; ++ prP2PConnSettings->fgSupportPersistentReconnect = FALSE; ++ ++ prP2PConnSettings->fgSupportOppPS = FALSE; ++ prP2PConnSettings->u2CTWindow = P2P_CTWINDOW_DEFAULT; ++ ++ /* For Connection Settings. */ ++ prP2PConnSettings->eAuthMode = AUTH_MODE_OPEN; ++ ++ prP2PConnSettings->prTargetP2pDesc = NULL; ++ prP2PConnSettings->ucSSIDLen = 0; ++ ++ /* Misc */ ++ prP2PConnSettings->fgIsScanReqIssued = FALSE; ++ prP2PConnSettings->fgIsServiceDiscoverIssued = FALSE; ++ prP2PConnSettings->fgP2pGroupLimit = FALSE; ++ prP2PConnSettings->ucOperatingChnl = 0; ++ prP2PConnSettings->ucListenChnl = 0; ++ prP2PConnSettings->ucTieBreaker = (UINT_8) (kalRandomNumber() & 0x1); ++ ++ prP2PConnSettings->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; ++#if CFG_SUPPORT_CFG_FILE ++ /* prP2PConnSettings->fgIsWPSMode = prWifiVar->ucApWpsMode; */ ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = prWifiVar->ucApWpsMode; ++#endif ++} /* p2pFuncInitConnectionSettings */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Assoc Req Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Assoc Resp ++* @retval FALSE Don't reply the Assoc Resp ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAssocResp = TRUE; ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_WFD_ATTRIBUTE_T prWfdAttribute = (P_WFD_ATTRIBUTE_T) NULL; ++ BOOLEAN fgNeedFree = FALSE; ++#endif ++ /* UINT_16 u2AttriListLen = 0; */ ++ UINT_16 u2WfdDevInfo = 0; ++ P_WFD_DEVICE_INFORMATION_IE_T prAttriWfdDevInfo; ++ ++ /* TODO(Kevin): Call P2P functions to check .. ++ 2. Check we can accept connection from thsi peer ++ a. If we are in PROVISION state, only accept the peer we do the GO formation previously. ++ b. If we are in OPERATION state, only accept the other peer when P2P_GROUP_LIMIT is 0. ++ 3. Check Black List here. ++ */ ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (pu2StatusCode != NULL)); ++ ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prStaRec == NULL) { ++ /* Station record should be ready while RX AUTH frame. */ ++ fgReplyAssocResp = FALSE; ++ ASSERT(FALSE); ++ break; ++ } ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ ++ prStaRec->u2DesiredNonHTRateSet &= prP2pBssInfo->u2OperationalRateSet; ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet; ++ ++ if (prStaRec->ucDesiredPhyTypeSet == 0) { ++ /* The station only support 11B rate. */ ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++#if CFG_SUPPORT_WFD && 1 ++ /* LOG_FUNC("Skip check WFD IE because some API is not ready\n"); */ ++ if (!prAdapter->rWifiVar.prP2pFsmInfo) { ++ fgReplyAssocResp = FALSE; ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ DBGLOG(P2P, INFO, "AssocReq, wfd_en %u wfd_info 0x%x wfd_policy 0x%x wfd_flag 0x%x\n", ++ prWfdCfgSettings->ucWfdEnable, prWfdCfgSettings->u2WfdDevInfo, ++ prWfdCfgSettings->u4WfdPolicy, prWfdCfgSettings->u4WfdFlag); /* Eddie */ ++ if (prWfdCfgSettings->ucWfdEnable) { ++ if (prWfdCfgSettings->u4WfdPolicy & BIT(6)) { ++ /* Rejected all. */ ++ break; ++ } ++ ++ /* fgNeedFree = p2pFuncGetAttriList(prAdapter, */ ++ /* VENDOR_OUI_TYPE_WFD, */ ++ /* (PUINT_8)prAssocReqFrame->aucInfoElem, */ ++ /* (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), */ ++ /* (PPUINT_8)&prWfdAttribute, */ ++ /* &u2AttriListLen); */ ++ ++ prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) ++ p2pFuncGetSpecAttri(prAdapter, ++ VENDOR_OUI_TYPE_WFD, ++ (PUINT_8) prAssocReqFrame->aucInfoElem, ++ (prSwRfb->u2PacketLen - ++ OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), ++ WFD_ATTRI_ID_DEV_INFO); ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(5)) && (prAttriWfdDevInfo != NULL)) { ++ /* Rejected with WFD IE. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(0)) && (prAttriWfdDevInfo == NULL)) { ++ /* Rejected without WFD IE. */ ++ break; ++ } ++ ++ if (prAttriWfdDevInfo == NULL) { ++ /* ++ * Without WFD IE. ++ * Do nothing. Accept the connection request. ++ */ ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ break; ++ } ++ ++ /* prAttriWfdDevInfo = */ ++ /* (P_WFD_DEVICE_INFORMATION_IE_T)p2pFuncGetSpecAttri(prAdapter, */ ++ /* VENDOR_OUI_TYPE_WFD, */ ++ /* (PUINT_8)prWfdAttribute, */ ++ /* u2AttriListLen, */ ++ /* WFD_ATTRI_ID_DEV_INFO); */ ++ /* if (prAttriWfdDevInfo == NULL) { */ ++ /* No such attribute. */ ++ /* break; */ ++ /* } */ ++ ++ WLAN_GET_FIELD_BE16(&prAttriWfdDevInfo->u2WfdDevInfo, &u2WfdDevInfo); ++ DBGLOG(P2P, INFO, "RX Assoc Req WFD Info:0x%x.\n", u2WfdDevInfo); ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(1)) && ((u2WfdDevInfo & 0x3) == 0x0)) { ++ /* Rejected because of SOURCE. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(2)) && ((u2WfdDevInfo & 0x3) == 0x1)) { ++ /* Rejected because of Primary Sink. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(3)) && ((u2WfdDevInfo & 0x3) == 0x2)) { ++ /* Rejected because of Secondary Sink. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(4)) && ((u2WfdDevInfo & 0x3) == 0x3)) { ++ /* Rejected because of Source & Primary Sink. */ ++ break; ++ } ++ ++ /* Check role */ ++ ++ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) && ++ ((prWfdCfgSettings->u2WfdDevInfo & BITS(0, 1)) == 0x3)) { ++ /* P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = ++ * (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T)NULL; */ ++ UINT_16 u2DevInfo = prWfdCfgSettings->u2WfdDevInfo; ++ ++ /* We may change role here if we are dual role */ ++ ++ if ((u2WfdDevInfo & BITS(0, 1)) == 0x00 /* Peer is Source */) { ++ DBGLOG(P2P, INFO, "WFD: Switch role to primary sink\n"); ++ ++ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); ++ prWfdCfgSettings->u2WfdDevInfo |= 0x1; ++ ++ /* event to annonce the role is chanaged to P-Sink */ ++ ++ } else if ((u2WfdDevInfo & BITS(0, 1)) == 0x01 /* Peer is P-Sink */) { ++ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); ++ ++ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); ++ /* event to annonce the role is chanaged to Source */ ++ } else { ++ DBGLOG(P2P, INFO, "WFD: Peer role is wrong type(dev 0x%x)\n", ++ (u2DevInfo)); ++ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); ++ ++ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); ++ /* event to annonce the role is chanaged to Source */ ++ } ++ ++ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); ++ ++ } /* Dual role p2p->wfd_params->WfdDevInfo */ ++ ++ /* WFD_FLAG_DEV_INFO_VALID */ ++ } ++ /* ucWfdEnable */ ++#endif ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ } while (FALSE); ++ ++#if CFG_SUPPORT_WFD ++ if ((prWfdAttribute) && (fgNeedFree)) ++ kalMemFree(prWfdAttribute, VIR_MEM_TYPE, WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE); ++#endif ++ ++ return fgReplyAssocResp; ++ ++} /* p2pFuncValidateAssocReq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to check the P2P IE ++* ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType) ++{ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ P_IE_WFA_T prWfaIE = (P_IE_WFA_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pucOuiType != NULL)); ++ ++ prWfaIE = (P_IE_WFA_T) pucBuf; ++ ++ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { ++ break; ++ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || ++ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { ++ break; ++ } ++ ++ *pucOuiType = prWfaIE->ucOuiType; ++ ++ return TRUE; ++ } while (FALSE); ++ ++ return FALSE; ++} /* p2pFuncParseCheckForP2PInfoElem */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) ++{ ++ BOOLEAN fgIsReplyProbeRsp = FALSE; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("p2pFuncValidateProbeReq"); ++ DBGLOG(P2P, TRACE, "p2pFuncValidateProbeReq\n"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) { ++ ++ DBGLOG(P2P, TRACE, "report probe req to OS\n"); ++ /* Leave the probe response to p2p_supplicant. */ ++ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); ++ } ++ ++ } while (FALSE); ++ ++ return fgIsReplyProbeRsp; ++ ++} /* end of p2pFuncValidateProbeReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("p2pFuncValidateProbeReq"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME) { ++ /* Leave the probe response to p2p_supplicant. */ ++ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pFuncValidateRxMgmtFrame */ ++ ++BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ if (prP2pFsmInfo) { ++ if (prP2pFsmInfo->fgIsWPSMode == 1) ++ return FALSE; ++ return prP2pFsmInfo->fgIsApMode; ++ } else { ++ return FALSE; ++ } ++} ++ ++/* p2pFuncIsAPMode */ ++ ++VOID ++p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen) ++{ ++ PUINT_8 pucIE = (PUINT_8) NULL; ++ UINT_16 u2Offset = 0; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ BOOLEAN ucNewSecMode = FALSE; ++ BOOLEAN ucOldSecMode = FALSE; ++ UINT_8 ucOuiType; ++ UINT_16 u2SubTypeVersion; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); ++ ++ if (u4IELen == 0) ++ break; ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pSpecificBssInfo->u2AttributeLen = 0; ++ ++ ASSERT_BREAK(pucIEInfo != NULL); ++ ++ pucIE = pucIEInfo; ++ ++ ucOldSecMode = kalP2PGetCipher(prAdapter->prGlueInfo); ++ ++ IE_FOR_EACH(pucIE, u4IELen, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ { ++ /* 0 */ /* V */ /* Done */ ++ /* DBGLOG(P2P, TRACE, ("SSID update\n")); */ ++ /* SSID is saved when start AP/GO */ ++ /* SSID IE set in beacon from supplicant will not always be */ ++ /* the true since hidden SSID case */ ++ /* ++ COPY_SSID(prP2pBssInfo->aucSSID, ++ prP2pBssInfo->ucSSIDLen, ++ SSID_IE(pucIE)->aucSSID, ++ SSID_IE(pucIE)->ucLength); ++ ++ COPY_SSID(prP2pSpecificBssInfo->aucGroupSsid, ++ prP2pSpecificBssInfo->u2GroupSsidLen, ++ SSID_IE(pucIE)->aucSSID, ++ SSID_IE(pucIE)->ucLength); ++ */ ++ } ++ break; ++ case ELEM_ID_SUP_RATES: ++ { ++ /* 1 */ /* V */ /* Done */ ++ DBGLOG(P2P, TRACE, "Support Rate IE\n"); ++ kalMemCopy(prP2pBssInfo->aucAllSupportedRates, ++ SUP_RATES_IE(pucIE)->aucSupportedRates, ++ SUP_RATES_IE(pucIE)->ucLength); ++ ++ prP2pBssInfo->ucAllSupportedRatesLen = SUP_RATES_IE(pucIE)->ucLength; ++ ++ DBGLOG_MEM8(P2P, TRACE, SUP_RATES_IE(pucIE)->aucSupportedRates, ++ SUP_RATES_IE(pucIE)->ucLength); ++ } ++ break; ++ case ELEM_ID_DS_PARAM_SET: ++ { ++ /* 3 */ /* V */ /* Done */ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = ++ prAdapter->rWifiVar.prP2PConnSettings; ++ ++ DBGLOG(P2P, TRACE, "DS PARAM IE\n"); ++ ++ ASSERT(prP2pConnSettings->ucOperatingChnl == DS_PARAM_IE(pucIE)->ucCurrChnl); ++ ++ if (prP2pConnSettings->eBand != BAND_2G4) { ++ ASSERT(FALSE); ++ break; ++ } ++ /* prP2pBssInfo->ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; */ ++ ++ /* prP2pBssInfo->eBand = BAND_2G4; */ ++ } ++ break; ++ case ELEM_ID_TIM: /* 5 */ /* V */ ++ DBGLOG(P2P, TRACE, "TIM IE\n"); ++ TIM_IE(pucIE)->ucDTIMPeriod = prP2pBssInfo->ucDTIMPeriod; ++ break; ++ case ELEM_ID_ERP_INFO: /* 42 */ /* V */ ++ { ++#if 1 ++ /* This IE would dynamic change due to FW detection change is required. */ ++ DBGLOG(P2P, TRACE, "ERP IE will be over write by driver\n"); ++ DBGLOG(P2P, TRACE, " ucERP: %x.\n", ERP_INFO_IE(pucIE)->ucERP); ++ ++#else ++ /* This IE would dynamic change due to FW detection change is required. */ ++ DBGLOG(P2P, TRACE, "ERP IE.\n"); ++ ++ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11GN; ++ ++ ASSERT(prP2pBssInfo->eBand == BAND_2G4); ++ ++ prP2pBssInfo->fgObssErpProtectMode = ++ ((ERP_INFO_IE(pucIE)->ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE); ++ ++ prP2pBssInfo->fgErpProtectMode = ++ ((ERP_INFO_IE(pucIE)->ucERP & ++ (ERP_INFO_USE_PROTECTION | ERP_INFO_NON_ERP_PRESENT)) ? TRUE : FALSE); ++#endif ++ ++ } ++ break; ++ case ELEM_ID_HT_CAP: /* 45 */ /* V */ ++ { ++#if 1 ++ DBGLOG(P2P, TRACE, "HT CAP IE would be overwritten by driver\n"); ++ ++ DBGLOG(P2P, TRACE, ++ "HT Cap Info:%x, AMPDU Param:%x\n", HT_CAP_IE(pucIE)->u2HtCapInfo, ++ HT_CAP_IE(pucIE)->ucAmpduParam); ++ ++ DBGLOG(P2P, TRACE, ++ "HT Extended Cap Info%x,TX Beamforming Cap Info%x,Ant Selection Cap Info%x\n", ++ HT_CAP_IE(pucIE)->u2HtExtendedCap, HT_CAP_IE(pucIE)->u4TxBeamformingCap, ++ HT_CAP_IE(pucIE)->ucAselCap); ++#else ++ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ ++ /* u2HtCapInfo */ ++ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & ++ (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | ++ HT_CAP_INFO_DSSS_CCK_IN_40M)) == 0) { ++ prP2pBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } else { ++ prP2pBssInfo->fgAssoc40mBwAllowed = TRUE; ++ } ++ ++ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & ++ (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M)) == 0) { ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; ++ } else { ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = FALSE; ++ } ++ ++ /* ucAmpduParam */ ++ DBGLOG(P2P, TRACE, ++ "AMPDU setting from supplicant:0x%x, & default value:0x%x\n", ++ (UINT_8) HT_CAP_IE(pucIE)->ucAmpduParam, ++ (UINT_8) AMPDU_PARAM_DEFAULT_VAL); ++ ++ /* rSupMcsSet */ ++ /* Can do nothing. the field is default value from other configuration. */ ++ /* HT_CAP_IE(pucIE)->rSupMcsSet; */ ++ ++ /* u2HtExtendedCap */ ++ ASSERT(HT_CAP_IE(pucIE)->u2HtExtendedCap == ++ (HT_EXT_CAP_DEFAULT_VAL & ++ ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE))); ++ ++ /* u4TxBeamformingCap */ ++ ASSERT(HT_CAP_IE(pucIE)->u4TxBeamformingCap == TX_BEAMFORMING_CAP_DEFAULT_VAL); ++ ++ /* ucAselCap */ ++ ASSERT(HT_CAP_IE(pucIE)->ucAselCap == ASEL_CAP_DEFAULT_VAL); ++#endif ++ } ++ break; ++ case ELEM_ID_RSN: /* 48 */ /* V */ ++ { ++ RSN_INFO_T rRsnIe; ++ ++ DBGLOG(P2P, TRACE, "RSN IE\n"); ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); ++ ucNewSecMode = TRUE; ++ ++ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) { ++ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; ++ prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; ++ prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap; ++ } ++ } ++ break; ++ case ELEM_ID_EXTENDED_SUP_RATES: /* 50 */ /* V */ ++ /* Be attention, ++ * ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */ ++ DBGLOG(P2P, TRACE, "Ex Support Rate IE\n"); ++ kalMemCopy(&(prP2pBssInfo->aucAllSupportedRates[prP2pBssInfo->ucAllSupportedRatesLen]), ++ EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, ++ EXT_SUP_RATES_IE(pucIE)->ucLength); ++ ++ DBGLOG_MEM8(P2P, TRACE, EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, ++ EXT_SUP_RATES_IE(pucIE)->ucLength); ++ ++ prP2pBssInfo->ucAllSupportedRatesLen += EXT_SUP_RATES_IE(pucIE)->ucLength; ++ break; ++ case ELEM_ID_HT_OP: ++ { ++ /* 61 */ /* V */ /* TODO: */ ++#if 1 ++ DBGLOG(P2P, TRACE, "HT OP IE would be overwritten by driver\n"); ++ ++ DBGLOG(P2P, TRACE, ++ " Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n", ++ HT_OP_IE(pucIE)->ucPrimaryChannel, HT_OP_IE(pucIE)->ucInfo1, ++ HT_OP_IE(pucIE)->u2Info2, HT_OP_IE(pucIE)->u2Info3); ++#else ++ UINT_16 u2Info2 = 0; ++ ++ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ ++ DBGLOG(P2P, TRACE, "HT OP IE\n"); ++ ++ /* ucPrimaryChannel. */ ++ ASSERT(HT_OP_IE(pucIE)->ucPrimaryChannel == prP2pBssInfo->ucPrimaryChannel); ++ ++ /* ucInfo1 */ ++ prP2pBssInfo->ucHtOpInfo1 = HT_OP_IE(pucIE)->ucInfo1; ++ ++ /* u2Info2 */ ++ u2Info2 = HT_OP_IE(pucIE)->u2Info2; ++ ++ if (u2Info2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) { ++ ASSERT(prP2pBssInfo->eGfOperationMode != GF_MODE_NORMAL); ++ u2Info2 &= ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT; ++ } ++ ++ if (u2Info2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) { ++ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; ++ u2Info2 &= ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; ++ } ++ ++ switch (u2Info2 & HT_OP_INFO2_HT_PROTECTION) { ++ case HT_PROTECT_MODE_NON_HT: ++ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NON_HT; ++ break; ++ case HT_PROTECT_MODE_NON_MEMBER: ++ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; ++ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; ++ break; ++ default: ++ prP2pBssInfo->eHtProtectMode = HT_OP_IE(pucIE)->u2Info2; ++ break; ++ } ++ ++ /* u2Info3 */ ++ prP2pBssInfo->u2HtOpInfo3 = HT_OP_IE(pucIE)->u2Info3; ++ ++ /* aucBasicMcsSet */ ++ DBGLOG_MEM8(P2P, TRACE, HT_OP_IE(pucIE)->aucBasicMcsSet, 16); ++#endif ++ } ++ break; ++ case ELEM_ID_OBSS_SCAN_PARAMS: /* 74 */ /* V */ ++ { ++ DBGLOG(P2P, TRACE, ++ "ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n"); ++ } ++ break; ++ case ELEM_ID_EXTENDED_CAP: /* 127 */ /* V */ ++ { ++ DBGLOG(P2P, TRACE, "ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n"); ++ } ++ break; ++ case ELEM_ID_VENDOR: /* 221 */ /* V */ ++ DBGLOG(P2P, TRACE, "Vender Specific IE\n"); ++ if (rsnParseCheckForWFAInfoElem ++ (prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { ++ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) ++ && (u2SubTypeVersion == VERSION_WPA)) { ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP); ++ ucNewSecMode = TRUE; ++ kalMemCopy(prP2pSpecificBssInfo->aucWpaIeBuffer, pucIE, ++ IE_SIZE(pucIE)); ++ prP2pSpecificBssInfo->u2WpaIeLen = IE_SIZE(pucIE); ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 0, pucIE, ++ IE_SIZE(pucIE)); ++ } ++ /* WMM here. */ ++ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { ++ /* TODO Store the whole P2P IE & generate later. */ ++ /* Be aware that there may be one or more P2P IE. */ ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache ++ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, ++ IE_SIZE(pucIE)); ++ ++ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache ++ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, ++ IE_SIZE(pucIE)); ++ ++ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); ++ } ++ } else { ++ ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache ++ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, ++ IE_SIZE(pucIE)); ++ ++ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); ++ DBGLOG(P2P, TRACE, "Driver unprocessed Vender Specific IE\n"); ++ ASSERT(FALSE); ++ } ++ ++ /* TODO: Store other Vender IE except for WMM Param. */ ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Unprocessed element ID:%d\n", IE_ID(pucIE)); ++ break; ++ } ++ } ++ ++ if (!ucNewSecMode && ucOldSecMode) ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_NONE); ++ ++ } while (FALSE); ++ ++} /* p2pFuncParseBeaconContent */ ++ ++P_BSS_DESC_T ++p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, ++ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) ++{ ++ P_BSS_DESC_T prTargetBss = (P_BSS_DESC_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prConnReqInfo != NULL) && (prChnlReqInfo != NULL) && (prScanReqInfo != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ break; ++ /* Update connection request information. */ ++ ASSERT(prConnReqInfo->fgIsConnRequest == TRUE); ++ ++ /* Find BSS Descriptor first. */ ++ prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); ++ ++ if (prTargetBss == NULL) { ++ /* Update scan parameter... to scan target device. */ ++ prScanReqInfo->ucNumChannelList = 1; ++ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; ++ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ ++ prScanReqInfo->fgIsAbort = TRUE; ++ } else { ++ prChnlReqInfo->u8Cookie = 0; ++ prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum; ++ prChnlReqInfo->eBand = prTargetBss->eBand; ++ prChnlReqInfo->eChnlSco = prTargetBss->eSco; ++ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; ++ } ++ ++ } while (FALSE); ++ ++ return prTargetBss; ++} /* p2pFuncKeepOnConnection */ ++ ++/* Currently Only for ASSOC Response Frame. */ ++VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; ++ INT_16 i2IELen = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; ++ ++ if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP) ++ break; ++ ++ i2IELen = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); ++ ++ if (i2IELen <= 0) ++ break; ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); ++ prJoinInfo->u4BufLength = (UINT_32) i2IELen; ++ ++ kalMemCopy(prJoinInfo->aucIEBuf, prAssocRspFrame->aucInfoElem, prJoinInfo->u4BufLength); ++ ++ } while (FALSE); ++ ++} /* p2pFuncStoreAssocRspIEBuffer */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Packet Filter. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_NOT_SUPPORTED ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, ++ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter) ++{ ++ UINT_32 u4NewPacketFilter = 0; ++ ++ DEBUGFUNC("p2pFuncMgmtFrameRegister"); ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ if (pu4P2pPacketFilter) ++ u4NewPacketFilter = *pu4P2pPacketFilter; ++ ++ switch (u2FrameType) { ++ case MAC_FRAME_PROBE_REQ: ++ if (fgIsRegistered) { ++ u4NewPacketFilter |= PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); ++ } else { ++ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); ++ } ++ break; ++ case MAC_FRAME_ACTION: ++ if (fgIsRegistered) { ++ u4NewPacketFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); ++ } else { ++ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); ++ } ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Ask frog to add code for mgmt:%x\n", u2FrameType); ++ break; ++ } ++ ++ if (pu4P2pPacketFilter) ++ *pu4P2pPacketFilter = u4NewPacketFilter; ++ ++ /* u4NewPacketFilter |= prAdapter->u4OsPacketFilter; */ ++ ++ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; ++ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; ++ ++ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RX_FILTER, ++ TRUE, ++ FALSE, ++ FALSE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(UINT_32), ++ (PUINT_8) &prAdapter->u4OsPacketFilter, ++ &u4NewPacketFilter, sizeof(u4NewPacketFilter) ++ ); ++ ++ } while (FALSE); ++ ++} /* p2pFuncMgmtFrameRegister */ ++ ++VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter) ++{ ++ ++ do { ++ ++ prAdapter->rWifiVar.prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter; ++ ++ if ((prAdapter->u4OsPacketFilter & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) { ++ ++ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; ++ ++ prAdapter->u4OsPacketFilter |= (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RX_FILTER, ++ TRUE, ++ FALSE, ++ FALSE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(UINT_32), ++ (PUINT_8) &prAdapter->u4OsPacketFilter, &u4OsFilter, sizeof(u4OsFilter) ++ ); ++ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFuncUpdateMgmtFrameRegister */ ++ ++VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo) ++{ ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucMacAddr != NULL) && (prStaInfo != NULL)); ++ ++ prStaInfo->u4InactiveTime = 0; ++ prStaInfo->u4RxBytes = 0; ++ prStaInfo->u4TxBytes = 0; ++ prStaInfo->u4RxPackets = 0; ++ prStaInfo->u4TxPackets = 0; ++ /* TODO: */ ++ ++ } while (FALSE); ++ ++} /* p2pFuncGetStationInfo */ ++ ++BOOLEAN ++p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen) ++{ ++ BOOLEAN fgIsAllocMem = FALSE; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_16 u2Offset = 0; ++ P_IE_P2P_T prIe = (P_IE_P2P_T) NULL; ++ PUINT_8 pucAttriListStart = (PUINT_8) NULL; ++ UINT_16 u2AttriListLen = 0, u2BufferSize = 0; ++ BOOLEAN fgBackupAttributes = FALSE; ++ UINT_16 u2CopyLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucIE); ++ ASSERT(ppucAttriList); ++ ASSERT(pu2AttriListLen); ++ ++ if (ppucAttriList) ++ *ppucAttriList = NULL; ++ if (pu2AttriListLen) ++ *pu2AttriListLen = 0; ++ ++ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ aucWfaOui[0] = 0x00; ++ aucWfaOui[1] = 0x50; ++ aucWfaOui[2] = 0xF2; ++ } else if ((ucOuiType != VENDOR_OUI_TYPE_P2P) ++#if CFG_SUPPORT_WFD ++ && (ucOuiType != VENDOR_OUI_TYPE_WFD) ++#endif ++ ) { ++ DBGLOG(P2P, INFO, "Not supported OUI Type to parsing 0x%x\n", ucOuiType); ++ return fgIsAllocMem; ++ } ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_VENDOR != IE_ID(pucIE)) ++ continue; ++ ++ prIe = (P_IE_P2P_T) pucIE; ++ ++ if (prIe->ucLength <= P2P_OUI_TYPE_LEN) ++ continue; ++ ++ if ((prIe->aucOui[0] == aucWfaOui[0]) && ++ (prIe->aucOui[1] == aucWfaOui[1]) && ++ (prIe->aucOui[2] == aucWfaOui[2]) && (ucOuiType == prIe->ucOuiType)) { ++ ++ if (!pucAttriListStart) { ++ pucAttriListStart = &prIe->aucP2PAttributes[0]; ++ if (prIe->ucLength > P2P_OUI_TYPE_LEN) ++ u2AttriListLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); ++ else ++ ASSERT(FALSE); ++ continue; ++ } ++/* More than 2 attributes. */ ++ ++ if (FALSE == fgBackupAttributes) { ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = ++ prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ fgBackupAttributes = TRUE; ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[0], ++ pucAttriListStart, u2AttriListLen); ++ ++ pucAttriListStart = ++ &prP2pSpecificBssInfo->aucAttributesCache[0]; ++ ++ u2BufferSize = P2P_MAXIMUM_ATTRIBUTE_LEN; ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ kalMemCopy(&prP2pSpecificBssInfo->aucWscAttributesCache ++ [0], pucAttriListStart, u2AttriListLen); ++ pucAttriListStart = ++ &prP2pSpecificBssInfo->aucWscAttributesCache[0]; ++ ++ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; ++ } ++#if CFG_SUPPORT_WFD ++ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ PUINT_8 pucTmpBuf = (PUINT_8) NULL; ++ ++ pucTmpBuf = (PUINT_8) ++ kalMemAlloc(WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE, ++ VIR_MEM_TYPE); ++ ++ if (pucTmpBuf != NULL) { ++ fgIsAllocMem = TRUE; ++ } else { ++ /* Can't alloca memory for WFD IE relocate. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ kalMemCopy(pucTmpBuf, ++ pucAttriListStart, u2AttriListLen); ++ ++ pucAttriListStart = pucTmpBuf; ++ ++ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; ++ } ++#endif ++ else ++ fgBackupAttributes = FALSE; ++ } ++ ++ u2CopyLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); ++ ++ if ((u2AttriListLen + u2CopyLen) > u2BufferSize) { ++ u2CopyLen = u2BufferSize - u2AttriListLen; ++ DBGLOG(P2P, WARN, ++ "Length of received P2P attributes > maximum cache size.\n"); ++ } ++ ++ if (u2CopyLen) { ++ kalMemCopy((PUINT_8) ++ ((ULONG) pucAttriListStart + ++ (UINT_32) u2AttriListLen), ++ &prIe->aucP2PAttributes[0], u2CopyLen); ++ ++ u2AttriListLen += u2CopyLen; ++ } ++ } /* prIe->aucOui */ ++ } /* IE_FOR_EACH */ ++ ++ if (pucAttriListStart) { ++ PUINT_8 pucAttribute = pucAttriListStart; ++ ++ DBGLOG(P2P, LOUD, "Checking Attribute Length.\n"); ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ P2P_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset); ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ /* Do nothing */ ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ /* Big Endian: WSC, WFD. */ ++ WSC_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset) { ++ DBGLOG(P2P, LOUD, "Attribute ID:%d, Length:%d.\n", ++ WSC_ATTRI_ID(pucAttribute), WSC_ATTRI_LEN(pucAttribute)); ++ } ++ } else { ++ } ++ ++ ASSERT(u2Offset == u2AttriListLen); ++ ++ if (ppucAttriList) ++ *ppucAttriList = pucAttriListStart; ++ if (pu2AttriListLen) ++ *pu2AttriListLen = u2AttriListLen; ++ ++ } else { ++ if (ppucAttriList) ++ *ppucAttriList = (PUINT_8) NULL; ++ if (pu2AttriListLen) ++ *pu2AttriListLen = 0; ++ } ++ ++ return fgIsAllocMem; ++} /* p2pFuncGetAttriList */ ++ ++P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu) ++{ ++ P_MSDU_INFO_T prRetMsduInfo = prMgmtTxMsdu; ++ P_WLAN_PROBE_RSP_FRAME_T prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ UINT_16 u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0; ++ BOOLEAN fgIsP2PIE = FALSE, fgIsWSCIE = FALSE; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ UINT_16 u2EstimateSize = 0, u2EstimatedExtraIELen = 0; ++ UINT_32 u4IeArraySize = 0, u4Idx = 0; ++ UINT_8 ucOuiType = 0; ++ UINT_16 u2SubTypeVersion = 0; ++ ++ BOOLEAN fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ /* 3 Make sure this is probe response frame. */ ++ prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP); ++ ++ if (prP2pBssInfo->u2BeaconInterval) ++ prProbeRspFrame->u2BeaconInterval = prP2pBssInfo->u2BeaconInterval; ++ ++ /* 3 Get the importent P2P IE. */ ++ u2ProbeRspHdrLen = ++ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); ++ pucIEBuf = prProbeRspFrame->aucInfoElem; ++ u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen; ++ ++#if CFG_SUPPORT_WFD ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen = 0; ++#endif ++ ++ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { ++ switch (IE_ID(pucIEBuf)) { ++ case ELEM_ID_SSID: ++ { ++ ++ COPY_SSID(prP2pBssInfo->aucSSID, ++ prP2pBssInfo->ucSSIDLen, ++ SSID_IE(pucIEBuf)->aucSSID, SSID_IE(pucIEBuf)->ucLength); ++ } ++ break; ++ case ELEM_ID_VENDOR: ++#if !CFG_SUPPORT_WFD ++ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 2, pucIEBuf, ++ IE_SIZE(pucIEBuf)); ++ fgIsWSCIE = TRUE; ++ } ++ ++ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIEBuf, &ucOuiType)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ /* 2 Note(frog): I use WSC IE buffer for Probe Request to ++ * store the P2P IE for Probe Response. */ ++ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 1, pucIEBuf, ++ IE_SIZE(pucIEBuf)); ++ fgIsP2PIE = TRUE; ++ } ++ ++ } else { ++ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + ++ IE_SIZE(pucIEBuf)) < 512) { ++ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, ++ pucIEBuf, IE_SIZE(pucIEBuf)); ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += ++ IE_SIZE(pucIEBuf); ++ } ++ } ++#else ++ /* Eddie May be WFD */ ++ if (rsnParseCheckForWFAInfoElem ++ (prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_WMM) ++ break; ++ ++ } ++ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + IE_SIZE(pucIEBuf)) < ++ 1024) { ++ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE + ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen, pucIEBuf, ++ IE_SIZE(pucIEBuf)); ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf); ++ } ++#endif ++ break; ++ default: ++ break; ++ } ++ ++ } ++ ++ /* 3 Check the total size & current frame. */ ++ u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN + ++ TIMESTAMP_FIELD_LEN + ++ BEACON_INTERVAL_FIELD_LEN + ++ CAP_INFO_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET); ++ ++ u2EstimatedExtraIELen = 0; ++ ++ u4IeArraySize = sizeof(txProbeRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); ++ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { ++ if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) { ++ u2EstimatedExtraIELen += txProbeRspIETable[u4Idx].u2EstimatedFixedIELen; ++ } ++ ++ else { ++ ASSERT(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen); ++ ++ u2EstimatedExtraIELen += ++ (UINT_16) (txProbeRspIETable[u4Idx].pfnCalculateVariableIELen ++ (prAdapter, NETWORK_TYPE_P2P_INDEX, NULL)); ++ } ++ ++ } ++ ++ if (fgIsWSCIE) ++ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); ++ ++ if (fgIsP2PIE) { ++ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); ++ u2EstimatedExtraIELen += p2pFuncCalculateP2P_IE_NoA(prAdapter, 0, NULL); ++ } ++#if CFG_SUPPORT_WFD ++ u2EstimatedExtraIELen += prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; ++#endif ++ ++ u2EstimateSize += u2EstimatedExtraIELen; ++ if (u2EstimateSize > (prRetMsduInfo->u2FrameLength)) { ++ prRetMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimateSize); ++ ++ if (prRetMsduInfo == NULL) { ++ DBGLOG(P2P, WARN, "No packet for sending new probe response, use original one\n"); ++ prRetMsduInfo = prMgmtTxMsdu; ++ break; ++ } ++ ++ prRetMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ } ++ /* 3 Compose / Re-compose probe response frame. */ ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ++ ((ULONG) (prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prProbeRspFrame->aucDestAddr, prProbeRspFrame->aucSrcAddr, ++ prProbeRspFrame->aucBSSID, prProbeRspFrame->u2BeaconInterval, ++ fgIsPureAP ? prP2pBssInfo-> ++ u2CapInfo : prProbeRspFrame->u2CapInfo); ++ ++ prRetMsduInfo->u2FrameLength = ++ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); ++ ++ bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo, prP2pBssInfo, prProbeRspFrame->aucDestAddr); ++ ++ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { ++ if (txProbeRspIETable[u4Idx].pfnAppendIE) ++ txProbeRspIETable[u4Idx].pfnAppendIE(prAdapter, prRetMsduInfo); ++ ++ } ++ ++ if (fgIsWSCIE) { ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, ++ 2, ++ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + ++ (UINT_32) prRetMsduInfo->u2FrameLength)); ++ ++ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); ++ } ++ ++ if (fgIsP2PIE) { ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, ++ 1, ++ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + ++ (UINT_32) prRetMsduInfo->u2FrameLength)); ++ ++ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); ++ p2pFuncGenerateP2P_IE_NoA(prAdapter, prRetMsduInfo); ++ } ++#if CFG_SUPPORT_WFD ++ if (prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen > 0) { ++ kalMemCopy((PUINT_8) ((ULONG) prRetMsduInfo->prPacket + (UINT_32) prRetMsduInfo->u2FrameLength), ++ prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen); ++ prRetMsduInfo->u2FrameLength += (UINT_16) prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; ++ } ++#endif ++ ++ } while (FALSE); ++ ++ if (prRetMsduInfo != prMgmtTxMsdu) ++ cnmMgtPktFree(prAdapter, prMgmtTxMsdu); ++ ++ return prRetMsduInfo; ++} /* p2pFuncProcessP2pProbeRsp */ ++ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++UINT_32 ++p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ UINT_32 u4IELen = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ u4IELen = prP2pSpeBssInfo->u2IELenForBCN; ++ ++ } while (FALSE); ++ ++ return u4IELen; ++} /* p2pFuncCalculateP2p_IELenForBeacon */ ++ ++VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ pucIEBuf = (PUINT_8) ((UINT_32) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucBeaconIECache, prP2pSpeBssInfo->u2IELenForBCN); ++ ++ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN; ++ ++ } while (FALSE); ++ ++} /* p2pFuncGenerateExtra_IEForBeacon */ ++ ++#else ++UINT_32 ++p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ UINT_32 u4IELen = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); ++ ++ if (!prAdapter->fgIsP2PRegistered) ++ break; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ u4IELen = prP2pSpeBssInfo->u2AttributeLen; ++ ++ } while (FALSE); ++ ++ return u4IELen; ++} /* p2pFuncCalculateP2p_IELenForBeacon */ ++ ++VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ if (!prAdapter->fgIsP2PRegistered) ++ break; ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen); ++ ++ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen; ++ ++ } while (FALSE); ++ ++} /* p2pFuncGenerateP2p_IEForBeacon */ ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ ++ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++} /* p2pFuncCalculateP2p_IELenForBeacon */ ++ ++VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ UINT_16 u2IELen = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) ++ return; ++ ++ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ /* TODO: Check P2P FSM State. */ ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); ++ ++ prMsduInfo->u2FrameLength += u2IELen; ++ ++} /* p2pFuncGenerateP2p_IEForBeacon */ ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to calculate P2P IE length for Beacon frame. ++* ++* @param[in] eNetTypeIndex Specify which network ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return The length of P2P IE added ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ++p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ ++ return p2pFuncCalculateP2P_IELen(prAdapter, ++ eNetTypeIndex, ++ prStaRec, ++ txAssocRspAttributesTable, ++ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ ++} /* p2pFuncCalculateP2p_IELenForAssocRsp */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Beacon frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ if (!prStaRec) ++ break; ++ ++ if (IS_STA_P2P_TYPE(prStaRec)) { ++ DBGLOG(P2P, TRACE, "Generate NULL P2P IE for Assoc Rsp.\n"); ++ ++ p2pFuncGenerateP2P_IE(prAdapter, ++ TRUE, ++ &prMsduInfo->u2FrameLength, ++ prMsduInfo->prPacket, ++ 1500, ++ txAssocRspAttributesTable, ++ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ } else { ++ ++ DBGLOG(P2P, TRACE, "Legacy device, no P2P IE.\n"); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pFuncGenerateP2p_IEForAssocRsp */ ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ DBGLOG(P2P, TRACE, "p2pFuncCalculateWSC_IELenForAssocRsp\n"); ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ ++ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++} /* p2pFuncCalculateP2p_IELenForAssocRsp */ ++ ++VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ UINT_16 u2IELen = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) ++ return; ++ DBGLOG(P2P, TRACE, "p2pFuncGenerateWSC_IEForAssocRsp\n"); ++ ++ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ /* TODO: Check P2P FSM State. */ ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); ++ ++ prMsduInfo->u2FrameLength += u2IELen; ++ ++} ++ ++/* p2pFuncGenerateP2p_IEForAssocRsp */ ++ ++UINT_32 ++p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_STA_RECORD_T prStaRec, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) ++{ ++ ++ UINT_32 u4OverallAttriLen, u4Dummy; ++ UINT_16 u2EstimatedFixedAttriLen; ++ UINT_32 i; ++ ++ /* Overall length of all Attributes */ ++ u4OverallAttriLen = 0; ++ ++ for (i = 0; i < u4AttriTableSize; i++) { ++ u2EstimatedFixedAttriLen = arAppendAttriTable[i].u2EstimatedFixedAttriLen; ++ ++ if (u2EstimatedFixedAttriLen) { ++ u4OverallAttriLen += u2EstimatedFixedAttriLen; ++ } else { ++ ASSERT(arAppendAttriTable[i].pfnCalculateVariableAttriLen); ++ ++ u4OverallAttriLen += arAppendAttriTable[i].pfnCalculateVariableAttriLen(prAdapter, prStaRec); ++ } ++ } ++ ++ u4Dummy = u4OverallAttriLen; ++ u4OverallAttriLen += P2P_IE_OUI_HDR; ++ ++ for (; (u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) { ++ u4OverallAttriLen += P2P_IE_OUI_HDR; ++ u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN; ++ } ++ ++ return u4OverallAttriLen; ++} /* p2pFuncCalculateP2P_IELen */ ++ ++VOID ++p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) ++{ ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ P_IE_P2P_T prIeP2P = (P_IE_P2P_T) NULL; ++ UINT_32 u4OverallAttriLen; ++ UINT_32 u4AttriLen; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; ++ UINT_32 i; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ /* Check buffer length is still enough. */ ++ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR); ++ ++ prIeP2P = (P_IE_P2P_T) pucBuffer; ++ ++ prIeP2P->ucId = ELEM_ID_P2P; ++ ++ prIeP2P->aucOui[0] = aucWfaOui[0]; ++ prIeP2P->aucOui[1] = aucWfaOui[1]; ++ prIeP2P->aucOui[2] = aucWfaOui[2]; ++ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; ++ ++ (*pu2Offset) += P2P_IE_OUI_HDR; ++ ++ /* Overall length of all Attributes */ ++ u4OverallAttriLen = 0; ++ ++ for (i = 0; i < u4AttriTableSize; i++) { ++ ++ if (arAppendAttriTable[i].pfnAppendAttri) { ++ u4AttriLen = ++ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, ++ u2BufSize); ++ ++ u4OverallAttriLen += u4AttriLen; ++ ++ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { ++ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; ++ ++ prIeP2P->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); ++ ++ pucBuffer = ++ (PUINT_8) ((ULONG) prIeP2P + ++ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)); ++ ++ prIeP2P = (P_IE_P2P_T) ((ULONG) prIeP2P + ++ (ELEM_HDR_LEN + ++ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN))); ++ ++ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); ++ ++ prIeP2P->ucId = ELEM_ID_P2P; ++ ++ prIeP2P->aucOui[0] = aucWfaOui[0]; ++ prIeP2P->aucOui[1] = aucWfaOui[1]; ++ prIeP2P->aucOui[2] = aucWfaOui[2]; ++ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; ++ ++ kalMemCopy(prIeP2P->aucP2PAttributes, aucTempBuffer, u4OverallAttriLen); ++ (*pu2Offset) += P2P_IE_OUI_HDR; ++ } ++ ++ } ++ ++ } ++ ++ prIeP2P->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); ++ ++ } while (FALSE); ++ ++} /* p2pFuncGenerateP2P_IE */ ++ ++UINT_32 ++p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ PUINT_8 pucBuffer; ++ P_P2P_ATTRI_STATUS_T prAttriStatus; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_32 u4AttriLen = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucBuf); ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (fgIsAssocFrame) ++ return u4AttriLen; ++ /* TODO: For assoc request P2P IE check in driver & return status in P2P IE. */ ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT(pucBuffer); ++ prAttriStatus = (P_P2P_ATTRI_STATUS_T) pucBuffer; ++ ++ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); ++ ++ prAttriStatus->ucId = P2P_ATTRI_ID_STATUS; ++ WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS); ++ ++ prAttriStatus->ucStatusCode = P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR; ++ ++ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} /* p2pFuncAppendAttriStatusForAssocRsp */ ++ ++UINT_32 ++p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ P_P2P_ATTRI_EXT_LISTEN_TIMING_T prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ PUINT_8 pucBuffer = NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucBuf); ++ ++ if (fgIsAssocFrame) ++ return u4AttriLen; ++ /* TODO: For extend listen timing. */ ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); ++ ++ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT(pucBuffer); ++ ++ prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) pucBuffer; ++ ++ prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING; ++ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); ++ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, prP2pSpecificBssInfo->u2AvailabilityInterval); ++ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, prP2pSpecificBssInfo->u2AvailabilityPeriod); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} /* p2pFuncAppendAttriExtListenTiming */ ++ ++P_IE_HDR_T ++p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore) ++{ ++ P_IE_HDR_T prTargetIE = (P_IE_HDR_T) NULL; ++ PUINT_8 pucIE = (PUINT_8) NULL; ++ UINT_16 u2Offset = 0; ++ ++ if (pfgIsMore) ++ *pfgIsMore = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) ++ && (pucIEBuf != NULL)); ++ ++ pucIE = pucIEBuf; ++ ++ IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) { ++ if (IE_ID(pucIE) == ucElemID) { ++ if ((prTargetIE) && (pfgIsMore)) { ++ ++ *pfgIsMore = TRUE; ++ break; ++ } ++ prTargetIE = (P_IE_HDR_T) pucIE; ++ ++ if (pfgIsMore == NULL) ++ break; ++ ++ } ++ } ++ ++ } while (FALSE); ++ ++ return prTargetIE; ++} /* p2pFuncGetSpecIE */ ++ ++P_ATTRIBUTE_HDR_T ++p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID) ++{ ++ P_IE_P2P_T prP2pIE = (P_IE_P2P_T) NULL; ++ P_ATTRIBUTE_HDR_T prTargetAttri = (P_ATTRIBUTE_HDR_T) NULL; ++ BOOLEAN fgIsMore = FALSE; ++ PUINT_8 pucIE = (PUINT_8) NULL, pucAttri = (PUINT_8) NULL; ++ UINT_16 u2OffsetAttri = 0; ++ UINT_16 u2BufferLenLeft = 0; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ ++ DBGLOG(P2P, INFO, "Check AssocReq Oui type %u attri %u for len %u\n", ucOuiType, u2AttriID, u2BufferLen); ++ ++ ASSERT(prAdapter); ++ ASSERT(pucIEBuf); ++ ++ u2BufferLenLeft = u2BufferLen; ++ pucIE = pucIEBuf; ++ do { ++ fgIsMore = FALSE; ++ prP2pIE = (P_IE_P2P_T) p2pFuncGetSpecIE(prAdapter, ++ pucIE, u2BufferLenLeft, ELEM_ID_VENDOR, &fgIsMore); ++ if (prP2pIE == NULL) ++ continue; ++ ++ ASSERT((ULONG) prP2pIE >= (ULONG) pucIE); ++ ++ u2BufferLenLeft = u2BufferLen - (UINT_16) (((ULONG) prP2pIE) - ((ULONG) pucIEBuf)); ++ ++ DBGLOG(P2P, INFO, "Find vendor id %u len %u oui %u more %u LeftLen %u\n", ++ IE_ID(prP2pIE), IE_LEN(prP2pIE), prP2pIE->ucOuiType, fgIsMore, ++ u2BufferLenLeft); ++ ++ if ((IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) && (prP2pIE->ucOuiType == ucOuiType)) { ++ switch (ucOuiType) { ++ case VENDOR_OUI_TYPE_WPS: ++ aucWfaOui[0] = 0x00; ++ aucWfaOui[1] = 0x50; ++ aucWfaOui[2] = 0xF2; ++ break; ++ case VENDOR_OUI_TYPE_P2P: ++ break; ++ case VENDOR_OUI_TYPE_WPA: ++ case VENDOR_OUI_TYPE_WMM: ++ case VENDOR_OUI_TYPE_WFD: ++ default: ++ break; ++ } ++ ++ if ((prP2pIE->aucOui[0] != aucWfaOui[0]) ++ || (prP2pIE->aucOui[1] != aucWfaOui[1]) ++ || (prP2pIE->aucOui[2] != aucWfaOui[2])) ++ continue; ++ ++ u2OffsetAttri = 0; ++ pucAttri = prP2pIE->aucP2PAttributes; ++ ++ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ WSC_ATTRI_FOR_EACH(pucAttri, ++ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { ++ /* LOG_FUNC("WSC: attri id=%u len=%u\n", ++ * WSC_ATTRI_ID(pucAttri), ++ * WSC_ATTRI_LEN(pucAttri)); */ ++ if (WSC_ATTRI_ID(pucAttri) == u2AttriID) { ++ prTargetAttri = ++ (P_ATTRIBUTE_HDR_T) pucAttri; ++ break; ++ } ++ } ++ ++ } else if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ P2P_ATTRI_FOR_EACH(pucAttri, ++ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { ++ /* LOG_FUNC("P2P: attri id=%u len=%u\n", ++ * ATTRI_ID(pucAttri), ATTRI_LEN(pucAttri)); */ ++ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { ++ prTargetAttri = (P_ATTRIBUTE_HDR_T) pucAttri; ++ break; ++ } ++ } ++ } ++#if CFG_SUPPORT_WFD ++ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ WFD_ATTRI_FOR_EACH(pucAttri, ++ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { ++ /* DBGLOG(P2P, INFO, ("WFD: attri id=%u ++ * len=%u\n",WFD_ATTRI_ID(pucAttri), ++ * WFD_ATTRI_LEN(pucAttri))); */ ++ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { ++ prTargetAttri = ++ (P_ATTRIBUTE_HDR_T) pucAttri; ++ break; ++ } ++ } ++ } ++#endif ++ /* Do nothing */ ++ /* Possible or else. */ ++ } /* ucOuiType */ ++ /* P2P_OUI_TYPE_LEN */ ++ pucIE = (PUINT_8) (((ULONG) prP2pIE) + IE_SIZE(prP2pIE)); ++ /* prP2pIE */ ++ } while (prP2pIE && fgIsMore && u2BufferLenLeft); ++ ++ return prTargetAttri; ++} ++ ++/* p2pFuncGetSpecAttri */ ++ ++WLAN_STATUS ++p2pFuncGenerateBeaconProbeRsp(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgIsProbeRsp) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++/* P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = (P_APPEND_VAR_IE_ENTRY_T)NULL; */ ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL) && (prMsduInfo != NULL)); ++ ++/* txBcnIETable */ ++ ++/* txProbeRspIETable */ ++ ++ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; ++ ++ return nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ NETWORK_TYPE_P2P_INDEX, ++ prBssInfo->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, ++ aucInfoElem)); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncGenerateBeaconProbeRsp */ ++ ++WLAN_STATUS ++p2pFuncComposeBeaconProbeRspTemplate(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBcnBuffer, ++ IN UINT_32 u4BcnBufLen, ++ IN BOOLEAN fgIsProbeRsp, ++ IN P_P2P_PROBE_RSP_UPDATE_INFO_T prP2pProbeRspInfo, IN BOOLEAN fgSynToFW) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_WLAN_MAC_HEADER_T prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBcnBuffer != NULL)); ++ ++ prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) pucBcnBuffer; ++ ++ if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) && (!fgIsProbeRsp)) { ++ rWlanStatus = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) { ++ rWlanStatus = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ if (fgIsProbeRsp) { ++ ASSERT_BREAK(prP2pProbeRspInfo != NULL); ++ ++ if (prP2pProbeRspInfo->prProbeRspMsduTemplate) ++ cnmMgtPktFree(prAdapter, prP2pProbeRspInfo->prProbeRspMsduTemplate); ++ ++ prP2pProbeRspInfo->prProbeRspMsduTemplate = cnmMgtPktAlloc(prAdapter, u4BcnBufLen); ++ ++ prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate; ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucStaRecIndex = 0xFF; ++ prMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ ++ } else { ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prMsduInfo = prP2pBssInfo->prBeacon; ++ ++ if (prMsduInfo == NULL) { ++ rWlanStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++ if (u4BcnBufLen > (OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH)) { ++ /* Unexpected error, buffer overflow. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen); ++ ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = (UINT_16) u4BcnBufLen; ++ ++ if (fgSynToFW && prP2pBssInfo) ++ rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, prP2pBssInfo, prMsduInfo, fgIsProbeRsp); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++ ++} /* p2pFuncComposeBeaconTemplate */ ++ ++#if CFG_SUPPORT_WFD ++WLAN_STATUS wfdAdjustResource(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) ++{ ++#if 1 ++ /* The API shall be called in tx_thread */ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); ++ if (fgEnable) { ++ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; ++ if (QM_GUARANTEED_TC0_RESOURCE > 2) { ++ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE - 2; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; ++ } ++ if (QM_GUARANTEED_TC1_RESOURCE > 2) { ++ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE - 2; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; ++ } ++ } else { ++ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS wfdAdjustThread(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) ++{ ++#define WFD_TX_THREAD_PRIORITY 70 ++ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); ++ if (prAdapter->prGlueInfo->main_thread != NULL) { ++ if (fgEnable) { ++#ifdef LINUX ++ /* TODO the change schedule API shall be provided by OS glue layer */ ++ /* Or the API shall be put in os glue layer */ ++ struct sched_param param = {.sched_priority = WFD_TX_THREAD_PRIORITY }; ++ ++ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_RR, ¶m); ++#endif ++ } else { ++#ifdef LINUX ++ /* TODO the change schedule API shall be provided by OS glue layer */ ++ struct sched_param param = {.sched_priority = 0 }; ++ ++ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_NORMAL, ¶m); ++#endif ++ } ++ } else { ++ ++ DBGLOG(P2P, WARN, "main_thread is null, please check if the wlanRemove is called in advance\n"); ++ } ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#endif /* CFG_SUPPORT_WFD */ ++ ++WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ENUM_PARAM_MEDIA_STATE_T eConnectionState) ++{ ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ if (prAdapter->fgIsP2PRegistered == FALSE) ++ return WLAN_STATUS_SUCCESS; ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ ++ if ((prWfdCfgSettings->ucWfdEnable) && ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == ++ PARAM_MEDIA_STATE_CONNECTED) { ++ wfdAdjustResource(prAdapter, TRUE); ++ wfdAdjustThread(prAdapter, TRUE); ++ } else { ++ wfdAdjustResource(prAdapter, FALSE); ++ wfdAdjustThread(prAdapter, FALSE); ++ } ++ ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c +new file mode 100644 +index 000000000000..991861f73608 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c +@@ -0,0 +1,612 @@ ++#include "p2p_precomp.h" ++ ++#if CFG_SUPPORT_WFD ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++#if 0 ++APPEND_VAR_ATTRI_ENTRY_T txProbeRspWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_EXT_CAPABILITY), NULL, wfdFuncAppendAttriExtCapability} /* 7 */ ++ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ ++}; ++ ++APPEND_VAR_ATTRI_ENTRY_T txBeaconWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++}; ++ ++APPEND_VAR_ATTRI_ENTRY_T txAssocReqWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++}; ++#endif ++ ++APPEND_VAR_ATTRI_ENTRY_T txAssocRspWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ ++ ++}; ++ ++#endif ++ ++UINT_32 ++p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; ++ UINT_32 u4RetValue = 0; ++ ++ do { ++ ASSERT_BREAK((eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) && (prAdapter != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ ++ u4RetValue = prConnReqInfo->u4BufLength; ++ ++ /* ADD HT Capability */ ++ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP); ++ ++ /* ADD WMM Information Element */ ++ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO); ++ ++ } while (FALSE); ++ ++ return u4RetValue; ++} /* p2pCalculate_IEForAssocReq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Beacon frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ ++ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, prConnReqInfo->u4BufLength); ++ ++ prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength; ++ ++ rlmReqGenerateHtCapIE(prAdapter, prMsduInfo); ++ mqmGenerateWmmInfoIE(prAdapter, prMsduInfo); ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pGenerate_IEForAssocReq */ ++ ++UINT_32 ++wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_DEVICE_INFORMATION_IE_T prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) pucBuffer; ++ ++ prWfdDevInfo->ucElemID = WFD_ATTRI_ID_DEV_INFO; ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevInfo, prWfdCfgSettings->u2WfdDevInfo); ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2SessionMgmtCtrlPort, prWfdCfgSettings->u2WfdControlPort); ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevMaxSpeed, prWfdCfgSettings->u2WfdMaximumTp); ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2Length, WFD_ATTRI_MAX_LEN_DEV_INFO); ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_DEV_INFO + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriDevInfo */ ++ ++UINT_32 ++wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_ASSOCIATED_BSSID_IE_T prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_BSS_INFO_T prAisBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if (prWfdCfgSettings->ucWfdEnable == 0) ++ break; ++ ++ /* AIS network. */ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if ((!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) || ++ (prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) pucBuffer; ++ ++ prWfdAssocBssid->ucElemID = WFD_ATTRI_ID_ASSOC_BSSID; ++ ++ WLAN_SET_FIELD_BE16(&prWfdAssocBssid->u2Length, WFD_ATTRI_MAX_LEN_ASSOC_BSSID); ++ ++ COPY_MAC_ADDR(prWfdAssocBssid->aucAssocBssid, prAisBssInfo->aucBSSID); ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_ASSOC_BSSID + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriAssocBssid */ ++ ++UINT_32 ++wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_COUPLE_SINK_INFORMATION_IE_T prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_SINK_INFO_VALID) == 0)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) pucBuffer; ++ ++ prWfdCoupleSinkInfo->ucElemID = WFD_ATTRI_ID_COUPLED_SINK_INFO; ++ ++ WLAN_SET_FIELD_BE16(&prWfdCoupleSinkInfo->u2Length, WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO); ++ ++ COPY_MAC_ADDR(prWfdCoupleSinkInfo->aucCoupleSinkMac, prWfdCfgSettings->aucWfdCoupleSinkAddress); ++ ++ prWfdCoupleSinkInfo->ucCoupleSinkStatusBp = prWfdCfgSettings->ucWfdCoupleSinkStatus; ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriCoupledSinkInfo */ ++ ++UINT_32 ++wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_EXTENDED_CAPABILITY_IE_T prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_EXT_CAPABILITY_VALID) == 0)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) pucBuffer; ++ ++ prWfdExtCapability->ucElemID = WFD_ATTRI_ID_EXT_CAPABILITY; ++ ++ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2Length, WFD_ATTRI_MAX_LEN_EXT_CAPABILITY); ++ ++ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2WfdExtCapabilityBp, prWfdCfgSettings->u2WfdExtendCap); ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_EXT_CAPABILITY + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriExtCapability */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to calculate length of Channel List Attribute ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return The length of Attribute added ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ UINT_16 u2AttriLen = 0; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ if (prWfdCfgSettings->ucWfdEnable == 0) ++ break; ++ ++ u2AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ return (UINT_32) u2AttriLen; ++ ++} /* wfdFuncCalculateAttriLenSessionInfo */ ++ ++UINT_32 ++wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_SESSION_INFORMATION_IE_T prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || (prWfdCfgSettings->u2WfdSessionInformationIELen == 0)) ++ break; ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) pucBuffer; ++ ++ prWfdSessionInfo->ucElemID = WFD_ATTRI_ID_SESSION_INFO; ++ ++ /* TODO: Check endian issue? */ ++ kalMemCopy(prWfdSessionInfo->pucWfdDevInfoDesc, prWfdCfgSettings->aucWfdSessionInformationIE, ++ prWfdCfgSettings->u2WfdSessionInformationIELen); ++ ++ WLAN_SET_FIELD_16(&prWfdSessionInfo->u2Length, prWfdCfgSettings->u2WfdSessionInformationIELen); ++ ++ u4AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriSessionInfo */ ++ ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++VOID ++wfdFuncGenerateWfd_IE(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) ++{ ++ ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ P_IE_WFD_T prIeWFD = (P_IE_WFD_T) NULL; ++ UINT_32 u4OverallAttriLen; ++ UINT_32 u4AttriLen; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; ++ UINT_32 i; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ /* Check buffer length is still enough. */ ++ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= WFD_IE_OUI_HDR); ++ ++ prIeWFD = (P_IE_WFD_T) pucBuffer; ++ ++ prIeWFD->ucId = ELEM_ID_WFD; ++ ++ prIeWFD->aucOui[0] = aucWfaOui[0]; ++ prIeWFD->aucOui[1] = aucWfaOui[1]; ++ prIeWFD->aucOui[2] = aucWfaOui[2]; ++ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; ++ ++ (*pu2Offset) += WFD_IE_OUI_HDR; ++ ++ /* Overall length of all Attributes */ ++ u4OverallAttriLen = 0; ++ ++ for (i = 0; i < u4AttriTableSize; i++) { ++ ++ if (arAppendAttriTable[i].pfnAppendAttri) { ++ u4AttriLen = ++ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, ++ u2BufSize); ++ ++ u4OverallAttriLen += u4AttriLen; ++ ++ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { ++ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; ++ ++ prIeWFD->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); ++ ++ pucBuffer = ++ (PUINT_8) ((ULONG) prIeWFD + (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); ++ ++ prIeWFD = ++ (P_IE_WFD_T) ((ULONG) prIeWFD + ++ (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); ++ ++ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); ++ ++ prIeWFD->ucId = ELEM_ID_WFD; ++ ++ prIeWFD->aucOui[0] = aucWfaOui[0]; ++ prIeWFD->aucOui[1] = aucWfaOui[1]; ++ prIeWFD->aucOui[2] = aucWfaOui[2]; ++ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; ++ ++ kalMemCopy(prIeWFD->aucWFDAttributes, aucTempBuffer, u4OverallAttriLen); ++ (*pu2Offset) += WFD_IE_OUI_HDR; ++ } ++ ++ } ++ ++ } ++ ++ prIeWFD->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); ++ ++ } while (FALSE); ++ ++} /* wfdFuncGenerateWfd_IE */ ++ ++#endif /* CFG_SUPPORT_WFD_COMPOSE_IE */ ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ if (!IS_STA_P2P_TYPE(prStaRec) || (prWfdCfgSettings->ucWfdEnable == 0)) ++ return 0; ++ ++ return p2pFuncCalculateP2P_IELen(prAdapter, ++ eNetTypeIndex, ++ prStaRec, ++ txAssocRspWFDAttributesTable, ++ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ ++#else ++ return 0; ++#endif ++} /* wfdFuncCalculateWfdIELenForAssocRsp */ ++ ++VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_STA_RECORD_T prStaRec; ++ ++ do { ++ ASSERT_BREAK((prMsduInfo != NULL) && (prAdapter != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) { ++ ASSERT(FALSE); ++ } else if (IS_STA_P2P_TYPE(prStaRec)) { ++ ++ if (prWfdCfgSettings->ucWfdEnable == 0) ++ break; ++ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0) ++ break; ++ ++ wfdFuncGenerateWfd_IE(prAdapter, ++ FALSE, ++ &prMsduInfo->u2FrameLength, ++ prMsduInfo->prPacket, ++ 1500, ++ txAssocRspWFDAttributesTable, ++ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ } ++ } while (FALSE); ++ ++ return; ++#else ++ ++ return; ++#endif ++} /* wfdFuncGenerateWfdIEForAssocRsp */ ++ ++VOID p2pFuncComposeNoaAttribute(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ ++ P_IE_P2P_T prIeP2P; ++ P_P2P_ATTRI_NOA_T prNoaAttr = NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; ++ P_NOA_DESCRIPTOR_T prNoaDesc = NULL; ++ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_32 u4AttributeLen; ++ UINT_32 u4NumOfNoaDesc = 0; ++ UINT_32 i = 0; ++ /*P2P IE format */ ++ prIeP2P = (P_IE_P2P_T) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ prIeP2P->ucId = ELEM_ID_P2P; ++ prIeP2P->aucOui[0] = aucWfaOui[0]; ++ prIeP2P->aucOui[1] = aucWfaOui[1]; ++ prIeP2P->aucOui[2] = aucWfaOui[2]; ++ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ /*P2P Attribute--NoA */ ++ prNoaAttr = (P_P2P_ATTRI_NOA_T) prIeP2P->aucP2PAttributes; ++ ++ prNoaAttr->ucId = P2P_ATTRI_ID_NOTICE_OF_ABSENCE; ++ prNoaAttr->ucIndex = prP2pSpecificBssInfo->ucNoAIndex; ++ /*OPP*/ if (prP2pSpecificBssInfo->fgEnableOppPS) { ++ prNoaAttr->ucCTWOppPSParam = P2P_CTW_OPPPS_PARAM_OPPPS_FIELD | ++ (prP2pSpecificBssInfo->u2CTWindow & P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK); ++ } else { ++ prNoaAttr->ucCTWOppPSParam = 0; ++ } ++ /*NoA Description */ ++ DBGLOG(P2P, INFO, "Compose NoA count=%d.\n", prP2pSpecificBssInfo->ucNoATimingCount); ++ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { ++ if (prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse) { ++ ++ prNoaDesc = (P_NOA_DESCRIPTOR_T) &prNoaAttr->aucNoADesc[u4NumOfNoaDesc]; ++ ++ prNoaDesc->ucCountType = prP2pSpecificBssInfo->arNoATiming[i].ucCount; ++ prNoaDesc->u4Duration = prP2pSpecificBssInfo->arNoATiming[i].u4Duration; ++ prNoaDesc->u4Interval = prP2pSpecificBssInfo->arNoATiming[i].u4Interval; ++ prNoaDesc->u4StartTime = prP2pSpecificBssInfo->arNoATiming[i].u4StartTime; ++ ++ u4NumOfNoaDesc++; ++ } ++ } ++ ++ /* include "index" + "OppPs Params" + "NOA descriptors" */ ++ prNoaAttr->u2Length = 2 + u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T); ++ u4NumOfNoaDesc++; ++ ++ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ ++ u4AttributeLen = P2P_ATTRI_HDR_LEN + prNoaAttr->u2Length; ++ ++ prIeP2P->ucLength = VENDOR_OUI_TYPE_LEN + u4AttributeLen; ++ prMsduInfo->u2FrameLength += (ELEM_HDR_LEN + prIeP2P->ucLength); ++ ++} ++ ++UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; ++ UINT_8 ucIdx; ++ UINT_32 u4NumOfNoaDesc = 0; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ return 0; ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ for (ucIdx = 0; ucIdx < prP2pSpecificBssInfo->ucNoATimingCount; ucIdx++) { ++ if (prP2pSpecificBssInfo->arNoATiming[ucIdx].fgIsInUse) ++ u4NumOfNoaDesc++; ++ } ++ ++ /* include "index" + "OppPs Params" + "NOA descriptors" */ ++ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ ++ ++ return P2P_ATTRI_LEN_NOTICE_OF_ABSENCE + (u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T)); ++} ++ ++VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { /* Hotspot */ ++ return; ++ } ++ ++ /* Compose NoA attribute */ ++ p2pFuncComposeNoaAttribute(prAdapter, ++ prMsduInfo /*prMsduInfo->ucBssIndex, prIeP2P->aucP2PAttributes, &u4AttributeLen */); ++ ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c +new file mode 100644 +index 000000000000..f25df82d9ca7 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c +@@ -0,0 +1,905 @@ ++/* ++** Id: @(#) p2p_rlm.c@@ ++*/ ++ ++/*! \file "p2p_rlm.c" ++ \brief ++ ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Init AP Bss ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ENUM_BAND_T eBand; ++ UINT_8 ucChannel; ++ ENUM_CHNL_EXT_T eSCO; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ++ return; ++ ++ /* Operation band, channel shall be ready before invoking this function. ++ * Bandwidth may be ready if other network is connected ++ */ ++ prBssInfo->fg40mBwAllowed = FALSE; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ prBssInfo->eBssSCO = CHNL_EXT_SCN; ++ ++ if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) { ++ /* In this case, the first BSS's SCO is 40MHz and known, so AP can ++ * apply 40MHz bandwidth, but the first BSS's SCO may be changed ++ * later if its Beacon lost timeout occurs ++ */ ++ if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) && ++ eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) { ++ prBssInfo->eBssSCO = eSCO; ++ } else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) { ++ prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo); ++ } ++ ++ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { ++ prBssInfo->fg40mBwAllowed = TRUE; ++ prBssInfo->fgAssoc40mBwAllowed = TRUE; ++ ++ prBssInfo->ucHtOpInfo1 = (UINT_8) ++ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); ++ ++ rlmUpdateBwByChListForAP(prAdapter, prBssInfo); ++ } ++ } ++ ++ DBGLOG(RLM, INFO, "WLAN AP SCO=%d\n", prBssInfo->eBssSCO); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_IE_OBSS_SCAN_PARAM_T prObssScanIe; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) && ++ prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) && ++ prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) { ++ ++ prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ /* Add 20/40 BSS coexistence IE */ ++ prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS; ++ prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN; ++ ++ prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell; ++ prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell; ++ prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval; ++ prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel; ++ prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel; ++ prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor; ++ prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold; ++ ++ ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P GO. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ UINT_8 ucLevel; ++ BOOLEAN fgBwChange; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ fgBwChange = FALSE; ++ ++ if (prBssInfo->eBssSCO == CHNL_EXT_SCN) ++ return fgBwChange; ++ ++ ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO); ++ ++ if (ucLevel == CHNL_LEVEL0) { ++ /* Forced to 20MHz, so extended channel is SCN and STA width is zero */ ++ prBssInfo->fgObssActionForcedTo20M = TRUE; ++ ++ if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) { ++ prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; ++ fgBwChange = TRUE; ++ } ++ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC); ++ } ++ ++ /* Clear up all channel lists */ ++ prBssInfo->auc2G_20mReqChnlList[0] = 0; ++ prBssInfo->auc2G_NonHtChnlList[0] = 0; ++ prBssInfo->auc2G_PriChnlList[0] = 0; ++ prBssInfo->auc2G_SecChnlList[0] = 0; ++ prBssInfo->auc5G_20mReqChnlList[0] = 0; ++ prBssInfo->auc5G_NonHtChnlList[0] = 0; ++ prBssInfo->auc5G_PriChnlList[0] = 0; ++ prBssInfo->auc5G_SecChnlList[0] = 0; ++ ++ return fgBwChange; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_20_40_COEXIST_FRAME prRxFrame; ++ P_IE_20_40_COEXIST_T prCoexist; ++ P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport; ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength, u2Offset; ++ UINT_8 i, j; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST || ++ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || ++ prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) || ++ HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != NETWORK_TYPE_P2P_INDEX) { ++ return; ++ } ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ASSERT(prBssInfo); ++ ++ if (!IS_BSS_ACTIVE(prBssInfo) || ++ prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) { ++ return; ++ } ++ ++ prCoexist = &prRxFrame->rBssCoexist; ++ if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) { ++ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel; ++ prBssInfo->auc2G_20mReqChnlList[0]++; ++ } ++ } ++ ++ /* Process intolerant channel report IE */ ++ pucIE = (PUINT_8) &prRxFrame->rChnlReport; ++ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5); ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT: ++ prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE; ++ ++ if (prChnlReport->ucLength <= 1) ++ break; ++ ++ /* To do: process regulatory class. Now we assume 2.4G band */ ++ ++ for (j = 0; j < prChnlReport->ucLength - 1; j++) { ++ /* Update non-HT channel list */ ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j]) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j]; ++ prBssInfo->auc2G_NonHtChnlList[0]++; ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) { ++ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); ++ rlmSyncOperationParams(prAdapter, prBssInfo); ++ } ++ ++ /* Check if OBSS scan exemption response should be sent */ ++ if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) ++ rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH || ++ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || ++ prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) { ++ return; ++ } ++ ++ /* To do: depending regulation class 13 and 14 based on spec ++ * Note: (ucChannelWidth==1) shall restored back to original capability, ++ * not current setting to 40MHz BW here ++ */ ++ if (prRxFrame->ucChannelWidth == 0) ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; ++ else if (prRxFrame->ucChannelWidth == 1) ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prObssStatus); ++ ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex]; ++ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); ++ ++ prBssInfo->fgObssErpProtectMode = (BOOLEAN) prObssStatus->ucObssErpProtectMode; ++ prBssInfo->eObssHtProtectMode = (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode; ++ prBssInfo->eObssGfOperationMode = (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode; ++ prBssInfo->fgObssRifsOperationMode = (BOOLEAN) prObssStatus->ucObssRifsOperationMode; ++ prBssInfo->fgObssBeaconForcedTo20M = (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M; ++ ++ /* Check if Beacon content need to be updated */ ++ rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon) ++{ ++ P_LINK_T prStaList; ++ P_STA_RECORD_T prStaRec; ++ BOOLEAN fgErpProtectMode, fgSta40mIntolerant; ++ BOOLEAN fgUseShortPreamble, fgUseShortSlotTime; ++ ENUM_HT_PROTECT_MODE_T eHtProtectMode; ++ ENUM_GF_MODE_T eGfOperationMode; ++ UINT_8 ucHtOpInfo1; ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ P_GLUE_INFO_T prGlueInfo; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ++ return; ++ ++ fgErpProtectMode = FALSE; ++ eHtProtectMode = HT_PROTECT_MODE_NONE; ++ eGfOperationMode = GF_MODE_NORMAL; ++ fgSta40mIntolerant = FALSE; ++ fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; ++ fgUseShortSlotTime = TRUE; ++ ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; ++ ++ prStaList = &prBssInfo->rStaRecOfClientList; ++ ++ LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) { ++ /* ASSERT(prStaRec); */ ++ if (!prStaRec) { ++ DBGLOG(P2P, TRACE, "prStaRec is NULL in rlmUpdateParamsForAP()\n"); ++ break; ++ } ++ if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 && ++ prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) { ++ if (!(prStaRec->ucPhyTypeSet & (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) { ++ /* B-only mode, so mode 1 (ERP protection) */ ++ fgErpProtectMode = TRUE; ++ } ++ ++ if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { ++ /* BG-only or A-only */ ++ eHtProtectMode = HT_PROTECT_MODE_NON_HT; ++ } else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) { ++ /* 20MHz-only */ ++ /* ++ The HT Protection field may be set to 20 MHz protection ++ mode only if the following are true: ++ \A1X All STAs detected (by any means) in the primary channel ++ and all STAs detected (by any means) in the secondary ++ channel are HT STAs and all STAs that are members of ++ this BSS are HT STAs, and ++ \A1X This BSS is a 20/40 MHz BSS, and ++ \A1X There is at least one 20 MHz HT STA associated with this BSS. ++ */ ++ if (eHtProtectMode == HT_PROTECT_MODE_NONE && prBssInfo->fgAssoc40mBwAllowed) ++ eHtProtectMode = HT_PROTECT_MODE_20M; ++ } ++ ++ if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) ++ eGfOperationMode = GF_MODE_PROTECT; ++ ++ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) ++ fgUseShortPreamble = FALSE; ++ ++ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) ++ fgUseShortSlotTime = FALSE; ++ ++ if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) ++ fgSta40mIntolerant = TRUE; ++ } ++ } /* end of LINK_FOR_EACH_ENTRY */ ++ ++ /* Check if HT operation IE about 20/40M bandwidth shall be updated */ ++ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { ++ if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant && ++ !prBssInfo->fgObssActionForcedTo20M && !prBssInfo->fgObssBeaconForcedTo20M) { ++ ++ ucHtOpInfo1 = (UINT_8) ++ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); ++ } ++ } ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ prGlueInfo = prAdapter->prGlueInfo; ++ if (prGlueInfo->prP2PInfo->u4PsLevel & BITS(8, 15)) ++ fgErpProtectMode = TRUE; ++#endif ++ ++ /* Check if any new parameter may be updated */ ++ if (prBssInfo->fgErpProtectMode != fgErpProtectMode || ++ prBssInfo->eHtProtectMode != eHtProtectMode || ++ prBssInfo->eGfOperationMode != eGfOperationMode || ++ prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 || ++ prBssInfo->fgUseShortPreamble != fgUseShortPreamble || ++ prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) { ++ ++ prBssInfo->fgErpProtectMode = fgErpProtectMode; ++ prBssInfo->eHtProtectMode = eHtProtectMode; ++ prBssInfo->eGfOperationMode = eGfOperationMode; ++ prBssInfo->ucHtOpInfo1 = ucHtOpInfo1; ++ prBssInfo->fgUseShortPreamble = fgUseShortPreamble; ++ prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime; ++ ++ if (fgUseShortSlotTime) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ else ++ prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; ++ ++ rlmSyncOperationParams(prAdapter, prBssInfo); ++ fgUpdateBeacon = TRUE; ++ } ++ ++ /* Update Beacon content if related IE content is changed */ ++ if (fgUpdateBeacon) ++ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Initial the channel list from the domain information. ++* This function is called after P2P initial and Domain information changed. ++* Make sure the device is disconnected while changing domain information. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return boolean value if probe response frame is ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY) NULL; ++ P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO) NULL; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ UINT_32 u4Idx = 0, u4IdxII = 0; ++ UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE; ++#if 0 ++ UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0; ++#endif ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++#if 0 ++ ucAutoChnl = prP2pConnSetting->ucOperatingChnl; ++#endif ++ ++ prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter); ++ ++ ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL)); ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) { ++ prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx]; ++ ++ if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) || ++ (prDomainSubBand->ucBand == BAND_NULL)) { ++ continue; ++ } ++ ++ if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) { ++ /* Buffer is not enough to include all supported channels. */ ++ break; /* for */ ++ } ++ ++ prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass; ++ prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels; ++ ++ for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) { ++ prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum + ++ (u4IdxII * prDomainSubBand->ucChannelSpan); ++ ++#if 0 ++ switch (prChannelEntryField->aucChannelList[u4IdxII]) { ++ case 1: ++ ucSocialChnlSupport = 1; ++ break; ++ case 6: ++ ucSocialChnlSupport = 6; ++ break; ++ case 11: ++ ucSocialChnlSupport = 11; ++ break; ++ default: ++ break; ++ } ++ ++#endif ++ } ++ ++ if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels)) ++ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); ++ else ++ break; ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) ++ prChannelEntryField->ucNumberOfChannels); ++ ++ } ++ ++#if 0 ++ if (prP2pConnSetting->ucListenChnl == 0) { ++ prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL; ++ ++ if (ucSocialChnlSupport != 0) { ++ /* 1. User Not Set LISTEN channel. ++ * 2. Social channel is not empty. ++ */ ++ prP2pConnSetting->ucListenChnl = ucSocialChnlSupport; ++ } ++ } ++#endif ++ ++ /* TODO: 20110921 frog - */ ++ /* If LISTEN channel is not set, ++ * a random supported channel would be set. ++ * If no social channel is supported, DEFAULT channel would be set. ++ */ ++ ++ prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize; ++ ++#if 0 ++ if (prP2pConnSetting->ucOperatingChnl == 0) { /* User not set OPERATE channel. */ ++ ++ if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) ++ break; /* while */ ++ ++ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ while (ucBufferSize != 0) { ++ if (prChannelEntryField->ucNumberOfChannels != 0) { ++ ucAutoChnl = prChannelEntryField->aucChannelList[0]; ++ break; /* while */ ++ } ++ ++ else { ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((UINT_32) prChannelEntryField + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (UINT_32)prChannelEntryField->ucNumberOfChannels); ++ ++ ucBufferSize -= ++ (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); ++ } ++ ++ } ++ ++ } ++#endif ++ /* We assume user would not set a channel not in the channel list. ++ * If so, the operating channel still depends on target device supporting capability. ++ */ ++ ++ /* TODO: 20110921 frog - */ ++ /* If the Operating channel is not set, a channel from supported channel list is set automatically. ++ * If there is no supported channel in channel list, a DEFAULT channel is set. ++ */ ++ ++ } while (FALSE); ++ ++#if 0 ++ prP2pConnSetting->ucOperatingChnl = ucAutoChnl; ++#endif ++ ++} /* rlmFuncInitialChannelList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find a common channel list from the local channel list info & target channel list info. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return boolean value if probe response frame is ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, ++ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) NULL, prChannelEntryIII = ++ (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE] = {0}; ++ UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0; ++ ++ do { ++ ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) aucCommonChannelList; ++ ++ while (ucChannelListSize > 0) { ++ ++ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize; ++ ++ while (ucOriChnlSize > 0) { ++ if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) { ++ prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass; ++ /* TODO: Currently we assume that the regulatory class the same, ++ * the channels are the same. */ ++ kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList, ++ prChannelEntryII->ucNumberOfChannels); ++ prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels; ++ ++ ucNewChnlSize += ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels; ++ ++ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryIII + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG)prChannelEntryIII->ucNumberOfChannels); ++ } ++ ++ ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels); ++ ++ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryI + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) ++ prChannelEntryI->ucNumberOfChannels); ++ ++ } ++ ++ ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels); ++ ++ prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryII + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) prChannelEntryII->ucNumberOfChannels); ++ ++ } ++ ++ kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize); ++ prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize; ++ ++ } while (FALSE); ++ ++} /* rlmFuncCommonChannelList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum) ++{ ++ UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ UINT_32 u4Idx = 0; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ while (ucBufferSize != 0) { ++ ++ for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) { ++ if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) { ++ ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass; ++ break; ++ } ++ ++ } ++ ++ if (ucRegulatoryClass != 0) ++ break; /* while */ ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG)prChannelEntryField->ucNumberOfChannels); ++ ++ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); ++ ++ } ++ ++ } while (FALSE); ++ ++ return ucRegulatoryClass; ++} /* rlmFuncFindOperatingClass */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucCheckChnl, ++ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel) ++{ ++ BOOLEAN fgIsResultAvailable = FALSE; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ if (fgIsDefaultChannel) ++ ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL; ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; ++ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ while ((ucBufferSize != 0) && (!fgIsResultAvailable)) { ++ ++ for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) { ++ if ((!fgIsSocialChannel) || ++ (prChannelEntry->aucChannelList[ucIdx] == 1) || ++ (prChannelEntry->aucChannelList[ucIdx] == 6) || ++ (prChannelEntry->aucChannelList[ucIdx] == 11)) { ++ ++ if (prChannelEntry->aucChannelList[ucIdx] <= 11) { ++ /* 2.4G. */ ++ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; ++ } else if ((prChannelEntry->aucChannelList[ucIdx] < 52) && ++ (prChannelEntry->aucChannelList[ucIdx] > 14)) { ++ /* 2.4G + 5G. */ ++ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; ++ } ++ ++ if (ucChannelSelected == ucCheckChnl) { ++ fgIsResultAvailable = TRUE; ++ break; ++ } ++ } ++ ++ } ++ ++ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels); ++ ++ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntry + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) prChannelEntry->ucNumberOfChannels); ++ ++ } ++ ++ if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) { ++ DBGLOG(P2P, TRACE, ++ "The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl, ++ ucChannelSelected); ++ /* Given a suggested channel. */ ++ *pucSuggestChannel = ucChannelSelected; ++ } ++ ++ } while (FALSE); ++ ++ return fgIsResultAvailable; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ P_DOMAIN_SUBBAND_INFO prSubband; ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ UINT_8 ucSecondChannel, i, j; ++ ENUM_CHNL_EXT_T eSCO; ++ ++ eSCO = CHNL_EXT_SCN; ++ ++ if (prBssInfo->eBand == BAND_2G4) { ++ if (prBssInfo->ucPrimaryChannel != 14) ++ eSCO = (prBssInfo->ucPrimaryChannel > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA; ++ } else { ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubband = &prDomainInfo->rSubBand[i]; ++ if (prSubband->ucBand == prBssInfo->eBand) { ++ for (j = 0; j < prSubband->ucNumChannels; j++) { ++ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) ++ == prBssInfo->ucPrimaryChannel) { ++ eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA; ++ break; ++ } ++ } ++ ++ if (j < prSubband->ucNumChannels) ++ break; /* Found */ ++ } ++ } ++ } ++ ++ /* Check if it is boundary channel and 40MHz BW is permitted */ ++ if (eSCO != CHNL_EXT_SCN) { ++ ucSecondChannel = (eSCO == CHNL_EXT_SCA) ? ++ (prBssInfo->ucPrimaryChannel + 4) : (prBssInfo->ucPrimaryChannel - 4); ++ ++ if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel)) ++ eSCO = CHNL_EXT_SCN; ++ } ++ ++ return eSCO; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c +new file mode 100644 +index 000000000000..154f1e5db0f7 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c +@@ -0,0 +1,313 @@ ++/* ++** Id: @(#) gl_p2p_cfg80211.c@@ ++*/ ++ ++/*! \file gl_p2p_cfg80211.c ++ \brief Main routines of Linux driver interface for Wi-Fi Direct ++ using cfg80211 interface ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Different concurrent network has itself channel lists, and ++* concurrent networks should have been recorded in channel lists. ++* If role of active P2P is GO, assume associated AP of AIS will ++* record our Beacon for P2P GO because of same channel. ++* ++* Note: If we have scenario of different channel in the future, ++* the internal FW communication channel shall be established. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 ucChannelLevel; ++ ++ ASSERT(prBssInfo); ++ ++ if (eBand == BAND_2G4) { ++ ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend); ++ ++ /* (TBD) If concurrent networks permit different channel, extra ++ * channel judgement should be added. Please refer to ++ * previous version of this file. ++ */ ++ } else if (eBand == BAND_5G) { ++ ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend); ++ ++ /* (TBD) If concurrent networks permit different channel, extra ++ * channel judgement should be added. Please refer to ++ * previous version of this file. ++ */ ++ } else { ++ ucChannelLevel = CHNL_LEVEL0; ++ } ++ ++ return ucChannelLevel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 i, ucChannelLevel; ++ UINT_8 ucSecChannel, ucCenterChannel; ++ UINT_8 ucAffectedChnl_L, ucAffectedChnl_H; ++ ++ ASSERT(prBssInfo); ++ ++ ucChannelLevel = CHNL_LEVEL2; ++ ++ /* Calculate center channel for 2.4G band */ ++ if (eExtend == CHNL_EXT_SCA) { ++ ucCenterChannel = ucPriChannel + 2; ++ ucSecChannel = ucPriChannel + 4; ++ } else if (eExtend == CHNL_EXT_SCB) { ++ ucCenterChannel = ucPriChannel - 2; ++ ucSecChannel = ucPriChannel - 4; ++ } else { ++ return CHNL_LEVEL0; ++ } ++ ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14); ++ ++ /* Calculated low/upper channels in affected freq range */ ++ ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ? 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET); ++ ++ ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ? ++ 14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET); ++ ++ /* Check intolerant (Non-HT) channel list */ ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) && ++ prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++ /* Check 20M BW request channel list */ ++ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++ /* Check 2.4G primary channel list */ ++ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) && ++ prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++ /* Check 2.4G secondary channel list */ ++ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) && ++ prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++L_2G4_level_end: ++ ++ return ucChannelLevel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 i, ucChannelLevel; ++ UINT_8 ucSecChannel; ++ ++ ASSERT(prBssInfo); ++ ++ ucChannelLevel = CHNL_LEVEL2; ++ ++ /* Calculate center channel for 2.4G band */ ++ if (eExtend == CHNL_EXT_SCA) ++ ucSecChannel = ucPriChannel + 4; ++ else if (eExtend == CHNL_EXT_SCB) ++ ucSecChannel = ucPriChannel - 4; ++ else ++ return CHNL_LEVEL0; ++ ASSERT(ucSecChannel >= 36); ++ ++ /* Check 5G primary channel list */ ++ ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G); ++ for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { ++ if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_5G_level_end; ++ } else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) { ++ ucChannelLevel = CHNL_LEVEL1; ++ } ++ } ++ ++ /* Check non-HT channel list */ ++ ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G); ++ for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { ++ if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_5G_level_end; ++ } else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) { ++ ucChannelLevel = CHNL_LEVEL1; ++ } ++ } ++ ++ /* Check secondary channel list */ ++ ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G); ++ for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { ++ if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_5G_level_end; ++ } ++ } ++ ++L_5G_level_end: ++ ++ return ucChannelLevel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_20_40_COEXIST_FRAME prTxFrame; ++ ++ /* To do: need an algorithm to do judgement. Now always reject request */ ++ ++ prMsduInfo = (P_MSDU_INFO_T)cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); ++ if (prMsduInfo == NULL) ++ return; ++ ++ DBGLOG(RLM, INFO, "Send 20/40 coexistence rsp frame!\n"); ++ ++ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket; ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; ++ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; ++ ++ /* To do: find correct algorithm */ ++ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; ++ prTxFrame->rBssCoexist.ucLength = 1; ++ prTxFrame->rBssCoexist.ucData = 0; ++ ++ ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN); ++ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prSwRfb->ucStaRecIdx; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* Send them to HW queue */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c +new file mode 100644 +index 000000000000..b5bd23965fe3 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c +@@ -0,0 +1,756 @@ ++/* ++** Id: @(#) p2p_scan.c@@ ++*/ ++ ++/*! \file "p2p_scan.c" ++ \brief This file defines the p2p scan profile and the processing function of ++ scan result for SCAN Module. ++ ++ The SCAN Profile selection is part of SCAN MODULE and responsible for defining ++ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. ++ In this file we also define the process of SCAN Result including adding, searching ++ and removing SCAN record from the list. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++P_P2P_DEVICE_DESC_T ++scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc) ++{ ++ ++ P_P2P_DEVICE_DESC_T prTargetP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucDeviceID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* 4 <1> The outer loop to search for a candidate. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ /* Loop for each prBssDesc */ ++ prTargetP2pDesc = scanFindP2pDeviceDesc(prAdapter, prBssDesc, aucDeviceID, TRUE, FALSE); ++ ++ if (prTargetP2pDesc != NULL) ++ break; ++ } ++ ++ if ((pprBssDesc) && (prTargetP2pDesc != NULL)) { ++ /* Only valid if prTargetP2pDesc is not NULL. */ ++ *pprBssDesc = prBssDesc; ++ } ++ ++ return prTargetP2pDesc; ++} /* scanSearchTargetP2pDesc */ ++ ++VOID scanInvalidAllP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ ++ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ if (prTargetDesc->fgDevInfoValid) ++ prTargetDesc->fgDevInfoValid = FALSE; ++ } ++ ++} /* scanRenewP2pClientDevice */ ++ ++VOID scanRemoveInvalidP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL, prNexEntry = (P_LINK_ENTRY_T) NULL; ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ LINK_FOR_EACH_SAFE(prLinkEntry, prNexEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ if (!prTargetDesc->fgDevInfoValid) { ++ LINK_REMOVE_KNOWN_ENTRY(&prBssDesc->rP2pDeviceList, prLinkEntry); ++ if ((prP2pConnSettings) && (prP2pConnSettings->prTargetP2pDesc == prTargetDesc)) ++ prP2pConnSettings->prTargetP2pDesc = NULL; ++ kalMemFree(prTargetDesc, VIR_MEM_TYPE, sizeof(P2P_DEVICE_DESC_T)); ++ } ++ } ++ ++} /* scanRenewP2pClientDevice */ ++ ++P_P2P_DEVICE_DESC_T ++scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, ++ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound) ++{ ++ ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prBssDesc != NULL) && (aucMacAddr != NULL)); ++ ++ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ if (fgIsDeviceAddr) { ++ if (EQUAL_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr)) ++ break; ++ } else { ++ if (EQUAL_MAC_ADDR(prTargetDesc->aucInterfaceAddr, aucMacAddr)) ++ break; ++ } ++ ++ prTargetDesc = NULL; ++ } ++ ++ if ((fgAddIfNoFound) && (prTargetDesc == NULL)) { ++ /* Target Not Found. */ ++ /* TODO: Use memory pool in the future. */ ++ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); ++ ++ if (prTargetDesc) { ++ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); ++ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); ++ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr); ++ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); ++ prTargetDesc->fgDevInfoValid = TRUE; ++ } else { ++ ASSERT(FALSE); ++ } ++ } ++ ++ } while (FALSE); ++ ++ return prTargetDesc; ++} /* scanFindP2pDeviceDesc */ ++ ++P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssDesc); ++ ++ if (prBssDesc->prP2pDesc == NULL) { ++ ++ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); ++ ++ if (prTargetDesc) { ++ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); ++ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); ++ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); ++ prTargetDesc->fgDevInfoValid = TRUE; ++ prBssDesc->prP2pDesc = prTargetDesc; ++ /* We are not sure the SrcAddr is Device Address or Interface Address. */ ++ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, prBssDesc->aucSrcAddr); ++ COPY_MAC_ADDR(prTargetDesc->aucInterfaceAddr, prBssDesc->aucSrcAddr); ++ } else { ++ ++ ASSERT(FALSE); ++ } ++ } else { ++ prTargetDesc = prBssDesc->prP2pDesc; ++ } ++ ++ return prTargetDesc; ++ ++} /* scanFindP2pDeviceDesc */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. ++* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_P2P_DEVICE_DESC_T prP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; ++ UINT_16 u2AttributeLen = 0; ++ UINT_32 u4Idx = 0; ++ BOOLEAN fgUpdateDevInfo = FALSE; ++ ++ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; ++ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; ++ ++ ASSERT(prAdapter); ++ ++ prP2pDesc = scanGetP2pDeviceDesc(prAdapter, prBssDesc); ++ ++ if (!prP2pDesc) { ++ ASSERT(FALSE); ++ return fgUpdateDevInfo; ++ } ++ ++ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, ++ &u2AttributeLen); ++ ++ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { ++ switch (prP2pAttribute->ucId) { ++ case P2P_ATTRI_ID_P2P_CAPABILITY: /* Beacon, Probe Response */ ++ { ++ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; ++ ++ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; ++ ASSERT(prP2pAttriCapability->u2Length == 2); ++ ++ prP2pDesc->ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; ++ prP2pDesc->ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_ID: /* Beacon */ ++ { ++ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; ++ ++ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; ++ ASSERT(prP2pAttriDevID->u2Length == P2P_ATTRI_MAX_LEN_P2P_DEV_ID); ++ ++ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_INFO: /* Probe Response */ ++ { ++ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ UINT_16 u2NameLen = 0, u2Id = 0; ++ ++ fgUpdateDevInfo = TRUE; ++ ++ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; ++ ++ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN); ++ ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); ++ ++ prP2pDevType = &prP2pDesc->rPriDevType; ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ ++ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= ++ P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); ++ /* TODO: Fixme if secondary device type is more than 2. */ ++ prP2pDesc->ucSecDevTypeNum = 0; ++ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { ++ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { ++ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> ++ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> ++ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ prP2pDesc->ucSecDevTypeNum++; ++ } ++ ++ } ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) ((PUINT_8) prP2pAttriDevInfo->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &u2NameLen); ++ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Id, &u2Id); ++ ASSERT(u2Id == WPS_ATTRI_ID_DEVICE_NAME); ++ if (u2NameLen > WPS_ATTRI_MAX_LEN_DEVICE_NAME) ++ u2NameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; ++ prP2pDesc->u2NameLength = u2NameLen; ++ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_GROUP_INFO: /* Probe Response */ ++ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; ++ break; ++ case P2P_ATTRI_ID_NOTICE_OF_ABSENCE: ++ break; ++ case P2P_ATTRI_ID_EXT_LISTEN_TIMING: ++ /* TODO: Not implement yet. */ ++ /* ASSERT(FALSE); */ ++ break; ++ default: ++ break; ++ } ++ ++ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); ++ ++ prP2pAttribute = ++ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); ++ ++ } ++ ++ if (prP2pAttriGroupInfo != NULL) { ++ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ ++ scanInvalidAllP2pClientDevice(prAdapter, prBssDesc); ++ ++ /* GO/Device itself. */ ++ prP2pDesc->fgDevInfoValid = TRUE; ++ ++ prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) prP2pAttriGroupInfo->arClientDesc; ++ u2AttributeLen = prP2pAttriGroupInfo->u2Length; ++ ++ while (u2AttributeLen > 0) { ++ prP2pDesc = ++ scanFindP2pDeviceDesc(prAdapter, prBssDesc, prClientInfoDesc->aucDevAddr, TRUE, TRUE); ++ ++ if (!prP2pDesc) { ++ ASSERT(FALSE); ++ break; /* while */ ++ } ++ ++ prP2pDesc->fgDevInfoValid = TRUE; ++ ++ /* Basic size for P2P client info descriptor. */ ++ ASSERT(u2AttributeLen >= 25); ++ if (u2AttributeLen < 25) { ++ DBGLOG(P2P, WARN, "Length incorrect warning.\n"); ++ break; ++ } ++ COPY_MAC_ADDR(prP2pDesc->aucInterfaceAddr, prClientInfoDesc->aucIfAddr); ++ ++ prP2pDesc->ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; ++ ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); ++ ++ prP2pDevType = &(prP2pDesc->rPriDevType); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ ++ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); ++ prP2pDesc->ucSecDevTypeNum = 0; ++ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { ++ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { ++ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> ++ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> ++ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ prP2pDesc->ucSecDevTypeNum++; ++ } ++ ++ } ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &prP2pDesc->u2NameLength); ++ if (prP2pDesc->u2NameLength > WPS_ATTRI_MAX_LEN_DEVICE_NAME) ++ prP2pDesc->u2NameLength = WPS_ATTRI_MAX_LEN_DEVICE_NAME; ++ ++ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); ++ ++ u2AttributeLen -= (prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN); ++ prClientInfoDesc = ++ (P_P2P_CLIENT_INFO_DESC_T) ((UINT_32) prClientInfoDesc + ++ (UINT_32) prClientInfoDesc->ucLength + ++ P2P_CLIENT_INFO_DESC_HDR_LEN); ++ } ++ ++ scanRemoveInvalidP2pClientDevice(prAdapter, prBssDesc); ++ } ++ ++ return fgUpdateDevInfo; ++} /* end of scanAddP2pDeviceInfo() */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. ++* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) ++{ ++ EVENT_P2P_DEV_DISCOVER_RESULT_T rEventDevInfo; ++#if 1 ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ ++ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ COPY_MAC_ADDR(rEventDevInfo.aucDeviceAddr, prTargetDesc->aucDeviceAddr); ++ COPY_MAC_ADDR(rEventDevInfo.aucInterfaceAddr, prTargetDesc->aucInterfaceAddr); ++ ++ rEventDevInfo.ucDeviceCapabilityBitmap = prTargetDesc->ucDeviceCapabilityBitmap; ++ rEventDevInfo.ucGroupCapabilityBitmap = prTargetDesc->ucGroupCapabilityBitmap; ++ rEventDevInfo.u2ConfigMethod = prTargetDesc->u2ConfigMethod; ++ ++ kalMemCopy(&rEventDevInfo.rPriDevType, &prTargetDesc->rPriDevType, sizeof(P2P_DEVICE_TYPE_T)); ++ ++ kalMemCopy(rEventDevInfo.arSecDevType, ++ prTargetDesc->arSecDevType, (prTargetDesc->ucSecDevTypeNum * sizeof(P2P_DEVICE_TYPE_T))); ++ ++ rEventDevInfo.ucSecDevTypeNum = prTargetDesc->ucSecDevTypeNum; ++ ++ rEventDevInfo.u2NameLength = prTargetDesc->u2NameLength; ++ kalMemCopy(rEventDevInfo.aucName, prTargetDesc->aucName, prTargetDesc->u2NameLength); ++ ++ COPY_MAC_ADDR(rEventDevInfo.aucBSSID, prBssDesc->aucBSSID); ++ ++ if (prTargetDesc == prBssDesc->prP2pDesc) ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, prBssDesc->aucIEBuf, prBssDesc->u2IELength); ++ else ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, NULL, 0); ++ } ++ ++ kalP2PIndicateFound(prAdapter->prGlueInfo); ++ ++#else ++ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; ++ UINT_16 u2AttributeLen = 0; ++ UINT_32 u4Idx = 0; ++ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; ++ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; ++ ++ ASSERT(prAdapter); ++ ++ prP2pSpecificBssInfo = &prAdapter->rWifiVar.rP2pSpecificBssInfo; ++ ++#if 1 ++ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, ++ &u2AttributeLen); ++#else ++ prP2pAttribute = (P_P2P_ATTRIBUTE_T) &prP2pSpecificBssInfo->aucAttributesCache[0]; ++ u2AttributeLen = prP2pSpecificBssInfo->u2AttributeLen; ++#endif ++ rEventDevInfo.fgDevInfoValid = FALSE; ++ ++ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { ++ switch (prP2pAttribute->ucId) { ++ case P2P_ATTRI_ID_P2P_CAPABILITY: ++ { ++ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; ++ ++ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; ++ ASSERT(prP2pAttriCapability->u2Length == 2); ++ rEventDevInfo.ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; ++ rEventDevInfo.ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_ID: ++ { ++ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; ++ ++ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; ++ ASSERT(prP2pAttriDevID->u2Length == 6); ++ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_INFO: ++ { ++ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ ++ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; ++ rEventDevInfo.fgDevInfoValid = TRUE; ++ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevInfo->aucDevAddr, ++ MAC_ADDR_LEN); ++ rEventDevInfo.u2ConfigMethod = prP2pAttriDevInfo->u2ConfigMethodsBE; ++ ++ prP2pDevType = &rEventDevInfo.rPriDevType; ++ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; ++ prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; ++ ++ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= 2); ++ /* TODO: Fixme if secondary device type is more than 2. */ ++ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { ++ /* TODO: Current sub device type can only support 2. */ ++ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; ++ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; ++ prP2pDevType->u2SubCategoryID = ++ prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; ++ } ++ ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) (prP2pAttriDevInfo->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ ASSERT(prP2pDevName->u2Id == 0x1011); ++ ASSERT(prP2pDevName->u2Length <= 32); ++ /* TODO: Fixme if device name length is longer than 32 bytes. */ ++ kalMemCopy(rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_GROUP_INFO: ++ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; ++ break; ++ } ++ ++ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); ++ ++ prP2pAttribute = ++ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); ++ ++ } ++ ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); ++ ++ if (prP2pAttriGroupInfo != NULL) { ++ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ ++ prClientInfoDesc = prP2pAttriGroupInfo->arClientDesc; ++ u2AttributeLen = prP2pAttriGroupInfo->u2Length; ++ ++ while (u2AttributeLen > 0) { ++ /* Basic size for P2P client info descriptor. */ ++ ASSERT(u2AttributeLen >= 25); ++ rEventDevInfo.fgDevInfoValid = TRUE; ++ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prClientInfoDesc->aucIfAddr, MAC_ADDR_LEN); ++ rEventDevInfo.ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; ++ rEventDevInfo.u2ConfigMethod = prClientInfoDesc->u2ConfigMethodsBE; ++ ++ prP2pDevType = &rEventDevInfo.rPriDevType; ++ prP2pDevType->u2CategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId; ++ prP2pDevType->u2SubCategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId; ++ ++ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= 2); ++ /* TODO: Fixme if secondary device type is more than 2. */ ++ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { ++ /* TODO: Current sub device type can only support 2. */ ++ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; ++ prP2pDevType->u2CategoryID = ++ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId; ++ prP2pDevType->u2SubCategoryID = ++ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId; ++ } ++ ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ ASSERT(prP2pDevName->u2Id == 0x1011); ++ ASSERT(prP2pDevName->u2Length <= 32); ++ /* TODO: Fixme if device name length is longer than 32 bytes. */ ++ kalMemCopy(&rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); ++ ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); ++ ++ u2AttributeLen -= prP2pAttriGroupInfo->u2Length; ++ prP2pAttriGroupInfo = prP2pAttriGroupInfo + prP2pAttriGroupInfo->u2Length + 1; ++ } ++ ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} /* scanSendDeviceDiscoverEvent */ ++ ++VOID ++scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN P_WLAN_STATUS prStatus, ++ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame) ++{ ++ BOOLEAN fgIsSkipThisBeacon; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ fgIsSkipThisBeacon = FALSE; ++ if (prBssDesc->fgIsP2PPresent) { ++ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && /* P2P GC */ ++ (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && /* Connected */ ++ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { /* TX Beacon */ ++ ++ fgIsSkipThisBeacon = TRUE; ++ } ++ ++ if ((!prP2pBssInfo->ucDTIMPeriod) && /* First time. */ ++ fgIsSkipThisBeacon && (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, ++ prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen))) { /* SSID Match */ ++ prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ do { ++ RF_CHANNEL_INFO_T rChannelInfo; ++ ++ ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL)); ++ ++ if (((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_PROBE_RSP)) { ++ /* Only report Probe Response frame to supplicant. */ ++ /* Probe response collect much more information. */ ++ ++ if (fgIsSkipThisBeacon || prBssDesc->eBand == BAND_2G4) ++ break; ++ } ++ ++ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; ++ rChannelInfo.eBand = prBssDesc->eBand; ++ prBssDesc->fgIsP2PReport = TRUE; ++ ++ DBGLOG(P2P, INFO, "indicate %s [%d]\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prSwRfb->pvHeader, ++ (UINT_32) prSwRfb->u2PacketLen, ++ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ ++ } while (FALSE); ++ } ++} ++ ++VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum) ++{ ++ ++ CMD_SCAN_CANCEL rCmdScanCancel; ++ ++ /* send cancel message to firmware domain */ ++ rCmdScanCancel.ucSeqNum = ucScnSeqNum; ++ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_CANCEL, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8)&rCmdScanCancel, NULL, 0); ++ ++} /* scnEventReturnChannel */ ++ ++VOID scanRemoveAllP2pBssDesc(IN P_ADAPTER_T prAdapter) ++{ ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prBSSDescNext; ++ ++ ASSERT(prAdapter); ++ ++ prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ scanRemoveP2pBssDesc(prAdapter, prBssDesc); ++ } ++} /* scanRemoveAllP2pBssDesc */ ++ ++VOID scanRemoveP2pBssDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ ++ ++} /* scanRemoveP2pBssDesc */ ++ ++P_BSS_DESC_T ++scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo) ++{ ++ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL, prBssDesc = (P_BSS_DESC_T) NULL; ++ P_LINK_T prBssDescList = (P_LINK_T) NULL; ++ ++ do { ++ if ((prAdapter == NULL) || (prP2pBssInfo == NULL) || (prConnReqInfo == NULL)) ++ break; ++ ++ prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); ++ ++ DBGLOG(P2P, LOUD, "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); ++ DBGLOG(P2P, LOUD, "Connecting to SSID:%s, length:%d\n", ++ prConnReqInfo->rSsidStruct.aucSsid, prConnReqInfo->rSsidStruct.ucSsidLen); ++ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, rLinkEntry, BSS_DESC_T) { ++ DBGLOG(P2P, LOUD, "Checking BSS: %pM\n", prBssDesc->aucBSSID); ++ ++ if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) { ++ DBGLOG(P2P, LOUD, "Ignore mismatch BSS type.\n"); ++ continue; ++ } ++ ++ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnReqInfo->aucBssid)) { ++ DBGLOG(P2P, LOUD, "Ignore mismatch BSSID.\n"); ++ continue; ++ } ++ ++ /* SSID should be the same? SSID is vary for each connection. so... */ ++ if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid, ++ prConnReqInfo->rSsidStruct.ucSsidLen, ++ prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) { ++ ++ DBGLOG(P2P, TRACE, ++ "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); ++ DBGLOG(P2P, TRACE, ++ "Connecting to SSID:%s, length:%d\n", prConnReqInfo->rSsidStruct.aucSsid, ++ prConnReqInfo->rSsidStruct.ucSsidLen); ++ DBGLOG(P2P, TRACE, ++ "Checking SSID:%s, length:%d\n", prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ DBGLOG(P2P, TRACE, "Ignore mismatch SSID, (But BSSID match).\n"); ++ ASSERT(FALSE); ++ continue; ++ } ++ ++ if (!prBssDesc->fgIsP2PPresent) { ++ DBGLOG(P2P, ERROR, "SSID, BSSID, BSSTYPE match, but no P2P IE present.\n"); ++ continue; ++ } ++ ++ /* Final decision. */ ++ prCandidateBssDesc = prBssDesc; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return prCandidateBssDesc; ++} /* scanP2pSearchDesc */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c +new file mode 100644 +index 000000000000..befb9978f473 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c +@@ -0,0 +1,466 @@ ++#include "p2p_precomp.h" ++ ++BOOLEAN ++p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState) ++{ ++ BOOLEAN fgIsTransOut = FALSE; ++/* P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL; */ ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (peNextState != NULL)); ++ ++ if ((prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) ++ && IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ fgIsTransOut = TRUE; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; ++ ++ DBGLOG(P2P, INFO, "p2pStateInit_IDLE GO Scan\n"); ++ *peNextState = P2P_STATE_REQING_CHANNEL; ++ ++ } else { ++#if 0 ++ else ++ if (IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { ++ ++ ASSERT((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)); ++ ++ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ if (prChnlReqInfo->fgIsChannelRequested) { ++ /* Start a timer for return channel. */ ++ DBGLOG(P2P, TRACE, "start a GO channel timer.\n"); ++ } ++ ++ } ++#endif ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), 5000); ++ } ++ ++ } while (FALSE); ++ ++ return fgIsTransOut; ++} /* p2pStateInit_IDLE */ ++ ++VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ if (prChnlReqInfo->fgIsChannelRequested) { ++ /* Release channel before timeout. */ ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ } ++ ++ /* Stop timer for leaving this state. */ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ ++ } while (FALSE); ++ ++} /* p2pStateAbort_IDLE */ ++ ++VOID p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ /* Store the original channel info. */ ++ prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; ++ prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; ++ prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; ++ ++ /* RX Probe Request would check primary channel. */ ++ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; ++ prP2pBssInfo->eBand = prChnlReqInfo->eBand; ++ prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; ++ ++ DBGLOG(P2P, TRACE, "start a channel on hand timer.\n"); ++ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING) { ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), ++ prChnlReqInfo->u4MaxInterval); ++ ++ kalP2PIndicateChannelReady(prAdapter->prGlueInfo, ++ prChnlReqInfo->u8Cookie, ++ prChnlReqInfo->ucReqChnlNum, ++ prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval); ++ } else ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), ++ (P2P_EXT_LISTEN_TIME_MS - prChnlReqInfo->u4MaxInterval)); ++ } while (FALSE); ++ ++} /* p2pStateInit_CHNL_ON_HAND */ ++ ++VOID ++p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ ++ /* Restore the original channel info. */ ++ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum; ++ prP2pBssInfo->eBand = prChnlReqInfo->eOriBand; ++ prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco; ++ ++ DBGLOG(P2P, INFO, "p2p state trans abort chann on hand, eListenExted: %d, eNextState: %d\n", ++ prP2pFsmInfo->eListenExted, eNextState); ++ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING || ++ eNextState != P2P_STATE_CHNL_ON_HAND) { ++ /* Here maybe have a bug, when it's extlistening, a new remain_on_channel ++ was sent to driver? need to verify */ ++ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; ++ /* Indicate channel return. */ ++ kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo); ++ ++ /* Return Channel. */ ++ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ } ++ ++ } while (FALSE); ++} /* p2pStateAbort_CHNL_ON_HAND */ ++ ++VOID ++p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (eNextState < P2P_STATE_NUM)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (eNextState == P2P_STATE_IDLE) { ++ if (prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) { ++ /* Intend to be AP. */ ++ /* Setup for AP mode. */ ++ p2pFuncStartGO(prAdapter, ++ prP2pBssInfo, ++ prP2pSpecificBssInfo->aucGroupSsid, ++ prP2pSpecificBssInfo->u2GroupSsidLen, ++ prP2pSpecificBssInfo->ucPreferredChannel, ++ prP2pSpecificBssInfo->eRfBand, ++ prP2pSpecificBssInfo->eRfSco, prP2pFsmInfo->fgIsApMode); ++ ++ } else { ++ /* Return Channel. */ ++ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ } ++ ++ } ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_AP_CHANNEL_DETECT */ ++ ++VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ prScanReqInfo->eScanType = SCAN_TYPE_PASSIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_2G4; ++ prScanReqInfo->u2PassiveDewellTime = 50; /* 50ms for passive channel load detection */ ++ prScanReqInfo->fgIsAbort = TRUE; ++ prScanReqInfo->fgIsScanRequest = TRUE; ++ prScanReqInfo->ucNumChannelList = 0; ++ prScanReqInfo->u4BufLength = 0; ++ prScanReqInfo->rSsidStruct.ucSsidLen = 0; ++ ++ p2pFuncRequestScan(prAdapter, prScanReqInfo); ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_AP_CHANNEL_DETECT */ ++ ++VOID ++p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ++ if (eNextState == P2P_STATE_REQING_CHANNEL) { ++ UINT_8 ucPreferedChnl = 0; ++ ENUM_BAND_T eBand = BAND_NULL; ++ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ /* Determine the channel for AP. */ ++ if (cnmPreferredChannel(prAdapter, &eBand, &ucPreferedChnl, &eSco) == FALSE) { ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ucPreferedChnl = prP2pConnSettings->ucOperatingChnl; ++ if (ucPreferedChnl == 0) { ++ ++ if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) { ++ ++ /* What to do? */ ++ ASSERT(FALSE); ++ /* TODO: Pick up a valid channel from channel list. */ ++ ucPreferedChnl = 1; ++ eBand = BAND_2G4; ++ } ++ } ++ } ++ ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; ++ ++ DBGLOG(P2P, INFO, "p2pStateAbort_AP_CHANNEL_DETECT GO Scan\n"); ++ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; ++ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand; ++ prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco; ++ } else { ++ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pStateAbort_AP_CHANNEL_DETECT */ ++ ++VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prScanReqInfo = &prP2pFsmInfo->rScanReqInfo; ++ ++ prScanReqInfo->fgIsScanRequest = TRUE; ++ ++ p2pFuncRequestScan(prAdapter, prScanReqInfo); ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_SCAN */ ++ ++VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ /* 1. Scan cancel. (Make sure the scan request is invalid. */ ++ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); ++ ++ /* Scan done indication. */ ++ kalP2PIndicateScanDone(prAdapter->prGlueInfo, prP2pFsmInfo->rScanReqInfo.fgIsAbort); ++ } while (FALSE); ++ ++} /* p2pStateAbort_SCAN */ ++ ++VOID ++p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prP2pFsmInfo != NULL) && ++ (prP2pBssInfo != NULL) && (prJoinInfo != NULL) && (prBssDesc != NULL)); ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prBssDesc->ucSSIDLen) { ++ COPY_SSID(prP2pConnSettings->aucSSID, ++ prP2pConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ } ++ /* Setup a join timer. */ ++ DBGLOG(P2P, TRACE, "Start a join init timer\n"); ++ cnmTimerStartTimer(prAdapter, ++ &(prAdapter->rP2pFsmTimeoutTimer), ++ (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD)); ++ ++ /* 2 <1> We are goin to connect to this BSS */ ++ prBssDesc->fgIsConnecting = TRUE; ++ ++ /* 2 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, ++ (prBssDesc->fgIsP2PPresent ? (STA_TYPE_P2P_GO) ++ : (STA_TYPE_LEGACY_AP)), NETWORK_TYPE_P2P_INDEX, prBssDesc); ++ ++ if (prStaRec == NULL) { ++ DBGLOG(P2P, TRACE, "Create station record fail\n"); ++ break; ++ } ++ ++ prJoinInfo->prTargetStaRec = prStaRec; ++ prJoinInfo->fgIsJoinComplete = FALSE; ++ prJoinInfo->u4BufLength = 0; ++ ++ /* 2 <2.1> Sync. to FW domain */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prStaRec->fgIsReAssoc = FALSE; ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ switch (prP2pConnSettings->eAuthMode) { ++ case AUTH_MODE_OPEN: /* Note: Omit break here. */ ++ case AUTH_MODE_WPA: ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA2: ++ case AUTH_MODE_WPA2_PSK: ++ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ break; ++ case AUTH_MODE_SHARED: ++ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; ++ break; ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(P2P, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); ++ prJoinInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | ++ AUTH_TYPE_SHARED_KEY); ++ break; ++ default: ++ ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); ++ DBGLOG(P2P, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", ++ prP2pConnSettings->eAuthMode); ++ /* TODO(Kevin): error handling ? */ ++ return; ++ } ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; ++ } else { ++ ASSERT(FALSE); ++ /* TODO: Shall we considering ROAMIN case for P2P Device?. */ ++ } ++ ++ /* 2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes. */ ++ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { ++ ++ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { ++ ++ DBGLOG(P2P, TRACE, ++ "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; ++ } else { ++ ASSERT(0); ++ } ++ ++ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ ++ if (prBssDesc->ucSSIDLen) { ++ COPY_SSID(prJoinInfo->rSsidStruct.aucSsid, ++ prJoinInfo->rSsidStruct.ucSsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ } ++ /* 2 <5> Backup desired channel. */ ++ ++ /* 2 <6> Send a Msg to trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ ++ if (!prJoinReqMsg) { ++ DBGLOG(P2P, TRACE, "Allocation Join Message Fail\n"); ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ /* TODO: Consider fragmentation info in station record. */ ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_GC_JOIN */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of JOIN Abort. Leave JOIN State & Abort JOIN. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_MSG_JOIN_ABORT_T prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prJoinInfo != NULL)); ++ ++ if (prJoinInfo->fgIsJoinComplete == FALSE) { ++ ++ prJoinAbortMsg = ++ (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); ++ if (!prJoinAbortMsg) { ++ DBGLOG(P2P, TRACE, "Fail to allocate join abort message buffer\n"); ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT; ++ prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg; ++ prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ /* Stop Join Timer. */ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ ++ /* Release channel requested. */ ++ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pStateAbort_GC_JOIN */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c +new file mode 100644 +index 000000000000..72fa52e761da +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c +@@ -0,0 +1,915 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/privacy.c#1 ++*/ ++ ++/*! \file "privacy.c" ++ \brief This file including the protocol layer privacy function. ++ ++ This file provided the macros and functions library support for the ++ protocol layer security setting from rsn.c and nic_privacy.c ++ ++*/ ++ ++/* ++** Log: privacy.c ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 20 2011 terry.wu ++ * NULL ++ * Fix Hotspot deauth send failed. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 28 2011 tsaiyuan.hsu ++ * [WCXRP00000819] [MT6620 Wi-Fi][Driver] check if staRec is NULL or not in secCheckClassError ++ * check if staRec is NULL or not in secCheckClassError. ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * adding the compiling flag for migration. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the ad-hoc wpa-none send non-encrypted frame issue. ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 04 29 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * adjsut the pre-authentication code. ++ * ++ * 04 22 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the wpi same key id rx issue and fixed the remove wep key issue. ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Send Deauth for Class 3 Error and Leave Network Support ++ * ++ * 04 15 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * remove the assert code for allow ad-hoc pkt. ++ * ++ * 04 13 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the Klocwork error and refine the class error message. ++ * ++ * 03 04 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Code refine, and remove non-used code. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 02 26 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * change the waning message shown level, and clear the global transmit flag for CMD INFRASTRUCTURE. ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * For support the WHQL test, do the remove key code refine. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 12 25 2009 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) ++ * * * * * * * * * MQM: BA handling ++ * * * * * * * * * TXM: Macros updates ++ * * * * * * * * * RXM: Macros/Duplicate Removal updates ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 11 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * modify the cmd with result return ++ * ++ * Dec 11 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * fixed the value not initialize issue ++ * ++ * Dec 10 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the cmd return type ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function to update the auth mode and encryption status for cmd build connection ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some code for wapi mode ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the call to check the 4th and eapol error report frame ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * rename the function name ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code for parsing the EAPoL frame, and do some code refine ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the class error check ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the cmd_802_11_pmkid code ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * doing some function rename, and adding the code for cmd CMD_ADD_REMOVE_KEY ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the clear pmkid function ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix eStaType check for AIS ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the ap selection related code ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_PRIVACY_MIGRATION ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to initialize the privacy-related ++* parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] ucNetTypeIdx Pointer to netowrk type index ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx) ++{ ++ UINT_8 i; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("secInit"); ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ prBssInfo->u4RsnSelectedGroupCipher = 0; ++ prBssInfo->u4RsnSelectedPairwiseCipher = 0; ++ prBssInfo->u4RsnSelectedAKMSuite = 0; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; ++ ++ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; ++#endif ++ ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[0].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP40; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[1].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_TKIP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[2].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_CCMP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[3].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP104; ++ ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[4].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP40; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[5].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_TKIP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[6].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[7].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP104; ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[0].dot11RSNAConfigAuthenticationSuite = ++ WPA_AKM_SUITE_NONE; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[1].dot11RSNAConfigAuthenticationSuite = ++ WPA_AKM_SUITE_802_1X; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[2].dot11RSNAConfigAuthenticationSuite = ++ WPA_AKM_SUITE_PSK; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[3].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_NONE; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[4].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_802_1X; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[5].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_PSK; ++ ++#if CFG_SUPPORT_802_11W ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[6].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_802_1X_SHA256; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[7].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_PSK_SHA256; ++#endif ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i].dot11RSNAConfigAuthenticationSuiteEnabled = ++ FALSE; ++ } ++ ++ secClearPmkid(prAdapter); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisSpecBssInfo->rPreauthenticationTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) rsnIndicatePmkidCand, (ULONG) NULL); ++ ++#if CFG_SUPPORT_802_11W ++ cnmTimerInitTimer(prAdapter, ++ &prAisSpecBssInfo->rSaQueryTimer, (PFN_MGMT_TIMEOUT_FUNC) rsnStartSaQueryTimer, (ULONG) NULL); ++#endif ++ ++ prAisSpecBssInfo->fgCounterMeasure = FALSE; ++ prAisSpecBssInfo->ucWEPDefaultKeyID = 0; ++ ++#if 0 ++ for (i = 0; i < WTBL_SIZE; i++) { ++ g_prWifiVar->arWtbl[i].fgUsed = FALSE; ++ g_prWifiVar->arWtbl[i].prSta = NULL; ++ g_prWifiVar->arWtbl[i].ucNetTypeIdx = NETWORK_TYPE_INDEX_NUM; ++ ++ } ++ nicPrivacyInitialize((UINT_8) NETWORK_TYPE_INDEX_NUM); ++#endif ++} /* secInit */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Rx Class Error" to SEC_FSM for ++* JOIN Module. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSwRfb Pointer to the SW RFB. ++* ++* \return FALSE Class Error ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec) ++{ ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (!prStaRec) ++ return FALSE; ++ ++ eNetTypeIndex = prStaRec->ucNetTypeIndex; ++ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) ++ return FALSE; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]; ++ if ((STA_STATE_3 != prStaRec->ucStaState) && prBssInfo->fgIsNetAbsent == FALSE) { ++ /*(IS_AP_STA(prStaRec) || IS_CLIENT_STA(prStaRec))) { */ ++ ++#if 0 /* by scott's suggestions, do not put work-around in JB2,we need to find the root cause */ ++ /* work-around for CR ALPS00816361 */ ++ if (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ DBGLOG(RSN, INFO, ++ "p2p> skip to send Deauth to MAC:[%pM] for Rx Class 3.\n", ++ prStaRec->aucMacAddr); ++ return TRUE; ++ } ++#endif ++ ++ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, ++ prStaRec, ++ NULL, ++ REASON_CODE_CLASS_3_ERR, ++ (PFN_TX_DONE_HANDLER) NULL)) ++ ++ DBGLOG(RSN, INFO, "Send Deauth to [ %pM ] for Rx Class 3 Error.\n", ++ prStaRec->aucMacAddr); ++ else ++ DBGLOG(RSN, INFO, "Host sends Deauth to [ %pM ] for Rx Class 3 fail.\n", ++ prStaRec->aucMacAddr); ++ return FALSE; ++ } ++ ++ return secRxPortControlCheck(prAdapter, prSwRfb); ++} /* end of secCheckClassError() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to setting the sta port status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSta Pointer to the sta ++* \param[in] fgPortBlock The port status ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPortBlock) ++{ ++ if (prSta == NULL) ++ return; ++ ++ prSta->fgPortBlock = fgPortBlock; ++ ++ DBGLOG(RSN, TRACE, ++ "The STA %pM port %s\n", prSta->aucMacAddr, fgPortBlock == TRUE ? "BLOCK" : " OPEN"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to report the sta port status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSta Pointer to the sta ++* \param[out] fgPortBlock The port status ++* ++* \return TRUE sta exist, FALSE sta not exist ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secGetPortStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, OUT PBOOLEAN pfgPortStatus) ++{ ++ if (prSta == NULL) ++ return FALSE; ++ ++ *pfgPortStatus = prSta->fgPortBlock; ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle Peer device Tx Security process MSDU. ++* ++* \param[in] prMsduInfo pointer to the packet info pointer ++* ++* \retval TRUE Accept the packet ++* \retval FALSE Refuse the MSDU packet due port blocked ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN /* ENUM_PORT_CONTROL_RESULT */ ++secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) { ++ ++ /* Todo:: */ ++ if (prMsduInfo->fgIs802_1x) ++ return TRUE; ++ ++ if (prStaRec->fgPortBlock == TRUE) { ++ DBGLOG(SEC, TRACE, "Drop Tx packet due Port Control!\n"); ++ return FALSE; ++ } ++#if CFG_SUPPORT_WAPI ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) ++ return TRUE; ++#endif ++ if (IS_STA_IN_AIS(prStaRec)) { ++ if (!prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist && ++ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED)) { ++ DBGLOG(SEC, TRACE, "Drop Tx packet due the key is removed!!!\n"); ++ return FALSE; ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle The Rx Security process MSDU. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSWRfb SW rfb pinter ++* ++* \retval TRUE Accept the packet ++* \retval FALSE Refuse the MSDU packet due port control ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb) ++{ ++ ASSERT(prSWRfb); ++ ++#if 0 ++ /* whsu:Todo: Process MGMT and DATA */ ++ if (prSWRfb->prStaRec) { ++ if (prSWRfb->prStaRec->fgPortBlock == TRUE) { ++ if (1 /* prSWRfb->fgIsDataFrame and not 1x */ && ++ (g_prWifiVar->rConnSettings.eAuthMode >= AUTH_MODE_WPA)) { ++ /* DBGLOG(SEC, WARN, ("Drop Rx data due port control !\r\n")); */ ++ return TRUE; /* Todo: whsu FALSE; */ ++ } ++ /* if (!RX_STATUS_IS_PROTECT(prSWRfb->prRxStatus)) { */ ++ /* DBGLOG(RSN, WARN, ("Drop rcv non-encrypted data frame!\n")); */ ++ /* return FALSE; */ ++ /* } */ ++ } ++ } else { ++ } ++#endif ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine will enable/disable the cipher suite ++* ++* \param[in] prAdapter Pointer to the adapter object data area. ++* \param[in] u4CipherSuitesFlags flag for cipher suite ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags) ++{ ++ UINT_32 i; ++ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; ++ P_IEEE_802_11_MIB_T prMib; ++ ++ ASSERT(prAdapter); ++ ++ prMib = &prAdapter->rMib; ++ ++ ASSERT(prMib); ++ ++ if (u4CipherSuitesFlags == CIPHER_FLAG_NONE) { ++ /* Disable all the pairwise cipher suites. */ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) ++ prMib->dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ ++ /* Update the group cipher suite. */ ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; ++ ++ return; ++ } ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { ++ prEntry = &prMib->dot11RSNAConfigPairwiseCiphersTable[i]; ++ ++ switch (prEntry->dot11RSNAConfigPairwiseCipher) { ++ case WPA_CIPHER_SUITE_WEP40: ++ case RSN_CIPHER_SUITE_WEP40: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP40) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ ++ case WPA_CIPHER_SUITE_TKIP: ++ case RSN_CIPHER_SUITE_TKIP: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_TKIP) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ ++ case WPA_CIPHER_SUITE_CCMP: ++ case RSN_CIPHER_SUITE_CCMP: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_CCMP) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ ++ case WPA_CIPHER_SUITE_WEP104: ++ case RSN_CIPHER_SUITE_WEP104: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP104) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* Update the group cipher suite. */ ++ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_CCMP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_TKIP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP104; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP40; ++ else ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; ++ ++} /* secSetCipherSuite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle The 2nd Tx EAPoL Frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prMsduInfo pointer to the packet info pointer ++* \param[in] pucPayload pointer to the 1x hdr ++* \param[in] u2PayloadLen the 1x payload length ++* ++* \retval TRUE Accept the packet ++* \retval FALSE Refuse the MSDU packet due port control ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++secProcessEAPOL(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen) ++{ ++ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; ++ P_IEEE_802_1X_HDR pr1xHdr; ++ UINT_16 u2KeyInfo; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prStaRec); ++ ++ /* prStaRec = &(g_arStaRec[prMsduInfo->ucStaRecIndex]); */ ++ ASSERT(prStaRec); ++ ++ if (prStaRec && IS_AP_STA(prStaRec)) { ++ pr1xHdr = (P_IEEE_802_1X_HDR) pucPayload; ++ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { ++ prEapol = (P_EAPOL_KEY) ((PUINT_32) (pucPayload + 4)); ++ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); ++ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { ++ if (u2KeyInfo & WPA_KEY_INFO_SECURE) { ++ /* 4th EAPoL check at secHandleTxDoneCallback() */ ++ /* DBGLOG(RSN, TRACE, ("Tx 4th EAPoL frame\r\n")); */ ++ } else if (u2PayloadLen == 123 /* Not include LLC */) { ++ DBGLOG(RSN, INFO, "Tx 2nd EAPoL frame\r\n"); ++ secFsmEvent2ndEapolTx(prAdapter, prStaRec); ++ } ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will handle the 4th EAPoL Tx done and mic Error Report frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pMsduInfo Pointer to the Msdu Info ++* \param[in] rStatus The Tx done status ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus) ++{ ++ PUINT_8 pucPayload; ++ P_IEEE_802_1X_HDR pr1xHdr = (P_IEEE_802_1X_HDR) NULL; ++ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; ++ UINT_16 u2KeyInfo; ++ UINT_16 u2PayloadLen; ++ ++ DEBUGFUNC("secHandleTxDoneCallback"); ++ ++ ASSERT(prMsduInfo); ++ /* Todo:: Notice if using the TX free immediate after send to firmware, the payload may not correcttly!!!! */ ++ ++ ASSERT(prStaRec); ++ ++ /* Todo:: This call back may not need because the order of set key and send 4th 1x can be make sure */ ++ /* Todo:: Notice the LLC offset */ ++#if 1 ++ pucPayload = (PUINT_8) prMsduInfo->prPacket; ++ ASSERT(pucPayload); ++ ++ u2PayloadLen = prMsduInfo->u2FrameLength; ++ ++ if (0 /* prMsduInfo->fgIs1xFrame */) { ++ ++ if (prStaRec && IS_AP_STA(prStaRec)) { ++ pr1xHdr = (P_IEEE_802_1X_HDR) (PUINT_32) (pucPayload + 8); ++ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { ++ prEapol = (P_EAPOL_KEY) (PUINT_32) (pucPayload + 12); ++ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); ++ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { ++ if (prStaRec->rSecInfo.fg2nd1xSend == TRUE ++ && u2PayloadLen == ++ 107 /* include LLC *//* u2KeyInfo & WPA_KEY_INFO_SECURE */) { ++ DBGLOG(RSN, INFO, "Tx 4th EAPoL frame\r\n"); ++ secFsmEvent4ndEapolTxDone(prAdapter, prStaRec); ++ } else if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone) { ++ DBGLOG(RSN, INFO, "Tx EAPoL Error report frame\r\n"); ++ /* secFsmEventEapolTxDone(prAdapter, (UINT_32)prMsduInfo->prStaRec); */ ++ } ++ } ++ } ++ } ++ ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to initialize the pmkid parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secClearPmkid(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("secClearPmkid"); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ DBGLOG(RSN, TRACE, "secClearPmkid\n"); ++ prAisSpecBssInfo->u4PmkidCandicateCount = 0; ++ prAisSpecBssInfo->u4PmkidCacheCount = 0; ++ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCandicate, sizeof(PMKID_CANDICATE_T) * CFG_MAX_PMKID_CACHE); ++ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Whether WPA, or WPA2 but not WPA-None is enabled. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval BOOLEAN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ ++ ASSERT(prConnSettings); ++ ++ ASSERT(prConnSettings->eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); ++ ++ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION_DISABLED) ++ return FALSE; ++ ++ ASSERT(prConnSettings->eAuthMode < AUTH_MODE_NUM); ++ if ((prConnSettings->eAuthMode >= AUTH_MODE_WPA) && (prConnSettings->eAuthMode != AUTH_MODE_WPA_NONE)) ++ return TRUE; ++ ++ return FALSE; ++} /* secRsnKeyHandshakeEnabled */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return whether the transmit key alread installed. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSta Pointer the sta record ++* ++* \retval TRUE Default key or Transmit key installed ++* FALSE Default key or Transmit key not installed ++* ++* \note: ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ASSERT(prSta); ++ ++ if (prSta->fgTransmitKeyExist) ++ return TRUE; ++ else ++ return FALSE; ++} /* secTransmitKeyExist */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Whether 802.11 privacy is enabled. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval BOOLEAN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter) ++{ ++ DEBUGFUNC("secEnabled"); ++ ++ ASSERT(prAdapter->rWifiVar.rConnSettings.eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); ++ ++ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { ++ case ENUM_ENCRYPTION_DISABLED: ++ return FALSE; ++ case ENUM_ENCRYPTION1_ENABLED: ++ case ENUM_ENCRYPTION2_ENABLED: ++ case ENUM_ENCRYPTION3_ENABLED: ++ return TRUE; ++ default: ++ DBGLOG(RSN, TRACE, "Unknown encryption setting %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ break; ++ } ++ return FALSE; ++} /* secEnabled */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the privacy bit at mac header for TxM ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prMsdu the msdu for known the sta record ++* ++* \return TRUE the privacy need to set ++* FALSE the privacy no need to set ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec) ++{ ++ ASSERT(prAdapter); ++ ++ ASSERT(prMsdu); ++ ++ ASSERT(prStaRec); ++ /* prStaRec = &(g_arStaRec[prMsdu->ucStaRecIndex]); */ ++ ++ if (prStaRec == NULL) { ++ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) ++ return TRUE; ++ return FALSE; /* No privacy bit */ ++ } ++ ++ /* Todo:: */ ++ if (0 /* prMsdu->fgIs1xFrame */) { ++ if (IS_STA_IN_AIS(prStaRec) && prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { ++ DBGLOG(RSN, LOUD, "For AIS Legacy 1x, always not encryped\n"); ++ return FALSE; ++ } else if (!prStaRec->fgTransmitKeyExist) { ++ DBGLOG(RSN, LOUD, "1x Not Protected.\n"); ++ return FALSE; ++ } else if (prStaRec->rSecInfo.fgKeyStored) { ++ DBGLOG(RSN, LOUD, "1x not Protected due key stored!\n"); ++ return FALSE; ++ } ++ DBGLOG(RSN, LOUD, "1x Protected.\n"); ++ return TRUE; ++ } ++ if (!prStaRec->fgTransmitKeyExist) { ++ /* whsu , check for AIS only */ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA && ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) { ++ DBGLOG(RSN, LOUD, "Protected\n"); ++ return TRUE; ++ } ++ } else { ++ DBGLOG(RSN, LOUD, "Protected.\n"); ++ return TRUE; ++ } ++ ++ /* No sec or key is removed!!! */ ++ return FALSE; ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c +new file mode 100644 +index 000000000000..fd0a8772a666 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c +@@ -0,0 +1,497 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1 ++*/ ++ ++/*! \file "rate.c" ++ \brief This file contains the transmission rate handling routines. ++ ++ This file contains the transmission rate handling routines for setting up ++ ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do ++ conversion between Rate Set and Data Rates. ++*/ ++ ++/* ++** Log: rate.c ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add rate.c. ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update comments ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix DBGLOG ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461 ++** Fix the problem that do not ASSERT the length of Supported Rate IE == 8 ++** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088 ++** fixed the lint "possible using null pointer" warning ++** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461 ++** Revise GEN Link Speed OID ++** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461 ++** Add rateGetRateSetFromDataRates() for set desired rate OID ++** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461 ++** Add adopt operational rate as ACK rate if BasicRateSet was not found ++** Add comments ++** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461 ++** Add initial rate according rx signal quality support ++** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461 ++** Fix typo of rate adaptation of CtrlResp Frame ++** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461 ++** Add VOIP SCAN Support & Refine Roaming ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* The list of valid data rates. */ ++const UINT_8 aucDataRate[] = { ++ RATE_1M, /* RATE_1M_INDEX = 0 */ ++ RATE_2M, /* RATE_2M_INDEX */ ++ RATE_5_5M, /* RATE_5_5M_INDEX */ ++ RATE_11M, /* RATE_11M_INDEX */ ++ RATE_22M, /* RATE_22M_INDEX */ ++ RATE_33M, /* RATE_33M_INDEX */ ++ RATE_6M, /* RATE_6M_INDEX */ ++ RATE_9M, /* RATE_9M_INDEX */ ++ RATE_12M, /* RATE_12M_INDEX */ ++ RATE_18M, /* RATE_18M_INDEX */ ++ RATE_24M, /* RATE_24M_INDEX */ ++ RATE_36M, /* RATE_36M_INDEX */ ++ RATE_48M, /* RATE_48M_INDEX */ ++ RATE_54M, /* RATE_54M_INDEX */ ++ RATE_HT_PHY /* RATE_HT_PHY_INDEX */ ++}; ++ ++static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = { ++ RATE_1M_INDEX, /* RATE_1M_INDEX = 0 */ ++ RATE_2M_INDEX, /* RATE_2M_INDEX */ ++ RATE_5_5M_INDEX, /* RATE_5_5M_INDEX */ ++ RATE_11M_INDEX, /* RATE_11M_INDEX */ ++ RATE_1M_INDEX, /* RATE_22M_INDEX - Not supported */ ++ RATE_1M_INDEX, /* RATE_33M_INDEX - Not supported */ ++ RATE_6M_INDEX, /* RATE_6M_INDEX */ ++ RATE_6M_INDEX, /* RATE_9M_INDEX */ ++ RATE_12M_INDEX, /* RATE_12M_INDEX */ ++ RATE_12M_INDEX, /* RATE_18M_INDEX */ ++ RATE_24M_INDEX, /* RATE_24M_INDEX */ ++ RATE_24M_INDEX, /* RATE_36M_INDEX */ ++ RATE_24M_INDEX, /* RATE_48M_INDEX */ ++ RATE_24M_INDEX /* RATE_54M_INDEX */ ++}; ++ ++const BOOLEAN afgIsOFDMRate[RATE_NUM] = { ++ FALSE, /* RATE_1M_INDEX = 0 */ ++ FALSE, /* RATE_2M_INDEX */ ++ FALSE, /* RATE_5_5M_INDEX */ ++ FALSE, /* RATE_11M_INDEX */ ++ FALSE, /* RATE_22M_INDEX - Not supported */ ++ FALSE, /* RATE_33M_INDEX - Not supported */ ++ TRUE, /* RATE_6M_INDEX */ ++ TRUE, /* RATE_9M_INDEX */ ++ TRUE, /* RATE_12M_INDEX */ ++ TRUE, /* RATE_18M_INDEX */ ++ TRUE, /* RATE_24M_INDEX */ ++ TRUE, /* RATE_36M_INDEX */ ++ TRUE, /* RATE_48M_INDEX */ ++ TRUE /* RATE_54M_INDEX */ ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the given Supported Rate & Extended Supported Rate IE to the ++* Operational Rate Set and Basic Rate Set, and also check if any Basic ++* Rate Code is unknown by driver. ++* ++* @param[in] prIeSupportedRate Pointer to the Supported Rate IE ++* @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE ++* @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set ++* @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set ++* @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic ++* Rate Set has unknown Rate Code ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, ++ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, ++ OUT PUINT_16 pu2OperationalRateSet, ++ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate) ++{ ++ UINT_16 u2OperationalRateSet = 0; ++ UINT_16 u2BSSBasicRateSet = 0; ++ BOOLEAN fgIsUnknownBSSBasicRate = FALSE; ++ UINT_8 ucRate; ++ UINT_32 i, j; ++ ++ ASSERT(pu2OperationalRateSet); ++ ASSERT(pu2BSSBasicRateSet); ++ ASSERT(pfgIsUnknownBSSBasicRate); ++ ++ if (prIeSupportedRate) { ++ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. ++ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), ++ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" ++ */ ++ /* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */ ++ ASSERT(prIeSupportedRate->ucLength <= RATE_NUM); ++ ++ for (i = 0; i < prIeSupportedRate->ucLength; i++) { ++ ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK; ++ ++ /* Search all valid data rates */ ++ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { ++ if (ucRate == aucDataRate[j]) { ++ u2OperationalRateSet |= BIT(j); ++ ++ if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) ++ u2BSSBasicRateSet |= BIT(j); ++ ++ break; ++ } ++ } ++ ++ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && ++ (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) { ++ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ ++ } ++ } ++ } ++ ++ if (prIeExtSupportedRate) { ++ /* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */ ++ ++ for (i = 0; i < prIeExtSupportedRate->ucLength; i++) { ++ ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK; ++ ++ /* Search all valid data rates */ ++ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { ++ if (ucRate == aucDataRate[j]) { ++ u2OperationalRateSet |= BIT(j); ++ ++ if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) ++ u2BSSBasicRateSet |= BIT(j); ++ ++ break; ++ } ++ } ++ ++ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && ++ (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) { ++ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ ++ } ++ } ++ } ++ ++ *pu2OperationalRateSet = u2OperationalRateSet; ++ *pu2BSSBasicRateSet = u2BSSBasicRateSet; ++ *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate; ++ ++ return; ++ ++} /* end of rateGetRateSetFromIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code ++* Format for used in (Ext)Supportec Rate IE. ++* ++* @param[in] u2OperationalRateSet Operational Rate Set ++* @param[in] u2BSSBasicRateSet Basic Rate Set ++* @param[out] pucDataRates Pointer to the Data Rate Buffer ++* @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, ++ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen) ++{ ++ UINT_32 i, j; ++ ++ ASSERT(pucDataRates); ++ ASSERT(pucDataRatesLen); ++ ++ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); ++ ++ for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) { ++ if (u2OperationalRateSet & BIT(i)) { ++ ++ *(pucDataRates + j) = aucDataRate[i]; ++ ++ if (u2BSSBasicRateSet & BIT(i)) ++ *(pucDataRates + j) |= RATE_BASIC_BIT; ++ ++ j++; ++ } ++ } ++ ++ *pucDataRatesLen = (UINT_8) j; ++ ++ return; ++ ++} /* end of rateGetDataRatesFromRateSet() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the highest rate from given Rate Set. ++* ++* \param[in] u2RateSet Rate Set ++* \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index ++* ++* \retval TRUE Highest Rate Index was found ++* \retval FALSE Highest Rate Index was not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex) ++{ ++ INT_32 i; ++ ++ ASSERT(pucHighestRateIndex); ++ ++ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { ++ if (u2RateSet & BIT(i)) { ++ *pucHighestRateIndex = (UINT_8) i; ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++ ++} /* end of rateGetHighestRateIndexFromRateSet() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the lowest rate from given Rate Set. ++* ++* \param[in] u2RateSet Rate Set ++* \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index ++* ++* \retval TRUE Lowest Rate Index was found ++* \retval FALSE Lowest Rate Index was not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex) ++{ ++ UINT_32 i; ++ ++ ASSERT(pucLowestRateIndex); ++ ++ for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) { ++ if (u2RateSet & BIT(i)) { ++ *pucLowestRateIndex = (UINT_8) i; ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++ ++} /* end of rateGetLowestRateIndexFromRateSet() */ ++ ++#if 0 /* NOTE(Kevin): For reference */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Convert the given Data Rates to the Rate Set. ++* ++* \param[in] pucDataRates Pointer to the Data Rates ++* \param[in] ucDataRatesLen Length of given Data Rates ++* \param[out] pu2RateSet Pointer to the Rate Set ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates, IN UINT_8 ucDataRatesLen, OUT PUINT_16 pu2RateSet) ++{ ++ UINT_16 u2RateSet = 0; ++ UINT_8 ucRate; ++ UINT_32 i, j; ++ ++ ASSERT(pucDataRates); ++ ASSERT(pu2RateSet); ++ ++ if (pucDataRates) { ++ for (i = 0; i < ucDataRatesLen; i++) { ++ ucRate = pucDataRates[i] & RATE_MASK; ++ ++ /* Search all valid data rates */ ++ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { ++ if (ucRate == aucDataRate[j]) { ++ u2RateSet |= BIT(j); ++ break; ++ } ++ } ++ } ++ } ++ ++ *pu2RateSet = u2RateSet; ++ ++ return; ++ ++} /* end of rateGetRateSetFromDataRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding ++* ACK/CTS(Respnose) TX Rates. ++* ++* \param[in] u2OperationalRateSet Operational Rate Set ++* \param[in] u2BSSBasicRateSet Basic Rate Set ++* \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, ++ IN UINT_16 u2BSSBasicRateSet, IN OUT UINT_8 aucAckCtsRateIndex[]) ++{ ++ INT_32 i, j; ++ ++ ASSERT(aucAckCtsRateIndex); ++ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); ++ ++ /* Setup default ACK/CTS response rate */ ++ kalMemCopy(aucAckCtsRateIndex, (PVOID) aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex)); ++ ++ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { ++ if (u2OperationalRateSet & BIT(i)) { ++ for (j = i; j >= RATE_1M_INDEX; j--) { ++ if (u2BSSBasicRateSet & BIT(j)) { ++ /* Reply ACK Frame at the same Modulation Scheme. */ ++ if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || ++ (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) ++ aucAckCtsRateIndex[i] = (UINT_8) j; ++ break; ++ } ++ } ++ ++ /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has ++ * NULL BasicRateSet. ++ * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL. ++ * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"]. ++ * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M], ++ * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still ++ * use highest mandatory rate as default. ++ */ ++ if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */ ++ if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet)) ++ aucAckCtsRateIndex[i] = (UINT_8) i; ++ } ++ } ++ } ++ ++ return; ++ ++} /* end of rateSetAckCtsDataRatesFromRateSet() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the proper initial rate from Rate Set according to given RCPI value ++* ++* \param[in] u2RateSet Rate Set ++* \param[in] rRcpi RCPI value from AP or Peer STA ++* \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index ++* ++* \retval TRUE Initial Rate Index was found ++* \retval FALSE Initial Rate Index was not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rateGetBestInitialRateIndex(IN UINT_16 u2RateSet, IN RCPI rRcpi, OUT PUINT_8 pucInitialRateIndex) ++{ ++ UINT_16 u2InitRateSet; ++ INT_32 i; ++ ++ ASSERT(pucInitialRateIndex); ++ ++ DBGLOG(MGT, TRACE, "rRcpi = %d\n", rRcpi); ++ ++ if (rRcpi >= RCPI_100) { /* Best Signal */ ++ u2InitRateSet = INITIAL_RATE_SET(RCPI_100); ++ } else if (rRcpi >= RCPI_80) { /* Better Signal */ ++ u2InitRateSet = INITIAL_RATE_SET(RCPI_80); ++ } else if (rRcpi >= RCPI_60) { /* Good Signal */ ++ u2InitRateSet = INITIAL_RATE_SET(RCPI_60); ++ } else { /* Worse Signal */ ++ /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index ++ * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in ++ * function - bssUpdateTxRateForControlFrame(). ++ */ ++ return FALSE; ++ } ++ ++ u2RateSet &= u2InitRateSet; ++ ++ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { ++ if (u2RateSet & BIT(i)) { ++ *pucInitialRateIndex = (UINT_8) i; ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++ ++} /* end of rateGetBestInitialRateIndex() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c +new file mode 100644 +index 000000000000..244346983f40 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c +@@ -0,0 +1,1858 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#2 ++*/ ++ ++/*! \file "rlm.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Check length HT cap IE about RX associate request frame ++ * ++ * 11 10 2011 cm.chang ++ * NULL ++ * Modify debug message for XLOG ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 11 03 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Fix preamble type of STA mode ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Not send ERP IE if peer STA is 802.11b-only ++ * ++ * 10 11 2011 cm.chang ++ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter ++ * Ignore HT OP IE if its length field is not valid ++ * ++ * 09 28 2011 cm.chang ++ * NULL ++ * Add length check to reduce possibility to adopt wrong IE ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Handle client mode about preamble type and slot time ++ * ++ * 09 01 2011 cm.chang ++ * [WCXRP00000971] [MT6620 Wi-Fi][Driver][FW] Not set Beacon timeout interval when CPTT ++ * Final channel number only adopts the field from assoc response ++ * ++ * 06 10 2011 cm.chang ++ * [WCXRP00000773] [MT6620 Wi-Fi][Driver] Workaround some AP fill primary channel field with its secondary channel ++ * If DS IE exists, ignore the primary channel field in HT OP IE ++ * ++ * 05 03 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Fix compiling error ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Refine range of valid channel number ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Check if channel is valided before record ing BSS channel ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 29 2011 cm.chang ++ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning ++ * As CR title ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode ++ * and stop ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 15 2010 cm.chang ++ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. ++ * Add exception handle when no mgmt buffer in free build ++ * ++ * 10 08 2010 cm.chang ++ * NULL ++ * When 20M only setting, ignore OBSS IE ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Temporary add rlmUpdateParamByStaForBow() and rlmBssInitForBow(). ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Add CFG_ENABLE_BT_OVER_WIFI. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Fix compile error while enabling WiFi Direct function. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 06 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix channel ID definition in RFB status to primary channel instead of center channel ++ * ++ * 06 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add TX short GI compiling option ++ * ++ * 06 02 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Roll back to remove CFG_SUPPORT_BCM_TEST. ++ * ++ * 06 01 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Update BCM Test and RW configuration. ++ * ++ * 05 31 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add some compiling options to control 11n functions ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Set RTS threshold of 2K bytes initially ++ * ++ * 05 18 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Ad-hoc Beacon should not carry HT OP and OBSS IEs ++ * ++ * 05 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process 20/40 coexistence public action frame in AP mode ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Utilize status of swRfb to know channel number and band ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Different invoking order for WTBL entry of associated AP ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add virtual test for OBSS scan ++ * ++ * 04 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process Beacon only ready for infra STA now ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 03 24 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * fixed some WHQL testing error. ++ * ++ * 03 15 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Provide draft measurement and quiet functions ++ * ++ * 03 09 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * If bss is not 11n network, zero WTBL HT parameters ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * To support CFG_SUPPORT_BCM_STP ++ * ++ * 03 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Generate HT IE only depending on own phyTypeSet ++ * ++ * 03 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not fill HT related IE if BssInfo does not include 11n phySet ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * To store field AMPDU Parameters in STA_REC ++ * ++ * 02 26 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable RDG RX, but disable RDG TX for IOT and LongNAV ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Modify the parameter of rlmRecAssocRspHtInfo function ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix prBssInfo->ucPrimaryChannel handle for assoc resp ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add some function to process HT operation ++ * ++ * Nov 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Call rlmStatisticsInit() to handle MIB counters ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++static BOOLEAN ++rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++static BOOLEAN ++rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFsmEventInit(P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* Note: assume TIMER_T structures are reset to zero or stopped ++ * before invoking this function. ++ */ ++ ++ /* Initialize OBSS FSM */ ++ rlmObssInit(prAdapter); ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ rlmDomainCheckCountryPowerLimitTable(prAdapter); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 ucNetIdx; ++ ++ ASSERT(prAdapter); ++ ++ RLM_NET_FOR_EACH(ucNetIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; ++ ASSERT(prBssInfo); ++ ++ /* Note: all RLM timers will also be stopped. ++ * Now only one OBSS scan timer. ++ */ ++ rlmBssReset(prAdapter, prBssInfo); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe request, association request ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe request, association request ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ else if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ hs20FillExtCapIE(prAdapter, prBssInfo, prMsduInfo); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ P_IE_ERP_T prErpIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) { ++ prErpIe = (P_IE_ERP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ /* Add ERP IE */ ++ prErpIe->ucId = ELEM_ID_ERP_INFO; ++ prErpIe->ucLength = 1; ++ ++ prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ? ERP_INFO_USE_PROTECTION : 0; ++ ++ if (prBssInfo->fgErpProtectMode) ++ prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION); ++ ++ /* Handle barker preamble */ ++ if (!prBssInfo->fgUseShortPreamble) ++ prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE; ++ ++ ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prErpIe); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT32 ++rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, ++ BOOLEAN fgShortGIDisabled, ++ UINT_8 u8SupportRxSgi20, ++ UINT_8 u8SupportRxSgi40, ++ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf) ++{ ++ P_IE_HT_CAP_T prHtCap; ++ P_SUP_MCS_SET_FIELD prSupMcsSet; ++ ++ ASSERT(pOutBuf); ++ ++ prHtCap = (P_IE_HT_CAP_T) pOutBuf; ++ ++ /* Add HT capabilities IE */ ++ prHtCap->ucId = ELEM_ID_HT_CAP; ++ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; ++ ++ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; ++ if (!fg40mAllowed) { ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | ++ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); ++ } ++ if (fgShortGIDisabled) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++ ++ if (u8SupportRxSgi20 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); ++ if (u8SupportRxSgi40 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); ++ if (u8SupportRxGf == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); ++ if (u8SupportRxSTBC == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_RX_STBC_1_SS); ++ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; ++ ++ prSupMcsSet = &prHtCap->rSupMcsSet; ++ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); ++ ++ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); ++ ++ if (fg40mAllowed) ++ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ ++ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; ++ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; ++ ++ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; ++ if (!fg40mAllowed || eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); ++ ++ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; ++ ++ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; ++ ++ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); ++ ++ return IE_SIZE(prHtCap); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_IE_HT_CAP_T prHtCap; ++/* P_SUP_MCS_SET_FIELD prSupMcsSet; */ ++ BOOLEAN fg40mAllowed; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ASSERT(prMsduInfo); ++ ++ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; ++ ++ prHtCap = (P_IE_HT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++#if 0 ++ /* Add HT capabilities IE */ ++ prHtCap->ucId = ELEM_ID_HT_CAP; ++ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; ++ ++ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; ++ if (!fg40mAllowed) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | ++ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); ++ if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++ ++ if (prAdapter->rWifiVar.u8SupportRxSgi20 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); ++ if (prAdapter->rWifiVar.u8SupportRxSgi40 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); ++ if (prAdapter->rWifiVar.u8SupportRxGf == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); ++ ++ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; ++ ++ prSupMcsSet = &prHtCap->rSupMcsSet; ++ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); ++ ++ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); ++ ++ if (fg40mAllowed) ++ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ ++ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; ++ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; ++ ++ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; ++ if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); ++ ++ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; ++ ++ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; ++ ++ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prHtCap); ++#else ++ ++ prMsduInfo->u2FrameLength += rlmFillHtCapIEByParams(fg40mAllowed, ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, ++ prAdapter->rWifiVar.u8SupportRxSgi20, ++ prAdapter->rWifiVar.u8SupportRxSgi40, ++ prAdapter->rWifiVar.u8SupportRxGf, ++ prAdapter->rWifiVar.u8SupportRxSTBC, ++ prBssInfo->eCurrentOPMode, (UINT_8 *) prHtCap); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ P_HS20_EXT_CAP_T prHsExtCap; ++#else ++ P_EXT_CAP_T prExtCap; ++#endif ++ BOOLEAN fg40mAllowed; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ prHsExtCap = (P_HS20_EXT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ prHsExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; ++ else ++ prHsExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ ++ kalMemZero(prHsExtCap->aucCapabilities, sizeof(prHsExtCap->aucCapabilities)); ++ ++ prHsExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (!fg40mAllowed) ++ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { ++ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); ++ ++ /* For R2 WNM-Notification */ ++ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); ++ } ++ ++ ASSERT(IE_SIZE(prHsExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prHsExtCap); ++ ++#else ++ /* Add Extended Capabilities IE */ ++ prExtCap = (P_EXT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ ++ prExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ kalMemZero(prExtCap->aucCapabilities, sizeof(prExtCap->aucCapabilities)); ++ ++ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (!fg40mAllowed) ++ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; ++ ++ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme) ++{ ++ P_IE_HT_OP_T prHtOp; ++ UINT_16 i; ++ ++ prHtOp = (P_IE_HT_OP_T) pFme; ++ ++ /* Add HT operation IE */ ++ prHtOp->ucId = ELEM_ID_HT_OP; ++ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; ++ ++ /* RIFS and 20/40 bandwidth operations are included */ ++ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; ++ ++ /* Decide HT protection mode field */ ++ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; ++ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; ++ else { ++ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ ++ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; ++ } ++ ++ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { ++ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED ++ * Note: it will also be set in ad-hoc network ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; ++ } ++ ++ if (0 /* Regulatory class 16 */ && ++ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { ++ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection ++ * although it is possible to have no protection by spec. ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; ++ } ++ ++ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ ++ ++ /* No basic MCSx are needed temporarily */ ++ for (i = 0; i < 16; i++) ++ prHtOp->aucBasicMcsSet[i] = 0; ++ ++ return sizeof(IE_HT_OP_T); ++} ++ ++static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++/* P_IE_HT_OP_T prHtOp; */ ++/* UINT_16 i; */ ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ASSERT(prMsduInfo); ++ ++ prMsduInfo->u2FrameLength += rlmFillHtOpIeBody(prBssInfo, ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength)); ++#if 0 ++ prHtOp = (P_IE_HT_OP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ /* Add HT operation IE */ ++ prHtOp->ucId = ELEM_ID_HT_OP; ++ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; ++ ++ /* RIFS and 20/40 bandwidth operations are included */ ++ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; ++ ++ /* Decide HT protection mode field */ ++ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; ++ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; ++ else { ++ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ ++ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; ++ } ++ ++ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { ++ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED ++ * Note: it will also be set in ad-hoc network ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; ++ } ++ ++ if (0 /* Regulatory class 16 */ && ++ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { ++ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection ++ * although it is possible to have no protection by spec. ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; ++ } ++ ++ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ ++ ++ /* No basic MCSx are needed temporarily */ ++ for (i = 0; i < 16; i++) ++ prHtOp->aucBasicMcsSet[i] = 0; ++ ++ ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prHtOp); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked to update parameters of associated AP. ++* (Association response and Beacon) ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ UINT_16 u2Offset; ++ P_STA_RECORD_T prStaRec; ++ P_IE_HT_CAP_T prHtCap; ++ P_IE_HT_OP_T prHtOp; ++ P_IE_OBSS_SCAN_PARAM_T prObssScnParam; ++ UINT_8 ucERP, ucPrimaryChannel; ++#if CFG_SUPPORT_QUIET && 0 ++ BOOLEAN fgHasQuietIE = FALSE; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ASSERT(pucIE); ++ ++ prStaRec = prBssInfo->prStaRecOfAP; ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return 0; ++ ++ prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; ++ ucPrimaryChannel = 0; ++ prObssScnParam = NULL; ++ ++ /* Note: HT-related members in staRec may not be zero before, so ++ * if following IE does not exist, they are still not zero. ++ * These HT-related parameters are valid only when the corresponding ++ * BssInfo supports 802.11n, i.e., RLM_NET_IS_11N() ++ */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_HT_CAP: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) ++ break; ++ prHtCap = (P_IE_HT_CAP_T) pucIE; ++ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; ++ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; ++ ++ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; ++ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; ++ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; ++ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; ++ prStaRec->ucAselCap = prHtCap->ucAselCap; ++ break; ++ ++ case ELEM_ID_HT_OP: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) ++ break; ++ prHtOp = (P_IE_HT_OP_T) pucIE; ++ /* Workaround that some APs fill primary channel field by its ++ * secondary channel, but its DS IE is correct 20110610 ++ */ ++ if (ucPrimaryChannel == 0) ++ ucPrimaryChannel = prHtOp->ucPrimaryChannel; ++ prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1; ++ prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2; ++ prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3; ++ ++ if (!prBssInfo->fg40mBwAllowed) ++ prBssInfo->ucHtOpInfo1 &= ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH); ++ ++ if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) ++ prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)(prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO); ++ ++ prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T) ++ (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION); ++ ++ /* To do: process regulatory class 16 */ ++ if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) ++ && 0 /* && regulatory class is 16 */) ++ prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED; ++ else if (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) ++ prBssInfo->eGfOperationMode = GF_MODE_PROTECT; ++ else ++ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; ++ ++ prBssInfo->eRifsOperationMode = ++ (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ? RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED; ++ ++ break; ++ ++ case ELEM_ID_20_40_BSS_COEXISTENCE: ++ if (!RLM_NET_IS_11N(prBssInfo)) ++ break; ++ /* To do: store if scanning exemption grant to BssInfo */ ++ break; ++ ++ case ELEM_ID_OBSS_SCAN_PARAMS: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) ++ break; ++ /* Store OBSS parameters to BssInfo */ ++ prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE; ++ break; ++ ++ case ELEM_ID_EXTENDED_CAP: ++ if (!RLM_NET_IS_11N(prBssInfo)) ++ break; ++ /* To do: store extended capability (PSMP, coexist) to BssInfo */ ++ break; ++ ++ case ELEM_ID_ERP_INFO: ++ if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) || prBssInfo->eBand != BAND_2G4) ++ break; ++ ucERP = ERP_INFO_IE(pucIE)->ucERP; ++ prBssInfo->fgErpProtectMode = (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE; ++ ++ if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) ++ prBssInfo->fgUseShortPreamble = FALSE; ++ break; ++ ++ case ELEM_ID_DS_PARAM_SET: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) ++ ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; ++ break; ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++ case ELEM_ID_CH_SW_ANNOUNCEMENT: ++ { ++ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) pucIE); ++ } ++ break; ++ ++#if CFG_SUPPORT_QUIET && 0 ++ /* Note: RRM code should be moved to independent RRM function by ++ * component design rule. But we attach it to RLM temporarily ++ */ ++ case ELEM_ID_QUIET: ++ rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE); ++ fgHasQuietIE = TRUE; ++ break; ++#endif ++#endif ++ ++ default: ++ break; ++ } /* end of switch */ ++ } /* end of IE_FOR_EACH */ ++ ++ /* Some AP will have wrong channel number (255) when running time. ++ * Check if correct channel number information. 20110501 ++ */ ++ if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) || ++ (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14))) ++ ucPrimaryChannel = 0; ++#if CFG_SUPPORT_QUIET && 0 ++ if (!fgHasQuietIE) ++ rrmQuietIeNotExist(prAdapter, prBssInfo); ++#endif ++ ++ /* Check if OBSS scan process will launch */ ++ if (!prAdapter->fgEnOnlineScan || !prObssScnParam || ++ !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) || ++ prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) { ++ ++ /* Note: it is ok not to stop rObssScanTimer() here */ ++ prBssInfo->u2ObssScanInterval = 0; ++ } else { ++ if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) ++ prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL; ++ if (prBssInfo->u2ObssScanInterval != prObssScnParam->u2TriggerScanInterval) { ++ ++ prBssInfo->u2ObssScanInterval = prObssScnParam->u2TriggerScanInterval; ++ ++ /* Start timer to trigger OBSS scanning */ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, ++ prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); ++ } ++ } ++ ++ return ucPrimaryChannel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief AIS or P2P GC. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN ++rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ UINT_16 u2Offset, i; ++ UINT_8 ucPriChannel, ucSecChannel; ++ ENUM_CHNL_EXT_T eSCO; ++ BOOLEAN fgHtBss, fg20mReq; ++ ++ if ((prAdapter == NULL) ++ || (pucIE == NULL) ++ || (prBssInfo == NULL) ++ || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ /* Record it to channel list to change 20/40 bandwidth */ ++ ucPriChannel = 0; ++ eSCO = CHNL_EXT_SCN; ++ ++ fgHtBss = FALSE; ++ fg20mReq = FALSE; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_HT_CAP: ++ { ++ P_IE_HT_CAP_T prHtCap; ++ ++ if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) ++ break; ++ ++ prHtCap = (P_IE_HT_CAP_T) pucIE; ++ if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) ++ fg20mReq = TRUE; ++ fgHtBss = TRUE; ++ break; ++ } ++ case ELEM_ID_HT_OP: ++ { ++ P_IE_HT_OP_T prHtOp; ++ ++ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) ++ break; ++ ++ prHtOp = (P_IE_HT_OP_T) pucIE; ++ /* Workaround that some APs fill primary channel field by its ++ * secondary channel, but its DS IE is correct 20110610 ++ */ ++ if (ucPriChannel == 0) ++ ucPriChannel = prHtOp->ucPrimaryChannel; ++ ++ if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) ++ eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO); ++ break; ++ } ++ case ELEM_ID_20_40_BSS_COEXISTENCE: ++ { ++ P_IE_20_40_COEXIST_T prCoexist; ++ ++ if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) ++ break; ++ ++ prCoexist = (P_IE_20_40_COEXIST_T) pucIE; ++ if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) ++ fg20mReq = TRUE; ++ break; ++ } ++ case ELEM_ID_DS_PARAM_SET: ++ if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) ++ break; ++ ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* To do: Update channel list and 5G band. All channel lists have the same ++ * update procedure. We should give it the entry pointer of desired ++ * channel list. ++ */ ++ if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) ++ return FALSE; ++ ++ if (ucPriChannel == 0 || ucPriChannel > 14) ++ ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); ++ ++ if (fgHtBss) { ++ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_PriChnlList[i] = ucPriChannel; ++ prBssInfo->auc2G_PriChnlList[0]++; ++ } ++ ++ /* Update secondary channel */ ++ if (eSCO != CHNL_EXT_SCN) { ++ ucSecChannel = (eSCO == CHNL_EXT_SCA) ? (ucPriChannel + 4) : (ucPriChannel - 4); ++ ++ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_SecChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_SecChnlList[i] = ucSecChannel; ++ prBssInfo->auc2G_SecChnlList[0]++; ++ } ++ } ++ ++ /* Update 20M bandwidth request channels */ ++ if (fg20mReq) { ++ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel; ++ prBssInfo->auc2G_20mReqChnlList[0]++; ++ } ++ } ++ } else { ++ /* Update non-HT channel list */ ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel; ++ prBssInfo->auc2G_NonHtChnlList[0]++; ++ } ++ ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief AIS or P2P GC. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN ++rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ if ((prAdapter == NULL) ++ || (pucIE == NULL) ++ || (prBssInfo == NULL) ++ || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++#if 0 /* SW migration 2010/8/20 */ ++ /* Note: we shall not update parameters when scanning, otherwise ++ * channel and bandwidth will not be correct or asserted failure ++ * during scanning. ++ * Note: remove channel checking. All received Beacons should be processed ++ * if measurement or other actions are executed in adjacent channels ++ * and Beacon content checking mechanism is not disabled. ++ */ ++ if (IS_SCAN_ACTIVE() ++ /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */ ++ ) { ++ return FALSE; ++ } ++#endif ++ ++ /* Handle change of slot time */ ++ prBssInfo->u2CapInfo = ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->u2CapInfo; ++ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; ++ ++ rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ P_BSS_INFO_T prBssInfo; ++ BOOLEAN fgNewParameter; ++ UINT_8 ucNetIdx; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ fgNewParameter = FALSE; ++ ++ /* When concurrent networks exist, GO shall have the same handle as ++ * the other BSS, so the Beacon shall be processed for bandwidth and ++ * protection mechanism. ++ * Note1: we do not have 2 AP (GO) cases simultaneously now. ++ * Note2: If we are GO, concurrent AIS AP should detect it and reflect ++ * action in its Beacon, so AIS STA just follows Beacon from AP. ++ */ ++ RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; ++ ASSERT(prBssInfo); ++ ++ if (IS_BSS_ACTIVE(prBssInfo)) { ++ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && ++ prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* P2P client or AIS infra STA */ ++ if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, ((P_WLAN_MAC_MGMT_HEADER_T) ++ (prSwRfb->pvHeader))->aucBSSID)) { ++ ++ fgNewParameter = rlmRecBcnInfoForClient(prAdapter, ++ prBssInfo, prSwRfb, pucIE, u2IELength); ++ } else { ++ fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter, ++ prBssInfo, prSwRfb, pucIE, ++ u2IELength); ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered && ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || ++ prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) { ++ /* AP scan to check if 20/40M bandwidth is permitted */ ++ rlmRecBcnFromNeighborForClient(prAdapter, prBssInfo, prSwRfb, pucIE, u2IELength); ++ } ++#endif ++ else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ /* Do nothing */ ++ /* To do: Ad-hoc */ ++ } ++ ++ /* Appy new parameters if necessary */ ++ if (fgNewParameter) { ++ DBGLOG(RLM, TRACE, "rlmProcessBcn\n"); ++ rlmSyncOperationParams(prAdapter, prBssInfo); ++ fgNewParameter = FALSE; ++ } ++ } /* end of IS_BSS_ACTIVE() */ ++ } /* end of RLM_NET_FOR_EACH_NO_BOW */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked after judging successful association. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ UINT_8 ucPriChannel; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ASSERT(prStaRec == prBssInfo->prStaRecOfAP); ++ ++ /* To do: the invoked function is used to clear all members. It may be ++ * done by center mechanism in invoker. ++ */ ++ rlmBssReset(prAdapter, prBssInfo); ++ ++ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; ++ ++ ucPriChannel = rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); ++ if (ucPriChannel > 0) ++ prBssInfo->ucPrimaryChannel = ucPriChannel; ++ ++ if (!RLM_NET_IS_11N(prBssInfo) || !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) ++ prBssInfo->fg40mBwAllowed = FALSE; ++ ++ /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which ++ * shall be invoked afterwards. ++ * Update channel, bandwidth and protection mode by nicUpdateBss() ++ */ ++#if 1 ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ ++ DBGLOG(P2P, WARN, "Force P2P BW to 20\n"); ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked after judging successful association. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prCmdBody && prBssInfo); ++ if (!prCmdBody || !prBssInfo) ++ return; ++ ++ prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; ++ prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand; ++ prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO; ++ prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode; ++ prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode; ++ prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode; ++ prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode; ++ prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3; ++ prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2; ++ prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1; ++ prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble; ++ prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime; ++ prCmdBody->ucCheckId = 0x72; ++ ++ if (RLM_NET_PARAM_VALID(prBssInfo)) { ++ DBGLOG(RLM, INFO, "N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n", ++ prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand, ++ prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco, ++ prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode, ++ prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime, ++ prCmdBody->ucUseShortPreamble); ++ } else { ++ DBGLOG(RLM, TRACE, "N=%d closed\n", prCmdBody->ucNetTypeIndex); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will operation parameters based on situations of ++* concurrent networks. Channel, bandwidth, protection mode, supported ++* rate will be modified. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ P_CMD_SET_BSS_RLM_PARAM_T prCmdBody; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T)); ++ ASSERT(prCmdBody); ++ ++ /* To do: exception handle */ ++ if (!prCmdBody) { ++ DBGLOG(RLM, WARN, "No buf for sync RLM params (Net=%d)\n", prBssInfo->ucNetTypeIndex); ++ return; ++ } ++ ++ rlmFillSyncCmdParam(prCmdBody, prBssInfo); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_BSS_RLM_PARAM, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SET_BSS_RLM_PARAM_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdBody, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdBody); ++} ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked after judging successful association. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ P_IE_HT_CAP_T prHtCap; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_HT_CAP: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) ++ break; ++ prHtCap = (P_IE_HT_CAP_T) pucIE; ++ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; ++ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; ++ ++ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; ++ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; ++ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; ++ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; ++ prStaRec->ucAselCap = prHtCap->ucAselCap; ++ break; ++ ++ default: ++ break; ++ } /* end of switch */ ++ } /* end of IE_FOR_EACH */ ++} ++#endif /* CFG_SUPPORT_AAA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief It is for both STA and AP modes ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ rlmBssInitForAP(prAdapter, prBssInfo); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief It is for both STA and AP modes ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ rlmBssReset(prAdapter, prBssInfo); ++ ++ prBssInfo->fg40mBwAllowed = FALSE; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ ++ /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so ++ * the sync CMD is not needed here. ++ */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief All RLM timers will also be stopped. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ /* HT related parameters */ ++ prBssInfo->ucHtOpInfo1 = 0; /* RIFS disabled. 20MHz */ ++ prBssInfo->u2HtOpInfo2 = 0; ++ prBssInfo->u2HtOpInfo3 = 0; ++ ++ prBssInfo->eBssSCO = 0; ++ prBssInfo->fgErpProtectMode = 0; ++ prBssInfo->eHtProtectMode = 0; ++ prBssInfo->eGfOperationMode = 0; ++ prBssInfo->eRifsOperationMode = 0; ++ ++ /* OBSS related parameters */ ++ prBssInfo->auc2G_20mReqChnlList[0] = 0; ++ prBssInfo->auc2G_NonHtChnlList[0] = 0; ++ prBssInfo->auc2G_PriChnlList[0] = 0; ++ prBssInfo->auc2G_SecChnlList[0] = 0; ++ prBssInfo->auc5G_20mReqChnlList[0] = 0; ++ prBssInfo->auc5G_NonHtChnlList[0] = 0; ++ prBssInfo->auc5G_PriChnlList[0] = 0; ++ prBssInfo->auc5G_SecChnlList[0] = 0; ++ ++ /* All RLM timers will also be stopped */ ++ cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer); ++ prBssInfo->u2ObssScanInterval = 0; ++ ++ prBssInfo->fgObssErpProtectMode = 0; /* GO only */ ++ prBssInfo->eObssHtProtectMode = 0; /* GO only */ ++ prBssInfo->eObssGfOperationMode = 0; /* GO only */ ++ prBssInfo->fgObssRifsOperationMode = 0; /* GO only */ ++ prBssInfo->fgObssActionForcedTo20M = 0; /* GO only */ ++ prBssInfo->fgObssBeaconForcedTo20M = 0; /* GO only */ ++} ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function handle spectrum management action frame ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_CHANNEL_SWITCH_FRAME prRxFrame; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ DBGLOG(RLM, INFO, "[5G DFS]rlmProcessSpecMgtAction \r\n"); ++ ++ prRxFrame = (P_ACTION_CHANNEL_SWITCH_FRAME) prSwRfb->pvHeader; ++ DBGLOG(RLM, INFO, "[5G DFS]prRxFrame->ucAction[%d] \r\n", prRxFrame->ucAction); ++ if (prRxFrame->ucAction == ACTION_CHNL_SWITCH) ++ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) prRxFrame->aucInfoElem); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function process Channel Switch IE ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prChannelSwitchIE); ++ ++ DBGLOG(RLM, INFO, "[5G DFS] rlmProcessChannelSwitchIE \r\n"); ++ DBGLOG(RLM, INFO, "[5G DFS] ucChannelSwitchMode[%d], ucChannelSwitchCount[%d], ucNewChannelNum[%d] \r\n", ++ prChannelSwitchIE->ucChannelSwitchMode, ++ prChannelSwitchIE->ucChannelSwitchCount, prChannelSwitchIE->ucNewChannelNum); ++ if (prChannelSwitchIE->ucChannelSwitchMode == 1) { ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ DBGLOG(RLM, INFO, "[5G DFS] switch channel [%d]->[%d] \r\n", prAisBssInfo->ucPrimaryChannel, ++ prChannelSwitchIE->ucNewChannelNum); ++ prAisBssInfo->ucPrimaryChannel = prChannelSwitchIE->ucNewChannelNum; ++ nicUpdateBss(prAdapter, prAisBssInfo->ucNetTypeIndex); ++ } ++ ++} ++ ++#endif ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++VOID ++rlmTxRateEnhanceConfig( ++ P_ADAPTER_T prAdapter ++ ) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ CMD_RLM_INFO_T rTxRInfo; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ++ /* init */ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* suggestion from Tsaiyuan.Hsu */ ++ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); ++ rTxRInfo.fgIsErrRatioEnhanceApplied = TRUE; ++ rTxRInfo.ucErrRatio2LimitMinRate = 3; ++ rTxRInfo.ucMinLegacyRateIdx = 2; ++ rTxRInfo.cMinRssiThreshold = -60; ++ rTxRInfo.fgIsRtsApplied = TRUE; ++ rTxRInfo.ucRecoverTime = 60; ++ ++ DBGLOG(RLM, INFO, "Enable tx rate enhance function\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetTxRateInfo, ++ &rTxRInfo, ++ sizeof(rTxRInfo), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(RLM, WARN, "set tx rate advance info fail 0x%lx\n", rStatus); ++} ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a command to TX Auto Rate module. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ UINT_32 u4Subcmd; ++ ++ ++ /* parse TAR sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(RLM, INFO, " sub command = %u\n", (UINT32)u4Subcmd); ++ ++ /* handle different sub-command */ ++ switch (u4Subcmd) { ++ case 0x00: /* configure */ ++ /* iwpriv wlan0 set_str_cmd 1_0_0_1_3_2_60_1_60 */ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ CMD_RLM_INFO_T rTxRInfo; ++ UINT_32 u4SetInfoLen = 0; ++ ++ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); ++ rTxRInfo.u4Version = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.fgIsErrRatioEnhanceApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.ucErrRatio2LimitMinRate = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.ucMinLegacyRateIdx = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.cMinRssiThreshold = 0 - CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.fgIsRtsApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.ucRecoverTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(RLM, INFO, " rlmCmd = %u %u %u %u %d %u %u\n", ++ rTxRInfo.u4Version, ++ rTxRInfo.fgIsErrRatioEnhanceApplied, ++ rTxRInfo.ucErrRatio2LimitMinRate, ++ rTxRInfo.ucMinLegacyRateIdx, ++ rTxRInfo.cMinRssiThreshold, ++ rTxRInfo.fgIsRtsApplied, ++ rTxRInfo.ucRecoverTime)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetTxRateInfo, ++ &rTxRInfo, ++ sizeof(rTxRInfo), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4SetInfoLen); ++ break; ++ ++ default: ++ break; ++ } ++} ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c +new file mode 100644 +index 000000000000..5e127488ea49 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c +@@ -0,0 +1,1791 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_domain.c#1 ++*/ ++ ++/*! \file "rlm_domain.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm_domain.c ++ * ++ * 11 10 2011 cm.chang ++ * NULL ++ * Modify debug message for XLOG ++ * ++ * 09 29 2011 cm.chang ++ * NULL ++ * Change the function prototype of rlmDomainGetChnlList() ++ * ++ * 09 23 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Let channel number to zero if band is illegal ++ * ++ * 09 22 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Exclude channel list with illegal band ++ * ++ * 09 15 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use defined country group to have a change to add new group ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Provide legal channel function based on domain ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support for WiFi Direct Network. ++ * ++ * 03 02 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Export rlmDomainGetDomainInfo for p2p driver. ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 03 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Filter out not supported RF freq when reporting available chnl list ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Provide query function about full channel list. ++ * ++ * Dec 1 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++#include "rlm_txpwr_init.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* The following country or domain shall be set from host driver. ++ * And host driver should pass specified DOMAIN_INFO_ENTRY to MT6620 as ++ * the channel list of being a STA to do scanning/searching AP or being an ++ * AP to choose an adequate channel if auto-channel is set. ++ */ ++ ++/* Define mapping tables between country code and its channel set ++ */ ++static const UINT_16 g_u2CountryGroup0[] = { ++ COUNTRY_CODE_AO, COUNTRY_CODE_BZ, COUNTRY_CODE_BJ, COUNTRY_CODE_BT, ++ COUNTRY_CODE_BO, COUNTRY_CODE_BI, COUNTRY_CODE_CM, COUNTRY_CODE_CF, ++ COUNTRY_CODE_TD, COUNTRY_CODE_KM, COUNTRY_CODE_CD, COUNTRY_CODE_CG, ++ COUNTRY_CODE_CI, COUNTRY_CODE_DJ, COUNTRY_CODE_GQ, COUNTRY_CODE_ER, ++ COUNTRY_CODE_FJ, COUNTRY_CODE_GA, COUNTRY_CODE_GM, COUNTRY_CODE_GN, ++ COUNTRY_CODE_GW, COUNTRY_CODE_RKS, COUNTRY_CODE_KG, COUNTRY_CODE_LY, ++ COUNTRY_CODE_MG, COUNTRY_CODE_ML, COUNTRY_CODE_NR, COUNTRY_CODE_NC, ++ COUNTRY_CODE_ST, COUNTRY_CODE_SC, COUNTRY_CODE_SL, COUNTRY_CODE_SB, ++ COUNTRY_CODE_SO, COUNTRY_CODE_SR, COUNTRY_CODE_SZ, COUNTRY_CODE_TJ, ++ COUNTRY_CODE_TG, COUNTRY_CODE_TO, COUNTRY_CODE_TM, COUNTRY_CODE_TV, ++ COUNTRY_CODE_VU, COUNTRY_CODE_YE ++}; ++ ++static const UINT_16 g_u2CountryGroup1[] = { ++ COUNTRY_CODE_AS, COUNTRY_CODE_AI, COUNTRY_CODE_BM, COUNTRY_CODE_CA, ++ COUNTRY_CODE_KY, COUNTRY_CODE_GU, COUNTRY_CODE_FM, COUNTRY_CODE_PR, ++ COUNTRY_CODE_US, COUNTRY_CODE_VI ++}; ++ ++static const UINT_16 g_u2CountryGroup2[] = { ++ COUNTRY_CODE_AR, COUNTRY_CODE_AU, COUNTRY_CODE_AZ, COUNTRY_CODE_BW, ++ COUNTRY_CODE_KH, COUNTRY_CODE_CX, COUNTRY_CODE_CO, COUNTRY_CODE_CR, ++#if (CFG_CN_SUPPORT_CLASS121 == 1) ++ COUNTRY_CODE_CN, ++#endif ++ COUNTRY_CODE_EC, COUNTRY_CODE_GD, COUNTRY_CODE_GT, COUNTRY_CODE_HK, ++ COUNTRY_CODE_KI, COUNTRY_CODE_LB, COUNTRY_CODE_LR, COUNTRY_CODE_MN, ++ COUNTRY_CODE_AN, COUNTRY_CODE_NZ, COUNTRY_CODE_NI, COUNTRY_CODE_PW, ++ COUNTRY_CODE_PY, COUNTRY_CODE_PE, COUNTRY_CODE_PH, COUNTRY_CODE_WS, ++ COUNTRY_CODE_SG, COUNTRY_CODE_LK, COUNTRY_CODE_TH, COUNTRY_CODE_TT, ++ COUNTRY_CODE_UY, COUNTRY_CODE_VN ++}; ++ ++static const UINT_16 g_u2CountryGroup3[] = { ++ COUNTRY_CODE_AW, COUNTRY_CODE_LA, COUNTRY_CODE_SA, COUNTRY_CODE_AE, ++ COUNTRY_CODE_UG ++}; ++ ++static const UINT_16 g_u2CountryGroup4[] = { COUNTRY_CODE_MM }; ++ ++static const UINT_16 g_u2CountryGroup5[] = { ++ COUNTRY_CODE_AL, COUNTRY_CODE_DZ, COUNTRY_CODE_AD, COUNTRY_CODE_AT, ++ COUNTRY_CODE_BY, COUNTRY_CODE_BE, COUNTRY_CODE_BA, COUNTRY_CODE_VG, ++ COUNTRY_CODE_BG, COUNTRY_CODE_CV, COUNTRY_CODE_HR, COUNTRY_CODE_CY, ++ COUNTRY_CODE_CZ, COUNTRY_CODE_DK, COUNTRY_CODE_EE, COUNTRY_CODE_ET, ++ COUNTRY_CODE_FI, COUNTRY_CODE_FR, COUNTRY_CODE_GF, COUNTRY_CODE_PF, ++ COUNTRY_CODE_TF, COUNTRY_CODE_GE, COUNTRY_CODE_DE, COUNTRY_CODE_GH, ++ COUNTRY_CODE_GR, COUNTRY_CODE_GP, COUNTRY_CODE_HU, COUNTRY_CODE_IS, ++ COUNTRY_CODE_IQ, COUNTRY_CODE_IE, COUNTRY_CODE_IT, COUNTRY_CODE_KE, ++ COUNTRY_CODE_LV, COUNTRY_CODE_LS, COUNTRY_CODE_LI, COUNTRY_CODE_LT, ++ COUNTRY_CODE_LU, COUNTRY_CODE_MK, COUNTRY_CODE_MT, COUNTRY_CODE_MQ, ++ COUNTRY_CODE_MR, COUNTRY_CODE_MU, COUNTRY_CODE_YT, COUNTRY_CODE_MD, ++ COUNTRY_CODE_MC, COUNTRY_CODE_ME, COUNTRY_CODE_MS, COUNTRY_CODE_NL, ++ COUNTRY_CODE_NO, COUNTRY_CODE_OM, COUNTRY_CODE_PL, COUNTRY_CODE_PT, ++ COUNTRY_CODE_RE, COUNTRY_CODE_RO, COUNTRY_CODE_MF, COUNTRY_CODE_SM, ++ COUNTRY_CODE_SN, COUNTRY_CODE_RS, COUNTRY_CODE_SK, COUNTRY_CODE_SI, ++ COUNTRY_CODE_ZA, COUNTRY_CODE_ES, COUNTRY_CODE_SE, COUNTRY_CODE_CH, ++ COUNTRY_CODE_TR, COUNTRY_CODE_TC, COUNTRY_CODE_GB, COUNTRY_CODE_VA, ++ COUNTRY_CODE_EU ++}; ++ ++static const UINT_16 g_u2CountryGroup6[] = { COUNTRY_CODE_JP }; ++ ++static const UINT_16 g_u2CountryGroup7[] = { ++ COUNTRY_CODE_AM, COUNTRY_CODE_IL, COUNTRY_CODE_KW, COUNTRY_CODE_MA, ++ COUNTRY_CODE_NE, COUNTRY_CODE_TN, COUNTRY_CODE_MA ++}; ++ ++static const UINT_16 g_u2CountryGroup8[] = { COUNTRY_CODE_NP }; ++ ++static const UINT_16 g_u2CountryGroup9[] = { COUNTRY_CODE_AF }; ++ ++static const UINT_16 g_u2CountryGroup10[] = { ++ COUNTRY_CODE_AG, COUNTRY_CODE_BS, COUNTRY_CODE_BH, COUNTRY_CODE_BB, ++ COUNTRY_CODE_BN, COUNTRY_CODE_CL, COUNTRY_CODE_EG, ++#if (CFG_CN_SUPPORT_CLASS121 == 0) ++ COUNTRY_CODE_CN, ++#endif ++ COUNTRY_CODE_SV, COUNTRY_CODE_IN, COUNTRY_CODE_MY, COUNTRY_CODE_MV, ++ COUNTRY_CODE_PA, COUNTRY_CODE_VE, COUNTRY_CODE_ZM ++}; ++ ++static const UINT_16 g_u2CountryGroup11[] = { COUNTRY_CODE_JO, COUNTRY_CODE_PG }; ++ ++static const UINT_16 g_u2CountryGroup12[] = { ++ COUNTRY_CODE_BF, COUNTRY_CODE_GY, COUNTRY_CODE_HT, COUNTRY_CODE_HN, ++ COUNTRY_CODE_JM, COUNTRY_CODE_MO, COUNTRY_CODE_MW, COUNTRY_CODE_PK, ++ COUNTRY_CODE_QA, COUNTRY_CODE_RW, COUNTRY_CODE_KN, COUNTRY_CODE_TZ ++}; ++ ++static const UINT_16 g_u2CountryGroup13[] = { COUNTRY_CODE_ID }; ++ ++static const UINT_16 g_u2CountryGroup14[] = { COUNTRY_CODE_KR }; ++ ++static const UINT_16 g_u2CountryGroup15[] = { COUNTRY_CODE_NG }; ++ ++static const UINT_16 g_u2CountryGroup16[] = { ++ COUNTRY_CODE_BD, COUNTRY_CODE_BR, COUNTRY_CODE_DM, COUNTRY_CODE_DO, ++ COUNTRY_CODE_FK, COUNTRY_CODE_KZ, COUNTRY_CODE_MX, COUNTRY_CODE_MZ, ++ COUNTRY_CODE_NA, COUNTRY_CODE_RU, COUNTRY_CODE_LC, COUNTRY_CODE_VC, ++ COUNTRY_CODE_UA, COUNTRY_CODE_UZ, COUNTRY_CODE_ZW ++}; ++ ++static const UINT_16 g_u2CountryGroup17[] = { COUNTRY_CODE_MP }; ++ ++static const UINT_16 g_u2CountryGroup18[] = { COUNTRY_CODE_TW }; ++ ++static const UINT_16 g_u2CountryGroup19[] = { ++ COUNTRY_CODE_CK, COUNTRY_CODE_CU, COUNTRY_CODE_TL, COUNTRY_CODE_FO, ++ COUNTRY_CODE_GI, COUNTRY_CODE_GG, COUNTRY_CODE_IR, COUNTRY_CODE_IM, ++ COUNTRY_CODE_JE, COUNTRY_CODE_KP, COUNTRY_CODE_MH, COUNTRY_CODE_NU, ++ COUNTRY_CODE_NF, COUNTRY_CODE_PS, COUNTRY_CODE_PN, COUNTRY_CODE_PM, ++ COUNTRY_CODE_SS, COUNTRY_CODE_SD, COUNTRY_CODE_SY ++}; ++ ++static const UINT_16 g_u2CountryGroup20[] = { ++ COUNTRY_CODE_DF, COUNTRY_CODE_FF ++ /* When country code is not found and no matched NVRAM setting, ++ * this domain info will be used. ++ */ ++}; ++ ++static const UINT_16 g_u2CountryGroup21[] = { ++ COUNTRY_CODE_UDF ++}; ++ ++DOMAIN_INFO_ENTRY arSupportedRegDomains[] = { ++ { ++ (PUINT_16) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_NA */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} ++ , /* CH_SET_2G4_1_11 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup2, sizeof(g_u2CountryGroup2) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ {82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE} ++ , /* CH_SET_2G4_14_14 */ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup7, sizeof(g_u2CountryGroup7) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup8, sizeof(g_u2CountryGroup8) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup10, sizeof(g_u2CountryGroup10) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup11, sizeof(g_u2CountryGroup11) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_NA */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_NA */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup14, sizeof(g_u2CountryGroup14) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 8, FALSE} ++ , /* CH_SET_UNII_WW_100_128 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup15, sizeof(g_u2CountryGroup15) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup16, sizeof(g_u2CountryGroup16) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup17, sizeof(g_u2CountryGroup17) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} ++ , /* CH_SET_2G4_1_11 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup18, sizeof(g_u2CountryGroup18) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} ++ , /* CH_SET_2G4_1_11 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, FALSE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup19, sizeof(g_u2CountryGroup19) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ /* Note: Default group if no matched country code */ ++ (PUINT_16) g_u2CountryGroup20, sizeof(g_u2CountryGroup20) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ /* Note: for customer configured their own scanning list and passive scan list */ ++ (PUINT_16) g_u2CountryGroup21, sizeof(g_u2CountryGroup21) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 12, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE} ++ , ++ {118, BAND_5G, CHNL_SPAN_20, 52, 0, FALSE} ++ , ++ {121, BAND_5G, CHNL_SPAN_20, 100, 0, FALSE} ++ , ++ {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE} ++ , ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++}; ++ ++static UINT_16 g_u2CountryGroup0_Passive[] = { ++ COUNTRY_CODE_UDF ++}; ++ ++DOMAIN_INFO_ENTRY arSupportedRegDomains_Passive[] = { ++ { ++ /* Default passive scan channel table is empty */ ++ COUNTRY_CODE_NULL, 0, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 11, 0, 0}, /* CH_SET_2G4_1_14 */ ++ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ ++ } ++ }, ++ { ++ /* User Defined passive scan channel table */ ++ g_u2CountryGroup0_Passive, 0, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 12, 1, 0}, /* CH_SET_2G4_1_14 */ ++ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ ++ } ++ } ++}; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++SUBBAND_CHANNEL_T g_rRlmSubBand[] = { ++ ++ {BAND_2G4_LOWER_BOUND, BAND_2G4_UPPER_BOUND, 1, 0} ++ , /* 2.4G */ ++ {UNII1_LOWER_BOUND, UNII1_UPPER_BOUND, 2, 0} ++ , /* ch36,38,40,..,48 */ ++ {UNII2A_LOWER_BOUND, UNII2A_UPPER_BOUND, 2, 0} ++ , /* ch52,54,56,..,64 */ ++ {UNII2C_LOWER_BOUND, UNII2C_UPPER_BOUND, 2, 0} ++ , /* ch100,102,104,...,144 */ ++ {UNII3_LOWER_BOUND, UNII3_UPPER_BOUND, 2, 0} ++ /* ch149,151,153,....,173 */ ++}; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter) ++{ ++#define REG_DOMAIN_DEF_IDX 20 /* Default country domain */ ++#define REG_DOMAIN_GROUP_NUM \ ++ (sizeof(arSupportedRegDomains) / sizeof(DOMAIN_INFO_ENTRY)) ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ P_REG_INFO_T prRegInfo; ++ UINT_16 u2TargetCountryCode; ++ UINT_16 i, j; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->prDomainInfo) ++ return prAdapter->prDomainInfo; ++ ++ prRegInfo = &prAdapter->prGlueInfo->rRegInfo; ++ ++ DBGLOG(RLM, TRACE, "eRegChannelListMap=%d, u2CountryCode=0x%04x\n", ++ prRegInfo->eRegChannelListMap, ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode); ++ ++ /* ++ * Domain info can be specified by given idx of arSupportedRegDomains table, ++ * customized, or searched by country code, ++ * only one is set among these three methods in NVRAM. ++ */ ++ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX && ++ prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) { ++ /* by given table idx */ ++ DBGLOG(RLM, TRACE, "ucRegChannelListIndex=%d\n", prRegInfo->ucRegChannelListIndex); ++ prDomainInfo = &arSupportedRegDomains[prRegInfo->ucRegChannelListIndex]; ++ } else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { ++ /* by customized */ ++ prDomainInfo = &prRegInfo->rDomainInfo; ++ } else { ++ /* by country code */ ++ u2TargetCountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ ++ for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) { ++ prDomainInfo = &arSupportedRegDomains[i]; ++ ++ if ((prDomainInfo->u4CountryNum && prDomainInfo->pu2CountryGroup) || ++ prDomainInfo->u4CountryNum == 0) { ++ for (j = 0; j < prDomainInfo->u4CountryNum; j++) { ++ if (prDomainInfo->pu2CountryGroup[j] == u2TargetCountryCode) ++ break; ++ } ++ if (j < prDomainInfo->u4CountryNum) ++ break; /* Found */ ++ } ++ } ++ ++ /* If no matched country code, use the default country domain */ ++ if (i >= REG_DOMAIN_GROUP_NUM) { ++ DBGLOG(RLM, INFO, "No matched country code, use the default country domain\n"); ++ prDomainInfo = &arSupportedRegDomains[REG_DOMAIN_DEF_IDX]; ++ } ++ } ++ ++ prAdapter->prDomainInfo = prDomainInfo; ++ return prDomainInfo; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] The input variable pointed by pucNumOfChannel is the max ++* arrary size. The return value indciates meaning list size. ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rlmDomainGetChnlList(P_ADAPTER_T prAdapter, ++ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, ++ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList) ++{ ++ UINT_8 i, j, ucNum; ++ P_DOMAIN_SUBBAND_INFO prSubband; ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(paucChannelList); ++ ASSERT(pucNumOfChannel); ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ ucNum = 0; ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubband = &prDomainInfo->rSubBand[i]; ++ ++ if (prSubband->ucBand == BAND_NULL || prSubband->ucBand >= BAND_NUM || ++ (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand)) ++ continue; ++ ++ if (fgNoDfs == TRUE && prSubband->fgDfs == TRUE) ++ continue; ++ ++ if (eSpecificBand == BAND_NULL || prSubband->ucBand == eSpecificBand) { ++ for (j = 0; j < prSubband->ucNumChannels; j++) { ++ if (ucNum >= ucMaxChannelNum) ++ break; ++ paucChannelList[ucNum].eBand = prSubband->ucBand; ++ paucChannelList[ucNum].ucChannelNum = ++ prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan; ++ ucNum++; ++ } ++ } ++ } ++ ++ *pucNumOfChannel = ucNum; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) ++{ ++ rlmDomainSendDomainInfoCmd(prAdapter, fgIsOid); ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ rlmDomainSendPwrLimitCmd(prAdapter); ++#endif ++ rlmDomainSendPassiveScanInfoCmd(prAdapter, fgIsOid); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) ++{ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ P_CMD_SET_DOMAIN_INFO_T prCmd; ++ P_DOMAIN_SUBBAND_INFO prSubBand; ++ UINT_8 i; ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); ++ return; ++ } ++ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ ++ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ prCmd->u2IsSetPassiveScan = 0; ++ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; ++ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; ++ prCmd->aucReserved[0] = 0; ++ prCmd->aucReserved[1] = 0; ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubBand = &prDomainInfo->rSubBand[i]; ++ ++ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; ++ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; ++ ++ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { ++ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; ++ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; ++ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; ++ } ++ } ++ ++ /* Set domain info to chip */ ++ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ fgIsOid, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ ++ (PUINT_8)prCmd, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ cnmMemFree(prAdapter, prCmd); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) ++{ ++#define REG_DOMAIN_PASSIVE_DEF_IDX 0 ++#define REG_DOMAIN_PASSIVE_UDF_IDX 1 ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ P_CMD_SET_DOMAIN_INFO_T prCmd; ++ P_DOMAIN_SUBBAND_INFO prSubBand; ++ UINT_8 i; ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); ++ return; ++ } ++ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ ++ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ prCmd->u2IsSetPassiveScan = 1; ++ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; ++ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; ++ prCmd->aucReserved[0] = 0; ++ prCmd->aucReserved[1] = 0; ++ ++ DBGLOG(RLM, TRACE, "u2CountryCode=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCode); ++ ++ if (prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_UDF) ++ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_UDF_IDX]; ++ else ++ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_DEF_IDX]; ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubBand = &prDomainInfo->rSubBand[i]; ++ ++ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; ++ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; ++ ++ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { ++ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; ++ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; ++ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; ++ } ++ } ++ ++ /* Set passive scan channel info to chip */ ++ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ fgIsOid, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmd, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ cnmMemFree(prAdapter, prCmd); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] ++* ++* \return TRUE Legal channel ++* FALSE Illegal channel for current regulatory domain ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel) ++{ ++ UINT_8 i, j; ++ P_DOMAIN_SUBBAND_INFO prSubband; ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubband = &prDomainInfo->rSubBand[i]; ++ ++ if (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand) ++ continue; ++ ++ if (prSubband->ucBand == eBand) { ++ for (j = 0; j < prSubband->ucNumChannels; j++) { ++ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) ++ == ucChannel) { ++ return TRUE; ++ } ++ } ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf) ++{ ++ /* ++ The Country element should only be included for Status Code 0 (Successful). ++ */ ++ UINT_32 u4IeLen; ++ UINT_8 aucClass[12] = { 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, ++ 0x1c, 0x1e, 0x20, 0x21 ++ }; ++ ++ /* ++ The Supported Operating Classes element is used by a STA to advertise the ++ operating classes that it is capable of operating with in this country. ++ ++ The Country element (see 8.4.2.10) allows a STA to configure its PHY and MAC ++ for operation when the operating triplet of Operating Extension Identifier, ++ Operating Class, and Coverage Class fields is present. ++ */ ++ SUP_OPERATING_CLASS_IE(pBuf)->ucId = ELEM_ID_SUP_OPERATING_CLASS; ++ SUP_OPERATING_CLASS_IE(pBuf)->ucLength = 1 + sizeof(aucClass); ++ SUP_OPERATING_CLASS_IE(pBuf)->ucCur = 0x0c; /* 0x51 */ ++ kalMemCopy(SUP_OPERATING_CLASS_IE(pBuf)->ucSup, aucClass, sizeof(aucClass)); ++ u4IeLen = (SUP_OPERATING_CLASS_IE(pBuf)->ucLength + 2); ++ pBuf += u4IeLen; ++ ++ COUNTRY_IE(pBuf)->ucId = ELEM_ID_COUNTRY_INFO; ++ COUNTRY_IE(pBuf)->ucLength = 6; ++ COUNTRY_IE(pBuf)->aucCountryStr[0] = 0x55; ++ COUNTRY_IE(pBuf)->aucCountryStr[1] = 0x53; ++ COUNTRY_IE(pBuf)->aucCountryStr[2] = 0x20; ++ COUNTRY_IE(pBuf)->arCountryStr[0].ucFirstChnlNum = 1; ++ COUNTRY_IE(pBuf)->arCountryStr[0].ucNumOfChnl = 11; ++ COUNTRY_IE(pBuf)->arCountryStr[0].cMaxTxPwrLv = 0x1e; ++ u4IeLen += (COUNTRY_IE(pBuf)->ucLength + 2); ++ ++ return u4IeLen; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (fgValid) : 0 -> inValid, 1 -> Valid ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh) ++{ ++ BOOLEAN fgValid = FALSE; ++ UINT_8 ucTemp = 0; ++ UINT_8 i; ++ /*Check Power limit table channel efficient or not */ ++ ++ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { ++ if ((ucCentralCh >= g_rRlmSubBand[i].ucStartCh) && (ucCentralCh <= g_rRlmSubBand[i].ucEndCh)) ++ ucTemp = (ucCentralCh - g_rRlmSubBand[i].ucStartCh) % g_rRlmSubBand[i].ucInterval; ++ } ++ ++#if 0 ++ /*2.4G, ex 1, 2, 3 */ ++ if (ucCentralCh >= BAND_2G4_LOWER_BOUND && ucCentralCh <= BAND_2G4_UPPER_BOUND) ++ ucTemp = 0; ++ /*FCC- Spec : Band UNII-1, ex 36, 38, 40.... */ ++ else if (ucCentralCh >= UNII1_LOWER_BOUND && ucCentralCh <= UNII1_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII1_LOWER_BOUND) % 2; ++ /*FCC- Spec : Band UNII-2A, ex 52, 54, 56.... */ ++ else if (ucCentralCh >= UNII2A_LOWER_BOUND && ucCentralCh <= UNII2A_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII2A_LOWER_BOUND) % 2; ++ /*FCC- Spec : Band UNII-2C, ex 100, 102, 104.... */ ++ else if (ucCentralCh >= UNII2C_LOWER_BOUND && ucCentralCh <= UNII2C_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII2C_LOWER_BOUND) % 2; ++ /*FCC- Spec : Band UNII-3, ex 149, 151, 153... */ ++ else if (ucCentralCh >= UNII3_LOWER_BOUND && ucCentralCh <= UNII3_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII3_LOWER_BOUND) % 2; ++#endif ++ if (ucTemp == 0) ++ fgValid = TRUE; ++ return fgValid; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 ucCenterChannel; ++ ++ if (eExtend == CHNL_EXT_SCA) ++ ucCenterChannel = ucPriChannel + 2; ++ else if (eExtend == CHNL_EXT_SCB) ++ ucCenterChannel = ucPriChannel - 2; ++ else ++ ucCenterChannel = ucPriChannel; ++ ++ return ucCenterChannel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ++ ENUM_BAND_T eBand, ++ UINT_8 ucPriChannel, ++ ENUM_CHNL_EXT_T eExtend, ++ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2) ++{ ++ UINT_8 ucCenterChannel; ++ BOOLEAN fgValidChannel = TRUE; ++ BOOLEAN fgValidBW = TRUE; ++ BOOLEAN fgValidRfSetting = TRUE; ++ UINT_32 u4PrimaryOffset; ++ ++ /*DBG msg for Channel InValid */ ++ if (eChannelWidth == CW_20_40MHZ) { ++ ucCenterChannel = rlmDomainGetCenterChannel(eBand, ucPriChannel, eExtend); ++ ++ /* Check Central Channel Valid or Not */ ++ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); ++ if (fgValidChannel == FALSE) ++ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); ++ } else if (eChannelWidth == CW_80MHZ) { ++ ucCenterChannel = ucChannelS1; ++ ++ /* Check Central Channel Valid or Not */ ++ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); ++ if (fgValidChannel == FALSE) ++ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); ++ } else if (eChannelWidth == CW_160MHZ) { ++ ucCenterChannel = ucChannelS2; ++ ++ /* Check Central Channel Valid or Not */ ++ /*TODo */ ++ } ++ ++ /* Check BW Setting Correct or Not */ ++ if (eBand == BAND_2G4) { ++ if (eChannelWidth != CW_20_40MHZ) { ++ fgValidBW = FALSE; ++ DBGLOG(RLM, WARN, "Rf: B=%d, W=%d\n", eBand, eChannelWidth); ++ } ++ } else { ++ if (eChannelWidth == CW_80MHZ) { ++ u4PrimaryOffset = CAL_CH_OFFSET_80M(ucPriChannel, ucCenterChannel); ++ if (u4PrimaryOffset > 4) { ++ fgValidBW = FALSE; ++ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); ++ } ++ } else if (eChannelWidth == CW_160MHZ) { ++ u4PrimaryOffset = CAL_CH_OFFSET_160M(ucPriChannel, ucCenterChannel); ++ if (u4PrimaryOffset > 8) { ++ fgValidBW = FALSE; ++ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); ++ } ++ } ++ } ++ ++ if ((fgValidBW == FALSE) || (fgValidChannel == FALSE)) ++ fgValidRfSetting = FALSE; ++ ++ return fgValidRfSetting; ++ ++} ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (fgValid) : 0 -> inValid, 1 -> Valid ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, ++ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, ++ UINT_8 ucPwrLimitNum) ++{ ++ UINT_8 i; ++ BOOLEAN fgValid = TRUE; ++ PINT_8 prPwrLimit; ++ ++ prPwrLimit = &rPowerLimitTableConfiguration.aucPwrLimit[0]; ++ ++ for (i = 0; i < ucPwrLimitNum; i++, prPwrLimit++) { ++ if (*prPwrLimit > MAX_TX_POWER || *prPwrLimit < MIN_TX_POWER) { ++ fgValid = FALSE; ++ break; /*Find out Wrong Power limit */ ++ } ++ } ++ return fgValid; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter) ++{ ++ UINT_8 i, j; ++ UINT_16 u2CountryCodeTable, u2CountryCodeCheck; ++ BOOLEAN fgChannelValid = FALSE; ++ BOOLEAN fgPowerLimitValid = FALSE; ++ BOOLEAN fgEntryRepetetion = FALSE; ++ BOOLEAN fgTableValid = TRUE; ++ ++ /*Configuration Table Check */ ++ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { ++ /*Table Country Code */ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ /*Repetition Entry Check */ ++ for (j = i + 1; ++ j < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); ++ j++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[j].aucCountryCode[0], &u2CountryCodeCheck); ++ if (((g_rRlmPowerLimitConfiguration[i].ucCentralCh) == ++ g_rRlmPowerLimitConfiguration[j].ucCentralCh) ++ && (u2CountryCodeTable == u2CountryCodeCheck)) { ++ fgEntryRepetetion = TRUE; ++ DBGLOG(RLM, LOUD, "Domain: Configuration Repetition CC=%c%c, Ch=%d\n", ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], ++ g_rRlmPowerLimitConfiguration[i].ucCentralCh); ++ } ++ } ++ ++ /*Channel Number Check */ ++ fgChannelValid = ++ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); ++ ++ /*Power Limit Check */ ++ fgPowerLimitValid = ++ rlmDomainCheckPowerLimitValid(prAdapter, g_rRlmPowerLimitConfiguration[i], PWR_LIMIT_NUM); ++ ++ if (fgChannelValid == FALSE || fgPowerLimitValid == FALSE) { ++ fgTableValid = FALSE; ++ DBGLOG(RLM, LOUD, "Domain: CC=%c%c, Ch=%d, Limit: %d,%d,%d,%d,%d\n", ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], ++ g_rRlmPowerLimitConfiguration[i].ucCentralCh, ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]); ++ } ++ ++ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { ++ DBGLOG(RLM, LOUD, "Domain: Full search down\n"); ++ break; /*End of country table entry */ ++ } ++ ++ } ++ ++ if (fgEntryRepetetion == FALSE) ++ DBGLOG(RLM, TRACE, "Domain: Configuration Table no Repetiton.\n"); ++ ++ /*Configuration Table no error */ ++ if (fgTableValid == TRUE) ++ prAdapter->fgIsPowerLimitTableValid = TRUE; ++ else ++ prAdapter->fgIsPowerLimitTableValid = FALSE; ++ ++ /*Default Table Check */ ++ fgEntryRepetetion = FALSE; ++ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ for (j = i + 1; j < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); j++) { ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[j].aucCountryCode[0], &u2CountryCodeCheck); ++ if (u2CountryCodeTable == u2CountryCodeCheck) { ++ fgEntryRepetetion = TRUE; ++ DBGLOG(RLM, LOUD, ++ "Domain: Default Repetition CC=%c%c\n", ++ g_rRlmPowerLimitDefault[j].aucCountryCode[0], ++ g_rRlmPowerLimitDefault[j].aucCountryCode[1]); ++ } ++ } ++ } ++ if (fgEntryRepetetion == FALSE) ++ DBGLOG(RLM, TRACE, "Domain: Default Table no Repetiton.\n"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (u2TableIndex) : if 0xFFFF -> No Table Match ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode) ++{ ++ ++ UINT_16 i; ++ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; ++ UINT_16 u2TableIndex = POWER_LIMIT_TABLE_NULL; /* No Table Match */ ++ ++ /*Default Table Index */ ++ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ if (u2CountryCodeTable == u2CountryCode) { ++ u2TableIndex = i; ++ break; /*match country code */ ++ } else if (u2CountryCodeTable == COUNTRY_CODE_NULL) { ++ u2TableIndex = i; ++ break; /*find last one country- Default */ ++ } ++ } ++ ++ DBGLOG(RLM, TRACE, "Domain: Default Table Index = %d\n", u2TableIndex); ++ ++ return u2TableIndex; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainBuildCmdByDefaultTable(P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd, UINT_16 u2DefaultTableIndex) ++{ ++ UINT_8 i, k; ++ P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT prPwrLimitSubBand; ++ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; ++ ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ prPwrLimitSubBand = &g_rRlmPowerLimitDefault[u2DefaultTableIndex]; ++ ++ /*Build power limit cmd by default table information */ ++ ++ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[i] < MAX_TX_POWER) { ++ for (k = g_rRlmSubBand[i].ucStartCh; k <= g_rRlmSubBand[i].ucEndCh; ++ k += g_rRlmSubBand[i].ucInterval) { ++ if ((prPwrLimitSubBand->ucPwrUnit & BIT(i)) == 0) { ++ prCmdPwrLimit->ucCentralCh = k; ++ prCmdPwrLimit->cPwrLimitCCK = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit20 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit40 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit80 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit160 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ ++ } else { ++ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 ++ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ ++ prCmdPwrLimit->ucCentralCh = k; ++ prCmdPwrLimit->cPwrLimitCCK = prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit20 = prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit40 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 6; ++ if (prCmdPwrLimit->cPwrLimit40 > MAX_TX_POWER) ++ prCmdPwrLimit->cPwrLimit40 = MAX_TX_POWER; ++ prCmdPwrLimit->cPwrLimit80 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 12; ++ if (prCmdPwrLimit->cPwrLimit80 > MAX_TX_POWER) ++ prCmdPwrLimit->cPwrLimit80 = MAX_TX_POWER; ++ prCmdPwrLimit->cPwrLimit160 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 18; ++ if (prCmdPwrLimit->cPwrLimit160 > MAX_TX_POWER) ++ prCmdPwrLimit->cPwrLimit160 = MAX_TX_POWER; ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ } ++ } ++ ++#if 0 ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4] < MAX_TX_POWER) { ++ for (i = BAND_2G4_LOWER_BOUND; i <= BAND_2G4_UPPER_BOUND; i++) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4], ++ PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1] < MAX_TX_POWER) { ++ if (prCmd->u2CountryCode != COUNTRY_CODE_KR) { ++ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } else { ++ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { ++ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 ++ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ ++ prCmdPwrLimit->ucCentralCh = i; ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 6; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 12; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 18; ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ } ++ ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A] < MAX_TX_POWER) { ++ for (i = UNII2A_LOWER_BOUND; i <= UNII2A_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C] < MAX_TX_POWER) { ++ for (i = UNII2C_LOWER_BOUND; i <= UNII2C_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3] < MAX_TX_POWER) { ++ for (i = UNII3_LOWER_BOUND; i <= UNII3_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainBuildCmdByConfigTable(P_ADAPTER_T prAdapter, P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd) ++{ ++ UINT_8 i, k; ++ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; ++ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; ++ BOOLEAN fgChannelValid; ++ ++ /*Build power limit cmd by configuration table information */ ++ ++ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ fgChannelValid = ++ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); ++ ++ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { ++ DBGLOG(RLM, TRACE, "Domain: full search configuration table done.\n"); ++ break; /*end of configuration table */ ++ } else if ((u2CountryCodeTable == prCmd->u2CountryCode) && (fgChannelValid == TRUE)) { ++ ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ ++ if (prCmd->ucNum != 0) { ++ for (k = 0; k < prCmd->ucNum; k++) { ++ if (prCmdPwrLimit->ucCentralCh == ++ g_rRlmPowerLimitConfiguration[i].ucCentralCh) { ++ ++ /*Cmd setting (Default table information) and ++ Configuration table has repetition channel entry, ++ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, ++ Configuration table (ex: ch1, limit = 22dBm) --> ch 1 = 22 dBm ++ Cmd final setting --> ch1 = 22dBm, ch12~14 = 20dBm ++ */ ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; ++ ++ DBGLOG(RLM, LOUD, ++ "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ ((prCmd->u2CountryCode & 0xff00) >> 8), ++ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, ++ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, ++ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, ++ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); ++ ++ break; ++ } ++ prCmdPwrLimit++; ++ } ++ if (k == prCmd->ucNum) { ++ ++ /*Full search cmd (Default table setting) no match channey, ++ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, ++ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm ++ Cmd final setting --> ch1~14 = 20dBm, ch36= 22dBm ++ */ ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; ++ prCmd->ucNum++; ++ ++ DBGLOG(RLM, LOUD, ++ "Domain: Full CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ ((prCmd->u2CountryCode & 0xff00) >> 8), (prCmd->u2CountryCode & 0x00ff), ++ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, ++ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, ++ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, ++ prCmdPwrLimit->ucFlag); ++ ++ } ++ } else { ++ ++ /*Default table power limit value are 63--> cmd table no channel entry ++ ex : Default table (ex: 2.4G, limit = 63Bm) --> no channel entry in cmd, ++ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm ++ Cmd final setting --> ch36= 22dBm ++ */ ++ prCmdPwrLimit->ucCentralCh = g_rRlmPowerLimitConfiguration[i].ucCentralCh; ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; ++ prCmd->ucNum++; ++ ++ DBGLOG(RLM, LOUD, "Domain: Default table power limit value are 63.\n"); ++ DBGLOG(RLM, LOUD, "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ ((prCmd->u2CountryCode & 0xff00) >> 8), ++ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, ++ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, ++ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, ++ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); ++ ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter) ++{ ++ P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd; ++ UINT_8 i; ++ UINT_16 u2DefaultTableIndex; ++ UINT_32 u4SetCmdTableMaxSize; ++ UINT_32 u4SetQueryInfoLen; ++ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; /* for print usage */ ++ ++ u4SetCmdTableMaxSize = ++ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + ++ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); ++ ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); ++ return; ++ } ++ kalMemZero(prCmd, u4SetCmdTableMaxSize); ++ ++ u2DefaultTableIndex = ++ rlmDomainPwrLimitDefaultTableDecision(prAdapter, prAdapter->rWifiVar.rConnSettings.u2CountryCode); ++ ++ if (u2DefaultTableIndex != POWER_LIMIT_TABLE_NULL) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[u2DefaultTableIndex].aucCountryCode[0], ++ &prCmd->u2CountryCode); ++ ++ prCmd->ucNum = 0; ++ ++ if (prCmd->u2CountryCode != COUNTRY_CODE_NULL) { ++ /*Command - default table information */ ++ rlmDomainBuildCmdByDefaultTable(prCmd, u2DefaultTableIndex); ++ ++ /*Command - configuration table information */ ++ rlmDomainBuildCmdByConfigTable(prAdapter, prCmd); ++ } ++ } ++#if 0 ++ u4SetCmdTableMaxSize = ++ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + ++ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); ++ ASSERT(prCmd); ++ ++ /* To do: exception handle */ ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); ++ return; ++ } ++ kalMemZero(prCmd, u4SetCmdTableMaxSize); /* TODO memzero */ ++ ++ if (u2TableIndex != POWER_LIMIT_TABLE_NULL && u2TableIndex < MAX_DEFAULT_TABLE_COUNTRY_NUM) { ++ ++ prCmd->u2CountryCode = (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[0]) << 8) | ++ (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[1]) & BITS(0, 7)); ++ prChPwrLimit = &g_rRlmCountryPowerLimitTable[u2TableIndex].rChannelPowerLimit[0]; ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ prCmd->ucNum = 0; ++ for (i = 0; i < MAX_CMD_SUPPORT_CHANNEL_NUM; i++) { ++ ++ if (prChPwrLimit->ucCentralCh != ENDCH) { ++ ++ /*Check Power limit table channel efficient or not */ ++ fgChannelValid = rlmDomainCheckChannelEntryValid(prAdapter, prChPwrLimit->ucCentralCh); ++ ++ /*Cmd set up */ ++ if (fgChannelValid) { ++ kalMemCopy(prCmdPwrLimit, prChPwrLimit, sizeof(CMD_CHANNEL_POWER_LIMIT)); ++ DBGLOG(RLM, INFO, ++ "Domain: ValidCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, ++ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, ++ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, ++ prCmdPwrLimit->ucFlag); ++ prCmd->ucNum++; ++ prCmdPwrLimit++; ++ } else { ++ DBGLOG(RLM, INFO, ++ "Domain: Non-Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ prChPwrLimit->ucCentralCh, prChPwrLimit->cPwrLimitCCK, ++ prChPwrLimit->cPwrLimit20, prChPwrLimit->cPwrLimit40, ++ prChPwrLimit->cPwrLimit80, prChPwrLimit->cPwrLimit160, ++ prChPwrLimit->ucFlag); ++ } ++ prChPwrLimit++; ++ } else { ++ /*End of the chanel entry */ ++ break; ++ } ++ }; ++ } ++#endif ++ ++ if (prCmd->u2CountryCode != 0) { ++ DBGLOG(RLM, INFO, ++ "Domain: ValidCC =%c%c, ChNum=%d\n", ((prCmd->u2CountryCode & 0xff00) >> 8), ++ (prCmd->u2CountryCode & 0x00ff), prCmd->ucNum); ++ } else { ++ DBGLOG(RLM, INFO, "Domain: ValidCC =0x%04x, ucNum=%d\n", prCmd->u2CountryCode, prCmd->ucNum); ++ } ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ ++ for (i = 0; i < prCmd->ucNum; i++) { ++ DBGLOG(RLM, TRACE, "Domain: Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", prCmdPwrLimit->ucCentralCh, ++ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, ++ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); ++ prCmdPwrLimit++; ++ } ++ ++ u4SetQueryInfoLen = ++ (sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + (prCmd->ucNum) * sizeof(CMD_CHANNEL_POWER_LIMIT)); ++ ++ /* Update domain info to chip */ ++ if (prCmd->ucNum <= MAX_CMD_SUPPORT_CHANNEL_NUM) { ++ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ u4SetQueryInfoLen, /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmd, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ } else ++ DBGLOG(RLM, ERROR, "Domain: illegal power limit table"); ++ ++ cnmMemFree(prAdapter, prCmd); ++ ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c +new file mode 100644 +index 000000000000..8450124a3f38 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c +@@ -0,0 +1,436 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2 ++*/ ++ ++/*! \file "rlm_obss.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm_obss.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Avoid possible OBSS scan when BSS is switched ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Regulation class is changed to 81 in 20_40_coexistence action frame ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 29 2011 cm.chang ++ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning ++ * As CR title ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame ++ * in AP mode and stop ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Refine function when rcv a 20/40M public action frame ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * Use SCO of BSS_INFO to replace user-defined setting variables ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Fix compile error while enabling WiFi Direct function. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 05 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process 20/40 coexistence public action frame in AP mode ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add more ASSERT to check exception ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add virtual test for OBSS scan ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * To support CFG_SUPPORT_BCM_STP ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssInit(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 ucNetIdx; ++ ++ RLM_NET_FOR_EACH(ucNetIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; ++ ASSERT(prBssInfo); ++ ++ cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, rlmObssScanTimeout, (ULONG) prBssInfo); ++ } /* end of RLM_NET_FOR_EACH */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmObssUpdateChnlLists(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_20_40_COEXIST_FRAME prTxFrame; ++ UINT_16 i, u2PayloadLen; ++ ++ ASSERT(prMsgHdr); ++ ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; ++ ASSERT(prBssInfo); ++ ++ DBGLOG(RLM, INFO, "OBSS Scan Done (NetIdx=%d, Mode=%d)\n", ++ prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* AP mode */ ++ if ((prAdapter->fgIsP2PRegistered) && ++ (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { ++ return; ++ } ++#endif ++ ++ /* STA mode */ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || ++ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { ++ DBGLOG(RLM, WARN, "OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); ++ return; ++ } ++ ++ /* To do: check 2.4G channel list to decide if obss mgmt should be ++ * sent to associated AP. Note: how to handle concurrent network? ++ * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence ++ * management frame is needed. ++ */ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && prMsduInfo != NULL) { ++ DBGLOG(RLM, INFO, "Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", ++ prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0]); ++ ++ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; ++ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; ++ ++ /* To do: find correct algorithm */ ++ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; ++ prTxFrame->rBssCoexist.ucLength = 1; ++ prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; ++ ++ u2PayloadLen = 2 + 3; ++ ++ if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ ++ prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; ++ prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; ++ prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ ++ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) ++ prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i + 1]; ++ ++ u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); ++ } ++ ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); ++ ++ /* Clear up channel lists in 2.4G band */ ++ prBssInfo->auc2G_20mReqChnlList[0] = 0; ++ prBssInfo->auc2G_NonHtChnlList[0] = 0; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ } ++ /* end of prMsduInfo != NULL */ ++ if (prBssInfo->u2ObssScanInterval > 0) { ++ DBGLOG(RLM, INFO, "Set OBSS timer (NetIdx=%d, %d sec)\n", ++ prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval); ++ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = (P_BSS_INFO_T) ulData; ++ ASSERT(prBssInfo); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex))) { ++ ++ /* AP mode */ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ ++ prBssInfo->fgObssActionForcedTo20M = FALSE; ++ ++ /* Check if Beacon content need to be updated */ ++ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); ++ ++ return; ++ } ++#if CFG_SUPPORT_WFD ++ /* WFD streaming */ ++ else { ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = ++ &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ P_BSS_INFO_T prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ /* If WFD is enabled & connected */ ++ if (prWfdCfgSettings->ucWfdEnable && ++ (prWfdCfgSettings->u4WfdFlag & BIT(0)) && RLM_NET_PARAM_VALID(prP2pBssInfo)) { ++ ++ /* Skip OBSS scan */ ++ prBssInfo->u2ObssScanInterval = 0; ++ ++ DBGLOG(RLM, INFO, "WFD is running. Stop net[%u] OBSS scan.\n", ++ (UINT_32) prBssInfo->ucNetTypeIndex); ++ ++ return; ++ } ++ } ++#endif ++ } ++#endif /* end of CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* STA mode */ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || ++ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { ++ DBGLOG(RLM, WARN, "OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); ++ return; ++ } ++ ++ rlmObssTriggerScan(prAdapter, prBssInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ P_MSG_SCN_SCAN_REQ prScanReqMsg; ++ ++ ASSERT(prBssInfo); ++ ++ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) ++ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); ++ ASSERT(prScanReqMsg); ++ ++ if (!prScanReqMsg) { ++ DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); ++ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); ++ return; ++ } ++ ++ /* It is ok that ucSeqNum is set to fixed value because the same network ++ * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) ++ * and scan module don't care seqNum of OBSS scanning ++ */ ++ prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ; ++ prScanReqMsg->ucSeqNum = 0x33; ++ prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; ++ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; ++ prScanReqMsg->ucSSIDLength = 0; ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ prScanReqMsg->u2IELen = 0; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); ++ ++ DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c +new file mode 100644 +index 000000000000..d3c513397095 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c +@@ -0,0 +1,105 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_protection.c#1 ++*/ ++ ++/*! \file "rlm_protection.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm_protection.c ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Set RTS threshold of 2K bytes initially ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 03 31 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable RTS threshold temporarily for AMPDU ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * To support CFG_SUPPORT_BCM_STP ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c +new file mode 100644 +index 000000000000..3f088c283993 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c +@@ -0,0 +1,539 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "roaming_fsm.c" ++ \brief This file defines the FSM for Roaming MODULE. ++ ++ This file defines the FSM for Roaming MODULE. ++*/ ++ ++/* ++** Log: roaming_fsm.c ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 08 31 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * remove obsolete code. ++ * ++ * 08 15 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * add swcr in driver reg, 0x9fxx0000, to disable roaming . ++ * ++ * 03 16 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * remove obsolete definition and unused variables. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_ROAMING ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugRoamingState[ROAMING_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("ROAMING_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("ROAMING_STATE_DECISION"), ++ (PUINT_8) DISP_STRING("ROAMING_STATE_DISCOVERY"), ++ (PUINT_8) DISP_STRING("ROAMING_STATE_ROAM") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* ++#define ROAMING_ENABLE_CHECK(_roam) \ ++{ \ ++ if (!(_roam->fgIsEnableRoaming)) \ ++ return; \ ++} ++*/ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmInit(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmInit(): Current Time = %u\n", kalGetTimeTick()); ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> Initiate FSM */ ++ prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming; ++ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; ++ prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0; ++ ++} /* end of roamingFsmInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmUninit(): Current Time = %u\n", kalGetTimeTick()); ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; ++ ++} /* end of roamingFsmUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send commands to firmware ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* [IN P_ROAMING_PARAM_T] prParam ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ WLAN_STATUS rStatus; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmSendCmd(): Current Time = %u\n", kalGetTimeTick()); ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_ROAMING_TRANSIT, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(ROAMING_PARAM_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prParam, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++} /* end of roamingFsmSendCmd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update the recent time when ScanDone occurred ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmScanResultsUpdate(): Current Time = %u", kalGetTimeTick()); ++ ++ GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime); ++ ++} /* end of roamingFsmScanResultsUpdate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The Core FSM engine of ROAMING for AIS Infra. ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T ePreviousState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ do { ++ ++ /* Do entering Next State */ ++#if DBG ++ DBGLOG(ROAMING, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugRoamingState[prRoamingFsmInfo->eCurrentState], ++ apucDebugRoamingState[eNextState]); ++#else ++ DBGLOG(ROAMING, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_ROAMING_IDX, prRoamingFsmInfo->eCurrentState, eNextState); ++#endif ++ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ ++ ePreviousState = prRoamingFsmInfo->eCurrentState; ++ prRoamingFsmInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ ++ /* Do tasks of the State that we just entered */ ++ switch (prRoamingFsmInfo->eCurrentState) { ++ /* NOTE(Kevin): we don't have to rearrange the sequence of following ++ * switch case. Instead I would like to use a common lookup table of array ++ * of function pointer to speed up state search. ++ */ ++ case ROAMING_STATE_IDLE: ++ case ROAMING_STATE_DECISION: ++ break; ++ ++ case ROAMING_STATE_DISCOVERY: ++ { ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prRoamingFsmInfo->rRoamingDiscoveryUpdateTime, ++ SEC_TO_SYSTIME(ROAMING_DISCOVERY_TIMEOUT_SEC))) { ++ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Timeout"); ++ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); ++ } else { ++ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Updated"); ++#if CFG_SUPPORT_ROAMING_ENC ++ if (prAdapter->fgIsRoamingEncEnabled == TRUE) ++ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); ++ else ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ aisFsmRunEventRoamingDiscovery(prAdapter, FALSE); ++ } ++ } ++ break; ++ ++ case ROAMING_STATE_ROAM: ++ break; ++ ++ default: ++ ASSERT(0); /* Make sure we have handle all STATEs */ ++ } ++ } while (fgIsTransition); ++ ++ return; ++ ++} /* end of roamingFsmSteps() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Decision state after join completion ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ P_BSS_INFO_T prAisBssInfo; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING START: Current Time = %u\n", kalGetTimeTick()); ++ ++ /* IDLE, ROAM -> DECISION */ ++ /* Errors as DECISION, DISCOVERY -> DECISION */ ++ if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE || ++ prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) ++ return; ++ ++ eNextState = ROAMING_STATE_DECISION; ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_START; ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventStart() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Discovery state when deciding to find a candidate ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING DISCOVERY: Current Time = %u Reason = %u\n", ++ kalGetTimeTick(), prParam->u2Reason); ++ ++ /* DECISION -> DISCOVERY */ ++ /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */ ++ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) ++ return; ++#if CFG_SUPPORT_ROAMING_ENC ++ prRoamingFsmInfo->RoamingEntryTimeoutSkipCount = 0; ++#endif ++ ++ eNextState = ROAMING_STATE_DISCOVERY; ++ /* DECISION -> DISCOVERY */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ P_BSS_INFO_T prAisBssInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ /* sync. rcpi with firmware */ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ if (prBssDesc) ++ prBssDesc->ucRCPI = (UINT_8) (prParam->u2Data & 0xff); ++ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventDiscovery() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Roam state after Scan Done ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ROAM: Current Time = %u\n", kalGetTimeTick()); ++ ++ /* IDLE, ROAM -> DECISION */ ++ /* Errors as IDLE, DECISION, ROAM -> ROAM */ ++ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY) ++ return; ++ ++ eNextState = ROAMING_STATE_ROAM; ++ /* DISCOVERY -> ROAM */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_ROAM; ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventRoam() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Decision state as being failed to find out any candidate ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING FAIL: reason %x Current Time = %u\n", u4Param, kalGetTimeTick()); ++ ++ /* IDLE, ROAM -> DECISION */ ++ /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */ ++ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) ++ return; ++ ++ eNextState = ROAMING_STATE_DECISION; ++ /* ROAM -> DECISION */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_FAIL; ++ rParam.u2Data = (UINT_16) (u4Param & 0xffff); ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventFail() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Idle state as beging aborted by other moduels, AIS ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ABORT: Current Time = %u\n", kalGetTimeTick()); ++ ++ eNextState = ROAMING_STATE_IDLE; ++ /* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_ABORT; ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventAbort() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process events from firmware ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* [IN P_ROAMING_PARAM_T] prParam ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) ++{ ++ DBGLOG(ROAMING, LOUD, "ROAMING Process Events: Current Time = %u\n", kalGetTimeTick()); ++ ++ if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) ++ roamingFsmRunEventDiscovery(prAdapter, prParam); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c +new file mode 100644 +index 000000000000..eedd8d12f2fd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c +@@ -0,0 +1,2533 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#2 ++*/ ++ ++/*! \file "rsn.c" ++ \brief This file including the 802.11i, wpa and wpa2(rsn) related function. ++ ++ This file provided the macros and functions library support the wpa/rsn ie parsing, ++ cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support. ++*/ ++ ++/* ++** Log: rsn.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 09 2012 chinglan.wang ++ * NULL ++ * Fix the condition error. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 12 24 2010 chinglan.wang ++ * NULL ++ * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value ++ * fixed the.pmkid value mismatch issue ++ * ++ * 11 03 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Refine the HT rate disallow TKIP pairwise cipher . ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 29 2010 yuche.tsai ++ * NULL ++ * Fix compile error, remove unused pointer in rsnGenerateRSNIE(). ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 08 30 2010 wh.su ++ * NULL ++ * remove non-used code. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * [WPD00003840] [MT6620 5931] Security migration ++ * migration from firmware. ++ * ++ * 05 27 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * not indicate pmkid candidate while no new one scanned. ++ * ++ * 04 29 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * adjsut the pre-authentication code. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the name ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * using the Rx0 port to indicate event ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * refine the code for generate the WPA/RSN IE for assoc req ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust code for pmkid event ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code for event (mic error and pmkid indicate) and do some function rename ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some security function ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some security feature, including pmkid ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_RSN_MIGRATION ++ ++/* extern PHY_ATTRIBUTE_T rPhyAttributes[]; */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to parse RSN IE. ++* ++* \param[in] prInfoElem Pointer to the RSN IE ++* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the ++** RSN information from the given RSN IE ++* ++* \retval TRUE - Succeeded ++* \retval FALSE - Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo) ++{ ++ UINT_32 i; ++ INT_32 u4RemainRsnIeLen; ++ UINT_16 u2Version; ++ UINT_16 u2Cap = 0; ++ UINT_32 u4GroupSuite = RSN_CIPHER_SUITE_CCMP; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_16 u2AuthSuiteCount = 0; ++ PUINT_8 pucPairSuite = NULL; ++ PUINT_8 pucAuthSuite = NULL; ++ PUINT_8 cp; ++ ++ DEBUGFUNC("rsnParseRsnIE"); ++ ++ ASSERT(prInfoElem); ++ ASSERT(prRsnInfo); ++ ++ /* Verify the length of the RSN IE. */ ++ if (prInfoElem->ucLength < 2) { ++ DBGLOG(RSN, TRACE, "RSN IE length too short (length=%d)\n", prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ /* Check RSN version: currently, we only support version 1. */ ++ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); ++ if (u2Version != 1) { ++ DBGLOG(RSN, TRACE, "Unsupported RSN IE version: %d\n", u2Version); ++ return FALSE; ++ } ++ ++ cp = (PUCHAR) & prInfoElem->u4GroupKeyCipherSuite; ++ u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2; ++ ++ do { ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the Group Key Cipher Suite field. */ ++ if (u4RemainRsnIeLen < 4) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in group cipher suite (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ cp += 4; ++ u4RemainRsnIeLen -= 4; ++ ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the Pairwise Key Cipher Suite Count field. */ ++ if (u4RemainRsnIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ cp += 2; ++ u4RemainRsnIeLen -= 2; ++ ++ /* Parse the Pairwise Key Cipher Suite List field. */ ++ i = (UINT_32) u2PairSuiteCount * 4; ++ if (u4RemainRsnIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucPairSuite = cp; ++ ++ cp += i; ++ u4RemainRsnIeLen -= (INT_32) i; ++ ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the Authentication and Key Management Cipher Suite Count field. */ ++ if (u4RemainRsnIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ cp += 2; ++ u4RemainRsnIeLen -= 2; ++ ++ /* Parse the Authentication and Key Management Cipher Suite List ++ field. */ ++ i = (UINT_32) u2AuthSuiteCount * 4; ++ if (u4RemainRsnIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucAuthSuite = cp; ++ ++ cp += i; ++ u4RemainRsnIeLen -= (INT_32) i; ++ ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the RSN u2Capabilities field. */ ++ if (u4RemainRsnIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2Cap); ++ } while (FALSE); ++ ++ /* Save the RSN information for the BSS. */ ++ prRsnInfo->ucElemId = ELEM_ID_RSN; ++ ++ prRsnInfo->u2Version = u2Version; ++ ++ prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite; ++ ++ DBGLOG(RSN, LOUD, "RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", ++ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (pucPairSuite) { ++ /* The information about the pairwise key cipher suites is present. */ ++ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) ++ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; ++ ++ prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucPairSuite, &prRsnInfo->au4PairwiseKeyCipherSuite[i]); ++ pucPairSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the pairwise key cipher suites is not present. ++ Use the default chipher suite for RSN: CCMP. */ ++ prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1; ++ prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP; ++ ++ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (pucAuthSuite) { ++ /* The information about the authentication and key management suites ++ is present. */ ++ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) ++ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; ++ ++ prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]); ++ pucAuthSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the authentication and key management suites ++ is not present. Use the default AKM suite for RSN. */ ++ prRsnInfo->u4AuthKeyMgtSuiteCount = 1; ++ prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X; ++ ++ DBGLOG(RSN, LOUD, "RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ prRsnInfo->u2RsnCap = u2Cap; ++#if CFG_SUPPORT_802_11W ++ prRsnInfo->fgRsnCapPresent = TRUE; ++#endif ++ DBGLOG(RSN, LOUD, "RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap); ++ ++ return TRUE; ++} /* rsnParseRsnIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to parse WPA IE. ++* ++* \param[in] prInfoElem Pointer to the WPA IE. ++* \param[out] prWpaInfo Pointer to the BSSDescription structure to store the ++* WPA information from the given WPA IE. ++* ++* \retval TRUE Succeeded. ++* \retval FALSE Failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo) ++{ ++ UINT_32 i; ++ INT_32 u4RemainWpaIeLen; ++ UINT_16 u2Version; ++ UINT_16 u2Cap = 0; ++ UINT_32 u4GroupSuite = WPA_CIPHER_SUITE_TKIP; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_16 u2AuthSuiteCount = 0; ++ PUCHAR pucPairSuite = NULL; ++ PUCHAR pucAuthSuite = NULL; ++ PUCHAR cp; ++ BOOLEAN fgCapPresent = FALSE; ++ ++ DEBUGFUNC("rsnParseWpaIE"); ++ ++ ASSERT(prInfoElem); ++ ASSERT(prWpaInfo); ++ ++ /* Verify the length of the WPA IE. */ ++ if (prInfoElem->ucLength < 6) { ++ DBGLOG(RSN, TRACE, "WPA IE length too short (length=%d)\n", prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ /* Check WPA version: currently, we only support version 1. */ ++ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); ++ if (u2Version != 1) { ++ DBGLOG(RSN, TRACE, "Unsupported WPA IE version: %d\n", u2Version); ++ return FALSE; ++ } ++ ++ cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite; ++ u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6; ++ ++ do { ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* WPA_OUI : 4 ++ Version : 2 ++ GroupSuite : 4 ++ PairwiseCount: 2 ++ PairwiseSuite: 4 * pairSuiteCount ++ AuthCount : 2 ++ AuthSuite : 4 * authSuiteCount ++ Cap : 2 */ ++ ++ /* Parse the Group Key Cipher Suite field. */ ++ if (u4RemainWpaIeLen < 4) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in group cipher suite (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ cp += 4; ++ u4RemainWpaIeLen -= 4; ++ ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* Parse the Pairwise Key Cipher Suite Count field. */ ++ if (u4RemainWpaIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ cp += 2; ++ u4RemainWpaIeLen -= 2; ++ ++ /* Parse the Pairwise Key Cipher Suite List field. */ ++ i = (UINT_32) u2PairSuiteCount * 4; ++ if (u4RemainWpaIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucPairSuite = cp; ++ ++ cp += i; ++ u4RemainWpaIeLen -= (INT_32) i; ++ ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* Parse the Authentication and Key Management Cipher Suite Count ++ field. */ ++ if (u4RemainWpaIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ cp += 2; ++ u4RemainWpaIeLen -= 2; ++ ++ /* Parse the Authentication and Key Management Cipher Suite List ++ field. */ ++ i = (UINT_32) u2AuthSuiteCount * 4; ++ if (u4RemainWpaIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucAuthSuite = cp; ++ ++ cp += i; ++ u4RemainWpaIeLen -= (INT_32) i; ++ ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* Parse the WPA u2Capabilities field. */ ++ if (u4RemainWpaIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in WPA capabilities (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ fgCapPresent = TRUE; ++ WLAN_GET_FIELD_16(cp, &u2Cap); ++ u4RemainWpaIeLen -= 2; ++ } while (FALSE); ++ ++ /* Save the WPA information for the BSS. */ ++ ++ prWpaInfo->ucElemId = ELEM_ID_WPA; ++ ++ prWpaInfo->u2Version = u2Version; ++ ++ prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite; ++ ++ DBGLOG(RSN, LOUD, "WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", ++ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (pucPairSuite) { ++ /* The information about the pairwise key cipher suites is present. */ ++ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) ++ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; ++ ++ prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucPairSuite, &prWpaInfo->au4PairwiseKeyCipherSuite[i]); ++ pucPairSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the pairwise key cipher suites is not present. ++ Use the default chipher suite for WPA: TKIP. */ ++ prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1; ++ prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP; ++ ++ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (pucAuthSuite) { ++ /* The information about the authentication and key management suites ++ is present. */ ++ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) ++ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; ++ ++ prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]); ++ pucAuthSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the authentication and key management suites ++ is not present. Use the default AKM suite for WPA. */ ++ prWpaInfo->u4AuthKeyMgtSuiteCount = 1; ++ prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X; ++ ++ DBGLOG(RSN, LOUD, "WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (fgCapPresent) { ++ prWpaInfo->fgRsnCapPresent = TRUE; ++ prWpaInfo->u2RsnCap = u2Cap; ++ DBGLOG(RSN, LOUD, "WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap); ++ } else { ++ prWpaInfo->fgRsnCapPresent = FALSE; ++ prWpaInfo->u2RsnCap = 0; ++ } ++ ++ return TRUE; ++} /* rsnParseWpaIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to search the desired pairwise ++* cipher suite from the MIB Pairwise Cipher Suite ++* configuration table. ++* ++* \param[in] u4Cipher The desired pairwise cipher suite to be searched ++* \param[out] pu4Index Pointer to the index of the desired pairwise cipher in ++* the table ++* ++* \retval TRUE - The desired pairwise cipher suite is found in the table. ++* \retval FALSE - The desired pairwise cipher suite is not found in the ++* table. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index) ++{ ++ UINT_8 i; ++ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; ++ ++ DEBUGFUNC("rsnSearchSupportedCipher"); ++ ++ ASSERT(pu4Index); ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { ++ prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i]; ++ if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher && ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled) { ++ *pu4Index = i; ++ return TRUE; ++ } ++ } ++ return FALSE; ++} /* rsnSearchSupportedCipher */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Whether BSS RSN is matched from upper layer set. ++* ++* \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information ++* ++* \retval BOOLEAN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo) ++{ ++ UINT_8 i = 0; ++ ++ DEBUGFUNC("rsnIsSuitableBSS"); ++ ++ do { ++ ++ if ((prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite & 0x000000FF) != ++ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)) { ++ DBGLOG(RSN, TRACE, "Break by GroupKeyCipherSuite\n"); ++ break; ++ } ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] & 0x000000FF) != ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])) ++ && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1)) { ++ DBGLOG(RSN, TRACE, "Break by PairwiseKeyCipherSuite\n"); ++ break; ++ } ++ } ++ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { ++ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] & 0x000000FF) != ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0])) ++ && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)) { ++ DBGLOG(RSN, TRACE, "Break by AuthKeyMgtSuite\n"); ++ break; ++ } ++ } ++ return TRUE; ++ } while (FALSE); ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to search the desired ++* authentication and key management (AKM) suite from the ++* MIB Authentication and Key Management Suites table. ++* ++* \param[in] u4AkmSuite The desired AKM suite to be searched ++* \param[out] pu4Index Pointer to the index of the desired AKM suite in the ++* table ++* ++* \retval TRUE The desired AKM suite is found in the table. ++* \retval FALSE The desired AKM suite is not found in the table. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index) ++{ ++ UINT_8 i; ++ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; ++ ++ DEBUGFUNC("rsnSearchAKMSuite"); ++ ++ ASSERT(pu4Index); ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { ++ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; ++ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite && ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) { ++ *pu4Index = i; ++ return TRUE; ++ } ++ } ++ return FALSE; ++} /* rsnSearchAKMSuite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to perform RSNA or TSN policy ++* selection for a given BSS. ++* ++* \param[in] prBss Pointer to the BSS description ++* ++* \retval TRUE - The RSNA/TSN policy selection for the given BSS is ++* successful. The selected pairwise and group cipher suites ++* are returned in the BSS description. ++* \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed. ++* The driver shall not attempt to join the given BSS. ++* ++* \note The Encrypt status matched score will save to bss for final ap select. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) ++{ ++#if CFG_SUPPORT_802_11W ++ INT_32 i; ++ UINT_32 j; ++#else ++ UINT_32 i, j; ++#endif ++ BOOLEAN fgSuiteSupported; ++ UINT_32 u4PairwiseCipher = 0; ++ UINT_32 u4GroupCipher = 0; ++ UINT_32 u4AkmSuite = 0; ++ P_RSN_INFO_T prBssRsnInfo; ++ ENUM_NETWORK_TYPE_INDEX_T eNetwotkType; ++ BOOLEAN fgIsWpsActive = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("rsnPerformPolicySelection"); ++ ++ ASSERT(prBss); ++ ++ DBGLOG(RSN, TRACE, "rsnPerformPolicySelection\n"); ++ /* Todo:: */ ++ eNetwotkType = NETWORK_TYPE_AIS_INDEX; ++ ++ prBss->u4RsnSelectedPairwiseCipher = 0; ++ prBss->u4RsnSelectedGroupCipher = 0; ++ prBss->u4RsnSelectedAKMSuite = 0; ++ prBss->ucEncLevel = 0; ++ ++#if CFG_SUPPORT_WPS ++ fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo); ++ ++ /* CR1640, disable the AP select privacy check */ ++ if (fgIsWpsActive && ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) && ++ (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) { ++ DBGLOG(RSN, TRACE, "-- Skip the Protected BSS check\n"); ++ return TRUE; ++ } ++#endif ++ ++ /* Protection is not required in this BSS. */ ++ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) { ++ ++ if (secEnabledInAis(prAdapter) == FALSE) { ++ DBGLOG(RSN, TRACE, "-- No Protected BSS\n"); ++ return TRUE; ++ } ++ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); ++ return FALSE; ++ ++ } ++ ++ /* Protection is required in this BSS. */ ++ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) { ++ if (secEnabledInAis(prAdapter) == FALSE) { ++ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); ++ return FALSE; ++ } ++ } ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA || ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK || ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { ++ ++ if (prBss->fgIEWPA) { ++ prBssRsnInfo = &prBss->rWPAInfo; ++ } else { ++ DBGLOG(RSN, TRACE, "WPA Information Element does not exist.\n"); ++ return FALSE; ++ } ++ } else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 || ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) { ++ ++ if (prBss->fgIERSN) { ++ prBssRsnInfo = &prBss->rRSNInfo; ++ } else { ++ DBGLOG(RSN, TRACE, "RSN Information Element does not exist.\n"); ++ return FALSE; ++ } ++ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) { ++ /* If the driver is configured to use WEP only, ignore this BSS. */ ++ DBGLOG(RSN, TRACE, "-- Not WEP-only legacy BSS %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ return FALSE; ++ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) { ++ /* If the driver is configured to use WEP only, use this BSS. */ ++ DBGLOG(RSN, TRACE, "-- WEP-only legacy BSS, fgIERSN %d, fgIEWPA %d\n", ++ prBss->fgIERSN, prBss->fgIEWPA); ++ /* if this BSS was configured to WPA/WPA2, don't select this AP */ ++ return (prBss->fgIERSN || prBss->fgIEWPA) ? FALSE : TRUE; ++ } ++ ++ if (!rsnIsSuitableBSS(prAdapter, prBssRsnInfo)) { ++ DBGLOG(RSN, TRACE, "RSN info check no matched\n"); ++ return FALSE; ++ } ++ ++ if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 && ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == CIPHER_SUITE_NONE) { ++ /* Since the pairwise cipher use the same cipher suite as the group ++ cipher in the BSS, we check the group cipher suite against the ++ current encryption status. */ ++ fgSuiteSupported = FALSE; ++ ++ switch (prBssRsnInfo->u4GroupKeyCipherSuite) { ++ case WPA_CIPHER_SUITE_CCMP: ++ case RSN_CIPHER_SUITE_CCMP: ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) ++ fgSuiteSupported = TRUE; ++ break; ++ ++ case WPA_CIPHER_SUITE_TKIP: ++ case RSN_CIPHER_SUITE_TKIP: ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) ++ fgSuiteSupported = TRUE; ++ break; ++ ++ case WPA_CIPHER_SUITE_WEP40: ++ case WPA_CIPHER_SUITE_WEP104: ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) ++ fgSuiteSupported = TRUE; ++ break; ++ } ++ ++ if (fgSuiteSupported) { ++ u4PairwiseCipher = WPA_CIPHER_SUITE_NONE; ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ } ++#if DBG ++ else { ++ DBGLOG(RSN, TRACE, "Inproper encryption status %d for group-key-only BSS\n", ++ prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ } ++#endif ++ } else { ++ fgSuiteSupported = FALSE; ++ ++ DBGLOG(RSN, TRACE, "eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, ++ (UINT_32) prBssRsnInfo->u4PairwiseKeyCipherSuiteCount, ++ (UINT_32) prBssRsnInfo->au4PairwiseKeyCipherSuite[0]); ++ /* Select pairwise/group ciphers */ ++ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { ++ case ENUM_ENCRYPTION3_ENABLED: ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_CCMP) { ++ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ break; ++ ++ case ENUM_ENCRYPTION2_ENABLED: ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_TKIP) { ++ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_CCMP) ++ DBGLOG(RSN, TRACE, "Cannot join CCMP BSS\n"); ++ else ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ break; ++ ++ case ENUM_ENCRYPTION1_ENABLED: ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_WEP40 || ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_WEP104) { ++ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == ++ CIPHER_SUITE_CCMP || ++ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) { ++ DBGLOG(RSN, TRACE, "Cannot join CCMP/TKIP BSS\n"); ++ } else { ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* Exception handler */ ++ /* If we cannot find proper pairwise and group cipher suites to join the ++ BSS, do not check the supported AKM suites. */ ++ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { ++ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) { ++ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || ++ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { ++ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher for P2P network (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) { ++ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || ++ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { ++ /* Do nothing */ ++ } ++ DBGLOG(RSN, TRACE, ++ "Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++#endif ++ ++ /* Verify if selected pairwisse cipher is supported */ ++ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i); ++ ++ /* Verify if selected group cipher is supported */ ++ if (fgSuiteSupported) ++ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i); ++ ++ if (!fgSuiteSupported) { ++ DBGLOG(RSN, TRACE, "Failed to support selected pairwise/group cipher (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++ ++ /* Select AKM */ ++ /* If the driver cannot support any authentication suites advertised in ++ the given BSS, we fail to perform RSNA policy selection. */ ++ /* Attempt to find any overlapping supported AKM suite. */ ++#if CFG_SUPPORT_802_11W ++ if (i != 0) ++ for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--) { ++#else ++ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { ++#endif ++ if (rsnSearchAKMSuite(prAdapter, prBssRsnInfo->au4AuthKeyMgtSuite[i], &j)) { ++ u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i]; ++ break; ++ } ++ } ++ ++ if (u4AkmSuite == 0) { ++ DBGLOG(RSN, TRACE, "Cannot support any AKM suites\n"); ++ return FALSE; ++ } ++ ++ DBGLOG(RSN, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4PairwiseCipher & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), ++ (UINT_8) (u4GroupCipher & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); ++ ++ DBGLOG(RSN, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4AkmSuite & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); ++ ++#if CFG_SUPPORT_802_11W ++ DBGLOG(RSN, TRACE, "MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)); ++ ++ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) { ++ if (!prBssRsnInfo->fgRsnCapPresent) { ++ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability.\n"); ++ return FALSE; ++ } else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) { ++ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required\n"); ++ return FALSE; ++ } ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ } else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) { ++ if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) || ++ (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ } else { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; ++ } ++ } else { ++ if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) { ++ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability\n"); ++ return FALSE; ++ } ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; ++ } ++ DBGLOG(RSN, TRACE, "fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection); ++#endif ++ ++ if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) { ++ prBss->ucEncLevel = 3; ++ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) { ++ prBss->ucEncLevel = 2; ++ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 || ++ GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) { ++ prBss->ucEncLevel = 1; ++ } else { ++ ASSERT(FALSE); ++ } ++ prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher; ++ prBss->u4RsnSelectedGroupCipher = u4GroupCipher; ++ prBss->u4RsnSelectedAKMSuite = u4AkmSuite; ++ ++ return TRUE; ++ ++} /* rsnPerformPolicySelection */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to generate WPA IE for beacon frame. ++* ++* \param[in] pucIeStartAddr Pointer to put the generated WPA IE. ++* ++* \return The append WPA-None IE length ++* \note ++* Called by: JOIN module, compose beacon IE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_32 i; ++ P_WPA_INFO_ELEM_T prWpaIE; ++ UINT_32 u4Suite; ++ UINT_16 u2SuiteCount; ++ PUINT_8 cp, cp2; ++ UINT_8 ucExpendedLen = 0; ++ PUINT_8 pucBuffer; ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; ++ ++ DEBUGFUNC("rsnGenerateWpaNoneIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) ++ return; ++ ++ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; ++ ++ if (eNetworkId != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ prWpaIE = (P_WPA_INFO_ELEM_T) (pucBuffer); ++ ++ /* Start to construct a WPA IE. */ ++ /* Fill the Element ID field. */ ++ prWpaIE->ucElemId = ELEM_ID_WPA; ++ ++ /* Fill the OUI and OUI Type fields. */ ++ prWpaIE->aucOui[0] = 0x00; ++ prWpaIE->aucOui[1] = 0x50; ++ prWpaIE->aucOui[2] = 0xF2; ++ prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA; ++ ++ /* Fill the Version field. */ ++ WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1); /* version 1 */ ++ ucExpendedLen = 6; ++ ++ /* Fill the Pairwise Key Cipher Suite List field. */ ++ u2SuiteCount = 0; ++ cp = (PUINT_8) &prWpaIE->aucPairwiseKeyCipherSuite1[0]; ++ ++ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) ++ u4Suite = WPA_CIPHER_SUITE_CCMP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) ++ u4Suite = WPA_CIPHER_SUITE_TKIP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) ++ u4Suite = WPA_CIPHER_SUITE_WEP104; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) ++ u4Suite = WPA_CIPHER_SUITE_WEP40; ++ else ++ u4Suite = WPA_CIPHER_SUITE_TKIP; ++ ++ WLAN_SET_FIELD_32(cp, u4Suite); ++ u2SuiteCount++; ++ ucExpendedLen += 4; ++ cp += 4; ++ ++ /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */ ++ WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite); ++ ucExpendedLen += 4; ++ ++ /* Fill the Pairwise Key Cipher Suite Count field. */ ++ WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount); ++ ucExpendedLen += 2; ++ ++ cp2 = cp; ++ ++ /* Fill the Authentication and Key Management Suite List field. */ ++ u2SuiteCount = 0; ++ cp += 2; ++ ++ if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) ++ u4Suite = WPA_AKM_SUITE_802_1X; ++ else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) ++ u4Suite = WPA_AKM_SUITE_PSK; ++ else ++ u4Suite = WPA_AKM_SUITE_NONE; ++ ++ /* This shall be the only available value for current implementation */ ++ ASSERT(u4Suite == WPA_AKM_SUITE_NONE); ++ ++ WLAN_SET_FIELD_32(cp, u4Suite); ++ u2SuiteCount++; ++ ucExpendedLen += 4; ++ cp += 4; ++ ++ /* Fill the Authentication and Key Management Suite Count field. */ ++ WLAN_SET_FIELD_16(cp2, u2SuiteCount); ++ ucExpendedLen += 2; ++ ++ /* Fill the Length field. */ ++ prWpaIE->ucLength = (UINT_8) ucExpendedLen; ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ ++} /* rsnGenerateWpaNoneIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate WPA IE for ++* associate request frame. ++* ++* \param[in] prCurrentBss The Selected BSS description ++* ++* \retval The append WPA IE length ++* ++* \note ++* Called by: AIS module, Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUCHAR cp; ++ PUINT_8 pucBuffer; ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ ++ DEBUGFUNC("rsnGenerateWPAIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ /* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */ ++ /* return; */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((1 /* prCurrentBss->fgIEWPA */ && ++ ((prAdapter->fgIsP2PRegistered) && ++ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && ++ (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || ++ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) { ++#else ++ if ((1 /* prCurrentBss->fgIEWPA */ && ++ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) { ++#endif ++ if (prP2pSpecificBssInfo->u2WpaIeLen != 0) { ++ kalMemCopy(pucBuffer, prP2pSpecificBssInfo->aucWpaIeBuffer, prP2pSpecificBssInfo->u2WpaIeLen); ++ prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen; ++ return; ++ } ++ ++ /* Construct a WPA IE for association request frame. */ ++ WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA; ++ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; ++ WPA_IE(pucBuffer)->aucOui[0] = 0x00; ++ WPA_IE(pucBuffer)->aucOui[1] = 0x50; ++ WPA_IE(pucBuffer)->aucOui[2] = 0xF2; ++ WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA; ++ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { ++ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP); ++ } else ++#endif ++ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, ++ prAdapter->rWifiVar. ++ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher); ++ ++ cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; ++ ++ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { ++ WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP); ++ } else ++#endif ++ WLAN_SET_FIELD_32(cp, ++ prAdapter->rWifiVar. ++ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher); ++ cp += 4; ++ ++ WLAN_SET_FIELD_16(cp, 1); ++ cp += 2; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { ++ WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK); ++ } else ++#endif ++ WLAN_SET_FIELD_32(cp, ++ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite); ++ cp += 4; ++ ++ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* rsnGenerateWPAIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate RSN IE for ++* associate request frame. ++* ++* \param[in] prMsduInfo The Selected BSS description ++* ++* \retval The append RSN IE length ++* ++* \note ++* Called by: AIS module, P2P module, BOW module Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_32 u4Entry; ++ PUCHAR cp; ++ /* UINT_8 ucExpendedLen = 0; */ ++ PUINT_8 pucBuffer; ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("rsnGenerateRSNIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ /* Todo:: network id */ ++ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; ++ ++ if ( ++#if CFG_ENABLE_WIFI_DIRECT ++ ((prAdapter->fgIsP2PRegistered) && ++ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) || ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ (eNetworkId == NETWORK_TYPE_BOW_INDEX) || ++#endif ++ (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ && ++ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) || ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK)))) { ++ /* Construct a RSN IE for association request frame. */ ++ RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN; ++ RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED; ++ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); /* Version */ ++ WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite, ++ prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); /* Group key suite */ ++ cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; ++ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); ++ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher); ++ cp += 4; ++ WLAN_SET_FIELD_16(cp, 1); /* AKM suite count */ ++ cp += 2; ++ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); /* AKM suite */ ++ cp += 4; ++ WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo);/* Capabilities */ ++#if CFG_SUPPORT_802_11W ++ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) { ++ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) ++ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); /* Capabilities */ ++ else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) ++ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); /* Capabilities */ ++ } ++#endif ++ cp += 2; ++ ++ if (eNetworkId == NETWORK_TYPE_AIS_INDEX) { ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ if (!prStaRec) { ++ DBGLOG(RSN, TRACE, "rsnGenerateRSNIE: prStaRec is NULL\n"); ++ return; ++ } ++ } ++ ++ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && ++ rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) { ++ /* DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); */ ++ /* DBGLOG(RSN, TRACE, ("addr %pM PMKID %pM\n", */ ++ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID),*/ ++ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID))); */ ++ if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) { ++ RSN_IE(pucBuffer)->ucLength = 38; ++ WLAN_SET_FIELD_16(cp, 1); /* PMKID count */ ++ cp += 2; ++ DBGLOG(RSN, TRACE, ++ "BSSID %pM ind=%d\n", prStaRec->aucMacAddr, (UINT_32) u4Entry); ++ DBGLOG(RSN, TRACE, "use PMKID %pM\n", ++ (prAdapter->rWifiVar.rAisSpecificBssInfo. ++ arPmkidCache[u4Entry].rBssidInfo.arPMKID)); ++ kalMemCopy(cp, ++ (PVOID) prAdapter->rWifiVar.rAisSpecificBssInfo. ++ arPmkidCache[u4Entry].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); ++ /* ucExpendedLen = 40; */ ++ } else { ++ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ ++ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ ++#if CFG_SUPPORT_802_11W ++ cp += 2; ++ RSN_IE(pucBuffer)->ucLength += 2; ++#endif ++ } ++ } else { ++ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ ++ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ ++#if CFG_SUPPORT_802_11W ++ cp += 2; ++ RSN_IE(pucBuffer)->ucLength += 2; ++#endif ++ } ++ ++#if CFG_SUPPORT_802_11W ++ if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) ++ && (kalGetMfpSetting(prAdapter->prGlueInfo) != ++ RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */) { ++ WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC); ++ cp += 4; ++ RSN_IE(pucBuffer)->ucLength += 4; ++ } ++#endif ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* rsnGenerateRSNIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Parse the given IE buffer and check if it is WFA IE and return Type and ++* SubType for further process. ++* ++* \param[in] pucBuf Pointer to the buffer of WFA Information Element. ++* \param[out] pucOuiType Pointer to the storage of OUI Type. ++* \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version. ++ ++* \retval TRUE Parse IE ok ++* \retval FALSE Parse IE fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion) ++{ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ P_IE_WFA_T prWfaIE; ++ ++ ASSERT(pucBuf); ++ ASSERT(pucOuiType); ++ ASSERT(pu2SubTypeVersion); ++ prWfaIE = (P_IE_WFA_T) pucBuf; ++ ++ do { ++ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { ++ break; ++ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || ++ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { ++ break; ++ } ++ ++ *pucOuiType = prWfaIE->ucOuiType; ++ WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion); ++ ++ return TRUE; ++ } while (FALSE); ++ ++ return FALSE; ++ ++} /* end of rsnParseCheckForWFAInfoElem() */ ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK ++* ++* \param[in] prAdapter Pointer to Adapter ++* \param[in] prSwRfb Pointer to the rx buffer ++* \param[in] pIE Pointer rthe buffer of Information Element. ++* \param[out] prStatusCode Pointer to the return status code. ++ ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode) ++{ ++ ++ RSN_INFO_T rRsnIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(prIe); ++ ASSERT(pu2StatusCode); ++ ++ *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; ++ ++ if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) { ++ if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) ++ || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) { ++ *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER; ++ return; ++ } ++ if (rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP) { ++ *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER; ++ return; ++ } ++ if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) { ++ *pu2StatusCode = STATUS_CODE_INVALID_AKMP; ++ return; ++ } ++ ++ DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n"); ++ *pu2StatusCode = WLAN_STATUS_SUCCESS; ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to generate an authentication event to NDIS. ++* ++* \param[in] u4Flags Authentication event: \n ++* PARAM_AUTH_REQUEST_REAUTH 0x01 \n ++* PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n ++* PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n ++* PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenMicErrorEvent(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgFlags) ++{ ++ P_PARAM_AUTH_EVENT_T prAuthEvent; ++ ++ DEBUGFUNC("rsnGenMicErrorEvent"); ++ ++ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; ++ ++ /* Status type: Authentication Event */ ++ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; ++ ++ /* Authentication request */ ++ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); ++ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, ++ (PVOID) prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN); ++ ++ if (fgFlags == TRUE) ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; ++ else ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAuthEvent, ++ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); ++ ++} /* rsnGenMicErrorEvent */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle TKIP MIC failures. ++* ++* \param[in] adapter_p Pointer to the adapter object data area. ++* \param[in] prSta Pointer to the STA which occur MIC Error ++* \param[in] fgErrorKeyType type of error key ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType) ++{ ++ /* UINT_32 u4RsnaCurrentMICFailTime; */ ++ /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */ ++ ++ DEBUGFUNC("rsnTkipHandleMICFailure"); ++ ++ ASSERT(prAdapter); ++#if 1 ++ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); ++ ++ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, Param_PowerModeCAM, FALSE); ++ ++ /* Generate authentication request event. */ ++ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); ++#else ++ ASSERT(prSta); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ /* Record the MIC error occur time. */ ++ GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime); ++ ++ /* Generate authentication request event. */ ++ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); ++ ++ /* If less than 60 seconds have passed since a previous TKIP MIC failure, ++ disassociate from the AP and wait for 60 seconds before (re)associating ++ with the same AP. */ ++ if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 && ++ !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime, ++ prAisSpecBssInfo->u4RsnaLastMICFailTime, SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) { ++ /* If less than 60 seconds expired since last MIC error, we have to ++ block traffic. */ ++ ++ DBGLOG(RSN, INFO, "Start blocking traffic!\n"); ++ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); ++ ++ secFsmEventStartCounterMeasure(prAdapter, prSta); ++ } else { ++ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); ++ DBGLOG(RSN, INFO, "First TKIP MIC error!\n"); ++ } ++ ++ COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime); ++#endif ++} /* rsnTkipHandleMICFailure */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to select a list of BSSID from ++* the scan results for PMKID candidate list. ++* ++* \param[in] prBssDesc the BSS Desc at scan result list ++* \param[out] pu4CandidateCount Pointer to the number of selected candidates. ++* It is set to zero if no BSSID matches our requirement. ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ DEBUGFUNC("rsnSelectPmkidCandidateList"); ++ ++ ASSERT(prBssDesc); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ /* Search a BSS with the same SSID from the given BSS description set. */ ++ /* DBGLOG(RSN, TRACE, ("Check scan result [%pM]\n", */ ++ /* prBssDesc->aucBSSID)); */ ++ ++ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { ++ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); ++ return; ++ } ++#if 0 ++ if ((prBssDesc->u2BSSBasicRateSet & ++ ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) || prBssDesc->fgIsUnknownBssBasicRate) { ++ DBGLOG(RSN, TRACE, "-- Rate set not matched\n"); ++ return; ++ } ++ ++ if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher || */ ++ prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*|| ++ prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) { ++ DBGLOG(RSN, TRACE, "-- Encrypt status not matched for PMKID\n"); ++ return; ++ } ++#endif ++ ++ rsnUpdatePmkidCandidateList(prAdapter, prBssDesc); ++ ++} /* rsnSelectPmkidCandidateList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to select a list of BSSID from ++* the scan results for PMKID candidate list. ++* ++* \param[in] prBssDesc the BSS DESC at scan result list ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ UINT_32 i; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("rsnUpdatePmkidCandidateList"); ++ ++ ASSERT(prBssDesc); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { ++ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); ++ return; ++ } ++ ++ for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) { ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)) ++ return; ++ } ++ ++ /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16), ++ then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */ ++ if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1) > CFG_MAX_PMKID_CACHE) ++ prAisSpecBssInfo->u4PmkidCandicateCount--; ++ ++ i = prAisSpecBssInfo->u4PmkidCandicateCount; ++ ++ COPY_MAC_ADDR((PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, (PVOID) prBssDesc->aucBSSID); ++ ++ if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) { ++ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1; ++ DBGLOG(RSN, TRACE, "Add %pM with pre-auth to candidate list\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); ++ } else { ++ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0; ++ DBGLOG(RSN, TRACE, "Add %pM without pre-auth to candidate list\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); ++ } ++ ++ prAisSpecBssInfo->u4PmkidCandicateCount++; ++ ++} /* rsnUpdatePmkidCandidateList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to search the desired entry in ++* PMKID cache according to the BSSID ++* ++* \param[in] pucBssid Pointer to the BSSID ++* \param[out] pu4EntryIndex Pointer to place the found entry index ++* ++* \retval TRUE, if found one entry for specified BSSID ++* \retval FALSE, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex) ++{ ++ UINT_32 i; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("rsnSearchPmkidEntry"); ++ ++ ASSERT(pucBssid); ++ ASSERT(pu4EntryIndex); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) ++ return FALSE; ++ ++ ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE); ++ ++ /* Search for desired BSSID */ ++ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { ++ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid, MAC_ADDR_LEN)) ++ break; ++ } ++ ++ /* If desired BSSID is found, then set the PMKID */ ++ if (i < prAisSpecBssInfo->u4PmkidCacheCount) { ++ *pu4EntryIndex = i; ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} /* rsnSearchPmkidEntry */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to check if there is difference ++* between PMKID candicate list and PMKID cache. If there ++* is new candicate that no cache entry is available, then ++* add a new entry for the new candicate in the PMKID cache ++* and set the PMKID indication flag to TRUE. ++* ++* \retval TRUE, if new member in the PMKID candicate list ++* \retval FALSe, if no new member in the PMKID candicate list ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ UINT_32 i; /* Index for PMKID candicate */ ++ UINT_32 j; /* Indix for PMKID cache */ ++ BOOLEAN status = FALSE; ++ ++ DEBUGFUNC("rsnCheckPmkidCandicate"); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ /* Check for each candicate */ ++ for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) { ++ for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) { ++ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, ++ prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN)) { ++ /* DBGLOG(RSN, TRACE, ("%pM at PMKID cache!!\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); */ ++ break; ++ } ++ } ++ ++ /* No entry found in PMKID cache for the candicate, add new one */ ++ if (j == prAisSpecBssInfo->u4PmkidCacheCount ++ && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) { ++ DBGLOG(RSN, TRACE, ++ "Add %pM to PMKID cache!!\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); ++ kalMemCopy((PVOID) prAisSpecBssInfo-> ++ arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID, ++ (PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN); ++ prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE; ++ prAisSpecBssInfo->u4PmkidCacheCount++; ++ ++ status = TRUE; ++ } ++ } ++ ++ return status; ++} /* rsnCheckPmkidCandicate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to wait a duration to indicate the pre-auth AP candicate ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) ++{ ++ DBGLOG(RSN, EVENT, "Security - Time to indicate the PMKID cand.\n"); ++ ++ /* If the authentication mode is WPA2 and indication PMKID flag ++ is available, then we indicate the PMKID candidate list to NDIS and ++ clear the flag, indicatePMKID */ ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED && ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { ++ rsnGeneratePmkidIndication(prAdapter); ++ } ++ ++} /* end of rsnIndicatePmkidCand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to check the BSS Desc at scan result ++* with pre-auth cap at wpa2 mode. If there ++* is candicate that no cache entry is available, then ++* add a new entry for the new candicate in the PMKID cache ++* and set the PMKID indication flag to TRUE. ++* ++* \param[in] prBss The BSS Desc at scan result ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) ++{ ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("rsnCheckPmkidCandicate"); ++ ++ ASSERT(prBss); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && ++ (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) { ++ rsnSelectPmkidCandidateList(prAdapter, prBss); ++ ++ /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection() ++ will indicate this later */ ++ if (rsnCheckPmkidCandicate(prAdapter)) { ++ DBGLOG(RSN, TRACE, "Prepare a timer to indicate candidate PMKID Candidate\n"); ++ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); ++ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, ++ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to generate an PMKID candidate list ++* indication to NDIS. ++* ++* \param[in] prAdapter Pointer to the adapter object data area. ++* \param[in] u4Flags PMKID candidate list event: ++* PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter) ++{ ++ P_PARAM_STATUS_INDICATION_T prStatusEvent; ++ P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ UINT_8 i, j = 0, count = 0; ++ UINT_32 u4LenOfUsedBuffer; ++ ++ DEBUGFUNC("rsnGeneratePmkidIndication"); ++ ++ ASSERT(prAdapter); ++ ++ prStatusEvent = (P_PARAM_STATUS_INDICATION_T) prAdapter->aucIndicationEventBuffer; ++ ++ /* Status type: PMKID Candidatelist Event */ ++ prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; ++ ASSERT(prStatusEvent); ++ ++ prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T) (&prStatusEvent->eStatusType + 1); ++ ASSERT(prPmkidEvent); ++ ++ prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prAisSpecificBssInfo); ++ ++ for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) { ++ for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) { ++ if (EQUAL_MAC_ADDR(prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, ++ prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) && ++ (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)) { ++ break; ++ } ++ } ++ if (count >= CFG_MAX_PMKID_CACHE) ++ break; ++ ++ if (j == prAisSpecificBssInfo->u4PmkidCacheCount) { ++ kalMemCopy((PVOID) prPmkidEvent->arCandidateList[count].arBSSID, ++ (PVOID) prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid, PARAM_MAC_ADDR_LEN); ++ prPmkidEvent->arCandidateList[count].u4Flags = ++ prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags; ++ DBGLOG(RSN, TRACE, "%pM %d\n", (prPmkidEvent->arCandidateList[count].arBSSID), ++ (UINT_32) prPmkidEvent->arCandidateList[count].u4Flags); ++ count++; ++ } ++ } ++ ++ /* PMKID Candidate List */ ++ prPmkidEvent->u4Version = 1; ++ prPmkidEvent->u4NumCandidates = count; ++ DBGLOG(RSN, TRACE, "rsnGeneratePmkidIndication #%d\n", (UINT_32) prPmkidEvent->u4NumCandidates); ++ u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) + ++ (count * sizeof(PARAM_PMKID_CANDIDATE_T)); ++ /* dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); */ ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); ++ ++} /* rsnGeneratePmkidIndication */ ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate WSC IE for ++* associate request frame. ++* ++* \param[in] prCurrentBss The Selected BSS description ++* ++* \retval The append WSC IE length ++* ++* \note ++* Called by: AIS module, Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ /* ASSOC INFO IE ID: 221 :0xDD */ ++ if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) { ++ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, ++ prAdapter->prGlueInfo->u2WSCAssocInfoIELen); ++ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen; ++ } ++ ++} ++#endif ++ ++#if CFG_SUPPORT_802_11W ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if the Bip Key installed or not ++* ++* \param[in] ++* prAdapter ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX) ++ return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled; ++ else ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to check the Sa query timeout. ++* ++* ++* \note ++* Called by: AIS module, Handle by Sa Quert timeout ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ UINT_32 now; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ GET_CURRENT_SYSTIME(&now); ++ ++ if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, TU_TO_MSEC(1000))) { ++ LOG_FUNC("association SA Query timed out\n"); ++ ++ prBssSpecInfo->ucSaQueryTimedOut = 1; ++ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ prBssSpecInfo->pucSaQueryTransId = NULL; ++ prBssSpecInfo->u4SaQueryCount = 0; ++ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); ++ /* Re-connect */ ++ DBGLOG(RSN, TRACE, "DisBy11w\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to start the 802.11w sa query timer. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_SA_QUERY_FRAME prTxFrame; ++ UINT_16 u2PayloadLen; ++ PUINT_8 pucTmp = NULL; ++ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ASSERT(prBssInfo); ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ LOG_FUNC("MFP: Start Sa Query\n"); ++ ++ if (prBssSpecInfo->u4SaQueryCount > 0 && rsnCheckSaQueryTimeout(prAdapter)) { ++ LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount); ++ return; ++ } ++ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ ++ if (!prMsduInfo) ++ return; ++ ++ prTxFrame = (P_ACTION_SA_QUERY_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; ++ prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST; ++ ++ if (prBssSpecInfo->u4SaQueryCount == 0) ++ GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart); ++ ++ if (prBssSpecInfo->u4SaQueryCount) { ++ pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); ++ if (!pucTmp) { ++ DBGLOG(RSN, ERROR, "MFP: Fail to alloc tmp buffer for backup sa query id\n"); ++ return; ++ } ++ kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ } ++ ++ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ ++ ucTransId[0] = (UINT_8) (kalRandomNumber() & 0xFF); ++ ucTransId[1] = (UINT_8) (kalRandomNumber() & 0xFF); ++ ++ kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ prBssSpecInfo->u4SaQueryCount++; ++ ++ prBssSpecInfo->pucSaQueryTransId = ++ kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); ++ if (!prBssSpecInfo->pucSaQueryTransId) { ++ DBGLOG(RSN, ERROR, "MFP: Fail to alloc buffer for sa query id list\n"); ++ return; ++ } ++ ++ if (pucTmp) { ++ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, ++ (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); ++ kalMemCopy(&prBssSpecInfo->pucSaQueryTransId ++ [(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN], ucTransId, ++ ACTION_SA_QUERY_TR_ID_LEN); ++ kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); ++ } else { ++ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ } ++ ++ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ DBGLOG(RSN, TRACE, ++ "Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval); ++ ++ cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, TU_TO_MSEC(201)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to start the 802.11w sa query. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnStartSaQuery(IN P_ADAPTER_T prAdapter) ++{ ++ rsnStartSaQueryTimer(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to stop the 802.11w sa query. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnStopSaQuery(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); ++ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ prBssSpecInfo->pucSaQueryTransId = NULL; ++ prBssSpecInfo->u4SaQueryCount = 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11w sa query action frame. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_SA_QUERY_FRAME prRxFrame = NULL; ++ UINT_16 u2PayloadLen; ++ P_STA_RECORD_T prStaRec; ++ P_ACTION_SA_QUERY_FRAME prTxFrame; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ASSERT(prBssInfo); ++ ++ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; ++ if (!prRxFrame) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Request from %pM\n", prStaRec->aucMacAddr); ++ ++ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Ignore SA Query Request from unassociated STA %pM\n", ++ prStaRec->aucMacAddr); ++ return; ++ } ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Sending SA Query Response to %pM\n", prStaRec->aucMacAddr); ++ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ ++ if (!prMsduInfo) ++ return; ++ ++ prTxFrame = (P_ACTION_SA_QUERY_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ /* SA Query always with protected */ ++ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; ++ prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE; ++ ++ kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11w sa query action frame. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ P_ACTION_SA_QUERY_FRAME prRxFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_32 i; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Too short SA Query Action frame (len=%u)\n", ++ prSwRfb->u2PacketLen); ++ return; ++ } ++ ++ if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) { ++ rsnSaQueryRequest(prAdapter, prSwRfb); ++ return; ++ } ++ ++ if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Unexpected SA Query " "Action %d\n", prRxFrame->ucAction); ++ return; ++ } ++ ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Response from %pM\n", prStaRec->aucMacAddr); ++ ++ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ /* MLME-SAQuery.confirm */ ++ ++ for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) { ++ if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId + ++ i * ACTION_SA_QUERY_TR_ID_LEN, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0) ++ break; ++ } ++ ++ if (i >= prBssSpecInfo->u4SaQueryCount) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: No matching SA Query " "transaction identifier found\n"); ++ return; ++ } ++ ++ DBGLOG(RSN, TRACE, "Reply to pending SA Query received\n"); ++ ++ rsnStopSaQuery(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11w mgmt frame. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype) ++{ ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ BOOLEAN fgUnicast = TRUE; ++ BOOLEAN fgRobustAction = FALSE; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ++ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) && ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { ++ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; ++ ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ ++ if (prAssocReqFrame->aucDestAddr[0] & BIT(0)) ++ fgUnicast = FALSE; ++ ++ LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved, ++ (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype); ++ ++ if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) { ++ /* "Dropped unprotected Robust Action frame from an MFP STA" */ ++ /* exclude Public Action */ ++ if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */) { ++ UINT_8 ucAction = *prSwRfb->pucRecvBuff; ++ ++ if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) { ++#if DBG && CFG_RX_PKTS_DUMP ++ LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction); ++#endif ++ fgRobustAction = TRUE; ++ return TRUE; ++ } ++ } ++ if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) ++ || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) { ++ LOG_FUNC("QM RX MGT: rsnStartSaQuery\n"); ++ /* MFP test plan 5.3.3.5 */ ++ rsnStartSaQuery(prAdapter); ++ return TRUE; ++ } ++ } ++#if 0 ++ else { ++ if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) { ++ /* This done by function handler */ ++ /* kalIndicateStatusAndComplete(prAdapter->prGlueInfo, */ ++ /* WLAN_STATUS_MEDIA_DISCONNECT, */ ++ /* NULL, */ ++ /* 0); */ ++ } ++ } ++#endif ++ } ++ return FALSE; ++} ++#endif ++ ++#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE ++static BOOLEAN rsnCheckWpaRsnInfo(P_BSS_INFO_T prBss, P_RSN_INFO_T prWpaRsnInfo) ++{ ++ UINT_32 i = 0; ++ ++ if (prWpaRsnInfo->u4GroupKeyCipherSuite != prBss->u4RsnSelectedGroupCipher) { ++ DBGLOG(RSN, INFO, "GroupCipherSuite change, old=0x%04x, new=0x%04x\n", ++ prBss->u4RsnSelectedGroupCipher, prWpaRsnInfo->u4GroupKeyCipherSuite); ++ return TRUE; ++ } ++ for (; i < prWpaRsnInfo->u4AuthKeyMgtSuiteCount; i++) ++ if (prBss->u4RsnSelectedAKMSuite == prWpaRsnInfo->au4AuthKeyMgtSuite[i]) ++ break; ++ if (i == prWpaRsnInfo->u4AuthKeyMgtSuiteCount) { ++ DBGLOG(RSN, INFO, "KeyMgmt change, not find 0x%04x in new beacon\n", prBss->u4RsnSelectedAKMSuite); ++ return TRUE; ++ } ++ ++ for (i = 0; i < prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) ++ if (prBss->u4RsnSelectedPairwiseCipher == prWpaRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ break; ++ if (i == prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount) { ++ DBGLOG(RSN, INFO, "Pairwise Cipher change, not find 0x%04x in new beacon\n", ++ prBss->u4RsnSelectedPairwiseCipher); ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc) ++{ ++ ENUM_PARAM_AUTH_MODE_T eAuthMode = prAdapter->rWifiVar.rConnSettings.eAuthMode; ++ ++ switch (eAuthMode) { ++ case AUTH_MODE_OPEN: /* original is open system */ ++ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) && !prAdapter->prGlueInfo->rWpaInfo.fgPrivacyInvoke) { ++ DBGLOG(RSN, INFO, "security change, open->privacy\n"); ++ return TRUE; ++ } ++ break; ++ case AUTH_MODE_SHARED: /* original is WEP */ ++ case AUTH_MODE_AUTO_SWITCH: ++ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) == 0) { ++ DBGLOG(RSN, INFO, "security change, WEP->open\n"); ++ return TRUE; ++ } else if (prBssDesc->fgIERSN || prBssDesc->fgIEWPA) { ++ DBGLOG(RSN, INFO, "security change, WEP->WPA/WPA2\n"); ++ return TRUE; ++ } ++ break; ++ case AUTH_MODE_WPA: /*original is WPA */ ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA_NONE: ++ if (prBssDesc->fgIEWPA) ++ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rWPAInfo); ++ DBGLOG(RSN, INFO, "security change, WPA->%s\n", ++ prBssDesc->fgIERSN ? "WPA2" : ++ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); ++ return TRUE; ++ case AUTH_MODE_WPA2: /*original is WPA2 */ ++ case AUTH_MODE_WPA2_PSK: ++ if (prBssDesc->fgIERSN) ++ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rRSNInfo); ++ DBGLOG(RSN, INFO, "security change, WPA2->%s\n", ++ prBssDesc->fgIEWPA ? "WPA" : ++ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); ++ return TRUE; ++ default: ++ DBGLOG(RSN, WARN, "unknowned eAuthMode=%d\n", eAuthMode); ++ break; ++ } ++ /*DBGLOG(RSN, INFO, ("rsnCheckSecurityModeChanged, eAuthMode=%d, u2CapInfo=0x%02x, fgIEWPA=%d, fgIERSN=%d\n", ++ eAuthMode, prBssDesc->u2CapInfo, prBssDesc->fgIEWPA, prBssDesc->fgIERSN)); */ ++ return FALSE; ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c +new file mode 100644 +index 000000000000..596ede60d788 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c +@@ -0,0 +1,1788 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2 ++*/ ++ ++/*! \file "saa_fsm.c" ++ \brief This file defines the FSM for SAA MODULE. ++ ++ This file defines the FSM for SAA MODULE. ++*/ ++ ++/* ++** Log: saa_fsm.c ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 04 20 2012 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * correct macro ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT ++ * for REASSOCIATED cases as an explicit trigger for Android framework ++ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. ++ * 2. (Android only) when reassociation-and-non-roaming cases happened, ++ * indicate an extra DISCONNECT indication to Android Wi-Fi framework ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * Add debug message about 40MHz bandwidth allowed ++ * ++ * 05 12 2011 cp.wu ++ * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC ++ * has been invalidated before SAA-FSM starts to roll ++ * check for valid STA-REC before SAA-FSM starts to roll. ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 31 2011 puff.wen ++ * NULL ++ * . ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add RX deauthentication & disassociation process under Hot-Spot mode. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix compile error of after Station Type Macro modification. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete ++ * and might leads to BSOD when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. ++ * Update saa_fsm for BOW. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * Add support for P2P join event start. ++ * ++ * 07 12 2010 cp.wu ++ * ++ * SAA will take a record for tracking request sequence number. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with main branch for resetting to state 1 when associating with another AP ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error when enable WiFi Direct function. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * ++ * * * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support of Driver STA_RECORD_T activation ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 12 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix compile warning due to declared but not used ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Refine Debug Label ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update comment ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * rename the function ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugAAState[AA_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("AA_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH1"), ++ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH2"), ++ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH3"), ++ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH4"), ++ (PUINT_8) DISP_STRING("SAA_STATE_SEND_ASSOC1"), ++ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_ASSOC2"), ++ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH2"), ++ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH4"), ++ (PUINT_8) DISP_STRING("AAA_STATE_SEND_ASSOC2"), ++ (PUINT_8) DISP_STRING("AA_STATE_RESOURCE") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The Core FSM engine of SAA Module. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] eNextState The value of Next State ++* @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN Success ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++saaFsmSteps(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb) ++{ ++ ENUM_AA_STATE_T ePreviousState; ++ BOOLEAN fgIsTransition; ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) { ++ return; ++ } ++ ++ do { ++ ++#if DBG ++ DBGLOG(SAA, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugAAState[prStaRec->eAuthAssocState], apucDebugAAState[eNextState]); ++#else ++ DBGLOG(SAA, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_SAA_IDX, prStaRec->eAuthAssocState, eNextState); ++#endif ++ ePreviousState = prStaRec->eAuthAssocState; ++ ++ /* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */ ++ prStaRec->eAuthAssocState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ switch (prStaRec->eAuthAssocState) { ++ case AA_STATE_IDLE: ++ if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */ ++ ++ if (prRetainedSwRfb) { ++ if (saaFsmSendEventJoinComplete(prAdapter, ++ WLAN_STATUS_SUCCESS, ++ prStaRec, ++ prRetainedSwRfb) == WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ } else { ++ eNextState = AA_STATE_RESOURCE; ++ fgIsTransition = TRUE; ++ } ++ } else { ++ if (saaFsmSendEventJoinComplete(prAdapter, ++ WLAN_STATUS_FAILURE, ++ prStaRec, ++ NULL) == WLAN_STATUS_RESOURCES) { ++ eNextState = AA_STATE_RESOURCE; ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ } ++ ++ /* Free allocated TCM memory */ ++ if (prStaRec->prChallengeText) { ++ cnmMemFree(prAdapter, prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ break; ++ ++ case SAA_STATE_SEND_AUTH1: ++ { ++ /* Do tasks in INIT STATE */ ++ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ eNextState = AA_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } else { ++ prStaRec->ucTxAuthAssocRetryCount++; ++ ++ /* Update Station Record - Class 1 Flag */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++#if !CFG_SUPPORT_AAA ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) { ++#else ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, ++ prStaRec->ucNetTypeIndex, ++ NULL, ++ AUTH_TRANSACTION_SEQ_1, ++ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { ++#endif /* CFG_SUPPORT_AAA */ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); ++ } ++ } ++ } ++ break; ++ ++ case SAA_STATE_WAIT_AUTH2: ++ break; ++ ++ case SAA_STATE_SEND_AUTH3: ++ { ++ /* Do tasks in INIT STATE */ ++ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ eNextState = AA_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } else { ++ prStaRec->ucTxAuthAssocRetryCount++; ++ ++#if !CFG_SUPPORT_AAA ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) { ++#else ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, ++ prStaRec->ucNetTypeIndex, ++ NULL, ++ AUTH_TRANSACTION_SEQ_3, ++ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { ++#endif /* CFG_SUPPORT_AAA */ ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); ++ } ++ } ++ } ++ break; ++ ++ case SAA_STATE_WAIT_AUTH4: ++ break; ++ ++ case SAA_STATE_SEND_ASSOC1: ++ /* Do tasks in INIT STATE */ ++ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; ++ ++ eNextState = AA_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } else { ++ prStaRec->ucTxAuthAssocRetryCount++; ++ ++ if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU)); ++ } ++ } ++ ++ break; ++ ++ case SAA_STATE_WAIT_ASSOC2: ++ break; ++ ++ case AA_STATE_RESOURCE: ++ /* TODO(Kevin) Can setup a timer and send message later */ ++ break; ++ ++ default: ++ DBGLOG(SAA, ERROR, "Unknown AA STATE\n"); ++ ASSERT(0); ++ break; ++ } ++ ++ } while (fgIsTransition); ++ ++ return; ++ ++} /* end of saaFsmSteps() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Event to AIS/BOW/P2P ++* ++* @param[in] rJoinStatus To indicate JOIN success or failure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prSwRfb Pointer to the SW_RFB_T ++ ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, ++ IN WLAN_STATUS rJoinStatus, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ ++ /* Store limitation about 40Mhz bandwidth capability during association */ ++ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ if (rJoinStatus == WLAN_STATUS_SUCCESS) ++ prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++ ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; ++ ++ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); ++ if (!prSaaFsmCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; ++ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; ++ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; ++ prSaaFsmCompMsg->prStaRec = prStaRec; ++ prSaaFsmCompMsg->prSwRfb = prSwRfb; ++ ++ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; ++ ++ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); ++ if (!prSaaFsmCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; ++ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; ++ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; ++ prSaaFsmCompMsg->prStaRec = prStaRec; ++ prSaaFsmCompMsg->prSwRfb = prSwRfb; ++ ++ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { ++ /* @TODO: BOW handler */ ++ ++ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; ++ ++ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); ++ if (!prSaaFsmCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; ++ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; ++ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; ++ prSaaFsmCompMsg->prStaRec = prStaRec; ++ prSaaFsmCompMsg->prSwRfb = prSwRfb; ++ ++ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ else { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++} /* end of saaFsmSendEventJoinComplete() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Start Event to SAA FSM. ++* ++* @param[in] prMsgHdr Message of Join Request for a particular STA. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SAA_FSM_START_T prSaaFsmStartMsg; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T) prMsgHdr; ++ prStaRec = prSaaFsmStartMsg->prStaRec; ++ ++ if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ ASSERT(prStaRec); ++ ++ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n"); ++ ++ /* record sequence number of request message */ ++ prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ /* 4 <1> Validation of SAA Start Event */ ++ if (!IS_AP_STA(prStaRec)) { ++ ++ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); ++ ++ /* Ignore the return value because don't care the prSwRfb */ ++ saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL); ++ ++ return; ++ } ++ /* 4 <2> The previous JOIN process is not completed ? */ ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ } ++ /* 4 <3> Reset Status Code and Time */ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); ++ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ if (prStaRec->prChallengeText) { ++ cnmMemFree(prAdapter, prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++#if CFG_PRIVACY_MIGRATION ++ /* 4 <4> Init the sec fsm */ ++ secFsmInit(prAdapter, prStaRec); ++#endif ++ ++ /* 4 <5> Reset the STA STATE */ ++ /* Update Station Record - Class 1 Flag */ ++ /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue - ++ * We won't deactivate the same STA_RECORD_T and then activate it again for the ++ * case of reconnection. ++ */ ++ /* cnmStaRecChangeState(prStaRec, STA_STATE_1); */ ++ ++ /* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */ ++ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) ++ && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { ++ prBssInfo->fgAssoc40mBwAllowed = cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex); ++ } else { ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++ DBGLOG(RLM, INFO, "STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed); ++ } ++ /* 4 <7> Trigger SAA FSM */ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); ++ else if (prStaRec->ucStaState == STA_STATE_2 || prStaRec->ucStaState == STA_STATE_3) ++ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, (P_SW_RFB_T) NULL); ++ ++} /* end of saaFsmRunEventStart() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM. ++* ++* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. ++* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. ++* ++* @retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ ++ P_STA_RECORD_T prStaRec; ++ ENUM_AA_STATE_T eNextState; ++ ++ ASSERT(prMsduInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) { ++ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status %d, Invalid StaRec\n", rTxDoneStatus); ++ return WLAN_STATUS_INVALID_PACKET; ++ } ++ ++ ASSERT(prStaRec); ++ ++ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status: %d, eAuthAssocState: %d , SeqNO: %d ", ++ rTxDoneStatus, prStaRec->eAuthAssocState, ++ prMsduInfo->ucTxSeqNum); ++ ++ eNextState = prStaRec->eAuthAssocState; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_AUTH1: ++ { ++ /* Strictly check the outgoing frame is matched with current AA STATE */ ++ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) { ++ eNextState = SAA_STATE_WAIT_AUTH2; ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); ++ } ++ ++ /* if TX was successful, change to next state. ++ * if TX was failed, do retry if possible. ++ */ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ case SAA_STATE_SEND_AUTH3: ++ { ++ /* Strictly check the outgoing frame is matched with current JOIN STATE */ ++ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) { ++ eNextState = SAA_STATE_WAIT_AUTH4; ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); ++ } ++ ++ /* if TX was successful, change to next state. ++ * if TX was failed, do retry if possible. ++ */ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ case SAA_STATE_SEND_ASSOC1: ++ { ++ /* Strictly check the outgoing frame is matched with current SAA STATE */ ++ if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) { ++ eNextState = SAA_STATE_WAIT_ASSOC2; ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &(prStaRec->rTxReqDoneOrRxRespTimer), ++ TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU)); ++ } ++ /* if TX was successful, change to next state. ++ * if TX was failed, do retry if possible. ++ */ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of saaFsmRunEventTxDone() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Tx Request Timeout Event to SAA FSM. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ++ DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %u\n", kalGetTimeTick()); ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_AUTH1: ++ case SAA_STATE_SEND_AUTH3: ++ case SAA_STATE_SEND_ASSOC1: ++ saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T) NULL); ++ break; ++ ++ default: ++ return; ++ } ++ ++} /* end of saaFsmRunEventTxReqTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Rx Response Timeout Event to SAA FSM. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ ENUM_AA_STATE_T eNextState; ++ ++ DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %u\n", kalGetTimeTick()); ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ++ eNextState = prStaRec->eAuthAssocState; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_WAIT_AUTH2: ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ /* Pull back to earlier state to do retry */ ++ eNextState = SAA_STATE_SEND_AUTH1; ++ break; ++ ++ case SAA_STATE_WAIT_AUTH4: ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ /* Pull back to earlier state to do retry */ ++ eNextState = SAA_STATE_SEND_AUTH3; ++ break; ++ ++ case SAA_STATE_WAIT_ASSOC2: ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; ++ ++ /* Pull back to earlier state to do retry */ ++ eNextState = SAA_STATE_SEND_ASSOC1; ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ if (eNextState != prStaRec->eAuthAssocState) ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ ++} /* end of saaFsmRunEventRxRespTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Auth Response Frame and then ++* trigger SAA FSM. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2StatusCode; ++ ENUM_AA_STATE_T eNextState; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ /* We should have the corresponding Sta Record. */ ++ if (!prStaRec) { ++ /* Peter: we can handle the packet without station record */ ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ if (!IS_AP_STA(prStaRec)) ++ return; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_AUTH1: ++ case SAA_STATE_WAIT_AUTH2: ++ /* Check if the incoming frame is what we are waiting for */ ++ if (authCheckRxAuthFrameStatus(prAdapter, ++ prSwRfb, AUTH_TRANSACTION_SEQ_2, &u2StatusCode) == WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); ++ ++ if (prStaRec->ucAuthAlgNum == (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY) { ++ ++ eNextState = SAA_STATE_SEND_AUTH3; ++ } else { ++ /* Update Station Record - Class 2 Flag */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++ eNextState = SAA_STATE_SEND_ASSOC1; ++ } ++ } else { ++ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", ++ (prStaRec->aucMacAddr), u2StatusCode); ++ ++ eNextState = AA_STATE_IDLE; ++ } ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ case SAA_STATE_SEND_AUTH3: ++ case SAA_STATE_WAIT_AUTH4: ++ /* Check if the incoming frame is what we are waiting for */ ++ if (authCheckRxAuthFrameStatus(prAdapter, ++ prSwRfb, AUTH_TRANSACTION_SEQ_4, &u2StatusCode) == WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */ ++ ++ /* Update Station Record - Class 2 Flag */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++ eNextState = SAA_STATE_SEND_ASSOC1; ++ } else { ++ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", ++ (prStaRec->aucMacAddr), u2StatusCode); ++ ++ eNextState = AA_STATE_IDLE; ++ } ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++} /* end of saaFsmRunEventRxAuth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx (Re)Association Response Frame and then ++* trigger SAA FSM. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS if the status code was not success ++* @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2StatusCode; ++ ENUM_AA_STATE_T eNextState; ++ P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T) NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ /* We should have the corresponding Sta Record. */ ++ if (!prStaRec) { ++ ASSERT(0); ++ return rStatus; ++ } ++ ++ if (!IS_AP_STA(prStaRec)) ++ return rStatus; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_ASSOC1: ++ case SAA_STATE_WAIT_ASSOC2: ++ /* TRUE if the incoming frame is what we are waiting for */ ++ if (assocCheckRxReAssocRspFrameStatus(prAdapter, prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++ /* Update Station Record - Class 3 Flag */ ++ /* NOTE(Kevin): Moved to AIS FSM for roaming issue - ++ * We should deactivate the STA_RECORD_T of previous AP before ++ * activate new one in Driver. ++ */ ++ /* cnmStaRecChangeState(prStaRec, STA_STATE_3); */ ++ ++ prStaRec->ucJoinFailureCount = 0; /* Clear history. */ ++ ++ prRetainedSwRfb = prSwRfb; ++ rStatus = WLAN_STATUS_PENDING; ++ } else { ++ DBGLOG(SAA, INFO, "Assoc Req was rejected by [ %pM ], Status Code = %d\n", ++ (prStaRec->aucMacAddr), u2StatusCode); ++ } ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ /* update RCPI */ ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ ++ eNextState = AA_STATE_IDLE; ++ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb); ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ return rStatus; ++ ++} /* end of saaFsmRunEventRxAssoc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the incoming Deauth Frame. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if (prStaRec == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; ++ DBGLOG(SAA, INFO, "Rx Deauth frame from BSSID=[ %pM ].\n", prDeauthFrame->aucBSSID); ++ ++ do { ++ if (IS_STA_IN_AIS(prStaRec)) { ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ if (!IS_AP_STA(prStaRec)) ++ break; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prStaRec->ucStaState <= STA_STATE_1) ++ break; ++ ++ /* Check if this is the AP we are associated or associating with */ ++ if (authProcessRxDeauthFrame(prSwRfb, ++ prStaRec->aucMacAddr, ++ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ ++ DBGLOG(SAA, INFO, "Deauth reason = %d\n", prStaRec->u2ReasonCode); ++ ++ if (STA_STATE_2 <= prStaRec->ucStaState) { ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ ++ /* NOTE(Kevin): Change state immediately to avoid starvation of ++ * MSG buffer because of too many deauth frames before changing ++ * the STA state. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ prAisAbortMsg = ++ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) ++ break; ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; ++ prAisAbortMsg->ucReasonOfDisconnect = ++ DISCONNECT_REASON_CODE_DEAUTHENTICATED; ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, ++ MBOX_ID_0, ++ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ } else { ++ ++ /* TODO(Kevin): Joining Abort */ ++ } ++ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; ++ ++ } ++ ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ /* TODO(Kevin) */ ++ p2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb); ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb); ++#endif ++ else ++ ASSERT(0); ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of saaFsmRunEventRxDeauth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the incoming Disassociation Frame. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if (prStaRec == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; ++ DBGLOG(SAA, INFO, "Rx Disassoc frame from BSSID=[ %pM ].\n", (prDisassocFrame->aucBSSID)); ++ ++ do { ++ if (IS_STA_IN_AIS(prStaRec)) { ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ if (!IS_AP_STA(prStaRec)) ++ break; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prStaRec->ucStaState <= STA_STATE_1) ++ break; ++ ++ /* Check if this is the AP we are associated or associating with */ ++ if (assocProcessRxDisassocFrame(prAdapter, ++ prSwRfb, ++ prStaRec->aucMacAddr, ++ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ ++ DBGLOG(SAA, INFO, "Disassoc reason = %d\n", prStaRec->u2ReasonCode); ++ ++ if (STA_STATE_3 <= prStaRec->ucStaState) { ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ /* NOTE(Chaozhong): Change state immediately to avoid starvation of ++ * MSG buffer because of too many disassoc frames before changing ++ * the STA state. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++ prAisAbortMsg = ++ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) ++ break; ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; ++ prAisAbortMsg->ucReasonOfDisconnect = ++ DISCONNECT_REASON_CODE_DISASSOCIATED; ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, ++ MBOX_ID_0, ++ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ } else { ++ ++ /* TODO(Kevin): Joining Abort */ ++ } ++ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; ++ ++ } ++ ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ /* TODO(Kevin) */ ++ p2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb); ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (IS_STA_IN_BOW(prStaRec)) { ++ /* Do nothing */ ++ /* TODO(Kevin) */ ++ } ++#endif ++ else ++ ASSERT(0); ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of saaFsmRunEventRxDisassoc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Abort Event to SAA FSM. ++* ++* @param[in] prMsgHdr Message of Abort Request for a particular STA. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prMsgHdr); ++ ++ prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T) prMsgHdr; ++ prStaRec = prSaaFsmAbortMsg->prStaRec; ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) { ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n"); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel JOIN relative Timer */ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++#if DBG ++ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %s.\n", ++ apucDebugAAState[prStaRec->eAuthAssocState]); ++#else ++ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %d.\n", prStaRec->eAuthAssocState); ++#endif ++ } ++#if 0 ++ /* For the Auth/Assoc State to IDLE */ ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++#else ++ /* Free this StaRec */ ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++#endif ++ ++} /* end of saaFsmRunEventAbort() */ ++ ++/* TODO(Kevin): following code will be modified and move to AIS FSM */ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will send Join Timeout Event to JOIN FSM. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ ++ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); ++ ++ /* Get a Station Record if possible, TA == BSSID for AP */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); ++ ++ /* We have renew this Sta Record when in JOIN_STATE_INIT */ ++ ASSERT(prStaRec); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; ++ ++ /* Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prJoinInfo->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel other JOIN relative Timer */ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); ++ ++ /* Restore original setting from current BSS_INFO_T */ ++ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) ++ joinAdoptParametersFromCurrentBss(prAdapter); ++ ++ /* Pull back to IDLE */ ++ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); ++ ++ return WLAN_STATUS_FAILURE; ++ ++} /* end of joinFsmRunEventJoinTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from Peer BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ DEBUGFUNC("joinAdoptParametersFromPeerBss"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ ++ /* 4 <1> Adopt Peer BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; ++ ++ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", ++ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); ++ ++ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); ++ ++ prJoinInfo->fgIsParameterAdopted = TRUE; ++ ++} /* end of joinAdoptParametersFromPeerBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from current associated BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) ++{ ++ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ prBssInfo = &prAdapter->rBssInfo; ++ ++ /* 4 <1> Adopt current BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; ++ ++ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); ++} /* end of joinAdoptParametersFromCurrentBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will update all the SW variables and HW MCR registers after ++* the association with target BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinComplete(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ P_PEER_BSS_INFO_T prPeerBssInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SUPPORT_802_11D ++ P_IE_COUNTRY_T prIECountry; ++#endif ++ ++ DEBUGFUNC("joinComplete"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ prPeerBssInfo = &prAdapter->rPeerBssInfo; ++ prBssInfo = &prAdapter->rBssInfo; ++ prConnSettings = &prAdapter->rConnSettings; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ ++ /* Remove previous AP's Connection Flags if have */ ++ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); ++ ++ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ ++ ++ if (prBssDesc->fgIsHiddenSSID) { ++ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't ++ * broadcast SSID on its Beacon Frame. ++ */ ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); ++ ++ if (prBssDesc->ucSSIDLen) ++ prBssDesc->fgIsHiddenSSID = FALSE; ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); ++ } ++/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ ++ /* 4 <2.A> PHY Type */ ++ prBssInfo->ePhyType = prBssDesc->ePhyType; ++ ++ /* 4 <2.B> BSS Type */ ++ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ ++ /* 4 <2.C> BSSID */ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); ++ ++ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); ++ ++ /* 4 <2.D> SSID */ ++ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ ++ /* 4 <2.E> Channel / Band information. */ ++ prBssInfo->eBand = prBssDesc->eBand; ++ prBssInfo->ucChnl = prBssDesc->ucChannelNum; ++ ++ /* 4 <2.F> RSN/WPA information. */ ++ secFsmRunEventStart(prAdapter); ++ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; ++ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; ++ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; ++ ++ if (secRsnKeyHandshakeEnabled()) ++ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; ++ else ++ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; ++ ++ /* 4 <2.G> Beacon interval. */ ++ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ ++ /* 4 <2.H> DTIM period. */ ++ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; ++ ++ /* 4 <2.I> ERP Information */ ++ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ ++ (prBssDesc->fgIsERPPresent)) { ++ ++ prBssInfo->fgIsERPPresent = TRUE; ++ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ ++ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ ++ prBssInfo->fgIsERPPresent = FALSE; ++ prBssInfo->ucERP = 0; ++ } ++ ++#if CFG_SUPPORT_802_11D ++ /* 4 <2.J> Country inforamtion of the associated AP */ ++ if (prConnSettings->fgMultiDomainCapabilityEnabled) { ++ DOMAIN_INFO_ENTRY rDomainInfo; ++ ++ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { ++ if (prBssDesc->prIECountry) { ++ prIECountry = prBssDesc->prIECountry; ++ ++ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); ++ ++ /* use the domain get from the BSS info */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); ++ } else { ++ /* use the domain get from the scan result */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); ++ } ++ } ++ } ++#endif ++ ++ /* 4 <2.K> Signal Power of the associated AP */ ++ prBssInfo->rRcpi = prBssDesc->rRcpi; ++ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); ++ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); ++ ++ /* 4 <2.L> Capability Field of the associated AP */ ++ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; ++ ++ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", ++ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); ++ ++/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ ++ /* 4 <3.A> Association ID */ ++ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; ++ ++ /* 4 <3.B> WMM Information */ ++ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { ++ ++ prBssInfo->fgIsWmmAssoc = TRUE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; ++ ++ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); ++ ++ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { ++ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } else { ++ kalMemCopy(&prBssInfo->rWmmInfo, ++ &prPeerBssInfo->rWmmInfo, ++ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); ++ } ++ } else { ++ prBssInfo->fgIsWmmAssoc = FALSE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; ++ ++ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } ++ ++ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ ++ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; ++ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; ++ ++ /* 4 <3.D> Short Preamble */ ++ if (prBssInfo->fgIsERPPresent) { ++ ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) ++ * TRUE FALSE TRUE FALSE ++ * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) ++ * FALSE FALSE TRUE FALSE ++ * TRUE TRUE FALSE TRUE(follow ERP) ++ * TRUE TRUE TRUE FALSE(follow ERP) ++ * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) ++ * FALSE TRUE TRUE FALSE(we should set to FALSE) ++ */ ++ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && ++ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { ++ ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ ++ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) ++ prBssInfo->fgUseShortPreamble = FALSE; ++ else ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ } else { ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE ++ * FALSE FALSE FALSE ++ * TRUE TRUE TRUE ++ * FALSE TRUE(status success) TRUE ++ * --> Honor the result of prPeerBssInfo. ++ */ ++ ++ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = ++ prPeerBssInfo->fgIsShortPreambleAllowed; ++ } ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", ++ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); ++ ++ /* 4 <3.E> Short Slot Time */ ++ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); ++ ++ nicSetSlotTime(prAdapter, ++ prBssInfo->ePhyType, ++ ((prConnSettings->fgIsShortSlotTimeOptionEnable && ++ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); ++ ++ /* 4 <3.F> Update Tx Rate for Control Frame */ ++ bssUpdateTxRateForControlFrame(prAdapter); ++ ++ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ ++ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ ++ { ++ ++ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; ++ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; ++ ++ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; ++ ++ /* Set the stable time of the associated BSS. We won't do roaming decision ++ * during the stable time. ++ */ ++ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, ++ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); ++ } ++ ++ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ ++#if CFG_TX_FRAGMENT ++ txFragInfoUpdate(prAdapter); ++#endif /* CFG_TX_FRAGMENT */ ++ ++/* 4 <4> Update STA_RECORD_T */ ++ /* Get a Station Record if possible */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); ++ ++ if (prStaRec) { ++ UINT_16 u2OperationalRateSet, u2DesiredRateSet; ++ ++ /* 4 <4.A> Desired Rate Set */ ++ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & ++ prBssInfo->u2OperationalRateSet); ++ ++ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); ++ if (u2DesiredRateSet) { ++ prStaRec->u2DesiredRateSet = u2DesiredRateSet; ++ } else { ++ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ ++ prStaRec->u2DesiredRateSet = u2OperationalRateSet; ++ } ++ ++ /* Try to set the best initial rate for this entry */ ++ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, ++ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { ++ ++ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) ++ ASSERT(0); ++ } ++ ++ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); ++ ++ /* 4 <4.B> Preamble Mode */ ++ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; ++ ++ /* 4 <4.C> QoS Flag */ ++ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; ++ } ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++/* 4 <5> Update NIC */ ++ /* 4 <5.A> Update BSSID & Operation Mode */ ++ nicSetupBSS(prAdapter, prBssInfo); ++ ++ /* 4 <5.B> Update WLAN Table. */ ++ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) ++ ASSERT(FALSE); ++ /* 4 <5.C> Update Desired Rate Set for BT. */ ++#if CFG_TX_FRAGMENT ++ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) ++ txRateSetInitForBT(prAdapter, prStaRec); ++#endif /* CFG_TX_FRAGMENT */ ++ ++ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ ++ if (prBssInfo->fgIsWmmAssoc) { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, FALSE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); ++ } else { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, TRUE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); ++ ++ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); ++ } ++ ++#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN ++ { ++ prTxCtrl->fgBlockTxDuringJoin = FALSE; ++ ++#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ ++ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxRetransmitOfSendWaitQue(prAdapter); ++ ++ if (prTxCtrl->fgIsPacketInOsSendQueue) ++ nicTxRetransmitOfOsSendQue(prAdapter); ++#if CFG_SDIO_TX_ENHANCE ++ halTxLeftClusteredMpdu(prAdapter); ++#endif /* CFG_SDIO_TX_ENHANCE */ ++ ++ } ++#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ ++ ++/* 4 <6> Setup CONNECTION flag. */ ++ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; ++ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; ++ ++ if (prJoinInfo->fgIsReAssoc) ++ prAdapter->fgBypassPortCtrlForRoaming = TRUE; ++ else ++ prAdapter->fgBypassPortCtrlForRoaming = FALSE; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); ++ ++} /* end of joinComplete() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c +new file mode 100644 +index 000000000000..2c9ccbe82dd1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c +@@ -0,0 +1,3103 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3 ++*/ ++ ++/*! \file "scan.c" ++ \brief This file defines the scan profile and the processing function of ++ scan result for SCAN Module. ++ ++ The SCAN Profile selection is part of SCAN MODULE and responsible for defining ++ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. ++ In this file we also define the process of SCAN Result including adding, searching ++ and removing SCAN record from the list. ++*/ ++ ++/* ++** Log: scan.c ++** ++** 01 30 2013 yuche.tsai ++** [ALPS00451578] [JB2][WFD][Case Fail][JE][MR1]?????????[Java (JE),660,-1361051648,99, ++** /data/core/,0,system_server_crash,system_server]JE happens when try to connect WFD.(4/5) ++** Fix possible old scan result indicate to supplicant after formation. ++** ++** 01 16 2013 yuche.tsai ++** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect ++** Fix possible FW assert issue. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 25 2012 cp.wu ++ * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target ++ * drop off scan result which is older than 5 seconds when choosing which BSS to join ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 cp.wu ++ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band ++ * configuration with corresponding network configuration ++ * correct typo. ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration ++ * with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred ++ * band configuration corresponding to network type. ++ * ++ * 12 05 2011 cp.wu ++ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path ++ * add CONNECT_BY_BSSID policy ++ * ++ * 11 23 2011 cp.wu ++ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection ++ * add compile option to disable beacon content change detection. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp ++ * is reset with received beacon/probe response frames ++ * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before ++ * ++ * 10 11 2011 cm.chang ++ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter ++ * Ignore HT OP IE if its length field is not valid ++ * ++ * 09 30 2011 cp.wu ++ * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode ++ * correct type casting issue. ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix multicast address list issue. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 08 10 2011 cp.wu ++ * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing ++ * traverse whole BSS-DESC list because BSSID is not unique anymore. ++ * ++ * 07 12 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * for multiple BSS descriptior detecting issue: ++ * 1) check BSSID for infrastructure network ++ * 2) check SSID for AdHoc network ++ * ++ * 07 12 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * check for BSSID for beacons used to update DTIM ++ * ++ * 07 12 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * do not check BSS descriptor for connected flag due to linksys's hidden ++ * SSID will use another BSS descriptor and never connected ++ * ++ * 07 11 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * just pass beacons with the same BSSID. ++ * ++ * 07 11 2011 wh.su ++ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define ++ * for make sure the value is initialize, for customer not enable WAPI ++ * For make sure wapi initial value is set. ++ * ++ * 06 28 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * Do not check for SSID as beacon content change due to the existence of ++ * single BSSID with multiple SSID AP configuration ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * 1. correct logic ++ * 2. replace only BSS-DESC which doesn't have a valid SSID. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID ++ * settings to work around some tricky AP which use space character as hidden SSID ++ * remove unused temporal variable reference. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID ++ * settings to work around some tricky AP which use space character as hidden SSID ++ * allow to have a single BSSID with multiple SSID to be presented in scanning result ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels ++ * filter out BSS in disallowed channel by ++ * 1. do not add to scan result array if BSS is at disallowed channel ++ * 2. do not allow to search for BSS-DESC in disallowed channels ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Refine range of valid channel number ++ * ++ * 05 02 2011 cp.wu ++ * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of ++ * hardware channel number passed from firmware domain ++ * take parsed result for generating scanning result with channel information. ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Check if channel is valided before record ing BSS channel ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Always update Bss Type, for Bss Type for P2P Network is changing every time. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix concurrent issue when AIS scan result would overwrite p2p scan result. ++ * ++ * 03 14 2011 cp.wu ++ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently ++ * filtering out other BSS coming from adjacent channels ++ * ++ * 03 11 2011 chinglan.wang ++ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. ++ * . ++ * ++ * 03 11 2011 cp.wu ++ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently ++ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() ++ * won't sleep long enough for specified interval such as 500ms ++ * implement beacon change detection by checking SSID and supported rate. ++ * ++ * 02 22 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue ++ * Fix WSC big endian issue. ++ * ++ * 02 21 2011 terry.wu ++ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P ++ * Clean P2P scan list while removing P2P. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Fix scan channel extension issue when p2p module is not registered. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 21 2011 cp.wu ++ * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered ++ * BSS_DESC_T rather than using beacon-carried information ++ * SSID should come from buffered prBssDesc rather than beacon-carried information ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix compile error. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Memfree for P2P Descriptor & P2P Descriptor List. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Free P2P Descriptor List & Descriptor under BSS Descriptor. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc ++ * and vmalloc implementations to ease physically continuous memory demands ++ * 1) correct typo in scan.c ++ * 2) TX descriptors, RX descriptos and management buffer should use virtually ++ * continuous buffer instead of physically continuous one ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc ++ * and vmalloc implementations to ease physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * while being unloaded, clear all pending interrupt then set LP-own to firmware ++ * ++ * 12 21 2010 cp.wu ++ * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module ++ * SCN: enable BEST RSSI selection policy support ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 11 03 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Refine the HT rate disallow TKIP pairwise cipher . ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out ++ * beacons which is received on the folding frequency ++ * trust HT IE if available for 5GHz band ++ * ++ * 10 11 2010 cp.wu ++ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out ++ * beacons which is received on the folding frequency ++ * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 10 01 2010 yuche.tsai ++ * NULL ++ * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV. ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate unused variables which lead gcc to argue ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * When indicate scan result, append IE buffer information in the scan result. ++ * ++ * 09 03 2010 yuche.tsai ++ * NULL ++ * 1. Update Beacon RX count when running SLT. ++ * 2. Ignore Beacon when running SLT, would not update information from Beacon. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free. ++ * 2.. Fix P2P Device Name Length BE issue. ++ * ++ * 08 23 2010 yuche.tsai ++ * NULL ++ * Add P2P Device Found Indication to supplicant ++ * ++ * 08 20 2010 cp.wu ++ * NULL ++ * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured. ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Workaround for P2P Descriptor Infinite loop issue. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Modify code of processing Probe Resonse frame for P2P. ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add function to get P2P descriptor of BSS descriptor directly. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Modify Scan result processing for P2P module. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Update P2P Device Discovery result add function. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add support for Probe Request & Response parsing. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Fix compile error for SCAN module while disabling P2P feature. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * SCN module is now able to handle multiple concurrent scanning requests ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * driver no longer generates probe request frames ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * remove timer in DRV-SCN. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct BSS_DESC_T initialization after allocated. ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) for event packet, no need to fill RFB. ++ * 2) when wlanAdapterStart() failed, no need to initialize state machines ++ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan uninitialization procedure ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available, ++ * trust IE instead of RMAC information ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RLM APIs by CFG_RLM_MIGRATION. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Update P2P Function call. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * RSN/PRIVACY compilation flag awareness correction ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error when enable P2P function. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct when ADHOC support is turned on. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the TKIP disallow join a HT AP code. ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add more chance of JOIN retry for BG_SCAN ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 29 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * adjsut the pre-authentication code. ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 04 13 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add new HW CH macro support ++ * ++ * 04 06 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the firmware return the broadcast frame at wrong tc. ++ * ++ * 03 29 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * let the rsn wapi IE always parsing. ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Solve the compile warning for 'return non-void' function ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Fix No PKT_INFO_T issue ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Update outgoing ProbeRequest Frame's TX data rate ++ * ++ * 02 23 2010 wh.su ++ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver ++ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 20 2010 kevin.huang ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * ++ * Refine Beacon processing, add read RF channel from RX Status ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Modify u2EstimatedExtraIELen for probe request ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add HT cap IE to probe request ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update the process of SCAN Result by adding more Phy Attributes ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function and code for meet the new define ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename u4RSSI to i4RSSI ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Report event of scan result to host ++ * ++ * Nov 26 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix SCAN Record update ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status and Integrate with TXM ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add (Ext)Support Rate Set IE to ProbeReq ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Removed the use of SW_RFB->u2FrameLength ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix uninitial aucMacAddress[] for ProbeReq ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add scanSearchBssDescByPolicy() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Send Probe Request Frame ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define REPLICATED_BEACON_TIME_THRESHOLD (3000) ++#define REPLICATED_BEACON_FRESH_PERIOD (10000) ++#define REPLICATED_BEACON_STRENGTH_THRESHOLD (32) ++ ++#define ROAMING_NO_SWING_RCPI_STEP (10) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used by SCN to initialize its variables ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnInit(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_BSS_DESC_T prBSSDesc; ++ PUINT_8 pucBSSBuff; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ pucBSSBuff = &prScanInfo->aucScanBuffer[0]; ++ ++ DBGLOG(SCN, INFO, "->scnInit()\n"); ++ ++ /* 4 <1> Reset STATE and Message List */ ++ prScanInfo->eCurrentState = SCAN_STATE_IDLE; ++ ++ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; ++ ++ LINK_INITIALIZE(&prScanInfo->rPendingMsgList); ++ ++ /* 4 <2> Reset link list of BSS_DESC_T */ ++ kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE); ++ ++ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); ++ LINK_INITIALIZE(&prScanInfo->rBSSDescList); ++ ++ for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) { ++ ++ prBSSDesc = (P_BSS_DESC_T) pucBSSBuff; ++ ++ LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry); ++ ++ pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T)); ++ } ++ /* Check if the memory allocation consist with this initialization function */ ++ ASSERT(((ULONG) pucBSSBuff - (ULONG)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE); ++ ++ /* reset freest channel information */ ++ prScanInfo->fgIsSparseChannelValid = FALSE; ++ ++ /* reset NLO state */ ++ prScanInfo->fgNloScanning = FALSE; ++ prScanInfo->fgPscnOnnning = FALSE; ++ ++ prScanInfo->prPscnParam = kalMemAlloc(sizeof(PSCN_PARAM_T), VIR_MEM_TYPE); ++ if (prScanInfo->prPscnParam) ++ kalMemZero(prScanInfo->prPscnParam, sizeof(PSCN_PARAM_T)); ++ ++} /* end of scnInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used by SCN to uninitialize its variables ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ DBGLOG(SCN, INFO, "->scnUninit()\n"); ++ ++ /* 4 <1> Reset STATE and Message List */ ++ prScanInfo->eCurrentState = SCAN_STATE_IDLE; ++ ++ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; ++ ++ /* NOTE(Kevin): Check rPendingMsgList ? */ ++ ++ /* 4 <2> Reset link list of BSS_DESC_T */ ++ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); ++ LINK_INITIALIZE(&prScanInfo->rBSSDescList); ++ ++ kalMemFree(prScanInfo->prPscnParam, VIR_MEM_TYPE, sizeof(PSCN_PARAM_T)); ++ ++} /* end of scnUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given BSSID ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given BSSID ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ if (fgCheckSsid == FALSE || prSsid == NULL) ++ return prBssDesc; ++ ++ if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { ++ return prBssDesc; ++ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { ++ prDstBssDesc = prBssDesc; ++ } else { ++ /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, ++ * SSID must be updated. */ ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen); ++ return prBssDesc; ++ } ++ } ++ } ++ ++ return prDstBssDesc; ++ ++} /* end of scanSearchBssDescByBssid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucSrcAddr Given Source Address(TA). ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]) ++{ ++ return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucSrcAddr Given Source Address(TA). ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucSrcAddr); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) { ++ if (fgCheckSsid == FALSE || prSsid == NULL) ++ return prBssDesc; ++ ++ if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { ++ return prBssDesc; ++ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { ++ prDstBssDesc = prBssDesc; ++ } ++ ++ } ++ } ++ ++ return prDstBssDesc; ++ ++} /* end of scanSearchBssDescByTA() */ ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given BSSID ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; ++ OS_SYSTIME rLatestUpdateTime = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ if (!rLatestUpdateTime || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, rLatestUpdateTime)) { ++ prDstBssDesc = prBssDesc; ++ COPY_SYSTIME(rLatestUpdateTime, prBssDesc->rUpdateTime); ++ } ++ } ++ } ++ ++ return prDstBssDesc; ++ ++} /* end of scanSearchBssDescByBssid() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to ++* given eBSSType, BSSID and Transmitter Address ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. ++* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. ++* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]) ++{ ++ return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to ++* given eBSSType, BSSID and Transmitter Address ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. ++* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. ++* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, ++ IN UINT_8 aucBSSID[], ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_BSS_DESC_T prBssDesc, prIBSSBssDesc; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ ++ ++ ASSERT(prAdapter); ++ ASSERT(aucSrcAddr); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ switch (eBSSType) { ++ case BSS_TYPE_P2P_DEVICE: ++ fgCheckSsid = FALSE; ++ case BSS_TYPE_INFRASTRUCTURE: ++ case BSS_TYPE_BOW_DEVICE: ++ { ++ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); ++ ++ /* if (eBSSType == prBssDesc->eBSSType) */ ++ ++ return prBssDesc; ++ } ++ ++ case BSS_TYPE_IBSS: ++ { ++ prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); ++ prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid); ++ ++ /* NOTE(Kevin): ++ * Rules to maintain the SCAN Result: ++ * For AdHoc - ++ * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2 ++ * -> Update TA1 entry's BSSID. ++ * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again ++ * -> Update TA1 entry's contain. ++ * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or ++ * later, TA2 merge into TA1, we get TA2(BSSID1) ++ * -> Remove TA2 first and then replace TA1 entry's TA with TA2, ++ * Still have only one entry of BSSID. ++ * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1. ++ * -> Replace TA1 entry's TA with TA2, Still have only one entry. ++ * CASE V New IBSS ++ * -> Add this one to SCAN result. ++ */ ++ if (prBssDesc) { ++ if ((!prIBSSBssDesc) || /* CASE I */ ++ (prBssDesc == prIBSSBssDesc)) { /* CASE II */ ++ ++ return prBssDesc; ++ } /* CASE III */ ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ ++ return prIBSSBssDesc; ++ } ++ ++ if (prIBSSBssDesc) { /* CASE IV */ ++ ++ return prIBSSBssDesc; ++ } ++ /* CASE V */ ++ break; /* Return NULL; */ ++ } ++ ++ default: ++ break; ++ } ++ ++ return (P_BSS_DESC_T) NULL; ++ ++} /* end of scanSearchExistingBssDesc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Delete BSS Descriptors from current list according to given Remove Policy. ++* ++* @param[in] u4RemovePolicy Remove Policy. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ /* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */ ++ /* prBSSDescList->u4NumElem)); */ ++ ++ if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) { ++ P_BSS_DESC_T prBSSDescNext; ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { ++ ++ /* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): ++ * MAC: %pM, Current Time = %08lx, Update Time = %08lx\n", */ ++ /* prBssDesc, prBssDesc->aucBSSID, rCurrentTime, prBssDesc->rUpdateTime)); */ ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ } ++ } else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) { ++ P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ if (!prBssDesc->fgIsHiddenSSID) ++ continue; ++ ++ if (!prBssDescOldest) { /* 1st element */ ++ prBssDescOldest = prBssDesc; ++ continue; ++ } ++ ++ if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) ++ prBssDescOldest = prBssDesc; ++ } ++ ++ if (prBssDescOldest) { ++ ++ /* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): ++ * MAC: %pM, Update Time = %08lx\n", */ ++ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry); ++ } ++ } else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) { ++ P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL; ++ UINT_32 u4SameSSIDCount = 0; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ if ((!prBssDesc->fgIsHiddenSSID) && ++ (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) { ++ ++ u4SameSSIDCount++; ++ ++ if (!prBssDescWeakestSameSSID) ++ prBssDescWeakestSameSSID = prBssDesc; ++ else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) ++ prBssDescWeakestSameSSID = prBssDesc; ++ } ++ ++ if (!prBssDescWeakest) { /* 1st element */ ++ prBssDescWeakest = prBssDesc; ++ continue; ++ } ++ ++ if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) ++ prBssDescWeakest = prBssDesc; ++ ++ } ++ ++ if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) && (prBssDescWeakestSameSSID)) ++ prBssDescWeakest = prBssDescWeakestSameSSID; ++ ++ if (prBssDescWeakest) { ++ ++ /* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: %pM, Update Time = %08lx\n", */ ++ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry); ++ } ++ } else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) { ++ P_BSS_DESC_T prBSSDescNext; ++ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ ++ } ++ ++ return; ++ ++} /* end of scanRemoveBssDescsByPolicy() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Delete BSS Descriptors from current list according to given BSSID. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prBSSDescNext; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ /* Check if such BSS Descriptor exists in a valid list */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ ++ /* BSSID is not unique, so need to traverse whols link-list */ ++ } ++ } ++ ++} /* end of scanRemoveBssDescByBssid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Delete BSS Descriptors from current list according to given band configuration ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eBand Given band ++* @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS ++* BOW - Remove BOW BSS ++* P2P - Remove P2P BSS ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prBSSDescNext; ++ BOOLEAN fgToRemove; ++ ++ ASSERT(prAdapter); ++ ASSERT(eBand <= BAND_NUM); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ if (eBand == BAND_NULL) ++ return; /* no need to do anything, keep all scan result */ ++ ++ /* Check if such BSS Descriptor exists in a valid list */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ fgToRemove = FALSE; ++ ++ if (prBssDesc->eBand == eBand) { ++ switch (eNetTypeIndex) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) ++ || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) { ++ fgToRemove = TRUE; ++ } ++ break; ++ ++ case NETWORK_TYPE_P2P_INDEX: ++ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) ++ fgToRemove = TRUE; ++ break; ++ ++ case NETWORK_TYPE_BOW_INDEX: ++ if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) ++ fgToRemove = TRUE; ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ } ++ ++ if (fgToRemove == TRUE) { ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ } ++ ++} /* end of scanRemoveBssDescByBand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Clear the CONNECTION FLAG of a specified BSS Descriptor. ++* ++* @param[in] aucBSSID Given BSSID. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ prBssDesc->fgIsConnected = FALSE; ++ prBssDesc->fgIsConnecting = FALSE; ++ ++ /* BSSID is not unique, so need to traverse whols link-list */ ++ } ++ } ++ ++ return; ++ ++} /* end of scanRemoveConnectionFlagOfBssDescByBssid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Allocate new BSS_DESC_T ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* ++* @return Pointer to BSS Descriptor, if has free space. NULL, if has no space. ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T); ++ ++ if (prBssDesc) { ++ P_LINK_T prBSSDescList; ++ ++ kalMemZero(prBssDesc, sizeof(BSS_DESC_T)); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList)); ++ prBssDesc->fgIsP2PPresent = FALSE; ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be ++ * inserted to BSSDescList immediately. ++ */ ++ LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ ++ return prBssDesc; ++ ++} /* end of scanAllocateBssDesc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T ++* with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to the receiving frame buffer. ++* ++* @return Pointer to BSS Descriptor ++* NULL if the Beacon/ProbeResp frame is invalid ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_DESC_T prBssDesc = NULL; ++ UINT_16 u2CapInfo; ++ ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ ++ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; ++ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_8 ucHwChannelNum = 0; ++ UINT_8 ucIeDsChannelNum = 0; ++ UINT_8 ucIeHtChannelNum = 0; ++ BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE; ++ PARAM_SSID_T rSsid; ++ UINT_64 u8Timestamp; ++ BOOLEAN fgIsNewBssDesc = FALSE; ++ ++ UINT_32 i; ++ UINT_8 ucSSIDChar; ++ ++ UINT_8 ucOuiType; ++ UINT_16 u2SubTypeVersion; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; ++ ++ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo); ++ WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp); ++ ++ /* decide BSS type */ ++ switch (u2CapInfo & CAP_INFO_BSS_TYPE) { ++ case CAP_INFO_ESS: ++ /* It can also be Group Owner of P2P Group. */ ++ eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ break; ++ ++ case CAP_INFO_IBSS: ++ eBSSType = BSS_TYPE_IBSS; ++ break; ++ case 0: ++ /* The P2P Device shall set the ESS bit of the Capabilities field ++ * in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */ ++ eBSSType = BSS_TYPE_P2P_DEVICE; ++ break; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /* @TODO: add rule to identify BOW beacons */ ++#endif ++ ++ default: ++ DBGLOG(SCN, ERROR, "wrong bss type %d\n", (INT_32)(u2CapInfo & CAP_INFO_BSS_TYPE)); ++ return NULL; ++ } ++ ++ /* 4 <1.1> Pre-parse SSID IE */ ++ pucIE = prWlanBeaconFrame->aucInfoElem; ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); ++ ++ if (u2IELength > CFG_IE_BUFFER_SIZE) ++ u2IELength = CFG_IE_BUFFER_SIZE; ++ kalMemZero(&rSsid, sizeof(rSsid)); ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) { ++ ucSSIDChar = '\0'; ++ ++ /* D-Link DWL-900AP+ */ ++ if (IE_LEN(pucIE) == 0) ++ fgIsValidSsid = FALSE; ++ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ ++ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && ++ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ ++ else { ++ for (i = 0; i < IE_LEN(pucIE); i++) ++ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; ++ ++ if (ucSSIDChar) ++ fgIsValidSsid = TRUE; ++ } ++ ++ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ ++ if (fgIsValidSsid == TRUE) { ++ COPY_SSID(rSsid.aucSsid, ++ rSsid.u4SsidLen, SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); ++ } ++ } ++ fgEscape = TRUE; ++ break; ++ default: ++ break; ++ } ++ ++ if (fgEscape == TRUE) ++ break; ++ } ++ if (fgIsValidSsid) ++ DBGLOG(SCN, EVENT, "%s %pM channel %d\n", rSsid.aucSsid, prWlanBeaconFrame->aucBSSID, ++ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); ++ else ++ DBGLOG(SCN, EVENT, "hidden ssid, %pM channel %d\n", prWlanBeaconFrame->aucBSSID, ++ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); ++ /* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */ ++ prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter, ++ eBSSType, ++ (PUINT_8) prWlanBeaconFrame->aucBSSID, ++ (PUINT_8) prWlanBeaconFrame->aucSrcAddr, ++ fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL); ++ ++ if (prBssDesc == (P_BSS_DESC_T) NULL) { ++ fgIsNewBssDesc = TRUE; ++ ++ do { ++ /* 4 <1.2.1> First trial of allocation */ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (prBssDesc) ++ break; ++ /* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */ ++ scanRemoveBssDescsByPolicy(prAdapter, ++ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN)); ++ ++ /* 4 <1.2.3> Second tail of allocation */ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (prBssDesc) ++ break; ++ /* 4 <1.2.4> Remove the weakest one */ ++ /* If there are more than half of BSS which has the same ssid as connection ++ * setting, remove the weakest one from them. ++ * Else remove the weakest one. ++ */ ++ scanRemoveBssDescsByPolicy(prAdapter, ++ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST)); ++ ++ /* 4 <1.2.5> reallocation */ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (prBssDesc) ++ break; ++ /* 4 <1.2.6> no space, should not happen */ ++ DBGLOG(SCN, ERROR, "no bss desc available after remove policy\n"); ++ return NULL; ++ ++ } while (FALSE); ++ ++ } else { ++ OS_SYSTIME rCurrentTime; ++ ++ /* WCXRP00000091 */ ++ /* if the received strength is much weaker than the original one, */ ++ /* ignore it due to it might be received on the folding frequency */ ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ if (prBssDesc->eBSSType != eBSSType) { ++ prBssDesc->eBSSType = eBSSType; ++ } else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum && ++ prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) { ++ /* for signal strength is too much weaker and previous beacon is not stale */ ++ if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD && ++ (rCurrentTime - prBssDesc->rUpdateTime) <= REPLICATED_BEACON_FRESH_PERIOD) { ++ DBGLOG(SCN, EVENT, "rssi is too much weaker and previous one is fresh\n"); ++ return prBssDesc; ++ } ++ /* for received beacons too close in time domain */ ++ else if (rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) { ++ DBGLOG(SCN, EVENT, "receive beacon/probe reponses too close\n"); ++ return prBssDesc; ++ } ++ } ++ ++ /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */ ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) { ++ BOOLEAN fgIsConnected, fgIsConnecting; ++ ++ /* set flag for indicating this is a new BSS-DESC */ ++ fgIsNewBssDesc = TRUE; ++ ++ /* backup 2 flags for APs which reset timestamp unexpectedly */ ++ fgIsConnected = prBssDesc->fgIsConnected; ++ fgIsConnecting = prBssDesc->fgIsConnecting; ++ scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID); ++ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (!prBssDesc) ++ return NULL; ++ ++ /* restore */ ++ prBssDesc->fgIsConnected = fgIsConnected; ++ prBssDesc->fgIsConnecting = fgIsConnecting; ++ } ++ } ++#if 1 ++ ++ prBssDesc->u2RawLength = prSwRfb->u2PacketLen; ++ if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE) ++ prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE; ++ kalMemCopy(prBssDesc->aucRawBuf, prWlanBeaconFrame, prBssDesc->u2RawLength); ++#endif ++ ++ /* NOTE: Keep consistency of Scan Record during JOIN process */ ++ if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) { ++ DBGLOG(SCN, INFO, "we're connecting this BSS(%pM) now, don't update it\n", ++ prBssDesc->aucBSSID); ++ return prBssDesc; ++ } ++ /* 4 <2> Get information from Fixed Fields */ ++ prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */ ++ ++ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr); ++ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID); ++ ++ prBssDesc->u8TimeStamp.QuadPart = u8Timestamp; ++ ++ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval); ++ ++ prBssDesc->u2CapInfo = u2CapInfo; ++ ++ /* 4 <2.1> Retrieve IEs for later parsing */ ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); ++ ++ if (u2IELength > CFG_IE_BUFFER_SIZE) { ++ u2IELength = CFG_IE_BUFFER_SIZE; ++ prBssDesc->fgIsIEOverflow = TRUE; ++ } else { ++ prBssDesc->fgIsIEOverflow = FALSE; ++ } ++ prBssDesc->u2IELength = u2IELength; ++ ++ kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength); ++ ++ /* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */ ++ prBssDesc->fgIsERPPresent = FALSE; ++ prBssDesc->fgIsHTPresent = FALSE; ++ prBssDesc->eSco = CHNL_EXT_SCN; ++ prBssDesc->fgIEWAPI = FALSE; ++#if CFG_RSN_MIGRATION ++ prBssDesc->fgIERSN = FALSE; ++#endif ++#if CFG_PRIVACY_MIGRATION ++ prBssDesc->fgIEWPA = FALSE; ++#endif ++ ++ /* 4 <3.1> Full IE parsing on SW_RFB_T */ ++ pucIE = prWlanBeaconFrame->aucInfoElem; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */ ++ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { ++ BOOLEAN fgIsHiddenSSID = FALSE; ++ ++ ucSSIDChar = '\0'; ++ ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ ++ /* D-Link DWL-900AP+ */ ++ if (IE_LEN(pucIE) == 0) ++ fgIsHiddenSSID = TRUE; ++ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ ++ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && ++ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ ++ else { ++ for (i = 0; i < IE_LEN(pucIE); i++) ++ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; ++ ++ if (!ucSSIDChar) ++ fgIsHiddenSSID = TRUE; ++ } ++ ++ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ ++ if (!fgIsHiddenSSID) { ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, ++ SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); ++ } ++#if 0 ++ /* ++ After we connect to a hidden SSID, prBssDesc->aucSSID[] will ++ not be empty and prBssDesc->ucSSIDLen will not be 0, ++ so maybe we need to empty prBssDesc->aucSSID[] and set ++ prBssDesc->ucSSIDLen to 0 in prBssDesc to avoid that ++ UI still displays hidden SSID AP in scan list after ++ we disconnect the hidden SSID AP. ++ */ ++ else { ++ prBssDesc->aucSSID[0] = '\0'; ++ prBssDesc->ucSSIDLen = 0; ++ } ++#endif ++ ++ } ++ break; ++ ++ case ELEM_ID_SUP_RATES: ++ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. ++ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), ++ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" ++ */ ++ /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */ ++ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) ++ prIeSupportedRate = SUP_RATES_IE(pucIE); ++ break; ++ ++ case ELEM_ID_DS_PARAM_SET: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) ++ ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl; ++ break; ++ ++ case ELEM_ID_TIM: ++ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) ++ prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod; ++ break; ++ ++ case ELEM_ID_IBSS_PARAM_SET: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET) ++ prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow; ++ break; ++ ++#if 0 /* CFG_SUPPORT_802_11D */ ++ case ELEM_ID_COUNTRY_INFO: ++ prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE; ++ break; ++#endif ++ ++ case ELEM_ID_ERP_INFO: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) ++ prBssDesc->fgIsERPPresent = TRUE; ++ break; ++ ++ case ELEM_ID_EXTENDED_SUP_RATES: ++ if (!prIeExtSupportedRate) ++ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); ++ break; ++ ++#if CFG_RSN_MIGRATION ++ case ELEM_ID_RSN: ++ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) { ++ prBssDesc->fgIERSN = TRUE; ++ prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap; ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) ++ rsnCheckPmkidCache(prAdapter, prBssDesc); ++ } ++ break; ++#endif ++ ++ case ELEM_ID_HT_CAP: ++ prBssDesc->fgIsHTPresent = TRUE; ++ break; ++ ++ case ELEM_ID_HT_OP: ++ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) ++ break; ++ ++ if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) { ++ prBssDesc->eSco = (ENUM_CHNL_EXT_T) ++ (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO); ++ } ++ ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel; ++ ++ break; ++ ++#if CFG_SUPPORT_WAPI ++ case ELEM_ID_WAPI: ++ if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) ++ prBssDesc->fgIEWAPI = TRUE; ++ break; ++#endif ++ ++ case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */ ++#if CFG_PRIVACY_MIGRATION ++ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { ++ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && (u2SubTypeVersion == VERSION_WPA)) { ++ ++ if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) ++ prBssDesc->fgIEWPA = TRUE; ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) ++ prBssDesc->fgIsP2PPresent = TRUE; ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ break; ++ ++ /* no default */ ++ } ++ } ++ ++ /* 4 <3.2> Save information from IEs - SSID */ ++ /* Update Flag of Hidden SSID for used in SEARCH STATE. */ ++ ++ /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent ++ * all cases of hidden SSID. ++ * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with ++ * valid SSID. ++ */ ++ if (prBssDesc->ucSSIDLen == 0) ++ prBssDesc->fgIsHiddenSSID = TRUE; ++ else ++ prBssDesc->fgIsHiddenSSID = FALSE; ++ ++ /* 4 <3.3> Check rate information in related IEs. */ ++ if (prIeSupportedRate || prIeExtSupportedRate) { ++ rateGetRateSetFromIEs(prIeSupportedRate, ++ prIeExtSupportedRate, ++ &prBssDesc->u2OperationalRateSet, ++ &prBssDesc->u2BSSBasicRateSet, &prBssDesc->fgIsUnknownBssBasicRate); ++ } ++ /* 4 <4> Update information from HIF RX Header */ ++ { ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ++ ASSERT(prHifRxHdr); ++ ++ /* 4 <4.1> Get TSF comparison result */ ++ prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr); ++ ++ /* 4 <4.2> Get Band information */ ++ prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr); ++ ++ /* 4 <4.2> Get channel and RCPI information */ ++ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr); ++ ++ if (BAND_2G4 == prBssDesc->eBand) { ++ ++ /* Update RCPI if in right channel */ ++ if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) { ++ ++ /* Receive Beacon/ProbeResp frame from adjacent channel. */ ++ if ((ucIeDsChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ /* trust channel information brought by IE */ ++ prBssDesc->ucChannelNum = ucIeDsChannelNum; ++ } else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) { ++ /* Receive Beacon/ProbeResp frame from adjacent channel. */ ++ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ /* trust channel information brought by IE */ ++ prBssDesc->ucChannelNum = ucIeHtChannelNum; ++ } else { ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ ++ prBssDesc->ucChannelNum = ucHwChannelNum; ++ } ++ } ++ /* 5G Band */ ++ else { ++ if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) { ++ /* Receive Beacon/ProbeResp frame from adjacent channel. */ ++ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ /* trust channel information brought by IE */ ++ prBssDesc->ucChannelNum = ucIeHtChannelNum; ++ } else { ++ /* Always update RCPI */ ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ ++ prBssDesc->ucChannelNum = ucHwChannelNum; ++ } ++ } ++ } ++ ++ /* 4 <5> PHY type setting */ ++ prBssDesc->ucPhyTypeSet = 0; ++ ++ if (BAND_2G4 == prBssDesc->eBand) { ++ /* check if support 11n */ ++ if (prBssDesc->fgIsHTPresent) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; ++ ++ /* if not 11n only */ ++ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { ++ /* check if support 11g */ ++ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) || prBssDesc->fgIsERPPresent) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; ++ ++ /* if not 11g only */ ++ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) { ++ /* check if support 11b */ ++ if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; ++ } ++ } ++ } else { /* (BAND_5G == prBssDesc->eBande) */ ++ /* check if support 11n */ ++ if (prBssDesc->fgIsHTPresent) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; ++ ++ /* if not 11n only */ ++ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { ++ /* Support 11a definitely */ ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; ++ ++ ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)); ++ } ++ } ++ ++ /* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */ ++ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); ++ ++ return prBssDesc; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. ++* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; ++ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame; ++ PARAM_MAC_ADDRESS rMacAddr; ++ PARAM_SSID_T rSsid; ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; ++ PARAM_802_11_CONFIG_T rConfiguration; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ UINT_8 ucRateLen = 0; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prBssDesc->eBand == BAND_2G4) { ++ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) ++ || prBssDesc->fgIsERPPresent) { ++ eNetworkType = PARAM_NETWORK_TYPE_OFDM24; ++ } else { ++ eNetworkType = PARAM_NETWORK_TYPE_DS; ++ } ++ } else { ++ ASSERT(prBssDesc->eBand == BAND_5G); ++ eNetworkType = PARAM_NETWORK_TYPE_OFDM5; ++ } ++ ++ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) { ++ /* NOTE(Kevin): Not supported by WZC(TBD) */ ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; ++ COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID); ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ ++ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); ++ rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval; ++ rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow; ++ rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum); ++ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); ++ ++ rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen); ++ ++ /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0. ++ * from OID_802_11_BSSID_LIST ++ */ ++ for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++) ++ aucRatesEx[i] = 0; ++ ++ switch (prBssDesc->eBSSType) { ++ case BSS_TYPE_IBSS: ++ eOpMode = NET_TYPE_IBSS; ++ break; ++ ++ case BSS_TYPE_INFRASTRUCTURE: ++ case BSS_TYPE_P2P_DEVICE: ++ case BSS_TYPE_BOW_DEVICE: ++ default: ++ eOpMode = NET_TYPE_INFRA; ++ break; ++ } ++ ++ DBGLOG(SCN, TRACE, "ind %s %d\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ { ++ if (flgTdlsTestExtCapElm == TRUE) { ++ /* only for RALINK AP */ ++ UINT8 *pucElm = (UINT8 *) (prSwRfb->pvHeader + prSwRfb->u2PacketLen); ++ ++ kalMemCopy(pucElm - 9, aucTdlsTestExtCapElm, 7); ++ prSwRfb->u2PacketLen -= 2; ++/* prSwRfb->u2PacketLen += 7; */ ++ ++ DBGLOG(TDLS, INFO, ++ " %s: append ext cap element to %pM\n", ++ __func__, prBssDesc->aucBSSID); ++ } ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ if (prAdapter->rWifiVar.rScanInfo.fgNloScanning && ++ test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag)) { ++ UINT_8 i = 0; ++ P_BSS_DESC_T *pprPendBssDesc = &prScanInfo->rNloParam.aprPendingBssDescToInd[0]; ++ ++ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { ++ if (pprPendBssDesc[i]) ++ continue; ++ DBGLOG(SCN, INFO, ++ "indicate bss[%pM] before wiphy resume, need to indicate again after wiphy resume\n", ++ prBssDesc->aucBSSID); ++ pprPendBssDesc[i] = prBssDesc; ++ break; ++ } ++ } ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prSwRfb->pvHeader, ++ prSwRfb->u2PacketLen, prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ ++ nicAddScanResult(prAdapter, ++ rMacAddr, ++ &rSsid, ++ prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0, ++ RCPI_TO_dBm(prBssDesc->ucRCPI), ++ eNetworkType, ++ &rConfiguration, ++ eOpMode, ++ aucRatesEx, ++ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen, ++ (PUINT_8) ((ULONG) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN)); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of scanAddScanResult() */ ++ ++#if 1 ++ ++BOOLEAN scanCheckBssIsLegal(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) ++{ ++ BOOLEAN fgAddToScanResult = FALSE; ++ ENUM_BAND_T eBand = 0; ++ UINT_8 ucChannel = 0; ++ ++ ASSERT(prAdapter); ++ /* check the channel is in the legal doamin */ ++ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) { ++ /* check ucChannelNum/eBand for adjacement channel filtering */ ++ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE && ++ (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) { ++ fgAddToScanResult = FALSE; ++ } else { ++ fgAddToScanResult = TRUE; ++ } ++ } ++ return fgAddToScanResult; ++ ++} ++ ++VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc) ++{ ++ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; ++ P_LINK_T prBSSDescList = (P_LINK_T) NULL; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ RF_CHANNEL_INFO_T rChannelInfo; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ DBGLOG(SCN, TRACE, "scanReportBss2Cfg80211\n"); ++ ++ if (SpecificprBssDesc) { ++ { ++ /* check BSSID is legal channel */ ++ if (!scanCheckBssIsLegal(prAdapter, SpecificprBssDesc)) { ++ DBGLOG(SCN, TRACE, "Remove specific SSID[%s %d]\n", ++ SpecificprBssDesc->aucSSID, SpecificprBssDesc->ucChannelNum); ++ return; ++ } ++ ++ DBGLOG(SCN, TRACE, "Report Specific SSID[%s]\n", SpecificprBssDesc->aucSSID); ++ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) SpecificprBssDesc->aucRawBuf, ++ SpecificprBssDesc->u2RawLength, ++ SpecificprBssDesc->ucChannelNum, ++ RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); ++ } else { ++ ++ rChannelInfo.ucChannelNum = SpecificprBssDesc->ucChannelNum; ++ rChannelInfo.eBand = SpecificprBssDesc->eBand; ++ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) SpecificprBssDesc->aucRawBuf, ++ SpecificprBssDesc->u2RawLength, ++ &rChannelInfo, RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); ++ ++ } ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ SpecificprBssDesc->fgIsP2PReport = FALSE; ++#endif ++ } ++ } else { ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ /* 4 Auto Channel Selection:Record the AP Number */ ++ P_PARAM_CHN_LOAD_INFO prChnLoad; ++ UINT_8 ucIdx = 0; ++ ++ if (((prBssDesc->ucChannelNum > 0) && (prBssDesc->ucChannelNum <= 48)) ++ || (prBssDesc->ucChannelNum >= 147) /*non-DFS Channel */) { ++ if (prBssDesc->ucChannelNum <= HW_CHNL_NUM_MAX_2G4) { ++ ucIdx = prBssDesc->ucChannelNum - 1; ++ } else if (prBssDesc->ucChannelNum <= 48) { ++ ucIdx = (UINT_8) (HW_CHNL_NUM_MAX_2G4 + (prBssDesc->ucChannelNum - 34) / 4); ++ } else { ++ ucIdx = ++ (UINT_8) (HW_CHNL_NUM_MAX_2G4 + 4 + (prBssDesc->ucChannelNum - 149) / 4); ++ } ++ ++ if (ucIdx < MAX_AUTO_CHAL_NUM) { ++ prChnLoad = (P_PARAM_CHN_LOAD_INFO) & ++ (prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]); ++ prChnLoad->ucChannel = prBssDesc->ucChannelNum; ++ prChnLoad->u2APNum++; ++ } else { ++ DBGLOG(SCN, WARN, "ACS: ChIdx > MAX_AUTO_CHAL_NUM\n"); ++ } ++ ++ } ++#endif ++ /* check BSSID is legal channel */ ++ if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) { ++ DBGLOG(SCN, TRACE, "Remove SSID[%s %d]\n", ++ prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++ continue; ++ } ++ ++ if ((prBssDesc->eBSSType == eBSSType) ++#if CFG_ENABLE_WIFI_DIRECT ++ || ((eBSSType == BSS_TYPE_P2P_DEVICE) && (prBssDesc->fgIsP2PReport == TRUE)) ++#endif ++ ) { ++ ++ DBGLOG(SCN, TRACE, "Report ALL SSID[%s %d]\n", ++ prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ if (prBssDesc->u2RawLength != 0) { ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBssDesc->aucRawBuf, ++ prBssDesc->u2RawLength, ++ prBssDesc->ucChannelNum, ++ RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); ++ prBssDesc->u2RawLength = 0; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ prBssDesc->fgIsP2PReport = FALSE; ++#endif ++ } ++ } else { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prBssDesc->fgIsP2PReport == TRUE) { ++#endif ++ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; ++ rChannelInfo.eBand = prBssDesc->eBand; ++ ++ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBssDesc->aucRawBuf, ++ prBssDesc->u2RawLength, ++ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ ++ /* do not clear it then we can pass the bss in Specific report */ ++ /* kalMemZero(prBssDesc->aucRawBuf,CFG_RAW_BUFFER_SIZE); */ ++ ++ /* ++ the BSS entry will not be cleared after scan done. ++ So if we dont receive the BSS in next scan, we cannot ++ pass it. We use u2RawLength for the purpose. ++ */ ++ /* prBssDesc->u2RawLength=0; */ ++#if CFG_ENABLE_WIFI_DIRECT ++ prBssDesc->fgIsP2PReport = FALSE; ++ } ++#endif ++ } ++ } ++ ++ } ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = TRUE; ++#endif ++ ++ } ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse the content of given Beacon or ProbeResp Frame. ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host ++* @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_BSS_INFO_T prAisBssInfo; ++ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++#if CFG_SLT_SUPPORT ++ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ /* 4 <0> Ignore invalid Beacon Frame */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < ++ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) { ++ /* to debug beacon length too small issue */ ++ UINT_32 u4MailBox0; ++ ++ nicGetMailbox(prAdapter, 0, &u4MailBox0); ++ DBGLOG(SCN, WARN, "if conn sys also get less length (0x5a means yes) %x\n", (UINT_32) u4MailBox0); ++ DBGLOG(SCN, WARN, "u2PacketLen %d, u2HeaderLen %d, payloadLen %d\n", ++ prSwRfb->u2PacketLen, prSwRfb->u2HeaderLen, ++ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); ++ /* dumpMemory8(prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ ++ ++#ifndef _lint ++ ASSERT(0); ++#endif /* _lint */ ++ return rStatus; ++ } ++#if CFG_SLT_SUPPORT ++ prSltInfo = &prAdapter->rWifiVar.rSltInfo; ++ ++ if (prSltInfo->fgIsDUT) { ++ DBGLOG(SCN, INFO, "\n\rBCN: RX\n"); ++ prSltInfo->u4BeaconReceiveCnt++; ++ return WLAN_STATUS_SUCCESS; ++ } else { ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; ++ ++ /*ALPS01475157: don't show SSID on scan list for multicast MAC AP */ ++ if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr)) { ++ DBGLOG(SCN, WARN, "received beacon/probe response from multicast AP\n"); ++ return rStatus; ++ } ++ ++ /* 4 <1> Parse and add into BSS_DESC_T */ ++ prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb); ++ ++ if (prBssDesc) { ++ /* 4 <1.1> Beacon Change Detection for Connected BSS */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED && ++ ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) ++ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) && ++ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && ++ EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, ++ prAisBssInfo->ucSSIDLen)) { ++ BOOLEAN fgNeedDisconnect = FALSE; ++ ++#if CFG_SUPPORT_BEACON_CHANGE_DETECTION ++ /* <1.1.2> check if supported rate differs */ ++ if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) ++ fgNeedDisconnect = TRUE; ++#endif ++#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE ++ if ( ++#if CFG_SUPPORT_WAPI ++ (prAdapter->rWifiVar.rConnSettings.fgWapiMode == TRUE && ++ !wapiPerformPolicySelection(prAdapter, prBssDesc)) || ++#endif ++ rsnCheckSecurityModeChanged(prAdapter, prAisBssInfo, prBssDesc)) { ++ DBGLOG(SCN, INFO, "Beacon security mode change detected\n"); ++ fgNeedDisconnect = FALSE; ++ aisBssSecurityChanged(prAdapter); ++ } ++#endif ++ ++ /* <1.1.3> beacon content change detected, disconnect immediately */ ++ if (fgNeedDisconnect == TRUE) ++ aisBssBeaconTimeout(prAdapter); ++ } ++ /* 4 <1.1> Update AIS_BSS_INFO */ ++ if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) ++ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) { ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* *not* checking prBssDesc->fgIsConnected anymore, ++ * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */ ++ if ((!prAisBssInfo->ucDTIMPeriod) && ++ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && ++ (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && ++ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { ++ ++ prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; ++ ++ /* sync with firmware for beacon information */ ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ } ++ } ++#if CFG_SUPPORT_ADHOC ++ if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, ++ prConnSettings->ucSSIDLen) && ++ (prBssDesc->eBSSType == BSS_TYPE_IBSS) && (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) { ++ ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, ++ prSwRfb->prHifRxHdr->ucRcpi); ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ } ++ ++ rlmProcessBcn(prAdapter, ++ prSwRfb, ++ ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem, ++ (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]))); ++ ++ /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */ ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE || prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ /* for AIS, send to host */ ++ if (prConnSettings->fgIsScanReqIssued || prAdapter->rWifiVar.rScanInfo.fgNloScanning) { ++ BOOLEAN fgAddToScanResult; ++ ++ fgAddToScanResult = scanCheckBssIsLegal(prAdapter, prBssDesc); ++ ++ if (fgAddToScanResult == TRUE) ++ rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb); ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, &rStatus, prBssDesc, prWlanBeaconFrame); ++#endif ++ } ++ ++ return rStatus; ++ ++} /* end of scanProcessBeaconAndProbeResp() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or ++* MERGE(AdHoc) according to current Connection Policy. ++* ++* \return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ P_SCAN_INFO_T prScanInfo; ++ ++ P_LINK_T prBSSDescList; ++ ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL; ++ ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_STA_RECORD_T prPrimaryStaRec; ++ P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL; ++ ++ OS_SYSTIME rCurrentTime; ++ ++ /* The first one reach the check point will be our candidate */ ++ BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE; ++ ++ BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE; ++ BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE; ++ /* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */ ++ ++ /* TODO(Kevin): Support Min Channel Load */ ++ /* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */ ++ ++ BOOLEAN fgIsFixedChannel; ++ ENUM_BAND_T eBand = 0; ++ UINT_8 ucChannel = 0; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ /* check for fixed channel operation */ ++ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++#if CFG_P2P_LEGACY_COEX_REVISE ++ fgIsFixedChannel = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel); ++#else ++ fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); ++#endif ++ } else { ++ fgIsFixedChannel = FALSE; ++ } ++ ++#if DBG ++ if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) ++ prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0'; ++#endif ++ ++ DBGLOG(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, %pM Band=%d, channel=%d\n", ++ (UINT_32) prBSSDescList->u4NumElem, prConnSettings->aucSSID, ++ (prConnSettings->aucBSSID), eBand, ucChannel); ++ ++ /* 4 <1> The outer loop to search for a candidate. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ /* TODO(Kevin): Update Minimum Channel Load Information here */ ++ ++ DBGLOG(SCN, TRACE, "SEARCH: [ %pM ], SSID:%s\n", ++ prBssDesc->aucBSSID, prBssDesc->aucSSID); ++ ++ /* 4 <2> Check PHY Type and attributes */ ++ /* 4 <2.1> Check Unsupported BSS PHY Type */ ++ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { ++ DBGLOG(SCN, TRACE, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", prBssDesc->ucPhyTypeSet); ++ continue; ++ } ++ /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */ ++ if (prBssDesc->fgIsUnknownBssBasicRate) ++ continue; ++ /* 4 <2.3> Check if fixed operation cases should be aware */ ++ if (fgIsFixedChannel == TRUE && (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) ++ continue; ++ /* 4 <2.4> Check if the channel is legal under regulatory domain */ ++ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) ++ continue; ++ /* 4 <2.5> Check if this BSS_DESC_T is stale */ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { ++ ++ BOOLEAN fgIsNeedToCheckTimeout = TRUE; ++ ++#if CFG_SUPPORT_ROAMING ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ if ((prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) || ++ (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) { ++ if (++prRoamingFsmInfo->RoamingEntryTimeoutSkipCount < ++ ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX) { ++ fgIsNeedToCheckTimeout = FALSE; ++ DBGLOG(SCN, INFO, "SEARCH: Romaing skip SCN_BSS_DESC_REMOVE_TIMEOUT_SEC\n"); ++ } ++ } ++#endif ++ ++ if (fgIsNeedToCheckTimeout == TRUE) { ++ DBGLOG(SCN, TRACE, "Ignore stale bss %pM\n", prBssDesc->aucBSSID); ++ continue; ++ } ++ } ++ /* 4 <3> Check if reach the excessive join retry limit */ ++ /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); ++ ++ if (prStaRec) { ++ /* NOTE(Kevin): ++ * The Status Code is the result of a Previous Connection Request, ++ * we use this as SCORE for choosing a proper ++ * candidate (Also used for compare see <6>) ++ * The Reason Code is an indication of the reason why AP reject us, ++ * we use this Code for "Reject" ++ * a SCAN result to become our candidate(Like a blacklist). ++ */ ++#if 0 /* TODO(Kevin): */ ++ if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) { ++ DBGLOG(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n", ++ prStaRec->u2ReasonCode); ++ continue; ++ } else ++#endif ++ if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ /* NOTE(Kevin): greedy association - after timeout, we'll still ++ * try to associate to the AP whose STATUS of conection attempt ++ * was not success. ++ * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for ++ * time bound. ++ */ ++ if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) || ++ (CHECK_FOR_TIMEOUT(rCurrentTime, ++ prStaRec->rLastJoinTime, ++ SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) { ++ ++ /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry ++ * JOIN_MAX_RETRY_FAILURE_COUNT times. ++ */ ++ if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) ++ prStaRec->ucJoinFailureCount = 0; ++ DBGLOG(SCN, INFO, ++ "SEARCH: Try to join BSS again,Status Code=%d (Curr=%u/Last Join=%u)\n", ++ prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime); ++ } else { ++ DBGLOG(SCN, INFO, ++ "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n", ++ JOIN_MAX_RETRY_FAILURE_COUNT); ++ continue; ++ } ++ ++ } ++ } ++ /* 4 <4> Check for various NETWORK conditions */ ++ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ ++ /* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */ ++ /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */ ++ if (((prConnSettings->eOPMode == NET_TYPE_INFRA) && ++ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) ++#if CFG_SUPPORT_ADHOC ++ || ((prConnSettings->eOPMode == NET_TYPE_IBSS ++ || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) ++ && (prBssDesc->eBSSType != BSS_TYPE_IBSS)) ++#endif ++ ) { ++ ++ DBGLOG(SCN, TRACE, "Cur OPMode %d, Ignore eBSSType = %d\n", ++ prConnSettings->eOPMode, prBssDesc->eBSSType); ++ continue; ++ } ++ /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */ ++ if ((prConnSettings->fgIsConnByBssidIssued) && ++ (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) { ++ ++ if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) { ++ ++ DBGLOG(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n"); ++ continue; ++ } ++ } ++#if CFG_SUPPORT_ADHOC ++ /* 4 <4.3> Check for AdHoc Mode */ ++ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ OS_SYSTIME rCurrentTime; ++ ++ /* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */ ++ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it ++ * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one. ++ * For BSS, if the old record was matched, however it won't be able to pass ++ * the Join Process later. ++ */ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) { ++ DBGLOG(SCN, LOUD, ++ "SEARCH: Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", ++ prBssDesc->aucBSSID); ++ continue; ++ } ++ /* 4 <4.3.2> Check Peer's capability */ ++ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { ++ ++ if (prPrimaryBssDesc) ++ DBGLOG(SCN, INFO, ++ "SEARCH: BSS DESC MAC: %pM, not supported AdHoc Mode.\n", ++ prPrimaryBssDesc->aucBSSID); ++ ++ continue; ++ } ++ /* 4 <4.3.3> Compare TSF */ ++ if (prBssInfo->fgIsBeaconActivated && ++ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) { ++ ++ DBGLOG(SCN, LOUD, ++ "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", prBssDesc->fgIsLargerTSF); ++ ++ if (!prBssDesc->fgIsLargerTSF) { ++ DBGLOG(SCN, INFO, ++ "SEARCH: Ignore BSS DESC MAC: [ %pM ], Smaller TSF\n", ++ prBssDesc->aucBSSID); ++ continue; ++ } ++ } ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ } ++#if 0 /* TODO(Kevin): For IBSS */ ++ /* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */ ++ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it ++ * create the IBSS, so we need to make sure we get the new one. ++ * For BSS, if the old record was matched, however it won't be able to pass ++ * the Join Process later. ++ */ ++ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { ++ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", ++ prBssDesc->aucBSSID); ++ continue; ++ } ++ } ++ ++ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) && ++ (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) { ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { ++ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", ++ (prBssDesc->aucBSSID)); ++ continue; ++ } ++ } ++ /* 4 <4B> Check for IBSS AdHoc Mode. */ ++ /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */ ++ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ /* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */ ++ if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) { ++ ++ DBGLOG(SCAN, TRACE, ++ "Ignore BSS DESC MAC: %pM, Capability not supported for AdHoc Mode.\n", ++ prPrimaryBssDesc->aucBSSID); ++ ++ continue; ++ } ++ /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */ ++ if (prAdapter->fgIsIBSSActive && ++ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) { ++ ++ if (!fgIsLocalTSFRead) { ++ NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf); ++ ++ DBGLOG(SCAN, TRACE, ++ "\n\nCurrent TSF : %08lx-%08lx\n\n", ++ rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart); ++ } ++ ++ if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) { ++ DBGLOG(SCAN, TRACE, ++ "Ignore BSS DESC MAC: [%pM], Current BSSID: [%pM].\n", ++ prPrimaryBssDesc->aucBSSID, prBssInfo->aucBSSID); ++ ++ DBGLOG(SCAN, TRACE, ++ "\n\nBSS's TSF : %08lx-%08lx\n\n", ++ prPrimaryBssDesc->u8TimeStamp.u.HighPart, ++ prPrimaryBssDesc->u8TimeStamp.u.LowPart); ++ ++ prPrimaryBssDesc->fgIsLargerTSF = FALSE; ++ continue; ++ } else { ++ prPrimaryBssDesc->fgIsLargerTSF = TRUE; ++ } ++ ++ } ++ } ++ /* 4 <5> Check the Encryption Status. */ ++ if (rsnPerformPolicySelection(prPrimaryBssDesc)) { ++ ++ if (prPrimaryBssDesc->ucEncLevel > 0) { ++ fgIsFindBestEncryptionLevel = TRUE; ++ ++ fgIsFindFirst = FALSE; ++ } ++ } else { ++ /* Can't pass the Encryption Status Check, get next one */ ++ continue; ++ } ++ ++ /* For RSN Pre-authentication, update the PMKID canidate list for ++ same SSID and encrypt status */ ++ /* Update PMKID candicate list. */ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { ++ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); ++ if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) ++ prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate(); ++ } ++#endif ++ ++ prPrimaryBssDesc = (P_BSS_DESC_T) NULL; ++ ++ /* 4 <6> Check current Connection Policy. */ ++ switch (prConnSettings->eConnectionPolicy) { ++ case CONNECT_BY_SSID_BEST_RSSI: ++ /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */ ++ if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) { ++ /* NOTE(Kevin): following if () statement means that ++ * If Target is hidden, then we won't connect when user specify SSID_ANY policy. ++ */ ++ if (prConnSettings->ucSSIDLen) { ++ prPrimaryBssDesc = prBssDesc; ++ fgIsFindBestRSSI = TRUE; ++ } ++ ++ } else if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { ++ prPrimaryBssDesc = prBssDesc; ++ fgIsFindBestRSSI = TRUE; ++ ++ DBGLOG(SCN, TRACE, "SEARCH: fgIsFindBestRSSI=TRUE, %d, prPrimaryBssDesc=[ %pM ]\n", ++ prBssDesc->ucRCPI, prPrimaryBssDesc->aucBSSID); ++ } ++ break; ++ ++ case CONNECT_BY_SSID_ANY: ++ /* NOTE(Kevin): In this policy, we don't know the desired ++ * SSID from user, so we should exclude the Hidden SSID from scan list. ++ * And because we refuse to connect to Hidden SSID node at the beginning, so ++ * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE, ++ * then the Connection Settings must be valid without doubt. ++ */ ++ if (!prBssDesc->fgIsHiddenSSID) { ++ prPrimaryBssDesc = prBssDesc; ++ fgIsFindFirst = TRUE; ++ } ++ break; ++ ++ case CONNECT_BY_BSSID: ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) ++ prPrimaryBssDesc = prBssDesc; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Primary Candidate was not found */ ++ if (prPrimaryBssDesc == NULL) ++ continue; ++ /* 4 <7> Check the Encryption Status. */ ++ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++#if CFG_SUPPORT_WAPI ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { ++ DBGLOG(SCN, TRACE, "SEARCH: fgWapiMode == 1\n"); ++ ++ if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { ++ fgIsFindFirst = TRUE; ++ } else { ++ /* Can't pass the Encryption Status Check, get next one */ ++ DBGLOG(SCN, TRACE, "SEARCH: WAPI cannot pass the Encryption Status Check!\n"); ++ continue; ++ } ++ } else ++#endif ++#if CFG_RSN_MIGRATION ++ if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { ++ if (prAisSpecBssInfo->fgCounterMeasure) { ++ DBGLOG(RSN, INFO, "Skip while at counter measure period!!!\n"); ++ continue; ++ } ++ ++ if (prPrimaryBssDesc->ucEncLevel > 0) { ++ fgIsFindBestEncryptionLevel = TRUE; ++ fgIsFindFirst = FALSE; ++ } ++#if 0 ++ /* Update PMKID candicate list. */ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { ++ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); ++ if (prAisSpecBssInfo->u4PmkidCandicateCount) { ++ if (rsnCheckPmkidCandicate()) { ++ DBGLOG(RSN, WARN, ++ "Prepare a timer to indicate candidate %pM\n", ++ (prAisSpecBssInfo->arPmkidCache ++ [prAisSpecBssInfo->u4PmkidCacheCount]. ++ rBssidInfo.aucBssid))); ++ cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer); ++ cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer, ++ SEC_TO_MSEC ++ (WAIT_TIME_IND_PMKID_CANDICATE_SEC)); ++ } ++ } ++ } ++#endif ++ } else { ++ /* Can't pass the Encryption Status Check, get next one */ ++ continue; ++ } ++#endif ++ } else { ++ /* Todo:: P2P and BOW Policy Selection */ ++ } ++ ++ prPrimaryStaRec = prStaRec; ++ ++ /* 4 <8> Compare the Candidate and the Primary Scan Record. */ ++ if (!prCandidateBssDesc) { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ ++ /* 4 <8.1> Condition - Get the first matched one. */ ++ if (fgIsFindFirst) ++ break; ++ } else { ++#if 0 /* TODO(Kevin): For security(TBD) */ ++ /* 4 <6B> Condition - Choose the one with best Encryption Score. */ ++ if (fgIsFindBestEncryptionLevel) { ++ if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) { ++ ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++ ++ /* If reach here, that means they have the same Encryption Score. ++ */ ++ ++ /* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */ ++ /* For roaming, only compare the candidates other than current associated BSSID. */ ++ if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) { ++ if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) && ++ (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { ++ ++ DBGLOG(SCAN, TRACE, ++ "So far -BSS DESC MAC: %pM has nonzero Status Code = %d\n", ++ prCandidateBssDesc->aucBSSID, ++ prCandidateStaRec->u2StatusCode); ++ ++ if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) { ++ if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ ++ /* Give opportunity to the one with smaller rLastJoinTime */ ++ if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime, ++ prPrimaryStaRec->rLastJoinTime)) { ++ continue; ++ } ++ /* We've connect to CANDIDATE recently, ++ * let us try PRIMARY now */ ++ else { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++ /* PRIMARY's u2StatusCode = 0 */ ++ else { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++ /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */ ++ else { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else { ++ if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) && ++ (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { ++ continue; ++ } ++ } ++ } ++#endif ++ ++ /* 4 <6D> Condition - Visible SSID win Hidden SSID. */ ++ if (prCandidateBssDesc->fgIsHiddenSSID) { ++ if (!prPrimaryBssDesc->fgIsHiddenSSID) { ++ prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */ ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else { ++ if (prPrimaryBssDesc->fgIsHiddenSSID) ++ continue; ++ } ++ ++ /* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */ ++ if (fgIsFindBestRSSI) { ++ /* TODO(Kevin): We shouldn't compare the actual value, we should ++ * allow some acceptable tolerance of some RSSI percentage here. ++ */ ++ DBGLOG(SCN, TRACE, ++ "Candidate [%pM]: RCPI = %d, joinFailCnt=%d, Primary [%pM]: RCPI = %d, joinFailCnt=%d\n", ++ prCandidateBssDesc->aucBSSID, ++ prCandidateBssDesc->ucRCPI, prCandidateBssDesc->ucJoinFailureCount, ++ prPrimaryBssDesc->aucBSSID, ++ prPrimaryBssDesc->ucRCPI, prPrimaryBssDesc->ucJoinFailureCount); ++ ++ ASSERT(!(prCandidateBssDesc->fgIsConnected && prPrimaryBssDesc->fgIsConnected)); ++ if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { ++ /* give a chance to do join if join fail before ++ * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC seconds ++ */ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rJoinFailTime, ++ SEC_TO_SYSTIME(SCN_BSS_JOIN_FAIL_CNT_RESET_SEC))) { ++ prBssDesc->ucJoinFailureCount = SCN_BSS_JOIN_FAIL_THRESOLD - ++ SCN_BSS_JOIN_FAIL_RESET_STEP; ++ DBGLOG(SCN, INFO, ++ "decrease join fail count for Bss %pM to %u, timeout second %d\n", ++ prBssDesc->aucBSSID, prBssDesc->ucJoinFailureCount, ++ SCN_BSS_JOIN_FAIL_CNT_RESET_SEC); ++ } ++ } ++ ++ /* NOTE: To prevent SWING, ++ * we do roaming only if target AP has at least 5dBm larger than us. */ ++ if (prCandidateBssDesc->fgIsConnected) { ++ if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= ++ prPrimaryBssDesc->ucRCPI && ++ prPrimaryBssDesc->ucJoinFailureCount < SCN_BSS_JOIN_FAIL_THRESOLD) { ++ ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else if (prPrimaryBssDesc->fgIsConnected) { ++ if (prCandidateBssDesc->ucRCPI < ++ (prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) || ++ (prCandidateBssDesc->ucJoinFailureCount >= ++ SCN_BSS_JOIN_FAIL_THRESOLD)) { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) ++ continue; ++ else if (prCandidateBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD || ++ prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++#if 0 ++ /* If reach here, that means they have the same Encryption Score, and ++ * both RSSI value are close too. ++ */ ++ /* 4 <6F> Seek the minimum Channel Load for less interference. */ ++ if (fgIsFindMinChannelLoad) { ++ /* Do nothing */ ++ /* TODO(Kevin): Check which one has minimum channel load in its channel */ ++ } ++#endif ++ } ++ } ++ ++ ++ if (prCandidateBssDesc != NULL) { ++ DBGLOG(SCN, INFO, ++ "SEARCH: Candidate BSS: %pM\n", prCandidateBssDesc->aucBSSID); ++ } ++ ++ return prCandidateBssDesc; ++ ++} /* end of scanSearchBssDescByPolicy() */ ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter) ++{ ++ P_LINK_T prBSSDescList = &prAdapter->rWifiVar.rScanInfo.rBSSDescList; ++ P_BSS_DESC_T prBssDesc = NULL; ++ P_AGPS_AP_LIST_T prAgpsApList; ++ P_AGPS_AP_INFO_T prAgpsInfo; ++ P_SCAN_INFO_T prScanInfo = &prAdapter->rWifiVar.rScanInfo; ++ UINT_8 ucIndex = 0; ++ ++ prAgpsApList = kalMemAlloc(sizeof(AGPS_AP_LIST_T), VIR_MEM_TYPE); ++ if (!prAgpsApList) ++ return; ++ ++ prAgpsInfo = &prAgpsApList->arApInfo[0]; ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime) ++ continue; ++ COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID); ++ prAgpsInfo->ePhyType = AGPS_PHY_G; ++ prAgpsInfo->u2Channel = prBssDesc->ucChannelNum; ++ prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); ++ prAgpsInfo++; ++ ucIndex++; ++ if (ucIndex == 32) ++ break; ++ } ++ prAgpsApList->ucNum = ucIndex; ++ GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime); ++ /* DBGLOG(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */ ++ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, (PUINT_8) prAgpsApList, sizeof(AGPS_AP_LIST_T)); ++ kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(AGPS_AP_LIST_T)); ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c +new file mode 100644 +index 000000000000..fac9f94428dd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c +@@ -0,0 +1,2136 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#1 ++*/ ++ ++/*! \file "scan_fsm.c" ++ \brief This file defines the state transition function for SCAN FSM. ++ ++ The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN ++ behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 . ++*/ ++ ++/* ++** Log: scan_fsm.c ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 14 2011 yuche.tsai ++ * [WCXRP00001095] [Volunteer Patch][Driver] Always Scan before enable Hot-Spot. ++ * Fix bug when unregister P2P network.. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search ++ * for more than one SSID in a single scanning request ++ * free mailbox message afte parsing is completed. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search ++ * for more than one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support ++ * as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning ++ * surpress klock warning with code path rewritten ++ * ++ * 03 18 2011 cm.chang ++ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command ++ * As CR title ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame ++ * during search phase do not contain P2P wildcard SSID. ++ * Take P2P wildcard SSID into consideration. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Fix scan channel extension issue when p2p module is not registered. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Fix bug for processing queued scan request. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add a function for returning channel. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Update SCAN FSM for support P2P Device discovery scan. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add option of channel extension while cancelling scan request. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 20 2010 cp.wu ++ * ++ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * due to FW/DRV won't be sync. precisely, some strict assertions should be eased. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * SCN module is now able to handle multiple concurrent scanning requests ++ * ++ * 07 16 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * bugfix for SCN migration ++ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue ++ * 2) before AIS issues scan request, network(BSS) needs to be activated first ++ * 3) only invoke COPY_SSID when using specified SSID for scan ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * driver no longer generates probe request frames ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * pass band with channel number information as scan parameter ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * remove timer in DRV-SCN. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * when returning to SCAN_IDLE state, send a correct message to source FSM. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RLM APIs by CFG_RLM_MIGRATION. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine the order of Stop TX Queue and Switch Channel ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update pause/resume/flush API to new Bitmap API ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Ignore the PROBE_DELAY state if the value of Probe Delay == 0 ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add set RX Filter to receive BCN from different BSSID during SCAN ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Nov 25 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove flag of CFG_TEST_MGMT_FSM ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Change parameter of scanSendProbeReqFrames() ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update scnFsmSteps() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("SCAN_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("SCAN_STATE_SCANNING"), ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++#define CURRENT_PSCN_VERSION 1 ++#define RSSI_MARGIN_DEFAULT 5 ++#define MAX_PERIOD 200000 ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ P_MSG_HDR_T prMsgHdr; ++ ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ do { ++ ++#if DBG ++ DBGLOG(SCN, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState]); ++#else ++ DBGLOG(SCN, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_SCN_IDX, prScanInfo->eCurrentState, eNextState); ++#endif ++ ++ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ ++ prScanInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ ++ switch (prScanInfo->eCurrentState) { ++ case SCAN_STATE_IDLE: ++ /* check for pending scanning requests */ ++ if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { ++ /* load next message from pending list as scan parameters */ ++ LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T); ++ ++ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { ++ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); ++ } else { ++ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); ++ } ++ ++ /* switch to next state */ ++ eNextState = SCAN_STATE_SCANNING; ++ fgIsTransition = TRUE; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ } ++ break; ++ ++ case SCAN_STATE_SCANNING: ++ if (prScanParam->fgIsScanV2 == FALSE) ++ scnSendScanReq(prAdapter); ++ else ++ scnSendScanReqV2(prAdapter); ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ ++ } ++ } while (fgIsTransition); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ_EXT_CH rCmdScanReq;*/ ++ P_CMD_SCAN_REQ_EXT_CH prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_EXT_CH), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) ++ return; ++ ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_EXT_CH)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ if (prScanParam->ucSSIDNum == 1) { ++ COPY_SSID(prCmdScanReq->aucSSID, ++ prCmdScanReq->ucSSIDLength, ++ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); ++ } ++ ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++ ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ_EXT_CH, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ else if (prCmdScanReq->ucSSIDLength > 32) ++ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_EXT_CH)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReq(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ rCmdScanReq;*/ ++ P_CMD_SCAN_REQ prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanParam->ucChannelListNum > 32) { ++ scnSendScanReqExtCh(prAdapter); ++ } else { ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) { ++ DBGLOG(SCN, INFO, "alloc CmdScanReq fail"); ++ return; ++ } ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ if (prScanParam->ucSSIDNum == 1) { ++ COPY_SSID(prCmdScanReq->aucSSID, ++ prCmdScanReq->ucSSIDLength, ++ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); ++ } ++ ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. ++ * (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++#if CFG_ENABLE_FAST_SCAN ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = CFG_FAST_SCAN_DWELL_TIME; ++#endif ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ else if (prCmdScanReq->ucSSIDLength > 32) ++ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ)); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ_V2 command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ_V2_EXT_CH rCmdScanReq;*/ ++ P_CMD_SCAN_REQ_V2_EXT_CH prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2_EXT_CH), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) ++ return; ++ ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ for (i = 0; i < prScanParam->ucSSIDNum; i++) { ++ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, ++ prCmdScanReq->arSSID[i].u4SsidLen, ++ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); ++ } ++ ++ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++ ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ_V2, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ_V2_EXT_CH, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ_V2 command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ_V2 rCmdScanReq;*/ ++ P_CMD_SCAN_REQ_V2 prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanParam->ucChannelListNum > 32) { ++ scnSendScanReqV2ExtCh(prAdapter); ++ } else { ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) { ++ DBGLOG(SCN, INFO, "alloc CmdScanReq v2 fail"); ++ return; ++ } ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ for (i = 0; i < prScanParam->ucSSIDNum; i++) { ++ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, ++ prCmdScanReq->arSSID[i].u4SsidLen, ++ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); ++ } ++ ++ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. ++ * (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ_V2, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2)); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ ++ ASSERT(prMsgHdr); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) { ++ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { ++ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); ++ } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 ++ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 ++ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 ++ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { ++ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); ++ } else { ++ /* should not deliver to this function */ ++ ASSERT(0); ++ } ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ scnFsmSteps(prAdapter, SCAN_STATE_SCANNING); ++ } else { ++ LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_CANCEL prScanCancel; ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ CMD_SCAN_CANCEL rCmdScanCancel; ++ ++ ASSERT(prMsgHdr); ++ ++ prScanCancel = (P_MSG_SCN_SCAN_CANCEL) prMsgHdr; ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { ++ if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum && ++ prScanCancel->ucNetTypeIndex == (UINT_8) prScanParam->eNetTypeIndex) { ++ /* send cancel message to firmware domain */ ++ rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt; ++ else ++ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; ++#endif ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_CANCEL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8) &rCmdScanCancel, NULL, 0); ++ ++ /* generate scan-done event for caller */ ++ scnFsmGenerateScanDoneMsg(prAdapter, ++ prScanParam->ucSeqNum, ++ (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_CANCELLED); ++ ++ /* switch to next pending scan */ ++ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); ++ } else { ++ scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucNetTypeIndex); ++ } ++ } ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Scan Message Parsing (Legacy) ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prScanReqMsg); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prScanParam->eScanType = prScanReqMsg->eScanType; ++ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; ++ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; ++ if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) { ++ prScanParam->ucSSIDNum = 1; ++ ++ COPY_SSID(prScanParam->aucSpecifiedSSID[0], ++ prScanParam->ucSpecifiedSSIDLen[0], prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength); ++ ++ /* reset SSID length to zero for rest array entries */ ++ for (i = 1; i < SCN_SSID_MAX_NUM; i++) ++ prScanParam->ucSpecifiedSSIDLen[i] = 0; ++ } else { ++ prScanParam->ucSSIDNum = 0; ++ ++ for (i = 0; i < SCN_SSID_MAX_NUM; i++) ++ prScanParam->ucSpecifiedSSIDLen[i] = 0; ++ } ++ ++ prScanParam->u2ProbeDelayTime = 0; ++ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) ++ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; ++ else ++ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; ++ ++ kalMemCopy(prScanParam->arChnlInfoList, ++ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); ++ } ++ ++ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) ++ prScanParam->u2IELen = prScanReqMsg->u2IELen; ++ else ++ prScanParam->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; ++#endif ++ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; ++ ++ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) ++ prScanParam->fgIsObssScan = TRUE; ++ else ++ prScanParam->fgIsObssScan = FALSE; ++ ++ prScanParam->fgIsScanV2 = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Scan Message Parsing - V2 with multiple SSID support ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prScanReqMsg); ++ ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prScanParam->eScanType = prScanReqMsg->eScanType; ++ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; ++ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; ++ prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum; ++ ++ for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) { ++ COPY_SSID(prScanParam->aucSpecifiedSSID[i], ++ prScanParam->ucSpecifiedSSIDLen[i], ++ prScanReqMsg->prSsid[i].aucSsid, (UINT_8) prScanReqMsg->prSsid[i].u4SsidLen); ++ } ++ ++ prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay; ++ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) ++ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; ++ else ++ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; ++ ++ kalMemCopy(prScanParam->arChnlInfoList, ++ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); ++ } ++ ++ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) ++ prScanParam->u2IELen = prScanReqMsg->u2IELen; ++ else ++ prScanParam->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; ++#endif ++ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; ++ ++ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) ++ prScanParam->fgIsObssScan = TRUE; ++ else ++ prScanParam->fgIsObssScan = FALSE; ++ ++ prScanParam->fgIsScanV2 = TRUE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Remove pending scan request ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL; ++ P_LINK_ENTRY_T prRemoveLinkEntry = NULL; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ /* traverse through rPendingMsgList for removal */ ++ LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr, ++ prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), rLinkEntry, MSG_HDR_T) { ++ if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ ++ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ ++ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ ++ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { ++ P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) prPendingMsgHdr; ++ ++ if (ucSeqNum == prScanReqMsg->ucSeqNum && ucNetTypeIndex == prScanReqMsg->ucNetTypeIndex) { ++ prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry); ++ prRemoveMsgHdr = prPendingMsgHdr; ++ } ++ } else if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 ++ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 ++ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 ++ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { ++ P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2) prPendingMsgHdr; ++ ++ if (ucSeqNum == prScanReqMsgV2->ucSeqNum && ucNetTypeIndex == prScanReqMsgV2->ucNetTypeIndex) { ++ prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry); ++ prRemoveMsgHdr = prPendingMsgHdr; ++ } ++ } ++ ++ if (prRemoveLinkEntry) { ++ /* generate scan-done event for caller */ ++ scnFsmGenerateScanDoneMsg(prAdapter, ucSeqNum, ucNetTypeIndex, SCAN_STATUS_CANCELLED); ++ ++ /* remove from pending list */ ++ LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry); ++ cnmMemFree(prAdapter, prRemoveMsgHdr); ++ ++ break; ++ } ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ /* buffer empty channel information */ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_FULL || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) { ++ if (prScanDone->ucSparseChannelValid) { ++ prScanInfo->fgIsSparseChannelValid = TRUE; ++ prScanInfo->rSparseChannel.eBand = (ENUM_BAND_T) prScanDone->rSparseChannel.ucBand; ++ prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum; ++ } else { ++ prScanInfo->fgIsSparseChannelValid = FALSE; ++ } ++ } ++ ++ if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING && prScanDone->ucSeqNum == prScanParam->ucSeqNum) { ++ /* generate scan-done event for caller */ ++ scnFsmGenerateScanDoneMsg(prAdapter, ++ prScanParam->ucSeqNum, (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_DONE); ++ ++ /* switch to next pending scan */ ++ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); ++ } else { ++ DBGLOG(SCN, WARN, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", ++ prScanDone->ucSeqNum, prScanInfo->eCurrentState); ++ } ++ ++} /* end of scnEventScanDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ DBGLOG(SCN, INFO, "Rcv Scan Done, NetIdx %d, Obss %d, Status %d, Seq %d\n", ++ ucNetTypeIndex, prScanParam->fgIsObssScan, eScanStatus, ucSeqNum); ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE)); ++ if (!prScanDoneMsg) { ++ ASSERT(0); /* Can't indicate SCAN FSM Complete */ ++ return; ++ } ++ ++ if (prScanParam->fgIsObssScan == TRUE) { ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE; ++ } else { ++ switch ((ENUM_NETWORK_TYPE_INDEX_T) ucNetTypeIndex) { ++ case NETWORK_TYPE_AIS_INDEX: ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE; ++ break; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ case NETWORK_TYPE_P2P_INDEX: ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE; ++ break; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ case NETWORK_TYPE_BOW_INDEX: ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE; ++ break; ++#endif ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ } ++ ++ prScanDoneMsg->ucSeqNum = ucSeqNum; ++ prScanDoneMsg->ucNetTypeIndex = ucNetTypeIndex; ++ prScanDoneMsg->eScanStatus = eScanStatus; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanDoneMsg, MSG_SEND_METHOD_BUF); ++ ++} /* end of scnFsmGenerateScanDoneMsg() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Query for most sparse channel ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prScanInfo->fgIsSparseChannelValid == TRUE) { ++ if (prSparseBand) ++ *prSparseBand = prScanInfo->rSparseChannel.eBand; ++ ++ if (pucSparseChannel) ++ *pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum; ++ ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Event handler for NLO done event ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_NLO_PARAM_T prNloParam; ++ P_SCAN_PARAM_T prScanParam; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prNloParam = &prScanInfo->rNloParam; ++ prScanParam = &prNloParam->rScanParam; ++ ++ if (prScanInfo->fgNloScanning == TRUE) { ++ DBGLOG(SCN, INFO, "scnEventNloDone Current State = %d\n", prScanInfo->eCurrentState); ++ ++ kalSchedScanResults(prAdapter->prGlueInfo); ++ ++ if (prNloParam->fgStopAfterIndication == TRUE) ++ prScanInfo->fgNloScanning = FALSE; ++ ++ kalMemZero(&prNloParam->aprPendingBssDescToInd[0], ++ CFG_SCAN_SSID_MATCH_MAX_NUM * sizeof(P_BSS_DESC_T)); ++ } else { ++ DBGLOG(SCN, INFO, "Unexpected NLO-DONE event\n"); ++ } ++ ++} ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for starting scheduled scan ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSsidNum, ++ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_NLO_PARAM_T prNloParam; ++ P_SCAN_PARAM_T prScanParam; ++ P_CMD_NLO_REQ prCmdNloReq; ++ UINT_32 i, j; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prNloParam = &prScanInfo->rNloParam; ++ prScanParam = &prNloParam->rScanParam; ++ ++ if (prScanInfo->fgNloScanning) { ++ DBGLOG(SCN, INFO, "prScanInfo->fgNloScanning == TRUE already scanning\n"); ++ return TRUE; ++ } ++ ++ prScanInfo->fgNloScanning = TRUE; ++ ++ /* 1. load parameters */ ++ prScanParam->ucSeqNum++; ++ /* prScanParam->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex; */ ++ ++ prNloParam->fgStopAfterIndication = TRUE; ++ prNloParam->ucFastScanIteration = 0; ++ prNloParam->u2FastScanPeriod = u2Interval; ++ prNloParam->u2SlowScanPeriod = u2Interval; ++ ++ if (prScanParam->ucSSIDNum > CFG_SCAN_SSID_MAX_NUM) ++ prScanParam->ucSSIDNum = CFG_SCAN_SSID_MAX_NUM; ++ else ++ prScanParam->ucSSIDNum = ucSsidNum; ++ ++ if (prNloParam->ucMatchSSIDNum > CFG_SCAN_SSID_MATCH_MAX_NUM) ++ prNloParam->ucMatchSSIDNum = CFG_SCAN_SSID_MATCH_MAX_NUM; ++ else ++ prNloParam->ucMatchSSIDNum = ucSsidNum; ++ ++ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { ++ if (i < CFG_SCAN_SSID_MAX_NUM) { ++ COPY_SSID(prScanParam->aucSpecifiedSSID[i], ++ prScanParam->ucSpecifiedSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); ++ } ++ ++ COPY_SSID(prNloParam->aucMatchSSID[i], ++ prNloParam->ucMatchSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); ++ ++ prNloParam->aucCipherAlgo[i] = 0; ++ prNloParam->au2AuthAlgo[i] = 0; ++ ++ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) ++ prNloParam->aucChannelHint[i][j] = 0; ++ } ++ ++ /* 2. prepare command for sending */ ++ prCmdNloReq = (P_CMD_NLO_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_NLO_REQ) + prScanParam->u2IELen); ++ ++ if (!prCmdNloReq) { ++ ASSERT(0); /* Can't initiate NLO operation */ ++ return FALSE; ++ } ++ ++ /* 3. send command packet for NLO operation */ ++ kalMemZero(prCmdNloReq, sizeof(CMD_NLO_REQ)); ++ ++ prCmdNloReq->ucSeqNum = prScanParam->ucSeqNum; ++ /* prCmdNloReq->ucBssIndex = prScanParam->ucBssIndex; */ ++ ++ prCmdNloReq->ucNetworkType = prScanParam->eNetTypeIndex; ++ prCmdNloReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ ++ prCmdNloReq->fgStopAfterIndication = prNloParam->fgStopAfterIndication; ++ prCmdNloReq->ucFastScanIteration = prNloParam->ucFastScanIteration; ++ prCmdNloReq->u2FastScanPeriod = prNloParam->u2FastScanPeriod; ++ prCmdNloReq->u2SlowScanPeriod = prNloParam->u2SlowScanPeriod; ++ prCmdNloReq->ucEntryNum = prNloParam->ucMatchSSIDNum; ++ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { ++ COPY_SSID(prCmdNloReq->arNetworkList[i].aucSSID, ++ prCmdNloReq->arNetworkList[i].ucSSIDLength, ++ prNloParam->aucMatchSSID[i], prNloParam->ucMatchSSIDLen[i]); ++ ++ prCmdNloReq->arNetworkList[i].ucCipherAlgo = prNloParam->aucCipherAlgo[i]; ++ prCmdNloReq->arNetworkList[i].u2AuthAlgo = prNloParam->au2AuthAlgo[i]; ++ ++ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) ++ prCmdNloReq->arNetworkList[i].ucNumChannelHint[j] = prNloParam->aucChannelHint[i][j]; ++ } ++ ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdNloReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdNloReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdNloReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdNloReq->u2IELen); ++#if !CFG_SUPPORT_GSCN ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NLO_REQ, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_NLO_REQ) + prCmdNloReq->u2IELen, (PUINT_8) prCmdNloReq, NULL, 0); ++ ++#else ++ scnPSCNFsm(prAdapter, PSCN_RESET, prCmdNloReq, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE); ++#endif ++ cnmMemFree(prAdapter, (PVOID) prCmdNloReq); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for stopping scheduled scan ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_NLO_PARAM_T prNloParam; ++ P_SCAN_PARAM_T prScanParam; ++ CMD_NLO_CANCEL rCmdNloCancel; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prNloParam = &prScanInfo->rNloParam; ++ prScanParam = &prNloParam->rScanParam; ++ ++ /* send cancel message to firmware domain */ ++ rCmdNloCancel.ucSeqNum = prScanParam->ucSeqNum; ++ ++#if !CFG_SUPPORT_GSCN ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NLO_CANCEL, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetStopSchedScan, ++ nicOidCmdTimeoutCommon, sizeof(CMD_NLO_CANCEL), (PUINT_8)(&rCmdNloCancel), NULL, 0); ++#else ++ ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE); ++#endif ++ ++ prScanInfo->fgNloScanning = FALSE; ++ ++ return TRUE; ++} ++ ++#if CFG_SUPPORT_GSCN ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set PSCN action ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct) ++{ ++ CMD_SET_PSCAN_ENABLE rCmdPscnAction; ++ P_SCAN_INFO_T prScanInfo; ++ ++ DBGLOG(SCN, TRACE, "scnFsmPSCNAction Act = %d\n", ucPscanAct); ++ ++ rCmdPscnAction.ucPscanAct = ucPscanAct; ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (ucPscanAct == DISABLE) ++ prScanInfo->fgPscnOnnning = FALSE; ++ if (ucPscanAct == ENABLE) ++ prScanInfo->fgPscnOnnning = TRUE; ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_ENABLE, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_ENABLE), (PUINT_8) &rCmdPscnAction, NULL, 0); ++ ++ DBGLOG(SCN, INFO, "scnFsmPSCNAction Act = %d is Set to FW\n", ucPscanAct); ++ return TRUE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set PSCN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ UINT_8 i, j; ++ ++ i = 0; ++ j = 0; ++ ++ ASSERT(prAdapter); ++ /*prCmdPscnParam->u4BasePeriod = prCmdPscnParam->u4BasePeriod;*/ ++#if 0 ++ DBGLOG(SCN, TRACE, ++ "rCmdPscnParam: Period[%u],NumCache[%u],Threshold[%u],NumBkts[%u],fgGSCN[%d] fgNLO[%d] fgBatch[%d]\n", ++ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, ++ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, prCmdPscnParam->fgBatchScnEnable)); ++ ++ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { ++ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); ++ DBGLOG(SCN, TRACE, ++ "band[%u], Index[%u] NumChannels[%u], ucBktFreqMultiple[%u] Flag[%u]\n", ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); ++ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) ++ DBGLOG(SCN, TRACE, ++ " %d, ", prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); ++ DBGLOG(SCN, TRACE, "\n"); ++ } ++#endif ++ ++ if (1 /*prScanInfo->fgPscnOnnning == FALSE */) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCAN_PARAM, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_PARAM), (PUINT_8) prCmdPscnParam, NULL, 0); ++ ++ DBGLOG(SCN, TRACE, "CMD_ID_SET_PSCAN_PARAM is set to FW !!!!!!!!!!\n"); ++ return TRUE; ++ } ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set hotlist ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID prCmdPscnAddHotlist) ++{ ++ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ memcpy(&rCmdPscnAddHotlist.aucMacAddr, &(prCmdPscnAddHotlist->aucMacAddr), sizeof(MAC_ADDR_LEN)); ++ ++ /* rCmdPscnAddHotlist.aucMacAddr = prCmdPscnAddHotlist->aucMacAddr; */ ++ rCmdPscnAddHotlist.ucFlags = prCmdPscnAddHotlist->ucFlags; ++ ++ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_SET_PSCAN_ADD_HOTLIST_BSSID), (PUINT_8) &rCmdPscnAddHotlist, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_ADD_SW_BSSID ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId) ++{ ++ CMD_SET_PSCAN_ADD_SWC_BSSID rCmdPscnAddSWCBssId; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ memcpy(&rCmdPscnAddSWCBssId.aucMacAddr, &(prCmdPscnAddSWCBssId->aucMacAddr), sizeof(MAC_ADDR_LEN)); ++ ++ /* rCmdPscnAddSWCBssId.aucMacAddr = prCmdPscnAddSWCBssId->aucMacAddr; */ ++ rCmdPscnAddSWCBssId.i4RssiHighThreshold = prCmdPscnAddSWCBssId->i4RssiHighThreshold; ++ rCmdPscnAddSWCBssId.i4RssiLowThreshold = prCmdPscnAddSWCBssId->i4RssiLowThreshold; ++ ++ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_ADD_SW_BSSID, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_SET_PSCAN_ADD_SWC_BSSID), (PUINT_8) &rCmdPscnAddSWCBssId, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr) ++{ ++ CMD_SET_PSCAN_MAC_ADDR rCmdPscnSetMacAddr; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ /* rCmdPscnSetMacAddr.aucMacAddr = prCmdPscnSetMacAddr->aucMacAddr; */ ++ memcpy(&rCmdPscnSetMacAddr.aucMacAddr, &(prCmdPscnSetMacAddr->aucMacAddr), sizeof(MAC_ADDR_LEN)); ++ ++ rCmdPscnSetMacAddr.ucFlags = prCmdPscnSetMacAddr->ucFlags; ++ rCmdPscnSetMacAddr.ucVersion = prCmdPscnSetMacAddr->ucVersion; ++ ++ if (1 /* (prScanInfo->fgPscnOnnning == TRUE */) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_MAC_ADDR, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_SET_PSCAN_MAC_ADDR), (PUINT_8) &rCmdPscnSetMacAddr, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set GSCN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam) ++{ ++ /*CMD_GSCN_REQ_T rCmdGscnParam;*/ ++ P_CMD_GSCN_REQ_T rCmdGscnParamp; ++ P_SCAN_INFO_T prScanInfo; ++ UINT_8 ucChannelBuckIndex; ++ UINT_8 i; ++ ++ ASSERT(prAdapter); ++ rCmdGscnParamp = kalMemAlloc(sizeof(CMD_GSCN_REQ_T), VIR_MEM_TYPE); ++ if (rCmdGscnParamp == NULL) { ++ DBGLOG(SCN, INFO, "alloc CmdGscnParam fail\n"); ++ return TRUE; ++ } ++ kalMemZero(rCmdGscnParamp, sizeof(CMD_GSCN_REQ_T)); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ rCmdGscnParamp->u4NumBuckets = prCmdGscnParam->num_buckets; ++ rCmdGscnParamp->u4BasePeriod = prCmdGscnParam->base_period; ++ DBGLOG(SCN, INFO, ++ "u4BasePeriod[%d], u4NumBuckets[%d]\n", rCmdGscnParamp->u4BasePeriod, rCmdGscnParamp->u4NumBuckets); ++ for (ucChannelBuckIndex = 0; ucChannelBuckIndex < prCmdGscnParam->num_buckets; ucChannelBuckIndex++) { ++ DBGLOG(SCN, TRACE, "assign channels to bucket[%d]\n", ucChannelBuckIndex); ++ for (i = 0; i < prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; i++) { ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel = ++ (UINT_8) nicFreq2ChannelNum(prCmdGscnParam->buckets[ucChannelBuckIndex]. ++ channels[i].channel * 1000); ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive = ++ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].passive; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs = ++ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].dwellTimeMs; ++ ++ DBGLOG(SCN, TRACE, "[ucChannel %d, ucPassive %d, u4DwellTimeMs %d\n", ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel, ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive, ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs); ++ ++ } ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].u2BucketIndex = ++ (UINT_16) prCmdGscnParam->buckets[ucChannelBuckIndex].bucket; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].eBand = ++ prCmdGscnParam->buckets[ucChannelBuckIndex].band; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucBucketFreqMultiple = ++ (prCmdGscnParam->buckets[ucChannelBuckIndex].period / prCmdGscnParam->base_period); ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucNumChannels = ++ prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucReportFlag = ++ prCmdGscnParam->buckets[ucChannelBuckIndex].report_events; ++ ++ /* printk("\n"); */ ++ } ++ ++ DBGLOG(SCN, INFO, "scnSetGSCNParam ---> scnPSCNFsm PSCN_RESET\n"); ++ ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, rCmdGscnParamp, NULL, FALSE, FALSE, FALSE, FALSE); ++ kalMemFree(rCmdGscnParamp, VIR_MEM_TYPE, sizeof(CMD_GSCN_REQ_T)); ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine PNO Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnSubCombineNLOtoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_NLO_REQ prNewCmdNloReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prNewCmdNloReq) { ++ prCmdPscnParam->fgNLOScnEnable = TRUE; ++ memcpy(&prCmdPscnParam->rCmdNloReq, prNewCmdNloReq, sizeof(CMD_NLO_REQ)); ++ } else if (prScanInfo->prPscnParam->fgNLOScnEnable) { ++ memcpy(&prCmdPscnParam->rCmdNloReq, &prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); ++ } else ++ prCmdPscnParam->fgNLOScnEnable = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine Batcht Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnSubCombineBatchSCNtoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prNewCmdBatchReq) { ++ prCmdPscnParam->fgBatchScnEnable = TRUE; ++ memcpy(&prCmdPscnParam->rCmdBatchReq, prNewCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); ++ } else if (prScanInfo->prPscnParam->fgBatchScnEnable) { ++ memcpy(&prCmdPscnParam->rCmdBatchReq, &prScanInfo->prPscnParam->rCurrentCmdBatchReq, ++ sizeof(CMD_BATCH_REQ_T)); ++ } else ++ prCmdPscnParam->fgBatchScnEnable = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine GSCN Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnSubCombineGSCNtoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ UINT_32 ucPeriodMin = MAX_PERIOD; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prCmdPscnParam->fgGScnEnable = FALSE; ++ ++ DBGLOG(SCN, TRACE, "scnSubCombineGSCNtoPSCN fgGScnParamSet %d fgGScnConfigSet %d\n", ++ prScanInfo->fgGScnParamSet, prScanInfo->fgGScnConfigSet); ++ ++ if (prNewCmdGscnReq) { ++ DBGLOG(SCN, INFO, "setup prNewCmdGscnReq\n"); ++ prScanInfo->fgGScnParamSet = TRUE; ++ memcpy(&prCmdPscnParam->rCmdGscnReq, prNewCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); ++ if (ucPeriodMin > prNewCmdGscnReq->u4BasePeriod) ++ prCmdPscnParam->u4BasePeriod = prNewCmdGscnReq->u4BasePeriod; ++ } else if (prScanInfo->fgGScnParamSet) { ++ DBGLOG(SCN, INFO, "no new prNewCmdGscnReq but there is a old one\n"); ++ memcpy(&prCmdPscnParam->rCmdGscnReq, &prScanInfo->prPscnParam->rCurrentCmdGscnReq, ++ sizeof(CMD_GSCN_REQ_T)); ++ prCmdPscnParam->u4BasePeriod = prScanInfo->prPscnParam->u4BasePeriod; ++ } else ++ prScanInfo->fgGScnParamSet = FALSE; ++ ++ if (prNewCmdGscnConfig) { ++ DBGLOG(SCN, INFO, "set up prNewCmdGscnConfig\n"); ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prScanInfo->fgGScnConfigSet = TRUE; ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = prNewCmdGscnConfig->u4BufferThreshold; ++ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = (UINT_8) prNewCmdGscnConfig->u4NumScnToCache; ++ } else if (prScanInfo->fgGScnConfigSet) { ++ DBGLOG(SCN, INFO, "no new prNewCmdGscnConfig but there is a old one\n"); ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = ++ prScanInfo->prPscnParam->rCurrentCmdGscnReq.u4BufferThreshold; ++ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = ++ (UINT_8) prScanInfo->prPscnParam->rCurrentCmdGscnReq.ucNumScnToCache; ++ } else ++ prScanInfo->fgGScnConfigSet = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine GSCN Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnRemoveFromPSCN(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, ++ IN BOOLEAN fgRemoveGSCNfromPSCN, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ UINT_8 ucPscanAct = DISABLE; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ { ++ DBGLOG(SCN, INFO, "remove NLO or Batch or GSCN from PSCN--->NLO=%d, BSN=%d, GSN=%d\n", ++ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); ++ ++ if (fgRemoveNLOfromPSCN) { ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->fgNLOScnEnable = FALSE; ++ kalMemZero(&prCmdPscnParam->rCmdNloReq, sizeof(CMD_NLO_REQ)); ++ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); ++ } ++ if (fgRemoveBatchSCNfromPSCN) { ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->fgBatchScnEnable = FALSE; ++ kalMemZero(&prCmdPscnParam->rCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); ++ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); ++ } ++ if (fgRemoveGSCNfromPSCN) { ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->fgGScnEnable = FALSE; ++ prScanInfo->fgGScnParamSet = FALSE; ++ kalMemZero(&prCmdPscnParam->rCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); ++ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); ++ } ++ ++ if (!fgRemoveNLOfromPSCN && !fgRemoveBatchSCNfromPSCN && !fgRemoveGSCNfromPSCN) { ++ /* prCmdPscnParam->fgIsPeriodicallyScn = FALSE; */ ++ prScanInfo->fgPscnOnnning = FALSE; ++ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); ++ scnFsmPSCNAction(prAdapter, ucPscanAct); ++ } else { ++ /* prCmdPscnParam->fgIsPeriodicallyScn = TRUE; */ ++ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); ++ DBGLOG(SCN, INFO, " disable NLO or GSCN or Batch but fgIsPeriodicallyScn = TRUE <-----\n"); ++ } ++ } ++ ++} ++ ++#if 1 ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine GSCN , Batch, PNO Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++BOOLEAN ++scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_NLO_REQ prNewCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ /* CMD_SET_PSCAN_PARAM rCmdPscnParam; */ ++ P_CMD_SET_PSCAN_PARAM prCmdPscnParam; ++ /* UINT_8 i, j = 0; */ ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prCmdPscnParam = (P_CMD_SET_PSCAN_PARAM) kalMemAlloc(sizeof(CMD_SET_PSCAN_PARAM), VIR_MEM_TYPE); ++ if (!prCmdPscnParam) { ++ DBGLOG(SCN, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); ++ return -ENOMEM; ++ } ++ kalMemZero(prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ ++ prCmdPscnParam->ucVersion = CURRENT_PSCN_VERSION; ++ ++ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { ++ scnRemoveFromPSCN(prAdapter, ++ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN, prCmdPscnParam); ++ } else { ++ DBGLOG(SCN, INFO, "combine GSCN or Batch or NLO to PSCN --->\n"); ++ ++ scnSubCombineNLOtoPSCN(prAdapter, prNewCmdNloReq, prCmdPscnParam); ++ scnSubCombineBatchSCNtoPSCN(prAdapter, prNewCmdBatchReq, prCmdPscnParam); ++ if (prNewCmdGscnReq) ++ scnSubCombineGSCNtoPSCN(prAdapter, prNewCmdGscnReq, NULL, prCmdPscnParam); ++ if (prNewCmdGscnConfig) ++ scnSubCombineGSCNtoPSCN(prAdapter, NULL, prNewCmdGscnConfig, prCmdPscnParam); ++ /* scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); */ ++ ++#if 0 ++ DBGLOG(SCN, TRACE, "combine GSCN or Batch or NLO to PSCN <--- rCmdPscnParam\n"); ++ DBGLOG(SCN, TRACE, ++ "Period[%u], NumCache[%u], Threshold[%u], NumBuckets[%u],GSCNEn[%d] NLOEn[%d] BatchEn[%d]\n", ++ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, ++ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, ++ prCmdPscnParam->fgBatchScnEnable)); ++ ++ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { ++ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); ++ DBGLOG(SCN, TRACE, ++ "band[%u], ChnBkt[%u] NumChns[%u], BktFreqMltpl[%u] Flag[%u]\n", ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); ++ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) { ++ DBGLOG(SCN, TRACE, " %d, ", ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); ++ } ++ DBGLOG(SCN, TRACE, "\n"); ++ } ++#endif ++ } ++ ++ memcpy(prScanInfo->prPscnParam, prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ kalMemFree(prCmdPscnParam, VIR_MEM_TYPE, sizeof(CMD_SET_PSCAN_PARAM)); ++ return TRUE; ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig) ++{ ++ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; ++ ++ ASSERT(prAdapter); ++ memcpy(&rCmdGscnScnConfig, prCmdGscnScnConfig, sizeof(CMD_GSCN_SCN_COFIG_T)); ++ DBGLOG(SCN, TRACE, "rCmdGscnScnConfig: u4BufferThreshold; [%d] ucNumApPerScn [%d] ucNumScnToCache [%d]\n", ++ rCmdGscnScnConfig.u4BufferThreshold, ++ rCmdGscnScnConfig.ucNumApPerScn, ++ rCmdGscnScnConfig.u4NumScnToCache); ++ ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, &rCmdGscnScnConfig, FALSE, FALSE, FALSE, FALSE); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd) ++{ ++ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultCmd, sizeof(CMD_GET_GSCAN_RESULT_T)); ++ DBGLOG(SCN, INFO, "rGetGscnScnResultCmd: ucGetNum [%d] fgFlush [%d]\n", ++ rGetGscnScnResultCmd.u4Num, rGetGscnScnResultCmd.ucFlush); ++ ++ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_GSCN_SCN_RESULT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_GET_GSCAN_RESULT_T), (PUINT_8) &rGetGscnScnResultCmd, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN GSCN ongoing ??? */ ++ return FALSE; ++ ++} ++ ++VOID ++scnPSCNFsm(IN P_ADAPTER_T prAdapter, ++ ENUM_PSCAN_STATE_T eNextPSCNState, ++ IN P_CMD_NLO_REQ prCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ BOOLEAN fgTransitionState = FALSE; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ do { ++ fgTransitionState = FALSE; ++ ++ DBGLOG(SCN, STATE, "eCurrentPSCNState=%d, eNextPSCNState=%d\n", ++ prScanInfo->eCurrentPSCNState, eNextPSCNState); ++ ++ switch (prScanInfo->eCurrentPSCNState) { ++ case PSCN_IDLE: ++ if (eNextPSCNState == PSCN_RESET) { ++ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { ++ DBGLOG(SCN, TRACE, "Unexpected remove NLO/BATCH/GSCN request\n"); ++ eNextPSCNState = PSCN_IDLE; ++ break; ++ } ++ ++ if (prCmdNloReq || prCmdBatchReq) { ++ DBGLOG(SCN, TRACE, "PSCN_IDLE->PSCN_RESET,.... scnFsmPSCNActionDISABLE\n"); ++ /*TBD check PSCAN is ongoing */ ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ break; ++ } ++ ++ } else if (eNextPSCNState == PSCN_SCANNING) { ++ if (fgEnableGSCN) { ++ if (prScanInfo->fgPscnOnnning) ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ if (prScanInfo->fgGScnParamSet) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_IDLE->PSCN_SCANNING,.... scnFsmPSCNActionENABLE\n"); ++ prScanInfo->prPscnParam->fgGScnEnable = TRUE; ++ scnFsmPSCNSetParam(prAdapter, ++ (P_CMD_SET_PSCAN_PARAM)prScanInfo->prPscnParam); ++ scnFsmPSCNAction(prAdapter, ENABLE); ++ eNextPSCNState = PSCN_SCANNING; ++ } ++ } ++ } ++ break; ++ ++ case PSCN_RESET: ++ scnCombineParamsIntoPSCN(prAdapter, ++ prCmdNloReq, ++ prCmdBatchReq, ++ prCmdGscnReq, ++ prNewCmdGscnConfig, ++ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); ++ ++ if (!prScanInfo->prPscnParam->fgNLOScnEnable && !prScanInfo->prPscnParam->fgBatchScnEnable ++ && !prScanInfo->prPscnParam->fgGScnEnable) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_RESET->PSCN_IDLE,.... fgNLOScnEnable/fgBatchScnEnable/fgGScnEnable false\n"); ++ eNextPSCNState = PSCN_IDLE; ++ } else { ++ if (prScanInfo->prPscnParam->fgNLOScnEnable ++ || prScanInfo->prPscnParam->fgBatchScnEnable) { ++ scnFsmPSCNSetParam(prAdapter, (P_CMD_SET_PSCAN_PARAM) prScanInfo->prPscnParam); ++ scnFsmPSCNAction(prAdapter, ENABLE); ++ eNextPSCNState = PSCN_SCANNING; ++ DBGLOG(SCN, TRACE, ++ "PSCN_RESET->PSCN_SCANNING,.... fgNLOScnEnable/fgBatchScnEnable ENABLE\n"); ++ } ++ } ++ break; ++ ++ case PSCN_SCANNING: ++ if (eNextPSCNState == PSCN_RESET) { ++ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_RESET,.... fgRemoveNLOfromPSCN/fgRemoveBatchSCNfromPSCN/fgRemoveGSCNfromPSCN\n"); ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ break; ++ } ++ ++ if (prCmdNloReq || prCmdBatchReq || prCmdGscnReq || prNewCmdGscnConfig) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_RESET,.... prCmdNloReq/prCmdBatchReq/prCmdGscnReq/prNewCmdGscnConfig\n"); ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ break; ++ } ++ ++ } else if (eNextPSCNState == PSCN_SCANNING) { ++ if (fgEnableGSCN) { ++ if (prScanInfo->prPscnParam->fgGScnEnable && (!prScanInfo->fgPscnOnnning)) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); ++ /* scnFsmPSCNAction(prAdapter, ENABLE); */ ++ eNextPSCNState = PSCN_SCANNING; ++ } else { ++ ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); ++ } ++ } ++ } ++ eNextPSCNState = PSCN_SCANNING; ++ break; ++ ++ default: ++ DBGLOG(SCN, WARN, "Unexpected state\n"); ++ ASSERT(0); ++ break; ++ } ++ ++ DBGLOG(SCN, STATE, "eCurrentState %d , eNextPSCNState %d\n", ++ prScanInfo->eCurrentPSCNState, eNextPSCNState); ++ if (prScanInfo->eCurrentPSCNState != eNextPSCNState) ++ fgTransitionState = TRUE; ++ ++ prScanInfo->eCurrentPSCNState = eNextPSCNState; ++ } while (fgTransitionState); ++ ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c +new file mode 100644 +index 000000000000..29eb8d4e7d92 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c +@@ -0,0 +1,1112 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/sec_fsm.c#1 ++*/ ++ ++/*! \file "sec_fsm.c" ++ \brief This is the file implement security check state machine. ++ ++ In security module, do the port control check after success join to an AP, ++ and the path to NORMAL TR, the state machine handle these state transition. ++*/ ++ ++/* ++** Log: sec_fsm.c ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 03 29 2011 wh.su ++ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error ++ * fixed the kclocwork error. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 20 2010 wh.su ++ * NULL ++ * adding the eapol callback setting. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 19 2010 wh.su ++ * ++ * fixed the compilng error at debug mode. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the ad-hoc wpa-none send non-encrypted frame issue. ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 13 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the Klocwork error and refine the class error message. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 13 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * fixed the compiling warning ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * refine some code ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * refine the code ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * code refine ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function name ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the state machine, to meet the firmware security design v1.1 ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_RSN_MIGRATION ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugSecState[SEC_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("SEC_STATE_INIT"), ++ (PUINT_8) DISP_STRING("SEC_STATE_INITIATOR_PORT_BLOCKED"), ++ (PUINT_8) DISP_STRING("SEC_STATE_RESPONDER_PORT_BLOCKED"), ++ (PUINT_8) DISP_STRING("SEC_STATE_CHECK_OK"), ++ (PUINT_8) DISP_STRING("SEC_STATE_SEND_EAPOL"), ++ (PUINT_8) DISP_STRING("SEC_STATE_SEND_DEAUTH"), ++ (PUINT_8) DISP_STRING("SEC_STATE_COUNTERMEASURE"), ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do initialization of Security FSM and all variables in ++* SEC_INFO_T. ++* ++* \param[in] prSta Pointer to the STA record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ ++#if 1 /* MT6620 */ ++ /* At MT5921, is ok, but at MT6620, firmware base ASIC, the firmware */ ++ /* will lost these data, thus, driver have to keep the wep material and */ ++ /* setting to firmware while awake from D3. */ ++#endif ++ ++ prSecInfo->eCurrentState = SEC_STATE_INIT; ++ ++ prSecInfo->fg2nd1xSend = FALSE; ++ prSecInfo->fgKeyStored = FALSE; ++ ++ if (IS_STA_IN_AIS(prSta)) { ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ prAisSpecBssInfo->u4RsnaLastMICFailTime = 0; ++ prAisSpecBssInfo->fgCheckEAPoLTxDone = FALSE; ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEapolTxTimeout, (ULONG) prSta); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEndOfCounterMeasure, (ULONG) prSta); ++ ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do uninitialization of Security FSM and all variables in ++* SEC_INFO_T. ++* ++* \param[in] prSta Pointer to the STA record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID /* whsu:Todo: */ ++secFsmUnInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ ++ prSecInfo->fg2nd1xSend = FALSE; ++ prSecInfo->fgKeyStored = FALSE; ++ ++ /* nicPrivacyRemoveWlanTable(prSta->ucWTEntry); */ ++ ++ if (IS_STA_IN_AIS(prSta)) { ++ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); ++ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* STANDBY to CHECK_OK. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INIT_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ secSetPortBlocked(prAdapter, prSta, FALSE); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* INIT to INITIATOR_PORT_BLOCKED. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INIT_to_INITIATOR_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* INIT to RESPONDER_PORT_BLOCKED. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INIT_to_RESPONDER_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* INITIATOR_PORT_BLOCKED to CHECK_OK. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INITIATOR_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ secSetPortBlocked(prAdapter, prSta, FALSE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* RESPONDER_PORT_BLOCKED to CHECK_OK. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_RESPONDER_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ secSetPortBlocked(prAdapter, prSta, FALSE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* CHECK_OK to SEND_EAPOL ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_CHECK_OK_to_SEND_EAPOL(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(prSta); ++ ++ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ ASSERT(prAisBssInfo); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prAisBssInfo->fgCheckEAPoLTxDone = TRUE; ++ ++ /* cnmTimerStartTimer(prAdapter, */ ++ /* &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer, */ ++ /* SEC_TO_MSEC(EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC)); */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* SEND_EAPOL to SEND_DEAUTH. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_SEND_EAPOL_to_SEND_DEAUTH(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Compose deauth frame to AP, a call back function for tx done */ ++ if (authSendDeauthFrame(prAdapter, ++ prSta, ++ (P_SW_RFB_T) NULL, ++ REASON_CODE_MIC_FAILURE, ++ (PFN_TX_DONE_HANDLER) secFsmEventDeauthTxDone) != WLAN_STATUS_SUCCESS) { ++ ASSERT(FALSE); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* SEND_DEAUTH to COUNTERMEASURE. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_SEND_DEAUTH_to_COUNTERMEASURE(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prSta); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ /* Start the 60 sec timer */ ++ cnmTimerStartTimer(prAdapter, ++ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, ++ SEC_TO_MSEC(COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* SEND_DEAUTH to COUNTERMEASURE. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_COUNTERMEASURE_to_INIT(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++ /* Clear the counter measure flag */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The Core FSM engine of security module. ++* ++* \param[in] prSta Pointer to the Sta record ++* \param[in] eNextState Enum value of next sec STATE ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmSteps(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN ENUM_SEC_STATE_T eNextState) ++{ ++ P_SEC_INFO_T prSecInfo; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ ASSERT(prSecInfo); ++ ++ DEBUGFUNC("secFsmSteps"); ++ do { ++ /* Do entering Next State */ ++ prSecInfo->ePreviousState = prSecInfo->eCurrentState; ++ ++ /* Do entering Next State */ ++#if DBG ++ DBGLOG(RSN, STATE, "\n %pM TRANSITION: [%s] -> [%s]\n\n", ++ prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState], apucDebugSecState[eNextState]); ++#else ++ DBGLOG(RSN, STATE, "\n %pM [%d] TRANSITION: [%d] -> [%d]\n\n", ++ prSta->aucMacAddr, DBG_RSN_IDX, prSecInfo->eCurrentState, eNextState); ++#endif ++ prSecInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++#if 0 ++ /* Do tasks of the State that we just entered */ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INIT: ++ break; ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ break; ++ case SEC_STATE_RESPONDER_PORT_BLOCKED: ++ break; ++ case SEC_STATE_CHECK_OK: ++ break; ++ case SEC_STATE_SEND_EAPOL: ++ break; ++ case SEC_STATE_SEND_DEAUTH: ++ break; ++ case SEC_STATE_COUNTERMEASURE: ++ break; ++ default: ++ ASSERT(0); /* Make sure we have handle all STATEs */ ++ break; ++ } ++#endif ++ } while (fgIsTransition); ++ ++ return; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do initialization of Security FSM and all variables in ++* SEC_INFO_T. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ENUM_SEC_STATE_T eNextState; ++ ++ DBGLOG(RSN, TRACE, "secFsmRunEventStart\n"); ++ ++ ASSERT(prSta); ++ ++ if (!prSta) ++ return; ++ ++ if (!IS_STA_IN_AIS(prSta)) ++ return; ++ ++ DBGLOG(RSN, TRACE, "secFsmRunEventStart for sta %pM network %d\n", ++ prSta->aucMacAddr, prSta->ucNetTypeIndex); ++ ++ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; ++ ++ eNextState = prSecInfo->eCurrentState; ++ ++ secSetPortBlocked(prAdapter, prSta, TRUE); ++ ++ /* prSta->fgTransmitKeyExist = FALSE; */ ++ /* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */ ++ ++#if 1 /* Since the 1x and key can set to firmware in order, always enter the check ok state */ ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); ++#else ++ if (IS_STA_IN_AIS(prSta->eStaType)) { ++ if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE ++#if CFG_SUPPORT_WAPI ++ || (prAdapter->rWifiVar.rConnSettings.fgWapiMode) ++#endif ++ ) { ++ prSta->fgTransmitKeyExist = FALSE; ++ /* nicPrivacyInitialize(prSta->ucNetTypeIndex); */ ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); ++ } else { ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI ++ else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC)) { ++#elif CFG_ENABLE_WIFI_DIRECT ++ else if (prSta->eStaType == STA_TYPE_P2P_GC) { ++#elif CFG_ENABLE_BT_OVER_WIFI ++ else if (prSta->eStaType == STA_TYPE_BOW_CLIENT) { ++#endif ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED); ++ } ++#endif ++ else ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); ++#endif ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++} /* secFsmRunEventStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function called by reset procedure to force the sec fsm enter ++* idle state ++* ++* \param[in] ucNetTypeIdx The Specific Network type index ++* \param[in] prSta Pointer to the Sta record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ++ DBGLOG(RSN, TRACE, "secFsmEventAbort for sta %pM network %d\n", ++ prSta->aucMacAddr, prSta->ucNetTypeIndex); ++ ++ ASSERT(prSta); ++ ++ if (!prSta) ++ return; ++ ++ if (!IS_STA_IN_AIS(prSta)) ++ return; ++ ++ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; ++ ++ prSta->fgTransmitKeyExist = FALSE; ++ ++ secSetPortBlocked(prAdapter, prSta, TRUE); ++ ++ if (prSecInfo == NULL) ++ return; ++ ++ if (IS_STA_IN_AIS(prSta)) { ++ ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; ++ ++ if (prSecInfo->eCurrentState == SEC_STATE_SEND_EAPOL) { ++ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone == FALSE) { ++ DBGLOG(RSN, TRACE, "EAPOL STATE not match the flag\n"); ++ /* cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar. ++ * rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); */ ++ } ++ } ++ } ++ prSecInfo->eCurrentState = SEC_STATE_INIT; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "2nd EAPoL Tx is sending" to Sec FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ /* BOOLEAN fgIsTransition = (BOOLEAN)FALSE; */ ++ ++ DEBUGFUNC("secFsmRunEvent2ndEapolTx"); ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ case SEC_STATE_CHECK_OK: ++ prSecInfo->fg2nd1xSend = TRUE; ++ break; ++ default: ++#if DBG ++ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState); ++#endif ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return; ++ ++} /* secFsmRunEvent2ndEapolTx */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "4th EAPoL Tx is Tx done" to Sec FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ P_CMD_802_11_KEY prStoredKey; ++ ++ DEBUGFUNC("secFsmRunEvent4ndEapolTx"); ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ case SEC_STATE_CHECK_OK: ++ prSecInfo->fg2nd1xSend = FALSE; ++ if (prSecInfo->fgKeyStored) { ++ prStoredKey = (P_CMD_802_11_KEY) prSecInfo->aucStoredKey; ++ ++ /* prSta = rxmLookupStaRecIndexFromTA(prStoredKey->aucPeerAddr); */ ++ /* if (nicPrivacySetKeyEntry(prStoredKey, prSta->ucWTEntry) == FALSE) */ ++ /* DBGLOG(RSN, WARN, ("nicPrivacySetKeyEntry() fail,..\n")); */ ++ ++ /* key update */ ++ prSecInfo->fgKeyStored = FALSE; ++ prSta->fgTransmitKeyExist = TRUE; ++ } ++ if (prSecInfo->eCurrentState == SEC_STATE_INITIATOR_PORT_BLOCKED) ++ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); ++ break; ++ default: ++ ++#if DBG ++ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at [%d]\n", prSecInfo->eCurrentState); ++#endif ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return; ++ ++} /* secFsmRunEvent4ndEapolTx */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Pairwise key installed" to SEC FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \retval TRUE The key can be installed to HW ++* \retval FALSE The kay conflict with the current key, abort it ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgStatus = TRUE; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ if (prSecInfo == NULL) ++ return TRUE; /* Not PTK */ ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAdd), ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ eNextState = prSecInfo->eCurrentState; ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INIT: ++ /* Legacy wep, wpa-none */ ++ break; ++ ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ if (prSecInfo->fg2nd1xSend) ++ ; ++ else ++ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); ++ break; ++ ++ case SEC_STATE_RESPONDER_PORT_BLOCKED: ++ SEC_STATE_TRANSITION(prAdapter, prSta, RESPONDER_PORT_BLOCKED, CHECK_OK); ++ break; ++ ++ case SEC_STATE_CHECK_OK: ++ break; ++ ++ default: ++ fgStatus = FALSE; ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return fgStatus; ++ ++} /* end of secFsmRunEventPTKInstalled() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Counter Measure" to SEC FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("secFsmRunEventStartCounterMeasure"); ++ ++ ASSERT(prSta); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prSecInfo = &prSta->rSecInfo; ++ ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ prAdapter->rWifiVar.rAisSpecificBssInfo.u4RsnaLastMICFailTime = 0; ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_CHECK_OK: ++ { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = TRUE; ++ ++ /* dls port control */ ++ SEC_STATE_TRANSITION(prAdapter, prSta, CHECK_OK, SEND_EAPOL); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Call arbFsmSteps() when we are going to change ARB STATE */ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return; ++ ++} /* secFsmRunEventStartCounterMeasure */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "802.1x EAPoL Tx Done" to Sec FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; ++ ++ DEBUGFUNC("secFsmRunEventEapolTxDone"); ++ ++ ASSERT(prStaRec); ++ ++ if (rTxDoneStatus != TX_RESULT_SUCCESS) { ++ DBGLOG(RSN, INFO, "Error EAPoL fram fail to send!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ if (!IS_STA_IN_AIS(prStaRec)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ ASSERT(prAisBssInfo); ++ ++ prSecInfo = &prStaRec->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_SEND_EAPOL: ++ if (prAisBssInfo->fgCheckEAPoLTxDone == FALSE) ++ ASSERT(0); ++ ++ prAisBssInfo->fgCheckEAPoLTxDone = FALSE; ++ /* cnmTimerStopTimer(prAdapter, &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer); */ ++ ++ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_EAPOL, SEND_DEAUTH); ++ break; ++ default: ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prStaRec, eNextState); ++ ++ return; ++ ++} /* secFsmRunEventEapolTxDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Deauth frame Tx Done" to Sec FSM. ++* ++* \param[in] pMsduInfo Pointer to the Msdu Info ++* \param[in] rStatus The Tx done status ++* ++* \return - ++* ++* \note after receive deauth frame, callback function call this ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("secFsmRunEventDeauthTxDone"); ++ ++ ASSERT(prMsduInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return; ++ ++ if (!IS_STA_IN_AIS(prStaRec)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prSecInfo = (P_SEC_INFO_T) &prStaRec->rSecInfo; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_SEND_DEAUTH: ++ ++ DBGLOG(RSN, TRACE, "Set timer %d\n", COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC); ++ ++ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_DEAUTH, COUNTERMEASURE); ++ ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++} /* secFsmRunEventDeauthTxDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will check the eapol error frame fail to send issue. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("secFsmRunEventEapolTxTimeout"); ++ ++ prStaRec = (P_STA_RECORD_T) ulParm; ++ ++ ASSERT(prStaRec); ++ ++ /* Todo:: How to handle the Eapol Error fail to send case? */ ++ ASSERT(0); ++ ++ return; ++ ++} /* secFsmEventEapolTxTimeout */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will stop the counterMeasure duration. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, ULONG ulParm) ++{ ++ P_STA_RECORD_T prSta; ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("secFsmRunEventEndOfCounterMeasure"); ++ ++ prSta = (P_STA_RECORD_T) ulParm; ++ ++ ASSERT(prSta); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prSecInfo = &prSta->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_SEND_DEAUTH: ++ { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = FALSE; ++ ++ SEC_STATE_TRANSITION(prAdapter, prSta, COUNTERMEASURE, INIT); ++ } ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ /* Call arbFsmSteps() when we are going to change ARB STATE */ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++} /* end of secFsmRunEventEndOfCounterMeasure */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c +new file mode 100644 +index 000000000000..ab3fcc028375 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c +@@ -0,0 +1,1342 @@ ++/* ++** Id: stats.c#1 ++*/ ++ ++/*! \file stats.c ++ \brief This file includes statistics support. ++*/ ++ ++/* ++** Log: stats.c ++ * ++ * 07 17 2014 samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++#include "precomp.h" ++ ++enum EVENT_TYPE { ++ EVENT_RX, ++ EVENT_TX, ++ EVENT_TX_DONE ++}; ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++static WLAN_STATUS ++statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++UINT_64 u8DrvOwnStart, u8DrvOwnEnd; ++UINT32 u4DrvOwnMax = 0; ++#define CFG_USER_LOAD 0 ++static UINT_16 su2TxDoneCfg = CFG_DHCP | CFG_ICMP | CFG_EAPOL; ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display all environment log. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ P_ADAPTER_T prAdapter; ++ STA_RECORD_T *prStaRec; ++ UINT32 u4NumOfInfo, u4InfoId; ++ UINT32 u4RxErrBitmap; ++ STATS_INFO_ENV_T *prInfo; ++ UINT32 u4Total, u4RateId; ++ ++/* ++[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 ++[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) ++ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, ++ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) ++ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) ++ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) ++ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) ++ ERR (1st: total number of tx err, 2nd ~ 7st: total number of ++ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, ++ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) ++ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) ++ RX (1st: latest RCPI, 2nd: chan num) ++ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) ++ OK (number of rx packets without error, number of rx packets to OS) ++ ERR (number of rx packets with error) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ CCK MODE (1 2 5.5 11M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) ++ MIXED MODE (number of rx packets with MCS0 ~ MCS15) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) ++ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) ++ delay from MAC start TX to MAC TX done ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) ++ delay from HIF to MAC TX done (min, avg, max_system time for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) ++ delay from driver to MAC TX done (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) ++ delay from MAC to HIF (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) ++ delay from HIF to Driver OS (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) ++ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) ++ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) ++ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) ++ Channel idle time, scan count, channel change count, empty tx quota count, ++ power save change count from active to PS, maximum delay from PS to active ++*/ ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ /*prInfo = &rStatsInfoEnv;*/ ++ prInfo = kalMemAlloc(sizeof(STATS_INFO_ENV_T), VIR_MEM_TYPE); ++ if (prInfo == NULL) { ++ DBGLOG(RX, INFO, "prInfo alloc fail"); ++ return; ++ } ++ ++ kalMemZero(prInfo, sizeof(STATS_INFO_ENV_T)); ++ ++ if (u4InBufLen > sizeof(STATS_INFO_ENV_T)) ++ u4InBufLen = sizeof(STATS_INFO_ENV_T); ++ ++ /* parse */ ++ u4NumOfInfo = *(UINT32 *) prInBuf; ++ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); ++ ++ /* print */ ++ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { ++ /* ++ use u4InBufLen, not sizeof(rStatsInfoEnv) ++ because the firmware version maybe not equal to driver version ++ */ ++ kalMemCopy(prInfo, prInBuf + 8, u4InBufLen); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prInfo->ucStaRecIdx); ++ if (prStaRec == NULL) ++ continue; ++ ++ DBGLOG(RX, INFO, " Display stats for [%pM]: %uB\n", ++ prStaRec->aucMacAddr, (UINT32) sizeof(STATS_INFO_ENV_T)); ++ ++ if (prStaRec->ucStatsGenDisplayCnt++ > 10) { ++ /* display general statistics information every 10 * (5 or 10s) */ ++ DBGLOG(RX, INFO, " TBA(0x%x %u) RBA(0x%x %u)\n", ++ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, ++ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize); ++ prStaRec->ucStatsGenDisplayCnt = 0; ++ } ++ ++ if (prInfo->u4TxDataCntErr == 0) { ++ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u)\n", ++ (UINT32) prGlueInfo->rNetDevStats.tx_packets, ++ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK); ++ } else { ++ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u) ERR(%u)\n", ++ (UINT32) prGlueInfo->rNetDevStats.tx_packets, ++ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, prInfo->u4TxDataCntErr); ++ DBGLOG(RX, INFO, " ERR type(%u %u %u %u %u %u)\n", ++ prInfo->u4TxDataCntErrType[0], prInfo->u4TxDataCntErrType[1], ++ prInfo->u4TxDataCntErrType[2], prInfo->u4TxDataCntErrType[3], ++ prInfo->u4TxDataCntErrType[4], prInfo->u4TxDataCntErrType[5]); ++ } ++ ++ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4TxRateCntNonHT[u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, " non-HT TRATE (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], ++ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], ++ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], ++ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], ++ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], ++ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], ++ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], ++ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15]); ++ } ++ if (prInfo->u4TxRateCntNonHT[0] > 0) { ++ DBGLOG(RX, INFO, " HT TRATE (1M %u) (%u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntNonHT[0], ++ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], ++ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], ++ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], ++ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); ++ } else { ++ DBGLOG(RX, INFO, " HT TRATE (%u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], ++ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], ++ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], ++ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); ++ } ++ ++ if ((prStaRec->u4RxReorderFallAheadCnt != 0) || ++ (prStaRec->u4RxReorderFallBehindCnt != 0) || (prStaRec->u4RxReorderHoleCnt != 0)) { ++ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", ++ prStaRec->u4RxReorderFallAheadCnt, ++ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); ++ } ++ ++ if (prInfo->u4RxDataCntErr == 0) { ++ DBGLOG(RX, INFO, " ROK(%u %u)\n", ++ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt); ++ } else { ++ DBGLOG(RX, INFO, " ROK(%u %u) ERR(%u)\n", ++ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, ++ prInfo->u4RxDataCntErr); ++ } ++ ++ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateCnt[0][u4RateId] + prInfo->u4RxRateRetryCnt[0][u4RateId]; ++ if (u4Total > 0) { ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateRetryCnt[0][u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, ++ " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], ++ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], ++ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], ++ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], ++ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], ++ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], ++ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], ++ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], ++ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], ++ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], ++ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], ++ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], ++ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], ++ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], ++ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], ++ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15]); ++ } else { ++ DBGLOG(RX, INFO, " RCCK (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4RxRateCnt[0][0], ++ prInfo->u4RxRateCnt[0][1], ++ prInfo->u4RxRateCnt[0][2], ++ prInfo->u4RxRateCnt[0][3], ++ prInfo->u4RxRateCnt[0][4], ++ prInfo->u4RxRateCnt[0][5], ++ prInfo->u4RxRateCnt[0][6], ++ prInfo->u4RxRateCnt[0][7], ++ prInfo->u4RxRateCnt[0][8], ++ prInfo->u4RxRateCnt[0][9], ++ prInfo->u4RxRateCnt[0][10], ++ prInfo->u4RxRateCnt[0][11], ++ prInfo->u4RxRateCnt[0][12], ++ prInfo->u4RxRateCnt[0][13], ++ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateCnt[0][15]); ++ } ++ } else { ++ if ((prInfo->u4RxRateCnt[0][0] + prInfo->u4RxRateRetryCnt[0][0]) > 0) { ++ DBGLOG(RX, INFO, " RCCK (%u %u)\n", ++ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0]); ++ } ++ } ++ ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateCnt[1][u4RateId] + prInfo->u4RxRateRetryCnt[1][u4RateId]; ++ if (u4Total > 0) { ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateRetryCnt[1][u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, ++ " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], ++ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], ++ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], ++ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], ++ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], ++ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], ++ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], ++ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], ++ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], ++ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], ++ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], ++ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], ++ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], ++ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], ++ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], ++ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15]); ++ } else { ++ DBGLOG(RX, INFO, " ROFDM (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4RxRateCnt[1][0], ++ prInfo->u4RxRateCnt[1][1], ++ prInfo->u4RxRateCnt[1][2], ++ prInfo->u4RxRateCnt[1][3], ++ prInfo->u4RxRateCnt[1][4], ++ prInfo->u4RxRateCnt[1][5], ++ prInfo->u4RxRateCnt[1][6], ++ prInfo->u4RxRateCnt[1][7], ++ prInfo->u4RxRateCnt[1][8], ++ prInfo->u4RxRateCnt[1][9], ++ prInfo->u4RxRateCnt[1][10], ++ prInfo->u4RxRateCnt[1][11], ++ prInfo->u4RxRateCnt[1][12], ++ prInfo->u4RxRateCnt[1][13], ++ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateCnt[1][15]); ++ } ++ } ++ ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateCnt[2][u4RateId] + prInfo->u4RxRateRetryCnt[2][u4RateId]; ++ if (u4Total > 0) { ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateRetryCnt[2][u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, " RHT\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], ++ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], ++ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], ++ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], ++ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], ++ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], ++ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], ++ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7]); ++ } else { ++ DBGLOG(RX, INFO, " RHT (%u %u %u %u %u %u %u %u)\n", ++ prInfo->u4RxRateCnt[2][0], ++ prInfo->u4RxRateCnt[2][1], ++ prInfo->u4RxRateCnt[2][2], ++ prInfo->u4RxRateCnt[2][3], ++ prInfo->u4RxRateCnt[2][4], ++ prInfo->u4RxRateCnt[2][5], ++ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateCnt[2][7]); ++ } ++ } ++ ++ /* RX drop counts */ ++ for (u4RateId = 0, u4Total = 0; u4RateId < 20; u4RateId++) ++ u4Total += prInfo->u4NumOfRxDrop[u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, " RX Drop Count: (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n" ++ " (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", ++ prInfo->u4NumOfRxDrop[0], prInfo->u4NumOfRxDrop[1], ++ prInfo->u4NumOfRxDrop[2], prInfo->u4NumOfRxDrop[3], ++ prInfo->u4NumOfRxDrop[4], prInfo->u4NumOfRxDrop[5], ++ prInfo->u4NumOfRxDrop[6], prInfo->u4NumOfRxDrop[7], ++ prInfo->u4NumOfRxDrop[8], prInfo->u4NumOfRxDrop[9], ++ prInfo->u4NumOfRxDrop[10], prInfo->u4NumOfRxDrop[11], ++ prInfo->u4NumOfRxDrop[12], prInfo->u4NumOfRxDrop[13], ++ prInfo->u4NumOfRxDrop[14], prInfo->u4NumOfRxDrop[15], ++ prInfo->u4NumOfRxDrop[16], prInfo->u4NumOfRxDrop[17], ++ prInfo->u4NumOfRxDrop[18], prInfo->u4NumOfRxDrop[19]); ++ } ++ ++ /* delay from HIF RX to HIF RX Done */ ++ if (((prInfo->u4StayIntMinHR2HRD[1] + prInfo->u4StayIntAvgHR2HRD[1] + ++ prInfo->u4StayIntMaxHR2HRD[1]) > 0) || ++ ((prInfo->u4StayIntMinHR2HRD[2] + prInfo->u4StayIntAvgHR2HRD[2] + ++ prInfo->u4StayIntMaxHR2HRD[2]) > 0)) { ++ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], ++ prInfo->u4StayIntMaxHR2HRD[0], ++ prInfo->u4StayIntMinHR2HRD[1], prInfo->u4StayIntAvgHR2HRD[1], ++ prInfo->u4StayIntMaxHR2HRD[1], ++ prInfo->u4StayIntMinHR2HRD[2], prInfo->u4StayIntAvgHR2HRD[2], ++ prInfo->u4StayIntMaxHR2HRD[2]); ++ } else { ++ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u)\n", ++ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], ++ prInfo->u4StayIntMaxHR2HRD[0]); ++ } ++ ++ /* others */ ++ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%x)\n", ++ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, ++ prInfo->u4NumOfChanChange, prInfo->u4CurrChnlInfo); ++#if CFG_SUPPORT_THERMO_THROTTLING ++ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; ++#endif ++ /* reset */ ++ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); ++ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); ++ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); ++ prStaRec->u4StatsRxPassToOsCnt = 0; ++ prStaRec->u4RxReorderFallAheadCnt = 0; ++ prStaRec->u4RxReorderFallBehindCnt = 0; ++ prStaRec->u4RxReorderHoleCnt = 0; ++ } ++ ++ STATS_DRIVER_OWN_RESET(); ++ kalMemFree(prInfo, VIR_MEM_TYPE, sizeof(STATS_INFO_ENV_T)); ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display all environment log. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ P_ADAPTER_T prAdapter; ++ STA_RECORD_T *prStaRec; ++ UINT32 u4NumOfInfo, u4InfoId; ++ UINT32 u4RxErrBitmap; ++ STATS_INFO_ENV_T rStatsInfoEnv, *prInfo; ++ ++/* ++[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 ++[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) ++ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, ++ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) ++ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) ++ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) ++ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) ++ ERR (1st: total number of tx err, 2nd ~ 7st: total number of ++ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, ++ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) ++ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) ++ RX (1st: latest RCPI, 2nd: chan num) ++ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) ++ OK (number of rx packets without error, number of rx packets to OS) ++ ERR (number of rx packets with error) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ CCK MODE (1 2 5.5 11M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) ++ MIXED MODE (number of rx packets with MCS0 ~ MCS15) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) ++ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) ++ delay from MAC start TX to MAC TX done ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) ++ delay from HIF to MAC TX done (min, avg, max_system time for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) ++ delay from driver to MAC TX done (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) ++ delay from MAC to HIF (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) ++ delay from HIF to Driver OS (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) ++ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) ++ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) ++ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) ++ Channel idle time, scan count, channel change count, empty tx quota count, ++ power save change count from active to PS, maximum delay from PS to active ++*/ ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ prInfo = &rStatsInfoEnv; ++ kalMemZero(&rStatsInfoEnv, sizeof(rStatsInfoEnv)); ++ ++ if (u4InBufLen > sizeof(rStatsInfoEnv)) ++ u4InBufLen = sizeof(rStatsInfoEnv); ++ ++ /* parse */ ++ u4NumOfInfo = *(UINT32 *) prInBuf; ++ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); ++ ++ /* print */ ++ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { ++ /* ++ use u4InBufLen, not sizeof(rStatsInfoEnv) ++ because the firmware version maybe not equal to driver version ++ */ ++ kalMemCopy(&rStatsInfoEnv, prInBuf + 8, u4InBufLen); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, rStatsInfoEnv.ucStaRecIdx); ++ if (prStaRec == NULL) ++ continue; ++ ++ DBGLOG(RX, INFO, " Display stats V%d.%d for [%pM]: %uB %ums\n", ++ prInfo->ucFwVer[0], prInfo->ucFwVer[1], ++ (prStaRec->aucMacAddr), (UINT32) sizeof(STATS_INFO_ENV_T), ++ prInfo->u4ReportSysTime); ++ DBGLOG(RX, INFO, "TPAM(0x%x)RTS(%u %u)BA(0x%x %u)OS(%u)OK(%u %u)ERR(%u %u %u %u %u %u %u)\n", ++ prInfo->ucTxParam, ++ prInfo->fgTxIsRtsUsed, prInfo->fgTxIsRtsEverUsed, ++ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, ++ (UINT32) prGlueInfo->rNetDevStats.tx_packets, ++ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, ++ prInfo->u4TxDataCntErr, prInfo->u4TxDataCntErrType[0], ++ prInfo->u4TxDataCntErrType[1], prInfo->u4TxDataCntErrType[2], ++ prInfo->u4TxDataCntErrType[3], prInfo->u4TxDataCntErrType[4], ++ prInfo->u4TxDataCntErrType[5])); ++ ++ DBGLOG(RX, INFO, "TRATE(%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], ++ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], ++ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], ++ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], ++ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], ++ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], ++ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], ++ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15], ++ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], ++ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], ++ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], ++ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7])); ++ ++ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", ++ prStaRec->u4RxReorderFallAheadCnt, ++ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); ++ ++ DBGLOG(RX, INFO, " RX(%u %u %u) BA(0x%x %u) OK(%u %u) ERR(%u)\n", ++ prInfo->ucRcvRcpi, prInfo->ucHwChanNum, prInfo->fgRxIsShortGI, ++ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize, ++ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, prInfo->u4RxDataCntErr); ++ ++ DBGLOG(RX, INFO, " RX Free MAC DESC(%u %u %u %u %u %u) Free HIF DESC(%u %u %u %u %u %u)\n", ++ prInfo->u4RxMacFreeDescCnt[0], prInfo->u4RxMacFreeDescCnt[1], ++ prInfo->u4RxMacFreeDescCnt[2], prInfo->u4RxMacFreeDescCnt[3], ++ prInfo->u4RxMacFreeDescCnt[4], prInfo->u4RxMacFreeDescCnt[5], ++ prInfo->u4RxHifFreeDescCnt[0], prInfo->u4RxHifFreeDescCnt[1], ++ prInfo->u4RxHifFreeDescCnt[2], prInfo->u4RxHifFreeDescCnt[3], ++ prInfo->u4RxHifFreeDescCnt[4], prInfo->u4RxHifFreeDescCnt[5])); ++ ++ DBGLOG(RX, INFO, " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], ++ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], ++ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], ++ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], ++ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], ++ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], ++ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], ++ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], ++ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], ++ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], ++ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], ++ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], ++ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], ++ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], ++ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], ++ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15])); ++ DBGLOG(RX, INFO, " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], ++ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], ++ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], ++ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], ++ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], ++ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], ++ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], ++ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], ++ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], ++ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], ++ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], ++ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], ++ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], ++ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], ++ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], ++ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15])); ++ DBGLOG(RX, INFO, " RHT (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], ++ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], ++ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], ++ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], ++ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], ++ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], ++ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], ++ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7], ++ prInfo->u4RxRateCnt[2][8], prInfo->u4RxRateRetryCnt[2][8], ++ prInfo->u4RxRateCnt[2][9], prInfo->u4RxRateRetryCnt[2][9], ++ prInfo->u4RxRateCnt[2][10], prInfo->u4RxRateRetryCnt[2][10], ++ prInfo->u4RxRateCnt[2][11], prInfo->u4RxRateRetryCnt[2][11], ++ prInfo->u4RxRateCnt[2][12], prInfo->u4RxRateRetryCnt[2][12], ++ prInfo->u4RxRateCnt[2][13], prInfo->u4RxRateRetryCnt[2][13], ++ prInfo->u4RxRateCnt[2][14], prInfo->u4RxRateRetryCnt[2][14], ++ prInfo->u4RxRateCnt[2][15], prInfo->u4RxRateRetryCnt[2][15])); ++ ++ /* delay from HIF to MAC */ ++ DBGLOG(RX, INFO, " StayIntH2M us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinH2M[0], prInfo->u4StayIntAvgH2M[0], ++ prInfo->u4StayIntMaxH2M[0], ++ prInfo->u4StayIntMinH2M[1], prInfo->u4StayIntAvgH2M[1], ++ prInfo->u4StayIntMaxH2M[1], ++ prInfo->u4StayIntMinH2M[2], prInfo->u4StayIntAvgH2M[2], ++ prInfo->u4StayIntMaxH2M[2])); ++ /* delay from MAC to TXDONE */ ++ DBGLOG(RX, INFO, " AirTime us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4AirDelayMin[0] << 5, prInfo->u4AirDelayAvg[0] << 5, ++ prInfo->u4AirDelayMax[0] << 5, ++ prInfo->u4AirDelayMin[1] << 5, prInfo->u4AirDelayAvg[1] << 5, ++ prInfo->u4AirDelayMax[1] << 5, ++ prInfo->u4TxDataCntAll, (prInfo->u4AirDelayAvg[2] << 5) / (prInfo->u4TxDataCntAll), ++ (prInfo->u4AirDelayAvg[2] << 5) / 400000)); ++ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; ++ /* delay from HIF to TXDONE */ ++ DBGLOG(RX, INFO, " StayInt us (%u %u %u_%u) (%u %u %u_%u) (%u %u %u_%u)\n", ++ prInfo->u4StayIntMin[0], prInfo->u4StayIntAvg[0], ++ prInfo->u4StayIntMax[0], prInfo->u4StayIntMaxSysTime[0], ++ prInfo->u4StayIntMin[1], prInfo->u4StayIntAvg[1], ++ prInfo->u4StayIntMax[1], prInfo->u4StayIntMaxSysTime[1], ++ prInfo->u4StayIntMin[2], prInfo->u4StayIntAvg[2], ++ prInfo->u4StayIntMax[2], prInfo->u4StayIntMaxSysTime[2])); ++ /* delay from Driver to TXDONE */ ++ DBGLOG(RX, INFO, " StayIntD2T us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinD2T[0], prInfo->u4StayIntAvgD2T[0], ++ prInfo->u4StayIntMaxD2T[0], ++ prInfo->u4StayIntMinD2T[1], prInfo->u4StayIntAvgD2T[1], ++ prInfo->u4StayIntMaxD2T[1], ++ prInfo->u4StayIntMinD2T[2], prInfo->u4StayIntAvgD2T[2], ++ prInfo->u4StayIntMaxD2T[2])); ++ ++ /* delay from RXDONE to HIF */ ++ DBGLOG(RX, INFO, " StayIntR_M2H us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinRx[0], prInfo->u4StayIntAvgRx[0], ++ prInfo->u4StayIntMaxRx[0], ++ prInfo->u4StayIntMinRx[1], prInfo->u4StayIntAvgRx[1], ++ prInfo->u4StayIntMaxRx[1], ++ prInfo->u4StayIntMinRx[2], prInfo->u4StayIntAvgRx[2], prInfo->u4StayIntMaxRx[2])); ++ /* delay from HIF to OS */ ++ DBGLOG(RX, INFO, " StayIntR_H2D us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prStaRec->u4StayIntMinRx[0], prStaRec->u4StayIntAvgRx[0], ++ prStaRec->u4StayIntMaxRx[0], ++ prStaRec->u4StayIntMinRx[1], prStaRec->u4StayIntAvgRx[1], ++ prStaRec->u4StayIntMaxRx[1], ++ prStaRec->u4StayIntMinRx[2], prStaRec->u4StayIntAvgRx[2], ++ prStaRec->u4StayIntMaxRx[2])); ++ ++ /* count based on delay from OS to HIF */ ++ DBGLOG(RX, INFO, " StayCntD2H unit:%dms (%d %d %d %d)\n", ++ STATS_STAY_INT_D2H_CONST, ++ prInfo->u4StayIntD2HByConst[0], prInfo->u4StayIntD2HByConst[1], ++ prInfo->u4StayIntD2HByConst[2], prInfo->u4StayIntD2HByConst[3]); ++ ++ /* count based on different delay from HIF to TX DONE */ ++ DBGLOG(RX, INFO, " StayCnt unit:%dms (%d %d %d %d)\n", ++ STATS_STAY_INT_CONST, ++ prInfo->u4StayIntByConst[0], prInfo->u4StayIntByConst[1], ++ prInfo->u4StayIntByConst[2], prInfo->u4StayIntByConst[3]); ++ DBGLOG(RX, INFO, " StayCnt (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~:%d)\n", ++ 0, prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntCnt[0], ++ prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntCnt[1], ++ prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntMaxPast * 3 / 4, ++ prInfo->u4StayIntCnt[2], prInfo->u4StayIntMaxPast * 3 / 4, prInfo->u4StayIntMaxPast, ++ prInfo->u4StayIntCnt[3], prInfo->u4StayIntMaxPast, prInfo->u4StayIntCnt[4])); ++ ++ /* channel idle time */ ++ DBGLOG(RX, INFO, " Idle Time (slot): (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", ++ prInfo->au4ChanIdleCnt[0], prInfo->au4ChanIdleCnt[1], ++ prInfo->au4ChanIdleCnt[2], prInfo->au4ChanIdleCnt[3], ++ prInfo->au4ChanIdleCnt[4], prInfo->au4ChanIdleCnt[5], ++ prInfo->au4ChanIdleCnt[6], prInfo->au4ChanIdleCnt[7], ++ prInfo->au4ChanIdleCnt[8], prInfo->au4ChanIdleCnt[9])); ++ ++ /* BT coex */ ++ DBGLOG(RX, INFO, " BT coex (0x%x)\n", prInfo->u4BtContUseTime); ++ ++ /* others */ ++ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%u) (%u) (%ums) (%uus)\n", ++ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, ++ prInfo->u4NumOfChanChange, prStaRec->u4NumOfNoTxQuota, ++ prInfo->ucNumOfPsChange, prInfo->u4PsIntMax, u4DrvOwnMax / 1000); ++ ++ /* reset */ ++ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); ++ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); ++ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); ++ prStaRec->u4StatsRxPassToOsCnt = 0; ++ prStaRec->u4RxReorderFallAheadCnt = 0; ++ prStaRec->u4RxReorderFallBehindCnt = 0; ++ prStaRec->u4RxReorderHoleCnt = 0; ++ } ++ ++ STATS_DRIVER_OWN_RESET(); ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to request firmware to feedback statistics. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ STATS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* sanity check */ ++ if (fgIsUnderSuspend == true) ++ return WLAN_STATUS_SUCCESS; /* do not request stats after early suspend */ ++ ++ /* init command buffer */ ++ prCmdContent = (STATS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = STATS_CORE_CMD_ENV_REQUEST; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_STATS, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(STATS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(RX, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return WLAN_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(RX, INFO, "%s cmd ok.\n", __func__); ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle any statistics event. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ UINT32 u4EventId; ++ ++ /* sanity check */ ++/* DBGLOG(RX, INFO, */ ++/* (" %s: Rcv a event\n", __FUNCTION__)); */ ++ ++ if ((prGlueInfo == NULL) || (prInBuf == NULL)) ++ return; /* shall not be here */ ++ ++ /* handle */ ++ u4EventId = *(UINT32 *) prInBuf; ++ u4InBufLen -= 4; ++ ++/* DBGLOG(RX, INFO, */ ++/* (" %s: Rcv a event: %d\n", __FUNCTION__, u4EventId)); */ ++ ++ switch (u4EventId) { ++ case STATS_HOST_EVENT_ENV_REPORT: ++ statsInfoEnvDisplay(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to detect if we can request firmware to feedback statistics. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] ucStaRecIndex The station index ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex) ++{ ++ STA_RECORD_T *prStaRec; ++ OS_SYSTIME rCurTime; ++ STATS_CMD_CORE_T rCmd; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); ++ if (prStaRec == NULL) ++ return; ++ ++ prStaRec->u4StatsEnvTxCnt++; ++ GET_CURRENT_SYSTIME(&rCurTime); ++ ++ if (prStaRec->rStatsEnvTxPeriodLastTime == 0) { ++ prStaRec->rStatsEnvTxLastTime = rCurTime; ++ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; ++ return; ++ } ++ ++ if (prStaRec->u4StatsEnvTxCnt > STATS_ENV_TX_CNT_REPORT_TRIGGER) { ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxLastTime, ++ SEC_TO_SYSTIME(STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC))) { ++ rCmd.ucStaRecIdx = ucStaRecIndex; ++ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); ++ ++ prStaRec->rStatsEnvTxLastTime = rCurTime; ++ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; ++ prStaRec->u4StatsEnvTxCnt = 0; ++ return; ++ } ++ } ++ ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxPeriodLastTime, SEC_TO_SYSTIME(STATS_ENV_TIMEOUT_SEC))) { ++ rCmd.ucStaRecIdx = ucStaRecIndex; ++ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); ++ ++ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle rx done. ++* ++* \param[in] prStaRec Pointer to the STA_RECORD_T structure ++* \param[in] prSwRfb Pointer to the received packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb) ++{ ++ UINT32 u4LenId; ++ UINT32 u4CurTime, u4DifTime; ++ ++ /* sanity check */ ++ if (prStaRec == NULL) ++ return; ++ ++ /* stats: rx done count */ ++ prStaRec->u4StatsRxPassToOsCnt++; ++ ++ /* get length partition ID */ ++ u4LenId = 0; ++ if (prSwRfb->u2PacketLen < STATS_STAY_INT_BYTE_THRESHOLD) { ++ u4LenId = 0; ++ } else { ++ if ((STATS_STAY_INT_BYTE_THRESHOLD <= prSwRfb->u2PacketLen) && ++ (prSwRfb->u2PacketLen < (STATS_STAY_INT_BYTE_THRESHOLD << 1))) { ++ u4LenId = 1; ++ } else ++ u4LenId = 2; ++ } ++ ++ /* stats: rx delay */ ++ u4CurTime = kalGetTimeTick(); ++ ++ if ((u4CurTime > prSwRfb->rRxTime) && (prSwRfb->rRxTime != 0)) { ++ u4DifTime = u4CurTime - prSwRfb->rRxTime; ++ ++ if (prStaRec->u4StayIntMinRx[u4LenId] == 0) /* impossible */ ++ prStaRec->u4StayIntMinRx[u4LenId] = 0xffffffff; ++ ++ if (u4DifTime > prStaRec->u4StayIntMaxRx[u4LenId]) ++ prStaRec->u4StayIntMaxRx[u4LenId] = u4DifTime; ++ else if (u4DifTime < prStaRec->u4StayIntMinRx[u4LenId]) ++ prStaRec->u4StayIntMinRx[u4LenId] = u4DifTime; ++ ++ prStaRec->u4StayIntAvgRx[u4LenId] += u4DifTime; ++ if (prStaRec->u4StayIntAvgRx[u4LenId] != u4DifTime) ++ prStaRec->u4StayIntAvgRx[u4LenId] >>= 1; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle rx done. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_64 StatsEnvTimeGet(VOID) ++{ ++ /* TODO: use better API to get time to save time, jiffies unit is 10ms, too large */ ++ ++/* struct timeval tv; */ ++ ++/* do_gettimeofday(&tv); */ ++/* return tv.tv_usec + tv.tv_sec * (UINT_64)1000000; */ ++ ++ UINT_64 u8Clk; ++/* UINT32 *pClk = &u8Clk; */ ++ ++ u8Clk = sched_clock(); /* unit: naro seconds */ ++/* printk(" sched_clock() = %x %x %u\n", pClk[0], pClk[1], sizeof(jiffies)); */ ++ ++ return (UINT_64) u8Clk; /* sched_clock *//* jiffies size = 4B */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle rx done. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader) ++{ ++ UINT_64 u8SysTime, u8SysTimeIn; ++ UINT32 u4TimeDiff; ++ ++ u8SysTime = StatsEnvTimeGet(); ++ u8SysTimeIn = GLUE_GET_PKT_XTIME(prMsduInfo->prPacket); ++ ++/* printk(" hif: 0x%x %u %u %u\n", */ ++/* prMsduInfo->prPacket, StatsEnvTimeGet(), u8SysTime, GLUE_GET_PKT_XTIME(prMsduInfo->prPacket)); */ ++ ++ if ((u8SysTimeIn > 0) && (u8SysTime > u8SysTimeIn)) { ++ u8SysTime = u8SysTime - u8SysTimeIn; ++ u4TimeDiff = (UINT32) u8SysTime; ++ u4TimeDiff = u4TimeDiff / 1000; /* ns to us */ ++ ++ /* pass the delay between OS to us and we to HIF */ ++ if (u4TimeDiff > 0xFFFF) ++ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) 0xFFFF; /* 65535 us */ ++ else ++ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) u4TimeDiff; ++ ++/* printk(" u4TimeDiff: %u\n", u4TimeDiff); */ ++ } else { ++ prHwTxHeader->aucReserved[0] = 0; ++ prHwTxHeader->aucReserved[1] = 0; ++ } ++} ++ ++static VOID statsParsePktInfo(PUINT_8 pucPkt, UINT_8 status, UINT_8 eventType, P_MSDU_INFO_T prMsduInfo) ++{ ++ /* get ethernet protocol */ ++ UINT_16 u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); ++ PUINT_8 pucEthBody = &pucPkt[ETH_HLEN]; ++ ++ switch (u2EtherType) { ++ case ETH_P_ARP: ++ { ++ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; ++ if (eventType == EVENT_TX) ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ if ((su2TxDoneCfg & CFG_ARP) == 0) ++ break; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(RX, INFO, " Arp Req From IP: %d.%d.%d.%d\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(RX, INFO, " Arp Rsp from IP: %d.%d.%d.%d\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ break; ++ case EVENT_TX: ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", status, ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", status, ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ break; ++ } ++ break; ++ } ++ case ETH_P_IP: ++ { ++ UINT_8 ucIpProto = pucEthBody[9]; /* IP header without options */ ++ UINT_8 ucIpVersion = (pucEthBody[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ UINT_16 u2IpId = pucEthBody[4]<<8 | pucEthBody[5]; ++ ++ if (ucIpVersion != IPVERSION) ++ break; ++ ++ switch (ucIpProto) { ++ case IP_PRO_ICMP: ++ { ++ /* the number of ICMP packets is seldom so we print log here */ ++ UINT_8 ucIcmpType; ++ UINT_16 u2IcmpId, u2IcmpSeq; ++ PUINT_8 pucIcmp = &pucEthBody[20]; ++ ++ ucIcmpType = pucIcmp[0]; ++ /* don't log network unreachable packet */ ++ if (((su2TxDoneCfg & CFG_ICMP) == 0) || ucIcmpType == 3) ++ break; ++ u2IcmpId = *(UINT_16 *) &pucIcmp[4]; ++ u2IcmpSeq = *(UINT_16 *) &pucIcmp[6]; ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " ICMP: Type %d, Id BE 0x%04x, Seq BE 0x%04x\n", ++ ucIcmpType, u2IcmpId, u2IcmpSeq); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " ICMP: Type %d, Id 0x04%x, Seq BE 0x%04x\n", ++ ucIcmpType, u2IcmpId, u2IcmpSeq); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " Type %d, Id 0x%04x, Seq 0x%04x\n", ++ status, ucIcmpType, u2IcmpId, u2IcmpSeq); ++ break; ++ } ++ break; ++ } ++ case IP_PRO_UDP: ++ { ++ /* the number of DHCP packets is seldom so we print log here */ ++ PUINT_8 pucUdp = &pucEthBody[20]; ++ PUINT_8 pucUdpPayload = &pucUdp[8]; ++ UINT_16 u2UdpDstPort; ++ UINT_16 u2UdpSrcPort; ++ ++ u2UdpDstPort = (pucUdp[2] << 8) | pucUdp[3]; ++ u2UdpSrcPort = (pucUdp[0] << 8) | pucUdp[1]; ++ /* dhcp */ ++ if ((u2UdpDstPort == UDP_PORT_DHCPS) || (u2UdpDstPort == UDP_PORT_DHCPC)) { ++ UINT_32 u4TransID = pucUdpPayload[4]<<24 | pucUdpPayload[5]<<16 | ++ pucUdpPayload[6]<<8 | pucUdpPayload[7]; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", ++ u2IpId, pucUdpPayload[0], u4TransID); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", ++ u2IpId, pucUdpPayload[0], u4TransID); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, ++ " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", ++ status, u2IpId, pucUdpPayload[0], u4TransID); ++ break; ++ } ++ } else if (u2UdpDstPort == UDP_PORT_DNS) { /* tx dns */ ++ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; ++ if (eventType == EVENT_TX) ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ if ((su2TxDoneCfg & CFG_DNS) == 0) ++ break; ++ if (eventType == EVENT_TX) { ++ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ } else if (eventType == EVENT_TX_DONE) ++ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", ++ status, u2IpId, u2TransId); ++ } else if (u2UdpSrcPort == UDP_PORT_DNS && eventType == EVENT_RX) { /* rx dns */ ++ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; ++ ++ if ((su2TxDoneCfg & CFG_DNS) == 0) ++ break; ++ DBGLOG(RX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); ++ } else if ((su2TxDoneCfg & CFG_UDP) != 0) { ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " UDP: IPID 0x%04x\n", u2IpId); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", u2IpId); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", status, u2IpId); ++ break; ++ } ++ } ++ break; ++ } ++ case IP_PRO_TCP: ++ if ((su2TxDoneCfg & CFG_TCP) == 0) ++ break; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " TCP: IPID 0x%04x\n", u2IpId); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", u2IpId); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", status, u2IpId); ++ break; ++ } ++ break; ++ } ++ break; ++ } ++ case ETH_P_PRE_1X: ++ DBGLOG(RX, INFO, "pre-1x\n"); ++ case ETH_P_1X: ++ { ++ PUINT_8 pucEapol = pucEthBody; ++ UINT_8 ucEapolType = pucEapol[1]; ++ ++ switch (ucEapolType) { ++ case 0: /* eap packet */ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " EAP Packet: code %d, id %d, type %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7]); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7]); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", ++ status, pucEapol[4], pucEapol[5], pucEapol[7]); ++ break; ++ } ++ break; ++ case 1: /* eapol start */ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " EAPOL: start\n"); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " EAPOL: start\n"); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " EAPOL: start\n", status); ++ break; ++ } ++ break; ++ case 3: /* key */ ++ { ++ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", ++ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", ++ u2KeyInfo, ++ pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", ++ status, u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], ++ pucEapol[20], pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); ++ break; ++ } ++ ++ break; ++ } ++ } ++ break; ++ } ++ case ETH_WPI_1X: ++ { ++ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ ++ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; ++ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ ucSubType, u2Length, u2Seq); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ ucSubType, u2Length, u2Seq); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ status, ucSubType, u2Length, u2Seq); ++ break; ++ } ++ break; ++ } ++ } ++} ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display rx packet information. ++* ++* \param[in] pPkt Pointer to the packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsRxPktInfoDisplay(UINT_8 *pPkt) ++{ ++ statsParsePktInfo(pPkt, 0, EVENT_RX, NULL); ++#if 0 /* carefully! too many ARP */ ++ if (pucIpHdr[0] == 0x00) { /* ARP */ ++ UINT_8 *pucDstIp = (UINT_8 *) pucIpHdr; ++ ++ if (pucDstIp[7] == ARP_PRO_REQ) { ++ DBGLOG(RX, TRACE, " OS rx a arp req from %d.%d.%d.%d\n", ++ pucDstIp[14], pucDstIp[15], pucDstIp[16], pucDstIp[17]); ++ } else if (pucDstIp[7] == ARP_PRO_RSP) { ++ DBGLOG(RX, TRACE, " OS rx a arp rsp from %d.%d.%d.%d\n", ++ pucDstIp[24], pucDstIp[25], pucDstIp[26], pucDstIp[27]); ++ } ++ } ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display tx packet information. ++* ++* \param[in] pPkt Pointer to the packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_16 u2EtherTypeLen; ++ ++ u2EtherTypeLen = (pPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pPkt[ETH_TYPE_LEN_OFFSET + 1]); ++ statsParsePktInfo(pPkt, 0, EVENT_TX, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle display tx packet tx done information. ++* ++* \param[in] pPkt Pointer to the packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf) ++{ ++ EVENT_TX_DONE_STATUS_T *prTxDone; ++ ++ prTxDone = (EVENT_TX_DONE_STATUS_T *) pucEvtBuf; ++ /* ++ * Why 65 Bytes: ++ * 8B + wlanheader(40B) + hif_tx_header(16B) + 6B + 6B(LLC) - 12B ++ */ ++ statsParsePktInfo(&prTxDone->aucPktBuf[64], prTxDone->ucStatus, EVENT_TX_DONE, NULL); ++} ++ ++VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet) ++{ ++ if (fgSet) ++ su2TxDoneCfg |= u2Cfg; ++ else ++ su2TxDoneCfg &= ~u2Cfg; ++} ++ ++UINT_16 StatsGetCfgTxDone(VOID) ++{ ++ return su2TxDoneCfg; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c +new file mode 100644 +index 000000000000..67eccbda9fa8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c +@@ -0,0 +1,1170 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/swcr.c#1 ++*/ ++ ++/*! \file "swcr.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: swcr.c ++ * ++ * 06 04 2012 tsaiyuan.hsu ++ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" ++ * resolve build waring for "WNM_UNIT_TEST not defined". ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 11 22 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * keep debug counter setting after wake up. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * fix debug counters of rx in driver. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters of bb and ar for xlog. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters, eCurPsProf, for PS. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 08 31 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * remove obsolete code. ++ * ++ * 08 15 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * add swcr in driver reg, 0x9fxx0000, to disable roaming . ++ * ++ * 05 11 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Fix dest type when GO packet copying. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 04 14 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Check the SW RFB free. Fix the compile warning.. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Fix Klockwork warning. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 01 11 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * Add swcr for test. ++ * ++* ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_SWCR ++ ++#ifdef __GNUC__ ++#pragma GCC diagnostic ignored "-Wformat" ++#endif ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if 0 ++SWCR_MOD_MAP_ENTRY_T g_arSwCrAllMaps[] = { ++ {SWCR_MAP_NUM(g_arRlmArSwCrMap), g_arRlmArSwCrMap}, /* 0x00nn */ ++ {0, NULL} ++}; ++#endif ++ ++UINT_32 g_au4SwCr[SWCR_CR_NUM]; /*: 0: command other: data */ ++ ++/* JB mDNS Filter*/ ++UINT_32 g_u4mDNSRXFilter = 0; /* [31] 0: stop 1: start, [3] IPv6 [2] IPv4 */ ++ ++static TIMER_T g_rSwcrDebugTimer; ++static BOOLEAN g_fgSwcrDebugTimer = FALSE; ++static UINT_32 g_u4SwcrDebugCheckTimeout; ++static ENUM_SWCR_DBG_TYPE_T g_ucSwcrDebugCheckType; ++static UINT_32 g_u4SwcrDebugFrameDumpType; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#define TEST_PS 1 ++ ++static const PFN_CMD_RW_T g_arSwCtrlCmd[] = { ++ swCtrlCmdCategory0, ++ swCtrlCmdCategory1 ++#if TEST_PS ++ , testPsCmdCategory0, testPsCmdCategory1 ++#endif ++#if CFG_SUPPORT_802_11V ++#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) ++ , testWNMCmdCategory0 ++#endif ++#endif ++}; ++ ++const PFN_SWCR_RW_T g_arSwCrModHandle[] = { ++ swCtrlSwCr, ++ NULL ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++enum { ++ SWCTRL_MAGIC, ++ SWCTRL_DEBUG, ++ SWCTRL_WIFI_VAR, ++ SWCTRL_ENABLE_INT, ++ SWCTRL_DISABLE_INT, ++ SWCTRL_TXM_INFO, ++ SWCTRL_RXM_INFO, ++ SWCTRL_DUMP_BSS, ++ SWCTRL_QM_INFO, ++ SWCTRL_DUMP_ALL_QUEUE_LEN, ++ SWCTRL_DUMP_MEM, ++ SWCTRL_TX_CTRL_INFO, ++ SWCTRL_DUMP_QUEUE, ++ SWCTRL_DUMP_QM_DBG_CNT, ++ SWCTRL_QM_DBG_CNT, ++ SWCTRL_RX_PKTS_DUMP, ++ SWCTRL_RX_MDNS_FILTER, ++ SWCTRL_CATA0_INDEX_NUM ++}; ++ ++enum { ++ SWCTRL_STA_INFO, ++ SWCTRL_DUMP_STA, ++ SWCTRL_STA_QUE_INFO, ++ SWCTRL_CATA1_INDEX_NUM ++}; ++ ++/* JB mDNS Filter*/ ++#define RX_MDNS_FILTER_START (1<<31) ++#define RX_MDNS_FILTER_IPV4 (1<<2) ++#define RX_MDNS_FILTER_IPV6 (1<<3) ++typedef enum _ENUM_SWCR_RX_MDNS_FILTER_CMD_T { ++ SWCR_RX_MDNS_FILTER_CMD_STOP = 0, ++ SWCR_RX_MDNS_FILTER_CMD_START, ++ SWCR_RX_MDNS_FILTER_CMD_ADD, ++ SWCR_RX_MDNS_FILTER_CMD_REMOVE, ++ SWCR_RX_MDNS_FILTER_NUM ++} ENUM_SWCR_RX_MDNS_FILTER_CMD_T; ++ ++#if TEST_PS ++enum { ++ TEST_PS_MAGIC, ++ TEST_PS_SETUP_BSS, ++ TEST_PS_ENABLE_BEACON, ++ TEST_PS_TRIGGER_BMC, ++ TEST_PS_SEND_NULL, ++ TEST_PS_BUFFER_BMC, ++ TEST_PS_UPDATE_BEACON, ++ TEST_PS_CATA0_INDEX_NUM ++}; ++ ++enum { ++ TEST_PS_STA_PS, ++ TEST_PS_STA_ENTER_PS, ++ TEST_PS_STA_EXIT_PS, ++ TEST_PS_STA_TRIGGER_PSPOLL, ++ TEST_PS_STA_TRIGGER_FRAME, ++ TEST_PS_CATA1_INDEX_NUM ++}; ++#endif ++ ++#if CFG_SUPPORT_802_11V ++#if WNM_UNIT_TEST ++enum { ++ TEST_WNM_TIMING_MEAS, ++ TEST_WNM_CATA0_INDEX_NUM ++}; ++#endif ++#endif ++ ++#define _SWCTRL_MAGIC 0x66201642 ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++void dumpQueue(P_ADAPTER_T prAdapter) ++{ ++ ++ P_TX_CTRL_T prTxCtrl; ++ P_QUE_MGT_T prQM; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 i; ++ UINT_32 j; ++ ++ DEBUGFUNC("dumpQueue"); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prQM = &prAdapter->rQM; ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ for (i = TC0_INDEX; i <= TC5_INDEX; i++) { ++ DBGLOG(SW4, INFO, "TC %u\n", i); ++ DBGLOG(SW4, INFO, "Max %u Free %u\n", ++ prTxCtrl->rTc.aucMaxNumOfBuffer[i], prTxCtrl->rTc.aucFreeBufferCount[i]); ++ ++ DBGLOG(SW4, INFO, "Average %u minReserved %u CurrentTcResource %u GuaranteedTcResource %u\n", ++ QM_GET_TX_QUEUE_LEN(prAdapter, i), ++ prQM->au4MinReservedTcResource[i], ++ prQM->au4CurrentTcResource[i], prQM->au4GuaranteedTcResource[i]); ++ ++ } ++ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { ++ DBGLOG(SW4, INFO, ++ "TC %u HeadStaIdx %u ForwardCount %u\n", i, prQM->au4HeadStaRecIndex[i], ++ prQM->au4ForwardCount[i]); ++ } ++ ++ DBGLOG(SW4, INFO, "BMC or unknown TxQueue Len %u\n", prQM->arTxQueue[0].u4NumElem); ++ DBGLOG(SW4, INFO, "Pending %d\n", prGlueInfo->i4TxPendingFrameNum); ++ DBGLOG(SW4, INFO, "Pending Security %d\n", prGlueInfo->i4TxPendingSecurityFrameNum); ++#if defined(LINUX) ++ for (i = 0; i < 4; i++) { ++ for (j = 0; j < CFG_MAX_TXQ_NUM; j++) { ++ DBGLOG(SW4, INFO, ++ "Pending Q[%u][%u] %d\n", i, j, prGlueInfo->ai4TxPendingFrameNumPerQueue[i][j]); ++ } ++ } ++#endif ++ ++ DBGLOG(SW4, INFO, " rFreeSwRfbList %u\n", prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ DBGLOG(SW4, INFO, " rReceivedRfbList %u\n", prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem); ++ DBGLOG(SW4, INFO, " rIndicatedRfbList %u\n", prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem); ++ DBGLOG(SW4, INFO, " ucNumIndPacket %u\n", prAdapter->rRxCtrl.ucNumIndPacket); ++ DBGLOG(SW4, INFO, " ucNumRetainedPacket %u\n", prAdapter->rRxCtrl.ucNumRetainedPacket); ++ ++} ++ ++void dumpSTA(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) ++{ ++ UINT_8 ucWTEntry; ++ UINT_32 i; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("dumpSTA"); ++ ++ ASSERT(prStaRec); ++ ucWTEntry = prStaRec->ucWTEntry; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ASSERT(prBssInfo); ++ ++ DBGLOG(SW4, INFO, "Mac address: %pM Rcpi %u" "\n", prStaRec->aucMacAddr, prStaRec->ucRCPI); ++ ++ DBGLOG(SW4, INFO, "Idx %u Wtbl %u Used %u State %u Bss Phy 0x%x Sta DesiredPhy 0x%x\n", ++ prStaRec->ucIndex, ucWTEntry, ++ prStaRec->fgIsInUse, prStaRec->ucStaState, ++ prBssInfo->ucPhyTypeSet, prStaRec->ucDesiredPhyTypeSet); ++ ++ DBGLOG(SW4, INFO, "Sta Operation 0x%x DesiredNontHtRateSet 0x%x Mcs 0x%x u2HtCapInfo 0x%x\n", ++ prStaRec->u2OperationalRateSet, prStaRec->u2DesiredNonHTRateSet, prStaRec->ucMcsSet, ++ prStaRec->u2HtCapInfo); ++ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) ++ DBGLOG(SW4, INFO, "TC %u Queue Len %u\n", i, prStaRec->arTxQueue[i].u4NumElem); ++ ++ DBGLOG(SW4, INFO, "BmpDeliveryAC %x\n", prStaRec->ucBmpDeliveryAC); ++ DBGLOG(SW4, INFO, "BmpTriggerAC %x\n", prStaRec->ucBmpTriggerAC); ++ DBGLOG(SW4, INFO, "UapsdSpSupproted %u\n", prStaRec->fgIsUapsdSupported); ++ DBGLOG(SW4, INFO, "IsQoS %u\n", prStaRec->fgIsQoS); ++ DBGLOG(SW4, INFO, "AssocId %u\n", prStaRec->u2AssocId); ++ ++ DBGLOG(SW4, INFO, "fgIsInPS %u\n", prStaRec->fgIsInPS); ++ DBGLOG(SW4, INFO, "ucFreeQuota %u\n", prStaRec->ucFreeQuota); ++ DBGLOG(SW4, INFO, "ucFreeQuotaForDelivery %u\n", prStaRec->ucFreeQuotaForDelivery); ++ DBGLOG(SW4, INFO, "ucFreeQuotaForNonDelivery %u\n", prStaRec->ucFreeQuotaForNonDelivery); ++ ++#if 0 ++ DBGLOG(SW4, INFO, "IsQmmSup %u\n", prStaRec->fgIsWmmSupported); ++ DBGLOG(SW4, INFO, "IsUapsdSup %u\n", prStaRec->fgIsUapsdSupported); ++ DBGLOG(SW4, INFO, "AvailabaleDeliverPkts %u\n", prStaRec->ucAvailableDeliverPkts); ++ DBGLOG(SW4, INFO, "BmpDeliverPktsAC %u\n", prStaRec->u4BmpDeliverPktsAC); ++ DBGLOG(SW4, INFO, "BmpBufferAC %u\n", prStaRec->u4BmpBufferAC); ++ DBGLOG(SW4, INFO, "BmpNonDeliverPktsAC %u\n", prStaRec->u4BmpNonDeliverPktsAC); ++#endif ++ ++ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { ++ if (prStaRec->aprRxReorderParamRefTbl[i]) { ++ DBGLOG(SW4, INFO, ++ "RxReorder fgIsValid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->fgIsValid); ++ DBGLOG(SW4, INFO, "RxReorder Tid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->ucTid); ++ DBGLOG(SW4, INFO, ++ "RxReorder rReOrderQue Len: %u\n", ++ prStaRec->aprRxReorderParamRefTbl[i]->rReOrderQue.u4NumElem); ++ DBGLOG(SW4, INFO, ++ "RxReorder WinStart: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinStart); ++ DBGLOG(SW4, INFO, "RxReorder WinEnd: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinEnd); ++ DBGLOG(SW4, INFO, "RxReorder WinSize: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinSize); ++ } ++ } ++ ++} ++ ++VOID dumpBss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ++ DBGLOG(SW4, INFO, "SSID %s\n", prBssInfo->aucSSID); ++ DBGLOG(SW4, INFO, "OWN %pM\n", prBssInfo->aucOwnMacAddr); ++ DBGLOG(SW4, INFO, "BSSID %pM\n", prBssInfo->aucBSSID); ++ DBGLOG(SW4, INFO, "ucNetTypeIndex %u\n", prBssInfo->ucNetTypeIndex); ++ DBGLOG(SW4, INFO, "eConnectionState %u\n", prBssInfo->eConnectionState); ++ DBGLOG(SW4, INFO, "eCurrentOPMode %u\n", prBssInfo->eCurrentOPMode); ++ DBGLOG(SW4, INFO, "fgIsQBSS %u\n", prBssInfo->fgIsQBSS); ++ DBGLOG(SW4, INFO, "fgIsShortPreambleAllowed %u\n", prBssInfo->fgIsShortPreambleAllowed); ++ DBGLOG(SW4, INFO, "fgUseShortPreamble %u\n", prBssInfo->fgUseShortPreamble); ++ DBGLOG(SW4, INFO, "fgUseShortSlotTime %u\n", prBssInfo->fgUseShortSlotTime); ++ DBGLOG(SW4, INFO, "ucNonHTBasicPhyType %x\n", prBssInfo->ucNonHTBasicPhyType); ++ DBGLOG(SW4, INFO, "u2OperationalRateSet %x\n", prBssInfo->u2OperationalRateSet); ++ DBGLOG(SW4, INFO, "u2BSSBasicRateSet %x\n", prBssInfo->u2BSSBasicRateSet); ++ DBGLOG(SW4, INFO, "ucPhyTypeSet %x\n", prBssInfo->ucPhyTypeSet); ++ DBGLOG(SW4, INFO, "rStaRecOfClientList %d\n", prBssInfo->rStaRecOfClientList.u4NumElem); ++ DBGLOG(SW4, INFO, "u2CapInfo %x\n", prBssInfo->u2CapInfo); ++ DBGLOG(SW4, INFO, "u2ATIMWindow %x\n", prBssInfo->u2ATIMWindow); ++ DBGLOG(SW4, INFO, "u2AssocId %x\n", prBssInfo->u2AssocId); ++ DBGLOG(SW4, INFO, "ucDTIMPeriod %x\n", prBssInfo->ucDTIMPeriod); ++ DBGLOG(SW4, INFO, "ucDTIMCount %x\n", prBssInfo->ucDTIMCount); ++ DBGLOG(SW4, INFO, "fgIsNetAbsent %x\n", prBssInfo->fgIsNetAbsent); ++ DBGLOG(SW4, INFO, "eBand %d\n", prBssInfo->eBand); ++ DBGLOG(SW4, INFO, "ucPrimaryChannel %d\n", prBssInfo->ucPrimaryChannel); ++ DBGLOG(SW4, INFO, "ucHtOpInfo1 %d\n", prBssInfo->ucHtOpInfo1); ++ DBGLOG(SW4, INFO, "ucHtOpInfo2 %d\n", prBssInfo->u2HtOpInfo2); ++ DBGLOG(SW4, INFO, "ucHtOpInfo3 %d\n", prBssInfo->u2HtOpInfo3); ++ DBGLOG(SW4, INFO, "fgErpProtectMode %d\n", prBssInfo->fgErpProtectMode); ++ DBGLOG(SW4, INFO, "eHtProtectMode %d\n", prBssInfo->eHtProtectMode); ++ DBGLOG(SW4, INFO, "eGfOperationMode %d\n", prBssInfo->eGfOperationMode); ++ DBGLOG(SW4, INFO, "eRifsOperationMode %d\n", prBssInfo->eRifsOperationMode); ++ DBGLOG(SW4, INFO, "fgObssErpProtectMode %d\n", prBssInfo->fgObssErpProtectMode); ++ DBGLOG(SW4, INFO, "eObssHtProtectMode %d\n", prBssInfo->eObssHtProtectMode); ++ DBGLOG(SW4, INFO, "eObssGfProtectMode %d\n", prBssInfo->eObssGfOperationMode); ++ DBGLOG(SW4, INFO, "fgObssRifsOperationMode %d\n", prBssInfo->fgObssRifsOperationMode); ++ DBGLOG(SW4, INFO, "fgAssoc40mBwAllowed %d\n", prBssInfo->fgAssoc40mBwAllowed); ++ DBGLOG(SW4, INFO, "fg40mBwAllowed %d\n", prBssInfo->fg40mBwAllowed); ++ DBGLOG(SW4, INFO, "eBssSCO %d\n", prBssInfo->eBssSCO); ++ ++} ++ ++VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ UINT_32 i; ++ ++ DEBUGFUNC("swCtrlCmdCategory0"); ++ ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ i = 0; ++ ++ if (ucIndex >= SWCTRL_CATA0_INDEX_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ switch (ucIndex) { ++ case SWCTRL_DEBUG: ++#if DBG ++ aucDebugModule[ucOpt0] = (UINT_8) g_au4SwCr[1]; ++#endif ++ break; ++ case SWCTRL_WIFI_VAR: ++ break; ++ ++#if QM_DEBUG_COUNTER ++ case SWCTRL_DUMP_QM_DBG_CNT: ++ for (i = 0; i < QM_DBG_CNT_NUM; i++) ++ prAdapter->rQM.au4QmDebugCounters[i] = 0; ++ break; ++ case SWCTRL_QM_DBG_CNT: ++ prAdapter->rQM.au4QmDebugCounters[ucOpt0] = g_au4SwCr[1]; ++ ++ break; ++#endif ++#if CFG_RX_PKTS_DUMP ++ case SWCTRL_RX_PKTS_DUMP: ++ /* DBGLOG(SW4, INFO,("SWCTRL_RX_PKTS_DUMP: mask %x\n", g_au4SwCr[1])); */ ++ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = g_au4SwCr[1]; ++ break; ++#endif ++ case SWCTRL_RX_MDNS_FILTER: ++ { ++ UINT_32 u4rxfilter; ++ BOOLEAN fgUpdate = FALSE; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_STOP) { ++ g_u4mDNSRXFilter &= ~(RX_MDNS_FILTER_START); ++ ++ u4rxfilter = prAdapter->u4OsPacketFilter; ++ fgUpdate = TRUE; ++ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_START) { ++ g_u4mDNSRXFilter |= (RX_MDNS_FILTER_START); ++ ++ u4rxfilter = prAdapter->u4OsPacketFilter; ++ if ((g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV4) || ++ (g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV6)) { ++ u4rxfilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; ++ } ++ fgUpdate = TRUE; ++ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_ADD) { ++ if (ucOpt1 < 31) ++ g_u4mDNSRXFilter |= (1 << ucOpt1); ++ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_REMOVE) { ++ if (ucOpt1 < 31) ++ g_u4mDNSRXFilter &= ~(1 << ucOpt1); ++ } ++ ++ if (fgUpdate == TRUE) { ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_RX_FILTER, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(UINT_32), /* u4SetQueryInfoLen */ ++ (PUINT_8)&u4rxfilter, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* un4SetQueryBufferLen */ ++ ); ++ } ++/* DBGLOG(SW4, INFO,("SWCTRL_RX_MDNS_FILTER: g_u4mDNSRXFilter %x ucOpt0 %x ucOpt1 %x fgUpdate %x u4rxfilter %x, */ ++/* rStatus %x\n", g_u4mDNSRXFilter, ucOpt0, ucOpt1, fgUpdate, u4rxfilter, rStatus)); */ ++ } ++ break; ++ default: ++ break; ++ } ++ } else { ++ switch (ucIndex) { ++ case SWCTRL_DEBUG: ++#if DBG ++ g_au4SwCr[1] = aucDebugModule[ucOpt0]; ++#endif ++ break; ++ case SWCTRL_MAGIC: ++ g_au4SwCr[1] = _SWCTRL_MAGIC; ++ /* DBGLOG(SW4, INFO, "BUILD TIME: %s %s\n", __DATE__, __TIME__); */ ++ break; ++ case SWCTRL_QM_INFO: ++ { ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ switch (ucOpt0) { ++ case 0: ++ g_au4SwCr[1] = (QM_GET_TX_QUEUE_LEN(prAdapter, ucOpt1)); ++ g_au4SwCr[2] = prQM->au4MinReservedTcResource[ucOpt1]; ++ g_au4SwCr[3] = prQM->au4CurrentTcResource[ucOpt1]; ++ g_au4SwCr[4] = prQM->au4GuaranteedTcResource[ucOpt1]; ++ break; ++ ++ case 1: ++ g_au4SwCr[1] = prQM->au4ForwardCount[ucOpt1]; ++ g_au4SwCr[2] = prQM->au4HeadStaRecIndex[ucOpt1]; ++ break; ++ ++ case 2: ++ g_au4SwCr[1] = prQM->arTxQueue[ucOpt1].u4NumElem; /* only one */ ++ ++ break; ++ } ++ ++ } ++ break; ++ case SWCTRL_TX_CTRL_INFO: ++ { ++ P_TX_CTRL_T prTxCtrl; ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ switch (ucOpt0) { ++ case 0: ++ g_au4SwCr[1] = prAdapter->rTxCtrl.rTc.aucFreeBufferCount[ucOpt1]; ++ g_au4SwCr[2] = prAdapter->rTxCtrl.rTc.aucMaxNumOfBuffer[ucOpt1]; ++ break; ++ } ++ ++ } ++ break; ++ case SWCTRL_DUMP_QUEUE: ++ dumpQueue(prAdapter); ++ ++ break; ++#if QM_DEBUG_COUNTER ++ case SWCTRL_DUMP_QM_DBG_CNT: ++ for (i = 0; i < QM_DBG_CNT_NUM; i++) ++ DBGLOG(SW4, INFO, "QM:DBG %u %u\n", i, prAdapter->rQM.au4QmDebugCounters[i]); ++ break; ++ ++ case SWCTRL_QM_DBG_CNT: ++ g_au4SwCr[1] = prAdapter->rQM.au4QmDebugCounters[ucOpt0]; ++ break; ++#endif ++ case SWCTRL_DUMP_BSS: ++ { ++ dumpBss(prAdapter, &(prAdapter->rWifiVar.arBssInfo[ucOpt0])); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ } ++} ++ ++VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ UINT_8 ucWTEntry; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("swCtrlCmdCategory1"); ++ ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ if (ucOpt0 >= CFG_STA_REC_NUM) ++ return; ++ ++ /* prStaRec = cnmGetStaRecByIndex (prAdapter, ucOpt0); */ ++ prStaRec = &prAdapter->arStaRec[ucOpt0]; ++ ucWTEntry = prStaRec->ucWTEntry; ++ if (ucRead == SWCR_WRITE) { ++ /* Do nothing */ ++ } else { ++ /* Read */ ++ switch (ucIndex) { ++ case SWCTRL_STA_QUE_INFO: ++ { ++ g_au4SwCr[1] = prStaRec->arTxQueue[ucOpt1].u4NumElem; ++ } ++ break; ++ case SWCTRL_STA_INFO: ++ switch (ucOpt1) { ++ case 0: ++ g_au4SwCr[1] = prStaRec->fgIsInPS; ++ break; ++ } ++ ++ break; ++ ++ case SWCTRL_DUMP_STA: ++ { ++ dumpSTA(prAdapter, prStaRec); ++ } ++ break; ++ ++ default: ++ ++ break; ++ } ++ } ++ ++} ++ ++#if TEST_PS ++ ++VOID ++testPsSendQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN UINT_8 ucUP, ++ IN UINT_8 ucNetTypeIndex, ++ IN BOOLEAN fgBMC, ++ IN BOOLEAN fgIsBurstEnd, IN BOOLEAN ucPacketType, IN BOOLEAN ucPsSessionID, IN BOOLEAN fgSetEOSP) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; ++ ++ DEBUGFUNC("testPsSendQoSNullFrame"); ++ DBGLOG(SW4, LOUD, "\n"); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ ++ /* Init with MGMT Header Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SW4, WARN, "No PKT_INFO_T for sending Null Frame.\n"); ++ return; ++ } ++ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ ++ bssComposeQoSNullFrame(prAdapter, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prStaRec, ucUP, fgSetEOSP); ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ /* prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; */ ++ prMsduInfo->ucPacketType = ucPacketType; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ prMsduInfo->fgIsBurstEnd = fgIsBurstEnd; ++ prMsduInfo->ucUserPriority = ucUP; ++ prMsduInfo->ucPsSessionID = ucPsSessionID /* 0~7 Test 7 means NOACK */; ++ ++ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) (((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD)); ++ ++ if (fgBMC) ++ prQoSNullFrame->aucAddr1[0] = 0xfd; ++ else ++ prQoSNullFrame->aucAddr1[5] = 0xdd; ++ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++} ++ ++VOID testPsSetupBss(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetworkTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; ++ ++ DEBUGFUNC("testPsSetupBss()"); ++ DBGLOG(SW4, INFO, "index %d\n", ucNetworkTypeIndex); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetworkTypeIndex]); ++ ++ /* 4 <1.2> Initiate PWR STATE */ ++ /* SET_NET_PWR_STATE_IDLE(prAdapter, ucNetworkTypeIndex); */ ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BSS_INFO_INIT(prAdapter, ucNetworkTypeIndex); ++ ++ prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; ++ prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; ++ prBssInfo->eCurrentOPMode = OP_MODE_ACCESS_POINT; ++ prBssInfo->fgIsNetActive = TRUE; ++ prBssInfo->ucNetTypeIndex = (ucNetworkTypeIndex); ++ prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; ++ ++ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; /* Depend on eBand */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->u2BSSBasicRateSet = RATE_SET_ERP; ++ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; ++ prBssInfo->fgErpProtectMode = FALSE; ++ prBssInfo->fgIsQBSS = TRUE; ++ ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prBssInfo->u2BeaconInterval = 100; ++ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; ++ prBssInfo->u2ATIMWindow = 0; ++ ++ prBssInfo->ucBeaconTimeoutCount = 0; ++ ++ bssInitForAP(prAdapter, prBssInfo, TRUE); ++ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, _aucZeroMacAddr); ++ LINK_INITIALIZE(&prBssInfo->rStaRecOfClientList); ++ prBssInfo->fgIsBeaconActivated = TRUE; ++ prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; ++ ++ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); ++ ++ /* 4 <3> Initiate BSS_INFO_T - private part */ ++ /* TODO */ ++ prBssInfo->eBand = BAND_2G4; ++ prBssInfo->ucPrimaryChannel = 1; ++ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ ++ /* prBssInfo->fgErpProtectMode = eErpProectMode; */ ++ /* prBssInfo->eHtProtectMode = eHtProtectMode; */ ++ /* prBssInfo->eGfOperationMode = eGfOperationMode; */ ++ ++ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ ++ prBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); ++ ++ if (prBssInfo->prBeacon) { ++ prBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; ++ prBssInfo->prBeacon->ucNetworkType = ucNetworkTypeIndex; ++ } else { ++ DBGLOG(SW4, INFO, "prBeacon allocation fail\n"); ++ } ++ ++#if 0 ++ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; ++ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; ++ prBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; ++#else ++ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; ++#endif ++ ++#if 0 ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prBssInfo->arACQueParms[eAci].fgIsACMSet = FALSE; ++ prBssInfo->arACQueParms[eAci].u2Aifsn = (UINT_16) eAci; ++ prBssInfo->arACQueParms[eAci].u2CWmin = 7; ++ prBssInfo->arACQueParms[eAci].u2CWmax = 31; ++ prBssInfo->arACQueParms[eAci].u2TxopLimit = eAci + 1; ++ DBGLOG(SW4, INFO, "MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", ++ eAci, prBssInfo->arACQueParms[eAci].fgIsACMSet, ++ prBssInfo->arACQueParms[eAci].u2Aifsn, ++ prBssInfo->arACQueParms[eAci].u2CWmin, ++ prBssInfo->arACQueParms[eAci].u2CWmax, prBssInfo->arACQueParms[eAci].u2TxopLimit)); ++ ++ } ++#endif ++ ++ DBGLOG(SW4, INFO, "[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", ++ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, ++ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, prBssInfo->rPmProfSetupInfo.ucUapsdSp); ++ ++} ++ ++VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("testPsCmdCategory0"); ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ DBGLOG(SW4, LOUD, "Read %u Index %u\n", ucRead, ucIndex); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, 0); ++ ++ if (ucIndex >= TEST_PS_CATA0_INDEX_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ switch (ucIndex) { ++ case TEST_PS_SETUP_BSS: ++ testPsSetupBss(prAdapter, ucOpt0); ++ break; ++ ++ case TEST_PS_ENABLE_BEACON: ++ break; ++ ++ case TEST_PS_TRIGGER_BMC: ++ /* txmForwardQueuedBmcPkts (ucOpt0); */ ++ break; ++ case TEST_PS_SEND_NULL: ++ { ++ ++ testPsSendQoSNullFrame(prAdapter, prStaRec, (UINT_8) (g_au4SwCr[1] & 0xFF), /* UP */ ++ ucOpt0, (BOOLEAN) ((g_au4SwCr[1] >> 8) & 0xFF), /* BMC */ ++ (BOOLEAN) ((g_au4SwCr[1] >> 16) & 0xFF), /* BurstEnd */ ++ (BOOLEAN) ((g_au4SwCr[1] >> 24) & 0xFF), /* Packet type */ ++ (UINT_8) ((g_au4SwCr[2]) & 0xFF), /* PS sesson ID 7: NOACK */ ++ FALSE /* EOSP */ ++ ); ++ } ++ break; ++ case TEST_PS_BUFFER_BMC: ++ /* g_aprBssInfo[ucOpt0]->fgApToBufferBMC = (g_au4SwCr[1] & 0xFF); */ ++ break; ++ case TEST_PS_UPDATE_BEACON: ++ bssUpdateBeaconContent(prAdapter, ucOpt0 /*networktype */); ++ break; ++ ++ default: ++ break; ++ } ++ } else { ++ switch (ucIndex) { ++ ++ case TEST_PS_MAGIC: ++ g_au4SwCr[1] = 0x88660011; ++ break; ++ ++ } ++ } ++} ++ ++#endif /* TEST_PS */ ++ ++#if TEST_PS ++ ++VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ UINT_8 ucWTEntry; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("testPsCmdCategory1"); ++ ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ if (ucOpt0 >= CFG_STA_REC_NUM) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucOpt0); ++ if (!prStaRec) ++ return; ++ ucWTEntry = prStaRec->ucWTEntry; ++ if (ucRead == SWCR_WRITE) { ++ ++ switch (ucIndex) { ++ case TEST_PS_STA_PS: ++ prStaRec->fgIsInPS = (BOOLEAN) (g_au4SwCr[1] & 0x1); ++ prStaRec->fgIsQoS = (BOOLEAN) (g_au4SwCr[1] >> 8 & 0xFF); ++ prStaRec->fgIsUapsdSupported = (BOOLEAN) (g_au4SwCr[1] >> 16 & 0xFF); ++ prStaRec->ucBmpDeliveryAC = (BOOLEAN) (g_au4SwCr[1] >> 24 & 0xFF); ++ break; ++ ++ } ++ ++ } else { ++ /* Read */ ++ switch (ucIndex) { ++ default: ++ break; ++ } ++ } ++ ++} ++ ++#endif /* TEST_PS */ ++ ++#if CFG_SUPPORT_802_11V ++#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) ++VOID testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("testWNMCmdCategory0"); ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ DBGLOG(SW4, INFO, "Read %u Index %u\n", ucRead, ucIndex); ++ ++ if (ucIndex >= TEST_WNM_CATA0_INDEX_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ switch (ucIndex) { ++ case TEST_WNM_TIMING_MEAS: ++ wnmTimingMeasUnitTest1(prAdapter, ucOpt0); ++ break; ++ ++ default: ++ break; ++ } ++ } ++} ++#endif /* TEST_WNM */ ++#endif /* CFG_SUPPORT_802_11V */ ++ ++VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) ++{ ++ /* According other register STAIDX */ ++ UINT_8 ucOffset; ++ ++ ucOffset = (u2Addr >> 2) & 0x3F; ++ ++ if (ucOffset >= SWCR_CR_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ g_au4SwCr[ucOffset] = *pu4Data; ++ if (ucOffset == 0x0) { ++ /* Commmand [31:24]: Category */ ++ /* Commmand [23:23]: 1(W) 0(R) */ ++ /* Commmand [22:16]: Index */ ++ /* Commmand [15:08]: Option0 */ ++ /* Commmand [07:00]: Option1 */ ++ UINT_8 ucCate; ++ UINT_32 u4Cmd; ++ ++ u4Cmd = g_au4SwCr[0]; ++ ucCate = (UINT_8) (u4Cmd >> 24); ++ if (ucCate < sizeof(g_arSwCtrlCmd) / sizeof(g_arSwCtrlCmd[0])) { ++ if (g_arSwCtrlCmd[ucCate] != NULL) { ++ g_arSwCtrlCmd[ucCate] (prAdapter, ucCate, (UINT_8) (u4Cmd >> 16 & 0xFF), ++ (UINT_8) ((u4Cmd >> 8) & 0xFF), (UINT_8) (u4Cmd & 0xFF)); ++ } ++ } ++ } ++ } else { ++ *pu4Data = g_au4SwCr[ucOffset]; ++ } ++} ++ ++VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) ++{ ++ UINT_8 ucMod; ++ ++ ucMod = u2Addr >> 8; ++ /* Address [15:8] MOD ID */ ++ /* Address [7:0] OFFSET */ ++ ++ DEBUGFUNC("swCrReadWriteCmd"); ++ DBGLOG(SW4, TRACE, "%u addr 0x%x data 0x%x\n", ucRead, u2Addr, *pu4Data); ++ ++ if (ucMod < (sizeof(g_arSwCrModHandle) / sizeof(g_arSwCrModHandle[0]))) { ++ ++ if (g_arSwCrModHandle[ucMod] != NULL) ++ g_arSwCrModHandle[ucMod] (prAdapter, ucRead, u2Addr, pu4Data); ++ } /* ucMod */ ++} ++ ++/* Debug Support */ ++VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType) ++{ ++ g_u4SwcrDebugFrameDumpType = u4DumpType; ++ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = u4DumpType; ++} ++ ++VOID swCrDebugInit(P_ADAPTER_T prAdapter) ++{ ++ /* frame dump */ ++ if (g_u4SwcrDebugFrameDumpType) ++ swCrFrameCheckEnable(prAdapter, g_u4SwcrDebugFrameDumpType); ++ /* debug counter */ ++ g_fgSwcrDebugTimer = FALSE; ++ ++ cnmTimerInitTimer(prAdapter, &g_rSwcrDebugTimer, (PFN_MGMT_TIMEOUT_FUNC) swCrDebugCheckTimeout, (ULONG) NULL); ++ ++ if (g_u4SwcrDebugCheckTimeout) ++ swCrDebugCheckEnable(prAdapter, TRUE, g_ucSwcrDebugCheckType, g_u4SwcrDebugCheckTimeout); ++} ++ ++VOID swCrDebugUninit(P_ADAPTER_T prAdapter) ++{ ++ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); ++ ++ g_fgSwcrDebugTimer = FALSE; ++} ++ ++VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout) ++{ ++ if (fgIsEnable) { ++ g_ucSwcrDebugCheckType = ucType; ++ g_u4SwcrDebugCheckTimeout = u4Timeout; ++ if (g_fgSwcrDebugTimer == FALSE) ++ swCrDebugCheckTimeout(prAdapter, 0); ++ } else { ++ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); ++ g_u4SwcrDebugCheckTimeout = 0; ++ } ++ ++ g_fgSwcrDebugTimer = fgIsEnable; ++} ++ ++VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ /* dump counters */ ++ if (prCmdSwCtrl) { ++ if (prCmdSwCtrl->u4Data == SWCR_DBG_TYPE_ALL) { ++ ++ /* TX Counter from fw */ ++ DBGLOG(SW4, INFO, "TX0\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_BCN_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_FAILED_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_RETRY_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_MGNT_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_ERROR_CNT]); ++#if 1 ++ /* TX Counter from drv */ ++ DBGLOG(SW4, INFO, "TX1\n" ++ "%08x %08x %08x %08x\n", ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_BSS_DROP), ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_STA_DROP), ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_FORWARD_OVERFLOW_DROP), ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_AP_BORADCAST_DROP)); ++#endif ++ ++ /* RX Counter */ ++ DBGLOG(SW4, INFO, "RX0\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DUP_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FCSERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FIFOFULL_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_PFDROP_CNT]); ++ ++ DBGLOG(SW4, INFO, "RX1\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT)); ++ ++ DBGLOG(SW4, INFO, "PWR\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PS_POLL_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_IND_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE0], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE1], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF0], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF1]); ++ ++ DBGLOG(SW4, INFO, "ARM\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RATE], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_BWGI], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ENABLE], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ROAM_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_INT_CNT]); ++ ++ DBGLOG(SW4, INFO, "BB\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_MDRDY_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_FCSERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_PD_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_PD_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SFDERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SIGERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT]); ++ ++ } ++ } ++ /* start the next check */ ++ if (g_u4SwcrDebugCheckTimeout) ++ cnmTimerStartTimer(prAdapter, &g_rSwcrDebugTimer, g_u4SwcrDebugCheckTimeout * MSEC_PER_SEC); ++} ++ ++VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ WLAN_STATUS rStatus; ++ ++ rCmdSwCtrl.u4Id = (0xb000 << 16) + g_ucSwcrDebugCheckType; ++ rCmdSwCtrl.u4Data = 0; ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SW_DBG_CTRL, /* ucCID */ ++ FALSE, /* fgSetQuery */ ++ TRUE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ swCrDebugQuery, /* pfCmdDoneHandler */ ++ swCrDebugQueryTimeout, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SW_DBG_CTRL_T), /* u4SetQueryInfoLen */ ++ (PUINT_8)&rCmdSwCtrl, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++} ++ ++VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ++ swCrDebugCheck(prAdapter, (P_CMD_SW_DBG_CTRL_T) (pucEventBuf)); ++} ++ ++VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ++ swCrDebugCheck(prAdapter, NULL); ++} ++ ++#endif /* CFG_SUPPORT_SWCR */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c +new file mode 100644 +index 000000000000..96293c57e2b0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c +@@ -0,0 +1,5199 @@ ++/* ++** Id: tdls.c#1 ++*/ ++ ++/*! \file tdls.c ++ \brief This file includes IEEE802.11z TDLS support. ++*/ ++ ++/* ++** Log: tdls.c ++ * ++ * 11 13 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++#include "precomp.h" ++ ++#if (CFG_SUPPORT_TDLS == 1) ++#include "gl_wext.h" ++#include "tdls.h" ++#include "gl_cfg80211.h" ++#include ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb); ++ ++#if TDLS_CFG_CMD_TEST ++static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static TDLS_STATUS ++TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd); ++ ++static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param); ++ ++static TDLS_STATUS ++TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static TDLS_STATUS ++TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static VOID ++TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, ++ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers); ++ ++static VOID ++TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, ++ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo); ++ ++static TDLS_STATUS ++TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++#endif /* TDLS_CFG_CMD_TEST */ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static BOOLEAN fgIsPtiTimeoutSkip = FALSE; ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to indicate packets to upper layer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prSkb A pointer to the received packet ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb) ++{ ++ struct net_device *prNetDev; ++ ++ /* init */ ++ prNetDev = prGlueInfo->prDevHandler; ++ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; ++ prGlueInfo->rNetDevStats.rx_packets++; ++ ++ /* pass to upper layer */ ++ //prNetDev->last_rx = jiffies; ++ prSkb->protocol = eth_type_trans(prSkb, prNetDev); ++ prSkb->dev = prNetDev; ++ ++ if (!in_interrupt()) ++ netif_rx_ni(prSkb); /* only in non-interrupt context */ ++ else ++ netif_rx(prSkb); ++} ++ ++#if TDLS_CFG_CMD_TEST ++ ++#define LR_TDLS_FME_FIELD_FILL(__Len) \ ++do { \ ++ pPkt += __Len; \ ++ u4PktLen += __Len; \ ++} while (0) ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to add a TDLS peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_2_[Responder MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_2_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ struct wireless_dev *prWdev; ++ ++ /* reset */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); ++ ++ /* init */ ++ rCmd.rPeerInfo.supported_rates = NULL; ++ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; ++ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ ++ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); ++ ++ /* send command to wifi task to handle */ ++ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; ++ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_16_[Enable/Disable]_[Set/Clear] ++ ++ iwpriv wlan0 set_str_cmd 0_16_1_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ TDLS_CMD_CORE_T rCmd; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); ++ ++ /* command to do this */ ++ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; ++ ++ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; ++ aucTdlsTestExtCapElm[1] = 5; ++ aucTdlsTestExtCapElm[2] = 0; ++ aucTdlsTestExtCapElm[3] = 0; ++ aucTdlsTestExtCapElm[4] = 0; ++ aucTdlsTestExtCapElm[5] = 0; ++ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 7); /* bit39 */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a channel switch request from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_5_[TDLS Peer MAC]_[Chan]_[RegulatoryClass]_ ++ [SecondaryChannelOffset]_[SwitchTime]_[SwitchTimeout] ++ ++ iwpriv wlan0 set_str_cmd 0_1_5_00:11:22:33:44:01_1_255_0_15000_30000 ++ ++ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) ++ Secondary Channel Offset: 0 (SCN - no secondary channel) ++ 1 (SCA - secondary channel above) ++ 2 (SCB - secondary channel below) ++ SwitchTime: units of microseconds ++ ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdChStReqRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4RegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4SecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s:[%pM]u4Chan=%u u4RegClass=%u u4SecChanOff=%u u4SwitchTime=%u u4SwitchTimeout=%u\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4Chan, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4RegClass, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SecChanOff, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTime, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestChStReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a channel switch response from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_6_[TDLS Peer MAC]_[Chan]_ ++ [SwitchTime]_[SwitchTimeout]_[StatusCode] ++ ++ iwpriv wlan0 set_str_cmd 0_1_6_00:11:22:33:44:01_11_15000_30000_0 ++ ++ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) ++ Secondary Channel Offset: 0 (SCN - no secondary channel) ++ 1 (SCA - secondary channel above) ++ 2 (SCB - secondary channel below) ++ SwitchTime: units of microseconds ++ ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdChStRspRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStRspRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStRspRcv.u4StatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4Chan=%u u4SwitchTime=%u u4SwitchTimeout=%u u4StatusCode=%u\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4Chan, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTime, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4StatusCode); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestChStRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip channel switch timeout function. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_11_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsTestChSwTimeoutSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a data frame to the peer periodically. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TIMER_T rTdlsTimerTestDataSend; ++static UINT_8 aucTdlsTestDataSPeerMac[6]; ++static UINT_16 u2TdlsTestDataSInterval; ++ ++static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ BOOLEAN fgIsEnabled; ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucTdlsTestDataSPeerMac); ++ u2TdlsTestDataSInterval = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ fgIsEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); ++ ++ if (fgIsEnabled == FALSE) { ++ /* stop test timer */ ++ return; ++ } ++ ++ /* re-init test timer */ ++ cnmTimerInitTimer(prAdapter, ++ &rTdlsTimerTestDataSend, (PFN_MGMT_TIMEOUT_FUNC) TdlsTimerTestDataContSend, (ULONG) NULL); ++ ++ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a data frame from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_0_x80_[TDLS Peer MAC]_[PM]_[UP]_[EOSP]_[IsNull] ++ ++ iwpriv wlan0 set_str_cmd 0_1_x80_00:11:22:33:44:01_0_0_0_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ rCmd.Content.rCmdDatRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdDatRcv.u4UP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdDatRcv.u4EOSP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdDatRcv.u4IsNull = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: [%pM] PM(%u) UP(%u) EOSP(%u) NULL(%u)\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdDatRcv.u4PM, ++ (UINT32) rCmd.Content.rCmdDatRcv.u4UP, ++ (UINT32) rCmd.Content.rCmdDatRcv.u4EOSP, (UINT32) rCmd.Content.rCmdDatRcv.u4IsNull); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestDataRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a data frame to the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_4_[Responder MAC]_[tx status] ++ ++ iwpriv wlan0 set_str_cmd 0_4_00:11:22:33:44:01_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ P_ADAPTER_T prAdapter; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *prPkt; ++ UINT_8 MAC[6]; ++ UINT_8 ucTxStatus; ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, MAC); ++ ucTxStatus = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ /* allocate a data frame */ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); ++ return; ++ } ++ ++ /* init dev */ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* init packet */ ++ prMsduInfo->len = 1000; ++ kalMemZero(prMsduInfo->data, 100); /* for QoS field */ ++ kalMemCopy(prMsduInfo->data, MAC, 6); ++ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); ++ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; ++ ++ /* simulate OS to send the packet */ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_16_[mili seconds] ++ ++ iwpriv wlan0 set_str_cmd 0_19_1000 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ UINT32 u4Delay; ++ ++ u4Delay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, "%s: Delay = %d\n", __func__, u4Delay); ++ ++ kalMdelay(u4Delay); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test discovery request frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_10_[DialogToken]_[Peer MAC]_[BSSID] ++ ++ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01 ++ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01_00:22:33:44:11:22 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); ++ kalMemZero(aucBSSID, sizeof(aucBSSID)); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_DISCOVERY_REQ; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; ++ ++ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ else ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip keep alive function. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_10_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_10_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsTestKeepAliveSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]_[Set/Clear] ++ ++ iwpriv wlan0 set_str_cmd 0_13_1_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ TDLS_CMD_CORE_T rCmd; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); ++ ++ /* command to do this */ ++ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; ++ ++ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; ++ aucTdlsTestExtCapElm[1] = 5; ++ aucTdlsTestExtCapElm[2] = 0; ++ aucTdlsTestExtCapElm[3] = 0; ++ aucTdlsTestExtCapElm[4] = 0; ++ aucTdlsTestExtCapElm[5] = 0; ++ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 6); /* bit38 */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI request from the AP. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_4_[TDLS Peer MAC]_[Dialog Token] ++ ++ iwpriv wlan0 set_str_cmd 0_1_4_00:11:22:33:44:01_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4DialogToken = %u\n", ++ __func__, rCmd.aucPeerMac, (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI response from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_9_[TDLS Peer MAC]_[Dialog Token]_[PM] ++ ++ iwpriv wlan0 set_str_cmd 0_1_9_00:11:22:33:44:01_0_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdPtiRspRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [%pM] u4DialogToken = %u %u\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken, ++ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4PM); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to simulate PTI tx done fail case. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_21_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_21_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdPtiTxFail.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdPtiTxFail.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiTxFail, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test frame. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++/* PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; */ ++/* TDLS_STATUS u4Status; */ ++ UINT_32 u4Subcmd; ++/* UINT_32 u4BufLen; */ ++ ++ /* parse sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " test rv frame sub command = %u\n", (UINT32) u4Subcmd); ++ ++ /* parse command arguments */ ++ switch (u4Subcmd) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ /* simulate to receive a setup request frame */ ++ TdlsCmdTestSetupReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ /* simulate to receive a setup response frame */ ++ TdlsCmdTestSetupRspRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_CONFIRM: ++ /* simulate to receive a setup confirm frame */ ++ TdlsCmdTestSetupConfirmRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_TEARDOWN: ++ /* simulate to receive a tear down frame */ ++ TdlsCmdTestTearDownRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_PTI: ++ /* simulate to receive a PTI request frame */ ++ TdlsCmdTestPtiReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_PTI_RSP: ++ /* simulate to receive a PTI response frame */ ++ TdlsCmdTestPtiRspRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_DATA_TEST_DATA: ++ /* simulate to receive a DATA frame */ ++ TdlsCmdTestDataRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_CHAN_SWITCH_REQ: ++ /* simulate to receive a channel switch request frame */ ++ TdlsCmdTestChSwReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_CHAN_SWITCH_RSP: ++ /* simulate to receive a channel switch response frame */ ++ TdlsCmdTestChSwRspRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_DISCOVERY_REQ: ++ /* simulate to receive a discovery request frame */ ++ TdlsCmdTestDiscoveryReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ default: ++ DBGLOG(TDLS, ERROR, " wrong test rv frame sub command\n"); ++ return; ++ } ++ ++/* if (u4Status != TDLS_STATUS_SUCCESS) */ ++ { ++/* DBGLOG(TDLS, ERROR, (" command parse fail\n")); */ ++/* return; */ ++ } ++ ++ /* send command to wifi task to handle */ ++#if 0 ++ kalIoctl(prGlueInfo, ++ TdlsTestFrameSend, ++ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test setup confirm frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_2_[DialogToken]_[StatusCode]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_1_2_1_0_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d StatusCode=%d from %pM\n", ++ __func__, ucDialogToken, ucStatusCode, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_CONFIRM; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Status Code */ ++ *pPkt = ucStatusCode; ++ *(pPkt + 1) = 0x00; ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 3. Frame Formation - (4) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (17) WMM Information element */ ++ if (prAdapter->rWifiVar.fgSupportQoS) { ++ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test setup request frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_0_[DialogToken]_[Peer MAC]_[BSSID] ++ ++ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01 ++ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01_00:22:33:44:11:22 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; ++ UINT_16 u2CapInfo; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); ++ kalMemZero(aucBSSID, sizeof(aucBSSID)); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_SETUP_REQ; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (4) Capability */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); ++ WLAN_SET_FIELD_16(pPkt, u2CapInfo); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (10) Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ /* TDLS_EX_CAP_PEER_UAPSD */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ /* TDLS_EX_CAP_CHAN_SWITCH */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ /* TDLS_EX_CAP_TDLS */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; ++ ++ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ else ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test setup response frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_1_[DialogToken]_[StatusCode]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_1_1_1_0_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; ++ UINT_16 u2CapInfo; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d StatusCode=%d from %pM\n", ++ __func__, ucDialogToken, ucStatusCode, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_SETUP_RSP; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Status Code */ ++ *pPkt = ucStatusCode; ++ *(pPkt + 1) = 0x00; ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 3. Frame Formation - (4) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (5) Capability */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); ++ WLAN_SET_FIELD_16(pPkt, u2CapInfo); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (10) Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ /* TDLS_EX_CAP_PEER_UAPSD */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ /* TDLS_EX_CAP_CHAN_SWITCH */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ /* TDLS_EX_CAP_TDLS */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip channel switch timeout function. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_14_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_14_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdScanSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdScanSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestScanSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test tear down frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_3_[IsInitiator]_[ReasonCode]_[Peer MAC]_[Where] ++ ++ Where 0 (From driver) or 1 (From FW) ++ ++ iwpriv wlan0 set_str_cmd 0_1_3_1_26_00:11:22:33:44:01_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ BOOLEAN fgIsInitiator; ++ UINT_8 ucReasonCode, aucPeerMac[6]; ++ BOOLEAN fgIsFromWhich; ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ fgIsInitiator = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ucReasonCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ fgIsFromWhich = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: ReasonCode=%d from %pM %d\n", ++ __func__, ucReasonCode, aucPeerMac, fgIsFromWhich); ++ ++ if (fgIsFromWhich == 0) { ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_TEARDOWN; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Reason Code */ ++ *pPkt = ucReasonCode; ++ *(pPkt + 1) = 0x00; ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ if (fgIsInitiator == 1) { ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ } else { ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); ++ } ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++ } else { ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ kalMemCopy(rCmd.aucPeerMac, aucPeerMac, 6); ++ rCmd.Content.rCmdTearDownRcv.u4ReasonCode = (UINT32) ucReasonCode; ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsTestTearDownRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip tx fail case. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_7_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_7_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdTxFailSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdTxFailSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestTxFailSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a test frame command to wifi task. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 ++* ++* EX: iwpriv wlan0 set_str_cmd 0_12_2_[FrameType]_[DialogToken]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_12_2_0_1_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ UINT32 u4Subcmd; ++ UINT_32 u4BufLen; ++ ++ /* parse sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " test tx tdls frame sub command = %u\n", u4Subcmd); ++ ++ /* parse command arguments */ ++ rCmd.ucFmeType = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); ++ ++ switch (u4Subcmd) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_CONFIRM: ++ rCmd.ucToken = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); ++ ++ DBGLOG(TDLS, INFO, " setup FmeType=%d Token=%d to [%pM]\n", ++ rCmd.ucFmeType, rCmd.ucToken, rCmd.arRspAddr); ++ break; ++ ++ default: ++ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); ++ return; ++ } ++ ++ /* send command to wifi task to handle */ ++ kalIoctl(prGlueInfo, ++ TdlsTestTdlsFrameSend, ++ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a test frame command to wifi task. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ ++ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ ++ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ ++ [Timeout]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ TDLS_STATUS u4Status; ++ UINT_32 u4Subcmd; ++ UINT_32 u4BufLen; ++ ++ /* parse sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " test tx frame sub command = %u\n", (UINT32) u4Subcmd); ++ ++ /* parse command arguments */ ++ switch (u4Subcmd) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ u4Status = TdlsCmdTestTxFmeSetupReqBufTranslate(prInBuf, u4InBufLen, &rCmd); ++ break; ++ ++ default: ++ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); ++ return; ++ } ++ ++ if (u4Status != TDLS_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, " command parse fail\n"); ++ return; ++ } ++ ++ /* send command to wifi task to handle */ ++ kalIoctl(prGlueInfo, ++ TdlsTestFrameSend, ++ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse the TDLS test frame command, setup request ++* ++* @param CmdBuf Pointer to the buffer. ++* @param BufLen Record buffer length. ++* @param CmdTspec Pointer to the structure. ++* ++* @retval WLAN_STATUS_SUCCESS: Translate OK. ++* @retval WLAN_STATUS_FAILURE: Translate fail. ++* @usage iwpriv wlan0 set_str_cmd [tdls]_[command] ++* ++* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ ++ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ ++ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ ++ [Timeout]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd) ++{ ++/* dumpMemory8(ANDROID_LOG_INFO, pCmdBuf, u4BufLen); */ ++ ++ prCmd->ucFmeType = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->ucToken = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->u2Cap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->ucExCap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->u4Timeout = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ CmdStringMacParse(pCmdBuf, &pCmdBuf, &u4BufLen, prCmd->arRspAddr); ++ ++ DBGLOG(TDLS, INFO, " command content =\n"); ++ DBGLOG(TDLS, INFO, "\tPeer MAC = %pM\n", (prCmd->arRspAddr)); ++ DBGLOG(TDLS, INFO, "\tToken = %u, Cap = 0x%x, ExCap = 0x%x, Timeout = %us FrameType = %u\n", ++ (UINT32) prCmd->ucToken, prCmd->u2Cap, prCmd->ucExCap, ++ (UINT32) prCmd->u4Timeout, (UINT32) prCmd->ucFmeType); ++ DBGLOG(TDLS, INFO, "\tSupRate = 0x%x %x %x %x\n", ++ prCmd->arSupRate[0], prCmd->arSupRate[1], prCmd->arSupRate[2], prCmd->arSupRate[3]); ++ DBGLOG(TDLS, INFO, "\tSupChan = %d %d %d %d\n", ++ prCmd->arSupChan[0], prCmd->arSupChan[1], prCmd->arSupChan[2], prCmd->arSupChan[3]); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update a TDLS peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_3_[Responder MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_3_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ struct wireless_dev *prWdev; ++ ++ /* reset */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); ++ ++ /* init */ ++ rCmd.rPeerInfo.supported_rates = rCmd.arSupRate; ++ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; ++ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ ++ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); ++ rCmd.rPeerInfo.uapsd_queues = 0xf; /* all AC */ ++ rCmd.rPeerInfo.max_sp = 0; /* delivery all packets */ ++ ++ /* send command to wifi task to handle */ ++ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; ++ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); ++ ++ /* update */ ++ TdlsexCfg80211TdlsOper(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, NL80211_TDLS_ENABLE_LINK); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Null frame from the peer. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++* EX: iwpriv wlan0 set_str_cmd 0_5_[Responder MAC]_[PM bit] ++ ++ iwpriv wlan0 set_str_cmd 0_5_00:11:22:33:44:01_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ rCmd.Content.rCmdNullRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [%pM] u4PM = %u\n", ++ __func__, (rCmd.aucPeerMac), (UINT32) rCmd.Content.rCmdNullRcv.u4PM); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestNullRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a data frame to the peer periodically. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] u4Param no use ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_15_[Responder MAC]_[Interval: ms]_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_15_00:11:22:33:44:01_5000_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *prPkt; ++ ++ /* init */ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* allocate a data frame */ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); ++ return; ++ } ++ ++ /* init dev */ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* init packet */ ++ prMsduInfo->len = 1000; ++ kalMemCopy(prMsduInfo->data, aucTdlsTestDataSPeerMac, 6); ++ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); ++ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; ++ ++ DBGLOG(TDLS, INFO, " %s try to send a data frame to %pM\n", ++ __func__, aucTdlsTestDataSPeerMac); ++ ++ /* simulate OS to send the packet */ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++ ++ /* restart test timer */ ++ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Channel Switch Request frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_REQ; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Channel Switch Response frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_RSP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send a test frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if (u4SetBufferLen == 0) ++ return TDLS_STATUS_INVALID_LENGTH; ++ ++ /* allocate/init packet */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ *pu4SetInfoLen = u4SetBufferLen; ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prCmd->arRspAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = prCmd->ucFmeType; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ *pPkt = prCmd->ucToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (4) Capability */ ++ WLAN_SET_FIELD_16(pPkt, prCmd->u2Cap); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (10) Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */ ++ TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL; ++ TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5; ++ ++ TIMEOUT_INTERVAL_IE(pPkt)->ucType = IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; ++ TIMEOUT_INTERVAL_IE(pPkt)->u4Value = htonl(prCmd->u4Timeout); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prCmd->arRspAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* 5. send the data frame */ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a NULL frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_NULL_RCV; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_REQ; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI response frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_RSP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Tear Down frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TEAR_DOWN; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a data frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_DATA_RCV; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip PTI tx fail status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_TX_FAIL; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send a TDLS action frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; ++ struct wireless_dev *prWdev; ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if (u4SetBufferLen == 0) ++ return TDLS_STATUS_INVALID_LENGTH; ++ ++ /* allocate/init packet */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; ++ prWdev = (struct wireless_dev *)prGlueInfo->prDevHandler->ieee80211_ptr; ++ ++ TdlsexCfg80211TdlsMgmt(prWdev->wiphy, NULL, ++ prCmd->arRspAddr, prCmd->ucFmeType, 1, ++ 0, 0, /* open/none */ ++ FALSE, NULL, 0); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip tx fail status. So always success in tx done in firmware. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TX_FAIL_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip to do keep alive function in firmware. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip channel switch timeout. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip scan request. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_SCAN_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++#endif /* TDLS_CFG_CMD_TEST */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure channel switch parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_CHSW_CONF; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update channel switch parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_9_[TDLS Peer MAC]_ ++ [NetworkTypeIndex]_[1 (Enable) or (0) Disable]_[1 (Start) or 0 (Stop)]_ ++ [RegClass]_[Chan]_[SecChanOff]_[1 (Reqular) or (0) One Shot] ++ ++ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) ++ Secondary Channel Offset: 0 (SCN - no secondary channel) ++ 1 (SCA - secondary channel above) ++ 2 (SCB - secondary channel below) ++ SwitchTime: units of microseconds ++ ++ iwpriv wlan0 set_str_cmd 0_9_00:11:22:33:44:01_0_1_0_0_1_0_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.fgIsChSwStarted = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.ucRegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.ucTargetChan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.ucSecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.fgIsChSwRegular = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: %pM ucNetTypeIndex=%d, fgIsChSwEnabled=%d, fgIsChSwStarted=%d", ++ __func__, (rCmd.aucPeerMac), ++ rCmd.Content.rCmdChSwConf.ucNetTypeIndex, ++ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled, ++ rCmd.Content.rCmdChSwConf.fgIsChSwStarted); ++ DBGLOG(TDLS, INFO, " RegClass=%d, TargetChan=%d, SecChanOff=%d, Regular=%d\n", ++ rCmd.Content.rCmdChSwConf.ucRegClass, ++ rCmd.Content.rCmdChSwConf.ucTargetChan, ++ rCmd.Content.rCmdChSwConf.ucSecChanOff, rCmd.Content.rCmdChSwConf.fgIsChSwRegular); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsChSwConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display TDLS related information. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_18_[Peer MAC]_[Network Interface ID]_[IsClear] ++ ++ Network Interface ID: reference to ENUM_NETWORK_TYPE_INDEX_T ++ ++ typedef enum _ENUM_NETWORK_TYPE_INDEX_T { ++ NETWORK_TYPE_AIS_INDEX = 0, ++ NETWORK_TYPE_P2P_INDEX, ++ NETWORK_TYPE_BOW_INDEX, ++ NETWORK_TYPE_INDEX_NUM ++ } ENUM_NETWORK_TYPE_INDEX_T; ++ ++ iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ rCmd.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdInfoDisplay.fgIsToClearAllHistory = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, " %s: Command PeerMac=%pM in BSS%u\n", ++ __func__, (rCmd.aucPeerMac), rCmd.ucNetTypeIndex); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display key related information. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_20 ++ ++ iwpriv wlan0 set_str_cmd 0_20 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsKeyInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update MIB parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_6_[TdlsEn]_[UapsdEn]_[PsmEn]_[PtiWin]_[CWCap]_ ++ [AckMisRetry]_[RspTimeout]_[CWPbDelay]_[DRWin]_[LowestAcInt] ++ ++ iwpriv wlan0 set_str_cmd 0_6_1_1_0_1_1_3_5_1000_2_1 ++ ++ reference to TDLS_CMD_CORE_MIB_PARAM_UPDATE_T ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* reset */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ /* parse arguments */ ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, " MIB param = %d %d %d %d %d %d %d %d %d %d\n", ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsMibParamUpdate, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update setup parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_17_[20/40 Support] ++ ++ iwpriv wlan0 set_str_cmd 0_17_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ ++ rCmd.Content.rCmdSetupConf.fgIs2040Supported = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: rCmdSetupConf=%d\n", __func__, rCmd.Content.rCmdSetupConf.fgIs2040Supported); ++ ++ /* command to do this */ ++ prGlueInfo->rTdlsLink.fgIs2040Sup = rCmd.Content.rCmdSetupConf.fgIs2040Supported; ++ ++ rStatus = kalIoctl(prGlueInfo, TdlsSetupConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update UAPSD parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_8_[SP timeout skip]_[PTI timeout skip] ++ ++ iwpriv wlan0 set_str_cmd 0_8_1_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ ++ /* UAPSD Service Period */ ++ rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ /* PTI Service Period */ ++ fgIsPtiTimeoutSkip = rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip; ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsSpTimeoutSkip=%d, fgIsPtiTimeoutSkip=%d\n", ++ __func__, rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip, fgIsPtiTimeoutSkip); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsUapsdConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display TDLS all information. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++* iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_CORE_T *prCmdContent; ++ STA_RECORD_T *prStaRec; ++ TDLS_INFO_LINK_T *prLink; ++ UINT32 u4StartIdx; ++ UINT32 u4PeerNum; ++ BOOLEAN fgIsListAll; ++ UINT8 ucMacZero[6]; ++ UINT32 u4HisIdx; ++ UINT8 ucNetTypeIndex; ++ ++ /* init */ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ u4StartIdx = 0; ++ u4PeerNum = 1; ++ fgIsListAll = TRUE; ++ kalMemZero(ucMacZero, sizeof(ucMacZero)); ++ ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ ++ /* display common information */ ++ DBGLOG(TDLS, TRACE, "TDLS common:\n"); ++ DBGLOG(TDLS, TRACE, "\t\trFreeSwRfbList=%u\n", (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ DBGLOG(TDLS, TRACE, "\t\tjiffies=%u %ums (HZ=%d)\n", (UINT32) jiffies, (UINT32) kalGetTimeTick(), HZ); ++ ++ /* display disconnection history information */ ++ DBGLOG(TDLS, TRACE, "TDLS link history: %d\n", prGlueInfo->rTdlsLink.u4LinkIdx); ++ ++ for (u4HisIdx = prGlueInfo->rTdlsLink.u4LinkIdx + 1; u4HisIdx < TDLS_LINK_HISTORY_MAX; u4HisIdx++) { ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; ++ ++ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) ++ continue; /* skip all zero */ ++ ++ DBGLOG(TDLS, TRACE, ++ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", ++ u4HisIdx, prLink->aucPeerMac, ++ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), ++ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), ++ prLink->ucReasonCode, ++ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); ++ ++ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { ++ DBGLOG(TDLS, TRACE, ++ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", ++ prLink->ucHtBa[0], prLink->ucHtBa[1], ++ prLink->ucHtBa[2], prLink->ucHtBa[3], ++ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); ++ } ++ } ++ for (u4HisIdx = 0; u4HisIdx <= prGlueInfo->rTdlsLink.u4LinkIdx; u4HisIdx++) { ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; ++ ++ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) ++ continue; /* skip all zero, use continue, not break */ ++ ++ DBGLOG(TDLS, TRACE, ++ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", ++ u4HisIdx, (prLink->aucPeerMac), ++ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), ++ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), ++ prLink->ucReasonCode, ++ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); ++ ++ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { ++ DBGLOG(TDLS, TRACE, ++ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", ++ prLink->ucHtBa[0], prLink->ucHtBa[1], ++ prLink->ucHtBa[2], prLink->ucHtBa[3], ++ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); ++ } ++ } ++ DBGLOG(TDLS, TRACE, "\n"); ++ ++ /* display link information */ ++ if (prCmdContent != NULL) { ++ if (kalMemCmp(prCmdContent->aucPeerMac, ucMacZero, 6) != 0) { ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ prCmdContent->ucNetTypeIndex, prCmdContent->aucPeerMac); ++ if (prStaRec == NULL) ++ fgIsListAll = TRUE; ++ } ++ ++ ucNetTypeIndex = prCmdContent->ucNetTypeIndex; ++ } ++ ++ while (1) { ++ if (fgIsListAll == TRUE) { ++ /* list all TDLS peers */ ++ prStaRec = cnmStaTheTypeGet(prAdapter, ucNetTypeIndex, STA_TYPE_TDLS_PEER, &u4StartIdx); ++ if (prStaRec == NULL) ++ break; ++ } ++ ++ DBGLOG(TDLS, TRACE, "-------- TDLS %d: 0x %pM\n", u4PeerNum, (prStaRec->aucMacAddr)); ++ DBGLOG(TDLS, TRACE, "\t\t\t State %d, PM %d, Cap 0x%x\n", ++ prStaRec->ucStaState, prStaRec->fgIsInPS, prStaRec->u2CapInfo); ++ DBGLOG(TDLS, TRACE, "\t\t\t SetupDisable %d, ChSwDisable %d\n", ++ prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); ++ ++ if (fgIsListAll == FALSE) ++ break; /* only list one */ ++ } ++ ++ /* check if we need to clear all histories */ ++ if ((prCmdContent != NULL) && (prCmdContent->Content.rCmdInfoDisplay.fgIsToClearAllHistory == TRUE)) { ++ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); ++ prGlueInfo->rTdlsLink.u4LinkIdx = TDLS_LINK_HISTORY_MAX - 1; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display key information. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_KEY_INFO; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to record a disconnection event. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure ++* \param[in] fgIsTearDown TRUE: the link is torn down ++* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] fgIsFromUs TRUE: tear down is from us ++* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, ++ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers) ++{ ++ TDLS_INFO_LINK_T *prLink; ++ ++ DBGLOG(TDLS, INFO, ++ " %s: record history for %pM %d %d %d %d\n", ++ __func__, pucPeerMac, prGlueInfo->rTdlsLink.u4LinkIdx, ++ fgIsTearDown, fgIsFromUs, u2ReasonCode); ++ ++ /* check duplicate one */ ++ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) { ++ DBGLOG(TDLS, ERROR, " %s: u4LinkIdx >= TDLS_LINK_HISTORY_MAX\n", __func__); ++ ++ /* reset to 0 */ ++ prGlueInfo->rTdlsLink.u4LinkIdx = 0; ++ } ++ ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; ++ ++ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) == 0) { ++ if ((prLink->ucReasonCode == u2ReasonCode) && (prLink->fgIsFromUs == fgIsFromUs)) { ++ /* same Peer MAC, Reason Code, Trigger source */ ++ if (fgIsTearDown == TRUE) { ++ if (prLink->jiffies_end != 0) { ++ /* already torn down */ ++ prLink->ucDupCount++; ++ return; ++ } ++ } else { ++ /* already built */ ++ prLink->ucDupCount++; ++ return; ++ } ++ } ++ } ++ ++ /* search old entry */ ++ if (fgIsTearDown == TRUE) { ++ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ ++ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { ++ /* error! can not find the link entry */ ++ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); ++ return; ++ } ++ ++ prLink->jiffies_end = jiffies; ++ prLink->ucReasonCode = (UINT8) u2ReasonCode; ++ prLink->fgIsFromUs = fgIsFromUs; ++ } else { ++ /* record new one */ ++ prGlueInfo->rTdlsLink.u4LinkIdx++; ++ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) ++ prGlueInfo->rTdlsLink.u4LinkIdx = 0; ++ ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; ++ ++ prLink->jiffies_start = jiffies; ++ prLink->jiffies_end = 0; ++ kalMemCopy(&prLink->aucPeerMac, pucPeerMac, 6); ++ prLink->ucReasonCode = 0; ++ prLink->fgIsFromUs = (UINT8) fgIsFromUs; ++ prLink->ucDupCount = 0; ++ ++ if (prOthers != NULL) { ++ /* record other parameters */ ++ TDLS_LINK_HIS_OTHERS_T *prHisOthers; ++ ++ prHisOthers = (TDLS_LINK_HIS_OTHERS_T *) prOthers; ++ if (prHisOthers->fgIsHt == TRUE) ++ prLink->ucHtCap |= TDLS_INFO_LINK_HT_CAP_SUP; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update a disconnection event. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure ++* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] eFmeStatus TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME ++* \param[in] pInfo other information ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, ++ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo) ++{ ++ TDLS_INFO_LINK_T *prLink; ++ UINT32 u4LinkIdx; ++ UINT32 u4Tid; ++ ++ /* sanity check */ ++ if ((eFmeStatus < TDLS_HOST_EVENT_SF_BA) || (eFmeStatus > TDLS_HOST_EVENT_SF_BA_RSP_DECLINE)) { ++ /* do not care these frames */ ++ return; ++ } ++ ++ DBGLOG(TDLS, INFO, ++ " %s: update history for %pM %d %d\n", ++ __func__, (pucPeerMac), prGlueInfo->rTdlsLink.u4LinkIdx, eFmeStatus); ++ ++ /* init */ ++ u4LinkIdx = prGlueInfo->rTdlsLink.u4LinkIdx; ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4LinkIdx]; ++ ++ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ ++ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { ++ /* error! can not find the link entry */ ++ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); ++ return; ++ } ++ ++ /* update */ ++ u4Tid = *(UINT32 *) pInfo; ++ switch (eFmeStatus) { ++ case TDLS_HOST_EVENT_SF_BA: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_OK: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_OK; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_DECLINE: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_DECLINE; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_PEER: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_PEER; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_RSP_OK: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_OK; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_RSP_DECLINE: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_DECLINE; ++ break; ++ } ++ ++ /* display TDLS link history */ ++ TdlsInfoDisplay(prGlueInfo->prAdapter, NULL, 0, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure TDLS MIB parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_MIB_UPDATE; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure TDLS SETUP parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_SETUP_CONF; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure UAPSD parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_UAPSD_CONF; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update frame status. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventFmeStatus(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus; ++ STA_RECORD_T *prStaRec; ++ UINT32 u4Tid; ++ ++ /* init */ ++ u4Tid = *(UINT32 *) prInBuf; ++ prInBuf += 4; /* skip u4EventSubId */ ++ ++ /* sanity check */ ++ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); ++ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) ++ return; ++ prInBuf++; ++ ++ /* update status */ ++ eFmeStatus = *prInBuf; ++ TdlsLinkHistoryRecordUpdate(prGlueInfo, prStaRec->aucMacAddr, eFmeStatus, &u4Tid); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to collect TDLS statistics from firmware. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ STA_RECORD_T *prStaRec; ++ STAT_CNT_INFO_FW_T *prStat; ++ UINT32 u4RateId; ++ ++ /* init */ ++ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); ++ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) ++ return; ++ ++ prInBuf += 4; /* skip prStaRec->ucIndex */ ++ ++ /* update statistics */ ++ kalMemCopy(&prStaRec->rTdlsStatistics.rFw, prInBuf, sizeof(prStaRec->rTdlsStatistics.rFw)); ++ ++ /* display statistics */ ++ prStat = &prStaRec->rTdlsStatistics.rFw; ++ ++ DBGLOG(TDLS, TRACE, " peer [%pM] statistics:\n", (prStaRec->aucMacAddr)); ++ DBGLOG(TDLS, TRACE, "\t\tT%d %d %d (P%d %d) (%dus) - E%d 0x%x - R%d (P%d)\n", ++ prStat->u4NumOfTx, prStat->u4NumOfTxOK, prStat->u4NumOfTxRetry, ++ prStat->u4NumOfPtiRspTxOk, prStat->u4NumOfPtiRspTxErr, ++ prStat->u4TxDoneAirTimeMax, ++ prStat->u4NumOfTxErr, prStat->u4TxErrBitmap, prStat->u4NumOfRx, prStat->u4NumOfPtiRspRx); ++ ++ DBGLOG(TDLS, TRACE, "\t\t"); ++ ++ for (u4RateId = prStat->u4TxRateOkHisId; u4RateId < STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM; u4RateId++) ++ DBGLOG(TDLS, TRACE, ++ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); ++ for (u4RateId = 0; u4RateId < prStat->u4TxRateOkHisId; u4RateId++) ++ DBGLOG(TDLS, TRACE, ++ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); ++ ++ DBGLOG(TDLS, TRACE, "\n\n"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to do tear down. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ STA_RECORD_T *prStaRec; ++ UINT16 u2ReasonCode; ++ UINT32 u4TearDownSubId; ++ UINT8 *pMac, aucZeroMac[6]; ++ ++ /* init */ ++ u4TearDownSubId = *(UINT32 *) prInBuf; ++ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); ++ pMac = aucZeroMac; ++ ++ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4)); ++ if (prStaRec != NULL) ++ pMac = prStaRec->aucMacAddr; ++ ++ /* handle */ ++ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { ++ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=PTI timeout\n", ++ __func__, pMac); ++ } else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) { ++ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=AGE timeout\n", ++ __func__, pMac); ++ } else { ++ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=%d\n", ++ __func__, pMac, u4TearDownSubId); ++ } ++ ++ /* sanity check */ ++ if (prStaRec == NULL) ++ return; ++ ++ if (fgIsPtiTimeoutSkip == TRUE) { ++ /* skip PTI timeout event */ ++ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { ++ DBGLOG(TDLS, WARN, " %s: skip PTI timeout\n", __func__); ++ return; ++ } ++ } ++ ++ /* record history */ ++ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_FAIL) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_NON_STATE3) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN; ++ else { ++ /* shall not be here */ ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN; ++ } ++ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, TRUE, u2ReasonCode, NULL); ++ ++ /* correct correct reason code for PTI or AGE timeout to supplicant */ ++ if ((u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT) || ++ (u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT)) { ++ u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE; ++ } ++ ++ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ ++ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN, u2ReasonCode, GFP_ATOMIC); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to do tx down. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventTxDone(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ /* UINT32 u4FmeIdx; */ ++ UINT8 *pucFmeHdr; ++ UINT8 ucErrStatus; ++ ++ ucErrStatus = *(UINT32 *) prInBuf; ++ ++ pucFmeHdr = prInBuf + 4; /* skip ucErrStatus */ ++ ++ if (ucErrStatus == 0) ++ DBGLOG(TDLS, TRACE, " %s: OK to tx a TDLS action:", __func__); ++ else ++ DBGLOG(TDLS, TRACE, " %s: fail to tx a TDLS action (err=0x%x):", __func__, ucErrStatus); ++ #if 0 ++ /* dump TX packet content from wlan header */ ++ for (u4FmeIdx = 0; u4FmeIdx < (u4InBufLen - 4); u4FmeIdx++) { ++ if ((u4FmeIdx % 16) == 0) ++ DBGLOG(TDLS, TRACE, "\n"); ++ ++ DBGLOG(TDLS, TRACE, "%02x ", *pucFmeHdr++); ++ } ++ DBGLOG(TDLS, TRACE, "\n\n"); ++ #endif ++} ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to parse TDLS Extended Capabilities element. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE) ++{ ++ UINT_8 *pucIeExtCap; ++ ++ /* sanity check */ ++ if ((prStaRec == NULL) || (pucIE == NULL)) ++ return; ++ ++ if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP) ++ return; ++ ++ /* ++ from bit0 ~ ++ ++ bit 38: TDLS Prohibited ++ The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The ++ field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is ++ allowed. ++ */ ++ if (IE_LEN(pucIE) < 5) ++ return; /* we need 39/8 = 5 bytes */ ++ ++ /* init */ ++ prStaRec->fgTdlsIsProhibited = FALSE; ++ prStaRec->fgTdlsIsChSwProhibited = FALSE; ++ ++ /* parse */ ++ pucIeExtCap = pucIE + 2; ++ pucIeExtCap += 4; /* shift to the byte we care about */ ++ ++ if ((*pucIeExtCap) & BIT(38 - 32)) ++ prStaRec->fgTdlsIsProhibited = TRUE; ++ if ((*pucIeExtCap) & BIT(39 - 32)) ++ prStaRec->fgTdlsIsChSwProhibited = TRUE; ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: AP [%pM] tdls prohibit bit=%d %d\n", ++ __func__, ++ prStaRec->aucMacAddr, prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to transmit a TDLS data frame from nl80211. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] ++* \param[in] ++* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, u8 action_code, u8 dialog_token, ++ u16 status_code, u32 peer_capability, ++ bool initiator, const u8 *buf, size_t len) ++{ ++ ADAPTER_T *prAdapter; ++ GLUE_INFO_T *prGlueInfo; ++ BSS_INFO_T *prAisBssInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ TDLS_MGMT_TX_INFO *prMgmtTxInfo; ++ ++ /* ++ Have correct behavior for STAUT receiving TDLS Setup Request after sending TDLS ++ Set Request and before receiving TDLS Setup Response: ++ -- Source Address of received Request is higher than own MAC address ++ -- Source Address of received Request is lower than own MAC address ++ ++ ==> STA with larger MAC address will send the response frame. ++ ++ Supplicant will do this in wpa_tdls_process_tpk_m1(). ++ */ ++ ++ /* sanity check */ ++ if ((wiphy == NULL) || (peer == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: wrong 0x%p 0x%p!\n", __func__, wiphy, peer); ++ return -EINVAL; ++ } ++ ++ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d %d 0x%p %u\n", ++ __func__, peer, action_code, dialog_token, status_code, buf, (UINT32) len); ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); ++ return -EINVAL; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ if (prAdapter->fgTdlsIsSup == FALSE) { ++ DBGLOG(TDLS, ERROR, " %s: firmware TDLS is not supported!\n", __func__); ++ return -EBUSY; ++ } ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (prAisBssInfo->fgTdlsIsProhibited == TRUE) { ++ /* do not send anything if TDLS is prohibited in the BSS */ ++ return 0; ++ } ++ ++ prMgmtTxInfo = kalMemAlloc(sizeof(TDLS_MGMT_TX_INFO), VIR_MEM_TYPE); ++ if (prMgmtTxInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate fail!\n", __func__); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); ++ ++ if (peer != NULL) ++ kalMemCopy(prMgmtTxInfo->aucPeer, peer, 6); ++ prMgmtTxInfo->ucActionCode = action_code; ++ prMgmtTxInfo->ucDialogToken = dialog_token; ++ prMgmtTxInfo->u2StatusCode = status_code; ++ ++ if (buf != NULL) { ++ if (len > sizeof(prMgmtTxInfo->aucSecBuf)) { ++ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); ++ return -EINVAL; ++ } ++ prMgmtTxInfo->u4SecBufLen = len; ++ kalMemCopy(prMgmtTxInfo->aucSecBuf, buf, len); ++ } ++ ++ /* send the TDLS action data frame */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexMgmtCtrl, ++ prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ /* ++ clear all content to avoid any bug if we dont yet execute TdlsexMgmtCtrl() ++ then kalIoctl finishes ++ */ ++ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); ++ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); ++ return -EINVAL; ++ } ++ ++ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to enable or disable TDLS link from upper layer. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] ++* \param[in] ++* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, enum nl80211_tdls_operation oper) ++{ ++ ADAPTER_T *prAdapter; ++ GLUE_INFO_T *prGlueInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ TDLS_CMD_LINK_T rCmdLink; ++ ++ /* sanity check */ ++ if (peer == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: peer == NULL!\n", __func__); ++ return -EINVAL; ++ } ++ ++ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d\n", ++ __func__, peer, oper, (wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)); ++ ++ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) ++ return -ENOTSUPP; ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); ++ return -EINVAL; ++ } ++ prAdapter = prGlueInfo->prAdapter; ++ kalMemCopy(rCmdLink.aucPeerMac, peer, sizeof(rCmdLink.aucPeerMac)); ++ rCmdLink.fgIsEnabled = FALSE; ++ ++ /* ++ enum nl80211_tdls_operation { ++ NL80211_TDLS_DISCOVERY_REQ, ++ NL80211_TDLS_SETUP, ++ NL80211_TDLS_TEARDOWN, ++ NL80211_TDLS_ENABLE_LINK, ++ NL80211_TDLS_DISABLE_LINK, ++ }; ++ */ ++ ++ switch (oper) { ++ case NL80211_TDLS_ENABLE_LINK: ++ rCmdLink.fgIsEnabled = TRUE; ++ break; ++ ++ case NL80211_TDLS_DISABLE_LINK: ++ rCmdLink.fgIsEnabled = FALSE; ++ break; ++ ++ case NL80211_TDLS_TEARDOWN: ++ case NL80211_TDLS_SETUP: ++ case NL80211_TDLS_DISCOVERY_REQ: ++ /* we do not support setup/teardown/discovery from driver */ ++ return -ENOTSUPP; ++ ++ default: ++ return -ENOTSUPP; ++ } ++ ++ /* enable or disable TDLS link */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexLinkCtrl, &rCmdLink, sizeof(TDLS_CMD_LINK_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a command to TDLS module. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ UINT_32 u4Subcmd; ++ static void (*TdlsCmdTestFunc)(P_GLUE_INFO_T, UINT_8 *, UINT_32); ++ ++ /* parse TDLS sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " sub command = %u\n", (UINT32) u4Subcmd); ++ TdlsCmdTestFunc = NULL; ++ ++ /* handle different sub-command */ ++ switch (u4Subcmd) { ++#if TDLS_CFG_CMD_TEST /* only for unit test */ ++ case TDLS_CMD_TEST_TX_FRAME: ++ /* simulate to send a TDLS frame */ ++ /* TdlsCmdTestTxFrame(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestTxFrame; ++ break; ++ ++ case TDLS_CMD_TEST_TX_TDLS_FRAME: ++ /* simulate to send a TDLS frame from supplicant */ ++ /* TdlsCmdTestTxTdlsFrame(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestTxTdlsFrame; ++ break; ++ ++ case TDLS_CMD_TEST_RCV_FRAME: ++ /* simulate to receive a TDLS frame */ ++ /* TdlsCmdTestRvFrame(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestRvFrame; ++ break; ++ ++ case TDLS_CMD_TEST_PEER_ADD: ++ /* simulate to add a TDLS peer */ ++ /* TdlsCmdTestAddPeer(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestAddPeer; ++ break; ++ ++ case TDLS_CMD_TEST_PEER_UPDATE: ++ /* simulate to update a TDLS peer */ ++ /* TdlsCmdTestUpdatePeer(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestUpdatePeer; ++ break; ++ ++ case TDLS_CMD_TEST_DATA_FRAME: ++ /* simulate to send a data frame to the peer */ ++ /* TdlsCmdTestDataSend(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestDataSend; ++ break; ++ ++ case TDLS_CMD_TEST_RCV_NULL: ++ /* simulate to receive a QoS null frame from the peer */ ++ /* TdlsCmdTestNullRecv(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestNullRecv; ++ break; ++ ++ case TDLS_CMD_TEST_SKIP_TX_FAIL: ++ /* command firmware to skip tx fail case */ ++ /* TdlsCmdTestTxFailSkip(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestTxFailSkip; ++ break; ++ ++ case TDLS_CMD_TEST_SKIP_KEEP_ALIVE: ++ /* command firmware to skip keep alive function */ ++ /* TdlsCmdTestKeepAliveSkip(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestKeepAliveSkip; ++ break; ++ ++ case TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT: ++ /* command firmware to skip channel switch timeout function */ ++ /* TdlsCmdTestChSwTimeoutSkip(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestChSwTimeoutSkip; ++ break; ++ ++ case TDLS_CMD_TEST_PROHIBIT_SET_IN_AP: ++ /* simulate to set Prohibited Bit in AP */ ++ /* TdlsCmdTestProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestProhibitedBitSet; ++ break; ++ ++ case TDLS_CMD_TEST_SCAN_DISABLE: ++ /* command to disable scan request to do channel switch */ ++ /* TdlsCmdTestScanCtrl(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestScanCtrl; ++ break; ++ ++ case TDLS_CMD_TEST_DATA_FRAME_CONT: ++ /* simulate to send a data frame to the peer periodically */ ++ /* TdlsCmdTestDataContSend(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestDataContSend; ++ break; ++ ++ case TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP: ++ /* simulate to set channel switch Prohibited Bit in AP */ ++ /* TdlsCmdTestChSwProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestChSwProhibitedBitSet; ++ break; ++ ++ case TDLS_CMD_TEST_DELAY: ++ /* delay a where */ ++ /* TdlsCmdTestDelay(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestDelay; ++ break; ++ ++ case TDLS_CMD_TEST_PTI_TX_FAIL: ++ /* simulate the tx done fail for PTI */ ++ /* TdlsCmdTestPtiTxDoneFail(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestPtiTxDoneFail; ++ break; ++#endif /* TDLS_CFG_CMD_TEST */ ++ ++ case TDLS_CMD_MIB_UPDATE: ++ /* update MIB parameters */ ++ /* TdlsCmdMibParamUpdate(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdMibParamUpdate; ++ break; ++ ++ case TDLS_CMD_UAPSD_CONF: ++ /* config UAPSD parameters */ ++ /* TdlsCmdUapsdConf(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdUapsdConf; ++ break; ++ ++ case TDLS_CMD_CH_SW_CONF: ++ /* enable or disable or start or stop channel switch function */ ++ /* TdlsCmdChSwConf(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdChSwConf; ++ break; ++ ++ case TDLS_CMD_SETUP_CONF: ++ /* config setup parameters */ ++ /* TdlsCmdSetupConf(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdSetupConf; ++ break; ++ ++ case TDLS_CMD_INFO: ++ /* display all TDLS information */ ++ /* TdlsCmdInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdInfoDisplay; ++ break; ++ ++ case TDLS_CMD_KEY_INFO: ++ /* display key information */ ++ /* TdlsCmdKeyInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdKeyInfoDisplay; ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (TdlsCmdTestFunc != NULL) ++ TdlsCmdTestFunc(prGlueInfo, prInBuf, u4InBufLen); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to record a disconnection event. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure ++* \param[in] fgIsTearDown TRUE: tear down ++* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] fgIsFromUs TRUE: tear down is from us ++* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode) ++{ ++ /* sanity check */ ++ if ((prGlueInfo == NULL) || (pucPeerMac == NULL)) ++ return; ++ ++ DBGLOG(TDLS, INFO, ++ " %s: Rcv a inform from %pM %d %d\n", ++ __func__, pucPeerMac, fgIsFromUs, u2ReasonCode); ++ ++ /* record */ ++ TdlsLinkHistoryRecord(prGlueInfo, fgIsTearDown, pucPeerMac, fgIsFromUs, u2ReasonCode, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a command to TDLS module. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ UINT32 u4EventId; ++ ++ /* sanity check */ ++ if ((prGlueInfo == NULL) || (prInBuf == NULL)) ++ return; /* shall not be here */ ++ ++ /* handle */ ++ u4EventId = *(UINT32 *) prInBuf; ++ u4InBufLen -= 4; ++ ++ DBGLOG(TDLS, INFO, " %s: Rcv a event: %d\n", __func__, u4EventId); ++ ++ switch (u4EventId) { ++ case TDLS_HOST_EVENT_TEAR_DOWN: ++ TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ case TDLS_HOST_EVENT_TX_DONE: ++ TdlsEventTxDone(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ case TDLS_HOST_EVENT_FME_STATUS: ++ TdlsEventFmeStatus(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ case TDLS_HOST_EVENT_STATISTICS: ++ TdlsEventStatistics(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in TDLS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return TDLS_STATUS_SUCCESS: do not set key and key infor. is queued ++ TDLS_STATUS_FAILURE: set key ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey) ++{ ++ STA_RECORD_T *prStaRec; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (prNewKey == NULL)) ++ return TDLS_STATUS_FAILURE; ++ ++ /* ++ supplicant will set key before updating station & enabling the link so we need to ++ backup the key information and set key when link is enabled ++ */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prNewKey->arBSSID); ++ if ((prStaRec != NULL) && IS_TDLS_STA(prStaRec)) { ++ DBGLOG(TDLS, TRACE, " %s: [%pM] queue key (len=%d) until link is enabled\n", ++ __func__, prNewKey->arBSSID, (UINT32) prNewKey->u4KeyLength); ++ ++ if (prStaRec->ucStaState == STA_STATE_3) { ++ DBGLOG(TDLS, TRACE, " %s: [%pM] tear down the link due to STA_STATE_3\n", ++ __func__, prNewKey->arBSSID); ++ ++ /* re-key */ ++ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, ++ prStaRec->aucMacAddr, TRUE, ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); ++ ++ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ ++ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); ++ return TDLS_STATUS_SUCCESS; ++ } ++ ++ /* backup the key */ ++ kalMemCopy(&prStaRec->rTdlsKeyTemp, prNewKey, sizeof(prStaRec->rTdlsKeyTemp)); ++ return TDLS_STATUS_SUCCESS; ++ } ++ ++ return TDLS_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in TDLS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexInit(ADAPTER_T *prAdapter) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ ++ /* reset */ ++ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get any peer is in power save. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval TRUE (at least one peer is in power save) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter) ++{ ++ STA_RECORD_T *prStaRec; ++ UINT32 u4StaId, u4StartIdx; ++ ++ for (u4StaId = 0, u4StartIdx = 0; u4StaId < CFG_STA_REC_NUM; u4StaId++) { ++ /* list all TDLS peers */ ++ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); ++ if (prStaRec == NULL) ++ break; ++ ++ if (prStaRec->fgIsInPS == TRUE) { ++ DBGLOG(TDLS, TRACE, " yes, at least one peer is in ps\n"); ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to enable or disable a TDLS link. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_LINK_T *prCmd; ++ BSS_INFO_T *prBssInfo; ++ STA_RECORD_T *prStaRec; ++ TDLS_LINK_HIS_OTHERS_T rHisOthers; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_CMD_LINK_T); ++ prCmd = (TDLS_CMD_LINK_T *) pvSetBuffer; ++ ++ /* search old entry */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); ++ if (prStaRec == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: cannot find the peer! %pM\n", ++ __func__, prCmd->aucPeerMac); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ if (prCmd->fgIsEnabled == TRUE) { ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_ENABLE_LINK\n", __func__); ++ ++ /* update key information after cnmStaRecChangeState(STA_STATE_3) */ ++ prStaRec->fgTdlsInSecurityMode = FALSE; ++ ++ if (prStaRec->rTdlsKeyTemp.u4Length > 0) { ++ UINT_32 u4BufLen; /* no use */ ++ ++ DBGLOG(TDLS, INFO, " %s: key len=%d\n", ++ __func__, (UINT32) prStaRec->rTdlsKeyTemp.u4Length); ++ ++ /* ++ reminder the function that we are CIPHER_SUITE_CCMP, ++ do not change cipher type to CIPHER_SUITE_WEP128 ++ */ ++ _wlanoidSetAddKey(prAdapter, &prStaRec->rTdlsKeyTemp, ++ prStaRec->rTdlsKeyTemp.u4Length, FALSE, CIPHER_SUITE_CCMP, &u4BufLen); ++ ++ /* clear the temp key */ ++ prStaRec->fgTdlsInSecurityMode = TRUE; ++ kalMemZero(&prStaRec->rTdlsKeyTemp, sizeof(prStaRec->rTdlsKeyTemp)); ++ } ++ ++ /* check if we need to disable channel switch function */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ if (prBssInfo->fgTdlsIsChSwProhibited == TRUE) { ++ TDLS_CMD_CORE_T rCmd; ++ ++ kalMemZero(&rCmd, sizeof(TDLS_CMD_CORE_T)); ++ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = prStaRec->ucNetTypeIndex; ++ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = FALSE; ++ kalMemCopy(rCmd.aucPeerMac, prStaRec->aucMacAddr, 6); ++ TdlsChSwConf(prAdapter, &rCmd, 0, 0); ++ ++ DBGLOG(TDLS, INFO, " %s: disable channel switch\n", __func__); ++ } ++ ++ TDLS_LINK_INCREASE(prGlueInfo); ++ ++ /* record link */ ++ if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N) ++ rHisOthers.fgIsHt = TRUE; ++ else ++ rHisOthers.fgIsHt = FALSE; ++ ++ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, FALSE, ++ prStaRec->aucMacAddr, !prStaRec->flgTdlsIsInitiator, 0, &rHisOthers); ++ } else { ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); /* release to other TDLS peers */ ++ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_DISABLE_LINK\n", __func__); ++ ++ TDLS_LINK_DECREASE(prGlueInfo); ++/* while(1); //sample debug */ ++ } ++ ++ /* work-around link count */ ++ if ((TDLS_LINK_COUNT(prGlueInfo) < 0) || (TDLS_LINK_COUNT(prGlueInfo) > 1)) { ++ /* ERROR case: work-around to recount by searching all station records */ ++ UINT32 u4Idx; ++ ++ TDLS_LINK_COUNT_RESET(prGlueInfo); ++ ++ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { ++ prStaRec = &prAdapter->arStaRec[u4Idx]; ++ ++ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) ++ TDLS_LINK_INCREASE(prGlueInfo); ++ } ++ ++ if (TDLS_LINK_COUNT(prGlueInfo) > 1) { ++ /* number of links is still > 1 */ ++ DBGLOG(TDLS, INFO, " %s: cTdlsLinkCnt %d > 1?\n", ++ __func__, TDLS_LINK_COUNT(prGlueInfo)); ++ ++ TDLS_LINK_COUNT_RESET(prGlueInfo); ++ ++ /* free all TDLS links */ ++ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { ++ prStaRec = &prAdapter->arStaRec[u4Idx]; ++ ++ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ } ++ ++ /* maybe inform supplicant ? */ ++ } ++ } ++ ++ /* display TDLS link history */ ++ TdlsInfoDisplay(prAdapter, NULL, 0, NULL); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send a TDLS action data frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_MGMT_TX_INFO *prMgmtTxInfo; ++ STA_RECORD_T *prStaRec; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_MGMT_TX_INFO); ++ prMgmtTxInfo = (TDLS_MGMT_TX_INFO *) pvSetBuffer; ++ ++ switch (prMgmtTxInfo->ucActionCode) { ++ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: ++ prStaRec = NULL; ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); ++ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3)) { ++ /* rekey? we reject re-setup link currently */ ++ /* TODO: Still can setup link during rekey */ ++ ++ /* ++ return success to avoid supplicant clear TDLS entry; ++ Or we cannot send out any TDLS tear down frame to the peer ++ */ ++ DBGLOG(TDLS, TRACE, " %s: skip new setup on the exist link!\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++ } ++ ++ prStaRec = NULL; ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_CONFIRM: ++ case TDLS_FRM_ACTION_TEARDOWN: ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); ++#if 0 /* in some cases, the prStaRec is still NULL */ ++ /* ++ EX: if a peer sends us a TDLS setup request with wrong BSSID, ++ supplicant will not call TdlsexPeerAdd() to create prStaRec and ++ supplicant will send a TDLS setup response with status code 7. ++ ++ So in the case, prStaRec will be NULL. ++ */ ++ if (prStaRec == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); ++ return -EINVAL; ++ } ++#endif ++ break; ++ ++ /* ++ TODO: Discovery response frame ++ Note that the TDLS Discovery Response frame is not a TDLS frame but a 11 ++ Public Action frame. ++ In WiFi TDLS Tech Minutes June 8 2010.doc, ++ a public action frame (i.e. it is no longer an encapsulated data frame) ++ */ ++ ++ default: ++ DBGLOG(TDLS, ERROR, ++ " %s: wrong action_code %d!\n", __func__, prMgmtTxInfo->ucActionCode); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* send the TDLS data frame */ ++ if (prStaRec != NULL) { ++ DBGLOG(TDLS, INFO, " %s: [%pM] ps=%d status=%d\n", ++ __func__, prStaRec->aucMacAddr, ++ prStaRec->fgIsInPS, prMgmtTxInfo->u2StatusCode); ++ ++ if (prMgmtTxInfo->ucActionCode == TDLS_FRM_ACTION_TEARDOWN) { ++ /* record disconnect history */ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prMgmtTxInfo->aucPeer, ++ TRUE, prMgmtTxInfo->u2StatusCode, NULL); ++ } ++ } ++ ++ return TdlsDataFrameSend(prAdapter, ++ prStaRec, ++ prMgmtTxInfo->aucPeer, ++ prMgmtTxInfo->ucActionCode, ++ prMgmtTxInfo->ucDialogToken, ++ prMgmtTxInfo->u2StatusCode, ++ (UINT_8 *) prMgmtTxInfo->aucSecBuf, prMgmtTxInfo->u4SecBufLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to add a peer record. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexPeerAdd(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_PEER_ADD_T *prCmd; ++ BSS_INFO_T *prAisBssInfo; ++ STA_RECORD_T *prStaRec; ++ UINT_8 ucNonHTPhyTypeSet; ++ UINT32 u4StartIdx; ++ OS_SYSTIME rCurTime; ++ ++ /* sanity check */ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); ++ prCmd = (TDLS_CMD_PEER_ADD_T *) pvSetBuffer; ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4StartIdx = 0; ++ ++ /* search old entry */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); ++ ++ /* check if any TDLS link exists because we only support one TDLS link currently */ ++ if (prStaRec == NULL) { ++ /* the MAC is new peer */ ++ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); ++ ++ if (prStaRec != NULL) { ++ /* a building TDLS link exists */ ++ DBGLOG(TDLS, ERROR, ++ " %s: one TDLS link setup [%pM] is going...\n", ++ __func__, prStaRec->aucMacAddr); ++ ++ if (prStaRec->ucStaState != STA_STATE_3) { ++ /* check timeout */ ++ GET_CURRENT_SYSTIME(&rCurTime); ++ ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsSetupStartTime, ++ SEC_TO_SYSTIME(TDLS_SETUP_TIMEOUT_SEC))) { ++ /* free the StaRec */ ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ ++ DBGLOG(TDLS, ERROR, ++ " %s: free going TDLS link setup [%pM]\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ /* handle new setup */ ++ prStaRec = NULL; ++ } else ++ return TDLS_STATUS_FAILURE; ++ } else { ++ /* the TDLS is built and works fine, reject new one */ ++ return TDLS_STATUS_FAILURE; ++ } ++ } ++ } else { ++ if (prStaRec->ucStaState == STA_STATE_3) { ++ /* the peer exists, maybe TPK lifetime expired, supplicant wants to renew key */ ++ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, ++ prStaRec->aucMacAddr, TRUE, ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); ++ ++ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ ++ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: re-setup link for [%pM] maybe re-key?\n", ++ __func__, (prStaRec->aucMacAddr)); ++ return TDLS_STATUS_FAILURE; ++ } ++ } ++ ++ /* ++ create new entry if not exist ++ ++ 1. we are initiator ++ (1) send TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) got TDLS setup response and send TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ ++ 2. we are responder ++ (1) got TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) send TDLS setup response ++ (3) got TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ */ ++ if (prStaRec == NULL) { ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); ++ ++ if (prStaRec == NULL) { ++ /* shall not be here */ ++ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ /* init the prStaRec */ ++ /* prStaRec will be zero first in cnmStaRecAlloc() */ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prCmd->aucPeerMac); ++ ++/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); */ ++ } else { ++#if 0 ++ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_TDLS_STA(prStaRec))) { ++ /* ++ test plan: The STAUT should locally tear down existing TDLS direct link and ++ respond with Set up Response frame. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++#endif ++ } ++ ++ /* reference to bssCreateStaRecFromBssDesc() and use our best capability */ ++ /* reference to assocBuildReAssocReqFrameCommonIEs() to fill elements */ ++ ++ /* prStaRec->u2CapInfo */ ++ /* TODO: Need to parse elements from setup request frame */ ++ prStaRec->u2OperationalRateSet = prAisBssInfo->u2OperationalRateSet; ++ prStaRec->u2BSSBasicRateSet = prAisBssInfo->u2BSSBasicRateSet; ++ prStaRec->u2DesiredNonHTRateSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet; ++ prStaRec->ucPhyTypeSet = prAisBssInfo->ucPhyTypeSet; ++ prStaRec->eStaType = STA_TYPE_TDLS_PEER; ++ ++ prStaRec->ucDesiredPhyTypeSet = /*prStaRec->ucPhyTypeSet & */ ++ prAdapter->rWifiVar.ucAvailablePhyTypeSet; ++ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; ++ ++ /* check for Target BSS's non HT Phy Types */ ++ if (ucNonHTPhyTypeSet) { ++ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; ++ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; ++ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ ++ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++ prStaRec->fgHasBasicPhyType = TRUE; ++ } else { ++ /* use mandatory for 11N only BSS */ ++/* ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); */ ++ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ prStaRec->fgHasBasicPhyType = FALSE; ++ } ++ ++ /* update non HT Desired Rate Set */ ++ { ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prStaRec->u2DesiredNonHTRateSet = ++ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); ++ } ++ ++#if 0 /* TdlsexPeerAdd() will be called before we receive setup rsp in TdlsexRxFrameHandle() */ ++ /* check if the add is from the same peer in the 1st unhandled setup request frame */ ++ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", ++ __func__, prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac); ++ ++ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { ++ /* copy the HT capability from its setup request */ ++ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); ++ ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); ++ ++ /* reset backup */ ++ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); ++ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); ++ ++ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); ++ } ++#endif ++ ++ /* update WMM: must support due to UAPSD in TDLS link */ ++ prStaRec->fgIsWmmSupported = TRUE; ++ prStaRec->fgIsUapsdSupported = TRUE; ++ ++ /* update station record to firmware */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* update time */ ++ GET_CURRENT_SYSTIME(&prStaRec->rTdlsSetupStartTime); ++ ++ DBGLOG(TDLS, INFO, " %s: create a peer [%pM]\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to update a peer record. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexPeerUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_PEER_UPDATE_T *prCmd; ++ BSS_INFO_T *prAisBssInfo; ++ STA_RECORD_T *prStaRec; ++ IE_HT_CAP_T *prHtCap; ++ ++ /* sanity check */ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); ++ prCmd = (TDLS_CMD_PEER_UPDATE_T *) pvSetBuffer; ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* search old entry */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); ++ ++ /* ++ create new entry if not exist ++ ++ 1. we are initiator ++ (1) send TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) got TDLS setup response and send TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ ++ 2. we are responder ++ (1) got TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) send TDLS setup response ++ (3) got TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ */ ++ if ((prStaRec == NULL) || (prStaRec->fgIsInUse == 0)) { ++ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ DBGLOG(TDLS, INFO, " %s: update a peer [%pM] %d -> %d, 0x%x\n", ++ __func__, (prStaRec->aucMacAddr), ++ prStaRec->ucStaState, STA_STATE_3, prStaRec->eStaType); ++ ++ if (!IS_TDLS_STA(prStaRec)) { ++ DBGLOG(TDLS, ERROR, " %s: peer is not TDLS one!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* check if the add is from the same peer in the 1st unhandled setup request frame */ ++ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", ++ __func__, (prGlueInfo->aucTdlsHtPeerMac), (prCmd->aucPeerMac)); ++ ++ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { ++ /* copy the HT capability from its setup request */ ++ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); ++ ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); ++ ++ /* reset backup */ ++ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); ++ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); ++ ++ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); ++ } ++ ++ /* update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ ++ /* update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = prCmd->u2StatusCode; ++ ++ /* prStaRec->ucStaState shall be STA_STATE_1 */ ++ ++ prStaRec->u2CapInfo = prCmd->u2Capability; ++/* prStaRec->u2OperationalRateSet */ ++ prStaRec->u2AssocId = 0; /* no use */ ++ prStaRec->u2ListenInterval = 0; /* unknown */ ++/* prStaRec->ucDesiredPhyTypeSet */ ++/* prStaRec->u2DesiredNonHTRateSet */ ++/* prStaRec->u2BSSBasicRateSet */ ++/* prStaRec->ucMcsSet */ ++/* prStaRec->fgSupMcs32 */ ++/* prStaRec->u2HtCapInfo */ ++ prStaRec->fgIsQoS = TRUE; ++ prStaRec->fgIsUapsdSupported = (prCmd->UapsdBitmap == 0) ? FALSE : TRUE; ++/* prStaRec->ucAmpduParam */ ++/* prStaRec->u2HtExtendedCap */ ++ prStaRec->u4TxBeamformingCap = 0; /* no use */ ++ prStaRec->ucAselCap = 0; /* no use */ ++ prStaRec->ucRCPI = 0; ++ prStaRec->ucBmpTriggerAC = prCmd->UapsdBitmap; ++ prStaRec->ucBmpDeliveryAC = prCmd->UapsdBitmap; ++ prStaRec->ucUapsdSp = prCmd->UapsdMaxSp; ++ ++ /* update HT */ ++#if (TDLS_CFG_HT_SUP == 1) ++ if (prCmd->fgIsSupHt == FALSE) { ++ /* no HT IE is from supplicant so we use the backup */ ++ prHtCap = (IE_HT_CAP_T *) &prStaRec->rTdlsHtCap; ++ ++ DBGLOG(TDLS, INFO, " %s: [%pM] update ht ie 0x%x\n", ++ __func__, (prStaRec->aucMacAddr), prHtCap->ucId); ++ ++ if (prHtCap->ucId == ELEM_ID_HT_CAP) { ++ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; ++ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; ++ ++ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; ++ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; ++ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; ++ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; ++ prStaRec->ucAselCap = prHtCap->ucAselCap; ++ prStaRec->ucDesiredPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ } ++ } else { ++ /* TODO: use the HT IE from supplicant */ ++ } ++#endif /* TDLS_CFG_HT_SUP */ ++ ++ DBGLOG(TDLS, INFO, " %s: UAPSD 0x%x %d MCS=0x%x\n", ++ __func__, prCmd->UapsdBitmap, prCmd->UapsdMaxSp, prStaRec->ucMcsSet); ++ ++/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ ++ ++ DBGLOG(TDLS, INFO, " %s: update a peer [%pM]\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to check if we need to drop a TDLS action frame. ++* ++* \param[in] *pPkt Pointer to the struct sk_buff->data. ++* \param[in] ++* \param[in] ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt) ++{ ++ ADAPTER_T *prAdapter; ++ UINT8 ucActionId; ++ ++ /* sanity check */ ++ if ((pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) ++ return FALSE; /* not TDLS data frame htons(0x890d) */ ++ ++#if 0 /* supplicant handles this check */ ++ if (prStaRec == NULL) ++ return FALSE; /* shall not be here */ ++ ++ DBGLOG(TDLS, INFO, ++ " %s: Rcv a TDLS action frame (id=%d) %d %d\n", ++ __func__, *(pPkt + 13 + 4), prStaRec->fgTdlsIsProhibited, fgIsPtiTimeoutSkip); ++ ++ /* check if TDLS Prohibited bit is set in AP's beacon */ ++ if (prStaRec->fgTdlsIsProhibited == TRUE) ++ return TRUE; ++#endif ++ ++ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ ++ ++ if (fgIsPtiTimeoutSkip == TRUE) { ++ /* also skip any tear down frame from the peer */ ++ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) ++ return TRUE; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ DBGLOG(TDLS, INFO, ++ " %s: Rcv a TDLS action frame %d (%u)\n", ++ __func__, ucActionId, (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ ++ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) { ++ DBGLOG(TDLS, WARN, " %s: Rcv a TDLS tear down frame %d, will DISABLE link\n", ++ __func__, *(pPkt + 13 + 4)); /* reason code */ ++ ++ /* record disconnect history */ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, pPkt + 6, FALSE, *(pPkt + 13 + 4), NULL); ++ ++ /* inform tear down to supplicant only in OPEN/NONE mode */ ++ /* ++ we need to tear down the link manually; or supplicant will display ++ "No FTIE in TDLS Teardown" and it will not tear down the link ++ */ ++ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, ++ pPkt + 6, TDLS_FRM_ACTION_TEARDOWN, *(pPkt + 13 + 4), GFP_ATOMIC); ++ } ++#if 0 /* pass all to supplicant except same thing is handled in supplicant */ ++ if (((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI) || ++ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_REQ) || ++ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_RSP) || ++ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI_RSP)) { ++ return TRUE; ++ } ++#endif ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to parse some IEs in the setup frame from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] pPkt Pointer to the ethernet packet ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen) ++{ ++ ADAPTER_T *prAdapter; ++ STA_RECORD_T *prStaRec; ++ UINT8 ucActionId; ++ UINT8 *pucPeerMac, ucElmId, ucElmLen; ++ INT16 s2FmeLen; ++ ++ /* sanity check */ ++ if ((prGlueInfo == NULL) || (pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) ++ return; ++ ++ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ ++ ++ if ((ucActionId != TDLS_FRM_ACTION_SETUP_REQ) && (ucActionId != TDLS_FRM_ACTION_SETUP_RSP)) ++ return; ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ pucPeerMac = pPkt + 6; ++ s2FmeLen = (INT16) u2PktLen; ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: get a setup frame %d from %pM\n", ++ __func__, ucActionId, (pucPeerMac)); ++ ++ if (ucActionId == TDLS_FRM_ACTION_SETUP_REQ) ++ pPkt += 12 + 2 + 2 + 1 + 1 + 2; /* skip action, dialog token, capability */ ++ else ++ pPkt += 12 + 2 + 2 + 1 + 2 + 1 + 2; /* skip action, status code, dialog token, capability */ ++ ++ /* check station record */ ++ prStaRec = cnmGetStaRecByAddress(prGlueInfo->prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, pucPeerMac); ++ ++ if (prStaRec == NULL) { ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); ++ ++ if (prStaRec == NULL) { ++ /* TODO: only one TDLS entry, need to free old one if timeout */ ++ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); ++ return; ++ } ++ ++ /* init the prStaRec */ ++ /* prStaRec will be zero first in cnmStaRecAlloc() */ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMac); ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++ ++ /* backup HT IE to station record */ ++ /* TODO: Maybe our TDLS only supports non-11n */ ++ while (s2FmeLen > 0) { ++ ucElmId = *pPkt++; ++ ucElmLen = *pPkt++; ++ ++ switch (ucElmId) { ++ case ELEM_ID_HT_CAP: /* 0x2d */ ++ /* backup the HT IE of 1st unhandled setup request frame */ ++ if (prGlueInfo->rTdlsHtCap.ucId == 0x00) { ++ kalMemCopy(prGlueInfo->aucTdlsHtPeerMac, pucPeerMac, 6); ++ kalMemCopy(&prGlueInfo->rTdlsHtCap, pPkt - 2, ucElmLen + 2); ++ ++ /* ++ cannot backup in prStaRec; or ++ ++ 1. we build a TDLS link ++ 2. peer re-sends setup req ++ 3. we backup HT cap element ++ 4. supplicant disables the link ++ 5. we clear the prStaRec ++ */ ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: %pM: find a HT IE\n", ++ __func__, (pucPeerMac)); ++ } ++ return; ++ ++ case ELEM_ID_EXTENDED_CAP: ++ /* TODO: backup the extended capability IE */ ++ break; ++ } ++ ++ pPkt += ucElmLen; ++ s2FmeLen -= (2 + ucElmLen); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to get the TDLS station record. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval TDLS_STATUS_SUCCESS: this is TDLS packet ++* TDLS_STATUS_FAILURE: this is not TDLS packet ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo) ++{ ++ BSS_INFO_T *prBssInfo; ++ STA_RECORD_T *prStaRec; ++ TDLS_STATUS Status; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (prMsduInfo == NULL)) ++ return TDLS_STATUS_FAILURE; ++ ++ if (prAdapter->prGlueInfo == NULL) ++ return TDLS_STATUS_FAILURE; ++ if (TDLS_IS_NO_LINK_GOING(prAdapter->prGlueInfo)) ++ return TDLS_STATUS_FAILURE; ++ ++ /* init */ ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; ++ Status = TDLS_STATUS_SUCCESS; ++ ++ /* get record by ether dest */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMsduInfo->aucEthDestAddr); ++ ++ /* ++ TDLS Setup Request frames, TDLS Setup Response frames and TDLS Setup Confirm ++ frames shall be transmitted through the AP and shall not be transmitted to a group ++ address. ++ ++ 1. In first time, prStaRec == NULL or prStaRec->ucStaState != STA_STATE_3, ++ we will send them to AP; ++ 2. When link is still on, if you command to send TDLS setup from supplicant, ++ supplicant will DISABLE LINK first, prStaRec will be NULL then send TDLS ++ setup frame to the peer. ++ */ ++ ++ do { ++ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3) && (IS_TDLS_STA(prStaRec))) { ++ /* ++ TDLS Test Case 5.3 Tear Down ++ Automatically sends TDLS Teardown frame to STA 2 via AP ++ ++ 11.21.5 TDLS Direct Link Teardown ++ The TDLS Teardown frame shall be sent over the direct path and the reason ++ code shall be set to "TDLS 40 direct link teardown for unspecified reason", ++ except when the TDLS peer STA is unreachable via the TDLS direct link, ++ in which case, the TDLS Teardown frame shall be sent through the AP and ++ the reason code shall be set to "TDLS direct link teardown due to TDLS peer ++ STA unreachable via the TDLS direct link". ++ */ ++ /* if (prStaRec->fgIsInPS == TRUE) */ ++ /* ++ check if the packet is tear down: ++ we do not want to use PTI to indicate the tear down and ++ we want to send the tear down to AP then AP help us to send it ++ */ ++ struct sk_buff *prSkb; ++ UINT8 *pEth; ++ UINT_16 u2EtherTypeLen; ++ ++ prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ if (prSkb != NULL) { ++ UINT8 ucActionCode, ucReasonCode; ++ ++ /* init */ ++ pEth = prSkb->data; ++ u2EtherTypeLen = (pEth[ETH_TYPE_LEN_OFFSET] << 8) | ++ (pEth[ETH_TYPE_LEN_OFFSET + 1]); ++ ucActionCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 3]; ++ ucReasonCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] | ++ (pEth[ETH_TYPE_LEN_OFFSET + 1 + 5] << 8); ++ ++ /* TDLS_REASON_CODE_UNREACHABLE: keep alive fail or PTI timeout */ ++ if ((u2EtherTypeLen == TDLS_FRM_PROT_TYPE) && ++ (ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && ++ (ucReasonCode == TDLS_REASON_CODE_UNREACHABLE)) { ++ /* ++ when we cannot reach the peer, ++ we need AP's help to send the tear down frame ++ */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prStaRec = prBssInfo->prStaRecOfAP; ++ if (prStaRec == NULL) { ++ Status = TDLS_STATUS_FAILURE; ++ break; ++ } ++#if 0 ++ /* change status code */ ++ pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] = TDLS_REASON_CODE_UNREACHABLE; ++#endif ++ } ++ } ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ } ++ } while (FALSE); ++ ++ DBGLOG(TDLS, INFO, " %s: (Status=%x) [%pM] ucStaRecIndex = %d!\n", ++ __func__, (INT32) Status, (prMsduInfo->aucEthDestAddr), ++ prMsduInfo->ucStaRecIndex); ++ return Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to check if we suffer timeout for TX quota empty case. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota) ++{ ++ OS_SYSTIME rCurTime; ++ ++ /* sanity check */ ++ if (!IS_TDLS_STA(prStaRec)) ++ return; ++ ++ if (FreeQuota != 0) { ++ /* reset timeout */ ++ prStaRec->rTdlsTxQuotaEmptyTime = 0; ++ return; ++ } ++ ++ /* work-around: check if the no free quota case is too long */ ++ GET_CURRENT_SYSTIME(&rCurTime); ++ ++ if (prStaRec->rTdlsTxQuotaEmptyTime == 0) { ++ prStaRec->rTdlsTxQuotaEmptyTime = rCurTime; ++ } else { ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsTxQuotaEmptyTime, ++ SEC_TO_SYSTIME(TDLS_TX_QUOTA_EMPTY_TIMEOUT))) { ++ /* tear down the link */ ++ DBGLOG(TDLS, WARN, ++ " %s: [%pM] TX quota empty timeout!\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ /* record disconnect history */ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, ++ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY, NULL); ++ ++ /* inform tear down to supplicant only in OPEN/NONE mode */ ++ /* ++ we need to tear down the link manually; or supplicant will display ++ "No FTIE in TDLS Teardown" and it will not tear down the link ++ */ ++ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_REASON_CODE_UNREACHABLE, GFP_ATOMIC); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to un-initialize variables in TDLS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexUninit(ADAPTER_T *prAdapter) ++{ ++#if TDLS_CFG_CMD_TEST ++ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); ++#endif /* TDLS_CFG_CMD_TEST */ ++} ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++/* End of tdls.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c +new file mode 100644 +index 000000000000..5450cbb65183 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c +@@ -0,0 +1,741 @@ ++/* ++** Id: tdls_com.c#1 ++*/ ++ ++/*! \file tdls_com.c ++ \brief This file includes IEEE802.11z TDLS main support. ++*/ ++ ++/* ++** Log: tdls_com.c ++ * ++ * 11 13 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++ ++#include "precomp.h" ++ ++#if (CFG_SUPPORT_TDLS == 1) ++#include "tdls.h" ++ ++ /******************************************************************************* ++ * C O N S T A N T S ++ ******************************************************************************** ++ */ ++ ++ /******************************************************************************* ++ * F U N C T I O N D E C L A R A T I O N S ++ ******************************************************************************** ++ */ ++ ++ /******************************************************************************* ++ * P R I V A T E D A T A ++ ******************************************************************************** ++ */ ++ ++ /******************************************************************************* ++ * P R I V A T E F U N C T I O N S ++ ******************************************************************************** ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to append general IEs. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] prStaRec Pointer to the STA_RECORD_T structure. ++* \param[in] u2StatusCode Status code. ++* \param[in] pPkt Pointer to the frame body ++* ++* \retval append length ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ BSS_INFO_T *prBssInfo; ++ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; ++ UINT_32 u4NonHTPhyType; ++ UINT_16 u2SupportedRateSet; ++ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; ++ UINT_8 ucAllSupportedRatesLen; ++ UINT_8 ucSupRatesLen; ++ UINT_8 ucExtSupRatesLen; ++ UINT_32 u4PktLen, u4IeLen; ++ BOOLEAN fg40mAllowed; ++ ++ /* reference to assocBuildReAssocReqFrameCommonIEs() */ ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ u4PktLen = 0; ++ ++ /* 3. Frame Formation - (5) Supported Rates element */ ++ /* use all sup rate we can support */ ++ if (prStaRec != NULL) ++ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; ++ else ++ u4NonHTPhyType = PHY_TYPE_ERP_INDEX; /* default */ ++ ++ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; ++ ++ if (prStaRec != NULL) { ++ u2SupportedRateSet &= prStaRec->u2OperationalRateSet; ++ ++ if (u2SupportedRateSet == 0) ++ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; ++ } ++ ++ rateGetDataRatesFromRateSet(u2SupportedRateSet, ++ prBssInfo->u2BSSBasicRateSet, aucAllSupportedRates, &ucAllSupportedRatesLen); ++ ++ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? ++ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); ++ ++ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; ++ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (7) Extended sup rates element */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates, ++ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (8) Supported channels element */ ++ /* ++ The Supported channels element is included in Request frame and also in Response ++ frame if Status Code 0 (successful). ++ */ ++ if (u2StatusCode == 0) { ++ SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 11; ++ ++#if CFG_SUPPORT_DFS ++ if (prAdapter->fgEnable5GBand == TRUE) { ++ /* 5G support */ ++ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 4; ++ } ++#endif /* CFG_SUPPORT_DFS */ ++ ++ u4IeLen = IE_SIZE(pPkt); ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (14) HT capabilities element */ ++ ++ /* no need to check AP capability */ ++/* if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && */ ++ ++ /* ++ after we set ucPhyTypeSet to PHY_TYPE_SET_802_11N in TdlsexRxFrameHandle(), ++ supplicant will disable link if exists and we will clear prStaRec. ++ ++ finally, prStaRec->ucPhyTypeSet will also be 0 ++ ++ so we have a fix in TdlsexPeerAdd(). ++ */ ++ if (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { ++ /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */ ++#if 0 /* always support */ ++ if (prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode == CONFIG_BW_20M) ++ fg40mAllowed = FALSE; ++ else ++#endif ++ fg40mAllowed = TRUE; ++ ++ u4IeLen = rlmFillHtCapIEByParams(fg40mAllowed, ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, ++ prAdapter->rWifiVar.u8SupportRxSgi20, ++ prAdapter->rWifiVar.u8SupportRxSgi40, ++ prAdapter->rWifiVar.u8SupportRxGf, ++ prAdapter->rWifiVar.u8SupportRxSTBC, prBssInfo->eCurrentOPMode, pPkt); ++ ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (17) WMM Information element */ ++ ++ /* always support */ ++/* if (prAdapter->rWifiVar.fgSupportQoS) */ ++ ++ { ++ /* force to support all UAPSD in TDLS link */ ++ u4IeLen = mqmGenerateWmmInfoIEByParam(TRUE /*prAdapter->rWifiVar.fgSupportUAPSD */ , ++ 0xf /*prPmProfSetupInfo->ucBmpDeliveryAC */ , ++ 0xf /*prPmProfSetupInfo->ucBmpTriggerAC */ , ++ WMM_MAX_SP_LENGTH_ALL /*prPmProfSetupInfo->ucUapsdSp */ , ++ pPkt); ++ ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ return u4PktLen; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to transmit a TDLS data frame (setup req/rsp/confirm and tear down). ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] prStaRec Pointer to the STA_RECORD_T structure. ++* \param[in] pPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] ucActionCode TDLS Action ++* \param[in] ucDialogToken Dialog token ++* \param[in] u2StatusCode Status code ++* \param[in] pAppendIe Others IEs (here are security IEs from supplicant) ++* \param[in] AppendIeLen IE length of others IEs ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS ++TdlsDataFrameSend(ADAPTER_T *prAdapter, ++ STA_RECORD_T *prStaRec, ++ UINT_8 *pPeerMac, ++ UINT_8 ucActionCode, ++ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen) ++{ ++#define LR_TDLS_FME_FIELD_FILL(__Len) \ ++do { \ ++ pPkt += __Len; \ ++ u4PktLen += __Len; \ ++} while (0) ++ ++ GLUE_INFO_T *prGlueInfo; ++ BSS_INFO_T *prBssInfo; ++ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; ++ struct sk_buff *prMsduInfo; ++ MSDU_INFO_T *prMsduInfoMgmt; ++ UINT8 *pPkt, *pucInitiator, *pucResponder; ++ UINT32 u4PktLen, u4IeLen; ++ UINT16 u2CapInfo; ++/* UINT8 *pPktTemp; */ ++ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ ++ DBGLOG(TDLS, INFO, " %s: 2040=%d\n", __func__, prGlueInfo->rTdlsLink.fgIs2040Sup); ++ ++ /* sanity check */ ++ if (prStaRec != NULL) { ++ if (prStaRec->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { ++ DBGLOG(TDLS, ERROR, ++ " %s: net index %d fail\n", __func__, prStaRec->ucNetTypeIndex); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ } else { ++ /* prStaRec maybe NULL in setup request */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ } ++ ++ /* allocate/init packet */ ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ u4PktLen = 0; ++ prMsduInfo = NULL; ++ prMsduInfoMgmt = NULL; ++ ++ /* make up frame content */ ++ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { ++ /* ++ The STAUT will not respond to a TDLS Discovery Request Frame with different BSSID. ++ Supplicant will check this in wpa_tdls_process_discovery_request(). ++ */ ++ ++ /* TODO: reduce 1600 to correct size */ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* 1. 802.3 header */ ++/* pPktTemp = pPkt; */ ++ kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ } else { ++ /* discovery response */ ++ WLAN_MAC_HEADER_T *prHdr; ++ ++ prMsduInfoMgmt = (MSDU_INFO_T *) ++ cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); ++ if (prMsduInfoMgmt == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate mgmt pkt fail\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ pPkt = (UINT8 *) prMsduInfoMgmt->prPacket; ++ prHdr = (WLAN_MAC_HEADER_T *) pPkt; ++ ++ /* 1. 802.11 header */ ++ prHdr->u2FrameCtrl = MAC_FRAME_ACTION; ++ prHdr->u2DurationID = 0; ++ kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN); ++ prHdr->u2SeqCtrl = 0; ++ LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T)); ++ ++ /* Frame Formation - (1) Category */ ++ *pPkt = CATEGORY_PUBLIC_ACTION; ++ LR_TDLS_FME_FIELD_FILL(1); ++ } ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = ucActionCode; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - Status Code */ ++ switch (ucActionCode) { ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_CONFIRM: ++ case TDLS_FRM_ACTION_TEARDOWN: ++ WLAN_SET_FIELD_16(pPkt, u2StatusCode); ++ LR_TDLS_FME_FIELD_FILL(2); ++ break; ++ } ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ } ++ ++ /* Fill elements */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ /* ++ Capability ++ ++ Support Rates ++ Extended Support Rates ++ Supported Channels ++ HT Capabilities ++ WMM Information Element ++ ++ Extended Capabilities ++ Link Identifier ++ ++ RSNIE ++ FTIE ++ Timeout Interval ++ */ ++ if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) { ++ /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); ++ WLAN_SET_FIELD_16(pPkt, u2CapInfo); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ /* ++ TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode ++ must be CONFIG_BW_20_40M. ++ ++ TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if ++ Tdls 20/40 is enabled. ++ */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, u2StatusCode, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 5. Frame Formation - Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } else { ++ /* 5. Frame Formation - WMM Parameter element */ ++ if (prAdapter->rWifiVar.fgSupportQoS) { ++ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, ++ prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); ++ ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } ++ } ++ } ++ ++ /* 6. Frame Formation - 20/40 BSS Coexistence */ ++ /* ++ Follow WiFi test plan, add 20/40 element to request/response/confirm. ++ */ ++/* if (prGlueInfo->rTdlsLink.fgIs2040Sup == TRUE) */ /* force to enable */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ /* ++ bit0 = 1: The Information Request field is used to indicate that a ++ transmitting STA is requesting the recipient to transmit a 20/40 BSS ++ Coexistence Management frame with the transmitting STA as the ++ recipient. ++ ++ bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP ++ that receives this information or reports of this information from ++ operating a 20/40 MHz BSS. ++ ++ bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit ++ a receiving AP from operating its BSS as a 20/40 MHz BSS. ++ */ ++ BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE; ++ BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; ++ BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; ++ LR_TDLS_FME_FIELD_FILL(3); ++ } ++ ++ /* 6. Frame Formation - HT Operation element */ ++/* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */ ++/* LR_TDLS_FME_FIELD_FILL(u4IeLen); */ ++ ++ /* 7. Frame Formation - Link identifier element */ ++ /* Note1: Link ID sequence must be correct; Or the calculated MIC will be error */ ++ /* ++ Note2: When we receive a setup request with link ID, Marvell will send setup response ++ to the peer in link ID, not the SA in the WLAN header. ++ */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ ++ switch (ucActionCode) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ case TDLS_FRM_ACTION_CONFIRM: ++ default: ++ /* we are initiator */ ++ pucInitiator = prBssInfo->aucOwnMacAddr; ++ pucResponder = pPeerMac; ++ ++ if (prStaRec != NULL) ++ prStaRec->flgTdlsIsInitiator = TRUE; ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: ++ /* peer is initiator */ ++ pucInitiator = pPeerMac; ++ pucResponder = prBssInfo->aucOwnMacAddr; ++ ++ if (prStaRec != NULL) ++ prStaRec->flgTdlsIsInitiator = FALSE; ++ break; ++ ++ case TDLS_FRM_ACTION_TEARDOWN: ++ if (prStaRec != NULL) { ++ if (prStaRec->flgTdlsIsInitiator == TRUE) { ++ /* we are initiator */ ++ pucInitiator = prBssInfo->aucOwnMacAddr; ++ pucResponder = pPeerMac; ++ } else { ++ /* peer is initiator */ ++ pucInitiator = pPeerMac; ++ pucResponder = prBssInfo->aucOwnMacAddr; ++ } ++ } else { ++ /* peer is initiator */ ++ pucInitiator = pPeerMac; ++ pucResponder = prBssInfo->aucOwnMacAddr; ++ } ++ break; ++ } ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 8. Append security IEs */ ++ /* ++ 11.21.5 TDLS Direct Link Teardown ++ If the STA has security enabled on the link 37 with the AP, then the FTIE shall be ++ included in the TDLS Teardown frame. ++ ++ For ralink station, it can accept our tear down without FTIE but marvell station. ++ */ ++/* if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) */ ++ if (pAppendIe != NULL) { ++ if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) || ++ ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && ++ (prStaRec != NULL) && (prStaRec->fgTdlsInSecurityMode == TRUE))) { ++ kalMemCopy(pPkt, pAppendIe, AppendIeLen); ++ LR_TDLS_FME_FIELD_FILL(AppendIeLen); ++ } ++ } ++ ++ /* 7. Append Supported Operating Classes IE */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */ ++ u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } ++ ++ /* 11. send the data or management frame */ ++ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { ++#if 0 ++ /* ++ Note1: remember to modify our MAC & AP MAC & peer MAC in LINK ID ++ Note2: dialog token in rsp & confirm must be same as sender. ++ */ ++ ++#if 1 ++ /* example for Ralink's and Broadcom's TDLS setup request frame in open/none */ ++ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { ++#if 0 ++ /* mediatek */ ++ char buffer[] = { 0x31, 0x04, ++ 0x01, 0x08, 0x02, 0x04, 0x0b, 0x16, 0xc, 0x12, 0x18, 0x24, ++ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, ++ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, ++ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, ++ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, ++ 0x48, 0x01, 0x01, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e ++ }; ++#endif ++ ++#if 1 ++ /* ralink *//* from capability */ ++ char buffer[] = { 0x21, 0x04, ++ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, ++ 0x32, 0x04, 0x0c, 0x18, 0x30, 0x60, ++ 0x24, 0x06, 0x01, 0x0b, 0x24, 0x08, 0x95, 0x04, ++ 0x7f, 0x05, 0x01, 0x00, 0x00, 0x50, 0x20, ++ 0x3b, 0x10, 0x20, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19, ++ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, ++ 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x48, 0x01, 0x01, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f ++ }; ++#endif ++#if 0 ++ /* 6630 */ ++ char buffer[] = { 0x01, 0x01, ++ 0x01, 0x04, 0x02, 0x04, 0x0b, 0x16, ++ 0x24, 0x02, 0x01, 0x0d, ++ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0xff, ++ 0x2d, 0x1a, 0x61, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, ++ 0x48, 0x01, 0x01, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, ++ 0x00, 0x00, 0x00, ++ 0xbf, 0x0c, 0x30, 0x01, 0x80, 0x03, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, ++ 0x00, 0x00 ++ }; ++#endif ++ ++ pPktTemp += 18; ++ memcpy(pPktTemp, buffer, sizeof(buffer)); ++ u4PktLen = 18 + sizeof(buffer); ++ } ++#endif ++ ++#if 1 ++ if (ucActionCode == TDLS_FRM_ACTION_CONFIRM) { ++ /* Note: dialog token must be same as request */ ++#if 1 ++ /* ralink */ ++ char buffer[] = { 0x00, ++ 0x01, 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x00, 0x03, ++ 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, ++ 0x62, 0x32, 0x2f, 0x00 ++ }; ++#endif ++ ++#if 0 ++ /* 6630 */ ++ char buffer[] = { 0x00, ++ 0x01, ++ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, ++ 0x48, 0x01, 0x01, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x3f, 0x00, 0x00, ++ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, ++ 0x00, 0x00, 0x00 ++ }; ++#endif ++ ++#if 0 ++ /* A/D die */ ++ char buffer[] = { 0x00, ++ 0x01, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x6b, 0x00, 0x00, ++ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, ++ 0x00, 0x00, 0x00 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0x38, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, ++ 0x1c, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e ++ }; ++#endif ++ ++ pPktTemp += 18; ++ memcpy(pPktTemp, buffer, sizeof(buffer)); ++ u4PktLen = 18 + sizeof(buffer); ++ } ++#endif ++ ++#else ++ ++#if 0 ++ /* for test in open/none */ ++ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { ++ char buffer[] = { 0x01, 0x04, ++ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, ++ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, ++ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, ++ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, ++ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, ++ 0x48, 0x01, 0x01, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1e, 0x20, 0x21 ++ }; ++ ++ pPktTemp += 18; ++ memcpy(pPktTemp, buffer, sizeof(buffer)); ++ u4PktLen = 18 + sizeof(buffer); ++ } ++#endif ++#endif /* 0 */ ++ ++ /* 9. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++ } else { ++ /* ++ A TDLS capable STA that receives a TDLS Discovery Request frame is required to ++ send the response "to the requesting STA, via the direct path." ++ However, prior to establishment of the direct link, the responding STA may not ++ know the rate capabilities of the requesting STA. In this case, the responding ++ STA shall send the TDLS Discovery Response frame using a rate from the ++ BSSBasicRateSet of the BSS to which the STA is currently associated. ++ */ ++ prMsduInfoMgmt->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfoMgmt->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfoMgmt->fgIs802_1x = FALSE; ++ prMsduInfoMgmt->fgIs802_11 = TRUE; ++ prMsduInfoMgmt->u2FrameLength = u4PktLen; ++ prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfoMgmt->pfTxDoneHandler = NULL; ++ prMsduInfoMgmt->fgIsBasicRate = TRUE; /* use basic rate */ ++ ++ /* Send them to HW queue */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt); ++ } ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* End of tdls_com.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c +new file mode 100644 +index 000000000000..af66ef95d17c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c +@@ -0,0 +1,491 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1 ++*/ ++ ++/*! \file "wapi.c" ++ \brief This file including the WAPI related function. ++ ++ This file provided the macros and functions library support the wapi ie parsing, ++ cipher and AKM check to help the AP seleced deciding. ++*/ ++ ++/* ++** Log: wapi.c ++** ++** 10 24 2012 wh.su ++** [ALPS00376392] [klocwork 9.1] in wapi.c, line 344 ++** Use MAX_NUM_SUPPORTED_WAPI_AKM_SUITESfor avoid Klocwork warning. ++** ++** 10 24 2012 wh.su ++** [ALPS00376391] [klocwork 9.1] in wapi.c, line 311 ++** Use the MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES for avoid Klccwork waring. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function ++ * fixed the network type ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 07 20 2010 wh.su ++ * ++ * . ++ * ++ * 04 06 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the firmware return the broadcast frame at wrong tc. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function to check and update the default wapi tx ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the generate wapi ie function, and replace the tabe by space ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++#if CFG_SUPPORT_WAPI ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate WPA IE for ++* associate request frame. ++* ++* \param[in] prCurrentBss The Selected BSS description ++* ++* \retval The append WPA IE length ++* ++* \note ++* Called by: AIS module, Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); ++ ++ /* ASSOC INFO IE ID: 68 :0x44 */ ++ if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) { ++ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs, ++ prAdapter->prGlueInfo->u2WapiAssocInfoIESz); ++ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to parse WAPI IE. ++* ++* \param[in] prInfoElem Pointer to the RSN IE ++* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the ++** WAPI information from the given WAPI IE ++* ++* \retval TRUE - Succeeded ++* \retval FALSE - Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo) ++{ ++ UINT_32 i; ++ INT_32 u4RemainWapiIeLen; ++ UINT_16 u2Version; ++ UINT_16 u2Cap = 0; ++ UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_16 u2AuthSuiteCount = 0; ++ PUCHAR pucPairSuite = NULL; ++ PUCHAR pucAuthSuite = NULL; ++ PUCHAR cp; ++ ++ DEBUGFUNC("wapiParseWapiIE"); ++ ++ ASSERT(prInfoElem); ++ ASSERT(prWapiInfo); ++ ++ /* Verify the length of the WAPI IE. */ ++ if (prInfoElem->ucLength < 6) { ++ DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ /* Check WAPI version: currently, we only support version 1. */ ++ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); ++ if (u2Version != 1) { ++ DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", u2Version); ++ return FALSE; ++ } ++ ++ cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount; ++ u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2; ++ ++ do { ++ if (u4RemainWapiIeLen == 0) ++ break; ++ ++ /* ++ AuthCount : 2 ++ AuthSuite : 4 * authSuiteCount ++ PairwiseCount: 2 ++ PairwiseSuite: 4 * pairSuiteCount ++ GroupSuite : 4 ++ Cap : 2 */ ++ ++ /* Parse the Authentication and Key Management Cipher Suite Count ++ field. */ ++ if (u4RemainWapiIeLen < 2) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ cp += 2; ++ u4RemainWapiIeLen -= 2; ++ ++ /* Parse the Authentication and Key Management Cipher Suite List ++ field. */ ++ i = (UINT_32) u2AuthSuiteCount * 4; ++ if (u4RemainWapiIeLen < (INT_32) i) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucAuthSuite = cp; ++ ++ cp += i; ++ u4RemainWapiIeLen -= (INT_32) i; ++ ++ if (u4RemainWapiIeLen == 0) ++ break; ++ ++ /* Parse the Pairwise Key Cipher Suite Count field. */ ++ if (u4RemainWapiIeLen < 2) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ cp += 2; ++ u4RemainWapiIeLen -= 2; ++ ++ /* Parse the Pairwise Key Cipher Suite List field. */ ++ i = (UINT_32) u2PairSuiteCount * 4; ++ if (u4RemainWapiIeLen < (INT_32) i) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucPairSuite = cp; ++ ++ cp += i; ++ u4RemainWapiIeLen -= (INT_32) i; ++ ++ /* Parse the Group Key Cipher Suite field. */ ++ if (u4RemainWapiIeLen < 4) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ cp += 4; ++ u4RemainWapiIeLen -= 4; ++ ++ /* Parse the WAPI u2Capabilities field. */ ++ if (u4RemainWapiIeLen < 2) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2Cap); ++ u4RemainWapiIeLen -= 2; ++ ++ /* Todo:: BKID support */ ++ } while (FALSE); ++ ++ /* Save the WAPI information for the BSS. */ ++ ++ prWapiInfo->ucElemId = ELEM_ID_WAPI; ++ ++ prWapiInfo->u2Version = u2Version; ++ ++ prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite; ++ ++ DBGLOG(SEC, LOUD, "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", ++ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (pucPairSuite) { ++ /* The information about the pairwise key cipher suites is present. */ ++ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES) ++ u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES; ++ ++ prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucPairSuite, &prWapiInfo->au4PairwiseKeyCipherSuite[i]); ++ pucPairSuite += 4; ++ ++ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the pairwise key cipher suites is not present. ++ Use the default chipher suite for WAPI: WPI. */ ++ prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1; ++ prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI; ++ ++ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (pucAuthSuite) { ++ /* The information about the authentication and key management suites ++ is present. */ ++ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES) ++ u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES; ++ ++ prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]); ++ pucAuthSuite += 4; ++ ++ DBGLOG(SEC, LOUD, "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the authentication and key management suites ++ is not present. Use the default AKM suite for WAPI. */ ++ prWapiInfo->u4AuthKeyMgtSuiteCount = 1; ++ prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X; ++ ++ DBGLOG(SEC, LOUD, "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ prWapiInfo->u2WapiCap = u2Cap; ++ DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap); ++ ++ return TRUE; ++} /* wapiParseWapiIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to perform WAPI policy selection for a given BSS. ++* ++* \param[in] prAdapter Pointer to the adapter object data area. ++* \param[in] prBss Pointer to the BSS description ++* ++* \retval TRUE - The WAPI policy selection for the given BSS is ++* successful. The selected pairwise and group cipher suites ++* are returned in the BSS description. ++* \retval FALSE - The WAPI policy selection for the given BSS is failed. ++* The driver shall not attempt to join the given BSS. ++* ++* \note The Encrypt status matched score will save to bss for final ap select. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) ++{ ++ UINT_32 i; ++ UINT_32 u4PairwiseCipher = 0; ++ UINT_32 u4GroupCipher = 0; ++ UINT_32 u4AkmSuite = 0; ++ P_WAPI_INFO_T prBssWapiInfo; ++ P_WLAN_INFO_T prWlanInfo; ++ ++ DEBUGFUNC("wapiPerformPolicySelection"); ++ ++ ASSERT(prBss); ++ ++ /* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */ ++ prWlanInfo = &prAdapter->rWlanInfo; ++ ++ if (prBss->fgIEWAPI) { ++ prBssWapiInfo = &prBss->rIEWAPI; ++ } else { ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) { ++ DBGLOG(SEC, TRACE, "-- No Protected BSS\n"); ++ return TRUE; ++ } ++ DBGLOG(SEC, TRACE, "WAPI Information Element does not exist.\n"); ++ return FALSE; ++ } ++ ++ /* Select pairwise/group ciphers */ ++ for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] == ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) { ++ u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ if (prBssWapiInfo->u4GroupKeyCipherSuite == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher) ++ u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite; ++ ++ /* Exception handler */ ++ /* If we cannot find proper pairwise and group cipher suites to join the ++ BSS, do not check the supported AKM suites. */ ++ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { ++ DBGLOG(SEC, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++ ++ /* Select AKM */ ++ /* If the driver cannot support any authentication suites advertised in ++ the given BSS, we fail to perform RSNA policy selection. */ ++ /* Attempt to find any overlapping supported AKM suite. */ ++ for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) { ++ if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) { ++ u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i]; ++ break; ++ } ++ } ++ ++ if (u4AkmSuite == 0) { ++ DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n"); ++ return FALSE; ++ } ++ ++ DBGLOG(SEC, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4PairwiseCipher & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), ++ (UINT_8) (u4GroupCipher & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); ++ ++ DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4AkmSuite & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); ++ ++ return TRUE; ++} /* wapiPerformPolicySelection */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 . ++* ++* \param[in] prStaRec Pointer to the Sta record ++* \param[out] ucWlanIdx The Rx status->wlanidx field ++* ++* \retval TRUE - Succeeded ++* \retval FALSE - Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wapiUpdateTxKeyIdx(IN P_STA_RECORD_T prStaRec, IN UINT_8 ucWlanIdx) ++{ ++ UINT_8 ucKeyId; ++ ++ if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) { ++ ++ ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4); ++ ++ if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) { ++ DBGLOG(RSN, STATE, ++ "Change wapi key index from %d->%d\n", ++ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId); ++ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId; ++ ++ prStaRec->ucWTEntry = ++ (ucKeyId == ++ WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1; ++ } ++ } ++} ++#endif ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c +new file mode 100644 +index 000000000000..f54d22941148 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c +@@ -0,0 +1,301 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1 ++*/ ++ ++/*! \file "wnm.c" ++ \brief This file includes the 802.11v default vale and functions. ++*/ ++ ++/* ++** Log: wnm.c ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_802_11V ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define WNM_MAX_TOD_ERROR 0 ++#define WNM_MAX_TOA_ERROR 0 ++#define MICRO_TO_10NANO(x) ((x)*100) ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static UINT_8 ucTimingMeasToken; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11v wnm category action frame. ++* ++* ++* \note ++* Called by: Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_ACTION_FRAME prRxFrame; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++ if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) { ++ wnmTimingMeasRequest(prAdapter, prSwRfb); ++ return; ++ } ++#endif ++ ++ DBGLOG(WNM, TRACE, "Unsupport WNM action frame: %d\n", prRxFrame->ucAction); ++} ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to report timing measurement data. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); ++ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return; ++ ++ DBGLOG(WNM, TRACE, "wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA); ++ ++ if (!prStaRec->rWNMTimingMsmt.ucTrigger) ++ return; ++ ++ prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD); ++ prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle TxDone(TimingMeasurement) Event. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. ++* @param[in] rTxDoneStatus Return TX status of the Timing Measurement frame. ++* ++* @retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ DBGLOG(WNM, LOUD, "EVENT-TX DONE: Current Time = %u\n", kalGetTimeTick()); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ ++ ++ DBGLOG(WNM, TRACE, "wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x", ++ prStaRec->rWNMTimingMsmt.ucDialogToken, ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken, ++ prStaRec->rWNMTimingMsmt.u4ToD, prStaRec->rWNMTimingMsmt.u4ToA); ++ ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; ++ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; ++ ++ wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wnmRunEventTimgingMeasTxDone() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Timing Measurement frame. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame; ++ UINT_16 u2PayloadLen; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ASSERT(prBssInfo); ++ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ ++ if (!prMsduInfo) ++ return; ++ ++ prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION; ++ prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT; ++ ++ /* 3 Compose the frame body's frame. */ ++ prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; ++ prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken; ++ prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD; ++ prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA; ++ prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR; ++ prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR; ++ ++ u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ DBGLOG(WNM, TRACE, "wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n", ++ prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, ++ prTxFrame->u4ToD, prTxFrame->u4ToA); ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return; ++ ++} /* end of wnmComposeTimingMeasFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11v timing measurement request. ++* ++* ++* \note ++* Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL; ++ P_STA_RECORD_T prStaRec; ++ ++ prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME) prSwRfb->pvHeader; ++ if (!prRxFrame) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return; ++ ++ DBGLOG(WNM, TRACE, "IEEE 802.11: Received Timing Measuremen Request from %pM\n" ++ prStaRec->aucMacAdd); ++ ++ /* reset timing msmt */ ++ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; ++ prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger; ++ if (!prRxFrame->ucTrigger) ++ return; ++ ++ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; ++ ++ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); ++} ++ ++#if WNM_UNIT_TEST ++VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return; ++ ++ DBGLOG(WNM, INFO, "IEEE 802.11v: Test Timing Measuremen Request from %pM\n", ++ prStaRec->aucMacAddr); ++ ++ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; ++ prStaRec->rWNMTimingMsmt.ucTrigger = 1; ++ ++ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; ++ ++ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); ++} ++#endif ++ ++#endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */ ++ ++#endif /* CFG_SUPPORT_802_11V */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c +new file mode 100644 +index 000000000000..6f1bb6fd771e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c +@@ -0,0 +1,254 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/cmd_buf.c#1 ++*/ ++ ++/*! \file "cmd_buf.c" ++ \brief This file contain the management function of internal Command Buffer ++ for CMD_INFO_T. ++ ++ We'll convert the OID into Command Packet and then send to FW. Thus we need ++ to copy the OID information to Command Buffer for following reasons. ++ 1. The data structure of OID information may not equal to the data structure of ++ Command, we cannot use the OID buffer directly. ++ 2. If the Command was not generated by driver we also need a place to store the ++ information. ++ 3. Because the CMD is NOT FIFO when doing memory allocation (CMD will be generated ++ from OID or interrupt handler), thus we'll use the Block style of Memory Allocation ++ here. ++*/ ++ ++/* ++** Log: cmd_buf.c ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. clear prPendingCmdInfo properly ++ * * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-13 21:59:08 GMT mtk01084 ++** remove un-neceasary spaces ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-05-20 12:24:26 GMT mtk01461 ++** Increase CMD Buffer - HIF_RX_HW_APPENDED_LEN when doing CMD_INFO_T allocation ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 09:41:08 GMT mtk01461 ++** Add init of Driver Domain MCR flag and fix lint MTK WARN ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-17 19:51:45 GMT mtk01461 ++** allocation function of CMD_INFO_T ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static BOOLEAN fgCmdDumpIsDone = FALSE; ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initial the MGMT memory pool for CMD Packet. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ QUEUE_INITIALIZE(&prAdapter->rFreeCmdList); ++ ++ for (i = 0; i < CFG_TX_MAX_CMD_PKT_NUM; i++) { ++ prCmdInfo = &prAdapter->arHifCmdDesc[i]; ++ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); ++ } ++ fgCmdDumpIsDone = FALSE; ++} /* end of cmdBufInitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief dump CMD queue and print to trace, for debug use only ++* @param[in] prQueue Pointer to the command Queue to be dumped ++* @param[in] quename Name of the queue ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName) ++{ ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_HEAD(prQueue); ++ ++ DBGLOG(NIC, INFO, "Dump CMD info for %s, Elem number:%u\n", queName, prQueue->u4NumElem); ++ while (prCmdInfo) { ++ P_CMD_INFO_T prCmdInfo1, prCmdInfo2, prCmdInfo3; ++ ++ prCmdInfo1 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo); ++ if (!prCmdInfo1) { ++ DBGLOG(NIC, INFO, "CID:%d SEQ:%d\n", prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); ++ break; ++ } ++ prCmdInfo2 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo1); ++ if (!prCmdInfo2) { ++ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, ++ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum); ++ break; ++ } ++ prCmdInfo3 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo2); ++ if (!prCmdInfo3) { ++ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, ++ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum, ++ prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum); ++ break; ++ } ++ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", ++ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, ++ prCmdInfo1->ucCmdSeqNum, prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum, ++ prCmdInfo3->ucCID, prCmdInfo3->ucCmdSeqNum); ++ prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo3); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Allocate CMD_INFO_T from a free list and MGMT memory pool. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] u4Length Length of the frame buffer to allocate. ++* ++* @retval NULL Pointer to the valid CMD Packet handler ++* @retval !NULL Fail to allocat CMD Packet ++*/ ++/*----------------------------------------------------------------------------*/ ++P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("cmdBufAllocateCmdInfo"); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ if (prCmdInfo) { ++ /* Setup initial value in CMD_INFO_T */ ++ /* Start address of allocated memory */ ++ prCmdInfo->pucInfoBuffer = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); ++ ++ if (prCmdInfo->pucInfoBuffer == NULL) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ prCmdInfo = NULL; ++ ++ DBGLOG(NIC, ERROR, "Allocate prCmdInfo->pucInfoBuffer fail!\n"); ++ } else { ++ prCmdInfo->u2InfoBufLen = 0; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ } ++ fgCmdDumpIsDone = FALSE; ++ } else if (!fgCmdDumpIsDone) { ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ P_QUE_T prCmdQue = &prGlueInfo->rCmdQueue; ++ P_QUE_T prPendingCmdQue = &prAdapter->rPendingCmdQueue; ++ P_TX_TCQ_STATUS_T prTc = &prAdapter->rTxCtrl.rTc; ++ ++ fgCmdDumpIsDone = TRUE; ++ cmdBufDumpCmdQueue(prCmdQue, "waiting Tx CMD queue"); ++ cmdBufDumpCmdQueue(prPendingCmdQue, "waiting response CMD queue"); ++ DBGLOG(NIC, INFO, "Tc4 number:%d\n", prTc->aucFreeBufferCount[TC4_INDEX]); ++ if (prTc->aucFreeBufferCount[TC4_INDEX] != 0) ++ glDoChipReset(); ++ } ++ ++ return prCmdInfo; ++ ++} /* end of cmdBufAllocateCmdInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to free the CMD Packet to the MGMT memory pool. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo CMD Packet handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("cmdBufFreeCmdInfo"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo) { ++ if (prCmdInfo->pucInfoBuffer) { ++ cnmMemFree(prAdapter, prCmdInfo->pucInfoBuffer); ++ prCmdInfo->pucInfoBuffer = NULL; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ } ++ ++ return; ++ ++} /* end of cmdBufFreeCmdPacket() */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c +new file mode 100644 +index 000000000000..dfaaedd118bf +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c +@@ -0,0 +1,4062 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#2 ++*/ ++ ++/*! \file nic.c ++ \brief Functions that provide operation in NIC's (Network Interface Card) point of view. ++ ++ This file includes functions which unite multiple hal(Hardware) operations ++ and also take the responsibility of Software Resource Management in order ++ to keep the synchronization with Hardware Manipulation. ++*/ ++ ++/* ++** Log: nic.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 05 02 2012 terry.wu ++ * NULL ++ * Set the default value of AP StaRec index to "STA_REC_INDEX_NOT_FOUND" in update firmware bss command. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 11 28 2011 cp.wu ++ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when ++ * returining to ROM code ++ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware ++ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not ++ * ++ * 11 22 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * keep debug counter setting after wake up. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001079] [MT5931][Driver] Release pending MMPDU only when BSS is being deactivated ++ * pre-check for NULL before calling MMPDU free function ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. ++ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to ++ * the AP.. ++ * ++ * 10 11 2011 terry.wu ++ * NULL ++ * Rewrite Assert Dump Function for Portability. ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * New CMD definition about RLM parameters ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device ++ * issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 11 2011 wh.su ++ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for ++ * customer not enable WAPI ++ * For make sure wapi initial value is set. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky ++ * AP which use space character as hidden SSID ++ * 1. correct logic ++ * 2. replace only BSS-DESC which doesn't have a valid SSID. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky ++ * AP which use space character as hidden SSID ++ * allow to have a single BSSID with multiple SSID to be presented in scanning result ++ * ++ * 05 12 2011 puff.wen ++ * NULL ++ * FW Assert information dump to driver ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 15 2011 cp.wu ++ * [WCXRP00000651] [MT6620 Wi-Fi][Driver] Refine RSSI buffering mechanism ++ * ROLLBACK due to the special design is to workaround incorrect initial RCPI value coming from firmware domain. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 14 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected ++ * 2. add dummy function for both Win32 and Linux part. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for ++ * dedicated network type ++ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected ++ * ++ * 04 12 2011 wh.su ++ * NULL ++ * enable the p2p check the cipher to set the bssInfo auth mode. ++ * ++ * 04 12 2011 wh.su ++ * NULL ++ * prepare the code for sync the auth mode and encryption status for P2P and BOW. ++ * ++ * 04 11 2011 yuche.tsai ++ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. ++ * Fix kernel panic issue when MMPDU of P2P is pending in driver. ++ * ++ * 04 10 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * Fix compiler issue. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 04 07 2011 cp.wu ++ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside ++ * wlanAdapterStart ++ * . ++ * ++ * 04 07 2011 cp.wu ++ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside ++ * wlanAdapterStart ++ * implementation of internal error handling of nicAllocateAdapterMemory. ++ * ++ * 03 31 2011 chinglan.wang ++ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. ++ * . ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 08 2011 terry.wu ++ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log ++ * Use kalPrint to print firmware assert info. ++ * ++ * 02 01 2011 terry.wu ++ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log ++ * . ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 31 2011 terry.wu ++ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log ++ * Print firmware ASSERT info at Android kernel log, driver side ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 19 2011 cp.wu ++ * [WCXRP00000372] [MT6620 Wi-Fi][Driver] Check bus access failure inside nicProcessIST() ++ * check bus error and/or card removal when retrieving interrupt status from HAL ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * 1) correct typo in scan.c ++ * 2) TX descriptors, RX descriptos and management buffer should use virtually continuous buffer instead of ++ * physically contineous one ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * host driver not to set FW-own when there is still pending interrupts ++ * ++ * 12 17 2010 cp.wu ++ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged ++ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 02 2010 eddie.chen ++ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry ++ * Add more control value but dont use it now. ++ * ++ * 11 30 2010 eddie.chen ++ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry ++ * Add auto rate check window in registry ++ * ++ * 11 10 2010 eddie.chen ++ * [WCXRP00000156] [MT6620][FW] Change Auto rate window to 64 and add throughput swcr ++ * Use autorate parameter 1 as phy rate mask. ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to ++ * BSOD when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A ++ * reset ptrs when IEs are going to be dropped ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * add HT (802.11n) fixed rate support. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test ++ * with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * Androi/Linux: return current operating channel information ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Fix someones coding error while enable WIFI_DIRECT. ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Add state change indication. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add support for P2P BSS update info. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [removing debugging] not to dump beacon content. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 11 2010 cp.wu ++ * NULL ++ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) ++ * 2) extending scanning result to 64 instead of 48 ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 23 2010 cp.wu ++ * ++ * FIX: structure of CMD_SET_BSS_INFO has been changed but no follow-ups are done. ++ * ++ * 07 22 2010 george.huang ++ * ++ * . ++ * ++ * 07 22 2010 george.huang ++ * ++ * Update fgIsQoS information in BSS INFO by CMD ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * update prStaRecOfAP with BSS-INFO. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * STA-REC is maintained by CNM only. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill fgIsUapsdConnection when indicating BSS-CREATE with AIS-STA mode. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement TX_DONE callback path. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * TX descriptors are now allocated once for reducing allocation overhead ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add channel frequency <-> number conversion ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver ++ * correct nicProcessIST_impl() for interrupt status brought up by RX enhanced response ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always process TX interrupt first then RX interrupt. ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-16 18:03:43 GMT mtk02752 ++** handling enhanced response which fields are fetched at different moments ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-15 17:00:29 GMT mtk02752 ++** if RX enhanced response is used, D2H interrupt status should be coming from buffered result as well ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-15 12:01:55 GMT mtk02752 ++** if TX_DONE bit is not set but WTSR0/WTSR1 is non-zero, then set TX_DONE ++** bit due to time latency of interrupt status enhanced response ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:52:52 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-24 20:51:01 GMT mtk02752 ++** integrate with SD1 by invoking qmHandleMailboxRxMessage() ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-16 17:32:33 GMT mtk02752 ++** prepare code for invoking rxHandleMailboxRxMessage() ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:08 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-09 22:56:41 GMT mtk01084 ++** modify HW access routines ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:20 GMT mtk01084 ++** prevent warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:54:57 GMT mtk01084 ++** init HIF ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:30 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:12 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-09-09 17:26:15 GMT mtk01084 ++** modify for CFG_TEST_WITH_MT5921 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-19 10:55:22 GMT mtk01461 ++** Unmask the unused HISR ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-18 15:59:13 GMT mtk01084 ++** remove debug purpose code ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 14:05:02 GMT mtk01084 ++** update for WIFI ownback part on initial ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-04 21:32:57 GMT mtk01084 ++** add temporarily code to set driver own on adapter initialization ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:35:41 GMT mtk01461 ++** Add init of TX aggregation and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-24 21:12:10 GMT mtk01104 ++** Add function nicRestoreSpiDefMode() ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:43:31 GMT mtk01461 ++** Revise for MTK coding style - nicInitializeAdapter() ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:52:47 GMT mtk01461 ++** Update allocate Adapter Memory for MGMT Memory pool ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:57:08 GMT mtk01461 ++** Refine the order of release memory from pucRxCoalescingBufCached ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-19 18:32:57 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:00:14 GMT mtk01426 ++** Add CFG_SDIO_RX_ENHANCE support ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:27 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:25:59 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++const UINT_8 aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] = { ++ PHY_TYPE_SET_802_11ABG, /* PHY_CONFIG_802_11ABG */ ++ PHY_TYPE_SET_802_11BG, /* PHY_CONFIG_802_11BG */ ++ PHY_TYPE_SET_802_11G, /* PHY_CONFIG_802_11G */ ++ PHY_TYPE_SET_802_11A, /* PHY_CONFIG_802_11A */ ++ PHY_TYPE_SET_802_11B, /* PHY_CONFIG_802_11B */ ++ PHY_TYPE_SET_802_11ABGN, /* PHY_CONFIG_802_11ABGN */ ++ PHY_TYPE_SET_802_11BGN, /* PHY_CONFIG_802_11BGN */ ++ PHY_TYPE_SET_802_11AN, /* PHY_CONFIG_802_11AN */ ++ PHY_TYPE_SET_802_11GN /* PHY_CONFIG_802_11GN */ ++}; ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++#define REQ_GATING_ENABLE_H2D_INT BIT(31) ++#define REQ_GATING_DISABLE_H2D_INT BIT(30) ++#define ACK_GATING_ENABLE_D2H_INT BIT(31) ++#define ACK_GATING_DISABLE_D2H_INT BIT(30) ++ ++#define GATING_CONTROL_POLL_LIMIT 64 ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++static INT_EVENT_MAP_T arIntEventMapTable[] = { ++ {WHISR_ABNORMAL_INT, INT_EVENT_ABNORMAL}, ++ {WHISR_D2H_SW_INT, INT_EVENT_SW_INT}, ++ {WHISR_TX_DONE_INT, INT_EVENT_TX}, ++ {(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX} ++}; ++ ++static const UINT_8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T)); ++ ++static IST_EVENT_FUNCTION apfnEventFuncTable[] = { ++ nicProcessAbnormalInterrupt, /*!< INT_EVENT_ABNORMAL */ ++ nicProcessSoftwareInterrupt, /*!< INT_EVENT_SW_INT */ ++ nicProcessTxInterrupt, /*!< INT_EVENT_TX */ ++ nicProcessRxInterrupt, /*!< INT_EVENT_RX */ ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory() ++ * and also enhance the readability. ++ */ ++#define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \ ++ { \ ++ DBGLOG(NIC, INFO, "Allocating %u bytes for %s.\n", u4Size, pucComment); \ ++ pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType); \ ++ if (pucMem == (PUINT_8)NULL) { \ ++ DBGLOG(NIC, ERROR, "Could not allocate %u bytes for %s.\n", u4Size, pucComment); \ ++ break; \ ++ } \ ++ ASSERT(((ULONG)pucMem % 4) == 0); \ ++ DBGLOG(NIC, TRACE, "Virtual Address = %p for %s.\n", pucMem, pucComment); \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter) ++{ ++ dumpMemory32((PUINT_32)prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++} ++ ++VOID HifRegDump(P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ UINT_32 RegVal = 0; ++ ++ for (i = 0; i <= 0x58; i += 4) { ++ if ((i != MCR_WTDR0) && (i != MCR_WTDR1) && (i != MCR_WRDR0) && ++ (i != MCR_WRDR1) && (i != MCR_WSDIOCSR) && (i != MCR_WRPLR)) { ++ HAL_MCR_RD(prAdapter, i, &RegVal); ++ DBGLOG(NIC, WARN, "HIF Reg 0x%x = 0x%x\n", i, RegVal); ++ } ++ } ++ DBGLOG(NIC, WARN, "\n\n"); ++} ++ ++BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter) ++{ ++ return prAdapter->fgIsFwOwn; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is responsible for the allocation of the data structures ++* inside the Adapter structure, include: ++* 1. SW_RFB_Ts ++* 2. Common coalescing buffer for TX PATH. ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @retval WLAN_STATUS_SUCCESS - Has enough memory. ++* @retval WLAN_STATUS_RESOURCES - Memory is not enough. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS status = WLAN_STATUS_RESOURCES; ++ P_RX_CTRL_T prRxCtrl; ++ P_TX_CTRL_T prTxCtrl; ++ ++ DEBUGFUNC("nicAllocateAdapterMemory"); ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ do { ++ /* 4 <0> Reset all Memory Handler */ ++#if CFG_DBG_MGT_BUF ++ prAdapter->u4MemFreeDynamicCount = 0; ++ prAdapter->u4MemAllocDynamicCount = 0; ++#endif ++ prAdapter->pucMgtBufCached = (PUINT_8) NULL; ++ prRxCtrl->pucRxCached = (PUINT_8) NULL; ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; ++ ++ /* 4 <1> Memory for Management Memory Pool and CMD_INFO_T */ ++ /* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */ ++ prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE; ++ ++ LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached, ++ prAdapter->u4MgtBufCachedSize, VIR_MEM_TYPE, "COMMON MGMT MEMORY POOL"); ++ ++ /* 4 <2> Memory for RX Descriptor */ ++ /* Initialize the number of rx buffers we will have in our queue. */ ++ /* We may setup ucRxPacketDescriptors by GLUE Layer, and using ++ * this variable directly. ++ */ ++ /* Allocate memory for the SW receive structures. */ ++ prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * ALIGN_4(sizeof(SW_RFB_T)); ++ ++ LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize, VIR_MEM_TYPE, "SW_RFB_T"); ++ ++ /* 4 <3> Memory for TX DEscriptor */ ++ prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * ALIGN_4(sizeof(MSDU_INFO_T)); ++ ++ LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, prTxCtrl->u4TxCachedSize, VIR_MEM_TYPE, "MSDU_INFO_T"); ++ ++ /* 4 <4> Memory for Common Coalescing Buffer */ ++#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG ++ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; ++ ++ /* Allocate memory for the common coalescing buffer. */ ++ prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ? ++ CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE; ++ ++ prAdapter->pucCoalescingBufCached = kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize); ++ ++ if (prAdapter->pucCoalescingBufCached == NULL) { ++ DBGLOG(NIC, ERROR, ++ "Could not allocate %u bytes for coalescing buffer.\n", ++ prAdapter->u4CoalescingBufCachedSize); ++ break; ++ } ++#endif /* CFG_COALESCING_BUFFER_SIZE */ ++ ++ /* 4 <5> Memory for enhanced interrupt response */ ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) ++ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ ++ if (prAdapter->prSDIOCtrl == NULL) { ++ DBGLOG(NIC, ERROR, ++ "Could not allocate %zu bytes for interrupt response.\n", ++ sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ break; ++ } ++ ++ status = WLAN_STATUS_SUCCESS; ++ ++ } while (FALSE); ++ ++ if (status != WLAN_STATUS_SUCCESS) ++ nicReleaseAdapterMemory(prAdapter); ++ ++ return status; ++ ++} /* end of nicAllocateAdapterMemory() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is responsible for releasing the allocated memory by ++* nicAllocatedAdapterMemory(). ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ /* 4 <5> Memory for enhanced interrupt response */ ++ if (prAdapter->prSDIOCtrl) { ++ kalReleaseIOBuffer((PVOID) prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; ++ } ++ /* 4 <4> Memory for Common Coalescing Buffer */ ++#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG ++ if (prAdapter->pucCoalescingBufCached) { ++ kalReleaseIOBuffer((PVOID) prAdapter->pucCoalescingBufCached, prAdapter->u4CoalescingBufCachedSize); ++ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; ++ } ++#endif /* CFG_COALESCING_BUFFER_SIZE */ ++ ++ /* 4 <3> Memory for TX Descriptor */ ++ if (prTxCtrl->pucTxCached) { ++ kalMemFree((PVOID) prTxCtrl->pucTxCached, VIR_MEM_TYPE, prTxCtrl->u4TxCachedSize); ++ prTxCtrl->pucTxCached = (PUINT_8) NULL; ++ } ++ /* 4 <2> Memory for RX Descriptor */ ++ if (prRxCtrl->pucRxCached) { ++ kalMemFree((PVOID) prRxCtrl->pucRxCached, VIR_MEM_TYPE, prRxCtrl->u4RxCachedSize); ++ prRxCtrl->pucRxCached = (PUINT_8) NULL; ++ } ++ /* 4 <1> Memory for Management Memory Pool */ ++ if (prAdapter->pucMgtBufCached) { ++ kalMemFree((PVOID) prAdapter->pucMgtBufCached, VIR_MEM_TYPE, prAdapter->u4MgtBufCachedSize); ++ prAdapter->pucMgtBufCached = (PUINT_8) NULL; ++ } ++#if CFG_DBG_MGT_BUF ++ /* Check if all allocated memories are free */ ++ ASSERT(prAdapter->u4MemFreeDynamicCount == prAdapter->u4MemAllocDynamicCount); ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief disable global interrupt ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ prAdapter->fgIsIntEnable = FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief enable global interrupt ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ BOOLEAN fgIsIntEnableCache; ++ ++ ASSERT(prAdapter); ++ fgIsIntEnableCache = prAdapter->fgIsIntEnable; ++ ++ prAdapter->fgIsIntEnable = TRUE; /* NOTE(Kevin): It must be placed before MCR GINT write. */ ++ ++ /* If need enable INT and also set LPOwn at the same time. */ ++ if (prAdapter->fgIsIntEnableWithLPOwnSet) { ++ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; /* NOTE(Kevin): It's better to place it ++ * before MCR GINT write. ++ */ ++ /* If INT was enabled, only set LPOwn */ ++ if (fgIsIntEnableCache) { ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); ++ prAdapter->fgIsFwOwn = TRUE; ++ } ++ /* If INT was not enabled, enable it and also set LPOwn now */ ++ else { ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET | WHLPCR_INT_EN_SET); ++ prAdapter->fgIsFwOwn = TRUE; ++ } ++ } ++ /* If INT was not enabled, enable it now */ ++ else if (!fgIsIntEnableCache) ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++} /* end of nicEnableInterrupt() */ ++ ++#if CFG_SDIO_INTR_ENHANCE ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief For SDIO enhance mode, set the max rx len and tx status ++* ++* @param prAdapter a pointer to adapter private data structure. ++* ++* @return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicSDIOInit(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4Value = 0; ++ ++ ASSERT(prAdapter); ++ ++ /* 4 <1> Check STATUS Buffer is DW alignment. */ ++ ASSERT(IS_ALIGN_4((ULONG)&prAdapter->prSDIOCtrl->u4WHISR)); ++ ++ /* 4 <2> Setup STATUS count. */ ++ { ++ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value); ++ ++ /* 4 <2.1> Setup the number of maximum RX length to be report */ ++ u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM); ++ u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM)); ++ ++ /* 4 <2.2> Setup RX enhancement mode */ ++#if CFG_SDIO_RX_ENHANCE ++ u4Value |= WHCR_RX_ENHANCE_MODE_EN; ++#else ++ u4Value &= ~WHCR_RX_ENHANCE_MODE_EN; ++#endif /* CFG_SDIO_RX_AGG */ ++ ++ HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value); ++ } ++ ++ return; ++ ++} /* end of nicSDIOInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read interrupt status from hardware ++* ++* @param prAdapter pointer to the Adapter handler ++* @param the interrupts ++* ++* @return N/A ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus) ++{ ++ P_SDIO_CTRL_T prSDIOCtrl; ++ ++ DEBUGFUNC("nicSDIOReadIntStatus"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4IntStatus); ++ ++ /* ++ prSDIOCtrl is from IO buffer. ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) ++ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ */ ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++ ASSERT(prSDIOCtrl); ++ ++ HAL_PORT_RD(prAdapter, ++ MCR_WHISR, ++ sizeof(ENHANCE_MODE_DATA_STRUCT_T), (PUINT_8) prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ *pu4IntStatus = 0; ++ return; ++ } ++ ++ /* workaround */ ++ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && ++ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { ++ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; ++ } ++ ++ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && ++ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && ++ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { ++ prSDIOCtrl->u4WHISR |= BIT(31); ++ } ++ ++ *pu4IntStatus = prSDIOCtrl->u4WHISR; ++ ++} /* end of nicSDIOReadIntStatus() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function used to read interrupt status and then invoking ++* dispatching procedure for the appropriate functions ++* corresponding to specific interrupt bits ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @retval WLAN_STATUS_SUCCESS ++* @retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_32 u4IntStatus = 0; ++ UINT_32 i; ++ ++ DEBUGFUNC("nicProcessIST"); ++ /* DBGLOG(NIC, LOUD, ("\n")); */ ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(REQ, WARN, "Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ ++ for (i = 0; i < CFG_IST_LOOP_COUNT; i++) { /* CFG_IST_LOOP_COUNT = 1 */ ++ ++#if CFG_SDIO_INTR_ENHANCE ++ nicSDIOReadIntStatus(prAdapter, &u4IntStatus); ++#else ++ HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++/* DBGLOG(NIC, TRACE, ("u4IntStatus: 0x%x\n", u4IntStatus)); */ ++ ++ if (u4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) { ++ DBGLOG(INTR, WARN, "Un-handled HISR %#x, HISR = %#x (HIER:0x%x)\n", ++ (UINT_32) (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus, ++ (UINT_32) WHIER_DEFAULT); ++ u4IntStatus &= WHIER_DEFAULT; ++ } ++ ++ nicProcessIST_impl(prAdapter, u4IntStatus); ++ ++ if (u4IntStatus == 0) { ++ if (i == 0) ++ u4Status = WLAN_STATUS_NOT_INDICATING; ++ break; ++ } ++ } ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ nicEnableClockGating(prAdapter); ++#endif ++ ++ return u4Status; ++} /* end of nicProcessIST() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function used to dispatch the appropriate functions for specific ++* interrupt bits ++* ++* @param prAdapter pointer to the Adapter handler ++* u4IntStatus interrupt status bits ++* ++* @retval WLAN_STATUS_SUCCESS ++* @retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus) ++{ ++ UINT_32 u4IntCount = 0; ++ P_INT_EVENT_MAP_T prIntEventMap = NULL; ++ ++ ASSERT(prAdapter); ++ ++ prAdapter->u4IntStatus = u4IntStatus; ++ ++ /* Process each of the interrupt status consequently */ ++ prIntEventMap = &arIntEventMapTable[0]; ++ for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) { ++ if (prIntEventMap->u4Int & prAdapter->u4IntStatus) { ++ if (prIntEventMap->u4Event == INT_EVENT_RX && prAdapter->fgIsEnterD3ReqIssued == TRUE) { ++ /* ignore */ ++ } else if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) { ++ apfnEventFuncTable[prIntEventMap->u4Event] (prAdapter); ++ } else { ++ DBGLOG(INTR, WARN, ++ "Empty INTR handler! ISAR bit#: %u, event:%u, func: %p\n", ++ prIntEventMap->u4Int, prIntEventMap->u4Event, ++ apfnEventFuncTable[prIntEventMap->u4Event]); ++ ++ ASSERT(0); /* to trap any NULL interrupt handler */ ++ } ++ prAdapter->u4IntStatus &= ~prIntEventMap->u4Int; ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of nicProcessIST_impl() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Verify the CHIP ID ++* ++* @param prAdapter a pointer to adapter private data structure. ++* ++* ++* @retval TRUE CHIP ID is the same as the setting compiled ++* @retval FALSE CHIP ID is different from the setting compiled ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4CIR = 0; ++ ++ ASSERT(prAdapter); ++ ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR); ++ ++ DBGLOG(NIC, TRACE, "Chip ID: 0x%x\n", (UINT_32) (u4CIR & WCIR_CHIP_ID)); ++ DBGLOG(NIC, TRACE, "Revision ID: 0x%x\n", (UINT_32) ((u4CIR & WCIR_REVISION_ID) >> 16)); ++ ++#if 0 ++ if (((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_72) && ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_82)) ++ return FALSE; ++#endif ++ ++ prAdapter->ucRevID = (UINT_8) (((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the MCR to the appropriate init value, and verify the init ++* value ++* ++* @param prAdapter a pointer to adapter private data structure. ++* ++* @return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicMCRInit(IN P_ADAPTER_T prAdapter) ++{ ++ ++ ASSERT(prAdapter); ++ ++ /* 4 <0> Initial value */ ++} ++ ++VOID nicHifInit(IN P_ADAPTER_T prAdapter) ++{ ++ ++ ASSERT(prAdapter); ++#if 0 ++ /* reset event */ ++ nicPutMailbox(prAdapter, 0, 0x52455345); /* RESE */ ++ nicPutMailbox(prAdapter, 1, 0x545F5746); /* T_WF */ ++ nicSetSwIntr(prAdapter, BIT(16)); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the Adapter soft variable ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ++ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; ++ ++ do { ++ if (!nicVerifyChipID(prAdapter)) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ /* 4 <1> MCR init */ ++ nicMCRInit(prAdapter); ++ ++#if CFG_SDIO_INTR_ENHANCE ++ nicSDIOInit(prAdapter); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT); ++ ++ /* 4 <2> init FW HIF */ ++ nicHifInit(prAdapter); ++ } while (FALSE); ++ ++ return u4Status; ++} ++ ++#if defined(_HIF_SPI) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Restore the SPI Mode Select to default mode, ++* this is important while driver is unload, and this must be last mcr ++* since the operation will let the hif use 8bit mode access ++* ++* \param[in] prAdapter a pointer to adapter private data structure. ++* \param[in] eGPIO2_Mode GPIO2 operation mode ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA); ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process rx interrupt. When the rx ++* Interrupt is asserted, it means there are frames in queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4Value = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prGlueInfo->IsrAbnormalCnt++; ++ HAL_MCR_RD(prAdapter, MCR_WASR, &u4Value); ++ DBGLOG(REQ, WARN, "MCR_WASR: 0x%x\n", u4Value); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief . ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessFwOwnBackInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ ++} /* end of nicProcessFwOwnBackInterrupt() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief . ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4IntrBits; ++ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31); ++ ++ prGlueInfo->IsrSoftWareCnt++; ++ ++ if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) { ++ nicPrintFirmwareAssertInfo(prAdapter); ++#if CFG_CHIP_RESET_SUPPORT ++ glSendResetRequest(); ++#endif ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ ASSERT((u4IntrBits & (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)) ++ != (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)); ++ ++ if (u4IntrBits & ACK_GATING_ENABLE_D2H_INT) ++ prAdapter->fgIsClockGatingEnabled = TRUE; ++ ++ if (u4IntrBits & ACK_GATING_DISABLE_D2H_INT) { ++ prAdapter->fgIsClockGatingEnabled = FALSE; ++ ++ /* Indicate Service Thread for TX */ ++ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ } ++#endif ++ ++ DBGLOG(REQ, WARN, "u4IntrBits: 0x%x\n", u4IntrBits); ++} /* end of nicProcessSoftwareInterrupt() */ ++ ++VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data) ++{ ++ if (u4MailboxNum == 0) { ++ /* HAL_MCR_WR */ ++ HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data); ++ } else if (u4MailboxNum == 1) { ++ /* HAL_MCR_WR */ ++ HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data) ++{ ++ if (u4MailboxNum == 0) { ++ /* HAL_MCR_RD */ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data); ++ } else if (u4MailboxNum == 1) { ++ /* HAL_MCR_RD */ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap) ++{ ++ /* NOTE: ++ * SW interrupt in HW bit 16 is mapping to SW bit 0 (shift 16bit in HW transparancy) ++ * SW interrupt valid from b0~b15 ++ */ ++ ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0); ++/* DBGLOG(NIC, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap)); */ ++ ++ HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue ++* with specified sequential number ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ucSeqNum Sequential Number ++* ++* @retval - P_CMD_INFO_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ prCmdQue = &prAdapter->rPendingCmdQueue; ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->ucCmdSeqNum == ucSeqNum) ++ break; ++ ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ ++ prCmdInfo = NULL; ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ return prCmdInfo; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to dequeue from prAdapter->rTxCtrl.rTxMgmtTxingQueue ++* with specified sequential number ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ucSeqNum Sequential Number ++* ++* @retval - P_MSDU_INFO_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) ++{ ++ P_QUE_T prTxingQue; ++ QUE_T rTempQue; ++ P_QUE_T prTempQue = &rTempQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ QUEUE_MOVE_ALL(prTempQue, prTxingQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ if (prMsduInfo->ucTxSeqNum == ucSeqNum) ++ break; ++ ++ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); ++ ++ prMsduInfo = NULL; ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ return prMsduInfo; ++} ++ ++P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx) ++{ ++ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; ++ P_QUE_T prTxingQue = (P_QUE_T) NULL; ++ QUE_T rTempQue; ++ P_QUE_T prTempQue = &rTempQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ if (prAdapter == NULL) { ++ ASSERT(FALSE); ++ return NULL; ++ } ++ ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ do { ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ QUEUE_MOVE_ALL(prTempQue, prTxingQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ if ((prMsduInfo->ucStaRecIndex == ucStaRecIdx) && (prMsduInfo->pfTxDoneHandler != NULL)) { ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfo, prMsduInfoListHead); ++ prMsduInfoListHead = prMsduInfo; ++ } else { ++ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); ++ ++ prMsduInfo = NULL; ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ } while (FALSE); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ return prMsduInfoListHead; ++} /* nicGetPendingStaMMPDU */ ++ ++VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) ++{ ++ P_QUE_T prTxingQue; ++ QUE_T rTempQue; ++ P_QUE_T prTempQue = &rTempQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; ++ P_MSDU_INFO_T prMsduInfoListTail = (P_MSDU_INFO_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ QUEUE_MOVE_ALL(prTempQue, prTxingQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ if ((ENUM_NETWORK_TYPE_INDEX_T) (prMsduInfo->ucNetworkType) == eNetworkType) { ++ if (prMsduInfoListHead == NULL) { ++ prMsduInfoListHead = prMsduInfoListTail = prMsduInfo; ++ } else { ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, prMsduInfo); ++ prMsduInfoListTail = prMsduInfo; ++ } ++ } else { ++ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); ++ ++ prMsduInfo = NULL; ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ /* free */ ++ if (prMsduInfoListHead) ++ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); ++ ++ return; ++ ++} /* end of nicFreePendingTxMsduInfoByNetwork() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to retrieve a CMD sequence number atomically ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval - UINT_8 ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucRetval; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); ++ ++ prAdapter->ucCmdSeqNum++; ++ ucRetval = prAdapter->ucCmdSeqNum; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); ++ ++ return ucRetval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to retrieve a TX sequence number atomically ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval - UINT_8 ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucRetval; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); ++ ++ prAdapter->ucTxSeqNum++; ++ ucRetval = prAdapter->ucTxSeqNum; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); ++ ++ return ucRetval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to handle ++* media state change event ++* ++* @param ++* ++* @retval ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicMediaStateChange(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ ASSERT(prAdapter); ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ switch (eNetworkType) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { /* disconnected */ ++ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ DBGLOG(NIC, TRACE, "DisByMC\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ } ++ ++ /* reset buffered link quality information */ ++ prAdapter->fgIsLinkQualityValid = FALSE; ++ prAdapter->fgIsLinkRateValid = FALSE; ++ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { /* connected */ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ ++ /* fill information for association result */ ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ prConnectionStatus->aucBssid, MAC_ADDR_LEN); ++ prAdapter->rWlanInfo.rCurrBssId.u4Privacy ++ = prConnectionStatus->ucEncryptStatus; /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse ++ = PARAM_NETWORK_TYPE_AUTOMODE; /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod ++ = prConnectionStatus->u2BeaconPeriod; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow = prConnectionStatus->u2ATIMWindow; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig = prConnectionStatus->u4FreqInKHz; ++ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode ++ = (ENUM_PARAM_OP_MODE_T) prConnectionStatus->ucInfraMode; ++ ++ /* always indicate to OS according to MSDN (re-association/roaming) */ ++ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); ++ } else { ++ /* connected -> connected : roaming ? */ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_ROAM_OUT_FIND_BEST, NULL, 0); ++ } ++ } ++ break; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ case NETWORK_TYPE_BOW_INDEX: ++ break; ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ case NETWORK_TYPE_P2P_INDEX: ++ break; ++#endif ++ default: ++ ASSERT(0); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* nicMediaStateChange */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to convert between ++* frequency and channel number ++* ++* @param u4ChannelNum ++* ++* @retval - Frequency in unit of KHz, 0 for invalid channel number ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 nicChannelNum2Freq(UINT_32 u4ChannelNum) ++{ ++ UINT_32 u4ChannelInMHz; ++ ++ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) ++ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; ++ else if (u4ChannelNum == 14) ++ u4ChannelInMHz = 2484; ++ else if (u4ChannelNum == 133) ++ u4ChannelInMHz = 3665; /* 802.11y */ ++ else if (u4ChannelNum == 137) ++ u4ChannelInMHz = 3685; /* 802.11y */ ++ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) ++ u4ChannelInMHz = 5000 + u4ChannelNum * 5; ++ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) ++ u4ChannelInMHz = 4000 + u4ChannelNum * 5; ++ else ++ u4ChannelInMHz = 0; ++ ++ return 1000 * u4ChannelInMHz; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to convert between ++* frequency and channel number ++* ++* @param u4FreqInKHz ++* ++* @retval - Frequency Number, 0 for invalid freqency ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 nicFreq2ChannelNum(UINT_32 u4FreqInKHz) ++{ ++ switch (u4FreqInKHz) { ++ case 2412000: ++ return 1; ++ case 2417000: ++ return 2; ++ case 2422000: ++ return 3; ++ case 2427000: ++ return 4; ++ case 2432000: ++ return 5; ++ case 2437000: ++ return 6; ++ case 2442000: ++ return 7; ++ case 2447000: ++ return 8; ++ case 2452000: ++ return 9; ++ case 2457000: ++ return 10; ++ case 2462000: ++ return 11; ++ case 2467000: ++ return 12; ++ case 2472000: ++ return 13; ++ case 2484000: ++ return 14; ++ case 3665000: ++ return 133; /* 802.11y */ ++ case 3685000: ++ return 137; /* 802.11y */ ++ case 4915000: ++ return 183; ++ case 4920000: ++ return 184; ++ case 4925000: ++ return 185; ++ case 4930000: ++ return 186; ++ case 4935000: ++ return 187; ++ case 4940000: ++ return 188; ++ case 4945000: ++ return 189; ++ case 4960000: ++ return 192; ++ case 4980000: ++ return 196; ++ case 5170000: ++ return 34; ++ case 5180000: ++ return 36; ++ case 5190000: ++ return 38; ++ case 5200000: ++ return 40; ++ case 5210000: ++ return 42; ++ case 5220000: ++ return 44; ++ case 5230000: ++ return 46; ++ case 5240000: ++ return 48; ++ case 5250000: ++ return 50; ++ case 5260000: ++ return 52; ++ case 5270000: ++ return 54; ++ case 5280000: ++ return 56; ++ case 5290000: ++ return 58; ++ case 5300000: ++ return 60; ++ case 5320000: ++ return 64; ++ case 5500000: ++ return 100; ++ case 5520000: ++ return 104; ++ case 5540000: ++ return 108; ++ case 5560000: ++ return 112; ++ case 5580000: ++ return 116; ++ case 5600000: ++ return 120; ++ case 5620000: ++ return 124; ++ case 5640000: ++ return 128; ++ case 5660000: ++ return 132; ++ case 5680000: ++ return 136; ++ case 5700000: ++ return 140; ++ case 5745000: ++ return 149; ++ case 5765000: ++ return 153; ++ case 5785000: ++ return 157; ++ case 5805000: ++ return 161; ++ case 5825000: ++ return 165; ++ case 5845000: ++ return 169; ++ case 5865000: ++ return 173; ++ default: ++ return 0; ++ } ++} ++ ++/* firmware command wrapper */ ++/* NETWORK (WIFISYS) */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to activate WIFISYS for specified network ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of network type ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdActivateCtrl.ucActive = 1; ++ ++ if (((UINT_8) eNetworkTypeIdx) < NETWORK_TYPE_INDEX_NUM) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]; ++ prBssInfo->fg40mBwAllowed = FALSE; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BSS_ACTIVATE_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to deactivate WIFISYS for specified network ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of network type ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ WLAN_STATUS u4Status; ++ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdActivateCtrl.ucActive = 0; ++ ++ u4Status = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BSS_ACTIVATE_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); ++ ++ /* free all correlated station records */ ++ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); ++ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); ++ nicFreePendingTxMsduInfoByNetwork(prAdapter, eNetworkTypeIdx); ++ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); ++ ++ return u4Status; ++} ++ ++/* BSS-INFO */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to sync bss info with firmware ++* when a new BSS has been connected or disconnected ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO type ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ WLAN_STATUS u4Status; ++ P_BSS_INFO_T prBssInfo; ++ CMD_SET_BSS_INFO rCmdSetBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ ++ kalMemZero(&rCmdSetBssInfo, sizeof(CMD_SET_BSS_INFO)); ++ ++ rCmdSetBssInfo.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdSetBssInfo.ucConnectionState = (UINT_8) prBssInfo->eConnectionState; ++ rCmdSetBssInfo.ucCurrentOPMode = (UINT_8) prBssInfo->eCurrentOPMode; ++ rCmdSetBssInfo.ucSSIDLen = (UINT_8) prBssInfo->ucSSIDLen; ++ kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID); ++ rCmdSetBssInfo.ucIsQBSS = (UINT_8) prBssInfo->fgIsQBSS; ++ rCmdSetBssInfo.ucNonHTBasicPhyType = prBssInfo->ucNonHTBasicPhyType; ++ rCmdSetBssInfo.u2OperationalRateSet = prBssInfo->u2OperationalRateSet; ++ rCmdSetBssInfo.u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; ++ rCmdSetBssInfo.ucPhyTypeSet = prBssInfo->ucPhyTypeSet; ++ rCmdSetBssInfo.fgHiddenSsidMode = prBssInfo->eHiddenSsidType; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ COPY_MAC_ADDR(rCmdSetBssInfo.aucOwnMac, prBssInfo->aucOwnMacAddr); ++#endif ++ ++ rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, prBssInfo); ++ ++ rCmdSetBssInfo.fgWapiMode = (UINT_8) FALSE; ++ ++ if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) prConnSettings->eAuthMode; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) prConnSettings->eEncStatus; ++ rCmdSetBssInfo.fgWapiMode = (UINT_8) prConnSettings->fgWapiMode; ++ } ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { ++ /* P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); */ ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; ++ } ++#endif ++ else { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; ++ } else { ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_OPEN; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION_DISABLED; ++ } ++ /* Need the probe response to detect the PBC overlap */ ++ rCmdSetBssInfo.fgIsApMode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); ++ } ++#else ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; ++#endif ++ } ++ ++ if (eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX && ++ prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && prBssInfo->prStaRecOfAP != NULL) { ++ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; ++ ++ cnmAisInfraConnectNotify(prAdapter); ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && ++ (eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && ++ (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && (prBssInfo->prStaRecOfAP != NULL)) { ++ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (eNetworkTypeIdx == NETWORK_TYPE_BOW_INDEX && ++ prBssInfo->eCurrentOPMode == OP_MODE_BOW && prBssInfo->prStaRecOfAP != NULL) { ++ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; ++ } ++#endif ++ else ++ rCmdSetBssInfo.ucStaRecIdxOfAP = STA_REC_INDEX_NOT_FOUND; ++ ++ u4Status = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BSS_INFO, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_SET_BSS_INFO), (PUINT_8)&rCmdSetBssInfo, NULL, 0); ++ ++ /* if BSS-INFO is going to be disconnected state, free all correlated station records */ ++ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ /* clear client list */ ++ bssClearClientList(prAdapter, prBssInfo); ++ ++ /* free all correlated station records */ ++ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); ++ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); ++ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ if (prBssInfo->prIpV4NetAddrList) ++ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); ++#endif ++ } ++ ++ return u4Status; ++} ++ ++/* BSS-INFO Indication (PM) */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate PM that ++* a BSS has been created. (for AdHoc / P2P-GO) ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ ++ rCmdIndicatePmBssCreated.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdIndicatePmBssCreated.ucDtimPeriod = prBssInfo->ucDTIMPeriod; ++ rCmdIndicatePmBssCreated.u2BeaconInterval = prBssInfo->u2BeaconInterval; ++ rCmdIndicatePmBssCreated.u2AtimWindow = prBssInfo->u2ATIMWindow; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INDICATE_PM_BSS_CREATED, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_INDICATE_PM_BSS_CREATED), (PUINT_8)&rCmdIndicatePmBssCreated, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate PM that ++* a BSS has been connected ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ CMD_INDICATE_PM_BSS_CONNECTED rCmdIndicatePmBssConnected; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ ++ rCmdIndicatePmBssConnected.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdIndicatePmBssConnected.ucDtimPeriod = prBssInfo->ucDTIMPeriod; ++ rCmdIndicatePmBssConnected.u2AssocId = prBssInfo->u2AssocId; ++ rCmdIndicatePmBssConnected.u2BeaconInterval = prBssInfo->u2BeaconInterval; ++ rCmdIndicatePmBssConnected.u2AtimWindow = prBssInfo->u2ATIMWindow; ++ ++ rCmdIndicatePmBssConnected.ucBmpDeliveryAC = prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC; ++ rCmdIndicatePmBssConnected.ucBmpTriggerAC = prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC; ++ ++ /* DBGPRINTF("nicPmIndicateBssConnected: ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x", */ ++ /* rCmdIndicatePmBssConnected.ucBmpDeliveryAC, */ ++ /* rCmdIndicatePmBssConnected.ucBmpTriggerAC); */ ++ ++ if ((eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX) ++#if CFG_ENABLE_WIFI_DIRECT ++ || ((eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->fgIsP2PRegistered)) ++#endif ++ ) { ++ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ rCmdIndicatePmBssConnected.fgIsUapsdConnection = ++ (UINT_8) prBssInfo->prStaRecOfAP->fgIsUapsdSupported; ++ } else { ++ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; /* @FIXME */ ++ } ++ } else { ++ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; ++ } ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INDICATE_PM_BSS_CONNECTED, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_INDICATE_PM_BSS_CONNECTED), ++ (PUINT_8)&rCmdIndicatePmBssConnected, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate PM that ++* a BSS has been disconnected ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ rCmdIndicatePmBssAbort.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INDICATE_PM_BSS_ABORT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_INDICATE_PM_BSS_ABORT), (PUINT_8)&rCmdIndicatePmBssAbort, NULL, 0); ++} ++ ++WLAN_STATUS ++nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent) ++{ ++ DEBUGFUNC("nicConfigPowerSaveProfile"); ++ DBGLOG(NIC, TRACE, "eNetTypeIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n", ++ eNetTypeIndex, ePwrMode, fgEnCmdEvent); ++ ++ ASSERT(prAdapter); ++ ++ if (eNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { ++ ASSERT(0); ++ return WLAN_STATUS_NOT_SUPPORTED; ++ } ++/* prAdapter->rWlanInfo.ePowerSaveMode.ucNetTypeIndex = eNetTypeIndex; */ ++/* prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile = (UINT_8)ePwrMode; */ ++ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucNetTypeIndex = eNetTypeIndex; ++ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucPsProfile = (UINT_8) ePwrMode; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_POWER_SAVE_MODE, ++ TRUE, ++ FALSE, ++ (fgEnCmdEvent ? TRUE : FALSE), ++ (fgEnCmdEvent ? nicCmdEventSetCommon : NULL), ++ (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL), ++ sizeof(CMD_PS_PROFILE_T), ++ (PUINT_8)&(prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex]), ++ NULL, sizeof(PARAM_POWER_MODE) ++ ); ++ ++} /* end of wlanoidSetAcpiDevicePowerStateMode() */ ++ ++WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent) ++{ ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ CMD_ACCESS_REG rCmdAccessReg; ++ WLAN_STATUS rWlanStatus; ++ ++ DEBUGFUNC("nicEnterCtiaMode"); ++ DBGLOG(NIC, TRACE, "nicEnterCtiaMode: %d\n", fgEnterCtia); ++ ++ ASSERT(prAdapter); ++ ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ if (fgEnterCtia) { ++ /* 1. Disable On-Lin Scan */ ++ prAdapter->fgEnOnlineScan = FALSE; ++ ++ /* 3. Disable FIFO FULL no ack */ ++ rCmdAccessReg.u4Address = 0x60140028; ++ rCmdAccessReg.u4Data = 0x904; ++ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ ++ FALSE, /* TRUE, */ ++ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); ++ ++ /* 4. Disable Roaming */ ++ rCmdSwCtrl.u4Id = 0x90000204; ++ rCmdSwCtrl.u4Data = 0x0; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ rCmdSwCtrl.u4Id = 0x90000200; ++ rCmdSwCtrl.u4Data = 0x820000; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* Disalbe auto tx power */ ++ rCmdSwCtrl.u4Id = 0xa0100003; ++ rCmdSwCtrl.u4Data = 0x0; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* 2. Keep at CAM mode */ ++ { ++ PARAM_POWER_MODE ePowerMode; ++ ++ prAdapter->u4CtiaPowerMode = 0; ++ prAdapter->fgEnCtiaPowerMode = TRUE; ++ ++ ePowerMode = Param_PowerModeCAM; ++ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); ++ } ++ ++ /* 5. Disable Beacon Timeout Detection */ ++ prAdapter->fgDisBcnLostDetection = TRUE; ++ } else { ++ /* 1. Enaable On-Lin Scan */ ++ prAdapter->fgEnOnlineScan = TRUE; ++ ++ /* 3. Enable FIFO FULL no ack */ ++ rCmdAccessReg.u4Address = 0x60140028; ++ rCmdAccessReg.u4Data = 0x905; ++ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ ++ FALSE, /* TRUE, */ ++ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); ++ ++ /* 4. Enable Roaming */ ++ rCmdSwCtrl.u4Id = 0x90000204; ++ rCmdSwCtrl.u4Data = 0x1; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ rCmdSwCtrl.u4Id = 0x90000200; ++ rCmdSwCtrl.u4Data = 0x820000; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* Enable auto tx power */ ++ /* */ ++ ++ rCmdSwCtrl.u4Id = 0xa0100003; ++ rCmdSwCtrl.u4Data = 0x1; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* 2. Keep at Fast PS */ ++ { ++ PARAM_POWER_MODE ePowerMode; ++ ++ prAdapter->u4CtiaPowerMode = 2; ++ prAdapter->fgEnCtiaPowerMode = TRUE; ++ ++ ePowerMode = Param_PowerModeFast_PSP; ++ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); ++ } ++ ++ /* 5. Enable Beacon Timeout Detection */ ++ prAdapter->fgDisBcnLostDetection = FALSE; ++ ++ } ++ ++ return rWlanStatus; ++} /* end of nicEnterCtiaMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate firmware domain ++* for beacon generation parameters ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eIeUpdMethod, Update Method ++* eNetTypeIndex Index of Network ++* u2Capability Capability ++* aucIe Pointer to buffer of IEs ++* u2IELen Length of IEs ++* ++* @retval - WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++* WLAN_STATUS_PENDING ++* WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, ++ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen) ++{ ++ P_CMD_BEACON_TEMPLATE_UPDATE prCmdBcnUpdate; ++ UINT_16 u2CmdBufLen = 0; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanUpdateBeaconIETemplate"); ++ ++ DBGLOG(NIC, LOUD, "\nnicUpdateBeaconIETemplate\n"); ++ ++ ASSERT(prAdapter); ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (u2IELen > MAX_IE_LENGTH) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) { ++ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, aucIE) + u2IELen; ++ } else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) { ++ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, u2IELen); ++ } else { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* prepare command info */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u2CmdBufLen)); ++ if (!prCmdInfo) { ++ DBGLOG(NIC, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = eNetTypeIndex; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u2CmdBufLen); ++ prCmdInfo->pfCmdDoneHandler = NULL; /* @FIXME */ ++ prCmdInfo->pfCmdTimeoutHandler = NULL; /* @FIXME */ ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u2CmdBufLen; ++ prCmdInfo->pvInformationBuffer = NULL; ++ prCmdInfo->u4InformationBufferLength = 0; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdBcnUpdate = (P_CMD_BEACON_TEMPLATE_UPDATE) (prWifiCmd->aucBuffer); ++ ++ /* fill beacon updating command */ ++ prCmdBcnUpdate->ucUpdateMethod = (UINT_8) eIeUpdMethod; ++ prCmdBcnUpdate->ucNetTypeIndex = (UINT_8) eNetTypeIndex; ++ prCmdBcnUpdate->u2Capability = u2Capability; ++ prCmdBcnUpdate->u2IELen = u2IELen; ++ if (u2IELen > 0) ++ kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to initialization PHY related ++* varaibles ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ if (prConnSettings->eDesiredPhyConfig >= PHY_CONFIG_NUM) { ++ ASSERT(0); ++ return; ++ } ++ ++ prAdapter->rWifiVar.ucAvailablePhyTypeSet = aucPhyCfg2PhyTypeSet[prConnSettings->eDesiredPhyConfig]; ++ ++ if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_BIT_ERP) ++ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_ERP_INDEX; ++ /* NOTE(Kevin): Because we don't have N only mode, TBD */ ++ else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ ++ ++ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ CMD_UPDATE_WMM_PARMS_T rCmdUpdateWmmParms; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ DBGLOG(QM, EVENT, "sizeof(AC_QUE_PARMS_T): %zu\n", sizeof(AC_QUE_PARMS_T)); ++ DBGLOG(QM, EVENT, "sizeof(CMD_UPDATE_WMM_PARMS): %zu\n", sizeof(CMD_UPDATE_WMM_PARMS_T)); ++ DBGLOG(QM, EVENT, "sizeof(WIFI_CMD_T): %zu\n", sizeof(WIFI_CMD_T)); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ rCmdUpdateWmmParms.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], &prBssInfo->arACQueParms[0], (sizeof(AC_QUE_PARMS_T) * AC_NUM)); ++ ++ rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_UPDATE_WMM_PARMS, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_UPDATE_WMM_PARMS_T), (PUINT_8)&rCmdUpdateWmmParms, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update TX power gain corresponding to ++* each band/modulation combination ++* ++* @param prAdapter Pointer of ADAPTER_T ++* prTxPwrParam Pointer of TX power parameters ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) ++{ ++ DEBUGFUNC("nicUpdateTxPower"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_TX_PWR, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to set auto tx power parameter ++* ++* @param prAdapter Pointer of ADAPTER_T ++* prTxPwrParam Pointer of Auto TX power parameters ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam) ++{ ++ DEBUGFUNC("nicSetAutoTxPower"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_AUTOPWR_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_AUTO_POWER_PARAM_T), (PUINT_8) prAutoPwrParam, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update TX power gain corresponding to ++* each band/modulation combination ++* ++* @param prAdapter Pointer of ADAPTER_T ++* prTxPwrParam Pointer of TX power parameters ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicSetAutoTxPowerControl(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) ++{ ++ DEBUGFUNC("nicUpdateTxPower"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_TX_PWR, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update power offset around 5GHz band ++* ++* @param prAdapter Pointer of ADAPTER_T ++* pr5GPwrOffset Pointer of 5GHz power offset parameter ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset) ++{ ++ DEBUGFUNC("nicUpdate5GOffset"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_5G_PWR_OFFSET, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_5G_PWR_OFFSET_T), (PUINT_8) pr5GPwrOffset, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update DPD calibration result ++* ++* @param prAdapter Pointer of ADAPTER_T ++* pr5GPwrOffset Pointer of parameter for DPD calibration result ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult) ++{ ++ DEBUGFUNC("nicUpdateDPD"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PWR_PARAM, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_PWR_PARAM_T), (PUINT_8) prDpdCalResult, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function starts system service such as timer and ++* memory pools ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicInitSystemService(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* <1> Initialize MGMT Memory pool and STA_REC */ ++ cnmMemInit(prAdapter); ++ cnmStaRecInit(prAdapter); ++ cmdBufInitialize(prAdapter); ++ ++ /* <2> Mailbox Initialization */ ++ mboxInitialize(prAdapter); ++ ++ /* <3> Timer Initialization */ ++ cnmTimerInitialize(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function reset some specific system service, ++* such as STA-REC ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicResetSystemService(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* Timer Destruction */ ++ cnmTimerDestroy(prAdapter); ++ ++ /* Mailbox Destruction */ ++ mboxDestroy(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) ++{ ++ ASSERT(prAdapter); ++ ++ /* CNM Module - initialization */ ++ cnmInit(prAdapter); ++ ++ /* RLM Module - initialization */ ++ rlmFsmEventInit(prAdapter); ++ ++ /* SCN Module - initialization */ ++ scnInit(prAdapter); ++ ++ /* AIS Module - intiailization */ ++ aisInitializeConnectionSettings(prAdapter, prRegInfo); ++ aisFsmInit(prAdapter); ++ ++#if CFG_SUPPORT_ROAMING ++ /* Roaming Module - intiailization */ ++ roamingFsmInit(prAdapter); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++#if CFG_SUPPORT_SWCR ++ swCrDebugInit(prAdapter); ++#endif /* CFG_SUPPORT_SWCR */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexInit(prAdapter); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++#if CFG_SUPPORT_SWCR ++ swCrDebugUninit(prAdapter); ++#endif /* CFG_SUPPORT_SWCR */ ++ ++#if CFG_SUPPORT_ROAMING ++ /* Roaming Module - unintiailization */ ++ roamingFsmUninit(prAdapter); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* AIS Module - unintiailization */ ++ aisFsmUninit(prAdapter); ++ ++ /* SCN Module - unintiailization */ ++ scnUninit(prAdapter); ++ ++ /* RLM Module - uninitialization */ ++ rlmFsmEventUninit(prAdapter); ++ ++ /* CNM Module - uninitialization */ ++ cnmUninit(prAdapter); ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexUninit(prAdapter); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++} ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is to inform firmware to enable MCU clock gating ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4WHISR = 0; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ ++ nicSetSwIntr(prAdapter, REQ_GATING_ENABLE_H2D_INT); ++ ++ i = 0; ++ while (i < GATING_CONTROL_POLL_LIMIT) { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) ++ return WLAN_STATUS_FAILURE; ++ ++ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); ++ ++ if (u4WHISR & ACK_GATING_ENABLE_D2H_INT) { ++ prAdapter->fgIsClockGatingEnabled = TRUE; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++ ++ ASSERT(0); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is to inform firmware to disable MCU clock gating ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4WHISR = 0; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ return WLAN_STATUS_SUCCESS; ++ ++ nicSetSwIntr(prAdapter, REQ_GATING_DISABLE_H2D_INT); ++ ++ i = 0; ++ while (i < GATING_CONTROL_POLL_LIMIT) { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) ++ return WLAN_STATUS_FAILURE; ++ ++ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); ++ ++ if (u4WHISR & ACK_GATING_DISABLE_D2H_INT) { ++ prAdapter->fgIsClockGatingEnabled = FALSE; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++ ++ ASSERT(0); ++ return WLAN_STATUS_PENDING; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is invoked to buffer scan result ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param rMacAddr BSSID ++* @param prSsid Pointer to SSID ++* @param u4Privacy Privacy settings (0: Open / 1: WEP/WPA/WPA2 enabled) ++* @param rRssi Received Strength (-10 ~ -200 dBm) ++* @param eNetworkType Network Type (a/b/g) ++* @param prConfiguration Network Parameter ++* @param eOpMode Infra/Ad-Hoc ++* @param rSupportedRates Supported basic rates ++* @param u2IELength IE Length ++* @param pucIEBuf Pointer to Information Elements(IEs) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicAddScanResult(IN P_ADAPTER_T prAdapter, ++ IN PARAM_MAC_ADDRESS rMacAddr, ++ IN P_PARAM_SSID_T prSsid, ++ IN UINT_32 u4Privacy, ++ IN PARAM_RSSI rRssi, ++ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, ++ IN P_PARAM_802_11_CONFIG_T prConfiguration, ++ IN ENUM_PARAM_OP_MODE_T eOpMode, ++ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf) ++{ ++ BOOLEAN bReplace; ++ UINT_32 i; ++ UINT_32 u4IdxWeakest = 0; ++ PARAM_RSSI rWeakestRssi; ++ UINT_32 u4BufferSize; ++ ++ ASSERT(prAdapter); ++ ++ rWeakestRssi = (PARAM_RSSI) INT_MAX; ++ u4BufferSize = sizeof(prAdapter->rWlanInfo.aucScanIEBuf) / sizeof(prAdapter->rWlanInfo.aucScanIEBuf[0]); ++ ++ bReplace = FALSE; ++ ++ /* decide to replace or add */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ /* find weakest entry && not connected one */ ++ if (UNEQUAL_MAC_ADDR ++ (prAdapter->rWlanInfo.arScanResult[i].arMacAddress, prAdapter->rWlanInfo.rCurrBssId.arMacAddress) ++ && prAdapter->rWlanInfo.arScanResult[i].rRssi < rWeakestRssi) { ++ u4IdxWeakest = i; ++ rWeakestRssi = prAdapter->rWlanInfo.arScanResult[i].rRssi; ++ } ++ ++ if (prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode && ++ EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo.arScanResult[i].arMacAddress), rMacAddr) && ++ (EQUAL_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen) ++ || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == 0)) { ++ /* replace entry */ ++ bReplace = TRUE; ++ ++ /* free IE buffer then zero */ ++ nicFreeScanResultIE(prAdapter, i); ++ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /* then fill buffer */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length = ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; ++ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); ++ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen); ++ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; ++ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; ++ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), ++ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); ++ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; ++ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), ++ rSupportedRates, sizeof(PARAM_RATES_EX)); ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; ++ ++ /* IE - allocate buffer and update pointer */ ++ if (u2IELength > 0) { ++ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { ++ kalMemCopy(& ++ (prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), ++ pucIEBuf, u2IELength); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ &(prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); ++ } else { ++ /* buffer is not enough */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ ++ break; ++ } ++ } ++ ++ if (bReplace == FALSE) { ++ if (prAdapter->rWlanInfo.u4ScanResultNum < (CFG_MAX_NUM_BSS_LIST - 1)) { ++ i = prAdapter->rWlanInfo.u4ScanResultNum; ++ ++ /* zero */ ++ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /* then fill buffer */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length = ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; ++ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); ++ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen); ++ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; ++ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; ++ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), ++ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); ++ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; ++ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), ++ rSupportedRates, sizeof(PARAM_RATES_EX)); ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; ++ ++ /* IE - allocate buffer and update pointer */ ++ if (u2IELength > 0) { ++ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { ++ kalMemCopy(& ++ (prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), ++ pucIEBuf, u2IELength); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ &(prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); ++ } else { ++ /* buffer is not enough */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ ++ prAdapter->rWlanInfo.u4ScanResultNum++; ++ } else if (rWeakestRssi != (PARAM_RSSI) INT_MAX) { ++ /* replace weakest one */ ++ i = u4IdxWeakest; ++ ++ /* free IE buffer then zero */ ++ nicFreeScanResultIE(prAdapter, i); ++ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /* then fill buffer */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length = ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; ++ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); ++ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen); ++ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; ++ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; ++ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), ++ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); ++ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; ++ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), ++ rSupportedRates, sizeof(PARAM_RATES_EX)); ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; ++ ++ if (u2IELength > 0) { ++ /* IE - allocate buffer and update pointer */ ++ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { ++ kalMemCopy(& ++ (prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), ++ pucIEBuf, u2IELength); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ &(prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); ++ } else { ++ /* buffer is not enough */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is invoked to free IE buffer for dedicated scan result ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param u4Idx Index of Scan Result ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx) ++{ ++ UINT_32 i; ++ PUINT_8 pucPivot, pucMovePivot; ++ UINT_32 u4MoveSize, u4FreeSize, u4ReserveSize; ++ ++ ASSERT(prAdapter); ++ ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST); ++ ++ if (prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0 ++ || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) { ++ return; ++ } ++ ++ u4FreeSize = ALIGN_4(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength); ++ ++ pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]; ++ pucMovePivot = (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize); ++ ++ u4ReserveSize = ((ULONG) pucPivot) - (ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])); ++ u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - u4ReserveSize - u4FreeSize; ++ ++ /* 1. rest of buffer to move forward */ ++ kalMemCopy(pucPivot, pucMovePivot, u4MoveSize); ++ ++ /* 1.1 modify pointers */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ if (i != u4Idx) { ++ if (prAdapter->rWlanInfo.apucScanResultIEs[i] >= pucMovePivot) { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[i]) - u4FreeSize); ++ } ++ } ++ } ++ ++ /* 1.2 reset the freed one */ ++ prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ ++ /* 2. reduce IE buffer usage */ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to hack parameters for WLAN TABLE for ++* fixed rate settings ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param eRateSetting ++* @param pu2DesiredNonHTRateSet, ++* @param pu2BSSBasicRateSet, ++* @param pucMcsSet ++* @param pucSupMcs32 ++* @param pu2HtCapInfo ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicUpdateRateParams(IN P_ADAPTER_T prAdapter, ++ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, ++ IN PUINT_8 pucDesiredPhyTypeSet, ++ IN PUINT_16 pu2DesiredNonHTRateSet, ++ IN PUINT_16 pu2BSSBasicRateSet, ++ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 pu2HtCapInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eRateSetting > FIXED_RATE_NONE && eRateSetting < FIXED_RATE_NUM); ++ ++ switch (prAdapter->rWifiVar.eRateSetting) { ++ case FIXED_RATE_1M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_1M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_1M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_2M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_2M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_2M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_5_5M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_5_5M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_11M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_11M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_11M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_6M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_6M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_6M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_9M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_9M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_9M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_12M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_12M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_12M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_18M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_18M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_18M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_24M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_24M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_24M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_36M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_36M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_36M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_48M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_48M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_48M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_54M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_54M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_54M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_MCS0_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS1_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS2_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS3_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS4_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS5_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS6_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS7_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS0_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS1_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS2_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS3_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS4_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS5_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS6_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS7_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS0_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS1_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS2_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS3_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS4_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS5_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS6_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS7_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS32_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS32_INDEX; ++ *pucSupMcs32 = 1; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS0_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS1_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS2_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS3_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS4_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS5_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS6_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS7_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS32_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS32_INDEX; ++ *pucSupMcs32 = 1; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to write the register ++* ++* @param u4Address Register address ++* u4Value the value to be written ++* ++* @retval WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value) ++{ ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++ rCmdAccessReg.u4Address = u4Address; ++ rCmdAccessReg.u4Data = u4Value; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8) &rCmdAccessReg, NULL, 0); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to modify the auto rate parameters ++* ++* @param u4ArSysParam0 see description below ++* u4ArSysParam1 ++* u4ArSysParam2 ++* u4ArSysParam3 ++* ++* ++* @retval WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++* ++* @note ++* ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2) ++* ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2) ++* ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2) ++* ArSysParam0[8:15]-> HT rate clear mask ++* ArSysParam0[16:31]-> Legacy rate clear mask ++* ArSysParam1[0:7]-> Auto Rate check weighting window ++* ArSysParam1[8:15]-> Auto Rate v1 Force Rate down ++* ArSysParam1[16:23]-> Auto Rate v1 PerH ++* ArSysParam1[24:31]-> Auto Rate v1 PerL ++* ++* Examples ++* ArSysParam0 = 1, ++* Enable auto rate version 1 ++* ++* ArSysParam0 = 983041, ++* Enable auto rate version 1 ++* Remove CCK 1M, 2M, 5.5M, 11M ++* ++* ArSysParam0 = 786433 ++* Enable auto rate version 1 ++* Remove CCK 5.5M 11M ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS ++nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4ArSysParam0, ++ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3) ++{ ++ UINT_8 ucArVer, ucAbwVer, ucAgiVer; ++ UINT_16 u2HtClrMask; ++ UINT_16 u2LegacyClrMask; ++ UINT_8 ucArCheckWindow; ++ UINT_8 ucArPerL; ++ UINT_8 ucArPerH; ++ UINT_8 ucArPerForceRateDownPer; ++ ++ ucArVer = (UINT_8) (u4ArSysParam0 & BITS(0, 3)); ++ ucAbwVer = (UINT_8) ((u4ArSysParam0 & BITS(4, 5)) >> 4); ++ ucAgiVer = (UINT_8) ((u4ArSysParam0 & BITS(6, 7)) >> 6); ++ u2HtClrMask = (UINT_16) ((u4ArSysParam0 & BITS(8, 15)) >> 8); ++ u2LegacyClrMask = (UINT_16) ((u4ArSysParam0 & BITS(16, 31)) >> 16); ++ ++#if 0 ++ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); ++ ucArPerForceRateDownPer = (UINT_8) ((u4ArSysParam1 & BITS(8, 15) >> 8)); ++ ucArPerH = (UINT_8) ((u4ArSysParam1 & BITS(16, 23)) >> 16); ++ ucArPerL = (UINT_8) ((u4ArSysParam1 & BITS(24, 31)) >> 24); ++#endif ++ ++ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); ++ ucArPerForceRateDownPer = (UINT_8) (((u4ArSysParam1 >> 8) & BITS(0, 7))); ++ ucArPerH = (UINT_8) (((u4ArSysParam1 >> 16) & BITS(0, 7))); ++ ucArPerL = (UINT_8) (((u4ArSysParam1 >> 24) & BITS(0, 7))); ++ ++ DBGLOG(NIC, INFO, "ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3); ++ DBGLOG(NIC, INFO, "ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer); ++ DBGLOG(NIC, INFO, "HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask); ++ DBGLOG(NIC, INFO, ++ "CheckWin %u RateDownPer %u PerH %u PerL %u\n", ucArCheckWindow, ucArPerForceRateDownPer, ucArPerH, ++ ucArPerL); ++ ++#define SWCR_DATA_ADDR(MOD, ADDR) (0x90000000+(MOD<<8)+(ADDR)) ++#define SWCR_DATA_CMD(CATE, WRITE, INDEX, OPT0, OPT1) ((CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 << 8) | OPT1) ++#define SWCR_DATA0 0x0 ++#define SWCR_DATA1 0x4 ++#define SWCR_DATA2 0x8 ++#define SWCR_DATA3 0xC ++#define SWCR_DATA4 0x10 ++#define SWCR_WRITE 1 ++#define SWCR_READ 0 ++ ++ if (ucArVer > 0) { ++ /* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */ ++ /* dummy = WiFi.WriteMCR(&h90000100, &h00850000) */ ++ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 1); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); ++ } else { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 0); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); ++ } ++ ++ /* ucArVer 0: none 1:PER 2:Rcpi */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArVer); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 7, 0, 0)); ++ ++ /* Candidate rate Ht mask */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2HtClrMask); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1c, 0, 0)); ++ ++ /* Candidate rate legacy mask */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2LegacyClrMask); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1d, 0, 0)); ++ ++#if 0 ++ if (ucArCheckWindow != 0) { ++ /* TX DONE MCS INDEX CHECK STA RATE DOWN TH */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x14, 0, 0)); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0xc, 0, 0)); ++ } ++ ++ if (ucArPerForceRateDownPer != 0) { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerForceRateDownPer); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x18, 0, 0)); ++ } ++ if (ucArPerH != 0) { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerH); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1, 0, 0)); ++ } ++ if (ucArPerL != 0) { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerL); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x2, 0, 0)); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to enable roaming ++* ++* @param u4EnableRoaming ++* ++* ++* @retval WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++* ++* @note ++* u4EnableRoaming -> Enable Romaing ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prConnSettings->fgIsEnableRoaming = ((u4EnableRoaming > 0) ? (TRUE) : (FALSE)); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief dump firmware Assert message ++* ++* \param[in] ++* prAdapter ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4MailBox0, u4MailBox1; ++ UINT_32 line = 0; ++ UINT_8 aucAssertFile[7]; ++ UINT_32 u4ChipId; ++ ++#if CFG_SDIO_INTR_ENHANCE ++ u4MailBox0 = prAdapter->prSDIOCtrl->u4RcvMailbox0; ++ u4MailBox1 = prAdapter->prSDIOCtrl->u4RcvMailbox1; ++#else ++ nicGetMailbox(prAdapter, 0, &u4MailBox0); ++ nicGetMailbox(prAdapter, 1, &u4MailBox1); ++#endif ++ ++ line = u4MailBox0 & 0x0000FFFF; ++ ++ u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF); ++ ++ kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2); ++ kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4); ++ ++ aucAssertFile[6] = '\0'; ++ ++#if defined(MT6620) ++ u4ChipId = 6620; ++#elif defined(MT6628) ++ u4ChipId = 6582; ++#endif ++ ++ kalPrint("\n[MT%u][wifi][Firmware] Assert at \"%s\" #%u\n\n", u4ChipId, aucAssertFile, line); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update Link Quality information ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* eNetTypeIdx ++* prEventLinkQuality ++* cRssi ++* cLinkQuality ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ASSERT(prEventLinkQuality); ++ ++ switch (eNetTypeIdx) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* check is to prevent RSSI to be updated by incorrect initial RSSI from hardware */ ++ /* buffer statistics for further query */ ++ if (prAdapter->fgIsLinkQualityValid == FALSE ++ || (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { ++ nicUpdateRSSI(prAdapter, eNetTypeIdx, prEventLinkQuality->cRssi, ++ prEventLinkQuality->cLinkQuality); ++ } ++ ++ if (prAdapter->fgIsLinkRateValid == FALSE ++ || (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { ++ nicUpdateLinkSpeed(prAdapter, eNetTypeIdx, prEventLinkQuality->u2LinkSpeed); ++ } ++ } ++ break; ++#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY ++ case NETWORK_TYPE_P2P_INDEX: ++ if (prAdapter->fgIsP2pLinkQualityValid == FALSE ++ || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { ++ P_EVENT_LINK_QUALITY_EX prEventLQEx = (P_EVENT_LINK_QUALITY_EX) prEventLinkQuality; ++ ++ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, prEventLQEx->cRssiP2P, ++ prEventLQEx->cLinkQualityP2P); ++ } ++ break; ++#endif ++ default: ++ break; ++ ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update RSSI and Link Quality information ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* eNetTypeIdx ++* cRssi ++* cLinkQuality ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicUpdateRSSI(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ switch (eNetTypeIdx) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ prAdapter->fgIsLinkQualityValid = TRUE; ++ prAdapter->rLinkQualityUpdateTime = kalGetTimeTick(); ++ ++ prAdapter->rLinkQuality.cRssi = cRssi; ++ prAdapter->rLinkQuality.cLinkQuality = cLinkQuality; ++ ++ /* indicate to glue layer */ ++ kalUpdateRSSI(prAdapter->prGlueInfo, ++ KAL_NETWORK_TYPE_AIS_INDEX, ++ prAdapter->rLinkQuality.cRssi, prAdapter->rLinkQuality.cLinkQuality); ++ } ++ ++ break; ++#if CFG_ENABLE_WIFI_DIRECT ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ case NETWORK_TYPE_P2P_INDEX: ++ prAdapter->fgIsP2pLinkQualityValid = TRUE; ++ prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick(); ++ ++ prAdapter->rP2pLinkQuality.cRssi = cRssi; ++ prAdapter->rP2pLinkQuality.cLinkQuality = cLinkQuality; ++ ++ kalUpdateRSSI(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_P2P_INDEX, cRssi, cLinkQuality); ++ break; ++#endif ++#endif ++ default: ++ break; ++ ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update Link Quality information ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* eNetTypeIdx ++* prEventLinkQuality ++* cRssi ++* cLinkQuality ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ switch (eNetTypeIdx) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* buffer statistics for further query */ ++ prAdapter->fgIsLinkRateValid = TRUE; ++ prAdapter->rLinkRateUpdateTime = kalGetTimeTick(); ++ ++ prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed; ++ } ++ break; ++ ++ default: ++ break; ++ ++ } ++ ++} ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam) ++{ ++ DEBUGFUNC("nicUpdateRddTestMode.\n"); ++ ++ ASSERT(prAdapter); ++ ++/* aisFsmScanRequest(prAdapter, NULL); */ ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RDD_CH, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_RDD_CH_T), (PUINT_8) prRddChParam, NULL, 0); ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c +new file mode 100644 +index 000000000000..3c9c24f9542b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c +@@ -0,0 +1,1636 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_cmd_event.c#1 ++*/ ++ ++/*! \file nic_cmd_event.c ++ \brief Callback functions for Command packets. ++ ++ Various Event packet handlers which will be setup in the callback function of ++ a command packet. ++*/ ++ ++/* ++** Log: nic_cmd_event.c ++ * ++ * 04 10 2012 yuche.tsai ++ * NULL ++ * Update address for wifi direct connection issue. ++ * ++ * 06 15 2011 cm.chang ++ * [WCXRP00000785] [MT6620 Wi-Fi][Driver][FW] P2P/BOW MAC address is XOR with AIS MAC address ++ * P2P/BOW mac address XOR with local bit instead of OR ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000493] [MT6620 Wi-Fi][Driver] Do not indicate redundant disconnection to host when entering into RF ++ * test mode ++ * only indicate DISCONNECTION to host when entering RF test if necessary (connected -> disconnected cases) ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to ++ * system scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 12 01 2010 cp.wu ++ * [WCXRP00000223] MT6620 Wi-Fi][Driver][FW] Adopt NVRAM parameters when enter/exit RF test mode ++ * reload NVRAM settings before entering RF test mode and leaving from RF test mode. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 20 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * use OID_CUSTOM_TEST_MODE as indication for driver reset ++ * by dropping pending TX packets ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 15 2010 yuche.tsai ++ * NULL ++ * Start to test AT GO only when P2P state is not IDLE. ++ * ++ * 09 09 2010 yuche.tsai ++ * NULL ++ * Add AT GO Test mode after MAC address available. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add support for P2P Device Address query from FW. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 08 02 2010 cp.wu ++ * NULL ++ * reset FSMs before entering RF test mode. ++ * ++ * 07 22 2010 cp.wu ++ * ++ * 1) refine AIS-FSM indent. ++ * 2) when entering RF Test mode, flush 802.1X frames as well ++ * 3) when entering D3 state, flush 802.1X frames as well ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. ++ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 29 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change upon request: indicate as disconnected in driver domain when leaving from RF test mode ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * do not clear scanning list array after disassociation ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. ++ * 2) finish statistics OIDs ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change OID behavior to meet WHQL requirement. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_DISASSOCIATE handling. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * are now handled in glue layer ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * are done in adapter layer. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glude code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * sync statistics data structure definition with firmware implementation ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * statistics information OIDs are now handled by querying from firmware domain ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * limit RSSI return value to micxxsoft defined range. ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 29 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * block until firmware finished RF test enter/leave then indicate completion to upper layer ++ * ++ * 01 29 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when entering RF test mode and leaving from RF test mode, wait for W_FUNC_RDY bit to be asserted forever until it ++ * is set or card is removed. ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * * * 4. correct some HAL implementation ++ * ++ * 01 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * * * OID_802_11_RSSI, ++ * * * * * OID_802_11_RSSI_TRIGGER, ++ * * * * * OID_802_11_STATISTICS, ++ * * * * * OID_802_11_DISASSOCIATE, ++ * * * * * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:47:47 GMT mtk02752 ++** only handle MCR read when accessing FW domain register ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 17:37:28 GMT mtk02752 ++** * refine nicCmdEventQueryMcrRead ++** + add TxStatus/RxStatus for RF test QueryInformation OIDs ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 22:05:45 GMT mtk02752 ++** kalOidComplete() will decrease i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-01 23:02:57 GMT mtk02752 ++** remove unnecessary spin locks ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-01 22:51:18 GMT mtk02752 ++** maintein i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-30 10:55:03 GMT mtk02752 ++** modify for compatibility ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 14:46:32 GMT mtk02752 ++** add another version of command-done handler upon new event structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:33 GMT mtk01461 ++** Add comment ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 19:32:42 GMT mtk01461 ++** Add nicCmdEventSetCommon() for general set OID ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:35 GMT mtk01461 ++** Command Done Handler ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_ACCESS_REG prCmdAccessReg; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdAccessReg = (P_CMD_ACCESS_REG) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); ++ ++ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prMcrRdInfo->u4McrOffset = prCmdAccessReg->u4Address; ++ prMcrRdInfo->u4McrData = prCmdAccessReg->u4Data; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ return; ++ ++} ++ ++VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_SW_DBG_CTRL_T prCmdSwCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdSwCtrl = (P_CMD_SW_DBG_CTRL_T) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); ++ ++ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prSwCtrlInfo->u4Id = prCmdSwCtrl->u4Id; ++ prSwCtrlInfo->u4Data = prCmdSwCtrl->u4Data; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ return; ++ ++} ++ ++VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4InformationBufferLength, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ } ++ ++ DBGLOG(NIC, TRACE, "DisByCmdE\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++#if !defined(LINUX) ++ prAdapter->fgIsRadioOff = TRUE; ++#endif ++ ++} ++ ++VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4Count; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ u4Count = (prCmdInfo->u4SetInfoLen - OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress)) ++ / sizeof(IPV4_NETWORK_ADDRESS); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, ++ OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress) + u4Count * ++ (OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP)), ++ WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_TEST_STATUS prTestStatus, prQueryBuffer; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prTestStatus = (P_EVENT_TEST_STATUS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prQueryBuffer = (P_EVENT_TEST_STATUS) prCmdInfo->pvInformationBuffer; ++ ++ kalMemCopy(prQueryBuffer, prTestStatus, sizeof(EVENT_TEST_STATUS)); ++ ++ u4QueryInfoLen = sizeof(EVENT_TEST_STATUS); ++ ++ /* Update Query Information Length */ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ PARAM_RSSI rRssi, *prRssi; ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ rRssi = (PARAM_RSSI) prLinkQuality->cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ ++ DBGLOG(NIC, INFO, " %s: rRssi = %d\n", __func__, rRssi); ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ } else { ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ } ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prRssi = (PARAM_RSSI *) prCmdInfo->pvInformationBuffer; ++ ++ kalMemCopy(prRssi, &rRssi, sizeof(PARAM_RSSI)); ++ u4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is in response of OID_GEN_LINK_SPEED query request ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the pending command info ++* @param pucEventBuf ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4LinkSpeed; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ pu4LinkSpeed = (PUINT_32) (prCmdInfo->pvInformationBuffer); ++ ++ *pu4LinkSpeed = prLinkQuality->u2LinkSpeed * 5000; ++ ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ u4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ ++ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics->rTransmittedFragmentCount = prEventStatistics->rTransmittedFragmentCount; ++ prStatistics->rMulticastTransmittedFrameCount = prEventStatistics->rMulticastTransmittedFrameCount; ++ prStatistics->rFailedCount = prEventStatistics->rFailedCount; ++ prStatistics->rRetryCount = prEventStatistics->rRetryCount; ++ prStatistics->rMultipleRetryCount = prEventStatistics->rMultipleRetryCount; ++ prStatistics->rRTSSuccessCount = prEventStatistics->rRTSSuccessCount; ++ prStatistics->rRTSFailureCount = prEventStatistics->rRTSFailureCount; ++ prStatistics->rACKFailureCount = prEventStatistics->rACKFailureCount; ++ prStatistics->rFrameDuplicateCount = prEventStatistics->rFrameDuplicateCount; ++ prStatistics->rReceivedFragmentCount = prEventStatistics->rReceivedFragmentCount; ++ prStatistics->rMulticastReceivedFrameCount = prEventStatistics->rMulticastReceivedFrameCount; ++ prStatistics->rFCSErrorCount = prEventStatistics->rFCSErrorCount; ++ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; ++ prStatistics->rTKIPICVErrors.QuadPart = 0; ++ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; ++ prStatistics->rTKIPReplays.QuadPart = 0; ++ prStatistics->rCCMPFormatErrors.QuadPart = 0; ++ prStatistics->rCCMPReplays.QuadPart = 0; ++ prStatistics->rCCMPDecryptErrors.QuadPart = 0; ++ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; ++ prStatistics->rWEPUndecryptableCount.QuadPart = 0; ++ prStatistics->rWEPICVErrorCount.QuadPart = 0; ++ prStatistics->rDecryptSuccessCount.QuadPart = 0; ++ prStatistics->rDecryptFailureCount.QuadPart = 0; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++#define WAIT_FW_READY_RETRY_CNT 200 ++ ++ UINT_32 u4WHISR = 0, u4Value = 0; ++ UINT_8 aucTxCount[8]; ++ UINT_16 u2RetryCnt = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* [driver-land] */ ++ prAdapter->fgTestMode = TRUE; ++ ++ /* 0. always indicate disconnection */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ /* 1. Remove pending TX */ ++ nicTxRelease(prAdapter); ++ ++ /* 1.1 clear pending Security / Management Frames */ ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++ kalClearMgmtFrames(prAdapter->prGlueInfo); ++ ++ /* 1.2 clear pending TX packet queued in glue layer */ ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* 2. Reset driver-domain FSMs */ ++ nicUninitMGMT(prAdapter); ++ ++ nicResetSystemService(prAdapter); ++ nicInitMGMT(prAdapter, NULL); ++ ++ /* 3. Disable Interrupt */ ++ HAL_INTR_DISABLE(prAdapter); ++ ++ /* 4. Block til firmware completed entering into RF test mode */ ++ kalMsleep(500); ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || ++ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, ++ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); ++ ++ } ++ return; ++ } ++ kalMsleep(10); ++ u2RetryCnt++; ++ } ++ ++ /* 5. Clear Interrupt Status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ /* 6. Reset TX Counter */ ++ nicTxResetResource(prAdapter); ++ ++ /* 7. Re-enable Interrupt */ ++ HAL_INTR_ENABLE(prAdapter); ++ ++ /* 8. completion indication */ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); ++ } ++#if CFG_SUPPORT_NVRAM ++ /* 9. load manufacture data */ ++ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); ++#endif ++ ++} ++ ++VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++#define WAIT_FW_READY_RETRY_CNT 200 ++ ++ UINT_32 u4WHISR = 0, u4Value = 0; ++ UINT_8 aucTxCount[8]; ++ UINT_16 u2RetryCnt = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* 1. Disable Interrupt */ ++ HAL_INTR_DISABLE(prAdapter); ++ ++ /* 2. Block til firmware completed leaving from RF test mode */ ++ kalMsleep(500); ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || ++ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, ++ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); ++ ++ } ++ return; ++ } ++ kalMsleep(10); ++ u2RetryCnt++; ++ } ++ ++ /* 3. Clear Interrupt Status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ /* 4. Reset TX Counter */ ++ nicTxResetResource(prAdapter); ++ ++ /* 5. Re-enable Interrupt */ ++ HAL_INTR_ENABLE(prAdapter); ++ ++ /* 6. set driver-land variable */ ++ prAdapter->fgTestMode = FALSE; ++ ++ /* 7. completion indication */ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ /* 8. Indicate as disconnected */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ } ++#if CFG_SUPPORT_NVRAM ++ /* 9. load manufacture data */ ++ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); ++#endif ++ ++ /* 10. Override network address */ ++ wlanUpdateNetworkAddress(prAdapter); ++ ++} ++ ++VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_BASIC_CONFIG prEventBasicConfig; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (pucEventBuf); ++ ++ /* copy to adapter */ ++ kalMemCopy(&(prAdapter->rMyMacAddr), &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ kalMemCopy(prCmdInfo->pvInformationBuffer, &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); ++ u4QueryInfoLen = MAC_ADDR_LEN; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ /* 4 <3> Update new MAC address and all 3 networks */ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, prAdapter->rMyMacAddr); ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, prAdapter->rMyMacAddr); ++ prAdapter->rWifiVar.aucDeviceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress, prAdapter->rMyMacAddr); ++ prAdapter->rWifiVar.aucInterfaceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucOwnMacAddr, prAdapter->rMyMacAddr); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].aucOwnMacAddr, ++ prAdapter->rWifiVar.aucDeviceAddress); ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].aucOwnMacAddr, ++ prAdapter->rWifiVar.aucDeviceAddress); ++#endif ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_IDLE) { ++ wlanEnableP2pFunction(prAdapter); ++ ++ wlanEnableATGO(prAdapter); ++ } ++#endif ++ ++ kalUpdateMACAddress(prAdapter->prGlueInfo, prAdapter->rWifiVar.aucMacAddress); ++ ++} ++ ++VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_MAC_MCAST_ADDR prEventMacMcastAddr; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventMacMcastAddr = (P_EVENT_MAC_MCAST_ADDR) (pucEventBuf); ++ ++ u4QueryInfoLen = prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN; ++ ++ /* buffer length check */ ++ if (prCmdInfo->u4InformationBufferLength < u4QueryInfoLen) { ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_BUFFER_TOO_SHORT); ++ } else { ++ kalMemCopy(prCmdInfo->pvInformationBuffer, ++ prEventMacMcastAddr->arAddress, ++ prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ } ++} ++ ++VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRdInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_ACCESS_EEPROM prEventAccessEeprom; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventAccessEeprom = (P_EVENT_ACCESS_EEPROM) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ prEepromRdInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prEepromRdInfo->ucEepromIndex = (UINT_8) (prEventAccessEeprom->u2Offset); ++ prEepromRdInfo->u2EepromData = prEventAccessEeprom->u2Data; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ return; ++ ++} ++ ++VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ PARAM_MEDIA_STREAMING_INDICATION rParamMediaStreamIndication; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ rParamMediaStreamIndication.rStatus.eStatusType = ENUM_STATUS_TYPE_MEDIA_STREAM_MODE; ++ rParamMediaStreamIndication.eMediaStreamMode = ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID)&rParamMediaStreamIndication, sizeof(PARAM_MEDIA_STREAMING_INDICATION)); ++} ++ ++/* Statistics responder */ ++VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rTransmittedFragmentCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rTransmittedFragmentCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rReceivedFragmentCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rReceivedFragmentCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; ++ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; ++ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = 0; /* @FIXME? */ ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = 0; /* @FIXME? */ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) 0; /* @FIXME */ ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = 0; /* @FIXME */ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = ++ (UINT_32) (prEventStatistics->rMultipleRetryCount.QuadPart - ++ prEventStatistics->rRetryCount.QuadPart); ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = ++ (UINT_64) (prEventStatistics->rMultipleRetryCount.QuadPart - ++ prEventStatistics->rRetryCount.QuadPart); ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rMultipleRetryCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = (UINT_64) prEventStatistics->rMultipleRetryCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when command by OID/ioctl has been timeout ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is a generic command timeout handler ++* ++* @param pfnOidHandler Pointer to the OID handler ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when command for entering RF test has ++* failed sending due to timeout (highly possibly by firmware crash) ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ++ /* 1. Remove pending TX frames */ ++ nicTxRelease(prAdapter); ++ ++ /* 1.1 clear pending Security / Management Frames */ ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++ kalClearMgmtFrames(prAdapter->prGlueInfo); ++ ++ /* 1.2 clear pending TX packet queued in glue layer */ ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* 2. indicate for OID failure */ ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when command for memory dump has ++* replied a event. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_DUMP_MEM_T prEventDumpMem; ++ static UINT_8 aucPath[256]; ++ static UINT_32 u4CurTimeTick; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventDumpMem = (P_EVENT_DUMP_MEM_T) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T); ++ ++ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prMemDumpInfo->u4Address = prEventDumpMem->u4Address; ++ prMemDumpInfo->u4Length = prEventDumpMem->u4Length; ++ prMemDumpInfo->u4RemainLength = prEventDumpMem->u4RemainLength; ++ prMemDumpInfo->ucFragNum = prEventDumpMem->ucFragNum; ++ ++#if 0 ++ do { ++ UINT_32 i = 0; ++ ++ DBGLOG(REQ, TRACE, "Rx dump address 0x%X, Length %d, FragNum %d, remain %d\n", ++ prEventDumpMem->u4Address, ++ prEventDumpMem->u4Length, prEventDumpMem->ucFragNum, prEventDumpMem->u4RemainLength); ++#if 0 ++ for (i = 0; i < prEventDumpMem->u4Length; i++) { ++ DBGLOG(REQ, TRACE, "%02X ", prEventDumpMem->aucBuffer[i]); ++ if (i % 32 == 31) ++ DBGLOG(REQ, TRACE, "\n"); ++ } ++#endif ++ } while (FALSE); ++#endif ++ ++ if (prEventDumpMem->ucFragNum == 1) { ++ /* Store memory dump into sdcard, ++ * path /sdcard/dump___.hex ++ */ ++ u4CurTimeTick = kalGetTimeTick(); ++ sprintf(aucPath, "/sdcard/dump_%d_0x%08X_%d.hex", ++ u4CurTimeTick, ++ prEventDumpMem->u4Address, prEventDumpMem->u4Length + prEventDumpMem->u4RemainLength); ++ kalWriteToFile(aucPath, FALSE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); ++ } else { ++ /* Append current memory dump to the hex file */ ++ kalWriteToFile(aucPath, TRUE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); ++ } ++ ++ if (prEventDumpMem->u4RemainLength == 0 || prEventDumpMem->u4Address == 0xFFFFFFFF) { ++ /* The request is finished or firmware response a error */ ++ /* Reply time tick to iwpriv */ ++ *((PUINT_32) prCmdInfo->pvInformationBuffer) = u4CurTimeTick; ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } else { ++ /* The memory dump request is not finished, Send next command */ ++ wlanSendMemDumpCmd(prAdapter, ++ prCmdInfo->pvInformationBuffer, prCmdInfo->u4InformationBufferLength); ++ } ++ } ++ ++ return; ++ ++} ++ ++#if CFG_SUPPORT_BATCH_SCAN ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for SUPPORT_BATCH_SCAN ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_BATCH_RESULT_T prEventBatchResult; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DBGLOG(SCN, TRACE, "nicCmdEventBatchScanResult"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pucEventBuf; ++ ++ u4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); ++ kalMemCopy(prCmdInfo->pvInformationBuffer, prEventBatchResult, sizeof(EVENT_BATCH_RESULT_T)); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++#endif ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for build date code information ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_BUILD_DATE_CODE prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_BUILD_DATE_CODE) pucEventBuf; ++ ++ u4QueryInfoLen = sizeof(UINT_8) * 16; ++ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent->aucDateCode, sizeof(UINT_8) * 16); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for query STA link status ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_STA_STATISTICS_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_GET_STA_STATISTICS prStaStatistics; ++ ++ if ((prAdapter == NULL) ++ || (prCmdInfo == NULL) ++ || (pucEventBuf == NULL) ++ || (prCmdInfo->pvInformationBuffer == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_STA_STATISTICS_T) pucEventBuf; ++ prStaStatistics = (P_PARAM_GET_STA_STATISTICS) prCmdInfo->pvInformationBuffer; ++ ++ u4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); ++ ++ /* Statistics from FW is valid */ ++ if (prEvent->u4Flags & BIT(0)) { ++ prStaStatistics->ucPer = prEvent->ucPer; ++ prStaStatistics->ucRcpi = prEvent->ucRcpi; ++ prStaStatistics->u4PhyMode = prEvent->u4PhyMode; ++ prStaStatistics->u2LinkSpeed = prEvent->u2LinkSpeed; ++ ++ prStaStatistics->u4TxFailCount = prEvent->u4TxFailCount; ++ prStaStatistics->u4TxLifeTimeoutCount = prEvent->u4TxLifeTimeoutCount; ++ ++ if (prEvent->u4TxCount) { ++ UINT_32 u4TxDoneAirTimeMs = USEC_TO_MSEC(prEvent->u4TxDoneAirTime * 32); ++ ++ prStaStatistics->u4TxAverageAirTime = (u4TxDoneAirTimeMs / prEvent->u4TxCount); ++ } else { ++ prStaStatistics->u4TxAverageAirTime = 0; ++ } ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++/* 4 Auto Channel Selection */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for query STA link status ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_CHN_LOAD_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_GET_CHN_LOAD prChnLoad; ++ ++ if ((prAdapter == NULL) ++ || (prCmdInfo == NULL) ++ || (pucEventBuf == NULL) ++ || (prCmdInfo->pvInformationBuffer == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_CHN_LOAD_T) pucEventBuf; /* 4 The firmware responsed data */ ++ /* 4 Fill the firmware data in and send it back to host */ ++ prChnLoad = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; ++ ++ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); ++ ++ /* Statistics from FW is valid */ ++ if (prEvent->u4Flags & BIT(0)) { ++ prChnLoad->rEachChnLoad[0].ucChannel = prEvent->ucChannel; ++ prChnLoad->rEachChnLoad[0].u2ChannelLoad = prEvent->u2ChannelLoad; ++ DBGLOG(P2P, INFO, "CHN[%d]=%d\n", prEvent->ucChannel, prEvent->u2ChannelLoad); ++ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_8 ucIdx = 0; ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_LTE_MODE_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_GET_CHN_LOAD prLteSafeChnInfo; ++ ++ if ((prAdapter == NULL) ++ || (prCmdInfo == NULL) ++ || (pucEventBuf == NULL) ++ || (prCmdInfo->pvInformationBuffer == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_LTE_MODE_T) pucEventBuf; /* 4 The firmware responsed data */ ++ ++ prLteSafeChnInfo = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; ++ ++ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); ++ ++ /* Statistics from FW is valid */ ++ if (prEvent->u4Flags & BIT(0)) { ++ for (ucIdx = 0; ucIdx < (NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1); ucIdx++) { ++ prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx] = ++ prEvent->rLteSafeChn.au4SafeChannelBitmask[ucIdx]; ++ ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]LTE safe channels [%d]=[%x]\n", ucIdx, ++ (UINT32) prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx]); ++ } ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for query FW bss info ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_AIS_BSS_INFO_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_AIS_BSS_INFO_T) pucEventBuf; ++ ++ u4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); ++ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent, sizeof(EVENT_AIS_BSS_INFO_T)); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prEvent->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ if (prEvent->eConnectionState != prAisBssInfo->eConnectionState) { ++ DBGLOG(NIC, ERROR, "driver[%d] & FW[%d] status didn't sync !!!\n", ++ prAisBssInfo->eConnectionState, prEvent->eCurrentOPMode); ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, FALSE); ++ } ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c +new file mode 100644 +index 000000000000..cf80fd999a24 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c +@@ -0,0 +1,669 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1 ++*/ ++ ++/*! \file "nic_pwr_mgt.c" ++ \brief In this file we define the STATE and EVENT for Power Management FSM. ++ ++ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter ++ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail ++ description. ++*/ ++ ++/* ++** Log: nic_pwr_mgt.c ++ * ++ * 11 28 2011 cp.wu ++ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when ++ * returining to ROM code ++ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware ++ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 04 29 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * fix for compilation error when applied with FW_DOWNLOAD = 0 ++ * ++ * 04 18 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * 1) add API for glue layer to query ACPI state ++ * 2) Windows glue should not access to hardware after switched into D3 state ++ * ++ * 04 13 2011 cp.wu ++ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete ++ * refine for MT5931/MT6620 logic separation. ++ * ++ * 04 13 2011 cp.wu ++ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete ++ * bugfix: firmware download procedure for ACPI state transition is not complete. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system ++ * scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * check success or failure for setting fw-own ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * host driver not to set FW-own when there is still pending interrupts ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * reset ACPI power state before waking up MT6620 Wi-Fi firmware. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 22 2010 cp.wu ++ * ++ * 1) refine AIS-FSM indent. ++ * 2) when entering RF Test mode, flush 802.1X frames as well ++ * 3) when entering D3 state, flush 802.1X frames as well ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll ++ * 2) correct address list parsing ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * sleepy notify is only used for sleepy state, ++ * while wake-up state is automatically set when host needs to access device ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct hibernation problem. ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when acquiring driver-own, wait for up to 8 seconds. ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove redundant firmware image unloading ++ * * 2) use compile-time macros to separate logic related to accquiring own ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * * are now handled in glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * ePowerCtrl is not necessary as a glue variable. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always send CMD_NIC_POWER_CTRL packet when nic is being halted ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct typo. ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX ++ * response ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084 ++** remove CMD52 access ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084 ++** modify lines in nicpmSetDriverOwn() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084 ++** modify nicpmSetDriverOwn() ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084 ++** Initial version ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to process the POWER ON procedure. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt) ++{ ++ UINT_32 u4RegValue = 0; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsFwOwn == TRUE) ++ return; ++ ++ if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { ++ /* pending interrupts */ ++ return; ++ } ++ ++ if (fgEnableGlobalInt) { ++ prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; ++ } else { ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); ++ ++ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); ++ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { ++ /* if set firmware own not successful (possibly pending interrupts), */ ++ /* indicate an own clear event */ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ ++ return; ++ } ++ ++ prAdapter->fgIsFwOwn = TRUE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to process the POWER OFF procedure. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 u4OriRegValue = 0; ++BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) ++{ ++#define LP_OWN_BACK_TOTAL_DELAY_MS 2000 /* exponential of 2 */ ++#define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ ++#define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ ++ ++ BOOLEAN fgStatus = TRUE; ++ UINT_32 i, u4CurrTick; ++ UINT_32 u4RegValue = 0; ++ GL_HIF_INFO_T *HifInfo; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsFwOwn == FALSE) ++ return fgStatus; ++ ++ HifInfo = &prAdapter->prGlueInfo->rHifInfo; ++ ++ u4CurrTick = kalGetTimeTick(); ++ STATS_DRIVER_OWN_START_RECORD(); ++ i = 0; ++ ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); ++ ++ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); ++ prAdapter->fgIsFwOwn = FALSE; ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE ++ || fgIsBusAccessFailed == TRUE ++ || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { ++ /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */ ++ fgStatus = FALSE; ++ if (fgIsResetting != TRUE) { ++ UINT_32 u4FwCnt; ++ static unsigned int u4OwnCnt; ++ /* MCR_D2HRM2R: low 4 bit means interrupt times, ++ * high 4 bit means firmware response times. ++ * ORI_MCR_D2HRM2R: the last successful value. ++ * for example: ++ * MCR_D2HRM2R = 0x44, ORI_MCR_D2HRM2R = 0x44 ++ * means firmware no receive interrupt form hardware. ++ * MCR_D2HRM2R = 0x45, ORI_MCR_D2HRM2R = 0x44 ++ * means firmware no send response. ++ * MCR_D2HRM2R = 0x55, ORI_MCR_D2HRM2R = 0x44 ++ * means firmware send response, but driver no receive. */ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); ++ DBGLOG(NIC, WARN, " [1]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", ++ u4RegValue, u4OriRegValue); ++ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); ++ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); ++ prAdapter->fgIsFwOwn = FALSE; ++ break; ++ } ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); ++ DBGLOG(NIC, WARN, " [2]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", ++ u4RegValue, u4OriRegValue); ++ DBGLOG(NIC, WARN, ++ " Fatal error! Driver own fail!!!!!!!!!!!! %d, fgIsBusAccessFailed: %d\n", ++ u4OwnCnt++, fgIsBusAccessFailed); ++ ++ DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n"); ++ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) ++ DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); ++ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ ++ kalSendAeeWarning("[Fatal error! Driver own fail!]", __func__); ++ glDoChipReset(); ++ } ++ break; ++ } ++ if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { ++ /* Software get LP ownership - per 256 iterations */ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ } ++ ++ /* Delay for LP engine to complete its operation. */ ++ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); ++ i++; ++ } ++ ++ STATS_DRIVER_OWN_END_RECORD(); ++ STATS_DRIVER_OWN_STOP(); ++ ++ return fgStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set ACPI power mode to D0. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_32 u4Value = 0, u4WHISR = 0; ++ UINT_8 aucTxCount[8]; ++ UINT_32 i; ++#if CFG_ENABLE_FW_DOWNLOAD ++ UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize; ++ PVOID prFwMappingHandle; ++ PVOID pvFwImageMapFile = NULL; ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ UINT_32 j; ++ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; ++ BOOLEAN fgValidHead; ++ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); ++#endif ++#endif ++ ++ DEBUGFUNC("nicpmSetAcpiPowerD0"); ++ ASSERT(prAdapter); ++ ++ do { ++ /* 0. Reset variables in ADAPTER_T */ ++ prAdapter->fgIsFwOwn = TRUE; ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ prAdapter->rAcpiState = ACPI_STATE_D0; ++ prAdapter->fgIsEnterD3ReqIssued = FALSE; ++ ++ /* 1. Request Ownership to enter F/W download state */ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++#if !CFG_ENABLE_FULL_PM ++ nicpmSetDriverOwn(prAdapter); ++#endif ++ ++ /* 2. Initialize the Adapter */ ++ u4Status = nicInitializeAdapter(prAdapter); ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); ++ if (!prFwMappingHandle) { ++ DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n"); ++ pvFwImageMapFile = NULL; ++ } ++ ++ if (pvFwImageMapFile == NULL) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++ /* 3.1 disable interrupt, download is done by polling mode only */ ++ nicDisableInterrupt(prAdapter); ++ ++ /* 3.2 Initialize Tx Resource to fw download state */ ++ nicTxInitResetResource(prAdapter); ++ ++ /* 3.3 FW download here */ ++ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); ++ ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ /* 3a. parse file header for decision of divided firmware download or not */ ++ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; ++ ++ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && ++ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, ++ u4FwImgLength - u4CRCOffset)) { ++ fgValidHead = TRUE; ++ } else { ++ fgValidHead = FALSE; ++ } ++ ++ /* 3b. engage divided firmware downloading */ ++ if (fgValidHead == TRUE) { ++ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ prFwHead->arSection[i].u4DestAddr, ++ prFwHead->arSection[i].u4Length, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ prFwHead->arSection[i].u4DestAddr + j, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ /* escape from loop if any pending error occurs */ ++ if (u4Status == WLAN_STATUS_FAILURE) ++ break; ++ } ++ } else ++#endif ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ u4FwLoadAddr, ++ u4FwImgLength, ++ (PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = u4FwImgLength - i; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ u4FwLoadAddr + i, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "wlanImageSectionDownload failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); ++ break; ++ } ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ ++ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { ++ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++#endif ++ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); ++ ++ /* 4. send Wi-Fi Start command */ ++#if CFG_OVERRIDE_FW_START_ADDRESS ++ wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo)); ++#else ++ wlanConfigWifiFunc(prAdapter, FALSE, 0); ++#endif ++#endif /* if CFG_ENABLE_FW_DOWNLOAD */ ++ ++ /* 5. check Wi-Fi FW asserts ready bit */ ++ DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); ++ i = 0; ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ DBGLOG(NIC, TRACE, "Ready bit asserted\n"); ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { ++ DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ i++; ++ kalMsleep(10); ++ } ++ ++ if (u4Status == WLAN_STATUS_SUCCESS) { ++ /* 6.1 reset interrupt status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)(&u4WHISR)); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ ++ /* 6.2 reset TX Resource for normal operation */ ++ nicTxResetResource(prAdapter); ++ ++ /* 6.3 Enable interrupt */ ++ nicEnableInterrupt(prAdapter); ++ ++ /* 6.4 Override network address */ ++ wlanUpdateNetworkAddress(prAdapter); ++ ++ /* 6.5 indicate disconnection as default status */ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ } ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++ /* MGMT Initialization */ ++ nicInitMGMT(prAdapter, NULL); ++ ++ } while (FALSE); ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) ++ return FALSE; ++ else ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is used to set ACPI power mode to D3. ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ /* 1. MGMT - unitialization */ ++ nicUninitMGMT(prAdapter); ++ ++ /* 2. Disable Interrupt */ ++ nicDisableInterrupt(prAdapter); ++ ++ /* 3. emit CMD_NIC_POWER_CTRL command packet */ ++ wlanSendNicPowerCtrlCmd(prAdapter, 1); ++ ++ /* 4. Clear Interrupt Status */ ++ i = 0; ++ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { ++ i++; ++ }; ++ ++ /* 5. Remove pending TX */ ++ nicTxRelease(prAdapter); ++ ++ /* 5.1 clear pending Security / Management Frames */ ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++ kalClearMgmtFrames(prAdapter->prGlueInfo); ++ ++ /* 5.2 clear pending TX packet queued in glue layer */ ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* 6. Set Onwership to F/W */ ++ nicpmSetFWOwn(prAdapter, FALSE); ++ ++ /* 7. Set variables */ ++ prAdapter->rAcpiState = ACPI_STATE_D3; ++ ++ return TRUE; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c +new file mode 100644 +index 000000000000..ba4840414da8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c +@@ -0,0 +1,3782 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_rx.c#3 ++*/ ++ ++/*! \file nic_rx.c ++ \brief Functions that provide many rx-related functions ++ ++ This file includes the functions used to process RFB and dispatch RFBs to ++ the appropriate related rx functions for protocols. ++*/ ++ ++/* ++** Log: nic_rx.c ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, ++** one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 02 14 2012 cp.wu ++ * NULL ++ * remove another assertion by error message dump ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * avoid deactivating staRec when changing state from 3 to 3. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 09 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog for beacon timeout and sta aging timeout. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 10 21 2011 eddie.chen ++ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout ++ * Add switch to ignore the STA aging timeout. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 08 26 2011 cp.wu ++ * [WCXRP00000958] [MT6620 Wi-Fi][Driver] Extend polling timeout from 25ms to 1sec due to RF calibration might took ++ * up to 600ms ++ * extend polling RX response timeout period from 25ms to 1000ms. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 27 2011 cp.wu ++ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count ++ * correct comment. ++ * ++ * 07 27 2011 cp.wu ++ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count ++ * take use of QUE_MGT exported function to estimate currently RX buffer usage count. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 05 11 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Fix dest type when GO packet copying. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add delay after whole-chip resetting for MT5931 E1 ASIC. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support for GO. ++ * ++ * 04 01 2011 tsaiyuan.hsu ++ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues ++ * fix the klocwork issues, 57500, 57501, 57502 and 57503. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support for WiFi Direct Network. ++ * ++ * 03 18 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the Anti_piracy check at driver . ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to target station for AAA ++ * module. ++ * Remove Station Record after Aging timeout. ++ * ++ * 02 10 2011 cp.wu ++ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers ++ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add MLME deauthentication support for Hot-Spot mode. ++ * ++ * 02 09 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Adjust variable order. ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Remove comments. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Add destination decision in AP mode. ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec ++ * is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * update beacon for NoA ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 20 2010 wh.su ++ * NULL ++ * add a cmd to reset the p2p key ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * fixed compilier error. ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * release RX packet to packet pool when in RF test mode ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ @ associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a common buffer, store the IE of a P2P device in this common buffer. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * When enable WiFi Direct function, check each packet to tell which interface to indicate. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Add P2P Device Discovery Function. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * Add support API for RX public action frame. ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Update Device Capability Bitmap & Group Capability Bitmap from 16 bits to 8 bits. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill ucStaRecIdx into SW_RFB_T. ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) for event packet, no need to fill RFB. ++ * 2) when wlanAdapterStart() failed, no need to initialize state machines ++ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement TX_DONE callback path. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add TX Done Event handle entry ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync with MT6620 driver for scan result replacement policy ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 04 29 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * fixing the PMKID candicate indicate code. ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * basic implementation for EVENT_BT_OVER_WIFI ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * nicRxProcessEvent packet doesn't access spin-lock directly from now on. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * do not need to release the spin lock due to it is done inside nicGetPendingCmdInfo() ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add channel frequency <-> number conversion ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) add spinlock ++ * 2) add KAPI for handling association info ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 01 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve Linux supplicant compliance ++ * ++ * 03 31 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix ioctl which may cause cmdinfo memory leak ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * rWlanInfo is modified before data is indicated to OS ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * rWlanInfo is modified before data is indicated to OS ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * * * the frequency is used for adhoc connection only ++ * * * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * * * ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX ++ * response ++ * ++ * 03 15 2010 kevin.huang ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * Add event for activate STA_RECORD_T ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct fgSetQuery/fgNeedResp check ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * * * * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 02 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c ++ * * 'cause it involves OS dependent data structure handling ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Updated API interfaces for qmHandleEventRxAddBa() and qmHandleEventRxDelBa() ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * * * 4) nicRxWaitResponse() revised ++ * * * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * * * * OID_802_11_RSSI, ++ * * * * * * OID_802_11_RSSI_TRIGGER, ++ * * * * * * OID_802_11_STATISTICS, ++ * * * * * * OID_802_11_DISASSOCIATE, ++ * * * * * * OID_802_11_POWER_MODE ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * * * 2) add 4 counter for recording aggregation statistics ++ * ++ * 12 23 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a precheck: if free sw rfb is not enough, do not invoke read transactionu1rwduu`wvpghlqg|fu+rp ++ * ++ * 12 22 2009 cp.wu ++ * [WPD00003809][Bug] Host driver will crash when processing reordered MSDUs ++ * The root cause is pointer accessing by mistake. After dequeued from reordering-buffer, handling logic should access ++ * returned pointer instead of pointer which has been passed in before. ++** \main\maintrunk.MT6620WiFiDriver_Prj\58 2009-12-17 13:40:33 GMT mtk02752 ++** always update prAdapter->rSDIOCtrl when enhanced response is read by RX ++** \main\maintrunk.MT6620WiFiDriver_Prj\57 2009-12-16 18:01:38 GMT mtk02752 ++** if interrupt enhanced response is fetched by RX enhanced response, RX needs to invoke interrupt handlers too ++** \main\maintrunk.MT6620WiFiDriver_Prj\56 2009-12-16 14:16:52 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\55 2009-12-15 20:03:12 GMT mtk02752 ++** ASSERT when RX FreeSwRfb is not enough ++** \main\maintrunk.MT6620WiFiDriver_Prj\54 2009-12-15 17:01:29 GMT mtk02752 ++** when CFG_SDIO_RX_ENHANCE is enabled, after enhanced response is read, rx procedure should process ++** 1) TX_DONE_INT 2) D2H INT as well ++** \main\maintrunk.MT6620WiFiDriver_Prj\53 2009-12-14 20:45:28 GMT mtk02752 ++** when CFG_SDIO_RX_ENHANCE is set, TC counter must be updated each time RX enhance response is read ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\52 2009-12-14 11:34:16 GMT mtk02752 ++** correct a trivial logic issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\51 2009-12-14 10:28:25 GMT mtk02752 ++** add a protection to avoid out-of-boundary access ++** \main\maintrunk.MT6620WiFiDriver_Prj\50 2009-12-10 16:55:18 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\49 2009-12-09 14:06:47 GMT MTK02468 ++** Added parsing event packets with EVENT_ID_RX_ADDBA or EVENT_ID_RX_DELBA ++** \main\maintrunk.MT6620WiFiDriver_Prj\48 2009-12-08 17:37:51 GMT mtk02752 ++** handle EVENT_ID_TEST_STATUS as well ++** \main\maintrunk.MT6620WiFiDriver_Prj\47 2009-12-04 17:59:11 GMT mtk02752 ++** to pass free-build compilation check ++** \main\maintrunk.MT6620WiFiDriver_Prj\46 2009-12-04 12:09:52 GMT mtk02752 ++** correct trivial mistake ++** \main\maintrunk.MT6620WiFiDriver_Prj\45 2009-12-04 11:53:37 GMT mtk02752 ++** all API should be compilable under SD1_SD3_DATAPATH_INTEGRATION == 0 ++** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-03 16:19:48 GMT mtk01461 ++** Fix the Connected Event ++** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-11-30 10:56:18 GMT mtk02752 ++** 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-11-30 10:11:27 GMT mtk02752 ++** implement replacement for bss scan result ++** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-11-27 11:08:05 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-11-26 09:38:59 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-11-26 09:29:40 GMT mtk02752 ++** enable packet forwarding path (for AP mode) ++** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-11-25 21:37:00 GMT mtk02752 ++** sync. with EVENT_SCAN_RESULT_T change, and add an assert for checking event size ++** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-25 20:17:41 GMT mtk02752 ++** fill HIF_TX_HEADER_T.u2SeqNo ++** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-25 18:18:57 GMT mtk02752 ++** buffer scan result to prGlueInfo->rWlanInfo.arScanResult directly. ++** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-24 22:42:45 GMT mtk02752 ++** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event (not implemented yet) ++** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-24 20:51:41 GMT mtk02752 ++** integrate with SD1's data path API ++** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-24 19:56:17 GMT mtk02752 ++** adopt P_HIF_RX_HEADER_T in new path ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-23 20:31:21 GMT mtk02752 ++** payload to send into pfCmdDoneHandler() will not include WIFI_EVENT_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-23 17:51:34 GMT mtk02752 ++** when event packet corresponding to some pendingOID is received, pendingOID should be cleared ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 14:46:54 GMT mtk02752 ++** implement nicRxProcessEventPacket() ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-17 22:40:54 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-16 21:48:22 GMT mtk02752 ++** add SD1_SD3_DATAPATH_INTEGRATION data path handling ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-16 15:41:18 GMT mtk01084 ++** modify the length to be read in emu mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-13 17:00:12 GMT mtk02752 ++** add blank function for event packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-13 13:54:24 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 14:41:51 GMT mtk02752 ++** fix typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-11 14:33:46 GMT mtk02752 ++** add protection when there is no packet avilable ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 12:33:36 GMT mtk02752 ++** add RX1 read path for aggregated/enhanced/normal packet read procedures ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:18 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-04 14:11:08 GMT mtk01084 ++** modify lines in RX aggregation ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:23 GMT mtk01084 ++** modify RX aggregation handling ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:56:12 GMT mtk01084 ++** modify HAL part ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:34 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:20 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-02 13:59:08 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-21 23:39:05 GMT mtk01461 ++** Fix the paste error of RX STATUS in OOB of HIF Loopback CTRL ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-20 12:25:32 GMT mtk01461 ++** Fix process of Read Done, and add u4MaxEventBufferLen to nicRxWaitResponse() ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 21:13:18 GMT mtk01426 ++** Fixed compiler error ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:05:29 GMT mtk01426 ++** Fixed nicRxSDIOAggReceiveRFBs() ASSERT issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:38:43 GMT mtk01461 ++** Fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode and refine nicRxSDIOAggeceiveRFBs() for RX Aggregation ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-22 09:12:17 GMT mtk01461 ++** Fix nicRxProcessHIFLoopbackPacket(), the size of HIF CTRL LENGTH field is 1 byte ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426 ++** Update RX OOB Setting ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426 ++** Fixed logical error ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461 ++** Rename the HIF_PKT_TYPE_DATA ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461 ++** Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket() ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426 ++** Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426 ++** Add nicRxWaitResponse function ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#ifndef LINUX ++#include ++#else ++#include ++#endif ++ ++#include "gl_os.h" ++#include "debug.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include ++#include ++#include ++#include "gl_cfg80211.h" ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define RX_RESPONSE_TIMEOUT (1000) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_MGMT_FRAME_HANDLING ++static PROCESS_RX_MGT_FUNCTION apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = { ++#if CFG_SUPPORT_AAA ++ aaaFsmRunEventRxAssoc, /* subtype 0000: Association request */ ++#else ++ NULL, /* subtype 0000: Association request */ ++#endif /* CFG_SUPPORT_AAA */ ++ saaFsmRunEventRxAssoc, /* subtype 0001: Association response */ ++#if CFG_SUPPORT_AAA ++ aaaFsmRunEventRxAssoc, /* subtype 0010: Reassociation request */ ++#else ++ NULL, /* subtype 0010: Reassociation request */ ++#endif /* CFG_SUPPORT_AAA */ ++ saaFsmRunEventRxAssoc, /* subtype 0011: Reassociation response */ ++#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) ++ bssProcessProbeRequest, /* subtype 0100: Probe request */ ++#else ++ NULL, /* subtype 0100: Probe request */ ++#endif /* CFG_SUPPORT_ADHOC */ ++ scanProcessBeaconAndProbeResp, /* subtype 0101: Probe response */ ++ NULL, /* subtype 0110: reserved */ ++ NULL, /* subtype 0111: reserved */ ++ scanProcessBeaconAndProbeResp, /* subtype 1000: Beacon */ ++ NULL, /* subtype 1001: ATIM */ ++ saaFsmRunEventRxDisassoc, /* subtype 1010: Disassociation */ ++ authCheckRxAuthFrameTransSeq, /* subtype 1011: Authentication */ ++ saaFsmRunEventRxDeauth, /* subtype 1100: Deauthentication */ ++ nicRxProcessActionFrame, /* subtype 1101: Action */ ++ NULL, /* subtype 1110: reserved */ ++ NULL /* subtype 1111: reserved */ ++}; ++#endif ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the RFBs ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucMemHandle; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ UINT_32 i; ++ ++ DEBUGFUNC("nicRxInitialize"); ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ /* 4 <0> Clear allocated memory. */ ++ kalMemZero((PVOID) prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize); ++ ++ /* 4 <1> Initialize the RFB lists */ ++ QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList); ++ QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList); ++ QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList); ++ ++ pucMemHandle = prRxCtrl->pucRxCached; ++ for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) { ++ prSwRfb = (P_SW_RFB_T) pucMemHandle; ++ ++ nicRxSetupRFB(prAdapter, prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++ pucMemHandle += ALIGN_4(sizeof(SW_RFB_T)); ++ } ++ ++ ASSERT(prRxCtrl->rFreeSwRfbList.u4NumElem == CFG_RX_MAX_PKT_NUM); ++ /* Check if the memory allocation consist with this initialization function */ ++ ASSERT((ULONG) (pucMemHandle - prRxCtrl->pucRxCached) == prRxCtrl->u4RxCachedSize); ++ ++ /* 4 <2> Clear all RX counters */ ++ RX_RESET_ALL_CNTS(prRxCtrl); ++ ++#if CFG_SDIO_RX_AGG ++ prRxCtrl->pucRxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; ++ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM); ++#else ++ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1); ++#endif ++ ++#if CFG_HIF_STATISTICS ++ prRxCtrl->u4TotalRxAccessNum = 0; ++ prRxCtrl->u4TotalRxPacketNum = 0; ++#endif ++ ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4QueuedCnt = 0; ++ prRxCtrl->u4DequeuedCnt = 0; ++#endif ++ ++} /* end of nicRxInitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Uninitialize the RFBs ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ nicRxFlush(prAdapter); ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ if (prSwRfb) { ++ if (prSwRfb->pvPacket) ++ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); ++ prSwRfb->pvPacket = NULL; ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ if (prSwRfb) { ++ if (prSwRfb->pvPacket) ++ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); ++ prSwRfb->pvPacket = NULL; ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++} /* end of nicRxUninitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Fill RFB ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb specify the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ UINT_32 u4PktLen = 0; ++ UINT_32 u4MacHeaderLen; ++ UINT_32 u4HeaderOffset; ++ ++ DEBUGFUNC("nicRxFillRFB"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ u4PktLen = prHifRxHdr->u2PacketLen; ++ ++ u4HeaderOffset = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); ++ u4MacHeaderLen = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_LEN) ++ >> HIF_RX_HDR_HEADER_LEN_OFFSET; ++ ++ /* DBGLOG(RX, TRACE, ("u4HeaderOffset = %d, u4MacHeaderLen = %d\n", */ ++ /* u4HeaderOffset, u4MacHeaderLen)); */ ++ ++ prSwRfb->u2HeaderLen = (UINT_16) u4MacHeaderLen; ++ prSwRfb->pvHeader = (PUINT_8) prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; ++ prSwRfb->u2PacketLen = (UINT_16) (u4PktLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); ++ ++ /* DBGLOG(RX, TRACE, ("Dump Rx packet, u2PacketLen = %d\n", prSwRfb->u2PacketLen)); */ ++ /* DBGLOG_MEM8(RX, TRACE, prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ ++ ++#if 0 ++ if (prHifRxHdr->ucReorder & HIF_RX_HDR_80211_HEADER_FORMAT) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n"); ++ } ++ ++ if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n"); ++ ++ /* Get Seq. No and TID, Wlan Index info */ ++ if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n"); ++ } ++ ++ prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_SEQ_NO_MASK; ++ prSwRfb->ucTid = (UINT_8) ((prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_TID_MASK) ++ >> HIF_RX_HDR_TID_OFFSET); ++ DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", prSwRfb->u2SSN, prSwRfb->ucTid); ++ } ++ ++ if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n"); ++ } ++#endif ++} ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Fill checksum status in RFB ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* @param u4TcpUdpIpCksStatus specify the Checksum status ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus) ++{ ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED) { ++ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv4) { /* IPv4 packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_IP) { /* IP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_SUCCESS; ++ } ++ ++ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; ++ } ++ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; ++ } ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ } ++ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv6) { /* IPv6 packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS; ++ ++ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; ++ } ++ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; ++ } ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ } ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; ++ } ++ } ++ ++} ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process packet doesn't need to do buffer reordering ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_TX_CTRL_T prTxCtrl; ++ BOOLEAN fgIsRetained = FALSE; ++ UINT_32 u4CurrentRxBufferCount; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ DEBUGFUNC("nicRxProcessPktWithoutReorder"); ++ /* DBGLOG(RX, TRACE, ("\n")); */ ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem; ++ /* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C ++ * TOTAL = $A + $B + $C ++ * ++ * Case #1 (Retain) ++ * ------------------------------------------------------- ++ * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C := $TOTAL - THRESHOLD < $C ++ * => $C used too much, retain ++ * ++ * Case #2 (Non-Retain) ++ * ------------------------------------------------------- ++ * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C := $TOTAL - THRESHOLD > $C ++ * => still available for $C to use ++ * ++ */ ++ fgIsRetained = (((u4CurrentRxBufferCount + ++ qmGetRxReorderQueuedBufferCount(prAdapter) + ++ prTxCtrl->i4PendingFwdFrameCount) < CFG_RX_RETAINED_PKT_THRESHOLD) ? TRUE : FALSE); ++ ++ /* DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained)); */ ++ ++ if (kalProcessRxPacket(prAdapter->prGlueInfo, ++ prSwRfb->pvPacket, ++ prSwRfb->pvHeader, ++ (UINT_32) prSwRfb->u2PacketLen, fgIsRetained, prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(RX, ERROR, "kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n"); ++ ASSERT(0); ++ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ return; ++ } ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prStaRec) { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX && prAdapter->fgIsP2PRegistered == TRUE) ++ GLUE_SET_PKT_FLAG_P2P(prSwRfb->pvPacket); ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++ GLUE_SET_PKT_FLAG_PAL(prSwRfb->pvPacket); ++#endif ++ ++ /* record the count to pass to os */ ++ STATS_RX_PASS2OS_INC(prStaRec, prSwRfb); ++ } ++ prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = prSwRfb->pvPacket; ++ prRxCtrl->ucNumIndPacket++; ++ ++ if (fgIsRetained) { ++ prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = prSwRfb->pvPacket; ++ prRxCtrl->ucNumRetainedPacket++; ++ /* TODO : error handling of nicRxSetupRFB */ ++ nicRxSetupRFB(prAdapter, prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ } else { ++ prSwRfb->pvPacket = NULL; ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process forwarding data packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_MSDU_INFO_T prMsduInfo, prRetMsduInfoList; ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxProcessForwardPkt"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ if (prMsduInfo && kalProcessRxPacket(prAdapter->prGlueInfo, ++ prSwRfb->pvPacket, ++ prSwRfb->pvHeader, ++ (UINT_32) prSwRfb->u2PacketLen, ++ prRxCtrl->rFreeSwRfbList.u4NumElem < ++ CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE, ++ prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) { ++ ++ prMsduInfo->eSrc = TX_PACKET_FORWARDING; ++ /* pack into MSDU_INFO_T */ ++ nicTxFillMsduInfo(prAdapter, prMsduInfo, (P_NATIVE_PACKET) (prSwRfb->pvPacket)); ++ /* Overwrite the ucNetworkType */ ++ prMsduInfo->ucNetworkType = HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr); ++ ++ /* release RX buffer (to rIndicatedRfbList) */ ++ prSwRfb->pvPacket = NULL; ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++ /* increase forward frame counter */ ++ GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); ++ ++ /* send into TX queue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ if (prRetMsduInfoList != NULL) { /* TX queue refuses queuing the packet */ ++ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList); ++ nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList); ++ } ++ /* indicate service thread for sending */ ++ if (prTxCtrl->i4PendingFwdFrameCount > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ } else /* no TX resource */ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process broadcast data packet for both host and forwarding ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_SW_RFB_T prSwRfbDuplicated; ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxProcessGOBroadcastPkt"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16); ++ ++ if (prRxCtrl->rFreeSwRfbList.u4NumElem ++ >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - 16 /* Reserved for others */))) { ++ ++ /* 1. Duplicate SW_RFB_T */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfbDuplicated, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (prSwRfbDuplicated) { ++ kalMemCopy(prSwRfbDuplicated->pucRecvBuff, ++ prSwRfb->pucRecvBuff, ALIGN_4(prHifRxHdr->u2PacketLen + HIF_RX_HW_APPENDED_LEN)); ++ ++ prSwRfbDuplicated->ucPacketType = HIF_RX_PKT_TYPE_DATA; ++ prSwRfbDuplicated->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ nicRxFillRFB(prAdapter, prSwRfbDuplicated); ++ ++ /* 2. Modify eDst */ ++ prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD; ++ ++ /* 4. Forward */ ++ nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated); ++ } ++ } else { ++ DBGLOG(RX, WARN, "Stop to forward BMC packet due to less free Sw Rfb %u\n", ++ prRxCtrl->rFreeSwRfbList.u4NumElem); ++ } ++ ++ /* 3. Indicate to host */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_HOST; ++ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process HIF data packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prRetSwRfb, prNextSwRfb; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_STA_RECORD_T prStaRec; ++ BOOLEAN fIsDummy = FALSE; ++ ++ DEBUGFUNC("nicRxProcessDataPacket"); ++ /* DBGLOG(RX, TRACE, ("\n")); */ ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ fIsDummy = (prHifRxHdr->u2PacketLen >= 12) ? FALSE : TRUE; ++ ++ nicRxFillRFB(prAdapter, prSwRfb); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++ { ++ UINT_32 u4TcpUdpIpCksStatus; ++ ++ u4TcpUdpIpCksStatus = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); ++ nicRxFillChksumStatus(prAdapter, prSwRfb, u4TcpUdpIpCksStatus); ++ ++ } ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prHifRxHdr->ucStaRecIdx); ++ if (secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE && prAdapter->fgTestMode == FALSE) { ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4QueuedCnt++; ++#endif ++ prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb); ++ if (prRetSwRfb != NULL) { ++ do { ++ /* save next first */ ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prRetSwRfb); ++ if (fIsDummy == TRUE) { ++ nicRxReturnRFB(prAdapter, prRetSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ DBGLOG(RX, WARN, "Drop Dummy Packets"); ++ ++ } else { ++ switch (prRetSwRfb->eDst) { ++ case RX_PKT_DESTINATION_HOST: ++#if ARP_MONITER_ENABLE ++ if (IS_STA_IN_AIS(prStaRec)) ++ qmHandleRxArpPackets(prAdapter, prRetSwRfb); ++#endif ++ nicRxProcessPktWithoutReorder(prAdapter, prRetSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_FORWARD: ++ nicRxProcessForwardPkt(prAdapter, prRetSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: ++ nicRxProcessGOBroadcastPkt(prAdapter, prRetSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_NULL: ++ nicRxReturnRFB(prAdapter, prRetSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ break; ++ ++ default: ++ break; ++ } ++ } ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4DequeuedCnt++; ++#endif ++ prRetSwRfb = prNextSwRfb; ++ } while (prRetSwRfb); ++ } ++ } else { ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process HIF event packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++UINT_8 nicRxProcessGSCNEvent(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_WIFI_EVENT_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ struct sk_buff *skb; ++ struct wiphy *wiphy; ++ ++ UINT_32 real_num = 0; ++ ++ P_EVENT_GSCAN_SCAN_AVAILABLE_T prEventGscnAvailable; ++ P_EVENT_GSCAN_RESULT_T prEventBuffer; ++ P_WIFI_GSCAN_RESULT_T prEventGscnResult; ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_32 scan_id; ++ UINT_8 scan_flag; ++ P_EVENT_GSCAN_CAPABILITY_T prEventGscnCapbiblity; ++ P_EVENT_GSCAN_SCAN_COMPLETE_T prEventGscnScnDone; ++ P_WIFI_GSCAN_RESULT_T prEventGscnFullResult; ++ P_PARAM_WIFI_GSCAN_RESULT prParamGscnFullResult; ++ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnSignificantChange; ++ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnGeofenceFound; ++ ++ P_PARAM_WIFI_GSCAN_RESULT prResults; ++ ++ DEBUGFUNC("nicRxProcessGSCNEvent"); ++ /* DBGLOG(RX, TRACE, ("\n")); */ ++ ++ DBGLOG(SCN, INFO, "nicRxProcessGSCNEvent\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* Push the data to the skb */ ++ wiphy = priv_to_wiphy(prGlueInfo); ++ ++ /* prGlueInfo-> */ ++ ++ /* Event Handling */ ++ switch (prEvent->ucEID) { ++ case EVENT_ID_GSCAN_SCAN_AVAILABLE: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n"); ++ ++ prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T)); ++ ++ mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, ++ prEventGscnAvailable->u2Num); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_RESULT: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_RESULT 2\n"); ++ ++ prEventBuffer = (P_EVENT_GSCAN_RESULT_T) (prEvent->aucBuffer); ++ prEventGscnResult = prEventBuffer->rResult; ++/* ++ the following event struct should moved to kal and use the kal api to avoid future porting effort ++ ++*/ ++ scan_id = prEventBuffer->u2ScanId; ++ scan_flag = prEventBuffer->u2ScanFlags; ++ real_num = prEventBuffer->u2NumOfResults; ++ ++ DBGLOG(SCN, INFO, "scan_id=%d, scan_flag =%d, real_num=%d\r\n", scan_id, scan_flag, real_num); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num); ++ if (!skb) { ++ DBGLOG(RX, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ attr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); ++ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_SCAN_ID, scan_id);*/ ++ { ++ unsigned int __tmp = scan_id; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_ID, sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, 1);*/ ++ { ++ unsigned char __tmp = 1; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, sizeof(u8), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, real_num);*/ ++ { ++ unsigned int __tmp = real_num; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ prResults = (P_PARAM_WIFI_GSCAN_RESULT) prEventGscnResult; ++ if (prResults) ++ DBGLOG(SCN, INFO, "ssid=%s, rssi=%d, channel=%d \r\n", ++ prResults->ssid, prResults->rssi, prResults->channel); ++ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num, ++ prResults);*/ ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, ++ sizeof(PARAM_WIFI_GSCAN_RESULT)*real_num, prResults) < 0)) ++ goto nla_put_failure; ++ ++ DBGLOG(SCN, INFO, "NLA_PUT scan results over\t"); ++ ++ if (attr) ++ nla_nest_end(skb, attr); ++ /* report_events=1 */ ++ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, 1);*/ ++ { ++ unsigned char __tmp = 1; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ skb = NULL; ++ DBGLOG(SCN, INFO, " i4Status %d\n", i4Status); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_CAPABILITY: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_CAPABILITY\n"); ++ ++ prEventGscnCapbiblity = (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnCapbiblity, (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_CAPABILITY_T)); ++ ++ mtk_cfg80211_vendor_get_gscan_capabilities(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, ++ prEventGscnCapbiblity, sizeof(EVENT_GSCAN_CAPABILITY_T)); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_SCAN_COMPLETE: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n"); ++ prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SCAN_COMPLETE_T)); ++ ++ mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, ++ prEventGscnScnDone->ucScanState); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_FULL_RESULT: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_FULL_RESULT\n"); ++ ++ prEventGscnFullResult = kalMemAlloc(sizeof(WIFI_GSCAN_RESULT_T), VIR_MEM_TYPE); ++ if (prEventGscnFullResult) ++ memcpy(prEventGscnFullResult, (P_WIFI_GSCAN_RESULT_T) (prEvent->aucBuffer), ++ sizeof(WIFI_GSCAN_RESULT_T)); ++ ++ prParamGscnFullResult = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_RESULT), VIR_MEM_TYPE); ++ if (prEventGscnFullResult && prParamGscnFullResult) { ++ kalMemZero(prParamGscnFullResult, sizeof(PARAM_WIFI_GSCAN_RESULT)); ++ memcpy(prParamGscnFullResult, prEventGscnFullResult, sizeof(WIFI_GSCAN_RESULT_T)); ++ ++ mtk_cfg80211_vendor_event_full_scan_results(wiphy, ++ prGlueInfo->prDevHandler->ieee80211_ptr, ++ prParamGscnFullResult, ++ sizeof(PARAM_WIFI_GSCAN_RESULT)); ++ } ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: ++ { ++ prEventGscnSignificantChange = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnSignificantChange, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_GEOFENCE_FOUND: ++ { ++ prEventGscnGeofenceFound = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnGeofenceFound, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); ++ } ++ break; ++ ++ default: ++ DBGLOG(SCN, INFO, "not GSCN event ????\n"); ++ break; ++ } ++ ++ DBGLOG(SCN, INFO, "Done with GSCN event handling\n"); ++ return real_num; /* cfg80211_vendor_cmd_reply(skb); */ ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ DBGLOG(SCN, INFO, "nla_put_failure\n"); ++ return 0; /* cfg80211_vendor_cmd_reply(skb); */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process HIF event packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_WIFI_EVENT_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DEBUGFUNC("nicRxProcessEventPacket"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ DBGLOG(RX, EVENT, "prEvent->ucEID = 0x%02x\n", prEvent->ucEID); ++ /* Event Handling */ ++ switch (prEvent->ucEID) { ++ case EVENT_ID_CMD_RESULT: ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ P_EVENT_CMD_RESULT prCmdResult; ++ ++ prCmdResult = (P_EVENT_CMD_RESULT) ((PUINT_8) prEvent + EVENT_HDR_SIZE); ++ ++ /* CMD_RESULT should be only in response to Set commands */ ++ ASSERT(prCmdInfo->fgSetQuery == FALSE || prCmdInfo->fgNeedResp == TRUE); ++ ++ if (prCmdResult->ucStatus == 0) { /* success */ ++ if (prCmdInfo->pfCmdDoneHandler) { ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ } else if (prCmdInfo->fgIsOid == TRUE) { ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, ++ WLAN_STATUS_SUCCESS); ++ } ++ } else if (prCmdResult->ucStatus == 1) { /* reject */ ++ if (prCmdInfo->fgIsOid == TRUE) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, ++ WLAN_STATUS_FAILURE); ++ } else if (prCmdResult->ucStatus == 2) { /* unknown CMD */ ++ if (prCmdInfo->fgIsOid == TRUE) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, ++ WLAN_STATUS_NOT_SUPPORTED); ++ } ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ ++#if 0 ++ case EVENT_ID_CONNECTION_STATUS: ++ /* OBSELETE */ ++ { ++ P_EVENT_CONNECTION_STATUS prConnectionStatus; ++ ++ prConnectionStatus = (P_EVENT_CONNECTION_STATUS) (prEvent->aucBuffer); ++ ++ DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", prConnectionStatus->ucMediaStatus); ++ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { ++ /* disconnected */ ++ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ } ++ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { ++ /* connected */ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ ++ /* fill information for association result */ ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); ++ ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ prConnectionStatus->aucBssid, MAC_ADDR_LEN); ++ ++ /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.u4Privacy = prConnectionStatus->ucEncryptStatus; ++ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ ++ /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse = PARAM_NETWORK_TYPE_AUTOMODE; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod ++ = prConnectionStatus->u2BeaconPeriod; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow ++ = prConnectionStatus->u2ATIMWindow; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig ++ = prConnectionStatus->u4FreqInKHz; ++ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; ++ ++ switch (prConnectionStatus->ucInfraMode) { ++ case 0: ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_IBSS; ++ break; ++ case 1: ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_INFRA; ++ break; ++ case 2: ++ default: ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_AUTO_SWITCH; ++ break; ++ } ++ /* always indicate to OS according to MSDN (re-association/roaming) */ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); ++ } ++ } ++ break; ++ ++ case EVENT_ID_SCAN_RESULT: ++ /* OBSELETE */ ++ break; ++#endif ++ ++ case EVENT_ID_RX_ADDBA: ++ /* The FW indicates that an RX BA agreement will be established */ ++ qmHandleEventRxAddBa(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_RX_DELBA: ++ /* The FW indicates that an RX BA agreement has been deleted */ ++ qmHandleEventRxDelBa(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_LINK_QUALITY: ++#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY ++ if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof(EVENT_LINK_QUALITY_EX)) { ++ P_EVENT_LINK_QUALITY_EX prLqEx = (P_EVENT_LINK_QUALITY_EX) (prEvent->aucBuffer); ++ ++ if (prLqEx->ucIsLQ0Rdy) ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); ++ if (prLqEx->ucIsLQ1Rdy) ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_P2P_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); ++ } else { ++ /* For old FW, P2P may invoke link quality query, and make driver flag becone TRUE. */ ++ DBGLOG(P2P, WARN, "Old FW version, not support P2P RSSI query.\n"); ++ ++ /* Must not use NETWORK_TYPE_P2P_INDEX, cause the structure is mismatch. */ ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, ++ (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); ++ } ++#else ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); ++#endif ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++#ifndef LINUX ++ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_GREATER && ++ prAdapter->rWlanInfo.rRssiTriggerValue >= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; ++ ++ kalIndicateStatusAndComplete(prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), ++ sizeof(PARAM_RSSI)); ++ } else if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_LESS ++ && prAdapter->rWlanInfo.rRssiTriggerValue <= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; ++ ++ kalIndicateStatusAndComplete(prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), ++ sizeof(PARAM_RSSI)); ++ } ++#endif ++ ++ break; ++ ++ case EVENT_ID_MIC_ERR_INFO: ++ { ++ P_EVENT_MIC_ERR_INFO prMicError; ++ /* P_PARAM_AUTH_EVENT_T prAuthEvent; */ ++ P_STA_RECORD_T prStaRec; ++ ++ DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n"); ++ ++ prMicError = (P_EVENT_MIC_ERR_INFO) (prEvent->aucBuffer); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ (UINT_8) NETWORK_TYPE_AIS_INDEX, ++ prAdapter->rWlanInfo.rCurrBssId.arMacAddress); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) ++ rsnTkipHandleMICFailure(prAdapter, prStaRec, (BOOLEAN) prMicError->u4Flags); ++ else ++ DBGLOG(RSN, WARN, "No STA rec!!\n"); ++#if 0 ++ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; ++ ++ /* Status type: Authentication Event */ ++ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; ++ ++ /* Authentication request */ ++ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); ++ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, ++ (PVOID) prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ /* whsu:Todo? */PARAM_MAC_ADDR_LEN); ++ ++ if (prMicError->u4Flags != 0) ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; ++ else ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAuthEvent, ++ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); ++#endif ++ } ++ break; ++ ++ case EVENT_ID_ASSOC_INFO: ++ { ++ P_EVENT_ASSOC_INFO prAssocInfo; ++ ++ prAssocInfo = (P_EVENT_ASSOC_INFO) (prEvent->aucBuffer); ++ ++ kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo); ++ } ++ break; ++ ++ case EVENT_ID_802_11_PMKID: ++ { ++ P_PARAM_AUTH_EVENT_T prAuthEvent; ++ PUINT_8 cp; ++ UINT_32 u4LenOfUsedBuffer; ++ ++ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; ++ ++ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; ++ ++ u4LenOfUsedBuffer = (UINT_32) (prEvent->u2PacketLen - 8); ++ ++ prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer; ++ ++ cp = (PUINT_8) &prAuthEvent->arRequest[0]; ++ ++ /* Status type: PMKID Candidatelist Event */ ++ kalMemCopy(cp, (P_EVENT_PMKID_CANDIDATE_LIST_T) (prEvent->aucBuffer), prEvent->u2PacketLen - 8); ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAuthEvent, ++ sizeof(PARAM_STATUS_INDICATION_T) + u4LenOfUsedBuffer); ++ } ++ break; ++ ++#if 0 ++ case EVENT_ID_ACTIVATE_STA_REC_T: ++ { ++ P_EVENT_ACTIVATE_STA_REC_T prActivateStaRec; ++ ++ prActivateStaRec = (P_EVENT_ACTIVATE_STA_REC_T) (prEvent->aucBuffer); ++ ++ DbgPrint("RX EVENT: EVENT_ID_ACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", ++ prActivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); ++ ++ qmActivateStaRec(prAdapter, ++ (UINT_32) prActivateStaRec->ucStaRecIdx, ++ ((prActivateStaRec->fgIsQoS) ? TRUE : FALSE), ++ prActivateStaRec->ucNetworkTypeIndex, ++ ((prActivateStaRec->fgIsAP) ? TRUE : FALSE), prActivateStaRec->aucMacAddr); ++ ++ } ++ break; ++ ++ case EVENT_ID_DEACTIVATE_STA_REC_T: ++ { ++ P_EVENT_DEACTIVATE_STA_REC_T prDeactivateStaRec; ++ ++ prDeactivateStaRec = (P_EVENT_DEACTIVATE_STA_REC_T) (prEvent->aucBuffer); ++ ++ DbgPrint("RX EVENT: EVENT_ID_DEACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", ++ prDeactivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); ++ ++ qmDeactivateStaRec(prAdapter, prDeactivateStaRec->ucStaRecIdx); ++ } ++ break; ++#endif ++ ++ case EVENT_ID_SCAN_DONE: ++ scnEventScanDone(prAdapter, (P_EVENT_SCAN_DONE) (prEvent->aucBuffer)); ++ break; ++ ++ case EVENT_ID_TX_DONE_STATUS: ++ STATS_TX_PKT_DONE_INFO_DISPLAY(prAdapter, prEvent->aucBuffer); ++ break; ++ ++ case EVENT_ID_TX_DONE: ++ { ++ P_EVENT_TX_DONE_T prTxDone; ++ ++ prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer); ++ if (prTxDone->ucStatus) ++ DBGLOG(RX, INFO, "EVENT_ID_TX_DONE PacketSeq:%u ucStatus: %u SN: %u\n", ++ prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber); ++ ++ /* call related TX Done Handler */ ++ prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucPacketSeq); ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++ DBGLOG(RX, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n", ++ prTxDone->au4Reserved1, prTxDone->au4Reserved2); ++ ++ wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex, ++ prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2); ++#endif ++ ++ if (prMsduInfo) { ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, ++ (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus)); ++ ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } ++ } ++ break; ++ case EVENT_ID_SLEEPY_NOTIFY: ++ { ++ P_EVENT_SLEEPY_NOTIFY prEventSleepyNotify; ++ ++ prEventSleepyNotify = (P_EVENT_SLEEPY_NOTIFY) (prEvent->aucBuffer); ++ ++ /* DBGLOG(RX, INFO, ("ucSleepyState = %d\n", prEventSleepyNotify->ucSleepyState)); */ ++ ++ prAdapter->fgWiFiInSleepyState = (BOOLEAN) (prEventSleepyNotify->ucSleepyState); ++ } ++ break; ++ case EVENT_ID_BT_OVER_WIFI: ++#if CFG_ENABLE_BT_OVER_WIFI ++ { ++ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; ++ P_EVENT_BT_OVER_WIFI prEventBtOverWifi; ++ P_AMPC_EVENT prBowEvent; ++ P_BOW_LINK_CONNECTED prBowLinkConnected; ++ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; ++ ++ prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); ++ ++ /* construct event header */ ++ prBowEvent = (P_AMPC_EVENT) aucTmp; ++ ++ if (prEventBtOverWifi->ucLinkStatus == 0) { ++ /* Connection */ ++ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; ++ prBowEvent->rHeader.ucSeqNumber = 0; ++ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); ++ ++ /* fill event body */ ++ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prBowEvent->aucPayload); ++ prBowLinkConnected->rChannel.ucChannelNum = prEventBtOverWifi->ucSelectedChannel; ++ kalMemZero(prBowLinkConnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); ++ } else { ++ /* Disconnection */ ++ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; ++ prBowEvent->rHeader.ucSeqNumber = 0; ++ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); ++ ++ /* fill event body */ ++ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prBowEvent->aucPayload); ++ prBowLinkDisconnected->ucReason = 0; /* @FIXME */ ++ kalMemZero(prBowLinkDisconnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); ++ } ++ } ++ break; ++#endif ++ case EVENT_ID_STATISTICS: ++ /* buffer statistics for further query */ ++ prAdapter->fgIsStatValid = TRUE; ++ prAdapter->rStatUpdateTime = kalGetTimeTick(); ++ kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, sizeof(EVENT_STATISTICS)); ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ ++ case EVENT_ID_CH_PRIVILEGE: ++ cnmChMngrHandleChEvent(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_BSS_ABSENCE_PRESENCE: ++ qmHandleEventBssAbsencePresence(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_STA_CHANGE_PS_MODE: ++ qmHandleEventStaChangePsMode(prAdapter, prEvent); ++ break; ++#if CFG_ENABLE_WIFI_DIRECT ++ case EVENT_ID_STA_UPDATE_FREE_QUOTA: ++ qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent); ++ break; ++#endif ++ case EVENT_ID_BSS_BEACON_TIMEOUT: ++ if (prAdapter->fgDisBcnLostDetection == FALSE) { ++ P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout; ++ ++ prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T) (prEvent->aucBuffer); ++ ++ DBGLOG(RX, INFO, "Beacon Timeout Reason = %u\n", prEventBssBeaconTimeout->ucReason); ++ ++ if (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ /* Request stats report before beacon timeout */ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (prBssInfo) { ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ++ prBssInfo->aucBSSID); ++ if (prStaRec) ++ STATS_ENV_REPORT_DETECT(prAdapter, prStaRec->ucIndex); ++ } ++ aisBssBeaconTimeout(prAdapter); ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && ++ (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) ++ ++ p2pFsmRunEventBeaconTimeout(prAdapter); ++#endif ++ else { ++ DBGLOG(RX, ERROR, "EVENT_ID_BSS_BEACON_TIMEOUT: (ucNetTypeIdx = %d)\n", ++ prEventBssBeaconTimeout->ucNetTypeIndex); ++ } ++ } ++ ++ break; ++ case EVENT_ID_UPDATE_NOA_PARAMS: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam; ++ ++ prEventUpdateNoaParam = (P_EVENT_UPDATE_NOA_PARAMS_T) (prEvent->aucBuffer); ++ ++ if (prEventUpdateNoaParam->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ p2pProcessEvent_UpdateNOAParam(prAdapter, ++ prEventUpdateNoaParam->ucNetTypeIndex, ++ prEventUpdateNoaParam); ++ } else { ++ ASSERT(0); ++ } ++ } ++#else ++ ASSERT(0); ++#endif ++ break; ++ ++ case EVENT_ID_STA_AGING_TIMEOUT: ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) { ++ P_EVENT_STA_AGING_TIMEOUT_T prEventStaAgingTimeout; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; ++ ++ prEventStaAgingTimeout = (P_EVENT_STA_AGING_TIMEOUT_T) (prEvent->aucBuffer); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventStaAgingTimeout->ucStaRecIdx); ++ if (prStaRec == NULL) ++ break; ++ ++ DBGLOG(RX, INFO, "EVENT_ID_STA_AGING_TIMEOUT %u %pM\n", ++ prEventStaAgingTimeout->ucStaRecIdx, ++ prStaRec->aucMacAddr); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); ++ ++ /* Call False Auth */ ++ if (prAdapter->fgIsP2PRegistered) ++ p2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY); ++ ++ } ++ /* gDisStaAgingTimeoutDetection */ ++ } ++#endif ++ break; ++ ++ case EVENT_ID_AP_OBSS_STATUS: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ rlmHandleObssStatusEventPkt(prAdapter, (P_EVENT_AP_OBSS_STATUS_T) prEvent->aucBuffer); ++#endif ++ break; ++ ++ case EVENT_ID_ROAMING_STATUS: ++#if CFG_SUPPORT_ROAMING ++ { ++ P_ROAMING_PARAM_T prParam; ++ ++ prParam = (P_ROAMING_PARAM_T) (prEvent->aucBuffer); ++ roamingFsmProcessEvent(prAdapter, prParam); ++ } ++#endif /* CFG_SUPPORT_ROAMING */ ++ break; ++ case EVENT_ID_SEND_DEAUTH: ++ { ++ P_WLAN_MAC_HEADER_T prWlanMacHeader; ++ P_STA_RECORD_T prStaRec; ++ ++ prWlanMacHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; ++ DBGLOG(RSN, INFO, "nicRx: aucAddr1: %pM, nicRx: aucAddr2: %pM\n", ++ prWlanMacHeader->aucAddr1, prWlanMacHeader->aucAddr2); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanMacHeader->aucAddr2); ++ if (prStaRec != NULL && prStaRec->ucStaState == STA_STATE_3) { ++ DBGLOG(RSN, WARN, "Ignore Deauth for Rx Class 3 error!\n"); ++ } else { ++ /* receive packets without StaRec */ ++ prSwRfb->pvHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; ++ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, ++ NULL, ++ prSwRfb, ++ REASON_CODE_CLASS_3_ERR, ++ (PFN_TX_DONE_HANDLER) NULL)) ++ DBGLOG(RSN, INFO, "Send Deauth for Rx Class3 Error\n"); ++ else ++ DBGLOG(RSN, WARN, "failed to send deauth for Rx class3 error\n"); ++ } ++ } ++ break; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ case EVENT_ID_UPDATE_RDD_STATUS: ++ { ++ P_EVENT_RDD_STATUS_T prEventRddStatus; ++ ++ prEventRddStatus = (P_EVENT_RDD_STATUS_T) (prEvent->aucBuffer); ++ ++ prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus; ++ } ++ ++ break; ++#endif ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ case EVENT_ID_UPDATE_BWCS_STATUS: ++ { ++ P_PTA_IPC_T prEventBwcsStatus; ++ ++ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); ++ ++#if CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(RSN, INFO, ++ "BCM BWCS Event: %02x%02x%02x%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); ++ ++ DBGLOG(RSN, INFO, ++ "BCM BWCS Event: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); ++#endif ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_BWCS_UPDATE, ++ (PVOID) prEventBwcsStatus, sizeof(PTA_IPC_T)); ++ } ++ ++ break; ++ ++ case EVENT_ID_UPDATE_BCM_DEBUG: ++ { ++ P_PTA_IPC_T prEventBwcsStatus; ++ ++ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); ++ ++#if CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(RSN, INFO, ++ "BCM FW status: %02x%02x%02x%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); ++ ++ DBGLOG(RSN, INFO, ++ "BCM FW status: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]; ++#endif ++ } ++ ++ break; ++#endif ++ ++ case EVENT_ID_DEBUG_CODE: /* only for debug */ ++ { ++ UINT_32 u4CodeId; ++ ++ DBGLOG(RSN, INFO, "[wlan-fw] function sequence: "); ++ for (u4CodeId = 0; u4CodeId < 1000; u4CodeId++) ++ DBGLOG(RSN, INFO, "%d ", prEvent->aucBuffer[u4CodeId]); ++ DBGLOG(RSN, INFO, "\n\n"); ++ } ++ break; ++ ++ case EVENT_ID_RFTEST_READY: ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ ++ case EVENT_ID_GSCAN_SCAN_AVAILABLE: ++ case EVENT_ID_GSCAN_CAPABILITY: ++ case EVENT_ID_GSCAN_SCAN_COMPLETE: ++ case EVENT_ID_GSCAN_FULL_RESULT: ++ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: ++ case EVENT_ID_GSCAN_GEOFENCE_FOUND: ++ nicRxProcessGSCNEvent(prAdapter, prSwRfb); ++ break; ++ ++ case EVENT_ID_GSCAN_RESULT: ++ { ++ ++ UINT_8 realnum = 0; ++ ++ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent ----->\n"); ++ realnum = nicRxProcessGSCNEvent(prAdapter, prSwRfb); ++ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent <-----\n"); ++ ++#if 0 /* workaround for FW events cnt mis-match with the actual reqirements from wifi_hal */ ++ if (g_GetResultsCmdCnt == 0) { ++ DBGLOG(SCN, INFO, ++ "FW report events more than the wifi_hal asked number, buffer the results\n"); ++ UINT_8 i = 0; ++ ++ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { ++#if 1 ++ if (!g_arGscanResultsIndicateNumber[i]) { ++ DBGLOG(SCN, INFO, ++ "found available index %d to insert results number %d into buffer\r\n", ++ i, realnum); ++ ++ g_arGscnResultsTempBuffer[i] = prSwRfb; ++ g_arGscanResultsIndicateNumber[i] = realnum; ++ g_GetResultsBufferedCnt++; ++ fgKeepprSwRfb = TRUE; ++ DBGLOG(SCN, INFO, "results buffered in index[%d] \r\n", i); ++ break; ++ } ++#endif ++ } ++ if (i == MAX_BUFFERED_GSCN_RESULTS) ++ DBGLOG(SCN, INFO, ++ "Gscn results buffer is full(all valid), no space to buffer result\r\n"); ++ } else if (g_GetResultsCmdCnt > 0) { ++ DBGLOG(SCN, INFO, "FW report events match the wifi_hal asked number\n"); ++ g_GetResultsCmdCnt--; ++ } else ++ DBGLOG(SCN, INFO, "g_GetResultsCmdCnt < 0 ??? unexpected case\n"); ++#endif ++ /* end of workaround */ ++ ++ } ++ break; ++ ++ case EVENT_ID_NLO_DONE: ++ prAdapter->rWifiVar.rScanInfo.fgPscnOnnning = FALSE; ++ ++ DBGLOG(INIT, INFO, "EVENT_ID_NLO_DONE\n"); ++ scnEventNloDone(prAdapter, (P_EVENT_NLO_DONE_T) (prEvent->aucBuffer)); ++ ++ break; ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ case EVENT_ID_BATCH_RESULT: ++ DBGLOG(SCN, TRACE, "Got EVENT_ID_BATCH_RESULT"); ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++#endif /* CFG_SUPPORT_BATCH_SCAN */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ case EVENT_ID_TDLS: ++ TdlsexEventHandle(prAdapter->prGlueInfo, ++ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); ++ break; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#if (CFG_SUPPORT_STATISTICS == 1) ++ case EVENT_ID_STATS_ENV: ++ statsEventHandle(prAdapter->prGlueInfo, ++ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); ++ break; ++#endif /* CFG_SUPPORT_STATISTICS */ ++ ++ case EVENT_ID_FW_LOG_ENV: ++ { ++ P_EVENT_FW_LOG_T prEventLog; ++ ++ prEventLog = (P_EVENT_FW_LOG_T) (prEvent->aucBuffer); ++ DBGLOG(RX, INFO, "[F-L]%s\n", prEventLog->log); ++ } ++ break; ++ ++ default: ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ } ++ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief nicRxProcessMgmtPacket is used to dispatch management frames ++* to corresponding modules ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ UINT_8 ucSubtype; ++#if CFG_SUPPORT_802_11W ++ BOOLEAN fgMfgDrop = FALSE; ++#endif ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ nicRxFillRFB(prAdapter, prSwRfb); ++ ++ ucSubtype = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; ++ ++#if 0 /* CFG_RX_PKTS_DUMP */ ++ { ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_16 u2TxFrameCtrl; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ u2TxFrameCtrl = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FRAME_TYPE); ++ /* if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_MANAGEMENT)) { */ ++ /* if (u2TxFrameCtrl == MAC_FRAME_BEACON || */ ++ /* u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { */ ++ ++ DBGLOG(RX, INFO, "QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n", ++ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), prHifRxHdr->ucStaRecIdx, ++ prSwRfb->ucWlanIdx, (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr),/* The new SN of the frame */ ++ prSwRfb->ucPacketType, ucSubtype, HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); ++ ++ /* DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ ++ /* } */ ++ /* } */ ++ } ++#endif ++ ++ if ((prAdapter->fgTestMode == FALSE) && (prAdapter->prGlueInfo->fgIsRegistered == TRUE)) { ++#if CFG_MGMT_FRAME_HANDLING ++#if CFG_SUPPORT_802_11W ++ fgMfgDrop = rsnCheckRxMgmt(prAdapter, prSwRfb, ucSubtype); ++ if (fgMfgDrop) { ++#if DBG ++ LOG_FUNC("QM RX MGT: Drop Unprotected Mgmt frame!!!\n"); ++#endif ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ return; ++ } ++#endif ++ if (apfnProcessRxMgtFrame[ucSubtype]) { ++ switch (apfnProcessRxMgtFrame[ucSubtype] (prAdapter, prSwRfb)) { ++ case WLAN_STATUS_PENDING: ++ return; ++ case WLAN_STATUS_SUCCESS: ++ case WLAN_STATUS_FAILURE: ++ break; ++ ++ default: ++ DBGLOG(RX, WARN, ++ "Unexpected MMPDU(0x%02X) returned with abnormal status\n", ucSubtype); ++ break; ++ } ++ } ++#endif ++ } ++ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++} ++ ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++static VOID nicRxCheckWakeupReason(P_SW_RFB_T prSwRfb) ++{ ++ PUINT_8 pvHeader = NULL; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_16 u2PktLen = 0; ++ UINT_32 u4HeaderOffset; ++ ++ if (!prSwRfb) ++ return; ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ if (!prHifRxHdr) ++ return; ++ ++ switch (prSwRfb->ucPacketType) { ++ case HIF_RX_PKT_TYPE_DATA: ++ { ++ UINT_16 u2Temp = 0; ++ ++ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { ++ DBGLOG(RX, INFO, "BAR frame[SSN:%d, TID:%d] wakeup host\n", ++ (UINT_16)HIF_RX_HDR_GET_SN(prHifRxHdr), (UINT_8)HIF_RX_HDR_GET_TID(prHifRxHdr)); ++ break; ++ } ++ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); ++ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; ++ u2PktLen = (UINT_16)(prHifRxHdr->u2PacketLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); ++ if (!pvHeader) { ++ DBGLOG(RX, ERROR, "data packet but pvHeader is NULL!\n"); ++ break; ++ } ++ u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | (pvHeader[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ switch (u2Temp) { ++ case ETH_P_IPV4: ++ u2Temp = *(UINT_16 *) &pvHeader[ETH_HLEN + 4]; ++ DBGLOG(RX, INFO, "IP Packet from:%d.%d.%d.%d, IP ID 0x%04x wakeup host\n", ++ pvHeader[ETH_HLEN + 12], pvHeader[ETH_HLEN + 13], ++ pvHeader[ETH_HLEN + 14], pvHeader[ETH_HLEN + 15], u2Temp); ++ break; ++ case ETH_P_ARP: ++ { ++ PUINT_8 pucEthBody = &pvHeader[ETH_HLEN]; ++ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; ++ ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(RX, INFO, "Arp Req From IP: %d.%d.%d.%d wakeup host\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(RX, INFO, "Arp Rsp from IP: %d.%d.%d.%d wakeup host\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ break; ++ } ++ case ETH_P_1X: ++ case ETH_P_PRE_1X: ++#if CFG_SUPPORT_WAPI ++ case ETH_WPI_1X: ++#endif ++ case ETH_P_AARP: ++ case ETH_P_IPV6: ++ case ETH_P_IPX: ++ case 0x8100: /* VLAN */ ++ case 0x890d: /* TDLS */ ++ DBGLOG(RX, INFO, "Data Packet, EthType 0x%04x wakeup host\n", u2Temp); ++ break; ++ default: ++ DBGLOG(RX, WARN, "maybe abnormal data packet, EthType 0x%04x wakeup host, dump it\n", ++ u2Temp); ++ DBGLOG_MEM8(RX, INFO, pvHeader, u2PktLen > 50 ? 50:u2PacketLen); ++ break; ++ } ++ break; ++ } ++ case HIF_RX_PKT_TYPE_EVENT: ++ { ++ P_WIFI_EVENT_T prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; ++ ++ DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", prEvent->ucEID); ++ break; ++ } ++ case HIF_RX_PKT_TYPE_MANAGEMENT: ++ { ++ UINT_8 ucSubtype; ++ P_WLAN_MAC_MGMT_HEADER_T prWlanMgmtHeader; ++ ++ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); ++ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; ++ if (!pvHeader) { ++ DBGLOG(RX, ERROR, "Mgmt Frame but pvHeader is NULL!\n"); ++ break; ++ } ++ prWlanMgmtHeader = (P_WLAN_MAC_MGMT_HEADER_T)pvHeader; ++ ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> ++ OFFSET_OF_FC_SUBTYPE; ++ DBGLOG(RX, INFO, "MGMT frame subtype: %d SeqCtrl %d wakeup host\n", ++ ucSubtype, prWlanMgmtHeader->u2SeqCtrl); ++ break; ++ } ++ default: ++ DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", prSwRfb->ucPacketType); ++ break; ++ } ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxProcessRFBs"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ prRxCtrl->ucNumIndPacket = 0; ++ prRxCtrl->ucNumRetainedPacket = 0; ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (prSwRfb) { ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++ if (kalIsWakeupByWlan(prAdapter)) ++ nicRxCheckWakeupReason(prSwRfb); ++#endif ++ switch (prSwRfb->ucPacketType) { ++ case HIF_RX_PKT_TYPE_DATA: ++ nicRxProcessDataPacket(prAdapter, prSwRfb); ++ break; ++ ++ case HIF_RX_PKT_TYPE_EVENT: ++ nicRxProcessEventPacket(prAdapter, prSwRfb); ++ break; ++ ++ case HIF_RX_PKT_TYPE_TX_LOOPBACK: ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ { ++ kalDevLoopbkRxHandle(prAdapter, prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ } ++#else ++ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ break; ++ ++ case HIF_RX_PKT_TYPE_MANAGEMENT: ++ nicRxProcessMgmtPacket(prAdapter, prSwRfb); ++ break; ++ ++ default: ++ RX_INC_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); ++ nicRxReturnRFB(prAdapter, prSwRfb); /* need to free it */ ++ break; ++ } ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++ if (prRxCtrl->ucNumIndPacket > 0) { ++ RX_ADD_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT, prRxCtrl->ucNumIndPacket); ++ RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, prRxCtrl->ucNumRetainedPacket); ++ ++ /* DBGLOG(RX, INFO, ("%d packets indicated, Retained cnt = %d\n", */ ++ /* prRxCtrl->ucNumIndPacket, prRxCtrl->ucNumRetainedPacket)); */ ++#if CFG_NATIVE_802_11 ++ kalRxIndicatePkts(prAdapter->prGlueInfo, (UINT_32) prRxCtrl->ucNumIndPacket, ++ (UINT_32) prRxCtrl->ucNumRetainedPacket); ++#else ++ kalRxIndicatePkts(prAdapter->prGlueInfo, prRxCtrl->apvIndPacket, (UINT_32) prRxCtrl->ucNumIndPacket); ++#endif ++ } ++ ++} /* end of nicRxProcessRFBs() */ ++ ++#if !CFG_SDIO_INTR_ENHANCE ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read the rx data from data port and setup RFB ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @retval WLAN_STATUS_SUCCESS: SUCCESS ++* @retval WLAN_STATUS_FAILURE: FAILURE ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucBuf; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_32 u4PktLen = 0, u4ReadBytes; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgResult = TRUE; ++ UINT_32 u4RegValue; ++ UINT_32 rxNum; ++ ++ DEBUGFUNC("nicRxReadBuffer"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ pucBuf = prSwRfb->pucRecvBuff; ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(pucBuf); ++ DBGLOG(RX, TRACE, "pucBuf= 0x%x, prHifRxHdr= 0x%x\n", pucBuf, prHifRxHdr); ++ ++ do { ++ /* Read the RFB DW length and packet length */ ++ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue); ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 20091021 move the line to get the HIF RX header (for RX0/1) */ ++ if (u4RegValue == 0) { ++ DBGLOG(RX, ERROR, "No RX packet\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ u4PktLen = u4RegValue & BITS(0, 15); ++ if (u4PktLen != 0) { ++ rxNum = 0; ++ } else { ++ rxNum = 1; ++ u4PktLen = (u4RegValue & BITS(16, 31)) >> 16; ++ } ++ ++ DBGLOG(RX, TRACE, "RX%d: u4PktLen = %d\n", rxNum, u4PktLen); ++ ++ /* 4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status) */ ++ u4ReadBytes = ALIGN_4(u4PktLen) + 4; ++ HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE); ++ ++ /* 20091021 move the line to get the HIF RX header */ ++ /* u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen; */ ++ if (u4PktLen != (UINT_32) prHifRxHdr->u2PacketLen) { ++ DBGLOG(RX, ERROR, "Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n", ++ u4PktLen, prHifRxHdr->u2PacketLen); ++#if DBG ++ dumpMemory8((PUINT_8) prHifRxHdr, ++ (prHifRxHdr->u2PacketLen > 4096) ? 4096 : prHifRxHdr->u2PacketLen); ++#endif ++ ASSERT(0); ++ } ++ /* u4PktLen is byte unit, not inlude HW appended DW */ ++ ++ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); ++ DBGLOG(RX, TRACE, "ucPacketType = %d\n", prSwRfb->ucPacketType); ++ ++ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ ++ /* fgResult will be updated in MACRO */ ++ if (!fgResult) ++ return WLAN_STATUS_FAILURE; ++ ++ DBGLOG(RX, TRACE, "Dump RX buffer, length = 0x%x\n", u4ReadBytes); ++ DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes); ++ } while (FALSE); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port, fill RFB ++* and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ UINT_32 u4HwAppendDW; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxReceiveRFBs"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (!prSwRfb) { ++ DBGLOG(RX, TRACE, "No More RFB\n"); ++ break; ++ } ++ /* need to consider */ ++ if (nicRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) { ++ DBGLOG(RX, TRACE, "halRxFillRFB failed\n"); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ break; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); ++ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ u4HwAppendDW = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); ++ DBGLOG(RX, TRACE, "u4HwAppendDW = 0x%x\n", u4HwAppendDW); ++ DBGLOG(RX, TRACE, "u2PacketLen = 0x%x\n", prHifRxHdr->u2PacketLen); ++ } while (FALSE); /* while (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW)); */ ++ ++ return; ++ ++} /* end of nicReceiveRFBs() */ ++ ++#else ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port, fill RFB ++* and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param u4DataPort Specify which port to read ++* @param u2RxLength Specify to the the rx packet length in Byte. ++* @param prSwRfb the RFB to receive rx data. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS ++nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucBuf; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_32 u4PktLen = 0; ++ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; ++ BOOLEAN fgResult = TRUE; ++ ++ DEBUGFUNC("nicRxEnhanceReadBuffer"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ pucBuf = prSwRfb->pucRecvBuff; ++ ASSERT(pucBuf); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ /* DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength)); */ ++ ++ do { ++ /* 4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW */ ++ HAL_READ_RX_PORT(prAdapter, ++ u4DataPort, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN), pucBuf, CFG_RX_MAX_PKT_SIZE); ++ ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); ++ break; ++ } ++ ++ u4PktLen = (UINT_32) (prHifRxHdr->u2PacketLen); ++ /* DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen)); */ ++ ++ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); ++ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ ++ ++ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ ++ /* 4 <2> if the RFB dw size or packet size is zero */ ++ if (u4PktLen == 0) { ++ DBGLOG(RX, ERROR, "Packet Length = %u\n", u4PktLen); ++ ASSERT(0); ++ break; ++ } ++ /* 4 <3> if the packet is too large or too small */ ++ if (u4PktLen > CFG_RX_MAX_PKT_SIZE) { ++ DBGLOG(RX, TRACE, "Read RX Packet Lentgh Error (%u)\n", u4PktLen); ++ ASSERT(0); ++ break; ++ } ++ ++ u4Status = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN)); ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port for SDIO ++* I/F, fill RFB and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_SDIO_CTRL_T prSDIOCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ UINT_32 i, rxNum; ++ UINT_16 u2RxPktNum, u2RxLength = 0, u2Tmp = 0; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxSDIOReceiveRFBs"); ++ ++ ASSERT(prAdapter); ++ ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++ ASSERT(prSDIOCtrl); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ for (rxNum = 0; rxNum < 2; rxNum++) { ++ u2RxPktNum = ++ (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len); ++ ++ if (u2RxPktNum == 0) ++ continue; ++ ++ for (i = 0; i < u2RxPktNum; i++) { ++ if (rxNum == 0) { ++ /* HAL_READ_RX_LENGTH */ ++ HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp); ++ } else if (rxNum == 1) { ++ /* HAL_READ_RX_LENGTH */ ++ HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength); ++ } ++ ++ if (!u2RxLength) ++ break; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (!prSwRfb) { ++ DBGLOG(RX, TRACE, "No More RFB\n"); ++ break; ++ } ++ ASSERT(prSwRfb); ++ ++ if (nicRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) { ++ DBGLOG(RX, TRACE, "nicRxEnhanceRxReadBuffer failed\n"); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ break; ++ } ++ /* prSDIOCtrl->au4RxLength[i] = 0; */ ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); ++ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ } ++ } ++ ++ prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0; ++ prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0; ++ ++} /* end of nicRxSDIOReceiveRFBs() */ ++ ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++#if CFG_SDIO_RX_AGG ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port for SDIO with Rx aggregation enabled ++* I/F, fill RFB and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_ENHANCE_MODE_DATA_STRUCT_T prEnhDataStr; ++ P_RX_CTRL_T prRxCtrl; ++ P_SDIO_CTRL_T prSDIOCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ UINT_32 u4RxLength; ++ UINT_32 i, rxNum; ++ UINT_32 u4RxAggCount = 0, u4RxAggLength = 0; ++ UINT_32 u4RxAvailAggLen, u4CurrAvailFreeRfbCnt; ++ PUINT_8 pucSrcAddr; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ BOOLEAN fgResult = TRUE; ++ BOOLEAN fgIsRxEnhanceMode; ++ UINT_16 u2RxPktNum; ++#if CFG_SDIO_RX_ENHANCE ++ UINT_32 u4MaxLoopCount = CFG_MAX_RX_ENHANCE_LOOP_COUNT; ++#endif ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxSDIOAggReceiveRFBs"); ++ ++ ASSERT(prAdapter); ++ prEnhDataStr = prAdapter->prSDIOCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++ ++#if CFG_SDIO_RX_ENHANCE ++ fgIsRxEnhanceMode = TRUE; ++#else ++ fgIsRxEnhanceMode = FALSE; ++#endif ++ ++ do { ++#if CFG_SDIO_RX_ENHANCE ++ /* to limit maximum loop for RX */ ++ u4MaxLoopCount--; ++ if (u4MaxLoopCount == 0) ++ break; ++#endif ++ ++ if (prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0) ++ break; ++ ++ for (rxNum = 0; rxNum < 2; rxNum++) { ++ u2RxPktNum = ++ (rxNum == ++ 0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : prEnhDataStr->rRxInfo.u.u2NumValidRx1Len); ++ ++ /* if this assertion happened, it is most likely a F/W bug */ ++ ASSERT(u2RxPktNum <= 16); ++ ++ if (u2RxPktNum > 16) ++ continue; ++ ++ if (u2RxPktNum == 0) ++ continue; ++ ++#if CFG_HIF_STATISTICS ++ prRxCtrl->u4TotalRxAccessNum++; ++ prRxCtrl->u4TotalRxPacketNum += u2RxPktNum; ++#endif ++ ++ u4CurrAvailFreeRfbCnt = prRxCtrl->rFreeSwRfbList.u4NumElem; ++ ++ /* if SwRfb is not enough, abort reading this time */ ++ if (u4CurrAvailFreeRfbCnt < u2RxPktNum) { ++#if CFG_HIF_RX_STARVATION_WARNING ++ DbgPrint("FreeRfb is not enough: %d available, need %d\n", u4CurrAvailFreeRfbCnt, ++ u2RxPktNum); ++ DbgPrint("Queued Count: %d / Dequeud Count: %d\n", prRxCtrl->u4QueuedCnt, ++ prRxCtrl->u4DequeuedCnt); ++#endif ++ continue; ++ } ++#if CFG_SDIO_RX_ENHANCE ++ u4RxAvailAggLen = ++ CFG_RX_COALESCING_BUFFER_SIZE - (sizeof(ENHANCE_MODE_DATA_STRUCT_T) + ++ 4 /* extra HW padding */); ++#else ++ u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE; ++#endif ++ u4RxAggCount = 0; ++ ++ for (i = 0; i < u2RxPktNum; i++) { ++ u4RxLength = (rxNum == 0 ? ++ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : ++ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); ++ ++ if (!u4RxLength) { ++ ASSERT(0); ++ break; ++ } ++ ++ if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) { ++ if (u4RxAggCount < u4CurrAvailFreeRfbCnt) { ++ u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN); ++ u4RxAggCount++; ++ } else { ++ /* no FreeSwRfb for rx packet */ ++ ASSERT(0); ++ break; ++ } ++ } else { ++ /* CFG_RX_COALESCING_BUFFER_SIZE is not large enough */ ++ ASSERT(0); ++ break; ++ } ++ } ++ ++ u4RxAggLength = (CFG_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen); ++ /* DBGLOG(RX, INFO, ("u4RxAggCount = %d, u4RxAggLength = %d\n", */ ++ /* u4RxAggCount, u4RxAggLength)); */ ++ ++ HAL_READ_RX_PORT(prAdapter, ++ rxNum, ++ u4RxAggLength, prRxCtrl->pucRxCoalescingBufPtr, CFG_RX_COALESCING_BUFFER_SIZE); ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read RX Agg Packet Error\n"); ++ continue; ++ } ++ ++ pucSrcAddr = prRxCtrl->pucRxCoalescingBufPtr; ++ for (i = 0; i < u4RxAggCount; i++) { ++ UINT_16 u2PktLength; ++ ++ u2PktLength = (rxNum == 0 ? ++ prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : ++ prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ ASSERT(prSwRfb); ++ kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr, ++ ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN)); ++ ++ /* record the rx time */ ++ STATS_RX_ARRIVE_TIME_RECORD(prSwRfb); /* ms */ ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ prSwRfb->ucPacketType = ++ (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); ++ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ ++ ++ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); ++ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN); ++ /* prEnhDataStr->au4RxLength[i] = 0; */ ++ } ++ ++#if CFG_SDIO_RX_ENHANCE ++ kalMemCopy(prAdapter->prSDIOCtrl, (pucSrcAddr + 4), sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ ++ /* do the same thing what nicSDIOReadIntStatus() does */ ++ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && ++ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { ++ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; ++ } ++ ++ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && ++ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && ++ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { ++ prSDIOCtrl->u4WHISR |= BIT(31); ++ } ++ ++ /* dispatch to interrupt handler with RX bits masked */ ++ nicProcessIST_impl(prAdapter, ++ prSDIOCtrl->u4WHISR & (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT))); ++#endif ++ } ++ ++#if !CFG_SDIO_RX_ENHANCE ++ prEnhDataStr->rRxInfo.u.u2NumValidRx0Len = 0; ++ prEnhDataStr->rRxInfo.u.u2NumValidRx1Len = 0; ++#endif ++ } while ((prEnhDataStr->rRxInfo.u.u2NumValidRx0Len || prEnhDataStr->rRxInfo.u.u2NumValidRx1Len) ++ && fgIsRxEnhanceMode); ++ ++} ++#endif /* CFG_SDIO_RX_AGG */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Setup a RFB and allocate the os packet to the RFB ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prSwRfb Pointer to the RFB ++* ++* @retval WLAN_STATUS_SUCCESS ++* @retval WLAN_STATUS_RESOURCES ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ PVOID pvPacket; ++ PUINT_8 pucRecvBuff; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (!prSwRfb->pvPacket) { ++ kalMemZero(prSwRfb, sizeof(SW_RFB_T)); ++ pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, CFG_RX_MAX_PKT_SIZE, &pucRecvBuff); ++ if (pvPacket == NULL) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSwRfb->pvPacket = pvPacket; ++ prSwRfb->pucRecvBuff = (PVOID) pucRecvBuff; ++ } else { ++ kalMemZero(((PUINT_8) prSwRfb + OFFSET_OF(SW_RFB_T, prHifRxHdr)), ++ (sizeof(SW_RFB_T) - OFFSET_OF(SW_RFB_T, prHifRxHdr))); ++ } ++ ++ prSwRfb->prHifRxHdr = (P_HIF_RX_HEADER_T) (prSwRfb->pucRecvBuff); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of nicRxSetupRFB() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is called to put a RFB back onto the "RFB with Buffer" list ++* or "RFB without buffer" list according to pvPacket. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prSwRfb Pointer to the RFB ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_QUE_ENTRY_T prQueEntry; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ prQueEntry = &prSwRfb->rQueEntry; ++ ++ ASSERT(prQueEntry); ++ ++ /* The processing on this RFB is done, so put it back on the tail of ++ our list */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (prSwRfb->pvPacket) { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry); ++ } else { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry); ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++} /* end of nicRxReturnRFB() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process rx interrupt. When the rx ++* Interrupt is asserted, it means there are frames in queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ prGlueInfo->IsrRxCnt++; ++#if CFG_SDIO_INTR_ENHANCE ++#if CFG_SDIO_RX_AGG ++ nicRxSDIOAggReceiveRFBs(prAdapter); ++#else ++ nicRxSDIOReceiveRFBs(prAdapter); ++#endif ++#else ++ nicRxReceiveRFBs(prAdapter); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ nicRxProcessRFBs(prAdapter); ++ ++ return; ++ ++} /* end of nicProcessRxInterrupt() */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Used to update IP/TCP/UDP checksum statistics of RX Module. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param aeCSUM The array of checksum result. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(aeCSUM); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) || ++ (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT); ++ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT); ++ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT); ++ } else { ++ ASSERT(0); ++ } ++ ++ if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) { ++ /* count success num */ ++ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT); ++ } else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT); ++ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT); ++ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT); ++ } else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT); ++ } else { ++ ASSERT(0); ++ } ++ ++} /* end of nicRxUpdateCSUMStatistics() */ ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to query current status of RX Module. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param pucBuffer Pointer to the message buffer. ++* @param pu4Count Pointer to the buffer of message length count. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucCurrBuf = pucBuffer; ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ ++ ASSERT(pu4Count); ++ ++ SPRINTF(pucCurrBuf, ("\n\nRX CTRL STATUS:")); ++ SPRINTF(pucCurrBuf, ("\n===============")); ++ SPRINTF(pucCurrBuf, ("\nFREE RFB w/i BUF LIST :%9u", prRxCtrl->rFreeSwRfbList.u4NumElem)); ++ SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9u", prRxCtrl->rIndicatedRfbList.u4NumElem)); ++ SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST :%9u", prRxCtrl->rReceivedRfbList.u4NumElem)); ++ ++ SPRINTF(pucCurrBuf, ("\n\n")); ++ ++ /* *pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); */ ++ ++} /* end of nicRxQueryStatus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Clear RX related counters ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return - (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ RX_RESET_ALL_CNTS(prRxCtrl); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to query current statistics of RX Module. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param pucBuffer Pointer to the message buffer. ++* @param pu4Count Pointer to the buffer of message length count. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucCurrBuf = pucBuffer; ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ ++ ASSERT(pu4Count); ++ ++#define SPRINTF_RX_COUNTER(eCounter) \ ++ SPRINTF(pucCurrBuf, ("%-30s : %u\n", #eCounter, (UINT_32)prRxCtrl->au8Statistics[eCounter])) ++ ++ SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT); ++ SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT); ++ SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT); ++ SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT); ++ SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++ SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT); ++ SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT); ++#endif ++ ++ /* *pu4Count = (UINT_32)(pucCurrBuf - pucBuffer); */ ++ ++ nicRxClearStatistics(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read the Response data from data port ++* ++* @param prAdapter pointer to the Adapter handler ++* @param pucRspBuffer pointer to the Response buffer ++* ++* @retval WLAN_STATUS_SUCCESS: Response packet has been read ++* @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicRxWaitResponse(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length) ++{ ++ UINT_32 u4Value = 0, u4PktLen = 0; ++ UINT_32 i = 0; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgResult = TRUE; ++ UINT_32 u4Time, u4Current; ++ ++ DEBUGFUNC("nicRxWaitResponse"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pucRspBuffer); ++ ASSERT(ucPortIdx < 2); ++ ++ u4Time = kalGetTimeTick(); ++ ++ do { ++ /* Read the packet length */ ++ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value); ++ ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ if (ucPortIdx == 0) ++ u4PktLen = u4Value & 0xFFFF; ++ else ++ u4PktLen = (u4Value >> 16) & 0xFFFF; ++ ++/* DBGLOG(RX, TRACE, ("i = %d, u4PktLen = %d\n", i, u4PktLen)); */ ++ ++ if (u4PktLen == 0) { ++ /* timeout exceeding check */ ++ u4Current = kalGetTimeTick(); ++ ++ if ((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) { ++ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT1 %u %d %u\n", u4PktLen, i, u4Current); ++ return WLAN_STATUS_FAILURE; ++ } else if (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) { ++ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT2 %u %d %u\n", u4PktLen, i, u4Current); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Response packet is not ready */ ++ kalUdelay(50); ++ ++ i++; ++ continue; ++ } ++ if (u4PktLen > u4MaxRespBufferLen) { ++ /* ++ TO: buffer is not enough but we still need to read all data from HIF to avoid ++ HIF crazy. ++ */ ++ DBGLOG(RX, ERROR, ++ "Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n", ++ u4PktLen, u4MaxRespBufferLen); ++ DBGLOG(RX, ERROR, "i = %d, u4PktLen = %u\n", i, u4PktLen); ++ return WLAN_STATUS_FAILURE; ++ } ++ HAL_PORT_RD(prAdapter, ++ ucPortIdx == 0 ? MCR_WRDR0 : MCR_WRDR1, u4PktLen, pucRspBuffer, u4MaxRespBufferLen); ++ ++ /* fgResult will be updated in MACRO */ ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ DBGLOG(RX, TRACE, "Dump Response buffer, length = 0x%x\n", u4PktLen); ++ DBGLOG_MEM8(RX, TRACE, pucRspBuffer, u4PktLen); ++ ++ *pu4Length = u4PktLen; ++ break; ++ } while (TRUE); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Set filter to enable Promiscuous Mode ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++} /* end of nicRxEnablePromiscuousMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Set filter to disable Promiscuous Mode ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++} /* end of nicRxDisablePromiscuousMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function flushes all packets queued in reordering module ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Flushed successfully ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter) ++{ ++ P_SW_RFB_T prSwRfb; ++ ++ ASSERT(prAdapter); ++ ++ prSwRfb = qmFlushRxQueues(prAdapter); ++ if (prSwRfb != NULL) { ++ do { ++ P_SW_RFB_T prNextSwRfb; ++ ++ /* save next first */ ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); ++ ++ /* free */ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++ prSwRfb = prNextSwRfb; ++ } while (prSwRfb); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param ++* ++* @retval ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_ACTION_FRAME prActFrame; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (prSwRfb->u2PacketLen < sizeof(WLAN_ACTION_FRAME) - 1) ++ return WLAN_STATUS_INVALID_PACKET; ++ prActFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; ++ DBGLOG(RX, INFO, "Category %u\n", prActFrame->ucCategory); ++ ++ switch (prActFrame->ucCategory) { ++ case CATEGORY_PUBLIC_ACTION: ++ if (HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) ++ aisFuncValidateRxActionFrame(prAdapter, prSwRfb); ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered) { ++ rlmProcessPublicAction(prAdapter, prSwRfb); ++ ++ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); ++ ++ } ++#endif ++ break; ++ ++ case CATEGORY_HT_ACTION: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ rlmProcessHtAction(prAdapter, prSwRfb); ++#endif ++ break; ++ case CATEGORY_VENDOR_SPECIFIC_ACTION: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); ++#endif ++ break; ++#if CFG_SUPPORT_802_11W ++ case CATEGORY_SA_QUERT_ACTION: ++ { ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ++ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) ++ && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { ++ if (!(prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC)) { ++ /* MFP test plan 5.3.3.4 */ ++ rsnSaQueryAction(prAdapter, prSwRfb); ++ } else { ++ DBGLOG(RSN, TRACE, "Un-Protected SA Query, do nothing\n"); ++ } ++ } ++ } ++ break; ++#endif ++#if CFG_SUPPORT_802_11V ++ case CATEGORY_WNM_ACTION: ++ { ++ wnmWNMAction(prAdapter, prSwRfb); ++ } ++ break; ++#endif ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++ case CATEGORY_SPEC_MGT: ++ { ++ if (prAdapter->fgEnable5GBand == TRUE) ++ rlmProcessSpecMgtAction(prAdapter, prSwRfb); ++ } ++ break; ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ case 12: /* shall not be here */ ++ /* ++ A received TDLS Action frame with the Type field set to Management shall ++ be discarded. Note that the TDLS Discovery Response frame is not a TDLS ++ frame but a Public Action frame. ++ */ ++ break; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ default: ++ break; ++ } /* end of switch case */ ++ ++ return WLAN_STATUS_SUCCESS; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c +new file mode 100644 +index 000000000000..024bd9507603 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c +@@ -0,0 +1,2350 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#1 ++*/ ++ ++/*! \file nic_tx.c ++ \brief Functions that provide TX operation in NIC Layer. ++ ++ This file provides TX functions which are responsible for both Hardware and ++ Software Resource Management and keep their Synchronization. ++*/ ++ ++/* ++** Log: nic_tx.c ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 11 18 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add log counter for tx ++ * ++ * 11 09 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog for beacon timeout and sta aging timeout. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 05 17 2011 cp.wu ++ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss ++ * disconnection ++ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame ++ * dropping cases for TC4 path ++ * remove unused variables. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame ++ * dropping cases for TC4 path ++ * 1. add nicTxGetResource() API for QM to make decisions. ++ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 02 16 2011 cp.wu ++ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count ++ * and modify behavior ++ * 1. add new API: nicTxGetFreeCmdCount() ++ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation ++ * needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system ++ * scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add GPIO debug function ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 27 2010 wh.su ++ * NULL ++ * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra ++ * bytes padding. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * API added: nicTxPendingPackets(), for simplifying porting layer ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 20 2010 wh.su ++ * NULL ++ * adding the eapol callback setting. ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * . ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * simplify post-handling after TX_DONE interrupt is handled. ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network ++ * operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add checking for TX descriptor poll. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * TX descriptors are now allocated once for reducing allocation overhead ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change zero-padding for TX port access to HAL. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill extra information for revised HIF_TX_HEADER. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change to enqueue TX frame infinitely. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add TX_PACKET_MGMT to indicate the frame is coming from management modules ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * fill network type field while doing frame identification. ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Tag the packet for QoS on Tx path ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * * * * ++ * ++* 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 02 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * avoid referring to NDIS-specific data structure directly from non-glue layer. ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add Ethernet destination address information in packet info for TX ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * * * * 4) nicRxWaitResponse() revised ++ * * * * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * * * * 4. correct some HAL implementation ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++ * ++ * 01 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752 ++** remove unused API ++** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752 ++** correct assertion criterion ++** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752 ++** correct trivial mistake ++** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752 ++** + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data ++** + add more assertion for packet size check ++** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752 ++** nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort ++** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752 ++** add 2 assertion for size check ++** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461 ++** Add debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752 ++** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752 ++** use TC4 instead of TC5 for command packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752 ++** fill prMsduInfo->ucUserPriority ++** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752 ++** fill u2SeqNo ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752 ++** integration with SD1's data path API ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752 ++** nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752 ++** add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum, ++** WIFI_CMD_T will be created inside oid handler ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752 ++** use TxAccquireResource instead of accessing TCQ directly. ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752 ++** add nicTxMsduInfoList () implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752 ++** add nicTxAdjustTcq() implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752 ++** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752 ++** add SD1_SD3_DATAPATH_INTEGRATION data path handling ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084 ++** modify TX hdr format, fix tx retransmission issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084 ++** modify TX SW data structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084 ++** modify HAL part ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461 ++** Assign SeqNum to CMD Packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461 ++** Add debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461 ++** Fix Query Command need resp issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461 ++** Move OS dependent code to kalQueryTxOOBData() ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461 ++** Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461 ++** Update nicTxCmd() for moving wait RESP function call to wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461 ++** Move the CMD_INFO_T related function to cmd_buf.c ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426 ++** Update OOB query for TX packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426 ++** Support PKGUIO ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461 ++** Add virtual OOB for HIF LOOPBACK SW PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461 ++** Add function for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461 ++** Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test. ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461 ++** Add code for TX Data & Cmd Packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461 ++** Fix LINT warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will initial all variables in regard to SW TX Queues and ++* all free lists of MSDU_INFO_T and SW_TFCB_T. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ PUINT_8 pucMemHandle; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_32 i; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicTxInitialize"); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* 4 <1> Initialization of Traffic Class Queue Parameters */ ++ nicTxResetResource(prAdapter); ++ ++#if CFG_SDIO_TX_AGG ++ prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; ++#endif /* CFG_SDIO_TX_AGG */ ++ ++ /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */ ++ QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList); ++ ++ pucMemHandle = prTxCtrl->pucTxCached; ++ for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) { ++ prMsduInfo = (P_MSDU_INFO_T) pucMemHandle; ++ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T)); ++ } ++ ++ ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM); ++ /* Check if the memory allocation consist with this initialization function */ ++ ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize); ++ ++ QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue); ++ prTxCtrl->i4TxMgmtPendingNum = 0; ++ ++#if CFG_HIF_STATISTICS ++ prTxCtrl->u4TotalTxAccessNum = 0; ++ prTxCtrl->u4TotalTxPacketNum = 0; ++#endif ++ ++ prTxCtrl->i4PendingFwdFrameCount = 0; ++ ++ qmInit(prAdapter); ++ ++ TX_RESET_ALL_CNTS(prTxCtrl); ++ ++} /* end of nicTxInitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will check if has enough TC Buffer for incoming ++* packet and then update the value after promise to provide the resources. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucTC Specify the resource of TC ++* ++* \retval WLAN_STATUS_SUCCESS Resource is available and been assigned. ++* \retval WLAN_STATUS_RESOURCES Resource is not available. ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 u4CurrTick = 0; ++WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt) ++{ ++#define TC4_NO_RESOURCE_DELAY_MS 5 /* exponential of 5s */ ++ ++ P_TX_CTRL_T prTxCtrl; ++ WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES; ++ P_QUE_MGT_T prQM; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ prQM = &prAdapter->rQM; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++/* DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n", ++ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); */ ++ do { ++ if (pfgIsSecOrMgmt && (ucTC == TC4_INDEX)) { ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] < 2) { ++ DBGLOG(TX, EVENT, " aucFreeBufferCount = %d\n", ++ prTxCtrl->rTc.aucFreeBufferCount[ucTC]); ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) ++ u4CurrTick = 0; ++ ++ break; ++ } ++ } ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) { ++ ++ if (ucTC == TC4_INDEX) ++ u4CurrTick = 0; ++ /* get a available TX entry */ ++ prTxCtrl->rTc.aucFreeBufferCount[ucTC]--; ++ ++ prQM->au4ResourceUsedCounter[ucTC]++; ++ ++ DBGLOG(TX, EVENT, "Acquire: TC = %d aucFreeBufferCount = %d\n", ++ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); ++ ++ u4Status = WLAN_STATUS_SUCCESS; ++ } ++ } while (FALSE); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ if (ucTC == TC4_INDEX) { ++ if (u4CurrTick == 0) ++ u4CurrTick = kalGetTimeTick(); ++ if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick, ++ SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) { ++ wlanDumpTcResAndTxedCmd(NULL, 0); ++ cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, "waiting response CMD queue"); ++ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); ++ kalSendAeeWarning("[TC4 no resource delay 5s!]", __func__); ++ glDoChipReset(); ++ u4CurrTick = 0; ++ } ++ } ++ return u4Status; ++ ++} /* end of nicTxAcquireResourceAndTFCBs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will do polling if FW has return the resource. ++* Used when driver start up before enable interrupt. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param ucTC Specify the resource of TC ++* ++* @retval WLAN_STATUS_SUCCESS Resource is available. ++* @retval WLAN_STATUS_FAILURE Resource is not available. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; ++ INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT; ++ UINT_32 au4WTSR[2]; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ if (ucTC >= TC_NUM) ++ return WLAN_STATUS_FAILURE; ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) ++ return WLAN_STATUS_SUCCESS; ++ ++ while (i-- > 0) { ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR); ++ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } else if (nicTxReleaseResource(prAdapter, (PUINT_8) au4WTSR)) { ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) { ++ u4Status = WLAN_STATUS_SUCCESS; ++ break; ++ } ++ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); ++ ++ } else { ++ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); ++ } ++ } ++ ++ if (i <= 0 && ucTC == TC4_INDEX) { ++ DBGLOG(TX, ERROR, "polling Tx resource for Tc4 timeout\n"); ++ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); ++ } ++#if DBG ++ { ++ INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1); ++ ++ if (i4Times) { ++ DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %d times, %d msec\n", ++ i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC)); ++ } ++ } ++#endif /* DBG */ ++ ++ return u4Status; ++ ++} /* end of nicTxPollingResource() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will release TC Buffer count according to ++* the given TX_STATUS COUNTER after TX Done. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] u4TxStatusCnt Value of TX STATUS ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN unsigned char *aucTxRlsCnt) ++{ ++ PUINT_32 pu4Tmp = (PUINT_32) aucTxRlsCnt; ++ P_TX_CTRL_T prTxCtrl; ++ BOOLEAN bStatus = FALSE; ++ UINT_32 i; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ if (pu4Tmp[0] | pu4Tmp[1]) { ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ for (i = 0; i < TC_NUM; i++) ++ prTxCtrl->rTc.aucFreeBufferCount[i] += aucTxRlsCnt[i]; ++ for (i = 0; i < TC_NUM; i++) ++ prQM->au4QmTcResourceBackCounter[i] += aucTxRlsCnt[i]; ++ if (aucTxRlsCnt[TC4_INDEX] != 0) ++ wlanTraceReleaseTcRes(prAdapter, aucTxRlsCnt, prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX]); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++#if 0 ++ for (i = 0; i < TC_NUM; i++) { ++ DBGLOG(TX, TRACE, "aucFreeBufferCount[%d]: %d, aucMaxNumOfBuffer[%d]: %d\n", ++ i, prTxCtrl->rTc.aucFreeBufferCount[i], i, ++ prTxCtrl->rTc.aucMaxNumOfBuffer[i]); ++ } ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[0]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[0]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[1]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[1]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[2]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[2]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[3]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[3]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[4]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[4]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[5]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[5]); ++#endif ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX]); ++ bStatus = TRUE; ++ } ++ ++ return bStatus; ++} /* end of nicTxReleaseResource() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Reset TC Buffer Count to initialized value ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicTxResetResource"); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; ++ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; ++ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; ++ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; ++ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; ++ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; ++ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will return the value for other component ++* which needs this information for making decisions ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param ucTC Specify the resource of TC ++* ++* @retval UINT_8 The number of corresponding TC number ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ ASSERT(prTxCtrl); ++ ++ if (ucTC >= TC_NUM) ++ return 0; ++ else ++ return prTxCtrl->rTc.aucFreeBufferCount[ucTC]; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief In this function, we'll aggregate frame(PACKET_INFO_T) ++* corresponding to HIF TX port ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfoListHead a link list of P_MSDU_INFO_T ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; ++ QUE_T qDataPort0, qDataPort1; ++ WLAN_STATUS status; ++ BOOLEAN pfgIsSecOrMgmt = FALSE; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfoListHead); ++ ++ prMsduInfo = prMsduInfoListHead; ++ ++ QUEUE_INITIALIZE(&qDataPort0); ++ QUEUE_INITIALIZE(&qDataPort1); ++ ++ /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++#if DBG && 0 ++ LOG_FUNC("nicTxMsduInfoList Acquire TC %d net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prMsduInfo->ucTC, ++ prMsduInfo->ucNetworkType, ++ prMsduInfo->ucMacHeaderLength, ++ prMsduInfo->u2FrameLength, ++ prMsduInfo->ucPacketType, prMsduInfo->fgIs802_1x, prMsduInfo->fgIs802_11); ++ ++ LOG_FUNC("Dest Mac: %pM\n", prMsduInfo->aucEthDestAddr); ++#endif ++ ++ /* double-check available TX resouce (need to sync with CONNSYS FW) */ ++ /* caller must guarantee that the TX resource is enough in the func; OR assert here */ ++ switch (prMsduInfo->ucTC) { ++ case TC0_INDEX: ++ case TC1_INDEX: ++ case TC2_INDEX: ++ case TC3_INDEX: ++ case TC5_INDEX: /* Broadcast/multicast data packets */ ++ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; ++ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); ++ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, FALSE); ++ ASSERT(status == WLAN_STATUS_SUCCESS) ++ ++ break; ++ ++ case TC4_INDEX: /* Command or 802.1x packets */ ++ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; ++ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); ++ ++ if ((prMsduInfo->fgIs802_1x == TRUE) || ++ (prMsduInfo->fgIs802_11 == TRUE)) ++ pfgIsSecOrMgmt = TRUE; ++ ++ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, pfgIsSecOrMgmt); ++ ASSERT(status == WLAN_STATUS_SUCCESS) ++ ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ } ++ ++ /* send packets to HIF port0 or port1 here */ ++ if (qDataPort0.u4NumElem > 0) ++ nicTxMsduQueue(prAdapter, 0, &qDataPort0); ++ ++ if (qDataPort1.u4NumElem > 0) ++ nicTxMsduQueue(prAdapter, 1, &qDataPort1); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ ++#if CFG_PRINT_RTP_PROFILE ++PKT_PROFILE_T rPrevRoundLastPkt; ++ ++BOOLEAN ++nicTxLifetimePrintCheckRTP(IN P_MSDU_INFO_T prPrevProfileMsduInfo, ++ IN P_PKT_PROFILE_T prPrevRoundLastPkt, ++ IN P_PKT_PROFILE_T prPktProfile, ++ IN OUT PBOOLEAN pfgGotFirst, IN UINT_32 u4MaxDeltaTime, IN UINT_8 ucSnToBePrinted) ++{ ++ BOOLEAN fgPrintCurPkt = FALSE; ++ ++ if (u4MaxDeltaTime) { ++ /* 4 1. check delta between current round first pkt and prevous round last pkt */ ++ if (!*pfgGotFirst) { ++ *pfgGotFirst = TRUE; ++ ++ if (prPrevRoundLastPkt->fgIsValid) { ++ if (CHK_PROFILES_DELTA(prPktProfile, prPrevRoundLastPkt, u4MaxDeltaTime)) { ++ PRINT_PKT_PROFILE(prPrevRoundLastPkt, "PR"); ++ fgPrintCurPkt = TRUE; ++ } ++ } ++ } ++ /* 4 2. check delta between current pkt and previous pkt */ ++ if (prPrevProfileMsduInfo) { ++ if (CHK_PROFILES_DELTA(prPktProfile, &prPrevProfileMsduInfo->rPktProfile, u4MaxDeltaTime)) { ++ PRINT_PKT_PROFILE(&prPrevProfileMsduInfo->rPktProfile, "P"); ++ fgPrintCurPkt = TRUE; ++ } ++ } ++ /* 4 3. check delta of current pkt lifetime */ ++ if (CHK_PROFILE_DELTA(prPktProfile, u4MaxDeltaTime)) ++ fgPrintCurPkt = TRUE; ++ } ++ /* 4 4. print every X RTP packets */ ++#if CFG_SUPPORT_WFD ++ if ((ucSnToBePrinted != 0) && (prPktProfile->u2RtpSn % ucSnToBePrinted) == 0) ++ fgPrintCurPkt = TRUE; ++#endif ++ ++ return fgPrintCurPkt; ++} ++ ++BOOLEAN ++nicTxLifetimePrintCheckSnOrder(IN P_MSDU_INFO_T prPrevProfileMsduInfo, ++ IN P_PKT_PROFILE_T prPrevRoundLastPkt, ++ IN P_PKT_PROFILE_T prPktProfile, IN OUT PBOOLEAN pfgGotFirst, IN UINT_8 ucLayer) ++{ ++ BOOLEAN fgPrintCurPkt = FALSE; ++ P_PKT_PROFILE_T prTarPktProfile = NULL; ++ UINT_16 u2PredictSn = 0; ++ UINT_16 u2CurrentSn = 0; ++ UINT_8 aucNote[8]; ++ ++ /* 4 1. Get the target packet profile to compare */ ++ ++ /* 4 1.1 check SN between current round first pkt and prevous round last pkt */ ++ if ((!*pfgGotFirst) && (prPrevRoundLastPkt->fgIsValid)) { ++ *pfgGotFirst = TRUE; ++ prTarPktProfile = prPrevRoundLastPkt; ++ kalMemCopy(aucNote, "PR\0", 3); ++ } ++ /* 4 1.2 check SN between current pkt and previous pkt */ ++ else if (prPrevProfileMsduInfo) { ++ prTarPktProfile = &prPrevProfileMsduInfo->rPktProfile; ++ kalMemCopy(aucNote, "P\0", 2); ++ } ++ ++ if (!prTarPktProfile) ++ return FALSE; ++ /* 4 2. Check IP or RTP SN */ ++ switch (ucLayer) { ++ /* Check IP SN */ ++ case 0: ++ u2PredictSn = prTarPktProfile->u2IpSn + 1; ++ u2CurrentSn = prPktProfile->u2IpSn; ++ break; ++ /* Check RTP SN */ ++ case 1: ++ default: ++ u2PredictSn = prTarPktProfile->u2RtpSn + 1; ++ u2CurrentSn = prPktProfile->u2RtpSn; ++ break; ++ ++ } ++ /* 4 */ ++ /* 4 3. Compare SN */ ++ if (u2CurrentSn != u2PredictSn) { ++ PRINT_PKT_PROFILE(prTarPktProfile, aucNote); ++ fgPrintCurPkt = TRUE; ++ } ++ ++ return fgPrintCurPkt; ++} ++#endif ++ ++VOID nicTxReturnMsduInfoProfiling(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; ++ P_PKT_PROFILE_T prPktProfile; ++ UINT_16 u2MagicCode = 0; ++ ++ UINT_8 ucDebugtMode = 0; ++#if CFG_PRINT_RTP_PROFILE ++ P_MSDU_INFO_T prPrevProfileMsduInfo = NULL; ++ P_PKT_PROFILE_T prPrevRoundLastPkt = &rPrevRoundLastPkt; ++ ++ BOOLEAN fgPrintCurPkt = FALSE; ++ BOOLEAN fgGotFirst = FALSE; ++ UINT_8 ucSnToBePrinted = 0; ++ ++ UINT_32 u4MaxDeltaTime = 50; /* in ms */ ++#endif ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ UINT_32 u4PktPrintPeriod = 0; ++#endif ++ ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ if (prAdapter->fgIsP2PRegistered) { ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ u2MagicCode = prWfdCfgSettings->u2WfdMaximumTp; ++ ucDebugtMode = prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode; ++ /* if(prWfdCfgSettings->ucWfdEnable && (prWfdCfgSettings->u4WfdFlag & BIT(0))) { */ ++ /* u2MagicCode = 0xE040; */ ++ /* } */ ++ } ++#endif ++ ++#if CFG_PRINT_RTP_PROFILE ++ if ((u2MagicCode >= 0xF000)) { ++ ucSnToBePrinted = (UINT_8) (u2MagicCode & BITS(0, 7)); ++ u4MaxDeltaTime = (UINT_8) (((u2MagicCode & BITS(8, 11)) >> 8) * 10); ++ } else { ++ ucSnToBePrinted = 0; ++ u4MaxDeltaTime = 0; ++ } ++ ++#endif ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ if ((u2MagicCode >= 0xE000) && (u2MagicCode < 0xF000)) ++ u4PktPrintPeriod = (UINT_32) ((u2MagicCode & BITS(0, 7)) * 32); ++ else ++ u4PktPrintPeriod = 0; ++#endif ++ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ prPktProfile = &prMsduInfo->rPktProfile; ++ ++ if (prPktProfile->fgIsValid) { ++ ++ prPktProfile->rHifTxDoneTimestamp = kalGetTimeTick(); ++ if (ucDebugtMode > 1) { ++ ++#if CFG_PRINT_RTP_PROFILE ++#if CFG_PRINT_RTP_SN_SKIP ++ fgPrintCurPkt = nicTxLifetimePrintCheckSnOrder(prPrevProfileMsduInfo, ++ prPrevRoundLastPkt, ++ prPktProfile, &fgGotFirst, 0); ++#else ++ fgPrintCurPkt = nicTxLifetimePrintCheckRTP(prPrevProfileMsduInfo, ++ prPrevRoundLastPkt, ++ prPktProfile, ++ &fgGotFirst, ++ u4MaxDeltaTime, ucSnToBePrinted); ++#endif ++ ++ /* Print current pkt profile */ ++ if (fgPrintCurPkt && ucDebugtMode > 1) ++ PRINT_PKT_PROFILE(prPktProfile, "C"); ++ ++ prPrevProfileMsduInfo = prMsduInfo; ++ fgPrintCurPkt = FALSE; ++#endif ++ } ++#if CFG_ENABLE_PER_STA_STATISTICS ++ { ++ P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ UINT_32 u4DeltaTime; ++ UINT_32 u4DeltaHifTime; ++#if 0 ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++#endif ++ UINT_8 ucNetIndex; ++ ++ if (prStaRec) { ++ ucNetIndex = prStaRec->ucNetTypeIndex; ++ u4DeltaTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - ++ prPktProfile->rHardXmitArrivalTimestamp); ++ u4DeltaHifTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - ++ prPktProfile->rDequeueTimestamp); ++ prStaRec->u4TotalTxPktsNumber++; ++ ++ prStaRec->u4TotalTxPktsTime += u4DeltaTime; ++ prStaRec->u4TotalTxPktsHifTime += u4DeltaHifTime; ++ ++ if (u4DeltaTime > prStaRec->u4MaxTxPktsTime) ++ prStaRec->u4MaxTxPktsTime = u4DeltaTime; ++ ++ if (u4DeltaHifTime > prStaRec->u4MaxTxPktsHifTime) ++ prStaRec->u4MaxTxPktsHifTime = u4DeltaHifTime; ++ ++ ++ if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD) ++ prStaRec->u4ThresholdCounter++; ++#if 0 ++ if (u4PktPrintPeriod && (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) { ++ ++ DBGLOG(TX, TRACE, "[%u]N[%4u]A[%5u]M[%4u]T[%4u]E[%4u]\n", ++ prStaRec->ucIndex, ++ prStaRec->u4TotalTxPktsNumber, ++ prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber, ++ prStaRec->u4MaxTxPktsTime, ++ prStaRec->u4ThresholdCounter, ++ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX]); ++ ++ prStaRec->u4TotalTxPktsNumber = 0; ++ prStaRec->u4TotalTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsTime = 0; ++ prStaRec->u4ThresholdCounter = 0; ++ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX] = 0; ++ } ++#endif ++ } ++ ++ } ++#endif ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ }; ++ ++#if CFG_PRINT_RTP_PROFILE ++ /* 4 4. record the lifetime of current round last pkt */ ++ if (prPrevProfileMsduInfo) { ++ prPktProfile = &prPrevProfileMsduInfo->rPktProfile; ++ prPrevRoundLastPkt->u2IpSn = prPktProfile->u2IpSn; ++ prPrevRoundLastPkt->u2RtpSn = prPktProfile->u2RtpSn; ++ prPrevRoundLastPkt->rHardXmitArrivalTimestamp = prPktProfile->rHardXmitArrivalTimestamp; ++ prPrevRoundLastPkt->rEnqueueTimestamp = prPktProfile->rEnqueueTimestamp; ++ prPrevRoundLastPkt->rDequeueTimestamp = prPktProfile->rDequeueTimestamp; ++ prPrevRoundLastPkt->rHifTxDoneTimestamp = prPktProfile->rHifTxDoneTimestamp; ++ prPrevRoundLastPkt->ucTcxFreeCount = prPktProfile->ucTcxFreeCount; ++ prPrevRoundLastPkt->fgIsPrinted = prPktProfile->fgIsPrinted; ++ prPrevRoundLastPkt->fgIsValid = TRUE; ++ } ++#endif ++ ++ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); ++ ++} ++ ++VOID nicTxLifetimeRecordEn(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) ++{ ++ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; ++ ++ /* Enable packet lifetime profiling */ ++ prPktProfile->fgIsValid = TRUE; ++ ++ /* Packet arrival time at kernel Hard Xmit */ ++ prPktProfile->rHardXmitArrivalTimestamp = GLUE_GET_PKT_ARRIVAL_TIME(prPacket); ++ ++ /* Packet enqueue time */ ++ prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) kalGetTimeTick(); ++ ++} ++ ++#if CFG_PRINT_RTP_PROFILE ++/* ++ in: ++ data RTP packet pointer ++ size RTP size ++ return ++ 0:audio 1: video, -1:none ++*/ ++UINT8 checkRtpAV(PUINT_8 data, UINT_32 size) ++{ ++ PUINT_8 buf = data + 12; ++ ++ while (buf + 188 <= data + size) { ++ int pid = ((buf[1] << 8) & 0x1F00) | (buf[2] & 0xFF); ++ ++ if (pid == 0 || pid == 0x100 || pid == 0x1000) ++ buf += 188; ++ else if (pid == 0x1100) ++ return 0; ++ else if (pid == 0x1011) ++ return 1; ++ } ++ return -1; ++} ++ ++VOID ++nicTxLifetimeCheckRTP(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, ++ IN P_NATIVE_PACKET prPacket, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) ++{ ++ struct sk_buff *prSkb = (struct sk_buff *)prPacket; ++ UINT_16 u2EtherTypeLen; ++ PUINT_8 aucLookAheadBuf = NULL; ++ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; ++ ++ /* UINT_8 ucRtpHdrOffset = 28; */ ++ UINT_8 ucRtpSnOffset = 30; ++ /* UINT_32 u4RtpSrcPort = 15550; */ ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_WFD_DBG_CFG_SETTINGS_T prWfdDbgSettings = (P_WFD_DBG_CFG_SETTINGS_T) NULL; ++ ++ BOOLEAN fgEnProfiling = FALSE; ++ ++ if (prAdapter->fgIsP2PRegistered) { ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ prWfdDbgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting; ++#if CFG_PRINT_RTP_SN_SKIP ++ if (ucNetworkType == NETWORK_TYPE_P2P_INDEX) { ++ fgEnProfiling = TRUE; ++ } else ++#endif ++ if (((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000) || ++ (prWfdDbgSettings->ucWfdDebugMode > 0)) && (ucNetworkType == NETWORK_TYPE_P2P_INDEX)) { ++ fgEnProfiling = TRUE; ++ } ++ } ++ ++ if (fgEnProfiling == FALSE) { ++ /* prPktProfile->fgIsValid = FALSE; */ ++ return; ++ } ++#endif ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ /* prPktProfile->fgIsValid = FALSE; */ ++ ++ aucLookAheadBuf = prSkb->data; ++ ++ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { ++ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_16 u2tmpIpSN = 0; ++ UINT_8 ucIpVersion; ++ ++ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if (ucIpVersion == IPVERSION) { ++ if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) { ++ ++ /* if(checkRtpAV(&pucIpHdr[ucRtpHdrOffset], ++ (u4PacketLen - ETH_HLEN - ucRtpHdrOffset)) == 0) { */ ++ ++ if (prPktProfile->fgIsValid == FALSE) ++ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); ++ ++ prPktProfile->fgIsPrinted = FALSE; ++ ++ prPktProfile->ucTcxFreeCount = prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX]; ++ ++ /* RTP SN */ ++ prPktProfile->u2RtpSn = pucIpHdr[ucRtpSnOffset] << 8 | pucIpHdr[ucRtpSnOffset + 1]; ++ ++ /* IP SN */ ++ prPktProfile->u2IpSn = pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET] << 8 | ++ pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET + 1]; ++ u2tmpIpSN = prPktProfile->u2IpSn; ++ if (prWfdDbgSettings->ucWfdDebugMode == 1) { ++ if ((u2tmpIpSN & (prWfdDbgSettings->u2WfdSNShowPeiroid)) == 0) ++ DBGLOG(TX, TRACE, ++ "RtpSn=%d IPId=%d j=%lu\n", prPktProfile->u2RtpSn, ++ prPktProfile->u2IpSn, jiffies); ++ } ++ /* } */ ++ } ++ } ++ } ++ ++} ++#endif ++#if CFG_ENABLE_PER_STA_STATISTICS ++VOID ++nicTxLifetimeCheckByAC(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket, IN UINT_8 ucPriorityParam) ++{ ++ switch (ucPriorityParam) { ++ /* BK */ ++ /* case 1: */ ++ /* case 2: */ ++ ++ /* BE */ ++ /* case 0: */ ++ /* case 3: */ ++ ++ /* VI */ ++ case 4: ++ case 5: ++ ++ /* VO */ ++ case 6: ++ case 7: ++ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); ++ break; ++ default: ++ break; ++ } ++} ++ ++#endif ++ ++VOID ++nicTxLifetimeCheck(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, ++ IN P_NATIVE_PACKET prPacket, ++ IN UINT_8 ucPriorityParam, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) ++{ ++ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; ++ ++ /* Reset packet profile */ ++ prPktProfile->fgIsValid = FALSE; ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ nicTxLifetimeCheckByAC(prAdapter, prMsduInfo, prPacket, ucPriorityParam); ++#endif ++ ++#if CFG_PRINT_RTP_PROFILE ++ nicTxLifetimeCheckRTP(prAdapter, prMsduInfo, prPacket, u4PacketLen, ucNetworkType); ++#endif ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param ucPortIdx Port Number ++* @param prQue a link list of P_MSDU_INFO_T ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue) ++{ ++ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; ++ HIF_TX_HEADER_T rHwTxHeader; ++ P_NATIVE_PACKET prNativePacket; ++ UINT_16 u2OverallBufferLength; ++ UINT_8 ucEtherTypeOffsetInWord; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_32 u4TxHdrSize; ++ UINT_32 u4ValidBufSize; ++ UINT_32 u4TotalLength; ++ P_TX_CTRL_T prTxCtrl; ++ QUE_T rFreeQueue; ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ UINT_8 ucChksumFlag; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(ucPortIdx < 2); ++ ASSERT(prQue); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize; ++ ++#if CFG_HIF_STATISTICS ++ prTxCtrl->u4TotalTxAccessNum++; ++ prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem; ++#endif ++ ++ QUEUE_INITIALIZE(&rFreeQueue); ++ ++ if (prQue->u4NumElem > 0) { ++ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue); ++ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; ++ u4TotalLength = 0; ++ ++ while (prMsduInfo) { ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ UINT8 *pkt = prSkb->data; ++ UINT16 u2Identifier; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ DBGLOG(TX, TRACE, " %d\n", u2Identifier); ++ } ++ } ++#endif ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ kalMetProfilingFinish(prAdapter, prMsduInfo); ++#endif ++ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); ++ ++ prNativePacket = prMsduInfo->prPacket; ++ ++ ASSERT(prNativePacket); ++ ++ u4TxHdrSize = TX_HDR_SIZE; ++ ++ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & ++ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ /* init TX header */ ++ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; ++ rHwTxHeader.u2TxByteCount_UserPriority |= ++ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); ++ ++ if (prMsduInfo->fgIs802_11) { ++ ucEtherTypeOffsetInWord = ++ (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; ++ } else { ++ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; ++ } ++ ++ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; ++ ++ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; ++ rHwTxHeader.ucResource_PktType_CSflags |= ++ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & ++ (HIF_TX_HDR_PACKET_TYPE_MASK)); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ if (prAdapter->u4CSUMFlags & ++ (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) { ++ kalQueryTxChksumOffloadParam(prNativePacket, &ucChksumFlag); ++ ++ if (ucChksumFlag & TX_CS_IP_GEN) ++ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_IP_CSUM; ++ ++ if (ucChksumFlag & TX_CS_TCP_UDP_GEN) ++ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_TCP_CSUM; ++ } ++ } ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; ++ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; ++ rHwTxHeader.ucForwardingType_SessionID_Reserved = ++ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << ++ HIF_TX_HDR_PS_SESSION_ID_OFFSET) ++ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); ++ ++ rHwTxHeader.ucWlanHeaderLength = ++ (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); ++ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) ++ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & ++ HIF_TX_HDR_NETWORK_TYPE_MASK) ++ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & ++ HIF_TX_HDR_FLAG_1X_FRAME_MASK) ++ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & ++ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); ++ ++ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; ++ ++ if (prMsduInfo->pfTxDoneHandler) { ++ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; ++ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; ++ } else { ++ rHwTxHeader.ucPacketSeqNo = 0; ++ rHwTxHeader.ucAck_BIP_BasicRate = 0; ++ } ++ ++ if (prMsduInfo->fgNeedTxDoneStatus == TRUE) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_NEED_TX_DONE_STATUS; ++ ++ if (prMsduInfo->fgIsBIP) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; ++ ++ if (prMsduInfo->fgIsBasicRate) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ if (prMsduInfo->rPktProfile.fgIsValid) ++ prMsduInfo->rPktProfile.rDequeueTimestamp = kalGetTimeTick(); ++#endif ++ ++ /* record the queue time in driver */ ++ STATS_TX_TIME_TO_HIF(prMsduInfo, &rHwTxHeader); ++ ++#if CFG_SDIO_TX_AGG ++ /* attach to coalescing buffer */ ++ kalMemCopy(pucOutputBuf + u4TotalLength, &rHwTxHeader, u4TxHdrSize); ++ u4TotalLength += u4TxHdrSize; ++ ++ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) ++ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength); ++ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) ++ kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength); ++ else ++ ASSERT(0); ++ ++ u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength); ++ ++#else ++ kalMemCopy(pucOutputBuf, &rHwTxHeader, u4TxHdrSize); ++ ++ /* Copy Frame Body */ ++ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) ++ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TxHdrSize); ++ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) ++ kalMemCopy(pucOutputBuf + u4TxHdrSize, prNativePacket, prMsduInfo->u2FrameLength); ++ else ++ ASSERT(0); ++ ++ ASSERT(u2OverallBufferLength <= u4ValidBufSize); ++ ++ HAL_WRITE_TX_PORT(prAdapter, ++ ucPortIdx, ++ (UINT_32) u2OverallBufferLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); ++ ++ /* send immediately */ ++#endif ++ prNextMsduInfo = (P_MSDU_INFO_T) ++ QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry); ++ ++ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { ++ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ ++ if (prMsduInfo->pfTxDoneHandler == NULL) { ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } else { ++ KAL_SPIN_LOCK_DECLARATION(); ++ DBGLOG(TX, TRACE, "Wait TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ } ++ } else { ++ /* only free MSDU when it is not a MGMT frame */ ++ QUEUE_INSERT_TAIL(&rFreeQueue, (P_QUE_ENTRY_T) prMsduInfo); ++ ++ if (prMsduInfo->eSrc == TX_PACKET_OS) ++ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS); ++ else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) ++ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ } ++ ++#if CFG_SDIO_TX_AGG ++ ASSERT(u4TotalLength <= u4ValidBufSize); ++ ++#if CFG_DBG_GPIO_PINS ++ { ++ /* Start port write */ ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_LOW); ++ kalUdelay(1); ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_HIGH); ++ } ++#endif ++ ++ /* send coalescing buffer */ ++ HAL_WRITE_TX_PORT(prAdapter, ucPortIdx, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); ++#endif ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++#if CFG_SUPPORT_WFD && CFG_PRINT_RTP_PROFILE && !CFG_ENABLE_PER_STA_STATISTICS ++ do { ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ ++ if ((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000)) { ++ /* Enable profiling */ ++ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++ } else { ++ /* Skip profiling */ ++ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++ } ++ } while (FALSE); ++#else ++ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++#endif ++#else ++ /* return */ ++ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++#endif ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prPacketInfo Pointer of CMD_INFO_T ++* @param ucTC Specify the resource of TC ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) ++{ ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_16 u2OverallBufferLength; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_8 ucPortIdx; ++ HIF_TX_HEADER_T rHwTxHeader; ++ P_NATIVE_PACKET prNativePacket; ++ UINT_8 ucEtherTypeOffsetInWord; ++ P_MSDU_INFO_T prMsduInfo; ++ P_TX_CTRL_T prTxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; ++ ++ /* <1> Assign Data Port */ ++ if (ucTC != TC4_INDEX) { ++ ucPortIdx = 0; ++ } else { ++ /* Broadcast/multicast data frames, 1x frames, command packets, MMPDU */ ++ ucPortIdx = 1; ++ } ++ wlanTraceTxCmd(prCmdInfo); ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { ++ /* <2> Compose HIF_TX_HEADER */ ++ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); ++ ++ prNativePacket = prCmdInfo->prPacket; ++ ++ ASSERT(prNativePacket); ++ ++ u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) ++ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ rHwTxHeader.u2TxByteCount_UserPriority = ((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) ++ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; ++ ++ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; ++ ++ rHwTxHeader.ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET); ++ ++ rHwTxHeader.ucStaRecIdx = prCmdInfo->ucStaRecIndex; ++ rHwTxHeader.ucForwardingType_SessionID_Reserved = HIF_TX_HDR_BURST_END_MASK; ++ ++ rHwTxHeader.ucWlanHeaderLength = (ETH_HLEN & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); ++ rHwTxHeader.ucPktFormtId_Flags = ++ (((UINT_8) (prCmdInfo->eNetworkType) << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & ++ HIF_TX_HDR_NETWORK_TYPE_MASK) ++ | ((1 << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK); ++ ++ rHwTxHeader.u2SeqNo = 0; ++ rHwTxHeader.ucPacketSeqNo = 0; ++ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_TX_DONE_STATUS; ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE /* | HIF_TX_HDR_RTS */; ++ ++ /* <2.3> Copy HIF TX HEADER */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); ++ ++ /* <3> Copy Frame Body Copy */ ++ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + TX_HDR_SIZE); ++ } else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; ++ ++ ASSERT(prMsduInfo->fgIs802_11 == TRUE); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ /* <2> Compose HIF_TX_HEADER */ ++ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); ++ ++ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & ++ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; ++ rHwTxHeader.u2TxByteCount_UserPriority |= ++ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); ++ ++ ucEtherTypeOffsetInWord = (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; ++ ++ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; ++ ++ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; ++ rHwTxHeader.ucResource_PktType_CSflags |= ++ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & ++ (HIF_TX_HDR_PACKET_TYPE_MASK)); ++ ++ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; ++ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; ++ rHwTxHeader.ucForwardingType_SessionID_Reserved = ++ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << HIF_TX_HDR_PS_SESSION_ID_OFFSET) ++ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); ++ ++ rHwTxHeader.ucWlanHeaderLength = (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); ++ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) ++ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & HIF_TX_HDR_NETWORK_TYPE_MASK) ++ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK) ++ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & ++ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); ++ ++ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; ++ ++ if (prMsduInfo->pfTxDoneHandler) { ++ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; ++ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; ++ } else { ++ rHwTxHeader.ucPacketSeqNo = 0; ++ rHwTxHeader.ucAck_BIP_BasicRate = 0; ++ } ++ ++ if (prMsduInfo->fgIsBIP) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; ++ ++ if (prMsduInfo->fgIsBasicRate) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; ++ /* <2.3> Copy HIF TX HEADER */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); ++ ++ /* <3> Copy Frame Body */ ++ kalMemCopy(pucOutputBuf + TX_HDR_SIZE, prMsduInfo->prPacket, prMsduInfo->u2FrameLength); ++ ++ /* <4> Management Frame Post-Processing */ ++ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ ++ if (prMsduInfo->pfTxDoneHandler == NULL) { ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } else { ++ ++ DBGLOG(TX, TRACE, "Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ } ++ } else { ++ prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer; ++ ++ /* <2> Compose the Header of Transmit Data Structure for CMD Packet */ ++ u2OverallBufferLength = ++ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ prWifiCmd->u2TxByteCount_UserPriority = u2OverallBufferLength; ++ prWifiCmd->ucEtherTypeOffset = 0; ++ prWifiCmd->ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET) ++ | (UINT_8) ((HIF_TX_PKT_TYPE_CMD << HIF_TX_HDR_PACKET_TYPE_OFFSET) & (HIF_TX_HDR_PACKET_TYPE_MASK)); ++ ++ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); ++ ++ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); ++ ++ if ((prCmdInfo->ucCID == CMD_ID_SCAN_REQ) || ++ (prCmdInfo->ucCID == CMD_ID_SCAN_CANCEL) || ++ (prCmdInfo->ucCID == CMD_ID_SCAN_REQ_V2)) ++ DBGLOG(TX, INFO, "ucCmdSeqNum =%d, ucCID =%d\n", prCmdInfo->ucCmdSeqNum, prCmdInfo->ucCID); ++ } ++ ++ /* <4> Write frame to data port */ ++ HAL_WRITE_TX_PORT(prAdapter, ++ ucPortIdx, ++ (UINT_32) u2OverallBufferLength, ++ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of nicTxCmd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will clean up all the pending frames in internal SW Queues ++* by return the pending TX packet to the system. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxRelease(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ nicTxFlush(prAdapter); ++ ++ /* free MSDU_INFO_T from rTxMgmtMsduInfoList */ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ if (prMsduInfo) { ++ /* the packet must be mgmt frame with tx done callback */ ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ /* invoke done handler */ ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT); ++ ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++} /* end of nicTxRelease() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process the TX Done interrupt and pull in more pending frames in SW ++* Queues for transmission. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SDIO_INTR_ENHANCE ++ P_SDIO_CTRL_T prSDIOCtrl; ++#else ++ UINT_32 au4TxCount[2]; ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ prGlueInfo->IsrTxCnt++; ++ ++ /* Get the TX STATUS */ ++#if CFG_SDIO_INTR_ENHANCE ++ ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++#if DBG ++ /* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */ ++#endif ++ ++ nicTxReleaseResource(prAdapter, (PUINT_8) &prSDIOCtrl->rTxInfo); ++ kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo)); ++ ++#else ++ ++ HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]); ++ HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]); ++ DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]); ++ ++ nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount); ++ ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ nicTxAdjustTcq(prAdapter); ++ ++ /* Indicate Service Thread */ ++ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ ++} /* end of nicProcessTxInterrupt() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function frees packet of P_MSDU_INFO_T linked-list ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfoList a link list of P_MSDU_INFO_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_NATIVE_PACKET prNativePacket; ++ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead; ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfoListHead); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ while (prMsduInfo) { ++ prNativePacket = prMsduInfo->prPacket; ++ ++ if (prMsduInfo->eSrc == TX_PACKET_OS) { ++ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE); ++ } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) { ++ P_MSDU_INFO_T prTempMsduInfo = prMsduInfo; ++ ++ if (prMsduInfo->pfTxDoneHandler) ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); ++ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ cnmMgtPktFree(prAdapter, prTempMsduInfo); ++ continue; ++ } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); ++ } ++ ++ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfoList a link list of P_MSDU_INFO_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ ++ switch (prMsduInfo->eSrc) { ++ case TX_PACKET_FORWARDING: ++ wlanReturnPacket(prAdapter, prMsduInfo->prPacket); ++ break; ++ case TX_PACKET_OS: ++ case TX_PACKET_OS_OID: ++ case TX_PACKET_MGMT: ++ default: ++ break; ++ } ++ ++ /* Reset MSDU_INFO fields */ ++ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ prMsduInfo = prNextMsduInfo; ++ }; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function fills packet information to P_MSDU_INFO_T ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfo P_MSDU_INFO_T ++* @param prPacket P_NATIVE_PACKET ++* ++* @retval TRUE Success to extract information ++* @retval FALSE Fail to extract correct information ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_8 ucPriorityParam; ++ UINT_8 ucMacHeaderLen; ++ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; ++ BOOLEAN fgIs1x = FALSE; ++ BOOLEAN fgIsPAL = FALSE; ++ UINT_32 u4PacketLen; ++ ULONG u4SysTime; ++ UINT_8 ucNetworkType; ++ struct sk_buff *prSkb = (struct sk_buff *)prPacket; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ASSERT(prGlueInfo); ++ ++ if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo, ++ prPacket, ++ &ucPriorityParam, ++ &u4PacketLen, ++ aucEthDestAddr, ++ &fgIs1x, &fgIsPAL, &ucNetworkType, ++ NULL) == FALSE) { ++ return FALSE; ++ } ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ nicTxLifetimeCheck(prAdapter, prMsduInfo, prPacket, ucPriorityParam, u4PacketLen, ucNetworkType); ++#endif ++ ++ /* Save the value of Priority Parameter */ ++ GLUE_SET_PKT_TID(prPacket, ucPriorityParam); ++ ++ if (fgIs1x) ++ GLUE_SET_PKT_FLAG_1X(prPacket); ++ ++ if (fgIsPAL) ++ GLUE_SET_PKT_FLAG_PAL(prPacket); ++ ++ ucMacHeaderLen = ETH_HLEN; ++ ++ /* Save the value of Header Length */ ++ GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen); ++ ++ /* Save the value of Frame Length */ ++ GLUE_SET_PKT_FRAME_LEN(prPacket, (UINT_16) u4PacketLen); ++ ++ /* Save the value of Arrival Time */ ++ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); ++ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); ++ ++ prMsduInfo->prPacket = prPacket; ++ prMsduInfo->fgIs802_1x = fgIs1x; ++ prMsduInfo->fgIs802_11 = FALSE; ++ prMsduInfo->ucNetworkType = ucNetworkType; ++ prMsduInfo->ucUserPriority = ucPriorityParam; ++ prMsduInfo->ucMacHeaderLength = ucMacHeaderLen; ++ prMsduInfo->u2FrameLength = (UINT_16) u4PacketLen; ++ COPY_MAC_ADDR(prMsduInfo->aucEthDestAddr, aucEthDestAddr); ++ ++ if (prSkb->len > ETH_HLEN) ++ STATS_TX_PKT_CALLBACK(prSkb->data, prMsduInfo); ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function update TCQ values by passing current status to txAdjustTcQuotas ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Updated successfully ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4Num; ++ TX_TCQ_ADJUST_T rTcqAdjust; ++ P_TX_CTRL_T prTxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ for (u4Num = 0; u4Num < TC_NUM; u4Num++) { ++ prTxCtrl->rTc.aucFreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num]; ++ prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num]; ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function flushes all packets queued in STA/AC queue ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Flushed successfully ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ /* ask Per STA/AC queue to be fllushed and return all queued packets */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prMsduInfo = qmFlushTxQueues(prAdapter); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ if (prMsduInfo != NULL) { ++ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo); ++ nicTxReturnMsduInfo(prAdapter, prMsduInfo); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. ++* However this function is used for INIT_CMD. ++* ++* In order to avoid further maintenance issues, these 2 functions are separated ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prPacketInfo Pointer of CMD_INFO_T ++* @param ucTC Specify the resource of TC ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) ++{ ++ P_INIT_HIF_TX_HEADER_T prInitTxHeader; ++ UINT_16 u2OverallBufferLength; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_32 ucPortIdx; ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(ucTC == TC0_INDEX); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; ++ prInitTxHeader = (P_INIT_HIF_TX_HEADER_T) prCmdInfo->pucInfoBuffer; ++ ++ /* <1> Compose the Header of Transmit Data Structure for CMD Packet */ ++ u2OverallBufferLength = ++ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ prInitTxHeader->u2TxByteCount = u2OverallBufferLength; ++ prInitTxHeader->ucEtherTypeOffset = 0; ++ prInitTxHeader->ucCSflags = 0; ++ ++ /* <2> Assign Data Port */ ++ if (ucTC != TC4_INDEX) { ++ ucPortIdx = 0; ++ } else { /* Broadcast/multicast data packets */ ++ ucPortIdx = 1; ++ } ++ ++ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); ++ ++ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); ++ ++ /* <4> Write frame to data port */ ++ HAL_WRITE_TX_PORT(prAdapter, ++ ucPortIdx, ++ (UINT_32) u2OverallBufferLength, ++ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief In this function, we'll reset TX resource counter to initial value used ++* in F/W download state ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Reset is done successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ ++ DEBUGFUNC("nicTxInitResetResource"); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; ++ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; ++ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; ++ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; ++ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; ++ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; ++ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief this function enqueues MSDU_INFO_T into queue management, ++* or command queue ++* ++* @param prAdapter Pointer to the Adapter structure. ++* prMsduInfo Pointer to MSDU ++* ++* @retval WLAN_STATUS_SUCCESS Reset is done successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead; ++ QUE_T qDataPort0, qDataPort1; ++ P_CMD_INFO_T prCmdInfo; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ QUEUE_INITIALIZE(&qDataPort0); ++ QUEUE_INITIALIZE(&qDataPort1); ++ ++ /* check how many management frame are being queued */ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ ++ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; ++ ++ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { ++ /* MMPDU: force stick to TC4 */ ++ prMsduInfo->ucTC = TC4_INDEX; ++ ++ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); ++ } else { ++ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ } ++ ++ if (qDataPort0.u4NumElem) { ++ /* send to QM: queue the packet to different TX queue by policy */ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort0)); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ /* post-process for "dropped" packets */ ++ if (prRetMsduInfo != NULL) { /* unable to enqueue */ ++ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo); ++ nicTxReturnMsduInfo(prAdapter, prRetMsduInfo); ++ } ++ } ++ ++ if (qDataPort1.u4NumElem) { ++ prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort1); ++ ++ if (qDataPort1.u4NumElem > nicTxGetFreeCmdCount(prAdapter)) { ++ /* not enough descriptors for sending */ ++ u4Status = WLAN_STATUS_FAILURE; ++ ++ /* free all MSDUs */ ++ while (prMsduInfoHead) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); ++ ++ if (prMsduInfoHead->pfTxDoneHandler != NULL) { ++ prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead, ++ TX_RESULT_DROPPED_IN_DRIVER); ++ } ++ ++ cnmMgtPktFree(prAdapter, prMsduInfoHead); ++ ++ prMsduInfoHead = prNextMsduInfo; ++ } ++ } else { ++ /* send to command queue */ ++ while (prMsduInfoHead) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ if (prCmdInfo) { ++ GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ ++ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); ++ ++ prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME; ++ prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength; ++ prCmdInfo->pucInfoBuffer = NULL; ++ prCmdInfo->prPacket = (P_NATIVE_PACKET) prMsduInfoHead; ++ prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex; ++ prCmdInfo->eNetworkType = prMsduInfoHead->ucNetworkType; ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ ++ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ } else { ++ /* Cmd free count is larger than expected, but allocation fail. */ ++ ASSERT(0); ++ ++ u4Status = WLAN_STATUS_FAILURE; ++ cnmMgtPktFree(prAdapter, prMsduInfoHead); ++ } ++ ++ prMsduInfoHead = prNextMsduInfo; ++ } ++ } ++ } ++ ++ /* indicate service thread for sending */ ++ if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief this function returns available count in command queue ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->rFreeCmdList.u4NumElem; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c +new file mode 100644 +index 000000000000..38e4569bc04f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c +@@ -0,0 +1,192 @@ ++/* ++** Id: @(#) p2p_nic.c@@ ++*/ ++ ++/*! \file p2p_nic.c ++ \brief Wi-Fi Direct Functions that provide operation in NIC's (Network Interface Card) point of view. ++ ++ This file includes functions which unite multiple hal(Hardware) operations ++ and also take the responsibility of Software Resource Management in order ++ to keep the synchronization with Hardware Manipulation. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief When Probe Rsp & Beacon frame is received and decide a P2P device, ++* this function will be invoked to buffer scan result ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prEventScanResult Pointer of EVENT_SCAN_RESULT_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, ++ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength) ++{ ++ P_P2P_INFO_T prP2pInfo = (P_P2P_INFO_T) NULL; ++ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; ++ UINT_32 u4Idx = 0; ++ BOOLEAN bUpdate = FALSE; ++ ++ PUINT_8 pucIeBuf = (PUINT_8) NULL; ++ UINT_16 u2IELength = 0; ++ UINT_8 zeroMac[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; ++ ++ ASSERT(prAdapter); ++ ++ prP2pInfo = prAdapter->prP2pInfo; ++ ++ for (u4Idx = 0; u4Idx < prP2pInfo->u4DeviceNum; u4Idx++) { ++ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; ++ ++ if (EQUAL_MAC_ADDR(prTargetResult->aucDeviceAddr, prP2pResult->aucDeviceAddr)) { ++ bUpdate = TRUE; ++ ++ /* Backup OLD buffer result. */ ++ pucIeBuf = prTargetResult->pucIeBuf; ++ u2IELength = prTargetResult->u2IELength; ++ ++ /* Update Device Info. */ ++ /* zero */ ++ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* then buffer */ ++ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* See if new IE length is longer or not. */ ++ if ((u2RxIELength > u2IELength) && (u2IELength != 0)) { ++ /* Buffer is not enough. */ ++ u2RxIELength = u2IELength; ++ } else if ((u2IELength == 0) && (u2RxIELength != 0)) { ++ /* RX new IE buf. */ ++ ASSERT(pucIeBuf == NULL); ++ pucIeBuf = prP2pInfo->pucCurrIePtr; ++ ++ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > ++ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { ++ /* Common Buffer is no enough. */ ++ u2RxIELength = ++ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - ++ (ULONG) prP2pInfo->pucCurrIePtr); ++ } ++ ++ /* Step to next buffer address. */ ++ prP2pInfo->pucCurrIePtr = ++ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength); ++ } ++ ++ /* Restore buffer pointer. */ ++ prTargetResult->pucIeBuf = pucIeBuf; ++ ++ if (pucRxIEBuf) { ++ /* If new received IE is available. ++ * Replace the old one & update new IE length. ++ */ ++ kalMemCopy(pucIeBuf, pucRxIEBuf, u2RxIELength); ++ prTargetResult->u2IELength = u2RxIELength; ++ } else { ++ /* There is no new IE information, keep the old one. */ ++ prTargetResult->u2IELength = u2IELength; ++ } ++ } ++ } ++ ++ if (!bUpdate) { ++ /* We would flush the whole scan result after each scan request is issued. ++ * If P2P device is too many, it may over the scan list. ++ */ ++ if ((u4Idx < CFG_MAX_NUM_BSS_LIST) && (UNEQUAL_MAC_ADDR(zeroMac, prP2pResult->aucDeviceAddr))) { ++ /* whsu:XXX */ ++ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; ++ ++ /* zero */ ++ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* then buffer */ ++ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* printk("DVC FND %d %pM, %pM\n", ++ prP2pInfo->u4DeviceNum, ++ prP2pResult->aucDeviceAddr, ++ prTargetResult->aucDeviceAddr); */ ++ ++ if (u2RxIELength) { ++ prTargetResult->pucIeBuf = prP2pInfo->pucCurrIePtr; ++ ++ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > ++ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { ++ /* Common Buffer is no enough. */ ++ u2IELength = ++ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - ++ (ULONG) prP2pInfo->pucCurrIePtr); ++ } else { ++ u2IELength = u2RxIELength; ++ } ++ ++ prP2pInfo->pucCurrIePtr = ++ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2IELength); ++ ++ kalMemCopy((PVOID) prTargetResult->pucIeBuf, (PVOID) pucRxIEBuf, (UINT_32) u2IELength); ++ prTargetResult->u2IELength = u2IELength; ++ } else { ++ prTargetResult->pucIeBuf = NULL; ++ prTargetResult->u2IELength = 0; ++ } ++ ++ prP2pInfo->u4DeviceNum++; ++ ++ } else { ++ /* TODO: Fixme to replace an old one. (?) */ ++ ASSERT(FALSE); ++ } ++ } ++} /* nicRxAddP2pDevice */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c +new file mode 100644 +index 000000000000..dd00859d4608 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c +@@ -0,0 +1,5038 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/que_mgt.c#1 ++*/ ++ ++/*! \file "que_mgt.c" ++ \brief TX/RX queues management ++ ++ The main tasks of queue management include TC-based HIF TX flow control, ++ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save ++ forwarding control, RX packet reordering, and RX BA agreement management. ++*/ ++ ++/* ++** Log: que_mgt.c ++** ++** 04 11 2013 yuche.tsai ++** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. ++** Drop the probe response packet when absent. ++** ++** 04 09 2013 yuche.tsai ++** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. ++** Fix CMD buffer short issue. ++** ++** 04 09 2013 yuche.tsai ++** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. ++** Fix CMD buffer short issue. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 02 23 2012 eddie.chen ++ * [WCXRP00001194] [MT6620][DRV/FW] follow admission control bit to change the enqueue rule ++ * Change the enqueue policy when ACM = 1. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Code refine, remove one #if 0 code. ++ * ++ * 11 19 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog for tx ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 18 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Fix xlog format to hex format ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * avoid deactivating staRec when changing state from 3 to 3. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug msg for xlog. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters of bb and ar for xlog. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Use short name for xlog. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 10 2011 chinglan.wang ++ * NULL ++ * [WiFi WPS]Can't switch to new AP via WPS PBC when there existing a connection to another AP. ++ * ++ * 11 09 2011 chinglan.wang ++ * NULL ++ * [WiFi direct]Can't make P2P connect via PBC. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. ++ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to ++ * the AP.. ++ * ++ * 10 25 2011 wh.su ++ * [WCXRP00001059] [MT6620 Wi-Fi][Driver][P2P] Fixed sometimes data (1x) will not indicate to upper layer due ba check ++ * un-expect ++ * let the Rx BA accept even the sta not valid. ++ * ++ * 09 28 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * enlarge window size only by 4. ++ * ++ * 09 01 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * set rx window size as twice buffer size. ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix multicast address list issue. ++ * ++ * 08 03 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * force window size at least 16. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device ++ * issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 26 2011 eddie.chen ++ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter ++ * API for query the RX reorder queued packets counter. ++ * ++ * 07 07 2011 eddie.chen ++ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. ++ * Add setEvent when free quota is updated. ++ * ++ * 07 05 2011 eddie.chen ++ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. ++ * Send 1x when peer STA is in PS. ++ * ++ * 05 31 2011 eddie.chen ++ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 ++ * Fix the QM quota in MT5931. ++ * ++ * 05 11 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Fix dest type when GO packet copying. ++ * ++ * 05 09 2011 yuche.tsai ++ * [WCXRP00000712] [Volunteer Patch][MT6620][Driver] Sending deauth issue when Hot spot is disabled. (GO is dissolved) ++ * Deauthentication frame is not bound to network active status. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 04 14 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Check the SW RFB free. Fix the compile warning.. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 11 2011 yuche.tsai ++ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. ++ * Fix kernel panic issue when MMPDU of P2P is pending in driver. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Fix Klockwork warning. ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW ++ * Fix wmm parameters in beacon for BOW. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 02 23 2011 eddie.chen ++ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap ++ * Fix parsing WMM INFO and bmp delivery bitmap definition. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Remove comments. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Add destination decision in AP mode. ++ * ++ * 01 14 2011 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out[WCXRP00000326] ++ * [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! ++ * Allow 802.1x can be send even the net is not active due the drver / fw sync issue. ++ * ++ * 01 13 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ * Fix typo and compile error. ++ * ++ * 01 12 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ * Fix WMM parameter condition for STA ++ * ++ * 01 12 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ * 1) Check Bss if support QoS before adding WMMIE ++ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control ++ * ++ * 01 12 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Update MQM for WMM IE generation method ++ * ++ * 01 11 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * Add per STA flow control when STA is in PS mode ++ * ++ * 01 03 2011 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * update prStaRec->fgIsUapsdSupported flag. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * Add WMM parameter for broadcast. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out ++ * use the #14 and modify the add code for check MMPDU. ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out ++ * only MMPDU not check the netActive flag. ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out ++ * not check the netActive flag for mgmt . ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 08 30 2010 yarco.yang ++ * NULL ++ * Fixed klockwork error message ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 10 2010 yarco.yang ++ * NULL ++ * Code refine ++ * ++ * 08 06 2010 yarco.yang ++ * NULL ++ * Update qmGetFrameAction() to allow P2P MGMT frame w/o STA_Record still can perform TX action ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet ++ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found ++ * ++ * 07 20 2010 yarco.yang ++ * ++ * Add to SetEvent when BSS is from Absent to Present or STA from PS to Awake ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 13 2010 yarco.yang ++ * ++ * [WPD00003849] ++ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * . ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Use fgInUse instead of fgIsValid for De-queue judgement ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * For MMPDU, STA_REC will be decided by caller module ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add MGMT Packet type for HIF_TX_HEADER ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 31 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Refined the debug msg ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * comment out one assertion which refer to undefined data member. ++ * ++ * 03 30 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled adaptive TC resource control ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++* 03 17 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) ++ * ++ * 03 11 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Fixed buffer leak when processing BAR frames ++ * ++ * 03 02 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * For TX packets with STA_REC index = STA_REC_INDEX_NOT_FOUND, use TC5 ++ * ++ * 03 01 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Fixed STA_REC index determination bug (fgIsValid shall be checked) ++ * ++ * 02 25 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Refined function qmDetermineStaRecIndex() for BMCAST packets ++ * ++ * 02 25 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled multi-STA TX path with fairness ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled dynamically activating and deactivating STA_RECs ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added code for dynamic activating and deactivating STA_RECs. ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the 802.1x path ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-14 15:01:37 GMT MTK02468 ++** Fixed casting for qmAddRxBaEntry() ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:51:03 GMT mtk02752 ++** remove SD1_SD3.. flag ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-09 14:07:25 GMT MTK02468 ++** Added RX buffer reordering functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-04 13:34:16 GMT MTK02468 ++** Modified Flush Queue function to let queues be reinitialized ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-04 13:18:25 GMT MTK02468 ++** Added flushing per-Type queues code ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 23:39:49 GMT MTK02468 ++** Added Debug msgs and fixed incorrect assert ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-26 23:50:27 GMT MTK02468 ++** Bug fixing (qmDequeueTxPackets local variable initialization) ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-26 09:39:25 GMT mtk02752 ++** correct and surpress PREfast warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-11-23 22:10:55 GMT mtk02468 ++** Used SD1_SD3_DATAPATH_INTEGRATION ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 22:02:30 GMT mtk02468 ++** Initial version ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++OS_SYSTIME g_arMissTimeout[CFG_STA_REC_NUM][CFG_RX_MAX_BA_TID_NUM]; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if ARP_MONITER_ENABLE ++static UINT_16 arpMoniter; ++static UINT_8 apIp[4]; ++#endif ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static inline VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++static inline VOID ++qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, ++ OUT P_QUE_T prQue, ++ IN UINT_8 ucTC, IN UINT_8 ucCurrentAvailableQuota, IN UINT_8 ucTotalQuota); ++ ++static inline VOID ++qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Init Queue Management for TX ++* ++* \param[in] (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmInit(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4QueArrayIdx; ++ UINT_32 i; ++ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* DbgPrint("QM: Enter qmInit()\n"); */ ++#if CFG_SUPPORT_QOS ++ prAdapter->rWifiVar.fgSupportQoS = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportQoS = FALSE; ++#endif ++ ++#if CFG_SUPPORT_AMPDU_RX ++ prAdapter->rWifiVar.fgSupportAmpduRx = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportAmpduRx = FALSE; ++#endif ++ ++#if CFG_SUPPORT_AMPDU_TX ++ prAdapter->rWifiVar.fgSupportAmpduTx = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportAmpduTx = FALSE; ++#endif ++ ++#if CFG_SUPPORT_TSPEC ++ prAdapter->rWifiVar.fgSupportTspec = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportTspec = FALSE; ++#endif ++ ++#if CFG_SUPPORT_UAPSD ++ prAdapter->rWifiVar.fgSupportUAPSD = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportUAPSD = FALSE; ++#endif ++ ++#if CFG_SUPPORT_UL_PSMP ++ prAdapter->rWifiVar.fgSupportULPSMP = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportULPSMP = FALSE; ++#endif ++ ++#if CFG_SUPPORT_RX_SGI ++ prAdapter->rWifiVar.u8SupportRxSgi20 = 0; ++ prAdapter->rWifiVar.u8SupportRxSgi40 = 0; ++#else ++ prAdapter->rWifiVar.u8SupportRxSgi20 = 2; ++ prAdapter->rWifiVar.u8SupportRxSgi40 = 2; ++#endif ++ ++#if CFG_SUPPORT_RX_HT_GF ++ prAdapter->rWifiVar.u8SupportRxGf = 0; ++#else ++ prAdapter->rWifiVar.u8SupportRxGf = 2; ++#endif ++ ++ /* 4 <2> Initialize other TX queues (queues not in STA_RECs) */ ++ for (u4QueArrayIdx = 0; u4QueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; u4QueArrayIdx++) ++ QUEUE_INITIALIZE(&(prQM->arTxQueue[u4QueArrayIdx])); ++ ++ /* 4 <3> Initialize the RX BA table and RX queues */ ++ /* Initialize the RX Reordering Parameters and Queues */ ++ for (u4QueArrayIdx = 0; u4QueArrayIdx < CFG_NUM_OF_RX_BA_AGREEMENTS; u4QueArrayIdx++) { ++ prQM->arRxBaTable[u4QueArrayIdx].fgIsValid = FALSE; ++ QUEUE_INITIALIZE(&(prQM->arRxBaTable[u4QueArrayIdx].rReOrderQue)); ++ prQM->arRxBaTable[u4QueArrayIdx].u2WinStart = 0xFFFF; ++ prQM->arRxBaTable[u4QueArrayIdx].u2WinEnd = 0xFFFF; ++ ++ prQM->arRxBaTable[u4QueArrayIdx].fgIsWaitingForPktWithSsn = FALSE; ++ ++ } ++ prQM->ucRxBaCount = 0; ++ ++ kalMemSet(&g_arMissTimeout, 0, sizeof(g_arMissTimeout)); ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ /* 4 <4> Initialize TC resource control variables */ ++ for (i = 0; i < TC_NUM; i++) ++ prQM->au4AverageQueLen[i] = 0; ++ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; ++ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; ++ prQM->u4TxNumOfVi = 0; ++ prQM->u4TxNumOfVo = 0; ++ ++/* ASSERT(prQM->u4TimeToAdjust && prQM->u4TimeToUpdateQueLen); */ ++ ++ /* 1 20 1 1 4 1 */ ++ prQM->au4CurrentTcResource[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; ++ prQM->au4CurrentTcResource[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; ++ prQM->au4CurrentTcResource[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; ++ prQM->au4CurrentTcResource[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; ++ prQM->au4CurrentTcResource[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; /* Not adjustable (TX port 1) */ ++ prQM->au4CurrentTcResource[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC0 = %d\n", NIC_TX_BUFF_COUNT_TC0); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC1 = %d\n", NIC_TX_BUFF_COUNT_TC1); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC2 = %d\n", NIC_TX_BUFF_COUNT_TC2); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC3 = %d\n", NIC_TX_BUFF_COUNT_TC3); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC4 = %d\n", NIC_TX_BUFF_COUNT_TC4); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC5 = %d\n", NIC_TX_BUFF_COUNT_TC5); ++ ++ /* 1 1 1 1 2 1 */ ++ prQM->au4MinReservedTcResource[TC0_INDEX] = QM_MIN_RESERVED_TC0_RESOURCE; ++ prQM->au4MinReservedTcResource[TC1_INDEX] = QM_MIN_RESERVED_TC1_RESOURCE; ++ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; ++ prQM->au4MinReservedTcResource[TC3_INDEX] = QM_MIN_RESERVED_TC3_RESOURCE; ++ prQM->au4MinReservedTcResource[TC4_INDEX] = QM_MIN_RESERVED_TC4_RESOURCE; /* Not adjustable (TX port 1) */ ++ prQM->au4MinReservedTcResource[TC5_INDEX] = QM_MIN_RESERVED_TC5_RESOURCE; ++ ++ /* 4 4 6 6 2 4 */ ++ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC3_INDEX] = QM_GUARANTEED_TC3_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC4_INDEX] = QM_GUARANTEED_TC4_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC5_INDEX] = QM_GUARANTEED_TC5_RESOURCE; ++ ++ prQM->fgTcResourcePostAnnealing = FALSE; ++ ++ ASSERT(QM_INITIAL_RESIDUAL_TC_RESOURCE < 64); ++#endif ++ ++#if QM_TEST_MODE ++ prQM->u4PktCount = 0; ++ ++#if QM_TEST_FAIR_FORWARDING ++ ++ prQM->u4CurrentStaRecIndexToEnqueue = 0; ++ { ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ P_STA_RECORD_T prStaRec; ++ ++ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ ++ aucMacAddr[0] = 0x11; ++ aucMacAddr[1] = 0x22; ++ aucMacAddr[2] = 0xAA; ++ aucMacAddr[3] = 0xBB; ++ aucMacAddr[4] = 0xCC; ++ aucMacAddr[5] = 0xDD; ++ ++ prStaRec = &prAdapter->arStaRec[1]; ++ ASSERT(prStaRec); ++ ++ prStaRec->fgIsValid = TRUE; ++ prStaRec->fgIsQoS = TRUE; ++ prStaRec->fgIsInPS = FALSE; ++ prStaRec->ucPsSessionID = 0xFF; ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prStaRec->fgIsAp = TRUE; ++ COPY_MAC_ADDR((prStaRec)->aucMacAddr, aucMacAddr); ++ ++ } ++ ++#endif ++ ++#endif ++ ++#if QM_FORWARDING_FAIRNESS ++ { ++ UINT_32 i; ++ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { ++ prQM->au4ForwardCount[i] = 0; ++ prQM->au4HeadStaRecIndex[i] = 0; ++ } ++ } ++#endif ++ ++#if QM_TC_RESOURCE_EMPTY_COUNTER ++ kalMemZero(prQM->au4QmTcResourceEmptyCounter, sizeof(prQM->au4QmTcResourceEmptyCounter)); ++#endif ++ ++} ++ ++#if QM_TEST_MODE ++VOID qmTestCases(IN P_ADAPTER_T prAdapter) ++{ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ DbgPrint("QM: ** TEST MODE **\n"); ++ ++ if (QM_TEST_STA_REC_DETERMINATION) { ++ if (prAdapter->arStaRec[0].fgIsValid) { ++ prAdapter->arStaRec[0].fgIsValid = FALSE; ++ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); ++ } else { ++ prAdapter->arStaRec[0].fgIsValid = TRUE; ++ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); ++ } ++ } ++ ++ if (QM_TEST_STA_REC_DEACTIVATION) { ++ /* Note that QM_STA_REC_HARD_CODING shall be set to 1 for this test */ ++ ++ if (prAdapter->arStaRec[0].fgIsValid) { ++ ++ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); ++ qmDeactivateStaRec(prAdapter, 0); ++ } else { ++ ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ ++ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ ++ aucMacAddr[0] = 0x11; ++ aucMacAddr[1] = 0x22; ++ aucMacAddr[2] = 0xAA; ++ aucMacAddr[3] = 0xBB; ++ aucMacAddr[4] = 0xCC; ++ aucMacAddr[5] = 0xDD; ++ ++ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); ++ qmActivateStaRec(prAdapter, /* Adapter pointer */ ++ 0, /* STA_REC index from FW */ ++ TRUE, /* fgIsQoS */ ++ NETWORK_TYPE_AIS_INDEX, /* Network type */ ++ TRUE, /* fgIsAp */ ++ aucMacAddr /* MAC address */ ++ ); ++ } ++ } ++ ++ if (QM_TEST_FAIR_FORWARDING) { ++ if (prAdapter->arStaRec[1].fgIsValid) { ++ prQM->u4CurrentStaRecIndexToEnqueue++; ++ prQM->u4CurrentStaRecIndexToEnqueue %= 2; ++ DbgPrint("QM: (Test) Switch to STA_REC[%u]\n", prQM->u4CurrentStaRecIndexToEnqueue); ++ } ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Activate a STA_REC ++* ++* \param[in] prAdapter Pointer to the Adapter instance ++* \param[in] u4StaRecIdx The index of the STA_REC ++* \param[in] fgIsQoS Set to TRUE if this is a QoS STA ++* \param[in] pucMacAddr The MAC address of the STA ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ /* 4 <1> Deactivate first */ ++ ASSERT(prStaRec); ++ ++ if (prStaRec->fgIsValid) { /* The STA_REC has been activated */ ++ DBGLOG(QM, WARN, "QM: (WARNING) Activating a STA_REC which has been activated\n"); ++ DBGLOG(QM, WARN, "QM: (WARNING) Deactivating a STA_REC before re-activating\n"); ++ /* To flush TX/RX queues and del RX BA agreements */ ++ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); ++ } ++ /* 4 <2> Activate the STA_REC */ ++ /* Init the STA_REC */ ++ prStaRec->fgIsValid = TRUE; ++ prStaRec->fgIsInPS = FALSE; ++ prStaRec->ucPsSessionID = 0xFF; ++ prStaRec->fgIsAp = (IS_AP_STA(prStaRec)) ? TRUE : FALSE; ++ ++ /* Done in qmInit() or qmDeactivateStaRec() */ ++#if 0 ++ /* At the beginning, no RX BA agreements have been established */ ++ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) ++ (prStaRec->aprRxReorderParamRefTbl)[i] = NULL; ++#endif ++ ++ DBGLOG(QM, TRACE, "QM: +STA[%u]\n", (UINT_32) prStaRec->ucIndex); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Deactivate a STA_REC ++* ++* \param[in] prAdapter Pointer to the Adapter instance ++* \param[in] u4StaRecIdx The index of the STA_REC ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_32 i; ++ P_MSDU_INFO_T prFlushedTxPacketList = NULL; ++ ++ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* 4<1> Flush TX queues */ ++ prFlushedTxPacketList = qmFlushStaTxQueues(prAdapter, u4StaRecIdx); ++ ++ if (prFlushedTxPacketList) ++ wlanProcessQueuedMsduInfo(prAdapter, prFlushedTxPacketList); ++ /* 4 <2> Flush RX queues and delete RX BA agreements */ ++ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { ++ /* Delete the RX BA entry with TID = i */ ++ qmDelRxBaEntry(prAdapter, (UINT_8) u4StaRecIdx, (UINT_8) i, FALSE); ++ } ++ ++ /* 4 <3> Deactivate the STA_REC */ ++ prStaRec->fgIsValid = FALSE; ++ prStaRec->fgIsInPS = FALSE; ++ ++ /* To reduce printk for IOT sta to connect all the time, */ ++ /* DBGLOG(QM, INFO, ("QM: -STA[%ld]\n", u4StaRecIdx)); */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Deactivate a STA_REC ++* ++* \param[in] prAdapter Pointer to the Adapter instance ++* \param[in] u4StaRecIdx The index of the network ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ ++ P_QUE_MGT_T prQM; ++ P_QUE_T prQue; ++ QUE_T rNeedToFreeQue; ++ QUE_T rTempQue; ++ P_QUE_T prNeedToFreeQue; ++ P_QUE_T prTempQue; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ prQM = &prAdapter->rQM; ++ prQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; ++ ++ QUEUE_INITIALIZE(&rNeedToFreeQue); ++ QUEUE_INITIALIZE(&rTempQue); ++ ++ prNeedToFreeQue = &rNeedToFreeQue; ++ prTempQue = &rTempQue; ++ ++ QUEUE_MOVE_ALL(prTempQue, prQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); ++ while (prMsduInfo) { ++ ++ if (prMsduInfo->ucNetworkType == eNetworkTypeIdx) { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(prNeedToFreeQue, (P_QUE_ENTRY_T) prMsduInfo); ++ } else { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prMsduInfo); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); ++ } ++ if (QUEUE_IS_NOT_EMPTY(prNeedToFreeQue)) ++ wlanProcessQueuedMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prNeedToFreeQue)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush all TX queues ++* ++* \param[in] (none) ++* ++* \return The flushed packets (in a list of MSDU_INFOs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucStaArrayIdx; ++ UINT_8 ucQueArrayIdx; ++ ++ P_MSDU_INFO_T prMsduInfoListHead; ++ P_MSDU_INFO_T prMsduInfoListTail; ++ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ DBGLOG(QM, TRACE, "QM: Enter qmFlushTxQueues()\n"); ++ ++ prMsduInfoListHead = NULL; ++ prMsduInfoListTail = NULL; ++ ++ /* Concatenate all MSDU_INFOs in per-STA queues */ ++ for (ucStaArrayIdx = 0; ucStaArrayIdx < CFG_NUM_OF_STA_RECORD; ucStaArrayIdx++) { ++ ++ /* Always check each STA_REC when flushing packets no matter it is inactive or active */ ++#if 0 ++ if (!prAdapter->arStaRec[ucStaArrayIdx].fgIsValid) ++ continue; /* Continue to check the next STA_REC */ ++#endif ++ ++ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { ++ if (QUEUE_IS_EMPTY(&(prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]))) ++ continue; /* Continue to check the next TX queue of the same STA */ ++ ++ if (!prMsduInfoListHead) { ++ ++ /* The first MSDU_INFO is found */ ++ prMsduInfoListHead = (P_MSDU_INFO_T) ++ QUEUE_GET_HEAD(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, ++ QUEUE_GET_HEAD(&prAdapter-> ++ arStaRec[ucStaArrayIdx].arTxQueue ++ [ucQueArrayIdx])); ++ ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ } ++ ++ QUEUE_INITIALIZE(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ } ++ } ++ ++ /* Flush per-Type queues */ ++ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; ucQueArrayIdx++) { ++ ++ if (QUEUE_IS_EMPTY(&(prQM->arTxQueue[ucQueArrayIdx]))) ++ continue; /* Continue to check the next TX queue of the same STA */ ++ ++ if (!prMsduInfoListHead) { ++ ++ /* The first MSDU_INFO is found */ ++ prMsduInfoListHead = (P_MSDU_INFO_T) ++ QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx]); ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx])); ++ ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); ++ } ++ ++ QUEUE_INITIALIZE(&prQM->arTxQueue[ucQueArrayIdx]); ++ ++ } ++ ++ if (prMsduInfoListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, NULL); ++ } ++ ++ return prMsduInfoListHead; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush TX packets for a particular STA ++* ++* \param[in] u4StaRecIdx STA_REC index ++* ++* \return The flushed packets (in a list of MSDU_INFOs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) ++{ ++ UINT_8 ucQueArrayIdx; ++ P_MSDU_INFO_T prMsduInfoListHead; ++ P_MSDU_INFO_T prMsduInfoListTail; ++ P_STA_RECORD_T prStaRec; ++ ++ /* To reduce printk for IOT sta to connect all the time, */ ++ /* DBGLOG(QM, TRACE, ("QM: Enter qmFlushStaTxQueues(%ld)\n", u4StaRecIdx)); */ ++ ++ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ prMsduInfoListHead = NULL; ++ prMsduInfoListTail = NULL; ++ ++ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* No matter whether this is an activated STA_REC, do flush */ ++#if 0 ++ if (!prStaRec->fgIsValid) ++ return NULL; ++#endif ++ ++ /* Concatenate all MSDU_INFOs in TX queues of this STA_REC */ ++ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { ++ if (QUEUE_IS_EMPTY(&(prStaRec->arTxQueue[ucQueArrayIdx]))) ++ continue; ++ ++ if (!prMsduInfoListHead) { ++ /* The first MSDU_INFO is found */ ++ prMsduInfoListHead = (P_MSDU_INFO_T) ++ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, ++ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx])); ++ ++ prMsduInfoListTail = (P_MSDU_INFO_T) QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ } ++ ++ QUEUE_INITIALIZE(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ ++ } ++ ++#if 0 ++ if (prMsduInfoListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx)); ++ } else { ++ prMsduInfoListHead = nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx); ++ } ++#endif ++ ++ return prMsduInfoListHead; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush RX packets ++* ++* \param[in] (none) ++* ++* \return The flushed packets (in a list of SW_RFBs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ P_SW_RFB_T prSwRfbListHead; ++ P_SW_RFB_T prSwRfbListTail; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ prSwRfbListHead = prSwRfbListTail = NULL; ++ ++ DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n"); ++ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ if (QUEUE_IS_NOT_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) { ++ if (!prSwRfbListHead) { ++ ++ /* The first MSDU_INFO is found */ ++ prSwRfbListHead = (P_SW_RFB_T) ++ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue)); ++ prSwRfbListTail = (P_SW_RFB_T) ++ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prSwRfbListTail, ++ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue))); ++ ++ prSwRfbListTail = (P_SW_RFB_T) ++ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); ++ } ++ ++ QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue)); ++ ++ } else { ++ continue; ++ } ++ } ++ ++ if (prSwRfbListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); ++ } ++ return prSwRfbListHead; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush RX packets with respect to a particular STA ++* ++* \param[in] u4StaRecIdx STA_REC index ++* \param[in] u4Tid TID ++* ++* \return The flushed packets (in a list of SW_RFBs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_SW_RFB_T qmFlushStaRxQueue(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx, IN UINT_32 u4Tid) ++{ ++ /* UINT_32 i; */ ++ P_SW_RFB_T prSwRfbListHead; ++ P_SW_RFB_T prSwRfbListTail; ++ P_RX_BA_ENTRY_T prReorderQueParm; ++ P_STA_RECORD_T prStaRec; ++ ++ DBGLOG(QM, TRACE, "QM: Enter qmFlushStaRxQueues(%u)\n", u4StaRecIdx); ++ ++ prSwRfbListHead = prSwRfbListTail = NULL; ++ ++ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* No matter whether this is an activated STA_REC, do flush */ ++#if 0 ++ if (!prStaRec->fgIsValid) ++ return NULL; ++#endif ++ ++ /* Obtain the RX BA Entry pointer */ ++ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[u4Tid]); ++ ++ /* Note: For each queued packet, prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST */ ++ if (prReorderQueParm) { ++ ++ if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) { ++ ++ prSwRfbListHead = (P_SW_RFB_T) ++ QUEUE_GET_HEAD(&(prReorderQueParm->rReOrderQue)); ++ prSwRfbListTail = (P_SW_RFB_T) ++ QUEUE_GET_TAIL(&(prReorderQueParm->rReOrderQue)); ++ ++ QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue)); ++ ++ } ++ } ++ ++ if (prSwRfbListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); ++ } ++ return prSwRfbListHead; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Enqueue TX packets ++* ++* \param[in] prMsduInfoListHead Pointer to the list of TX packets ++* ++* \return The freed packets, which are not enqueued ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_MSDU_INFO_T prMsduInfoReleaseList; ++ P_MSDU_INFO_T prCurrentMsduInfo; ++ P_MSDU_INFO_T prNextMsduInfo; ++ ++ P_STA_RECORD_T prStaRec; ++ QUE_T rNotEnqueuedQue; ++ P_QUE_T prTxQue = &rNotEnqueuedQue; ++ ++ UINT_8 ucPacketType; ++ UINT_8 ucTC; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ UINT_8 aucNextUP[WMM_AC_INDEX_NUM] = { 1 /* BEtoBK */ , 1 /*na */ , 0 /*VItoBE */ , 4 /*VOtoVI */ }; ++ ++ DBGLOG(QM, LOUD, "Enter qmEnqueueTxPackets\n"); ++ ++ ASSERT(prMsduInfoListHead); ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ { ++ /* UINT_32 i; */ ++ /* 4 <0> Update TC resource control related variables */ ++ /* Keep track of the queue length */ ++ if (--prQM->u4TimeToUpdateQueLen == 0) { /* -- only here */ ++ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; ++ qmUpdateAverageTxQueLen(prAdapter); ++ } ++ } ++#endif ++ ++ /* Push TX packets into STA_REC (for UNICAST) or prAdapter->rQM (for BMCAST) */ ++ prStaRec = NULL; ++ prMsduInfoReleaseList = NULL; ++ prCurrentMsduInfo = NULL; ++ QUEUE_INITIALIZE(&rNotEnqueuedQue); ++ prNextMsduInfo = prMsduInfoListHead; ++ ++ do { ++ P_BSS_INFO_T prBssInfo; ++ BOOLEAN fgCheckACMAgain; ++ ENUM_WMM_ACI_T eAci = WMM_AC_BE_INDEX; ++ ++ prCurrentMsduInfo = prNextMsduInfo; ++ prNextMsduInfo = QM_TX_GET_NEXT_MSDU_INFO(prCurrentMsduInfo); ++ ucTC = TC1_INDEX; ++ ++ /* 4 <1> Lookup the STA_REC index */ ++ /* The ucStaRecIndex will be set in this function */ ++ qmDetermineStaRecIndex(prAdapter, prCurrentMsduInfo); ++ ucPacketType = HIF_TX_PACKET_TYPE_DATA; ++ ++ STATS_ENV_REPORT_DETECT(prAdapter, prCurrentMsduInfo->ucStaRecIndex); ++ ++ DBGLOG(QM, LOUD, "***** ucStaRecIndex = %d *****\n", prCurrentMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prCurrentMsduInfo->ucNetworkType]); ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 0) ++ if (IS_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType)) { ++#else ++ /* force to send the loopback test packet */ ++ if (1) { ++ SET_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType); ++ prCurrentMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; ++ ucPacketType = HIF_TX_PKT_TYPE_HIF_LOOPBACK; ++#endif /* End of CONF_HIF_LOOPBACK_AUTO */ ++ ++ switch (prCurrentMsduInfo->ucStaRecIndex) { ++ case STA_REC_INDEX_BMCAST: ++ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; ++ ucTC = TC5_INDEX; ++#if 0 ++ if (prCurrentMsduInfo->ucNetworkType == NETWORK_TYPE_P2P_INDEX ++ && prCurrentMsduInfo->eSrc != TX_PACKET_MGMT) { ++ if (LINK_IS_EMPTY ++ (&prAdapter->rWifiVar. ++ arBssInfo[NETWORK_TYPE_P2P_INDEX].rStaRecOfClientList)) { ++ prTxQue = &rNotEnqueuedQue; ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_AP_BORADCAST_DROP); ++ } ++ } ++#endif ++ ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23); ++ break; ++ ++ case STA_REC_INDEX_NOT_FOUND: ++ ucTC = TC5_INDEX; ++ ++ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ ++ /* if the packet is the forward type. the packet should be freed */ ++ DBGLOG(QM, TRACE, "Forwarding packet but Sta is STA_REC_INDEX_NOT_FOUND\n"); ++ /* prTxQue = &rNotEnqueuedQue; */ ++ } ++ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_NO_STA_REC]; ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); ++ ++ break; ++ ++ default: ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prCurrentMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) { ++ DBGLOG(QM, ERROR, "prStaRec is NULL\n"); ++ break; ++ } ++ ASSERT(prStaRec->fgIsValid); ++ ++ if (prCurrentMsduInfo->ucUserPriority < 8) { ++ QM_DBG_CNT_INC(prQM, prCurrentMsduInfo->ucUserPriority + 15); ++ /* QM_DBG_CNT_15 *//* QM_DBG_CNT_16 *//* QM_DBG_CNT_17 *//* QM_DBG_CNT_18 */ ++ /* QM_DBG_CNT_19 *//* QM_DBG_CNT_20 *//* QM_DBG_CNT_21 *//* QM_DBG_CNT_22 */ ++ } ++ ++ eAci = WMM_AC_BE_INDEX; ++ do { ++ fgCheckACMAgain = FALSE; ++ if (!prStaRec->fgIsQoS) { ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; ++ ucTC = TC1_INDEX; ++ break; ++ } ++ ++ switch (prCurrentMsduInfo->ucUserPriority) { ++ case 1: ++ case 2: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC0]; ++ ucTC = TC0_INDEX; ++ eAci = WMM_AC_BK_INDEX; ++ break; ++ case 0: ++ case 3: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; ++ ucTC = TC1_INDEX; ++ eAci = WMM_AC_BE_INDEX; ++ break; ++ case 4: ++ case 5: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC2]; ++ ucTC = TC2_INDEX; ++ eAci = WMM_AC_VI_INDEX; ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ prQM->u4TxNumOfVi++; ++#endif ++ break; ++ case 6: ++ case 7: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC3]; ++ ucTC = TC3_INDEX; ++ eAci = WMM_AC_VO_INDEX; ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ prQM->u4TxNumOfVo++; ++#endif ++ break; ++ default: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; ++ ucTC = TC1_INDEX; ++ eAci = WMM_AC_BE_INDEX; ++ ASSERT(0); ++ break; ++ } ++ if (prBssInfo->arACQueParms[eAci].fgIsACMSet && eAci ++ != WMM_AC_BK_INDEX) { ++ prCurrentMsduInfo->ucUserPriority = aucNextUP[eAci]; ++ fgCheckACMAgain = TRUE; ++ } ++ } while (fgCheckACMAgain); ++ ++ /* LOG_FUNC ("QoS %u UP %u TC %u", */ ++ /* prStaRec->fgIsQoS,prCurrentMsduInfo->ucUserPriority, ucTC); */ ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ /* ++ In TDLS or AP mode, peer maybe enter "sleep mode". ++ ++ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, ++ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets ++ u4TimeToAdjustTcResource = 3, ++ then we will adjust TC resouce for VI or VO. ++ ++ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, ++ we will to wait about 12 seconds to collect 180 packets. ++ but the test time is only 20 seconds. ++ */ ++ if ((prQM->u4TxNumOfVi == 10) || (prQM->u4TxNumOfVo == 10)) { ++ /* force to do TC resouce update */ ++ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN; ++ prQM->u4TimeToAdjustTcResource = 1; ++ } ++#endif ++#if ARP_MONITER_ENABLE ++ if (IS_STA_IN_AIS(prStaRec) && prCurrentMsduInfo->eSrc == TX_PACKET_OS) ++ qmDetectArpNoResponse(prAdapter, prCurrentMsduInfo); ++#endif ++ ++ break; /*default */ ++ } /* switch (prCurrentMsduInfo->ucStaRecIndex) */ ++ ++ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ if (prTxQue->u4NumElem > 32) { ++ DBGLOG(QM, WARN, ++ "Drop the Packet for full Tx queue (forwarding) Bss %u\n", ++ prCurrentMsduInfo->ucNetworkType); ++ prTxQue = &rNotEnqueuedQue; ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_FORWARD_OVERFLOW_DROP); ++ } ++ } ++ ++ } else { ++ ++ DBGLOG(QM, WARN, "Drop the Packet for inactive Bss %u\n", prCurrentMsduInfo->ucNetworkType); ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31); ++ prTxQue = &rNotEnqueuedQue; ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); ++ } ++ ++ /* 4 <3> Fill the MSDU_INFO for constructing HIF TX header */ ++ ++ /* TODO: Fill MSDU_INFO according to the network type, ++ * EtherType, and STA status (for PS forwarding control). ++ */ ++ ++ /* Note that the Network Type Index and STA_REC index are determined in ++ * qmDetermineStaRecIndex(prCurrentMsduInfo). ++ */ ++ QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(prCurrentMsduInfo, /* MSDU_INFO ptr */ ++ ucTC, /* TC tag */ ++ ucPacketType, /* Packet Type */ ++ 0, /* Format ID */ ++ prCurrentMsduInfo->fgIs802_1x, /* Flag 802.1x */ ++ prCurrentMsduInfo->fgIs802_11, /* Flag 802.11 */ ++ 0, /* PAL LLH */ ++ 0, /* ACL SN */ ++ PS_FORWARDING_TYPE_NON_PS, /* PS Forwarding Type */ ++ 0 /* PS Session ID */ ++ ); ++ ++ /* 4 <4> Enqueue the packet to different AC queue (max 5 AC queues) */ ++ QUEUE_INSERT_TAIL(prTxQue, (P_QUE_ENTRY_T) prCurrentMsduInfo); ++ ++ if (prTxQue != &rNotEnqueuedQue) { ++ prQM->u4EnqeueuCounter++; ++ prQM->au4ResourceWantedCounter[ucTC]++; ++ } ++ if (prStaRec) ++ prStaRec->u4EnqeueuCounter++; ++ ++#if QM_TC_RESOURCE_EMPTY_COUNTER ++ { ++ P_TX_CTRL_T prTxCtrl = &prAdapter->rTxCtrl; ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] == 0) { ++ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC]++; ++ /* ++ DBGLOG(QM, TRACE, ("TC%d Q Empty Count: [%d]%ld\n", ++ ucTC, ++ prCurrentMsduInfo->ucNetworkType, ++ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC])); ++ */ ++ } ++ ++ } ++#endif ++ ++#if QM_TEST_MODE ++ if (++prQM->u4PktCount == QM_TEST_TRIGGER_TX_COUNT) { ++ prQM->u4PktCount = 0; ++ qmTestCases(prAdapter); ++ } ++#endif ++ ++ DBGLOG(QM, LOUD, "Current queue length = %u\n", prTxQue->u4NumElem); ++ } while (prNextMsduInfo); ++ ++ if (QUEUE_IS_NOT_EMPTY(&rNotEnqueuedQue)) { ++ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rNotEnqueuedQue), NULL); ++ prMsduInfoReleaseList = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rNotEnqueuedQue); ++ } ++ ++ return prMsduInfoReleaseList; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Determine the STA_REC index for a packet ++* ++* \param[in] prMsduInfo Pointer to the packet ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_32 i; ++ ++ P_STA_RECORD_T prTempStaRec; ++ /* P_QUE_MGT_T prQM = &prAdapter->rQM; */ ++ ++ prTempStaRec = NULL; ++ ++ ASSERT(prMsduInfo); ++ ++ /* 4 <1> DA = BMCAST */ ++ if (IS_BMCAST_MAC_ADDR(prMsduInfo->aucEthDestAddr)) { ++ /* For intrastructure mode and P2P (playing as a GC), BMCAST frames shall be sent to the AP. ++ * FW shall take care of this. The host driver is not able to distinguish these cases. */ ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; ++ DBGLOG(QM, LOUD, "TX with DA = BMCAST\n"); ++ return; ++ } ++#if (CFG_SUPPORT_TDLS == 1) ++ /* Check if the peer is TDLS one */ ++ if (TdlsexStaRecIdxGet(prAdapter, prMsduInfo) == TDLS_STATUS_SUCCESS) ++ return; /* find a TDLS record */ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* 4 <2> Check if an AP STA is present */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ ++ if ((prTempStaRec->ucNetTypeIndex == prMsduInfo->ucNetworkType) ++ && (prTempStaRec->fgIsAp) ++ && (prTempStaRec->fgIsValid)) { ++ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; ++ return; ++ } ++ } ++ ++ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ if (prTempStaRec->fgIsValid) { ++ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prMsduInfo->aucEthDestAddr)) { ++ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; ++ return; ++ } ++ } ++ } ++ ++ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; ++ DBGLOG(QM, LOUD, "QM: TX with STA_REC_INDEX_NOT_FOUND\n"); ++ ++#if (QM_TEST_MODE && QM_TEST_FAIR_FORWARDING) ++ prMsduInfo->ucStaRecIndex = (UINT_8) prQM->u4CurrentStaRecIndexToEnqueue; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dequeue TX packets from a STA_REC for a particular TC ++* ++* \param[out] prQue The queue to put the dequeued packets ++* \param[in] ucTC The TC index (TC0_INDEX to TC5_INDEX) ++* \param[in] ucMaxNum The maximum amount of dequeued packets ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, ++ OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucCurrentQuota, IN UINT_8 ucTotalQuota) ++{ ++ ++#if QM_FORWARDING_FAIRNESS ++ UINT_32 i; /* Loop for */ ++ ++ PUINT_32 pu4HeadStaRecIndex; /* The Head STA index */ ++ PUINT_32 pu4HeadStaRecForwardCount; /* The total forwarded packets for the head STA */ ++ ++ P_STA_RECORD_T prStaRec; /* The current focused STA */ ++ P_BSS_INFO_T prBssInfo; /* The Bss for current focused STA */ ++ P_QUE_T prCurrQueue; /* The current TX queue to dequeue */ ++ P_MSDU_INFO_T prDequeuedPkt; /* The dequeued packet */ ++ ++ UINT_32 u4ForwardCount; /* To remember the total forwarded packets for a STA */ ++ UINT_32 u4MaxForwardCount; /* The maximum number of packets a STA can forward */ ++ UINT_32 u4Resource; /* The TX resource amount */ ++ ++ BOOLEAN fgChangeHeadSta; /* Whether a new head STA shall be determined at the end of the function */ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ PUINT_8 pucFreeQuota = NULL; ++#if CFG_ENABLE_WIFI_DIRECT ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; ++ /*NFC Beam + Indication */ ++#endif ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); ++ ++ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); ++ ++ if (!ucCurrentQuota) { ++ prQM->au4DequeueNoTcResourceCounter[ucTC]++; ++ DBGLOG(TX, LOUD, "@@@@@ TC = %u ucCurrentQuota = %u @@@@@\n", ucTC, ucCurrentQuota); ++ return; ++ } ++ ++ u4Resource = ucCurrentQuota; ++ ++ /* 4 <1> Determine the head STA */ ++ /* The head STA shall be an active STA */ ++ ++ pu4HeadStaRecIndex = &(prQM->au4HeadStaRecIndex[ucTC]); ++ pu4HeadStaRecForwardCount = &(prQM->au4ForwardCount[ucTC]); ++ ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Init Head STA = %u Resource = %u\n", ++ ucTC, *pu4HeadStaRecIndex, u4Resource); ++ ++ /* From STA[x] to STA[x+1] to STA[x+2] to ... to STA[x] */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD + 1; i++) { ++ prStaRec = &prAdapter->arStaRec[(*pu4HeadStaRecIndex)]; ++ ASSERT(prStaRec); ++ ++ /* Only Data frame (1x was not included) will be queued in */ ++ if (prStaRec->fgIsValid) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); ++ ++ /* Determine how many packets the head STA is allowed to send in a round */ ++ ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_25); ++ u4MaxForwardCount = ucTotalQuota; ++#if CFG_ENABLE_WIFI_DIRECT ++ ++ pucFreeQuota = NULL; ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ ++ /* u4MaxForwardCount = ucTotalQuota; */ ++ /* Per STA flow control when STA in PS mode */ ++ /* The PHASE 1: only update from ucFreeQuota (now) */ ++ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ ++ /* aucFreeQuotaPerQueue[] */ ++ /* NOTE: other method to set u4Resource */ ++ ++ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported ++ /* && prAdapter->rWifiVar.fgSupportQoS ++ && prAdapter->rWifiVar.fgSupportUAPSD */) { ++ ++ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; ++ } else { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } else { ++ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } /* fgIsInPS */ ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++ /*NFC Beam + Indication */ ++ ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ if ((prChnlReqInfo->NFC_BEAM != 1) && ++ (u4MaxForwardCount > prBssInfo->ucBssFreeQuota)) ++ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; ++ } else { ++ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) ++ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* Determine whether the head STA can continue to forward packets in this round */ ++ if ((*pu4HeadStaRecForwardCount) < u4MaxForwardCount) ++ break; ++ ++ } /* prStaRec->fgIsValid */ ++ else { ++ /* The current Head STA has been deactivated, so search for a new head STA */ ++ prStaRec = NULL; ++ prBssInfo = NULL; ++ (*pu4HeadStaRecIndex)++; ++ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; ++ ++ /* Reset the forwarding count before searching (since this is for a new selected STA) */ ++ (*pu4HeadStaRecForwardCount) = 0; ++ } ++ } /* i < CFG_NUM_OF_STA_RECORD + 1 */ ++ ++ /* All STA_RECs are inactive, so exit */ ++ if (!prStaRec) { ++ /* Under concurrent, it is possible that there is no candidcated STA. */ ++ /* DBGLOG(TX, EVENT, ("All STA_RECs are inactive\n")); */ ++ return; ++ } ++ ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Round Head STA = %u\n", ucTC, *pu4HeadStaRecIndex); ++ ++ /* 4 <2> Dequeue packets from the head STA */ ++ ++ prCurrQueue = &prStaRec->arTxQueue[ucTC]; ++ prDequeuedPkt = NULL; ++ fgChangeHeadSta = FALSE; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ if (pucFreeQuota != NULL) ++ TdlsexTxQuotaCheck(prAdapter->prGlueInfo, prStaRec, *pucFreeQuota); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ while (prCurrQueue) { ++ ++#if QM_DEBUG_COUNTER ++ ++ if (ucTC <= TC4_INDEX) { ++ if (QUEUE_IS_EMPTY(prCurrQueue)) { ++ QM_DBG_CNT_INC(prQM, ucTC); ++ /* QM_DBG_CNT_00 *//* QM_DBG_CNT_01 *//* QM_DBG_CNT_02 */ ++ /* QM_DBG_CNT_03 *//* QM_DBG_CNT_04 */ ++ } ++ if (u4Resource == 0) { ++ QM_DBG_CNT_INC(prQM, ucTC + 5); ++ /* QM_DBG_CNT_05 *//* QM_DBG_CNT_06 *//* QM_DBG_CNT_07 */ ++ /* QM_DBG_CNT_08 *//* QM_DBG_CNT_09 */ ++ } ++ if (((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { ++ QM_DBG_CNT_INC(prQM, ucTC + 10); ++ /* QM_DBG_CNT_10 *//* QM_DBG_CNT_11 *//* QM_DBG_CNT_12 */ ++ /* QM_DBG_CNT_13 *//* QM_DBG_CNT_14 */ ++ } ++ } ++#endif ++ ++ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ ++ if (QUEUE_IS_EMPTY(prCurrQueue) || ((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { ++ fgChangeHeadSta = TRUE; ++ break; ++ } else if (u4Resource == 0) { ++#if (CFG_SUPPORT_STATISTICS == 1) ++ prStaRec->u4NumOfNoTxQuota++; ++#endif /* CFG_SUPPORT_STATISTICS */ ++ break; ++ } ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ prStaRec->u4DeqeueuCounter++; ++ prQM->u4DequeueCounter++; ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ if (prDequeuedPkt != NULL) { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ UINT8 *pkt = prSkb->data; ++ UINT16 u2Identifier; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ DBGLOG(QM, LOUD, " %d\n", u2Identifier); ++ } ++ } ++#endif ++#if DBG && 0 ++ LOG_FUNC("Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prDequeuedPkt->ucTC, ++ prCurrQueue->u4NumElem, ++ prDequeuedPkt->ucNetworkType, ++ prDequeuedPkt->ucMacHeaderLength, ++ prDequeuedPkt->u2FrameLength, ++ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11); ++ ++ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); ++ ++#if LINUX ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ ++ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); ++ } ++#endif ++ ++#endif ++ ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ if (!QUEUE_IS_EMPTY(prCurrQueue)) { ++ /* XXX: check all queues for STA */ ++ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; ++ } ++ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ u4Resource--; ++ (*pu4HeadStaRecForwardCount)++; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ if ((pucFreeQuota) && (*pucFreeQuota > 0)) ++ *pucFreeQuota = *pucFreeQuota - 1; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (prBssInfo->ucBssFreeQuota > 0) ++ prBssInfo->ucBssFreeQuota--; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ } ++ ++ if (*pu4HeadStaRecForwardCount) { ++ DBGLOG(QM, LOUD, ++ "TC = %u Round Head STA = %u, u4HeadStaRecForwardCount = %u\n", ucTC, *pu4HeadStaRecIndex, ++ (*pu4HeadStaRecForwardCount)); ++ } ++#if QM_BURST_END_INFO_ENABLED ++ /* Let FW know which packet is the last one dequeued from the STA */ ++ if (prDequeuedPkt) ++ prDequeuedPkt->fgIsBurstEnd = TRUE; ++#endif ++ ++ /* 4 <3> Dequeue from the other STAs if there is residual TX resource */ ++ ++ /* Check all of the STAs to continue forwarding packets (including the head STA) */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ /* Break in case no reasource is available */ ++ if (u4Resource == 0) { ++ prQM->au4DequeueNoTcResourceCounter[ucTC]++; ++ break; ++ } ++ ++ /* The current head STA will be examined when i = CFG_NUM_OF_STA_RECORD-1 */ ++ prStaRec = &prAdapter->arStaRec[((*pu4HeadStaRecIndex) + i + 1) % CFG_NUM_OF_STA_RECORD]; ++ ASSERT(prStaRec); ++ ++ if (prStaRec->fgIsValid) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); ++ ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Sharing STA = %u Resource = %u\n", ++ ucTC, prStaRec->ucIndex, u4Resource); ++ ++ prCurrQueue = &prStaRec->arTxQueue[ucTC]; ++ u4ForwardCount = 0; ++ u4MaxForwardCount = ucTotalQuota; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ pucFreeQuota = NULL; ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ ++ /* u4MaxForwardCount = ucTotalQuota; */ ++ /* Per STA flow control when STA in PS mode */ ++ /* The PHASE 1: only update from ucFreeQuota (now) */ ++ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ ++ /* aucFreeQuotaPerQueue[] */ ++ /* NOTE: other method to set u4Resource */ ++ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported ++ /* && prAdapter->rWifiVar.fgSupportQoS ++ && prAdapter->rWifiVar.fgSupportUAPSD */) { ++ ++ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; ++ } else { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } else { ++ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) ++ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ } /* prStaRec->fgIsValid */ ++ else { ++ prBssInfo = NULL; ++ /* Invalid STA, so check the next STA */ ++ continue; ++ } ++ ++ while (prCurrQueue) { ++ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ ++ if ((u4Resource == 0) || QUEUE_IS_EMPTY(prCurrQueue) || (u4ForwardCount >= u4MaxForwardCount)) ++ break; ++ ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ ++#if DBG && 0 ++ DBGLOG(QM, LOUD, "Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prDequeuedPkt->ucTC, ++ prCurrQueue->u4NumElem, ++ prDequeuedPkt->ucNetworkType, ++ prDequeuedPkt->ucMacHeaderLength, ++ prDequeuedPkt->u2FrameLength, ++ prDequeuedPkt->ucPacketType, ++ prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11)); ++ ++ DBGLOG(QM, LOUD, "Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); ++ ++#if LINUX ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ ++ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); ++ } ++#endif ++ ++#endif ++ ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ if (!QUEUE_IS_EMPTY(prCurrQueue)) ++ /* more data field ? */ ++ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; ++ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ if (prStaRec) ++ prStaRec->u4DeqeueuCounter++; ++ prQM->u4DequeueCounter++; ++ u4Resource--; ++ u4ForwardCount++; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ ASSERT(pucFreeQuota); ++ ASSERT(*pucFreeQuota > 0); ++ if (*pucFreeQuota > 0) ++ *pucFreeQuota = *pucFreeQuota - 1; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (prBssInfo->ucBssFreeQuota > 0) ++ prBssInfo->ucBssFreeQuota--; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ } ++ ++#if QM_BURST_END_INFO_ENABLED ++ /* Let FW know which packet is the last one dequeued from the STA */ ++ if (u4ForwardCount) ++ prDequeuedPkt->fgIsBurstEnd = TRUE; ++#endif ++ } ++ ++ if (fgChangeHeadSta) { ++ (*pu4HeadStaRecIndex)++; ++ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; ++ (*pu4HeadStaRecForwardCount) = 0; ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Scheduled Head STA = %u Left Resource = %u\n", ++ ucTC, (*pu4HeadStaRecIndex), u4Resource); ++ } ++ ++/***************************************************************************************/ ++#else ++ UINT_8 ucStaRecIndex; ++ P_STA_RECORD_T prStaRec; ++ P_QUE_T prCurrQueue; ++ UINT_8 ucPktCount; ++ P_MSDU_INFO_T prDequeuedPkt; ++ ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); ++ ++ if (ucCurrentQuota == 0) ++ return; ++ /* 4 <1> Determine the queue index and the head STA */ ++ ++ /* The head STA */ ++ ucStaRecIndex = 0; /* TODO: Get the current head STA */ ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ /* The queue to pull out packets */ ++ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); ++ prCurrQueue = &prStaRec->arTxQueue[ucTC]; ++ ++ ucPktCount = ucCurrentQuota; ++ prDequeuedPkt = NULL; ++ ++ /* 4 <2> Dequeue packets for the head STA */ ++ while (TRUE) { ++ if (!(prStaRec->fgIsValid) || ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) { ++ break; ++ ++ } else { ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ /* DbgPrint("QM: Remove Queue Head, TC= %d\n", prDequeuedPkt->ucTC); */ ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ ucPktCount--; ++ } ++ } ++ ++ /* DbgPrint("QM: Remaining number of queued packets = %d\n", prCurrQueue->u4NumElem); */ ++ ++#if QM_BURST_END_INFO_ENABLED ++ if (prDequeuedPkt) ++ prDequeuedPkt->fgIsBurstEnd = TRUE; ++#endif ++ ++ /* 4 <3> Update scheduling info */ ++ /* TODO */ ++ ++ /* 4 <4> Utilize the remainaing TX opportunities for non-head STAs */ ++ /* TODO */ ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dequeue TX packets from a per-Type-based Queue for a particular TC ++* ++* \param[out] prQue The queue to put the dequeued packets ++* \param[in] ucTC The TC index (Shall always be TC5_INDEX) ++* \param[in] ucMaxNum The maximum amount of dequeued packets ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum) ++{ ++ /* UINT_8 ucQueIndex; */ ++ /* UINT_8 ucStaRecIndex; */ ++ P_BSS_INFO_T prBssInfo; ++ P_BSS_INFO_T parBssInfo; ++ P_QUE_T prCurrQueue; ++ UINT_8 ucPktCount; ++ P_MSDU_INFO_T prDequeuedPkt; ++ P_MSDU_INFO_T prBurstEndPkt; ++ QUE_T rMergeQue; ++ P_QUE_T prMergeQue; ++ P_QUE_MGT_T prQM; ++ ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerTypeQueues (TC = %d, Max = %d)\n", ucTC, ucMaxNum); ++ ++ /* TC5: Broadcast/Multicast data packets */ ++ ASSERT(ucTC == TC5_INDEX); ++ ++ if (ucMaxNum == 0) ++ return; ++ ++ prQM = &prAdapter->rQM; ++ /* 4 <1> Determine the queue */ ++ ++ prCurrQueue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; ++ ucPktCount = ucMaxNum; ++ prDequeuedPkt = NULL; ++ prBurstEndPkt = NULL; ++ ++ parBssInfo = prAdapter->rWifiVar.arBssInfo; ++ ++ QUEUE_INITIALIZE(&rMergeQue); ++ prMergeQue = &rMergeQue; ++ ++ /* 4 <2> Dequeue packets */ ++ while (TRUE) { ++ if (ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) ++ break; ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ ASSERT(prDequeuedPkt->ucNetworkType < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &parBssInfo[prDequeuedPkt->ucNetworkType]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo)) { ++ if (!prBssInfo->fgIsNetAbsent) { ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ prQM->u4DequeueCounter++; ++ prBurstEndPkt = prDequeuedPkt; ++ ucPktCount--; ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_26); ++#if DBG && 0 ++ LOG_FUNC ++ ("DeqType TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prDequeuedPkt->ucTC, prCurrQueue->u4NumElem, prDequeuedPkt->ucNetworkType, ++ prDequeuedPkt->ucMacHeaderLength, prDequeuedPkt->u2FrameLength, ++ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, ++ prDequeuedPkt->fgIs802_11); ++ ++ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); ++ ++#if LINUX ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ ++ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); ++ } ++#endif ++ ++#endif ++ } else { ++ QUEUE_INSERT_TAIL(prMergeQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ } ++ } else { ++ QM_TX_SET_NEXT_MSDU_INFO(prDequeuedPkt, NULL); ++ wlanProcessQueuedMsduInfo(prAdapter, prDequeuedPkt); ++ } ++ } ++ ++ if (QUEUE_IS_NOT_EMPTY(prMergeQue)) { ++ QUEUE_CONCATENATE_QUEUES(prMergeQue, prCurrQueue); ++ QUEUE_MOVE_ALL(prCurrQueue, prMergeQue); ++ if (QUEUE_GET_TAIL(prCurrQueue)) ++ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(prCurrQueue), NULL); ++ } ++#if QM_BURST_END_INFO_ENABLED ++ if (prBurstEndPkt) ++ prBurstEndPkt->fgIsBurstEnd = TRUE; ++#endif ++} /* qmDequeueTxPacketsFromPerTypeQueues */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dequeue TX packets to send to HIF TX ++* ++* \param[in] prTcqStatus Info about the maximum amount of dequeued packets ++* ++* \return The list of dequeued TX packets ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus) ++{ ++ ++ INT32 i; ++ P_MSDU_INFO_T prReturnedPacketListHead; ++ QUE_T rReturnedQue; ++ ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPackets\n"); ++ ++ QUEUE_INITIALIZE(&rReturnedQue); ++ ++ prReturnedPacketListHead = NULL; ++ ++ /* dequeue packets from different AC queue based on available aucFreeBufferCount */ ++ /* TC0 to TC4: AC0~AC3, 802.1x (commands packets are not handled by QM) */ ++ for (i = TC4_INDEX; i >= TC0_INDEX; i--) { ++ DBGLOG(QM, LOUD, "Dequeue packets from Per-STA queue[%d]\n", i); ++ ++ /* ++ in the function, we will re-calculate the ucFreeQuota. ++ If any packet with any priority for the station will be sent, ucFreeQuota -- ++ ++ Note1: ucFreeQuota will be decrease only when station is in power save mode. ++ In active mode, we will sent the packet to the air directly. ++ ++ if(prStaRec->fgIsInPS && (ucTC!=TC4_INDEX)) { ++ ASSERT(pucFreeQuota); ++ ASSERT(*pucFreeQuota>0); ++ if ((pucFreeQuota) && (*pucFreeQuota>0)) { ++ *pucFreeQuota = *pucFreeQuota - 1; ++ } ++ } ++ ++ Note2: maximum queued number for a station is 10, TXM_MAX_BUFFER_PER_STA_DEF in fw ++ i.e. default prStaRec->ucFreeQuota = 10 ++ ++ Note3: In qmUpdateFreeQuota(), we will adjust ++ ucFreeQuotaForNonDelivery = ucFreeQuota>>1; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ */ ++ qmDequeueTxPacketsFromPerStaQueues(prAdapter, ++ &rReturnedQue, ++ (UINT_8) i, ++ prTcqStatus->aucFreeBufferCount[i], /* maximum dequeue number */ ++ prTcqStatus->aucMaxNumOfBuffer[i]); ++ ++ /* The aggregate number of dequeued packets */ ++ DBGLOG(QM, LOUD, "DQA)[%u](%u)\n", i, rReturnedQue.u4NumElem); ++ } ++ ++ /* TC5 (BMCAST or STA-NOT-FOUND packets) */ ++ qmDequeueTxPacketsFromPerTypeQueues(prAdapter, ++ &rReturnedQue, TC5_INDEX, prTcqStatus->aucFreeBufferCount[TC5_INDEX] ++ ); ++ ++ DBGLOG(QM, LOUD, "Current total number of dequeued packets = %u\n", rReturnedQue.u4NumElem); ++ ++ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) { ++ prReturnedPacketListHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rReturnedQue); ++ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); ++ } ++ ++ return prReturnedPacketListHead; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Adjust the TC quotas according to traffic demands ++* ++* \param[out] prTcqAdjust The resulting adjustment ++* \param[in] prTcqStatus Info about the current TC quotas and counters ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus) ++{ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ UINT_32 i; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* Must reset */ ++ for (i = 0; i < TC_NUM; i++) ++ prTcqAdjust->acVariation[i] = 0; ++ ++ /* 4 <1> If TC resource is not just adjusted, exit directly */ ++ if (!prQM->fgTcResourcePostAnnealing) ++ return; ++ /* 4 <2> Adjust TcqStatus according to the updated prQM->au4CurrentTcResource */ ++ else { ++ INT_32 i4TotalExtraQuota = 0; ++ INT_32 ai4ExtraQuota[TC_NUM]; ++ BOOLEAN fgResourceRedistributed = TRUE; ++ ++ /* Obtain the free-to-distribute resource */ ++ for (i = 0; i < TC_NUM; i++) { ++ ai4ExtraQuota[i] = ++ (INT_32) prTcqStatus->aucMaxNumOfBuffer[i] - (INT_32) prQM->au4CurrentTcResource[i]; ++ ++ if (ai4ExtraQuota[i] > 0) { /* The resource shall be reallocated to other TCs */ ++ ++ if (ai4ExtraQuota[i] > prTcqStatus->aucFreeBufferCount[i]) { ++ /* ++ we have residunt TC resources for the TC: ++ EX: aucMaxNumOfBuffer[] = 20, au4CurrentTcResource[] = 5 ++ ai4ExtraQuota[] = 15, aucFreeBufferCount[] = 10 ++ ++ so ai4ExtraQuota[] = aucFreeBufferCount[] = 10 ++ because we available TC resources actually is 10, not 20 ++ */ ++ ai4ExtraQuota[i] = prTcqStatus->aucFreeBufferCount[i]; ++ ++ /* ++ FALSE means we can re-do TC resource adjustment in tx done ++ at next time, maybe more tx done is finished ++ */ ++ fgResourceRedistributed = FALSE; ++ } ++ ++ /* accumulate current all available TC resources */ ++ i4TotalExtraQuota += ai4ExtraQuota[i]; ++ ++ /* deduce unused TC resources for the TC */ ++ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); ++ } ++ } ++ ++ /* Distribute quotas to TCs which need extra resource according to prQM->au4CurrentTcResource */ ++ for (i = 0; i < TC_NUM; i++) { ++ if (ai4ExtraQuota[i] < 0) { ++ ++ /* The TC needs extra resources */ ++ if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) { ++ /* the number of needed extra resources is larger than total available */ ++ ai4ExtraQuota[i] = (-i4TotalExtraQuota); ++ ++ /* wait for next tx done to do adjustment */ ++ fgResourceRedistributed = FALSE; ++ } ++ ++ /* decrease the total available */ ++ i4TotalExtraQuota += ai4ExtraQuota[i]; ++ ++ /* mark to increase TC resources for the TC */ ++ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); ++ } ++ } ++ ++ /* In case some TC is waiting for TX Done, continue to adjust TC quotas upon TX Done */ ++ ++ /* ++ if fgResourceRedistributed == TRUE, it means we will adjust at this time so ++ we need to re-adjust TC resources (fgTcResourcePostAnnealing = FALSE). ++ */ ++ prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed); ++ ++#if QM_PRINT_TC_RESOURCE_CTRL ++ DBGLOG(QM, LOUD, "QM: Curr Quota [0]=%u [1]=%u [2]=%u [3]=%u [4]=%u [5]=%u\n", ++ prTcqStatus->aucFreeBufferCount[0], ++ prTcqStatus->aucFreeBufferCount[1], ++ prTcqStatus->aucFreeBufferCount[2], ++ prTcqStatus->aucFreeBufferCount[3], ++ prTcqStatus->aucFreeBufferCount[4], prTcqStatus->aucFreeBufferCount[5] ++ )); ++#endif ++ } ++ ++#else ++ UINT_32 i; ++ ++ for (i = 0; i < TC_NUM; i++) ++ prTcqAdjust->acVariation[i] = 0; ++ ++#endif ++} ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Update the average TX queue length for the TC resource control mechanism ++* ++* \param (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter) ++{ ++ INT_32 u4CurrQueLen, i, k; ++ P_STA_RECORD_T prStaRec; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* 4 <1> Update the queue lengths for TC0 to TC3 (skip TC4) and TC5 */ ++ /* use moving average algorithm to calculate au4AverageQueLen for every TC queue */ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES - 1; i++) { ++ u4CurrQueLen = 0; ++ ++ for (k = 0; k < CFG_NUM_OF_STA_RECORD; k++) { ++ prStaRec = &prAdapter->arStaRec[k]; ++ ASSERT(prStaRec); ++ ++ /* If the STA is activated, get the queue length */ ++ if (prStaRec->fgIsValid && ++ (!prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].fgIsNetAbsent) ++ ) { ++ ++ u4CurrQueLen += (prStaRec->arTxQueue[i].u4NumElem); ++ } ++ } ++ ++ if (prQM->au4AverageQueLen[i] == 0) { ++ prQM->au4AverageQueLen[i] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); /* *8 */ ++ } else { ++ /* len => len - len/8 = 7/8 * len + new len */ ++ prQM->au4AverageQueLen[i] -= (prQM->au4AverageQueLen[i] >> QM_QUE_LEN_MOVING_AVE_FACTOR); ++ prQM->au4AverageQueLen[i] += (u4CurrQueLen); ++ } ++ ++ } ++ ++ /* Update the queue length for TC5 (BMCAST) */ ++ u4CurrQueLen = prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST].u4NumElem; ++ ++ if (prQM->au4AverageQueLen[TC_NUM - 1] == 0) { ++ prQM->au4AverageQueLen[TC_NUM - 1] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); ++ } else { ++ prQM->au4AverageQueLen[TC_NUM - 1] -= ++ (prQM->au4AverageQueLen[TC_NUM - 1] >> QM_QUE_LEN_MOVING_AVE_FACTOR); ++ prQM->au4AverageQueLen[TC_NUM - 1] += (u4CurrQueLen); ++ } ++ ++ /* 4 <2> Adjust TC resource assignment every 3 times */ ++ /* Check whether it is time to adjust the TC resource assignment */ ++ if (--prQM->u4TimeToAdjustTcResource == 0) { /* u4TimeToAdjustTcResource = 3 */ ++ ++ /* The last assignment has not been completely applied */ ++ if (prQM->fgTcResourcePostAnnealing) { ++ /* Upon the next qmUpdateAverageTxQueLen function call, do this check again */ ++ ++ /* wait for next time to do qmReassignTcResource */ ++ prQM->u4TimeToAdjustTcResource = 1; ++ } else { /* The last assignment has been applied */ ++ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; ++ qmReassignTcResource(prAdapter); ++ } ++ } ++ ++ /* Debug */ ++#if QM_PRINT_TC_RESOURCE_CTRL ++ for (i = 0; i < TC_NUM; i++) { ++ if (QM_GET_TX_QUEUE_LEN(prAdapter, i) >= 100) { ++ DBGLOG(QM, LOUD, "QM: QueLen [%u %u %u %u %u %u]\n", ++ QM_GET_TX_QUEUE_LEN(prAdapter, 0), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 1), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 2), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 3), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 4), QM_GET_TX_QUEUE_LEN(prAdapter, 5) ++ )); ++ break; ++ } ++ } ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Assign TX resource for each TC according to TX queue length and current assignment ++* ++* \param (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter) ++{ ++ INT_32 i4TotalResourceDemand = 0; ++ UINT_32 u4ResidualResource = 0; ++ UINT_32 i; ++ INT_32 ai4PerTcResourceDemand[TC_NUM]; ++ UINT_32 u4ShareCount = 0; ++ UINT_32 u4Share = 0; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* Note: After the new assignment is obtained, set prQM->fgTcResourcePostAnnealing to TRUE to ++ * start the TC-quota adjusting procedure, which will be invoked upon every TX Done ++ */ ++ /* tx done -> nicProcessTxInterrupt() -> nicTxAdjustTcq() ++ * -> qmAdjustTcQuotas() -> check fgTcResourcePostAnnealing */ ++ ++ /* 4 <1> Determine the demands */ ++ /* Determine the amount of extra resource to fulfill all of the demands */ ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4, which is not adjustable */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ /* ++ Define: extra_demand = average que_length (includes all station records) + ++ min_reserved_quota - ++ current available TC resources ++ ++ extra_demand means we need extra TC resources to transmit; other TCs can ++ borrow their resources to us? ++ */ ++ ai4PerTcResourceDemand[i] = ++ ((UINT_32) (QM_GET_TX_QUEUE_LEN(prAdapter, i)) + ++ prQM->au4MinReservedTcResource[i] - prQM->au4CurrentTcResource[i]); ++ ++ /* If there are queued packets, allocate extra resource for the TC (for TCP consideration) */ ++ if (QM_GET_TX_QUEUE_LEN(prAdapter, i)) ++ ai4PerTcResourceDemand[i] += QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY; /* 0 */ ++ ++ /* ++ accumulate all needed extra TC resources ++ maybe someone need + resource, maybe someone need - resource ++ */ ++ i4TotalResourceDemand += ai4PerTcResourceDemand[i]; ++ } ++ ++ /* 4 <2> Case 1: Demand <= Total Resource */ ++ if (i4TotalResourceDemand <= 0) { ++ /* 4 <2.1> Satisfy every TC */ ++ /* total TC resources are enough, no extra TC resources is needed */ ++ ++ /* adjust used TC resources to average TC resources + min reserve TC resources */ ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4 (not adjustable) */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ /* ++ the number of resources that one TC releases can be used for ++ other TCs ++ ++ EX: TC0 au4CurrentTcResource[0] = 10 ai4PerTcResourceDemand[0] = -5 ++ TC1 au4CurrentTcResource[1] = 5 ai4PerTcResourceDemand[0] = +5 ++ => TC0 au4CurrentTcResource[0] = 10 + (-5) = 5 ++ TC1 au4CurrentTcResource[1] = 5 + (+5) = 10 ++ */ ++ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; ++ } ++ ++ /* 4 <2.2> Share the residual resource evenly */ ++ u4ShareCount = (TC_NUM - 1); /* 5, excluding TC4 */ ++ ++ /* ++ EX: i4TotalResourceDemand = -10 ++ means we have 10 available resources can be used. ++ */ ++ u4ResidualResource = (UINT_32) (-i4TotalResourceDemand); ++ u4Share = (u4ResidualResource / u4ShareCount); ++ ++ /* share available TC resources to all TCs averagely */ ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4 (not adjustable) */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ /* allocate residual average resources to the TC */ ++ prQM->au4CurrentTcResource[i] += u4Share; ++ ++ /* Every TC is fully satisfied so no need extra resources */ ++ ai4PerTcResourceDemand[i] = 0; ++ ++ /* decrease the allocated resources */ ++ u4ResidualResource -= u4Share; ++ } ++ ++ /* if still have available resources, we decide to give them to VO (TC3) queue */ ++ /* 4 <2.3> Allocate the left resource to TC3 (VO) */ ++ prQM->au4CurrentTcResource[TC3_INDEX] += (u4ResidualResource); ++ ++ } ++ /* 4 <3> Case 2: Demand > Total Resource --> Guarantee a minimum amount of resource for each TC */ ++ else { ++ /* ++ u4ResidualResource means we at least need to keep ++ QM_INITIAL_RESIDUAL_TC_RESOURCE available TC resources ++ ++ in 6628, u4ResidualResource = 26, max 28 ++ */ ++ u4ResidualResource = QM_INITIAL_RESIDUAL_TC_RESOURCE; ++ ++ /* 4 <3.1> Allocated resource amount = minimum of (guaranteed, total demand) */ ++ for (i = 0; i < TC_NUM; i++) { ++ ++ if (i == TC4_INDEX) ++ continue; /* Skip TC4 (not adjustable) */ ++ ++ /* The demand can be fulfilled with the guaranteed resource amount 4 4 6 6 2 4 */ ++ ++ /* ++ ai4PerTcResourceDemand[i] = ++ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + ++ prQM->au4MinReservedTcResource[i] - ++ prQM->au4CurrentTcResource[i]); ++ ++ so au4CurrentTcResource + ai4PerTcResourceDemand = ++ ++ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + ++ prQM->au4MinReservedTcResource[i] = ++ ++ current average queue len + min TC resources ++ */ ++ if (prQM->au4CurrentTcResource[i] + ai4PerTcResourceDemand[i] < ++ prQM->au4GuaranteedTcResource[i]) { ++ ++ /* avg queue len + min reserve still smaller than guarantee so enough */ ++ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; ++ ++ /* accumulate available TC resources from the TC */ ++ u4ResidualResource += ++ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); ++ ai4PerTcResourceDemand[i] = 0; ++ } ++ ++ /* The demand can not be fulfilled with the guaranteed resource amount */ ++ else { ++ ++ /* means even we use all guarantee resources for the TC is still not enough */ ++ ++ /* ++ guarantee number is always for the TC so extra resource number cannot ++ include the guarantee number. ++ ++ EX: au4GuaranteedTcResource = 10, au4CurrentTcResource = 5 ++ ai4PerTcResourceDemand = 6 ++ ++ ai4PerTcResourceDemand -= (10 - 5) ==> 1 ++ only need extra 1 TC resouce is enough. ++ */ ++ ai4PerTcResourceDemand[i] -= ++ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); ++ ++ /* update current avg TC resource to guarantee number */ ++ prQM->au4CurrentTcResource[i] = prQM->au4GuaranteedTcResource[i]; ++ ++ /* count how many TC queues need to get extra resources */ ++ u4ShareCount++; ++ } ++ } ++ ++ /* 4 <3.2> Allocate the residual resource */ ++ do { ++ /* If there is no resource left, exit directly */ ++ if (u4ResidualResource == 0) ++ break; ++ ++ /* This shall not happen */ ++ if (u4ShareCount == 0) { ++ prQM->au4CurrentTcResource[TC1_INDEX] += u4ResidualResource; ++ DBGLOG(QM, ERROR, "QM: (Error) u4ShareCount = 0\n"); ++ break; ++ } ++ ++ /* Share the residual resource evenly */ ++ u4Share = (u4ResidualResource / u4ShareCount); ++ ++ if (u4Share) { ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4 (not adjustable) */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ if (ai4PerTcResourceDemand[i] == 0) ++ continue; ++ ++ if (ai4PerTcResourceDemand[i] - u4Share) { ++ /* still not enough but we just can give it u4Share resources */ ++ prQM->au4CurrentTcResource[i] += u4Share; ++ u4ResidualResource -= u4Share; ++ ai4PerTcResourceDemand[i] -= u4Share; ++ } else { ++ /* enough */ ++ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; ++ u4ResidualResource -= ai4PerTcResourceDemand[i]; ++ ai4PerTcResourceDemand[i] = 0; ++ } ++ } ++ } ++ ++ if (u4ResidualResource == 0) ++ break; ++ /* By priority, allocate the left resource that is not divisible by u4Share */ ++ ++ if (ai4PerTcResourceDemand[TC3_INDEX]) { /* VO */ ++ prQM->au4CurrentTcResource[TC3_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC2_INDEX]) { /* VI */ ++ prQM->au4CurrentTcResource[TC2_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC5_INDEX]) { /* BMCAST */ ++ prQM->au4CurrentTcResource[TC5_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC1_INDEX]) { /* BE */ ++ prQM->au4CurrentTcResource[TC1_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC0_INDEX]) { /* BK */ ++ prQM->au4CurrentTcResource[TC0_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ /* Allocate the left resource */ ++ prQM->au4CurrentTcResource[TC3_INDEX] += u4ResidualResource; ++ ++ } while (FALSE); ++ } ++ ++ /* mark the flag that we can start to do TC resource adjustment after TX done handle */ ++ prQM->fgTcResourcePostAnnealing = TRUE; ++ ++#if QM_PRINT_TC_RESOURCE_CTRL ++ /* Debug print */ ++ DBGLOG(QM, LOUD, "QM: TC Rsc %u %u %u %u %u %u\n", ++ prQM->au4CurrentTcResource[0], ++ prQM->au4CurrentTcResource[1], ++ prQM->au4CurrentTcResource[2], ++ prQM->au4CurrentTcResource[3], prQM->au4CurrentTcResource[4], prQM->au4CurrentTcResource[5] ++ )); ++#endif ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* RX-Related Queue Management */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Init Queue Management for RX ++* ++* \param[in] (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter) ++{ ++ /* DbgPrint("QM: Enter qmInitRxQueues()\n"); */ ++ /* TODO */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle RX packets (buffer reordering) ++* ++* \param[in] prSwRfbListHead The list of RX packets ++* ++* \return The list of packets which are not buffered for reordering ++*/ ++/*----------------------------------------------------------------------------*/ ++P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) ++{ ++ ++#if CFG_RX_REORDERING_ENABLED ++ /* UINT_32 i; */ ++ P_SW_RFB_T prCurrSwRfb; ++ P_SW_RFB_T prNextSwRfb; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ QUE_T rReturnedQue; ++ PUINT_8 pucEthDestAddr; ++ BOOLEAN fgIsBMC; ++ ++ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ ++ ++ DEBUGFUNC("qmHandleRxPackets"); ++ ++ ASSERT(prSwRfbListHead); ++ ++ QUEUE_INITIALIZE(&rReturnedQue); ++ prNextSwRfb = prSwRfbListHead; ++ ++ do { ++ prCurrSwRfb = prNextSwRfb; ++ prNextSwRfb = QM_RX_GET_NEXT_SW_RFB(prCurrSwRfb); ++ ++ prHifRxHdr = prCurrSwRfb->prHifRxHdr; /* TODO: (Tehuang) Use macro to obtain the pointer */ ++ ++ /* TODO: (Tehuang) Check if relaying */ ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST; ++ ++ /* Decide the Destination */ ++#if CFG_RX_PKTS_DUMP ++ if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_DATA)) { ++ DBGLOG(SW4, INFO, "QM RX DATA: net %u sta idx %u wlan idx %u ssn %u tid %u ptype %u 11 %u\n", ++ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), ++ prHifRxHdr->ucStaRecIdx, prCurrSwRfb->ucWlanIdx, ++ (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr), /* The new SN of the frame */ ++ (UINT_32) HIF_RX_HDR_GET_TID(prHifRxHdr), ++ prCurrSwRfb->ucPacketType, ++ (UINT_32) HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); ++ ++ DBGLOG_MEM8(SW4, TRACE, (PUINT_8) prCurrSwRfb->pvHeader, prCurrSwRfb->u2PacketLen); ++ } ++#endif ++ ++ fgIsBMC = FALSE; ++ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { ++ ++ UINT_8 ucNetTypeIdx; ++ P_BSS_INFO_T prBssInfo; ++ ++ pucEthDestAddr = prCurrSwRfb->pvHeader; ++ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); ++ /* DBGLOG_MEM8(QM, TRACE,prCurrSwRfb->pvHeader, 16); */ ++ /* */ ++ ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) && (OP_MODE_ACCESS_POINT != prBssInfo->eCurrentOPMode)) ++ fgIsBMC = TRUE; ++ ++ if (prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem > ++ (CFG_RX_MAX_PKT_NUM - CFG_NUM_OF_QM_RX_PKT_NUM)) { ++ ++ if (!IS_BSS_ACTIVE(prBssInfo)) { ++ DBGLOG(QM, WARN, "Mark NULL the Packet for inactive Bss %u\n", ucNetTypeIdx); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++ ++ if (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode) { ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; ++ else if (UNEQUAL_MAC_ADDR(prBssInfo->aucOwnMacAddr, pucEthDestAddr) && ++ bssGetClientByAddress(prBssInfo, pucEthDestAddr)) ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_FORWARD; ++ /* TODO : need to check the dst mac is valid */ ++ /* If src mac is invalid, the packet will be freed in fw */ ++ } /* OP_MODE_ACCESS_POINT */ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ else if (hs20IsFrameFilterEnabled(prAdapter, prBssInfo) && ++ hs20IsUnsecuredFrame(prAdapter, prBssInfo, prCurrSwRfb)) { ++ DBGLOG(QM, WARN, ++ "Mark NULL the Packet for Dropped Packet %u\n", ucNetTypeIdx); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++#endif ++ } else { ++ /* Dont not occupy other SW RFB */ ++ DBGLOG(QM, WARN, "Mark NULL the Packet for less Free Sw Rfb\n"); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++ ++ } ++#if CFG_SUPPORT_WAPI ++ if (prCurrSwRfb->u2PacketLen > ETHER_HEADER_LEN) { ++ PUINT_8 pc = (PUINT_8) prCurrSwRfb->pvHeader; ++ UINT_16 u2Etype = 0; ++ ++ u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ /* for wapi integrity test. WPI_1x packet should be always in non-encrypted mode. ++ if we received any WPI(0x88b4) packet that is encrypted, drop here. */ ++ if (u2Etype == ETH_WPI_1X && HIF_RX_HDR_GET_SEC_MODE(prHifRxHdr) != 0) { ++ DBGLOG(QM, INFO, "drop wpi packet with sec mode\n"); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++ } ++#endif ++ /* BAR frame */ ++ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ qmProcessBarFrame(prAdapter, prCurrSwRfb, &rReturnedQue); ++ } ++ /* Reordering is not required for this packet, return it without buffering */ ++ else if (!HIF_RX_HDR_GET_REORDER_FLAG(prHifRxHdr) || fgIsBMC) { ++#if 0 ++ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { ++ UINT_8 ucNetTypeIdx; ++ P_BSS_INFO_T prBssInfo; ++ ++ pucEthDestAddr = prCurrSwRfb->pvHeader; ++ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); ++ ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) ++ && (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode)) { ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; ++ } ++ } ++#endif ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ } ++ /* Reordering is required for this packet */ ++ else { ++ /* If this packet should dropped or indicated to the host immediately, ++ * it should be enqueued into the rReturnedQue with specific flags. If ++ * this packet should be buffered for reordering, it should be enqueued ++ * into the reordering queue in the STA_REC rather than into the ++ * rReturnedQue. ++ */ ++ qmProcessPktWithReordering(prAdapter, prCurrSwRfb, &rReturnedQue); ++ ++ } ++ } while (prNextSwRfb); ++ ++ /* RX_PKT_DESTINATION_HOST_WITH_FORWARD or RX_PKT_DESTINATION_FORWARD */ ++ /* The returned list of SW_RFBs must end with a NULL pointer */ ++ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) ++ QM_TX_SET_NEXT_MSDU_INFO((P_SW_RFB_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); ++ ++ return (P_SW_RFB_T) QUEUE_GET_HEAD(&rReturnedQue); ++ ++#else ++ ++ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ ++ return prSwRfbListHead; ++ ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Reorder the received packet ++* ++* \param[in] prSwRfb The RX packet to process ++* \param[out] prReturnedQue The queue for indicating packets ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) ++{ ++ ++ P_STA_RECORD_T prStaRec; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_RX_BA_ENTRY_T prReorderQueParm; ++ ++ UINT_32 u4SeqNo; ++ UINT_32 u4WinStart; ++ UINT_32 u4WinEnd; ++ P_QUE_T prReorderQue; ++ /* P_SW_RFB_T prReorderedSwRfb; */ ++ BOOLEAN fgIsBaTimeout; ++ ++ DEBUGFUNC("qmProcessPktWithReordering"); ++ ++ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; ++ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SN of the frame */ ++ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); ++ /* prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ ++ ++ /* Incorrect STA_REC index */ ++ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ DBGLOG(QM, WARN, "Reordering for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Check whether the STA_REC is activated */ ++ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); ++ ASSERT(prStaRec); ++ ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ DBGLOG(QM, WARN, "Reordering for an invalid STA_REC\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++#endif ++ ++ /* Check whether the BA agreement exists */ ++ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); ++ if (!prReorderQueParm) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ DBGLOG(QM, WARN, "Reordering for a NULL ReorderQueParm\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Start to reorder packets */ ++ u4SeqNo = (UINT_32) (prSwRfb->u2SSN); ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); ++ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); ++ ++ /* Debug */ ++ /* DbgPrint("QM:(R)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ ++ ++ /* Case 1: Fall within */ ++ if /* 0 - start - sn - end - 4095 */ ++ (((u4WinStart <= u4SeqNo) && (u4SeqNo <= u4WinEnd)) ++ /* 0 - end - start - sn - 4095 */ ++ || ((u4WinEnd < u4WinStart) && (u4WinStart <= u4SeqNo)) ++ /* 0 - sn - end - start - 4095 */ ++ || ((u4SeqNo <= u4WinEnd) && (u4WinEnd < u4WinStart))) { ++ ++ qmInsertFallWithinReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); ++ ++#if QM_RX_WIN_SSN_AUTO_ADVANCING ++ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { ++ /* Let the first received packet pass the reorder check */ ++ DBGLOG(QM, LOUD, "QM:(A)[%d](%u){%u,%u}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); ++ ++ prReorderQueParm->u2WinStart = (UINT_16) u4SeqNo; ++ prReorderQueParm->u2WinEnd = ++ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; ++ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; ++ } ++#endif ++ ++ if (qmPopOutDueToFallWithin(prReorderQueParm, prReturnedQue, &fgIsBaTimeout) == FALSE) ++ STATS_RX_REORDER_HOLE_INC(prStaRec); /* record hole count */ ++ STATS_RX_REORDER_HOLE_TIMEOUT_INC(prStaRec, fgIsBaTimeout); ++ } ++ /* Case 2: Fall ahead */ ++ else if ++ /* 0 - start - end - sn - (start+2048) - 4095 */ ++ (((u4WinStart < u4WinEnd) ++ && (u4WinEnd < u4SeqNo) ++ && (u4SeqNo < (u4WinStart + HALF_SEQ_NO_COUNT))) ++ /* 0 - sn - (start+2048) - start - end - 4095 */ ++ || ((u4SeqNo < u4WinStart) ++ && (u4WinStart < u4WinEnd) ++ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT))) ++ /* 0 - end - sn - (start+2048) - start - 4095 */ ++ || ((u4WinEnd < u4SeqNo) ++ && (u4SeqNo < u4WinStart) ++ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT)))) { ++ ++#if QM_RX_WIN_SSN_AUTO_ADVANCING ++ if (prReorderQueParm->fgIsWaitingForPktWithSsn) ++ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; ++#endif ++ ++ qmInsertFallAheadReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); ++ ++ /* Advance the window after inserting a new tail */ ++ prReorderQueParm->u2WinEnd = (UINT_16) u4SeqNo; ++ prReorderQueParm->u2WinStart = ++ (((prReorderQueParm->u2WinEnd) - (prReorderQueParm->u2WinSize) + MAX_SEQ_NO_COUNT + 1) ++ % MAX_SEQ_NO_COUNT); ++ ++ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); ++ ++ STATS_RX_REORDER_FALL_AHEAD_INC(prStaRec); ++ ++ } ++ /* Case 3: Fall behind */ ++ else { ++ ++#if QM_RX_WIN_SSN_AUTO_ADVANCING ++#if QM_RX_INIT_FALL_BEHIND_PASS ++ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { ++ /* ?? prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ /* DbgPrint("QM:(P)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ ++ return; ++ } ++#endif ++#endif ++ ++ STATS_RX_REORDER_FALL_BEHIND_INC(prStaRec); ++ /* An erroneous packet */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ /* DbgPrint("QM:(D)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ ++ return; ++ } ++ ++ return; ++ ++} ++ ++VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) ++{ ++ ++ P_STA_RECORD_T prStaRec; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_RX_BA_ENTRY_T prReorderQueParm; ++ ++ UINT_32 u4SSN; ++ UINT_32 u4WinStart; ++ UINT_32 u4WinEnd; ++ P_QUE_T prReorderQue; ++ /* P_SW_RFB_T prReorderedSwRfb; */ ++ ++ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; ++ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SSN */ ++ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); ++ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ ++ /* Incorrect STA_REC index */ ++ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { ++ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Check whether the STA_REC is activated */ ++ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); ++ ASSERT(prStaRec); ++ ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ DbgPrint("QM: (Warning) BAR for an invalid STA_REC\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++#endif ++ ++ /* Check whether the BA agreement exists */ ++ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); ++ if (!prReorderQueParm) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL ReorderQueParm\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ u4SSN = (UINT_32) (prSwRfb->u2SSN); ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); ++ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); ++ ++ if (qmCompareSnIsLessThan(u4WinStart, u4SSN)) { ++ prReorderQueParm->u2WinStart = (UINT_16) u4SSN; ++ prReorderQueParm->u2WinEnd = ++ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; ++ DBGLOG(QM, TRACE, ++ "QM:(BAR)[%d](%u){%d,%d}\n", prSwRfb->ucTid, u4SSN, prReorderQueParm->u2WinStart, ++ prReorderQueParm->u2WinEnd); ++ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); ++ } else { ++ DBGLOG(QM, TRACE, "QM:(BAR)(%d)(%u){%u,%u}\n", prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd); ++ } ++} ++ ++VOID qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) ++{ ++ P_SW_RFB_T prExaminedQueuedSwRfb; ++ P_QUE_T prReorderQue; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prReorderQueParm); ++ ASSERT(prReturnedQue); ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ prExaminedQueuedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); ++ ++ /* There are no packets queued in the Reorder Queue */ ++ if (prExaminedQueuedSwRfb == NULL) { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; ++ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; ++ prReorderQue->u4NumElem++; ++ } ++ ++ /* Determine the insert position */ ++ else { ++ do { ++ /* Case 1: Terminate. A duplicate packet */ ++ if (((prExaminedQueuedSwRfb->u2SSN) == (prSwRfb->u2SSN))) { ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ return; ++ } ++ ++ /* Case 2: Terminate. The insert point is found */ ++ else if (qmCompareSnIsLessThan((prSwRfb->u2SSN), (prExaminedQueuedSwRfb->u2SSN))) ++ break; ++ ++ /* Case 3: Insert point not found. Check the next SW_RFB in the Reorder Queue */ ++ else ++ prExaminedQueuedSwRfb = (P_SW_RFB_T) (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prNext); ++ } while (prExaminedQueuedSwRfb); ++ ++ /* Update the Reorder Queue Parameters according to the found insert position */ ++ if (prExaminedQueuedSwRfb == NULL) { ++ /* The received packet shall be placed at the tail */ ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); ++ prReorderQue->prTail = (P_QUE_ENTRY_T) (prSwRfb); ++ } else { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = (P_QUE_ENTRY_T) prExaminedQueuedSwRfb; ++ if (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb) == (prReorderQue->prHead)) { ++ /* The received packet will become the head */ ++ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; ++ } else { ++ (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev)->prNext = (P_QUE_ENTRY_T) prSwRfb; ++ } ++ ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev = (P_QUE_ENTRY_T) prSwRfb; ++ } ++ ++ prReorderQue->u4NumElem++; ++ ++ } ++ ++} ++ ++VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) ++{ ++ P_QUE_T prReorderQue; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prReorderQueParm); ++ ASSERT(prReturnedQue); ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ ++ /* There are no packets queued in the Reorder Queue */ ++ if (QUEUE_IS_EMPTY(prReorderQue)) { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; ++ } else { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); ++ } ++ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; ++ prReorderQue->u4NumElem++; ++ ++} ++ ++BOOLEAN ++qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout) ++{ ++ P_SW_RFB_T prReorderedSwRfb; ++ P_QUE_T prReorderQue; ++ BOOLEAN fgDequeuHead, fgMissing; ++ OS_SYSTIME rCurrentTime, *prMissTimeout; ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ ++ *fgIsTimeout = FALSE; ++ fgMissing = FALSE; ++ rCurrentTime = 0; ++ prMissTimeout = &(g_arMissTimeout[prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid]); ++ if ((*prMissTimeout)) { ++ fgMissing = TRUE; ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ } ++ ++ /* Check whether any packet can be indicated to the higher layer */ ++ while (TRUE) { ++ if (QUEUE_IS_EMPTY(prReorderQue)) ++ break; ++ ++ /* Always examine the head packet */ ++ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); ++ fgDequeuHead = FALSE; ++ ++ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ ++ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { ++ ++ fgDequeuHead = TRUE; ++ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); ++ } ++ /* SN > WinStart, break to update WinEnd */ ++ else { ++ if ((fgMissing == TRUE) && ++ CHECK_FOR_TIMEOUT(rCurrentTime, (*prMissTimeout), ++ MSEC_TO_SYSTIME(QM_RX_BA_ENTRY_MISS_TIMEOUT_MS))) { ++ DBGLOG(QM, TRACE, ++ "QM:RX BA Timout Next Tid %d SSN %d\n", prReorderQueParm->ucTid, ++ prReorderedSwRfb->u2SSN); ++ fgDequeuHead = TRUE; ++ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); ++ ++ fgMissing = FALSE; ++ *fgIsTimeout = TRUE; ++ } else ++ break; ++ } ++ ++ /* Dequeue the head packet */ ++ if (fgDequeuHead) { ++ ++ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { ++ prReorderQue->prHead = NULL; ++ prReorderQue->prTail = NULL; ++ } else { ++ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; ++ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; ++ } ++ prReorderQue->u4NumElem--; ++ /* DbgPrint("QM: [%d] %d (%d)\n", ++ prReorderQueParm->ucTid, ++ prReorderedSwRfb->u2PacketLen, ++ prReorderedSwRfb->u2SSN); */ ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); ++ } ++ } ++ ++ if (QUEUE_IS_EMPTY(prReorderQue)) ++ *prMissTimeout = 0; ++ else { ++ if (fgMissing == FALSE) ++ GET_CURRENT_SYSTIME(prMissTimeout); ++ } ++ ++ /* After WinStart has been determined, update the WinEnd */ ++ prReorderQueParm->u2WinEnd = ++ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); ++ return QUEUE_IS_EMPTY(prReorderQue); ++} ++ ++VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) ++{ ++ P_SW_RFB_T prReorderedSwRfb; ++ P_QUE_T prReorderQue; ++ BOOLEAN fgDequeuHead; ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ ++ /* Check whether any packet can be indicated to the higher layer */ ++ while (TRUE) { ++ if (QUEUE_IS_EMPTY(prReorderQue)) ++ break; ++ ++ /* Always examine the head packet */ ++ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); ++ fgDequeuHead = FALSE; ++ ++ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ ++ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { ++ ++ fgDequeuHead = TRUE; ++ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); ++ } ++ ++ /* SN < WinStart, so the head packet shall be indicated (do not advance the window) */ ++ else if (qmCompareSnIsLessThan((UINT_32) (prReorderedSwRfb->u2SSN), ++ (UINT_32) (prReorderQueParm->u2WinStart))) ++ fgDequeuHead = TRUE; ++ ++ /* SN > WinStart, break to update WinEnd */ ++ else ++ break; ++ ++ /* Dequeue the head packet */ ++ if (fgDequeuHead) { ++ ++ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { ++ prReorderQue->prHead = NULL; ++ prReorderQue->prTail = NULL; ++ } else { ++ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; ++ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; ++ } ++ prReorderQue->u4NumElem--; ++ /* DbgPrint("QM: [%d] %d (%d)\n", */ ++ /* prReorderQueParm->ucTid, prReorderedSwRfb->u2PacketLen, prReorderedSwRfb->u2SSN); */ ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); ++ } ++ } ++ ++ /* After WinStart has been determined, update the WinEnd */ ++ prReorderQueParm->u2WinEnd = ++ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); ++ ++} ++ ++BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater) ++{ ++ /* 0 <---> SnLess <--(gap>2048)--> SnGreater : SnLess > SnGreater */ ++ if ((u4SnLess + HALF_SEQ_NO_COUNT) <= u4SnGreater) /* Shall be <= */ ++ return FALSE; ++ ++ /* 0 <---> SnGreater <--(gap>2048)--> SnLess : SnLess < SnGreater */ ++ else if ((u4SnGreater + HALF_SEQ_NO_COUNT) < u4SnLess) ++ return TRUE; ++ ++ /* 0 <---> SnGreater <--(gap<2048)--> SnLess : SnLess > SnGreater */ ++ /* 0 <---> SnLess <--(gap<2048)--> SnGreater : SnLess < SnGreater */ ++ else if (u4SnLess < u4SnGreater) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle Mailbox RX messages ++* ++* \param[in] prMailboxRxMsg The received Mailbox message from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg) ++{ ++ /* DbgPrint("QM: Enter qmHandleMailboxRxMessage()\n"); */ ++ /* TODO */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle ADD RX BA Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_RX_ADDBA_T prEventRxAddBa; ++ P_STA_RECORD_T prStaRec; ++ UINT_32 u4Tid; ++ UINT_32 u4WinSize; ++ ++ DBGLOG(QM, INFO, "QM:Event +RxBa\n"); ++ ++ prEventRxAddBa = (P_EVENT_RX_ADDBA_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxAddBa->ucStaRecIdx); ++ ++ if (!prStaRec) { ++ /* Invalid STA_REC index, discard the event packet */ ++ /* ASSERT(0); */ ++ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for a NULL STA_REC\n"); ++ return; ++ } ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ ++ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for an invalid STA_REC\n"); ++ /* ASSERT(0); */ ++ /* return; */ ++ } ++#endif ++ ++ u4Tid = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_TID_MASK) ++ >> BA_PARAM_SET_TID_MASK_OFFSET); ++ ++ u4WinSize = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_BUFFER_SIZE_MASK) ++ >> BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); ++ ++ if (!qmAddRxBaEntry(prAdapter, ++ prStaRec->ucIndex, ++ (UINT_8) u4Tid, ++ (prEventRxAddBa->u2BAStartSeqCtrl >> OFFSET_BAR_SSC_SN), (UINT_16) u4WinSize)) { ++ ++ /* FW shall ensure the availabiilty of the free-to-use BA entry */ ++ DBGLOG(QM, ERROR, "QM: (Error) qmAddRxBaEntry() failure\n"); ++ ASSERT(0); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle DEL RX BA Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_RX_DELBA_T prEventRxDelBa; ++ P_STA_RECORD_T prStaRec; ++ ++ /* DbgPrint("QM:Event -RxBa\n"); */ ++ ++ prEventRxDelBa = (P_EVENT_RX_DELBA_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxDelBa->ucStaRecIdx); ++ ++ if (!prStaRec) ++ /* Invalid STA_REC index, discard the event packet */ ++ /* ASSERT(0); */ ++ return; ++#if 0 ++ if (!(prStaRec->fgIsValid)) ++ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ ++ /* ASSERT(0); */ ++ return; ++#endif ++ ++ qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, prEventRxDelBa->ucTid, TRUE); ++ ++} ++ ++P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, UINT_8 ucStaRecIdx, UINT_8 ucTid) ++{ ++ int i; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* DbgPrint("QM: Enter qmLookupRxBaEntry()\n"); */ ++ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ if (prQM->arRxBaTable[i].fgIsValid) { ++ if ((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) && (prQM->arRxBaTable[i].ucTid == ucTid)) ++ return &prQM->arRxBaTable[i]; ++ } ++ } ++ return NULL; ++} ++ ++BOOLEAN ++qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize) ++{ ++ int i; ++ P_RX_BA_ENTRY_T prRxBaEntry = NULL; ++ P_STA_RECORD_T prStaRec; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ if (ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { ++ /* Invalid STA_REC index, discard the event packet */ ++ DBGLOG(QM, WARN, "QM: (WARNING) RX ADDBA Event for a invalid ucStaRecIdx = %d\n", ucStaRecIdx); ++ return FALSE; ++ } ++ ++ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* if(!(prStaRec->fgIsValid)){ */ ++ /* DbgPrint("QM: (WARNING) Invalid STA when adding an RX BA\n"); */ ++ /* return FALSE; */ ++ /* } */ ++ ++ /* 4 <1> Delete before adding */ ++ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ ++ if (qmLookupRxBaEntry(prAdapter, ucStaRecIdx, ucTid)) ++ qmDelRxBaEntry(prAdapter, ucStaRecIdx, ucTid, TRUE); /* prQM->ucRxBaCount-- */ ++ /* 4 <2> Add a new BA entry */ ++ /* No available entry to store the BA agreement info. Retrun FALSE. */ ++ if (prQM->ucRxBaCount >= CFG_NUM_OF_RX_BA_AGREEMENTS) { ++ DBGLOG(QM, ERROR, "QM: **failure** (limited resource, ucRxBaCount=%d)\n", prQM->ucRxBaCount); ++ return FALSE; ++ } ++ /* Find the free-to-use BA entry */ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ if (!prQM->arRxBaTable[i].fgIsValid) { ++ prRxBaEntry = &(prQM->arRxBaTable[i]); ++ prQM->ucRxBaCount++; ++ DBGLOG(QM, LOUD, "QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); ++ break; ++ } ++ } ++ /* If a free-to-use entry is found, configure it and associate it with the STA_REC */ ++ u2WinSize += CFG_RX_BA_INC_SIZE; ++ if (prRxBaEntry) { ++ prRxBaEntry->ucStaRecIdx = ucStaRecIdx; ++ prRxBaEntry->ucTid = ucTid; ++ prRxBaEntry->u2WinStart = u2WinStart; ++ prRxBaEntry->u2WinSize = u2WinSize; ++ prRxBaEntry->u2WinEnd = ((u2WinStart + u2WinSize - 1) % MAX_SEQ_NO_COUNT); ++ prRxBaEntry->fgIsValid = TRUE; ++ prRxBaEntry->fgIsWaitingForPktWithSsn = TRUE; ++ ++ g_arMissTimeout[ucStaRecIdx][ucTid] = 0; ++ ++ DBGLOG(QM, INFO, "QM: +RxBA(STA=%d TID=%d WinStart=%d WinEnd=%d WinSize=%d)\n", ++ ucStaRecIdx, ucTid, ++ prRxBaEntry->u2WinStart, prRxBaEntry->u2WinEnd, prRxBaEntry->u2WinSize); ++ ++ /* Update the BA entry reference table for per-packet lookup */ ++ prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry; ++ } else { ++ /* This shall not happen because FW should keep track of the usage of RX BA entries */ ++ DBGLOG(QM, ERROR, "QM: **AddBA Error** (ucRxBaCount=%d)\n", prQM->ucRxBaCount); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost) ++{ ++ P_RX_BA_ENTRY_T prRxBaEntry; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prFlushedPacketList = NULL; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; ++ ASSERT(prStaRec); ++ ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ DbgPrint("QM: (WARNING) Invalid STA when deleting an RX BA\n"); ++ return; ++ } ++#endif ++ ++ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ ++ prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[ucTid]; ++ ++ if (prRxBaEntry) { ++ ++ prFlushedPacketList = qmFlushStaRxQueue(prAdapter, ucStaRecIdx, ucTid); ++ ++ if (prFlushedPacketList) { ++ ++ if (fgFlushToHost) { ++ wlanProcessQueuedSwRfb(prAdapter, prFlushedPacketList); ++ } else { ++ ++ P_SW_RFB_T prSwRfb; ++ P_SW_RFB_T prNextSwRfb; ++ ++ prSwRfb = prFlushedPacketList; ++ ++ do { ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ prSwRfb = prNextSwRfb; ++ } while (prSwRfb); ++ ++ } ++ ++ } ++#if ((QM_TEST_MODE == 0) && (QM_TEST_STA_REC_DEACTIVATION == 0)) ++ /* Update RX BA entry state. Note that RX queue flush is not done here */ ++ prRxBaEntry->fgIsValid = FALSE; ++ prQM->ucRxBaCount--; ++ ++ /* Debug */ ++#if 0 ++ DbgPrint("QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); ++#endif ++ ++ /* Update STA RX BA table */ ++ prStaRec->aprRxReorderParamRefTbl[ucTid] = NULL; ++#endif ++ ++ DBGLOG(QM, INFO, "QM: -RxBA(STA=%d,TID=%d)\n", ucStaRecIdx, ucTid); ++ ++ } ++ ++ /* Debug */ ++#if CFG_HIF_RX_STARVATION_WARNING ++ { ++ P_RX_CTRL_T prRxCtrl; ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ DBGLOG(QM, TRACE, ++ "QM: (RX DEBUG) Enqueued: %d / Dequeued: %d\n", prRxCtrl->u4QueuedCnt, ++ prRxCtrl->u4DequeuedCnt); ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To process WMM related IEs in ASSOC_RSP ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prSwRfb The received frame ++* \param[in] pucIE The pointer to the first IE in the frame ++* \param[in] u2IELength The total length of IEs in the frame ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ PUINT_8 pucIEStart; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ P_IE_WMM_INFO_T prIeWmmInfo; ++ UINT_8 ucQosInfo; ++ UINT_8 ucQosInfoAC; ++ UINT_8 ucBmpAC; ++ ++ DEBUGFUNC("mqmProcessAssocReq"); ++ ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ prStaRec->fgIsQoS = FALSE; ++ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; ++ ++ pucIEStart = pucIE; ++ ++ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ /* Determine whether QoS is enabled with the association */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_WMM: ++ ++ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && ++ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_INFO: ++ if (IE_LEN(pucIE) != 7) ++ break; /* WMM Info IE with a wrong length */ ++ prStaRec->fgIsQoS = TRUE; ++ prStaRec->fgIsWmmSupported = TRUE; ++ ++ prIeWmmInfo = (P_IE_WMM_INFO_T) pucIE; ++ ucQosInfo = prIeWmmInfo->ucQosInfo; ++ ucQosInfoAC = ucQosInfo & BITS(0, 3); ++ ++ prStaRec->fgIsUapsdSupported = ((ucQosInfoAC) ? TRUE : FALSE) & ++ prAdapter->rWifiVar.fgSupportUAPSD; ++ ++ ucBmpAC = 0; ++ ++ if (ucQosInfoAC & WMM_QOS_INFO_VO_UAPSD) ++ ucBmpAC |= BIT(ACI_VO); ++ if (ucQosInfoAC & WMM_QOS_INFO_VI_UAPSD) ++ ucBmpAC |= BIT(ACI_VI); ++ if (ucQosInfoAC & WMM_QOS_INFO_BE_UAPSD) ++ ucBmpAC |= BIT(ACI_BE); ++ if (ucQosInfoAC & WMM_QOS_INFO_BK_UAPSD) ++ ucBmpAC |= BIT(ACI_BK); ++ ++ prStaRec->ucBmpTriggerAC = prStaRec->ucBmpDeliveryAC = ucBmpAC; ++ ++ prStaRec->ucUapsdSp = ++ (ucQosInfo & WMM_QOS_INFO_MAX_SP_LEN_MASK) >> 5; ++ break; ++ default: ++ /* Other WMM QoS IEs. Ignore any */ ++ break; ++ } ++ } ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ ++ ++ break; ++ ++ case ELEM_ID_HT_CAP: ++ /* Some client won't put the WMM IE if client is 802.11n */ ++ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ DBGLOG(QM, TRACE, "MQM: Assoc_Req Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To process WMM related IEs in ASSOC_RSP ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prSwRfb The received frame ++* \param[in] pucIE The pointer to the first IE in the frame ++* \param[in] u2IELength The total length of IEs in the frame ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ PUINT_8 pucIEStart; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ DEBUGFUNC("mqmProcessAssocRsp"); ++ ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ prStaRec->fgIsQoS = FALSE; ++ ++ pucIEStart = pucIE; ++ ++ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgSupportQoS=%d)\n", ++ prStaRec->fgIsWmmSupported, prAdapter->rWifiVar.fgSupportQoS); ++ ++ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ ++ /* if((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported)) */ ++ if ((!prAdapter->rWifiVar.fgSupportQoS)) ++ return; ++ ++ /* Determine whether QoS is enabled with the association */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_WMM: ++ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && ++ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { ++ ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_PARAM: ++ if (IE_LEN(pucIE) != 24) ++ break; /* WMM Info IE with a wrong length */ ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ ++ case VENDOR_OUI_SUBTYPE_WMM_INFO: ++ if (IE_LEN(pucIE) != 7) ++ break; /* WMM Info IE with a wrong length */ ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ ++ default: ++ /* Other WMM QoS IEs. Ignore any */ ++ break; ++ } ++ } ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ ++ break; ++ ++ case ELEM_ID_HT_CAP: ++ /* Some AP won't put the WMM IE if client is 802.11n */ ++ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* Parse AC parameters and write to HW CRs */ ++ if ((prStaRec->fgIsQoS) && (prStaRec->eStaType == STA_TYPE_LEGACY_AP)) { ++ mqmParseEdcaParameters(prAdapter, prSwRfb, pucIEStart, u2IELength, TRUE); ++#if ARP_MONITER_ENABLE ++ qmResetArpDetect(); ++#endif ++ } ++ ++ DBGLOG(QM, TRACE, "MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); ++ if (prStaRec->fgIsWmmSupported) ++ nicQmUpdateWmmParms(prAdapter, prStaRec->ucNetTypeIndex); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To parse WMM Parameter IE (in BCN or Assoc_Rsp) ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prSwRfb The received frame ++* \param[in] pucIE The pointer to the first IE in the frame ++* \param[in] u2IELength The total length of IEs in the frame ++* \param[in] fgForceOverride TRUE: If EDCA parameters are found, always set to HW CRs. ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ P_BSS_INFO_T prBssInfo; ++ P_AC_QUE_PARMS_T prAcQueParams; ++ P_IE_WMM_PARAM_T prIeWmmParam; ++ ENUM_WMM_ACI_T eAci; ++ PUINT_8 pucWmmParamSetCount; ++ ++ DEBUGFUNC("mqmParseEdcaParameters"); ++ ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ if (prStaRec == NULL) ++ return; ++ ++ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgIsQoS=%d)\n", prStaRec->fgIsWmmSupported, prStaRec->fgIsQoS); ++ ++ if ((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported) || (!prStaRec->fgIsQoS)) ++ return; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Goal: Obtain the EDCA parameters */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_WMM: ++ if ((WMM_IE_OUI_TYPE(pucIE) != VENDOR_OUI_TYPE_WMM) || ++ (kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) ++ break; ++ ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_PARAM: ++ if (IE_LEN(pucIE) != 24) ++ break; /* WMM Param IE with a wrong length */ ++ ++ pucWmmParamSetCount = &(prBssInfo->ucWmmParamSetCount); ++ prIeWmmParam = (P_IE_WMM_PARAM_T) pucIE; ++ ++ /* Check the Parameter Set Count to determine whether EDCA parameters */ ++ /* have been changed */ ++ if (!fgForceOverride && (*pucWmmParamSetCount ++ == (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT))) ++ break; /* Ignore the IE without updating HW CRs */ ++ ++ /* Update Parameter Set Count */ ++ *pucWmmParamSetCount = ++ (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT); ++ ++ /* Update EDCA parameters */ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prAcQueParams = &prBssInfo->arACQueParms[eAci]; ++ mqmFillAcQueParam(prIeWmmParam, eAci, prAcQueParams); ++ ++ prAcQueParams->fgIsACMSet = ++ (prAcQueParams->u2Aifsn & WMM_ACIAIFSN_ACM) ? TRUE : FALSE; ++ prAcQueParams->u2Aifsn &= WMM_ACIAIFSN_AIFSN; ++ ++ DBGLOG(QM, LOUD, ++ "eAci:%d, ACM:%d, Aifsn:%d, CWmin:%d, CWmax:%d, TxopLmt:%d\n", ++ eAci, prAcQueParams->fgIsACMSet, prAcQueParams->u2Aifsn, ++ prAcQueParams->u2CWmin, prAcQueParams->u2CWmax, ++ prAcQueParams->u2TxopLimit); ++ } ++ break; ++ default: ++ /* Other WMM QoS IEs. Ignore */ ++ break; ++ } ++ ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used for parsing EDCA parameters specified in the WMM Parameter IE ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prIeWmmParam The pointer to the WMM Parameter IE ++* \param[in] u4AcOffset The offset specifying the AC queue for parsing ++* \param[in] prHwAcParams The parameter structure used to configure the HW CRs ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams) ++{ ++ prAcQueParams->u2Aifsn = *((PUINT_8) (&(prIeWmmParam->ucAciAifsn_BE)) + (u4AcOffset * 4)); ++ ++ prAcQueParams->u2CWmax = BIT(((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMAX_MASK) ++ >> WMM_ECW_WMAX_OFFSET) - 1; ++ ++ prAcQueParams->u2CWmin = ++ BIT((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMIN_MASK) - 1; ++ ++ WLAN_GET_FIELD_16(((PUINT_8) (&(prIeWmmParam->aucTxopLimit_BE)) + (u4AcOffset * 4)), ++ &(prAcQueParams->u2TxopLimit)); ++ ++ prAcQueParams->ucGuradTime = TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To parse WMM/11n related IEs in scan results (only for AP peers) ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prScanResult The scan result which shall be parsed to obtain needed info ++* \param[out] prStaRec The obtained info is stored in the STA_REC ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++#if (CFG_SUPPORT_TDLS == 1) /* for test purpose */ ++BOOLEAN flgTdlsTestExtCapElm = FALSE; ++UINT8 aucTdlsTestExtCapElm[7]; ++#endif /* CFG_SUPPORT_TDLS */ ++VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec) ++{ ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ DEBUGFUNC("mqmProcessScanResult"); ++ ++ ASSERT(prScanResult); ++ ASSERT(prStaRec); ++ ++ /* Reset the flag before parsing */ ++ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; ++ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ u2IELength = prScanResult->u2IELength; ++ pucIE = prScanResult->aucIEBuf; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* TDLS test purpose */ ++ if (flgTdlsTestExtCapElm == TRUE) ++ TdlsexBssExtCapParse(prStaRec, aucTdlsTestExtCapElm); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* Goal: Determine whether the peer supports WMM/QoS and UAPSDU */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_EXTENDED_CAP: ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexBssExtCapParse(prStaRec, pucIE); ++#endif /* CFG_SUPPORT_TDLS */ ++ break; ++ ++ case ELEM_ID_WMM: ++ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && ++ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { ++ ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_PARAM: ++ if (IE_LEN(pucIE) != 24) ++ break; /* WMM Param IE with a wrong length */ ++ ++ prStaRec->fgIsWmmSupported = TRUE; ++ prStaRec->fgIsUapsdSupported = ++ (((((P_IE_WMM_PARAM_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? ++ TRUE : FALSE); ++ break; ++ ++ case VENDOR_OUI_SUBTYPE_WMM_INFO: ++ if (IE_LEN(pucIE) != 7) ++ break; /* WMM Info IE with a wrong length */ ++ ++ prStaRec->fgIsWmmSupported = TRUE; ++ prStaRec->fgIsUapsdSupported = ++ (((((P_IE_WMM_INFO_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? ++ TRUE : FALSE); ++ break; ++ ++ default: ++ /* A WMM QoS IE that doesn't matter. Ignore it. */ ++ break; ++ } ++ } ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ ++ ++ break; ++ ++ default: ++ /* A WMM IE that doesn't matter. Ignore it. */ ++ break; ++ } ++ } ++ DBGLOG(QM, LOUD, "MQM: Scan Result Parsing (WMM=%d, UAPSD=%d)\n", ++ prStaRec->fgIsWmmSupported, prStaRec->fgIsUapsdSupported); ++ ++} ++ ++UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) ++{ ++ UINT_32 i; ++ P_STA_RECORD_T prTempStaRec; ++ ++ prTempStaRec = NULL; ++ ++ ASSERT(prAdapter); ++ ++ /* 4 <1> DA = BMCAST */ ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) ++ return STA_REC_INDEX_BMCAST; ++ /* 4 <2> Check if an AP STA is present */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ if ((prTempStaRec->ucNetTypeIndex == eNetworkType) ++ && (prTempStaRec->fgIsAp) ++ && (prTempStaRec->fgIsValid)) { ++ return prTempStaRec->ucIndex; ++ } ++ } ++ ++ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ if (prTempStaRec->fgIsValid) { ++ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, pucEthDestAddr)) ++ return prTempStaRec->ucIndex; ++ } ++ } ++ ++ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ ++ return STA_REC_INDEX_NOT_FOUND; ++} ++ ++UINT_32 ++mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, ++ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf) ++{ ++ P_IE_WMM_INFO_T prIeWmmInfo; ++ UINT_32 ucUapsd[] = { ++ WMM_QOS_INFO_BE_UAPSD, ++ WMM_QOS_INFO_BK_UAPSD, ++ WMM_QOS_INFO_VI_UAPSD, ++ WMM_QOS_INFO_VO_UAPSD ++ }; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ ASSERT(pOutBuf); ++ ++ prIeWmmInfo = (P_IE_WMM_INFO_T) pOutBuf; ++ ++ prIeWmmInfo->ucId = ELEM_ID_WMM; ++ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; ++ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; ++ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; ++ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; ++ ++ prIeWmmInfo->ucVersion = VERSION_WMM; ++ prIeWmmInfo->ucQosInfo = 0; ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++ if (fgSupportUAPSD) { ++ ++ UINT_8 ucQosInfo = 0; ++ UINT_8 i; ++ ++ /* Static U-APSD setting */ ++ for (i = ACI_BE; i <= ACI_VO; i++) { ++ if (ucBmpDeliveryAC & ucBmpTriggerAC & BIT(i)) ++ ucQosInfo |= (UINT_8) ucUapsd[i]; ++ } ++ ++ if (ucBmpDeliveryAC & ucBmpTriggerAC) { ++ switch (ucUapsdSp) { ++ case WMM_MAX_SP_LENGTH_ALL: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_2: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_4: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_6: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; ++ break; ++ ++ default: ++ DBGLOG(QM, WARN, "MQM: Incorrect SP length\n"); ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ } ++ } ++ prIeWmmInfo->ucQosInfo = ucQosInfo; ++ ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ return IE_SIZE(prIeWmmInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Generate the WMM Info IE ++* ++* \param[in] prAdapter Adapter pointer ++* @param prMsduInfo The TX MMPDU ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_IE_WMM_INFO_T prIeWmmInfo; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("mqmGenerateWmmInfoIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ /* In case QoS is not turned off, exit directly */ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ if (!prStaRec->fgIsWmmSupported) ++ return; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ ++ prIeWmmInfo = (P_IE_WMM_INFO_T) ++ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); ++ ++#if 0 ++ prIeWmmInfo->ucId = ELEM_ID_WMM; ++ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; ++ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; ++ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; ++ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; ++ ++ prIeWmmInfo->ucVersion = VERSION_WMM; ++ prIeWmmInfo->ucQosInfo = 0; ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++/* if(prAdapter->rWifiVar.fgSupportUAPSD){ */ ++ if (prAdapter->rWifiVar.fgSupportUAPSD && prStaRec->fgIsUapsdSupported) { ++ ++ UINT_8 ucQosInfo = 0; ++ UINT_8 i; ++ ++ /* Static U-APSD setting */ ++ for (i = ACI_BE; i <= ACI_VO; i++) { ++ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC & BIT(i)) ++ ucQosInfo |= (UINT_8) ucUapsd[i]; ++ } ++ ++ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC) { ++ switch (prPmProfSetupInfo->ucUapsdSp) { ++ case WMM_MAX_SP_LENGTH_ALL: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_2: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_4: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_6: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; ++ break; ++ ++ default: ++ DBGLOG(QM, INFO, "MQM: Incorrect SP length\n"); ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ } ++ } ++ prIeWmmInfo->ucQosInfo = ucQosInfo; ++ ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmInfo); ++#else ++ ++ prMsduInfo->u2FrameLength += mqmGenerateWmmInfoIEByParam((prAdapter->rWifiVar.fgSupportUAPSD ++ && prStaRec->fgIsUapsdSupported), ++ prPmProfSetupInfo->ucBmpDeliveryAC, ++ prPmProfSetupInfo->ucBmpTriggerAC, ++ prPmProfSetupInfo->ucUapsdSp, (UINT_8 *) prIeWmmInfo); ++#endif ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief log2 calculation for CW ++* ++* @param[in] val value ++* ++* @return log2(val) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++UINT_32 cwlog2(UINT_32 val) ++{ ++ ++ UINT_32 n; ++ ++ n = 0; ++ ++ while (val >= 512) { ++ n += 9; ++ val = val >> 9; ++ } ++ while (val >= 16) { ++ n += 4; ++ val >>= 4; ++ } ++ while (val >= 2) { ++ n += 1; ++ val >>= 1; ++ } ++ return n; ++} ++#endif ++ ++UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode) ++{ ++ P_IE_WMM_PARAM_T prIeWmmParam; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ UINT_8 aucACI[] = { ++ WMM_ACI_AC_BE, ++ WMM_ACI_AC_BK, ++ WMM_ACI_AC_VI, ++ WMM_ACI_AC_VO ++ }; ++ ENUM_WMM_ACI_T eAci; ++ UCHAR *pucAciAifsn, *pucEcw, *pucTxopLimit; ++ ++ ASSERT(pOutBuf); ++ ++ prIeWmmParam = (P_IE_WMM_PARAM_T) pOutBuf; ++ ++ prIeWmmParam->ucId = ELEM_ID_WMM; ++ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmParam->aucOui[0] = aucWfaOui[0]; ++ prIeWmmParam->aucOui[1] = aucWfaOui[1]; ++ prIeWmmParam->aucOui[2] = aucWfaOui[2]; ++ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; ++ ++ prIeWmmParam->ucVersion = VERSION_WMM; ++ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++ if (prAdapter->rWifiVar.fgSupportUAPSD) { ++ if (ucOpMode == OP_MODE_INFRASTRUCTURE) ++ prIeWmmParam->ucQosInfo = 0xf; ++ else ++ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; ++ } ++ ++ /* EDCA parameter */ ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ /* DBGLOG(QM, LOUD, */ ++ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ ++ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ ++ ++#if 0 ++ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].fgIsACMSet ? ++ WMM_ACIAIFSN_ACM : 0) ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].u2Aifsn & ++ (WMM_ACIAIFSN_AIFSN))); ++#else ++ /* avoid compile warnings in Klockwork tool */ ++ if (eAci == WMM_AC_BE_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BE; ++ pucEcw = &prIeWmmParam->ucEcw_BE; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_BE; ++ } else if (eAci == WMM_AC_BK_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BG; ++ pucEcw = &prIeWmmParam->ucEcw_BG; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_BG; ++ } else if (eAci == WMM_AC_VI_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VI; ++ pucEcw = &prIeWmmParam->ucEcw_VI; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_VI; ++ } else if (eAci == WMM_AC_VO_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VO; ++ pucEcw = &prIeWmmParam->ucEcw_VO; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_VO; ++ } ++ ++ *pucAciAifsn = (UINT_8) (aucACI[eAci] ++ | (prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet ? WMM_ACIAIFSN_ACM : 0) ++ | (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & (WMM_ACIAIFSN_AIFSN))); ++#endif ++ ++#if 1 ++/* *( ((PUINT_8)(&prIeWmmParam->ucEcw_BE)) + (eAci <<2) ) = (UINT_8) (0 */ ++ *pucEcw = (UINT_8) (0 | (((prBssInfo->aucCWminLog2ForBcast[eAci])) & WMM_ECW_WMIN_MASK) ++ | ((((prBssInfo->aucCWmaxLog2ForBcast[eAci])) << WMM_ECW_WMAX_OFFSET) & ++ WMM_ECW_WMAX_MASK) ++ ); ++#else ++ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 ++ | ++ (cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmin + ++ 1)) & WMM_ECW_WMIN_MASK) ++ | ++ ((cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmax + ++ 1)) << WMM_ECW_WMAX_OFFSET) & ++ WMM_ECW_WMAX_MASK) ++ ); ++#endif ++ ++#if 0 ++ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) ++ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); ++#else ++ WLAN_SET_FIELD_16(pucTxopLimit, prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); ++#endif ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ return IE_SIZE(prIeWmmParam); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Generate the WMM Param IE ++* ++* \param[in] prAdapter Adapter pointer ++* @param prMsduInfo The TX MMPDU ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_IE_WMM_PARAM_T prIeWmmParam; ++ ++#if 0 ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ UINT_8 aucACI[] = { ++ WMM_ACI_AC_BE, ++ WMM_ACI_AC_BK, ++ WMM_ACI_AC_VI, ++ WMM_ACI_AC_VO ++ }; ++ ENUM_WMM_ACI_T eAci; ++#endif ++ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("mqmGenerateWmmParamIE"); ++ DBGLOG(QM, LOUD, "\n"); ++ ++ ASSERT(prMsduInfo); ++ ++ /* In case QoS is not turned off, exit directly */ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (prStaRec) { ++ if (!prStaRec->fgIsQoS) ++ return; ++ } ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); ++ ++ if (!prBssInfo->fgIsQBSS) ++ return; ++/* 20120220 frog: update beacon content & change OP mode is a separate event for P2P network. */ ++#if 0 ++ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT && prBssInfo->eCurrentOPMode != OP_MODE_BOW) ++ return; ++#endif ++ ++ prIeWmmParam = (P_IE_WMM_PARAM_T) ++ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); ++ ++#if 0 ++ prIeWmmParam->ucId = ELEM_ID_WMM; ++ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmParam->aucOui[0] = aucWfaOui[0]; ++ prIeWmmParam->aucOui[1] = aucWfaOui[1]; ++ prIeWmmParam->aucOui[2] = aucWfaOui[2]; ++ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; ++ ++ prIeWmmParam->ucVersion = VERSION_WMM; ++ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++ if (prAdapter->rWifiVar.fgSupportUAPSD) ++ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; ++ ++ /* EDCA parameter */ ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ /* DBGLOG(QM, LOUD, */ ++ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ ++ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ ++ ++ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].fgIsACMSet ? ++ WMM_ACIAIFSN_ACM : 0) ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].u2Aifsn & ++ (WMM_ACIAIFSN_AIFSN))); ++#if 1 ++ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 ++ | ++ (((prBssInfo->aucCWminLog2ForBcast ++ [eAci])) & WMM_ECW_WMIN_MASK) ++ | ++ ((((prBssInfo->aucCWmaxLog2ForBcast ++ [eAci])) << WMM_ECW_WMAX_OFFSET) ++ & WMM_ECW_WMAX_MASK) ++ ); ++#else ++ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 ++ | ++ (cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmin + ++ 1)) & WMM_ECW_WMIN_MASK) ++ | ++ ((cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmax + ++ 1)) << WMM_ECW_WMAX_OFFSET) & ++ WMM_ECW_WMAX_MASK) ++ ); ++#endif ++ ++ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) ++ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); ++ ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmParam); ++#else ++ ++ prMsduInfo->u2FrameLength += mqmGenerateWmmParamIEByParam(prAdapter, ++ prBssInfo, (UINT_8 *) prIeWmmParam, OP_MODE_ACCESS_POINT); ++#endif ++} ++ ++ENUM_FRAME_ACTION_T ++qmGetFrameAction(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, ++ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_MAC_HEADER_T prWlanFrame; ++ UINT_16 u2TxFrameCtrl; ++ ++ DEBUGFUNC("qmGetFrameAction"); ++ ++#if (NIC_TX_BUFF_COUNT_TC4 > 2) ++#define QM_MGMT_QUUEUD_THRESHOLD 2 ++#else ++#define QM_MGMT_QUUEUD_THRESHOLD 1 ++#endif ++ ++ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD <= (NIC_TX_BUFF_COUNT_TC4)); ++ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD > 0); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkType]); ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx); ++ ++ /* XXX Check BOW P2P AIS time ot set active */ ++ if (!IS_BSS_ACTIVE(prBssInfo)) { ++ if (eFrameType == FRAME_TYPE_MMPDU) { ++ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; ++ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ ++ if (((u2TxFrameCtrl == MAC_FRAME_DEAUTH) ++ && (prMsduInfo->pfTxDoneHandler == NULL)) ++ || (u2TxFrameCtrl == MAC_FRAME_ACTION)) /* whsu */ ++ return FRAME_ACTION_TX_PKT; ++ } ++ ++ DBGLOG(QM, WARN, "Drop packets Action, eFrameType: %d (Bss Index %u).\n", ++ eFrameType, prBssInfo->ucNetTypeIndex); ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); ++ return FRAME_ACTION_DROP_PKT; ++ } ++ ++ /* TODO Handle disconnect issue */ ++ ++ /* P2P probe Request frame */ ++ do { ++ if (eFrameType == FRAME_TYPE_MMPDU) { ++ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; ++ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ ++ ++ if (u2TxFrameCtrl == MAC_FRAME_BEACON) { ++ if (prBssInfo->fgIsNetAbsent) ++ return FRAME_ACTION_DROP_PKT; ++ } else if (u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { ++ if (prBssInfo->fgIsNetAbsent) ++ return FRAME_ACTION_DROP_PKT; ++ } else if (u2TxFrameCtrl == MAC_FRAME_DEAUTH) { ++ if (prBssInfo->fgIsNetAbsent) ++ break; ++ DBGLOG(P2P, LOUD, "Sending DEAUTH Frame\n"); ++ return FRAME_ACTION_TX_PKT; ++ } ++ /* MMPDU with prStaRec && fgIsInUse not check fgIsNetActive */ ++ else if (u2TxFrameCtrl == MAC_FRAME_ASSOC_REQ ++ || u2TxFrameCtrl == MAC_FRAME_AUTH ++ || u2TxFrameCtrl == MAC_FRAME_REASSOC_REQ ++ || u2TxFrameCtrl == MAC_FRAME_PROBE_REQ || u2TxFrameCtrl == MAC_FRAME_ACTION) { ++ ++ if ((prStaRec) && (prStaRec->fgIsInPS)) { ++ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) ++ return FRAME_ACTION_TX_PKT; ++ else ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ return FRAME_ACTION_TX_PKT; ++ } ++ ++ if (!prStaRec) ++ return FRAME_ACTION_TX_PKT; ++ ++ if (!prStaRec->fgIsInUse) ++ return FRAME_ACTION_DROP_PKT; ++ ++ } /* FRAME_TYPE_MMPDU */ ++ else if (eFrameType == FRAME_TYPE_802_1X) { ++ ++ if (!prStaRec) ++ return FRAME_ACTION_TX_PKT; ++ ++ if (!prStaRec->fgIsInUse) ++ return FRAME_ACTION_DROP_PKT; ++ if (prStaRec->fgIsInPS) { ++ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) ++ return FRAME_ACTION_TX_PKT; ++ else ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ ++ } /* FRAME_TYPE_802_1X */ ++ else if ((!IS_BSS_ACTIVE(prBssInfo)) ++ || (!prStaRec) ++ || (!prStaRec->fgIsInUse)) { ++ return FRAME_ACTION_DROP_PKT; ++ } ++ } while (0); ++ ++ if (prBssInfo->fgIsNetAbsent) { ++ DBGLOG(QM, LOUD, "Queue packets (Absent %u).\n", prBssInfo->ucNetTypeIndex); ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ ++ if (prStaRec && prStaRec->fgIsInPS) { ++ DBGLOG(QM, LOUD, "Queue packets (PS %u).\n", prStaRec->fgIsInPS); ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ switch (eFrameType) { ++ case FRAME_TYPE_802_1X: ++ if (!prStaRec->fgIsValid) ++ return FRAME_ACTION_QUEUE_PKT; ++ break; ++ ++ case FRAME_TYPE_MMPDU: ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ return FRAME_ACTION_TX_PKT; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle BSS change operation Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_BSS_ABSENCE_PRESENCE_T prEventBssStatus; ++ P_BSS_INFO_T prBssInfo; ++ BOOLEAN fgIsNetAbsentOld; ++ ++ prEventBssStatus = (P_EVENT_BSS_ABSENCE_PRESENCE_T) prEvent; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prEventBssStatus->ucNetTypeIdx]); ++ fgIsNetAbsentOld = prBssInfo->fgIsNetAbsent; ++ prBssInfo->fgIsNetAbsent = prEventBssStatus->fgIsAbsent; ++ prBssInfo->ucBssFreeQuota = prEventBssStatus->ucBssFreeQuota; ++ ++ /* DBGLOG(QM, TRACE, ("qmHandleEventBssAbsencePresence (ucNetTypeIdx=%d, fgIsAbsent=%d, FreeQuota=%d)\n", */ ++ /* prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota)); */ ++ ++ DBGLOG(QM, INFO, "NAF=%d,%d,%d\n", ++ prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota); ++ ++ if (!prBssInfo->fgIsNetAbsent) { ++ /* QM_DBG_CNT_27 */ ++ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_27); ++ } else { ++ /* QM_DBG_CNT_28 */ ++ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_28); ++ } ++ /* From Absent to Present */ ++ if ((fgIsNetAbsentOld) && (!prBssInfo->fgIsNetAbsent)) ++ kalSetEvent(prAdapter->prGlueInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle STA change PS mode Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_STA_CHANGE_PS_MODE_T prEventStaChangePsMode; ++ P_STA_RECORD_T prStaRec; ++ BOOLEAN fgIsInPSOld; ++ ++ /* DbgPrint("QM:Event -RxBa\n"); */ ++ ++ prEventStaChangePsMode = (P_EVENT_STA_CHANGE_PS_MODE_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaChangePsMode->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) { ++ ++ fgIsInPSOld = prStaRec->fgIsInPS; ++ prStaRec->fgIsInPS = prEventStaChangePsMode->fgIsInPs; ++ ++ qmUpdateFreeQuota(prAdapter, ++ prStaRec, ++ prEventStaChangePsMode->ucUpdateMode, prEventStaChangePsMode->ucFreeQuota, 0); ++ ++ /* DBGLOG(QM, TRACE, ("qmHandleEventStaChangePsMode (ucStaRecIdx=%d, fgIsInPs=%d)\n", */ ++ /* prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS)); */ ++ ++ DBGLOG(QM, TRACE, "PS=%d,%d\n", prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS); ++ ++ /* From PS to Awake */ ++ if ((fgIsInPSOld) && (!prStaRec->fgIsInPS)) ++ kalSetEvent(prAdapter->prGlueInfo); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Update STA free quota Event from FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_STA_UPDATE_FREE_QUOTA_T prEventStaUpdateFreeQuota; ++ P_STA_RECORD_T prStaRec; ++ ++ prEventStaUpdateFreeQuota = (P_EVENT_STA_UPDATE_FREE_QUOTA_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaUpdateFreeQuota->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) { ++ if (prStaRec->fgIsInPS) { ++ qmUpdateFreeQuota(prAdapter, ++ prStaRec, ++ prEventStaUpdateFreeQuota->ucUpdateMode, ++ prEventStaUpdateFreeQuota->ucFreeQuota, ++ prEventStaUpdateFreeQuota->aucReserved[0]); ++ ++ kalSetEvent(prAdapter->prGlueInfo); ++ } ++#if 0 ++ DBGLOG(QM, TRACE, ++ "qmHandleEventStaUpdateFreeQuota (ucStaRecIdx=%d, ucUpdateMode=%d, ucFreeQuota=%d)\n", ++ prEventStaUpdateFreeQuota->ucStaRecIdx, prEventStaUpdateFreeQuota->ucUpdateMode, ++ prEventStaUpdateFreeQuota->ucFreeQuota); ++#endif ++ ++ DBGLOG(QM, TRACE, "UFQ=%d,%d,%d\n", ++ prEventStaUpdateFreeQuota->ucStaRecIdx, ++ prEventStaUpdateFreeQuota->ucUpdateMode, prEventStaUpdateFreeQuota->ucFreeQuota); ++ ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Update STA free quota ++* ++* \param[in] prStaRec the STA ++* \param[in] ucUpdateMode the method to update free quota ++* \param[in] ucFreeQuota the value for update ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone) ++{ ++ ++ UINT_8 ucFreeQuotaForNonDelivery; ++ UINT_8 ucFreeQuotaForDelivery; ++ BOOLEAN flgIsUpdateForcedToDelivery; ++ ++ ASSERT(prStaRec); ++ DBGLOG(QM, LOUD, "qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n", ++ prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota); ++ ++ if (!prStaRec->fgIsInPS) ++ return; ++ ++ flgIsUpdateForcedToDelivery = FALSE; ++ ++ if (ucNumOfTxDone > 0) { ++ /* ++ update free quota by ++ num of tx done + resident free quota (delivery + non-delivery) ++ */ ++ UINT_8 ucAvailQuota; ++ ++ ucAvailQuota = ucNumOfTxDone + prStaRec->ucFreeQuotaForDelivery + prStaRec->ucFreeQuotaForNonDelivery; ++ if (ucAvailQuota > ucFreeQuota) /* sanity check */ ++ ucAvailQuota = ucFreeQuota; ++ ++ /* update current free quota */ ++ ucFreeQuota = ucAvailQuota; ++ ++ /* check if the update is from last packet */ ++ if (ucFreeQuota == (prStaRec->ucFreeQuota + 1)) { ++ /* just add the extra quota to delivery queue */ ++ ++ /* ++ EX: ++ 1. TDLS peer enters power save ++ 2. When the last 2 VI packets are tx done, we will receive 2 update events ++ 3. 1st update event: ucFreeQuota = 9 ++ 4. We will correct new quota for delivey and non-delivery to 7:2 ++ 5. 2rd update event: ucFreeQuota = 10 ++ 6. We will re-correct new quota for delivery and non-delivery to 5:5 ++ ++ But non-delivery queue is not busy. ++ So in the case, we will have wrong decision, i.e. higher queue always quota 5 ++ ++ Solution: skip the 2rd update event and just add the extra quota to delivery. ++ */ ++ ++ flgIsUpdateForcedToDelivery = TRUE; ++ } ++ } ++ ++ switch (ucUpdateMode) { ++ case FREE_QUOTA_UPDATE_MODE_INIT: ++ case FREE_QUOTA_UPDATE_MODE_OVERWRITE: ++ prStaRec->ucFreeQuota = ucFreeQuota; ++ break; ++ case FREE_QUOTA_UPDATE_MODE_INCREASE: ++ prStaRec->ucFreeQuota += ucFreeQuota; ++ break; ++ case FREE_QUOTA_UPDATE_MODE_DECREASE: ++ prStaRec->ucFreeQuota -= ucFreeQuota; ++ break; ++ default: ++ ASSERT(0); ++ } ++ ++ DBGLOG(QM, LOUD, "qmUpdateFreeQuota new ucFreeQuota=%d)\n", prStaRec->ucFreeQuota); ++ ++ ucFreeQuota = prStaRec->ucFreeQuota; ++ ++ ucFreeQuotaForNonDelivery = 0; ++ ucFreeQuotaForDelivery = 0; ++ ++ if (ucFreeQuota > 0) { ++ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported ++ /* && prAdapter->rWifiVar.fgSupportQoS ++ && prAdapter->rWifiVar.fgSupportUAPSD */) { ++ /* XXX We should assign quota to aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES] */ ++ ++ if (flgIsUpdateForcedToDelivery == FALSE) { ++ if (prStaRec->ucFreeQuotaForNonDelivery > 0 && prStaRec->ucFreeQuotaForDelivery > 0) { ++ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } else if (prStaRec->ucFreeQuotaForNonDelivery == 0 ++ && prStaRec->ucFreeQuotaForDelivery == 0) { ++ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } else if (prStaRec->ucFreeQuotaForNonDelivery > 0) { ++ /* NonDelivery is not busy */ ++ if (ucFreeQuota >= 3) { ++ ucFreeQuotaForNonDelivery = 2; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } else { ++ ucFreeQuotaForDelivery = ucFreeQuota; ++ ucFreeQuotaForNonDelivery = 0; ++ } ++ } else if (prStaRec->ucFreeQuotaForDelivery > 0) { ++ /* Delivery is not busy */ ++ if (ucFreeQuota >= 3) { ++ ucFreeQuotaForDelivery = 2; ++ ucFreeQuotaForNonDelivery = ucFreeQuota - ucFreeQuotaForDelivery; ++ } else { ++ ucFreeQuotaForNonDelivery = ucFreeQuota; ++ ucFreeQuotaForDelivery = 0; ++ } ++ } ++ } else { ++ ucFreeQuotaForNonDelivery = 2; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } ++ } else { ++ /* no use ? */ ++ /* !prStaRec->fgIsUapsdSupported */ ++ ucFreeQuotaForNonDelivery = ucFreeQuota; ++ ucFreeQuotaForDelivery = 0; ++ } ++ } ++ /* ucFreeQuota > 0 */ ++ prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery; ++ prStaRec->ucFreeQuotaForNonDelivery = ucFreeQuotaForNonDelivery; ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ if (IS_TDLS_STA(prStaRec)) ++ DBGLOG(QM, LOUD, " quota %d %d %d\n", ++ ucFreeQuota, ucFreeQuotaForDelivery, ucFreeQuotaForNonDelivery); ++#endif ++ ++ DBGLOG(QM, LOUD, "new QuotaForDelivery = %d QuotaForNonDelivery = %d\n", ++ prStaRec->ucFreeQuotaForDelivery, prStaRec->ucFreeQuotaForNonDelivery); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return the reorder queued RX packets ++* ++* \param[in] (none) ++* ++* \return The number of queued RX packets ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4Total; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ u4Total = 0; ++ /* XXX The summation may impact the performance */ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ u4Total += prQM->arRxBaTable[i].rReOrderQue.u4NumElem; ++#if DBG && 0 ++ if (QUEUE_IS_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) ++ ASSERT(prQM->arRxBaTable[i].rReOrderQue == 0); ++#endif ++ } ++ ASSERT(u4Total <= (CFG_NUM_OF_QM_RX_PKT_NUM * 2)); ++ return u4Total; ++} ++ ++#if ARP_MONITER_ENABLE ++VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ struct sk_buff *prSkb = NULL; ++ PUINT_8 pucData = NULL; ++ UINT_16 u2EtherType = 0; ++ int arpOpCode = 0; ++ ++ prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ ++ if (!prSkb || (prSkb->len <= ETHER_HEADER_LEN)) ++ return; ++ ++ pucData = prSkb->data; ++ if (!pucData) ++ return; ++ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if (u2EtherType != ETH_P_ARP || (apIp[0] | apIp[1] | apIp[2] | apIp[3]) == 0) ++ return; ++ ++ if (strncmp(apIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], sizeof(apIp))) /* dest ip address */ ++ return; ++ ++ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); ++ if (arpOpCode == ARP_PRO_REQ) { ++ arpMoniter++; ++ if (arpMoniter > 20) { ++ DBGLOG(INIT, WARN, "IOT Critical issue, arp no resp, check AP!\n"); ++ aisBssBeaconTimeout(prAdapter); ++ arpMoniter = 0; ++ kalMemZero(apIp, sizeof(apIp)); ++ } ++ } ++} ++ ++VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ PUINT_8 pucData = NULL; ++ UINT_16 u2EtherType = 0; ++ int arpOpCode = 0; ++ P_BSS_INFO_T prBssInfo = NULL; ++ ++ if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) ++ return; ++ ++ pucData = (PUINT_8)prSwRfb->pvHeader; ++ if (!pucData) ++ return; ++ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if (u2EtherType != ETH_P_ARP) ++ return; ++ ++ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (arpOpCode == ARP_PRO_RSP) { ++ arpMoniter = 0; ++ if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { ++ if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ ++ prBssInfo->prStaRecOfAP->aucMacAddr)) { ++ strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ ++ DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", ++ apIp[0], apIp[1], apIp[2], apIp[3]); ++ } ++ } ++ } ++} ++ ++VOID qmResetArpDetect(VOID) ++{ ++ arpMoniter = 0; ++ kalMemZero(apIp, sizeof(apIp)); ++} ++#endif ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c +new file mode 100644 +index 000000000000..6f5c0bcdd90b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c +@@ -0,0 +1,1177 @@ ++/* ++** Id: @(#) gl_bow.c@@ ++*/ ++ ++/*! \file gl_bow.c ++ \brief Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS) ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_bow.c ++ * ++ * 02 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * [ALPS00235223] [Rose][ICS][Cross Feature][AEE-IPANIC]The device reboot automatically and then the "KE" pops up ++ * after you turn on the "Airplane mode".(once) ++ * ++ * [Root Cause] ++ * PAL operates BOW char dev poll after BOW char dev is registered. ++ * ++ * [Solution] ++ * Rejects PAL char device operation after BOW is unregistered or when wlan GLUE_FLAG_HALT is set. ++ * ++ * This is a workaround for BOW driver robustness, happens only in ICS. ++ * ++ * Root cause should be fixed by CR [ALPS00231570] ++ * ++ * 02 03 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5) ++ * ++ * [Root Cause] ++ * PAL operates BOW char dev poll after BOW char dev is registered. ++ * ++ * [Solution] ++ * Rejects PAL char device operation after BOW is unregistered. ++ * ++ * Happens only in ICS. ++ * ++ * Notified PAL owener to reivew MTKBT/PAL closing BOW char dev procedure. ++ * ++ * [Side Effect] ++ * None. ++ * ++ * 01 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW for 5GHz band. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 25 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Modify ampc0 char device for major number 151 for all MT6575 projects. ++ * ++ * 07 28 2011 cp.wu ++ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl ++ * unlocked_ioctl returns as long instead of int. ++ * ++ * 07 28 2011 cp.wu ++ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl ++ * migrate to unlocked ioctl interface ++ * ++ * 04 12 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add WMM IE for BOW initiator data. ++ * ++ * 04 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. ++ * ++ * 04 09 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link connection event procedure and change skb length check to 1512 bytes. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * replace alloc_netdev to alloc_netdev_mq for BoW ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update net register and BOW for concurrent features. ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 ++ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 ++ * with BOW and P2P enabled as default ++ * ++ * 02 08 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. ++ * Update BOW get MAC status, remove returning event for AIS network type. ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation ++ * needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 11 11 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix BoW timer assert issue. ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Add bowRunEventAAAComplete. ++ * ++ * 09 14 2010 cp.wu ++ * NULL ++ * correct typo: POLLOUT instead of POLL_OUT ++ * ++ * 09 13 2010 cp.wu ++ * NULL ++ * add waitq for poll() and read(). ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 05 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change variable names for multiple physical link to match with coding convention ++ * ++ * 05 05 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * multiple BoW interfaces need to compare with peer address ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * fix kalIndicateBOWEvent. ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" ++#include "debug.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#include ++#include "bss.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* @FIXME if there is command/event with payload length > 28 */ ++#define MAX_BUFFER_SIZE (64) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_BOW_TEST ++UINT_32 g_u4PrevSysTime = 0; ++UINT_32 g_u4CurrentSysTime = 0; ++UINT_32 g_arBowRevPalPacketTime[11]; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* forward declarations */ ++static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos); ++ ++static ssize_t ++mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos); ++ ++static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg); ++ ++static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait); ++ ++static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp); ++ ++static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp); ++ ++/* character file operations */ ++static const struct file_operations mt6620_ampc_fops = { ++ /* .owner = THIS_MODULE, */ ++ .read = mt6620_ampc_read, ++ .write = mt6620_ampc_write, ++ .unlocked_ioctl = mt6620_ampc_ioctl, ++ .poll = mt6620_ampc_poll, ++ .open = mt6620_ampc_open, ++ .release = mt6620_ampc_release, ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Register for character device to communicate with 802.11 PAL ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glRegisterAmpc(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE) ++ return FALSE; ++ ++#if 0 ++ /* 1. allocate major number dynamically */ ++ ++ if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0, /* first minor number */ ++ 1, /* number */ ++ GLUE_BOW_DEVICE_NAME) != 0) ++ ++ return FALSE; ++#endif ++ ++#if 1 ++ ++#if defined(CONFIG_AMPC_CDEV_NUM) ++ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0); ++#else ++ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0); ++#endif ++ ++ if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1, /* number */ ++ GLUE_BOW_DEVICE_NAME) != 0) ++ ++ return FALSE; ++#endif ++ ++ /* 2. spin-lock initialization */ ++ /* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */ ++ ++ /* 3. initialize kfifo */ ++/* prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH, ++ GFP_KERNEL, ++ &(prGlueInfo->rBowInfo.rSpinLock));*/ ++ if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL))) ++ goto fail_kfifo_alloc; ++ ++/* if(prGlueInfo->rBowInfo.prKfifo == NULL) */ ++ if (&(prGlueInfo->rBowInfo.rKfifo) == NULL) ++ goto fail_kfifo_alloc; ++ ++ /* 4. initialize cdev */ ++ cdev_init(&(prGlueInfo->rBowInfo.cdev), &mt6620_ampc_fops); ++ /* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */ ++ prGlueInfo->rBowInfo.cdev.ops = &mt6620_ampc_fops; ++ ++ /* 5. add character device */ ++ if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1)) ++ goto fail_cdev_add; ++ ++ /* 6. in queue initialization */ ++ init_waitqueue_head(&(prGlueInfo->rBowInfo.outq)); ++ ++ /* 7. finish */ ++ prGlueInfo->rBowInfo.fgIsRegistered = TRUE; ++ return TRUE; ++ ++fail_cdev_add: ++ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); ++/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ ++fail_kfifo_alloc: ++ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); ++ return FALSE; ++} /* end of glRegisterAmpc */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Unregister character device for communicating with 802.11 PAL ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glUnregisterAmpc(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE) ++ return FALSE; ++ ++ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; ++ ++ /* 1. free netdev if necessary */ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ kalUninitBowDevice(prGlueInfo); ++#endif ++ ++ /* 2. removal of character device */ ++ cdev_del(&(prGlueInfo->rBowInfo.cdev)); ++ ++ /* 3. free kfifo */ ++/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ ++ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); ++/* prGlueInfo->rBowInfo.prKfifo = NULL; */ ++/* prGlueInfo->rBowInfo.rKfifo = NULL; */ ++ ++ /* 4. free device number */ ++ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); ++ ++ return TRUE; ++} /* end of glUnregisterAmpc */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief read handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos) ++{ ++ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; ++ ssize_t retval; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ /* size check */ ++/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */ ++ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size) ++ retval = size; ++ else ++ retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); ++/* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */ ++ ++/* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ ++/* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ ++ if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) { ++ retval = -EIO; ++ return retval; ++ } ++ ++ if (copy_to_user(buf, aucBuffer, retval)) ++ retval = -EIO; ++ ++ return retval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief write handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t ++mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos) ++{ ++#if CFG_BOW_TEST ++ UINT_8 i; ++#endif ++ ++ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; ++ P_AMPC_COMMAND prCmd; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ ++ if (size > MAX_BUFFER_SIZE) ++ return -EINVAL; ++ else if (copy_from_user(aucBuffer, buf, size)) ++ return -EIO; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size); ++ ++ for (i = 0; i < MAX_BUFFER_SIZE; i++) ++ DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]); ++ ++ DBGLOG(BOW, EVENT, "BoW CMD write.\n"); ++#endif ++ ++ prCmd = (P_AMPC_COMMAND) aucBuffer; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength); ++ ++ DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(AMPC_COMMAND_HEADER_T)); ++#endif ++ ++ /* size check */ ++ if (prCmd->rHeader.u2PayloadLength + sizeof(AMPC_COMMAND_HEADER_T) != size) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Wrong CMD total length.\n"); ++#endif ++ ++ return -EINVAL; ++ } ++ ++ if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS) ++ return size; ++ else ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ioctl handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg) ++{ ++ int err = 0; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ /* permission check */ ++ if (_IOC_DIR(cmd) & _IOC_READ) ++ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); ++ else if (_IOC_DIR(cmd) & _IOC_WRITE) ++ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); ++ if (err) ++ return -EFAULT; ++ ++ /* no ioctl is implemented yet */ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ioctl handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait) ++{ ++ unsigned int retval; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ ++ poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait); ++ ++ retval = (POLLOUT | POLLWRNORM); /* always accepts incoming command packets */ ++ ++/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */ ++ ++/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */ ++ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) { ++ retval |= (POLLIN | POLLRDNORM); ++ ++/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */ ++ ++ } ++ ++ return retval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief open handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_GL_BOW_INFO prBowInfo; ++ ++ prBowInfo = container_of(inodep->i_cdev, GL_BOW_INFO, cdev); ++ ASSERT(prBowInfo); ++ ++ prGlueInfo = container_of(prBowInfo, GLUE_INFO_T, rBowInfo); ++ ASSERT(prGlueInfo); ++ ++ /* set-up private data */ ++ filp->private_data = prGlueInfo; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief close handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to indicate event for Bluetooth over Wi-Fi ++* ++* \param[in] ++* prGlueInfo ++* prEvent ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent) ++{ ++ size_t u4AvailSize, u4EventSize; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prEvent); ++ ++ /* check device */ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return; ++ ++/* u4AvailSize = ++ GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo);*/ ++ ++ u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); ++ ++ u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(AMPC_EVENT_HEADER_T); ++ ++ /* check kfifo availability */ ++ if (u4AvailSize < u4EventSize) { ++ DBGLOG(BOW, EVENT, "[bow] no space for event: %zu/%zu\n", u4EventSize, u4AvailSize); ++ return; ++ } ++ /* queue into kfifo */ ++/* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ ++/* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ ++ kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (PUINT_8) prEvent, u4EventSize); ++ wake_up_interruptible(&(prGlueInfo->rBowInfo.outq)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer ++* ++* \param[in] ++* prGlueInfo ++* rPeerAddr ++* \return ++* ENUM_BOW_DEVICE_STATE ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 i; ++ ++ ASSERT(prGlueInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalGetBowState.\n"); ++#endif ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, ++ prGlueInfo->rBowInfo.aeState[i]); ++ ++#endif ++ ++ return prGlueInfo->rBowInfo.aeState[i]; ++ } ++ } ++ ++ return BOW_DEVICE_STATE_DISCONNECTED; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Bluetooth-over-Wi-Fi state in glue layer ++* ++* \param[in] ++* prGlueInfo ++* eBowState ++* rPeerAddr ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 i; ++ ++ ASSERT(prGlueInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalSetBowState.\n"); ++ ++ DBGLOG(BOW, EVENT, "kalSetBowState, prGlueInfo->rBowInfo.arPeerAddr, %x:%x:%x:%x:%x:%x.\n", ++ prGlueInfo->rBowInfo.arPeerAddr[0], ++ prGlueInfo->rBowInfo.arPeerAddr[1], ++ prGlueInfo->rBowInfo.arPeerAddr[2], ++ prGlueInfo->rBowInfo.arPeerAddr[3], ++ prGlueInfo->rBowInfo.arPeerAddr[4], prGlueInfo->rBowInfo.arPeerAddr[5])); ++ ++ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); ++#endif ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { ++ prGlueInfo->rBowInfo.aeState[i] = eBowState; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, ++ prGlueInfo->rBowInfo.aeState[i]); ++#endif ++ ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi global state ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* BOW_DEVICE_STATE_DISCONNECTED ++* in case there is no BoW connection or ++* BoW connection under initialization ++* ++* BOW_DEVICE_STATE_STARTING ++* in case there is no BoW connection but ++* some BoW connection under initialization ++* ++* BOW_DEVICE_STATE_CONNECTED ++* in case there is any BoW connection available ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ++/* Henry, can reduce this logic to indentify state change */ ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED) ++ return BOW_DEVICE_STATE_CONNECTED; ++ } ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING) ++ return BOW_DEVICE_STATE_STARTING; ++ } ++ ++ return BOW_DEVICE_STATE_DISCONNECTED; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi operating frequency ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* in unit of KHz ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rBowInfo.u4FreqInKHz; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi role ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* 0: Responder ++* 1: Initiator ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr) ++{ ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) ++ return prGlueInfo->rBowInfo.aucRole[i]; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Bluetooth-over-Wi-Fi role ++* ++* \param[in] ++* prGlueInfo ++* ucRole ++* 0: Responder ++* 1: Initiator ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr) ++{ ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ucRole <= 1); ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) ++ prGlueInfo->rBowInfo.aucRole[i] = ucRole; /* Henry, 0 : Responder, 1 : Initiator */ ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get available Bluetooth-over-Wi-Fi physical link number ++* ++* \param[in] ++* prGlueInfo ++* \return ++* UINT_32 ++* how many physical links are aviailable ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_8 i; ++ UINT_8 ucLinkCount = 0; ++ ++ ASSERT(prGlueInfo); ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED) ++ ucLinkCount++; ++ } ++ ++#if 0 /* CFG_BOW_TEST */ ++ DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount); ++#endif ++ ++ return ucLinkCount; ++} ++ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ ++/* Net Device Hooks */ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device open (ifup) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int bowOpen(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* 2. carrier on & start TX queue */ ++ netif_carrier_on(prDev); ++ netif_tx_start_all_queues(prDev); ++ ++ return 0; /* success */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device stop (ifdown) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int bowStop(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* 1. stop TX queue */ ++ netif_tx_stop_all_queues(prDev); ++ ++ /* 2. turn of carrier */ ++ if (netif_carrier_ok(prDev)) ++ netif_carrier_off(prDev); ++ ++ return 0; ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This function is TX entry point of NET DEVICE. ++ * ++ * \param[in] prSkb Pointer of the sk_buff to be sent ++ * \param[in] prDev Pointer to struct net_device ++ * ++ * \retval NETDEV_TX_OK - on success. ++ * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_QUE_T prTxQueue = NULL; ++ UINT_16 u2QueueIdx = 0; ++ UINT_8 ucDSAP, ucSSAP, ucControl; ++ UINT_8 aucOUI[3]; ++ PUINT_8 aucLookAheadBuf = NULL; ++ ++#if CFG_BOW_TEST ++ UINT_32 i; ++#endif ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prSkb); ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ ++ aucLookAheadBuf = prSkb->data; ++ ++ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; ++ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; ++ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; ++ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; ++ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; ++ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; ++ prGlueInfo->u8SkbToDriver++; ++ ++ if (!(ucDSAP == ETH_LLC_DSAP_SNAP && ++ ucSSAP == ETH_LLC_SSAP_SNAP && ++ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && ++ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && ++ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "Invalid BOW packet, skip tx\n"); ++#endif ++ ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n"); ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++ ++ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); ++ prTxQueue = &prGlueInfo->rTxQueue; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "Tx sk_buff->len: %d\n", prSkb->len); ++ DBGLOG(BOW, TRACE, "Tx sk_buff->data_len: %d\n", prSkb->data_len); ++ DBGLOG(BOW, TRACE, "Tx sk_buff->data:\n"); ++ ++ for (i = 0; i < prSkb->len; i++) { ++ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); ++ ++ if ((i + 1) % 16 == 0) ++ DBGLOG(BOW, TRACE, "\n"); ++ } ++ ++ DBGLOG(BOW, TRACE, "\n"; ++#endif ++#if CFG_BOW_TEST ++/* g_u4CurrentSysTime = (OS_SYSTIME)kalGetTimeTick(; */ ++ g_u4CurrentSysTime = (OS_SYSTIME) jiffies_to_usecs(jiffies); ++ i = g_u4CurrentSysTime - g_u4PrevSysTime; ++ if ((i >> 10) > 0) ++ i = 10; ++ else ++ i = i >> 7; ++ g_arBowRevPalPacketTime[i]++; ++ g_u4PrevSysTime = g_u4CurrentSysTime; ++#endif ++ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); ++ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx] >= ++ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) ++ DBGLOG(TX, INFO, "netif_stop_subqueue for BOW, Queue len: %d\n", ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); ++ ++ netif_stop_subqueue(prDev, u2QueueIdx); ++ } else { ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++ } ++ ++ kalSetEvent(prGlueInfo); ++ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ ++ return NETDEV_TX_OK; ++} ++ ++/* callbacks for netdevice */ ++static const struct net_device_ops bow_netdev_ops = { ++ .ndo_open = bowOpen, .ndo_stop = bowStop, .ndo_start_xmit = bowHardStartXmit,}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief initialize net device for Bluetooth-over-Wi-Fi ++* ++* \param[in] ++* prGlueInfo ++* prDevName ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName) ++{ ++ P_ADAPTER_T prAdapter; ++ P_GL_HIF_INFO_T prHif; ++ PARAM_MAC_ADDRESS rMacAddr; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ prHif = &prGlueInfo->rHifInfo; ++ ASSERT(prHif); ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) { ++ prGlueInfo->rBowInfo.prDevHandler = ++ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); ++ if (!prGlueInfo->rBowInfo.prDevHandler) ++ return FALSE; ++ ++ /* 1. setup netdev */ ++ /* 1.1 Point to shared glue structure */ ++ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo; ++ /* 1.2 fill hardware address */ ++ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); ++ rMacAddr[0] |= 0x2; ++ /* change to local administrated address */ ++ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr); ++ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->perm_addr, ++ prGlueInfo->rBowInfo.prDevHandler->dev_addr); ++ /* 1.3 register callback functions */ ++ prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops; ++#if (MTK_WCN_HIF_SDIO == 0) ++ SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, prHif->Dev); ++#endif ++ register_netdev(prGlueInfo->rBowInfo.prDevHandler); ++ /* 2. net device initialize */ ++ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); ++ /* 3. finish */ ++ prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE; ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief uninitialize net device for Bluetooth-over-Wi-Fi ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ /* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */ ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) { ++ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; ++ if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler)) ++ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); ++ ++ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); ++ /* netdevice unregistration & free */ ++ unregister_netdev(prGlueInfo->rBowInfo.prDevHandler); ++ free_netdev(prGlueInfo->rBowInfo.prDevHandler); ++ prGlueInfo->rBowInfo.prDevHandler = NULL; ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++#endif /* CFG_BOW_SEPARATE_DATA_PATH */ ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c +new file mode 100644 +index 000000000000..1fed65ebc60e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c +@@ -0,0 +1,3110 @@ ++/* ++** Id: @(#) gl_cfg80211.c@@ ++*/ ++ ++/*! \file gl_cfg80211.c ++ \brief Main routines for supporintg MT6620 cfg80211 control interface ++ ++ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_cfg80211.c ++** ++** 09 05 2013 cp.wu ++** correct length to pass to wlanoidSetBssid() ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 11 23 2012 yuche.tsai ++** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely ++** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" ++#include "debug.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#include ++#include ++#include ++#include "gl_cfg80211.h" ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor ++to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause ++is that there is no resource in TC4, so del key command was not able to set, and then oid ++timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this ++workaround */ ++static UINT_8 gucKeyIndex = 255; ++ ++P_SW_RFB_T g_arGscnResultsTempBuffer[MAX_BUFFERED_GSCN_RESULTS]; ++UINT_8 g_GscanResultsTempBufferIndex = 0; ++UINT_8 g_arGscanResultsIndicateNumber[MAX_BUFFERED_GSCN_RESULTS] = { 0, 0, 0, 0, 0 }; ++ ++UINT_8 g_GetResultsBufferedCnt = 0; ++UINT_8 g_GetResultsCmdCnt = 0; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for change STA type between ++ * 1. Infrastructure Client (Non-AP STA) ++ * 2. Ad-Hoc IBSS ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_change_iface(struct wiphy *wiphy, ++ struct net_device *ndev, enum nl80211_iftype type, /*u32 *flags,*/ struct vif_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (type == NL80211_IFTYPE_STATION) ++ eOpMode = NET_TYPE_INFRA; ++ else if (type == NL80211_IFTYPE_ADHOC) ++ eOpMode = NET_TYPE_IBSS; ++ else ++ return -EINVAL; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", rStatus); ++ ++ /* reset wpa info */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for adding key ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) ++{ ++ PARAM_KEY_T rKey; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Rslt = -EINVAL; ++ UINT_32 u4BufLen = 0; ++ UINT_8 tmp1[8]; ++ UINT_8 tmp2[8]; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(&rKey, sizeof(PARAM_KEY_T)); ++ ++ rKey.u4KeyIndex = key_index; ++ ++ if (mac_addr) { ++ COPY_MAC_ADDR(rKey.arBSSID, mac_addr); ++ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && ++ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ } ++ if (rKey.arBSSID[0] != 0xFF) { ++ rKey.u4KeyIndex |= BIT(31); ++ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || ++ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) ++ rKey.u4KeyIndex |= BIT(30); ++ } ++ } else { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ /* rKey.u4KeyIndex |= BIT(31);//Enable BIT 31 will make tx use bc key id,should use pairwise key id 0 */ ++ } ++ ++ if (params->key) { ++ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ ++ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); ++ if (params->key_len == 32) { ++ kalMemCopy(tmp1, ¶ms->key[16], 8); ++ kalMemCopy(tmp2, ¶ms->key[24], 8); ++ kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); ++ kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); ++ } ++ } ++ ++ rKey.u4KeyLength = params->key_len; ++ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) ++ i4Rslt = 0; ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for getting key for specified STA ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ /* not implemented */ ++ ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for removing key for specified STA ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ PARAM_REMOVE_KEY_T rRemoveKey; ++ UINT_32 u4BufLen = 0; ++ INT_32 i4Rslt = -EINVAL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); ++ if (mac_addr) ++ COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); ++ else if (key_index <= gucKeyIndex) { /* new operation, reset gucKeyIndex */ ++ gucKeyIndex = 255; ++ } else { /* bypass the next remove key operation */ ++ gucKeyIndex = key_index; ++ return -EBUSY; ++ } ++ rRemoveKey.u4KeyIndex = key_index; ++ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "remove key error:%x\n", rStatus); ++ if (WLAN_STATUS_FAILURE == rStatus && mac_addr) { ++ i4Rslt = -EBUSY; ++ gucKeyIndex = key_index; ++ } ++ } else { ++ gucKeyIndex = 255; ++ i4Rslt = 0; ++ } ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for setting default key on an interface ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ /* not implemented */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for setting set_default_mgmt_ke on an interface ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for getting station information such as RSSI ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo) ++{ ++#define LINKSPEED_MAX_RANGE_11BGN 3000 ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ PARAM_MAC_ADDRESS arBssid; ++ UINT_32 u4BufLen; ++ UINT_32 u4Rate = 0; ++ UINT_32 u8diffTxBad, u8diffRetry; ++ INT_32 i4Rssi = 0; ++ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(arBssid, MAC_ADDR_LEN); ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); ++ ++ /* 1. check BSSID */ ++ if (UNEQUAL_MAC_ADDR(arBssid, mac)) { ++ /* wrong MAC address */ ++ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", ++ mac, arBssid); ++ return -ENOENT; ++ } ++ ++ /* 2. fill TX rate */ ++ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { ++ /* not connected */ ++ DBGLOG(REQ, WARN, "not yet connected\n"); ++ } else { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); ++ ++ if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) { ++ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n")); */ ++ DBGLOG(REQ, WARN, "last link speed\n"); ++ sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache; ++ } else { ++ /* sinfo->filled |= STATION_INFO_TX_BITRATE; */ ++ sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */ ++ prGlueInfo->u4LinkSpeedCache = u4Rate / 1000; ++ } ++ } ++ ++ /* 3. fill RSSI */ ++ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { ++ /* not connected */ ++ DBGLOG(REQ, WARN, "not yet connected\n"); ++ } else { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM) ++ || (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) { ++ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n"); */ ++ DBGLOG(REQ, WARN, "last rssi\n"); ++ sinfo->signal = prGlueInfo->i4RssiCache; ++ } else { ++ /* in the cfg80211 layer, the signal is a signed char variable. */ ++ sinfo->signal = i4Rssi; /* dBm */ ++ prGlueInfo->i4RssiCache = i4Rssi; ++ } ++ sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets; ++ ++ /* 4. Fill Tx OK and Tx Bad */ ++ ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); ++ { ++ WLAN_STATUS rStatus; ++ ++ kalMemZero(&rStatistics, sizeof(rStatistics)); ++ /* Get Tx OK/Fail cnt from AIS statistic counter */ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatisticsPL, ++ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "unable to retrieive statistic\n"); ++ } else { ++ INT_32 i4RssiThreshold = -85; /* set rssi threshold -85dBm */ ++ UINT_32 u4LinkspeedThreshold = 55; /* set link speed threshold 5.5Mbps */ ++ BOOLEAN fgWeighted = 0; ++ ++ /* calculate difference */ ++ u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0]; ++ u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1]; ++ /* restore counters */ ++ prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart; ++ prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart; ++ ++ /* check threshold is valid */ ++ if (prGlueInfo->fgPoorlinkValid) { ++ if (prGlueInfo->i4RssiThreshold) ++ i4RssiThreshold = prGlueInfo->i4RssiThreshold; ++ if (prGlueInfo->u4LinkspeedThreshold) ++ u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold; ++ } ++ /* add weighted to fail counter */ ++ if (sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold) { ++ prGlueInfo->u8TotalFailCnt += (u8diffTxBad * 16 + u8diffRetry); ++ fgWeighted = 1; ++ } else { ++ prGlueInfo->u8TotalFailCnt += u8diffTxBad; ++ } ++ /* report counters */ ++ prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart; ++ prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt; ++ ++ sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets; ++ sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors; ++ /* Good Fail Bad Difference retry difference Linkspeed Rate Weighted */ ++ DBGLOG(REQ, TRACE, ++ "Poorlink State TxOK(%d) TxFail(%d) Bad(%d) Retry(%d)", ++ sinfo->tx_packets, ++ sinfo->tx_failed, ++ (int)u8diffTxBad, ++ (int)u8diffRetry); ++ DBGLOG(REQ, TRACE, ++ "Rate(%d) Signal(%d) Weight(%d) QuadPart(%d)\n", ++ sinfo->txrate.legacy, ++ sinfo->signal, ++ (int)fgWeighted, ++ (int)rStatistics.rMultipleRetryCount.QuadPart); ++ } ++ } ++ ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for adding a station information ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params) ++{ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* ++ EX: In supplicant, ++ (Supplicant) wpa_tdls_process_tpk_m3() -> ++ (Supplicant) wpa_tdls_enable_link() -> ++ (Supplicant) wpa_sm_tdls_peer_addset() -> ++ (Supplicant) ..tdls_peer_addset() -> ++ (Supplicant) wpa_supplicant_tdls_peer_addset() -> ++ (Supplicant) wpa_drv_sta_add() -> ++ (Supplicant) ..sta_add() -> ++ (Supplicant) wpa_driver_nl80211_sta_add() -> ++ (NL80211) nl80211_set_station() -> ++ (Driver) mtk_cfg80211_change_station() ++ ++ if nl80211_set_station fails, supplicant will tear down the link. ++ */ ++ P_GLUE_INFO_T prGlueInfo; ++ TDLS_CMD_PEER_UPDATE_T rCmdUpdate; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen, u4Temp; ++ ++ /* sanity check */ ++ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) ++ return -EINVAL; ++ ++ DBGLOG(TDLS, INFO, "%s: 0x%p 0x%x\n", __func__, params->supported_rates, params->sta_flags_set); ++ ++ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) ++ return -EOPNOTSUPP; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) ++ return -EINVAL; ++ ++ /* TODO: check if we are station mode, not AP mode */ ++ ++ /* init */ ++ kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate)); ++ kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6); ++ ++ if (params->supported_rates != NULL) { ++ u4Temp = params->supported_rates_len; ++ if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX) { ++ u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX; ++ DBGLOG(TDLS, ERROR, "%s sup rate too long: %d\n", __func__, params->supported_rates_len); ++ } ++ kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp); ++ rCmdUpdate.u2SupRateLen = u4Temp; ++ } ++ ++ /* ++ In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM ++ So force to support UAPSD here. ++ */ ++ rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */ ++ rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */ ++ ++ DBGLOG(TDLS, INFO, "%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n", ++ __func__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp); ++ ++ rCmdUpdate.u2Capability = params->capability; ++ ++ if (params->ext_capab != NULL) { ++ u4Temp = params->ext_capab_len; ++ if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN) { ++ u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN; ++ DBGLOG(TDLS, ERROR, "%s ext_capab too long: %d\n", __func__, params->ext_capab_len); ++ } ++ kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp); ++ rCmdUpdate.u2ExtCapLen = u4Temp; ++ } ++ ++ if (params->ht_capa != NULL) { ++ DBGLOG(TDLS, INFO, "%s: peer is 11n device\n", __func__); ++ ++ rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info; ++ rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info; ++ rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info; ++ rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info; ++ rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info; ++ kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask, ++ params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask)); ++ rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest; ++ rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params; ++ rCmdUpdate.fgIsSupHt = TRUE; ++ } ++ ++ /* update a TDLS peer record */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexPeerUpdate, ++ &rCmdUpdate, sizeof(TDLS_CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s update error:%x\n", __func__, rStatus); ++ return -EINVAL; ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for adding a station information ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params) ++{ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ ++ P_GLUE_INFO_T prGlueInfo; ++ TDLS_CMD_PEER_ADD_T rCmdCreate; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) ++ return -EINVAL; ++ ++ /* ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, ++ NULL, 0); ++ ++ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, ++ u16 aid, u16 capability, const u8 *supp_rates, ++ size_t supp_rates_len, ++ const struct ieee80211_ht_capabilities *ht_capab, ++ const struct ieee80211_vht_capabilities *vht_capab, ++ u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len) ++ ++ Only MAC address of the peer is valid. ++ */ ++ ++ DBGLOG(TDLS, INFO, "%s: 0x%p %d\n", __func__, params->supported_rates, params->supported_rates_len); ++ ++ /* sanity check */ ++ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) ++ return -EOPNOTSUPP; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) ++ return -EINVAL; ++ ++ /* TODO: check if we are station mode, not AP mode */ ++ ++ /* init */ ++ kalMemZero(&rCmdCreate, sizeof(rCmdCreate)); ++ kalMemCopy(rCmdCreate.aucPeerMac, mac, 6); ++ ++#if 0 ++ rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ ++ rCmdCreate.u2CapInfo = params->capability; ++ ++ DBGLOG(TDLS, INFO, " %s: capability = 0x%x\n", __func__, rCmdCreate.u2CapInfo); ++ ++ if ((params->supported_rates != NULL) && (params->supported_rates_len != 0)) { ++ UINT32 u4Idx; ++ ++ DBGLOG(TDLS, INFO, " %s: sup rate = 0x", __func__); ++ ++ rIeSup.ucId = ELEM_ID_SUP_RATES; ++ rIeSup.ucLength = params->supported_rates_len; ++ for (u4Idx = 0; u4Idx < rIeSup.ucLength; u4Idx++) { ++ rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx]; ++ DBGLOG(TDLS, INFO, "%x ", rIeSup.aucSupportedRates[u4Idx]); ++ } ++ DBGLOG(TDLS, INFO, "\n"); ++ ++ rateGetRateSetFromIEs(&rIeSup, ++ NULL, ++ &rCmdCreate.u2OperationalRateSet, ++ &rCmdCreate.u2BSSBasicRateSet, &rCmdCreate.fgIsUnknownBssBasicRate); ++ } ++ ++ /* phy type */ ++#endif ++ ++ /* create a TDLS peer record */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexPeerAdd, ++ &rCmdCreate, sizeof(TDLS_CMD_PEER_ADD_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s create error:%x\n", __func__, rStatus); ++ return -EINVAL; ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for deleting a station information ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ * ++ * @other ++ * must implement if you have add_station(). ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params) ++//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to do a scan ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++static PARAM_SCAN_REQUEST_EXT_T rScanRequest; ++int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++/* PARAM_SCAN_REQUEST_EXT_T rScanRequest; */ ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "mtk_cfg80211_scan\n"); ++ kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T)); ++ ++ /* check if there is any pending scan not yet finished */ ++ if (prGlueInfo->prScanRequest != NULL) { ++ DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n"); ++ return -EBUSY; ++ } ++ ++ if (request->n_ssids == 0) { ++ rScanRequest.rSsid.u4SsidLen = 0; ++ } else if (request->n_ssids == 1) { ++ COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid, ++ request->ssids[0].ssid_len); ++ } else { ++ DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", request->n_ssids); ++ return -EINVAL; ++ } ++ ++ if (request->ie_len > 0) { ++ rScanRequest.u4IELength = request->ie_len; ++ rScanRequest.pucIE = (PUINT_8) (request->ie); ++ } else { ++ rScanRequest.u4IELength = 0; ++ } ++#if 0 ++ prGlueInfo->prScanRequest = request; ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssidListScanExt, ++ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); ++ prGlueInfo->prScanRequest = NULL; ++ return -EINVAL; ++ } ++ ++ /*prGlueInfo->prScanRequest = request;*/ ++#endif ++ ++ prGlueInfo->prScanRequest = request; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssidListScanExt, ++ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ prGlueInfo->prScanRequest = NULL; ++ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static UINT_8 wepBuf[48]; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to connect to ++ * the ESS with the specified parameters ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ UINT_32 cipher; ++ PARAM_CONNECT_T rNewSsid; ++ BOOLEAN fgCarryWPSIE = FALSE; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "[wlan] mtk_cfg80211_connect %p %zu\n", sme->ie, sme->ie_len); ++ ++ if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) ++ eOpMode = NET_TYPE_AUTO_SWITCH; ++ else ++ eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ /* after set operation mode, key table are cleared */ ++ ++ /* reset wpa info */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; ++ else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2; ++ else ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ ++ switch (sme->auth_type) { ++ case NL80211_AUTHTYPE_OPEN_SYSTEM: ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++ break; ++ case NL80211_AUTHTYPE_SHARED_KEY: ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; ++ break; ++ default: ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY; ++ break; ++ } ++ ++ if (sme->crypto.n_ciphers_pairwise) { ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = ++ sme->crypto.ciphers_pairwise[0]; ++ switch (sme->crypto.ciphers_pairwise[0]) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40; ++ break; ++ case WLAN_CIPHER_SUITE_WEP104: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104; ++ break; ++ case WLAN_CIPHER_SUITE_TKIP: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; ++ break; ++ case WLAN_CIPHER_SUITE_AES_CMAC: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]); ++ return -EINVAL; ++ } ++ } ++ ++ if (sme->crypto.cipher_group) { ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group; ++ switch (sme->crypto.cipher_group) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40; ++ break; ++ case WLAN_CIPHER_SUITE_WEP104: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104; ++ break; ++ case WLAN_CIPHER_SUITE_TKIP: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; ++ break; ++ case WLAN_CIPHER_SUITE_AES_CMAC: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); ++ return -EINVAL; ++ } ++ } ++ ++ if (sme->crypto.n_akm_suites) { ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = ++ sme->crypto.akm_suites[0]; ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) { ++ switch (sme->crypto.akm_suites[0]) { ++ case WLAN_AKM_SUITE_8021X: ++ eAuthMode = AUTH_MODE_WPA; ++ break; ++ case WLAN_AKM_SUITE_PSK: ++ eAuthMode = AUTH_MODE_WPA_PSK; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); ++ return -EINVAL; ++ } ++ } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { ++ switch (sme->crypto.akm_suites[0]) { ++ case WLAN_AKM_SUITE_8021X: ++ eAuthMode = AUTH_MODE_WPA2; ++ break; ++ case WLAN_AKM_SUITE_PSK: ++ eAuthMode = AUTH_MODE_WPA2_PSK; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); ++ return -EINVAL; ++ } ++ } ++ } ++ ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { ++ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? ++ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; ++ } ++ ++ prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy; ++ ++ prGlueInfo->fgWpsActive = FALSE; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ prGlueInfo->fgConnectHS20AP = FALSE; ++#endif ++ ++ if (sme->ie && sme->ie_len > 0) { ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ PUINT_8 prDesiredIE = NULL; ++ PUINT_8 pucIEStart = (PUINT_8)sme->ie; ++ ++#if CFG_SUPPORT_WAPI ++ if (wextSrchDesiredWAPIIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiAssocInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(SEC, WARN, "[wapi] set wapi assoc info error:%x\n", rStatus); ++ } ++#endif ++ ++ DBGLOG(REQ, TRACE, "[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n", ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode); ++ ++#if CFG_SUPPORT_WPS2 ++ if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ prGlueInfo->fgWpsActive = TRUE; ++ fgCarryWPSIE = TRUE; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWSCAssocInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(SEC, WARN, "WSC] set WSC assoc info error:%x\n", rStatus); ++ } ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetHS20Info, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInterworkingInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRoamingConsortiumIEInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ ++ } ++ } ++#endif ++ } ++ ++ /* clear WSC Assoc IE buffer in case WPS IE is not detected */ ++ if (fgCarryWPSIE == FALSE) { ++ kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200); ++ prGlueInfo->u2WSCAssocInfoIELen = 0; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus); ++ ++ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; ++ ++ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) { ++ if (cipher & IW_AUTH_CIPHER_CCMP) { ++ eEncStatus = ENUM_ENCRYPTION3_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_TKIP) { ++ eEncStatus = ENUM_ENCRYPTION2_ENABLED; ++ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_NONE) { ++ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } else { ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } ++ } else { ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "set encryption mode error:%x\n", rStatus); ++ ++ if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { ++ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; ++ ++ prWepKey->u4Length = 12 + sme->key_len; ++ prWepKey->u4KeyLength = (UINT_32) sme->key_len; ++ prWepKey->u4KeyIndex = (UINT_32) sme->key_idx; ++ prWepKey->u4KeyIndex |= BIT(31); ++ if (prWepKey->u4KeyLength > 32) { ++ DBGLOG(REQ, ERROR, "Too long key length (%u)\n", prWepKey->u4KeyLength); ++ return -EINVAL; ++ } ++ kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddWep, ++ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ } ++ ++ if (sme->channel) ++ rNewSsid.u4CenterFreq = sme->channel->center_freq; ++ else ++ rNewSsid.u4CenterFreq = 0; ++ rNewSsid.pucBssid = (UINT_8 *)sme->bssid; ++ rNewSsid.pucSsid = (UINT_8 *)sme->ssid; ++ rNewSsid.u4SsidLen = sme->ssid_len; ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetConnect, ++ (PVOID)(&rNewSsid), sizeof(PARAM_CONNECT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "set SSID:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to disconnect from ++ * currently connected ESS ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to join an IBSS group ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params) ++{ ++ PARAM_SSID_T rNewSsid; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ ++ UINT_32 u4BufLen = 0; ++ WLAN_STATUS rStatus; ++ struct ieee80211_channel *channel = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ /* set channel */ ++ if (params->chandef.chan) ++ channel = params->chandef.chan; ++ if (channel) { ++ u4ChnlFreq = nicChannelNum2Freq(channel->hw_value); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetFrequency, ++ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ } ++ ++ /* set SSID */ ++ kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetSsid, ++ (PVOID)(&rNewSsid), sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++ ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to leave from IBSS group ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to configure ++ * WLAN power managemenet ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ PARAM_POWER_MODE ePowerMode; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (enabled) { ++ if (timeout == -1) ++ ePowerMode = Param_PowerModeFast_PSP; ++ else ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else { ++ ePowerMode = Param_PowerModeCAM; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSet802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to cache ++ * a PMKID for a BSSID ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_PARAM_PMKID_T prPmkid; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); ++ return -ENOMEM; ++ } ++ ++ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); ++ prPmkid->u4BSSIDInfoCount = 1; ++ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6); ++ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "add pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to remove ++ * a cached PMKID for a BSSID ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) ++{ ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to flush ++ * all cached PMKID ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_PARAM_PMKID_T prPmkid; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_FLUSH\n"); ++ return -ENOMEM; ++ } ++ ++ prPmkid->u4Length = 8; ++ prPmkid->u4BSSIDInfoCount = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "flush pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); ++ ++ return 0; ++} ++ ++void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, ++ IN struct wireless_dev *wdev, ++ IN u16 frame_type, IN bool reg) ++{ ++#if 0 ++ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; ++#endif ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ do { ++ ++ DBGLOG(REQ, LOUD, "mtk_cfg80211_mgmt_frame_register\n"); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ switch (frame_type) { ++ case MAC_FRAME_PROBE_REQ: ++ if (reg) { ++ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(REQ, LOUD, "Open packet filer probe request\n"); ++ } else { ++ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(REQ, LOUD, "Close packet filer probe request\n"); ++ } ++ break; ++ case MAC_FRAME_ACTION: ++ if (reg) { ++ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(REQ, LOUD, "Open packet filer action frame.\n"); ++ } else { ++ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(REQ, LOUD, "Close packet filer action frame.\n"); ++ } ++ break; ++ default: ++ DBGLOG(REQ, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type); ++ break; ++ } ++ ++ if (prGlueInfo->prAdapter != NULL) { ++ /* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */ ++ set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ if (in_interrupt()) ++ DBGLOG(REQ, TRACE, "It is in interrupt level\n"); ++ } ++#if 0 ++ ++ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ sizeof ++ (MSG_P2P_MGMT_FRAME_REGISTER_T)); ++ ++ if (prMgmtFrameRegister == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; ++ ++ prMgmtFrameRegister->u2FrameType = frame_type; ++ prMgmtFrameRegister->fgIsRegister = reg; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); ++ ++#endif ++ ++ } while (FALSE); ++ ++} /* mtk_cfg80211_mgmt_frame_register */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to stay on a ++ * specified channel ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, ++ unsigned int duration, u64 *cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++#if 1 ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ *cookie = prGlueInfo->u8Cookie++; ++ ++ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T)); ++ ++ if (prMsgChnlReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ kalMemZero(prMsgChnlReq, sizeof(MSG_REMAIN_ON_CHANNEL_T)); ++ ++ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL; ++ prMsgChnlReq->u8Cookie = *cookie; ++ prMsgChnlReq->u4DurationMs = duration; ++ ++ prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000); ++ ++ switch (chan->band) { ++ case NL80211_BAND_2GHZ: ++ prMsgChnlReq->eBand = BAND_2G4; ++ break; ++ case NL80211_BAND_5GHZ: ++ prMsgChnlReq->eBand = BAND_5G; ++ break; ++ default: ++ prMsgChnlReq->eBand = BAND_2G4; ++ break; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to cancel staying ++ * on a specified channel ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ u64 cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL)) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++#if 1 ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ prMsgChnlAbort = ++ cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T)); ++ ++ if (prMsgChnlAbort == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL; ++ prMsgChnlAbort->u8Cookie = cookie; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to send a management frame ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL; ++ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; ++ PUINT_8 pucFrameBuf = (PUINT_8) NULL; ++ ++ do { ++#if 1 ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ *cookie = prGlueInfo->u8Cookie++; ++ ++ /* Channel & Channel Type & Wait time are ignored. */ ++ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T)); ++ ++ if (prMsgTxReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgTxReq->fgNoneCckRate = FALSE; ++ prMsgTxReq->fgIsWaitRsp = TRUE; ++ ++ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); ++ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; ++ if (prMsgTxReq->prMgmtMsduInfo == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgTxReq->u8Cookie = *cookie; ++ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX; ++ ++ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); ++ ++ kalMemCopy(pucFrameBuf, params->buf, params->len); ++ ++ prMgmtFrame->u2FrameLength = params->len; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { ++ if (prMsgTxReq->prMgmtMsduInfo != NULL) ++ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); ++ ++ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); ++ } ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to cancel the wait time ++ * from transmitting a management frame on another channel ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ u64 cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ /* not implemented */ ++ ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for handling sched_scan start/stop request ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++ ++int ++mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, ++ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 i, u4BufLen; ++ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ ASSERT(prGlueInfo); ++ ++ /* check if there is any pending scan/sched_scan not yet finished */ ++ if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) { ++ DBGLOG(SCN, ERROR, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n"); ++ return -EBUSY; ++ } else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) { ++ DBGLOG(SCN, ERROR, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n"); ++ /* invalid scheduled scan request */ ++ return -EINVAL; ++ } else if (/* !request->n_ssids || */!request->n_match_sets) { ++ /* invalid scheduled scan request */ ++ return -EINVAL; ++ } ++ ++ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE); ++ if (prSchedScanRequest == NULL) { ++ DBGLOG(SCN, ERROR, "(prSchedScanRequest == NULL) kalMemAlloc fail\n"); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST)); ++ ++ prSchedScanRequest->u4SsidNum = request->n_match_sets; ++ for (i = 0; i < request->n_match_sets; i++) { ++ if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) { ++ prSchedScanRequest->arSsid[i].u4SsidLen = 0; ++ } else { ++ COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid, ++ prSchedScanRequest->arSsid[i].u4SsidLen, ++ request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len); ++ } ++ } ++ ++ prSchedScanRequest->u4IELength = request->ie_len; ++ if (request->ie_len > 0) ++ prSchedScanRequest->pucIE = (PUINT_8) (request->ie); ++ ++ prSchedScanRequest->u2ScanInterval = (UINT_16) (request->scan_plans[0].interval); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetStartSchedScan, ++ prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST)); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(SCN, ERROR, "scheduled scan error:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ prGlueInfo->prSchedScanRequest = request; ++ ++ return 0; ++} ++ ++int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev, u64 reqid) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ /* check if there is any pending scan/sched_scan not yet finished */ ++ if (prGlueInfo->prSchedScanRequest == NULL) { ++ DBGLOG(SCN, ERROR, "prGlueInfo->prSchedScanRequest == NULL\n"); ++ return -EBUSY; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(SCN, ERROR, "scheduled scan error, rStatus: %d\n", rStatus); ++ return -EINVAL; ++ } ++ ++ /* 1. reset first for newly incoming request */ ++ /* GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ ++ if (prGlueInfo->prSchedScanRequest != NULL) ++ prGlueInfo->prSchedScanRequest = NULL; ++ /* GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ ++ ++ DBGLOG(SCN, TRACE, "start work queue to send event\n"); ++ schedule_delayed_work(&sched_workq, 0); ++ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for handling association request ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_MAC_ADDRESS arBssid; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ PUINT_8 prDesiredIE = NULL; ++#endif ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(arBssid, MAC_ADDR_LEN); ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); ++ ++ /* 1. check BSSID */ ++ if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) { ++ /* wrong MAC address */ ++ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", ++ req->bss->bssid, arBssid); ++ return -ENOENT; ++ } ++ ++ if (req->ie && req->ie_len > 0) { ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetHS20Info, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ ++ if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInterworkingInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ ++ if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRoamingConsortiumIEInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ ++ } ++ } ++#endif ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssid, ++ (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#if CONFIG_NL80211_TESTMODE ++/* ++#define NLA_PUT(skb, attrtype, attrlen, data) \ ++do { \ ++ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ ++ goto nla_put_failure; \ ++} while (0) ++ ++#define NLA_PUT_TYPE(skb, type, attrtype, value) \ ++do { \ ++ type __tmp = value; \ ++ NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ ++} while (0) ++ ++#define NLA_PUT_U8(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u8, attrtype, value) ++ ++#define NLA_PUT_U16(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u16, attrtype, value) ++ ++#define NLA_PUT_U32(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u32, attrtype, value) ++ ++#define NLA_PUT_U64(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u64, attrtype, value) ++*/ ++#if CFG_SUPPORT_WAPI ++int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL; ++ struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4BufLen = 0; ++ ++ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; ++ ++ memset(keyStructBuf, 0, sizeof(keyStructBuf)); ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data; ++ } else { ++ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_key_ext, data is NULL\n"); ++ return -EINVAL; ++ } ++ ++ if (prParams) ++ prIWEncExt = (struct iw_encode_exts *)&prParams->ext; ++ ++ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { ++ /* KeyID */ ++ prWpiKey->ucKeyID = prParams->key_index; ++ prWpiKey->ucKeyID--; ++ if (prWpiKey->ucKeyID > 1) { ++ /* key id is out of range */ ++ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ ++ return -EINVAL; ++ } ++ ++ if (prIWEncExt->key_len != 32) { ++ /* key length not valid */ ++ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ ++ return -EINVAL; ++ } ++ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ ++ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX; ++ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX_TX; ++ } ++/* #if CFG_SUPPORT_WAPI */ ++ /* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */ ++/* #endif */ ++ /* PN */ ++ memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE); ++ memcpy(prWpiKey->aucPN + IW_ENCODE_SEQ_MAX_SIZE, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); ++ ++ ++ /* BSSID */ ++ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6); ++ ++ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); ++ prWpiKey->u4LenWPIEK = 16; ++ ++ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); ++ prWpiKey->u4LenWPICK = 16; ++ ++ rstatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiKey, ++ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rstatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ ++ fgIsValid = -EFAULT; ++ } ++ ++ } ++ return fgIsValid; ++} ++#endif ++ ++int ++mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Status = -EINVAL; ++ UINT_32 u4BufLen; ++ UINT_32 u4LinkScore; ++ UINT_32 u4TotalError; ++ UINT_32 u4TxExceedThresholdCount; ++ UINT_32 u4TxTotalCount; ++ ++ P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; ++ PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics; ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data; ++ } else { ++ DBGLOG(QM, ERROR, "mtk_cfg80211_testmode_get_sta_statistics, data is NULL\n"); ++ return -EINVAL; ++ } ++/* ++ if (!prParams->aucMacAddr) { ++ DBGLOG(QM, INFO, "%s MAC Address is NULL\n", __func__); ++ return -EINVAL; ++ } ++*/ ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); ++ ++ if (!skb) { ++ DBGLOG(QM, ERROR, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ DBGLOG(QM, TRACE, "Get [ %pM ] STA statistics\n", prParams->aucMacAddr); ++ ++ kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics)); ++ COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStaStatistics, ++ &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ /* Calcute Link Score */ ++ u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount; ++ u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount; ++ u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount; ++ ++ /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */ ++ /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */ ++ if (u4TxTotalCount) { ++ if (u4TxExceedThresholdCount <= u4TxTotalCount) ++ u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount)); ++ else ++ u4LinkScore = 0; ++ } else { ++ u4LinkScore = 90; ++ } ++ ++ u4LinkScore += 10; ++ ++ if (u4LinkScore == 10) { ++ ++ if (u4TotalError <= u4TxTotalCount) ++ u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount)); ++ else ++ u4LinkScore = 0; ++ ++ } ++ ++ if (u4LinkScore > 100) ++ u4LinkScore = 100; ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);*/ ++ { ++ unsigned char __tmp = NL80211_DRIVER_TESTMODE_VERSION; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); */ ++ { ++ unsigned int __tmp = u4LinkScore; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, &prParams->aucMacAddr) < 0)) ++ goto nla_put_failure; ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4Flag; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ /* FW part STA link status */ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);*/ ++ { ++ unsigned char __tmp = rQueryStaStatistics.ucPer; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);*/ ++ { ++ unsigned char __tmp = rQueryStaStatistics.ucRcpi; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4PhyMode; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);*/ ++ { ++ unsigned short __tmp = rQueryStaStatistics.u2LinkSpeed; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, ++ sizeof(unsigned short), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxFailCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxAverageAirTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* Driver part link status */ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxTotalCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, ++ rQueryStaStatistics.u4TxExceedThresholdCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxExceedThresholdCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, ++ rQueryStaStatistics.u4TxAverageProcessTime);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxAverageProcessTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxMaxTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxAverageHifTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxMaxHifTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, rQueryStaStatistics.u4EnqueueCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4EnqueueCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, rQueryStaStatistics.u4DequeueCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4DequeueCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, rQueryStaStatistics.u4EnqueueStaCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4EnqueueStaCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, rQueryStaStatistics.u4DequeueStaCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4DequeueStaCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, rQueryStaStatistics.IsrCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, rQueryStaStatistics.IsrPassCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrPassCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, rQueryStaStatistics.TaskIsrCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.TaskIsrCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, rQueryStaStatistics.IsrAbnormalCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrAbnormalCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, rQueryStaStatistics.IsrSoftWareCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrSoftWareCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, rQueryStaStatistics.IsrTxCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrTxCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ *NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, rQueryStaStatistics.IsrRxCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrRxCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* Network counter */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), &rQueryStaStatistics.au4TcResourceEmptyCount) < 0)) ++ goto nla_put_failure; ++ /* ++ NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, ++ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), rQueryStaStatistics.au4DequeueNoTcResource); ++ */ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, ++ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), &rQueryStaStatistics.au4DequeueNoTcResource) < 0)) ++ goto nla_put_failure; ++ /* ++ NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceBackCount), rQueryStaStatistics.au4TcResourceBackCount); ++ */ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceBackCount), &rQueryStaStatistics.au4TcResourceBackCount) < 0)) ++ goto nla_put_failure; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceUsedCount), &rQueryStaStatistics.au4TcResourceUsedCount) < 0)) ++ goto nla_put_failure; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceWantedCount), ++ &rQueryStaStatistics.au4TcResourceWantedCount) < 0)) ++ goto nla_put_failure; ++ ++ /* Sta queue length */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcQueLen), &rQueryStaStatistics.au4TcQueLen) < 0)) ++ goto nla_put_failure; ++ ++ ++ /* Global QM counter */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcAverageQueLen), &rQueryStaStatistics.au4TcAverageQueLen) < 0)) ++ goto nla_put_failure; ++ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), &rQueryStaStatistics.au4TcCurrentQueLen) < 0)) ++ goto nla_put_failure; ++ ++ ++ /* Reserved field */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, ++ sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, ++ sizeof(rQueryStaStatistics.au4Reserved), &rQueryStaStatistics.au4Reserved) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ skb = NULL; ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int ++mtk_cfg80211_testmode_get_link_detection(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Status = -EINVAL; ++ UINT_32 u4BufLen; ++ ++ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); ++ ++ if (!skb) { ++ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&rStatistics, sizeof(rStatistics)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rFailedCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rFailedCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rMultipleRetryCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rACKFailureCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rFCSErrorCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ skb = NULL; ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ if (data && len) ++ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; ++ ++ if (prParams) { ++ if (prParams->set == 1) { ++ rstatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, ++ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ } ++ ++ if (WLAN_STATUS_SUCCESS != rstatus) ++ fgIsValid = -EFAULT; ++ ++ return fgIsValid; ++} ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct wpa_driver_hs20_data_s *prParams = NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ if (data && len) { ++ prParams = (struct wpa_driver_hs20_data_s *)data; ++ ++ DBGLOG(REQ, TRACE, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType); ++ } ++ ++ if (prParams) { ++ int i; ++ ++ switch (prParams->CmdType) { ++ case HS20_CMD_ID_SET_BSSID_POOL: ++ DBGLOG(REQ, TRACE, "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n", ++ prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable, ++ prParams->hs20_set_bssid_pool.ucNumBssidPool); ++ for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) { ++ DBGLOG(REQ, TRACE, "[%d][ %pM ]\n", i, ++ (prParams->hs20_set_bssid_pool.arBssidPool[i])); ++ } ++ rstatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool, ++ &prParams->hs20_set_bssid_pool, ++ sizeof(struct param_hs20_set_bssid_pool), ++ FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ break; ++ default: ++ DBGLOG(REQ, TRACE, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType); ++ rstatus = WLAN_STATUS_FAILURE; ++ ++ } ++ ++ } ++ ++ if (WLAN_STATUS_SUCCESS != rstatus) ++ fgIsValid = -EFAULT; ++ ++ return fgIsValid; ++} ++ ++#endif ++int ++mtk_cfg80211_testmode_set_poorlink_param(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++ int fgIsValid = 0; ++ P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_POORLINK_PARAMS) data; ++ } else { ++ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_poorlink_param, data is NULL\n"); ++ return -EINVAL; ++ } ++ if (prParams->ucLinkSpeed) ++ prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed * 10; ++ if (prParams->cRssi) ++ prGlueInfo->i4RssiThreshold = prParams->cRssi; ++ if (!prGlueInfo->fgPoorlinkValid) ++ prGlueInfo->fgPoorlinkValid = 1; ++#if 0 ++ DBGLOG(REQ, TRACE, "poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n", ++ prGlueInfo->fgPoorlinkValid, prGlueInfo->i4RssiThreshold, prGlueInfo->u4LinkspeedThreshold); ++#endif ++ ++ return fgIsValid; ++ ++} ++ ++int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL; ++ INT_32 i4Status = -EINVAL; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ BOOLEAN fgIsValid = 0; ++#endif ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data; ++ } else { ++ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n"); ++ return i4Status; ++ } ++ ++ /* Clear the version byte */ ++ prParams->index = prParams->index & ~BITS(24, 31); ++ ++ if (prParams) { ++ switch (prParams->index) { ++ case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */ ++ i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len); ++ break; ++ case TESTMODE_CMD_ID_WAPI: /* WAPI */ ++#if CFG_SUPPORT_WAPI ++ i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len); ++#endif ++ break; ++ case TESTMODE_CMD_ID_SUSPEND: ++ { ++ P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS) data; ++ ++ if (prParams->suspend == 1) { ++ wlanHandleSystemSuspend(); ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pHandleSystemSuspend(); ++ i4Status = 0; ++ } else if (prParams->suspend == 0) { ++ wlanHandleSystemResume(); ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pHandleSystemResume(); ++ i4Status = 0; ++ } ++ break; ++ } ++ case TESTMODE_CMD_ID_STATISTICS: ++ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); ++ break; ++ case TESTMODE_CMD_ID_LINK_DETECT: ++ i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo); ++ break; ++ case TESTMODE_CMD_ID_POORLINK: ++ i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo); ++ break; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ case TESTMODE_CMD_ID_HS20: ++ if (mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len)) ++ fgIsValid = TRUE; ++ break; ++#endif ++ default: ++ i4Status = -EINVAL; ++ break; ++ } ++ } ++ ++ return i4Status; ++} ++ ++int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++#define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0 ++#define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1 ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0; ++ ++/* P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; */ ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32)); ++ READY_TO_BEAM = ++ (UINT_32) (prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo. ++ fgIsGOInitialDone) & ++ (!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); ++ DBGLOG(QM, TRACE, ++ "NFC:GOInitialDone[%d] and P2PScanning[%d]\n", ++ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone, ++ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); ++ ++ if (!skb) { ++ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);*/ ++ { ++ unsigned int __tmp = READY_TO_BEAM; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ skb = NULL; ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++int ++mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++#define MAXMUN_2_4G_CHA_NUM 14 ++#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 ++ ++ BOOLEAN fgIsReady = FALSE, fgIsFistRecord = TRUE; ++ BOOLEAN fgIsPureAP, fgIsLteSafeChn = FALSE; ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucDefaultIdx = 0, ucArrayIdx = 0; ++ UINT_16 u2APNumScore = 0, u2UpThreshold = 0, u2LowThreshold = 0, ucInnerIdx = 0; ++ INT_32 i4Status = -EINVAL; ++ UINT_32 u4BufLen, u4LteSafeChnBitMask_2_4G = 0; ++ UINT32 AcsChnReport[4]; ++ /*RF_CHANNEL_INFO_T aucChannelList[MAXMUN_2_4G_CHA_NUM];*/ ++ ++ struct sk_buff *skb; ++ ++ /*PARAM_GET_CHN_LOAD rQueryLTEChn;*/ ++ P_PARAM_GET_CHN_LOAD prQueryLTEChn; ++ PARAM_PREFER_CHN_INFO rPreferChannels[2], ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM]; ++ P_PARAM_CHN_LOAD_INFO prChnLoad; ++ P_PARAM_GET_CHN_LOAD prGetChnLoad; ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++/* ++ P_PARAM_GET_CHN_LOAD prParams = NULL; ++*/ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(rPreferChannels, sizeof(rPreferChannels)); ++ fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; ++#if 0 ++ if (data && len) ++ prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS) data; ++#endif ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(AcsChnReport) + sizeof(UINT8) + 1); ++ if (!skb) { ++ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n"); ++ prQueryLTEChn = kalMemAlloc(sizeof(PARAM_GET_CHN_LOAD), VIR_MEM_TYPE); ++ if (prQueryLTEChn == NULL) { ++ DBGLOG(QM, TRACE, "alloc QueryLTEChn fail\n"); ++ kalMemFree(skb, VIR_MEM_TYPE, sizeof(struct sk_buff)); ++ return -ENOMEM; ++ } ++ kalMemZero(prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD)); ++ ++ /* Query LTE Safe Channels */ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] ++ = 0xFFFFFFFF; ++ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] ++ = 0xFFFFFFFF; ++ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] ++ = 0xFFFFFFFF; ++ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = ++ 0xFFFFFFFF; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryACSChannelList, prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD), ++ TRUE, FALSE, TRUE, TRUE, &u4BufLen); ++#if 0 ++ if (fgIsPureAP) { ++ ++ AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20; /* Channel 6 */ ++ } else ++#endif ++ { ++ fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit; ++ rPreferChannels[0].u2APNum = 0xFFFF; ++ rPreferChannels[1].u2APNum = 0xFFFF; ++ ++ /* 4 In LTE Mode, Hotspot pick up channels from ch4. */ ++ ucDefaultIdx = 0; ++ /* ++ if (fgIsPureAP) { ++ ucDefaultIdx=3; //SKIP LTE Channels 1~3 ++ } ++ */ ++ ++ /* 4 Get the Maximun channel List in 2.4G Bands */ ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter); ++ ASSERT(prDomainInfo); ++ ++ /* 4 ToDo: Enable Step 2 only if we could get Country Code from framework */ ++ /* 4 2. Get current domain channel list */ ++ ++#if 0 ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, ++ BAND_2G4, MAXMUN_2_4G_CHA_NUM, &ucMax_24G_Chn_List, aucChannelList); ++#endif ++ ++ prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo); ++ for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) { ++ DBGLOG(P2P, INFO, ++ "[Auto Channel] ch[%d]=%d\n", ucIdx, ++ prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx].u2APNum); ++ } ++ ++ /*Calculate Each Channel Direty Score */ ++ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { ++ ++#if 1 ++ u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND; ++ u2UpThreshold = u2LowThreshold = 3; ++ ++ if (ucIdx < 3) { ++ u2UpThreshold = ucIdx; ++ u2LowThreshold = 3; ++ } else if (ucIdx >= (ucMax_24G_Chn_List - 3)) { ++ u2UpThreshold = 3; ++ u2LowThreshold = ucMax_24G_Chn_List - (ucIdx + 1); ++ ++ } ++ ++ /*Calculate Lower Channel Dirty Score */ ++ for (ucInnerIdx = 0; ucInnerIdx < u2LowThreshold; ucInnerIdx++) { ++ ucArrayIdx = ucIdx + ucInnerIdx + 1; ++ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { ++ u2APNumScore += ++ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * ++ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); ++ } ++ } ++ ++ /*Calculate Upper Channel Dirty Score */ ++ for (ucInnerIdx = 0; ucInnerIdx < u2UpThreshold; ucInnerIdx++) { ++ ucArrayIdx = ucIdx - ucInnerIdx - 1; ++ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { ++ u2APNumScore += ++ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * ++ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); ++ } ++ } ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ ++ DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx, u2APNumScore); ++#else ++ if (ucIdx == 0) { ++ /* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = ++ (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ++ prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */ ++ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) ++ ((3 * ++ (prGetChnLoad-> ++ rEachChnLoad[ucIdx + ++ 1]. ++ u2APNum + ++ prGetChnLoad-> ++ rEachChnLoad[ucIdx + ++ 2]. ++ u2APNum)) / 4))); ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum)); ++ } ++ if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) { ++ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) ++ ((3 * ++ (prGetChnLoad-> ++ rEachChnLoad[ucIdx + ++ 1]. ++ u2APNum + ++ prGetChnLoad-> ++ rEachChnLoad[ucIdx - ++ 1]. ++ u2APNum)) / 4))); ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx, ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); ++ } ++ ++ if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) { ++ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ++ ((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4))); ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); ++ } ++#endif ++ ++ } ++ ++ u4LteSafeChnBitMask_2_4G = ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; ++ ++ /*Find out the best channel */ ++ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { ++ /* 4 Skip LTE Unsafe Channel */ ++ fgIsLteSafeChn = ((u4LteSafeChnBitMask_2_4G & BIT(ucIdx + 1)) >> ucIdx); ++ if (!fgIsLteSafeChn) ++ continue; ++ ++ prChnLoad = ++ (P_PARAM_CHN_LOAD_INFO) &(prGlueInfo->prAdapter->rWifiVar. ++ rChnLoadInfo.rEachChnLoad[ucIdx]); ++ if (rPreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) { ++ rPreferChannels[1].ucChannel = rPreferChannels[0].ucChannel; ++ rPreferChannels[1].u2APNum = rPreferChannels[0].u2APNum; ++ ++ rPreferChannels[0].ucChannel = ucIdx; ++ rPreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; ++ } else { ++ if (rPreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum ++ || fgIsFistRecord == 1) { ++ fgIsFistRecord = FALSE; ++ rPreferChannels[1].ucChannel = ucIdx; ++ rPreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; ++ } ++ } ++ } ++ /* AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] = ++ BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1)); */ ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0; ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |= BIT(rPreferChannels[0].ucChannel); ++ } ++ ++ /* ToDo: Support 5G Channel Selection */ ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344; ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788; ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC; ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n", AcsChnReport[0], AcsChnReport[1], AcsChnReport[2], ++ AcsChnReport[3]); ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ /*need confirm cfg80211_testmode_reply will free skb*/ ++ skb = NULL; ++ /*kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));*/ ++ ++nla_put_failure: ++ kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD)); ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++ ++} ++#endif ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief cfg80211 suspend callback, will be invoked in wiphy_suspend ++ * ++ * @param wiphy: pointer to wiphy ++ * wow: pointer to cfg80211_wowlan ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (kalHaltTryLock()) ++ return 0; ++ ++ if (kalIsHalted() || !wiphy) ++ goto end; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prGlueInfo->prAdapter->ulSuspendFlag); ++ set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prGlueInfo->prAdapter->ulSuspendFlag); ++end: ++ kalHaltUnlock(); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief cfg80211 resume callback, will be invoked in wiphy_resume. ++ * ++ * @param wiphy: pointer to wiphy ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_resume(struct wiphy *wiphy) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_BSS_DESC_T *pprBssDesc = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ UINT_8 i = 0; ++ ++ if (kalHaltTryLock()) ++ return 0; ++ ++ if (kalIsHalted() || !wiphy) ++ goto end; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ prAdapter = prGlueInfo->prAdapter; ++ clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag); ++ pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rNloParam.aprPendingBssDescToInd[0]; ++ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { ++ if (pprBssDesc[i] == NULL) ++ break; ++ if (pprBssDesc[i]->u2RawLength == 0) ++ continue; ++ kalIndicateBssInfo(prGlueInfo, ++ (PUINT_8) pprBssDesc[i]->aucRawBuf, ++ pprBssDesc[i]->u2RawLength, ++ pprBssDesc[i]->ucChannelNum, ++ RCPI_TO_dBm(pprBssDesc[i]->ucRCPI)); ++ } ++ DBGLOG(SCN, INFO, "pending %d sched scan results\n", i); ++ if (i > 0) ++ kalMemZero(&pprBssDesc[0], i * sizeof(P_BSS_DESC_T)); ++end: ++ kalHaltUnlock(); ++ return 0; ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c +new file mode 100644 +index 000000000000..abe366585d05 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c +@@ -0,0 +1,3501 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7 ++*/ ++ ++/*! \file gl_init.c ++ \brief Main routines of Linux driver ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_init.c ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 05 25 2012 yuche.tsai ++ * NULL ++ * Fix reset KE issue. ++ * ++ * 05 11 2012 cp.wu ++ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience ++ * show MAC address & source while initiliazation ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Enable CFG80211 Support. ++ * ++ * 12 22 2011 george.huang ++ * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency ++ * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before ++ * TX thread handling ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 14 2011 yuche.tsai ++ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. ++ * Fix large network type index assert in FW issue. ++ * ++ * 11 14 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 06 2011 eddie.chen ++ * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation ++ * Add rlmDomainGetChnlList symbol. ++ * ++ * 09 22 2011 cm.chang ++ * NULL ++ * Safer writng stype to avoid unitialized regitry structure ++ * ++ * 09 21 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Avoid possible structure alignment problem ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * expose scnQuerySparseChannel() for P2P-FSM. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting ++ * device issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 07 2011 wh.su ++ * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL ++ * Add the dumpMemory8 symbol export for debug mode. ++ * ++ * 07 06 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Improve BoW connection establishment speed. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Export one symbol for enhancement. ++ * ++ * 06 13 2011 eddie.chen ++ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni ++ * Add tx rx statistics and netif_rx_ni. ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain ++ * pass PHY_PARAM in NVRAM from driver to firmware. ++ * ++ * 05 09 2011 jeffrey.chang ++ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change ++ * support ARP filter through kernel notifier ++ * ++ * 05 03 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * Support P2P ARP filter setting on early suspend/ late resume ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Modify some driver connection flow or behavior to pass Sigma test more easier.. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 11 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * export wlan functions to p2p ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 04 08 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 04 06 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port ++ * 2. update perm_addr as well for MAC address ++ * 3. not calling check_mem_region() anymore for eHPI ++ * 4. correct MSC_CS macro for 0-based notation ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * fix typo. ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism ++ * ++ * 03 23 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * apply multi-queue operation only for linux kernel > 2.6.26 ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability for compatible with linux 2.6.12. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 18 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * remove early suspend functions ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * reverse order to prevent probing racing. ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 15 2011 jeffrey.chang ++ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM ++ * refine the queue_select function ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 03 10 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Remove unnecessary assert and message. ++ * ++ * 03 08 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Export nicQmUpdateWmmParms. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 02 24 2011 george.huang ++ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames ++ * Support ARP filter during suspended ++ * ++ * 02 21 2011 cp.wu ++ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain ++ * simplify logic for checking NVRAM existence only once. ++ * ++ * 02 17 2011 terry.wu ++ * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove ++ * Fix deference a null pointer problem in wlanRemove. ++ * ++ * 02 16 2011 jeffrey.chang ++ * NULL ++ * fix compilig error ++ * ++ * 02 16 2011 jeffrey.chang ++ * NULL ++ * Add query ipv4 and ipv6 address during early suspend and late resume ++ * ++ * 02 15 2011 jeffrey.chang ++ * NULL ++ * to support early suspend in android ++ * ++ * 02 11 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add one more export symbol. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add RX deauthentication & disassociation process under Hot-Spot mode. ++ * ++ * 02 09 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * Halt p2p module init and exit until TxThread finished p2p register and unregister. ++ * ++ * 02 08 2011 george.huang ++ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler ++ * Support querying power mode OID. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue ++ * Export Deactivation Network. ++ * ++ * 02 01 2011 jeffrey.chang ++ * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded ++ * Unregister the KAL timer during driver unloading ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 19 2011 cp.wu ++ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 ++ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues ++ * due to multiple access ++ * use mutex to protect kalIoctl() for thread safe. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 15 2010 cp.wu ++ * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver ++ * remove set MAC address. MAC address is always loaded from NVRAM instead. ++ * ++ * 12 10 2010 kevin.huang ++ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check ++ * Add Linux Proc Support ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add GPIO debug function ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 21 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * . ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK ++ * HIF by default ++ * Refine linux kernel module to the license of MTK and enable MTK HIF ++ * ++ * 10 18 2010 jeffrey.chang ++ * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android ++ * . ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 16 2010 yarco.yang ++ * NULL ++ * Support Linux x86 ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 29 2010 jeffrey.chang ++ * NULL ++ * fix memory leak for module unloading ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) remove unused spinlocks ++ * 2) enable encyption ioctls ++ * 3) fix scan ioctl which may cause supplicant to hang ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * bug fix: allocate regInfo when disabling firmware download ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * use glue layer api to decrease or increase counter atomically ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * add new spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * modify cmd/data path for new design ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) Modify set mac address code ++ * 2) remove power management macro ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * prevent supplicant accessing driver during resume ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) fix firmware download bug ++ * 2) remove query statistics for acelerating firmware download ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Query statistics from firmware ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * modify tcp/ip checksum offload flags ++ * ++ * 04 16 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix tcp/ip checksum offload bug ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler ++ * * * * * * * * * * * * * * * * * capability ++ * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix spinlock usage ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Set MAC address from firmware ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)improve none-glue code portability ++ * * (2) disable set Multicast address during atomic context ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding debug module ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix f/w download start and load address by using config.h ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download support ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090 ++** Fix compile error for Linux EHPI driver ++** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input ++** parameters and pointers. ++** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088 ++** remove non-used code ++** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088 ++** adding the module parameter for wapi ++** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088 ++** adding the code to check the wapi 1x frame ++** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461 ++** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY ++** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088 ++** set the tid and 1x value at same packet reserved field ++** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104 ++** Fix wrong variable name "prDev" in wlanStop() ++** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461 ++** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY ++** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461 ++** Update driver for Code review ++** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461 ++** Update Driver for Code Review ++** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461 ++** Update driver for code review ++** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461 ++** Add support for linux statistics ++** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461 ++** Fix ASSERT if removing module in BG_SSID_SCAN state ++** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461 ++** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS ++** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461 ++** Not use wlanoidSetCurrentAddrForLinux() ++** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461 ++** Remove WMM Assoc Flag ++** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084 ++** modify wlanISR interface ++** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461 ++** Fix Unset Broadcast filter when setMulticast ++** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461 ++** Move Query Media Status to GLUE ++** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461 ++** Revise set multicast function by using windows oid style for LP own back ++** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461 ++** Fix multicast setting in Linux and add comment ++** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461 ++** Fix set mac address func in Linux ++** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461 ++** Add set MAC Address ++** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461 ++** For Linux, set net_device has feature with checksum offload by default ++** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461 ++** Fix typo ++** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088 ++** add 1x decide code for sw port control ++** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461 ++** Rearrange the set off place of GLUE spin lock in HardStartXmit ++** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461 ++** Add debug option - Packet Order for Linux and add debug level - Event ++** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461 ++** Fix SPIN_LOCK protection ++** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425 ++** 1. Set Rx multicast packets mode before setting the address list ++** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461 ++** Add OS_TIMESTAMP to packet ++** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088 ++** fixed the unload module issue ++** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461 ++** Fix compile warnning ++** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425 ++** 1. Refine for multicast list ++** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461 ++** Add VOIP SCAN Support & Refine Roaming ++** Revision 1.4 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:50 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "gl_cfg80211.h" ++#include "precomp.h" ++#if CFG_SUPPORT_AGPS_ASSIST ++#include "gl_kal.h" ++#endif ++#if defined(CONFIG_MTK_TC1_FEATURE) ++#include ++#endif ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* #define MAX_IOREQ_NUM 10 */ ++ ++BOOLEAN fgIsUnderSuspend = false; ++ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++spinlock_t g_p2p_lock; ++int g_u4P2PEnding = 0; ++int g_u4P2POnOffing = 0; ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Tasklet mechanism is like buttom-half in Linux. We just want to ++ * send a signal to OS for interrupt defer processing. All resources ++ * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty. ++ */ ++typedef struct _WLANDEV_INFO_T { ++ struct net_device *prDev; ++} WLANDEV_INFO_T, *P_WLANDEV_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++#define CHAN2G(_channel, _freq, _flags) \ ++{ \ ++ .band = NL80211_BAND_2GHZ, \ ++ .center_freq = (_freq), \ ++ .hw_value = (_channel), \ ++ .flags = (_flags), \ ++ .max_antenna_gain = 0, \ ++ .max_power = 30, \ ++} ++ ++static struct ieee80211_channel mtk_2ghz_channels[] = { ++ CHAN2G(1, 2412, 0), ++ CHAN2G(2, 2417, 0), ++ CHAN2G(3, 2422, 0), ++ CHAN2G(4, 2427, 0), ++ CHAN2G(5, 2432, 0), ++ CHAN2G(6, 2437, 0), ++ CHAN2G(7, 2442, 0), ++ CHAN2G(8, 2447, 0), ++ CHAN2G(9, 2452, 0), ++ CHAN2G(10, 2457, 0), ++ CHAN2G(11, 2462, 0), ++ CHAN2G(12, 2467, 0), ++ CHAN2G(13, 2472, 0), ++ CHAN2G(14, 2484, 0), ++}; ++ ++#define CHAN5G(_channel, _flags) \ ++{ \ ++ .band = NL80211_BAND_5GHZ, \ ++ .center_freq = 5000 + (5 * (_channel)), \ ++ .hw_value = (_channel), \ ++ .flags = (_flags), \ ++ .max_antenna_gain = 0, \ ++ .max_power = 30, \ ++} ++ ++static struct ieee80211_channel mtk_5ghz_channels[] = { ++ CHAN5G(34, 0), CHAN5G(36, 0), ++ CHAN5G(38, 0), CHAN5G(40, 0), ++ CHAN5G(42, 0), CHAN5G(44, 0), ++ CHAN5G(46, 0), CHAN5G(48, 0), ++ CHAN5G(52, 0), CHAN5G(56, 0), ++ CHAN5G(60, 0), CHAN5G(64, 0), ++ CHAN5G(100, 0), CHAN5G(104, 0), ++ CHAN5G(108, 0), CHAN5G(112, 0), ++ CHAN5G(116, 0), CHAN5G(120, 0), ++ CHAN5G(124, 0), CHAN5G(128, 0), ++ CHAN5G(132, 0), CHAN5G(136, 0), ++ CHAN5G(140, 0), CHAN5G(149, 0), ++ CHAN5G(153, 0), CHAN5G(157, 0), ++ CHAN5G(161, 0), CHAN5G(165, 0), ++ CHAN5G(169, 0), CHAN5G(173, 0), ++ CHAN5G(184, 0), CHAN5G(188, 0), ++ CHAN5G(192, 0), CHAN5G(196, 0), ++ CHAN5G(200, 0), CHAN5G(204, 0), ++ CHAN5G(208, 0), CHAN5G(212, 0), ++ CHAN5G(216, 0), ++}; ++ ++#define RATETAB_ENT(_rate, _rateid, _flags) \ ++{ \ ++ .bitrate = (_rate), \ ++ .hw_value = (_rateid), \ ++ .flags = (_flags), \ ++} ++ ++/* for cfg80211 - rate table */ ++static struct ieee80211_rate mtk_rates[] = { ++ RATETAB_ENT(10, 0x1000, 0), ++ RATETAB_ENT(20, 0x1001, 0), ++ RATETAB_ENT(55, 0x1002, 0), ++ RATETAB_ENT(110, 0x1003, 0), /* 802.11b */ ++ RATETAB_ENT(60, 0x2000, 0), ++ RATETAB_ENT(90, 0x2001, 0), ++ RATETAB_ENT(120, 0x2002, 0), ++ RATETAB_ENT(180, 0x2003, 0), ++ RATETAB_ENT(240, 0x2004, 0), ++ RATETAB_ENT(360, 0x2005, 0), ++ RATETAB_ENT(480, 0x2006, 0), ++ RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */ ++}; ++ ++#define mtk_a_rates (mtk_rates + 4) ++#define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4) ++#define mtk_g_rates (mtk_rates + 0) ++#define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0) ++ ++#define WLAN_MCS_INFO \ ++{ \ ++ .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ ++ .rx_highest = 0, \ ++ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ ++} ++ ++#define WLAN_HT_CAP \ ++{ \ ++ .ht_supported = true, \ ++ .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \ ++ | IEEE80211_HT_CAP_SM_PS \ ++ | IEEE80211_HT_CAP_GRN_FLD \ ++ | IEEE80211_HT_CAP_SGI_20 \ ++ | IEEE80211_HT_CAP_SGI_40, \ ++ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ ++ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \ ++ .mcs = WLAN_MCS_INFO, \ ++} ++ ++/********************************************************** ++* Public for both legacy Wi-Fi and P2P to access ++**********************************************************/ ++struct ieee80211_supported_band mtk_band_2ghz = { ++ .band = NL80211_BAND_2GHZ, ++ .channels = mtk_2ghz_channels, ++ .n_channels = ARRAY_SIZE(mtk_2ghz_channels), ++ .bitrates = mtk_g_rates, ++ .n_bitrates = mtk_g_rates_size, ++ .ht_cap = WLAN_HT_CAP, ++}; ++ ++struct ieee80211_supported_band mtk_band_5ghz = { ++ .band = NL80211_BAND_5GHZ, ++ .channels = mtk_5ghz_channels, ++ .n_channels = ARRAY_SIZE(mtk_5ghz_channels), ++ .bitrates = mtk_a_rates, ++ .n_bitrates = mtk_a_rates_size, ++ .ht_cap = WLAN_HT_CAP, ++}; ++ ++const UINT_32 mtk_cipher_suites[5] = { ++ /* keep WEP first, it may be removed below */ ++ WLAN_CIPHER_SUITE_WEP40, ++ WLAN_CIPHER_SUITE_WEP104, ++ WLAN_CIPHER_SUITE_TKIP, ++ WLAN_CIPHER_SUITE_CCMP, ++ ++ /* keep last -- depends on hw flags! */ ++ WLAN_CIPHER_SUITE_AES_CMAC ++}; ++ ++/*********************************************************/ ++ ++#define NIC_INF_NAME "wlan%d" /* interface name */ ++#if CFG_TC1_FEATURE ++#define NIC_INF_NAME_IN_AP_MODE "legacy%d" ++#endif ++ ++/* support to change debug module info dynamically */ ++UINT_8 aucDebugModule[DBG_MODULE_NUM]; ++UINT_32 u4DebugModule = 0; ++ ++/* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */ ++static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} }; ++ ++static UINT_32 u4WlanDevNum; /* How many NICs coexist now */ ++ ++/**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/ ++struct delayed_work sched_workq; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if CFG_ENABLE_WIFI_DIRECT ++static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} }; ++#endif ++ ++static struct cfg80211_ops mtk_wlan_ops = { ++ .suspend = mtk_cfg80211_suspend, ++ .resume = mtk_cfg80211_resume, ++ .change_virtual_intf = mtk_cfg80211_change_iface, ++ .add_key = mtk_cfg80211_add_key, ++ .get_key = mtk_cfg80211_get_key, ++ .del_key = mtk_cfg80211_del_key, ++ .set_default_key = mtk_cfg80211_set_default_key, ++ .set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key, ++ .get_station = mtk_cfg80211_get_station, ++ .change_station = mtk_cfg80211_change_station, ++ .add_station = mtk_cfg80211_add_station, ++ .del_station = mtk_cfg80211_del_station, ++ .scan = mtk_cfg80211_scan, ++ .connect = mtk_cfg80211_connect, ++ .disconnect = mtk_cfg80211_disconnect, ++ .join_ibss = mtk_cfg80211_join_ibss, ++ .leave_ibss = mtk_cfg80211_leave_ibss, ++ .set_power_mgmt = mtk_cfg80211_set_power_mgmt, ++ .set_pmksa = mtk_cfg80211_set_pmksa, ++ .del_pmksa = mtk_cfg80211_del_pmksa, ++ .flush_pmksa = mtk_cfg80211_flush_pmksa, ++ .assoc = mtk_cfg80211_assoc, ++ /* Action Frame TX/RX */ ++ .remain_on_channel = mtk_cfg80211_remain_on_channel, ++ .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel, ++ .mgmt_tx = mtk_cfg80211_mgmt_tx, ++/* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */ ++ .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register, ++#ifdef CONFIG_NL80211_TESTMODE ++ .testmode_cmd = mtk_cfg80211_testmode_cmd, ++#endif ++#if (CFG_SUPPORT_TDLS == 1) ++ .tdls_mgmt = TdlsexCfg80211TdlsMgmt, ++ .tdls_oper = TdlsexCfg80211TdlsOper, ++#endif /* CFG_SUPPORT_TDLS */ ++#if 1 /* Remove schedule_scan because we need more verification for NLO */ ++ .sched_scan_start = mtk_cfg80211_sched_scan_start, ++ .sched_scan_stop = mtk_cfg80211_sched_scan_stop, ++#endif ++}; ++ ++static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = { ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_channel_list ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_country_code ++ }, ++ /* GSCAN */ ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_gscan_capabilities ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_CONFIG ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_config ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV, ++ .doit = mtk_cfg80211_vendor_set_scan_config ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_enable_scan ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_enable_full_scan_results ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_scan_results ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_significant_change ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_HOTLIST ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_hotlist ++ }, ++ /* RTT */ ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = RTT_SUBCMD_GETCAPABILITY ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_rtt_capabilities ++ }, ++ /* Link Layer Statistics */ ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = LSTATS_SUBCMD_GET_INFO ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_llstats_get_info ++ }, ++ ++}; ++ ++static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = RTT_EVENT_COMPLETE ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_COMPLETE_SCAN ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST ++ }, ++}; ++ ++/* There isn't a lot of sense in it, but you can transmit anything you like */ ++static const struct ieee80211_txrx_stypes ++ mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { ++ [NL80211_IFTYPE_ADHOC] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_STATION] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_AP] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_AP_VLAN] = { ++ /* copy AP */ ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | ++ BIT(IEEE80211_STYPE_DISASSOC >> 4) | ++ BIT(IEEE80211_STYPE_AUTH >> 4) | ++ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_CLIENT] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_GO] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ } ++}; ++ ++#ifdef CONFIG_PM ++static const struct wiphy_wowlan_support mtk_wlan_wowlan_support = { ++ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, ++}; ++#endif ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Override the implementation of select queue ++* ++* \param[in] dev Pointer to struct net_device ++* \param[in] skb Pointer to struct skb_buff ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++unsigned int _cfg80211_classify8021d(struct sk_buff *skb) ++{ ++ unsigned int dscp = 0; ++ ++ /* skb->priority values from 256->263 are magic values ++ * directly indicate a specific 802.1d priority. This is ++ * to allow 802.1d priority to be passed directly in from ++ * tags ++ */ ++ ++ if (skb->priority >= 256 && skb->priority <= 263) ++ return skb->priority - 256; ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ dscp = ip_hdr(skb)->tos & 0xfc; ++ break; ++ } ++ return dscp >> 5; ++} ++ ++static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; ++ ++static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb, ++ void *accel_priv, select_queue_fallback_t fallback) ++{ ++ skb->priority = _cfg80211_classify8021d(skb); ++ ++ return au16Wlan1dToQueueIdx[skb->priority]; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Load NVRAM data and translate it into REG_INFO_T ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* \param[out] prRegInfo Pointer to struct REG_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo) ++{ ++ UINT_32 i, j; ++ UINT_8 aucTmp[2]; ++ PUINT_8 pucDest; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prRegInfo); ++ ++ if ((!prGlueInfo) || (!prRegInfo)) ++ return; ++ ++ if (kalCfgDataRead16(prGlueInfo, sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16), (PUINT_16) aucTmp) == TRUE) { ++ prGlueInfo->fgNvramAvailable = TRUE; ++ ++ /* load MAC Address */ ++#if !defined(CONFIG_MTK_TC1_FEATURE) ++ for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, ++ (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i)); ++ } ++#else ++ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr); ++#endif ++ ++ /* load country code */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp); ++ ++ /* cast to wide characters */ ++ prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0]; ++ prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1]; ++ ++ /* load default normal TX power */ ++ for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i, ++ (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i)); ++ } ++ ++ /* load feature flags */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp); ++ prRegInfo->ucTxPwrValid = aucTmp[0]; ++ prRegInfo->ucSupport5GBand = aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp); ++ prRegInfo->uc2G4BwFixed20M = aucTmp[0]; ++ prRegInfo->uc5GBwFixed20M = aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp); ++ prRegInfo->ucEnable5GBand = aucTmp[0]; ++ ++ /* load EFUSE overriding part */ ++ for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i, ++ (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i)); ++ } ++ ++ /* load band edge tx power control */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp); ++ prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0]; ++ if (aucTmp[0]) { ++ prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp); ++ prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0]; ++ prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1]; ++ } ++ ++ /* load regulation subbands */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp); ++ prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0]; ++ prRegInfo->ucRegChannelListIndex = aucTmp[1]; ++ ++ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i]; ++ for (j = 0; j < 6; j += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) ++ + (i * 6 + j), (PUINT_16) aucTmp); ++ ++ *pucDest++ = aucTmp[0]; ++ *pucDest++ = aucTmp[1]; ++ } ++ } ++ } ++ /* load RSSI compensation */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp); ++ prRegInfo->uc2GRssiCompensation = aucTmp[0]; ++ prRegInfo->uc5GRssiCompensation = aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp); ++ prRegInfo->fgRssiCompensationValidbit = aucTmp[0]; ++ prRegInfo->ucRxAntennanumber = aucTmp[1]; ++ } else { ++ prGlueInfo->fgNvramAvailable = FALSE; ++ } ++ ++} ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief called by txthread, run sub module init function ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo) ++{ ++ /*now, we only have p2p module */ ++ if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) { ++ rSubModHandler[P2P_MODULE].subModInit(prGlueInfo); ++ rSubModHandler[P2P_MODULE].fgIsInited = TRUE; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief called by txthread, run sub module exit function ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo) ++{ ++ /*now, we only have p2p module */ ++ if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) { ++ rSubModHandler[P2P_MODULE].subModExit(prGlueInfo); ++ rSubModHandler[P2P_MODULE].fgIsInited = FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set sub module init flag, force TxThread to run sub modle init ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo) ++{ ++ /* 4 Mark HALT, notify main thread to finish current job */ ++ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT; ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread finish sub module INIT */ ++ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); ++ ++#if 0 ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pNetRegister(prGlueInfo); ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set sub module exit flag, force TxThread to run sub modle exit ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo) ++{ ++#if 0 ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pNetUnregister(prGlueInfo); ++#endif ++ ++ /* 4 Mark HALT, notify main thread to finish current job */ ++ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT; ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread finish sub module EXIT */ ++ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set by sub module, indicate sub module is already inserted ++* ++* \param[in] rSubModInit, function pointer point to sub module init function ++* \param[in] rSubModExit, function pointer point to sub module exit function ++* \param[in] eSubModIdx, sub module index ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx) ++{ ++ rSubModHandler[eSubModIdx].subModInit = rSubModInit; ++ rSubModHandler[eSubModIdx].subModExit = rSubModExit; ++ rSubModHandler[eSubModIdx].fgIsInited = FALSE; ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief check wlan is launched or not ++* ++* \param[in] (none) ++* ++* \return TRUE, wlan is already started ++* FALSE, wlan is not started yet ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanIsLaunched(VOID) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ /* 4 <0> Sanity check */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (0 == u4WlanDevNum) ++ return FALSE; ++ ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ ++ ASSERT(prDev); ++ if (NULL == prDev) ++ return FALSE; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (NULL == prGlueInfo) ++ return FALSE; ++ ++ return prGlueInfo->prAdapter->fgIsWlanLaunched; ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Export wlan GLUE_INFO_T pointer to p2p module ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return TRUE: get GlueInfo pointer successfully ++* FALSE: wlan is not started yet ++*/ ++/*---------------------------------------------------------------------------*/ ++BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (0 == u4WlanDevNum) ++ return FALSE; ++ ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ if (NULL == prDev) ++ return FALSE; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ if (NULL == prGlueInfo) ++ return FALSE; ++ ++ if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) ++ return FALSE; ++ ++ *prGlueInfoExpAddr = prGlueInfo; ++ return TRUE; ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Release prDev from wlandev_array and free tasklet object related to it. ++* ++* \param[in] prDev Pointer to struct net_device ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void wlanClearDevIdx(struct net_device *prDev) ++{ ++ int i; ++ ++ ASSERT(prDev); ++ ++ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { ++ if (arWlanDevInfo[i].prDev == prDev) { ++ arWlanDevInfo[i].prDev = NULL; ++ u4WlanDevNum--; ++ } ++ } ++ ++} /* end of wlanClearDevIdx() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Allocate an unique interface index, net_device::ifindex member for this ++* wlan device. Store the net_device in wlandev_array, and initialize ++* tasklet object related to it. ++* ++* \param[in] prDev Pointer to struct net_device ++* ++* \retval >= 0 The device number. ++* \retval -1 Fail to get index. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanGetDevIdx(struct net_device *prDev) ++{ ++ int i; ++ ++ ASSERT(prDev); ++ ++ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { ++ if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) { ++ /* Reserve 2 bytes space to store one digit of ++ * device number and NULL terminator. ++ */ ++ arWlanDevInfo[i].prDev = prDev; ++ u4WlanDevNum++; ++ return i; ++ } ++ } ++ ++ return -1; ++} /* end of wlanGetDevIdx() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method of struct net_device, a primary SOCKET interface to configure ++* the interface lively. Handle an ioctl call on one of our devices. ++* Everything Linux ioctl specific is done here. Then we pass the contents ++* of the ifr->data to the request message handler. ++* ++* \param[in] prDev Linux kernel netdevice ++* ++* \param[in] prIfReq Our private ioctl request structure, typed for the generic ++* struct ifreq so we can use ptr to function ++* ++* \param[in] cmd Command ID ++* ++* \retval 0 The IOCTL command is executed successfully. ++* \retval <0 The execution of IOCTL command is failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ int ret = 0; ++ ++ /* Verify input parameters for the following functions */ ++ ASSERT(prDev && prIfReq); ++ if (!prDev || !prIfReq) { ++ DBGLOG(INIT, ERROR, "Invalid input data\n"); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ if (!prGlueInfo) { ++ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); ++ return -EFAULT; ++ } ++ ++ if (prGlueInfo->u4ReadyFlag == 0) { ++ DBGLOG(INIT, ERROR, "Adapter is not ready\n"); ++ return -EINVAL; ++ } ++ ++ if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) { ++ /* 0x8B00 ~ 0x8BDF, wireless extension region */ ++ ret = wext_support_ioctl(prDev, prIfReq, i4Cmd); ++ } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) { ++ /* 0x8BE0 ~ 0x8BFF, private ioctl region */ ++ ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); ++ } else if (i4Cmd == SIOCDEVPRIVATE + 1) { ++ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); ++ } else { ++ DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd); ++ ret = -EOPNOTSUPP; ++ } ++ ++ return ret; ++} /* end of wlanDoIOCTL() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to set multicast list and set rx mode. ++* ++* \param[in] prDev Pointer to struct net_device ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++static struct delayed_work workq; ++static struct net_device *gPrDev; ++static BOOLEAN fgIsWorkMcStart = FALSE; ++static BOOLEAN fgIsWorkMcEverInit = FALSE; ++static struct wireless_dev *gprWdev; ++ ++static void createWirelessDevice(void) ++{ ++ struct wiphy *prWiphy = NULL; ++ struct wireless_dev *prWdev = NULL; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ struct net_device *prNetDev = NULL; ++#endif ++ ++ /* <1.1> Create wireless_dev */ ++ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); ++ return; ++ } ++ ++ ++ /* <1.2> Create wiphy */ ++ prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T)); ++ if (!prWiphy) { ++ DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n"); ++ goto free_wdev; ++ } ++ ++ /* <1.3> configure wireless_dev & wiphy */ ++ prWdev->iftype = NL80211_IFTYPE_STATION; ++ prWiphy->max_scan_ssids = 1; /* FIXME: for combo scan */ ++ prWiphy->max_scan_ie_len = 512; ++ ++ prWiphy->max_sched_scan_ssids = CFG_SCAN_SSID_MAX_NUM; ++ prWiphy->max_match_sets = CFG_SCAN_SSID_MATCH_MAX_NUM; ++ prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN; ++ ++ prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); ++ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; ++ /* always assign 5Ghz bands here, if the chip is not support 5Ghz, ++ bands[IEEE80211_BAND_5GHZ] will be assign to NULL */ ++ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; ++ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; ++ prWiphy->cipher_suites = mtk_cipher_suites; ++ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); ++ prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM ++ | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL ++ | WIPHY_FLAG_SUPPORTS_SCHED_SCAN; ++ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; ++#if CFG_SUPPORT_TDLS ++ TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags); ++#endif /* CFG_SUPPORT_TDLS */ ++ prWiphy->max_remain_on_channel_duration = 5000; ++ prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes; ++ prWiphy->vendor_commands = mtk_wlan_vendor_ops; ++ prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command); ++ prWiphy->vendor_events = mtk_wlan_vendor_events; ++ prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events); ++ ++ /* <1.4> wowlan support */ ++#ifdef CONFIG_PM ++ prWiphy->wowlan = &mtk_wlan_wowlan_support; ++#endif ++#ifdef CONFIG_CFG80211_WEXT ++ /* <1.5> Use wireless extension to replace IOCTL */ ++ prWiphy->wext = &wext_handler_def; ++#endif ++ ++ if (wiphy_register(prWiphy) < 0) { ++ DBGLOG(INIT, ERROR, "wiphy_register error\n"); ++ goto free_wiphy; ++ } ++ prWdev->wiphy = prWiphy; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* <2> allocate and register net_device */ ++#if CFG_TC1_FEATURE ++ if (wlan_if_changed) ++ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++ else ++#else ++ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++#endif ++ if (!prNetDev) { ++ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); ++ goto unregister_wiphy; ++ } ++ ++ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy); ++ ++ prNetDev->netdev_ops = &wlan_netdev_ops; ++#ifdef CONFIG_WIRELESS_EXT ++ prNetDev->wireless_handlers = &wext_handler_def; ++#endif ++ netif_carrier_off(prNetDev); ++ netif_tx_stop_all_queues(prNetDev); ++ ++ /* <2.1> co-relate with wireless_dev bi-directionally */ ++ prNetDev->ieee80211_ptr = prWdev; ++ prWdev->netdev = prNetDev; ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prNetDev->features = NETIF_F_HW_CSUM; ++#endif ++ ++ /* <2.2> co-relate net device & device tree */ ++ SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy)); ++ ++ /* <2.3> register net_device */ ++ if (register_netdev(prWdev->netdev) < 0) { ++ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); ++ goto unregister_wiphy; ++ } ++#endif /* CFG_SUPPORT_PERSIST_NETDEV */ ++ gprWdev = prWdev; ++ DBGLOG(INIT, INFO, "create wireless device success\n"); ++ return; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++unregister_wiphy: ++ wiphy_unregister(prWiphy); ++#endif ++free_wiphy: ++ wiphy_free(prWiphy); ++free_wdev: ++ kfree(prWdev); ++} ++ ++static void destroyWirelessDevice(void) ++{ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ unregister_netdev(gprWdev->netdev); ++ free_netdev(gprWdev->netdev); ++#endif ++ wiphy_unregister(gprWdev->wiphy); ++ wiphy_free(gprWdev->wiphy); ++ kfree(gprWdev); ++ gprWdev = NULL; ++} ++ ++static void wlanSetMulticastList(struct net_device *prDev) ++{ ++ gPrDev = prDev; ++ schedule_delayed_work(&workq, 0); ++} ++ ++/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange ++ * another workqueue for sleeping. We don't want to block ++ * tx_thread, so we can't let tx_thread to do this */ ++ ++static void wlanSetMulticastListWorkQueue(struct work_struct *work) ++{ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4PacketFilter = 0; ++ UINT_32 u4SetInfoLen; ++ struct net_device *prDev = gPrDev; ++ ++ fgIsWorkMcStart = TRUE; ++ ++ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) ++ return; ++ if (kalIsHalted()) { ++ fgIsWorkMcStart = FALSE; ++ kalHaltUnlock(); ++ return; ++ } ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ if (!prDev || !prGlueInfo) { ++ DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); ++ fgIsWorkMcStart = FALSE; ++ kalHaltUnlock(); ++ return; ++ } ++ ++ if (prDev->flags & IFF_PROMISC) ++ u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; ++ ++ if (prDev->flags & IFF_BROADCAST) ++ u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; ++ ++ if (prDev->flags & IFF_MULTICAST) { ++ if ((prDev->flags & IFF_ALLMULTI) || ++ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { ++ ++ u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; ++ } else { ++ u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; ++ } ++ } ++ ++ kalHaltUnlock(); ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidSetCurrentPacketFilter, ++ &u4PacketFilter, ++ sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) { ++ fgIsWorkMcStart = FALSE; ++ DBGLOG(INIT, ERROR, "wlanSetMulticastListWorkQueue kalIoctl u4PacketFilter=%d\n", u4PacketFilter); ++ return; ++ } ++ ++ if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { ++ /* Prepare multicast address list */ ++ struct netdev_hw_addr *ha; ++ PUINT_8 prMCAddrList = NULL; ++ UINT_32 i = 0; ++ ++ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) ++ return; ++ if (kalIsHalted()) { ++ fgIsWorkMcStart = FALSE; ++ kalHaltUnlock(); ++ /*DBGLOG(INIT, WARN, "wlanSetMulticastListWorkQueue g_u4HaltFlag=%d\n", g_u4HaltFlag);*/ ++ return; ++ } ++ ++ prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE); ++ ++ netdev_for_each_mc_addr(ha, prDev) { ++ if (i < MAX_NUM_GROUP_ADDR) { ++ memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN); ++ i++; ++ } ++ } ++ ++ kalHaltUnlock(); ++ ++ kalIoctl(prGlueInfo, ++ wlanoidSetMulticastList, ++ prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ ++ kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN); ++ } ++ ++ fgIsWorkMcStart = FALSE; ++ ++} /* end of wlanSetMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate scheduled scan has been stopped ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct net_device *prDev = gPrDev; ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ if (!prGlueInfo) { ++ DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n"); ++ return; ++ } ++ ++ /* 2. indication to cfg80211 */ ++ /* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */ ++ cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo),0); ++ DBGLOG(SCN, INFO, ++ "cfg80211_sched_scan_stopped event send done\n"); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is TX entry point of NET DEVICE. ++* ++* \param[in] prSkb Pointer of the sk_buff to be sent ++* \param[in] prDev Pointer to struct net_device ++* ++* \retval NETDEV_TX_OK - on success. ++* \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. ++*/ ++/*----------------------------------------------------------------------------*/ ++int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_QUE_T prTxQueue = NULL; ++ UINT_16 u2QueueIdx = 0; ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ UINT16 u2Identifier = 0; ++#endif ++ ++#if CFG_BOW_TEST ++ UINT_32 i; ++#endif ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prSkb); ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ prGlueInfo->u8SkbToDriver++; ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ { ++ UINT8 *pkt = prSkb->data; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ /* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */ ++ DBGLOG(INIT, INFO, " %d\n", u2Identifier); ++ } ++ } ++#endif ++ /* check if WiFi is halt */ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n"); ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ if (prGlueInfo->fgIsDad) { ++ /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */ ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++ if (prGlueInfo->fgIs6Dad) { ++ /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */ ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++#endif ++ ++ STATS_TX_TIME_ARRIVE(prSkb); ++ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); ++ prTxQueue = &prGlueInfo->rTxQueue; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len); ++ DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len); ++ DBGLOG(BOW, TRACE, "sk_buff->data:\n"); ++ ++ for (i = 0; i < prSkb->len; i++) { ++ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); ++ ++ if ((i + 1) % 16 == 0) ++ DBGLOG(BOW, TRACE, "\n"); ++ } ++ ++ DBGLOG(BOW, TRACE, "\n"); ++#endif ++ ++ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { ++ ++ /* non-1x packets */ ++ ++#if CFG_DBG_GPIO_PINS ++ { ++ /* TX request from OS */ ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW); ++ kalUdelay(1); ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH); ++ } ++#endif ++ ++ u2QueueIdx = skb_get_queue_mapping(prSkb); ++ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); ++#endif ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ if (u2QueueIdx < CFG_MAX_TXQ_NUM) ++ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++/* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */ ++/* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */ ++ ++ if (u2QueueIdx < CFG_MAX_TXQ_NUM) { ++ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= ++ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { ++ DBGLOG(TX, INFO, "netif_stop_subqueue for wlan0, Queue len: %d\n", ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); ++ ++ netif_stop_subqueue(prDev, u2QueueIdx); ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01; ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ } ++ } ++ } else { ++ /* printk("is security frame\n"); */ ++ ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++ } ++ ++ DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len); ++ prGlueInfo->rNetDevStats.tx_bytes += prSkb->len; ++ prGlueInfo->rNetDevStats.tx_packets++; ++ kalPerMonStart(prGlueInfo); ++ ++ /* set GLUE_FLAG_TXREQ_BIT */ ++ ++ /* pr->u4Flag |= GLUE_FLAG_TXREQ; */ ++ /* wake_up_interruptible(&prGlueInfo->waitq); */ ++ kalSetEvent(prGlueInfo); ++ ++ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ ++ return NETDEV_TX_OK; ++} /* end of wlanHardStartXmit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method of struct net_device, to get the network interface statistical ++* information. ++* ++* Whenever an application needs to get statistics for the interface, this method ++* is called. This happens, for example, when ifconfig or netstat -i is run. ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \return net_device_stats buffer pointer. ++*/ ++/*----------------------------------------------------------------------------*/ ++struct net_device_stats *wlanGetStats(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++#if 0 ++ WLAN_STATUS rStatus; ++ UINT_32 u4XmitError = 0; ++ UINT_32 u4XmitOk = 0; ++ UINT_32 u4RecvError = 0; ++ UINT_32 u4RecvOk = 0; ++ UINT_32 u4BufLen; ++ ++ ASSERT(prDev); ++ ++ /* @FIX ME: need a more clear way to do this */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ prGlueInfo->rNetDevStats.rx_packets = u4RecvOk; ++ prGlueInfo->rNetDevStats.tx_packets = u4XmitOk; ++ prGlueInfo->rNetDevStats.tx_errors = u4XmitError; ++ prGlueInfo->rNetDevStats.rx_errors = u4RecvError; ++ /* prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes; */ ++ /* prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes; */ ++ /* prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors; */ ++ /* prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast; */ ++#endif ++ /* prGlueInfo->rNetDevStats.rx_packets = 0; */ ++ /* prGlueInfo->rNetDevStats.tx_packets = 0; */ ++ prGlueInfo->rNetDevStats.tx_errors = 0; ++ prGlueInfo->rNetDevStats.rx_errors = 0; ++ /* prGlueInfo->rNetDevStats.rx_bytes = 0; */ ++ /* prGlueInfo->rNetDevStats.tx_bytes = 0; */ ++ prGlueInfo->rNetDevStats.rx_errors = 0; ++ prGlueInfo->rNetDevStats.multicast = 0; ++ ++ return &prGlueInfo->rNetDevStats; ++ ++} /* end of wlanGetStats() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->init ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanInit succeeds. ++* \retval -ENXIO No such device. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanInit(struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (fgIsWorkMcEverInit == FALSE) { ++ if (!prDev) ++ return -ENXIO; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue); ++ ++ /* 20150205 work queue for sched_scan */ ++ INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue); ++ ++ fgIsWorkMcEverInit = TRUE; ++ } ++ ++ return 0; /* success */ ++} /* end of wlanInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->uninit ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void wlanUninit(struct net_device *prDev) ++{ ++ ++} /* end of wlanUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->open ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanOpen succeeds. ++* \retval < 0 The execution of wlanOpen failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanOpen(struct net_device *prDev) ++{ ++ ASSERT(prDev); ++ ++ netif_tx_start_all_queues(prDev); ++ ++ return 0; /* success */ ++} /* end of wlanOpen() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->stop ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanStop succeeds. ++* \retval < 0 The execution of wlanStop failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanStop(struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ ++ struct cfg80211_scan_info info = { ++ .aborted = true, ++ }; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ /* CFG80211 down */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueInfo->prScanRequest; ++ prGlueInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (prScanRequest) ++ cfg80211_scan_done(prScanRequest, &info); ++ netif_tx_stop_all_queues(prDev); ++ ++ return 0; /* success */ ++} /* end of wlanStop() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief Update channel table for cfg80211 based on current country domain ++ * ++ * \param[in] prGlueInfo Pointer to glue info ++ * ++ * \return none ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_8 i, j; ++ UINT_8 ucNumOfChannel; ++ RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)]; ++ ++ /* 1. Disable all channels */ ++ for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) { ++ mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; ++ mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) { ++ mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; ++ mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; ++ } ++ ++ /* 2. Get current domain channel list */ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, ++ BAND_NULL, FALSE, ++ ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels), ++ &ucNumOfChannel, aucChannelList); ++ ++ /* 3. Enable specific channel based on domain channel list */ ++ for (i = 0; i < ucNumOfChannel; i++) { ++ switch (aucChannelList[i].eBand) { ++ case BAND_2G4: ++ for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) { ++ if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { ++ mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; ++ mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; ++ break; ++ } ++ } ++ break; ++ ++ case BAND_5G: ++ for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) { ++ if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { ++ mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; ++ mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; ++ break; ++ } ++ } ++ break; ++ ++ default: ++ DBGLOG(INIT, WARN, "Unknown band %d\n", aucChannelList[i].eBand); ++ break; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Register the device to the kernel and return the index. ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanNetRegister succeeds. ++* \retval < 0 The execution of wlanNetRegister failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++static INT_32 wlanNetRegister(struct wireless_dev *prWdev) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ INT_32 i4DevIdx = -1; ++ ++ ASSERT(prWdev); ++ ++ do { ++ if (!prWdev) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ i4DevIdx = wlanGetDevIdx(prWdev->netdev); ++ if (i4DevIdx < 0) { ++ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n"); ++ break; ++ } ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ if (register_netdev(prWdev->netdev) < 0) { ++ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); ++ ++ wiphy_unregister(prWdev->wiphy); ++ wlanClearDevIdx(prWdev->netdev); ++ i4DevIdx = -1; ++ } ++#endif ++ if (i4DevIdx != -1) ++ prGlueInfo->fgIsRegistered = TRUE; ++ ++ } while (FALSE); ++ ++ return i4DevIdx; /* success */ ++} /* end of wlanNetRegister() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Unregister the device from the kernel ++* ++* \param[in] prWdev Pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID wlanNetUnregister(struct wireless_dev *prWdev) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n"); ++ return; ++ } ++ DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev); ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ wlanClearDevIdx(prWdev->netdev); ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ unregister_netdev(prWdev->netdev); ++#endif ++ prGlueInfo->fgIsRegistered = FALSE; ++ ++ DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex); ++ ++} /* end of wlanNetUnregister() */ ++ ++static const struct net_device_ops wlan_netdev_ops = { ++ .ndo_open = wlanOpen, ++ .ndo_stop = wlanStop, ++ .ndo_set_rx_mode = wlanSetMulticastList, ++ .ndo_get_stats = wlanGetStats, ++ .ndo_do_ioctl = wlanDoIOCTL, ++ .ndo_start_xmit = wlanHardStartXmit, ++ .ndo_init = wlanInit, ++ .ndo_uninit = wlanUninit, ++ .ndo_select_queue = wlanSelectQueue, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method for creating Linux NET4 struct net_device object and the ++* private data(prGlueInfo and prAdapter). Setup the IO address to the HIF. ++* Assign the function pointer to the net_device object ++* ++* \param[in] pvData Memory address for the device ++* ++* \retval Not null The wireless_dev object. ++* \retval NULL Fail to create wireless_dev object ++*/ ++/*----------------------------------------------------------------------------*/ ++static struct lock_class_key rSpinKey[SPIN_LOCK_NUM]; ++static struct wireless_dev *wlanNetCreate(PVOID pvData) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct wireless_dev *prWdev = gprWdev; ++ UINT_32 i; ++ struct device *prDev; ++ ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); ++ return NULL; ++ } ++ /* 4 <1> co-relate wiphy & prDev */ ++#if MTK_WCN_HIF_SDIO ++ mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev); ++#else ++/* prDev = &((struct sdio_func *) pvData)->dev; //samp */ ++ prDev = pvData; /* samp */ ++#endif ++ if (!prDev) ++ DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n"); ++ /* don't set prDev as parent of wiphy->dev, because we have done device_add ++ in driver init. if we set parent here, parent will be not able to know this child, ++ and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent ++ has been freed. */ ++ /*set_wiphy_dev(prWdev->wiphy, prDev);*/ ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ /* 4 <3> Initial Glue structure */ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T)); ++ /* 4 <3.1> Create net device */ ++#if CFG_TC1_FEATURE ++ if (wlan_if_changed) { ++ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, ++ NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); ++ } else { ++ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++ } ++#else ++ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++#endif ++ if (!prGlueInfo->prDevHandler) { ++ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); ++ return NULL; ++ } ++ DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n", ++ prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex); ++ ++ /* 4 <3.1.1> initialize net device varaiables */ ++ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo; ++ ++ prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops; ++#ifdef CONFIG_WIRELESS_EXT ++ prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def; ++#endif ++ netif_carrier_off(prGlueInfo->prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); ++ ++ /* 4 <3.1.2> co-relate with wiphy bi-directionally */ ++ prGlueInfo->prDevHandler->ieee80211_ptr = prWdev; ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM; ++#endif ++ prWdev->netdev = prGlueInfo->prDevHandler; ++ ++ /* 4 <3.1.3> co-relate net device & prDev */ ++ /*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/ ++ SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev); ++#else /* CFG_SUPPORT_PERSIST_NETDEV */ ++ prGlueInfo->prDevHandler = gprWdev->netdev; ++#endif /* CFG_SUPPORT_PERSIST_NETDEV */ ++ ++ /* 4 <3.2> initiali glue variables */ ++ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; ++ prGlueInfo->ePowerState = ParamDeviceStateD0; ++ prGlueInfo->fgIsMacAddrOverride = FALSE; ++ prGlueInfo->fgIsRegistered = FALSE; ++ prGlueInfo->prScanRequest = NULL; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ /* Init DAD */ ++ prGlueInfo->fgIsDad = FALSE; ++ prGlueInfo->fgIs6Dad = FALSE; ++ kalMemZero(prGlueInfo->aucDADipv4, 4); ++ kalMemZero(prGlueInfo->aucDADipv6, 16); ++#endif ++ ++ init_completion(&prGlueInfo->rScanComp); ++ init_completion(&prGlueInfo->rHaltComp); ++ init_completion(&prGlueInfo->rPendComp); ++#if CFG_ENABLE_WIFI_DIRECT ++ init_completion(&prGlueInfo->rSubModComp); ++#endif ++ ++ /* initialize timer for OID timeout checker */ ++ kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler); ++ ++ for (i = 0; i < SPIN_LOCK_NUM; i++) { ++ spin_lock_init(&prGlueInfo->rSpinLock[i]); ++ lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]); ++ } ++ ++ /* initialize semaphore for ioctl */ ++ sema_init(&prGlueInfo->ioctl_sem, 1); ++ ++ glSetHifInfo(prGlueInfo, (ULONG) pvData); ++ ++ /* 4 <8> Init Queues */ ++ init_waitqueue_head(&prGlueInfo->waitq); ++ QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); ++ QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); ++ ++ /* 4 <4> Create Adapter structure */ ++ prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo); ++ ++ if (!prGlueInfo->prAdapter) { ++ DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n"); ++ return NULL; ++ } ++ KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR"); ++#if CFG_SUPPORT_PERSIST_NETDEV ++ dev_open(prGlueInfo->prDevHandler); ++ netif_carrier_off(prGlueInfo->prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); ++#endif ++ ++ return prWdev; ++} /* end of wlanNetCreate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Destroying the struct net_device object and the private data. ++* ++* \param[in] prWdev Pointer to struct wireless_dev. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID wlanNetDestroy(struct wireless_dev *prWdev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prWdev); ++ ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n"); ++ return; ++ } ++ ++ /* prGlueInfo is allocated with net_device */ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ ASSERT(prGlueInfo); ++ ++ /* destroy kal OS timer */ ++ kalCancelTimer(prGlueInfo); ++ ++ glClearHifInfo(prGlueInfo); ++ ++ wlanAdapterDestroy(prGlueInfo->prAdapter); ++ prGlueInfo->prAdapter = NULL; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* take the net_device to down state */ ++ dev_close(prGlueInfo->prDevHandler); ++#else ++ /* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */ ++ free_netdev(prWdev->netdev); ++#endif ++ ++} /* end of wlanNetDestroy() */ ++ ++#ifndef CONFIG_X86 ++UINT_8 g_aucBufIpAddr[32] = { 0 }; ++static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidNotifyFwSuspend, ++ (PVOID)&fgSuspend, ++ sizeof(fgSuspend), ++ FALSE, ++ FALSE, ++ TRUE, ++ FALSE, ++ &u4SetInfoLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n"); ++} ++ ++void wlanHandleSystemSuspend(void) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_8 ip[4] = { 0 }; ++ UINT_32 u4NumIPv4 = 0; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++ UINT_32 u4NumIPv6 = 0; ++#endif ++ UINT_32 i; ++ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; ++ ++ /* <1> Sanity check and acquire the net_device */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (u4WlanDevNum == 0) { ++ DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n"); ++ return; ++ } ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ ++ fgIsUnderSuspend = true; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ kalPerMonDisable(prGlueInfo); ++ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ goto notify_suspend; ++ } ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++ /* todo: traverse between list to find whole sets of IPv4 addresses */ ++ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) ++ u4NumIPv4++; ++#ifdef CONFIG_IPV6 ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ goto notify_suspend; ++ } ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ++ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] ++ ); ++ ++ /* todo: traverse between list to find whole sets of IPv6 addresses */ ++ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) { ++ /* Do nothing */ ++ /* u4NumIPv6++; */ ++ } ++#endif ++ ++ /* <7> set up the ARP filter */ ++ { ++ UINT_32 u4SetInfoLen = 0; ++ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = u4NumIPv4; ++#ifdef CONFIG_IPV6 ++ prParamNetAddrList->u4AddressCount += u4NumIPv6; ++#endif ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ for (i = 0; i < u4NumIPv4; i++) { ++ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; ++ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); ++ prParamNetAddr = ++ (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); ++ } ++#ifdef CONFIG_IPV6 ++ for (i = 0; i < u4NumIPv6; i++) { ++ prParamNetAddr->u2AddressLength = 6; ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); ++ } ++#endif ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ ++notify_suspend: ++ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ wlanNotifyFwSuspend(prGlueInfo, TRUE); ++} ++ ++void wlanHandleSystemResume(void) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_8 ip[4] = { 0 }; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++#endif ++ EVENT_AIS_BSS_INFO_T rParam; ++ UINT_32 u4BufLen = 0; ++ ++ /* <1> Sanity check and acquire the net_device */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (u4WlanDevNum == 0) { ++ DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n"); ++ return; ++ } ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ /* ASSERT(prDev); */ ++ ++ fgIsUnderSuspend = false; ++ ++ if (!prDev) { ++ DBGLOG(INIT, INFO, "prDev == NULL!!!\n"); ++ return; ++ } ++ /* <3> acquire the prGlueInfo */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ kalPerMonEnable(prGlueInfo); ++ ++ /* ++ We will receive the event in rx, we will check if the status is the same in driver ++ and FW, if not the same, trigger disconnetion procedure. ++ */ ++ ++ kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBSSInfo, ++ &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus); ++ } ++ ++ /* <2> get the IPv4 address */ ++ if (!(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ goto notify_resume; ++ } ++ /* <4> copy the IPv4 address */ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++#ifdef CONFIG_IPV6 ++ /* <5> get the IPv6 address */ ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ goto notify_resume; ++ } ++ /* <6> copy the IPv6 address */ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ++ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] ++ ); ++#endif ++ /* <7> clear the ARP filter */ ++ { ++ UINT_32 u4SetInfoLen = 0; ++/* UINT_8 aucBuf[32] = {0}; */ ++ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ /* aucBuf; */ ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = 0; ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ ++notify_resume: ++ DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n", ++ rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive, ++ ip[0], ip[1], ip[2], ip[3], rStatus); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ wlanNotifyFwSuspend(prGlueInfo, FALSE); ++ } ++} ++#endif /* ! CONFIG_X86 */ ++ ++int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode) ++{ ++#if 0 ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); ++ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ rSetP2P.u4Enable = p2pmode.u4Enable; ++ rSetP2P.u4Mode = p2pmode.u4Mode; ++ ++ if (!rSetP2P.u4Enable) ++ p2pNetUnregister(prGlueInfo, TRUE); ++ ++ rWlanStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pMode, ++ (PVOID) &rSetP2P, ++ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus); ++ if (rSetP2P.u4Enable) ++ p2pNetRegister(prGlueInfo, TRUE); ++ ++ return 0; ++ ++#else ++ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); ++ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgIsP2PEnding; ++ UINT_32 u4BufLen = 0; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode); ++ ++ /* avoid remove & p2p off command simultaneously */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ fgIsP2PEnding = g_u4P2PEnding; ++ g_u4P2POnOffing = 1; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ ++ if (fgIsP2PEnding == 1) { ++ /* skip the command if we are removing */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ return 0; ++ } ++ ++ rSetP2P.u4Enable = p2pmode.u4Enable; ++ rSetP2P.u4Mode = p2pmode.u4Mode; ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE)) ++ p2pNetUnregister(prGlueInfo, TRUE); ++#endif ++ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ ++ /* ++ Scenario: ++ 1. System enters suspend/resume but not yet enter wlanearlysuspend() ++ or wlanlateresume(); ++ ++ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() ++ and get g_halt_sem then do glRegisterEarlySuspend() or ++ glUnregisterEarlySuspend(); ++ ++ But system suspend/resume procedure is not yet finished so we ++ suspend; ++ ++ 3. System switches back to do suspend/resume procedure and execute ++ kalIoctl(). But driver does not yet release g_halt_sem so system ++ suspend in wlanearlysuspend() or wlanlateresume(); ++ ++ ==> deadlock occurs. ++ */ ++ ++ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */ ++ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ /* Need to check fgIsP2PRegistered, in case of whole chip reset. ++ * in this case, kalIOCTL return success always, ++ * and prGlueInfo->prP2pInfo may be NULL */ ++ if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE)) ++ p2pNetRegister(prGlueInfo, TRUE); ++#endif ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ return 0; ++#endif ++} ++ ++static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM]) ++{ ++ kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule)); ++ kalPrint("[wlan] change debug level"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Wlan probe function. This function probes and initializes the device. ++* ++* \param[in] pvData data passed by bus driver init function ++* _HIF_EHPI: NULL ++* _HIF_SDIO: sdio bus driver handle ++* ++* \retval 0 Success ++* \retval negative value Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++static INT_32 wlanProbe(PVOID pvData) ++{ ++ struct wireless_dev *prWdev = NULL; ++ enum probe_fail_reason { ++ BUS_INIT_FAIL, ++ NET_CREATE_FAIL, ++ BUS_SET_IRQ_FAIL, ++ ADAPTER_START_FAIL, ++ NET_REGISTER_FAIL, ++ PROC_INIT_FAIL, ++ FAIL_REASON_NUM ++ } eFailReason; ++ P_WLANDEV_INFO_T prWlandevInfo = NULL; ++ INT_32 i4DevIdx = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ INT_32 i4Status = 0; ++ BOOLEAN bRet = FALSE; ++ ++ eFailReason = FAIL_REASON_NUM; ++ do { ++ /* 4 <1> Initialize the IO port of the interface */ ++ /* GeorgeKuo: pData has different meaning for _HIF_XXX: ++ * _HIF_EHPI: pointer to memory base variable, which will be ++ * initialized by glBusInit(). ++ * _HIF_SDIO: bus driver handle ++ */ ++ ++ bRet = glBusInit(pvData); ++ wlanDebugInit(); ++ /* Cannot get IO address from interface */ ++ if (FALSE == bRet) { ++ DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n"); ++ i4Status = -EIO; ++ eFailReason = BUS_INIT_FAIL; ++ break; ++ } ++ /* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */ ++ prWdev = wlanNetCreate(pvData); ++ if (prWdev == NULL) { ++ DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n"); ++ i4Status = -ENOMEM; ++ eFailReason = NET_CREATE_FAIL; ++ break; ++ } ++ /* 4 <2.5> Set the ioaddr to HIF Info */ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ gPrDev = prGlueInfo->prDevHandler; ++ ++ /* 4 <4> Setup IRQ */ ++ prWlandevInfo = &arWlanDevInfo[i4DevIdx]; ++ ++ i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ ++ if (i4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n"); ++ eFailReason = BUS_SET_IRQ_FAIL; ++ break; ++ } ++ ++ prGlueInfo->i4DevIdx = i4DevIdx; ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ prGlueInfo->u4ReadyFlag = 0; ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP); ++#endif ++#if CFG_SUPPORT_CFG_FILE ++ { ++ PUINT_8 pucConfigBuf; ++ UINT_32 u4ConfigReadLen; ++ ++ wlanCfgInit(prAdapter, NULL, 0, 0); ++ pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE); ++ u4ConfigReadLen = 0; ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n"); ++ if (pucConfigBuf) { ++ kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); ++ if (kalReadToFile("/data/misc/wifi.cfg", ++ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n"); ++ ++ } else if (kalReadToFile("/data/misc/wifi/wifi.cfg", ++ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n"); ++ } else if (kalReadToFile("/etc/firmware/wifi.cfg", ++ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read /etc/firmware/wifi.cfg\n"); ++ } ++ ++ if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) ++ wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0); ++ kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE); ++ } /* pucConfigBuf */ ++ } ++#endif ++ /* 4 <5> Start Device */ ++ /* */ ++#if CFG_ENABLE_FW_DOWNLOAD ++ DBGLOG(INIT, TRACE, "start to download firmware...\n"); ++ ++ /* before start adapter, we need to open and load firmware */ ++ { ++ UINT_32 u4FwSize = 0; ++ PVOID prFwBuffer = NULL; ++ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; ++ ++ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ ++ kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T)); ++ prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS; ++ prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS; ++ ++ /* Load NVRAM content to REG_INFO_T */ ++ glLoadNvram(prGlueInfo, prRegInfo); ++#if CFG_SUPPORT_CFG_FILE ++ wlanCfgApply(prAdapter); ++#endif ++ ++ /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */ ++ ++ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; ++ prRegInfo->fgEnArpFilter = TRUE; ++ ++ if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) { ++ i4Status = -EIO; ++ DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n"); ++ goto bailout; ++ } else { ++ ++ if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, ++ u4FwSize) != WLAN_STATUS_SUCCESS) { ++ i4Status = -EIO; ++ } ++ } ++ ++ kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer); ++ ++bailout: ++ /* kfree(prRegInfo); */ ++ ++ DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status); ++ ++ if (i4Status < 0) { ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4FwCnt; ++ ++ DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n"); ++ HifInfo = &prAdapter->prGlueInfo->rHifInfo; ++ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) ++ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); ++ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ ++ ++ /* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */ ++ /* dump HIF register may be hung */ ++ if (!fgIsBusAccessFailed) ++ HifRegDump(prGlueInfo->prAdapter); ++/* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */ ++/* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */ ++ eFailReason = ADAPTER_START_FAIL; ++ break; ++ } ++ } ++#else ++ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ ++ kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T)); ++ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; ++ ++ /* Load NVRAM content to REG_INFO_T */ ++ glLoadNvram(prGlueInfo, prRegInfo); ++ ++ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; ++ ++ if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) { ++ i4Status = -EIO; ++ eFailReason = ADAPTER_START_FAIL; ++ break; ++ } ++#endif ++ if (FALSE == prAdapter->fgEnable5GBand) ++ prWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; ++ ++ prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread"); ++ kalSetHalted(FALSE); ++#if CFG_SUPPORT_ROAMING_ENC ++ /* adjust roaming threshold */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ CMD_ROAMING_INFO_T rRoamingInfo; ++ UINT_32 u4SetInfoLen = 0; ++ ++ prAdapter->fgIsRoamingEncEnabled = TRUE; ++ ++ /* suggestion from Tsaiyuan.Hsu */ ++ kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T)); ++ rRoamingInfo.fgIsFastRoamingApplied = TRUE; ++ ++ DBGLOG(INIT, TRACE, "Enable roaming enhance function\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRoamingInfo, ++ &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus); ++ } ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++ /* adjust tx rate switch threshold */ ++ rlmTxRateEnhanceConfig(prGlueInfo->prAdapter); ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ ++ /* set MAC address */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ struct sockaddr MacAddr; ++ UINT_32 u4SetInfoLen = 0; ++ ++ kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data)); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryCurrentAddr, ++ &MacAddr.sa_data, ++ PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus); ++ prGlueInfo->u4ReadyFlag = 0; ++ } else { ++ ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data)); ++ ether_addr_copy(prGlueInfo->prDevHandler->perm_addr, ++ prGlueInfo->prDevHandler->dev_addr); ++ ++ /* card is ready */ ++ prGlueInfo->u4ReadyFlag = 1; ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data)); ++#endif ++ } ++ } ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ /* set HW checksum offload */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; ++ UINT_32 u4SetInfoLen = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetCSUMOffload, ++ (PVOID) &u4CSUMFlags, ++ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus); ++ } ++#endif ++ ++ /* 4 <3> Register the card */ ++ DBGLOG(INIT, TRACE, "wlanNetRegister...\n"); ++ i4DevIdx = wlanNetRegister(prWdev); ++ if (i4DevIdx < 0) { ++ i4Status = -ENXIO; ++ DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n"); ++ eFailReason = NET_REGISTER_FAIL; ++ break; ++ } ++ ++ wlanRegisterNotifier(); ++ /* 4 <6> Initialize /proc filesystem */ ++#ifdef WLAN_INCLUDE_PROC ++ DBGLOG(INIT, TRACE, "init procfs...\n"); ++ i4Status = procCreateFsEntry(prGlueInfo); ++ if (i4Status < 0) { ++ DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n"); ++ eFailReason = PROC_INIT_FAIL; ++ break; ++ } ++#endif /* WLAN_INCLUDE_PROC */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; ++ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; ++ glRegisterAmpc(prGlueInfo); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ DBGLOG(INIT, TRACE, "wlanSubModInit...\n"); ++ ++ /* wlan is launched */ ++ prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE; ++ /* if p2p module is inserted, notify tx_thread to init p2p network */ ++ if (rSubModHandler[P2P_MODULE].subModInit) ++ wlanSubModInit(prGlueInfo); ++ /* register set_p2p_mode handler to mtk_wmt_wifi */ ++ register_set_p2p_mode_handler(set_p2p_mode_handler); ++#endif ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP"); ++#endif ++ } while (FALSE); ++ ++ if (i4Status != WLAN_STATUS_SUCCESS) { ++ switch (eFailReason) { ++ case PROC_INIT_FAIL: ++ wlanNetUnregister(prWdev); ++ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread stops */ ++ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ wlanAdapterStop(prAdapter); ++ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case NET_REGISTER_FAIL: ++ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread stops */ ++ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ wlanAdapterStop(prAdapter); ++ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case ADAPTER_START_FAIL: ++ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case BUS_SET_IRQ_FAIL: ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case NET_CREATE_FAIL: ++ break; ++ case BUS_INIT_FAIL: ++ break; ++ default: ++ break; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2PEnding = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ } ++#endif ++#if CFG_SUPPORT_AGPS_ASSIST ++ if (i4Status == WLAN_STATUS_SUCCESS) ++ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0); ++#endif ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ { ++ int iMetInitRet = WLAN_STATUS_FAILURE; ++ ++ if (i4Status == WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, TRACE, "init MET procfs...\n"); ++ iMetInitRet = kalMetInitProcfs(prGlueInfo); ++ if (iMetInitRet < 0) ++ DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n"); ++ } ++ } ++#endif ++ if (i4Status == WLAN_STATUS_SUCCESS) { ++ /*Init performance monitor structure */ ++ kalPerMonInit(prGlueInfo); ++ /* probe ok */ ++ DBGLOG(INIT, TRACE, "wlanProbe ok\n"); ++ } else { ++ /* we don't care the return value of mtk_wcn_set_connsys_power_off_flag, ++ * because even this function returns ++ * error, we can also call core dump but only core dump failed. */ ++ if (g_IsNeedDoChipReset) ++ mtk_wcn_set_connsys_power_off_flag(0); ++ /* probe failed */ ++ DBGLOG(INIT, ERROR, "wlanProbe failed\n"); ++ } ++ ++ return i4Status; ++} /* end of wlanProbe() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method to stop driver operation and release all resources. Following ++* this call, no frame should go up or down through this interface. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID wlanRemove(VOID) ++{ ++#define KAL_WLAN_REMOVE_TIMEOUT_MSEC 3000 ++ struct net_device *prDev = NULL; ++ P_WLANDEV_INFO_T prWlandevInfo = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ ++ DBGLOG(INIT, LOUD, "Remove wlan!\n"); ++ ++ /* 4 <0> Sanity check */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (0 == u4WlanDevNum) { ++ DBGLOG(INIT, ERROR, "0 == u4WlanDevNum\n"); ++ return; ++ } ++ /* unregister set_p2p_mode handler to mtk_wmt_wifi */ ++ register_set_p2p_mode_handler(NULL); ++ ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1]; ++ ++ ASSERT(prDev); ++ if (NULL == prDev) { ++ DBGLOG(INIT, ERROR, "NULL == prDev\n"); ++ return; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (NULL == prGlueInfo) { ++ DBGLOG(INIT, ERROR, "NULL == prGlueInfo\n"); ++ free_netdev(prDev); ++ return; ++ } ++ ++ kalPerMonDestroy(prGlueInfo); ++#if CFG_ENABLE_WIFI_DIRECT ++ /* avoid remove & p2p off command simultaneously */ ++ { ++ BOOLEAN fgIsP2POnOffing; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2PEnding = 1; ++ fgIsP2POnOffing = g_u4P2POnOffing; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ ++ DBGLOG(INIT, TRACE, "waiting for fgIsP2POnOffing...\n"); ++ ++ /* History: cannot use down() here, sometimes we cannot come back here */ ++ /* waiting for p2p off command finishes, we cannot skip the remove */ ++ while (1) { ++ if (fgIsP2POnOffing == 0) ++ break; ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ fgIsP2POnOffing = g_u4P2POnOffing; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered) { ++ bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter); ++ /* wait 300ms for BoW module to send deauth */ ++ kalMsleep(300); ++ } ++#endif ++ ++ /* 4 <1> Stopping handling interrupt and free IRQ */ ++ DBGLOG(INIT, TRACE, "free IRQ...\n"); ++ glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev))); ++ ++ kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); ++ ++ kalSetHalted(TRUE); /* before flush_delayed_work() */ ++ if (fgIsWorkMcStart == TRUE) { ++ DBGLOG(INIT, TRACE, "flush_delayed_work...\n"); ++ flush_delayed_work(&workq); /* flush_delayed_work_sync is deprecated */ ++ } ++ ++ flush_delayed_work(&sched_workq); ++ ++ DBGLOG(INIT, INFO, "down g_halt_sem...\n"); ++ kalHaltLock(KAL_WLAN_REMOVE_TIMEOUT_MSEC); ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); ++#endif ++ ++/* flush_delayed_work_sync(&workq); */ ++/* flush_delayed_work(&workq); */ /* flush_delayed_work_sync is deprecated */ ++ ++ /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */ ++/* prGlueInfo->u4Flag |= GLUE_FLAG_HALT; */ ++ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); ++ DBGLOG(INIT, TRACE, "waiting for tx_thread stop...\n"); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ DBGLOG(INIT, TRACE, "wait_for_completion_interruptible\n"); ++ ++ /* wait main thread stops */ ++ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); ++ ++ DBGLOG(INIT, TRACE, "mtk_sdiod stopped\n"); ++ ++ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rTxThreadWakeLock); ++ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ ++ /* prGlueInfo->rHifInfo.main_thread = NULL; */ ++ prGlueInfo->main_thread = NULL; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (prGlueInfo->rBowInfo.fgIsRegistered) ++ glUnregisterAmpc(prGlueInfo); ++#endif ++ ++ /* 4 <3> Remove /proc filesystem. */ ++#ifdef WLAN_INCLUDE_PROC ++ procRemoveProcfs(); ++#endif /* WLAN_INCLUDE_PROC */ ++ ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ kalMetRemoveProcfs(); ++#endif ++ ++ /* Force to do DMA reset */ ++ DBGLOG(INIT, TRACE, "glResetHif\n"); ++ glResetHif(prGlueInfo); ++ ++ /* 4 <4> wlanAdapterStop */ ++ prAdapter = prGlueInfo->prAdapter; ++#if CFG_SUPPORT_AGPS_ASSIST ++ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, 0); ++#endif ++ ++ wlanAdapterStop(prAdapter); ++ DBGLOG(INIT, TRACE, "Number of Stalled Packets = %d\n", prGlueInfo->i4TxPendingFrameNum); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE; ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) { ++ DBGLOG(INIT, TRACE, "p2pNetUnregister...\n"); ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ p2pNetUnregister(prGlueInfo, FALSE); ++#endif ++ DBGLOG(INIT, INFO, "p2pRemove...\n"); ++ p2pRemove(prGlueInfo); ++ } ++#endif ++ ++ /* 4 <5> Release the Bus */ ++ glBusRelease(prDev); ++ ++ kalHaltUnlock(); ++ wlanDebugUninit(); ++ /* 4 <6> Unregister the card */ ++ wlanNetUnregister(prDev->ieee80211_ptr); ++ ++ /* 4 <7> Destroy the device */ ++ wlanNetDestroy(prDev->ieee80211_ptr); ++ prDev = NULL; ++ ++ DBGLOG(INIT, LOUD, "wlanUnregisterNotifier...\n"); ++ wlanUnregisterNotifier(); ++ ++ DBGLOG(INIT, INFO, "wlanRemove ok\n"); ++} /* end of wlanRemove() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver entry point when the driver is configured as a Linux Module, and ++* is called once at module load time, by the user-level modutils ++* application: insmod or modprobe. ++* ++* \retval 0 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++/* 1 Module Entry Point */ ++static int initWlan(void) ++{ ++ int ret = 0, i; ++#if DBG ++ for (i = 0; i < DBG_MODULE_NUM; i++) ++ aucDebugModule[i] = DBG_CLASS_MASK; /* enable all */ ++#else ++ /* Initial debug level is D1 */ ++ for (i = 0; i < DBG_MODULE_NUM; i++) ++ aucDebugModule[i] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_INFO | DBG_CLASS_STATE; ++#endif /* DBG */ ++ DBGLOG(INIT, INFO, "initWlan\n"); ++ ++ spin_lock_init(&g_p2p_lock); ++ ++ /* memory pre-allocation */ ++ kalInitIOBuffer(); ++ procInitFs(); ++ createWirelessDevice(); ++ if (gprWdev) ++ glP2pCreateWirelessDevice((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy)); ++ ++ ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO); ++ ++ if (ret == -EIO) { ++ kalUninitIOBuffer(); ++ return ret; ++ } ++#if (CFG_CHIP_RESET_SUPPORT) ++ glResetInit(); ++#endif ++ ++ /* register set_dbg_level handler to mtk_wmt_wifi */ ++ register_set_dbg_level_handler(set_dbg_level_handler); ++ ++ /* Set the initial DEBUG CLASS of each module */ ++ return ret; ++} /* end of initWlan() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver exit point when the driver as a Linux Module is removed. Called ++* at module unload time, by the user level modutils application: rmmod. ++* This is our last chance to clean up after ourselves. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++/* 1 Module Leave Point */ ++static VOID exitWlan(void) ++{ ++ DBGLOG(INIT, INFO, "exitWlan\n"); ++ ++ /* unregister set_dbg_level handler to mtk_wmt_wifi */ ++ register_set_dbg_level_handler(NULL); ++ ++#if CFG_CHIP_RESET_SUPPORT ++ glResetUninit(); ++#endif ++ destroyWirelessDevice(); ++ glP2pDestroyWirelessDevice(); ++ ++ glUnregisterBus(wlanRemove); ++ ++ /* free pre-allocated memory */ ++ kalUninitIOBuffer(); ++ ++ DBGLOG(INIT, INFO, "exitWlan\n"); ++ procUninitProcFs(); ++ ++} /* end of exitWlan() */ ++ ++#ifdef MTK_WCN_BUILT_IN_DRIVER ++ ++int mtk_wcn_wlan_gen2_init(void) ++{ ++ return initWlan(); ++} ++EXPORT_SYMBOL(mtk_wcn_wlan_gen2_init); ++ ++void mtk_wcn_wlan_gen2_exit(void) ++{ ++ return exitWlan(); ++} ++EXPORT_SYMBOL(mtk_wcn_wlan_gen2_exit); ++ ++#else ++ ++module_init(initWlan); ++module_exit(exitWlan); ++ ++#endif ++ ++MODULE_AUTHOR(NIC_AUTHOR); ++MODULE_DESCRIPTION(NIC_DESC); ++MODULE_SUPPORTED_DEVICE(NIC_NAME); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +new file mode 100644 +index 000000000000..e8f4f76960a5 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +@@ -0,0 +1,4801 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#3 ++*/ ++ ++/*! \file gl_kal.c ++ \brief GLUE Layer will export the required procedures here for internal driver stack. ++ ++ This file contains all routines which are exported from GLUE Layer to internal ++ driver stack. ++*/ ++ ++/* ++** Log: gl_kal.c ++** ++** 08 20 2012 yuche.tsai ++** NULL ++** Fix possible KE issue. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 05 31 2012 terry.wu ++ * NULL ++ * . ++ * ++ * 03 26 2012 cp.wu ++ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist ++ * invoke put_cred() after get_current_cred() calls. ++ * ++ * 03 07 2012 yuche.tsai ++ * NULL ++ * Fix compile error when WiFi Direct is off. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 02 20 2012 cp.wu ++ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist ++ * do not need to invoke free() while firmware image file doesn't exist ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 21 2011 cp.wu ++ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing ++ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer ++ * add more checking for such cases ++ * ++ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. ++ * add some tweaking to protect such cases because that net device has become invalid. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 16 2011 yuche.tsai ++ * NULL ++ * Avoid using work thread. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 23 2011 yuche.tsai ++ * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue ++ * Regulation domain feature check in. ++ * ++ * 08 12 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 13 2011 eddie.chen ++ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni ++ * Add tx rx statistics and netif_rx_ni. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated ++ * network type ++ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected ++ * ++ * 04 08 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * correct i4TxPendingFrameNum decreasing. ++ * ++ * 03 23 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * apply multi-queue operation only for linux kernel > 2.6.26 ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability for compatible with linux 2.6.12. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * refix ... ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * correct compiling warning/error. ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * add more robust fault tolerance design when pre-allocation failed. (rarely happen) ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 14 2011 jeffrey.chang ++ * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message ++ * fix kernel build warning message ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 21 2011 cp.wu ++ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain ++ * simplify logic for checking NVRAM existence only once. ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 19 2011 cp.wu ++ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 ++ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues ++ * due to multiple access ++ * use mutex to protect kalIoctl() for thread safe. ++ * ++ * 11 26 2010 cp.wu ++ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field ++ * checking ++ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used ++ * to indicate user is attached ++ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 11 02 2010 jeffrey.chang ++ * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets ++ * . ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 jeffrey.chang ++ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform ++ * Remove redundant code which cause mismatch of power control release ++ * ++ * 10 25 2010 jeffrey.chang ++ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform ++ * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control ++ * ++ * 10 18 2010 jeffrey.chang ++ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue ++ * refine the scan ioctl to prevent hanging of Android UI ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * if there is NVRAM, then use MAC address on NVRAM as default MAC address. ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * API added: nicTxPendingPackets(), for simplifying porting layer ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Support second interface indicate when enabling P2P. ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 16 2010 jeffrey.chang ++ * NULL ++ * remove redundant code which cause kernel panic ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * simplify post-handling after TX_DONE interrupt is handled. ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) remove unused spinlocks ++ * 2) enable encyption ioctls ++ * 3) fix scan ioctl which may cause supplicant to hang ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * add new KAL api ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * bug fix: allocate regInfo when disabling firmware download ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * use glue layer api to decrease or increase counter atomically ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * modify tx thread and remove some spinlock ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * use different spin lock for security frame ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * add new spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add spinlock for pending security frame count ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * adjust the timer unit to microsecond ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * timer should return value greater than zero ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add kal api for scanning done ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * modify cmd/data path for new design ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add new kal api ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * for linux driver migration ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove unused files. ++ * ++ * 05 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix private ioctl for rftest ++ * ++ * 05 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * workaround for fixing request_firmware() failure on android 2.1 ++ * ++ * 05 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix kernel panic when debug mode enabled ++ * ++ * 05 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) Modify set mac address code ++ * 2) remove power management macro ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Disable network interface after disassociation ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * fill network type field while doing frame identification. ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * prevent supplicant accessing driver during resume ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) fix firmware download bug ++ * 2) remove query statistics for acelerating firmware download ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 15 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * change firmware name ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * flush pending TX packets while unloading driver ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Set driver own before handling cmd queue ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used ++ * 2) fix ioctl ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler ++ * * * * * * * * * * * * * * * * * * capability ++ * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix spinlock usage ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add spinlock for i4TxPendingFrameNum access ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) add spinlock ++ * * 2) add KAPI for handling association info ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix spinlock usage ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding firmware download KAPI ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Set MAC address from firmware ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. free cmdinfo after command is emiited. ++ * 2. for BoW frames, user priority is extracted from sk_buff directly. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * * * are now handled in glue layer ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)deliver the kalOidComplete status to upper layer ++ * (2) fix spin lock ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add timeout check in the kalOidComplete ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * * * 2) add 2 kal API for later integration ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * raising the priority of processing interrupt ++ * ++ * 04 01 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding secondary command queue for improving non-glue code portability ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download kal api ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add Bluetooth-over-Wifi frame header check ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088 ++** fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding ++** \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461 ++** Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL ++** \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088 ++** remove non-used code for code review, add assert check ++** \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461 ++** \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461 ++** Rename KAL function ++** \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461 ++** \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084 ++** rename wlanoid ++** \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084 ++** remove un-used KAL function ++** \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461 ++** Move Query Media Status to GLUE ++** \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461 ++** change awake queue threshold and remove code which mark #if 0 ++** \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084 ++** add KAL function to setting pattern search function enable/ disable ++** \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461 ++** Add comment ++** \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461 ++** Add update MAC Address for Linux ++** \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084 ++** update function for initial value access ++** \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088 ++** use kal update associate request at linux ++** \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385 ++** 1. add Query Registry Mac address function. ++** \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084 ++** modify KAL set network address/ checksum offload part ++** \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461 ++** Add debug option - Packet Order for Linux ++** \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084 ++** modify the argument of kalQueryPacketInfo() ++** \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425 ++** 1. Revise csum offload ++** \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425 ++** 1. Fix bugs ++** ++** \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461 ++** Fix Windows RX multiple packet retain problem ++** \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088 ++** CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit ++** \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425 ++** 1. Modify for CSUM offloading with Tx Fragment ++** \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461 ++** Add Tx Fragmentation Support ++** \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088 ++** add the WPS code, indicate the mgmt frame to upper layer ++** \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425 ++** 1. Update wlanQueryInformation ++** \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425 ++** 1. Refine multicast list code ++** 2. Refine TCP/IP csum offload code ++** ++** Revision 1.5 2007/07/17 13:01:18 MTK01088 ++** add associate req and rsp function ++** ++** Revision 1.4 2007/07/13 05:19:19 MTK01084 ++** provide timer set functions ++** ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include "gl_os.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#if defined(CONFIG_MTK_TC1_FEATURE) ++#include ++#endif ++#if CFG_SUPPORT_AGPS_ASSIST ++#include ++#endif ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++#include ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if DBG ++int allocatedMemSize = 0; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++/* #define MTK_DMA_BUF_MEMCPY_SUP */ ++static PVOID pvIoBuffer; ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++static PVOID pvIoPhyBuf; ++static PVOID pvDmaBuffer; ++static PVOID pvDmaPhyBuf; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++static UINT_32 pvIoBufferSize; ++static UINT_32 pvIoBufferUsage; ++static struct KAL_HALT_CTRL_T rHaltCtrl = { ++ .lock = __SEMAPHORE_INITIALIZER(rHaltCtrl.lock, 1), ++ .owner = NULL, ++ .fgHalt = TRUE, ++ .fgHeldByKalIoctl = FALSE, ++ .u4HoldStart = 0, ++}; ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT ++typedef enum _ENUM_WMTHWVER_TYPE_T { ++ WMTHWVER_MT6620_E1 = 0x0, ++ WMTHWVER_MT6620_E2 = 0x1, ++ WMTHWVER_MT6620_E3 = 0x2, ++ WMTHWVER_MT6620_E4 = 0x3, ++ WMTHWVER_MT6620_E5 = 0x4, ++ WMTHWVER_MT6620_E6 = 0x5, ++ WMTHWVER_MT6620_MAX, ++ WMTHWVER_INVALID = 0xff ++} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &(prGlueInfo->rAhbIsrWakeLock), (HZ / 10)); /* 100ms */ ++} ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ ++static struct file *filp; ++static uid_t orgfsuid; ++static gid_t orgfsgid; ++static mm_segment_t orgfs; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* open firmware image in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalFirmwareOpen(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_8 aucFilePath[50]; ++ ++ /* FIX ME: since we don't have hotplug script in the filesystem ++ * , so the request_firmware() KAPI can not work properly ++ */ ++ ++ /* save uid and gid used for filesystem access. ++ * set user and group to 0(root) */ ++ struct cred *cred = (struct cred *)get_current_cred(); ++ ++ orgfsuid = cred->fsuid.val; ++ orgfsgid = cred->fsgid.val; ++ cred->fsuid.val = cred->fsgid.val = 0; ++ ++ ASSERT(prGlueInfo); ++ ++ orgfs = get_fs(); ++ set_fs(get_ds()); ++ ++ /* open the fw file */ ++#if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT ++ switch (mtk_wcn_wmt_hwver_get()) { ++ case WMTHWVER_MT6620_E1: ++ case WMTHWVER_MT6620_E2: ++ case WMTHWVER_MT6620_E3: ++ case WMTHWVER_MT6620_E4: ++ case WMTHWVER_MT6620_E5: ++ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); ++ break; ++ ++ case WMTHWVER_MT6620_E6: ++ default: ++ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME "_E6", O_RDONLY, 0); ++ break; ++ } ++#elif defined(MT6628) ++/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6628", O_RDONLY, 0); */ ++/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6582", O_RDONLY, 0); */ ++#if 0 /* new wifi ram code mechanism, waiting firmware ready, then we can enable these code */ ++ kalMemZero(aucFilePath, sizeof(aucFilePath)); ++ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_AD", sizeof("/etc/firmware/" CFG_FW_FILENAME "_AD")); ++ filp = filp_open(aucFilePath, O_RDONLY, 0); ++ if (!IS_ERR(filp)) ++ goto open_success; ++#endif ++ kalMemZero(aucFilePath, sizeof(aucFilePath)); ++ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_", strlen("/etc/firmware/" CFG_FW_FILENAME "_")); ++ glGetChipInfo(prGlueInfo, &aucFilePath[strlen("/etc/firmware/" CFG_FW_FILENAME "_")]); ++ ++ DBGLOG(INIT, INFO, "open file: %s\n", aucFilePath); ++ ++ filp = filp_open(aucFilePath, O_RDONLY, 0); ++#else ++ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); ++#endif ++ if (IS_ERR(filp)) { ++ DBGLOG(INIT, ERROR, "Open FW image: %s failed\n", CFG_FW_FILENAME); ++ goto error_open; ++ } ++#if 0 ++open_success: ++#endif ++ DBGLOG(INIT, TRACE, "Open FW image: %s done\n", CFG_FW_FILENAME); ++ return WLAN_STATUS_SUCCESS; ++ ++error_open: ++ /* restore */ ++ set_fs(orgfs); ++ cred->fsuid.val = orgfsuid; ++ cred->fsgid.val = orgfsgid; ++ put_cred(cred); ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* release firmware image in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalFirmwareClose(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ if ((filp != NULL) && !IS_ERR(filp)) { ++ /* close firmware file */ ++ filp_close(filp, NULL); ++ ++ /* restore */ ++ set_fs(orgfs); ++ { ++ struct cred *cred = (struct cred *)get_current_cred(); ++ ++ cred->fsuid.val = orgfsuid; ++ cred->fsgid.val = orgfsgid; ++ put_cred(cred); ++ } ++ filp = NULL; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* load firmware image in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalFirmwareLoad(IN P_GLUE_INFO_T prGlueInfo, OUT PVOID prBuf, IN UINT_32 u4Offset, OUT PUINT_32 pu4Size) ++{ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4Size); ++ ASSERT(prBuf); ++ ++ /* l = filp->f_path.dentry->d_inode->i_size; */ ++#if 0 ++ /* the object must have a read method */ ++ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) { ++ goto error_read; ++ } else { ++ filp->f_pos = u4Offset; ++ *pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos); ++ } ++#else ++ /* the object must have a read method */ ++ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) ) { ++ goto error_read; ++ } else { ++ filp->f_pos = u4Offset; ++ *pu4Size = vfs_read(filp, prBuf, *pu4Size, &filp->f_pos); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++ ++error_read: ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* query firmware image size in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS kalFirmwareSize(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_32 pu4Size) ++{ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4Size); ++ ++ //*pu4Size = filp->f_path.dentry->d_inode->i_size; ++ *pu4Size = filp->f_op->llseek(filp, 0, 2); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to load firmware image ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image ++* \param pu4FileLength File length and memory mapped length as well ++ ++* \retval Map File Handle, used for unammping ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) ++{ ++ UINT_32 u4FwSize = 0; ++ PVOID prFwBuffer = NULL; ++ ++ DEBUGFUNC("kalFirmwareImageMapping"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ppvMapFileBuf); ++ ASSERT(pu4FileLength); ++ ++ do { ++ /* <1> Open firmware */ ++ if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, TRACE, "kalFirmwareOpen fail!\n"); ++ break; ++ } ++ ++ /* <2> Query firmare size */ ++ kalFirmwareSize(prGlueInfo, &u4FwSize); ++ printk(KERN_ERR "%s firmware size %d\n", __FUNCTION__, u4FwSize); ++ /* <3> Use vmalloc for allocating large memory trunk */ ++ prFwBuffer = vmalloc(ALIGN_4(u4FwSize)); ++ /* <4> Load image binary into buffer */ ++ if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) { ++ vfree(prFwBuffer); ++ kalFirmwareClose(prGlueInfo); ++ DBGLOG(INIT, TRACE, "kalFirmwareLoad fail!\n"); ++ break; ++ } ++ /* <5> write back info */ ++ *pu4FileLength = u4FwSize; ++ *ppvMapFileBuf = prFwBuffer; ++ ++ return prFwBuffer; ++ ++ } while (FALSE); ++ ++ return NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to unload firmware image mapped memory ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param pvFwHandle Pointer to mapping handle ++* \param pvMapFileBuf Pointer to memory-mapped firmware image ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) ++{ ++ DEBUGFUNC("kalFirmwareImageUnmapping"); ++ ++ ASSERT(prGlueInfo); ++ ++ /* pvMapFileBuf might be NULL when file doesn't exist */ ++ if (pvMapFileBuf) ++ vfree(pvMapFileBuf); ++ ++ kalFirmwareClose(prGlueInfo); ++} ++ ++#endif ++ ++#if 0 ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to load firmware image ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image ++* \param pu4FileLength File length and memory mapped length as well ++ ++* \retval Map File Handle, used for unammping ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) ++{ ++ INT_32 i4Ret = 0; ++ ++ DEBUGFUNC("kalFirmwareImageMapping"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ppvMapFileBuf); ++ ASSERT(pu4FileLength); ++ ++ do { ++ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; ++ ++ prGlueInfo->prFw = NULL; ++ ++ /* <1> Open firmware */ ++ i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, prHifInfo->Dev); ++ ++ if (i4Ret) { ++ DBGLOG(INIT, TRACE, "fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret); ++ break; ++ } ++ *pu4FileLength = prGlueInfo->prFw->size; ++ *ppvMapFileBuf = prGlueInfo->prFw->data; ++ return prGlueInfo->prFw->data; ++ ++ } while (FALSE); ++ ++ return NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to unload firmware image mapped memory ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param pvFwHandle Pointer to mapping handle ++* \param pvMapFileBuf Pointer to memory-mapped firmware image ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) ++{ ++ DEBUGFUNC("kalFirmwareImageUnmapping"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pvMapFileBuf); ++ ++ release_firmware(prGlueInfo->prFw); ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to acquire ++* OS SPIN_LOCK. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[out] pu4Flags Pointer of a variable for saving IRQ flags ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags) ++{ ++ unsigned long u4Flags = 0; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4Flags); ++ ++ if (rLockCategory < SPIN_LOCK_NUM) { ++ ++#if CFG_USE_SPIN_LOCK_BOTTOM_HALF ++ spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]); ++#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); ++#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ ++ *pu4Flags = u4Flags; ++/* DBGLOG(INIT, TRACE, ("A+%d\n", rLockCategory)); */ ++ } ++ ++} /* end of kalAcquireSpinLock() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to release ++* OS SPIN_LOCK. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[in] u4Flags Saved IRQ flags ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (rLockCategory < SPIN_LOCK_NUM) { ++ /* DBGLOG(INIT, TRACE, ("A-%d %d %d\n", rLockCategory, u4MemAllocCnt, u4MemFreeCnt)); */ ++#if CFG_USE_SPIN_LOCK_BOTTOM_HALF ++ spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]); ++#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); ++#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ ++ } ++ ++} /* end of kalReleaseSpinLock() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to update ++* current MAC address. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pucMacAddr Pointer of current MAC address ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr) ++{ ++ ASSERT(prGlueInfo); ++ ASSERT(pucMacAddr); ++ ++ if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr)) ++ memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN); ++ ++} ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To query the packet information for offload related parameters. ++* ++* \param[in] pvPacket Pointer to the packet descriptor. ++* \param[in] pucFlag Points to the offload related parameter. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag) ++{ ++ struct sk_buff *skb = (struct sk_buff *)pvPacket; ++ UINT_8 ucFlag = 0; ++ ++ ASSERT(pvPacket); ++ ASSERT(pucFlag); ++ ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++#if DBG ++ /* Kevin: do double check, we can remove this part in Normal Driver. ++ * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so ++ * we'll process IP packet only. ++ */ ++ if (skb->protocol != htons(ETH_P_IP)) { ++ /* printk("Wrong skb->protocol( = %08x) for TX Checksum Offload.\n", skb->protocol); */ ++ } else ++#endif ++ ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN); ++ } ++ ++ *pucFlag = ucFlag; ++ ++} /* kalQueryChksumOffloadParam */ ++ ++/* 4 2007/10/8, mikewu, this is rewritten by Mike */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To update the checksum offload status to the packet to be indicated to OS. ++* ++* \param[in] pvPacket Pointer to the packet descriptor. ++* \param[in] pucFlag Points to the offload related parameter. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T aeCSUM[]) ++{ ++ struct sk_buff *skb = (struct sk_buff *)pvPacket; ++ ++ ASSERT(pvPacket); ++ ++ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS) && ++ ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) { ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ } else { ++ skb->ip_summed = CHECKSUM_NONE; ++#if DBG ++ if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE) ++ DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n"); ++ else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) ++ DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n"); ++ else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) ++ DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n"); ++ else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) ++ DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n"); ++ else ++ /* Do nothing */ ++#endif ++ } ++ ++} /* kalUpdateRxCSUMOffloadParam */ ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to free packet allocated from kalPacketAlloc. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of the packet descriptor ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) ++{ ++ dev_kfree_skb((struct sk_buff *)pvPacket); ++ if (prGlueInfo) ++ prGlueInfo->u8SkbFreed++; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Only handles driver own creating packet (coalescing buffer). ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* \param u4Size Pointer of Packet Handle ++* \param ppucData Status Code for OS upper layer ++* ++* \return NULL: Failed to allocate skb, Not NULL get skb ++*/ ++/*----------------------------------------------------------------------------*/ ++PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData) ++{ ++ struct sk_buff *prSkb = dev_alloc_skb(u4Size); ++ ++ if (prSkb) ++ *ppucData = (PUINT_8) (prSkb->data); ++#if DBG ++ { ++ PUINT_32 pu4Head = (PUINT_32) &prSkb->cb[0]; ++ *pu4Head = (UINT_32) prSkb->head; ++ DBGLOG(RX, TRACE, "prSkb->head = %#x, prSkb->cb = %#x\n", (UINT_32) prSkb->head, *pu4Head); ++ } ++#endif ++ return (PVOID) prSkb; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Process the received packet for indicating to OS. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure. ++* \param[in] pvPacket Pointer of the packet descriptor ++* \param[in] pucPacketStart The starting address of the buffer of Rx packet. ++* \param[in] u4PacketLen The packet length. ++* \param[in] pfgIsRetain Is the packet to be retained. ++* \param[in] aerCSUM The result of TCP/ IP checksum offload. ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, ++ /* IN PBOOLEAN pfgIsRetain, */ ++ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[]) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ struct sk_buff *skb = (struct sk_buff *)pvPacket; ++ ++ skb->data = pucPacketStart; ++ skb_reset_tail_pointer(skb); /* reset tail pointer first, for 64bit kernel,we should call linux kernel API */ ++ skb_trim(skb, 0); /* only if skb->len > len, then skb_trim has effect */ ++ skb_put(skb, u4PacketLen); /* shift tail and skb->len to correct value */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ kalUpdateRxCSUMOffloadParam(skb, aerCSUM); ++#endif ++ ++ return rStatus; ++} ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Do HIF loopback test. ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++unsigned int testmode = 0; ++unsigned int testlen = 64; ++ ++void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo) ++{ ++#define HIF_LOOPBK_AUTO_TEST_LEN 1600 ++/* GL_HIF_INFO_T *HifInfo; */ ++ static unsigned int txcnt; ++ struct sk_buff *MsduInfo; ++ UINT_8 *Pkt; ++ UINT_32 RegVal; ++ UINT_32 PktLen = 16; ++ ++ /* Init */ ++ if (testmode != 0) { ++ PktLen = kalRandomNumber() % 1520; ++ if (PktLen < 64) ++ PktLen = 64; ++ } else { ++ PktLen = testlen++; ++ if (PktLen > 1520) { ++ testmode = 1; ++ PktLen = 64; ++ } ++ } ++ ++/* PktLen = 100; */ ++ DBGLOG(INIT, INFO, "kalDevLoopbkAuto> Send a packet to HIF (len = %d) (total = %d)...\n", PktLen, ++txcnt); ++/* HifInfo = &GlueInfo->rHifInfo; */ ++ ++ /* Allocate a MSDU_INFO_T */ ++ MsduInfo = kalPacketAlloc(GlueInfo, HIF_LOOPBK_AUTO_TEST_LEN, &Pkt); ++ if (MsduInfo == NULL) { ++ DBGLOG(INIT, WARN, "No PKT_INFO_T for sending loopback packet!\n"); ++ return; ++ } ++ ++ /* Init the packet */ ++ MsduInfo->dev = GlueInfo->prDevHandler; ++ if (MsduInfo->dev == NULL) { ++ DBGLOG(INIT, WARN, "MsduInfo->dev == NULL!!\n"); ++ kalPacketFree(GlueInfo, MsduInfo); ++ return; ++ } ++ ++ MsduInfo->len = PktLen; ++ kalMemSet(MsduInfo->data, 0xff, 6); ++ kalMemSet(MsduInfo->data + 6, 0x5a, PktLen - 6); ++ ++ /* Simulate OS to send the packet */ ++ wlanHardStartXmit(MsduInfo, MsduInfo->dev); ++ ++#if 0 ++ PktLen += 4; ++ if (PktLen >= 1600) ++ PktLen = 16; ++#endif ++ ++ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ ++/* HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(1000); */ ++/* add_timer(&(HifInfo->HifTmrLoopbkFn)); */ ++} ++ ++int kalDevLoopbkThread(IN void *data) ++{ ++ struct net_device *dev = data; ++ P_GLUE_INFO_T GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); ++ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; ++ int ret; ++ static int test; ++ ++ while (TRUE) { ++ ret = wait_event_interruptible(HifInfo->HifWaitq, (HifInfo->HifLoopbkFlg != 0)); ++ ++ if (HifInfo->HifLoopbkFlg == 0xFFFFFFFF) ++ break; ++ ++ while (TRUE) { ++ /* if ((HifInfo->HifLoopbkFlg & 0x01) == 0) */ ++ if (GlueInfo->i4TxPendingFrameNum < 64) { ++ DBGLOG(INIT, INFO, "GlueInfo->i4TxPendingFrameNum = %d\n", ++ GlueInfo->i4TxPendingFrameNum); ++ kalDevLoopbkAuto(GlueInfo); ++ ++ if (testmode == 0) ++ kalMsleep(3000); ++ } else ++ kalMsleep(1); ++ } ++ } ++} ++ ++void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ static unsigned int rxcnt; ++ UINT_32 i; ++ UINT_8 *Buf = prSwRfb->pucRecvBuff + sizeof(HIF_TX_HEADER_T); ++ P_HIF_RX_HEADER_T prHifRxHdr = prSwRfb->prHifRxHdr; ++ UINT_32 len = prHifRxHdr->u2PacketLen - sizeof(HIF_TX_HEADER_T); ++ ++ if (len > 1600) { ++ while (1) ++ DBGLOG(INIT, ERROR, "HIF> Loopback len > 1600!!! error!!!\n"); ++ } ++ ++ for (i = 0; i < 6; i++) { ++ if (Buf[i] != 0xff) { ++ while (1) { ++ DBGLOG(INIT, ERROR, "HIF> Loopbk dst addr error (len = %d)!\n", len); ++ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); ++ } ++ } ++ } ++ ++ for (i = 6; i < len; i++) { ++ if (Buf[i] != 0x5a) { ++ while (1) { ++ DBGLOG(INIT, ERROR, "HIF> Loopbk error (len = %d)!\n", len); ++ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); ++ } ++ } ++ } ++ ++ DBGLOG(INIT, INFO, "HIF> Loopbk OK (len = %d) (total = %d)!\n", len, ++rxcnt); ++} ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate an array of received packets is available for higher ++* level protocol uses. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure. ++* \param[in] apvPkts The packet array to be indicated ++* \param[in] ucPktNum The number of packets to be indicated ++* ++* \retval TRUE Success. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum) ++{ ++ UINT_8 ucIdx = 0; ++ struct net_device *prNetDev = prGlueInfo->prDevHandler; ++ struct sk_buff *prSkb = NULL; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(apvPkts); ++ ++#if CFG_BOW_TEST ++ UINT_32 i; ++#endif ++ ++ for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++) { ++ prSkb = apvPkts[ucIdx]; ++#if DBG ++ do { ++ PUINT_8 pu4Head = (PUINT_8) &prSkb->cb[0]; ++ UINT_32 u4HeadValue = 0; ++ ++ kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue)); ++ DBGLOG(RX, TRACE, "prSkb->head = %p, prSkb->cb = 0x%x\n", pu4Head, u4HeadValue); ++ } while (0); ++#endif ++ ++ if (GLUE_GET_PKT_IS_P2P(prSkb)) { ++ /* P2P */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ prNetDev = kalP2PGetDevHdlr(prGlueInfo); ++ /* prNetDev->stats.rx_bytes += prSkb->len; */ ++ /* prNetDev->stats.rx_packets++; */ ++ prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len; ++ prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++; ++ ++#else ++ prNetDev = prGlueInfo->prDevHandler; ++#endif ++ } else if (GLUE_GET_PKT_IS_PAL(prSkb)) { ++ /* BOW */ ++#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered) ++ prNetDev = prGlueInfo->rBowInfo.prDevHandler; ++#else ++ prNetDev = prGlueInfo->prDevHandler; ++#endif ++ } else { ++ /* AIS */ ++ prNetDev = prGlueInfo->prDevHandler; ++ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; ++ prGlueInfo->rNetDevStats.rx_packets++; ++ ++ } ++ ++ /* check if the "unicast" packet is from us */ ++ if (kalMemCmp(prSkb->data, prSkb->data + 6, 6) == 0) { ++ /* we will filter broadcast/multicast packet sent from us in hardware */ ++ /* source address = destination address ? */ ++ DBGLOG(RX, EVENT, ++ "kalRxIndicatePkts got from us!!! Drop it! ([ %pM ] len %d)\n", ++ prSkb->data, prSkb->len); ++ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); ++ continue; ++ } ++#if (CFG_SUPPORT_TDLS == 1) ++ if (TdlsexRxFrameDrop(prGlueInfo, prSkb->data) == TRUE) { ++ /* drop the received TDLS action frame */ ++ DBGLOG(TDLS, WARN, ++ " %s: drop a received packet from %pM %u\n", ++ __func__, prSkb->data, ++ (UINT32) ((P_ADAPTER_T) (prGlueInfo->prAdapter))->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); ++ continue; ++ } ++ ++ /* ++ get a TDLS request/response/confirm, we need to parse the HT IE ++ because older supplicant does not pass HT IE to us ++ */ ++ TdlsexRxFrameHandle(prGlueInfo, prSkb->data, prSkb->len); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ STATS_RX_PKT_INFO_DISPLAY(prSkb->data); ++ ++ //prNetDev->last_rx = jiffies; ++ prSkb->protocol = eth_type_trans(prSkb, prNetDev); ++ prSkb->dev = prNetDev; ++ /* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */ ++ DBGLOG(RX, TRACE, "kalRxIndicatePkts len = %d\n", prSkb->len); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "Rx sk_buff->len: %d\n", prSkb->len); ++ DBGLOG(BOW, TRACE, "Rx sk_buff->data_len: %d\n", prSkb->data_len); ++ DBGLOG(BOW, TRACE, "Rx sk_buff->data:\n"); ++ ++ for (i = 0; i < prSkb->len; i++) { ++ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); ++ ++ if ((i + 1) % 16 == 0) ++ DBGLOG(BOW, TRACE, "\n"); ++ } ++ ++ DBGLOG(BOW, TRACE, "\n"); ++#endif ++ ++ if (!in_interrupt()) ++ netif_rx_ni(prSkb); /* only in non-interrupt context */ ++ else ++ netif_rx(prSkb); ++ ++ wlanReturnPacket(prGlueInfo->prAdapter, NULL); ++ } ++ ++ kalPerMonStart(prGlueInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Called by driver to indicate event to upper layer, for example, the wpa ++* supplicant or wireless tools. ++* ++* \param[in] pvAdapter Pointer to the adapter descriptor. ++* \param[in] eStatus Indicated status. ++* \param[in] pvBuf Indicated message buffer. ++* \param[in] u4BufLen Indicated message buffer size. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ScanCnt = 0, ScanDoneFailCnt = 0; ++VOID ++kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen) ++{ ++ UINT_32 bufLen; ++ P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf; ++ P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus; ++ P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1); ++ PARAM_MAC_ADDRESS arBssid; ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ PARAM_SSID_T ssid; ++ struct ieee80211_channel *prChannel = NULL; ++ struct cfg80211_bss *bss; ++ UINT_8 ucChannelNum; ++ P_BSS_DESC_T prBssDesc = NULL; ++ struct cfg80211_scan_info info = { ++ .aborted = false, ++ }; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ kalMemZero(arBssid, MAC_ADDR_LEN); ++ ++ ASSERT(prGlueInfo); ++ ++ switch (eStatus) { ++ case WLAN_STATUS_ROAM_OUT_FIND_BEST: ++ case WLAN_STATUS_MEDIA_CONNECT: ++ ++ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED; ++ ++ /* indicate assoc event */ ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &bufLen); ++ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen); ++ ++ /* switch netif on */ ++ netif_carrier_on(prGlueInfo->prDevHandler); ++ ++ do { ++ /* print message on console */ ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen); ++ ++ ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ? ++ (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen] = '\0'; ++ DBGLOG(AIS, INFO, " %s netif_carrier_on [ssid:%s %pM ]\n", ++ prGlueInfo->prDevHandler->name, ssid.aucSsid, arBssid); ++ } while (0); ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ struct cfg80211_bss *bss_others = NULL; ++ UINT_8 ucLoopCnt = 15; /* only loop 15 times to avoid dead loop */ ++ ++ /* retrieve channel */ ++ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, ++ NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, ++ NL80211_BAND_5GHZ)); ++ } ++ ++ /* ensure BSS exists */ ++ bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid, ++ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); ++ ++ if (bss == NULL) { ++ /* create BSS on-the-fly */ ++ prBssDesc = ++ wlanGetTargetBssDescByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ if (prBssDesc != NULL) { ++ bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo), prChannel, ++ CFG80211_BSS_FTYPE_PRESP, ++ arBssid, 0, /* TSF */ ++ WLAN_CAPABILITY_ESS, ++ prBssDesc->u2BeaconInterval, /* beacon interval */ ++ prBssDesc->aucIEBuf, /* IE */ ++ prBssDesc->u2IELength, /* IE Length */ ++ RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */ ++ GFP_KERNEL); ++ } ++ } ++ /* remove all bsses that before and only channel different with the current connected one ++ if without this patch, UI will show channel A is connected even if AP has change channel ++ from A to B */ ++ while (ucLoopCnt--) { ++ bss_others = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), NULL, arBssid, ++ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); ++ if (bss && bss_others && bss_others != bss) { ++ DBGLOG(SCN, INFO, "remove BSSes that only channel different\n"); ++ cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss_others); ++ } else ++ break; ++ } ++ ++ /* CFG80211 Indication */ ++ if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) { ++ /*cfg80211_roamed_bss(prGlueInfo->prDevHandler, ++ bss, ++ prGlueInfo->aucReqIe, ++ prGlueInfo->u4ReqIeLength, ++ prGlueInfo->aucRspIe, prGlueInfo->u4RspIeLength, GFP_KERNEL); ++ */ ++ struct cfg80211_roam_info roam_info = { ++ .bss = bss, ++ .req_ie = prGlueInfo->aucReqIe, ++ .req_ie_len = prGlueInfo->u4ReqIeLength, ++ .resp_ie = prGlueInfo->aucRspIe, ++ .resp_ie_len = prGlueInfo->u4RspIeLength ++ }; ++ cfg80211_roamed(prGlueInfo->prDevHandler, ++ &roam_info, ++ GFP_KERNEL); ++ } else { ++ /* to support user space roaming, cfg80211 will change the sme_state to connecting ++ before reassociate */ ++ cfg80211_connect_result(prGlueInfo->prDevHandler, ++ arBssid, ++ prGlueInfo->aucReqIe, ++ prGlueInfo->u4ReqIeLength, ++ prGlueInfo->aucRspIe, ++ prGlueInfo->u4RspIeLength, WLAN_STATUS_SUCCESS, GFP_KERNEL); ++ } ++ } ++ ++ break; ++ ++ case WLAN_STATUS_MEDIA_DISCONNECT: ++ case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY: ++ /* indicate disassoc event */ ++ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0); ++ /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first, ++ after associated success, at joinComplete(), do netif_carier_on, ++ but for unknown reason, the supplicant 1x pkt will not called the driver ++ hardStartXmit, for template workaround these bugs, add this compiling flag ++ */ ++ /* switch netif off */ ++ ++ DBGLOG(AIS, INFO, "[wifi] %s netif_carrier_off\n", ++ prGlueInfo->prDevHandler->name); ++ ++ netif_carrier_off(prGlueInfo->prDevHandler); ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ P_WIFI_VAR_T prWifiVar = &prGlueInfo->prAdapter->rWifiVar; ++ UINT_16 u2DeauthReason = prWifiVar->arBssInfo[NETWORK_TYPE_AIS_INDEX].u2DeauthReason; ++ /* CFG80211 Indication */ ++ DBGLOG(AIS, INFO, "[wifi] %s cfg80211_disconnected\n", prGlueInfo->prDevHandler->name); ++ cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, false, GFP_KERNEL); ++ } ++ ++ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; ++ ++ break; ++ ++ case WLAN_STATUS_SCAN_COMPLETE: ++ /* indicate scan complete event */ ++ wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0); ++ ++ /* 1. reset first for newly incoming request */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueInfo->prScanRequest; ++ prGlueInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ /* 2. then CFG80211 Indication */ ++ DBGLOG(SCN, TRACE, "[ais] scan complete %p %d %d\n", prScanRequest, ScanCnt, ScanDoneFailCnt); ++ ++ if (prScanRequest != NULL) ++ cfg80211_scan_done(prScanRequest, &info); ++ break; ++ case WLAN_STATUS_CONNECT_INDICATION: ++ /* indicate AIS Jion fail event ++ if (prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) */ ++ cfg80211_connect_result(prGlueInfo->prDevHandler, ++ prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc->aucBSSID, ++ prGlueInfo->aucReqIe, ++ prGlueInfo->u4ReqIeLength, ++ prGlueInfo->aucRspIe, ++ prGlueInfo->u4RspIeLength, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); ++ break; ++ ++#if 0 ++ case WLAN_STATUS_MSDU_OK: ++ if (netif_running(prGlueInfo->prDevHandler)) ++ netif_wake_queue(prGlueInfo->prDevHandler); ++ break; ++#endif ++ ++ case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION: ++ if (pStatus) { ++ switch (pStatus->eStatusType) { ++ case ENUM_STATUS_TYPE_AUTHENTICATION: ++ /* ++ printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [ %pM ] F:%lx\n", ++ pAuth->Request[0].Length, ++ pAuth->Request[0].Bssid, ++ pAuth->Request[0].Flags); ++ */ ++ /* indicate (UC/GC) MIC ERROR event only */ ++ if ((pAuth->arRequest[0].u4Flags == ++ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) || ++ (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR)) { ++ cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL, ++ (pAuth->arRequest[0].u4Flags == ++ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ? ++ NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP, ++ 0, NULL, GFP_KERNEL); ++ wext_indicate_wext_event(prGlueInfo, IWEVMICHAELMICFAILURE, ++ (unsigned char *)&pAuth->arRequest[0], ++ pAuth->arRequest[0].u4Length); ++ } ++ break; ++ ++ case ENUM_STATUS_TYPE_CANDIDATE_LIST: ++ /* ++ printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n", ++ pPmkid->u2Version, ++ pPmkid->u4NumCandidates); ++ if (pPmkid->u4NumCandidates > 0) { ++ printk(KERN_NOTICE "candidate[ %pM ] preAuth Flag:%lx\n", ++ pPmkid->arCandidateList[0].rBSSID, ++ pPmkid->arCandidateList[0].fgFlags); ++ } ++ */ ++ { ++ UINT_32 i = 0; ++ /*struct net_device *prDev = prGlueInfo->prDevHandler; */ ++ P_PARAM_PMKID_CANDIDATE_T prCand = NULL; ++ /* indicate pmk candidate via cfg80211 to supplicant, ++ the second parameter is 1000 for ++ cfg80211_pmksa_candidate_notify, because wpa_supplicant defined it. */ ++ for (i = 0; i < pPmkid->u4NumCandidates; i++) { ++ prCand = &pPmkid->arCandidateList[i]; ++ cfg80211_pmksa_candidate_notify(prGlueInfo->prDevHandler, 1000, ++ prCand->arBSSID, prCand->u4Flags, ++ GFP_KERNEL); ++ ++ wext_indicate_wext_event(prGlueInfo, ++ IWEVPMKIDCAND, ++ (unsigned char *)prCand, ++ pPmkid->u4NumCandidates); ++ } ++ } ++ break; ++ ++ default: ++ /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */ ++ /* ++ printk(KERN_NOTICE "unknown media specific indication type:%x\n", ++ pStatus->StatusType); ++ */ ++ break; ++ } ++ } else { ++ /* ++ printk(KERN_WARNING "media specific indication buffer NULL\n"); ++ */ ++ } ++ break; ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ case WLAN_STATUS_BWCS_UPDATE: ++ { ++ wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T)); ++ } ++ ++ break; ++ ++#endif ++ ++ default: ++ /* ++ printk(KERN_WARNING "unknown indication:%lx\n", eStatus); ++ */ ++ break; ++ } ++} /* kalIndicateStatusAndComplete */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to update the (re)association request ++* information to the structure used to query and set ++* OID_802_11_ASSOCIATION_INFORMATION. ++* ++* \param[in] prGlueInfo Pointer to the Glue structure. ++* \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association ++* Request frame from the AP. ++* \param[in] u4FrameBodyLen The length of the frame body of the last ++* (Re)Association Request frame. ++* \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) ++{ ++ PUINT_8 cp; ++ ++ ASSERT(prGlueInfo); ++ ++ /* reset */ ++ prGlueInfo->u4ReqIeLength = 0; ++ ++ if (fgReassocRequest) { ++ if (u4FrameBodyLen < 15) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } else { ++ if (u4FrameBodyLen < 9) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } ++ ++ cp = pucFrameBody; ++ ++ if (fgReassocRequest) { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ /* Current AP address 6 */ ++ cp += 10; ++ u4FrameBodyLen -= 10; ++ } else { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ cp += 4; ++ u4FrameBodyLen -= 4; ++ } ++ ++ wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen); ++ ++ if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) { ++ prGlueInfo->u4ReqIeLength = u4FrameBodyLen; ++ kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is called to update the (re)association ++* response information to the structure used to reply with ++* cfg80211_connect_result ++* ++* @param prGlueInfo Pointer to adapter descriptor ++* @param pucFrameBody Pointer to the frame body of the last (Re)Association ++* Response frame from the AP ++* @param u4FrameBodyLen The length of the frame body of the last ++* (Re)Association Response frame ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen) ++{ ++ UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */ ++ UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset; ++ ++ ASSERT(prGlueInfo); ++ ++ /* reset */ ++ prGlueInfo->u4RspIeLength = 0; ++ ++ if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) { ++ prGlueInfo->u4RspIeLength = u4IELength; ++ kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength); ++ } ++ ++} /* kalUpdateReAssocRspInfo */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Notify OS with SendComplete event of the specific packet. Linux should ++* free packets here. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* \param[in] status Status Code for OS upper layer ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) ++{ ++ ++ struct net_device *prDev = NULL; ++ struct sk_buff *prSkb = NULL; ++ UINT_16 u2QueueIdx = 0; ++ UINT_8 ucNetworkType = 0; ++ BOOLEAN fgIsValidDevice = TRUE; ++ ++ ASSERT(pvPacket); ++ ASSERT(prGlueInfo->i4TxPendingFrameNum); ++ ++ prSkb = (struct sk_buff *)pvPacket; ++ u2QueueIdx = skb_get_queue_mapping(prSkb); ++ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); ++ ++ if (GLUE_GET_PKT_IS_PAL(prSkb)) { ++ ucNetworkType = NETWORK_TYPE_BOW_INDEX; ++ } else if (GLUE_GET_PKT_IS_P2P(prSkb)) { ++ ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* in case packet was sent after P2P device is unregistered */ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) ++ fgIsValidDevice = FALSE; ++#endif ++ } else { ++ ucNetworkType = NETWORK_TYPE_AIS_INDEX; ++ } ++ ++ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ if (u2QueueIdx < CFG_MAX_TXQ_NUM) ++ GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); ++ prDev = prSkb->dev; ++ ++ ASSERT(prDev); ++ ++ if ((fgIsValidDevice == TRUE) && (u2QueueIdx < CFG_MAX_TXQ_NUM)) { ++ if (netif_subqueue_stopped(prDev, prSkb) && ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= ++ CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) { ++ DBGLOG(TX, INFO, "netif_wake_subqueue for bss: %d. Queue len: %d\n", ++ ucNetworkType, ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); ++ netif_wake_subqueue(prDev, u2QueueIdx); ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ prGlueInfo->rHifInfo.HifLoopbkFlg &= ~0x01; ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ } ++ } ++ ++ dev_kfree_skb((struct sk_buff *)pvPacket); ++ prGlueInfo->u8SkbFreed++; ++ ++ DBGLOG(TX, EVENT, "----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Copy Mac Address setting from registry. It's All Zeros in Linux. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \param[out] paucMacAddr Pointer to the Mac Address buffer ++* ++* \retval WLAN_STATUS_SUCCESS ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalQueryRegistryMacAddr(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_8 paucMacAddr) ++{ ++ UINT_8 aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 } ++ ++ DEBUGFUNC("kalQueryRegistryMacAddr"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(paucMacAddr); ++ ++ kalMemCopy((PVOID) paucMacAddr, (PVOID) aucZeroMac, MAC_ADDR_LEN); ++ ++} /* end of kalQueryRegistryMacAddr() */ ++ ++#if CFG_SUPPORT_EXT_CONFIG ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Read external configuration, ex. NVRAM or file ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ /* External data is given from user space by ioctl or /proc, not read by ++ driver. ++ */ ++ if (0 != prGlueInfo->u4ExtCfgLength) ++ DBGLOG(INIT, TRACE, "Read external configuration data -- OK\n"); ++ else ++ DBGLOG(INIT, TRACE, "Read external configuration data -- fail\n"); ++ ++ return prGlueInfo->u4ExtCfgLength; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This inline function is to extract some packet information, including ++* user priority, packet length, destination address, 802.1x and BT over Wi-Fi ++* or not. ++* ++* @param prGlueInfo Pointer to the glue structure ++* @param prNdisPacket Packet descriptor ++* @param pucPriorityParam User priority ++* @param pu4PacketLen Packet length ++* @param pucEthDestAddr Destination address ++* @param pfgIs1X 802.1x packet or not ++* @param pfgIsPAL BT over Wi-Fi packet or not ++* @prGenUse General used param ++* ++* @retval TRUE Success to extract information ++* @retval FALSE Fail to extract correct information ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++BOOLEAN ++kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_NATIVE_PACKET prPacket, ++ OUT PUINT_8 pucPriorityParam, ++ OUT PUINT_32 pu4PacketLen, ++ OUT PUINT_8 pucEthDestAddr, ++ OUT PBOOLEAN pfgIs1X, ++ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, ++ OUT PVOID prGenUse) ++{ ++ ++ UINT_32 u4PacketLen; ++ ++ UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT; /* Default */ ++ UINT_16 u2EtherTypeLen; ++ struct sk_buff *prSkb = (struct sk_buff *)prPacket; ++ PUINT_8 aucLookAheadBuf = NULL; ++ ++ DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo"); ++ ++ u4PacketLen = prSkb->len; ++ ++ if (u4PacketLen < ETH_HLEN) { ++ DBGLOG(TX, WARN, "Invalid Ether packet length: %u\n", (UINT_32) u4PacketLen); ++ return FALSE; ++ } ++ ++ aucLookAheadBuf = prSkb->data; ++ ++ *pfgIs1X = FALSE; ++ *pfgIsPAL = FALSE; ++ ++ /* 4 <3> Obtain the User Priority for WMM */ ++ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { ++ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_8 ucIpVersion; ++ ++ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if (ucIpVersion == IPVERSION) { ++ UINT_8 ucIpTos; ++ /* Get the DSCP value from the header of IP packet. */ ++ ucIpTos = pucIpHdr[1]; ++ ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET); ++ } ++ ++ /* TODO(Kevin): Add TSPEC classifier here */ ++ } else if (u2EtherTypeLen == ETH_P_1X || u2EtherTypeLen == ETH_P_PRE_1X) { /* For Port Control */ ++ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_8 ucEapolType = pucEapol[1]; ++ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; ++ /* ++ * generate a seq number used to trace security frame TX ++ */ ++ if (prGenUse) ++ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); ++ ++ switch (ucEapolType) { ++ case 0: /* eap packet */ ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 1: /* eapol start */ ++ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 3: /* key */ ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x... seqNo %d\n", ++ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ } ++ *pfgIs1X = TRUE; ++ } ++#if CFG_SUPPORT_WAPI ++ else if (u2EtherTypeLen == ETH_WPI_1X) { ++ PUINT_8 pucEthBody = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ ++ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; ++ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; ++ ++ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ ucSubType, u2Length, u2Seq); ++ *pfgIs1X = TRUE; ++ } ++#endif ++#if (CFG_SUPPORT_TDLS == 1) ++ else if (u2EtherTypeLen == TDLS_FRM_PROT_TYPE) { ++ /* TDLS case */ ++ TDLSEX_UP_ASSIGN(ucUserPriority); ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ else if (u2EtherTypeLen <= 1500) { /* 802.3 Frame */ ++ UINT_8 ucDSAP, ucSSAP, ucControl; ++ UINT_8 aucOUI[3]; ++ ++ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; ++ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; ++ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; ++ ++ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; ++ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; ++ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; ++ ++ if (ucDSAP == ETH_LLC_DSAP_SNAP && ++ ucSSAP == ETH_LLC_SSAP_SNAP && ++ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && ++ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && ++ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) { ++ ++ UINT_16 tmp = ++ ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]); ++ ++ *pfgIsPAL = TRUE; ++ ucUserPriority = (UINT_8) prSkb->priority; ++ ++ if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) { ++ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_SNAP_OFFSET + 5]; ++ UINT_8 ucEapolType = pucEapol[1]; ++ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; ++ if (prGenUse) ++ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); ++ ++ switch (ucEapolType) { ++ case 0: /* eap packet */ ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 1: /* eapol start */ ++ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 3: /* key */ ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x seqNo %d\n", ++ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ } ++ *pfgIs1X = TRUE; ++ } ++ } ++ } ++ /* 4 <4> Return the value of Priority Parameter. */ ++ *pucPriorityParam = ucUserPriority; ++ ++ /* 4 <5> Retrieve Packet Information - DA */ ++ /* Packet Length/ Destination Address */ ++ *pu4PacketLen = u4PacketLen; ++ ++ kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN); ++ ++ /* <6> Network type */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (*pfgIsPAL == TRUE) { ++ *pucNetworkType = NETWORK_TYPE_BOW_INDEX; ++ } else ++#endif ++ { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) { ++ *pucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ } else ++#endif ++ { ++ *pucNetworkType = NETWORK_TYPE_AIS_INDEX; ++ } ++ } ++ return TRUE; ++} /* end of kalQoSFrameClassifier() */ ++ ++VOID ++kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, ++ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus) ++{ ++ ++ ASSERT(prGlueInfo); ++ /* remove timeout check timer */ ++ wlanoidClearTimeoutCheck(prGlueInfo->prAdapter); ++ ++ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ ++ prGlueInfo->rPendStatus = rOidStatus; ++ DBGLOG(OID, TEMP, "kalOidComplete, caller: %p\n", __builtin_return_address(0)); ++ complete(&prGlueInfo->rPendComp); ++ prGlueInfo->u4OidCompleteFlag = 1; ++ /* } */ ++ /* else let it timeout on kalIoctl entry */ ++} ++ ++VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ ++ /* clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag); */ ++ if (prGlueInfo->u4OidCompleteFlag != 1) { ++ DBGLOG(OID, TEMP, "kalOidClearance, caller: %p\n", __builtin_return_address(0)); ++ complete(&prGlueInfo->rPendComp); ++ } ++ /* } */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to transfer linux ioctl to OID, and we ++* need to specify the behavior of the OID by ourself ++* ++* @param prGlueInfo Pointer to the glue structure ++* @param pvInfoBuf Data buffer ++* @param u4InfoBufLen Data buffer length ++* @param fgRead Is this a read OID ++* @param fgWaitResp does this OID need to wait for values ++* @param fgCmd does this OID compose command packet ++* @param pu4QryInfoLen The data length of the return values ++* ++* @retval TRUE Success to extract information ++* @retval FALSE Fail to extract correct information ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++/* todo: enqueue the i/o requests for multiple processes access */ ++/* */ ++/* currently, return -1 */ ++/* */ ++ ++/* static GL_IO_REQ_T OidEntry; */ ++ ++WLAN_STATUS ++kalIoctl(IN P_GLUE_INFO_T prGlueInfo, ++ IN PFN_OID_HANDLER_FUNC pfnOidHandler, ++ IN PVOID pvInfoBuf, ++ IN UINT_32 u4InfoBufLen, ++ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen) ++{ ++ P_GL_IO_REQ_T prIoReq = NULL; ++ WLAN_STATUS ret = WLAN_STATUS_SUCCESS; ++ ++ if (fgIsResetting == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ ++ /* GLUE_SPIN_LOCK_DECLARATION(); */ ++ ASSERT(prGlueInfo); ++ ++ /* <1> Check if driver is halt */ ++ /* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */ ++ /* return WLAN_STATUS_ADAPTER_NOT_READY; */ ++ /* } */ ++ ++ /* if wait longer than double OID timeout timer, then will show backtrace who held halt lock. ++ at this case, we will return kalIoctl failure because tx_thread may be hung */ ++ if (kalHaltLock(2 * WLAN_OID_TIMEOUT_THRESHOLD)) ++ return WLAN_STATUS_FAILURE; ++ ++ if (kalIsHalted()) { ++ kalHaltUnlock(); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (down_interruptible(&prGlueInfo->ioctl_sem)) { ++ kalHaltUnlock(); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* <2> TODO: thread-safe */ ++ ++ /* <3> point to the OidEntry of Glue layer */ ++ ++ prIoReq = &(prGlueInfo->OidEntry); ++ ++ ASSERT(prIoReq); ++ ++ /* <4> Compose the I/O request */ ++ prIoReq->prAdapter = prGlueInfo->prAdapter; ++ prIoReq->pfnOidHandler = pfnOidHandler; ++ prIoReq->pvInfoBuf = pvInfoBuf; ++ prIoReq->u4InfoBufLen = u4InfoBufLen; ++ prIoReq->pu4QryInfoLen = pu4QryInfoLen; ++ prIoReq->fgRead = fgRead; ++ prIoReq->fgWaitResp = fgWaitResp; ++ prIoReq->rStatus = WLAN_STATUS_FAILURE; ++#if CFG_ENABLE_WIFI_DIRECT ++ prIoReq->fgIsP2pOid = fgIsP2pOid; ++#endif ++ ++ /* <5> Reset the status of pending OID */ ++ prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE; ++ /* prGlueInfo->u4TimeoutFlag = 0; */ ++ /* prGlueInfo->u4OidCompleteFlag = 0; */ ++ ++ /* <6> Check if we use the command queue */ ++ prIoReq->u4Flag = fgCmd; ++ ++ /* <7> schedule the OID bit */ ++ set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag); ++ ++ /* <8> Wake up tx thread to handle kick start the I/O request */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ /* <9> Block and wait for event or timeout, current the timeout is 5 secs */ ++ /* if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) { */ ++ /* if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) { */ ++ DBGLOG(OID, TEMP, "kalIoctl: before wait, caller: %p\n", __builtin_return_address(0)); ++ wait_for_completion(&prGlueInfo->rPendComp); { ++ /* Case 1: No timeout. */ ++ /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo */ ++ if (prIoReq->rStatus == WLAN_STATUS_PENDING) ++ ret = prGlueInfo->rPendStatus; ++ else ++ ret = prIoReq->rStatus; ++ } ++#if 0 ++ else { ++ /* Case 2: timeout */ ++ /* clear pending OID's cmd in CMD queue */ ++ if (fgCmd) { ++ prGlueInfo->u4TimeoutFlag = 1; ++ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); ++ } ++ ret = WLAN_STATUS_FAILURE; ++ } ++#endif ++ DBGLOG(OID, TEMP, "kalIoctl: done\n"); ++ up(&prGlueInfo->ioctl_sem); ++ kalHaltUnlock(); ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear all pending security frames ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending security frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { ++ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear pending security frames ++* belongs to dedicated network type ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* \param eNetworkTypeIdx Network Type Index ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending security frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME && prCmdInfo->eNetworkType == eNetworkTypeIdx) { ++ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear all pending management frames ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending management frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear all pending management frames ++* belongs to dedicated network type ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending management frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME && ++ prCmdInfo->eNetworkType == eNetworkTypeIdx) { ++ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} /* kalClearMgmtFramesByNetType */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is a kernel thread function for handling command packets ++* Tx requests and interrupt events ++* ++* @param data data pointer to private data of tx_thread ++* ++* @retval If the function succeeds, the return value is 0. ++* Otherwise, an error code is returned. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++int tx_thread(void *data) ++{ ++ struct net_device *dev = data; ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); ++ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_GL_IO_REQ_T prIoReq = NULL; ++ P_QUE_T prTxQueue = NULL; ++ P_QUE_T prCmdQue = NULL; ++ ++ int ret = 0; ++ ++ BOOLEAN fgNeedHwAccess = FALSE; ++ ++ struct sk_buff *prSkb = NULL; ++ ++ /* for spin lock acquire and release */ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ prTxQueue = &prGlueInfo->rTxQueue; ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ current->flags |= PF_NOFREEZE; ++ ++ DBGLOG(INIT, INFO, "tx_thread starts running...\n"); ++ ++ while (TRUE) { ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /*run p2p multicast list work. */ ++ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) ++ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); ++#endif ++ ++ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { ++ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; ++ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ ++ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); ++ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; ++ } ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ DBGLOG(INIT, INFO, "tx_thread should stop now...\n"); ++ break; ++ } ++ ++ /* ++ * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT ++ * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT ++ * ++ */ ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ ++ ret = wait_event_interruptible(prGlueInfo->waitq, (prGlueInfo->ulFlag != 0)); ++ ++ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ ++/* #if (CONF_HIF_LOOPBACK_AUTO == 1) */ ++/* if (test_and_clear_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &prGlueInfo->u4Flag)) { */ ++/* kalDevLoopbkAuto(prGlueInfo); */ ++/* } */ ++/* #endif */ /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if CFG_DBG_GPIO_PINS ++ /* TX thread Wake up */ ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW); ++#endif ++#if CFG_ENABLE_WIFI_DIRECT ++ /*run p2p multicast list work. */ ++ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) ++ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); ++ ++ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag)) { ++ p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter); ++ } ++#endif ++ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { ++ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; ++ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ ++ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); ++ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; ++ } ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ DBGLOG(INIT, INFO, "<1>tx_thread should stop now...\n"); ++ break; ++ } ++ ++ fgNeedHwAccess = FALSE; ++ ++ /* Handle Interrupt */ ++ if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) { ++ if (fgNeedHwAccess == FALSE) { ++ fgNeedHwAccess = TRUE; ++ ++ wlanAcquirePowerControl(prGlueInfo->prAdapter); ++ } ++ ++ /* the Wi-Fi interrupt is already disabled in mmc thread, ++ so we set the flag only to enable the interrupt later */ ++ prGlueInfo->prAdapter->fgIsIntEnable = FALSE; ++ /* wlanISR(prGlueInfo->prAdapter, TRUE); */ ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ /* Should stop now... skip pending interrupt */ ++ DBGLOG(INIT, INFO, "ignore pending interrupt\n"); ++ } else { ++ prGlueInfo->TaskIsrCnt++; ++ wlanIST(prGlueInfo->prAdapter); ++ } ++ } ++ ++ /* transfer ioctl to OID request */ ++#if 0 ++ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { ++ DBGLOG(INIT, INFO, "<2>tx_thread should stop now...\n"); ++ break; ++ } ++#endif ++ ++ do { ++ if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag)) { ++ /* get current prIoReq */ ++ prGlueInfo->u4OidCompleteFlag = 0; ++ ++ prIoReq = &(prGlueInfo->OidEntry); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE && prIoReq->fgIsP2pOid == TRUE) { ++ /* if this Oid belongs to p2p and p2p module is removed ++ * do nothing, ++ */ ++ } else ++#endif ++ { ++ if (FALSE == prIoReq->fgRead) { ++ prIoReq->rStatus = wlanSetInformation(prIoReq->prAdapter, ++ prIoReq->pfnOidHandler, ++ prIoReq->pvInfoBuf, ++ prIoReq->u4InfoBufLen, ++ prIoReq->pu4QryInfoLen); ++ } else { ++ prIoReq->rStatus = wlanQueryInformation(prIoReq->prAdapter, ++ prIoReq->pfnOidHandler, ++ prIoReq->pvInfoBuf, ++ prIoReq->u4InfoBufLen, ++ prIoReq->pu4QryInfoLen); ++ } ++ ++ if (prIoReq->rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(OID, TEMP, "tx_thread, complete\n"); ++ complete(&prGlueInfo->rPendComp); ++ } else { ++ wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler); ++ } ++ } ++ } ++ ++ } while (FALSE); ++ ++ /* ++ * ++ * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent ++ * indicates the following requests occur ++ * ++ */ ++#if 0 ++ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { ++ DBGLOG(INIT, INFO, "<3>tx_thread should stop now...\n"); ++ break; ++ } ++#endif ++ ++ if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->ulFlag)) { ++ /* Process Mailbox Messages */ ++ wlanProcessMboxMessage(prGlueInfo->prAdapter); ++ ++ /* Process CMD request */ ++ do { ++ if (prCmdQue->u4NumElem > 0) { ++ if (fgNeedHwAccess == FALSE) { ++ fgNeedHwAccess = TRUE; ++ ++ wlanAcquirePowerControl(prGlueInfo->prAdapter); ++ } ++ wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue); ++ } ++ } while (FALSE); ++ ++ /* Handle Packet Tx */ ++ { ++ while (QUEUE_IS_NOT_EMPTY(prTxQueue)) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ ASSERT(prQueueEntry); ++ if (NULL == prQueueEntry) ++ break; ++ ++ prSkb = (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); ++ ASSERT(prSkb); ++ if (NULL == prSkb) { ++ DBGLOG(INIT, ERROR, "prSkb == NULL!\n"); ++ continue; ++ } ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ UINT8 *pkt = prSkb->data; ++ UINT16 u2Identifier; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ DBGLOG(INIT, LOUD, " %d\n", u2Identifier); ++ } ++#endif ++ if (wlanEnqueueTxPacket(prGlueInfo->prAdapter, ++ (P_NATIVE_PACKET) prSkb) == WLAN_STATUS_RESOURCES) { ++ /* no available entry in rFreeMsduInfoList */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ break; ++ } ++ } ++ ++ if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) { ++ /* send packets to HIF here */ ++ wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess); ++ } ++ } ++ ++ } ++ ++ /* Process RX, In linux, we don't need to free sk_buff by ourself */ ++ ++ /* In linux, we don't need to free sk_buff by ourself */ ++ ++ /* In linux, we don't do reset */ ++ if (fgNeedHwAccess == TRUE) ++ wlanReleasePowerControl(prGlueInfo->prAdapter); ++ ++ /* handle cnmTimer time out */ ++ if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag)) ++ wlanTimerTimeoutCheck(prGlueInfo->prAdapter); ++#if CFG_DBG_GPIO_PINS ++ /* TX thread go to sleep */ ++ if (!prGlueInfo->ulFlag) ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH); ++#endif ++ } ++ ++#if 0 ++ if (fgNeedHwAccess == TRUE) ++ wlanReleasePowerControl(prGlueInfo->prAdapter); ++#endif ++ ++ /* exit while loop, tx thread is closed so we flush all pending packets */ ++ /* flush the pending TX packets */ ++ if (prGlueInfo->i4TxPendingFrameNum > 0) ++ kalFlushPendingTxPackets(prGlueInfo); ++ ++ /* flush pending security frames */ ++ if (prGlueInfo->i4TxPendingSecurityFrameNum > 0) ++ kalClearSecurityFrames(prGlueInfo); ++ ++ /* remove pending oid */ ++ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); ++ ++ /* In linux, we don't need to free sk_buff by ourself */ ++ ++ DBGLOG(INIT, INFO, "mtk_sdiod stops\n"); ++ complete(&prGlueInfo->rHaltComp); ++ ++ return 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to check if card is removed ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval TRUE: card is removed ++* FALSE: card is still attached ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return FALSE; ++ /* Linux MMC doesn't have removal notification yet */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This routine is used to send command to firmware for overriding netweork address ++ * ++ * \param pvGlueInfo Pointer of GLUE Data Structure ++ ++ * \retval TRUE ++ * FALSE ++ */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (prGlueInfo->fgIsMacAddrOverride == FALSE) { ++#if !defined(CONFIG_X86) ++#if !defined(CONFIG_MTK_TC1_FEATURE) ++ UINT_32 i; ++#endif ++ BOOLEAN fgIsReadError = FALSE; ++ ++#if !defined(CONFIG_MTK_TC1_FEATURE) ++ for (i = 0; i < MAC_ADDR_LEN; i += 2) { ++ if (kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, ++ (PUINT_16) (((PUINT_8) prMacAddr) + i)) == FALSE) { ++ fgIsReadError = TRUE; ++ break; ++ } ++ } ++#else ++ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prMacAddr); ++#endif ++ ++ if (fgIsReadError == TRUE) ++ return FALSE; ++ else ++ return TRUE; ++#else ++ /* x86 Linux doesn't need to override network address so far */ ++ return FALSE; ++#endif ++ } else { ++ COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride); ++ ++ return TRUE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to flush pending TX packets in glue layer ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prTxQue; ++ P_QUE_ENTRY_T prQueueEntry; ++ PVOID prPacket; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ prTxQue = &(prGlueInfo->rTxQueue); ++ ++ if (prGlueInfo->i4TxPendingFrameNum) { ++ while (TRUE) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ if (prQueueEntry == NULL) ++ break; ++ ++ prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); ++ ++ kalSendComplete(prGlueInfo, prPacket, WLAN_STATUS_NOT_ACCEPTED); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is get indicated media state ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->eParamMediaStateIndicated; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set indicated media state ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate) ++{ ++ ASSERT(prGlueInfo); ++ ++ prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear pending OID staying in command queue ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ ++ if (((P_CMD_INFO_T) prQueueEntry)->fgIsOid) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ break; ++ } ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ ++ if (prCmdInfo) { ++ if (prCmdInfo->pfCmdTimeoutHandler) ++ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); ++ else ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_ACCEPTED); ++ ++ prGlueInfo->u4OidCompleteFlag = 1; ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to insert command into prCmdQueue ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* prQueueEntry Pointer of queue entry to be inserted ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry) ++{ ++ P_QUE_T prCmdQue; ++ P_CMD_INFO_T prCmdInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prQueueEntry); ++ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ if (prCmdInfo->prPacket && prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); ++ prMsduInfo->eCmdType = prCmdInfo->eCmdType; ++ prMsduInfo->ucCID = prCmdInfo->ucCID; ++ prMsduInfo->u4InqueTime = kalGetTimeTick(); ++ } ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with ++* proper information ++* ++* @param pvGlueInfo Pointer of GLUE Data Structure ++* @param prAssocInfo Pointer of EVENT_ID_ASSOC_INFO Packet ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo) ++{ ++ /* to do */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to get firmware load address from registry ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rRegInfo.u4LoadAddress; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to get firmware start address from registry ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rRegInfo.u4StartAddress; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * * @brief Notify OS with SendComplete event of the specific packet. Linux should ++ * * free packets here. ++ * * ++ * * @param pvGlueInfo Pointer of GLUE Data Structure ++ * * @param pvPacket Pointer of Packet Handle ++ * * @param status Status Code for OS upper layer ++ * * ++ * * @return none ++ * */ ++/*----------------------------------------------------------------------------*/ ++ ++/* / Todo */ ++VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus) ++{ ++ ASSERT(pvPacket); ++ ++ dev_kfree_skb((struct sk_buff *)pvPacket); ++ if (prGlueInfo) ++ prGlueInfo->u8SkbFreed++; ++ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++} ++ ++UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return (UINT_32) (prGlueInfo->i4TxPendingFrameNum); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to retrieve the number of pending commands ++* (including MMPDU, 802.1X and command packets) ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ ++ ASSERT(prGlueInfo); ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ return prCmdQue->u4NumElem; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Timer Initialization Procedure ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* \param[in] prTimerHandler Pointer to timer handling function, whose only ++* argument is "prAdapter" ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++/* static struct timer_list tickfn; */ ++ ++VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler) ++{ ++ ++ ASSERT(prGlueInfo); ++ ++ init_timer(&(prGlueInfo->tickfn)); ++ prGlueInfo->tickfn.function = prTimerHandler; ++ prGlueInfo->tickfn.data = (ULONG) prGlueInfo; ++} ++ ++/* Todo */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the time to do the time out check. ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* \param[in] rInterval Time out interval from current time. ++* ++* \retval TRUE Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval) ++{ ++ ASSERT(prGlueInfo); ++ del_timer_sync(&(prGlueInfo->tickfn)); ++ ++ prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC; ++ add_timer(&(prGlueInfo->tickfn)); ++ ++ return TRUE; /* success */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to cancel ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* ++* \retval TRUE : Timer has been canceled ++* FALAE : Timer doens't exist ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); ++ ++ if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is a callback function for scanning done ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prGlueInfo); ++ ++ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); ++ /* report all queued beacon/probe response frames to upper layer */ ++ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); ++ cnmTimerStopTimer(prGlueInfo->prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ ++ /* check for system configuration for generating error message on scan list */ ++ wlanCheckSystemConfiguration(prGlueInfo->prAdapter); ++ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to generate a random number ++* ++* \param none ++* ++* \retval UINT_32 ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalRandomNumber(VOID) ++{ ++ UINT_32 number = 0; ++ ++ get_random_bytes(&number, 4); ++ ++ return number; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief command timeout call-back function ++ * ++ * \param[in] prGlueInfo Pointer to the GLUE data structure. ++ * ++ * \retval (none) ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID kalTimeoutHandler(ULONG arg) ++{ ++ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) arg; ++ ++ ASSERT(prGlueInfo); ++ ++ /* Notify tx thread for timeout event */ ++ set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++} ++ ++VOID kalSetEvent(P_GLUE_INFO_T pr) ++{ ++ set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag); ++ wake_up_interruptible(&pr->waitq); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if configuration file (NVRAM/Registry) exists ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo) ++{ ++#if !defined(CONFIG_X86) ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->fgNvramAvailable; ++#else ++ /* there is no configuration data for x86-linux */ ++ return FALSE; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Registry information ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* Pointer of REG_INFO_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return &(prGlueInfo->rRegInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve version information of corresponding configuration file ++* ++* \param[in] ++* prGlueInfo ++* ++* \param[out] ++* pu2Part1CfgOwnVersion ++* pu2Part1CfgPeerVersion ++* pu2Part2CfgOwnVersion ++* pu2Part2CfgPeerVersion ++* ++* \return ++* NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PUINT_16 pu2Part1CfgOwnVersion, ++ OUT PUINT_16 pu2Part1CfgPeerVersion, ++ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion) ++{ ++ ASSERT(prGlueInfo); ++ ++ ASSERT(pu2Part1CfgOwnVersion); ++ ASSERT(pu2Part1CfgPeerVersion); ++ ASSERT(pu2Part2CfgOwnVersion); ++ ASSERT(pu2Part2CfgPeerVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion), pu2Part1CfgOwnVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion), pu2Part1CfgPeerVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion), pu2Part2CfgOwnVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion), pu2Part2CfgPeerVersion); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if the WPS is active or not ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->fgWpsActive; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief update RSSI and LinkQuality to GLUE layer ++* ++* \param[in] ++* prGlueInfo ++* eNetTypeIdx ++* cRssi ++* cLinkQuality ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) ++{ ++ struct iw_statistics *pStats = (struct iw_statistics *)NULL; ++ ++ ASSERT(prGlueInfo); ++ ++ switch (eNetTypeIdx) { ++ case KAL_NETWORK_TYPE_AIS_INDEX: ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); ++ break; ++#if CFG_ENABLE_WIFI_DIRECT ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ case KAL_NETWORK_TYPE_P2P_INDEX: ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); ++ break; ++#endif ++#endif ++ default: ++ break; ++ ++ } ++ ++ if (pStats) { ++ pStats->qual.qual = cLinkQuality; ++ pStats->qual.noise = 0; ++ pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; ++ pStats->qual.level = 0x100 + cRssi; ++ pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Pre-allocate I/O buffer ++* ++* \param[in] ++* none ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitIOBuffer(VOID) ++{ ++ UINT_32 u4Size; ++ ++ if (CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE) ++ u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); ++ else ++ u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ pvDmaBuffer = dma_alloc_coherent(NULL, CFG_RX_MAX_PKT_SIZE, &pvDmaPhyBuf, GFP_KERNEL); ++ if (pvDmaBuffer == NULL) ++ return FALSE; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ pvIoBuffer = kmalloc(u4Size, GFP_KERNEL); ++/* pvIoBuffer = dma_alloc_coherent(NULL, u4Size, &pvIoPhyBuf, GFP_KERNEL); */ ++ if (pvIoBuffer) { ++ pvIoBufferSize = u4Size; ++ pvIoBufferUsage = 0; ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Free pre-allocated I/O buffer ++* ++* \param[in] ++* none ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUninitIOBuffer(VOID) ++{ ++ kfree(pvIoBuffer); ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ dma_free_coherent(NULL, CFG_RX_MAX_PKT_SIZE, pvDmaBuffer, pvDmaPhyBuf); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ /* dma_free_coherent(NULL, pvIoBufferSize, pvIoBuffer, pvIoPhyBuf); */ ++ ++ pvIoBuffer = (PVOID) NULL; ++ pvIoBufferSize = 0; ++ pvIoBufferUsage = 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dispatch pre-allocated I/O buffer ++* ++* \param[in] ++* u4AllocSize ++* ++* \return ++* PVOID for pointer of pre-allocated I/O buffer ++*/ ++/*----------------------------------------------------------------------------*/ ++PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize) ++{ ++ PVOID ret = (PVOID) NULL; ++ ++ if (pvIoBuffer) { ++ if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) { ++ ret = (PVOID) &(((PUINT_8) (pvIoBuffer))[pvIoBufferUsage]); ++ pvIoBufferUsage += u4AllocSize; ++ } ++ } else { ++ /* fault tolerance */ ++ ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE); ++ } ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Release all dispatched I/O buffer ++* ++* \param[in] ++* none ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size) ++{ ++ if (pvIoBuffer) { ++ pvIoBufferUsage -= u4Size; ++ } else { ++ /* fault tolerance */ ++ kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) ++{ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, ++ pucNumOfChannel, paucChannelList); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo) ++{ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) && ++ p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo)) ++ return TRUE; ++#endif ++ ++ return FALSE; ++} ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function gets the physical address for Pre-allocate I/O buffer. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[out] pu4Flags Pointer of a variable for saving IRQ flags ++* ++* \return physical addr ++*/ ++/*----------------------------------------------------------------------------*/ ++ULONG kalIOPhyAddrGet(IN ULONG VirtAddr) ++{ ++ ULONG PhyAddr; ++ ++ if ((VirtAddr >= (ULONG) pvIoBuffer) && (VirtAddr <= ((ULONG) (pvIoBuffer) + pvIoBufferSize))) { ++ PhyAddr = (ULONG) pvIoPhyBuf; ++ PhyAddr += (VirtAddr - (ULONG) (pvIoBuffer)); ++ return PhyAddr; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function gets the physical address for Pre-allocate I/O buffer. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[out] pu4Flags Pointer of a variable for saving IRQ flags ++* ++* \return physical addr ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr) ++{ ++ *VirtAddr = pvDmaBuffer; ++ *PhyAddr = pvDmaPhyBuf; ++} ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++#if CFG_SUPPORT_802_11W ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if the MFP is active or not ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rWpaInfo.u4Mfp; ++} ++#endif ++ ++struct file *kalFileOpen(const char *path, int flags, int rights) ++{ ++ struct file *filp = NULL; ++ mm_segment_t oldfs; ++ int err = 0; ++ ++ oldfs = get_fs(); ++ set_fs(get_ds()); ++ filp = filp_open(path, flags, rights); ++ set_fs(oldfs); ++ if (IS_ERR(filp)) { ++ err = PTR_ERR(filp); ++ return NULL; ++ } ++ return filp; ++} ++ ++VOID kalFileClose(struct file *file) ++{ ++ filp_close(file, NULL); ++} ++ ++UINT_32 kalFileRead(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) ++{ ++ mm_segment_t oldfs; ++ INT_32 ret; ++ ++ oldfs = get_fs(); ++ set_fs(get_ds()); ++ ++ ret = vfs_read(file, data, size, &offset); ++ ++ set_fs(oldfs); ++ return ret; ++} ++ ++UINT_32 kalFileWrite(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) ++{ ++ mm_segment_t oldfs; ++ INT_32 ret; ++ ++ oldfs = get_fs(); ++ set_fs(get_ds()); ++ ++ ret = vfs_write(file, data, size, &offset); ++ ++ set_fs(oldfs); ++ return ret; ++} ++ ++UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size) ++{ ++ struct file *file = NULL; ++ UINT_32 ret = -1; ++ UINT_32 u4Flags = 0; ++ ++ if (fgDoAppend) ++ u4Flags = O_APPEND; ++ ++ file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU); ++ if (file) { ++ ret = kalFileWrite(file, 0, pucData, u4Size); ++ kalFileClose(file); ++ } ++ ++ return ret; ++} ++ ++INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize) ++{ ++ struct file *file = NULL; ++ INT_32 ret = -1; ++ UINT_32 u4ReadSize = 0; ++ ++ DBGLOG(INIT, LOUD, "kalReadToFile() path %s\n", pucPath); ++ ++ file = kalFileOpen(pucPath, O_RDONLY, 0); ++ ++ if ((file != NULL) && !IS_ERR(file)) { ++ u4ReadSize = kalFileRead(file, 0, pucData, u4Size); ++ kalFileClose(file); ++ if (pu4ReadSize) ++ *pu4ReadSize = u4ReadSize; ++ ret = 0; ++ } ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate BSS-INFO to NL80211 as scanning result ++* ++* \param[in] ++* prGlueInfo ++* pucBeaconProbeResp ++* u4FrameLen ++* ++* ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucBeaconProbeResp, ++ IN UINT_32 u4FrameLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength) ++{ ++ struct wiphy *wiphy; ++ struct ieee80211_channel *prChannel = NULL; ++ ++ ASSERT(prGlueInfo); ++ wiphy = priv_to_wiphy(prGlueInfo); ++ ++ /* search through channel entries */ ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); ++ } ++ ++ if (prChannel != NULL && (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)) { ++ struct cfg80211_bss *bss; ++#if CFG_SUPPORT_TSF_USING_BOOTTIME ++ struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt *)pucBeaconProbeResp; ++ ++ prMgmtFrame->u.beacon.timestamp = kalGetBootTime(); ++#endif ++ ScanCnt++; ++ ++ /* indicate to NL80211 subsystem */ ++ bss = cfg80211_inform_bss_frame(wiphy, ++ prChannel, ++ (struct ieee80211_mgmt *)pucBeaconProbeResp, ++ u4FrameLen, i4SignalStrength * 100, GFP_KERNEL); ++ ++ if (!bss) { ++ ScanDoneFailCnt++; ++ DBGLOG(SCN, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", ++ ucChannelNum, i4SignalStrength); ++ } else { ++ cfg80211_put_bss(wiphy, bss); ++ DBGLOG(SCN, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", ++ ucChannelNum, i4SignalStrength); ++ } ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate channel ready ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs) ++{ ++ struct ieee80211_channel *prChannel = NULL; ++ enum nl80211_channel_type rChannelType; ++ ++ /* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); */ ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); ++ } ++ ++ switch (eSco) { ++ case CHNL_EXT_SCN: ++ rChannelType = NL80211_CHAN_NO_HT; ++ break; ++ ++ case CHNL_EXT_SCA: ++ rChannelType = NL80211_CHAN_HT40MINUS; ++ break; ++ ++ case CHNL_EXT_SCB: ++ rChannelType = NL80211_CHAN_HT40PLUS; ++ break; ++ ++ case CHNL_EXT_RES: ++ default: ++ rChannelType = NL80211_CHAN_HT20; ++ break; ++ } ++ ++ cfg80211_ready_on_channel(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, u4DurationMs, ++ GFP_KERNEL); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate channel expiration ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum) ++{ ++ struct ieee80211_channel *prChannel = NULL; ++ enum nl80211_channel_type rChannelType; ++ ++ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); ++ } ++ ++ switch (eSco) { ++ case CHNL_EXT_SCN: ++ rChannelType = NL80211_CHAN_NO_HT; ++ break; ++ ++ case CHNL_EXT_SCA: ++ rChannelType = NL80211_CHAN_HT40MINUS; ++ break; ++ ++ case CHNL_EXT_SCB: ++ rChannelType = NL80211_CHAN_HT40PLUS; ++ break; ++ ++ case CHNL_EXT_RES: ++ default: ++ rChannelType = NL80211_CHAN_HT20; ++ break; ++ } ++ ++ cfg80211_remain_on_channel_expired(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, ++ GFP_KERNEL); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate Mgmt tx status ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) ++{ ++ ++ do { ++ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { ++ DBGLOG(AIS, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", ++ prGlueInfo, pucFrameBuf, u4FrameLen); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ cfg80211_mgmt_tx_status(prGlueInfo->prDevHandler->ieee80211_ptr, ++ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); ++ } while (FALSE); ++ ++} /* kalIndicateMgmtTxStatus */ ++ ++VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) ++{ ++#define DBG_MGMT_FRAME_INDICATION 1 ++ INT_32 i4Freq = 0; ++ UINT_8 ucChnlNum = 0; ++#if DBG_MGMT_FRAME_INDICATION ++ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; ++#endif ++ ++ do { ++ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; ++ ++#if DBG_MGMT_FRAME_INDICATION ++ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; ++ ++ switch (prWlanHeader->u2FrameCtrl) { ++ case MAC_FRAME_PROBE_REQ: ++ DBGLOG(AIS, TRACE, "RX Probe Req at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_PROBE_RSP: ++ DBGLOG(AIS, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_ACTION: ++ DBGLOG(AIS, TRACE, "RX Action frame at channel %d ", ucChnlNum); ++ break; ++ default: ++ DBGLOG(AIS, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); ++ break; ++ } ++ ++#endif ++ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; ++ ++ cfg80211_rx_mgmt(prGlueInfo->prDevHandler->ieee80211_ptr, /* struct net_device * dev, */ ++ i4Freq, ++ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), ++ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_KERNEL); ++ } while (FALSE); ++ ++} /* kalIndicateRxMgmtFrame */ ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen) ++{ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ struct sk_buff *skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy(prGlueInfo), ++ dataLen, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(AIS, ERROR, "kalIndicateAgpsNotify: alloc skb failed\n"); ++ return FALSE; ++ } ++ ++ /* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */ ++ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), &cmd) < 0)) ++ goto nla_put_failure; ++ if (dataLen > 0 && data && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, data) < 0)) ++ goto nla_put_failure; ++ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, sizeof(UINT_32), &prGlueInfo->prDevHandler->ifindex) < 0)) ++ goto nla_put_failure; ++ /* currently, the ifname maybe wlan0, p2p0, so the maximum name length will be 5 bytes */ ++ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, prGlueInfo->prDevHandler->name) < 0)) ++ goto nla_put_failure; ++ cfg80211_testmode_event(skb, GFP_KERNEL); ++ return TRUE; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return FALSE; ++} ++#endif ++ ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++#define PROC_MET_PROF_CTRL "met_ctrl" ++#define PROC_MET_PROF_PORT "met_port" ++ ++struct proc_dir_entry *pMetProcDir; ++void *pMetGlobalData = NULL; ++static unsigned long __read_mostly tracing_mark_write_addr; ++ ++static inline void __mt_update_tracing_mark_write_addr(void) ++{ ++ if (unlikely(0 == tracing_mark_write_addr)) ++ tracing_mark_write_addr = kallsyms_lookup_name("tracing_mark_write"); ++} ++ ++VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb) ++{ ++ UINT_8 ucIpVersion; ++ UINT_16 u2UdpSrcPort; ++ UINT_16 u2RtpSn; ++ PUINT_8 pucEthHdr = prSkb->data; ++ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; ++ ++ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ ++ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ ++ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ ++ /* printk("MET_PROF: MET enable=%d(HardXmit)\n", prGlueInfo->u8MetProfEnable); */ ++ if (prGlueInfo->u8MetProfEnable == 1) { ++ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; ++ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { ++ /* IP */ ++ pucIpHdr = pucEthHdr + ETH_HLEN; ++ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { ++ /* UDP */ ++ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; ++ /* check UDP port number */ ++ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { ++ /* RTP */ ++ pucRtpHdr = pucUdpHdr + 8; ++ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; ++ /* trace_printk("S|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); ++ //frm_sequence); */ ++#ifdef CONFIG_TRACING ++ __mt_update_tracing_mark_write_addr(); ++ if (tracing_mark_write_addr != 0) { ++ event_trace_printk(tracing_mark_write_addr, "S|%d|%s|%d\n", ++ current->tgid, "WIFI-CHIP", u2RtpSn); ++ } ++#endif ++ } ++ } ++ } ++ } ++} ++ ++VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_8 ucIpVersion; ++ UINT_16 u2UdpSrcPort; ++ UINT_16 u2RtpSn; ++ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ PUINT_8 pucEthHdr = prSkb->data; ++ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ ++ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ ++ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ ++ /* printk("MET_PROF: MET enable=%d(TxMsdu)\n", prGlueInfo->u8MetProfEnable); */ ++ if (prGlueInfo->u8MetProfEnable == 1) { ++ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; ++ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { ++ /* IP */ ++ pucIpHdr = pucEthHdr + ETH_HLEN; ++ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { ++ /* UDP */ ++ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; ++ /* check UDP port number */ ++ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { ++ /* RTP */ ++ pucRtpHdr = pucUdpHdr + 8; ++ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; ++ /* trace_printk("F|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); ++ //frm_sequence); */ ++#ifdef CONFIG_TRACING ++ __mt_update_tracing_mark_write_addr(); ++ if (tracing_mark_write_addr != 0) { ++ event_trace_printk(tracing_mark_write_addr, "F|%d|%s|%d\n", ++ current->tgid, "WIFI-CHIP", u2RtpSn); ++ } ++#endif ++ } ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t kalMetCtrlWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) ++{ ++ char acBuf[128 + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ int u8MetProfEnable; ++ ++ IN P_GLUE_INFO_T prGlueInfo; ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ if (copy_from_user(acBuf, buffer, u4CopySize)) ++ return -1; ++ acBuf[u4CopySize] = '\0'; ++ ++ if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1) ++ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC Enable=%d\n", u8MetProfEnable); ++ if (pMetGlobalData != NULL) { ++ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; ++ prGlueInfo->u8MetProfEnable = (UINT_8) u8MetProfEnable; ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t kalMetPortWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) ++{ ++ char acBuf[128 + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ int u16MetUdpPort; ++ ++ IN P_GLUE_INFO_T prGlueInfo; ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ if (copy_from_user(acBuf, buffer, u4CopySize)) ++ return -1; ++ acBuf[u4CopySize] = '\0'; ++ ++ if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1) ++ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC UDP_PORT=%d\n", u16MetUdpPort); ++ if (pMetGlobalData != NULL) { ++ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; ++ prGlueInfo->u16MetUdpPort = (UINT_16) u16MetUdpPort; ++ } ++ return count; ++} ++ ++const struct file_operations rMetProcCtrlFops = { ++.write = kalMetCtrlWriteProcfs ++}; ++ ++const struct file_operations rMetProcPortFops = { ++.write = kalMetPortWriteProcfs ++}; ++ ++int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ /* struct proc_dir_entry *pMetProcDir; */ ++ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { ++ DBGLOG(INIT, INFO, "init proc fs fail: proc_net == NULL\n"); ++ return -ENOENT; ++ } ++ /* ++ * Directory: Root (/proc/net/wlan0) ++ */ ++ pMetProcDir = proc_mkdir("wlan0", init_net.proc_net); ++ if (pMetProcDir == NULL) ++ return -ENOENT; ++ /* ++ /proc/net/wlan0 ++ |-- met_ctrl (PROC_MET_PROF_CTRL) ++ |-- met_port (PROC_MET_PROF_PORT) ++ */ ++ /* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); */ ++ proc_create(PROC_MET_PROF_CTRL, 0, pMetProcDir, &rMetProcCtrlFops); ++ proc_create(PROC_MET_PROF_PORT, 0, pMetProcDir, &rMetProcPortFops); ++ ++ pMetGlobalData = (void *)prGlueInfo; ++ ++ return 0; ++} ++ ++int kalMetRemoveProcfs(void) ++{ ++ ++ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { ++ DBGLOG(INIT, WARN, "remove proc fs fail: proc_net == NULL\n"); ++ return -ENOENT; ++ } ++ remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir); ++ remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir); ++ /* remove root directory (proc/net/wlan0) */ ++ remove_proc_entry("wlan0", init_net.proc_net); ++ /* clear MetGlobalData */ ++ pMetGlobalData = NULL; ++ ++ return 0; ++} ++#endif ++UINT_64 kalGetBootTime(void) ++{ ++ struct timespec ts; ++ UINT_64 bootTime = 0; ++ ++ get_monotonic_boottime(&ts); ++ /* we assign ts.tv_sec to bootTime first, then multiply USEC_PER_SEC ++ this will prevent multiply result turn to a negative value on 32bit system */ ++ bootTime = ts.tv_sec; ++ bootTime *= USEC_PER_SEC; ++ bootTime += ts.tv_nsec / NSEC_PER_USEC; ++ return bootTime; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate scheduled scan results are avilable ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo),0); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate scheduled scan has been stopped ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* 1. reset first for newly incoming request */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prSchedScanRequest != NULL) ++ prGlueInfo->prSchedScanRequest = NULL; ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ DBGLOG(SCN, INFO, "cfg80211_sched_scan_stopped send event\n"); ++ ++ /* 2. indication to cfg80211 */ ++ /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K thread to send event instead of Tx thread ++ due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds and send event in the same time */ ++ DBGLOG(SCN, TRACE, "start work queue to send event\n"); ++ schedule_delayed_work(&sched_workq, 0); ++ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); ++ ++} ++ ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++/* if SPM is not implement this function, we will use this default one */ ++wake_reason_t __weak slp_get_wake_reason(VOID) ++{ ++ return WR_NONE; ++} ++/* if SPM is not implement this function, we will use this default one */ ++UINT_32 __weak spm_get_last_wakeup_src(VOID) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To check if device if wake up by wlan ++* ++* \param[in] ++* prAdapter ++* ++* \return ++* TRUE: wake up by wlan; otherwise, FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter) ++{ ++ /* SUSPEND_FLAG_FOR_WAKEUP_REASON is set means system has suspended, but may be failed ++ duo to some driver suspend failed. so we need help of function slp_get_wake_reason */ ++ if (test_and_clear_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prAdapter->ulSuspendFlag) == 0) ++ return FALSE; ++ /* if slp_get_wake_reason or spm_get_last_wakeup_src is NULL, it means SPM module didn't implement ++ it. then we should return FALSE always. otherwise, if slp_get_wake_reason returns WR_WAKE_SRC, ++ then it means the host is suspend successfully. */ ++ if (slp_get_wake_reason() != WR_WAKE_SRC) ++ return FALSE; ++ /* spm_get_last_wakeup_src will returns the last wakeup source, ++ WAKE_SRC_CONN2AP is connsys */ ++ return !!(spm_get_last_wakeup_src() & WAKE_SRC_CONN2AP); ++} ++#endif ++ ++INT_32 kalHaltLock(UINT_32 waitMs) ++{ ++ INT_32 i4Ret = 0; ++ ++ if (waitMs) { ++ i4Ret = down_timeout(&rHaltCtrl.lock, MSEC_TO_JIFFIES(waitMs)); ++ if (!i4Ret) ++ goto success; ++ if (i4Ret != -ETIME) ++ return i4Ret; ++ if (rHaltCtrl.fgHeldByKalIoctl) { ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ wlanExportGlueInfo(&prGlueInfo); ++ ++ DBGLOG(INIT, ERROR, ++ "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", ++ kalGetTimeTick() - rHaltCtrl.u4HoldStart); ++ if (prGlueInfo) ++ show_stack(prGlueInfo->main_thread, NULL); ++ } else { ++ DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", ++ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, ++ kalGetTimeTick() - rHaltCtrl.u4HoldStart); ++ show_stack(rHaltCtrl.owner, NULL); ++ } ++ return i4Ret; ++ } ++ down(&rHaltCtrl.lock); ++success: ++ rHaltCtrl.owner = current; ++ rHaltCtrl.u4HoldStart = kalGetTimeTick(); ++ return 0; ++} ++ ++INT_32 kalHaltTryLock(VOID) ++{ ++ INT_32 i4Ret = 0; ++ ++ i4Ret = down_trylock(&rHaltCtrl.lock); ++ if (i4Ret) ++ return i4Ret; ++ rHaltCtrl.owner = current; ++ rHaltCtrl.u4HoldStart = kalGetTimeTick(); ++ return 0; ++} ++ ++VOID kalHaltUnlock(VOID) ++{ ++ if (kalGetTimeTick() - rHaltCtrl.u4HoldStart > WLAN_OID_TIMEOUT_THRESHOLD * 2 && ++ rHaltCtrl.owner) ++ DBGLOG(INIT, ERROR, "process %s pid %d hold halt lock longer than 4s!\n", ++ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid); ++ rHaltCtrl.owner = NULL; ++ up(&rHaltCtrl.lock); ++} ++ ++VOID kalSetHalted(BOOLEAN fgHalt) ++{ ++ rHaltCtrl.fgHalt = fgHalt; ++} ++ ++BOOLEAN kalIsHalted(VOID) ++{ ++ return rHaltCtrl.fgHalt; ++} ++VOID kalPerMonDump(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, WARN, "ulPerfMonFlag:0x%lx\n", prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, WARN, "ulLastTxBytes:%ld\n", prPerMonitor->ulLastTxBytes); ++ DBGLOG(SW4, WARN, "ulLastRxBytes:%ld\n", prPerMonitor->ulLastRxBytes); ++ DBGLOG(SW4, WARN, "ulP2PLastTxBytes:%ld\n", prPerMonitor->ulP2PLastTxBytes); ++ DBGLOG(SW4, WARN, "ulP2PLastRxBytes:%ld\n", prPerMonitor->ulP2PLastRxBytes); ++ DBGLOG(SW4, WARN, "ulThroughput:%ld\n", prPerMonitor->ulThroughput); ++ DBGLOG(SW4, WARN, "u4UpdatePeriod:%d\n", prPerMonitor->u4UpdatePeriod); ++ DBGLOG(SW4, WARN, "u4TarPerfLevel:%d\n", prPerMonitor->u4TarPerfLevel); ++ DBGLOG(SW4, WARN, "u4CurrPerfLevel:%d\n", prPerMonitor->u4CurrPerfLevel); ++ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.tx_bytes); ++ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.rx_bytes); ++ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes); ++ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes); ++} ++ ++inline INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, INFO, "enter %s\n", __func__); ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) ++ DBGLOG(SW4, WARN, "abnormal, perf monitory already running\n"); ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ prPerMonitor->u4UpdatePeriod = 1000; ++ cnmTimerInitTimer(prGlueInfo->prAdapter, ++ &prPerMonitor->rPerfMonTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) kalPerMonHandler, (ULONG) NULL); ++ DBGLOG(SW4, INFO, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ ++ DBGLOG(SW4, INFO, "enter %s\n", __func__); ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "need to stop before disable\n"); ++ kalPerMonStop(prGlueInfo); ++ } ++ KAL_SET_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, TRACE, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ ++ DBGLOG(SW4, INFO, "enter %s\n", __func__); ++ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, TRACE, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, TRACE, "enter %s\n", __func__); ++ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) ++ return 0; ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "perf monitor already running\n"); ++ return 0; ++ } ++ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); ++ KAL_SET_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ KAL_CLR_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, INFO, "perf monitor started\n"); ++ return 0; ++} ++ ++inline INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, TRACE, "enter %s\n", __func__); ++ ++ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "perf monitory disabled\n"); ++ return 0; ++ } ++ ++ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "perf monitory already stopped\n"); ++ return 0; ++ } ++ ++ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ cnmTimerStopTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer); ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ prPerMonitor->ulLastRxBytes = 0; ++ prPerMonitor->ulLastTxBytes = 0; ++ prPerMonitor->ulP2PLastRxBytes = 0; ++ prPerMonitor->ulP2PLastTxBytes = 0; ++ prPerMonitor->ulThroughput = 0; ++ prPerMonitor->u4CurrPerfLevel = 0; ++ prPerMonitor->u4TarPerfLevel = 0; ++ /*Cancel CPU performance mode request*/ ++ kalBoostCpu(0); ++ } ++ DBGLOG(SW4, TRACE, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ kalPerMonDisable(prGlueInfo); ++ return 0; ++} ++ ++VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ /*Calculate current throughput*/ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ LONG latestTxBytes, latestRxBytes, txDiffBytes, rxDiffBytes; ++ LONG p2pLatestTxBytes, p2pLatestRxBytes, p2pTxDiffBytes, p2pRxDiffBytes; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) || (!prAdapter->fgIsP2PRegistered)) ++ return; ++ ++ prPerMonitor = &prAdapter->rPerMonitor; ++ DBGLOG(SW4, TRACE, "enter kalPerMonHandler\n"); ++ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, WARN, "perf monitory disabled, omit timeout event\n"); ++ return; ++ } ++ ++ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, WARN, "perf monitory stopped, omit timeout event\n"); ++ return; ++ } ++ latestTxBytes = prGlueInfo->rNetDevStats.tx_bytes; ++ latestRxBytes = prGlueInfo->rNetDevStats.rx_bytes; ++ p2pLatestTxBytes = prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes; ++ p2pLatestRxBytes = prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes; ++ if (0 == prPerMonitor->ulLastRxBytes && ++ 0 == prPerMonitor->ulLastTxBytes && ++ 0 == prPerMonitor->ulP2PLastRxBytes && ++ 0 == prPerMonitor->ulP2PLastTxBytes) { ++ prPerMonitor->ulThroughput = 0; ++ } else { ++ txDiffBytes = latestTxBytes - prPerMonitor->ulLastTxBytes; ++ rxDiffBytes = latestRxBytes - prPerMonitor->ulLastRxBytes; ++ if (0 > txDiffBytes) ++ txDiffBytes = -(txDiffBytes); ++ if (0 > rxDiffBytes) ++ rxDiffBytes = -(rxDiffBytes); ++ ++ p2pTxDiffBytes = p2pLatestTxBytes - prPerMonitor->ulP2PLastTxBytes; ++ p2pRxDiffBytes = p2pLatestRxBytes - prPerMonitor->ulP2PLastRxBytes; ++ if (0 > p2pTxDiffBytes) ++ p2pTxDiffBytes = -(p2pTxDiffBytes); ++ if (0 > p2pRxDiffBytes) ++ p2pRxDiffBytes = -(p2pRxDiffBytes); ++ ++ prPerMonitor->ulThroughput = txDiffBytes + rxDiffBytes + p2pTxDiffBytes + p2pRxDiffBytes; ++ prPerMonitor->ulThroughput *= 1000; ++ prPerMonitor->ulThroughput /= prPerMonitor->u4UpdatePeriod; ++ prPerMonitor->ulThroughput <<= 3; ++ } ++ /*start the timer again to make sure we can cancel performance mode request in the end*/ ++ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); ++ ++ prPerMonitor->ulLastTxBytes = latestTxBytes; ++ prPerMonitor->ulLastRxBytes = latestRxBytes; ++ prPerMonitor->ulP2PLastTxBytes = p2pLatestTxBytes; ++ prPerMonitor->ulP2PLastRxBytes = p2pLatestRxBytes; ++ ++ if (prPerMonitor->ulThroughput < THROUGHPUT_L1_THRESHOLD) ++ prPerMonitor->u4TarPerfLevel = 0; ++ else if (prPerMonitor->ulThroughput < THROUGHPUT_L2_THRESHOLD) ++ prPerMonitor->u4TarPerfLevel = 1; ++ else if (prPerMonitor->ulThroughput < THROUGHPUT_L3_THRESHOLD) ++ prPerMonitor->u4TarPerfLevel = 2; ++ else ++ prPerMonitor->u4TarPerfLevel = 3; ++ if (prPerMonitor->u4TarPerfLevel != prPerMonitor->u4CurrPerfLevel) { ++ if (0 == prPerMonitor->u4TarPerfLevel) { ++ /*cancel CPU performance mode request*/ ++ kalPerMonStop(prGlueInfo); ++ } else{ ++ DBGLOG(SW4, TRACE, "throughput:%ld bps\n", prPerMonitor->ulThroughput); ++ /*adjust CPU core number to prPerMonitor->u4TarPerfLevel+1*/ ++ kalBoostCpu(prPerMonitor->u4TarPerfLevel+1); ++ /*start the timer again to make sure we can cancel performance mode request in the end*/ ++ cnmTimerStartTimer(prGlueInfo->prAdapter, ++ &prPerMonitor->rPerfMonTimer, ++ prPerMonitor->u4UpdatePeriod); ++ } ++ } ++ prPerMonitor->u4CurrPerfLevel = prPerMonitor->u4TarPerfLevel; ++ DBGLOG(SW4, TRACE, "exit kalPerMonHandler\n"); ++} ++ ++INT32 __weak kalBoostCpu(UINT_32 core_num) ++{ ++ DBGLOG(SW4, WARN, "enter weak kalBoostCpu, core_num:%d\n", core_num); ++ return 0; ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c +new file mode 100644 +index 000000000000..2d9631538942 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c +@@ -0,0 +1,4671 @@ ++/* ++** Id: @(#) gl_p2p.c@@ ++*/ ++ ++/*! \file gl_p2p.c ++ \brief Main routines of Linux driver interface for Wi-Fi Direct ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_p2p.c ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 17 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 16 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** FPB from ALPS.JB to phase 2 release. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 01 09 2012 terry.wu ++ * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork ++ * cfg80211 integration for p2p network. ++ * ++ * 12 19 2011 terry.wu ++ * [WCXRP00001142] [Wi-Fi] [P2P Driver] XOR local admin bit to generate p2p net device MAC ++ * XOR local administrated bit to generate net device MAC of p2p network. ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Fix possible KE when unload p2p. ++ * ++ * 11 24 2011 yuche.tsai ++ * NULL ++ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Update RSSI link quality of P2P Network query method. (Bug fix) ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 16 2011 yuche.tsai ++ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. ++ * Avoid using work thread in set p2p multicast address callback. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix default device name issue. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service ++ * discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 11 07 2011 yuche.tsai ++ * NULL ++ * [ALPS 00087243] KE in worker thread. ++ * The multicast address list is scheduled in worker thread. ++ * Before the worker thread is excuted, if P2P is unloaded, a KE may occur. ++ * ++ * 10 26 2011 terry.wu ++ * [WCXRP00001066] [MT6620 Wi-Fi] [P2P Driver] Fix P2P Oid Issue ++ * Fix some P2P OID functions didn't raise its flag "fgIsP2pOid" issue. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * . ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 26 2011 yuche.tsai ++ * NULL ++ * Fix bug of parsing secondary device list type issue. ++ * ++ * 08 24 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Abort. ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix multicast address list issue of P2P. ++ * ++ * 08 22 2011 chinglan.wang ++ * NULL ++ * Fix invitation indication bug.. ++ * ++ * 08 16 2011 cp.wu ++ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence ++ * auto channel decision for 2.4GHz hot spot mode ++ * ++ * 08 16 2011 chinglan.wang ++ * NULL ++ * Add the group id information in the invitation indication. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 08 05 2011 yuche.tsai ++ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. ++ * Add Password ID check for quick connection. ++ * Also modify some connection policy. ++ * ++ * 07 18 2011 chinglan.wang ++ * NULL ++ * Add IOC_P2P_GO_WSC_IE (p2p capability). ++ * ++ * 06 14 2011 yuche.tsai ++ * NULL ++ * Add compile flag to disable persistent group support. ++ * ++ * 05 04 2011 chinglan.wang ++ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver ++ * . ++ * ++ * 05 02 2011 yuche.tsai ++ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. ++ * Clear formation flag after formation timeout. ++ * ++ * 04 22 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * . ++ * ++ * 04 21 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * 1. Revise P2P power mode setting. ++ * 2. Revise fast-PS for concurrent ++ * ++ * 04 19 2011 wh.su ++ * NULL ++ * Adding length check before doing WPA RSN IE parsing for scan results indicate. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Connection flow refine for Sigma test. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 04 07 2011 terry.wu ++ * [WCXRP00000619] [MT6620 Wi-Fi][Driver] fix kernel panic may occur when removing wlan ++ * Fix kernel panic may occur when removing wlan driver. ++ * ++ * 03 31 2011 wh.su ++ * [WCXRP00000614] [MT6620 Wi-Fi][Driver] P2P: Update beacon content while setting WSC IE ++ * Update the wsc ie to beacon content. ++ * ++ * 03 25 2011 wh.su ++ * NULL ++ * add the sample code for set power mode and get power mode. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Improve some error handleing. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 22 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Modify formation policy. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Modify formation policy setting. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow ++ * Modify connection flow after Group Formation Complete, or device connect to a GO. ++ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. ++ * ++ * 03 15 2011 wh.su ++ * [WCXRP00000563] [MT6620 Wi-Fi] [P2P] Set local config method while set password Id ready ++ * set lccal config method method while set password Id ready. ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix some configure method issue. ++ * ++ * 03 15 2011 jeffrey.chang ++ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM ++ * refine queue_select function ++ * ++ * 03 13 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * add code for avoid compiling warning. ++ * ++ * 03 10 2011 yuche.tsai ++ * NULL ++ * Add P2P API. ++ * ++ * 03 10 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Remove unnecessary assert and message. ++ * ++ * 03 08 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * support the power save related p2p setting. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify P2P's netdevice functions to support multiple H/W queues ++ * ++ * 03 03 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * for get request, the buffer length to be copied is header + payload. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add code to let the beacon and probe response for Auto GO WSC . ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * add a missed break. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation ++ * Update channel issue when doing GO formation.. ++ * ++ * 02 25 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * add the Operation channel setting. ++ * ++ * 02 23 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * fixed the set int ioctl set index and value map to driver issue. ++ * ++ * 02 22 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * adding the ioctl set int from supplicant, and can used to set the p2p parameters ++ * ++ * 02 21 2011 terry.wu ++ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P ++ * Clean P2P scan list while removing P2P. ++ * ++ * 02 18 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * fixed the ioctl setting that index not map to spec defined config method. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * append the WSC IE config method attribute at provision discovery request. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * modify the structure pointer for set WSC IE. ++ * ++ * 02 16 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * fixed the probe request send out without WSC IE issue (at P2P). ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * fix typo ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add Support for MLME deauthentication for Hot-Spot. ++ * ++ * 01 25 2011 terry.wu ++ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter ++ * Add a new module parameter to indicate current runnig mode, P2P or AP. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. ++ * 2. Call cnmP2pIsPermit() before active P2P network. ++ * 3. Add channel selection support for AP mode. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 12 15 2010 cp.wu ++ * NULL ++ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in ++ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 17 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] Set the Tx ++ * lowest rate at wlan table for normal operation ++ * fixed some ASSERT check. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * add a kal function for set cipher. ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * fixed compiling error while enable p2p. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 10 2010 george.huang ++ * NULL ++ * update iwpriv LP related ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at win XP. ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 20 2010 cp.wu ++ * NULL ++ * correct typo. ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Invert Connection request provision status parameter. ++ * ++ * 08 19 2010 cp.wu ++ * NULL ++ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. ++ * ++ * 08 18 2010 cp.wu ++ * NULL ++ * modify pwp ioctls attribution by removing FIXED_SIZE. ++ * ++ * 08 18 2010 jeffrey.chang ++ * NULL ++ * support multi-function sdio ++ * ++ * 08 17 2010 cp.wu ++ * NULL ++ * correct p2p net device registration with NULL pointer access issue. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add subroutines for P2P to set multicast list. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * add wext handlers to link P2P set PS profile/ network address function (TBD) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * revised implementation of Wi-Fi Direct io controls. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * follow-up with ioctl interface update for Wi-Fi Direct application ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * add basic support for ioctl of getting scan result. (only address and SSID are reporterd though) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * p2p interface revised to be sync. with HAL ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl to configure scan mode for p2p connection ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement private io controls for Wi-Fi Direct ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement get scan result. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement wireless extension ioctls in iw_handler form. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++ ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "gl_p2p_os.h" ++#include "gl_p2p_ioctl.h" ++#include "gl_vendor.h" ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define ARGV_MAX_NUM (4) ++ ++/*For CFG80211 - wiphy parameters*/ ++#define MAX_SCAN_LIST_NUM (1) ++#define MAX_SCAN_IE_LEN (512) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++static struct cfg80211_ops mtk_p2p_ops = { ++ .change_virtual_intf = mtk_p2p_cfg80211_change_iface, /* 1st */ ++ .change_bss = mtk_p2p_cfg80211_change_bss, ++ .scan = mtk_p2p_cfg80211_scan, ++ .remain_on_channel = mtk_p2p_cfg80211_remain_on_channel, ++ .cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel, ++ .mgmt_tx = mtk_p2p_cfg80211_mgmt_tx, ++ .connect = mtk_p2p_cfg80211_connect, ++ .disconnect = mtk_p2p_cfg80211_disconnect, ++ .deauth = mtk_p2p_cfg80211_deauth, ++ .disassoc = mtk_p2p_cfg80211_disassoc, ++ .start_ap = mtk_p2p_cfg80211_start_ap, ++ .change_beacon = mtk_p2p_cfg80211_change_beacon, ++ .stop_ap = mtk_p2p_cfg80211_stop_ap, ++ .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params, ++ .del_station = mtk_p2p_cfg80211_del_station, ++ .set_monitor_channel = mtk_p2p_cfg80211_set_channel, ++ .set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask, ++ .mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register, ++ .get_station = mtk_p2p_cfg80211_get_station, ++ .add_key = mtk_p2p_cfg80211_add_key, ++ .get_key = mtk_p2p_cfg80211_get_key, ++ .del_key = mtk_p2p_cfg80211_del_key, ++ .set_default_key = mtk_p2p_cfg80211_set_default_key, ++ .join_ibss = mtk_p2p_cfg80211_join_ibss, ++ .leave_ibss = mtk_p2p_cfg80211_leave_ibss, ++ .set_tx_power = mtk_p2p_cfg80211_set_txpower, ++ .get_tx_power = mtk_p2p_cfg80211_get_txpower, ++ .set_power_mgmt = mtk_p2p_cfg80211_set_power_mgmt, ++#ifdef CONFIG_NL80211_TESTMODE ++ .testmode_cmd = mtk_p2p_cfg80211_testmode_cmd, ++#endif ++}; ++ ++static const struct wiphy_vendor_command mtk_p2p_vendor_ops[] = { ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_channel_list ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_country_code ++ }, ++}; ++ ++/* There isn't a lot of sense in it, but you can transmit anything you like */ ++static const struct ieee80211_txrx_stypes ++ mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { ++ [NL80211_IFTYPE_ADHOC] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_STATION] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_AP] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_AP_VLAN] = { ++ /* copy AP */ ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | ++ BIT(IEEE80211_STYPE_DISASSOC >> 4) | ++ BIT(IEEE80211_STYPE_AUTH >> 4) | ++ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_CLIENT] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_GO] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ } ++}; ++ ++#endif ++ ++/* the legacy wireless extension stuff */ ++static const iw_handler rP2PIwStandardHandler[] = { ++ [SIOCGIWPRIV - SIOCIWFIRST] = mtk_p2p_wext_get_priv, ++ [SIOCGIWSCAN - SIOCIWFIRST] = mtk_p2p_wext_discovery_results, ++ [SIOCSIWESSID - SIOCIWFIRST] = mtk_p2p_wext_reconnect, ++ [SIOCSIWAUTH - SIOCIWFIRST] = mtk_p2p_wext_set_auth, ++ [SIOCSIWENCODEEXT - SIOCIWFIRST] = mtk_p2p_wext_set_key, ++ [SIOCSIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_set_powermode, ++ [SIOCGIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_get_powermode, ++ [SIOCSIWTXPOW - SIOCIWFIRST] = mtk_p2p_wext_set_txpow, ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ [SIOCGIWSTATS - SIOCIWFIRST] = mtk_p2p_wext_get_rssi, ++#endif ++ [SIOCSIWMLME - SIOCIWFIRST] = mtk_p2p_wext_mlme_handler, ++}; ++ ++static const iw_handler rP2PIwPrivHandler[] = { ++ [IOC_P2P_CFG_DEVICE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_local_dev_info, ++ [IOC_P2P_PROVISION_COMPLETE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_provision_complete, ++ [IOC_P2P_START_STOP_DISCOVERY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_start_stop_discovery, ++ [IOC_P2P_DISCOVERY_RESULTS - SIOCIWFIRSTPRIV] = mtk_p2p_wext_discovery_results, ++ [IOC_P2P_WSC_BEACON_PROBE_RSP_IE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_wsc_ie, ++ [IOC_P2P_CONNECT_DISCONNECT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_connect_disconnect, ++ [IOC_P2P_PASSWORD_READY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_password_ready, ++/* [IOC_P2P_SET_PWR_MGMT_PARAM - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_pm_param, */ ++ [IOC_P2P_SET_INT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_int, ++ [IOC_P2P_GET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_get_struct, ++ [IOC_P2P_SET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_struct, ++ [IOC_P2P_GET_REQ_DEVICE_INFO - SIOCIWFIRSTPRIV] = mtk_p2p_wext_request_dev_info, ++}; ++ ++static const struct iw_priv_args rP2PIwPrivTable[] = { ++ { ++ .cmd = IOC_P2P_CFG_DEVICE, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CFG_DEVICE_TYPE), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_CFG_DEVICE"} ++ , ++ { ++ .cmd = IOC_P2P_START_STOP_DISCOVERY, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_REQ_DEVICE_TYPE), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_DISCOVERY"} ++ , ++ { ++ .cmd = IOC_P2P_DISCOVERY_RESULTS, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_RESULT"} ++ , ++ { ++ .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_HOSTAPD_PARAM), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_WSC_IE"} ++ , ++ { ++ .cmd = IOC_P2P_CONNECT_DISCONNECT, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CONNECT_DEVICE), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_CONNECT"} ++ , ++ { ++ .cmd = IOC_P2P_PASSWORD_READY, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_PASSWORD_READY), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_PASSWD_RDY"} ++ , ++ { ++ .cmd = IOC_P2P_GET_STRUCT, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = 256, ++ .name = "P2P_GET_STRUCT"} ++ , ++ { ++ .cmd = IOC_P2P_SET_STRUCT, ++ .set_args = 256, ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_SET_STRUCT"} ++ , ++ { ++ .cmd = IOC_P2P_GET_REQ_DEVICE_INFO, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_DEVICE_REQ), ++ .name = "P2P_GET_REQDEV"} ++ , ++ { ++ /* SET STRUCT sub-ioctls commands */ ++ .cmd = PRIV_CMD_OID, ++ .set_args = 256, ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "set_oid"} ++ , ++ { ++ /* GET STRUCT sub-ioctls commands */ ++ .cmd = PRIV_CMD_OID, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = 256, ++ .name = "get_oid"} ++}; ++ ++const struct iw_handler_def mtk_p2p_wext_handler_def = { ++ .num_standard = (__u16) sizeof(rP2PIwStandardHandler) / sizeof(iw_handler), ++ .num_private = (__u16) sizeof(rP2PIwPrivHandler) / sizeof(iw_handler), ++ .num_private_args = (__u16) sizeof(rP2PIwPrivTable) / sizeof(struct iw_priv_args), ++ .standard = rP2PIwStandardHandler, ++ .private = rP2PIwPrivHandler, ++ .private_args = rP2PIwPrivTable, ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ .get_wireless_stats = mtk_p2p_wext_get_wireless_stats, ++#else ++ .get_wireless_stats = NULL, ++#endif ++}; ++ ++#ifdef CONFIG_PM ++static const struct wiphy_wowlan_support p2p_wowlan_support = { ++ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, ++}; ++#endif ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* for IE Searching */ ++extern BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++ ++#if CFG_SUPPORT_WPS ++extern BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++/* Net Device Hooks */ ++static int p2pOpen(IN struct net_device *prDev); ++ ++static int p2pStop(IN struct net_device *prDev); ++ ++static struct net_device_stats *p2pGetStats(IN struct net_device *prDev); ++ ++static void p2pSetMulticastList(IN struct net_device *prDev); ++ ++static int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev); ++ ++static int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd); ++ ++static int p2pSetMACAddress(IN struct net_device *prDev, void *addr); ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Override the implementation of select queue ++* ++* \param[in] dev Pointer to struct net_device ++* \param[in] skb Pointer to struct skb_buff ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++unsigned int _p2p_cfg80211_classify8021d(struct sk_buff *skb) ++{ ++ unsigned int dscp = 0; ++ ++ /* skb->priority values from 256->263 are magic values ++ * directly indicate a specific 802.1d priority. This is ++ * to allow 802.1d priority to be passed directly in from ++ * tags ++ */ ++ ++ if (skb->priority >= 256 && skb->priority <= 263) ++ return skb->priority - 256; ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ dscp = ip_hdr(skb)->tos & 0xfc; ++ break; ++ } ++ return dscp >> 5; ++} ++ ++static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; ++ ++static UINT_16 p2pSelectQueue(struct net_device *dev, struct sk_buff *skb, ++ void *accel_priv, select_queue_fallback_t fallback) ++{ ++ skb->priority = _p2p_cfg80211_classify8021d(skb); ++ ++ return au16Wlan1dToQueueIdx[skb->priority]; ++} ++ ++static struct net_device *g_P2pPrDev; ++static struct wireless_dev *gprP2pWdev; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->init ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanInit succeeds. ++* \retval -ENXIO No such device. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int p2pInit(struct net_device *prDev) ++{ ++/* P_GLUE_INFO_T prGlueInfo; */ ++ if (!prDev) ++ return -ENXIO; ++ ++ DBGLOG(P2P, INFO, "dev name=%s\n", prDev->name); ++ return 0; /* success */ ++} /* end of p2pInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->uninit ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void p2pUninit(IN struct net_device *prDev) ++{ ++ ++} /* end of p2pUninit() */ ++ ++static const struct net_device_ops p2p_netdev_ops = { ++ .ndo_open = p2pOpen, ++ .ndo_stop = p2pStop, ++ .ndo_set_mac_address = p2pSetMACAddress, ++ .ndo_set_rx_mode = p2pSetMulticastList, ++ .ndo_get_stats = p2pGetStats, ++ .ndo_do_ioctl = p2pDoIOCTL, ++ .ndo_start_xmit = p2pHardStartXmit, ++ .ndo_select_queue = p2pSelectQueue, ++ .ndo_init = p2pInit, ++ .ndo_uninit = p2pUninit, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS ++* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2PAllocInfo(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_WIFI_VAR_T prWifiVar = NULL; ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ prWifiVar = &(prAdapter->rWifiVar); ++ ++ if (!prWifiVar) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ do { ++ if (prGlueInfo->prP2PInfo == NULL) { ++ /*alloc memory for p2p info */ ++ prGlueInfo->prP2PInfo = kalMemAlloc(sizeof(GL_P2P_INFO_T), VIR_MEM_TYPE); ++ prAdapter->prP2pInfo = kalMemAlloc(sizeof(P2P_INFO_T), VIR_MEM_TYPE); ++ prWifiVar->prP2PConnSettings = kalMemAlloc(sizeof(P2P_CONNECTION_SETTINGS_T), VIR_MEM_TYPE); ++ prWifiVar->prP2pFsmInfo = kalMemAlloc(sizeof(P2P_FSM_INFO_T), VIR_MEM_TYPE); ++ prWifiVar->prP2pSpecificBssInfo = kalMemAlloc(sizeof(P2P_SPECIFIC_BSS_INFO_T), VIR_MEM_TYPE); ++ } else { ++ ASSERT(prAdapter->prP2pInfo != NULL); ++ ASSERT(prWifiVar->prP2PConnSettings != NULL); ++ ASSERT(prWifiVar->prP2pFsmInfo != NULL); ++ ASSERT(prWifiVar->prP2pSpecificBssInfo != NULL); ++ } ++ /*MUST set memory to 0 */ ++ if (prGlueInfo->prP2PInfo) ++ kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T)); ++ if (prAdapter->prP2pInfo) ++ kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T)); ++ if (prWifiVar->prP2PConnSettings) ++ kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T)); ++ if (prWifiVar->prP2pFsmInfo) ++ kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T)); ++ if (prWifiVar->prP2pSpecificBssInfo) ++ kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T)); ++ ++ } while (FALSE); ++ ++ /* chk if alloc successful or not */ ++ if (prGlueInfo->prP2PInfo && ++ prAdapter->prP2pInfo && ++ prWifiVar->prP2PConnSettings && prWifiVar->prP2pFsmInfo && prWifiVar->prP2pSpecificBssInfo) { ++ return TRUE; ++ } ++ ++ if (prWifiVar->prP2pSpecificBssInfo) { ++ kalMemFree(prWifiVar->prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T)); ++ ++ prWifiVar->prP2pSpecificBssInfo = NULL; ++ } ++ if (prWifiVar->prP2pFsmInfo) { ++ kalMemFree(prWifiVar->prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); ++ ++ prWifiVar->prP2pFsmInfo = NULL; ++ } ++ if (prWifiVar->prP2PConnSettings) { ++ kalMemFree(prWifiVar->prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T)); ++ ++ prWifiVar->prP2PConnSettings = NULL; ++ } ++ if (prGlueInfo->prP2PInfo) { ++ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); ++ ++ prGlueInfo->prP2PInfo = NULL; ++ } ++ if (prAdapter->prP2pInfo) { ++ kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); ++ ++ prAdapter->prP2pInfo = NULL; ++ } ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS ++* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo) ++{ ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ /* free memory after p2p module is ALREADY unregistered */ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { ++ ++ kalMemFree(prGlueInfo->prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); ++ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); ++ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings, VIR_MEM_TYPE, ++ sizeof(P2P_CONNECTION_SETTINGS_T)); ++ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); ++ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo, VIR_MEM_TYPE, ++ sizeof(P2P_SPECIFIC_BSS_INFO_T)); ++ ++ /*Reomve p2p bss scan list */ ++ scanRemoveAllP2pBssDesc(prGlueInfo->prAdapter); ++ ++ /*reset all pointer to NULL */ ++ prGlueInfo->prP2PInfo = NULL; ++ prGlueInfo->prAdapter->prP2pInfo = NULL; ++ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings = NULL; ++ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo = NULL; ++ prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo = NULL; ++ ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++ ++} ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) ++{ ++ BOOLEAN fgDoRegister = FALSE; ++/* BOOLEAN fgRollbackRtnlLock = FALSE; */ ++ BOOLEAN ret; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) { ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERING; ++ fgDoRegister = TRUE; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (!fgDoRegister) ++ return TRUE; ++ ++ /* net device initialize */ ++ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ /* register for net device */ ++ if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) { ++ DBGLOG(P2P, WARN, "unable to register netdevice for p2p\n"); ++ ++ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ ret = FALSE; ++ } else { ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERED; ++ ret = TRUE; ++ } ++ return ret; ++} ++ ++BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) ++{ ++ BOOLEAN fgDoUnregister = FALSE; ++/* BOOLEAN fgRollbackRtnlLock = FALSE; */ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) { ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING; ++ fgDoUnregister = TRUE; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (!fgDoUnregister) ++ return TRUE; ++ ++ /* prepare for removal */ ++ if (netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) ++ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); ++ DBGLOG(P2P, INFO, "P2P unregister_netdev 0x%p\n", prGlueInfo->prP2PInfo->prDevHandler); ++ unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; ++ ++ return TRUE; ++} ++#endif ++ ++BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo) ++{ ++ struct wiphy *prWiphy = NULL; ++ struct wireless_dev *prWdev = NULL; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ struct net_device *prNetDev = NULL; ++#endif ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); ++ if (!prWdev) { ++ DBGLOG(P2P, ERROR, "allocate p2p wireless device fail, no memory\n"); ++ return FALSE; ++ } ++ /* 1. allocate WIPHY */ ++ prWiphy = wiphy_new(&mtk_p2p_ops, sizeof(P_GLUE_INFO_T)); ++ if (!prWiphy) { ++ DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n"); ++ goto free_wdev; ++ } ++ ++ prWiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_STATION); ++ ++ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; ++ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; ++ ++ prWiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes; ++ prWiphy->max_remain_on_channel_duration = 5000; ++ prWiphy->cipher_suites = mtk_cipher_suites; ++ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); ++ prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_HAVE_AP_SME; ++ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; ++ prWiphy->ap_sme_capa = 1; ++ ++ prWiphy->max_scan_ssids = MAX_SCAN_LIST_NUM; ++ prWiphy->max_scan_ie_len = MAX_SCAN_IE_LEN; ++ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; ++ prWiphy->vendor_commands = mtk_p2p_vendor_ops; ++ prWiphy->n_vendor_commands = sizeof(mtk_p2p_vendor_ops) / sizeof(struct wiphy_vendor_command); ++ ++#ifdef CONFIG_PM ++ prWiphy->wowlan = &p2p_wowlan_support; ++#endif ++ ++ /* 2.1 set priv as pointer to glue structure */ ++ *((P_GLUE_INFO_T *) wiphy_priv(prWiphy)) = prGlueInfo; ++ if (wiphy_register(prWiphy) < 0) { ++ DBGLOG(P2P, ERROR, "fail to register wiphy for p2p\n"); ++ goto free_wiphy; ++ } ++ prWdev->wiphy = prWiphy; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* 3. allocate netdev */ ++ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), P2P_MODE_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++ if (!prNetDev) { ++ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); ++ goto unregister_wiphy; ++ } ++ ++ /* 4. setup netdev */ ++ /* 4.1 Point to shared glue structure */ ++ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = prGlueInfo; ++ ++ /* 4.2 fill hardware address */ ++ /* COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); ++ rMacAddr[0] ^= 0x2; // change to local administrated address ++ memcpy(prGlueInfo->prP2PInfo->prDevHandler->dev_addr, rMacAddr, ETH_ALEN); ++ memcpy(prGlueInfo->prP2PInfo->prDevHandler->perm_addr, ++ prGlueInfo->prP2PInfo->prDevHandler->dev_addr, ETH_ALEN);*/ ++ ++ /* 4.3 register callback functions */ ++ prNetDev->netdev_ops = &p2p_netdev_ops; ++ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def;*/ ++ ++ prNetDev->ieee80211_ptr = prWdev; ++ prWdev->netdev = prNetDev; ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prNetDev->features = NETIF_F_IP_CSUM; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ /* net device initialize */ ++ netif_carrier_off(prNetDev); ++ netif_tx_stop_all_queues(prNetDev); ++ ++ /* register for net device */ ++ if (register_netdev(prNetDev) < 0) { ++ DBGLOG(P2P, ERROR, "unable to register netdevice for p2p\n"); ++ free_netdev(prNetDev); ++ goto unregister_wiphy; ++ } ++#endif ++ gprP2pWdev = prWdev; ++ return TRUE; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++unregister_wiphy: ++ wiphy_unregister(prWiphy); ++#endif ++free_wiphy: ++ wiphy_free(prWiphy); ++free_wdev: ++ kfree(prWdev); ++#endif ++ return FALSE; ++} ++ ++void glP2pDestroyWirelessDevice(VOID) ++{ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#if CFG_SUPPORT_PERSIST_NETDEV ++ unregister_netdev(gprP2pWdev->netdev); ++ free_netdev(gprP2pWdev->netdev); ++#endif ++ wiphy_unregister(gprP2pWdev->wiphy); ++ wiphy_free(gprP2pWdev->wiphy); ++ kfree(gprP2pWdev); ++ gprP2pWdev = NULL; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Register for cfg80211 for Wi-Fi Direct ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GL_HIF_INFO_T prHif = NULL; ++ PARAM_MAC_ADDRESS rMacAddr; ++ struct net_device *prDevHandler = NULL; ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ struct device *prDev; ++#endif ++ ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prHif = &prGlueInfo->rHifInfo; ++ ASSERT(prHif); ++ ++ DBGLOG(P2P, TRACE, "glRegisterP2P\n"); ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ if (!gprP2pWdev) { ++ DBGLOG(P2P, ERROR, "gl_p2p, wireless device is not exist\n"); ++ return FALSE; ++ } ++#endif ++ /*0. allocate p2pinfo */ ++ if (!p2PAllocInfo(prGlueInfo)) { ++ DBGLOG(P2P, ERROR, "Allocate memory for p2p FAILED\n"); ++ ASSERT(0); ++ return FALSE; ++ } ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ prGlueInfo->prP2PInfo->prWdev = gprP2pWdev; ++ /* 1. fill wiphy parameters */ ++#if MTK_WCN_HIF_SDIO ++ mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev); ++ if (!prDev) ++ DBGLOG(P2P, WARN, "unable to get struct dev for p2p\n"); ++#else ++ prDev = prHif->Dev; ++#endif ++ /*set_wiphy_dev(gprP2pWdev->wiphy, prDev);*/ ++ if (!prGlueInfo->prAdapter->fgEnable5GBand) ++ gprP2pWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; ++ ++ /* 2 set priv as pointer to glue structure */ ++ *(P_GLUE_INFO_T *) wiphy_priv(gprP2pWdev->wiphy) = prGlueInfo; ++ ++ if (fgIsApMode) { ++ gprP2pWdev->iftype = NL80211_IFTYPE_AP; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ if (kalStrnCmp(gprP2pWdev->netdev->name, AP_MODE_INF_NAME, 2)) { ++ rtnl_lock(); ++ dev_change_name(gprP2pWdev->netdev->name, AP_MODE_INF_NAME); ++ rtnl_unlock(); ++ } ++#endif ++ } else { ++#if CFG_SUPPORT_PERSIST_NETDEV ++ if (kalStrnCmp(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME, 3)) { ++ rtnl_lock(); ++ dev_change_name(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME); ++ rtnl_unlock(); ++ } ++#endif ++ gprP2pWdev->iftype = NL80211_IFTYPE_P2P_CLIENT; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ prP2PInfo->prDevHandler = gprP2pWdev->netdev; ++#else /* CFG_SUPPORT_PERSIST_NETDEV */ ++ /* 3. allocate netdev */ ++ prDevHandler = ++ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); ++ if (!prDevHandler) { ++ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); ++ return FALSE; ++ } ++ prGlueInfo->prP2PInfo->prDevHandler = prDevHandler; ++ /* 4. setup netdev */ ++ /* 4.1 Point to shared glue structure */ ++ *((P_GLUE_INFO_T *) netdev_priv(prDevHandler)) = prGlueInfo; ++ ++ /* 4.2 fill hardware address */ ++ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); ++ rMacAddr[0] ^= 0x2; /* change to local administrated address */ ++ ether_addr_copy(prDevHandler->dev_addr, rMacAddr); ++ ether_addr_copy(prDevHandler->perm_addr, prDevHandler->dev_addr); ++ ++ /* 4.3 register callback functions */ ++ prDevHandler->netdev_ops = &p2p_netdev_ops; ++ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def; */ ++ ++#if (MTK_WCN_HIF_SDIO == 0) ++ SET_NETDEV_DEV(prDevHandler, prHif->Dev); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ prDevHandler->ieee80211_ptr = gprP2pWdev; ++ gprP2pWdev->netdev = prDevHandler; ++#endif ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prDevHandler->features = NETIF_F_IP_CSUM; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++#endif /* CFG_SUPPORT_PERSIST_NETDEV */ ++ ++ /* 5. set p2p net device register state */ ++ prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; ++ ++ /* 6. setup running mode */ ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode; ++ ++ /* 7. finish */ ++ p2pFsmInit(prAdapter); ++ ++ p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings); ++ ++ /* Active network too early would cause HW not able to sleep. ++ * Defer the network active time. ++ */ ++/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ return TRUE; ++} /* end of glRegisterP2P() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Unregister Net Device for Wi-Fi Direct ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ /* normal flow: this func will called first before wlanRemove, and it can do fsmUninit/deactivateNetwork ++ gracefully. */ ++ /* when reset: because tx_thread with fw has stopped, so it can't do these job and the recovery will be ++ dependent on chip system reset. */ ++ /* if so, just skip it by flag GLUE_FLAG_HALT(warning: when tx_thread was stop, this flag was not cleared, ++ and NEED TO KEEP IT NOT CLEARED!). */ ++ if (!(prGlueInfo->ulFlag & GLUE_FLAG_HALT)) { ++ p2pFsmUninit(prGlueInfo->prAdapter); ++ nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++#if CFG_SUPPORT_PERSIST_NETDEV ++ dev_close(prGlueInfo->prP2PInfo->prDevHandler); ++#else ++ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); ++ prGlueInfo->prP2PInfo->prDevHandler = NULL; ++#endif ++ /* Free p2p memory */ ++ if (!p2PFreeInfo(prGlueInfo)) { ++ DBGLOG(P2P, ERROR, "Free memory for p2p FAILED\n"); ++ ASSERT(0); ++ return FALSE; ++ } ++ return TRUE; ++} /* end of glUnregisterP2P() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for stop p2p fsm immediate ++ * ++ * \param[in] prGlueInfo Pointer to struct P_GLUE_INFO_T. ++ * ++ * \retval TRUE The execution succeeds. ++ * \retval FALSE The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo) ++{ ++/* P_ADAPTER_T prAdapter = NULL; */ ++/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ ++ ++ ASSERT(prGlueInfo); ++ ++/* prAdapter = prGlueInfo->prAdapter; */ ++/* ASSERT(prAdapter); */ ++ ++ /* 1. stop TX queue */ ++ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); ++ ++#if 0 ++ /* 2. switch P2P-FSM off */ ++ /* 2.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ DBGLOG(P2P, ERROR, "Allocate for p2p mesasage FAILED\n"); ++ /* return -ENOMEM; */ ++ } ++ ++ /* 2.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = FALSE; ++ ++ /* 2.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_UNBUF); ++ ++#endif ++ ++ /* 3. stop queue and turn off carrier */ ++ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; ++ ++ return TRUE; ++} /* end of p2pStop() */ ++ ++/* Net Device Hooks */ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device open (ifup) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int p2pOpen(IN struct net_device *prDev) ++{ ++/* P_GLUE_INFO_T prGlueInfo = NULL; */ ++/* P_ADAPTER_T prAdapter = NULL; */ ++/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ ++ ++ ASSERT(prDev); ++ ++#if 0 /* Move after device name set. (mtk_p2p_set_local_dev_info) */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* 1. switch P2P-FSM on */ ++ /* 1.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = TRUE; ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ ++ /* 2. carrier on & start TX queue */ ++ netif_carrier_on(prDev); ++ netif_tx_start_all_queues(prDev); ++ ++ return 0; /* success */ ++} /* end of p2pOpen() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device stop (ifdown) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int p2pStop(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ /* P_ADAPTER_T prAdapter = NULL; */ ++/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ struct cfg80211_scan_info info = { ++ .aborted = true, ++ }; ++ ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ASSERT(prGlueP2pInfo); ++ ++ /* CFG80211 down */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueP2pInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueP2pInfo->prScanRequest; ++ prGlueP2pInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (prScanRequest) ++ cfg80211_scan_done(prScanRequest, &info); ++#if 0 ++ ++ /* 1. stop TX queue */ ++ netif_tx_stop_all_queues(prDev); ++ ++ /* 2. switch P2P-FSM off */ ++ /* 2.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 2.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = FALSE; ++ ++ /* 2.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ /* 3. stop queue and turn off carrier */ ++ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; ++ ++ netif_tx_stop_all_queues(prDev); ++ if (netif_carrier_ok(prDev)) ++ netif_carrier_off(prDev); ++ ++ return 0; ++} /* end of p2pStop() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A method of struct net_device, to get the network interface statistical ++ * information. ++ * ++ * Whenever an application needs to get statistics for the interface, this method ++ * is called. This happens, for example, when ifconfig or netstat -i is run. ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \return net_device_stats buffer pointer. ++ */ ++/*----------------------------------------------------------------------------*/ ++struct net_device_stats *p2pGetStats(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* @FIXME */ ++ /* prDev->stats.rx_packets = 0; */ ++ /* prDev->stats.tx_packets = 0; */ ++ prDev->stats.tx_errors = 0; ++ prDev->stats.rx_errors = 0; ++ /* prDev->stats.rx_bytes = 0; */ ++ /* prDev->stats.tx_bytes = 0; */ ++ prDev->stats.multicast = 0; ++ ++ return &prDev->stats; ++ ++#else ++ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_packets = 0; */ ++ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_packets = 0; */ ++ prGlueInfo->prP2PInfo->rNetDevStats.tx_errors = 0; ++ prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; ++ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes = 0; */ ++ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes = 0; */ ++ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; */ ++ prGlueInfo->prP2PInfo->rNetDevStats.multicast = 0; ++ ++ return &prGlueInfo->prP2PInfo->rNetDevStats; ++#endif ++} /* end of p2pGetStats() */ ++ ++static void p2pSetMulticastList(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ if (!prDev || !prGlueInfo) { ++ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); ++ return; ++ } ++ ++ g_P2pPrDev = prDev; ++ ++ /* 4 Mark HALT, notify main thread to finish current job */ ++/* prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_MULTICAST; */ ++ set_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++} /* p2pSetMulticastList */ ++ ++/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange ++ * another workqueue for sleeping. We don't want to block ++ * tx_thread, so we can't let tx_thread to do this */ ++ ++void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo) ++{ ++ if (!prGlueInfo) { ++ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); ++ return; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ mtk_p2p_wext_set_Multicastlist(prGlueInfo); ++#endif ++} /* end of p2pSetMulticastListWorkQueueWrapper() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This function is to set multicast list and set rx mode. ++ * ++ * \param[in] prDev Pointer to struct net_device ++ * ++ * \return (none) ++ */ ++/*----------------------------------------------------------------------------*/ ++void mtk_p2p_wext_set_Multicastlist(P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_32 u4SetInfoLen = 0; ++ struct net_device *prDev = g_P2pPrDev; ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ if (!prDev || !prGlueInfo) { ++ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); ++ return; ++ } ++ ++ if (prDev->flags & IFF_PROMISC) ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; ++ ++ if (prDev->flags & IFF_BROADCAST) ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; ++ ++ if (prDev->flags & IFF_MULTICAST) { ++ if ((prDev->flags & IFF_ALLMULTI) || ++ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; ++ } else { ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; ++ } ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { ++ /* Prepare multicast address list */ ++ struct netdev_hw_addr *ha; ++ UINT_32 i = 0; ++ ++ netdev_for_each_mc_addr(ha, prDev) { ++ if (i < MAX_NUM_GROUP_ADDR) { ++ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr); ++ i++; ++ } ++ } ++ ++ DBGLOG(P2P, TRACE, "SEt Multicast Address List\n"); ++ ++ if (i >= MAX_NUM_GROUP_ADDR) ++ return; ++ wlanoidSetP2PMulticastList(prGlueInfo->prAdapter, ++ &(prGlueInfo->prP2PInfo->aucMCAddrList[0]), (i * ETH_ALEN), &u4SetInfoLen); ++ ++ } ++ ++} /* end of mtk_p2p_wext_set_Multicastlist */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * * \brief This function is TX entry point of NET DEVICE. ++ * * ++ * * \param[in] prSkb Pointer of the sk_buff to be sent ++ * * \param[in] prDev Pointer to struct net_device ++ * * ++ * * \retval NETDEV_TX_OK - on success. ++ * * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. ++ * */ ++/*----------------------------------------------------------------------------*/ ++int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) ++{ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_QUE_T prTxQueue = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_16 u2QueueIdx = 0; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prSkb); ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prGlueInfo->u8SkbToDriver++; ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ DBGLOG(P2P, ERROR, "GLUE_FLAG_HALT skip tx\n"); ++ prGlueInfo->u8SkbFreed++; ++ dev_kfree_skb(prSkb); ++ return NETDEV_TX_OK; ++ } ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ kalMetProfilingStart(prGlueInfo, prSkb); ++#endif ++ ++ /* mark as P2P packets */ ++ GLUE_SET_PKT_FLAG_P2P(prSkb); ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); ++#endif ++ ++ STATS_TX_TIME_ARRIVE(prSkb); ++ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); ++ prTxQueue = &prGlueInfo->rTxQueue; ++ ++ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { ++ ++ u2QueueIdx = skb_get_queue_mapping(prSkb); ++ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); ++ ++ if (u2QueueIdx >= CFG_MAX_TXQ_NUM) { ++ DBGLOG(P2P, ERROR, "Incorrect queue index, skip this frame\n"); ++ prGlueInfo->u8SkbFreed++; ++ dev_kfree_skb(prSkb); ++ return NETDEV_TX_OK; ++ } ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); ++ ++ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx] >= ++ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { ++ DBGLOG(TX, INFO, "netif_stop_subqueue for p2p0, Queue len: %d\n", ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); ++ netif_stop_subqueue(prDev, u2QueueIdx); ++ } ++ } else { ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++ } ++ ++ kalSetEvent(prGlueInfo); ++ ++ /* Statistic usage. */ ++ prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes += prSkb->len; ++ prGlueInfo->prP2PInfo->rNetDevStats.tx_packets++; ++ /* prDev->stats.tx_packets++; */ ++ kalPerMonStart(prGlueInfo); ++ return NETDEV_TX_OK; ++} /* end of p2pHardStartXmit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A method of struct net_device, a primary SOCKET interface to configure ++ * the interface lively. Handle an ioctl call on one of our devices. ++ * Everything Linux ioctl specific is done here. Then we pass the contents ++ * of the ifr->data to the request message handler. ++ * ++ * \param[in] prDev Linux kernel netdevice ++ * ++ * \param[in] prIfReq Our private ioctl request structure, typed for the generic ++ * struct ifreq so we can use ptr to function ++ * ++ * \param[in] cmd Command ID ++ * ++ * \retval 0 The IOCTL command is executed successfully. ++ * \retval <0 The execution of IOCTL command is failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ int ret = 0; ++ char *prExtraBuf = NULL; ++ UINT_32 u4ExtraSize = 0; ++ struct iwreq *prIwReq = (struct iwreq *)prIfReq; ++ struct iw_request_info rIwReqInfo; ++ ++ ASSERT(prDev && prIfReq); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ if (!prGlueInfo) { ++ DBGLOG(P2P, ERROR, "prGlueInfo is NULL\n"); ++ return -EFAULT; ++ } ++ ++ if (prGlueInfo->u4ReadyFlag == 0) { ++ DBGLOG(P2P, ERROR, "Adapter is not ready\n"); ++ return -EINVAL; ++ } ++ ++ rIwReqInfo.cmd = (__u16) i4Cmd; ++ rIwReqInfo.flags = 0; ++ ++ switch (i4Cmd) { ++ case SIOCSIWENCODEEXT: ++ /* Set Encryption Material after 4-way handshaking is done */ ++ if (prIwReq->u.encoding.pointer) { ++ u4ExtraSize = prIwReq->u.encoding.length; ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, prIwReq->u.encoding.pointer, prIwReq->u.encoding.length)) ++ ret = -EFAULT; ++ } else if (prIwReq->u.encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret == 0) ++ ret = mtk_p2p_wext_set_key(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ break; ++ ++ case SIOCSIWMLME: ++ /* IW_MLME_DISASSOC used for disconnection */ ++ if (prIwReq->u.data.length != sizeof(struct iw_mlme)) { ++ DBGLOG(P2P, WARN, "MLME buffer strange:%d\n", prIwReq->u.data.length); ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (!prIwReq->u.data.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, prIwReq->u.data.pointer, sizeof(struct iw_mlme))) ++ ret = -EFAULT; ++ else ++ ret = mtk_p2p_wext_mlme_handler(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); ++ prExtraBuf = NULL; ++ break; ++ ++ case SIOCGIWPRIV: ++ /* This ioctl is used to list all IW privilege ioctls */ ++ ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++ ++ case SIOCGIWSCAN: ++ ret = mtk_p2p_wext_discovery_results(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++ ++ case SIOCSIWAUTH: ++ ret = mtk_p2p_wext_set_auth(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++ ++ case IOC_P2P_CFG_DEVICE: ++ case IOC_P2P_PROVISION_COMPLETE: ++ case IOC_P2P_START_STOP_DISCOVERY: ++ case IOC_P2P_DISCOVERY_RESULTS: ++ case IOC_P2P_WSC_BEACON_PROBE_RSP_IE: ++ case IOC_P2P_CONNECT_DISCONNECT: ++ case IOC_P2P_PASSWORD_READY: ++ case IOC_P2P_GET_STRUCT: ++ case IOC_P2P_SET_STRUCT: ++ case IOC_P2P_GET_REQ_DEVICE_INFO: ++ ret = ++ rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV] (prDev, &rIwReqInfo, &(prIwReq->u), ++ (char *)&(prIwReq->u)); ++ break; ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ case SIOCGIWSTATS: ++ ret = mtk_p2p_wext_get_rssi(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++#endif ++ case IOC_GET_PRIVATE_IOCTL_CMD: ++ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); ++ ++ break; ++ default: ++ ret = -ENOTTY; ++ } ++ ++ return ret; ++} /* end of p2pDoIOCTL() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief To report the iw private args table to user space. ++ * ++ * \param[in] prDev Net device requested. ++ * \param[in] info Pointer to iw_request_info. ++ * \param[inout] wrqu Pointer to iwreq_data. ++ * \param[inout] extra ++ * ++ * \retval 0 For success. ++ * \retval -E2BIG For user's buffer size is too small. ++ * \retval -EFAULT For fail. ++ * ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_priv(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ UINT_16 u2BufferSize = prData->length; ++ ++ /* Update our private args table size */ ++ prData->length = (__u16)sizeof(rP2PIwPrivTable); ++ if (u2BufferSize < prData->length) ++ return -E2BIG; ++ ++ if (prData->length) { ++ if (copy_to_user(prData->pointer, rP2PIwPrivTable, sizeof(rP2PIwPrivTable))) ++ return -EFAULT; ++ } ++ ++ return 0; ++} /* end of mtk_p2p_wext_get_priv() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief To indicate P2P-FSM for re-associate to the connecting device ++ * ++ * \param[in] prDev Net device requested. ++ * \param[inout] wrqu Pointer to iwreq_data ++ * ++ * \retval 0 For success. ++ * \retval -EFAULT For fail. ++ * ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_reconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_MSG_HDR_T prMsgHdr; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); ++ if (!prMsgHdr) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_reconnect: P2P Reconnect\n"); ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); ++#endif ++ return 0; ++} /* end of mtk_p2p_wext_reconnect() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief MLME command handler ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_mlme *mlme = (struct iw_mlme *)extra; ++ P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_mlme_handler:\n"); ++ ++ switch (mlme->cmd) { ++ case IW_MLME_DISASSOC: ++ prMsgP2PConnAbt = ++ (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ if (!prMsgP2PConnAbt) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, mlme->addr.sa_data); ++ ++ prMsgP2PConnAbt->u2ReasonCode = mlme->reason_code; ++ ++ if (EQUAL_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prP2pBssInfo->aucOwnMacAddr)) { ++ DBGLOG(P2P, TRACE, "P2P Connection Abort:\n"); ++ ++ /* 1.2 fill message */ ++ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ } else { ++ DBGLOG(P2P, TRACE, "P2P Connection Pause:\n"); ++ ++ /* 1.2 fill message */ ++ } ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); ++ ++ break; ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++#endif ++ return 0; ++} /* end of mtk_p2p_wext_mlme_handler() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_PROVISION_COMPLETE) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_MSG_HDR_T prMsgHdr; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ switch (prData->flags) { ++ case P2P_PROVISIONING_SUCCESS: ++ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); ++ if (!prMsgHdr) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ ++ prGlueInfo->prP2PInfo->u4CipherPairwise = IW_AUTH_CIPHER_CCMP; ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); ++ ++ break; ++ ++ case P2P_PROVISIONING_FAIL: ++ ++ break; ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++#endif ++ ++ return 0; ++} /* end of mtk_p2p_wext_set_provision_complete() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_START_STOP_DISCOVERY) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_IW_P2P_REQ_DEVICE_TYPE prReqDeviceType = (P_IW_P2P_REQ_DEVICE_TYPE) extra; ++ UINT_8 au4IeBuf[MAX_IE_LENGTH]; ++ P_MSG_HDR_T prMsgHdr; ++ P_MSG_P2P_DEVICE_DISCOVER_T prDiscoverMsg; ++ P_P2P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prData->flags == P2P_STOP_DISCOVERY) { ++ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); ++ ++ if (!prMsgHdr) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); ++ } else if (prData->flags == P2P_START_DISCOVERY) { ++ ++ /* retrieve IE for Probe Response */ ++ if (prReqDeviceType->probe_rsp_len > 0) { ++ if (prReqDeviceType->probe_rsp_len <= MAX_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[2], prReqDeviceType->probe_rsp_ie, ++ prReqDeviceType->probe_rsp_len)) { ++ return -EFAULT; ++ } ++ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prReqDeviceType->probe_rsp_len; ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ /* retrieve IE for Probe Request */ ++ if (prReqDeviceType->probe_req_len > 0) { ++ if (prReqDeviceType->probe_req_len <= MAX_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[1], prReqDeviceType->probe_req_ie, ++ prReqDeviceType->probe_req_len)) { ++ return -EFAULT; ++ } ++ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prReqDeviceType->probe_req_len; ++ } else { ++ return -E2BIG; ++ } ++ } ++ /* update IE for Probe Request */ ++ ++ if (prReqDeviceType->scan_type == P2P_LISTEN) { ++ /* update listening parameter */ ++ ++ /* @TODO: update prConnSettings for Probe Response IE */ ++ } else { ++ /* indicate P2P-FSM with MID_MNY_P2P_DEVICE_DISCOVERY */ ++ prDiscoverMsg = (P_MSG_P2P_DEVICE_DISCOVER_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ sizeof(MSG_P2P_DEVICE_DISCOVER_T)); ++ ++ if (!prDiscoverMsg) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ prDiscoverMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; ++ prDiscoverMsg->u4DevDiscoverTime = 0; /* unlimited */ ++ prDiscoverMsg->fgIsSpecificType = TRUE; ++ prDiscoverMsg->rTargetDeviceType.u2CategoryID = ++ *(PUINT_16) (&(prReqDeviceType->pri_device_type[0])); ++ prDiscoverMsg->rTargetDeviceType.u2SubCategoryID = ++ *(PUINT_16) (&(prReqDeviceType->pri_device_type[6])); ++ COPY_MAC_ADDR(prDiscoverMsg->aucTargetDeviceID, aucNullAddr); ++ ++ /* @FIXME: parameter to be refined, where to pass IE buffer ? */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDiscoverMsg, MSG_SEND_METHOD_BUF); ++ } ++ } else { ++ return -EINVAL; ++ } ++#endif ++ ++ return 0; ++} /* end of mtk_p2p_wext_start_stop_discovery() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int i4Status = 0; ++#if 0 ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_IW_P2P_IOCTL_INVITATION_STRUCT prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) NULL; ++ ++ do { ++ if ((prDev == NULL) || (extra == NULL)) { ++ ASSERT(FALSE); ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) extra; ++ ++ if (prGlueInfo == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ if (prAdapter == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ if (prIoctlInvitation->ucReinvoke == 1) { ++ /* TODO: Set Group ID */ ++ p2pFuncSetGroupID(prAdapter, prIoctlInvitation->aucGroupID, prIoctlInvitation->aucSsid, ++ prIoctlInvitation->u4SsidLen); ++ } ++ ++ else { ++ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; ++ ++ /* TODO: Do Invitation. */ ++ prMsgP2PInvitationReq = ++ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_INVITATION_REQUEST_T)); ++ if (!prMsgP2PInvitationReq) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ i4Status = -ENOMEM; ++ break; ++ } ++ ++ /* 1.2 fill message */ ++ kalMemCopy(prMsgP2PInvitationReq->aucDeviceID, prIoctlInvitation->aucDeviceID, MAC_ADDR_LEN); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationReq, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ } while (FALSE); ++#endif ++ ++ return i4Status; ++ ++} ++ ++/* mtk_p2p_wext_invitation_request */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_abort(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int i4Status = 0; ++#if 0 ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_IW_P2P_IOCTL_ABORT_INVITATION prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) NULL; ++ ++ UINT_8 bssid[MAC_ADDR_LEN]; ++ ++ do { ++ if ((prDev == NULL) || (extra == NULL)) { ++ ASSERT(FALSE); ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) extra; ++ ++ if (prGlueInfo == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ if (prAdapter == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; ++ ++ prMsgP2PInvitationAbort = ++ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_INVITATION_REQUEST_T)); ++ ++ if (!prMsgP2PInvitationAbort) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ i4Status = -ENOMEM; ++ break; ++ } ++ ++ /* 1.2 fill message */ ++ kalMemCopy(prMsgP2PInvitationAbort->aucDeviceID, prIoctlInvitationAbort->dev_addr, ++ MAC_ADDR_LEN); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationAbort, MSG_SEND_METHOD_BUF); ++ ++ ++ } while (FALSE); ++#endif ++ ++ return i4Status; ++ ++} ++ ++/* mtk_p2p_wext_invitation_abort */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief To override p2p interface address ++ * ++ * \param[in] prDev Net device requested. ++ * \param[in] addr Pointer to address ++ * ++ * \retval 0 For success. ++ * \retval -E2BIG For user's buffer size is too small. ++ * \retval -EFAULT For fail. ++ * ++ */ ++/*----------------------------------------------------------------------------*/ ++int p2pSetMACAddress(IN struct net_device *prDev, void *addr) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @FIXME */ ++ return eth_mac_addr(prDev, addr); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher suite ++* ++* \param[in] prDev Net device requested. ++* \param[out] ++* ++* \retval 0 Success. ++* \retval -EINVAL Invalid parameter ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_auth(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_param *prAuth = (struct iw_param *)wrqu; ++ ++ ASSERT(prDev); ++ ASSERT(prAuth); ++ if (FALSE == GLUE_CHK_PR2(prDev, prAuth)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ /* Save information to glue info and process later when ssid is set. */ ++ switch (prAuth->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ break; ++ case IW_AUTH_CIPHER_PAIRWISE: ++ prGlueInfo->prP2PInfo->u4CipherPairwise = prAuth->value; ++ break; ++ case IW_AUTH_CIPHER_GROUP: ++ case IW_AUTH_KEY_MGMT: ++ case IW_AUTH_TKIP_COUNTERMEASURES: ++ case IW_AUTH_DROP_UNENCRYPTED: ++ case IW_AUTH_80211_AUTH_ALG: ++ case IW_AUTH_WPA_ENABLED: ++ case IW_AUTH_RX_UNENCRYPTED_EAPOL: ++ case IW_AUTH_ROAMING_CONTROL: ++ case IW_AUTH_PRIVACY_INVOKED: ++ default: ++ /* @TODO */ ++ break; ++ } ++ ++ return 0; ++} /* end of mtk_p2p_wext_set_auth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[out] prIfReq Pointer to ifreq structure, content is copied back to ++* user space buffer in gl_iwpriv_table. ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_key(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int ret = 0; ++ struct iw_encode_ext *prIWEncExt; ++ struct iw_point *prEnc; ++ char *prExtraBuf = NULL; ++ UINT_32 u4ExtraSize = 0; ++ UINT_8 keyStructBuf[100]; ++ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; ++ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ do { ++ if (wrqu->encoding.pointer) { ++ u4ExtraSize = wrqu->encoding.length; ++ /*need confirm u4ExtraSize > 0 but is not very large*/ ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ /* here should set prExtraBuf default value */ ++ memset(prExtraBuf, 0, u4ExtraSize); ++ if (copy_from_user(prExtraBuf, wrqu->encoding.pointer, wrqu->encoding.length)) { ++ ret = -EFAULT; ++ break; ++ } ++ } else if (wrqu->encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prEnc = &wrqu->encoding; ++ /* here, need confirm (struct iw_encode_ext) < u4ExtraSize */ ++ prIWEncExt = (struct iw_encode_ext *)prExtraBuf; ++ ++ if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) != TRUE) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ memset(keyStructBuf, 0, sizeof(keyStructBuf)); ++ ++ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { /* Key Removal */ ++ prRemoveKey->u4Length = sizeof(*prRemoveKey); ++ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveP2PKey, ++ prRemoveKey, ++ prRemoveKey->u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ ret = -EFAULT; ++ } else { ++ if (prIWEncExt->alg == IW_ENCODE_ALG_CCMP) { ++ /* KeyID */ ++ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? ++ ((prEnc->flags & IW_ENCODE_INDEX) - 1) : 0; ++ if (prKey->u4KeyIndex <= 3) { ++ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ ++ /* Tx Key Bit(31) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) ++ prKey->u4KeyIndex |= 0x1UL << 31; ++ ++ /* Pairwise Key Bit(30) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ /* group key */ ++ } else { ++ /* pairwise key */ ++ prKey->u4KeyIndex |= 0x1UL << 30; ++ } ++ ++ /* Rx SC Bit(29) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { ++ prKey->u4KeyIndex |= 0x1UL << 29; ++ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, ++ IW_ENCODE_SEQ_MAX_SIZE); ++ } ++ ++ /* BSSID */ ++ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); ++ ++ prKey->u4KeyLength = prIWEncExt->key_len; ++ prKey->u4Length = ++ ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + ++ prKey->u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddP2PKey, ++ prKey, ++ prKey->u4Length, ++ FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ ret = -EFAULT; ++ } else { ++ ret = -EINVAL; ++ } ++ } else { ++ ret = -EINVAL; ++ } ++ } ++ ++ } while (FALSE); ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ ++ return ret; ++} /* end of mtk_p2p_wext_set_key() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set the p2p gc power mode ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_powermode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ /* printk("set_powermode = %d, value = %d\n", wrqu->power.disabled, wrqu->power.value); */ ++ struct iw_param *prPower = (struct iw_param *)&wrqu->power; ++#if 1 ++ PARAM_POWER_MODE ePowerMode; ++ INT_32 i4PowerValue; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ ++ /* prPower->value, prPower->disabled, prPower->flags); */ ++ ++ if (prPower->disabled) { ++ ePowerMode = Param_PowerModeCAM; ++ } else { ++ i4PowerValue = prPower->value; ++#if WIRELESS_EXT < 21 ++ i4PowerValue /= 1000000; ++#endif ++ if (i4PowerValue == 0) { ++ ePowerMode = Param_PowerModeCAM; ++ } else if (i4PowerValue == 1) { ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else if (i4PowerValue == 2) { ++ ePowerMode = Param_PowerModeFast_PSP; ++ } else { ++ DBGLOG(P2P, ERROR, "%s(): unsupported power management mode value = %d.\n", ++ __func__, prPower->value); ++ ++ return -EINVAL; ++ } ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++#endif ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief get the p2p gc power mode ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_powermode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ /* printk("mtk_p2p_wext_get_powermode\n"); */ ++ /* wrqu->power.disabled = 0; */ ++ /* wrqu->power.value = 1; */ ++ ++ struct iw_param *prPower = (struct iw_param *)&wrqu->power; ++ PARAM_POWER_MODE ePowerMode = Param_PowerModeMax; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ ++#if 1 ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryP2pPowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), TRUE, FALSE, FALSE, TRUE, &u4BufLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryP2pPowerSaveProfile, &ePowerMode, sizeof(ePowerMode), &u4BufLen); ++#endif ++ ++ prPower->value = 0; ++ prPower->disabled = 1; ++ ++ if (Param_PowerModeCAM == ePowerMode) { ++ prPower->value = 0; ++ prPower->disabled = 1; ++ } else if (Param_PowerModeMAX_PSP == ePowerMode) { ++ prPower->value = 1; ++ prPower->disabled = 0; ++ } else if (Param_PowerModeFast_PSP == ePowerMode) { ++ prPower->value = 2; ++ prPower->disabled = 0; ++ } ++ ++ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; ++#if WIRELESS_EXT < 21 ++ prPower->value *= 1000000; ++#endif ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_CFG_DEVICE) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_CFG_DEVICE_TYPE prDeviceCfg = (P_IW_P2P_CFG_DEVICE_TYPE) extra; ++ P_P2P_CONNECTION_SETTINGS_T prConnSettings; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ /* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL; */ ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ /* update connection settings for P2P-FSM */ ++ /* 1. update SSID */ ++ if (prDeviceCfg->ssid_len > ELEM_MAX_LEN_SSID) ++ prConnSettings->ucSSIDLen = ELEM_MAX_LEN_SSID; ++ else ++ prConnSettings->ucSSIDLen = prDeviceCfg->ssid_len; ++ ++ if (copy_from_user(prConnSettings->aucSSID, prDeviceCfg->ssid, prConnSettings->ucSSIDLen)) ++ return -EFAULT; ++ /* 2. update device type (WPS IE) */ ++ kalMemCopy(&(prConnSettings->rPrimaryDevTypeBE), &(prDeviceCfg->pri_device_type), sizeof(DEVICE_TYPE_T)); ++#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT ++ kalMemCopy(&(prConnSettings->arSecondaryDevTypeBE[0]), &(prDeviceCfg->snd_device_type), sizeof(DEVICE_TYPE_T)); ++#endif ++ ++ /* 3. update device name */ ++ if (prDeviceCfg->device_name_len > WPS_ATTRI_MAX_LEN_DEVICE_NAME) ++ prConnSettings->ucDevNameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; ++ else ++ prConnSettings->ucDevNameLen = prDeviceCfg->device_name_len; ++ if (copy_from_user(prConnSettings->aucDevName, prDeviceCfg->device_name, prConnSettings->ucDevNameLen)) ++ return -EFAULT; ++ /* 4. update GO intent */ ++ prConnSettings->ucGoIntent = prDeviceCfg->intend; ++ ++ /* Preferred channel bandwidth */ ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; ++ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; ++ ++#if 0 ++ /* 1. switch P2P-FSM on */ ++ /* 1.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = TRUE; ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ return 0; ++} /* end of mtk_p2p_wext_set_local_dev_info() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief I/O Control handler for both ++ * IOC_P2P_START_STOP_DISCOVERY & SIOCGIWSCAN ++ * ++ * \param[in] prDev Net device requested. ++ * \param[inout] wrqu Pointer to iwreq_data ++ * ++ * \retval 0 Success. ++ * \retval -EFAULT Setting parameters to driver fail. ++ * \retval -EOPNOTSUPP Key size not supported. ++ * ++ * \note ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_discovery_results(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ struct iw_event iwe; ++ char *current_ev = extra; ++ UINT_32 i; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ P_P2P_INFO_T prP2PInfo = (P_P2P_INFO_T) NULL; ++ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; ++ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prP2PInfo = prAdapter->prP2pInfo; ++ ++ for (i = 0; i < prP2PInfo->u4DeviceNum; i++) { ++ prTargetResult = &prP2PInfo->arP2pDiscoverResult[i]; ++ ++ /* SIOCGIWAP */ ++ iwe.cmd = SIOCGIWAP; ++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; ++ memcpy(iwe.u.ap_addr.sa_data, prTargetResult->aucInterfaceAddr, 6); ++ ++ current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); ++ ++ /* SIOCGIWESSID */ ++ iwe.cmd = SIOCGIWESSID; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = prTargetResult->u2NameLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, prTargetResult->aucName); ++ ++ /* IWEVGENIE for WPA IE */ ++ if (prTargetResult->u2IELength <= 600 && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, ++ prTargetResult->u2IELength, ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); ++ } ++#if CFG_SUPPORT_WPS ++ ++ /* IWEVGENIE for WPS IE */ ++ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPSIE(prTargetResult->pucIeBuf, ++ prTargetResult->u2IELength, ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); ++ } ++#endif ++ ++ /* IWEVGENIE for RSN IE */ ++ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, ++ prTargetResult->u2IELength, ++ 0x30, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); ++ } ++ ++ /* IOC_P2P_GO_WSC_IE */ ++#if 1 ++ /* device capability */ ++ if (1) { ++ UINT_8 data[40]; ++ ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.flags = 0; ++ iwe.u.data.length = 9 + sizeof("p2p_cap="); ++ if (iwe.u.data.length > 40) ++ iwe.u.data.length = 40; ++ ++ snprintf(data, iwe.u.data.length, "p2p_cap=%02x%02x%02x%02x%c", ++ prTargetResult->ucDeviceCapabilityBitmap, prTargetResult->ucGroupCapabilityBitmap, ++ (UINT_8) prTargetResult->u2ConfigMethod, ++ (UINT_8) (prTargetResult->u2ConfigMethod >> 8), '\0'); ++ current_ev = ++ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); ++ ++ /* printk("%s\n", data); */ ++ kalMemZero(data, 40); ++ ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.flags = 0; ++ iwe.u.data.length = 13 + sizeof("p2p_dev_type="); ++ if (iwe.u.data.length > 40) ++ iwe.u.data.length = 40; ++ ++ snprintf(data, iwe.u.data.length, "p2p_dev_type=%02x%02x%02x%02x%02x%02x%c", ++ (UINT_8) prTargetResult->rPriDevType.u2CategoryID, ++ (UINT_8) prTargetResult->rPriDevType.u2SubCategoryID, ++ (UINT_8) prTargetResult->arSecDevType[0].u2CategoryID, ++ (UINT_8) prTargetResult->arSecDevType[0].u2SubCategoryID, ++ (UINT_8) prTargetResult->arSecDevType[1].u2CategoryID, ++ (UINT_8) prTargetResult->arSecDevType[1].u2SubCategoryID, '\0'); ++ current_ev = ++ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); ++ /* printk("%s\n", data); */ ++ ++ kalMemZero(data, 40); ++ ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.flags = 0; ++ iwe.u.data.length = 17 + sizeof("p2p_grp_bssid="); ++ if (iwe.u.data.length > 40) ++ iwe.u.data.length = 40; ++ ++ snprintf(data, iwe.u.data.length, "p2p_grp_bssid= %pM %c", ++ prTargetResult->aucBSSID, '\0'); ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); ++ /* printk("%s\n", data); */ ++ ++ } ++#endif ++ } ++ ++ /* Length of data */ ++ wrqu->data.length = (current_ev - extra); ++ wrqu->data.flags = 0; ++ ++ return 0; ++} /* end of mtk_p2p_wext_discovery_results() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_WSC_BEACON_PROBE_RSP_IE) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_HOSTAPD_PARAM prHostapdParam = (P_IW_P2P_HOSTAPD_PARAM) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ if (prHostapdParam->len > 0) { ++ if (prHostapdParam->len <= MAX_WSC_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[0], prHostapdParam->data, prHostapdParam->len)) { ++ return -EFAULT; ++ } ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[2], prHostapdParam->data, prHostapdParam->len)) { ++ return -EFAULT; ++ } ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ prGlueInfo->prP2PInfo->u2WSCIELen[0] = prHostapdParam->len; ++ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prHostapdParam->len; ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* @TODO: send message to P2P-FSM */ ++ ++ return 0; ++} /* end of mtk_p2p_wext_wsc_ie() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_CONNECT_DISCONNECT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++/* P_IW_P2P_CONNECT_DEVICE prConnectDevice = (P_IW_P2P_CONNECT_DEVICE)extra; */ ++/* P_MSG_HDR_T prMsgHdr; */ ++/* P_MSG_P2P_CONNECTION_REQUEST_T prMsgP2PConnReq; */ ++/* P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt; */ ++/* UINT_8 aucBCAddr[] = BC_MAC_ADDR; */ ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ if (prData->flags == P2P_CONNECT) { ++#if 0 ++ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_REQ */ ++ prMsgP2PConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ ++ if (!prMsgP2PConnReq) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnReq, MSG_SEND_METHOD_BUF); ++#endif ++ } else if (prData->flags == P2P_DISCONNECT) { ++#if 0 ++ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_ABORT */ ++ prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ ++ if (!prMsgP2PConnAbt) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prConnectDevice->sta_addr); ++ ++ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); ++#endif ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} /* end of mtk_p2p_wext_connect_disconnect() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_PASSWORD_READY) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_password_ready(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY) extra; ++ P_P2P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ /* retrieve IE for Probe Request */ ++ if (prPasswordReady->probe_req_len > 0) { ++ if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, ++ prPasswordReady->probe_req_len)) { ++ return -EFAULT; ++ } ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len; ++ ++ /* retrieve IE for Probe Response */ ++ if (prPasswordReady->probe_rsp_len > 0) { ++ if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, ++ prPasswordReady->probe_rsp_len)) { ++ return -EFAULT; ++ } ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len; ++ ++ switch (prPasswordReady->active_config_method) { ++ case 1: ++ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_PUSH_BUTTON; ++ break; ++ case 2: ++ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_KEYPAD; ++ break; ++ case 3: ++ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_DISPLAY; ++ break; ++ default: ++ break; ++ } ++ ++ prConnSettings->fgIsPasswordIDRdy = TRUE; ++ return 0; ++} /* end of mtk_p2p_wext_password_ready() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_REQ_DEVICE_INFO) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_DEVICE_REQ prDeviceReq = (P_IW_P2P_DEVICE_REQ) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* specify data length */ ++ wrqu->data.length = sizeof(IW_P2P_DEVICE_REQ); ++ ++ /* copy to upper-layer supplied buffer */ ++ kalMemCopy(prDeviceReq->name, prGlueInfo->prP2PInfo->aucConnReqDevName, ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ prDeviceReq->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; ++ prDeviceReq->name[prDeviceReq->name_len] = '\0'; ++ COPY_MAC_ADDR(prDeviceReq->device_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); ++ prDeviceReq->device_type = prGlueInfo->prP2PInfo->ucConnReqDevType; ++ prDeviceReq->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; ++ prDeviceReq->active_config_method = prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod; ++ ++ return 0; ++} /* end of mtk_p2p_wext_request_dev_info() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_IOCTL_INVITATION_INDICATE prInvIndicate = (P_IW_P2P_IOCTL_INVITATION_INDICATE) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* specify data length */ ++ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_INDICATE); ++ ++ /* copy to upper-layer supplied buffer */ ++ kalMemCopy(prInvIndicate->dev_name, prGlueInfo->prP2PInfo->aucConnReqDevName, ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ kalMemCopy(prInvIndicate->group_bssid, prGlueInfo->prP2PInfo->rConnReqGroupAddr, MAC_ADDR_LEN); ++ prInvIndicate->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; ++ prInvIndicate->dev_name[prInvIndicate->name_len] = '\0'; ++ COPY_MAC_ADDR(prInvIndicate->dev_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); ++ prInvIndicate->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; ++ prInvIndicate->operating_channel = prGlueInfo->prP2PInfo->ucOperatingChnl; ++ prInvIndicate->invitation_type = prGlueInfo->prP2PInfo->ucInvitationType; ++ ++ return 0; ++} /* end of mtk_p2p_wext_invitation_indicate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_status(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_IOCTL_INVITATION_STATUS prInvStatus = (P_IW_P2P_IOCTL_INVITATION_STATUS) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* specify data length */ ++ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_STATUS); ++ ++ /* copy to upper-layer supplied buffer */ ++ prInvStatus->status_code = prGlueInfo->prP2PInfo->u4InvStatus; ++ ++ return 0; ++} /* end of mtk_p2p_wext_invitation_status() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief indicate an event to supplicant for device found ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval TRUE Success. ++* \retval FALSE Failure ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_FND"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PDVCFND event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++ return FALSE; ++} /* end of kalP2PIndicateFound() */ ++ ++int ++mtk_p2p_wext_set_network_address(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @TODO: invoke wlan_p2p functions */ ++#if 0 ++ rStatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pNetworkAddress, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); ++#endif ++ ++ return 0; ++ ++} ++ ++int ++mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @TODO: invoke wlan_p2p functions */ ++#if 0 ++ rStatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); ++#endif ++ ++ return 0; ++ ++} ++ ++int ++mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @TODO: invoke wlan_p2p functions */ ++#if 0 ++ rStatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); ++#endif ++ ++ return 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_start_formation(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int i4Status = 0; ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++/* struct iw_point *prData = (struct iw_point*)&wrqu->data; */ ++ P_IW_P2P_IOCTL_START_FORMATION prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) NULL; ++ ++ do { ++ if ((prDev == NULL) || (extra == NULL)) { ++ ASSERT(FALSE); ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) extra; ++ ++ if (prGlueInfo == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ if (prAdapter == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return i4Status; ++ ++} ++ ++/* mtk_p2p_wext_start_formation */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_int(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int status = 0; ++ UINT_32 u4SubCmd = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 index; ++ INT_32 value; ++ PUINT_32 pu4IntBuf; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ UINT_32 u4Leng; ++ ++ ASSERT(prDev); ++ ASSERT(wrqu); ++ ++ /* printk("mtk_p2p_wext_set_int\n"); */ ++ pu4IntBuf = (PUINT_32) extra; ++ ++ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ u4SubCmd = (UINT_32) wrqu->mode; ++ index = pu4IntBuf[1]; ++ value = pu4IntBuf[2]; ++ ++ DBGLOG(P2P, INFO, "set parameter, u4SubCmd=%d idx=%d value=%d\n", (INT_16) u4SubCmd, (INT_16) index, value); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_INT_P2P_SET: ++ switch (index) { ++ case 0: /* Listen CH */ ++ { ++ UINT_8 ucSuggestChnl = 0; ++ ++ prP2pConnSettings->ucListenChnl = value; ++ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ if (rlmFuncFindAvailableChannel ++ (prGlueInfo->prAdapter, value, &ucSuggestChnl, TRUE, TRUE)) { ++ prP2pSpecificBssInfo->ucListenChannel = value; ++ } else { ++ prP2pSpecificBssInfo->ucListenChannel = ucSuggestChnl; ++ } ++ ++ break; ++ } ++ case 1: /* P2p mode */ ++ break; ++ case 4: /* Noa duration */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, ++ (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 5: /* Noa interval */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, ++ (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 6: /* Noa count */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; ++ status = ++ mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); ++ break; ++ case 100: /* Oper CH */ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ prP2pConnSettings->ucOperatingChnl = value; ++ break; ++ case 101: /* Local config Method, for P2P SDK */ ++ /* prP2pConnSettings->u2LocalConfigMethod; */ ++ break; ++ case 102: /* Sigma P2p reset */ ++ kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); ++ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ ++ break; ++ case 103: /* WPS MODE */ ++ kalP2PSetWscMode(prGlueInfo, value); ++ break; ++ case 104: /* P2p send persence, duration */ ++ break; ++ case 105: /* P2p send persence, interval */ ++ break; ++ case 106: /* P2P set sleep */ ++ value = 1; ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, ++ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ case 107: /* P2P set opps, CTWindowl */ ++ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; ++ status = ++ mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rOppPsParam); ++ break; ++ case 108: /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, ++ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ ++ break; ++ ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int status = 0; ++ UINT_32 u4SubCmd = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; ++ ++ ASSERT(prDev); ++ ASSERT(wrqu); ++ ++ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ u4SubCmd = (UINT_32) wrqu->data.flags; ++ ++ kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0], sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_OID: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ ++ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) ++ DBGLOG(P2P, INFO, "extra buffer is valid\n"); ++ else ++ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_SEND_SD_RESPONSE: ++ status = mtk_p2p_wext_send_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_SEND_SD_REQUEST: ++ status = mtk_p2p_wext_send_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_TERMINATE_SD_PHASE: ++ status = mtk_p2p_wext_terminate_service_discovery_phase(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_INVITATION: ++ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_INVITATION_STRUCT)) { ++ /* Do nothing */ ++ /* status = mtk_p2p_wext_invitation_request(prDev, info, wrqu, ++ (char *)(prP2PReq->aucBuffer)); */ ++ } ++ break; ++ ++ case P2P_CMD_ID_INVITATION_ABORT: ++ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_ABORT_INVITATION)) { ++ /* Do nothing */ ++ /* status = mtk_p2p_wext_invitation_abort(prDev, info, wrqu, ++ (char *)(prP2PReq->aucBuffer)); */ ++ } ++ break; ++ ++ case P2P_CMD_ID_START_FORMATION: ++ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_START_FORMATION)) ++ status = mtk_p2p_wext_start_formation(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ } ++ ++ break; ++#if CFG_SUPPORT_ANTI_PIRACY ++ case PRIV_SEC_CHECK_OID: ++ if (wrqu->data.length > 256) { ++ status = -EOPNOTSUPP; ++ break; ++ } ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), wrqu->data.pointer, wrqu->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ ++ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length)) ++ DBGLOG(P2P, INFO, "extra buffer is valid\n"); ++ else ++ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_SEC_CHECK: ++ status = mtk_p2p_wext_set_sec_check_request(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ } ++ break; ++#endif ++ case PRIV_CMD_P2P_VERSION: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ ++ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) ++ DBGLOG(P2P, INFO, "extra buffer is valid\n"); ++ else ++ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_P2P_VERSION: ++ status = mtk_p2p_wext_set_p2p_version(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ break; ++ } ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ break; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int status = 0; ++ UINT_32 u4SubCmd = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; ++ ++ ASSERT(prDev); ++ ASSERT(wrqu); ++ ++ if (!prDev || !wrqu) { ++ DBGLOG(P2P, WARN, "%s(): invalid param(0x%p, 0x%p)\n", __func__, prDev, wrqu); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ u4SubCmd = (UINT_32) wrqu->data.flags; ++ ++ kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_OID: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { ++ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); ++ return -EFAULT; ++ } ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_GET_SD_REQUEST: ++ status = mtk_p2p_wext_get_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_GET_SD_RESPONSE: ++ status = mtk_p2p_wext_get_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_INVITATION_INDICATE: ++ { ++ status = ++ mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); ++ prP2PReq->outBufferLength = wrqu->data.length; ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++ break; ++ } ++ case P2P_CMD_ID_INVITATION_STATUS: ++ { ++ status = ++ mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); ++ prP2PReq->outBufferLength = wrqu->data.length; ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++ break; ++ } ++ case P2P_CMD_ID_GET_CH_LIST: ++ { ++ UINT_16 i; ++ UINT_8 NumOfChannel = 50; ++ RF_CHANNEL_INFO_T aucChannelList[50]; ++ UINT_8 ucMaxChannelNum = 50; ++ PUINT_8 pucChnlList = (PUINT_8) prP2PReq->aucBuffer; ++ ++ kalGetChnlList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList); ++ if (NumOfChannel > 50) ++ NumOfChannel = 50; ++ prP2PReq->outBufferLength = NumOfChannel; ++ /*here must confirm NumOfChannel < 16, for prP2PReq->aucBuffer 16 byte*/ ++ if (NumOfChannel >= 15) { ++ /*DBGLOG(P2P, ERROR, "channel num > 15\n", __func__);*/ ++ ASSERT(FALSE); ++ } ++ ++ for (i = 0; i < NumOfChannel; i++) { ++#if 0 ++ /* 20120208 frog: modify to avoid clockwork warning. */ ++ prP2PReq->aucBuffer[i] = aucChannelList[i].ucChannelNum; ++#else ++ *pucChnlList = aucChannelList[i].ucChannelNum; ++ pucChnlList++; ++#endif ++ } ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ NumOfChannel + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++ break; ++ } ++ ++ case P2P_CMD_ID_GET_OP_CH: ++ { ++ prP2PReq->inBufferLength = 4; ++ ++ status = wlanoidQueryP2pOpChannel(prGlueInfo->prAdapter, ++ prP2PReq->aucBuffer, ++ prP2PReq->inBufferLength, &prP2PReq->outBufferLength); ++ ++ if (status == 0) { /* WLAN_STATUS_SUCCESS */ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, ++ aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } else { ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } ++ break; ++ } ++ ++ default: ++ status = -EOPNOTSUPP; ++ } ++ ++ break; ++#if CFG_SUPPORT_ANTI_PIRACY ++ case PRIV_SEC_CHECK_OID: ++ if (wrqu->data.length > 256) { ++ status = -EOPNOTSUPP; ++ break; ++ } ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), ++ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { ++ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); ++ return -EFAULT; ++ } ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_SEC_CHECK: ++ status = mtk_p2p_wext_get_sec_check_response(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ } ++ break; ++#endif ++ case PRIV_CMD_P2P_VERSION: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { ++ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); ++ return -EFAULT; ++ } ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_P2P_VERSION: ++ status = mtk_p2p_wext_get_p2p_version(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ break; ++ } ++ ++ /* Copy queried data to user. */ ++ if (status == 0) { /* WLAN_STATUS_SUCCESS */ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } ++ ++ else { ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } ++ ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* getting service discovery request frame from driver ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidGetP2PSDRequest, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prP2PReq->outBufferLength = u4QueryInfoLen; ++ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* getting service discovery response frame from driver ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidGetP2PSDResponse, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prP2PReq->outBufferLength = u4QueryInfoLen; ++ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ return 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* sending service discovery request frame ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSendP2PSDRequest, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* sending service discovery response frame ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSendP2PSDResponse, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetSecCheckRequest, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_wext_get_sec_check_response\n"); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidGetSecCheckResponse, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prP2PReq->outBufferLength = u4QueryInfoLen; ++ ++ if (copy_to_user(wrqu->data.pointer, ++ prP2PReq->aucBuffer, u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ return 0; ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* terminating service discovery phase ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2PTerminateSDPhase, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ /* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ ++ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_noa_param\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetNoaParam, prNoaParam, /* prP2PReq->aucBuffer, */ ++ sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ ++ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++/* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ ++ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_oppps_param\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetOppPsParam, prOppPsParam, /* prP2PReq->aucBuffer, */ ++ sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ ++ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++int ++mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ UINT_32 u4SetInfoLen; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pSupplicantVersion, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return rStatus; ++ ++} ++ ++/* mtk_p2p_wext_set_p2p_version */ ++ ++int ++mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryP2pVersion, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return rStatus; ++ ++} /* mtk_p2p_wext_get_p2p_version */ ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ ++int ++mtk_p2p_wext_get_rssi(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ UINT_16 u2BufferSize = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rssi; ++ struct iw_statistics *pStats = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ if (!prGlueInfo) { ++ rStatus = WLAN_STATUS_FAILURE; ++ goto stat_out; ++ } ++ ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ u2BufferSize = prData->length; ++ ++ if (u2BufferSize < sizeof(struct iw_statistics)) ++ return -E2BIG; ++ ++ if (copy_to_user(prData->pointer, pStats, sizeof(struct iw_statistics))) ++ rStatus = WLAN_STATUS_FAILURE; ++ ++stat_out: ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return rStatus; ++ ++} /* mtk_p2p_wext_get_rssi */ ++ ++struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_statistics *pStats = NULL; ++ INT_32 i4Rssi; ++ UINT_32 bufLen = 0; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) ++ goto stat_out; ++ ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); ++ ++ if (!prDev || !netif_carrier_ok(prDev)) { ++ /* network not connected */ ++ goto stat_out; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &bufLen); ++ ++stat_out: ++ return pStats; ++} /* mtk_p2p_wext_get_wireless_stats */ ++ ++#endif /* CFG_SUPPORT_P2P_RSSI_QUERY */ ++ ++int ++mtk_p2p_wext_set_txpow(IN struct net_device *prDev, ++ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++#if 0 ++ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; ++#endif ++ int i4Ret = 0; ++ ++ ASSERT(prDev); ++ ASSERT(prTxPow); ++ ++ do { ++ if ((!prDev) || (!prTxPow)) { ++ i4Ret = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ if (!prGlueInfo) { ++ i4Ret = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++#if 0 ++ prMsgFuncSwitch = ++ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ if (!prMsgFuncSwitch) { ++ ASSERT(0); ++ return -ENOMEM; ++ } ++ ++ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ ++ if (prTxPow->disabled) { ++ /* Dissolve. */ ++ prMsgFuncSwitch->fgIsFuncOn = FALSE; ++ } else { ++ ++ /* Re-enable function. */ ++ prMsgFuncSwitch->fgIsFuncOn = TRUE; ++ } ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ ++ } while (FALSE); ++ ++ return i4Ret; ++} /* mtk_p2p_wext_set_txpow */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c +new file mode 100644 +index 000000000000..4d71e0c59b05 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c +@@ -0,0 +1,1935 @@ ++/* ++** Id: @(#) gl_p2p_cfg80211.c@@ ++*/ ++ ++/*! \file gl_p2p_cfg80211.c ++ \brief Main routines of Linux driver interface for Wi-Fi Direct ++ using cfg80211 interface ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_p2p_cfg80211.c ++** ++** 01 30 2013 yuche.tsai ++** [ALPS00455459] [GN_WIFI]??wifi direct??????????? ++** Fix possible race condition under GO mode. ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 09 05 2012 wh.su ++** [ALPS00351547] [6577JB][WiFi direct]The 3rd device fail to establish p2p connection with GO sometimes ++** sync with the ICS code. ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, ++** one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 08 21 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 20 2012 yuche.tsai ++** NULL ++** Fix possible KE issue. ++** ++** 08 17 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 16 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** Fix p2p bug find on ALPS.JB trunk. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "config.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "precomp.h" ++#include "gl_cfg80211.h" ++#include "gl_p2p_ioctl.h" ++ ++#ifdef __GNUC__ ++#pragma GCC diagnostic ignored "-Wformat" ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++BOOLEAN ++mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, ++ IN enum nl80211_channel_type channel_type, ++ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ P2P_PARAM_KEY_T rKey; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ kalMemZero(&rKey, sizeof(P2P_PARAM_KEY_T)); ++ ++ rKey.u4KeyIndex = key_index; ++ if (mac_addr) { ++ ether_addr_copy(rKey.arBSSID, mac_addr); ++ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && ++ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ } ++ if (rKey.arBSSID[0] != 0xFF) { ++ rKey.u4KeyIndex |= BIT(31); ++ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || ++ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) ++ rKey.u4KeyIndex |= BIT(30); ++ } else { ++ rKey.u4KeyIndex |= BIT(31); ++ } ++ } else { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ rKey.u4KeyIndex |= BIT(31); /* ???? */ ++ } ++ if (params->key) { ++ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ ++ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); ++ } ++ rKey.u4KeyLength = params->key_len; ++ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddP2PKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ if (rStatus == WLAN_STATUS_SUCCESS) ++ i4Rslt = 0; ++ ++ return i4Rslt; ++} ++ ++int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) ++) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, ++ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_REMOVE_KEY_T prRemoveKey; ++ INT_32 i4Rslt = -EINVAL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ i4Rslt = 0; ++ return i4Rslt; ++ } ++ ++ kalMemZero(&prRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); ++ if (mac_addr) ++ memcpy(prRemoveKey.arBSSID, mac_addr, PARAM_MAC_ADDR_LEN); ++ prRemoveKey.u4KeyIndex = key_index; ++ prRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveP2PKey, ++ &prRemoveKey, prRemoveKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) ++ i4Rslt = 0; ++ ++ return i4Rslt; ++} ++ ++int ++mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, ++ struct net_device *netdev, u8 key_index, bool unicast, bool multicast) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_info *sinfo) ++{ ++ INT_32 i4RetRslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; ++ P2P_STATION_INFO_T rP2pStaInfo; ++ ++ ASSERT(wiphy); ++ ++ do { ++ if ((wiphy == NULL) || (ndev == NULL) || (sinfo == NULL) || (mac == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_get_station\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ prP2pGlueInfo = prGlueInfo->prP2PInfo; ++ ++ sinfo->filled = 0; ++ ++ /* Get station information. */ ++ /* 1. Inactive time? */ ++ p2pFuncGetStationInfo(prGlueInfo->prAdapter, (PUINT_8)mac, &rP2pStaInfo); ++ ++ /* Inactive time. */ ++ sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME; ++ sinfo->inactive_time = rP2pStaInfo.u4InactiveTime; ++ sinfo->generation = prP2pGlueInfo->i4Generation; ++ ++ i4RetRslt = 0; ++ } while (FALSE); ++ ++ return i4RetRslt; ++} ++ ++int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; ++ P_MSG_P2P_SCAN_REQUEST_T prMsgScanRequest = (P_MSG_P2P_SCAN_REQUEST_T) NULL; ++ UINT_32 u4MsgSize = 0, u4Idx = 0; ++ INT_32 i4RetRslt = -EINVAL; ++ P_RF_CHANNEL_INFO_T prRfChannelInfo = (P_RF_CHANNEL_INFO_T) NULL; ++ P_P2P_SSID_STRUCT_T prSsidStruct = (P_P2P_SSID_STRUCT_T) NULL; ++ struct ieee80211_channel *prChannel = NULL; ++ struct cfg80211_ssid *prSsid = NULL; ++ ++ /* [---------Channel---------] [---------SSID---------][---------IE---------] */ ++ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan\n"); ++ ++ do { ++ if ((wiphy == NULL) || (request == NULL)) ++ break; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prP2pGlueInfo = prGlueInfo->prP2PInfo; ++ ++ if (prP2pGlueInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_scan.\n"); ++ ++ if (prP2pGlueInfo->prScanRequest != NULL) { ++ /* There have been a scan request on-going processing. */ ++ DBGLOG(P2P, TRACE, "There have been a scan request on-going processing.\n"); ++ break; ++ } ++ ++ prP2pGlueInfo->prScanRequest = request; ++ ++ /* Should find out why the n_channels so many? */ ++ if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) { ++ request->n_channels = MAXIMUM_OPERATION_CHANNEL_LIST; ++ DBGLOG(P2P, TRACE, "Channel list exceed the maximun support.\n"); ++ } ++ ++ u4MsgSize = sizeof(MSG_P2P_SCAN_REQUEST_T) + ++ (request->n_channels * sizeof(RF_CHANNEL_INFO_T)) + ++ (request->n_ssids * sizeof(PARAM_SSID_T)) + request->ie_len; ++ ++ prMsgScanRequest = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, u4MsgSize); ++ ++ if (prMsgScanRequest == NULL) { ++ ASSERT(FALSE); ++ i4RetRslt = -ENOMEM; ++ prP2pGlueInfo->prScanRequest = NULL; ++ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan Allocate Mem failed\n"); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "Generating scan request message.\n"); ++ ++ prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; ++ ++ DBGLOG(P2P, INFO, "Requesting channel number:%d.\n", request->n_channels); ++ ++ for (u4Idx = 0; u4Idx < request->n_channels; u4Idx++) { ++ /* Translate Freq from MHz to channel number. */ ++ prRfChannelInfo = &(prMsgScanRequest->arChannelListInfo[u4Idx]); ++ prChannel = request->channels[u4Idx]; ++ ++ prRfChannelInfo->ucChannelNum = nicFreq2ChannelNum(prChannel->center_freq * 1000); ++ DBGLOG(P2P, TRACE, "Scanning Channel:%d, freq: %d\n", ++ prRfChannelInfo->ucChannelNum, prChannel->center_freq); ++ switch (prChannel->band) { ++ case NL80211_BAND_2GHZ: ++ prRfChannelInfo->eBand = BAND_2G4; ++ break; ++ case NL80211_BAND_5GHZ: ++ prRfChannelInfo->eBand = BAND_5G; ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "UNKNOWN Band info from supplicant\n"); ++ prRfChannelInfo->eBand = BAND_NULL; ++ break; ++ } ++ ++ /* Iteration. */ ++ prRfChannelInfo++; ++ } ++ prMsgScanRequest->u4NumChannel = request->n_channels; ++ ++ DBGLOG(P2P, TRACE, "Finish channel list.\n"); ++ ++ /* SSID */ ++ prSsid = request->ssids; ++ prSsidStruct = (P_P2P_SSID_STRUCT_T) prRfChannelInfo; ++ if (prSsidStruct) { ++ if (request->n_ssids) { ++ ASSERT((ULONG) prSsidStruct == (ULONG)&(prMsgScanRequest->arChannelListInfo[u4Idx])); ++ prMsgScanRequest->prSSID = prSsidStruct; ++ } ++ ++ for (u4Idx = 0; u4Idx < request->n_ssids; u4Idx++) { ++ COPY_SSID(prSsidStruct->aucSsid, ++ prSsidStruct->ucSsidLen, request->ssids->ssid, request->ssids->ssid_len); ++ ++ prSsidStruct++; ++ prSsid++; ++ } ++ ++ prMsgScanRequest->i4SsidNum = request->n_ssids; ++ ++ DBGLOG(P2P, TRACE, "Finish SSID list:%d.\n", request->n_ssids); ++ ++ /* IE BUFFERS */ ++ prMsgScanRequest->pucIEBuf = (PUINT_8) prSsidStruct; ++ if (request->ie_len) { ++ kalMemCopy(prMsgScanRequest->pucIEBuf, request->ie, request->ie_len); ++ prMsgScanRequest->u4IELen = request->ie_len; ++ } ++ } ++ ++ DBGLOG(P2P, TRACE, "Finish IE Buffer.\n"); ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = FALSE; ++#endif ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgScanRequest, MSG_SEND_METHOD_BUF); ++ ++ i4RetRslt = 0; ++ } while (FALSE); ++ ++ return i4RetRslt; ++} /* mtk_p2p_cfg80211_scan */ ++ ++int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ do { ++ if (wiphy == NULL) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_wiphy_params\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ if (changed & WIPHY_PARAM_RETRY_SHORT) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY short param is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_RETRY_LONG) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY long param is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY fragmentation threshold is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_RTS_THRESHOLD) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY RTS threshold is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_COVERAGE_CLASS) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The coverage class is changed???\n"); ++ } ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_set_wiphy_params */ ++ ++int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ enum nl80211_tx_power_setting type, int mbm) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ int *dbm) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 value; ++ UINT_32 u4Leng; ++ ++ ASSERT(wiphy); ++ ++ if (enabled) ++ value = 2; ++ else ++ value = 0; ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_power_mgmt ps=%d.\n", enabled); ++ ++ /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ return 0; ++} ++ ++/* &&&&&&&&&&&&&&&&&&&&&&&&&& Add for ICS Wi-Fi Direct Support. &&&&&&&&&&&&&&&&&&&&&&& */ ++int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; ++ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ /* P_IE_SSID_T prSsidIE = (P_IE_SSID_T)NULL; */ ++ ++ struct wireless_dev *wdev = dev->ieee80211_ptr; ++ struct cfg80211_chan_def *chandef = &wdev->preset_chandef; ++ ++ do { ++ if ((wiphy == NULL) || (settings == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_start_ap.\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++#if 1 ++ mtk_p2p_cfg80211_set_channel(wiphy, chandef); ++#else ++ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->ucOperatingChnl = ++ (chandef->chan->center_freq - 2407) / 5; ++ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->eBand = BAND_2G4; ++#endif ++ ++ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_BEACON_UPDATE_T) + ++ settings->beacon.head_len + ++ settings->beacon.tail_len)); ++ ++ if (prP2pBcnUpdateMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; ++ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; ++ ++ if (settings->beacon.head_len != 0) { ++ kalMemCopy(pucBuffer, settings->beacon.head, settings->beacon.head_len); ++ ++ prP2pBcnUpdateMsg->u4BcnHdrLen = settings->beacon.head_len; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) settings->beacon.head_len); ++ } else { ++ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = NULL; ++ } ++ ++ if (settings->beacon.tail_len != 0) { ++ UINT_32 ucLen = settings->beacon.tail_len; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; ++ ++ /*Add TIM IE */ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; ++ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ ++ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; ++ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; ++ /* will be overwrite by FW */ ++ ucLen += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ kalMemCopy(pucBuffer, settings->beacon.tail, settings->beacon.tail_len); ++ ++ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; ++ } else { ++ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = NULL; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); ++ ++ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_START_AP_T)); ++ ++ if (prP2pStartAPMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pStartAPMsg->rMsgHdr.eMsgId = MID_MNY_P2P_START_AP; ++ ++ prP2pStartAPMsg->fgIsPrivacy = settings->privacy; ++ ++ prP2pStartAPMsg->u4BcnInterval = settings->beacon_interval; ++ ++ prP2pStartAPMsg->u4DtimPeriod = settings->dtim_period; ++ ++ /* Copy NO SSID. */ ++ prP2pStartAPMsg->ucHiddenSsidType = settings->hidden_ssid; ++ ++ COPY_SSID(prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen, settings->ssid, settings->ssid_len); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pStartAPMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); ++#endif ++ ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++/* /////////////////////// */ ++ /** ++ * struct cfg80211_ap_settings - AP configuration ++ * ++ * Used to configure an AP interface. ++ * ++ * @beacon: beacon data ++ * @beacon_interval: beacon interval ++ * @dtim_period: DTIM period ++ * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from ++ * user space) ++ * @ssid_len: length of @ssid ++ * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames ++ * @crypto: crypto settings ++ * @privacy: the BSS uses privacy ++ * @auth_type: Authentication type (algorithm) ++ * @inactivity_timeout: time in seconds to determine station's inactivity. ++ */ ++/* struct cfg80211_ap_settings { */ ++/* struct cfg80211_beacon_data beacon; */ ++/* */ ++/* int beacon_interval, dtim_period; */ ++/* const u8 *ssid; */ ++/* size_t ssid_len; */ ++/* enum nl80211_hidden_ssid hidden_ssid; */ ++/* struct cfg80211_crypto_settings crypto; */ ++/* bool privacy; */ ++/* enum nl80211_auth_type auth_type; */ ++/* int inactivity_timeout; */ ++/* }; */ ++/* ////////////////// */ ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_start_ap */ ++ ++int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (info == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_beacon.\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_BEACON_UPDATE_T) + ++ info->head_len + info->tail_len)); ++ ++ if (prP2pBcnUpdateMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; ++ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; ++ ++ if (info->head_len != 0) { ++ kalMemCopy(pucBuffer, info->head, info->head_len); ++ ++ prP2pBcnUpdateMsg->u4BcnHdrLen = info->head_len; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) info->head_len); ++ } else { ++ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = NULL; ++ } ++ ++ if (info->tail_len != 0) { ++ UINT_32 ucLen = info->tail_len; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; ++ ++ /*Add TIM IE */ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; ++ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ ++ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; ++ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; ++ /* will be overwrite by FW */ ++ ucLen += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ kalMemCopy(pucBuffer, info->tail, info->tail_len); ++ ++ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; ++ } else { ++ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = NULL; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); ++ ++/* ////////////////////////// */ ++/** ++ * struct cfg80211_beacon_data - beacon data ++ * @head: head portion of beacon (before TIM IE) ++ * or %NULL if not changed ++ * @tail: tail portion of beacon (after TIM IE) ++ * or %NULL if not changed ++ * @head_len: length of @head ++ * @tail_len: length of @tail ++ * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL ++ * @beacon_ies_len: length of beacon_ies in octets ++ * @proberesp_ies: extra information element(s) to add into Probe Response ++ * frames or %NULL ++ * @proberesp_ies_len: length of proberesp_ies in octets ++ * @assocresp_ies: extra information element(s) to add into (Re)Association ++ * Response frames or %NULL ++ * @assocresp_ies_len: length of assocresp_ies in octets ++ * @probe_resp_len: length of probe response template (@probe_resp) ++ * @probe_resp: probe response template (AP mode only) ++ */ ++/* struct cfg80211_beacon_data { */ ++/* const u8 *head, *tail; */ ++/* const u8 *beacon_ies; */ ++/* const u8 *proberesp_ies; */ ++/* const u8 *assocresp_ies; */ ++/* const u8 *probe_resp; */ ++ ++/* size_t head_len, tail_len; */ ++/* size_t beacon_ies_len; */ ++/* size_t proberesp_ies_len; */ ++/* size_t assocresp_ies_len; */ ++/* size_t probe_resp_len; */ ++/* }; */ ++ ++/* ////////////////////////// */ ++ ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_change_beacon */ ++ ++int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_SWITCH_OP_MODE_T prP2pSwitchMode = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; ++ ++ do { ++ if (wiphy == NULL) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_stop_ap.\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* Switch OP MOde. */ ++ prP2pSwitchMode = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_SWITCH_OP_MODE_T)); ++ ++ if (prP2pSwitchMode == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pSwitchMode->rMsgHdr.eMsgId = MID_MNY_P2P_STOP_AP; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pSwitchMode, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); ++#endif ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_stop_ap */ ++ ++/* TODO: */ ++int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_deauth.\n"); ++ ++ return -EINVAL; ++} /* mtk_p2p_cfg80211_deauth */ ++ ++/* TODO: */ ++int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_disassoc.\n"); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} /* mtk_p2p_cfg80211_disassoc */ ++ ++int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, ++ unsigned int duration, u64 *cookie) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ P_MSG_P2P_CHNL_REQUEST_T prMsgChnlReq = (P_MSG_P2P_CHNL_REQUEST_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) ++ break; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ *cookie = prGlueP2pInfo->u8Cookie++; ++ ++ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_REQUEST_T)); ++ ++ if (prMsgChnlReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_remain_on_channel\n"); ++ ++ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ; ++ prMsgChnlReq->u8Cookie = *cookie; ++ prMsgChnlReq->u4Duration = duration; ++ ++ mtk_p2p_cfg80211func_channel_format_switch(chan, NL80211_CHAN_HT20, /* 4 KH Need Check */ ++ &prMsgChnlReq->rChannelInfo, &prMsgChnlReq->eChnlSco); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} ++ ++/* mtk_p2p_cfg80211_remain_on_channel */ ++int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ u64 cookie) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_MSG_P2P_CHNL_ABORT_T prMsgChnlAbort = (P_MSG_P2P_CHNL_ABORT_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL)) ++ break; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_ABORT_T)); ++ ++ if (prMsgChnlAbort == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_cancel_remain_on_channel\n"); ++ ++ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT; ++ prMsgChnlAbort->u8Cookie = cookie; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_cancel_remain_on_channel */ ++ ++int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prMsgExtListenReq = NULL; ++ P_MSG_P2P_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; ++ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; ++ PUINT_8 pucFrameBuf = (PUINT_8) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) ++ break; ++ /* DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_mgmt_tx\n")); */ ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ *cookie = prGlueP2pInfo->u8Cookie++; ++ ++ /* Channel & Channel Type & Wait time are ignored. */ ++ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_MGMT_TX_REQUEST_T)); ++ ++ if (prMsgTxReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ /* Here need to extend the listen interval */ ++ prMsgExtListenReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T)); ++ if (prMsgExtListenReq) { ++ prMsgExtListenReq->rMsgHdr.eMsgId = MID_MNY_P2P_EXTEND_LISTEN_INTERVAL; ++ prMsgExtListenReq->wait = params->wait; ++ DBGLOG(P2P, INFO, "ext listen, wait: %d\n", prMsgExtListenReq->wait); ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T)prMsgExtListenReq, ++ MSG_SEND_METHOD_BUF); ++ } ++ ++ prMsgTxReq->fgNoneCckRate = FALSE; ++ prMsgTxReq->fgIsWaitRsp = TRUE; ++ ++ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); ++ ++ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; ++ if (prMsgTxReq->prMgmtMsduInfo == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgTxReq->u8Cookie = *cookie; ++ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX; ++ ++ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); ++ ++ kalMemCopy(pucFrameBuf, params->buf, params->len); ++ ++ prMgmtFrame->u2FrameLength = params->len; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { ++ if (prMsgTxReq->prMgmtMsduInfo != NULL) ++ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); ++ ++ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); ++ } ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_mgmt_tx */ ++ ++int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ switch (params->use_cts_prot) { ++ case -1: ++ DBGLOG(P2P, TRACE, "CTS protection no change\n"); ++ break; ++ case 0: ++ DBGLOG(P2P, TRACE, "CTS protection disable.\n"); ++ break; ++ case 1: ++ DBGLOG(P2P, TRACE, "CTS protection enable\n"); ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "CTS protection unknown\n"); ++ break; ++ } ++ ++ switch (params->use_short_preamble) { ++ case -1: ++ DBGLOG(P2P, TRACE, "Short prreamble no change\n"); ++ break; ++ case 0: ++ DBGLOG(P2P, TRACE, "Short prreamble disable.\n"); ++ break; ++ case 1: ++ DBGLOG(P2P, TRACE, "Short prreamble enable\n"); ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Short prreamble unknown\n"); ++ break; ++ } ++ ++#if 0 ++ /* not implemented yet */ ++ p2pFuncChangeBssParam(prGlueInfo->prAdapter, ++ prBssInfo->fgIsProtection, ++ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortSlotTime, ++ /* Basic rates */ ++ /* basic rates len */ ++ /* ap isolate */ ++ /* ht opmode. */ ++ ); ++#else ++ i4Rslt = 0; ++#endif ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_change_bss */ ++ ++int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params) ++//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_CONNECTION_ABORT_T prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ UINT_8 aucBcMac[] = BC_MAC_ADDR; ++ const UINT_8 *mac = NULL; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL)) ++ break; ++ ++ if (params->mac == NULL) ++ mac = aucBcMac; ++ else ++ mac = params->mac; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_del_station.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(MSG_P2P_CONNECTION_ABORT_T), ++ VIR_MEM_TYPE); */ ++ prDisconnectMsg = ++ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ ++ if (prDisconnectMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); ++ prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnectMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++} /* mtk_p2p_cfg80211_del_station */ ++ ++int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL) || (sme == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_connect.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prConnReqMsg = ++ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_CONNECTION_REQUEST_T) + sme->ie_len)); ++ ++ if (prConnReqMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prConnReqMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; ++ ++ COPY_SSID(prConnReqMsg->rSsid.aucSsid, prConnReqMsg->rSsid.ucSsidLen, sme->ssid, sme->ssid_len); ++ ++ COPY_MAC_ADDR(prConnReqMsg->aucBssid, sme->bssid); ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_connect to %pM, IE len: %d\n", ++ prConnReqMsg->aucBssid, sme->ie_len); ++ ++ DBGLOG(P2P, TRACE, "Assoc Req IE Buffer Length:%d\n", sme->ie_len); ++ kalMemCopy(prConnReqMsg->aucIEBuf, sme->ie, sme->ie_len); ++ prConnReqMsg->u4IELen = sme->ie_len; ++ ++ mtk_p2p_cfg80211func_channel_format_switch(sme->channel, ++ NL80211_CHAN_NO_HT, ++ &prConnReqMsg->rChannelInfo, &prConnReqMsg->eChnlSco); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prConnReqMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_connect */ ++ ++int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL)) ++ break; ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++/* prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(P_MSG_P2P_CONNECTION_ABORT_T), VIR_MEM_TYPE); */ ++ prDisconnMsg = ++ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ ++ if (prDisconnMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.Allocate Memory Failed.\n"); ++ break; ++ } ++ ++ prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ prDisconnMsg->u2ReasonCode = reason_code; ++ prDisconnMsg->fgSendDeauth = TRUE; ++ COPY_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCAddr); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_disconnect */ ++ ++int ++mtk_p2p_cfg80211_change_iface(IN struct wiphy *wiphy, ++ IN struct net_device *ndev, ++ IN enum nl80211_iftype type,/* IN u32 *flags,*/ IN struct vif_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchModeMsg = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (ndev == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_iface.\n"); ++ ++ if (ndev->ieee80211_ptr) ++ ndev->ieee80211_ptr->iftype = type; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* Switch OP MOde. */ ++ prSwitchModeMsg = ++ (P_MSG_P2P_SWITCH_OP_MODE_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_SWITCH_OP_MODE_T)); ++ ++ if (prSwitchModeMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ ++ switch (type) { ++ case NL80211_IFTYPE_P2P_CLIENT: ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n"); ++ case NL80211_IFTYPE_STATION: ++ if (type == NL80211_IFTYPE_STATION) ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n"); ++ prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; ++ break; ++ case NL80211_IFTYPE_AP: ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n"); ++ case NL80211_IFTYPE_P2P_GO: ++ if (type == NL80211_IFTYPE_P2P_GO) ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_GO not AP.\n"); ++ prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Other type :%d .\n", type); ++ prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE; ++ break; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSwitchModeMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++} /* mtk_p2p_cfg80211_change_iface */ ++ ++int mtk_p2p_cfg80211_set_channel(IN struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ RF_CHANNEL_INFO_T rRfChnlInfo; ++ ++ do { ++ if (wiphy == NULL) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_channel.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ mtk_p2p_cfg80211func_channel_format_switch(chandef->chan, chandef->width, &rRfChnlInfo, NULL); ++ p2pFuncSetChannel(prGlueInfo->prAdapter, &rRfChnlInfo); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++} ++ ++/* mtk_p2p_cfg80211_set_channel */ ++ ++int ++mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, ++ IN struct net_device *dev, ++ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL) || (mask == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_bitrate_mask\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* TODO: Set bitrate mask of the peer? */ ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_set_bitrate_mask */ ++ ++void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ IN u16 frame_type, IN bool reg) ++{ ++#if 0 ++ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; ++#endif ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_mgmt_frame_register\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ switch (frame_type) { ++ case MAC_FRAME_PROBE_REQ: ++ if (reg) { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); ++ } else { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); ++ } ++ break; ++ case MAC_FRAME_ACTION: ++ if (reg) { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); ++ } else { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); ++ } ++ break; ++ default: ++ DBGLOG(P2P, ERROR, "Ask frog to add code for mgmt:%x\n", frame_type); ++ break; ++ } ++ ++ if ((prGlueInfo->prAdapter != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { ++ ++ /* prGlueInfo->u4Flag |= GLUE_FLAG_FRAME_FILTER; */ ++ set_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ if (in_interrupt()) ++ DBGLOG(P2P, TRACE, "It is in interrupt level\n"); ++ } ++#if 0 ++ ++ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ sizeof ++ (MSG_P2P_MGMT_FRAME_REGISTER_T)); ++ ++ if (prMgmtFrameRegister == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; ++ ++ prMgmtFrameRegister->u2FrameType = frame_type; ++ prMgmtFrameRegister->fgIsRegister = reg; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); ++ ++#endif ++ ++ } while (FALSE); ++ ++} /* mtk_p2p_cfg80211_mgmt_frame_register */ ++ ++BOOLEAN ++mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, ++ IN enum nl80211_channel_type channel_type, ++ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco) ++{ ++ BOOLEAN fgIsValid = FALSE; ++ ++ do { ++ if (channel == NULL) ++ break; ++ ++ if (prRfChnlInfo) { ++ prRfChnlInfo->ucChannelNum = nicFreq2ChannelNum(channel->center_freq * 1000); ++ ++ switch (channel->band) { ++ case NL80211_BAND_2GHZ: ++ prRfChnlInfo->eBand = BAND_2G4; ++ break; ++ case NL80211_BAND_5GHZ: ++ prRfChnlInfo->eBand = BAND_5G; ++ break; ++ default: ++ prRfChnlInfo->eBand = BAND_2G4; ++ break; ++ } ++ ++ } ++ ++ if (prChnlSco) { ++ ++ switch (channel_type) { ++ case NL80211_CHAN_NO_HT: ++ *prChnlSco = CHNL_EXT_SCN; ++ break; ++ case NL80211_CHAN_HT20: ++ *prChnlSco = CHNL_EXT_SCN; ++ break; ++ case NL80211_CHAN_HT40MINUS: ++ *prChnlSco = CHNL_EXT_SCA; ++ break; ++ case NL80211_CHAN_HT40PLUS: ++ *prChnlSco = CHNL_EXT_SCB; ++ break; ++ default: ++ ASSERT(FALSE); ++ *prChnlSco = CHNL_EXT_SCN; ++ break; ++ } ++ } ++ ++ fgIsValid = TRUE; ++ } while (FALSE); ++ ++ return fgIsValid; ++} ++ ++/* mtk_p2p_cfg80211func_channel_format_switch */ ++ ++#if CONFIG_NL80211_TESTMODE ++int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_TEST_PARAMS prParams = (P_NL80211_DRIVER_TEST_PARAMS) NULL; ++ INT_32 i4Status = -EINVAL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = NULL; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_cmd\n"); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_TEST_PARAMS) data; ++ } else { ++ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_cmd, data is NULL\n"); ++ return i4Status; ++ } ++ ++ if (prParams->index >> 24 == 0x01) { ++ /* New version */ ++ } else { ++ /* Old version */ ++ mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len); ++ i4Status = 0; ++ return i4Status; ++ } ++ ++ /* Clear the version byte */ ++ prParams->index = prParams->index & ~BITS(24, 31); ++ ++ if (prParams) { ++ switch (prParams->index) { ++ case 1: /* P2P Simga */ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ { ++ P_NL80211_DRIVER_SW_CMD_PARAMS prParamsCmd; ++ ++ prParamsCmd = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; ++ ++ if ((prParamsCmd->adr & 0xffff0000) == 0xffff0000) { ++ i4Status = mtk_p2p_cfg80211_testmode_sw_cmd(wiphy, data, len); ++ break; ++ } ++ } ++#endif ++ i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(wiphy, data, len); ++ break; ++#if CFG_SUPPORT_WFD ++ case 2: /* WFD */ ++ i4Status = mtk_p2p_cfg80211_testmode_wfd_update_cmd(wiphy, data, len); ++ break; ++#endif ++ case 3: /* Hotspot Client Management */ ++ i4Status = mtk_p2p_cfg80211_testmode_hotspot_block_cmd(wiphy, data, len); ++ break; ++ case 0x10: ++ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); ++ break; ++#if 1 ++ case 0x11: /*NFC Beam + Indication */ ++ prChnlReqInfo = &prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; ++ if (data && len) { ++ P_NL80211_DRIVER_SET_NFC_PARAMS prParams = (P_NL80211_DRIVER_SET_NFC_PARAMS) data; ++ ++ prChnlReqInfo->NFC_BEAM = prParams->NFC_Enable; ++ DBGLOG(P2P, INFO, "NFC: BEAM[%d]\n", prChnlReqInfo->NFC_BEAM); ++ } ++ break; ++ case 0x12: /*NFC Beam + Indication */ ++ DBGLOG(P2P, INFO, "NFC: Polling\n"); ++ i4Status = mtk_cfg80211_testmode_get_scan_done(wiphy, data, len, prGlueInfo); ++ break; ++#endif ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ case 0x30: ++ i4Status = mtk_cfg80211_testmode_get_lte_channel(wiphy, data, len, prGlueInfo); ++ break; ++#endif ++ ++ default: ++ i4Status = -EINVAL; ++ break; ++ } ++ } ++ ++ return i4Status; ++} ++ ++int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ NL80211_DRIVER_TEST_PRE_PARAMS rParams; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_32 index_mode; ++ UINT_32 index; ++ INT_32 value; ++ int status = 0; ++ UINT_32 u4Leng; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ kalMemZero(&rParams, sizeof(NL80211_DRIVER_TEST_PRE_PARAMS)); ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd\n"); ++ ++ if (data && len) ++ memcpy(&rParams, data, len); ++ ++ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA,idx_mode=%d idx=%d value=%u\n", ++ (INT_16) rParams.idx_mode, (INT_16) rParams.idx, rParams.value); ++ ++ index_mode = rParams.idx_mode; ++ index = rParams.idx; ++ value = rParams.value; ++ ++ switch (index) { ++ case 0: /* Listen CH */ ++ break; ++ case 1: /* P2p mode */ ++ break; ++ case 4: /* Noa duration */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 5: /* Noa interval */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 6: /* Noa count */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 100: /* Oper CH */ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ /* prP2pConnSettings->ucOperatingChnl = value; */ ++ break; ++ case 101: /* Local config Method, for P2P SDK */ ++ prP2pConnSettings->u2LocalConfigMethod = value; ++ break; ++ case 102: /* Sigma P2p reset */ ++ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ ++ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ ++ p2pFsmUninit(prGlueInfo->prAdapter); ++ p2pFsmInit(prGlueInfo->prAdapter); ++ break; ++ case 103: /* WPS MODE */ ++ kalP2PSetWscMode(prGlueInfo, value); ++ break; ++ case 104: /* P2p send persence, duration */ ++ break; ++ case 105: /* P2p send persence, interval */ ++ break; ++ case 106: /* P2P set sleep */ ++ value = 1; ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ case 107: /* P2P set opps, CTWindowl */ ++ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; ++ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ ++ break; ++ case 108: /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ ++ break; ++ default: ++ break; ++ } ++ ++ return status; ++ ++} ++ ++int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_P2P_SIGMA_PARAMS prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_32 index; ++ INT_32 value; ++ int status = 0; ++ UINT_32 u4Leng; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd\n"); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) data; ++ } else { ++ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd, data is NULL or len is 0\n"); ++ return -EINVAL; ++ } ++ ++ index = (INT_32) prParams->idx; ++ value = (INT_32) prParams->value; ++ ++ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA, idx=%d value=%d\n", ++ (INT_32) prParams->idx, (INT_32) prParams->value); ++ ++ switch (index) { ++ case 0: /* Listen CH */ ++ break; ++ case 1: /* P2p mode */ ++ break; ++ case 4: /* Noa duration */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 5: /* Noa interval */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 6: /* Noa count */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 100: /* Oper CH */ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ /* prP2pConnSettings->ucOperatingChnl = value; */ ++ break; ++ case 101: /* Local config Method, for P2P SDK */ ++ prP2pConnSettings->u2LocalConfigMethod = value; ++ break; ++ case 102: /* Sigma P2p reset */ ++ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ ++ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ ++ break; ++ case 103: /* WPS MODE */ ++ kalP2PSetWscMode(prGlueInfo, value); ++ break; ++ case 104: /* P2p send persence, duration */ ++ break; ++ case 105: /* P2p send persence, interval */ ++ break; ++ case 106: /* P2P set sleep */ ++ value = 1; ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ case 107: /* P2P set opps, CTWindowl */ ++ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; ++ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ ++ break; ++ case 108: /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ ++ break; ++ case 109: /* Max Clients */ ++ kalP2PSetMaxClients(prGlueInfo, value); ++ break; ++ case 110: /* Hotspot WPS mode */ ++ kalIoctl(prGlueInfo, wlanoidSetP2pWPSmode, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ default: ++ break; ++ } ++ ++ return status; ++ ++} ++ ++#if CFG_SUPPORT_WFD ++int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_WFD_PARAMS prParams = (P_NL80211_DRIVER_WFD_PARAMS) NULL; ++ int status = 0; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; ++ static UINT_8 prevWfdEnable; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prParams = (P_NL80211_DRIVER_WFD_PARAMS) data; ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_wfd_update_cmd\n"); ++ ++ /* to reduce log, print when state changed */ ++ if (prevWfdEnable != prParams->WfdEnable) { ++ prevWfdEnable = prParams->WfdEnable; ++ DBGLOG(P2P, INFO, "WFD Enable:%x\n", prParams->WfdEnable); ++ DBGLOG(P2P, INFO, "WFD Session Available:%x\n", prParams->WfdSessionAvailable); ++ DBGLOG(P2P, INFO, "WFD Couple Sink Status:%x\n", prParams->WfdCoupleSinkStatus); ++ /* aucReserved0[2] */ ++ DBGLOG(P2P, INFO, "WFD Device Info:%x\n", prParams->WfdDevInfo); ++ DBGLOG(P2P, INFO, "WFD Control Port:%x\n", prParams->WfdControlPort); ++ DBGLOG(P2P, INFO, "WFD Maximum Throughput:%x\n", prParams->WfdMaximumTp); ++ DBGLOG(P2P, INFO, "WFD Extend Capability:%x\n", prParams->WfdExtendCap); ++ DBGLOG(P2P, INFO, "WFD Couple Sink Addr %pM\n", prParams->WfdCoupleSinkAddress); ++ DBGLOG(P2P, INFO, "WFD Associated BSSID %pM\n", prParams->WfdAssociatedBssid); ++ /* UINT_8 aucVideolp[4]; */ ++ /* UINT_8 aucAudiolp[4]; */ ++ DBGLOG(P2P, INFO, "WFD Video Port:%x\n", prParams->WfdVideoPort); ++ DBGLOG(P2P, INFO, "WFD Audio Port:%x\n", prParams->WfdAudioPort); ++ DBGLOG(P2P, INFO, "WFD Flag:%x\n", prParams->WfdFlag); ++ DBGLOG(P2P, INFO, "WFD Policy:%x\n", prParams->WfdPolicy); ++ DBGLOG(P2P, INFO, "WFD State:%x\n", prParams->WfdState); ++ /* UINT_8 aucWfdSessionInformationIE[24*8]; */ ++ DBGLOG(P2P, INFO, "WFD Session Info Length:%x\n", prParams->WfdSessionInformationIELen); ++ /* UINT_8 aucReserved1[2]; */ ++ DBGLOG(P2P, INFO, "WFD Primary Sink Addr %pM\n", prParams->aucWfdPrimarySinkMac); ++ DBGLOG(P2P, INFO, "WFD Secondary Sink Addr %pM\n", prParams->aucWfdSecondarySinkMac); ++ DBGLOG(P2P, INFO, "WFD Advanced Flag:%x\n", prParams->WfdAdvanceFlag); ++ DBGLOG(P2P, INFO, "WFD Sigma mode:%x\n", prParams->WfdSigmaMode); ++ /* UINT_8 aucReserved2[64]; */ ++ /* UINT_8 aucReserved3[64]; */ ++ /* UINT_8 aucReserved4[64]; */ ++ } ++ ++ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ kalMemCopy(&prWfdCfgSettings->u4WfdCmdType, &prParams->WfdCmdType, sizeof(WFD_CFG_SETTINGS_T)); ++ ++ prMsgWfdCfgUpdate = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); ++ ++ if (prMsgWfdCfgUpdate == NULL) { ++ ASSERT(FALSE); ++ return status; ++ } ++ ++ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; ++ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); ++#if 0 /* Test Only */ ++/* prWfdCfgSettings->ucWfdEnable = 1; */ ++/* prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; */ ++ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; ++ prWfdCfgSettings->u2WfdDevInfo = 123; ++ prWfdCfgSettings->u2WfdControlPort = 456; ++ prWfdCfgSettings->u2WfdMaximumTp = 789; ++ ++ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_SINK_INFO_VALID; ++ prWfdCfgSettings->ucWfdCoupleSinkStatus = 0xAB; ++ { ++ UINT_8 aucTestAddr[MAC_ADDR_LEN] = { 0x77, 0x66, 0x55, 0x44, 0x33, 0x22 }; ++ ++ COPY_MAC_ADDR(prWfdCfgSettings->aucWfdCoupleSinkAddress, aucTestAddr); ++ } ++ ++ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_EXT_CAPABILITY_VALID; ++ prWfdCfgSettings->u2WfdExtendCap = 0xCDE; ++ ++#endif ++ ++ return status; ++ ++} ++#endif /* CFG_SUPPORT_WFD */ ++ ++int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) data; ++ } else { ++ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd, data is NULL or len is 0\n"); ++ return -EINVAL; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd\n"); ++ ++ return kalP2PSetBlackList(prGlueInfo, prParams->aucBssid, prParams->ucblocked); ++} ++ ++int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++#if 1 ++ DBGLOG(P2P, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ if (data && len) ++ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; ++ ++ if (prParams) { ++ if (prParams->set == 1) { ++ rstatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, ++ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ } ++ ++ if (WLAN_STATUS_SUCCESS != rstatus) ++ fgIsValid = -EFAULT; ++ ++ return fgIsValid; ++} ++ ++#endif ++ ++#endif /* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c +new file mode 100644 +index 000000000000..d0f2d25a4529 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c +@@ -0,0 +1,433 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/* ++** Id: @(#) gl_p2p_init.c@@ ++*/ ++ ++/*! \file gl_p2p_init.c ++ \brief init and exit routines of Linux driver interface for Wi-Fi Direct ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define P2P_MODE_INF_NAME "p2p%d" ++#if CFG_TC1_FEATURE ++#define AP_MODE_INF_NAME "wlan%d" ++#else ++#define AP_MODE_INF_NAME "ap%d" ++#endif ++/* #define MAX_INF_NAME_LEN 15 */ ++/* #define MIN_INF_NAME_LEN 1 */ ++ ++#define RUNNING_P2P_MODE 0 ++#define RUNNING_AP_MODE 1 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* Get interface name and running mode from module insertion parameter ++* Usage: insmod p2p.ko mode=1 ++* default: interface name is p2p%d ++* running mode is P2P ++*/ ++static PUCHAR ifname = P2P_MODE_INF_NAME; ++static UINT_16 mode = RUNNING_P2P_MODE; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief check interface name parameter is valid or not ++* if invalid, set ifname to P2P_MODE_INF_NAME ++* ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pCheckInterfaceName(VOID) ++{ ++ ++ if (mode) { ++ mode = RUNNING_AP_MODE; ++ ifname = AP_MODE_INF_NAME; ++ } ++#if 0 ++ UINT_32 ifLen = 0; ++ ++ if (ifname) { ++ ifLen = strlen(ifname); ++ ++ if (ifLen > MAX_INF_NAME_LEN) ++ ifname[MAX_INF_NAME_LEN] = '\0'; ++ else if (ifLen < MIN_INF_NAME_LEN) ++ ifname = P2P_MODE_INF_NAME; ++ } else { ++ ifname = P2P_MODE_INF_NAME; ++ } ++#endif ++} ++ ++void p2pHandleSystemSuspend(void) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_8 ip[4] = { 0 }; ++ UINT_32 u4NumIPv4 = 0; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++ UINT_32 u4NumIPv6 = 0; ++#endif ++ UINT_32 i; ++ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; ++ ++ ++ if (!wlanExportGlueInfo(&prGlueInfo)) { ++ DBGLOG(P2P, INFO, "No glue info\n"); ++ return; ++ } ++ ++ ASSERT(prGlueInfo); ++ /* <1> Sanity check and acquire the net_device */ ++ prDev = prGlueInfo->prP2PInfo->prDevHandler; ++ ASSERT(prDev); ++ ++ /* <3> get the IPv4 address */ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ip is not available.\n"); ++ return; ++ } ++ /* <4> copy the IPv4 address */ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++ /* todo: traverse between list to find whole sets of IPv4 addresses */ ++ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) ++ u4NumIPv4++; ++#ifdef CONFIG_IPV6 ++ /* <5> get the IPv6 address */ ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); ++ return; ++ } ++ /* <6> copy the IPv6 address */ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); ++ /* todo: traverse between list to find whole sets of IPv6 addresses */ ++ ++ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) ++ ; /* Do nothing */ ++#endif ++ /* <7> set up the ARP filter */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen = 0; ++/* UINT_8 aucBuf[32] = {0}; */ ++ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ /* aucBuf; */ ++ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = u4NumIPv4; ++#ifdef CONFIG_IPV6 ++ prParamNetAddrList->u4AddressCount += u4NumIPv6; ++#endif ++ ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ for (i = 0; i < u4NumIPv4; i++) { ++ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++#if 0 ++ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr + sizeof(ip)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); ++#else ++ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; ++ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); ++ ++/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); ++// TODO: frog. The pointer is not right. */ ++ ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + ++ (ULONG) (prParamNetAddr->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP); ++#endif ++ } ++#ifdef CONFIG_IPV6 ++ for (i = 0; i < u4NumIPv6; i++) { ++ prParamNetAddr->u2AddressLength = 6; ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); ++/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6)); */ ++ ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + ++ (ULONG) (prParamNetAddr->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); ++ } ++#endif ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); ++ } ++} ++ ++void p2pHandleSystemResume(void) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_8 ip[4] = { 0 }; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++#endif ++ ++ if (!wlanExportGlueInfo(&prGlueInfo)) { ++ DBGLOG(P2P, WARN, "no glue info\n"); ++ return; ++ } ++ ++ ASSERT(prGlueInfo); ++ /* <1> Sanity check and acquire the net_device */ ++ prDev = prGlueInfo->prP2PInfo->prDevHandler; ++ ASSERT(prDev); ++ ++ /* <3> get the IPv4 address */ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ip is not available.\n"); ++ return; ++ } ++ /* <4> copy the IPv4 address */ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++#ifdef CONFIG_IPV6 ++ /* <5> get the IPv6 address */ ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); ++ return; ++ } ++ /* <6> copy the IPv6 address */ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); ++#endif ++ /* <7> clear the ARP filter */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen = 0; ++/* UINT_8 aucBuf[32] = {0}; */ ++ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ /* aucBuf; */ ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = 0; ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* run p2p init procedure, include register pointer to wlan ++* glue register p2p ++* set p2p registered flag ++* \retval 1 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo) ++{ ++ ++ DBGLOG(P2P, TRACE, "p2pLaunch\n"); ++ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) { ++ DBGLOG(P2P, INFO, "p2p already registered\n"); ++ return FALSE; ++ } else if (glRegisterP2P(prGlueInfo, ifname, (BOOLEAN) mode)) { ++ prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE; ++ ++ DBGLOG(P2P, TRACE, "Launch success, fgIsP2PRegistered TRUE.\n"); ++ return TRUE; ++ } ++ DBGLOG(P2P, ERROR, "Launch Fail\n"); ++ ++ return FALSE; ++} ++ ++VOID p2pSetMode(IN BOOLEAN fgIsAPMOde) ++{ ++ if (fgIsAPMOde) { ++ mode = RUNNING_AP_MODE; ++ ifname = AP_MODE_INF_NAME; ++ } else { ++ mode = RUNNING_P2P_MODE; ++ ifname = P2P_MODE_INF_NAME; ++ } ++ ++} /* p2pSetMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* run p2p exit procedure, include unregister pointer to wlan ++* glue unregister p2p ++* set p2p registered flag ++ ++* \retval 1 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo) ++{ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { ++ DBGLOG(P2P, INFO, "p2p is not Registered.\n"); ++ return FALSE; ++ } ++ /*Check p2p fsm is stop or not. If not then stop now */ ++ if (IS_P2P_ACTIVE(prGlueInfo->prAdapter)) ++ p2pStopImmediate(prGlueInfo); ++ prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE; ++ glUnregisterP2P(prGlueInfo); ++ /*p2p is removed successfully */ ++ return TRUE; ++ ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver entry point when the driver is configured as a Linux Module, and ++* is called once at module load time, by the user-level modutils ++* application: insmod or modprobe. ++* ++* \retval 0 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++static int initP2P(void) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ /*check interface name validation */ ++ p2pCheckInterfaceName(); ++ ++ DBGLOG(P2P, INFO, "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP" : "P2P"); ++ ++ /*register p2p init & exit function to wlan sub module handler */ ++ wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE); ++ ++ /*if wlan is not start yet, do nothing ++ * p2pLaunch will be called by txthread while wlan start ++ */ ++ /*if wlan is not started yet, return FALSE */ ++ if (wlanExportGlueInfo(&prGlueInfo)) { ++ wlanSubModInit(prGlueInfo); ++ return prGlueInfo->prAdapter->fgIsP2PRegistered ? 0 : -EIO; ++ } ++ ++ return 0; ++} /* end of initP2P() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver exit point when the driver as a Linux Module is removed. Called ++* at module unload time, by the user level modutils application: rmmod. ++* This is our last chance to clean up after ourselves. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++/* 1 Module Leave Point */ ++static VOID __exit exitP2P(void) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DBGLOG(P2P, INFO, KERN_INFO DRV_NAME "ExitP2P\n"); ++ ++ /*if wlan is not started yet, return FALSE */ ++ if (wlanExportGlueInfo(&prGlueInfo)) ++ wlanSubModExit(prGlueInfo); ++ /*UNregister p2p init & exit function to wlan sub module handler */ ++ wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE); ++} /* end of exitP2P() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c +new file mode 100644 +index 000000000000..11a417e4c74c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c +@@ -0,0 +1,1314 @@ ++/* ++** Id: @(#) gl_p2p_cfg80211.c@@ ++*/ ++ ++/*! \file gl_p2p_kal.c ++ \brief ++ ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "net/cfg80211.h" ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Wi-Fi Direct state from glue layer ++* ++* \param[in] ++* prGlueInfo ++* rPeerAddr ++* \return ++* ENUM_BOW_DEVICE_STATE ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->prP2PInfo->eState; ++} /* end of kalP2PGetState() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to update the assoc req to p2p ++* ++* \param[in] ++* prGlueInfo ++* pucFrameBody ++* u4FrameBodyLen ++* fgReassocRequest ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) ++{ ++ union iwreq_data wrqu; ++ unsigned char *pucExtraInfo = NULL; ++ unsigned char *pucDesiredIE = NULL; ++/* unsigned char aucExtraInfoBuf[200]; */ ++ PUINT_8 cp; ++ ++ memset(&wrqu, 0, sizeof(wrqu)); ++ ++ if (fgReassocRequest) { ++ if (u4FrameBodyLen < 15) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } else { ++ if (u4FrameBodyLen < 9) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } ++ ++ cp = pucFrameBody; ++ ++ if (fgReassocRequest) { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ /* Current AP address 6 */ ++ cp += 10; ++ u4FrameBodyLen -= 10; ++ } else { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ cp += 4; ++ u4FrameBodyLen -= 4; ++ } ++ ++ /* do supplicant a favor, parse to the start of WPA/RSN IE */ ++ if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { ++ /* printk("wextSrchDesiredWPSIE!!\n"); */ ++ /* WPS IE found */ ++ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0x30, &pucDesiredIE)) { ++ /* printk("wextSrchDesiredWPAIE!!\n"); */ ++ /* RSN IE found */ ++ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { ++ /* printk("wextSrchDesiredWPAIE!!\n"); */ ++ /* WPA IE found */ ++ } else { ++ /* no WPA/RSN IE found, skip this event */ ++ goto skip_indicate_event; ++ } ++ ++ /* IWEVASSOCREQIE, indicate binary string */ ++ pucExtraInfo = pucDesiredIE; ++ wrqu.data.length = pucDesiredIE[1] + 2; ++ ++ /* Send event to user space */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVASSOCREQIE, &wrqu, pucExtraInfo); ++ ++skip_indicate_event: ++ return; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Wi-Fi Direct state in glue layer ++* ++* \param[in] ++* prGlueInfo ++* eBowState ++* rPeerAddr ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ if (eState == PARAM_MEDIA_STATE_CONNECTED) { ++ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_CONNECTED; ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_CONNECT=%pM ", rPeerAddr); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++ } else if (eState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_DISCONNECT=%pM ", rPeerAddr); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ } else { ++ ASSERT(0); ++ } ++ ++} /* end of kalP2PSetState() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Wi-Fi Direct operating frequency ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* in unit of KHz ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->prP2PInfo->u4FreqInKHz; ++} /* end of kalP2PGetFreqInKHz() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi role ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* 0: P2P Device ++* 1: Group Client ++* 2: Group Owner ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->prP2PInfo->ucRole; ++} /* end of kalP2PGetRole() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Wi-Fi Direct role ++* ++* \param[in] ++* prGlueInfo ++* ucResult ++* 0: successful ++* 1: error ++* ucRole ++* 0: P2P Device ++* 1: Group Client ++* 2: Group Owner ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ucRole <= 2); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ if (ucResult == 0) ++ prGlueInfo->prP2PInfo->ucRole = ucRole; ++ ++ if (pucSSID) ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, ++ 1 /* persistence or not */ , pucSSID[7], pucSSID[8]); ++ else ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, ++ 1 /* persistence or not */ , '0', '0'); ++ ++ evt.data.length = strlen(aucBuffer); ++ ++ /* if (pucSSID) */ ++ /* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */ ++ ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PSetRole() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set the cipher for p2p ++* ++* \param[in] ++* prGlueInfo ++* u4Cipher ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prGlueInfo->prP2PInfo->u4CipherPairwise = u4Cipher; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get the cipher, return for cipher is ccmp ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE: cipher is ccmp ++* FALSE: cipher is none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) ++ return TRUE; ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) ++ return TRUE; ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) ++ return FALSE; ++ ++ return FALSE; ++} ++ ++BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) ++ return FALSE; ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set the status of WSC ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prGlueInfo->prP2PInfo->ucWSCRunning = ucWscMode; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get the status of WSC ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return 0; ++ } ++ ++ return prGlueInfo->prP2PInfo->ucWSCRunning; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get the wsc ie length ++* ++* \param[in] ++* prGlueInfo ++* ucType : 0 for beacon, 1 for probe req, 2 for probe resp ++* ++* \return ++* The WSC IE length ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType) ++{ ++ ASSERT(prGlueInfo); ++ ++ ASSERT(ucType < 3); ++ ++ return prGlueInfo->prP2PInfo->u2WSCIELen[ucType]; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to copy the wsc ie setting from p2p supplicant ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* The WPS IE length ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer) ++{ ++ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (ucType >= 3) || (pucBuffer == NULL)) ++ break; ++ ++ prGlP2pInfo = prGlueInfo->prP2PInfo; ++ ++ kalMemCopy(pucBuffer, prGlP2pInfo->aucWSCIE[ucType], prGlP2pInfo->u2WSCIELen[ucType]); ++ ++ } while (FALSE); ++ ++} ++ ++VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength) ++{ ++ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (ucType >= 3) || ((u2BufferLength > 0) && (pucBuffer == NULL))) ++ break; ++ ++ if (u2BufferLength > 400) { ++ DBGLOG(P2P, ERROR, ++ "Buffer length is not enough, GLUE only 400 bytes but %d received\n", u2BufferLength); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlP2pInfo = prGlueInfo->prP2PInfo; ++ ++ kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], pucBuffer, u2BufferLength); ++ ++ prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength; ++ ++ } while (FALSE); ++ ++} /* kalP2PUpdateWSC_IE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief indicate an event to supplicant for device connection request ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, ++ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ ++ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ /* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */ ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength; ++ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, pucDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, rPeerAddr); ++ prGlueInfo->prP2PInfo->ucConnReqDevType = ucDevType; ++ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = i4ConfigMethod; ++ prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod; ++ ++ /* prepare event structure */ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWEVCUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateConnReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for device connection request from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* \param[in] pucGroupBssid Only valid when invitation Type equals to 0. ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, ++ IN PUINT_8 pucSsid, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid) ++{ ++#if 1 ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength = ++ (UINT_32) ((prP2pDevDesc->u2NameLength > 32) ? 32 : prP2pDevDesc->u2NameLength); ++ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, prP2pDevDesc->aucName, ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, prP2pDevDesc->aucDeviceAddr); ++ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqGroupAddr, pucGroupBssid); ++ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = (INT_32) (prP2pDevDesc->u2ConfigMethod); ++ prGlueInfo->prP2PInfo->ucOperatingChnl = ucOperatingChnl; ++ prGlueInfo->prP2PInfo->ucInvitationType = ucInvitationType; ++ ++ /* prepare event structure */ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWEVCUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ return; ++ ++#else ++ P_MSG_P2P_CONNECTION_REQUEST_T prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL)); ++ ++ /* Not a real solution */ ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ ++ prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ ++ if (prP2pConnReq == NULL) ++ break; ++ ++ kalMemZero(prP2pConnReq, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ ++ prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; ++ ++ prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; ++ ++ COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, prP2pDevDesc->aucDeviceAddr); ++ ++ prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod; ++ ++ if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) { ++ prP2pConnReq->fgIsPersistentGroup = FALSE; ++ prP2pConnReq->fgIsTobeGO = FALSE; ++ ++ } ++ ++ else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) { ++ DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n"); ++ prP2pConnReq->fgIsPersistentGroup = TRUE; ++ prP2pConnReq->fgIsTobeGO = (prGlueInfo->prP2PInfo->ucRole == 2) ? TRUE : FALSE; ++ ++ } ++ ++ p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL); ++ ++ if (ucOperatingChnl != 0) ++ prP2pSpecificBssInfo->ucPreferredChannel = ucOperatingChnl; ++ ++ if ((ucSsidLen < 32) && (pucSsid != NULL)) ++ COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, pucSsid, ucSsidLen); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pConnReq, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++ /* frog add. */ ++ /* TODO: Invitation Indication */ ++ ++ return; ++#endif ++ ++} /* kalP2PInvitationIndication */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an status to supplicant for device invitation status. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ ++ prGlueInfo->prP2PInfo->u4InvStatus = u4InvStatus; ++ ++ /* prepare event structure */ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWEVCUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* kalP2PInvitationStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for Service Discovery request from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_REQ %d", ucSeqNum); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PSDREQ event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for Service Discovery response ++* from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_RESP %d", ucSeqNum); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PSDREQ event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateSDResponse() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for Service Discovery TX Done ++* from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* \param[in] ucSeqNum Sequence number of the frame ++* \param[in] ucStatus Status code for TX ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PSDREQ event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateSDResponse() */ ++ ++struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return NULL; ++ } ++ ++ return prGlueInfo->prP2PInfo->prDevHandler; ++} ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP="); ++ ++ kalMemCopy(prGlueInfo->prP2PInfo->aucSecCheckRsp, pucRsp, u2RspLen); ++ evt.data.length = strlen(aucBuffer); ++ ++#if DBG ++ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u2RspLen); ++#endif ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++} /* p2pFsmRunEventRxDisassociation */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) ++{ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, ++ pucNumOfChannel, paucChannelList); ++} /* kalGetChnlList */ ++ ++/* ////////////////////////////////////ICS SUPPORT////////////////////////////////////// */ ++ ++VOID ++kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8SeqNum, ++ IN UINT_32 u4ChannelNum, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration) ++{ ++ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; ++ RF_CHANNEL_INFO_T rChannelInfo; ++ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; ++ ++ do { ++ if (prGlueInfo == NULL) ++ break; ++ ++ kalMemZero(&rChannelInfo, sizeof(RF_CHANNEL_INFO_T)); ++ ++ rChannelInfo.ucChannelNum = u4ChannelNum; ++ rChannelInfo.eBand = eBand; ++ ++ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo, &rChannelInfo); ++ ++ kalP2pFuncGetChannelType(eSco, &eChnlType); ++ ++ cfg80211_ready_on_channel(prGlueInfo->prP2PInfo->prWdev, /* struct wireless_dev, */ ++ u8SeqNum, /* u64 cookie, */ ++ prIEEE80211ChnlStruct, /* struct ieee80211_channel * chan, */ ++ u4Duration, /* unsigned int duration, */ ++ GFP_KERNEL); /* gfp_t gfp */ /* allocation flags */ ++ } while (FALSE); ++ ++} /* kalP2PIndicateChannelReady */ ++ ++VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) ++{ ++ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; ++ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; ++ RF_CHANNEL_INFO_T rRfChannelInfo; ++ ++ do { ++ if ((prGlueInfo == NULL) || (prChnlReqInfo == NULL)) { ++ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prGlueP2pInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n"); ++ ++ rRfChannelInfo.eBand = prChnlReqInfo->eBand; ++ rRfChannelInfo.ucChannelNum = prChnlReqInfo->ucReqChnlNum; ++ ++ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueP2pInfo, &rRfChannelInfo); ++ ++ kalP2pFuncGetChannelType(prChnlReqInfo->eChnlSco, &eChnlType); ++ ++ cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev, /* struct wireless_dev, */ ++ prChnlReqInfo->u8Cookie, prIEEE80211ChnlStruct, GFP_KERNEL); ++ } while (FALSE); ++ ++} /* kalP2PIndicateChannelExpired */ ++ ++VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ struct cfg80211_scan_info info = { ++ .aborted = true, ++ }; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ do { ++ if (prGlueInfo == NULL) { ++ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prGlueP2pInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(INIT, TRACE, "[p2p] scan complete %p\n", prGlueP2pInfo->prScanRequest); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueP2pInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueP2pInfo->prScanRequest; ++ prGlueP2pInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ /* 2. then CFG80211 Indication */ ++ ++ if (prScanRequest != NULL) { ++ ++ /* report all queued beacon/probe response frames to upper layer */ ++ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL); ++ ++ info.aborted = fgIsAbort; ++ DBGLOG(INIT, TRACE, "DBG:p2p_cfg_scan_done\n"); ++ cfg80211_scan_done(prScanRequest, &info); ++ } ++ ++ } while (FALSE); ++ ++} /* kalP2PIndicateScanDone */ ++ ++VOID ++kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBuf, ++ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ struct ieee80211_channel *prChannelEntry = (struct ieee80211_channel *)NULL; ++ struct ieee80211_mgmt *prBcnProbeRspFrame = (struct ieee80211_mgmt *)pucFrameBuf; ++ struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (prChannelInfo == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prGlueP2pInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prChannelEntry = kalP2pFuncGetChannelEntry(prGlueP2pInfo, prChannelInfo); ++ ++ if (prChannelEntry == NULL) { ++ DBGLOG(P2P, WARN, "Unknown channel info\n"); ++ break; ++ } ++ /* rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; */ ++ ++ prCfg80211Bss = cfg80211_inform_bss_frame(prGlueP2pInfo->prWdev->wiphy, /* struct wiphy * wiphy, */ ++ prChannelEntry, ++ prBcnProbeRspFrame, u4BufLen, i4SignalStrength, GFP_KERNEL); ++ ++ /* Return this structure. */ ++ if (!prCfg80211Bss) { ++ DBGLOG(P2P, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", ++ prChannelInfo->ucChannelNum, i4SignalStrength); ++ } else { ++ cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, prCfg80211Bss); ++ DBGLOG(P2P, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", ++ prChannelInfo->ucChannelNum, i4SignalStrength); ++ } ++ } while (FALSE); ++ ++} /* kalP2PIndicateBssInfo */ ++ ++VOID ++kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { ++ DBGLOG(P2P, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", ++ prGlueInfo, pucFrameBuf, u4FrameLen); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ cfg80211_mgmt_tx_status(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ ++ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); ++ ++ } while (FALSE); ++ ++} /* kalP2PIndicateMgmtTxStatus */ ++ ++VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) ++{ ++#define DBG_P2P_MGMT_FRAME_INDICATION 0 ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ INT_32 i4Freq = 0; ++ UINT_8 ucChnlNum = 0; ++#if DBG_P2P_MGMT_FRAME_INDICATION ++ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; ++#endif ++ ++ do { ++ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; ++ ++#if DBG_P2P_MGMT_FRAME_INDICATION ++ ++ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; ++ ++ switch (prWlanHeader->u2FrameCtrl) { ++ case MAC_FRAME_PROBE_REQ: ++ DBGLOG(P2P, TRACE, "RX Probe Req at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_PROBE_RSP: ++ DBGLOG(P2P, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_ACTION: ++ DBGLOG(P2P, TRACE, "RX Action frame at channel %d ", ucChnlNum); ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "from: %pM\n", prWlanHeader->aucAddr2); ++#endif ++ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; ++ ++ cfg80211_rx_mgmt(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ ++ i4Freq, ++ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), ++ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_ATOMIC); ++ } while (FALSE); ++ ++} /* kalP2PIndicateRxMgmtFrame */ ++ ++VOID ++kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, ++ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, ++ IN WLAN_STATUS eStatus) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if (prGlueInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prP2pConnInfo) { ++ cfg80211_connect_result(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ ++ prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, ++ prP2pConnInfo->u4BufLength, ++ pucRxIEBuf, u2RxIELen, u2StatusReason, GFP_KERNEL); ++ /* gfp_t gfp */ /* allocation flags */ ++ prP2pConnInfo->fgIsConnRequest = FALSE; ++ } else { ++ /* Disconnect, what if u2StatusReason == 0? */ ++ cfg80211_disconnected(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ ++ u2StatusReason, pucRxIEBuf, u2RxIELen, ++ eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ? true : false, ++ GFP_KERNEL); ++ } ++ ++ } while (FALSE); ++ ++} /* kalP2PGCIndicateConnectionStatus */ ++ ++VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew) ++{ ++ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; ++ struct station_info rStationInfo; ++ ++ memset(&rStationInfo, 0, sizeof(struct station_info)); ++ ++ do { ++ if ((prGlueInfo == NULL) || (prCliStaRec == NULL)) ++ break; ++ ++ prP2pGlueInfo = prGlueInfo->prP2PInfo; ++ ++ if (fgIsNew) { ++ //rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES; ++ rStationInfo.generation = ++prP2pGlueInfo->i4Generation; ++ ++ rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe; ++ rStationInfo.assoc_req_ies_len = prCliStaRec->u2AssocReqIeLen; ++/* rStationInfo.filled |= STATION_INFO_ASSOC_REQ_IES; */ ++ ++ cfg80211_new_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ ++ prCliStaRec->aucMacAddr, &rStationInfo, GFP_KERNEL); ++ } else { ++ ++prP2pGlueInfo->i4Generation; ++ ++ cfg80211_del_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ ++ prCliStaRec->aucMacAddr, GFP_KERNEL); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* kalP2PGOStationUpdate */ ++ ++BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type) ++{ ++ BOOLEAN fgIsValid = FALSE; ++ ++ do { ++ if (channel_type) { ++ ++ switch (rChnlSco) { ++ case CHNL_EXT_SCN: ++ *channel_type = NL80211_CHAN_NO_HT; ++ break; ++ case CHNL_EXT_SCA: ++ *channel_type = NL80211_CHAN_HT40MINUS; ++ break; ++ case CHNL_EXT_SCB: ++ *channel_type = NL80211_CHAN_HT40PLUS; ++ break; ++ default: ++ ASSERT(FALSE); ++ *channel_type = NL80211_CHAN_NO_HT; ++ break; ++ } ++ ++ } ++ ++ fgIsValid = TRUE; ++ } while (FALSE); ++ ++ return fgIsValid; ++} /* kalP2pFuncGetChannelType */ ++ ++struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo) ++{ ++ struct ieee80211_channel *prTargetChannelEntry = (struct ieee80211_channel *)NULL; ++ UINT_32 u4TblSize = 0, u4Idx = 0; ++ struct ieee80211_supported_band **bands; ++ ++ do { ++ if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) ++ break; ++ bands = &prP2pInfo->prWdev->wiphy->bands[0]; ++ switch (prChannelInfo->eBand) { ++ case BAND_2G4: ++ prTargetChannelEntry = bands[NL80211_BAND_2GHZ]->channels; ++ u4TblSize = bands[NL80211_BAND_2GHZ]->n_channels; ++ break; ++ case BAND_5G: ++ prTargetChannelEntry = bands[NL80211_BAND_5GHZ]->channels; ++ u4TblSize = bands[NL80211_BAND_5GHZ]->n_channels; ++ break; ++ default: ++ break; ++ } ++ ++ if (prTargetChannelEntry == NULL) ++ break; ++ ++ for (u4Idx = 0; u4Idx < u4TblSize; u4Idx++, prTargetChannelEntry++) { ++ if (prTargetChannelEntry->hw_value == prChannelInfo->ucChannelNum) ++ break; ++ } ++ ++ if (u4Idx == u4TblSize) { ++ prTargetChannelEntry = NULL; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return prTargetChannelEntry; ++} /* kalP2pFuncGetChannelEntry */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set the block list of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock) ++{ ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prGlueInfo->prP2PInfo); ++ ++ if (EQUAL_MAC_ADDR(rbssid, aucNullAddr)) ++ return -EINVAL; ++ ++ if (fgIsblock) { ++ for (i = 0; i < 8; i++) { ++ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { ++ break; ++ } else if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr)) { ++ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid); ++ break; ++ } ++ } ++ if (i >= 8) { ++ DBGLOG(P2P, ERROR, "AP black list is full, cannot block more STA!!\n"); ++ return -ENOBUFS; ++ } ++ } else { ++ for (i = 0; i < 8; i++) { ++ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { ++ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr); ++ break; ++ } ++ } ++ if (i >= 8) ++ DBGLOG(P2P, ERROR, "The STA is not found in black list!!\n"); ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to compare the black list of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid) ++{ ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ BOOLEAN fgIsExsit = FALSE; ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prGlueInfo->prP2PInfo); ++ ++ for (i = 0; i < 8; i++) { ++ if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { ++ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { ++ fgIsExsit = TRUE; ++ return fgIsExsit; ++ } ++ } ++ } ++ ++ return fgIsExsit; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to return the max clients of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ if (u4MaxClient == 0 || prGlueInfo->prP2PInfo->ucMaxClients >= P2P_MAXIMUM_CLIENT_COUNT) ++ prGlueInfo->prP2PInfo->ucMaxClients = P2P_MAXIMUM_CLIENT_COUNT; ++ else ++ prGlueInfo->prP2PInfo->ucMaxClients = u4MaxClient; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to return the max clients of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->ucMaxClients) { ++ if ((UINT_8) u4NumClient > prGlueInfo->prP2PInfo->ucMaxClients) ++ return TRUE; ++ else ++ return FALSE; ++ } ++ ++ return FALSE; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c +new file mode 100644 +index 000000000000..075045f547b7 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c +@@ -0,0 +1,1020 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_proc.c#1 ++*/ ++ ++/*! \file "gl_proc.c" ++ \brief This file defines the interface which can interact with users in /proc fs. ++ ++ Detail description. ++*/ ++ ++/* ++** Log: gl_proc.c ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 12 10 2010 kevin.huang ++ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check ++ * Add Linux Proc Support ++** \main\maintrunk.MT5921\19 2008-09-02 21:08:37 GMT mtk01461 ++** Fix the compile error of SPRINTF() ++** \main\maintrunk.MT5921\18 2008-08-10 18:48:28 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\17 2008-08-04 16:52:01 GMT mtk01461 ++** Add proc dbg print message of DOMAIN_INDEX level ++** \main\maintrunk.MT5921\16 2008-07-10 00:45:16 GMT mtk01461 ++** Remove the check of MCR offset, we may use the MCR address which is not align to DW boundary or proprietary usage. ++** \main\maintrunk.MT5921\15 2008-06-03 20:49:44 GMT mtk01461 ++** \main\maintrunk.MT5921\14 2008-06-02 22:56:00 GMT mtk01461 ++** Rename some functions for linux proc ++** \main\maintrunk.MT5921\13 2008-06-02 20:23:18 GMT mtk01461 ++** Revise PROC mcr read / write for supporting TELNET ++** \main\maintrunk.MT5921\12 2008-03-28 10:40:25 GMT mtk01461 ++** Remove temporary set desired rate in linux proc ++** \main\maintrunk.MT5921\11 2008-01-07 15:07:29 GMT mtk01461 ++** Add User Update Desired Rate Set for QA in Linux ++** \main\maintrunk.MT5921\10 2007-12-11 00:11:14 GMT mtk01461 ++** Fix SPIN_LOCK protection ++** \main\maintrunk.MT5921\9 2007-12-04 18:07:57 GMT mtk01461 ++** Add additional debug category to proc ++** \main\maintrunk.MT5921\8 2007-11-02 01:03:23 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** \main\maintrunk.MT5921\7 2007-10-25 18:08:14 GMT mtk01461 ++** Add VOIP SCAN Support & Refine Roaming ++** Revision 1.3 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.2 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/* #include "wlan_lib.h" */ ++/* #include "debug.h" */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define PROC_WLAN_THERMO "wlanThermo" ++#define PROC_DRV_STATUS "status" ++#define PROC_RX_STATISTICS "rx_statistics" ++#define PROC_TX_STATISTICS "tx_statistics" ++#define PROC_DBG_LEVEL_NAME "dbgLevel" ++#define PROC_NEED_TX_DONE "TxDoneCfg" ++#define PROC_AUTO_PER_CFG "autoPerCfg" ++#define PROC_ROOT_NAME "wlan" ++#define PROC_CMD_DEBUG_NAME "cmdDebug" ++ ++#define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN 20 ++#define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN 10 ++#define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN 10 ++#define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN (20*10) ++#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN 8 ++ ++#define PROC_UID_SHELL 2000 ++#define PROC_GID_WIFI 1010 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++/* static UINT_32 u4McrOffset; */ ++#if CFG_SUPPORT_THERMO_THROTTLING ++static P_GLUE_INFO_T g_prGlueInfo_proc; ++#endif ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading MCR register to User Space, the offset of ++* the MCR is specified in u4McrOffset. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++#if 0 ++static int procMCRRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; ++ UINT_32 u4BufLen; ++ char *p = page; ++ UINT_32 u4Count; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); ++ ++ rMcrInfo.u4McrOffset = u4McrOffset; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryMcrRead, ++ (PVOID)&rMcrInfo, sizeof(rMcrInfo), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ ++ /* SPRINTF(p, ("MCR (0x%08lxh): 0x%08lx\n", */ ++ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData)); */ ++ ++ u4Count = (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procMCRRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for writing MCR register to HW or update u4McrOffset ++* for reading MCR later. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procMCRWrite(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ ++ int i4CopySize; ++ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; ++ UINT_32 u4BufLen; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(data); ++ ++ i4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ if (copy_from_user(acBuf, buffer, i4CopySize)) ++ return 0; ++ acBuf[i4CopySize] = '\0'; ++ ++ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 2) { ++ /* NOTE: Sometimes we want to test if bus will still be ok, after accessing ++ * the MCR which is not align to DW boundary. ++ */ ++ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); ++ ++ u4McrOffset = rMcrInfo.u4McrOffset; ++ ++ /* printk("Write 0x%lx to MCR 0x%04lx\n", */ ++ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData); */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetMcrWrite, ++ (PVOID)&rMcrInfo, sizeof(rMcrInfo), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ ++ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 1) { ++ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ ++ u4McrOffset = rMcrInfo.u4McrOffset; ++ } ++ ++ return count; ++ ++} /* end of procMCRWrite() */ ++#endif ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading Driver Status to User Space. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procDrvStatusRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char *p = page; ++ UINT_32 u4Count; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ SPRINTF(p, ("GLUE LAYER STATUS:")); ++ SPRINTF(p, ("\n==================")); ++ ++ SPRINTF(p, ("\n* Number of Pending Frames: %ld\n", prGlueInfo->u4TxPendingFrameNum)); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ u4Count += (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procDrvStatusRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading Driver RX Statistic Counters to User Space. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procRxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char *p = page; ++ UINT_32 u4Count; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ SPRINTF(p, ("RX STATISTICS (Write 1 to clear):")); ++ SPRINTF(p, ("\n=================================\n")); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ u4Count += (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procRxStatisticsRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reset Driver RX Statistic Counters. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procRxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ UINT_32 u4ClearCounter; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ copy_from_user(acBuf, buffer, u4CopySize); ++ acBuf[u4CopySize] = '\0'; ++ ++ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { ++ if (u4ClearCounter == 1) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidSetRxStatisticsForLinuxProc(prGlueInfo->prAdapter); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ } ++ } ++ ++ return count; ++ ++} /* end of procRxStatisticsWrite() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading Driver TX Statistic Counters to User Space. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procTxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char *p = page; ++ UINT_32 u4Count; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ SPRINTF(p, ("TX STATISTICS (Write 1 to clear):")); ++ SPRINTF(p, ("\n=================================\n")); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ u4Count += (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procTxStatisticsRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reset Driver TX Statistic Counters. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procTxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ UINT_32 u4ClearCounter; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ copy_from_user(acBuf, buffer, u4CopySize); ++ acBuf[u4CopySize] = '\0'; ++ ++ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { ++ if (u4ClearCounter == 1) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ } ++ } ++ ++ return count; ++ ++} /* end of procTxStatisticsWrite() */ ++#endif ++static struct proc_dir_entry *gprProcRoot; ++static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = { ++ "INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", "SW1", "SW2", ++ "SW3", "SW4", "HEM", "AIS", "RLM", "MEM", "CNM", "RSN", "BSS", "SCN", ++ "SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "OID", ++ "NIC" ++}; ++static UINT_8 aucProcBuf[1536]; ++static ssize_t procDbgLevelRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_32 u4CopySize = 0; ++ UINT_16 i; ++ UINT_16 u2ModuleNum = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ kalStrCpy(temp, "\nTEMP |LOUD |INFO |TRACE|EVENT|STATE|WARN |ERROR\n" ++ "bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0\n\n" ++ "Debug Module\tIndex\tLevel\tDebug Module\tIndex\tLevel\n\n"); ++ temp += kalStrLen(temp); ++ ++ u2ModuleNum = (sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0xfe; ++ for (i = 0; i < u2ModuleNum; i += 2) ++ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\tDBG_%s_IDX\t(0x%02x):\t0x%02x\n", ++ &aucDbModuleName[i][0], i, aucDebugModule[i], ++ &aucDbModuleName[i+1][0], i+1, aucDebugModule[i+1])); ++ ++ if ((sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0x1) ++ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\n", ++ &aucDbModuleName[u2ModuleNum][0], u2ModuleNum, aucDebugModule[u2ModuleNum])); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static ssize_t procDbgLevelWrite(struct file *file, const char *buffer, size_t count, loff_t *data) ++{ ++ UINT_32 u4NewDbgModule, u4NewDbgLevel; ++ UINT_8 i = 0; ++ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); ++ UINT_8 *temp = &aucProcBuf[0]; ++ ++ if (u4CopySize >= count + 1) ++ u4CopySize = count; ++ ++ kalMemSet(aucProcBuf, 0, u4CopySize); ++ ++ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { ++ kalPrint("error of copy from user\n"); ++ return -EFAULT; ++ } ++ aucProcBuf[u4CopySize] = '\0'; ++ ++ while (temp) { ++ if (sscanf(temp, "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2) { ++ kalPrint("debug module and debug level should be one byte in length\n"); ++ break; ++ } ++ if (u4NewDbgModule == 0xFF) { ++ for (i = 0; i < DBG_MODULE_NUM; i++) ++ aucDebugModule[i] = u4NewDbgLevel & DBG_CLASS_MASK; ++ ++ break; ++ } else if (u4NewDbgModule >= DBG_MODULE_NUM) { ++ kalPrint("debug module index should less than %d\n", DBG_MODULE_NUM); ++ break; ++ } ++ aucDebugModule[u4NewDbgModule] = u4NewDbgLevel & DBG_CLASS_MASK; ++ temp = kalStrChr(temp, ','); ++ if (!temp) ++ break; ++ temp++; /* skip ',' */ ++ } ++ return count; ++} ++ ++ ++static const struct file_operations dbglevel_ops = { ++ .owner = THIS_MODULE, ++ .read = procDbgLevelRead, ++ .write = procDbgLevelWrite, ++}; ++ ++static ssize_t procTxDoneCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_32 u4CopySize = 0; ++ UINT_16 u2TxDoneCfg = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ u2TxDoneCfg = StatsGetCfgTxDone(); ++ SPRINTF(temp, ("Tx Done Configure:\nARP %d\tDNS %d\nTCP %d\tUDP %d\nEAPOL %d\tDHCP %d\nICMP %d\n", ++ !!(u2TxDoneCfg & CFG_ARP), !!(u2TxDoneCfg & CFG_DNS), !!(u2TxDoneCfg & CFG_TCP), ++ !!(u2TxDoneCfg & CFG_UDP), !!(u2TxDoneCfg & CFG_EAPOL), !!(u2TxDoneCfg & CFG_DHCP), ++ !!(u2TxDoneCfg & CFG_ICMP))); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static ssize_t procTxDoneCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) ++{ ++#define MODULE_NAME_LENGTH 6 ++ ++ UINT_8 i = 0; ++ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_16 u2SetTxDoneCfg = 0; ++ UINT_16 u2ClsTxDoneCfg = 0; ++ UINT_8 aucModule[MODULE_NAME_LENGTH]; ++ UINT_32 u4Enabled; ++ UINT_8 aucModuleArray[][MODULE_NAME_LENGTH] = {"ARP", "DNS", "TCP", "UDP", "EAPOL", "DHCP", "ICMP"}; ++ ++ if (u4CopySize >= count + 1) ++ u4CopySize = count; ++ ++ kalMemSet(aucProcBuf, 0, u4CopySize); ++ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { ++ kalPrint("error of copy from user\n"); ++ return -EFAULT; ++ } ++ aucProcBuf[u4CopySize] = '\0'; ++ temp = &aucProcBuf[0]; ++ while (temp) { ++ /* pick up a string and teminated after meet : */ ++ if (sscanf(temp, "%s %d", aucModule, &u4Enabled) != 2) { ++ kalPrint("read param fail, aucModule=%s\n", aucModule); ++ break; ++ } ++ for (i = 0; i < sizeof(aucModuleArray)/MODULE_NAME_LENGTH; i++) { ++ if (kalStrniCmp(aucModule, aucModuleArray[i], MODULE_NAME_LENGTH) == 0) { ++ if (u4Enabled) ++ u2SetTxDoneCfg |= 1 << i; ++ else ++ u2ClsTxDoneCfg |= 1 << i; ++ break; ++ } ++ } ++ temp = kalStrChr(temp, ','); ++ if (!temp) ++ break; ++ temp++; /* skip ',' */ ++ } ++ if (u2SetTxDoneCfg) ++ StatsSetCfgTxDone(u2SetTxDoneCfg, TRUE); ++ ++ if (u2ClsTxDoneCfg) ++ StatsSetCfgTxDone(u2ClsTxDoneCfg, FALSE); ++ return count; ++} ++ ++static const struct file_operations proc_txdone_ops = { ++ .owner = THIS_MODULE, ++ .read = procTxDoneCfgRead, ++ .write = procTxDoneCfgWrite, ++}; ++ ++static ssize_t procAutoPerCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_32 u4CopySize = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ SPRINTF(temp, ("Auto Performance Configure:\nperiod\tL1\nL2\tL3\n")); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static ssize_t procAutoPerCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) ++{ ++ DBGLOG(INIT, WARN, "%s\n", __func__); ++ return 0; ++} ++ ++static const struct file_operations auto_per_ops = { ++ .owner = THIS_MODULE, ++ .read = procAutoPerCfgRead, ++ .write = procAutoPerCfgWrite, ++}; ++ ++ ++static ssize_t procCmdDebug(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_32 u4CopySize = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ wlanDumpTcResAndTxedCmd(aucProcBuf, sizeof(aucProcBuf)); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static const struct file_operations proc_CmdDebug_ops = { ++ .owner = THIS_MODULE, ++ .read = procCmdDebug, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function create a PROC fs in linux /proc/net subdirectory. ++* ++* \param[in] prDev Pointer to the struct net_device. ++* \param[in] pucDevName Pointer to the name of net_device. ++* ++* \return N/A ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++#if CFG_SUPPORT_THERMO_THROTTLING ++ ++/** ++ * This function is called then the /proc file is read ++ * ++ */ ++typedef struct _COEX_BUF1 { ++ UINT8 buffer[128]; ++ INT32 availSize; ++} COEX_BUF1, *P_COEX_BUF1; ++ ++COEX_BUF1 gCoexBuf1; ++ ++static ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ ++ INT32 retval = 0; ++ INT32 i_ret = 0; ++ CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; ++ ++ if (*f_pos > 0) { ++ retval = 0; ++ } else { ++ /*len = sprintf(page, "%d\n", g_psm_enable); */ ++#if 1 ++ if (gCoexBuf1.availSize <= 0) { ++ DBGLOG(INIT, WARN, "no data available\n"); ++ retval = strlen(warn_msg) + 1; ++ if (count < retval) ++ retval = count; ++ i_ret = copy_to_user(buf, warn_msg, retval); ++ if (i_ret) { ++ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ } else ++#endif ++ { ++ INT32 i = 0; ++ INT32 len = 0; ++ CHAR msg_info[128]; ++ INT32 max_num = 0; ++ /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page ++ buffer is not enough, a bomb is placed here on unexpected condition */ ++ ++ DBGLOG(INIT, TRACE, "%d bytes available\n", gCoexBuf1.availSize); ++ max_num = ((sizeof(msg_info) > count ? sizeof(msg_info) : count) - 1) / 5; ++ ++ if (max_num > gCoexBuf1.availSize) ++ max_num = gCoexBuf1.availSize; ++ else ++ DBGLOG(INIT, TRACE, ++ "round to %d bytes due to local buffer size limitation\n", max_num); ++ ++ for (i = 0; i < max_num; i++) ++ len += sprintf(msg_info + len, "%d", gCoexBuf1.buffer[i]); ++ ++ len += sprintf(msg_info + len, "\n"); ++ retval = len; ++ ++ i_ret = copy_to_user(buf, msg_info, retval); ++ if (i_ret) { ++ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ } ++ } ++ gCoexBuf1.availSize = 0; ++err_exit: ++ ++ return retval; ++} ++ ++#if 1 ++typedef INT32 (*WLAN_DEV_DBG_FUNC)(void); ++static INT32 wlan_get_thermo_power(void); ++static INT32 wlan_get_link_mode(void); ++ ++static const WLAN_DEV_DBG_FUNC wlan_dev_dbg_func[] = { ++ [0] = wlan_get_thermo_power, ++ [1] = wlan_get_link_mode, ++ ++}; ++ ++INT32 wlan_get_thermo_power(void) ++{ ++ P_ADAPTER_T prAdapter; ++ ++ prAdapter = g_prGlueInfo_proc->prAdapter; ++ ++ if (prAdapter->u4AirDelayTotal > 100) ++ gCoexBuf1.buffer[0] = 100; ++ else ++ gCoexBuf1.buffer[0] = prAdapter->u4AirDelayTotal; ++ gCoexBuf1.availSize = 1; ++ DBGLOG(RLM, TRACE, "PROC %s thrmo_power(%d)\n", __func__, gCoexBuf1.buffer[0]); ++ ++ return 0; ++} ++ ++INT32 wlan_get_link_mode(void) ++{ ++ UINT_8 ucLinkMode = 0; ++ P_ADAPTER_T prAdapter; ++ BOOLEAN fgIsAPmode; ++ ++ prAdapter = g_prGlueInfo_proc->prAdapter; ++ fgIsAPmode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); ++ ++ DBGLOG(RLM, TRACE, "PROC %s AIS(%d)P2P(%d)AP(%d)\n", ++ __func__, ++ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState, ++ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState, fgIsAPmode); ++ ++#if 1 ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ ucLinkMode |= BIT(0); ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ ucLinkMode |= BIT(1); ++ if (fgIsAPmode) ++ ucLinkMode |= BIT(2); ++ ++#endif ++ gCoexBuf1.buffer[0] = ucLinkMode; ++ gCoexBuf1.availSize = 1; ++ ++ return 0; ++} ++ ++static ssize_t procfile_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) ++{ ++ char buf[256]; ++ char *pBuf; ++ ULONG len = count; ++ INT32 x = 0, y = 0, z = 0; ++ char *pToken = NULL; ++ char *pDelimiter = " \t"; ++ INT32 i4Ret = 0; ++ ++ if (copy_from_user(gCoexBuf1.buffer, buffer, count)) ++ return -EFAULT; ++ /* gCoexBuf1.availSize = count; */ ++ ++ /* return gCoexBuf1.availSize; */ ++#if 1 ++ DBGLOG(INIT, TRACE, "write parameter len = %d\n\r", (INT32) len); ++ if (len >= sizeof(buf)) { ++ DBGLOG(INIT, ERROR, "input handling fail!\n"); ++ len = sizeof(buf) - 1; ++ return -1; ++ } ++ ++ if (copy_from_user(buf, buffer, len)) ++ return -EFAULT; ++ buf[len] = '\0'; ++ DBGLOG(INIT, TRACE, "write parameter data = %s\n\r", buf); ++ ++ pBuf = buf; ++ pToken = strsep(&pBuf, pDelimiter); ++ ++ if (pToken) /* x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; */ ++ i4Ret = kalkStrtos32(pToken, 16, &x); ++ if (!i4Ret) ++ DBGLOG(INIT, TRACE, "x = 0x%x\n", x); ++ ++#if 1 ++ pToken = strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ i4Ret = kalkStrtos32(pToken, 16, &y); /* y = simple_strtol(pToken, NULL, 16); */ ++ if (!i4Ret) ++ DBGLOG(INIT, TRACE, "y = 0x%08x\n\r", y); ++ } else { ++ y = 3000; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ y = 0x80000000; ++ } ++ ++ pToken = strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ i4Ret = kalkStrtos32(pToken, 16, &z); /* z = simple_strtol(pToken, NULL, 16); */ ++ if (!i4Ret) ++ DBGLOG(INIT, TRACE, "z = 0x%08x\n\r", z); ++ } else { ++ z = 10; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ z = 0xffffffff; ++ } ++ ++ DBGLOG(INIT, TRACE, " x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); ++#endif ++ ++ if (((sizeof(wlan_dev_dbg_func) / sizeof(wlan_dev_dbg_func[0])) > x) && NULL != wlan_dev_dbg_func[x]) ++ (*wlan_dev_dbg_func[x]) (); ++ else ++ DBGLOG(INIT, ERROR, "no handler defined for command id(0x%08x)\n\r", x); ++#endif ++ ++ /* len = gCoexBuf1.availSize; */ ++ return len; ++} ++#endif ++ static const struct file_operations proc_fops = { ++ .owner = THIS_MODULE, ++ .read = procfile_read, ++ .write = procfile_write, ++ }; ++#endif ++ ++INT_32 procInitFs(VOID) ++{ ++ struct proc_dir_entry *prEntry; ++ ++ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { ++ kalPrint("init proc fs fail: proc_net == NULL\n"); ++ return -ENOENT; ++ } ++ ++ /* ++ * Directory: Root (/proc/net/wlan0) ++ */ ++ ++ gprProcRoot = proc_mkdir(PROC_ROOT_NAME, init_net.proc_net); ++ if (!gprProcRoot) { ++ kalPrint("gprProcRoot == NULL\n"); ++ return -ENOENT; ++ } ++ proc_set_user(gprProcRoot, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ prEntry = proc_create(PROC_DBG_LEVEL_NAME, 0664, gprProcRoot, &dbglevel_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry dbgLevel\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ prEntry = proc_create(PROC_NEED_TX_DONE, 0664, gprProcRoot, &proc_txdone_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry dbgLevel\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ prEntry = proc_create(PROC_AUTO_PER_CFG, 0664, gprProcRoot, &auto_per_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry autoPerCfg\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ return 0; ++} /* end of procInitProcfs() */ ++ ++INT_32 procUninitProcFs(VOID) ++{ ++ remove_proc_entry(PROC_DBG_LEVEL_NAME, gprProcRoot); ++ remove_proc_subtree(PROC_ROOT_NAME, init_net.proc_net); ++ remove_proc_entry(PROC_AUTO_PER_CFG, gprProcRoot); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function clean up a PROC fs created by procInitProcfs(). ++* ++* \param[in] prDev Pointer to the struct net_device. ++* \param[in] pucDevName Pointer to the name of net_device. ++* ++* \return N/A ++*/ ++/*----------------------------------------------------------------------------*/ ++INT_32 procRemoveProcfs(VOID) ++{ ++ /* remove root directory (proc/net/wlan0) */ ++ /* remove_proc_entry(pucDevName, init_net.proc_net); */ ++ remove_proc_entry(PROC_WLAN_THERMO, gprProcRoot); ++ remove_proc_entry(PROC_CMD_DEBUG_NAME, gprProcRoot); ++#if CFG_SUPPORT_THERMO_THROTTLING ++ g_prGlueInfo_proc = NULL; ++#endif ++ return 0; ++} /* end of procRemoveProcfs() */ ++ ++INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo) ++{ ++ struct proc_dir_entry *prEntry; ++ ++ DBGLOG(INIT, TRACE, "[%s]\n", __func__); ++ ++#if CFG_SUPPORT_THERMO_THROTTLING ++ g_prGlueInfo_proc = prGlueInfo; ++#endif ++ ++ prGlueInfo->pProcRoot = gprProcRoot; ++ ++ prEntry = proc_create(PROC_WLAN_THERMO, 0664, gprProcRoot, &proc_fops); ++ if (prEntry == NULL) { ++ DBGLOG(INIT, ERROR, "Unable to create /proc entry\n\r"); ++ return -1; ++ } ++ ++ prEntry = proc_create(PROC_CMD_DEBUG_NAME, 0444, gprProcRoot, &proc_CmdDebug_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry dbgLevel\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ return 0; ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +new file mode 100644 +index 000000000000..f97db8a69fd2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +@@ -0,0 +1,228 @@ ++/* ++** Id: @(#) gl_rst.c@@ ++*/ ++ ++/*! \file gl_rst.c ++ \brief Main routines for supporintg MT6620 whole-chip reset mechanism ++ ++ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_rst.c ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 04 22 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * skip power-off handshaking when RESET indication is received. ++ * ++ * 04 14 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected ++ * 2. add dummy function for both Win32 and Linux part. ++ * ++ * 03 30 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * use netlink unicast instead of broadcast ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++ ++#include "precomp.h" ++#include "gl_rst.h" ++ ++#if CFG_CHIP_RESET_SUPPORT ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++BOOLEAN fgIsResetting = FALSE; ++UINT_32 g_IsNeedDoChipReset = 0; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static RESET_STRUCT_T wifi_rst; ++ ++static void mtk_wifi_reset(struct work_struct *work); ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, ++ ENUM_WMTDRV_TYPE_T eDstType, ++ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for ++ * 1. register wifi reset callback ++ * 2. initialize wifi reset work ++ * ++ * @param none ++ * ++ * @retval none ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID glResetInit(VOID) ++{ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++ /* 1. Register reset callback */ ++ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB) glResetCallback); ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++ /* 2. Initialize reset work */ ++ INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for ++ * 1. deregister wifi reset callback ++ * ++ * @param none ++ * ++ * @retval none ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID glResetUninit(VOID) ++{ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++ /* 1. Deregister reset callback */ ++ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI); ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is invoked when there is reset messages indicated ++ * ++ * @param eSrcType ++ * eDstType ++ * eMsgType ++ * prMsgBody ++ * u4MsgLength ++ * ++ * @retval ++ */ ++/*----------------------------------------------------------------------------*/ ++static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, ++ ENUM_WMTDRV_TYPE_T eDstType, ++ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength) ++{ ++ switch (eMsgType) { ++ case WMTMSG_TYPE_RESET: ++ if (u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) { ++ P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody; ++ ++ switch (*prRstMsg) { ++ case WMTRSTMSG_RESET_START: ++ DBGLOG(INIT, WARN, "Whole chip reset start!\n"); ++ fgIsResetting = TRUE; ++ wifi_reset_start(); ++ break; ++ ++ case WMTRSTMSG_RESET_END: ++ DBGLOG(INIT, WARN, "Whole chip reset end!\n"); ++ fgIsResetting = FALSE; ++ wifi_rst.rst_data = RESET_SUCCESS; ++ schedule_work(&(wifi_rst.rst_work)); ++ break; ++ ++ case WMTRSTMSG_RESET_END_FAIL: ++ DBGLOG(INIT, WARN, "Whole chip reset fail!\n"); ++ fgIsResetting = FALSE; ++ wifi_rst.rst_data = RESET_FAIL; ++ schedule_work(&(wifi_rst.rst_work)); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is called for wifi reset ++ * ++ * @param skb ++ * info ++ * ++ * @retval 0 ++ * nonzero ++ */ ++/*----------------------------------------------------------------------------*/ ++static void mtk_wifi_reset(struct work_struct *work) ++{ ++ RESET_STRUCT_T *rst = container_of(work, RESET_STRUCT_T, rst_work); ++ ++ wifi_reset_end(rst->rst_data); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is called for generating reset request to WMT ++ * ++ * @param None ++ * ++ * @retval None ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID glSendResetRequest(VOID) ++{ ++ /* WMT thread would trigger whole chip reset itself */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is called for checking if connectivity chip is resetting ++ * ++ * @param None ++ * ++ * @retval TRUE ++ * FALSE ++ */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsResetting(VOID) ++{ ++ return fgIsResetting; ++} ++ ++#endif /* CFG_CHIP_RESET_SUPPORT */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c +new file mode 100644 +index 000000000000..862d011a43df +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c +@@ -0,0 +1,1220 @@ ++/* ++** Id: @(#) gl_cfg80211.c@@ ++*/ ++ ++/*! \file gl_cfg80211.c ++ \brief Main routines for supporintg MT6620 cfg80211 control interface ++ ++ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_cfg80211.c ++** ++** 09 05 2013 cp.wu ++** correct length to pass to wlanoidSetBssid() ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 11 23 2012 yuche.tsai ++** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely ++** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++ ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#include "gl_cfg80211.h" ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++static struct nla_policy nla_parse_policy[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1] = { ++ [GSCAN_ATTRIBUTE_NUM_BUCKETS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BASE_PERIOD] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKETS_BAND] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_ID] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_PERIOD] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_CHANNELS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_REPORT_THRESHOLD] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_REPORT_EVENTS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BSSID] = {.type = NLA_UNSPEC}, ++ [GSCAN_ATTRIBUTE_RSSI_LOW] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_RSSI_HIGH] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE] = {.type = NLA_U16}, ++ [GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_MIN_BREACHING] = {.type = NLA_U16}, ++ [GSCAN_ATTRIBUTE_NUM_AP] = {.type = NLA_U16}, ++ [GSCAN_ATTRIBUTE_HOTLIST_FLUSH] = {.type = NLA_U8}, ++ [GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH] = {.type = NLA_U8}, ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ struct nlattr *attr; ++ UINT_32 band = 0; ++ UINT_8 ucNumOfChannel, i, j; ++ RF_CHANNEL_INFO_T aucChannelList[64]; ++ UINT_32 num_channels; ++ wifi_channel channels[64]; ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy && wdev); ++ if ((data == NULL) || !data_len) ++ return -EINVAL; ++ ++ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == WIFI_ATTRIBUTE_BAND) ++ band = nla_get_u32(attr); ++ ++ DBGLOG(REQ, INFO, "Get channel list for band: %d\n", band); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (!prGlueInfo) ++ return -EFAULT; ++ ++ if (band == 0) { /* 2.4G band */ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, ++ 64, &ucNumOfChannel, aucChannelList); ++ } else { /* 5G band */ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, ++ 64, &ucNumOfChannel, aucChannelList); ++ } ++ ++ kalMemZero(channels, sizeof(channels)); ++ for (i = 0, j = 0; i < ucNumOfChannel; i++) { ++ /* We need to report frequency list to HAL */ ++ channels[j] = nicChannelNum2Freq(aucChannelList[i].ucChannelNum) / 1000; ++ if (channels[j] == 0) ++ continue; ++ else if ((prGlueInfo->prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_TW) && ++ (channels[j] >= 5180 && channels[j] <= 5260)) { ++ /* Taiwan NCC has resolution to follow FCC spec to support 5G Band 1/2/3/4 ++ * (CH36~CH48, CH52~CH64, CH100~CH140, CH149~CH165) ++ * Filter CH36~CH52 for compatible with some old devices. ++ */ ++ continue; ++ } else { ++ DBGLOG(REQ, INFO, "channels[%d] = %d\n", j, channels[j]); ++ j++; ++ } ++ } ++ num_channels = j; ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(channels)); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "Allocate skb failed\n"); ++ return -ENOMEM; ++ } ++ ++ if (unlikely(nla_put_u32(skb, WIFI_ATTRIBUTE_NUM_CHANNELS, num_channels) < 0)) ++ goto nla_put_failure; ++ ++ if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_CHANNEL_LIST, ++ (sizeof(wifi_channel) * num_channels), channels) < 0)) ++ goto nla_put_failure; ++ ++ return cfg80211_vendor_cmd_reply(skb); ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -EFAULT; ++} ++ ++int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ struct nlattr *attr; ++ UINT_8 country[2] = {0, 0}; ++ ++ ASSERT(wiphy && wdev); ++ if ((data == NULL) || (data_len == 0)) ++ return -EINVAL; ++ ++ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == WIFI_ATTRIBUTE_COUNTRY_CODE) { ++ country[0] = *((PUINT_8)nla_data(attr)); ++ country[1] = *((PUINT_8)nla_data(attr) + 1); ++ } ++ ++ DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], country[1]); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (!prGlueInfo) ++ return -EFAULT; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, country, 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Status = -EINVAL; ++ PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T rGscanCapabilities; ++ struct sk_buff *skb; ++ /* UINT_32 u4BufLen; */ ++ ++ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rGscanCapabilities)); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&rGscanCapabilities, sizeof(rGscanCapabilities)); ++ ++ /*rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rGscanCapabilities, ++ sizeof(rGscanCapabilities), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4BufLen); */ ++ rGscanCapabilities.max_scan_cache_size = PSCAN_MAX_SCAN_CACHE_SIZE; ++ rGscanCapabilities.max_scan_buckets = GSCAN_MAX_BUCKETS; ++ rGscanCapabilities.max_ap_cache_per_scan = PSCAN_MAX_AP_CACHE_PER_SCAN; ++ rGscanCapabilities.max_rssi_sample_size = 10; ++ rGscanCapabilities.max_scan_reporting_threshold = GSCAN_MAX_REPORT_THRESHOLD; ++ rGscanCapabilities.max_hotlist_aps = MAX_HOTLIST_APS; ++ rGscanCapabilities.max_significant_wifi_change_aps = MAX_SIGNIFICANT_CHANGE_APS; ++ rGscanCapabilities.max_bssid_history_entries = PSCAN_MAX_AP_CACHE_PER_SCAN * PSCAN_MAX_SCAN_CACHE_SIZE; ++ ++ /* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); */ ++ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_ID, GOOGLE_OUI); */ ++ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_GET_CAPABILITIES); */ ++ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities);*/ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CAPABILITIES, ++ sizeof(rGscanCapabilities), &rGscanCapabilities) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ return i4Status; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ /* CMD_GSCN_REQ_T rCmdGscnParam; */ ++ ++ /* INT_32 i4Status = -EINVAL; */ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; ++ struct nlattr *attr[GSCAN_ATTRIBUTE_REPORT_EVENTS + 1]; ++ struct nlattr *pbucket, *pchannel; ++ UINT_32 len_basic, len_bucket, len_channel; ++ int i, j, k; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ ++ prWifiScanCmd = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); ++ if (!prWifiScanCmd) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); ++ return -ENOMEM; ++ } ++ ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_REPORT_EVENTS + 1)); ++ ++ nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL); ++ len_basic = 0; ++ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BASE_PERIOD: ++ prWifiScanCmd->base_period = nla_get_u32(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_BUCKETS: ++ prWifiScanCmd->num_buckets = nla_get_u32(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "attr=0x%x, num_buckets=%d nla_len=%d, \r\n", ++ *(UINT_32 *) attr[k], prWifiScanCmd->num_buckets, attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ pbucket = (struct nlattr *)((UINT_8 *) data + len_basic); ++ DBGLOG(REQ, TRACE, "+++basic attribute size=%d pbucket=%p\r\n", len_basic, pbucket); ++ ++ for (i = 0; i < prWifiScanCmd->num_buckets; i++) { ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)pbucket, ++ nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ len_bucket = 0; ++ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BUCKETS_BAND: ++ prWifiScanCmd->buckets[i].band = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_BUCKET_ID: ++ prWifiScanCmd->buckets[i].bucket = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_BUCKET_PERIOD: ++ prWifiScanCmd->buckets[i].period = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_REPORT_EVENTS: ++ prWifiScanCmd->buckets[i].report_events = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: ++ prWifiScanCmd->buckets[i].num_channels = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "bucket%d: attr=0x%x, num_channels=%d nla_len = %d, \r\n", ++ i, *(UINT_32 *) attr[k], nla_get_u32(attr[k]), attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ pbucket = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); ++ /* request.attr_start(i) as nested attribute */ ++ DBGLOG(REQ, TRACE, "+++pure bucket size=%d pbucket=%p \r\n", len_bucket, pbucket); ++ pbucket = (struct nlattr *)((UINT_8 *) pbucket + len_bucket); ++ /* pure bucket payload, not include channels */ ++ ++ /*don't need to use nla_parse_nested to parse channels */ ++ /* the header of channel in bucket i */ ++ pchannel = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); ++ for (j = 0; j < prWifiScanCmd->buckets[i].num_channels; j++) { ++ prWifiScanCmd->buckets[i].channels[j].channel = nla_get_u32(pchannel); ++ len_channel = NLA_ALIGN(pchannel->nla_len); ++ DBGLOG(REQ, TRACE, ++ "attr=0x%x, channel=%d, \r\n", *(UINT_32 *) pchannel, nla_get_u32(pchannel)); ++ ++ pchannel = (struct nlattr *)((UINT_8 *) pchannel + len_channel); ++ } ++ pbucket = pchannel; ++ } ++ ++ DBGLOG(REQ, TRACE, "base_period=%d, num_buckets=%d, bucket0: %d %d %d %d", ++ prWifiScanCmd->base_period, prWifiScanCmd->num_buckets, ++ prWifiScanCmd->buckets[0].bucket, prWifiScanCmd->buckets[0].period, ++ prWifiScanCmd->buckets[0].band, prWifiScanCmd->buckets[0].report_events); ++ ++ DBGLOG(REQ, TRACE, "num_channels=%d, channel0=%d, channel1=%d; num_channels=%d, channel0=%d, channel1=%d", ++ prWifiScanCmd->buckets[0].num_channels, ++ prWifiScanCmd->buckets[0].channels[0].channel, prWifiScanCmd->buckets[0].channels[1].channel, ++ prWifiScanCmd->buckets[1].num_channels, ++ prWifiScanCmd->buckets[1].channels[0].channel, prWifiScanCmd->buckets[1].channels[1].channel); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetGSCNAParam, ++ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiScanCmd != NULL) ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ INT_32 i4Status = -EINVAL; ++ /*PARAM_WIFI_GSCAN_CMD_PARAMS rWifiScanCmd;*/ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; ++ struct nlattr *attr[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1]; ++ /* UINT_32 num_scans = 0; */ /* another attribute */ ++ int k; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ /*kalMemZero(&rWifiScanCmd, sizeof(rWifiScanCmd));*/ ++ prWifiScanCmd = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); ++ if (prWifiScanCmd == NULL) ++ goto nla_put_failure; ++ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1)); ++ ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, ++ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ for (k = GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN; k <= GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: ++ prWifiScanCmd->max_ap_per_scan = nla_get_u32(attr[k]); ++ break; ++ case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: ++ prWifiScanCmd->report_threshold = nla_get_u32(attr[k]); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: ++ prWifiScanCmd->num_scans = nla_get_u32(attr[k]); ++ break; ++ } ++ } ++ } ++ DBGLOG(REQ, TRACE, "attr=0x%x, attr2=0x%x ", *(UINT_32 *) attr[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN], ++ *(UINT_32 *) attr[GSCAN_ATTRIBUTE_REPORT_THRESHOLD]); ++ ++ DBGLOG(REQ, TRACE, "max_ap_per_scan=%d, report_threshold=%d num_scans=%d \r\n", ++ prWifiScanCmd->max_ap_per_scan, prWifiScanCmd->report_threshold, prWifiScanCmd->num_scans); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetGSCNAConfig, ++ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiScanCmd != NULL) ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len) ++{ ++ INT_32 i4Status = -EINVAL; ++ P_PARAM_WIFI_SIGNIFICANT_CHANGE prWifiChangeCmd = NULL; ++ UINT_8 flush = 0; ++ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ ++ struct nlattr **attr = NULL; ++ struct nlattr *paplist; ++ int i, k; ++ UINT_32 len_basic, len_aplist; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ for (i = 0; i < 6; i++) ++ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", ++ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), ++ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); ++ prWifiChangeCmd = kalMemAlloc(sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE), VIR_MEM_TYPE); ++ if (prWifiChangeCmd == NULL) ++ goto nla_put_failure; ++ kalMemZero(prWifiChangeCmd, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); ++ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); ++ if (attr == NULL) ++ goto nla_put_failure; ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, ++ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ len_basic = 0; ++ for (k = GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE; k <= GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: ++ prWifiChangeCmd->rssi_sample_size = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: ++ prWifiChangeCmd->lost_ap_sample_size = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_MIN_BREACHING: ++ prWifiChangeCmd->min_breaching = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_AP: ++ prWifiChangeCmd->num_ap = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", ++ *(UINT_32 *) attr[k], prWifiChangeCmd->num_ap, attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: ++ flush = nla_get_u8(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); ++ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); ++ ++ if (paplist->nla_type == GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS) ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ ++ for (i = 0; i < prWifiChangeCmd->num_ap; i++) { ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ /* request.attr_start(i) as nested attribute */ ++ len_aplist = 0; ++ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BSSID: ++ kalMemCopy(prWifiChangeCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_LOW: ++ prWifiChangeCmd->ap[i].low = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_HIGH: ++ prWifiChangeCmd->ap[i].high = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ if (((i + 1) % 4 == 0) || (i == prWifiChangeCmd->num_ap - 1)) ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); ++ else ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); ++ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); ++ } ++ ++ DBGLOG(REQ, TRACE, ++ "flush=%d, rssi_sample_size=%d lost_ap_sample_size=%d min_breaching=%d", ++ flush, prWifiChangeCmd->rssi_sample_size, prWifiChangeCmd->lost_ap_sample_size, ++ prWifiChangeCmd->min_breaching); ++ DBGLOG(REQ, TRACE, ++ "ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", ++ prWifiChangeCmd->ap[0].channel, prWifiChangeCmd->ap[0].low, prWifiChangeCmd->ap[0].high, ++ prWifiChangeCmd->ap[1].channel, prWifiChangeCmd->ap[1].low, prWifiChangeCmd->ap[1].high); ++ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); ++ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiChangeCmd) ++ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); ++ if (attr) ++ kalMemFree(attr, VIR_MEM_TYPE, ++ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ /*WLAN_STATUS rStatus;*/ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; ++ ++ INT_32 i4Status = -EINVAL; ++ P_PARAM_WIFI_BSSID_HOTLIST prWifiHotlistCmd = NULL; ++ UINT_8 flush = 0; ++ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ ++ struct nlattr **attr = NULL; ++ struct nlattr *paplist; ++ int i, k; ++ UINT_32 len_basic, len_aplist; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ for (i = 0; i < 5; i++) ++ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", ++ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), ++ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); ++ prWifiHotlistCmd = kalMemAlloc(sizeof(PARAM_WIFI_BSSID_HOTLIST), VIR_MEM_TYPE); ++ if (prWifiHotlistCmd == NULL) ++ goto nla_put_failure; ++ kalMemZero(prWifiHotlistCmd, sizeof(PARAM_WIFI_BSSID_HOTLIST)); ++ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); ++ if (attr == NULL) ++ goto nla_put_failure; ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_AP, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ len_basic = 0; ++ for (k = GSCAN_ATTRIBUTE_HOTLIST_FLUSH; k <= GSCAN_ATTRIBUTE_NUM_AP; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: ++ prWifiHotlistCmd->lost_ap_sample_size = nla_get_u32(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_AP: ++ prWifiHotlistCmd->num_ap = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", ++ *(UINT_32 *) attr[k], prWifiHotlistCmd->num_ap, attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: ++ flush = nla_get_u8(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); ++ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); ++ ++ if (paplist->nla_type == GSCAN_ATTRIBUTE_HOTLIST_BSSIDS) ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ ++ for (i = 0; i < prWifiHotlistCmd->num_ap; i++) { ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ /* request.attr_start(i) as nested attribute */ ++ len_aplist = 0; ++ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BSSID: ++ kalMemCopy(prWifiHotlistCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_LOW: ++ prWifiHotlistCmd->ap[i].low = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_HIGH: ++ prWifiHotlistCmd->ap[i].high = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ if (((i + 1) % 4 == 0) || (i == prWifiHotlistCmd->num_ap - 1)) ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); ++ else ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); ++ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); ++ } ++ ++ DBGLOG(REQ, TRACE, ++ "flush=%d, lost_ap_sample_size=%d, Hotlist:ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", ++ flush, prWifiHotlistCmd->lost_ap_sample_size, ++ prWifiHotlistCmd->ap[0].channel, prWifiHotlistCmd->ap[0].low, prWifiHotlistCmd->ap[0].high, ++ prWifiHotlistCmd->ap[1].channel, prWifiHotlistCmd->ap[1].low, prWifiHotlistCmd->ap[1].high); ++ ++ memcpy(&(rCmdPscnAddHotlist.aucMacAddr), &(prWifiHotlistCmd->ap[0].bssid), 6 * sizeof(UINT_8)); ++ rCmdPscnAddHotlist.ucFlags = (UINT_8) TRUE; ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); ++ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiHotlistCmd) ++ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); ++ if (attr) ++ kalMemFree(attr, VIR_MEM_TYPE, ++ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS rWifiScanActionCmd; ++ ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_8 gGScanEn = 0; ++ ++ static UINT_8 k; /* only for test */ ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", ++ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == GSCAN_ATTRIBUTE_ENABLE_FEATURE) ++ gGScanEn = nla_get_u32(attr); ++ DBGLOG(REQ, INFO, "gGScanEn=%d, \r\n", gGScanEn); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ if (gGScanEn == TRUE) ++ rWifiScanActionCmd.ucPscanAct = ENABLE; ++ else ++ rWifiScanActionCmd.ucPscanAct = DISABLE; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetGSCNAction, ++ &rWifiScanActionCmd, ++ sizeof(PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ /* mtk_cfg80211_vendor_get_scan_results(wiphy, wdev, data, data_len ); */ ++ ++ return 0; ++ ++ /* only for test */ ++ if (k % 3 == 1) { ++ mtk_cfg80211_vendor_event_significant_change_results(wiphy, wdev, NULL, 0); ++ mtk_cfg80211_vendor_event_hotlist_ap_found(wiphy, wdev, NULL, 0); ++ mtk_cfg80211_vendor_event_hotlist_ap_lost(wiphy, wdev, NULL, 0); ++ } ++ k++; ++ ++ return 0; ++ ++nla_put_failure: ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len) ++{ ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_8 gFullScanResultsEn = 0; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", ++ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == GSCAN_ENABLE_FULL_SCAN_RESULTS) ++ gFullScanResultsEn = nla_get_u32(attr); ++ DBGLOG(REQ, INFO, "gFullScanResultsEn=%d, \r\n", gFullScanResultsEn); ++ ++ return 0; ++ ++ /* only for test */ ++ mtk_cfg80211_vendor_event_complete_scan(wiphy, wdev, WIFI_SCAN_COMPLETE); ++ mtk_cfg80211_vendor_event_scan_results_available(wiphy, wdev, 4); ++ if (gFullScanResultsEn == TRUE) ++ mtk_cfg80211_vendor_event_full_scan_results(wiphy, wdev, NULL, 0); ++ ++ return 0; ++ ++nla_put_failure: ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ /*WLAN_STATUS rStatus;*/ ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_WIFI_GSCAN_GET_RESULT_PARAMS rGSscnResultParm; ++ ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_32 get_num = 0, real_num = 0; ++ UINT_8 flush = 0; ++ /*PARAM_WIFI_GSCAN_RESULT result[4], *pResult; ++ struct sk_buff *skb;*/ ++ int i; /*int j;*/ ++ /*UINT_32 scan_id;*/ ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, TRACE, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ for (i = 0; i < 2; i++) ++ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), ++ *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), ++ *((UINT_32 *) data + i * 4 + 3)); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { ++ get_num = nla_get_u32(attr); ++ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); ++ } ++ if (attr->nla_type == GSCAN_ATTRIBUTE_FLUSH_RESULTS) { ++ flush = nla_get_u8(attr); ++ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); ++ } ++ DBGLOG(REQ, TRACE, "number=%d, flush=%d \r\n", get_num, flush); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ real_num = (get_num < PSCAN_MAX_SCAN_CACHE_SIZE) ? get_num : PSCAN_MAX_SCAN_CACHE_SIZE; ++ get_num = real_num; ++ ++#if 0 /* driver buffer FW results and reports by buffer workaround for FW mismatch with hal results numbers */ ++ g_GetResultsCmdCnt++; ++ DBGLOG(REQ, INFO, ++ "(g_GetResultsCmdCnt [%d], g_GetResultsBufferedCnt [%d]\n", g_GetResultsCmdCnt, ++ g_GetResultsBufferedCnt); ++ ++ BOOLEAN fgIsGetResultFromBuffer = FALSE; ++ UINT_8 BufferedResultReportIndex = 0; ++ ++ if (g_GetResultsBufferedCnt > 0) { ++ ++ DBGLOG(REQ, INFO, ++ "(g_GetResultsBufferedCnt > 0), report buffered results instead of ask from FW\n"); ++ ++ /* reply the results to wifi_hal */ ++ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { ++ ++ if (g_arGscanResultsIndicateNumber[i] > 0) { ++ real_num = g_arGscanResultsIndicateNumber[i]; ++ get_num = real_num; ++ g_arGscanResultsIndicateNumber[i] = 0; ++ fgIsGetResultFromBuffer = TRUE; ++ BufferedResultReportIndex = i; ++ break; ++ } ++ } ++ if (i == MAX_BUFFERED_GSCN_RESULTS) ++ DBGLOG(REQ, TRACE, "all buffered results are invalid, unexpected case \r\n"); ++ DBGLOG(REQ, TRACE, "BufferedResultReportIndex[%d] i = %d real_num[%d] get_num[%d] \r\n", ++ BufferedResultReportIndex, i, real_num, get_num); ++ } ++#endif ++ ++ rGSscnResultParm.get_num = get_num; ++ rGSscnResultParm.flush = flush; ++#if 0/* //driver buffer FW results and reports by buffer workaround for FW results mismatch with hal results number */ ++ if (fgIsGetResultFromBuffer) { ++ nicRxProcessGSCNEvent(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); ++ g_GetResultsBufferedCnt--; ++ g_GetResultsCmdCnt--; ++ nicRxReturnRFB(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); ++ } else ++#endif ++ { ++ kalIoctl(prGlueInfo, ++ wlanoidGetGSCNResult, ++ &rGSscnResultParm, ++ sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ return 0; ++ ++nla_put_failure: ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Status = -EINVAL; ++ PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities; ++ struct sk_buff *skb; ++ ++ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rRttCapabilities)); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities)); ++ ++ /*rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rRttCapabilities, ++ sizeof(rRttCapabilities), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4BufLen); */ ++ rRttCapabilities.rtt_one_sided_supported = 0; ++ rRttCapabilities.rtt_ftm_supported = 0; ++ rRttCapabilities.lci_support = 0; ++ rRttCapabilities.lcr_support = 0; ++ rRttCapabilities.preamble_support = 0; ++ rRttCapabilities.bw_support = 0; ++ ++ if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES, ++ sizeof(rRttCapabilities), &rRttCapabilities) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ return i4Status; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ INT_32 i4Status = -EINVAL; ++ WIFI_RADIO_STAT *pRadioStat; ++ struct sk_buff *skb; ++ UINT_32 u4BufLen; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ ++ u4BufLen = sizeof(WIFI_RADIO_STAT) + sizeof(WIFI_IFACE_STAT); ++ pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE); ++ if (!pRadioStat) { ++ DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", __func__); ++ return -ENOMEM; ++ } ++ kalMemZero(pRadioStat, u4BufLen); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen); ++ if (!skb) { ++ DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ /*rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rRadioStat, ++ sizeof(rRadioStat), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4BufLen); */ ++ /* only for test */ ++ pRadioStat->radio = 10; ++ pRadioStat->on_time = 11; ++ pRadioStat->tx_time = 12; ++ pRadioStat->num_channels = 4; ++ ++ /*NLA_PUT(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat);*/ ++ if (unlikely(nla_put(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); ++ return -1; /* not support LLS now*/ ++ /* return i4Status; */ ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete) ++{ ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ /* WIFI_SCAN_EVENT complete_scan; */ ++ ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(complete), GSCAN_EVENT_COMPLETE_SCAN, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ /* complete_scan = WIFI_SCAN_COMPLETE; */ ++ /*NLA_PUT_U32(skb, GSCAN_EVENT_COMPLETE_SCAN, complete);*/ ++ { ++ unsigned int __tmp = complete; ++ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_COMPLETE_SCAN, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num) ++{ ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ /* UINT_32 scan_result; */ ++ ++ DBGLOG(REQ, INFO, "%s for vendor command %d \r\n", __func__, num); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(num), GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ /* scan_result = 2; */ ++ /*NLA_PUT_U32(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, num);*/ ++ { ++ unsigned int __tmp = num; ++ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_GSCAN_RESULT result; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(result), GSCAN_EVENT_FULL_SCAN_RESULTS, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&result, sizeof(result)); ++ kalMemCopy(result.ssid, "Gscan_full_test", sizeof("Gscan_full_test")); ++ result.channel = 2437; ++ ++ /* kalMemCopy(&result, pdata, sizeof(PARAM_WIFI_GSCAN_RESULT); */ ++ /*NLA_PUT(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, sizeof(result), &result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, ++ sizeof(result), &result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_CHANGE_RESULT result[2], *presult; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_CHANGE_RESULT), ++ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ presult = result; ++ kalMemZero(presult, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2)); ++ /* only for test */ ++ kalMemCopy(presult->bssid, "213123", sizeof(mac_addr)); ++ presult->channel = 2437; ++ presult->rssi[0] = -45; ++ presult->rssi[1] = -46; ++ presult++; ++ presult->channel = 2439; ++ presult->rssi[0] = -47; ++ presult->rssi[1] = -48; ++ /*NLA_PUT(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, ++ (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_GSCAN_RESULT result[2], *presult; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), ++ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ presult = result; ++ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); ++ /* only for test */ ++ kalMemCopy(presult->bssid, "123123", sizeof(mac_addr)); ++ presult->channel = 2441; ++ presult->rssi = -45; ++ presult++; ++ presult->channel = 2443; ++ presult->rssi = -47; ++ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, ++ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_GSCAN_RESULT result[2], *presult; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), ++ GSCAN_EVENT_HOTLIST_RESULTS_LOST, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ presult = result; ++ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); ++ /* only for test */ ++ kalMemCopy(presult->bssid, "321321", sizeof(mac_addr)); ++ presult->channel = 2445; ++ presult->rssi = -46; ++ presult++; ++ presult->channel = 2447; ++ presult->rssi = -48; ++ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, ++ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c +new file mode 100644 +index 000000000000..1793742e9802 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c +@@ -0,0 +1,4158 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3 ++*/ ++ ++/*! \file gl_wext.c ++ \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver. ++*/ ++ ++/* ++** Log: gl_wext.c ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 01 16 2012 wh.su ++ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl ++ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 23 2011 tsaiyuan.hsu ++ * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state ++ * avoid entering D3 state after deep sleep. ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 27 2011 wh.su ++ * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query ++ * the ap address ++ * Remove the netif check while query bssid and ssid ++ * ++ * 07 26 2011 chinglan.wang ++ * NULL ++ * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection.. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 05 17 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Initialize the vairlabes. ++ * ++ * 05 11 2011 jeffrey.chang ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * modify set_tx_pow ioctl ++ * ++ * 03 29 2011 terry.wu ++ * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring ++ * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of ++ * essid storage array. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 02 21 2011 wh.su ++ * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get ++ * essid ++ * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running. ++ * ++ * 02 08 2011 george.huang ++ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler ++ * Support querying power mode OID. ++ * ++ * 01 29 2011 wh.su ++ * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0 ++ * not doing mem alloc. while set ie length already 0 ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Remove debug text. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Adjust OID order. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 11 2011 chinglan.wang ++ * NULL ++ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish ++ * successfully. ++ * Use the WPS function to connect AP, the privacy bit always is set to 1. . ++ * ++ * 01 07 2011 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add a new compiling option to control if MCR read/write is permitted ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous types ++ * to ease slab system pressure ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add some iwpriv commands to support test mode operation ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Support set PS profile and set WMM-PS related iwpriv. ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Allow change PS profile function (through wext_set_power()). ++ * ++ * 12 14 2010 jeffrey.chang ++ * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID ++ * handle hidden SSID ++ * ++ * 12 13 2010 chinglan.wang ++ * NULL ++ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * Fix compiling error ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 30 2010 cp.wu ++ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 ++ * . ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power ++ * saving ++ * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving ++ * ++ * 10 18 2010 jeffrey.chang ++ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue ++ * refine the scan ioctl to prevent hanging of Android UI ++ * ++ * 10 01 2010 wh.su ++ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function ++ * add the scan result with wapi ie. ++ * ++ * 09 30 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * fixed the wapi ie assigned issue. ++ * ++ * 09 27 2010 wh.su ++ * NULL ++ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * Androi/Linux: return current operating channel information ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * enable remove key ioctl ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) enable encyption ioctls ++ * 2) temporarily disable remove keys ioctl to prevent TX1 busy ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) remove unused spinlocks ++ * 2) enable encyption ioctls ++ * 3) fix scan ioctl which may cause supplicant to hang ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add kal api for scanning done ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * for linux driver migration ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove unused macro and debug messages ++ * ++ * 05 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add dissassoication support for wpa supplicant ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add ioctl of power management ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove debug message ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used ++ * * 2) fix ioctl ++ * ++ * 04 12 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove debug messages for pre-release ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * * are done in adapter layer. ++ * ++ * 04 02 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix ioctl type ++ * ++ * 04 01 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * enable pmksa cache operation ++ * ++ * 03 31 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix ioctl which may cause cmdinfo memory leak ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). ++** Add more checking for input parameters and pointers. ++** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090 ++** Remove unused variables ++** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088 ++** adding the wapi ioctl support ++** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089 ++** fix compiling warning ++** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089 ++** Add mandatory and private IO control for Linux BWCS ++** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088 ++** fixed the compiling error ++** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088 ++** add the privacy setting from linux supplicant ap selection ++** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088 ++** fixed the compling error ++** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088 ++** rename some variable with pre-fix to avoid the misunderstanding ++** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088 ++** fixed compiling error ++** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088 ++** adjust the code for meet the coding style, and add assert check ++** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461 ++** Update after wlanoidSetPowerMode changed ++** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084 ++** rename wlanoid ++** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461 ++** Add set desired rate in Linux STD IOCTL ++** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088 ++** add pmkid ioctl and indicate ++** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461 ++** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461 ++** Refine WPS related priv ioctl for unified interface ++** ++** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088 ++** move the configuration code from set essid function, ++** remove the non-used code ++** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461 ++** Fix CR[489] ++** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461 ++** Add Set Frequency & Channel oid support for Linux ++** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461 ++** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461 ++** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter ++** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425 ++** 1. Branch Test ++** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461 ++** fix typo ++** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425 ++** 1. Fix compiling erros ++** ++** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425 ++** 1. Add WMM-PS setting ++** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088 ++** fixed the compiler error ++** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088 ++** add WPS code ++** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425 ++** 1. Update wlanQueryInformation ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "gl_os.h" ++ ++#include "config.h" ++#include "wlan_oid.h" ++ ++#include "gl_wext.h" ++#include "gl_wext_priv.h" ++ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_WAPI ++#include "gl_sec.h" ++#endif ++ ++/* compatibility to wireless extensions */ ++#ifdef WIRELESS_EXT ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++const long channel_freq[] = { ++ 2412, 2417, 2422, 2427, 2432, 2437, 2442, ++ 2447, 2452, 2457, 2462, 2467, 2472, 2484 ++}; ++ ++ ++#define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0])) ++ ++#define MAX_SSID_LEN 32 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++/* NOTE: name in iwpriv_args only have 16 bytes */ ++static const struct iw_priv_args rIwPrivTable[] = { ++ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, ++ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""}, ++ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""}, ++ ++ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, ++ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, ++ ++ {IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_CHAR | 16, ""}, ++ ++ {IOCTL_SET_STRING, IW_PRIV_TYPE_CHAR | 256, 0, ""}, ++ ++ /* added for set_oid and get_oid */ ++ {IOCTL_SET_STRUCT, 256, 0, ""}, ++ {IOCTL_GET_STRUCT, 0, 256, ""}, ++ ++ /* sub-ioctl definitions */ ++#if 0 ++ {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain"}, ++ {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain"}, ++#endif ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum"}, ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode"}, ++ {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode"}, ++ ++ {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps"}, ++ ++ {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode"}, ++ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd"}, ++ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_test_result"}, ++#if CFG_SUPPORT_PRIV_MCR_RW ++ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr"}, ++ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_mcr"}, ++#endif ++ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl"}, ++ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_sw_ctrl"}, ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"}, ++ /* GET STRUCT sub-ioctls commands */ ++ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_bwcs"}, ++#endif ++ ++ /* SET STRUCT sub-ioctls commands */ ++ {PRIV_CMD_OID, 256, 0, "set_oid"}, ++ /* GET STRUCT sub-ioctls commands */ ++ {PRIV_CMD_OID, 0, 256, "get_oid"}, ++ ++ {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band"}, ++ {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band"}, ++ ++ {PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower"}, ++ {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list"}, ++ {PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_mem"}, ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode"}, ++#endif ++ {PRIV_CMD_GET_BUILD_DATE_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_date_code"}, ++ {PRIV_CMD_GET_DEBUG_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_dbg_code"}, ++ /* handle any command with many input parameters */ ++ {PRIV_CMD_OTHER, IW_PRIV_TYPE_CHAR | 256, 0, "set_str_cmd"}, ++ ++ {PRIV_CMD_WFD_DEBUG_CODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_wfd_dbg_code"}, ++}; ++ ++static const iw_handler rIwPrivHandler[] = { ++ [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int, ++ [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int, ++ [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct, ++ [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct, ++ [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct, ++ [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints, ++ [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints, ++ [IOCTL_SET_STRING - SIOCIWFIRSTPRIV] = priv_set_string, ++}; ++ ++const struct iw_handler_def wext_handler_def = { ++ .num_standard = 0, ++ .num_private = (__u16) sizeof(rIwPrivHandler) / sizeof(iw_handler), ++ .num_private_args = (__u16) sizeof(rIwPrivTable) / sizeof(struct iw_priv_args), ++ .standard = (iw_handler *) NULL, ++ .private = rIwPrivHandler, ++ .private_args = rIwPrivTable, ++ .get_wireless_stats = wext_get_wireless_stats, ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired WPA/RSN Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { ++ if (ucDesiredElemId != 0xDD) { ++ /* Non 0xDD, OK! */ ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ /* EID == 0xDD, check WPA IE */ ++ if (pucIEStart[1] >= 4) { ++ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ } /* check WPA IE length */ ++ /* check EID == 0xDD */ ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* parseSearchDesiredWPAIE */ ++ ++#if CFG_SUPPORT_WAPI ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired WAPI Information Element . ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredWAPIIE */ ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired HS2.0 Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredHS20IE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { ++ if (pucCurIE[1] >= ELEM_MIN_LEN_HS20_INDICATION) { ++ if (memcmp(&pucCurIE[2], "\x50\x6f\x9a\x10", 4) == 0) ++ return TRUE; ++ } ++ } ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredHS20IE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired interworking Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredInterworkingIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { ++ switch (pucCurIE[1]) { ++ case IW_IE_LENGTH_ANO: ++ case IW_IE_LENGTH_ANO_HESSID: ++ case IW_IE_LENGTH_ANO_VENUE: ++ case IW_IE_LENGTH_ANO_VENUE_HESSID: ++ return TRUE; ++ ++ default: ++ break; ++ } ++ ++ } ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredInterworkingIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredAdvProtocolIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) ++ return TRUE; ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredAdvProtocolIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredRoamingConsortiumIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) ++ return TRUE; ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredRoamingConsortiumIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired HS2.0 Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { ++ if (pucIEStart[1] >= ELEM_MIN_LEN_HS20_INDICATION) { ++ if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x10", 4) == 0) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ } ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredHS20IE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired interworking Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredInterworkingIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired Adv Protocol Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredAdvProtocolIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired Roaming Consortium Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredRoamingConsortiumIE */ ++#endif ++ ++#if CFG_SUPPORT_WPS ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired WPS Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { ++ if (ucDesiredElemId != 0xDD) { ++ /* Non 0xDD, OK! */ ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ /* EID == 0xDD, check WPS IE */ ++ if (pucIEStart[1] >= 4) { ++ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ } /* check WPS IE length */ ++ /* check EID == 0xDD */ ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* parseSearchDesiredWPSIE */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the name of the protocol used on the air. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] pcName Buffer to store protocol name string ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* ++* \note If netif_carrier_ok, protocol name is returned; ++* otherwise, "disconnected" is returned. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_name(IN struct net_device *prNetDev, IN struct iw_request_info *prIwrInfo, OUT char *pcName, IN char *pcExtra) ++{ ++ ENUM_PARAM_NETWORK_TYPE_T eNetWorkType = PARAM_NETWORK_TYPE_NUM; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pcName); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcName)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (netif_carrier_ok(prNetDev)) { ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryNetworkTypeInUse, ++ &eNetWorkType, sizeof(eNetWorkType), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ switch (eNetWorkType) { ++ case PARAM_NETWORK_TYPE_DS: ++ strcpy(pcName, "IEEE 802.11b"); ++ break; ++ case PARAM_NETWORK_TYPE_OFDM24: ++ strcpy(pcName, "IEEE 802.11bgn"); ++ break; ++ case PARAM_NETWORK_TYPE_AUTOMODE: ++ case PARAM_NETWORK_TYPE_OFDM5: ++ strcpy(pcName, "IEEE 802.11abgn"); ++ break; ++ case PARAM_NETWORK_TYPE_FH: ++ default: ++ strcpy(pcName, "IEEE 802.11"); ++ break; ++ } ++ } else { ++ strcpy(pcName, "Disconnected"); ++ } ++ ++ return 0; ++} /* wext_get_name */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set the operating channel in the wireless device. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL ++* \param[in] prFreq Buffer to store frequency information ++* \param[in] pcExtra NULL ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS. ++* \retval -EINVAL Invalid channel frequency. ++* ++* \note If infrastructure mode is IBSS, new channel frequency is set to device. ++* The range of channel number depends on different regulatory domain. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_freq(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN struct iw_freq *prIwFreq, IN char *pcExtra) ++{ ++ ++#if 0 ++ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwFreq); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* ++ printk("set m:%d, e:%d, i:%d, flags:%d\n", ++ prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags); ++ */ ++ ++ /* If setting by frequency, convert to a channel */ ++ if ((prIwFreq->e == 1) && (prIwFreq->m >= (int)2.412e8) && (prIwFreq->m <= (int)2.484e8)) { ++ ++ /* Change to KHz format */ ++ u4ChnlFreq = (UINT_32) (prIwFreq->m / (KILO / 10)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetFrequency, ++ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (WLAN_STATUS_SUCCESS != rStatus) ++ return -EINVAL; ++ } ++ /* Setting by channel number */ ++ else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) ++ return -EOPNOTSUPP; ++ ++ /* Change to channel number format */ ++ u4ChnlFreq = (UINT_32) prIwFreq->m; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetChannel, &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (WLAN_STATUS_SUCCESS != rStatus) ++ return -EINVAL; ++ ++#endif ++ ++ return 0; ++ ++} /* wext_set_freq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get the operating channel in the wireless device. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prFreq Buffer to store frequency information. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise ++* ++* \note If netif_carrier_ok, channel frequency information is stored in pFreq. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_freq(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_freq *prIwFreq, IN char *pcExtra) ++{ ++ UINT_32 u4Channel = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwFreq); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* GeorgeKuo: TODO skip checking in IBSS mode */ ++ if (!netif_carrier_ok(prNetDev)) ++ return -ENOTCONN; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryFrequency, &u4Channel, sizeof(u4Channel), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ prIwFreq->m = (int)u4Channel; /* freq in KHz */ ++ prIwFreq->e = 3; ++ ++ return 0; ++ ++} /* wext_get_freq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set operating mode. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] pu4Mode Pointer to new operation mode. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If new mode is not supported. ++* ++* \note Device will run in new operation mode if it is valid. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_mode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN unsigned int *pu4Mode, IN char *pcExtra) ++{ ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pu4Mode); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ switch (*pu4Mode) { ++ case IW_MODE_AUTO: ++ eOpMode = NET_TYPE_AUTO_SWITCH; ++ break; ++ ++ case IW_MODE_ADHOC: ++ eOpMode = NET_TYPE_IBSS; ++ break; ++ ++ case IW_MODE_INFRA: ++ eOpMode = NET_TYPE_INFRA; ++ break; ++ ++ default: ++ DBGLOG(REQ, ERROR, "%s(): Set UNSUPPORTED Mode = %d.\n", __func__, *pu4Mode); ++ return -EOPNOTSUPP; ++ } ++ ++ /* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ /* after set operation mode, key table are cleared */ ++ ++ /* reset wpa info */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ return 0; ++} /* wext_set_mode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get operating mode. ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIwReqInfo NULL. ++* \param[out] pu4Mode Buffer to store operating mode information. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If data is valid. ++* \retval -EINVAL Otherwise. ++* ++* \note If netif_carrier_ok, operating mode information is stored in pu4Mode. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_mode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, OUT unsigned int *pu4Mode, IN char *pcExtra) ++{ ++ ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_NUM; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pu4Mode); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ switch (eOpMode) { ++ case NET_TYPE_IBSS: ++ *pu4Mode = IW_MODE_ADHOC; ++ break; ++ ++ case NET_TYPE_INFRA: ++ *pu4Mode = IW_MODE_INFRA; ++ break; ++ ++ case NET_TYPE_AUTO_SWITCH: ++ *pu4Mode = IW_MODE_AUTO; ++ break; ++ ++ default: ++ DBGLOG(REQ, ERROR, "%s(): Get UNKNOWN Mode.\n", __func__); ++ return -EINVAL; ++ } ++ ++ return 0; ++} /* wext_get_mode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get the valid range for each configurable STA setting value. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prData Pointer to iw_point structure, not used. ++* \param[out] pcExtra Pointer to buffer which is allocated by caller of this ++* function, wext_support_ioctl() or ioctl_standard_call() in ++* wireless.c. ++* ++* \retval 0 If data is valid. ++* ++* \note The extra buffer (pcExtra) is filled with information from driver. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_range(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, OUT char *pcExtra) ++{ ++ struct iw_range *prRange = NULL; ++ PARAM_RATES_EX aucSuppRate = { 0 }; /* data buffers */ ++ int i = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ prRange = (struct iw_range *)pcExtra; ++ ++ memset(prRange, 0, sizeof(*prRange)); ++ prRange->throughput = 20000000; /* 20Mbps */ ++ prRange->min_nwid = 0; /* not used */ ++ prRange->max_nwid = 0; /* not used */ ++ ++ /* scan_capa not implemented */ ++ ++ /* event_capa[6]: kernel + driver capabilities */ ++ prRange->event_capa[0] = (IW_EVENT_CAPA_K_0 | IW_EVENT_CAPA_MASK(SIOCGIWAP) ++ | IW_EVENT_CAPA_MASK(SIOCGIWSCAN) ++ /* can't display meaningful string in iwlist ++ | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW) ++ | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE) ++ | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE) ++ | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND) ++ */ ++ ); ++ prRange->event_capa[1] = IW_EVENT_CAPA_K_1; ++ ++ /* report 2.4G channel and frequency only */ ++ prRange->num_channels = (__u16) NUM_CHANNELS; ++ prRange->num_frequency = (__u8) NUM_CHANNELS; ++ for (i = 0; i < NUM_CHANNELS; i++) { ++ /* iwlib takes this number as channel number */ ++ prRange->freq[i].i = i + 1; ++ prRange->freq[i].m = channel_freq[i]; ++ prRange->freq[i].e = 6; /* Values in table in MHz */ ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQuerySupportedRates, ++ &aucSuppRate, sizeof(aucSuppRate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX; i++) { ++ if (aucSuppRate[i] == 0) ++ break; ++ prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000; /* 0.5Mbps */ ++ } ++ prRange->num_bitrates = i; ++ ++ prRange->min_rts = 0; ++ prRange->max_rts = 2347; ++ prRange->min_frag = 256; ++ prRange->max_frag = 2346; ++ ++ prRange->min_pmp = 0; /* power management by driver */ ++ prRange->max_pmp = 0; /* power management by driver */ ++ prRange->min_pmt = 0; /* power management by driver */ ++ prRange->max_pmt = 0; /* power management by driver */ ++ prRange->pmp_flags = IW_POWER_RELATIVE; /* pm default flag */ ++ prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */ ++ prRange->pm_capa = IW_POWER_ON; /* power management by driver */ ++ ++ prRange->encoding_size[0] = 5; /* wep40 */ ++ prRange->encoding_size[1] = 16; /* tkip */ ++ prRange->encoding_size[2] = 16; /* ckip */ ++ prRange->encoding_size[3] = 16; /* ccmp */ ++ prRange->encoding_size[4] = 13; /* wep104 */ ++ prRange->encoding_size[5] = 16; /* wep128 */ ++ prRange->num_encoding_sizes = 6; ++ prRange->max_encoding_tokens = 6; /* token? */ ++ ++#if WIRELESS_EXT < 17 ++ prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */ ++#else ++ prRange->txpower_capa = IW_TXPOW_RELATIVE; ++#endif ++ prRange->num_txpower = 5; ++ prRange->txpower[0] = 0; /* minimum */ ++ prRange->txpower[1] = 25; /* 25% */ ++ prRange->txpower[2] = 50; /* 50% */ ++ prRange->txpower[3] = 100; /* 100% */ ++ ++ prRange->we_version_compiled = WIRELESS_EXT; ++ prRange->we_version_source = WIRELESS_EXT; ++ ++ prRange->retry_capa = IW_RETRY_LIMIT; ++ prRange->retry_flags = IW_RETRY_LIMIT; ++ prRange->min_retry = 7; ++ prRange->max_retry = 7; ++ prRange->r_time_flags = IW_RETRY_ON; ++ prRange->min_r_time = 0; ++ prRange->max_r_time = 0; ++ ++ /* signal strength and link quality */ ++ /* Just define range here, reporting value moved to wext_get_stats() */ ++ prRange->sensitivity = -83; /* fixed value */ ++ prRange->max_qual.qual = 100; /* max 100% */ ++ prRange->max_qual.level = (__u8) (0x100 - 0); /* max 0 dbm */ ++ prRange->max_qual.noise = (__u8) (0x100 - 0); /* max 0 dbm */ ++ ++ /* enc_capa */ ++#if WIRELESS_EXT > 17 ++ prRange->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; ++#endif ++ ++ /* min_pms; Minimal PM saving */ ++ /* max_pms; Maximal PM saving */ ++ /* pms_flags; How to decode max/min PM saving */ ++ ++ /* modul_capa; IW_MODUL_* bit field */ ++ /* bitrate_capa; Types of bitrates supported */ ++ ++ return 0; ++} /* wext_get_range */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set BSSID of AP to connect. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* ++* \note Desired AP's BSSID is set to driver. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_ap(IN struct net_device *prDev, ++ IN struct iw_request_info *prIwrInfo, IN struct sockaddr *prAddr, IN char *pcExtra) ++{ ++ return 0; ++} /* wext_set_ap */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get AP MAC address. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise. ++* ++* \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_ap(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct sockaddr *prAddr, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prAddr); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* if (!netif_carrier_ok(prNetDev)) { */ ++ /* return -ENOTCONN; */ ++ /* } */ ++ ++ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED) { ++ /*memset(prAddr, 0, 6);*/ ++ memset(prAddr, 0, sizeof(struct sockaddr)); ++ return 0; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBssid, prAddr->sa_data, ETH_ALEN, TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ return 0; ++} /* wext_get_ap */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set mlme operation request. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prData Pointer of iw_point header. ++* \param[in] pcExtra Pointer to iw_mlme structure mlme request information. ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP unsupported IW_MLME_ command. ++* \retval -EINVAL Set MLME Fail, different bssid. ++* ++* \note Driver will start mlme operation if valid. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_mlme(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, IN char *pcExtra) ++{ ++ struct iw_mlme *prMlme = NULL; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ prMlme = (struct iw_mlme *)pcExtra; ++ if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) { ++ if (!netif_carrier_ok(prNetDev)) { ++ DBGLOG(REQ, WARN, "[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"); ++ return 0; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ return 0; ++ } ++ DBGLOG(REQ, WARN, "[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd); ++ return -EOPNOTSUPP; ++ ++} /* wext_set_mlme */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To issue scan request. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prData NULL. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* \retval -EFAULT Tx power is off. ++* ++* \note Device will start scanning. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_scan(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN union iwreq_data *prData, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ int essid_len = 0; ++ ++ ASSERT(prNetDev); ++ if (FALSE == GLUE_CHK_DEV(prNetDev)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++#if WIRELESS_EXT > 17 ++ /* retrieve SSID */ ++ if (prData) ++ essid_len = ((struct iw_scan_req *)(((struct iw_point *)prData)->pointer))->essid_len; ++#endif ++ ++ init_completion(&prGlueInfo->rScanComp); ++ ++ /* TODO: parse flags and issue different scan requests? */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssidListScan, pcExtra, essid_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ); */ ++ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ ++ ++ return 0; ++} /* wext_set_scan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To write the ie to buffer ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) ++{ ++ size_t i; ++ char *pos = buf, *end = buf + buf_size; ++ int ret; ++ ++ if (buf_size == 0) ++ return 0; ++ ++ for (i = 0; i < len; i++) { ++ ret = snprintf(pos, end - pos, "%02x", data[i]); ++ if (ret < 0 || ret >= end - pos) { ++ end[-1] = '\0'; ++ return pos - buf; ++ } ++ pos += ret; ++ } ++ end[-1] = '\0'; ++ return pos - buf; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get scan results, transform results from driver's format to WE's. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prData Pointer to iw_point structure, pData->length is the size of ++* pcExtra buffer before used, and is updated after filling scan ++* results. ++* \param[out] pcExtra Pointer to buffer which is allocated by caller of this ++* function, wext_support_ioctl() or ioctl_standard_call() in ++* wireless.c. ++* ++* \retval 0 For success. ++* \retval -ENOMEM If dynamic memory allocation fail. ++* \retval -E2BIG Invalid length. ++* ++* \note Scan results is filled into pcExtra buffer, data size is updated in ++* pData->length. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_scan(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN OUT struct iw_point *prData, IN char *pcExtra) ++{ ++ UINT_32 i = 0; ++ UINT_32 j = 0; ++ P_PARAM_BSSID_LIST_EX_T prList = NULL; ++ P_PARAM_BSSID_EX_T prBss = NULL; ++ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; ++ struct iw_event iwEvent; /* local iw_event buffer */ ++ ++ /* write pointer of extra buffer */ ++ char *pcCur = NULL; ++ /* pointer to the end of last full entry in extra buffer */ ++ char *pcValidEntryEnd = NULL; ++ char *pcEnd = NULL; /* end of extra buffer */ ++ ++ UINT_32 u4AllocBufLen = 0; ++ ++ /* arrange rate information */ ++ UINT_32 u4HighestRate = 0; ++ char aucRatesBuf[64]; ++ UINT_32 u4BufIndex; ++ ++ /* return value */ ++ int ret = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prData); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* Initialize local variables */ ++ pcCur = pcExtra; ++ pcValidEntryEnd = pcExtra; ++ pcEnd = pcExtra + prData->length; /* end of extra buffer */ ++ ++ /* Allocate another query buffer with the same size of extra buffer */ ++ u4AllocBufLen = prData->length; ++ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); ++ if (prList == NULL) { ++ DBGLOG(REQ, ERROR, "[wifi] no memory for scan list:%d\n", prData->length); ++ ret = -ENOMEM; ++ goto error; ++ } ++ prList->u4NumberOfItems = 0; ++ ++ /* wait scan done */ ++ /* printk ("wait for scan results\n"); */ ++ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ); */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { ++ /* Buffer length is not large enough. */ ++ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ ++ ++#if WIRELESS_EXT >= 17 ++ /* This feature is supported in WE-17 or above, limited by iwlist. ++ ** Return -E2BIG and iwlist will request again with a larger buffer. ++ */ ++ ret = -E2BIG; ++ /* Update length to give application a hint on result length */ ++ prData->length = (__u16) u4BufLen; ++ goto error; ++#else ++ /* Realloc a larger query buffer here, but don't write too much to extra ++ ** buffer when filling it later. ++ */ ++ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); ++ ++ u4AllocBufLen = u4BufLen; ++ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); ++ if (prList == NULL) { ++ DBGLOG(REQ, ERROR, "[wifi] no memory for larger scan list :%u\n", u4BufLen); ++ ret = -ENOMEM; ++ goto error; ++ } ++ prList->NumberOfItems = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { ++ DBGLOG(REQ, ERROR, "[wifi] larger buf:%u result:%u\n", u4AllocBufLen, u4BufLen); ++ ret = -E2BIG; ++ prData->length = (__u16) u4BufLen; ++ goto error; ++ } ++#endif /* WIRELESS_EXT >= 17 */ ++ ++ } ++ ++ if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) { ++ DBGLOG(REQ, WARN, "[wifi] strange scan result count:%u\n", prList->u4NumberOfItems); ++ goto error; ++ } ++ ++ /* Copy required data from pList to pcExtra */ ++ prBss = &prList->arBssid[0]; /* set to the first entry */ ++ for (i = 0; i < prList->u4NumberOfItems; ++i) { ++ /* BSSID */ ++ iwEvent.cmd = SIOCGIWAP; ++ iwEvent.len = IW_EV_ADDR_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER; ++ ether_addr_copy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress); ++ memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN); ++ pcCur += IW_EV_ADDR_LEN; ++ ++ /* SSID */ ++ iwEvent.cmd = SIOCGIWESSID; ++ /* Modification to user space pointer(essid.pointer) is not needed. */ ++ iwEvent.u.essid.length = (__u16) prBss->rSsid.u4SsidLen; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length; ++ ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.essid.flags = 1; ++ iwEvent.u.essid.pointer = NULL; ++ ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, iwEvent.len); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length); ++ pcCur += iwEvent.len; ++ /* Frequency */ ++ iwEvent.cmd = SIOCGIWFREQ; ++ iwEvent.len = IW_EV_FREQ_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig; ++ iwEvent.u.freq.e = 3; /* (in KHz) */ ++ iwEvent.u.freq.i = 0; ++ memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN); ++ pcCur += IW_EV_FREQ_LEN; ++ ++ /* Operation Mode */ ++ iwEvent.cmd = SIOCGIWMODE; ++ iwEvent.len = IW_EV_UINT_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ if (prBss->eOpMode == NET_TYPE_IBSS) ++ iwEvent.u.mode = IW_MODE_ADHOC; ++ else if (prBss->eOpMode == NET_TYPE_INFRA) ++ iwEvent.u.mode = IW_MODE_INFRA; ++ else ++ iwEvent.u.mode = IW_MODE_AUTO; ++ memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN); ++ pcCur += IW_EV_UINT_LEN; ++ ++ /* Quality */ ++ iwEvent.cmd = IWEVQUAL; ++ iwEvent.len = IW_EV_QUAL_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.qual.qual = 0; /* Quality not available now */ ++ /* -100 < Rssi < -10, normalized by adding 0x100 */ ++ iwEvent.u.qual.level = 0x100 + prBss->rRssi; ++ iwEvent.u.qual.noise = 0; /* Noise not available now */ ++ iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; ++ memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN); ++ pcCur += IW_EV_QUAL_LEN; ++ ++ /* Security Mode */ ++ iwEvent.cmd = SIOCGIWENCODE; ++ iwEvent.len = IW_EV_POINT_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.data.pointer = NULL; ++ iwEvent.u.data.flags = 0; ++ iwEvent.u.data.length = 0; ++ if (!prBss->u4Privacy) ++ iwEvent.u.data.flags |= IW_ENCODE_DISABLED; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ pcCur += IW_EV_POINT_LEN; ++ ++ /* rearrange rate information */ ++ u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):"); ++ u4HighestRate = 0; ++ for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) { ++ UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F; ++ ++ if (curRate == 0) ++ break; ++ ++ if (curRate > u4HighestRate) ++ u4HighestRate = curRate; ++ ++ if (curRate == RATE_5_5M) ++ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5"); ++ else ++ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2); ++#if DBG ++ if (u4BufIndex > sizeof(aucRatesBuf)) { ++ /* printk("rate info too long\n"); */ ++ break; ++ } ++#endif ++ } ++ /* Report Highest Rates */ ++ iwEvent.cmd = SIOCGIWRATE; ++ iwEvent.len = IW_EV_PARAM_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.bitrate.value = u4HighestRate * 500000; ++ iwEvent.u.bitrate.fixed = 0; ++ iwEvent.u.bitrate.disabled = 0; ++ iwEvent.u.bitrate.flags = 0; ++ memcpy(pcCur, &iwEvent, iwEvent.len); ++ pcCur += iwEvent.len; ++ ++#if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */ ++ /* Report Residual Rates */ ++ iwEvent.cmd = IWEVCUSTOM; ++ iwEvent.u.data.length = u4BufIndex; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.data.flags = 0; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex); ++ pcCur += iwEvent.len; ++#endif /* WIRELESS_EXT >= 15 */ ++ ++ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++ } ++#if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */ ++ if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++ } ++#endif ++ ++ /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */ ++ /* pBss->IEs starts from timestamp */ ++ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), ++ 0x30, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++ } ++#if CFG_SUPPORT_WAPI /* Android+ */ ++ if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), (PUINT_8 *) &prDesiredIE)) { ++ ++#if 0 ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++#else ++ iwEvent.cmd = IWEVCUSTOM; ++ iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.data.flags = 1; ++ ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++ ++ pcCur += (IW_EV_POINT_LEN); ++ ++ pcCur += sprintf(pcCur, "wapi_ie="); ++ ++ snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *) prDesiredIE, prDesiredIE->ucLength + 2); ++ ++ pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */; ++#endif ++ } ++#endif ++ /* Complete an entry. Update end of valid entry */ ++ pcValidEntryEnd = pcCur; ++ /* Extract next bss */ ++ prBss = (P_PARAM_BSSID_EX_T) ((char *)prBss + prBss->u4Length); ++ } ++ ++ /* Update valid data length for caller function and upper layer ++ * applications. ++ */ ++ prData->length = (pcValidEntryEnd - pcExtra); ++ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ ++ ++ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ ++ ++error: ++ /* free local query buffer */ ++ if (prList) ++ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); ++ ++ return ret; ++} /* wext_get_scan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set desired network name ESSID. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEssid Pointer of iw_point header. ++* \param[in] pcExtra Pointer to buffer srtoring essid string. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -E2BIG Essid string length is too big. ++* \retval -EINVAL pcExtra is null pointer. ++* \retval -EFAULT Driver fail to set new essid. ++* ++* \note If string length is ok, device will try connecting to the new network. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_essid(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, IN char *pcExtra) ++{ ++ PARAM_SSID_T rNewSsid; ++ UINT_32 cipher; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEssid); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (prEssid->length > IW_ESSID_MAX_SIZE) ++ return -E2BIG; ++ ++ /* set auth mode */ ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { ++ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? ++ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; ++ /* printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n", */ ++ /* (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); */ ++ } else { ++ /* set auth mode */ ++ switch (prGlueInfo->rWpaInfo.u4KeyMgmt) { ++ case IW_AUTH_KEY_MGMT_802_1X: ++ eAuthMode = ++ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? ++ AUTH_MODE_WPA : AUTH_MODE_WPA2; ++ /* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", */ ++ /* (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); */ ++ break; ++ case IW_AUTH_KEY_MGMT_PSK: ++ eAuthMode = ++ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? ++ AUTH_MODE_WPA_PSK : AUTH_MODE_WPA2_PSK; ++ /* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", */ ++ /* (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); */ ++ break; ++#if CFG_SUPPORT_WAPI /* Android+ */ ++ case IW_AUTH_KEY_MGMT_WAPI_PSK: ++ break; ++ case IW_AUTH_KEY_MGMT_WAPI_CERT: ++ break; ++#endif ++ ++/* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */ ++/* case IW_AUTH_KEY_MGMT_WPA_NONE: */ ++/* eAuthMode = AUTH_MODE_WPA_NONE; */ ++/* //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); */ ++/* break; */ ++/* #endif */ ++#if CFG_SUPPORT_802_11W ++ case IW_AUTH_KEY_MGMT_802_1X_SHA256: ++ eAuthMode = AUTH_MODE_WPA2; ++ break; ++ case IW_AUTH_KEY_MGMT_PSK_SHA256: ++ eAuthMode = AUTH_MODE_WPA2_PSK; ++ break; ++#endif ++ default: ++ /* printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n", */ ++ /* prGlueInfo->rWpaInfo.u4KeyMgmt); */ ++ eAuthMode = AUTH_MODE_AUTO_SWITCH; ++ break; ++ } ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ /* set encryption status */ ++ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; ++ if (cipher & IW_AUTH_CIPHER_CCMP) { ++ /* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */ ++ eEncStatus = ENUM_ENCRYPTION3_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_TKIP) { ++ /* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */ ++ eEncStatus = ENUM_ENCRYPTION2_ENABLED; ++ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { ++ /* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */ ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_NONE) { ++ /* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */ ++ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } else { ++ /* printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n"); */ ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++#if WIRELESS_EXT < 21 ++ /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before ++ ** 2.6.19. Cut the trailing '\0'. ++ */ ++ rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0; ++#else ++ rNewSsid.u4SsidLen = prEssid->length; ++#endif ++ kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen); ++ ++ /* ++ rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0'; ++ printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid); ++ */ ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidSetSsid, ++ (PVOID)&rNewSsid, ++ sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen) != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_WARNING "Fail to set ssid\n"); */ ++ return -EFAULT; ++ } ++ ++ return 0; ++} /* wext_set_essid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get current network name ESSID. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEssid Pointer to iw_point structure containing essid information. ++* \param[out] pcExtra Pointer to buffer srtoring essid string. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise. ++* ++* \note If netif_carrier_ok, network essid is stored in pcExtra. ++*/ ++/*----------------------------------------------------------------------------*/ ++/* static PARAM_SSID_T ssid; */ ++static int ++wext_get_essid(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, OUT char *pcExtra) ++{ ++ /* PARAM_SSID_T ssid; */ ++ ++ P_PARAM_SSID_T prSsid; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEssid); ++ ASSERT(pcExtra); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* if (!netif_carrier_ok(prNetDev)) { */ ++ /* return -ENOTCONN; */ ++ /* } */ ++ ++ prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE); ++ ++ if (!prSsid) ++ return -ENOMEM; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQuerySsid, prSsid, sizeof(PARAM_SSID_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) { ++ kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen); ++ prEssid->length = prSsid->u4SsidLen; ++ prEssid->flags = 1; ++ } ++ ++ kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T)); ++ ++ return 0; ++} /* wext_get_essid */ ++ ++#if 0 ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set tx desired bit rate. Three cases here ++* iwconfig wlan0 auto -> Set to origianl supported rate set. ++* iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate. ++* iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps ++* ++* \param[in] prNetDev Pointer to the net_device handler. ++* \param[in] prIwReqInfo Pointer to the Request Info. ++* \param[in] prRate Pointer to the Rate Parameter. ++* \param[in] pcExtra Pointer to the extra buffer. ++* ++* \retval 0 Update desired rate. ++* \retval -EINVAL Wrong parameter ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++wext_set_rate(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra) ++{ ++ PARAM_RATES_EX aucSuppRate = { 0 }; ++ PARAM_RATES_EX aucNewRate = { 0 }; ++ UINT_32 u4NewRateLen = 0; ++ UINT_32 i; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRate); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* ++ printk("value = %d, fixed = %d, disable = %d, flags = %d\n", ++ prRate->value, prRate->fixed, prRate->disabled, prRate->flags); ++ */ ++ ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuerySupportedRates, &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); ++ ++ /* Case: AUTO */ ++ if (prRate->value < 0) { ++ if (prRate->fixed == 0) { ++ /* iwconfig wlan0 rate auto */ ++ ++ /* set full supported rate to device */ ++ /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */ ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetDesiredRates, ++ &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); ++ return 0; ++ } ++ /* iwconfig wlan0 rate fixed */ ++ ++ /* fix rate to what? DO NOTHING */ ++ return -EINVAL; ++ } ++ ++ aucNewRate[0] = prRate->value / 500000; /* In unit of 500k */ ++ ++ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) { ++ /* check the given value is supported */ ++ if (aucSuppRate[i] == 0) ++ break; ++ ++ if (aucNewRate[0] == aucSuppRate[i]) { ++ u4NewRateLen = 1; ++ break; ++ } ++ } ++ ++ if (u4NewRateLen == 0) { ++ /* the given value is not supported */ ++ /* return error or use given rate as upper bound? */ ++ return -EINVAL; ++ } ++ ++ if (prRate->fixed == 0) { ++ /* add all rates lower than desired rate */ ++ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) { ++ if (aucSuppRate[i] == 0) ++ break; ++ ++ if (aucSuppRate[i] < aucNewRate[0]) ++ aucNewRate[u4NewRateLen++] = aucSuppRate[i]; ++ } ++ } ++ ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetDesiredRates, &aucNewRate, sizeof(aucNewRate), &u4BufLen); ++ return 0; ++} /* wext_set_rate */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get current tx bit rate. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prRate Pointer to iw_param structure to store current tx rate. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise. ++* ++* \note If netif_carrier_ok, current tx rate is stored in pRate. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_rate(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRate, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ UINT_32 u4Rate = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRate); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (!netif_carrier_ok(prNetDev)) ++ return -ENOTCONN; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prRate->value = u4Rate * 100; /* u4Rate is in unit of 100bps */ ++ prRate->fixed = 0; ++ ++ return 0; ++} /* wext_get_rate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set RTS/CTS theshold. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prRts Pointer to iw_param structure containing rts threshold. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* \retval -EINVAL Given value is out of range. ++* ++* \note If given value is valid, device will follow the new setting. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_rts(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prRts, IN char *pcExtra) ++{ ++ PARAM_RTS_THRESHOLD u4RtsThresh; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRts); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (prRts->disabled == 1) ++ u4RtsThresh = 2347; ++ else if (prRts->value < 0 || prRts->value > 2347) ++ return -EINVAL; ++ ++ u4RtsThresh = (PARAM_RTS_THRESHOLD) prRts->value; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRtsThreshold, ++ &u4RtsThresh, sizeof(u4RtsThresh), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ prRts->value = (typeof(prRts->value)) u4RtsThresh; ++ prRts->disabled = (prRts->value > 2347) ? 1 : 0; ++ prRts->fixed = 1; ++ ++ return 0; ++} /* wext_set_rts */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get RTS/CTS theshold. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prRts Pointer to iw_param structure containing rts threshold. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note RTS threshold is stored in pRts. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_rts(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRts, IN char *pcExtra) ++{ ++ PARAM_RTS_THRESHOLD u4RtsThresh = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRts); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryRtsThreshold, ++ &u4RtsThresh, sizeof(u4RtsThresh), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ prRts->value = (typeof(prRts->value)) u4RtsThresh; ++ prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0; ++ prRts->fixed = 1; ++ ++ return 0; ++} /* wext_get_rts */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get fragmentation threshold. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prFrag Pointer to iw_param structure containing frag threshold. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note RTS threshold is stored in pFrag. Fragmentation is disabled. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_frag(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prFrag, IN char *pcExtra) ++{ ++ ASSERT(prFrag); ++ ++ prFrag->value = 2346; ++ prFrag->fixed = 1; ++ prFrag->disabled = 1; ++ return 0; ++} /* wext_get_frag */ ++ ++#if 1 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set TX power, or enable/disable the radio. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prTxPow Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used ++* to enable/disable the radio. ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++static int ++wext_set_txpow(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prTxPow, IN char *pcExtra) ++{ ++ int ret = 0; ++ /* PARAM_DEVICE_POWER_STATE ePowerState; */ ++ ENUM_ACPI_STATE_T ePowerState; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prTxPow); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (prTxPow->disabled) { ++ /* <1> disconnect */ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "######set disassoc failed\n"); ++ else ++ DBGLOG(REQ, TRACE, "######set assoc ok\n"); ++ /* <2> mark to power state flag */ ++ ePowerState = ACPI_STATE_D0; ++ DBGLOG(REQ, INFO, "set to acpi d3(0)\n"); ++ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); ++ ++ } else { ++ ePowerState = ACPI_STATE_D0; ++ DBGLOG(REQ, INFO, "set to acpi d0\n"); ++ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); ++ } ++ ++ prGlueInfo->ePowerState = ePowerState; ++ ++ return ret; ++} /* wext_set_txpow */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get TX power. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prTxPow Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note Tx power is stored in pTxPow. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_txpow(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prTxPow, IN char *pcExtra) ++{ ++ /* PARAM_DEVICE_POWER_STATE ePowerState; */ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prNetDev); ++ ASSERT(prTxPow); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not ++ * current state. Use GLUE_INFO_T to store state. ++ */ ++ /* ePowerState = prGlueInfo->ePowerState; */ ++ ++ /* TxPow parameters: Fixed at relative 100% */ ++#if WIRELESS_EXT < 17 ++ prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */ ++#else ++ prTxPow->flags = IW_TXPOW_RELATIVE; ++#endif ++ prTxPow->value = 100; ++ prTxPow->fixed = 1; ++ /* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE; */ ++ prTxPow->disabled = TRUE; ++ ++ return 0; ++} /* wext_get_txpow */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prEnc Pointer to iw_point structure containing securiry information. ++* \param[in] pcExtra Buffer to store key content. ++* ++* \retval 0 Success. ++* ++* \note Securiry information is stored in pEnc except key content. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_encode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_point *prEnc, IN char *pcExtra) ++{ ++#if 1 ++ /* ENUM_ENCRYPTION_STATUS_T eEncMode; */ ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode = ENUM_WEP_ENABLED; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEnc); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryEncryptionStatus, ++ &eEncMode, sizeof(eEncMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ switch (eEncMode) { ++ case ENUM_WEP_DISABLED: ++ prEnc->flags = IW_ENCODE_DISABLED; ++ break; ++ case ENUM_WEP_ENABLED: ++ prEnc->flags = IW_ENCODE_ENABLED; ++ break; ++ case ENUM_WEP_KEY_ABSENT: ++ prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; ++ break; ++ default: ++ prEnc->flags = IW_ENCODE_ENABLED; ++ break; ++ } ++ ++ /* Cipher, Key Content, Key ID can't be queried */ ++ prEnc->flags |= IW_ENCODE_NOKEY; ++#endif ++ return 0; ++} /* wext_get_encode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEnc Pointer to iw_point structure containing securiry information. ++* \param[in] pcExtra Pointer to key string buffer. ++* ++* \retval 0 Success. ++* \retval -EINVAL Key ID error for WEP. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 wepBuf[48]; ++ ++static int ++wext_set_encode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) ++{ ++#if 1 ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ /* UINT_8 wepBuf[48]; */ ++ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEnc); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* reset to default mode */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ /* iwconfig wlan0 key off */ ++ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { ++ eAuthMode = AUTH_MODE_OPEN; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, ++ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ return 0; ++ } ++ ++ /* iwconfig wlan0 key 0123456789 */ ++ /* iwconfig wlan0 key s:abcde */ ++ /* iwconfig wlan0 key 0123456789 [1] */ ++ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ ++ /* check key size for WEP */ ++ if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) { ++ /* prepare PARAM_WEP key structure */ ++ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; ++ if (prWepKey->u4KeyIndex > 3) { ++ /* key id is out of range */ ++ return -EINVAL; ++ } ++ prWepKey->u4KeyIndex |= 0x80000000; ++ prWepKey->u4Length = 12 + prEnc->length; ++ prWepKey->u4KeyLength = prEnc->length; ++ kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddWep, ++ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ /* change to auto switch */ ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; ++ eAuthMode = AUTH_MODE_AUTO_SWITCH; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, ++ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++ ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ ++ eEncStatus = ENUM_WEP_ENABLED; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, ++ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++ ++ return 0; ++ } ++#endif ++ return -EOPNOTSUPP; ++} /* wext_set_encode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set power management. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prPower Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note New Power Management Mode is set to driver. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_power(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prPower, IN char *pcExtra) ++{ ++#if 1 ++ ++ PARAM_POWER_MODE ePowerMode; ++ INT_32 i4PowerValue; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ ++ /* prPower->value, prPower->disabled, prPower->flags); */ ++ ++ if (prPower->disabled) { ++ ePowerMode = Param_PowerModeCAM; ++ } else { ++ i4PowerValue = prPower->value; ++#if WIRELESS_EXT < 21 ++ i4PowerValue /= 1000000; ++#endif ++ if (i4PowerValue == 0) { ++ ePowerMode = Param_PowerModeCAM; ++ } else if (i4PowerValue == 1) { ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else if (i4PowerValue == 2) { ++ ePowerMode = Param_PowerModeFast_PSP; ++ } else { ++ DBGLOG(REQ, ERROR, "%s(): unsupported power management mode value = %d.\n", ++ __func__, prPower->value); ++ ++ return -EINVAL; ++ } ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSet802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++#endif ++ return 0; ++} /* wext_set_power */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get power management. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prPower Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note Power management mode is stored in pTxPow->value. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_power(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prPower, IN char *pcExtra) ++{ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++#if 0 ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidQuery802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), TRUE, TRUE, &u4BufLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuery802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), &u4BufLen); ++#endif ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuery802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), &u4BufLen); ++#endif ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prPower->value = 0; ++ prPower->disabled = 1; ++ ++ if (Param_PowerModeCAM == ePowerMode) { ++ prPower->value = 0; ++ prPower->disabled = 1; ++ } else if (Param_PowerModeMAX_PSP == ePowerMode) { ++ prPower->value = 1; ++ prPower->disabled = 0; ++ } else if (Param_PowerModeFast_PSP == ePowerMode) { ++ prPower->value = 2; ++ prPower->disabled = 0; ++ } ++ ++ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; ++#if WIRELESS_EXT < 21 ++ prPower->value *= 1000000; ++#endif ++ ++ /* printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", */ ++ /* prPower->value, prPower->disabled, prPower->flags); */ ++ ++ return 0; ++} /* wext_get_power */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set authentication parameters. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] rpAuth Pointer to iw_param structure containing authentication information. ++* \param[in] pcExtra Pointer to key string buffer. ++* ++* \retval 0 Success. ++* \retval -EINVAL Key ID error for WEP. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_auth(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prAuth, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prNetDev); ++ ASSERT(prAuth); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* Save information to glue info and process later when ssid is set. */ ++ switch (prAuth->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++#if CFG_SUPPORT_WAPI ++ if (wlanQueryWapiMode(prGlueInfo->prAdapter)) { ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++ } else { ++ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; ++ } ++#else ++ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; ++#endif ++ break; ++ ++ case IW_AUTH_CIPHER_PAIRWISE: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value; ++ break; ++ ++ case IW_AUTH_CIPHER_GROUP: ++ prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value; ++ break; ++ ++ case IW_AUTH_KEY_MGMT: ++ prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value; ++#if CFG_SUPPORT_WAPI ++ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK || ++ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) { ++ UINT_32 u4BufLen; ++ WLAN_STATUS rStatus; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiMode, ++ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); ++ } ++#endif ++ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS) ++ prGlueInfo->fgWpsActive = TRUE; ++ else ++ prGlueInfo->fgWpsActive = FALSE; ++ break; ++ ++ case IW_AUTH_80211_AUTH_ALG: ++ prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value; ++ break; ++ ++ case IW_AUTH_PRIVACY_INVOKED: ++ prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value; ++ break; ++#if CFG_SUPPORT_802_11W ++ case IW_AUTH_MFP: ++ /* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */ ++ prGlueInfo->rWpaInfo.u4Mfp = prAuth->value; ++ break; ++#endif ++#if CFG_SUPPORT_WAPI ++ case IW_AUTH_WAPI_ENABLED: ++ { ++ UINT_32 u4BufLen; ++ WLAN_STATUS rStatus; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiMode, ++ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); ++ break; ++#endif ++ default: ++ /* ++ printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags); ++ */ ++ break; ++ } ++ return 0; ++} /* wext_set_auth */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEnc Pointer to iw_point structure containing securiry information. ++* \param[in] pcExtra Pointer to key string buffer. ++* ++* \retval 0 Success. ++* \retval -EINVAL Key ID error for WEP. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++#if CFG_SUPPORT_WAPI ++UINT_8 keyStructBuf[320]; /* add/remove key shared buffer */ ++#else ++UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ ++#endif ++ ++static int ++wext_set_encode_ext(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) ++{ ++ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; ++ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; ++ ++ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; ++ ++ struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *)pcExtra; ++ ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ /* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */ ++ ++#if CFG_SUPPORT_WAPI ++ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; ++#endif ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEnc); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ memset(keyStructBuf, 0, sizeof(keyStructBuf)); ++ ++#if CFG_SUPPORT_WAPI ++ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { ++ if (prEnc->flags & IW_ENCODE_DISABLED) { ++ /* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */ ++ return 0; ++ } ++ /* KeyID */ ++ prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX); ++ prWpiKey->ucKeyID--; ++ if (prWpiKey->ucKeyID > 1) { ++ /* key id is out of range */ ++ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ ++ return -EINVAL; ++ } ++ ++ if (prIWEncExt->key_len != 32) { ++ /* key length not valid */ ++ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ ++ return -EINVAL; ++ } ++ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ ++ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX; ++ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX_TX; ++ } ++ ++ /* PN */ ++ { ++ UINT_32 i; ++ ++ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) ++ prWpiKey->aucPN[i] = prIWEncExt->tx_seq[i]; ++ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) ++ prWpiKey->aucPN[IW_ENCODE_SEQ_MAX_SIZE + i] = prIWEncExt->rx_seq[i]; ++ } ++ ++ /* BSSID */ ++ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6); ++ ++ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); ++ prWpiKey->u4LenWPIEK = 16; ++ ++ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); ++ prWpiKey->u4LenWPICK = 16; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiKey, ++ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ ++ } ++ } else ++#endif ++ { ++ ++ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { ++ prRemoveKey->u4Length = sizeof(*prRemoveKey); ++ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ /* ++ printk("IW_ENCODE_DISABLED: ID:%d, Addr:[ %pM ]\n", ++ prRemoveKey->KeyIndex, prRemoveKey->BSSID); ++ */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveKey, ++ prRemoveKey, prRemoveKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, INFO, "remove key error:%x\n", rStatus); ++ return 0; ++ } ++ /* return 0; */ ++ /* printk ("alg %x\n", prIWEncExt->alg); */ ++ ++ switch (prIWEncExt->alg) { ++ case IW_ENCODE_ALG_NONE: ++ break; ++ case IW_ENCODE_ALG_WEP: ++ /* iwconfig wlan0 key 0123456789 */ ++ /* iwconfig wlan0 key s:abcde */ ++ /* iwconfig wlan0 key 0123456789 [1] */ ++ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ ++ /* check key size for WEP */ ++ if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) { ++ /* prepare PARAM_WEP key structure */ ++ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? ++ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; ++ if (prWepKey->u4KeyIndex > 3) { ++ /* key id is out of range */ ++ return -EINVAL; ++ } ++ prWepKey->u4KeyIndex |= 0x80000000; ++ prWepKey->u4Length = 12 + prIWEncExt->key_len; ++ prWepKey->u4KeyLength = prIWEncExt->key_len; ++ /* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len); */ ++ kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddWep, ++ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ /* change to auto switch */ ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; ++ eAuthMode = AUTH_MODE_AUTO_SWITCH; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, ++ &eAuthMode, ++ sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAuthMode fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ ++ eEncStatus = ENUM_WEP_ENABLED; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, ++ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), ++ FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetEncryptionStatus fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ } else { ++ DBGLOG(REQ, INFO, "key length %x\n", prIWEncExt->key_len); ++ DBGLOG(REQ, INFO, "key error\n"); ++ } ++ ++ break; ++ case IW_ENCODE_ALG_TKIP: ++ case IW_ENCODE_ALG_CCMP: ++#if CFG_SUPPORT_802_11W ++ case IW_ENCODE_ALG_AES_CMAC: ++#endif ++ { ++ ++ /* KeyID */ ++ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? ++ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; ++#if CFG_SUPPORT_802_11W ++ if (prKey->u4KeyIndex > 5) { ++#else ++ if (prKey->u4KeyIndex > 3) { ++#endif ++ DBGLOG(REQ, ERROR, "key index error:0x%x\n", prKey->u4KeyIndex); ++ /* key id is out of range */ ++ return -EINVAL; ++ } ++ ++ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ ++ /* Tx Key Bit(31) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ++ prKey->u4KeyIndex |= 0x1UL << 31; ++ /* Code style */ ++ } ++ /* Pairwise Key Bit(30) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ /* Do nothing */ ++ /* group key */ ++ } else { ++ /* pairwise key */ ++ prKey->u4KeyIndex |= 0x1UL << 30; ++ } ++ } ++ /* Rx SC Bit(29) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { ++ prKey->u4KeyIndex |= 0x1UL << 29; ++ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); ++ } ++ ++ /* BSSID */ ++ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ ++ /* switch tx/rx MIC key for sta */ ++ if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) { ++ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16); ++ memcpy(((PUINT_8) prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8); ++ memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8); ++ } else { ++ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); ++ } ++ ++ prKey->u4KeyLength = prIWEncExt->key_len; ++ prKey->u4Length = ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + prKey->u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddKey, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "add key error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ break; ++ } ++ } ++ ++ return 0; ++} /* wext_set_encode_ext */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set country code ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prData iwreq.u.data carries country code value. ++* ++* \retval 0 For success. ++* \retval -EEFAULT For fail. ++* ++* \note Country code is stored and channel list is updated based on current country domain. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wext_set_country(IN struct net_device *prNetDev, IN struct iw_point *prData) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ UINT_8 aucCountry[2]; ++ ++ ASSERT(prNetDev); ++ ++ /* prData->pointer should be like "COUNTRY US", "COUNTRY EU" ++ * and "COUNTRY JP" ++ */ ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prData) || !prData->pointer || prData->length < 10) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ aucCountry[0] = *((PUINT_8)prData->pointer + 8); ++ aucCountry[1] = *((PUINT_8)prData->pointer + 9); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, &aucCountry[0], 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To report the iw private args table to user space. ++* ++* \param[in] prNetDev Net device requested. ++* \param[out] prData iwreq.u.data to carry the private args table. ++* ++* \retval 0 For success. ++* \retval -E2BIG For user's buffer size is too small. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wext_get_priv(IN struct net_device *prNetDev, OUT struct iw_point *prData) ++{ ++ UINT_16 u2BufferSize = prData->length; ++ ++ /* Update our private args table size */ ++ prData->length = (__u16)sizeof(rIwPrivTable); ++ if (u2BufferSize < prData->length) ++ return -E2BIG; ++ ++ if (prData->length) { ++ if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable))) ++ return -EFAULT; ++ } ++ ++ return 0; ++} /* wext_get_priv */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ioctl() (Linux Wireless Extensions) routines ++* ++* \param[in] prDev Net device requested. ++* \param[in] ifr The ifreq structure for seeting the wireless extension. ++* \param[in] i4Cmd The wireless extension ioctl command. ++* ++* \retval zero On success. ++* \retval -EOPNOTSUPP If the cmd is not supported. ++* \retval -EFAULT If copy_to_user goes wrong. ++* \retval -EINVAL If any value's out of range. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd) ++{ ++ struct iwreq *iwr = (struct iwreq *)prIfReq; ++ struct iw_request_info rIwReqInfo; ++ int ret = 0; ++ char *prExtraBuf = NULL; ++ UINT_32 u4ExtraSize = 0; ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_PARAM_PMKID_T prPmkid; ++ ++ /* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */ ++ ++ rIwReqInfo.cmd = (__u16) i4Cmd; ++ rIwReqInfo.flags = 0; ++ ++ switch (i4Cmd) { ++ case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */ ++ ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL); ++ break; ++ ++ /* case SIOCSIWNWID: 0x8B02, deprecated */ ++ /* case SIOCGIWNWID: 0x8B03, deprecated */ ++ ++ case SIOCSIWFREQ: /* 0x8B04, set channel */ ++ ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL); ++ break; ++ ++ case SIOCGIWFREQ: /* 0x8B05, get channel */ ++ ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL); ++ break; ++ ++ case SIOCSIWMODE: /* 0x8B06, set operation mode */ ++ ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL); ++ /* ret = 0; */ ++ break; ++ ++ case SIOCGIWMODE: /* 0x8B07, get operation mode */ ++ ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL); ++ break; ++ ++ /* case SIOCSIWSENS: 0x8B08, unsupported */ ++ /* case SIOCGIWSENS: 0x8B09, unsupported */ ++ ++ /* case SIOCSIWRANGE: 0x8B0A, unused */ ++ case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */ ++ if (iwr->u.data.pointer != NULL) { ++ /* Buffer size should be large enough */ ++ if (iwr->u.data.length < sizeof(struct iw_range)) { ++ ret = -E2BIG; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ /* reset all fields */ ++ memset(prExtraBuf, 0, sizeof(struct iw_range)); ++ iwr->u.data.length = sizeof(struct iw_range); ++ ++ ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf); ++ /* Push up to the caller */ ++ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) ++ ret = -EFAULT; ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range)); ++ prExtraBuf = NULL; ++ } else { ++ ret = -EINVAL; ++ } ++ break; ++ ++ case SIOCSIWPRIV: /* 0x8B0C, set country code */ ++ ret = wext_set_country(prDev, &iwr->u.data); ++ break; ++ ++ case SIOCGIWPRIV: /* 0x8B0D, get private args table */ ++ ret = wext_get_priv(prDev, &iwr->u.data); ++ break; ++ ++ /* case SIOCSIWSTATS: 0x8B0E, unused */ ++ /* case SIOCGIWSTATS: ++ get statistics, intercepted by wireless_process_ioctl() in wireless.c, ++ redirected to dev_iwstats(), dev->get_wireless_stats(). ++ */ ++ /* case SIOCSIWSPY: 0x8B10, unsupported */ ++ /* case SIOCGIWSPY: 0x8B11, unsupported */ ++ /* case SIOCSIWTHRSPY: 0x8B12, unsupported */ ++ /* case SIOCGIWTHRSPY: 0x8B13, unsupported */ ++ ++ case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */ ++ if (iwr->u.ap_addr.sa_data[0] == 0 && ++ iwr->u.ap_addr.sa_data[1] == 0 && ++ iwr->u.ap_addr.sa_data[2] == 0 && ++ iwr->u.ap_addr.sa_data[3] == 0 && ++ iwr->u.ap_addr.sa_data[4] == 0 && iwr->u.ap_addr.sa_data[5] == 0) { ++ /* WPA Supplicant will set 000000000000 in ++ ** wpa_driver_wext_deinit(), do nothing here or disassoc again? ++ */ ++ ret = 0; ++ break; ++ } ++ ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL); ++ ++ break; ++ ++ case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */ ++ ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL); ++ break; ++ ++ case SIOCSIWMLME: /* 0x8B16, request MLME operation */ ++ /* Fixed length structure */ ++ if (iwr->u.data.length != sizeof(struct iw_mlme)) { ++ DBGLOG(REQ, ERROR, "MLME buffer strange:%d\n", iwr->u.data.length); ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (!iwr->u.data.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme))) ++ ret = -EFAULT; ++ else ++ ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf); ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); ++ prExtraBuf = NULL; ++ break; ++ ++ /* case SIOCGIWAPLIST: 0x8B17, deprecated */ ++ case SIOCSIWSCAN: /* 0x8B18, scan request */ ++ if (iwr->u.data.pointer == NULL) ++ ret = wext_set_scan(prDev, NULL, NULL, NULL); ++#if WIRELESS_EXT > 17 ++ else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { ++ prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ if (copy_from_user(prExtraBuf, ((struct iw_scan_req *)(iwr->u.data.pointer))->essid, ++ ((struct iw_scan_req *)(iwr->u.data.pointer))->essid_len)) { ++ ret = -EFAULT; ++ } else { ++ ret = wext_set_scan(prDev, NULL, (union iwreq_data *)&(iwr->u.data), prExtraBuf); ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN); ++ prExtraBuf = NULL; ++ } ++#endif ++ else ++ ret = -EINVAL; ++ break; ++#if 1 ++ case SIOCGIWSCAN: /* 0x8B19, get scan results */ ++ if (!iwr->u.data.pointer || !iwr->u.essid.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ u4ExtraSize = iwr->u.data.length; ++ /* allocate the same size of kernel buffer to store scan results. */ ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ /* iwr->u.data.length may be updated by wext_get_scan() */ ++ ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf); ++ if (ret != 0) { ++ if (ret == -E2BIG) ++ DBGLOG(REQ, WARN, "[wifi] wext_get_scan -E2BIG\n"); ++ } else { ++ /* check updated length is valid */ ++ ASSERT(iwr->u.data.length <= u4ExtraSize); ++ if (iwr->u.data.length > u4ExtraSize) { ++ DBGLOG(REQ, INFO, "Updated result length is larger than allocated (%d > %u)\n", ++ iwr->u.data.length, u4ExtraSize); ++ iwr->u.data.length = u4ExtraSize; ++ } ++ ++ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) ++ ret = -EFAULT; ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ ++ break; ++ ++#endif ++ ++#if 1 ++ case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */ ++ if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) { ++ ret = -E2BIG; ++ break; ++ } ++ if (!iwr->u.essid.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, iwr->u.essid.length)) { ++ ret = -EFAULT; ++ } else { ++ /* Add trailing '\0' for printk */ ++ /* prExtraBuf[iwr->u.essid.length] = 0; */ ++ /* printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length); */ ++ ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); ++ /* printk ("set essid %d\n", ret); */ ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4); ++ prExtraBuf = NULL; ++ break; ++ ++#endif ++ ++ case SIOCGIWESSID: /* 0x8B1B, get SSID */ ++ if (!iwr->u.essid.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) { ++ DBGLOG(REQ, ERROR, "[wifi] iwr->u.essid.length:%d too small\n", iwr->u.essid.length); ++ ret = -E2BIG; /* let caller try larger buffer */ ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ /* iwr->u.essid.length is updated by wext_get_essid() */ ++ ++ ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); ++ if (ret == 0) { ++ if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) ++ ret = -EFAULT; ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE); ++ prExtraBuf = NULL; ++ ++ break; ++ ++ /* case SIOCSIWNICKN: 0x8B1C, not supported */ ++ /* case SIOCGIWNICKN: 0x8B1D, not supported */ ++ ++ case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */ ++ /* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL); */ ++ break; ++ ++ case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */ ++ ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL); ++ break; ++ ++ case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */ ++ ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL); ++ break; ++ ++ case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */ ++ ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL); ++ break; ++ ++ /* case SIOCSIWFRAG: 0x8B24, unsupported */ ++ case SIOCGIWFRAG: /* 0x8B25, get frag threshold */ ++ ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL); ++ break; ++ ++ case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */ ++ ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL); ++ break; ++ ++ case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */ ++ ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL); ++ break; ++ ++ /* case SIOCSIWRETRY: 0x8B28, unsupported */ ++ /* case SIOCGIWRETRY: 0x8B29, unsupported */ ++ ++#if 1 ++ case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */ ++ /* Only DISABLED case has NULL pointer and length == 0 */ ++ if (iwr->u.encoding.pointer) { ++ if (iwr->u.encoding.length > 16) { ++ ret = -E2BIG; ++ break; ++ } ++ ++ u4ExtraSize = iwr->u.encoding.length; ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) ++ ret = -EFAULT; ++ } else if (iwr->u.encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret == 0) ++ ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf); ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ break; ++ ++ case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */ ++ /* check pointer */ ++ ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL); ++ break; ++ ++ case SIOCSIWPOWER: /* 0x8B2C, set power management */ ++ ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL); ++ break; ++ ++ case SIOCGIWPOWER: /* 0x8B2D, get power management */ ++ ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL); ++ break; ++ ++#if WIRELESS_EXT > 17 ++ case SIOCSIWGENIE: /* 0x8B30, set gen ie */ ++ if (iwr->u.data.pointer == NULL) ++ break; ++ ++ if (0 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) ++ break; ++ ++ /* Fixed length structure */ ++#if CFG_SUPPORT_WAPI ++ if (iwr->u.data.length > 42 /* The max wapi ie buffer */) { ++ ret = -EINVAL; ++ break; ++ } ++#endif ++ u4ExtraSize = iwr->u.data.length; ++ if (u4ExtraSize == 0) ++ break; ++ ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, iwr->u.data.length)) { ++ ret = -EFAULT; ++ } else { ++#if CFG_SUPPORT_WAPI ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiAssocInfo, ++ prExtraBuf, ++ u4ExtraSize, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", ++ rStatus); */ ++#endif ++#if CFG_SUPPORT_WPS2 ++ PUINT_8 prDesiredIE = NULL; ++ ++ if (wextSrchDesiredWPSIE(prExtraBuf, ++ u4ExtraSize, ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWSCAssocInfo, ++ prDesiredIE, ++ IE_SIZE(prDesiredIE), ++ FALSE, ++ FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO "[WSC] set WSC assoc info ++ error:%lx\n", rStatus); */ ++ } ++ } ++#endif ++#if CFG_SUPPORT_WAPI ++ } ++#endif ++ } ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ break; ++ ++ case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */ ++ break; ++ ++#endif ++ ++ case SIOCSIWAUTH: /* 0x8B32, set auth mode params */ ++ ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL); ++ break; ++ ++ /* case SIOCGIWAUTH: 0x8B33, unused? */ ++ case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */ ++ if (iwr->u.encoding.pointer) { ++ u4ExtraSize = iwr->u.encoding.length; ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) ++ ret = -EFAULT; ++ } else if (iwr->u.encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret == 0) ++ ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf); ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ break; ++ ++ /* case SIOCGIWENCODEEXT: 0x8B35, unused? */ ++ ++ case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */ ++#if 1 ++ if (iwr->u.data.pointer) { ++ /* Fixed length structure */ ++ if (iwr->u.data.length != sizeof(struct iw_pmksa)) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ u4ExtraSize = sizeof(struct iw_pmksa); ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_pmksa))) { ++ ret = -EFAULT; ++ } else { ++ switch (((struct iw_pmksa *)prExtraBuf)->cmd) { ++ case IW_PMKSA_ADD: ++ /* ++ printk(KERN_INFO "IW_PMKSA_ADD [ %pM ]\n", ++ (((struct iw_pmksa *)pExtraBuf)->bssid.sa_data)); ++ */ ++ prPmkid = ++ (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), ++ VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); ++ ret = -ENOMEM; ++ break; ++ } ++ ++ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); ++ prPmkid->u4BSSIDInfoCount = 1; ++ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, ++ ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data, 6); ++ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, ++ ((struct iw_pmksa *)prExtraBuf)->pmkid, IW_PMKID_LEN); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, ++ prPmkid, ++ sizeof(PARAM_PMKID_T), ++ FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "add pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); ++ break; ++ case IW_PMKSA_REMOVE: ++ /* ++ printk(KERN_INFO "IW_PMKSA_REMOVE [ %pM ]\n", ++ (((struct iw_pmksa *)buf)->bssid.sa_data)); ++ */ ++ break; ++ case IW_PMKSA_FLUSH: ++ /* ++ printk(KERN_INFO "IW_PMKSA_FLUSH\n"); ++ */ ++ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, ++ "Can not alloc memory for IW_PMKSA_FLUSH\n"); ++ ret = -ENOMEM; ++ break; ++ } ++ ++ prPmkid->u4Length = 8; ++ prPmkid->u4BSSIDInfoCount = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, ++ prPmkid, ++ sizeof(PARAM_PMKID_T), ++ FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "flush pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); ++ break; ++ default: ++ DBGLOG(REQ, WARN, "UNKNOWN iw_pmksa command:%d\n", ++ ((struct iw_pmksa *)prExtraBuf)->cmd); ++ ret = -EFAULT; ++ break; ++ } ++ } ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ } else if (iwr->u.data.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++#endif ++ break; ++ ++#endif ++ ++ default: ++ /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */ ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ /* printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); */ ++ ++ return ret; ++} /* wext_support_ioctl */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To send an event (RAW socket pacekt) to user process actively. ++* ++* \param[in] prGlueInfo Glue layer info. ++* \param[in] u4cmd Whcih event command we want to indicate to user process. ++* \param[in] pData Data buffer to be indicated. ++* \param[in] dataLen Available data size in pData. ++* ++* \return (none) ++* ++* \note Event is indicated to upper layer if cmd is supported and data is valid. ++* Using of kernel symbol wireless_send_event(), which is defined in ++* after WE-14 (2.4.20). ++*/ ++/*----------------------------------------------------------------------------*/ ++void ++wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, ++ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4dataLen) ++{ ++ union iwreq_data wrqu; ++ unsigned char *pucExtraInfo = NULL; ++#if WIRELESS_EXT >= 15 ++ unsigned char *pucDesiredIE = NULL; ++ unsigned char aucExtraInfoBuf[200]; ++#endif ++#if WIRELESS_EXT < 18 ++ int i; ++#endif ++ ++ memset(&wrqu, 0, sizeof(wrqu)); ++ ++ switch (u4Cmd) { ++ case SIOCGIWTXPOW: ++ memcpy(&wrqu.power, pucData, u4dataLen); ++ break; ++ case SIOCGIWSCAN: ++ complete_all(&prGlueInfo->rScanComp); ++ break; ++ ++ case SIOCGIWAP: ++ if (pucData) ++ ether_addr_copy((u8 *)&(wrqu.ap_addr.sa_data), pucData); ++ /*memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);*/ ++ else ++ memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN); ++ break; ++ ++ case IWEVASSOCREQIE: ++#if WIRELESS_EXT < 15 ++ /* under WE-15, no suitable Event can be used */ ++ goto skip_indicate_event; ++#else ++ /* do supplicant a favor, parse to the start of WPA/RSN IE */ ++ if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) { ++ /* RSN IE found */ ++ /* Do nothing */ ++#if 0 ++ } else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { ++ /* WPS IE found */ ++ /* Do nothing */ ++#endif ++ } else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { ++ /* WPA IE found */ ++ /* Do nothing*/ ++#if CFG_SUPPORT_WAPI /* Android+ */ ++ } else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) { ++ /* WAPI IE found */ ++ /* printk("wextSrchDesiredWAPIIE!!\n"); */ ++#endif ++ } else { ++ /* no WPA/RSN IE found, skip this event */ ++ goto skip_indicate_event; ++ } ++#if WIRELESS_EXT < 18 ++ /* under WE-18, only IWEVCUSTOM can be used */ ++ u4Cmd = IWEVCUSTOM; ++ pucExtraInfo = aucExtraInfoBuf; ++ pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs="); ++ /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */ ++ /* translate binary string to hex string, requirement of IWEVCUSTOM */ ++ for (i = 0; i < pucDesiredIE[1] + 2; ++i) ++ pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]); ++ pucExtraInfo = aucExtraInfoBuf; ++ wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2; ++#else ++ /* IWEVASSOCREQIE, indicate binary string */ ++ pucExtraInfo = pucDesiredIE; ++ wrqu.data.length = pucDesiredIE[1] + 2; ++#endif ++#endif /* WIRELESS_EXT < 15 */ ++ break; ++ ++ case IWEVMICHAELMICFAILURE: ++#if WIRELESS_EXT < 15 ++ /* under WE-15, no suitable Event can be used */ ++ goto skip_indicate_event; ++#else ++ if (pucData) { ++ P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T) pucData; ++ /* under WE-18, only IWEVCUSTOM can be used */ ++ u4Cmd = IWEVCUSTOM; ++ pucExtraInfo = aucExtraInfoBuf; ++ pucExtraInfo += sprintf(pucExtraInfo, "MLME-MICHAELMICFAILURE.indication "); ++ pucExtraInfo += sprintf(pucExtraInfo, ++ "%s", ++ (pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ? ++ "groupcast " : "unicast "); ++ ++ wrqu.data.length = pucExtraInfo - aucExtraInfoBuf; ++ pucExtraInfo = aucExtraInfoBuf; ++ } ++#endif /* WIRELESS_EXT < 15 */ ++ break; ++ ++ case IWEVPMKIDCAND: ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 && ++ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) { ++ ++ /* only used in WPA2 */ ++#if WIRELESS_EXT >= 18 ++ P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T) pucData; ++ ++ struct iw_pmkid_cand rPmkidCand; ++ ++ pucExtraInfo = aucExtraInfoBuf; ++ ++ rPmkidCand.flags = prPmkidCand->u4Flags; ++ rPmkidCand.index = 0; ++ rPmkidCand.bssid.sa_family = 0; ++ kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6); ++ ++ kalMemCopy(pucExtraInfo, (PUINT_8) &rPmkidCand, sizeof(struct iw_pmkid_cand)); ++ wrqu.data.length = sizeof(struct iw_pmkid_cand); ++ ++ /* pmkid canadidate list is supported after WE-18 */ ++ /* indicate struct iw_pmkid_cand */ ++#else ++ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */ ++ goto skip_indicate_event; ++#endif ++ } else { ++ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */ ++ goto skip_indicate_event; ++ } ++ break; ++ ++ case IWEVCUSTOM: ++ u4Cmd = IWEVCUSTOM; ++ pucExtraInfo = aucExtraInfoBuf; ++ kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T)); ++ wrqu.data.length = sizeof(PTA_IPC_T); ++ break; ++ ++ default: ++ /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */ ++ goto skip_indicate_event; ++ } ++ ++ /* Send event to user space */ ++ wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo); ++ ++skip_indicate_event: ++ return; ++} /* wext_indicate_wext_event */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method of struct net_device, to get the network interface statistical ++* information. ++* ++* Whenever an application needs to get statistics for the interface, this method ++* is called. This happens, for example, when ifconfig or netstat -i is run. ++* ++* \param[in] pDev Pointer to struct net_device. ++* ++* \return net_device_stats buffer pointer. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev) ++{ ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_statistics *pStats = NULL; ++ INT_32 i4Rssi; ++ UINT_32 bufLen = 0; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) ++ goto stat_out; ++ ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); ++ ++ if (!prDev || !netif_carrier_ok(prDev)) { ++ /* network not connected */ ++ goto stat_out; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, FALSE, &bufLen); ++ ++stat_out: ++ return pStats; ++} /* wlan_get_wireless_stats */ ++ ++ ++#endif /* WIRELESS_EXT */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c +new file mode 100644 +index 000000000000..2b6c3df84594 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c +@@ -0,0 +1,3142 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext_priv.c#4 ++*/ ++ ++/*! \file gl_wext_priv.c ++ \brief This file includes private ioctl support. ++*/ ++ ++/* ++** Log: gl_wext_priv.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 20 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * [WCXRP00001202] [MT6628 Wi-Fi][FW] Adding the New PN init code ++ * use return to avoid the ioctl return not supported ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 01 16 2012 wh.su ++ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl ++ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 11 02 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Fixed typo. ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 01 27 2011 cm.chang ++ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default ++ * . ++ * ++ * 01 26 2011 wh.su ++ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux ++ * adding the SW cmd ioctl support, use set/get structure ioctl. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Adjust OID order. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 07 2011 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add a new compiling option to control if MCR read/write is permitted ++ * ++ * 12 31 2010 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add some iwpriv commands to support test mode operation ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Support set PS profile and set WMM-PS related iwpriv. ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * correct typo for NVRAM access. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * enable OID_CUSTOM_MTK_WIFI_TEST for RFTest & META tool ++ * ++ * 05 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix private ioctl for rftest ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++** \main\maintrunk.MT5921\32 2009-10-08 10:33:25 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input ++** parameters and pointers. ++** \main\maintrunk.MT5921\31 2009-09-29 16:46:21 GMT mtk01090 ++** Remove unused functions ++** \main\maintrunk.MT5921\30 2009-09-29 14:46:47 GMT mtk01090 ++** Fix compile warning ++** \main\maintrunk.MT5921\29 2009-09-29 14:28:48 GMT mtk01090 ++** Fix compile warning ++** \main\maintrunk.MT5921\28 2009-09-28 22:21:38 GMT mtk01090 ++** Refine lines to suppress compile warning ++** \main\maintrunk.MT5921\27 2009-09-28 20:19:14 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\26 2009-08-18 22:56:53 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\25 2009-05-07 22:26:15 GMT mtk01089 ++** Add mandatory and private IO control for Linux BWCS ++** \main\maintrunk.MT5921\24 2009-04-29 10:07:05 GMT mtk01088 ++** fixed the compiling error at linux ++** \main\maintrunk.MT5921\23 2009-04-24 09:09:45 GMT mtk01088 ++** mark the code not used at linux supplicant v0.6.7 ++** \main\maintrunk.MT5921\22 2008-11-24 21:03:51 GMT mtk01425 ++** 1. Add PTA_ENABLED flag ++** \main\maintrunk.MT5921\21 2008-08-29 14:55:59 GMT mtk01088 ++** adjust the code for meet the coding style, and add assert check ++** \main\maintrunk.MT5921\20 2008-07-16 15:23:20 GMT mtk01104 ++** Support GPIO2 mode ++** \main\maintrunk.MT5921\19 2008-07-15 17:43:11 GMT mtk01084 ++** modify variable name ++** \main\maintrunk.MT5921\18 2008-07-14 14:37:58 GMT mtk01104 ++** Add exception handle about length in function priv_set_struct() ++** \main\maintrunk.MT5921\17 2008-07-14 13:55:32 GMT mtk01104 ++** Support PRIV_CMD_BT_COEXIST ++** \main\maintrunk.MT5921\16 2008-07-09 00:20:15 GMT mtk01461 ++** Add priv oid to support WMM_PS_TEST ++** \main\maintrunk.MT5921\15 2008-06-02 11:15:22 GMT mtk01461 ++** Update after wlanoidSetPowerMode changed ++** \main\maintrunk.MT5921\14 2008-05-30 19:31:07 GMT mtk01461 ++** Add IOCTL for Power Mode ++** \main\maintrunk.MT5921\13 2008-05-30 18:57:15 GMT mtk01461 ++** Not use wlanoidSetCSUMOffloadForLinux() ++** \main\maintrunk.MT5921\12 2008-05-30 15:13:18 GMT mtk01084 ++** rename wlanoid ++** \main\maintrunk.MT5921\11 2008-05-29 14:16:31 GMT mtk01084 ++** rename for wlanoidSetBeaconIntervalForLinux ++** \main\maintrunk.MT5921\10 2008-04-17 23:06:37 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\9 2008-03-31 21:00:55 GMT mtk01461 ++** Add priv IOCTL for VOIP setting ++** \main\maintrunk.MT5921\8 2008-03-31 13:49:43 GMT mtk01461 ++** Add priv ioctl to turn on / off roaming ++** \main\maintrunk.MT5921\7 2008-03-26 15:35:14 GMT mtk01461 ++** Add CSUM offload priv ioctl for Linux ++** \main\maintrunk.MT5921\6 2008-03-11 14:50:59 GMT mtk01461 ++** Unify priv ioctl ++** \main\maintrunk.MT5921\5 2007-11-06 19:32:30 GMT mtk01088 ++** add WPS code ++** \main\maintrunk.MT5921\4 2007-10-30 12:01:39 GMT MTK01425 ++** 1. Update wlanQueryInformation and wlanSetInformation ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#include "gl_os.h" ++#include "gl_wext_priv.h" ++#if CFG_SUPPORT_WAPI ++#include "gl_sec.h" ++#endif ++#if CFG_ENABLE_WIFI_DIRECT ++#include "gl_p2p_os.h" ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY)) ++#define CMD_START "START" ++#define CMD_STOP "STOP" ++#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" ++#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" ++#define CMD_RSSI "RSSI" ++#define CMD_LINKSPEED "LINKSPEED" ++#define CMD_RXFILTER_START "RXFILTER-START" ++#define CMD_RXFILTER_STOP "RXFILTER-STOP" ++#define CMD_RXFILTER_ADD "RXFILTER-ADD" ++#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" ++#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" ++#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" ++#define CMD_BTCOEXMODE "BTCOEXMODE" ++#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" ++#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" ++#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" ++#define CMD_SETFWPATH "SETFWPATH" ++#define CMD_SETBAND "SETBAND" ++#define CMD_GETBAND "GETBAND" ++#define CMD_COUNTRY "COUNTRY" ++#define CMD_P2P_SET_NOA "P2P_SET_NOA" ++#define CMD_P2P_GET_NOA "P2P_GET_NOA" ++#define CMD_P2P_SET_PS "P2P_SET_PS" ++#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" ++#define CMD_SETROAMMODE "SETROAMMODE" ++#define CMD_MIRACAST "MIRACAST" ++ ++#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" ++#define CMD_PNOSETUP_SET "PNOSETUP " ++#define CMD_PNOENABLE_SET "PNOFORCE" ++#define CMD_PNODEBUG_SET "PNODEBUG" ++#define CMD_WLS_BATCHING "WLS_BATCHING" ++ ++#define CMD_OKC_SET_PMK "SET_PMK" ++#define CMD_OKC_ENABLE "OKC_ENABLE" ++ ++/* miracast related definition */ ++#define MIRACAST_MODE_OFF 0 ++#define MIRACAST_MODE_SOURCE 1 ++#define MIRACAST_MODE_SINK 2 ++ ++#ifndef MIRACAST_AMPDU_SIZE ++#define MIRACAST_AMPDU_SIZE 8 ++#endif ++ ++#ifndef MIRACAST_MCHAN_ALGO ++#define MIRACAST_MCHAN_ALGO 1 ++#endif ++ ++#ifndef MIRACAST_MCHAN_BW ++#define MIRACAST_MCHAN_BW 25 ++#endif ++ ++#define CMD_BAND_AUTO 0 ++#define CMD_BAND_5G 1 ++#define CMD_BAND_2G 2 ++#define CMD_BAND_ALL 3 ++ ++/* Mediatek private command */ ++ ++#define CMD_SET_SW_CTRL "SET_SW_CTRL" ++#define CMD_GET_SW_CTRL "GET_SW_CTRL" ++#define CMD_SET_CFG "SET_CFG" ++#define CMD_GET_CFG "GET_CFG" ++#define CMD_SET_CHIP "SET_CHIP" ++#define CMD_GET_CHIP "GET_CHIP" ++#define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL" ++#define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL" ++#define PRIV_CMD_SIZE 512 ++ ++static UINT_32 g_ucMiracastMode = MIRACAST_MODE_OFF; ++ ++typedef struct cmd_tlv { ++ char prefix; ++ char version; ++ char subver; ++ char reserved; ++} cmd_tlv_t; ++ ++typedef struct priv_driver_cmd_s { ++ char buf[PRIV_CMD_SIZE]; ++ int used_len; ++ int total_len; ++} priv_driver_cmd_t; ++ ++#if CFG_SUPPORT_BATCH_SCAN ++#define CMD_BATCH_SET "WLS_BATCHING SET" ++#define CMD_BATCH_GET "WLS_BATCHING GET" ++#define CMD_BATCH_STOP "WLS_BATCHING STOP" ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static int ++priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); ++ ++static int ++priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); ++ ++#if 0 /* CFG_SUPPORT_WPS */ ++static int ++priv_set_appie(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); ++ ++static int ++priv_set_filter(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); ++#endif /* CFG_SUPPORT_WPS */ ++ ++static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY * ppWlanReqEntry); ++ ++#if 0 ++static WLAN_STATUS ++reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++static WLAN_STATUS ++reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++static WLAN_STATUS ++reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static UINT_8 aucOidBuf[4096] = { 0 }; ++ ++/* OID processing table */ ++/* Order is important here because the OIDs should be in order of ++ increasing value for binary searching. */ ++static WLAN_REQ_ENTRY arWlanOidReqTable[] = { ++ /* ++ {(NDIS_OID)rOid, ++ (PUINT_8)pucOidName, ++ fgQryBufLenChecking, fgSetBufLenChecking, fgIsHandleInGlueLayerOnly, u4InfoBufLen, ++ pfOidQueryHandler, ++ pfOidSetHandler} ++ */ ++ /* General Operational Characteristics */ ++ ++ /* Ethernet Operational Characteristics */ ++ {OID_802_3_CURRENT_ADDRESS, ++ DISP_STRING("OID_802_3_CURRENT_ADDRESS"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr, ++ NULL}, ++ ++ /* OID_802_3_MULTICAST_LIST */ ++ /* OID_802_3_MAXIMUM_LIST_SIZE */ ++ /* Ethernet Statistics */ ++ ++ /* NDIS 802.11 Wireless LAN OIDs */ ++ {OID_802_11_SUPPORTED_RATES, ++ DISP_STRING("OID_802_11_SUPPORTED_RATES"), ++ TRUE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_RATES_EX), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates, ++ NULL} ++ , ++ /* ++ {OID_802_11_CONFIGURATION, ++ DISP_STRING("OID_802_11_CONFIGURATION"), ++ TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_802_11_CONFIG_T), ++ (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration, ++ (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration}, ++ */ ++ {OID_PNP_SET_POWER, ++ DISP_STRING("OID_PNP_SET_POWER"), ++ TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_DEVICE_POWER_STATE), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState} ++ , ++ ++ /* Custom OIDs */ ++ {OID_CUSTOM_OID_INTERFACE_VERSION, ++ DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"), ++ TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion, ++ NULL} ++ , ++ ++ /* ++ #if PTA_ENABLED ++ {OID_CUSTOM_BT_COEXIST_CTRL, ++ DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_BT_COEXIST_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl}, ++ #endif ++ */ ++ ++ /* ++ {OID_CUSTOM_POWER_MANAGEMENT_PROFILE, ++ DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam}, ++ {OID_CUSTOM_PATTERN_CONFIG, ++ DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUCT_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig}, ++ {OID_CUSTOM_BG_SSID_SEARCH_CONFIG, ++ DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam}, ++ {OID_CUSTOM_VOIP_SETUP, ++ DISP_STRING("OID_CUSTOM_VOIP_SETUP"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus}, ++ {OID_CUSTOM_ADD_TS, ++ DISP_STRING("OID_CUSTOM_ADD_TS"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS}, ++ {OID_CUSTOM_DEL_TS, ++ DISP_STRING("OID_CUSTOM_DEL_TS"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS}, ++ */ ++ ++ /* ++ #if CFG_LP_PATTERN_SEARCH_SLT ++ {OID_CUSTOM_SLT, ++ DISP_STRING("OID_CUSTOM_SLT"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode}, ++ #endif ++ ++ {OID_CUSTOM_ROAMING_EN, ++ DISP_STRING("OID_CUSTOM_ROAMING_EN"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction}, ++ {OID_CUSTOM_WMM_PS_TEST, ++ DISP_STRING("OID_CUSTOM_WMM_PS_TEST"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest}, ++ {OID_CUSTOM_COUNTRY_STRING, ++ DISP_STRING("OID_CUSTOM_COUNTRY_STRING"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry}, ++ ++ #if CFG_SUPPORT_802_11D ++ {OID_CUSTOM_MULTI_DOMAIN_CAPABILITY, ++ DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap}, ++ #endif ++ ++ {OID_CUSTOM_GPIO2_MODE, ++ DISP_STRING("OID_CUSTOM_GPIO2_MODE"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_PARAM_GPIO2_MODE_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode}, ++ {OID_CUSTOM_CONTINUOUS_POLL, ++ DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CONTINUOUS_POLL_T), ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile}, ++ {OID_CUSTOM_DISABLE_BEACON_DETECTION, ++ DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryDisableBeaconDetectionFunc, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc}, ++ */ ++ ++ /* WPS */ ++ /* ++ {OID_CUSTOM_DISABLE_PRIVACY_CHECK, ++ DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck}, ++ */ ++ ++ {OID_CUSTOM_MCR_RW, ++ DISP_STRING("OID_CUSTOM_MCR_RW"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite} ++ , ++ ++ {OID_CUSTOM_EEPROM_RW, ++ DISP_STRING("OID_CUSTOM_EEPROM_RW"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite} ++ , ++ ++ {OID_CUSTOM_SW_CTRL, ++ DISP_STRING("OID_CUSTOM_SW_CTRL"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite} ++ , ++ ++ {OID_CUSTOM_MEM_DUMP, ++ DISP_STRING("OID_CUSTOM_MEM_DUMP"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MEM_DUMP_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump, ++ NULL} ++ , ++ ++ {OID_CUSTOM_TEST_MODE, ++ DISP_STRING("OID_CUSTOM_TEST_MODE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode} ++ , ++ ++ /* ++ {OID_CUSTOM_TEST_RX_STATUS, ++ DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus, ++ NULL}, ++ {OID_CUSTOM_TEST_TX_STATUS, ++ DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus, ++ NULL}, ++ */ ++ {OID_CUSTOM_ABORT_TEST_MODE, ++ DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode} ++ , ++ {OID_CUSTOM_MTK_WIFI_TEST, ++ DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest} ++ , ++ ++ /* OID_CUSTOM_EMULATION_VERSION_CONTROL */ ++ ++ /* BWCS */ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ {OID_CUSTOM_BWCS_CMD, ++ DISP_STRING("OID_CUSTOM_BWCS_CMD"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PTA_IPC_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT} ++ , ++#endif ++ ++/* {OID_CUSTOM_SINGLE_ANTENNA, ++ DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna}, ++ {OID_CUSTOM_SET_PTA, ++ DISP_STRING("OID_CUSTOM_SET_PTA"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta}, ++ */ ++ ++ {OID_CUSTOM_MTK_NVRAM_RW, ++ DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite} ++ , ++ ++ {OID_CUSTOM_CFG_SRC_TYPE, ++ DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_CFG_SRC_TYPE_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType, ++ NULL} ++ , ++ ++ {OID_CUSTOM_EEPROM_TYPE, ++ DISP_STRING("OID_CUSTOM_EEPROM_TYPE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_EEPROM_TYPE_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType, ++ NULL} ++ , ++ ++#if CFG_SUPPORT_WAPI ++ {OID_802_11_WAPI_MODE, ++ DISP_STRING("OID_802_11_WAPI_MODE"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode} ++ , ++ {OID_802_11_WAPI_ASSOC_INFO, ++ DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo} ++ , ++ {OID_802_11_SET_WAPI_KEY, ++ DISP_STRING("OID_802_11_SET_WAPI_KEY"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_WPI_KEY_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey} ++ , ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++ {OID_802_11_WSC_ASSOC_INFO, ++ DISP_STRING("OID_802_11_WSC_ASSOC_INFO"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWSCAssocInfo} ++ , ++#endif ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~ ++* SIOCIWLASTPRIV). ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIfReq Pointer to ifreq structure. ++* \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV. ++* ++* \retval 0 for success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++int priv_support_ioctl(IN struct net_device *prNetDev, IN OUT struct ifreq *prIfReq, IN int i4Cmd) ++{ ++ /* prIfReq is verified in the caller function wlanDoIOCTL() */ ++ struct iwreq *prIwReq = (struct iwreq *)prIfReq; ++ struct iw_request_info rIwReqInfo; ++ ++ /* prDev is verified in the caller function wlanDoIOCTL() */ ++ ++ /* Prepare the call */ ++ rIwReqInfo.cmd = (__u16) i4Cmd; ++ rIwReqInfo.flags = 0; ++ ++ switch (i4Cmd) { ++ case IOCTL_SET_INT: ++ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ ++ return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); ++ ++ case IOCTL_GET_INT: ++ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ ++ return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); ++ ++ case IOCTL_SET_STRUCT: ++ case IOCTL_SET_STRUCT_FOR_EM: ++ return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); ++ ++ case IOCTL_GET_STRUCT: ++ return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); ++ ++ default: ++ return -EOPNOTSUPP; ++ ++ } /* end of switch */ ++ ++} /* priv_support_ioctl */ ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ ++EVENT_BATCH_RESULT_T g_rEventBatchResult[CFG_BATCH_MAX_MSCAN]; ++ ++UINT_32 batchChannelNum2Freq(UINT_32 u4ChannelNum) ++{ ++ UINT_32 u4ChannelInMHz; ++ ++ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) ++ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; ++ else if (u4ChannelNum == 14) ++ u4ChannelInMHz = 2484; ++ else if (u4ChannelNum == 133) ++ u4ChannelInMHz = 3665; /* 802.11y */ ++ else if (u4ChannelNum == 137) ++ u4ChannelInMHz = 3685; /* 802.11y */ ++ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) ++ u4ChannelInMHz = 5000 + u4ChannelNum * 5; ++ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) ++ u4ChannelInMHz = 4000 + u4ChannelNum * 5; ++ else ++ u4ChannelInMHz = 0; ++ ++ return u4ChannelInMHz; ++} ++ ++#define TMP_TEXT_LEN_S 40 ++#define TMP_TEXT_LEN_L 60 ++static UCHAR text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], text3[TMP_TEXT_LEN_L]; /* A safe len */ ++ ++WLAN_STATUS ++batchConvertResult(IN P_EVENT_BATCH_RESULT_T prEventBatchResult, ++ OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) ++{ ++ CHAR *p = pvBuffer; ++ CHAR ssid[ELEM_MAX_LEN_SSID + 1]; ++ INT_32 nsize = 0, nsize1, nsize2, nsize3, scancount; ++ INT_32 i, j, nleft; ++ UINT_32 freq; ++ ++ P_EVENT_BATCH_RESULT_ENTRY_T prEntry; ++ P_EVENT_BATCH_RESULT_T pBr; ++ ++ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ ++ ++ pBr = prEventBatchResult; ++ scancount = 0; ++ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { ++ scancount += pBr->ucScanCount; ++ pBr++; ++ } ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "scancount=%x\nnextcount=%x\n", scancount, scancount); ++ if (nsize1 < nleft) { ++ p += nsize1 = kalSprintf(p, "%s", text1); ++ nleft -= nsize1; ++ } else ++ goto short_buf; ++ ++ pBr = prEventBatchResult; ++ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { ++ DBGLOG(SCN, TRACE, "convert mscan = %d, apcount=%d, nleft=%d\n", j, pBr->ucScanCount, nleft); ++ ++ if (pBr->ucScanCount == 0) { ++ pBr++; ++ continue; ++ } ++ ++ nleft -= 5; /* -5 for "####\n" */ ++ ++ /* We only support one round scan result now. */ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", pBr->ucScanCount); ++ if (nsize1 < nleft) { ++ p += nsize1 = kalSprintf(p, "%s", text1); ++ nleft -= nsize1; ++ } else ++ goto short_buf; ++ ++ for (i = 0; i < pBr->ucScanCount; i++) { ++ prEntry = &pBr->arBatchResult[i]; ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "bssid=" MACSTR "\n", ++ prEntry->aucBssid[0], ++ prEntry->aucBssid[1], ++ prEntry->aucBssid[2], ++ prEntry->aucBssid[3], ++ prEntry->aucBssid[4], prEntry->aucBssid[5]); ++ ++ kalMemCopy(ssid, ++ prEntry->aucSSID, ++ (prEntry->ucSSIDLen < ELEM_MAX_LEN_SSID ? prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID)); ++ ssid[(prEntry->ucSSIDLen < ++ (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : (ELEM_MAX_LEN_SSID - 1))] = '\0'; ++ nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", ssid); ++ ++ freq = batchChannelNum2Freq(prEntry->ucFreq); ++ nsize3 = ++ kalSnprintf(text3, TMP_TEXT_LEN_L, ++ "freq=%u\nlevel=%d\ndist=%u\ndistSd=%u\n====\n", freq, ++ prEntry->cRssi, prEntry->u4Dist, prEntry->u4Distsd); ++ ++ nsize = nsize1 + nsize2 + nsize3; ++ if (nsize < nleft) { ++ ++ kalStrnCpy(p, text1, TMP_TEXT_LEN_S); ++ p += nsize1; ++ ++ kalStrnCpy(p, text2, TMP_TEXT_LEN_L); ++ p += nsize2; ++ ++ kalStrnCpy(p, text3, TMP_TEXT_LEN_L); ++ p += nsize3; ++ ++ nleft -= nsize; ++ } else { ++ DBGLOG(SCN, TRACE, "Warning: Early break! (%d)\n", i); ++ break; /* discard following entries, TODO: apcount? */ ++ } ++ } ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n"); ++ p += kalSprintf(p, "%s", text1); ++ ++ pBr++; ++ } ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n"); ++ kalSprintf(p, "%s", text1); ++ ++ *pu4RetLen = u4MaxBufferLen - nleft; ++ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++short_buf: ++ DBGLOG(SCN, TRACE, ++ "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), ++ u4MaxBufferLen, (char *)pvBuffer); ++ return WLAN_STATUS_INVALID_LENGTH; ++} ++#endif ++ ++#if CFG_SUPPORT_GET_CH_ENV ++WLAN_STATUS ++scanEnvResult(P_GLUE_INFO_T prGlueInfo, OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ CHAR *p = pvBuffer; ++ INT_32 nsize; ++ INT_32 i, nleft; ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ CH_ENV_T chEnvInfo[54]; /* 54: from FW define; TODO: sync MAXIMUM_OPERATION_CHANNEL_LIST */ ++ UINT_32 i4GetCh = 0; ++ INT_32 i4Argc = 0; ++ PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; ++ UINT_8 ucTextLen = 40; ++ UCHAR text[ucTextLen]; ++ INT_32 u4Ret; ++ ++ prAdapter = prGlueInfo->prAdapter; ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ kalMemZero(chEnvInfo, sizeof(chEnvInfo)); ++ ++ DBGLOG(SCN, TRACE, "pvBuffer:%s, pu4RetLen:%d\n", (char *)pvBuffer, *pu4RetLen); ++ ++ wlanCfgParseArgument(pvBuffer, &i4Argc, apcArgv); ++ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); ++ ++ if (i4Argc >= 2) { ++ u4Ret = kalkStrtou32(apcArgv[1], 0, &i4GetCh); ++ if (u4Ret) ++ DBGLOG(SCN, TRACE, "parse pvBuffer error u4Ret=%d\n", u4Ret); ++ /* i4GetCh = kalStrtoul(apcArgv[1], NULL, 0); */ ++ } ++ ++ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ ++ ++ nsize = kalSnprintf(text, ucTextLen, "%s", "scanEnvResult\nResult:1\n");/* Always return 1 for alpha version. */ ++ ++ if (nsize < nleft) { ++ p += nsize = kalSnprintf(p, ucTextLen, "%s", text); ++ nleft -= nsize; ++ } else ++ goto short_buf; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ if (prBssDesc->ucChannelNum > 0) { ++ if (prBssDesc->ucChannelNum <= 14) { /* 1~14 */ ++ chEnvInfo[prBssDesc->ucChannelNum - 1].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum - 1].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 64) { /* 15~22 */ ++ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 116) { /* 23~27 */ ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 140) { /* 28~30 */ ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 165) { /* 31~35 */ ++ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucApNum++; ++ } ++ } ++ } ++ ++ for (i = 0; i < 54; i++) { ++ if (chEnvInfo[i].ucChNum != 0) { ++ if (i4GetCh == 0 || (chEnvInfo[i].ucChNum == (UINT_8)i4GetCh)) { ++ DBGLOG(SCN, TRACE, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, chEnvInfo[i].ucApNum); ++ p += nsize = ++ kalSnprintf(p, ucTextLen, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, ++ chEnvInfo[i].ucApNum); ++ nleft -= nsize; ++ } ++ } ++ } ++ ++ p += nsize = kalSnprintf(p, ucTextLen, "%s", "----\n"); ++ nleft -= nsize; ++ ++ *pu4RetLen = u4MaxBufferLen - nleft; ++ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++short_buf: ++ DBGLOG(SCN, TRACE, "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), u4MaxBufferLen, p); ++ return WLAN_STATUS_INVALID_LENGTH; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl set int handler. ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIwReqInfo Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. ++* \param[in] pcExtra The buffer with input value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL If a value is out of range. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ UINT_32 u4SubCmd; ++ PUINT_32 pu4IntBuf; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4BufLen = 0; ++ int status = 0; ++ P_PTA_IPC_T prPtaIpc; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->mode; ++ pu4IntBuf = (PUINT_32) pcExtra; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_TEST_MODE: ++ /* printk("TestMode=%ld\n", pu4IntBuf[1]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) { ++ prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE; ++ } else if (pu4IntBuf[1] == 0) { ++ prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE; ++ } else { ++ status = 0; ++ break; ++ } ++ prNdisReq->inNdisOidlength = 0; ++ prNdisReq->outNdisOidLength = 0; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++ case PRIV_CMD_TEST_CMD: ++ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++#if CFG_SUPPORT_PRIV_MCR_RW ++ case PRIV_CMD_ACCESS_MCR: ++ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (!prGlueInfo->fgMcrAccessAllowed) { ++ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) ++ prGlueInfo->fgMcrAccessAllowed = TRUE; ++ status = 0; ++ break; ++ } ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++#endif ++ ++ case PRIV_CMD_SW_CTRL: ++ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++#if 0 ++ case PRIV_CMD_BEACON_PERIOD: ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBeaconInterval, ++ (PVOID)&pu4IntBuf[1],/* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(UINT_32), &u4BufLen); ++ break; ++#endif ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ case PRIV_CMD_CSUM_OFFLOAD: ++ { ++ UINT_32 u4CSUMFlags; ++ ++ if (pu4IntBuf[1] == 1) ++ u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; ++ else if (pu4IntBuf[1] == 0) ++ u4CSUMFlags = 0; ++ else ++ return -EINVAL; ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidSetCSUMOffload, ++ (PVOID)&u4CSUMFlags, ++ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { ++ if (pu4IntBuf[1] == 1) ++ prNetDev->features |= NETIF_F_HW_CSUM; ++ else if (pu4IntBuf[1] == 0) ++ prNetDev->features &= ~NETIF_F_HW_CSUM; ++ } ++ } ++ break; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ case PRIV_CMD_POWER_MODE: ++ kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, ++ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ break; ++ ++ case PRIV_CMD_WMM_PS: ++ { ++ PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T rWmmPsTest; ++ ++ rWmmPsTest.bmfgApsdEnAc = (UINT_8) pu4IntBuf[1]; ++ rWmmPsTest.ucIsEnterPsAtOnce = (UINT_8) pu4IntBuf[2]; ++ rWmmPsTest.ucIsDisableUcTrigger = (UINT_8) pu4IntBuf[3]; ++ rWmmPsTest.reserved = 0; ++ ++ kalIoctl(prGlueInfo, ++ wlanoidSetWiFiWmmPsTest, ++ (PVOID)&rWmmPsTest, ++ sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ break; ++ ++#if 0 ++ case PRIV_CMD_ADHOC_MODE: ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetAdHocMode, ++ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(UINT_32), &u4BufLen); ++ break; ++#endif ++ ++ case PRIV_CUSTOM_BWCS_CMD: ++ ++ DBGLOG(REQ, INFO, "pu4IntBuf[1] = %x, size of PTA_IPC_T = %zu.\n", ++ pu4IntBuf[1], sizeof(PARAM_PTA_IPC_T)); ++ ++ prPtaIpc = (P_PTA_IPC_T) aucOidBuf; ++ prPtaIpc->u.aucBTPParams[0] = (UINT_8) (pu4IntBuf[1] >> 24); ++ prPtaIpc->u.aucBTPParams[1] = (UINT_8) (pu4IntBuf[1] >> 16); ++ prPtaIpc->u.aucBTPParams[2] = (UINT_8) (pu4IntBuf[1] >> 8); ++ prPtaIpc->u.aucBTPParams[3] = (UINT_8) (pu4IntBuf[1]); ++ ++ DBGLOG(REQ, INFO, ++ "BCM BWCS CMD : BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", ++ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], ++ prPtaIpc->u.aucBTPParams[3]); ++ ++#if 0 ++ status = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++#endif ++ ++ status = wlanoidSetBT(prGlueInfo->prAdapter, ++ (PVOID)&aucOidBuf[0], sizeof(PARAM_PTA_IPC_T), &u4BufLen); ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ status = -EFAULT; ++ ++ break; ++ ++ case PRIV_CMD_BAND_CONFIG: ++ { ++ DBGLOG(REQ, INFO, "CMD set_band=%u\n", (UINT_32) pu4IntBuf[1]); ++ } ++ break; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ case PRIV_CMD_P2P_MODE: ++ { ++ /* no use, move to set_p2p_mode_handler() */ ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ ++ p2pmode.u4Enable = pu4IntBuf[1]; ++ p2pmode.u4Mode = pu4IntBuf[2]; ++ set_p2p_mode_handler(prNetDev, p2pmode); ++#if 0 ++ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgIsP2PEnding; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ /* avoid remove & p2p off command simultaneously */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ fgIsP2PEnding = g_u4P2PEnding; ++ g_u4P2POnOffing = 1; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ ++ if (fgIsP2PEnding == 1) { ++ /* skip the command if we are removing */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ break; ++ } ++ rSetP2P.u4Enable = pu4IntBuf[1]; ++ rSetP2P.u4Mode = pu4IntBuf[2]; ++ ++ if (!rSetP2P.u4Enable) ++ p2pNetUnregister(prGlueInfo, TRUE); ++ ++ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ ++ /* ++ Scenario: ++ 1. System enters suspend/resume but not yet enter wlanearlysuspend() ++ or wlanlateresume(); ++ ++ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() ++ and get g_halt_sem then do glRegisterEarlySuspend() or ++ glUnregisterEarlySuspend(); ++ ++ But system suspend/resume procedure is not yet finished so we ++ suspend; ++ ++ 3. System switches back to do suspend/resume procedure and execute ++ kalIoctl(). But driver does not yet release g_halt_sem so system ++ suspend in wlanearlysuspend() or wlanlateresume(); ++ ++ ==> deadlock occurs. ++ */ ++ if ((!rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { ++ /* fgIsP2PRegistered == TRUE means P2P is enabled */ ++ DBGLOG(P2P, INFO, "p2pEalySuspendReg\n"); ++ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p remove */ ++ } ++ ++ DBGLOG(P2P, INFO, ++ "wlanoidSetP2pMode 0x%p %d %d\n", &rSetP2P, rSetP2P.u4Enable, rSetP2P.u4Mode); ++ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, ++ (PVOID)&rSetP2P, /* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), ++ FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ DBGLOG(P2P, INFO, "wlanoidSetP2pMode ok\n"); ++ ++ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ ++ if ((rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { ++ /* fgIsP2PRegistered == TRUE means P2P on successfully */ ++ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p on */ ++ } ++ ++ if (rSetP2P.u4Enable) ++ p2pNetRegister(prGlueInfo, TRUE); ++ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++#endif ++ } ++ break; ++#endif ++ ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ case PRIV_CMD_MET_PROFILING: ++ { ++ /* PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; */ ++ /* rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1]; */ ++ /* rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2]; */ ++ /* DBGLOG(REQ, INFO,("WFD Debug Mode:%d Period:%d\n", ++ rWfdDebugModeInfo.ucWFDDebugMode,rWfdDebugModeInfo.u2SNPeriod)); */ ++ prGlueInfo->u8MetProfEnable = (UINT_8) pu4IntBuf[1]; ++ prGlueInfo->u16MetUdpPort = (UINT_16) pu4IntBuf[2]; ++ DBGLOG(REQ, INFO, "MET_PROF: Enable=%d UDP_PORT=%d\n", prGlueInfo->u8MetProfEnable, ++ prGlueInfo->u16MetUdpPort); ++ ++ } ++ break; ++ ++#endif ++ case PRIV_CMD_WFD_DEBUG_CODE: ++ { ++ PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; ++ ++ rWfdDebugModeInfo.ucWFDDebugMode = (UINT_8) pu4IntBuf[1]; ++ rWfdDebugModeInfo.u2SNPeriod = (UINT_16) pu4IntBuf[2]; ++ DBGLOG(REQ, INFO, "WFD Debug Mode:%d Period:%d\n", rWfdDebugModeInfo.ucWFDDebugMode, ++ rWfdDebugModeInfo.u2SNPeriod); ++ kalIoctl(prGlueInfo, wlanoidSetWfdDebugMode, (PVOID)&rWfdDebugModeInfo, ++ sizeof(PARAM_CUSTOM_WFD_DEBUG_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ } ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl get int handler. ++* ++* \param[in] pDev Net device requested. ++* \param[out] pIwReq Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. ++* \param[out] pcExtra The buffer with put the return value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 gucBufDbgCode[1000]; ++ ++static int ++_priv_get_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ UINT_32 u4SubCmd; ++ PUINT_32 pu4IntBuf; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4BufLen = 0; ++ int status = 0; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->mode; ++ pu4IntBuf = (PUINT_32) pcExtra; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_TEST_CMD: ++ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; ++ /* ++ if (copy_to_user(prIwReqData->data.pointer, ++ &prNdisReq->ndisOidContent[4], 4)) { ++ printk(KERN_NOTICE "priv_get_int() copy_to_user oidBuf fail(3)\n"); ++ return -EFAULT; ++ } ++ */ ++ } ++ return status; ++ ++#if CFG_SUPPORT_PRIV_MCR_RW ++ case PRIV_CMD_ACCESS_MCR: ++ /* printk("addr=0x%08lx\n", pu4IntBuf[1]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (!prGlueInfo->fgMcrAccessAllowed) { ++ status = 0; ++ return status; ++ } ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; ++ } ++ return status; ++#endif ++ ++ case PRIV_CMD_DUMP_MEM: ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++#if 1 ++ if (!prGlueInfo->fgMcrAccessAllowed) { ++ status = 0; ++ return status; ++ } ++#endif ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[0]; ++ return status; ++ ++ case PRIV_CMD_SW_CTRL: ++ /* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */ ++ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; ++ } ++ return status; ++ ++#if 0 ++ case PRIV_CMD_BEACON_PERIOD: ++ status = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryBeaconInterval, ++ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); ++ return status; ++ ++ case PRIV_CMD_POWER_MODE: ++ status = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuery802dot11PowerSaveProfile, ++ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); ++ return status; ++ ++ case PRIV_CMD_ADHOC_MODE: ++ status = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryAdHocMode, (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); ++ return status; ++#endif ++ ++ case PRIV_CMD_BAND_CONFIG: ++ DBGLOG(REQ, INFO, "CMD get_band=\n"); ++ prIwReqData->mode = 0; ++ return status; ++ ++ default: ++ break; ++ } ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_GET_CH_LIST: ++ { ++ UINT_16 i, j = 0; ++ UINT_8 NumOfChannel = 50; ++ UINT_8 ucMaxChannelNum = 50; ++ INT_32 ch[50]; ++ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ ++ P_RF_CHANNEL_INFO_T paucChannelList; ++ P_RF_CHANNEL_INFO_T ChannelList_t; ++ ++ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); ++ if (paucChannelList == NULL) { ++ DBGLOG(REQ, INFO, "alloc ChannelList fail\n"); ++ return -EFAULT; ++ } ++ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); ++ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); ++ if (NumOfChannel > 50) { ++ ASSERT(0); ++ NumOfChannel = 50; ++ } ++ ++ ChannelList_t = paucChannelList; ++ if (kalIsAPmode(prGlueInfo)) { ++ for (i = 0; i < NumOfChannel; i++) { ++ if ((ChannelList_t->ucChannelNum <= 13) ++ || (ChannelList_t->ucChannelNum == 36 ++ || ChannelList_t->ucChannelNum == 40 ++ || ChannelList_t->ucChannelNum == 44 ++ || ChannelList_t->ucChannelNum == 48)) { ++ ch[j] = (INT_32) ChannelList_t->ucChannelNum; ++ ChannelList_t++; ++ j++; ++ } ++ } ++ } else { ++ for (j = 0; j < NumOfChannel; j++) { ++ ch[j] = (INT_32) ChannelList_t->ucChannelNum; ++ ChannelList_t++; ++ } ++ } ++ ++ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); ++ ++ prIwReqData->data.length = j; ++ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) ++ return -EFAULT; ++ else ++ return status; ++ } ++ ++ case PRIV_CMD_GET_BUILD_DATE_CODE: ++ { ++ UINT_8 aucBuffer[16]; ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidQueryBuildDateCode, ++ (PVOID) aucBuffer, ++ sizeof(UINT_8) * 16, TRUE, TRUE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { ++ prIwReqData->data.length = sizeof(UINT_8) * 16; ++ ++ if (copy_to_user(prIwReqData->data.pointer, aucBuffer, prIwReqData->data.length)) ++ return -EFAULT; ++ else ++ return status; ++ } else { ++ return -EFAULT; ++ } ++ } ++ ++ case PRIV_CMD_GET_DEBUG_CODE: ++ { ++ wlanQueryDebugCode(prGlueInfo->prAdapter); ++ ++ kalMemSet(gucBufDbgCode, '.', sizeof(gucBufDbgCode)); ++ if (copy_to_user(prIwReqData->data.pointer, gucBufDbgCode, prIwReqData->data.length)) ++ return -EFAULT; ++ else ++ return status; ++ } ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} /* priv_get_int */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl set int array handler. ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIwReqInfo Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. ++* \param[in] pcExtra The buffer with input value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL If a value is out of range. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ UINT_32 u4SubCmd, u4BufLen; ++ P_GLUE_INFO_T prGlueInfo; ++ int status = 0; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_SET_TXPWR_CTRL_T prTxpwr; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_SET_TX_POWER: ++ { ++ INT_32 *setting = prIwReqData->data.pointer; ++ UINT_16 i; ++ ++#if 0 ++ DBGLOG(REQ, INFO, "Tx power num = %d\n", prIwReqData->data.length); ++ ++ DBGLOG(REQ, INFO, "Tx power setting = %d %d %d %d\n", ++ setting[0], setting[1], setting[2], setting[3]); ++#endif ++ prTxpwr = &prGlueInfo->rTxPwr; ++ if (setting[0] == 0 && prIwReqData->data.length == 4 /* argc num */) { ++ /* 0 (All networks), 1 (legacy STA), 2 (Hotspot AP), 3 (P2P), 4 (BT over Wi-Fi) */ ++ if (setting[1] == 1 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GLegacyStaPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GLegacyStaPwrOffset = setting[3]; ++ } ++ if (setting[1] == 2 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GHotspotPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GHotspotPwrOffset = setting[3]; ++ } ++ if (setting[1] == 3 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GP2pPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GP2pPwrOffset = setting[3]; ++ } ++ if (setting[1] == 4 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GBowPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GBowPwrOffset = setting[3]; ++ } ++ } else if (setting[0] == 1 && prIwReqData->data.length == 2) { ++ prTxpwr->ucConcurrencePolicy = setting[1]; ++ } else if (setting[0] == 2 && prIwReqData->data.length == 3) { ++ if (setting[1] == 0) { ++ for (i = 0; i < 14; i++) ++ prTxpwr->acTxPwrLimit2G[i] = setting[2]; ++ } else if (setting[1] <= 14) ++ prTxpwr->acTxPwrLimit2G[setting[1] - 1] = setting[2]; ++ } else if (setting[0] == 3 && prIwReqData->data.length == 3) { ++ if (setting[1] == 0) { ++ for (i = 0; i < 4; i++) ++ prTxpwr->acTxPwrLimit5G[i] = setting[2]; ++ } else if (setting[1] <= 4) ++ prTxpwr->acTxPwrLimit5G[setting[1] - 1] = setting[2]; ++ } else if (setting[0] == 4 && prIwReqData->data.length == 2) { ++ if (setting[1] == 0) ++ wlanDefTxPowerCfg(prGlueInfo->prAdapter); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetTxPower, ++ prTxpwr, ++ sizeof(SET_TXPWR_CTRL_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ } else ++ return -EFAULT; ++ } ++ return status; ++ default: ++ break; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl get int array handler. ++* ++* \param[in] pDev Net device requested. ++* \param[out] pIwReq Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. ++* \param[out] pcExtra The buffer with put the return value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_get_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ UINT_32 u4SubCmd; ++ P_GLUE_INFO_T prGlueInfo; ++ int status = 0; ++ INT_32 ch[50]; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_GET_CH_LIST: ++ { ++ UINT_16 i; ++ UINT_8 NumOfChannel = 50; ++ UINT_8 ucMaxChannelNum = 50; ++ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ ++ P_RF_CHANNEL_INFO_T paucChannelList; ++ P_RF_CHANNEL_INFO_T ChannelList_t; ++ ++ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); ++ if (paucChannelList == NULL) { ++ DBGLOG(REQ, INFO, "alloc fail\n"); ++ return -EINVAL; ++ } ++ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); ++ ++ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); ++ if (NumOfChannel > 50) ++ NumOfChannel = 50; ++ ++ ChannelList_t = paucChannelList; ++ for (i = 0; i < NumOfChannel; i++) { ++ ch[i] = (INT_32) ChannelList_t->ucChannelNum; ++ ChannelList_t++; ++ } ++ ++ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); ++ prIwReqData->data.length = NumOfChannel; ++ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) ++ return -EFAULT; ++ else ++ return status; ++ } ++ default: ++ break; ++ } ++ ++ return status; ++} /* priv_get_int */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl set structure handler. ++* ++* \param[in] pDev Net device requested. ++* \param[in] prIwReqData Pointer to iwreq_data structure. ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL If a value is out of range. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ UINT_32 u4SubCmd = 0; ++ int status = 0; ++ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ ++ UINT_32 u4CmdLen = 0; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq; ++ PUINT_32 pu4IntBuf = NULL; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ /* ASSERT(prIwReqInfo); */ ++ ASSERT(prIwReqData); ++ /* ASSERT(pcExtra); */ ++ ++ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); ++ ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++#if 0 ++ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", ++ prIwReqInfo->cmd, u4SubCmd); ++#endif ++ ++ switch (u4SubCmd) { ++#if 0 /* PTA_ENABLED */ ++ case PRIV_CMD_BT_COEXIST: ++ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); ++ ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen); ++ if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) ++ return -EFAULT; ++ ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { ++ status = -EFAULT; /* return -EFAULT; */ ++ break; ++ } ++ ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBtCoexistCtrl, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++ if (WLAN_STATUS_SUCCESS != rStatus) ++ status = -EFAULT; ++ break; ++#endif ++ ++ case PRIV_CUSTOM_BWCS_CMD: ++ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); ++ ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen); ++ if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen) ++ return -EFAULT; ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(REQ, INFO, ++ "ucCmdLen = %d, size of PTA_IPC_T = %d, prIwReqData->data = 0x%x.\n", u4CmdLen, ++ sizeof(PARAM_PTA_IPC_T), prIwReqData->data); ++ ++ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%u)\n", ++ prIwReqInfo->cmd, u4SubCmd); ++ ++ DBGLOG(REQ, INFO, "*pcExtra = 0x%x\n", *pcExtra); ++#endif ++ ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { ++ status = -EFAULT; /* return -EFAULT; */ ++ break; ++ } ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(REQ, INFO, "priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n", ++ aucOidBuf[2], aucOidBuf[3], aucOidBuf[4], aucOidBuf[5]); ++#endif ++ ++#if 0 ++ status = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++#endif ++ ++#if 1 ++ status = wlanoidSetBT(prGlueInfo->prAdapter, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++#endif ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ status = -EFAULT; ++ ++ break; ++ ++#if CFG_SUPPORT_WPS2 ++ case PRIV_CMD_WSC_PROBE_REQ: ++ { ++ /* retrieve IE for Probe Request */ ++ if (prIwReqData->data.length > 0) { ++ if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer, ++ prIwReqData->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ prGlueInfo->u2WSCIELen = prIwReqData->data.length; ++ } else { ++ prGlueInfo->u2WSCIELen = 0; ++ } ++ } ++ break; ++#endif ++ case PRIV_CMD_OID: ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) ++ DBGLOG(REQ, INFO, "pcExtra buffer is valid\n"); ++ else ++ DBGLOG(REQ, INFO, "pcExtra 0x%p\n", pcExtra); ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0], &u4BufLen); ++ /* Copy result to user space */ ++ ((P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0])->outNdisOidLength = u4BufLen; ++ ++ if (copy_to_user(prIwReqData->data.pointer, ++ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { ++ DBGLOG(REQ, INFO, "copy_to_user oidBuf fail\n"); ++ status = -EFAULT; ++ } ++ ++ break; ++ ++ case PRIV_CMD_SW_CTRL: ++ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ /* kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); */ ++ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, ++ prIwReqData->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl get struct handler. ++* ++* \param[in] pDev Net device requested. ++* \param[out] pIwReq Pointer to iwreq structure. ++* \param[in] cmd Private sub-command. ++* ++* \retval 0 For success. ++* \retval -EFAULT If copy from user space buffer fail. ++* \retval -EOPNOTSUPP Parameter "cmd" not recognized. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_get_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ UINT_32 u4SubCmd = 0; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq = NULL; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4BufLen = 0; ++ PUINT_32 pu4IntBuf = NULL; ++ int status = 0; ++ ++ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqData); ++ if (!prNetDev || !prIwReqData) { ++ DBGLOG(REQ, INFO, "priv_get_struct(): invalid param(0x%p, 0x%p)\n", prNetDev, prIwReqData); ++ return -EINVAL; ++ } ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) { ++ DBGLOG(REQ, INFO, "priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n", ++ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); ++ return -EINVAL; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", ++ prIwReqInfo->cmd, u4SubCmd); ++#endif ++ memset(aucOidBuf, 0, sizeof(aucOidBuf)); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_OID: ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, sizeof(NDIS_TRANSPORT_STRUCT))) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); ++ return -EFAULT; ++ } ++ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++#if 0 ++ DBGLOG(REQ, INFO, "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n", ++ cmd, pIwReq->u.data.length, ndisReq->ndisOidCmd, ndisReq->inNdisOidlength); ++#endif ++ if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) { ++ prNdisReq->outNdisOidLength = u4BufLen; ++ if (copy_to_user(prIwReqData->data.pointer, ++ &aucOidBuf[0], ++ u4BufLen + sizeof(NDIS_TRANSPORT_STRUCT) - ++ sizeof(prNdisReq->ndisOidContent))) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(1)\n"); ++ return -EFAULT; ++ } ++ return 0; ++ } ++ prNdisReq->outNdisOidLength = u4BufLen; ++ if (copy_to_user(prIwReqData->data.pointer, ++ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); ++ } ++ return -EFAULT; ++ ++ case PRIV_CMD_SW_CTRL: ++ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, ++ prIwReqData->data.length)) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); ++ return -EFAULT; ++ } ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ prNdisReq->outNdisOidLength = u4BufLen; ++ /* printk("len=%d Result=%08lx\n", u4BufLen, *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ ++ if (copy_to_user(prIwReqData->data.pointer, ++ &prNdisReq->ndisOidContent[4], ++ 4 /* OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent) */)) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); ++ } ++ } ++ return 0; ++ ++ default: ++ DBGLOG(REQ, WARN, "get struct cmd:0x%x\n", u4SubCmd); ++ return -EOPNOTSUPP; ++ } ++} /* priv_get_struct */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The routine handles a set operation for a single OID. ++* ++* \param[in] pDev Net device requested. ++* \param[in] ndisReq Ndis request OID information copy from user. ++* \param[out] outputLen_p If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed.. ++* ++* \retval 0 On success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) ++{ ++ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prNdisReq); ++ ASSERT(pu4OutputLen); ++ ++ if (!prNetDev || !prNdisReq || !pu4OutputLen) { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", ++ prNetDev, prNdisReq, pu4OutputLen); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", ++ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); ++ return -EINVAL; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); ++#endif ++ ++ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { ++ /* WARNLOG(("Set OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ ++ return -EOPNOTSUPP; ++ } ++ ++ if (NULL == prWlanReqEntry->pfOidSetHandler) { ++ /* WARNLOG(("Set %s: Null set handler\n", prWlanReqEntry->pucOidName)); */ ++ return -EOPNOTSUPP; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_set_ndis(): %s\n", prWlanReqEntry->pucOidName); ++#endif ++ ++ if (prWlanReqEntry->fgSetBufLenChecking) { ++ if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) { ++ DBGLOG(REQ, WARN, "Set %s: Invalid length (current=%u, needed=%u)\n", ++ prWlanReqEntry->pucOidName, ++ prNdisReq->inNdisOidlength, prWlanReqEntry->u4InfoBufLen); ++ ++ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; ++ return -EINVAL; ++ } ++ } ++ ++ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { ++ /* GLUE sw info only */ ++ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4SetInfoLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { ++ /* multiple sw operations */ ++ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4SetInfoLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { ++ /* driver core */ ++ ++ status = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } else { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); ++ return -EOPNOTSUPP; ++ } ++ ++ *pu4OutputLen = u4SetInfoLen; ++ ++ switch (status) { ++ case WLAN_STATUS_SUCCESS: ++ break; ++ ++ case WLAN_STATUS_INVALID_LENGTH: ++ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ ++ /* prWlanReqEntry->pucOidName, */ ++ /* prNdisReq->inNdisOidlength, */ ++ /* u4SetInfoLen)); */ ++ break; ++ } ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ return -EFAULT; ++ ++ return 0; ++} /* priv_set_ndis */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The routine handles a query operation for a single OID. Basically we ++* return information about the current state of the OID in question. ++* ++* \param[in] pDev Net device requested. ++* \param[in] ndisReq Ndis request OID information copy from user. ++* \param[out] outputLen_p If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed.. ++* ++* \retval 0 On success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL invalid input parameters ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) ++{ ++ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; ++ UINT_32 u4BufLen = 0; ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prNetDev); ++ ASSERT(prNdisReq); ++ ASSERT(pu4OutputLen); ++ ++ if (!prNetDev || !prNdisReq || !pu4OutputLen) { ++ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", ++ prNetDev, prNdisReq, pu4OutputLen); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) { ++ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", ++ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); ++ return -EINVAL; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); ++#endif ++ ++ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { ++ /* WARNLOG(("Query OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ ++ return -EOPNOTSUPP; ++ } ++ ++ if (NULL == prWlanReqEntry->pfOidQueryHandler) { ++ /* WARNLOG(("Query %s: Null query handler\n", prWlanReqEntry->pucOidName)); */ ++ return -EOPNOTSUPP; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_get_ndis(): %s\n", prWlanReqEntry->pucOidName); ++#endif ++ ++ if (prWlanReqEntry->fgQryBufLenChecking) { ++ if (prNdisReq->inNdisOidlength < prWlanReqEntry->u4InfoBufLen) { ++ /* Not enough room in InformationBuffer. Punt */ ++ /* WARNLOG(("Query %s: Buffer too short (current=%ld, needed=%ld)\n", */ ++ /* prWlanReqEntry->pucOidName, */ ++ /* prNdisReq->inNdisOidlength, */ ++ /* prWlanReqEntry->u4InfoBufLen)); */ ++ ++ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; ++ ++ status = WLAN_STATUS_INVALID_LENGTH; ++ return -EINVAL; ++ } ++ } ++ ++ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { ++ /* GLUE sw info only */ ++ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4BufLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { ++ /* multiple sw operations */ ++ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4BufLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { ++ /* driver core */ ++ ++ status = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidQueryHandler, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ } else { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); ++ return -EOPNOTSUPP; ++ } ++ ++ *pu4OutputLen = u4BufLen; ++ ++ switch (status) { ++ case WLAN_STATUS_SUCCESS: ++ break; ++ ++ case WLAN_STATUS_INVALID_LENGTH: ++ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ ++ /* prWlanReqEntry->pucOidName, */ ++ /* prNdisReq->inNdisOidlength, */ ++ /* u4BufLen)); */ ++ break; ++ } ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ return -EOPNOTSUPP; ++ ++ return 0; ++} /* priv_get_ndis */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse command value in a string. ++* ++* @param InStr Pointer to the string buffer. ++* @param OutStr Pointer to the next command value. ++* @param OutLen Record the resident buffer length. ++* ++* @retval Command value. ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen) ++{ ++ unsigned char Charc, *Buf; ++ unsigned int Num; ++ int Maxloop; ++ int ReadId; ++ int TotalLen; ++ ++ /* init */ ++ Num = 0; ++ Maxloop = 0; ++ ReadId = 0; ++ Buf = (unsigned char *)InStr; ++ TotalLen = *OutLen; ++ *OutStr = Buf; ++ ++ /* sanity check */ ++ if (Buf[0] == 0x00) ++ return 0; ++ ++ /* check the value is decimal or hex */ ++ if ((Buf[ReadId] == 'x') || ((Buf[ReadId] == '0') && (Buf[ReadId + 1] == 'x'))) { ++ /* skip x or 0x */ ++ if (Buf[ReadId] == 'x') ++ ReadId++; ++ else ++ ReadId += 2; ++ ++ /* translate the hex number */ ++ while (Maxloop++ < 10) { ++ Charc = Buf[ReadId]; ++ if ((Charc >= 0x30) && (Charc <= 0x39)) ++ Charc -= 0x30; ++ else if ((Charc >= 'a') && (Charc <= 'f')) ++ Charc -= 'a'; ++ else if ((Charc >= 'A') && (Charc <= 'F')) ++ Charc -= 'A'; ++ else ++ break; /* exit the parsing */ ++ Num = Num * 16 + Charc + 10; ++ ReadId++; ++ TotalLen--; ++ } ++ } else { ++ /* translate the decimal number */ ++ while (Maxloop++ < 10) { ++ Charc = Buf[ReadId]; ++ if ((Charc < 0x30) || (Charc > 0x39)) ++ break; /* exit the parsing */ ++ Charc -= 0x30; ++ Num = Num * 10 + Charc; ++ ReadId++; ++ TotalLen--; ++ } ++ } ++ ++ if (Buf[ReadId] == 0x00) ++ *OutStr = &Buf[ReadId]; ++ else ++ *OutStr = &Buf[ReadId + 1]; /* skip the character: _ */ ++ ++ *OutLen = TotalLen - 1; /* skip the character: _ */ ++ return Num; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse command MAC address in a string. ++* ++* @param InStr Pointer to the string buffer. ++* @param OutStr Pointer to the next command value. ++* @param OutLen Record the resident buffer length. ++* ++* @retval Command value. ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac) ++{ ++ unsigned char Charc, *Buf; ++ unsigned int Num; ++ int Maxloop; ++ int ReadId; ++ int TotalLen; ++ ++ /* init */ ++ Num = 0; ++ Maxloop = 0; ++ ReadId = 0; ++ Buf = (unsigned char *)InStr; ++ TotalLen = *OutLen; ++ *OutStr = Buf; ++ ++ /* sanity check */ ++ if (Buf[0] == 0x00) ++ return 0; ++ ++ /* parse MAC */ ++ while (Maxloop < 6) { ++ Charc = Buf[ReadId]; ++ if ((Charc >= 0x30) && (Charc <= 0x39)) ++ Charc -= 0x30; ++ else if ((Charc >= 'a') && (Charc <= 'f')) ++ Charc = Charc - 'a' + 10; ++ else if ((Charc >= 'A') && (Charc <= 'F')) ++ Charc = Charc - 'A' + 10; ++ else ++ return -1; /* error, exit the parsing */ ++ ++ Num = Charc; ++ ReadId++; ++ TotalLen--; ++ ++ Charc = Buf[ReadId]; ++ if ((Charc >= 0x30) && (Charc <= 0x39)) ++ Charc -= 0x30; ++ else if ((Charc >= 'a') && (Charc <= 'f')) ++ Charc = Charc - 'a' + 10; ++ else if ((Charc >= 'A') && (Charc <= 'F')) ++ Charc = Charc - 'A' + 10; ++ else ++ return -1; /* error, exit the parsing */ ++ ++ Num = Num * 16 + Charc; ++ ReadId += 2; /* skip the character and ':' */ ++ TotalLen -= 2; ++ ++ OutMac[Maxloop] = Num; ++ Maxloop++; ++ } ++ ++ *OutStr = &Buf[ReadId]; /* skip the character: _ */ ++ *OutLen = TotalLen; /* skip the character: _ */ ++ return Num; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The routine handles a set operation for a single OID. ++* ++* \param[in] pDev Net device requested. ++* \param[in] ndisReq Ndis request OID information copy from user. ++* \param[out] outputLen_p If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed.. ++* ++* \retval 0 On success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_string(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T GlueInfo; ++ INT_32 Status; ++ UINT_32 Subcmd; ++ UINT_8 *InBuf; ++ UINT_32 InBufLen; ++ ++ /* sanity check */ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ ++ /* init */ ++ DBGLOG(REQ, INFO, "priv_set_string (%s)(%d)\n", ++ (UINT8 *) prIwReqData->data.pointer, (INT32) prIwReqData->data.length); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ InBuf = aucOidBuf; ++ InBufLen = prIwReqData->data.length; ++ Status = 0; ++ ++ if (copy_from_user(InBuf, prIwReqData->data.pointer, prIwReqData->data.length)) ++ return -EFAULT; ++ ++ Subcmd = CmdStringDecParse(prIwReqData->data.pointer, &InBuf, &InBufLen); ++ DBGLOG(REQ, INFO, "priv_set_string> command = %u\n", (UINT32) Subcmd); ++ ++ /* handle the command */ ++ switch (Subcmd) { ++#if (CFG_SUPPORT_TDLS == 1) ++ case PRIV_CMD_OTHER_TDLS: ++ TdlsexCmd(GlueInfo, InBuf, InBufLen); ++ break; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++ case PRIV_CMD_OTHER_TAR: ++ { ++ rlmCmd(GlueInfo, InBuf, InBufLen); ++ break; ++ } ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ default: ++ break; ++ } ++ ++ return Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to search desired OID. ++* ++* \param rOid[in] Desired NDIS_OID ++* \param ppWlanReqEntry[out] Found registered OID entry ++* ++* \retval TRUE: Matched OID is found ++* \retval FALSE: No matched OID is found ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY *ppWlanReqEntry) ++{ ++ INT_32 i, j, k; ++ ++ i = 0; ++ j = NUM_SUPPORTED_OIDS - 1; ++ ++ while (i <= j) { ++ k = (i + j) / 2; ++ ++ if (rOid == arWlanOidReqTable[k].rOid) { ++ *ppWlanReqEntry = &arWlanOidReqTable[k]; ++ return TRUE; ++ } else if (rOid < arWlanOidReqTable[k].rOid) { ++ j = k - 1; ++ } else { ++ i = k + 1; ++ } ++ } ++ ++ return FALSE; ++} /* reqSearchSupportedOidEntry */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the radio configuration used in IBSS ++* mode and RF test mode. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[out] pvQueryBuffer Pointer to the buffer that holds the result of the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_802_11_CONFIG_T prQueryConfig = (P_PARAM_802_11_CONFIG_T) pvQueryBuffer; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ ++ DEBUGFUNC("wlanoidQueryConfiguration"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_CONFIG_T); ++ if (u4QueryBufferLen < sizeof(PARAM_802_11_CONFIG_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvQueryBuffer); ++ ++ kalMemZero(prQueryConfig, sizeof(PARAM_802_11_CONFIG_T)); ++ ++ /* Update the current radio configuration. */ ++ prQueryConfig->u4Length = sizeof(PARAM_802_11_CONFIG_T); ++ ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetBeaconInterval, ++ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryBeaconInterval, ++ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), &u4QueryInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidQueryAtimWindow, ++ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryAtimWindow, ++ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), &u4QueryInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidQueryFrequency, ++ &prQueryConfig->u4DSConfig, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryFrequency, ++ &prQueryConfig->u4DSConfig, sizeof(UINT_32), &u4QueryInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++ ++ prQueryConfig->rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); ++ ++ return rStatus; ++ ++} /* end of reqExtQueryConfiguration() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the radio configuration used in IBSS ++* mode. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_802_11_CONFIG_T prNewConfig = (P_PARAM_802_11_CONFIG_T) pvSetBuffer; ++ UINT_32 u4SetInfoLen = 0; ++ ++ DEBUGFUNC("wlanoidSetConfiguration"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_802_11_CONFIG_T); ++ ++ if (u4SetBufferLen < *pu4SetInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be returned. */ ++ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ ++ ASSERT(pvSetBuffer); ++ ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetBeaconInterval, ++ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); ++#else ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBeaconInterval, ++ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), &u4SetInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetAtimWindow, ++ &prNewConfig->u4ATIMWindow, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); ++#else ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetAtimWindow, &prNewConfig->u4ATIMWindow, sizeof(UINT_32), &u4SetInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetFrequency, ++ &prNewConfig->u4DSConfig, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); ++#else ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetFrequency, &prNewConfig->u4DSConfig, sizeof(UINT_32), &u4SetInfoLen); ++#endif ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++ ++ return rStatus; ++ ++} /* end of reqExtSetConfiguration() */ ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set beacon detection function enable/disable state ++* This is mainly designed for usage under BT inquiry state (disable function). ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ /* WIFI is enabled, when ACPI is D0 (ParamDeviceStateD0 = 1). And vice versa */ ++ ++ /* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */ ++ /* wlanoidSetAcpiDevicePowerState, */ ++ /* pvSetBuffer, */ ++ /* u4SetBufferLen, */ ++ /* pu4SetInfoLen); */ ++ return rStatus; ++} ++ ++int priv_driver_set_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ UINT_32 u4BufLen = 0; ++ INT_32 i4BytesWritten = 0; ++ UINT_32 u4CmdLen = 0; ++ UINT_32 u4PrefixLen = 0; ++ /* INT_32 i4Argc = 0; */ ++ /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */ ++ ++ PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T rChipConfigInfo; ++ ++ ASSERT(prNetDev); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) ++ return -1; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ prAdapter = prGlueInfo->prAdapter; ++ DBGLOG(REQ, INFO, "priv_driver_set_chip_config command is %s\n", pcCommand); ++ /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */ ++ /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */ ++ /* */ ++ u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); ++ u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */; ++ ++ kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); ++ ++ /* if(i4Argc >= 2) { */ ++ if (u4CmdLen > u4PrefixLen) { ++ ++ rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; ++ /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ ++ rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen; ++ /* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ ++ if (u4PrefixLen <= CHIP_CONFIG_RESP_SIZE) { ++ kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, ++ CHIP_CONFIG_RESP_SIZE - u4PrefixLen); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetChipConfig, ++ &rChipConfigInfo, ++ sizeof(rChipConfigInfo), FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ } else { ++ ++ DBGLOG(REQ, INFO, "%s: kalIoctl Command Len > %d\n", __func__, CHIP_CONFIG_RESP_SIZE); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, rStatus); ++ i4BytesWritten = -1; ++ } ++ } ++ ++ return i4BytesWritten; ++ ++} ++ ++int priv_driver_set_miracast(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 i4BytesWritten = 0; ++ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ ++ /* UINT_32 u4BufLen = 0; */ ++ INT_32 i4Argc = 0; ++ UINT_32 ucMode = 0; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; ++ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; ++ INT_32 u4Ret; ++ ++ ASSERT(prNetDev); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) ++ return -1; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); ++ wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); ++ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ if (i4Argc >= 2) { ++ u4Ret = kalkStrtou32(apcArgv[1], 0, &ucMode); /* ucMode = kalStrtoul(apcArgv[1], NULL, 0); */ ++ if (u4Ret) ++ DBGLOG(REQ, LOUD, "parse pcCommand error u4Ret=%d\n", u4Ret); ++ ++ if (g_ucMiracastMode == ucMode) ++ ; ++ /* XXX: continue or skip */ ++ ++ g_ucMiracastMode = ucMode; ++ prMsgWfdCfgUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); ++ ++ if (prMsgWfdCfgUpdate != NULL) { ++ ++ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; ++ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; ++ ++ if (ucMode == MIRACAST_MODE_OFF) { ++ prWfdCfgSettings->ucWfdEnable = 0; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); ++ } else if (ucMode == MIRACAST_MODE_SOURCE) { ++ prWfdCfgSettings->ucWfdEnable = 1; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 1"); ++ } else if (ucMode == MIRACAST_MODE_SINK) { ++ prWfdCfgSettings->ucWfdEnable = 2; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 2"); ++ } else { ++ prWfdCfgSettings->ucWfdEnable = 0; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); ++ } ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); ++ ++ priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); ++ ++ } /* prMsgWfdCfgUpdate */ ++ else { ++ ASSERT(FALSE); ++ i4BytesWritten = -1; ++ } ++ } ++ ++ /* i4Argc */ ++ return i4BytesWritten; ++} ++ ++int priv_support_driver_cmd(IN struct net_device *prNetDev, IN OUT struct ifreq *prReq, IN int i4Cmd) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ int ret = 0; ++ char *pcCommand = NULL; ++ priv_driver_cmd_t *priv_cmd = NULL; ++ int i4BytesWritten = 0; ++ int i4TotalLen = 0; ++ ++ if (!prReq->ifr_data) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (!prGlueInfo) { ++ DBGLOG(REQ, WARN, "No glue info\n"); ++ ret = -EFAULT; ++ goto exit; ++ } ++ if (prGlueInfo->u4ReadyFlag == 0) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ priv_cmd = kzalloc(sizeof(priv_driver_cmd_t), GFP_KERNEL); ++ if (!priv_cmd) { ++ DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(priv_cmd, prReq->ifr_data, sizeof(priv_driver_cmd_t))) { ++ DBGLOG(REQ, INFO, "%s: copy_from_user fail\n", __func__); ++ ret = -EFAULT; ++ goto exit; ++ } ++ ++ i4TotalLen = priv_cmd->total_len; ++ ++ if (i4TotalLen <= 0) { ++ ret = -EINVAL; ++ DBGLOG(REQ, INFO, "%s: i4TotalLen invalid\n", __func__); ++ goto exit; ++ } ++ ++ pcCommand = priv_cmd->buf; ++ ++ DBGLOG(REQ, INFO, "%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, prReq->ifr_name); ++ ++ i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen); ++ ++ if (i4BytesWritten < 0) { ++ DBGLOG(REQ, INFO, "%s: command %s failed; Written is %d\n", ++ __func__, pcCommand, i4BytesWritten); ++ ret = -EFAULT; ++ } ++ ++exit: ++ kfree(priv_cmd); ++ ++ return ret; ++} ++ ++#if CFG_SUPPORT_BATCH_SCAN ++#define CMD_BATCH_SET "WLS_BATCHING SET" ++#define CMD_BATCH_GET "WLS_BATCHING GET" ++#define CMD_BATCH_STOP "WLS_BATCHING STOP" ++#endif ++ ++#if CFG_SUPPORT_GET_CH_ENV ++#define CMD_CH_ENV_GET "CH_ENV_GET" ++#endif ++ ++INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4BytesWritten = 0; ++ INT_32 i4CmdFound = 0; ++ ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) ++ return -1; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (i4CmdFound == 0) { ++ i4CmdFound = 1; ++ ++ if (strnicmp(pcCommand, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) ++ i4BytesWritten = priv_driver_set_miracast(prNetDev, pcCommand, i4TotalLen); ++#if CFG_SUPPORT_BATCH_SCAN ++ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); ++ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { ++ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ ++ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ ++ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ ++ ++ UINT_32 u4BufLen; ++ int i; ++ /* int rlen=0; */ ++ ++ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { ++ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ ++ kalIoctl(prGlueInfo, ++ wlanoidQueryBatchScanResult, ++ (PVOID)&g_rEventBatchResult[i], ++ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ } ++ ++#if 0 ++ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); ++ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { ++ prEntry = &g_rEventBatchResult.arBatchResult[i]; ++ DBGLOG(SCN, INFO, "Entry %u\n", i); ++ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); ++ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); ++ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); ++ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); ++ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); ++ } ++#endif ++ ++ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); ++ ++ /* Dump for debug */ ++ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, ++ i4BytesWritten, TRUE); */ ++ ++ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); ++ } ++#endif ++#if CFG_SUPPORT_GET_CH_ENV ++ else if (strnicmp(pcCommand, CMD_CH_ENV_GET, strlen(CMD_CH_ENV_GET)) == 0) ++ scanEnvResult(prGlueInfo, pcCommand, i4TotalLen, &i4BytesWritten); ++#endif ++ ++#if 0 ++ ++ else if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) { ++ /* i4BytesWritten = wl_android_get_rssi(net, command, i4TotalLen); */ ++ } else if (strnicmp(pcCommand, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { ++ i4BytesWritten = priv_driver_get_linkspeed(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { ++ /* Do nothing */ ++ } else if (strnicmp(pcCommand, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { ++ /* Do nothing */ ++ } else if (strnicmp(pcCommand, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { ++ /* Do nothing */ ++ } else if (strnicmp(pcCommand, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { ++ /* i4BytesWritten = wl_android_set_suspendopt(net, pcCommand, i4TotalLen); */ ++ } else if (strnicmp(pcCommand, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { ++ i4BytesWritten = priv_driver_set_suspend_mode(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { ++ i4BytesWritten = priv_driver_set_band(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { ++ /* i4BytesWritten = wl_android_get_band(net, pcCommand, i4TotalLen); */ ++ } else if (strnicmp(pcCommand, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { ++ i4BytesWritten = priv_driver_set_country(prNetDev, pcCommand, i4TotalLen); ++ } ++ /* Mediatek private command */ ++ else if (strnicmp(pcCommand, CMD_SET_SW_CTRL, strlen(CMD_SET_SW_CTRL)) == 0) { ++ i4BytesWritten = priv_driver_set_sw_ctrl(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_SW_CTRL, strlen(CMD_GET_SW_CTRL)) == 0) { ++ i4BytesWritten = priv_driver_get_sw_ctrl(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SET_CFG, strlen(CMD_SET_CFG)) == 0) { ++ i4BytesWritten = priv_driver_set_cfg(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_CFG, strlen(CMD_GET_CFG)) == 0) { ++ i4BytesWritten = priv_driver_get_cfg(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SET_CHIP, strlen(CMD_SET_CHIP)) == 0) { ++ i4BytesWritten = priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_CHIP, strlen(CMD_GET_CHIP)) == 0) { ++ i4BytesWritten = priv_driver_get_chip_config(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SET_DBG_LEVEL, strlen(CMD_SET_DBG_LEVEL)) == 0) { ++ i4BytesWritten = priv_driver_set_dbg_level(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_DBG_LEVEL, strlen(CMD_GET_DBG_LEVEL)) == 0) { ++ i4BytesWritten = priv_driver_get_dbg_level(prNetDev, pcCommand, i4TotalLen); ++ } ++#if CFG_SUPPORT_BATCH_SCAN ++ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); ++ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { ++ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ ++ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ ++ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ ++ ++ UINT_32 u4BufLen; ++ int i; ++ /* int rlen=0; */ ++ ++ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { ++ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ ++ kalIoctl(prGlueInfo, ++ wlanoidQueryBatchScanResult, ++ (PVOID)&g_rEventBatchResult[i], ++ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, &u4BufLen); ++ } ++ ++#if 0 ++ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); ++ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { ++ prEntry = &g_rEventBatchResult.arBatchResult[i]; ++ DBGLOG(SCN, INFO, "Entry %u\n", i); ++ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); ++ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); ++ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); ++ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); ++ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); ++ } ++#endif ++ ++ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); ++ ++ /* Dump for debug */ ++ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, i4BytesWritten, ++ TRUE); */ ++ ++ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); ++ } ++#endif ++ ++#endif ++ ++ else ++ i4CmdFound = 0; ++ } ++ ++ /* i4CmdFound */ ++ if (i4CmdFound == 0) ++ DBGLOG(REQ, TRACE, "Unknown driver command %s - ignored\n", pcCommand); ++ ++ if (i4BytesWritten >= 0) { ++ if ((i4BytesWritten == 0) && (i4TotalLen > 0)) { ++ /* reset the command buffer */ ++ pcCommand[0] = '\0'; ++ } ++ ++ if (i4BytesWritten >= i4TotalLen) { ++ DBGLOG(REQ, INFO, ++ "%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__, i4BytesWritten, i4TotalLen); ++ i4BytesWritten = i4TotalLen; ++ } else { ++ pcCommand[i4BytesWritten] = '\0'; ++ i4BytesWritten++; ++ } ++ } ++ ++ return i4BytesWritten; ++ ++} ++ ++static int compat_priv(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra, ++ int (*priv_func)(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)) ++{ ++ struct iw_point *prIwp; ++ int ret = 0; ++#ifdef CONFIG_COMPAT ++ struct compat_iw_point *iwp_compat = NULL; ++ struct iw_point iwp; ++#endif ++ ++ if (!prIwReqData) ++ return -EINVAL; ++ ++#ifdef CONFIG_COMPAT ++ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { ++ iwp_compat = (struct compat_iw_point *) &prIwReqData->data; ++ iwp.pointer = compat_ptr(iwp_compat->pointer); ++ iwp.length = iwp_compat->length; ++ iwp.flags = iwp_compat->flags; ++ prIwp = &iwp; ++ } else ++#endif ++ prIwp = &prIwReqData->data; ++ ++ ++ ret = priv_func(prNetDev, prIwReqInfo, (union iwreq_data *)prIwp, pcExtra); ++ ++#ifdef CONFIG_COMPAT ++ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { ++ iwp_compat->pointer = ptr_to_compat(iwp.pointer); ++ iwp_compat->length = iwp.length; ++ iwp_compat->flags = iwp.flags; ++ } ++#endif ++ return ret; ++} ++ ++int ++priv_set_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_int); ++} ++ ++int ++priv_get_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_int); ++} ++ ++int ++priv_set_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_ints); ++} ++ ++int ++priv_get_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_ints); ++} ++ ++int ++priv_set_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_struct); ++} ++ ++int ++priv_get_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_struct); ++} ++ ++int ++priv_set_string(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_string); ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c +new file mode 100644 +index 000000000000..c13d24906bf8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c +@@ -0,0 +1,1643 @@ ++/****************************************************************************** ++*[File] ahb.c ++*[Version] v1.0 ++*[Revision Date] 2013-01-16 ++*[Author] ++*[Description] ++* The program provides AHB HIF driver ++*[Copyright] ++* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. ++******************************************************************************/ ++ ++/* ++** Log: ahb.c ++ * ++ * 01 16 2013 vend_samp.lin ++ * Port sdio.c to ahb.c on MT6572/MT6582 ++ * 1) Initial version ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ * ++ * 02 14 2012 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * include correct header file upon setting. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 09 20 2011 cp.wu ++ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized ++ * 1. always show error message for SDIO bus errors. ++ * 2. reset bus error flag when re-initialization ++ * ++ * 08 17 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628 related definitions for Linux/Android driver. ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add device ID for MT5931. ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 11 15 2010 jeffrey.chang ++ * [WCXRP00000181] [MT6620 Wi-Fi][Driver] fix the driver message "GLUE_FLAG_HALT skip INT" during unloading ++ * Fix GLUE_FALG_HALT message which cause driver to hang ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * correct typo ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 19 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK ++ * HIF by default ++ * Refine linux kernel module to the license of MTK and enable MTK HIF ++ * ++ * 08 21 2010 jeffrey.chang ++ * NULL ++ * 1) add sdio two setting ++ * 2) bug fix of sdio glue ++ * ++ * 08 18 2010 jeffrey.chang ++ * NULL ++ * support multi-function sdio ++ * ++ * 08 18 2010 cp.wu ++ * NULL ++ * #if defined(__X86__) is not working, change to use #ifdef CONFIG_X86. ++ * ++ * 08 17 2010 cp.wu ++ * NULL ++ * add ENE SDIO host workaround for x86 linux platform. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Fix hotplug bug ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * clear sdio interrupt ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++/* #include */ ++#include ++/* #include */ ++#include ++/* #include */ ++/* #include */ ++/* #include */ ++ ++#include ++#ifndef CONFIG_X86 ++#include ++#endif ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#else ++ ++#endif ++ ++/* #include ++#include */ ++ ++#include "gl_os.h" ++ ++#if defined(MT6620) ++#include "mt6620_reg.h" ++#elif defined(MT6628) ++#include "mtreg.h" ++#endif ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++#include ++#endif ++ ++/* #define MTK_DMA_BUF_MEMCPY_SUP */ /* no virt_to_phys() use */ ++/* #define HIF_DEBUG_SUP */ ++/* #define HIF_DEBUG_SUP_TX */ ++ ++#ifdef HIF_DEBUG_SUP ++#define HIF_DBG(msg) (printk msg) ++#else ++#define HIF_DBG(msg) ++#endif /* HIF_DEBUG_SUP */ ++ ++#ifdef HIF_DEBUG_SUP_TX ++#define HIF_DBG_TX(msg) (printk msg) ++#else ++#define HIF_DBG_TX(msg) ++#endif /* HIF_DEBUG_SUP */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static UINT_32 ++HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T *GlueInfo, IN UINT_32 BurstLen, IN UINT_32 PortId, IN UINT_32 TransByte); ++ ++static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg); ++ ++static int HifAhbProbe(VOID); ++ ++static int HifAhbRemove(VOID); ++ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++static int HifAhbBusCntGet(VOID); ++ ++static int HifAhbBusCntClr(VOID); ++ ++static int HifTxCnt; ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++#if (CONF_HIF_DEV_MISC == 1) ++static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos); ++ ++static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos); ++ ++static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg); ++ ++static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp); ++ ++static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp); ++#else ++ ++static int HifAhbPltmProbe(IN struct platform_device *PDev); ++ ++static int __exit HifAhbPltmRemove(IN struct platform_device *PDev); ++ ++#ifdef CONFIG_PM ++static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message); ++ ++static int HifAhbPltmResume(IN struct platform_device *PDev); ++#endif /* CONFIG_PM */ ++ ++#endif /* CONF_HIF_DEV_MISC */ ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ ++static VOID HifAhbLoopbkAuto(IN unsigned long arg); ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if (CONF_HIF_DMA_INT == 1) ++static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg); ++#endif /* CONF_HIF_DMA_INT */ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* initialiation function from other module */ ++static probe_card pfWlanProbe; ++ ++/* release function from other module */ ++static remove_card pfWlanRemove; ++ ++static BOOLEAN WlanDmaFatalErr; ++ ++#if (CONF_HIF_DEV_MISC == 1) ++static const struct file_operations MtkAhbOps = { ++ .owner = THIS_MODULE, ++ .read = HifAhbMiscRead, ++ .write = HifAhbMiscWrite, ++ .unlocked_ioctl = HifAhbMiscIoctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = HifAhbMiscIoctl, ++#endif ++ .open = HifAhbMiscOpen, ++ .release = HifAhbMiscClose, ++}; ++ ++static struct miscdevice MtkAhbDriver = { ++ .minor = MISC_DYNAMIC_MINOR, /* any minor number */ ++ .name = HIF_MOD_NAME, ++ .fops = &MtkAhbOps, ++}; ++#else ++ ++#ifdef CONFIG_OF ++static const struct of_device_id apwifi_of_ids[] = { ++ {.compatible = "mediatek,wifi", .data = (void *)0}, ++ {.compatible = "mediatek,mt7623-wifi", .data = (void *)0x7623}, ++ {} ++}; ++#endif ++ ++struct platform_driver MtkPltmAhbDriver = { ++ .driver = { ++ .name = "mt-wifi", ++ .owner = THIS_MODULE, ++#ifdef CONFIG_OF ++ .of_match_table = apwifi_of_ids, ++#endif ++ }, ++ .probe = HifAhbPltmProbe, ++#ifdef CONFIG_PM ++ .suspend = HifAhbPltmSuspend, ++ .resume = HifAhbPltmResume, ++#else ++ .suspend = NULL, ++ .resume = NULL, ++#endif /* CONFIG_PM */ ++ .remove = __exit_p(HifAhbPltmRemove), ++}; ++ ++static struct platform_device *HifAhbPDev; ++ ++#endif /* CONF_HIF_DEV_MISC */ ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will register sdio bus to the os ++* ++* \param[in] pfProbe Function pointer to detect card ++* \param[in] pfRemove Function pointer to remove card ++* ++* \return The result of registering HIF driver (WLAN_STATUS_SUCCESS = 0) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove) ++{ ++ WLAN_STATUS Ret; ++ ++ ASSERT(pfProbe); ++ ASSERT(pfRemove); ++ ++ pfWlanProbe = pfProbe; /* wlan card initialization in other modules = wlanProbe() */ ++ pfWlanRemove = pfRemove; ++ ++#if (CONF_HIF_DEV_MISC == 1) ++ Ret = misc_register(&MtkAhbDriver); ++ if (Ret != 0) ++ return Ret; ++ HifAhbProbe(); ++#else ++ Ret = platform_driver_register(&MtkPltmAhbDriver); ++#endif /* CONF_HIF_DEV_MISC */ ++ ++ return Ret; ++ ++} /* end of glRegisterBus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will unregister sdio bus to the os ++* ++* \param[in] pfRemove Function pointer to remove card ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glUnregisterBus(remove_card pfRemove) ++{ ++ ASSERT(pfRemove); ++ ++ pfRemove(); ++ ++#if (CONF_HIF_DEV_MISC == 1) ++ HifAhbRemove(); ++ ++ if ((misc_deregister(&MtkAhbDriver)) != 0) ++ ; ++#else ++ ++ platform_driver_unregister(&MtkPltmAhbDriver); ++#endif /* CONF_HIF_DEV_MISC */ ++ ++ return; ++ ++} /* end of glUnregisterBus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will inform us whole chip reset start event. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glResetHif(GLUE_INFO_T *GlueInfo) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ if (HifInfo->DmaOps) ++ HifInfo->DmaOps->DmaReset(HifInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function stores hif related info, which is initialized before. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glSetHifInfo(GLUE_INFO_T *GlueInfo, ULONG ulCookie) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ const struct of_device_id *of_id; ++ ++ /* Init HIF */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++#if (CONF_HIF_DEV_MISC == 1) ++ HifInfo->Dev = MtkAhbDriver.this_device; ++#else ++ HifInfo->Dev = &HifAhbPDev->dev; ++#endif /* CONF_HIF_DEV_MISC */ ++ SET_NETDEV_DEV(GlueInfo->prDevHandler, HifInfo->Dev); ++ ++ HifInfo->HifRegBaseAddr = ioremap(HIF_DRV_BASE, HIF_DRV_LENGTH); ++ HifInfo->McuRegBaseAddr = ioremap(CONN_MCU_DRV_BASE, CONN_MCU_REG_LENGTH); ++ DBGLOG(INIT, INFO, "[WiFi/HIF]HifInfo->HifRegBaseAddr=0x%p, HifInfo->McuRegBaseAddr=0x%p\n", ++ HifInfo->HifRegBaseAddr, HifInfo->McuRegBaseAddr); ++ ++ /* default disable DMA */ ++ HifInfo->fgDmaEnable = FALSE; ++ HifInfo->DmaRegBaseAddr = 0; ++ HifInfo->DmaOps = NULL; ++ of_id = of_match_node(apwifi_of_ids, HifAhbPDev->dev.of_node); ++ if (of_id && of_id->data) { ++ HifInfo->ChipID = (UINT_32)(unsigned long)of_id->data; ++ } else { ++ /* read chip ID */ ++ HifInfo->ChipID = HIF_REG_READL(HifInfo, MCR_WCIR) & 0xFFFF; ++ if (HifInfo->ChipID == 0x0321 || HifInfo->ChipID == 0x0335 || HifInfo->ChipID == 0x0337) ++ HifInfo->ChipID = 0x6735; /* Denali ChipID transition */ ++ if (HifInfo->ChipID == 0x0326) ++ HifInfo->ChipID = 0x6755; ++ } ++ DBGLOG(INIT, INFO, "[WiFi/HIF] ChipID = 0x%x\n", HifInfo->ChipID); ++#ifdef CONFIG_OF ++#if !defined(CONFIG_MTK_CLKMGR) ++ HifInfo->clk_wifi_dma = devm_clk_get(&HifAhbPDev->dev, "wifi-dma"); ++ if (IS_ERR(HifInfo->clk_wifi_dma)) ++ DBGLOG(INIT, ERROR, "[WiFi/HIF][CCF]cannot get HIF clk_wifi_dma clock.\n"); ++ DBGLOG(INIT, TRACE, "[WiFi/HIF][CCF]HIF clk_wifi_dma=0x%p\n", HifInfo->clk_wifi_dma); ++#endif ++#endif ++ ++ /* Init DMA */ ++ WlanDmaFatalErr = 0; /* reset error flag */ ++ ++#if (CONF_MTK_AHB_DMA == 1) ++ spin_lock_init(&HifInfo->DdmaLock); ++ ++ HifPdmaInit(HifInfo); ++#endif /* CONF_MTK_AHB_DMA */ ++ ++ /* Start loopback test after 10 seconds */ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ ++ { ++ init_timer(&(HifInfo->HifTmrLoopbkFn)); ++ HifInfo->HifTmrLoopbkFn.function = HifAhbLoopbkAuto; ++ HifInfo->HifTmrLoopbkFn.data = (unsigned long)GlueInfo; ++ ++ init_waitqueue_head(&HifInfo->HifWaitq); ++ HifInfo->HifTaskLoopbkFn = kthread_run(kalDevLoopbkThread, GlueInfo->prDevHandler, "LoopbkThread"); ++ HifInfo->HifLoopbkFlg = 0; ++ ++ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ ++ HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(30000); ++ add_timer(&(HifInfo->HifTmrLoopbkFn)); ++ ++ HIF_DBG(("[WiFi/HIF] Start loopback test after 10 seconds (jiffies = %u)...\n", jiffies)); ++ } ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if (CONF_HIF_DMA_INT == 1) ++ init_waitqueue_head(&HifInfo->HifDmaWaitq); ++ HifInfo->HifDmaWaitFlg = 0; ++#endif /* CONF_HIF_DMA_INT */ ++ ++} /* end of glSetHifInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function clears hif related info. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glClearHifInfo(GLUE_INFO_T *GlueInfo) ++{ ++ iounmap(GlueInfo->rHifInfo.HifRegBaseAddr); ++ iounmap(GlueInfo->rHifInfo.DmaRegBaseAddr); ++ iounmap(GlueInfo->rHifInfo.McuRegBaseAddr); ++ return; ++ ++} /* end of glClearHifInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function clears hif related info. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ DBGLOG(INIT, TRACE, "glGetChipInfo ChipID = 0x%x\n", HifInfo->ChipID); ++ switch (HifInfo->ChipID) { ++ case MTK_CHIP_ID_6571: ++ case MTK_CHIP_ID_8127: ++ case MTK_CHIP_ID_6752: ++ case MTK_CHIP_ID_8163: ++ case MTK_CHIP_ID_6735: ++ case MTK_CHIP_ID_6580: ++ case MTK_CHIP_ID_6755: ++ case MTK_CHIP_ID_7623: ++ kalSprintf(pucChipBuf, "%04x", HifInfo->ChipID); ++ break; ++ default: ++ kalMemCopy(pucChipBuf, "SOC", strlen("SOC")); ++ } ++} /* end of glGetChipInfo() */ ++ ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function to check if we need wakelock under Hotspot mode. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ if (HifInfo->ChipID == MTK_CHIP_ID_6572 || HifInfo->ChipID == MTK_CHIP_ID_6582) ++ return TRUE; ++ else ++ return FALSE; ++} /* end of glIsChipNeedWakelock() */ ++#endif /* CFG_SPM_WORKAROUND_FOR_HOTSPOT */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Initialize bus operation and hif related information, request resources. ++* ++* \param[out] pvData A pointer to HIF-specific data type buffer. ++* For eHPI, pvData is a pointer to UINT_32 type and stores a ++* mapped base address. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glBusInit(PVOID pvData) ++{ ++ return TRUE; ++} /* end of glBusInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Stop bus operation and release resources. ++* ++* \param[in] pvData A pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glBusRelease(PVOID pvData) ++{ ++} /* end of glBusRelease() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setup bus interrupt operation and interrupt handler for os. ++* ++* \param[in] pvData A pointer to struct net_device. ++* \param[in] pfnIsr A pointer to interrupt handler function. ++* \param[in] pvCookie Private data for pfnIsr function. ++* ++* \retval WLAN_STATUS_SUCCESS if success ++* NEGATIVE_VALUE if fail ++*/ ++/*----------------------------------------------------------------------------*/ ++#ifdef CONFIG_OF ++INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = { 0, 0, 0 }; ++ /* unsigned int phy_base; */ ++ unsigned int irq_id = 0; ++ unsigned int irq_flags = 0; ++ ++ struct net_device *prNetDevice; ++ ++ ASSERT(pvData); ++ if (!pvData) ++ return -1; ++ prNetDevice = (struct net_device *)pvData; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); ++ if (node) { ++ irq_id = irq_of_parse_and_map(node, 0); ++ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); ++ } else { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); ++ } ++ ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); ++ } else { ++ irq_flags = irq_info[2]; ++ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); ++ } ++ ++ /* Register AHB IRQ */ ++ if (request_irq(irq_id, HifAhbISR, irq_flags, HIF_MOD_NAME, prNetDevice)) { ++ DBGLOG(INIT, ERROR, "WIFI-OF: request irq %d fail!\n", irq_id); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = { 0, 0, 0 }; ++ /* unsigned int phy_base; */ ++ unsigned int irq_id = 0; ++ unsigned int irq_flags = 0; ++ ++ struct net_device *prNetDevice; ++ ++ /* Init */ ++ ASSERT(pvData); ++ if (!pvData) ++ return; ++ prNetDevice = (struct net_device *)pvData; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); ++ if (node) { ++ irq_id = irq_of_parse_and_map(node, 0); ++ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); ++ } else { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); ++ } ++ ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); ++ } else { ++ irq_flags = irq_info[2]; ++ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); ++ } ++ ++ /* Free the IRQ */ ++ free_irq(irq_id, prNetDevice); ++ return; ++ ++} ++#else ++/* the name is different in 72 and 82 */ ++#ifndef MT_WF_HIF_IRQ_ID /* for MT6572/82/92 */ ++#define MT_WF_HIF_IRQ_ID WF_HIF_IRQ_ID ++#endif /* MT_WF_HIF_IRQ_ID */ ++ ++INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) ++{ ++ int ret = 0; ++ struct net_device *prNetDevice; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ ASSERT(pvData); ++ if (!pvData) ++ return -1; ++ ++ prNetDevice = (struct net_device *)pvData; ++ GlueInfo = (GLUE_INFO_T *) pvCookie; ++ ASSERT(GlueInfo); ++ if (!GlueInfo) { ++ DBGLOG(INIT, ERROR, "GlueInfo == NULL!\n"); ++ return -1; ++ } ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* Register AHB IRQ */ ++ if (request_irq(MT_WF_HIF_IRQ_ID, HifAhbISR, IRQF_TRIGGER_LOW, HIF_MOD_NAME, prNetDevice)) { ++ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_WF_HIF_IRQ_ID); ++ return -1; ++ } ++#if (CONF_HIF_DMA_INT == 1) ++ if (request_irq(MT_GDMA2_IRQ_ID, HifDmaISR, IRQF_TRIGGER_LOW, "AHB_DMA", prNetDevice)) { ++ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_GDMA2_IRQ_ID); ++ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); ++ return -1; ++ } ++#endif /* CONF_HIF_DMA_INT */ ++ ++ return ret; ++ ++} /* end of glBusSetIrq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Stop bus interrupt operation and disable interrupt handling for os. ++* ++* \param[in] pvData A pointer to struct net_device. ++* \param[in] pvCookie Private data for pfnIsr function. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) ++{ ++ struct net_device *prNetDevice; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ ASSERT(pvData); ++ if (!pvData) ++ return; ++ ++ prNetDevice = (struct net_device *)pvData; ++ GlueInfo = (GLUE_INFO_T *) pvCookie; ++ ASSERT(GlueInfo); ++ if (!GlueInfo) ++ return; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* Free the IRQ */ ++ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); ++ return; ++ ++} /* end of glBusreeIrq() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Read a 32-bit device register ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] RegOffset Register offset ++* \param[in] pu4Value Pointer to variable used to store read value ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalDevRegRead(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, OUT UINT_32 *pu4Value) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* sanity check and init */ ++ ASSERT(GlueInfo); ++ ASSERT(pu4Value); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* use PIO mode to read register */ ++ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) ++ return FALSE; ++ *pu4Value = HIF_REG_READL(HifInfo, RegOffset); ++ ++ if ((RegOffset == MCR_WRDR0) || (RegOffset == MCR_WRDR1)) ++ HIF_DBG(("[WiFi/HIF] kalDevRegRead from Data Port 0 or 1\n")); ++ ++ return TRUE; ++ ++} /* end of kalDevRegRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Write a 32-bit device register ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] RegOffset Register offset ++* \param[in] RegValue RegValue to be written ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalDevRegWrite(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, IN UINT_32 RegValue) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* sanity check and init */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* use PIO mode to write register */ ++ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) ++ return FALSE; ++ HIF_REG_WRITEL(HifInfo, RegOffset, RegValue); ++ ++ if ((RegOffset == MCR_WTDR0) || (RegOffset == MCR_WTDR1)) ++ HIF_DBG(("[WiFi/HIF] kalDevRegWrite to Data Port 0 or 1\n")); ++ ++ return TRUE; ++ ++} /* end of kalDevRegWrite() */ ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Read device I/O port ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] Port I/O port offset ++* \param[in] Size Length to be read ++* \param[out] Buf Pointer to read buffer ++* \param[in] MaxBufSize Length of the buffer valid to be accessed ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++kalDevPortRead(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, OUT PUINT_8 Buf, IN UINT_32 MaxBufSize) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4HSTCRValue = 0; ++ UINT_32 RegWHLPCR = 0; ++ ++ /* sanity check */ ++ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { ++ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", ++ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); ++ return FALSE; ++ } ++ /* Init */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ ASSERT(Buf); ++ ASSERT(Size <= MaxBufSize); ++ ++ /* Note: burst length should be equal to the one used in DMA */ ++ if (Port == MCR_WRDR0) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD0, Size); ++ else if (Port == MCR_WRDR1) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD1, Size); ++ else if (Port == MCR_WHISR) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_WHISR, Size); ++ ++ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ /* Read */ ++#if (CONF_MTK_AHB_DMA == 1) ++ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) ++ && ((Port == MCR_WRDR0) || (Port == MCR_WRDR1))) { ++ /* only for data port */ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; ++ MTK_WCN_HIF_DMA_CONF DmaConf; ++ UINT_32 LoopCnt; ++ unsigned long PollTimeout; ++#if (CONF_HIF_DMA_INT == 1) ++ INT_32 RtnVal = 0; ++#endif ++ /* config DMA, Port = MCR_WRDR0 or MCR_WRDR1 */ ++ DmaConf.Count = Size; ++ DmaConf.Dir = HIF_DMA_DIR_RX; ++ DmaConf.Src = HIF_DRV_BASE + Port; /* must be physical addr */ ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ DmaConf.Dst = kalIOPhyAddrGet(Buf); /* must be physical addr */ ++ ++ /* TODO: use virt_to_phys() */ ++ if (DmaConf.Dst == NULL) { ++ HIF_DBG(("[WiFi/HIF] Use Dma Buffer to RX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); ++ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); ++ ++ kalDmaBufGet(&DmaVBuf, &DmaPBuf); ++ DmaConf.Dst = (ULONG) DmaPBuf; ++ } ++#else ++ /* ++ http://kernelnewbies.org/KernelMemoryAllocation ++ Since the cache-coherent mapping may be expensive, also a streaming allocation exists. ++ ++ This is a buffer for one-way communication, which means coherency is limited to ++ flushing the data from the cache after a write finishes. The buffer has to be ++ pre-allocated (e.g. using kmalloc()). DMA for it is set up with dma_map_single(). ++ ++ When the DMA is finished (e.g. when the device has sent an interrupt signaling end of ++ DMA), call dma_unmap_single(). Between map and unmap, the device is in control of the ++ buffer: if you write to the device, do it before dma_map_single(), if you read from ++ it, do it after dma_unmap_single(). ++ */ ++ /* DMA_FROM_DEVICE invalidated (without writeback) the cache */ ++ /* TODO: if dst_off was not cacheline aligned */ ++ DmaConf.Dst = dma_map_single(HifInfo->Dev, Buf, Size, DMA_FROM_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ /* start to read data */ ++ AP_DMA_HIF_LOCK(HifInfo); /* lock to avoid other codes config GDMA */ ++ ++ prDmaOps->DmaClockCtrl(TRUE); ++ prDmaOps->DmaConfig(HifInfo, &DmaConf); ++ prDmaOps->DmaStart(HifInfo); ++ ++#if (CONF_HIF_DMA_INT == 1) ++ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); ++ if (RtnVal <= 0) ++ DBGLOG(RX, ERROR, "fatal error1! reset DMA!\n"); ++ HifInfo->HifDmaWaitFlg = 0; ++#else ++ PollTimeout = jiffies + HZ * 5; ++ ++ do { ++ if (time_before(jiffies, PollTimeout)) ++ continue; ++ DBGLOG(RX, INFO, "RX DMA Timeout, HSTCR: 0x%08x, and dump WHISR EnhanceMode data\n", ++ u4HSTCRValue); ++ HifDumpEnhanceModeData(GlueInfo->prAdapter); ++ if (prDmaOps->DmaRegDump != NULL) ++ prDmaOps->DmaRegDump(HifInfo); ++ WlanDmaFatalErr = 1; ++ /* we still need complete dma progress even dma timeout */ ++ break; ++ } while (!prDmaOps->DmaPollIntr(HifInfo)); ++#endif /* CONF_HIF_DMA_INT */ ++ /* we should disable dma interrupt then clear dma interrupt, otherwise, ++ for dma timeout case, interrupt may be set after we clear it */ ++ prDmaOps->DmaStop(HifInfo); ++ prDmaOps->DmaAckIntr(HifInfo); ++ ++ LoopCnt = 0; ++ do { ++ if (LoopCnt++ > 100000) { ++ /* TODO: impossible! reset DMA */ ++ DBGLOG(RX, ERROR, "fatal error2! reset DMA!\n"); ++ break; ++ } ++ } while (prDmaOps->DmaPollStart(HifInfo) != 0); ++ ++ prDmaOps->DmaClockCtrl(FALSE); ++ ++ AP_DMA_HIF_UNLOCK(HifInfo); ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ if (DmaVBuf != NULL) ++ kalMemCopy(Buf, DmaVBuf, Size); ++#else ++ dma_unmap_single(HifInfo->Dev, DmaConf.Dst, Size, DMA_FROM_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++ if (WlanDmaFatalErr) { ++ if (!fgIsResetting) ++ glDoChipReset(); ++ return FALSE; ++ } ++ HIF_DBG(("[WiFi/HIF] DMA RX OK!\n")); ++ } else ++#endif /* CONF_MTK_AHB_DMA */ ++ { ++ UINT_32 IdLoop, MaxLoop; ++ UINT_32 *LoopBuf; ++ ++ /* default PIO mode */ ++ MaxLoop = Size >> 2; ++ if (Size & 0x3) ++ MaxLoop++; ++ LoopBuf = (UINT_32 *) Buf; ++ ++ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { ++ ++ *LoopBuf = HIF_REG_READL(HifInfo, Port); ++ LoopBuf++; ++ } ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ } ++ ++ return TRUE; ++ ++} /* end of kalDevPortRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Write device I/O port ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] Port I/O port offset ++* \param[in] Size Length to be write ++* \param[in] Buf Pointer to write buffer ++* \param[in] MaxBufSize Length of the buffer valid to be accessed ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++kalDevPortWrite(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, IN PUINT_8 Buf, IN UINT_32 MaxBufSize) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4HSTCRValue = 0; ++ UINT_32 RegWHLPCR = 0; ++ ++ /* sanity check */ ++ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { ++ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", ++ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); ++ return FALSE; ++ } ++ ++ /* Init */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ ASSERT(Buf); ++ ASSERT(Size <= MaxBufSize); ++ ++ HifTxCnt++; ++ ++ /* Note: burst length should be equal to the one used in DMA */ ++ if (Port == MCR_WTDR0) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD0, Size); ++ else if (Port == MCR_WTDR1) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD1, Size); ++ /* else other non-data port */ ++ ++ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ /* Write */ ++#if (CONF_MTK_AHB_DMA == 1) ++ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) && ((Port == MCR_WTDR0) || ++ (Port == MCR_WTDR1))) { ++ /* only for data port */ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; ++ MTK_WCN_HIF_DMA_CONF DmaConf; ++ UINT_32 LoopCnt; ++ unsigned long PollTimeout; ++#if (CONF_HIF_DMA_INT == 1) ++ INT_32 RtnVal = 0; ++#endif ++ ++ /* config GDMA */ ++ HIF_DBG_TX(("[WiFi/HIF/DMA] Prepare to send data...\n")); ++ DmaConf.Count = Size; ++ DmaConf.Dir = HIF_DMA_DIR_TX; ++ DmaConf.Dst = HIF_DRV_BASE + Port; /* must be physical addr */ ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ DmaConf.Src = kalIOPhyAddrGet(Buf); /* must be physical addr */ ++ ++ /* TODO: use virt_to_phys() */ ++ if (DmaConf.Src == NULL) { ++ HIF_DBG_TX(("[WiFi/HIF] Use Dma Buffer to TX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); ++ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); ++ ++ kalDmaBufGet(&DmaVBuf, &DmaPBuf); ++ DmaConf.Src = (ULONG) DmaPBuf; ++ ++ kalMemCopy(DmaVBuf, Buf, Size); ++ } ++#else ++ ++ /* DMA_TO_DEVICE writeback the cache */ ++ DmaConf.Src = dma_map_single(HifInfo->Dev, Buf, Size, DMA_TO_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ /* start to write */ ++ AP_DMA_HIF_LOCK(HifInfo); ++ ++ prDmaOps->DmaClockCtrl(TRUE); ++ prDmaOps->DmaConfig(HifInfo, &DmaConf); ++ prDmaOps->DmaStart(HifInfo); ++ ++#if (CONF_HIF_DMA_INT == 1) ++ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); ++ if (RtnVal <= 0) ++ DBGLOG(TX, ERROR, "fatal error1! reset DMA!\n"); ++ HifInfo->HifDmaWaitFlg = 0; ++#else ++ ++ LoopCnt = 0; ++ PollTimeout = jiffies + HZ * 5; ++ ++ do { ++ if (time_before(jiffies, PollTimeout)) ++ continue; ++ DBGLOG(TX, INFO, "TX DMA Timeout, HSTCR: 0x%08x\n", u4HSTCRValue); ++ if (prDmaOps->DmaRegDump != NULL) ++ prDmaOps->DmaRegDump(HifInfo); ++ WlanDmaFatalErr = 1; ++ /* we still need complete dma progress even dma timeout */ ++ break; ++ } while (!prDmaOps->DmaPollIntr(HifInfo)); ++#endif /* CONF_HIF_DMA_INT */ ++ /* we should disable dma interrupt then clear dma interrupt, otherwise, ++ for dma timeout case, interrupt may be set after we clear it */ ++ prDmaOps->DmaStop(HifInfo); ++ prDmaOps->DmaAckIntr(HifInfo); ++ ++ LoopCnt = 0; ++ do { ++ if (LoopCnt++ > 100000) { ++ DBGLOG(TX, ERROR, "fatal error2! reset DMA!\n"); ++ break; ++ } ++ } while (prDmaOps->DmaPollStart(HifInfo) != 0); ++ ++ prDmaOps->DmaClockCtrl(FALSE); ++ ++ AP_DMA_HIF_UNLOCK(HifInfo); ++ ++#ifndef MTK_DMA_BUF_MEMCPY_SUP ++ dma_unmap_single(HifInfo->Dev, DmaConf.Src, Size, DMA_TO_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++ if (WlanDmaFatalErr) { ++ if (!fgIsResetting) ++ glDoChipReset(); ++ return FALSE; ++ } ++ HIF_DBG_TX(("[WiFi/HIF] DMA TX OK!\n")); ++ } else ++#endif /* CONF_MTK_AHB_DMA */ ++ { ++ UINT_32 IdLoop, MaxLoop; ++ UINT_32 *LoopBuf; ++ ++ /* PIO mode */ ++ MaxLoop = Size >> 2; ++ LoopBuf = (UINT_32 *) Buf; ++ ++ HIF_DBG_TX(("[WiFi/HIF/PIO] Prepare to send data (%d 0x%p-0x%p)...\n", ++ Size, LoopBuf, (((UINT8 *) LoopBuf) + (Size & (~0x03))))); ++ ++ if (Size & 0x3) ++ MaxLoop++; ++ ++ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { ++ HIF_REG_WRITEL(HifInfo, Port, *LoopBuf); ++ LoopBuf++; ++ } ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++ HIF_DBG_TX(("\n\n")); ++ } ++ ++ return TRUE; ++ ++} /* end of kalDevPortWrite() */ ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a SDIO interrupt callback function ++* ++* \param[in] func pointer to SDIO handle ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg) ++{ ++ struct net_device *prNetDevice = (struct net_device *)Arg; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ IsrCnt++; ++ ASSERT(prNetDevice); ++ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); ++ ASSERT(GlueInfo); ++ ++ if (!GlueInfo) ++ return IRQ_HANDLED; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ GlueInfo->IsrCnt++; ++ ++ if (GlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ return IRQ_HANDLED; ++ } ++ ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ /* lock 100ms to avoid suspend */ ++ kalHifAhbKalWakeLockTimeout(GlueInfo); ++ ++ /* Wake up main thread */ ++ set_bit(GLUE_FLAG_INT_BIT, &GlueInfo->ulFlag); ++ ++ /* when we got sdio interrupt, we wake up the tx servie thread */ ++ wake_up_interruptible(&GlueInfo->waitq); ++ ++ IsrPassCnt++; ++ GlueInfo->IsrPassCnt++; ++ return IRQ_HANDLED; ++ ++} ++ ++#if (CONF_HIF_DMA_INT == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a SDIO interrupt callback function ++* ++* \param[in] func pointer to SDIO handle ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg) ++{ ++ struct net_device *prNetDevice = (struct net_device *)Arg; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ ASSERT(prNetDevice); ++ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); ++ ASSERT(GlueInfo); ++ ++ if (!GlueInfo) ++ return IRQ_HANDLED; ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* disable interrupt */ ++ HifInfo->DmaOps->DmaAckIntr(HifInfo); ++ ++ /* Wake up main thread */ ++ set_bit(1, &HifInfo->HifDmaWaitFlg); ++ ++ /* when we got sdio interrupt, we wake up the tx servie thread */ ++ wake_up_interruptible(&HifInfo->HifDmaWaitq); ++ ++ return IRQ_HANDLED; ++ ++} ++#endif /* CONF_HIF_DMA_INT */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a SDIO probe function ++* ++* \param[in] func pointer to SDIO handle ++* \param[in] id pointer to SDIO device id table ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++#if defined(CONFIG_MTK_CLKMGR) ++#if defined(MTK_EXTERNAL_LDO) || defined(MTK_ALPS_BOX_SUPPORT) ++#include ++#endif ++#endif ++ ++static int HifAhbProbe(VOID) ++{ ++ int Ret = 0; ++ ++ DBGLOG(INIT, INFO, "HifAhbProbe()\n"); ++ ++ /* power on WiFi TX PA 3.3V and HIF GDMA clock */ ++ { ++#ifdef CONFIG_MTK_PMIC_MT6397 ++#if defined(CONFIG_MTK_CLKMGR) ++#ifdef MTK_EXTERNAL_LDO ++ /* for 8127 tablet */ ++ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_UP); ++#elif defined(MTK_ALPS_BOX_SUPPORT) ++ /* for 8127 box */ ++ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_UP); ++#else ++ hwPowerOn(MT65XX_POWER_LDO_VGP4, VOL_3300, "WLAN"); ++#endif ++#endif ++#else ++#ifdef CONFIG_OF /*for MT6752 */ ++ mtk_wcn_consys_hw_wifi_paldo_ctrl(1); /* switch to HW mode */ ++#else /*for MT6572/82/92 */ ++ hwPowerOn(MT6323_POWER_LDO_VCN33_WIFI, VOL_3300, "WLAN"); ++ upmu_set_vcn33_on_ctrl_wifi(1); /* switch to HW mode */ ++#endif ++#endif ++ ++ } ++ ++#if (CONF_HIF_DEV_MISC == 1) ++ if (pfWlanProbe((PVOID) &MtkAhbDriver.this_device) != WLAN_STATUS_SUCCESS) { ++#else ++ if (pfWlanProbe((PVOID) &HifAhbPDev->dev) != WLAN_STATUS_SUCCESS) { ++#endif /* CONF_HIF_DEV_MISC */ ++ ++ pfWlanRemove(); ++ Ret = -1; ++ } ++ ++ return Ret; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do module remove. ++* ++* \param[in] None ++* ++* \return The result of remove (WLAN_STATUS_SUCCESS = 0) ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbRemove(VOID) ++{ ++ DBGLOG(INIT, INFO, "HifAhbRemove()\n"); ++ ++ pfWlanRemove(); ++ ++ { ++#ifdef CONFIG_MTK_PMIC_MT6397 ++#if defined(CONFIG_MTK_CLKMGR) ++#ifdef MTK_EXTERNAL_LDO ++ /* for 8127 tablet */ ++ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_DOWN); ++#elif defined(MTK_ALPS_BOX_SUPPORT) ++ /* for 8127 box */ ++ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_DOWN); ++#else ++ hwPowerDown(MT65XX_POWER_LDO_VGP4, "WLAN"); ++#endif ++#endif ++#else ++#ifdef CONFIG_OF /*for MT6752 */ ++ mtk_wcn_consys_hw_wifi_paldo_ctrl(0); /* switch to SW mode */ ++#else /*for MT6572/82/92 */ ++ upmu_set_vcn33_on_ctrl_wifi(0); /* switch to SW mode */ ++ hwPowerDown(MT6323_POWER_LDO_VCN33_WIFI, "WLAN"); ++#endif ++#endif ++ ++ } ++ ++ return 0; ++} ++ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function gets the TX count pass through HIF AHB bus. ++* ++* \param[in] None ++* ++* \return TX count ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbBusCntGet(VOID) ++{ ++ return HifTxCnt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function resets the TX count pass through HIF AHB bus. ++* ++* \param[in] None ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbBusCntClr(VOID) ++{ ++ HifTxCnt = 0; ++ return 0; ++} ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function configs the DMA TX/RX settings before any real TX/RX. ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] BurstLen 0(1DW), 1(4DW), 2(8DW), Others(Reserved) ++* \param[in] PortId 0(TXD0), 1(TXD1), 2(RXD0), 3(RXD1), 4(WHISR enhance) ++* \param[in] TransByte Should be 4-byte align. ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_32 HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T * GlueInfo, UINT_32 BurstLen, UINT_32 PortId, UINT_32 TransByte) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 RegHSTCR; ++ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ RegHSTCR = HIF_REG_READL(HifInfo, MCR_WHIER); ++ ++ RegHSTCR = HIF_REG_READL(HifInfo, MCR_HSTCR); ++ RegHSTCR = ++ ((BurstLen << HSTCR_AFF_BURST_LEN_OFFSET) & HSTCR_AFF_BURST_LEN) | ++ ((PortId << HSTCR_TRANS_TARGET_OFFSET) & HSTCR_TRANS_TARGET) | ++ (((TransByte & 0x3) == 0) ? (TransByte & HSTCR_HSIF_TRANS_CNT) : ((TransByte + 4) & HSTCR_HSIF_TRANS_CNT)); ++ HIF_REG_WRITEL(HifInfo, MCR_HSTCR, RegHSTCR); ++ return RegHSTCR; ++} ++ ++VOID glSetPowerState(IN GLUE_INFO_T *GlueInfo, IN UINT_32 ePowerMode) ++{ ++ ++} ++ ++#if (CONF_HIF_DEV_MISC == 1) ++/* no use */ ++static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos) ++{ ++ return 0; ++} ++ ++static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos) ++{ ++ return 0; ++} ++ ++static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg) ++{ ++ return 0; ++} ++ ++static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp) ++{ ++ return 0; ++} ++ ++static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp) ++{ ++ return 0; ++} ++#else ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbPltmProbe(IN struct platform_device *PDev) ++{ ++ HifAhbPDev = PDev; ++ ++ DBGLOG(INIT, INFO, "HifAhbPltmProbe\n"); ++ ++#if (CONF_HIF_PMIC_TEST == 1) ++ wmt_set_jtag_for_mcu(); ++ wmt_set_jtag_for_gps(); ++ ++#endif /* CONF_HIF_PMIC_TEST */ ++ ++#if (MTK_WCN_SINGLE_MODULE == 1) ++ HifAhbProbe(); /* only for test purpose without WMT module */ ++ ++#else ++ ++ /* register WiFi function to WMT */ ++ DBGLOG(INIT, INFO, "mtk_wcn_wmt_wlan_reg\n"); ++ { ++ MTK_WCN_WMT_WLAN_CB_INFO WmtCb; ++ ++ WmtCb.wlan_probe_cb = HifAhbProbe; ++ WmtCb.wlan_remove_cb = HifAhbRemove; ++ WmtCb.wlan_bus_cnt_get_cb = HifAhbBusCntGet; ++ WmtCb.wlan_bus_cnt_clr_cb = HifAhbBusCntClr; ++ mtk_wcn_wmt_wlan_reg(&WmtCb); ++ } ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int __exit HifAhbPltmRemove(IN struct platform_device *PDev) ++{ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++ mtk_wcn_wmt_wlan_unreg(); ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* \param[in] Message ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbPltmResume(IN struct platform_device *PDev) ++{ ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++#endif /* CONF_HIF_DEV_MISC */ ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Trigger to do HIF loopback test. ++* ++* \param[in] arg Pointer to the GLUE_INFO_T structure. ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifAhbLoopbkAuto(IN unsigned long arg) ++{ ++ ++ P_GLUE_INFO_T GlueInfo = (P_GLUE_INFO_T) arg; ++ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; ++ ++ ASSERT(GlueInfo); ++ ++ HIF_DBG(("[WiFi/HIF] Trigger to do loopback test...\n")); ++ ++ set_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &HifInfo->HifLoopbkFlg); ++ wake_up_interruptible(&HifInfo->HifWaitq); ++ ++} ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo) ++{ ++ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; ++ unsigned short j; ++ ++ for (j = 0; j < 512; j++) { ++ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(prHifInfo, CONN_MCU_CPUPCR)); ++ if ((j + 1) % 16 == 0) ++ DBGLOG(INIT, WARN, "\n"); ++ } ++} ++ ++/* End of ahb.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c +new file mode 100644 +index 000000000000..6b719028ae93 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c +@@ -0,0 +1,31 @@ ++/****************************************************************************** ++*[File] mt6516-evb.c ++*[Version] v1.0 ++*[Revision Date] 2010-03-01 ++*[Author] ++*[Description] ++* dummy file for build system ++*[Copyright] ++* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. ++******************************************************************************/ ++ ++/* ++** Log: mt6516-evb.c ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove debug message ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h +new file mode 100644 +index 000000000000..1507d5560040 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h +@@ -0,0 +1,340 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 ++*/ ++ ++/*! \file "hif.h" ++ \brief Functions for the driver to register bus and setup the IRQ ++ ++ Functions for the driver to register bus and setup the IRQ ++*/ ++ ++/* ++** Log: hif.h ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add GPIO debug function ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK ++ * HIF by default ++ * Refine linux kernel module to the license of MTK and enable MTK HIF ++ * ++ * 08 18 2010 jeffrey.chang ++ * NULL ++ * support multi-function sdio ++ * ++ * 08 17 2010 cp.wu ++ * NULL ++ * add ENE SDIO host workaround for x86 linux platform. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\4 2009-10-20 17:38:28 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\3 2009-09-28 20:19:20 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\2 2009-08-18 22:57:05 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\2 2008-09-22 23:18:17 GMT mtk01461 ++** Update driver for code review ++** Revision 1.1 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++*/ ++ ++#ifndef _HIF_H ++#define _HIF_H ++ ++#include "gl_typedef.h" ++#include "mtk_porting.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CONF_MTK_AHB_DMA 1 /* PIO mode is default mode if DMA is disabled */ ++ ++#define CONF_HIF_DEV_MISC 0 /* register as misc device */ ++#define CONF_HIF_LOOPBACK_AUTO 0 /* hif loopback test triggered by open() */ ++ /* only for development test */ ++ ++#define CONF_HIF_PMIC_TEST 0 /* test purpose: power on CONNSYS */ ++ ++#define CONF_HIF_DMA_INT 0 /* DMA interrupt mode */ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern phys_addr_t gConEmiPhyBase; ++extern BOOLEAN fgIsResetting; ++extern UINT_32 IsrCnt, IsrPassCnt; ++extern int kalDevLoopbkThread(IN void *data); ++ ++#ifdef CONFIG_MTK_PMIC_MT6397 ++#else ++#ifdef CONFIG_OF /*for MT6752 */ ++extern INT_32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT_32 enable); ++#else /*for MT6572/82/92 */ ++extern void upmu_set_vcn33_on_ctrl_wifi(UINT_32 val); ++#endif ++#endif ++ ++#if (CONF_HIF_DEV_MISC == 1) ++#else ++/* extern INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_en); */ ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#ifndef CONN_MCU_CONFIG_BASE ++#define CONN_MCU_CONFIG_BASE 0xF8070000 /* MT6572 */ ++#endif /* CONN_MCU_CONFIG_BASE */ ++ ++#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) ++#define CONSYS_REG_READ(addr) (*((volatile unsigned int *)(addr))) ++ ++#define CONN_MCU_DRV_BASE 0x18070000 ++#define CONN_MCU_REG_LENGTH 0x0200 ++#define CONN_MCU_CPUPCR 0x0160 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* host interface's private data structure, which is attached to os glue ++** layer info structure. ++ */ ++typedef struct _GL_HIF_DMA_OPS_T { /* DMA Operators */ ++ VOID (*DmaConfig)(IN VOID *HifInfo, IN VOID *Conf); ++ ++ VOID (*DmaStart)(IN VOID *HifInfo); ++ ++ VOID (*DmaStop)(IN VOID *HifInfo); ++ ++ MTK_WCN_BOOL (*DmaPollStart)(IN VOID *HifInfo); ++ ++ MTK_WCN_BOOL (*DmaPollIntr)(IN VOID *HifInfo); ++ ++ VOID (*DmaAckIntr)(IN VOID *HifInfo); ++ ++ VOID (*DmaClockCtrl)(IN UINT_32 FlgIsEnabled); ++ ++ VOID (*DmaRegDump)(IN VOID *HifInfo); ++ ++ VOID (*DmaReset)(IN VOID *HifInfo); ++ ++} GL_HIF_DMA_OPS_T; ++ ++typedef struct _GL_HIF_INFO_T { ++ ++ /* General */ ++ VOID *Dev; /* struct device */ ++ ++#define MTK_CHIP_ID_6571 0x6571 ++#define MTK_CHIP_ID_6572 0x6572 ++#define MTK_CHIP_ID_6582 0x6582 ++#define MTK_CHIP_ID_8127 0x8127 ++#define MTK_CHIP_ID_6752 0x6752 ++#define MTK_CHIP_ID_8163 0x8163 ++#define MTK_CHIP_ID_6735 0x6735 ++#define MTK_CHIP_ID_6580 0x6580 ++#define MTK_CHIP_ID_6755 0x6755 ++#define MTK_CHIP_ID_7623 0x7623 ++ ++ UINT_32 ChipID; ++ ++ /* Control flag */ ++ BOOLEAN fgIntReadClear; ++ BOOLEAN fgMbxReadClear; ++ BOOLEAN fgDmaEnable; /* TRUE: DMA mode is used (default) */ ++ ++ /* HIF related */ ++ UINT_8 *HifRegBaseAddr; /* HIF register base */ ++ UINT_8 *McuRegBaseAddr; /* CONN MCU register base */ ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ struct timer_list HifTmrLoopbkFn; /* HIF loopback test trigger timer */ ++ wait_queue_head_t HifWaitq; ++ UINT_32 HifLoopbkFlg; ++ struct task_struct *HifTaskLoopbkFn; /* HIF loopback test task */ ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if (CONF_HIF_DMA_INT == 1) ++ wait_queue_head_t HifDmaWaitq; ++ UINT_32 HifDmaWaitFlg; ++#endif /* CONF_HIF_DMA_INT */ ++ ++ /* DMA related */ ++#define AP_DMA_HIF_LOCK(_lock) /* spin_lock_bh(&(_lock)->DdmaLock) */ ++#define AP_DMA_HIF_UNLOCK(_lock) /* spin_unlock_bh(&(_lock)->DdmaLock) */ ++ spinlock_t DdmaLock; /* protect DMA access */ ++ ++ UINT_8 *DmaRegBaseAddr; /* DMA register base */ ++ GL_HIF_DMA_OPS_T *DmaOps; /* DMA Operators */ ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ struct clk *clk_wifi_dma; ++#endif ++} GL_HIF_INFO_T, *P_GL_HIF_INFO_T; ++ ++#define HIF_MOD_NAME "AHB_SLAVE_HIF" ++ ++#define HIF_DRV_BASE 0x180F0000 ++#define HIF_DRV_LENGTH 0x005c ++ ++typedef enum _MTK_WCN_HIF_BURST_LEN { ++ HIF_BURST_1DW = 0, ++ HIF_BURST_4DW, ++ HIF_BURST_8DW ++} MTK_WCN_HIF_BURST_LEN; ++ ++typedef enum _MTK_WCN_HIF_TXRX_TARGET { ++ HIF_TARGET_TXD0 = 0, ++ HIF_TARGET_TXD1, ++ HIF_TARGET_RXD0, ++ HIF_TARGET_RXD1, ++ HIF_TARGET_WHISR ++} MTK_WCN_HIF_TXRX_TARGET; ++ ++typedef enum _MTK_WCN_HIF_DMA_DIR { ++ HIF_DMA_DIR_TX = 0, ++ HIF_DMA_DIR_RX ++} MTK_WCN_HIF_DMA_DIR; ++ ++typedef struct _MTK_WCN_HIF_DMA_CONF { ++ UINT_32 Count; ++ MTK_WCN_HIF_DMA_DIR Dir; ++ UINT_32 Burst; ++ UINT_32 Wsize; ++ UINT_32 Ratio; ++ UINT_32 Connect; ++ UINT_32 Fix_en; ++ ULONG Src; ++ ULONG Dst; ++} MTK_WCN_HIF_DMA_CONF; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define MCU_REG_READL(_hif, _addr) \ ++ readl((volatile UINT_32 *)((_hif)->McuRegBaseAddr + _addr)) ++ ++/* PIO mode HIF register read/write */ ++#define HIF_REG_READL(_hif, _addr) \ ++ readl((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr)) ++ ++#define HIF_REG_WRITEL(_hif, _addr, _val) \ ++ writel(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) ++ ++#define HIF_REG_WRITEB(_hif, _addr, _val) \ ++ writeb(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) ++ ++/* PIO mode DMA register read/write */ ++#define HIF_DMAR_READL(_hif, _addr) \ ++ readl((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr)) ++ ++#define HIF_DMAR_WRITEL(_hif, _addr, _val) \ ++ writel(_val, ((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr))) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#ifndef MODULE_AHB_DMA ++VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter); ++ ++VOID HifRegDump(P_ADAPTER_T prAdapter); ++ ++BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove); ++ ++VOID glUnregisterBus(remove_card pfRemove); ++ ++VOID glResetHif(GLUE_INFO_T *GlueInfo); ++ ++VOID glSetHifInfo(P_GLUE_INFO_T prGlueInfo, ULONG ulCookie); ++ ++VOID glClearHifInfo(P_GLUE_INFO_T prGlueInfo); ++ ++VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf); ++ ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo); ++#endif ++ ++BOOLEAN glBusInit(PVOID pvData); ++ ++VOID glBusRelease(PVOID pData); ++ ++INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie); ++ ++VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie); ++ ++VOID glSetPowerState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 ePowerMode); ++ ++VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo); ++ ++#endif /* MODULE_AHB_DMA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config GDMA TX/RX. ++* ++* \param[in] DmaRegBaseAddr Pointer to the IO register base. ++* \param[in] Conf Pointer to the DMA operator. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID HifGdmaInit(GL_HIF_INFO_T *HifInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config PDMA TX/RX. ++* ++* \param[in] DmaRegBaseAddr Pointer to the IO register base. ++* \param[in] Conf Pointer to the DMA operator. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _HIF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h +new file mode 100644 +index 000000000000..094c07f98eff +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h +@@ -0,0 +1,154 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 ++*/ ++ ++/*! \file "hif_gdma.h" ++ \brief MARCO, definition, structure for GDMA. ++ ++ MARCO, definition, structure for GDMA. ++*/ ++ ++/* ++** Log: hif_gdma.h ++ * ++ * 01 16 2013 vend_samp.lin ++ * Add AHB GDMA support ++ * 1) Initial version ++** ++*/ ++ ++#ifndef _HIF_GDMA_H ++#define _HIF_GDMA_H ++ ++#include "mtk_porting.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _MTK_WCN_HIF_GDMA_BURST_LEN { ++ HIF_GDMA_BURST_1_8 = 0, ++ HIF_GDMA_BURST_2_8, ++ HIF_GDMA_BURST_3_8, ++ HIF_GDMA_BURST_4_8, ++ HIF_GDMA_BURST_5_8, ++ HIF_GDMA_BURST_6_8, ++ HIF_GDMA_BURST_7_8, ++ HIF_GDMA_BURST_8_8 /* same as HIF_GDMA_BURST_7_8 */ ++} MTK_WCN_HIF_GDMA_BURST_LEN; ++ ++typedef enum _MTK_WCN_HIF_GDMA_WRITE_LEN { ++ HIF_GDMA_WRITE_0 = 0, /* transaction size is 1 byte */ ++ HIF_GDMA_WRITE_1, /* transaction size is 2 byte */ ++ HIF_GDMA_WRITE_2, /* transaction size is 4 byte */ ++ HIF_GDMA_WRITE_3 /* transaction size is 1 byte */ ++} MTK_WCN_HIF_GDMA_WRITE_LEN; ++ ++typedef enum _MTK_WCN_HIF_GDMA_RATIO { ++ HIF_GDMA_RATIO_0 = 0, /* 1/2 */ ++ HIF_GDMA_RATIO_1 /* 1/1 */ ++} MTK_WCN_HIF_GDMA_RATIO; ++ ++typedef enum _MTK_WCN_HIF_GDMA_CONNECT { ++ HIF_GDMA_CONNECT_NO = 0, /* no connect */ ++ HIF_GDMA_CONNECT_SET1, /* connect set1 (req/ack) */ ++ HIF_GDMA_CONNECT_SET2, /* connect set2 (req/ack) */ ++ HIF_GDMA_CONNECT_SET3 /* connect set3 (req/ack) */ ++} MTK_WCN_HIF_GDMA_CONNECT; ++ ++/* reference to MT6572_AP_P_DMA_Spec.doc */ ++#define AP_DMA_HIF_BASE 0x11000100 ++ ++#define AP_P_DMA_G_DMA_2_INT_FLAG (0x0000) ++#define AP_P_DMA_G_DMA_2_CON (0x0018) ++#define AP_P_DMA_G_DMA_2_CONNECT (0x0034) ++#define AP_P_DMA_G_DMA_2_LEN1 (0x0024) ++#define AP_P_DMA_G_DMA_2_SRC_ADDR (0x001C) ++#define AP_P_DMA_G_DMA_2_DST_ADDR (0x0020) ++#define AP_P_DMA_G_DMA_2_INT_EN (0x0004) ++#define AP_P_DMA_G_DMA_2_EN (0x0008) ++#define AP_P_DMA_G_DMA_2_RST (0x000C) ++#define AP_P_DMA_G_DMA_2_STOP (0x0010) ++ ++#define AP_DMA_HIF_0_LENGTH 0x0038 ++ ++/* AP_DMA_HIF_0_INT_FLAG */ ++#define ADH_CR_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_INT_EN */ ++#define ADH_CR_INTEN_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_EN */ ++#define ADH_CR_EN BIT(0) ++#define ADH_CR_CONN_BUR_EN BIT(1) ++ ++/* AP_DMA_HIF_0_STOP */ ++#define ADH_CR_PAUSE BIT(1) ++#define ADH_CR_STOP BIT(0) ++ ++/* AP_P_DMA_G_DMA_2_CON */ ++#define ADH_CR_FLAG_FINISH BIT(30) ++#define ADH_CR_RSIZE BITS(28, 29) ++#define ADH_CR_RSIZE_OFFSET 28 ++#define ADH_CR_WSIZE BITS(24, 25) ++#define ADH_CR_WSIZE_OFFSET 24 ++#define ADH_CR_BURST_LEN BITS(16, 18) ++#define ADH_CR_BURST_LEN_OFFSET 16 ++#define ADH_CR_WADDR_FIX_EN BIT(3) ++#define ADH_CR_WADDR_FIX_EN_OFFSET 3 ++#define ADH_CR_RADDR_FIX_EN BIT(4) ++#define ADH_CR_RADDR_FIX_EN_OFFSET 4 ++ ++/* AP_P_DMA_G_DMA_2_CONNECT */ ++#define ADH_CR_RATIO BIT(3) ++#define ADH_CR_RATIO_OFFSET 3 ++#define ADH_CR_DIR BIT(2) ++#define ADH_CR_DIR_OFFSET 2 ++#define ADH_CR_CONNECT BITS(0, 1) ++ ++/* AP_DMA_HIF_0_LEN */ ++#define ADH_CR_LEN BITS(0, 19) ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _HIF_GDMA_H */ ++ ++/* End of hif_gdma.h */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h +new file mode 100644 +index 000000000000..32224e8f17d8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h +@@ -0,0 +1,141 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 ++*/ ++ ++/*! \file "hif_pdma.h" ++ \brief MARCO, definition, structure for PDMA. ++ ++ MARCO, definition, structure for PDMA. ++*/ ++ ++/* ++** Log: hif_pdma.h ++ * ++ * 01 16 2013 vend_samp.lin ++ * Add AHB PDMA support ++ * 1) Initial version ++** ++*/ ++ ++#ifndef _HIF_PDMA_H ++#define _HIF_PDMA_H ++ ++#include "mtk_porting.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _MTK_WCN_HIF_PDMA_BURST_LEN { ++ HIF_PDMA_BURST_1_4 = 0, ++ HIF_PDMA_BURST_2_4, ++ HIF_PDMA_BURST_3_4, ++ HIF_PDMA_BURST_4_4 ++} MTK_WCN_HIF_PDMA_BURST_LEN; ++ ++/* reference to MT6572_AP_P_DMA_Spec.doc */ ++#ifdef CONFIG_OF ++/*for MT6752*/ ++#define AP_DMA_HIF_BASE 0x11000080 ++#else ++/*for MT6572/82/92*/ ++#define AP_DMA_HIF_BASE 0x11000180 ++#endif ++ ++#define AP_DMA_HIF_0_INT_FLAG (0x0000) ++#define AP_DMA_HIF_0_INT_EN (0x0004) ++#define AP_DMA_HIF_0_EN (0x0008) ++#define AP_DMA_HIF_0_RST (0x000C) ++#define AP_DMA_HIF_0_STOP (0x0010) ++#define AP_DMA_HIF_0_FLUSH (0x0014) ++#define AP_DMA_HIF_0_CON (0x0018) ++#define AP_DMA_HIF_0_SRC_ADDR (0x001C) ++#define AP_DMA_HIF_0_DST_ADDR (0x0020) ++#define AP_DMA_HIF_0_LEN (0x0024) ++#define AP_DMA_HIF_0_INT_BUF_SIZE (0x0038) ++#define AP_DMA_HIF_0_DEBUG_STATUS (0x0050) ++#define AP_DMA_HIF_0_SRC_ADDR2 (0x0054) ++#define AP_DMA_HIF_0_DST_ADDR2 (0x0058) ++ ++#define AP_DMA_HIF_0_LENGTH 0x0080 ++ ++/* AP_DMA_HIF_0_INT_FLAG */ ++#define ADH_CR_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_INT_EN */ ++#define ADH_CR_INTEN_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_EN */ ++#define ADH_CR_EN BIT(0) ++ ++/* AP_DMA_HIF_0_RST */ ++#define ADH_CR_HARD_RST BIT(1) ++#define ADH_CR_WARM_RST BIT(0) ++ ++/* AP_DMA_HIF_0_STOP */ ++#define ADH_CR_PAUSE BIT(1) ++#define ADH_CR_STOP BIT(0) ++ ++/* AP_DMA_HIF_0_FLUSH */ ++#define ADH_CR_FLUSH BIT(0) ++ ++/* AP_DMA_HIF_0_CON */ ++#define ADH_CR_BURST_LEN BITS(16, 17) ++#define ADH_CR_BURST_LEN_OFFSET 16 ++#define ADH_CR_SLOW_CNT BITS(5, 14) ++#define ADH_CR_SLOW_EN BIT(2) ++#define ADH_CR_FIX_EN BIT(1) ++#define ADH_CR_FIX_EN_OFFSET 1 ++#define ADH_CR_DIR BIT(0) ++ ++/* AP_DMA_HIF_0_LEN */ ++#define ADH_CR_LEN BITS(0, 19) ++ ++/* AP_DMA_HIF_0_SRC_ADDR2 */ ++#define ADH_CR_SRC_ADDR2 BIT(0) ++/* AP_DMA_HIF_0_DST_ADDR2 */ ++#define ADH_CR_DST_ADDR2 BIT(0) ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _HIF_PDMA_H */ ++ ++/* End of hif_gdma.h */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h +new file mode 100644 +index 000000000000..91557137af9a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h +@@ -0,0 +1,91 @@ ++/* porting layer */ ++/* Android */ ++ ++#ifndef _MTK_PORTING_H_ ++#define _MTK_PORTING_H_ ++ ++#include /* include stddef.h for NULL */ ++ ++#define CONF_MTK_AHB_DMA 1 ++ ++/* Type definition for signed integers */ ++/*typedef signed char INT8, *PINT8; ++typedef signed short INT16, *PINT16; ++typedef signed int INT_32, *PINT32;*/ ++ ++/* Type definition for unsigned integers */ ++/*typedef unsigned char UINT8, *PUINT8; ++typedef unsigned short UINT16, *PUINT16; ++typedef unsigned int UINT32, *PUINT32;*/ ++ ++#ifndef VOID ++/*typedef void VOID, *PVOID;*/ ++#endif ++ ++#ifndef IN ++#define IN ++#endif ++ ++#ifndef OUT ++#define OUT ++#endif ++ ++#ifndef INTOUT ++#define INOUT ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef BIT ++#define BIT(n) ((UINT_32) 1U << (n)) ++#endif /* BIT */ ++ ++#ifndef BITS ++/* bits range: for example BITS(16,23) = 0xFF0000 ++ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 ++ * ==> (BIT(n+1)-1) = 0x00FFFFFF ++ */ ++#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) ++#endif /* BIT */ ++ ++#ifndef BOOLEAN ++#define BOOLEAN unsigned char ++#endif ++ ++typedef int MTK_WCN_BOOL; ++#ifndef MTK_WCN_BOOL_TRUE ++#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) ++#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) ++#endif ++ ++typedef int MTK_WCN_MUTEX; ++ ++typedef int MTK_WCN_TIMER; ++ ++/* system APIs */ ++/* mutex */ ++typedef MTK_WCN_MUTEX(*MUTEX_CREATE) (const char *const name); ++typedef INT_32(*MUTEX_DESTROY) (MTK_WCN_MUTEX mtx); ++typedef INT_32(*MUTEX_LOCK) (MTK_WCN_MUTEX mtx); ++typedef INT_32(*MUTEX_UNLOCK) (MTK_WCN_MUTEX mtx, unsigned long flags); ++/* debug */ ++typedef INT_32(*DBG_PRINT) (const char *str, ...); ++typedef INT_32(*DBG_ASSERT) (INT_32 expr, const char *file, INT_32 line); ++/* timer */ ++typedef void (*MTK_WCN_TIMER_CB) (void); ++typedef MTK_WCN_TIMER(*TIMER_CREATE) (const char *const name); ++typedef INT_32(*TIMER_DESTROY) (MTK_WCN_TIMER tmr); ++typedef INT_32(*TIMER_START) (MTK_WCN_TIMER tmr, UINT_32 timeout, MTK_WCN_TIMER_CB tmr_cb, void *param); ++typedef INT_32(*TIMER_STOP) (MTK_WCN_TIMER tmr); ++/* kernel lib */ ++typedef void *(*SYS_MEMCPY) (void *dest, const void *src, UINT_32 n); ++typedef void *(*SYS_MEMSET) (void *s, INT_32 c, UINT_32 n); ++typedef INT_32(*SYS_SPRINTF) (char *str, const char *format, ...); ++ ++#endif /* _MTK_PORTING_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c +new file mode 100644 +index 000000000000..94cc05ba3224 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c +@@ -0,0 +1,480 @@ ++/****************************************************************************** ++*[File] ahb_pdma.c ++*[Version] v1.0 ++*[Revision Date] 2013-03-13 ++*[Author] ++*[Description] ++* The program provides AHB PDMA driver ++*[Copyright] ++* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. ++******************************************************************************/ ++ ++/* ++** Log: ahb_pdma.c ++ * ++ * 03 13 2013 vend_samp.lin ++ * Add AHB PDMA support ++ * 1) Initial version ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#define MODULE_AHB_DMA ++ ++#include /* constant of kernel version */ ++ ++#include /* bitops.h */ ++ ++#include /* struct timer_list */ ++#include /* jiffies */ ++#include /* udelay and mdelay macro */ ++ ++#if 0 ++#if CONFIG_ANDROID ++#include ++#endif ++#endif ++ ++#include /* IRQT_FALLING */ ++ ++#include /* struct net_device, struct net_device_stats */ ++#include /* for eth_type_trans() function */ ++#include /* struct iw_statistics */ ++#include ++#include /* struct in_device */ ++ ++#include /* struct iphdr */ ++ ++#include /* for memcpy()/memset() function */ ++#include /* for offsetof() macro */ ++ ++#include /* The proc filesystem constants/structures */ ++ ++#include /* for rtnl_lock() and rtnl_unlock() */ ++#include /* kthread_should_stop(), kthread_run() */ ++#include /* for copy_from_user() */ ++#include /* for firmware download */ ++#include ++ ++#include /* for kfifo interface */ ++#include /* for cdev interface */ ++ ++#include /* for firmware download */ ++ ++#include ++ ++#include /* readw and writew */ ++ ++#include ++ ++#if defined(CONFIG_MTK_CLKMGR) ++#include ++#else ++#include ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ ++#include "hif.h" ++#include "hif_pdma.h" ++#include "gl_os.h" ++ ++/* #include */ ++ ++/* #if (CONF_MTK_AHB_DMA == 1) */ ++ ++/* #define PDMA_DEBUG_SUP */ ++ ++#ifdef PDMA_DEBUG_SUP ++#define PDMA_DBG pr_debug ++#else ++#define PDMA_DBG(_fmt, ...) ++#endif /* PDMA_DEBUG_SUP */ ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++struct clk *g_clk_wifi_pdma; ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Conf); ++ ++static VOID HifPdmaStart(IN void *HifInfoSrc); ++ ++static VOID HifPdmaStop(IN void *HifInfoSrc); ++ ++static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc); ++ ++static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc); ++ ++static VOID HifPdmaAckIntr(IN void *HifInfoSrc); ++ ++static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled); ++ ++static VOID HifPdmaRegDump(IN void *HifInfoSrc); ++ ++static VOID HifPdmaReset(IN void *HifInfoSrc); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++GL_HIF_DMA_OPS_T HifPdmaOps = { ++ .DmaConfig = HifPdmaConfig, ++ .DmaStart = HifPdmaStart, ++ .DmaStop = HifPdmaStop, ++ .DmaPollStart = HifPdmaPollStart, ++ .DmaPollIntr = HifPdmaPollIntr, ++ .DmaAckIntr = HifPdmaAckIntr, ++ .DmaClockCtrl = HifPdmaClockCtrl, ++ .DmaRegDump = HifPdmaRegDump, ++ .DmaReset = HifPdmaReset ++}; ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config PDMA TX/RX. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] Conf Pointer to the settings. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo) ++{ ++ /* IO remap PDMA register memory */ ++#ifdef AP_DMA_HIF_BASE ++#undef AP_DMA_HIF_BASE ++#define AP_DMA_HIF_BASE 0x11000180 ++#endif ++ HifInfo->DmaRegBaseAddr = ioremap(AP_DMA_HIF_BASE, AP_DMA_HIF_0_LENGTH); ++ ++ /* assign PDMA operators */ ++ HifInfo->DmaOps = &HifPdmaOps; ++ ++ /* enable PDMA mode */ ++ HifInfo->fgDmaEnable = TRUE; ++ ++ /* Set EMI protection here */ ++#if 0 ++#ifdef MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT ++ DBGLOG(INIT, INFO, "WIFI set EMI MPU for TEE project\n"); ++ emi_mpu_set_region_protection(gConEmiPhyBase, ++ gConEmiPhyBase + SZ_1M / 2, ++ 5, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); ++#else ++ DBGLOG(INIT, INFO, "WIFI set EMI MPU for non-TEE project\n"); ++ emi_mpu_set_region_protection(gConEmiPhyBase, ++ gConEmiPhyBase + SZ_1M / 2, ++ 4, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); ++#endif ++#endif ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ g_clk_wifi_pdma = HifInfo->clk_wifi_dma; ++#endif ++ ++ PDMA_DBG("PDMA> HifPdmaInit ok!\n"); ++} ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* \param[in] Param Pointer to the settings. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Param) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *) Param; ++ UINT32 RegVal; ++ ++ /* Assign fixed value */ ++ Conf->Burst = HIF_PDMA_BURST_4_4; /* vs. HIF_BURST_4DW */ ++ Conf->Fix_en = FALSE; ++ ++ /* AP_P_DMA_G_DMA_2_CON */ ++ PDMA_DBG("PDMA> Conf->Dir = %d\n", Conf->Dir); ++ ++ /* AP_DMA_HIF_0_CON */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_CON); ++ RegVal &= ~(ADH_CR_BURST_LEN | ADH_CR_FIX_EN | ADH_CR_DIR); ++ RegVal |= (((Conf->Burst << ADH_CR_BURST_LEN_OFFSET) & ADH_CR_BURST_LEN) | ++ (Conf->Fix_en << ADH_CR_FIX_EN_OFFSET) | (Conf->Dir)); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_CON, RegVal); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_CON = 0x%08x\n", RegVal); ++ ++ /* AP_DMA_HIF_0_SRC_ADDR */ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_SRC_ADDR, Conf->Src); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_SRC_ADDR = 0x%08lx\n", Conf->Src); ++ ++ /* AP_DMA_HIF_0_DST_ADDR */ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_DST_ADDR, Conf->Dst); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_DST_ADDR = 0x%08lx\n", Conf->Dst); ++ ++ /* AP_DMA_HIF_0_LEN */ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_LEN, (Conf->Count & ADH_CR_LEN)); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_LEN = %u\n", (UINT_32)(Conf->Count & ADH_CR_LEN)); ++ ++} /* End of HifPdmaConfig */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Start PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaStart(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ /* Enable interrupt */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0)); ++ ++ /* Start DMA */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_EN, (RegVal | ADH_CR_EN)); ++ ++ PDMA_DBG("PDMA> HifPdmaStart...\n"); ++ ++} /* End of HifPdmaStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Stop PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaStop(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++/* UINT32 pollcnt; */ ++ ++ /* Disable interrupt */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal & ~(ADH_CR_INTEN_FLAG_0))); ++ ++#if 0 /* DE says we donot need to do it */ ++ /* Stop DMA */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_STOP); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_STOP, (RegVal | ADH_CR_STOP)); ++ ++ /* Polling START bit turn to 0 */ ++ pollcnt = 0; ++ do { ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); ++ if (pollcnt++ > 100000) ++ ; /* TODO: warm reset PDMA */ ++ } while (RegVal & ADH_CR_EN); ++#endif ++ ++} /* End of HifPdmaStop */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Enable PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); ++ return ((RegVal & ADH_CR_EN) != 0) ? TRUE : FALSE; ++ ++} /* End of HifPdmaPollStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Poll PDMA TX/RX done. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); ++ return ((RegVal & ADH_CR_FLAG_0) != 0) ? TRUE : FALSE; ++ ++} /* End of HifPdmaPollIntr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Acknowledge PDMA TX/RX done. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaAckIntr(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ /* Write 0 to clear interrupt */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0)); ++ ++} /* End of HifPdmaAckIntr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Acknowledge PDMA TX/RX done. ++* ++* \param[in] FlgIsEnabled TRUE: enable; FALSE: disable ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled) ++{ ++#if !defined(CONFIG_MTK_CLKMGR) ++ int ret = 0; ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++ if (FlgIsEnabled == TRUE) ++ enable_clock(MT_CG_INFRA_APDMA, "WLAN"); ++ else ++ disable_clock(MT_CG_INFRA_APDMA, "WLAN"); ++#else ++ if (FlgIsEnabled == TRUE) { ++ ret = clk_prepare_enable(g_clk_wifi_pdma); ++ if (ret) ++ DBGLOG(INIT, TRACE, "[CCF]clk_prepare_enable ret= %d\n", ret); ++ } else { ++ clk_disable_unprepare(g_clk_wifi_pdma); ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dump PDMA related registers. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaRegDump(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegId, RegVal; ++ UINT32 RegNum = 0; ++ ++ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE); ++ for (RegId = 0; RegId < AP_DMA_HIF_0_LENGTH; RegId += 4) { ++ RegVal = HIF_DMAR_READL(HifInfo, RegId); ++ DBGLOG(INIT, INFO, "0x%08x ", RegVal); ++ ++ if (RegNum++ >= 3) { ++ DBGLOG(INIT, INFO, "\n"); ++ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE + RegId + 4); ++ RegNum = 0; ++ } ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Reset DMA. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaReset(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 LoopCnt; ++ ++ /* do warm reset: DMA will wait for current traction finished */ ++ DBGLOG(INIT, INFO, "\nDMA> do warm reset...\n"); ++ ++ /* normally, we need to sure that bit0 of AP_P_DMA_G_DMA_2_EN is 1 here */ ++ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x01); ++ ++ for (LoopCnt = 0; LoopCnt < 10000; LoopCnt++) { ++ if (!HifPdmaPollStart(HifInfo)) ++ break; /* reset ok */ ++ } ++ ++ if (HifPdmaPollStart(HifInfo)) { ++ /* do hard reset because warm reset fails */ ++ DBGLOG(INIT, INFO, "\nDMA> do hard reset...\n"); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x02); ++ mdelay(1); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x00); ++ } ++} ++ ++/* #endif */ /* CONF_MTK_AHB_DMA */ ++ ++/* End of ahb_pdma.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h +new file mode 100644 +index 000000000000..ec9f46bdab2e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h +@@ -0,0 +1,341 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_cfg80211.h#1 ++*/ ++ ++/*! \file gl_cfg80211.h ++ \brief This file is for Portable Driver linux cfg80211 support. ++*/ ++ ++/* ++** Log: gl_cfg80211.h ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++*/ ++ ++#ifndef _GL_CFG80211_H ++#define _GL_CFG80211_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++ ++#include "gl_os.h" ++extern void wlanHandleSystemResume(void); ++extern void wlanHandleSystemSuspend(void); ++extern void p2pHandleSystemResume(void); ++extern void p2pHandleSystemSuspend(void); ++ ++#if CFG_SUPPORT_WAPI ++extern UINT_8 keyStructBuf[1024]; /* add/remove key shared buffer */ ++#else ++extern UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ ++#endif ++ ++extern struct delayed_work sched_workq; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#if CONFIG_NL80211_TESTMODE ++#define NL80211_DRIVER_TESTMODE_VERSION 2 ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++#if CONFIG_NL80211_TESTMODE ++ ++typedef struct _NL80211_DRIVER_GET_STA_STATISTICS_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 u4Version; ++ UINT_32 u4Flag; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++} NL80211_DRIVER_GET_STA_STATISTICS_PARAMS, *P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS; ++ ++typedef struct _NL80211_DRIVER_POORLINK_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ INT_8 cRssi; /* cRssi=0 means it is a invalid value. */ ++ UINT_8 ucLinkSpeed; /* ucLinkSpeed=0 means it is a invalid value */ ++ UINT_16 u2Reserved; ++} NL80211_DRIVER_POORLINK_PARAMS, *P_NL80211_DRIVER_POORLINK_PARAMS; ++ ++typedef enum _ENUM_TESTMODE_STA_STATISTICS_ATTR { ++ NL80211_TESTMODE_STA_STATISTICS_INVALID = 0, ++ NL80211_TESTMODE_STA_STATISTICS_VERSION, ++ NL80211_TESTMODE_STA_STATISTICS_MAC, ++ NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, ++ NL80211_TESTMODE_STA_STATISTICS_FLAG, ++ ++ NL80211_TESTMODE_STA_STATISTICS_PER, ++ NL80211_TESTMODE_STA_STATISTICS_RSSI, ++ NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, ++ NL80211_TESTMODE_STA_STATISTICS_TX_RATE, ++ ++ NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, ++ ++ NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, ++ NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, ++ NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, ++ NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, ++ ++ NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, ++ ++ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, ++ ++ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, ++ ++ /* ++ * how many packages TX during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, ++ ++ /* ++ * how many packages this TX during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, ++ ++ /* ++ * how many packages dequeue during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, ++ ++ /* ++ * how many packages this sta dequeue during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, ++ ++ /* ++ * how many TC[0-3] resource back from firmware during ++ * statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, ++ ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, ++ ++ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, ++ ++ NL80211_TESTMODE_STA_STATISTICS_NUM ++} ENUM_TESTMODE_STA_STATISTICS_ATTR; ++typedef struct _NL80211_DRIVER_SET_NFC_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 NFC_Enable; ++ ++} NL80211_DRIVER_SET_NFC_PARAMS, *P_NL80211_DRIVER_SET_NFC_PARAMS; ++typedef struct _NL80211_DRIVER_GET_SCANDONE_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 u4ScanDone; ++ ++} NL80211_DRIVER_GET_SCANDONE_PARAMS, *P_NL80211_DRIVER_GET_SCANDONE_PARAMS; ++ ++typedef enum _ENUM_TESTMODE_LINK_DETECTION_ATTR { ++ NL80211_TESTMODE_LINK_INVALID = 0, ++ NL80211_TESTMODE_LINK_TX_FAIL_CNT, ++ NL80211_TESTMODE_LINK_TX_RETRY_CNT, ++ NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, ++ NL80211_TESTMODE_LINK_ACK_FAIL_CNT, ++ NL80211_TESTMODE_LINK_FCS_ERR_CNT, ++ ++ NL80211_TESTMODE_LINK_DETECT_NUM, ++} ENUM_TESTMODE_LINK_DETECTION_ATTR; ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++typedef struct _NL80211_DRIVER_GET_LTE_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 u4Version; ++ UINT_32 u4Flag; ++ ++} NL80211_DRIVER_GET_LTE_PARAMS, *P_NL80211_DRIVER_GET_LTE_PARAMS; ++ ++/*typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR{ ++ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, ++ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ ++ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, ++}ENUM_TESTMODE_AVAILABLE_CHAN_ATTR;*/ ++ ++#endif ++#endif ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* cfg80211 hooks */ ++int ++mtk_cfg80211_change_iface(struct wiphy *wiphy, ++ struct net_device *ndev, enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); ++ ++int ++mtk_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); ++ ++int ++mtk_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) ++); ++ ++int ++mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); ++ ++int ++mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast); ++ ++int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); ++ ++int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo); ++ ++int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params); ++ ++int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params); ++ ++int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params); ++//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac); ++ ++int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); ++ ++int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme); ++ ++int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code); ++ ++int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params); ++ ++int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev); ++ ++int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout); ++ ++int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); ++ ++int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); ++ ++int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev); ++ ++int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, ++ unsigned int duration, u64 *cookie); ++ ++int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); ++ ++int ++mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie); ++ ++void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, ++ IN struct wireless_dev *wdev, ++ IN u16 frame_type, IN bool reg); ++ ++int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); ++ ++int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req); ++ ++int ++mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, ++ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request); ++ ++int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev,u64 reqid); ++ ++#if CONFIG_NL80211_TESTMODE ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++WLAN_STATUS ++wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++int ++mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); ++#endif ++int ++mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, ++ IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); ++ ++int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); ++ ++int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); ++ ++int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#if CFG_SUPPORT_WAPI ++int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++#else ++#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" ++#endif ++int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); ++int mtk_cfg80211_resume(struct wiphy *wiphy); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_CFG80211_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h +new file mode 100644 +index 000000000000..512e149abf75 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h +@@ -0,0 +1,1565 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_kal.h#1 ++*/ ++ ++/*! \file gl_kal.h ++ \brief Declaration of KAL functions - kal*() which is provided by GLUE Layer. ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/* ++** Log: gl_kal.h ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 02 06 2012 wh.su ++ * [WCXRP00001177] [MT6620 Wi-Fi][Driver][2.2] Adding the query channel filter for AP mode ++ * adding the channel query filter for AP mode. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adjust the code for Non-DBG and no XLOG. ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to asynchronous ++ * approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state without join ++ * timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Using the new XLOG define for dum Memory. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters, eCurPsProf, for PS. ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Add dumpMemory8 at XLOG support. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated ++ * network type ++ * include link.h for linux's port. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated ++ * network type ++ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected ++ * ++ * 04 01 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface ++ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR ++ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW table. ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep ++ * long enough for specified interval such as 500ms ++ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system ++ * scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 12 31 2010 jeffrey.chang ++ * [WCXRP00000332] [MT6620 Wi-Fi][Driver] add kal sleep function for delay which use blocking call ++ * modify the implementation of kalDelay to msleep ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 26 2010 cp.wu ++ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field ++ * checking ++ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used ++ * to indicate user is attached ++ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * add a kal function for set cipher. ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * fixed compiling error while enable p2p. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at win XP. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * modify kalSetEvent declaration ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * simplify post-handling after TX_DONE interrupt is handled. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * fix kal header file ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * use different spin lock for security frame ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * add new spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add kal api for scanning done ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * modify cmd/data path for new design ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add new kal api ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * gl_kal merged ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * fill network type field while doing frame identification. ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * modify kalMemAlloc method ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when acquiring driver-own, wait for up to 8 seconds. ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL ++ * * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler ++ * * * * * * * * * * * * * * * * * * * capability ++ * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) add spinlock ++ * * * 2) add KAPI for handling association info ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding firmware download KAPI ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * * * * are now handled in glue layer ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * * * * 2) add 2 kal API for later integration ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download KAPI ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\41 2009-09-28 20:19:23 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\40 2009-08-18 22:57:09 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\39 2009-06-23 23:19:15 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\38 2009-02-09 14:03:17 GMT mtk01090 ++** Add KAL function kalDevSetPowerState(). It is not implemented yet. Only add an empty macro. ++** ++** \main\maintrunk.MT5921\37 2009-01-22 13:05:59 GMT mtk01088 ++** new defeine to got 1x value at packet reserved field ++** \main\maintrunk.MT5921\36 2008-12-08 16:15:02 GMT mtk01461 ++** Add kalQueryValidBufferLength() macro ++** \main\maintrunk.MT5921\35 2008-11-13 20:33:15 GMT mtk01104 ++** Remove lint warning ++** \main\maintrunk.MT5921\34 2008-10-22 11:05:52 GMT mtk01461 ++** Remove unused macro ++** \main\maintrunk.MT5921\33 2008-10-16 15:48:17 GMT mtk01461 ++** Update driver to fix lint warning ++** \main\maintrunk.MT5921\32 2008-09-02 11:50:51 GMT mtk01461 ++** SPIN_LOCK_SDIO_DDK_TX_QUE ++** \main\maintrunk.MT5921\31 2008-08-29 15:58:30 GMT mtk01088 ++** remove non-used function for code refine ++** \main\maintrunk.MT5921\30 2008-08-21 00:33:29 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\29 2008-06-19 13:29:14 GMT mtk01425 ++** 1. Add declaration of SPIN_LOCK_SDIO_DDK_TX_QUE and SPIN_LOCK_SDIO_DDK_RX_QUE ++** \main\maintrunk.MT5921\28 2008-05-30 20:27:34 GMT mtk01461 ++** Rename KAL function ++** \main\maintrunk.MT5921\27 2008-05-30 14:42:05 GMT mtk01461 ++** Remove WMM Assoc Flag in KAL ++** \main\maintrunk.MT5921\26 2008-05-29 14:15:18 GMT mtk01084 ++** remove un-used function ++** \main\maintrunk.MT5921\25 2008-04-23 14:02:20 GMT mtk01084 ++** modify KAL port access function prototype ++** \main\maintrunk.MT5921\24 2008-04-17 23:06:41 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\23 2008-04-08 15:38:50 GMT mtk01084 ++** add KAL function to setting pattern search function enable/ disable ++** \main\maintrunk.MT5921\22 2008-03-26 15:34:48 GMT mtk01461 ++** Add update MAC address func ++** \main\maintrunk.MT5921\21 2008-03-18 15:56:15 GMT mtk01084 ++** update ENUM_NIC_INITIAL_PARAM_E ++** \main\maintrunk.MT5921\20 2008-03-18 11:49:28 GMT mtk01084 ++** update function for initial value access ++** \main\maintrunk.MT5921\19 2008-03-18 10:21:31 GMT mtk01088 ++** use kal update associate request at linux ++** \main\maintrunk.MT5921\18 2008-03-14 18:03:41 GMT mtk01084 ++** refine register and port access function ++** \main\maintrunk.MT5921\17 2008-03-11 14:51:02 GMT mtk01461 ++** Add copy_to(from)_user macro ++** \main\maintrunk.MT5921\16 2008-03-06 23:42:21 GMT mtk01385 ++** 1. add Query Registry Mac address function. ++** \main\maintrunk.MT5921\15 2008-02-26 09:48:04 GMT mtk01084 ++** modify KAL set network address/ checksum offload part ++** \main\maintrunk.MT5921\14 2008-01-09 17:54:58 GMT mtk01084 ++** Modify the argument of kalQueryPacketInfo ++** \main\maintrunk.MT5921\13 2007-11-29 02:05:20 GMT mtk01461 ++** Fix Windows RX multiple packet retain problem ++** \main\maintrunk.MT5921\12 2007-11-26 19:43:45 GMT mtk01461 ++** Add OS_TIMESTAMP macro ++** ++** \main\maintrunk.MT5921\11 2007-11-09 16:36:15 GMT mtk01425 ++** 1. Modify for CSUM offloading with Tx Fragment ++** \main\maintrunk.MT5921\10 2007-11-07 18:38:37 GMT mtk01461 ++** Add Tx Fragmentation Support ++** \main\maintrunk.MT5921\9 2007-11-06 19:36:50 GMT mtk01088 ++** add the WPS related code ++** \main\maintrunk.MT5921\8 2007-11-02 01:03:57 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** Revision 1.4 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:50 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:23 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++#ifndef _GL_KAL_H ++#define _GL_KAL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "config.h" ++#include "gl_typedef.h" ++#include "gl_os.h" ++#include "link.h" ++#include "nic/mac.h" ++#include "nic/wlan_def.h" ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "gl_wext_priv.h" ++#include ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#include "nic/bow.h" ++#endif ++ ++#if DBG ++extern int allocatedMemSize; ++#endif ++ ++#if CFG_SUPPORT_MET_PROFILING ++#include "linux/kallsyms.h" ++#include ++#endif ++ ++extern BOOLEAN fgIsUnderSuspend; ++extern UINT_32 TaskIsrCnt; ++extern BOOLEAN fgIsResetting; ++extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); ++extern UINT_32 u4MemAllocCnt, u4MemFreeCnt; ++ ++ ++extern struct delayed_work sched_workq; ++ ++#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT ++extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* #define USEC_PER_MSEC (1000) */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_SPIN_LOCK_CATEGORY_E { ++ SPIN_LOCK_FSM = 0, ++ ++ /* FIX ME */ ++ SPIN_LOCK_RX_QUE, ++ SPIN_LOCK_TX_QUE, ++ SPIN_LOCK_CMD_QUE, ++ SPIN_LOCK_TX_RESOURCE, ++ SPIN_LOCK_CMD_RESOURCE, ++ SPIN_LOCK_QM_TX_QUEUE, ++ SPIN_LOCK_CMD_PENDING, ++ SPIN_LOCK_CMD_SEQ_NUM, ++ SPIN_LOCK_TX_MSDU_INFO_LIST, ++ SPIN_LOCK_TXING_MGMT_LIST, ++ SPIN_LOCK_TX_SEQ_NUM, ++ SPIN_LOCK_TX_COUNT, ++ SPIN_LOCK_TXS_COUNT, ++ /* end */ ++ SPIN_LOCK_TX, ++ SPIN_LOCK_IO_REQ, ++ SPIN_LOCK_INT, ++ ++ SPIN_LOCK_MGT_BUF, ++ SPIN_LOCK_MSG_BUF, ++ SPIN_LOCK_STA_REC, ++ ++ SPIN_LOCK_MAILBOX, ++ SPIN_LOCK_TIMER, ++ ++ SPIN_LOCK_BOW_TABLE, ++ ++ SPIN_LOCK_EHPI_BUS, /* only for EHPI */ ++ SPIN_LOCK_NET_DEV, ++ SPIN_LOCK_NUM ++} ENUM_SPIN_LOCK_CATEGORY_E; ++ ++/* event for assoc information update */ ++typedef struct _EVENT_ASSOC_INFO { ++ UINT_8 ucAssocReq; /* 1 for assoc req, 0 for assoc rsp */ ++ UINT_8 ucReassoc; /* 0 for assoc, 1 for reassoc */ ++ UINT_16 u2Length; ++ PUINT_8 pucIe; ++} EVENT_ASSOC_INFO, *P_EVENT_ASSOC_INFO; ++ ++typedef enum _ENUM_KAL_NETWORK_TYPE_INDEX_T { ++ KAL_NETWORK_TYPE_AIS_INDEX = 0, ++#if CFG_ENABLE_WIFI_DIRECT ++ KAL_NETWORK_TYPE_P2P_INDEX, ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ KAL_NETWORK_TYPE_BOW_INDEX, ++#endif ++ KAL_NETWORK_TYPE_INDEX_NUM ++} ENUM_KAL_NETWORK_TYPE_INDEX_T; ++ ++typedef enum _ENUM_KAL_MEM_ALLOCATION_TYPE_E { ++ PHY_MEM_TYPE, /* physically continuous */ ++ VIR_MEM_TYPE, /* virtually continuous */ ++ MEM_TYPE_NUM ++} ENUM_KAL_MEM_ALLOCATION_TYPE; ++ ++#if CONFIG_ANDROID /* Defined in Android kernel source */ ++typedef struct wake_lock KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; ++#else ++typedef UINT_32 KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; ++#endif ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++typedef enum _ENUM_MTK_AGPS_ATTR { ++ MTK_ATTR_AGPS_INVALID, ++ MTK_ATTR_AGPS_CMD, ++ MTK_ATTR_AGPS_DATA, ++ MTK_ATTR_AGPS_IFINDEX, ++ MTK_ATTR_AGPS_IFNAME, ++ MTK_ATTR_AGPS_MAX ++} ENUM_MTK_CCX_ATTR; ++ ++typedef enum _ENUM_AGPS_EVENT { ++ AGPS_EVENT_WLAN_ON, ++ AGPS_EVENT_WLAN_OFF, ++ AGPS_EVENT_WLAN_AP_LIST, ++ WIFI_EVENT_CHIP_RESET, ++} ENUM_CCX_EVENT; ++BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen); ++#endif ++ ++struct KAL_HALT_CTRL_T { ++ struct semaphore lock; ++ struct task_struct *owner; ++ BOOLEAN fgHalt; ++ BOOLEAN fgHeldByKalIoctl; ++ OS_SYSTIME u4HoldStart; ++}; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros of bit operation */ ++/*----------------------------------------------------------------------------*/ ++#define KAL_SET_BIT(bitOffset, value) set_bit(bitOffset, &value) ++#define KAL_CLR_BIT(bitOffset, value) clear_bit(bitOffset, &value) ++#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value) test_and_clear_bit(bitOffset, &value) ++#define KAL_TEST_BIT(bitOffset, value) test_bit(bitOffset, &value) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros of SPIN LOCK operations for using in Driver Layer */ ++/*----------------------------------------------------------------------------*/ ++#define KAL_SPIN_LOCK_DECLARATION() unsigned long __u4Flags ++ ++#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory) \ ++ kalAcquireSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, &__u4Flags) ++ ++#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory) \ ++ kalReleaseSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, __u4Flags) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for accessing Reserved Fields of native packet */ ++/*----------------------------------------------------------------------------*/ ++#define KAL_GET_PKT_QUEUE_ENTRY(_p) GLUE_GET_PKT_QUEUE_ENTRY(_p) ++#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry) GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) ++#define KAL_GET_PKT_TID(_p) GLUE_GET_PKT_TID(_p) ++#define KAL_GET_PKT_IS1X(_p) GLUE_GET_PKT_IS1X(_p) ++#define KAL_GET_PKT_HEADER_LEN(_p) GLUE_GET_PKT_HEADER_LEN(_p) ++#define KAL_GET_PKT_PAYLOAD_LEN(_p) GLUE_GET_PKT_PAYLOAD_LEN(_p) ++#define KAL_GET_PKT_ARRIVAL_TIME(_p) GLUE_GET_PKT_ARRIVAL_TIME(_p) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros of wake_lock operations for using in Driver Layer */ ++/*----------------------------------------------------------------------------*/ ++#if CONFIG_ANDROID /* Defined in Android kernel source */ ++#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ ++ wake_lock_init(_prWakeLock, WAKE_LOCK_SUSPEND, _pcName) ++ ++#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ ++ wake_lock_destroy(_prWakeLock) ++ ++#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \ ++ wake_lock(_prWakeLock) ++ ++#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \ ++ wake_lock_timeout(_prWakeLock, _u4Timeout) ++ ++#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \ ++ wake_unlock(_prWakeLock) ++ ++#else ++#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) ++#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) ++#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) ++#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) ++#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Cache memory allocation ++* ++* \param[in] u4Size Required memory size. ++* \param[in] eMemType Memory allocation type ++* ++* \return Pointer to allocated memory ++* or NULL ++*/ ++/*----------------------------------------------------------------------------*/ ++#if DBG ++#define kalMemAlloc(u4Size, eMemType) ({ \ ++ void *pvAddr; \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ ++ } \ ++ else { \ ++ pvAddr = vmalloc(u4Size); \ ++ } \ ++ if (pvAddr) { \ ++ allocatedMemSize += u4Size; \ ++ DBGLOG(INIT, INFO, "%p(%u) allocated (%s:%s)\n", \ ++ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ ++ } \ ++ pvAddr; \ ++}) ++#else ++#define kalMemAlloc(u4Size, eMemType) ({ \ ++ void *pvAddr; \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ ++ } \ ++ else { \ ++ pvAddr = vmalloc(u4Size); \ ++ } \ ++ pvAddr; \ ++}) ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Free allocated cache memory ++* ++* \param[in] pvAddr Required memory size. ++* \param[in] eMemType Memory allocation type ++* \param[in] u4Size Allocated memory size. ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++#if DBG ++#define kalMemFree(pvAddr, eMemType, u4Size) \ ++{ \ ++ if (pvAddr) { \ ++ allocatedMemSize -= u4Size; \ ++ DBGLOG(INIT, INFO, "%p(%u) freed (%s:%s)\n", \ ++ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ ++ } \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ kfree(pvAddr); \ ++ } \ ++ else { \ ++ vfree(pvAddr); \ ++ } \ ++} ++#else ++#define kalMemFree(pvAddr, eMemType, u4Size) \ ++{ \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ kfree(pvAddr); \ ++ } \ ++ else { \ ++ vfree(pvAddr); \ ++ } \ ++} ++#endif ++ ++#define kalUdelay(u4USec) udelay(u4USec) ++ ++#define kalMdelay(u4MSec) mdelay(u4MSec) ++#define kalMsleep(u4MSec) msleep(u4MSec) ++ ++/* Copy memory from user space to kernel space */ ++#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N) copy_from_user(_pvTo, _pvFrom, _u4N) ++ ++/* Copy memory from kernel space to user space */ ++#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N) copy_to_user(_pvTo, _pvFrom, _u4N) ++ ++/* Copy memory block with specific size */ ++#define kalMemCopy(pvDst, pvSrc, u4Size) memcpy(pvDst, pvSrc, u4Size) ++ ++/* Set memory block with specific pattern */ ++#define kalMemSet(pvAddr, ucPattern, u4Size) memset(pvAddr, ucPattern, u4Size) ++ ++/* Compare two memory block with specific length. ++ * Return zero if they are the same. ++ */ ++#define kalMemCmp(pvAddr1, pvAddr2, u4Size) memcmp(pvAddr1, pvAddr2, u4Size) ++ ++/* Zero specific memory block */ ++#define kalMemZero(pvAddr, u4Size) memset(pvAddr, 0, u4Size) ++ ++/* string operation */ ++#define kalStrCpy(dest, src) strcpy(dest, src) ++#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) ++#define kalStrCmp(ct, cs) strcmp(ct, cs) ++#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) ++#define kalStrChr(s, c) strchr(s, c) ++#define kalStrrChr(s, c) strrchr(s, c) ++#define kalStrnChr(s, n, c) strnchr(s, n, c) ++#define kalStrLen(s) strlen(s) ++#define kalStrnLen(s, b) strnlen(s, b) ++//#define kalStrniCmp(s1, s2, n) strnicmp(s1, s2, n) ++#define kalStrniCmp(s1, s2, n) strncasecmp(s1, s2, n) ++#define strnicmp(s1, s2, n) strncasecmp(s1, s2, n) ++/* #define kalStrtoul(cp, endp, base) simple_strtoul(cp, endp, base) ++#define kalStrtol(cp, endp, base) simple_strtol(cp, endp, base) */ ++#define kalkStrtou32(cp, base, resp) kstrtou32(cp, base, resp) ++#define kalkStrtos32(cp, base, resp) kstrtos32(cp, base, resp) ++#define kalSnprintf(buf, size, fmt, ...) snprintf(buf, size, fmt, __VA_ARGS__) ++#define kalSprintf(buf, fmt, ...) sprintf(buf, fmt, __VA_ARGS__) ++/* remove for AOSP */ ++/* #define kalSScanf(buf, fmt, ...) sscanf(buf, fmt, __VA_ARGS__) */ ++#define kalStrStr(ct, cs) strstr(ct, cs) ++#define kalStrSep(s, ct) strsep(s, ct) ++#define kalStrCat(dest, src) strcat(dest, src) ++ ++/* defined for wince sdio driver only */ ++#if defined(_HIF_SDIO) ++#define kalDevSetPowerState(prGlueInfo, ePowerMode) glSetPowerState(prGlueInfo, ePowerMode) ++#else ++#define kalDevSetPowerState(prGlueInfo, ePowerMode) ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Notify OS with SendComplete event of the specific packet. Linux should ++* free packets here. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* \param[in] status Status Code for OS upper layer ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalSendComplete(prGlueInfo, pvPacket, status) \ ++ kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket) ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to locate the starting address of incoming ethernet ++* frame for skb. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* ++* \return starting address of ethernet frame buffer. ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalQueryBufferPointer(prGlueInfo, pvPacket) \ ++ ((PUINT_8)((struct sk_buff *)pvPacket)->data) ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to query the length of valid buffer which is accessible during ++* port read/write. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* ++* \return starting address of ethernet frame buffer. ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalQueryValidBufferLength(prGlueInfo, pvPacket) \ ++ ((UINT_32)((struct sk_buff *)pvPacket)->end - \ ++ (UINT_32)((struct sk_buff *)pvPacket)->data) ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to copy the entire frame from skb to the destination ++* address in the input parameter. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* \param[in] pucDestBuffer Destination Address ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer) \ ++ do {struct sk_buff *skb = (struct sk_buff *)pvPacket; \ ++ memcpy(pucDestBuffer, skb->data, skb->len); } while (0) ++ ++#define kalGetTimeTick() jiffies_to_msecs(jiffies) ++ ++#define kalPrint pr_debug ++ ++#if !DBG ++#define AIS_ERROR_LOGFUNC(_Fmt...) ++#define AIS_WARN_LOGFUNC(_Fmt...) ++#define AIS_INFO_LOGFUNC(_Fmt...) ++#define AIS_STATE_LOGFUNC(_Fmt...) ++#define AIS_EVENT_LOGFUNC(_Fmt...) ++#define AIS_TRACE_LOGFUNC(_Fmt...) ++#define AIS_LOUD_LOGFUNC(_Fmt...) ++#define AIS_TEMP_LOGFUNC(_Fmt...) ++ ++#define INTR_ERROR_LOGFUNC(_Fmt...) ++#define INTR_WARN_LOGFUNC(_Fmt...) ++#define INTR_INFO_LOGFUNC(_Fmt...) ++#define INTR_STATE_LOGFUNC(_Fmt...) ++#define INTR_EVENT_LOGFUNC(_Fmt...) ++#define INTR_TRACE_LOGFUNC(_Fmt...) ++#define INTR_LOUD_LOGFUNC(_Fmt...) ++#define INTR_TEMP_LOGFUNC(_Fmt...) ++ ++#define INIT_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_TRACE_LOGFUNC(_Fmt...) ++#define INIT_LOUD_LOGFUNC(_Fmt...) ++#define INIT_TEMP_LOGFUNC(_Fmt...) ++ ++#define AAA_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_LOUD_LOGFUNC(_Fmt...) ++#define AAA_TEMP_LOGFUNC(_Fmt...) ++ ++#define ROAMING_ERROR_LOGFUNC(_Fmt...) ++#define ROAMING_WARN_LOGFUNC(_Fmt...) ++#define ROAMING_INFO_LOGFUNC(_Fmt...) ++#define ROAMING_STATE_LOGFUNC(_Fmt...) ++#define ROAMING_EVENT_LOGFUNC(_Fmt...) ++#define ROAMING_TRACE_LOGFUNC(_Fmt...) ++#define ROAMING_LOUD_LOGFUNC(_Fmt...) ++#define ROAMING_TEMP_LOGFUNC(_Fmt...) ++ ++#define REQ_ERROR_LOGFUNC(_Fmt...) ++#define REQ_WARN_LOGFUNC(_Fmt...) ++#define REQ_INFO_LOGFUNC(_Fmt...) ++#define REQ_STATE_LOGFUNC(_Fmt...) ++#define REQ_EVENT_LOGFUNC(_Fmt...) ++#define REQ_TRACE_LOGFUNC(_Fmt...) ++#define REQ_LOUD_LOGFUNC(_Fmt...) ++#define REQ_TEMP_LOGFUNC(_Fmt...) ++ ++#define TX_ERROR_LOGFUNC(_Fmt...) ++#define TX_WARN_LOGFUNC(_Fmt...) ++#define TX_INFO_LOGFUNC(_Fmt...) ++#define TX_STATE_LOGFUNC(_Fmt...) ++#define TX_EVENT_LOGFUNC(_Fmt...) ++#define TX_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TX_LOUD_LOGFUNC(_Fmt...) ++#define TX_TEMP_LOGFUNC(_Fmt...) ++ ++#define RX_ERROR_LOGFUNC(_Fmt...) ++#define RX_WARN_LOGFUNC(_Fmt...) ++#define RX_INFO_LOGFUNC(_Fmt...) ++#define RX_STATE_LOGFUNC(_Fmt...) ++#define RX_EVENT_LOGFUNC(_Fmt...) ++#define RX_TRACE_LOGFUNC(_Fmt...) ++#define RX_LOUD_LOGFUNC(_Fmt...) ++#define RX_TEMP_LOGFUNC(_Fmt...) ++ ++#define RFTEST_ERROR_LOGFUNC(_Fmt...) ++#define RFTEST_WARN_LOGFUNC(_Fmt...) ++#define RFTEST_INFO_LOGFUNC(_Fmt...) ++#define RFTEST_STATE_LOGFUNC(_Fmt...) ++#define RFTEST_EVENT_LOGFUNC(_Fmt...) ++#define RFTEST_TRACE_LOGFUNC(_Fmt...) ++#define RFTEST_LOUD_LOGFUNC(_Fmt...) ++#define RFTEST_TEMP_LOGFUNC(_Fmt...) ++ ++#define EMU_ERROR_LOGFUNC(_Fmt...) ++#define EMU_WARN_LOGFUNC(_Fmt...) ++#define EMU_INFO_LOGFUNC(_Fmt...) ++#define EMU_STATE_LOGFUNC(_Fmt...) ++#define EMU_EVENT_LOGFUNC(_Fmt...) ++#define EMU_TRACE_LOGFUNC(_Fmt...) ++#define EMU_LOUD_LOGFUNC(_Fmt...) ++#define EMU_TEMP_LOGFUNC(_Fmt...) ++ ++#define HEM_ERROR_LOGFUNC(_Fmt...) ++#define HEM_WARN_LOGFUNC(_Fmt...) ++#define HEM_INFO_LOGFUNC(_Fmt...) ++#define HEM_STATE_LOGFUNC(_Fmt...) ++#define HEM_EVENT_LOGFUNC(_Fmt...) ++#define HEM_TRACE_LOGFUNC(_Fmt...) ++#define HEM_LOUD_LOGFUNC(_Fmt...) ++#define HEM_TEMP_LOGFUNC(_Fmt...) ++ ++#define RLM_ERROR_LOGFUNC(_Fmt...) ++#define RLM_WARN_LOGFUNC(_Fmt...) ++#define RLM_INFO_LOGFUNC(_Fmt...) ++#define RLM_STATE_LOGFUNC(_Fmt...) ++#define RLM_EVENT_LOGFUNC(_Fmt...) ++#define RLM_TRACE_LOGFUNC(_Fmt...) ++#define RLM_LOUD_LOGFUNC(_Fmt...) ++#define RLM_TEMP_LOGFUNC(_Fmt...) ++ ++#define MEM_ERROR_LOGFUNC(_Fmt...) ++#define MEM_WARN_LOGFUNC(_Fmt...) ++#define MEM_INFO_LOGFUNC(_Fmt...) ++#define MEM_STATE_LOGFUNC(_Fmt...) ++#define MEM_EVENT_LOGFUNC(_Fmt...) ++#define MEM_TRACE_LOGFUNC(_Fmt...) ++#define MEM_LOUD_LOGFUNC(_Fmt...) ++#define MEM_TEMP_LOGFUNC(_Fmt...) ++ ++#define CNM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define CNM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define CNM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define CNM_STATE_LOGFUNC(_Fmt...) ++#define CNM_EVENT_LOGFUNC(_Fmt...) ++#define CNM_TRACE_LOGFUNC(_Fmt...) ++#define CNM_LOUD_LOGFUNC(_Fmt...) ++#define CNM_TEMP_LOGFUNC(_Fmt...) ++ ++#define RSN_ERROR_LOGFUNC(_Fmt...) ++#define RSN_WARN_LOGFUNC(_Fmt...) ++#define RSN_INFO_LOGFUNC(_Fmt...) ++#define RSN_STATE_LOGFUNC(_Fmt...) ++#define RSN_EVENT_LOGFUNC(_Fmt...) ++#define RSN_TRACE_LOGFUNC(_Fmt...) ++#define RSN_LOUD_LOGFUNC(_Fmt...) ++#define RSN_TEMP_LOGFUNC(_Fmt...) ++ ++#define BSS_ERROR_LOGFUNC(_Fmt...) ++#define BSS_WARN_LOGFUNC(_Fmt...) ++#define BSS_INFO_LOGFUNC(_Fmt...) ++#define BSS_STATE_LOGFUNC(_Fmt...) ++#define BSS_EVENT_LOGFUNC(_Fmt...) ++#define BSS_TRACE_LOGFUNC(_Fmt...) ++#define BSS_LOUD_LOGFUNC(_Fmt...) ++#define BSS_TEMP_LOGFUNC(_Fmt...) ++ ++#define SCN_ERROR_LOGFUNC(_Fmt...) ++#define SCN_WARN_LOGFUNC(_Fmt...) ++#define SCN_INFO_LOGFUNC(_Fmt...) ++#define SCN_STATE_LOGFUNC(_Fmt...) ++#define SCN_EVENT_LOGFUNC(_Fmt...) ++#define SCN_TRACE_LOGFUNC(_Fmt...) ++#define SCN_LOUD_LOGFUNC(_Fmt...) ++#define SCN_TEMP_LOGFUNC(_Fmt...) ++ ++#define SAA_ERROR_LOGFUNC(_Fmt...) ++#define SAA_WARN_LOGFUNC(_Fmt...) ++#define SAA_INFO_LOGFUNC(_Fmt...) ++#define SAA_STATE_LOGFUNC(_Fmt...) ++#define SAA_EVENT_LOGFUNC(_Fmt...) ++#define SAA_TRACE_LOGFUNC(_Fmt...) ++#define SAA_LOUD_LOGFUNC(_Fmt...) ++#define SAA_TEMP_LOGFUNC(_Fmt...) ++ ++#define P2P_ERROR_LOGFUNC(_Fmt...) ++#define P2P_WARN_LOGFUNC(_Fmt...) ++#define P2P_INFO_LOGFUNC(_Fmt...) ++#define P2P_STATE_LOGFUNC(_Fmt...) ++#define P2P_EVENT_LOGFUNC(_Fmt...) ++#define P2P_TRACE_LOGFUNC(_Fmt...) ++#define P2P_LOUD_LOGFUNC(_Fmt...) ++#define P2P_TEMP_LOGFUNC(_Fmt...) ++ ++#define QM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_STATE_LOGFUNC(_Fmt...) ++#define QM_EVENT_LOGFUNC(_Fmt...) ++#define QM_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_LOUD_LOGFUNC(_Fmt...) ++#define QM_TEMP_LOGFUNC(_Fmt...) ++ ++#define SEC_ERROR_LOGFUNC(_Fmt...) ++#define SEC_WARN_LOGFUNC(_Fmt...) ++#define SEC_INFO_LOGFUNC(_Fmt...) ++#define SEC_STATE_LOGFUNC(_Fmt...) ++#define SEC_EVENT_LOGFUNC(_Fmt...) ++#define SEC_TRACE_LOGFUNC(_Fmt...) ++#define SEC_LOUD_LOGFUNC(_Fmt...) ++#define SEC_TEMP_LOGFUNC(_Fmt...) ++ ++#define BOW_ERROR_LOGFUNC(_Fmt...) ++#define BOW_WARN_LOGFUNC(_Fmt...) ++#define BOW_INFO_LOGFUNC(_Fmt...) ++#define BOW_STATE_LOGFUNC(_Fmt...) ++#define BOW_EVENT_LOGFUNC(_Fmt...) ++#define BOW_TRACE_LOGFUNC(_Fmt...) ++#define BOW_LOUD_LOGFUNC(_Fmt...) ++#define BOW_TEMP_LOGFUNC(_Fmt...) ++ ++#define HAL_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define HAL_WARN_LOGFUNC(_Fmt...) ++#define HAL_INFO_LOGFUNC(_Fmt...) ++#define HAL_STATE_LOGFUNC(_Fmt...) ++#define HAL_EVENT_LOGFUNC(_Fmt...) ++#define HAL_TRACE_LOGFUNC(_Fmt...) ++#define HAL_LOUD_LOGFUNC(_Fmt...) ++#define HAL_TEMP_LOGFUNC(_Fmt...) ++ ++#define WAPI_ERROR_LOGFUNC(_Fmt...) ++#define WAPI_WARN_LOGFUNC(_Fmt...) ++#define WAPI_INFO_LOGFUNC(_Fmt...) ++#define WAPI_STATE_LOGFUNC(_Fmt...) ++#define WAPI_EVENT_LOGFUNC(_Fmt...) ++#define WAPI_TRACE_LOGFUNC(_Fmt...) ++#define WAPI_LOUD_LOGFUNC(_Fmt...) ++#define WAPI_TEMP_LOGFUNC(_Fmt...) ++ ++#define TDLS_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TDLS_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TDLS_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TDLS_STATE_LOGFUNC(_Fmt...) ++#define TDLS_EVENT_LOGFUNC(_Fmt...) ++#define TDLS_TRACE_LOGFUNC(_Fmt...) ++#define TDLS_LOUD_LOGFUNC(_Fmt...) ++#define TDLS_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW1_ERROR_LOGFUNC(_Fmt...) ++#define SW1_WARN_LOGFUNC(_Fmt...) ++#define SW1_INFO_LOGFUNC(_Fmt...) ++#define SW1_STATE_LOGFUNC(_Fmt...) ++#define SW1_EVENT_LOGFUNC(_Fmt...) ++#define SW1_TRACE_LOGFUNC(_Fmt...) ++#define SW1_LOUD_LOGFUNC(_Fmt...) ++#define SW1_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW2_ERROR_LOGFUNC(_Fmt...) ++#define SW2_WARN_LOGFUNC(_Fmt...) ++#define SW2_INFO_LOGFUNC(_Fmt...) ++#define SW2_STATE_LOGFUNC(_Fmt...) ++#define SW2_EVENT_LOGFUNC(_Fmt...) ++#define SW2_TRACE_LOGFUNC(_Fmt...) ++#define SW2_LOUD_LOGFUNC(_Fmt...) ++#define SW2_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW3_ERROR_LOGFUNC(_Fmt...) ++#define SW3_WARN_LOGFUNC(_Fmt...) ++#define SW3_INFO_LOGFUNC(_Fmt...) ++#define SW3_STATE_LOGFUNC(_Fmt...) ++#define SW3_EVENT_LOGFUNC(_Fmt...) ++#define SW3_TRACE_LOGFUNC(_Fmt...) ++#define SW3_LOUD_LOGFUNC(_Fmt...) ++#define SW3_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW4_ERROR_LOGFUNC(_Fmt...) ++#define SW4_WARN_LOGFUNC(_Fmt...) ++#define SW4_INFO_LOGFUNC(_Fmt...) ++#define SW4_STATE_LOGFUNC(_Fmt...) ++#define SW4_EVENT_LOGFUNC(_Fmt...) ++#define SW4_TRACE_LOGFUNC(_Fmt...) ++#define SW4_LOUD_LOGFUNC(_Fmt...) ++#define SW4_TEMP_LOGFUNC(_Fmt...) ++#endif ++ ++#define kalBreakPoint() \ ++do { \ ++ BUG(); \ ++ panic("Oops"); \ ++} while (0) ++ ++#if CFG_ENABLE_AEE_MSG ++#define kalSendAeeException aee_kernel_exception ++#define kalSendAeeWarning aee_kernel_warning ++#define kalSendAeeReminding aee_kernel_reminding ++#else ++#define kalSendAeeException(_module, _desc, ...) ++#define kalSendAeeWarning(_module, _desc, ...) ++#define kalSendAeeReminding(_module, _desc, ...) ++#endif ++ ++#define PRINTF_ARG(...) __VA_ARGS__ ++#define SPRINTF(buf, arg) {buf += sprintf((char *)(buf), PRINTF_ARG arg); } ++ ++#define USEC_TO_SYSTIME(_usec) ((_usec) / USEC_PER_MSEC) ++#define MSEC_TO_SYSTIME(_msec) (_msec) ++ ++#define MSEC_TO_JIFFIES(_msec) msecs_to_jiffies(_msec) ++ ++#define KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE 3000 /* 3s */ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in gl_kal.c */ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags); ++ ++VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags); ++ ++VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr); ++ ++VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); ++ ++PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData); ++ ++VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler); ++ ++BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN OS_SYSTIME rInterval); ++ ++WLAN_STATUS ++kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, ++ /* IN PBOOLEAN pfgIsRetain, */ ++ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aeCSUM[] ++); ++ ++WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum); ++ ++VOID ++kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen); ++ ++VOID ++kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); ++ ++VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen); ++ ++#if CFG_TX_FRAGMENT ++BOOLEAN ++kalQueryTxPacketHeader(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvPacket, OUT PUINT_16 pu2EtherTypeLen, OUT PUINT_8 pucEthDestAddr); ++#endif /* CFG_TX_FRAGMENT */ ++ ++VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag); ++ ++VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T eCSUM[] ++); ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr); ++ ++VOID ++kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs); ++ ++VOID ++kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum); ++ ++VOID ++kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); ++ ++VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines in interface - ehpi/sdio.c */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalDevRegRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value); ++ ++BOOLEAN kalDevRegWrite(P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value); ++ ++BOOLEAN ++kalDevPortRead(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_16 u2Port, IN UINT_32 u2Len, OUT PUINT_8 pucBuf, IN UINT_32 u2ValidOutBufSize); ++ ++BOOLEAN ++kalDevPortWrite(P_GLUE_INFO_T prGlueInfo, ++ IN UINT_16 u2Port, IN UINT_32 u2Len, IN PUINT_8 pucBuf, IN UINT_32 u2ValidInBufSize); ++ ++BOOLEAN kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData); ++ ++void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo); ++ ++#if CFG_SUPPORT_EXT_CONFIG ++UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo); ++#endif ++ ++BOOLEAN ++kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_NATIVE_PACKET prPacket, ++ OUT PUINT_8 pucPriorityParam, ++ OUT PUINT_32 pu4PacketLen, ++ OUT PUINT_8 pucEthDestAddr, ++ OUT PBOOLEAN pfgIs1X, ++ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, ++ OUT PVOID prGenUse); ++ ++VOID ++kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, ++ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus); ++ ++WLAN_STATUS ++kalIoctl(IN P_GLUE_INFO_T prGlueInfo, ++ IN PFN_OID_HANDLER_FUNC pfnOidHandler, ++ IN PVOID pvInfoBuf, ++ IN UINT_32 u4InfoBufLen, ++ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen); ++ ++VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ ++PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength); ++ ++VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* Card Removal Check */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* TX */ ++/*----------------------------------------------------------------------------*/ ++VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Media State Indication */ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID handling */ ++/*----------------------------------------------------------------------------*/ ++VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry); ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++/*----------------------------------------------------------------------------*/ ++/* Bluetooth over Wi-Fi handling */ ++/*----------------------------------------------------------------------------*/ ++VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent); ++ ++ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); ++ ++BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, PARAM_MAC_ADDRESS rPeerAddr); ++ ++ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); ++ ++VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr); ++ ++UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo); ++ ++#if CFG_BOW_SEPARATE_DATA_PATH ++/*----------------------------------------------------------------------------*/ ++/* Bluetooth over Wi-Fi Net Device Init/Uninit */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName); ++ ++BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo); ++#endif /* CFG_BOW_SEPARATE_DATA_PATH */ ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++/*----------------------------------------------------------------------------*/ ++/* Firmware Download Handling */ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Security Frame Clearance */ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Management Frame Clearance */ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval); ++ ++BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status); ++ ++UINT_32 kalRandomNumber(VOID); ++ ++VOID kalTimeoutHandler(ULONG arg); ++ ++VOID kalSetEvent(P_GLUE_INFO_T pr); ++ ++/*----------------------------------------------------------------------------*/ ++/* NVRAM/Registry Service */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo); ++ ++P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PUINT_16 pu2Part1CfgOwnVersion, ++ OUT PUINT_16 pu2Part1CfgPeerVersion, ++ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion); ++ ++BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data); ++ ++BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, IN UINT_16 u2Data); ++ ++/*----------------------------------------------------------------------------*/ ++/* WSC Connection */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* RSSI Updating */ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); ++ ++/*----------------------------------------------------------------------------*/ ++/* I/O Buffer Pre-allocation */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitIOBuffer(VOID); ++ ++VOID kalUninitIOBuffer(VOID); ++ ++PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize); ++ ++VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size); ++ ++VOID ++kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); ++ ++BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo); ++ ++ULONG kalIOPhyAddrGet(IN ULONG VirtAddr); ++ ++VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr); ++ ++#if CFG_SUPPORT_802_11W ++/*----------------------------------------------------------------------------*/ ++/* 802.11W */ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo); ++#endif ++ ++UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size); ++ ++/*----------------------------------------------------------------------------*/ ++/* NL80211 */ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBuf, IN UINT_32 u4BufLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength); ++ ++/*----------------------------------------------------------------------------*/ ++/* PNO Support */ ++/*----------------------------------------------------------------------------*/ ++VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++int tx_thread(void *data); ++ ++VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo); ++VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb); ++VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo); ++int kalMetRemoveProcfs(void); ++ ++UINT_64 kalGetBootTime(void); ++ ++INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize); ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter); ++#endif ++INT_32 kalHaltLock(UINT_32 waitMs); ++INT_32 kalHaltTryLock(VOID); ++VOID kalHaltUnlock(VOID); ++VOID kalSetHalted(BOOLEAN fgHalt); ++BOOLEAN kalIsHalted(VOID); ++ ++INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo); ++VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++INT32 kalBoostCpu(UINT_32 core_num); ++ ++#endif /* _GL_KAL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h +new file mode 100644 +index 000000000000..a4321e7f9a11 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h +@@ -0,0 +1,1270 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_os.h#2 ++*/ ++ ++/*! \file gl_os.h ++ \brief List the external reference to OS for GLUE Layer. ++ ++ In this file we define the data structure - GLUE_INFO_T to store those objects ++ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the ++ external reference (header file, extern func() ..) to OS for GLUE Layer should ++ also list down here. ++*/ ++ ++/* ++** Log: gl_os.h ++** ++** 08 20 2012 yuche.tsai ++** NULL ++** Fix possible KE issue. ++** ++** 08 20 2012 yuche.tsai ++** [ALPS00339327] [Rose][6575JB][BSP Package][Free Test][KE][WIFI]There is no response when you tap the turn off/on ++** button,wait a minutes, the device will reboot automatically and "KE" will pop up. ++** Fix possible KE when netlink operate mgmt frame register. ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Enable CFG80211 Support. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 16 2011 yuche.tsai ++ * NULL ++ * Avoid using work thread. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 29 2011 terry.wu ++ * NULL ++ * Show DRV_NAME by chip id. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 02 21 2011 cp.wu ++ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain ++ * simplify logic for checking NVRAM existence only once. ++ * ++ * 02 16 2011 jeffrey.chang ++ * NULL ++ * Add query ipv4 and ipv6 address during early suspend and late resume ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module with structure miss-align ++ * pointer issue ++ * always pre-allio WAPI related structure for align p2p module. ++ * ++ * 02 09 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * Halt p2p module init and exit until TxThread finished p2p register and unregister. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 27 2011 cm.chang ++ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default ++ * . ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation ++ * needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 01 11 2011 chinglan.wang ++ * NULL ++ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish ++ * successfully. ++ * Use the WPS function to connect AP, the privacy bit always is set to 1. ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues ++ * due to multiple access ++ * use mutex to protect kalIoctl() for thread safe. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 09 13 2010 cp.wu ++ * NULL ++ * add waitq for poll() and read(). ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * revised implementation of Wi-Fi Direct io controls. ++ * ++ * 08 11 2010 cp.wu ++ * NULL ++ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) ++ * 2) extending scanning result to 64 instead of 48 ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * add new KAL api ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * modify tx thread and remove some spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add security frame pending count ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl to configure scan mode for p2p connection ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * prevent supplicant accessing driver during resume ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * 05 05 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change variable names for multiple physical link to match with coding convention ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) fix firmware download bug ++ * 2) remove query statistics for acelerating firmware download ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * supporting power management ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * pvInformationBuffer and u4InformationBufferLength are no longer in glue ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple ++ * * * * * * * * * * * * * * * * * * * * handler capability ++ * * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other ++ * * * * * * * * * * * * * * * * * * * * purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * * * * are done in adapter layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Tag the packet for QoS on Tx path ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)deliver the kalOidComplete status to upper layer ++ * * (2) fix spin lock ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add timeout check in the kalOidComplete ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download related data type ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * * * * the frequency is used for adhoc connection only ++ * * * * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add Bluetooth-over-Wifi frame header check ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\30 2009-10-20 17:38:31 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\29 2009-10-08 10:33:33 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input ++** parameters and pointers. ++** \main\maintrunk.MT5921\28 2009-09-28 20:19:26 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\27 2009-08-18 22:57:12 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\26 2009-07-06 21:42:25 GMT mtk01088 ++** fixed the compiling error at linux ++** \main\maintrunk.MT5921\25 2009-07-06 20:51:46 GMT mtk01088 ++** adding the wapi 1x ether type define ++** \main\maintrunk.MT5921\24 2009-06-23 23:19:18 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\23 2009-02-07 15:05:06 GMT mtk01088 ++** add the privacy flag to ingo driver the supplicant selected ap's security ++** \main\maintrunk.MT5921\22 2009-02-05 15:34:09 GMT mtk01088 ++** fixed the compiling error for using bits marco for only one parameter ++** \main\maintrunk.MT5921\21 2009-01-22 13:02:13 GMT mtk01088 ++** data frame is or not 802.1x value share with tid, using the same reserved byte, provide the function to set and get ++** \main\maintrunk.MT5921\20 2008-10-24 12:04:16 GMT mtk01088 ++** move the config.h from precomp.h to here for lint check ++** \main\maintrunk.MT5921\19 2008-09-22 23:19:02 GMT mtk01461 ++** Update driver for code review ++** \main\maintrunk.MT5921\18 2008-09-05 17:25:13 GMT mtk01461 ++** Update Driver for Code Review ++** \main\maintrunk.MT5921\17 2008-08-01 13:32:47 GMT mtk01084 ++** Prevent redundent driver assertion in driver logic when BUS is detached ++** \main\maintrunk.MT5921\16 2008-05-30 14:41:43 GMT mtk01461 ++** Remove WMM Assoc Flag in KAL ++** \main\maintrunk.MT5921\15 2008-05-29 14:16:25 GMT mtk01084 ++** remoev un-used variable ++** \main\maintrunk.MT5921\14 2008-05-03 15:17:14 GMT mtk01461 ++** Add Media Status variable in Glue Layer ++** \main\maintrunk.MT5921\13 2008-04-24 11:58:41 GMT mtk01461 ++** change threshold to 256 ++** \main\maintrunk.MT5921\12 2008-03-11 14:51:05 GMT mtk01461 ++** Remove redundant GL_CONN_INFO_T ++** \main\maintrunk.MT5921\11 2008-01-07 15:07:41 GMT mtk01461 ++** Adjust the netif stop threshold to 150 ++** \main\maintrunk.MT5921\10 2007-11-26 19:43:46 GMT mtk01461 ++** Add OS_TIMESTAMP macro ++** ++** \main\maintrunk.MT5921\9 2007-11-07 18:38:38 GMT mtk01461 ++** Move definition ++** \main\maintrunk.MT5921\8 2007-11-02 01:04:00 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** Revision 1.5 2007/07/12 11:04:28 MTK01084 ++** update macro to delay for ms order ++** ++** Revision 1.4 2007/07/05 07:25:34 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++#ifndef _GL_OS_H ++#define _GL_OS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++/*------------------------------------------------------------------------------ ++ * Flags for LINUX(OS) dependent ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_MAX_WLAN_DEVICES 1 /* number of wlan card will coexist */ ++ ++#define CFG_MAX_TXQ_NUM 4 /* number of tx queue for support multi-queue h/w */ ++ ++#define CFG_USE_SPIN_LOCK_BOTTOM_HALF 0 /* 1: Enable use of SPIN LOCK Bottom Half for LINUX ++ 0: Disable - use SPIN LOCK IRQ SAVE instead */ ++ ++#define CFG_TX_PADDING_SMALL_ETH_PACKET 0 /* 1: Enable - Drop ethernet packet if it < 14 bytes. ++ And pad ethernet packet with dummy 0 if it < 60 bytes. ++ 0: Disable */ ++ ++#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD 256 /* packets */ ++ ++#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 256 /* packets */ ++#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 128 /* packets */ ++ ++#define ETH_P_1X 0x888E ++#define IPTOS_PREC_OFFSET 5 ++#define USER_PRIORITY_DEFAULT 0 ++ ++#define ETH_WPI_1X 0x88B4 ++ ++#define ETH_HLEN 14 ++#define ETH_TYPE_LEN_OFFSET 12 ++#define ETH_P_IP 0x0800 ++#define ETH_P_1X 0x888E ++#define ETH_P_PRE_1X 0x88C7 ++#define ETH_P_ARP 0x0806 ++ ++#define ARP_PRO_REQ 1 ++#define ARP_PRO_RSP 2 ++ ++#define IPVERSION 4 ++#define IP_HEADER_LEN 20 ++ ++#define IP_PRO_ICMP 0x01 ++#define IP_PRO_UDP 0x11 ++#define IP_PRO_TCP 0x06 ++ ++#define UDP_PORT_DHCPS 0x43 ++#define UDP_PORT_DHCPC 0x44 ++#define UDP_PORT_DNS 0x35 ++ ++#define IPVH_VERSION_OFFSET 4 /* For Little-Endian */ ++#define IPVH_VERSION_MASK 0xF0 ++#define IPTOS_PREC_OFFSET 5 ++#define IPTOS_PREC_MASK 0xE0 ++ ++#define SOURCE_PORT_LEN 2 ++/* NOTE(Kevin): Without IP Option Length */ ++#define LOOK_AHEAD_LEN (ETH_HLEN + IP_HEADER_LEN + SOURCE_PORT_LEN) ++ ++/* 802.2 LLC/SNAP */ ++#define ETH_LLC_OFFSET (ETH_HLEN) ++#define ETH_LLC_LEN 3 ++#define ETH_LLC_DSAP_SNAP 0xAA ++#define ETH_LLC_SSAP_SNAP 0xAA ++#define ETH_LLC_CONTROL_UNNUMBERED_INFORMATION 0x03 ++ ++/* Bluetooth SNAP */ ++#define ETH_SNAP_OFFSET (ETH_HLEN + ETH_LLC_LEN) ++#define ETH_SNAP_LEN 5 ++#define ETH_SNAP_BT_SIG_OUI_0 0x00 ++#define ETH_SNAP_BT_SIG_OUI_1 0x19 ++#define ETH_SNAP_BT_SIG_OUI_2 0x58 ++ ++#define BOW_PROTOCOL_ID_SECURITY_FRAME 0x0003 ++ ++#if defined(MT6620) ++#define CHIP_NAME "MT6620" ++#elif defined(MT6628) ++#define CHIP_NAME "MT6582" ++#endif ++ ++#define DRV_NAME "["CHIP_NAME"]: " ++ ++#define CONFIG_ANDROID 1 ++/* Define if target platform is Android. ++ * It should already be defined in Android kernel source ++ */ ++ ++/* for CFG80211 IE buffering mechanism */ ++#define CFG_CFG80211_IE_BUF_LEN (512) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include /* constant of kernel version */ ++ ++#include /* bitops.h */ ++ ++#include /* struct timer_list */ ++#include /* jiffies */ ++#include /* udelay and mdelay macro */ ++ ++#if CONFIG_ANDROID ++#include ++#endif ++ ++#include /* IRQT_FALLING */ ++ ++#include /* struct net_device, struct net_device_stats */ ++#include /* for eth_type_trans() function */ ++#include /* struct iw_statistics */ ++#include ++#include /* struct in_device */ ++ ++#include /* struct iphdr */ ++ ++#include /* for memcpy()/memset() function */ ++#include /* for offsetof() macro */ ++ ++#include /* The proc filesystem constants/structures */ ++ ++#include /* for rtnl_lock() and rtnl_unlock() */ ++#include /* kthread_should_stop(), kthread_run() */ ++#include /* for copy_from_user() */ ++#include /* for firmware download */ ++#include ++ ++#include /* for kfifo interface */ ++#include /* for cdev interface */ ++ ++#include /* for firmware download */ ++ ++#if defined(_HIF_SDIO) ++#include ++#include ++#endif ++ ++#include ++ ++#include ++#include ++ ++#include /* readw and writew */ ++ ++#if WIRELESS_EXT > 12 ++#include ++#endif ++ ++#include "version.h" ++#include "config.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#include ++#endif ++ ++#include ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++#include ++#endif ++ ++#include "gl_typedef.h" ++#include "typedef.h" ++#include "queue.h" ++#include "gl_kal.h" ++#include "hif.h" ++#if CFG_CHIP_RESET_SUPPORT ++#include "gl_rst.h" ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++#include "tdls_extr.h" ++#endif ++#include "debug.h" ++ ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++ ++#if CFG_ENABLE_AEE_MSG ++#include ++#endif ++ ++extern BOOLEAN fgIsBusAccessFailed; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define GLUE_FLAG_HALT BIT(0) ++#define GLUE_FLAG_INT BIT(1) ++#define GLUE_FLAG_OID BIT(2) ++#define GLUE_FLAG_TIMEOUT BIT(3) ++#define GLUE_FLAG_TXREQ BIT(4) ++#define GLUE_FLAG_SUB_MOD_INIT BIT(5) ++#define GLUE_FLAG_SUB_MOD_EXIT BIT(6) ++#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7) ++#define GLUE_FLAG_FRAME_FILTER BIT(8) ++#define GLUE_FLAG_FRAME_FILTER_AIS BIT(9) ++#define GLUE_FLAG_HIF_LOOPBK_AUTO BIT(10) ++#define GLUE_FLAG_HALT_BIT (0) ++#define GLUE_FLAG_INT_BIT (1) ++#define GLUE_FLAG_OID_BIT (2) ++#define GLUE_FLAG_TIMEOUT_BIT (3) ++#define GLUE_FLAG_TXREQ_BIT (4) ++#define GLUE_FLAG_SUB_MOD_INIT_BIT (5) ++#define GLUE_FLAG_SUB_MOD_EXIT_BIT (6) ++#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7) ++#define GLUE_FLAG_FRAME_FILTER_BIT (8) ++#define GLUE_FLAG_FRAME_FILTER_AIS_BIT (9) ++#define GLUE_FLAG_HIF_LOOPBK_AUTO_BIT (10) ++ ++#define GLUE_BOW_KFIFO_DEPTH (1024) ++/* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ ++#define GLUE_BOW_DEVICE_NAME "ampc0" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _GL_WPA_INFO_T { ++ UINT_32 u4WpaVersion; ++ UINT_32 u4KeyMgmt; ++ UINT_32 u4CipherGroup; ++ UINT_32 u4CipherPairwise; ++ UINT_32 u4AuthAlg; ++ BOOLEAN fgPrivacyInvoke; ++#if CFG_SUPPORT_802_11W ++ UINT_32 u4Mfp; ++#endif ++} GL_WPA_INFO_T, *P_GL_WPA_INFO_T; ++ ++typedef enum _ENUM_RSSI_TRIGGER_TYPE { ++ ENUM_RSSI_TRIGGER_NONE, ++ ENUM_RSSI_TRIGGER_GREATER, ++ ENUM_RSSI_TRIGGER_LESS, ++ ENUM_RSSI_TRIGGER_TRIGGERED, ++ ENUM_RSSI_TRIGGER_NUM ++} ENUM_RSSI_TRIGGER_TYPE; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++typedef enum _ENUM_SUB_MODULE_IDX_T { ++ P2P_MODULE = 0, ++ SUB_MODULE_NUM ++} ENUM_SUB_MODULE_IDX_T; ++ ++typedef enum _ENUM_NET_REG_STATE_T { ++ ENUM_NET_REG_STATE_UNREGISTERED, ++ ENUM_NET_REG_STATE_REGISTERING, ++ ENUM_NET_REG_STATE_REGISTERED, ++ ENUM_NET_REG_STATE_UNREGISTERING, ++ ENUM_NET_REG_STATE_NUM ++} ENUM_NET_REG_STATE_T; ++ ++#endif ++ ++typedef struct _GL_IO_REQ_T { ++ QUE_ENTRY_T rQueEntry; ++ /* wait_queue_head_t cmdwait_q; */ ++ BOOLEAN fgRead; ++ BOOLEAN fgWaitResp; ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsP2pOid; ++#endif ++ P_ADAPTER_T prAdapter; ++ PFN_OID_HANDLER_FUNC pfnOidHandler; ++ PVOID pvInfoBuf; ++ UINT_32 u4InfoBufLen; ++ PUINT_32 pu4QryInfoLen; ++ WLAN_STATUS rStatus; ++ UINT_32 u4Flag; ++} GL_IO_REQ_T, *P_GL_IO_REQ_T; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++typedef struct _GL_BOW_INFO { ++ BOOLEAN fgIsRegistered; ++ dev_t u4DeviceNumber; /* dynamic device number */ ++/* struct kfifo *prKfifo; */ /* for buffering indicated events */ ++ struct kfifo rKfifo; /* for buffering indicated events */ ++ spinlock_t rSpinLock; /* spin lock for kfifo */ ++ struct cdev cdev; ++ UINT_32 u4FreqInKHz; /* frequency */ ++ ++ UINT_8 aucRole[CFG_BOW_PHYSICAL_LINK_NUM]; /* 0: Responder, 1: Initiator */ ++ ENUM_BOW_DEVICE_STATE aeState[CFG_BOW_PHYSICAL_LINK_NUM]; ++ PARAM_MAC_ADDRESS arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM]; ++ ++ wait_queue_head_t outq; ++ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ /* Device handle */ ++ struct net_device *prDevHandler; ++ BOOLEAN fgIsNetRegistered; ++#endif ++ ++} GL_BOW_INFO, *P_GL_BOW_INFO; ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++typedef struct _TDLS_INFO_LINK_T { ++ /* start time when link is built, end time when link is broken */ ++ unsigned long jiffies_start, jiffies_end; ++ ++ /* the peer MAC */ ++ UINT8 aucPeerMac[6]; ++ ++ /* broken reason */ ++ UINT8 ucReasonCode; ++ ++ /* TRUE: torn down is triggerred by us */ ++ UINT8 fgIsFromUs; ++ ++ /* duplicate count; same reason */ ++ UINT8 ucDupCount; ++ ++ /* HT capability */ ++#define TDLS_INFO_LINK_HT_CAP_SUP 0x01 ++ UINT8 ucHtCap; ++#define TDLS_INFO_LINK_HT_BA_SETUP 0x01 ++#define TDLS_INFO_LINK_HT_BA_SETUP_OK 0x02 ++#define TDLS_INFO_LINK_HT_BA_SETUP_DECLINE 0x04 ++#define TDLS_INFO_LINK_HT_BA_PEER 0x10 ++#define TDLS_INFO_LINK_HT_BA_RSP_OK 0x20 ++#define TDLS_INFO_LINK_HT_BA_RSP_DECLINE 0x40 ++ UINT8 ucHtBa[8]; /* TID0 ~ TID7 */ ++} TDLS_INFO_LINK_T; ++ ++typedef struct _TDLS_INFO_T { ++ /* link history */ ++#define TDLS_LINK_HISTORY_MAX 30 ++ TDLS_INFO_LINK_T rLinkHistory[TDLS_LINK_HISTORY_MAX]; ++ UINT32 u4LinkIdx; ++ ++ /* TRUE: support 20/40 bandwidth in TDLS link */ ++ BOOLEAN fgIs2040Sup; ++ ++ /* total TDLS link count */ ++ INT8 cLinkCnt; ++} TDLS_INFO_T; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++/* ++* type definition of pointer to p2p structure ++*/ ++typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; ++ ++struct _GLUE_INFO_T { ++ /* Device handle */ ++ struct net_device *prDevHandler; ++ ++ /* Device Index(index of arWlanDevInfo[]) */ ++ INT_32 i4DevIdx; ++ ++ /* Device statistics */ ++ struct net_device_stats rNetDevStats; ++ ++ /* Wireless statistics struct net_device */ ++ struct iw_statistics rIwStats; ++ ++ /* spinlock to sync power save mechanism */ ++ spinlock_t rSpinLock[SPIN_LOCK_NUM]; ++ ++ /* semaphore for ioctl */ ++ struct semaphore ioctl_sem; ++ ++ UINT_64 u8Cookie; ++ ++ ULONG ulFlag; /* GLUE_FLAG_XXX */ ++ UINT_32 u4PendFlag; ++ /* UINT_32 u4TimeoutFlag; */ ++ UINT_32 u4OidCompleteFlag; ++ UINT_32 u4ReadyFlag; /* check if card is ready */ ++ ++ UINT_32 u4OsMgmtFrameFilter; ++ ++ /* Number of pending frames, also used for debuging if any frame is ++ * missing during the process of unloading Driver. ++ * ++ * NOTE(Kevin): In Linux, we also use this variable as the threshold ++ * for manipulating the netif_stop(wake)_queue() func. ++ */ ++ INT_32 ai4TxPendingFrameNumPerQueue[4][CFG_MAX_TXQ_NUM]; ++ INT_32 i4TxPendingFrameNum; ++ INT_32 i4TxPendingSecurityFrameNum; ++ ++ /* current IO request for kalIoctl */ ++ GL_IO_REQ_T OidEntry; ++ ++ /* registry info */ ++ REG_INFO_T rRegInfo; ++ ++ /* firmware */ ++ struct firmware *prFw; ++ ++ /* Host interface related information */ ++ /* defined in related hif header file */ ++ GL_HIF_INFO_T rHifInfo; ++ ++ /*! \brief wext wpa related information */ ++ GL_WPA_INFO_T rWpaInfo; ++ ++ /* Pointer to ADAPTER_T - main data structure of internal protocol stack */ ++ P_ADAPTER_T prAdapter; ++ ++#ifdef WLAN_INCLUDE_PROC ++ struct proc_dir_entry *pProcRoot; ++#endif /* WLAN_INCLUDE_PROC */ ++ ++ /* Indicated media state */ ++ ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicated; ++ ++ /* Device power state D0~D3 */ ++ PARAM_DEVICE_POWER_STATE ePowerState; ++ ++ struct completion rScanComp; /* indicate scan complete */ ++ struct completion rHaltComp; /* indicate main thread halt complete */ ++ struct completion rPendComp; /* indicate main thread halt complete */ ++#if CFG_ENABLE_WIFI_DIRECT ++ struct completion rSubModComp; /*indicate sub module init or exit complete */ ++#endif ++ WLAN_STATUS rPendStatus; ++ ++ QUE_T rTxQueue; ++ ++ /* OID related */ ++ QUE_T rCmdQueue; ++ /* PVOID pvInformationBuffer; */ ++ /* UINT_32 u4InformationBufferLength; */ ++ /* PVOID pvOidEntry; */ ++ /* PUINT_8 pucIOReqBuff; */ ++ /* QUE_T rIOReqQueue; */ ++ /* QUE_T rFreeIOReqQueue; */ ++ ++ wait_queue_head_t waitq; ++ struct task_struct *main_thread; ++ ++ struct timer_list tickfn; ++ ++#if CFG_SUPPORT_EXT_CONFIG ++ UINT_16 au2ExtCfg[256]; /* NVRAM data buffer */ ++ UINT_32 u4ExtCfgLength; /* 0 means data is NOT valid */ ++#endif ++ ++#if 1 /* CFG_SUPPORT_WAPI */ ++ /* Should be large than the PARAM_WAPI_ASSOC_INFO_T */ ++ UINT_8 aucWapiAssocInfoIEs[42]; ++ UINT_16 u2WapiAssocInfoIESz; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ GL_BOW_INFO rBowInfo; ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ P_GL_P2P_INFO_T prP2PInfo; ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ /* Wireless statistics struct net_device */ ++ struct iw_statistics rP2pIwStats; ++#endif ++#endif ++ BOOLEAN fgWpsActive; ++ UINT_8 aucWSCIE[500]; /*for probe req */ ++ UINT_16 u2WSCIELen; ++ UINT_8 aucWSCAssocInfoIE[200]; /*for Assoc req */ ++ UINT_16 u2WSCAssocInfoIELen; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ UINT_8 aucHS20AssocInfoIE[200]; /*for Assoc req */ ++ UINT_16 u2HS20AssocInfoIELen; ++ UINT_8 ucHotspotConfig; ++ BOOLEAN fgConnectHS20AP; ++#endif ++ ++ /* NVRAM availability */ ++ BOOLEAN fgNvramAvailable; ++ ++ BOOLEAN fgMcrAccessAllowed; ++ ++ /* MAC Address Overridden by IOCTL */ ++ BOOLEAN fgIsMacAddrOverride; ++ PARAM_MAC_ADDRESS rMacAddrOverride; ++ ++ SET_TXPWR_CTRL_T rTxPwr; ++ ++ /* for cfg80211 scan done indication */ ++ struct cfg80211_scan_request *prScanRequest; ++ ++ /* for cfg80211 scheduled scan */ ++ struct cfg80211_sched_scan_request *prSchedScanRequest; ++ ++ /* to indicate registered or not */ ++ BOOLEAN fgIsRegistered; ++ ++ /* for cfg80211 connected indication */ ++ UINT_32 u4RspIeLength; ++ UINT_8 aucRspIe[CFG_CFG80211_IE_BUF_LEN]; ++ ++ UINT_32 u4ReqIeLength; ++ UINT_8 aucReqIe[CFG_CFG80211_IE_BUF_LEN]; ++ ++ KAL_WAKE_LOCK_T rAhbIsrWakeLock; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ BOOLEAN fgIsDad; ++ UINT_8 aucDADipv4[4]; ++ BOOLEAN fgIs6Dad; ++ UINT_8 aucDADipv6[16]; ++#endif ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ UINT_8 u8MetProfEnable; ++ INT_16 u16MetUdpPort; ++#endif ++ BOOLEAN fgPoorlinkValid; ++ UINT_64 u8Statistic[2]; ++ UINT_64 u8TotalFailCnt; ++ UINT_32 u4LinkspeedThreshold; ++ INT_32 i4RssiThreshold; ++ INT_32 i4RssiCache; ++ UINT_32 u4LinkSpeedCache; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TDLS_INFO_T rTdlsLink; ++ ++ UINT8 aucTdlsHtPeerMac[6]; ++ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ ++ ++ /* ++ [0~7]: jiffies ++ [8~13]: Peer MAC ++ [14]: Reason Code ++ [15]: From us or peer ++ [16]: Duplicate Count ++ */ ++/* UINT8 aucTdlsDisconHistory[TDLS_DISCON_HISTORY_MAX][20]; */ ++/* UINT32 u4TdlsDisconIdx; */ ++#endif /* CFG_SUPPORT_TDLS */ ++ UINT_32 IsrCnt; ++ UINT_32 IsrPassCnt; ++ UINT_32 TaskIsrCnt; ++ ++ UINT_32 IsrPreCnt; ++ UINT_32 IsrPrePassCnt; ++ UINT_32 TaskPreIsrCnt; ++ ++ UINT_32 IsrAbnormalCnt; ++ UINT_32 IsrSoftWareCnt; ++ UINT_32 IsrTxCnt; ++ UINT_32 IsrRxCnt; ++ UINT_64 u8SkbToDriver; ++ UINT_64 u8SkbFreed; ++}; ++ ++typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, struct pt_regs *regs); ++ ++typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long); ++ ++/* generic sub module init/exit handler ++* now, we only have one sub module, p2p ++*/ ++#if CFG_ENABLE_WIFI_DIRECT ++typedef BOOLEAN(*SUB_MODULE_INIT) (P_GLUE_INFO_T prGlueInfo); ++typedef BOOLEAN(*SUB_MODULE_EXIT) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef struct _SUB_MODULE_HANDLER { ++ SUB_MODULE_INIT subModInit; ++ SUB_MODULE_EXIT subModExit; ++ BOOLEAN fgIsInited; ++} SUB_MODULE_HANDLER, *P_SUB_MODULE_HANDLER; ++ ++#endif ++ ++ ++#ifdef CONFIG_NL80211_TESTMODE ++enum TestModeCmdType { ++ /* old test mode command id, compatible with exist testmode command */ ++ TESTMODE_CMD_ID_SW_CMD = 1, ++ TESTMODE_CMD_ID_WAPI = 2, ++ TESTMODE_CMD_ID_HS20 = 3, ++ TESTMODE_CMD_ID_POORLINK = 4, ++ TESTMODE_CMD_ID_STATISTICS = 0x10, ++ TESTMODE_CMD_ID_LINK_DETECT = 0x20, ++ /* old test mode command id, compatible with exist testmode command */ ++ ++ /* all new added test mode command should great than TESTMODE_CMD_ID_NEW_BEGIN */ ++ TESTMODE_CMD_ID_NEW_BEGIN = 100, ++ TESTMODE_CMD_ID_SUSPEND = 101, ++}; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++enum Hs20CmdType { ++ HS20_CMD_ID_SET_BSSID_POOL = 0, ++ NUM_OF_HS20_CMD_ID ++}; ++#endif ++ ++typedef struct _NL80211_DRIVER_TEST_MODE_PARAMS { ++ UINT_32 index; ++ UINT_32 buflen; ++} NL80211_DRIVER_TEST_MODE_PARAMS, *P_NL80211_DRIVER_TEST_MODE_PARAMS; ++ ++/*SW CMD */ ++typedef struct _NL80211_DRIVER_SW_CMD_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_8 set; ++ UINT_32 adr; ++ UINT_32 data; ++} NL80211_DRIVER_SW_CMD_PARAMS, *P_NL80211_DRIVER_SW_CMD_PARAMS; ++ ++typedef struct _NL80211_DRIVER_SUSPEND_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_8 suspend; ++} NL80211_DRIVER_SUSPEND_PARAMS, *P_NL80211_DRIVER_SUSPEND_PARAMS; ++struct iw_encode_exts { ++ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ ++ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ __u8 addr[MAC_ADDR_LEN]; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast ++ * (group) keys or unicast address for ++ * individual keys */ ++ __u16 alg; /*!< IW_ENCODE_ALG_* */ ++ __u16 key_len; ++ __u8 key[32]; ++}; ++ ++/*SET KEY EXT */ ++typedef struct _NL80211_DRIVER_SET_KEY_EXTS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_8 key_index; ++ UINT_8 key_len; ++ struct iw_encode_exts ext; ++} NL80211_DRIVER_SET_KEY_EXTS, *P_NL80211_DRIVER_SET_KEY_EXTS; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ ++struct param_hs20_set_bssid_pool { ++ u8 fgBssidPoolIsEnable; ++ u8 ucNumBssidPool; ++ u8 arBssidPool[8][ETH_ALEN]; ++}; ++ ++struct wpa_driver_hs20_data_s { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ enum Hs20CmdType CmdType; ++ struct param_hs20_set_bssid_pool hs20_set_bssid_pool; ++}; ++ ++#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Macros of SPIN LOCK operations for using in Glue Layer */ ++/*----------------------------------------------------------------------------*/ ++#if CFG_USE_SPIN_LOCK_BOTTOM_HALF ++#define GLUE_SPIN_LOCK_DECLARATION() ++#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_lock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ ++ } ++#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_unlock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ ++ } ++#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ ++ spin_lock_bh(prLock) ++#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ ++ spin_unlock_bh(prLock) ++ ++#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++#define GLUE_SPIN_LOCK_DECLARATION() unsigned long __u4Flags = 0 ++#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_lock_irqsave(&(prGlueInfo)->rSpinLock[rLockCategory], __u4Flags); \ ++ } ++#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_unlock_irqrestore(&(prGlueInfo->rSpinLock[rLockCategory]), __u4Flags); \ ++ } ++#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ ++ spin_lock_irqsave(prLock, __u4Flags) ++#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ ++ spin_unlock_irqrestore(prLock, __u4Flags) ++#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for accessing Reserved Fields of native packet */ ++/*----------------------------------------------------------------------------*/ ++#define GLUE_CB_OFFSET 4 /* For 64-bit platform, avoiding that the cb ++ isoverwrited by "(prQueueEntry)->prNext = ++ (P_QUE_ENTRY_T)NULL;" in QUEUE_INSERT_TAIL */ ++#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ ++ (&(((struct sk_buff *)(_p))->cb[0])) ++ ++#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) \ ++ ((P_NATIVE_PACKET) ((ULONG)_prQueueEntry - offsetof(struct sk_buff, cb[0]))) ++ ++#define GLUE_SET_PKT_FLAG_802_11(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(7)) ++ ++#define GLUE_SET_PKT_FLAG_1X(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(6)) ++ ++#define GLUE_SET_PKT_FLAG_PAL(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(5)) ++ ++#define GLUE_SET_PKT_FLAG_P2P(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(4)) ++ ++#define GLUE_SET_PKT_TID(_p, _tid) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= (((UINT_8)((_tid) & (BITS(0, 3)))))) ++ ++#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ ++ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6])) = (UINT_16)(_u2PayloadLen)) ++ ++#define GLUE_GET_PKT_FRAME_LEN(_p) \ ++ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6]))) ++ ++#define GLUE_GET_PKT_IS_802_11(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(7))) ++ ++#define GLUE_GET_PKT_IS_1X(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(6))) ++ ++#define GLUE_GET_PKT_TID(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BITS(0, 3))) ++ ++#define GLUE_GET_PKT_IS_PAL(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(5))) ++ ++#define GLUE_GET_PKT_IS_P2P(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(4))) ++ ++#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5])) = (UINT_8)(_ucMacHeaderLen)) ++ ++#define GLUE_GET_PKT_HEADER_LEN(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5]))) ++ ++#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ ++ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8])) = (OS_SYSTIME)(_rSysTime)) ++ ++#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ ++ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8]))) ++ ++#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \ ++ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16])) = (UINT_64)(_rSysTime)) ++ ++#define GLUE_GET_PKT_XTIME(_p) \ ++ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16]))) ++ ++/* Check validity of prDev, private data, and pointers */ ++#define GLUE_CHK_DEV(prDev) \ ++ ((prDev && *((P_GLUE_INFO_T *) netdev_priv(prDev))) ? TRUE : FALSE) ++ ++#define GLUE_CHK_PR2(prDev, pr2) \ ++ ((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE) ++ ++#define GLUE_CHK_PR3(prDev, pr2, pr3) \ ++ ((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE) ++ ++#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \ ++ ((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE) ++ ++#define GLUE_SET_EVENT(pr) \ ++ kalSetEvent(pr) ++ ++#define GLUE_INC_REF_CNT(_refCount) atomic_inc((atomic_t *)&(_refCount)) ++#define GLUE_DEC_REF_CNT(_refCount) atomic_dec((atomic_t *)&(_refCount)) ++ ++#define DbgPrint(...) ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#ifdef WLAN_INCLUDE_PROC ++INT_32 procRemoveProcfs(VOID); ++ ++INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo); ++INT_32 procInitFs(VOID); ++INT_32 procUninitProcFs(VOID); ++ ++#endif /* WLAN_INCLUDE_PROC */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++BOOLEAN glRegisterAmpc(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN glUnregisterAmpc(P_GLUE_INFO_T prGlueInfo); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo); ++ ++VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx); ++ ++BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr); ++ ++BOOLEAN wlanIsLaunched(VOID); ++ ++VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo); ++ ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_OS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h +new file mode 100644 +index 000000000000..a27294e33500 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h +@@ -0,0 +1,743 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_ioctl.h#9 ++*/ ++ ++/*! \file gl_p2p_ioctl.h ++ \brief This file is for custom ioctls for Wi-Fi Direct only ++*/ ++ ++/* ++** Log: gl_p2p_ioctl.h ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Fix RX SD request under AP mode issue. ++ * ++ * 03 25 2011 wh.su ++ * NULL ++ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Update RSSI link quality of P2P Network query method. (Bug fix) ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service ++ * discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * . ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 16 2011 chinglan.wang ++ * NULL ++ * Add the group id information in the invitation indication. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 05 04 2011 chinglan.wang ++ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver ++ * . ++ * ++ * 03 29 2011 wh.su ++ * [WCXRP00000095] [MT6620 Wi-Fi] [FW] Refine the P2P GO send broadcast protected code ++ * add the set power and get power function sample. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 03 01 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * fixed the ioctl sumcmd to meet the p2p_supplicant setting. ++ * ++ * 02 23 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * adding the ioctl set int define for p2p parameter. ++ * ++ * 02 22 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * adding the ioctl set int from supplicant, and can used to set the p2p parameters ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * adjust the set wsc ie structure. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 12 15 2010 cp.wu ++ * NULL ++ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() ++ * ++ * 12 07 2010 cp.wu ++ * [WCXRP00000237] [MT6620 Wi-Fi][Wi-Fi Direct][Driver] Add interface for supporting service discovery ++ * define a pair of i/o control for multiplexing layer ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 10 2010 george.huang ++ * NULL ++ * update iwpriv LP related ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Refine a function parameter name. ++ * ++ * 08 19 2010 cp.wu ++ * NULL ++ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * add wext handlers to link P2P set PS profile/ network address function (TBD) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * revised implementation of Wi-Fi Direct io controls. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * follow-up with ioctl interface update for Wi-Fi Direct application ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl to configure scan mode for p2p connection ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement get scan result. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement wireless extension ioctls in iw_handler form. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++*/ ++ ++#ifndef _GL_P2P_IOCTL_H ++#define _GL_P2P_IOCTL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#include ++#endif ++ ++#include "wlan_oid.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Device private ioctl calls */ ++/* #define SIOCDEVPRIVATE 0x89F0*/ ++#define IOC_GET_PRIVATE_IOCTL_CMD (SIOCDEVPRIVATE+1) ++ ++/* (WirelessExtension) Private I/O Controls */ ++#define IOC_P2P_CFG_DEVICE (SIOCIWFIRSTPRIV+0) ++#define IOC_P2P_PROVISION_COMPLETE (SIOCIWFIRSTPRIV+2) ++#define IOC_P2P_START_STOP_DISCOVERY (SIOCIWFIRSTPRIV+4) ++#define IOC_P2P_DISCOVERY_RESULTS (SIOCIWFIRSTPRIV+5) ++#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6) ++#define IOC_P2P_GO_WSC_IE IOC_P2P_WSC_BEACON_PROBE_RSP_IE ++#define IOC_P2P_CONNECT_DISCONNECT (SIOCIWFIRSTPRIV+8) ++#define IOC_P2P_PASSWORD_READY (SIOCIWFIRSTPRIV+10) ++/* #define IOC_P2P_SET_PWR_MGMT_PARAM (SIOCIWFIRSTPRIV+12) */ ++#define IOC_P2P_SET_INT (SIOCIWFIRSTPRIV+12) ++#define IOC_P2P_GET_STRUCT (SIOCIWFIRSTPRIV+13) ++#define IOC_P2P_SET_STRUCT (SIOCIWFIRSTPRIV+14) ++#define IOC_P2P_GET_REQ_DEVICE_INFO (SIOCIWFIRSTPRIV+15) ++ ++#define PRIV_CMD_INT_P2P_SET 0 ++ ++/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */ ++#define P2P_PROVISIONING_SUCCESS 0 ++#define P2P_PROVISIONING_FAIL 1 ++ ++/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */ ++#define P2P_STOP_DISCOVERY 0 ++#define P2P_START_DISCOVERY 1 ++ ++/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */ ++#define P2P_CONNECT 0 ++#define P2P_DISCONNECT 1 ++ ++/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */ ++#define P2P_SCAN_FULL_AND_FIND 0 ++#define P2P_SCAN_FULL 1 ++#define P2P_SCAN_SEARCH_AND_LISTEN 2 ++#define P2P_LISTEN 3 ++ ++/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */ ++#define P2P_SEND_SD_RESPONSE 0 ++#define P2P_GET_SD_REQUEST 1 ++#define P2P_SEND_SD_REQUEST 2 ++#define P2P_GET_SD_RESPONSE 3 ++#define P2P_TERMINATE_SD_PHASE 4 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Wireless Extension: Private I/O Control */ ++/*----------------------------------------------------------------------------*/ ++typedef struct iw_p2p_cfg_device_type { ++ void __user *ssid; ++ UINT_8 ssid_len; ++ UINT_8 pri_device_type[8]; ++ UINT_8 snd_device_type[8]; ++ void __user *device_name; ++ UINT_8 device_name_len; ++ UINT_8 intend; ++ UINT_8 persistence; ++ UINT_8 sec_mode; ++ UINT_8 ch; ++ UINT_8 ch_width; /* 0: 20 Mhz 1:20/40 Mhz auto */ ++ UINT_8 max_scb; ++} IW_P2P_CFG_DEVICE_TYPE, *P_IW_P2P_CFG_DEVICE_TYPE; ++ ++typedef struct iw_p2p_hostapd_param { ++ UINT_8 cmd; ++ UINT_8 rsv[3]; ++ UINT_8 sta_addr[6]; ++ void __user *data; ++ UINT_16 len; ++} IW_P2P_HOSTAPD_PARAM, *P_IW_P2P_HOSTAPD_PARAM; ++ ++typedef struct iw_p2p_req_device_type { ++ UINT_8 scan_type; /* 0: Full scan + Find ++ * 1: Full scan ++ * 2: Scan (Search +Listen) ++ * 3: Listen ++ * other : reserved ++ */ ++ UINT_8 pri_device_type[8]; ++ void __user *probe_req_ie; ++ UINT_16 probe_req_len; ++ void __user *probe_rsp_ie; ++ UINT_16 probe_rsp_len; ++} IW_P2P_REQ_DEVICE_TYPE, *P_IW_P2P_REQ_DEVICE_TYPE; ++ ++typedef struct iw_p2p_connect_device { ++ UINT_8 sta_addr[6]; ++ UINT_8 p2pRole; /* 0: P2P Device, 1:GC, 2: GO */ ++ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ ++ UINT_8 authPeer; /* 1: auth peer invitation request */ ++ UINT_8 intend_config_method; /* Request Peer Device used config method */ ++} IW_P2P_CONNECT_DEVICE, *P_IW_P2P_CONNECT_DEVICE; ++ ++typedef struct iw_p2p_password_ready { ++ UINT_8 active_config_method; ++ void __user *probe_req_ie; ++ UINT_16 probe_req_len; ++ void __user *probe_rsp_ie; ++ UINT_16 probe_rsp_len; ++} IW_P2P_PASSWORD_READY, *P_IW_P2P_PASSWORD_READY; ++ ++typedef struct iw_p2p_device_req { ++ UINT_8 name[33]; ++ UINT_32 name_len; ++ UINT_8 device_addr[6]; ++ UINT_8 device_type; ++ INT_32 config_method; ++ INT_32 active_config_method; ++} IW_P2P_DEVICE_REQ, *P_IW_P2P_DEVICE_REQ; ++ ++typedef struct iw_p2p_transport_struct { ++ UINT_32 u4CmdId; ++ UINT_32 inBufferLength; ++ UINT_32 outBufferLength; ++ UINT_8 aucBuffer[16]; ++} IW_P2P_TRANSPORT_STRUCT, *P_IW_P2P_TRANSPORT_STRUCT; ++ ++/* For Invitation */ ++typedef struct iw_p2p_ioctl_invitation_struct { ++ UINT_8 aucDeviceID[6]; ++ UINT_8 aucGroupID[6]; /* BSSID */ ++ UINT_8 aucSsid[32]; ++ UINT_32 u4SsidLen; ++ UINT_8 ucReinvoke; ++} IW_P2P_IOCTL_INVITATION_STRUCT, *P_IW_P2P_IOCTL_INVITATION_STRUCT; ++ ++typedef struct iw_p2p_ioctl_abort_invitation { ++ UINT_8 dev_addr[6]; ++} IW_P2P_IOCTL_ABORT_INVITATION, *P_IW_P2P_IOCTL_ABORT_INVITATION; ++ ++typedef struct iw_p2p_ioctl_invitation_indicate { ++ UINT_8 dev_addr[6]; ++ UINT_8 group_bssid[6]; ++ INT_32 config_method; /* peer device supported config method */ ++ UINT_8 dev_name[32]; /* for reinvoke */ ++ UINT_32 name_len; ++ UINT_8 operating_channel; /* for re-invoke, target operating channel */ ++ UINT_8 invitation_type; /* invitation or re-invoke */ ++} IW_P2P_IOCTL_INVITATION_INDICATE, *P_IW_P2P_IOCTL_INVITATION_INDICATE; ++ ++typedef struct iw_p2p_ioctl_invitation_status { ++ UINT_32 status_code; ++} IW_P2P_IOCTL_INVITATION_STATUS, *P_IW_P2P_IOCTL_INVITATION_STATUS; ++ ++/* For Formation */ ++typedef struct iw_p2p_ioctl_start_formation { ++ UINT_8 dev_addr[6]; /* bssid */ ++ UINT_8 role; /* 0: P2P Device, 1:GC, 2: GO */ ++ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ ++ UINT_8 auth; /* 1: auth peer invitation request */ ++ UINT_8 config_method; /* Request Peer Device used config method */ ++} IW_P2P_IOCTL_START_FORMATION, *P_IW_P2P_IOCTL_START_FORMATION; ++ ++/* SET_STRUCT / GET_STRUCT */ ++typedef enum _ENUM_P2P_CMD_ID_T { ++ P2P_CMD_ID_SEND_SD_RESPONSE = 0, /* 0x00 (Set) */ ++ P2P_CMD_ID_GET_SD_REQUEST, /* 0x01 (Get) */ ++ P2P_CMD_ID_SEND_SD_REQUEST, /* 0x02 (Set) */ ++ P2P_CMD_ID_GET_SD_RESPONSE, /* 0x03 (Get) */ ++ P2P_CMD_ID_TERMINATE_SD_PHASE, /* 0x04 (Set) */ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ P2P_CMD_ID_SEC_CHECK, /* 0x05(Set) */ ++#endif ++ P2P_CMD_ID_INVITATION, /* 0x06 (Set) */ ++ P2P_CMD_ID_INVITATION_INDICATE, /* 0x07 (Get) */ ++ P2P_CMD_ID_INVITATION_STATUS, /* 0x08 (Get) */ ++ P2P_CMD_ID_INVITATION_ABORT, /* 0x09 (Set) */ ++ P2P_CMD_ID_START_FORMATION, /* 0x0A (Set) */ ++ P2P_CMD_ID_P2P_VERSION, /* 0x0B (Set/Get) */ ++ P2P_CMD_ID_GET_CH_LIST = 12, /* 0x0C (Get) */ ++ P2P_CMD_ID_GET_OP_CH = 14 /* 0x0E (Get) */ ++} ENUM_P2P_CMD_ID_T, *P_ENUM_P2P_CMD_ID_T; ++ ++/* Service Discovery */ ++typedef struct iw_p2p_cmd_send_sd_response { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucSeqNum; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_SEND_SD_RESPONSE, *P_IW_P2P_CMD_SEND_SD_RESPONSE; ++ ++typedef struct iw_p2p_cmd_get_sd_request { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_GET_SD_REQUEST, *P_IW_P2P_CMD_GET_SD_REQUEST; ++ ++typedef struct iw_p2p_cmd_send_service_discovery_request { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucSeqNum; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_SEND_SD_REQUEST, *P_IW_P2P_CMD_SEND_SD_REQUEST; ++ ++typedef struct iw_p2p_cmd_get_sd_response { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_GET_SD_RESPONSE, *P_IW_P2P_CMD_GET_SD_RESPONSE; ++ ++typedef struct iw_p2p_cmd_terminate_sd_phase { ++ PARAM_MAC_ADDRESS rPeerAddr; ++} IW_P2P_CMD_TERMINATE_SD_PHASE, *P_IW_P2P_CMD_TERMINATE_SD_PHASE; ++ ++typedef struct iw_p2p_version { ++ UINT_32 u4Version; ++} IW_P2P_VERSION, *P_IW_P2P_VERSION; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++extern struct ieee80211_supported_band mtk_band_2ghz; ++extern struct ieee80211_supported_band mtk_band_5ghz; ++extern UINT_32 mtk_cipher_suites[5]; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++int mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy, ++ struct net_device *ndev, ++ enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); ++ ++int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); ++ ++int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) ++); ++ ++int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, ++ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); ++ ++int ++mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, ++ struct net_device *netdev, u8 key_index, bool unicast, bool multicast); ++ ++int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_info *sinfo); ++ ++int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); ++ ++int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme); ++ ++int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); ++ ++int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); ++ ++int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev); ++ ++int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); ++ ++int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); ++ ++int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, unsigned int duration, u64 *cookie); ++ ++int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); ++ ++int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); ++ ++int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, ++ struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm); ++ ++int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); ++ ++int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req); ++ ++int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req); ++ ++int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings); ++ ++int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info); ++ ++int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie); ++ ++int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev); ++ ++int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params); ++//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac); ++ ++int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef); ++ ++void mtk_p2p_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); ++ ++int ++mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, ++ IN struct net_device *dev, ++ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask); ++ ++#ifdef CONFIG_NL80211_TESTMODE ++int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); ++int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++ ++#if CFG_SUPPORT_WFD ++int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#else ++#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" ++#endif ++ ++#endif ++ ++/* I/O control handlers */ ++ ++int ++mtk_p2p_wext_get_priv(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_reconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_auth(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_key(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_powermode(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_powermode(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++/* Private Wireless I/O Controls takes use of iw_handler */ ++int ++mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_discovery_results(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_password_ready(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_invitation_status(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_network_address(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_int(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */ ++int ++mtk_p2p_wext_set_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */ ++int ++mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++int ++mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++#endif ++ ++int ++mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++void mtk_p2p_wext_set_Multicastlist(IN P_GLUE_INFO_T prGlueInfo); ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++int ++mtk_p2p_wext_get_rssi(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev); ++ ++#endif ++ ++int ++mtk_p2p_wext_set_txpow(IN struct net_device *prDev, ++ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_P2P_IOCTL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h +new file mode 100644 +index 000000000000..bf9d8871ef48 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h +@@ -0,0 +1,243 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_kal.h#2 ++*/ ++ ++/*! \file gl_p2p_kal.h ++ \brief Declaration of KAL functions for Wi-Fi Direct support ++ - kal*() which is provided by GLUE Layer. ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/* ++** Log: gl_p2p_kal.h ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 15 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Add group BSSID in invitation request indication. ++ * The BSSID is used for APP to decide the configure method. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 03 19 2011 terry.wu ++ * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver ++ * create V2.0 p2p driver release based on label "MT6620_WIFI_P2P_DRIVER_V2_0_2100_0319_2011" from main trunk. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++*/ ++ ++#ifndef _GL_P2P_KAL_H ++#define _GL_P2P_KAL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "config.h" ++#include "gl_typedef.h" ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "wlan_p2p.h" ++#include "gl_kal.h" ++#include "gl_wext_priv.h" ++#include "nic/p2p.h" ++ ++#if DBG ++extern int allocatedMemSize; ++#endif ++ ++extern BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); ++ ++#if CFG_SUPPORT_WPS ++extern BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type); ++struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo); ++ ++/* Service Discovery */ ++VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); ++ ++void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); ++ ++VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Wi-Fi Direct handling */ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole); ++ ++VOID ++kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); ++ ++UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole); ++ ++VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher); ++ ++BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode); ++ ++UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType); ++ ++VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer); ++ ++VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength); ++ ++BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, ++ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ ++ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod); ++ ++VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus); ++ ++VOID ++kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, ++ IN PUINT_8 pucSsid, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid); ++ ++struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID ++kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8SeqNum, ++ IN UINT_32 u4ChannelNum, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration); ++ ++VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort); ++ ++VOID ++kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBuf, ++ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength); ++ ++VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); ++ ++VOID ++kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); ++ ++VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); ++ ++VOID ++kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, ++ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, ++ IN WLAN_STATUS eStatus); ++ ++VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew); ++ ++INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock); ++ ++BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid); ++ ++VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient); ++ ++BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient); ++ ++#endif /* _GL_P2P_KAL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h +new file mode 100644 +index 000000000000..e5026e7e6eec +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h +@@ -0,0 +1,242 @@ ++/* ++** Id: ++//Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/os/linux/include/gl_p2p_os.h#28 ++*/ ++ ++/*! \file gl_p2p_os.h ++ \brief List the external reference to OS for p2p GLUE Layer. ++ ++ In this file we define the data structure - GLUE_INFO_T to store those objects ++ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the ++ external reference (header file, extern func() ..) to OS for GLUE Layer should ++ also list down here. ++*/ ++ ++#ifndef _GL_P2P_OS_H ++#define _GL_P2P_OS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#endif ++ ++#include "wlan_oid.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++struct _GL_P2P_INFO_T { ++ ++ /* Device handle */ ++ struct net_device *prDevHandler; ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ /* cfg80211 */ ++ struct wireless_dev *prWdev; ++ ++ struct cfg80211_scan_request *prScanRequest; ++ ++ UINT_64 u8Cookie; ++ ++ /* Generation for station list update. */ ++ INT_32 i4Generation; ++ ++ UINT_32 u4OsMgmtFrameFilter; ++ ++#endif ++ ++ /* Device statistics */ ++ struct net_device_stats rNetDevStats; ++ ++ /* glue layer variables */ ++ UINT_32 u4FreqInKHz; /* frequency */ ++ UINT_8 ucRole; /* 0: P2P Device, 1: Group Client, 2: Group Owner */ ++ UINT_8 ucIntent; /* range: 0-15 */ ++ UINT_8 ucScanMode; /* 0: Search & Listen, 1: Scan without probe response */ ++ ++ ENUM_PARAM_MEDIA_STATE_T eState; ++ UINT_32 u4PacketFilter; ++ PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR]; ++ ++ /* connection-requested peer information */ ++ UINT_8 aucConnReqDevName[32]; ++ INT_32 u4ConnReqNameLength; ++ PARAM_MAC_ADDRESS rConnReqPeerAddr; ++ PARAM_MAC_ADDRESS rConnReqGroupAddr; /* For invitation group. */ ++ UINT_8 ucConnReqDevType; ++ INT_32 i4ConnReqConfigMethod; ++ INT_32 i4ConnReqActiveConfigMethod; ++ ++ UINT_32 u4CipherPairwise; ++ UINT_8 ucWSCRunning; ++ ++ UINT_8 aucWSCIE[3][400]; /* 0 for beacon, 1 for probe req, 2 for probe response */ ++ UINT_16 u2WSCIELen[3]; ++ ++#if CFG_SUPPORT_WFD ++ UINT_8 aucVenderIE[1024]; /* Save the other IE for prove resp */ ++ UINT_16 u2VenderIELen; ++#endif ++ ++ UINT_8 ucOperatingChnl; ++ UINT_8 ucInvitationType; ++ ++ UINT_32 u4InvStatus; ++ ++ /* For SET_STRUCT/GET_STRUCT */ ++ UINT_8 aucOidBuf[4096]; ++ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ UINT_8 aucSecCheck[256]; ++ UINT_8 aucSecCheckRsp[256]; ++#endif ++ ++ /* Hotspot Client Management */ ++ PARAM_MAC_ADDRESS aucblackMACList[8]; ++ UINT_8 ucMaxClients; ++ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ UINT_32 u4PsLevel; ++#endif ++}; ++ ++#ifdef CONFIG_NL80211_TESTMODE ++typedef struct _NL80211_DRIVER_TEST_PRE_PARAMS { ++ UINT_16 idx_mode; ++ UINT_16 idx; ++ UINT_32 value; ++} NL80211_DRIVER_TEST_PRE_PARAMS, *P_NL80211_DRIVER_TEST_PRE_PARAMS; ++ ++typedef struct _NL80211_DRIVER_TEST_PARAMS { ++ UINT_32 index; ++ UINT_32 buflen; ++} NL80211_DRIVER_TEST_PARAMS, *P_NL80211_DRIVER_TEST_PARAMS; ++ ++/* P2P Sigma*/ ++typedef struct _NL80211_DRIVER_P2P_SIGMA_PARAMS { ++ NL80211_DRIVER_TEST_PARAMS hdr; ++ UINT_32 idx; ++ UINT_32 value; ++} NL80211_DRIVER_P2P_SIGMA_PARAMS, *P_NL80211_DRIVER_P2P_SIGMA_PARAMS; ++ ++/* Hotspot Client Management */ ++typedef struct _NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS { ++ NL80211_DRIVER_TEST_PARAMS hdr; ++ UINT_8 ucblocked; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++} NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS, *P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS; ++ ++#if CFG_SUPPORT_WFD ++typedef struct _NL80211_DRIVER_WFD_PARAMS { ++ NL80211_DRIVER_TEST_PARAMS hdr; ++ UINT_32 WfdCmdType; ++ UINT_8 WfdEnable; ++ UINT_8 WfdCoupleSinkStatus; ++ UINT_8 WfdSessionAvailable; ++ UINT_8 WfdSigmaMode; ++ UINT_16 WfdDevInfo; ++ UINT_16 WfdControlPort; ++ UINT_16 WfdMaximumTp; ++ UINT_16 WfdExtendCap; ++ UINT_8 WfdCoupleSinkAddress[MAC_ADDR_LEN]; ++ UINT_8 WfdAssociatedBssid[MAC_ADDR_LEN]; ++ UINT_8 WfdVideoIp[4]; ++ UINT_8 WfdAudioIp[4]; ++ UINT_16 WfdVideoPort; ++ UINT_16 WfdAudioPort; ++ UINT_32 WfdFlag; ++ UINT_32 WfdPolicy; ++ UINT_32 WfdState; ++ UINT_8 WfdSessionInformationIE[24 * 8]; /* Include Subelement ID, length */ ++ UINT_16 WfdSessionInformationIELen; ++ UINT_8 aucReserved1[2]; ++ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; ++ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; ++ UINT_32 WfdAdvanceFlag; ++ /* Group 1 64 bytes */ ++ UINT_8 aucWfdLocalIp[4]; ++ UINT_16 WfdLifetimeAc2; /* Unit is 2 TU */ ++ UINT_16 WfdLifetimeAc3; /* Unit is 2 TU */ ++ UINT_16 WfdCounterThreshold; /* Unit is ms */ ++ UINT_8 aucReserved2[54]; ++ /* Group 3 64 bytes */ ++ UINT_8 aucReserved3[64]; ++ /* Group 3 64 bytes */ ++ UINT_8 aucReserved4[64]; ++} NL80211_DRIVER_WFD_PARAMS, *P_NL80211_DRIVER_WFD_PARAMS; ++#endif ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo); ++ ++VOID p2pSetMode(IN BOOLEAN fgIsAPMOde); ++ ++BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode); ++ ++VOID p2pEalySuspendReg(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsEnable); ++ ++BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); ++ ++BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); ++ ++BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo); ++ ++VOID glP2pDestroyWirelessDevice(VOID); ++ ++VOID p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h +new file mode 100644 +index 000000000000..f24ceee9e921 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h +@@ -0,0 +1,133 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_rst.h#1 ++*/ ++ ++/*! \file gl_rst.h ++ \brief Declaration of functions and finite state machine for ++ MT6620 Whole-Chip Reset Mechanism ++*/ ++ ++#ifndef _GL_RST_H ++#define _GL_RST_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if 1 ++typedef INT_32(*wmt_wlan_probe_cb) (VOID); ++typedef INT_32(*wmt_wlan_remove_cb) (VOID); ++typedef INT_32(*wmt_wlan_bus_cnt_get_cb) (VOID); ++typedef INT_32(*wmt_wlan_bus_cnt_clr_cb) (VOID); ++ ++typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { ++ wmt_wlan_probe_cb wlan_probe_cb; ++ wmt_wlan_remove_cb wlan_remove_cb; ++ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; ++ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; ++} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; ++ ++extern INT_32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); ++extern INT_32 mtk_wcn_wmt_wlan_unreg(VOID); ++#endif ++ ++typedef enum _ENUM_RESET_STATUS_T { ++ RESET_FAIL, ++ RESET_SUCCESS ++} ENUM_RESET_STATUS_T; ++ ++typedef struct _RESET_STRUCT_T { ++ ENUM_RESET_STATUS_T rst_data; ++ struct work_struct rst_work; ++} RESET_STRUCT_T; ++ ++typedef enum _ENUM_WMTRSTMSG_TYPE_T { ++ WMTRSTMSG_RESET_START = 0x0, ++ WMTRSTMSG_RESET_END = 0x1, ++ WMTRSTMSG_RESET_END_FAIL = 0x2, ++ WMTRSTMSG_RESET_MAX, ++ WMTRSTMSG_RESET_INVALID = 0xff ++} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; ++ ++typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ ++ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ ++ ENUM_WMTMSG_TYPE_T, /* Message type */ ++ void *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client ++ can't touch this buffer after this function return. */ ++ unsigned int /* Buffer size in unit of byte */ ++); ++ ++/******************************************************************************* ++* E X T E R N A L F U N C T I O N S ++******************************************************************************** ++*/ ++#define glDoChipReset() \ ++ do { \ ++ if (!kalStrnCmp(current->comm, "mtk_wmtd", 8)) { \ ++ g_IsNeedDoChipReset = 1; \ ++ DBGLOG(INIT, ERROR, "forbid core dump in mtk_wmtd %s line %d\n", __func__, __LINE__); \ ++ break; \ ++ } \ ++ DBGLOG(INIT, ERROR, "Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ ++ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 0x40); \ ++ } while (0) ++ ++#if CFG_CHIP_RESET_SUPPORT ++extern int mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++extern int mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++extern int wifi_reset_start(void); ++extern int wifi_reset_end(ENUM_RESET_STATUS_T); ++#endif ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++extern BOOLEAN mtk_wcn_set_connsys_power_off_flag(BOOLEAN value); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern UINT_32 g_IsNeedDoChipReset; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID glResetInit(VOID); ++ ++VOID glResetUninit(VOID); ++ ++VOID glSendResetRequest(VOID); ++ ++BOOLEAN kalIsResetting(VOID); ++ ++#endif /* _GL_RST_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h +new file mode 100644 +index 000000000000..3cc57780f201 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h +@@ -0,0 +1,21 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_sec.h#1 ++*/ ++ ++/*! \file p2p_fsm.h ++ \brief Declaration of functions and finite state machine for P2P Module. ++ ++ Declaration of functions and finite state machine for P2P Module. ++*/ ++ ++#ifndef _GL_SEC_H ++#define _GL_SEC_H ++ ++extern void handle_sec_msg_1(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_2(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_3(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_4(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_5(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_final(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++ ++#endif /* _GL_SEC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h +new file mode 100644 +index 000000000000..e9aa3e849eb2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h +@@ -0,0 +1,298 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_typedef.h#1 ++*/ ++ ++/*! \file gl_typedef.h ++ \brief Definition of basic data type(os dependent). ++ ++ In this file we define the basic data type. ++*/ ++ ++/* ++** Log: gl_typedef.h ++ * ++ * 06 22 2012 cp.wu ++ * [WCXRP00001257] [MT6620][MT5931][MT6628][Driver][Linux] Modify KAL_HZ to align ms accuracy ++ * modify KAL_HZ to (1000) for correct definition. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 02 15 2011 jeffrey.chang ++ * NULL ++ * to support early suspend in android ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\6 2009-08-18 22:57:14 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\5 2008-09-22 23:19:30 GMT mtk01461 ++** Update comment for code review ++** \main\maintrunk.MT5921\4 2008-09-05 17:25:16 GMT mtk01461 ++** Update Driver for Code Review ++** \main\maintrunk.MT5921\3 2007-11-09 11:00:50 GMT mtk01425 ++** 1. Use macro to unify network-to-host and host-to-network related functions ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++#ifndef _GL_TYPEDEF_H ++#define _GL_TYPEDEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Define HZ of timer tick for function kalGetTimeTick() */ ++#define KAL_HZ (1000) ++ ++/* Miscellaneous Equates */ ++#ifndef FALSE ++#define FALSE ((BOOLEAN) 0) ++#define TRUE ((BOOLEAN) 1) ++#endif /* FALSE */ ++ ++#ifndef NULL ++#if defined(__cplusplus) ++#define NULL 0 ++#else ++#define NULL ((void *) 0) ++#endif ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Type definition for void */ ++/*mach/mt_typedefs.h define _TYPEDEFS_H, to avoid compile error*/ ++#ifndef _TYPEDEFS_H ++typedef void VOID; ++#endif ++typedef void *PVOID, **PPVOID; ++ ++/* Type definition for Boolean */ ++typedef unsigned char BOOLEAN, *PBOOLEAN; ++ ++/* Type definition for signed integers */ ++typedef signed char CHAR, *PCHAR, **PPCHAR; ++typedef signed char INT_8, *PINT_8, **PPINT_8; ++typedef signed short INT_16, *PINT_16, **PPINT_16; ++typedef signed int INT_32, *PINT_32, **PPINT_32; ++typedef long LONG, *PLONG, **PPLONG; ++typedef signed long long INT_64, *PINT_64, **PPINT_64; ++ ++/* Type definition for unsigned integers */ ++typedef unsigned char UCHAR, *PUCHAR, **PPUCHAR; ++typedef unsigned char UINT_8, *PUINT_8, **PPUINT_8, *P_UINT_8; ++typedef unsigned short UINT_16, *PUINT_16, **PPUINT_16; ++typedef unsigned int UINT32, *PUINT32; ++typedef unsigned int UINT_32, *PUINT_32, **PPUINT_32; ++typedef unsigned long ULONG, *PULONG, **PPULONG; ++typedef unsigned long long UINT_64, *PUINT_64, **PPUINT_64; ++ ++typedef unsigned int OS_SYSTIME, *POS_SYSTIME, **PPOS_SYSTIME; ++ ++#ifndef _TYPEDEFS_H ++typedef signed char INT8, *PINT8; ++typedef signed short INT16, *PINT16; ++typedef signed int INT32, *PINT32; ++typedef unsigned char UINT8, *PUINT8; ++typedef unsigned short UINT16, *PUINT16; ++typedef unsigned int UINT32, *PUINT32; ++#endif ++ ++/* Type definition of large integer (64bits) union to be comptaible with ++ * Windows definition, so we won't apply our own coding style to these data types. ++ * NOTE: LARGE_INTEGER must NOT be floating variable. ++ * : Check for big-endian compatibility. ++ */ ++typedef union _LARGE_INTEGER { ++ struct { ++ UINT_32 LowPart; ++ INT_32 HighPart; ++ } u; ++ INT_64 QuadPart; ++} LARGE_INTEGER, *PLARGE_INTEGER; ++ ++typedef union _ULARGE_INTEGER { ++ struct { ++ UINT_32 LowPart; ++ UINT_32 HighPart; ++ } u; ++ UINT_64 QuadPart; ++} ULARGE_INTEGER, *PULARGE_INTEGER; ++ ++typedef INT_32(*probe_card) (PVOID pvData); ++typedef VOID(*remove_card) (VOID); ++ ++/* duplicated from wmt_exp.h for better driver isolation */ ++typedef enum _ENUM_WMTDRV_TYPE_T { ++ WMTDRV_TYPE_BT = 0, ++ WMTDRV_TYPE_FM = 1, ++ WMTDRV_TYPE_GPS = 2, ++ WMTDRV_TYPE_WIFI = 3, ++ WMTDRV_TYPE_WMT = 4, ++ WMTDRV_TYPE_STP = 5, ++ WMTDRV_TYPE_SDIO1 = 6, ++ WMTDRV_TYPE_SDIO2 = 7, ++ WMTDRV_TYPE_LPBK = 8, ++ WMTDRV_TYPE_MAX ++} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; ++ ++typedef enum _ENUM_WMTMSG_TYPE_T { ++ WMTMSG_TYPE_POWER_ON = 0, ++ WMTMSG_TYPE_POWER_OFF = 1, ++ WMTMSG_TYPE_RESET = 2, ++ WMTMSG_TYPE_STP_RDY = 3, ++ WMTMSG_TYPE_HW_FUNC_ON = 4, ++ WMTMSG_TYPE_MAX ++} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; ++ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define IN /* volatile */ ++#define OUT /* volatile */ ++ ++#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) ++#define __KAL_ATTRIB_ALIGN_4__ __aligned(4) ++ ++#ifndef BIT ++#define BIT(n) ((UINT_32) 1U << (n)) ++#endif /* BIT */ ++ ++#ifndef BITS ++/* bits range: for example BITS(16,23) = 0xFF0000 ++ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 ++ * ==> (BIT(n+1)-1) = 0x00FFFFFF ++ */ ++#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) ++#endif /* BIT */ ++ ++/* This macro returns the byte offset of a named field in a known structure ++ type. ++ _type - structure name, ++ _field - field name of the structure */ ++#ifndef OFFSET_OF ++#define OFFSET_OF(_type, _field) ((ULONG)&(((_type *)0)->_field)) ++#endif /* OFFSET_OF */ ++ ++/* This macro returns the base address of an instance of a structure ++ * given the type of the structure and the address of a field within the ++ * containing structure. ++ * _addrOfField - address of current field of the structure, ++ * _type - structure name, ++ * _field - field name of the structure ++ */ ++#ifndef ENTRY_OF ++#define ENTRY_OF(_addrOfField, _type, _field) \ ++ ((_type *)((PINT_8)(_addrOfField) - (PINT_8)OFFSET_OF(_type, _field))) ++#endif /* ENTRY_OF */ ++ ++/* This macro align the input value to the DW boundary. ++ * _value - value need to check ++ */ ++#ifndef ALIGN_4 ++#define ALIGN_4(_value) (((_value) + 3) & ~3u) ++#endif /* ALIGN_4 */ ++ ++/* This macro check the DW alignment of the input value. ++ * _value - value of address need to check ++ */ ++#ifndef IS_ALIGN_4 ++#define IS_ALIGN_4(_value) (((_value) & 0x3) ? FALSE : TRUE) ++#endif /* IS_ALIGN_4 */ ++ ++#ifndef IS_NOT_ALIGN_4 ++#define IS_NOT_ALIGN_4(_value) (((_value) & 0x3) ? TRUE : FALSE) ++#endif /* IS_NOT_ALIGN_4 */ ++ ++/* This macro evaluate the input length in unit of Double Word(4 Bytes). ++ * _value - value in unit of Byte, output will round up to DW boundary. ++ */ ++#ifndef BYTE_TO_DWORD ++#define BYTE_TO_DWORD(_value) ((_value + 3) >> 2) ++#endif /* BYTE_TO_DWORD */ ++ ++/* This macro evaluate the input length in unit of Byte. ++ * _value - value in unit of DW, output is in unit of Byte. ++ */ ++#ifndef DWORD_TO_BYTE ++#define DWORD_TO_BYTE(_value) ((_value) << 2) ++#endif /* DWORD_TO_BYTE */ ++ ++#if 1 /* Little-Endian */ ++#define CONST_NTOHS(_x) ntohs(_x) ++ ++#define CONST_HTONS(_x) htons(_x) ++ ++#define NTOHS(_x) ntohs(_x) ++ ++#define HTONS(_x) htons(_x) ++ ++#define NTOHL(_x) ntohl(_x) ++ ++#define HTONL(_x) htonl(_x) ++ ++#else /* Big-Endian */ ++ ++#define CONST_NTOHS(_x) ++ ++#define CONST_HTONS(_x) ++ ++#define NTOHS(_x) ++ ++#define HTONS(_x) ++ ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h +new file mode 100644 +index 000000000000..d8d5b0fb6740 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h +@@ -0,0 +1,619 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_vendor.h#1 ++*/ ++ ++/*! \file gl_vendor.h ++ \brief This file is for Portable Driver linux gl_vendor support. ++*/ ++ ++/* ++** Log: gl_vendor.h ++** ++** 10 14 2014 ++** add vendor declaration ++** ++ * ++*/ ++ ++#ifndef _GL_VENDOR_H ++#define _GL_VENDOR_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "gl_os.h" ++ ++#include "wlan_lib.h" ++#include "gl_wext.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define GOOGLE_OUI 0x001A11 ++ ++typedef enum { ++ /* Don't use 0 as a valid subcommand */ ++ ANDROID_NL80211_SUBCMD_UNSPECIFIED, ++ ++ /* Define all vendor startup commands between 0x0 and 0x0FFF */ ++ ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001, ++ ANDROID_NL80211_SUBCMD_WIFI_RANGE_END = 0x0FFF, ++ ++ /* Define all GScan related commands between 0x1000 and 0x10FF */ ++ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, ++ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, ++ ++ /* Define all RTT related commands between 0x1100 and 0x11FF */ ++ ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, ++ ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, ++ ++ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, ++ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, ++ ++ /* Define all Logger related commands between 0x1400 and 0x14FF */ ++ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, ++ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, ++ ++ /* Define all wifi offload related commands between 0x1600 and 0x16FF */ ++ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, ++ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, ++ ++ /* This is reserved for future usage */ ++ ++} ANDROID_VENDOR_SUB_COMMAND; ++ ++typedef enum { ++ WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START, ++ ++ WIFI_SUBCMD_GET_FEATURE_SET, /* 0x0001 */ ++ WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x0002 */ ++ WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x0003 */ ++ WIFI_SUBCMD_NODFS_SET, /* 0x0004 */ ++ WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x0005 */ ++ /* Add more sub commands here */ ++ ++} WIFI_SUB_COMMAND; ++ ++typedef enum { ++ GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, ++ ++ GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */ ++ GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */ ++ GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */ ++ GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */ ++ GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */ ++ ++ GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */ ++ ++ GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */ ++ GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */ ++ /* Add more sub commands here */ ++ ++} GSCAN_SUB_COMMAND; ++ ++typedef enum { ++ RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, ++ RTT_SUBCMD_CANCEL_CONFIG, ++ RTT_SUBCMD_GETCAPABILITY, ++} RTT_SUB_COMMAND; ++ ++typedef enum { ++ LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, ++} LSTATS_SUB_COMMAND; ++ ++typedef enum { ++ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, ++ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, ++ GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, ++ GSCAN_EVENT_FULL_SCAN_RESULTS, ++ RTT_EVENT_COMPLETE, ++ GSCAN_EVENT_COMPLETE_SCAN, ++ GSCAN_EVENT_HOTLIST_RESULTS_LOST ++} WIFI_VENDOR_EVENT; ++ ++typedef enum { ++ WIFI_ATTRIBUTE_BAND, ++ WIFI_ATTRIBUTE_NUM_CHANNELS, ++ WIFI_ATTRIBUTE_CHANNEL_LIST, ++ ++ WIFI_ATTRIBUTE_NUM_FEATURE_SET, ++ WIFI_ATTRIBUTE_FEATURE_SET, ++ WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, ++ WIFI_ATTRIBUTE_NODFS_VALUE, ++ WIFI_ATTRIBUTE_COUNTRY_CODE ++ ++} WIFI_ATTRIBUTE; ++ ++typedef enum { ++ GSCAN_ATTRIBUTE_CAPABILITIES = 1, ++ ++ GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, ++ GSCAN_ATTRIBUTE_BASE_PERIOD, ++ GSCAN_ATTRIBUTE_BUCKETS_BAND, ++ GSCAN_ATTRIBUTE_BUCKET_ID, ++ GSCAN_ATTRIBUTE_BUCKET_PERIOD, ++ GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, ++ GSCAN_ATTRIBUTE_BUCKET_CHANNELS, ++ GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, ++ GSCAN_ATTRIBUTE_REPORT_THRESHOLD, ++ GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, ++ ++ GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, ++ GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ ++ GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ ++ GSCAN_ENABLE_FULL_SCAN_RESULTS, ++ GSCAN_ATTRIBUTE_REPORT_EVENTS, ++ ++ GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, ++ GSCAN_ATTRIBUTE_FLUSH_RESULTS, ++ GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ ++ GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ ++ GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ ++ GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ ++ ++ GSCAN_ATTRIBUTE_SSID = 40, ++ GSCAN_ATTRIBUTE_BSSID, ++ GSCAN_ATTRIBUTE_CHANNEL, ++ GSCAN_ATTRIBUTE_RSSI, ++ GSCAN_ATTRIBUTE_TIMESTAMP, ++ GSCAN_ATTRIBUTE_RTT, ++ GSCAN_ATTRIBUTE_RTTSD, ++ ++ GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, ++ GSCAN_ATTRIBUTE_RSSI_LOW, ++ GSCAN_ATTRIBUTE_RSSI_HIGH, ++ GSCAN_ATTRIBUTE_HOTLIST_ELEM, ++ GSCAN_ATTRIBUTE_HOTLIST_FLUSH, ++ ++ GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, ++ GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, ++ GSCAN_ATTRIBUTE_MIN_BREACHING, ++ GSCAN_ATTRIBUTE_NUM_AP, ++ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, ++ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH ++ ++} GSCAN_ATTRIBUTE; ++ ++typedef enum { ++ RTT_ATTRIBUTE_CAPABILITIES = 1, ++ ++ RTT_ATTRIBUTE_TARGET_CNT = 10, ++ RTT_ATTRIBUTE_TARGET_INFO, ++ RTT_ATTRIBUTE_TARGET_MAC, ++ RTT_ATTRIBUTE_TARGET_TYPE, ++ RTT_ATTRIBUTE_TARGET_PEER, ++ RTT_ATTRIBUTE_TARGET_CHAN, ++ RTT_ATTRIBUTE_TARGET_PERIOD, ++ RTT_ATTRIBUTE_TARGET_NUM_BURST, ++ RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, ++ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, ++ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, ++ RTT_ATTRIBUTE_TARGET_LCI, ++ RTT_ATTRIBUTE_TARGET_LCR, ++ RTT_ATTRIBUTE_TARGET_BURST_DURATION, ++ RTT_ATTRIBUTE_TARGET_PREAMBLE, ++ RTT_ATTRIBUTE_TARGET_BW, ++ RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, ++ RTT_ATTRIBUTE_RESULTS_PER_TARGET, ++ RTT_ATTRIBUTE_RESULT_CNT, ++ RTT_ATTRIBUTE_RESULT ++} RTT_ATTRIBUTE; ++ ++typedef enum { ++ LSTATS_ATTRIBUTE_STATS = 2, ++} LSTATS_ATTRIBUTE; ++ ++typedef enum { ++ WIFI_BAND_UNSPECIFIED, ++ WIFI_BAND_BG = 1, /* 2.4 GHz */ ++ WIFI_BAND_A = 2, /* 5 GHz without DFS */ ++ WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */ ++ WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ ++ WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ ++ WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ ++} WIFI_BAND; ++ ++typedef enum { ++ WIFI_SCAN_BUFFER_FULL, ++ WIFI_SCAN_COMPLETE, ++} WIFI_SCAN_EVENT; ++ ++#define GSCAN_MAX_REPORT_THRESHOLD 1024000 ++#define GSCAN_MAX_CHANNELS 8 ++#define GSCAN_MAX_BUCKETS 8 ++#define MAX_HOTLIST_APS 16 ++#define MAX_SIGNIFICANT_CHANGE_APS 16 ++#define PSCAN_MAX_SCAN_CACHE_SIZE 16 ++#define PSCAN_MAX_AP_CACHE_PER_SCAN 16 ++#define PSCAN_VERSION 1 ++ ++#define MAX_BUFFERED_GSCN_RESULTS 5 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef UINT_64 wifi_timestamp; /* In microseconds (us) */ ++typedef UINT_64 wifi_timespan; /* In nanoseconds (ns) */ ++ ++typedef UINT_8 mac_addr[6]; ++typedef UINT_32 wifi_channel; /* Indicates channel frequency in MHz */ ++typedef INT_32 wifi_rssi; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++typedef struct _PARAM_WIFI_GSCAN_GET_RESULT_PARAMS { ++ UINT_32 get_num; ++ UINT_8 flush; ++} PARAM_WIFI_GSCAN_GET_RESULT_PARAMS, *P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS; ++ ++typedef struct _PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS { ++ UINT_8 ucPscanAct; ++ UINT_8 aucReserved[3]; ++} PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS; ++ ++typedef struct _PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T { ++ UINT_32 max_scan_cache_size; /* total space allocated for scan (in bytes) */ ++ UINT_32 max_scan_buckets; /* maximum number of channel buckets */ ++ UINT_32 max_ap_cache_per_scan; /* maximum number of APs that can be stored per scan */ ++ UINT_32 max_rssi_sample_size; /* number of RSSI samples used for averaging RSSI */ ++ UINT_32 max_scan_reporting_threshold; /* max possible report_threshold as described */ ++ /* in wifi_scan_cmd_params */ ++ UINT_32 max_hotlist_aps; /* maximum number of entries for hotlist APs */ ++ UINT_32 max_significant_wifi_change_aps; /* maximum number of entries for */ ++ /* significant wifi change APs */ ++ UINT_32 max_bssid_history_entries; /* number of BSSID/RSSI entries that device can hold */ ++} PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T, *P_PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T; ++ ++typedef struct _PARAM_WIFI_GSCAN_CHANNEL_SPEC { ++ UINT_32 channel; /* frequency */ ++ UINT_32 dwellTimeMs; /* dwell time hint */ ++ UINT_32 passive; /* 0 => active, 1 => passive scan; ignored for DFS */ ++ /* Add channel class */ ++} PARAM_WIFI_GSCAN_CHANNEL_SPEC, *P_PARAM_WIFI_GSCAN_CHANNEL_SPEC; ++ ++typedef struct _PARAM_WIFI_GSCAN_BUCKET_SPEC { ++ UINT_32 bucket; /* bucket index, 0 based */ ++ WIFI_BAND band; /* when UNSPECIFIED, use channel list */ ++ UINT_32 period; /* desired period, in millisecond; if this is too */ ++ /* low, the firmware should choose to generate results as */ ++ /* fast as it can instead of failing the command */ ++ /* report_events semantics - ++ * 0 => report only when scan history is % full ++ * 1 => same as 0 + report a scan completion event after scanning this bucket ++ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL ++ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to ++ supplicant as well (optional) . */ ++ UINT_8 report_events; ++ ++ UINT_32 num_channels; ++ PARAM_WIFI_GSCAN_CHANNEL_SPEC channels[GSCAN_MAX_CHANNELS]; /* channels to scan; ++ these may include DFS channels */ ++} PARAM_WIFI_GSCAN_BUCKET_SPEC, *P_PARAM_WIFI_GSCAN_BUCKET_SPEC; ++ ++typedef struct _PARAM_WIFI_GSCAN_CMD_PARAMS { ++ UINT_32 base_period; /* base timer period in ms */ ++ UINT_32 max_ap_per_scan; /* number of APs to store in each scan in the */ ++ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ ++ UINT_32 report_threshold; /* in %, when scan buffer is this much full, wake up AP */ ++ UINT_32 num_scans; ++ UINT_32 num_buckets; ++ PARAM_WIFI_GSCAN_BUCKET_SPEC buckets[GSCAN_MAX_BUCKETS]; ++} PARAM_WIFI_GSCAN_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_CMD_PARAMS; ++ ++typedef struct _PARAM_WIFI_GSCAN_RESULT { ++ wifi_timestamp ts; /* time since boot (in microsecond) when the result was */ ++ /* retrieved */ ++ UINT_8 ssid[32 + 1]; /* null terminated */ ++ mac_addr bssid; ++ wifi_channel channel; /* channel frequency in MHz */ ++ wifi_rssi rssi; /* in db */ ++ wifi_timespan rtt; /* in nanoseconds */ ++ wifi_timespan rtt_sd; /* standard deviation in rtt */ ++ UINT_16 beacon_period; /* period advertised in the beacon */ ++ UINT_16 capability; /* capabilities advertised in the beacon */ ++ UINT_32 ie_length; /* size of the ie_data blob */ ++ UINT_8 ie_data[1]; /* blob of all the information elements found in the */ ++ /* beacon; this data should be a packed list of */ ++ /* wifi_information_element objects, one after the other. */ ++ /* other fields */ ++} PARAM_WIFI_GSCAN_RESULT, *P_PARAM_WIFI_GSCAN_RESULT; ++ ++/* Significant wifi change*/ ++/*typedef struct _PARAM_WIFI_CHANGE_RESULT{ ++ mac_addr bssid; // BSSID ++ wifi_channel channel; // channel frequency in MHz ++ UINT_32 num_rssi; // number of rssi samples ++ wifi_rssi rssi[8]; // RSSI history in db ++} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT;*/ ++ ++typedef struct _PARAM_WIFI_CHANGE_RESULT { ++ UINT_16 flags; ++ UINT_16 channel; ++ mac_addr bssid; /* BSSID */ ++ INT_8 rssi[8]; /* RSSI history in db */ ++} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT; ++ ++typedef struct _PARAM_AP_THRESHOLD { ++ mac_addr bssid; /* AP BSSID */ ++ wifi_rssi low; /* low threshold */ ++ wifi_rssi high; /* high threshold */ ++ wifi_channel channel; /* channel hint */ ++} PARAM_AP_THRESHOLD, *P_PARAM_AP_THRESHOLD; ++ ++typedef struct _PARAM_WIFI_BSSID_HOTLIST { ++ UINT_32 lost_ap_sample_size; ++ UINT_32 num_ap; /* number of hotlist APs */ ++ PARAM_AP_THRESHOLD ap[MAX_HOTLIST_APS]; /* hotlist APs */ ++} PARAM_WIFI_BSSID_HOTLIST, *P_PARAM_WIFI_BSSID_HOTLIST; ++ ++typedef struct _PARAM_WIFI_SIGNIFICANT_CHANGE { ++ UINT_16 rssi_sample_size; /* number of samples for averaging RSSI */ ++ UINT_16 lost_ap_sample_size; /* number of samples to confirm AP loss */ ++ UINT_16 min_breaching; /* number of APs breaching threshold */ ++ UINT_16 num_ap; /* max 64 */ ++ PARAM_AP_THRESHOLD ap[MAX_SIGNIFICANT_CHANGE_APS]; ++} PARAM_WIFI_SIGNIFICANT_CHANGE, *P_PARAM_WIFI_SIGNIFICANT_CHANGE; ++ ++/* RTT Capabilities */ ++typedef struct _PARAM_WIFI_RTT_CAPABILITIES { ++ UINT_8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */ ++ UINT_8 rtt_ftm_supported; /* if ftm rtt data collection is supported */ ++ UINT_8 lci_support; /* if initiator supports LCI request. Applies to 2-sided RTT */ ++ UINT_8 lcr_support; /* if initiator supports LCR request. Applies to 2-sided RTT */ ++ UINT_8 preamble_support; /* bit mask indicates what preamble is supported by initiator */ ++ UINT_8 bw_support; /* bit mask indicates what BW is supported by initiator */ ++} PARAM_WIFI_RTT_CAPABILITIES, *P_PARAM_WIFI_RTT_CAPABILITIES; ++ ++/* channel operating width */ ++typedef enum { ++ WIFI_CHAN_WIDTH_20 = 0, ++ WIFI_CHAN_WIDTH_40 = 1, ++ WIFI_CHAN_WIDTH_80 = 2, ++ WIFI_CHAN_WIDTH_160 = 3, ++ WIFI_CHAN_WIDTH_80P80 = 4, ++ WIFI_CHAN_WIDTH_5 = 5, ++ WIFI_CHAN_WIDTH_10 = 6, ++ WIFI_CHAN_WIDTH_INVALID = -1 ++} WIFI_CHANNEL_WIDTH; ++ ++/* channel information */ ++typedef struct { ++ WIFI_CHANNEL_WIDTH width; /* channel width (20, 40, 80, 80+80, 160) */ ++ UINT_32 center_freq; /* primary 20 MHz channel */ ++ UINT_32 center_freq0; /* center frequency (MHz) first segment */ ++ UINT_32 center_freq1; /* center frequency (MHz) second segment */ ++} WIFI_CHANNEL_INFO; ++ ++/* channel statistics */ ++typedef struct { ++ WIFI_CHANNEL_INFO channel; /* channel */ ++ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ ++ UINT_32 cca_busy_time; /* msecs the CCA register is busy (32 bits number accruing over time) */ ++} WIFI_CHANNEL_STAT; ++ ++/* radio statistics */ ++typedef struct { ++ UINT_32 radio; /* wifi radio (if multiple radio supported) */ ++ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ ++ UINT_32 tx_time; /* msecs the radio is transmitting (32 bits number accruing over time) */ ++ UINT_32 rx_time; /* msecs the radio is in active receive (32 bits number accruing over time) */ ++ UINT_32 on_time_scan; /* msecs the radio is awake due to all scan (32 bits number accruing over time) */ ++ UINT_32 on_time_nbd; /* msecs the radio is awake due to NAN (32 bits number accruing over time) */ ++ UINT_32 on_time_gscan; /* msecs the radio is awake due to G?scan (32 bits number accruing over time) */ ++ UINT_32 on_time_roam_scan; /* msecs the radio is awake due to roam?scan ++ (32 bits number accruing over time) */ ++ UINT_32 on_time_pno_scan; /* msecs the radio is awake due to PNO scan ++ (32 bits number accruing over time) */ ++ UINT_32 on_time_hs20; /* msecs the radio is awake due to HS2.0 scans and GAS exchange ++ 32 bits number accruing over time) */ ++ UINT_32 num_channels; /* number of channels */ ++ WIFI_CHANNEL_STAT channels[]; /* channel statistics */ ++} WIFI_RADIO_STAT; ++ ++/* wifi rate */ ++typedef struct { ++ UINT_32 preamble:3; /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ ++ UINT_32 nss:2; /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ ++ UINT_32 bw:3; /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ ++ UINT_32 rateMcsIdx:8; /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ ++ /* HT/VHT it would be mcs index */ ++ UINT_32 reserved:16; /* reserved */ ++ UINT_32 bitrate; /* units of 100 Kbps */ ++} WIFI_RATE; ++ ++/* per rate statistics */ ++typedef struct { ++ WIFI_RATE rate; /* rate information */ ++ UINT_32 tx_mpdu; /* number of successfully transmitted data pkts (ACK rcvd) */ ++ UINT_32 rx_mpdu; /* number of received data pkts */ ++ UINT_32 mpdu_lost; /* number of data packet losses (no ACK) */ ++ UINT_32 retries; /* total number of data pkt retries */ ++ UINT_32 retries_short; /* number of short data pkt retries */ ++ UINT_32 retries_long; /* number of long data pkt retries */ ++} WIFI_RATE_STAT; ++ ++/*wifi_interface_link_layer_info*/ ++typedef enum { ++ WIFI_DISCONNECTED = 0, ++ WIFI_AUTHENTICATING = 1, ++ WIFI_ASSOCIATING = 2, ++ WIFI_ASSOCIATED = 3, ++ WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ ++ WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ ++} WIFI_CONNECTION_STATE; ++ ++typedef enum { ++ WIFI_ROAMING_IDLE = 0, ++ WIFI_ROAMING_ACTIVE = 1, ++} WIFI_ROAM_STATE; ++ ++typedef enum { ++ WIFI_INTERFACE_STA = 0, ++ WIFI_INTERFACE_SOFTAP = 1, ++ WIFI_INTERFACE_IBSS = 2, ++ WIFI_INTERFACE_P2P_CLIENT = 3, ++ WIFI_INTERFACE_P2P_GO = 4, ++ WIFI_INTERFACE_NAN = 5, ++ WIFI_INTERFACE_MESH = 6, ++ WIFI_INTERFACE_UNKNOWN = -1 ++} WIFI_INTERFACE_MODE; ++ ++typedef struct { ++ WIFI_INTERFACE_MODE mode; /* interface mode */ ++ u8 mac_addr[6]; /* interface mac address (self) */ ++ WIFI_CONNECTION_STATE state; /* connection state (valid for STA, CLI only) */ ++ WIFI_ROAM_STATE roaming; /* roaming state */ ++ u32 capabilities; /* WIFI_CAPABILITY_XXX (self) */ ++ u8 ssid[33]; /* null terminated SSID */ ++ u8 bssid[6]; /* bssid */ ++ u8 ap_country_str[3]; /* country string advertised by AP */ ++ u8 country_str[3]; /* country string for this association */ ++} WIFI_INTERFACE_LINK_LAYER_INFO; ++ ++/* access categories */ ++typedef enum { ++ WIFI_AC_VO = 0, ++ WIFI_AC_VI = 1, ++ WIFI_AC_BE = 2, ++ WIFI_AC_BK = 3, ++ WIFI_AC_MAX = 4, ++} WIFI_TRAFFIC_AC; ++ ++/* wifi peer type */ ++typedef enum { ++ WIFI_PEER_STA, ++ WIFI_PEER_AP, ++ WIFI_PEER_P2P_GO, ++ WIFI_PEER_P2P_CLIENT, ++ WIFI_PEER_NAN, ++ WIFI_PEER_TDLS, ++ WIFI_PEER_INVALID, ++} WIFI_PEER_TYPE; ++ ++/* per peer statistics */ ++typedef struct { ++ WIFI_PEER_TYPE type; /* peer type (AP, TDLS, GO etc.) */ ++ UINT_8 peer_mac_address[6]; /* mac address */ ++ UINT_32 capabilities; /* peer WIFI_CAPABILITY_XXX */ ++ UINT_32 num_rate; /* number of rates */ ++ WIFI_RATE_STAT rate_stats[]; /* per rate statistics, number of entries = num_rate */ ++} WIFI_PEER_INFO; ++ ++/* per access category statistics */ ++typedef struct { ++ WIFI_TRAFFIC_AC ac; /* access category (VI, VO, BE, BK) */ ++ UINT_32 tx_mpdu; /* number of successfully transmitted unicast data pkts (ACK rcvd) */ ++ UINT_32 rx_mpdu; /* number of received unicast mpdus */ ++ UINT_32 tx_mcast; /* number of successfully transmitted multicast data packets */ ++ /* STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent */ ++ UINT_32 rx_mcast; /* number of received multicast data packets */ ++ UINT_32 rx_ampdu; /* number of received unicast a-mpdus */ ++ UINT_32 tx_ampdu; /* number of transmitted unicast a-mpdus */ ++ UINT_32 mpdu_lost; /* number of data pkt losses (no ACK) */ ++ UINT_32 retries; /* total number of data pkt retries */ ++ UINT_32 retries_short; /* number of short data pkt retries */ ++ UINT_32 retries_long; /* number of long data pkt retries */ ++ UINT_32 contention_time_min; /* data pkt min contention time (usecs) */ ++ UINT_32 contention_time_max; /* data pkt max contention time (usecs) */ ++ UINT_32 contention_time_avg; /* data pkt avg contention time (usecs) */ ++ UINT_32 contention_num_samples; /* num of data pkts used for contention statistics */ ++} WIFI_WMM_AC_STAT; ++ ++/* interface statistics */ ++typedef struct { ++ /* wifi_interface_handle iface; // wifi interface */ ++ WIFI_INTERFACE_LINK_LAYER_INFO info; /* current state of the interface */ ++ UINT_32 beacon_rx; /* access point beacon received count from connected AP */ ++ UINT_32 mgmt_rx; /* access point mgmt frames received count from connected AP (including Beacon) */ ++ UINT_32 mgmt_action_rx; /* action frames received count */ ++ UINT_32 mgmt_action_tx; /* action frames transmit count */ ++ wifi_rssi rssi_mgmt; /* access Point Beacon and Management frames RSSI (averaged) */ ++ wifi_rssi rssi_data; /* access Point Data Frames RSSI (averaged) from connected AP */ ++ wifi_rssi rssi_ack; /* access Point ACK RSSI (averaged) from connected AP */ ++ WIFI_WMM_AC_STAT ac[WIFI_AC_MAX]; /* per ac data packet statistics */ ++ UINT_32 num_peers; /* number of peers */ ++ WIFI_PEER_INFO peer_info[]; /* per peer statistics */ ++} WIFI_IFACE_STAT; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete); ++ ++int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num); ++ ++int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); ++ ++int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len); ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); ++ ++#endif /* _GL_VENDOR_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h +new file mode 100644 +index 000000000000..827ff92b1581 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h +@@ -0,0 +1,357 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext.h#1 ++*/ ++ ++/*! \file gl_wext.h ++ \brief This file is for Portable Driver linux wireless extension support. ++*/ ++ ++/* ++** Log: gl_wext.h ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 01 11 2011 chinglan.wang ++ * NULL ++ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. ++ * Connection establish successfully. ++ * Use the WPS function to connect AP, the privacy bit always is set to 1. . ++ * ++ * 09 27 2010 wh.su ++ * NULL ++ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\12 2009-10-20 17:38:33 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\11 2009-09-28 20:19:28 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\10 2009-09-03 12:12:35 GMT mtk01088 ++** adding the function declaration ++** \main\maintrunk.MT5921\9 2009-08-18 22:57:17 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\8 2008-08-29 16:59:07 GMT mtk01088 ++** fixed compiling error ++** \main\maintrunk.MT5921\7 2008-08-29 14:13:28 GMT mtk01088 ++** adjust the header file for code refine ++** \main\maintrunk.MT5921\6 2008-03-28 10:40:31 GMT mtk01461 ++** Add set desired rate in Linux STD IOCTL ++** \main\maintrunk.MT5921\5 2008-03-11 14:51:08 GMT mtk01461 ++** Refine private IOCTL functions ++** \main\maintrunk.MT5921\4 2008-02-12 23:45:45 GMT mtk01461 ++** Add Set Frequency & Channel oid support for Linux ++** \main\maintrunk.MT5921\3 2007-11-06 19:36:19 GMT mtk01088 ++** add the WPS related code ++*/ ++ ++#ifndef _GL_WEXT_H ++#define _GL_WEXT_H ++ ++#ifdef WIRELESS_EXT ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define KILO 1000 ++#define RATE_5_5M 11 /* 5.5M */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _PARAM_FIXED_IEs { ++ UINT_8 aucTimestamp[8]; ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2Capabilities; ++} PARAM_FIXED_IEs; ++ ++typedef struct _PARAM_VARIABLE_IE_T { ++ UINT_8 ucElementID; ++ UINT_8 ucLength; ++ UINT_8 aucData[1]; ++} PARAM_VARIABLE_IE_T, *P_PARAM_VARIABLE_IE_T; ++ ++#if WIRELESS_EXT < 18 ++ ++#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses struct iw_mlme */ ++/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ ++#define IW_MLME_DEAUTH 0 ++#define IW_MLME_DISASSOC 1 ++ ++/*! \brief SIOCSIWMLME data */ ++struct iw_mlme { ++ __u16 cmd; /*!< IW_MLME_* */ ++ __u16 reason_code; ++ struct sockaddr addr; ++}; ++ ++#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ ++#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ ++/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ ++#define IW_AUTH_INDEX 0x0FFF ++#define IW_AUTH_FLAGS 0xF000 ++/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) ++ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the ++ * parameter that is being set/get to; value will be read/written to ++ * struct iw_param value field) */ ++#define IW_AUTH_WPA_VERSION 0 ++#define IW_AUTH_CIPHER_PAIRWISE 1 ++#define IW_AUTH_CIPHER_GROUP 2 ++#define IW_AUTH_KEY_MGMT 3 ++#define IW_AUTH_TKIP_COUNTERMEASURES 4 ++#define IW_AUTH_DROP_UNENCRYPTED 5 ++#define IW_AUTH_80211_AUTH_ALG 6 ++#define IW_AUTH_WPA_ENABLED 7 ++#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 ++#define IW_AUTH_ROAMING_CONTROL 9 ++#define IW_AUTH_PRIVACY_INVOKED 10 ++#if CFG_SUPPORT_802_11W ++#define IW_AUTH_MFP 12 ++ ++#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ ++#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ ++#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ ++#endif ++ ++/* IW_AUTH_WPA_VERSION values (bit field) */ ++#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 ++#define IW_AUTH_WPA_VERSION_WPA 0x00000002 ++#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 ++ ++/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ ++#define IW_AUTH_CIPHER_NONE 0x00000001 ++#define IW_AUTH_CIPHER_WEP40 0x00000002 ++#define IW_AUTH_CIPHER_TKIP 0x00000004 ++#define IW_AUTH_CIPHER_CCMP 0x00000008 ++#define IW_AUTH_CIPHER_WEP104 0x00000010 ++ ++/* IW_AUTH_KEY_MGMT values (bit field) */ ++#define IW_AUTH_KEY_MGMT_802_1X 1 ++#define IW_AUTH_KEY_MGMT_PSK 2 ++#define IW_AUTH_KEY_MGMT_WPA_NONE 4 ++ ++/* IW_AUTH_80211_AUTH_ALG values (bit field) */ ++#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 ++#define IW_AUTH_ALG_SHARED_KEY 0x00000002 ++#define IW_AUTH_ALG_LEAP 0x00000004 ++ ++/* IW_AUTH_ROAMING_CONTROL values */ ++#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ ++#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming ++ * control */ ++ ++#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ ++#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ ++/* SIOCSIWENCODEEXT definitions */ ++#define IW_ENCODE_SEQ_MAX_SIZE 8 ++/* struct iw_encode_ext ->alg */ ++#define IW_ENCODE_ALG_NONE 0 ++#define IW_ENCODE_ALG_WEP 1 ++#define IW_ENCODE_ALG_TKIP 2 ++#define IW_ENCODE_ALG_CCMP 3 ++#if CFG_SUPPORT_802_11W ++#define IW_ENCODE_ALG_AES_CMAC 5 ++#endif ++ ++/* struct iw_encode_ext ->ext_flags */ ++#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 ++#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 ++#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 ++#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 ++ ++struct iw_encode_ext { ++ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ ++ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ struct sockaddr addr; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast ++ * (group) keys or unicast address for ++ * individual keys */ ++ __u16 alg; /*!< IW_ENCODE_ALG_* */ ++ __u16 key_len; ++ __u8 key[0]; ++}; ++ ++#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ ++#define IW_PMKSA_ADD 1 ++#define IW_PMKSA_REMOVE 2 ++#define IW_PMKSA_FLUSH 3 ++ ++#define IW_PMKID_LEN 16 ++ ++struct iw_pmksa { ++ __u32 cmd; /*!< IW_PMKSA_* */ ++ struct sockaddr bssid; ++ __u8 pmkid[IW_PMKID_LEN]; ++}; ++ ++#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) ++ * (scan results); This includes id and ++ * length fields. One IWEVGENIE may ++ * contain more than one IE. Scan ++ * results may contain one or more ++ * IWEVGENIE events. */ ++#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure ++ * (struct iw_michaelmicfailure) ++ */ ++#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. ++ * The data includes id and length ++ * fields and may contain more than one ++ * IE. This event is required in ++ * Managed mode if the driver ++ * generates its own WPA/RSN IE. This ++ * should be sent just before ++ * IWEVREGISTERED event for the ++ * association. */ ++#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association ++ * Response. The data includes id and ++ * length fields and may contain more ++ * than one IE. This may be sent ++ * between IWEVASSOCREQIE and ++ * IWEVREGISTERED events for the ++ * association. */ ++#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN ++ * pre-authentication ++ * (struct iw_pmkid_cand) */ ++ ++#endif /* WIRELESS_EXT < 18 */ ++ ++#if WIRELESS_EXT < 17 ++/* Statistics flags (bitmask in updated) */ ++#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ ++#define IW_QUAL_LEVEL_UPDATED 0x2 ++#define IW_QUAL_NOISE_UPDATED 0x4 ++#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ ++#define IW_QUAL_LEVEL_INVALID 0x20 ++#define IW_QUAL_NOISE_INVALID 0x40 ++#endif ++ ++enum { ++ IEEE80211_FILTER_TYPE_BEACON = 1 << 0, ++ IEEE80211_FILTER_TYPE_PROBE_REQ = 1 << 1, ++ IEEE80211_FILTER_TYPE_PROBE_RESP = 1 << 2, ++ IEEE80211_FILTER_TYPE_ASSOC_REQ = 1 << 3, ++ IEEE80211_FILTER_TYPE_ASSOC_RESP = 1 << 4, ++ IEEE80211_FILTER_TYPE_AUTH = 1 << 5, ++ IEEE80211_FILTER_TYPE_DEAUTH = 1 << 6, ++ IEEE80211_FILTER_TYPE_DISASSOC = 1 << 7, ++ IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ ++}; ++ ++#if CFG_SUPPORT_WAPI ++#define IW_AUTH_WAPI_ENABLED 0x20 ++#define IW_ENCODE_ALG_SMS4 0x20 ++#endif ++ ++#if CFG_SUPPORT_WAPI /* Android+ */ ++#define IW_AUTH_KEY_MGMT_WAPI_PSK 3 ++#define IW_AUTH_KEY_MGMT_WAPI_CERT 4 ++#endif ++#define IW_AUTH_KEY_MGMT_WPS 5 ++ ++#if CFG_SUPPORT_802_11W ++#define IW_AUTH_KEY_MGMT_802_1X_SHA256 7 ++#define IW_AUTH_KEY_MGMT_PSK_SHA256 8 ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern const struct iw_handler_def wext_handler_def; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* wireless extensions' ioctls */ ++int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd); ++ ++int ++wext_set_rate(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra); ++ ++void ++wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, ++ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4DataLen); ++ ++struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev); ++ ++BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++ ++#if CFG_SUPPORT_WPS ++BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++ ++BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++ ++BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++ ++BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++#if CFG_SUPPORT_WAPI ++BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* WIRELESS_EXT */ ++ ++#endif /* _GL_WEXT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h +new file mode 100644 +index 000000000000..31933fc6a461 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h +@@ -0,0 +1,402 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext_priv.h#3 ++*/ ++ ++/*! \file gl_wext_priv.h ++ \brief This file includes private ioctl support. ++*/ ++ ++/* ++** Log: gl_wext_priv.h ++ * ++ * 01 16 2012 wh.su ++ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl ++ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service ++ * discovery version check. ++ * Add a CMD ID for P2P driver version query. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 01 27 2011 cm.chang ++ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default ++ * . ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 07 2011 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add a new compiling option to control if MCR read/write is permitted ++ * ++ * 12 31 2010 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add some iwpriv commands to support test mode operation ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\16 2009-09-29 16:47:23 GMT mtk01090 ++** Remove unused functions ++** \main\maintrunk.MT5921\15 2009-09-28 20:19:31 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\14 2009-05-07 22:26:06 GMT mtk01089 ++** add private IO control for Linux BWCS ++** \main\maintrunk.MT5921\13 2008-08-29 14:55:20 GMT mtk01088 ++** adjust the code to meet coding style ++** \main\maintrunk.MT5921\12 2008-07-16 15:23:45 GMT mtk01104 ++** Support GPIO2 mode ++** \main\maintrunk.MT5921\11 2008-07-14 13:55:58 GMT mtk01104 ++** Support PRIV_CMD_BT_COEXIST ++** \main\maintrunk.MT5921\10 2008-07-09 00:20:24 GMT mtk01461 ++** Add priv oid to support WMM_PS_TEST ++** \main\maintrunk.MT5921\9 2008-05-30 20:27:24 GMT mtk01461 ++** Add POWER_MODE Private IOCTL cmd ++** \main\maintrunk.MT5921\8 2008-04-17 23:06:44 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\7 2008-03-31 21:01:24 GMT mtk01461 ++** Add priv IOCTL for VOIP settings ++** \main\maintrunk.MT5921\6 2008-03-31 13:49:47 GMT mtk01461 ++** add priv ioctl arg definition for turning on / off roaming ++** \main\maintrunk.MT5921\5 2008-03-26 15:35:09 GMT mtk01461 ++** Add CSUM offload priv ioctl for Linux ++** \main\maintrunk.MT5921\4 2008-03-11 14:51:11 GMT mtk01461 ++** Refine private IOCTL functions ++** \main\maintrunk.MT5921\3 2007-11-06 19:36:25 GMT mtk01088 ++** add the WPS related code ++*/ ++ ++#ifndef _GL_WEXT_PRIV_H ++#define _GL_WEXT_PRIV_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++/* If it is set to 1, iwpriv will support register read/write */ ++#define CFG_SUPPORT_PRIV_MCR_RW 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++extern int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); ++#if 0 ++extern BOOLEAN fgIsResetting; ++extern BOOLEAN g_u4HaltFlag; ++extern spinlock_t g_p2p_lock; ++extern int g_u4P2PEnding; ++extern int g_u4P2POnOffing; ++#endif ++#endif ++ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++extern VOID rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* New wireless extensions API - SET/GET convention (even ioctl numbers are ++ * root only) ++ */ ++#define IOCTL_SET_INT (SIOCIWFIRSTPRIV + 0) ++#define IOCTL_GET_INT (SIOCIWFIRSTPRIV + 1) ++ ++#define IOCTL_SET_ADDRESS (SIOCIWFIRSTPRIV + 2) ++#define IOCTL_GET_ADDRESS (SIOCIWFIRSTPRIV + 3) ++#define IOCTL_SET_STR (SIOCIWFIRSTPRIV + 4) ++#define IOCTL_GET_STR (SIOCIWFIRSTPRIV + 5) ++#define IOCTL_SET_KEY (SIOCIWFIRSTPRIV + 6) ++#define IOCTL_GET_KEY (SIOCIWFIRSTPRIV + 7) ++#define IOCTL_SET_STRUCT (SIOCIWFIRSTPRIV + 8) ++#define IOCTL_GET_STRUCT (SIOCIWFIRSTPRIV + 9) ++#define IOCTL_SET_STRUCT_FOR_EM (SIOCIWFIRSTPRIV + 11) ++#define IOCTL_SET_INTS (SIOCIWFIRSTPRIV + 12) ++#define IOCTL_GET_INTS (SIOCIWFIRSTPRIV + 13) ++#define IOCTL_SET_STRING (SIOCIWFIRSTPRIV + 14) ++ ++#define PRIV_CMD_REG_DOMAIN 0 ++#define PRIV_CMD_BEACON_PERIOD 1 ++#define PRIV_CMD_ADHOC_MODE 2 ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++#define PRIV_CMD_CSUM_OFFLOAD 3 ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++#define PRIV_CMD_ROAMING 4 ++#define PRIV_CMD_VOIP_DELAY 5 ++#define PRIV_CMD_POWER_MODE 6 ++ ++#define PRIV_CMD_WMM_PS 7 ++#define PRIV_CMD_BT_COEXIST 8 ++#define PRIV_GPIO2_MODE 9 ++ ++#define PRIV_CUSTOM_SET_PTA 10 ++#define PRIV_CUSTOM_CONTINUOUS_POLL 11 ++#define PRIV_CUSTOM_SINGLE_ANTENNA 12 ++#define PRIV_CUSTOM_BWCS_CMD 13 ++#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION 14 /* later */ ++#define PRIV_CMD_OID 15 ++#define PRIV_SEC_MSG_OID 16 ++ ++#define PRIV_CMD_TEST_MODE 17 ++#define PRIV_CMD_TEST_CMD 18 ++#define PRIV_CMD_ACCESS_MCR 19 ++#define PRIV_CMD_SW_CTRL 20 ++ ++#if 1 /* ANTI_PRIVCY */ ++#define PRIV_SEC_CHECK_OID 21 ++#endif ++ ++#define PRIV_CMD_WSC_PROBE_REQ 22 ++ ++#define PRIV_CMD_P2P_VERSION 23 ++ ++#define PRIV_CMD_GET_CH_LIST 24 ++ ++#define PRIV_CMD_SET_TX_POWER 25 ++ ++#define PRIV_CMD_BAND_CONFIG 26 ++ ++#define PRIV_CMD_DUMP_MEM 27 ++ ++#define PRIV_CMD_P2P_MODE 28 ++ ++#define PRIV_CMD_GET_BUILD_DATE_CODE 29 ++ ++#define PRIV_CMD_GET_DEBUG_CODE 30 ++ ++#define PRIV_CMD_OTHER 31 ++ ++#define PRIV_CMD_WFD_DEBUG_CODE 32 ++ ++#define PRIV_CMD_MET_PROFILING 33 ++ ++/* other string command ID */ ++#define PRIV_CMD_OTHER_TDLS 0x00 ++#define PRIV_CMD_OTHER_TAR 0x01 /* TX auto rate */ ++ ++/* 802.3 Objects (Ethernet) */ ++#define OID_802_3_CURRENT_ADDRESS 0x01010102 ++ ++/* IEEE 802.11 OIDs */ ++#define OID_802_11_SUPPORTED_RATES 0x0D01020E ++#define OID_802_11_CONFIGURATION 0x0D010211 ++ ++/* PnP and PM OIDs, NDIS default OIDS */ ++#define OID_PNP_SET_POWER 0xFD010101 ++ ++#define OID_CUSTOM_OID_INTERFACE_VERSION 0xFFA0C000 ++ ++/* MT5921 specific OIDs */ ++#define OID_CUSTOM_BT_COEXIST_CTRL 0xFFA0C580 ++#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE 0xFFA0C581 ++#define OID_CUSTOM_PATTERN_CONFIG 0xFFA0C582 ++#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG 0xFFA0C583 ++#define OID_CUSTOM_VOIP_SETUP 0xFFA0C584 ++#define OID_CUSTOM_ADD_TS 0xFFA0C585 ++#define OID_CUSTOM_DEL_TS 0xFFA0C586 ++#define OID_CUSTOM_SLT 0xFFA0C587 ++#define OID_CUSTOM_ROAMING_EN 0xFFA0C588 ++#define OID_CUSTOM_WMM_PS_TEST 0xFFA0C589 ++#define OID_CUSTOM_COUNTRY_STRING 0xFFA0C58A ++#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY 0xFFA0C58B ++#define OID_CUSTOM_GPIO2_MODE 0xFFA0C58C ++#define OID_CUSTOM_CONTINUOUS_POLL 0xFFA0C58D ++#define OID_CUSTOM_DISABLE_BEACON_DETECTION 0xFFA0C58E ++ ++/* CR1460, WPS privacy bit check disable */ ++#define OID_CUSTOM_DISABLE_PRIVACY_CHECK 0xFFA0C600 ++ ++/* Precedent OIDs */ ++#define OID_CUSTOM_MCR_RW 0xFFA0C801 ++#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 ++#define OID_CUSTOM_SW_CTRL 0xFFA0C805 ++#define OID_CUSTOM_MEM_DUMP 0xFFA0C807 ++ ++/* RF Test specific OIDs */ ++#define OID_CUSTOM_TEST_MODE 0xFFA0C901 ++#define OID_CUSTOM_TEST_RX_STATUS 0xFFA0C903 ++#define OID_CUSTOM_TEST_TX_STATUS 0xFFA0C905 ++#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 ++#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 ++ ++/* BWCS */ ++#define OID_CUSTOM_BWCS_CMD 0xFFA0C931 ++#define OID_CUSTOM_SINGLE_ANTENNA 0xFFA0C932 ++#define OID_CUSTOM_SET_PTA 0xFFA0C933 ++ ++/* NVRAM */ ++#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 ++#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 ++#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 ++ ++#if CFG_SUPPORT_WAPI ++#define OID_802_11_WAPI_MODE 0xFFA0CA00 ++#define OID_802_11_WAPI_ASSOC_INFO 0xFFA0CA01 ++#define OID_802_11_SET_WAPI_KEY 0xFFA0CA02 ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++#define OID_802_11_WSC_ASSOC_INFO 0xFFA0CB00 ++#endif ++ ++/* Define magic key of test mode (Don't change it for future compatibity) */ ++#define PRIV_CMD_TEST_MAGIC_KEY 2011 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* NIC BBCR configuration entry structure */ ++typedef struct _PRIV_CONFIG_ENTRY { ++ UINT_8 ucOffset; ++ UINT_8 ucValue; ++} PRIV_CONFIG_ENTRY, *PPRIV_CONFIG_ENTRY; ++ ++typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC_REQ) (IN PVOID prAdapter, ++ IN OUT PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); ++ ++typedef enum _ENUM_OID_METHOD_T { ++ ENUM_OID_GLUE_ONLY, ++ ENUM_OID_GLUE_EXTENSION, ++ ENUM_OID_DRIVER_CORE ++} ENUM_OID_METHOD_T, *P_ENUM_OID_METHOD_T; ++ ++/* OID set/query processing entry */ ++typedef struct _WLAN_REQ_ENTRY { ++ UINT_32 rOid; /* OID */ ++ PUINT_8 pucOidName; /* OID name text */ ++ BOOLEAN fgQryBufLenChecking; ++ BOOLEAN fgSetBufLenChecking; ++ ENUM_OID_METHOD_T eOidMethod; ++ UINT_32 u4InfoBufLen; ++ PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler; /* PFN_OID_HANDLER_FUNC */ ++ PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler; /* PFN_OID_HANDLER_FUNC */ ++} WLAN_REQ_ENTRY, *P_WLAN_REQ_ENTRY; ++ ++typedef struct _NDIS_TRANSPORT_STRUCT { ++ UINT_32 ndisOidCmd; ++ UINT_32 inNdisOidlength; ++ UINT_32 outNdisOidLength; ++ UINT_8 ndisOidContent[16]; ++} NDIS_TRANSPORT_STRUCT, *P_NDIS_TRANSPORT_STRUCT; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++int ++priv_set_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int ++priv_get_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); ++ ++int ++priv_set_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int ++priv_get_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); ++ ++int ++priv_set_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int ++priv_get_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); ++ ++UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen); ++ ++UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac); ++ ++int ++priv_set_string(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int priv_support_ioctl(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); ++ ++int priv_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); ++ ++INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_WEXT_PRIV_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c +new file mode 100644 +index 000000000000..fba854cfd68e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c +@@ -0,0 +1,542 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#1 ++*/ ++ ++/*! \file "platform.c" ++ \brief This file including the protocol layer privacy function. ++ ++ This file provided the macros and functions library support for the ++ protocol layer security setting from wlan_oid.c and for parse.c and ++ rsn.c and nic_privacy.c ++ ++*/ ++ ++/* ++** Log: platform.c ++ * ++ * 11 14 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 09 13 2011 jeffrey.chang ++ * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection ++ * fix the pointer casting ++ * ++ * 06 29 2011 george.huang ++ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 ++ * . ++ * ++ * 06 28 2011 george.huang ++ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 ++ * remove un-used code ++ * ++ * 05 11 2011 jeffrey.chang ++ * NULL ++ * fix build error ++ * ++ * 05 09 2011 jeffrey.chang ++ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change ++ * support ARP filter through kernel notifier ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 18 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * remove early suspend functions ++ * ++ * 03 03 2011 jeffrey.chang ++ * NULL ++ * add the ARP filter callback ++ * ++ * 02 15 2011 jeffrey.chang ++ * NULL ++ * to support early suspend in android ++ * ++ * 02 01 2011 cp.wu ++ * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 ++ * branch ++ * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/... ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++** ++*/ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "gl_os.h" ++ ++#ifndef CONFIG_X86 ++#if defined(CONFIG_HAS_EARLY_SUSPEND) ++#include ++#endif ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define WIFI_NVRAM_FILE_NAME "/etc/firmware/nvram/WIFI" ++#define WIFI_NVRAM_CUSTOM_NAME "/etc/firmware/nvram/WIFI_CUSTOM" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) ++{ ++ UINT_8 ip[4] = { 0 }; ++ UINT_32 u4NumIPv4 = 0; ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++ UINT_32 u4NumIPv6 = 0; ++#endif ++ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; ++ struct net_device *prDev = ifa->ifa_dev->dev; ++ UINT_32 i; ++ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (prDev == NULL) { ++ DBGLOG(REQ, ERROR, "netdev_event: device is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ DBGLOG(REQ, INFO, "netdev_event, addr=%x, notification=%lx, dev_name=%s\n", ++ ifa->ifa_address, notification, prDev->name); ++ if (!fgIsUnderSuspend) ++ return NOTIFY_DONE; ++ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { ++ DBGLOG(REQ, WARN, "netdev_event: not our device\n"); ++ return NOTIFY_DONE; ++ } ++#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ ++ { ++ /* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */ ++ prGlueInfo->fgIsDad = FALSE; ++ } ++#endif ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ if (prGlueInfo == NULL) { ++ DBGLOG(REQ, ERROR, "netdev_event: prGlueInfo is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ ASSERT(prGlueInfo); ++ ++ /* <3> get the IPv4 address */ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(REQ, INFO, "ip is not available.\n"); ++ return NOTIFY_DONE; ++ } ++ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ DBGLOG(REQ, INFO, "ip is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); ++ ++ /* todo: traverse between list to find whole sets of IPv4 addresses */ ++ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) ++ u4NumIPv4++; ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(REQ, INFO, "ipv6 is not available.\n"); ++ return NOTIFY_DONE; ++ } ++ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(REQ, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); ++ ++ /* todo: traverse between list to find whole sets of IPv6 addresses */ ++ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) ++ /* u4NumIPv6++; */ ++#endif ++ ++ /* here we can compare the dev with other network's netdev to */ ++ /* set the proper arp filter */ ++ /* */ ++ /* IMPORTANT: please make sure if the context can sleep, if the context can't sleep */ ++ /* we should schedule a kernel thread to do this for us */ ++ ++ /* <7> set up the ARP filter */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen = 0; ++ UINT_8 aucBuf[32] = { 0 }; ++ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) aucBuf; ++ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; ++ ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6; ++#else ++ prParamNetAddrList->u4AddressCount = u4NumIPv4; ++#endif ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ for (i = 0; i < u4NumIPv4; i++) { ++ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++#if 0 ++ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); ++#else ++ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; ++ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); ++ prParamNetAddr = ++ (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); ++#endif ++ } ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ for (i = 0; i < u4NumIPv6; i++) { ++ prParamNetAddr->u2AddressLength = 6; ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip6)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); ++ } ++#endif ++ ASSERT(u4Len <= sizeof(aucBuf)); ++ ++ DBGLOG(REQ, INFO, "kalIoctl (0x%p, 0x%p)\n", prGlueInfo, prParamNetAddrList); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "set HW pattern filter fail 0x%x\n", rStatus); ++ } ++ ++ return NOTIFY_DONE; ++ ++} ++ ++/* #if CFG_SUPPORT_HOTSPOT_2_0 */ ++#if 0 ++static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr) ++{ ++ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; ++ struct net_device *prDev = ifa->idev->dev; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (prDev == NULL) { ++ DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ ++ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { ++ DBGLOG(REQ, INFO, "net6dev_event: xxx\n"); ++ return NOTIFY_DONE; ++ } ++ ++ if (strncmp(prDev->name, "p2p", 3) == 0) { ++ /* because we store the address of prGlueInfo in p2p's private date of net device */ ++ /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ } else { /* wlan0 */ ++ prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); ++ } ++ ++ if (prGlueInfo == NULL) { ++ DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */ ++ prGlueInfo->fgIs6Dad = FALSE; ++ ++ return NOTIFY_DONE; ++} ++#endif ++ ++static struct notifier_block inetaddr_notifier = { ++ .notifier_call = netdev_event, ++}; ++ ++#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ ++static struct notifier_block inet6addr_notifier = { ++ .notifier_call = net6dev_event, ++}; ++#endif ++ ++void wlanRegisterNotifier(void) ++{ ++ register_inetaddr_notifier(&inetaddr_notifier); ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ /* register_inet6addr_notifier(&inet6addr_notifier); */ ++#endif ++} ++ ++/* EXPORT_SYMBOL(wlanRegisterNotifier); */ ++ ++void wlanUnregisterNotifier(void) ++{ ++ unregister_inetaddr_notifier(&inetaddr_notifier); ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ /* unregister_inetaddr_notifier(&inet6addr_notifier); */ ++#endif ++} ++ ++/* EXPORT_SYMBOL(wlanUnregisterNotifier); */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Utility function for reading data from files on NVRAM-FS ++* ++* \param[in] ++* filename ++* len ++* offset ++* \param[out] ++* buf ++* \return ++* actual length of data being read ++*/ ++/*----------------------------------------------------------------------------*/ ++static int nvram_read(char *filename, char *buf, ssize_t len, int offset) ++{ ++#if CFG_SUPPORT_NVRAM ++ struct file *fd; ++ int retLen = -1; ++ ++ mm_segment_t old_fs = get_fs(); ++ ++ set_fs(KERNEL_DS); ++ ++ fd = filp_open(filename, O_RDONLY, 0644); ++ ++ if (IS_ERR(fd)) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to open!!\n"); ++ return -1; ++ } ++ ++ do { ++ //if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) { ++ if ( fd->f_op == NULL ) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : file can not be read!!\n"); ++ break; ++ } ++ ++ if (fd->f_pos != offset) { ++ if (fd->f_op->llseek) { ++ if (fd->f_op->llseek(fd, offset, 0) != offset) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to seek!!\n"); ++ break; ++ } ++ } else { ++ fd->f_pos = offset; ++ } ++ } ++ ++ retLen = vfs_read(fd, buf, len, &fd->f_pos); ++ ++ } while (FALSE); ++ ++ filp_close(fd, NULL); ++ ++ set_fs(old_fs); ++ ++ return retLen; ++ ++#else /* !CFG_SUPPORT_NVRAM */ ++ ++ return -EIO; ++ ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Utility function for writing data to files on NVRAM-FS ++* ++* \param[in] ++* filename ++* buf ++* len ++* offset ++* \return ++* actual length of data being written ++*/ ++/*----------------------------------------------------------------------------*/ ++static int nvram_write(char *filename, char *buf, ssize_t len, int offset) ++{ ++#if CFG_SUPPORT_NVRAM ++ struct file *fd; ++ int retLen = -1; ++ ++ mm_segment_t old_fs = get_fs(); ++ ++ set_fs(KERNEL_DS); ++ ++ fd = filp_open(filename, O_WRONLY | O_CREAT, 0644); ++ ++ if (IS_ERR(fd)) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to open!!\n"); ++ return -1; ++ } ++ ++ do { ++ if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : file can not be write!!\n"); ++ break; ++ } ++ /* End of if */ ++ if (fd->f_pos != offset) { ++ if (fd->f_op->llseek) { ++ if (fd->f_op->llseek(fd, offset, 0) != offset) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to seek!!\n"); ++ break; ++ } ++ } else { ++ fd->f_pos = offset; ++ } ++ } ++ ++ retLen = vfs_write(fd, buf, len, &fd->f_pos); ++ ++ } while (FALSE); ++ ++ filp_close(fd, NULL); ++ ++ set_fs(old_fs); ++ ++ return retLen; ++ ++#else /* !CFG_SUPPORT_NVRAMS */ ++ ++ return -EIO; ++ ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief API for reading data on NVRAM ++* ++* \param[in] ++* prGlueInfo ++* u4Offset ++* \param[out] ++* pu2Data ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data) ++{ ++ if (pu2Data == NULL) ++ return FALSE; ++ ++ if (nvram_read(WIFI_NVRAM_FILE_NAME, ++ (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { ++ return FALSE; ++ } else { ++ return TRUE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief API for writing data on NVRAM ++* ++* \param[in] ++* prGlueInfo ++* u4Offset ++* u2Data ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data) ++{ ++ if (nvram_write(WIFI_NVRAM_FILE_NAME, ++ (char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { ++ return FALSE; ++ } else { ++ return TRUE; ++ } ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h +new file mode 100644 +index 000000000000..9444d415c60e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h +@@ -0,0 +1,190 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/version.h#1 ++*/ ++ ++/*! \file "version.h" ++ \brief Driver's version definition ++ ++*/ ++ ++/* ++** Log: version.h ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.1.1. ++ * ++ * 08 26 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.9.. ++ * ++ * 08 23 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.8. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * correct typo. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * for building MT6628 Win32 driver environment ++ * ++ * 08 03 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.7. ++ * ++ * 07 24 2011 puff.wen ++ * NULL ++ * [MT5931][Beta 5]Change the version number to v0.2.2.0 ++ * ++ * 06 01 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.6.. ++ * ++ * 05 09 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.5.. ++ * ++ * 04 19 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.4. ++ * ++ * 04 18 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.3. ++ * ++ * 03 25 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.2. ++ * ++ * 03 21 2011 chinglan.wang ++ * NULL ++ * Change the version number to 2.0.0.1. ++ * ++ * 03 18 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.0. ++ * ++ * 02 11 2011 chinglan.wang ++ * NULL ++ * Change to the version 1.2.0.2. ++ * ++ * 02 10 2011 chinglan.wang ++ * NULL ++ * Change the version to 1.2.0.1. ++ * ++ * 02 08 2011 cp.wu ++ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number ++ * change version number to v1.2.0.0 for preparing v1.2 software package release. ++ * ++ * 12 10 2010 kevin.huang ++ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check ++ * Add Linux Proc Support ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * [WINDDK] build system changes for MT5931 ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-12-14 14:10:55 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-17 22:41:00 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-13 16:20:33 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:27:13 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _VERSION_H ++#define _VERSION_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#ifndef NIC_AUTHOR ++#define NIC_AUTHOR "NIC_AUTHOR" ++#endif ++#ifndef NIC_DESC ++#define NIC_DESC "NIC_DESC" ++#endif ++ ++#ifndef NIC_NAME ++#if defined(MT6620) ++#define NIC_NAME "MT6620" ++#define NIC_DEVICE_ID "MT6620" ++#define NIC_DEVICE_ID_LOW "mt6620" ++#elif defined(MT6628) ++#define NIC_NAME "MT6582" ++#define NIC_DEVICE_ID "MT6582" ++#define NIC_DEVICE_ID_LOW "mt6582" ++#endif ++#endif ++ ++/* NIC driver information */ ++#define NIC_VENDOR "MediaTek Inc." ++#define NIC_VENDOR_OUI {0x00, 0x0C, 0xE7} ++ ++#if defined(MT6620) ++#define NIC_PRODUCT_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter" ++#define NIC_DRIVER_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter Driver" ++#elif defined(MT6628) ++/* #define NIC_PRODUCT_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter" */ ++/* #define NIC_DRIVER_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter Driver" */ ++#define NIC_PRODUCT_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter" ++#define NIC_DRIVER_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter Driver" ++#endif ++ ++/* Define our driver version */ ++#define NIC_DRIVER_MAJOR_VERSION 2 ++#define NIC_DRIVER_MINOR_VERSION 0 ++#define NIC_DRIVER_VERSION (2, 0, 1, 1) ++#define NIC_DRIVER_VERSION_STRING "2.0.1.1" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _VERSION_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/aee.h b/drivers/misc/mediatek/include/mt-plat/aee.h +new file mode 100644 +index 000000000000..d1cf448dafb2 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/aee.h +@@ -0,0 +1,284 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#if !defined(__AEE_H__) ++#define __AEE_H__ ++ ++#include ++#include ++ ++#define AEE_MODULE_NAME_LENGTH 64 ++#define AEE_PROCESS_NAME_LENGTH 256 ++#define AEE_BACKTRACE_LENGTH 3072 ++ ++typedef enum { ++ AE_DEFECT_FATAL, ++ AE_DEFECT_EXCEPTION, ++ AE_DEFECT_WARNING, ++ AE_DEFECT_REMINDING, ++ AE_DEFECT_ATTR_END ++} AE_DEFECT_ATTR; ++ ++typedef enum { ++ AE_KE = 0, /* Fatal Exception */ ++ AE_HWT, ++ AE_REBOOT, ++ AE_NE, ++ AE_JE, ++ AE_SWT, ++ AE_EE, ++ AE_EXP_ERR_END, ++ AE_ANR, /* Error or Warning or Defect */ ++ AE_RESMON, ++ AE_MODEM_WARNING, ++ AE_WTF, ++ AE_WRN_ERR_END, ++ AE_MANUAL, /* Manual Raise */ ++ AE_EXP_CLASS_END, ++ ++ AE_KERNEL_PROBLEM_REPORT = 1000, ++ AE_SYSTEM_JAVA_DEFECT, ++ AE_SYSTEM_NATIVE_DEFECT, ++ AE_MANUAL_MRDUMP_KEY, ++} AE_EXP_CLASS; /* General Program Exception Class */ ++ ++typedef enum { ++ AEE_REBOOT_MODE_NORMAL = 0, ++ AEE_REBOOT_MODE_KERNEL_OOPS, ++ AEE_REBOOT_MODE_KERNEL_PANIC, ++ AEE_REBOOT_MODE_NESTED_EXCEPTION, ++ AEE_REBOOT_MODE_WDT, ++ AEE_REBOOT_MODE_MANUAL_KDUMP, ++} AEE_REBOOT_MODE; ++ ++#define AEE_SZ_SYMBOL_L 140 ++#define AEE_SZ_SYMBOL_S 80 ++struct aee_bt_frame { ++ __u64 pc; ++ __u64 lr; ++ __u32 pad[5]; ++ char pc_symbol[AEE_SZ_SYMBOL_S]; /* Now we use different symbol length for PC &LR */ ++ char lr_symbol[AEE_SZ_SYMBOL_L]; ++}; ++ ++/* aee_process_info struct should strictly small than ipanic_buffer, now 4KB */ ++struct aee_process_info { ++ char process_path[AEE_PROCESS_NAME_LENGTH]; ++ char backtrace[AEE_BACKTRACE_LENGTH]; ++ struct aee_bt_frame ke_frame; ++}; ++ ++struct aee_process_bt { ++ __u32 pid; ++ __u32 nr_entries; ++ struct aee_bt_frame *entries; ++}; ++ ++ ++struct aee_thread_reg { ++ pid_t tid; ++ struct pt_regs regs; ++}; ++ ++struct aee_user_thread_stack { ++ pid_t tid; ++ int StackLength; ++ unsigned char *Userthread_Stack; /*8k stack ,define to char only for match 64bit/32bit*/ ++}; ++ ++struct aee_user_thread_maps { ++ pid_t tid; ++ int Userthread_mapsLength; ++ unsigned char *Userthread_maps; /*8k stack ,define to char only for match 64bit/32bit*/ ++}; ++ ++ ++ ++struct aee_oops { ++ struct list_head list; ++ AE_DEFECT_ATTR attr; ++ AE_EXP_CLASS clazz; ++ ++ char module[AEE_MODULE_NAME_LENGTH]; ++ /* consist with struct aee_process_info */ ++ char process_path[AEE_PROCESS_NAME_LENGTH]; ++ char backtrace[AEE_BACKTRACE_LENGTH]; ++ struct aee_bt_frame ke_frame; ++ ++ char *detail; ++ int detail_len; ++ ++ char *console; ++ int console_len; ++ ++ char *android_main; ++ int android_main_len; ++ char *android_radio; ++ int android_radio_len; ++ char *android_system; ++ int android_system_len; ++ ++ char *userspace_info; ++ int userspace_info_len; ++ ++ char *mmprofile; ++ int mmprofile_len; ++ ++ char *mini_rdump; ++ int mini_rdump_len; ++ ++ ++ struct aee_user_thread_stack userthread_stack; ++ struct aee_thread_reg userthread_reg; ++ struct aee_user_thread_maps userthread_maps; ++ ++ int dump_option; ++}; ++ ++struct aee_kernel_api { ++ void (*kernel_reportAPI)(const AE_DEFECT_ATTR attr, const int db_opt, const char *module, ++ const char *msg); ++ void (*md_exception)(const char *assert_type, const int *log, int log_size, const int *phy, ++ int phy_size, const char *detail, const int db_opt); ++ void (*md32_exception)(const char *assert_type, const int *log, int log_size, ++ const int *phy, int phy_size, const char *detail, const int db_opt); ++ void (*combo_exception)(const char *assert_type, const int *log, int log_size, ++ const int *phy, int phy_size, const char *detail, const int db_opt); ++ void (*scp_exception)(const char *assert_type, const int *log, int log_size, ++ const int *phy, int phy_size, const char *detail, const int db_opt); ++}; ++ ++void aee_sram_printk(const char *fmt, ...); ++int aee_nested_printf(const char *fmt, ...); ++void aee_wdt_irq_info(void); ++void aee_wdt_fiq_info(void *arg, void *regs, void *svc_sp); ++void aee_trigger_kdb(void); ++struct aee_oops *aee_oops_create(AE_DEFECT_ATTR attr, AE_EXP_CLASS clazz, const char *module); ++void aee_oops_set_backtrace(struct aee_oops *oops, const char *backtrace); ++void aee_oops_set_process_path(struct aee_oops *oops, const char *process_path); ++void aee_oops_free(struct aee_oops *oops); ++/* powerkey press,modules use bits */ ++#define AE_WDT_Powerkey_DEVICE_PATH "/dev/kick_powerkey" ++#define WDT_SETBY_DEFAULT (0) ++#define WDT_SETBY_Backlight (1<<0) ++#define WDT_SETBY_Display (1<<1) ++#define WDT_SETBY_SF (1<<2) ++#define WDT_SETBY_PM (1<<3) ++#define WDT_SETBY_WMS_DISABLE_PWK_MONITOR (0xAEEAEE00) ++#define WDT_SETBY_WMS_ENABLE_PWK_MONITOR (0xAEEAEE01) ++#define WDT_PWK_HANG_FORCE_HWT (0xAEE0FFFF) ++ ++/* QHQ RT Monitor */ ++#define AEEIOCTL_RT_MON_Kick _IOR('p', 0x0A, int) ++#define AE_WDT_DEVICE_PATH "/dev/RT_Monitor" ++/* QHQ RT Monitor end */ ++ ++/* DB dump option bits, set relative bit to 1 to include related file in db */ ++#define DB_OPT_DEFAULT (0) ++#define DB_OPT_FTRACE (1<<0) ++#define DB_OPT_PRINTK_TOO_MUCH (1<<1) ++#define DB_OPT_NE_JBT_TRACES (1<<2) ++#define DB_OPT_SWT_JBT_TRACES (1<<3) ++#define DB_OPT_VM_TRACES (1<<4) ++#define DB_OPT_DUMPSYS_ACTIVITY (1<<5) ++#define DB_OPT_DUMPSYS_WINDOW (1<<6) ++#define DB_OPT_DUMPSYS_GFXINFO (1<<7) ++#define DB_OPT_DUMPSYS_SURFACEFLINGER (1<<8) ++#define DB_OPT_DISPLAY_HANG_DUMP (1<<9) ++#define DB_OPT_LOW_MEMORY_KILLER (1<<10) ++#define DB_OPT_PROC_MEM (1<<11) ++#define DB_OPT_FS_IO_LOG (1<<12) ++#define DB_OPT_PROCESS_COREDUMP (1<<13) ++#define DB_OPT_VM_HPROF (1<<14) ++#define DB_OPT_PROCMEM (1<<15) ++#define DB_OPT_DUMPSYS_INPUT (1<<16) ++#define DB_OPT_MMPROFILE_BUFFER (1<<17) ++#define DB_OPT_BINDER_INFO (1<<18) ++#define DB_OPT_WCN_ISSUE_INFO (1<<19) ++#define DB_OPT_DUMMY_DUMP (1<<20) ++#define DB_OPT_PID_MEMORY_INFO (1<<21) ++#define DB_OPT_VM_OOME_HPROF (1<<22) ++#define DB_OPT_PID_SMAPS (1<<23) ++#define DB_OPT_PROC_CMDQ_INFO (1<<24) ++#define DB_OPT_PROC_USKTRK (1<<25) ++#define DB_OPT_SF_RTT_DUMP (1<<26) ++#define DB_OPT_PAGETYPE_INFO (1<<27) ++#define DB_OPT_DUMPSYS_PROCSTATS (1<<28) ++#define DB_OPT_DUMP_DISPLAY (1<<29) ++#define DB_OPT_NATIVE_BACKTRACE (1<<30) ++#define DB_OPT_AARCH64 (1<<31) ++ ++#define aee_kernel_exception(module, msg...) \ ++ aee_kernel_exception_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) ++#define aee_kernel_warning(module, msg...) \ ++ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) ++#define aee_kernel_reminding(module, msg...) \ ++ aee_kernel_reminding_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) ++#define aee_kernel_dal_show(msg) \ ++ aee_kernel_dal_api(__FILE__, __LINE__, msg) ++ ++#define aed_md_exception(log, log_size, phy, phy_size, detail) \ ++ aed_md_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++#define aed_md32_exception(log, log_size, phy, phy_size, detail) \ ++ aed_md32_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++#define aed_scp_exception(log, log_size, phy, phy_size, detail) \ ++ aed_scp_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++#define aed_combo_exception(log, log_size, phy, phy_size, detail) \ ++ aed_combo_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++ ++void aee_kernel_exception_api(const char *file, const int line, const int db_opt, ++ const char *module, const char *msg, ...); ++void aee_kernel_warning_api(const char *file, const int line, const int db_opt, const char *module, ++ const char *msg, ...); ++void aee_kernel_reminding_api(const char *file, const int line, const int db_opt, ++ const char *module, const char *msg, ...); ++void aee_kernel_dal_api(const char *file, const int line, const char *msg); ++ ++void aed_md_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++void aed_md32_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++void aed_scp_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++void aed_combo_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++ ++void aee_kernel_wdt_kick_Powkey_api(const char *module, int msg); ++int aee_kernel_wdt_kick_api(int kinterval); ++void aee_powerkey_notify_press(unsigned long pressed); ++int aee_kernel_Powerkey_is_press(void); ++ ++void ipanic_recursive_ke(struct pt_regs *regs, struct pt_regs *excp_regs, int cpu); ++ ++/* QHQ RT Monitor */ ++void aee_kernel_RT_Monitor_api(int lParam); ++/* QHQ RT Monitor end */ ++void mt_fiq_printf(const char *fmt, ...); ++void aee_register_api(struct aee_kernel_api *aee_api); ++int aee_in_nested_panic(void); ++void aee_stop_nested_panic(struct pt_regs *regs); ++void aee_wdt_dump_info(void); ++void aee_wdt_printf(const char *fmt, ...); ++ ++void aee_fiq_ipi_cpu_stop(void *arg, void *regs, void *svc_sp); ++ ++#if defined(CONFIG_MTK_AEE_DRAM_CONSOLE) ++void aee_dram_console_reserve_memory(void); ++#else ++static inline void aee_dram_console_reserve_memory(void) ++{ ++} ++#endif ++ ++extern void *aee_excp_regs; /* To store latest exception, in case of stack corruption */ ++#endif /* __AEE_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mrdump.h b/drivers/misc/mediatek/include/mt-plat/mrdump.h +new file mode 100644 +index 000000000000..b6bdfa2f7617 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mrdump.h +@@ -0,0 +1,204 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. ++ */ ++ ++#if !defined(__MRDUMP_H__) ++#define __MRDUMP_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __aarch64__ ++#define reg_pc pc ++#define reg_lr regs[30] ++#define reg_sp sp ++#define reg_fp regs[29] ++#else ++#define reg_pc ARM_pc ++#define reg_lr ARM_lr ++#define reg_sp ARM_sp ++#define reg_ip ARM_ip ++#define reg_fp ARM_fp ++#endif ++ ++#define MRDUMP_CPU_MAX 16 ++ ++#define MRDUMP_DEV_NULL 0 ++#define MRDUMP_DEV_SDCARD 1 ++#define MRDUMP_DEV_EMMC 2 ++ ++#define MRDUMP_FS_NULL 0 ++#define MRDUMP_FS_VFAT 1 ++#define MRDUMP_FS_EXT4 2 ++ ++#define MRDUMP_GO_DUMP "MRDUMP04" ++ ++typedef uint32_t arm32_gregset_t[18]; ++typedef uint64_t aarch64_gregset_t[34]; ++ ++struct mrdump_crash_record { ++ int reboot_mode; ++ ++ char msg[128]; ++ char backtrace[512]; ++ ++ uint32_t fault_cpu; ++ ++ union { ++ arm32_gregset_t arm32_regs; ++ aarch64_gregset_t aarch64_regs; ++ } cpu_regs[MRDUMP_CPU_MAX]; ++}; ++ ++struct mrdump_machdesc { ++ uint32_t crc; ++ ++ uint32_t output_device; ++ ++ uint32_t nr_cpus; ++ ++ uint64_t page_offset; ++ uint64_t high_memory; ++ ++ uint64_t vmalloc_start; ++ uint64_t vmalloc_end; ++ ++ uint64_t modules_start; ++ uint64_t modules_end; ++ ++ uint64_t phys_offset; ++ uint64_t master_page_table; ++ ++ uint32_t output_fstype; ++ uint32_t output_lbaooo; ++}; ++ ++struct mrdump_control_block { ++ char sig[8]; ++ ++ struct mrdump_machdesc machdesc; ++ struct mrdump_crash_record crash_record; ++}; ++ ++/* NOTE!! any change to this struct should be compatible in aed */ ++struct mrdump_mini_reg_desc { ++ unsigned long reg; /* register value */ ++ unsigned long kstart; /* start kernel addr of memory dump */ ++ unsigned long kend; /* end kernel addr of memory dump */ ++ unsigned long pos; /* next pos to dump */ ++ int valid; /* 1: valid regiser, 0: invalid regiser */ ++ int pad; /* reserved */ ++ loff_t offset; /* offset in buffer */ ++}; ++ ++/* it should always be smaller than MRDUMP_MINI_HEADER_SIZE */ ++struct mrdump_mini_header { ++ struct mrdump_mini_reg_desc reg_desc[ELF_NGREG]; ++}; ++ ++#define MRDUMP_MINI_NR_SECTION 60 ++#define MRDUMP_MINI_SECTION_SIZE (32 * 1024) ++#define NT_IPANIC_MISC 4095 ++#define MRDUMP_MINI_NR_MISC 20 ++ ++struct mrdump_mini_elf_misc { ++ unsigned long vaddr; ++ unsigned long paddr; ++ unsigned long start; ++ unsigned long size; ++}; ++ ++#define NOTE_NAME_SHORT 12 ++#define NOTE_NAME_LONG 20 ++ ++struct mrdump_mini_elf_psinfo { ++ struct elf_note note; ++ char name[NOTE_NAME_SHORT]; ++ struct elf_prpsinfo data; ++}; ++ ++struct mrdump_mini_elf_prstatus { ++ struct elf_note note; ++ char name[NOTE_NAME_SHORT]; ++ struct elf_prstatus data; ++}; ++ ++struct mrdump_mini_elf_note { ++ struct elf_note note; ++ char name[NOTE_NAME_LONG]; ++ struct mrdump_mini_elf_misc data; ++}; ++ ++struct mrdump_mini_elf_header { ++ struct elfhdr ehdr; ++ struct elf_phdr phdrs[MRDUMP_MINI_NR_SECTION]; ++ struct mrdump_mini_elf_psinfo psinfo; ++ struct mrdump_mini_elf_prstatus prstatus[NR_CPUS + 1]; ++ struct mrdump_mini_elf_note misc[MRDUMP_MINI_NR_MISC]; ++}; ++ ++typedef struct mrdump_rsvmem_block { ++ phys_addr_t start_addr; ++ phys_addr_t size; ++} mrdump_rsvmem_block_t; ++ ++ ++#define MRDUMP_MINI_HEADER_SIZE ALIGN(sizeof(struct mrdump_mini_elf_header), PAGE_SIZE) ++#define MRDUMP_MINI_DATA_SIZE (MRDUMP_MINI_NR_SECTION * MRDUMP_MINI_SECTION_SIZE) ++#define MRDUMP_MINI_BUF_SIZE (MRDUMP_MINI_HEADER_SIZE + MRDUMP_MINI_DATA_SIZE) ++ ++#ifdef CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR ++#define MRDUMP_MINI_BUF_PADDR (CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR + 0xf0000) ++#else ++#define MRDUMP_MINI_BUF_PADDR 0 ++#endif ++ ++int mrdump_init(void); ++void __mrdump_create_oops_dump(AEE_REBOOT_MODE reboot_mode, struct pt_regs *regs, const char *msg, ++ ...); ++#if defined(CONFIG_MTK_AEE_IPANIC) ++void mrdump_rsvmem(void); ++#else ++static inline void mrdump_rsvmem(void) ++{ ++} ++#endif ++ ++#if defined(CONFIG_MTK_AEE_MRDUMP) ++void aee_kdump_reboot(AEE_REBOOT_MODE, const char *msg, ...); ++#else ++static inline void aee_kdump_reboot(AEE_REBOOT_MODE reboot_mode, const char *msg, ...) ++{ ++} ++#endif ++ ++typedef int (*mrdump_write)(void *buf, int off, int len, int encrypt); ++#if defined(CONFIG_MTK_AEE_IPANIC) ++int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, ++ loff_t sd_offset, const char *msg, va_list ap); ++void mrdump_mini_reserve_memory(void); ++#else ++static inline int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, ++ loff_t sd_offset, const char *msg, va_list ap) ++{ ++ return 0; ++} ++ ++static inline void mrdump_mini_reserve_memory(void) ++{ ++} ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h +new file mode 100644 +index 000000000000..1b60f007d0fd +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h +@@ -0,0 +1,295 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++ ++#ifndef _MT8167_THERMAL_H ++#define _MT8167_THERMAL_H ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "sync_write.h" ++ ++extern void __iomem *thermal_base; ++extern void __iomem *auxadc_ts_base; ++extern void __iomem *apmixed_base; ++extern void __iomem *pericfg_base; ++extern int auxadc_ts_phy_base; ++extern int apmixed_phy_base; ++ ++#define THERM_CTRL_BASE_2 thermal_base ++#define AUXADC_BASE_2 auxadc_ts_base ++#define PERICFG_BASE pericfg_base ++#define APMIXED_BASE_2 apmixed_base ++ ++#define MT6752_EVB_BUILD_PASS /*Jerry fix build error FIX_ME*/ ++ ++/******************************************************************************* ++* AUXADC Register Definition ++******************************************************************************/ ++/*AUXADC_BASE: 0xF1001000 from Vincent Liang 2014.5.8*/ ++ ++#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /*yes, 0x11003000*/ ++#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) ++#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) ++#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) ++#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) ++/*#define AUXADC_CON3_V (AUXADC_BASE_2 + 0x014)*/ ++#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) ++#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) ++#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) ++#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) ++#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) ++#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) ++#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) ++#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) ++#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) ++#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) ++#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) ++#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) ++#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) ++ ++#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) ++#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) ++#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) ++#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) ++#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) ++/*#define AUXADC_CON3_P (auxadc_ts_phy_base + 0x014)*/ ++#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) ++#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) ++#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) ++#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) ++#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) ++#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) ++#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) ++#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) ++#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) ++#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) ++#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) ++#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) ++ ++#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) ++ ++/******************************************************************************* ++* Peripheral Configuration Register Definition ++******************************************************************************/ ++/*#define PERICFG_BASE (0x10002000)*/ ++#define PERI_GLOBALCON_RST0 (pericfg_base + 0x000) /*yes, 0x10002000*/ ++/******************************************************************************* ++ * APMixedSys Configuration Register Definition ++ ******************************************************************************/ ++#define TS_CON0 (APMIXED_BASE_2 + 0x600) /*yes 0x10209000*/ ++#define TS_CON1 (APMIXED_BASE_2 + 0x604) ++#define TS_CON0_TM (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ ++#define TS_CON1_TM (APMIXED_BASE_2 + 0x604) ++#define TS_CON0_P (apmixed_phy_base + 0x600) ++#define TS_CON1_P (apmixed_phy_base + 0x604) ++ ++/******************************************************************************* ++ * Thermal Controller Register Definition ++ ******************************************************************************/ ++#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /*yes 0x1100B000*/ ++#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) ++#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) ++#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) ++#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) ++#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) ++#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) ++#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) ++#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) ++#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) ++#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) ++#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) ++#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) ++#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) ++#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) ++#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) ++#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) ++#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) ++#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) ++#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) ++#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) ++ ++#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) ++#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) ++#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) ++#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) ++#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) ++#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) ++#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) ++#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) ++#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) ++#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) ++#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) ++#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) ++#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) ++#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) ++#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) ++#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) ++#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) ++#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) ++#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) ++ ++#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) ++#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) ++#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) ++#define TEMPIMMD3 (THERM_CTRL_BASE_2 + 0x0BC) ++ ++ ++#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) ++#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) ++#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) ++#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) ++ ++#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) ++#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) ++#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) ++#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) ++ ++#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) ++#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) ++#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) ++#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) ++#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) ++#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) ++#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) ++#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /*Only for DE debug*/ ++#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) ++#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) ++#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) ++#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) ++#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) ++ ++ ++#define PTPSPARE0_P (thermal_phy_base + 0x420) ++#define PTPSPARE1_P (thermal_phy_base + 0x424) ++#define PTPSPARE2_P (thermal_phy_base + 0x428) ++#define PTPSPARE3_P (thermal_phy_base + 0x42C) ++ ++/******************************************************************************* ++ * Thermal Controller Register Mask Definition ++ ******************************************************************************/ ++#define THERMAL_ENABLE_SEN0 0x1 ++#define THERMAL_ENABLE_SEN1 0x2 ++#define THERMAL_ENABLE_SEN2 0x4 ++#define THERMAL_MONCTL0_MASK 0x00000007 ++ ++#define THERMAL_PUNT_MASK 0x00000FFF ++#define THERMAL_FSINTVL_MASK 0x03FF0000 ++#define THERMAL_SPINTVL_MASK 0x000003FF ++#define THERMAL_MON_INT_MASK 0x0007FFFF ++ ++#define THERMAL_MON_CINTSTS0 0x000001 ++#define THERMAL_MON_HINTSTS0 0x000002 ++#define THERMAL_MON_LOINTSTS0 0x000004 ++#define THERMAL_MON_HOINTSTS0 0x000008 ++#define THERMAL_MON_NHINTSTS0 0x000010 ++#define THERMAL_MON_CINTSTS1 0x000020 ++#define THERMAL_MON_HINTSTS1 0x000040 ++#define THERMAL_MON_LOINTSTS1 0x000080 ++#define THERMAL_MON_HOINTSTS1 0x000100 ++#define THERMAL_MON_NHINTSTS1 0x000200 ++#define THERMAL_MON_CINTSTS2 0x000400 ++#define THERMAL_MON_HINTSTS2 0x000800 ++#define THERMAL_MON_LOINTSTS2 0x001000 ++#define THERMAL_MON_HOINTSTS2 0x002000 ++#define THERMAL_MON_NHINTSTS2 0x004000 ++#define THERMAL_MON_TOINTSTS 0x008000 ++#define THERMAL_MON_IMMDINTSTS0 0x010000 ++#define THERMAL_MON_IMMDINTSTS1 0x020000 ++#define THERMAL_MON_IMMDINTSTS2 0x040000 ++#define THERMAL_MON_FILTINTSTS0 0x080000 ++#define THERMAL_MON_FILTINTSTS1 0x100000 ++#define THERMAL_MON_FILTINTSTS2 0x200000 ++ ++ ++#define THERMAL_tri_SPM_State0 0x20000000 ++#define THERMAL_tri_SPM_State1 0x40000000 ++#define THERMAL_tri_SPM_State2 0x80000000 ++ ++ ++#define THERMAL_MSRCTL0_MASK 0x00000007 ++#define THERMAL_MSRCTL1_MASK 0x00000038 ++#define THERMAL_MSRCTL2_MASK 0x000001C0 ++ ++enum thermal_sensor_name { ++ THERMAL_SENSOR1 = 0,/*TS_MCU1*/ ++ THERMAL_SENSOR_NUM ++}; ++ ++enum thermal_bank_name { ++ THERMAL_BANK0 = 0, /*CPU (TS_MCU1) (TS1)*/ ++ THERMAL_BANK_NUM ++}; ++ ++struct TS_SVS { ++ unsigned int ts_MTS; ++ unsigned int ts_BTS; ++}; ++ ++struct mtk_gpu_power_info { ++ unsigned int gpufreq_khz; ++ unsigned int gpufreq_power; ++}; ++ ++/* svs driver need this function */ ++extern void get_thermal_slope_intercept(struct TS_SVS *ts_info, enum thermal_bank_name ts_bank); ++ ++/* mtk_thermal_platform.c need this */ ++extern void set_taklking_flag(bool flag); ++ ++#define THERMAL_WRAP_WR32(val, addr) mt_reg_sync_writel((val), ((void *)addr)) ++ ++enum MTK_THERMAL_SENSOR_CPU_ID_MET { ++ MTK_THERMAL_SENSOR_TS1 = 0, ++ MTK_THERMAL_SENSOR_TS2, ++ MTK_THERMAL_SENSOR_TS3, ++ MTK_THERMAL_SENSOR_TS4, ++ MTK_THERMAL_SENSOR_TSABB, ++ ++ ATM_CPU_LIMIT, ++ ATM_GPU_LIMIT, ++ ++ MTK_THERMAL_SENSOR_CPU_COUNT ++}; ++ ++extern int tscpu_get_cpu_temp_met(enum MTK_THERMAL_SENSOR_CPU_ID_MET id); ++extern int mtk_gpufreq_register(struct mtk_gpu_power_info *freqs, int num); ++ ++typedef void (*met_thermalsampler_funcMET)(void); ++void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); ++ ++void tscpu_start_thermal(void); ++void tscpu_stop_thermal(void); ++void tscpu_cancel_thermal_timer(void); ++void tscpu_start_thermal_timer(void); ++int mtkts_bts_get_hw_temp(void); ++ ++extern int get_immediate_ts1_wrap(void); ++extern int get_immediate_ts2_wrap(void); ++extern int get_immediate_ts3_wrap(void); ++ ++extern int is_cpu_power_unlimit(void); /* in mtk_ts_cpu.c */ ++extern int is_cpu_power_min(void); /* in mtk_ts_cpu.c */ ++extern int get_cpu_target_tj(void); ++extern int get_cpu_target_offset(void); ++ ++extern int mtktscpu_debug_log; ++ ++#endif ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h +new file mode 100644 +index 000000000000..142a007805b9 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (C) 2011 MediaTek, Inc. ++ * ++ * Author: Holmes Chiou ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef __MT_FREQHOPPING_H__ ++#define __MT_FREQHOPPING_H__ ++ ++#define MT_FHPLL_MAX 6 ++#define MT_SSC_NR_PREDEFINE_SETTING 10 /* TODO: is 10 a good number ? */ ++ ++#define MEMPLL_SSC 0 ++#define MAINPLL_SSC 1 ++ ++#define FHTAG "[FH]" ++ ++#define VERBOSE_DEBUG 0 ++ ++#if VERBOSE_DEBUG ++#define FH_MSG(fmt, args...) \ ++ pr_debug(FHTAG""fmt" <- %s(): L<%d> PID<%s><%d>\n", ##args, __func__, __LINE__, current->comm, current->pid) ++#else ++ ++#if 1 /* log level is 6 xlog */ ++#define FH_MSG(fmt, args...) pr_debug(fmt, ##args) ++#else /* log level is 4 (printk) */ ++#define FH_MSG(fmt, args...) printk(FHTAG""fmt"\n", ##args) ++#endif ++ ++#endif ++ ++/* not support at mt2701 yet */ ++/* DRAMC */ ++#define FULLY_VERSION_FHCTL 0 ++ ++enum FH_FH_STATUS { ++ FH_FH_DISABLE = 0, ++ FH_FH_ENABLE_SSC, ++ FH_FH_ENABLE_DFH, ++ FH_FH_ENABLE_DVFS, ++}; ++ ++enum FH_PLL_STATUS { ++ FH_PLL_DISABLE = 0, ++ FH_PLL_ENABLE = 1 ++}; ++ ++/* TODO: FREQ_MODIFIED should not be here */ ++/* FH_PLL_STATUS_FREQ_MODIFIED = 3 */ ++ ++ ++enum FH_CMD { ++ FH_CMD_ENABLE = 1, ++ FH_CMD_DISABLE, ++ FH_CMD_ENABLE_USR_DEFINED, ++ FH_CMD_DISABLE_USR_DEFINED, ++ FH_CMD_INTERNAL_MAX_CMD, ++/* TODO: do we need these cmds ? ++ * FH_CMD_PLL_ENABLE, ++ * FH_CMD_PLL_DISABLE, ++ * FH_CMD_EXT_ALL_FULL_RANGE_CMD, ++ * FH_CMD_EXT_ALL_HALF_RANGE_CMD, ++ * FH_CMD_EXT_DISABLE_ALL_CMD, ++ * FH_CMD_EXT_DESIGNATED_PLL_FULL_RANGE_CMD, ++ * FH_CMD_EXT_DESIGNATED_PLL_AND_SETTING_CMD ++*/ ++}; ++ ++/* ++ * enum FH_OPCODE{ ++ * FH_OPCODE_ENABLE_WITH_ID = 1, ++ * FH_OPCODE_ENABLE_WITHOUT_ID, ++ * FH_OPCODE_DISABLE, ++ * }; ++*/ ++ ++enum FH_PLL_ID { ++ MT658X_FH_MINIMUMM_PLL = 0, ++ MT658X_FH_ARM_PLL = MT658X_FH_MINIMUMM_PLL, ++ MT658X_FH_MAIN_PLL = 1, ++ MT658X_FH_MEM_PLL = 2, ++ MT658X_FH_MSDC_PLL = 3, ++ MT658X_FH_MM_PLL = 4, /* MT658X_FH_TVD_PLL = 4, */ ++ MT658X_FH_VENC_PLL = 5, /* MT658X_FH_LVDS_PLL = 5, */ ++ /* 8127 FHCTL MB */ ++ MT658X_FH_TVD_PLL = 6, /* MT658X_FH_TVD_PLL = 6, */ ++ MT658X_FH_MAXIMUMM_PLL = MT658X_FH_TVD_PLL, ++ /* 8127 FHCTL ME */ ++ MT658X_FH_PLL_TOTAL_NUM ++}; ++ ++/* keep track the status of each PLL */ ++/* TODO: do we need another "uint mode" for Dynamic FH */ ++typedef struct { ++ unsigned int fh_status; ++ unsigned int pll_status; ++ unsigned int setting_id; ++ unsigned int curr_freq; ++ unsigned int user_defined; ++} fh_pll_t; ++ ++ ++/* Record the owner of enable freq hopping <==TBD */ ++struct freqhopping_pll { ++ union { ++ int mt_pll[MT_FHPLL_MAX]; ++ struct { ++ int mt_arm_fhpll; ++ int mt_main_fhpll; ++ int mt_mem_fhpll; ++ int mt_msdc_fhpll; ++ int mt_mm_fhpll; ++ int mt_venc_fhpll; ++ }; ++ }; ++}; ++ ++struct freqhopping_ssc { ++ unsigned int freq; ++ unsigned int dt; ++ unsigned int df; ++ unsigned int upbnd; ++ unsigned int lowbnd; ++ unsigned int dds; ++}; ++ ++struct freqhopping_ioctl { ++ unsigned int pll_id; ++ struct freqhopping_ssc ssc_setting; /* used only when user-define */ ++ int result; ++}; ++ ++int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable); ++void mt_freqhopping_init(void); ++void mt_freqhopping_pll_init(void); ++int mt_h2l_mempll(void); ++int mt_l2h_mempll(void); ++int mt_h2l_dvfs_mempll(void); ++int mt_l2h_dvfs_mempll(void); ++int mt_dfs_armpll(unsigned int current_freq, unsigned int target_freq); ++int mt_is_support_DFS_mode(void); ++void mt_fh_popod_save(void); ++void mt_fh_popod_restore(void); ++int mt_fh_dram_overclock(int clk); ++int mt_fh_get_dramc(void); ++unsigned int mt_get_emi_freq(void); ++ ++#endif /* !__MT_FREQHOPPING_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h +new file mode 100644 +index 000000000000..0c049db9aa97 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++ ++#define STA_POWER_DOWN 0 ++#define STA_POWER_ON 1 ++ ++/* ++ * 1. for CPU MTCMOS: CPU0, CPU1, CPU2, CPU3, DBG0, CPU4, CPU5, CPU6, CPU7, DBG1, CPUSYS1 ++ * 2. call spm_mtcmos_cpu_lock/unlock() before/after any operations ++ */ ++extern int spm_mtcmos_cpu_init(void); ++extern void spm_mtcmos_cpu_lock(unsigned long *flags); ++extern void spm_mtcmos_cpu_unlock(unsigned long *flags); ++extern int spm_mtcmos_ctrl_cpu(unsigned int cpu, int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu0(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu1(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu2(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu3(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu4(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu5(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu6(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu7(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpusys0(int state, int chkWfiBeforePdn); ++extern bool spm_cpusys0_can_power_down(void); +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h +new file mode 100644 +index 000000000000..28176b3cd9af +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_BOOT_SHARE_PAGE_H__ ++#define __MTK_BOOT_SHARE_PAGE_H__ ++ ++#define BOOT_SHARE_BASE (0xC0002000) /* address in linux kernel */ ++#define BOOT_SHARE_SIZE (0x1000) /* page size 4K bytes */ ++ ++#define BOOT_SHARE_MAGIC (0x4545544D) /* MTEE */ ++ ++/* Memory map & defines for boot share page */ ++/* ++ * Note: ++ * 1. BOOT_SHARE_XXXXX_OFST is the address offset related to BOOT_SHARE_BASE ++ */ ++#define BOOT_SHARE_MAGIC1_OFST (0) ++#define BOOT_SHARE_MAGIC1_SIZE (4) ++ ++#define BOOT_SHARE_DEV_INFO_OFST (BOOT_SHARE_MAGIC1_OFST+BOOT_SHARE_MAGIC1_SIZE) ++#define BOOT_SHARE_DEV_INFO_SIZE (16) ++ ++#define BOOT_SHARE_HOTPLUG_OFST (1008) /* 16 bytes for hotplug/jump-reg */ ++#define BOOT_SHARE_HOTPLUG_SIZE (32) ++ ++#define BOOT_SHARE_MAGIC2_OFST (4092) ++#define BOOT_SHARE_MAGIC2_SIZE (4) ++ ++#endif /* __MTK_BOOT_SHARE_PAGE_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h +new file mode 100644 +index 000000000000..eefdaad4aaa5 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h +@@ -0,0 +1,301 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. ++ */ ++ ++#ifndef _MT8127_THERMAL_H ++#define _MT8127_THERMAL_H ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mt-plat/sync_write.h" ++#include ++ ++/* #include */ ++/* #include "../../../../../thermal/mt8127/inc/mt_gpufreq.h" */ ++ ++#if 1 ++extern void __iomem *thermal_base; ++extern void __iomem *auxadc_ts_base; ++extern void __iomem *pericfg_base; ++extern void __iomem *apmixed_ts_base; ++ ++extern int mtktscpu_limited_dmips; ++ ++void __attribute__ ((weak)) mt_gpufreq_thermal_protect(unsigned int limited_power) { ++} ++ ++unsigned int __attribute__ ((weak)) mt_gpufreq_get_cur_freq(void) { ++ return 0; ++} ++ ++u32 __attribute__ ((weak)) get_devinfo_with_index(u32 index) { ++ return 0; ++} ++ ++extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); ++extern int IMM_IsAdcInitReady(void); ++extern int PMIC_IMM_GetOneChannelValue(int dwChannel, int deCount, int trimd); ++extern int thermal_phy_base; ++extern int auxadc_ts_phy_base; ++extern int apmixed_phy_base; ++extern int pericfg_phy_base; ++ ++/* extern int last_abb_t; */ ++/* extern int last_CPU2_t; */ ++extern int get_immediate_temp2_wrap(void); ++extern void mtkts_dump_cali_info(void); ++extern u32 get_devinfo_with_index(u32 index); ++extern int bts_cur_temp; ++ ++#define THERM_CTRL_BASE_2 thermal_base ++#define AUXADC_BASE_2 auxadc_ts_base ++#define PERICFG_BASE_2 pericfg_base ++#define APMIXED_BASE_2 apmixed_ts_base ++#endif ++ ++/******************************************************************************* ++ * AUXADC Register Definition ++ ******************************************************************************/ ++#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /* yes, 0x11001000 */ ++#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) ++#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) ++#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) ++#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) ++#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) ++#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) ++#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) ++#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) ++#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) ++#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) ++#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) ++#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) ++#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) ++#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) ++#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) ++#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) ++#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) ++#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) ++#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) ++#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) ++#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) ++#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) ++#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) ++#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) ++#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) ++#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) ++#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) ++#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) ++#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) ++#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) ++#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) ++#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) ++#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) ++#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) ++#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) ++ ++/******************************************************************************* ++ * Peripheral Configuration Register Definition ++ ******************************************************************************/ ++#define PERI_GLOBALCON_RST0 (PERICFG_BASE_2 + 0x000) /* yes, 0x10003000 */ ++ ++/******************************************************************************* ++ * APMixedSys Configuration Register Definition ++ ******************************************************************************/ ++#define TS_CON0 (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ ++#define TS_CON1 (APMIXED_BASE_2 + 0x604) ++/******************************************************************************* ++ * Thermal Controller Register Definition ++ ******************************************************************************/ ++#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /* yes 0x1100B000 */ ++#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) ++#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) ++#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) ++#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) ++#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) ++#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) ++#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) ++#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) ++#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) ++#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) ++#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) ++#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) ++#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) ++#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) ++#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) ++#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) ++#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) ++#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) ++#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) ++#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) ++ ++#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) ++#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) ++#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) ++#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) ++#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) ++#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) ++#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) ++#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) ++#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) ++#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) ++#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) ++#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) ++#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) ++#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) ++#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) ++#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) ++#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) ++#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) ++#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) ++ ++#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) ++#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) ++#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) ++ ++#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) ++#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) ++#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) ++#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) ++ ++#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) ++#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) ++#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) ++#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) ++ ++#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) ++#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) ++#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) ++#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) ++#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) ++#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) ++#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) ++#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /* Only for DE debug */ ++#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) ++#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) ++#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) ++#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) ++#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) ++ ++/******************************************************************************* ++ * Thermal Controller Register Mask Definition ++ ******************************************************************************/ ++#define THERMAL_ENABLE_SEN0 0x1 ++#define THERMAL_ENABLE_SEN1 0x2 ++#define THERMAL_ENABLE_SEN2 0x4 ++#define THERMAL_MONCTL0_MASK 0x00000007 ++ ++#define THERMAL_PUNT_MASK 0x00000FFF ++#define THERMAL_FSINTVL_MASK 0x03FF0000 ++#define THERMAL_SPINTVL_MASK 0x000003FF ++#define THERMAL_MON_INT_MASK 0x0007FFFF ++ ++#define THERMAL_MON_CINTSTS0 0x000001 ++#define THERMAL_MON_HINTSTS0 0x000002 ++#define THERMAL_MON_LOINTSTS0 0x000004 ++#define THERMAL_MON_HOINTSTS0 0x000008 ++#define THERMAL_MON_NHINTSTS0 0x000010 ++#define THERMAL_MON_CINTSTS1 0x000020 ++#define THERMAL_MON_HINTSTS1 0x000040 ++#define THERMAL_MON_LOINTSTS1 0x000080 ++#define THERMAL_MON_HOINTSTS1 0x000100 ++#define THERMAL_MON_NHINTSTS1 0x000200 ++#define THERMAL_MON_CINTSTS2 0x000400 ++#define THERMAL_MON_HINTSTS2 0x000800 ++#define THERMAL_MON_LOINTSTS2 0x001000 ++#define THERMAL_MON_HOINTSTS2 0x002000 ++#define THERMAL_MON_NHINTSTS2 0x004000 ++#define THERMAL_MON_TOINTSTS 0x008000 ++#define THERMAL_MON_IMMDINTSTS0 0x010000 ++#define THERMAL_MON_IMMDINTSTS1 0x020000 ++#define THERMAL_MON_IMMDINTSTS2 0x040000 ++#define THERMAL_MON_FILTINTSTS0 0x080000 ++#define THERMAL_MON_FILTINTSTS1 0x100000 ++#define THERMAL_MON_FILTINTSTS2 0x200000 ++ ++ ++#define THERMAL_tri_SPM_State0 0x20000000 ++#define THERMAL_tri_SPM_State1 0x40000000 ++#define THERMAL_tri_SPM_State2 0x80000000 ++ ++ ++#define THERMAL_MSRCTL0_MASK 0x00000007 ++#define THERMAL_MSRCTL1_MASK 0x00000038 ++#define THERMAL_MSRCTL2_MASK 0x000001C0 ++ ++/* extern int thermal_one_shot_handler(int times); */ ++ ++typedef enum { ++ THERMAL_SENSOR1 = 0, /* TS1 */ ++ THERMAL_SENSOR_NUM ++} thermal_sensor_name; ++ ++struct TS_PTPOD { ++ unsigned int ts_MTS; ++ unsigned int ts_BTS; ++}; ++ ++extern void get_thermal_slope_intercept(struct TS_PTPOD *ts_info); ++extern void set_taklking_flag(bool flag); ++extern int tscpu_get_cpu_temp(void); ++ ++/*5 thermal sensors*/ ++typedef enum { ++ MTK_THERMAL_SENSOR_TS1 = 0, ++ ATM_CPU_LIMIT, ++ ATM_GPU_LIMIT, ++ MTK_THERMAL_SENSOR_CPU_COUNT ++} MTK_THERMAL_SENSOR_CPU_ID_MET; ++ ++struct mtk_cpu_power_info { ++ unsigned int cpufreq_khz; ++ unsigned int cpufreq_ncpu; ++ unsigned int cpufreq_power; ++}; ++extern int mtk_cpufreq_register(struct mtk_cpu_power_info *freqs, int num); ++ ++extern int tscpu_get_cpu_temp_met(MTK_THERMAL_SENSOR_CPU_ID_MET id); ++ ++ ++typedef void (*met_thermalsampler_funcMET) (void); ++void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); ++ ++void tscpu_start_thermal(void); ++void tscpu_stop_thermal(void); ++void tscpu_cancel_thermal_timer(void); ++void tscpu_start_thermal_timer(void); ++int mtkts_AP_get_hw_temp(void); ++ ++extern int amddulthro_backoff(int level); ++/* extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); */ ++/* extern int IMM_IsAdcInitReady(void); */ ++extern int get_immediate_temp2_wrap(void); ++extern void mtkts_dump_cali_info(void); ++extern unsigned int read_dram_temperature(void); ++extern int mtk_thermal_get_cpu_load_sum(void); ++ ++/********************************** ++ * Power table struct for thermal ++ **********************************/ ++struct mt_gpufreq_power_table_info { ++ unsigned int gpufreq_khz; ++ unsigned int gpufreq_volt; ++ unsigned int gpufreq_power; ++}; ++ ++extern int mtk_gpufreq_register(struct mt_gpufreq_power_table_info *freqs, int num); ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mt_sched.h b/drivers/misc/mediatek/include/mt-plat/mt_sched.h +new file mode 100644 +index 000000000000..71206f080548 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt_sched.h +@@ -0,0 +1,34 @@ ++/* ++* Copyright (C) 2016 MediaTek Inc. ++* ++* This program is free software; you can redistribute it and/or modify ++* it under the terms of the GNU General Public License version 2 as ++* published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, ++* but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See http://www.gnu.org/licenses/gpl-2.0.html for more details. ++*/ ++ ++#ifdef CONFIG_MTK_SCHED_RQAVG_US ++/* ++ * @cpu: cpu id ++ * @reset: reset the statistic start time after this time query ++ * @use_maxfreq: caculate cpu loading with max cpu max frequency ++ * return: cpu loading as percentage (0~100) ++ */ ++extern unsigned int sched_get_percpu_load(int cpu, bool reset, bool use_maxfreq); ++ ++/* ++ * return: heavy task(loading>90%) number in the system ++ */ ++extern unsigned int sched_get_nr_heavy_task(void); ++ ++/* ++ * @threshold: heavy task loading threshold (0~1023) ++ * return: heavy task(loading>threshold) number in the system ++ */ ++extern unsigned int sched_get_nr_heavy_task_by_threshold(unsigned int threshold); ++#endif /* CONFIG_MTK_SCHED_RQAVG_US */ ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_io.h b/drivers/misc/mediatek/include/mt-plat/mtk_io.h +new file mode 100644 +index 000000000000..de17db505d3e +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_io.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MT_IO_H__ ++#define __MT_IO_H__ ++ ++/* only for arm64 */ ++#ifdef CONFIG_ARM64 ++#define IOMEM(a) ((void __force __iomem *)((a))) ++#endif ++ ++#endif /* !__MT_IO_H__ */ ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h +new file mode 100644 +index 000000000000..d679c5a1ce73 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_LPAE_H__ ++#define __MTK_LPAE_H__ ++#ifdef CONFIG_MTK_LM_MODE ++ ++#include ++ ++#define INTERAL_MAPPING_OFFSET (0x40000000) ++#define INTERAL_MAPPING_LIMIT (INTERAL_MAPPING_OFFSET + 0x80000000) ++ ++#define MT_OVERFLOW_ADDR_START 0x100000000ULL ++ ++unsigned int __attribute__((weak)) enable_4G(void) ++{ ++ return 0; ++} ++ ++/* For HW modules which support 33-bit address setting */ ++#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) \ ++ do { \ ++ ret = 0; \ ++ if (enable_4G()) {\ ++ if (((phys_addr_t)phy_addr < MT_OVERFLOW_ADDR_START)\ ++ && (((phys_addr_t)phy_addr + size) >= MT_OVERFLOW_ADDR_START)) \ ++ ret = MT_OVERFLOW_ADDR_START - phy_addr; \ ++ } \ ++ } while (0) \ ++ ++/* For SPM and MD32 only in ROME */ ++#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) \ ++ do { \ ++ if (enable_4G()) {\ ++ if (phy_addr >= INTERAL_MAPPING_OFFSET && phy_addr < INTERAL_MAPPING_LIMIT) \ ++ phy_addr += INTERAL_MAPPING_OFFSET; \ ++ } \ ++ } while (0)\ ++ ++#else /* !CONFIG_ARM_LPAE */ ++ ++#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) ++#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) ++#define MT_OVERFLOW_ADDR_START 0 ++ ++static inline unsigned int enable_4G(void) ++{ ++ return 0; ++} ++ ++#endif ++#endif /*!__MTK_LPAE_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h +new file mode 100644 +index 000000000000..7baafc4329bf +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_MDM_MONITOR_H ++#define _MTK_MDM_MONITOR_H ++ ++struct md_info { ++ char *attribute; ++ int value; ++ char *unit; ++ int invalid_value; ++ int index; ++}; ++ ++extern ++int mtk_mdm_get_md_info(struct md_info **p_inf, int *size); ++ ++extern ++int mtk_mdm_start_query(void); ++ ++extern ++int mtk_mdm_stop_query(void); ++ ++extern ++int mtk_mdm_set_signal_period(int second); ++ ++extern ++int mtk_mdm_set_md1_signal_period(int second); ++ ++extern ++int mtk_mdm_set_md2_signal_period(int second); ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h +new file mode 100644 +index 000000000000..8f20f38b75d6 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_PLATFORM_DEBUG_H__ ++#define __MTK_PLATFORM_DEBUG_H__ ++ ++#ifdef CONFIG_MTK_PLAT_SRAM_FLAG ++/* plat_sram_flag */ ++extern int set_sram_flag_lastpc_valid(void); ++extern int set_sram_flag_dfd_valid(void); ++extern int set_sram_flag_etb_user(unsigned int etb_id, unsigned int user_id); ++#endif ++ ++#ifdef CONFIG_MTK_DFD_INTERNAL_DUMP ++extern int dfd_setup(void); ++#endif ++ ++#endif /* __MTK_PLATFORM_DEBUG_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h +new file mode 100644 +index 000000000000..3a94a1bbcd24 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_RAM_CONSOLE_H__ ++#define __MTK_RAM_CONSOLE_H__ ++ ++#include ++#include ++ ++typedef enum { ++ AEE_FIQ_STEP_FIQ_ISR_BASE = 1, ++ AEE_FIQ_STEP_WDT_FIQ_INFO = 4, ++ AEE_FIQ_STEP_WDT_FIQ_STACK, ++ AEE_FIQ_STEP_WDT_FIQ_LOOP, ++ AEE_FIQ_STEP_WDT_FIQ_DONE, ++ AEE_FIQ_STEP_WDT_IRQ_INFO = 8, ++ AEE_FIQ_STEP_WDT_IRQ_KICK, ++ AEE_FIQ_STEP_WDT_IRQ_SMP_STOP, ++ AEE_FIQ_STEP_WDT_IRQ_TIME, ++ AEE_FIQ_STEP_WDT_IRQ_STACK, ++ AEE_FIQ_STEP_WDT_IRQ_GIC, ++ AEE_FIQ_STEP_WDT_IRQ_LOCALTIMER, ++ AEE_FIQ_STEP_WDT_IRQ_IDLE, ++ AEE_FIQ_STEP_WDT_IRQ_SCHED, ++ AEE_FIQ_STEP_WDT_IRQ_DONE, ++ AEE_FIQ_STEP_KE_WDT_INFO = 20, ++ AEE_FIQ_STEP_KE_WDT_PERCPU, ++ AEE_FIQ_STEP_KE_WDT_LOG, ++ AEE_FIQ_STEP_KE_SCHED_DEBUG, ++ AEE_FIQ_STEP_KE_EINT_DEBUG, ++ AEE_FIQ_STEP_KE_WDT_DONE, ++ AEE_FIQ_STEP_KE_IPANIC_DIE = 32, ++ AEE_FIQ_STEP_KE_IPANIC_START, ++ AEE_FIQ_STEP_KE_IPANIC_OOP_HEADER, ++ AEE_FIQ_STEP_KE_IPANIC_DETAIL, ++ AEE_FIQ_STEP_KE_IPANIC_CONSOLE, ++ AEE_FIQ_STEP_KE_IPANIC_USERSPACE, ++ AEE_FIQ_STEP_KE_IPANIC_ANDROID, ++ AEE_FIQ_STEP_KE_IPANIC_MMPROFILE, ++ AEE_FIQ_STEP_KE_IPANIC_HEADER, ++ AEE_FIQ_STEP_KE_IPANIC_DONE, ++ AEE_FIQ_STEP_KE_NESTED_PANIC = 64, ++} AEE_FIQ_STEP_NUM; ++ ++#ifdef CONFIG_MTK_RAM_CONSOLE ++extern int aee_rr_curr_fiq_step(void); ++extern void aee_rr_rec_fiq_step(u8 i); ++extern void aee_rr_rec_reboot_mode(u8 mode); ++extern void aee_rr_rec_kdump_params(void *params); ++extern void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j); ++extern void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j); ++extern void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm); ++extern void aee_sram_fiq_log(const char *msg); ++extern void ram_console_write(struct console *console, const char *s, unsigned int count); ++extern void aee_sram_fiq_save_bin(const char *buffer, size_t len); ++extern void aee_rr_rec_hotplug_footprint(int cpu, u8 fp); ++extern void aee_rr_rec_hotplug_cpu_event(u8 val); ++extern void aee_rr_rec_hotplug_cb_index(u8 val); ++extern void aee_rr_rec_hotplug_cb_fp(unsigned long val); ++#ifdef CONFIG_MTK_EMMC_SUPPORT ++extern void last_kmsg_store_to_emmc(void); ++#endif ++ ++#else ++static inline void aee_rr_rec_hotplug_footprint(int cpu, u8 fp) ++{ ++} ++static inline void aee_rr_rec_hotplug_cpu_event(u8 val) ++{ ++} ++static inline void aee_rr_rec_hotplug_cb_index(u8 val) ++{ ++} ++static inline void aee_rr_rec_hotplug_cb_fp(unsigned long val) ++{ ++} ++static inline int aee_rr_curr_fiq_step(void) ++{ ++ return 0; ++} ++ ++static inline void aee_rr_rec_fiq_step(u8 i) ++{ ++} ++ ++static inline unsigned int aee_rr_curr_exp_type(void) ++{ ++ return 0; ++} ++ ++static inline void aee_rr_rec_exp_type(unsigned int type) ++{ ++} ++ ++static inline void aee_rr_rec_reboot_mode(u8 mode) ++{ ++} ++ ++static inline void aee_rr_rec_kdump_params(void *params) ++{ ++} ++ ++static inline void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j) ++{ ++} ++ ++static inline void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j) ++{ ++} ++ ++static inline void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm) ++{ ++} ++ ++static inline void aee_sram_fiq_log(const char *msg) ++{ ++} ++ ++static inline void ram_console_write(struct console *console, const char *s, unsigned int count) ++{ ++} ++ ++static inline void aee_sram_fiq_save_bin(unsigned char *buffer, size_t len) ++{ ++} ++ ++#ifdef CONFIG_MTK_EMMC_SUPPORT ++static inline void last_kmsg_store_to_emmc(void) ++{ ++} ++#endif ++ ++#endif /* CONFIG_MTK_RAM_CONSOLE */ ++ ++#ifdef CONFIG_MTK_AEE_IPANIC ++extern int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size); ++extern int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, ++ char **buf, struct pstore_info *psi); ++#else ++static inline int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size) ++{ ++ return 0; ++} ++ ++static inline int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, ++ char **buf, struct pstore_info *psi) ++{ ++ return 0; ++} ++#endif /* CONFIG_MTK_AEE_IPANIC */ ++ ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h +new file mode 100644 +index 000000000000..2181e9989593 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h +@@ -0,0 +1,85 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef MTK_RTC_H ++#define MTK_RTC_H ++ ++#include ++#include ++#include ++ ++typedef enum { ++ RTC_GPIO_USER_WIFI = 8, ++ RTC_GPIO_USER_GPS = 9, ++ RTC_GPIO_USER_BT = 10, ++ RTC_GPIO_USER_FM = 11, ++ RTC_GPIO_USER_PMIC = 12, ++} rtc_gpio_user_t; ++ ++#ifdef CONFIG_MTK_RTC ++ ++/* ++ * NOTE: ++ * 1. RTC_GPIO always exports 32K enabled by some user even if the phone is powered off ++ */ ++ ++extern unsigned long rtc_read_hw_time(void); ++extern void rtc_gpio_enable_32k(rtc_gpio_user_t user); ++extern void rtc_gpio_disable_32k(rtc_gpio_user_t user); ++extern bool rtc_gpio_32k_status(void); ++ ++/* for AUDIOPLL (deprecated) */ ++extern void rtc_enable_abb_32k(void); ++extern void rtc_disable_abb_32k(void); ++ ++/* NOTE: used in Sleep driver to workaround Vrtc-Vore level shifter issue */ ++extern void rtc_enable_writeif(void); ++extern void rtc_disable_writeif(void); ++ ++extern void rtc_mark_recovery(void); ++#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) ++extern void rtc_mark_kpoc(void); ++#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ ++extern void rtc_mark_fast(void); ++extern u16 rtc_rdwr_uart_bits(u16 *val); ++extern void rtc_bbpu_power_down(void); ++extern void rtc_read_pwron_alarm(struct rtc_wkalrm *alm); ++extern int get_rtc_spare_fg_value(void); ++extern int set_rtc_spare_fg_value(int val); ++extern void rtc_irq_handler(void); ++extern bool crystal_exist_status(void); ++extern void mt_power_off(void); ++#else/*ifdef CONFIG_MTK_RTC*/ ++#define rtc_read_hw_time() ({ 0; }) ++#define rtc_gpio_enable_32k(user) do {} while (0) ++#define rtc_gpio_disable_32k(user) do {} while (0) ++#define rtc_gpio_32k_status() do {} while (0) ++#define rtc_enable_abb_32k() do {} while (0) ++#define rtc_disable_abb_32k() do {} while (0) ++#define rtc_enable_writeif() do {} while (0) ++#define rtc_disable_writeif() do {} while (0) ++#define rtc_mark_recovery() do {} while (0) ++#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) ++#define rtc_mark_kpoc() do {} while (0) ++#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ ++#define rtc_mark_fast() do {} while (0) ++#define rtc_rdwr_uart_bits(val) ({ 0; }) ++#define rtc_bbpu_power_down() do {} while (0) ++#define rtc_read_pwron_alarm(alm) do {} while (0) ++#define get_rtc_spare_fg_value() ({ 0; }) ++#define set_rtc_spare_fg_value(val) ({ 0; }) ++#define rtc_irq_handler() do {} while (0) ++#define crystal_exist_status() do {} while (0) ++__weak void mt_power_off(void); ++#endif/*ifdef CONFIG_MTK_RTC*/ ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h +new file mode 100644 +index 000000000000..eac6bc713c98 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (c) 2009 Travis Geiselbrecht ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files ++ * (the "Software"), to deal in the Software without restriction, ++ * including without limitation the rights to use, copy, modify, merge, ++ * publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, ++ * subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef _MTK_THERMAL_EXT_CONTROL_H ++#define _MTK_THERMAL_EXT_CONTROL_H ++ ++#define THERMAL_MD32_IPI_MSG_BASE 0x1F00 ++#define THERMAL_AP_IPI_MSG_BASE 0x2F00 ++ ++typedef enum { ++ THERMAL_AP_IPI_MSG_SET_TZ_THRESHOLD = THERMAL_AP_IPI_MSG_BASE, ++ THERMAL_AP_IPI_MSG_MD32_START, ++ ++ THERMAL_MD32_IPI_MSG_READY = THERMAL_MD32_IPI_MSG_BASE, ++ THERMAL_MD32_IPI_MSG_MD32_START_ACK, ++ THERMAL_MD32_IPI_MSG_REACH_THRESHOLD, ++} thermal_ipi_msg_id; ++ ++typedef enum { ++/* MTK_THERMAL_EXT_SENSOR_CPU = 0, */ ++ MTK_THERMAL_EXT_SENSOR_ABB = 0, ++ MTK_THERMAL_EXT_SENSOR_PMIC, ++ MTK_THERMAL_EXT_SENSOR_BATTERY, ++ MTK_THERMAL_EXT_SENSOR_COUNT ++} MTK_THERMAL_EXT_SENSOR_ID; ++ ++typedef struct { ++ int id; /* id of this tz */ ++ int polling_delay; /* polling delay of this tz */ ++ long high_trip_point; /* high threshold of this tz */ ++ long low_trip_point; /* low threshold of this tz */ ++} thermal_zone_data; ++ ++typedef struct { ++ int id; /* id of this tz */ ++ long high_trip_point; /* high threshold of this tz */ ++ long low_trip_point; /* low threshold of this tz */ ++ long temperature; /* Current temperature gotten from TS */ ++} thermal_zone_status; ++ ++typedef struct { ++ short id; ++ union { ++ thermal_zone_data tz; ++ thermal_zone_status tz_status; ++ } data; ++} thermal_ipi_msg; ++ ++#endif /* _MTK_THERMAL_EXT_CONTROL_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h +new file mode 100644 +index 000000000000..7903b49dc419 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h +@@ -0,0 +1,102 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_THERMAL_MONITOR_H ++#define _MTK_THERMAL_MONITOR_H ++ ++#include ++ ++/* ++ * MTK_THERMAL_WRAPPER_BYPASS = 1 (use original Linux Thermal API) ++ * MTK_THERMAL_WRAPPER_BYPASS = 0 (use MTK Thermal API Monitor) ++ */ ++#define MTK_THERMAL_WRAPPER_BYPASS 0 ++ ++#if MTK_THERMAL_WRAPPER_BYPASS ++/* Original LTF API */ ++#define mtk_thermal_zone_device_register thermal_zone_device_register ++#define mtk_thermal_zone_device_unregister thermal_zone_device_unregister ++#define mtk_thermal_cooling_device_unregister thermal_cooling_device_unregister ++#define mtk_thermal_cooling_device_register thermal_cooling_device_register ++#define mtk_thermal_zone_bind_cooling_device thermal_zone_bind_cooling_device ++ ++#else ++ ++struct thermal_cooling_device_ops_extra { ++ int (*set_cur_temp)(struct thermal_cooling_device *, unsigned long); ++}; ++ ++extern ++struct thermal_zone_device *mtk_thermal_zone_device_register_wrapper ++(char *type, int trips, void *devdata, const struct thermal_zone_device_ops *ops, ++int tc1, int tc2, int passive_delay, int polling_delay); ++ ++extern ++void mtk_thermal_zone_device_unregister_wrapper(struct thermal_zone_device *tz); ++ ++extern ++struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper ++(char *type, void *devdata, const struct thermal_cooling_device_ops *ops); ++ ++extern ++struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper_extra ++(char *type, void *devdata, const struct thermal_cooling_device_ops *ops, ++const struct thermal_cooling_device_ops_extra *ops_ext); ++ ++extern ++int mtk_thermal_cooling_device_add_exit_point ++(struct thermal_cooling_device *cdev, int exit_point); ++ ++extern ++void mtk_thermal_cooling_device_unregister_wrapper(struct thermal_cooling_device *cdev); ++ ++extern int mtk_thermal_zone_bind_cooling_device_wrapper ++(struct thermal_zone_device *tz, int trip, struct thermal_cooling_device *cdev); ++ ++extern int mtk_thermal_zone_bind_trigger_trip(struct thermal_zone_device *tz, int trip, int mode); ++#define mtk_thermal_zone_device_register mtk_thermal_zone_device_register_wrapper ++#define mtk_thermal_zone_device_unregister mtk_thermal_zone_device_unregister_wrapper ++#define mtk_thermal_cooling_device_unregister mtk_thermal_cooling_device_unregister_wrapper ++#define mtk_thermal_cooling_device_register mtk_thermal_cooling_device_register_wrapper ++#define mtk_thermal_zone_bind_cooling_device mtk_thermal_zone_bind_cooling_device_wrapper ++ ++#endif ++ ++typedef enum { ++ MTK_THERMAL_SENSOR_CPU = 0, ++ MTK_THERMAL_SENSOR_ABB, ++ MTK_THERMAL_SENSOR_PMIC, ++ MTK_THERMAL_SENSOR_BATTERY, ++ MTK_THERMAL_SENSOR_MD1, ++ MTK_THERMAL_SENSOR_MD2, ++ MTK_THERMAL_SENSOR_WIFI, ++ MTK_THERMAL_SENSOR_BATTERY2, ++ MTK_THERMAL_SENSOR_BUCK, ++ MTK_THERMAL_SENSOR_AP, ++ MTK_THERMAL_SENSOR_PCB1, ++ MTK_THERMAL_SENSOR_PCB2, ++ MTK_THERMAL_SENSOR_SKIN, ++ MTK_THERMAL_SENSOR_XTAL, ++ MTK_THERMAL_SENSOR_MD_PA, ++ ++ MTK_THERMAL_SENSOR_COUNT ++} MTK_THERMAL_SENSOR_ID; ++ ++extern int mtk_thermal_get_temp(MTK_THERMAL_SENSOR_ID id); ++extern struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void); ++ ++/* This API function is implemented in mediatek/kernel/drivers/leds/leds.c */ ++extern int setMaxbrightness(int max_level, int enable); ++ ++extern void machine_power_off(void); ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h +new file mode 100644 +index 000000000000..305574031196 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_THERMAL_PLATFORM_H ++#define _MTK_THERMAL_PLATFORM_H ++ ++#include ++#include ++ ++extern ++int mtk_thermal_get_cpu_info(int *nocores, int **cpufreq, int **cpuloading); ++ ++extern ++int mtk_thermal_get_gpu_info(int *nocores, int **gpufreq, int **gpuloading); ++ ++extern ++int mtk_thermal_get_batt_info(int *batt_voltage, int *batt_current, int *batt_temp); ++ ++extern ++int mtk_thermal_get_extra_info(int *no_extra_attr, ++ char ***attr_names, int **attr_values, char ***attr_unit); ++ ++extern ++int mtk_thermal_force_get_batt_temp(void); ++ ++ ++enum { ++ MTK_THERMAL_SCEN_CALL = 0x1 ++}; ++ ++extern ++unsigned int mtk_thermal_set_user_scenarios(unsigned int mask); ++ ++extern ++unsigned int mtk_thermal_clear_user_scenarios(unsigned int mask); ++ ++ ++#if defined(CONFIG_MTK_SMART_BATTERY) ++/* global variable from battery driver... */ ++extern kal_bool gFG_Is_Charging; ++#endif ++ ++extern int force_get_tbat(void); ++#endif /* _MTK_THERMAL_PLATFORM_H */ ++ ++ ++typedef enum { ++ TA_DAEMON_CMD_GET_INIT_FLAG = 0, ++ TA_DAEMON_CMD_SET_DAEMON_PID, ++ TA_DAEMON_CMD_NOTIFY_DAEMON, ++ TA_DAEMON_CMD_NOTIFY_DAEMON_CATMINIT, ++ TA_DAEMON_CMD_SET_TTJ, ++ TA_DAEMON_CMD_GET_TPCB, ++ ++ TA_DAEMON_CMD_TO_KERNEL_NUMBER ++} TA_DAEMON_CTRL_CMD_TO_KERNEL; /*must sync userspace/kernel: TA_DAEMON_CTRL_CMD_FROM_USER*/ ++ ++#define TAD_NL_MSG_T_HDR_LEN 12 ++#define TAD_NL_MSG_MAX_LEN 2048 ++ ++struct tad_nl_msg_t { ++ unsigned int tad_cmd; ++ unsigned int tad_data_len; ++ unsigned int tad_ret_data_len; ++ char tad_data[TAD_NL_MSG_MAX_LEN]; ++}; ++ ++enum { ++ TA_CATMPLUS = 1, ++ TA_CONTINUOUS = 2, ++ TA_CATMPLUS_TTJ = 3 ++}; ++ ++ ++struct cATM_params_t { ++ int CATM_ON; ++ int K_TT; ++ int K_SUM_TT_LOW; ++ int K_SUM_TT_HIGH; ++ int MIN_SUM_TT; ++ int MAX_SUM_TT; ++ int MIN_TTJ; ++ int CATMP_STEADY_TTJ_DELTA; ++}; ++struct continuetm_params_t { ++ int STEADY_TARGET_TJ; ++ int MAX_TARGET_TJ; ++ int TRIP_TPCB; ++ int STEADY_TARGET_TPCB; ++}; ++ ++ ++struct CATM_T { ++ struct cATM_params_t t_catm_par; ++ struct continuetm_params_t t_continuetm_par; ++}; ++extern struct CATM_T thermal_atm_t; ++int wakeup_ta_algo(int flow_state); ++int ta_get_ttj(void); ++ ++extern int mtk_thermal_get_tpcb_target(void); ++extern int tsatm_thermal_get_catm_type(void); ++ ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h +new file mode 100644 +index 000000000000..1c23a9f4a862 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM thermal ++ ++#if !defined(_MTK_THERMAL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _MTK_THERMAL_TRACE_H ++ ++#include ++ ++TRACE_EVENT(cooling_device_state, ++ TP_PROTO(int device, unsigned long state), ++ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) ++ __field(unsigned long, state) ++ ), ++ TP_fast_assign(__entry->device = device; ++ __entry->state = state;), ++ TP_printk("cooling_device=%d, state=%lu\n", __entry->device, __entry->state) ++); ++ ++TRACE_EVENT(thermal_zone_state, ++ TP_PROTO(int device, int state), ++ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) ++ __field(int, state) ++ ), ++ TP_fast_assign(__entry->device = device; ++ __entry->state = state;), ++ TP_printk("thermal_zone=%d, state=%d\n", __entry->device, __entry->state) ++); ++#endif /* _MTK_THERMAL_TRACE_H */ ++ ++/* This part must be outside protection */ ++#undef TRACE_INCLUDE_PATH ++#define TRACE_INCLUDE_PATH . ++#define TRACE_INCLUDE_FILE mach/mtk_thermal_trace ++#include +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h +new file mode 100644 +index 000000000000..dfcef3d952fc +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h +@@ -0,0 +1,241 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _TYPEDEFS_H ++#define _TYPEDEFS_H ++ ++#include ++ ++/* --------------------------------------------------------------------------- */ ++/* Basic Type Definitions */ ++/* --------------------------------------------------------------------------- */ ++ ++typedef volatile unsigned char *P_kal_uint8; ++typedef volatile unsigned short *P_kal_uint16; ++typedef volatile unsigned int *P_kal_uint32; ++ ++typedef long LONG; ++typedef unsigned char UBYTE; ++typedef short SHORT; ++ ++typedef signed char kal_int8; ++typedef signed short kal_int16; ++typedef signed int kal_int32; ++typedef long long kal_int64; ++typedef unsigned char kal_uint8; ++typedef unsigned short kal_uint16; ++typedef unsigned int kal_uint32; ++typedef unsigned long long kal_uint64; ++typedef char kal_char; ++ ++typedef unsigned int *UINT32P; ++typedef volatile unsigned short *UINT16P; ++typedef volatile unsigned char *UINT8P; ++typedef unsigned char *U8P; ++ ++typedef volatile unsigned char *P_U8; ++typedef volatile signed char *P_S8; ++typedef volatile unsigned short *P_U16; ++typedef volatile signed short *P_S16; ++typedef volatile unsigned int *P_U32; ++typedef volatile signed int *P_S32; ++typedef unsigned long long *P_U64; ++typedef signed long long *P_S64; ++ ++typedef unsigned char U8; ++typedef signed char S8; ++typedef unsigned short U16; ++typedef signed short S16; ++typedef unsigned int U32; ++typedef signed int S32; ++typedef unsigned long long U64; ++typedef signed long long S64; ++/* typedef unsigned char bool; */ ++ ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++typedef unsigned short USHORT; ++typedef signed char INT8; ++typedef signed short INT16; ++typedef signed int INT32; ++typedef unsigned int DWORD; ++typedef void VOID; ++typedef unsigned char BYTE; ++typedef float FLOAT; ++ ++typedef char *LPCSTR; ++typedef short *LPWSTR; ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Constants */ ++/* --------------------------------------------------------------------------- */ ++ ++#ifndef FALSE ++#define FALSE (0) ++#endif ++ ++#ifndef TRUE ++#define TRUE (1) ++#endif ++ ++#ifndef NULL ++#define NULL (0) ++#endif ++ ++/* enum boolean {false, true}; */ ++enum { RX, TX, NONE }; ++ ++#ifndef BOOL ++typedef unsigned char BOOL; ++#endif ++ ++#ifndef BATTERY_BOOL ++#define BATTERY_BOOL ++typedef enum { ++ KAL_FALSE = 0, ++ KAL_TRUE = 1, ++} kal_bool; ++#endif ++ ++/* --------------------------------------------------------------------------- */ ++/* Type Casting */ ++/* --------------------------------------------------------------------------- */ ++ ++#define AS_INT32(x) (*(INT32 *)((void *)x)) ++#define AS_INT16(x) (*(INT16 *)((void *)x)) ++#define AS_INT8(x) (*(INT8 *)((void *)x)) ++ ++#define AS_UINT32(x) (*(UINT32 *)((void *)x)) ++#define AS_UINT16(x) (*(UINT16 *)((void *)x)) ++#define AS_UINT8(x) (*(UINT8 *)((void *)x)) ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Register Manipulations */ ++/* --------------------------------------------------------------------------- */ ++ ++#define READ_REGISTER_UINT32(reg) \ ++ (*(volatile UINT32 * const)(reg)) ++ ++#define WRITE_REGISTER_UINT32(reg, val) \ ++ ((*(volatile UINT32 * const)(reg)) = (val)) ++ ++#define READ_REGISTER_UINT16(reg) \ ++ ((*(volatile UINT16 * const)(reg))) ++ ++#define WRITE_REGISTER_UINT16(reg, val) \ ++ ((*(volatile UINT16 * const)(reg)) = (val)) ++ ++#define READ_REGISTER_UINT8(reg) \ ++ ((*(volatile UINT8 * const)(reg))) ++ ++#define WRITE_REGISTER_UINT8(reg, val) \ ++ ((*(volatile UINT8 * const)(reg)) = (val)) ++ ++#define INREG8(x) READ_REGISTER_UINT8((UINT8 *)((void *)(x))) ++#define OUTREG8(x, y) WRITE_REGISTER_UINT8((UINT8 *)((void *)(x)), (UINT8)(y)) ++#define SETREG8(x, y) OUTREG8(x, INREG8(x)|(y)) ++#define CLRREG8(x, y) OUTREG8(x, INREG8(x)&~(y)) ++#define MASKREG8(x, y, z) OUTREG8(x, (INREG8(x)&~(y))|(z)) ++ ++#define INREG16(x) READ_REGISTER_UINT16((UINT16 *)((void *)(x))) ++#define OUTREG16(x, y) WRITE_REGISTER_UINT16((UINT16 *)((void *)(x)), (UINT16)(y)) ++#define SETREG16(x, y) OUTREG16(x, INREG16(x)|(y)) ++#define CLRREG16(x, y) OUTREG16(x, INREG16(x)&~(y)) ++#define MASKREG16(x, y, z) OUTREG16(x, (INREG16(x)&~(y))|(z)) ++ ++#define INREG32(x) READ_REGISTER_UINT32((UINT32 *)((void *)(x))) ++#define OUTREG32(x, y) WRITE_REGISTER_UINT32((UINT32 *)((void *)(x)), (UINT32)(y)) ++#define SETREG32(x, y) OUTREG32(x, INREG32(x)|(y)) ++#define CLRREG32(x, y) OUTREG32(x, INREG32(x)&~(y)) ++#define MASKREG32(x, y, z) OUTREG32(x, (INREG32(x)&~(y))|(z)) ++ ++ ++#define DRV_Reg8(addr) INREG8(addr) ++#define DRV_WriteReg8(addr, data) OUTREG8(addr, data) ++#define DRV_SetReg8(addr, data) SETREG8(addr, data) ++#define DRV_ClrReg8(addr, data) CLRREG8(addr, data) ++ ++#define DRV_Reg16(addr) INREG16(addr) ++#define DRV_WriteReg16(addr, data) OUTREG16(addr, data) ++#define DRV_SetReg16(addr, data) SETREG16(addr, data) ++#define DRV_ClrReg16(addr, data) CLRREG16(addr, data) ++ ++#define DRV_Reg32(addr) INREG32(addr) ++#define DRV_WriteReg32(addr, data) OUTREG32(addr, data) ++#define DRV_SetReg32(addr, data) SETREG32(addr, data) ++#define DRV_ClrReg32(addr, data) CLRREG32(addr, data) ++ ++/* !!! DEPRECATED, WILL BE REMOVED LATER !!! */ ++#define DRV_Reg(addr) DRV_Reg16(addr) ++#define DRV_WriteReg(addr, data) DRV_WriteReg16(addr, data) ++#define DRV_SetReg(addr, data) DRV_SetReg16(addr, data) ++#define DRV_ClrReg(addr, data) DRV_ClrReg16(addr, data) ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Compiler Time Deduction Macros */ ++/* --------------------------------------------------------------------------- */ ++ ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Assertions */ ++/* --------------------------------------------------------------------------- */ ++ ++/* ++*#ifndef ASSERT ++*#define ASSERT(expr) BUG_ON(!(expr)) ++*#endif ++* ++*#ifndef NOT_IMPLEMENTED ++*#define NOT_IMPLEMENTED() BUG_ON(1) ++*#endif ++*/ ++#define STATIC_ASSERT(pred) STATIC_ASSERT_X(pred, __LINE__) ++#define STATIC_ASSERT_X(pred, line) STATIC_ASSERT_XX(pred, line) ++#define STATIC_ASSERT_XX(pred, line) \ ++extern char assertion_failed_at_##line[(pred) ? 1 : -1] ++ ++/* --------------------------------------------------------------------------- */ ++/* Resolve Compiler Warnings */ ++/* --------------------------------------------------------------------------- */ ++ ++#define NOT_REFERENCED(x) { (x) = (x); } ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Utilities */ ++/* --------------------------------------------------------------------------- */ ++ ++#define MAXIMUM(A, B) (((A) > (B))?(A):(B)) ++#define MINIMUM(A, B) (((A) < (B))?(A):(B)) ++ ++#define ARY_SIZE(x) (sizeof((x)) / sizeof((x[0]))) ++#define DVT_DELAYMACRO(u4Num) \ ++{ \ ++ UINT32 u4Count = 0; \ ++ for (u4Count = 0; u4Count < u4Num; u4Count++) \ ++ ; \ ++} \ ++ ++#define A68351B 0 ++#define B68351B 1 ++#define B68351D 2 ++#define B68351E 3 ++#define UNKNOWN_IC_VERSION 0xFF ++ ++ ++#endif /* _TYPEDEFS_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h +new file mode 100644 +index 000000000000..0a4fda191654 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h +@@ -0,0 +1,185 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/*! \file ++ * \brief Declaration of library functions ++ * ++ * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _MTK_WCN_CMB_STUB_H_ ++#define _MTK_WCN_CMB_STUB_H_ ++ ++#include ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Audio GPIO naming style for 73/75/77 */ ++/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_0 1 */ ++/* Audio GPIO naming style for 89/8135 */ ++/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_1 1 */ ++/* Audio GPIO naming style for 6592 */ ++/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_2 1 */ ++/* Audio GPIO naming style for 6595 */ ++#define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_3 1 ++#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum { ++ CMB_STUB_AIF_0 = 0, /* 0000: BT_PCM_OFF & FM analog (line in/out) */ ++ CMB_STUB_AIF_1 = 1, /* 0001: BT_PCM_ON & FM analog (in/out) */ ++ CMB_STUB_AIF_2 = 2, /* 0010: BT_PCM_OFF & FM digital (I2S) */ ++ CMB_STUB_AIF_3 = 3, /* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */ ++ CMB_STUB_AIF_4 = 4, /* 0100: BT_I2S & FM disable in special projects, e.g. protea*/ ++ CMB_STUB_AIF_MAX = 5, ++} CMB_STUB_AIF_X; ++ ++/*COMBO_CHIP_AUDIO_PIN_CTRL*/ ++typedef enum { ++ CMB_STUB_AIF_CTRL_DIS = 0, ++ CMB_STUB_AIF_CTRL_EN = 1, ++ CMB_STUB_AIF_CTRL_MAX = 2, ++} CMB_STUB_AIF_CTRL; ++ ++typedef enum { ++ COMBO_FUNC_TYPE_BT = 0, ++ COMBO_FUNC_TYPE_FM = 1, ++ COMBO_FUNC_TYPE_GPS = 2, ++ COMBO_FUNC_TYPE_WIFI = 3, ++ COMBO_FUNC_TYPE_WMT = 4, ++ COMBO_FUNC_TYPE_STP = 5, ++ COMBO_FUNC_TYPE_NUM = 6 ++} COMBO_FUNC_TYPE; ++ ++typedef enum { ++ COMBO_IF_UART = 0, ++ COMBO_IF_MSDC = 1, ++ COMBO_IF_BTIF = 2, ++ COMBO_IF_MAX, ++} COMBO_IF; ++ ++typedef void (*wmt_bgf_eirq_cb) (void); ++typedef int (*wmt_aif_ctrl_cb) (CMB_STUB_AIF_X, CMB_STUB_AIF_CTRL); ++typedef void (*wmt_func_ctrl_cb) (unsigned int, unsigned int); ++typedef signed long (*wmt_thermal_query_cb) (void); ++typedef int (*wmt_deep_idle_ctrl_cb) (unsigned int); ++typedef int (*wmt_func_do_reset) (unsigned int); ++ ++/* for DVFS driver do 1v autok */ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++typedef unsigned int (*wmt_get_drv_status)(unsigned int); ++#endif ++ ++typedef void (*msdc_sdio_irq_handler_t) (void *); /* external irq handler */ ++typedef void (*pm_callback_t) (pm_message_t state, void *data); ++ ++struct sdio_ops { ++ void (*sdio_request_eirq)(msdc_sdio_irq_handler_t irq_handler, void *data); ++ void (*sdio_enable_eirq)(void); ++ void (*sdio_disable_eirq)(void); ++ void (*sdio_register_pm)(pm_callback_t pm_cb, void *data); ++}; ++ ++typedef struct _CMB_STUB_CB_ { ++ unsigned int size; /* structure size */ ++ /*wmt_bgf_eirq_cb bgf_eirq_cb; *//* remove bgf_eirq_cb from stub. handle it in platform */ ++ wmt_aif_ctrl_cb aif_ctrl_cb; ++ wmt_func_ctrl_cb func_ctrl_cb; ++ wmt_thermal_query_cb thermal_query_cb; ++ wmt_deep_idle_ctrl_cb deep_idle_ctrl_cb; ++ wmt_func_do_reset wmt_do_reset_cb; ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ wmt_get_drv_status get_drv_status_cb; ++#endif ++} CMB_STUB_CB, *P_CMB_STUB_CB; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern struct sdio_ops mt_sdio_ops[4]; ++ ++extern int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb); ++extern int mtk_wcn_cmb_stub_unreg(void); ++ ++extern int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); ++ ++static inline int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state) ++{ ++/* return mtk_wcn_cmb_stub_aif_ctrl(state, 1); */ ++ return 0; ++} ++ ++extern int mt_combo_plt_enter_deep_idle(COMBO_IF src); ++extern int mt_combo_plt_exit_deep_idle(COMBO_IF src); ++ ++/* Use new mtk_wcn_stub APIs instead of old mt_combo ones for kernel to control ++ * function on/off. ++ */ ++extern void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on); ++extern int mtk_wcn_cmb_stub_query_ctrl(void); ++extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); ++extern int mtk_wcn_sdio_irq_flag_set(int falg); ++ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++extern int mtk_wcn_cmb_stub_1vautok_for_dvfs(void); ++#endif ++ ++extern int mtk_wcn_wmt_chipid_query(void); ++extern void mtk_wcn_wmt_set_chipid(int chipid); ++ ++/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver ++ * ++ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" ++ * @ enable - "1", enable deep idle; "0", disable deep idle ++ * ++ * Return 0 if success, else -1 ++ */ ++extern unsigned int mtk_uart_pdn_enable(char *port, int enable); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _MTK_WCN_CMB_STUB_H_ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/rt-regmap.h b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h +new file mode 100644 +index 000000000000..9a45e23005ca +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h +@@ -0,0 +1,291 @@ ++/* drivers/misc/mediatek/include/mt-plat/rt-regmap.h ++ * Header of Richtek regmap with debugfs Driver ++ * ++ * Copyright (C) 2014 Richtek Technology Corp. ++ * Jeff Chang ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef MISC_MEDIATEK_RT_REGMAP_H ++#define MISC_MEDIATEK_RT_REGMAP_H ++ ++#include ++#include ++ ++/* #define RT_REGMAP_VERSION "1.1.11_G" */ ++ ++enum rt_access_mode { ++ RT_1BYTE_MODE = 1, ++ RT_2BYTE_MODE = 2, ++ RT_4BYTE_MODE = 4, ++}; ++ ++/* start : the start address of group ++ * end : the end address of group ++ * mode : access mode (1,2,4 bytes) ++ */ ++struct rt_access_group { ++ u32 start; ++ u32 end; ++ enum rt_access_mode mode; ++}; ++ ++/* rt_reg_type ++ * RT_NORMAL : Write data without mask ++ * Read from cache ++ * RT_WBITS : Write data with mask ++ * Read from cache ++ * RT_VOLATILE : Write data to chip directly ++ * Read data from chip ++ * RT_RESERVE : Reserve registers (Write/Read as RT_NORMAL) ++ */ ++ ++#define RT_REG_TYPE_MASK (0x03) ++#define RT_NORMAL (0x00) ++#define RT_WBITS (0x01) ++#define RT_VOLATILE (0x02) ++#define RT_RESERVE (0x03) ++ ++/* RT_WR_ONCE : write once will check write data and cache data, ++ * if write data = cache data, data will not be writen. ++ */ ++#define RT_WR_ONCE (0x08) ++#define RT_NORMAL_WR_ONCE (RT_NORMAL|RT_WR_ONCE) ++#define RT_WBITS_WR_ONCE (RT_WBITS|RT_WR_ONCE) ++ ++enum rt_data_format { ++ RT_LITTLE_ENDIAN, ++ RT_BIG_ENDIAN, ++}; ++ ++/* rt_regmap_mode ++ * 0 0 0 0 0 0 0 0 ++ * | | | | | | ++ * | | | |__| byte_mode ++ * | |__| || ++ * | || Cache_mode ++ * | Block_mode ++ * Debug_mode ++ */ ++ ++#define RT_BYTE_MODE_MASK (0x01) ++/* 1 byte for each register*/ ++#define RT_SINGLE_BYTE (0 << 0) ++/* multi bytes for each regiseter*/ ++#define RT_MULTI_BYTE (1 << 0) ++ ++#define RT_CACHE_MODE_MASK (0x06) ++/* write to cache and chip synchronously */ ++#define RT_CACHE_WR_THROUGH (0 << 1) ++/* write to cache and chip asynchronously */ ++#define RT_CACHE_WR_BACK (1 << 1) ++/* disable cache */ ++#define RT_CACHE_DISABLE (2 << 1) ++ ++#define RT_IO_BLK_MODE_MASK (0x18) ++/* pass through all write function */ ++#define RT_IO_PASS_THROUGH (0 << 3) ++/* block all write function */ ++#define RT_IO_BLK_ALL (1 << 3) ++/* block cache write function */ ++#define RT_IO_BLK_CACHE (2 << 3) ++/* block chip write function */ ++#define RT_IO_BLK_CHIP (3 << 3) ++ ++#define DBG_MODE_MASK (0x20) ++/* create general debugfs for register map */ ++#define RT_DBG_GENERAL (0 << 5) ++/* create node for each regisetr map by register address*/ ++#define RT_DBG_SPECIAL (1 << 5) ++ ++ ++/* struct rt_register ++ * ++ * Ricktek register map structure for store mapping data ++ * @addr: register address. ++ * @name: register name. ++ * @size: register byte size. ++ * @reg_type: register R/W type ( RT_NORMAL, RT_WBITS, RT_VOLATILE, RT_RESERVE) ++ * @wbit_mask: register writeable bits mask; ++ * @cache_data: cache data for store cache value. ++ */ ++struct rt_register { ++ u32 addr; ++ const char *name; ++ unsigned int size; ++ unsigned char reg_type; ++ unsigned char *wbit_mask; ++ unsigned char *cache_data; ++}; ++ ++/* Declare a rt_register by RT_REG_DECL ++ * @_addr: regisetr address. ++ * @_reg_length: register data length. ++ * @_reg_type: register type (rt_reg_type). ++ * @_mask: register writealbe mask. ++ */ ++#define RT_REG_DECL(_addr, _reg_length, _reg_type, _mask_...) \ ++ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ ++ static struct rt_register rt_register_##_addr = { \ ++ .addr = _addr, \ ++ .size = _reg_length,\ ++ .reg_type = _reg_type,\ ++ .wbit_mask = rt_writable_mask_##_addr,\ ++ } ++ ++/* Declare a rt_register by RT_NAMED_REG_DECL ++ * @_name: a name for a rt_register. ++ */ ++#define RT_NAMED_REG_DECL(_addr, _name, _reg_length, _reg_type, _mask_...) \ ++ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ ++ static struct rt_register rt_register_##_addr = { \ ++ .addr = _addr, \ ++ .name = _name, \ ++ .size = _reg_length,\ ++ .reg_type = _reg_type,\ ++ .wbit_mask = rt_writable_mask_##_addr,\ ++ } ++ ++#define RT_REG(_addr) (&rt_register_##_addr) ++ ++/* rt_regmap_properties ++ * @name: the name of debug node. ++ * @aliases: alisis name of rt_regmap_device. ++ * @register_num: the number of rt_register_map registers. ++ * @rm: rt_regiseter_map pointer array. ++ * @group: register map access group. ++ * @rt_format: default is little endian. ++ * @rt_regmap_mode: rt_regmap_device mode. ++ * @io_log_en: enable/disable io log ++ */ ++struct rt_regmap_properties { ++ const char *name; ++ const char *aliases; ++ int register_num; ++ struct rt_register **rm; ++ struct rt_access_group *group; ++ enum rt_data_format rt_format; ++ unsigned char rt_regmap_mode; ++ unsigned char io_log_en:1; ++}; ++ ++/* A passing struct for rt_regmap_reg_read and rt_regmap_reg_write function ++ * reg: regmap addr. ++ * mask: mask for update bits. ++ * rt_data: register value. ++ */ ++struct rt_reg_data { ++ u32 reg; ++ u32 mask; ++ union { ++ u32 data_u32; ++ u16 data_u16; ++ u8 data_u8; ++ u8 data[4]; ++ } rt_data; ++}; ++ ++struct rt_regmap_device; ++ ++struct rt_debug_st { ++ void *info; ++ int id; ++}; ++ ++/* basic chip read/write function */ ++struct rt_regmap_fops { ++ int (*read_device)(void *client, u32 addr, int leng, void *dst); ++ int (*write_device)(void *client, u32 addr, int leng, const void *src); ++}; ++ ++/* with slave address */ ++extern struct rt_regmap_device* ++ rt_regmap_device_register_ex(struct rt_regmap_properties *props, ++ struct rt_regmap_fops *rops, ++ struct device *parent, ++ void *client, int slv_addr, void *drvdata); ++ ++static inline struct rt_regmap_device* ++ rt_regmap_device_register(struct rt_regmap_properties *props, ++ struct rt_regmap_fops *rops, ++ struct device *parent, ++ struct i2c_client *client, void *drvdata) ++{ ++ return rt_regmap_device_register_ex(props, rops, parent, ++ client, client->addr, drvdata); ++} ++ ++extern void rt_regmap_device_unregister(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_cache_init(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_cache_reload(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_block_write(struct rt_regmap_device *rd, u32 reg, ++ int bytes, const void *rc); ++extern int rt_asyn_regmap_block_write(struct rt_regmap_device *rd, u32 reg, ++ int bytes, const void *rc); ++extern int rt_regmap_block_read(struct rt_regmap_device *rd, u32 reg, ++ int bytes, void *dst); ++ ++extern int _rt_regmap_reg_read(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++extern int _rt_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++extern int _rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++extern int _rt_regmap_update_bits(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++ ++static inline int rt_regmap_reg_read(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg) ++{ ++ rrd->reg = reg; ++ return _rt_regmap_reg_read(rd, rrd); ++}; ++ ++static inline int rt_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg, const u32 data) ++{ ++ rrd->reg = reg; ++ rrd->rt_data.data_u32 = data; ++ return _rt_regmap_reg_write(rd, rrd); ++}; ++ ++static inline int rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg, const u32 data) ++{ ++ rrd->reg = reg; ++ rrd->rt_data.data_u32 = data; ++ return _rt_asyn_regmap_reg_write(rd, rrd); ++}; ++ ++static inline int rt_regmap_update_bits(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg, u32 mask, u32 data) ++{ ++ rrd->reg = reg; ++ rrd->mask = mask; ++ rrd->rt_data.data_u32 = data; ++ return _rt_regmap_update_bits(rd, rrd); ++} ++ ++extern void rt_regmap_cache_backup(struct rt_regmap_device *rd); ++ ++extern void rt_regmap_cache_sync(struct rt_regmap_device *rd); ++extern void rt_regmap_cache_write_back(struct rt_regmap_device *rd, u32 reg); ++ ++extern int rt_is_reg_readable(struct rt_regmap_device *rd, u32 reg); ++extern int rt_is_reg_volatile(struct rt_regmap_device *rd, u32 reg); ++extern int rt_get_regsize(struct rt_regmap_device *rd, u32 reg); ++extern void rt_cache_getlasterror(struct rt_regmap_device *rd, char *buf); ++extern void rt_cache_clrlasterror(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_add_debugfs(struct rt_regmap_device *rd, const char *name, ++ umode_t mode, void *data, const struct file_operations *fops); ++ ++#define to_rt_regmap_device(obj) container_of(obj, struct rt_regmap_device, dev) ++ ++#endif /*MISC_MEDIATEK_RT_REGMAP_H*/ +diff --git a/drivers/misc/mediatek/include/mt-plat/sync_write.h b/drivers/misc/mediatek/include/mt-plat/sync_write.h +new file mode 100644 +index 000000000000..f9e5fe4c23e1 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/sync_write.h +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MT_SYNC_WRITE_H ++#define _MT_SYNC_WRITE_H ++ ++#if defined(__KERNEL__) ++ ++#include ++#include ++ ++/* ++ * Define macros. ++ */ ++#define mt_reg_sync_writel(v, a) \ ++ do { \ ++ __raw_writel((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writew(v, a) \ ++ do { \ ++ __raw_writew((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writeb(v, a) \ ++ do { \ ++ __raw_writeb((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++ ++#ifdef CONFIG_64BIT ++#define mt_reg_sync_writeq(v, a) \ ++ do { \ ++ __raw_writeq((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++#endif ++ ++#else /* __KERNEL__ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define mt_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) ++#define mt_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) ++#define mt_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) ++ ++#define mb() \ ++ { \ ++ __asm__ __volatile__ ("dsb" : : : "memory"); \ ++ } ++ ++#define mt65xx_reg_sync_writel(v, a) \ ++ do { \ ++ *(volatile unsigned int *)(a) = (v); \ ++ mb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writew(v, a) \ ++ do { \ ++ *(volatile unsigned short *)(a) = (v); \ ++ mb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writeb(v, a) \ ++ do { \ ++ *(volatile unsigned char *)(a) = (v); \ ++ mb(); \ ++ } while (0) ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* !_MT_SYNC_WRITE_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/wakelock.h b/drivers/misc/mediatek/include/mt-plat/wakelock.h +new file mode 100644 +index 000000000000..f4a698a22880 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/wakelock.h +@@ -0,0 +1,67 @@ ++/* include/linux/wakelock.h ++ * ++ * Copyright (C) 2007-2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_WAKELOCK_H ++#define _LINUX_WAKELOCK_H ++ ++#include ++#include ++ ++/* A wake_lock prevents the system from entering suspend or other low power ++ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock ++ * prevents a full system suspend. ++ */ ++ ++enum { ++ WAKE_LOCK_SUSPEND, /* Prevent suspend */ ++ WAKE_LOCK_TYPE_COUNT ++}; ++ ++struct wake_lock { ++ struct wakeup_source ws; ++}; ++ ++static inline void wake_lock_init(struct wake_lock *lock, int type, ++ const char *name) ++{ ++ wakeup_source_init(&lock->ws, name); ++} ++ ++static inline void wake_lock_destroy(struct wake_lock *lock) ++{ ++ wakeup_source_trash(&lock->ws); ++} ++ ++static inline void wake_lock(struct wake_lock *lock) ++{ ++ __pm_stay_awake(&lock->ws); ++} ++ ++static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) ++{ ++ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); ++} ++ ++static inline void wake_unlock(struct wake_lock *lock) ++{ ++ __pm_relax(&lock->ws); ++} ++ ++static inline int wake_lock_active(struct wake_lock *lock) ++{ ++ return lock->ws.active; ++} ++ ++#endif +diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c +index e3df1e96b141..086c9ea8d7cb 100644 +--- a/drivers/soc/mediatek/mtk-pmic-wrap.c ++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c +@@ -1107,6 +1107,22 @@ static const struct of_device_id of_pwrap_match_tbl[] = { + }; + MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl); + ++struct regmap *pwrap_node_to_regmap(struct device_node *np) ++{ ++ struct platform_device *pdev; ++ struct pmic_wrapper *wrp; ++ ++ pdev = of_find_device_by_node(np); ++ ++ if (!pdev) ++ return ERR_PTR(-ENODEV); ++ ++ wrp = platform_get_drvdata(pdev); ++ ++ return wrp->regmap; ++} ++EXPORT_SYMBOL_GPL(pwrap_node_to_regmap); ++ + static int pwrap_probe(struct platform_device *pdev) + { + int ret, irq; +diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c +index 7ed417a765c7..43676313f32b 100644 +--- a/drivers/watchdog/mtk_wdt.c ++++ b/drivers/watchdog/mtk_wdt.c +@@ -21,14 +21,34 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include ++#include ++#include + #include ++#include + #include ++#ifdef CONFIG_FIQ_GLUE ++#include ++#include ++#endif + #include + #include ++#include ++#include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_MT6397_MISC ++#include ++#endif + + #define WDT_MAX_TIMEOUT 31 + #define WDT_MIN_TIMEOUT 1 +@@ -47,37 +67,167 @@ + #define WDT_MODE_EXRST_EN (1 << 2) + #define WDT_MODE_IRQ_EN (1 << 3) + #define WDT_MODE_AUTO_START (1 << 4) ++#define WDT_MODE_IRQ_LVL (1 << 5) + #define WDT_MODE_DUAL_EN (1 << 6) + #define WDT_MODE_KEY 0x22000000 + ++#define WDT_STATUS 0x0c ++#define WDT_NONRST_REG 0x20 ++#define WDT_NONRST_REG2 0x24 ++ + #define WDT_SWRST 0x14 + #define WDT_SWRST_KEY 0x1209 + ++#define WDT_SWSYSRST 0x18 ++#define WDT_SWSYSRST_KEY 0x88000000 ++ ++#define WDT_REQ_MODE 0x30 ++#define WDT_REQ_MODE_KEY 0x33000000 ++#define WDT_REQ_IRQ_EN 0x34 ++#define WDT_REQ_IRQ_KEY 0x44000000 ++#define WDT_REQ_MODE_DEBUG_EN 0x80000 ++ ++ + #define DRV_NAME "mtk-wdt" +-#define DRV_VERSION "1.0" ++#define DRV_VERSION "2.0" + + static bool nowayout = WATCHDOG_NOWAYOUT; + static unsigned int timeout = WDT_MAX_TIMEOUT; + ++struct toprgu_reset { ++ spinlock_t lock; ++ void __iomem *toprgu_swrst_base; ++ int regofs; ++ struct reset_controller_dev rcdev; ++}; ++ + struct mtk_wdt_dev { + struct watchdog_device wdt_dev; + void __iomem *wdt_base; ++ int wdt_irq_id; ++ struct notifier_block restart_handler; ++ struct toprgu_reset reset_controller; + }; + +-static int mtk_wdt_restart(struct watchdog_device *wdt_dev, +- unsigned long action, void *data) ++static void __iomem *toprgu_base; ++static struct watchdog_device *wdt_dev; ++ ++static int toprgu_reset_assert(struct reset_controller_dev *rcdev, ++ unsigned long id) + { +- struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); ++ unsigned int tmp; ++ unsigned long flags; ++ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); ++ ++ spin_lock_irqsave(&data->lock, flags); ++ ++ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); ++ tmp |= BIT(id); ++ tmp |= WDT_SWSYSRST_KEY; ++ writel(tmp, data->toprgu_swrst_base + data->regofs); ++ ++ spin_unlock_irqrestore(&data->lock, flags); ++ ++ return 0; ++} ++ ++static int toprgu_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ unsigned int tmp; ++ unsigned long flags; ++ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); ++ ++ spin_lock_irqsave(&data->lock, flags); ++ ++ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); ++ tmp &= ~BIT(id); ++ tmp |= WDT_SWSYSRST_KEY; ++ writel(tmp, data->toprgu_swrst_base + data->regofs); ++ ++ spin_unlock_irqrestore(&data->lock, flags); ++ ++ return 0; ++} ++ ++static int toprgu_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = toprgu_reset_assert(rcdev, id); ++ if (ret) ++ return ret; ++ ++ return toprgu_reset_deassert(rcdev, id); ++} ++ ++static struct reset_control_ops toprgu_reset_ops = { ++ .assert = toprgu_reset_assert, ++ .deassert = toprgu_reset_deassert, ++ .reset = toprgu_reset, ++}; ++ ++static void toprgu_register_reset_controller(struct platform_device *pdev, int regofs) ++{ ++ int ret; ++ struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); ++ ++ spin_lock_init(&mtk_wdt->reset_controller.lock); ++ ++ mtk_wdt->reset_controller.toprgu_swrst_base = mtk_wdt->wdt_base; ++ mtk_wdt->reset_controller.regofs = regofs; ++ mtk_wdt->reset_controller.rcdev.owner = THIS_MODULE; ++ mtk_wdt->reset_controller.rcdev.nr_resets = 15; ++ mtk_wdt->reset_controller.rcdev.ops = &toprgu_reset_ops; ++ mtk_wdt->reset_controller.rcdev.of_node = pdev->dev.of_node; ++ ++ ret = reset_controller_register(&mtk_wdt->reset_controller.rcdev); ++ if (ret) ++ pr_err("could not register toprgu reset controller: %d\n", ret); ++} ++ ++static int mtk_reset_handler(struct notifier_block *this, unsigned long mode, ++ void *cmd) ++{ ++ struct mtk_wdt_dev *mtk_wdt; + void __iomem *wdt_base; ++ u32 reg; + ++ mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler); + wdt_base = mtk_wdt->wdt_base; + +- while (1) { +- writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); +- mdelay(5); ++ /* WDT_STATUS will be cleared to zero after writing to WDT_MODE, so we backup it in WDT_NONRST_REG, ++ * and then print it out in mtk_wdt_probe() after reset ++ */ ++ writel(__raw_readl(wdt_base + WDT_STATUS), wdt_base + WDT_NONRST_REG); ++ ++ reg = ioread32(wdt_base + WDT_MODE); ++ reg &= ~(WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EN); ++ reg |= WDT_MODE_KEY; ++ iowrite32(reg, wdt_base + WDT_MODE); ++ ++ if (cmd && !strcmp(cmd, "rpmbpk")) { ++ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 0), wdt_base + WDT_NONRST_REG2); ++ } else if (cmd && !strcmp(cmd, "recovery")) { ++ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 1), wdt_base + WDT_NONRST_REG2); ++ #ifdef CONFIG_MT6397_MISC ++ mtk_misc_mark_recovery(); ++ #endif ++ } else if (cmd && !strcmp(cmd, "bootloader")) { ++ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 2), wdt_base + WDT_NONRST_REG2); ++ #ifdef CONFIG_MT6397_MISC ++ mtk_misc_mark_fast(); ++ #endif + } + +- return 0; ++ if (!arm_pm_restart) { ++ while (1) { ++ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); ++ mdelay(5); ++ } ++ } ++ return NOTIFY_DONE; + } + + static int mtk_wdt_ping(struct watchdog_device *wdt_dev) +@@ -86,6 +236,7 @@ static int mtk_wdt_ping(struct watchdog_device *wdt_dev) + void __iomem *wdt_base = mtk_wdt->wdt_base; + + iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); ++ printk_deferred("[WDK]: kick Ex WDT\n"); + + return 0; + } +@@ -137,7 +288,8 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev) + return ret; + + reg = ioread32(wdt_base + WDT_MODE); +- reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); ++ reg |= (WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EXRST_EN); ++ reg &= ~(WDT_MODE_IRQ_LVL | WDT_MODE_EXT_POL_HIGH); + reg |= (WDT_MODE_EN | WDT_MODE_KEY); + iowrite32(reg, wdt_base + WDT_MODE); + +@@ -157,13 +309,56 @@ static const struct watchdog_ops mtk_wdt_ops = { + .stop = mtk_wdt_stop, + .ping = mtk_wdt_ping, + .set_timeout = mtk_wdt_set_timeout, +- .restart = mtk_wdt_restart, + }; + ++#ifdef CONFIG_FIQ_GLUE ++static void wdt_fiq(void *arg, void *regs, void *svc_sp) ++{ ++ unsigned int wdt_mode_val; ++ void __iomem *wdt_base = ((struct mtk_wdt_dev *)arg)->wdt_base; ++ ++ wdt_mode_val = __raw_readl(wdt_base + WDT_STATUS); ++ writel(wdt_mode_val, wdt_base + WDT_NONRST_REG); ++ ++ aee_wdt_fiq_info(arg, regs, svc_sp); ++} ++#else ++static void wdt_report_info(void) ++{ ++ struct task_struct *task; ++ ++ task = &init_task; ++ pr_debug("Qwdt: -- watchdog time out\n"); ++ ++ for_each_process(task) { ++ if (task->state == 0) { ++ pr_debug("PID: %d, name: %s\n backtrace:\n", task->pid, task->comm); ++ show_stack(task, NULL); ++ pr_debug("\n"); ++ } ++ } ++ ++ pr_debug("backtrace of current task:\n"); ++ show_stack(NULL, NULL); ++ pr_debug("Qwdt: -- watchdog time out\n"); ++} ++ ++static irqreturn_t mtk_wdt_isr(int irq, void *dev_id) ++{ ++ pr_err("fwq mtk_wdt_isr\n"); ++ ++ wdt_report_info(); ++ BUG(); ++ ++ return IRQ_HANDLED; ++} ++#endif ++ + static int mtk_wdt_probe(struct platform_device *pdev) + { + struct mtk_wdt_dev *mtk_wdt; + struct resource *res; ++ unsigned int tmp; + int err; + + mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL); +@@ -174,9 +369,32 @@ static int mtk_wdt_probe(struct platform_device *pdev) + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res); ++ + if (IS_ERR(mtk_wdt->wdt_base)) + return PTR_ERR(mtk_wdt->wdt_base); + ++ pr_err("MTK_WDT_NONRST_REG(%x)\n", __raw_readl(mtk_wdt->wdt_base + WDT_NONRST_REG)); ++ ++ mtk_wdt->wdt_irq_id = irq_of_parse_and_map(pdev->dev.of_node, 0); ++ if (!mtk_wdt->wdt_irq_id) { ++ pr_err("RGU get IRQ ID failed\n"); ++ return -ENODEV; ++ } ++ ++#ifndef CONFIG_FIQ_GLUE ++ err = request_irq(mtk_wdt->wdt_irq_id, (irq_handler_t)mtk_wdt_isr, IRQF_TRIGGER_NONE, DRV_NAME, mtk_wdt); ++#else ++ mtk_wdt->wdt_irq_id = get_hardware_irq(mtk_wdt->wdt_irq_id); ++ err = request_fiq(mtk_wdt->wdt_irq_id, wdt_fiq, IRQF_TRIGGER_FALLING, mtk_wdt); ++#endif ++ if (err != 0) { ++ pr_err("mtk_wdt_probe : failed to request irq (%d)\n", err); ++ return err; ++ } ++ ++ toprgu_base = mtk_wdt->wdt_base; ++ wdt_dev = &mtk_wdt->wdt_dev; ++ + mtk_wdt->wdt_dev.info = &mtk_wdt_info; + mtk_wdt->wdt_dev.ops = &mtk_wdt_ops; + mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT; +@@ -186,7 +404,6 @@ static int mtk_wdt_probe(struct platform_device *pdev) + + watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev); + watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout); +- watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128); + + watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); + +@@ -196,9 +413,40 @@ static int mtk_wdt_probe(struct platform_device *pdev) + if (unlikely(err)) + return err; + ++ mtk_wdt->restart_handler.notifier_call = mtk_reset_handler; ++ mtk_wdt->restart_handler.priority = 128; ++ ++ if (arm_pm_restart) { ++ dev_info(&pdev->dev, "register restart_handler on reboot_notifier_list for psci reset\n"); ++ err = register_reboot_notifier(&mtk_wdt->restart_handler); ++ if (err != 0) ++ dev_warn(&pdev->dev, ++ "cannot register reboot notifier (err=%d)\n", err); ++ } else { ++ err = register_restart_handler(&mtk_wdt->restart_handler); ++ if (err) ++ dev_warn(&pdev->dev, ++ "cannot register restart handler (err=%d)\n", err); ++ } ++ + dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", + mtk_wdt->wdt_dev.timeout, nowayout); + ++ writel(WDT_REQ_MODE_KEY | (__raw_readl(mtk_wdt->wdt_base + WDT_REQ_MODE) & ++ (~WDT_REQ_MODE_DEBUG_EN)), mtk_wdt->wdt_base + WDT_REQ_MODE); ++ ++ toprgu_register_reset_controller(pdev, WDT_SWSYSRST); ++ ++ /* enable scpsys thermal and thermal_controller request, and set to reset directly mode */ ++ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_MODE) | (1 << 18) | (1 << 0); ++ tmp |= WDT_REQ_MODE_KEY; ++ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_MODE); ++ ++ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); ++ tmp &= ~((1 << 18) | (1 << 0)); ++ tmp |= WDT_REQ_IRQ_KEY; ++ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); ++ + return 0; + } + +@@ -214,8 +462,12 @@ static int mtk_wdt_remove(struct platform_device *pdev) + { + struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); + ++ unregister_restart_handler(&mtk_wdt->restart_handler); ++ + watchdog_unregister_device(&mtk_wdt->wdt_dev); + ++ reset_controller_unregister(&mtk_wdt->reset_controller.rcdev); ++ + return 0; + } + +@@ -267,6 +519,95 @@ static struct platform_driver mtk_wdt_driver = { + + module_platform_driver(mtk_wdt_driver); + ++static int wk_proc_cmd_read(struct seq_file *s, void *v) ++{ ++ unsigned int enabled = 1; ++ ++ if (!(ioread32(toprgu_base + WDT_MODE) & WDT_MODE_EN)) ++ enabled = 0; ++ ++ seq_printf(s, "enabled timeout\n%-4d %-8d\n", enabled, wdt_dev->timeout); ++ ++ return 0; ++} ++ ++static int wk_proc_cmd_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, wk_proc_cmd_read, NULL); ++} ++ ++static ssize_t wk_proc_cmd_write(struct file *file, const char *buf, size_t count, loff_t *data) ++{ ++ int ret; ++ int enable; ++ int timeout; ++ char wk_cmd_buf[256]; ++ ++ if (count == 0) ++ return -1; ++ ++ if (count > 255) ++ count = 255; ++ ++ ret = copy_from_user(wk_cmd_buf, buf, count); ++ if (ret < 0) ++ return -1; ++ ++ wk_cmd_buf[count] = '\0'; ++ ++ pr_debug("Write %s\n", wk_cmd_buf); ++ ++ ret = sscanf(wk_cmd_buf, "%d %d", &enable, &timeout); ++ if (ret != 2) ++ pr_debug("%s: expect 2 numbers\n", __func__); ++ ++ pr_debug("[WDK] enable=%d timeout=%d\n", enable, timeout); ++ ++ if (timeout > 20 && timeout <= WDT_MAX_TIMEOUT) { ++ wdt_dev->timeout = timeout; ++ mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); ++ } else { ++ pr_err("[WDK] The timeout(%d) should bigger than 20 and not bigger than %d\n", ++ timeout, WDT_MAX_TIMEOUT); ++ ++ } ++ ++ if (enable == 1) { ++ mtk_wdt_start(wdt_dev); ++ set_bit(WDOG_ACTIVE, &wdt_dev->status); ++ pr_err("[WDK] enable wdt\n"); ++ } else if (enable == 0) { ++ mtk_wdt_stop(wdt_dev); ++ clear_bit(WDOG_ACTIVE, &wdt_dev->status); ++ pr_err("[WDK] disable wdt\n"); ++ } ++ ++ return count; ++} ++ ++static const struct file_operations wk_proc_cmd_fops = { ++ .owner = THIS_MODULE, ++ .open = wk_proc_cmd_open, ++ .read = seq_read, ++ .write = wk_proc_cmd_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int __init wk_proc_init(void) ++{ ++ struct proc_dir_entry *de = proc_create("wdk", 0660, NULL, &wk_proc_cmd_fops); ++ ++ if (!de) ++ pr_err("[wk_proc_init]: create /proc/wdk failed\n"); ++ ++ pr_debug("[WDK] Initialize proc\n"); ++ ++ return 0; ++} ++ ++late_initcall(wk_proc_init); ++ + module_param(timeout, uint, 0); + MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); + +diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h +new file mode 100644 +index 000000000000..f4a698a22880 +--- /dev/null ++++ b/include/linux/wakelock.h +@@ -0,0 +1,67 @@ ++/* include/linux/wakelock.h ++ * ++ * Copyright (C) 2007-2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_WAKELOCK_H ++#define _LINUX_WAKELOCK_H ++ ++#include ++#include ++ ++/* A wake_lock prevents the system from entering suspend or other low power ++ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock ++ * prevents a full system suspend. ++ */ ++ ++enum { ++ WAKE_LOCK_SUSPEND, /* Prevent suspend */ ++ WAKE_LOCK_TYPE_COUNT ++}; ++ ++struct wake_lock { ++ struct wakeup_source ws; ++}; ++ ++static inline void wake_lock_init(struct wake_lock *lock, int type, ++ const char *name) ++{ ++ wakeup_source_init(&lock->ws, name); ++} ++ ++static inline void wake_lock_destroy(struct wake_lock *lock) ++{ ++ wakeup_source_trash(&lock->ws); ++} ++ ++static inline void wake_lock(struct wake_lock *lock) ++{ ++ __pm_stay_awake(&lock->ws); ++} ++ ++static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) ++{ ++ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); ++} ++ ++static inline void wake_unlock(struct wake_lock *lock) ++{ ++ __pm_relax(&lock->ws); ++} ++ ++static inline int wake_lock_active(struct wake_lock *lock) ++{ ++ return lock->ws.active; ++} ++ ++#endif +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index f12fa5245a45..946ccff6ddc0 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -3261,7 +3261,7 @@ enum wiphy_flags { + WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), + WIPHY_FLAG_IBSS_RSN = BIT(8), + WIPHY_FLAG_MESH_AUTH = BIT(10), +- /* use hole at 11 */ ++ WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), + /* use hole at 12 */ + WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13), + WIPHY_FLAG_AP_UAPSD = BIT(14), +diff --git a/include/net/genetlink.h b/include/net/genetlink.h +index 5ac169a735f4..b25568a44e59 100644 +--- a/include/net/genetlink.h ++++ b/include/net/genetlink.h +@@ -144,6 +144,51 @@ struct genl_ops { + }; + + int genl_register_family(struct genl_family *family); ++ ++/** ++ * genl_register_family_with_ops - register a generic netlink family with ops ++ * @family: generic netlink family ++ * @ops: operations to be registered ++ * @n_ops: number of elements to register ++ * ++ * Registers the specified family and operations from the specified table. ++ * Only one family may be registered with the same family name or identifier. ++ * ++ * The family id may equal GENL_ID_GENERATE causing an unique id to ++ * be automatically generated and assigned. ++ * ++ * Either a doit or dumpit callback must be specified for every registered ++ * operation or the function will fail. Only one operation structure per ++ * command identifier may be registered. ++ * ++ * See include/net/genetlink.h for more documenation on the operations ++ * structure. ++ * ++ * Return 0 on success or a negative error code. ++ */ ++static inline int ++_genl_register_family_with_ops_grps(struct genl_family *family, ++ const struct genl_ops *ops, size_t n_ops, ++ const struct genl_multicast_group *mcgrps, ++ size_t n_mcgrps) ++{ ++ family->module = THIS_MODULE; ++ family->ops = ops; ++ family->n_ops = n_ops; ++ family->mcgrps = mcgrps; ++ family->n_mcgrps = n_mcgrps; ++ return genl_register_family(family); ++} ++ ++#define genl_register_family_with_ops(family, ops) \ ++ _genl_register_family_with_ops_grps((family), \ ++ (ops), ARRAY_SIZE(ops), \ ++ NULL, 0) ++#define genl_register_family_with_ops_groups(family, ops, grps) \ ++ _genl_register_family_with_ops_grps((family), \ ++ (ops), ARRAY_SIZE(ops), \ ++ (grps), ARRAY_SIZE(grps)) ++ + int genl_unregister_family(const struct genl_family *family); + void genl_notify(const struct genl_family *family, struct sk_buff *skb, + struct genl_info *info, u32 group, gfp_t flags); +diff --git a/include/soc/mediatek/pmic_wrap.h b/include/soc/mediatek/pmic_wrap.h +new file mode 100644 +index 000000000000..5b5c85272c58 +--- /dev/null ++++ b/include/soc/mediatek/pmic_wrap.h +@@ -0,0 +1,19 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __SOC_MEDIATEK_PMIC_WRAP_H ++#define __SOC_MEDIATEK_PMIC_WRAP_H ++ ++extern struct regmap *pwrap_node_to_regmap(struct device_node *np); ++ ++#endif /* __SOC_MEDIATEK_PMIC_WRAP_H */ +diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h +index 877f7fa95466..c8456b78cc25 100644 +--- a/include/uapi/linux/genetlink.h ++++ b/include/uapi/linux/genetlink.h +@@ -27,6 +27,7 @@ struct genlmsghdr { + /* + * List of reserved static generic netlink identifiers: + */ ++#define GENL_ID_GENERATE 0 + #define GENL_ID_CTRL NLMSG_MIN_TYPE + #define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) + #define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) +-- +2.17.1 + diff --git a/root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch b/root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch new file mode 100755 index 00000000..5b8e6131 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch @@ -0,0 +1,35 @@ +From 16c20209050ce9dc0d67e256c3dfba902868c3ed Mon Sep 17 00:00:00 2001 +From: Nikolay Amiantov +Date: Tue, 3 Jul 2018 12:40:04 +0000 +Subject: [PATCH] Revert "fs: unexport vfs_read and vfs_write" + +This reverts commit bd8df82be66698042d11e7919e244c8d72b042ca. +--- + fs/read_write.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/read_write.c b/fs/read_write.c +index 0046d72efe94..62b9c341afa9 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -455,6 +455,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) + return ret; + } + ++EXPORT_SYMBOL(vfs_read); ++ + static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) + { + struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; +@@ -553,6 +555,8 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ + return ret; + } + ++EXPORT_SYMBOL(vfs_write); ++ + static inline loff_t file_pos_read(struct file *file) + { + return file->f_pos; +-- +2.17.1 + diff --git a/root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch b/root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch new file mode 100755 index 00000000..bc957ee1 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch @@ -0,0 +1,127 @@ +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +@@ -519,6 +519,9 @@ INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl( + } + + #endif ++ ++EXPORT_SYMBOL(mtk_wcn_consys_hw_wifi_paldo_ctrl); ++ + INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) + { + if (enable) { +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +@@ -4530,13 +4530,10 @@ INT_32 kalHaltLock(UINT_32 waitMs) + DBGLOG(INIT, ERROR, + "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", + kalGetTimeTick() - rHaltCtrl.u4HoldStart); +- if (prGlueInfo) +- show_stack(prGlueInfo->main_thread, NULL); + } else { + DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", + rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, + kalGetTimeTick() - rHaltCtrl.u4HoldStart); +- show_stack(rHaltCtrl.owner, NULL); + } + return i4Ret; + } +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +@@ -58,7 +58,6 @@ + ******************************************************************************** + */ + BOOLEAN fgIsResetting = FALSE; +-UINT_32 g_IsNeedDoChipReset = 0; + + /******************************************************************************* + * P R I V A T E D A T A +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +@@ -44,6 +44,9 @@ MODULE_LICENSE("Dual BSD/GPL"); + #define WIFI_LOG_WARN 1 + #define WIFI_LOG_ERR 0 + ++UINT32 g_IsNeedDoChipReset = 0; ++EXPORT_SYMBOL(g_IsNeedDoChipReset); ++ + UINT32 gDbgLevel = WIFI_LOG_DBG; + + #define WIFI_DBG_FUNC(fmt, arg...)\ +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +@@ -21,7 +21,11 @@ endif + obj-y += osal.o \ + bgw_desense.o \ + wmt_idc.o +-obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o +-obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o ++ifneq ($(CONFIG_MTK_COMBO_BT),) ++ obj-y += stp_chrdev_bt.o ++endif ++ifneq ($(CONFIG_MTK_COMBO_WIFI),) ++ obj-y += wmt_chrdev_wifi.o ++endif + + endif +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +@@ -25,7 +25,7 @@ int do_wlan_drv_init(int chip_id) + { + int i_ret = 0; + +-#ifdef CONFIG_MTK_COMBO_WIFI ++#ifdef MTK_WIFI_ENABLED + int ret = 0; + + WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); +@@ -35,6 +35,7 @@ int do_wlan_drv_init(int chip_id) + WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); + i_ret += ret; + ++#ifdef CONFIG_MTK_COMBO_WIFI + switch (chip_id) { + case 0x6630: + case 0x6797: +@@ -61,13 +62,10 @@ int do_wlan_drv_init(int chip_id) + #endif + break; + } +- ++#endif + WMT_DETECT_INFO_FUNC("finish wlan module init\n"); +- + #else +- + WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); +- + #endif + + return i_ret; +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +@@ -11,6 +11,10 @@ else ifneq ($(filter "CONSYS_%",$(CONFIG + ccflags-y += -D MTK_WCN_WLAN_GEN2 + endif + ++ifneq ($(CONFIG_MTK_COMBO_WIFI),) ++ ccflags-y += -D MTK_WIFI_ENABLED ++endif ++ + obj-y += conn_drv_init.o + obj-y += common_drv_init.o + obj-y += bluetooth_drv_init.o diff --git a/root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch b/root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch new file mode 100755 index 00000000..a9f2078c --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch @@ -0,0 +1,12 @@ +Index: linux-4.14.51/drivers/watchdog/mtk_wdt.c +=================================================================== +--- linux-4.14.51.orig/drivers/watchdog/mtk_wdt.c ++++ linux-4.14.51/drivers/watchdog/mtk_wdt.c +@@ -236,7 +236,6 @@ static int mtk_wdt_ping(struct watchdog_ + void __iomem *wdt_base = mtk_wdt->wdt_base; + + iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); +- printk_deferred("[WDK]: kick Ex WDT\n"); + + return 0; + } diff --git a/root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch b/root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch new file mode 100755 index 00000000..e1691fd3 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch @@ -0,0 +1,13 @@ +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +@@ -62,7 +62,7 @@ UINT32 gDbgLevel = WIFI_LOG_DBG; + + #define VERSION "1.0" + +-#define WLAN_IFACE_NAME "wlan0" ++#define WLAN_IFACE_NAME "mtkwlan0" + #if CFG_TC1_FEATURE + #define LEGACY_IFACE_NAME "legacy0" + #endif diff --git a/root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch b/root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch new file mode 100755 index 00000000..5f71df06 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch @@ -0,0 +1,1824 @@ +From b3ba09aea285ecdac5228805411f1e7a6c68382a Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 8 Jul 2018 17:27:58 +0200 +Subject: [PATCH] [HNAT] applied full Patch from hnat-branch + +--- + arch/arm/boot/dts/mt7623.dtsi | 9 + + arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 +- + drivers/net/ethernet/mediatek/Kconfig | 7 + + drivers/net/ethernet/mediatek/Makefile | 1 + + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 + + .../net/ethernet/mediatek/mtk_hnat/Makefile | 4 + + drivers/net/ethernet/mediatek/mtk_hnat/hnat.c | 329 ++++++++++++ + drivers/net/ethernet/mediatek/mtk_hnat/hnat.h | 427 +++++++++++++++ + .../ethernet/mediatek/mtk_hnat/hnat_debugfs.c | 489 ++++++++++++++++++ + .../ethernet/mediatek/mtk_hnat/hnat_nf_hook.c | 312 +++++++++++ + .../ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h | 44 ++ + net/netfilter/nf_conntrack_proto_tcp.c | 19 + + 12 files changed, 1666 insertions(+), 1 deletion(-) + create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/Makefile + create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat.c + create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat.h + create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c + create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c + create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 44831a813a48f..1633d19564ca8 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -1207,6 +1207,15 @@ + status = "disabled"; + }; + ++ hnat: hnat@1b000000 { ++ compatible = "mediatek,mt7623-hnat"; ++ reg = <0 0x1b100000 0 0x3000>; ++ mtketh-wan = "wan"; ++ resets = <ðsys 0>; ++ reset-names = "mtketh"; ++ }; ++ ++ + crypto: crypto@1b240000 { + compatible = "mediatek,mt7623-crypto"; + reg = <0 0x1b240000 0 0x20000>; +diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig +index f9149d2a46940..314c6fe670f81 100644 +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -14,4 +14,11 @@ config NET_MEDIATEK_SOC + This driver supports the gigabit ethernet MACs in the + MediaTek SoC family. + ++config NET_MEDIATEK_HNAT ++ tristate "MediaTek MT7623 hardware NAT support" ++ depends on NET_MEDIATEK_SOC && NF_CONNTRACK && NF_CONNTRACK_IPV4 && IP_NF_NAT && IP_NF_TARGET_MASQUERADE ++ ---help--- ++ This driver supports the hardware NAT in the ++ MediaTek MT2701/MT7623 chipset family. ++ + endif #NET_VENDOR_MEDIATEK +diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile +index aa3f1c8ccd4ab..355c928f4700e 100644 +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -3,3 +3,4 @@ + # + + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth_soc.o ++obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtk_hnat/ +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index e6b6596e6a4a9..de4969cc672c4 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -24,6 +24,10 @@ + #include + #include + ++#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) ++#include "mtk_hnat/nf_hnat_mtk.h" ++#endif ++ + #include "mtk_eth_soc.h" + + static int mtk_msg_level = -1; +@@ -699,6 +703,11 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, + return -ENOMEM; + + /* set the forward port */ ++#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) ++ if (HNAT_SKB_CB2(skb)->magic == 0x78681415) ++ fport |= 0x4 << TX_DMA_FPORT_SHIFT; ++ else ++#endif + fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT; + txd4 |= fport; + +@@ -1063,6 +1072,10 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, + RX_DMA_VID(trxd.rxd3)) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + RX_DMA_VID(trxd.rxd3)); ++#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) ++ *(u32 *)(skb->head) = trxd.rxd4; ++ skb_hnat_alg(skb) = 0; ++#endif + skb_record_rx_queue(skb, 0); + napi_gro_receive(napi, skb); + +@@ -2000,6 +2013,12 @@ static int mtk_hw_init(struct mtk_eth *eth) + val = mtk_r32(eth, MTK_CDMP_IG_CTRL); + mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); + ++ /* Indicates CDM to parse the MTK special tag from CPU ++ * which also is working out for untag packets. ++ */ ++ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); ++ mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); ++ + /* Enable RX VLan Offloading */ + if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX) + mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); +@@ -2033,6 +2052,9 @@ static int mtk_hw_init(struct mtk_eth *eth) + /* Enable RX checksum */ + val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN; + ++ /* Enable special tag */ ++ val |= BIT(24); ++ + /* setup the mac dma */ + mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); + } +diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/Makefile b/drivers/net/ethernet/mediatek/mtk_hnat/Makefile +new file mode 100644 +index 0000000000000..e052abcd43020 +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_hnat/Makefile +@@ -0,0 +1,4 @@ ++ccflags-y=-Werror -Wno-missing-braces ++ ++obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtkhnat.o ++mtkhnat-objs := hnat.o hnat_nf_hook.o hnat_debugfs.o +diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c +new file mode 100644 +index 0000000000000..22a822737934f +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c +@@ -0,0 +1,329 @@ ++/* This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Copyright (C) 2014-2016 Sean Wang ++ * Copyright (C) 2016-2017 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "hnat.h" ++ ++struct hnat_priv *host; ++ ++static void cr_set_bits(void __iomem * reg, u32 bs) ++{ ++ u32 val = readl(reg); ++ ++ val |= bs; ++ writel(val, reg); ++} ++ ++static void cr_clr_bits(void __iomem * reg, u32 bs) ++{ ++ u32 val = readl(reg); ++ ++ val &= ~bs; ++ writel(val, reg); ++} ++ ++static void cr_set_field(void __iomem * reg, u32 field, u32 val) ++{ ++ unsigned int tv = readl(reg); ++ ++ tv &= ~field; ++ tv |= ((val) << (ffs((unsigned int)field) - 1)); ++ writel(tv, reg); ++} ++ ++static int hnat_start(void) ++{ ++ u32 foe_table_sz; ++ ++ /* mapp the FOE table */ ++ foe_table_sz = FOE_4TB_SIZ * sizeof(struct foe_entry); ++ host->foe_table_cpu = ++ dma_alloc_coherent(host->dev, foe_table_sz, &host->foe_table_dev, ++ GFP_KERNEL); ++ if (!host->foe_table_cpu) ++ return -1; ++ ++ writel(host->foe_table_dev, host->ppe_base + PPE_TB_BASE); ++ memset(host->foe_table_cpu, 0, foe_table_sz); ++ ++ /* setup hashing */ ++ cr_set_field(host->ppe_base + PPE_TB_CFG, TB_ETRY_NUM, TABLE_4K); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, HASH_MODE, HASH_MODE_1); ++ writel(HASH_SEED_KEY, host->ppe_base + PPE_HASH_SEED); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, XMODE, 0); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, TB_ENTRY_SIZE, ENTRY_64B); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, SMA, SMA_FWD_CPU_BUILD_ENTRY); ++ ++ /* set ip proto */ ++ writel(0xFFFFFFFF, host->ppe_base + PPE_IP_PROT_CHK); ++ ++ /* setup caching */ ++ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 1); ++ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 0); ++ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_EN, 1); ++ ++ /* enable FOE */ ++ cr_set_bits(host->ppe_base + PPE_FLOW_CFG, ++ BIT_IPV4_NAT_EN | BIT_IPV4_NAPT_EN | ++ BIT_IPV4_NAT_FRAG_EN | BIT_IPV4_HASH_GREK); ++ ++ /* setup FOE aging */ ++ cr_set_field(host->ppe_base + PPE_TB_CFG, NTU_AGE, 1); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, UNBD_AGE, 1); ++ cr_set_field(host->ppe_base + PPE_UNB_AGE, UNB_MNP, 1000); ++ cr_set_field(host->ppe_base + PPE_UNB_AGE, UNB_DLTA, 3); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, TCP_AGE, 1); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, UDP_AGE, 1); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, FIN_AGE, 1); ++ cr_set_field(host->ppe_base + PPE_BND_AGE_0, UDP_DLTA, 5); ++ cr_set_field(host->ppe_base + PPE_BND_AGE_0, NTU_DLTA, 5); ++ cr_set_field(host->ppe_base + PPE_BND_AGE_1, FIN_DLTA, 5); ++ cr_set_field(host->ppe_base + PPE_BND_AGE_1, TCP_DLTA, 5); ++ ++ /* setup FOE ka */ ++ cr_set_field(host->ppe_base + PPE_TB_CFG, KA_CFG, 3); ++ cr_set_field(host->ppe_base + PPE_KA, KA_T, 1); ++ cr_set_field(host->ppe_base + PPE_KA, TCP_KA, 1); ++ cr_set_field(host->ppe_base + PPE_KA, UDP_KA, 1); ++ cr_set_field(host->ppe_base + PPE_BIND_LMT_1, NTU_KA, 1); ++ ++ /* setup FOE rate limit */ ++ cr_set_field(host->ppe_base + PPE_BIND_LMT_0, QURT_LMT, 16383); ++ cr_set_field(host->ppe_base + PPE_BIND_LMT_0, HALF_LMT, 16383); ++ cr_set_field(host->ppe_base + PPE_BIND_LMT_1, FULL_LMT, 16383); ++ cr_set_field(host->ppe_base + PPE_BNDR, BIND_RATE, 1); ++ ++ /* setup FOE cf gen */ ++ cr_set_field(host->ppe_base + PPE_GLO_CFG, PPE_EN, 1); ++ writel(0, host->ppe_base + PPE_DFT_CPORT); // pdma ++ //writel(0x55555555, host->ppe_base + PPE_DFT_CPORT); //qdma ++ cr_set_field(host->ppe_base + PPE_GLO_CFG, TTL0_DRP, 1); ++ ++ /* fwd packets from gmac to PPE */ ++ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK); ++ cr_set_bits(host->fe_base + GDMA1_FWD_CFG, ++ BITS_GDM1_ALL_FRC_P_PPE); ++ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK); ++ cr_set_bits(host->fe_base + GDMA2_FWD_CFG, ++ BITS_GDM2_ALL_FRC_P_PPE); ++ ++ dev_info(host->dev, "hwnat start\n"); ++ ++ return 0; ++} ++ ++static int ppe_busy_wait(void) ++{ ++ unsigned long t_start = jiffies; ++ u32 r = 0; ++ ++ while (1) { ++ r = readl((host->ppe_base + 0x0)); ++ if (!(r & BIT(31))) ++ return 0; ++ if (time_after(jiffies, t_start + HZ)) ++ break; ++ usleep_range(10, 20); ++ } ++ ++ dev_err(host->dev, "ppe:%s timeout\n", __func__); ++ ++ return -1; ++} ++ ++static void hnat_stop(void) ++{ ++ u32 foe_table_sz; ++ struct foe_entry *entry, *end; ++ u32 r1 = 0, r2 = 0; ++ ++ /* discard all traffic while we disable the PPE */ ++ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK); ++ cr_set_bits(host->fe_base + GDMA1_FWD_CFG, ++ BITS_GDM1_ALL_FRC_P_DISCARD); ++ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK); ++ cr_set_bits(host->fe_base + GDMA2_FWD_CFG, ++ BITS_GDM2_ALL_FRC_P_DISCARD); ++ ++ if (ppe_busy_wait()) { ++#if 0 ++ reset_control_reset(host->rstc); ++#endif ++ msleep(2000); ++ return; ++ } ++ ++ entry = host->foe_table_cpu; ++ end = host->foe_table_cpu + FOE_4TB_SIZ; ++ while (entry < end) { ++ entry->bfib1.state = INVALID; ++ entry++; ++ } ++ ++ /* disable caching */ ++ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 1); ++ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 0); ++ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_EN, 0); ++ ++ /* flush cache has to be ahead of hnat diable --*/ ++ cr_set_field(host->ppe_base + PPE_GLO_CFG, PPE_EN, 0); ++ ++ /* disable FOE */ ++ cr_clr_bits(host->ppe_base + PPE_FLOW_CFG, ++ BIT_IPV4_NAPT_EN | BIT_IPV4_NAT_EN | ++ BIT_IPV4_NAT_FRAG_EN | ++ BIT_FUC_FOE | BIT_FMC_FOE | BIT_FUC_FOE); ++ ++ /* disable FOE aging */ ++ cr_set_field(host->ppe_base + PPE_TB_CFG, NTU_AGE, 0); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, UNBD_AGE, 0); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, TCP_AGE, 0); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, UDP_AGE, 0); ++ cr_set_field(host->ppe_base + PPE_TB_CFG, FIN_AGE, 0); ++ ++ r1 = readl(host->fe_base + 0x100); ++ r2 = readl(host->fe_base + 0x10c); ++ ++ dev_info(host->dev, "0x100 = 0x%x, 0x10c = 0x%x\n", r1, r2); ++ ++ if (((r1 & 0xff00) >> 0x8) >= (r1 & 0xff) || ++ ((r1 & 0xff00) >> 0x8) >= (r2 & 0xff)) { ++ dev_info(host->dev, "reset pse\n"); ++ writel(0x1, host->fe_base + 0x4); ++ } ++ ++ /* free the FOE table */ ++ foe_table_sz = FOE_4TB_SIZ * sizeof(struct foe_entry); ++ dma_free_coherent(NULL, foe_table_sz, host->foe_table_cpu, ++ host->foe_table_dev); ++ writel(0, host->ppe_base + PPE_TB_BASE); ++ ++ if (ppe_busy_wait()) { ++#if 0 ++ reset_control_reset(host->rstc); ++#endif ++ msleep(2000); ++ return; ++ } ++ ++ /* send all traffic back to the DMA engine */ ++ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK); ++ cr_set_bits(host->fe_base + GDMA1_FWD_CFG, ++ BITS_GDM1_ALL_FRC_P_CPU_PDMA); ++ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK); ++ cr_set_bits(host->fe_base + GDMA2_FWD_CFG, ++ BITS_GDM2_ALL_FRC_P_CPU_PDMA); ++} ++ ++static int hnat_probe(struct platform_device *pdev) ++{ ++ struct net *net; ++ int ret; ++ int err = 0; ++ struct resource *res ; ++ const char *name; ++ struct device_node *np; ++ ++ host = devm_kzalloc(&pdev->dev, sizeof(struct hnat_priv), GFP_KERNEL); ++ if (!host) ++ return -ENOMEM; ++ ++ host->dev = &pdev->dev; ++ np = host->dev->of_node; ++ ++ err = of_property_read_string(np, "mtketh-wan", &name); ++ if (err < 0) ++ return -EINVAL; ++ ++ memcpy(host->wan, (char *)name, IFNAMSIZ); ++ dev_info(&pdev->dev, "wan = %s\n", host->wan); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -ENOENT; ++ ++ host->fe_base = devm_ioremap_nocache(&pdev->dev, res->start, ++ res->end - res->start + 1); ++ if (!host->fe_base) ++ return -EADDRNOTAVAIL; ++ ++ host->ppe_base = host->fe_base + 0xe00; ++ err = hnat_init_debugfs(host); ++ if (err) ++ return err; ++#if 0 ++ host->rstc = devm_reset_control_get(&pdev->dev, NULL); ++ if (IS_ERR(host->rstc)) ++ return PTR_ERR(host->rstc); ++#endif ++ err = hnat_start(); ++ if (err) ++ goto err_out; ++ ++ //err = hnat_register_nf_hooks(); //how to call the function with net-param?? ++ for_each_net(net) { ++ ret=hnat_register_nf_hooks(net); ++ //if (err) ++ if (ret && ret != -ENOENT) ++ goto err_out; ++ } ++ return 0; ++ ++err_out: ++ hnat_stop(); ++ hnat_deinit_debugfs(host); ++ return err; ++} ++ ++static int hnat_remove(struct platform_device *pdev) ++{ ++ struct net *net; ++ //hnat_unregister_nf_hooks(); //how to call the function with net-param?? ++ for_each_net(net) { ++ hnat_unregister_nf_hooks(net); ++ } ++ ++ hnat_stop(); ++ hnat_deinit_debugfs(host); ++ ++ return 0; ++} ++ ++const struct of_device_id of_hnat_match[] = { ++ { .compatible = "mediatek,mt7623-hnat" }, ++ {}, ++}; ++ ++static struct platform_driver hnat_driver = { ++ .probe = hnat_probe, ++ .remove = hnat_remove, ++ .driver = { ++ .name = "mediatek_soc_hnat", ++ .of_match_table = of_hnat_match, ++ }, ++}; ++ ++module_platform_driver(hnat_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Sean Wang "); ++MODULE_AUTHOR("John Crispin "); ++MODULE_DESCRIPTION("Mediatek Hardware NAT"); +diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h +new file mode 100644 +index 0000000000000..336ebb34c325d +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h +@@ -0,0 +1,427 @@ ++/* This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Copyright (C) 2014-2016 Sean Wang ++ * Copyright (C) 2016-2017 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++/*--------------------------------------------------------------------------*/ ++/* Register Offset*/ ++/*--------------------------------------------------------------------------*/ ++#define PPE_GLO_CFG 0x00 ++#define PPE_FLOW_CFG 0x04 ++#define PPE_IP_PROT_CHK 0x08 ++#define PPE_IP_PROT_0 0x0C ++#define PPE_IP_PROT_1 0x10 ++#define PPE_IP_PROT_2 0x14 ++#define PPE_IP_PROT_3 0x18 ++#define PPE_TB_CFG 0x1C ++#define PPE_TB_BASE 0x20 ++#define PPE_TB_USED 0x24 ++#define PPE_BNDR 0x28 ++#define PPE_BIND_LMT_0 0x2C ++#define PPE_BIND_LMT_1 0x30 ++#define PPE_KA 0x34 ++#define PPE_UNB_AGE 0x38 ++#define PPE_BND_AGE_0 0x3C ++#define PPE_BND_AGE_1 0x40 ++#define PPE_HASH_SEED 0x44 ++#define PPE_DFT_CPORT 0x48 ++#define PPE_MCAST_PPSE 0x84 ++#define PPE_MCAST_L_0 0x88 ++#define PPE_MCAST_H_0 0x8C ++#define PPE_MCAST_L_1 0x90 ++#define PPE_MCAST_H_1 0x94 ++#define PPE_MCAST_L_2 0x98 ++#define PPE_MCAST_H_2 0x9C ++#define PPE_MCAST_L_3 0xA0 ++#define PPE_MCAST_H_3 0xA4 ++#define PPE_MCAST_L_4 0xA8 ++#define PPE_MCAST_H_4 0xAC ++#define PPE_MCAST_L_5 0xB0 ++#define PPE_MCAST_H_5 0xB4 ++#define PPE_MCAST_L_6 0xBC ++#define PPE_MCAST_H_6 0xC0 ++#define PPE_MCAST_L_7 0xC4 ++#define PPE_MCAST_H_7 0xC8 ++#define PPE_MCAST_L_8 0xCC ++#define PPE_MCAST_H_8 0xD0 ++#define PPE_MCAST_L_9 0xD4 ++#define PPE_MCAST_H_9 0xD8 ++#define PPE_MCAST_L_A 0xDC ++#define PPE_MCAST_H_A 0xE0 ++#define PPE_MCAST_L_B 0xE4 ++#define PPE_MCAST_H_B 0xE8 ++#define PPE_MCAST_L_C 0xEC ++#define PPE_MCAST_H_C 0xF0 ++#define PPE_MCAST_L_D 0xF4 ++#define PPE_MCAST_H_D 0xF8 ++#define PPE_MCAST_L_E 0xFC ++#define PPE_MCAST_H_E 0xE0 ++#define PPE_MCAST_L_F 0x100 ++#define PPE_MCAST_H_F 0x104 ++#define PPE_MTU_DRP 0x108 ++#define PPE_MTU_VLYR_0 0x10C ++#define PPE_MTU_VLYR_1 0x110 ++#define PPE_MTU_VLYR_2 0x114 ++#define PPE_VPM_TPID 0x118 ++#define PPE_CAH_CTRL 0x120 ++#define PPE_CAH_TAG_SRH 0x124 ++#define PPE_CAH_LINE_RW 0x128 ++#define PPE_CAH_WDATA 0x12C ++#define PPE_CAH_RDATA 0x130 ++ ++#define GDMA1_FWD_CFG 0x500 ++#define GDMA2_FWD_CFG 0x1500 ++/*--------------------------------------------------------------------------*/ ++/* Register Mask*/ ++/*--------------------------------------------------------------------------*/ ++/* PPE_TB_CFG mask */ ++#define TB_ETRY_NUM (0x7 << 0) /* RW */ ++#define TB_ENTRY_SIZE (0x1 << 3) /* RW */ ++#define SMA (0x3 << 4) /* RW */ ++#define NTU_AGE (0x1 << 7) /* RW */ ++#define UNBD_AGE (0x1 << 8) /* RW */ ++#define TCP_AGE (0x1 << 9) /* RW */ ++#define UDP_AGE (0x1 << 10) /* RW */ ++#define FIN_AGE (0x1 << 11) /* RW */ ++#define KA_CFG (0x3<< 12) ++#define HASH_MODE (0x3 << 14) /* RW */ ++#define XMODE (0x3 << 18) /* RW */ ++ ++/*PPE_CAH_CTRL mask*/ ++#define CAH_EN (0x1 << 0) /* RW */ ++#define CAH_X_MODE (0x1 << 9) /* RW */ ++ ++/*PPE_UNB_AGE mask*/ ++#define UNB_DLTA (0xff << 0) /* RW */ ++#define UNB_MNP (0xffff << 16) /* RW */ ++ ++/*PPE_BND_AGE_0 mask*/ ++#define UDP_DLTA (0xffff << 0) /* RW */ ++#define NTU_DLTA (0xffff << 16) /* RW */ ++ ++/*PPE_BND_AGE_1 mask*/ ++#define TCP_DLTA (0xffff << 0) /* RW */ ++#define FIN_DLTA (0xffff << 16) /* RW */ ++ ++/*PPE_KA mask*/ ++#define KA_T (0xffff << 0) /* RW */ ++#define TCP_KA (0xff << 16) /* RW */ ++#define UDP_KA (0xff << 24) /* RW */ ++ ++/*PPE_BIND_LMT_0 mask*/ ++#define QURT_LMT (0x3ff << 0) /* RW */ ++#define HALF_LMT (0x3ff << 16) /* RW */ ++ ++/*PPE_BIND_LMT_1 mask*/ ++#define FULL_LMT (0x3fff << 0) /* RW */ ++#define NTU_KA (0xff << 16) /* RW */ ++ ++/*PPE_BNDR mask*/ ++#define BIND_RATE (0xffff << 0) /* RW */ ++#define PBND_RD_PRD (0xffff << 16) /* RW */ ++ ++/*PPE_GLO_CFG mask*/ ++#define PPE_EN (0x1 << 0) /* RW */ ++#define TTL0_DRP (0x1 << 4) /* RW */ ++ ++/*GDMA1_FWD_CFG mask */ ++#define GDM1_UFRC_MASK (0x7 << 12) /* RW */ ++#define GDM1_BFRC_MASK (0x7 << 8) /*RW*/ ++#define GDM1_MFRC_MASK (0x7 << 4) /*RW*/ ++#define GDM1_OFRC_MASK (0x7 << 0) /*RW*/ ++#define GDM1_ALL_FRC_MASK (GDM1_UFRC_MASK | GDM1_BFRC_MASK | GDM1_MFRC_MASK | GDM1_OFRC_MASK) ++ ++#define GDM2_UFRC_MASK (0x7 << 12) /* RW */ ++#define GDM2_BFRC_MASK (0x7 << 8) /*RW*/ ++#define GDM2_MFRC_MASK (0x7 << 4) /*RW*/ ++#define GDM2_OFRC_MASK (0x7 << 0) /*RW*/ ++#define GDM2_ALL_FRC_MASK (GDM2_UFRC_MASK | GDM2_BFRC_MASK | GDM2_MFRC_MASK | GDM2_OFRC_MASK) ++ ++/*--------------------------------------------------------------------------*/ ++/* Descriptor Structure */ ++/*--------------------------------------------------------------------------*/ ++#define HNAT_SKB_CB(__skb) ((struct hnat_skb_cb *)&((__skb)->cb[40])) ++struct hnat_skb_cb { ++ __u16 iif; ++}; ++ ++struct hnat_unbind_info_blk { ++ u32 time_stamp:8; ++ u32 pcnt:16; /* packet count */ ++ u32 preb:1; ++ u32 pkt_type:3; ++ u32 state:2; ++ u32 udp:1; ++ u32 sta:1; /* static entry */ ++} __attribute__ ((packed)); ++ ++struct hnat_bind_info_blk { ++ u32 time_stamp:15; ++ u32 ka:1; /* keep alive */ ++ u32 vlan_layer:3; ++ u32 psn:1; /* egress packet has PPPoE session */ ++ u32 vpm:1; /* 0:ethertype remark, 1:0x8100(CR default) */ ++ u32 ps:1; /* packet sampling */ ++ u32 cah:1; /* cacheable flag */ ++ u32 rmt:1; /* remove tunnel ip header (6rd/dslite only) */ ++ u32 ttl:1; ++ u32 pkt_type:3; ++ u32 state:2; ++ u32 udp:1; ++ u32 sta:1; /* static entry */ ++} __attribute__ ((packed)); ++ ++struct hnat_info_blk2 { ++ u32 qid:4; /* QID in Qos Port */ ++ u32 fqos:1; /* force to PSE QoS port */ ++ u32 dp:3; /* force to PSE port x ++ 0:PSE,1:GSW, 2:GMAC,4:PPE,5:QDMA,7=DROP */ ++ u32 mcast:1; /* multicast this packet to CPU */ ++ u32 pcpl:1; /* OSBN */ ++ u32 mlen:1; /* 0:post 1:pre packet length in meter */ ++ u32 alen:1; /* 0:post 1:pre packet length in accounting */ ++ u32 port_mg:6; /* port meter group */ ++ u32 port_ag:6; /* port account group */ ++ u32 dscp:8; /* DSCP value */ ++} __attribute__ ((packed)); ++ ++struct hnat_ipv4_hnapt { ++ union { ++ struct hnat_bind_info_blk bfib1; ++ struct hnat_unbind_info_blk udib1; ++ u32 info_blk1; ++ }; ++ u32 sip; ++ u32 dip; ++ u16 dport; ++ u16 sport; ++ union { ++ struct hnat_info_blk2 iblk2; ++ u32 info_blk2; ++ }; ++ u32 new_sip; ++ u32 new_dip; ++ u16 new_dport; ++ u16 new_sport; ++ u32 resv1; ++ u32 resv2; ++ u32 resv3:26; ++ u32 act_dp:6; /* UDF */ ++ u16 vlan1; ++ u16 etype; ++ u32 dmac_hi; ++ u16 vlan2; ++ u16 dmac_lo; ++ u32 smac_hi; ++ u16 pppoe_id; ++ u16 smac_lo; ++} __attribute__ ((packed)); ++ ++struct foe_entry { ++ union { ++ struct hnat_unbind_info_blk udib1; ++ struct hnat_bind_info_blk bfib1; ++ struct hnat_ipv4_hnapt ipv4_hnapt; ++ }; ++}; ++ ++#define HNAT_AC_BYTE_LO(x) (0x2000 + (x * 16)) ++#define HNAT_AC_BYTE_HI(x) (0x2004 + (x * 16)) ++#define HNAT_AC_PACKET(x) (0x2008 + (x * 16)) ++#define HNAT_COUNTER_MAX 64 ++#define HNAT_AC_TIMER_INTERVAL (HZ) ++ ++struct hnat_accounting { ++ u64 bytes; ++ u64 packets; ++}; ++ ++struct hnat_priv { ++ struct device *dev; ++ void __iomem *fe_base; ++ void __iomem *ppe_base; ++ struct foe_entry *foe_table_cpu; ++ dma_addr_t foe_table_dev; ++ u8 enable; ++ u8 enable1; ++ struct dentry *root; ++ struct debugfs_regset32 *regset; ++ ++ struct timer_list ac_timer; ++ struct hnat_accounting acct[HNAT_COUNTER_MAX]; ++ ++ /*devices we plays for*/ ++ char wan[IFNAMSIZ]; ++ ++ struct reset_control *rstc; ++}; ++ ++enum FoeEntryState { ++ INVALID = 0, ++ UNBIND = 1, ++ BIND = 2, ++ FIN = 3 ++}; ++/*--------------------------------------------------------------------------*/ ++/* Common Definition*/ ++/*--------------------------------------------------------------------------*/ ++ ++#define FOE_4TB_SIZ 4096 ++#define HASH_SEED_KEY 0x12345678 ++ ++/*PPE_TB_CFG value*/ ++#define ENTRY_80B 1 ++#define ENTRY_64B 0 ++#define TABLE_1K 0 ++#define TABLE_2K 1 ++#define TABLE_4K 2 ++#define TABLE_8K 3 ++#define TABLE_16K 4 ++#define SMA_DROP 0 /* Drop the packet */ ++#define SMA_DROP2 1 /* Drop the packet */ ++#define SMA_ONLY_FWD_CPU 2 /* Only Forward to CPU */ ++#define SMA_FWD_CPU_BUILD_ENTRY 3 /* Forward to CPU and build new FOE entry */ ++#define HASH_MODE_0 0 ++#define HASH_MODE_1 1 ++#define HASH_MODE_2 2 ++#define HASH_MODE_3 3 ++ ++/*PPE_FLOW_CFG*/ ++#define BIT_FUC_FOE BIT(2) ++#define BIT_FMC_FOE BIT(1) ++#define BIT_FBC_FOE BIT(0) ++#define BIT_IPV4_NAT_EN BIT(12) ++#define BIT_IPV4_NAPT_EN BIT(13) ++#define BIT_IPV4_NAT_FRAG_EN BIT(17) ++#define BIT_IPV4_HASH_GREK BIT(19) ++ ++/*GDMA1_FWD_CFG value */ ++#define BITS_GDM1_UFRC_P_PPE (NR_PPE_PORT << 12) ++#define BITS_GDM1_BFRC_P_PPE (NR_PPE_PORT << 8) ++#define BITS_GDM1_MFRC_P_PPE (NR_PPE_PORT << 4) ++#define BITS_GDM1_OFRC_P_PPE (NR_PPE_PORT << 0) ++#define BITS_GDM1_ALL_FRC_P_PPE (BITS_GDM1_UFRC_P_PPE | BITS_GDM1_BFRC_P_PPE | BITS_GDM1_MFRC_P_PPE | BITS_GDM1_OFRC_P_PPE) ++ ++#define BITS_GDM1_UFRC_P_CPU_PDMA (NR_PDMA_PORT << 12) ++#define BITS_GDM1_BFRC_P_CPU_PDMA (NR_PDMA_PORT << 8) ++#define BITS_GDM1_MFRC_P_CPU_PDMA (NR_PDMA_PORT << 4) ++#define BITS_GDM1_OFRC_P_CPU_PDMA (NR_PDMA_PORT << 0) ++#define BITS_GDM1_ALL_FRC_P_CPU_PDMA (BITS_GDM1_UFRC_P_CPU_PDMA | BITS_GDM1_BFRC_P_CPU_PDMA | BITS_GDM1_MFRC_P_CPU_PDMA | BITS_GDM1_OFRC_P_CPU_PDMA) ++ ++#define BITS_GDM1_UFRC_P_CPU_QDMA (NR_QDMA_PORT << 12) ++#define BITS_GDM1_BFRC_P_CPU_QDMA (NR_QDMA_PORT << 8) ++#define BITS_GDM1_MFRC_P_CPU_QDMA (NR_QDMA_PORT << 4) ++#define BITS_GDM1_OFRC_P_CPU_QDMA (NR_QDMA_PORT << 0) ++#define BITS_GDM1_ALL_FRC_P_CPU_QDMA (BITS_GDM1_UFRC_P_CPU_QDMA | BITS_GDM1_BFRC_P_CPU_QDMA | BITS_GDM1_MFRC_P_CPU_QDMA | BITS_GDM1_OFRC_P_CPU_QDMA) ++ ++#define BITS_GDM1_UFRC_P_DISCARD (NR_DISCARD << 12) ++#define BITS_GDM1_BFRC_P_DISCARD (NR_DISCARD << 8) ++#define BITS_GDM1_MFRC_P_DISCARD (NR_DISCARD << 4) ++#define BITS_GDM1_OFRC_P_DISCARD (NR_DISCARD << 0) ++#define BITS_GDM1_ALL_FRC_P_DISCARD (BITS_GDM1_UFRC_P_DISCARD | BITS_GDM1_BFRC_P_DISCARD | BITS_GDM1_MFRC_P_DISCARD | BITS_GDM1_OFRC_P_DISCARD) ++ ++#define BITS_GDM2_UFRC_P_PPE (NR_PPE_PORT << 12) ++#define BITS_GDM2_BFRC_P_PPE (NR_PPE_PORT << 8) ++#define BITS_GDM2_MFRC_P_PPE (NR_PPE_PORT << 4) ++#define BITS_GDM2_OFRC_P_PPE (NR_PPE_PORT << 0) ++#define BITS_GDM2_ALL_FRC_P_PPE (BITS_GDM2_UFRC_P_PPE | BITS_GDM2_BFRC_P_PPE | BITS_GDM2_MFRC_P_PPE | BITS_GDM2_OFRC_P_PPE) ++ ++#define BITS_GDM2_UFRC_P_CPU_PDMA (NR_PDMA_PORT << 12) ++#define BITS_GDM2_BFRC_P_CPU_PDMA (NR_PDMA_PORT << 8) ++#define BITS_GDM2_MFRC_P_CPU_PDMA (NR_PDMA_PORT << 4) ++#define BITS_GDM2_OFRC_P_CPU_PDMA (NR_PDMA_PORT << 0) ++#define BITS_GDM2_ALL_FRC_P_CPU_PDMA (BITS_GDM2_UFRC_P_CPU_PDMA | BITS_GDM2_BFRC_P_CPU_PDMA | BITS_GDM2_MFRC_P_CPU_PDMA | BITS_GDM2_OFRC_P_CPU_PDMA) ++ ++#define BITS_GDM2_UFRC_P_CPU_QDMA (NR_QDMA_PORT << 12) ++#define BITS_GDM2_BFRC_P_CPU_QDMA (NR_QDMA_PORT << 8) ++#define BITS_GDM2_MFRC_P_CPU_QDMA (NR_QDMA_PORT << 4) ++#define BITS_GDM2_OFRC_P_CPU_QDMA (NR_QDMA_PORT << 0) ++#define BITS_GDM2_ALL_FRC_P_CPU_QDMA (BITS_GDM2_UFRC_P_CPU_QDMA | BITS_GDM2_BFRC_P_CPU_QDMA | BITS_GDM2_MFRC_P_CPU_QDMA | BITS_GDM2_OFRC_P_CPU_QDMA) ++ ++#define BITS_GDM2_UFRC_P_DISCARD (NR_DISCARD << 12) ++#define BITS_GDM2_BFRC_P_DISCARD (NR_DISCARD << 8) ++#define BITS_GDM2_MFRC_P_DISCARD (NR_DISCARD << 4) ++#define BITS_GDM2_OFRC_P_DISCARD (NR_DISCARD << 0) ++#define BITS_GDM2_ALL_FRC_P_DISCARD (BITS_GDM2_UFRC_P_DISCARD | BITS_GDM2_BFRC_P_DISCARD | BITS_GDM2_MFRC_P_DISCARD | BITS_GDM2_OFRC_P_DISCARD) ++ ++#define hnat_is_enabled(host) (host->enable) ++#define hnat_enabled(host) (host->enable = 1) ++#define hnat_disabled(host) (host->enable = 0) ++#define hnat_is_enabled1(host) (host->enable1) ++#define hnat_enabled1(host) (host->enable1 = 1) ++#define hnat_disabled1(host) (host->enable1 = 0) ++ ++#define entry_hnat_is_bound(e) (e->bfib1.state == BIND) ++#define entry_hnat_state(e) (e->bfib1.state) ++ ++#define skb_hnat_is_hashed(skb) (skb_hnat_entry(skb)!=0x3fff && skb_hnat_entry(skb)< FOE_4TB_SIZ) ++#define FROM_GE_LAN(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_LAN) ++#define FROM_GE_WAN(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_WAN) ++#define FROM_GE_PPD(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_PPD) ++#define FOE_MAGIC_GE_WAN 0x7273 ++#define FOE_MAGIC_GE_LAN 0x7272 ++#define FOE_INVALID 0xffff ++ ++#define TCP_FIN_SYN_RST 0x0C /* Ingress packet is TCP fin/syn/rst (for IPv4 NAPT/DS-Lite or IPv6 5T-route/6RD) */ ++#define UN_HIT 0x0D/* FOE Un-hit */ ++#define HIT_UNBIND 0x0E/* FOE Hit unbind */ ++#define HIT_UNBIND_RATE_REACH 0xf ++#define HNAT_HIT_BIND_OLD_DUP_HDR 0x15 ++#define HNAT_HIT_BIND_FORCE_TO_CPU 0x16 ++ ++#define HIT_BIND_KEEPALIVE_MC_NEW_HDR 0x14 ++#define HIT_BIND_KEEPALIVE_DUP_OLD_HDR 0x15 ++#define IPV4_HNAPT 0 ++#define IPV4_HNAT 1 ++#define IP_FORMAT(addr) \ ++ ((unsigned char *)&addr)[3], \ ++ ((unsigned char *)&addr)[2], \ ++ ((unsigned char *)&addr)[1], \ ++ ((unsigned char *)&addr)[0] ++ ++/*PSE Ports*/ ++#define NR_PDMA_PORT 0 ++#define NR_GMAC1_PORT 1 ++#define NR_GMAC2_PORT 2 ++#define NR_PPE_PORT 4 ++#define NR_QDMA_PORT 5 ++#define NR_DISCARD 7 ++#define IS_LAN(dev) (!strncmp(dev->name, "lan", 3)) ++#define IS_WAN(dev) (!strcmp(dev->name, host->wan)) ++#define IS_BR(dev) (!strncmp(dev->name, "br", 2)) ++#define IS_IPV4_HNAPT(x) (((x)->bfib1.pkt_type == IPV4_HNAPT) ? 1: 0) ++#define IS_IPV4_HNAT(x) (((x)->bfib1.pkt_type == IPV4_HNAT) ? 1 : 0) ++#define IS_IPV4_GRP(x) (IS_IPV4_HNAPT(x) | IS_IPV4_HNAT(x)) ++ ++#define es(entry) (entry_state[entry->bfib1.state]) ++#define ei(entry, end) (FOE_4TB_SIZ - (int)(end - entry)) ++#define pt(entry) (packet_type[entry->ipv4_hnapt.bfib1.pkt_type]) ++#define ipv4_smac(mac,e) ({mac[0]=e->ipv4_hnapt.smac_hi[3]; mac[1]=e->ipv4_hnapt.smac_hi[2];\ ++ mac[2]=e->ipv4_hnapt.smac_hi[1]; mac[3]=e->ipv4_hnapt.smac_hi[0];\ ++ mac[4]=e->ipv4_hnapt.smac_lo[1]; mac[5]=e->ipv4_hnapt.smac_lo[0];}) ++#define ipv4_dmac(mac,e) ({mac[0]=e->ipv4_hnapt.dmac_hi[3]; mac[1]=e->ipv4_hnapt.dmac_hi[2];\ ++ mac[2]=e->ipv4_hnapt.dmac_hi[1]; mac[3]=e->ipv4_hnapt.dmac_hi[0];\ ++ mac[4]=e->ipv4_hnapt.dmac_lo[1]; mac[5]=e->ipv4_hnapt.dmac_lo[0];}) ++ ++extern struct hnat_priv *host; ++ ++extern void hnat_deinit_debugfs(struct hnat_priv *h); ++extern int hnat_init_debugfs(struct hnat_priv *h); ++//extern int hnat_register_nf_hooks(void); ++//extern void hnat_unregister_nf_hooks(void); ++extern int hnat_register_nf_hooks(struct net *net); ++extern void hnat_unregister_nf_hooks(struct net *net); ++ +diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c +new file mode 100644 +index 0000000000000..fbb0380ea0d92 +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c +@@ -0,0 +1,489 @@ ++/* This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Copyright (C) 2014-2016 Sean Wang ++ * Copyright (C) 2016-2017 John Crispin ++ */ ++ ++#include ++#include ++#include ++ ++#include "hnat.h" ++ ++static const char *entry_state[] = { ++ "INVALID", ++ "UNBIND", ++ "BIND", ++ "FIN" ++}; ++ ++static const char *packet_type[] = { ++ "IPV4_HNAPT", ++ "IPV4_HNAT", ++ "IPV6_1T_ROUTE", ++ "IPV4_DSLITE", ++ "IPV6_3T_ROUTE", ++ "IPV6_5T_ROUTE", ++ "IPV6_6RD", ++}; ++ ++static int hnat_debug_show(struct seq_file *m, void *private) ++{ ++ struct hnat_priv *h = host; ++ struct foe_entry *entry, *end; ++ ++ entry = h->foe_table_cpu; ++ end = h->foe_table_cpu + FOE_4TB_SIZ; ++ while (entry < end) { ++ if (!entry->bfib1.state) { ++ entry++; ++ continue; ++ } ++ ++ if (IS_IPV4_HNAPT(entry)) { ++ __be32 saddr = htonl(entry->ipv4_hnapt.sip); ++ __be32 daddr = htonl(entry->ipv4_hnapt.dip); ++ __be32 nsaddr = htonl(entry->ipv4_hnapt.new_sip); ++ __be32 ndaddr = htonl(entry->ipv4_hnapt.new_dip); ++ unsigned char h_dest[ETH_ALEN]; ++ unsigned char h_source[ETH_ALEN]; ++ ++ *((u32*) h_source) = swab32(entry->ipv4_hnapt.smac_hi); ++ *((u16*) &h_source[4]) = swab16(entry->ipv4_hnapt.smac_lo); ++ *((u32*) h_dest) = swab32(entry->ipv4_hnapt.dmac_hi); ++ *((u16*) &h_dest[4]) = swab16(entry->ipv4_hnapt.dmac_lo); ++ seq_printf(m, ++ "(%p)0x%05x|state=%s|type=%s|%pI4:%d->%pI4:%d=>%pI4:%d->%pI4:%d|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n", ++ (void *)h->foe_table_dev + ((void *)(entry) - (void *)h->foe_table_cpu), ++ ei(entry, end), es(entry), pt(entry), ++ &saddr, entry->ipv4_hnapt.sport, ++ &daddr, entry->ipv4_hnapt.dport, ++ &nsaddr, entry->ipv4_hnapt.new_sport, ++ &ndaddr, entry->ipv4_hnapt.new_dport, h_source, ++ h_dest, ntohs(entry->ipv4_hnapt.etype), ++ entry->ipv4_hnapt.info_blk1, ++ entry->ipv4_hnapt.info_blk2, ++ entry->ipv4_hnapt.vlan1, ++ entry->ipv4_hnapt.vlan2); ++ } else ++ seq_printf(m, "0x%05x state=%s\n", ++ ei(entry, end), es(entry)); ++ entry++; ++ } ++ ++ return 0; ++} ++ ++static int hnat_debug_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, hnat_debug_show, file->private_data); ++} ++ ++static const struct file_operations hnat_debug_fops = { ++ .open = hnat_debug_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++#define QDMA_TX_SCH_TX 0x1a14 ++ ++static ssize_t hnat_sched_show(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ int id = (int) file->private_data; ++ struct hnat_priv *h = host; ++ u32 reg = readl(h->fe_base + QDMA_TX_SCH_TX); ++ int enable; ++ int max_rate; ++ char *buf; ++ unsigned int len = 0, buf_len = 1500; ++ ssize_t ret_cnt; ++ ++ buf = kzalloc(buf_len, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ ++ if (id) ++ reg >>= 16; ++ reg &= 0xffff; ++ enable = !! (reg & BIT(11)); ++ max_rate = ((reg >> 4) & 0x7f); ++ reg &= 0xf; ++ while (reg--) ++ max_rate *= 10; ++ ++ len += scnprintf(buf + len, buf_len - len, ++ "EN\tMAX\n%d\t%d\n", enable, max_rate); ++ ++ if (len > buf_len) ++ len = buf_len; ++ ++ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ ++ kfree(buf); ++ return ret_cnt; ++} ++ ++static ssize_t hnat_sched_write(struct file *file, ++ const char __user *buf, size_t length, loff_t *offset) ++{ ++ int id = (int) file->private_data; ++ struct hnat_priv *h = host; ++ char line[64]; ++ int enable, rate, exp = 0, shift = 0; ++ size_t size; ++ u32 reg = readl(h->fe_base + QDMA_TX_SCH_TX); ++ u32 val = 0; ++ ++ if (length > sizeof(line)) ++ return -EINVAL; ++ ++ if (copy_from_user(line, buf, length)) ++ return -EFAULT; ++ ++ sscanf(line, "%d %d", &enable, &rate); ++ ++ while (rate > 127) { ++ rate /= 10; ++ exp++; ++ } ++ ++ if (enable) ++ val |= BIT(11); ++ val |= (rate & 0x7f) << 4; ++ val |= exp & 0xf; ++ if (id) ++ shift = 16; ++ reg &= ~(0xffff << shift); ++ reg |= val << shift; ++ writel(reg, h->fe_base + QDMA_TX_SCH_TX); ++ ++ size = strlen(line); ++ *offset += size; ++ ++ return length; ++} ++ ++static const struct file_operations hnat_sched_fops = { ++ .open = simple_open, ++ .read = hnat_sched_show, ++ .write = hnat_sched_write, ++ .llseek = default_llseek, ++}; ++ ++#define QTX_CFG(x) (0x1800 + (x * 0x10)) ++#define QTX_SCH(x) (0x1804 + (x * 0x10)) ++ ++static ssize_t hnat_queue_show(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct hnat_priv *h = host; ++ int id = (int) file->private_data; ++ u32 reg = readl(h->fe_base + QTX_SCH(id)); ++ u32 cfg = readl(h->fe_base + QTX_CFG(id)); ++ int scheduler = !!(reg & BIT(31)); ++ int min_rate_en = !!(reg & BIT(27)); ++ int min_rate = (reg >> 20) & 0x7f; ++ int min_rate_exp = (reg >> 16) & 0xf; ++ int max_rate_en = !!(reg & BIT(11)); ++ int max_weight = (reg >> 12) & 0xf; ++ int max_rate = (reg >> 4) & 0x7f; ++ int max_rate_exp = reg & 0xf; ++ char *buf; ++ unsigned int len = 0, buf_len = 1500; ++ ssize_t ret_cnt; ++ ++ buf = kzalloc(buf_len, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ while (min_rate_exp--) ++ min_rate *= 10; ++ ++ while (max_rate_exp--) ++ max_rate *= 10; ++ ++ len += scnprintf(buf + len, buf_len - len, ++ "scheduler: %d\nhw resv: %d\nsw resv: %d\n", ++ scheduler, (cfg >> 8) & 0xff, cfg & 0xff); ++ len += scnprintf(buf + len, buf_len - len, ++ "\tEN\tRATE\t\tWEIGHT\n"); ++ len += scnprintf(buf + len, buf_len - len, ++ "max\t%d\t%8d\t%d\n", max_rate_en, max_rate, max_weight); ++ len += scnprintf(buf + len, buf_len - len, ++ "min\t%d\t%8d\t-\n", min_rate_en, min_rate); ++ ++ if (len > buf_len) ++ len = buf_len; ++ ++ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ ++ kfree(buf); ++ return ret_cnt; ++} ++ ++static ssize_t hnat_queue_write(struct file *file, ++ const char __user *buf, size_t length, loff_t *offset) ++{ ++ int id = (int) file->private_data; ++ struct hnat_priv *h = host; ++ char line[64]; ++ int max_enable, max_rate, max_exp = 0; ++ int min_enable, min_rate, min_exp = 0; ++ int weight; ++ int resv; ++ int scheduler; ++ size_t size; ++ u32 reg = readl(h->fe_base + QTX_SCH(id)); ++ ++ if (length > sizeof(line)) ++ return -EINVAL; ++ ++ if (copy_from_user(line, buf, length)) ++ return -EFAULT; ++ ++ sscanf(line, "%d %d %d %d %d %d %d", &scheduler, &min_enable, &min_rate, &max_enable, &max_rate, &weight, &resv); ++ ++ while (max_rate > 127) { ++ max_rate /= 10; ++ max_exp++; ++ } ++ ++ while (min_rate > 127) { ++ min_rate /= 10; ++ min_exp++; ++ } ++ ++ reg &= 0x70000000; ++ if (scheduler) ++ reg |= BIT(31); ++ if (min_enable) ++ reg |= BIT(27); ++ reg |= (min_rate & 0x7f) << 20; ++ reg |= (min_exp & 0xf) << 16; ++ if (max_enable) ++ reg |= BIT(11); ++ reg |= (weight & 0xf) << 12; ++ reg |= (max_rate & 0x7f) << 4; ++ reg |= max_exp & 0xf; ++ writel(reg, h->fe_base + QTX_SCH(id)); ++ ++ resv &= 0xff; ++ reg = readl(h->fe_base + QTX_CFG(id)); ++ reg &= 0xffff0000; ++ reg |= (resv << 8) | resv; ++ writel(reg, h->fe_base + QTX_CFG(id)); ++ ++ size = strlen(line); ++ *offset += size; ++ ++ return length; ++} ++ ++static const struct file_operations hnat_queue_fops = { ++ .open = simple_open, ++ .read = hnat_queue_show, ++ .write = hnat_queue_write, ++ .llseek = default_llseek, ++}; ++ ++static void hnat_ac_timer_handle(unsigned long priv) ++{ ++ struct hnat_priv *h = (struct hnat_priv*) priv; ++ int i; ++ ++ for (i = 0; i < HNAT_COUNTER_MAX; i++) { ++ u32 b_hi, b_lo; ++ u64 b; ++ ++ b_lo = readl(h->fe_base + HNAT_AC_BYTE_LO(i)); ++ b_hi = readl(h->fe_base + HNAT_AC_BYTE_HI(i)); ++ b = b_hi; ++ b <<= 32; ++ b += b_lo; ++ h->acct[i].bytes += b; ++ h->acct[i].packets += readl(h->fe_base + HNAT_AC_PACKET(i)); ++ } ++ ++ mod_timer(&h->ac_timer, jiffies + HNAT_AC_TIMER_INTERVAL); ++} ++ ++static ssize_t hnat_counter_show(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct hnat_priv *h = host; ++ int id = (int) file->private_data; ++ char *buf; ++ unsigned int len = 0, buf_len = 1500; ++ ssize_t ret_cnt; ++ int id2 = id + (HNAT_COUNTER_MAX / 2); ++ ++ buf = kzalloc(buf_len, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ len += scnprintf(buf + len, buf_len - len, ++ "tx pkts : %llu\ntx bytes: %llu\nrx pktks : %llu\nrx bytes : %llu\n", ++ h->acct[id].packets, h->acct[id].bytes, ++ h->acct[id2].packets, h->acct[id2].bytes); ++ ++ if (len > buf_len) ++ len = buf_len; ++ ++ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ ++ kfree(buf); ++ return ret_cnt; ++} ++ ++static const struct file_operations hnat_counter_fops = { ++ .open = simple_open, ++ .read = hnat_counter_show, ++ .llseek = default_llseek, ++}; ++ ++#define dump_register(nm) \ ++{ \ ++ .name = __stringify(nm), \ ++ .offset = PPE_ ##nm , \ ++} ++ ++static const struct debugfs_reg32 hnat_regs[] = { ++ dump_register(GLO_CFG), ++ dump_register(FLOW_CFG), ++ dump_register(IP_PROT_CHK), ++ dump_register(IP_PROT_0), ++ dump_register(IP_PROT_1), ++ dump_register(IP_PROT_2), ++ dump_register(IP_PROT_3), ++ dump_register(TB_CFG), ++ dump_register(TB_BASE), ++ dump_register(TB_USED), ++ dump_register(BNDR), ++ dump_register(BIND_LMT_0), ++ dump_register(BIND_LMT_1), ++ dump_register(KA), ++ dump_register(UNB_AGE), ++ dump_register(BND_AGE_0), ++ dump_register(BND_AGE_1), ++ dump_register(HASH_SEED), ++ dump_register(DFT_CPORT), ++ dump_register(MCAST_PPSE), ++ dump_register(MCAST_L_0), ++ dump_register(MCAST_H_0), ++ dump_register(MCAST_L_1), ++ dump_register(MCAST_H_1), ++ dump_register(MCAST_L_2), ++ dump_register(MCAST_H_2), ++ dump_register(MCAST_L_3), ++ dump_register(MCAST_H_3), ++ dump_register(MCAST_L_4), ++ dump_register(MCAST_H_4), ++ dump_register(MCAST_L_5), ++ dump_register(MCAST_H_5), ++ dump_register(MCAST_L_6), ++ dump_register(MCAST_H_6), ++ dump_register(MCAST_L_7), ++ dump_register(MCAST_H_7), ++ dump_register(MCAST_L_8), ++ dump_register(MCAST_H_8), ++ dump_register(MCAST_L_9), ++ dump_register(MCAST_H_9), ++ dump_register(MCAST_L_A), ++ dump_register(MCAST_H_A), ++ dump_register(MCAST_L_B), ++ dump_register(MCAST_H_B), ++ dump_register(MCAST_L_C), ++ dump_register(MCAST_H_C), ++ dump_register(MCAST_L_D), ++ dump_register(MCAST_H_D), ++ dump_register(MCAST_L_E), ++ dump_register(MCAST_H_E), ++ dump_register(MCAST_L_F), ++ dump_register(MCAST_H_F), ++ dump_register(MTU_DRP), ++ dump_register(MTU_VLYR_0), ++ dump_register(MTU_VLYR_1), ++ dump_register(MTU_VLYR_2), ++ dump_register(VPM_TPID), ++ dump_register(VPM_TPID), ++ dump_register(CAH_CTRL), ++ dump_register(CAH_TAG_SRH), ++ dump_register(CAH_LINE_RW), ++ dump_register(CAH_WDATA), ++ dump_register(CAH_RDATA), ++}; ++ ++int hnat_init_debugfs(struct hnat_priv *h) ++{ ++ int ret = 0; ++ struct dentry *root; ++ struct dentry *file; ++ int i; ++ char name[16]; ++ ++ root = debugfs_create_dir("hnat", NULL); ++ if (!root) { ++ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__); ++ ret = -ENOMEM; ++ goto err0; ++ } ++ h->root = root; ++ h->regset = kzalloc(sizeof(*h->regset), GFP_KERNEL); ++ if (!h->regset) { ++ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__); ++ ret = -ENOMEM; ++ goto err1; ++ } ++ h->regset->regs = hnat_regs; ++ h->regset->nregs = ARRAY_SIZE(hnat_regs); ++ h->regset->base = h->ppe_base; ++ ++ file = debugfs_create_regset32("regdump", S_IRUGO, root, h->regset); ++ if (!file) { ++ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__); ++ ret = -ENOMEM; ++ goto err1; ++ } ++ debugfs_create_file("all_entry", S_IRUGO, root, h, &hnat_debug_fops); ++ for (i = 0; i < HNAT_COUNTER_MAX / 2; i++) { ++ snprintf(name, sizeof(name), "counter%d", i); ++ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_counter_fops); ++ } ++ ++ for (i = 0; i < 2; i++) { ++ snprintf(name, sizeof(name), "scheduler%d", i); ++ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_sched_fops); ++ } ++ ++ for (i = 0; i < 16; i++) { ++ snprintf(name, sizeof(name), "queue%d", i); ++ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_queue_fops); ++ } ++ ++ setup_timer(&h->ac_timer, hnat_ac_timer_handle, (unsigned long) h); ++ mod_timer(&h->ac_timer, jiffies + HNAT_AC_TIMER_INTERVAL); ++ ++ return 0; ++ ++ err1: ++ debugfs_remove_recursive(root); ++ err0: ++ return ret; ++} ++ ++void hnat_deinit_debugfs(struct hnat_priv *h) ++{ ++ del_timer(&h->ac_timer); ++ debugfs_remove_recursive(h->root); ++ h->root = NULL; ++} +diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c +new file mode 100644 +index 0000000000000..0ce436ac00e61 +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c +@@ -0,0 +1,312 @@ ++/* This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Copyright (C) 2014-2016 Sean Wang ++ * Copyright (C) 2016-2017 John Crispin ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "nf_hnat_mtk.h" ++#include "hnat.h" ++ ++#include "../mtk_eth_soc.h" ++ ++static unsigned int skb_to_hnat_info(struct sk_buff *skb, ++ const struct net_device *dev, ++ struct foe_entry *foe) ++{ ++ struct foe_entry entry = { 0 }; ++ int lan = IS_LAN(dev); ++ int wan = IS_WAN(dev); ++ struct ethhdr *eth; ++ struct iphdr *iph; ++ struct tcphdr *tcph; ++ struct udphdr *udph; ++ int tcp = 0; ++ int ipv4 = 0; ++ u32 gmac; ++ ++ eth = eth_hdr(skb); ++ switch (ntohs(eth->h_proto)) { ++ case ETH_P_IP: ++ ipv4 = 1; ++ break; ++ ++ default: ++ return -1; ++ } ++ ++ iph = ip_hdr(skb); ++ switch (iph->protocol) { ++ case IPPROTO_TCP: ++ tcph = tcp_hdr(skb); ++ tcp = 1; ++ break; ++ ++ case IPPROTO_UDP: ++ udph = udp_hdr(skb); ++ break; ++ ++ default: ++ return -1; ++ } ++ ++ entry.ipv4_hnapt.etype = htons(ETH_P_IP); ++ ++ if (lan) { ++ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q); ++ entry.bfib1.vlan_layer = 1; ++ ++ /* lan0-port1, lan1-port2, lan2-port3, lan3-port4 */ ++ entry.ipv4_hnapt.vlan1 = BIT((dev->name[3] - '0')+1); ++ } else if (wan) { ++ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q); ++ entry.bfib1.vlan_layer = 1; ++ ++ /* wan port 0 */ ++ entry.ipv4_hnapt.vlan1 = BIT(0); ++ } ++ ++ if (dev->priv_flags & IFF_802_1Q_VLAN) { ++ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); ++ ++ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q); ++ entry.bfib1.vlan_layer = 1; ++ entry.ipv4_hnapt.vlan2 = vlan->vlan_id; ++ } ++ ++ entry.ipv4_hnapt.dmac_hi = swab32(*((u32*) eth->h_dest)); ++ entry.ipv4_hnapt.dmac_lo = swab16(*((u16*) ð->h_dest[4])); ++ entry.ipv4_hnapt.smac_hi = swab32(*((u32*) eth->h_source)); ++ entry.ipv4_hnapt.smac_lo = swab16(*((u16*) ð->h_source[4])); ++ entry.ipv4_hnapt.pppoe_id = 0; ++ entry.bfib1.psn = 0; ++ entry.ipv4_hnapt.bfib1.vpm = 1; ++ ++ if (ipv4) ++ entry.ipv4_hnapt.bfib1.pkt_type = IPV4_HNAPT; ++ ++ entry.ipv4_hnapt.new_sip = ntohl(iph->saddr); ++ entry.ipv4_hnapt.new_dip = ntohl(iph->daddr); ++ entry.ipv4_hnapt.iblk2.dscp = iph->tos; ++#if defined(CONFIG_NET_MEDIATEK_HW_QOS) ++ entry.ipv4_hnapt.iblk2.qid = skb->mark & 0x7; ++ if (lan) ++ entry.ipv4_hnapt.iblk2.qid += 8; ++ entry.ipv4_hnapt.iblk2.fqos = 1; ++#endif ++ if (tcp) { ++ entry.ipv4_hnapt.new_sport = ntohs(tcph->source); ++ entry.ipv4_hnapt.new_dport = ntohs(tcph->dest); ++ entry.ipv4_hnapt.bfib1.udp = 0; ++ } else { ++ entry.ipv4_hnapt.new_sport = ntohs(udph->source); ++ entry.ipv4_hnapt.new_dport = ntohs(udph->dest); ++ entry.ipv4_hnapt.bfib1.udp = 1; ++ } ++ ++ if (IS_LAN(dev)) ++ gmac = NR_GMAC1_PORT; ++ else if (IS_WAN(dev)) ++ gmac = NR_GMAC2_PORT; ++ ++ if (is_multicast_ether_addr(ð->h_dest[0])) ++ entry.ipv4_hnapt.iblk2.mcast = 1; ++ else ++ entry.ipv4_hnapt.iblk2.mcast = 0; ++ ++ entry.ipv4_hnapt.iblk2.dp = gmac; ++ entry.ipv4_hnapt.iblk2.port_mg = 0x3f; ++ entry.ipv4_hnapt.iblk2.port_ag = (skb->mark >> 3) & 0x1f; ++ if (IS_LAN(dev)) ++ entry.ipv4_hnapt.iblk2.port_ag += 32; ++ entry.bfib1.time_stamp = readl((host->fe_base + 0x0010)) & (0xFFFF); ++ entry.ipv4_hnapt.bfib1.ttl = 1; ++ entry.ipv4_hnapt.bfib1.cah = 1; ++ entry.ipv4_hnapt.bfib1.ka = 1; ++ entry.bfib1.state = BIND; ++ ++ entry.ipv4_hnapt.sip = foe->ipv4_hnapt.sip; ++ entry.ipv4_hnapt.dip = foe->ipv4_hnapt.dip; ++ entry.ipv4_hnapt.sport = foe->ipv4_hnapt.sport; ++ entry.ipv4_hnapt.dport = foe->ipv4_hnapt.dport; ++ ++ memcpy(foe, &entry, sizeof(entry)); ++ ++ return 0; ++} ++ ++static unsigned int mtk_hnat_nf_post_routing(struct sk_buff *skb, ++ const struct net_device *out, ++ unsigned int (*fn)(struct sk_buff *, const struct net_device *), ++ const char *func) ++{ ++ struct foe_entry *entry; ++ struct nf_conn *ct; ++ enum ip_conntrack_info ctinfo; ++ const struct nf_conn_help *help; ++ ++#if 0 ++ if ((skb->mark & 0x7) < 4) ++ return 0; ++#endif ++ ++ ct = nf_ct_get(skb, &ctinfo); ++ if (!ct) ++ return 0; ++ ++ /* rcu_read_lock()ed by nf_hook_slow */ ++ help = nfct_help(ct); ++ if (help && rcu_dereference(help->helper)) ++ return 0; ++ ++ if ((FROM_GE_WAN(skb) || FROM_GE_LAN(skb)) && ++ skb_hnat_is_hashed(skb) && ++ (skb_hnat_reason(skb) == HIT_BIND_KEEPALIVE_DUP_OLD_HDR)) ++ return -1; ++ ++ if ((IS_LAN(out) && FROM_GE_WAN(skb)) || ++ (IS_WAN(out) && FROM_GE_LAN(skb))) { ++ if (!skb_hnat_is_hashed(skb)) ++ return 0; ++ ++ entry = &host->foe_table_cpu[skb_hnat_entry(skb)]; ++ if (entry_hnat_is_bound(entry)) ++ return 0; ++ ++ if (skb_hnat_reason(skb) == HIT_UNBIND_RATE_REACH && ++ skb_hnat_alg(skb) == 0) { ++ if (fn && fn(skb, out)) ++ return 0; ++ skb_to_hnat_info(skb, out, entry); ++ } ++ } ++ ++ return 0; ++} ++ ++static unsigned int mtk_hnat_nf_pre_routing(void *priv, ++ struct sk_buff *skb, ++ const struct nf_hook_state *state) ++{ ++ if (IS_WAN(state->in)) ++ HNAT_SKB_CB(skb)->iif = FOE_MAGIC_GE_WAN; ++ else if (IS_LAN(state->in)) ++ HNAT_SKB_CB(skb)->iif = FOE_MAGIC_GE_LAN; ++ else if (!IS_BR(state->in)) ++ HNAT_SKB_CB(skb)->iif = FOE_INVALID; ++ ++ return NF_ACCEPT; ++} ++ ++static unsigned int hnat_get_nexthop(struct sk_buff *skb, const struct net_device *out) { ++ ++ u32 nexthop; ++ struct neighbour *neigh; ++ struct dst_entry *dst = skb_dst(skb); ++ struct rtable *rt = (struct rtable *)dst; ++ struct net_device *dev = (__force struct net_device *)out; ++ ++ rcu_read_lock_bh(); ++ nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr); ++ neigh = __ipv4_neigh_lookup_noref(dev, nexthop); ++ if (unlikely(!neigh)) { ++ dev_err(host->dev, "%s:++ no neigh\n", __func__); ++ return -1; ++ } ++ ++ /* why do we get all zero ethernet address ? */ ++ if (!is_valid_ether_addr(neigh->ha)){ ++ rcu_read_unlock_bh(); ++ return -1; ++ } ++ ++ memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN); ++ memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN); ++ ++ rcu_read_unlock_bh(); ++ ++ return 0; ++} ++ ++static unsigned int mtk_hnat_ipv4_nf_post_routing(void *priv, ++ struct sk_buff *skb, ++ const struct nf_hook_state *state) ++{ ++ if (!mtk_hnat_nf_post_routing(skb, state->out, hnat_get_nexthop, __func__)) ++ return NF_ACCEPT; ++ ++ return NF_DROP; ++} ++ ++static unsigned int mtk_hnat_br_nf_post_routing(void *priv, ++ struct sk_buff *skb, ++ const struct nf_hook_state *state) ++{ ++ if (!mtk_hnat_nf_post_routing(skb, state->out , 0, __func__)) ++ return NF_ACCEPT; ++ ++ return NF_DROP; ++} ++ ++static struct nf_hook_ops mtk_hnat_nf_ops[] __read_mostly = { ++ { ++ .hook = mtk_hnat_nf_pre_routing, ++ .pf = NFPROTO_IPV4, ++ .hooknum = NF_INET_PRE_ROUTING, ++ .priority = NF_IP_PRI_FIRST, ++ }, { ++ .hook = mtk_hnat_ipv4_nf_post_routing, ++ .pf = NFPROTO_IPV4, ++ .hooknum = NF_INET_POST_ROUTING, ++ .priority = NF_IP_PRI_LAST, ++ }, { ++ .hook = mtk_hnat_nf_pre_routing, ++ .pf = NFPROTO_BRIDGE, ++ .hooknum = NF_BR_PRE_ROUTING, ++ .priority = NF_BR_PRI_FIRST, ++ }, { ++ .hook = mtk_hnat_br_nf_post_routing, ++ .pf = NFPROTO_BRIDGE, ++ .hooknum = NF_BR_POST_ROUTING, ++ .priority = NF_BR_PRI_LAST - 1, ++ }, ++}; ++ ++/* ++int hnat_register_nf_hooks(void) ++{ ++ return nf_register_hooks(mtk_hnat_nf_ops, ++ ARRAY_SIZE(mtk_hnat_nf_ops)); ++} ++ ++void hnat_unregister_nf_hooks(void) ++{ ++ nf_unregister_hooks(mtk_hnat_nf_ops, ++ ARRAY_SIZE(mtk_hnat_nf_ops)); ++} ++*/ ++int hnat_register_nf_hooks(struct net *net) ++{ ++ return nf_register_net_hooks(net,mtk_hnat_nf_ops, ++ ARRAY_SIZE(mtk_hnat_nf_ops)); ++} ++ ++void hnat_unregister_nf_hooks(struct net *net) ++{ ++ nf_unregister_net_hooks(net,mtk_hnat_nf_ops, ++ ARRAY_SIZE(mtk_hnat_nf_ops)); ++} +diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h +new file mode 100644 +index 0000000000000..e19812840a840 +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h +@@ -0,0 +1,44 @@ ++/* This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Copyright (C) 2014-2016 Sean Wang ++ * Copyright (C) 2016-2017 John Crispin ++ */ ++ ++#ifndef NF_HNAT_MTK_H ++#define NF_HNAT_MTK_H ++ ++#include ++#include ++ ++#define HNAT_SKB_CB2(__skb) ((struct hnat_skb_cb2 *)&((__skb)->cb[44])) ++struct hnat_skb_cb2 { ++ __u32 magic; ++}; ++ ++struct hnat_desc { ++ u32 entry:14; ++ u32 crsn:5; ++ u32 sport:4; ++ u32 alg:9; ++} __attribute__ ((packed)); ++ ++#define skb_hnat_magic(skb) (((struct hnat_desc *)(skb->head))->magic) ++#define skb_hnat_reason(skb) (((struct hnat_desc *)(skb->head))->crsn) ++#define skb_hnat_entry(skb) (((struct hnat_desc *)(skb->head))->entry) ++#define skb_hnat_sport(skb) (((struct hnat_desc *)(skb->head))->sport) ++#define skb_hnat_alg(skb) (((struct hnat_desc *)(skb->head))->alg) ++ ++u32 hnat_tx(struct sk_buff *skb); ++u32 hnat_set_skb_info(struct sk_buff *skb, u32 *rxd); ++u32 hnat_reg(struct net_device *, void __iomem *); ++u32 hnat_unreg(void); ++ ++#endif ++ +diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c +index 8febdd48b9f16..9bcc787f8abf3 100644 +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -20,6 +21,7 @@ + #include + #include + ++#include + #include + + #include +@@ -51,6 +53,11 @@ static int nf_ct_tcp_max_retrans __read_mostly = 3; + /* FIXME: Examine ipfilter's timeouts and conntrack transitions more + closely. They're more complex. --RR */ + ++#ifndef IPV4_DEVCONF_DFLT ++ #define IPV4_DEVCONF_DFLT(net, attr) \ ++ IPV4_DEVCONF((*net->ipv4.devconf_dflt), attr) ++#endif ++ + static const char *const tcp_conntrack_names[] = { + "NONE", + "SYN_SENT", +@@ -506,6 +513,18 @@ static bool tcp_in_window(const struct nf_conn *ct, + s32 receiver_offset; + bool res, in_recv_win; + ++ if (net) { ++ if ((net->ipv4.devconf_all && net->ipv4.devconf_dflt && net->ipv6.devconf_all) && ++ net->ipv6.devconf_dflt) { ++ if ((IPV4_DEVCONF_DFLT(net, FORWARDING) || ++ IPV4_DEVCONF_ALL(net, FORWARDING)) || ++ (net->ipv6.devconf_all->forwarding || ++ net->ipv6.devconf_dflt->forwarding)) { ++ return true; ++ } ++ } ++ } ++ + /* + * Get the required data from the packet. + */ diff --git a/root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch b/root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch new file mode 100755 index 00000000..467141c7 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch @@ -0,0 +1,747 @@ +From 8196b5b6d823fb8c61268121052826db7fb6ce3c Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 22 Oct 2018 19:06:10 +0200 +Subject: [PATCH 01/77] adding defconfig and build-script, change gitignore, + making kernel compatible with r2-images + +--- + arch/arm/boot/dts/mt7623.dtsi | 42 +- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 651 +++++++++++++++++++++ + 4 files changed, 1200 insertions(+), 22 deletions(-) + create mode 100644 arch/arm/configs/mt7623n_evb_fwu_defconfig + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 1cdc346a05e8..04228cf9ddbb 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -354,6 +354,17 @@ + #io-channel-cells = <1>; + }; + ++ uart2: serial@11004000 { ++ compatible = "mediatek,mt7623-uart", ++ "mediatek,mt6577-uart"; ++ reg = <0 0x11004000 0 0x400>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_UART2_SEL>, ++ <&pericfg CLK_PERI_UART2>; ++ clock-names = "baud", "bus"; ++ status = "disabled"; ++ }; ++ + uart0: serial@11002000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; +@@ -376,17 +387,6 @@ + status = "disabled"; + }; + +- uart2: serial@11004000 { +- compatible = "mediatek,mt7623-uart", +- "mediatek,mt6577-uart"; +- reg = <0 0x11004000 0 0x400>; +- interrupts = ; +- clocks = <&pericfg CLK_PERI_UART2_SEL>, +- <&pericfg CLK_PERI_UART2>; +- clock-names = "baud", "bus"; +- status = "disabled"; +- }; +- + uart3: serial@11005000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; +@@ -661,24 +661,24 @@ + }; + }; + +- mmc0: mmc@11230000 { ++ mmc1: mmc@11240000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt2701-mmc"; +- reg = <0 0x11230000 0 0x1000>; +- interrupts = ; +- clocks = <&pericfg CLK_PERI_MSDC30_0>, +- <&topckgen CLK_TOP_MSDC30_0_SEL>; ++ reg = <0 0x11240000 0 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_MSDC30_1>, ++ <&topckgen CLK_TOP_MSDC30_1_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; + +- mmc1: mmc@11240000 { ++ mmc0: mmc@11230000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt2701-mmc"; +- reg = <0 0x11240000 0 0x1000>; +- interrupts = ; +- clocks = <&pericfg CLK_PERI_MSDC30_1>, +- <&topckgen CLK_TOP_MSDC30_1_SEL>; ++ reg = <0 0x11230000 0 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_MSDC30_0>, ++ <&topckgen CLK_TOP_MSDC30_0_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +new file mode 100644 +index 000000000000..09df75013c09 +--- /dev/null ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -0,0 +1,651 @@ ++CONFIG_LOCALVERSION="-bpi-r2" ++CONFIG_LOCALVERSION_AUTO=n ++ ++#spectre/meltdown ++CONFIG_PAGE_TABLE_ISOLATION=y ++ ++CONFIG_SYSVIPC=y ++CONFIG_IRQ_DOMAIN_DEBUG=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_CGROUPS=y ++CONFIG_NAMESPACES=y ++ ++#for lxc ++CONFIG_USER_NS=y ++CONFIG_MEMCG=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_CPUSETS=y ++#some options for docker ++CONFIG_CGROUP_FREEZER=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_OVERLAY_FS=y ++CONFIG_MEMCG_SWAP=y ++CONFIG_MEMCG_SWAP_ENABLED=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CFS_BANDWIDTH=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_PERF=y ++CONFIG_CGROUP_NET_CLASSID=y ++CONFIG_CGROUP_NET_PRIO=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++ ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_KALLSYMS_ALL=y ++CONFIG_EMBEDDED=y ++CONFIG_PERF_EVENTS=y ++CONFIG_MODULES=y ++CONFIG_MODULE_FORCE_LOAD=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_CMDLINE_PARTITION=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_ARM_THUMB=y ++CONFIG_ARM_THUMBEE=y ++CONFIG_ARM_ERRATA_720789=y ++CONFIG_ARM_ERRATA_754322=y ++CONFIG_ARM_ERRATA_754327=y ++CONFIG_ARM_ERRATA_764369=y ++CONFIG_ARM_ERRATA_775420=y ++CONFIG_ARM_ERRATA_798181=y ++ ++CONFIG_PL310_ERRATA_588369=y ++CONFIG_PL310_ERRATA_727915=y ++CONFIG_PL310_ERRATA_753970=y ++CONFIG_PL310_ERRATA_769419=y ++ ++CONFIG_PCI=y ++CONFIG_SMP=y ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_NR_CPUS=16 ++CONFIG_AEABI=y ++CONFIG_HIGHMEM=y ++CONFIG_CMA=y ++CONFIG_FORCE_MAX_ZONEORDER=12 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 vmalloc=496M debug=7 no_console_suspend" ++#CONFIG_CMDLINE_FORCE=y ++ ++CONFIG_IKCONFIG=m ++CONFIG_IKCONFIG_PROC=y ++ ++CONFIG_KEXEC=y ++ ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_ARM_MEDIATEK_CPUFREQ=y ++ ++CONFIG_VFP=y ++CONFIG_NEON=y ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_PM_AUTOSLEEP=y ++CONFIG_PM_DEBUG=y ++CONFIG_PM_ADVANCED_DEBUG=y ++CONFIG_APM_EMULATION=y ++ ++CONFIG_NET=y ++CONFIG_DUMMY=m ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_OPTIMISTIC_DAD=y ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_MIP6=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_BRIDGE=y ++CONFIG_NET_DSA=y ++CONFIG_VLAN_8021Q=y ++CONFIG_NETLINK_DIAG=y ++CONFIG_INET_UDP_DIAG=m ++CONFIG_NET_IPIP=m ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_MROUTE=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++ ++#added for lxc ++CONFIG_UNIX_DIAG=m ++CONFIG_PACKET_DIAG=m ++ ++ ++CONFIG_IPV6=m ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_NETFILTER_NETLINK=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV4=m ++CONFIG_NF_REJECT_IPV4=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_NF_LOG_IPV6=m ++CONFIG_NF_REJECT_IPV6=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_NF_NAT_MASQUERADE_IPV4=m ++CONFIG_NF_NAT_MASQUERADE_IPV6=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MATCH_RT=m ++ ++CONFIG_NETFILTER_SYNPROXY=m ++CONFIG_IP_NF_TARGET_SYNPROXY=m ++CONFIG_IP6_NF_TARGET_SYNPROXY=m ++ ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MARK=m ++CONFIG_NETFILTER_XT_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_IP_VS=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++ ++CONFIG_NET_MEDIATEK_HNAT=m ++CONFIG_DEBUG_SECTION_MISMATCH=y ++ ++#active ftp-support ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_NAT_FTP=m ++ ++ ++CONFIG_SYN_COOKIES=y ++ ++CONFIG_PPP=m ++CONFIG_PPPOE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_MPPE=m ++ ++#veth for lxc ++CONFIG_VETH=m ++ ++#for systemd ++CONFIG_AF_KCM=y ++CONFIG_CGROUP_BPF=y ++ ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=64 ++CONFIG_ARM_CCI400_PMU=y ++CONFIG_MTD=y ++CONFIG_OF_OVERLAY=y ++CONFIG_CONFIGFS_FS=m ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_SRAM=y ++CONFIG_EEPROM_93CX6=y ++CONFIG_IDE=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_ATA=y ++CONFIG_SATA_AHCI=y ++CONFIG_AHCI_MTK=m ++ ++CONFIG_NETDEVICES=y ++CONFIG_NET_DSA_MT7530=y ++CONFIG_NET_VENDOR_MEDIATEK=y ++CONFIG_NET_MEDIATEK_SOC=y ++ ++CONFIG_ICPLUS_PHY=y ++CONFIG_INPUT_EVDEV=y ++CONFIG_INPUT_EVBUG=m ++CONFIG_KEYBOARD_MATRIX=y ++CONFIG_KEYBOARD_SAMSUNG=y ++CONFIG_KEYBOARD_MTK_PMIC=m ++CONFIG_MOUSE_PS2_ELANTECH=y ++CONFIG_MOUSE_PS2_SENTELIC=y ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++CONFIG_INPUT_TOUCHSCREEN=y ++# CONFIG_SERIO_SERPORT is not set ++CONFIG_VT_HW_CONSOLE_BINDING=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=4 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=4 ++CONFIG_SERIAL_8250_MT6577=y ++CONFIG_SERIAL_8250_BTIF=y ++CONFIG_HW_RANDOM=y ++CONFIG_I2C=y ++CONFIG_I2C_MT65XX=y ++CONFIG_PINCTRL_MT2701=y ++# CONFIG_PINCTRL_MT6397 is not set ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_MEDIATEK_WATCHDOG=y ++CONFIG_MFD_MT6397=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_MT6323=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_MEDIA_SUPPORT=y ++CONFIG_MEDIA_RC_SUPPORT=y ++CONFIG_RC_DEVICES=y ++CONFIG_IR_MTK=y ++CONFIG_MMC=y ++CONFIG_MMC_MTK=y ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_MT6323=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA963X=y ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_DMADEVICES=y ++CONFIG_DMATEST=m ++CONFIG_COMMON_CLK_MT2701_HIFSYS=y ++CONFIG_COMMON_CLK_MT2701_ETHSYS=y ++CONFIG_ARM_TIMER_SP804=y ++CONFIG_MTK_IOMMU_V1=y ++CONFIG_MTK_PMIC_WRAP=y ++CONFIG_IIO=y ++CONFIG_RESET_CONTROLLER=y ++CONFIG_PHY_MT65XX_USB3=y ++CONFIG_PSTORE=y ++CONFIG_PSTORE_CONSOLE=y ++CONFIG_PSTORE_PMSG=y ++CONFIG_PSTORE_FTRACE=y ++CONFIG_PSTORE_RAM=y ++CONFIG_PRINTK_TIME=y ++CONFIG_DYNAMIC_DEBUG=y ++CONFIG_DEBUG_INFO=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_DEBUG_LIST=y ++CONFIG_FUNCTION_TRACER=y ++CONFIG_FTRACE_SYSCALLS=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_DEBUG_LL=y ++CONFIG_DEBUG_UART_PHYS=0x11002000 ++CONFIG_DEBUG_UART_VIRT=0xf1002000 ++CONFIG_KEYS=y ++CONFIG_CRYPTO_RSA=y ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++CONFIG_CRYPTO_ECB=m ++CONFIG_CRYPTO_CMAC=m ++CONFIG_CRYPTO_ARC4=m ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++CONFIG_CRC_CCITT=m ++CONFIG_CRC_ITU_T=m ++CONFIG_CRYPTO_DEV_MEDIATEK=y ++ ++#ARM Accelerated Cryptographic Algorithms ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_SHA1_ARM_NEON=m ++CONFIG_CRYPTO_SHA1_ARM_CE=m ++CONFIG_CRYPTO_SHA2_ARM_CE=m ++CONFIG_CRYPTO_SHA512_ARM=m ++CONFIG_CRYPTO_AES_ARM=m ++CONFIG_CRYPTO_AES_ARM_BS=m ++CONFIG_CRYPTO_AES_ARM_CE=m ++CONFIG_CRYPTO_GHASH_ARM_CE=m ++CONFIG_CRYPTO_CRC32_ARM_CE=m ++CONFIG_CRYPTO_CHACHA20_NEON=m ++ ++#LVM ++CONFIG_MD=y ++CONFIG_BLK_DEV_DM=y ++CONFIG_DM_BUFIO=y ++CONFIG_DM_CRYPT=y ++CONFIG_DM_SNAPSHOT=y ++CONFIG_DM_MIRROR=y ++CONFIG_DM_MULTIPATH=y ++CONFIG_DM_MULTIPATH_QL=y ++CONFIG_DM_MULTIPATH_ST=y ++CONFIG_DM_THIN_PROVISIONING=m ++CONFIG_DAX=y ++CONFIG_CRYPTO_CBC=y ++ ++#RAID ++CONFIG_DM_RAID=y ++CONFIG_MD_RAID0=y ++CONFIG_MD_RAID1=y ++CONFIG_MD_RAID10=y ++CONFIG_MD_RAID456=y ++ ++#RamFS ++#CONFIG_INITRAMFS_SOURCE="../rootfs_ttys0_rng.cpio.gz" ++#CONFIG_INITRAMFS_SOURCE="../initramfs.cpio" ++#CONFIG_INITRAMFS_FORCE=y ++ ++#Filesystem ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_MSDOS_FS=m ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_UTF8=y ++CONFIG_CIFS=m ++CONFIG_F2FS_FS=m ++CONFIG_BTRFS_FS=m ++ ++#GPIO ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_GPIO=y ++CONFIG_GPIO_SYSFS=y ++ ++#wlan ++CONFIG_MAC80211=y ++CONFIG_CFG80211=y ++ ++#internal wlan (not working yet) ++# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set ++#CONFIG_MTK_COMBO=y ++#CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y ++#used in 4.4, but should be set in Kconfig by selecting mt7623 COMBO ++#CONFIG_MTK_PLATFORM="mt7623" ++ ++#CONFIG_MTK_COMBO_COMM=y ++#CONFIG_MTK_COMBO_WIFI=y ++#CONFIG_NL80211_TESTMODE=y ++ ++#internal Bluetooth (also not working yet) ++#CONFIG_BT=y ++#CONFIG_MTK_COMBO_BT=y ++#CONFIG_MTK_COMBO_BT_HCI=y ++#needed for BT? ++#Bluetooth Classic (BR/EDR) features ++CONFIG_BT_BREDR=y ++#Bluetooth High Speed (HS) features ++CONFIG_BT_HS=y ++#Bluetooth Low Energy (LE) features ++CONFIG_BT_LE=y ++#Export Bluetooth internals in debugfs ++CONFIG_BT_DEBUGFS=y ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_BNEP=m ++ ++#to run bluetoothd rfkill needed ++CONFIG_RFKILL=y ++CONFIG_RFKILL_LEDS=y ++CONFIG_RFKILL_INPUT=y ++CONFIG_RFKILL_GPIO=y ++ ++#if you use a mt76x2 or mt76x3 pcie-card ++#CONFIG_MT76=m ++ ++#pcie ++CONFIG_PCIEPORTBUS=y ++CONFIG_PCIE_MEDIATEK=y ++CONFIG_PHY_MTK_TPHY=y ++ ++CONFIG_I2C_CHARDEV=m ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1307_CENTURY=y ++CONFIG_RTC_DRV_MT6397=m ++ ++CONFIG_SPI=y ++CONFIG_SPI_MASTER=y ++CONFIG_SPI_SPIDEV=m ++CONFIG_SPI_MT65XX=m ++ ++CONFIG_PWM=y ++CONFIG_PWM_MEDIATEK=m ++ ++#Temperature sensor driver for mediatek SoCs ++CONFIG_MEDIATEK_MT6577_AUXADC=m ++CONFIG_THERMAL=m ++CONFIG_MTK_THERMAL=m ++CONFIG_MTK_EFUSE=m ++ ++#HDMI ++#CONFIG_DRM=y ++#CONFIG_DRM_ARM=y ++#CONFIG_DRM_MALI_DISPLAY=y ++#CONFIG_DRM_MEDIATEK=y ++#CONFIG_DRM_MEDIATEK_HDMI=y ++#CONFIG_COMMON_CLK_MT2701_MMSYS=y ++#CONFIG_COMMON_CLK_MT2701_IMGSYS=y ++#CONFIG_COMMON_CLK_MT2701_VDECSYS=y ++#CONFIG_FRAMEBUFFER_CONSOLE=y ++#CONFIG_DRM_FBDEV_EMULATION=y ++ ++#Sound ++CONFIG_SOUND=y ++CONFIG_SND=y #alsa core ++CONFIG_SND_SOC=y ++ ++#CONFIG_SOUND_OSS_CORE=y ++#CONFIG_SOUND_OSS_CORE_PRECLAIM=y ++#CONFIG_SND_OSSEMUL=y ++#CONFIG_SND_MIXER_OSS=m ++#CONFIG_SND_PCM_OSS=m #alsa The PCM OSS emulation module. ++ ++#USB/HID ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MTK=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_SERIAL=y ++#CONFIG_NOP_USB_XCEIV=y ++#CONFIG_USB_GPIO_VBUS=y ++#CONFIG_USB_GADGET=y ++#CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_SERIAL=y ++#CONFIG_USB_CONFIGFS_ACM=y ++#CONFIG_USB_CONFIGFS_OBEX=y ++#CONFIG_USB_CONFIGFS_NCM=y ++#CONFIG_USB_CONFIGFS_ECM=y ++#CONFIG_USB_CONFIGFS_ECM_SUBSET=y ++#CONFIG_USB_CONFIGFS_RNDIS=y ++#CONFIG_USB_CONFIGFS_EEM=y ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++ ++CONFIG_HID=y ++CONFIG_HIDRAW=y ++#CONFIG_UHID=m ++CONFIG_HID_GENERIC=y ++ ++CONFIG_USB_HID=y ++#CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++ ++# CONFIG_USB_OHCI_LITTLE_ENDIAN=y ? ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++# CONFIG_USB_ARCH_HAS_HCD=y ? ++ ++#additional NET (e.g. tunneling incl. openvpn,vlan-base-support) ++CONFIG_TUN=m ++#vlan ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_VLAN_8021Q_MVRP=y ++CONFIG_NET_L3_MASTER_DEV=y ++CONFIG_IPVLAN=m ++CONFIG_MACVLAN=m ++CONFIG_NET_ACT_VLAN=m ++CONFIG_NET_CLS_ACT=y ++ ++# QoS and/or fair queueing ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_CSZ=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_QOS=y ++CONFIG_NET_ESTIMATOR=y ++CONFIG_NET_CLS=y ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_ROUTE=y ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_POLICE=y ++ ++#unused drivers which are set by default ++CONFIG_WLAN_VENDOR_ADMTEK=n ++CONFIG_WLAN_VENDOR_ATH=n ++CONFIG_WLAN_VENDOR_ATMEL=n ++CONFIG_WLAN_VENDOR_BROADCOM=n ++CONFIG_WLAN_VENDOR_CISCO=n ++CONFIG_WLAN_VENDOR_INTEL=n ++CONFIG_WLAN_VENDOR_INTERSIL=n ++CONFIG_WLAN_VENDOR_MARVELL=n ++CONFIG_WLAN_VENDOR_REALTEK=n ++CONFIG_WLAN_VENDOR_RALINK=n ++CONFIG_WLAN_VENDOR_RSI=n ++CONFIG_WLAN_VENDOR_ST=n ++CONFIG_WLAN_VENDOR_TI=n ++CONFIG_WLAN_VENDOR_ZYDAS=n ++CONFIG_WLAN_VENDOR_QUANTENNA=n ++# CONFIG_ADAPTEC_STARFIRE is not set ++# CONFIG_NET_VENDOR_ADAPTEC is not set ++# CONFIG_NET_VENDOR_AGERE is not set ++# CONFIG_NET_VENDOR_ALACRITECH is not set ++# CONFIG_NET_VENDOR_ALTEON is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_AMD is not set ++# CONFIG_NET_VENDOR_AQUANTIA is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_ATHEROS is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_BROCADE is not set ++# CONFIG_NET_VENDOR_CAVIUM is not set ++# CONFIG_NET_VENDOR_CHELSIO is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_NET_VENDOR_CISCO is not set ++# CONFIG_NET_VENDOR_MELLANOX is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++# CONFIG_NET_VENDOR_MYRI is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_NET_VENDOR_NVIDIA is not set ++# CONFIG_NET_VENDOR_OKI is not set ++# CONFIG_NET_PACKET_ENGINE is not set ++# CONFIG_NET_VENDOR_QLOGIC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_REALTEK is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_RDC is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SILAN is not set ++# CONFIG_NET_VENDOR_SIS is not set ++# CONFIG_NET_VENDOR_SOLARFLARE is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SUN is not set ++# CONFIG_NET_VENDOR_TEHUTI is not set ++# CONFIG_NET_VENDOR_TI is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_DEC is not set ++# CONFIG_NET_VENDOR_DLINK is not set ++# CONFIG_NET_VENDOR_EMULEX is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_EXAR is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++# CONFIG_NET_VENDOR_HP is not set ++# CONFIG_NET_VENDOR_HUAWEI is not set ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_3COM is not set ++ ++#NFS Client ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_V4_2=y ++CONFIG_PNFS_FILE_LAYOUT=m ++CONFIG_PNFS_BLOCK=m ++CONFIG_PNFS_FLEXFILE_LAYOUT=m ++CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" ++CONFIG_NFS_V4_1_MIGRATION=y ++CONFIG_NFS_USE_LEGACY_DNS=y ++ ++#NFS Server ++CONFIG_NFSD=m ++CONFIG_NFSD_V2_ACL=y ++CONFIG_NFSD_V3=y ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_NFSD_PNFS=y ++CONFIG_NFSD_BLOCKLAYOUT=y ++CONFIG_NFSD_SCSILAYOUT=y ++CONFIG_NFSD_FLEXFILELAYOUT=y ++CONFIG_NFSD_FAULT_INJECTION=y ++CONFIG_NFS_ACL_SUPPORT=m ++CONFIG_NFS_COMMON=y ++ ++CONFIG_ROOT_NFS=y ++ ++#xfs ++CONFIG_XFS_FS=m ++ ++#RTC/POWER ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_MT6323=y ++CONFIG_POWER_RESET_MT6397_RTC=y ++ ++#CONFIG_NET_MEDIATEK_HW_QOS=m ++ +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch b/root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch new file mode 100755 index 00000000..a9380314 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch @@ -0,0 +1,216265 @@ +From ce8c582c6121469db64197b1b4aa4e4c377c660f Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 23 Oct 2018 13:12:12 +0200 +Subject: [PATCH 06/77] [wifi] adding driver-folder + +--- + drivers/misc/Kconfig | 1 + + drivers/misc/Makefile | 1 + + drivers/misc/mediatek/Kconfig | 11 + + drivers/misc/mediatek/Makefile | 19 + + drivers/misc/mediatek/btif/Kconfig | 4 + + drivers/misc/mediatek/btif/Makefile | 33 + + drivers/misc/mediatek/btif/common/Makefile | 31 + + .../misc/mediatek/btif/common/btif_dma_plat.c | 1436 ++ + drivers/misc/mediatek/btif/common/btif_plat.c | 1396 ++ + .../misc/mediatek/btif/common/inc/mtk_btif.h | 370 + + .../mediatek/btif/common/inc/mtk_btif_exp.h | 280 + + drivers/misc/mediatek/btif/common/mtk_btif.c | 3472 +++++ + .../misc/mediatek/btif/common/mtk_btif_exp.c | 786 ++ + .../btif/common/plat_inc/btif_dma_priv.h | 164 + + .../btif/common/plat_inc/btif_dma_pub.h | 197 + + .../mediatek/btif/common/plat_inc/btif_priv.h | 105 + + .../mediatek/btif/common/plat_inc/btif_pub.h | 237 + + .../btif/common/plat_inc/plat_common.h | 307 + + drivers/misc/mediatek/connectivity/Kconfig | 299 + + drivers/misc/mediatek/connectivity/Makefile | 41 + + .../mediatek/connectivity/common/Makefile | 23 + + .../common/common_detect/Makefile | 47 + + .../common/common_detect/drv_init/Makefile | 22 + + .../common_detect/drv_init/ant_drv_init.c | 38 + + .../drv_init/bluetooth_drv_init.c | 35 + + .../common_detect/drv_init/common_drv_init.c | 103 + + .../common_detect/drv_init/conn_drv_init.c | 80 + + .../common_detect/drv_init/fm_drv_init.c | 33 + + .../common_detect/drv_init/gps_drv_init.c | 35 + + .../common_detect/drv_init/inc/ant_drv_init.h | 20 + + .../drv_init/inc/bluetooth_drv_init.h | 20 + + .../drv_init/inc/common_drv_init.h | 31 + + .../drv_init/inc/conn_drv_init.h | 18 + + .../common_detect/drv_init/inc/fm_drv_init.h | 20 + + .../common_detect/drv_init/inc/gps_drv_init.h | 19 + + .../drv_init/inc/wlan_drv_init.h | 30 + + .../common_detect/drv_init/wlan_drv_init.c | 74 + + .../common/common_detect/mtk_wcn_stub_alps.c | 605 + + .../common/common_detect/sdio_detect.c | 269 + + .../common/common_detect/sdio_detect.h | 43 + + .../common/common_detect/wmt_detect.c | 380 + + .../common/common_detect/wmt_detect.h | 114 + + .../common/common_detect/wmt_detect_pwr.c | 232 + + .../common/common_detect/wmt_detect_pwr.h | 29 + + .../common/common_detect/wmt_gpio.c | 371 + + .../common/common_detect/wmt_gpio.h | 103 + + .../common/common_detect/wmt_stp_exp.c | 480 + + .../common/common_detect/wmt_stp_exp.h | 610 + + .../connectivity/common/conn_soc/Makefile | 65 + + .../common/conn_soc/core/Makefile | 22 + + .../common/conn_soc/core/btm_core.c | 1376 ++ + .../common/conn_soc/core/dbg_core.c | 13 + + .../common/conn_soc/core/include/btm_core.h | 133 + + .../common/conn_soc/core/include/dbg_core.h | 69 + + .../common/conn_soc/core/include/psm_core.h | 251 + + .../common/conn_soc/core/include/stp_core.h | 629 + + .../common/conn_soc/core/include/stp_wmt.h | 89 + + .../common/conn_soc/core/include/wmt_conf.h | 74 + + .../common/conn_soc/core/include/wmt_core.h | 428 + + .../common/conn_soc/core/include/wmt_ctrl.h | 120 + + .../common/conn_soc/core/include/wmt_func.h | 140 + + .../common/conn_soc/core/include/wmt_ic.h | 122 + + .../common/conn_soc/core/include/wmt_lib.h | 300 + + .../common/conn_soc/core/psm_core.c | 1890 +++ + .../common/conn_soc/core/stp_core.c | 3358 +++++ + .../common/conn_soc/core/wmt_conf.c | 529 + + .../common/conn_soc/core/wmt_core.c | 2521 ++++ + .../common/conn_soc/core/wmt_ctrl.c | 1019 ++ + .../common/conn_soc/core/wmt_func.c | 713 + + .../common/conn_soc/core/wmt_ic_soc.c | 2452 ++++ + .../common/conn_soc/core/wmt_lib.c | 1938 +++ + .../common/conn_soc/include/stp_exp.h | 252 + + .../common/conn_soc/include/wmt.h | 19 + + .../common/conn_soc/include/wmt_exp.h | 329 + + .../common/conn_soc/include/wmt_plat.h | 295 + + .../common/conn_soc/linux/Makefile | 6 + + .../conn_soc/linux/include/bgw_desense.h | 74 + + .../common/conn_soc/linux/include/osal.h | 349 + + .../conn_soc/linux/include/osal_typedef.h | 90 + + .../common/conn_soc/linux/include/wmt_idc.h | 97 + + .../common/conn_soc/linux/pri/Makefile | 21 + + .../conn_soc/linux/pri/include/stp_btif.h | 31 + + .../conn_soc/linux/pri/include/stp_dbg.h | 316 + + .../conn_soc/linux/pri/include/wmt_dev.h | 71 + + .../common/conn_soc/linux/pri/stp_btif.c | 279 + + .../common/conn_soc/linux/pri/stp_dbg.c | 2061 +++ + .../common/conn_soc/linux/pri/stp_exp.c | 279 + + .../common/conn_soc/linux/pri/wmt_dev.c | 2566 ++++ + .../common/conn_soc/linux/pri/wmt_exp.c | 610 + + .../common/conn_soc/linux/pub/Makefile | 27 + + .../common/conn_soc/linux/pub/bgw_desense.c | 153 + + .../common/conn_soc/linux/pub/osal.c | 1211 ++ + .../common/conn_soc/linux/pub/stp_chrdev_bt.c | 899 ++ + .../conn_soc/linux/pub/wmt_chrdev_wifi.c | 668 + + .../common/conn_soc/linux/pub/wmt_idc.c | 307 + + .../common/conn_soc/mt7623/Makefile | 25 + + .../mt7623/include/mtk_wcn_consys_hw.h | 287 + + .../conn_soc/mt7623/mtk_wcn_consys_hw.c | 738 ++ + .../common/conn_soc/mt7623/wmt_plat_alps.c | 1071 ++ + .../misc/mediatek/connectivity/wlan/Makefile | 8 + + .../mediatek/connectivity/wlan/gen2/Makefile | 237 + + .../connectivity/wlan/gen2/common/debug.c | 165 + + .../connectivity/wlan/gen2/common/dump.c | 345 + + .../connectivity/wlan/gen2/common/wlan_bow.c | 3442 +++++ + .../connectivity/wlan/gen2/common/wlan_lib.c | 6240 +++++++++ + .../connectivity/wlan/gen2/common/wlan_oid.c | 11050 ++++++++++++++++ + .../connectivity/wlan/gen2/common/wlan_p2p.c | 1654 +++ + .../wlan/gen2/include/CFG_Wifi_File.h | 238 + + .../connectivity/wlan/gen2/include/config.h | 1628 +++ + .../connectivity/wlan/gen2/include/debug.h | 466 + + .../connectivity/wlan/gen2/include/link.h | 368 + + .../wlan/gen2/include/mgmt/aa_fsm.h | 188 + + .../wlan/gen2/include/mgmt/ais_fsm.h | 573 + + .../wlan/gen2/include/mgmt/assoc.h | 112 + + .../wlan/gen2/include/mgmt/auth.h | 125 + + .../wlan/gen2/include/mgmt/bow_fsm.h | 184 + + .../connectivity/wlan/gen2/include/mgmt/bss.h | 265 + + .../connectivity/wlan/gen2/include/mgmt/cnm.h | 258 + + .../wlan/gen2/include/mgmt/cnm_mem.h | 1164 ++ + .../wlan/gen2/include/mgmt/cnm_scan.h | 169 + + .../wlan/gen2/include/mgmt/cnm_timer.h | 235 + + .../wlan/gen2/include/mgmt/hem_mbox.h | 446 + + .../wlan/gen2/include/mgmt/hs20.h | 148 + + .../connectivity/wlan/gen2/include/mgmt/mib.h | 153 + + .../wlan/gen2/include/mgmt/p2p_assoc.h | 55 + + .../wlan/gen2/include/mgmt/p2p_bss.h | 56 + + .../wlan/gen2/include/mgmt/p2p_fsm.h | 2190 +++ + .../wlan/gen2/include/mgmt/p2p_func.h | 155 + + .../wlan/gen2/include/mgmt/p2p_ie.h | 156 + + .../wlan/gen2/include/mgmt/p2p_rlm.h | 74 + + .../wlan/gen2/include/mgmt/p2p_rlm_obss.h | 64 + + .../wlan/gen2/include/mgmt/p2p_scan.h | 81 + + .../wlan/gen2/include/mgmt/p2p_state.h | 43 + + .../wlan/gen2/include/mgmt/privacy.h | 230 + + .../wlan/gen2/include/mgmt/rate.h | 93 + + .../connectivity/wlan/gen2/include/mgmt/rlm.h | 396 + + .../wlan/gen2/include/mgmt/rlm_domain.h | 557 + + .../wlan/gen2/include/mgmt/rlm_obss.h | 150 + + .../wlan/gen2/include/mgmt/rlm_protection.h | 122 + + .../wlan/gen2/include/mgmt/rlm_txpwr_init.h | 1213 ++ + .../wlan/gen2/include/mgmt/roaming_fsm.h | 171 + + .../connectivity/wlan/gen2/include/mgmt/rsn.h | 271 + + .../wlan/gen2/include/mgmt/scan.h | 988 ++ + .../wlan/gen2/include/mgmt/sec_fsm.h | 233 + + .../wlan/gen2/include/mgmt/stats.h | 368 + + .../wlan/gen2/include/mgmt/swcr.h | 187 + + .../wlan/gen2/include/mgmt/tdls.h | 262 + + .../wlan/gen2/include/mgmt/wapi.h | 104 + + .../wlan/gen2/include/mgmt/wlan_typedef.h | 87 + + .../connectivity/wlan/gen2/include/mgmt/wnm.h | 95 + + .../wlan/gen2/include/nic/adapter.h | 1506 +++ + .../connectivity/wlan/gen2/include/nic/bow.h | 322 + + .../wlan/gen2/include/nic/cmd_buf.h | 150 + + .../connectivity/wlan/gen2/include/nic/hal.h | 618 + + .../wlan/gen2/include/nic/hif_rx.h | 220 + + .../wlan/gen2/include/nic/hif_tx.h | 214 + + .../connectivity/wlan/gen2/include/nic/mac.h | 2323 ++++ + .../wlan/gen2/include/nic/mtreg.h | 272 + + .../connectivity/wlan/gen2/include/nic/nic.h | 498 + + .../wlan/gen2/include/nic/nic_rx.h | 420 + + .../wlan/gen2/include/nic/nic_tx.h | 642 + + .../connectivity/wlan/gen2/include/nic/p2p.h | 192 + + .../wlan/gen2/include/nic/p2p_cmd_buf.h | 83 + + .../wlan/gen2/include/nic/p2p_mac.h | 207 + + .../wlan/gen2/include/nic/p2p_nic.h | 62 + + .../wlan/gen2/include/nic/p2p_nic_cmd_event.h | 70 + + .../wlan/gen2/include/nic/que_mgt.h | 971 ++ + .../wlan/gen2/include/nic/wlan_def.h | 1010 ++ + .../wlan/gen2/include/nic_cmd_event.h | 2290 ++++ + .../wlan/gen2/include/nic_init_cmd_event.h | 177 + + .../wlan/gen2/include/p2p_precomp.h | 201 + + .../wlan/gen2/include/p2p_typedef.h | 165 + + .../connectivity/wlan/gen2/include/precomp.h | 388 + + .../connectivity/wlan/gen2/include/pwr_mgt.h | 141 + + .../connectivity/wlan/gen2/include/queue.h | 195 + + .../connectivity/wlan/gen2/include/rftest.h | 294 + + .../wlan/gen2/include/tdls_extr.h | 427 + + .../connectivity/wlan/gen2/include/typedef.h | 244 + + .../connectivity/wlan/gen2/include/wlan_bow.h | 352 + + .../connectivity/wlan/gen2/include/wlan_lib.h | 1001 ++ + .../connectivity/wlan/gen2/include/wlan_oid.h | 1715 +++ + .../connectivity/wlan/gen2/include/wlan_p2p.h | 307 + + .../connectivity/wlan/gen2/mgmt/aaa_fsm.c | 1303 ++ + .../connectivity/wlan/gen2/mgmt/ais_fsm.c | 5039 +++++++ + .../connectivity/wlan/gen2/mgmt/assoc.c | 1932 +++ + .../connectivity/wlan/gen2/mgmt/auth.c | 1211 ++ + .../connectivity/wlan/gen2/mgmt/bss.c | 2521 ++++ + .../connectivity/wlan/gen2/mgmt/cnm.c | 738 ++ + .../connectivity/wlan/gen2/mgmt/cnm_mem.c | 1236 ++ + .../connectivity/wlan/gen2/mgmt/cnm_timer.c | 482 + + .../connectivity/wlan/gen2/mgmt/hem_mbox.c | 816 ++ + .../connectivity/wlan/gen2/mgmt/hs20.c | 498 + + .../connectivity/wlan/gen2/mgmt/mib.c | 111 + + .../connectivity/wlan/gen2/mgmt/p2p_assoc.c | 87 + + .../connectivity/wlan/gen2/mgmt/p2p_bss.c | 58 + + .../connectivity/wlan/gen2/mgmt/p2p_fsm.c | 3139 +++++ + .../connectivity/wlan/gen2/mgmt/p2p_func.c | 3796 ++++++ + .../connectivity/wlan/gen2/mgmt/p2p_ie.c | 612 + + .../connectivity/wlan/gen2/mgmt/p2p_rlm.c | 905 ++ + .../wlan/gen2/mgmt/p2p_rlm_obss.c | 313 + + .../connectivity/wlan/gen2/mgmt/p2p_scan.c | 756 ++ + .../connectivity/wlan/gen2/mgmt/p2p_state.c | 466 + + .../connectivity/wlan/gen2/mgmt/privacy.c | 915 ++ + .../connectivity/wlan/gen2/mgmt/rate.c | 497 + + .../connectivity/wlan/gen2/mgmt/rlm.c | 1858 +++ + .../connectivity/wlan/gen2/mgmt/rlm_domain.c | 1791 +++ + .../connectivity/wlan/gen2/mgmt/rlm_obss.c | 436 + + .../wlan/gen2/mgmt/rlm_protection.c | 105 + + .../connectivity/wlan/gen2/mgmt/roaming_fsm.c | 539 + + .../connectivity/wlan/gen2/mgmt/rsn.c | 2533 ++++ + .../connectivity/wlan/gen2/mgmt/saa_fsm.c | 1788 +++ + .../connectivity/wlan/gen2/mgmt/scan.c | 3103 +++++ + .../connectivity/wlan/gen2/mgmt/scan_fsm.c | 2136 +++ + .../connectivity/wlan/gen2/mgmt/sec_fsm.c | 1112 ++ + .../connectivity/wlan/gen2/mgmt/stats.c | 1342 ++ + .../connectivity/wlan/gen2/mgmt/swcr.c | 1170 ++ + .../connectivity/wlan/gen2/mgmt/tdls.c | 5199 ++++++++ + .../connectivity/wlan/gen2/mgmt/tdls_com.c | 741 ++ + .../connectivity/wlan/gen2/mgmt/wapi.c | 491 + + .../connectivity/wlan/gen2/mgmt/wnm.c | 301 + + .../connectivity/wlan/gen2/nic/cmd_buf.c | 254 + + .../mediatek/connectivity/wlan/gen2/nic/nic.c | 4062 ++++++ + .../wlan/gen2/nic/nic_cmd_event.c | 1636 +++ + .../connectivity/wlan/gen2/nic/nic_pwr_mgt.c | 669 + + .../connectivity/wlan/gen2/nic/nic_rx.c | 3782 ++++++ + .../connectivity/wlan/gen2/nic/nic_tx.c | 2350 ++++ + .../connectivity/wlan/gen2/nic/p2p_nic.c | 192 + + .../connectivity/wlan/gen2/nic/que_mgt.c | 5038 +++++++ + .../connectivity/wlan/gen2/os/linux/gl_bow.c | 1177 ++ + .../wlan/gen2/os/linux/gl_cfg80211.c | 3110 +++++ + .../connectivity/wlan/gen2/os/linux/gl_init.c | 3502 +++++ + .../connectivity/wlan/gen2/os/linux/gl_kal.c | 4799 +++++++ + .../connectivity/wlan/gen2/os/linux/gl_p2p.c | 4672 +++++++ + .../wlan/gen2/os/linux/gl_p2p_cfg80211.c | 1935 +++ + .../wlan/gen2/os/linux/gl_p2p_init.c | 433 + + .../wlan/gen2/os/linux/gl_p2p_kal.c | 1314 ++ + .../connectivity/wlan/gen2/os/linux/gl_proc.c | 1020 ++ + .../connectivity/wlan/gen2/os/linux/gl_rst.c | 228 + + .../wlan/gen2/os/linux/gl_vendor.c | 1220 ++ + .../connectivity/wlan/gen2/os/linux/gl_wext.c | 4158 ++++++ + .../wlan/gen2/os/linux/gl_wext_priv.c | 3142 +++++ + .../wlan/gen2/os/linux/hif/ahb/ahb.c | 1643 +++ + .../wlan/gen2/os/linux/hif/ahb/arm.c | 31 + + .../wlan/gen2/os/linux/hif/ahb/include/hif.h | 340 + + .../gen2/os/linux/hif/ahb/include/hif_gdma.h | 154 + + .../gen2/os/linux/hif/ahb/include/hif_pdma.h | 141 + + .../os/linux/hif/ahb/include/mtk_porting.h | 91 + + .../gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c | 480 + + .../wlan/gen2/os/linux/include/gl_cfg80211.h | 341 + + .../wlan/gen2/os/linux/include/gl_kal.h | 1565 +++ + .../wlan/gen2/os/linux/include/gl_os.h | 1270 ++ + .../wlan/gen2/os/linux/include/gl_p2p_ioctl.h | 743 ++ + .../wlan/gen2/os/linux/include/gl_p2p_kal.h | 243 + + .../wlan/gen2/os/linux/include/gl_p2p_os.h | 242 + + .../wlan/gen2/os/linux/include/gl_rst.h | 133 + + .../wlan/gen2/os/linux/include/gl_sec.h | 21 + + .../wlan/gen2/os/linux/include/gl_typedef.h | 298 + + .../wlan/gen2/os/linux/include/gl_vendor.h | 619 + + .../wlan/gen2/os/linux/include/gl_wext.h | 357 + + .../wlan/gen2/os/linux/include/gl_wext_priv.h | 402 + + .../wlan/gen2/os/linux/platform.c | 542 + + .../connectivity/wlan/gen2/os/version.h | 190 + + drivers/misc/mediatek/include/mt-plat/aee.h | 284 + + .../misc/mediatek/include/mt-plat/mrdump.h | 204 + + .../mt-plat/mt7622/include/mach/mtk_thermal.h | 295 + + .../mt8127/include/mach/mt_freqhopping.h | 159 + + .../mt8127/include/mach/mt_spm_mtcmos.h | 37 + + .../mt8127/include/mach/mtk_boot_share_page.h | 40 + + .../mt-plat/mt8127/include/mach/mtk_thermal.h | 301 + + .../misc/mediatek/include/mt-plat/mt_sched.h | 34 + + .../misc/mediatek/include/mt-plat/mtk_io.h | 23 + + .../misc/mediatek/include/mt-plat/mtk_lpae.h | 62 + + .../include/mt-plat/mtk_mdm_monitor.h | 42 + + .../include/mt-plat/mtk_platform_debug.h | 28 + + .../include/mt-plat/mtk_ram_console.h | 162 + + .../misc/mediatek/include/mt-plat/mtk_rtc.h | 85 + + .../include/mt-plat/mtk_thermal_ext_control.h | 69 + + .../include/mt-plat/mtk_thermal_monitor.h | 102 + + .../include/mt-plat/mtk_thermal_platform.h | 114 + + .../include/mt-plat/mtk_thermal_trace.h | 47 + + .../include/mt-plat/mtk_thermal_typedefs.h | 241 + + .../include/mt-plat/mtk_wcn_cmb_stub.h | 185 + + .../misc/mediatek/include/mt-plat/rt-regmap.h | 291 + + .../mediatek/include/mt-plat/sync_write.h | 88 + + .../misc/mediatek/include/mt-plat/wakelock.h | 67 + + 285 files changed, 213970 insertions(+) + create mode 100644 drivers/misc/mediatek/Kconfig + create mode 100644 drivers/misc/mediatek/Makefile + create mode 100644 drivers/misc/mediatek/btif/Kconfig + create mode 100644 drivers/misc/mediatek/btif/Makefile + create mode 100644 drivers/misc/mediatek/btif/common/Makefile + create mode 100644 drivers/misc/mediatek/btif/common/btif_dma_plat.c + create mode 100644 drivers/misc/mediatek/btif/common/btif_plat.c + create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif.h + create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h + create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif.c + create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif_exp.c + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h + create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/plat_common.h + create mode 100644 drivers/misc/mediatek/connectivity/Kconfig + create mode 100644 drivers/misc/mediatek/connectivity/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c + create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c + create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/Makefile + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c + create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/aee.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mrdump.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mt_sched.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_io.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_lpae.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_rtc.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/rt-regmap.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/sync_write.h + create mode 100644 drivers/misc/mediatek/include/mt-plat/wakelock.h + +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 3726eacdf65d..9008a09172e1 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -527,4 +527,5 @@ source "drivers/misc/echo/Kconfig" + source "drivers/misc/cxl/Kconfig" + source "drivers/misc/ocxl/Kconfig" + source "drivers/misc/cardreader/Kconfig" ++source "drivers/misc/mediatek/Kconfig" + endmenu +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index af22bbc3d00c..cdced6d59e2c 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o + obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o + obj-$(CONFIG_OCXL) += ocxl/ + obj-$(CONFIG_MISC_RTSX) += cardreader/ ++obj-$(CONFIG_MTK_COMBO) += mediatek/ +diff --git a/drivers/misc/mediatek/Kconfig b/drivers/misc/mediatek/Kconfig +new file mode 100644 +index 000000000000..4829a6598c7a +--- /dev/null ++++ b/drivers/misc/mediatek/Kconfig +@@ -0,0 +1,11 @@ ++menu "Mediatek Peripherals " ++ ++config MTK_PLATFORM ++ string "MTK platform name" ++source "drivers/misc/mediatek/btif/Kconfig" ++ ++menu "Modem & Connectivity related configs" ++source "drivers/misc/mediatek/connectivity/Kconfig" ++endmenu ++ ++endmenu # CONN +diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile +new file mode 100644 +index 000000000000..5e7f06db38f2 +--- /dev/null ++++ b/drivers/misc/mediatek/Makefile +@@ -0,0 +1,19 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++#$(call all-subdir-src-or-makefile) ++subdir-ccflags-y += -Werror ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ ++ ++obj-$(CONFIG_MTK_COMBO) += connectivity/ ++obj-$(CONFIG_MTK_BTIF) += btif/ +diff --git a/drivers/misc/mediatek/btif/Kconfig b/drivers/misc/mediatek/btif/Kconfig +new file mode 100644 +index 000000000000..908898bd95c3 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/Kconfig +@@ -0,0 +1,4 @@ ++config MTK_BTIF ++ tristate"MediaTek BTIF Driver" ++ help ++ MTK connectivity BTIF driver for A/D die +diff --git a/drivers/misc/mediatek/btif/Makefile b/drivers/misc/mediatek/btif/Makefile +new file mode 100644 +index 000000000000..2be3ab66f426 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/Makefile +@@ -0,0 +1,33 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++# BTIF driver for AD DIE ++# If KERNELRELEASE is defined, we've been invoked from the ++# kernel build system and can use its language. ++ifneq ($(KERNELRELEASE),) ++ #subdir-ccflags-y can be used in 2.6.34 in the future ++ MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) ++ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include ++ subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/include/mach ++ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat ++ ++ obj-y += common/ ++ ++# Otherwise we were called directly from the command ++# line; invoke the kernel build system. ++else ++ KERNELDIR ?= /lib/modules/$(shell uname -r)/build ++ PWD := $(shell pwd) ++default: ++ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ++endif +diff --git a/drivers/misc/mediatek/btif/common/Makefile b/drivers/misc/mediatek/btif/common/Makefile +new file mode 100644 +index 000000000000..61e9d4ea9e89 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/Makefile +@@ -0,0 +1,31 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++# BTIF driver for AD DIE ++# If KERNELRELEASE is defined, we've been invoked from the ++# kernel build system and can use its language. ++ifneq ($(KERNELRELEASE),) ++ ccflags-y += -I$(src)/inc ++ ccflags-y += -I$(src)/plat_inc ++ ++ obj-y += btif.o ++ btif-y := mtk_btif.o mtk_btif_exp.o btif_dma_plat.o btif_plat.o ++ ++# Otherwise we were called directly from the command ++# line; invoke the kernel build system. ++else ++ KERNELDIR ?= /lib/modules/$(shell uname -r)/build ++ PWD := $(shell pwd) ++default: ++ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ++endif +diff --git a/drivers/misc/mediatek/btif/common/btif_dma_plat.c b/drivers/misc/mediatek/btif/common/btif_dma_plat.c +new file mode 100644 +index 000000000000..58be46927953 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/btif_dma_plat.c +@@ -0,0 +1,1436 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF-DMA" ++ ++#include "btif_dma_priv.h" ++ ++#define DMA_USER_ID "btif_driver" ++ ++/************************************Global variable***********************************/ ++ ++static MTK_BTIF_DMA_VFIFO mtk_tx_dma_vfifo = { ++ .vfifo = { ++ .p_vir_addr = NULL, ++ .phy_addr = 0, ++ .vfifo_size = TX_DMA_VFF_SIZE, ++ .thre = DMA_TX_THRE(TX_DMA_VFF_SIZE), ++ }, ++ .wpt = 0, ++ .last_wpt_wrap = 0, ++ .rpt = 0, ++ .last_rpt_wrap = 0, ++}; ++ ++static MTK_BTIF_IRQ_STR mtk_btif_tx_dma_irq = { ++ .name = "mtk btif tx dma irq", ++ .is_irq_sup = true, ++ .reg_flag = false, ++#ifdef CONFIG_OF ++ .irq_flags = IRQF_TRIGGER_NONE, ++#else ++ .irq_id = MT_DMA_BTIF_TX_IRQ_ID, ++ .sens_type = IRQ_SENS_LVL, ++ .lvl_type = IRQ_LVL_LOW, ++#endif ++ .p_irq_handler = NULL, ++}; ++ ++static MTK_BTIF_DMA_VFIFO mtk_rx_dma_vfifo = { ++ .vfifo = { ++ .p_vir_addr = NULL, ++ .phy_addr = 0, ++ .vfifo_size = RX_DMA_VFF_SIZE, ++ .thre = DMA_RX_THRE(RX_DMA_VFF_SIZE), ++ }, ++ ++ .wpt = 0, ++ .last_wpt_wrap = 0, ++ .rpt = 0, ++ .last_rpt_wrap = 0, ++}; ++ ++static MTK_BTIF_IRQ_STR mtk_btif_rx_dma_irq = { ++ .name = "mtk btif rx dma irq", ++ .is_irq_sup = true, ++ .reg_flag = false, ++#ifdef CONFIG_OF ++ .irq_flags = IRQF_TRIGGER_NONE, ++#else ++ .irq_id = MT_DMA_BTIF_RX_IRQ_ID, ++ .sens_type = IRQ_SENS_LVL, ++ .lvl_type = IRQ_LVL_LOW, ++#endif ++ .p_irq_handler = NULL, ++}; ++ ++static MTK_DMA_INFO_STR mtk_btif_tx_dma = { ++#ifndef CONFIG_OF ++ .base = AP_DMA_BASE + BTIF_TX_DMA_OFFSET, ++#endif ++ .dir = DMA_DIR_TX, ++ .p_irq = &mtk_btif_tx_dma_irq, ++ .p_vfifo = &(mtk_tx_dma_vfifo.vfifo), ++}; ++ ++static MTK_DMA_INFO_STR mtk_btif_rx_dma = { ++#ifndef CONFIG_OF ++ .base = AP_DMA_BASE + BTIF_RX_DMA_OFFSET, ++#endif ++ .dir = DMA_DIR_RX, ++ .p_irq = &mtk_btif_rx_dma_irq, ++ .p_vfifo = &(mtk_rx_dma_vfifo.vfifo), ++}; ++ ++static spinlock_t g_clk_cg_spinlock; /*dma clock's spinlock */ ++ ++/************************************Function declearation***********************************/ ++static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info); ++static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info); ++static int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_DMA_CTRL ctrl_id); ++static int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_DMA_CTRL ctrl_id); ++static int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); ++static int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); ++static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag); ++static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag); ++static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info); ++static int _btif_dma_dump_dbg_reg(void); ++static void hal_btif_tx_dma_vff_set_for_4g(void); ++static void hal_btif_rx_dma_vff_set_for_4g(void); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ier_ctrl ++* DESCRIPTION ++* BTIF Tx DMA's interrupt enable/disable ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* enable [IN] control if tx interrupt enabled or not ++* dma_dir [IN] DMA's direction ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_receive_data ++* DESCRIPTION ++* receive data from btif module in DMA polling mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++static int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, ++ const unsigned int max_len); ++ ++/************************************Function***********************************/ ++#endif ++ ++#ifdef CONFIG_OF ++static void hal_dma_set_default_setting(ENUM_DMA_DIR dma_dir) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = {0, 0, 0}; ++ unsigned int phy_base; ++ ++ if (dma_dir == DMA_DIR_RX) { ++ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_rx"); ++ if (node) { ++ mtk_btif_rx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); ++ /*fixme, be compitable arch 64bits*/ ++ mtk_btif_rx_dma.base = (unsigned long)of_iomap(node, 0); ++ BTIF_INFO_FUNC("get rx_dma irq(%d),register base(0x%lx)\n", ++ mtk_btif_rx_dma.p_irq->irq_id, mtk_btif_rx_dma.base); ++ } else { ++ BTIF_ERR_FUNC("get rx_dma device node fail\n"); ++ } ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); ++ } else { ++ mtk_btif_rx_dma.p_irq->irq_flags = irq_info[2]; ++ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", ++ mtk_btif_rx_dma.p_irq->irq_flags); ++ } ++ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { ++ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", ++ dma_dir); ++ } else { ++ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", ++ dma_dir, (unsigned int)phy_base); ++ } ++ } else if (dma_dir == DMA_DIR_TX) { ++ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_tx"); ++ if (node) { ++ mtk_btif_tx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); ++ /*fixme, be compitable arch 64bits*/ ++ mtk_btif_tx_dma.base = (unsigned long)of_iomap(node, 0); ++ BTIF_INFO_FUNC("get tx_dma irq(%d),register base(0x%lx)\n", ++ mtk_btif_tx_dma.p_irq->irq_id, mtk_btif_tx_dma.base); ++ } else { ++ BTIF_ERR_FUNC("get tx_dma device node fail\n"); ++ } ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); ++ } else { ++ mtk_btif_tx_dma.p_irq->irq_flags = irq_info[2]; ++ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", ++ mtk_btif_tx_dma.p_irq->irq_flags); ++ } ++ ++ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { ++ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", ++ dma_dir); ++ } else { ++ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", ++ dma_dir, (unsigned int)phy_base); ++ } ++ } ++ ++} ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_info_get ++* DESCRIPTION ++* get btif tx dma channel's information ++* PARAMETERS ++* dma_dir [IN] DMA's direction ++* RETURNS ++* pointer to btif dma's information structure ++*****************************************************************************/ ++P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir) ++{ ++ P_MTK_DMA_INFO_STR p_dma_info = NULL; ++ ++ BTIF_TRC_FUNC(); ++#ifdef CONFIG_OF ++ hal_dma_set_default_setting(dma_dir); ++#endif ++ if (dma_dir == DMA_DIR_RX) ++ /*Rx DMA*/ ++ p_dma_info = &mtk_btif_rx_dma; ++ else if (dma_dir == DMA_DIR_TX) ++ /*Tx DMA*/ ++ p_dma_info = &mtk_btif_tx_dma; ++ else ++ /*print error log*/ ++ BTIF_ERR_FUNC("invalid DMA dir (%d)\n", dma_dir); ++ spin_lock_init(&g_clk_cg_spinlock); ++ BTIF_TRC_FUNC(); ++ return p_dma_info; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of DMA module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag) ++{ ++/*In MTK DMA BTIF channel, there's only one global CG on AP_DMA, no sub channel's CG bit*/ ++/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ ++ int i_ret = 0; ++ unsigned long irq_flag = 0; ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ static atomic_t s_clk_ref = ATOMIC_INIT(0); ++#else ++ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; ++#endif ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_CTL ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++ if (flag == CLK_OUT_ENABLE) { ++ if (atomic_inc_return(&s_clk_ref) == 1) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); ++ i_ret = clk_enable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++ if (atomic_dec_return(&s_clk_ref) == 0) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif_apdma) calling\n"); ++ clk_disable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ ++#else ++ ++ if (status == flag) { ++ i_ret = 0; ++ BTIF_DBG_FUNC("dma clock already %s\n", ++ CLK_OUT_ENABLE == ++ status ? "enabled" : "disabled"); ++ } else { ++ if (flag == CLK_OUT_ENABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); ++ i_ret = clk_enable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable_unprepare(clk_btif_apdma) calling\n"); ++ clk_disable(clk_btif_apdma); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ } ++#endif ++ ++#else ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++#else ++ ++ status = flag; ++#endif ++ ++ i_ret = 0; ++#endif ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#else ++ ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++ BTIF_DBG_FUNC("DMA's clock is %s\n", (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) ? "off" : "on"); ++#endif ++ return i_ret; ++} ++ ++int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ int i_ret = 0; ++ unsigned int dat = 0; ++ unsigned long base = p_dma_info->base; ++ unsigned long addr_h = 0; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ ++ if (p_dma_info->dir == DMA_DIR_RX) { ++ /*Rx DMA*/ ++ /*do hardware reset*/ ++ /* BTIF_SET_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ ++ /* BTIF_CLR_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ ++ BTIF_SET_BIT(RX_DMA_RST(base), DMA_WARM_RST); ++ do { ++ dat = BTIF_READ32(RX_DMA_EN(base)); ++ } while (0x01 & dat); ++ /*write vfifo base address to VFF_ADDR*/ ++ btif_reg_sync_writel(p_vfifo->phy_addr, RX_DMA_VFF_ADDR(base)); ++ if (enable_4G()) ++ hal_btif_rx_dma_vff_set_for_4g(); ++ else { ++ addr_h = p_vfifo->phy_addr >> 16; ++ addr_h = addr_h >> 16; ++ btif_reg_sync_writel(addr_h, RX_DMA_VFF_ADDR_H(base)); ++ } ++ /*write vfifo length to VFF_LEN*/ ++ btif_reg_sync_writel(p_vfifo->vfifo_size, RX_DMA_VFF_LEN(base)); ++ /*write wpt to VFF_WPT*/ ++ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, ++ RX_DMA_VFF_WPT(base)); ++ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, ++ RX_DMA_VFF_RPT(base)); ++ /*write vff_thre to VFF_THRESHOLD*/ ++ btif_reg_sync_writel(p_vfifo->thre, RX_DMA_VFF_THRE(base)); ++ /*clear Rx DMA's interrupt status*/ ++ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), ++ RX_DMA_INT_DONE | RX_DMA_INT_THRE); ++ ++ /*enable Rx IER by default*/ ++ btif_rx_dma_ier_ctrl(p_dma_info, true); ++ } else { ++/*Tx DMA*/ ++/*do hardware reset*/ ++/* BTIF_SET_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ ++/* BTIF_CLR_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ ++ BTIF_SET_BIT(TX_DMA_RST(base), DMA_WARM_RST); ++ do { ++ dat = BTIF_READ32(TX_DMA_EN(base)); ++ } while (0x01 & dat); ++/*write vfifo base address to VFF_ADDR*/ ++ btif_reg_sync_writel(p_vfifo->phy_addr, TX_DMA_VFF_ADDR(base)); ++ if (enable_4G()) ++ hal_btif_tx_dma_vff_set_for_4g(); ++ else { ++ addr_h = p_vfifo->phy_addr >> 16; ++ addr_h = addr_h >> 16; ++ btif_reg_sync_writel(addr_h, TX_DMA_VFF_ADDR_H(base)); ++ } ++/*write vfifo length to VFF_LEN*/ ++ btif_reg_sync_writel(p_vfifo->vfifo_size, TX_DMA_VFF_LEN(base)); ++/*write wpt to VFF_WPT*/ ++ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, ++ TX_DMA_VFF_WPT(base)); ++ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, ++ TX_DMA_VFF_RPT(base)); ++/*write vff_thre to VFF_THRESHOLD*/ ++ btif_reg_sync_writel(p_vfifo->thre, TX_DMA_VFF_THRE(base)); ++ ++ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); ++ ++ hal_btif_dma_ier_ctrl(p_dma_info, false); ++ } ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ctrl ++* DESCRIPTION ++* enable/disable Tx DMA channel ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* ctrl_id [IN] enable/disable ID ++* RETURNS ++* 0 means success; negative means fail ++*****************************************************************************/ ++int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) ++{ ++ unsigned int i_ret = -1; ++ ENUM_DMA_DIR dir = p_dma_info->dir; ++ ++ if (dir == DMA_DIR_RX) ++ i_ret = btif_rx_dma_ctrl(p_dma_info, ctrl_id); ++ else if (dir == DMA_DIR_TX) ++ i_ret = btif_tx_dma_ctrl(p_dma_info, ctrl_id); ++ else { ++ /*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid dma ctrl id (%d)\n", ctrl_id); ++ i_ret = ERR_INVALID_PAR; ++ } ++ return i_ret; ++} ++ ++int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ dma_rx_buf_write rx_cb) ++{ ++ if (p_dma_info->rx_cb != NULL) { ++ BTIF_DBG_FUNC ++ ("rx_cb already registered, replace (0x%p) with (0x%p)\n", ++ p_dma_info->rx_cb, rx_cb); ++ } ++ p_dma_info->rx_cb = rx_cb; ++ return 0; ++} ++ ++int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int dat; ++ ++ BTIF_TRC_FUNC(); ++ if (ctrl_id == DMA_CTRL_DISABLE) { ++ /*if write 0 to EN bit, DMA will be stopped imediately*/ ++ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ ++ /*BTIF_CLR_BIT(TX_DMA_EN(base), DMA_EN_BIT);*/ ++ BTIF_SET_BIT(TX_DMA_STOP(base), DMA_STOP_BIT); ++ do { ++ dat = BTIF_READ32(TX_DMA_STOP(base)); ++ } while (0x1 & dat); ++ BTIF_DBG_FUNC("BTIF Tx DMA disabled,EN(0x%x),STOP(0x%x)\n", ++ BTIF_READ32(TX_DMA_EN(base)), BTIF_READ32(TX_DMA_STOP(base))); ++ i_ret = 0; ++ } else if (ctrl_id == DMA_CTRL_ENABLE) { ++ BTIF_SET_BIT(TX_DMA_EN(base), DMA_EN_BIT); ++ BTIF_DBG_FUNC("BTIF Tx DMA enabled\n"); ++ i_ret = 0; ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); ++ i_ret = ERR_INVALID_PAR; ++ } ++ BTIF_TRC_FUNC(); ++ return i_ret; ++} ++ ++int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int dat; ++ ++ BTIF_TRC_FUNC(); ++ ++ if (ctrl_id == DMA_CTRL_DISABLE) { ++ /*if write 0 to EN bit, DMA will be stopped imediately*/ ++ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ ++ /*BTIF_CLR_BIT(RX_DMA_EN(base), DMA_EN_BIT);*/ ++ BTIF_SET_BIT(RX_DMA_STOP(base), DMA_STOP_BIT); ++ do { ++ dat = BTIF_READ32(RX_DMA_STOP(base)); ++ } while (0x1 & dat); ++ BTIF_DBG_FUNC("BTIF Rx DMA disabled,EN(0x%x),STOP(0x%x)\n", ++ BTIF_READ32(RX_DMA_EN(base)), BTIF_READ32(RX_DMA_STOP(base))); ++ i_ret = 0; ++ } else if (ctrl_id == DMA_CTRL_ENABLE) { ++ BTIF_SET_BIT(RX_DMA_EN(base), DMA_EN_BIT); ++ BTIF_DBG_FUNC("BTIF Rx DMA enabled\n"); ++ i_ret = 0; ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); ++ i_ret = ERR_INVALID_PAR; ++ } ++ BTIF_TRC_FUNC(); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_vfifo_reset ++* DESCRIPTION ++* reset tx virtual fifo information, except memory information ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ unsigned int i_ret = -1; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ ++ BTIF_TRC_FUNC(); ++ p_mtk_dma_vfifo->rpt = 0; ++ p_mtk_dma_vfifo->last_rpt_wrap = 0; ++ p_mtk_dma_vfifo->wpt = 0; ++ p_mtk_dma_vfifo->last_wpt_wrap = 0; ++ BTIF_TRC_FUNC(); ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ier_ctrl ++* DESCRIPTION ++* BTIF Tx DMA's interrupt enable/disable ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* enable [IN] control if tx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) ++{ ++ unsigned int i_ret = -1; ++ ENUM_DMA_DIR dir = p_dma_info->dir; ++ ++ if (dir == DMA_DIR_RX) { ++ i_ret = btif_rx_dma_ier_ctrl(p_dma_info, en); ++ } else if (dir == DMA_DIR_TX) { ++ i_ret = btif_tx_dma_ier_ctrl(p_dma_info, en); ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("invalid DMA dma dir (%d)\n", dir); ++ i_ret = ERR_INVALID_PAR; ++ } ++ ++ return i_ret; ++} ++ ++int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ ++ BTIF_TRC_FUNC(); ++ if (!en) { ++ BTIF_CLR_BIT(RX_DMA_INT_EN(base), ++ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); ++ } else { ++ BTIF_SET_BIT(RX_DMA_INT_EN(base), ++ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); ++ } ++ i_ret = 0; ++ BTIF_TRC_FUNC(); ++ ++ return i_ret; ++} ++ ++int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ ++ BTIF_TRC_FUNC(); ++ if (!en) ++ BTIF_CLR_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); ++ else ++ BTIF_SET_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); ++ i_ret = 0; ++ BTIF_TRC_FUNC(); ++ ++ return i_ret; ++} ++ ++static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ int tx_irq_done = 0; ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++/*if we enable this clock reference couner, just return , because when enter IRQ handler, DMA's clock will be opened*/ ++ tx_irq_done = 1; ++#else ++ unsigned long flag = 0; ++ unsigned long base = p_dma_info->base; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); ++ tx_irq_done = ((BTIF_READ32(TX_DMA_INT_FLAG(base)) & TX_DMA_INT_FLAG_MASK) == 0) ? 1 : 0; ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++#endif ++ return tx_irq_done; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_irq_handler ++* DESCRIPTION ++* lower level tx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++#define MAX_CONTINIOUS_TIMES 512 ++ unsigned int i_ret = -1; ++ unsigned int valid_size = 0; ++ unsigned int vff_len = 0; ++ unsigned int left_len = 0; ++ unsigned long base = p_dma_info->base; ++ static int flush_irq_counter; ++ static struct timeval start_timer; ++ static struct timeval end_timer; ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); ++ ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ BTIF_ERR_FUNC ++ ("%s: clock is off before irq status clear done!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*check if Tx VFF Left Size equal to VFIFO size or not*/ ++ vff_len = BTIF_READ32(TX_DMA_VFF_LEN(base)); ++ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); ++ left_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); ++ if (flush_irq_counter == 0) ++ do_gettimeofday(&start_timer); ++ if ((valid_size > 0) && (valid_size < 8)) { ++ i_ret = _tx_dma_flush(p_dma_info); ++ flush_irq_counter++; ++ if (flush_irq_counter >= MAX_CONTINIOUS_TIMES) { ++ do_gettimeofday(&end_timer); ++/* ++ * when btif tx fifo cannot accept any data and counts of bytes left in tx vfifo < 8 for a while ++ * we assume that btif cannot send data for a long time ++ * in order not to generate interrupt continiously, which may effect system's performance. ++ * we clear tx flag and disable btif tx interrupt ++ */ ++/*clear interrupt flag*/ ++ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), ++ TX_DMA_INT_FLAG_MASK); ++/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ ++ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); ++ BTIF_ERR_FUNC ++ ("**********************ERROR, ERROR, ERROR**************************\n"); ++ BTIF_ERR_FUNC ++ ("BTIF Tx IRQ happened %d times (continiously), between %d.%d and %d.%d\n", ++ MAX_CONTINIOUS_TIMES, start_timer.tv_sec, ++ start_timer.tv_usec, end_timer.tv_usec, ++ end_timer.tv_usec); ++ } ++ } else if (vff_len == left_len) { ++ flush_irq_counter = 0; ++/*clear interrupt flag*/ ++ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); ++/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ ++ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); ++ } else { ++#if 0 ++ BTIF_ERR_FUNC ++ ("**********************WARNING**************************\n"); ++ BTIF_ERR_FUNC("invalid irq condition, dump register\n"); ++ hal_dma_dump_reg(p_dma_info, REG_TX_DMA_ALL); ++#endif ++ BTIF_DBG_FUNC ++ ("superious IRQ occurs, vff_len(%d), valid_size(%d), left_len(%d)\n", ++ vff_len, valid_size, left_len); ++ } ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_send_data ++* DESCRIPTION ++* send data through btif in DMA mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, ++ const unsigned char *p_buf, const unsigned int buf_len) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ unsigned int len_to_send = buf_len; ++ unsigned int ava_len = 0; ++ unsigned int wpt = 0; ++ unsigned int last_wpt_wrap = 0; ++ unsigned int vff_size = 0; ++ unsigned char *p_data = (unsigned char *)p_buf; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ ++ BTIF_TRC_FUNC(); ++ if ((p_buf == NULL) || (buf_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid parameters, p_buf:0x%p, buf_len:%d\n", ++ p_buf, buf_len); ++ return i_ret; ++ } ++/*check if tx dma in flush operation? if yes, should wait until DMA finish flush operation*/ ++/*currently uplayer logic will make sure this pre-condition*/ ++/*disable Tx IER, in case Tx irq happens, flush bit may be set in irq handler*/ ++ btif_tx_dma_ier_ctrl(p_dma_info, false); ++ ++ vff_size = p_mtk_vfifo->vfifo.vfifo_size; ++ ava_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); ++ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_MASK; ++ last_wpt_wrap = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_WRAP; ++ ++/* ++ * copy data to vFIFO, Note: ava_len should always large than buf_len, ++ * otherwise common logic layer will not call hal_dma_send_data ++ */ ++ if (buf_len > ava_len) { ++ BTIF_ERR_FUNC ++ ("length to send:(%d) < length available(%d), abnormal!!!---!!!\n", ++ buf_len, ava_len); ++ WARN_ON(buf_len > ava_len); /* this will cause kernel panic */ ++ } ++ ++ len_to_send = buf_len < ava_len ? buf_len : ava_len; ++ if (len_to_send + wpt >= vff_size) { ++ unsigned int tail_len = vff_size - wpt; ++ ++ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), p_data, tail_len); ++ p_data += tail_len; ++ memcpy(p_mtk_vfifo->vfifo.p_vir_addr, ++ p_data, len_to_send - tail_len); ++/*make sure all data write to memory area tx vfifo locates*/ ++ mb(); ++ ++/*calculate WPT*/ ++ wpt = wpt + len_to_send - vff_size; ++ last_wpt_wrap ^= DMA_WPT_WRAP; ++ } else { ++ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), ++ p_data, len_to_send); ++/*make sure all data write to memory area tx vfifo locates*/ ++ mb(); ++ ++/*calculate WPT*/ ++ wpt += len_to_send; ++ } ++ p_mtk_vfifo->wpt = wpt; ++ p_mtk_vfifo->last_wpt_wrap = last_wpt_wrap; ++ ++/*make sure tx dma is allowed(tx flush bit is not set) to use before update WPT*/ ++ if (hal_dma_is_tx_allow(p_dma_info)) { ++ /*make sure tx dma enabled*/ ++ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); ++ ++ /*update WTP to Tx DMA controller's control register*/ ++ btif_reg_sync_writel(wpt | last_wpt_wrap, TX_DMA_VFF_WPT(base)); ++ ++ if ((BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) < 8) && ++ (BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) > 0)) { ++ /* ++ * 0 < valid size in Tx vFIFO < 8 && TX Flush is not in process? ++ * if yes, set flush bit to DMA ++ */ ++ _tx_dma_flush(p_dma_info); ++ } ++ i_ret = len_to_send; ++ } else { ++/*TODO: print error log*/ ++ BTIF_ERR_FUNC("Tx DMA flush operation is in process, this case should never happen,", ++ "please check if tx operation is allowed before call this API\n"); ++/*if flush operation is in process , we will return 0*/ ++ i_ret = 0; ++ } ++ ++/*Enable Tx IER*/ ++ btif_tx_dma_ier_ctrl(p_dma_info, true); ++ ++ BTIF_TRC_FUNC(); ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ bool b_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); ++ unsigned int inter_size = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); ++ unsigned int tx_done = is_tx_dma_irq_finish_done(p_dma_info); ++ ++/* ++ * only when virtual FIFO valid size and Tx channel internal buffer size are both becomes to be 0, ++ * we can identify tx operation finished ++ * confirmed with DE. ++ */ ++ if ((valid_size == 0) && (inter_size == 0) && (tx_done == 1)) { ++ b_ret = true; ++ BTIF_DBG_FUNC("DMA tx finished.\n"); ++ } else { ++ BTIF_DBG_FUNC ++ ("DMA tx is in process. vfifo valid size(%d), dma internal size (%d), tx_done(%d)\n", ++ valid_size, inter_size, tx_done); ++ b_ret = false; ++ } ++ ++ return b_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_get_ava_room ++* DESCRIPTION ++* get tx available room ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* available room size ++*****************************************************************************/ ++int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ ++/*read vFIFO's left size*/ ++ i_ret = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); ++ BTIF_DBG_FUNC("DMA tx ava room (%d).\n", i_ret); ++ if (i_ret == 0) ++ BTIF_INFO_FUNC("DMA tx vfifo is full.\n"); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_allow ++* DESCRIPTION ++* is tx operation allowed by DMA ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) ++#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) ++ ++ bool b_ret = false; ++ unsigned int wait_us = 8 / MIN_TX_MB; /*only ava length */ ++/*see if flush operation is in process*/ ++ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; ++ if (!b_ret) { ++ usleep_range(wait_us, 2 * wait_us); ++ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; ++ } ++ if (!b_ret) ++ BTIF_WARN_FUNC("btif tx dma is not allowed\n"); ++/*after Tx flush operation finished, HW will set DMA_EN back to 0 and stop DMA*/ ++ return b_ret; ++} ++ ++ ++/***************************************************************************** ++* FUNCTION ++* hal_rx_dma_irq_handler ++* DESCRIPTION ++* lower level rx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++ int i_ret = -1; ++ unsigned int valid_len = 0; ++ unsigned int wpt_wrap = 0; ++ unsigned int rpt_wrap = 0; ++ unsigned int wpt = 0; ++ unsigned int rpt = 0; ++ unsigned int tail_len = 0; ++ unsigned int real_len = 0; ++ unsigned long base = p_dma_info->base; ++ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; ++ dma_rx_buf_write rx_cb = p_dma_info->rx_cb; ++ unsigned char *p_vff_buf = NULL; ++ unsigned char *vff_base = p_vfifo->p_vir_addr; ++ unsigned int vff_size = p_vfifo->vfifo_size; ++ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, ++ MTK_BTIF_DMA_VFIFO, ++ vfifo); ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*disable DMA Rx IER*/ ++ hal_btif_dma_ier_ctrl(p_dma_info, false); ++ ++/*clear Rx DMA's interrupt status*/ ++ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), RX_DMA_INT_DONE | RX_DMA_INT_THRE); ++ ++ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); ++ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); ++ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); ++ if ((valid_len == 0) && (rpt == wpt)) { ++ BTIF_DBG_FUNC ++ ("rx interrupt, no data available in Rx DMA, wpt(0x%08x), rpt(0x%08x)\n", ++ rpt, wpt); ++ } ++ ++ i_ret = 0; ++ ++ while ((valid_len > 0) || (rpt != wpt)) { ++ rpt_wrap = rpt & DMA_RPT_WRAP; ++ wpt_wrap = wpt & DMA_WPT_WRAP; ++ rpt &= DMA_RPT_MASK; ++ wpt &= DMA_WPT_MASK; ++ ++/*calcaute length of available data in vFIFO*/ ++ if (wpt_wrap != p_mtk_vfifo->last_wpt_wrap) ++ real_len = wpt + vff_size - rpt; ++ else ++ real_len = wpt - rpt; ++ ++ if (rx_cb != NULL) { ++ tail_len = vff_size - rpt; ++ p_vff_buf = vff_base + rpt; ++ if (tail_len >= real_len) { ++ (*rx_cb) (p_dma_info, p_vff_buf, real_len); ++ } else { ++ (*rx_cb) (p_dma_info, p_vff_buf, tail_len); ++ p_vff_buf = vff_base; ++ (*rx_cb) (p_dma_info, p_vff_buf, real_len - ++ tail_len); ++ } ++ i_ret += real_len; ++ } else ++ BTIF_ERR_FUNC("no rx_cb found, please check your init process\n"); ++ mb(); ++ rpt += real_len; ++ if (rpt >= vff_size) { ++ /*read wrap bit should be revert*/ ++ rpt_wrap ^= DMA_RPT_WRAP; ++ rpt %= vff_size; ++ } ++ rpt |= rpt_wrap; ++/*record wpt, last_wpt_wrap, rpt, last_rpt_wrap*/ ++ p_mtk_vfifo->wpt = wpt; ++ p_mtk_vfifo->last_wpt_wrap = wpt_wrap; ++ ++ p_mtk_vfifo->rpt = rpt; ++ p_mtk_vfifo->last_rpt_wrap = rpt_wrap; ++ ++/*update rpt information to DMA controller*/ ++ btif_reg_sync_writel(rpt, RX_DMA_VFF_RPT(base)); ++ ++/*get vff valid size again and check if rx data is processed completely*/ ++ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); ++ ++ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); ++ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); ++ } ++ ++/*enable DMA Rx IER*/ ++ hal_btif_dma_ier_ctrl(p_dma_info, true); ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); ++ ++ return i_ret; ++} ++ ++static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag) ++{ ++ int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int int_flag = 0; ++ unsigned int enable = 0; ++ unsigned int stop = 0; ++ unsigned int flush = 0; ++ unsigned int wpt = 0; ++ unsigned int rpt = 0; ++ unsigned int int_buf = 0; ++ unsigned int valid_size = 0; ++ /*unsigned long irq_flag = 0;*/ ++ ++#if defined(CONFIG_MTK_CLKMGR) ++ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++ int_flag = BTIF_READ32(TX_DMA_INT_FLAG(base)); ++ enable = BTIF_READ32(TX_DMA_EN(base)); ++ stop = BTIF_READ32(TX_DMA_STOP(base)); ++ flush = BTIF_READ32(TX_DMA_FLUSH(base)); ++ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)); ++ rpt = BTIF_READ32(TX_DMA_VFF_RPT(base)); ++ int_buf = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); ++ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ ++ BTIF_INFO_FUNC("DMA's clock is on\n"); ++ BTIF_INFO_FUNC("Tx DMA's base address: 0x%lx\n", base); ++ ++ if (flag == REG_TX_DMA_ALL) { ++ BTIF_INFO_FUNC("TX_EN(:0x%x\n", enable); ++ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); ++ BTIF_INFO_FUNC("TX_STOP:0x%x\n", stop); ++ BTIF_INFO_FUNC("TX_FLUSH:0x%x\n", flush); ++ BTIF_INFO_FUNC("TX_WPT:0x%x\n", wpt); ++ BTIF_INFO_FUNC("TX_RPT:0x%x\n", rpt); ++ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); ++ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); ++ BTIF_INFO_FUNC("INT_EN:0x%x\n", ++ BTIF_READ32(TX_DMA_INT_EN(base))); ++ BTIF_INFO_FUNC("TX_RST:0x%x\n", BTIF_READ32(TX_DMA_RST(base))); ++ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_ADDR(base))); ++ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_LEN(base))); ++ BTIF_INFO_FUNC("TX_THRE:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_THRE(base))); ++ BTIF_INFO_FUNC("W_INT_BUF_SIZE:0x%x\n", ++ BTIF_READ32(TX_DMA_W_INT_BUF_SIZE(base))); ++ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", ++ BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base))); ++ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", ++ BTIF_READ32(TX_DMA_DEBUG_STATUS(base))); ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC("unknown flag:%d\n", flag); ++ } ++ BTIF_INFO_FUNC("tx dma %s\n", (enable & DMA_EN_BIT) && ++ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); ++ BTIF_INFO_FUNC("data in tx dma is %s sent by HW\n", ++ ((wpt == rpt) && ++ (int_buf == 0)) ? "completely" : "not completely"); ++ ++ return i_ret; ++} ++ ++static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ ENUM_BTIF_REG_ID flag) ++{ ++ int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int int_flag = 0; ++ unsigned int enable = 0; ++ unsigned int stop = 0; ++ unsigned int flush = 0; ++ unsigned int wpt = 0; ++ unsigned int rpt = 0; ++ unsigned int int_buf = 0; ++ unsigned int valid_size = 0; ++ /*unsigned long irq_flag = 0;*/ ++#if defined(CONFIG_MTK_CLKMGR) ++ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ ++ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++ BTIF_INFO_FUNC("dump DMA status register\n"); ++ _btif_dma_dump_dbg_reg(); ++ ++ int_flag = BTIF_READ32(RX_DMA_INT_FLAG(base)); ++ enable = BTIF_READ32(RX_DMA_EN(base)); ++ stop = BTIF_READ32(RX_DMA_STOP(base)); ++ flush = BTIF_READ32(RX_DMA_FLUSH(base)); ++ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); ++ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); ++ int_buf = BTIF_READ32(RX_DMA_INT_BUF_SIZE(base)); ++ valid_size = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ ++ BTIF_INFO_FUNC("DMA's clock is on\n"); ++ BTIF_INFO_FUNC("Rx DMA's base address: 0x%lx\n", base); ++ ++ if (flag == REG_RX_DMA_ALL) { ++ BTIF_INFO_FUNC("RX_EN(:0x%x\n", enable); ++ BTIF_INFO_FUNC("RX_STOP:0x%x\n", stop); ++ BTIF_INFO_FUNC("RX_FLUSH:0x%x\n", flush); ++ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); ++ BTIF_INFO_FUNC("RX_WPT:0x%x\n", wpt); ++ BTIF_INFO_FUNC("RX_RPT:0x%x\n", rpt); ++ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); ++ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); ++ BTIF_INFO_FUNC("INT_EN:0x%x\n", ++ BTIF_READ32(RX_DMA_INT_EN(base))); ++ BTIF_INFO_FUNC("RX_RST:0x%x\n", BTIF_READ32(RX_DMA_RST(base))); ++ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_ADDR(base))); ++ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_LEN(base))); ++ BTIF_INFO_FUNC("RX_THRE:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_THRE(base))); ++ BTIF_INFO_FUNC("RX_FLOW_CTRL_THRE:0x%x\n", ++ BTIF_READ32(RX_DMA_FLOW_CTRL_THRE(base))); ++ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", ++ BTIF_READ32(RX_DMA_VFF_LEFT_SIZE(base))); ++ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", ++ BTIF_READ32(RX_DMA_DEBUG_STATUS(base))); ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC("unknown flag:%d\n", flag); ++ } ++ BTIF_INFO_FUNC("rx dma %s\n", (enable & DMA_EN_BIT) && ++ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); ++ BTIF_INFO_FUNC("data in rx dma is %s by driver\n", ++ ((wpt == rpt) && ++ (int_buf == 0)) ? "received" : "not received"); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag) ++{ ++ unsigned int i_ret = -1; ++ ++ if (p_dma_info->dir == DMA_DIR_TX) ++ i_ret = hal_tx_dma_dump_reg(p_dma_info, flag); ++ else if (p_dma_info->dir == DMA_DIR_RX) ++ i_ret = hal_rx_dma_dump_reg(p_dma_info, flag); ++ else ++ BTIF_WARN_FUNC("unknown dir:%d\n", p_dma_info->dir); ++ ++ return i_ret; ++} ++ ++static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ unsigned int i_ret = -1; ++ unsigned long base = p_dma_info->base; ++ unsigned int stop = BTIF_READ32(TX_DMA_STOP(base)); ++ ++/*in MTK DMA BTIF channel we cannot set STOP and FLUSH bit at the same time*/ ++ if ((stop && DMA_STOP_BIT) != 0) ++ BTIF_ERR_FUNC("BTIF's DMA in stop state, omit flush operation\n"); ++ else { ++ BTIF_DBG_FUNC("flush tx dma\n"); ++ BTIF_SET_BIT(TX_DMA_FLUSH(base), DMA_FLUSH_BIT); ++ i_ret = 0; ++ } ++ return i_ret; ++} ++ ++static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info) ++{ ++ bool b_ret = true; ++ unsigned long base = p_dma_info->base; ++ ++/*see if flush operation is in process*/ ++ b_ret = ((DMA_FLUSH_BIT & BTIF_READ32(TX_DMA_FLUSH(base))) != 0) ? true : false; ++ ++ return b_ret; ++} ++ ++int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("op id: %d\n", opid); ++ switch (opid) { ++ case BTIF_PM_DPIDLE_EN: ++ i_ret = 0; ++ break; ++ case BTIF_PM_DPIDLE_DIS: ++ i_ret = 0; ++ break; ++ case BTIF_PM_SUSPEND: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESUME: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESTORE_NOIRQ:{ ++ unsigned int flag = 0; ++ P_MTK_BTIF_IRQ_STR p_irq = p_dma_info->p_irq; ++ ++#ifdef CONFIG_OF ++ flag = p_irq->irq_flags; ++#else ++ switch (p_irq->sens_type) { ++ case IRQ_SENS_EDGE: ++ if (p_irq->edge_type == IRQ_EDGE_FALL) ++ flag = IRQF_TRIGGER_FALLING; ++ else if (p_irq->edge_type == IRQ_EDGE_RAISE) ++ flag = IRQF_TRIGGER_RISING; ++ else if (p_irq->edge_type == IRQ_EDGE_BOTH) ++ flag = IRQF_TRIGGER_RISING | ++ IRQF_TRIGGER_FALLING; ++ else ++ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ ++ break; ++ case IRQ_SENS_LVL: ++ if (p_irq->lvl_type == IRQ_LVL_LOW) ++ flag = IRQF_TRIGGER_LOW; ++ else if (p_irq->lvl_type == IRQ_LVL_HIGH) ++ flag = IRQF_TRIGGER_HIGH; ++ else ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ default: ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ } ++#endif ++/* irq_set_irq_type(p_irq->irq_id, flag); */ ++ i_ret = 0; ++ } ++ i_ret = 0; ++ break; ++ default: ++ i_ret = ERR_INVALID_PAR; ++ break; ++ } ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_receive_data ++* DESCRIPTION ++* receive data from btif module in DMA polling mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++ unsigned int i_ret = -1; ++ ++ return i_ret; ++} ++#endif ++ ++int _btif_dma_dump_dbg_reg(void) ++{ ++#if 0 ++ static MTK_BTIF_DMA_REG_DMP_DBG g_dma_dbg_regs[] = { ++ {0x10201180, 0x0}, ++ {0x10201184, 0x0}, ++ {0x10201188, 0x0}, ++ {0x1020118C, 0x0}, ++ {0x10201190, 0x0}, ++ {0x1000320C, 0x0}, ++ {0x10003210, 0x0}, ++ {0x10003214, 0x0}, ++ }; ++ ++ int i = 0; ++ char *addr1 = NULL; ++ char *addr2 = NULL; ++ ++ int array_num = ARRAY_SIZE(g_dma_dbg_regs) ++ ++ addr1 = ioremap(g_dma_dbg_regs[0].reg_addr, 0x20); ++ if (addr1) { ++ for (i = 0; i < 5; i++) ++ g_dma_dbg_regs[i].reg_val = *(volatile unsigned int*)(addr1 + i*4); ++ iounmap(addr1); ++ } ++ ++ addr2 = ioremap(g_dma_dbg_regs[5].reg_addr, 0x10); ++ if (addr2) { ++ g_dma_dbg_regs[5].reg_val = *(volatile unsigned int*)(addr2); ++ g_dma_dbg_regs[6].reg_val = *(volatile unsigned int*)(addr2+4); ++ g_dma_dbg_regs[7].reg_val = *(volatile unsigned int*)(addr2+8); ++ iounmap(addr2); ++ } ++ ++ for (i = 0; i < array_num; i++) ++ BTIF_INFO_FUNC("-<0x%lx, 0x%08x>\n", g_dma_dbg_regs[i].reg_addr, g_dma_dbg_regs[i].reg_val); ++#endif ++ return 0; ++} ++ ++static void hal_btif_tx_dma_vff_set_for_4g(void) ++{ ++ BTIF_DBG_FUNC("Set btif tx_vff_addr bit29\n"); ++ BTIF_SET_BIT(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), DMA_VFF_BIT29_OFFSET); ++ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), ++ BTIF_READ32(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base))); ++} ++static void hal_btif_rx_dma_vff_set_for_4g(void) ++{ ++ BTIF_DBG_FUNC("Set btif rx_vff_addr bit29\n"); ++ BTIF_SET_BIT(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), DMA_VFF_BIT29_OFFSET); ++ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), ++ BTIF_READ32(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base))); ++} ++ +diff --git a/drivers/misc/mediatek/btif/common/btif_plat.c b/drivers/misc/mediatek/btif/common/btif_plat.c +new file mode 100644 +index 000000000000..e098e902317c +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/btif_plat.c +@@ -0,0 +1,1396 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF" ++ ++#define NEW_TX_HANDLING_SUPPORT 1 ++ ++#include "btif_pub.h" ++#include "btif_priv.h" ++ ++#define BTIF_USER_ID "btif_driver" ++ ++static spinlock_t g_clk_cg_spinlock; /*BTIF clock's spinlock */ ++ ++/*-----------------------------BTIF Module Clock and Power Control Defination------------------*/ ++ ++MTK_BTIF_IRQ_STR mtk_btif_irq = { ++ .name = "mtk btif irq", ++ .is_irq_sup = true, ++ .reg_flag = false, ++#ifdef CONFIG_OF ++ .irq_flags = IRQF_TRIGGER_NONE, ++#else ++ .irq_id = MT_BTIF_IRQ_ID, ++ .sens_type = IRQ_SENS_LVL, ++ .lvl_type = IRQ_LVL_LOW, ++#endif ++ .p_irq_handler = NULL, ++}; ++ ++/* ++ * will call clock manager's API export by WCP to control BTIF's clock, ++ * but we may need to access these registers in case of btif clock control logic is wrong in clock manager ++ */ ++ ++MTK_BTIF_INFO_STR mtk_btif = { ++#ifndef CONFIG_OF ++ .base = MTK_BTIF_REG_BASE, ++#endif ++ .p_irq = &mtk_btif_irq, ++ .tx_fifo_size = BTIF_TX_FIFO_SIZE, ++ .rx_fifo_size = BTIF_RX_FIFO_SIZE, ++ .tx_tri_lvl = BTIF_TX_FIFO_THRE, ++ .rx_tri_lvl = BTIF_RX_FIFO_THRE, ++ .rx_data_len = 0, ++ .p_tx_fifo = NULL, ++}; ++#if !(NEW_TX_HANDLING_SUPPORT) ++static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); ++#endif ++ ++static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, ++ const unsigned int max_len); ++static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_ier_ctrl ++* DESCRIPTION ++* BTIF Rx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if rx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_ier_ctrl ++* DESCRIPTION ++* BTIF Tx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if tx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++static int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* _btif_receive_data ++* DESCRIPTION ++* receive data from btif module in FIFO polling mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++static int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len); ++static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count); ++#endif ++ ++static int btif_dump_array(char *string, char *p_buf, int len) ++{ ++ unsigned int idx = 0; ++ unsigned char str[30]; ++ unsigned char *p_str; ++ ++ pr_debug("========dump %s start ========\n", string, len); ++ p_str = &str[0]; ++ for (idx = 0; idx < len; idx++, p_buf++) { ++ sprintf(p_str, "%02x ", *p_buf); ++ p_str += 3; ++ if (7 == (idx % 8)) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ p_str = &str[0]; ++ } ++ } ++ if (len % 8) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ } ++ pr_debug("========dump %s end========\n", string); ++ return 0; ++} ++ ++#if NEW_TX_HANDLING_SUPPORT ++static int _btif_tx_fifo_init(P_MTK_BTIF_INFO_STR p_btif_info) ++{ ++ int i_ret = -1; ++ ++ spin_lock_init(&(p_btif_info->tx_fifo_spinlock)); ++ ++ if (p_btif_info->p_tx_fifo == NULL) { ++ p_btif_info->p_tx_fifo = kzalloc(sizeof(struct kfifo), ++ GFP_ATOMIC); ++ if (p_btif_info->p_tx_fifo == NULL) { ++ i_ret = -ENOMEM; ++ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); ++ goto ret; ++ } ++ ++ i_ret = kfifo_alloc(p_btif_info->p_tx_fifo, ++ BTIF_HAL_TX_FIFO_SIZE, GFP_ATOMIC); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); ++ i_ret = -ENOMEM; ++ goto ret; ++ } ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC ++ ("p_btif_info->p_tx_fifo is already init p_btif_info->p_tx_fifo(0x%p)\n", ++ p_btif_info->p_tx_fifo); ++ i_ret = 0; ++ } ++ret: ++ return i_ret; ++} ++ ++static int _get_btif_tx_fifo_room(P_MTK_BTIF_INFO_STR p_btif_info) ++{ ++ int i_ret = 0; ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(p_btif_info->tx_fifo_spinlock), flag); ++ if (p_btif_info->p_tx_fifo == NULL) ++ i_ret = 0; ++ else ++ i_ret = kfifo_avail(p_btif_info->p_tx_fifo); ++ spin_unlock_irqrestore(&(p_btif_info->tx_fifo_spinlock), flag); ++ BTIF_DBG_FUNC("tx kfifo:0x%p, available room:%d\n", p_btif_info->p_tx_fifo, i_ret); ++ return i_ret; ++} ++ ++static int _btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif_info) ++{ ++ int i_ret = 0; ++ ++ if (p_btif_info->p_tx_fifo != NULL) ++ kfifo_reset(p_btif_info->p_tx_fifo); ++ return i_ret; ++} ++ ++#endif ++ ++#ifdef CONFIG_OF ++static void _btif_set_default_setting(void) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = {0, 0, 0}; ++ unsigned int phy_base; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,mtk-btif"); ++ if (node) { ++ mtk_btif.p_irq->irq_id = irq_of_parse_and_map(node, 0); ++ /*fixme, be compitable arch 64bits*/ ++ mtk_btif.base = (unsigned long)of_iomap(node, 0); ++ BTIF_INFO_FUNC("get btif irq(%d),register base(0x%lx)\n", ++ mtk_btif.p_irq->irq_id, mtk_btif.base); ++ } else { ++ BTIF_ERR_FUNC("get btif device node fail\n"); ++ } ++ ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); ++ } else { ++ mtk_btif.p_irq->irq_flags = irq_info[2]; ++ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", mtk_btif.p_irq->irq_flags); ++ } ++ ++ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) ++ BTIF_ERR_FUNC("get register phy base from DTS fail\n"); ++ else ++ BTIF_INFO_FUNC("get register phy base(0x%x)\n", (unsigned int)phy_base); ++} ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_info_get ++* DESCRIPTION ++* get btif's information included base address , irq related information ++* PARAMETERS ++* RETURNS ++* BTIF's information ++*****************************************************************************/ ++P_MTK_BTIF_INFO_STR hal_btif_info_get(void) ++{ ++#if NEW_TX_HANDLING_SUPPORT ++ int i_ret = 0; ++/*tx fifo and fifo lock init*/ ++ i_ret = _btif_tx_fifo_init(&mtk_btif); ++ if (i_ret == 0) ++ BTIF_INFO_FUNC("_btif_tx_fifo_init succeed\n"); ++ else ++ BTIF_ERR_FUNC("_btif_tx_fifo_init failed, i_ret:%d\n", i_ret); ++ ++#endif ++ ++#ifdef CONFIG_OF ++ _btif_set_default_setting(); ++#endif ++ ++ spin_lock_init(&g_clk_cg_spinlock); ++ ++ return &mtk_btif; ++} ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_get_and_prepare ++* DESCRIPTION ++* get clock from device tree and prepare for enable/disable control ++* PARAMETERS ++* pdev device pointer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++#if !defined(CONFIG_MTK_CLKMGR) ++int hal_btif_clk_get_and_prepare(struct platform_device *pdev) ++{ ++ int i_ret = -1; ++ ++ clk_btif = devm_clk_get(&pdev->dev, "main"); ++ if (IS_ERR(clk_btif)) { ++ BTIF_ERR_FUNC("[CCF]cannot get clk_btif clock.\n"); ++ return PTR_ERR(clk_btif); ++ } ++ BTIF_ERR_FUNC("[CCF]clk_btif=%p\n", clk_btif); ++ clk_btif_apdma = devm_clk_get(&pdev->dev, "apdmac"); ++ if (IS_ERR(clk_btif_apdma)) { ++ BTIF_ERR_FUNC("[CCF]cannot get clk_btif_apdma clock.\n"); ++ return PTR_ERR(clk_btif_apdma); ++ } ++ BTIF_ERR_FUNC("[CCF]clk_btif_apdma=%p\n", clk_btif_apdma); ++ ++ i_ret = clk_prepare(clk_btif); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("clk_prepare clk_btif failed! ret:%d\n", i_ret); ++ return i_ret; ++ } ++ ++ i_ret = clk_prepare(clk_btif_apdma); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("clk_prepare clk_btif_apdma failed! ret:%d\n", i_ret); ++ return i_ret; ++ } ++ return i_ret; ++} ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_unprepare ++* DESCRIPTION ++* unprepare btif clock and apdma clock ++* PARAMETERS ++* none ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_unprepare(void) ++{ ++ clk_unprepare(clk_btif); ++ clk_unprepare(clk_btif_apdma); ++ return 0; ++} ++#endif ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of BTIF module ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag) ++{ ++/*In MTK BTIF, there's only one global CG on AP_DMA, no sub channel's CG bit*/ ++/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ ++ int i_ret = 0; ++ unsigned long irq_flag = 0; ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ static atomic_t s_clk_ref = ATOMIC_INIT(0); ++#else ++ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; ++#endif ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_CTL ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++ if (flag == CLK_OUT_ENABLE) { ++ if (atomic_inc_return(&s_clk_ref) == 1) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); ++ i_ret = clk_enable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++ if (atomic_dec_return(&s_clk_ref) == 0) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); ++ clk_disable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ ++#else ++ ++ if (status == flag) { ++ i_ret = 0; ++ BTIF_DBG_FUNC("btif clock already %s\n", ++ CLK_OUT_ENABLE == ++ status ? "enabled" : "disabled"); ++ } else { ++ if (flag == CLK_OUT_ENABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++#else ++ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); ++ i_ret = clk_enable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++ } else if (flag == CLK_OUT_DISABLE) { ++#if defined(CONFIG_MTK_CLKMGR) ++ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); ++ status = (i_ret == 0) ? flag : status; ++ if (i_ret) { ++ BTIF_WARN_FUNC ++ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", ++ i_ret); ++ } ++#else ++ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); ++ clk_disable(clk_btif); ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ } else { ++ i_ret = ERR_INVALID_PAR; ++ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); ++ } ++ } ++#endif ++ ++#else ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ ++#else ++ ++ status = flag; ++#endif ++ ++ i_ret = 0; ++#endif ++ ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#else ++ ++ if (i_ret == 0) { ++ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); ++ } else { ++ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", ++ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); ++ } ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++ BTIF_DBG_FUNC("BTIF's clock is %s\n", (clock_is_on(MTK_BTIF_CG_BIT) == 0) ? "off" : "on"); ++#endif ++ return i_ret; ++} ++ ++static int btif_new_handshake_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool enable) ++{ ++ unsigned long base = p_btif->base; ++ ++ if (enable == true) ++ BTIF_SET_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); ++ else ++ BTIF_CLR_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); ++ return true; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_hw_init ++* DESCRIPTION ++* BTIF hardware init ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++#if NEW_TX_HANDLING_SUPPORT ++ _btif_tx_fifo_reset(p_btif); ++#endif ++ ++/*set to normal mode*/ ++ btif_reg_sync_writel(BTIF_FAKELCR_NORMAL_MODE, BTIF_FAKELCR(base)); ++/*set to newhandshake mode*/ ++ btif_new_handshake_ctrl(p_btif, true); ++/*No need to access: enable sleep mode*/ ++/*No need to access: set Rx timeout count*/ ++/*set Tx threshold*/ ++/*set Rx threshold*/ ++/*disable internal loopback test*/ ++ ++/*set Rx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++/*clear Rx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++/*set Tx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++/*clear Tx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++ ++ btif_reg_sync_writel(BTIF_TRI_LVL_TX(p_btif->tx_tri_lvl) ++ | BTIF_TRI_LVL_RX(p_btif->rx_tri_lvl) ++ | BTIF_TRI_LOOP_DIS, BTIF_TRI_LVL(base)); ++ hal_btif_loopback_ctrl(p_btif, false); ++/*disable BTIF Tx DMA mode*/ ++ hal_btif_tx_mode_ctrl(p_btif, false); ++/*disable BTIF Rx DMA mode*/ ++ hal_btif_rx_mode_ctrl(p_btif, false); ++/*auto reset*/ ++ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_AUTORST_EN); ++/*disable Tx IER*/ ++ hal_btif_tx_ier_ctrl(p_btif, false); ++/*enable Rx IER by default*/ ++ hal_btif_rx_ier_ctrl(p_btif, true); ++ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_ier_ctrl ++* DESCRIPTION ++* BTIF Rx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if rx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_RXFEN); ++ else ++ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_RXFEN); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_ier_ctrl ++* DESCRIPTION ++* BTIF Tx interrupt enable/disable ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* enable [IN] control if tx interrupt enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_TXEEN); ++ else ++ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_TXEEN); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++ i_ret = 0; ++ ++ return i_ret; ++} ++ ++#ifndef MTK_BTIF_MARK_UNUSED_API ++ ++/***************************************************************************** ++* FUNCTION ++* _btif_receive_data ++* DESCRIPTION ++* receive data from btif module in FIFO polling mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* positive means data is available, 0 means no data available ++*****************************************************************************/ ++int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ ++/*check parameter valid or not*/ ++ if ((p_buf == NULL) || (max_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ return i_ret; ++ } ++ i_ret = btif_rx_irq_handler(p_btif, p_buf, max_len); ++ ++ return i_ret; ++} ++ ++int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); ++ else ++ BTIF_SET_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ unsigned int value = 0; ++ ++/*read BTIF_TRI_LVL*/ ++ value = BTIF_READ32(BTIF_TRI_LVL(base)); ++/*clear Tx threshold bits*/ ++ value &= (~BTIF_TRI_LVL_TX_MASK); ++/*set tx threshold bits*/ ++ value |= BTIF_TRI_LVL_TX(BTIF_TX_FIFO_THRE); ++/*write back to BTIF_TRI_LVL*/ ++ btif_reg_sync_writel(value, BTIF_TRI_LVL(base)); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_rx_fifo_reset ++* DESCRIPTION ++* reset BTIF's rx fifo ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* ec [IN] control if loopback mode is enabled or not ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int btif_rx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++/*set Rx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++ ++/*clear Rx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_tx_fifo_reset ++* DESCRIPTION ++* reset BTIF's tx fifo ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++/*set Tx FIFO clear bit to 1*/ ++ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++ ++/*clear Tx FIFO clear bit to 0*/ ++ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_loopback_ctrl ++* DESCRIPTION ++* BTIF Tx/Rx loopback mode set, this operation can only be done after set BTIF to normal mode ++* PARAMETERS ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (en == false) ++ BTIF_CLR_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); ++ else ++ BTIF_SET_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); ++ ++/*TODO:do we need to read back ? Answer: no*/ ++/*TODO:do we need to dsb?*/ ++ i_ret = 0; ++ return i_ret; ++} ++ ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_handler ++* DESCRIPTION ++* lower level interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success; negative means fail; positive means rx data length ++*****************************************************************************/ ++int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ unsigned int iir = 0; ++ unsigned int rx_len = 0; ++ unsigned long base = p_btif->base; ++ ++#if 0 ++/*check parameter valid or not*/ ++ if ((p_buf == NULL) || (max_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ return i_ret; ++ } ++#endif ++ unsigned long irq_flag = 0; ++ ++ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); ++ ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*read interrupt identifier register*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ ++/*is rx interrupt exist?*/ ++#if 0 ++ while ((iir & BTIF_IIR_RX) && (rx_len < max_len)) { ++ rx_len += ++ btif_rx_irq_handler(p_btif, (p_buf + rx_len), ++ (max_len - rx_len)); ++ ++/*update IIR*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ } ++#endif ++ ++ while (iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) { ++ rx_len += btif_rx_irq_handler(p_btif, p_buf, max_len); ++ ++/*update IIR*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ } ++ ++/*is tx interrupt exist?*/ ++ if (iir & BTIF_IIR_TX_EMPTY) ++ i_ret = btif_tx_irq_handler(p_btif); ++ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); ++ ++ i_ret = rx_len != 0 ? rx_len : i_ret; ++ return i_ret; ++} ++ ++int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, btif_rx_buf_write rx_cb) ++{ ++ if (p_btif_info->rx_cb != NULL) ++ BTIF_DBG_FUNC("rx_cb already registered, replace (0x%p) with (0x%p)\n", ++ p_btif_info->rx_cb, rx_cb); ++ p_btif_info->rx_cb = rx_cb; ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_rx_irq_handler ++* DESCRIPTION ++* lower level rx interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* positive means length of rx data , negative means fail ++*****************************************************************************/ ++static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, const unsigned int max_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = 0; ++ unsigned int iir = 0; ++ unsigned int rx_len = 0; ++ unsigned long base = p_btif_info->base; ++ unsigned char rx_buf[256]; ++ unsigned int local_buf_len = 256; ++ btif_rx_buf_write rx_cb = p_btif_info->rx_cb; ++ unsigned int total_len = 0; ++ ++/*read interrupt identifier register*/ ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ while ((iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) && ++ (rx_len < local_buf_len)) { ++ rx_buf[rx_len] = BTIF_READ8(base); ++ rx_len++; ++/*need to consult CC Hwang for advice */ ++/* ++ * whether we need to do memory barrier here ++ * Ans: no ++ */ ++/* ++ * whether we need to d memory barrier when call BTIF_SET_BIT or BTIF_CLR_BIT ++ * Ans: no ++ */ ++ if (rx_len == local_buf_len) { ++ if (rx_cb) ++ (*rx_cb) (p_btif_info, rx_buf, rx_len); ++ rx_len = 0; ++ total_len += rx_len; ++ } ++ iir = BTIF_READ32(BTIF_IIR(base)); ++ } ++ total_len += rx_len; ++ if (rx_len && rx_cb) ++ (*rx_cb) (p_btif_info, rx_buf, rx_len); ++ ++/* ++ * make sure all data write back to memory, mb or dsb? ++ * need to consult CC Hwang for advice ++ * Ans: no need here ++ */ ++ i_ret = total_len; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* btif_tx_irq_handler ++* DESCRIPTION ++* lower level tx interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif) ++{ ++ int i_ret = -1; ++ ++#if NEW_TX_HANDLING_SUPPORT ++ int how_many = 0; ++ unsigned int lsr; ++ unsigned int ava_len = 0; ++ unsigned long base = p_btif->base; ++ char local_buf[BTIF_TX_FIFO_SIZE]; ++ char *p_data = local_buf; ++ unsigned long flag = 0; ++ ++ struct kfifo *p_tx_fifo = p_btif->p_tx_fifo; ++ ++/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ ++ if (lsr & BTIF_LSR_TEMT_BIT) ++ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE; ++ else if (lsr & BTIF_LSR_THRE_BIT) ++ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; ++ else { ++ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ ++ ava_len = 0; ++ goto ret; ++ } ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); ++ how_many = kfifo_out(p_tx_fifo, local_buf, ava_len); ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); ++ BTIF_DBG_FUNC("BTIF tx size %d done, left:%d\n", how_many, ++ kfifo_avail(p_tx_fifo)); ++ while (how_many--) ++ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); ++ ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); ++/*clear Tx enable flag if necessary*/ ++ if (kfifo_is_empty(p_tx_fifo)) { ++ hal_btif_tx_ier_ctrl(p_btif, false); ++ BTIF_DBG_FUNC("BTIF tx FIFO is empty\n"); ++ } ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); ++ret: ++#else ++/*clear Tx enable flag*/ ++ hal_btif_tx_ier_ctrl(p_btif, false); ++#endif ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_mode_ctrl ++* DESCRIPTION ++* set BTIF tx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (mode == BTIF_MODE_DMA) ++ /*set to DMA mode*/ ++ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); ++ else ++ /*set to PIO mode*/ ++ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); ++ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_mode_ctrl ++* DESCRIPTION ++* set BTIF rx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++ ++ if (mode == BTIF_MODE_DMA) ++ /*set to DMA mode*/ ++ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); ++ else ++ /*set to PIO mode*/ ++ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); ++ ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_send_data ++* DESCRIPTION ++* send data through btif in FIFO mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* positive means number of data sent; 0 means no data put to FIFO; negative means error happens ++*****************************************************************************/ ++int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, ++ const unsigned char *p_buf, const unsigned int buf_len) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ ++ unsigned int ava_len = 0; ++ unsigned int sent_len = 0; ++ ++#if !(NEW_TX_HANDLING_SUPPORT) ++ unsigned long base = p_btif->base; ++ unsigned int lsr = 0; ++ unsigned int left_len = 0; ++ unsigned char *p_data = (unsigned char *)p_buf; ++#endif ++ ++/*check parameter valid or not*/ ++ if ((p_buf == NULL) || (buf_len == 0)) { ++ i_ret = ERR_INVALID_PAR; ++ return i_ret; ++ } ++#if NEW_TX_HANDLING_SUPPORT ++ ava_len = _get_btif_tx_fifo_room(p_btif); ++ sent_len = buf_len <= ava_len ? buf_len : ava_len; ++ if (sent_len > 0) { ++ int enqueue_len = 0; ++ unsigned long flag = 0; ++ ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); ++ enqueue_len = kfifo_in(p_btif->p_tx_fifo, ++ (unsigned char *)p_buf, sent_len); ++ if (sent_len != enqueue_len) { ++ BTIF_ERR_FUNC("target tx len:%d, len sent:%d\n", ++ sent_len, enqueue_len); ++ } ++ i_ret = enqueue_len; ++ mb(); ++/*enable BTIF Tx IRQ*/ ++ hal_btif_tx_ier_ctrl(p_btif, true); ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); ++ BTIF_DBG_FUNC("enqueue len:%d\n", enqueue_len); ++ } else { ++ i_ret = 0; ++ } ++#else ++ while ((_btif_is_tx_allow(p_btif)) && (sent_len < buf_len)) { ++ /*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ ++ if (lsr & BTIF_LSR_TEMT_BIT) ++ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE; ++ else if (lsr & BTIF_LSR_THRE_BIT) ++ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ ++ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; ++ else { ++ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ ++ ava_len = 0; ++ break; ++ } ++ ++ left_len = buf_len - sent_len; ++/*ava_len will be real length will write to BTIF THR*/ ++ ava_len = ava_len > left_len ? left_len : ava_len; ++/*update sent length valud after this operation*/ ++ sent_len += ava_len; ++/* ++ * whether we need memory barrier here? ++ * Ans: No, no memory ordering issue exist, ++ * CPU will make sure logically right ++ */ ++ while (ava_len--) ++ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); ++ ++ } ++/* while ((hal_btif_is_tx_allow()) && (sent_len < buf_len)); */ ++ ++ i_ret = sent_len; ++ ++/*enable BTIF Tx IRQ*/ ++ hal_btif_tx_ier_ctrl(p_btif, true); ++#endif ++ return i_ret; ++} ++ ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_raise_wak_sig ++* DESCRIPTION ++* raise wakeup signal to counterpart ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif) ++{ ++ int i_ret = -1; ++ unsigned long base = p_btif->base; ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { ++ BTIF_ERR_FUNC("%s: clock is off before send wakeup signal!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++/*write 0 to BTIF_WAK to pull ap_wakeup_consyss low */ ++ BTIF_CLR_BIT(BTIF_WAK(base), BTIF_WAK_BIT); ++ ++/*wait for a period for longer than 1/32k period, here we use 40us*/ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ usleep_range(128, 160); ++/* ++ * according to linux/documentation/timers/timers-how-to, we choose usleep_range ++ * SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms): * Use usleep_range ++ */ ++/*write 1 to pull ap_wakeup_consyss high*/ ++ BTIF_SET_BIT(BTIF_WAK(base), BTIF_WAK_BIT); ++ i_ret = 0; ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag) ++{ ++/*Chaozhong: To be implement*/ ++ int i_ret = -1; ++ int idx = 0; ++ /*unsigned long irq_flag = 0;*/ ++ unsigned long base = p_btif->base; ++ unsigned char reg_map[0xE0 / 4] = { 0 }; ++ unsigned int lsr = 0x0; ++ unsigned int dma_en = 0; ++ ++ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ ++#if defined(CONFIG_MTK_CLKMGR) ++ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", ++ __FILE__); ++ return i_ret; ++ } ++#endif ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ dma_en = BTIF_READ32(BTIF_DMA_EN(base)); ++ /* ++ * here we omit 1st register which is THR/RBR register to avoid ++ * Rx data read by this debug information accidently ++ */ ++ for (idx = 1; idx < sizeof(reg_map); idx++) ++ reg_map[idx] = BTIF_READ8(p_btif->base + (4 * idx)); ++ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ ++ BTIF_INFO_FUNC("BTIF's clock is on\n"); ++ BTIF_INFO_FUNC("base address: 0x%lx\n", base); ++ switch (flag) { ++ case REG_BTIF_ALL: ++#if 0 ++ BTIF_INFO_FUNC("BTIF_IER:0x%x\n", BTIF_READ32(BTIF_IER(base))); ++ BTIF_INFO_FUNC("BTIF_IIR:0x%x\n", BTIF_READ32(BTIF_IIR(base))); ++ BTIF_INFO_FUNC("BTIF_FAKELCR:0x%x\n", ++ BTIF_READ32(BTIF_FAKELCR(base))); ++ BTIF_INFO_FUNC("BTIF_LSR:0x%x\n", BTIF_READ32(BTIF_LSR(base))); ++ BTIF_INFO_FUNC("BTIF_SLEEP_EN:0x%x\n", ++ BTIF_READ32(BTIF_SLEEP_EN(base))); ++ BTIF_INFO_FUNC("BTIF_DMA_EN:0x%x\n", ++ BTIF_READ32(BTIF_DMA_EN(base))); ++ BTIF_INFO_FUNC("BTIF_RTOCNT:0x%x\n", ++ BTIF_READ32(BTIF_RTOCNT(base))); ++ BTIF_INFO_FUNC("BTIF_TRI_LVL:0x%x\n", ++ BTIF_READ32(BTIF_TRI_LVL(base))); ++ BTIF_INFO_FUNC("BTIF_WAT_TIME:0x%x\n", ++ BTIF_READ32(BTIF_WAT_TIME(base))); ++ BTIF_INFO_FUNC("BTIF_HANDSHAKE:0x%x\n", ++ BTIF_READ32(BTIF_HANDSHAKE(base))); ++#endif ++ btif_dump_array("BTIF register", reg_map, sizeof(reg_map)); ++ break; ++ default: ++ break; ++ } ++ ++ BTIF_INFO_FUNC("Tx DMA %s\n", ++ (dma_en & BTIF_DMA_EN_TX) ? "enabled" : "disabled"); ++ BTIF_INFO_FUNC("Rx DMA %s\n", ++ (dma_en & BTIF_DMA_EN_RX) ? "enabled" : "disabled"); ++ ++ BTIF_INFO_FUNC("Rx data is %s\n", ++ (lsr & BTIF_LSR_DR_BIT) ? "not empty" : "empty"); ++ BTIF_INFO_FUNC("Tx data is %s\n", ++ (lsr & BTIF_LSR_TEMT_BIT) ? "empty" : "not empty"); ++ ++ return i_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ bool b_ret = false; ++ unsigned int lsr = 0; ++ unsigned long flags = 0; ++ unsigned long base = p_btif->base; ++ unsigned int tx_empty = 0; ++ unsigned int rx_dr = 0; ++ unsigned int tx_irq_disable = 0; ++ ++/* ++ * 3 conditions allow clock to be disable ++ * 1. if TEMT is set or not ++ * 2. if DR is set or not ++ * 3. Tx IRQ is disabled or not ++ */ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ tx_empty = lsr & BTIF_LSR_TEMT_BIT; ++ rx_dr = lsr & BTIF_LSR_DR_BIT; ++ tx_irq_disable = BTIF_READ32(BTIF_IER(base)) & BTIF_IER_TXEEN; ++ ++ b_ret = ++ (tx_empty && (tx_irq_disable == 0) && (rx_dr == 0)) ? true : false; ++ if (!b_ret) { ++ BTIF_DBG_FUNC ++ ("BTIF flag, tx_empty:%d, rx_dr:%d, tx_irq_disable:%d\n", ++ tx_empty, rx_dr, tx_irq_disable); ++ } ++#if NEW_TX_HANDLING_SUPPORT ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); ++/*clear Tx enable flag if necessary*/ ++ if (!(kfifo_is_empty(p_btif->p_tx_fifo))) { ++ BTIF_DBG_FUNC("BTIF tx FIFO is not empty\n"); ++ b_ret = false; ++ } ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); ++#endif ++ return b_ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_allow ++* DESCRIPTION ++* whether tx is allowed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) ++{ ++#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) ++#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) ++ ++/*Chaozhong: To be implement*/ ++ bool b_ret = false; ++ ++#if NEW_TX_HANDLING_SUPPORT ++ unsigned long flags = 0; ++ ++ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); ++/*clear Tx enable flag if necessary*/ ++ if (kfifo_is_full(p_btif->p_tx_fifo)) { ++ BTIF_WARN_FUNC("BTIF tx FIFO is full\n"); ++ b_ret = false; ++ } else { ++ b_ret = true; ++ } ++ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); ++#else ++ unsigned int lsr = 0; ++ unsigned long base = p_btif->base; ++ unsigned int wait_us = (BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE) / MIN_TX_MB; /*only ava length */ ++ ++/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ ++ if (!(lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT))) { ++ BTIF_DBG_FUNC("wait for %d ~ %d us\n", wait_us, 3 * wait_us); ++/* usleep_range(wait_us, 3 * 10 * wait_us); */ ++ usleep_range(wait_us, 3 * wait_us); ++ } ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; ++ if (!b_ret) ++ BTIF_DBG_FUNC(" tx is not allowed for the moment\n"); ++ else ++ BTIF_DBG_FUNC(" tx is allowed\n"); ++#endif ++ return b_ret; ++} ++ ++#if !(NEW_TX_HANDLING_SUPPORT) ++ ++static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) ++{ ++/*Chaozhong: To be implement*/ ++ bool b_ret = false; ++ unsigned long base = p_btif->base; ++ unsigned int lsr = 0; ++ ++/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ ++ lsr = BTIF_READ32(BTIF_LSR(base)); ++ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; ++ return b_ret; ++} ++#endif ++ ++int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif_info, MTK_BTIF_PM_OPID opid) ++{ ++ int i_ret = -1; ++ ++ BTIF_DBG_FUNC("op id: %d\n", opid); ++ switch (opid) { ++ case BTIF_PM_DPIDLE_EN: ++ i_ret = 0; ++ break; ++ case BTIF_PM_DPIDLE_DIS: ++ i_ret = 0; ++ break; ++ case BTIF_PM_SUSPEND: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESUME: ++ i_ret = 0; ++ break; ++ case BTIF_PM_RESTORE_NOIRQ:{ ++ unsigned int flag = 0; ++ P_MTK_BTIF_IRQ_STR p_irq = p_btif_info->p_irq; ++ ++#ifdef CONFIG_OF ++ flag = p_irq->irq_flags; ++#else ++ switch (p_irq->sens_type) { ++ case IRQ_SENS_EDGE: ++ if (p_irq->edge_type == IRQ_EDGE_FALL) ++ flag = IRQF_TRIGGER_FALLING; ++ else if (p_irq->edge_type == IRQ_EDGE_RAISE) ++ flag = IRQF_TRIGGER_RISING; ++ else if (p_irq->edge_type == IRQ_EDGE_BOTH) ++ flag = IRQF_TRIGGER_RISING | ++ IRQF_TRIGGER_FALLING; ++ else ++ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ ++ break; ++ case IRQ_SENS_LVL: ++ if (p_irq->lvl_type == IRQ_LVL_LOW) ++ flag = IRQF_TRIGGER_LOW; ++ else if (p_irq->lvl_type == IRQ_LVL_HIGH) ++ flag = IRQF_TRIGGER_HIGH; ++ else ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ default: ++ flag = IRQF_TRIGGER_LOW; /*make this as default type */ ++ break; ++ } ++#endif ++/* irq_set_irq_type(p_irq->irq_id, flag); */ ++ i_ret = 0; ++ } ++ break; ++ default: ++ i_ret = ERR_INVALID_PAR; ++ break; ++ } ++ ++ return i_ret; ++} ++void mtk_btif_read_cpu_sw_rst_debug_plat(void) ++{ ++#define CONSYS_AP2CONN_WAKEUP_OFFSET 0x00000064 ++ BTIF_WARN_FUNC("+CONSYS_AP2CONN_WAKEUP_OFFSET(0x%x)\n", ++ BTIF_READ32(mtk_btif.base + CONSYS_AP2CONN_WAKEUP_OFFSET)); ++} ++ +diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h +new file mode 100644 +index 000000000000..5e2f5a9857d9 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h +@@ -0,0 +1,370 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_BTIF_H_ ++#define __MTK_BTIF_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* gettimeofday */ ++#include ++ ++#include "btif_pub.h" ++#include "btif_dma_pub.h" ++#include "mtk_btif_exp.h" ++ ++#define BTIF_PORT_NR 1 ++#define BTIF_USER_NAME_MAX_LEN 32 ++ ++/*-------------Register Defination Start ---------------*/ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) ++#define BTIF_RX_BUFFER_SIZE (1024 * 32) ++#else ++#define BTIF_RX_BUFFER_SIZE (1024 * 64) ++#endif ++#define BTIF_TX_FIFO_SIZE (1024 * 4) ++ ++/*------------Register Defination End ----------------*/ ++ ++/*------------BTIF Module Clock and Power Control Defination---------------*/ ++typedef enum _ENUM_BTIF_RX_TYPE_ { ++ BTIF_IRQ_CTX = 0, ++ BTIF_TASKLET_CTX = BTIF_IRQ_CTX + 1, ++ BTIF_THREAD_CTX = BTIF_TASKLET_CTX + 1, ++ BTIF_WQ_CTX = BTIF_THREAD_CTX + 1, ++ BTIF_RX_TYPE_MAX, ++} ENUM_BTIF_RX_TYPE; ++ ++typedef enum _ENUM_BTIF_TX_TYPE_ { ++ BTIF_TX_USER_CTX = 0, ++ BTIF_TX_SINGLE_CTX = BTIF_TX_USER_CTX + 1, ++ BTIF_TX_TYPE_MAX, ++} ENUM_BTIF_TX_TYPE; ++ ++typedef enum _ENUM_BTIF_STATE_ { ++ B_S_OFF = 0, ++ B_S_SUSPEND = B_S_OFF + 1, ++ B_S_DPIDLE = B_S_SUSPEND + 1, ++ B_S_ON = B_S_DPIDLE + 1, ++ B_S_MAX, ++} ENUM_BTIF_STATE; ++ ++#define ENABLE_BTIF_RX_DMA 1 ++#define ENABLE_BTIF_TX_DMA 1 ++ ++#if ENABLE_BTIF_TX_DMA ++#define BTIF_TX_MODE BTIF_MODE_DMA ++#else ++#define BTIF_TX_MODE BTIF_MODE_PIO ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++#define BTIF_RX_MODE BTIF_MODE_DMA ++#else ++#define BTIF_RX_MODE BTIF_MODE_PIO ++#endif ++ ++#define BTIF_RX_BTM_CTX BTIF_THREAD_CTX/*BTIF_WQ_CTX*//* BTIF_TASKLET_CTX */ ++/* ++ * -- cannot be used because , ++ * mtk_wcn_stp_parser data will call *(stp_if_tx) to send ack, ++ * in which context sleepable lock or usleep operation may be used, ++ * these operation is not allowed in tasklet, may cause schedule_bug ++ */ ++ ++#define BTIF_TX_CTX BTIF_TX_USER_CTX /* BTIF_TX_SINGLE_CTX */ ++ ++#define ENABLE_BTIF_RX_THREAD_RT_SCHED 0 ++#define MAX_BTIF_RXD_TIME_REC 3 ++ ++/*Structure Defination*/ ++ ++/*-----------------BTIF setting--------------*/ ++typedef struct _mtk_btif_setting_ { ++ ENUM_BTIF_MODE tx_mode; /*BTIF Tx Mode Setting */ ++ ENUM_BTIF_MODE rx_mode; /*BTIF Tx Mode Setting */ ++ ENUM_BTIF_RX_TYPE rx_type; /*rx handle type */ ++ ENUM_BTIF_TX_TYPE tx_type; /*tx type */ ++} mtk_btif_setting, *p_mtk_btif_setting; ++/*---------------------------------------------------------------------------*/ ++ ++#if 0 ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_register_ { ++ unsigned int iir; /*Interrupt Identification Register */ ++ unsigned int lsr; /*Line Status Register */ ++ unsigned int fake_lcr; /*Fake Lcr Regiseter */ ++ unsigned int fifo_ctrl; /*FIFO Control Register */ ++ unsigned int ier; /*Interrupt Enable Register */ ++ unsigned int sleep_en; /*Sleep Enable Register */ ++ unsigned int rto_counter; /*Rx Timeout Counter Register */ ++ unsigned int dma_en; /*DMA Enalbe Register */ ++ unsigned int tri_lvl; /*Tx/Rx Trigger Level Register */ ++ unsigned int wat_time; /*Async Wait Time Register */ ++ unsigned int handshake; /*New HandShake Mode Register */ ++ unsigned int sleep_wak; /*Sleep Wakeup Reigster */ ++} mtk_btif_register, *p_mtk_btif_register; ++/*---------------------------------------------------------------------------*/ ++ ++#endif ++ ++typedef struct _btif_buf_str_ { ++ unsigned int size; ++ unsigned char *p_buf; ++ /* ++ * For Tx: next Tx data pointer to FIFO; ++ * For Rx: next read data pointer from BTIF user ++ */ ++ unsigned int rd_idx; ++ /* ++ * For Tx: next Tx data pointer from BTIF user; ++ * For Rx: next write data(from FIFO) pointer ++ */ ++ unsigned int wr_idx; ++} btif_buf_str, *p_btif_buf_str; ++ ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_dma_ { ++ /*p_mtk_btif*/ void *p_btif; ++ /*BTIF pointer to which DMA belongs */ ++ ++#if 0 ++ unsigned int channel; /*DMA's channel */ ++#endif ++ ++ ENUM_BTIF_DIR dir; /*DMA's direction: */ ++ bool enable; /*DMA enable or disable flag */ ++ ++ P_MTK_DMA_INFO_STR p_dma_info; /*DMA's IRQ information */ ++ ++#if 0 ++ mtk_dma_register register; /*DMA's register */ ++#endif ++ ++ spinlock_t iolock; /*io lock for DMA channel */ ++ atomic_t entry; /* entry count */ ++} mtk_btif_dma, *p_mtk_btif_dma; ++ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) ++#define BTIF_LOG_ENTRY_NUM 10 ++#else ++#define BTIF_LOG_ENTRY_NUM 30 ++#endif ++ ++#define BTIF_LOG_SZ 1536 ++ ++typedef void (*MTK_BTIF_RX_NOTIFY) (void); ++ ++typedef struct _btif_log_buf_t_ { ++ unsigned int len; ++ struct timeval timer; ++ unsigned char buffer[BTIF_LOG_SZ]; ++} BTIF_LOG_BUF_T, *P_BTIF_LOG_BUF_T; ++ ++typedef struct _btif_log_queue_t_ { ++ ENUM_BTIF_DIR dir; ++ bool enable; ++ bool output_flag; ++ unsigned int in; ++ unsigned int out; ++ unsigned int size; ++ spinlock_t lock; ++ P_BTIF_LOG_BUF_T p_queue[BTIF_LOG_ENTRY_NUM]; ++} BTIF_LOG_QUEUE_T, *P_BTIF_LOG_QUEUE_T; ++ ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_ { ++ unsigned int open_counter; /*open counter */ ++ bool enable; /*BTIF module enable flag */ ++ bool lpbk_flag; /*BTIF module enable flag */ ++#if 0 ++ unsigned long base; /* BTIF controller base address */ ++#endif ++ ++ ENUM_BTIF_STATE state; /*BTIF state mechanism */ ++ struct mutex state_mtx; /*lock to BTIF state mechanism's state change */ ++ struct mutex ops_mtx; /*lock to BTIF's open and close */ ++ ++#if 0 ++ mtk_btif_register register; /*BTIF registers */ ++#endif ++ ++ ENUM_BTIF_MODE tx_mode; /* BTIF Tx channel mode */ ++ ENUM_BTIF_MODE rx_mode; /* BTIF Rx channel mode */ ++ struct mutex tx_mtx; /*lock to BTIF's tx process */ ++/*rx handling */ ++ ENUM_BTIF_RX_TYPE btm_type; /*BTIF Rx bottom half context */ ++/*tx handling*/ ++ ENUM_BTIF_TX_TYPE tx_ctx; /*BTIF tx context */ ++/* unsigned char rx_buf[BTIF_RX_BUFFER_SIZE]; */ ++ btif_buf_str btif_buf; ++ spinlock_t rx_irq_spinlock; /*lock for rx irq handling */ ++ ++/*rx workqueue information*/ ++ /*lock to BTIF's rx bottom half when kernel thread is used */ ++ struct mutex rx_mtx; ++ struct workqueue_struct *p_rx_wq; ++ struct work_struct rx_work; ++ ++ struct workqueue_struct *p_tx_wq; ++ struct work_struct tx_work; ++ struct kfifo *p_tx_fifo; ++ ++/*rx tasklet information*/ ++ struct tasklet_struct rx_tasklet; ++ /*lock to BTIF's rx bottom half when tasklet is used */ ++ spinlock_t rx_tasklet_spinlock; ++ ++/*rx thread information*/ ++ struct task_struct *p_task; ++ struct completion rx_comp; ++ ++ mtk_btif_setting *setting; /*BTIF setting */ ++ ++ p_mtk_btif_dma p_tx_dma; /*BTIF Tx channel DMA */ ++ p_mtk_btif_dma p_rx_dma; /*BTIF Rx channel DMA */ ++ ++ MTK_WCN_BTIF_RX_CB rx_cb; /*Rx callback function */ ++ MTK_BTIF_RX_NOTIFY rx_notify; ++ ++ P_MTK_BTIF_INFO_STR p_btif_info; /*BTIF's information */ ++ ++/*Log Tx data to buffer*/ ++ BTIF_LOG_QUEUE_T tx_log; ++ ++/*Log Rx data to buffer*/ ++ BTIF_LOG_QUEUE_T rx_log; ++ ++/* struct list_head *p_user_list; */ ++ struct list_head user_list; ++/* get btif dev pointer*/ ++ void *private_data; ++} mtk_btif, *p_mtk_btif; ++/*---------------------------------------------------------------------------*/ ++ ++/*---------------------------------------------------------------------------*/ ++#if 0 ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_dma_register_ { ++ unsigned int int_flag; /*Tx offset:0x0 Rx offset:0x0 */ ++ unsigned int int_enable; /*Tx offset:0x4 Rx offset:0x4 */ ++ unsigned int dma_enable; /*Tx offset:0x8 Rx offset:0x8 */ ++ unsigned int dma_reset; /*Tx offset:0xc Rx offset:0xc */ ++ unsigned int dma_stop; /*Tx offset:0x10 Rx offset:0x10 */ ++ unsigned int dma_flush; /*Tx offset:0x14 Rx offset:0x14 */ ++ unsigned int vff_addr; /*Tx offset:0x1c Rx offset:0x1c */ ++ unsigned int vff_len; /*Tx offset:0x24 Rx offset:0x24 */ ++ unsigned int vff_thr; /*Tx offset:0x28 Rx offset:0x28 */ ++ unsigned int vff_wpt; /*Tx offset:0x2c Rx offset:0x2c */ ++ unsigned int vff_rpt; /*Tx offset:0x30 Rx offset:0x30 */ ++ unsigned int rx_fc_thr; /*Tx:No this register Rx offset:0x34 */ ++ unsigned int int_buf_size; /*Tx offset:0x38 Rx offset:0x38 */ ++ unsigned int vff_valid_size; /*Tx offset:0x3c Rx offset:0x3c */ ++ unsigned int vff_left_size; /*Tx offset:0x40 Rx offset:0x40 */ ++ unsigned int debug_status; /*Tx offset:0x50 Rx offset:0x50 */ ++} mtk_dma_register, *p_mtk_dma_register; ++/*---------------------------------------------------------------------------*/ ++#endif ++ ++/*---------------------------------------------------------------------------*/ ++typedef struct _mtk_btif_user_ { ++ bool enable; /*register its state */ ++ struct list_head entry; /*btif_user's bi-direction list table */ ++ /*BTIF's user, static allocation */ ++ char u_name[BTIF_USER_NAME_MAX_LEN]; ++ unsigned long u_id; ++ p_mtk_btif p_btif; ++} mtk_btif_user, *p_mtk_btif_user; ++ ++/*---------------------------------------------------------------------------*/ ++#define BBS_PTR(ptr, idx) ((ptr->p_buf) + idx) ++ ++#define BBS_SIZE(ptr) ((ptr)->size) ++#define BBS_MASK(ptr) (BBS_SIZE(ptr) - 1) ++#define BBS_COUNT(ptr) ((ptr)->wr_idx >= (ptr)->rd_idx ? (ptr)->wr_idx - \ ++(ptr)->rd_idx : BBS_SIZE(ptr) - \ ++((ptr)->rd_idx - (ptr)->wr_idx)) ++#define BBS_COUNT_CUR(ptr, wr_idx) (wr_idx >= (ptr)->rd_idx ? wr_idx - \ ++(ptr)->rd_idx : BBS_SIZE(ptr) - \ ++((ptr)->rd_idx - wr_idx)) ++ ++#define BBS_LEFT(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) ++ ++#define BBS_AVL_SIZE(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) ++#define BBS_FULL(ptr) (BBS_COUNT(ptr) - BBS_SIZE(ptr)) ++#define BBS_EMPTY(ptr) ((ptr)->wr_idx == (ptr)->rd_idx) ++#define BBS_WRITE_MOVE_NEXT(ptr) ((ptr)->wr_idx = \ ++((ptr)->wr_idx + 1) & BBS_MASK(ptr)) ++#define BBS_READ_MOVE_NEXT(ptr) ((ptr)->rd_idx = \ ++((ptr)->rd_idx + 1) & BBS_MASK(ptr)) ++ ++#define BBS_INIT(ptr) \ ++{ \ ++(ptr)->rd_idx = (ptr)->wr_idx = 0; \ ++(ptr)->size = BTIF_RX_BUFFER_SIZE; \ ++} ++ ++ ++#define BTIF_MUTEX_UNLOCK(x) mutex_unlock(x) ++ ++extern mtk_btif g_btif[]; ++ ++int btif_open(p_mtk_btif p_btif); ++int btif_close(p_mtk_btif p_btif); ++int btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++int btif_enter_dpidle(p_mtk_btif p_btif); ++int btif_exit_dpidle(p_mtk_btif p_btif); ++int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb); ++ ++/*for test purpose*/ ++int _btif_suspend(p_mtk_btif p_btif); ++int _btif_resume(p_mtk_btif p_btif); ++int _btif_restore_noirq(p_mtk_btif p_btif); ++ ++int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); ++int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, ++ int len); ++int btif_dump_data(char *p_buf, int len); ++int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que); ++int btif_log_buf_init(p_mtk_btif p_btif); ++int btif_dump_reg(p_mtk_btif p_btif); ++int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify); ++int btif_raise_wak_signal(p_mtk_btif p_btif); ++int btif_clock_ctrl(p_mtk_btif p_btif, int en); ++bool btif_parser_wmt_evt(p_mtk_btif p_btif, ++ const char *sub_str, ++ unsigned int sub_len); ++void mtk_btif_read_cpu_sw_rst_debug(void); ++ ++#endif /*__MTK_BTIF_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h +new file mode 100644 +index 000000000000..3752644fe0aa +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h +@@ -0,0 +1,280 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_BTIF_EXP_H_ ++#define _MTK_BTIF_EXP_H_ ++ ++/*--------------marco defination---------------*/ ++#define BTIF_MAX_LEN_PER_PKT 2048 ++#define BTIF_RXD_BE_BLOCKED_DETECT 1 ++/*--------------Enum Defination---------------*/ ++typedef enum _ENUM_BTIF_DPIDLE_ { ++ BTIF_DPIDLE_DISABLE = 0, ++ BTIF_DPIDLE_ENABLE = BTIF_DPIDLE_DISABLE + 1, ++ BTIF_DPIDLE_MAX, ++} ENUM_BTIF_DPIDLE_CTRL; ++ ++typedef enum _ENUM_BTIF_LPBK_MODE_ { ++ BTIF_LPBK_DISABLE = 0, ++ BTIF_LPBK_ENABLE = BTIF_LPBK_DISABLE + 1, ++ BTIF_LPBK_MAX, ++} ENUM_BTIF_LPBK_MODE; ++ ++typedef enum _ENUM_BTIF_DBG_ID_ { ++ BTIF_DISABLE_LOGGER = 0, ++ BTIF_ENABLE_LOGGER = BTIF_DISABLE_LOGGER + 1, ++ BTIF_DUMP_LOG = BTIF_ENABLE_LOGGER + 1, ++ BTIF_CLR_LOG = BTIF_DUMP_LOG + 1, ++ BTIF_DUMP_BTIF_REG = BTIF_CLR_LOG + 1, ++ BTIF_ENABLE_RT_LOG = BTIF_DUMP_BTIF_REG + 1, ++ BTIF_DISABLE_RT_LOG = BTIF_ENABLE_RT_LOG + 1, ++ BTIF_DBG_MAX, ++} ENUM_BTIF_DBG_ID; ++ ++typedef enum _ENUM_BTIF_OP_ERROR_CODE_ { ++ E_BTIF_AGAIN = 0, ++ E_BTIF_FAIL = -1, ++ E_BTIF_BAD_POINTER = -2, ++ E_BTIF_NO_SPACE = -3, ++ E_BTIF_INTR = -4, ++ E_BTIF_INVAL_PARAM = -5, ++ E_BTIF_ALREADY_OPEN = -6, ++ E_BTIF_NOT_OPEN = -7, ++ E_BTIF_INVAL_STATE = -8, ++} ENUM_BTIF_OP_ERROR_CODE; ++ ++/*--------------End of Enum Defination---------------*/ ++ ++/*--------------Type Definition---------------*/ ++ ++typedef int (*MTK_WCN_BTIF_RX_CB) (const unsigned char *p_buf, ++ unsigned int len); ++ ++/*--------------End of Type Definition---------------*/ ++ ++/*--------------Normal Mode API declearation---------------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_open ++* DESCRIPTION ++* open BTIF interface, will do BTIF module HW and SW initialization ++* PARAMETERS ++* p_owner [IN] pointer to owner who call this API, ++* currently there are 2 owner ("stp" or "btif_tester") ++* may use this module ++* user's id string must be less than 32 bytes ++* for "stp", BTIF will call rx callback function to route rx data to STP module ++* for "stp_tester", BTIF will save rx data ++* and wait for native process to access ++* p_id [IN] BTIF's user id will be put to this address ++* RETURNS ++* int 0 = succeed; others = fail, for detailed information, ++* please see ENUM_BTIF_OP_ERROR_CODE ++* if open success, value p_id will be the only identifier for ++* user to access BTIF's other operations ++* including read/write/dpidle_ctrl/rx_cb_retister ++* this user id is only an identifier used for owner identification ++*****************************************************************************/ ++int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id); ++//EXPORT_SYMBOL(mtk_wcn_btif_open) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_close ++* DESCRIPTION ++* close BTIF interface, will do BTIF module HW and SW de-initialization ++* once this API is called, p_btif should never be used by BTIF's user again ++* PARAMETERS ++* u_id [IN] BTIF's user id ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_close(unsigned long u_id); ++//EXPORT_SYMBOL(mtk_wcn_btif_close) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_write ++* DESCRIPTION ++* send data throuth BTIF module ++* there's no internal buffer to cache STP data in BTIF driver, ++* if in DMA mode ++* btif driver will check if there's enough space ++* in vFIFO for data to send in DMA mode ++* if yes, put data to vFIFO and return corresponding data length to caller ++* if no, corresponding error code will be returned to called ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN] pointer to target data to send ++* len [IN] data length (should be less than 2014 bytes per STP package) ++* ++* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller ++* if btif driver detected that no space is available in Tx FIFO, ++* will return E_BTIF_NO_SPACE, ++* mostly something is wrong with BTIF or consys when this ++* return value is returned ++* RETURNS ++* int positive: data length send through BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++* E_BTIF_AGAIN (0) will be returned to caller if btif does not have ++* enough vFIFO to send data, when caller get 0, ++* he should wait for a moment (5~10ms maybe) and ++* try a few times (maybe 10~20) ++* if still get E_BTIF_AGAIN, should call BTIF's debug API and ++* dump BTIF driver and BTIF/DMA register information to kernel log ++* for debug ++* E_BTIF_BAD_POINTER will be returned to caller if btif is not ++* opened successfully before call this API ++* E_BTIF_INVAL_PARAM will be returned if parameter is not valid ++ ++*****************************************************************************/ ++int mtk_wcn_btif_write(unsigned long u_id, ++ const unsigned char *p_buf, unsigned int len); ++//EXPORT_SYMBOL(mtk_wcn_btif_write) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_read ++* DESCRIPTION ++* read data from BTIF module ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN/OUT] pointer to buffer where rx data will be put ++* max_len [IN] max buffer length ++* RETURNS ++* int positive: data length read from BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_read(unsigned long u_id, ++ unsigned char *p_buf, unsigned int max_len); ++//EXPORT_SYMBOL(mtk_wcn_btif_read) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_dpidle_ctrl ++* DESCRIPTION ++* control if BTIF module allow system enter deepidle state or not ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL ++* RETURNS ++* int always return 0 ++*****************************************************************************/ ++int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_rx_cb_register ++* DESCRIPTION ++* register rx callback function to BTIF module by btif user ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* rx_cb [IN] pointer to stp rx handler callback function, ++* should be comply with MTK_WCN_BTIF_RX_CB ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_wakeup_consys ++* DESCRIPTION ++* once sleep command is sent to con sys, ++* should call this API before send wakeup command to ++* make con sys aware host want to send data to consys ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_wakeup_consys(unsigned long u_id); ++ ++/*--------------End of Normal Mode API declearation----------------*/ ++ ++/*--------------Debug Purpose API declearation----------------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_loopback_ctrl ++* DESCRIPTION ++* enable/disable BTIF internal loopback function, ++* when this function is enabled, ++* data send to btif will be received by btif itself ++* only for debug purpose, should never use this function in normal mode ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* enable [IN] loopback mode control flag, enable or disable, ++* shou be one of ENUM_BTIF_LPBK_MODE ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable); ++//EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl) ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_logger_ctrl ++* DESCRIPTION ++* control BTIF logger function's behavior ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* flag [IN] should be one of ENUM_BTIF_DBG_ID ++* BTIF_DISABLE_LOGGER - disable btif logger ++* BTIF_ENABLE_LOGGER - enable btif logger ++* BTIF_DUMP_LOG - dump log logged by btif ++* BTIF_CLR_LOG - clear btif log buffer ++* BTIF_DUMP_BTIF_REG - dump btif controller's register ++* BTIF_DUMP_DMA_REG - dump DMA controller's register ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, ++* please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag); ++//EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); ++/*-----------End of Debug Purpose API declearation------------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_parser_wmt_evt ++* DESCRIPTION ++* parser wmt sleep/wakeup evt in btif bbs buffer for debug ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* sub_str [IN] the str to be parsered ++* str_len [IN] the length of sub_str ++* RETURNS ++* bool true = succeed; ++* false = fail; ++*****************************************************************************/ ++bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, ++ const char *sub_str, unsigned int str_len); ++ ++int mtk_btif_exp_open_test(void); ++int mtk_btif_exp_close_test(void); ++int mtk_btif_exp_write_test(void); ++int mtk_btif_exp_suspend_test(void); ++int mtk_btif_exp_resume_test(void); ++int mtk_btif_exp_enter_dpidle_test(void); ++int mtk_btif_exp_exit_dpidle_test(void); ++int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int loop); ++int mtk_btif_exp_log_debug_test(int flag); ++int mtk_btif_exp_restore_noirq_test(void); ++int btif_wakeup_consys_no_id(void); ++int mtk_btif_exp_clock_ctrl(int en); ++#if BTIF_RXD_BE_BLOCKED_DETECT ++int mtk_btif_rxd_be_blocked_flag_get(void); ++#endif ++void mtk_btif_read_cpu_sw_rst_debug_exp(void); ++#endif /*_MTK_BTIF_EXP_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/mtk_btif.c b/drivers/misc/mediatek/btif/common/mtk_btif.c +new file mode 100644 +index 000000000000..0212ad41049f +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/mtk_btif.c +@@ -0,0 +1,3472 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/*-----------linux system header files----------------*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*#include */ ++/*-----------driver own header files----------------*/ ++#ifdef CONFIG_COMPAT ++#include ++#endif ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF" ++ ++#define BTIF_CDEV_SUPPORT 1 ++ ++#include "btif_pub.h" ++#include "btif_dma_pub.h" ++#include "mtk_btif_exp.h" ++#include "mtk_btif.h" ++ ++/*-----------static function declearation----------------*/ ++static int mtk_btif_probe(struct platform_device *pdev); ++static int mtk_btif_remove(struct platform_device *pdev); ++static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state); ++static int mtk_btif_resume(struct platform_device *pdev); ++static int mtk_btif_drv_resume(struct device *dev); ++static int mtk_btif_drv_suspend(struct device *pdev); ++ ++static int mtk_btif_restore_noirq(struct device *device); ++static int btif_file_open(struct inode *pinode, struct file *pfile); ++static int btif_file_release(struct inode *pinode, struct file *pfile); ++static ssize_t btif_file_read(struct file *pfile, ++ char __user *buf, size_t count, loff_t *f_ops); ++static unsigned int btif_poll(struct file *filp, poll_table *wait); ++static int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, ++ mtk_btif_irq_handler irq_handler, void *data); ++static int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data); ++static int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en); ++static int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en); ++static irqreturn_t btif_irq_handler(int irq, void *data); ++static unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++ ++static irqreturn_t btif_tx_dma_irq_handler(int irq, void *data); ++static irqreturn_t btif_rx_dma_irq_handler(int irq, void *data); ++ ++static unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++static int _btif_controller_tx_setup(p_mtk_btif p_btif); ++static int _btif_controller_tx_free(p_mtk_btif p_btif); ++static int _btif_controller_rx_setup(p_mtk_btif p_btif); ++static int _btif_controller_rx_free(p_mtk_btif p_btif); ++static int _btif_tx_pio_setup(p_mtk_btif p_btif); ++static int _btif_rx_pio_setup(p_mtk_btif p_btif); ++static int _btif_rx_dma_setup(p_mtk_btif p_btif); ++static int _btif_rx_dma_free(p_mtk_btif p_btif); ++static int _btif_tx_dma_setup(p_mtk_btif p_btif); ++static int _btif_tx_dma_free(p_mtk_btif p_btif); ++static int _btif_controller_setup(p_mtk_btif p_btif); ++static int _btif_controller_free(p_mtk_btif p_btif); ++ ++static int _btif_pio_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++static int _btif_dma_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++ ++static unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len); ++static unsigned int btif_bbs_read(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len); ++static unsigned int btif_bbs_write(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len); ++static void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs); ++static int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len); ++static int _btif_rx_btm_deinit(p_mtk_btif p_btif); ++static int _btif_rx_btm_sched(p_mtk_btif p_btif); ++static int _btif_rx_btm_init(p_mtk_btif p_btif); ++static void btif_rx_tasklet(unsigned long func_data); ++static void btif_rx_worker(struct work_struct *p_work); ++static int btif_rx_thread(void *p_data); ++static int btif_rx_data_consummer(p_mtk_btif p_btif); ++ ++static int _btif_tx_ctx_init(p_mtk_btif p_btif); ++static int _btif_tx_ctx_deinit(p_mtk_btif p_btif); ++static void btif_tx_worker(struct work_struct *p_work); ++ ++static int _btif_state_deinit(p_mtk_btif p_btif); ++static int _btif_state_release(p_mtk_btif p_btif); ++static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif); ++static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state); ++static int _btif_state_hold(p_mtk_btif p_btif); ++static int _btif_state_init(p_mtk_btif p_btif); ++ ++static int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ++ ENUM_BTIF_DPIDLE_CTRL en_flag); ++static int _btif_enter_dpidle(p_mtk_btif p_btif); ++static int _btif_exit_dpidle(p_mtk_btif p_btif); ++static int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif); ++static int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif); ++static int _btif_enter_dpidle_from_on(p_mtk_btif p_btif); ++static int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif); ++ ++#if ENABLE_BTIF_TX_DMA ++static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma); ++static int _btif_vfifo_init(p_mtk_btif_dma p_dma); ++#endif ++ ++static bool _btif_is_tx_complete(p_mtk_btif p_btif); ++static int _btif_init(p_mtk_btif p_btif); ++static int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); ++static int btif_rx_dma_mode_set(int en); ++static int btif_tx_dma_mode_set(int en); ++ ++static int _btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len); ++ ++/*-----------end of static function declearation----------------*/ ++ ++static const char *g_state[B_S_MAX] = { ++ "OFF", ++ "SUSPEND", ++ "DPIDLE", ++ "ON", ++}; ++ ++/*-----------BTIF setting--------------*/ ++mtk_btif_setting g_btif_setting[BTIF_PORT_NR] = { ++ { ++ .tx_mode = BTIF_TX_MODE, ++ .rx_mode = BTIF_RX_MODE, ++ .rx_type = BTIF_RX_BTM_CTX, ++ .tx_type = BTIF_TX_CTX, ++ }, ++}; ++ ++mtk_btif g_btif[BTIF_PORT_NR] = { ++ { ++ .open_counter = 0, ++ .state = B_S_OFF, ++ .setting = &g_btif_setting[0], ++ .p_tx_dma = NULL, ++ .p_rx_dma = NULL, ++ .rx_cb = NULL, ++ .p_btif_info = NULL, ++ }, ++}; ++ ++mtk_btif_dma g_dma[BTIF_PORT_NR][BTIF_DIR_MAX] = { ++ { ++ { ++ .p_btif = NULL, ++ .dir = BTIF_TX, ++ .p_dma_info = NULL, ++ .entry = ATOMIC_INIT(0), ++ }, ++ { ++ .p_btif = NULL, ++ .dir = BTIF_RX, ++ .p_dma_info = NULL, ++ .entry = ATOMIC_INIT(0), ++ }, ++ }, ++}; ++ ++#define G_MAX_PKG_LEN (7 * 1024) ++static int g_max_pkg_len = G_MAX_PKG_LEN; /*DMA vFIFO is set to 8 * 1024, we set this to 7/8 * vFIFO size*/ ++static int g_max_pding_data_size = BTIF_RX_BUFFER_SIZE * 3 / 4; ++ ++ ++static int mtk_btif_dbg_lvl = BTIF_LOG_ERR; ++ ++#if BTIF_RXD_BE_BLOCKED_DETECT ++static struct timeval btif_rxd_time_stamp[MAX_BTIF_RXD_TIME_REC]; ++#endif ++/*-----------Platform bus related structures----------------*/ ++#define DRV_NAME "mtk_btif" ++ ++#ifdef CONFIG_OF ++const struct of_device_id apbtif_of_ids[] = { ++ { .compatible = "mediatek,mtk-btif", }, ++ {} ++}; ++#endif ++ ++const struct dev_pm_ops mtk_btif_drv_pm_ops = { ++ .restore_noirq = mtk_btif_restore_noirq, ++ .suspend = mtk_btif_drv_suspend, ++ .resume = mtk_btif_drv_resume, ++}; ++ ++struct platform_driver mtk_btif_dev_drv = { ++ .probe = mtk_btif_probe, ++ .remove = mtk_btif_remove, ++#ifdef CONFIG_PM ++ .suspend = mtk_btif_suspend, ++ .resume = mtk_btif_resume, ++#endif ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++#ifdef CONFIG_PM ++ .pm = &mtk_btif_drv_pm_ops, ++#endif ++#ifdef CONFIG_OF ++ .of_match_table = apbtif_of_ids, ++#endif ++ } ++}; ++ ++#define BTIF_STATE_RELEASE(x) _btif_state_release(x) ++ ++/*-----------End of Platform bus related structures----------------*/ ++ ++/*-----------platform bus related operation APIs----------------*/ ++ ++static int mtk_btif_probe(struct platform_device *pdev) ++{ ++/*Chaozhong: ToDo: to be implement*/ ++/*register IRQ for BTIF and Tx Rx DMA and disable them by default*/ ++ BTIF_INFO_FUNC("DO BTIF PROBE\n"); ++ platform_set_drvdata(pdev, &g_btif[0]); ++ g_btif[0].private_data = (struct device *)&pdev->dev; ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ hal_btif_clk_get_and_prepare(pdev); ++#endif ++ ++ return 0; ++} ++ ++static int mtk_btif_remove(struct platform_device *pdev) ++{ ++/*Chaozhong: ToDo: to be implement*/ ++ BTIF_INFO_FUNC("DO BTIF REMOVE\n"); ++ platform_set_drvdata(pdev, NULL); ++ g_btif[0].private_data = NULL; ++ return 0; ++} ++ ++int _btif_suspend(p_mtk_btif p_btif) ++{ ++ int i_ret; ++ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ if (p_btif != NULL) { ++ if (!(p_btif->enable)) ++ i_ret = 0; ++ else { ++ if (_btif_state_get(p_btif) == B_S_ON) { ++ BTIF_ERR_FUNC("BTIF in ON state,", ++ "there are data need to be send or recev,suspend fail\n"); ++ i_ret = -1; ++ } else { ++ /* ++ * before disable BTIF controller and DMA controller ++ * we need to set BTIF to ON state ++ */ ++ i_ret = _btif_exit_dpidle(p_btif); ++ if (i_ret == 0) { ++ i_ret += _btif_controller_free(p_btif); ++ i_ret = _btif_controller_tx_free(p_btif); ++ i_ret += _btif_controller_rx_free(p_btif); ++ } ++ if (i_ret != 0) { ++ BTIF_INFO_FUNC("failed\n"); ++ /*Chaozhong: what if failed*/ ++ } else { ++ BTIF_INFO_FUNC("succeed\n"); ++ i_ret = _btif_state_set(p_btif, B_S_SUSPEND); ++ if (i_ret && _btif_init(p_btif)) { ++ /*Chaozhong:BTIF re-init failed? what to do*/ ++ i_ret = _btif_state_set(p_btif, B_S_OFF); ++ } ++ } ++ } ++ } ++ } else ++ i_ret = -1; ++ BTIF_STATE_RELEASE(p_btif); ++ ++ return i_ret; ++} ++ ++ ++static int mtk_btif_drv_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ pm_message_t state = PMSG_SUSPEND; ++ ++ return mtk_btif_suspend(pdev, state); ++} ++ ++static int mtk_btif_drv_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ ++ return mtk_btif_resume(pdev); ++} ++ ++static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = NULL; ++ ++/*Chaozhong: ToDo: to be implement*/ ++ BTIF_DBG_FUNC("++\n"); ++ p_btif = platform_get_drvdata(pdev); ++ i_ret = _btif_suspend(p_btif); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++int _btif_restore_noirq(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*BTIF IRQ restore no irq*/ ++ i_ret = hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_RESTORE_NOIRQ); ++ if (i_ret == 0) { ++ BTIF_INFO_FUNC("BTIF HW IRQ restore succeed\n"); ++ } else { ++ BTIF_INFO_FUNC("BTIF HW IRQ restore failed, i_ret:%d\n", i_ret); ++ return i_ret; ++ } ++/*BTIF DMA restore no irq*/ ++ if (p_btif->tx_mode & BTIF_MODE_DMA) { ++ i_ret = hal_dma_pm_ops(p_btif->p_tx_dma->p_dma_info, ++ BTIF_PM_RESTORE_NOIRQ); ++ if (i_ret == 0) { ++ BTIF_INFO_FUNC("BTIF Tx DMA IRQ restore succeed\n"); ++ } else { ++ BTIF_INFO_FUNC ++ ("BTIF Tx DMA IRQ restore failed, i_ret:%d\n", ++ i_ret); ++ return i_ret; ++ } ++ } ++ if (p_btif->rx_mode & BTIF_MODE_DMA) { ++ i_ret = hal_dma_pm_ops(p_btif->p_rx_dma->p_dma_info, ++ BTIF_PM_RESTORE_NOIRQ); ++ if (i_ret == 0) { ++ BTIF_INFO_FUNC("BTIF Rx DMA IRQ restore succeed\n"); ++ } else { ++ BTIF_INFO_FUNC ++ ("BTIF Rx DMA IRQ restore failed, i_ret:%d\n", ++ i_ret); ++ return i_ret; ++ } ++ } ++ return i_ret; ++} ++ ++static int mtk_btif_restore_noirq(struct device *dev) ++{ ++ int i_ret = 0; ++ struct platform_device *pdev = to_platform_device(dev); ++ p_mtk_btif p_btif = platform_get_drvdata(pdev); ++ ++ BTIF_INFO_FUNC("++\n"); ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ if (p_btif->enable) ++ BTIF_ERR_FUNC("!!!-----------------!BTIF is not closed before IPOH shutdown!!!---------------!\n"); ++ WARN_ON(p_btif->enable); ++ ++ i_ret = _btif_restore_noirq(p_btif); ++ BTIF_STATE_RELEASE(p_btif); ++ BTIF_INFO_FUNC("--\n"); ++ return 0; ++} ++ ++int _btif_resume(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ENUM_BTIF_STATE state = B_S_MAX; ++ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ if (p_btif != NULL) { ++ state = _btif_state_get(p_btif); ++ if (!(p_btif->enable)) ++ i_ret = 0; ++ else if (state == B_S_SUSPEND) ++ i_ret = _btif_enter_dpidle(p_btif); ++ else ++ BTIF_INFO_FUNC ++ ("BTIF state: %s before resume, do nothing\n", g_state[state]); ++ } else ++ i_ret = -1; ++ BTIF_STATE_RELEASE(p_btif); ++ ++ return i_ret; ++} ++ ++static int mtk_btif_resume(struct platform_device *pdev) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = NULL; ++/*Chaozhong: ToDo: to be implement*/ ++ BTIF_DBG_FUNC("++\n"); ++ p_btif = platform_get_drvdata(pdev); ++ i_ret = _btif_resume(p_btif); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return 0; ++} ++ ++/*-----------device node----------------*/ ++#if BTIF_CDEV_SUPPORT ++ ++dev_t btif_dev; ++struct class *p_btif_class; ++struct device *p_btif_dev; ++const char *p_btif_dev_name = "btif"; ++static struct semaphore wr_mtx; ++static struct semaphore rd_mtx; ++unsigned char wr_buf[2048]; ++unsigned char rd_buf[2048]; ++static int rx_notify_flag; ++static DECLARE_WAIT_QUEUE_HEAD(btif_wq); ++static int btif_file_open(struct inode *pinode, struct file *pfile); ++static int btif_file_release(struct inode *pinode, struct file *pfile); ++static ssize_t btif_file_read(struct file *pfile, ++ char __user *buf, size_t count, loff_t *f_ops); ++ ++static ssize_t btif_file_write(struct file *filp, ++ const char __user *buf, size_t count, loff_t *f_pos); ++static long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, ++ unsigned long arg); ++#ifdef CONFIG_COMPAT ++static long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); ++#endif ++static struct cdev btif_dev_c; ++static wait_queue_head_t btif_read_inq; /* read queues */ ++ ++const struct file_operations mtk_btif_fops = { ++ .owner = THIS_MODULE, ++ .open = btif_file_open, ++ .release = btif_file_release, ++ .read = btif_file_read, ++ .write = btif_file_write, ++ .unlocked_ioctl = btif_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = btif_compat_ioctl, ++#endif ++ .poll = btif_poll, ++}; ++ ++static int btif_chrdev_init(void) ++{ ++ int i_ret; ++ ++ int i_err; ++ ++ /* alloc device number dynamically */ ++ i_ret = alloc_chrdev_region(&btif_dev, 0, 1, p_btif_dev_name); ++ if (i_ret) { ++ BTIF_ERR_FUNC("devuce number allocation failed, i_ret:%d\n", ++ i_ret); ++ } else { ++ BTIF_INFO_FUNC("devuce number allocation succeed\n"); ++ } ++ cdev_init(&btif_dev_c, &mtk_btif_fops); ++ btif_dev_c.owner = THIS_MODULE; ++ i_err = cdev_add(&btif_dev_c, btif_dev, 1); ++ if (i_err) { ++ BTIF_ERR_FUNC("error add btif dev to kernel, error code:%d\n", ++ i_err); ++ unregister_chrdev_region(btif_dev, 1); ++ btif_dev = 0; ++ return -1; ++ } ++ BTIF_INFO_FUNC("add btif dev to kernel succeed\n"); ++ ++ p_btif_class = class_create(THIS_MODULE, p_btif_dev_name); ++ if (IS_ERR(p_btif_class)) { ++ BTIF_ERR_FUNC("error happened when doing class_create\n"); ++ unregister_chrdev_region(btif_dev, 1); ++ btif_dev = 0; ++ return -2; ++ } ++ BTIF_INFO_FUNC("create class for btif succeed\n"); ++ ++ p_btif_dev = device_create(p_btif_class, ++ NULL, btif_dev, 0, p_btif_dev_name); ++ if (IS_ERR(p_btif_dev)) { ++ BTIF_ERR_FUNC("error happened when doing device_create\n"); ++ class_destroy(p_btif_class); ++ p_btif_class = NULL; ++ unregister_chrdev_region(btif_dev, 1); ++ btif_dev = 0; ++ return -3; ++ } ++ BTIF_INFO_FUNC("create device for btif succeed\n"); ++ ++ return 0; ++} ++ ++void btif_rx_notify_cb(void) ++{ ++ BTIF_DBG_FUNC("++\n"); ++ rx_notify_flag = 1; ++ wake_up(&btif_wq); ++ wake_up_interruptible(&btif_read_inq); ++ BTIF_DBG_FUNC("--\n"); ++} ++ ++unsigned int btif_poll(struct file *filp, poll_table *wait) ++{ ++ unsigned int mask = 0; ++ unsigned int ava_len = 0; ++/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ ++ unsigned int wr_idx = g_btif[0].btif_buf.wr_idx; ++ ++/* BTIF_Rx_IRQ_Disable(); */ ++ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); ++ BTIF_INFO_FUNC("++\n"); ++ if (ava_len == 0) { ++ poll_wait(filp, &btif_read_inq, wait); ++ wr_idx = g_btif[0].btif_buf.wr_idx; ++ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); ++/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ ++ if (ava_len) ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ } else { ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ } ++/*make for writable*/ ++ mask |= POLLOUT | POLLWRNORM; /* writable */ ++ BTIF_INFO_FUNC("--, mask:%d\n", mask); ++ return mask; ++} ++ ++static int _btif_file_open(void) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ BTIF_INFO_FUNC("++\n"); ++ ++/*Chaozhong: ToDo: to be implement*/ ++ i_ret = btif_open(p_btif); ++ if ((i_ret != 0) && (i_ret != E_BTIF_ALREADY_OPEN)) { ++ BTIF_ERR_FUNC("btif_open failed, error code:%d\n", i_ret); ++ } else { ++ BTIF_INFO_FUNC("btif_open succeed\n"); ++ i_ret = 0; ++ } ++/*semaphore for read and write operation init*/ ++ sema_init(&wr_mtx, 1); ++ sema_init(&rd_mtx, 1); ++ ++/*buffer for read and write init*/ ++ memset(wr_buf, 0, sizeof(wr_buf)); ++ memset(rd_buf, 0, sizeof(rd_buf)); ++ init_waitqueue_head(&(btif_read_inq)); ++ btif_rx_notify_reg(p_btif, btif_rx_notify_cb); ++ BTIF_INFO_FUNC("--\n"); ++ return i_ret; ++} ++ ++static int _btif_file_close(void) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("++\n"); ++/*Chaozhong: ToDo: to be implement*/ ++ i_ret = btif_close(&g_btif[0]); ++ if (i_ret != 0) ++ BTIF_ERR_FUNC("btif_close failed, error code:%d\n", i_ret); ++ else ++ BTIF_INFO_FUNC("btif_close succeed\n"); ++ ++ BTIF_INFO_FUNC("--\n"); ++ return i_ret; ++} ++ ++static int btif_file_open(struct inode *pinode, struct file *pfile) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("pid:%d\n", current->pid); ++ i_ret = 0; ++ return i_ret; ++} ++ ++static int btif_file_release(struct inode *pinode, struct file *pfile) ++{ ++ int i_ret = -1; ++ ++ BTIF_INFO_FUNC("pid:%d\n", current->pid); ++ i_ret = 0; ++ return i_ret; ++} ++ ++static ssize_t btif_file_read(struct file *pfile, ++ char __user *buf, size_t count, loff_t *f_ops) ++{ ++ int i_ret = 0; ++ int rd_len = 0; ++ ++ BTIF_INFO_FUNC("++\n"); ++ down(&rd_mtx); ++ rd_len = btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); ++ while (rd_len == 0) { ++ if (pfile->f_flags & O_NONBLOCK) ++ break; ++ ++ wait_event(btif_wq, rx_notify_flag != 0); ++ rx_notify_flag = 0; ++ rd_len = ++ btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, ++ sizeof(rd_buf)); ++ } ++ ++ if (rd_len == 0) ++ i_ret = 0; ++ else if ((rd_len > 0) && (copy_to_user(buf, rd_buf, rd_len) == 0)) ++ i_ret = rd_len; ++ else ++ i_ret = -EFAULT; ++ ++ up(&rd_mtx); ++ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++ssize_t btif_file_write(struct file *filp, ++ const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ int i_ret = 0; ++ int copy_size = 0; ++ ++ copy_size = count > sizeof(wr_buf) ? sizeof(wr_buf) : count; ++ ++ BTIF_INFO_FUNC("++\n"); ++ down(&wr_mtx); ++ if (copy_from_user(&wr_buf[0], &buf[0], copy_size)) ++ i_ret = -EFAULT; ++ else ++ i_ret = btif_send_data(&g_btif[0], wr_buf, copy_size); ++ ++ up(&wr_mtx); ++ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); ++ ++ return i_ret; ++} ++#ifdef CONFIG_COMPAT ++long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ BTIF_INFO_FUNC("cmd[0x%x]\n", cmd); ++ ret = btif_unlocked_ioctl(filp, cmd, arg); ++ return ret; ++} ++#endif ++long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++#define BTIF_IOC_MAGIC 0xb0 ++#define BTIF_IOCTL_OPEN _IOW(BTIF_IOC_MAGIC, 1, int) ++#define BTIF_IOCTL_CLOSE _IOW(BTIF_IOC_MAGIC, 2, int) ++#define BTIF_IOCTL_LPBK_CTRL _IOWR(BTIF_IOC_MAGIC, 3, int) ++#define BTIF_IOCTL_LOG_FUNC_CTRL _IOWR(BTIF_IOC_MAGIC, 4, int) ++#define BTIF_IOCTL_RT_LOG_CTRL _IOWR(BTIF_IOC_MAGIC, 5, int) ++#define BTIF_IOCTL_LOG_DUMP _IOWR(BTIF_IOC_MAGIC, 6, int) ++#define BTIF_IOCTL_REG_DUMP _IOWR(BTIF_IOC_MAGIC, 7, int) ++#define BTIF_IOCTL_DMA_CTRL _IOWR(BTIF_IOC_MAGIC, 8, int) ++ ++ long ret = 0; ++/* unsigned char p_buf[NAME_MAX + 1]; */ ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ BTIF_INFO_FUNC("++\n"); ++ BTIF_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); ++ ++ switch (cmd) { ++ case BTIF_IOCTL_OPEN: ++ ret = _btif_file_open(); ++ break; ++ case BTIF_IOCTL_CLOSE: ++ ret = _btif_file_close(); ++ break; ++ case BTIF_IOCTL_LPBK_CTRL: ++ ret = btif_lpbk_ctrl(p_btif, arg == 0 ? 0 : 1); ++ break; ++ case BTIF_IOCTL_LOG_FUNC_CTRL: ++ if (arg == 0) { ++ ret += btif_log_buf_disable(&p_btif->tx_log); ++ ret += btif_log_buf_disable(&p_btif->rx_log); ++ } else { ++ ret += btif_log_buf_enable(&p_btif->tx_log); ++ ret += btif_log_buf_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_IOCTL_RT_LOG_CTRL: ++ if (arg == 0) { ++ ret += btif_log_output_disable(&p_btif->tx_log); ++ ret += btif_log_output_disable(&p_btif->rx_log); ++ } else { ++ ret += btif_log_output_enable(&p_btif->tx_log); ++ ret += btif_log_output_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_IOCTL_LOG_DUMP: ++ ++ ret += btif_log_buf_dmp_out(&p_btif->tx_log); ++ ret += btif_log_buf_dmp_out(&p_btif->rx_log); ++ break; ++ case BTIF_IOCTL_REG_DUMP: ++ ret += btif_dump_reg(p_btif); ++ break; ++ case BTIF_IOCTL_DMA_CTRL: ++ if (arg == 0) { ++ ret += btif_tx_dma_mode_set(0); ++ ret += btif_rx_dma_mode_set(0); ++ } else { ++ ret += btif_tx_dma_mode_set(1); ++ ret += btif_rx_dma_mode_set(1); ++ } ++ break; ++ default: ++ BTIF_INFO_FUNC("unknown cmd(%d)\n", cmd); ++ ret = -2; ++ break; ++ } ++ BTIF_INFO_FUNC("--\n"); ++ return ret; ++} ++ ++#endif ++ ++/*-----------device property----------------*/ ++//static ssize_t driver_flag_read(struct device_driver *drv, char *buf) ++static ssize_t flag_show(struct device_driver *drv, char *buf) ++{ ++ return sprintf(buf, "btif driver debug level:%d\n", mtk_btif_dbg_lvl); ++} ++ ++//static ssize_t driver_flag_set(struct device_driver *drv, ++static ssize_t flag_store(struct device_driver *drv, ++ const char *buffer, size_t count) ++{ ++ char buf[256]; ++ char *p_buf; ++ unsigned long len = count; ++ long x = 0; ++ long y = 0; ++ long z = 0; ++ int result = 0; ++ char *p_token = NULL; ++ char *p_delimiter = " \t"; ++ ++ BTIF_INFO_FUNC("buffer = %s, count = %zd\n", buffer, count); ++ if (len >= sizeof(buf)) { ++ BTIF_ERR_FUNC("input handling fail!\n"); ++ len = sizeof(buf) - 1; ++ return -1; ++ } ++ ++ memcpy(buf, buffer, sizeof(buf)); ++ p_buf = buf; ++ ++ p_token = strsep(&p_buf, p_delimiter); ++ if (p_token != NULL) { ++ result = kstrtol(p_token, 16, &x); ++ BTIF_INFO_FUNC("x = 0x%08x\n\r", x); ++ } else ++ x = 0; ++/* x = (NULL != p_token) ? kstrtol(p_token, 16, NULL) : 0;*/ ++ ++ p_token = strsep(&p_buf, "\t\n "); ++ if (p_token != NULL) { ++ result = kstrtol(p_token, 16, &y); ++ BTIF_INFO_FUNC("y = 0x%08x\n\r", y); ++ } else ++ y = 0; ++ ++ p_token = strsep(&p_buf, "\t\n "); ++ if (p_token != NULL) ++ result = kstrtol(p_token, 16, &z); ++ else ++ z = 0; ++ ++ BTIF_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); ++ ++ switch (x) { ++ case 1: ++ mtk_btif_exp_open_test(); ++ break; ++ case 2: ++ mtk_btif_exp_close_test(); ++ break; ++ case 3: ++ mtk_btif_exp_write_test(); ++ break; ++ case 4: ++ mtk_btif_exp_enter_dpidle_test(); ++ break; ++ case 5: ++ mtk_btif_exp_exit_dpidle_test(); ++ break; ++ case 6: ++ mtk_btif_exp_suspend_test(); ++ break; ++ case 7: ++ mtk_btif_exp_resume_test(); ++ break; ++ case 8: ++ if (y > BTIF_LOG_LOUD) ++ mtk_btif_dbg_lvl = BTIF_LOG_LOUD; ++ else if (y < BTIF_LOG_ERR) ++ mtk_btif_dbg_lvl = BTIF_LOG_WARN; ++ else ++ mtk_btif_dbg_lvl = y; ++ BTIF_ERR_FUNC("mtk_btif_dbg_lvl set to %d\n", mtk_btif_dbg_lvl); ++ break; ++ case 9: ++ mtk_btif_exp_open_test(); ++ mtk_btif_exp_write_test(); ++ mtk_btif_exp_close_test(); ++ break; ++ case 0xa: ++ mtk_btif_exp_log_debug_test(y); ++ break; ++ case 0xb: ++ btif_tx_dma_mode_set(1); ++ btif_rx_dma_mode_set(1); ++ break; ++ case 0xc: ++ btif_tx_dma_mode_set(0); ++ btif_rx_dma_mode_set(0); ++ break; ++ case 0xd: ++ mtk_btif_exp_restore_noirq_test(); ++ break; ++ case 0xe: ++ btif_wakeup_consys_no_id(); ++ break; ++ case 0xf: ++ mtk_btif_exp_clock_ctrl(y); ++ break; ++ case 0x10: ++ y = y > G_MAX_PKG_LEN ? G_MAX_PKG_LEN : y; ++ y = y < 1024 ? 1024 : y; ++ BTIF_INFO_FUNC("g_max_pkg_len is set to %d\n", y); ++ g_max_pkg_len = y; ++ break; ++ case 0x11: ++ y = y > BTIF_RX_BUFFER_SIZE ? BTIF_RX_BUFFER_SIZE : y; ++ y = y < 1024 ? 1024 : y; ++ BTIF_INFO_FUNC("g_max_pding_data_size is set to %d\n", y); ++ g_max_pding_data_size = y; ++ break; ++ default: ++ mtk_btif_exp_open_test(); ++ mtk_btif_exp_write_stress_test(3030, 1); ++ mtk_btif_exp_close_test(); ++ BTIF_WARN_FUNC("not supported.\n"); ++ break; ++ } ++ ++ return count; ++} ++ ++//FWU: driver_ATTR dropped in 4.14 ++//static DRIVER_ATTR(flag, S_IRUGO | S_IWUSR, driver_flag_read, driver_flag_set); ++static DRIVER_ATTR_RW(flag); ++ ++/*-----------End of platform bus related operation APIs------------*/ ++ ++/*-----------------------platform driver ----------------*/ ++ ++int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, ++ mtk_btif_irq_handler irq_handler, void *data) ++{ ++ int i_ret = -1; ++ unsigned int irq_id; ++ unsigned int flag; ++ ++ if ((p_irq == NULL) || (irq_handler == NULL)) ++ return E_BTIF_INVAL_PARAM; ++ ++ if (!(p_irq->is_irq_sup)) { ++ BTIF_WARN_FUNC("%s is not supported\n", p_irq->name); ++ return 0; ++ } ++ ++ irq_id = p_irq->irq_id; ++ ++#ifdef CONFIG_OF ++ flag = p_irq->irq_flags; ++#else ++ switch (p_irq->sens_type) { ++ case IRQ_SENS_EDGE: ++ if (p_irq->edge_type == IRQ_EDGE_FALL) ++ flag = IRQF_TRIGGER_FALLING; ++ else if (p_irq->edge_type == IRQ_EDGE_RAISE) ++ flag = IRQF_TRIGGER_RISING; ++ else if (p_irq->edge_type == IRQ_EDGE_BOTH) ++ flag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; ++ else ++ /*make this as default type */ ++ flag = IRQF_TRIGGER_FALLING; ++ break; ++ case IRQ_SENS_LVL: ++ if (p_irq->lvl_type == IRQ_LVL_LOW) ++ flag = IRQF_TRIGGER_LOW; ++ else if (p_irq->lvl_type == IRQ_LVL_HIGH) ++ flag = IRQF_TRIGGER_HIGH; ++ else ++ /*make this as default type */ ++ flag = IRQF_TRIGGER_LOW; ++ break; ++ default: ++ /*make this as default type */ ++ flag = IRQF_TRIGGER_LOW; ++ break; ++ } ++#endif ++ ++ p_irq->p_irq_handler = irq_handler; ++ i_ret = request_irq(irq_id, ++ (irq_handler_t) irq_handler, ++ flag, p_irq->name, data); ++ if (i_ret) ++ return i_ret; ++ ++ p_irq->reg_flag = true; ++ return 0; ++} ++ ++int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data) ++{ ++ int i_ret = 0; ++ unsigned int eint_num = p_irq->irq_id; ++ ++ if ((p_irq->is_irq_sup) && (p_irq->reg_flag)) { ++ _btif_irq_ctrl(p_irq, false); ++ free_irq(eint_num, data); ++ p_irq->reg_flag = false; ++ } ++/*do nothing for this operation*/ ++ return i_ret; ++} ++ ++int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en) ++{ ++ unsigned int eint_num = p_irq->irq_id; ++ ++ if (en) ++ enable_irq(eint_num); ++ else ++ disable_irq_nosync(eint_num); ++ ++ return 0; ++} ++ ++int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en) ++{ ++ unsigned int eint_num = p_irq->irq_id; ++ ++ if (en) ++ enable_irq(eint_num); ++ else ++ disable_irq(eint_num); ++ ++ return 0; ++} ++ ++ ++irqreturn_t btif_irq_handler(int irq, void *data) ++{ ++/*search BTIF? just use index 0*/ ++/*Chaozhong: do we need lock here?*/ ++ ++ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ ++ ++ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); ++ ++ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, false); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++#endif ++ ++ hal_btif_irq_handler(p_btif->p_btif_info, NULL, 0); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++#endif ++ ++ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, true); ++ _btif_rx_btm_sched(p_btif); ++ ++ BTIF_DBG_FUNC("--\n"); ++ return IRQ_HANDLED; ++} ++ ++irqreturn_t btif_tx_dma_irq_handler(int irq, void *data) ++{ ++/*search BTIF? just use index 0*/ ++ ++ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ ++ p_mtk_btif_dma p_tx_dma = p_btif->p_tx_dma; ++ P_MTK_DMA_INFO_STR p_dma_info = p_tx_dma->p_dma_info; ++ ++ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); ++ _btif_irq_ctrl(p_dma_info->p_irq, false); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); ++#endif ++ ++ hal_tx_dma_irq_handler(p_dma_info); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++#endif ++ _btif_irq_ctrl(p_dma_info->p_irq, true); ++ BTIF_DBG_FUNC("--\n"); ++ return IRQ_HANDLED; ++} ++ ++irqreturn_t btif_rx_dma_irq_handler(int irq, void *data) ++{ ++/*search BTIF? just use index 0*/ ++ ++ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ ++ p_mtk_btif_dma p_rx_dma = p_btif->p_rx_dma; ++ P_MTK_DMA_INFO_STR p_rx_dma_info = p_rx_dma->p_dma_info; ++ ++ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); ++ ++ _btif_irq_ctrl(p_rx_dma_info->p_irq, false); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_ENABLE); ++#endif ++ ++ hal_rx_dma_irq_handler(p_rx_dma_info, NULL, 0); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_DISABLE); ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++#endif ++ ++ _btif_irq_ctrl(p_rx_dma_info->p_irq, true); ++ ++ _btif_rx_btm_sched(p_btif); ++ ++ BTIF_DBG_FUNC("--\n"); ++ ++ return IRQ_HANDLED; ++} ++ ++unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, ++ unsigned int buf_len) ++{ ++ unsigned int index = 0; ++ p_mtk_btif p_btif = &(g_btif[index]); ++ ++#if 0 ++ _btif_dump_memory("", p_buf, buf_len); ++#endif ++ ++ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); ++/*save DMA Rx packet here*/ ++ if (buf_len > 0) ++ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); ++ ++ return 0; ++} ++ ++unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, ++ unsigned char *p_buf, ++ unsigned int buf_len) ++{ ++ unsigned int index = 0; ++ p_mtk_btif p_btif = &(g_btif[index]); ++ ++#if 0 ++ _btif_dump_memory("", p_buf, buf_len); ++#endif ++ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); ++ ++/*save PIO Rx packet here*/ ++ if (buf_len > 0) ++ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); ++ ++ return 0; ++} ++ ++bool btif_parser_wmt_evt(p_mtk_btif p_btif, ++ const char *sub_str, ++ unsigned int str_len) ++{ ++ unsigned int data_cnt = 0; ++ unsigned int copy_cnt = 0; ++ char *local_buf = NULL; ++ bool b_ret = false; ++ p_btif_buf_str p_bbs = &(p_btif->btif_buf); ++ unsigned int wr_idx = p_bbs->wr_idx; ++ unsigned int rd_idx = p_bbs->rd_idx; ++ ++ data_cnt = copy_cnt = BBS_COUNT(p_bbs); ++ ++ if (data_cnt < str_len) { ++ BTIF_WARN_FUNC("there is not enough data for parser,need(%d),have(%d)\n", str_len, data_cnt); ++ return false; ++ } ++ BTIF_INFO_FUNC("data count in bbs buffer:%d,wr_idx(%d),rd_idx(%d)\n", data_cnt, wr_idx, rd_idx); ++ local_buf = vmalloc((data_cnt + 3) & ~0x3UL); ++ if (!local_buf) { ++ BTIF_WARN_FUNC("vmalloc memory fail\n"); ++ return false; ++ } ++ ++ if (wr_idx >= rd_idx) { ++ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), copy_cnt); ++ } else { ++ unsigned int tail_len = BBS_SIZE(p_bbs) - rd_idx; ++ ++ BTIF_INFO_FUNC("tail_Len(%d)\n", tail_len); ++ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), tail_len); ++ memcpy(local_buf + tail_len, BBS_PTR(p_bbs, 0), copy_cnt - tail_len); ++ } ++ ++ do { ++ int i = 0; ++ int j = 0; ++ int k = 0; ++ int d = 0; ++ ++ BTIF_INFO_FUNC("sub_str_len:%d\n", str_len); ++ for (i = 0; i < copy_cnt; i++) { ++ BTIF_DBG_FUNC("i:%d\n", i); ++ k = i; ++ while (1) { ++ if ((j >= str_len) || (k >= copy_cnt) || (sub_str[j++] != local_buf[k++])) ++ break; ++ } ++ ++ if (j == str_len) { ++ for (d = i; d < (str_len + i); d++) ++ BTIF_INFO_FUNC("0x%2x", local_buf[d]); ++ BTIF_INFO_FUNC("find sub str index:%d\n", i); ++ b_ret = true; ++ break; ++ } ++ if (j < str_len) ++ j = 0; ++ } ++ ++ } while (0); ++ ++ vfree(local_buf); ++ return b_ret; ++} ++int _btif_controller_tx_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_tx_dma_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_tx_dma_setup failed,i_ret(%d),", ++ "set tx to PIO mode\n", i_ret); ++ i_ret = _btif_tx_pio_setup(p_btif); ++ } ++ } else ++/*enable Tx PIO mode*/ ++ i_ret = _btif_tx_pio_setup(p_btif); ++ ++ return i_ret; ++} ++ ++int _btif_controller_tx_free(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_tx_dma_free(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_tx_dma_free failed, i_ret(%d)\n", ++ i_ret); ++ } ++ } else { ++/*do nothing for Tx PIO mode*/ ++ } ++ return i_ret; ++} ++ ++int _btif_controller_rx_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_rx_dma_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_tx_dma_setup failed, i_ret(%d),", ++ "set tx to PIO mode\n", i_ret); ++ i_ret = _btif_rx_pio_setup(p_btif); ++ } ++ } else { ++/*enable Tx PIO mode*/ ++ i_ret = _btif_rx_pio_setup(p_btif); ++ } ++ return i_ret; ++} ++ ++int _btif_controller_rx_free(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ i_ret = _btif_rx_dma_free(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_rx_dma_free failed, i_ret(%d)\n", ++ i_ret); ++ } ++ } else { ++/*do nothing for Rx PIO mode*/ ++ } ++ return i_ret; ++} ++ ++int _btif_tx_pio_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ++/*set Tx to PIO mode*/ ++ p_btif->tx_mode = BTIF_MODE_PIO; ++/*enable Tx PIO mode*/ ++ i_ret = hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); ++ return i_ret; ++} ++ ++int _btif_rx_pio_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; ++ ++ p_btif->rx_mode = BTIF_MODE_PIO; ++/*Enable Rx IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, true); ++/*enable Rx PIO mode*/ ++ i_ret = hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); ++ return i_ret; ++} ++ ++int _btif_rx_dma_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = NULL; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = NULL; ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; ++ ++ p_btif_info = p_btif->p_btif_info; ++ p_btif_irq = p_dma_info->p_irq; ++ ++/*vFIFO reset*/ ++ hal_btif_vfifo_reset(p_dma_info); ++ ++ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d),", ++ "set rx to pio mode\n", i_ret); ++/*DMA control failed set Rx to PIO mode*/ ++ return _btif_rx_pio_setup(p_btif); ++ } ++/*hardware init*/ ++ hal_btif_dma_hw_init(p_dma_info); ++ ++ hal_btif_dma_rx_cb_reg(p_dma_info, ++ (dma_rx_buf_write) btif_dma_rx_data_receiver); ++ ++/*DMA controller enable*/ ++ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", ++ "set rx to pio mode\n", i_ret); ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++/*DMA control failed set Rx to PIO mode*/ ++ i_ret = _btif_rx_pio_setup(p_btif); ++ } else { ++/*enable Rx DMA mode*/ ++ hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); ++ ++/*DMA Rx IRQ register*/ ++ _btif_irq_reg(p_btif_irq, btif_rx_dma_irq_handler, p_btif); ++#if 0 ++/*Enable DMA Rx IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, true); ++#endif ++ BTIF_DBG_FUNC("succeed\n"); ++ } ++ return i_ret; ++} ++ ++int _btif_rx_dma_free(p_mtk_btif p_btif) ++{ ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; ++ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_rx_dma->p_dma_info->p_irq; ++ ++ hal_btif_dma_rx_cb_reg(p_dma_info, (dma_rx_buf_write) NULL); ++ _btif_irq_free(p_irq, p_btif); ++/*disable BTIF Rx DMA channel*/ ++ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); ++/*disable clock output*/ ++ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++} ++ ++int _btif_tx_dma_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = p_dma_info->p_irq; ++ ++/*vFIFO reset*/ ++ hal_btif_vfifo_reset(p_dma_info); ++ ++ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d)\n", ++ i_ret); ++ return i_ret; ++ } ++/*DMA controller setup*/ ++ hal_btif_dma_hw_init(p_dma_info); ++ ++/*DMA HW Enable*/ ++ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", ++ "set tx to pio mode\n", i_ret); ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++#endif ++ ++ _btif_tx_pio_setup(p_btif); ++ } else { ++ hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); ++/*DMA Tx IRQ register*/ ++ _btif_irq_reg(p_btif_irq, btif_tx_dma_irq_handler, p_btif); ++#if 0 ++/*disable DMA Tx IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, false); ++#endif ++ ++ BTIF_DBG_FUNC("succeed\n"); ++ } ++ return i_ret; ++} ++ ++int _btif_tx_dma_free(p_mtk_btif p_btif) ++{ ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; ++ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_tx_dma->p_dma_info->p_irq; ++ ++ _btif_irq_free(p_irq, p_btif); ++/*disable BTIF Tx DMA channel*/ ++ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); ++/*disable clock output*/ ++ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); ++} ++ ++int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) ++{ ++ int i_ret = -1; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++#if 0 ++ state = _btif_state_get(p_btif); ++ if (p_btif->enable && B_S_ON == state) ++ i_ret = _btif_lpbk_ctrl(p_btif, flag); ++ else ++ i_ret = E_BTIF_INVAL_STATE; ++#endif ++ i_ret = _btif_exit_dpidle(p_btif); ++ if (i_ret == 0) ++ i_ret = _btif_lpbk_ctrl(p_btif, flag); ++ else ++ i_ret = E_BTIF_INVAL_STATE; ++ ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) ++{ ++ int i_ret = -1; ++ ++ if (flag) { ++ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, true); ++ BTIF_DBG_FUNC("loopback function enabled\n"); ++ } else { ++ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, false); ++ BTIF_DBG_FUNC("loopback function disabled\n"); ++ } ++ if (i_ret == 0) ++ p_btif->lpbk_flag = flag; ++ ++ return i_ret; ++} ++ ++int btif_clock_ctrl(p_mtk_btif p_btif, int en) ++{ ++ int i_ret = 0; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ENUM_CLOCK_CTRL ctrl_flag = en == 0 ? CLK_OUT_DISABLE : CLK_OUT_ENABLE; ++ ++ i_ret = hal_btif_clk_ctrl(p_btif_info, ctrl_flag); ++ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ctrl_flag); ++ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ctrl_flag); ++ ++ return i_ret; ++} ++ ++int _btif_controller_setup(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; ++ ++/*BTIF rx buffer init*/ ++/* memset(p_btif->rx_buf, 0, BTIF_RX_BUFFER_SIZE); */ ++ BBS_INIT(&(p_btif->btif_buf)); ++/************************************************/ ++ hal_btif_rx_cb_reg(p_btif_info, ++ (btif_rx_buf_write) btif_pio_rx_data_receiver); ++ ++ i_ret = hal_btif_clk_ctrl(p_btif_info, CLK_OUT_ENABLE); ++ if (i_ret) { ++ BTIF_ERR_FUNC("hal_btif_clk_ctrl failed, i_ret(%d)\n", i_ret); ++ return i_ret; ++ } ++/*BTIF controller init*/ ++ i_ret = hal_btif_hw_init(p_btif_info); ++ if (i_ret) { ++ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); ++ BTIF_ERR_FUNC("hal_btif_hw_init failed, i_ret(%d)\n", i_ret); ++ return i_ret; ++ } ++ _btif_lpbk_ctrl(p_btif, p_btif->lpbk_flag); ++/*BTIF IRQ register*/ ++ i_ret = _btif_irq_reg(p_btif_irq, btif_irq_handler, p_btif); ++ if (i_ret) { ++ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); ++ ++ BTIF_ERR_FUNC("_btif_irq_reg failed, i_ret(%d)\n", i_ret); ++ return i_ret; ++ } ++ ++/*disable IRQ*/ ++ _btif_irq_ctrl(p_btif_irq, false); ++ i_ret = 0; ++ BTIF_DBG_FUNC("succeed\n"); ++ return i_ret; ++} ++ ++int _btif_controller_free(p_mtk_btif p_btif) ++{ ++/*No need to set BTIF to PIO mode, only enable BTIF CG*/ ++ hal_btif_rx_cb_reg(p_btif->p_btif_info, (btif_rx_buf_write) NULL); ++ _btif_irq_free(p_btif->p_btif_info->p_irq, p_btif); ++ return hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++} ++ ++int _btif_init(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ i_ret = _btif_controller_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_controller_init failed, i_ret(%d)\n", ++ i_ret); ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++ } ++ ++ i_ret = _btif_controller_tx_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", ++ i_ret); ++ _btif_controller_free(p_btif); ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++ } ++ ++ i_ret = _btif_controller_rx_setup(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", ++ i_ret); ++ _btif_controller_tx_free(p_btif); ++ _btif_controller_free(p_btif); ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++ } ++ return i_ret; ++} ++ ++int btif_open(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif->enable) ++ return E_BTIF_ALREADY_OPEN; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++/*disable deepidle*/ ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); ++ ++ i_ret = _btif_init(p_btif); ++ if (i_ret == 0) { ++ /*set BTIF's enable flag*/ ++ p_btif->enable = true; ++ _btif_state_set(p_btif, B_S_ON); ++ } else { ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ } ++ btif_log_buf_reset(&p_btif->tx_log); ++ btif_log_buf_reset(&p_btif->rx_log); ++ ++ BTIF_STATE_RELEASE(p_btif); ++ ++ BTIF_DBG_FUNC("BTIF's Tx Mode:%d, Rx Mode(%d)\n", ++ p_btif->tx_mode, p_btif->rx_mode); ++ return i_ret; ++} ++ ++int btif_close(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ if (!(p_btif->enable)) ++ return E_BTIF_NOT_OPEN; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++/*always set state back to B_S_ON before do close operation*/ ++ _btif_exit_dpidle(p_btif); ++/*set BTIF's state to disable state*/ ++ p_btif->enable = false; ++ ++ _btif_controller_free(p_btif); ++ _btif_controller_tx_free(p_btif); ++ _btif_controller_rx_free(p_btif); ++ ++/*reset BTIF's rx_cb function*/ ++ p_btif->rx_cb = NULL; ++ p_btif->rx_notify = NULL; ++ p_btif->lpbk_flag = false; ++ ++/*set state mechine to B_S_OFF*/ ++ _btif_state_set(p_btif, B_S_OFF); ++ ++ btif_log_buf_disable(&p_btif->tx_log); ++ btif_log_buf_disable(&p_btif->rx_log); ++ ++ BTIF_STATE_RELEASE(p_btif); ++ ++ return i_ret; ++} ++ ++int _btif_exit_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ENUM_BTIF_STATE state = B_S_MAX; ++ ++ state = _btif_state_get(p_btif); ++ switch (state) { ++ case B_S_DPIDLE: ++ i_ret = _btif_exit_dpidle_from_dpidle(p_btif); ++ break; ++ case B_S_SUSPEND: ++/*in suspend state, need to do reinit of btif*/ ++ i_ret = _btif_exit_dpidle_from_sus(p_btif); ++ break; ++ case B_S_OFF: ++ i_ret = _btif_init(p_btif); ++ break; ++ case B_S_ON: ++ i_ret = 0; /* for btif_close case */ ++ break; ++ default: ++ i_ret = E_BTIF_INVAL_PARAM; ++ BTIF_INFO_FUNC("invalid state change:%d->\n", state, B_S_ON); ++ break; ++ } ++ ++ if (i_ret == 0) ++ i_ret = _btif_state_set(p_btif, B_S_ON); ++ return i_ret; ++} ++ ++int btif_exit_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ i_ret = _btif_exit_dpidle(p_btif); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int _btif_enter_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ENUM_BTIF_STATE state = B_S_MAX; ++ ++ state = _btif_state_get(p_btif); ++ if (state == B_S_ON) { ++ i_ret = _btif_enter_dpidle_from_on(p_btif); ++ } else if (state == B_S_SUSPEND) { ++ /*do reinit and enter deepidle*/ ++ i_ret = _btif_enter_dpidle_from_sus(p_btif); ++ } else if (state == B_S_DPIDLE) { ++ /*do nothing*/ ++ i_ret = 0; ++ } else { ++ BTIF_WARN_FUNC("operation is not allowed, current state:%d\n", ++ state); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++/*anyway, set to B_S_DPIDLE state*/ ++ if (i_ret == 0) ++ i_ret = _btif_state_set(p_btif, B_S_DPIDLE); ++ return i_ret; ++} ++ ++int btif_enter_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*hold state mechine lock*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ i_ret = _btif_enter_dpidle(p_btif); ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++/*in dpidle state, only need to open related clock*/ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ /*enable BTIF Tx DMA's clock*/ ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ++ CLK_OUT_ENABLE); ++ } ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ /*enable BTIF Rx DMA's clock*/ ++ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ++ CLK_OUT_ENABLE); ++ } ++/*enable BTIF's clock*/ ++ i_ret += hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++ ++ if (i_ret != 0) ++ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif) ++{ ++/*in suspend state, need to do driver re-init*/ ++ ++ int i_ret = _btif_init(p_btif); ++ ++ return i_ret; ++} ++ ++int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif) ++{ ++/*do driiver reinit*/ ++ int i_ret = _btif_init(p_btif); ++ ++ if (i_ret == 0) ++ i_ret = _btif_enter_dpidle_from_on(p_btif); ++ return i_ret; ++} ++ ++int _btif_enter_dpidle_from_on(p_mtk_btif p_btif) ++{ ++#define MAX_WAIT_TIME_MS 5000 ++/* ++ * this max wait time cannot exceed 12s, ++ * because dpm will monitor each device's ++ * resume/suspend process by start up a watch dog timer of 12s ++ * incase of one driver's suspend/resume process block other device's suspend/resume ++ */ ++ int i_ret = 0; ++ unsigned int retry = 0; ++ unsigned int wait_period = 1; ++ unsigned int max_retry = MAX_WAIT_TIME_MS / wait_period; ++ struct timeval timer_start; ++ struct timeval timer_now; ++ ++ do_gettimeofday(&timer_start); ++ ++ while ((!_btif_is_tx_complete(p_btif)) && (retry < max_retry)) { ++ do_gettimeofday(&timer_now); ++ if ((MAX_WAIT_TIME_MS/1000) <= (timer_now.tv_sec - timer_start.tv_sec)) { ++ BTIF_WARN_FUNC("max retry timer expired, timer_start.tv_sec:%d, timer_now.tv_sec:%d,", ++ "retry:%d\n", timer_start.tv_sec, timer_now.tv_sec, retry); ++ break; ++ } ++ msleep(wait_period); ++ retry++; ++ } ++ ++ if (retry < max_retry) { ++ if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ /*disable BTIF Tx DMA's clock*/ ++ i_ret += ++ hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ } ++ if (p_btif->rx_mode == BTIF_MODE_DMA) { ++ /*disable BTIF Rx DMA's clock*/ ++ i_ret += ++ hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ } ++/*disable BTIF's clock*/ ++ i_ret += ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); ++ ++ if (i_ret) ++ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); ++ } else ++ i_ret = -1; ++ ++ return i_ret; ++} ++ ++int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++/*call WCP's API to control deepidle's enable/disable*/ ++ if (en_flag == BTIF_DPIDLE_DISABLE) ++ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_DIS); ++ else ++ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_EN); ++ ++ return 0; ++} ++ ++int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ if (p_btif->rx_cb) { ++ BTIF_WARN_FUNC ++ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", ++ p_btif->rx_cb, rx_cb); ++ } ++ p_btif->rx_cb = rx_cb; ++ ++ return 0; ++} ++ ++int btif_raise_wak_signal(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); ++#endif ++ ++ i_ret = hal_btif_raise_wak_sig(p_btif_info); ++ ++#if MTK_BTIF_ENABLE_CLK_REF_COUNTER ++ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); ++#endif ++ return i_ret; ++} ++ ++bool _btif_is_tx_complete(p_mtk_btif p_btif) ++{ ++ bool b_ret = false; ++ ENUM_BTIF_MODE tx_mode = p_btif->tx_mode; ++ ++/* ++ * make sure BTIF tx finished in PIO mode ++ * make sure BTIF tx finished and DMA tx finished in DMA mode ++ */ ++ if (tx_mode == BTIF_MODE_DMA) { ++ b_ret = hal_dma_is_tx_complete(p_btif->p_tx_dma->p_dma_info); ++ if (b_ret == false) { ++ BTIF_DBG_FUNC("Tx DMA is not finished\n"); ++ return b_ret; ++ } ++ } ++ ++ b_ret = hal_btif_is_tx_complete(p_btif->p_btif_info); ++ if (b_ret == false) { ++ BTIF_DBG_FUNC("BTIF Tx is not finished\n"); ++ return b_ret; ++ } ++ b_ret = true; ++ return b_ret; ++} ++ ++/*--------------------------------Functions-------------------------------------------*/ ++ ++#if ENABLE_BTIF_TX_DMA ++static int _btif_vfifo_init(p_mtk_btif_dma p_dma) ++{ ++ P_DMA_VFIFO p_vfifo = NULL; ++ struct device *dev = NULL; ++ p_mtk_btif p_btif = NULL; ++ ++ if (p_dma == NULL) { ++ BTIF_ERR_FUNC("p_dma is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ p_btif = (p_mtk_btif)p_dma->p_btif; ++ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ dev = (struct device *)p_btif->private_data; ++ if (dev == NULL) ++ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); ++ ++ p_vfifo = p_dma->p_dma_info->p_vfifo; ++ if (p_vfifo->p_vir_addr != NULL) { ++ BTIF_ERR_FUNC ++ ("BTIF vFIFO memory already allocated, do nothing\n"); ++ return E_BTIF_BAD_POINTER; ++ } ++ ++/*vFIFO memory allocation*/ ++ p_vfifo->p_vir_addr = dma_zalloc_coherent(dev, ++ p_vfifo->vfifo_size, ++ &p_vfifo->phy_addr, GFP_DMA | GFP_DMA32); ++ if (p_vfifo->p_vir_addr == NULL) { ++ BTIF_ERR_FUNC("alloc vFIFO memory for BTIF failed\n"); ++ return E_BTIF_FAIL; ++ } ++ ++ if (sizeof(dma_addr_t) == sizeof(unsigned long long)) ++ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch64,vir addr:0x%p,", ++ "phy addr:0x%llx\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); ++ else ++ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch32,vir addr:0x%p,", ++ "phy addr:0x%08x\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); ++ ++ return 0; ++} ++#endif ++#if ENABLE_BTIF_TX_DMA ++static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma) ++{ ++ P_DMA_VFIFO p_vfifo = NULL; ++ struct device *dev = NULL; ++ p_mtk_btif p_btif = NULL; ++ ++ if (p_dma == NULL) { ++ BTIF_ERR_FUNC("p_dma is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ ++ p_btif = (p_mtk_btif)p_dma->p_btif; ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ dev = (struct device *)p_btif->private_data; ++ if (dev == NULL) ++ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); ++ ++ p_vfifo = p_dma->p_dma_info->p_vfifo; ++ ++/*free DMA memory if allocated successfully before*/ ++ if (p_vfifo->p_vir_addr != NULL) { ++ dma_free_coherent(dev, ++ p_vfifo->vfifo_size, ++ p_vfifo->p_vir_addr, p_vfifo->phy_addr); ++ p_vfifo->p_vir_addr = NULL; ++ } ++ ++ return 0; ++} ++#endif ++ ++static int _btif_state_init(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ p_btif->state = B_S_OFF; ++ mutex_init(&(p_btif->state_mtx)); ++ ++ return 0; ++} ++ ++static int _btif_state_hold(p_mtk_btif p_btif) ++{ ++ return mutex_lock_killable(&(p_btif->state_mtx)); ++} ++ ++static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state) ++{ ++/*chaozhong: To do: need to finished state mechine here*/ ++ int i_ret = 0; ++ int ori_state = p_btif->state; ++ ++ if (ori_state == state) { ++ BTIF_INFO_FUNC("already in %s state\n", g_state[state]); ++ return i_ret; ++ } ++ if ((state >= B_S_OFF) && (state < B_S_MAX)) { ++ BTIF_DBG_FUNC("%s->%s request\n", g_state[ori_state], ++ g_state[state]); ++ if (state == B_S_ON) ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); ++ switch (ori_state) { ++ case B_S_ON: ++/*B_S_ON can only be switched to B_S_OFF, B_S_SUSPEND and B_S_DPIDLE*/ ++/*B_S_ON->B_S_OFF : do nothing here*/ ++/* ++ * B_S_ON->B_S_DPLE : disable clock backup ++ * BTIF and DMA controller's register if necessary ++ */ ++ if (state == B_S_DPIDLE) { ++ /*clock controlled id done in _btif_enter_dpidle*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_OFF) { ++ /*clock controlled is done in btif_close*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_SUSPEND) { ++ /*clock controlled is done in btif_close*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ break; ++ case B_S_DPIDLE: ++/*B_S_DPIDLE can only be switched to B_S_ON and B_S_SUSPEND*/ ++/*B_S_DPIDLE-> B_S_ON: do nothing for this moment*/ ++/* ++ * B_S_DPIDLE-> B_S_SUSPEND: ++ * disable clock backup BTIF and DMA controller's register if necessary ++ */ ++ if (state == B_S_ON) { ++ /*clock controlled id done in _btif_exit_dpidle*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_SUSPEND) { ++ /*clock controlled is done in _btif_exit_dpidle*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ break; ++ ++ case B_S_SUSPEND: ++/*B_S_SUSPEND can be switched to B_S_IDLE and B_S_ON*/ ++/*reinit BTIF controller and DMA controller*/ ++ if (state == B_S_DPIDLE) { ++ /* ++ * system call resume API, do resume operation, ++ * change to deepidle state ++ */ ++ p_btif->state = state; ++ i_ret = 0; ++ } else if (state == B_S_ON) { ++ /* ++ * when stp want to send data before ++ * system do resume operation ++ */ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ break; ++ ++ case B_S_OFF:{ ++/*B_S_OFF can only be switched to B_S_ON*/ ++ if (state == B_S_ON) { ++ /*clock controlled is done in btif_open*/ ++ p_btif->state = state; ++ i_ret = 0; ++ } else { ++ BTIF_ERR_FUNC("%s->%s is not allowed\n", ++ g_state[ori_state], ++ g_state[state]); ++ i_ret = E_BTIF_INVAL_STATE; ++ } ++ } ++ break; ++ default: ++/*no this possibility*/ ++ BTIF_ERR_FUNC ++ ("state change request is not allowed, this should never happen\n"); ++ break; ++ } ++ ++ if (state != B_S_ON) ++ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); ++ ++ } else { ++ i_ret = E_BTIF_INVAL_PARAM; ++ BTIF_ERR_FUNC("invalid state:%d, do nothing\n", state); ++ } ++ return i_ret; ++} ++ ++static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif) ++{ ++ return p_btif->state; ++} ++ ++static int _btif_state_release(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ BTIF_MUTEX_UNLOCK(&(p_btif->state_mtx)); ++ return i_ret; ++} ++ ++static int _btif_state_deinit(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ p_btif->state = B_S_OFF; ++ mutex_destroy(&(p_btif->state_mtx)); ++ ++ return 0; ++} ++ ++static int btif_rx_data_consummer(p_mtk_btif p_btif) ++{ ++ unsigned int length = 0; ++ unsigned char *p_buf = NULL; ++/*get BTIF rx buffer's information*/ ++ p_btif_buf_str p_bbs = &(p_btif->btif_buf); ++/* ++ * wr_idx of btif_buf may be modified in IRQ handler, ++ * in order not to be effected by case in which irq interrupt this operation, ++ * we record wr_idx here ++ */ ++ unsigned int wr_idx = p_bbs->wr_idx; ++ ++ length = BBS_COUNT_CUR(p_bbs, wr_idx); ++ ++/*make sure length of rx buffer data > 0*/ ++ do { ++ if (length > 0) { ++ /* ++ * check if rx_cb empty or not, if registered , ++ * call user's rx callback to handle these data ++ */ ++ if (p_btif->rx_cb) { ++ if (p_bbs->rd_idx <= wr_idx) { ++ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); ++ /* p_buf = &(p_bbs->buf[p_bbs->rd_idx]); */ ++ /* length = BBS_COUNT(p_bbs); */ ++ length = (wr_idx >= (p_bbs)->rd_idx) ? ++ (wr_idx - (p_bbs)->rd_idx) : ++ BBS_SIZE(p_bbs) - ++ ((p_bbs)->rd_idx - wr_idx); ++ if (p_btif->rx_cb) ++ (*(p_btif->rx_cb)) (p_buf, length); ++ else ++ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); ++ /*update rx data read index*/ ++ p_bbs->rd_idx = wr_idx; ++ } else { ++ unsigned int len_tail = ++ BBS_SIZE(p_bbs) - (p_bbs)->rd_idx; ++ /*p_buf = &(p_bbs->buf[p_bbs->->rd_idx]);*/ ++ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); ++ if (p_btif->rx_cb) ++ (*(p_btif->rx_cb)) (p_buf, len_tail); ++ else ++ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); ++ length = BBS_COUNT_CUR(p_bbs, wr_idx); ++ length -= len_tail; ++ /*p_buf = &(p_bbs->buf[0]);*/ ++ p_buf = BBS_PTR(p_bbs, 0); ++ if (p_btif->rx_cb) ++ (*(p_btif->rx_cb)) (p_buf, length); ++ else ++ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); ++ /*update rx data read index*/ ++ p_bbs->rd_idx = wr_idx; ++ } ++ } else if (p_btif->rx_notify != NULL) { ++ (*p_btif->rx_notify) (); ++ } else { ++ BTIF_WARN_FUNC ++ ("p_btif:0x%p, both rx_notify and rx_cb are NULL\n", ++ p_btif); ++ break; ++ } ++ } else { ++ BTIF_DBG_FUNC("length:%d\n", length); ++ break; ++ } ++ wr_idx = p_bbs->wr_idx; ++ length = BBS_COUNT_CUR(p_bbs, wr_idx); ++ } while (1); ++ return length; ++} ++ ++#if BTIF_RXD_BE_BLOCKED_DETECT ++static int mtk_btif_rxd_be_blocked_by_timer(void) ++{ ++ int ret = 0; ++ int counter = 0; ++ unsigned int i; ++ struct timeval now; ++ int time_gap[MAX_BTIF_RXD_TIME_REC]; ++ ++ do_gettimeofday(&now); ++ ++ for (i = 0; i < MAX_BTIF_RXD_TIME_REC; i++) { ++ BTIF_INFO_FUNC("btif_rxd_time_stamp[%d]=%d.%d\n", i, ++ btif_rxd_time_stamp[i].tv_sec, btif_rxd_time_stamp[i].tv_usec); ++ if (now.tv_sec >= btif_rxd_time_stamp[i].tv_sec) { ++ time_gap[i] = now.tv_sec - btif_rxd_time_stamp[i].tv_sec; ++ time_gap[i] *= 1000000; /*second*/ ++ if (now.tv_usec >= btif_rxd_time_stamp[i].tv_usec) ++ time_gap[i] += now.tv_usec - btif_rxd_time_stamp[i].tv_usec; ++ else ++ time_gap[i] += 1000000 - now.tv_usec + btif_rxd_time_stamp[i].tv_usec; ++ ++ if (time_gap[i] > 1000000) ++ counter++; ++ BTIF_INFO_FUNC("time_gap[%d]=%d,counter:%d\n", i, time_gap[i], counter); ++ } else { ++ time_gap[i] = 0; ++ BTIF_ERR_FUNC("abnormal case now:%d < time_stamp[%d]:%d\n", now.tv_sec, ++ i, btif_rxd_time_stamp[i].tv_usec); ++ } ++ } ++ if (counter > (MAX_BTIF_RXD_TIME_REC - 2)) ++ ret = 1; ++ return ret; ++} ++static int mtk_btif_rxd_be_blocked_by_data(void) ++{ ++ unsigned int out_index = 0; ++ unsigned int in_index = 0; ++ unsigned int dump_size = 0; ++ unsigned int len = 0; ++ unsigned long flags; ++ unsigned int sync_pkt_n = 0; ++ P_BTIF_LOG_BUF_T p_log_buf = NULL; ++ P_BTIF_LOG_QUEUE_T p_log_que = NULL; ++ p_mtk_btif p_btif = &(g_btif[0]); ++ ++ p_log_que = &p_btif->rx_log; ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ in_index = p_log_que->in; ++ dump_size = p_log_que->size; ++ out_index = p_log_que->size >= ++ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - ++ p_log_que->size + ++ in_index) % BTIF_LOG_ENTRY_NUM; ++ if (dump_size != 0) { ++ while (dump_size--) { ++ p_log_buf = p_log_que->p_queue[0] + out_index; ++ len = p_log_buf->len; ++ if (len > BTIF_LOG_SZ) ++ len = BTIF_LOG_SZ; ++ if ((0x7f == *(p_log_buf->buffer)) && (0x7f == *(p_log_buf->buffer + 1))) { ++ sync_pkt_n++; ++ BTIF_INFO_FUNC("tx pkt_count:%d is sync pkt\n", out_index); ++ } ++ out_index++; ++ out_index %= BTIF_LOG_ENTRY_NUM; ++ } ++ } ++ if (sync_pkt_n == 0) ++ BTIF_ERR_FUNC("there is no sync pkt in BTIF buffer\n"); ++ else ++ BTIF_ERR_FUNC("there are %d sync pkt in BTIF buffer\n", sync_pkt_n); ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ return sync_pkt_n; ++} ++ ++int mtk_btif_rxd_be_blocked_flag_get(void) ++{ ++ int ret = 0; ++ int condition1 = 0, condition2 = 0; ++ ++ condition1 = mtk_btif_rxd_be_blocked_by_timer(); ++ condition2 = mtk_btif_rxd_be_blocked_by_data(); ++ if (condition1 && condition2) { ++ BTIF_ERR_FUNC("btif_rxd thread be blocked too long!\n"); ++ ret = 1; ++ } ++ return ret; ++} ++#endif ++static int btif_rx_thread(void *p_data) ++{ ++#if BTIF_RXD_BE_BLOCKED_DETECT ++ unsigned int i = 0; ++#endif ++ p_mtk_btif p_btif = (p_mtk_btif)p_data; ++ ++ ++ while (1) { ++ wait_for_completion_interruptible(&p_btif->rx_comp); ++ ++ if (kthread_should_stop()) { ++ BTIF_WARN_FUNC("btif rx thread stoping ...\n"); ++ break; ++ } ++#ifdef BTIF_RXD_BE_BLOCKED_DETECT ++ do_gettimeofday(&btif_rxd_time_stamp[i]); ++ i++; ++ if (i >= MAX_BTIF_RXD_TIME_REC) ++ i = 0; ++#endif ++ btif_rx_data_consummer(p_btif); ++ } ++ return 0; ++} ++ ++static void btif_rx_worker(struct work_struct *p_work) ++{ ++/*get mtk_btif's pointer*/ ++ p_mtk_btif p_btif = container_of(p_work, mtk_btif, rx_work); ++ ++ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); ++/*lock rx_mutex*/ ++ ++ if (mutex_lock_killable(&(p_btif->rx_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return; ++ } ++ btif_rx_data_consummer(p_btif); ++ BTIF_MUTEX_UNLOCK(&(p_btif->rx_mtx)); ++} ++ ++static void btif_tx_worker(struct work_struct *p_work) ++{ ++ int i_ret = 0; ++ int leng_sent = 0; ++/*tx fifo out*/ ++ int how_much_get = 0; ++ unsigned char local_buf[384]; ++ ++/*get mtk_btif's pointer*/ ++ p_mtk_btif p_btif = container_of(p_work, mtk_btif, tx_work); ++ ++ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); ++ ++ if (mutex_lock_killable(&(p_btif->tx_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return; ++ } ++ how_much_get = ++ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); ++ do { ++ while (leng_sent < how_much_get) { ++ i_ret = _btif_send_data(p_btif, ++ local_buf + leng_sent, ++ how_much_get - leng_sent); ++ if (i_ret > 0) { ++ leng_sent += i_ret; ++ } else if (i_ret == 0) { ++ BTIF_WARN_FUNC ++ ("_btif_send_data return 0, retry\n"); ++ } else { ++ BTIF_WARN_FUNC ++ ("btif send data fail,reset tx fifo, i_ret(%d)\n", ++ i_ret); ++ kfifo_reset(p_btif->p_tx_fifo); ++ break; ++ } ++ } ++ how_much_get = ++ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); ++ leng_sent = 0; ++ } while (how_much_get > 0); ++ BTIF_MUTEX_UNLOCK(&(p_btif->tx_mtx)); ++} ++ ++static void btif_rx_tasklet(unsigned long func_data) ++{ ++ unsigned long flags; ++/*get mtk_btif's pointer*/ ++ p_mtk_btif p_btif = (p_mtk_btif) func_data; ++ ++ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); ++/*lock rx_spinlock*/ ++ spin_lock_irqsave(&p_btif->rx_tasklet_spinlock, flags); ++ btif_rx_data_consummer(p_btif); ++ spin_unlock_irqrestore(&p_btif->rx_tasklet_spinlock, flags); ++} ++ ++static int _btif_tx_ctx_init(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ p_btif->p_tx_wq = create_singlethread_workqueue("btif_txd"); ++ ++ if (!(p_btif->p_tx_wq)) { ++ BTIF_ERR_FUNC ++ ("create_singlethread_workqueue for tx thread fail\n"); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ mutex_init(&(p_btif->tx_mtx)); ++/* init btif tx work */ ++ INIT_WORK(&(p_btif->tx_work), btif_tx_worker); ++ BTIF_INFO_FUNC("btif_tx_worker init succeed\n"); ++ ++ p_btif->p_tx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); ++ if (p_btif->p_tx_fifo == NULL) { ++ i_ret = -ENOMEM; ++ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); ++ goto btm_init_err; ++ } ++ ++ i_ret = kfifo_alloc(p_btif->p_tx_fifo, ++ BTIF_TX_FIFO_SIZE, GFP_ATOMIC); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ } else if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { ++ BTIF_INFO_FUNC ++ ("nothing is done when btif tx in user's thread\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported tx context type:%d\n", ++ p_btif->tx_ctx); ++ goto btm_init_err; ++ } ++ ++ BTIF_INFO_FUNC("succeed\n"); ++ ++ i_ret = 0; ++ return i_ret; ++btm_init_err: ++ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ if (p_btif->p_tx_wq) { ++ destroy_workqueue(p_btif->p_tx_wq); ++ p_btif->p_tx_wq = NULL; ++ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); ++ } ++ kfree(p_btif->p_tx_fifo); ++ } ++ return i_ret; ++} ++ ++static int _btif_tx_ctx_deinit(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ ++ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ if (p_btif->p_tx_wq) { ++ destroy_workqueue(p_btif->p_tx_wq); ++ p_btif->p_tx_wq = NULL; ++ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); ++ } ++ if (p_btif->p_tx_fifo) { ++ kfifo_free(p_btif->p_tx_fifo); ++ kfree(p_btif->p_tx_fifo); ++ p_btif->p_tx_fifo = NULL; ++ } ++ } ++ return i_ret; ++} ++ ++static int _btif_rx_btm_init(p_mtk_btif p_btif) ++{ ++ int i_ret = -1; ++ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ init_completion(&p_btif->rx_comp); ++ ++ /*create kernel thread for later rx data handle*/ ++ p_btif->p_task = kthread_create(btif_rx_thread, p_btif, "btif_rxd"); ++ if (p_btif->p_task == NULL) { ++ BTIF_ERR_FUNC("kthread_create fail\n"); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ ++#if ENABLE_BTIF_RX_THREAD_RT_SCHED ++ { ++ int i_ret = -1; ++ int policy = SCHED_FIFO; ++ struct sched_param param; ++ ++ param.sched_priority = MAX_RT_PRIO - 20; ++ i_ret = sched_setscheduler(p_btif->p_task, policy, ¶m); ++ if (i_ret != 0) ++ BTIF_WARN_FUNC("set RT to btif_rxd workqueue failed\n"); ++ else ++ BTIF_INFO_FUNC("set RT to btif_rxd workqueue succeed\n"); ++ } ++#endif ++ ++ wake_up_process(p_btif->p_task); ++ BTIF_INFO_FUNC("btif_rxd start to work!\n"); ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ p_btif->p_rx_wq = create_singlethread_workqueue("btif_rxwq"); ++ if (!(p_btif->p_rx_wq)) { ++ BTIF_ERR_FUNC("create_singlethread_workqueue fail\n"); ++ i_ret = -ENOMEM; ++ goto btm_init_err; ++ } ++ mutex_init(&(p_btif->rx_mtx)); ++ /* init btif rx work */ ++ INIT_WORK(&(p_btif->rx_work), btif_rx_worker); ++ BTIF_INFO_FUNC("btif_rx_worker init succeed\n"); ++ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { ++ /*init rx tasklet*/ ++ tasklet_init(&(p_btif->rx_tasklet), btif_rx_tasklet, ++ (unsigned long)p_btif); ++ spin_lock_init(&(p_btif->rx_tasklet_spinlock)); ++ BTIF_INFO_FUNC("btif_rx_tasklet init succeed\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported rx context type:%d\n", ++ p_btif->btm_type); ++ } ++ ++/*spinlock init*/ ++ spin_lock_init(&(p_btif->rx_irq_spinlock)); ++ BTIF_INFO_FUNC("rx_spin_lock init succeed\n"); ++ ++ i_ret = 0; ++ return i_ret; ++btm_init_err: ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ /*do nothing*/ ++ BTIF_INFO_FUNC("failed\n"); ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ if (p_btif->p_rx_wq) { ++ destroy_workqueue(p_btif->p_rx_wq); ++ p_btif->p_rx_wq = NULL; ++ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); ++ } ++ } ++ return i_ret; ++} ++ ++static int _btif_rx_btm_sched(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ complete(&p_btif->rx_comp); ++ BTIF_DBG_FUNC("schedule btif_rx_thread\n"); ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ queue_work(p_btif->p_rx_wq, &(p_btif->rx_work)); ++ BTIF_DBG_FUNC("schedule btif_rx_worker\n"); ++ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { ++ /*schedule it!*/ ++ tasklet_schedule(&(p_btif->rx_tasklet)); ++ BTIF_DBG_FUNC("schedule btif_rx_tasklet\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported rx context type:%d\n", ++ p_btif->btm_type); ++ } ++ ++ return 0; ++} ++ ++static int _btif_rx_btm_deinit(p_mtk_btif p_btif) ++{ ++ if (p_btif == NULL) { ++ BTIF_ERR_FUNC("p_btif is NULL\n"); ++ return E_BTIF_INVAL_PARAM; ++ } ++ if (p_btif->btm_type == BTIF_THREAD_CTX) { ++ if (p_btif->p_task != NULL) { ++ BTIF_INFO_FUNC("signaling btif rx thread to stop ...\n"); ++ kthread_stop(p_btif->p_task); ++ } ++ } else if (p_btif->btm_type == BTIF_WQ_CTX) { ++ if (p_btif->p_rx_wq) { ++ cancel_work_sync(&(p_btif->rx_work)); ++ BTIF_INFO_FUNC("btif_rx_worker cancelled\n"); ++ destroy_workqueue(p_btif->p_rx_wq); ++ p_btif->p_rx_wq = NULL; ++ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); ++ } ++ mutex_destroy(&(p_btif->rx_mtx)); ++ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { ++ tasklet_kill(&(p_btif->rx_tasklet)); ++ BTIF_INFO_FUNC("rx_tasklet killed\n"); ++ } else { ++ BTIF_ERR_FUNC("unsupported rx context type:%d\n", ++ p_btif->btm_type); ++ } ++ ++ spin_lock_init(&(p_btif->rx_irq_spinlock)); ++ ++ return 0; ++} ++ ++ ++void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs) ++{ ++ BTIF_INFO_FUNC ++ ("%s UBS:0x%p\n Size:0x%p\n read:0x%08x\n write:0x%08x\n", ++ p_str, p_bbs, p_bbs->size, p_bbs->rd_idx, p_bbs->wr_idx); ++} ++ ++unsigned int btif_bbs_write(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len) ++{ ++/*in IRQ context, so read operation won't interrupt this operation*/ ++ ++ unsigned int wr_len = 0; ++ ++ unsigned int emp_len = BBS_LEFT(p_bbs); ++ unsigned int ava_len = emp_len - 1; ++ p_mtk_btif p_btif = container_of(p_bbs, mtk_btif, btif_buf); ++ ++ if (ava_len <= 0) { ++ BTIF_ERR_FUNC ++ ("no empty space left for write, (%d)ava_len, (%d)to write\n", ++ ava_len, buf_len); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ return 0; ++ } ++ ++ if (ava_len < buf_len) { ++ BTIF_ERR_FUNC("BTIF overrun, (%d)empty, (%d)needed\n", ++ emp_len, buf_len); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ _btif_dump_memory("", p_buf, buf_len); ++ } ++ ++ if (buf_len >= g_max_pkg_len) { ++ BTIF_WARN_FUNC("buf_len too long, (%d)ava_len, (%d)to write\n", ++ ava_len, buf_len); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ _btif_dump_memory("", p_buf, buf_len); ++ } ++ ++ wr_len = min(buf_len, ava_len); ++ btif_bbs_wr_direct(p_bbs, p_buf, wr_len); ++ ++ if (BBS_COUNT(p_bbs) >= g_max_pding_data_size) { ++ BTIF_WARN_FUNC("Rx buf_len too long, size(%d)\n", ++ BBS_COUNT(p_bbs)); ++ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ _btif_dump_memory("", p_buf, buf_len); ++ BBS_INIT(p_bbs); ++ } ++ ++ return wr_len; ++} ++ ++unsigned int btif_bbs_read(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int rd_len = 0; ++ unsigned int ava_len = 0; ++ unsigned int wr_idx = p_bbs->wr_idx; ++ ++ ava_len = BBS_COUNT_CUR(p_bbs, wr_idx); ++ if (ava_len >= 4096) { ++ BTIF_WARN_FUNC("ava_len too long, size(%d)\n", ava_len); ++ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); ++ } ++ if (ava_len != 0) { ++ if (buf_len >= ava_len) { ++ rd_len = ava_len; ++ if (wr_idx >= (p_bbs)->rd_idx) { ++ memcpy(p_buf, BBS_PTR(p_bbs, ++ p_bbs->rd_idx), ++ ava_len); ++ (p_bbs)->rd_idx = wr_idx; ++ } else { ++ unsigned int tail_len = BBS_SIZE(p_bbs) - ++ (p_bbs)->rd_idx; ++ memcpy(p_buf, BBS_PTR(p_bbs, ++ p_bbs->rd_idx), ++ tail_len); ++ memcpy(p_buf + tail_len, BBS_PTR(p_bbs, ++ 0), ava_len - tail_len); ++ (p_bbs)->rd_idx = wr_idx; ++ } ++ } else { ++ rd_len = buf_len; ++ if (wr_idx >= (p_bbs)->rd_idx) { ++ memcpy(p_buf, BBS_PTR(p_bbs, ++ p_bbs->rd_idx), ++ rd_len); ++ (p_bbs)->rd_idx = (p_bbs)->rd_idx + rd_len; ++ } else { ++ unsigned int tail_len = BBS_SIZE(p_bbs) - ++ (p_bbs)->rd_idx; ++ if (tail_len >= rd_len) { ++ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), ++ rd_len); ++ (p_bbs)->rd_idx = ++ ((p_bbs)->rd_idx + rd_len) & (BBS_MASK(p_bbs)); ++ } else { ++ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), tail_len); ++ memcpy(p_buf + tail_len, ++ (p_bbs)->p_buf, rd_len - tail_len); ++ (p_bbs)->rd_idx = rd_len - tail_len; ++ } ++ } ++ } ++ } ++ mb(); ++ return rd_len; ++} ++ ++unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, ++ unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int tail_len = 0; ++ unsigned int l = 0; ++ unsigned int tmp_wr_idx = p_bbs->wr_idx; ++ ++ tail_len = BBS_SIZE(p_bbs) - (tmp_wr_idx & BBS_MASK(p_bbs)); ++ ++ l = min(tail_len, buf_len); ++ ++ memcpy((p_bbs->p_buf) + (tmp_wr_idx & BBS_MASK(p_bbs)), p_buf, l); ++ memcpy(p_bbs->p_buf, p_buf + l, buf_len - l); ++ ++ mb(); ++ ++ tmp_wr_idx += buf_len; ++ tmp_wr_idx &= BBS_MASK(p_bbs); ++ p_bbs->wr_idx = tmp_wr_idx; ++ ++ mb(); ++ return buf_len; ++} ++ ++int _btif_dma_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int i_ret = 0; ++ unsigned int retry = 0; ++ unsigned int max_tx_retry = 10; ++ ++ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; ++ ++ _btif_irq_ctrl_sync(p_dma_info->p_irq, false); ++ do { ++ /*wait until tx is allowed*/ ++ while (!hal_dma_is_tx_allow(p_dma_info) && ++ (retry < max_tx_retry)) { ++ retry++; ++ if (retry >= max_tx_retry) { ++ BTIF_ERR_FUNC("wait for tx allowed timeout\n"); ++ break; ++ } ++ } ++ if (retry >= max_tx_retry) ++ break; ++ ++ if (buf_len <= hal_dma_get_ava_room(p_dma_info)) ++ i_ret = hal_dma_send_data(p_dma_info, p_buf, buf_len); ++ else ++ i_ret = 0; ++ } while (0); ++ _btif_irq_ctrl_sync(p_dma_info->p_irq, true); ++ return i_ret; ++} ++ ++int _btif_pio_write(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int i_ret = 0; ++ unsigned int sent_len = 0; ++ unsigned int retry = 0; ++ unsigned int max_tx_retry = 10; ++ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; ++ ++ while ((sent_len < buf_len)) { ++ if (hal_btif_is_tx_allow(p_btif_info)) { ++ i_ret = hal_btif_send_data(p_btif_info, ++ p_buf + sent_len, ++ buf_len - sent_len); ++ if (i_ret > 0) { ++ sent_len += i_ret; ++ BTIF_DBG_FUNC("lent sent:%d, total sent:%d\n", ++ i_ret, sent_len); ++ retry = 0; ++ } ++ } ++ if ((++retry > max_tx_retry) || (i_ret < 0)) { ++ BTIF_INFO_FUNC("exceed retry times limit :%d\n", retry); ++ break; ++ } ++ } ++ i_ret = sent_len; ++ return i_ret; ++} ++ ++int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len) ++{ ++ unsigned int idx = 0; ++ ++ pr_debug("%s:, length:%d\n", str, buf_len); ++ for (idx = 0; idx < buf_len;) { ++ pr_debug("%02x ", p_buf[idx]); ++ idx++; ++ if (idx % 8 == 0) ++ pr_debug("\n"); ++ } ++ return 0; ++} ++ ++int btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ int i_ret = 0; ++ ++ if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { ++ i_ret = _btif_send_data(p_btif, p_buf, buf_len); ++ } else if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { ++ int length = 0; ++/*tx fifo in*/ ++ length = kfifo_in(p_btif->p_tx_fifo, ++ (unsigned char *)p_buf, buf_len); ++ if (length == buf_len) { ++ queue_work(p_btif->p_tx_wq, &(p_btif->tx_work)); ++ BTIF_DBG_FUNC("schedule btif_tx_worker\n"); ++ i_ret = length; ++ } else { ++ i_ret = 0; ++ BTIF_ERR_FUNC("fifo in failed, target len(%d),in len(%d),", ++ "don't schedule btif_tx_worker\n", buf_len, length); ++ } ++ } else { ++ BTIF_ERR_FUNC("invalid btif tx context:%d\n", p_btif->tx_ctx); ++ i_ret = 0; ++ } ++ ++ return i_ret; ++} ++ ++int _btif_send_data(p_mtk_btif p_btif, ++ const unsigned char *p_buf, unsigned int buf_len) ++{ ++ int i_ret = 0; ++ unsigned int state = 0; ++ ++/*make sure BTIF in ON state before doing tx operation*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ state = _btif_state_get(p_btif); ++ ++ if (state != B_S_ON) ++ i_ret = _btif_exit_dpidle(p_btif); ++ ++ if (i_ret != 0) { ++ i_ret = E_BTIF_INVAL_STATE; ++ } else if (p_btif->tx_mode == BTIF_MODE_DMA) { ++ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ ++ i_ret = _btif_dma_write(p_btif, p_buf, buf_len); ++ } else if (p_btif->tx_mode == BTIF_MODE_PIO) { ++ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ ++ i_ret = _btif_pio_write(p_btif, p_buf, buf_len); ++ } else { ++ BTIF_ERR_FUNC("invalid tx mode:%d\n", p_btif->tx_mode); ++ i_ret = 0; ++ } ++ ++/*save Tx packet here*/ ++ if (i_ret > 0) ++ btif_log_buf_dmp_in(&p_btif->tx_log, p_buf, i_ret); ++ ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int btif_dump_reg(p_mtk_btif p_btif) ++{ ++ int i_ret = 0; ++ unsigned int ori_state = 0; ++ ++/*make sure BTIF in ON state before doing tx operation*/ ++ if (_btif_state_hold(p_btif)) ++ return E_BTIF_INTR; ++ ori_state = _btif_state_get(p_btif); ++ ++ if (ori_state == B_S_OFF) { ++ i_ret = E_BTIF_INVAL_STATE; ++ BTIF_ERR_FUNC ++ ("BTIF in OFF state, ", ++ "should no need to dump register, ", ++ "please check wmt's operation is okay or not.\n"); ++ goto dmp_reg_err; ++ } ++ ++ if ((ori_state != B_S_ON) && (ori_state < B_S_MAX)) { ++ BTIF_ERR_FUNC("BTIF's original state is %s, not B_S_ON\n", g_state[ori_state]); ++ BTIF_ERR_FUNC("!!!!---<<>>---!!!"); ++ i_ret = _btif_exit_dpidle(p_btif); ++ } ++ ++ if (i_ret != 0) { ++ i_ret = E_BTIF_INVAL_STATE; ++ BTIF_ERR_FUNC("switch to B_S_ON failed\n"); ++ goto dmp_reg_err; ++ } ++ ++/*dump BTIF register*/ ++ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); ++ ++/*dump BTIF Tx DMA channel register if in DMA mode*/ ++ if (p_btif->tx_mode == BTIF_MODE_DMA) ++ hal_dma_dump_reg(p_btif->p_tx_dma->p_dma_info, REG_TX_DMA_ALL); ++ else ++ BTIF_INFO_FUNC("BTIF Tx in PIO mode,no need to dump Tx DMA's register\n"); ++ ++/*dump BTIF Rx DMA channel register if in DMA mode*/ ++ if (p_btif->rx_mode == BTIF_MODE_DMA) ++ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); ++ else ++ BTIF_INFO_FUNC("BTIF Rx in PIO mode,no need to dump Rx DMA's register\n"); ++ ++ switch (ori_state) { ++ case B_S_SUSPEND: ++/*return to dpidle state*/ ++/* break; */ ++ case B_S_DPIDLE: ++/*return to dpidle state*/ ++ _btif_enter_dpidle(p_btif); ++ break; ++ case B_S_ON: ++/*nothing needs to be done*/ ++ break; ++ default: ++ break; ++ } ++ ++dmp_reg_err: ++ ++ BTIF_STATE_RELEASE(p_btif); ++ return i_ret; ++} ++ ++int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify) ++{ ++ if (p_btif->rx_notify) { ++ BTIF_WARN_FUNC ++ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", ++ p_btif->rx_notify, rx_notify); ++ } ++ p_btif->rx_notify = rx_notify; ++ ++ return 0; ++} ++ ++int btif_dump_data(char *p_buf, int len) ++{ ++ unsigned int idx = 0; ++ unsigned char str[30]; ++ unsigned char *p_str; ++ ++ p_str = &str[0]; ++ for (idx = 0; idx < len; idx++, p_buf++) { ++ sprintf(p_str, "%02x ", *p_buf); ++ p_str += 3; ++ if (7 == (idx % 8)) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ p_str = &str[0]; ++ } ++ } ++ if (len % 8) { ++ *p_str++ = '\n'; ++ *p_str = '\0'; ++ pr_debug("%s", str); ++ } ++ return 0; ++} ++ ++int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, ++ int len) ++{ ++ P_BTIF_LOG_BUF_T p_log_buf = NULL; ++ char *dir = NULL; ++ struct timeval *p_timer = NULL; ++ unsigned long flags; ++ bool output_flag = false; ++ ++ BTIF_DBG_FUNC("++\n"); ++ ++ if ((p_log_que == NULL) || (p_buf == NULL) || (len == 0)) { ++ BTIF_ERR_FUNC("invalid parameter, p_log_que(0x%x), buf(0x%x), ", ++ "len(%d)\n", p_log_que, p_buf, len); ++ return 0; ++ } ++ if (!(p_log_que->enable)) ++ return 0; ++ ++ dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; ++ output_flag = p_log_que->output_flag; ++ ++ spin_lock_irqsave(&(p_log_que->lock), flags); ++ ++/*get next log buffer for record usage*/ ++ p_log_buf = p_log_que->p_queue[0] + p_log_que->in; ++ p_timer = &p_log_buf->timer; ++ ++/*log time stamp*/ ++ do_gettimeofday(p_timer); ++ ++/*record data information including length and content*/ ++ p_log_buf->len = len; ++ memcpy(p_log_buf->buffer, p_buf, len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len); ++ ++/*update log queue size information*/ ++ p_log_que->size++; ++ p_log_que->size = p_log_que->size > ++ BTIF_LOG_ENTRY_NUM ? BTIF_LOG_ENTRY_NUM : p_log_que->size; ++ ++/*update log queue index information*/ ++ p_log_que->in++; ++ p_log_que->in %= BTIF_LOG_ENTRY_NUM; ++ ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ ++/*check if log dynamic output function is enabled or not*/ ++ if (output_flag) { ++ pr_debug("BTIF-DBG, dir:%s, %d.%ds len:%d\n", ++ dir, (int)p_timer->tv_sec, (int)p_timer->tv_usec, len); ++/*output buffer content*/ ++ btif_dump_data((char *)p_buf, len); ++ } ++ BTIF_DBG_FUNC("--\n"); ++ ++ return 0; ++} ++ ++int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ P_BTIF_LOG_BUF_T p_log_buf = NULL; ++ unsigned int out_index = 0; ++ unsigned int in_index = 0; ++ unsigned int dump_size = 0; ++ unsigned char *p_buf = NULL; ++ unsigned int len = 0; ++ unsigned int pkt_count = 0; ++ unsigned char *p_dir = NULL; ++ struct timeval *p_timer = NULL; ++ unsigned long flags; ++ ++#if 0 /* no matter enable or not, we allowed output */ ++ if (!(p_log_que->enable)) ++ return; ++#endif ++ BTIF_DBG_FUNC("++\n"); ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ in_index = p_log_que->in; ++ dump_size = p_log_que->size; ++ out_index = p_log_que->size >= ++ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - ++ p_log_que->size + ++ in_index) % BTIF_LOG_ENTRY_NUM; ++ p_dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; ++ ++ BTIF_INFO_FUNC("btif %s log buffer size:%d\n", p_dir, dump_size); ++ ++ if (dump_size != 0) { ++ while (dump_size--) { ++ p_log_buf = p_log_que->p_queue[0] + out_index; ++ ++ len = p_log_buf->len; ++ p_buf = p_log_buf->buffer; ++ p_timer = &p_log_buf->timer; ++ ++ len = len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len; ++ ++ BTIF_INFO_FUNC("dir:%s, pkt_count:%d, %d.%ds len:%d\n", ++ p_dir, ++ pkt_count++, ++ (int)p_timer->tv_sec, ++ (int)p_timer->tv_usec, len); ++/*output buffer content*/ ++ btif_dump_data(p_log_buf->buffer, len); ++ out_index++; ++ out_index %= BTIF_LOG_ENTRY_NUM; ++ } ++ } ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_DBG_FUNC("--\n"); ++ ++ return 0; ++} ++ ++int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->enable = true; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("enable %s log function\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->enable = false; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("disable %s log function\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->output_flag = true; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("%s log rt output enabled\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ p_log_que->output_flag = false; ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_INFO_FUNC("%s log rt output disabled\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&p_log_que->lock, flags); ++ ++/*tx log buffer init*/ ++ p_log_que->in = 0; ++ p_log_que->out = 0; ++ p_log_que->size = 0; ++ p_log_que->enable = true; ++ memset((p_log_que->p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); ++ ++ spin_unlock_irqrestore(&p_log_que->lock, flags); ++ BTIF_DBG_FUNC("reset %s log buffer\n", ++ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); ++ return 0; ++} ++ ++int btif_log_buf_init(p_mtk_btif p_btif) ++{ ++/*tx log buffer init*/ ++ p_btif->tx_log.dir = BTIF_TX; ++ p_btif->tx_log.in = 0; ++ p_btif->tx_log.out = 0; ++ p_btif->tx_log.size = 0; ++ p_btif->tx_log.output_flag = false; ++ p_btif->tx_log.enable = true; ++ spin_lock_init(&(p_btif->tx_log.lock)); ++ BTIF_DBG_FUNC("tx_log.p_queue:0x%p\n", p_btif->tx_log.p_queue[0]); ++ memset((p_btif->tx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); ++ ++/*rx log buffer init*/ ++ p_btif->rx_log.dir = BTIF_RX; ++ p_btif->rx_log.in = 0; ++ p_btif->rx_log.out = 0; ++ p_btif->rx_log.size = 0; ++ p_btif->rx_log.output_flag = false; ++ p_btif->rx_log.enable = true; ++ spin_lock_init(&(p_btif->rx_log.lock)); ++ BTIF_DBG_FUNC("rx_log.p_queue:0x%p\n", p_btif->rx_log.p_queue[0]); ++ memset((p_btif->rx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); ++ ++ return 0; ++} ++ ++int btif_tx_dma_mode_set(int en) ++{ ++ int index = 0; ++ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; ++ ++ for (index = 0; index < BTIF_PORT_NR; index++) ++ g_btif[index].tx_mode = mode; ++ ++ return 0; ++} ++ ++int btif_rx_dma_mode_set(int en) ++{ ++ int index = 0; ++ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; ++ ++ for (index = 0; index < BTIF_PORT_NR; index++) ++ g_btif[index].rx_mode = mode; ++ ++ return 0; ++} ++ ++static int BTIF_init(void) ++{ ++ int i_ret = -1; ++ int index = 0; ++ p_mtk_btif_dma p_tx_dma = NULL; ++ p_mtk_btif_dma p_rx_dma = NULL; ++ unsigned char *p_btif_buffer = NULL; ++ unsigned char *p_tx_queue = NULL; ++ unsigned char *p_rx_queue = NULL; ++ ++ BTIF_DBG_FUNC("++\n"); ++ ++/*Platform Driver initialization*/ ++ i_ret = platform_driver_register(&mtk_btif_dev_drv); ++ if (i_ret) { ++ BTIF_ERR_FUNC("BTIF platform driver registered failed, ret(%d)\n", i_ret); ++ goto err_exit1; ++ } ++ ++ i_ret = driver_create_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); ++ if (i_ret) ++ BTIF_ERR_FUNC("BTIF pdriver_create_file failed, ret(%d)\n", i_ret); ++ ++/*SW init*/ ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ p_btif_buffer = kmalloc(BTIF_RX_BUFFER_SIZE, GFP_ATOMIC); ++ if (!p_btif_buffer) { ++ BTIF_ERR_FUNC("p_btif_buffer kmalloc memory fail\n"); ++ return -1; ++ } ++ BTIF_INFO_FUNC("p_btif_buffer get memory 0x%p\n", p_btif_buffer); ++ p_tx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); ++ if (!p_tx_queue) { ++ BTIF_ERR_FUNC("p_tx_queue kmalloc memory fail\n"); ++ kfree(p_btif_buffer); ++ return -1; ++ } ++ BTIF_INFO_FUNC("p_tx_queue get memory 0x%p\n", p_tx_queue); ++ p_rx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); ++ if (!p_rx_queue) { ++ BTIF_ERR_FUNC("p_rx_queue kmalloc memory fail\n"); ++ kfree(p_btif_buffer); ++ kfree(p_tx_queue); ++ return -1; ++ } ++ BTIF_INFO_FUNC("p_rx_queue get memory 0x%p\n", p_rx_queue); ++ ++ INIT_LIST_HEAD(&(g_btif[index].user_list)); ++ BBS_INIT(&(g_btif[index].btif_buf)); ++ g_btif[index].enable = false; ++ g_btif[index].open_counter = 0; ++ g_btif[index].setting = &g_btif_setting[index]; ++ g_btif[index].p_btif_info = hal_btif_info_get(); ++ g_btif[index].tx_mode = g_btif_setting[index].tx_mode; ++ g_btif[index].rx_mode = g_btif_setting[index].rx_mode; ++ g_btif[index].btm_type = g_btif_setting[index].rx_type; ++ g_btif[index].tx_ctx = g_btif_setting[index].tx_type; ++ g_btif[index].lpbk_flag = false; ++ g_btif[index].rx_cb = NULL; ++ g_btif[index].rx_notify = NULL; ++ g_btif[index].btif_buf.p_buf = p_btif_buffer; ++ g_btif[index].tx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_tx_queue; ++ g_btif[index].rx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_rx_queue; ++ btif_log_buf_init(&g_btif[index]); ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++/*enable BTIF clock gating by default*/ ++ i_ret = hal_btif_clk_ctrl(g_btif[index].p_btif_info, ++ CLK_OUT_DISABLE); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF controller CG failed\n"); ++ goto err_exit2; ++ } ++#endif ++ ++/* ++ * viftual FIFO memory must be physical continious, ++ * because DMA will access it directly without MMU ++ */ ++#if ENABLE_BTIF_TX_DMA ++ p_tx_dma = &g_dma[index][BTIF_TX]; ++ g_btif[index].p_tx_dma = p_tx_dma; ++ p_tx_dma->dir = BTIF_TX; ++ p_tx_dma->p_btif = &(g_btif[index]); ++ ++/*DMA Tx vFIFO initialization*/ ++ p_tx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_TX); ++/*spinlock init*/ ++ spin_lock_init(&(p_tx_dma->iolock)); ++/*entry setup*/ ++ atomic_set(&(p_tx_dma->entry), 0); ++/*vFIFO initialization*/ ++ i_ret = _btif_vfifo_init(p_tx_dma); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Tx vFIFO allocation failed\n"); ++ goto err_exit2; ++ } ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++/*enable BTIF Tx DMA channel's clock gating by default*/ ++ i_ret = hal_btif_dma_clk_ctrl(p_tx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Tx DMA's CG failed\n"); ++ goto err_exit2; ++ } ++#endif ++ ++#else ++ g_btif[index].p_tx_dma = NULL; ++/*force tx mode to DMA no matter what it is in default setting*/ ++ g_btif[index].tx_mode = BTIF_MODE_PIO; ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++ p_rx_dma = &g_dma[index][BTIF_RX]; ++ g_btif[index].p_rx_dma = p_rx_dma; ++ p_rx_dma->p_btif = &(g_btif[index]); ++ p_rx_dma->dir = BTIF_RX; ++ ++/*DMA Tx vFIFO initialization*/ ++ p_rx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_RX); ++/*spinlock init*/ ++ spin_lock_init(&(p_rx_dma->iolock)); ++/*entry setup*/ ++ atomic_set(&(p_rx_dma->entry), 0); ++/*vFIFO initialization*/ ++ i_ret = _btif_vfifo_init(p_rx_dma); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Rx vFIFO allocation failed\n"); ++ goto err_exit2; ++ } ++ ++#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) ++/*enable BTIF Tx DMA channel's clock gating by default*/ ++ i_ret = hal_btif_dma_clk_ctrl(p_rx_dma->p_dma_info, ++ CLK_OUT_DISABLE); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Rx DMA's CG failed\n"); ++ goto err_exit2; ++ } ++#endif ++ ++#else ++ g_btif[index].p_rx_dma = NULL; ++/*force rx mode to DMA no matter what it is in default setting*/ ++ g_btif[index].rx_mode = BTIF_MODE_PIO; ++ ++#endif ++/*PM state mechine initialization*/ ++ i_ret = _btif_state_init(&(g_btif[index])); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF state mechanism init failed\n"); ++ goto err_exit2; ++ } ++ ++/*Rx bottom half initialization*/ ++ i_ret = _btif_rx_btm_init(&(g_btif[index])); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Rx btm init failed\n"); ++ goto err_exit3; ++ } ++ i_ret = _btif_tx_ctx_init(&(g_btif[index])); ++ if (i_ret != 0) { ++ BTIF_ERR_FUNC("BTIF Tx context init failed\n"); ++ goto err_exit4; ++ } ++/*Character Device initialization*/ ++/*Chaozhong: ToDo: to be initialized*/ ++ ++ mutex_init(&g_btif[index].ops_mtx); ++ } ++ ++/*Debug purpose initialization*/ ++ ++#if BTIF_CDEV_SUPPORT ++ btif_chrdev_init(); ++#endif ++ ++ return 0; ++ ++err_exit4: ++ for (index = 0; index < BTIF_PORT_NR; index++) ++ _btif_tx_ctx_deinit(&(g_btif[index])); ++ ++err_exit3: ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ _btif_rx_btm_deinit(&(g_btif[index])); ++ ++ _btif_state_deinit(&(g_btif[index])); ++ } ++ ++err_exit2: ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ p_tx_dma = &g_dma[index][BTIF_TX]; ++ p_rx_dma = &g_dma[index][BTIF_RX]; ++#if ENABLE_BTIF_TX_DMA ++ _btif_vfifo_deinit(p_tx_dma); ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++ _btif_vfifo_deinit(p_rx_dma); ++#endif ++ g_btif[index].open_counter = 0; ++ g_btif[index].enable = false; ++ } ++ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); ++ platform_driver_unregister(&mtk_btif_dev_drv); ++ ++err_exit1: ++ i_ret = -1; ++ BTIF_DBG_FUNC("--\n"); ++ return i_ret; ++} ++ ++static void BTIF_exit(void) ++{ ++ unsigned int index = 0; ++ p_mtk_btif_dma p_tx_dma = NULL; ++ p_mtk_btif_dma p_rx_dma = NULL; ++ ++ BTIF_DBG_FUNC("++\n"); ++ ++ for (index = 0; index < BTIF_PORT_NR; index++) { ++ g_btif[index].open_counter = 0; ++ g_btif[index].enable = false; ++ p_tx_dma = &g_dma[index][BTIF_TX]; ++ p_rx_dma = &g_dma[index][BTIF_RX]; ++#if ENABLE_BTIF_TX_DMA ++ _btif_vfifo_deinit(p_tx_dma); ++#endif ++ ++#if ENABLE_BTIF_RX_DMA ++ _btif_vfifo_deinit(p_rx_dma); ++#endif ++ _btif_state_deinit(&(g_btif[index])); ++ ++ _btif_rx_btm_deinit(&(g_btif[index])); ++ ++ mutex_destroy(&g_btif[index].ops_mtx); ++ } ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ hal_btif_clk_unprepare(); ++#endif ++ ++ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); ++ platform_driver_unregister(&mtk_btif_dev_drv); ++ BTIF_DBG_FUNC("--\n"); ++} ++ ++int mtk_btif_hal_get_log_lvl(void) ++{ ++ return mtk_btif_dbg_lvl; ++} ++ ++void mtk_btif_read_cpu_sw_rst_debug(void) ++{ ++ mtk_btif_read_cpu_sw_rst_debug_plat(); ++} ++ ++/*---------------------------------------------------------------------------*/ ++ ++module_init(BTIF_init); ++module_exit(BTIF_exit); ++ ++/*---------------------------------------------------------------------------*/ ++ ++MODULE_AUTHOR("MBJ/WCN/SE/SS1/Chaozhong.Liang"); ++MODULE_DESCRIPTION("MTK BTIF Driver$1.0$"); ++MODULE_LICENSE("GPL"); ++ ++/*---------------------------------------------------------------------------*/ +diff --git a/drivers/misc/mediatek/btif/common/mtk_btif_exp.c b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c +new file mode 100644 +index 000000000000..c0df44558357 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c +@@ -0,0 +1,786 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "MTK-BTIF-EXP" ++ ++/*#include "mtk_btif_exp.h"*/ ++#include "mtk_btif.h" ++ ++/*---------------------------------Function----------------------------------*/ ++ ++p_mtk_btif btif_exp_srh_id(unsigned long u_id) ++{ ++ int index = 0; ++ p_mtk_btif p_btif = NULL; ++ struct list_head *p_list = NULL; ++ struct list_head *tmp = NULL; ++ p_mtk_btif_user p_user = NULL; ++ ++ for (index = 0; (index < BTIF_PORT_NR) && (p_btif == NULL); index++) { ++ p_list = &(g_btif[index].user_list); ++ list_for_each(tmp, p_list) { ++ p_user = container_of(tmp, mtk_btif_user, entry); ++ if (u_id == p_user->u_id) { ++ p_btif = p_user->p_btif; ++ BTIF_DBG_FUNC ++ ("BTIF's user id(0x%p), p_btif(0x%p)\n", ++ p_user->u_id, p_btif); ++ break; ++ } ++ } ++ } ++ if (p_btif == NULL) { ++ BTIF_INFO_FUNC ++ ("no btif structure found for BTIF's user id(0x%lx)\n", ++ u_id); ++ } ++ return p_btif; ++} ++ ++/*-----Normal Mode API declearation-------*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_open ++* DESCRIPTION ++* open BTIF interface, will do BTIF module HW and SW initialization ++* PARAMETERS ++* p_owner [IN] pointer to owner who call this API, ++* currently there are 2 owner ("stp" or "btif_tester") ++* may use this module ++* for "stp", BTIF will call rx callback function to route rx data to STP module ++* for "stp_tester", BTIF will save rx data and wait for native process to access ++* p_id [IN] BTIF's user id will be put to this address ++* RETURNS ++* int 0 = BTIF module initialization fail; negative = BTIF module initialization success ++* if open success, value p_id will be the only identifier ++* for user to access BTIF's other operations ++* including read/write/dpidle_ctrl/rx_cb_retister ++* this user id is only an identifier used for owner identification ++*****************************************************************************/ ++int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id) ++{ ++ int i_ret = -1; ++ unsigned int index = 0; ++ p_mtk_btif_user p_new_user = NULL; ++ p_mtk_btif p_btif = &g_btif[index]; ++ struct list_head *p_user_list = &(p_btif->user_list); ++ ++ BTIF_DBG_FUNC("++"); ++ BTIF_DBG_FUNC("p_btif(0x%p)\n", p_btif); ++ ++ if (mutex_lock_killable(&(p_btif->ops_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return E_BTIF_INTR; ++ } ++ if ((p_owner == NULL) || (p_id == NULL)) { ++ if (p_id) ++ *p_id = 0; ++ BTIF_ERR_FUNC("parameter invalid, p_owner(0x%p), p_id(0x%p)\n", ++ p_owner, p_id); ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++/*check if btif is already opened or not, if yes, just return fail*/ ++ if (!list_empty(p_user_list)) { ++ struct list_head *pos; ++ p_mtk_btif_user p_user; ++ ++ BTIF_ERR_FUNC("BTIF's user list is not empty\n"); ++ list_for_each(pos, p_user_list) { ++ p_user = container_of(pos, mtk_btif_user, entry); ++ BTIF_INFO_FUNC("BTIF's user id(0x%lx), name(%s)\n", ++ p_user->u_id, p_user->u_name); ++ } ++/*leave p_id alone*/ ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ return E_BTIF_ALREADY_OPEN; ++ } ++ p_new_user = vmalloc(sizeof(mtk_btif_user)); ++ ++ if (p_new_user != NULL) { ++ INIT_LIST_HEAD(&(p_new_user->entry)); ++ p_new_user->enable = false; ++ p_new_user->p_btif = p_btif; ++ p_new_user->u_id = (unsigned long)p_new_user; ++ strncpy(p_new_user->u_name, p_owner, sizeof(p_new_user->u_name) - 1); ++ p_new_user->u_name[sizeof(p_new_user->u_name) - 1] = '\0'; ++ BTIF_DBG_FUNC("owner name:%s, recorded name:%s\n", ++ p_owner, p_new_user->u_name); ++ ++ i_ret = btif_open(p_btif); ++ if (i_ret) { ++ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); ++ *p_id = 0; ++/*free btif new user's structure*/ ++ vfree(p_new_user); ++ p_new_user = NULL; ++ } else { ++ BTIF_INFO_FUNC("btif_open succeed\n"); ++ *p_id = p_new_user->u_id; ++/*mark enable flag to true*/ ++ p_new_user->enable = true; ++/*add to uer lsit*/ ++ list_add_tail(&(p_new_user->entry), p_user_list); ++ } ++ } else { ++ *p_id = 0; ++ i_ret = -ENOMEM; ++ BTIF_ERR_FUNC("allocate memory for mtk_btif_user failed\n"); ++ } ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ BTIF_DBG_FUNC("--"); ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_open); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_close ++* DESCRIPTION ++* close BTIF interface, will do BTIF module HW and SW de-initialization ++* once this API is called, p_btif should never be used by BTIF's user again ++* PARAMETERS ++* u_id [IN] BTIF's user id ++* RETURNS ++* int 0 = succeed; ++* others = fail, ++* for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_close(unsigned long u_id) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ struct list_head *pos = NULL; ++ struct list_head *p_user_list = NULL; ++ ++ BTIF_DBG_FUNC("++"); ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ if (mutex_lock_killable(&(p_btif->ops_mtx))) { ++ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); ++ return E_BTIF_INTR; ++ } ++ p_user_list = &(p_btif->user_list); ++ list_for_each(pos, p_user_list) { ++ p_mtk_btif_user p_user = ++ container_of(pos, mtk_btif_user, entry); ++ ++ if (p_user->u_id == u_id) { ++ BTIF_INFO_FUNC ++ ("user who's id is 0x%lx deleted from user list\n", ++ u_id); ++ list_del(pos); ++ vfree(p_user); ++ i_ret = btif_close(p_btif); ++ if (i_ret) ++ BTIF_WARN_FUNC("BTIF close failed"); ++ break; ++ } ++ } ++ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); ++ BTIF_DBG_FUNC("--"); ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_close); ++ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_write ++* DESCRIPTION ++* send data throuth BTIF module ++* there's no internal buffer to cache STP data in BTIF driver, ++* if in DMA mode ++* btif driver will check if there's enough space in vFIFO for data to send in DMA mode ++* if yes, put data to vFIFO and return corresponding data length to caller ++* if no, corresponding error code will be returned to called ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN] pointer to target data to send ++* len [IN] data length (should be less than 2014 bytes per STP package) ++* ++* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller ++* if btif driver detected that no space is available in Tx FIFO, ++* will return E_BTIF_NO_SPACE, mostly something is wrong with BTIF or ++* consys when this return value is returned ++* RETURNS ++* int positive: data length send through BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++* E_BTIF_AGAIN (0) will be returned to caller ++* if btif does not have enough vFIFO to send data, ++* when caller get 0, he should wait for a moment ++* (5~10ms maybe) and try a few times (maybe 10~20) ++* if still get E_BTIF_AGAIN, ++* should call BTIF's debug API and dump BTIF driver ++* and BTIF/DMA register information to kernel log for debug ++* E_BTIF_BAD_POINTER will be returned to caller ++* if btif is not opened successfully before call this API ++* E_BTIF_INVAL_PARAM will be returned if parameter is not valid ++ ++*****************************************************************************/ ++int mtk_wcn_btif_write(unsigned long u_id, ++ const unsigned char *p_buf, unsigned int len) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ BTIF_DBG_FUNC("++"); ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ if (p_buf == NULL) { ++ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); ++ return E_BTIF_INVAL_PARAM; ++ } ++ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { ++ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ i_ret = btif_send_data(p_btif, p_buf, len); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_write); ++ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_read ++* DESCRIPTION ++* read data from BTIF module ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* p_buf [IN/OUT] pointer to buffer where rx data will be put ++* max_len [IN] max buffer length ++* RETURNS ++* int positive: data length read from BTIF; ++* negative: please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_read(unsigned long u_id, ++ unsigned char *p_buf, unsigned int max_len) ++{ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_dpidle_ctrl ++* DESCRIPTION ++* control if BTIF module allow system enter deepidle state or not ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL ++* RETURNS ++* int always return 0 ++*****************************************************************************/ ++int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ if (en_flag == BTIF_DPIDLE_DISABLE) ++ i_ret = btif_exit_dpidle(p_btif); ++ else ++ i_ret = btif_enter_dpidle(p_btif); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_dpidle_ctrl); ++ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_rx_cb_register ++* DESCRIPTION ++* register rx callback function to BTIF module by btif user ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* rx_cb [IN] pointer to stp rx handler callback function, ++* should be comply with MTK_WCN_BTIF_RX_CB ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, ++* please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ i_ret = btif_rx_cb_reg(p_btif, rx_cb); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_rx_cb_register); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_wakeup_consys ++* DESCRIPTION ++* once sleep command is sent to con sys, ++* should call this API before send wakeup command ++* to make con sys aware host want to send data to consys ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* RETURNS ++* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_wakeup_consys(unsigned long u_id) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ ++ i_ret = btif_raise_wak_signal(p_btif); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_wakeup_consys); ++ ++ ++/***************End of Normal Mode API declearation**********/ ++ ++/***************Debug Purpose API declearation**********/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_loopback_ctrl ++* DESCRIPTION ++* enable/disable BTIF internal loopback function, ++* when this function is enabled data send to btif ++* will be received by btif itself ++* only for debug purpose, should never use this function in normal mode ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* enable [IN] loopback mode control flag, enable or disable, ++* shou be one of ENUM_BTIF_LPBK_MODE ++* RETURNS ++* int 0 = succeed; ++* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ i_ret = ++ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_btif_logger_ctrl ++* DESCRIPTION ++* control BTIF logger function's behavior ++* PARAMETERS ++* p_btif [IN] pointer returned by mtk_wcn_btif_open ++* flag [IN] should be one of ENUM_BTIF_DBG_ID ++* BTIF_DISABLE_LOGGER - disable btif logger ++* BTIF_ENABLE_LOGGER - enable btif logger ++* BTIF_DUMP_LOG - dump log logged by btif ++* BTIF_CLR_LOG - clear btif log buffer ++* BTIF_DUMP_BTIF_REG - dump btif controller's register ++* BTIF_DUMP_DMA_REG - dump DMA controller's register ++* RETURNS ++* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE ++*****************************************************************************/ ++int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ ++ i_ret = 0; ++ switch (flag) { ++ case BTIF_DISABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("disable btif log function for both Tx and Rx\n"); ++ btif_log_buf_disable(&p_btif->tx_log); ++ btif_log_buf_disable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_ENABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("enable btif log function for both Tx and Rx\n"); ++ btif_log_buf_enable(&p_btif->tx_log); ++ btif_log_buf_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_LOG:{ ++ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); ++ btif_log_buf_dmp_out(&p_btif->tx_log); ++ btif_log_buf_dmp_out(&p_btif->rx_log); ++ } ++ break; ++ ++ case BTIF_CLR_LOG:{ ++ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); ++ btif_log_buf_reset(&p_btif->tx_log); ++ btif_log_buf_reset(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_BTIF_REG: ++ /*TBD*/ btif_dump_reg(p_btif); ++ break; ++ case BTIF_ENABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("enable btif real time log for both Tx and Rx\n"); ++ btif_log_output_enable(&p_btif->tx_log); ++ btif_log_output_enable(&p_btif->rx_log); ++ break; ++ case BTIF_DISABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("disable btif real time log for both Tx and Rx\n"); ++ btif_log_output_disable(&p_btif->tx_log); ++ btif_log_output_disable(&p_btif->rx_log); ++ break; ++ default: ++ BTIF_INFO_FUNC("not supported flag:%d\n", flag); ++ i_ret = -2; ++ break; ++ } ++ ++ return i_ret; ++} ++EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); ++ ++bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, ++ const char *sub_str, unsigned int str_len) ++{ ++ bool b_ret = false; ++ p_mtk_btif p_btif = NULL; ++ ++ p_btif = btif_exp_srh_id(u_id); ++ ++ if (p_btif == NULL) ++ return E_BTIF_INVAL_PARAM; ++ b_ret = btif_parser_wmt_evt(p_btif, sub_str, str_len); ++ BTIF_INFO_FUNC("parser wmt evt %s\n", b_ret ? "ok" : "fail"); ++ ++ return b_ret; ++} ++ ++/**********End of Debug Purpose API declearation**********/ ++ ++int btif_open_no_id(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = btif_open(p_btif); ++ ++ if (i_ret) ++ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); ++ else ++ BTIF_INFO_FUNC("btif_open succeed\n"); ++ ++ return i_ret; ++} ++ ++int btif_close_no_id(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = btif_close(p_btif); ++ ++ if (i_ret) ++ BTIF_ERR_FUNC("btif_close failed, i_ret(%d)\n", i_ret); ++ else ++ BTIF_INFO_FUNC("btif_close succeed\n"); ++ return i_ret; ++} ++ ++int btif_write_no_id(const unsigned char *p_buf, unsigned int len) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ BTIF_DBG_FUNC("++"); ++ ++ if (p_buf == NULL) { ++ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); ++ return E_BTIF_INVAL_PARAM; ++ } ++ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { ++ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); ++ return E_BTIF_INVAL_PARAM; ++ } ++ ++ i_ret = btif_send_data(p_btif, p_buf, len); ++ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); ++ return i_ret; ++} ++ ++int btif_dpidle_ctrl_no_id(ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ if (en_flag == BTIF_DPIDLE_DISABLE) ++ i_ret = btif_exit_dpidle(p_btif); ++ else ++ i_ret = btif_enter_dpidle(p_btif); ++ ++ return i_ret; ++} ++ ++int btif_wakeup_consys_no_id(void) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ ++ i_ret = btif_raise_wak_signal(p_btif); ++ ++ return i_ret; ++} ++ ++int btif_loopback_ctrl_no_id(ENUM_BTIF_LPBK_MODE enable) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = ++ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); ++ ++ return i_ret; ++} ++ ++int btif_dbg_ctrl_no_id(ENUM_BTIF_DBG_ID flag) ++{ ++ int i_ret = -1; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = 0; ++ switch (flag) { ++ case BTIF_DISABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("disable btif log function for both Tx and Rx\n"); ++ btif_log_buf_disable(&p_btif->tx_log); ++ btif_log_buf_disable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_ENABLE_LOGGER:{ ++ BTIF_INFO_FUNC ++ ("enable btif log function for both Tx and Rx\n"); ++ btif_log_buf_enable(&p_btif->tx_log); ++ btif_log_buf_enable(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_LOG:{ ++ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); ++ btif_log_buf_dmp_out(&p_btif->tx_log); ++ btif_log_buf_dmp_out(&p_btif->rx_log); ++ } ++ break; ++ ++ case BTIF_CLR_LOG:{ ++ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); ++ btif_log_buf_reset(&p_btif->tx_log); ++ btif_log_buf_reset(&p_btif->rx_log); ++ } ++ break; ++ case BTIF_DUMP_BTIF_REG: ++ /*TBD*/ btif_dump_reg(p_btif); ++ break; ++ case BTIF_ENABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("enable btif real time log for both Tx and Rx\n"); ++ btif_log_output_enable(&p_btif->tx_log); ++ btif_log_output_enable(&p_btif->rx_log); ++ break; ++ case BTIF_DISABLE_RT_LOG: ++ BTIF_INFO_FUNC ++ ("disable btif real time log for both Tx and Rx\n"); ++ btif_log_output_disable(&p_btif->tx_log); ++ btif_log_output_disable(&p_btif->rx_log); ++ break; ++ default: ++ BTIF_INFO_FUNC("not supported flag:%d\n", flag); ++ i_ret = -2; ++ break; ++ } ++ ++ return i_ret; ++} ++ ++int mtk_btif_exp_open_test(void) ++{ ++ int i_ret = 0; ++ ++ i_ret = btif_open_no_id(); ++ if (i_ret < 0) { ++ BTIF_INFO_FUNC("mtk_wcn_btif_open failed\n"); ++ return -1; ++ } ++ ++ BTIF_INFO_FUNC("mtk_wcn_btif_open succeed\n"); ++ ++ return i_ret; ++} ++ ++int mtk_btif_exp_close_test(void) ++{ ++ int i_ret = 0; ++ ++ i_ret = btif_close_no_id(); ++ if (i_ret < 0) { ++ BTIF_INFO_FUNC("mtk_wcn_btif_close failed\n"); ++ return -1; ++ } ++ ++ BTIF_INFO_FUNC("mtk_wcn_btif_close succeed\n"); ++ ++ return i_ret; ++} ++ ++int mtk_btif_exp_write_test(void) ++{ ++ return mtk_btif_exp_write_stress_test(100, 10); ++} ++ ++int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int max_loop) ++{ ++#define BUF_LEN 1024 ++ int i_ret = 0; ++ int idx = 0; ++ int buf_len = length > BUF_LEN ? BUF_LEN : length; ++ int loop = max_loop > 1000000 ? 1000000 : max_loop; ++ unsigned char *buffer; ++ ++ buffer = kmalloc(BUF_LEN, GFP_KERNEL); ++ if (!buffer) { ++ BTIF_ERR_FUNC("btif tester kmalloc failed\n"); ++ return -1; ++ } ++ ++ for (idx = 0; idx < buf_len; idx++) ++ /* btif_stress_test_buf[idx] = BUF_LEN -idx; */ ++ *(buffer + idx) = idx % 255; ++ i_ret = btif_loopback_ctrl_no_id(BTIF_LPBK_ENABLE); ++ BTIF_INFO_FUNC("mtk_wcn_btif_loopback_ctrl returned %d\n", i_ret); ++ while (loop--) { ++ i_ret = btif_write_no_id(buffer, buf_len); ++ BTIF_INFO_FUNC("mtk_wcn_btif_write left loop:%d, i_ret:%d\n", ++ loop, i_ret); ++ if (i_ret != buf_len) { ++ BTIF_INFO_FUNC ++ ("mtk_wcn_btif_write failed, target len %d, sent len: %d\n", ++ buf_len, i_ret); ++ break; ++ } ++ buf_len--; ++ if (buf_len <= 0) ++ buf_len = length > BUF_LEN ? BUF_LEN : length; ++ } ++ kfree(buffer); ++ return i_ret; ++} ++ ++int mtk_btif_exp_suspend_test(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = _btif_suspend(p_btif); ++ return i_ret; ++} ++ ++int mtk_btif_exp_restore_noirq_test(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = _btif_restore_noirq(p_btif); ++ return i_ret; ++} ++ ++int mtk_btif_exp_clock_ctrl(int en) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = btif_clock_ctrl(p_btif, en); ++ return i_ret; ++} ++ ++int mtk_btif_exp_resume_test(void) ++{ ++ int i_ret = 0; ++ p_mtk_btif p_btif = &g_btif[0]; ++ ++ i_ret = _btif_resume(p_btif); ++ return i_ret; ++} ++ ++int mtk_btif_exp_enter_dpidle_test(void) ++{ ++ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_ENABLE); ++} ++ ++int mtk_btif_exp_exit_dpidle_test(void) ++{ ++ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_DISABLE); ++} ++ ++int mtk_btif_exp_log_debug_test(int flag) ++{ ++ int i_ret = 0; ++ ++ i_ret = btif_dbg_ctrl_no_id(flag); ++ return i_ret; ++} ++ ++void mtk_btif_read_cpu_sw_rst_debug_exp(void) ++{ ++ mtk_btif_read_cpu_sw_rst_debug(); ++} ++ ++/************End of Function**********/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h +new file mode 100644 +index 000000000000..97756f684ab4 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h +@@ -0,0 +1,164 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIF_DMA_H_ ++#define __HAL_BTIF_DMA_H_ ++ ++#include ++#include "btif_dma_pub.h" ++ ++#if defined(CONFIG_MTK_CLKMGR) ++#if defined(CONFIG_ARCH_MT6580) ++#define MTK_BTIF_APDMA_CLK_CG MT_CG_APDMA_SW_CG ++#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) ++#define MTK_BTIF_APDMA_CLK_CG MT_CG_PERI_APDMA ++#endif ++#else ++extern struct clk *clk_btif_apdma; /*btif apdma clock*/ ++#endif /* !defined(CONFIG_MTK_CLKMGR) */ ++ ++#define TX_DMA_VFF_SIZE (1024 * 8) /*Tx vFIFO Len must be 8 Byte allignment */ ++#define RX_DMA_VFF_SIZE (1024 * 8) /*Rx vFIFO Len must be 8 Byte allignment */ ++ ++#define DMA_TX_THRE(n) (n - 7) /*Tx Trigger Level */ ++#define DMA_RX_THRE(n) ((n) * 3 / 4) /*Rx Trigger Level */ ++ ++/**********************************Hardware related defination**************************/ ++#ifndef CONFIG_OF ++/*DMA channel's offset refer to AP_DMA's base address*/ ++#define BTIF_TX_DMA_OFFSET 0x880 ++#define BTIF_RX_DMA_OFFSET 0x900 ++#endif ++ ++/*Register Address Mapping*/ ++#define DMA_INT_FLAG_OFFSET 0x00 ++#define DMA_INT_EN_OFFSET 0x04 ++#define DMA_EN_OFFSET 0x08 ++#define DMA_RST_OFFSET 0x0C ++#define DMA_STOP_OFFSET 0x10 ++#define DMA_FLUSH_OFFSET 0x14 ++ ++#define DMA_BASE_OFFSET 0x1C ++#define DMA_LEN_OFFSET 0x24 ++ ++#define DMA_THRE_OFFSET 0x28 ++#define DMA_WPT_OFFSET 0x2C ++#define DMA_RPT_OFFSET 0x30 ++#define DMA_VALID_OFFSET 0x3C ++#define DMA_LEFT_OFFSET 0x40 ++#define DMA_VFF_BIT29_OFFSET 0x01 ++ ++#define TX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Tx Virtual FIFO Interrupt Flag Register */ ++#define TX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Tx Virtual FIFO Interrupt Enable Register */ ++#define TX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET)/*BTIF Tx Virtual FIFO Enable Register */ ++#define TX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET)/*BTIF Tx Virtual FIFO Reset Register */ ++#define TX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET)/*BTIF Tx Virtual FIFO STOP Register */ ++#define TX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET)/*BTIF Tx Virtual FIFO Flush Register */ ++#define TX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Tx Virtual FIFO Base Address Register */ ++#define TX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Tx Virtual FIFO Length Register */ ++#define TX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Tx Virtual FIFO Threshold Register */ ++#define TX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Tx Virtual FIFO Write Pointer Register */ ++#define TX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Tx Virtual FIFO Read Pointer Register */ ++#define TX_DMA_W_INT_BUF_SIZE(base) (unsigned long)(base + 0x34) ++/*BTIF Tx Virtual FIFO Internal Tx Write Buffer Size Register */ ++#define TX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) ++/*BTIF Tx Virtual FIFO Internal Tx Buffer Size Register */ ++ ++#define TX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Tx Virtual FIFO Valid Size Register */ ++#define TX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Tx Virtual FIFO Left Size Register */ ++#define TX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Tx Virtual FIFO Debug Status Register */ ++#define TX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Tx Virtual FIFO Base High Address Register */ ++ ++/*Rx Register Address Mapping*/ ++#define RX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Rx Virtual FIFO Interrupt Flag Register */ ++#define RX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Rx Virtual FIFO Interrupt Enable Register */ ++#define RX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET) /*BTIF Rx Virtual FIFO Enable Register */ ++#define RX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET) /*BTIF Rx Virtual FIFO Reset Register */ ++#define RX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET) /*BTIF Rx Virtual FIFO Stop Register */ ++#define RX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET) /*BTIF Rx Virtual FIFO Flush Register */ ++#define RX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Rx Virtual FIFO Base Address Register */ ++#define RX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Rx Virtual FIFO Length Register */ ++#define RX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Rx Virtual FIFO Threshold Register */ ++#define RX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Rx Virtual FIFO Write Pointer Register */ ++#define RX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Rx Virtual FIFO Read Pointer Register */ ++#define RX_DMA_FLOW_CTRL_THRE(base) (unsigned long)(base + 0x34) /*BTIF Rx Virtual FIFO Flow Control Register */ ++#define RX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) /*BTIF Rx Virtual FIFO Internal Buffer Register */ ++#define RX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Rx Virtual FIFO Valid Size Register */ ++#define RX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Rx Virtual FIFO Left Size Register */ ++#define RX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Rx Virtual FIFO Debug Status Register */ ++#define RX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Rx Virtual FIFO Base High Address Register */ ++ ++#define DMA_EN_BIT (0x1) ++#define DMA_STOP_BIT (0x1) ++#define DMA_RST_BIT (0x1) ++#define DMA_FLUSH_BIT (0x1) ++ ++#define DMA_WARM_RST (0x1 << 0) ++#define DMA_HARD_RST (0x1 << 1) ++ ++#define DMA_WPT_MASK (0x0000FFFF) ++#define DMA_WPT_WRAP (0x00010000) ++ ++#define DMA_RPT_MASK (0x0000FFFF) ++#define DMA_RPT_WRAP (0x00010000) ++ ++/*APDMA BTIF Tx Reg Ctrl Bit*/ ++#define TX_DMA_INT_FLAG_MASK (0x1) ++ ++#define TX_DMA_INTEN_BIT (0x1) ++ ++#define TX_DMA_ADDR_MASK (0xFFFFFFF8) ++#define TX_DMA_LEN_MASK (0x0000FFF8) ++ ++#define TX_DMA_THRE_MASK (0x0000FFFF) ++ ++#define TX_DMA_W_INT_BUF_MASK (0x000000FF) ++ ++#define TX_DMA_VFF_VALID_MASK (0x0000FFFF) ++#define TX_DMA_VFF_LEFT_MASK (0x0000FFFF) ++ ++/*APDMA BTIF Rx Reg Ctrl Bit*/ ++#define RX_DMA_INT_THRE (0x1 << 0) ++#define RX_DMA_INT_DONE (0x1 << 1) ++ ++#define RX_DMA_INT_THRE_EN (0x1 << 0) ++#define RX_DMA_INT_DONE_EN (0x1 << 1) ++ ++#define RX_DMA_ADDR_MASK (0xFFFFFFF8) ++#define RX_DMA_LEN_MASK (0x0000FFF8) ++ ++#define RX_DMA_THRE_MASK (0x0000FFFF) ++ ++#define RX_DMA_FLOW_CTRL_THRE_MASK (0x000000FF) ++ ++#define RX_DMA_INT_BUF_SIZE_MASK (0x0000001F) ++ ++#define RX_DMA_VFF_VALID_MASK (0x0000001F) ++ ++#define RX_DMA_VFF_LEFT_MASK (0x0000FFFF) ++ ++typedef struct _MTK_BTIF_DMA_VFIFO_ { ++ DMA_VFIFO vfifo; ++ unsigned int wpt; /*DMA's write pointer, which is maintained by SW for Tx DMA and HW for Rx DMA */ ++ unsigned int last_wpt_wrap; /*last wrap bit for wpt */ ++ unsigned int rpt; /*DMA's read pointer, which is maintained by HW for Tx DMA and SW for Rx DMA */ ++ unsigned int last_rpt_wrap; /*last wrap bit for rpt */ ++} MTK_BTIF_DMA_VFIFO, *P_MTK_BTIF_DMA_VFIFO; ++ ++/*for DMA debug purpose*/ ++typedef struct _MTK_BTIF_DMA_REG_DMP_DBG_ { ++ unsigned long reg_addr; ++ unsigned int reg_val; ++} MTK_BTIF_DMA_REG_DMP_DBG, *P_MTK_BTIF_DMA_REG_DMP_DBG; ++ ++#endif /*__HAL_BTIF_DMA_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h +new file mode 100644 +index 000000000000..0773f2ce387a +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h +@@ -0,0 +1,197 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIFD_DMA_PUB_H_ ++#define __HAL_BTIFD_DMA_PUB_H_ ++ ++#include ++ ++#include "plat_common.h" ++ ++typedef enum _ENUM_DMA_CTRL_ { ++ DMA_CTRL_DISABLE = 0, ++ DMA_CTRL_ENABLE = DMA_CTRL_DISABLE + 1, ++ DMA_CTRL_BOTH, ++} ENUM_DMA_CTRL; ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_info_get ++* DESCRIPTION ++* get btif tx dma channel's information ++* PARAMETERS ++* dma_dir [IN] DMA's direction ++* RETURNS ++* pointer to btif dma's information structure ++*****************************************************************************/ ++P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dma_hw_init ++* DESCRIPTION ++* control clock output enable/disable of DMA module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of DMA module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_ctrl ++* DESCRIPTION ++* enable/disable Tx DMA channel ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* ctrl_id [IN] enable/disable ID ++* dma_dir [IN] DMA's direction ++* RETURNS ++* 0 means success; negative means fail ++*****************************************************************************/ ++int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dma_rx_cb_reg ++* DESCRIPTION ++* register rx callback function to dma module ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* rx_cb [IN] function pointer to btif ++* RETURNS ++* 0 means success; negative means fail ++*****************************************************************************/ ++int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, ++ dma_rx_buf_write rx_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_vfifo_reset ++* DESCRIPTION ++* reset tx virtual fifo information, except memory information ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* dma_dir [IN] DMA's direction ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_tx_dma_irq_handler ++* DESCRIPTION ++* lower level tx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_send_data ++* DESCRIPTION ++* send data through btif in DMA mode ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, ++ const unsigned char *p_buf, const unsigned int buf_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_get_ava_room ++* DESCRIPTION ++* get tx available room ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* available room size ++*****************************************************************************/ ++int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_is_tx_allow ++* DESCRIPTION ++* is tx operation allowed by DMA ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_rx_dma_irq_handler ++* DESCRIPTION ++* lower level rx interrupt handler ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, ++ unsigned char *p_buf, const unsigned int max_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_dma_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_dma_info [IN] pointer to BTIF dma channel's information ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag); ++ ++int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid); ++ ++#endif /*__HAL_BTIFD_DMA_PUB_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h +new file mode 100644 +index 000000000000..51fe58a82b49 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIF_H_ ++#define __HAL_BTIF_H_ ++ ++#ifndef CONFIG_OF ++#define MTK_BTIF_REG_BASE BTIF_BASE ++#endif ++ ++#if defined(CONFIG_MTK_CLKMGR) ++#if defined(CONFIG_ARCH_MT6580) ++#define MTK_BTIF_CG_BIT MT_CG_BTIF_SW_CG ++#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) ++#define MTK_BTIF_CG_BIT MT_CG_PERI_BTIF ++#endif ++#else ++struct clk *clk_btif_apdma; /*btif apdma clock*/ ++struct clk *clk_btif; /*btif clock*/ ++#endif /* !defined(CONFIG_MTK_CLKMGR) */ ++ ++#define BTIF_RBR(base) (unsigned long)(base + 0x0) /*RX Buffer Register: read only */ ++#define BTIF_THR(base) (unsigned long)(base + 0x0) /*Rx Holding Register: write only */ ++#define BTIF_IER(base) (unsigned long)(base + 0x4) /*Interrupt Enable Register: read/write */ ++#define BTIF_IIR(base) (unsigned long)(base + 0x8) /*Interrupt Identification Register: read only */ ++#define BTIF_FIFOCTRL(base) (unsigned long)(base + 0x8) /*FIFO Control Register: write only */ ++#define BTIF_FAKELCR(base) (unsigned long)(base + 0xC) /*FAKE LCR Register: read/write */ ++#define BTIF_LSR(base) (unsigned long)(base + 0x14) /*Line Status Register: read only */ ++#define BTIF_SLEEP_EN(base) (unsigned long)(base + 0x48) /*Sleep Enable Register: read/write */ ++#define BTIF_DMA_EN(base) (unsigned long)(base + 0x4C) /*DMA Enable Register: read/write */ ++#define BTIF_RTOCNT(base) (unsigned long)(base + 0x54) /*Rx Timeout Count Register: read/write */ ++#define BTIF_TRI_LVL(base) (unsigned long)(base + 0x60) /*Tx/Rx Trigger Level Control Register: read/write */ ++#define BTIF_WAK(base) (unsigned long)(base + 0x64) /*BTIF module wakeup Register: write only */ ++#define BTIF_WAT_TIME(base) (unsigned long)(base + 0x68) /*BTIF ASYNC Wait Time Control Register: read/write */ ++#define BTIF_HANDSHAKE(base) (unsigned long)(base + 0x6C) /*BTIF New Handshake Control Register: read/write */ ++ ++/*BTIF_IER bits*/ ++#define BTIF_IER_TXEEN (0x1 << 1) /*1: Tx holding register is empty */ ++#define BTIF_IER_RXFEN (0x1 << 0) /*1: Rx buffer contains data */ ++ ++/*BTIF_IIR bits*/ ++#define BTIF_IIR_NINT (0x1 << 0) /*No INT Pending */ ++#define BTIF_IIR_TX_EMPTY (0x1 << 1) /*Tx Holding Register empty */ ++#define BTIF_IIR_RX (0x1 << 2) /*Rx data received */ ++#define BTIF_IIR_RX_TIMEOUT (0x11 << 2) /*Rx data received */ ++ ++/*BTIF_LSR bits*/ ++#define BTIF_LSR_DR_BIT (0x1 << 0) ++#define BTIF_LSR_THRE_BIT (0x1 << 5) ++#define BTIF_LSR_TEMT_BIT (0x1 << 6) ++ ++/*BTIF_FIFOCTRL bits*/ ++#define BTIF_FIFOCTRL_CLR_TX (0x1 << 2) /*Clear Tx FIRO */ ++#define BTIF_FIFOCTRL_CLR_RX (0x1 << 1) /*Clear Rx FIRO */ ++ ++/*BTIF_FAKELCR bits*/ ++#define BTIF_FAKELCR_NORMAL_MODE 0x0 ++ ++/*BTIF_SLEEP_EN bits*/ ++#define BTIF_SLEEP_EN_BIT (0x1 << 0) /*enable Sleep mode */ ++#define BTIF_SLEEP_DIS_BIT (0x0) /*disable sleep mode */ ++ ++/*BTIF_DMA_EN bits*/ ++#define BTIF_DMA_EN_RX (0x1 << 0) /*Enable Rx DMA */ ++#define BTIF_DMA_EN_TX (0x1 << 1) /*Enable Tx DMA */ ++#define BTIF_DMA_EN_AUTORST_EN (0x1 << 2) /*1: timeout counter will be auto reset */ ++#define BTIF_DMA_EN_AUTORST_DIS (0x0 << 2) /* ++ * 0: after Rx timeout happens, ++ * SW shall reset the interrupt by reading BTIF 0x4C ++ */ ++ ++/*BTIF_TRI_LVL bits*/ ++#define BTIF_TRI_LVL_TX_MASK ((0xf) << 0) ++#define BTIF_TRI_LVL_RX_MASK ((0x7) << 4) ++ ++#define BTIF_TRI_LVL_TX(x) ((x & 0xf) << 0) ++#define BTIF_TRI_LVL_RX(x) ((x & 0x7) << 4) ++ ++#define BTIF_TRI_LOOP_EN (0x1 << 7) ++#define BTIF_TRI_LOOP_DIS (0x0 << 7) ++ ++/*BTIF_WAK bits*/ ++#define BTIF_WAK_BIT (0x1 << 0) ++ ++/*BTIF_HANDSHAKE bits*/ ++#define BTIF_HANDSHAKE_EN_HANDSHAKE 1 ++#define BTIF_HANDSHAKE_DIS_HANDSHAKE 0 ++ ++#define BTIF_TX_FIFO_SIZE 16 ++#define BTIF_RX_FIFO_SIZE 8 ++ ++#define BTIF_TX_FIFO_THRE (BTIF_TX_FIFO_SIZE / 2) ++#define BTIF_RX_FIFO_THRE 0x1 /* 0x5 */ ++ ++#endif /*__HAL_BTIF_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h +new file mode 100644 +index 000000000000..1555d5a50c38 +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h +@@ -0,0 +1,237 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_BTIF_PUB_H_ ++#define __HAL_BTIF_PUB_H_ ++ ++#include "plat_common.h" ++ ++/*Enum Defination*/ ++/*BTIF Mode Enum */ ++typedef enum _ENUM_BTIF_MODE_ { ++ BTIF_MODE_PIO = 0, ++ BTIF_MODE_DMA = BTIF_MODE_PIO + 1, ++ BTIF_MODE_MAX, ++} ENUM_BTIF_MODE; ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_info_get ++* DESCRIPTION ++* get btif's information included base address , irq related information ++* PARAMETERS ++* RETURNS ++* BTIF's information ++*****************************************************************************/ ++P_MTK_BTIF_INFO_STR hal_btif_info_get(void); ++ ++#if 0 /*included in hal_btif_info_get */ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_get_irq ++* DESCRIPTION ++* get BTIF module's IRQ information ++* PARAMETERS ++* RETURNS ++* pointer to BTIF's irq structure ++*****************************************************************************/ ++P_MTK_BTIF_IRQ_STR hal_btif_get_irq(void); ++#endif ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_get_and_prepare ++* DESCRIPTION ++* get clock from device tree and prepare for enable/disable control ++* PARAMETERS ++* pdev device pointer ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_get_and_prepare(struct platform_device *pdev); ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_unprepare ++* DESCRIPTION ++* unprepare btif clock and apdma clock ++* PARAMETERS ++* none ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_unprepare(void); ++#endif ++/***************************************************************************** ++* FUNCTION ++* hal_btif_clk_ctrl ++* DESCRIPTION ++* control clock output enable/disable of BTIF module ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_hw_init ++* DESCRIPTION ++* BTIF module init, after this step, BTIF should enable to do tx/rx with PIO ++* mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_cb_reg ++* DESCRIPTION ++* BTIF rx callback register API ++* PARAMETERS ++* p_btif_info [IN] pointer to BTIF's information ++* rx_cb [IN] rx callback function ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, ++ btif_rx_buf_write rx_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_loopback_ctrl ++* DESCRIPTION ++* BTIF Tx/Rx loopback mode set, this operation can only be done ++* after set BTIF to normal mode ++* PARAMETERS ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_handler ++* DESCRIPTION ++* lower level interrupt handler ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN/OUT] pointer to rx data buffer ++* max_len [IN] max length of rx buffer ++* RETURNS ++* 0 means success; negative means fail; positive means rx data length ++*****************************************************************************/ ++int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, ++ unsigned char *p_buf, const unsigned int max_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_tx_mode_ctrl ++* DESCRIPTION ++* set BTIF tx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_rx_mode_ctrl ++* DESCRIPTION ++* set BTIF rx to corresponding mode (PIO/DMA) ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* mode [IN] rx mode ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_send_data ++* DESCRIPTION ++* send data through btif in FIFO mode ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* p_buf [IN] pointer to rx data buffer ++* max_len [IN] tx buffer length ++* RETURNS ++* positive means number of data sent; ++* 0 means no data put to FIFO; ++* negative means error happens ++*****************************************************************************/ ++int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, ++ const unsigned char *p_buf, const unsigned int buf_len); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_raise_wak_sig ++* DESCRIPTION ++* raise wakeup signal to counterpart ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_dump_reg ++* DESCRIPTION ++* dump BTIF module's information when needed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* flag [IN] register id flag ++* RETURNS ++* 0 means success, negative means fail ++*****************************************************************************/ ++int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_complete ++* DESCRIPTION ++* get tx complete flag ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true means tx complete, false means tx in process ++*****************************************************************************/ ++bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif); ++ ++/***************************************************************************** ++* FUNCTION ++* hal_btif_is_tx_allow ++* DESCRIPTION ++* whether tx is allowed ++* PARAMETERS ++* p_base [IN] BTIF module's base address ++* RETURNS ++* true if tx operation is allowed; false if tx is not allowed ++*****************************************************************************/ ++bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); ++ ++int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif, MTK_BTIF_PM_OPID opid); ++ ++void mtk_btif_read_cpu_sw_rst_debug_plat(void); ++ ++#endif /*__HAL_BTIF_PUB_H_*/ +diff --git a/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h +new file mode 100644 +index 000000000000..2a1462cb32ff +--- /dev/null ++++ b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h +@@ -0,0 +1,307 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __HAL_PUB_H_ ++#define __HAL_PUB_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++#include ++#else ++#include ++#include ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++#include ++ ++extern int mtk_btif_hal_get_log_lvl(void); ++ ++#define MTK_BTIF_MARK_UNUSED_API ++ ++typedef irq_handler_t mtk_btif_irq_handler; ++ ++#define MTK_BTIF_ENABLE_CLK_CTL 1 ++#define MTK_BTIF_ENABLE_CLK_REF_COUNTER 1 ++ ++#define DBG_LOG_STR_SIZE 256 ++ ++/*Log defination*/ ++static int hal_log_print(const char *str, ...) ++{ ++ va_list args; ++ char temp_sring[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(temp_sring, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_err("%s", temp_sring); ++ ++ return 0; ++} ++ ++#define BTIF_LOG_LOUD 4 ++#define BTIF_LOG_DBG 3 ++#define BTIF_LOG_INFO 2 ++#define BTIF_LOG_WARN 1 ++#define BTIF_LOG_ERR 0 ++ ++#ifndef DFT_TAG ++#define DFT_TAG "[BTIF-DFT]" ++#endif ++ ++#define BTIF_LOUD_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_LOUD) \ ++ hal_log_print(DFT_TAG "[L]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_INFO_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_INFO)\ ++ hal_log_print(DFT_TAG "[I]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_WARN_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_WARN)\ ++ hal_log_print(DFT_TAG "[W]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_ERR_FUNC(fmt, arg ...)\ ++do {\ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_ERR)\ ++ hal_log_print(DFT_TAG "[E]%s(%d):" fmt,\ ++ __func__, __LINE__, ## arg);\ ++} while (0) ++ ++#define BTIF_DBG_FUNC(fmt, arg ...) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ ++ hal_log_print(DFT_TAG "[D]%s:" fmt, \ ++ __func__, ## arg); \ ++} while (0) ++ ++#define BTIF_TRC_FUNC(f) \ ++do { \ ++ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ ++ hal_log_print(DFT_TAG "<%s> <%d>\n", \ ++ __func__, __LINE__); \ ++} while (0) ++ ++/*-----------------------------------Enum Defination--------------------------------*/ ++/*IRQ sensetive type */ ++typedef enum _ENUM_IRQ_SENS_TYPE_ { ++ IRQ_SENS_EDGE = 0, ++ IRQ_SENS_LVL = IRQ_SENS_EDGE + 1, ++ IRQ_SENS_TYPE_MAX ++} ENUM_IRQ_SENS_TYPE; ++ ++/*IRQ level trigger type */ ++typedef enum _ENUM_IRQ_LVL_TYPE_ { ++ IRQ_LVL_LOW = 0, ++ IRQ_LVL_HIGH = IRQ_LVL_LOW + 1, ++ IRQ_LVL_MAX ++} ENUM_IRQ_LVL; ++ ++/*IRQ edge trigger type */ ++typedef enum _ENUM_IRQ_EDGE_TYPE_ { ++ IRQ_EDGE_FALL = 0, ++ IRQ_EDGE_RAISE = IRQ_EDGE_FALL + 1, ++ IRQ_EDGE_BOTH = IRQ_EDGE_RAISE + 1, ++ IRQ_EDGE_MAX ++} ENUM_IRQ_EDGE; ++ ++typedef enum _ENUM_CLOCK_CTRL_ { ++ CLK_OUT_DISABLE = 0, ++ CLK_OUT_ENABLE = CLK_OUT_DISABLE + 1, ++ CLK_OUT_MAX ++} ENUM_CLOCK_CTRL; ++ ++/*Error No. table */ ++typedef enum _ENUM_ERROR_CODE_ { ++ ERR_NO_ERROR = 0, ++ ERR_INVALID_PAR = ERR_NO_ERROR - 1, ++ ERR_MAX = ERR_INVALID_PAR - 1, ++} ENUM_ERROR_CODE; ++ ++typedef enum _ENUM_BTIF_DIR_ { ++ BTIF_TX = 0, ++ BTIF_RX = BTIF_TX + 1, ++ BTIF_DIR_MAX, ++} ENUM_BTIF_DIR; ++ ++typedef enum _ENUM_DMA_DIR_ { ++ DMA_DIR_RX = 0, ++ DMA_DIR_TX = DMA_DIR_RX + 1, ++ DMA_DIR_BOTH, ++} ENUM_DMA_DIR; ++ ++typedef enum _ENUM_BTIF_REG_ID_ { ++ REG_IIR = 0, /*Interrupt Identification Register */ ++ REG_LSR = 1, /*Line Status Register */ ++ REG_FAKE_LCR = 2, /*Fake Lcr Regiseter */ ++ REG_FIFO_CTRL = 3, /*FIFO Control Register */ ++ REG_IER = 4, /*Interrupt Enable Register */ ++ REG_SLEEP_EN = 5, /*Sleep Enable Register */ ++ REG_RTO_COUNTER = 6, /*Rx Timeout Counter Register */ ++ REG_DMA_EN = 7, /*DMA Enalbe Register */ ++ REG_TRIG_LVL = 8, /*Tx/Rx Trigger Level Register */ ++ REG_WAT_TIME = 9, /*Async Wait Time Register */ ++ REG_HANDSHAKE = 10, /*New HandShake Mode Register */ ++ REG_SLP_WAK = 11, /*Sleep Wakeup Reigster */ ++ REG_BTIF_ALL = 12, /*all btif controller's registers */ ++ REG_TX_DMA_ALL = 13, ++ REG_RX_DMA_ALL = 14, ++ REG_MAX ++} ENUM_BTIF_REG_ID; ++ ++typedef enum _MTK_BTIF_PM_OPID_ { ++ BTIF_PM_DPIDLE_EN, ++ BTIF_PM_DPIDLE_DIS, ++ BTIF_PM_SUSPEND, ++ BTIF_PM_RESUME, ++ BTIF_PM_RESTORE_NOIRQ, ++} MTK_BTIF_PM_OPID; ++ ++#define BTIF_HAL_TX_FIFO_SIZE (1024 * 4) ++ ++/*-----------------------------------Enum Defination End--------------------------------*/ ++ ++/*****************************structure definition***************************/ ++/*IRQ related information*/ ++typedef struct _MTK_BTIF_IRQ_STR_ { ++ const char *name; ++ bool is_irq_sup; ++ unsigned int irq_id; ++#ifdef CONFIG_OF ++ unsigned int irq_flags; ++#else ++ ENUM_IRQ_SENS_TYPE sens_type; ++ union { ++ ENUM_IRQ_LVL lvl_type; ++ ENUM_IRQ_EDGE edge_type; ++ }; ++#endif ++ bool reg_flag; ++ irq_handler_t p_irq_handler; ++} MTK_BTIF_IRQ_STR, *P_MTK_BTIF_IRQ_STR; ++ ++typedef struct _DMA_VFIFO_ { ++ /*[Driver Access] vFIFO memory'svirtual address */ ++ unsigned char *p_vir_addr; ++ /*[HW Access] dma handle , physically address, set to DMA's HW Register */ ++ dma_addr_t phy_addr; ++ /*DMA's vFIFO size */ ++ unsigned int vfifo_size; ++ /*DMA's threshold value */ ++ unsigned int thre; ++} DMA_VFIFO, *P_DMA_VFIFO; ++ ++typedef unsigned int (*dma_rx_buf_write) (void *p_dma_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++typedef unsigned int (*btif_rx_buf_write) (void *p_btif_info, ++ unsigned char *p_buf, ++ unsigned int buf_len); ++ ++/*DMA related information*/ ++typedef struct _MTK_DMA_INFO_STR_ { ++ unsigned long base; ++ ENUM_DMA_DIR dir; ++ P_MTK_BTIF_IRQ_STR p_irq; ++ dma_rx_buf_write rx_cb; ++ P_DMA_VFIFO p_vfifo; ++} MTK_DMA_INFO_STR, *P_MTK_DMA_INFO_STR; ++ ++/*DMA related information*/ ++typedef struct _MTK_BTIF_INFO_STR_ { ++ unsigned long base; /*base address */ ++ P_MTK_BTIF_IRQ_STR p_irq; /*irq related information */ ++ ++ unsigned int tx_fifo_size; /*BTIF tx FIFO size */ ++ unsigned int rx_fifo_size; /*BTIF rx FIFO size */ ++ ++ unsigned int tx_tri_lvl; /*BTIFtx trigger level in FIFO mode */ ++ unsigned int rx_tri_lvl; /*BTIFrx trigger level in FIFO mode */ ++ ++ unsigned int clk_gat_addr; /*clock gating address */ ++ unsigned int set_bit; /*enable clock gating bit */ ++ unsigned int clr_bit; /*clear clock gating bit */ ++ ++ unsigned int rx_data_len; /*rx data length */ ++ ++ btif_rx_buf_write rx_cb; ++ ++ struct kfifo *p_tx_fifo; /*tx fifo */ ++ spinlock_t tx_fifo_spinlock; /*tx fifo spinlock */ ++} MTK_BTIF_INFO_STR, *P_MTK_BTIF_INFO_STR; ++ ++/**********End of Structure Definition***********/ ++ ++/***********register operation***********/ ++#ifdef __KERNEL__ ++/*byte write <1 byte> */ ++#define btif_reg_sync_writeb(v, a) mt_reg_sync_writeb(v, a) ++/*word write <2 byte> */ ++#define btif_reg_sync_writew(v, a) mt_reg_sync_writew(v, a) ++/*long write <4 byte> */ ++#define btif_reg_sync_writel(v, a) mt_reg_sync_writel(v, a) ++#else ++/*byte write <1 byte> */ ++#define btif_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) ++/*word write <2 byte> */ ++#define btif_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) ++/*long write <4 byte> */ ++#define btif_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) ++#endif ++#define BTIF_READ8(REG) __raw_readb((unsigned char *)(REG)) ++#define BTIF_READ16(REG) __raw_readw((unsigned short *)(REG)) ++#define BTIF_READ32(REG) __raw_readl((unsigned int *)(REG)) ++ ++#define BTIF_SET_BIT(REG, BITVAL) do { \ ++*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL)); \ ++mb(); /**/ \ ++} \ ++while (0) ++#define BTIF_CLR_BIT(REG, BITVAL) do { \ ++(*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL)); \ ++mb(); /**/\ ++} \ ++while (0) ++ ++/***********end of register operation *********/ ++ ++#endif /*__HAL_PUB_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/Kconfig b/drivers/misc/mediatek/connectivity/Kconfig +new file mode 100644 +index 000000000000..4a944b1f0ebe +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/Kconfig +@@ -0,0 +1,299 @@ ++config MTK_COMBO ++ tristate "MediaTek Connectivity Combo Chip Support" ++ help ++ MTK connectivity combo chip driver for MT66xx ++ ++# ++# MTK Combo Chip Selection ++# ++ ++choice ++ prompt "Select Chip" ++ depends on MTK_COMBO ++ ++config MTK_COMBO_CHIP_MT6620 ++ bool "MT6620" ++ help ++ this config is used to decided combo chip version ++ in current platform ++ is ++ MT6620 ++ ++config MTK_COMBO_CHIP_MT6628 ++ bool "MT6628" ++ help ++ this config is used to decided combo chip version ++ in current platform ++ is ++ MT6628 ++ ++config MTK_COMBO_CHIP_MT6630 ++ bool "MT6630" ++ help ++ this config is used to decided combo chip version ++ in current platform ++ is ++ MT6630 ++ ++config MTK_COMBO_CHIP_CONSYS_6572 ++ bool "CONSYS_6572" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6572 ++ ++config MTK_COMBO_CHIP_CONSYS_6582 ++ bool "CONSYS_6582" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6582 ++ ++config MTK_COMBO_CHIP_CONSYS_8127 ++ bool "CONSYS_8127" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6572 ++ ++config MTK_COMBO_CHIP_CONSYS_7623 ++ bool "CONSYS_7623" ++ #select MTK_PLATFORM::="mt7623" ++ help ++ this config is used to decide SOC consys version ++ in current platform is MT7623 and prepare proper ++ system services like radio power on/off and firmware ++ download for the Bluetotoh and Wifi. ++ ++ ++config MTK_COMBO_CHIP_CONSYS_6752 ++ bool "CONSYS_6752" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6752 ++ ++config MTK_COMBO_CHIP_CONSYS_6592 ++ bool "CONSYS_6592" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6592 ++ ++config MTK_COMBO_CHIP_CONSYS_8163 ++ bool "CONSYS_8163" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT8163 ++ ++config MTK_COMBO_CHIP_CONSYS_6735 ++ bool "CONSYS_6735" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6735 ++ ++config MTK_COMBO_CHIP_CONSYS_6755 ++ bool "CONSYS_6755" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6755 ++ ++config MTK_COMBO_CHIP_CONSYS_6580 ++ bool "CONSYS_6580" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6580 ++ ++config MTK_COMBO_CHIP_CONSYS_6797 ++ bool "CONSYS_6797" ++ help ++ this config is used to decided SOC consys version ++ in current platform ++ is ++ MT6797 ++endchoice ++ ++config MTK_COMBO_CHIP ++ string ++ default "MT6620" if MTK_COMBO_CHIP_MT6620 ++ default "MT6628" if MTK_COMBO_CHIP_MT6628 ++ default "MT6630" if MTK_COMBO_CHIP_MT6630 ++ default "CONSYS_6572" if MTK_COMBO_CHIP_CONSYS_6572 ++ default "CONSYS_6582" if MTK_COMBO_CHIP_CONSYS_6582 ++ default "CONSYS_8127" if MTK_COMBO_CHIP_CONSYS_8127 ++ default "CONSYS_7623" if MTK_COMBO_CHIP_CONSYS_7623 ++ default "CONSYS_6752" if MTK_COMBO_CHIP_CONSYS_6752 ++ default "CONSYS_6755" if MTK_COMBO_CHIP_CONSYS_6755 ++ default "CONSYS_6592" if MTK_COMBO_CHIP_CONSYS_6592 ++ default "CONSYS_8163" if MTK_COMBO_CHIP_CONSYS_8163 ++ default "CONSYS_6735" if MTK_COMBO_CHIP_CONSYS_6735 ++ default "CONSYS_6580" if MTK_COMBO_CHIP_CONSYS_6580 ++ default "CONSYS_6797" if MTK_COMBO_CHIP_CONSYS_6797 ++ help ++ this feature is used to identify combo chip version or SOC chip ++ consys version. ++ ++# ++# Target Platform Selection ++# ++config MTK_COMBO_PLAT_PATH ++ string "Platform folder name" ++ depends on MTK_COMBO ++ default "sample" if MTK_COMBO_PLAT_SAMPLE ++ help ++ Specify platform folder under common driver platform folder: ++ mtk_wcn_combo/common/platform/* ++ ++# ++# MTK COMBO Chip Configuration ++# ++config MTK_COMBO_COMM ++ depends on MTK_COMBO ++ tristate "MediaTek Combo Chip Common part driver" ++ help ++ MediaTek combo chip common part driver ++ ++#config MTK_COMBO_COMM_PS ++# depends on MTK_COMBO_COMM ++# bool "Enable PS support" ++# default n ++# help ++# Enable PS support of common UART interface ++ ++config MTK_COMBO_COMM_UART ++ depends on MTK_COMBO_COMM ++ tristate "Common interface UART" ++ help ++ Use UART for common part interface type ++ ++config MTK_COMBO_COMM_SDIO ++ depends on MTK_COMBO_COMM ++ tristate "Common interface SDIO" ++ help ++ Use SDIO for common part interface type ++ ++config MTK_COMBO_COMM_NPWR ++ depends on MTK_COMBO_COMM ++ bool "Enable NPWR support" ++ default n ++ help ++ Enable NPWR support of new power on swquence ++ ++config MTK_COMBO_COMM_APO ++ depends on MTK_COMBO_COMM ++ bool "Enable always power on support" ++ #default y ++ help ++ Enable chip will always power on ++ ++config MTK_COMBO_BT ++ tristate "MediaTek Combo Chip BT driver" ++ depends on BT && MTK_COMBO ++ select MTK_BTIF ++ help ++ MTK BT /dev/stpbt driver for Bluedroid ++ ++config MTK_COMBO_BT_HCI ++ tristate "MediaTek Combo Chip BlueZ driver" ++ depends on BT && MTK_COMBO ++ select MTK_BTIF ++ help ++ MTK BT driver for BlueZ ++ ++config MTK_COMBO_WIFI ++ tristate "MediaTek combo chip Wi-Fi support" ++ depends on MTK_COMBO ++ select MTK_BTIF ++ select WIRELESS_EXT ++ select WEXT_PRIV ++ ++config MTK_WAPI_SUPPORT ++ bool "MTK_WAPI_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ #default y ++ help ++ if it is set to TRUE: Support WAPI (WLAN Authentication and ++ Privacy Infrastructure) ++ ++config MTK_PASSPOINT_R1_SUPPORT ++ bool "MTK_PASSPOINT_R1_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ help ++ Support Passpoint R1 (Hotspot 2.0 R1) ++ ++config MTK_PASSPOINT_R2_SUPPORT ++ bool "MTK_PASSPOINT_R2_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ help ++ Support Passpoint R2 ++ ++config MTK_WIFI_MCC_SUPPORT ++ bool "MTK_WIFI_MCC_SUPPORT" ++ depends on MTK_COMBO_WIFI ++ #default y ++ help ++ if it is set to TRUE, wlan will support Multi-Channel Concurrency, ++ otherwise, only support Single Channel Concurrency ++ ++config MTK_DHCPV6C_WIFI ++ bool "MTK_DHCPV6C_WIFI" ++ help ++ no: disable this feature ++ ++config MTK_CONN_LTE_IDC_SUPPORT ++ bool "MediaTek CONN LTE IDC support" ++ select MTK_CONN_MD ++ #default y ++ help ++ This option enables CONN LTE IDC support ++ ++menuconfig GPS ++ tristate "GPS drivers" ++ #default y ++ ---help--- ++ Say Y here for supporting GPS. ++ ++if GPS ++config MTK_GPS ++ tristate "MediaTek GPS driver" ++ #default y ++ ---help--- ++ MTK GPS driver ++ To switch gps nmea port driver. ++ Set "yes" to turn on. ++ Set "no" to turn off. ++endif # GPS ++ ++config MTK_GPS_SUPPORT ++ tristate "MediaTek GPS driver" ++ select MTK_GPS ++ help ++ to switch GPS feature on the platform. ++ Set "yes" to turn on and set "no" ++ (with MTK_AGPS_APP=no at the same time) ++ to turn off. ++ ++config MTK_GPS_REGISTER_SETTING ++ tristate "MediaTek GPS Register Setting" ++ depends on MTK_COMBO_GPS ++ help ++ GPS register settings. ++ ++config MTK_GPS_EMI ++ tristate "MediaTek GPS EMI Driver" ++ depends on MTK_COMBO_GPS ++ help ++ GPS EMI driver is for MNL OFFLOAD feature. +diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile +new file mode 100644 +index 000000000000..0947788d189a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/Makefile +@@ -0,0 +1,41 @@ ++# ++# Copyright (C) 2015 MediaTek Inc. ++# ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License version 2 as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++ ++# Connectivity combo driver ++# If KERNELRELEASE is defined, we've been invoked from the ++# kernel build system and can use its language. ++ifneq ($(KERNELRELEASE),) ++subdir-ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE ++ifeq ($(CONFIG_ARM64), y) ++subdir-ccflags-y += -D CONFIG_MTK_WCN_ARM64 ++endif ++ ++ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) ++ subdir-ccflags-y += -D WMT_IDC_SUPPORT=1 ++else ++ subdir-ccflags-y += -D WMT_IDC_SUPPORT=0 ++endif ++ subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++ obj-y += common/ ++ obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/ ++ obj-n := dummy.o ++ ++# Otherwise we were called directly from the command line; ++# invoke the kernel build system. ++else ++ KERNELDIR ?= /lib/modules/$(shell uname -r)/build ++ PWD := $(shell pwd) ++default: ++ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/Makefile b/drivers/misc/mediatek/connectivity/common/Makefile +new file mode 100644 +index 000000000000..622b74430e13 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/Makefile +@@ -0,0 +1,23 @@ ++subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include ++subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat ++ ++#ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) ++# obj-y += combo/ ++#endif ++#ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) ++# subdir-ccflags-y += -D MT6628 ++# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT ++# obj-y += combo/ ++#endif ++#ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) ++# subdir-ccflags-y += -D MT6630 ++#ifneq ($(CONFIG_ARCH_MT2601),y) ++# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT ++#endif ++# obj-y += combo/ ++#endif ++ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++ obj-y += conn_soc/ ++endif ++ ++obj-y += common_detect/ +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile +new file mode 100644 +index 000000000000..8d7dc690affd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile +@@ -0,0 +1,47 @@ ++subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/dct/dct ++subdir-ccflags-y += -DWMT_PLAT_ALPS=1 ++ ++COMBO_CHIP_SUPPORT := false ++ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) ++ COMBO_CHIP_SUPPORT := true ++endif ++ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) ++ COMBO_CHIP_SUPPORT := true ++endif ++ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) ++ COMBO_CHIP_SUPPORT := true ++endif ++ifeq ($(COMBO_CHIP_SUPPORT), true) ++ subdir-ccflags-y += -D MTK_WCN_COMBO_CHIP_SUPPORT ++ ccflags-y += -I$(src)/../combo/linux/include ++endif ++ ++ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++ subdir-ccflags-y += -D MTK_WCN_SOC_CHIP_SUPPORT ++ ccflags-y += -I$(src)/../conn_soc/linux/include ++endif ++ ++ ++ifeq ($(CONFIG_MTK_COMBO),y) ++ ccflags-y += -I$(src)/drv_init/inc ++ obj-y += mtk_wcn_stub_alps.o ++ obj-y += wmt_stp_exp.o ++ obj-y += wmt_gpio.o ++ ++ obj-y += wmt_detect.o ++ obj-y += sdio_detect.o ++ obj-y += wmt_detect_pwr.o ++ ++ obj-y += drv_init/ ++endif ++ ++ifeq ($(CONFIG_MTK_COMBO),m) ++ obj-y += mtk_wcn_stub_alps.o ++ obj-y += wmt_stp_exp.o ++ obj-y += wmt_gpio.o ++ ++ obj-$(CONFIG_MTK_COMBO) += mtk_wmt_detect.o ++ mtk_wmt_detect-objs := wmt_detect.o ++ mtk_wmt_detect-objs += sdio_detect.o ++ mtk_wmt_detect-objs += wmt_detect_pwr.o ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +new file mode 100644 +index 000000000000..bb84384b9a24 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +@@ -0,0 +1,22 @@ ++ifeq ($(CONFIG_MTK_COMBO),y) ++ ccflags-y += -I$(src)/inc/ ++ ccflags-y += -I$(src)/../ ++ ++ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) ++ ccflags-y += -D MTK_WCN_WLAN_GEN3 ++endif ++ifneq ($(filter "CONSYS_6797",$(CONFIG_MTK_COMBO_CHIP)),) ++ ccflags-y += -D MTK_WCN_WLAN_GEN3 ++else ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++ ccflags-y += -D MTK_WCN_WLAN_GEN2 ++endif ++ ++ obj-y += conn_drv_init.o ++ obj-y += common_drv_init.o ++ obj-y += bluetooth_drv_init.o ++ obj-y += gps_drv_init.o ++ obj-y += fm_drv_init.o ++ obj-y += wlan_drv_init.o ++ obj-($(CONFIG_MTK_COMBO_ANT)) += ant_drv_init.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c +new file mode 100644 +index 000000000000..aa453f9397a4 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c +@@ -0,0 +1,38 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[ANT-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "ant_drv_init.h" ++ ++int do_ant_drv_init(int chip_id) ++{ ++ int i_ret = -1; ++ ++ WMT_DETECT_INFO_FUNC("start to do ANT driver init\n"); ++ switch (chip_id) { ++ case 0x6630: ++ case 0x6797: ++ i_ret = mtk_wcn_stpant_drv_init(); ++ WMT_DETECT_INFO_FUNC("finish ANT driver init, i_ret:%d\n", i_ret); ++ break; ++ default: ++ WMT_DETECT_ERR_FUNC("chipid is not 6630,ANT is not supported!\n"); ++ } ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c +new file mode 100644 +index 000000000000..47b055433443 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c +@@ -0,0 +1,35 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[BT-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "bluetooth_drv_init.h" ++ ++int do_bluetooth_drv_init(int chip_id) ++{ ++ int i_ret = -1; ++ ++#if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI) ++ WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n"); ++ i_ret = mtk_wcn_stpbt_drv_init(); ++ WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret); ++#else ++ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n"); ++#endif ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c +new file mode 100644 +index 000000000000..f9c332ea266b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c +@@ -0,0 +1,103 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "common_drv_init.h" ++ ++static int do_combo_common_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ int i_ret_tmp = 0; ++ ++ WMT_DETECT_DBG_FUNC("start to do combo driver init, chipid:0x%08x\n", chip_id); ++ ++ /* HIF-SDIO driver init */ ++ i_ret_tmp = mtk_wcn_hif_sdio_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("HIF-SDIO driver init, i_ret:%d\n", i_ret); ++ ++ /* WMT driver init */ ++ i_ret_tmp = mtk_wcn_combo_common_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); ++ ++ /* STP-UART driver init */ ++ i_ret_tmp = mtk_wcn_stp_uart_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("STP-UART driver init, i_ret:%d\n", i_ret); ++ ++ /* STP-SDIO driver init */ ++ i_ret_tmp = mtk_wcn_stp_sdio_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("STP-SDIO driver init, i_ret:%d\n", i_ret); ++ ++#else ++ i_ret = -1; ++ WMT_DETECT_ERR_FUNC("COMBO chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); ++#endif ++ WMT_DETECT_DBG_FUNC("finish combo driver init\n"); ++ return i_ret; ++} ++ ++static int do_soc_common_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++#ifdef MTK_WCN_SOC_CHIP_SUPPORT ++ int i_ret_tmp = 0; ++ ++ WMT_DETECT_DBG_FUNC("start to do soc common driver init, chipid:0x%08x\n", chip_id); ++ ++ /* WMT driver init */ ++ i_ret_tmp = mtk_wcn_soc_common_drv_init(); ++ i_ret += i_ret_tmp; ++ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); ++ ++#else ++ i_ret = -1; ++ WMT_DETECT_ERR_FUNC("SOC chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); ++#endif ++ ++ WMT_DETECT_DBG_FUNC("TBD........\n"); ++ return i_ret; ++} ++ ++int do_common_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++ WMT_DETECT_INFO_FUNC("start to do common driver init, chipid:0x%08x\n", chip_id); ++ ++ switch (chip_id) { ++ case 0x6620: ++ case 0x6628: ++ case 0x6630: ++ i_ret = do_combo_common_drv_init(chip_id); ++ break; ++ default: ++ i_ret = do_soc_common_drv_init(chip_id); ++ break; ++ } ++ ++ WMT_DETECT_INFO_FUNC("finish common driver init\n"); ++ ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c +new file mode 100644 +index 000000000000..8112d2a1d95e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c +@@ -0,0 +1,80 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WCN-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "conn_drv_init.h" ++#include "common_drv_init.h" ++#include "fm_drv_init.h" ++#include "wlan_drv_init.h" ++#include "bluetooth_drv_init.h" ++#include "gps_drv_init.h" ++#include "ant_drv_init.h" ++ ++int __weak do_wlan_drv_init(int chip_id) ++{ ++ WMT_DETECT_ERR_FUNC("Can not find wlan module for chip: %d !\n", chip_id); ++ return 0; ++} ++ ++int __weak do_ant_drv_init(int chip_id) ++{ ++ WMT_DETECT_DBG_FUNC("Chip: %d can not support ANT !\n", chip_id); ++ return 0; ++} ++ ++int do_connectivity_driver_init(int chip_id) ++{ ++ int i_ret = 0; ++ int tmp_ret = 0; ++ ++ tmp_ret = do_common_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) { ++ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); ++ WMT_DETECT_ERR_FUNC("abort connectivity driver init, because common part is not ready\n"); ++ return i_ret; ++ } ++ ++ tmp_ret = do_bluetooth_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_gps_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_fm_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do fm module init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_wlan_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do wlan module init failed, ret:%d\n", tmp_ret); ++ ++ tmp_ret = do_ant_drv_init(chip_id); ++ i_ret += tmp_ret; ++ if (tmp_ret) ++ WMT_DETECT_ERR_FUNC("do ANT module init failed, ret:%d\n", tmp_ret); ++ ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c +new file mode 100644 +index 000000000000..069c1cf13bba +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c +@@ -0,0 +1,33 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[FM-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "fm_drv_init.h" ++ ++int do_fm_drv_init(int chip_id) ++{ ++ WMT_DETECT_INFO_FUNC("start to do fm module init\n"); ++ ++#ifdef CONFIG_MTK_FMRADIO ++ mtk_wcn_fm_init(); ++#endif ++ ++ WMT_DETECT_INFO_FUNC("finish fm module init\n"); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c +new file mode 100644 +index 000000000000..6da1d70a3ca6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c +@@ -0,0 +1,35 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[GPS-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "gps_drv_init.h" ++ ++int do_gps_drv_init(int chip_id) ++{ ++ int i_ret = -1; ++#ifdef CONFIG_MTK_COMBO_GPS ++ WMT_DETECT_INFO_FUNC("start to do gps driver init\n"); ++ i_ret = mtk_wcn_stpgps_drv_init(); ++ WMT_DETECT_INFO_FUNC("finish gps driver init, i_ret:%d\n", i_ret); ++#else ++ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_GPS is not defined\n"); ++#endif ++ return i_ret; ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h +new file mode 100644 +index 000000000000..4a436a236290 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h +@@ -0,0 +1,20 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _ANT_DRIVER_INIT_H_ ++#define _ANT_DRIVER_INIT_H_ ++ ++extern int do_ant_drv_init(int chip_id); ++extern int mtk_wcn_stpant_drv_init(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h +new file mode 100644 +index 000000000000..8a847d361fc8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h +@@ -0,0 +1,20 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _BLUETOOTH_DRIVER_INIT_H_ ++#define _BLUETOOTH_DRIVER_INIT_H_ ++ ++extern int do_bluetooth_drv_init(int chip_id); ++extern int mtk_wcn_stpbt_drv_init(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h +new file mode 100644 +index 000000000000..ea01bd633c3c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h +@@ -0,0 +1,31 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _COMMON_DRV_INIT_H_ ++#define _COMMON_DRV_INIT_H_ ++extern int do_common_drv_init(int chip_id); ++ ++/*defined in common part driver*/ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++extern int mtk_wcn_combo_common_drv_init(void); ++extern int mtk_wcn_hif_sdio_drv_init(void); ++extern int mtk_wcn_stp_uart_drv_init(void); ++extern int mtk_wcn_stp_sdio_drv_init(void); ++#endif ++ ++#ifdef MTK_WCN_SOC_CHIP_SUPPORT ++extern int mtk_wcn_soc_common_drv_init(void); ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h +new file mode 100644 +index 000000000000..971193eade9e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h +@@ -0,0 +1,18 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _CONNECTIVITY_DRV_INIT_H_ ++#define _CONNECTIVITY_DRV_INIT_H_ ++extern int do_connectivity_driver_init(int chip_id); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h +new file mode 100644 +index 000000000000..f6ea30addc5d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h +@@ -0,0 +1,20 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _FM_DRV_INIT_H_ ++#define _FM_DRV_INIT_H_ ++extern int do_fm_drv_init(int chip_id); ++extern int mtk_wcn_fm_init(void); ++extern void mtk_wcn_fm_exit(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h +new file mode 100644 +index 000000000000..006ce072c53b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h +@@ -0,0 +1,19 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _GPS_DRIVER_INIT_H_ ++#define _GPS_DRIVER_INIT_H_ ++extern int do_gps_drv_init(int chip_id); ++extern int mtk_wcn_stpgps_drv_init(void); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h +new file mode 100644 +index 000000000000..cb71b50bf950 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h +@@ -0,0 +1,30 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WLAN_DRV_INIT_H_ ++#define _WLAN_DRV_INIT_H_ ++ ++ ++extern int do_wlan_drv_init(int chip_id); ++ ++extern int mtk_wcn_wmt_wifi_init(void); ++ ++#ifdef MTK_WCN_WLAN_GEN2 ++extern int mtk_wcn_wlan_gen2_init(void); ++#endif ++#ifdef MTK_WCN_WLAN_GEN3 ++extern int mtk_wcn_wlan_gen3_init(void); ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +new file mode 100644 +index 000000000000..5b0d039a4a42 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +@@ -0,0 +1,74 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WLAN-MOD-INIT]" ++ ++#include "wmt_detect.h" ++#include "wlan_drv_init.h" ++ ++ ++int do_wlan_drv_init(int chip_id) ++{ ++ int i_ret = 0; ++ ++#ifdef CONFIG_MTK_COMBO_WIFI ++ int ret = 0; ++ ++ WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); ++ ++ /* WMT-WIFI char dev init */ ++ ret = mtk_wcn_wmt_wifi_init(); ++ WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); ++ i_ret += ret; ++ ++ switch (chip_id) { ++ case 0x6630: ++ case 0x6797: ++#ifdef MTK_WCN_WLAN_GEN3 ++ /* WLAN driver init */ ++ ret = mtk_wcn_wlan_gen3_init(); ++ WMT_DETECT_INFO_FUNC("WLAN-GEN3 driver init, ret:%d\n", ret); ++ i_ret += ret; ++#else ++ WMT_DETECT_ERR_FUNC("WLAN-GEN3 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); ++ i_ret = -1; ++#endif ++ break; ++ ++ default: ++#ifdef MTK_WCN_WLAN_GEN2 ++ /* WLAN driver init */ ++ ret = mtk_wcn_wlan_gen2_init(); ++ WMT_DETECT_INFO_FUNC("WLAN-GEN2 driver init, ret:%d\n", ret); ++ i_ret += ret; ++#else ++ WMT_DETECT_ERR_FUNC("WLAN-GEN2 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); ++ i_ret = -1; ++#endif ++ break; ++ } ++ ++ WMT_DETECT_INFO_FUNC("finish wlan module init\n"); ++ ++#else ++ ++ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); ++ ++#endif ++ ++ return i_ret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c +new file mode 100644 +index 000000000000..fa8d437686f2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c +@@ -0,0 +1,605 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define CMB_STUB_DBG_LOG 3 ++#define CMB_STUB_INFO_LOG 2 ++#define CMB_STUB_WARN_LOG 1 ++ ++int gCmbStubLogLevel = CMB_STUB_INFO_LOG; ++ ++#define CMB_STUB_LOG_INFO(fmt, arg...) \ ++do { \ ++ if (gCmbStubLogLevel >= CMB_STUB_INFO_LOG) \ ++ pr_warn(fmt, ##arg); \ ++} while (0) ++#define CMB_STUB_LOG_WARN(fmt, arg...) \ ++do { \ ++ if (gCmbStubLogLevel >= CMB_STUB_WARN_LOG) \ ++ pr_warn(fmt, ##arg); \ ++} while (0) ++#define CMB_STUB_LOG_DBG(fmt, arg...) \ ++do { \ ++ if (gCmbStubLogLevel >= CMB_STUB_DBG_LOG) \ ++ pr_debug(fmt, ##arg); \ ++} while (0) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "wmt_detect.h" ++ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 ++#endif ++ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++struct work_struct *g_sdio_1v_autok_wk = NULL; ++#endif ++int gConnectivityChipId = -1; ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++/* ++* current used uart port name, default is "ttyMT2", ++* will be changed when wmt driver init ++*/ ++char *wmt_uart_port_desc = "ttyMT2"; ++EXPORT_SYMBOL(wmt_uart_port_desc); ++#endif ++ ++static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data); ++static void mtk_wcn_cmb_sdio_enable_eirq(void); ++static void mtk_wcn_cmb_sdio_disable_eirq(void); ++static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data); ++ ++struct sdio_ops mt_sdio_ops[4] = { ++ {NULL, NULL, NULL, NULL}, ++ {NULL, NULL, NULL, NULL}, ++ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, ++ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm}, ++ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, ++ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm} ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb; ++static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb; ++static wmt_thermal_query_cb cmb_stub_thermal_ctrl_cb; ++static CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0; ++static wmt_deep_idle_ctrl_cb cmb_stub_deep_idle_ctrl_cb; ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++static wmt_get_drv_status cmb_stub_drv_status_ctrl_cb; ++#endif ++static wmt_func_do_reset cmb_stub_do_reset_cb; ++/* A temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X. ++ * This is used for ALPS backward compatible ONLY!!! Remove this table, related ++ * functions, and type definition after modifying other kernel built-in modules, ++ * such as AUDIO. [FixMe][GeorgeKuo] ++ */ ++#if 0 ++static CMB_STUB_AIF_X audio2aif[] = { ++ [COMBO_AUDIO_STATE_0] = CMB_STUB_AIF_0, ++ [COMBO_AUDIO_STATE_1] = CMB_STUB_AIF_1, ++ [COMBO_AUDIO_STATE_2] = CMB_STUB_AIF_2, ++ [COMBO_AUDIO_STATE_3] = CMB_STUB_AIF_3, ++}; ++#endif ++static msdc_sdio_irq_handler_t mtk_wcn_cmb_sdio_eirq_handler; ++static atomic_t sdio_claim_irq_enable_flag; ++static atomic_t irq_enable_flag; ++static pm_callback_t mtk_wcn_cmb_sdio_pm_cb; ++static void *mtk_wcn_cmb_sdio_pm_data; ++static void *mtk_wcn_cmb_sdio_eirq_data; ++ ++static u32 wifi_irq = 0xffffffff; ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++static void mtk_wcn_cmb_stub_1v_autok_work(struct work_struct *work) ++{ ++ CMB_STUB_LOG_WARN("++enter++\n"); ++ mtk_wcn_cmb_stub_func_ctrl(11, 1); ++ mtk_wcn_cmb_stub_func_ctrl(11, 0); ++ CMB_STUB_LOG_WARN("--exit--\n"); ++} ++ ++/*! ++ * \brief A function for Getting current driver status:on/off ++ * ++ * \param driver type:0/bt,1/fm,2/gps,3/wifi,11/autok->run wmt turn on/off wifi flow ++ * ++ * \retval 0/off,2/on,-1/null pointer ++ */ ++static int mtk_wcn_cmb_stub_drv_status(unsigned int type) ++{ ++ int ret = -1; ++ ++ if (cmb_stub_drv_status_ctrl_cb) ++ ret = (*cmb_stub_drv_status_ctrl_cb) (type); ++ else ++ CMB_STUB_LOG_WARN("cmb_stub_drv_status_ctrl_cb is NULL\n"); ++ return ret; ++} ++ ++/*! ++ * \brief A 1v AutoK function for kernel DVFS driver calling when screen off ++ * ++ * \param void ++ * ++ * \retval int,mt6630 state:0/off,1/power on,2/func on, -1/null ++ */ ++int mtk_wcn_cmb_stub_1vautok_for_dvfs(void) ++{ ++ int wmt_status; ++ ++ CMB_STUB_LOG_WARN("DVFS driver call sdio 1v autok\n"); ++ ++ wmt_status = mtk_wcn_cmb_stub_drv_status(4); ++ CMB_STUB_LOG_WARN("current mt6630 status is %d\n", wmt_status); ++ if (0 == wmt_status) { ++ if (g_sdio_1v_autok_wk) ++ schedule_work(g_sdio_1v_autok_wk); ++ else ++ CMB_STUB_LOG_WARN("g_sdio_1v_autok_wk is NULL\n"); ++ } else if ((2 == wmt_status) || (1 == wmt_status)) { ++ CMB_STUB_LOG_WARN("mt6630 is on state,skip AUTOK\n"); ++ } else { ++ CMB_STUB_LOG_WARN("mt6630 is unknown state(%d)\n", wmt_status); ++ } ++ ++ return wmt_status; ++ ++} ++#endif ++/*! ++ * \brief A registration function for WMT-PLAT to register itself to CMB-STUB. ++ * ++ * An MTK-WCN-CMB-STUB registration function provided to WMT-PLAT to register ++ * itself and related callback functions when driver being loaded into kernel. ++ * ++ * \param p_stub_cb a pointer carrying CMB_STUB_CB information ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid parameters ++ */ ++int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb) ++{ ++ if ((!p_stub_cb) ++ || (p_stub_cb->size != sizeof(CMB_STUB_CB))) { ++ CMB_STUB_LOG_WARN("[cmb_stub] invalid p_stub_cb:0x%p size(%d)\n", ++ p_stub_cb, (p_stub_cb) ? p_stub_cb->size : 0); ++ return -1; ++ } ++ ++ CMB_STUB_LOG_DBG("[cmb_stub] registered, p_stub_cb:0x%p size(%d)\n", p_stub_cb, p_stub_cb->size); ++ ++ cmb_stub_aif_ctrl_cb = p_stub_cb->aif_ctrl_cb; ++ cmb_stub_func_ctrl_cb = p_stub_cb->func_ctrl_cb; ++ cmb_stub_thermal_ctrl_cb = p_stub_cb->thermal_query_cb; ++ cmb_stub_deep_idle_ctrl_cb = p_stub_cb->deep_idle_ctrl_cb; ++ cmb_stub_do_reset_cb = p_stub_cb->wmt_do_reset_cb; ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ cmb_stub_drv_status_ctrl_cb = p_stub_cb->get_drv_status_cb; ++ g_sdio_1v_autok_wk = vmalloc(sizeof(struct work_struct)); ++ if (!g_sdio_1v_autok_wk) ++ CMB_STUB_LOG_WARN("vmalloc work_struct(%zd) fail\n", sizeof(struct work_struct)); ++ else ++ INIT_WORK(g_sdio_1v_autok_wk, mtk_wcn_cmb_stub_1v_autok_work); ++ ++#endif ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_reg); ++/*! ++ * \brief A unregistration function for WMT-PLAT to unregister from CMB-STUB. ++ * ++ * An MTK-WCN-CMB-STUB unregistration function provided to WMT-PLAT to ++ * unregister itself and clear callback function references. ++ * ++ * \retval 0 operation success ++ */ ++int mtk_wcn_cmb_stub_unreg(void) ++{ ++ cmb_stub_aif_ctrl_cb = NULL; ++ cmb_stub_func_ctrl_cb = NULL; ++ cmb_stub_thermal_ctrl_cb = NULL; ++ cmb_stub_deep_idle_ctrl_cb = NULL; ++ cmb_stub_do_reset_cb = NULL; ++ CMB_STUB_LOG_INFO("[cmb_stub] unregistered\n"); /* KERN_DEBUG */ ++ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ if (g_sdio_1v_autok_wk) { ++ vfree(g_sdio_1v_autok_wk); ++ g_sdio_1v_autok_wk = NULL; ++ } ++#endif ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_unreg); ++ ++/* stub functions for kernel to control audio path pin mux */ ++int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) ++{ ++ int ret; ++ ++ if ((CMB_STUB_AIF_MAX <= state) ++ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { ++ ++ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl invalid (%d, %d)\n", state, ctrl); ++ return -1; ++ } ++ ++ /* avoid the early interrupt before we register the eirq_handler */ ++ if (cmb_stub_aif_ctrl_cb) { ++ ret = (*cmb_stub_aif_ctrl_cb) (state, ctrl); ++ CMB_STUB_LOG_INFO("[cmb_stub] aif_ctrl_cb state(%d->%d) ctrl(%d) ret(%d)\n", ++ cmb_stub_aif_stat, state, ctrl, ret); /* KERN_DEBUG */ ++ ++ cmb_stub_aif_stat = state; ++ } else { ++ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl_cb null\n"); ++ ret = -2; ++ } ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_aif_ctrl); ++ ++/* Use a temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X ++ * for ALPS backward compatible ONLY!!! Remove this table, related functions, ++ * and type definition after modifying other kernel built-in modules, such as ++ * AUDIO. [FixMe][GeorgeKuo] ++ */ ++ ++void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on) ++{ ++ if (cmb_stub_func_ctrl_cb) ++ (*cmb_stub_func_ctrl_cb) (type, on); ++ else ++ CMB_STUB_LOG_WARN("[cmb_stub] func_ctrl_cb null\n"); ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_func_ctrl); ++ ++int mtk_wcn_cmb_stub_query_ctrl(void) ++{ ++ signed long temp = 0; ++ ++ if (cmb_stub_thermal_ctrl_cb) ++ temp = (*cmb_stub_thermal_ctrl_cb) (); ++ else ++ CMB_STUB_LOG_WARN("[cmb_stub] thermal_ctrl_cb null\n"); ++ ++ return temp; ++} ++ ++/*platform-related APIs*/ ++/* void clr_device_working_ability(UINT32 clockId, MT6573_STATE state); */ ++/* void set_device_working_ability(UINT32 clockId, MT6573_STATE state); */ ++ ++static int _mt_combo_plt_do_deep_idle(COMBO_IF src, int enter) ++{ ++ int ret = -1; ++ ++#if 0 ++ if (src != COMBO_IF_UART && src != COMBO_IF_MSDC && src != COMBO_IF_BTIF) { ++ CMB_STUB_LOG_WARN("src = %d is error\n", src); ++ return ret; ++ } ++ if (src >= 0 && src < COMBO_IF_MAX) ++ CMB_STUB_LOG_INFO("src = %s, to enter deep idle? %d\n", combo_if_name[src], enter); ++#endif ++ /*TODO: For Common SDIO configuration, we need to do some judgement between STP and WIFI ++ to decide if the msdc will enter deep idle safely */ ++ ++ switch (src) { ++ case COMBO_IF_UART: ++ if (enter == 0) { ++ /* clr_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ ++ /* disable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++#if 0 ++ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 0); ++ if (ret < 0) ++ CMB_STUB_LOG_WARN("[CMB] %s exit deep idle failed\n", wmt_uart_port_desc); ++#endif ++#endif ++ } else { ++ /* set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ ++ /* enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++#if 0 ++ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 1); ++ if (ret < 0) ++ CMB_STUB_LOG_WARN("[CMB] %s enter deep idle failed\n", wmt_uart_port_desc); ++#endif ++#endif ++ } ++ ret = 0; ++ break; ++ ++ case COMBO_IF_MSDC: ++ if (enter == 0) { ++ /* for common sdio hif */ ++ /* clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ ++ } else { ++ /* for common sdio hif */ ++ /* set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ ++ } ++ ret = 0; ++ break; ++ ++ case COMBO_IF_BTIF: ++ if (cmb_stub_deep_idle_ctrl_cb) ++ ret = (*cmb_stub_deep_idle_ctrl_cb) (enter); ++ else ++ CMB_STUB_LOG_WARN("NULL function pointer\n"); ++ ++ if (ret) ++ CMB_STUB_LOG_WARN("%s deep idle fail(%d)\n", enter == 1 ? "enter" : "exit", ret); ++ else ++ CMB_STUB_LOG_DBG("%s deep idle ok(%d)\n", enter == 1 ? "enter" : "exit", ret); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++int mt_combo_plt_enter_deep_idle(COMBO_IF src) ++{ ++ /* return 0; */ ++ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ ++ return _mt_combo_plt_do_deep_idle(src, 1); ++} ++EXPORT_SYMBOL(mt_combo_plt_enter_deep_idle); ++ ++int mt_combo_plt_exit_deep_idle(COMBO_IF src) ++{ ++ /* return 0; */ ++ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ ++ return _mt_combo_plt_do_deep_idle(src, 0); ++} ++EXPORT_SYMBOL(mt_combo_plt_exit_deep_idle); ++ ++int mtk_wcn_wmt_chipid_query(void) ++{ ++ return gConnectivityChipId; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query); ++ ++void mtk_wcn_wmt_set_chipid(int chipid) ++{ ++ CMB_STUB_LOG_INFO("set current consys chipid (0x%x)\n", chipid); ++ gConnectivityChipId = chipid; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_set_chipid); ++ ++int mtk_wcn_cmb_stub_do_reset(unsigned int type) ++{ ++ if (cmb_stub_do_reset_cb) ++ return (*cmb_stub_do_reset_cb) (type); ++ else ++ return -1; ++} ++EXPORT_SYMBOL(mtk_wcn_cmb_stub_do_reset); ++ ++static void mtk_wcn_cmb_sdio_enable_eirq(void) ++{ ++ if (atomic_read(&irq_enable_flag)) ++ CMB_STUB_LOG_DBG("wifi eint has been enabled\n"); ++ else { ++ atomic_set(&irq_enable_flag, 1); ++ if (wifi_irq != 0xfffffff) { ++ enable_irq(wifi_irq); ++ CMB_STUB_LOG_DBG(" enable WIFI EINT irq %d !!\n", wifi_irq); ++ } ++ } ++} ++ ++static void mtk_wcn_cmb_sdio_disable_eirq(void) ++{ ++ if (!atomic_read(&irq_enable_flag)) ++ CMB_STUB_LOG_DBG("wifi eint has been disabled!\n"); ++ else { ++ if (wifi_irq != 0xfffffff) { ++ disable_irq_nosync(wifi_irq); ++ CMB_STUB_LOG_DBG("disable WIFI EINT irq %d !!\n", wifi_irq); ++ } ++ atomic_set(&irq_enable_flag, 0); ++ } ++} ++ ++irqreturn_t mtk_wcn_cmb_sdio_eirq_handler_stub(int irq, void *data) ++{ ++ if ((NULL != mtk_wcn_cmb_sdio_eirq_handler)&&(0 != atomic_read(&sdio_claim_irq_enable_flag))) ++ mtk_wcn_cmb_sdio_eirq_handler(mtk_wcn_cmb_sdio_eirq_data); ++ return IRQ_HANDLED; ++} ++ ++static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data) ++{ ++ struct device_node *node; ++ int ret = -EINVAL; ++#if 0 ++ unsigned int gpio_wifi_eint_pin; ++#endif ++ ++ CMB_STUB_LOG_INFO("enter %s\n", __func__); ++ mtk_wcn_sdio_irq_flag_set(0); ++ atomic_set(&irq_enable_flag, 0); ++ mtk_wcn_cmb_sdio_eirq_data = data; ++ mtk_wcn_cmb_sdio_eirq_handler = irq_handler; ++ ++ node = (struct device_node *)of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); ++ if (node) { ++#if 0 ++ gpio_wifi_eint_pin = of_get_gpio(node, 5); ++ CMB_STUB_LOG_INFO("WIFI EINT pin %d !!\n", gpio_wifi_eint_pin); ++ wifi_irq = gpio_to_irq(gpio_wifi_eint_pin); ++#else ++ wifi_irq = irq_of_parse_and_map(node, 0);/* get wifi eint num */ ++#endif ++#if 1 ++ ret = request_irq(wifi_irq, mtk_wcn_cmb_sdio_eirq_handler_stub, IRQF_TRIGGER_LOW, ++ "WIFI-eint", NULL); ++ CMB_STUB_LOG_DBG("WIFI EINT irq %d !!\n", wifi_irq); ++#endif ++ ++ if (ret) ++ CMB_STUB_LOG_WARN("WIFI EINT IRQ LINE NOT AVAILABLE!!\n"); ++ else ++ mtk_wcn_cmb_sdio_disable_eirq();/*not ,chip state is power off*/ ++ } else ++ CMB_STUB_LOG_WARN("[%s] can't find connectivity compatible node\n", __func__); ++ ++ CMB_STUB_LOG_INFO("exit %s\n", __func__); ++} ++ ++static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data) ++{ ++ CMB_STUB_LOG_DBG("mtk_wcn_cmb_sdio_register_pm (0x%p, 0x%p)\n", pm_cb, data); ++ /* register pm change callback */ ++ mtk_wcn_cmb_sdio_pm_cb = pm_cb; ++ mtk_wcn_cmb_sdio_pm_data = data; ++} ++ ++static void mtk_wcn_cmb_sdio_on(int sdio_port_num) ++{ ++ pm_message_t state = {.event = PM_EVENT_USER_RESUME }; ++ ++ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_on (%d)\n", sdio_port_num); ++ ++ /* 1. disable sdio eirq */ ++ mtk_wcn_cmb_sdio_disable_eirq(); ++ ++ /* 2. call sd callback */ ++ if (mtk_wcn_cmb_sdio_pm_cb) { ++ /* pr_warn("mtk_wcn_cmb_sdio_pm_cb(PM_EVENT_USER_RESUME, 0x%p, 0x%p)\n", ++ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ ++ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); ++ } else ++ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_on no sd callback!!\n"); ++} ++ ++static void mtk_wcn_cmb_sdio_off(int sdio_port_num) ++{ ++ pm_message_t state = {.event = PM_EVENT_USER_SUSPEND }; ++ ++ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_off (%d)\n", sdio_port_num); ++ ++ /* 1. call sd callback */ ++ if (mtk_wcn_cmb_sdio_pm_cb) { ++ /* pr_warn("mtk_wcn_cmb_sdio_off(PM_EVENT_USER_SUSPEND, 0x%p, 0x%p)\n", ++ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ ++ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); ++ } else ++ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_off no sd callback!!\n"); ++ ++ /* 2. disable sdio eirq */ ++ mtk_wcn_cmb_sdio_disable_eirq(); ++} ++ ++int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on) ++{ ++ CMB_STUB_LOG_DBG("mt_mtk_wcn_cmb_sdio_ctrl (%d, %d)\n", sdio_port_num, on); ++ if (on) { ++#if 1 ++ CMB_STUB_LOG_DBG("board_sdio_ctrl force off before on\n"); ++ mtk_wcn_cmb_sdio_off(sdio_port_num); ++#else ++ CMB_STUB_LOG_WARN("skip sdio off before on\n"); ++#endif ++ /* off -> on */ ++ mtk_wcn_cmb_sdio_on(sdio_port_num); ++ if (wifi_irq != 0xfffffff) ++ irq_set_irq_wake(wifi_irq, 1); ++ else ++ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); ++ } else { ++ if (wifi_irq != 0xfffffff) ++ irq_set_irq_wake(wifi_irq, 0); ++ else ++ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); ++ /* on -> off */ ++ mtk_wcn_cmb_sdio_off(sdio_port_num); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(board_sdio_ctrl); ++ ++int mtk_wcn_sdio_irq_flag_set(int flag) ++{ ++ if (0 != flag) ++ atomic_set(&sdio_claim_irq_enable_flag, 1); ++ else ++ atomic_set(&sdio_claim_irq_enable_flag, 0); ++ ++ CMB_STUB_LOG_DBG("sdio_claim_irq_enable_flag:%d\n", atomic_read(&sdio_claim_irq_enable_flag)); ++ ++ return atomic_read(&sdio_claim_irq_enable_flag); ++} ++EXPORT_SYMBOL(mtk_wcn_sdio_irq_flag_set); +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c +new file mode 100644 +index 000000000000..7ac5ac73ef5d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c +@@ -0,0 +1,269 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[SDIO-DETECT]" ++ ++#include "wmt_detect.h" ++ ++#if MTK_HIF_SDIO_AUTOK_ENABLED ++#include ++#endif ++ ++unsigned int gComboChipId = -1; ++struct sdio_func *g_func = NULL; ++ ++MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = { ++ /* MT6620 *//* Not an SDIO standard class device */ ++ {{SDIO_DEVICE(0x037A, 0x020A)}, 0x6620}, /* SDIO1:FUNC1:WIFI */ ++ {{SDIO_DEVICE(0x037A, 0x020B)}, 0x6620}, /* SDIO2:FUNC1:BT+FM+GPS */ ++ {{SDIO_DEVICE(0x037A, 0x020C)}, 0x6620}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ ++ ++ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {{SDIO_DEVICE(0x037A, 0x6628)}, 0x6628}, ++ ++ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {{SDIO_DEVICE(0x037A, 0x6630)}, 0x6630}, ++ ++}; ++ ++/* Supported SDIO device table */ ++static const struct sdio_device_id mtk_sdio_id_tbl[] = { ++ /* MT6618 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x018A)}, /* SDIO1:WIFI */ ++ {SDIO_DEVICE(0x037A, 0x018B)}, /* SDIO2:FUNC1:BT+FM */ ++ {SDIO_DEVICE(0x037A, 0x018C)}, /* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */ ++ ++ /* MT6619 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x6619)}, /* SDIO2:FUNC1:BT+FM+GPS */ ++ ++ /* MT6620 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x020A)}, /* SDIO1:FUNC1:WIFI */ ++ {SDIO_DEVICE(0x037A, 0x020B)}, /* SDIO2:FUNC1:BT+FM+GPS */ ++ {SDIO_DEVICE(0x037A, 0x020C)}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ ++ ++ /* MT5921 *//* Not an SDIO standard class device */ ++ {SDIO_DEVICE(0x037A, 0x5921)}, ++ ++ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {SDIO_DEVICE(0x037A, 0x6628)}, ++ ++ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ ++ {SDIO_DEVICE(0x037A, 0x6630)}, ++ { /* end: all zeroes */ }, ++}; ++ ++static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id); ++ ++static void sdio_detect_remove(struct sdio_func *func); ++ ++static struct sdio_driver mtk_sdio_client_drv = { ++ .name = "mtk_sdio_client", /* MTK SDIO Client Driver */ ++ .id_table = mtk_sdio_id_tbl, /* all supported struct sdio_device_id table */ ++ .probe = sdio_detect_probe, ++ .remove = sdio_detect_remove, ++}; ++ ++static int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id); ++ ++int hif_sdio_is_chipid_valid(int chipId) ++{ ++ int index = -1; ++ ++ int left = 0; ++ int middle = 0; ++ int right = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]) - 1; ++ ++ if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId)) ++ return index; ++ ++ middle = (left + right) / 2; ++ ++ while (left <= right) { ++ if (chipId > gChipInfoArray[middle].chipId) { ++ left = middle + 1; ++ } else if (chipId < gChipInfoArray[middle].chipId) { ++ right = middle - 1; ++ } else { ++ index = middle; ++ break; ++ } ++ middle = (left + right) / 2; ++ } ++ ++ if (0 > index) ++ WMT_DETECT_ERR_FUNC("no supported chipid found\n"); ++ else ++ WMT_DETECT_INFO_FUNC("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId); ++ ++ return index; ++} ++ ++int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id) ++{ ++ int maxIndex = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]); ++ int index = 0; ++ struct sdio_device_id *localId = NULL; ++ int chipId = -1; ++ ++ for (index = 0; index < maxIndex; index++) { ++ localId = &(gChipInfoArray[index].deviceId); ++ if ((localId->vendor == id->vendor) && (localId->device == id->device)) { ++ chipId = gChipInfoArray[index].chipId; ++ WMT_DETECT_INFO_FUNC ++ ("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index, ++ localId->vendor, localId->device, chipId); ++ gComboChipId = chipId; ++ mtk_wcn_wmt_set_chipid(gComboChipId); ++ break; ++ } ++ } ++ if (0 > chipId) { ++ WMT_DETECT_ERR_FUNC("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor, ++ id->device); ++ } ++ ++ return chipId; ++} ++ ++int sdio_detect_query_chipid(int waitFlag) ++{ ++ unsigned int timeSlotMs = 200; ++ unsigned int maxTimeSlot = 15; ++ unsigned int counter = 0; ++ /* gComboChipId = 0x6628; */ ++ if (0 == waitFlag) ++ return gComboChipId; ++ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) ++ return gComboChipId; ++ ++ while (counter < maxTimeSlot) { ++ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) ++ break; ++ msleep(timeSlotMs); ++ counter++; ++ } ++ ++ return gComboChipId; ++} ++ ++int sdio_detect_do_autok(int chipId) ++{ ++ int i_ret = 0; ++ ++#if MTK_HIF_SDIO_AUTOK_ENABLED ++#if 0 ++ BOOTMODE boot_mode; ++ ++ boot_mode = get_boot_mode(); ++ ++ if (boot_mode == META_BOOT) { ++ WMT_DETECT_INFO_FUNC("omit autok in meta mode\n"); ++ return 0; ++ } ++#endif ++ if (0x6630 == chipId) { ++#ifdef CONFIG_SDIOAUTOK_SUPPORT ++ if (NULL != g_func) { ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready++\n"); ++ i_ret = wait_sdio_autok_ready(g_func->card->host); ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready--\n"); ++ if (0 == i_ret) { ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return success\n"); ++ } else { ++ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return fail, i_ret:%d\n", i_ret); ++ gComboChipId = -1; ++ } ++ } else { ++ WMT_DETECT_INFO_FUNC("g_func NULL, omit autok\n"); ++ } ++#else ++ i_ret = 0; ++ WMT_DETECT_INFO_FUNC("MTK_SDIOAUTOK_SUPPORT not defined\n"); ++#endif ++ } else { ++ WMT_DETECT_INFO_FUNC("MT%x does not support SDIO3.0 autoK is not needed\n", chipId); ++ } ++#else ++ i_ret = 0; ++ WMT_DETECT_INFO_FUNC("MTK_HIF_SDIO_AUTOK_ENABLED is not defined\n"); ++#endif ++ return i_ret; ++} ++ ++/*! ++ * \brief hif_sdio probe function ++ * ++ * hif_sdio probe function called by mmc driver when any matched SDIO function ++ * is detected by it. ++ * ++ * \param func ++ * \param id ++ * ++ * \retval 0 register successfully ++ * \retval < 0 list error code here ++ */ ++static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id) ++{ ++ int chipId = 0; ++ ++ WMT_DETECT_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); ++ chipId = hif_sdio_match_chipid_by_dev_id(id); ++ ++ if ((0x6630 == chipId) && (1 == func->num)) { ++ int ret = 0; ++ ++ g_func = func; ++ WMT_DETECT_INFO_FUNC("autok function detected, func:0x%p\n", g_func); ++ ++ sdio_claim_host(func); ++ ret = sdio_enable_func(func); ++ sdio_release_host(func); ++ if (ret) ++ WMT_DETECT_ERR_FUNC("sdio_enable_func failed!\n"); ++ } ++ ++ return 0; ++} ++ ++static void sdio_detect_remove(struct sdio_func *func) ++{ ++ if (g_func == func) { ++ sdio_claim_host(func); ++ sdio_disable_func(func); ++ sdio_release_host(func); ++ g_func = NULL; ++ } ++ WMT_DETECT_INFO_FUNC("do sdio remove\n"); ++} ++ ++int sdio_detect_init(void) ++{ ++ int ret = -1; ++ /* register to mmc driver */ ++ ret = sdio_register_driver(&mtk_sdio_client_drv); ++ WMT_DETECT_INFO_FUNC("sdio_register_driver() ret=%d\n", ret); ++ return 0; ++} ++ ++int sdio_detect_exit(void) ++{ ++ g_func = NULL; ++ /* register to mmc driver */ ++ sdio_unregister_driver(&mtk_sdio_client_drv); ++ WMT_DETECT_INFO_FUNC("sdio_unregister_driver\n"); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h +new file mode 100644 +index 000000000000..3a0bff9def1b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h +@@ -0,0 +1,43 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _SDIO_DETECT_H_ ++#define _SDIO_DETECT_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_SDIOAUTOK_SUPPORT ++#define MTK_HIF_SDIO_AUTOK_ENABLED 1 ++extern int wait_sdio_autok_ready(void *); ++#else ++#define MTK_HIF_SDIO_AUTOK_ENABLED 0 ++#endif ++ ++typedef struct _MTK_WCN_HIF_SDIO_CHIP_INFO_ { ++ struct sdio_device_id deviceId; ++ unsigned int chipId; ++} MTK_WCN_HIF_SDIO_CHIP_INFO, *P_MTK_WCN_HIF_SDIO_CHIP_INFO; ++ ++extern int sdio_detect_exit(void); ++extern int sdio_detect_init(void); ++extern int sdio_detect_query_chipid(int waitFlag); ++extern int hif_sdio_is_chipid_valid(int chipId); ++ ++extern int sdio_detect_do_autok(int chipId); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c +new file mode 100644 +index 000000000000..487852df8f20 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c +@@ -0,0 +1,380 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-DETECT]" ++ ++#include "wmt_detect.h" ++#include "wmt_gpio.h" ++ ++#if MTK_WCN_REMOVE_KO ++#include "conn_drv_init.h" ++#endif ++#ifdef CONFIG_COMPAT ++#include ++#endif ++ ++#define WMT_DETECT_MAJOR 154 ++#define WMT_DETECT_DEV_NUM 1 ++#define WMT_DETECT_DRVIER_NAME "mtk_wcn_detect" ++#define WMT_DETECT_DEVICE_NAME "wmtdetect" ++ ++struct class *pDetectClass = NULL; ++struct device *pDetectDev = NULL; ++static int gWmtDetectMajor = WMT_DETECT_MAJOR; ++static struct cdev gWmtDetectCdev; ++unsigned int gWmtDetectDbgLvl = WMT_DETECT_LOG_INFO; ++ ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++inline unsigned int wmt_plat_get_soc_chipid(void) ++{ ++ WMT_DETECT_INFO_FUNC("no soc chip supported, due to MTK_WCN_SOC_CHIP_SUPPORT is not set.\n"); ++ return -1; ++} ++#endif ++ ++static int wmt_detect_open(struct inode *inode, struct file *file) ++{ ++ WMT_DETECT_INFO_FUNC("open major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ++ return 0; ++} ++ ++static int wmt_detect_close(struct inode *inode, struct file *file) ++{ ++ WMT_DETECT_INFO_FUNC("close major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ++ return 0; ++} ++ ++static ssize_t wmt_detect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ WMT_DETECT_INFO_FUNC(" ++\n"); ++ WMT_DETECT_INFO_FUNC(" --\n"); ++ ++ return 0; ++} ++ ++ssize_t wmt_detect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ WMT_DETECT_INFO_FUNC(" ++\n"); ++ WMT_DETECT_INFO_FUNC(" --\n"); ++ ++ return 0; ++} ++ ++static long wmt_detect_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ int retval = 0; ++ ++ WMT_DETECT_INFO_FUNC("cmd (%d),arg(%ld)\n", cmd, arg); ++ ++ switch (cmd) { ++ case COMBO_IOCTL_GET_CHIP_ID: ++ /*just get chipid from sdio-detect module */ ++ /*check if external combo chip exists or not */ ++ /*if yes, just return combo chip id */ ++ /*if no, get soc chipid */ ++ retval = mtk_wcn_wmt_chipid_query(); ++ break; ++ ++ case COMBO_IOCTL_SET_CHIP_ID: ++ mtk_wcn_wmt_set_chipid(arg); ++ ++ break; ++ ++ case COMBO_IOCTL_EXT_CHIP_PWR_ON: ++ retval = wmt_detect_ext_chip_pwr_on(); ++ break; ++ ++ case COMBO_IOCTL_EXT_CHIP_DETECT: ++ retval = wmt_detect_ext_chip_detect(); ++ break; ++ ++ case COMBO_IOCTL_EXT_CHIP_PWR_OFF: ++ retval = wmt_detect_ext_chip_pwr_off(); ++ break; ++ ++ case COMBO_IOCTL_DO_SDIO_AUDOK: ++ retval = sdio_detect_do_autok(arg); ++ break; ++ ++ case COMBO_IOCTL_GET_SOC_CHIP_ID: ++ retval = wmt_plat_get_soc_chipid(); ++ /*get soc chipid by HAL interface */ ++ break; ++ ++ case COMBO_IOCTL_MODULE_CLEANUP: ++#if (MTK_WCN_REMOVE_KO) ++ /*deinit SDIO-DETECT module */ ++ retval = sdio_detect_exit(); ++#else ++ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); ++#endif ++ break; ++ ++ case COMBO_IOCTL_DO_MODULE_INIT: ++#if (MTK_WCN_REMOVE_KO) ++ /*deinit SDIO-DETECT module */ ++ retval = do_connectivity_driver_init(arg); ++#else ++ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); ++#endif ++ break; ++ ++ default: ++ WMT_DETECT_WARN_FUNC("unknown cmd (%d)\n", cmd); ++ retval = 0; ++ break; ++ } ++ return retval; ++} ++#ifdef CONFIG_COMPAT ++static long WMT_compat_detect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ WMT_DETECT_INFO_FUNC("cmd (%d)\n", cmd); ++ ret = wmt_detect_unlocked_ioctl(filp, cmd, arg); ++ return ret; ++} ++#endif ++const struct file_operations gWmtDetectFops = { ++ .open = wmt_detect_open, ++ .release = wmt_detect_close, ++ .read = wmt_detect_read, ++ .write = wmt_detect_write, ++ .unlocked_ioctl = wmt_detect_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = WMT_compat_detect_ioctl, ++#endif ++}; ++ ++int wmt_detect_ext_chip_pwr_on(void) ++{ ++ /*pre power on external chip */ ++ /* wmt_plat_pwr_ctrl(FUNC_ON); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ WMT_DETECT_INFO_FUNC("++\n"); ++ if (0 != wmt_detect_chip_pwr_ctrl(1)) ++ return -1; ++ if (0 != wmt_detect_sdio_pwr_ctrl(1)) ++ return -2; ++ return 0; ++#else ++ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); ++ return -1; ++#endif ++} ++ ++int wmt_detect_ext_chip_pwr_off(void) ++{ ++ /*pre power off external chip */ ++ /* wmt_plat_pwr_ctrl(FUNC_OFF); */ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ WMT_DETECT_INFO_FUNC("--\n"); ++ wmt_detect_sdio_pwr_ctrl(0); ++ return wmt_detect_chip_pwr_ctrl(0); ++#else ++ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); ++ return 0; ++#endif ++} ++ ++int wmt_detect_ext_chip_detect(void) ++{ ++ int iRet = -1; ++ unsigned int chipId = -1; ++ /*if there is no external combo chip, return -1 */ ++ int bgfEintStatus = -1; ++ ++ WMT_DETECT_INFO_FUNC("++\n"); ++ /*wait for a stable time */ ++ msleep(20); ++ ++ /*read BGF_EINT_PIN status */ ++ bgfEintStatus = wmt_detect_read_ext_cmb_status(); ++ ++ if (0 == bgfEintStatus) { ++ /*external chip does not exist */ ++ WMT_DETECT_INFO_FUNC("external combo chip not detected\n"); ++ } else if (1 == bgfEintStatus) { ++ /*combo chip exists */ ++ WMT_DETECT_INFO_FUNC("external combo chip detected\n"); ++ ++ /*detect chipid by sdio_detect module */ ++ chipId = sdio_detect_query_chipid(1); ++ if (0 <= hif_sdio_is_chipid_valid(chipId)) ++ WMT_DETECT_INFO_FUNC("valid external combo chip id (0x%x)\n", chipId); ++ else ++ WMT_DETECT_INFO_FUNC("invalid external combo chip id (0x%x)\n", chipId); ++ iRet = 0; ++ } else { ++ /*Error exists */ ++ WMT_DETECT_ERR_FUNC("error happens when detecting combo chip\n"); ++ } ++ WMT_DETECT_INFO_FUNC("--\n"); ++ /*return 0 */ ++ return iRet; ++ /*todo: if there is external combo chip, power on chip return 0 */ ++} ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++static int wmt_detect_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ WMT_DETECT_ERR_FUNC("platform name: %s\n", pdev->name); ++ ret = wmt_gpio_init(pdev); ++ if (-1 == ret) ++ WMT_DETECT_ERR_FUNC("gpio init fail ret:%d\n", ret); ++ return ret; ++} ++ ++static int wmt_detect_remove(struct platform_device *pdev) ++{ ++ wmt_gpio_deinit(); ++ return 0; ++} ++#endif ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++static struct of_device_id wmt_detect_match[] = { ++ { .compatible = "mediatek,connectivity-combo", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, wmt_detect_match); ++ ++static struct platform_driver wmt_detect_driver = { ++ .probe = wmt_detect_probe, ++ .remove = wmt_detect_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "mediatek,connectivity-combo", ++ .of_match_table = wmt_detect_match, ++ }, ++}; ++#endif ++ ++/*module_platform_driver(wmt_detect_driver);*/ ++static int wmt_detect_driver_init(void) ++{ ++ dev_t devID = MKDEV(gWmtDetectMajor, 0); ++ int cdevErr = -1; ++ int ret = -1; ++ ++ ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME); ++ if (ret) { ++ WMT_DETECT_ERR_FUNC("fail to register chrdev\n"); ++ return ret; ++ } ++ ++ cdev_init(&gWmtDetectCdev, &gWmtDetectFops); ++ gWmtDetectCdev.owner = THIS_MODULE; ++ ++ cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM); ++ if (cdevErr) { ++ WMT_DETECT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); ++ goto err1; ++ } ++ ++ pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME); ++ if (IS_ERR(pDetectClass)) { ++ WMT_DETECT_ERR_FUNC("class create fail, error code(%ld)\n", PTR_ERR(pDetectClass)); ++ goto err1; ++ } ++ ++ pDetectDev = device_create(pDetectClass, NULL, devID, NULL, WMT_DETECT_DEVICE_NAME); ++ if (IS_ERR(pDetectDev)) { ++ WMT_DETECT_ERR_FUNC("device create fail, error code(%ld)\n", PTR_ERR(pDetectDev)); ++ goto err2; ++ } ++ ++ WMT_DETECT_INFO_FUNC("driver(major %d) installed success\n", gWmtDetectMajor); ++ ++ /*init SDIO-DETECT module */ ++ sdio_detect_init(); ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ ret = platform_driver_register(&wmt_detect_driver); ++ if (ret) ++ WMT_DETECT_ERR_FUNC("platform driver register fail ret:%d\n", ret); ++#endif ++ ++ return 0; ++ ++err2: ++ ++ if (pDetectClass) { ++ class_destroy(pDetectClass); ++ pDetectClass = NULL; ++ } ++ ++err1: ++ ++ if (cdevErr == 0) ++ cdev_del(&gWmtDetectCdev); ++ ++ if (ret == 0) { ++ unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM); ++ gWmtDetectMajor = -1; ++ } ++ ++ WMT_DETECT_ERR_FUNC("fail\n"); ++ ++ return -1; ++} ++ ++static void wmt_detect_driver_exit(void) ++{ ++ dev_t dev = MKDEV(gWmtDetectMajor, 0); ++ ++ if (pDetectDev) { ++ device_destroy(pDetectClass, dev); ++ pDetectDev = NULL; ++ } ++ ++ if (pDetectClass) { ++ class_destroy(pDetectClass); ++ pDetectClass = NULL; ++ } ++ ++ cdev_del(&gWmtDetectCdev); ++ unregister_chrdev_region(dev, WMT_DETECT_DEV_NUM); ++ ++#if !(MTK_WCN_REMOVE_KO) ++/*deinit SDIO-DETECT module*/ ++ sdio_detect_exit(); ++#endif ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ platform_driver_unregister(&wmt_detect_driver); ++#endif ++ ++ WMT_DETECT_INFO_FUNC("done\n"); ++} ++ ++module_init(wmt_detect_driver_init); ++module_exit(wmt_detect_driver_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Zhiguo.Niu & Chaozhong.Liang @ MBJ/WCNSE/SS1"); ++ ++module_param(gWmtDetectMajor, uint, 0); +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h +new file mode 100644 +index 000000000000..7e152bfd39ec +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h +@@ -0,0 +1,114 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_DETECT_H_ ++#define _WMT_DETECT_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++#define MTK_WCN_REMOVE_KO 1 ++#else ++#define MTK_WCN_REMOVE_KO 0 ++#endif ++ ++#include "sdio_detect.h" ++#include "wmt_detect_pwr.h" ++#include ++ ++#define WMT_DETECT_LOG_LOUD 4 ++#define WMT_DETECT_LOG_DBG 3 ++#define WMT_DETECT_LOG_INFO 2 ++#define WMT_DETECT_LOG_WARN 1 ++#define WMT_DETECT_LOG_ERR 0 ++ ++extern unsigned int gWmtDetectDbgLvl; ++ ++#define WMT_DETECT_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_LOUD) \ ++ pr_debug(DFT_TAG"[L]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_DETECT_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_DBG) \ ++ pr_debug(DFT_TAG"[D]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_DETECT_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_INFO) \ ++ pr_err(DFT_TAG"[I]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_DETECT_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_WARN) \ ++ pr_warn(DFT_TAG"[W]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define WMT_DETECT_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_ERR) \ ++ pr_err(DFT_TAG"[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++ ++#define WMT_IOC_MAGIC 'w' ++#define COMBO_IOCTL_GET_CHIP_ID _IOR(WMT_IOC_MAGIC, 0, int) ++#define COMBO_IOCTL_SET_CHIP_ID _IOW(WMT_IOC_MAGIC, 1, int) ++#define COMBO_IOCTL_EXT_CHIP_DETECT _IOR(WMT_IOC_MAGIC, 2, int) ++#define COMBO_IOCTL_GET_SOC_CHIP_ID _IOR(WMT_IOC_MAGIC, 3, int) ++#define COMBO_IOCTL_DO_MODULE_INIT _IOR(WMT_IOC_MAGIC, 4, int) ++#define COMBO_IOCTL_MODULE_CLEANUP _IOR(WMT_IOC_MAGIC, 5, int) ++#define COMBO_IOCTL_EXT_CHIP_PWR_ON _IOR(WMT_IOC_MAGIC, 6, int) ++#define COMBO_IOCTL_EXT_CHIP_PWR_OFF _IOR(WMT_IOC_MAGIC, 7, int) ++#define COMBO_IOCTL_DO_SDIO_AUDOK _IOR(WMT_IOC_MAGIC, 8, int) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++********************************************************************************/ ++extern int wmt_detect_ext_chip_detect(void); ++extern int wmt_detect_ext_chip_pwr_on(void); ++extern int wmt_detect_ext_chip_pwr_off(void); ++ ++#ifdef MTK_WCN_SOC_CHIP_SUPPORT ++extern unsigned int wmt_plat_get_soc_chipid(void); ++#endif ++ ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver ++ * ++ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" ++ * @ enable - "1", enable deep idle; "0", disable deep idle ++ * ++ * Return 0 if success, else -1 ++ */ ++extern unsigned int mtk_uart_pdn_enable(char *port, int enable); ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c +new file mode 100644 +index 000000000000..1dcb7ed358bc +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c +@@ -0,0 +1,232 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-DETECT]" ++ ++#include "wmt_detect.h" ++#include "wmt_gpio.h" ++ ++#define INVALID_PIN_ID (0xFFFFFFFF) ++ ++/*copied form WMT module*/ ++static int wmt_detect_dump_pin_conf(void) ++{ ++ WMT_DETECT_DBG_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n"); ++ ++ WMT_DETECT_INFO_FUNC("LDO(GPIO%d), PMU(GPIO%d), PMUV28(GPIO%d)\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num); ++ ++ WMT_DETECT_INFO_FUNC("RST(GPIO%d), BGF_EINT(GPIO%d), BGF_EINT_NUM(%d)\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num, ++ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num)); ++ ++ WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d), WIFI_EINT_NUM(%d)\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num, ++ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)); ++ ++ WMT_DETECT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration ends<=\n"); ++ ++ return 0; ++} ++ ++int _wmt_detect_output_low(unsigned int id) ++{ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0); ++ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", ++ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); ++ } ++ ++ return 0; ++} ++ ++int _wmt_detect_output_high(unsigned int id) ++{ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1); ++ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", ++ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); ++ } ++ ++ return 0; ++} ++ ++int _wmt_detect_read_gpio_input(unsigned int id) ++{ ++ int retval = 0; ++ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { ++ retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num); ++ WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n", ++ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval); ++ } ++ ++ return retval; ++} ++ ++/*This power on sequence must support all combo chip's basic power on sequence ++ * 1. LDO control is a must, if external LDO exist ++ * 2. PMU control is a must ++ * 3. RST control is a must ++ * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup ++ * 5. RTC32k clock control is a must ++ * */ ++static int wmt_detect_chip_pwr_on(void) ++{ ++ int retval = -1; ++ /*setting validiation check*/ ++ if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) || ++ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) || ++ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) { ++ WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n", ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num); ++ ++ return retval; ++ } ++ /*set LDO/PMU/RST to output 0, no pull*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]); ++ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); ++ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); ++ ++#if 0 ++ _wmt_detect_output_high(GPIO_WIFI_EINT_PIN); ++#endif ++ ++ /*pull high LDO*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) ++ _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN); ++ /*sleep for LDO stable time*/ ++ msleep(MAX_LDO_STABLE_TIME); ++ ++ /*export RTC clock, sleep for RTC stable time*/ ++ rtc_gpio_enable_32k(RTC_GPIO_USER_GPS); ++ msleep(MAX_RTC_STABLE_TIME); ++ /*PMU output low, RST output low, to make chip power off completely*/ ++ /*always done*/ ++ /*sleep for power off stable time*/ ++ msleep(MAX_OFF_STABLE_TIME); ++ /*PMU output high, and sleep for reset stable time*/ ++ _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN); ++#ifdef CONFIG_MTK_COMBO_COMM_NPWR ++ if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) && ++ (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) { ++ msleep(20); ++ _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN); ++ ++ msleep(20); ++ _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN); ++ ++ msleep(20); ++ _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN); ++ ++ msleep(20); ++ _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN); ++ ++ msleep(20); ++ } ++#endif ++ msleep(MAX_RST_STABLE_TIME); ++ /*RST output high, and sleep for power on stable time */ ++ _wmt_detect_output_high(GPIO_COMBO_RST_PIN); ++ msleep(MAX_ON_STABLE_TIME); ++ ++ retval = 0; ++ return retval; ++} ++ ++static int wmt_detect_chip_pwr_off(void) ++{ ++ ++ /*set RST pin to input low status*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); ++ /*set RST pin to input low status*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); ++ /*set PMU pin to input low status*/ ++ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) ++ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); ++ return 0; ++} ++ ++int wmt_detect_read_ext_cmb_status(void) ++{ ++ int retval = 0; ++ /*read WIFI_EINT pin status*/ ++ if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) { ++ retval = 0; ++ WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n"); ++ } else { ++ retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN); ++ WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval); ++ } ++ return retval; ++} ++ ++int wmt_detect_chip_pwr_ctrl(int on) ++{ ++ int retval = -1; ++ ++ if (0 == on) { ++ /*power off combo chip */ ++ retval = wmt_detect_chip_pwr_off(); ++ } else { ++ wmt_detect_dump_pin_conf(); ++ /*power on combo chip */ ++ retval = wmt_detect_chip_pwr_on(); ++ } ++ return retval; ++} ++ ++int wmt_detect_sdio_pwr_ctrl(int on) ++{ ++ int retval = -1; ++#ifdef MTK_WCN_COMBO_CHIP_SUPPORT ++ if (0 == on) { ++ /*power off SDIO slot */ ++ retval = board_sdio_ctrl(1, 0); ++ } else { ++ /*power on SDIO slot */ ++ retval = board_sdio_ctrl(1, 1); ++ } ++#else ++ WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n"); ++#endif ++ return retval; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h +new file mode 100644 +index 000000000000..32e661520fd0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h +@@ -0,0 +1,29 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef __WMT_DETECT_PWR_H_ ++#define __WMT_DETECT_PWR_H_ ++ ++#define MAX_RTC_STABLE_TIME 100 ++#define MAX_LDO_STABLE_TIME 100 ++#define MAX_RST_STABLE_TIME 30 ++#define MAX_OFF_STABLE_TIME 10 ++#define MAX_ON_STABLE_TIME 30 ++ ++extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); ++extern int wmt_detect_chip_pwr_ctrl(int on); ++extern int wmt_detect_sdio_pwr_ctrl(int on); ++extern int wmt_detect_read_ext_cmb_status(void); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c +new file mode 100644 +index 000000000000..3a79e1e9d15a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c +@@ -0,0 +1,371 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include "wmt_gpio.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX] = {{"gpio_ldo_en_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_ldo_en_in_pulldown", ++ ""}, ++ {"gpio_pmuv28_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_pmuv28_in_pulldown", ++ ""}, ++ {"gpio_pmu_en_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_pmu_en_in_pulldown", ++ ""}, ++ {"gpio_rst_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_bgf_eint_in_pulldown", ++ "gpio_bgf_eint_in_pullup"}, ++ {"", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_wifi_eint_in_pull_dis", ++ "", ++ "gpio_wifi_eint_in_pullup"}, ++ {"", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_all_eint_in_pulldown", ++ "gpio_all_eint_in_pullup"}, ++ {"gpio_urxd_uart_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "gpio_urxd_gpio_in_pull_dis", ++ "", ++ "gpio_urxd_gpio_in_pullup"}, ++ {"gpio_utxd_uart_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daiclk_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daipcmin_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daipcmout_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_pcm_daisync_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_i2s_ck_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_i2s_ws_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_i2s_dat_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_gps_sync_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""}, ++ {"gpio_gps_lna_pull_dis", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ ""} ++}; ++ ++const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX] = {"gpio_combo_ldo_en_pin", ++ "gpio_combo_pmuv28_en_pin", ++ "gpio_combo_pmu_en_pin", ++ "gpio_combo_rst_pin", ++ "gpio_combo_bgf_eint_pin", ++ "gpio_wifi_eint_pin", ++ "gpio_all_eint_pin", ++ "gpio_combo_urxd_pin", ++ "gpio_combo_utxd_pin", ++ "gpio_pcm_daiclk_pin", ++ "gpio_pcm_daipcmin_pin", ++ "gpio_pcm_daipcmout_pin", ++ "gpio_pcm_daisync_pin", ++ "gpio_combo_i2s_ck_pin", ++ "gpio_combo_i2s_ws_pin", ++ "gpio_combo_i2s_dat_pin", ++ "gpio_gps_sync_pin", ++ "gpio_gps_lna_pin"}; ++ ++GPIO_CTRL_INFO gpio_ctrl_info; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_gpio_init(struct platform_device *pdev) ++{ ++ INT32 iret = 0; ++ UINT32 i, j; ++ struct device_node *node; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); ++ if (!node) { ++ for (i = 0; i < GPIO_PIN_ID_MAX; i++) ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; ++ pr_err("wmt_gpio:can't find device tree node!\n"); ++ iret = -1; ++ goto err; ++ } ++ ++ gpio_ctrl_info.pinctrl_info = devm_pinctrl_get(&pdev->dev); ++ if (gpio_ctrl_info.pinctrl_info) { ++ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = of_get_named_gpio(node, ++ gpio_pin_name[i], 0); ++ if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num < 0) ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { ++ for (j = 0; j < GPIO_STATE_MAX; j++) { ++ if (0 != strlen(gpio_state_name[i][j])) { ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = ++ pinctrl_lookup_state(gpio_ctrl_info.pinctrl_info, ++ gpio_state_name[i][j]); ++ } else ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; ++ } ++ } ++ } ++ ++ pr_err("wmt_gpio: gpio init start!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, ++ 0); ++ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN out to 0: %d!\n", ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); ++ } ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) { ++ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, ++ 0); ++ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN out to 0: %d!\n", ++ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); ++ } ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); ++ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]) { ++ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, ++ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN]. ++ gpio_state[GPIO_PULL_DIS]); ++ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS done!\n"); ++ } else ++ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS fail, is NULL!\n"); ++ ++ pr_err("wmt_gpio: gpio init done!\n"); ++ } else { ++ pr_err("wmt_gpio:can't find pinctrl dev!\n"); ++ iret = -1; ++ } ++err: ++ return iret; ++} ++ ++INT32 wmt_gpio_deinit(VOID) ++{ ++ INT32 iret = 0; ++ UINT32 i; ++ UINT32 j; ++ ++ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; ++ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { ++ for (j = 0; j < GPIO_STATE_MAX; j++) { ++ if (0 != strlen(gpio_state_name[i][j])) ++ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; ++ } ++ } ++ } ++ if (gpio_ctrl_info.pinctrl_info) { ++ devm_pinctrl_put(gpio_ctrl_info.pinctrl_info); ++ gpio_ctrl_info.pinctrl_info = NULL; ++ } ++ ++ return iret; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h +new file mode 100644 +index 000000000000..cd935bfddd99 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h +@@ -0,0 +1,103 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_GPIO_H_ ++#define _WMT_GPIO_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "osal.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define DEFAULT_PIN_ID (0xffffffff) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_GPIO_PIN_ID { ++ GPIO_COMBO_LDO_EN_PIN = 0, ++ GPIO_COMBO_PMUV28_EN_PIN, ++ GPIO_COMBO_PMU_EN_PIN, ++ GPIO_COMBO_RST_PIN, ++ GPIO_COMBO_BGF_EINT_PIN, ++ GPIO_WIFI_EINT_PIN, ++ GPIO_COMBO_ALL_EINT_PIN, ++ GPIO_COMBO_URXD_PIN, ++ GPIO_COMBO_UTXD_PIN, ++ GPIO_PCM_DAICLK_PIN, ++ GPIO_PCM_DAIPCMIN_PIN, ++ GPIO_PCM_DAIPCMOUT_PIN, ++ GPIO_PCM_DAISYNC_PIN, ++ GPIO_COMBO_I2S_CK_PIN, ++ GPIO_COMBO_I2S_WS_PIN, ++ GPIO_COMBO_I2S_DAT_PIN, ++ GPIO_GPS_SYNC_PIN, ++ GPIO_GPS_LNA_PIN, ++ GPIO_PIN_ID_MAX ++} ENUM_GPIO_PIN_ID, *P_ENUM_GPIO_PIN_ID; ++ ++typedef enum _ENUM_GPIO_STATE_ID { ++ GPIO_PULL_DIS = 0, ++ GPIO_PULL_DOWN, ++ GPIO_PULL_UP, ++ GPIO_OUT_LOW, ++ GPIO_OUT_HIGH, ++ GPIO_IN_DIS, ++ GPIO_IN_EN, ++ GPIO_IN_PULL_DIS, ++ GPIO_IN_PULLDOWN, ++ GPIO_IN_PULLUP, ++ GPIO_STATE_MAX, ++} ENUM_GPIO_STATE_ID, *P_ENUM_GPIO_STATE_ID; ++ ++typedef struct _GPIO_CTRL_STATE { ++ INT32 gpio_num; ++ struct pinctrl_state *gpio_state[GPIO_STATE_MAX]; ++} GPIO_CTRL_STATE, *P_GPIO_CTRL_STATE; ++ ++typedef struct _GPIO_CTRL_INFO { ++ struct pinctrl *pinctrl_info; ++ GPIO_CTRL_STATE gpio_ctrl_state[GPIO_PIN_ID_MAX]; ++} GPIO_CTRL_INFO, *P_GPIO_CTRL_INFO; ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX]; ++extern const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX]; ++extern GPIO_CTRL_INFO gpio_ctrl_info; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_gpio_init(struct platform_device *pdev); ++ ++INT32 wmt_gpio_deinit(VOID); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c +new file mode 100644 +index 000000000000..4fc3144b3ba6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c +@@ -0,0 +1,480 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include "osal_typedef.h" ++#include "wmt_stp_exp.h" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-STP-EXP]" ++ ++#define WMT_STP_EXP_INFO_FUNC(fmt, arg...) pr_debug(DFT_TAG "[I]%s: " fmt, __func__ , ##arg) ++#define WMT_STP_EXP_WARN_FUNC(fmt, arg...) pr_warn(DFT_TAG "[W]%s: " fmt, __func__ , ##arg) ++#define WMT_STP_EXP_ERR_FUNC(fmt, arg...) pr_err(DFT_TAG "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++/*STP exp*/ ++MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_f = NULL; ++MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_raw_f = NULL; ++MTK_WCN_STP_PARSER_DATA mtk_wcn_stp_parser_data_f = NULL; ++MTK_WCN_STP_RECV_DATA mtk_wcn_stp_receive_data_f = NULL; ++MTK_WCN_STP_IS_RXQ_EMPTY mtk_wcn_stp_is_rxqueue_empty_f = NULL; ++MTK_WCN_STP_IS_RDY mtk_wcn_stp_is_ready_f = NULL; ++MTK_WCN_STP_SET_BLUEZ mtk_wcn_stp_set_bluez_f = NULL; ++MTK_WCN_STP_REG_IF_TX mtk_wcn_stp_if_tx_f = NULL; ++MTK_WCN_STP_REG_IF_RX mtk_wcn_stp_if_rx_f = NULL; ++MTK_WCN_STP_REG_EVENT_CB mtk_wcn_stp_reg_event_cb_f = NULL; ++MTK_WCN_STP_RGE_TX_EVENT_CB mtk_wcn_stp_reg_tx_event_cb_f = NULL; ++MTK_WCN_STP_COREDUMP_START_GET mtk_wcn_stp_coredump_start_get_f = NULL; ++ ++/*WMT exp*/ ++MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_on_f = NULL; ++MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_off_f = NULL; ++MTK_WCN_WMT_THERM_CTRL mtk_wcn_wmt_therm_ctrl_f = NULL; ++MTK_WCN_WMT_HWVER_GET mtk_wcn_wmt_hwver_get_f = NULL; ++MTK_WCN_WMT_DSNS_CTRL mtk_wcn_wmt_dsns_ctrl_f = NULL; ++MTK_WCN_WMT_MSGCB_REG mtk_wcn_wmt_msgcb_reg_f = NULL; ++MTK_WCN_WMT_MSGCB_UNREG mtk_wcn_wmt_msgcb_unreg_f = NULL; ++MTK_WCN_WMT_SDIO_OP_REG mtk_wcn_wmt_sdio_op_reg_f = NULL; ++MTK_WCN_WMT_SDIO_HOST_AWAKE mtk_wcn_wmt_sdio_host_awake_f = NULL; ++MTK_WCN_WMT_ASSERT mtk_wcn_wmt_assert_f = NULL; ++MTK_WCN_WMT_ASSERT_TIMEOUT mtk_wcn_wmt_assert_timeout_f = NULL; ++MTK_WCN_WMT_IC_INFO_GET mtk_wcn_wmt_ic_info_get_f = NULL; ++MTK_WCN_WMT_PSM_CTRL mtk_wcn_wmt_psm_ctrl_f = NULL; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb) ++{ ++ WMT_STP_EXP_INFO_FUNC("call stp exp cb reg\n"); ++ ++ mtk_wcn_stp_send_data_f = pStpExpCb->stp_send_data_cb; ++ mtk_wcn_stp_send_data_raw_f = pStpExpCb->stp_send_data_raw_cb; ++ mtk_wcn_stp_parser_data_f = pStpExpCb->stp_parser_data_cb; ++ mtk_wcn_stp_receive_data_f = pStpExpCb->stp_receive_data_cb; ++ mtk_wcn_stp_is_rxqueue_empty_f = pStpExpCb->stp_is_rxqueue_empty_cb; ++ mtk_wcn_stp_is_ready_f = pStpExpCb->stp_is_ready_cb; ++ mtk_wcn_stp_set_bluez_f = pStpExpCb->stp_set_bluez_cb; ++ mtk_wcn_stp_if_tx_f = pStpExpCb->stp_if_tx_cb; ++ mtk_wcn_stp_if_rx_f = pStpExpCb->stp_if_rx_cb; ++ mtk_wcn_stp_reg_event_cb_f = pStpExpCb->stp_reg_event_cb; ++ mtk_wcn_stp_reg_tx_event_cb_f = pStpExpCb->stp_reg_tx_event_cb; ++ mtk_wcn_stp_coredump_start_get_f = pStpExpCb->stp_coredump_start_get_cb; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_reg); ++ ++UINT32 mtk_wcn_stp_exp_cb_unreg(VOID) ++{ ++ WMT_STP_EXP_INFO_FUNC("call stp exp cb unreg\n"); ++ ++ mtk_wcn_stp_send_data_f = NULL; ++ mtk_wcn_stp_send_data_raw_f = NULL; ++ mtk_wcn_stp_parser_data_f = NULL; ++ mtk_wcn_stp_receive_data_f = NULL; ++ mtk_wcn_stp_is_rxqueue_empty_f = NULL; ++ mtk_wcn_stp_is_ready_f = NULL; ++ mtk_wcn_stp_set_bluez_f = NULL; ++ mtk_wcn_stp_if_tx_f = NULL; ++ mtk_wcn_stp_if_rx_f = NULL; ++ mtk_wcn_stp_reg_event_cb_f = NULL; ++ mtk_wcn_stp_reg_tx_event_cb_f = NULL; ++ mtk_wcn_stp_coredump_start_get_f = NULL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_unreg); ++ ++INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_send_data_f) { ++ ret = (*mtk_wcn_stp_send_data_f) (buffer, length, type); ++ /* WMT_STP_EXP_INFO_FUNC("mtk_wcn_stp_send_data_f send data(%d)\n",ret); */ ++ } else { ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_f cb is null\n"); ++ } ++ ++ return ret; ++ ++} ++EXPORT_SYMBOL(mtk_wcn_stp_send_data); ++ ++INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_send_data_raw_f) ++ ret = (*mtk_wcn_stp_send_data_raw_f) (buffer, length, type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_raw_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); ++ ++INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_parser_data_f) ++ ret = (*mtk_wcn_stp_parser_data_f) (buffer, length); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_parser_data_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_parser_data); ++ ++INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_receive_data_f) ++ ret = (*mtk_wcn_stp_receive_data_f) (buffer, length, type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_receive_data_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_receive_data); ++ ++MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_stp_is_rxqueue_empty_f) ++ ret = (*mtk_wcn_stp_is_rxqueue_empty_f) (type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_rxqueue_empty_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); ++ ++MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_stp_is_ready_f) ++ ret = (*mtk_wcn_stp_is_ready_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_ready_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_is_ready); ++ ++void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags) ++{ ++ ++ if (mtk_wcn_stp_set_bluez_f) ++ (*mtk_wcn_stp_set_bluez_f) (flags); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_set_bluez_f cb is null\n"); ++ ++} ++EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); ++ ++INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_if_tx_f) ++ ret = (*mtk_wcn_stp_if_tx_f) (stp_if, func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_tx_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); ++ ++INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_if_rx_f) ++ ret = (*mtk_wcn_stp_if_rx_f) (func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_rx_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); ++ ++INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_reg_event_cb_f) ++ ret = (*mtk_wcn_stp_reg_event_cb_f) (type, func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_event_cb_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); ++ ++INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_reg_tx_event_cb_f) ++ ret = (*mtk_wcn_stp_reg_tx_event_cb_f) (type, func); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_tx_event_cb_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); ++ ++INT32 mtk_wcn_stp_coredump_start_get(VOID) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_coredump_start_get_f) ++ ret = (*mtk_wcn_stp_coredump_start_get_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_coredump_start_get_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_coredump_start_get); ++ ++UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb) ++{ ++ WMT_STP_EXP_INFO_FUNC("call wmt exp cb reg\n"); ++ ++ mtk_wcn_wmt_func_on_f = pWmtExpCb->wmt_func_on_cb; ++ mtk_wcn_wmt_func_off_f = pWmtExpCb->wmt_func_off_cb; ++ mtk_wcn_wmt_therm_ctrl_f = pWmtExpCb->wmt_therm_ctrl_cb; ++ mtk_wcn_wmt_hwver_get_f = pWmtExpCb->wmt_hwver_get_cb; ++ mtk_wcn_wmt_dsns_ctrl_f = pWmtExpCb->wmt_dsns_ctrl_cb; ++ mtk_wcn_wmt_msgcb_reg_f = pWmtExpCb->wmt_msgcb_reg_cb; ++ mtk_wcn_wmt_msgcb_unreg_f = pWmtExpCb->wmt_msgcb_unreg_cb; ++ mtk_wcn_wmt_sdio_op_reg_f = pWmtExpCb->wmt_sdio_op_reg_cb; ++ mtk_wcn_wmt_sdio_host_awake_f = pWmtExpCb->wmt_sdio_host_awake_cb; ++ mtk_wcn_wmt_assert_f = pWmtExpCb->wmt_assert_cb; ++ mtk_wcn_wmt_assert_timeout_f = pWmtExpCb->wmt_assert_timeout_cb; ++ mtk_wcn_wmt_ic_info_get_f = pWmtExpCb->wmt_ic_info_get_cb; ++ mtk_wcn_wmt_psm_ctrl_f = pWmtExpCb->wmt_psm_ctrl_cb; ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_reg); ++ ++UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID) ++{ ++ WMT_STP_EXP_INFO_FUNC("call wmt exp cb unreg\n"); ++ ++ mtk_wcn_wmt_func_on_f = NULL; ++ mtk_wcn_wmt_func_off_f = NULL; ++ mtk_wcn_wmt_therm_ctrl_f = NULL; ++ mtk_wcn_wmt_hwver_get_f = NULL; ++ mtk_wcn_wmt_dsns_ctrl_f = NULL; ++ mtk_wcn_wmt_msgcb_reg_f = NULL; ++ mtk_wcn_wmt_msgcb_unreg_f = NULL; ++ mtk_wcn_wmt_sdio_op_reg_f = NULL; ++ mtk_wcn_wmt_sdio_host_awake_f = NULL; ++ mtk_wcn_wmt_assert_f = NULL; ++ mtk_wcn_wmt_assert_timeout_f = NULL; ++ mtk_wcn_wmt_ic_info_get_f = NULL; ++ mtk_wcn_wmt_psm_ctrl_f = NULL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_unreg); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_func_off_f) ++ ret = (*mtk_wcn_wmt_func_off_f) (type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_off_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_func_off); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_func_on_f) { ++ ret = (*mtk_wcn_wmt_func_on_f) (type); ++ WMT_STP_EXP_INFO_FUNC("mtk_wcn_wmt_func_on_f type(%d)\n", type); ++ } else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_on_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_func_on); ++ ++INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_wmt_therm_ctrl_f) ++ ret = (*mtk_wcn_wmt_therm_ctrl_f) (eType); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_therm_ctrl_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); ++ ++ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) ++{ ++ ENUM_WMTHWVER_TYPE_T ret = WMTHWVER_INVALID; ++ ++ if (mtk_wcn_wmt_hwver_get_f) ++ ret = (*mtk_wcn_wmt_hwver_get_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_hwver_get_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_dsns_ctrl_f) ++ ret = (*mtk_wcn_wmt_dsns_ctrl_f) (eType); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_dsns_ctrl_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); ++ ++INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++{ ++ INT32 ret = 0; ++ ++ if (mtk_wcn_wmt_msgcb_reg_f) ++ ret = (*mtk_wcn_wmt_msgcb_reg_f) (eType, pCb); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_reg_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); ++ ++INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++{ ++ INT32 ret = 0; ++ ++ if (mtk_wcn_wmt_msgcb_unreg_f) ++ ret = (*mtk_wcn_wmt_msgcb_unreg_f) (eType); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_unreg_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); ++ ++INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_wmt_sdio_op_reg_f) ++ ret = (*mtk_wcn_wmt_sdio_op_reg_f) (own_cb); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_op_reg_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); ++ ++INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_wmt_sdio_host_awake_f) ++ ret = (*mtk_wcn_wmt_sdio_host_awake_f) (); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_host_awake_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_assert_f) ++ ret = (*mtk_wcn_wmt_assert_f) (type, reason); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_assert); ++ ++MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout) ++{ ++ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_wcn_wmt_assert_timeout_f) ++ ret = (*mtk_wcn_wmt_assert_timeout_f)(type, reason, timeout); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_timeout_f cb is null\n"); ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_assert_timeout); ++ ++UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type) ++{ ++ UINT32 ret = 0; ++ ++ if (mtk_wcn_wmt_ic_info_get_f) ++ ret = (*mtk_wcn_wmt_ic_info_get_f) (type); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_ic_info_get_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_ic_info_get); ++ ++INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag) ++{ ++ UINT32 ret = 0; ++ ++ if (mtk_wcn_wmt_psm_ctrl_f) ++ ret = (*mtk_wcn_wmt_psm_ctrl_f)(flag); ++ else ++ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_psm_ctrl_f cb is null\n"); ++ ++ return ret; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_psm_ctrl); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h +new file mode 100644 +index 000000000000..1c3dc8965298 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h +@@ -0,0 +1,610 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_STP_EXP_H_ ++#define _WMT_STP_EXP_H_ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "osal_typedef.h" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 ++#endif ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++#if (WMT_IDC_SUPPORT) ++#define CFG_WMT_LTE_COEX_HANDLING 1 ++#define CFG_WMT_LTE_ENABLE_MSGID_MAPPING 0 ++#else ++#define CFG_WMT_LTE_COEX_HANDLING 0 ++#endif ++ ++/*from stp_exp.h*/ ++#define BT_TASK_INDX (0) ++#define FM_TASK_INDX (1) ++#define GPS_TASK_INDX (2) ++#define WIFI_TASK_INDX (3) ++#define WMT_TASK_INDX (4) ++#define STP_TASK_INDX (5) ++#define INFO_TASK_INDX (6) ++#define ANT_TASK_INDX (7) ++#if CFG_WMT_LTE_COEX_HANDLING ++#define COEX_TASK_INDX (8) ++#define MTKSTP_MAX_TASK_NUM (9) ++#else ++#define MTKSTP_MAX_TASK_NUM (8) ++#endif ++ ++#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ ++/*end from stp_exp.h*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++********************************************************************************/ ++ ++/*moved from stp_exp.h*/ ++typedef void (*MTK_WCN_STP_EVENT_CB) (void); ++typedef INT32(*MTK_WCN_STP_IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); ++/* export for HIF driver */ ++typedef void (*MTK_WCN_STP_IF_RX) (const PUINT8 data, INT32 size); ++ ++typedef enum { ++ STP_UART_IF_TX = 0, ++ STP_SDIO_IF_TX = 1, ++ STP_BTIF_IF_TX = 2, ++ STP_MAX_IF_TX ++} ENUM_STP_TX_IF_TYPE; ++ ++/*end moved from stp_exp.h*/ ++ ++typedef INT32(*MTK_WCN_STP_SEND_DATA) (const PUINT8 buffer, const UINT32 length, const UINT8 type); ++typedef INT32(*MTK_WCN_STP_PARSER_DATA) (PUINT8 buffer, UINT32 length); ++typedef INT32(*MTK_WCN_STP_RECV_DATA) (PUINT8 buffer, UINT32 length, UINT8 type); ++typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RXQ_EMPTY) (UINT8 type); ++typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RDY) (VOID); ++typedef VOID(*MTK_WCN_STP_SET_BLUEZ) (MTK_WCN_BOOL flags); ++typedef INT32(*MTK_WCN_STP_REG_IF_TX) (ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++typedef INT32(*MTK_WCN_STP_REG_IF_RX) (MTK_WCN_STP_IF_RX func); ++typedef INT32(*MTK_WCN_STP_REG_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); ++typedef INT32(*MTK_WCN_STP_RGE_TX_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); ++typedef INT32(*MTK_WCN_STP_COREDUMP_START_GET)(VOID); ++ ++typedef struct _MTK_WCN_STP_EXP_CB_INFO_ { ++ MTK_WCN_STP_SEND_DATA stp_send_data_cb; ++ MTK_WCN_STP_SEND_DATA stp_send_data_raw_cb; ++ MTK_WCN_STP_PARSER_DATA stp_parser_data_cb; ++ MTK_WCN_STP_RECV_DATA stp_receive_data_cb; ++ MTK_WCN_STP_IS_RXQ_EMPTY stp_is_rxqueue_empty_cb; ++ MTK_WCN_STP_IS_RDY stp_is_ready_cb; ++ MTK_WCN_STP_SET_BLUEZ stp_set_bluez_cb; ++ MTK_WCN_STP_REG_IF_TX stp_if_tx_cb; ++ MTK_WCN_STP_REG_IF_RX stp_if_rx_cb; ++ MTK_WCN_STP_REG_EVENT_CB stp_reg_event_cb; ++ MTK_WCN_STP_RGE_TX_EVENT_CB stp_reg_tx_event_cb; ++ MTK_WCN_STP_COREDUMP_START_GET stp_coredump_start_get_cb; ++} MTK_WCN_STP_EXP_CB_INFO, *P_MTK_WCN_STP_EXP_CB_INFO; ++ ++/*moved from wmt_exp.h*/ ++ ++typedef enum _ENUM_WMTDRV_TYPE_T { ++ WMTDRV_TYPE_BT = 0, ++ WMTDRV_TYPE_FM = 1, ++ WMTDRV_TYPE_GPS = 2, ++ WMTDRV_TYPE_WIFI = 3, ++ WMTDRV_TYPE_WMT = 4, ++ WMTDRV_TYPE_ANT = 5, ++ WMTDRV_TYPE_STP = 6, ++ WMTDRV_TYPE_SDIO1 = 7, ++ WMTDRV_TYPE_SDIO2 = 8, ++ WMTDRV_TYPE_LPBK = 9, ++ WMTDRV_TYPE_COREDUMP = 10, ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ WMTDRV_TYPE_AUTOK = 11, ++#endif ++ WMTDRV_TYPE_MAX ++} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; ++ ++typedef enum _ENUM_WMTDSNS_TYPE_T { ++ WMTDSNS_FM_DISABLE = 0, ++ WMTDSNS_FM_ENABLE = 1, ++ WMTDSNS_FM_GPS_DISABLE = 2, ++ WMTDSNS_FM_GPS_ENABLE = 3, ++ WMTDSNS_MAX ++} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; ++ ++typedef enum _ENUM_WMTHWVER_TYPE_T { ++ WMTHWVER_E1 = 0x0, ++ WMTHWVER_E2 = 0x1, ++ WMTHWVER_E3 = 0x2, ++ WMTHWVER_E4 = 0x3, ++ WMTHWVER_E5 = 0x4, ++ WMTHWVER_E6 = 0x5, ++ WMTHWVER_E7 = 0x6, ++ WMTHWVER_MAX, ++ WMTHWVER_INVALID = 0xff ++} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; ++ ++typedef enum _ENUM_WMTTHERM_TYPE_T { ++ WMTTHERM_ZERO = 0, ++ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, ++ WMTTHERM_READ = WMTTHERM_ENABLE + 1, ++ WMTTHERM_DISABLE = WMTTHERM_READ + 1, ++ WMTTHERM_MAX ++} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; ++ ++typedef enum _ENUM_WMTMSG_TYPE_T { ++ WMTMSG_TYPE_POWER_ON = 0, ++ WMTMSG_TYPE_POWER_OFF = 1, ++ WMTMSG_TYPE_RESET = 2, ++ WMTMSG_TYPE_STP_RDY = 3, ++ WMTMSG_TYPE_HW_FUNC_ON = 4, ++ WMTMSG_TYPE_MAX ++} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; ++ ++typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ ++ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ ++ ENUM_WMTMSG_TYPE_T, /* Message type */ ++ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client ++ can't touch this buffer after this function return. */ ++ UINT32 /* Buffer size in unit of byte */ ++); ++ ++typedef enum _SDIO_PS_OP { ++ OWN_SET = 0, ++ OWN_CLR = 1, ++ OWN_STATE = 2, ++} SDIO_PS_OP; ++ ++typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); ++ ++typedef enum _ENUM_WMTCHIN_TYPE_T { ++ WMTCHIN_CHIPID = 0x0, ++ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, ++ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, ++ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, ++ WMTCHIN_MAX, ++ ++} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; ++ ++/*end moved from wmt_exp.h*/ ++ ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_FUNC_CTRL) (ENUM_WMTDRV_TYPE_T type); ++typedef INT8(*MTK_WCN_WMT_THERM_CTRL) (ENUM_WMTTHERM_TYPE_T eType); ++typedef ENUM_WMTHWVER_TYPE_T(*MTK_WCN_WMT_HWVER_GET) (VOID); ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_DSNS_CTRL) (ENUM_WMTDSNS_TYPE_T eType); ++typedef INT32(*MTK_WCN_WMT_MSGCB_REG) (ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++typedef INT32(*MTK_WCN_WMT_MSGCB_UNREG) (ENUM_WMTDRV_TYPE_T eType); ++typedef INT32(*MTK_WCN_WMT_SDIO_OP_REG) (PF_WMT_SDIO_PSOP own_cb); ++typedef INT32(*MTK_WCN_WMT_SDIO_HOST_AWAKE) (VOID); ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT) (ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT_TIMEOUT)(ENUM_WMTDRV_TYPE_T type, ++ UINT32 reason, INT32 timeout); ++typedef UINT32(*MTK_WCN_WMT_IC_INFO_GET) (ENUM_WMT_CHIPINFO_TYPE_T type); ++typedef INT32 (*MTK_WCN_WMT_PSM_CTRL)(MTK_WCN_BOOL flag); ++ ++typedef struct _MTK_WCN_WMT_EXP_CB_INFO_ { ++ MTK_WCN_WMT_FUNC_CTRL wmt_func_on_cb; ++ MTK_WCN_WMT_FUNC_CTRL wmt_func_off_cb; ++ MTK_WCN_WMT_THERM_CTRL wmt_therm_ctrl_cb; ++ MTK_WCN_WMT_HWVER_GET wmt_hwver_get_cb; ++ MTK_WCN_WMT_DSNS_CTRL wmt_dsns_ctrl_cb; ++ MTK_WCN_WMT_MSGCB_REG wmt_msgcb_reg_cb; ++ MTK_WCN_WMT_MSGCB_UNREG wmt_msgcb_unreg_cb; ++ MTK_WCN_WMT_SDIO_OP_REG wmt_sdio_op_reg_cb; ++ MTK_WCN_WMT_SDIO_HOST_AWAKE wmt_sdio_host_awake_cb; ++ MTK_WCN_WMT_ASSERT wmt_assert_cb; ++ MTK_WCN_WMT_ASSERT_TIMEOUT wmt_assert_timeout_cb; ++ MTK_WCN_WMT_IC_INFO_GET wmt_ic_info_get_cb; ++ MTK_WCN_WMT_PSM_CTRL wmt_psm_ctrl_cb; ++} MTK_WCN_WMT_EXP_CB_INFO, *P_MTK_WCN_WMT_EXP_CB_INFO; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*exp for WMT/STP register callback*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_exp_cb_reg ++* DESCRIPTION ++* stp driver reigster exp symbols ++* PARAMETERS ++* pStpExpCb [IN] stp callback structure pointer ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_exp_cb_unreg ++* DESCRIPTION ++* stp driver unreigster exp symbols ++* PARAMETERS ++* VOID ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_stp_exp_cb_unreg(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_exp_cb_reg ++* DESCRIPTION ++* WMT driver reigster exp symbols ++* PARAMETERS ++* pStpExpCb [IN] wmt callback structure pointer ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_exp_cb_unreg ++* DESCRIPTION ++* wmt driver unreigster exp symbols ++* PARAMETERS ++* VOID ++* RETURNS ++* UINT32 = 0: OK ++*****************************************************************************/ ++UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID); ++ ++/*stp exp symbols*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data ++* DESCRIPTION ++* subfunction send data through STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data_raw ++* DESCRIPTION ++* subfunction send data through STP without seq/ack ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_parser_data ++* DESCRIPTION ++* push data to serial transport protocol parser engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_receive_data ++* DESCRIPTION ++* receive data from serial protocol engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* INT32 >= 0: size of data received; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_rxqueue_empty ++* DESCRIPTION ++* Is certain rx queue empty? ++* PARAMETERS ++* type [IN] subfunction type ++* RETURNS ++* INT32 0: queue is NOT empyt; !0: queue is empty ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_enable ++* DESCRIPTION ++* Is STP ready? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:ready, FALSE:not ready ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); ++ ++/***************************************************************************** ++* FUNCTION ++* set_bluetooth_rx_interface ++* DESCRIPTION ++* Set bluetooth rx interface ++* PARAMETERS ++* rx interface type ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_tx ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_rx ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_event_cb ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_tx_event_cb ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* INT32: 0:successful , -1: fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_get ++* DESCRIPTION ++* get coredump flag is set or not ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32: 0:coredump flag is not set , 1: coredump flag is set ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_coredump_start_get(VOID); ++ ++/*wmt exp symbols*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_func_off ++* DESCRIPTION ++* wmt turn off subsystem ++* PARAMETERS ++* type [IN] subsystem type ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_func_on ++* DESCRIPTION ++* wmt turn on subsystem ++* PARAMETERS ++* type [IN] subsystem type ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_therm_ctrl ++* DESCRIPTION ++* query chip temperature by WMT CMD ++* PARAMETERS ++* eType [IN] thermal ctrl type ++* RETURNS ++* >=0: chip temperature; 0xff:error ++*****************************************************************************/ ++extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_hwver_get ++* DESCRIPTION ++* get chip hardware version ++* PARAMETERS ++* VOID ++* RETURNS ++* >=0: chip hw version; 0xff:error ++*****************************************************************************/ ++extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_ic_info_get ++* DESCRIPTION ++* get chip hardware version or f/w version ++* PARAMETERS ++* type : which kind of information is needed ++* RETURNS ++* f/w version or hw version information ++*****************************************************************************/ ++extern UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_dsns_ctrl ++* DESCRIPTION ++* fm dsns cmd ctrl ++* PARAMETERS ++* eType [IN] fm dsns ctrl type ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_msgcb_reg ++* DESCRIPTION ++* used for subsystem register chip reset callback for received wmt reset msg. ++* PARAMETERS ++* eType [IN] subsystem type ++* pCb [IN] rst callback ++* RETURNS ++* 1: OK; 0:error ++*****************************************************************************/ ++extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_msgcb_unreg ++* DESCRIPTION ++* used for subsystem unregister chip reset callback for received wmt reset msg. ++* PARAMETERS ++* eType [IN] subsystem type ++* RETURNS ++* 1: OK; 0:error ++*****************************************************************************/ ++extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_wmt_sdio_op_reg ++* DESCRIPTION ++* used to register callback for set sdio ownership. ++* PARAMETERS ++* own_cb [IN] set owner ship callback ++* RETURNS ++* always return 0; ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_wmt_sdio_host_awake ++* DESCRIPTION ++* handing host awake when link is stp sdio? ++* PARAMETERS ++* VOID ++* RETURNS ++* always return 0; ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_assert ++* DESCRIPTION ++* host trigger firmware assert ++* PARAMETERS ++* type [IN] subsystem driver type ++* reason [IN] trigger assert reason ++* RETURNS ++* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++ ++/***************************************************************************** ++ * * FUNCTION ++ * * mtk_wcn_wmt_assert_timeout ++ * * DESCRIPTION ++ * * host trigger firmware assert ++ * * PARAMETERS ++ * * type [IN] subsystem driver type ++ * * reason [IN] trigger assert reason ++ * * timeout [IN] trigger assert timeout data ++ * * RETURNS ++ * * MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error ++ * *****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, ++ UINT32 reason, INT32 timeout); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmt_psm_ctrl ++* DESCRIPTION ++* disable/enable psm ++* PARAMETERS ++* flag [IN] disable:0, enable:1 ++* RETURNS ++* always return 0; ++*****************************************************************************/ ++extern INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag); ++ ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile +new file mode 100644 +index 000000000000..286bfd4bfed3 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile +@@ -0,0 +1,65 @@ ++subdir-ccflags-y += \ ++ -I$(src)/linux/include \ ++ -I$(src)/linux/pri/include \ ++ -I$(src)/core/include \ ++ -I$(src)/include \ ++ -I$(src)/../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/btif/common/inc ++ ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/ ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM) ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs/ ++subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/conn_md/include ++ ++EXT_FLAG=_soc ++COMMON_SRC_PATH := $(src) ++COMMON_OBJ_PATH := $(src) ++ ++ifeq ($(CONFIG_ARCH_MT6580), y) ++subdir-ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33 ++endif ++ ++ifeq ($(CONFIG_MTK_COMBO), m) ++# WMT DRIVER ++obj-$(CONFIG_MTK_COMBO) += mtk_stp_wmt$(EXT_FLAG).o ++# WMT DRIVER-core part ++mtk_stp_wmt$(EXT_FLAG)-objs := core/wmt_core.o core/wmt_ctrl.o core/wmt_func.o core/wmt_ic_soc.o core/wmt_lib.o core/wmt_conf.o ++ ++ ++# WMT DRIVER-linux private part ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/wmt_dev.o linux/pri/wmt_exp.o ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_btif.o ++ ++ ++# WMT DRIVER-OSAL ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pub/osal.o linux/pub/bgw_desense.o ++# WMT DRIVER-platform implementation ++# ccflags-y += -D WMT_PLAT_ALPS ++# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/wmt_plat_alps.o ++ ++# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/mtk_wcn_consys_hw.o ++ ++ ++mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_exp.o core/stp_core.o core/psm_core.o core/btm_core.o linux/pri/stp_dbg.o ++ ++# WMT stub part (built-in kernel image) ++# obj-y += platform/alps/mtk_wcn_consys_stub_alps.o ++ ++ ++ ++obj-$(CONFIG_MTK_COMBO_BT) += mtk_stp_bt$(EXT_FLAG).o ++mtk_stp_bt$(EXT_FLAG)-objs := linux/pub/stp_chrdev_bt.o ++ ++ ++obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi$(EXT_FLAG).o ++mtk_wmt_wifi$(EXT_FLAG)-objs := linux/pub/wmt_chrdev_wifi.o ++ ++endif ++ ++ifeq ($(CONFIG_MTK_COMBO), y) ++# subdir-ccflags-y += -D WMT_PLAT_ALPS ++obj-y += core/ ++obj-y += linux/ ++#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/ ++obj-y += mt7623/ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile +new file mode 100644 +index 000000000000..9df71b9e163e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile +@@ -0,0 +1,22 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++ccflags-y += \ ++ -I$(src)/../linux/include \ ++ -I$(src)/../linux/pri/include \ ++ -I$(src)/../core/include \ ++ -I$(src)/../include \ ++ -I$(src)/../../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ ++ ++obj-y += wmt_core.o \ ++ wmt_ctrl.o \ ++ wmt_func.o \ ++ wmt_ic_soc.o \ ++ wmt_lib.o \ ++ wmt_conf.o \ ++ btm_core.o \ ++ dbg_core.o \ ++ psm_core.o \ ++ stp_core.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c +new file mode 100644 +index 000000000000..4946b682d826 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c +@@ -0,0 +1,1376 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_dbg.h" ++#include "stp_core.h" ++#include "btm_core.h" ++#include "wmt_plat.h" ++ ++#define PFX_BTM "[STP-BTM] " ++#define STP_BTM_LOG_LOUD 4 ++#define STP_BTM_LOG_DBG 3 ++#define STP_BTM_LOG_INFO 2 ++#define STP_BTM_LOG_WARN 1 ++#define STP_BTM_LOG_ERR 0 ++ ++INT32 gBtmDbgLevel = STP_BTM_LOG_INFO; ++ ++#define STP_BTM_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_LOUD) \ ++ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ ++ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_INFO) \ ++ pr_debug(PFX_BTM "[I]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_WARN) \ ++ pr_warn(PFX_BTM "[W]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_BTM_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_ERR) \ ++ pr_err(PFX_BTM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define STP_BTM_TRC_FUNC(f) \ ++do { \ ++ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ ++ pr_debug(PFX_BTM "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++#define ASSERT(expr) ++ ++MTKSTP_BTM_T stp_btm_i; ++MTKSTP_BTM_T *stp_btm = &stp_btm_i; ++ ++const char *g_btm_op_name[] = { ++ "STP_OPID_BTM_RETRY", ++ "STP_OPID_BTM_RST", ++ "STP_OPID_BTM_DBG_DUMP", ++ "STP_OPID_BTM_DUMP_TIMEOUT", ++ "STP_OPID_BTM_POLL_CPUPCR", ++ "STP_OPID_BTM_PAGED_DUMP", ++ "STP_OPID_BTM_FULL_DUMP", ++ "STP_OPID_BTM_PAGED_TRACE", ++ "STP_OPID_BTM_FORCE_FW_ASSERT", ++#if CFG_WMT_LTE_COEX_HANDLING ++ "STP_OPID_BTM_WMT_LTE_COEX", ++#endif ++ "STP_OPID_BTM_EXIT" ++}; ++ ++#if 0 ++static char *_stp_pkt_type(int type) ++{ ++ ++ static char s[10]; ++ ++ switch (type) { ++ case WMT_TASK_INDX: ++ osal_memcpy(s, "WMT", strlen("WMT") + 1); ++ break; ++ case BT_TASK_INDX: ++ osal_memcpy(s, "BT", strlen("BT") + 1); ++ break; ++ case GPS_TASK_INDX: ++ osal_memcpy(s, "GPS", strlen("GPS") + 1); ++ break; ++ case FM_TASK_INDX: ++ osal_memcpy(s, "FM", strlen("FM") + 1); ++ break; ++ default: ++ osal_memcpy(s, "UNKNOWN", strlen("UNKNOWN") + 1); ++ break; ++ } ++ ++ return s; ++} ++#endif ++ ++static INT32 _stp_btm_put_dump_to_nl(void) ++{ ++#define NUM_FETCH_ENTRY 8 ++ ++ static UINT8 buf[2048]; ++ static UINT8 tmp[2048]; ++ ++ UINT32 buf_len; ++ STP_PACKET_T *pkt; ++ STP_DBG_HDR_T *hdr; ++ INT32 len; ++ INT32 remain = 0, index = 0; ++ INT32 retry = 0, rc = 0, nl_retry = 0; ++ ++ STP_BTM_INFO_FUNC("Enter..\n"); ++ ++ index = 0; ++ tmp[index++] = '['; ++ tmp[index++] = 'M'; ++ tmp[index++] = ']'; ++ ++ do { ++ index = 3; ++ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); ++ if (buf_len > 0) { ++ pkt = (STP_PACKET_T *) buf; ++ hdr = &pkt->hdr; ++ len = pkt->hdr.len; ++ osal_memcpy(&tmp[index], &len, 2); ++ index += 2; ++ if (hdr->dbg_type == STP_DBG_FW_DMP) { ++ osal_memcpy(&tmp[index], pkt->raw, len); ++ ++ if (len <= 1500) { ++ /* pr_warn("\n%s\n+++\n", tmp); */ ++ /* pr_warn("send coredump len:%d\n", len); */ ++ /* pr_warn("send coredump:%s\n", tmp); */ ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); ++ ++ while (rc) { ++ nl_retry++; ++ if (nl_retry > 1000) ++ break; ++ STP_BTM_WARN_FUNC ++ ("**dump send fails, and retry again.**\n"); ++ osal_sleep_ms(3); ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); ++ if (!rc) ++ STP_BTM_WARN_FUNC("****retry again ok!**\n"); ++ } ++ /* schedule(); */ ++ } else { ++ STP_BTM_INFO_FUNC("dump entry length is over long\n"); ++ BUG_ON(0); ++ } ++ retry = 0; ++ } ++ } else { ++ retry++; ++ osal_sleep_ms(100); ++ } ++ } while ((remain > 0) || (retry < 2)); ++ ++ STP_BTM_INFO_FUNC("Exit..\n"); ++ return 0; ++} ++ ++#define SUB_PKT_SIZE 1024 ++#define SUB_PKT_HEADER 5 /*'[M]',3Bytes; len,2Bytes*/ ++ ++INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len) ++{ ++ static UINT8 tmp[SUB_PKT_SIZE + SUB_PKT_HEADER]; ++ ++ INT32 remain = dump_len, index = 0; ++ INT32 rc = 0, nl_retry = 0; ++ INT32 len; ++ INT32 offset = 0; ++ ++ STP_BTM_INFO_FUNC("Enter..\n"); ++ ++ if (dump_len > 0) { ++ index = 0; ++ tmp[index++] = '['; ++ tmp[index++] = 'M'; ++ tmp[index++] = ']'; ++ ++ do { ++ index = 3; ++ if (remain >= SUB_PKT_SIZE) ++ len = SUB_PKT_SIZE; ++ else ++ len = remain; ++ remain -= len; ++ ++ osal_memcpy(&tmp[index], &len, 2); ++ index += 2; ++ osal_memcpy(&tmp[index], data_buf + offset, len); ++ offset += len; ++ STP_BTM_DBG_FUNC ++ ("send %d remain %d\n", len, remain); ++ ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); ++ while (rc) { ++ nl_retry++; ++ if (nl_retry > 1000) ++ break; ++ STP_BTM_WARN_FUNC ++ ("**dump send fails, and retry again.**\n"); ++ osal_sleep_ms(3); ++ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); ++ if (!rc) { ++ STP_BTM_WARN_FUNC ++ ("****retry again ok!**\n"); ++ } ++ } ++ /* schedule(); */ ++ } while (remain > 0); ++ } else ++ STP_BTM_INFO_FUNC("dump entry length is 0\n"); ++ ++ STP_BTM_INFO_FUNC("Exit..\n"); ++ return 0; ++} ++ ++static INT32 _stp_btm_put_dump_to_aee(void) ++{ ++ static UINT8 buf[2048]; ++ static UINT8 tmp[2048]; ++ ++ UINT32 buf_len; ++ STP_PACKET_T *pkt; ++ STP_DBG_HDR_T *hdr; ++ INT32 remain = 0; ++ INT32 retry = 0; ++ INT32 ret = 0; ++ ++ STP_BTM_INFO_FUNC("Enter..\n"); ++ ++ do { ++ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); ++ if (buf_len > 0) { ++ pkt = (STP_PACKET_T *) buf; ++ hdr = &pkt->hdr; ++ if (hdr->dbg_type == STP_DBG_FW_DMP) { ++ memcpy(&tmp[0], pkt->raw, pkt->hdr.len); ++ ++ if (pkt->hdr.len <= 1500) { ++ tmp[pkt->hdr.len] = '\n'; ++ tmp[pkt->hdr.len + 1] = '\0'; ++ ++ ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0); ++ } else { ++ STP_BTM_INFO_FUNC("dump entry length is over long\n"); ++ BUG_ON(0); ++ } ++ retry = 0; ++ } ++ } else { ++ retry++; ++ msleep(100); ++ } ++ } while ((remain > 0) || (retry < 2)); ++ ++ STP_BTM_INFO_FUNC("Exit..\n"); ++ return ret; ++} ++ ++#if 0 ++INT32 _stp_trigger_firmware_assert_via_emi(VOID) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ INT32 status = -1; ++ INT32 i = 0, j = 0; ++ ++ do { ++ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); ++ if (!p_virtual_addr) { ++ STP_BTM_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); ++ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); ++#if 1 ++ /* wait for firmware assert */ ++ osal_sleep_ms(50); ++ /* if firmware is not assert self, host driver helps it. */ ++ do { ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ status = 0; ++ break; ++ } ++ ++ mtk_wcn_stp_wakeup_consys(); ++ STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i); ++ stp_dbg_poll_cpupcr(5, 1, 1); ++ osal_sleep_ms(5); ++ ++ i++; ++ if (i > 20) { ++ i = 0; ++ break; ++ } ++ } while (1); ++#endif ++ ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ status = 0; ++ break; ++ } ++ ++ j++; ++ if (j > 8) { ++ j = 0; ++ break; ++ } ++ } while (1); ++ ++ return status; ++} ++#else ++INT32 _stp_trigger_firmware_assert_via_emi(VOID) ++{ ++ INT32 status = -1; ++ INT32 j = 0; ++ ++ wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); ++ ++ do { ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ status = 0; ++ break; ++ } ++ ++ stp_dbg_poll_cpupcr(5, 1, 1); ++ stp_dbg_poll_dmaregs(5, 1); ++ j++; ++ STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); ++ osal_sleep_ms(20); ++ if (j > 49) { /* wait for 1 second */ ++ stp_dbg_set_fw_info("host trigger fw assert timeout", ++ osal_strlen("host trigger fw assert timeout"), ++ STP_HOST_TRIGGER_ASSERT_TIMEOUT); ++ wcn_core_dump_timeout(); /* trigger collect SYS_FTRACE */ ++ break; ++ } ++ } while (1); ++ ++ return status; ++} ++#endif ++ ++#define COMBO_DUMP2AEE ++#if 1 ++#define STP_DBG_PAGED_DUMP_BUFFER_SIZE (32*1024*sizeof(char)) ++UINT8 g_paged_dump_buffer[STP_DBG_PAGED_DUMP_BUFFER_SIZE] = { 0 }; ++ ++#define STP_DBG_PAGED_TRACE_SIZE (2048*sizeof(char)) ++UINT8 g_paged_trace_buffer[STP_DBG_PAGED_TRACE_SIZE] = { 0 }; ++ ++UINT32 g_paged_dump_len = 0; ++UINT32 g_paged_trace_len = 0; ++VOID _stp_dump_emi_dump_buffer(UINT8 *buffer, UINT32 len) ++{ ++ UINT32 i = 0; ++ ++ if (len > 16) ++ len = 16; ++ for (i = 0; i < len; i++) { ++ if (i % 16 == 0 && i != 0) ++ pr_cont("\n "); ++ ++ if (buffer[i] == ']' || buffer[i] == '[' || buffer[i] == ',') ++ pr_cont("%c", buffer[i]); ++ else ++ pr_cont("0x%02x ", buffer[i]); ++ } ++} ++#endif ++static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) ++{ ++ INT32 ret = -1; ++ INT32 dump_sink = 1; /* core dump target, 0: aee; 1: netlink */ ++ INT32 Ret = 0; ++ static UINT32 counter; ++ UINT32 full_dump_left = STP_FULL_DUMP_TIME; ++ UINT32 page_counter = 0; ++ UINT32 packet_num = STP_PAGED_DUMP_TIME_LIMIT/100; ++ UINT32 dump_num = 0; ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ P_CONSYS_EMI_ADDR_INFO p_ecsi; ++ ++ p_ecsi = wmt_plat_get_emi_phy_add(); ++ osal_assert(p_ecsi); ++ if (NULL == pStpOp) ++ return -1; ++ ++ switch (pStpOp->opId) { ++ case STP_OPID_BTM_EXIT: ++ /* TODO: clean all up? */ ++ ret = 0; ++ break; ++ ++ /*tx timeout retry */ ++ case STP_OPID_BTM_RETRY: ++ stp_do_tx_timeout(); ++ ret = 0; ++ ++ break; ++ ++ /*whole chip reset */ ++ case STP_OPID_BTM_RST: ++ STP_BTM_INFO_FUNC("whole chip reset start!\n"); ++ STP_BTM_INFO_FUNC("....+\n"); ++ if (stp_btm->wmt_notify) { ++ stp_btm->wmt_notify(BTM_RST_OP); ++ ret = 0; ++ } else { ++ STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); ++ ret = -1; ++ } ++ ++ STP_BTM_INFO_FUNC("whole chip reset end!\n"); ++ ++ break; ++ ++ case STP_OPID_BTM_DBG_DUMP: ++ /*Notify the wmt to get dump data */ ++ STP_BTM_DBG_FUNC("wmt dmp notification\n"); ++ dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1); ++ ++ if (dump_sink == 0) ++ _stp_btm_put_dump_to_aee(); ++ else if (dump_sink == 1) ++ _stp_btm_put_dump_to_nl(); ++ else ++ STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink); ++ ++ break; ++ ++ case STP_OPID_BTM_DUMP_TIMEOUT: ++ /* Flush dump data, and reset compressor */ ++ STP_BTM_INFO_FUNC("Flush dump data\n"); ++ wcn_core_dump_flush(0, MTK_WCN_BOOL_TRUE); ++ break; ++ ++ case STP_OPID_BTM_POLL_CPUPCR: ++ do { ++ UINT32 times; ++ UINT32 sleep; ++ ++ times = pStpOp->au4OpData[0]; ++ sleep = pStpOp->au4OpData[1]; ++ ++ ret = stp_dbg_poll_cpupcr(times, sleep, 0); ++ ret += stp_dbg_poll_dmaregs(times, sleep); ++ } while (0); ++ break; ++ ++ case STP_OPID_BTM_PAGED_DUMP: ++ g_paged_dump_len = 0; ++ issue_type = STP_FW_ASSERT_ISSUE; ++ /*packet number depend on dump_num get from register:0xf0080044 ,support jade*/ ++ wcn_core_dump_deinit_gcoredump(); ++ dump_num = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_page_dump_num); ++ if (dump_num != 0) { ++ packet_num = dump_num; ++ STP_BTM_WARN_FUNC("get consys dump num packet_num(%d)\n", packet_num); ++ } else { ++ STP_BTM_ERR_FUNC("can not get consys dump num and default num is 35\n"); ++ } ++ Ret = wcn_core_dump_init_gcoredump(packet_num, STP_CORE_DUMP_TIMEOUT); ++ if (Ret) { ++ STP_BTM_ERR_FUNC("core dump init fail\n"); ++ break; ++ } ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ page_counter = 0; ++ do { ++ UINT32 loop_cnt1 = 0; ++ UINT32 loop_cnt2 = 0; ++ ENUM_HOST_DUMP_STATE host_state; ++ ENUM_CHIP_DUMP_STATE chip_state; ++ UINT32 dump_phy_addr = 0; ++ UINT8 *dump_vir_addr = NULL; ++ UINT32 dump_len = 0; ++ UINT32 isEnd = 0; ++ ++ host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_state); ++ if (STP_HOST_DUMP_NOT_START == host_state) { ++ counter++; ++ STP_BTM_INFO_FUNC("counter(%d)\n", counter); ++ osal_sleep_ms(100); ++ } else { ++ counter = 0; ++ } ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_PUT_DONE == chip_state) { ++ STP_BTM_INFO_FUNC("chip put done\n"); ++ break; ++ } ++ STP_BTM_INFO_FUNC("waiting chip put done\n"); ++ STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state); ++ loop_cnt1++; ++ osal_sleep_ms(5); ++ ++ if (loop_cnt1 > 10) ++ goto paged_dump_end; ++ ++ } ++ ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); ++ ++ dump_phy_addr = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); ++ ++ if (!dump_phy_addr) { ++ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); ++ ret = -1; ++ break; ++ } ++ ++ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); ++ if (!dump_vir_addr) { ++ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); ++ ret = -2; ++ break; ++ } ++ dump_len = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); ++ STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n", ++ dump_phy_addr, dump_vir_addr, dump_len); ++ ++ /*move dump info according to dump_addr & dump_len */ ++#if 1 ++ osal_memcpy(&g_paged_dump_buffer[0], dump_vir_addr, dump_len); ++ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], dump_len); ++ ++ if (0 == page_counter) { /* do fw assert infor paser in first paged dump */ ++ if (1 == stp_dbg_get_host_trigger_assert()) ++ issue_type = STP_HOST_TRIGGER_FW_ASSERT; ++ ++ ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0], 512, issue_type); ++ if (ret) { ++ STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n", ret); ++ stp_dbg_set_fw_info("Fw Warm reset", osal_strlen("Fw Warm reset"), ++ STP_FW_WARM_RST_ISSUE); ++ } ++ } ++ ++ if (dump_len <= 32 * 1024) { ++ pr_err("g_coredump_mode: %d!\n", g_coredump_mode); ++ if (1 == g_coredump_mode) ++ ret = stp_dbg_aee_send(&g_paged_dump_buffer[0], dump_len, 0); ++ else if (2 == g_coredump_mode) ++ ret = _stp_btm_put_emi_dump_to_nl(&g_paged_dump_buffer[0], dump_len); ++ else{ ++ STP_BTM_INFO_FUNC("coredump is disabled!\n"); ++ return 0; ++ } ++ if (ret == 0) ++ STP_BTM_INFO_FUNC("aee send ok!\n"); ++ else if (ret == 1) ++ STP_BTM_INFO_FUNC("aee send fisish!\n"); ++ else ++ STP_BTM_ERR_FUNC("aee send error!\n"); ++ } else ++ STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n", dump_len); ++ ++ g_paged_dump_len += dump_len; ++ STP_BTM_INFO_FUNC("dump len update(%d)\n", g_paged_dump_len); ++#endif ++ wmt_plat_update_host_sync_num(); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); ++ ++ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); ++ ++ page_counter++; ++ STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n", page_counter); ++ ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_END == chip_state) { ++ STP_BTM_INFO_FUNC("chip put end\n"); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); ++ break; ++ } ++ STP_BTM_INFO_FUNC("waiting chip put end\n"); ++ ++ loop_cnt2++; ++ osal_sleep_ms(10); ++ ++ if (loop_cnt2 > 10) ++ goto paged_dump_end; ++ } ++ ++paged_dump_end: ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ ++ if (counter > packet_num) { ++ isEnd = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_paded_dump_end); ++ ++ if (isEnd) { ++ STP_BTM_INFO_FUNC("paged dump end\n"); ++ ++ STP_BTM_INFO_FUNC("\n\n paged dump print ++\n\n"); ++ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], g_paged_dump_len); ++ STP_BTM_INFO_FUNC("\n\n paged dump print --\n\n"); ++ STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d\n\n", ++ g_paged_dump_len, page_counter); ++ counter = 0; ++ ret = 0; ++ } else { ++ STP_BTM_ERR_FUNC("paged dump fail\n"); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ stp_dbg_poll_cpupcr(5, 5, 0); ++ stp_dbg_poll_dmaregs(5, 1); ++ counter = 0; ++ ret = -1; ++ } ++ break; ++ } ++ ++ } while (1); ++ ++ break; ++ ++ case STP_OPID_BTM_FULL_DUMP: ++ ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ do { ++ UINT32 loop_cnt1 = 0; ++ UINT32 loop_cnt2 = 0; ++ ENUM_CHIP_DUMP_STATE chip_state; ++ UINT32 dump_phy_addr = 0; ++ UINT8 *dump_vir_addr = NULL; ++ UINT32 dump_len = 0; ++ UINT32 isFail = 0; ++ ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_PUT_DONE == chip_state) ++ break; ++ ++ loop_cnt1++; ++ osal_sleep_ms(10); ++ ++ if (loop_cnt1 > 10) { ++ isFail = 1; ++ goto full_dump_end; ++ } ++ } ++ ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); ++ ++ dump_phy_addr = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); ++ if (!dump_phy_addr) { ++ STP_BTM_ERR_FUNC("get phy dump address fail\n"); ++ ret = -1; ++ break; ++ } ++ ++ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); ++ if (!dump_vir_addr) { ++ STP_BTM_ERR_FUNC("get vir dump address fail\n"); ++ ret = -2; ++ break; ++ } ++ dump_len = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); ++ /*move dump info according to dump_addr & dump_len */ ++ wmt_plat_update_host_sync_num(); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); ++ ++ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), ++ wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); ++ ++ while (1) { ++ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); ++ if (STP_CHIP_DUMP_END == chip_state) { ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); ++ break; ++ } ++ loop_cnt2++; ++ osal_sleep_ms(10); ++ ++ if (loop_cnt2 > 10) { ++ isFail = 1; ++ goto full_dump_end; ++ } ++ } ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++full_dump_end: ++ if (isFail) { ++ STP_BTM_ERR_FUNC("full dump fail\n"); ++ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); ++ ret = -1; ++ break; ++ } ++ } while (--full_dump_left > 0); ++ if (0 == full_dump_left) { ++ STP_BTM_INFO_FUNC("full dump end\n"); ++ ret = 0; ++ } ++ break; ++ case STP_OPID_BTM_PAGED_TRACE: ++ g_paged_trace_len = 0; ++ do { ++ UINT32 ctrl_val = 0; ++ UINT32 loop_cnt1 = 0; ++ UINT32 buffer_start = 0; ++ UINT32 buffer_idx = 0; ++ UINT8 *dump_vir_addr = NULL; ++ ++ while (loop_cnt1 < 10) { ++ ctrl_val = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state); ++ if (0x8 == ctrl_val) ++ break; ++ osal_sleep_ms(10); ++ loop_cnt1++; ++ } ++ ++ if (loop_cnt1 >= 10) { ++ STP_BTM_ERR_FUNC("polling CTRL STATE fail\n"); ++ ret = -1; ++ break; ++ } ++ ++ buffer_start = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_start); ++ buffer_idx = wmt_plat_get_dump_info( ++ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_idx); ++ /* buffer_len = buffer_idx - buffer_start; */ ++ g_paged_trace_len = buffer_idx; ++ STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n", buffer_start, buffer_idx); ++ dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_ecsi->emi_phy_addr); ++ if (!dump_vir_addr) { ++ STP_BTM_ERR_FUNC("get vir dump address fail\n"); ++ ret = -2; ++ break; ++ } ++ osal_memcpy(&g_paged_trace_buffer[0], dump_vir_addr, ++ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE); ++ /*moving paged trace according to buffer_start & buffer_len */ ++ do { ++ int i = 0; ++ int dump_len = 0; ++ ++ dump_len = ++ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE; ++ pr_warn("\n\n -- paged trace hex output --\n\n"); ++ for (i = 0; i < dump_len; i++) { ++ if (i % 16 == 0) ++ pr_cont("\n"); ++ ++ pr_cont("%02x ", g_paged_trace_buffer[i]); ++ } ++ pr_warn("\n\n -- paged trace ascii output --\n\n"); ++ for (i = 0; i < dump_len; i++) { ++ if (i % 64 == 0) ++ pr_cont("\n"); ++ pr_cont("%c", g_paged_trace_buffer[i]); ++ } ++ } while (0); ++ /*move parser fw assert infor to paged dump in the one paged dump */ ++ /* ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type); */ ++ ret = 0; ++ ++ } while (0); ++ mtk_wcn_stp_ctx_restore(); ++ break; ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ case STP_OPID_BTM_WMT_LTE_COEX: ++ ret = wmt_idc_msg_to_lte_handing(); ++ break; ++#endif ++ default: ++ ret = -1; ++ break; ++ } ++ ++ return ret; ++} ++ ++static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ) ++{ ++ P_OSAL_OP pOp; ++ /* INT32 ret = 0; */ ++ ++ if (!pOpQ) { ++ STP_BTM_WARN_FUNC("!pOpQ\n"); ++ return NULL; ++ } ++ ++ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ /* acquire lock success */ ++ RB_GET(pOpQ, pOp); ++ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ ++ if (!pOp) ++ STP_BTM_WARN_FUNC("RB_GET fail\n"); ++ ++ return pOp; ++} ++ ++static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) ++{ ++ INT32 ret; ++ ++ if (!pOpQ || !pOp) { ++ STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); ++ return 0; /* ;MTK_WCN_BOOL_FALSE; */ ++ } ++ ++ ret = 0; ++ ++ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ /* acquire lock success */ ++ if (!RB_FULL(pOpQ)) ++ RB_PUT(pOpQ, pOp); ++ else ++ ret = -1; ++ ++ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ ++ if (ret) { ++ STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", ++ pOpQ, ++ RB_COUNT(pOpQ), ++ &stp_btm->rFreeOpQ, ++ &stp_btm->rActiveOpQ); ++ return 0; ++ } ++ /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ ++ return 1; ++ ++} ++ ++P_OSAL_OP _stp_btm_get_free_op(MTKSTP_BTM_T *stp_btm) ++{ ++ P_OSAL_OP pOp; ++ ++ if (stp_btm) { ++ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ); ++ if (pOp) ++ osal_memset(&pOp->op, 0, sizeof(pOp->op)); ++ ++ return pOp; ++ } else ++ return NULL; ++} ++ ++INT32 _stp_btm_put_act_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) ++{ ++ INT32 bRet = 0; ++ INT32 bCleanup = 0; ++ long wait_ret = -1; ++ ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ if (!stp_btm || !pOp) { ++ STP_BTM_ERR_FUNC("Input NULL pointer\n"); ++ return bRet; ++ } ++ do { ++ pSignal = &pOp->signal; ++ ++ if (pSignal->timeoutValue) { ++ pOp->result = -9; ++ osal_signal_init(&pOp->signal); ++ } ++ ++ /* put to active Q */ ++ bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp); ++ if (0 == bRet) { ++ STP_BTM_WARN_FUNC("put active queue fail\n"); ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ break; ++ } ++ ++ /* wake up wmtd */ ++ osal_trigger_event(&stp_btm->STPd_event); ++ ++ if (pSignal->timeoutValue == 0) { ++ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ ++ /* clean it in wmtd */ ++ break; ++ } ++ ++ /* wait result, clean it here */ ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ ++ /* check result */ ++ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); ++ ++ STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret); ++ if (!wait_ret) { ++ STP_BTM_ERR_FUNC("wait completion timeout\n"); ++ /* TODO: how to handle it? retry? */ ++ } else { ++ if (pOp->result) ++ STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); ++ ++ bRet = (pOp->result) ? 0 : 1; ++ } ++ } while (0); ++ ++ if (bCleanup) { ++ /* put Op back to freeQ */ ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); ++ } ++ bRet = (pOp->result) ? 0 : 1; ++ return bRet; ++} ++ ++static INT32 _stp_btm_wait_for_msg(void *pvData) ++{ ++ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; ++ ++ return (!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd); ++} ++ ++static INT32 _stp_btm_proc(void *pvData) ++{ ++ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; ++ P_OSAL_OP pOp; ++ INT32 id; ++ INT32 result; ++ ++ if (!stp_btm) { ++ STP_BTM_WARN_FUNC("!stp_btm\n"); ++ return -1; ++ } ++ ++ for (;;) { ++ pOp = NULL; ++ ++ osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm); ++ ++ if (osal_thread_should_stop(&stp_btm->BTMd)) { ++ STP_BTM_INFO_FUNC("should stop now...\n"); ++ /* TODO: clean up active opQ */ ++ break; ++ } ++ ++ /* get Op from activeQ */ ++ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); ++ ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); ++ continue; ++ } ++ ++ id = osal_op_get_id(pOp); ++ ++ STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", ++ id, (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), ++ RB_COUNT(&stp_btm->rActiveOpQ)); ++ ++ if (id >= STP_OPID_BTM_NUM) { ++ STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id); ++ result = -1; ++ goto handler_done; ++ } ++ ++ result = _stp_btm_handler(stp_btm, &pOp->op); ++ ++handler_done: ++ ++ if (result) { ++ STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, ++ (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), ++ result); ++ } ++ ++ if (osal_op_is_wait_for_signal(pOp)) { ++ osal_op_raise_signal(pOp, result); ++ } else { ++ /* put Op back to freeQ */ ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); ++ } ++ ++ if (STP_OPID_BTM_EXIT == id) { ++ break; ++ } else if (STP_OPID_BTM_RST == id) { ++ /* prevent multi reset case */ ++ stp_btm_reset_btm_wq(stp_btm); ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ } ++ } ++ ++ STP_BTM_INFO_FUNC("exits\n"); ++ ++ return 0; ++}; ++ ++static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_RST; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_RETRY; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (!stp_btm) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_DUMP_TIMEOUT; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_dump_type(MTKSTP_BTM_T *stp_btm, ENUM_STP_BTM_OPID_T opid) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = opid; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ INT32 retval; ++#if 0 ++ UINT32 dump_type; ++ UINT8 *virtual_addr = NULL; ++#endif ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++#if 1 /* Paged dump */ ++ STP_BTM_INFO_FUNC("paged dump start++\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); ++ if (retval) ++ STP_BTM_ERR_FUNC("paged dump fail\n"); ++#else ++ virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR); ++ if (!virtual_addr) { ++ STP_BTM_ERR_FUNC("get dump type virtual addr fail\n"); ++ return -1; ++ } ++ dump_type = CONSYS_REG_READ(virtual_addr); ++ STP_BTM_INFO_FUNC("dump type:%08x\n", dump_type); ++ ++ if ((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff)) { ++ STP_BTM_INFO_FUNC("do paged dump\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); ++ if (retval) { ++ STP_BTM_ERR_FUNC("paged dump fail,do full dump\n"); ++ _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); ++ } ++ } else if ((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff)) { ++ STP_BTM_INFO_FUNC("do full dump\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); ++ } else { ++ STP_BTM_INFO_FUNC("do normal dump\n"); ++ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DBG_DUMP); ++ } ++#endif ++ ++ return retval; ++} ++ ++static inline INT32 _stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_POLL_CPUPCR; ++ pOp->signal.timeoutValue = 0; ++ pOp->op.au4OpData[0] = times; ++ pOp->op.au4OpData[1] = sleep; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_PAGED_TRACE; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) ++{ ++ INT32 ret = -1; ++ ++ ret = _stp_trigger_firmware_assert_via_emi(); ++ ++ return ret; ++ ++} ++ ++INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_wmt_rst_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_stp_retry_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_coredump_timeout_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_wmt_dmp_wq(stp_btm); ++} ++ ++INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_btm_notify_wmt_trace_wq(stp_btm); ++} ++ ++INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) ++{ ++ return _stp_notify_btm_poll_cpupcr(stp_btm, times, sleep); ++} ++ ++INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en) ++{ ++ return stp_dbg_poll_cuppcr_ctrl(en); ++} ++ ++INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) ++{ ++ INT32 ret = -1; ++#if BTIF_RXD_BE_BLOCKED_DETECT ++ if (is_btif_rxd_be_blocked()) ++ ret = wcn_btif_rxd_blocked_collect_ftrace(); /* trigger collect SYS_FTRACE */ ++ else ++#endif ++ ret = _stp_btm_do_fw_assert_via_emi(stp_btm); ++ return ret; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ ++static inline INT32 _stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_btm == NULL) ++ return STP_BTM_OPERATION_FAIL; ++ ++ pOp = _stp_btm_get_free_op(stp_btm); ++ if (!pOp) { ++ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ ++ return -1; /* break; */ ++ } ++ pOp->op.opId = STP_OPID_BTM_WMT_LTE_COEX; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_btm_put_act_op(stp_btm, pOp); ++ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) ++{ ++ return _stp_notify_btm_handle_wmt_lte_coex(stp_btm); ++} ++ ++#endif ++MTKSTP_BTM_T *stp_btm_init(void) ++{ ++ INT32 i = 0x0; ++ INT32 ret = -1; ++ ++ osal_unsleepable_lock_init(&stp_btm->wq_spinlock); ++ osal_event_init(&stp_btm->STPd_event); ++ stp_btm->wmt_notify = wmt_lib_btm_cb; ++ ++ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); ++ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); ++ ++ /* Put all to free Q */ ++ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(stp_btm->arQue[i].signal)); ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); ++ } ++ ++ /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving */ ++ stp_btm->BTMd.pThreadData = (VOID *) stp_btm; ++ stp_btm->BTMd.pThreadFunc = (VOID *) _stp_btm_proc; ++ osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME, osal_strlen(BTM_THREAD_NAME)); ++ ++ ret = osal_thread_create(&stp_btm->BTMd); ++ if (ret < 0) { ++ STP_BTM_ERR_FUNC("osal_thread_create fail...\n"); ++ goto ERR_EXIT1; ++ } ++ ++ /* Start STPd thread */ ++ ret = osal_thread_run(&stp_btm->BTMd); ++ if (ret < 0) { ++ STP_BTM_ERR_FUNC("osal_thread_run FAILS\n"); ++ goto ERR_EXIT1; ++ } ++ ++ return stp_btm; ++ ++ERR_EXIT1: ++ ++ return NULL; ++ ++} ++ ++INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm) ++{ ++ ++ INT32 ret = -1; ++ ++ STP_BTM_INFO_FUNC("btm deinit\n"); ++ ++ if (!stp_btm) ++ return STP_BTM_OPERATION_FAIL; ++ ++ ret = osal_thread_destroy(&stp_btm->BTMd); ++ if (ret < 0) { ++ STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n"); ++ return STP_BTM_OPERATION_FAIL; ++ } ++ ++ return STP_BTM_OPERATION_SUCCESS; ++} ++ ++INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) ++{ ++ UINT32 i = 0; ++ ++ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); ++ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); ++ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); ++ /* Put all to free Q */ ++ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(stp_btm->arQue[i].signal)); ++ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); ++ } ++ ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c +new file mode 100644 +index 000000000000..246448b38b31 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c +@@ -0,0 +1,13 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h +new file mode 100644 +index 000000000000..9a429b4af1e3 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h +@@ -0,0 +1,133 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _BTM_CORE_H ++#define _BTM_CORE_H ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_wmt.h" ++#include "wmt_plat.h" ++#include "wmt_idc.h" ++#include "mtk_btif_exp.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define STP_BTM_OPERATION_FAIL (-1) ++#define STP_BTM_OPERATION_SUCCESS (0) ++ ++#define STP_BTM_OP_BUF_SIZE (64) ++ ++#define BTM_THREAD_NAME "mtk_stp_btm" ++ ++#define STP_PAGED_DUMP_TIME_LIMIT 3500 ++#define STP_FULL_DUMP_TIME 3 ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_STP_BTM_OPID_T { ++ STP_OPID_BTM_RETRY = 0x0, ++ STP_OPID_BTM_RST = 0x1, ++ STP_OPID_BTM_DBG_DUMP = 0x2, ++ STP_OPID_BTM_DUMP_TIMEOUT = 0x3, ++ STP_OPID_BTM_POLL_CPUPCR = 0x4, ++ STP_OPID_BTM_PAGED_DUMP = 0x5, ++ STP_OPID_BTM_FULL_DUMP = 0x6, ++ STP_OPID_BTM_PAGED_TRACE = 0x7, ++ STP_OPID_BTM_FORCE_FW_ASSERT = 0x8, ++#if CFG_WMT_LTE_COEX_HANDLING ++ STP_OPID_BTM_WMT_LTE_COEX = 0x9, ++#endif ++ STP_OPID_BTM_EXIT, ++ STP_OPID_BTM_NUM ++} ENUM_STP_BTM_OPID_T, *P_ENUM_STP_BTM_OPID_T; ++ ++typedef OSAL_OP_DAT STP_BTM_OP; ++typedef P_OSAL_OP_DAT P_STP_BTM_OP; ++ ++typedef struct mtk_stp_btm { ++ OSAL_THREAD BTMd; /* main thread (wmtd) handle */ ++ OSAL_EVENT STPd_event; ++ OSAL_UNSLEEPABLE_LOCK wq_spinlock; ++ ++ OSAL_OP_Q rFreeOpQ; /* free op queue */ ++ OSAL_OP_Q rActiveOpQ; /* active op queue */ ++ OSAL_OP arQue[STP_BTM_OP_BUF_SIZE]; /* real op instances */ ++ ++ /*wmt_notify */ ++ INT32 (*wmt_notify)(MTKSTP_BTM_WMT_OP_T); ++} MTKSTP_BTM_T; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm); ++INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep); ++INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en); ++INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm); ++INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm); ++INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm); ++INT32 wcn_psm_flag_trigger_collect_ftrace(void); ++#if BTIF_RXD_BE_BLOCKED_DETECT ++INT32 wcn_btif_rxd_blocked_collect_ftrace(void); ++MTK_WCN_BOOL is_btif_rxd_be_blocked(void); ++#endif ++MTKSTP_BTM_T *stp_btm_init(void); ++extern unsigned int g_coredump_mode; ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h +new file mode 100644 +index 000000000000..d8c6ebe9c4b0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h +@@ -0,0 +1,69 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _DBG_CORE_H ++#define _DBG_CORE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h +new file mode 100644 +index 000000000000..fe92f25e92c1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h +@@ -0,0 +1,251 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _PSM_CORE_H ++#define _PSM_CORE_H ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_wmt.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define PFX_PSM "[STP-PSM] " ++#define STP_PSM_LOG_LOUD 4 ++#define STP_PSM_LOG_DBG 3 ++#define STP_PSM_LOG_INFO 2 ++#define STP_PSM_LOG_WARN 1 ++#define STP_PSM_LOG_ERR 0 ++ ++#define ASSERT(expr) ++#define STP_PSM_FIFO_SIZE 0x2000 /* 8kbytes */ ++#define STP_PSM_TX_SIZE 0x800 /* 2kbytes */ ++ ++#define STP_PSM_OPERATION_FAIL (-1) ++#define STP_PSM_OPERATION_SUCCESS (0) ++ ++#define STP_PSM_PACKET_SIZE_MAX (2000) ++ ++#define PSM_HANDLING 127 ++ ++#define STP_PSM_WMT_PS_TASK_HANDLING_TIME 30 /* 20 milli-seconds */ ++#define STP_PSM_IDLE_TIME_SLEEP 30 /* temporary for stress testing */ ++#define STP_PSM_IDLE_TIME_SLEEP_1000 1000 /* for high speed transmission e.g. BT OPP*/ ++#define STP_PSM_SDIO_IDLE_TIME_SLEEP 100 /* temporary for SDIO stress testing */ ++#define STP_PSM_WAIT_EVENT_TIMEOUT 6000 ++#if 0 ++#define STP_PSM_WMT_EVENT_SLEEP_EN (0x1UL << 0) ++#define STP_PSM_WMT_EVENT_WAKEUP_EN (0x1UL << 1) ++#define STP_PSM_BLOCK_DATA_EN (0x1UL << 2) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (0x1UL << 3) ++#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (0x1UL << 4) ++#define STP_PSM_RESET_EN (0x1UL << 5) ++#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (0x1UL << 6) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (0x1UL << 7) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (0x1UL << 8) ++#endif ++ ++#define STP_PSM_WMT_EVENT_SLEEP_EN (0) ++#define STP_PSM_WMT_EVENT_WAKEUP_EN (1) ++#define STP_PSM_BLOCK_DATA_EN (2) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (3) ++#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (4) ++#define STP_PSM_RESET_EN (5) ++#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (6) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (7) ++#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (8) ++ ++#define STP_PSM_DBG_SIZE (16) ++ ++/* OP command ring buffer : must be power of 2 */ ++#define STP_OP_BUF_SIZE (16) ++ ++#define PSM_THREAD_NAME "mtk_stp_psm" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum { ++ ACT = 0, ++ ACT_INACT, ++ INACT, ++ INACT_ACT, ++ STP_PSM_MAX_STATE, ++} MTKSTP_PSM_STATE_T; ++ ++typedef enum _ENUM_STP_OPID_T { ++ STP_OPID_PSM_SLEEP = 0, ++ STP_OPID_PSM_WAKEUP, ++ STP_OPID_PSM_HOST_AWAKE, ++ STP_OPID_PSM_EXIT, ++ STP_OPID_PSM_NUM, ++ STP_OPID_PSM_INALID = STP_OPID_PSM_NUM, ++} ENUM_STP_OPID_T, *P_ENUM_STP_OPID_T; ++ ++typedef enum { ++ MON = 0, ++ UNMON, ++} MTKSTP_PSM_MONSTATE_T; ++ ++typedef INT32(*wmt_notify_t) (MTKSTP_PSM_ACTION_T action); ++typedef INT32(*stp_tx_cb_t) (unsigned char *buffer, UINT32 length, UINT8 type); ++ ++typedef OSAL_OP_DAT STP_OP; ++typedef P_OSAL_OP_DAT P_STP_OP; ++ ++typedef struct mtk_stp_psm { ++ OSAL_THREAD PSMd; /* main thread (wmtd) handle */ ++ OSAL_EVENT STPd_event; ++ ++ OSAL_OP_Q rFreeOpQ; /* free op queue */ ++ OSAL_OP_Q rActiveOpQ; /* active op queue */ ++ OSAL_OP arQue[STP_OP_BUF_SIZE]; /* real op instances */ ++ ++ /* OSAL_OP current_active_op; */ ++ /* P_OSAL_OP current_active_op; */ ++ UINT32 last_active_opId; ++ MTKSTP_PSM_STATE_T work_state; /*working state */ ++ OSAL_BIT_OP_VAR flag; ++ ++ /* in normal cases, sleep op is always enabled; ++ * but in error cases, we can't execute sleep cmd, ++ * Eg: FW assert, core dump ++ */ ++ INT32 sleep_en; ++ ++/* OSAL_UNSLEEPABLE_LOCK flagSpinlock; */ ++ INT32 idle_time_to_sleep; ++ OSAL_WAKE_LOCK wake_lock; ++ OSAL_TIMER psm_timer; /*monitor if active */ ++ OSAL_EVENT wait_wmt_q; ++ OSAL_FIFO hold_fifo; ++ OSAL_SLEEPABLE_LOCK hold_fifo_spinlock_global; ++ OSAL_UNSLEEPABLE_LOCK wq_spinlock; ++ OSAL_SLEEPABLE_LOCK stp_psm_lock; ++ INT32 (*wmt_notify)(MTKSTP_PSM_ACTION_T action); ++ INT32 (*stp_tx_cb)(unsigned char *buffer, UINT32 length, UINT8 type); ++ ++ MTK_WCN_BOOL (*is_wmt_quick_ps_support)(VOID); ++ UINT8 out_buf[STP_PSM_TX_SIZE]; ++} MTKSTP_PSM_T; ++ ++typedef struct { ++ UINT32 prev_flag; ++ UINT32 cur_flag; ++ UINT32 line_num; ++ UINT32 package_no; ++ UINT32 sec; ++ UINT32 usec; ++ UINT32 pid; ++} STP_PSM_ENTRY_T; ++ ++typedef struct stp_psm_record { ++ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; ++ UINT32 in; ++ UINT32 out; ++ UINT32 size; ++ OSAL_UNSLEEPABLE_LOCK lock; ++} STP_PSM_RECORD_T; ++ ++typedef struct stp_psm_opid_record { ++ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; ++ UINT32 in; ++ UINT32 out; ++ UINT32 size; ++ OSAL_UNSLEEPABLE_LOCK lock; ++} STP_PSM_OPID_RECORD, *P_STP_PSM_OPID_RECORD; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#define PSM_USE_COUNT_PACKAGE 0 ++ ++#if PSM_USE_COUNT_PACKAGE ++#define MTK_COMBO_PSM_RX_TH_DEFAULT (1600) ++#define MTK_COMBO_PSM_TX_TH_DEFAULT (300) ++INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir); ++#else ++#define SAMPLE_DURATION 1 /*1 second */ ++#define RTX_SPEED_THRESHOLD 50000 /*50KB/s */ ++INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*stp-psm external function*/ ++INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); ++INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm); ++ ++INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type); ++INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep); ++struct mtk_stp_psm *stp_psm_init(void); ++INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm); ++MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel); ++INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state); ++MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID); ++ ++INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm); ++INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h +new file mode 100644 +index 000000000000..eaa5ce773e33 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h +@@ -0,0 +1,629 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _STP_CORE_H ++#define _STP_CORE_H ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "stp_exp.h" ++#include "psm_core.h" ++#include "btm_core.h" ++#include "stp_btif.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CFG_STP_CORE_CTX_SPIN_LOCK (0) ++ ++#define WMT_LTE_COEX_FLAG (0x16) ++ ++/*configure using SPINLOCK or just mutex for STP-CORE tx*/ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define CONFIG_POWER_SAVING_SUPPORT ++ ++#ifdef PFX ++#undef PFX ++#endif ++#define PFX "[STP] " ++ ++#define STP_LOG_DBG 4 ++#define STP_LOG_PKHEAD 3 ++#define STP_LOG_INFO 2 ++#define STP_LOG_WARN 1 ++#define STP_LOG_ERR 0 ++ ++extern unsigned int gStpDbgLvl; ++ ++#define STP_DBG_FUNC(fmt, arg...)\ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_DBG) \ ++ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_INFO) \ ++ osal_dbg_print(PFX "%s:[I] " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_WARN) \ ++ osal_warn_print(PFX "%s:[W] " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_ERR) \ ++ osal_err_print(PFX "%s:[E] " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_TRC_FUNC(f) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_DBG) \ ++ osal_dbg_print(PFX "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++#define STP_DUMP_PACKET_HEAD(a, b, c) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_PKHEAD) \ ++ stp_dump_data(a, b, c); \ ++} while (0) ++#define STP_TRACE_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgLvl >= STP_LOG_DBG) \ ++ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++ ++#define STP_MODE_BIT(x) (0x1UL << x) ++#define MTKSTP_UART_FULL_MODE STP_MODE_BIT(0) ++#define MTKSTP_UART_MAND_MODE STP_MODE_BIT(1) ++#define MTKSTP_BTIF_FULL_MODE STP_MODE_BIT(2) ++#define MTKSTP_BTIF_MAND_MODE STP_MODE_BIT(3) ++#define MTKSTP_SDIO_MODE STP_MODE_BIT(4) ++ ++#define MTKSTP_BUFFER_SIZE (16384) ++ ++/*To check function driver's status by the the interface*/ ++/*Operation definition*/ ++#define OP_FUNCTION_ACTIVE 0 ++ ++/*Driver's status*/ ++#define STATUS_OP_INVALID 0 ++#define STATUS_FUNCTION_INVALID 1 ++ ++#define STATUS_FUNCTION_ACTIVE 31 ++#define STATUS_FUNCTION_INACTIVE 32 ++ ++#define MTKSTP_CRC_SIZE (2) ++#define MTKSTP_HEADER_SIZE (4) ++#define MTKSTP_SEQ_SIZE (8) ++ ++/*#define MTKSTP_WINSIZE (4)*/ ++#define MTKSTP_WINSIZE (7) ++#define MTKSTP_TX_TIMEOUT (180) /*TODO: Baudrate to decide this */ ++#define MTKSTP_RETRY_LIMIT (10) ++ ++#define INDEX_INC(idx) \ ++{ \ ++ idx++; \ ++ idx &= 0x7; \ ++} ++ ++#define INDEX_DEC(idx) \ ++{ \ ++ idx--; \ ++ idx &= 0x7; \ ++} ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef INT32(*IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); ++/* event/signal */ ++typedef INT32(*EVENT_SET) (UINT8 function_type); ++typedef INT32(*EVENT_TX_RESUME) (UINT8 winspace); ++typedef INT32(*FUNCTION_STATUS) (UINT8 type, UINT8 op); ++typedef INT32(*WMT_NOTIFY_FUNC_T) (UINT32 action); ++typedef INT32(*BTM_NOTIFY_WMT_FUNC_T) (INT32); ++ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++typedef OSAL_UNSLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; ++#else ++typedef OSAL_SLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; ++#endif ++ ++typedef struct { ++ /* common interface */ ++ IF_TX cb_if_tx; ++ /* event/signal */ ++ EVENT_SET cb_event_set; ++ EVENT_TX_RESUME cb_event_tx_resume; ++ FUNCTION_STATUS cb_check_funciton_status; ++} mtkstp_callback; ++ ++typedef enum { ++ MTKSTP_SYNC = 0, ++ MTKSTP_SEQ, ++ MTKSTP_ACK, ++ MTKSTP_NAK, ++ MTKSTP_TYPE, ++ MTKSTP_LENGTH, ++ MTKSTP_CHECKSUM, ++ MTKSTP_DATA, ++ MTKSTP_CRC1, ++ MTKSTP_CRC2, ++ MTKSTP_RESYNC1, ++ MTKSTP_RESYNC2, ++ MTKSTP_RESYNC3, ++ MTKSTP_RESYNC4, ++ MTKSTP_FW_MSG, ++} mtkstp_parser_state; ++ ++typedef struct { ++ mtkstp_parser_state state; ++ UINT8 seq; ++ UINT8 ack; ++ UINT8 nak; ++ UINT8 type; ++ UINT16 length; ++ UINT8 checksum; ++ UINT16 crc; ++#if 1 ++ UINT8 wmtsubtype; ++#endif ++} mtkstp_parser_context_struct; ++ ++typedef struct { ++ UINT8 txseq; /* last tx pkt's seq + 1 */ ++ UINT8 txack; /* last tx pkt's ack */ ++ UINT8 rxack; /* last rx pkt's ack */ ++ UINT8 winspace; /* current sliding window size */ ++ UINT8 expected_rxseq; /* last rx pkt's seq + 1 */ ++ UINT8 retry_times; ++} mtkstp_sequence_context_struct; ++ ++typedef struct { ++ /* MTK_WCN_MUTEX mtx; */ ++ OSAL_UNSLEEPABLE_LOCK mtx; ++ UINT8 buffer[MTKSTP_BUFFER_SIZE]; ++ UINT32 read_p; ++ UINT32 write_p; ++} mtkstp_ring_buffer_struct; ++ ++typedef struct { ++ UINT8 inband_rst_set; ++ UINT32 rx_counter; /* size of current processing pkt in rx_buf[] */ ++ UINT8 rx_buf[MTKSTP_BUFFER_SIZE]; /* input buffer of STP, room for current processing pkt */ ++ UINT32 tx_read; /* read ptr of tx_buf[] */ ++ UINT32 tx_write; /* write ptr of tx_buf[] */ ++ UINT8 tx_buf[MTKSTP_BUFFER_SIZE]; /* output buffer of STP */ ++ UINT32 tx_start_addr[MTKSTP_SEQ_SIZE]; /* ptr of each pkt in tx_buf[] */ ++ UINT32 tx_length[MTKSTP_SEQ_SIZE]; /* length of each pkt in tx_buf[] */ ++ mtkstp_ring_buffer_struct ring[MTKSTP_MAX_TASK_NUM]; /* ring buffers for each function driver */ ++ mtkstp_parser_context_struct parser; /* current rx pkt's content */ ++ mtkstp_sequence_context_struct sequence; /* state machine's current status */ ++ /* MTK_WCN_MUTEX stp_mutex; */ ++ /* OSAL_UNSLEEPABLE_LOCK stp_mutex; */ ++ STP_CTX_LOCK stp_mutex; ++ /* MTK_WCN_TIMER tx_timer; // timer for tx timeout handling */ ++ OSAL_TIMER tx_timer; ++ ++ MTKSTP_PSM_T *psm; ++ MTKSTP_BTM_T *btm; ++ UINT8 f_enable; /* default disabled */ ++ UINT8 f_ready; /* default non-ready */ ++ UINT8 f_pending_type; ++ UINT8 f_coredump; /*block tx flag, for now, only when f/w assert happens, we will set this bit on */ ++ UINT8 en_coredump; ++ /* Flag to identify Blueztooth is Bluez/or MTK Stack */ ++ MTK_WCN_BOOL f_bluez; ++ MTK_WCN_BOOL f_dbg_en; ++ MTK_WCN_BOOL f_autorst_en; ++ ++ /* Flag to identify STP by SDIO or UART */ ++ UINT32 f_mode; ++ ++ /* Flag to indicate the last WMT CLOSE */ ++ UINT32 f_wmt_last_close; ++ ++ /* Flag to indicate evt err has triggered assert or not */ ++ UINT32 f_evt_err_assert; ++} mtkstp_context_struct; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_init ++* DESCRIPTION ++* init STP kernel ++* PARAMETERS ++* cb_func [IN] function pointers of system APIs ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_deinit ++* DESCRIPTION ++* deinit STP kernel ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_deinit(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_enable ++* DESCRIPTION ++* enable/disable STP ++* PARAMETERS ++* value [IN] 0 = disable, others = enable ++* RETURNS ++* INT32 0 = success, others = error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_enable(INT32 value); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_ready ++* DESCRIPTION ++* ready/non-ready STP ++* PARAMETERS ++* value [IN] 0 = non-ready, others = ready ++* RETURNS ++* INT32 0 = success, others = error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_ready(INT32 value); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_ctrl ++* DESCRIPTION ++* set f/w assert flag in STP context ++* PARAMETERS ++* value [IN] 0=assert end, others=assert begins ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_get ++* DESCRIPTION ++* get f/w assert flag in STP context ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0= f/w assert flag is not set, others=f/w assert flag is set ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_coredump_start_get(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data_raw ++* DESCRIPTION ++* send raw data to common interface, bypass STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 length transmitted ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_set_sdio_mode ++* DESCRIPTION ++* Set stp for SDIO mode ++* PARAMETERS ++* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_mode(UINT32 sdio_flag); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_fullset_mode ++* DESCRIPTION ++* Is stp use UART Fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:UART Fullset, FALSE:UART Fullset ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_mand_mode ++* DESCRIPTION ++* Is stp use UART Mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:UART Mandatory, FALSE:UART Mandatory ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void); ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_fullset_mode ++* DESCRIPTION ++* Is stp use BTIF Fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Fullset, FALSE:BTIF Fullset ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_mand_mode ++* DESCRIPTION ++* Is stp use BTIF Mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Mandatory, FALSE:BTIF Mandatory ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_sdio_mode ++* DESCRIPTION ++* Is stp use SDIO mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void); ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To sync to oringnal stp state with f/w stp ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_inband_reset(void); ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To send testing command to chip ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_test_cmd(INT32 no); ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To control STP debugging mechanism ++* PARAMETERS ++* func_no: function control, func_op: dumpping filer, func_param: dumpping parameter ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_debug_ctrl(INT32 func_no, INT32 func_op, INT32 func_param); ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_flush ++* DESCRIPTION ++* flush all stp context ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_flush_context(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_rx_queue ++* DESCRIPTION ++* flush all stp rx queue ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++extern void mtk_wcn_stp_flush_rx_queue(UINT32 type); ++ ++/***************************************************************************** ++* FUNCTION ++* set stp debugging mdoe ++* DESCRIPTION ++* set stp debugging mdoe ++* PARAMETERS ++* dbg_mode: switch to dbg mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode); ++ ++/***************************************************************************** ++* FUNCTION ++* set stp auto reset mdoe ++* DESCRIPTION ++* set stp auto reset mdoe ++* PARAMETERS ++* auto_rst: switch to auto reset mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst); ++ ++/*stp_psm support*/ ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_notify_stp ++* DESCRIPTION ++* WMT notification to STP that power saving job is done or not ++* PARAMETERS ++* ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_notify_stp(const UINT32 action); ++ ++extern int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_enabla ++* DESCRIPTION ++* enable STP PSM ++* PARAMETERS ++* int idle_time_to_sleep: IDLE time to sleep ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_enable(int idle_time_to_sleep); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_disable ++* DESCRIPTION ++* disable STP PSM ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_disable(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_reset ++* DESCRIPTION ++* reset STP PSM (used on whole chip reset) ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_psm_reset(void); ++extern void stp_do_tx_timeout(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_btm_get_dmp ++* DESCRIPTION ++* get stp dump related information ++* PARAMETERS ++* buffer: dump placement, len: dump size ++* RETURNS ++* 0: Success Negative Value: Fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_btm_get_dmp(char *buf, int *len); ++ ++extern int mtk_wcn_stp_dbg_enable(void); ++ ++extern int mtk_wcn_stp_dbg_disable(void); ++ ++extern void mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type); ++ ++extern int mtk_wcn_sys_if_rx(UINT8 *data, INT32 size); ++ ++extern MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel); ++ ++extern INT32 mtk_wcn_stp_dbg_dump_package(VOID); ++ ++extern int stp_drv_init(void); ++ ++extern void stp_drv_exit(void); ++ ++extern INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on); ++ ++extern INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on); ++ ++extern INT32 mtk_wcn_stp_coredump_flag_get(VOID); ++extern INT32 mtk_wcn_stp_notify_sleep_for_thermal(void); ++ ++extern INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value); ++ ++/*stp btif API declared*/ ++extern INT32 mtk_wcn_stp_open_btif(VOID); ++extern INT32 mtk_wcn_stp_close_btif(VOID); ++extern INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb); ++extern INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len); ++extern INT32 mtk_wcn_stp_wakeup_consys(VOID); ++extern INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); ++extern INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); ++extern INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag); ++extern VOID mtk_wcn_stp_ctx_save(VOID); ++extern VOID mtk_wcn_stp_ctx_restore(VOID); ++extern INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(VOID); ++extern VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value); ++extern UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(VOID); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _STP_CORE_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h +new file mode 100644 +index 000000000000..94b3d8a597ac +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h +@@ -0,0 +1,89 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _STP_WMT_H ++#define _STP_WMT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum { ++ BTM_RST_OP = 0, ++ BTM_DMP_OP = 1, ++ BTM_GET_AEE_SUPPORT_FLAG = 2, ++ BTM_MAX_OP, ++} MTKSTP_BTM_WMT_OP_T; ++ ++typedef enum { ++ SLEEP = 0, ++ HOST_AWAKE, ++ WAKEUP, ++ EIRQ, ++ ROLL_BACK, ++ STP_PSM_MAX_ACTION ++} MTKSTP_PSM_ACTION_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++extern MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op); ++ ++extern INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action); ++extern MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _STP_WMT_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h +new file mode 100644 +index 000000000000..4c64b6b5e65b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h +@@ -0,0 +1,74 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_CONF_H_ ++#define _WMT_CONF_H_ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define CUST_CFG_WMT "WMT_SOC.cfg" ++#define CUST_CFG_WMT_PREFIX "/system/etc/firmware/" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_conf_read_file(VOID); ++P_WMT_GEN_CONF wmt_conf_get_cfg(VOID); ++INT32 wmt_conf_set_cfg_file(const char *name); ++ ++#endif /* _WMT_CONF_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h +new file mode 100644 +index 000000000000..cca52a15cc98 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h +@@ -0,0 +1,428 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_CORE_H_ ++#define _WMT_CORE_H_ ++ ++#include "osal.h" ++#include "wmt_ctrl.h" ++#include "wmt_exp.h" ++#include "wmt_plat.h" ++/* TODO: [GeorgeKuo][FixMe] remove temporarily */ ++/* for AIF state definition */ ++/* #include "mtk_wcn_cmb_stub.h" */ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++#define CFG_CORE_MT6620_SUPPORT 0 /* whether MT6620 is supported or not */ ++ ++#define CFG_CORE_MT6628_SUPPORT 0 /* whether MT6628 is supported or not */ ++ ++#define CFG_CORE_SOC_SUPPORT 1 ++ ++/* TODO:[ChangeFeature][George] move this definition outside so that wmt_dev can remove wmt_core.h inclusion. */ ++#define defaultPatchName "mt66xx_patch_hdr.bin" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define BCNT_PATCH_BUF_HEADROOM (8) ++ ++#define DWCNT_HIF_CONF (4) ++#define DWCNT_STRAP_CONF (4) ++#define DWCNT_RESERVED (8) ++#define DWCNT_CTRL_DATA (16) ++ ++#if 0 /* TODO: [obsolete][GeorgeKuo]: remove ubsolete definitions */ ++#define WMT_SET (1) ++#define WMT_QUERY (0) ++#define WMT_PKT_FMT_RAW (1) ++#define WMT_PKT_FMT_STP (0) ++#endif ++ ++#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE) ++#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE) ++ ++#define WMT_HDR_LEN (4) /* header length */ ++#define WMT_STS_LEN (1) /* status length */ ++#define WMT_FLAG_LEN (1) ++#define WMT_HIF_UART_INFO_LEN (4) ++#define WMT_FUNC_CTRL_PARAM_LEN (1) ++ ++#define WMT_DEFAULT_BAUD_RATE (115200) ++ ++#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_WMT_FM_T { ++ WMT_FM_INVALID = 0, ++ WMT_FM_I2C = 1, ++ WMT_FM_COMM = 2, ++ WMT_FM_MAX ++} ENUM_WMT_FM_T, *P_ENUM_WMT_FM_T; ++ ++typedef enum _ENUM_WMT_HIF_T { ++ WMT_HIF_UART = 0, ++ WMT_HIF_SDIO = 1, ++ WMT_HIF_BTIF = 2, ++ WMT_HIF_MAX ++} ENUM_WMT_HIF_T, *P_ENUM_WMT_HIF_T; ++ ++#if 0 /* [George] moved to wmt_exp.h for hif_sdio's use */ ++typedef enum { ++ WMT_SDIO_SLOT_INVALID = 0, ++ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ ++ WMT_SDIO_SLOT_SDIO2 = 2, ++ WMT_SDIO_SLOT_MAX ++} WMT_SDIO_SLOT_NUM; ++ ++typedef enum { ++ WMT_SDIO_FUNC_STP = 0, ++ WMT_SDIO_FUNC_WIFI = 1, ++ WMT_SDIO_FUNC_MAX ++} WMT_SDIO_FUNC_TYPE; ++#endif ++ ++typedef enum _ENUM_WMT_OPID_T { ++ WMT_OPID_HIF_CONF = 0, ++ WMT_OPID_PWR_ON = 1, ++ WMT_OPID_PWR_OFF = 2, ++ WMT_OPID_FUNC_ON = 3, ++ WMT_OPID_FUNC_OFF = 4, ++ WMT_OPID_REG_RW = 5, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ ++ WMT_OPID_EXIT = 6, ++ WMT_OPID_PWR_SV = 7, ++ WMT_OPID_DSNS = 8, ++ WMT_OPID_LPBK = 9, ++ WMT_OPID_CMD_TEST = 10, ++ WMT_OPID_HW_RST = 11, ++ WMT_OPID_SW_RST = 12, ++ WMT_OPID_BAUD_RST = 13, ++ WMT_OPID_STP_RST = 14, ++ WMT_OPID_THERM_CTRL = 15, ++ WMT_OPID_EFUSE_RW = 16, ++ WMT_OPID_GPIO_CTRL = 17, ++ WMT_OPID_FW_COREDMP = 18, ++ WMT_OPID_GPIO_STATE = 19, ++ WMT_OPID_BGW_DS = 20, ++ WMT_OPID_SET_MCU_CLK = 21, ++ WMT_OPID_ADIE_LPBK_TEST = 22, ++#if CFG_WMT_LTE_COEX_HANDLING ++ WMT_OPID_IDC_MSG_HANDLING = 23, ++#endif ++#ifdef CONFIG_MTK_COMBO_ANT ++ WMT_OPID_ANT_RAM_DOWN = 24, ++ WMT_OPID_ANT_RAM_STA_GET = 25, ++#endif ++ WMT_OPID_MAX ++} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T; ++ ++typedef OSAL_OP_DAT WMT_OP; ++typedef P_OSAL_OP_DAT P_WMT_OP; ++ ++typedef struct _WMT_HIF_CONF { ++ UINT32 hifType; /* HIF Type */ ++ UINT32 au4HifConf[DWCNT_HIF_CONF]; /* HIF Config */ ++ UINT32 au4StrapConf[DWCNT_STRAP_CONF]; /* Strap Config */ ++} WMT_HIF_CONF, *P_WMT_HIF_CONF; ++ ++typedef INT32(*WMT_OPID_FUNC) (P_WMT_OP); ++ ++typedef struct _WMT_GEN_CONF { ++ UINT8 cfgExist; ++ ++ UINT8 coex_wmt_ant_mode; ++ UINT8 coex_wmt_ext_component; ++ UINT8 coex_wmt_wifi_time_ctl; ++ UINT8 coex_wmt_ext_pta_dev_on; ++ /*mt6592 and LTE coex filter mode setting */ ++ UINT8 coex_wmt_filter_mode; ++ ++ UINT8 coex_bt_rssi_upper_limit; ++ UINT8 coex_bt_rssi_mid_limit; ++ UINT8 coex_bt_rssi_lower_limit; ++ UINT8 coex_bt_pwr_high; ++ UINT8 coex_bt_pwr_mid; ++ UINT8 coex_bt_pwr_low; ++ ++ UINT8 coex_wifi_rssi_upper_limit; ++ UINT8 coex_wifi_rssi_mid_limit; ++ UINT8 coex_wifi_rssi_lower_limit; ++ UINT8 coex_wifi_pwr_high; ++ UINT8 coex_wifi_pwr_mid; ++ UINT8 coex_wifi_pwr_low; ++ ++ UINT8 coex_ext_pta_hi_tx_tag; ++ UINT8 coex_ext_pta_hi_rx_tag; ++ UINT8 coex_ext_pta_lo_tx_tag; ++ UINT8 coex_ext_pta_lo_rx_tag; ++ UINT16 coex_ext_pta_sample_t1; ++ UINT16 coex_ext_pta_sample_t2; ++ UINT8 coex_ext_pta_wifi_bt_con_trx; ++ ++ UINT32 coex_misc_ext_pta_on; ++ UINT32 coex_misc_ext_feature_set; ++ /*GPS LNA setting */ ++ UINT8 wmt_gps_lna_pin; ++ UINT8 wmt_gps_lna_enable; ++ /*Power on sequence */ ++ UINT8 pwr_on_rtc_slot; ++ UINT8 pwr_on_ldo_slot; ++ UINT8 pwr_on_rst_slot; ++ UINT8 pwr_on_off_slot; ++ UINT8 pwr_on_on_slot; ++ UINT8 co_clock_flag; ++ ++ /* Combo chip side SDIO driving setting */ ++ UINT32 sdio_driving_cfg; ++ ++} WMT_GEN_CONF, *P_WMT_GEN_CONF; ++ ++typedef enum _ENUM_DRV_STS_ { ++#if 0 ++ DRV_STS_INVALID = 0, ++ DRV_STS_UNREG = 1, /* Initial State */ ++#endif ++ DRV_STS_POWER_OFF = 0, /* initial state */ ++ DRV_STS_POWER_ON = 1, /* powered on, only WMT */ ++ DRV_STS_FUNC_ON = 2, /* FUNC ON */ ++ DRV_STS_MAX ++} ENUM_DRV_STS, *P_ENUM_DRV_STS; ++ ++typedef enum _WMT_IC_PIN_ID_ { ++ WMT_IC_PIN_AUDIO = 0, ++ WMT_IC_PIN_EEDI = 1, ++ WMT_IC_PIN_EEDO = 2, ++ WMT_IC_PIN_GSYNC = 3, ++ WMT_IC_PIN_MAX ++} WMT_IC_PIN_ID, *P_WMT_IC_PIN_ID; ++ ++typedef enum _WMT_IC_PIN_STATE_ { ++ WMT_IC_PIN_EN = 0, ++ WMT_IC_PIN_DIS = 1, ++ WMT_IC_AIF_0 = 2, /* = CMB_STUB_AIF_0, */ ++ WMT_IC_AIF_1 = 3, /* = CMB_STUB_AIF_1, */ ++ WMT_IC_AIF_2 = 4, /* = CMB_STUB_AIF_2, */ ++ WMT_IC_AIF_3 = 5, /* = CMB_STUB_AIF_3, */ ++ WMT_IC_PIN_MUX = 6, ++ WMT_IC_PIN_GPIO = 7, ++ WMT_IC_PIN_GPIO_HIGH = 8, ++ WMT_IC_PIN_GPIO_LOW = 9, ++ WMT_IC_PIN_STATE_MAX ++} WMT_IC_PIN_STATE, *P_WMT_IC_PIN_STATE; ++ ++typedef enum _WMT_CO_CLOCK_ { ++ WMT_CO_CLOCK_DIS = 0, ++ WMT_CO_CLOCK_EN = 1, ++ WMT_CO_CLOCK_MAX ++} WMT_CO_CLOCK, *P_WMT_CO_CLOCK; ++ ++typedef INT32(*SW_INIT) (P_WMT_HIF_CONF pWmtHifConf); ++typedef INT32(*SW_DEINIT) (P_WMT_HIF_CONF pWmtHifConf); ++typedef INT32(*IC_PIN_CTRL) (WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); ++typedef INT32(*IC_VER_CHECK) (VOID); ++typedef INT32(*CO_CLOCK_CTRL) (WMT_CO_CLOCK on); ++typedef MTK_WCN_BOOL(*IS_QUICK_SLEEP_SUPPORT) (VOID); ++typedef MTK_WCN_BOOL(*IS_AEE_DUMP_SUPPORT) (VOID); ++ ++typedef struct _WMT_IC_OPS_ { ++ UINT32 icId; ++ SW_INIT sw_init; ++ SW_DEINIT sw_deinit; ++ IC_PIN_CTRL ic_pin_ctrl; ++ IC_VER_CHECK ic_ver_check; ++ CO_CLOCK_CTRL co_clock_ctrl; ++ IS_QUICK_SLEEP_SUPPORT is_quick_sleep; ++ IS_AEE_DUMP_SUPPORT is_aee_dump_support; ++} WMT_IC_OPS, *P_WMT_IC_OPS; ++ ++typedef struct _WMT_CTX_ { ++ ENUM_DRV_STS eDrvStatus[WMTDRV_TYPE_MAX]; /* Controlled driver status */ ++ UINT32 wmtInfoBit; /* valid info bit */ ++ WMT_HIF_CONF wmtHifConf; /* HIF information */ ++ ++ /* Pointer to WMT_IC_OPS. Shall be assigned to a correct table in stp_init ++ * if and only if getting chip id successfully. hwver and fwver are kept in ++ * WMT-IC module only. ++ */ ++ P_WMT_IC_OPS p_ic_ops; ++} WMT_CTX, *P_WMT_CTX; ++ ++/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ ++/* Using this struct relies on compiler's implementation and pack() settings */ ++typedef struct _WMT_PKT_ { ++ UINT8 eType; /* PKT_TYPE_* */ ++ UINT8 eOpCode; /* OPCODE_* */ ++ UINT16 u2SduLen; /* 2 bytes length, little endian */ ++ UINT8 aucParam[32]; ++} WMT_PKT, *P_WMT_PKT; ++ ++/* WMT Packet Format */ ++typedef enum _ENUM_PKT_TYPE { ++ PKT_TYPE_INVALID = 0, ++ PKT_TYPE_CMD = 1, ++ PKT_TYPE_EVENT = 2, ++ _PKT_TYPE_MAX ++} ENUM_PKT_TYPE, *P_ENUM_PKT_TYPE; ++ ++typedef enum _ENUM_OPCODE { ++ OPCODE_INVALID = 0, ++ OPCODE_PATCH = 1, ++ OPCODE_TEST = 2, ++ OPCODE_WAKEUP = 3, ++ OPCODE_HIF = 4, ++ OPCODE_STRAP_CONF = 5, ++ OPCODE_FUNC_CTRL = 6, ++ OPCODE_RESET = 7, ++ OPCODE_INT = 8, ++ OPCODE_MAX ++} ENUM_OPCODE, *P_ENUM_OPCODE; ++ ++typedef enum { ++ WMT_STP_CONF_EN = 0, ++ WMT_STP_CONF_RDY = 1, ++ WMT_STP_CONF_MODE = 2, ++ WMT_STP_CONF_MAX ++} WMT_STP_CONF_TYPE; ++ ++struct init_script { ++ UINT8 *cmd; ++ UINT32 cmdSz; ++ UINT8 *evt; ++ UINT32 evtSz; ++ UINT8 *str; ++}; ++ ++typedef struct _WMT_PATCH { ++ UINT8 ucDateTime[16]; ++ UINT8 ucPLat[4]; ++ UINT16 u2HwVer; ++ UINT16 u2SwVer; ++ UINT32 u4PatchVer; ++} WMT_PATCH, *P_WMT_PATCH; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if CFG_CORE_MT6620_SUPPORT ++extern WMT_IC_OPS wmt_ic_ops_mt6620; ++#endif ++ ++#if CFG_CORE_MT6628_SUPPORT ++extern WMT_IC_OPS wmt_ic_ops_mt6628; ++#endif ++ ++#if CFG_CORE_SOC_SUPPORT ++extern WMT_IC_OPS wmt_ic_ops_soc; ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern INT32 wmt_core_init(VOID); ++extern INT32 wmt_core_deinit(VOID); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_wmtd ++* DESCRIPTION ++* deinit STP kernel ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++extern INT32 wmt_core_opid(P_WMT_OP pWmtOp); ++ ++extern INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2); ++ ++extern INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn); ++ ++extern INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask); ++ ++extern VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len); ++ ++extern MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer); ++ ++extern INT32 wmt_core_init_script(struct init_script *script, INT32 count); ++ ++extern INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize); ++ ++extern INT32 wmt_core_tx(const PUINT8 pData, UINT32 size, PUINT32 writtenSize, MTK_WCN_BOOL bRawFlag); ++extern MTK_WCN_BOOL wmt_core_is_quick_ps_support(void); ++ ++extern MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void); ++ ++#if CFG_CORE_INTERNAL_TXRX ++extern INT32 wmt_core_lpbk_do_stp_init(void); ++extern INT32 wmt_core_lpbk_do_stp_deinit(void); ++#endif ++ ++extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state); ++#if CFG_WMT_LTE_COEX_HANDLING ++extern VOID wmt_core_set_flag_for_test(UINT32 enable); ++extern UINT32 wmt_core_get_flag_for_test(VOID); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static _osal_inline_ MTK_WCN_BOOL wmt_core_ic_ops_check(P_WMT_IC_OPS p_ops) ++{ ++ if (!p_ops) ++ return MTK_WCN_BOOL_FALSE; ++ ++ if ((NULL == p_ops->sw_init) ++ || (NULL == p_ops->sw_deinit) ++ || (NULL == p_ops->ic_ver_check) ++ || (NULL == p_ops->ic_pin_ctrl)) ++ return MTK_WCN_BOOL_FALSE; ++ else ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++#endif /* _WMT_CORE_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h +new file mode 100644 +index 000000000000..0ff3d6058c39 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h +@@ -0,0 +1,120 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_CTRL_H_ ++#define _WMT_CTRL_H_ ++ ++#include "osal.h" ++#include "wmt_stp_exp.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define DWCNT_CTRL_DATA (16) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _WMT_CTRL_DATA_ { ++ SIZE_T ctrlId; ++ SIZE_T au4CtrlData[DWCNT_CTRL_DATA]; ++} WMT_CTRL_DATA, *P_WMT_CTRL_DATA; ++ ++typedef enum _ENUM_WMT_CTRL_T { ++ WMT_CTRL_HW_PWR_OFF = 0, /* whole chip power off */ ++ WMT_CTRL_HW_PWR_ON = 1, /* whole chip power on */ ++ WMT_CTRL_HW_RST = 2, /* whole chip rst */ ++ WMT_CTRL_STP_CLOSE = 3, ++ WMT_CTRL_STP_OPEN = 4, ++ WMT_CTRL_STP_CONF = 5, ++ WMT_CTRL_FREE_PATCH = 6, ++ WMT_CTRL_GET_PATCH = 7, ++ WMT_CTRL_GET_PATCH_NAME = 8, ++ WMT_CTRL_HWIDVER_SET = 9, /* TODO: rename this and add chip id information in addition to chip version */ ++ WMT_CTRL_STP_RST = 10, ++ WMT_CTRL_GET_WMT_CONF = 11, ++ WMT_CTRL_TX = 12, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ ++ WMT_CTRL_RX = 13, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ ++ WMT_CTRL_RX_FLUSH = 14, /* [FixMe][SeanWang]: to be removed by Sean's stp integration */ ++ WMT_CTRL_GPS_SYNC_SET = 15, ++ WMT_CTRL_GPS_LNA_SET = 16, ++ WMT_CTRL_PATCH_SEARCH = 17, ++ WMT_CTRL_CRYSTAL_TRIMING_GET = 18, ++ WMT_CTRL_CRYSTAL_TRIMING_PUT = 19, ++ WMT_CTRL_HW_STATE_DUMP = 20, ++ WMT_CTRL_GET_PATCH_NUM = 21, ++ WMT_CTRL_GET_PATCH_INFO = 22, ++ WMT_CTRL_SOC_PALDO_CTRL = 23, ++ WMT_CTRL_SOC_WAKEUP_CONSYS = 24, ++ WMT_CTRL_SET_STP_DBG_INFO = 25, ++ WMT_CTRL_BGW_DESENSE_CTRL = 26, ++ WMT_CTRL_EVT_ERR_TRG_ASSERT = 27, ++#if CFG_WMT_LTE_COEX_HANDLING ++ WMT_CTRL_GET_TDM_REQ_ANTSEL = 28, ++#endif ++ WMT_CTRL_EVT_PARSER = 29, ++ WMT_CTRL_MAX ++} ENUM_WMT_CTRL_T, *P_ENUM_WMT_CTRL_T; ++ ++typedef INT32(*WMT_CTRL_FUNC) (P_WMT_CTRL_DATA); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData); ++ ++extern INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_CTRL_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h +new file mode 100644 +index 000000000000..d586f442e7ef +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h +@@ -0,0 +1,140 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_FUNC_H_ ++#define _WMT_FUNC_H_ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_core.h" ++#include "wmt_plat.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_HCI_DRIVER) || defined(CONFIG_MTK_COMBO_BT) */ ++#define CFG_FUNC_BT_SUPPORT 1 ++#else ++#define CFG_FUNC_BT_SUPPORT 0 ++#endif ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_FM) */ ++#define CFG_FUNC_FM_SUPPORT 1 ++#else ++#define CFG_FUNC_FM_SUPPORT 0 ++#endif ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_GPS) */ ++#define CFG_FUNC_GPS_SUPPORT 1 ++#else ++#define CFG_FUNC_GPS_SUPPORT 0 ++#endif ++ ++#if 1 /* defined(CONFIG_MTK_COMBO_WIFI) */ ++#define CFG_FUNC_WIFI_SUPPORT 1 ++#else ++#define CFG_FUNC_WIFI_SUPPORT 0 ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef INT32(*SUBSYS_FUNC_ON) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++typedef INT32(*SUBSYS_FUNC_OFF) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++typedef struct _WMT_FUNC_OPS_ { ++ SUBSYS_FUNC_ON func_on; ++ SUBSYS_FUNC_OFF func_off; ++} WMT_FUNC_OPS, *P_WMT_FUNC_OPS; ++ ++typedef struct _CMB_PIN_CTRL_REG_ { ++ UINT32 regAddr; ++ UINT32 regValue; ++ UINT32 regMask; ++ ++} CMB_PIN_CTRL_REG, *P_CMB_PIN_CTRL_REG; ++ ++typedef struct _CMB_PIN_CTRL_ { ++ UINT32 pinId; ++ UINT32 regNum; ++ P_CMB_PIN_CTRL_REG pFuncOnArray; ++ P_CMB_PIN_CTRL_REG pFuncOffArray; ++ ++} CMB_PIN_CTRL, *P_CMB_PIN_CTRL; ++ ++typedef enum _ENUM_CMP_PIN_ID_ { ++ CMB_PIN_EEDI_ID = 0, ++ CMB_PIN_EEDO_ID = 1, ++ CMB_PIN_GSYNC_ID = 2, ++} ENUM_CMP_PIN_ID, *P_ENUM_CMP_PIN_ID; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if CFG_FUNC_BT_SUPPORT ++extern WMT_FUNC_OPS wmt_func_bt_ops; ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++extern WMT_FUNC_OPS wmt_func_fm_ops; ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++extern WMT_FUNC_OPS wmt_func_gps_ops; ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++extern WMT_FUNC_OPS wmt_func_wifi_ops; ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_FUNC_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h +new file mode 100644 +index 000000000000..901becfdb92f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h +@@ -0,0 +1,122 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_IC_H_ ++#define _WMT_IC_H_ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "wmt_core.h" ++#include "wmt_exp.h" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define WMT_IC_NAME_MT6620 "MT6620" ++#define WMT_IC_NAME_MT6628 "MT6628" ++#define WMT_IC_NAME_DEFAULT "SOC_CONSYS" ++ ++#define WMT_IC_VER_E1 "E1" ++#define WMT_IC_VER_E2 "E2" ++#define WMT_IC_VER_E3 "E3" ++#define WMT_IC_VER_E4 "E4" ++#define WMT_IC_VER_E5 "E5" ++#define WMT_IC_VER_E6 "E6" ++ ++#define WMT_IC_PATCH_DUMMY_EXT "_ex" ++#define WMT_IC_PATCH_NO_EXT "" ++#define WMT_IC_PATCH_E1_EXT "_e1" ++#define WMT_IC_PATCH_E2_EXT "_e2" ++#define WMT_IC_PATCH_E3_EXT "_e3" ++#define WMT_IC_PATCH_E4_EXT "_e4" ++#define WMT_IC_PATCH_E5_EXT "_e5" ++#define WMT_IC_PATCH_E6_EXT "_e6" ++ ++#define WMT_IC_PATCH_TAIL "_hdr.bin" ++ ++#define WMT_IC_INVALID_CHIP_ID 0xFFFF ++ ++#define MAJORNUM(x) (x & 0x00F0) ++#define MINORNUM(x) (x & 0x000F) ++ ++/******************************************************************************* ++* R E G I S T E R M A P ++******************************************************************************** ++*/ ++/* General definition used for ALL/UNKNOWN CHIPS */ ++/* Now MT6620 uses these definitions */ ++#define GEN_CONFG_BASE (0x80000000UL) ++#define GEN_HVR (GEN_CONFG_BASE + 0x0UL) /* HW_VER */ ++#define GEN_FVR (GEN_CONFG_BASE + 0x4UL) /* FW_VER */ ++#define GEN_VER_MASK (0x0000FFFFUL) /* HW_VER and FW_VER valid bits mask */ ++#define GEN_HCR (GEN_CONFG_BASE + 0x8UL) /* HW_CODE, chip id */ ++#define GEN_HCR_MASK (0x0000FFFFUL) /* HW_CODE valid bits mask */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _WMT_IC_INFO_S { ++ UINT32 u4HwVer; /* u4HwId */ ++ PUINT8 cChipName; ++ PUINT8 cChipVersion; ++ PUINT8 cPatchNameExt; ++ MTK_WCN_BOOL bPsmSupport; ++ MTK_WCN_BOOL bWorkWithoutPatch; ++ ENUM_WMTHWVER_TYPE_T eWmtHwVer; ++} WMT_IC_INFO_S, *P_WMT_IC_INFO_S; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_IC_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h +new file mode 100644 +index 000000000000..b0c05cf3a252 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h +@@ -0,0 +1,300 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_LIB_H_ ++#define _WMT_LIB_H_ ++ ++#include "osal.h" ++#include "wmt_core.h" ++#include "wmt_exp.h" ++#include ++#include "stp_wmt.h" ++#include "wmt_plat.h" ++#include "wmt_idc.h" ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define WMT_OP_BUF_SIZE (16) ++ ++typedef enum _ENUM_WMTRSTRET_TYPE_T { ++ WMTRSTRET_SUCCESS = 0x0, ++ WMTRSTRET_FAIL = 0x1, ++ WMTRSTRET_ONGOING = 0x2, ++ WMTRSTRET_MAX ++} ENUM_WMTRSTRET_TYPE_T, *P_ENUM_WMTRSTRET_TYPE_T; ++ ++/* ++3(retry times) * 180 (STP retry time out) +++ 10 (firmware process time) + ++10 (transmit time) + ++10 (uart process -> WMT response pool) + ++230 (others) ++*/ ++#define WMT_LIB_RX_TIMEOUT 20000 /*800-->cover v1.2phone BT function on time (~830ms) */ ++/* ++open wifi during wifi power on procedure ++(because wlan is insert to system after mtk_hif_sdio module, ++so wifi card is not registered to hif module ++when mtk_wcn_wmt_func_on is called by wifi through rfkill) ++*/ ++#define MAX_WIFI_ON_TIME 55000 ++ ++#define WMT_PWRON_RTY_DFT 2 ++#define MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT (WMT_PWRON_RTY_DFT * WMT_LIB_RX_TIMEOUT) ++#define MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY WMT_LIB_RX_TIMEOUT /*each WMT command */ ++#define MAX_FUNC_ON_TIME \ ++ (MAX_WIFI_ON_TIME + MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT + MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY * 3) ++ ++#define MAX_EACH_FUNC_OFF (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ ++#define MAX_FUNC_OFF_TIME (MAX_EACH_FUNC_OFF * 4) ++ ++#define MAX_EACH_WMT_CMD (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ ++ ++#define MAX_GPIO_CTRL_TIME (2000) /* [FixMe][GeorgeKuo] a temp value */ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* AIF FLAG definition */ ++/* bit(0): share pin or not */ ++#define WMT_LIB_AIF_FLAG_MASK (0x1UL) ++#define WMT_LIB_AIF_FLAG_SHARE (0x1UL << 0) ++#define WMT_LIB_AIF_FLAG_SEPARATE (0x0UL << 0) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* bit field offset definition */ ++typedef enum { ++ WMT_STAT_PWR = 0, /* is powered on */ ++ WMT_STAT_STP_REG = 1, /* is STP driver registered: */ ++ WMT_STAT_STP_OPEN = 2, /* is STP opened: default FALSE */ ++ WMT_STAT_STP_EN = 3, /* is STP enabled: default FALSE */ ++ WMT_STAT_STP_RDY = 4, /* is STP ready for client: default FALSE */ ++ WMT_STAT_RX = 5, /* is rx data available */ ++ WMT_STAT_CMD = 6, /* is cmd string to be read */ ++ WMT_STAT_RST_ON = 7, ++ WMT_STAT_MAX ++} WMT_STAT; ++ ++typedef enum _ENUM_WMTRSTSRC_TYPE_T { ++ WMTRSTSRC_RESET_BT = 0x0, ++ WMTRSTSRC_RESET_FM = 0x1, ++ WMTRSTSRC_RESET_GPS = 0x2, ++ WMTRSTSRC_RESET_WIFI = 0x3, ++ WMTRSTSRC_RESET_STP = 0x4, ++ WMTRSTSRC_RESET_TEST = 0x5, ++ WMTRSTSRC_RESET_MAX ++} ENUM_WMTRSTSRC_TYPE_T, *P_ENUM_WMTRSTSRC_TYPE_T; ++ ++typedef struct { ++ PF_WMT_CB fDrvRst[4]; ++} WMT_FDRV_CB, *P_WMT_FDRV_CB; ++ ++typedef struct { ++ UINT32 dowloadSeq; ++ UINT8 addRess[4]; ++ UINT8 patchName[256]; ++} WMT_PATCH_INFO, *P_WMT_PATCH_INFO; ++ ++/* OS independent wrapper for WMT_OP */ ++typedef struct _DEV_WMT_ { ++ ++ OSAL_SLEEPABLE_LOCK psm_lock; ++ OSAL_SLEEPABLE_LOCK idc_lock; ++ /* WMTd thread information */ ++ /* struct task_struct *pWmtd; */ ++ OSAL_THREAD thread; /* main thread (wmtd) handle */ ++ /* wait_queue_head_t rWmtdWq; */ ++ OSAL_EVENT rWmtdWq; /*WMTd command wait queue */ ++ /* ULONG state; */ ++ OSAL_BIT_OP_VAR state; /* bit field of WMT_STAT */ ++ ++ /* STP context information */ ++ /* wait_queue_head_t rWmtRxWq; */ ++ OSAL_EVENT rWmtRxWq; /* STP Rx wait queue */ ++ /* WMT_STP_FUNC rStpFunc; */ ++ WMT_FDRV_CB rFdrvCb; /* STP functions */ ++ ++ /* WMT Configurations */ ++ WMT_HIF_CONF rWmtHifConf; ++ WMT_GEN_CONF rWmtGenConf; ++ ++ /* Patch information */ ++ UINT8 cPatchName[NAME_MAX + 1]; ++ UINT8 cFullPatchName[NAME_MAX + 1]; ++ UINT32 patchNum; ++ ++ const osal_firmware *pPatch; ++ ++ UINT8 cWmtcfgName[NAME_MAX + 1]; ++ const osal_firmware *pWmtCfg; ++ ++ const osal_firmware *pNvram; ++ ++ /* Current used UART port description */ ++ INT8 cUartName[NAME_MAX + 1]; ++ ++ OSAL_OP_Q rFreeOpQ; /* free op queue */ ++ OSAL_OP_Q rActiveOpQ; /* active op queue */ ++ OSAL_OP arQue[WMT_OP_BUF_SIZE]; /* real op instances */ ++ P_OSAL_OP pCurOP; /* current op */ ++ ++ /* cmd str buffer */ ++ UINT8 cCmd[NAME_MAX + 1]; ++ INT32 cmdResult; ++ /* struct completion cmd_comp; */ ++ /* wait_queue_head_t cmd_wq; */ ++ OSAL_SIGNAL cmdResp; /* read command queues */ ++ OSAL_EVENT cmdReq; ++ ++ /* WMT loopback Thread Information */ ++ /* WMT_CMB_VER combo_ver; */ ++ /* P_WMT_CMB_CHIP_INFO_S pChipInfo; */ ++ UINT32 chip_id; ++ UINT32 hw_ver; ++ UINT32 fw_ver; ++ /* TODO: [FixMe][GeorgeKuo] remove this translated version code in the */ ++ /* future. Just return the above 3 info to querist */ ++ ENUM_WMTHWVER_TYPE_T eWmtHwVer; ++ ++ P_WMT_PATCH_INFO pWmtPatchInfo; ++} DEV_WMT, *P_DEV_WMT; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern DEV_WMT gDevWmt; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++extern INT32 wmt_lib_init(VOID); ++extern INT32 wmt_lib_deinit(VOID); ++extern INT32 wmt_lib_tx(PUINT8 data, UINT32 size, PUINT32 writtenSize); ++extern INT32 wmt_lib_tx_raw(PUINT8 data, UINT32 size, PUINT32 writtenSize); ++extern INT32 wmt_lib_rx(PUINT8 buff, UINT32 buffLen, PUINT32 readSize); ++extern VOID wmt_lib_flush_rx(VOID); ++ ++#if CFG_WMT_PS_SUPPORT ++extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime); ++extern INT32 wmt_lib_ps_init(VOID); ++extern INT32 wmt_lib_ps_deinit(VOID); ++extern INT32 wmt_lib_ps_enable(VOID); ++extern INT32 wmt_lib_ps_ctrl(UINT32 state); ++ ++extern INT32 wmt_lib_ps_disable(VOID); ++extern VOID wmt_lib_ps_irq_cb(VOID); ++#endif ++extern VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb); ++ ++/* LXOP functions: */ ++extern P_OSAL_OP wmt_lib_get_free_op(VOID); ++extern INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp); ++extern MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp); ++ ++/* extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); */ ++extern UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T type); ++ ++extern MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID); ++extern MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID); ++extern INT32 wmt_lib_trigger_cmd_signal(INT32 result); ++extern PUINT8 wmt_lib_get_cmd(VOID); ++extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID); ++extern INT32 wmt_lib_set_patch_name(PUINT8 cPatchName); ++extern INT32 wmt_lib_set_hif(unsigned long hifconf); ++extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID); ++extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID); ++ ++/* GeorgeKuo: replace set_chip_gpio() with more specific ones */ ++#if 0 /* moved to wmt_exp.h */ ++extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ ++#endif ++extern INT32 wmt_lib_host_awake_get(VOID); ++extern INT32 wmt_lib_host_awake_put(VOID); ++extern UINT32 wmt_lib_dbg_level_set(UINT32 level); ++ ++extern INT32 wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++ ++extern INT32 wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src); ++MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst); ++MTK_WCN_BOOL wmt_lib_hw_rst(VOID); ++INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); ++INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); ++ ++extern INT32 DISABLE_PSM_MONITOR(void); ++extern VOID ENABLE_PSM_MONITOR(void); ++extern INT32 wmt_lib_notify_stp_sleep(void); ++extern void wmt_lib_psm_lock_release(void); ++extern INT32 wmt_lib_psm_lock_aquire(void); ++extern VOID wmt_lib_idc_lock_release(VOID); ++extern INT32 wmt_lib_idc_lock_aquire(VOID); ++extern INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value); ++ ++extern VOID wmt_lib_set_patch_num(UINT32 num); ++extern VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo); ++extern INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp); ++extern P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev); ++extern PUINT8 wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, PUINT8 buff, UINT32 len); ++extern INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee); ++extern PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 len); ++extern INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl); ++extern UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en); ++extern INT8 wmt_lib_co_clock_get(VOID); ++extern UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver); ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++extern MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor); ++#endif ++#if CFG_WMT_PS_SUPPORT ++extern UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en); ++#endif ++#if CONSYS_ENALBE_SET_JTAG ++extern UINT32 wmt_lib_jtag_flag_set(UINT32 en); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_LIB_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c +new file mode 100644 +index 000000000000..c826c513e2bd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c +@@ -0,0 +1,1890 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "psm_core.h" ++#include "stp_core.h" ++#include ++ ++INT32 gPsmDbgLevel = STP_PSM_LOG_INFO; ++MTKSTP_PSM_T stp_psm_i; ++MTKSTP_PSM_T *stp_psm = &stp_psm_i; ++ ++STP_PSM_RECORD_T *g_stp_psm_dbg = NULL; ++static UINT32 g_record_num; ++ ++P_STP_PSM_OPID_RECORD g_stp_psm_opid_dbg = NULL; ++static UINT32 g_opid_record_num; ++ ++#define STP_PSM_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) \ ++ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ ++ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_INFO) \ ++ pr_debug(PFX_PSM "[I]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_WARN) \ ++ pr_warn(PFX_PSM "[W]%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_PSM_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_ERR) \ ++ pr_err(PFX_PSM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define STP_PSM_TRC_FUNC(f) \ ++do { \ ++ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ ++ pr_debug(PFX_PSM "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); ++static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); ++static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); ++static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num); ++static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg); ++ ++static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num); ++static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg); ++ ++static const char *g_psm_state[STP_PSM_MAX_STATE] = { ++ "ACT", ++ "ACT_INACT", ++ "INACT", ++ "INACT_ACT" ++}; ++ ++static const char *g_psm_action[STP_PSM_MAX_ACTION] = { ++ "SLEEP", ++ "HOST_AWAKE", ++ "WAKEUP", ++ "EIRQ", ++ "ROLL_BACK" ++}; ++ ++static const char *g_psm_op_name[STP_OPID_PSM_NUM] = { ++ "STP_OPID_PSM_SLEEP", ++ "STP_OPID_PSM_WAKEUP", ++ "STP_OPID_PSM_HOST_AWAKE", ++ "STP_OPID_PSM_EXIT" ++}; ++ ++static int _stp_psm_release_data(MTKSTP_PSM_T *stp_psm); ++ ++static inline int _stp_psm_get_state(MTKSTP_PSM_T *stp_psm); ++ ++static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ); ++ ++static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ); ++static MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID); ++ ++MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel) ++{ ++ if (dbglevel <= 4) { ++ gPsmDbgLevel = dbglevel; ++ STP_PSM_INFO_FUNC("gPsmDbgLevel = %d\n", gPsmDbgLevel); ++ return true; ++ } ++ STP_PSM_INFO_FUNC("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel); ++ ++ return false; ++} ++ ++static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp) ++{ ++ INT32 ret = -1; ++ ++ /* if (NULL == pStpOp) */ ++ /* { */ ++ /* return -1; */ ++ /* } */ ++ ret = _stp_psm_thread_lock_aquire(stp_psm); ++ if (ret) { ++ STP_PSM_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); ++ return ret; ++ } ++ ++ switch (pStpOp->opId) { ++ case STP_OPID_PSM_EXIT: ++ /* TODO: clean all up? */ ++ ret = 0; ++ break; ++ ++ case STP_OPID_PSM_SLEEP: ++ if (stp_psm_check_sleep_enable(stp_psm) > 0) ++ ret = _stp_psm_notify_wmt(stp_psm, SLEEP); ++ else ++ STP_PSM_INFO_FUNC("cancel sleep request\n"); ++ ++ break; ++ ++ case STP_OPID_PSM_WAKEUP: ++ ret = _stp_psm_notify_wmt(stp_psm, WAKEUP); ++ break; ++ ++ case STP_OPID_PSM_HOST_AWAKE: ++ ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE); ++ break; ++ ++ default: ++ STP_PSM_ERR_FUNC("invalid operation id (%d)\n", pStpOp->opId); ++ ret = -1; ++ break; ++ } ++ _stp_psm_thread_lock_release(stp_psm); ++ return ret; ++} ++ ++static P_OSAL_OP _stp_psm_get_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ) ++{ ++ P_OSAL_OP pOp; ++ ++ if (!pOpQ) { ++ STP_PSM_WARN_FUNC("pOpQ == NULL\n"); ++ return NULL; ++ } ++ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ /* acquire lock success */ ++ RB_GET(pOpQ, pOp); ++ ++ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) { ++ /* stp_psm->current_active_op = pOp; */ ++ stp_psm->last_active_opId = pOp->op.opId; ++ } ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ ++ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) ++ STP_PSM_DBG_FUNC("last_active_opId(%d)\n", stp_psm->last_active_opId); ++ ++ if (!pOp) ++ STP_PSM_WARN_FUNC("RB_GET fail\n"); ++ ++ return pOp; ++} ++ ++static INT32 _stp_psm_dump_active_q(P_OSAL_OP_Q pOpQ) ++{ ++ UINT32 read_idx; ++ UINT32 write_idx; ++ UINT32 opId; ++ ++ if (pOpQ == &stp_psm->rActiveOpQ) { ++ read_idx = stp_psm->rActiveOpQ.read; ++ write_idx = stp_psm->rActiveOpQ.write; ++ ++ STP_PSM_DBG_FUNC("Active op list:++\n"); ++ while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ))) { ++ opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId; ++ if (opId < STP_OPID_PSM_NUM) ++ STP_PSM_DBG_FUNC("%s\n", g_psm_op_name[opId]); ++ else ++ STP_PSM_WARN_FUNC("Unknown OP Id\n"); ++ ++ ++read_idx; ++ } ++ STP_PSM_DBG_FUNC("Active op list:--\n"); ++ } else { ++ STP_PSM_DBG_FUNC("%s: not active queue, dont dump\n", __func__); ++ } ++ ++ return 0; ++} ++ ++static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ) ++{ ++ unsigned int opId = 0; ++ unsigned int prev_opId = 0; ++ ++ /* if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op)) */ ++ if ((pOpQ == &stp_psm->rActiveOpQ) && (STP_OPID_PSM_INALID != stp_psm->last_active_opId)) { ++ opId = pOp->op.opId; ++ ++ if (opId == STP_OPID_PSM_SLEEP) { ++ if (RB_EMPTY(pOpQ)) { ++ /* prev_opId = stp_psm->current_active_op->op.opId; */ ++ prev_opId = stp_psm->last_active_opId; ++ } else { ++ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; ++ } ++ ++ if (prev_opId == STP_OPID_PSM_SLEEP) { ++ STP_PSM_DBG_FUNC("redundant sleep opId found\n"); ++ return 1; ++ } else { ++ return 0; ++ } ++ } else { ++ if (RB_EMPTY(pOpQ)) { ++ /* prev_opId = stp_psm->current_active_op->op.opId; */ ++ prev_opId = stp_psm->last_active_opId; ++ } else { ++ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; ++ } ++ ++ if (((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_WAKEUP)) || ++ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_WAKEUP)) || ++ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) || ++ ((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) ++ ) { ++ STP_PSM_DBG_FUNC("redundant opId found, opId(%d), preOpid(%d)\n", opId, prev_opId); ++ return 1; ++ } else { ++ return 0; ++ } ++ } ++ } else { ++ return 0; ++ } ++ ++} ++ ++static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ) ++{ ++ unsigned int prev_opId = 0; ++ unsigned int prev_prev_opId = 0; ++ ++ P_OSAL_OP pOp; ++ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; ++ ++ if (pOpQ == &stp_psm->rActiveOpQ) { ++ /* sleep , wakeup | sleep, --> null | sleep (x) */ ++ /* wakeup , sleep , wakeup | sleep --> wakeup | sleep (v) */ ++ /* sleep , wakeup , sleep | wakeup --> sleep | wakeup (v) */ ++ /* xxx, sleep | sleep --> xxx, sleep (v) */ ++ /* xxx, wakeup | wakeup --> xxx, wakeup (v) */ ++ /* xxx, awake | awake --> xxx, awake (v) --> should never happen */ ++ while (RB_COUNT(pOpQ) > 2) { ++ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; ++ prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId; ++ ++ if ((prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_WAKEUP) || ++ (prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) || ++ (prev_opId == STP_OPID_PSM_WAKEUP && prev_prev_opId == STP_OPID_PSM_SLEEP) || ++ (prev_opId == STP_OPID_PSM_HOST_AWAKE && prev_prev_opId == STP_OPID_PSM_SLEEP) ++ ) { ++ RB_GET(pOpQ, pOp); ++ RB_PUT(pFreeOpQ, pOp); ++ RB_GET(pOpQ, pOp); ++ RB_PUT(pFreeOpQ, pOp); ++ } else if (prev_opId == prev_prev_opId) { ++ RB_GET(pOpQ, pOp); ++ STP_PSM_DBG_FUNC("redundant opId(%d) found, remove it\n", pOp->op.opId); ++ RB_PUT(pFreeOpQ, pOp); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static INT32 _stp_psm_put_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) ++{ ++ INT32 ret; ++ ++ /* if (!pOpQ || !pOp) */ ++ /* { */ ++ /* STP_PSM_WARN_FUNC("pOpQ = 0x%p, pLxOp = 0x%p\n", pOpQ, pOp); */ ++ /* return 0; */ ++ /* } */ ++ ret = 0; ++ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ /* acquire lock success */ ++ if (pOpQ == &stp_psm->rActiveOpQ) { ++ if (!_stp_psm_is_redundant_active_op(pOp, pOpQ)) { ++ /* acquire lock success */ ++ if (!RB_FULL(pOpQ)) { ++ RB_PUT(pOpQ, pOp); ++ STP_PSM_DBG_FUNC("opId(%d) enqueue\n", pOp->op.opId); ++ } else { ++ STP_PSM_INFO_FUNC("************ Active Queue Full ************\n"); ++ ret = -1; ++ } ++ ++ _stp_psm_clean_up_redundant_active_op(pOpQ); ++ } else { ++ /*redundant opId, mark ret as success */ ++ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; ++ ++ if (!RB_FULL(pFreeOpQ)) ++ RB_PUT(pFreeOpQ, pOp); ++ else ++ osal_assert(!RB_FULL(pFreeOpQ)); ++ ++ ret = 0; ++ } ++ } else { ++ if (!RB_FULL(pOpQ)) ++ RB_PUT(pOpQ, pOp); ++ else ++ ret = -1; ++ ++ } ++ ++ if (pOpQ == &stp_psm->rActiveOpQ) ++ _stp_psm_dump_active_q(&stp_psm->rActiveOpQ); ++ ++ ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ STP_PSM_DBG_FUNC("stp_psm do unlock,active queue? (%s)\n", (pOpQ == &stp_psm->rActiveOpQ) ? "y" : "n"); ++ ++ if (ret) { ++ STP_PSM_WARN_FUNC("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n", RB_COUNT(pOpQ), RB_SIZE(pOpQ)); ++ return 0; ++ } else ++ return 1; ++ ++} ++ ++P_OSAL_OP _stp_psm_get_free_op(MTKSTP_PSM_T *stp_psm) ++{ ++ P_OSAL_OP pOp; ++ ++ if (stp_psm) { ++ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ); ++ if (pOp) ++ osal_memset(&pOp->op, 0, sizeof(pOp->op)); ++ ++ return pOp; ++ } else ++ return NULL; ++ ++} ++ ++INT32 _stp_psm_put_act_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP pOp) ++{ ++ INT32 bRet = 0; /* MTK_WCN_BOOL_FALSE; */ ++ INT32 bCleanup = 0; /* MTK_WCN_BOOL_FALSE; */ ++ INT32 wait_ret = -1; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ do { ++ if (!stp_psm || !pOp) { ++ STP_PSM_ERR_FUNC("stp_psm = %p, pOp = %p\n", stp_psm, pOp); ++ break; ++ } ++ ++ pSignal = &pOp->signal; ++ ++ if (pSignal->timeoutValue) { ++ pOp->result = -9; ++ osal_signal_init(&pOp->signal); ++ } ++ ++ /* put to active Q */ ++ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp); ++ ++ if (0 == bRet) { ++ STP_PSM_WARN_FUNC("+++++++++++ Put op Active queue Fail\n"); ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ break; ++ } ++ _stp_psm_opid_dbg_dmp_in(g_stp_psm_opid_dbg, pOp->op.opId, __LINE__); ++ ++ /* wake up wmtd */ ++ osal_trigger_event(&stp_psm->STPd_event); ++ ++ if (pSignal->timeoutValue == 0) { ++ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ ++ /* clean it in wmtd */ ++ break; ++ } ++ ++ /* wait result, clean it here */ ++ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ ++ ++ /* check result */ ++ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); ++ STP_PSM_DBG_FUNC("wait completion:%d\n", wait_ret); ++ if (!wait_ret) { ++ STP_PSM_ERR_FUNC("wait completion timeout\n"); ++ /* TODO: how to handle it? retry? */ ++ } else { ++ if (pOp->result) ++ STP_PSM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); ++ /* op completes, check result */ ++ bRet = (pOp->result) ? 0 : 1; ++ } ++ } while (0); ++ ++ if (bCleanup) { ++ /* put Op back to freeQ */ ++ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp); ++ if (bRet == 0) ++ STP_PSM_WARN_FUNC("+++++++++++ Put op active free fail, maybe disable/enable psm\n"); ++ } ++ ++ return bRet; ++} ++ ++static INT32 _stp_psm_wait_for_msg(void *pvData) ++{ ++ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; ++ ++ STP_PSM_DBG_FUNC("%s: stp_psm->rActiveOpQ = %d\n", __func__, RB_COUNT(&stp_psm->rActiveOpQ)); ++ ++ return (!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd); ++} ++ ++static INT32 _stp_psm_proc(void *pvData) ++{ ++ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; ++ P_OSAL_OP pOp; ++ UINT32 id; ++ INT32 result; ++ ++ if (!stp_psm) { ++ STP_PSM_WARN_FUNC("!stp_psm\n"); ++ return -1; ++ } ++/* STP_PSM_INFO_FUNC("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d]\n", */ ++/* stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio); */ ++ ++ for (;;) { ++ ++ pOp = NULL; ++ ++ osal_wait_for_event(&stp_psm->STPd_event, _stp_psm_wait_for_msg, (void *)stp_psm); ++ ++ /* we set reset flag when calling stp_reset after cleanup all op. */ ++ if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_RESET_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } ++ if (osal_thread_should_stop(&stp_psm->PSMd)) { ++ STP_PSM_INFO_FUNC("should stop now...\n"); ++ /* TODO: clean up active opQ */ ++ break; ++ } ++ ++ /* get Op from activeQ */ ++ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n"); ++ continue; ++ } ++ ++ id = osal_op_get_id(pOp); ++ ++ if (id >= STP_OPID_PSM_NUM) { ++ STP_PSM_WARN_FUNC("abnormal opid id: 0x%x\n", id); ++ result = -1; ++ goto handler_done; ++ } ++ ++ result = _stp_psm_handler(stp_psm, &pOp->op); ++ ++handler_done: ++ ++ if (result) { ++ STP_PSM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, ++ (id >= 4) ? ("???") : (g_psm_op_name[id]), result); ++ } ++ ++ if (osal_op_is_wait_for_signal(pOp)) ++ osal_op_raise_signal(pOp, result); ++ else { ++ /* put Op back to freeQ */ ++ if (_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0) ++ STP_PSM_WARN_FUNC("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n"); ++ } ++ ++ if (STP_OPID_PSM_EXIT == id) ++ break; ++ } ++ STP_PSM_INFO_FUNC("exits\n"); ++ ++ return 0; ++}; ++ ++static inline INT32 _stp_psm_get_time(void) ++{ ++ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) ++ osal_printtimeofday(">>>"); ++ ++ return 0; ++} ++ ++static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (stp_psm->work_state < STP_PSM_MAX_STATE) ++ return stp_psm->work_state; ++ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); ++ ++ return STP_PSM_OPERATION_FAIL; ++} ++ ++static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_STATE_T state) ++{ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (stp_psm->work_state < STP_PSM_MAX_STATE) { ++ _stp_psm_get_time(); ++ /* STP_PSM_INFO_FUNC("work_state = %s --> %s\n", ++ * g_psm_state[stp_psm->work_state], g_psm_state[state]); ++ */ ++ ++ stp_psm->work_state = state; ++ if (stp_psm->work_state != ACT) { ++ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ osal_set_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ } ++ } else ++ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); ++ ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { ++ STP_PSM_DBG_FUNC("STP-PSM DISABLE, DONT restart monitor!\n\r"); ++ return STP_PSM_OPERATION_SUCCESS; ++ } ++ ++ STP_PSM_LOUD_FUNC("start monitor\n"); ++ osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_DBG_FUNC("stop monitor\n"); ++ osal_timer_stop_sync(&stp_psm->psm_timer); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++INT32 _stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) ++{ ++ INT32 available_space = 0; ++ INT32 needed_space = 0; ++ UINT8 delimiter[] = { 0xbb, 0xbb }; ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ available_space = STP_PSM_FIFO_SIZE - osal_fifo_len(&stp_psm->hold_fifo); ++ needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2; ++ ++ /* STP_PSM_INFO_FUNC("*******FIFO Available(%d), Need(%d)\n", available_space, needed_space); */ ++ ++ if (available_space < needed_space) { ++ STP_PSM_ERR_FUNC("FIFO Available!! Reset FIFO\n"); ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ } ++ /* type */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); ++ /* length */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); ++ /* buffer */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) buffer, len); ++ /* delimiter */ ++ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); ++ ++ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ return len; ++ ++} ++ ++INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) ++{ ++ return osal_fifo_len(&stp_psm->hold_fifo); ++} ++ ++INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ INT32 i = 20; /*Max buffered packet number */ ++ INT32 ret = 0; ++ UINT8 type = 0; ++ UINT32 len = 0; ++ UINT8 delimiter[2]; ++ ++ /* STP_PSM_ERR_FUNC("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo)); */ ++ while (osal_fifo_len(&stp_psm->hold_fifo) && i > 0) { ++ /* acquire spinlock */ ++ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); ++ ++ if (len > STP_PSM_PACKET_SIZE_MAX) { ++ STP_PSM_ERR_FUNC("***psm packet's length too Long!****\n"); ++ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); ++ } else { ++ osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE); ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) stp_psm->out_buf, len); ++ } ++ ++ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); ++ ++ if (delimiter[0] == 0xbb && delimiter[1] == 0xbb) { ++ /* osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32); */ ++ stp_send_data_no_ps(stp_psm->out_buf, len, type); ++ } else { ++ STP_PSM_ERR_FUNC("***psm packet fifo parsing fail****\n"); ++ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); ++ ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ } ++ i--; ++ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ } ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ pOp = _stp_psm_get_free_op(stp_psm); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = STP_OPID_PSM_HOST_AWAKE; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_psm_put_act_op(stp_psm, pOp); ++ ++ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ ++ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ pOp = _stp_psm_get_free_op(stp_psm); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = STP_OPID_PSM_WAKEUP; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_psm_put_act_op(stp_psm, pOp); ++ if (0 == bRet) { ++ STP_PSM_WARN_FUNC("OPID(%d) type(%zd) bRet(%s)\n\n", ++ pOp->op.opId, pOp->op.au4OpData[0], "fail"); ++ } ++ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS); ++ ++ return retval; ++} ++ ++static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ P_OSAL_OP pOp; ++ INT32 bRet; ++ INT32 retval; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag)) ++ return 0; ++#if PSM_USE_COUNT_PACKAGE ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag)) ++ return 0; ++#endif ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) ++ return 0; ++ ++ pOp = _stp_psm_get_free_op(stp_psm); ++ if (!pOp) { ++ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; /* break; */ ++ } ++ ++ pOp->op.opId = STP_OPID_PSM_SLEEP; ++ pOp->signal.timeoutValue = 0; ++ bRet = _stp_psm_put_act_op(stp_psm, pOp); ++ ++ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); ++ ++ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 1; ++ ++ return retval; ++} ++ ++/*internal function*/ ++ ++static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 i = 0; ++ P_OSAL_OP_Q pOpQ; ++ P_OSAL_OP pOp; ++ ++ STP_PSM_DBG_FUNC("PSM MODE RESET=============================>\n\r"); ++ ++ STP_PSM_DBG_FUNC("_stp_psm_reset\n"); ++ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_unlock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ ++ /* --> disable psm <--// */ ++ stp_psm->flag.data = 0; ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ _stp_psm_stop_monitor(stp_psm); ++ ++ /* --> prepare the op list <--// */ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); ++ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); ++ ++ /* stp_psm->current_active_op = NULL; */ ++ stp_psm->last_active_opId = STP_OPID_PSM_INALID; ++ ++ pOpQ = &stp_psm->rFreeOpQ; ++ for (i = 0; i < STP_OP_BUF_SIZE; i++) { ++ if (!RB_FULL(pOpQ)) { ++ pOp = &stp_psm->arQue[i]; ++ RB_PUT(pOpQ, pOp); ++ } ++ } ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ ++ /* --> clean up interal data structure<--// */ ++ _stp_psm_set_state(stp_psm, ACT); ++ ++ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); ++ ++ /* --> stop psm thread wait <--// */ ++ osal_set_bit(STP_PSM_RESET_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ ++ STP_PSM_DBG_FUNC("PSM MODE RESET<============================\n\r"); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static INT32 _stp_psm_wait_wmt_event(void *pvData) ++{ ++ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; ++ ++ STP_PSM_DBG_FUNC("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data); ++ ++ return (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) || ++ (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) || ++ (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) || ++ (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)); ++} ++ ++static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ INT32 retval = 0; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ osal_wait_for_event_timeout(&stp_psm->wait_wmt_q, _stp_psm_wait_wmt_event, (void *)stp_psm); ++ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ /* STP send data here: STP enqueue data to psm buffer. */ ++ _stp_psm_release_data(stp_psm); ++ /* STP send data here: STP enqueue data to psm buffer. We release packet by the next one. */ ++ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* STP send data here: STP sends data directly without PSM. */ ++ _stp_psm_set_state(stp_psm, ACT); ++/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ ++ if (stp_psm_is_quick_ps_support()) ++ stp_psm_notify_wmt_sleep(stp_psm); ++ else ++ _stp_psm_start_monitor(stp_psm); ++ } else if (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ _stp_psm_set_state(stp_psm, INACT); ++ ++ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle++\n"); ++ mt_combo_plt_enter_deep_idle(COMBO_IF_BTIF); ++ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle--\n"); ++ ++ STP_PSM_DBG_FUNC("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_unlock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ } else if (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ if (_stp_psm_get_state(stp_psm) == ACT_INACT) { ++ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ _stp_psm_release_data(stp_psm); ++ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ _stp_psm_set_state(stp_psm, ACT); ++ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ } else if (_stp_psm_get_state(stp_psm) == INACT_ACT) { ++ _stp_psm_set_state(stp_psm, INACT); ++ STP_PSM_INFO_FUNC("[WARNING]PSM state rollback due too wakeup fail\n"); ++ } ++ } else if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } else { ++ STP_PSM_ERR_FUNC("flag = %ld<== Abnormal flag be set!!\n\r", stp_psm->flag.data); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ wcn_psm_flag_trigger_collect_ftrace(); /* trigger collect SYS_FTRACE */ ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ } ++ retval = STP_PSM_OPERATION_SUCCESS; ++ ++ return retval; ++} ++ ++static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) ++{ ++ ++ INT32 retval = 0; ++ ++ if (action == EIRQ) { ++ STP_PSM_DBG_FUNC("Call _stp_psm_notify_wmt_host_awake_wq\n\r"); ++ ++ _stp_psm_notify_wmt_host_awake_wq(stp_psm); ++ ++ return STP_PSM_OPERATION_FAIL; ++ } ++ ++ if ((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0)) { ++ STP_PSM_DBG_FUNC("state = %s, action=%s\n\r", g_psm_state[_stp_psm_get_state(stp_psm)], ++ g_psm_action[action]); ++ } ++ /* If STP trigger WAKEUP and SLEEP, to do the job below */ ++ switch (_stp_psm_get_state(stp_psm)) { ++ /* stp trigger */ ++ case ACT_INACT: ++ ++ if (action == SLEEP) { ++ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, ready to INACT\n\r", g_psm_action[action]); ++ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_set_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else if (action == ROLL_BACK) { ++ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, back to ACT\n\r", g_psm_action[action]); ++ /* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */ ++ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else { ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, ACT_INACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ } ++ break; ++ /* stp trigger */ ++ ++ case INACT_ACT: ++ ++ if (action == WAKEUP) { ++ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); ++ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else if (action == HOST_AWAKE) { ++ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); ++ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else if (action == ROLL_BACK) { ++ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, back to INACT\n\r", g_psm_action[action]); ++ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ /* wake_up(&stp_psm->wait_wmt_q); */ ++ osal_trigger_event(&stp_psm->wait_wmt_q); ++ } else { ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, INACT_ACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ } ++ break; ++ ++ case INACT: ++ ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, INACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = -1; ++ ++ break; ++ ++ case ACT: ++ ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, ACT state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ ++ break; ++ ++ default: ++ ++ /*invalid */ ++ if (action < STP_PSM_MAX_ACTION) { ++ STP_PSM_ERR_FUNC("Action = %s, Invalid state, the case should not happens\n\r", ++ g_psm_action[action]); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ } else { ++ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); ++ } ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ retval = STP_PSM_OPERATION_FAIL; ++ ++ break; ++ } ++ ++ return retval; ++ ++} ++ ++static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm == NULL) ++ return STP_PSM_OPERATION_FAIL; ++ ++ switch (_stp_psm_get_state(stp_psm)) { ++ case ACT: ++ ++ if (action == SLEEP) { ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { ++ STP_PSM_ERR_FUNC("psm monitor disabled, can't do sleep op\n"); ++ return STP_PSM_OPERATION_FAIL; ++ } ++ ++ _stp_psm_set_state(stp_psm, ACT_INACT); ++ ++ _stp_psm_release_data(stp_psm); ++ ++ if (stp_psm->wmt_notify) { ++ stp_psm->wmt_notify(SLEEP); ++ _stp_psm_wait_wmt_event_wq(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ } else if (action == WAKEUP || action == HOST_AWAKE) { ++ STP_PSM_INFO_FUNC("In ACT state, dont do WAKEUP/HOST_AWAKE again\n"); ++ _stp_psm_release_data(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ ret = STP_PSM_OPERATION_FAIL; ++ ++ } ++ ++ break; ++ ++ case INACT: ++ ++ if (action == WAKEUP) { ++ _stp_psm_set_state(stp_psm, INACT_ACT); ++ ++ if (stp_psm->wmt_notify) { ++ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_lock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); ++ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); ++ ++ stp_psm->wmt_notify(WAKEUP); ++ _stp_psm_wait_wmt_event_wq(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ } else if (action == HOST_AWAKE) { ++ _stp_psm_set_state(stp_psm, INACT_ACT); ++ ++ if (stp_psm->wmt_notify) { ++ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)\n", ++ osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_lock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)#\n", ++ osal_wake_lock_count(&stp_psm->wake_lock)); ++ ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); ++ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); ++ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); ++ ++ stp_psm->wmt_notify(HOST_AWAKE); ++ _stp_psm_wait_wmt_event_wq(stp_psm); ++ } else { ++ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ } else if (action == SLEEP) { ++ STP_PSM_INFO_FUNC("In INACT state, dont do SLEEP again\n"); ++ } else { ++ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ ret = STP_PSM_OPERATION_FAIL; ++ } ++ ++ break; ++ ++ default: ++ ++ /*invalid */ ++ STP_PSM_ERR_FUNC("invalid state, the case should not happen\n"); ++ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); ++ _stp_psm_dbg_out_printk(g_stp_psm_dbg); ++ ret = STP_PSM_OPERATION_FAIL; ++ ++ break; ++ } ++ return ret; ++} ++ ++static inline void _stp_psm_stp_is_idle(/*unsigned long data*/struct timer_list *t) ++{ ++ //MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) data; ++ MTKSTP_PSM_T *stp_psm = from_timer(stp_psm,t,psm_timer.timer); ++ ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { ++ STP_PSM_DBG_FUNC("STP-PSM DISABLE!\n"); ++ return; ++ } ++ ++ if (1 == _stp_psm_notify_wmt_sleep_wq(stp_psm)) ++ STP_PSM_INFO_FUNC("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep); ++} ++ ++static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_INFO_FUNC("init monitor\n"); ++ ++ stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle; ++ stp_psm->psm_timer.timeroutHandlerData = (unsigned long)stp_psm; ++ osal_timer_create(&stp_psm->psm_timer); ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_INFO_FUNC("deinit monitor\n"); ++ ++ osal_timer_stop_sync(&stp_psm->psm_timer); ++ ++ return 0; ++} ++ ++static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 iRet = -1; ++ ++/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ ++ if (osal_test_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag)) ++ iRet = 1; ++ else ++ iRet = 0; ++ ++/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ ++ return iRet; ++} ++ ++static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) ++ return 1; ++ else ++ return 0; ++} ++ ++static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) ++{ ++ ++#define POLL_WAIT 20 /* 200 */ ++#define POLL_WAIT_TIME 2000 ++ ++ INT32 i = 0; ++ INT32 limit = POLL_WAIT_TIME / POLL_WAIT; ++ ++ while (_stp_psm_get_state(stp_psm) != state && i < limit) { ++ osal_sleep_ms(POLL_WAIT); ++ i++; ++ STP_PSM_INFO_FUNC("STP is waiting state for %s, i=%d, state = %d\n", g_psm_state[state], i, ++ _stp_psm_get_state(stp_psm)); ++ } ++ ++ if (i == limit) { ++ STP_PSM_WARN_FUNC("-Wait for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); ++ _stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg); ++ return STP_PSM_OPERATION_FAIL; ++ } ++ STP_PSM_DBG_FUNC("+Total waits for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); ++ /* _stp_psm_dbg_out_printk(g_stp_psm_opid_dbg); */ ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ INT32 ret = 0; ++ INT32 retry = 10; ++ P_OSAL_OP_Q pOpQ; ++ P_OSAL_OP pOp; ++ ++ STP_PSM_LOUD_FUNC("*** Do Force Wakeup!***\n\r"); ++ ++ /* <1>If timer is active, we will stop it. */ ++ _stp_psm_stop_monitor(stp_psm); ++ ++ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ ++ pOpQ = &stp_psm->rFreeOpQ; ++ ++ while (!RB_EMPTY(&stp_psm->rActiveOpQ)) { ++ RB_GET(&stp_psm->rActiveOpQ, pOp); ++ if (NULL != pOp && !RB_FULL(pOpQ)) { ++ STP_PSM_DBG_FUNC("opid = %d\n", pOp->op.opId); ++ RB_PUT(pOpQ, pOp); ++ } else { ++ STP_PSM_ERR_FUNC("clear up active queue fail, freeQ full\n"); ++ } ++ } ++ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); ++ /* <5>We issue wakeup request into op queue. and wait for active. */ ++ do { ++ ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm); ++ ++ if (ret == STP_PSM_OPERATION_SUCCESS) { ++ ret = _stp_psm_do_wait(stp_psm, ACT); ++ ++ /* STP_PSM_INFO_FUNC("<< wait ret = %d, num of activeQ = %d\n", ++ * ret, RB_COUNT(&stp_psm->rActiveOpQ)); ++ */ ++ if (ret == STP_PSM_OPERATION_SUCCESS) ++ break; ++ } else ++ STP_PSM_ERR_FUNC("_stp_psm_notify_wmt_wakeup_wq fail!!\n"); ++ ++ /* STP_PSM_INFO_FUNC("retry = %d\n", retry); */ ++ retry--; ++ ++ if (retry == 0) ++ break; ++ } while (1); ++ ++ if (retry == 0) ++ return STP_PSM_OPERATION_FAIL; ++ else ++ return STP_PSM_OPERATION_SUCCESS; ++} ++ ++static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_DBG_FUNC("PSM Disable start\n\r"); ++ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ ret = _stp_psm_do_wakeup(stp_psm); ++ if (ret == STP_PSM_OPERATION_SUCCESS) ++ STP_PSM_DBG_FUNC("PSM Disable Success\n"); ++ else ++ STP_PSM_ERR_FUNC("***PSM Disable Fail***\n"); ++ ++ return ret; ++} ++ ++static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) ++{ ++ INT32 ret = STP_PSM_OPERATION_FAIL; ++ ++ STP_PSM_LOUD_FUNC("PSM Enable start\n\r"); ++ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ ++ ret = _stp_psm_do_wakeup(stp_psm); ++ if (ret == STP_PSM_OPERATION_SUCCESS) { ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ stp_psm->idle_time_to_sleep = idle_time_to_sleep; ++ ++ if (osal_wake_lock_count(&stp_psm->wake_lock) == 0) { ++ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ osal_wake_lock(&stp_psm->wake_lock); ++ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); ++ } ++ ++ _stp_psm_start_monitor(stp_psm); ++ ++ STP_PSM_DBG_FUNC("PSM Enable succeed\n\r"); ++ } else ++ STP_PSM_ERR_FUNC("***PSM Enable Fail***\n"); ++ ++ return ret; ++} ++ ++INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) ++{ ++ return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock); ++} ++ ++INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) ++{ ++ osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock); ++ return 0; ++} ++ ++MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID) ++{ ++ if (stp_psm->is_wmt_quick_ps_support) ++ return (*(stp_psm->is_wmt_quick_ps_support)) (); ++ ++ STP_PSM_DBG_FUNC("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r"); ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID) ++{ ++ return _stp_psm_is_quick_ps_support(); ++} ++ ++#if PSM_USE_COUNT_PACKAGE ++int stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, int dir) ++{ ++ ++ /* easy the variable maintain beween stp tx, rx thread. */ ++ /* so we create variable for tx, rx respectively. */ ++ ++ static int tx_cnt; ++ static int rx_cnt; ++ static int is_tx_first = 1; ++ static int is_rx_first = 1; ++ static unsigned long tx_end_time; ++ static unsigned long rx_end_time; ++ ++ /* */ ++ /* BT A2DP TX CNT = 220, RX CNT = 843 */ ++ /* BT FTP Transferring TX CNT = 574, RX CNT = 2233 (1228~1588) */ ++ /* BT FTP Receiving TX CNT = 204, RX CNT = 3301 (2072~2515) */ ++ /* BT OPP Tx TX_CNT= 330, RX CNT = 1300~1800 */ ++ /* BT OPP Rx TX_CNT= (109~157), RX CNT = 1681~2436 */ ++ if (dir == 0) { /* tx */ ++ ++ tx_cnt++; ++ ++ if (((long)jiffies - (long)tx_end_time >= 0) || (is_tx_first)) { ++ tx_end_time = jiffies + (3 * HZ); ++ STP_PSM_INFO_FUNC("tx cnt = %d in the previous 3 sec\n", tx_cnt); ++ /* if(tx_cnt > 400)//for high traffic , not to do sleep. */ ++ if (tx_cnt > 300) { ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ stp_psm_start_monitor(stp_psm); ++ } else { ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } ++ tx_cnt = 0; ++ if (is_tx_first) ++ is_tx_first = 0; ++ } ++ } else { ++ rx_cnt++; ++ ++ if (((long)jiffies - (long)rx_end_time >= 0) || (is_rx_first)) { ++ rx_end_time = jiffies + (3 * HZ); ++ STP_PSM_INFO_FUNC("rx cnt = %d in the previous 3 sec\n", rx_cnt); ++ ++ /* if(rx_cnt > 2000)//for high traffic , not to do sleep. */ ++ if (rx_cnt > 1200) { /* for high traffic , not to do sleep. */ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ stp_psm_start_monitor(stp_psm); ++ } else { ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); ++ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); ++ } ++ rx_cnt = 0; ++ if (is_rx_first) ++ is_rx_first = 0; ++ } ++ } ++ ++ return 0; ++} ++ ++#else ++static struct timeval tv_now, tv_end; ++static INT32 sample_start; ++static INT32 tx_sum_len; ++static INT32 rx_sum_len; ++ ++INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length) ++{ ++ if (sample_start) { ++ if (dir) ++ rx_sum_len += length; ++ else ++ tx_sum_len += length; ++ ++ do_gettimeofday(&tv_now); ++ /* STP_PSM_INFO_FUNC("tv_now:%d.%d tv_end:%d.%d\n", ++ * tv_now.tv_sec,tv_now.tv_usec,tv_end.tv_sec,tv_end.tv_usec); ++ */ ++ if (((tv_now.tv_sec == tv_end.tv_sec) && (tv_now.tv_usec > tv_end.tv_usec)) || ++ (tv_now.tv_sec > tv_end.tv_sec)) { ++ STP_PSM_INFO_FUNC("STP speed rx:%d tx:%d\n", rx_sum_len, tx_sum_len); ++ if ((rx_sum_len + tx_sum_len) > RTX_SPEED_THRESHOLD) { ++ /* STP_PSM_INFO_FUNC("High speed,Disable monitor\n"); */ ++ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP_1000; ++ stp_psm_start_monitor(stp_psm); ++ } else { ++ /* STP_PSM_INFO_FUNC("Low speed,Enable monitor\n"); */ ++ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; ++ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); ++ } ++ sample_start = 0; ++ rx_sum_len = 0; ++ tx_sum_len = 0; ++ } ++ } else { ++ sample_start = 1; ++ do_gettimeofday(&tv_now); ++ tv_end = tv_now; ++ tv_end.tv_sec += SAMPLE_DURATION; ++ } ++ ++ return 0; ++} ++#endif ++ ++/*external function for WMT module to do sleep/wakeup*/ ++INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) ++{ ++ return _stp_psm_set_state(stp_psm, state); ++} ++ ++INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_thread_lock_aquire(stp_psm); ++} ++ ++INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_thread_lock_release(stp_psm); ++} ++ ++INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_do_wakeup(stp_psm); ++} ++ ++INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) ++{ ++ ++ return _stp_psm_notify_stp(stp_psm, action); ++} ++ ++INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_notify_wmt_wakeup_wq(stp_psm); ++} ++ ++int stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm) ++{ ++ ++ return _stp_psm_notify_wmt_sleep_wq(stp_psm); ++} ++ ++INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_start_monitor(stp_psm); ++} ++ ++INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_is_to_block_traffic(stp_psm); ++} ++ ++INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_is_disable(stp_psm); ++} ++ ++INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_has_pending_data(stp_psm); ++} ++ ++INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_release_data(stp_psm); ++} ++ ++INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) ++{ ++ return _stp_psm_hold_data(stp_psm, buffer, len, type); ++} ++ ++INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_disable(stp_psm); ++} ++ ++INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) ++{ ++ return _stp_psm_enable(stp_psm, idle_time_to_sleep); ++} ++ ++INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm) ++{ ++ stp_psm_set_sleep_enable(stp_psm); ++ ++ return _stp_psm_reset(stp_psm); ++} ++ ++INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm) ++{ ++ return _stp_psm_notify_wmt_sleep_wq(stp_psm); ++} ++ ++INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm) { ++ stp_psm->sleep_en = 1; ++ STP_PSM_DBG_FUNC("\n"); ++ ret = 0; ++ } else { ++ STP_PSM_INFO_FUNC("Null pointer\n"); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm) { ++ stp_psm->sleep_en = 0; ++ STP_PSM_DBG_FUNC("\n"); ++ ret = 0; ++ } else { ++ STP_PSM_INFO_FUNC("Null pointer\n"); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++/* stp_psm_check_sleep_enable - to check if sleep cmd is enabled or not ++ * @ stp_psm - pointer of psm ++ * ++ * return 1 if sleep is enabled; else return 0 if disabled; else error code ++ */ ++INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = 0; ++ ++ if (stp_psm) { ++ ret = stp_psm->sleep_en; ++ STP_PSM_DBG_FUNC("%s\n", ret ? "enabled" : "disabled"); ++ } else { ++ STP_PSM_INFO_FUNC("Null pointer\n"); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num) ++{ ++ INT32 index = 0; ++ struct timeval now; ++ ++ if (stp_psm_dbg) { ++ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); ++ do_gettimeofday(&now); ++ index = stp_psm_dbg->in - 1; ++ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; ++ STP_PSM_DBG_FUNC("index(%d)\n", index); ++ stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag = stp_psm_dbg->queue[index].cur_flag; ++ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag = flag; ++ stp_psm_dbg->queue[stp_psm_dbg->in].line_num = line_num; ++ stp_psm_dbg->queue[stp_psm_dbg->in].package_no = g_record_num++; ++ stp_psm_dbg->queue[stp_psm_dbg->in].sec = now.tv_sec; ++ stp_psm_dbg->queue[stp_psm_dbg->in].usec = now.tv_usec; ++ stp_psm_dbg->size++; ++ STP_PSM_DBG_FUNC("pre_Flag = %d, cur_flag = %d\n", stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag, ++ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag); ++ stp_psm_dbg->size = (stp_psm_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : stp_psm_dbg->size; ++ stp_psm_dbg->in = (stp_psm_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (stp_psm_dbg->in + 1); ++ STP_PSM_DBG_FUNC("record size = %d, in = %d num = %d\n", stp_psm_dbg->size, stp_psm_dbg->in, line_num); ++ ++ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); ++ } ++ return 0; ++} ++ ++static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg) ++{ ++ ++ UINT32 dumpSize = 0; ++ UINT32 inIndex = 0; ++ UINT32 outIndex = 0; ++ ++ if (!stp_psm_dbg) { ++ STP_PSM_ERR_FUNC("NULL g_stp_psm_dbg reference\n"); ++ return -1; ++ } ++ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); ++ ++ inIndex = stp_psm_dbg->in; ++ dumpSize = stp_psm_dbg->size; ++ if (STP_PSM_DBG_SIZE == dumpSize) ++ outIndex = inIndex; ++ else ++ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; ++ ++ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); ++ while (dumpSize > 0) { ++ ++ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d)\n", ++ stp_psm_dbg->queue[outIndex].sec, ++ stp_psm_dbg->queue[outIndex].usec, ++ stp_psm_dbg->queue[outIndex].package_no, ++ stp_psm_dbg->queue[outIndex].prev_flag, ++ stp_psm_dbg->queue[outIndex].cur_flag, stp_psm_dbg->queue[outIndex].line_num); ++ ++ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); ++ dumpSize--; ++ ++ } ++ ++ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); ++ ++ return 0; ++} ++ ++static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num) ++{ ++ INT32 index = 0; ++ struct timeval now; ++ ++ if (p_opid_dbg) { ++ osal_lock_unsleepable_lock(&p_opid_dbg->lock); ++ do_gettimeofday(&now); ++ index = p_opid_dbg->in - 1; ++ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; ++ STP_PSM_DBG_FUNC("index(%d)\n", index); ++ p_opid_dbg->queue[p_opid_dbg->in].prev_flag = p_opid_dbg->queue[index].cur_flag; ++ p_opid_dbg->queue[p_opid_dbg->in].cur_flag = opid; ++ p_opid_dbg->queue[p_opid_dbg->in].line_num = line_num; ++ p_opid_dbg->queue[p_opid_dbg->in].package_no = g_opid_record_num++; ++ p_opid_dbg->queue[p_opid_dbg->in].sec = now.tv_sec; ++ p_opid_dbg->queue[p_opid_dbg->in].usec = now.tv_usec; ++ p_opid_dbg->queue[p_opid_dbg->in].pid = current->pid; ++ p_opid_dbg->size++; ++ STP_PSM_DBG_FUNC("pre_opid = %d, cur_opid = %d\n", p_opid_dbg->queue[p_opid_dbg->in].prev_flag, ++ p_opid_dbg->queue[p_opid_dbg->in].cur_flag); ++ p_opid_dbg->size = (p_opid_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : p_opid_dbg->size; ++ p_opid_dbg->in = (p_opid_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (p_opid_dbg->in + 1); ++ STP_PSM_DBG_FUNC("opid record size = %d, in = %d num = %d\n", p_opid_dbg->size, p_opid_dbg->in, ++ line_num); ++ ++ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); ++ } ++ return 0; ++ ++} ++ ++static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg) ++{ ++ UINT32 dumpSize = 0; ++ UINT32 inIndex = 0; ++ UINT32 outIndex = 0; ++ ++ if (!p_opid_dbg) { ++ STP_PSM_ERR_FUNC("NULL p_opid_dbg reference\n"); ++ return -1; ++ } ++ osal_lock_unsleepable_lock(&p_opid_dbg->lock); ++ ++ inIndex = p_opid_dbg->in; ++ dumpSize = p_opid_dbg->size; ++ if (STP_PSM_DBG_SIZE == dumpSize) ++ outIndex = inIndex; ++ else ++ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; ++ ++ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); ++ while (dumpSize > 0) { ++ ++ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d) pid(%d)\n", ++ p_opid_dbg->queue[outIndex].sec, ++ p_opid_dbg->queue[outIndex].usec, ++ p_opid_dbg->queue[outIndex].package_no, ++ p_opid_dbg->queue[outIndex].prev_flag, ++ p_opid_dbg->queue[outIndex].cur_flag, ++ p_opid_dbg->queue[outIndex].line_num, p_opid_dbg->queue[outIndex].pid); ++ ++ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); ++ dumpSize--; ++ ++ } ++ ++ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); ++ ++ return 0; ++ ++} ++ ++MTKSTP_PSM_T *stp_psm_init(void) ++{ ++ INT32 err = 0; ++ INT32 i = 0; ++ INT32 ret = -1; ++ ++ STP_PSM_INFO_FUNC("psm init\n"); ++ ++ stp_psm->work_state = ACT; ++ stp_psm->wmt_notify = wmt_lib_ps_stp_cb; ++ stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support; ++ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; ++ stp_psm->flag.data = 0; ++ stp_psm->stp_tx_cb = NULL; ++ stp_psm_set_sleep_enable(stp_psm); ++ ++ ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("FIFO INIT FAILS\n"); ++ goto ERR_EXIT4; ++ } ++ ++ osal_fifo_reset(&stp_psm->hold_fifo); ++ osal_sleepable_lock_init(&stp_psm->hold_fifo_spinlock_global); ++ osal_unsleepable_lock_init(&stp_psm->wq_spinlock); ++ osal_sleepable_lock_init(&stp_psm->stp_psm_lock); ++ ++/* osal_unsleepable_lock_init(&stp_psm->flagSpinlock); */ ++ ++ osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6); ++ osal_wake_lock_init(&stp_psm->wake_lock); ++ ++ osal_event_init(&stp_psm->STPd_event); ++ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); ++ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); ++ /* Put all to free Q */ ++ for (i = 0; i < STP_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(stp_psm->arQue[i].signal)); ++ _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i])); ++ } ++ /* stp_psm->current_active_op = NULL; */ ++ stp_psm->last_active_opId = STP_OPID_PSM_INALID; ++ /*Generate BTM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake */ ++ stp_psm->PSMd.pThreadData = (VOID *) stp_psm; ++ stp_psm->PSMd.pThreadFunc = (VOID *) _stp_psm_proc; ++ osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME)); ++ ++ ret = osal_thread_create(&stp_psm->PSMd); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("osal_thread_create fail...\n"); ++ goto ERR_EXIT5; ++ } ++ /* init_waitqueue_head(&stp_psm->wait_wmt_q); */ ++ stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT; ++ osal_event_init(&stp_psm->wait_wmt_q); ++ ++ err = _stp_psm_init_monitor(stp_psm); ++ if (err) { ++ STP_PSM_ERR_FUNC("__stp_psm_init ERROR\n"); ++ goto ERR_EXIT6; ++ } ++ /* Start STPd thread */ ++ ret = osal_thread_run(&stp_psm->PSMd); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("osal_thread_run FAILS\n"); ++ goto ERR_EXIT6; ++ } ++ /* psm disable in default */ ++ _stp_psm_disable(stp_psm); ++ ++ g_stp_psm_dbg = (STP_PSM_RECORD_T *) osal_malloc(osal_sizeof(STP_PSM_RECORD_T)); ++ if (!g_stp_psm_dbg) { ++ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); ++ return NULL; ++ } ++ osal_memset(g_stp_psm_dbg, 0, osal_sizeof(STP_PSM_RECORD_T)); ++ osal_unsleepable_lock_init(&g_stp_psm_dbg->lock); ++ ++ g_stp_psm_opid_dbg = (STP_PSM_OPID_RECORD *) osal_malloc(osal_sizeof(STP_PSM_OPID_RECORD)); ++ if (!g_stp_psm_opid_dbg) { ++ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); ++ return NULL; ++ } ++ osal_memset(g_stp_psm_opid_dbg, 0, osal_sizeof(STP_PSM_OPID_RECORD)); ++ osal_unsleepable_lock_init(&g_stp_psm_opid_dbg->lock); ++ ++ return stp_psm; ++ ++ERR_EXIT6: ++ ++ ret = osal_thread_destroy(&stp_psm->PSMd); ++ if (ret < 0) { ++ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); ++ goto ERR_EXIT5; ++ } ++ERR_EXIT5: ++ osal_fifo_deinit(&stp_psm->hold_fifo); ++ERR_EXIT4: ++ ++ return NULL; ++} ++ ++INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm) ++{ ++ INT32 ret = -1; ++ ++ STP_PSM_INFO_FUNC("psm deinit\n"); ++ ++ if (g_stp_psm_dbg) { ++ osal_unsleepable_lock_deinit(&g_stp_psm_dbg->lock); ++ osal_free(g_stp_psm_dbg); ++ g_stp_psm_dbg = NULL; ++ } ++ ++ if (!stp_psm) ++ return STP_PSM_OPERATION_FAIL; ++ ++ ret = osal_thread_destroy(&stp_psm->PSMd); ++ if (ret < 0) ++ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); ++ ++ ret = _stp_psm_deinit_monitor(stp_psm); ++ if (ret < 0) ++ STP_PSM_ERR_FUNC("_stp_psm_deinit_monitor ERROR\n"); ++ ++ osal_wake_lock_deinit(&stp_psm->wake_lock); ++ osal_fifo_deinit(&stp_psm->hold_fifo); ++ osal_sleepable_lock_deinit(&stp_psm->hold_fifo_spinlock_global); ++ osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock); ++ osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock); ++/* osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock); */ ++ ++ return STP_PSM_OPERATION_SUCCESS; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c +new file mode 100644 +index 000000000000..a3c24ca14441 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c +@@ -0,0 +1,3358 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include "osal_typedef.h" ++#include "stp_core.h" ++#include "psm_core.h" ++#include "btm_core.h" ++#include "stp_dbg.h" ++#include "stp_btif.h" ++ ++#define PFX "[STP] " ++#define STP_LOG_DBG 4 ++#define STP_LOG_PKHEAD 3 ++#define STP_LOG_INFO 2 ++#define STP_LOG_WARN 1 ++#define STP_LOG_ERR 0 ++ ++#define STP_DEL_SIZE 2 /* STP delimiter length */ ++ ++UINT32 gStpDbgLvl = STP_LOG_INFO; ++unsigned int g_coredump_mode = 0; ++#define REMOVE_USELESS_LOG 1 ++ ++#define STP_POLL_CPUPCR_NUM 16 ++#define STP_POLL_CPUPCR_DELAY 10 ++#define STP_RETRY_OPTIMIZE 0 ++ ++/* global variables */ ++static const UINT8 stp_delimiter[STP_DEL_SIZE] = { 0x55, 0x55 }; ++ ++static INT32 fgEnableNak; /* 0=enable NAK; 1=disable NAK */ ++static INT32 fgEnableDelimiter; /* 0=disable Delimiter; 1=enable Delimiter */ ++#if STP_RETRY_OPTIMIZE ++static UINT32 g_retry_times; ++#endif ++/* common interface */ ++static IF_TX sys_if_tx; ++/* event/signal */ ++static EVENT_SET sys_event_set; ++static EVENT_TX_RESUME sys_event_tx_resume; ++static FUNCTION_STATUS sys_check_function_status; ++/* kernel lib */ ++/* int g_block_tx = 0; */ ++static mtkstp_context_struct stp_core_ctx = { 0 }; ++ ++#define STP_PSM_CORE(x) ((x).psm) ++#define STP_SET_PSM_CORE(x, v) ((x).psm = (v)) ++ ++#define STP_BTM_CORE(x) ((x).btm) ++#define STP_SET_BTM_CORE(x, v) ((x).btm = (v)) ++ ++#define STP_IS_ENABLE(x) ((x).f_enable != 0) ++#define STP_NOT_ENABLE(x) ((x).f_enable == 0) ++#define STP_SET_ENABLE(x, v) ((x).f_enable = (v)) ++ ++#define STP_IS_READY(x) ((x).f_ready != 0) ++#define STP_NOT_READY(x) ((x).f_ready == 0) ++#define STP_SET_READY(x, v) ((x).f_ready = (v)) ++ ++#define STP_PENDING_TYPE(x) ((x).f_pending_type) ++#define STP_SET_PENDING_TYPE(x, v) ((x).f_pending_type = (v)) ++ ++#define STP_BLUE_ANGEL (0) ++#define STP_BLUE_Z (1) ++#define STP_BT_STK(x) ((x).f_bluez) ++#define STP_BT_STK_IS_BLUEZ(x) ((x).f_bluez == (STP_BLUE_Z)) ++#define STP_SET_BT_STK(x, v) ((x).f_bluez = (v)) ++ ++#define STP_IS_ENABLE_DBG(x) ((x).f_dbg_en != 0) ++#define STP_NOT_ENABLE_DBG(x) ((x).f_dbg_en == 0) ++#define STP_SET_ENABLE_DBG(x, v) ((x).f_dbg_en = (v)) ++ ++#define STP_IS_ENABLE_RST(x) ((x).f_autorst_en != 0) ++#define STP_NOT_ENABLE_RST(x) ((x).f_autorst_en == 0) ++#define STP_SET_ENABLE_RST(x, v) ((x).f_autorst_en = (v)) ++ ++#define STP_SUPPORT_PROTOCOL(x) ((x).f_mode) ++#define STP_SET_SUPPORT_PROTOCOL(x, v) ((x).f_mode = (v)) ++ ++#define STP_FW_COREDUMP_FLAG(x) ((x).f_coredump) ++#define STP_SET_FW_COREDUMP_FLAG(x, v) ((x).f_coredump = (v)) ++#define STP_ENABLE_FW_COREDUMP(x, v) ((x).en_coredump = (v)) ++#define STP_ENABLE_FW_COREDUMP_FLAG(x) ((x).en_coredump) ++ ++#define STP_WMT_LAST_CLOSE(x) ((x).f_wmt_last_close) ++#define STP_SET_WMT_LAST_CLOSE(x, v) ((x).f_wmt_last_close = (v)) ++ ++#define STP_EVT_ERR_ASSERT(x) ((x).f_evt_err_assert) ++#define STP_SET_EVT_ERR_ASSERT(x, v) ((x).f_evt_err_assert = (v)) ++ ++/*[PatchNeed]Need to calculate the timeout value*/ ++static UINT32 mtkstp_tx_timeout = MTKSTP_TX_TIMEOUT; ++static mtkstp_parser_state prev_state = -1; ++ ++#define CONFIG_DEBUG_STP_TRAFFIC_SUPPORT ++#ifdef CONFIG_DEBUG_STP_TRAFFIC_SUPPORT ++static MTKSTP_DBG_T *g_mtkstp_dbg; ++#endif ++static VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len); ++static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc); ++static VOID stp_update_tx_queue(UINT32 txseq); ++static VOID stp_rest_ctx_state(VOID); ++static VOID stp_change_rx_state(mtkstp_parser_state next); ++static void stp_tx_timeout_handler(/*unsigned long data*/ struct timer_list *t); ++static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len); ++static VOID stp_dump_tx_queue(UINT32 txseq); ++static INT32 stp_is_apply_powersaving(VOID); ++/*static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type);*/ ++static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length); ++static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length); ++static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type); ++static VOID stp_send_tx_queue(UINT32 txseq); ++static VOID stp_send_ack(UINT8 txAck, UINT8 nak); ++static INT32 stp_process_rxack(VOID); ++static VOID stp_process_packet(VOID); ++ ++/*private functions*/ ++ ++static INT32 stp_ctx_lock_init(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_unsleepable_lock_init(&((pctx)->stp_mutex)); ++#else ++ osal_sleepable_lock_init(&((pctx)->stp_mutex)); ++ return 0; ++#endif ++} ++ ++static INT32 stp_ctx_lock_deinit(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_unsleepable_lock_deinit(&((pctx)->stp_mutex)); ++#else ++ return osal_sleepable_lock_deinit(&((pctx)->stp_mutex)); ++#endif ++} ++ ++static INT32 stp_ctx_lock(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_lock_unsleepable_lock(&((pctx)->stp_mutex)); ++#else ++ return osal_lock_sleepable_lock(&((pctx)->stp_mutex)); ++#endif ++} ++ ++static INT32 stp_ctx_unlock(mtkstp_context_struct *pctx) ++{ ++#if CFG_STP_CORE_CTX_SPIN_LOCK ++ return osal_unlock_unsleepable_lock(&((pctx)->stp_mutex)); ++#else ++ return osal_unlock_sleepable_lock(&((pctx)->stp_mutex)); ++#endif ++} ++ ++MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel) ++{ ++ if (dbglevel <= 4) { ++ gStpDbgLvl = dbglevel; ++ STP_INFO_FUNC("gStpDbgLvl = %d\n", gStpDbgLvl); ++ return MTK_WCN_BOOL_TRUE; ++ } ++ STP_INFO_FUNC("invalid stp debug level. gStpDbgLvl = %d\n", gStpDbgLvl); ++ ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++#if !(REMOVE_USELESS_LOG) ++static UINT8 *stp_type_to_dbg_string(UINT32 type) ++{ ++ UINT8 *type_name = NULL; ++ ++ if (type == BT_TASK_INDX) ++ type_name = "< BT>"; ++ else if (type == GPS_TASK_INDX) ++ type_name = ""; ++ else if (type == WMT_TASK_INDX) ++ type_name = ""; ++ else if (type == FM_TASK_INDX) ++ type_name = "< FM>"; ++ else if (type == ANT_TASK_INDX) ++ type_name = ""; ++ ++ return type_name; ++} ++#endif ++#if 0 ++/***************************************************************************** ++* FUNCTION ++* crc16 ++* DESCRIPTION ++* Compute the CRC-16 for the data buffer ++* PARAMETERS ++* crc [IN] previous CRC value ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* the updated CRC value ++*****************************************************************************/ ++static UINT16 crc16(const UINT8 *buffer, const UINT32 length) ++{ ++ UINT32 crc, i; ++ ++ /* FIXME: Add STP checksum feature */ ++ crc = 0; ++ for (i = 0; i < length; i++, buffer++) ++ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; ++ ++ return crc; ++} ++ ++#endif ++ ++VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len) ++{ ++ ++#ifndef CONFIG_LOG_STP_INTERNAL ++ return; ++#endif ++ ++ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { ++ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_PKT, type, /* type */ ++ txAck, /* ack */ ++ seq, /* seq */ ++ crc, /* crc */ ++ dir, /* dir */ ++ len, /* len */ ++ pBuf); /* body */ ++ } else { ++ STP_DBG_FUNC("stp_dbg not enabled"); ++ } ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_check_crc ++* DESCRIPTION ++* check the check sum of packet payload ++* PARAMETERS ++* pdata [IN] the data want to check ++* length [IN] the length of pdata ++* crc [IN] the crc of pdata ++* RETURNS ++* KAL_TRUE crc is ok ++* KAL_FALSE crc is wrong ++*****************************************************************************/ ++static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc) ++{ ++ /*----------------------------------------------------------------*/ ++ /* Local Variables */ ++ /*----------------------------------------------------------------*/ ++ UINT16 checksum; ++ ++ /*----------------------------------------------------------------*/ ++ /* Code Body */ ++ /*----------------------------------------------------------------*/ ++ ++ /* FIXME: Add STP feature: check or skip crc */ ++ ++ checksum = osal_crc16(buffer, length); ++ if (checksum == crc) ++ return MTK_WCN_BOOL_TRUE; ++ ++ STP_ERR_FUNC("CRC fail, length = %d, rx = %x, calc = %x \r\n", length, crc, checksum); ++ return MTK_WCN_BOOL_FALSE; ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_update_tx_queue ++* DESCRIPTION ++* update packet's ACK field ++* PARAMETERS ++* txseq [IN] index of the tx packet which we want to update ++* RETURNS ++* void ++*****************************************************************************/ ++static void stp_update_tx_queue(UINT32 txseq) ++{ ++ INT32 tx_read, i; ++ UINT8 checksum = 0; ++ ++ tx_read = stp_core_ctx.tx_start_addr[txseq]; ++ stp_core_ctx.tx_buf[tx_read] &= 0xf8; ++ stp_core_ctx.tx_buf[tx_read] |= stp_core_ctx.sequence.txack; ++ ++ for (i = 0; i < 3; i++) { ++ checksum += stp_core_ctx.tx_buf[tx_read]; ++ tx_read++; ++ if (tx_read >= MTKSTP_BUFFER_SIZE) ++ tx_read -= MTKSTP_BUFFER_SIZE; ++ ++ } ++ ++ stp_core_ctx.tx_buf[tx_read] = checksum; ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_rest_ctx_state ++* DESCRIPTION ++* Reset stp context state variables only. Mutex and timer resources are not touched. ++* ++* PARAMETERS ++* void ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_rest_ctx_state(VOID) ++{ ++ INT32 i; ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ stp_core_ctx.rx_counter = 0; ++ ++ /*reset rx buffer pointer */ ++ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) { ++ stp_core_ctx.ring[i].read_p = 0; ++ stp_core_ctx.ring[i].write_p = 0; ++ } ++ ++ /*reset tx buffer pointer */ ++ stp_core_ctx.tx_write = 0; ++ stp_core_ctx.tx_read = 0; ++ ++ /*reset STP protocol context */ ++ stp_core_ctx.parser.state = MTKSTP_SYNC; ++ stp_core_ctx.sequence.txseq = 0; ++ stp_core_ctx.sequence.txack = 7; ++ stp_core_ctx.sequence.rxack = 7; ++ stp_core_ctx.sequence.winspace = MTKSTP_WINSIZE; ++ stp_core_ctx.sequence.expected_rxseq = 0; ++ stp_core_ctx.sequence.retry_times = 0; ++ stp_core_ctx.inband_rst_set = 0; ++ ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_change_rx_state ++* DESCRIPTION ++* change the rx fsm of STP to "next" ++* PARAMETERS ++* next [IN] the next state of rx fsm ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_change_rx_state(mtkstp_parser_state next) ++{ ++ prev_state = stp_core_ctx.parser.state; ++ stp_core_ctx.parser.state = next; ++ ++} ++ ++/* static void stp_tx_timeout_handler(void){ */ ++static void stp_tx_timeout_handler(/*unsigned long data*/struct timer_list *t) ++{ ++ STP_WARN_FUNC("call retry btm retry wq ...\n"); ++ /*shorten the softirq lattency */ ++ stp_btm_notify_stp_retry_wq(STP_BTM_CORE(stp_core_ctx)); ++ STP_WARN_FUNC("call retry btm retry wq ...#\n"); ++} ++ ++VOID stp_do_tx_timeout(VOID) ++{ ++ UINT32 seq; ++ UINT32 ret; ++ INT32 iRet; ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ UINT8 resync[4]; ++ ++ STP_WARN_FUNC("==============================================================================\n"); ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++#if STP_RETRY_OPTIMIZE ++ if ((g_retry_times != 0) && (stp_core_ctx.sequence.retry_times == 0)) { ++ STP_INFO_FUNC("STP TX timeout has been recoveryed by resend,record_retry_time(%d)\n", g_retry_times); ++ g_retry_times = 0; ++ stp_ctx_unlock(&stp_core_ctx); ++ return; ++ } ++#endif ++ if (stp_core_ctx.sequence.retry_times > (MTKSTP_RETRY_LIMIT)) { ++ STP_INFO_FUNC("STP retry times(%d) have reached retry limit,stop it\n", ++ stp_core_ctx.sequence.retry_times); ++ stp_ctx_unlock(&stp_core_ctx); ++ return; ++ } ++#if STP_RETRY_OPTIMIZE ++ else ++ STP_DBG_FUNC("current TX timeout package has not received ACK yet,retry_times(%d)\n", ++ g_retry_times); ++#endif ++ /*polling cpupcr when no ack occurs at first retry */ ++ stp_notify_btm_poll_cpupcr(STP_BTM_CORE(stp_core_ctx), STP_POLL_CPUPCR_NUM, STP_POLL_CPUPCR_DELAY); ++ ++ seq = stp_core_ctx.sequence.rxack; ++ INDEX_INC(seq); ++ ++ if (seq != stp_core_ctx.sequence.txseq) { ++ osal_memset(&resync[0], 127, 4); ++ (*sys_if_tx) (&resync[0], 4, &ret); ++ if (ret != 4) { ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler: send resync fail\n"); ++ osal_assert(0); ++ } ++ ++ do { ++ STP_WARN_FUNC("[stp.ctx]*rxack (=last rx ack) = %d\n\r", stp_core_ctx.sequence.rxack); ++ STP_WARN_FUNC("[stp.ctx]txack (=last rx seq)= %d\n\r", stp_core_ctx.sequence.txack); ++ STP_WARN_FUNC("[stp.ctx]*txseq (=next tx seq)= %d\n\r", stp_core_ctx.sequence.txseq); ++ STP_WARN_FUNC("Resend STP packet from %d -> %d\n\r", seq, ++ (stp_core_ctx.sequence.txseq <= 0) ? (7) : (stp_core_ctx.sequence.txseq - 1)); ++ stp_dump_tx_queue(seq); ++ ++ stp_send_tx_queue(seq); ++ INDEX_INC(seq); ++ } while (seq != stp_core_ctx.sequence.txseq); ++ ++ } ++ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ ++ if (stp_core_ctx.sequence.winspace == MTKSTP_WINSIZE) { ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); ++ } else { ++ stp_core_ctx.sequence.retry_times++; ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler, retry = %d\n", stp_core_ctx.sequence.retry_times); ++#if STP_RETRY_OPTIMIZE ++ g_retry_times = stp_core_ctx.sequence.retry_times; ++#endif ++ /*If retry too much, try to recover STP by return back to initializatin state */ ++ /*And not to retry again */ ++ if (stp_core_ctx.sequence.retry_times > MTKSTP_RETRY_LIMIT) { ++#if STP_RETRY_OPTIMIZE ++ g_retry_times = 0; ++#endif ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ stp_ctx_unlock(&stp_core_ctx); ++ ++ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); ++ ++ STP_ERR_FUNC("TX retry limit = %d\n", MTKSTP_RETRY_LIMIT); ++ osal_assert(0); ++ mtk_wcn_stp_dbg_dump_package(); ++ ++ /*Whole Chip Reset Procedure Invoke */ ++ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ ++ ++ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); ++ stp_dbg_set_host_assert_info(4, 36, 1); ++ STP_INFO_FUNC("**STP NoAck trigger firmware assert**\n"); ++ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); ++ ++ if (iRet) { ++ STP_ERR_FUNC("host tigger fw assert fail(%d), do noack handle flow\n", iRet); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ issue_type = STP_FW_NOACK_ISSUE; ++ iRet = stp_dbg_set_fw_info("STP NoAck", osal_strlen("STP NoAck"), issue_type); ++ ++ osal_dbg_assert_aee("[SOC_CONNSYS]NoAck", ++ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n F/W has NO any RESPONSE. Please check F/W status first\n"); ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) { ++ STP_SET_READY(stp_core_ctx, 0); ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ } ++ } else { ++ STP_INFO_FUNC("do trigger assert & chip reset in wmt\n"); ++ } ++ return; ++ } ++ } ++ ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ STP_WARN_FUNC("==============================================================================#\n"); ++} ++ ++static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len) ++{ ++ osal_buffer_dump(buf, title, len, 32); ++} ++ ++/***************************************************************************** ++ * FUNCTION ++ * stp_tx_timeout_handler ++ * DESCRIPTION ++ * tx timeout handler, send resync & retransmitt ++ * PARAMETERS ++ * void ++ * RETURNS ++ * void ++ *****************************************************************************/ ++static VOID stp_dump_tx_queue(UINT32 txseq) ++{ ++ INT32 tx_read, tx_length, last_len; ++ ++ tx_read = stp_core_ctx.tx_start_addr[txseq]; ++ tx_length = stp_core_ctx.tx_length[txseq]; ++ ++ STP_ERR_FUNC("tx_seq=%d ..", txseq); ++ ++ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { ++ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q", (tx_length >= 8) ? (8) : (tx_length)); ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - tx_read; ++ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q_0", (last_len >= 8) ? (8) : (last_len)); ++ stp_dump_data(&stp_core_ctx.tx_buf[0], "tx_q_0", ++ ((tx_length - last_len) ? (8) : (tx_length - last_len))); ++ } ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_is_apply_powersaving ++* DESCRIPTION ++* Check if STP support power saving mode. ++* PARAMETERS ++* ++* RETURNS ++* True: support power saving False: not support power saving ++*****************************************************************************/ ++static INT32 stp_is_apply_powersaving(VOID) ++{ ++ ++ if (STP_IS_READY(stp_core_ctx) && !stp_psm_is_disable(STP_PSM_CORE(stp_core_ctx))) { ++ /* osal_dbg_print("apply power saving\n"); */ ++ return MTK_WCN_BOOL_TRUE; ++ } ++ if (mtk_wcn_stp_is_sdio_mode()) ++ return MTK_WCN_BOOL_FALSE; ++ ++ STP_DBG_FUNC("not apply power saving\n"); ++ return MTK_WCN_BOOL_FALSE; ++} ++#if 0 ++/***************************************************************************** ++* FUNCTION ++* stp_is_privileges_cmd ++* DESCRIPTION ++* Check if the data is privilege command ++* PARAMETERS ++* ++* RETURNS ++* True/False ++*****************************************************************************/ ++static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type) ++{ ++ typedef struct privileges_cmd { ++ UINT32 length; ++ UINT8 type; ++ UINT8 buf[7]; /* MAX length of target command is only 5 currently */ ++ } p_cmd_t; ++ ++ p_cmd_t p_cmd_table[] = { ++ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x01} }, /* sleep command */ ++ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x02} }, /* host_awake command */ ++ }; ++ ++ UINT32 i; ++ UINT32 size = sizeof(p_cmd_table) / sizeof(p_cmd_table[0]); ++ ++ for (i = 0; i < size; i++) { ++ if (type != p_cmd_table[i].type) ++ continue; ++ ++ if (length != p_cmd_table[i].length) ++ continue; ++ ++ if (osal_memcmp(p_cmd_table[i].buf, buffer, length)) ++ continue; ++ ++ /* matched entry is found */ ++ STP_DBG_FUNC("It's p_cmd_t\n"); ++ return MTK_WCN_BOOL_TRUE; ++ } ++ ++ return MTK_WCN_BOOL_FALSE; ++} ++#endif ++/***************************************************************************** ++* FUNCTION ++* tx_queue_room_available ++* DESCRIPTION ++* check room if available, ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length) ++{ ++ UINT32 roomLeft; ++ ++ /* ++ Get available space of TX Queue ++ */ ++ if (stp_core_ctx.tx_read <= stp_core_ctx.tx_write) ++ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write + stp_core_ctx.tx_read - 1; ++ else ++ roomLeft = stp_core_ctx.tx_read - stp_core_ctx.tx_write - 1; ++ ++ if (roomLeft < length) { ++ STP_ERR_FUNC("%s: tx queue room shortage\n", __func__); ++ return MTK_WCN_BOOL_FALSE; ++ } else ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_add_to_tx_queue ++* DESCRIPTION ++* put data to tx queue ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length) ++{ ++ UINT32 last_len; ++ ++ /* Get available space of TX Queue */ ++ if (length + stp_core_ctx.tx_write < MTKSTP_BUFFER_SIZE) { ++ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, length); ++ stp_core_ctx.tx_write += length; ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write; ++ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, last_len); ++ osal_memcpy(stp_core_ctx.tx_buf, buffer + last_len, length - last_len); ++ ++ stp_core_ctx.tx_write = length - last_len; ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_add_to_rx_queue ++* DESCRIPTION ++* put data to corresponding task's rx queue and notify corresponding task ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] corresponding task index ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type) ++{ ++ UINT32 roomLeft, last_len; ++ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ if (stp_core_ctx.ring[type].read_p <= stp_core_ctx.ring[type].write_p) ++ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p + stp_core_ctx.ring[type].read_p - 1; ++ else ++ roomLeft = stp_core_ctx.ring[type].read_p - stp_core_ctx.ring[type].write_p - 1; ++ ++ if (roomLeft < length) { ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ STP_ERR_FUNC("Queue is full !!!, type = %d\n", type); ++ osal_assert(0); ++ return -1; ++ } ++ ++ if (length + stp_core_ctx.ring[type].write_p < MTKSTP_BUFFER_SIZE) { ++ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, length); ++ stp_core_ctx.ring[type].write_p += length; ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p; ++ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, last_len); ++ osal_memcpy(stp_core_ctx.ring[type].buffer, buffer + last_len, length - last_len); ++ stp_core_ctx.ring[type].write_p = length - last_len; ++ } ++ ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_tx_queue ++* DESCRIPTION ++* send data in tx buffer to common interface ++* PARAMETERS ++* txseq [IN] sequence number of outgoing packet in tx buffer ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_send_tx_queue(UINT32 txseq) ++{ ++ UINT32 ret; ++ INT32 tx_read, tx_length, last_len; ++ ++ tx_read = stp_core_ctx.tx_start_addr[txseq]; ++ tx_length = stp_core_ctx.tx_length[txseq]; ++ ++ stp_update_tx_queue(txseq); ++ ++ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { ++ ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], tx_length, &ret); ++ ++ if (ret != tx_length) { ++ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length, ret); ++ osal_assert(0); ++ } ++ } else { ++ last_len = MTKSTP_BUFFER_SIZE - tx_read; ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], last_len, &ret); ++ ++ if (ret != last_len) { ++ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", last_len, ret); ++ osal_assert(0); ++ } ++ ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], tx_length - last_len, &ret); ++ ++ if (ret != tx_length - last_len) { ++ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length - last_len, ret); ++ osal_assert(0); ++ } ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_ack ++* DESCRIPTION ++* send ack packet to the peer ++* PARAMETERS ++* txAck [IN] Ack number ++* nak [IN] 0 = ack; !0 = NAK ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_send_ack(UINT8 txAck, UINT8 nak) ++{ ++ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE]; ++ UINT32 ret; ++ INT32 iStatus; ++ ++ mtkstp_header[0] = 0x80 + (0 << 3) + txAck; /* stp_core_ctx.sequence.txack; */ ++ ++ if (fgEnableNak == 0) ++ mtkstp_header[1] = 0x00; /* disable NAK */ ++ else ++ mtkstp_header[1] = ((nak == 0) ? 0x00 : 0x80); ++ ++ mtkstp_header[2] = 0; ++ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; ++ ++ stp_dbg_pkt_log(STP_TASK_INDX, txAck, 0, 0, PKT_DIR_TX, NULL, 0); ++ ++ if (fgEnableDelimiter == 1) { ++ iStatus = (*sys_if_tx) ((PUINT8) &stp_delimiter[0], STP_DEL_SIZE, &ret); ++ STP_DUMP_PACKET_HEAD((PUINT8) &stp_delimiter[0], "tx del", STP_DEL_SIZE); ++ if (ret != STP_DEL_SIZE) { ++ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", STP_DEL_SIZE, ret, iStatus); ++ osal_assert(0); ++ } ++ } ++ ++ iStatus = (*sys_if_tx) (&mtkstp_header[0], MTKSTP_HEADER_SIZE, &ret); ++ ++ if (ret != MTKSTP_HEADER_SIZE) { ++ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", MTKSTP_HEADER_SIZE, ret, iStatus); ++ osal_assert(0); ++ } ++ ++} ++ ++INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type) ++{ ++ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; ++ UINT8 *p_tx_buf = NULL; ++ UINT16 crc; ++ INT32 ret = 0; ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ /*Only WMT can set raw data */ ++ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { ++ /* no op */ ++ /* NULL; */ ++ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { ++ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ ++ /* NULL; */ ++ } ++ /* STP over SDIO */ ++ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++ osal_printtimeofday("[ STP][SDIO][ B][W]"); ++ ++ mtkstp_header[0] = 0x80; ++ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); ++ mtkstp_header[2] = (length) & 0xff; ++ mtkstp_header[3] = 0x00; ++ ++ p_tx_buf = &stp_core_ctx.tx_buf[0]; ++ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); ++ p_tx_buf += MTKSTP_HEADER_SIZE; ++ ++ osal_memcpy(p_tx_buf, buffer, length); ++ p_tx_buf += length; ++ ++ temp[0] = 0x00; ++ temp[1] = 0x00; ++ osal_memcpy(p_tx_buf, temp, 2); ++ stp_dbg_pkt_log(type, ++ stp_core_ctx.sequence.txack, ++ stp_core_ctx.sequence.txseq, 0, PKT_DIR_TX, buffer, length); ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); ++ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { ++ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); ++ osal_assert(0); ++ ret = 0; ++ } else { ++ ret = (INT32) length; ++ } ++ ++ osal_printtimeofday("[ STP][SDIO][ E][W]"); ++ } ++ /* STP over BTIF OR UART */ ++ else if ((mtk_wcn_stp_is_btif_fullset_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++ ++ if ((stp_core_ctx.sequence.winspace > 0) && ++ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { ++ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; ++ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); ++ mtkstp_header[2] = length & 0xff; ++ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; ++ ++ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; ++ ++ if (fgEnableDelimiter == 1) { ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; ++ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); ++ } ++ ++ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); ++ ++ /*Make Payload */ ++ stp_add_to_tx_queue(buffer, length); ++ ++ /*Make CRC */ ++ crc = osal_crc16(buffer, length); ++ temp[0] = crc & 0xff; ++ temp[1] = (crc & 0xff00) >> 8; ++ stp_add_to_tx_queue(temp, 2); ++ ++ stp_dbg_pkt_log(type, ++ stp_core_ctx.sequence.txack, ++ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); ++ ++ /*Kick to UART */ ++ stp_send_tx_queue(stp_core_ctx.sequence.txseq); ++ INDEX_INC(stp_core_ctx.sequence.txseq); ++ stp_core_ctx.sequence.winspace--; ++ ++ /*Setup the Retry Timer */ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ else ++ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); ++ ++ ret = (INT32) length; ++ } else { ++ /* No winspace to send. Let caller retry */ ++ STP_ERR_FUNC("%s: There is no winspace/txqueue to send !!!\n", __func__); ++ ret = 0; ++ } ++ } ++ ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ ++ return ret; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_process_rxack ++* DESCRIPTION ++* process ack packet ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++static INT32 stp_process_rxack(VOID) ++{ ++ INT32 j, k; ++ UINT8 rxack; ++ INT32 fgResult = (-1); ++ ++ if (stp_core_ctx.sequence.rxack != stp_core_ctx.parser.ack) { ++ j = k = 0; ++ rxack = stp_core_ctx.sequence.rxack; ++ INDEX_INC(rxack); ++ while (rxack != stp_core_ctx.sequence.txseq) { ++ j++; ++ if (rxack == stp_core_ctx.parser.ack) { ++ k = 1; ++ break; ++ } ++ INDEX_INC(rxack); ++ } ++ if (k == 1) { ++ stp_core_ctx.sequence.rxack = stp_core_ctx.parser.ack; ++ stp_core_ctx.tx_read = stp_core_ctx.tx_start_addr[rxack] + stp_core_ctx.tx_length[rxack]; ++ if (stp_core_ctx.tx_read >= MTKSTP_BUFFER_SIZE) ++ stp_core_ctx.tx_read -= MTKSTP_BUFFER_SIZE; ++ ++ stp_core_ctx.sequence.winspace += j; ++ stp_core_ctx.sequence.retry_times = 0; ++ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ ++ fgResult = 0; ++ } ++ } ++ ++ return fgResult; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_process_packet ++* DESCRIPTION ++* process STP packet ++* PARAMETERS ++* void ++* RETURNS ++* void ++*****************************************************************************/ ++static VOID stp_process_packet(VOID) ++{ ++ INT32 fgTriggerResume = (-1); ++ UINT8 txAck = 0; ++ static INT32 fgRxOk; ++ MTK_WCN_BOOL b; ++ MTK_WCN_BOOL is_function_active = 0; ++ static INT32 stp_process_packet_fail_count; ++ INT32 iRet = -1; ++ ++ stp_dbg_pkt_log(stp_core_ctx.parser.type, ++ stp_core_ctx.parser.ack, ++ stp_core_ctx.parser.seq, ++ stp_core_ctx.parser.crc, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.parser.length); ++ /*Optimization */ ++ /*If bluez, direct send packet to hci_core not through RX buffer! */ ++ if ((stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) && ++ (stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { ++ /*Indicate packet to hci_stp */ ++ STP_DBG_FUNC("Send Packet to BT_SUBFUCTION, len = %d\n", stp_core_ctx.rx_counter); ++ ++ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); ++ if (b) ++ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ /*Process rx ack */ ++ fgTriggerResume = stp_process_rxack(); ++ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; ++ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); ++ txAck = stp_core_ctx.sequence.txack; ++ ++ /*Send ack back */ ++ stp_send_ack(txAck, 0); ++ ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ fgRxOk = 0; ++ } ++ /* sequence matches expected, enqueue packet */ ++ else if (stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) { ++ is_function_active = ++ ((*sys_check_function_status) (stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) == ++ STATUS_FUNCTION_ACTIVE); ++ /*If type is valid and function works, then try to enqueue */ ++ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && (is_function_active == MTK_WCN_BOOL_TRUE)) { ++ if (stp_core_ctx.parser.type == BT_TASK_INDX) { ++ static const UINT8 rst_buf[7] = { 0x04, 0x0e, 0x04, 0x01, 0x3, 0xc, 0x00 }; ++ ++ if (!osal_strncmp(stp_core_ctx.rx_buf, rst_buf, 7)) ++ osal_printtimeofday("############ BT Rest end <--"); ++ } ++ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ fgTriggerResume = stp_process_rxack(); ++ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; ++ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); ++ ++ /*Send tx ack */ ++ txAck = stp_core_ctx.sequence.txack; ++ stp_send_ack(txAck, 0); ++ ++ stp_ctx_unlock(&stp_core_ctx); ++#if CFG_WMT_LTE_COEX_HANDLING ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++ fgRxOk = ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, COEX_TASK_INDX); ++ } else { ++ fgRxOk = ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ } ++#else ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++ STP_WARN_FUNC("BT/WIFI & LTE coex in non-LTE projects,drop it...\n"); ++ } else { ++ fgRxOk = ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ } ++#endif ++ } else { ++ if (is_function_active == MTK_WCN_BOOL_FALSE) { ++ STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n", ++ stp_core_ctx.parser.type); ++ fgRxOk = 0; /*drop packet */ ++ } else { ++ STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n", ++ stp_core_ctx.parser.type); ++ fgRxOk = 0; /*drop packet */ ++ } ++ stp_ctx_lock(&stp_core_ctx); ++ ++ fgTriggerResume = stp_process_rxack(); ++ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; ++ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); ++ ++ /*Send tx ack */ ++ txAck = stp_core_ctx.sequence.txack; ++ stp_send_ack(txAck, 0); ++ ++ stp_ctx_unlock(&stp_core_ctx); ++ } ++ ++ /* enqueue successfully */ ++ if (fgRxOk == 0) { ++ stp_process_packet_fail_count = 0; ++ /*notify corresponding subfunction of incoming data */ ++#if CFG_WMT_LTE_COEX_HANDLING ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++#if 1 ++ STP_DBG_FUNC ++ ("WMT/LTE package:[0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x]\n", ++ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], stp_core_ctx.rx_buf[2], ++ stp_core_ctx.rx_buf[3], stp_core_ctx.rx_buf[4], stp_core_ctx.rx_buf[5], ++ stp_core_ctx.rx_buf[6], stp_core_ctx.rx_buf[7]); ++#endif ++ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#else ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && ++ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { ++ STP_WARN_FUNC("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); ++ } else { ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#endif ++ } else { ++ stp_process_packet_fail_count++; ++ /*Queue is full */ ++ if (stp_core_ctx.parser.type == GPS_TASK_INDX) { ++ /*Clear Rx Queue if GPS */ ++ mtk_wcn_stp_flush_rx_queue(GPS_TASK_INDX); ++ } else { ++ /*notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++ /*enqueue fail, don't send ack and wait for peer retry */ ++ STP_ERR_FUNC("Enqueue to Rx queue fail, maybe function %d queue is full\n", ++ stp_core_ctx.parser.type); ++ } ++ } ++ /*sequence not match && previous packet enqueue successfully, send the previous ACK */ ++ else if (fgRxOk == 0) { ++ STP_ERR_FUNC("mtkstp_process_packet: expected_rxseq = %d, parser.seq = %d\n", ++ stp_core_ctx.sequence.expected_rxseq, stp_core_ctx.parser.seq); ++ stp_process_packet_fail_count++; ++ ++ stp_ctx_lock(&stp_core_ctx); ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ txAck = stp_core_ctx.sequence.txack; ++ stp_send_ack(txAck, 1); ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ STP_ERR_FUNC ++ ("sequence not match && previous packet enqueue successfully, send the previous ACK (ack no =%d)\n", ++ txAck); ++ } ++ /*sequence not match && previous packet enqueue failed, do nothing, make the other side timeout */ ++ else { ++ stp_process_packet_fail_count++; ++ STP_ERR_FUNC ++ ("sequence not match && previous packet enqueue failed, do nothing, make the other side timeout\n"); ++ } ++ ++ if (fgTriggerResume == 0) { ++ /*[PatchNeed]Just Notificaiton, not blocking call */ ++ /* notify adaptation layer for possible tx resume mechanism */ ++ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); ++ } ++ ++ if (stp_process_packet_fail_count > MTKSTP_RETRY_LIMIT) { ++ stp_process_packet_fail_count = 0; ++ STP_ERR_FUNC("The process packet fail count > 10 lastly\n\r, whole chip reset\n\r"); ++ mtk_wcn_stp_dbg_dump_package(); ++ /*Whole Chip Reset Procedure Invoke */ ++ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ ++ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); ++ stp_dbg_set_host_assert_info(4, 37, 1); ++ STP_INFO_FUNC("**Ack Miss trigger firmware assert**\n"); ++ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); ++ if (iRet) { ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ /* (*sys_dbg_assert_aee)("[MT662x]Ack Miss", "**STP Ack Miss**\n Ack Miss.\n"); */ ++ osal_dbg_assert_aee("[SOC_CONSYS]Ack Miss", ++ "**[WCN_ISSUE_INFO]STP Ack Miss**\n Ack Miss.\n"); ++ ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) { ++ STP_SET_READY(stp_core_ctx, 0); ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ } ++ } ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_init ++* DESCRIPTION ++* init STP kernel ++* PARAMETERS ++* cb_func [IN] function pointers of system APIs ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func) ++{ ++ INT32 ret = 0; ++ INT32 i = 0; ++ ++ /* Function pointer to point to the currently used transmission interface ++ */ ++ sys_if_tx = cb_func->cb_if_tx; ++ ++ /* Used to inform the function driver has received the corresponding type of information */ ++ sys_event_set = cb_func->cb_event_set; ++ ++ /* Used to inform the function driver can continue to send information and ++ STP has resources to deal with ++ */ ++ sys_event_tx_resume = cb_func->cb_event_tx_resume; ++ ++ /* STP driver determines whether the function is enable. If not enable and ++ STP has received the kind of information, and STP have the right to put it away. ++ */ ++ sys_check_function_status = cb_func->cb_check_funciton_status; ++ ++ /* osal_unsleepable_lock_init(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock_init(&stp_core_ctx); ++ /* Setup timer to be used to check if f/w receive the data in the specific time ++ interval after being sent ++ */ ++ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) ++ osal_unsleepable_lock_init(&stp_core_ctx.ring[i].mtx); ++ ++ stp_core_ctx.tx_timer.timeoutHandler = stp_tx_timeout_handler; ++ stp_core_ctx.tx_timer.timeroutHandlerData = 0; ++ osal_timer_create(&stp_core_ctx.tx_timer); ++ ++ STP_SET_BT_STK(stp_core_ctx, 0); ++ STP_SET_ENABLE(stp_core_ctx, 0); ++ STP_SET_ENABLE_DBG(stp_core_ctx, 0); ++ STP_SET_ENABLE_RST(stp_core_ctx, 0); ++ STP_SET_PENDING_TYPE(stp_core_ctx, 0); ++ STP_SET_READY(stp_core_ctx, 0); ++ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, 0); ++ STP_SET_PSM_CORE(stp_core_ctx, stp_psm_init()); ++ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, 0); ++ STP_ENABLE_FW_COREDUMP(stp_core_ctx, 0); ++ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, 0); ++ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, 0); ++ ++ if (!STP_PSM_CORE(stp_core_ctx)) { ++ ret = (-3); ++ goto ERROR; ++ } ++ ++ STP_SET_BTM_CORE(stp_core_ctx, stp_btm_init()); ++ if (!STP_BTM_CORE(stp_core_ctx)) { ++ STP_ERR_FUNC("STP_BTM_CORE(stp_core_ctx) initialization fail!\n"); ++ ret = (-3); ++ goto ERROR; ++ } ++ ++ if (STP_BTM_CORE(stp_core_ctx) != NULL) ++ g_mtkstp_dbg = stp_dbg_init(STP_BTM_CORE(stp_core_ctx)); ++ else ++ g_mtkstp_dbg = stp_dbg_init(NULL); ++ ++ if (!g_mtkstp_dbg) { ++ STP_ERR_FUNC("g_mtkstp_dbg initialization fail!\n"); ++ ret = (-3); ++ goto ERROR; ++ } ++ STP_SET_ENABLE_RST(stp_core_ctx, 1); ++#ifdef CONFIG_LOG_STP_INTERNAL ++ mtk_wcn_stp_dbg_enable(); ++#else ++ mtk_wcn_stp_dbg_enable(); ++#endif ++ goto RETURN; ++ ++ERROR: ++ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); ++ ++RETURN: ++ return ret; ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_deinit ++* DESCRIPTION ++* deinit STP kernel ++* PARAMETERS ++* void ++* RETURNS ++* INT32 0 = success, others = failure ++*****************************************************************************/ ++INT32 mtk_wcn_stp_deinit(void) ++{ ++ UINT32 i = 0; ++ ++ sys_if_tx = NULL; ++ sys_event_set = NULL; ++ sys_event_tx_resume = NULL; ++ sys_check_function_status = NULL; ++ ++ stp_dbg_deinit(g_mtkstp_dbg); ++ stp_btm_deinit(STP_BTM_CORE(stp_core_ctx)); ++ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); ++ ++ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) ++ osal_unsleepable_lock_deinit(&stp_core_ctx.ring[i].mtx); ++ ++ stp_ctx_lock_deinit(&stp_core_ctx); ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_btm_get_dmp ++* DESCRIPTION ++* get stp dump related information ++* PARAMETERS ++* buffer: dump placement, len: dump size ++* RETURNS ++* 0: Success Negative Value: Fail ++*****************************************************************************/ ++ ++int mtk_wcn_stp_btm_get_dmp(char *buf, int *len) ++{ ++ return stp_dbg_dmp_out(g_mtkstp_dbg, buf, len); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_notify_stp ++* DESCRIPTION ++* WMT notification to STP that power saving job is done or not ++* PARAMETERS ++* ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++int mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action) ++{ ++ return stp_psm_notify_stp(STP_PSM_CORE(stp_core_ctx), action); ++} ++ ++int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state) ++{ ++ return stp_psm_set_state(STP_PSM_CORE(stp_core_ctx), state); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_enable ++* DESCRIPTION ++* enable STP sleep/wakeup support ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep) ++{ ++#if 0 ++ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { ++ if (mtk_wcn_stp_is_ready()) ++ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ } ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); ++ return 0; ++ } ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ ++#else ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); ++ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); ++ return 0; ++ } ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++#endif ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_psm_disable ++* DESCRIPTION ++* disable STP sleep/wakeup support ++* PARAMETERS ++* void ++* RETURNS ++* 0: Sccuess Negative value: Fail ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_psm_disable(VOID) ++{ ++#if 0 ++ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { ++ if (mtk_wcn_stp_is_ready()) ++ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ } ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ return 0; ++ } ++ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return -1; ++ ++#else ++ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { ++ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ } else if (mtk_wcn_stp_is_sdio_mode()) { ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ return 0; ++ } ++ STP_DBG_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); ++ return 0; ++ ++#endif ++} ++ ++extern INT32 mtk_wcn_stp_psm_reset(VOID) ++{ ++ return stp_psm_reset(STP_PSM_CORE(stp_core_ctx)); ++} ++ ++extern INT32 mtk_wcn_stp_dbg_disable(VOID) ++{ ++ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { ++ STP_DBG_FUNC("STP dbg mode is turned off\n"); ++ STP_SET_ENABLE_DBG(stp_core_ctx, 0); ++ stp_dbg_disable(g_mtkstp_dbg); ++ } else { ++ STP_WARN_FUNC("STP dbg mode has been turned off\n"); ++ } ++ ++ return 0; ++} ++ ++extern INT32 mtk_wcn_stp_dbg_enable(VOID) ++{ ++ if (STP_NOT_ENABLE_DBG(stp_core_ctx)) { ++ STP_DBG_FUNC("STP dbg mode is turned on\n"); ++ STP_SET_ENABLE_DBG(stp_core_ctx, 1); ++ stp_dbg_enable(g_mtkstp_dbg); ++ } else { ++ STP_WARN_FUNC("STP dbg mode has been turned on\n"); ++ } ++ ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on) ++{ ++ stp_dbg_log_ctrl(on); ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on) ++{ ++ STP_ENABLE_FW_COREDUMP(stp_core_ctx, on); ++ STP_INFO_FUNC("coredump function mode: %d.\n", on); ++ g_coredump_mode = on; ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_coredump_flag_get(VOID) ++{ ++ return STP_ENABLE_FW_COREDUMP_FLAG(stp_core_ctx); ++} ++ ++static INT32 stp_parser_data_in_mand_mode(UINT32 length, UINT8 *p_data) ++{ ++ UINT8 padding_len = 0; ++ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ ++ MTK_WCN_BOOL is_function_active = 0; ++ INT32 i = length; ++ ++ while (i > 0) { ++ switch (stp_core_ctx.parser.state) { ++ case MTKSTP_SYNC: /* b'10 */ ++ /* if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) */ ++ /* if(*p_data == 0x80) */ ++ if ((*p_data & 0x80) == 0x80) { ++ /* STP_DBG_FUNC("[STP] STP Packet Start =========>\n"); */ ++ if (*p_data != 0x80) ++ STP_WARN_FUNC("SDIO not 0x80!!(0x%x)\n", *p_data); ++ ++ if (i >= 4) { ++#if !(REMOVE_USELESS_LOG) ++ /*print header, when get the full STP header */ ++ UINT32 type = (*(p_data + 1) & 0x70) >> 4; ++ UINT8 *type_name = ""; ++ ++ type_name = stp_type_to_dbg_string(type); ++ STP_DBG_FUNC( ++ "STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", ++ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), ++ type_name, ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), ++ (*p_data & 0x38) >> 3, *p_data & 0x07); ++#endif ++ } else { ++ STP_WARN_FUNC("STP Rx: discard due to i < 4 (%d)\n", i); ++ } ++ ++ /* STP_DBG_FUNC("[STP] sync->nak\n"); */ ++ stp_change_rx_state(MTKSTP_NAK); ++ stp_core_ctx.rx_counter++; ++ } else { ++ STP_WARN_FUNC("sync to sync!!(0x%x)\n", *p_data); ++ stp_change_rx_state(MTKSTP_SYNC); ++ } ++ break; ++ ++ case MTKSTP_NAK: ++ /* STP_DBG_FUNC("[STP] nak->length\n"); */ ++ stp_change_rx_state(MTKSTP_LENGTH); ++ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; ++ if (stp_core_ctx.parser.type <= MTKSTP_MAX_TASK_NUM) { ++ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; ++ stp_core_ctx.rx_counter++; ++ } else { ++ STP_WARN_FUNC("nak to sync\n"); ++ stp_change_rx_state(MTKSTP_SYNC); ++ } ++ break; ++ ++ case MTKSTP_LENGTH: ++ /* STP_DBG_FUNC("[STP] length -> checksum\n"); */ ++ stp_change_rx_state(MTKSTP_CHECKSUM); ++ stp_core_ctx.parser.length += *p_data; ++ ++ /*Valid length checking */ ++ if (stp_core_ctx.parser.length < 2000) { ++ stp_core_ctx.rx_counter++; ++ } else { ++ STP_WARN_FUNC("The length of STP packet is not valid !!! length = %d\n", ++ stp_core_ctx.parser.length); ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ /* return -1; */ ++ } ++ ++ break; ++ ++ case MTKSTP_CHECKSUM: ++ ++ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || ++ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { ++ stp_change_rx_state(MTKSTP_FW_MSG); ++ stp_core_ctx.rx_counter = 0; ++ i -= 1; ++ if (i != 0) ++ p_data += 1; ++ ++ continue; ++ } ++ ++ if (stp_core_ctx.parser.length == 0) { ++ STP_WARN_FUNC("checksum to sync\n"); ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ } else { ++ /* STP_DBG_FUNC("[STP] checksum->data\n"); */ ++ stp_change_rx_state(MTKSTP_DATA); ++ stp_core_ctx.rx_counter = 0; ++ } ++ break; ++ ++ case MTKSTP_DATA: ++ ++ /* block copy instead of byte copy */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ osal_assert(0); ++ } ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ if (i >= remain_length) { ++ /*boundary checking */ ++ if (stp_core_ctx.rx_counter + remain_length >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC("Abnormal!! Memory operation over boundary!!\n"); ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ return -1; ++ } ++ ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ stp_core_ctx.parser.state = MTKSTP_CRC1; ++ continue; ++ ++ } else { /* only copy by data length */ ++ ++ /*fixed klocwork insight issue */ ++ /*boundary checking */ ++ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC("Abnormal!! Memory operation over boundary 2!!\n"); ++ stp_core_ctx.rx_counter = 0; ++ return -1; ++ } ++ ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); ++ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ ++ i = 0; ++ p_data += i; ++ continue; ++ } ++ break; ++ ++ case MTKSTP_CRC1: ++ stp_change_rx_state(MTKSTP_CRC2); ++ break; ++ ++ case MTKSTP_CRC2: ++#if 1 ++ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { ++ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; ++ STP_DBG_FUNC("wmt sub type (0x%x)\n", stp_core_ctx.parser.wmtsubtype); ++ } ++#endif ++ /*SDIO mode do it. */ ++ if (mtk_wcn_stp_is_sdio_mode()) { ++ /*STP packet 4-bytes alignment */ ++ /*Discard padding bytes , otherwise make parser state machine disorder */ ++ if (i <= 4) { ++ /*STP_DBG_FUNC("STP last block padding %d bytes\n", i-1); */ ++ p_data += (i - 1); ++ i -= (i - 1); ++ } else { ++ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; ++ p_data += padding_len; ++ i -= padding_len; ++ /*STP_DBG_FUNC("STP Agg padding %d bytes\n", padding_len); */ ++ } ++ } ++ stp_dbg_pkt_log(stp_core_ctx.parser.type, ++ 0, 0, 0, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); ++ if ((stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { ++ int b; ++ ++ /*Indicate packet to hci_stp */ ++ if (gStpDbgLvl >= STP_LOG_DBG) { ++ stp_dump_data(stp_core_ctx.rx_buf, "indicate_to_bt_core", ++ stp_core_ctx.rx_counter); ++ } ++ ++ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); ++ if (b) ++ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); ++ ++ } else { ++ ++ is_function_active = ( ++ (*sys_check_function_status)(stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) ++ == STATUS_FUNCTION_ACTIVE); ++ ++ /*check type and function if active? */ ++ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) ++ && (is_function_active == MTK_WCN_BOOL_TRUE)) { ++#if CFG_WMT_LTE_COEX_HANDLING ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) ++ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { ++ STP_INFO_FUNC("wmt/lte coex package!\n"); ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, ++ stp_core_ctx.rx_counter, COEX_TASK_INDX); ++ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, ++ stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ ++ /*notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#else ++ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) ++ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { ++ STP_WARN_FUNC ++ ("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); ++ } else { ++ stp_add_to_rx_queue(stp_core_ctx.rx_buf, ++ stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type); ++ ++ /*notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (stp_core_ctx.parser.type); ++ } ++#endif ++ } else { ++ if (is_function_active == MTK_WCN_BOOL_FALSE) { ++ STP_ERR_FUNC ++ ("function type = %d is inactive, so no en-queue to rx\n", ++ stp_core_ctx.parser.type); ++ } else { ++ STP_ERR_FUNC ++ ("mtkstp_process_packet: type = %x, the type is invalid\n", ++ stp_core_ctx.parser.type); ++ } ++ } ++ } ++ ++ /* STP_DBG_FUNC("[STP] crc2->sync\n"); */ ++ /* STP_DBG_FUNC("[STP] STP Packet End <=========\n"); */ ++ stp_core_ctx.rx_counter = 0; ++ stp_change_rx_state(MTKSTP_SYNC); ++ ++ break; ++ ++ case MTKSTP_FW_MSG: ++ ++ /*f/w assert and exception information */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ } ++ ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ ++ if (i >= remain_length) { ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; ++ /*Trace32 Dump */ ++ if (stp_core_ctx.parser.type == STP_TASK_INDX) { ++ /* g_block_tx = 1; */ ++ mtk_wcn_stp_coredump_start_ctrl(1); ++ pr_debug("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); ++ /*use paged dump or full dump */ ++ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); ++#if 0 ++ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_DMP /*STP_DBG_FW_ASSERT */ , 5, ++ 0, 0, 0, 0, ++ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); ++#endif ++ } ++ ++ /*discard CRC */ ++ /* we will discard antoher CRC on the outer switch procedure. */ ++ if (i >= 1) { ++ STP_INFO_FUNC("crc discard.. i = %d\n", i); ++ i -= 1; ++ if (i > 0) ++ p_data += 1; ++ ++ } ++ ++ /*STP packet 4-bytes alignment */ ++ /*Discard padding bytes , otherwise make parser state machine disorder */ ++ if (i <= 4) { ++ STP_INFO_FUNC ++ ("\n[STP]FW_EVENT========= block padding %d bytes =========\n", ++ i - 1); ++ p_data += (i - 1); ++ i -= (i - 1); ++ } else { ++ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; ++ p_data += padding_len; ++ i -= padding_len; ++ STP_INFO_FUNC ++ ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n", ++ padding_len); ++ } ++ stp_change_rx_state(MTKSTP_SYNC); ++ ++ } else { /* only copy by data length */ ++ ++ STP_ERR_FUNC("raw data doesn't contain full stp packet!!\n"); ++ } ++ break; ++ default: ++ break; ++ } ++ p_data++; ++ i--; ++ } ++ ++ return 0; ++} ++ ++static INT32 stp_parser_data_in_full_mode(UINT32 length, UINT8 *p_data) ++{ ++ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ ++ INT32 i = length; ++ ++ while (i > 0) { ++ switch (stp_core_ctx.parser.state) { ++ ++ case MTKSTP_RESYNC1: /* RESYNC must be 4 _continuous_ 0x7f */ ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_RESYNC2); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_RESYNC2: ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_RESYNC3); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_RESYNC3: ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_RESYNC4); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_RESYNC4: ++ if (*p_data == 0x7f) ++ stp_change_rx_state(MTKSTP_SYNC); ++ else ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ break; ++ case MTKSTP_SYNC: /* b'10 */ ++ STP_DUMP_PACKET_HEAD(p_data, "rx (uart):", length > 4 ? 4 : length); ++ if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) { ++ stp_change_rx_state(MTKSTP_NAK); ++ stp_core_ctx.parser.seq = (*p_data & 0x38) >> 3; ++ stp_core_ctx.parser.ack = *p_data & 0x07; ++ stp_core_ctx.rx_buf[0] = *p_data; ++ /* Geoge FIXME: WHY comment the following line? */ ++ /* stp_core_ctx.rx_counter++; */ ++ ++ if (i >= 4 && gStpDbgLvl >= STP_LOG_DBG) { ++ /*print header, when get the full STP header */ ++#if !(REMOVE_USELESS_LOG) ++ int type = (*(p_data + 1) & 0x70) >> 4; ++ char *type_name = ""; ++ ++ type_name = stp_type_to_dbg_string(type); ++ ++ STP_DBG_FUNC ++ ("STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", ++ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), type_name, ++ ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), ++ (*p_data & 0x38) >> 3, *p_data & 0x07); ++#endif ++ } else { ++ STP_DBG_FUNC("STP Rx: discard due to i < 4\n"); ++ } ++ } else if ((*p_data == 0x7f) && (prev_state == MTKSTP_RESYNC4)) { ++ /* if this 0x7f is continuous to resync pattern */ ++ /* skip this continuous 0x7f, remain current & prev state */ ++ osal_assert(0); ++ STP_ERR_FUNC("MTKSTP_SYNC: continuous resync pattern, buff = %x\n", *p_data); ++ } else if (*p_data == 0x7f) { /* a start of 0x7f, maybe this is resync pattern */ ++ stp_change_rx_state(MTKSTP_RESYNC2); ++ osal_assert(0); ++ STP_ERR_FUNC("MTKSTP_SYNC: go to MTKSTP_RESYNC2, buff = %x\n", *p_data); ++ } else if (*p_data == 0x55) { /* STP delimiter */ ++ /* do nothing for delimiter */ ++ } else { /* unexpected, go to resync1 */ ++ osal_assert(0); ++ STP_ERR_FUNC("MTKSTP_SYNC: unexpected data, buff = %x\n", *p_data); ++ } ++ break; ++ ++ case MTKSTP_NAK: ++ /* (*sys_dbg_print)("MTKSTP_NAK : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ ++ if (fgEnableNak == 0) ++ stp_core_ctx.parser.nak = 0; /* disable NAK */ ++ else ++ stp_core_ctx.parser.nak = (*p_data & 0x80) >> 7; ++ ++ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; ++ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; ++ stp_core_ctx.rx_buf[1] = *p_data; ++ /* Geoge FIXME: WHY comment the following line? */ ++ /*stp_core_ctx.rx_counter++; */ ++ if (stp_core_ctx.parser.nak) ++ STP_ERR_FUNC("MTKSTP_NAK TRUE: mtk_wcn_stp_parser_data, buff = %x\n", *p_data); ++ ++ if (stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) ++ stp_change_rx_state(MTKSTP_LENGTH); ++ else ++ stp_change_rx_state(MTKSTP_SYNC); ++ break; ++ ++ case MTKSTP_LENGTH: ++ /* (*sys_dbg_print)("MTKSTP_LENGTH : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ ++ stp_change_rx_state(MTKSTP_CHECKSUM); ++ stp_core_ctx.parser.length += *p_data; ++ ++ /*Valid length checking */ ++ if (stp_core_ctx.parser.length > 2048) { ++ STP_ERR_FUNC("The length of STP packet is not valid !!! length = %d\n", ++ stp_core_ctx.parser.length); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ STP_TRACE_FUNC("--\n"); ++ return -1; ++ } ++ ++ stp_core_ctx.rx_buf[2] = *p_data; ++ /* Geoge FIXME: WHY comment the following line? */ ++ /*stp_core_ctx.rx_counter++; */ ++ break; ++ ++ case MTKSTP_CHECKSUM: ++ /* (*sys_dbg_print)("MTKSTP_CHECKSUM : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ ++ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || ++ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { ++ stp_change_rx_state(MTKSTP_FW_MSG); ++ stp_core_ctx.rx_counter = 0; ++ i -= 1; ++ if (i != 0) ++ p_data += 1; ++ ++ continue; ++ } ++ ++ if (((stp_core_ctx.rx_buf[0] + ++ stp_core_ctx.rx_buf[1] + stp_core_ctx.rx_buf[2]) & 0xff) == *p_data) { ++ /* header only packet */ ++ if (stp_core_ctx.parser.length == 0) { ++ INT32 fgTriggerResume = (-1); ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ if (stp_core_ctx.inband_rst_set == 0) { ++ stp_dbg_pkt_log(STP_TASK_INDX, ++ stp_core_ctx.parser.ack, ++ stp_core_ctx.parser.seq, ++ 5, /* STP type id */ ++ PKT_DIR_RX, ++ NULL, ++ 0); ++ fgTriggerResume = stp_process_rxack(); ++ } else { ++ STP_WARN_FUNC ++ ("Now it's inband reset process and drop ACK packet.\n"); ++ } ++ ++ if (fgTriggerResume == 0) { ++ /* notify adaptation layer for ++ * possible tx resume mechanism ++ */ ++ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); ++ } ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.rx_counter = 0; ++ } else { ++ stp_change_rx_state(MTKSTP_DATA); ++ stp_core_ctx.rx_counter = 0; ++ } ++ } else { ++ STP_ERR_FUNC("The checksum of header is error !!! %02x %02x %02x %02x\n", ++ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], ++ stp_core_ctx.rx_buf[2], *p_data); ++ /* George FIXME: error handling mechanism shall be refined */ ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ ++ /* since checksum error is usually related to interface ++ * buffer overflow, so we just let timeout mechanism to ++ * handle such error. ++ */ ++ STP_TRACE_FUNC("--\n"); ++ /* return and purge COMM port */ ++ return -1; ++ /*stp_send_ack(1); NAK mechanism is removed */ ++ } ++ break; ++ ++ case MTKSTP_DATA: ++#if 0 ++ if (stp_core_ctx.rx_counter < stp_core_ctx.parser.length) { ++ stp_core_ctx.rx_buf[stp_core_ctx.rx_counter] = *p_data; ++ stp_core_ctx.rx_counter++; ++ } ++ if (stp_core_ctx.rx_counter == stp_core_ctx.parser.length) ++ stp_change_rx_state(MTKSTP_CRC1); ++#else ++ /* block copy instead of byte copy */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ osal_assert(0); ++ } ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ if (i >= remain_length) { ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ stp_core_ctx.parser.state = MTKSTP_CRC1; ++ continue; ++ } else { /* only copy by data length */ ++ ++ /*fixed klocwork insight issue */ ++ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC ++ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ STP_TRACE_FUNC("--\n"); ++ return -1; ++ } ++ ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); ++ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ ++ i = 0; ++ p_data += i; ++ continue; ++ } ++#endif ++ break; ++ ++ case MTKSTP_CRC1: ++ stp_change_rx_state(MTKSTP_CRC2); ++ stp_core_ctx.parser.crc = *p_data; ++ break; ++ case MTKSTP_CRC2: ++ stp_change_rx_state(MTKSTP_SYNC); ++ stp_core_ctx.parser.crc += (*p_data) << 8; ++#if 1 ++ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { ++ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; ++ STP_DBG_FUNC("wmt sub type is (0x%x)\n", stp_core_ctx.parser.wmtsubtype); ++ } ++#endif ++ if (stp_check_crc(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, stp_core_ctx.parser.crc) ++ == MTK_WCN_BOOL_TRUE) { ++ if (stp_core_ctx.inband_rst_set == 0) ++ stp_process_packet(); ++ else ++ STP_WARN_FUNC("Now it's inband reset process and drop packet.\n"); ++ } else { ++ STP_ERR_FUNC("The CRC of packet is error !!!\n"); ++ /* George FIXME: error handling mechanism shall be refined */ ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ ++ /* since checksum error is usually related to interface ++ * buffer overflow, so we just let timeout mechanism to ++ * handle such error. ++ */ ++ STP_TRACE_FUNC("--\n"); ++ /* return and purge COMM port */ ++ return -1; ++ /*stp_send_ack(1); NAK mechanism is removed */ ++ } ++ break; ++ ++ case MTKSTP_FW_MSG: ++#if CFG_WMT_DUMP_INT_STATUS ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ if (STP_IS_READY(stp_core_ctx)) ++ mtk_wcn_stp_dbg_dump_package(); ++ ++ STP_SET_READY(stp_core_ctx, 0); ++ /*stp inband reset */ ++ if (stp_core_ctx.parser.type == STP_TASK_INDX && ++ stp_core_ctx.parser.seq == 0 && ++ stp_core_ctx.parser.ack == 0 && ++ stp_core_ctx.parser.length == 0 && stp_core_ctx.inband_rst_set == 1) { ++ STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r"); ++ stp_rest_ctx_state(); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.inband_rst_set = 0; ++ /* STP_INFO_FUNC("Restart STP Timer\n\r"); */ ++ /* (*sys_timer_start)(stp_core_ctx.tx_timer, ++ * mtkstp_tx_timeout, ++ * (MTK_WCN_TIMER_CB)stp_tx_timeout_handler, ++ * NULL); ++ */ ++ STP_TRACE_FUNC("--\n"); ++ return 0; ++ } ++ ++ /*f/w assert and exception information */ ++ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { ++ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", ++ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); ++ osal_assert(0); ++ } ++ ++ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; ++ if (i >= remain_length) { ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, ++ remain_length); ++ i -= remain_length; ++ p_data += remain_length; ++ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; ++ stp_change_rx_state(MTKSTP_SYNC); ++ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; ++ /* STP_ERR_FUNC("%s [%d]\n", stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); */ ++#if 0 ++ if ((stp_core_ctx.rx_counter == 1) && (stp_core_ctx.rx_buf[0] == 0xFF)) { ++ /* For MT6620, enable/disable coredump function is controlled by ++ * firmware for the moment, we need to set coredump enable flag ++ * to be 1 after see firmware send a pariticallar character(0xff) ++ * before any coredump packet is sent ++ */ ++ mtk_wcn_stp_coredump_flag_ctrl(1); ++ } ++#endif ++ /*Trace32 Dump */ ++ if (STP_IS_ENABLE_DBG(stp_core_ctx) && ++ (stp_core_ctx.parser.type == STP_TASK_INDX)) { ++ if (0 != stp_core_ctx.rx_counter) { ++ STP_SET_READY(stp_core_ctx, 0); ++ mtk_wcn_stp_ctx_save(); ++ STP_INFO_FUNC("++ start to read paged dump and paged trace ++\n"); ++ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); ++ stp_btm_notify_wmt_trace_wq(stp_core_ctx.btm); ++ STP_INFO_FUNC("++ start to read paged dump and paged trace --\n"); ++ ++ } ++ STP_INFO_FUNC("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, ++ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); ++ } ++ ++ /*Runtime FW Log */ ++ else if (STP_IS_ENABLE_DBG(stp_core_ctx) ++ && (stp_core_ctx.parser.type == INFO_TASK_INDX)) { ++ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0, ++ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); ++ mtk_wcn_stp_dbg_dump_package(); ++ } ++ /*Normal mode: whole chip reset */ ++ else { ++ /*Aee Kernel Warning Message Shown First */ ++ /* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */ ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ mtk_wcn_stp_dbg_dump_package(); ++ ++ osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf); ++ /*Whole Chip Reset Procedure Invoke */ ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) { ++ STP_SET_READY(stp_core_ctx, 0); ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ } else { ++ STP_INFO_FUNC ++ ("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ } ++ /*discard CRC */ ++ if (i >= 2) { ++ STP_DBG_FUNC("crc discard.. i = %d\n", i); ++ i -= 2; ++ if (i > 0) ++ p_data += 2; ++ } ++ continue; ++ } else { /* only copy by data length */ ++ ++ /*fixed klocwork insight issue */ ++ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { ++ STP_ERR_FUNC ++ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); ++ stp_change_rx_state(MTKSTP_RESYNC1); ++ stp_core_ctx.rx_counter = 0; ++ return -1; ++ } ++ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); ++ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ ++ i = 0; ++ p_data += i; ++ continue; ++ } ++ ++ break; ++ default: ++ break; ++ } ++ p_data++; ++ i--; ++ } ++ ++ return 0; ++} ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_parser_data ++* DESCRIPTION ++* push data to serial transport protocol parser engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* int 0 = success; -1 = crc/checksum error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++int _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) ++#else ++int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) ++#endif ++{ ++ /*----------------------------------------------------------------*/ ++ /* Local Variables */ ++ /*----------------------------------------------------------------*/ ++ INT32 i; ++ UINT8 *p_data; ++ INT32 ret = 0; ++#ifdef DEBUG_DUMP_PACKET_HEAD ++ static UINT32 counter; ++ ++ STP_TRACE_FUNC("++, rx (cnt=%d,len=%d)\n", ++counter, length); ++#endif ++ ++#if 0 ++#ifdef CONFIG_POWER_SAVING_SUPPORT ++ if (stp_is_apply_powersaving()) { ++ /* If now chip is awake, to restart monitor! */ ++ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { ++ STP_DBG_FUNC("To restart moinotr when rx\n\r"); ++ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); ++ } ++ } ++#endif ++#endif ++ ++ /*----------------------------------------------------------------*/ ++ /* Code Body */ ++ /*----------------------------------------------------------------*/ ++ /* George FIXME: WHY or HOW can we reduct the locked region? */ ++ /*flags = (*sys_mutex_lock)(stp_core_ctx.stp_mutex); */ ++ i = length; ++ p_data = (UINT8 *) buffer; ++ ++/* stp_dump_data(buffer, "rx queue", length); */ ++ ++ /*STP is not enabled and only WMT can use Raw data path */ ++ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == STP_PENDING_TYPE(stp_core_ctx)) { ++ /* route to task who send command */ ++ stp_add_to_rx_queue(buffer, length, STP_PENDING_TYPE(stp_core_ctx)); ++ ++ /* mike: notify corresponding subfunction of incoming data */ ++ (*sys_event_set) (STP_PENDING_TYPE(stp_core_ctx)); ++ } ++ /* STP over SDIO */ ++ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++#if !(REMOVE_USELESS_LOG) ++ if (gStpDbgLvl >= STP_LOG_DBG) ++ stp_dump_data(buffer, "sdio parser_in", length); ++#endif ++ /* STP_DBG_FUNC("sdio stp parser data length = %d\n", length); */ ++ ret = stp_parser_data_in_mand_mode(i, p_data); ++ } ++ /* STP over UART */ ++ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) ++ ret = stp_parser_data_in_full_mode(i, p_data); ++ ++ /* George FIXME: WHY or HOW can we reduct the locked region? */ ++ /*(*sys_mutex_unlock)(stp_core_ctx.stp_mutex, flags); */ ++ STP_TRACE_FUNC("--\n"); ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_parser_data); ++#endif ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_enable ++* DESCRIPTION ++* enable/disable STP ++* PARAMETERS ++* value [IN] 0=disable, others=enable ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++INT32 mtk_wcn_stp_enable(INT32 value) ++{ ++ STP_DBG_FUNC("%s: set the current enable = (%d)\n", __func__, value); ++ ++ stp_rest_ctx_state(); ++ STP_SET_ENABLE(stp_core_ctx, value); ++ if (!value) { ++ mtk_wcn_stp_psm_reset(); ++ } else { ++/* g_block_tx = 0; */ ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ } ++ return 0; ++} ++ ++INT32 mtk_wcn_stp_dbg_dump_package(VOID) ++{ ++ if (STP_NOT_ENABLE(stp_core_ctx)) { ++ STP_INFO_FUNC("STP dbg mode is off\n"); ++ ++ } else { ++ STP_INFO_FUNC("STP dbg mode is on\n"); ++ /* if (0 == g_block_tx) */ ++ if (0 == mtk_wcn_stp_coredump_start_get()) { ++ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); ++ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); ++ stp_dbg_dmp_printk(g_mtkstp_dbg); ++ } else { ++ STP_INFO_FUNC("assert start flag is set, disable packet dump function\n"); ++ } ++ } ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_ready ++* DESCRIPTION ++* ready/un-ready STP ++* PARAMETERS ++* value [IN] 0=un-ready, others=ready ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++INT32 mtk_wcn_stp_ready(INT32 value) ++{ ++ STP_DBG_FUNC("set ready (%d)\n", value); ++ ++ STP_SET_READY(stp_core_ctx, value); ++ /*if whole chip reset, reset the debuggine mode */ ++#ifndef CONFIG_LOG_STP_INTERNAL ++ /* mtk_wcn_stp_dbg_disable(); */ ++#endif ++ ++ if (stp_is_apply_powersaving()) { ++ STP_INFO_FUNC("Restart the stp-psm monitor !!\n"); ++ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); ++ } ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_ctrl ++* DESCRIPTION ++* set f/w assert flag in STP context ++* PARAMETERS ++* value [IN] 0=assert end, others=assert begins ++* RETURNS ++* INT32 0=success, others=error ++*****************************************************************************/ ++INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value) ++{ ++ STP_DBG_FUNC("set f/w assert (%d)\n", value); ++ ++ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, value); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_coredump_start_get ++* DESCRIPTION ++* get f/w assert flag in STP context ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0= f/w assert flag is not set, others=f/w assert flag is set ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_coredump_start_get(VOID) ++#else ++INT32 mtk_wcn_stp_coredump_start_get(VOID) ++#endif ++{ ++ return STP_FW_COREDUMP_FLAG(stp_core_ctx); ++} ++ ++/* mtk_wcn_stp_set_wmt_last_close -- set the state of link(UART or SDIO) ++ * @ value - 1, link already be closed; 0, link is open ++ * ++ * Return 0 if success; else error code ++ */ ++INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value) ++{ ++ STP_INFO_FUNC("set wmt_last_close flag (%d)\n", value); ++ ++ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, value); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data ++* DESCRIPTION ++* subfunction send data through STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 > 0: length transmitted; = 0: error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#else ++INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#endif ++{ ++ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; ++ UINT8 *p_tx_buf = NULL; ++ UINT16 crc; ++ INT32 ret = 0; ++ MTK_WCN_BOOL is_quick_enable = MTK_WCN_BOOL_TRUE; ++ ++ /* osal_buffer_dump(buffer,"tx", length, 32); */ ++ ++ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { ++ STP_ERR_FUNC("WMT lats close,should not have tx request!\n"); ++ return length; ++ } ++ /* if(g_block_tx) */ ++ if (0 != mtk_wcn_stp_coredump_start_get()) { ++ STP_ERR_FUNC("STP fw coredump start flag set...\n"); ++ return length; ++ } ++#ifdef CONFIG_POWER_SAVING_SUPPORT ++ is_quick_enable = stp_psm_is_quick_ps_support(); ++ STP_DBG_FUNC("is quick sleep enable:%s\n", is_quick_enable ? "yes" : "no"); ++ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { ++ if (type != WMT_TASK_INDX) { ++#if PSM_USE_COUNT_PACKAGE ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0); ++#else ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0, length); ++#endif ++ } ++ /* if(stp_is_apply_powersaving()) */ ++ { ++ if (type == WMT_TASK_INDX) ++ goto DONT_MONITOR; ++ /*-----------------------------STP_PSM_Lock----------------------------------------*/ ++ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); ++ if (ret) { ++ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); ++ return ret; ++ } ++ ++ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { ++ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { ++ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); ++ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); ++ } ++ } else { ++ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); ++ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); ++ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ return ret; ++ } ++ } ++ } else { ++ /* if(stp_is_apply_powersaving()) */ ++ { ++ if (type == WMT_TASK_INDX) ++ goto DONT_MONITOR; ++ /* If now chip is awake, to restart monitor! */ ++ /* STP_INFO_FUNC("check if block traffic !!\n"); */ ++ /*-----------------------------STP_PSM_Lock----------------------------------------*/ ++ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); ++ if (ret) { ++ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); ++ return ret; ++ } ++ ++ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { ++ /* STP_INFO_FUNC("not to block !!\n"); */ ++ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { ++ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); ++ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); ++ } ++ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); ++ } else { ++ /* STP_INFO_FUNC("to block !!\n"); */ ++ ++ /* STP_INFO_FUNC("*****hold data in psm queue data length = %d\n", ++ * length); ++ */ ++ /* stp_dump_data(buffer, "Hold in psm queue", length); */ ++ /* hold datas */ ++ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); ++ /* wmt notification */ ++ STP_INFO_FUNC("#####Type = %d, to inform WMT to wakeup chip, ret = %d:0x%2x,0x%2x\n", ++ type, ret, *buffer, *(buffer + 1)); ++ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); ++ /* STP_INFO_FUNC("*********Type = %d, to inform WMT to wakeup chip>end\n", type); */ ++ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ return ret; ++ } ++ } ++ } ++DONT_MONITOR: ++#endif ++ if (type == BT_TASK_INDX) { ++ static const UINT8 rst_buf[4] = { 0x01, 0x03, 0x0c, 0x00 }; ++ ++ if (!osal_strncmp(buffer, rst_buf, 4)) ++ osal_printtimeofday("############ BT Rest start -->"); ++ } ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ /*Only WMT can set raw data */ ++ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { ++ /* no-op */ ++ /* NULL; */ ++ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { ++ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ ++ /* NULL; */ ++ } ++ /* STP over SDIO */ ++ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { ++ ++ /* osal_printtimeofday("[ STP][SDIO][ B][W]"); */ ++ ++ mtkstp_header[0] = 0x80; ++ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); ++ mtkstp_header[2] = (length) & 0xff; ++ mtkstp_header[3] = 0x00; ++ ++ /* HEADER */ ++ p_tx_buf = &stp_core_ctx.tx_buf[0]; ++ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); ++ p_tx_buf += MTKSTP_HEADER_SIZE; ++ ++ /* PAYLOAD */ ++ osal_memcpy(p_tx_buf, buffer, length); ++ p_tx_buf += length; ++ ++ /* CRC */ ++ temp[0] = 0x00; ++ temp[1] = 0x00; ++ osal_memcpy(p_tx_buf, temp, 2); ++ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length); ++ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); ++ ++ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { ++ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); ++ osal_assert(0); ++ ret = 0; ++ } else { ++ ret = (INT32) length; ++ } ++ ++ /* osal_printtimeofday("[ STP][SDIO][ E][W]"); */ ++ } ++ /* STP over UART */ ++ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) { ++ ++ /* osal_printtimeofday("[ STP][UART][ B][W]"); */ ++ /* STP_INFO_FUNC("Write byte %d\n", length); */ ++ ++ if ((stp_core_ctx.sequence.winspace > 0) && ++ (stp_core_ctx.inband_rst_set == 0) && ++ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { ++ /*Make Header */ ++ /* (*sys_dbg_print)("mtk_wcn_stp_send_data 1, txseq = %d, winspace = %d", ++ * stp_core_ctx.sequence.txseq, stp_core_ctx.sequence.winspace); ++ */ ++ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; ++ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); ++ mtkstp_header[2] = length & 0xff; ++ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; ++ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; ++ if (fgEnableDelimiter == 1) { ++ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; ++ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); ++ } ++ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); ++ ++ /*Make Payload */ ++ stp_add_to_tx_queue(buffer, length); ++ ++ /*Make CRC */ ++ crc = osal_crc16(buffer, length); ++ temp[0] = crc & 0xff; ++ temp[1] = (crc & 0xff00) >> 8; ++ stp_add_to_tx_queue(temp, 2); ++ stp_dbg_pkt_log(type, ++ stp_core_ctx.sequence.txack, ++ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); ++ ++ /*Kick to UART */ ++ stp_send_tx_queue(stp_core_ctx.sequence.txseq); ++ ++ INDEX_INC(stp_core_ctx.sequence.txseq); ++ stp_core_ctx.sequence.winspace--; ++ ++ /*Setup the Retry Timer */ ++ osal_timer_stop(&stp_core_ctx.tx_timer); ++ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) ++ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); ++ else ++ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); ++ ++ ret = (INT32) length; ++ } else { ++ /* ++ No winspace to send. Let caller retry ++ */ ++ if (stp_core_ctx.inband_rst_set == 1) ++ STP_WARN_FUNC("Now it's inband reset process and drop sent packet.\n"); ++ else ++ STP_ERR_FUNC("There is no winspace/txqueue to send !!!\n"); ++ ++ ret = 0; ++ } ++ ++ /* osal_printtimeofday("[ STP][UART][ E][W]"); */ ++ } ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ ++#ifdef CONFIG_POWER_SAVING_SUPPORT ++ ++ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { ++ if (type != WMT_TASK_INDX) { ++ stp_psm_notify_wmt_sleep(STP_PSM_CORE(stp_core_ctx)); ++ /*-----------------------STP_PSM_UnLock-------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ } ++ } else { ++ /* if(stp_is_apply_powersaving()) */ ++ /* { */ ++ if (type != WMT_TASK_INDX) { ++ ++ /*--------------------STP_PSM_UnLock--------------------------*/ ++ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); ++ } ++ /* } */ ++ } ++#endif ++ ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_send_data); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data_raw ++* DESCRIPTION ++* send raw data to common interface, bypass STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#else ++INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) ++#endif ++{ ++ UINT32 written = 0; ++ INT32 ret = 0; ++ ++ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { ++ STP_ERR_FUNC("WMT lats close,should not have tx request!"); ++ return length; ++ } ++ ++ STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d, data = %x %x %x %x %x %x ", type, buffer[0], buffer[1], ++ buffer[2], buffer[3], buffer[4], buffer[5]); ++ STP_SET_PENDING_TYPE(stp_core_ctx, type); /* remember tx type, forward following rx to this type */ ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, 1); ++ (*sys_if_tx) (&buffer[0], length, &written); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ ++ if (written == 0) ++ stp_dump_data(&buffer[0], "tx raw failed:", length); ++ ++ if (written == length) ++ ret = (INT32) written; ++ else ++ ret = (-1); ++ ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_receive_data ++* DESCRIPTION ++* receive data from serial protocol engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: size of data received; < 0: error ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) ++#else ++INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) ++#endif ++{ ++ /* GeorgeKuo modify: reduce "if" branch */ ++ UINT16 copyLen = 0; ++ UINT16 tailLen = 0; ++ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ while (stp_core_ctx.ring[type].read_p != stp_core_ctx.ring[type].write_p) { ++ /* GeorgeKuo modify: reduce if branch */ ++ if (stp_core_ctx.ring[type].write_p > stp_core_ctx.ring[type].read_p) { ++ copyLen = stp_core_ctx.ring[type].write_p - stp_core_ctx.ring[type].read_p; ++ if (copyLen > length) ++ copyLen = length; ++ ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, copyLen); ++ stp_core_ctx.ring[type].read_p += copyLen; ++ } else { ++ tailLen = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].read_p; ++ if (tailLen > length) { /* exclude equal case to skip wrap check */ ++ copyLen = length; ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, ++ copyLen); ++ stp_core_ctx.ring[type].read_p += copyLen; ++ } else { ++ /* part 1: copy tailLen */ ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, ++ tailLen); ++ ++ buffer += tailLen; /* update buffer offset */ ++ ++ /* part 2: check if head length is enough */ ++ copyLen = length - tailLen; ++ copyLen = ++ (stp_core_ctx.ring[type].write_p < ++ copyLen) ? stp_core_ctx.ring[type].write_p : copyLen; ++ ++ if (copyLen) ++ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + 0, copyLen); ++ ++ /* Update read_p final position */ ++ stp_core_ctx.ring[type].read_p = copyLen; ++ ++ /* update return length: head + tail */ ++ copyLen += tailLen; ++ } ++ } ++ break; ++ } ++ ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ if ((MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) && (type != WMT_TASK_INDX)) { ++#if PSM_USE_COUNT_PACKAGE ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1); ++#else ++ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1, copyLen); ++#endif ++ } ++ ++ return copyLen; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_receive_data); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_rxqueue_empty ++* DESCRIPTION ++* Is certain rx queue empty? ++* PARAMETERS ++* type [IN] subfunction type ++* RETURNS ++* INT32 0: queue is NOT empyt; !0: queue is empty ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_is_rxqueue_empty(UINT8 type) ++#else ++INT32 mtk_wcn_stp_is_rxqueue_empty(UINT8 type) ++#endif ++{ ++ INT32 ret; ++ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ if (stp_core_ctx.ring[type].read_p == stp_core_ctx.ring[type].write_p) ++ ret = 1; /* queue is empty */ ++ else ++ ret = 0; /* queue is not empty */ ++ ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ ++ return ret; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); ++#endif ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_set_sdio_mode ++* DESCRIPTION ++* Set stp for SDIO mode ++* PARAMETERS ++* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) ++* RETURNS ++* void ++*****************************************************************************/ ++ ++void mtk_wcn_stp_set_mode(UINT32 mode) ++{ ++ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, mode); ++ ++ STP_DBG_FUNC("STP_SUPPORT_PROTOCOL = %08x\n", STP_SUPPORT_PROTOCOL(stp_core_ctx)); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_fullset_mode ++* DESCRIPTION ++* Is stp use UART fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:Uart Fullset mode, FALSE:Not UART Fullset mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void) ++{ ++ /* ++ bit 0: uart fullset mode ++ bit 1: uart mandatory mode ++ bit 2: sdio mode ++ */ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_FULL_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_uart_mand_mode ++* DESCRIPTION ++* Is stp use UART mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:Uart Mandatory mode, FALSE:Not UART Mandotary mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void) ++{ ++ /* ++ bit 0: uart fullset mode ++ bit 1: uart mandatory mode ++ bit 2: sdio mode ++ */ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_MAND_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_fullset_mode ++* DESCRIPTION ++* Is stp use BTIF fullset mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Fullset mode, FALSE:Not BTIF Fullset mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void) ++{ ++ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_FULL_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_btif_mand_mode ++* DESCRIPTION ++* Is stp use BTIF mandatory mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:BTIF Mandatory mode, FALSE:Not BTIF Mandotary mode ++*****************************************************************************/ ++ ++MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void) ++{ ++ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_MAND_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_sdio_mode ++* DESCRIPTION ++* Is stp use SDIO mode? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode ++*****************************************************************************/ ++MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void) ++{ ++ /* ++ bit 0: uart fullset mode ++ bit 1: uart mandatory mode ++ bit 2: sdio mode ++ */ ++ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_SDIO_MODE) ++ return MTK_WCN_BOOL_TRUE; ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* stp_send_inband_reset ++* DESCRIPTION ++* To sync to oringnal stp state with f/w stp ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++void mtk_wcn_stp_inband_reset(void) ++{ ++ UINT8 inband_reset_packet[64]; ++ UINT32 txseq = 0; ++ UINT32 txack = 0; ++ UINT32 crc = 0; ++ UINT32 ret = 0; ++ UINT32 reset_payload_len = 0; ++ ++ /*512 bytes */ ++ UINT8 reset_payload[] = { ++ 0xc0, 0x01, 0xc0, 0xde, 0x3e, 0xd1, 0xa7, 0xef ++ }; ++ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ /*RESYNC*/ inband_reset_packet[0] = 0x7f; ++ inband_reset_packet[1] = 0x7f; ++ inband_reset_packet[2] = 0x7f; ++ inband_reset_packet[3] = 0x7f; ++ inband_reset_packet[4] = 0x7f; ++ inband_reset_packet[5] = 0x7f; ++ inband_reset_packet[6] = 0x7f; ++ inband_reset_packet[7] = 0x7f; ++ ++ /*header */ ++ reset_payload_len = sizeof(reset_payload) / sizeof(reset_payload[0]); ++ inband_reset_packet[8] = 0x80 + (txseq << 3) + txack; ++ inband_reset_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); ++ inband_reset_packet[10] = reset_payload_len & 0xff; ++ inband_reset_packet[11] = (inband_reset_packet[8] + inband_reset_packet[9] + inband_reset_packet[10]) & 0xff; ++ ++ /*payload */ ++ osal_memcpy(&inband_reset_packet[12], reset_payload, reset_payload_len); ++ ++ /*crc */ ++ crc = osal_crc16(&reset_payload[0], reset_payload_len); ++ inband_reset_packet[12 + reset_payload_len] = crc & 0xff; ++ inband_reset_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; ++ ++ (*sys_if_tx) (&inband_reset_packet[0], 14 + reset_payload_len, &ret); ++ ++ if (ret != (14 + reset_payload_len)) ++ STP_ERR_FUNC("Inband sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ret); ++ ++ stp_core_ctx.inband_rst_set = 1; ++ stp_ctx_unlock(&stp_core_ctx); ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++} ++ ++void mtk_wcn_stp_debug_ctrl(INT32 op, INT32 filter, INT32 filter_param) ++{ ++ /*nothing at now*/ ++} ++ ++void mtk_wcn_stp_test_cmd(INT32 cmd_no) ++{ ++ UINT8 test_packet[64]; ++ UINT32 txseq = 0; ++ UINT32 txack = 0; ++ UINT32 crc = 0; ++ UINT32 ret = 0; ++ UINT32 reset_payload_len = 0; ++ ++ UINT8 test_payload[] = { ++ 0xAA, 0xAA, 0xC0, 0xDE, 0x3E, 0xD1, 0xA7, 0xEF ++ }; ++/* */ ++/* select your test command by cmd_no */ ++/* */ ++ if (cmd_no == 0) { ++ /* to test new command to chip */ ++ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_lock(&stp_core_ctx); ++ ++ /*RESYNC*/ test_packet[0] = 0x7f; ++ test_packet[1] = 0x7f; ++ test_packet[2] = 0x7f; ++ test_packet[3] = 0x7f; ++ test_packet[4] = 0x7f; ++ test_packet[5] = 0x7f; ++ test_packet[6] = 0x7f; ++ test_packet[7] = 0x7f; ++ ++ /*header */ ++ reset_payload_len = sizeof(test_payload) / sizeof(test_payload[0]); ++ test_packet[8] = 0x80 + (txseq << 3) + txack; ++ test_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); ++ test_packet[10] = reset_payload_len & 0xff; ++ test_packet[11] = (test_packet[8] + test_packet[9] + test_packet[10]) & 0xff; ++ ++ /*payload */ ++ osal_memcpy(&test_packet[12], test_payload, reset_payload_len); ++ ++ /*crc */ ++ crc = osal_crc16(&test_payload[0], reset_payload_len); ++ test_packet[12 + reset_payload_len] = crc & 0xff; ++ test_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; ++ ++ (*sys_if_tx) (&test_packet[0], 14 + reset_payload_len, &ret); ++ if (ret != (14 + reset_payload_len)) { ++ STP_ERR_FUNC("stp test sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ++ ret); ++ } ++ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ ++ stp_ctx_unlock(&stp_core_ctx); ++ } ++ ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_flush_context ++* DESCRIPTION ++* Flush STP Context ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++void mtk_wcn_stp_flush_context(void) ++{ ++ stp_rest_ctx_state(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_flush_rx_queue ++* DESCRIPTION ++* Flush STP Rx Queue ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++ ++void mtk_wcn_stp_flush_rx_queue(UINT32 type) ++{ ++ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++ if (type < MTKSTP_MAX_TASK_NUM) { ++ stp_core_ctx.ring[type].read_p = 0; ++ stp_core_ctx.ring[type].write_p = 0; ++ } ++ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_enable ++* DESCRIPTION ++* STP is ready? ++* PARAMETERS ++* none. ++* RETURNS ++* none ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void) ++#else ++MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) ++#endif ++{ ++ return STP_IS_READY(stp_core_ctx); ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_is_ready); ++#endif ++/***************************************************************************** ++* FUNCTION ++* set_bluetooth_rx_interface ++* DESCRIPTION ++* Set bluetooth rx interface ++* PARAMETERS ++* rx interface type ++* RETURNS ++* void ++*****************************************************************************/ ++#if STP_EXP_HID_API_EXPORT ++void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) ++#else ++void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) ++#endif ++{ ++ /* g_mtkstp_bluez_flag = bluez_flag; */ ++ STP_SET_BT_STK(stp_core_ctx, bluez_flag); ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); ++#endif ++/***************************************************************************** ++* FUNCTION ++* set stp debugging mdoe ++* DESCRIPTION ++* set stp debugging mdoe ++* PARAMETERS ++* dbg_mode: switch to dbg mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode) ++{ ++ STP_SET_ENABLE_DBG(stp_core_ctx, dbg_mode); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* set stp auto reset mdoe ++* DESCRIPTION ++* set stp auto reset mdoe ++* PARAMETERS ++* auto_rst: switch to auto reset mode ? ++* RETURNS ++* void ++*****************************************************************************/ ++void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst) ++{ ++ STP_SET_ENABLE_RST(stp_core_ctx, auto_rst); ++} ++ ++INT32 mtk_wcn_stp_notify_sleep_for_thermal(void) ++{ ++ return stp_psm_sleep_for_thermal(STP_PSM_CORE(stp_core_ctx)); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_open_btif ++* DESCRIPTION ++* init btif hw & sw by owner stp ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_open_btif(VOID) ++{ ++ return mtk_wcn_consys_stp_btif_open(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_open_close ++* DESCRIPTION ++* close btif hw & sw by owner stp ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_close_btif(VOID) ++{ ++ return mtk_wcn_consys_stp_btif_close(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_rx_cb_register ++* DESCRIPTION ++* register stp rx cb to btif ++* PARAMETERS ++* MTK_WCN_BTIF_RX_CB stp rx handle function ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ return mtk_wcn_consys_stp_btif_rx_cb_register(rx_cb); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_tx ++* DESCRIPTION ++* send stp package by btif ++* PARAMETERS ++* pBuf:package buffer pointer,len:package length ++* written_len:package written length ++* RETURNS ++* INT32 package length-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len) ++{ ++ INT32 iRet = -1; ++ ++ iRet = mtk_wcn_consys_stp_btif_tx(pBuf, len, written_len); ++ return iRet; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_wakeup_consys ++* DESCRIPTION ++* STP wakeup consys by btif ++* PARAMETERS ++* VOID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_wakeup_consys(VOID) ++{ ++ /*log wakeup int for debug */ ++ stp_dbg_pkt_log(7, 0, 0, 0, PKT_DIR_TX, NULL, 0); ++ return mtk_wcn_consys_stp_btif_wakeup(); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_dpidle_ctrl ++* DESCRIPTION ++* decide AP enter or exit deep idle ++* PARAMETERS ++* en_flag:1,enter,0,exit ++* RETURNS ++* always 0 ++*****************************************************************************/ ++INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ mtk_wcn_consys_stp_btif_dpidle_ctrl(en_flag); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_lpbk_ctrl ++* DESCRIPTION ++* enable stp internal lpbk test or not ++* PARAMETERS ++* mode:1,enable,0,disabel ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) ++{ ++ return mtk_wcn_consys_stp_btif_lpbk_ctrl(mode); ++} ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_logger_ctrl ++* DESCRIPTION ++* dump btif buffer or register status when No ACK or assert occurs ++* PARAMETERS ++* flag:see enum value in ENUM_BTIF_DBG_ID ++* RETURNS ++* INT32 0-success,other fail. ++*****************************************************************************/ ++INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag) ++{ ++ return mtk_wcn_consys_stp_btif_logger_ctrl(flag); ++} ++ ++VOID mtk_wcn_stp_ctx_save(void) ++{ ++ STP_INFO_FUNC("start ++\n"); ++ mtk_wcn_stp_coredump_start_ctrl(1); ++ stp_psm_set_sleep_disable(stp_core_ctx.psm); ++ STP_INFO_FUNC("exit --\n"); ++} ++ ++VOID mtk_wcn_stp_ctx_restore(void) ++{ ++ STP_INFO_FUNC("start ++\n"); ++ stp_psm_set_sleep_enable(stp_core_ctx.psm); ++ stp_btm_reset_btm_wq(STP_BTM_CORE(stp_core_ctx)); ++ ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ else ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++#if STP_RETRY_OPTIMIZE ++ g_retry_times = 0; ++#endif ++ STP_INFO_FUNC("exit --\n"); ++} ++ ++INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(void) ++{ ++ INT32 ret = -1; ++ ++ if (mtk_wcn_stp_coredump_start_get() != 0) { ++ STP_INFO_FUNC("firmware assert has been triggered\n"); ++ return 0; ++ } ++ ++ ret = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); ++ if (ret) { ++ STP_ERR_FUNC("evt err trigger assert fail,do chip reset to recovery\n"); ++ ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ if (STP_IS_ENABLE_RST(stp_core_ctx)) ++ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); ++ else ++ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); ++ } ++ ++ return ret; ++} ++ ++VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value) ++{ ++ STP_INFO_FUNC("set evt err tigger assert flag to %d\n", value); ++ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, value); ++} ++ ++UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(void) ++{ ++ return STP_EVT_ERR_ASSERT(stp_core_ctx); ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c +new file mode 100644 +index 000000000000..3009bd26df41 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c +@@ -0,0 +1,529 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CONF]" ++ ++#include "osal_typedef.h" ++/* #include "osal.h" */ ++#include "wmt_lib.h" ++#include "wmt_dev.h" ++#include "wmt_conf.h" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++struct parse_data { ++ PINT8 name; ++ INT32 (*parser)(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 value); ++ PINT8 (*writer)(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ /*PINT8 param1, *param2, *param3; */ ++ /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */ ++ PINT8 param1; ++ PINT8 param2; ++ PINT8 param3; ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); ++ ++static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ ++static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); ++ ++static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ ++static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); ++ ++static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data); ++ ++static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal); ++ ++static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size); ++ ++#define OFFSET(v) ((void *) &((P_DEV_WMT) 0)->v) ++ ++#define CHAR(f) \ ++{ \ ++ #f, \ ++ wmt_conf_parse_char, \ ++ wmt_conf_write_char, \ ++ OFFSET(rWmtGenConf.f), \ ++ NULL, \ ++ NULL \ ++} ++/* #define CHAR(f) _CHAR(f), NULL, NULL} */ ++ ++#define SHORT(f) \ ++{ \ ++ #f, \ ++ wmt_conf_parse_short, \ ++ wmt_conf_write_short, \ ++ OFFSET(rWmtGenConf.f), \ ++ NULL, \ ++ NULL \ ++} ++/* #define SHORT(f) _SHORT(f), NULL, NULL */ ++ ++#define INT(f) \ ++{ \ ++ #f, \ ++ wmt_conf_parse_int, \ ++ wmt_conf_write_int, \ ++ OFFSET(rWmtGenConf.f), \ ++ NULL, \ ++ NULL \ ++} ++/* #define INT(f) _INT(f), NULL, NULL */ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static const struct parse_data wmtcfg_fields[] = { ++ CHAR(coex_wmt_ant_mode), ++ CHAR(coex_wmt_ext_component), ++ CHAR(coex_wmt_wifi_time_ctl), ++ CHAR(coex_wmt_ext_pta_dev_on), ++ CHAR(coex_wmt_filter_mode), ++ ++ CHAR(coex_bt_rssi_upper_limit), ++ CHAR(coex_bt_rssi_mid_limit), ++ CHAR(coex_bt_rssi_lower_limit), ++ CHAR(coex_bt_pwr_high), ++ CHAR(coex_bt_pwr_mid), ++ CHAR(coex_bt_pwr_low), ++ ++ CHAR(coex_wifi_rssi_upper_limit), ++ CHAR(coex_wifi_rssi_mid_limit), ++ CHAR(coex_wifi_rssi_lower_limit), ++ CHAR(coex_wifi_pwr_high), ++ CHAR(coex_wifi_pwr_mid), ++ CHAR(coex_wifi_pwr_low), ++ ++ CHAR(coex_ext_pta_hi_tx_tag), ++ CHAR(coex_ext_pta_hi_rx_tag), ++ CHAR(coex_ext_pta_lo_tx_tag), ++ CHAR(coex_ext_pta_lo_rx_tag), ++ SHORT(coex_ext_pta_sample_t1), ++ SHORT(coex_ext_pta_sample_t2), ++ CHAR(coex_ext_pta_wifi_bt_con_trx), ++ ++ INT(coex_misc_ext_pta_on), ++ INT(coex_misc_ext_feature_set), ++ ++ CHAR(wmt_gps_lna_pin), ++ CHAR(wmt_gps_lna_enable), ++ ++ CHAR(pwr_on_rtc_slot), ++ CHAR(pwr_on_ldo_slot), ++ CHAR(pwr_on_rst_slot), ++ CHAR(pwr_on_off_slot), ++ CHAR(pwr_on_on_slot), ++ CHAR(co_clock_flag), ++ ++ INT(sdio_driving_cfg), ++ ++}; ++ ++#define NUM_WMTCFG_FIELDS (osal_sizeof(wmtcfg_fields) / osal_sizeof(wmtcfg_fields[0])) ++ ++static int wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) ++{ ++ PINT8 dst; ++ long res; ++ int ret; ++ ++ dst = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { ++ ret = osal_strtol(pos + 2, 16, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); ++ } else { ++ ret = osal_strtol(pos, 10, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); ++ } ++ return 0; ++} ++ ++static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data) ++{ ++ PINT8 src; ++ INT32 res; ++ PINT8 value; ++ ++ src = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ value = osal_malloc(20); ++ if (value == NULL) ++ return NULL; ++ res = osal_snprintf(value, 20, "0x%x", *src); ++ if (res < 0 || res >= 20) { ++ osal_free(value); ++ return NULL; ++ } ++ value[20 - 1] = '\0'; ++ return value; ++} ++ ++static int wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) ++{ ++ PUINT16 dst; ++ long res; ++ int ret; ++ ++ dst = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ ++ ++ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { ++ ret = osal_strtol(pos + 2, 16, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); ++ } else { ++ ret = osal_strtol(pos, 10, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); ++ } ++ ++ return 0; ++} ++ ++static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data) ++{ ++ PINT16 src; ++ INT32 res; ++ PINT8 value; ++ ++ /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */ ++ src = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ value = osal_malloc(20); ++ if (value == NULL) ++ return NULL; ++ res = osal_snprintf(value, 20, "0x%x", *src); ++ if (res < 0 || res >= 20) { ++ osal_free(value); ++ return NULL; ++ } ++ value[20 - 1] = '\0'; ++ return value; ++} ++ ++static int wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) ++{ ++ PUINT32 dst; ++ long res; ++ int ret; ++ ++ dst = (PINT32) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ ++ ++ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { ++ ret = osal_strtol(pos + 2, 16, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); ++ } else { ++ ret = osal_strtol(pos, 10, &res); ++ if (ret) ++ WMT_ERR_FUNC("fail(%d)\n", ret); ++ *dst = res; ++ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); ++ } ++ ++ return 0; ++} ++ ++static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data) ++{ ++ PINT32 src; ++ INT32 res; ++ PINT8 value; ++ ++ src = (PUINT32) (((PUINT8) pWmtDev) + (long)data->param1); ++ ++ value = osal_malloc(20); ++ if (value == NULL) ++ return NULL; ++ res = osal_snprintf(value, 20, "0x%x", *src); ++ if (res < 0 || res >= 20) { ++ osal_free(value); ++ return NULL; ++ } ++ value[20 - 1] = '\0'; ++ return value; ++} ++ ++static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal) ++{ ++ int i = 0; ++ int ret = 0; ++ ++ /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */ ++ ++ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { ++ const struct parse_data *field = &wmtcfg_fields[i]; ++ ++ if (osal_strcmp(pKey, field->name) != 0) ++ continue; ++ if (field->parser(pWmtDev, field, pVal)) { ++ WMT_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal); ++ ret = -1; ++ } ++ break; ++ } ++ if (i == NUM_WMTCFG_FIELDS) { ++ WMT_ERR_FUNC("unknown field '%s'.\n", pKey); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size) ++{ ++ PINT8 pch; ++ PINT8 pBuf; ++ PINT8 pLine; ++ PINT8 pKey; ++ PINT8 pVal; ++ PINT8 pPos; ++ INT32 ret = 0; ++ INT32 i = 0; ++ PINT8 pa = NULL; ++ ++ pBuf = osal_malloc(size); ++ if (!pBuf) ++ return -1; ++ ++ osal_memcpy(pBuf, pInBuf, size); ++ pBuf[size] = '\0'; ++ ++ pch = pBuf; ++ /* pch is to be updated by strsep(). Keep pBuf unchanged!! */ ++ ++#if 0 ++ { ++ PINT8 buf_ptr = pBuf; ++ INT32 k = 0; ++ ++ WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size); ++ for (k = 0; k < size; k++) { ++ /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */ ++ WMT_INFO_FUNC("%c", buf_ptr[k]); ++ } ++ WMT_INFO_FUNC("--end\n"); ++ } ++#endif ++ ++ while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) { ++ /* pch is updated to the end of pLine by strsep() and updated to '\0' */ ++ /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */ ++ /* parse each line */ ++ ++ /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */ ++ ++ if (!*pLine) ++ continue; ++ ++ pVal = osal_strchr(pLine, '='); ++ if (!pVal) { ++ WMT_WARN_FUNC("mal-format cfg string(%s)\n", pLine); ++ continue; ++ } ++ ++ /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */ ++ *pVal = '\0'; /* replace '=' with '\0' to get key */ ++ /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */ ++ pKey = pLine; ++ ++ if ((pVal - pBuf) < size) ++ pVal++; ++ ++ /*key handling */ ++ pPos = pKey; ++ /*skip space characeter */ ++ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*key head */ ++ pKey = pPos; ++ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*key tail */ ++ (*pPos) = '\0'; ++ ++ /*value handling */ ++ pPos = pVal; ++ /*skip space characeter */ ++ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*value head */ ++ pVal = pPos; ++ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { ++ if ((pPos - pBuf) >= size) ++ break; ++ pPos++; ++ } ++ /*value tail */ ++ (*pPos) = '\0'; ++ ++ /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */ ++ ret = wmt_conf_parse_pair(pWmtDev, pKey, pVal); ++ WMT_DBG_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret); ++ if (ret) ++ WMT_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret); ++ } ++ ++ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { ++ const struct parse_data *field = &wmtcfg_fields[i]; ++ ++ pa = field->writer(pWmtDev, field); ++ if (pa) { ++ WMT_DBG_FUNC("#%d(%s)=>%s\n", i, field->name, pa); ++ osal_free(pa); ++ } else { ++ WMT_ERR_FUNC("failed to parse '%s'.\n", field->name); ++ } ++ } ++ osal_free(pBuf); ++ return 0; ++} ++ ++INT32 wmt_conf_set_cfg_file(const char *name) ++{ ++ if (NULL == name) { ++ WMT_ERR_FUNC("name is NULL\n"); ++ return -1; ++ } ++ if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) { ++ WMT_ERR_FUNC("name is too long, length=%d, expect to < %d\n", osal_strlen(name), ++ osal_sizeof(gDevWmt.cWmtcfgName)); ++ return -2; ++ } ++ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); ++ osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name); ++ WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0])); ++ ++ return 0; ++} ++ ++INT32 wmt_conf_read_file(VOID) ++{ ++ INT32 ret = -1; ++ ++ osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf)); ++ osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg)); ++ ++#if 1 ++ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); ++ ++ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_PREFIX, osal_sizeof(CUST_CFG_WMT_PREFIX)); ++ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT, osal_sizeof(CUST_CFG_WMT)); ++#endif ++ ++ if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) { ++ WMT_ERR_FUNC("empty Wmtcfg name\n"); ++ osal_assert(0); ++ return ret; ++ } ++ WMT_DBG_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0])); ++ if (0 == wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg, 0)) { ++ /*get full name patch success */ ++ WMT_DBG_FUNC("get full file name(%s) buf(0x%p) size(%d)\n", ++ &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size); ++ ++ if (0 == wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size)) { ++ /*config file exists */ ++ gDevWmt.rWmtGenConf.cfgExist = 1; ++ ++ WMT_DBG_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf); ++ ret = 0; ++ } else { ++ WMT_ERR_FUNC("wmt conf parsing fail\n"); ++ osal_assert(0); ++ ret = -1; ++ } ++ wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg); ++/* ++ if (gDevWmt.pWmtCfg) ++ { ++ if (gDevWmt.pWmtCfg->data) ++ { ++ osal_free(gDevWmt.pWmtCfg->data); ++ } ++ osal_free(gDevWmt.pWmtCfg); ++ gDevWmt.pWmtCfg = 0; ++ } ++*/ ++ return ret; ++ } ++ WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0])); ++ osal_assert(0); ++ ++ gDevWmt.rWmtGenConf.cfgExist = 0; ++ return ret; ++} ++ ++P_WMT_GEN_CONF wmt_conf_get_cfg(VOID) ++{ ++ if (0 == gDevWmt.rWmtGenConf.cfgExist) ++ return NULL; ++ ++ return &gDevWmt.rWmtGenConf; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c +new file mode 100644 +index 000000000000..cca6729d53a0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c +@@ -0,0 +1,2521 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CORE]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include "wmt_lib.h" ++#include "wmt_core.h" ++#include "wmt_ctrl.h" ++#include "wmt_ic.h" ++#include "wmt_conf.h" ++ ++#include "wmt_func.h" ++#include "stp_core.h" ++#include "psm_core.h" ++ ++ ++P_WMT_FUNC_OPS gpWmtFuncOps[4] = { ++#if CFG_FUNC_BT_SUPPORT ++ [0] = &wmt_func_bt_ops, ++#else ++ [0] = NULL, ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++ [1] = &wmt_func_fm_ops, ++#else ++ [1] = NULL, ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++ [2] = &wmt_func_gps_ops, ++#else ++ [2] = NULL, ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++ [3] = &wmt_func_wifi_ops, ++#else ++ [3] = NULL, ++#endif ++ ++}; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting? ++*move to wmt_ic_6620 temporarily. ++*/ ++/* BT Port 2 Feature. */ ++/* #define CFG_WMT_BT_PORT2 (1) */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++static WMT_CTX gMtkWmtCtx; ++static UINT8 gLpbkBuf[1024+5] = { 0 }; ++#ifdef CONFIG_MTK_COMBO_ANT ++static UINT8 gAntBuf[1024] = { 0 }; ++#define CFG_CHECK_WMT_RESULT (1) ++#endif ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp); ++static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp); ++static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp); ++static INT32 opfunc_func_on(P_WMT_OP pWmtOp); ++static INT32 opfunc_func_off(P_WMT_OP pWmtOp); ++static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp); ++static INT32 opfunc_exit(P_WMT_OP pWmtOp); ++static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp); ++static INT32 opfunc_dsns(P_WMT_OP pWmtOp); ++static INT32 opfunc_lpbk(P_WMT_OP pWmtOp); ++static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp); ++static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp); ++static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp); ++static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp); ++static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); ++static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp); ++static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); ++static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp); ++static INT32 opfunc_pin_state(P_WMT_OP pWmtOp); ++static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp); ++static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp); ++static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp); ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp); ++#endif ++#ifdef CONFIG_MTK_COMBO_ANT ++static INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp); ++static INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp); ++#endif ++static VOID wmt_core_dump_func_state(PINT8 pSource); ++static INT32 wmt_core_stp_init(VOID); ++static INT32 wmt_core_stp_deinit(VOID); ++static INT32 wmt_core_hw_check(VOID); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static const UINT8 WMT_SLEEP_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x01 }; ++static const UINT8 WMT_SLEEP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; ++ ++static const UINT8 WMT_HOST_AWAKE_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x02 }; ++static const UINT8 WMT_HOST_AWAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; ++ ++static const UINT8 WMT_WAKEUP_CMD[] = { 0xFF }; ++static const UINT8 WMT_WAKEUP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; ++ ++static UINT8 WMT_THERM_CMD[] = { 0x01, 0x11, 0x01, 0x00, ++ 0x00 /*thermal sensor operation */ ++}; ++static UINT8 WMT_THERM_CTRL_EVT[] = { 0x02, 0x11, 0x01, 0x00, 0x00 }; ++static UINT8 WMT_THERM_READ_EVT[] = { 0x02, 0x11, 0x02, 0x00, 0x00, 0x00 }; ++ ++static UINT8 WMT_EFUSE_CMD[] = { 0x01, 0x0D, 0x08, 0x00, ++ 0x01, /*[4]operation, 0:init, 1:write 2:read */ ++ 0x01, /*[5]Number of register setting */ ++ 0xAA, 0xAA, /*[6-7]Address */ ++ 0xBB, 0xBB, 0xBB, 0xBB /*[8-11] Value */ ++}; ++ ++static UINT8 WMT_EFUSE_EVT[] = { 0x02, 0x0D, 0x08, 0x00, ++ 0xAA, /*[4]operation, 0:init, 1:write 2:read */ ++ 0xBB, /*[5]Number of register setting */ ++ 0xCC, 0xCC, /*[6-7]Address */ ++ 0xDD, 0xDD, 0xDD, 0xDD /*[8-11] Value */ ++}; ++ ++static UINT8 WMT_DSNS_CMD[] = { 0x01, 0x0E, 0x02, 0x00, 0x01, ++ 0x00 /*desnse type */ ++}; ++static UINT8 WMT_DSNS_EVT[] = { 0x02, 0x0E, 0x01, 0x00, 0x00 }; ++ ++/* TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT */ ++static UINT8 WMT_SET_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x00 /*op: w(1) & r(2) */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*res */ ++ , 0x01 /*1 register */ ++ , 0x00, 0x00, 0x00, 0x00 /* addr */ ++ , 0x00, 0x00, 0x00, 0x00 /* value */ ++ , 0xFF, 0xFF, 0xFF, 0xFF /*mask */ ++}; ++ ++static UINT8 WMT_SET_REG_WR_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 register */ ++ /* , 0x00, 0x00, 0x00, 0x00 */ /* addr */ ++ /* , 0x00, 0x00, 0x00, 0x00 */ /* value */ ++}; ++ ++static UINT8 WMT_SET_REG_RD_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 register */ ++ , 0x00, 0x00, 0x00, 0x00 /* addr */ ++ , 0x00, 0x00, 0x00, 0x00 /* value */ ++}; ++ ++#ifdef CONFIG_MTK_COMBO_ANT ++static UINT8 WMT_ANT_RAM_STA_GET_CMD[] = { 0x01, 0x06, 0x02, 0x00, 0x05, 0x02 ++}; ++ ++static UINT8 WMT_ANT_RAM_STA_GET_EVT[] = { 0x02, 0x06, 0x03, 0x00 /*length */ ++ , 0x05, 0x02, 0x00 /*S: result */ ++}; ++ ++static UINT8 WMT_ANT_RAM_DWN_CMD[] = { 0x01, 0x15, 0x00, 0x00, 0x01 ++}; ++ ++static UINT8 WMT_ANT_RAM_DWN_EVT[] = { 0x02, 0x15, 0x01, 0x00 /*length */ ++ , 0x00 ++}; ++#endif ++ ++/* GeorgeKuo: Use designated initializers described in ++ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html ++ */ ++ ++static const WMT_OPID_FUNC wmt_core_opfunc[] = { ++ [WMT_OPID_HIF_CONF] = opfunc_hif_conf, ++ [WMT_OPID_PWR_ON] = opfunc_pwr_on, ++ [WMT_OPID_PWR_OFF] = opfunc_pwr_off, ++ [WMT_OPID_FUNC_ON] = opfunc_func_on, ++ [WMT_OPID_FUNC_OFF] = opfunc_func_off, ++ [WMT_OPID_REG_RW] = opfunc_reg_rw, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ ++ [WMT_OPID_EXIT] = opfunc_exit, ++ [WMT_OPID_PWR_SV] = opfunc_pwr_sv, ++ [WMT_OPID_DSNS] = opfunc_dsns, ++ [WMT_OPID_LPBK] = opfunc_lpbk, ++ [WMT_OPID_CMD_TEST] = opfunc_cmd_test, ++ [WMT_OPID_HW_RST] = opfunc_hw_rst, ++ [WMT_OPID_SW_RST] = opfunc_sw_rst, ++ [WMT_OPID_STP_RST] = opfunc_stp_rst, ++ [WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl, ++ [WMT_OPID_EFUSE_RW] = opfunc_efuse_rw, ++ [WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl, ++ [WMT_OPID_GPIO_STATE] = opfunc_pin_state, ++ [WMT_OPID_BGW_DS] = opfunc_bgw_ds, ++ [WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk, ++ [WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test, ++#if CFG_WMT_LTE_COEX_HANDLING ++ [WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling, ++#endif ++#ifdef CONFIG_MTK_COMBO_ANT ++ [WMT_OPID_ANT_RAM_DOWN] = opfunc_ant_ram_down, ++ [WMT_OPID_ANT_RAM_STA_GET] = opfunc_ant_ram_stat_get, ++#endif ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_core_init(VOID) ++{ ++ INT32 i = 0; ++ ++ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); ++ /* gMtkWmtCtx.p_ops is cleared to NULL */ ++ ++ /* default FUNC_OFF state */ ++ for (i = 0; i < WMTDRV_TYPE_MAX; ++i) { ++ /* WinMo is default to DRV_STS_UNREG; */ ++ gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF; ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_core_deinit(VOID) ++{ ++ /* return to init state */ ++ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); ++ /* gMtkWmtCtx.p_ops is cleared to NULL */ ++ return 0; ++} ++ ++/* TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not...... */ ++/* parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer. */ ++INT32 wmt_core_tx(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) ++{ ++ INT32 iRet; ++#if 0 /* Test using direct function call instead of wmt_ctrl() interface */ ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_TX; ++ ctrlData.au4CtrlData[0] = (UINT32) pData; ++ ctrlData.au4CtrlData[1] = size; ++ ctrlData.au4CtrlData[2] = (UINT32) writtenSize; ++ ctrlData.au4CtrlData[3] = bRawFlag; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_TX, iRet:%d\n", iRet); ++ /* (*sys_dbg_assert)(0, __FILE__, __LINE__); */ ++ osal_assert(0); ++ } ++#endif ++ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); ++ if (0 == *writtenSize) { ++ INT32 retry_times = 0; ++ INT32 max_retry_times = 3; ++ INT32 retry_delay_ms = 360; ++ ++ WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n", ++ *writtenSize); ++ while ((0 == *writtenSize) && (retry_times < max_retry_times)) { ++ WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms); ++ osal_sleep_ms(retry_delay_ms); ++ ++ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); ++ retry_times++; ++ } ++ } ++ return iRet; ++} ++ ++INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize) ++{ ++ INT32 iRet; ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_RX; ++ ctrlData.au4CtrlData[0] = (SIZE_T) pBuf; ++ ctrlData.au4CtrlData[1] = bufLen; ++ ctrlData.au4CtrlData[2] = (SIZE_T) readSize; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet); ++ mtk_wcn_stp_dbg_dump_package(); ++ osal_assert(0); ++ } ++ return iRet; ++} ++ ++INT32 wmt_core_rx_flush(UINT32 type) ++{ ++ INT32 iRet; ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_RX_FLUSH; ++ ctrlData.au4CtrlData[0] = (UINT32) type; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet); ++ osal_assert(0); ++ } ++ return iRet; ++} ++ ++INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn) ++{ ++ INT32 iRet = 0; ++ UINT32 u4WmtCmdPduLen; ++ UINT32 u4WmtEventPduLen; ++ UINT32 u4ReadSize; ++ UINT32 u4WrittenSize; ++ WMT_PKT rWmtPktCmd; ++ WMT_PKT rWmtPktEvent; ++ MTK_WCN_BOOL fgFail; ++ ++ /* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ ++ /* Using this struct relies on compiler's implementation and pack() settings */ ++ osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd)); ++ osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent)); ++ ++ rWmtPktCmd.eType = (UINT8) PKT_TYPE_CMD; ++ rWmtPktCmd.eOpCode = (UINT8) OPCODE_FUNC_CTRL; ++ ++ /* Flag field: driver type */ ++ rWmtPktCmd.aucParam[0] = (UINT8) type; ++ /* Parameter field: ON/OFF */ ++ rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0; ++ rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN; /* (2) */ ++ ++ /* WMT Header + WMT SDU */ ++ u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen; /* (6) */ ++ u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN; /* (5) */ ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++/* iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize); */ ++ iRet = wmt_core_tx((PUINT8) &rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, MTK_WCN_BOOL_FALSE); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed\n"); ++ break; ++ } ++ ++ iRet = wmt_core_rx((PUINT8) &rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_rx failed\n"); ++ break; ++ } ++ ++ /* Error Checking */ ++ if (PKT_TYPE_EVENT != rWmtPktEvent.eType) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n", ++ rWmtPktEvent.eType); ++ break; ++ } ++ ++ if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) { ++ WMT_ERR_FUNC ++ ("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n", ++ rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode); ++ break; ++ } ++ ++ if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) { ++ WMT_ERR_FUNC ++ ("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n", ++ u4WmtEventPduLen, rWmtPktEvent.u2SduLen); ++ break; ++ } ++ /* Status field of event check */ ++ if (0 != rWmtPktEvent.aucParam[0]) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", rWmtPktEvent.aucParam[0]); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ } while (0); ++ ++ if (MTK_WCN_BOOL_FALSE == fgFail) { ++ /* WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n"); */ ++ return 0; ++ } ++ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]); ++ return -3; ++} ++ ++INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp) ++{ ++ UINT32 opId; ++ INT32 ret; ++ ++ opId = pWmtOp->opId; ++ ++ if (wmt_core_opfunc[opId]) { ++ ret = (*(wmt_core_opfunc[opId])) (pWmtOp); /*wmtCoreOpidHandlerPack[].opHandler */ ++ return ret; ++ } ++ WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId); ++ return -2; ++ ++} ++ ++INT32 wmt_core_opid(P_WMT_OP pWmtOp) ++{ ++ ++ /*sanity check */ ++ if (NULL == pWmtOp) { ++ WMT_ERR_FUNC("null pWmtOP\n"); ++ /*print some message with error info */ ++ return -1; ++ } ++ ++ if (WMT_OPID_MAX <= pWmtOp->opId) { ++ WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId); ++ return -2; ++ } ++ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ ++ return wmt_core_opid_handler(pWmtOp); ++} ++ ++INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2) ++{ ++ INT32 iRet = -1; ++ WMT_CTRL_DATA ctrlData; ++ SIZE_T val1 = (pPa1) ? *pPa1 : 0; ++ SIZE_T val2 = (pPa2) ? *pPa2 : 0; ++ ++ ctrlData.ctrlId = (SIZE_T) ctrId; ++ ctrlData.au4CtrlData[0] = val1; ++ ctrlData.au4CtrlData[1] = val2; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /* ERROR */ ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%d), value(%d) iRet:(%d)\n", ctrId, val1, ++ val2, iRet); ++ osal_assert(0); ++ } else { ++ if (pPa1) ++ *pPa1 = ctrlData.au4CtrlData[0]; ++ if (pPa2) ++ *pPa2 = ctrlData.au4CtrlData[1]; ++ } ++ return iRet; ++} ++ ++VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len) ++{ ++ PUINT8 ptr = pData; ++ INT32 k = 0; ++ ++ WMT_INFO_FUNC("%s len=%d\n", pTitle, len); ++ for (k = 0; k < len; k++) { ++ if (k % 16 == 0) ++ WMT_INFO_FUNC("\n"); ++ WMT_INFO_FUNC("0x%02x ", *ptr); ++ ptr++; ++ } ++ WMT_INFO_FUNC("--end\n"); ++} ++ ++/*! ++ * \brief An WMT-CORE function to support read, write, and read after write to ++ * an internal register. ++ * ++ * Detailed description. ++ * ++ * \param isWrite 1 for write, 0 for read ++ * \param offset of register to be written or read ++ * \param pVal a pointer to the 32-bit value to be writtern or read ++ * \param mask a 32-bit mask to be applied for the read or write operation ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid parameters ++ * \retval -2 tx cmd fail ++ * \retval -3 rx event fail ++ * \retval -4 read check error ++ */ ++INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask) ++{ ++ INT32 iRet; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2; /* w:1, r:2 */ ++ osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4); /* offset */ ++ osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4); /* [2] is var addr */ ++ osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4); /* mask */ ++ ++ /* send command */ ++ iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if ((iRet) || (u4Res != sizeof(WMT_SET_REG_CMD))) { ++ WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %d)\n", iRet, u4Res, sizeof(WMT_SET_REG_CMD)); ++ return -2; ++ } ++ ++ /* receive event */ ++ evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT); ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if ((iRet) || (u4Res != evtLen)) { ++ WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen); ++ return -3; ++ } ++ ++ if (!isWrite) { ++ UINT32 rxEvtAddr; ++ UINT32 txCmdAddr; ++ ++ osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4); ++ osal_memcpy(&rxEvtAddr, &evtBuf[8], 4); ++ ++ /* check read result */ ++ if (txCmdAddr != rxEvtAddr) { ++ WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, txCmdAddr); ++ return -4; ++ } ++ WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr); ++ ++ osal_memcpy(pVal, &evtBuf[12], 4); ++ } ++ ++ /* no error here just return 0 */ ++ return 0; ++} ++ ++INT32 wmt_core_init_script(struct init_script *script, INT32 count) ++{ ++ UINT8 evtBuf[256]; ++ UINT32 u4Res; ++ INT32 i = 0; ++ INT32 iRet; ++ ++ for (i = 0; i < count; i++) { ++ WMT_DBG_FUNC("WMT-CORE: init_script operation %s start\n", script[i].str); ++ /* CMD */ ++ /* iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res); */ ++ iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != script[i].cmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", script[i].str, iRet, u4Res, ++ script[i].cmdSz); ++ break; ++ } ++ /* EVENT BUF */ ++ osal_memset(evtBuf, 0, sizeof(evtBuf)); ++ iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res); ++ if (iRet || (u4Res != script[i].evtSz)) { ++ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", script[i].str, iRet, ++ u4Res, script[i].evtSz); ++ mtk_wcn_stp_dbg_dump_package(); ++ break; ++ } ++ /* RESULT */ ++ if (0x14 != evtBuf[1]) { /* workaround RF calibration data EVT,do not care this EVT */ ++ if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) { ++ WMT_ERR_FUNC("WMT-CORE:compare %s result error\n", script[i].str); ++ WMT_ERR_FUNC ++ ("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], script[i].evtSz, ++ script[i].evt[0], script[i].evt[1], script[i].evt[2], script[i].evt[3], ++ script[i].evt[4]); ++ mtk_wcn_stp_dbg_dump_package(); ++ break; ++ } ++ } ++ WMT_DBG_FUNC("init_script operation %s ok\n", script[i].str); ++ } ++ ++ return (i == count) ? 0 : -1; ++} ++ ++static INT32 wmt_core_stp_init(VOID) ++{ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ UINT8 co_clock_type; ++ P_WMT_CTX pctx = &gMtkWmtCtx; ++ P_WMT_GEN_CONF pWmtGenConf = NULL; ++ ++ wmt_conf_read_file(); ++ pWmtGenConf = wmt_conf_get_cfg(); ++ if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) { ++ WMT_ERR_FUNC("WMT-CORE: no hif info!\n"); ++ osal_assert(0); ++ return -1; ++ } ++ /* 4 <1> open stp */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); ++ return -2; ++ } ++ /* 4 <1.5> disable and un-ready stp */ ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WMT_STP_CONF_RDY; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ++ /* 4 <2> set mode and enable */ ++ if (WMT_HIF_BTIF == pctx->wmtHifConf.hifType) { ++ ctrlPa1 = WMT_STP_CONF_MODE; ++ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ } ++ ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 1; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); ++ return -3; ++ } ++ /* TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips??? */ ++ ++ iRet = wmt_core_hw_check(); ++ if (iRet) { ++ WMT_ERR_FUNC("hw_check fail:%d\n", iRet); ++ return -4; ++ } ++ /* mtkWmtCtx.p_ic_ops is identified and checked ok */ ++ if ((NULL != pctx->p_ic_ops->co_clock_ctrl) && (pWmtGenConf != NULL)) { ++ co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f); ++ (*(pctx->p_ic_ops->co_clock_ctrl)) (co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN); ++ } else { ++ WMT_WARN_FUNC("pctx->p_ic_ops->co_clock_ctrl(0x%x), pWmtGenConf(0x%x)\n", pctx->p_ic_ops->co_clock_ctrl, ++ pWmtGenConf); ++ } ++ osal_assert(NULL != pctx->p_ic_ops->sw_init); ++ if (NULL != pctx->p_ic_ops->sw_init) { ++ iRet = (*(pctx->p_ic_ops->sw_init)) (&pctx->wmtHifConf); ++ } else { ++ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); ++ return -5; ++ } ++ if (iRet) { ++ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet); ++ return -6; ++ } ++ /* 4 <10> set stp ready */ ++ ctrlPa1 = WMT_STP_CONF_RDY; ++ ctrlPa2 = 1; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ++ return iRet; ++} ++ ++static INT32 wmt_core_stp_deinit(VOID) ++{ ++ INT32 iRet; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ WMT_DBG_FUNC(" start\n"); ++ ++ if (NULL == gMtkWmtCtx.p_ic_ops) { ++ WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n"); ++ goto deinit_ic_ops_done; ++ } ++ if (NULL != gMtkWmtCtx.p_ic_ops->sw_deinit) { ++ iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit)) (&gMtkWmtCtx.wmtHifConf); ++ /* unbind WMT-IC */ ++ gMtkWmtCtx.p_ic_ops = NULL; ++ } else { ++ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); ++ } ++ ++deinit_ic_ops_done: ++ ++ /* 4 <1> un-ready, disable, and close stp. */ ++ ctrlPa1 = WMT_STP_CONF_RDY; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); ++ ++ if (iRet) ++ WMT_WARN_FUNC("end with fail:%d\n", iRet); ++ ++ return iRet; ++} ++ ++static VOID wmt_core_dump_func_state(PINT8 pSource) ++{ ++ WMT_WARN_FUNC("[%s]status(b:%d f:%d g:%d w:%d lpbk:%d coredump:%d wmt:%d stp:%d)\n", ++ (pSource == NULL ? (PINT8) "CORE" : pSource), ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP], ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] ++ ); ++ return; ++ ++} ++ ++MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer) ++{ ++ if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) { ++ /*major no. does not match */ ++ WMT_ERR_FUNC("WMT-CORE: chip version(0x%d) does not match patch version(0x%d)\n", u4HwVer, u4PatchVer); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++static INT32 wmt_core_hw_check(VOID) ++{ ++ UINT32 chipid; ++ P_WMT_IC_OPS p_ops; ++ INT32 iret; ++ ++ /* 1. get chip id */ ++ chipid = 0; ++ WMT_LOUD_FUNC("before read hwcode (chip id)\n"); ++ iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK); /* read 0x80000008 */ ++ if (iret) { ++ WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret); ++ return -2; ++ } ++ WMT_DBG_FUNC("get hwcode (chip id) (0x%x)\n", chipid); ++ ++ /* TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id */ ++ switch (chipid) { ++#if CFG_CORE_MT6620_SUPPORT ++ case 0x6620: ++ p_ops = &wmt_ic_ops_mt6620; ++ break; ++#endif ++#if CFG_CORE_MT6628_SUPPORT ++ case 0x6628: ++ p_ops = &wmt_ic_ops_mt6628; ++ break; ++#endif ++#if CFG_CORE_SOC_SUPPORT ++ case 0x6572: ++ case 0x6582: ++ case 0x6592: ++ case 0x8127: ++ case 0x6571: ++ case 0x6752: ++ case 0x0279: ++ case 0x0326: ++ case 0x0321: ++ case 0x0335: ++ case 0x0337: ++ case 0x8163: ++ case 0x6580: ++ p_ops = &wmt_ic_ops_soc; ++ break; ++#endif ++ default: ++ p_ops = (P_WMT_IC_OPS) NULL; ++#if CFG_CORE_SOC_SUPPORT ++ if (0x7f90 == chipid - 0x600) { ++ p_ops = &wmt_ic_ops_soc; ++ chipid -= 0xf6d; ++ } ++#endif ++ break; ++ } ++ ++ if (NULL == p_ops) { ++ WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid); ++ return -3; ++ } else if (MTK_WCN_BOOL_FALSE == wmt_core_ic_ops_check(p_ops)) { ++ WMT_ERR_FUNC ++ ("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", ++ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); ++ return -4; ++ } ++ WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", ++ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); ++ ++ wmt_ic_ops_soc.icId = chipid; ++ WMT_DBG_FUNC("wmt_ic_ops_soc.icId(0x%x)\n", wmt_ic_ops_soc.icId); ++ iret = p_ops->ic_ver_check(); ++ if (iret) { ++ WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret); ++ return -5; ++ } ++ ++ WMT_DBG_FUNC("chip id(0x%x) ver_check ok\n", chipid); ++ gMtkWmtCtx.p_ic_ops = p_ops; ++ return 0; ++} ++ ++static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp) ++{ ++ if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) { ++ WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n"); ++ return -1; ++ } ++ ++ if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) { ++ WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. overwrite! old (%d), new(%d))\n", ++ gMtkWmtCtx.wmtHifConf.hifType, pWmtOp->au4OpData[0]); ++ } else { ++ gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT; ++ WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n"); ++ } ++ ++ osal_memcpy(&gMtkWmtCtx.wmtHifConf, &pWmtOp->au4OpData[0], osal_sizeof(gMtkWmtCtx.wmtHifConf)); ++ return 0; ++ ++} ++ ++static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ INT32 retry = WMT_PWRON_RTY_DFT; ++ ++ if (DRV_STS_POWER_OFF != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n", ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); ++ osal_assert(0); ++ return -1; ++ } ++ /* TODO: [FixMe][GeorgeKuo]: clarify the following is reqiured or not! */ ++ if (pWmtOp->u4InfoBit & WMT_OP_HIF_BIT) ++ opfunc_hif_conf(pWmtOp); ++ ++pwr_on_rty: ++ /* power on control */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); ++ if (0 == retry--) { ++ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); ++ goto pwr_on_rty; ++ } ++ return -1; ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ ++ /* init stp */ ++ iRet = wmt_core_stp_init(); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet); ++ osal_assert(0); ++ ++ /* deinit stp */ ++ iRet = wmt_core_stp_deinit(); ++ iRet = opfunc_pwr_off(pWmtOp); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: opfunc_pwr_off fail during pwr_on retry\n"); ++ ++ if (0 < retry--) { ++ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); ++ goto pwr_on_rty; ++ } ++ iRet = -2; ++ return iRet; ++ } ++ ++ WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n"); ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; ++ ++ /* What to do when state is changed from POWER_OFF to POWER_ON? ++ * 1. STP driver does s/w reset ++ * 2. UART does 0xFF wake up ++ * 3. SDIO does re-init command(changed to trigger by host) ++ */ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n", ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); ++ osal_assert(0); ++ return -1; ++ } ++ if (MTK_WCN_BOOL_FALSE == g_pwr_off_flag) { ++ WMT_WARN_FUNC("CONNSYS power off be disabled, maybe need trigger core dump!\n"); ++ osal_assert(0); ++ return -2; ++ } ++ ++ /* wmt and stp are initialized successfully */ ++ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ iRet = wmt_core_stp_deinit(); ++ if (iRet) { ++ WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet); ++ /*should let run to power down chip */ ++ } ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ ++ /* power off control */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet); ++ WMT_WARN_FUNC("HW_PWR_OFF ok\n"); ++ ++ /*anyway, set to POWER_OFF state */ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; ++ return iRet; ++ ++} ++ ++static INT32 opfunc_func_on(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = -1; ++ INT32 iPwrOffRet = -1; ++ UINT32 drvType; ++ ++ drvType = pWmtOp->au4OpData[0]; ++ ++ /* Check abnormal type */ ++ if (WMTDRV_TYPE_COREDUMP < drvType) { ++ WMT_ERR_FUNC("abnormal Fun(%d)\n", drvType); ++ osal_assert(0); ++ return -1; ++ } ++ ++ /* Check abnormal state */ ++ if ((DRV_STS_POWER_OFF > gMtkWmtCtx.eDrvStatus[drvType]) ++ || (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType])) { ++ WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n", drvType, gMtkWmtCtx.eDrvStatus[drvType]); ++ osal_assert(0); ++ return -2; ++ } ++ ++ /* check if func already on */ ++ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[drvType]) { ++ WMT_WARN_FUNC("func(%d) already on\n", drvType); ++ return 0; ++ } ++ /*enable power off flag, if flag=0, power off connsys will not be executed */ ++ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); ++ /* check if chip power on is needed */ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ iRet = opfunc_pwr_on(pWmtOp); ++ ++ if (iRet) { ++ WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet); ++ osal_assert(0); ++ ++ /* check all sub-func and do power off */ ++ return -3; ++ } ++ } ++ ++ if (WMTDRV_TYPE_WMT > drvType) { ++ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_on) { ++ iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); ++ if (0 != iRet) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ else ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; ++ } else { ++ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); ++ iRet = -5; ++ } ++ } else { ++ if (WMTDRV_TYPE_LPBK == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; ++ else if (WMTDRV_TYPE_COREDUMP == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; ++ iRet = 0; ++ } ++ ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet); ++ osal_assert(0); ++ /* FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary? */ ++ /* check all sub-func and do power off */ ++ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { ++ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); ++ mtk_wcn_wmt_system_state_reset(); ++ ++ iPwrOffRet = opfunc_pwr_off(pWmtOp); ++ if (iPwrOffRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iPwrOffRet, ++ drvType); ++ osal_assert(0); ++ } ++ } ++ return iRet; ++ } ++ ++ wmt_core_dump_func_state("AF FUNC ON"); ++ ++ return 0; ++} ++ ++static INT32 opfunc_func_off(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 drvType; ++ ++ drvType = pWmtOp->au4OpData[0]; ++ /* Check abnormal type */ ++ if (WMTDRV_TYPE_COREDUMP < drvType) { ++ WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off\n", drvType); ++ osal_assert(0); ++ return -1; ++ } ++ ++ /* Check abnormal state */ ++ if (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) { ++ WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off\n", ++ drvType, gMtkWmtCtx.eDrvStatus[drvType]); ++ osal_assert(0); ++ return -2; ++ } ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[drvType]) { ++ WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n", ++ drvType, gMtkWmtCtx.eDrvStatus[drvType]); ++ /* needs to check 4 subsystem's state? */ ++ return 0; ++ } else if (WMTDRV_TYPE_WMT > drvType) { ++ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_off) { ++ iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); ++ } else { ++ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); ++ iRet = -3; ++ } ++ } else { ++ if (WMTDRV_TYPE_LPBK == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ else if (WMTDRV_TYPE_COREDUMP == drvType) ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ iRet = 0; ++ } ++ ++ /* shall we put device state to POWER_OFF state when fail? */ ++ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; ++ ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet); ++ osal_assert(0); ++ /* no matter subsystem function control fail or not, ++ *chip should be powered off when no subsystem is active ++ */ ++ /* return iRet; */ ++ } ++ ++ /* check all sub-func and do power off */ ++ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && ++ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { ++ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); ++ ++ iRet = opfunc_pwr_off(pWmtOp); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iRet, drvType); ++ osal_assert(0); ++ } ++ } ++ ++ wmt_core_dump_func_state("AF FUNC OFF"); ++ return iRet; ++} ++ ++/* TODO:[ChangeFeature][George] is this OP obsoleted? */ ++static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp) ++{ ++ INT32 iret; ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("reg_rw when WMT is powered off\n"); ++ return -1; ++ } ++ iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0], ++ pWmtOp->au4OpData[1], (PUINT32) pWmtOp->au4OpData[2], pWmtOp->au4OpData[3]); ++ ++ return iret; ++} ++ ++static INT32 opfunc_exit(P_WMT_OP pWmtOp) ++{ ++ /* TODO: [FixMe][George] is ok to leave this function empty??? */ ++ WMT_WARN_FUNC("EMPTY FUNCTION\n"); ++ return 0; ++} ++ ++static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp) ++{ ++ INT32 ret = -1; ++ UINT32 u4_result = 0; ++ UINT32 evt_len; ++ UINT8 evt_buf[16] = { 0 }; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ typedef INT32(*STP_PSM_CB) (INT32); ++ STP_PSM_CB psm_cb = NULL; ++ ++ if (SLEEP == pWmtOp->au4OpData[0]) { ++ WMT_DBG_FUNC("**** Send sleep command\n"); ++ /* mtk_wcn_stp_set_psm_state(ACT_INACT); */ ++ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ ++ ret = wmt_core_tx((PUINT8) &WMT_SLEEP_CMD[0], sizeof(WMT_SLEEP_CMD), &u4_result, 0); ++ if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) { ++ WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, ++ sizeof(WMT_SLEEP_CMD)); ++ goto pwr_sv_done; ++ } ++ ++ evt_len = sizeof(WMT_SLEEP_EVT); ++ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); ++ if (ret || (u4_result != evt_len)) { ++ unsigned long type = WMTDRV_TYPE_WMT; ++ unsigned long reason = 33; ++ unsigned long ctrlpa = 1; ++ ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); ++ mtk_wcn_stp_dbg_dump_package(); ++ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); ++ if (!ret) { /* parser ok */ ++ reason = 38; /* host schedule issue reason code */ ++ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); ++ } ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); ++ goto pwr_sv_done; ++ } ++ ++ if (osal_memcmp(evt_buf, WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n"); ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ u4_result, ++ evt_buf[0], ++ evt_buf[1], ++ evt_buf[2], ++ evt_buf[3], ++ evt_buf[4], ++ evt_buf[5]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_SLEEP_EVT), ++ WMT_SLEEP_EVT[0], ++ WMT_SLEEP_EVT[1], ++ WMT_SLEEP_EVT[2], ++ WMT_SLEEP_EVT[3], ++ WMT_SLEEP_EVT[4], ++ WMT_SLEEP_EVT[5]); ++ mtk_wcn_stp_dbg_dump_package(); ++ goto pwr_sv_done; ++ } else { ++ WMT_DBG_FUNC("Send sleep command OK!\n"); ++ } ++ } else if (pWmtOp->au4OpData[0] == WAKEUP) { ++ WMT_DBG_FUNC("wakeup connsys by btif"); ++ ++ ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS, &ctrlPa1, &ctrlPa2); ++ if (ret) { ++ WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)", ret); ++ goto pwr_sv_done; ++ } ++#if 0 ++ WMT_DBG_FUNC("**** Send wakeup command\n"); ++ ret = wmt_core_tx(WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1); ++ ++ if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD))) { ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, ++ sizeof(WMT_WAKEUP_CMD)); ++ goto pwr_sv_done; ++ } ++#endif ++ evt_len = sizeof(WMT_WAKEUP_EVT); ++ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); ++ if (ret || (u4_result != evt_len)) { ++ unsigned long type = WMTDRV_TYPE_WMT; ++ unsigned long reason = 34; ++ unsigned long ctrlpa = 2; ++ ++ WMT_ERR_FUNC("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); ++ mtk_wcn_stp_dbg_dump_package(); ++ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); ++ if (!ret) { /* parser ok */ ++ reason = 39; /* host schedule issue reason code */ ++ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); ++ } ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); ++ goto pwr_sv_done; ++ } ++ ++ if (osal_memcmp(evt_buf, WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n"); ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ u4_result, ++ evt_buf[0], ++ evt_buf[1], ++ evt_buf[2], ++ evt_buf[3], ++ evt_buf[4], ++ evt_buf[5]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_WAKEUP_EVT), ++ WMT_WAKEUP_EVT[0], ++ WMT_WAKEUP_EVT[1], ++ WMT_WAKEUP_EVT[2], ++ WMT_WAKEUP_EVT[3], ++ WMT_WAKEUP_EVT[4], ++ WMT_WAKEUP_EVT[5]); ++ mtk_wcn_stp_dbg_dump_package(); ++ goto pwr_sv_done; ++ } else { ++ WMT_DBG_FUNC("Send wakeup command OK!\n"); ++ } ++ } else if (pWmtOp->au4OpData[0] == HOST_AWAKE) { ++ ++ WMT_DBG_FUNC("**** Send host awake command\n"); ++ ++ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; ++ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ ++ ret = wmt_core_tx((PUINT8) WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), &u4_result, 0); ++ if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD))) { ++ WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, ++ sizeof(WMT_HOST_AWAKE_CMD)); ++ goto pwr_sv_done; ++ } ++ ++ evt_len = sizeof(WMT_HOST_AWAKE_EVT); ++ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); ++ if (ret || (u4_result != evt_len)) { ++ unsigned long type = WMTDRV_TYPE_WMT; ++ unsigned long reason = 35; ++ unsigned long ctrlpa = 3; ++ ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: read HOST_AWAKE_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); ++ mtk_wcn_stp_dbg_dump_package(); ++ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); ++ if (!ret) { /* parser ok */ ++ reason = 40; /* host schedule issue reason code */ ++ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); ++ } ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); ++ goto pwr_sv_done; ++ } ++ ++ if (osal_memcmp(evt_buf, WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n"); ++ wmt_core_rx_flush(WMT_TASK_INDX); ++ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ u4_result, ++ evt_buf[0], ++ evt_buf[1], ++ evt_buf[2], ++ evt_buf[3], ++ evt_buf[4], ++ evt_buf[5]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_HOST_AWAKE_EVT), ++ WMT_HOST_AWAKE_EVT[0], ++ WMT_HOST_AWAKE_EVT[1], ++ WMT_HOST_AWAKE_EVT[2], ++ WMT_HOST_AWAKE_EVT[3], ++ WMT_HOST_AWAKE_EVT[4], ++ WMT_HOST_AWAKE_EVT[5]); ++ mtk_wcn_stp_dbg_dump_package(); ++ /* goto pwr_sv_done; */ ++ } else { ++ WMT_DBG_FUNC("Send host awake command OK!\n"); ++ } ++ } ++pwr_sv_done: ++ ++ if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) { ++ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; ++ WMT_DBG_FUNC("Do STP-CB! %d %p / %p\n", pWmtOp->au4OpData[0], (PVOID) pWmtOp->au4OpData[1], ++ (PVOID) psm_cb); ++ if (NULL != psm_cb) { ++ psm_cb(pWmtOp->au4OpData[0]); ++ } else { ++ WMT_ERR_FUNC("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n", ++ psm_cb); ++ } ++ } ++ ++ return ret; ++} ++ ++static INT32 opfunc_dsns(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ WMT_DSNS_CMD[4] = (UINT8) pWmtOp->au4OpData[0]; ++ WMT_DSNS_CMD[5] = (UINT8) pWmtOp->au4OpData[1]; ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) { ++ WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, ++ osal_sizeof(WMT_DSNS_CMD)); ++ return iRet; ++ } ++ ++ evtLen = osal_sizeof(WMT_DSNS_EVT); ++ ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if (iRet || (u4Res != evtLen)) { ++ WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); ++ mtk_wcn_stp_dbg_dump_package(); ++ return iRet; ++ } ++ ++ if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) { ++ WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n"); ++ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], ++ osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2], ++ WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]); ++ } else { ++ WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n"); ++ } ++ ++ return iRet; ++} ++ ++#if CFG_CORE_INTERNAL_TXRX ++INT32 wmt_core_lpbk_do_stp_init(void) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); ++ return -1; ++ } ++ ++ ctrlPa1 = WMT_STP_CONF_MODE; ++ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 1; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); ++ return -2; ++ } ++} ++ ++INT32 wmt_core_lpbk_do_stp_deinit(void) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++#endif ++static INT32 opfunc_lpbk(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet; ++ UINT32 u4WrittenSize = 0; ++ UINT32 u4ReadSize = 0; ++ UINT32 buf_length = 0; ++ UINT32 *pbuffer = NULL; ++ UINT16 len_in_cmd; ++ ++ /* UINT32 offset; */ ++ UINT8 WMT_TEST_LPBK_CMD[] = { 0x1, 0x2, 0x0, 0x0, 0x7 }; ++ UINT8 WMT_TEST_LPBK_EVT[] = { 0x2, 0x2, 0x0, 0x0, 0x0 }; ++ ++ /* UINT8 lpbk_buf[1024 + 5] = {0}; */ ++ MTK_WCN_BOOL fgFail; ++ ++ buf_length = pWmtOp->au4OpData[0]; /* packet length */ ++ pbuffer = (VOID *) pWmtOp->au4OpData[1]; /* packet buffer pointer */ ++ WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk\n"); ++ ++#if 0 ++ osal_memcpy(&WMT_TEST_LPBK_EVT[0], &WMT_TEST_LPBK_CMD[0], osal_sizeof(WMT_TEST_LPBK_CMD)); ++#endif ++#if !CFG_CORE_INTERNAL_TXRX ++ /*check if WMTDRV_TYPE_LPBK function is already on */ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] ++ || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) { ++ WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n"); ++ osal_assert(0); ++ return -2; ++ } ++#endif ++ /*package loopback for STP */ ++ ++ /* init buffer */ ++ osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf)); ++ ++ len_in_cmd = buf_length + 1; /* add flag field */ ++ ++ osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2); ++ osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2); ++ ++ /* wmt cmd */ ++ osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD)); ++ osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length); ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ /*send packet through STP */ ++ ++ /* iRet = (*kal_stp_tx)( ++ *(PUINT8)gLpbkBuf, ++ *osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length, ++ *&u4WrittenSize); ++ */ ++ iRet = wmt_core_tx((PUINT8) gLpbkBuf, ++ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length), ++ &u4WrittenSize, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet) { ++ WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed\n"); ++ break; ++ } ++ WMT_INFO_FUNC("opfunc_lpbk wmt_core_tx OK\n"); ++ ++ /*receive firmware response from STP */ ++ iRet = wmt_core_rx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), &u4ReadSize); ++ if (iRet) { ++ WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed\n"); ++ break; ++ } ++ WMT_INFO_FUNC("opfunc_lpbk wmt_core_rx OK\n"); ++ /*check if loopback response ok or not */ ++ if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) { ++ WMT_ERR_FUNC("lpbk event read size wrong(%d, %d)\n", u4ReadSize, ++ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); ++ break; ++ } ++ WMT_INFO_FUNC("lpbk event read size right(%d, %d)\n", u4ReadSize, ++ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); ++ ++ if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) { ++ WMT_ERR_FUNC("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x]\n", ++ (INT32) u4ReadSize, gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], gLpbkBuf[4] ++ ); ++ break; ++ } ++ pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT); ++ osal_memcpy((VOID *) pWmtOp->au4OpData[1], gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length); ++ fgFail = MTK_WCN_BOOL_FALSE; ++ } while (0); ++ /*return result */ ++ /* WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d\n", fgFail); */ ++ return fgFail; ++ ++} ++ ++static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = 0; ++ UINT32 cmdNo = 0; ++ UINT32 cmdNoPa = 0; ++ ++ UINT8 tstCmd[64]; ++ UINT8 tstEvt[64]; ++ UINT8 tstEvtTmp[64]; ++ UINT32 u4Res; ++ SIZE_T tstCmdSz = 0; ++ SIZE_T tstEvtSz = 0; ++ ++ UINT8 *pRes = NULL; ++ UINT32 resBufRoom = 0; ++ /*test command list */ ++ /*1 */ ++ UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; ++ UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ UINT8 WMT_NOACK_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0A }; ++ UINT8 WMT_NOACK_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ UINT8 WMT_WARNRST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0B }; ++ UINT8 WMT_WARNRST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ UINT8 WMT_FWLOGTST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0C }; ++ UINT8 WMT_FWLOGTST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ ++ UINT8 WMT_EXCEPTION_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x09 }; ++ UINT8 WMT_EXCEPTION_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; ++ /*2 */ ++ UINT8 WMT_COEXDBG_CMD[] = { 0x01, 0x10, 0x02, 0x00, ++ 0x08, ++ 0xAA /*Debugging Parameter */ ++ }; ++ UINT8 WMT_COEXDBG_1_EVT[] = { 0x02, 0x10, 0x05, 0x00, ++ 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA /*event content */ ++ }; ++ UINT8 WMT_COEXDBG_2_EVT[] = { 0x02, 0x10, 0x07, 0x00, ++ 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB /*event content */ ++ }; ++ UINT8 WMT_COEXDBG_3_EVT[] = { 0x02, 0x10, 0x0B, 0x00, ++ 0x00, ++ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB /*event content */ ++ }; ++ /*test command list -end */ ++ ++ cmdNo = pWmtOp->au4OpData[0]; ++ ++ WMT_INFO_FUNC("Send Test command %d!\n", cmdNo); ++ if (cmdNo == 0) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send Assert command !\n"); ++ tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); ++ tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); ++ osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); ++ } else if (cmdNo == 1) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send Exception command !\n"); ++ tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD); ++ tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT); ++ osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz); ++ } else if (cmdNo == 2) { ++ cmdNoPa = pWmtOp->au4OpData[1]; ++ pRes = (PUINT8) pWmtOp->au4OpData[2]; ++ resBufRoom = pWmtOp->au4OpData[3]; ++ if (cmdNoPa <= 0xf) { ++ WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa); ++ tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD); ++ osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz); ++ if (tstCmdSz > 5) ++ tstCmd[5] = cmdNoPa; ++ ++ /*setup the expected event length */ ++ if (cmdNoPa <= 0x4) { ++ tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT); ++ osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz); ++ } else if (cmdNoPa == 0x5) { ++ tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT); ++ osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz); ++ } else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) { ++ tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT); ++ osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz); ++ } else { ++ ++ } ++ } else { ++ WMT_ERR_FUNC("cmdNoPa is wrong\n"); ++ return iRet; ++ } ++ } else if (cmdNo == 3) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send No Ack command !\n"); ++ tstCmdSz = osal_sizeof(WMT_NOACK_CMD); ++ tstEvtSz = osal_sizeof(WMT_NOACK_EVT); ++ osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz); ++ } else if (cmdNo == 4) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send Warm reset command !\n"); ++ tstCmdSz = osal_sizeof(WMT_WARNRST_CMD); ++ tstEvtSz = osal_sizeof(WMT_WARNRST_EVT); ++ osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz); ++ } else if (cmdNo == 5) { ++ /*dead command */ ++ WMT_INFO_FUNC("Send f/w log test command !\n"); ++ tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD); ++ tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT); ++ osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz); ++ osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz); ++ } ++ ++ else { ++ /*Placed youer test WMT command here, easiler to integrate and test with F/W side */ ++ } ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != tstCmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, tstCmdSz); ++ return -1; ++ } ++ ++ if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) { ++ WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n"); ++ return 0; ++ } ++ ++ iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res); ++ ++ /*Event Post Handling */ ++ if (cmdNo == 2) { ++ WMT_INFO_FUNC("#=========================================================#\n"); ++ WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa); ++ if (tstEvtSz > 5) { ++ wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5); ++ } else { ++ /* error log */ ++ WMT_ERR_FUNC("error coex debugging event\n"); ++ } ++ /*put response to buffer for shell to read */ ++ if (pRes != NULL && resBufRoom > 0) { ++ pWmtOp->au4OpData[3] = resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5; ++ osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]); ++ } else ++ pWmtOp->au4OpData[3] = 0; ++ WMT_INFO_FUNC("#=========================================================#\n"); ++ } ++ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ wmt_core_dump_func_state("BE HW RST"); ++ /*-->Reset WMT data structure*/ ++ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; */ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF; ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF; ++ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; */ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] = DRV_STS_POWER_OFF; ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF; ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF; ++ /*enable power off flag, if flag=0, power off connsys will not be executed */ ++ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); ++ /* if wmt is poweroff, we need poweron chip first */ ++ /* Zhiguo : this action also needed in BTIF interface to avoid KE */ ++#if 1 ++ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n"); ++ /* power on control */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); ++ return -1; ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ } ++#endif ++ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON) { ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); ++ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; ++ } ++ ++ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) { ++ ++ if (NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI] && NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off) { ++ iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet); ++ ++ /* check all sub-func and do power off */ ++ } else { ++ WMT_INFO_FUNC("wmt core: turn off WIFI func ok!!\n"); ++ } ++ } ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; ++ } ++#if 0 ++ /*<4>Power off Combo chip */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet); ++ WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet); ++#endif ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; ++ ++ /*-->PesetCombo chip*/ ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); ++ if (iRet) ++ WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet); ++ WMT_WARN_FUNC("WMT-CORE: -->[HW RST] ok\n"); ++ ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; ++ ++ /* 4 close stp */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ if (iRet == -2) { ++ WMT_INFO_FUNC("WMT-CORE:stp should have be closed\n"); ++ return 0; ++ } ++ WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n"); ++ return -1; ++ } ++ ++ wmt_core_dump_func_state("AF HW RST"); ++ return iRet; ++ ++} ++ ++static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = 0; ++ ++ iRet = wmt_core_stp_init(); ++ if (!iRet) ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; ++ return iRet; ++} ++ ++static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp) ++{ ++ ++ return 0; ++} ++ ++static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ WMT_THERM_CMD[4] = pWmtOp->au4OpData[0]; /*CMD type, refer to ENUM_WMTTHERM_TYPE_T */ ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) { ++ WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, ++ osal_sizeof(WMT_THERM_CMD)); ++ return iRet; ++ } ++ ++ evtLen = 16; ++ ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT)))) { ++ WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d, %d)\n", iRet, u4Res, ++ evtLen); ++ mtk_wcn_stp_dbg_dump_package(); ++ return iRet; ++ } ++ if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT)) { ++ if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) { ++ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n"); ++ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], ++ osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], WMT_THERM_CTRL_EVT[1], ++ WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], WMT_THERM_CTRL_EVT[4]); ++ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE; /*will return to function driver */ ++ mtk_wcn_stp_dbg_dump_package(); ++ } else { ++ WMT_DBG_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n"); ++ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE; /*will return to function driver */ ++ } ++ } else { ++ /*no need to judge the real thermal value */ ++ if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != 0) { ++ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n"); ++ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X]\n", ++ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5], ++ osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], WMT_THERM_READ_EVT[1], ++ WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]); ++ pWmtOp->au4OpData[1] = 0xFF; /*will return to function driver */ ++ mtk_wcn_stp_dbg_dump_package(); ++ } else { ++ WMT_DBG_FUNC("Send WMT_THERM_READ_CMD command OK!\n"); ++ pWmtOp->au4OpData[1] = evtBuf[5]; /*will return to function driver */ ++ } ++ } ++ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 u4Res; ++ UINT32 evtLen; ++ UINT8 evtBuf[16] = { 0 }; ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n"); ++ return -1; ++ } ++ ++ WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2; /* w:2, r:1 */ ++ osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8) &pWmtOp->au4OpData[1], 2); /* address */ ++ osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32) pWmtOp->au4OpData[2], 4); /* value */ ++ ++ wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD)); ++ ++ /* send command */ ++ /* iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res); */ ++ iRet = wmt_core_tx((PUINT8) WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) { ++ WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, ++ osal_sizeof(WMT_EFUSE_CMD)); ++ return iRet; ++ } ++ ++ evtLen = (pWmtOp->au4OpData[0]) ? osal_sizeof(WMT_EFUSE_EVT) : osal_sizeof(WMT_EFUSE_EVT); ++ ++ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); ++ if (iRet || (u4Res != evtLen)) ++ WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); ++ wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf)); ++ ++ return iRet; ++ ++} ++ ++static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = -1; ++ WMT_IC_PIN_ID id; ++ WMT_IC_PIN_STATE stat; ++ UINT32 flag; ++ ++ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { ++ WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n"); ++ return -1; ++ } ++ ++ if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) { ++ WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n"); ++ return -1; ++ } ++ ++ id = pWmtOp->au4OpData[0]; ++ stat = pWmtOp->au4OpData[1]; ++ flag = pWmtOp->au4OpData[2]; ++ ++ WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id, stat, flag); ++ ++ iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl)) (id, stat, flag); ++ ++ return iRet; ++} ++ ++MTK_WCN_BOOL wmt_core_is_quick_ps_support(void) ++{ ++ P_WMT_CTX pctx = &gMtkWmtCtx; ++ ++ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_quick_sleep)) ++ return (*(pctx->p_ic_ops->is_quick_sleep)) (); ++ ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void) ++{ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_WMT_CTX pctx = &gMtkWmtCtx; ++ ++ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_aee_dump_support)) ++ bRet = (*(pctx->p_ic_ops->is_aee_dump_support)) (); ++ else ++ bRet = MTK_WCN_BOOL_FALSE; ++ ++ return bRet; ++} ++ ++INT32 opfunc_pin_state(P_WMT_OP pWmtOp) ++{ ++ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ UINT32 iRet = 0; ++ ++ iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2); ++ return iRet; ++} ++ ++static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = -1; ++ UINT32 u4WrittenSize = 0; ++ UINT32 u4ReadSize = 0; ++ UINT32 buf_len = 0; ++ UINT8 *buffer = NULL; ++ UINT8 evt_buffer[8] = { 0 }; ++ MTK_WCN_BOOL fgFail; ++ ++ UINT8 WMT_BGW_DESENSE_CMD[] = { ++ 0x01, 0x0e, 0x0f, 0x00, ++ 0x02, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00 ++ }; ++ UINT8 WMT_BGW_DESENSE_EVT[] = { 0x02, 0x0e, 0x01, 0x00, 0x00 }; ++ ++ buf_len = pWmtOp->au4OpData[0]; ++ buffer = (PUINT8) pWmtOp->au4OpData[1]; ++ ++ osal_memcpy(&WMT_BGW_DESENSE_CMD[5], buffer, buf_len); ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ iRet = ++ wmt_core_tx(&WMT_BGW_DESENSE_CMD[0], osal_sizeof(WMT_BGW_DESENSE_CMD), &u4WrittenSize, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))) { ++ WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); ++ break; ++ } ++ ++ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_BGW_DESENSE_EVT), &u4ReadSize); ++ if (iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))) { ++ WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize); ++ break; ++ } ++ ++ if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) { ++ WMT_ERR_FUNC ++ ("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", ++ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4]); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ ++ return fgFail; ++} ++ ++static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp) ++{ ++ UINT32 kind = 0; ++ INT32 iRet = -1; ++ UINT32 u4WrittenSize = 0; ++ UINT32 u4ReadSize = 0; ++ UINT8 evt_buffer[12] = { 0 }; ++ MTK_WCN_BOOL fgFail; ++ PUINT8 set_mcu_clk_str[] = { ++ "Enable MCU PLL", ++ "SET MCU CLK to 26M", ++ "SET MCU CLK to 37M", ++ "SET MCU CLK to 64M", ++ "SET MCU CLK to 69M", ++ "SET MCU CLK to 104M", ++ "SET MCU CLK to 118.857M", ++ "SET MCU CLK to 138.67M", ++ "Disable MCU PLL" ++ }; ++ UINT8 WMT_SET_MCU_CLK_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++ }; ++ UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++ UINT8 WMT_EN_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00 }; /* enable pll clk */ ++ UINT8 WMT_26_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x00, 0x4d, 0x84, 0x00 }; /* set 26M */ ++ UINT8 WMT_37_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1e, 0x4d, 0x84, 0x00 }; /* set 37.8M */ ++ UINT8 WMT_64_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1d, 0x4d, 0x84, 0x00 }; /* set 64M */ ++ UINT8 WMT_69_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1c, 0x4d, 0x84, 0x00 }; /* set 69M */ ++ UINT8 WMT_104_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5b, 0x4d, 0x84, 0x00 }; /* set 104M */ ++ UINT8 WMT_108_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5a, 0x4d, 0x84, 0x00 }; /* set 118.857M */ ++ UINT8 WMT_138_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x59, 0x4d, 0x84, 0x00 }; /* set 138.67M */ ++ UINT8 WMT_DIS_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 }; /* disable pll clk */ ++ ++ kind = pWmtOp->au4OpData[0]; ++ WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]); ++ ++ switch (kind) { ++ case 0: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_EN_MCU_CLK_CMD[0], osal_sizeof(WMT_EN_MCU_CLK_CMD)); ++ break; ++ case 1: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_26_MCU_CLK_CMD[0], osal_sizeof(WMT_26_MCU_CLK_CMD)); ++ break; ++ case 2: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_37_MCU_CLK_CMD[0], osal_sizeof(WMT_37_MCU_CLK_CMD)); ++ break; ++ case 3: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_64_MCU_CLK_CMD[0], osal_sizeof(WMT_64_MCU_CLK_CMD)); ++ break; ++ case 4: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_69_MCU_CLK_CMD[0], osal_sizeof(WMT_69_MCU_CLK_CMD)); ++ break; ++ case 5: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_104_MCU_CLK_CMD[0], osal_sizeof(WMT_104_MCU_CLK_CMD)); ++ break; ++ case 6: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_108_MCU_CLK_CMD[0], osal_sizeof(WMT_108_MCU_CLK_CMD)); ++ break; ++ case 7: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_138_MCU_CLK_CMD[0], osal_sizeof(WMT_138_MCU_CLK_CMD)); ++ break; ++ case 8: ++ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_DIS_MCU_CLK_CMD[0], osal_sizeof(WMT_DIS_MCU_CLK_CMD)); ++ break; ++ default: ++ WMT_ERR_FUNC("unknown kind\n"); ++ break; ++ } ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ iRet = ++ wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { ++ WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); ++ break; ++ } ++ ++ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); ++ if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { ++ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); ++ break; ++ } ++ ++ if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { ++ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", ++ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4], ++ evt_buffer[5], evt_buffer[6], evt_buffer[7]); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ ++ if (MTK_WCN_BOOL_FALSE == fgFail) ++ WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]); ++ ++ WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]); ++ ++ return fgFail; ++} ++ ++static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp) ++{ ++ UINT8 *buffer = NULL; ++ MTK_WCN_BOOL fgFail; ++ UINT32 u4Res; ++ UINT32 aDieChipid = 0; ++ UINT8 soc_adie_chipid_cmd[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; ++ UINT8 soc_adie_chipid_evt[] = { 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ UINT8 evtbuf[20]; ++ INT32 iRet = -1; ++ ++ buffer = (PUINT8) pWmtOp->au4OpData[1]; ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ /* read A die chipid by wmt cmd */ ++ iRet = ++ wmt_core_tx((PUINT8) &soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, osal_sizeof(soc_adie_chipid_evt), &u4Res); ++ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); ++ osal_memcpy(buffer, &evtbuf[u4Res - 2], 2); ++ pWmtOp->au4OpData[0] = 2; ++ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ ++ return fgFail; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp) ++{ ++ MTK_WCN_BOOL fgFail; ++ UINT32 u4Res; ++ UINT8 host_lte_btwf_coex_cmd[] = { 0x01, 0x10, 0x00, 0x00, 0x00 }; ++ UINT8 host_lte_btwf_coex_evt[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ UINT8 *pTxBuf = NULL; ++ UINT8 evtbuf[8] = { 0 }; ++ INT32 iRet = -1; ++ UINT16 msg_len = 0; ++ UINT32 total_len = 0; ++ UINT32 index = 0; ++ UINT8 *msg_local_buffer = NULL; ++ ++ msg_local_buffer = kmalloc(1300, GFP_KERNEL); ++ if (!msg_local_buffer) { ++ WMT_ERR_FUNC("msg_local_buffer kmalloc memory fail\n"); ++ return 0; ++ } ++ ++ pTxBuf = (UINT8 *) pWmtOp->au4OpData[0]; ++ if (NULL == pTxBuf) { ++ WMT_ERR_FUNC("idc msg buffer is NULL\n"); ++ return -1; ++ } ++ iRet = wmt_lib_idc_lock_aquire(); ++ if (iRet) { ++ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", iRet); ++ return iRet; ++ } ++ osal_memcpy(&msg_len, &pTxBuf[0], osal_sizeof(msg_len)); ++ if (msg_len > 1200) { ++ wmt_lib_idc_lock_release(); ++ WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len); ++ return -2; ++ } ++ msg_len += 1; /*flag byte */ ++ ++ osal_memcpy(&host_lte_btwf_coex_cmd[2], &msg_len, 2); ++ host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff); ++ osal_memcpy(&msg_local_buffer[0], &host_lte_btwf_coex_cmd[0], osal_sizeof(host_lte_btwf_coex_cmd)); ++ osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)], ++ &pTxBuf[osal_sizeof(msg_len)], msg_len - 1); ++ ++ wmt_lib_idc_lock_release(); ++ total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1; ++ ++ WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n", msg_len - 1, ++ total_len); ++ WMT_DBG_FUNC("wmt_core:idc msg payload:\n"); ++ ++ for (index = 0; index < total_len; index++) ++ WMT_DBG_FUNC("0x%02x ", msg_local_buffer[index]); ++ ++ ++ do { ++ fgFail = MTK_WCN_BOOL_TRUE; ++ ++ /* read A die chipid by wmt cmd */ ++ iRet = wmt_core_tx((PUINT8) &msg_local_buffer[0], total_len, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != total_len)) { ++ WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, osal_sizeof(host_lte_btwf_coex_evt), &u4Res); ++ if (iRet || (u4Res != osal_sizeof(host_lte_btwf_coex_evt))) { ++ WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d),size(%d)\n", iRet, u4Res); ++ break; ++ } ++ ++ fgFail = MTK_WCN_BOOL_FALSE; ++ ++ } while (0); ++ kfree(msg_local_buffer); ++ return fgFail; ++} ++#endif ++ ++VOID wmt_core_set_coredump_state(ENUM_DRV_STS state) ++{ ++ WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n", state); ++ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state; ++} ++#ifdef CONFIG_MTK_COMBO_ANT ++INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = 0; ++ size_t ctrlPa1 = pWmtOp->au4OpData[0]; ++ UINT32 ctrlPa2 = pWmtOp->au4OpData[1]; ++ PUINT8 pbuf = (PUINT8) ctrlPa1; ++ UINT32 fragSeq = 0; ++ UINT16 fragSize = 0; ++ UINT16 wmtCmdLen; ++ UINT16 wmtPktLen; ++ UINT32 u4Res = 0; ++ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_DWN_EVT)]; ++#if 1 ++ UINT32 ctrlPa3 = pWmtOp->au4OpData[2]; ++ ++ do { ++ fragSize = ctrlPa2; ++ fragSeq = ctrlPa3; ++ gAntBuf[5] = fragSeq; ++ ++ ++ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_DWN_CMD) + 1; ++ ++ /*WMT command length cal */ ++ wmtCmdLen = wmtPktLen - 4; ++#if 0 ++ WMT_ANT_RAM_DWN_CMD[2] = wmtCmdLen & 0xFF; ++ WMT_ANT_RAM_DWN_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; ++#else ++ osal_memcpy(&WMT_ANT_RAM_DWN_CMD[2], &wmtCmdLen, 2); ++#endif ++ ++ ++ ++ WMT_ANT_RAM_DWN_CMD[4] = 1; /*RAM CODE download */ ++ ++ osal_memcpy(gAntBuf, WMT_ANT_RAM_DWN_CMD, sizeof(WMT_ANT_RAM_DWN_CMD)); ++ ++ /*copy ram code content to global buffer */ ++ osal_memcpy(&gAntBuf[osal_sizeof(WMT_ANT_RAM_DWN_CMD) + 1], pbuf, fragSize); ++ ++ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != wmtPktLen)) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ wmtPktLen, u4Res, iRet); ++ iRet = -4; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, wmtPktLen, u4Res); ++ ++ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); ++ ++ WMT_ANT_RAM_DWN_EVT[4] = 0; /*download result; 0 */ ++ ++ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_DWN_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_DWN_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) fail(%d)\n", ++ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res, iRet); ++ iRet = -5; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_DWN_EVT, sizeof(WMT_ANT_RAM_DWN_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_DWN_EVT result error\n"); ++ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], ++ antEvtBuf[4], sizeof(WMT_ANT_RAM_DWN_EVT), WMT_ANT_RAM_DWN_EVT[0], ++ WMT_ANT_RAM_DWN_EVT[1], WMT_ANT_RAM_DWN_EVT[2], WMT_ANT_RAM_DWN_EVT[3], ++ WMT_ANT_RAM_DWN_EVT[4]); ++ iRet = -6; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) ok\n", ++ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res); ++ ++ } while (0); ++#else ++ UINT32 patchSize = ctrlPa2; ++ UINT32 patchSizePerFrag = 1000; ++ UINT32 offset; ++ UINT32 fragNum = 0; ++ /*cal patch fragNum */ ++ fragNum = (patchSize + patchSizePerFrag - 1) / patchSizePerFrag; ++ if (2 >= fragNum) { ++ WMT_WARN_FUNC("ANT ramcode size(%d) too short\n", patchSize); ++ return -1; ++ } ++ ++ while (fragSeq < fragNum) { ++ /*update fragNum */ ++ fragSeq++; ++ ++ if (1 == fragSeq) { ++ fragSize = patchSizePerFrag; ++ /*first package */ ++ gAntBuf[5] = 1; /*RAM CODE start */ ++ } else if (fragNum == fragSeq) { ++ /*last package */ ++ fragSize = patchSizePerFrag; ++ gAntBuf[5] = 3; /*RAM CODE end */ ++ } else { ++ /*middle package */ ++ fragSize = patchSize - ((fragNum - 1) * patchSizePerFrag); ++ gAntBuf[5] = 2; /*RAM CODE confinue */ ++ } ++ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_OP_CMD) + 1; ++ ++ /*WMT command length cal */ ++ wmtCmdLen = wmtPktLen - 4; ++ ++ WMT_ANT_RAM_OP_CMD[2] = wmtCmdLen & 0xFF; ++ WMT_ANT_RAM_OP_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; ++ ++ WMT_ANT_RAM_OP_CMD[4] = 1; /*RAM CODE download */ ++ ++ osal_memcpy(gAntBuf, WMT_ANT_RAM_OP_CMD, sizeof(WMT_ANT_RAM_OP_CMD)); ++ ++ /*copy ram code content to global buffer */ ++ osal_memcpy(&gAntBuf[6], pbuf, fragSize); ++ ++ /*update offset */ ++ offset += fragSize; ++ pbuf += offset; ++ ++ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != wmtPktLen)) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ wmtPktLen, u4Res, iRet); ++ iRet = -4; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, wmtPktLen, u4Res); ++ ++ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); ++ ++ WMT_SET_RAM_OP_EVT[4] = 0; /*download result; 0 */ ++ ++ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_SET_RAM_OP_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_SET_RAM_OP_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) fail(%d)\n", ++ sizeof(WMT_SET_RAM_OP_EVT), u4Res, iRet); ++ iRet = -5; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(antEvtBuf, WMT_SET_RAM_OP_EVT, sizeof(WMT_SET_RAM_OP_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_SET_RAM_OP_EVT result error\n"); ++ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], ++ antEvtBuf[4], sizeof(WMT_SET_RAM_OP_EVT), WMT_SET_RAM_OP_EVT[0], ++ WMT_SET_RAM_OP_EVT[1], WMT_SET_RAM_OP_EVT[2], WMT_SET_RAM_OP_EVT[3], ++ WMT_SET_RAM_OP_EVT[4]); ++ iRet = -6; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) ok\n", ++ sizeof(WMT_SET_RAM_OP_EVT), u4Res); ++ ++ ++ } ++ if (fragSeq != fragNum) ++ iRet = -7; ++#endif ++ return iRet; ++} ++ ++ ++INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp) ++{ ++ INT32 iRet = 0; ++ UINT32 u4Res = 0; ++ UINT32 wmtPktLen = osal_sizeof(WMT_ANT_RAM_STA_GET_CMD); ++ UINT32 u4AntRamStatus = 0; ++ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_STA_GET_EVT)]; ++ ++ ++ iRet = wmt_core_tx(WMT_ANT_RAM_STA_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != wmtPktLen)) { ++ WMT_ERR_FUNC ++ ("wmt_core: write wmt and ramcode status query command failed, (%d, %d), iRet(%d)\n", ++ wmtPktLen, u4Res, iRet); ++ iRet = -4; ++ return iRet; ++ } ++ ++ ++ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_STA_GET_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_STA_GET_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_STA_GET_EVT length(%zu, %d) fail(%d)\n", ++ sizeof(WMT_ANT_RAM_STA_GET_EVT), u4Res, iRet); ++ iRet = -5; ++ return iRet; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_STA_GET_EVT, sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1) != ++ 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_STA_GET_EVT result error\n"); ++ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], antEvtBuf[4], ++ sizeof(WMT_ANT_RAM_STA_GET_EVT), WMT_ANT_RAM_STA_GET_EVT[0], ++ WMT_ANT_RAM_STA_GET_EVT[1], WMT_ANT_RAM_STA_GET_EVT[2], ++ WMT_ANT_RAM_STA_GET_EVT[3], WMT_ANT_RAM_STA_GET_EVT[4]); ++ iRet = -6; ++ return iRet; ++ } ++#endif ++ if (0 == iRet) { ++ u4AntRamStatus = antEvtBuf[sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1]; ++ pWmtOp->au4OpData[2] = u4AntRamStatus; ++ WMT_INFO_FUNC("ANT ram code %s\n", ++ 1 == u4AntRamStatus ? "exist already" : "not exist"); ++ } ++ return iRet; ++} ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++/*TEST CODE*/ ++static UINT32 g_open_wmt_lte_flag; ++VOID wmt_core_set_flag_for_test(UINT32 enable) ++{ ++ WMT_INFO_FUNC("%s wmt_lte_flag\n", enable ? "enable" : "disable"); ++ g_open_wmt_lte_flag = enable; ++} ++ ++UINT32 wmt_core_get_flag_for_test(VOID) ++{ ++ return g_open_wmt_lte_flag; ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c +new file mode 100644 +index 000000000000..fa603c208e59 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c +@@ -0,0 +1,1019 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CTRL]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "osal.h" ++ ++#include "wmt_ctrl.h" ++#include "wmt_core.h" ++#include "wmt_ic.h" ++#include "wmt_lib.h" ++#include "wmt_dev.h" ++#include "wmt_plat.h" ++#include "stp_core.h" ++#include "stp_dbg.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* moved to wmt_ctrl.h */ ++/*static INT32 wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/ ++ ++static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value); ++ ++static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA); ++#if 0 ++static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA); ++#endif ++static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData); ++static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData); ++static INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData); ++static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA); ++static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData); ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA); ++#endif ++ ++static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA); ++ ++static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData); ++ ++static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData); ++ ++static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData); ++ ++/* TODO: [FixMe][GeorgeKuo]: remove unused function */ ++/*static INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* GeorgeKuo: Use designated initializers described in ++ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html ++ */ ++static const WMT_CTRL_FUNC wmt_ctrl_func[] = { ++ [WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off, ++ [WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on, ++ [WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst, ++ [WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close, ++ [WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open, ++ [WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf, ++ [WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch, ++ [WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch, ++ [WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name, ++ [WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set, ++ [WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst, ++ [WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf, ++ [WMT_CTRL_TX] = wmt_ctrl_tx, ++ [WMT_CTRL_RX] = wmt_ctrl_rx, ++ [WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush, ++ [WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set, ++ [WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set, ++ [WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search, ++ [WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get, ++ [WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put, ++ [WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show, ++ [WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num, ++ [WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info, ++ [WMT_CTRL_SOC_PALDO_CTRL] = wmt_ctrl_soc_paldo_ctrl, ++ [WMT_CTRL_SOC_WAKEUP_CONSYS] = wmt_ctrl_soc_wakeup_consys, ++ [WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info, ++ [WMT_CTRL_BGW_DESENSE_CTRL] = wmt_ctrl_bgw_desense_ctrl, ++ [WMT_CTRL_EVT_ERR_TRG_ASSERT] = wmt_ctrl_evt_err_trg_assert, ++#if CFG_WMT_LTE_COEX_HANDLING ++ [WMT_CTRL_GET_TDM_REQ_ANTSEL] = wmt_ctrl_get_tdm_req_antsel, ++#endif ++ [WMT_CTRL_EVT_PARSER] = wmt_ctrl_evt_parser, ++ [WMT_CTRL_MAX] = wmt_ctrl_others, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 ctrlId; ++ ++ if (NULL == pWmtCtrlData) { ++ osal_assert(0); ++ return -1; ++ } ++ ++ ctrlId = pWmtCtrlData->ctrlId; ++ /*1sanity check, including wmtCtrlId */ ++ if ((NULL == pWmtCtrlData) ++ || (WMT_CTRL_MAX <= ctrlId)) ++ /* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */ ++ { ++ osal_assert(NULL != pWmtCtrlData); ++ osal_assert(WMT_CTRL_MAX > ctrlId); ++ /* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */ ++ return -2; ++ } ++ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ ++ if (wmt_ctrl_func[ctrlId]) { ++ /*call servicd handling API */ ++ return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData); /* serviceHandlerPack[ctrlId].serviceHandler */ ++ } ++ osal_assert(NULL != wmt_ctrl_func[ctrlId]); ++ return -3; ++ ++} ++ ++INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */) ++{ ++ UINT8 *pData = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ UINT32 size = pWmtCtrlData->au4CtrlData[1]; ++ PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; ++ MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3]; ++ ++ return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); ++} ++ ++INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 readLen; ++ long waitRet = -1; ++ PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ UINT32 buffLen = pWmtCtrlData->au4CtrlData[1]; ++ PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; ++ ++ if (readSize) ++ *readSize = 0; ++ ++ /* sanity check */ ++ if (!buffLen) { ++ WMT_WARN_FUNC("buffLen = 0\n"); ++ osal_assert(buffLen); ++ return 0; ++ } ++#if 0 ++ if (!pDev) { ++ WMT_WARN_FUNC("gpDevWmt = NULL\n"); ++ osal_assert(pDev); ++ return -1; ++ } ++#endif ++ ++ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { ++ WMT_WARN_FUNC("state(0x%lx)\n", pDev->state); ++ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); ++ return -2; ++ } ++ ++ /* sanity ok, proceeding rx operation */ ++ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ ++ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); ++ ++ while (readLen == 0) { /* got nothing, wait for STP's signal */ ++ WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n"); ++ /* iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state)); */ ++ /* waitRet = wait_event_interruptible_timeout( ++ * pDev->rWmtRxWq, ++ * osal_test_bit(WMT_STAT_RX, &pdev->state), ++ * msecs_to_jiffies(WMT_LIB_RX_TIMEOUT)); ++ */ ++ pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT; ++ /* waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX); */ ++ waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq); ++ ++ WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n"); ++ ++ if (0 == waitRet) { ++ WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d)\n", ++ jiffies, pDev->rWmtRxWq.timeoutValue); ++ return -1; ++ } else if (waitRet < 0) { ++ WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet); ++ return waitRet; ++ } ++ WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet); ++ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ ++ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); ++ ++ if (0 == readLen) ++ WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet); ++ ++ } ++ ++ if (readSize) ++ *readSize = readLen; ++ ++ return 0; ++ ++} ++ ++INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet; ++ ++ if (NULL != writtenSize) ++ *writtenSize = 0; ++ ++ /* sanity check */ ++ if (0 == size) { ++ WMT_WARN_FUNC("size to tx is 0\n"); ++ osal_assert(size); ++ return -1; ++ } ++ ++ /* if STP is not enabled yet, can't use this function. Use tx_raw instead */ ++ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) || !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) { ++ WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state); ++ osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state)); ++ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); ++ return -2; ++ } ++ ++ /* sanity ok, proceeding tx operation */ ++ /*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */ ++ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); ++ if (bRawFlag) ++ iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX); ++ else ++ iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX); ++ ++ if (iRet != size) { ++ WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet); ++ osal_assert(iRet == size); ++ } ++ ++ if (writtenSize) ++ *writtenSize = iRet; ++ ++ return 0; ++ ++} ++ ++INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 type = pWmtCtrlData->au4CtrlData[0]; ++ ++ WMT_INFO_FUNC("flush rx %d queue\n", type); ++ mtk_wcn_stp_flush_rx_queue(type); ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iret; ++ ++/*psm should be disabled before wmt_ic_deinit*/ ++ P_DEV_WMT pDev = &gDevWmt; ++ ++ if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) { ++ WMT_DBG_FUNC("on->off\n"); ++ iret = wmt_plat_pwr_ctrl(FUNC_OFF); ++ } else { ++ WMT_WARN_FUNC("already off\n"); ++ iret = 0; ++ } ++ ++ return iret; ++} ++ ++INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iret; ++ /*psm should be enabled right after wmt_ic_init */ ++ P_DEV_WMT pDev = &gDevWmt; ++ if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) { ++ WMT_WARN_FUNC("already on\n"); ++ iret = 0; ++ } else { ++ WMT_DBG_FUNC("off->on\n"); ++ iret = wmt_plat_pwr_ctrl(FUNC_ON); ++ } ++ ++ return iret; ++} ++ ++INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const UINT8 *pCmdStr) ++{ ++ INT32 waitRet = -1; ++ P_OSAL_SIGNAL pCmdSignal; ++ P_OSAL_EVENT pCmdReq; ++ ++ if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) { ++ WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd); ++ return -1; ++ } ++ ++ /* indicate baud rate change to user space app */ ++#if 0 ++ INIT_COMPLETION(pWmtDev->cmd_comp); ++ pWmtDev->cmd_result = -1; ++ strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); ++ pWmtDev->cCmd[NAME_MAX] = '\0'; ++ wake_up_interruptible(&pWmtDev->cmd_wq); ++#endif ++ ++ pCmdSignal = &pWmtDev->cmdResp; ++ osal_signal_init(pCmdSignal); ++ pCmdSignal->timeoutValue = 2000; ++ osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); ++ pWmtDev->cCmd[NAME_MAX] = '\0'; ++ ++ pCmdReq = &pWmtDev->cmdReq; ++ ++ osal_trigger_event(&pWmtDev->cmdReq); ++ WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr); ++ ++/* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */ ++ waitRet = osal_wait_for_signal_timeout(pCmdSignal); ++ WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet); ++ if (0 == waitRet) { ++ WMT_ERR_FUNC("wait signal timeout\n"); ++ return -2; ++ } ++ ++ WMT_DBG_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult); ++ ++ return pWmtDev->cmdResult; ++} ++ ++INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ wmt_plat_pwr_ctrl(FUNC_RST); ++ return 0; ++} ++ ++INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ wmt_plat_pwr_ctrl(FUNC_STAT); ++ return 0; ++} ++ ++INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet = 0; ++ /* un-register to STP-core for rx */ ++ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL); /* mtk_wcn_stp_register_event_cb */ ++ if (iRet) { ++ WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ /*un-register rxcb to btif */ ++ iRet = mtk_wcn_stp_rxcb_register(NULL); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_unregister fail(%d)\n", iRet); ++ return -2; ++ } ++ ++ iRet = mtk_wcn_stp_close_btif(); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_close_btif fail(%d)\n", iRet); ++ return -3; ++ } ++ osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state); ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet; ++ ++ iRet = mtk_wcn_stp_open_btif(); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_open_btif fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ /*register stp rx call back to btif */ ++ iRet = mtk_wcn_stp_rxcb_register((MTK_WCN_BTIF_RX_CB) mtk_wcn_stp_parser_data); ++ if (iRet) { ++ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_register fail(%d)\n", iRet); ++ return -2; ++ } ++ /* register to STP-core for rx */ ++ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb); ++ if (iRet) { ++ WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet); ++ return -3; ++ } ++ ++ osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state); ++ ++#if 0 ++ iRet = mtk_wcn_stp_lpbk_ctrl(1); ++#endif ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ INT32 iRet; ++ UINT8 cmdStr[NAME_MAX + 1] = { 0 }; ++ ++ osal_snprintf(cmdStr, NAME_MAX, "srh_patch"); ++ iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); ++ if (iRet) { ++ WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); ++ return -1; ++ } ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ pWmtCtrlData->au4CtrlData[0] = pDev->patchNum; ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ UINT32 downLoadSeq = 0; ++ P_WMT_PATCH_INFO pPatchinfo = NULL; ++ PUINT8 pNbuf = NULL; ++ PUINT8 pAbuf = NULL; ++ ++ downLoadSeq = pWmtCtrlData->au4CtrlData[0]; ++ WMT_DBG_FUNC("download seq is %d\n", downLoadSeq); ++ ++ pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1; ++ pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1]; ++ pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2]; ++ if (pPatchinfo) { ++ osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName)); ++ osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess)); ++ WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1], pAbuf[2], pAbuf[3]); ++ } else { ++ WMT_ERR_FUNC("NULL patchinfo pointer\n"); ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0; ++ ENUM_PALDO_TYPE ept = pWmtCtrlData->au4CtrlData[0]; ++ ENUM_PALDO_OP epo = pWmtCtrlData->au4CtrlData[1]; ++ ++ WMT_DBG_FUNC("ept(%d),epo(%d)\n", ept, epo); ++ iRet = wmt_plat_soc_paldo_ctrl(ept, epo); ++ if (iRet) { ++ if (PMIC_CHIPID_PALDO == ept) { ++ /* special handling for PMIC CHIPID */ ++ pWmtCtrlData->au4CtrlData[2] = iRet; ++ } else { ++ /* for other PA handling */ ++ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0; ++ ++ iRet = mtk_wcn_stp_wakeup_consys(); ++ if (iRet) ++ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value) ++{ ++ INT32 iRet = -1; ++ ++ switch (type) { ++ case WMT_STP_CONF_EN: ++ iRet = mtk_wcn_stp_enable(value); ++ break; ++ ++ case WMT_STP_CONF_RDY: ++ iRet = mtk_wcn_stp_ready(value); ++ break; ++ ++ case WMT_STP_CONF_MODE: ++ mtk_wcn_stp_set_mode(value); ++ iRet = 0; ++ break; ++ ++ default: ++ WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value); ++ break; ++ } ++ return iRet; ++} ++ ++INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ UINT32 type; ++ UINT32 value; ++ ++ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { ++ WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n"); ++ return -1; ++ } ++ ++ type = pWmtCtrlData->au4CtrlData[0]; ++ value = pWmtCtrlData->au4CtrlData[1]; ++ iRet = wmt_ctrl_stp_conf_ex(type, value); ++ ++ if (!iRet) { ++ if (WMT_STP_CONF_EN == type) { ++ if (value) { ++ osal_set_bit(WMT_STAT_STP_EN, &pDev->state); ++ WMT_DBG_FUNC("enable STP\n"); ++ } else { ++ osal_clear_bit(WMT_STAT_STP_EN, &pDev->state); ++ WMT_DBG_FUNC("disable STP\n"); ++ } ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0]; ++ ++ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); ++ if (NULL != gDevWmt.pPatch) ++ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch)); ++ ++ WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); ++ if (patchSeq == gDevWmt.patchNum) { ++ WMT_DBG_FUNC("the %d patch has been download\n", patchSeq); ++ wmt_dev_patch_info_free(); ++ } ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ ++ osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName)); ++ return 0; ++} ++ ++INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); ++ if (NULL != gDevWmt.pNvram) ++ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram)); ++ ++ WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(0x%08x)\n", gDevWmt.pNvram); ++ return 0; ++} ++ ++INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0x0; ++ PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1]; ++ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; ++ ++ osal_firmware *pNvram = NULL; ++ ++ if ((NULL == pFileName) || (NULL == pSize)) { ++ WMT_ERR_FUNC("parameter error, pFileName(0x%08x), pSize(0x%08x)\n", pFileName, pSize); ++ iRet = -1; ++ return iRet; ++ } ++ if (0 == wmt_dev_patch_get(pFileName, &pNvram, 0)) { ++ *ppBuf = (PUINT8) (pNvram)->data; ++ *pSize = (pNvram)->size; ++ gDevWmt.pNvram = pNvram; ++ return 0; ++ } ++ return -1; ++ ++} ++ ++INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT8 *pFullPatchName = NULL; ++ UINT8 *pDefPatchName = NULL; ++ PUINT8 *ppBuf = (PUINT8 *) pWmtCtrlData->au4CtrlData[2]; ++ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3]; ++ ++ osal_firmware *pPatch = NULL; ++ ++ pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1]; ++ WMT_DBG_FUNC("BF get patch, pPatch(0x%08x)\n", pPatch); ++ if ((NULL != pFullPatchName) ++ && (0 == wmt_dev_patch_get(pFullPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { ++ /*get full name patch success */ ++ WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%d)\n", ++ pFullPatchName, (pPatch)->data, (pPatch)->size); ++ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); ++ *ppBuf = (PUINT8) (pPatch)->data; ++ *pSize = (pPatch)->size; ++ gDevWmt.pPatch = pPatch; ++ return 0; ++ } ++ ++ pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; ++ if ((NULL != pDefPatchName) ++ && (0 == wmt_dev_patch_get(pDefPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { ++ WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%d)\n", ++ pDefPatchName, (pPatch)->data, (pPatch)->size); ++ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); ++ /*get full name patch success */ ++ *ppBuf = (PUINT8) (pPatch)->data; ++ *pSize = (pPatch)->size; ++ gDevWmt.pPatch = pPatch; ++ return 0; ++ } ++ return -1; ++ ++} ++ ++/*do not need contol uart because B/G/F send/receive data by BTIF*/ ++#if 0 ++INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ char cmdStr[NAME_MAX + 1] = { 0 }; ++ UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0]; ++ UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1]; ++ ++ WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl); ++ ++ if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) { ++ osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl); ++ iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr); ++ if (iRet) { ++ WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) fail(%d)\n", ++ u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet); ++ } else { ++ WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n", u4Baudrate, u4FlowCtrl); ++ } ++ } else { ++ WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n"); ++ } ++ return iRet; ++} ++#endif ++/*do not need control SDIO because wifi send/receive data by sdio*/ ++#if 0 ++INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = 0; ++ UINT32 statBit = WMT_STAT_SDIO1_ON; ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0]; ++ ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1]; ++ ++ if ((WMT_SDIO_SLOT_INVALID == sdioSlotNum) ++ || (WMT_SDIO_SLOT_MAX <= sdioSlotNum)) { ++ WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum); ++ return -1; ++ } ++ ++ WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState); ++ ++ if (WMT_SDIO_SLOT_SDIO2 == sdioSlotNum) ++ statBit = WMT_STAT_SDIO2_ON; ++ ++ if (funcState) { ++ if (osal_test_and_set_bit(statBit, &pDev->state)) { ++ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum); ++ /* still return 0 */ ++ iRet = 0; ++ } else { ++ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON); ++ } ++ } else { ++ if (osal_test_and_clear_bit(statBit, &pDev->state)) { ++ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF); ++ } else { ++ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum); ++ /* still return 0 */ ++ iRet = 0; ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ UINT32 statBit = WMT_STAT_SDIO_WIFI_ON; ++ INT32 retry = 10; ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0]; ++ UINT32 u4On = pWmtCtrlData->au4CtrlData[1]; ++ ++ if (WMT_SDIO_FUNC_MAX <= sdioFuncType) { ++ WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType); ++ return -1; ++ } ++ ++ if (WMT_SDIO_FUNC_STP == sdioFuncType) ++ statBit = WMT_STAT_SDIO_STP_ON; ++ ++ if (u4On) { ++ if (osal_test_bit(statBit, &pDev->state)) { ++ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType); ++ iRet = 0; ++ } else { ++ while (retry-- > 0 && iRet != 0) { ++ if (iRet) { ++ /* sleep 150ms before sdio slot ON ready */ ++ osal_sleep_ms(150); ++ } ++ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE); ++ if (HIF_SDIO_ERR_NOT_PROBED == iRet) { ++ /* not probed case, retry */ ++ continue; ++ } else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet) { ++ /* For WiFi, client not reg yet, no need to retry, ++ *WiFi function can work any time when wlan.ko ++ *is insert into system ++ */ ++ iRet = 0; ++ } else { ++ /* other fail cases, stop */ ++ break; ++ } ++ } ++ if (!retry || iRet) { ++ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n", ++ sdioFuncType, iRet, retry); ++ } else { ++ osal_set_bit(statBit, &pDev->state); ++ } ++ } ++ } else { ++ if (osal_test_bit(statBit, &pDev->state)) { ++ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE); ++ if (iRet) ++ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", sdioFuncType, iRet); ++ /*any way, set to OFF state */ ++ osal_clear_bit(statBit, &pDev->state); ++ } else { ++ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType); ++ iRet = 0; ++ } ++ } ++ ++ return iRet; ++} ++#endif ++ ++ ++INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ /* input sanity check is done in wmt_ctrl() */ ++ pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16; ++ pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF; ++ pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF; ++ ++ /* TODO: [FixMe][GeorgeKuo] remove translated ENUM_WMTHWVER_TYPE_T in the future!!! */ ++ /* Only use hw_ver read from hw. */ ++ pDev->eWmtHwVer = (ENUM_WMTHWVER_TYPE_T) (pWmtCtrlData->au4CtrlData[1] & 0xFFFF0000) >> 16; ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT8 *pRomVer = NULL; ++ P_WMT_PATCH pPatch = NULL; ++ UINT32 chipID = 0; ++ ++ chipID = pWmtCtrlData->au4CtrlData[0]; ++ pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]); ++ pPatch = (P_WMT_PATCH) (pWmtCtrlData->au4CtrlData[2]); ++ if (!pRomVer) { ++ WMT_ERR_FUNC("pRomVer null pointer\n"); ++ return -1; ++ } ++ if (!pPatch) { ++ WMT_ERR_FUNC("pPatch null pointer\n"); ++ return -2; ++ } ++ WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer, pPatch->ucDateTime, ++ pPatch->ucPLat); ++ return stp_dbg_set_version_info(chipID, pRomVer, &(pPatch->ucDateTime[0]), &(pPatch->ucPLat[0])); ++} ++ ++static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ UINT32 cmd = pWmtCtrlData->au4CtrlData[0]; ++ ++ WMT_INFO_FUNC("wmt-ctrl:send native cmd(%d)\n", cmd); ++ wmt_dev_send_cmd_to_daemon(cmd); ++ ++ return 0; ++} ++ ++static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 iRet = -1; ++ ++ ENUM_WMTDRV_TYPE_T drv_type; ++ UINT32 reason = 0; ++ ++ drv_type = pWmtCtrlData->au4CtrlData[0]; ++ reason = pWmtCtrlData->au4CtrlData[1]; ++ WMT_WARN_FUNC("wmt-ctrl:drv_type(%d),reason(%d)\n", drv_type, reason); ++ ++ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); ++ wmt_lib_set_host_assert_info(drv_type, reason, 1); ++ ++ iRet = mtk_wcn_stp_wmt_evt_err_trg_assert(); ++ if (iRet) ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++ } else { ++ /* maybe assert triggered by stp noack*/ ++ WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n"); ++ } ++ return 0; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 antsel_index = wmt_plat_get_tdm_antsel_index(); ++ ++ if (0 <= antsel_index) ++ pWmtCtrlData->au4CtrlData[0] = antsel_index; ++ else ++ pWmtCtrlData->au4CtrlData[0] = 0xff; ++ ++ WMT_INFO_FUNC("get tdm req antsel index is %d\n", antsel_index); ++ ++ return 0; ++} ++#endif ++ ++static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ INT32 ret = -1; ++ UINT32 evt_idx = (UINT32) pWmtCtrlData->au4CtrlData[0]; ++ UINT8 *p_buf = NULL; ++ ++ static UINT8 sleep_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; ++ static UINT8 wakeup_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; ++ static UINT8 hostawake_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; ++ static UINT8 *evt_array[] = { sleep_evt, wakeup_evt, hostawake_evt }; ++ ++ p_buf = evt_array[evt_idx - 1]; ++ ++ WMT_INFO_FUNC("evt index:%d,p_buf:%p\n", evt_idx, p_buf); ++ ++ ret = mtk_wcn_consys_stp_btif_parser_wmt_evt(p_buf, 6); ++ if (ret == 1) { ++ WMT_INFO_FUNC("parser wmt evt from BTIF buf is OK\n"); ++ return 0; ++ } ++ WMT_ERR_FUNC("parser wmt evt from BTIF buf fail(%d)\n", ret); ++ return -1; ++} ++ ++static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData) ++{ ++ INT32 iret; ++ ++ WMT_INFO_FUNC("ctrl GPS_SYNC(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); ++ iret = wmt_plat_gpio_ctrl(PIN_GPS_SYNC, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); ++ ++ if (iret) { ++ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", ++ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX, iret); ++ } ++ ++ return 0; ++} ++ ++static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData) ++{ ++ INT32 iret; ++ ++ WMT_INFO_FUNC("ctrl GPS_LNA(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); ++ iret = wmt_plat_gpio_ctrl(PIN_GPS_LNA, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); ++ ++ if (iret) { ++ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", ++ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret); ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ return 0; ++} ++ ++INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ P_DEV_WMT pDev = &gDevWmt; /* single instance */ ++ ++ pWmtCtrlData->au4CtrlData[0] = (SIZE_T) &pDev->rWmtGenConf; ++ ++ return 0; ++} ++ ++INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData) ++{ ++ WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId); ++ return -1; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c +new file mode 100644 +index 000000000000..d42d572c9292 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c +@@ -0,0 +1,713 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-FUNC]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include "wmt_func.h" ++#include "wmt_lib.h" ++#include "wmt_core.h" ++#include "wmt_exp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if CFG_FUNC_BT_SUPPORT ++ ++static INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_bt_ops = { ++ /* BT subsystem function on/off */ ++ .func_on = wmt_func_bt_on, ++ .func_off = wmt_func_bt_off ++}; ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++ ++static INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_fm_ops = { ++ /* FM subsystem function on/off */ ++ .func_on = wmt_func_fm_on, ++ .func_off = wmt_func_fm_off ++}; ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++ ++static INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_gps_ops = { ++ /* GPS subsystem function on/off */ ++ .func_on = wmt_func_gps_on, ++ .func_off = wmt_func_gps_off ++}; ++ ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++static INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++static INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); ++ ++WMT_FUNC_OPS wmt_func_wifi_ops = { ++ /* Wi-Fi subsystem function on/off */ ++ .func_on = wmt_func_wifi_on, ++ .func_off = wmt_func_wifi_off ++}; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if CFG_FUNC_GPS_SUPPORT ++CMB_PIN_CTRL_REG eediPinOhRegs[] = { ++ { ++ /* pull down ctrl register */ ++ .regAddr = 0x80050020, ++ .regValue = ~(0x1 << 5), ++ .regMask = 0x00000020, ++ }, ++ { ++ /* pull up ctrl register */ ++ .regAddr = 0x80050000, ++ .regValue = 0x1 << 5, ++ .regMask = 0x00000020, ++ }, ++ { ++ /* iomode ctrl register */ ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 0, ++ .regMask = 0x00000007, ++ }, ++ { ++ /* output high/low ctrl register */ ++ .regAddr = 0x80050040, ++ .regValue = 0x1 << 5, ++ .regMask = 0x00000020, ++ } ++ ++}; ++ ++CMB_PIN_CTRL_REG eediPinOlRegs[] = { ++ { ++ .regAddr = 0x80050020, ++ .regValue = 0x1 << 5, ++ .regMask = 0x00000020UL, ++ }, ++ { ++ .regAddr = 0x80050000, ++ .regValue = ~(0x1 << 5), ++ .regMask = 0x00000020, ++ }, ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 0, ++ .regMask = 0x00000007, ++ }, ++ { ++ .regAddr = 0x80050040, ++ .regValue = ~(0x1 << 5), ++ .regMask = 0x00000020, ++ } ++}; ++ ++CMB_PIN_CTRL_REG eedoPinOhRegs[] = { ++ { ++ .regAddr = 0x80050020, ++ .regValue = ~(0x1 << 7), ++ .regMask = 0x00000080UL, ++ }, ++ { ++ .regAddr = 0x80050000, ++ .regValue = 0x1 << 7, ++ .regMask = 0x00000080UL, ++ }, ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 12, ++ .regMask = 0x00007000UL, ++ }, ++ { ++ .regAddr = 0x80050040, ++ .regValue = 0x1 << 7, ++ .regMask = 0x00000080, ++ } ++}; ++ ++CMB_PIN_CTRL_REG eedoPinOlRegs[] = { ++ { ++ .regAddr = 0x80050020, ++ .regValue = 0x1 << 7, ++ .regMask = 0x00000080, ++ }, ++ { ++ .regAddr = 0x80050000, ++ .regValue = ~(0x1 << 7), ++ .regMask = 0x00000080, ++ }, ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x1 << 12, ++ .regMask = 0x00007000, ++ }, ++ { ++ .regAddr = 0x80050040, ++ .regValue = ~(0x1 << 7), ++ .regMask = 0x00000080, ++ } ++ ++}; ++ ++CMB_PIN_CTRL_REG gsyncPinOnRegs[] = { ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x3 << 20, ++ .regMask = 0x7 << 20, ++ } ++ ++}; ++ ++CMB_PIN_CTRL_REG gsyncPinOffRegs[] = { ++ { ++ .regAddr = 0x80050110, ++ .regValue = 0x0 << 20, ++ .regMask = 0x7 << 20, ++ } ++}; ++ ++/* templete usage for GPIO control */ ++CMB_PIN_CTRL gCmbPinCtrl[3] = { ++ { ++ .pinId = CMB_PIN_EEDI_ID, ++ .regNum = 4, ++ .pFuncOnArray = eediPinOhRegs, ++ .pFuncOffArray = eediPinOlRegs, ++ }, ++ { ++ .pinId = CMB_PIN_EEDO_ID, ++ .regNum = 4, ++ .pFuncOnArray = eedoPinOhRegs, ++ .pFuncOffArray = eedoPinOlRegs, ++ }, ++ { ++ .pinId = CMB_PIN_GSYNC_ID, ++ .regNum = 1, ++ .pFuncOnArray = gsyncPinOnRegs, ++ .pFuncOffArray = gsyncPinOffRegs, ++ } ++}; ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#if CFG_FUNC_BT_SUPPORT ++ ++INT32 _osal_inline_ wmt_func_bt_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ /*only need to send turn BT subsystem wmt command */ ++ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++} ++ ++INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_bt_ctrl(FUNC_ON); */ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_ON; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); ++ return -1; ++ } ++ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_on) failed(%d)\n", iRet); ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ++ /*do coredump when bt on fail */ ++ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); ++ ctrlPa1 = WMTDRV_TYPE_BT; ++ ctrlPa2 = 32; ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); ++ return -2; ++ } ++ osal_set_bit(WMT_BT_ON, &gBtWifiGpsState); ++ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { ++ /* send msg to GPS native for sending de-sense CMD */ ++ ctrlPa1 = 1; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ return 0; ++} ++ ++INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_bt_ctrl(FUNC_OFF); */ ++ INT32 iRet1 = -1; ++ INT32 iRet2 = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ iRet1 = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE); ++ if (iRet1) ++ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_off) failed(%d)\n", iRet1); ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet2 = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ if (iRet2) ++ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl(bt_off) failed(%d)\n", iRet2); ++ ++ if (iRet1 + iRet2) { ++ /*do coredump when bt off fail */ ++ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); ++ ctrlPa1 = WMTDRV_TYPE_BT; ++ ctrlPa2 = 32; ++ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); ++ return -1; ++ } ++ ++ osal_clear_bit(WMT_BT_ON, &gBtWifiGpsState); ++ if ((!osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for stopping send de-sense CMD */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ return 0; ++} ++ ++#endif ++ ++#if CFG_FUNC_GPS_SUPPORT ++ ++INT32 _osal_inline_ wmt_func_gps_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ /*send turn GPS subsystem wmt command */ ++ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_GPS, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++} ++ ++INT32 wmt_func_gps_pre_ctrl(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf, ENUM_FUNC_STATE funcStatus) ++{ ++ UINT32 i = 0; ++ INT32 iRet = 0; ++ UINT32 regAddr = 0; ++ UINT32 regValue = 0; ++ UINT32 regMask = 0; ++ UINT32 regNum = 0; ++ P_CMB_PIN_CTRL_REG pReg; ++ P_CMB_PIN_CTRL pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; ++ WMT_CTRL_DATA ctrlData; ++ WMT_IC_PIN_ID wmtIcPinId = WMT_IC_PIN_MAX; ++ /* sanity check */ ++ if (FUNC_ON != funcStatus && FUNC_OFF != funcStatus) { ++ WMT_ERR_FUNC("invalid funcStatus(%d)\n", funcStatus); ++ return -1; ++ } ++ /* turn on GPS sync function on both side */ ++ ctrlData.ctrlId = WMT_CTRL_GPS_SYNC_SET; ++ ctrlData.au4CtrlData[0] = (FUNC_ON == funcStatus) ? 1 : 0; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /*we suppose this would never print */ ++ WMT_ERR_FUNC("ctrl GPS_SYNC_SET(%d) fail, ret(%d)\n", funcStatus, iRet); ++ /* TODO:[FixMe][George] error handling? */ ++ return -2; ++ } ++ WMT_INFO_FUNC("ctrl GPS_SYNC_SET(%d) ok\n", funcStatus); ++ ++ ++ if ((NULL == pOps->ic_pin_ctrl) || ++ (0 > pOps->ic_pin_ctrl( ++ WMT_IC_PIN_GSYNC, ++ FUNC_ON == funcStatus ? WMT_IC_PIN_MUX : WMT_IC_PIN_GPIO, ++ 1))) { /*WMT_IC_PIN_GSYNC */ ++ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; ++ regNum = pCmbPinCtrl->regNum; ++ for (i = 0; i < regNum; i++) { ++ if (FUNC_ON == funcStatus) ++ pReg = &pCmbPinCtrl->pFuncOnArray[i]; ++ else ++ pReg = &pCmbPinCtrl->pFuncOffArray[i]; ++ ++ regAddr = pReg->regAddr; ++ regValue = pReg->regValue; ++ regMask = pReg->regMask; ++ ++ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); ++ if (iRet) { ++ WMT_ERR_FUNC("set reg for GPS_SYNC function fail(%d)\n", iRet); ++ /* TODO:[FixMe][Chaozhong] error handling? */ ++ return -2; ++ } ++ ++ } ++ } else { ++ WMT_INFO_FUNC("set reg for GPS_SYNC function okay by chip ic_pin_ctrl\n"); ++ } ++ WMT_INFO_FUNC("ctrl combo chip gps sync function succeed\n"); ++ /* turn on GPS lna ctrl function */ ++ if (NULL != pConf) { ++ if (0 == pConf->wmt_gps_lna_enable) { ++ ++ WMT_INFO_FUNC("host pin used for gps lna\n"); ++ /* host LNA ctrl pin needed */ ++ ctrlData.ctrlId = WMT_CTRL_GPS_LNA_SET; ++ ctrlData.au4CtrlData[0] = FUNC_ON == funcStatus ? 1 : 0; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ /*we suppose this would never print */ ++ WMT_ERR_FUNC("ctrl host GPS_LNA output high fail, ret(%d)\n", iRet); ++ /* TODO:[FixMe][Chaozhong] error handling? */ ++ return -3; ++ } ++ WMT_INFO_FUNC("ctrl host gps lna function succeed\n"); ++ } else { ++ WMT_INFO_FUNC("combo chip pin(%s) used for gps lna\n", ++ 0 == pConf->wmt_gps_lna_pin ? "EEDI" : "EEDO"); ++ wmtIcPinId = 0 == pConf->wmt_gps_lna_pin ? WMT_IC_PIN_EEDI : WMT_IC_PIN_EEDO; ++ if ((NULL == pOps->ic_pin_ctrl) || ++ (0 > pOps->ic_pin_ctrl( ++ wmtIcPinId, ++ FUNC_ON == funcStatus ? WMT_IC_PIN_GPIO_HIGH : WMT_IC_PIN_GPIO_LOW, ++ 1))) { /*WMT_IC_PIN_GSYNC */ ++ if (0 == pConf->wmt_gps_lna_pin) { ++ /* EEDI needed */ ++ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDI_ID]; ++ } else if (1 == pConf->wmt_gps_lna_pin) { ++ /* EEDO needed */ ++ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDO_ID]; ++ } ++ regNum = pCmbPinCtrl->regNum; ++ for (i = 0; i < regNum; i++) { ++ if (FUNC_ON == funcStatus) ++ pReg = &pCmbPinCtrl->pFuncOnArray[i]; ++ else ++ pReg = &pCmbPinCtrl->pFuncOffArray[i]; ++ regAddr = pReg->regAddr; ++ regValue = pReg->regValue; ++ regMask = pReg->regMask; ++ ++ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); ++ if (iRet) { ++ WMT_ERR_FUNC("set reg for GPS_LNA function fail(%d)\n", iRet); ++ /* TODO:[FixMe][Chaozhong] error handling? */ ++ return -3; ++ } ++ } ++ WMT_INFO_FUNC("ctrl combo chip gps lna succeed\n"); ++ } else { ++ WMT_INFO_FUNC("set reg for GPS_LNA function okay by chip ic_pin_ctrl\n"); ++ } ++ } ++ } ++ return 0; ++ ++} ++ ++INT32 wmt_func_gps_pre_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_ON); ++} ++ ++INT32 wmt_func_gps_pre_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ ++ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_OFF); ++} ++ ++INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ ++ if (!osal_test_bit(WMT_FM_ON, &gGpsFmState)) { ++ ctrlPa1 = GPS_PALDO; ++ ctrlPa2 = PALDO_ON; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else { ++ WMT_INFO_FUNC("LDO VCN28 has been turn on by FM\n"); ++ } ++ } ++ ++ iRet = wmt_func_gps_pre_on(pOps, pConf); ++ if (0 == iRet) { ++ iRet = wmt_func_gps_ctrl(FUNC_ON); ++ if (!iRet) { ++ osal_set_bit(WMT_GPS_ON, &gBtWifiGpsState); ++ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) ++ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for sending de-sense CMD */ ++ ctrlPa1 = 1; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ ++ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) /* use SOC external LNA */ ++ osal_set_bit(WMT_GPS_ON, &gGpsFmState); ++ } ++ } ++ return iRet; ++} ++ ++INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ iRet = wmt_func_gps_pre_off(pOps, pConf); ++ if (0 == iRet) { ++ iRet = wmt_func_gps_ctrl(FUNC_OFF); ++ if (!iRet) { ++ osal_clear_bit(WMT_GPS_ON, &gBtWifiGpsState); ++ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) ++ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for stop sending de-sense CMD */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ } ++ } ++ ++ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ ++ if (osal_test_bit(WMT_FM_ON, &gGpsFmState)) ++ WMT_INFO_FUNC("FM is still on, do not turn off LDO VCN28\n"); ++ else { ++ ctrlPa1 = GPS_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ ++ osal_clear_bit(WMT_GPS_ON, &gGpsFmState); ++ } ++ ++ return iRet; ++ ++} ++#endif ++ ++#if CFG_FUNC_FM_SUPPORT ++ ++INT32 _osal_inline_ wmt_func_fm_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ /*only need to send turn FM subsystem wmt command */ ++ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++} ++ ++INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_fm_ctrl(FUNC_ON); */ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ INT32 iRet = -1; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ if (co_clock_type) { ++ if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { ++ ctrlPa1 = FM_PALDO; ++ ctrlPa2 = PALDO_ON; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else { ++ WMT_INFO_FUNC("LDO VCN28 has been turn on by GPS\n"); ++ } ++ } ++ ++ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE); ++ if (!iRet) { ++ if (co_clock_type) ++ osal_set_bit(WMT_FM_ON, &gGpsFmState); ++ } ++ ++ return iRet; ++} ++ ++INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ /* return wmt_func_fm_ctrl(FUNC_OFF); */ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ INT32 iRet = -1; ++ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); ++ ++ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE); ++ ++ if (co_clock_type) { ++ if (osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { ++ WMT_INFO_FUNC("GPS is still on, do not turn off LDO VCN28\n"); ++ } else { ++ ctrlPa1 = FM_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ ++ osal_clear_bit(WMT_FM_ON, &gGpsFmState); ++ } ++ ++ return iRet; ++} ++ ++#endif ++ ++#if CFG_FUNC_WIFI_SUPPORT ++ ++/*in soc, wmt turn on wifi directly, no not need operate SDIO*/ ++#if 0 ++INT32 wmt_func_wifi_ctrl(ENUM_FUNC_STATE funcState) ++{ ++ INT32 iRet = 0; ++ unsigned long ctrlPa1 = WMT_SDIO_FUNC_WIFI; ++ unsigned long ctrlPa2 = (FUNC_ON == funcState) ? 1 : 0; /* turn on Wi-Fi driver */ ++ ++ iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-FUNC: turn on WIFI function fail (%d)", iRet); ++ return -1; ++ } ++ return 0; ++} ++#endif ++ ++INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ int iRet = 0; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ if (NULL != mtk_wcn_wlan_probe) { ++ ++ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan probe\n"); ++ iRet = (*mtk_wcn_wlan_probe) (); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan probe fail(%d)\n", iRet); ++ iRet = -1; ++ } else { ++ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan probe ok\n"); ++ } ++ } else { ++ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_probe\n"); ++ gWifiProbed = 1; ++ iRet = -2; ++ } ++ ++ if (!iRet) { ++ osal_set_bit(WMT_WIFI_ON, &gBtWifiGpsState); ++ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { ++ /* send msg to GPS native for sending de-sense CMD */ ++ ctrlPa1 = 1; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ } ++ return iRet; ++#if 0 ++ return wmt_func_wifi_ctrl(FUNC_ON); ++#endif ++} ++ ++INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) ++{ ++ int iRet = 0; ++ ++ unsigned long ctrlPa1 = 0; ++ unsigned long ctrlPa2 = 0; ++ ++ if (NULL != mtk_wcn_wlan_remove) { ++ ++ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan remove\n"); ++ iRet = (*mtk_wcn_wlan_remove) (); ++ if (iRet) { ++ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan remove fail(%d)\n", iRet); ++ iRet = -1; ++ } else { ++ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan remove ok\n"); ++ } ++ } else { ++ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_remove\n"); ++ iRet = -2; ++ } ++ ++ if (!iRet) { ++ osal_clear_bit(WMT_WIFI_ON, &gBtWifiGpsState); ++ if ((!osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { ++ /* send msg to GPS native for stopping send de-sense CMD */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); ++ } ++ } ++ return iRet; ++#if 0 ++ return wmt_func_wifi_ctrl(FUNC_OFF); ++#endif ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c +new file mode 100644 +index 000000000000..c07052bce8e6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c +@@ -0,0 +1,2452 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-IC]" ++#define CFG_IC_SOC 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "wmt_ic.h" ++#include "wmt_core.h" ++#include "wmt_lib.h" ++#include "stp_core.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define DEFAULT_PATCH_FRAG_SIZE (1000) ++#define WMT_PATCH_FRAG_1ST (0x1) ++#define WMT_PATCH_FRAG_MID (0x2) ++#define WMT_PATCH_FRAG_LAST (0x3) ++ ++#define CFG_CHECK_WMT_RESULT (1) ++/* BT Port 2 Feature. this command does not need ++ * after coex command is downconfirmed by LC, ++ */ ++#define CFG_WMT_BT_PORT2 (0) ++ ++#define CFG_SET_OPT_REG (0) ++#define CFG_WMT_I2S_DBGUART_SUPPORT (0) ++#define CFG_SET_OPT_REG_SWLA (0) ++#define CFG_SET_OPT_REG_MCUCLK (0) ++#define CFG_SET_OPT_REG_MCUIRQ (0) ++ ++#define CFG_SUBSYS_COEX_NEED 0 ++ ++#define CFG_WMT_COREDUMP_ENABLE 0 ++ ++#define CFG_WMT_MULTI_PATCH (1) ++ ++#define CFG_WMT_CRYSTAL_TIMING_SET (0) ++ ++#define CFG_WMT_SDIO_DRIVING_SET (0) ++ ++#define CFG_WMT_UART_HIF_USE (0) ++ ++#define CFG_WMT_WIFI_5G_SUPPORT (1) ++ ++#define CFG_WMT_PATCH_DL_OPTM (1) ++#if CFG_WMT_LTE_COEX_HANDLING ++#define CFG_WMT_FILTER_MODE_SETTING (1) ++#else ++#define CFG_WMT_FILTER_MODE_SETTING (0) ++#endif ++#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT (0) ++ ++#define CFG_WMT_POWER_ON_DLM (1) ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static UINT8 gFullPatchName[NAME_MAX + 1]; ++static const WMT_IC_INFO_S *gp_soc_info; ++static WMT_PATCH gp_soc_patch_info; ++static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; ++#if 0 ++static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; ++static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; ++ ++static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; ++static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; ++#endif ++ ++#if CFG_WMT_UART_HIF_USE ++static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; ++static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; ++static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; ++static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; ++static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; ++static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; ++static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; ++#endif ++static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; ++static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_QUERY_STP_EVT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; ++static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; ++static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; ++static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; ++ ++#if CFG_WMT_BT_PORT2 ++static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; ++static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++#endif ++ ++/*soc patial patch address cmd & evt need firmware owner provide*/ ++#if CFG_WMT_MULTI_PATCH ++static UINT8 WMT_PATCH_ADDRESS_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x3c, 0x02, 0x09, 0x02, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0xc4, 0x04, 0x09, 0x02, ++ 0x00, 0x3f, 0x00, 0x01, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++#endif ++ ++/*coex cmd/evt++*/ ++static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; ++static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++#if CFG_SUBSYS_COEX_NEED ++static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, ++ 0x00, 0x02, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA ++}; ++static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, ++ 0x00, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA ++}; ++static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, ++ 0x00, 0x04, ++ 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE ++}; ++static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, ++ 0x00, 0x05, ++ 0xAA, 0xAA, 0xAA, 0xAA, ++ 0xBB, 0xBB, 0xBB, 0xBB ++}; ++static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++#endif ++ ++/*coex cmd/evt--*/ ++static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; ++static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; ++static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; ++static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; ++ ++#if 0 ++static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; ++static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; ++#endif ++ ++#if 0 ++/* to enable dump feature */ ++static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 }; ++static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 }; ++ ++/* to get system stack dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++ ++/* to get task and system stack dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++ ++/* to get bt related memory dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A }; ++static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++#endif ++/* to get full dump when f/w assert */ ++static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; ++static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_CORE_START_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x1, 0x00, 0x01 }; ++static UINT8 WMT_CORE_START_RF_CALIBRATION_EVT[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x01 }; ++ ++#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) ++static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x78, 0x00, 0x05, 0x80 /*addr:0x80050078 */ ++ , 0x00, 0x00, 0x11, 0x01 /*value:0x11010000 */ ++ , 0x00, 0x00, 0x77, 0x07 /*mask:0x07770000 */ ++}; ++ ++static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++ ++static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x74, 0x00, 0x05, 0x80 /*addr:0x80050074 */ ++ , 0x44, 0x44, 0x00, 0x00 /*value:0x11010000 */ ++ , 0x77, 0x77, 0x00, 0x00 /*mask:0x07770000 */ ++}; ++ ++static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++ ++static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0xA0, 0x00, 0x05, 0x80 /*addr:0x80050074 */ ++ , 0x04, 0x00, 0x00, 0x00 /*value:0x11010000 */ ++ , 0x04, 0x00, 0x00, 0x00 /*mask:0x07770000 */ ++}; ++ ++static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++#endif ++ ++#if !(CFG_IC_SOC) /* For MT6628 no need to set ALLEINT registers, done in f/w */ ++/* enable all interrupt */ ++static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ ++ , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ ++ , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ ++}; ++ ++static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++ ++#endif ++ ++#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ ++static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++ , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ ++ , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ ++ , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ ++ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ ++ , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ ++ , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ ++}; ++ ++static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++}; ++#endif ++ ++#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ ++static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 4 registers */ ++ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ ++ , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ ++ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ ++ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ ++ , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ ++ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ ++ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ ++ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ ++ , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ ++ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ ++ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ ++ , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ ++}; ++ ++static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /* S: 0 */ ++ , 0x00 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 4 registers */ ++}; ++#endif ++ ++#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ ++static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++ , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ ++ , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ ++ , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ ++ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ ++ , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ ++ , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ ++}; ++ ++static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x02 /*2 registers */ ++}; ++#endif ++ ++#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ ++#if 1 /* Ray */ ++static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 4 registers */ ++ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ ++ , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ ++ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ ++ /* cirq_int_n */ ++ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ ++ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ ++ , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ ++ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ ++ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ ++ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ ++ /* 1. ARM irq_b, monitor flag 0 */ ++ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ ++ , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ ++ , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ ++}; ++ ++static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /* S: 0 */ ++ , 0x00 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x04 /* 5 registers */ ++}; ++#elif 0 /* KC */ ++static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x05 /* 5 registers */ ++ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ ++ , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ ++ , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ ++ /* 1. ARM irq_b, monitor flag 0 */ ++ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ ++ , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ ++ , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ ++ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ ++ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ ++ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ ++ /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ ++ , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ ++ , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ ++ , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ ++ , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ ++ , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ ++ , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ ++}; ++ ++static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /* S: 0 */ ++ , 0x00 /* type: reg */ ++ , 0x00 /* rev */ ++ , 0x05 /* 5 registers */ ++}; ++#endif ++#endif ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; ++static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; ++ ++static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; ++static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; ++#endif ++ ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++static UINT8 WMT_GET_EFUSE_VCN33_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x04, 0x00 }; ++static UINT8 WMT_GET_EFUSE_VCN33_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x04, 0x00 }; ++#endif ++ ++/* set sdio driving */ ++#if CFG_WMT_SDIO_DRIVING_SET ++static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ ++ , 0x01 /* op: w */ ++ , 0x01 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++ , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ ++ , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ ++ , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ ++}; ++ ++static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ ++ , 0x00 /*S: 0 */ ++ , 0x00 /*type: reg */ ++ , 0x00 /*rev */ ++ , 0x01 /*1 registers */ ++}; ++#endif ++ ++#if CFG_WMT_WIFI_5G_SUPPORT ++static UINT8 WMT_GET_SOC_ADIE_CHIPID_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; ++static UINT8 WMT_GET_SOC_ADIE_CHIPID_EVT[] = { ++ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, ++ 0x00, 0x00, 0x00, 0x00, 0x00 ++}; ++static UINT8 WMT_GET_SOC_6625_L_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x20, 0x01 }; ++static UINT8 WMT_GET_SOC_6625_L_EVT[] = { ++ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x20, ++ 0x01, 0x00, 0x00, 0x00, 0x00 ++}; ++#endif ++ ++#if CFG_WMT_PATCH_DL_OPTM ++static UINT8 WMT_SET_MCU_CLK_EN_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x34, 0x03, 0x00, 0x80, ++ 0x00, 0x00, 0x01, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_EN_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_SET_MCU_CLK_138_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, ++ 0x59, 0x4d, 0x84, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_138_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_SET_MCU_CLK_26_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, ++ 0x00, 0x4d, 0x84, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_26_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++static UINT8 WMT_SET_MCU_CLK_DIS_CMD[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x34, 0x03, 0x00, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++static UINT8 WMT_SET_MCU_CLK_DIS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++ ++/*only for 6797,enable high clock frequency*/ ++/*CLK EN*/ ++static UINT8 WMT_SET_MCU_CLK_EN_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x10, ++ 0x00, 0x00, 0x00, 0x10 ++}; ++/*RATIO SET*/ ++static UINT8 WMT_SET_MCU_RATIO_SET_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, ++ 0xc0, 0x00, 0x00, 0x00 ++}; ++/*DIV SET*/ ++static UINT8 WMT_SET_MCU_DIV_SET_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x18, 0x11, 0x02, 0x80, 0x07, 0x00, 0x00, 0x00, ++ 0x3f, 0x00, 0x00, 0x00 ++}; ++/*HCLK SET*/ ++static UINT8 WMT_SET_MCU_HCLK_SET_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x00, 0x11, 0x02, 0x81, 0x04, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x00, 0x00 ++}; ++ ++/*Change clock to 26MHz*/ ++/*HCLK DIS*/ ++static UINT8 WMT_SET_MCU_HCLK_DIS_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x00, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x00, 0x00 ++}; ++/*RATIO DIS*/ ++static UINT8 WMT_SET_MCU_RATIO_DIS_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x0c, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, ++ 0xc0, 0x00, 0x00, 0x00 ++}; ++/*CLK DIS*/ ++static UINT8 WMT_SET_MCU_CLK_DIS_6797[] = { ++ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x10 ++}; ++ ++static UINT8 WMT_SET_MCU_CLK_EVT_6797[] = { ++ 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 ++}; ++ ++#endif ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = {0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00}; ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, ++ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, ++ 0x01, 0x0e, 0x0e, 0x0e, 0x00, 0x0a, 0x0c, 0x0e, ++ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, ++ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xd4, ++ 0x09, 0xe3, 0x09, 0x5a, 0x0a, 0x14, 0x09, 0x2d, ++ 0x09, 0x46, 0x09, 0x60, 0x09, 0xd3, 0x09, 0xe2, ++ 0x09, 0x59, 0x0a, 0x8B, 0x0a}; ++static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; ++static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; ++ ++#if 0 ++static UINT8 WMT_COEX_SPLIT_FILTER_CMD_TEST[] = { ++ 0x01, 0x10, 0x19, 0x00, 0x0F, 0x00, 0x00, 0x00, ++ 0x00, 0x6c, 0x09, 0x8a, 0x09, 0x8a, 0x09, 0x9e, ++ 0x09, 0x01, 0x07, 0x07, 0x0b, 0x07, 0x07, 0x00, ++ 0x32, 0x27, 0x4e, 0x27, 0x32 ++}; ++ ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x07, 0x07, 0x07, 0x54, 0x54, 0x00, 0x00, ++ 0x00, 0x50, 0x50, 0x50, 0x54, 0x54, 0x39, 0x39, ++ 0x39, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x01, 0x01, ++ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x0a, ++ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00 ++}; ++ ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, ++ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, ++ 0x09, 0xf6, 0x09, 0x0f, 0xaf, 0x14, 0x09, 0x2d, ++ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, ++ 0x09, 0x0d, 0x0a, 0x27, 0x0a ++}; ++static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; ++static UINT8 WMT_COEX_EXT_COMPONENT_CMD_TEST[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x7f, 0x03 }; ++#endif ++ ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_0[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, ++ 0x00, 0x63, 0x63, 0x63, 0x63, 0x3c, 0x3c, 0x3c, ++ 0x3c, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, ++ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, 0x0b, ++ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00 ++}; ++ ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, ++ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, ++ 0x09, 0xf6, 0x09, 0x0f, 0x0a, 0x14, 0x09, 0x2d, ++ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, ++ 0x09, 0x0d, 0x0a, 0x27, 0x0a ++}; ++static UINT8 WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x14, 0x00 }; ++static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; ++static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; ++ ++static UINT8 WMT_COEX_FILTER_SPEC_CMD_6752[] = { ++ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, ++ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, ++ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, ++ 0x01, 0x0E, 0x0E, 0x0E, 0x00, 0x0A, 0x0C, 0x0E, ++ 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00 ++}; ++ ++static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752[] = { ++ 0x01, 0x10, 0x21, 0x00, 0x12, 0xFC, 0x08, 0x15, ++ 0x09, 0x2E, 0x09, 0x47, 0x09, 0xC4, 0x09, 0xD4, ++ 0x09, 0xE3, 0x09, 0x5A, 0x0A, 0x14, 0x09, 0x2D, ++ 0x09, 0x46, 0x09, 0x60, 0x09, 0xD3, 0x09, 0xE2, ++ 0x09, 0x59, 0x0A, 0x8B, 0x0A ++}; ++#endif ++ ++#if CFG_WMT_POWER_ON_DLM ++static UINT8 WMT_POWER_CTRL_DLM_CMD1[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x60, 0x00, 0x10, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x0f, 0x00, 0x00 ++}; ++ ++static UINT8 WMT_POWER_CTRL_DLM_CMD2[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x60, 0x00, 0x10, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xf0, 0x00, 0x00, 0x00 ++}; ++ ++static UINT8 WMT_POWER_CTRL_DLM_CMD3[] = { ++ 0x01, 0x08, 0x10, 0x00, ++ 0x01, 0x01, 0x00, 0x01, ++ 0x60, 0x00, 0x10, 0x80, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x08, 0x00, 0x00, 0x00 ++}; ++static UINT8 WMT_POWER_CTRL_DLM_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; ++#endif ++ ++#if (!CFG_IC_SOC) ++ ++/* stp sdio init scripts */ ++static struct init_script init_table_1_1[] = { ++ /* table_1_1 is only applied to common SDIO interface */ ++ INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), ++ /* applied to MT6628 ? */ ++ INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), ++}; ++ ++#endif ++ ++static struct init_script init_table_1_2[] = { ++ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), ++}; ++ ++#if CFG_WMT_UART_HIF_USE ++static struct init_script init_table_2[] = { ++ INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), ++}; ++#endif ++ ++static struct init_script init_table_3[] = { ++ INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), ++#if CFG_WMT_BT_PORT2 ++ INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), ++#endif ++}; ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static struct init_script set_crystal_timing_script[] = { ++ INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, "set crystal trim value"), ++}; ++ ++static struct init_script get_crystal_timing_script[] = { ++ INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, "get crystal trim value"), ++}; ++#endif ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++static struct init_script get_efuse_vcn33_script[] = { ++ INIT_CMD(WMT_GET_EFUSE_VCN33_CMD, WMT_GET_EFUSE_VCN33_EVT, "get efuse vcn33 value"), ++}; ++#endif ++ ++static struct init_script init_table_4[] = { ++ INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), ++}; ++ ++static struct init_script init_table_5[] = { ++ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT, "query stp"), ++}; ++ ++static struct init_script init_table_5_1[] = { ++ INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), ++}; ++ ++static struct init_script init_table_6[] = { ++ INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), ++}; ++ ++static struct init_script calibration_table[] = { ++ INIT_CMD(WMT_CORE_START_RF_CALIBRATION_CMD, WMT_CORE_START_RF_CALIBRATION_EVT, "start RF calibration data"), ++}; ++ ++#if CFG_WMT_PATCH_DL_OPTM ++static struct init_script set_mcuclk_table_1[] = { ++ INIT_CMD(WMT_SET_MCU_CLK_EN_CMD, WMT_SET_MCU_CLK_EN_EVT, "enable set mcu clk"), ++ INIT_CMD(WMT_SET_MCU_CLK_138_CMD, WMT_SET_MCU_CLK_138_EVT, "set mcu clk to 138.67MH"), ++}; ++ ++static struct init_script set_mcuclk_table_2[] = { ++ INIT_CMD(WMT_SET_MCU_CLK_26_CMD, WMT_SET_MCU_CLK_26_EVT, "set mcu clk to 26MH"), ++ INIT_CMD(WMT_SET_MCU_CLK_DIS_CMD, WMT_SET_MCU_CLK_DIS_EVT, "disable set mcu clk"), ++}; ++ ++static struct init_script set_mcuclk_table_3[] = { ++ INIT_CMD(WMT_SET_MCU_CLK_EN_6797, WMT_SET_MCU_CLK_EVT_6797, "enable set mcu clk"), ++ INIT_CMD(WMT_SET_MCU_RATIO_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu ratio set"), ++ INIT_CMD(WMT_SET_MCU_DIV_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu div set"), ++ INIT_CMD(WMT_SET_MCU_HCLK_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "set mcu clk to hclk"), ++}; ++static struct init_script set_mcuclk_table_4[] = { ++ INIT_CMD(WMT_SET_MCU_HCLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu hclk"), ++ INIT_CMD(WMT_SET_MCU_RATIO_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu ratio set"), ++ INIT_CMD(WMT_SET_MCU_CLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu clk set"), ++}; ++ ++#endif ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static struct init_script set_wifi_lte_coex_table_1[] = { ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), ++ INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"), ++}; ++ ++static struct init_script set_wifi_lte_coex_table_2[] = { ++ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), ++ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), ++ INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), ++}; ++ ++static struct init_script set_wifi_lte_coex_table_0[] = { ++#if 0 ++ INIT_CMD(WMT_COEX_SPLIT_FILTER_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex split filter"), ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), ++ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte channel unsafe"), ++ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi coex ext component"), ++#endif ++ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte coex filter spec"), ++ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte freq idx"), ++}; ++ ++static struct init_script get_tdm_req_antsel_num_table[] = { ++ INIT_CMD(WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD, WMT_COEX_SPLIT_MODE_EVT, "get tdm req antsel num"), ++}; ++#endif ++ ++#if CFG_SET_OPT_REG ++static struct init_script set_registers[] = { ++ /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ ++ /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ ++#if CFG_WMT_I2S_DBGUART_SUPPORT ++ INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), ++#endif ++#if CFG_SET_OPT_REG_SWLA ++ INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), ++#endif ++#if CFG_SET_OPT_REG_MCUCLK ++ INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), ++#endif ++#if CFG_SET_OPT_REG_MCUIRQ ++ INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), ++#endif ++}; ++#endif ++ ++static struct init_script coex_table[] = { ++ INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), ++ ++#if CFG_SUBSYS_COEX_NEED ++/* no need in MT6628 */ ++ INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), ++ INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), ++ INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), ++ INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), ++#endif ++}; ++ ++static struct init_script osc_type_table[] = { ++ INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), ++}; ++ ++#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) ++static struct init_script merge_pcm_table[] = { ++ INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"), ++ INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"), ++ INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"), ++}; ++#endif ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++static struct init_script sdio_driving_table[] = { ++ INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), ++}; ++#endif ++ ++#if CFG_WMT_POWER_ON_DLM ++static struct init_script wmt_power_on_dlm_table[] = { ++ INIT_CMD(WMT_POWER_CTRL_DLM_CMD1, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd1"), ++ INIT_CMD(WMT_POWER_CTRL_DLM_CMD2, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd2"), ++ INIT_CMD(WMT_POWER_CTRL_DLM_CMD3, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd3") ++}; ++#endif ++ ++/* SOC Chip Version and Info Table */ ++static const WMT_IC_INFO_S mtk_wcn_soc_info_table[] = { ++ { ++ .u4HwVer = 0x8A00, ++ .cChipName = WMT_IC_NAME_DEFAULT, ++ .cChipVersion = WMT_IC_VER_E1, ++ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, ++ /* need to refine? */ ++ .eWmtHwVer = WMTHWVER_E1, ++ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, ++ .bPsmSupport = MTK_WCN_BOOL_TRUE, ++ }, ++ { ++ .u4HwVer = 0x8A01, ++ .cChipName = WMT_IC_NAME_DEFAULT, ++ .cChipVersion = WMT_IC_VER_E2, ++ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, ++ .eWmtHwVer = WMTHWVER_E2, ++ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, ++ .bPsmSupport = MTK_WCN_BOOL_TRUE, ++ }, ++ { ++ .u4HwVer = 0x8B01, ++ .cChipName = WMT_IC_NAME_DEFAULT, ++ .cChipVersion = WMT_IC_VER_E3, ++ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, ++ .eWmtHwVer = WMTHWVER_E3, ++ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, ++ .bPsmSupport = MTK_WCN_BOOL_TRUE, ++ } ++}; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf); ++ ++static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); ++ ++static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); ++ ++static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); ++ ++static INT32 mtk_wcn_soc_ver_check(VOID); ++ ++static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver); ++ ++static INT32 wmt_stp_init_coex(VOID); ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static INT32 wmt_stp_wifi_lte_coex(VOID); ++#endif ++ ++#if CFG_WMT_MULTI_PATCH ++static INT32 mtk_wcn_soc_patch_dwn(UINT32 index); ++static INT32 mtk_wcn_soc_patch_info_prepare(VOID); ++#else ++static INT32 mtk_wcn_soc_patch_dwn(VOID); ++#endif ++ ++static INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on); ++static WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID); ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static INT32 mtk_wcn_soc_crystal_triming_set(VOID); ++#endif ++ ++static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID); ++ ++static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID); ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++static INT32 mtk_wcn_soc_set_sdio_driving(void); ++#endif ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* SOC Operation Function Table */ ++WMT_IC_OPS wmt_ic_ops_soc = { ++ .icId = 0x0000, /* soc may have mt6572/82/71/83,but they have the same sw init flow */ ++ .sw_init = mtk_wcn_soc_sw_init, ++ .sw_deinit = mtk_wcn_soc_sw_deinit, ++ .ic_pin_ctrl = mtk_wcn_soc_pin_ctrl, ++ .ic_ver_check = mtk_wcn_soc_ver_check, ++ .co_clock_ctrl = mtk_wcn_soc_co_clock_ctrl, ++ .is_quick_sleep = mtk_wcn_soc_quick_sleep_flag_get, ++ .is_aee_dump_support = mtk_wcn_soc_aee_dump_flag_get, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf) ++{ ++ INT32 iRet = -1; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ UINT32 hw_ver; ++ WMT_CTRL_DATA ctrlData; ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++ UINT32 efuse_d3_vcn33 = 2; /*default voltage is 3.5V*/ ++#endif ++#if CFG_WMT_MULTI_PATCH ++ UINT32 patch_num = 0; ++ UINT32 patch_index = 0; ++#endif ++#if CFG_WMT_WIFI_5G_SUPPORT ++ UINT32 dDieChipid = 0; ++ UINT32 aDieChipid = 0; ++ UINT8 evtbuf[20]; ++ UINT32 u4Res; ++ UINT32 pmicChipid = 0; ++#endif ++ WMT_DBG_FUNC(" start\n"); ++ ++ osal_assert(NULL != gp_soc_info); ++ if ((NULL == gp_soc_info) ++ || (NULL == pWmtHifConf) ++ ) { ++ WMT_ERR_FUNC("null pointers: gp_soc_info(0x%p), pWmtHifConf(0x%p)\n", gp_soc_info, pWmtHifConf); ++ return -1; ++ } ++ ++ hw_ver = gp_soc_info->u4HwVer; ++ ++ /* 4 <3.2> start init for BTIF */ ++ if (WMT_HIF_BTIF == pWmtHifConf->hifType) { ++ /* 1. Query chip STP default options (TEST-ONLY) */ ++ /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ ++ iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); ++ osal_assert(0); ++ return -2; ++ } ++ /* 2. Set chip STP options */ ++ iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); ++ return -3; ++ } ++ ++ /* 3. Enable host full mode */ ++ ctrlPa1 = WMT_STP_CONF_MODE; ++ ctrlPa2 = MTKSTP_BTIF_FULL_MODE; ++ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WMT_STP_CONF_EN; ++ ctrlPa2 = 1; ++ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); ++ if (iRet) { ++ WMT_ERR_FUNC("enable host STP-BTIF-FULL mode fail(%d)\n", iRet); ++ return -4; ++ } ++ WMT_DBG_FUNC("enable host STP-BTIF-FULL mode\n"); ++ /*4. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ ++ osal_sleep_ms(10); ++ /* 5. Query chip STP options (TEST-ONLY) */ ++ iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); ++ return -5; ++ } ++ } ++#if CFG_WMT_POWER_ON_DLM ++ iRet = wmt_core_init_script(wmt_power_on_dlm_table, osal_array_size(wmt_power_on_dlm_table)); ++ if (iRet) ++ WMT_ERR_FUNC("wmt_power_on_dlm_table fail(%d)\n", iRet); ++ WMT_DBG_FUNC("wmt_power_on_dlm_table ok\n"); ++#endif ++ /* 6. download patch */ ++#if CFG_WMT_MULTI_PATCH ++ /* 6.1 Let launcher to search patch info */ ++ iRet = mtk_wcn_soc_patch_info_prepare(); ++ if (iRet) { ++ WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); ++ return -6; ++ } ++ ++ /* 6.2 Read patch number */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); ++ patch_num = ctrlPa1; ++ WMT_DBG_FUNC("patch total num = [%d]\n", patch_num); ++ ++#if CFG_WMT_PATCH_DL_OPTM ++ if (0x0279 == wmt_ic_ops_soc.icId) { ++ iRet = wmt_core_init_script(set_mcuclk_table_3, osal_array_size(set_mcuclk_table_3)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_3 fail(%d)\n", iRet); ++ } else { ++ iRet = wmt_core_init_script(set_mcuclk_table_1, osal_array_size(set_mcuclk_table_1)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_1 fail(%d)\n", iRet); ++ } ++#endif ++ /* 6.3 Multi-patch Patch download */ ++ for (patch_index = 0; patch_index < patch_num; patch_index++) { ++ iRet = mtk_wcn_soc_patch_dwn(patch_index); ++ if (iRet) { ++ WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); ++ return -7; ++ } ++ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); ++ return -8; ++ } ++ } ++ ++#if CFG_WMT_PATCH_DL_OPTM ++ if (0x0279 == wmt_ic_ops_soc.icId) { ++ iRet = wmt_core_init_script(set_mcuclk_table_4, osal_array_size(set_mcuclk_table_4)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_4 fail(%d)\n", iRet); ++ } else { ++ iRet = wmt_core_init_script(set_mcuclk_table_2, osal_array_size(set_mcuclk_table_2)); ++ if (iRet) ++ WMT_ERR_FUNC("set_mcuclk_table_2 fail(%d)\n", iRet); ++ } ++#endif ++ ++#else ++ /* 6.3 Patch download */ ++ iRet = mtk_wcn_soc_patch_dwn(); ++ /* If patch download fail, we just ignore this error and let chip init process goes on */ ++ if (iRet) ++ WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); ++ ++ /* 6.4. WMT Reset command */ ++ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); ++ return -8; ++ } ++#endif ++ ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++ /*get CrystalTiming value before set it */ ++ iRet = wmt_core_tx(get_efuse_vcn33_script[0].cmd, get_efuse_vcn33_script[0].cmdSz, &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != get_efuse_vcn33_script[0].cmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", ++ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].cmdSz); ++ } ++ /* EVENT BUF */ ++ osal_memset(get_efuse_vcn33_script[0].evt, 0, get_efuse_vcn33_script[0].evtSz); ++ iRet = wmt_core_rx(get_efuse_vcn33_script[0].evt, get_efuse_vcn33_script[0].evtSz, &u4Res); ++ if (iRet || (u4Res != get_efuse_vcn33_script[0].evtSz)) { ++ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", ++ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].evtSz); ++ mtk_wcn_stp_dbg_dump_package(); ++ } ++ efuse_d3_vcn33 = WMT_GET_EFUSE_VCN33_EVT[5] & 0x03; ++ WMT_INFO_FUNC("Read efuse to set PMIC voltage:(%d)\n", efuse_d3_vcn33); ++ wmt_set_pmic_voltage(efuse_d3_vcn33); ++#endif ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++ if ((0x6580 == wmt_ic_ops_soc.icId) || ++ (0x8163 == wmt_ic_ops_soc.icId) || ++ (0x6752 == wmt_ic_ops_soc.icId) || ++ (0x6582 == wmt_ic_ops_soc.icId) || ++ (0x6592 == wmt_ic_ops_soc.icId) || ++ (0x0279 == wmt_ic_ops_soc.icId) || ++ (0x0326 == wmt_ic_ops_soc.icId) || ++ (0x0321 == wmt_ic_ops_soc.icId) || (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { ++ wmt_stp_wifi_lte_coex(); ++ WMT_DBG_FUNC("wmt_stp_wifi_lte_coex done!\n"); ++ } ++ if ((0x6582 == wmt_ic_ops_soc.icId) || (0x6592 == wmt_ic_ops_soc.icId)) { ++ /*get gpio tdm req antsel number */ ++ ctrlPa1 = 0; ++ ctrlPa2 = 0; ++ wmt_core_ctrl(WMT_CTRL_GET_TDM_REQ_ANTSEL, &ctrlPa1, &ctrlPa2); ++ WMT_INFO_FUNC("get GPIO TDM REQ ANTSEL number(%d)\n", ctrlPa1); ++ /*set gpio tdm req antsel number to firmware */ ++ WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[5] = ctrlPa1; ++ iRet = wmt_core_init_script(get_tdm_req_antsel_num_table, ++ osal_array_size(get_tdm_req_antsel_num_table)); ++ if (iRet) ++ WMT_ERR_FUNC("get_tdm_req_antsel_num_table fail(%d)\n", iRet); ++ } ++#endif ++ /* 7. start RF calibration data */ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_ON; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WIFI_PALDO; ++ ctrlPa2 = PALDO_ON; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ++ iRet = wmt_core_init_script(calibration_table, osal_array_size(calibration_table)); ++ if (iRet) { ++ /* pwrap_read(0x0210,&ctrlPa1); */ ++ /* pwrap_read(0x0212,&ctrlPa2); */ ++ WMT_ERR_FUNC("power status: 210:(%d),212:(%d)!\n", ctrlPa1, ctrlPa2); ++ WMT_ERR_FUNC("calibration_table fail(%d)\n", iRet); ++ return -9; ++ } ++ ++ ctrlPa1 = BT_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ctrlPa1 = WIFI_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ ++ iRet = wmt_stp_init_coex(); ++ if (iRet) { ++ WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); ++ return -10; ++ } ++ WMT_DBG_FUNC("init_coex ok\n"); ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++ mtk_wcn_soc_crystal_triming_set(); ++#endif ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++ mtk_wcn_soc_set_sdio_driving(); ++#endif ++ ++ if (WMT_CO_CLOCK_EN == mtk_wcn_soc_co_clock_get()) { ++ WMT_INFO_FUNC("co-clock enabled.\n"); ++ ++ iRet = wmt_core_init_script(osc_type_table, osal_array_size(osc_type_table)); ++ if (iRet) { ++ WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); ++ return -11; ++ } ++ } else { ++ WMT_WARN_FUNC("co-clock disabled.\n"); ++ } ++#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) ++ iRet = wmt_core_init_script(merge_pcm_table, osal_array_size(merge_pcm_table)); ++ if (iRet) { ++ WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); ++ return -12; ++ } ++#endif ++ ++ /* 15. Set FM strap */ ++ WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; ++ WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; ++ iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", pWmtHifConf->au4StrapConf[0], iRet); ++ return -13; ++ } ++ WMT_DBG_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); ++ ++#if CFG_SET_OPT_REG /*set registers */ ++ iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); ++ if (iRet) { ++ WMT_ERR_FUNC("set_registers fail(%d)", iRet); ++ return -14; ++ } ++#endif ++ ++#if CFG_WMT_COREDUMP_ENABLE ++ /*Open Core Dump Function @QC begin */ ++ mtk_wcn_stp_coredump_flag_ctrl(1); ++#endif ++ if (0 != mtk_wcn_stp_coredump_flag_get()) { ++ iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); ++ if (iRet) { ++ WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); ++ return -15; ++ } ++ WMT_DBG_FUNC("enable soc_consys firmware coredump\n"); ++ } else { ++ WMT_DBG_FUNC("disable soc_consys firmware coredump\n"); ++ } ++ ++#if CFG_WMT_WIFI_5G_SUPPORT ++ dDieChipid = wmt_ic_ops_soc.icId; ++ WMT_DBG_FUNC("current SOC chipid is 0x%x\n", dDieChipid); ++ if (0x6592 == dDieChipid) { ++ /* read A die chipid by wmt cmd */ ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_GET_SOC_ADIE_CHIPID_CMD[0], sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); ++ return -16; ++ } ++ osal_memset(evtbuf, 0, sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT))) { ++ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); ++ return -17; ++ } ++ ++ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); ++ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); ++ ++ if (0x6625 == aDieChipid) { ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_GET_SOC_6625_L_CMD[0], sizeof(WMT_GET_SOC_6625_L_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_CMD))) ++ WMT_ERR_FUNC("wmt_core:read A die efuse CMD fail(%d),size(%d)\n", iRet, u4Res); ++ osal_memset(evtbuf, 0, sizeof(evtbuf)); ++ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_6625_L_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_EVT))) ++ WMT_ERR_FUNC("wmt_core:read A die efuse EVT fail(%d),size(%d)\n", iRet, u4Res); ++ ++ WMT_INFO_FUNC("read SOC Adie Efuse(0x120) value:0x%2x,0x%2x,0x%2x,0x%2x -> %s\n", ++ evtbuf[u4Res - 4], evtbuf[u4Res - 3], evtbuf[u4Res - 2], evtbuf[u4Res - 1], ++ evtbuf[u4Res - 2] == 0x31 ? "MT6625L" : "MT6625"); ++ } ++ /* get PMIC chipid */ ++ ++ ctrlData.ctrlId = WMT_CTRL_SOC_PALDO_CTRL; ++ ctrlData.au4CtrlData[0] = PMIC_CHIPID_PALDO; ++ ctrlData.au4CtrlData[1] = 0; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet < 0) { ++ WMT_ERR_FUNC("wmt_core: read PMIC chipid fail(%d)\n", iRet); ++ return -18; ++ } ++ pmicChipid = ctrlData.au4CtrlData[2]; ++ WMT_INFO_FUNC("current PMIC chipid(0x%x)\n", pmicChipid); ++ ++ /* MT6625 & MT6322, write 1 to 0x0414[12] */ ++ /* MT6625 & MT6323, assert */ ++ /* MT6627 & (MT6322 or MT6323),write 0 to 0x0414[12] */ ++ ++ switch (aDieChipid) { ++ case 0x6625: ++ if (0x6322 == pmicChipid) { ++ WMT_INFO_FUNC("wmt-core:enable wifi 5G support\n"); ++ ctrlPa1 = WIFI_5G_PALDO; ++ ctrlPa2 = PALDO_ON; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else if (0x6323 == pmicChipid) { ++ osal_assert(0); ++ } else { ++ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); ++ } ++ break; ++ case 0x6627: ++ if ((0x6322 == pmicChipid) || (0x6323 == pmicChipid)) { ++ WMT_INFO_FUNC("wmt-core: disable wifi 5G support\n"); ++ ctrlPa1 = WIFI_5G_PALDO; ++ ctrlPa2 = PALDO_OFF; ++ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); ++ } else { ++ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); ++ } ++ break; ++ default: ++ WMT_WARN_FUNC("wmt-core: unknown A die chipid(0x%x)\n", aDieChipid); ++ break; ++ } ++ } ++#endif ++ ++#if 1 ++ ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; ++ ctrlData.au4CtrlData[0] = wmt_ic_ops_soc.icId; ++ ctrlData.au4CtrlData[1] = (SIZE_T) gp_soc_info->cChipVersion; ++ ctrlData.au4CtrlData[2] = (SIZE_T) &gp_soc_patch_info; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); ++ return -19; ++ } ++#endif ++ ++#if CFG_WMT_PS_SUPPORT ++ osal_assert(NULL != gp_soc_info); ++ if (NULL != gp_soc_info) { ++ if (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport) ++ wmt_lib_ps_enable(); ++ else ++ wmt_lib_ps_disable(); ++ } ++#endif ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) ++{ ++ WMT_DBG_FUNC(" start\n"); ++ ++#if CFG_WMT_PS_SUPPORT ++ osal_assert(NULL != gp_soc_info); ++ if ((NULL != gp_soc_info) ++ && (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport)) { ++ wmt_lib_ps_disable(); ++ } ++#endif ++ ++ gp_soc_info = NULL; ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) ++{ ++ INT32 ret = -1; ++ UINT32 val; ++ ++ if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { ++ WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); ++#if 0 ++ switch (state) { ++ case WMT_IC_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ val = 0x00000770; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_1: ++ /* BT_PCM_ON & FM line in/out */ ++ val = 0x00000700; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_2: ++ /* BT_PCM_OFF & FM I2S */ ++ val = 0x00000710; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ default: ++ WMT_ERR_FUNC("unsupported state (%d)\n", state); ++ ret = -1; ++ break; ++ } ++#else ++ WMT_WARN_FUNC("TBD!!"); ++ ret = 0; ++#endif ++ } else { ++ /*PCM & I2S separate */ ++ WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); ++#if 0 ++ switch (state) { ++ case WMT_IC_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ val = 0x00000770; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_1: ++ /* BT_PCM_ON & FM line in/out */ ++ val = 0x00000700; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000000; ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ break; ++ ++ case WMT_IC_AIF_2: ++ /* BT_PCM_OFF & FM I2S */ ++ val = 0x00000070; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ ++ break; ++ case WMT_IC_AIF_3: ++ val = 0x00000000; ++ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); ++ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ ++ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); ++ ++ break; ++ default: ++ WMT_ERR_FUNC("unsupported state (%d)\n", state); ++ ret = -1; ++ break; ++ } ++#else ++ switch (state) { ++ case WMT_IC_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ ret = 0; ++ break; ++ case WMT_IC_AIF_1: ++ /* BT_PCM_ON & FM line in/out */ ++ ret = 0; ++ break; ++ ++ case WMT_IC_AIF_2: ++ /* BT_PCM_OFF & FM I2S */ ++ val = 0x01110000; ++ ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); ++ ++ break; ++ case WMT_IC_AIF_3: ++ ret = 0; ++ break; ++ ++ default: ++ WMT_ERR_FUNC("unsupported state (%d)\n", state); ++ ret = -1; ++ break; ++ } ++#endif ++ } ++ ++ if (!ret) ++ WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); ++ WMT_INFO_FUNC("new state(%d) ok\n", state); ++ ++ return ret; ++} ++ ++static INT32 mtk_wcn_soc_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) ++{ ++ INT32 iRet = -1; ++ UINT32 uVal = 0; ++ ++ /* mt6797 can not access reg:0x80050078 and no need to do GPS SYNC */ ++ if (0x0279 != wmt_ic_ops_soc.icId) { ++ if (WMT_IC_PIN_MUX == state) ++ uVal = 0x1 << 28; ++ else ++ uVal = 0x5 << 28; ++ iRet = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28); ++ if (iRet) ++ WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet); ++ } else ++ WMT_INFO_FUNC("This chip no need to sync GPS and MODEM!\n"); ++ ++ /* anyway, we return 0 */ ++ return 0; ++} ++ ++static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) ++{ ++ INT32 ret; ++ ++ WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); ++ ++ ret = -1; ++ switch (id) { ++ case WMT_IC_PIN_AUDIO: ++ ret = mtk_wcn_soc_aif_ctrl(state, flag); ++ break; ++ ++ case WMT_IC_PIN_EEDI: ++ WMT_WARN_FUNC("TBD!!"); ++ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ ++ ret = 0; ++ break; ++ ++ case WMT_IC_PIN_EEDO: ++ WMT_WARN_FUNC("TBD!!"); ++ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ ++ ret = 0; ++ break; ++ case WMT_IC_PIN_GSYNC: ++ ret = mtk_wcn_soc_gps_sync_ctrl(state, flag); ++ break; ++ default: ++ break; ++ } ++ WMT_INFO_FUNC("ret = (%d)\n", ret); ++ ++ return ret; ++} ++ ++INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on) ++{ ++ INT32 iRet = 0; ++ ++ if ((WMT_CO_CLOCK_DIS <= on) && (WMT_CO_CLOCK_MAX > on)) { ++ gCoClockEn = on; ++ } else { ++ WMT_DBG_FUNC("0x%x: error parameter:%d\n", wmt_ic_ops_soc.icId, on); ++ iRet = -1; ++ } ++ WMT_DBG_FUNC("0x%x: Co-clock %s\n", wmt_ic_ops_soc.icId, ++ (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled"); ++ ++ return iRet; ++} ++ ++static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID) ++{ ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID) ++{ ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID) ++{ ++ return gCoClockEn; ++} ++ ++static INT32 mtk_wcn_soc_ver_check(VOID) ++{ ++ UINT32 hw_ver; ++ UINT32 fw_ver; ++ INT32 iret; ++ const WMT_IC_INFO_S *p_info; ++ unsigned long ctrlPa1; ++ unsigned long ctrlPa2; ++ ++ /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ ++ WMT_LOUD_FUNC("0x%x: before read hw_ver (hw version)\n", wmt_ic_ops_soc.icId); ++ iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); ++ if (iret) { ++ WMT_ERR_FUNC("0x%x: read hw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); ++ return -2; ++ } ++ WMT_WARN_FUNC("0x%x: read hw_ver (hw version) (0x%x)\n", wmt_ic_ops_soc.icId, hw_ver); ++ ++ WMT_LOUD_FUNC("0x%x: before fw_ver (rom version)\n", wmt_ic_ops_soc.icId); ++ wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); ++ if (iret) { ++ WMT_ERR_FUNC("0x%x: read fw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); ++ return -2; ++ } ++ WMT_WARN_FUNC("0x%x: read fw_ver (rom version) (0x%x)\n", wmt_ic_ops_soc.icId, fw_ver); ++ ++ p_info = mtk_wcn_soc_find_wmt_ic_info(hw_ver); ++ if (NULL == p_info) { ++ WMT_ERR_FUNC("0x%x: hw_ver(0x%x) find wmt ic info fail\n", wmt_ic_ops_soc.icId); ++ return -3; ++ } ++ WMT_WARN_FUNC("0x%x: ic info: %s.%s (0x%x/0x%x, WMTHWVER:%d, patch_ext:%s)\n", ++ wmt_ic_ops_soc.icId, p_info->cChipName, p_info->cChipVersion, ++ hw_ver, fw_ver, p_info->eWmtHwVer, p_info->cPatchNameExt); ++ ++ /* hw id & version */ ++ ctrlPa1 = (wmt_ic_ops_soc.icId << 16) | (hw_ver & 0x0000FFFF); ++ /* translated hw version & fw rom version */ ++ ctrlPa2 = ((UINT32) (p_info->eWmtHwVer) << 16) | (fw_ver & 0x0000FFFF); ++ ++ iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); ++ if (iret) ++ WMT_WARN_FUNC("0x%x: WMT_CTRL_HWIDVER_SET fail(%d)\n", wmt_ic_ops_soc.icId, iret); ++ ++ gp_soc_info = p_info; ++ return 0; ++} ++ ++static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver) ++{ ++ /* match chipversion with u4HwVer item in mtk_wcn_soc_info_table */ ++ const UINT32 size = osal_array_size(mtk_wcn_soc_info_table); ++ INT32 index = 0; ++ ++ /* George: reverse the search order to favor newer version products ++ * TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() ++ * is changed correctly in the future!! ++ * Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. ++ */ ++ index = size - 1; ++ /* full match */ ++ while ((0 <= index) && (hw_ver != mtk_wcn_soc_info_table[index].u4HwVer)) ++ --index; ++ if (0 <= index) { ++ WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); ++ return &mtk_wcn_soc_info_table[index]; ++ } ++ ++ WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); ++ ++ /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR ++ * NUM only can help us support future minor hw ECO, or fab switch, etc. ++ * FULL matching eliminate such flexibility and software package have to be ++ * updated EACH TIME even when minor hw ECO or fab switch!!! ++ */ ++ /* George: reverse the search order to favor newer version products */ ++ index = size - 1; ++ /* major num match */ ++ while ((0 <= index) && ++ (MAJORNUM(hw_ver) != MAJORNUM(mtk_wcn_soc_info_table[index].u4HwVer))) { ++ --index; ++ } ++ if (0 <= index) { ++ WMT_DBG_FUNC("0x%x: found ic info for hw_ver(0x%x) by major num! index:%d\n", ++ wmt_ic_ops_soc.icId, hw_ver, index); ++ return &mtk_wcn_soc_info_table[index]; ++ } ++ ++ WMT_ERR_FUNC("0x%x: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", ++ wmt_ic_ops_soc.icId, hw_ver); ++ WMT_ERR_FUNC("Set default chip version: E1!\n"); ++ return &mtk_wcn_soc_info_table[0]; ++} ++ ++#if CFG_WMT_FILTER_MODE_SETTING ++static INT32 wmt_stp_wifi_lte_coex(VOID) ++{ ++ INT32 iRet; ++ unsigned long addr; ++ WMT_GEN_CONF *pWmtGenConf; ++ ++ /*Get wmt config */ ++ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); ++ if (iRet) { ++ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); ++ return -2; ++ } ++ WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); ++ ++ pWmtGenConf = (P_WMT_GEN_CONF) addr; ++ ++ /*Check if WMT.cfg exists */ ++ if (pWmtGenConf->cfgExist == 0) { ++ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); ++ /*if WMT.cfg not existed, still return success and adopt the default value */ ++ return 0; ++ } ++ ++ osal_sleep_ms(5); ++ ++ if (pWmtGenConf->coex_wmt_filter_mode == 0) { ++ if ((0x6752 == wmt_ic_ops_soc.icId) || ++ (0x6580 == wmt_ic_ops_soc.icId) || ++ (0x8163 == wmt_ic_ops_soc.icId) || ++ (0x0326 == wmt_ic_ops_soc.icId) || ++ (0x0321 == wmt_ic_ops_soc.icId) || ++ (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { ++ iRet = ++ wmt_core_init_script(set_wifi_lte_coex_table_1, osal_array_size(set_wifi_lte_coex_table_1)); ++ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_1 %s(%d)\n", iRet ? "fail" : "ok", iRet); ++ } else if (0x0279 == wmt_ic_ops_soc.icId) { ++ /* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/ ++ if (pWmtGenConf->coex_wmt_ext_component) { ++ WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); ++ set_wifi_lte_coex_table_2[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; ++ } ++ iRet = ++ wmt_core_init_script(set_wifi_lte_coex_table_2, osal_array_size(set_wifi_lte_coex_table_2)); ++ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_2 %s(%d)\n", iRet ? "fail" : "ok", iRet); ++ } else { ++ iRet = ++ wmt_core_init_script(set_wifi_lte_coex_table_0, osal_array_size(set_wifi_lte_coex_table_0)); ++ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 %s(%d)\n", iRet ? "fail" : "ok", iRet); ++ } ++ } ++ ++ return iRet; ++} ++#endif ++ ++static INT32 wmt_stp_init_coex(VOID) ++{ ++ INT32 iRet; ++ unsigned long addr; ++ WMT_GEN_CONF *pWmtGenConf; ++ ++#define COEX_WMT 0 ++ ++#if CFG_SUBSYS_COEX_NEED ++ /* no need for MT6628 */ ++#define COEX_BT 1 ++#define COEX_WIFI 2 ++#define COEX_PTA 3 ++#define COEX_MISC 4 ++#endif ++ /*Get wmt config */ ++ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); ++ if (iRet) { ++ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); ++ return -2; ++ } ++ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); ++ ++ pWmtGenConf = (P_WMT_GEN_CONF) addr; ++ ++ /*Check if WMT.cfg exists */ ++ if (pWmtGenConf->cfgExist == 0) { ++ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); ++ /*if WMT.cfg not existed, still return success and adopt the default value */ ++ return 0; ++ } ++ ++ /*Dump the coex-related info */ ++ WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode); ++#if CFG_SUBSYS_COEX_NEED ++ WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_bt_rssi_upper_limit, ++ pWmtGenConf->coex_bt_rssi_mid_limit, ++ pWmtGenConf->coex_bt_rssi_lower_limit, ++ pWmtGenConf->coex_bt_pwr_high, pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); ++ WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_wifi_rssi_upper_limit, ++ pWmtGenConf->coex_wifi_rssi_mid_limit, ++ pWmtGenConf->coex_wifi_rssi_lower_limit, ++ pWmtGenConf->coex_wifi_pwr_high, pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); ++ WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_ext_pta_hi_tx_tag, ++ pWmtGenConf->coex_ext_pta_hi_rx_tag, ++ pWmtGenConf->coex_ext_pta_lo_tx_tag, ++ pWmtGenConf->coex_ext_pta_lo_rx_tag, ++ pWmtGenConf->coex_ext_pta_sample_t1, ++ pWmtGenConf->coex_ext_pta_sample_t2, pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); ++ WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", ++ pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); ++#endif ++ ++ /*command adjustion due to WMT.cfg */ ++ coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); ++ ++#if CFG_SUBSYS_COEX_NEED ++ coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; ++ coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; ++ coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; ++ coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; ++ coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; ++ coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); ++ ++ coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; ++ coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; ++ coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; ++ coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; ++ coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; ++ coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], ++ coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); ++ ++ coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; ++ coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; ++ coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; ++ coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; ++ coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); ++ coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); ++ coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); ++ coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); ++ coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; ++ if (gWmtDbgLvl >= WMT_LOG_DBG) ++ wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); ++ ++ osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, ++ sizeof(pWmtGenConf->coex_misc_ext_pta_on)); ++ osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, ++ sizeof(pWmtGenConf->coex_misc_ext_feature_set)); ++ ++ wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, coex_table[COEX_MISC].cmdSz); ++#endif ++ ++ iRet = wmt_core_init_script(coex_table, sizeof(coex_table) / sizeof(coex_table[0])); ++ ++ return iRet; ++} ++ ++#if CFG_WMT_SDIO_DRIVING_SET ++static INT32 mtk_wcn_soc_set_sdio_driving(void) ++{ ++ INT32 ret = 0; ++ ++ unsigned long addr; ++ WMT_GEN_CONF *pWmtGenConf; ++ UINT32 drv_val = 0; ++ ++ /*Get wmt config */ ++ ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); ++ if (ret) { ++ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); ++ return -1; ++ } ++ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); ++ ++ pWmtGenConf = (P_WMT_GEN_CONF) addr; ++ ++ /*Check if WMT.cfg exists */ ++ if (pWmtGenConf->cfgExist == 0) { ++ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); ++ /*if WMT.cfg not existed, still return success and adopt the default value */ ++ return 0; ++ } ++ ++ drv_val = pWmtGenConf->sdio_driving_cfg; ++ ++ /*Dump the sdio driving related info */ ++ WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); ++ ++ sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ ++ sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ ++ sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ ++ ++ ret = wmt_core_init_script(sdio_driving_table, sizeof(sdio_driving_table) / sizeof(sdio_driving_table[0])); ++ ++ return ret; ++} ++#endif ++ ++#if CFG_WMT_CRYSTAL_TIMING_SET ++static INT32 mtk_wcn_soc_crystal_triming_set(VOID) ++{ ++ INT32 iRet = 0; ++ PUINT8 pbuf = NULL; ++ UINT32 bufLen = 0; ++ WMT_CTRL_DATA ctrlData; ++ UINT32 uCryTimOffset = 0x6D; ++ MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ INT8 cCrystalTimingOffset = 0x0; ++ UINT8 cCrystalTiming = 0x0; ++ INT32 iCrystalTiming = 0x0; ++ MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; ++ UINT32 u4Res; ++ ++ bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ /**/ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; ++ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; ++ ctrlData.au4CtrlData[1] = (UINT32) &pbuf; ++ ctrlData.au4CtrlData[2] = (UINT32) &bufLen; ++ ++ iRet = wmt_ctrl(&ctrlData); ++ if (0 != iRet) { ++ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", wmt_ic_ops_soc.icId, iRet); ++ bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; ++ cCrystalTimingOffset = 0x0; ++ cCrystalTiming = 0x0; ++ iRet = -1; ++ } else { ++ WMT_DBG_FUNC("0x%x: nvram pBuf(0x%08x), bufLen(%d)\n", wmt_ic_ops_soc.icId, pbuf, bufLen); ++ if (bufLen < (uCryTimOffset + 1)) { ++ WMT_ERR_FUNC("0x%x: nvram len(%d) too short, crystalTimging value offset(%d)\n", ++ wmt_ic_ops_soc.icId, bufLen, uCryTimOffset); ++ bIsNvramExist = MTK_WCN_BOOL_FALSE; ++ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; ++ cCrystalTimingOffset = 0x0; ++ cCrystalTiming = 0x0; ++ } else { ++ bIsNvramExist = MTK_WCN_BOOL_TRUE; ++ cCrystalTimingOffset = *(pbuf + uCryTimOffset); ++ if (cCrystalTimingOffset & 0x80) { ++ bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; ++ cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; ++ } ++ WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", cCrystalTimingOffset, ++ bIsCrysTrimEnabled); ++ } ++ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; ++ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; ++ iRet = wmt_ctrl(&ctrlData); ++ if (0 != iRet) { ++ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", wmt_ic_ops_soc.icId, iRet); ++ iRet = -2; ++ } else { ++ WMT_DBG_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n", wmt_ic_ops_soc.icId); ++ } ++ } ++ if ((MTK_WCN_BOOL_TRUE == bIsNvramExist) && (MTK_WCN_BOOL_TRUE == bIsCrysTrimEnabled)) { ++ /*get CrystalTiming value before set it */ ++ iRet = ++ wmt_core_tx(get_crystal_timing_script[0].cmd, get_crystal_timing_script[0].cmdSz, &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { ++ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", ++ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].cmdSz); ++ iRet = -3; ++ goto done; ++ } ++ /* EVENT BUF */ ++ osal_memset(get_crystal_timing_script[0].evt, 0, get_crystal_timing_script[0].evtSz); ++ iRet = wmt_core_rx(get_crystal_timing_script[0].evt, get_crystal_timing_script[0].evtSz, &u4Res); ++ if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { ++ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", ++ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].evtSz); ++ mtk_wcn_stp_dbg_dump_package(); ++ iRet = -4; ++ goto done; ++ } ++ ++ iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; ++ if (cCrystalTimingOffset & 0x40) { ++ /*nagative offset value */ ++ iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; ++ } else { ++ iCrystalTiming += cCrystalTimingOffset; ++ } ++ WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); ++ cCrystalTiming = iCrystalTiming > 0x7f ? 0x7f : iCrystalTiming; ++ cCrystalTiming = iCrystalTiming < 0 ? 0 : iCrystalTiming; ++ WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); ++ /* set_crystal_timing_script */ ++ WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; ++ WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; ++ ++ iRet = wmt_core_init_script(set_crystal_timing_script, osal_array_size(set_crystal_timing_script)); ++ if (iRet) { ++ WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); ++ iRet = -5; ++ } else { ++ WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", WMT_SET_CRYSTAL_TRIMING_CMD[5]); ++ iRet = ++ wmt_core_init_script(get_crystal_timing_script, osal_array_size(get_crystal_timing_script)); ++ if (iRet) { ++ WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); ++ iRet = -6; ++ } else { ++ WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", ++ WMT_GET_CRYSTAL_TRIMING_EVT[5]); ++ iRet = 0x0; ++ } ++ } ++ } ++done: ++ return iRet; ++} ++#endif ++ ++#if CFG_WMT_MULTI_PATCH ++static INT32 mtk_wcn_soc_patch_info_prepare(VOID) ++{ ++ INT32 iRet = -1; ++ WMT_CTRL_DATA ctrlData; ++ ++ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; ++ iRet = wmt_ctrl(&ctrlData); ++ ++ return iRet; ++} ++ ++static INT32 mtk_wcn_soc_patch_dwn(UINT32 index) ++{ ++ INT32 iRet = -1; ++ P_WMT_PATCH patchHdr; ++ PUINT8 pbuf; ++ UINT32 patchSize; ++ UINT32 fragSeq; ++ UINT32 fragNum; ++ UINT16 fragSize = 0; ++ UINT16 cmdLen; ++ UINT32 offset; ++ UINT32 u4Res; ++ UINT8 evtBuf[8]; ++ UINT8 addressevtBuf[12]; ++ UINT8 addressByte[4]; ++ PINT8 cDataTime = NULL; ++ /*PINT8 cPlat = NULL; */ ++ UINT16 u2HwVer = 0; ++ UINT16 u2SwVer = 0; ++ UINT32 u4PatchVer = 0; ++ UINT32 patchSizePerFrag = 0; ++ WMT_CTRL_DATA ctrlData; ++ ++ /*1.check hardware information */ ++ if (NULL == gp_soc_info) { ++ WMT_ERR_FUNC("null gp_soc_info!\n"); ++ return -1; ++ } ++ ++ osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); ++ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; ++ ctrlData.au4CtrlData[0] = index + 1; ++ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; ++ ctrlData.au4CtrlData[2] = (SIZE_T) &addressByte; ++ iRet = wmt_ctrl(&ctrlData); ++ WMT_DBG_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); ++ ++ /* <2.2> read patch content */ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; ++ ctrlData.au4CtrlData[0] = (SIZE_T) NULL; ++ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; ++ ctrlData.au4CtrlData[2] = (SIZE_T) &pbuf; ++ ctrlData.au4CtrlData[3] = (SIZE_T) &patchSize; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); ++ iRet -= 1; ++ goto done; ++ } ++ ++ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ ++ pbuf += BCNT_PATCH_BUF_HEADROOM; ++ /* patch file with header: ++ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| ++ */ ++ patchHdr = (P_WMT_PATCH) pbuf; ++ /* check patch file information */ ++ ++ cDataTime = patchHdr->ucDateTime; ++ u2HwVer = patchHdr->u2HwVer; ++ u2SwVer = patchHdr->u2SwVer; ++ u4PatchVer = patchHdr->u4PatchVer; ++ /*cPlat = &patchHdr->ucPLat[0]; */ ++ ++ cDataTime[15] = '\0'; ++ if (index == 0) { ++ WMT_DBG_FUNC("===========================================\n"); ++ WMT_INFO_FUNC("[Patch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", ++ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), ++ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), ++ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); ++ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], ++ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("===========================================\n"); ++ } ++ ++ /* remove patch header: ++ * |<-patch body: X Bytes (X=patchSize)--->| ++ */ ++ patchSize -= sizeof(WMT_PATCH); ++ pbuf += sizeof(WMT_PATCH); ++ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; ++ /* reserve 1st patch cmd space before patch body ++ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| ++ */ ++ /* gp_soc_patch_info = patchHdr; */ ++ osal_memcpy(&gp_soc_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); ++ pbuf -= sizeof(WMT_PATCH_CMD); ++ ++ fragNum = patchSize / patchSizePerFrag; ++ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; ++ ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ ++ /*send wmt part patch address command */ ++ if (0x6752 == wmt_ic_ops_soc.icId || ++ 0x8127 == wmt_ic_ops_soc.icId || ++ 0x7623 == wmt_ic_ops_soc.icId || ++ 0x6571 == wmt_ic_ops_soc.icId || ++ 0x0326 == wmt_ic_ops_soc.icId || ++ 0x0321 == wmt_ic_ops_soc.icId || ++ 0x0335 == wmt_ic_ops_soc.icId || ++ 0x0337 == wmt_ic_ops_soc.icId || 0x8163 == wmt_ic_ops_soc.icId || 0x6580 == wmt_ic_ops_soc.icId) { ++ /* MT6571 patch RAM base */ ++ WMT_PATCH_ADDRESS_CMD[8] = 0x40; ++ WMT_PATCH_P_ADDRESS_CMD[8] = 0xc8; ++ } ++ /*send wmt part patch address command */ ++ if (0x0279 == wmt_ic_ops_soc.icId) { ++ /* MT6797 patch RAM base */ ++ WMT_PATCH_ADDRESS_CMD[8] = 0x08; ++ WMT_PATCH_ADDRESS_CMD[9] = 0x05; ++ WMT_PATCH_P_ADDRESS_CMD[8] = 0x2c; ++ WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b; ++ } ++ ++ /*send wmt part patch address command */ ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { ++ WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); ++ iRet -= 1; ++ goto done; ++ } ++ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); ++ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { ++ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); ++ iRet -= 1; ++ goto done; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); ++ iRet -= 1; ++ goto done; ++ } ++#endif ++ ++ /*send part patch address command */ ++ osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); ++ WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", ++ WMT_PATCH_P_ADDRESS_CMD[12], ++ WMT_PATCH_P_ADDRESS_CMD[13], WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); ++ iRet = ++ wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { ++ WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); ++ iRet -= 1; ++ goto done; ++ } ++ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); ++ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { ++ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); ++ iRet -= 1; ++ goto done; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", index); ++ iRet -= 1; ++ goto done; ++ } ++#endif ++ ++ /* send all fragments */ ++ offset = sizeof(WMT_PATCH_CMD); ++ fragSeq = 0; ++ while (fragSeq < fragNum) { ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ if (fragSeq == (fragNum - 1)) { ++ /* last fragment */ ++ fragSize = patchSize - fragSeq * patchSizePerFrag; ++ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; ++ } else { ++ fragSize = patchSizePerFrag; ++ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; ++ } ++ /* update length field in CMD:flag+frag */ ++ cmdLen = 1 + fragSize; ++ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); ++ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ ++ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); ++ ++ /* iRet = ++ *(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), ++ *&u4Res); ++ */ ++ iRet = ++ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), ++ &u4Res, MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); ++ ++ osal_memset(evtBuf, 0, sizeof(evtBuf)); ++ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ ++ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), ++ u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, ++ evtBuf[0], ++ evtBuf[1], ++ evtBuf[2], ++ evtBuf[3], ++ evtBuf[4]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_PATCH_EVT), ++ WMT_PATCH_EVT[0], ++ WMT_PATCH_EVT[1], ++ WMT_PATCH_EVT[2], ++ WMT_PATCH_EVT[3], ++ WMT_PATCH_EVT[4]); ++ iRet -= 1; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); ++ offset += patchSizePerFrag; ++ ++fragSeq; ++ } ++ ++ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", ++ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); ++ ++ if (fragSeq != fragNum) ++ iRet -= 1; ++done: ++ /* WMT_CTRL_FREE_PATCH always return 0 */ ++ /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ ++ ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; ++ ctrlData.au4CtrlData[0] = index + 1; ++ wmt_ctrl(&ctrlData); ++ ++ return iRet; ++} ++ ++#else ++static INT32 mtk_wcn_soc_patch_dwn(VOID) ++{ ++ INT32 iRet = -1; ++ P_WMT_PATCH patchHdr; ++ PUINT8 pbuf; ++ UINT32 patchSize; ++ UINT32 fragSeq; ++ UINT32 fragNum; ++ UINT16 fragSize = 0; ++ UINT16 cmdLen; ++ UINT32 offset; ++ UINT32 u4Res; ++ UINT8 evtBuf[8]; ++ PINT8 cDataTime = NULL; ++ /*PINT8 cPlat = NULL; */ ++ UINT16 u2HwVer = 0; ++ UINT16 u2SwVer = 0; ++ UINT32 u4PatchVer = 0; ++ UINT32 patchSizePerFrag = 0; ++ WMT_CTRL_DATA ctrlData; ++ ++ /*1.check hardware information */ ++ if (NULL == gp_soc_info) { ++ WMT_ERR_FUNC("null gp_soc_info!\n"); ++ return -1; ++ } ++ /* <2> search patch and read patch content */ ++ /* <2.1> search patch */ ++ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; ++ iRet = wmt_ctrl(&ctrlData); ++ if (0 == iRet) { ++ /* patch with correct Hw Ver Major Num found */ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; ++ ctrlData.au4CtrlData[0] = (UINT32) &gFullPatchName; ++ iRet = wmt_ctrl(&ctrlData); ++ ++ WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); ++ /* <2.2> read patch content */ ++ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; ++ ctrlData.au4CtrlData[0] = (UINT32) NULL; ++ ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName; ++ ++ } else { ++ iRet -= 1; ++ return iRet; ++ } ++ ctrlData.au4CtrlData[2] = (UINT32) &pbuf; ++ ctrlData.au4CtrlData[3] = (UINT32) &patchSize; ++ iRet = wmt_ctrl(&ctrlData); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); ++ iRet -= 1; ++ goto done; ++ } ++ ++ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ ++ pbuf += BCNT_PATCH_BUF_HEADROOM; ++ /* patch file with header: ++ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| ++ */ ++ patchHdr = (P_WMT_PATCH) pbuf; ++ /* check patch file information */ ++ ++ cDataTime = patchHdr->ucDateTime; ++ u2HwVer = patchHdr->u2HwVer; ++ u2SwVer = patchHdr->u2SwVer; ++ u4PatchVer = patchHdr->u4PatchVer; ++ /*cPlat = &patchHdr->ucPLat[0]; */ ++ ++ cDataTime[15] = '\0'; ++ WMT_DBG_FUNC("===========================================\n"); ++ WMT_INFO_FUNC("[ConsysPatch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", ++ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), ++ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), ++ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); ++ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", ++ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); ++ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], ++ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); ++ WMT_DBG_FUNC("===========================================\n"); ++ ++ /* remove patch header: ++ * |<-patch body: X Bytes (X=patchSize)--->| ++ */ ++ patchSize -= sizeof(WMT_PATCH); ++ pbuf += sizeof(WMT_PATCH); ++ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; ++ /* reserve 1st patch cmd space before patch body ++ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| ++ */ ++ pbuf -= sizeof(WMT_PATCH_CMD); ++ ++ fragNum = patchSize / patchSizePerFrag; ++ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; ++ ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ ++ /* send all fragments */ ++ offset = sizeof(WMT_PATCH_CMD); ++ fragSeq = 0; ++ while (fragSeq < fragNum) { ++ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); ++ if (fragSeq == (fragNum - 1)) { ++ /* last fragment */ ++ fragSize = patchSize - fragSeq * patchSizePerFrag; ++ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; ++ } else { ++ fragSize = patchSizePerFrag; ++ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; ++ } ++ /* update length field in CMD:flag+frag */ ++ cmdLen = 1 + fragSize; ++ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); ++ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ ++ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); ++ ++ /* iRet = ++ * (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), ++ * &u4Res); ++ */ ++ iRet = ++ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), &u4Res, ++ MTK_WCN_BOOL_FALSE); ++ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { ++ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, ++ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", ++ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); ++ ++ osal_memset(evtBuf, 0, sizeof(evtBuf)); ++ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ ++ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); ++ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { ++ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), ++ u4Res, iRet); ++ iRet -= 1; ++ break; ++ } ++#if CFG_CHECK_WMT_RESULT ++ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { ++ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ u4Res, ++ evtBuf[0], ++ evtBuf[1], ++ evtBuf[2], ++ evtBuf[3], ++ evtBuf[4]); ++ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", ++ sizeof(WMT_PATCH_EVT), ++ WMT_PATCH_EVT[0], ++ WMT_PATCH_EVT[1], ++ WMT_PATCH_EVT[2], ++ WMT_PATCH_EVT[3], ++ WMT_PATCH_EVT[4]); ++ iRet -= 1; ++ break; ++ } ++#endif ++ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); ++ offset += patchSizePerFrag; ++ ++fragSeq; ++ } ++ ++ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", ++ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); ++ ++ if (fragSeq != fragNum) ++ iRet -= 1; ++done: ++ /* WMT_CTRL_FREE_PATCH always return 0 */ ++ wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); ++ ++ return iRet; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c +new file mode 100644 +index 000000000000..747ed64af2d2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c +@@ -0,0 +1,1938 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-LIB]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include "wmt_dev.h" ++#include "wmt_lib.h" ++#include "wmt_conf.h" ++#include "wmt_core.h" ++#include "wmt_plat.h" ++ ++#include "stp_core.h" ++#include "btm_core.h" ++#include "psm_core.h" ++#include "stp_dbg.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* A table for translation: CMB_STUB_AIF_X=>WMT_IC_PIN_STATE */ ++static const WMT_IC_PIN_STATE cmb_aif2pin_stat[] = { ++ [CMB_STUB_AIF_0] = WMT_IC_AIF_0, ++ [CMB_STUB_AIF_1] = WMT_IC_AIF_1, ++ [CMB_STUB_AIF_2] = WMT_IC_AIF_2, ++ [CMB_STUB_AIF_3] = WMT_IC_AIF_3, ++}; ++ ++#if CFG_WMT_PS_SUPPORT ++static UINT32 gPsIdleTime = STP_PSM_IDLE_TIME_SLEEP; ++static UINT32 gPsEnable = 1; ++static PF_WMT_SDIO_PSOP sdio_own_ctrl; ++#endif ++ ++#define WMT_STP_CPUPCR_BUF_SIZE 6144 ++static UINT8 g_cpupcr_buf[WMT_STP_CPUPCR_BUF_SIZE] = { 0 }; ++ ++static UINT32 g_quick_sleep_ctrl = 1; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++DEV_WMT gDevWmt; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#if CFG_WMT_PS_SUPPORT ++static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action); ++static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID); ++static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID); ++static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID); ++static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action); ++#endif ++ ++static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pLxOp); ++ ++static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ); ++ ++static INT32 wmtd_thread(PVOID pvData); ++ ++static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag); ++static MTK_WCN_BOOL wmt_lib_hw_state_show(VOID); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++INT32 wmt_lib_idc_lock_aquire(VOID) ++{ ++ return osal_lock_sleepable_lock(&gDevWmt.idc_lock); ++} ++ ++VOID wmt_lib_idc_lock_release(VOID) ++{ ++ osal_unlock_sleepable_lock(&gDevWmt.idc_lock); ++} ++INT32 wmt_lib_psm_lock_aquire(void) ++{ ++ return osal_lock_sleepable_lock(&gDevWmt.psm_lock); ++} ++ ++void wmt_lib_psm_lock_release(void) ++{ ++ osal_unlock_sleepable_lock(&gDevWmt.psm_lock); ++} ++ ++INT32 DISABLE_PSM_MONITOR(void) ++{ ++ INT32 ret = 0; ++ ++ /* osal_lock_sleepable_lock(&gDevWmt.psm_lock); */ ++ ret = wmt_lib_psm_lock_aquire(); ++ if (ret) { ++ WMT_ERR_FUNC("--->lock psm_lock failed, ret=%d\n", ret); ++ return ret; ++ } ++#if CFG_WMT_PS_SUPPORT ++ ret = wmt_lib_ps_disable(); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_lib_ps_disable fail, ret=%d\n", ret); ++ wmt_lib_psm_lock_release(); ++ } ++#endif ++ ++ return ret; ++} ++ ++void ENABLE_PSM_MONITOR(void) ++{ ++#if CFG_WMT_PS_SUPPORT ++ wmt_lib_ps_enable(); ++#endif ++ /* osal_unlock_sleepable_lock(&gDevWmt.psm_lock); */ ++ wmt_lib_psm_lock_release(); ++} ++ ++INT32 wmt_lib_init(VOID) ++{ ++ INT32 iRet; ++ UINT32 i; ++ P_DEV_WMT pDevWmt; ++ P_OSAL_THREAD pThraed; ++ ++ /* create->init->start */ ++ /* 1. create: static allocation with zero initialization */ ++ pDevWmt = &gDevWmt; ++ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); ++ ++ iRet = wmt_conf_read_file(); ++ if (iRet) { ++ WMT_ERR_FUNC("read wmt config file fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ pThraed = &gDevWmt.thread; ++ ++ /* Create mtk_wmtd thread */ ++ osal_strncpy(pThraed->threadName, "mtk_wmtd", sizeof(pThraed->threadName)); ++ pThraed->pThreadData = (VOID *) pDevWmt; ++ pThraed->pThreadFunc = (VOID *) wmtd_thread; ++ iRet = osal_thread_create(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThraed, iRet); ++ return -2; ++ } ++ ++ /* 2. initialize */ ++ /* Initialize wmt_core */ ++ ++ iRet = wmt_core_init(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core_init() fail(%d)\n", iRet); ++ return -1; ++ } ++ ++ /* Initialize WMTd Thread Information: Thread */ ++ osal_event_init(&pDevWmt->rWmtdWq); ++ osal_sleepable_lock_init(&pDevWmt->psm_lock); ++ osal_sleepable_lock_init(&pDevWmt->idc_lock); ++ osal_sleepable_lock_init(&pDevWmt->rActiveOpQ.sLock); ++ osal_sleepable_lock_init(&pDevWmt->rFreeOpQ.sLock); ++ pDevWmt->state.data = 0; ++ ++ /* Initialize op queue */ ++ RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); ++ RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); ++ /* Put all to free Q */ ++ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(pDevWmt->arQue[i].signal)); ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); ++ } ++ ++ /* initialize stp resources */ ++ osal_event_init(&pDevWmt->rWmtRxWq); ++ ++ /*function driver callback */ ++ for (i = 0; i < WMTDRV_TYPE_WIFI; i++) ++ pDevWmt->rFdrvCb.fDrvRst[i] = NULL; ++ ++ pDevWmt->hw_ver = WMTHWVER_MAX; ++ WMT_INFO_FUNC("***********Init, hw->ver = %x\n", pDevWmt->hw_ver); ++ ++ /* TODO:[FixMe][GeorgeKuo]: wmt_lib_conf_init */ ++ /* initialize default configurations */ ++ /* i4Result = wmt_lib_conf_init(VOID); */ ++ /* WMT_WARN_FUNC("wmt_drv_conf_init(%d)\n", i4Result); */ ++ ++ osal_signal_init(&pDevWmt->cmdResp); ++ osal_event_init(&pDevWmt->cmdReq); ++ ++ /* initialize platform resources */ ++ if (0 != gDevWmt.rWmtGenConf.cfgExist) ++ iRet = wmt_plat_init(gDevWmt.rWmtGenConf.co_clock_flag & 0x0f); ++ else ++ iRet = wmt_plat_init(0); ++ ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_plat_init() fail(%d)\n", iRet); ++ return -3; ++ } ++#if CFG_WMT_PS_SUPPORT ++ iRet = wmt_lib_ps_init(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_lib_ps_init() fail(%d)\n", iRet); ++ return -4; ++ } ++#endif ++ ++ /* 3. start: start running mtk_wmtd */ ++ iRet = osal_thread_run(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThraed, iRet); ++ return -5; ++ } ++ ++ /*4. register irq callback to WMT-PLAT */ ++ wmt_plat_irq_cb_reg(wmt_lib_ps_irq_cb); ++ ++ /*5. register audio if control callback to WMT-PLAT */ ++ wmt_plat_aif_cb_reg(wmt_lib_set_aif); ++ ++ /*6. register function control callback to WMT-PLAT */ ++ wmt_plat_func_ctrl_cb_reg(mtk_wcn_wmt_func_ctrl_for_plat); ++ ++ wmt_plat_deep_idle_ctrl_cb_reg(mtk_wcn_consys_stp_btif_dpidle_ctrl); ++ /*7 reset gps/bt state */ ++ ++ mtk_wcn_wmt_system_state_reset(); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_wmt_exp_init(); ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ wmt_idc_init(); ++#endif ++ WMT_DBG_FUNC("init success\n"); ++ return 0; ++} ++ ++INT32 wmt_lib_deinit(VOID) ++{ ++ INT32 iRet; ++ P_DEV_WMT pDevWmt; ++ P_OSAL_THREAD pThraed; ++ INT32 i; ++ INT32 iResult; ++ ++ pDevWmt = &gDevWmt; ++ pThraed = &gDevWmt.thread; ++ iResult = 0; ++ ++ /* stop->deinit->destroy */ ++ ++ /* 1. stop: stop running mtk_wmtd */ ++ iRet = osal_thread_stop(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); ++ iResult += 1; ++ } ++ ++ /* 2. deinit: */ ++ ++#if CFG_WMT_PS_SUPPORT ++ iRet = wmt_lib_ps_deinit(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_lib_ps_deinit fail(%d)\n", iRet); ++ iResult += 2; ++ } ++#endif ++ ++ iRet = wmt_plat_deinit(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_plat_deinit fail(%d)\n", iRet); ++ iResult += 4; ++ } ++ ++ osal_event_deinit(&pDevWmt->cmdReq); ++ osal_signal_deinit(&pDevWmt->cmdResp); ++ ++ /* de-initialize stp resources */ ++ osal_event_deinit(&pDevWmt->rWmtRxWq); ++ ++ for (i = 0; i < WMT_OP_BUF_SIZE; i++) ++ osal_signal_deinit(&(pDevWmt->arQue[i].signal)); ++ ++ ++ osal_sleepable_lock_deinit(&pDevWmt->rFreeOpQ.sLock); ++ osal_sleepable_lock_deinit(&pDevWmt->rActiveOpQ.sLock); ++ osal_sleepable_lock_deinit(&pDevWmt->idc_lock); ++ osal_sleepable_lock_deinit(&pDevWmt->psm_lock); ++ osal_event_deinit(&pDevWmt->rWmtdWq); ++ ++ iRet = wmt_core_deinit(); ++ if (iRet) { ++ WMT_ERR_FUNC("wmt_core_deinit fail(%d)\n", iRet); ++ iResult += 8; ++ } ++ ++ /* 3. destroy */ ++ iRet = osal_thread_destroy(pThraed); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); ++ iResult += 16; ++ } ++ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_wmt_exp_deinit(); ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ wmt_idc_deinit(); ++#endif ++ ++ return iResult; ++} ++ ++VOID wmt_lib_flush_rx(VOID) ++{ ++ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); ++} ++ ++INT32 wmt_lib_trigger_cmd_signal(INT32 result) ++{ ++ P_OSAL_SIGNAL pSignal = &gDevWmt.cmdResp; ++ ++ gDevWmt.cmdResult = result; ++ osal_raise_signal(pSignal); ++ WMT_DBG_FUNC("wakeup cmdResp\n"); ++ return 0; ++} ++ ++P_OSAL_EVENT wmt_lib_get_cmd_event(VOID) ++{ ++ return &gDevWmt.cmdReq; ++} ++ ++INT32 wmt_lib_set_patch_name(PUINT8 cPatchName) ++{ ++ osal_strncpy(gDevWmt.cPatchName, cPatchName, NAME_MAX); ++ return 0; ++} ++ ++INT32 wmt_lib_set_hif(unsigned long hifconf) ++{ ++ UINT32 val; ++ P_WMT_HIF_CONF pHif = &gDevWmt.rWmtHifConf; ++ ++ val = hifconf & 0xF; ++ if (STP_UART_FULL == val) { ++ pHif->hifType = WMT_HIF_UART; ++ val = (hifconf >> 8); ++ pHif->au4HifConf[0] = val; ++ pHif->au4HifConf[1] = val; ++ mtk_wcn_stp_set_if_tx_type(STP_UART_IF_TX); ++ } else if (STP_SDIO == val) { ++ pHif->hifType = WMT_HIF_SDIO; ++ mtk_wcn_stp_set_if_tx_type(STP_SDIO_IF_TX); ++ } else if (STP_BTIF_FULL == val) { ++ pHif->hifType = WMT_HIF_BTIF; ++ mtk_wcn_stp_set_if_tx_type(STP_BTIF_IF_TX); ++ } else { ++ WMT_WARN_FUNC("invalid stp mode: %u\n", val); ++ mtk_wcn_stp_set_if_tx_type(STP_MAX_IF_TX); ++ return -1; ++ } ++ ++ val = (hifconf & 0xF0) >> 4; ++ if (WMT_FM_COMM == val) { ++ pHif->au4StrapConf[0] = WMT_FM_COMM; ++ } else if (WMT_FM_I2C == val) { ++ pHif->au4StrapConf[0] = WMT_FM_I2C; ++ } else { ++ WMT_WARN_FUNC("invalid fm mode: %u\n", val); ++ return -2; ++ } ++ ++ WMT_WARN_FUNC("new hifType: %d, fm:%d\n", pHif->hifType, pHif->au4StrapConf[0]); ++ return 0; ++} ++ ++P_WMT_HIF_CONF wmt_lib_get_hif(VOID) ++{ ++ return &gDevWmt.rWmtHifConf; ++} ++ ++PUINT8 wmt_lib_get_cmd(VOID) ++{ ++ if (osal_test_and_clear_bit(WMT_STAT_CMD, &gDevWmt.state)) ++ return gDevWmt.cCmd; ++ ++ return NULL; ++} ++ ++MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID) ++{ ++ return osal_test_bit(WMT_STAT_CMD, &gDevWmt.state) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; ++} ++ ++#if CFG_WMT_PS_SUPPORT ++INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime) ++{ ++ gPsIdleTime = psIdleTime; ++ return gPsIdleTime; ++} ++ ++INT32 wmt_lib_ps_ctrl(UINT32 state) ++{ ++ if (0 == state) { ++ wmt_lib_ps_disable(); ++ gPsEnable = 0; ++ } else { ++ gPsEnable = 1; ++ wmt_lib_ps_enable(); ++ } ++ return 0; ++} ++ ++INT32 wmt_lib_ps_enable(VOID) ++{ ++ if (gPsEnable) ++ mtk_wcn_stp_psm_enable(gPsIdleTime); ++ ++ return 0; ++} ++ ++INT32 wmt_lib_ps_disable(VOID) ++{ ++ if (gPsEnable) ++ return mtk_wcn_stp_psm_disable(); ++ ++ return 0; ++} ++ ++INT32 wmt_lib_ps_init(VOID) ++{ ++ /* mtk_wcn_stp_psm_register_wmt_cb(wmt_lib_ps_stp_cb); */ ++ return 0; ++} ++ ++INT32 wmt_lib_ps_deinit(VOID) ++{ ++ /* mtk_wcn_stp_psm_unregister_wmt_cb(); */ ++ return 0; ++} ++ ++static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action) ++{ ++ P_OSAL_OP lxop; ++ MTK_WCN_BOOL bRet; ++ UINT32 u4Wait; ++ P_OSAL_SIGNAL pSignal; ++ ++ lxop = wmt_lib_get_free_op(); ++ if (!lxop) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ pSignal = &lxop->signal; ++ pSignal->timeoutValue = 0; ++ lxop->op.opId = WMT_OPID_PWR_SV; ++ lxop->op.au4OpData[0] = action; ++ lxop->op.au4OpData[1] = (SIZE_T) mtk_wcn_stp_psm_notify_stp; ++ u4Wait = 0; ++ bRet = wmt_lib_put_act_op(lxop); ++ return bRet; ++} ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor) ++{ ++ P_OSAL_OP lxop; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ INT32 ret = 0; ++ UINT16 msg_len = 0; ++ static UINT8 msg_local_buffer[1300]; ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; ++#endif ++ WMT_DBG_FUNC("idc_infor from conn_md is 0x%p\n", idc_infor); ++ ret = wmt_lib_idc_lock_aquire(); ++ if (ret) { ++ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", ret); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ msg_len = idc_infor->local_para_ptr->msg_len - osal_sizeof(local_para_struct); ++ osal_memcpy(&msg_local_buffer[0], &msg_len, osal_sizeof(msg_len)); ++ osal_memcpy(&msg_local_buffer[osal_sizeof(msg_len)], ++ &(idc_infor->local_para_ptr->data[0]), msg_len - 1); ++ wmt_lib_idc_lock_release(); ++ lxop = wmt_lib_get_free_op(); ++ if (!lxop) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ pSignal = &lxop->signal; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ lxop->op.opId = WMT_OPID_IDC_MSG_HANDLING; ++ lxop->op.au4OpData[0] = (size_t) msg_local_buffer; ++ /*msg opcode fill rule is still not clrear,need scott comment */ ++ /***********************************************************/ ++ WMT_DBG_FUNC("ilm msg id is (0x%08x)\n", idc_infor->msg_id); ++ ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ switch (idc_infor->msg_id) { ++ case IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_PARA; ++ break; ++ case IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_FREQ; ++ break; ++ case IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_WIFI_MAX_POWER; ++ break; ++ case IPC_MSG_ID_EL1_LTE_TX_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_INDICATION; ++ break; ++ case IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND: ++ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS; ++ break; ++ default: ++ unknown_msgid = MTK_WCN_BOOL_TRUE; ++ break; ++ } ++ ++ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(lxop); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(lxop); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); ++ else ++ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", lxop->op.opId, lxop->op.au4OpData[1]); ++ } else { ++ bRet = MTK_WCN_BOOL_FALSE; ++ wmt_lib_put_op_to_free_queue(lxop); ++ WMT_ERR_FUNC("unknown msgid from LTE(%d)\n", idc_infor->msg_id); ++ } ++#else ++ if ((idc_infor->msg_id >= IPC_EL1_MSG_ID_BEGIN) ++ && (idc_infor->msg_id <= IPC_EL1_MSG_ID_BEGIN + IPC_EL1_MSG_ID_RANGE)) { ++ lxop->op.au4OpData[1] = idc_infor->msg_id - IPC_EL1_MSG_ID_BEGIN + LTE_MSG_ID_OFFSET - 1; ++ ++ WMT_DBG_FUNC("LTE->CONN:(0x%x->0x%zx)\n", idc_infor->msg_id, lxop->op.au4OpData[1]); ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(lxop); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(lxop); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); ++ } else { ++ WMT_DBG_FUNC("wmt_lib_handle_idc_msg OPID(%d) type(%d) ok\n", ++ lxop->op.opId, lxop->op.au4OpData[1]); ++ } ++ } else { ++ wmt_lib_put_op_to_free_queue(lxop); ++ WMT_ERR_FUNC("msgid(%d) out of range,wmt drop it!\n", idc_infor->msg_id); ++ } ++#endif ++ ++ return bRet; ++} ++#endif ++ ++static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID) ++{ ++ return wmt_lib_ps_action(SLEEP); ++} ++ ++static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID) ++{ ++ return wmt_lib_ps_action(WAKEUP); ++} ++ ++static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID) ++{ ++#if 1 ++ return wmt_lib_ps_action(WAKEUP); ++#else ++ return wmt_lib_ps_action(HOST_AWAKE); ++#endif ++} ++ ++/* extern int g_block_tx; */ ++static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action) ++{ ++ INT32 ret; ++ ++ ret = 0; /* TODO:[FixMe][George] initial value or compile warning? */ ++ /* if(g_block_tx && (action == SLEEP)) */ ++ if ((0 != mtk_wcn_stp_coredump_start_get()) && (action == SLEEP)) { ++ mtk_wcn_stp_psm_notify_stp(SLEEP); ++ return ret; ++ } ++ ++ /*MT662x Not Ready */ ++ if (!mtk_wcn_stp_is_ready()) { ++ WMT_DBG_FUNC("MT662x Not Ready, Dont Send Sleep/Wakeup Command\n"); ++ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); ++ return 0; ++ } ++ ++ if (SLEEP == action) { ++ WMT_DBG_FUNC("send op-----------> sleep job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ ret = wmt_lib_ps_do_sleep(); ++ WMT_DBG_FUNC("enable host eirq\n"); ++ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_EN); ++#if CFG_WMT_DUMP_INT_STATUS ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ } else { ++ /* ret = mtk_wcn_stp_sdio_do_own_set(); */ ++ if (sdio_own_ctrl) { ++ ret = (*sdio_own_ctrl) (OWN_SET); ++ } else { ++ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); ++ ret = -1; ++ } ++ ++ if (!ret) { ++ mtk_wcn_stp_psm_notify_stp(SLEEP); ++ } else if (ret == -2) { ++ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); ++ WMT_WARN_FUNC("===[SDIO-PS] rollback due to tx busy===%%\n"); ++ } else { ++ mtk_wcn_stp_psm_notify_stp(SLEEP); ++ WMT_ERR_FUNC("===[SDIO-PS] set own fails!===%%\n"); ++ } ++ } ++ ++ WMT_DBG_FUNC("send op<---------- sleep job\n"); ++ } else if (WAKEUP == action) { ++ WMT_DBG_FUNC("send op --------> wake job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ WMT_DBG_FUNC("disable host eirq\n"); ++#if CFG_WMT_DUMP_INT_STATUS ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ ret = wmt_lib_ps_do_wakeup(); ++ } else { ++ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ ++ ++ if (sdio_own_ctrl) { ++ ret = (*sdio_own_ctrl) (OWN_CLR); ++ } else { ++ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); ++ ret = -1; ++ } ++ ++ if (!ret) { ++ mtk_wcn_stp_psm_notify_stp(WAKEUP); ++ } else { ++ mtk_wcn_stp_psm_notify_stp(WAKEUP); ++ WMT_ERR_FUNC("===[SDIO-PS] set own back fails!===%%\n"); ++ } ++ } ++ ++ WMT_DBG_FUNC("send op<---------- wake job\n"); ++ } else if (HOST_AWAKE == action) { ++ WMT_DBG_FUNC("send op-----------> host awake job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ WMT_DBG_FUNC("disable host eirq\n"); ++ /* IRQ already disabled */ ++ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ ++#if 0 ++ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) ++ wmt_plat_BGF_irq_dump_status(); ++#endif ++ ret = wmt_lib_ps_do_host_awake(); ++ } else { ++ WMT_DBG_FUNC("[SDIO-PS] SDIO host awake! ####\n"); ++ ++ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ ++ ++ if (sdio_own_ctrl) { ++ ret = (*sdio_own_ctrl) (OWN_CLR); ++ } else { ++ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); ++ ret = -1; ++ } ++ ++ /* Here we set ret to 0 directly */ ++ ret = 0; ++ if (!ret) { ++ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); ++ } else { ++ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); ++ WMT_ERR_FUNC("===[SDIO-PS]set own back fails!===%%\n"); ++ } ++ } ++ ++ WMT_DBG_FUNC("send op<----------- host awake job\n"); ++ } else if (EIRQ == action) { ++ WMT_DBG_FUNC("send op -------------> eirq job\n"); ++ ++ if (!mtk_wcn_stp_is_sdio_mode()) { ++ WMT_DBG_FUNC("disable host eirq\n"); ++ /* Disable interrupt */ ++ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ ++ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); ++ } else { ++ WMT_ERR_FUNC("[SDIO-PS]sdio own-back eirq!######\n"); ++ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); ++ } ++ ++ WMT_DBG_FUNC("send op<----------- eirq job\n"); ++ } ++ ++ return ret; ++} ++#endif /* end of CFG_WMT_PS_SUPPORT */ ++ ++INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action) ++{ ++#if CFG_WMT_PS_SUPPORT ++ return wmt_lib_ps_handler(action); ++#else ++ WMT_WARN_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); ++ return 0; ++#endif ++} ++ ++MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID) ++{ ++ if ((g_quick_sleep_ctrl) && (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_TRUE)) ++ return wmt_core_is_quick_ps_support(); ++ else ++ return MTK_WCN_BOOL_FALSE; ++} ++ ++VOID wmt_lib_ps_irq_cb(VOID) ++{ ++#if CFG_WMT_PS_SUPPORT ++ wmt_lib_ps_handler(EIRQ); ++#else ++ WMT_DBG_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); ++ return; ++#endif ++} ++ ++VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb) ++{ ++#if CFG_WMT_PS_SUPPORT ++ sdio_own_ctrl = own_cb; ++#endif ++} ++ ++UINT32 wmt_lib_wait_event_checker(P_OSAL_THREAD pThread) ++{ ++ P_DEV_WMT pDevWmt; ++ ++ if (pThread) { ++ pDevWmt = (P_DEV_WMT) (pThread->pThreadData); ++ return !RB_EMPTY(&pDevWmt->rActiveOpQ); ++ } ++ WMT_ERR_FUNC("pThread(NULL)\n"); ++ return 0; ++} ++ ++static INT32 wmtd_thread(void *pvData) ++{ ++ P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData; ++ P_OSAL_EVENT pEvent = NULL; ++ P_OSAL_OP pOp; ++ INT32 iResult; ++ ++ if (NULL == pWmtDev) { ++ WMT_ERR_FUNC("pWmtDev(NULL)\n"); ++ return -1; ++ } ++ WMT_INFO_FUNC("wmtd thread starts\n"); ++ ++ pEvent = &(pWmtDev->rWmtdWq); ++ ++ for (;;) { ++ pOp = NULL; ++ pEvent->timeoutValue = 0; ++/* osal_thread_wait_for_event(&pWmtDev->thread, pEvent);*/ ++ osal_thread_wait_for_event(&pWmtDev->thread, pEvent, wmt_lib_wait_event_checker); ++ ++ if (osal_thread_should_stop(&pWmtDev->thread)) { ++ WMT_INFO_FUNC("wmtd thread should stop now...\n"); ++ /* TODO: clean up active opQ */ ++ break; ++ } ++ ++ /* get Op from activeQ */ ++ pOp = wmt_lib_get_op(&pWmtDev->rActiveOpQ); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_lxop activeQ fail\n"); ++ continue; ++ } ++#if 0 /* wmt_core_opid_handler will do sanity check on opId, so no usage here */ ++ id = lxop_get_opid(pLxOp); ++ if (id >= WMT_OPID_MAX) { ++ WMT_WARN_FUNC("abnormal opid id: 0x%x\n", id); ++ iResult = -1; ++ goto handlerDone; ++ } ++#endif ++ ++ if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) { ++ /* when whole chip reset, only HW RST and SW RST cmd can execute */ ++ if ((pOp->op.opId == WMT_OPID_HW_RST) || (pOp->op.opId == WMT_OPID_SW_RST) ++ || (pOp->op.opId == WMT_OPID_GPIO_STATE)) { ++ iResult = wmt_core_opid(&pOp->op); ++ } else { ++ iResult = -2; ++ WMT_WARN_FUNC("Whole chip resetting, opid (%d) failed, iRet(%d)\n", pOp->op.opId, ++ iResult); ++ } ++ } else { ++ wmt_lib_set_current_op(pWmtDev, pOp); ++ iResult = wmt_core_opid(&pOp->op); ++ wmt_lib_set_current_op(pWmtDev, NULL); ++ } ++ ++ if (iResult) ++ WMT_WARN_FUNC("opid (%d) failed, iRet(%d)\n", pOp->op.opId, iResult); ++ ++ if (osal_op_is_wait_for_signal(pOp)) { ++ osal_op_raise_signal(pOp, iResult); ++ } else { ++ /* put Op back to freeQ */ ++ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); ++ } ++ ++ if (WMT_OPID_EXIT == pOp->op.opId) { ++ WMT_INFO_FUNC("wmtd thread received exit signal\n"); ++ break; ++ } ++ } ++ ++ WMT_INFO_FUNC("wmtd thread exits succeed\n"); ++ ++ return 0; ++}; ++ ++static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) ++{ ++ INT32 iRet; ++ ++ if (!pOpQ || !pOp) { ++ WMT_WARN_FUNC("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", pOpQ, pOp); ++ osal_assert(pOpQ); ++ osal_assert(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); ++ if (iRet) { ++ WMT_WARN_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); ++ return MTK_WCN_BOOL_FALSE; ++ } ++#if 0 ++ if (pOpQ == &gDevWmt.rFreeOpQ) ++ WMT_INFO_FUNC("current wmt free queue count is(%d),opid(%d)\n", RB_COUNT(pOpQ), pOp->op.opId); ++#endif ++ /* acquire lock success */ ++ if (!RB_FULL(pOpQ)) ++ RB_PUT(pOpQ, pOp); ++ else ++ iRet = -1; ++ ++ osal_unlock_sleepable_lock(&pOpQ->sLock); ++ ++ if (iRet) { ++ WMT_WARN_FUNC("RB_FULL(0x%p)\n", pOpQ); ++ return MTK_WCN_BOOL_FALSE; ++ } else { ++ return MTK_WCN_BOOL_TRUE; ++ } ++} ++ ++static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ) ++{ ++ P_OSAL_OP pOp; ++ INT32 iRet; ++ ++ if (NULL == pOpQ) { ++ WMT_ERR_FUNC("pOpQ = NULL\n"); ++ osal_assert(pOpQ); ++ return NULL; ++ } ++ ++ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); ++ if (iRet) { ++ WMT_ERR_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); ++ return NULL; ++ } ++ ++ /* acquire lock success */ ++ RB_GET(pOpQ, pOp); ++ osal_unlock_sleepable_lock(&pOpQ->sLock); ++ ++ if (NULL == pOp) { ++ WMT_WARN_FUNC("RB_GET return NULL\n"); ++ osal_assert(pOp); ++ } ++ ++ return pOp; ++} ++ ++INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (MTK_WCN_BOOL_FALSE == wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp)) ++ return -1; ++ else ++ return 0; ++} ++ ++P_OSAL_OP wmt_lib_get_free_op(VOID) ++{ ++ P_OSAL_OP pOp = NULL; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ ++ osal_assert(pDevWmt); ++ ++ pOp = wmt_lib_get_op(&pDevWmt->rFreeOpQ); ++ if (pOp) ++ osal_memset(&pOp->op, 0, osal_sizeof(pOp->op)); ++ return pOp; ++} ++ ++MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ MTK_WCN_BOOL bCleanup = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal = NULL; ++ long waitRet = -1; ++ P_OSAL_THREAD pThread; ++ ++ osal_assert(pWmtDev); ++ osal_assert(pOp); ++ ++ do { ++ if (!pWmtDev || !pOp) { ++ WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp); ++ break; ++ } ++ if ((0 != mtk_wcn_stp_coredump_start_get()) && ++ (WMT_OPID_HW_RST != pOp->op.opId) && ++ (WMT_OPID_SW_RST != pOp->op.opId) && (WMT_OPID_GPIO_STATE != pOp->op.opId)) { ++ bCleanup = MTK_WCN_BOOL_TRUE; ++ WMT_WARN_FUNC("block tx flag is set\n"); ++ break; ++ } ++ pSignal = &pOp->signal; ++/* pOp->u4WaitMs = u4WaitMs; */ ++ if (pSignal->timeoutValue) { ++ pOp->result = -9; ++ osal_signal_init(pSignal); ++ } ++ ++ /* put to active Q */ ++ bRet = wmt_lib_put_op(&pWmtDev->rActiveOpQ, pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("put to active queue fail\n"); ++ bCleanup = MTK_WCN_BOOL_TRUE; ++ break; ++ } ++ ++ /* wake up wmtd */ ++ /* wake_up_interruptible(&pWmtDev->rWmtdWq); */ ++ osal_trigger_event(&pWmtDev->rWmtdWq); ++ ++ if (0 == pSignal->timeoutValue) { ++ bRet = MTK_WCN_BOOL_TRUE; ++ /* clean it in wmtd */ ++ break; ++ } ++ /* wait result, clean it here */ ++ bCleanup = MTK_WCN_BOOL_TRUE; ++ ++ /* check result */ ++ /* wait_ret = wait_for_completion_interruptible_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ ++ /* wait_ret = wait_for_completion_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ ++ waitRet = osal_wait_for_signal_timeout(pSignal); ++ WMT_DBG_FUNC("osal_wait_for_signal_timeout:%ld\n", waitRet); ++ ++ /* if (unlikely(!wait_ret)) { */ ++ if (0 == waitRet) { ++ pThread = &gDevWmt.thread; ++ WMT_ERR_FUNC ++ ("wait completion timeout, opId(%d), show wmtd_thread stack!\n", pOp->op.opId); ++ /* TODO: how to handle it? retry? */ ++ wcn_wmtd_timeout_collect_ftrace(); /* trigger collect SYS_FTRACE */ ++ osal_thread_show_stack(pThread); ++ } else { ++ if (pOp->result) ++ WMT_WARN_FUNC("opId(%d) result:%d\n", pOp->op.opId, pOp->result); ++ } ++ /* op completes, check result */ ++ bRet = (pOp->result) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; ++ } while (0); ++ ++ if (bCleanup) { ++ /* put Op back to freeQ */ ++ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); ++ } ++ ++ return bRet; ++} ++ ++/* TODO:[ChangeFeature][George] is this function obsoleted? */ ++#if 0 ++INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) ++{ ++ P_WMT_LXOP lxop; ++ MTK_WCN_BOOL bRet; ++ PUINT32 plv = NULL; ++ UINT32 pbuf[2]; ++ P_OSAL_EVENT pSignal = NULL; ++ ++ if (!pvalue) { ++ WMT_WARN_FUNC("!pvalue\n"); ++ return -1; ++ } ++ lxop = wmt_lib_get_free_lxop(); ++ if (!lxop) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ ++ return -1; ++ } ++ ++ plv = (PUINT32) (((UINT32) pbuf + 0x3) & ~0x3UL); ++ *plv = *pvalue; ++ pSignal = &lxop->signal; ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%d) offset(0x%x) value(0x%x) mask(0x%x)\n", isWrite, offset, *pvalue, mask); ++ ++ lxop->op.opId = WMT_OPID_REG_RW; ++ lxop->op.au4OpData[0] = isWrite; ++ lxop->op.au4OpData[1] = offset; ++ lxop->op.au4OpData[2] = (UINT32) plv; ++ lxop->op.au4OpData[3] = mask; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ DISABLE_PSM_MONITOR(); ++ bRet = wmt_lib_put_act_lxop(lxop); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE != bRet) { ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", ++ isWrite, offset, *plv, mask); ++ if (!isWrite) ++ *pvalue = *plv; ++ } else { ++ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", ++ isWrite, offset, *plv, mask, bRet); ++ } ++ ++ return bRet; ++} ++#endif ++ ++/* TODO:[ChangeFeature][George] is this function obsoleted? */ ++#if 0 ++static VOID wmt_lib_clear_chip_id(VOID) ++{ ++/* ++ gDevWmt.pChipInfo = NULL; ++*/ ++ gDevWmt.hw_ver = WMTHWVER_INVALID; ++} ++#endif ++ ++/* TODO: [FixMe][GeorgeKuo]: change this API to report real chip id, hw_ver, and */ ++/* fw_ver instead of WMT-translated WMTHWVER */ ++ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver(VOID) ++{ ++/* ++ P_WMT_CMB_CHIP_INFO_S pChipInfo = NULL; ++ P_DEV_WMT pWmtDev = gpDevWmt; ++ pChipInfo = wmt_lib_get_chip_info(pWmtDev); ++ return pChipInfo != NULL ? pChipInfo->eHwVersion : WMTHWVER_INVALID; ++ */ ++ return gDevWmt.eWmtHwVer; ++} ++ ++UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T index) ++{ ++ if (WMTCHIN_CHIPID == index) ++ return gDevWmt.chip_id; ++ else if (WMTCHIN_HWVER == index) ++ return gDevWmt.hw_ver; ++ else if (WMTCHIN_MAPPINGHWVER == index) ++ return gDevWmt.eWmtHwVer; ++ else if (WMTCHIN_FWVER == index) ++ return gDevWmt.fw_ver; ++ ++ return 0; ++ ++} ++ ++PUINT8 wmt_lib_def_patch_name(VOID) ++{ ++ WMT_INFO_FUNC("wmt-lib: use default patch name (%s)\n", gDevWmt.cPatchName); ++ return gDevWmt.cPatchName; ++} ++ ++MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID) ++{ ++ MTK_WCN_BOOL bIsSupportTherm = MTK_WCN_BOOL_TRUE; ++ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ ++ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) ++ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { ++ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); ++ bIsSupportTherm = MTK_WCN_BOOL_FALSE; ++ } ++ if (!mtk_wcn_stp_is_ready()) { ++ WMT_ERR_FUNC("thermal command can not be send: STP is not ready\n"); ++ bIsSupportTherm = MTK_WCN_BOOL_FALSE; ++ } ++ ++ return bIsSupportTherm; ++} ++ ++MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID) ++{ ++ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ ++ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) ++ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { ++ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++/*! ++ * \brief Update combo chip pin settings (GPIO) ++ * ++ * An internal library function to support various settings for chip GPIO. It is ++ * updated in a grouping way: configure all required pins in a single call. ++ * ++ * \param id desired pin ID to be controlled ++ * \param stat desired pin states to be set ++ * \param flag supplementary options for this operation ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid id ++ * \retval -2 invalid stat ++ * \retval < 0 error for operation fail ++ */ ++static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ /* input sanity check */ ++ if (WMT_IC_PIN_MAX <= id) { ++ WMT_ERR_FUNC("invalid ic pin id(%d)\n", id); ++ return -1; ++ } ++ if (WMT_IC_PIN_STATE_MAX <= stat) { ++ WMT_ERR_FUNC("invalid ic pin state (%d)\n", stat); ++ return -2; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_GPIO_CTRL (ic pin id:%d, stat:%d, flag:0x%x)\n", id, stat, flag); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_GPIO_CTRL; ++ pOp->op.au4OpData[0] = id; ++ pOp->op.au4OpData[1] = stat; ++ pOp->op.au4OpData[2] = flag; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("PIN_ID(%d) PIN_STATE(%d) flag(%d) fail\n", id, stat, flag); ++ else ++ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ return 0; ++} ++ ++INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT32 value; ++ P_OSAL_SIGNAL pSignal; ++ ++ if (!pvalue) { ++ WMT_WARN_FUNC("!pvalue\n"); ++ return -1; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; ++ } ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ value = *pvalue; ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", isWrite, offset, *pvalue, mask); ++ pOp->op.opId = WMT_OPID_REG_RW; ++ pOp->op.au4OpData[0] = isWrite; ++ pOp->op.au4OpData[1] = offset; ++ pOp->op.au4OpData[2] = (SIZE_T)&value; ++ pOp->op.au4OpData[3] = mask; ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE != bRet) { ++ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", ++ isWrite, offset, value, mask); ++ if (!isWrite) ++ *pvalue = value; ++ ++ return 0; ++ } ++ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", ++ isWrite, offset, value, mask, bRet); ++ return -1; ++} ++ ++INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT32 value; ++ P_OSAL_SIGNAL pSignal; ++ ++ if (!pvalue) { ++ WMT_WARN_FUNC("!pvalue\n"); ++ return -1; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; ++ } ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ value = *pvalue; ++ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", ++ isWrite, offset, *pvalue, mask); ++ pOp->op.opId = WMT_OPID_EFUSE_RW; ++ pOp->op.au4OpData[0] = isWrite; ++ pOp->op.au4OpData[1] = offset; ++ pOp->op.au4OpData[2] = (SIZE_T)&value; ++ pOp->op.au4OpData[3] = mask; ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE != bRet) { ++ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", ++ isWrite, offset, value, mask); ++ if (!isWrite) ++ *pvalue = value; ++ ++ return 0; ++ } ++ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", ++ isWrite, offset, value, mask, bRet); ++ return -1; ++ ++} ++ ++/*! ++ * \brief update combo chip AUDIO Interface (AIF) settings ++ * ++ * A library function to support updating chip AUDIO pin settings. A group of ++ * pins is updated as a whole. ++ * ++ * \param aif desired audio interface state to use ++ * \param flag whether audio pin is shared or not ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid aif ++ * \retval < 0 error for invalid parameters or operation fail ++ */ ++INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share) ++{ ++ if (CMB_STUB_AIF_MAX <= aif) { ++ WMT_ERR_FUNC("invalid aif (%d)\n", aif); ++ return -1; ++ } ++ WMT_DBG_FUNC("call pin_ctrl for aif:%d, share:%d\n", aif, (MTK_WCN_BOOL_TRUE == share) ? 1 : 0); ++ /* Translate CMB_STUB_AIF_X into WMT_IC_PIN_STATE by array */ ++ return wmt_lib_pin_ctrl(WMT_IC_PIN_AUDIO, ++ cmb_aif2pin_stat[aif], ++ (MTK_WCN_BOOL_TRUE == share) ? WMT_LIB_AIF_FLAG_SHARE : WMT_LIB_AIF_FLAG_SEPARATE); ++} ++ ++INT32 wmt_lib_host_awake_get(VOID) ++{ ++ return wmt_plat_wake_lock_ctrl(WL_OP_GET); ++} ++ ++INT32 wmt_lib_host_awake_put(VOID) ++{ ++ return wmt_plat_wake_lock_ctrl(WL_OP_PUT); ++} ++ ++MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op) ++{ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ ++ if (op == BTM_RST_OP) { ++ /* high priority, not to enqueue into the queue of wmtd */ ++ WMT_INFO_FUNC("Invoke whole chip reset from stp_btm!!!\n"); ++ wmt_lib_cmb_rst(WMTRSTSRC_RESET_STP); ++ bRet = MTK_WCN_BOOL_TRUE; ++ } else if (op == BTM_DMP_OP) { ++ ++ WMT_WARN_FUNC("TBD!!!\n"); ++ } else if (op == BTM_GET_AEE_SUPPORT_FLAG) { ++ bRet = wmt_core_get_aee_dump_flag(); ++ } ++ return bRet; ++} ++ ++MTK_WCN_BOOL wmt_cdev_rstmsg_snd(ENUM_WMTRSTMSG_TYPE_T msg) ++{ ++ ++ INT32 i = 0; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ PUINT8 drv_name[] = { ++ "DRV_TYPE_BT", ++ "DRV_TYPE_FM", ++ "DRV_TYPE_GPS", ++ "DRV_TYPE_WIFI" ++ }; ++ ++ for (i = 0; i <= WMTDRV_TYPE_WIFI; i++) { ++ /* <1> check if reset callback is registered */ ++ if (pDevWmt->rFdrvCb.fDrvRst[i]) { ++ /* <2> send the msg to this subfucntion */ ++ /*src, dst, msg_type, msg_data, msg_size */ ++ pDevWmt->rFdrvCb.fDrvRst[i] (WMTDRV_TYPE_WMT, i, WMTMSG_TYPE_RESET, &msg, ++ sizeof(ENUM_WMTRSTMSG_TYPE_T)); ++ WMT_INFO_FUNC("type = %s, msg sent\n", drv_name[i]); ++ } else { ++ WMT_DBG_FUNC("type = %s, unregistered\n", drv_name[i]); ++ } ++ } ++ ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++VOID wmt_lib_state_init(VOID) ++{ ++ /* UINT32 i = 0; */ ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ P_OSAL_OP pOp; ++ ++ /* Initialize op queue */ ++ /* RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); */ ++ /* RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); */ ++ ++ while (!RB_EMPTY(&pDevWmt->rActiveOpQ)) { ++#if 0 ++ osal_signal_init(&(pOp->signal)); ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); ++#endif ++ pOp = wmt_lib_get_op(&pDevWmt->rActiveOpQ); ++ if (pOp) { ++ if (osal_op_is_wait_for_signal(pOp)) ++ osal_op_raise_signal(pOp, -1); ++ else ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); ++ } ++ } ++ ++ /* Put all to free Q */ ++ /* ++ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { ++ osal_signal_init(&(pDevWmt->arQue[i].signal)); ++ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); ++ } */ ++} ++ ++#if 0 ++INT32 wmt_lib_sdio_ctrl(UINT32 on) ++{ ++ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_SDIO_CTRL\n"); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_SDIO_CTRL; ++ pOp->op.au4OpData[0] = on; ++ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_SDIO_CTRL failed\n"); ++ return -1; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_SDIO_CTRL)ok\n"); ++ ++ return 0; ++} ++#endif ++ ++MTK_WCN_BOOL wmt_lib_hw_state_show(VOID) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_HW_STATE_SHOW\n"); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_GPIO_STATE; ++ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_HW_STATE_SHOW failed\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_HW_STATE_SHOW)ok\n"); ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++MTK_WCN_BOOL wmt_lib_hw_rst(VOID) ++{ ++ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ ++ wmt_lib_state_init(); ++ ++ osal_clear_bit(WMT_STAT_STP_REG, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_STP_OPEN, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_STP_EN, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_STP_RDY, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_RX, &pDevWmt->state); ++ osal_clear_bit(WMT_STAT_CMD, &pDevWmt->state); ++ ++ /*Before do hardware reset, we show GPIO state to check if others modified our pin state accidentially */ ++ wmt_lib_hw_state_show(); ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_HW_RST\n"); ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_HW_RST; ++ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_HW_RST failed\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_HW_RST)ok\n"); ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst) ++{ ++ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ /* <1> wmt state reset */ ++ wmt_lib_state_init(); ++ ++ /* <2> Reset STP data structure */ ++ WMT_DBG_FUNC("Cleanup STP context\n"); ++ mtk_wcn_stp_flush_context(); ++ /* <3> Reset STP-PSM data structure */ ++ WMT_DBG_FUNC("Cleanup STP-PSM context\n"); ++ mtk_wcn_stp_psm_reset(); ++ ++ /* <4> do sw reset in wmt-core */ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ WMT_DBG_FUNC("call WMT_OPID_SW_RST\n"); ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = MAX_FUNC_ON_TIME; ++ ++ pOp->op.opId = WMT_OPID_SW_RST; ++ pOp->op.au4OpData[0] = baudRst; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("WMT_OPID_SW_RST failed\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_DBG_FUNC("OPID(WMT_OPID_SW_RST)ok\n"); ++ return MTK_WCN_BOOL_TRUE; ++} ++ ++ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src) ++{ ++#define RETRYTIMES 10 ++ MTK_WCN_BOOL bRet; ++ ENUM_WMTRSTRET_TYPE_T retval = WMTRSTRET_MAX; ++ ENUM_WMTRSTMSG_TYPE_T rstMsg = WMTRSTMSG_RESET_MAX; ++ INT32 retries = RETRYTIMES; ++ P_DEV_WMT pDevWmt = &gDevWmt; ++ P_OSAL_OP pOp; ++ PUINT8 srcName[] = { "WMTRSTSRC_RESET_BT", ++ "WMTRSTSRC_RESET_FM", ++ "WMTRSTSRC_RESET_GPS", ++ "WMTRSTSRC_RESET_WIFI", ++ "WMTRSTSRC_RESET_STP", ++ "WMTRSTSRC_RESET_TEST" ++ }; ++ ++ if (src < WMTRSTSRC_RESET_MAX) ++ WMT_INFO_FUNC("reset source = %s\n", srcName[src]); ++ ++ if (WMTRSTSRC_RESET_TEST == src) { ++ pOp = wmt_lib_get_current_op(pDevWmt); ++ if (pOp && ((WMT_OPID_FUNC_ON == pOp->op.opId) ++ || (WMT_OPID_FUNC_OFF == pOp->op.opId))) { ++ WMT_INFO_FUNC("can't do reset by test src when func on/off\n"); ++ return -1; ++ } ++ } ++ /* <1> Consider the multi-context combo_rst case. */ ++ if (osal_test_and_set_bit(WMT_STAT_RST_ON, &pDevWmt->state)) { ++ retval = WMTRSTRET_ONGOING; ++ goto rstDone; ++ } ++ /* <2> Block all STP request */ ++ mtk_wcn_stp_enable(0); ++ ++ /* <3> RESET_START notification */ ++ bRet = wmt_cdev_rstmsg_snd(WMTRSTMSG_RESET_START); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); ++ retval = WMTRSTRET_FAIL; ++ goto rstDone; ++ } ++ /* wakeup blocked opid */ ++ pOp = wmt_lib_get_current_op(pDevWmt); ++ if (osal_op_is_wait_for_signal(pOp)) ++ osal_op_raise_signal(pOp, -1); ++ ++ /* wakeup blocked cmd */ ++ wmt_dev_rx_event_cb(); ++ ++ /* <4> retry until reset flow successful */ ++ while (retries > 0) { ++ /* <4.1> reset combo hw */ ++ bRet = wmt_lib_hw_rst(); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_hw_rst!\n"); ++ retries--; ++ continue; ++ } ++ /* <4.2> reset driver/combo sw */ ++ bRet = wmt_lib_sw_rst(1); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_sw_rst!\n"); ++ retries--; ++ continue; ++ } ++ break; ++ } ++ ++ osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state); ++ ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ rstMsg = WMTRSTMSG_RESET_END_FAIL; ++ WMT_WARN_FUNC("[whole chip reset] fail! retries = %d\n", RETRYTIMES - retries); ++ } else { ++ rstMsg = WMTRSTMSG_RESET_END; ++ WMT_INFO_FUNC("[whole chip reset] ok! retries = %d\n", RETRYTIMES - retries); ++ } ++ ++ /* <5> RESET_END notification */ ++ bRet = wmt_cdev_rstmsg_snd(rstMsg); ++ if (bRet == MTK_WCN_BOOL_FALSE) { ++ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); ++ retval = WMTRSTRET_FAIL; ++ } else { ++ retval = WMTRSTMSG_RESET_END == rstMsg ? WMTRSTRET_SUCCESS : WMTRSTRET_FAIL; ++ } ++ mtk_wcn_stp_coredump_start_ctrl(0); ++ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); ++rstDone: ++ if (osal_test_and_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state)) ++ WMT_WARN_FUNC("[whole chip reset] retval = %d\n", retval); ++ ++ return retval; ++} ++ ++MTK_WCN_BOOL wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++{ ++ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { ++ WMT_DBG_FUNC("reg ok!\n"); ++ pWmtDev->rFdrvCb.fDrvRst[eType] = pCb; ++ bRet = MTK_WCN_BOOL_TRUE; ++ } else { ++ WMT_WARN_FUNC("reg fail!\n"); ++ } ++ ++ return bRet; ++} ++ ++MTK_WCN_BOOL wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++{ ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { ++ WMT_DBG_FUNC("unreg ok!\n"); ++ pWmtDev->rFdrvCb.fDrvRst[eType] = NULL; ++ bRet = MTK_WCN_BOOL_TRUE; ++ } else { ++ WMT_WARN_FUNC("unreg fail!\n"); ++ } ++ ++ return bRet; ++} ++ ++UINT32 wmt_lib_dbg_level_set(UINT32 level) ++{ ++ gWmtDbgLvl = level > WMT_LOG_LOUD ? WMT_LOG_LOUD : level; ++ return 0; ++} ++ ++INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value) ++{ ++ return mtk_wcn_stp_set_wmt_last_close(value); ++} ++ ++INT32 wmt_lib_notify_stp_sleep(void) ++{ ++ INT32 iRet = 0x0; ++ ++ iRet = wmt_lib_psm_lock_aquire(); ++ if (iRet) { ++ WMT_ERR_FUNC("--->lock psm_lock failed, iRet=%d\n", iRet); ++ return iRet; ++ } ++ ++ iRet = mtk_wcn_stp_notify_sleep_for_thermal(); ++ wmt_lib_psm_lock_release(); ++ ++ return iRet; ++} ++ ++VOID wmt_lib_set_patch_num(UINT32 num) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ pWmtDev->patchNum = num; ++} ++ ++VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo) ++{ ++ P_DEV_WMT pWmtDev = &gDevWmt; ++ ++ if (pPatchinfo) ++ pWmtDev->pWmtPatchInfo = pPatchinfo; ++ ++} ++ ++INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp) ++{ ++ if (pWmtDev) { ++ pWmtDev->pCurOP = pOp; ++ WMT_DBG_FUNC("pOp=0x%p\n", pOp); ++ return 0; ++ } ++ WMT_ERR_FUNC("Invalid pointer\n"); ++ return -1; ++} ++ ++P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev) ++{ ++ if (pWmtDev) ++ return pWmtDev->pCurOP; ++ ++ WMT_ERR_FUNC("Invalid pointer\n"); ++ return NULL; ++} ++ ++UINT8 *wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, UINT8 *buf, UINT32 len) ++{ ++ UINT8 *pAddr = NULL; ++ UINT32 sublen1 = 0; ++ UINT32 sublen2 = 0; ++ P_CONSYS_EMI_ADDR_INFO p_consys_info; ++ ++ p_consys_info = wmt_plat_get_emi_phy_add(); ++ osal_assert(p_consys_info); ++ ++ if (section == 0) { ++ pAddr = wmt_plat_get_emi_virt_add(0x0); ++ if (len > 1024) ++ len = 1024; ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); ++ osal_memcpy(&buf[0], pAddr, len); ++ } ++ } else { ++ if (offset >= 0x7fff) ++ offset = 0x0; ++ ++ if (offset + len > 32768) { ++ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get part1 EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("part1 vir addr(0x%p)\n", pAddr); ++ sublen1 = 0x7fff - offset; ++ osal_memcpy(&buf[0], pAddr, sublen1); ++ } ++ pAddr = wmt_plat_get_emi_virt_add(p_consys_info->paged_trace_off); ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get part2 EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("part2 vir addr(0x%p)\n", pAddr); ++ sublen2 = len - sublen1; ++ osal_memcpy(&buf[sublen1], pAddr, sublen2); ++ } ++ } else { ++ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); ++ if (!pAddr) { ++ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); ++ } else { ++ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); ++ osal_memcpy(&buf[0], pAddr, len); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee) ++{ ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ ++ issue_type = STP_DBG_PROC_TEST; ++ ++ stp_dbg_poll_cpupcr(count, sleep, 1); ++ ++ if (toAee) { ++ stp_dbg_set_fw_info("STP ProcTest", osal_strlen("STP ProcTest"), issue_type); ++ osal_dbg_assert_aee("[SOC_CONSYS]ProcTest", ++ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n Polling CPUPCR for FW debug usage\n"); ++ } else { ++ WMT_INFO_FUNC("wmt_lib:do not pass cpupcr to AEE\n"); ++ } ++ return 0; ++} ++ ++UINT8 *wmt_lib_get_cpupcr_xml_format(UINT32 *len) ++{ ++ PUINT8 temp; ++ UINT32 i = 0; ++ ++ osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE); ++ temp = g_cpupcr_buf; ++ stp_dbg_cpupcr_infor_format(&temp, len); ++ ++ pr_debug("print xml buffer,len(%d):\n\n", *len); ++ for (i = 0; i < *len; i++) ++ pr_cont("%c", g_cpupcr_buf[i]); ++ ++ return &g_cpupcr_buf[0]; ++} ++ ++UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en) ++{ ++ return stp_dbg_set_host_assert_info(type, reason, en); ++} ++ ++INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl) ++{ ++ wmt_plat_thermal_ctrl_cb_reg(thermal_ctrl); ++ return 0; ++} ++ ++INT8 wmt_lib_co_clock_get(void) ++{ ++ if (gDevWmt.rWmtGenConf.cfgExist) ++ return gDevWmt.rWmtGenConf.co_clock_flag; ++ else ++ return -1; ++} ++ ++#if CFG_WMT_PS_SUPPORT ++UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en) ++{ ++ WMT_WARN_FUNC("%s quick sleep mode\n", en ? "enable" : "disable"); ++ g_quick_sleep_ctrl = en; ++ return 0; ++} ++#endif ++ ++#if CONSYS_ENALBE_SET_JTAG ++UINT32 wmt_lib_jtag_flag_set(UINT32 en) ++{ ++ return wmt_plat_jtag_flag_ctrl(en); ++} ++#endif ++ ++UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver) ++{ ++ return stp_dbg_set_wifiver(wifiver); ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h +new file mode 100644 +index 000000000000..b1b5285638f9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h +@@ -0,0 +1,252 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _STP_EXP_H_ ++#define _STP_EXP_H_ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_stp_exp.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++#define BT_TASK_INDX (0) ++#define FM_TASK_INDX (1) ++#define GPS_TASK_INDX (2) ++#define WIFI_TASK_INDX (3) ++#define WMT_TASK_INDX (4) ++#define STP_TASK_INDX (5) ++#define INFO_TASK_INDX (6) ++#define ANT_TASK_INDX (7) ++#if CFG_WMT_LTE_COEX_HANDLING ++#define COEX_TASK_INDX (8) ++#define MTKSTP_MAX_TASK_NUM (9) ++#else ++#define MTKSTP_MAX_TASK_NUM (8) ++#endif ++ ++#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ ++ ++#define STP_EXP_HID_API_EXPORT 0 ++ ++#else ++ ++#define STP_EXP_HID_API_EXPORT 1 ++ ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++typedef void (*MTK_WCN_STP_EVENT_CB) (void); ++typedef INT32 (*MTK_WCN_STP_IF_TX) (const UINT8 *data, const UINT32 size, UINT32 *written_size); ++/* export for HIF driver */ ++typedef void (*MTK_WCN_STP_IF_RX) (const UINT8 *data, INT32 size); ++ ++typedef enum { ++ STP_UART_IF_TX = 0, ++ STP_SDIO_IF_TX = 1, ++ STP_BTIF_IF_TX = 2, ++ STP_MAX_IF_TX ++} ENUM_STP_TX_IF_TYPE; ++#endif ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_receive_data ++* DESCRIPTION ++* receive data from serial protocol engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* INT32 >= 0: size of data received; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_send_data ++* DESCRIPTION ++* subfunction send data through STP ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* type [IN] subfunction type ++* RETURNS ++* INT32 >= 0: length transmitted; < 0: error ++*****************************************************************************/ ++extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_rxqueue_empty ++* DESCRIPTION ++* Is certain rx queue empty? ++* PARAMETERS ++* type [IN] subfunction type ++* RETURNS ++* INT32 0: queue is NOT empyt; !0: queue is empty ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_is_enable ++* DESCRIPTION ++* Is STP ready? ++* PARAMETERS ++* none. ++* RETURNS ++* MTK_WCN_BOOL TRUE:ready, FALSE:not ready ++*****************************************************************************/ ++extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_parser_data ++* DESCRIPTION ++* push data to serial transport protocol parser engine ++* PARAMETERS ++* buffer [IN] data buffer ++* length [IN] data buffer length ++* RETURNS ++* void ++*****************************************************************************/ ++extern int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); ++ ++/***************************************************************************** ++* FUNCTION ++* set_bluetooth_rx_interface ++* DESCRIPTION ++* Set bluetooth rx interface ++* PARAMETERS ++* rx interface type ++* RETURNS ++* void ++*****************************************************************************/ ++extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_tx_event_cb ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_tx_event_cb(int type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_event_cb ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* func ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_event_cb(int type, MTK_WCN_STP_EVENT_CB func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_tx ++* DESCRIPTION ++* regiter Tx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++ ++/***************************************************************************** ++* FUNCTION ++* mtk_wcn_stp_register_if_rx ++* DESCRIPTION ++* regiter Rx event callback function ++* PARAMETERS ++* stp_if: SDIO or UART, fnnc: Call back function ++* RETURNS ++* int: 0:successful , -1: fail ++*****************************************************************************/ ++extern int mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#else ++extern INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); ++extern INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++extern INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); ++extern MTK_WCN_BOOL _mtk_wcn_stp_is_rxqueue_empty(UINT8 type); ++extern MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void); ++extern INT32 _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); ++extern void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); ++extern INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++extern INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); ++extern INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); ++extern INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); ++extern INT32 _mtk_wcn_stp_coredump_start_get(VOID); ++ ++#endif ++ ++#endif /* _WMT_EXP_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h +new file mode 100644 +index 000000000000..6d10c3ff2659 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h +@@ -0,0 +1,19 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _MTKWMT_H_ ++#define _MTKWMT_H_ ++#include "wmt_core.h" ++ ++#endif /*_MTKWMT_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h +new file mode 100644 +index 000000000000..06238e07879f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h +@@ -0,0 +1,329 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_EXP_H_ ++#define _WMT_EXP_H_ ++ ++#include ++#include "osal.h" ++#include "wmt_plat.h" ++#include "wmt_stp_exp.h" ++/* not to reference to internal wmt */ ++/* #include "wmt_core.h" */ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#if 1 /* moved from wmt_lib.h */ ++#ifndef DFT_TAG ++#define DFT_TAG "[WMT-DFT]" ++#endif ++ ++#define WMT_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_LOUD) \ ++ osal_dbg_print(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_INFO) \ ++ osal_dbg_print(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_WARN) \ ++ osal_warn_print(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_ERR) \ ++ osal_err_print(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define WMT_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_DBG) \ ++ osal_dbg_print(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_TRC_FUNC(f) \ ++do { \ ++ if (gWmtDbgLvl >= WMT_LOG_DBG) \ ++ osal_dbg_print(DFT_TAG "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#if 1 /* moved from wmt_lib.h */ ++extern UINT32 gWmtDbgLvl; ++#endif ++extern OSAL_BIT_OP_VAR gBtWifiGpsState; ++extern OSAL_BIT_OP_VAR gGpsFmState; ++extern UINT32 gWifiProbed; ++extern MTK_WCN_BOOL g_pwr_off_flag; ++extern UINT32 g_IsNeedDoChipReset; ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#if 1 /* moved from wmt_lib.h */ ++#define WMT_LOG_LOUD 4 ++#define WMT_LOG_DBG 3 ++#define WMT_LOG_INFO 2 ++#define WMT_LOG_WARN 1 ++#define WMT_LOG_ERR 0 ++#endif ++#define CFG_CORE_INTERNAL_TXRX 0 /*just do TX/RX in host side */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++typedef enum _ENUM_WMTDRV_TYPE_T { ++ WMTDRV_TYPE_BT = 0, ++ WMTDRV_TYPE_FM = 1, ++ WMTDRV_TYPE_GPS = 2, ++ WMTDRV_TYPE_WIFI = 3, ++ WMTDRV_TYPE_WMT = 4, ++ WMTDRV_TYPE_STP = 5, ++ WMTDRV_TYPE_LPBK = 6, ++ WMTDRV_TYPE_COREDUMP = 7, ++ WMTDRV_TYPE_MAX ++} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; ++ ++/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ ++/* TODO: how do we extend for new chip and newer revision? */ ++/* TODO: This way is hard to extend */ ++typedef enum _ENUM_WMTHWVER_TYPE_T { ++ WMTHWVER_E1 = 0x0, ++ WMTHWVER_E2 = 0x1, ++ WMTHWVER_E3 = 0x2, ++ WMTHWVER_E4 = 0x3, ++ WMTHWVER_E5 = 0x4, ++ WMTHWVER_E6 = 0x5, ++ WMTHWVER_MAX, ++ WMTHWVER_INVALID = 0xff ++} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; ++ ++typedef enum _ENUM_WMTDSNS_TYPE_T { ++ WMTDSNS_FM_DISABLE = 0, ++ WMTDSNS_FM_ENABLE = 1, ++ WMTDSNS_FM_GPS_DISABLE = 2, ++ WMTDSNS_FM_GPS_ENABLE = 3, ++ WMTDSNS_MAX ++} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; ++ ++typedef enum _ENUM_WMTTHERM_TYPE_T { ++ WMTTHERM_ZERO = 0, ++ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, ++ WMTTHERM_READ = WMTTHERM_ENABLE + 1, ++ WMTTHERM_DISABLE = WMTTHERM_READ + 1, ++ WMTTHERM_MAX ++} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; ++ ++typedef enum _ENUM_WMTMSG_TYPE_T { ++ WMTMSG_TYPE_POWER_ON = 0, ++ WMTMSG_TYPE_POWER_OFF = 1, ++ WMTMSG_TYPE_RESET = 2, ++ WMTMSG_TYPE_STP_RDY = 3, ++ WMTMSG_TYPE_HW_FUNC_ON = 4, ++ WMTMSG_TYPE_MAX ++} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; ++ ++typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ ++ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ ++ ENUM_WMTMSG_TYPE_T, /* Message type */ ++ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client ++ can't touch this buffer after this function return. */ ++ UINT32 /* Buffer size in unit of byte */ ++); ++ ++typedef enum _SDIO_PS_OP { ++ OWN_SET = 0, ++ OWN_CLR = 1, ++ OWN_STATE = 2, ++} SDIO_PS_OP; ++ ++typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); ++ ++typedef enum _ENUM_WMTCHIN_TYPE_T { ++ WMTCHIN_CHIPID = 0x0, ++ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, ++ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, ++ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, ++ WMTCHIN_MAX, ++ ++} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; ++ ++#endif ++ ++typedef enum _ENUM_WMTRSTMSG_TYPE_T { ++ WMTRSTMSG_RESET_START = 0x0, ++ WMTRSTMSG_RESET_END = 0x1, ++ WMTRSTMSG_RESET_END_FAIL = 0x2, ++ WMTRSTMSG_RESET_MAX, ++ WMTRSTMSG_RESET_INVALID = 0xff ++} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; ++ ++typedef enum _ENUM_BT_GPS_ONOFF_STATE_T { ++ WMT_BT_ON = 0, ++ WMT_GPS_ON = 1, ++ WMT_WIFI_ON = 2, ++ WMT_FM_ON = 3, ++ WMT_BT_GPS_STATE_MAX, ++ WMT_BT_GPS_STATE_INVALID = 0xff ++} ENUM_BT_GPS_ONOFF_STATE_T, *P_ENUM_BT_GPS_ONOFF_STATE_T; ++ ++#if 1 /* moved from wmt_core.h */ ++typedef enum { ++ WMT_SDIO_SLOT_INVALID = 0, ++ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ ++ WMT_SDIO_SLOT_SDIO2 = 2, ++ WMT_SDIO_SLOT_MAX ++} WMT_SDIO_SLOT_NUM; ++ ++typedef enum { ++ WMT_SDIO_FUNC_STP = 0, ++ WMT_SDIO_FUNC_WIFI = 1, ++ WMT_SDIO_FUNC_MAX ++} WMT_SDIO_FUNC_TYPE; ++#endif ++ ++typedef INT32(*wmt_wlan_probe_cb) (VOID); ++typedef INT32(*wmt_wlan_remove_cb) (VOID); ++typedef INT32(*wmt_wlan_bus_cnt_get_cb) (VOID); ++typedef INT32(*wmt_wlan_bus_cnt_clr_cb) (VOID); ++ ++typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { ++ wmt_wlan_probe_cb wlan_probe_cb; ++ wmt_wlan_remove_cb wlan_remove_cb; ++ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; ++ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; ++} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; ++ ++#ifdef CONFIG_MTK_COMBO_ANT ++typedef enum _ENUM_WMT_ANT_RAM_CTRL_T { ++ WMT_ANT_RAM_GET_STATUS = 0, ++ WMT_ANT_RAM_DOWNLOAD = WMT_ANT_RAM_GET_STATUS + 1, ++ WMT_ANT_RAM_CTRL_MAX ++} ENUM_WMT_ANT_RAM_CTRL, *P_ENUM_WMT_ANT_RAM_CTRL; ++ ++typedef enum _ENUM_WMT_ANT_RAM_SEQ_T { ++ WMT_ANT_RAM_START_PKT = 1, ++ WMT_ANT_RAM_CONTINUE_PKT = WMT_ANT_RAM_START_PKT + 1, ++ WMT_ANT_RAM_END_PKT = WMT_ANT_RAM_CONTINUE_PKT + 1, ++ WMT_ANT_RAM_SEQ_MAX ++} ENUM_WMT_ANT_RAM_SEQ, *P_ENUM_WMT_ANT_RAM_SEQ; ++ ++typedef enum _ENUM_WMT_ANT_RAM_STATUS_T { ++ WMT_ANT_RAM_NOT_EXIST = 0, ++ WMT_ANT_RAM_EXIST = WMT_ANT_RAM_NOT_EXIST + 1, ++ WMT_ANT_RAM_DOWN_OK = WMT_ANT_RAM_EXIST + 1, ++ WMT_ANT_RAM_DOWN_FAIL = WMT_ANT_RAM_DOWN_OK + 1, ++ WMT_ANT_RAM_PARA_ERR = WMT_ANT_RAM_DOWN_FAIL + 1, ++ WMT_ANT_RAM_OP_ERR = WMT_ANT_RAM_PARA_ERR + 1, ++ WMT_ANT_RAM_MAX ++} ENUM_WMT_ANT_RAM_STATUS, *P_ENUM_WMT_ANT_RAM_STATUS; ++#endif ++ ++extern INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); ++extern INT32 mtk_wcn_wmt_wlan_unreg(VOID); ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern wmt_wlan_probe_cb mtk_wcn_wlan_probe; ++extern wmt_wlan_remove_cb mtk_wcn_wlan_remove; ++extern wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt; ++extern wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*subsystem function ctrl APIs*/ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++ ++#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++#define WMT_EXP_HID_API_EXPORT 0 ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); ++ ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++ ++extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++ ++extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++ ++extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); ++ ++extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); ++/* ++return value: ++enable/disable thermal sensor function: true(1)/false(0) ++read thermal sensor function: thermal value ++ ++*/ ++extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); ++ ++extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); ++ ++#else ++#define WMT_EXP_HID_API_EXPORT 1 ++#endif ++ ++#ifdef CONFIG_MTK_COMBO_ANT ++extern ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, ++ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq); ++#endif ++extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ ++extern VOID wmt_lib_ps_irq_cb(VOID); ++ ++extern VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type); ++ ++extern INT32 mtk_wcn_wmt_system_state_reset(VOID); ++extern MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value); ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++extern VOID mtk_wcn_wmt_exp_init(VOID); ++extern VOID mtk_wcn_wmt_exp_deinit(VOID); ++#endif ++extern INT8 mtk_wcn_wmt_co_clock_flag_get(VOID); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_EXP_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h +new file mode 100644 +index 000000000000..075496cac54f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h +@@ -0,0 +1,295 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _WMT_PLAT_H_ ++#define _WMT_PLAT_H_ ++#include "osal_typedef.h" ++#include "stp_exp.h" ++#include ++ ++/* #include "mtk_wcn_consys_hw.h" */ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if 1 /* moved from wmt_exp.h */ ++#ifndef DFT_TAG ++#define DFT_TAG "[WMT-DFT]" ++#endif ++ ++#define WMT_PLAT_LOG_LOUD 4 ++#define WMT_PLAT_LOG_DBG 3 ++#define WMT_PLAT_LOG_INFO 2 ++#define WMT_PLAT_LOG_WARN 1 ++#define WMT_PLAT_LOG_ERR 0 ++ ++extern UINT32 wmtPlatLogLvl; ++ ++#define WMT_PLAT_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_LOUD) \ ++ pr_debug(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_PLAT_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_INFO) \ ++ pr_debug(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_PLAT_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_WARN) \ ++ pr_warn(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++#define WMT_PLAT_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_ERR) \ ++ pr_err(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ ++} while (0) ++#define WMT_PLAT_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (wmtPlatLogLvl >= WMT_PLAT_LOG_DBG) \ ++ pr_debug(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ ++} while (0) ++ ++#endif ++ ++#define CFG_WMT_PS_SUPPORT 1 /* moved from wmt_exp.h */ ++ ++#define CFG_WMT_DUMP_INT_STATUS 0 ++#define CONSYS_ENALBE_SET_JTAG 1 ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_FUNC_STATE_ { ++ FUNC_ON = 0, ++ FUNC_OFF = 1, ++ FUNC_RST = 2, ++ FUNC_STAT = 3, ++ FUNC_CTRL_MAX, ++} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE; ++ ++typedef enum _ENUM_PIN_ID_ { ++ PIN_BGF_EINT = 0, ++ PIN_I2S_GRP = 1, ++ PIN_GPS_SYNC = 2, ++ PIN_GPS_LNA = 3, ++#if CFG_WMT_LTE_COEX_HANDLING ++ PIN_TDM_REQ = 4, ++#endif ++ PIN_ID_MAX ++} ENUM_PIN_ID, *P_ENUM_PIN_ID; ++ ++typedef enum _ENUM_PIN_STATE_ { ++ PIN_STA_INIT = 0, ++ PIN_STA_OUT_L = 1, ++ PIN_STA_OUT_H = 2, ++ PIN_STA_IN_L = 3, ++ PIN_STA_MUX = 4, ++ PIN_STA_EINT_EN = 5, ++ PIN_STA_EINT_DIS = 6, ++ PIN_STA_DEINIT = 7, ++ PIN_STA_SHOW = 8, ++ PIN_STA_MAX ++} ENUM_PIN_STATE, *P_ENUM_PIN_STATE; ++ ++typedef enum _CMB_IF_TYPE_ { ++ CMB_IF_UART = 0, ++ CMB_IF_WIFI_SDIO = 1, ++ CMB_IF_BGF_SDIO = 2, ++ CMB_IF_BGWF_SDIO = 3, ++ CMB_IF_TYPE_MAX ++} CMB_IF_TYPE, *P_CMB_IF_TYPE; ++ ++typedef INT32(*fp_set_pin) (ENUM_PIN_STATE); ++ ++typedef enum _ENUM_WL_OP_ { ++ WL_OP_GET = 0, ++ WL_OP_PUT = 1, ++ WL_OP_MAX ++} ENUM_WL_OP, *P_ENUM_WL_OP; ++ ++typedef enum _ENUM_PALDO_TYPE_ { ++ BT_PALDO = 0, ++ WIFI_PALDO = 1, ++ FM_PALDO = 2, ++ GPS_PALDO = 3, ++ PMIC_CHIPID_PALDO = 4, ++ WIFI_5G_PALDO = 5, ++ PALDO_TYPE_MAX ++} ENUM_PALDO_TYPE, *P_ENUM_PALDO_TYPE; ++ ++typedef enum _ENUM_PALDO_OP_ { ++ PALDO_OFF = 0, ++ PALDO_ON = 1, ++ PALDO_OP_MAX ++} ENUM_PALDO_OP, *P_ENUM_PALDO_OP; ++ ++typedef enum _ENUM_HOST_DUMP_STATE_T { ++ STP_HOST_DUMP_NOT_START = 0, ++ STP_HOST_DUMP_GET = 1, ++ STP_HOST_DUMP_GET_DONE = 2, ++ STP_HOST_DUMP_END = 3, ++ STP_HOST_DUMP_MAX ++} ENUM_HOST_DUMP_STATE, *P_ENUM_HOST_DUMP_STATE_T; ++ ++typedef enum _ENUM_FORCE_TRG_ASSERT_T { ++ STP_FORCE_TRG_ASSERT_EMI = 0, ++ STP_FORCE_TRG_ASSERT_DEBUG_PIN = 1, ++ STP_FORCE_TRG_ASSERT_MAX = 2 ++} ENUM_FORCE_TRG_ASSERT_T, *P_ENUM_FORCE_TRG_ASSERT_T; ++ ++typedef enum _ENUM_CHIP_DUMP_STATE_T { ++ STP_CHIP_DUMP_NOT_START = 0, ++ STP_CHIP_DUMP_PUT = 1, ++ STP_CHIP_DUMP_PUT_DONE = 2, ++ STP_CHIP_DUMP_END = 3, ++ STP_CHIP_DUMP_MAX ++} ENUM_CHIP_DUMP_STATE, *P_ENUM_CHIP_DUMP_STATE_T; ++ ++typedef struct _EMI_CTRL_STATE_OFFSET_ { ++ UINT32 emi_apmem_ctrl_state; ++ UINT32 emi_apmem_ctrl_host_sync_state; ++ UINT32 emi_apmem_ctrl_host_sync_num; ++ UINT32 emi_apmem_ctrl_chip_sync_state; ++ UINT32 emi_apmem_ctrl_chip_sync_num; ++ UINT32 emi_apmem_ctrl_chip_sync_addr; ++ UINT32 emi_apmem_ctrl_chip_sync_len; ++ UINT32 emi_apmem_ctrl_chip_print_buff_start; ++ UINT32 emi_apmem_ctrl_chip_print_buff_len; ++ UINT32 emi_apmem_ctrl_chip_print_buff_idx; ++ UINT32 emi_apmem_ctrl_chip_int_status; ++ UINT32 emi_apmem_ctrl_chip_paded_dump_end; ++ UINT32 emi_apmem_ctrl_host_outband_assert_w1; ++ UINT32 emi_apmem_ctrl_chip_page_dump_num; ++} EMI_CTRL_STATE_OFFSET, *P_EMI_CTRL_STATE_OFFSET; ++ ++typedef struct _BGF_IRQ_BALANCE_ { ++ UINT32 counter; ++ unsigned long flags; ++ spinlock_t lock; ++} BGF_IRQ_BALANCE, *P_BGF_IRQ_BALANCE; ++ ++typedef struct _CONSYS_EMI_ADDR_INFO_ { ++ UINT32 emi_phy_addr; ++ UINT32 paged_trace_off; ++ UINT32 paged_dump_off; ++ UINT32 full_dump_off; ++ P_EMI_CTRL_STATE_OFFSET p_ecso; ++} CONSYS_EMI_ADDR_INFO, *P_CONSYS_EMI_ADDR_INFO; ++ ++typedef struct _GPIO_TDM_REQ_INFO_ { ++ UINT32 ant_sel_index; ++ UINT32 gpio_number; ++ UINT32 cr_address; ++} GPIO_TDM_REQ_INFO, *P_GPIO_TDM_REQ_INFO; ++ ++typedef VOID(*irq_cb) (VOID); ++typedef INT32(*device_audio_if_cb) (CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); ++typedef VOID(*func_ctrl_cb) (UINT32 on, UINT32 type); ++typedef long (*thermal_query_ctrl_cb) (VOID); ++typedef INT32(*deep_idle_ctrl_cb) (UINT32); ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern UINT32 gWmtDbgLvl; ++extern struct device *wmt_dev; ++#ifdef CFG_WMT_READ_EFUSE_VCN33 ++extern INT32 wmt_set_pmic_voltage(UINT32 level); ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++INT32 wmt_plat_init(UINT32 co_clock_type); ++ ++INT32 wmt_plat_deinit(VOID); ++ ++INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state); ++ ++INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); ++ ++INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); ++ ++INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId); ++ ++INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); ++ ++VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb); ++VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb); ++VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl); ++VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl); ++VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl); ++ ++INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo); ++UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset); ++#if CONSYS_ENALBE_SET_JTAG ++UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en); ++#endif ++#if CFG_WMT_DUMP_INT_STATUS ++VOID wmt_plat_BGF_irq_dump_status(VOID); ++MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID); ++#endif ++P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID); ++UINT32 wmt_plat_read_cpupcr(VOID); ++UINT32 wmt_plat_read_dmaregs(UINT32); ++INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state); ++UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type); ++INT32 wmt_plat_update_host_sync_num(VOID); ++INT32 wmt_plat_get_dump_info(UINT32 offset); ++UINT32 wmt_plat_get_soc_chipid(VOID); ++INT32 wmt_plat_set_dbg_mode(UINT32 flag); ++VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf); ++#if CFG_WMT_LTE_COEX_HANDLING ++INT32 wmt_plat_get_tdm_antsel_index(VOID); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WMT_PLAT_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile +new file mode 100644 +index 000000000000..905207118938 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile +@@ -0,0 +1,6 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++obj-y += pub/ ++obj-y += pri/ ++ ++endif +\ No newline at end of file +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h +new file mode 100644 +index 000000000000..95d1ab02a9fa +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h +@@ -0,0 +1,74 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef __BGW_DESENSE_H_ ++#define __BGW_DESENSE_H_ ++ ++#ifdef MSG ++#undef MSG ++#endif ++ ++#ifdef ERR ++#undef ERR ++#endif ++ ++#define PFX1 "[BWG] " ++#define MSG(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) ++#define ERR(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) ++ ++#ifdef NETLINK_TEST ++#undef NETLINK_TEST ++#endif ++ ++#define NETLINK_TEST 17 ++ ++#ifdef MAX_NL_MSG_LEN ++#undef MAX_NL_MSG_LEN ++#endif ++ ++#define MAX_NL_MSG_LEN 1024 ++ ++ ++#ifdef ON ++#undef ON ++#endif ++#ifdef OFF ++#undef OFF ++#endif ++#ifdef ACK ++#undef ACK ++#endif ++ ++#define ON 1 ++#define OFF 0 ++#define ACK 2 ++ ++/* ++used send command to native process ++ ++parameter: command could be macro ON: enable co-exist; OFF: disable co-exist; ++ACK: after get native process init message send ACK ++ ++*/ ++extern void send_command_to_daemon(const int command); ++ ++/* ++before use kernel socket, please call init socket first ++return value: 0: ok; -1: fail ++*/ ++extern int bgw_init_socket(void); ++ ++extern void bgw_destroy_netlink_kernel(void); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h +new file mode 100644 +index 000000000000..cf3e830003ac +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h +@@ -0,0 +1,349 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _OSAL_H_ ++#define _OSAL_H_ ++ ++#include ++#include ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define OS_BIT_OPS_SUPPORT 1 ++ ++#define _osal_inline_ inline ++ ++#define MAX_THREAD_NAME_LEN 16 ++#define MAX_WAKE_LOCK_NAME_LEN 16 ++#define OSAL_OP_BUF_SIZE 64 ++ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) ++#define OSAL_OP_DATA_SIZE 8 ++#else ++#define OSAL_OP_DATA_SIZE 32 ++#endif ++ ++#define DBG_LOG_STR_SIZE 256 ++ ++#define osal_sizeof(x) sizeof(x) ++ ++#define osal_array_size(x) (sizeof(x)/sizeof(x[0])) ++ ++#ifndef NAME_MAX ++#define NAME_MAX 256 ++#endif ++ ++#define WMT_OP_BIT(x) (0x1UL << x) ++#define WMT_OP_HIF_BIT WMT_OP_BIT(0) ++ ++#define RB_SIZE(prb) ((prb)->size) ++#define RB_MASK(prb) (RB_SIZE(prb) - 1) ++#define RB_COUNT(prb) ((prb)->write - (prb)->read) ++#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) ++#define RB_EMPTY(prb) ((prb)->write == (prb)->read) ++ ++#define RB_INIT(prb, qsize) \ ++do { \ ++ (prb)->read = (prb)->write = 0; \ ++ (prb)->size = (qsize); \ ++} while (0) ++ ++#define RB_PUT(prb, value) \ ++do { \ ++ if (!RB_FULL(prb)) { \ ++ (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ ++ ++((prb)->write); \ ++ } \ ++ else { \ ++ osal_assert(!RB_FULL(prb)); \ ++ } \ ++} while (0) ++ ++#define RB_GET(prb, value) \ ++do { \ ++ if (!RB_EMPTY(prb)) { \ ++ value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ ++ ++((prb)->read); \ ++ if (RB_EMPTY(prb)) { \ ++ (prb)->read = (prb)->write = 0; \ ++ } \ ++ } \ ++ else { \ ++ value = NULL; \ ++ osal_assert(!RB_EMPTY(prb)); \ ++ } \ ++} while (0) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++//typedef VOID(*P_TIMEOUT_HANDLER) (unsigned long); ++typedef VOID(*P_TIMEOUT_HANDLER) (struct timer_list *t); ++typedef INT32(*P_COND) (VOID *); ++ ++typedef struct _OSAL_TIMER_ { ++ struct timer_list timer; ++ P_TIMEOUT_HANDLER timeoutHandler; ++ unsigned long timeroutHandlerData; ++} OSAL_TIMER, *P_OSAL_TIMER; ++ ++typedef struct _OSAL_UNSLEEPABLE_LOCK_ { ++ spinlock_t lock; ++ unsigned long flag; ++} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; ++ ++typedef struct _OSAL_SLEEPABLE_LOCK_ { ++ struct mutex lock; ++} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; ++ ++typedef struct _OSAL_SIGNAL_ { ++ struct completion comp; ++ UINT32 timeoutValue; ++} OSAL_SIGNAL, *P_OSAL_SIGNAL; ++ ++typedef struct _OSAL_EVENT_ { ++ wait_queue_head_t waitQueue; ++/* VOID *pWaitQueueData; */ ++ UINT32 timeoutValue; ++ INT32 waitFlag; ++ ++} OSAL_EVENT, *P_OSAL_EVENT; ++ ++typedef struct _OSAL_THREAD_ { ++ struct task_struct *pThread; ++ VOID *pThreadFunc; ++ VOID *pThreadData; ++ char threadName[MAX_THREAD_NAME_LEN]; ++} OSAL_THREAD, *P_OSAL_THREAD; ++ ++typedef struct _OSAL_FIFO_ { ++ /*fifo definition */ ++ VOID *pFifoBody; ++ spinlock_t fifoSpinlock; ++ /*fifo operations */ ++ INT32 (*FifoInit)(struct _OSAL_FIFO_ *pFifo, UINT8 *buf, UINT32); ++ INT32 (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoReset)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoSz)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoLen)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo); ++ INT32 (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const VOID *buf, UINT32 len); ++ INT32 (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, UINT32 len); ++} OSAL_FIFO, *P_OSAL_FIFO; ++ ++typedef struct firmware osal_firmware; ++ ++typedef struct _OSAL_OP_DAT { ++ UINT32 opId; /* Event ID */ ++ UINT32 u4InfoBit; /* Reserved */ ++ SIZE_T au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ ++} OSAL_OP_DAT, *P_OSAL_OP_DAT; ++ ++typedef struct _OSAL_LXOP_ { ++ OSAL_OP_DAT op; ++ OSAL_SIGNAL signal; ++ INT32 result; ++} OSAL_OP, *P_OSAL_OP; ++ ++typedef struct _OSAL_LXOP_Q { ++ OSAL_SLEEPABLE_LOCK sLock; ++ UINT32 write; ++ UINT32 read; ++ UINT32 size; ++ P_OSAL_OP queue[OSAL_OP_BUF_SIZE]; ++} OSAL_OP_Q, *P_OSAL_OP_Q; ++ ++typedef struct _OSAL_WAKE_LOCK_ { ++ #ifdef CONFIG_PM_WAKELOCKS ++ struct wakeup_source wake_lock; ++ #else ++ struct wake_lock wake_lock; ++ #endif ++ UINT8 name[MAX_WAKE_LOCK_NAME_LEN]; ++} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK; ++#if 1 ++typedef struct _OSAL_BIT_OP_VAR_ { ++ unsigned long data; ++ OSAL_UNSLEEPABLE_LOCK opLock; ++} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; ++#else ++#define OSAL_BIT_OP_VAR unsigned long ++#define P_OSAL_BIT_OP_VAR unsigned long * ++ ++#endif ++typedef UINT32(*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread); ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern UINT32 osal_strlen(const char *str); ++extern INT32 osal_strcmp(const char *dst, const char *src); ++extern INT32 osal_strncmp(const char *dst, const char *src, UINT32 len); ++extern char *osal_strcpy(char *dst, const char *src); ++extern char *osal_strncpy(char *dst, const char *src, UINT32 len); ++extern char *osal_strcat(char *dst, const char *src); ++extern char *osal_strncat(char *dst, const char *src, UINT32 len); ++extern char *osal_strchr(const char *str, UINT8 c); ++extern char *osal_strsep(char **str, const char *c); ++extern int osal_strtol(const char *str, UINT32 adecimal, long *res); ++extern INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...); ++extern char *osal_strstr(char *str1, const char *str2); ++ ++extern INT32 osal_err_print(const char *str, ...); ++extern INT32 osal_dbg_print(const char *str, ...); ++extern INT32 osal_warn_print(const char *str, ...); ++ ++extern INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line); ++extern INT32 osal_sprintf(char *str, const char *format, ...); ++extern VOID *osal_malloc(UINT32 size); ++extern VOID osal_free(const VOID *dst); ++extern VOID *osal_memset(VOID *buf, INT32 i, UINT32 len); ++extern VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len); ++extern INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len); ++ ++extern INT32 osal_sleep_ms(UINT32 ms); ++extern INT32 osal_udelay(UINT32 us); ++extern INT32 osal_timer_create(P_OSAL_TIMER); ++extern INT32 osal_timer_start(P_OSAL_TIMER, UINT32); ++extern INT32 osal_timer_stop(P_OSAL_TIMER); ++extern INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer); ++extern INT32 osal_timer_modify(P_OSAL_TIMER, UINT32); ++extern INT32 osal_timer_delete(P_OSAL_TIMER); ++ ++extern INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size); ++extern VOID osal_fifo_deinit(P_OSAL_FIFO pFifo); ++extern INT32 osal_fifo_reset(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); ++extern UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); ++extern UINT32 osal_fifo_len(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo); ++extern UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo); ++ ++extern INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_lock(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK plock); ++extern INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK plock); ++ ++#if defined(CONFIG_PROVE_LOCKING) ++#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); } ++#else ++extern INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK); ++#endif ++extern INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); ++extern INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); ++extern INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK); ++ ++#if defined(CONFIG_PROVE_LOCKING) ++#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); } ++#else ++extern INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK); ++#endif ++extern INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); ++extern INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); ++extern INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK); ++ ++extern INT32 osal_signal_init(P_OSAL_SIGNAL); ++extern INT32 osal_wait_for_signal(P_OSAL_SIGNAL); ++extern INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL); ++extern INT32 osal_raise_signal(P_OSAL_SIGNAL); ++extern INT32 osal_signal_deinit(P_OSAL_SIGNAL); ++ ++extern INT32 osal_event_init(P_OSAL_EVENT); ++extern INT32 osal_wait_for_event(P_OSAL_EVENT, P_COND, void *); ++extern INT32 osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void *); ++extern INT32 osal_trigger_event(P_OSAL_EVENT); ++ ++extern INT32 osal_event_deinit(P_OSAL_EVENT); ++ ++extern INT32 osal_thread_create(P_OSAL_THREAD); ++extern INT32 osal_thread_run(P_OSAL_THREAD); ++extern INT32 osal_thread_should_stop(P_OSAL_THREAD); ++extern INT32 osal_thread_stop(P_OSAL_THREAD); ++/*extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/ ++extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER); ++/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/ ++extern INT32 osal_thread_destroy(P_OSAL_THREAD); ++ ++extern INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++extern INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); ++ ++extern INT32 osal_dbg_assert_aee(const char *module, const char *detail_description); ++extern INT32 osal_gettimeofday(PINT32 sec, PINT32 usec); ++extern INT32 osal_printtimeofday(const PUINT8 prefix); ++ ++extern VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, UINT32 len, UINT32 limit); ++ ++extern UINT32 osal_op_get_id(P_OSAL_OP pOp); ++extern MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp); ++extern VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result); ++extern VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result); ++extern UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length); ++extern VOID osal_thread_show_stack(P_OSAL_THREAD pThread); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#define osal_assert(condition) \ ++do { \ ++ if (!(condition)) \ ++ osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition); \ ++} while (0) ++ ++#endif /* _OSAL_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h +new file mode 100644 +index 000000000000..b3a9c57e062d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h +@@ -0,0 +1,90 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _OSAL_TYPEDEF_H_ ++#define _OSAL_TYPEDEF_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_EARLYSUSPEND ++#include ++#else ++#include ++#endif ++#include ++#include ++#ifdef WMT_PLAT_ALPS ++#include ++#endif ++#include ++#ifdef CONFIG_PM_WAKELOCKS ++#include ++#else ++#include ++#endif ++#include ++ ++#ifndef _TYPEDEFS_H /*fix redifine */ ++typedef char INT8; ++#endif ++ ++typedef void VOID, *PVOID, **PPVOID; ++typedef char *PINT8, **PPINT8; ++typedef short INT16, *PINT16, **PPINT16; ++typedef int INT32, *PINT32, **PPINT32; ++typedef long long INT64, *PINT64, **PPINT64; ++ ++typedef unsigned char UINT8, *PUINT8, **PPUINT8; ++typedef unsigned short UINT16, *PUINT16, **PPUINT16; ++typedef unsigned int UINT32, *PUINT32, **PPUINT32; ++typedef unsigned long long UINT64, *PUINT64, **PPUINT64; ++ ++typedef size_t SIZE_T; ++ ++typedef int MTK_WCN_BOOL; ++#ifndef MTK_WCN_BOOL_TRUE ++#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) ++#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) ++#endif ++ ++#endif /*_OSAL_TYPEDEF_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h +new file mode 100644 +index 000000000000..17be778484c1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h +@@ -0,0 +1,97 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_IDC_H_ ++#define _WMT_IDC_H_ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_stp_exp.h" ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ ++#include "wmt_stp_exp.h" ++#include "conn_md_exp.h" ++ ++#define LTE_IDC_BUFFER_MAX_SIZE 1024 ++/*comment from firmware owner,max pckage num is 5,but should not happened*/ ++#define WMT_IDC_RX_MAX_LEN 384 ++#define LTE_MSG_ID_OFFSET 0x30 ++ ++typedef enum { ++ WMT_IDC_TX_OPCODE_MIN = 0, ++ WMT_IDC_TX_OPCODE_LTE_PARA = 0x0a, ++ WMT_IDC_TX_OPCODE_LTE_FREQ = 0x0b, ++ WMT_IDC_TX_OPCODE_WIFI_MAX_POWER = 0x0c, ++ WMT_IDC_TX_OPCODE_DEBUG_MONITOR = 0x0e, ++ WMT_IDC_TX_OPCODE_SPLIT_FILTER = 0x0f, ++ WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS = 0x16, ++ WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION = 0x17, ++ WMT_IDC_TX_OPCODE_LTE_INDICATION = 0x20, ++ WMT_IDC_TX_OPCODE_MAX ++} WMT_IDC_TX_OPCODE; ++ ++typedef enum { ++ WMT_IDC_RX_OPCODE_BTWF_DEF_PARA = 0x0, ++ WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN = 0x1, ++ /* WMT_IDC_RX_OPCODE_TDM_REQ = 0x10, */ ++ WMT_IDC_RX_OPCODE_DEBUG_MONITOR = 0x02, ++ WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE = 0x03, ++ WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND = 0x04, ++ WMT_IDC_RX_OPCODE_UART_PIN_SEL = 0x05, ++ WMT_IDC_RX_OPCODE_MAX ++} WMT_IDC_RX_OPCODE; ++ ++#if (CFG_WMT_LTE_ENABLE_MSGID_MAPPING == 0) ++typedef enum { ++ IPC_L4C_MSG_ID_INVALID = IPC_L4C_MSG_ID_BEGIN, ++ IPC_L4C_MSG_ID_END, ++ IPC_EL1_MSG_ID_INVALID = IPC_EL1_MSG_ID_BEGIN, ++ /* below are EL1 IPC messages sent from AP */ ++ IPC_MSG_ID_EL1_LTE_TX_ALLOW_IND, ++ IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND, ++ IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND, ++ IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND, ++ IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND, ++ ++ /* below are EL1 messages sent to AP */ ++ IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, ++ IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, ++ IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, ++ IPC_MSG_ID_EL1_LTE_TX_IND, ++ IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND, ++ IPC_MSG_ID_EL1_PIN_TYPE_IND, ++ IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND, ++ IPC_MSG_ID_EL1_DUMMY13_IND, ++ IPC_MSG_ID_EL1_DUMMY14_IND, ++ IPC_MSG_ID_EL1_DUMMY15_IND, ++ IPC_EL1_MSG_ID_END, ++} IPC_MSG_ID_CODE; ++#endif ++ ++typedef struct _MTK_WCN_WMT_IDC_INFO_ { ++ ipc_ilm_t iit; ++ CONN_MD_BRIDGE_OPS ops; ++ UINT8 buffer[LTE_IDC_BUFFER_MAX_SIZE]; ++} MTK_WCN_WMT_IDC_INFO, *P_MTK_WCN_WMT_IDC_INFO; ++ ++extern INT32 wmt_idc_init(VOID); ++extern INT32 wmt_idc_deinit(VOID); ++extern INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm); ++extern INT32 wmt_idc_msg_to_lte_handing(VOID); ++extern UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len); ++ ++#endif /* endif CFG_WMT_LTE_COEX_HANDLING */ ++ ++#endif /* _WMT_IDC_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile +new file mode 100644 +index 000000000000..ff0f0b0aefda +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile +@@ -0,0 +1,21 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++ccflags-y += \ ++ -I$(src)/../../linux/include \ ++ -I$(src)/../../linux/pri/include \ ++ -I$(src)/../../core/include \ ++ -I$(src)/../../include \ ++ -I$(src)/../include \ ++ -I$(src)/../../../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ ++ -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach ++ ++ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 ++ ++obj-y += stp_btif.o \ ++ stp_dbg.o \ ++ stp_exp.o \ ++ wmt_dev.o \ ++ wmt_exp.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h +new file mode 100644 +index 000000000000..3730fbba6928 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h +@@ -0,0 +1,31 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _STP_BTIF_H_ ++#define _STP_BTIF_H_ ++ ++#include "osal_typedef.h" ++#include "mtk_btif_exp.h" ++ ++extern INT32 mtk_wcn_consys_stp_btif_open(VOID); ++extern INT32 mtk_wcn_consys_stp_btif_close(VOID); ++extern INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb); ++extern INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len); ++extern INT32 mtk_wcn_consys_stp_btif_wakeup(VOID); ++extern INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); ++extern INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); ++extern INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag); ++extern MTK_WCN_BOOL mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h +new file mode 100644 +index 000000000000..de5684a16853 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h +@@ -0,0 +1,316 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _STP_DEBUG_H_ ++#define _STP_DEBUG_H_ ++ ++#include ++#include "osal.h" ++ ++#define CONFIG_LOG_STP_INTERNAL ++ ++#if 1 /* #ifndef CONFIG_LOG_STP_INTERNAL */ ++#define STP_PKT_SZ 16 ++#define STP_DMP_SZ 2048 ++#define STP_PKT_NO 2048 ++ ++#define STP_DBG_LOG_ENTRY_NUM 60 ++#define STP_DBG_LOG_ENTRY_SZ 64 ++ ++#else ++ ++#define STP_PKT_SZ 16 ++#define STP_DMP_SZ 16 ++#define STP_PKT_NO 16 ++ ++#define STP_DBG_LOG_ENTRY_NUM 28 ++#define STP_DBG_LOG_ENTRY_SZ 64 ++ ++#endif ++ ++typedef enum { ++ STP_DBG_EN = 0, ++ STP_DBG_PKT = 1, ++ STP_DBG_DR = 2, ++ STP_DBG_FW_ASSERT = 3, ++ STP_DBG_FW_LOG = 4, ++ STP_DBG_FW_DMP = 5, ++ STP_DBG_MAX ++} STP_DBG_OP_T; ++ ++typedef enum { ++ STP_DBG_PKT_FIL_ALL = 0, ++ STP_DBG_PKT_FIL_BT = 1, ++ STP_DBG_PKT_FIL_GPS = 2, ++ STP_DBG_PKT_FIL_FM = 3, ++ STP_DBG_PKT_FIL_WMT = 4, ++ STP_DBG_PKT_FIL_MAX ++} STP_DBG_PKT_FIL_T; ++ ++static char *const gStpDbgType[] = { ++ "< BT>", ++ "< FM>", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "", ++ "" ++}; ++ ++typedef enum { ++ STP_DBG_DR_MAX = 0, ++} STP_DBG_DR_FIL_T; ++ ++typedef enum { ++ STP_DBG_FW_MAX = 0, ++} STP_DBG_FW_FIL_T; ++ ++typedef enum { ++ PKT_DIR_RX = 0, ++ PKT_DIR_TX ++} STP_DBG_PKT_DIR_T; ++ ++/*simple log system ++*/ ++ ++typedef struct { ++ /*type: 0. pkt trace 1. fw info ++ * 2. assert info 3. trace32 dump . ++ * -1. linked to the the previous ++ */ ++ int id; ++ int len; ++ char buffer[STP_DBG_LOG_ENTRY_SZ]; ++} MTKSTP_LOG_ENTRY_T; ++ ++typedef struct log_sys { ++ MTKSTP_LOG_ENTRY_T queue[STP_DBG_LOG_ENTRY_NUM]; ++ unsigned int size; ++ unsigned int in; ++ unsigned int out; ++ spinlock_t lock; ++} MTKSTP_LOG_SYS_T; ++/*--*/ ++ ++typedef struct stp_dbg_pkt_hdr { ++ /* packet information */ ++ unsigned int sec; ++ unsigned int usec; ++ unsigned int dbg_type; ++ unsigned int dmy; ++ unsigned int no; ++ unsigned int dir; ++ ++ /* packet content */ ++ unsigned int type; ++ unsigned int len; ++ unsigned int ack; ++ unsigned int seq; ++ unsigned int chs; ++ unsigned int crc; ++} STP_DBG_HDR_T; ++ ++typedef struct stp_dbg_pkt { ++ struct stp_dbg_pkt_hdr hdr; ++ unsigned char raw[STP_DMP_SZ]; ++} STP_PACKET_T; ++ ++typedef struct mtkstp_dbg_t { ++ /*log_sys */ ++ int pkt_trace_no; ++ void *btm; ++ int is_enable; ++ MTKSTP_LOG_SYS_T *logsys; ++} MTKSTP_DBG_T; ++ ++/* extern void aed_combo_exception(const int *, int, const int *, int, const char *); */ ++ ++#define STP_CORE_DUMP_TIMEOUT (5*60*1000) /* default 5minutes */ ++#define STP_OJB_NAME_SZ 20 ++#define STP_CORE_DUMP_INFO_SZ 500 ++#define STP_CORE_DUMP_INIT_SIZE 1 ++typedef enum wcn_compress_algorithm_t { ++ GZIP = 0, ++ BZIP2 = 1, ++ RAR = 2, ++ LMA = 3, ++ MAX ++} WCN_COMPRESS_ALG_T; ++ ++typedef INT32 (*COMPRESS_HANDLER) (void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, ++ INT32 finish); ++typedef struct wcn_compressor_t { ++ /* current object name */ ++ UINT8 name[STP_OJB_NAME_SZ + 1]; ++ ++ /* buffer for raw data, named L1 */ ++ PUINT8 L1_buf; ++ INT32 L1_buf_sz; ++ INT32 L1_pos; ++ ++ /* target buffer, named L2 */ ++ PUINT8 L2_buf; ++ INT32 L2_buf_sz; ++ INT32 L2_pos; ++ ++ /* compress state */ ++ UINT8 f_done; ++ UINT16 reserved; ++ UINT32 uncomp_size; ++ UINT32 crc32; ++ ++ /* compress algorithm */ ++ UINT8 f_compress_en; ++ WCN_COMPRESS_ALG_T compress_type; ++ void *worker; ++ COMPRESS_HANDLER handler; ++} WCN_COMPRESSOR_T, *P_WCN_COMPRESSOR_T; ++ ++P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz); ++INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T compressor); ++INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T compressor, PUINT8 buf, INT32 len, INT32 finish); ++INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T compressor, PUINT8 *pbuf, PINT32 len); ++INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T compressor, UINT8 enable, WCN_COMPRESS_ALG_T type); ++ ++typedef enum core_dump_state_t { ++ CORE_DUMP_INIT = 0, ++ CORE_DUMP_DOING, ++ CORE_DUMP_TIMEOUT, ++ CORE_DUMP_DONE, ++ CORE_DUMP_MAX ++} CORE_DUMP_STA; ++ ++typedef struct core_dump_t { ++ /* compress dump data and buffered */ ++ P_WCN_COMPRESSOR_T compressor; ++ ++ /* timer for monitor timeout */ ++ OSAL_TIMER dmp_timer; ++ UINT32 timeout; ++ ++ OSAL_SLEEPABLE_LOCK dmp_lock; ++ ++ /* state machine for core dump flow */ ++ CORE_DUMP_STA sm; ++ ++ /* dump info */ ++ INT8 info[STP_CORE_DUMP_INFO_SZ + 1]; ++} WCN_CORE_DUMP_T, *P_WCN_CORE_DUMP_T; ++ ++typedef enum _ENUM_STP_FW_ISSUE_TYPE_ { ++ STP_FW_ISSUE_TYPE_INVALID = 0x0, ++ STP_FW_ASSERT_ISSUE = 0x1, ++ STP_FW_NOACK_ISSUE = 0x2, ++ STP_FW_WARM_RST_ISSUE = 0x3, ++ STP_DBG_PROC_TEST = 0x4, ++ STP_HOST_TRIGGER_FW_ASSERT = 0x5, ++ STP_HOST_TRIGGER_ASSERT_TIMEOUT = 0x6, ++ STP_FW_ISSUE_TYPE_MAX ++} ENUM_STP_FW_ISSUE_TYPE, *P_ENUM_STP_FW_ISSUE_TYPE; ++ ++/* this was added for support dmareg's issue */ ++typedef enum _ENUM_DMA_ISSUE_TYPE_ { ++ CONNSYS_CLK_GATE_STATUS = 0x00, ++ CONSYS_EMI_STATUS, ++ SYSRAM1, ++ SYSRAM2, ++ SYSRAM3, ++ DMA_REGS_MAX ++} ENUM_DMA_ISSUE_TYPE; ++#define STP_PATCH_TIME_SIZE 12 ++#define STP_DBG_CPUPCR_NUM 512 ++#define STP_DBG_DMAREGS_NUM 16 ++#define STP_PATCH_BRANCH_SZIE 8 ++#define STP_ASSERT_INFO_SIZE 64 ++#define STP_DBG_ROM_VER_SIZE 4 ++#define STP_ASSERT_TYPE_SIZE 32 ++ ++typedef struct stp_dbg_host_assert_t { ++ UINT32 drv_type; ++ UINT32 reason; ++ UINT32 assert_from_host; ++} STP_DBG_HOST_ASSERT_T, *P_STP_DBG_HOST_ASSERT_T; ++ ++typedef struct stp_dbg_cpupcr_t { ++ UINT32 chipId; ++ UINT8 romVer[STP_DBG_ROM_VER_SIZE]; ++ UINT8 patchVer[STP_PATCH_TIME_SIZE]; ++ UINT8 branchVer[STP_PATCH_BRANCH_SZIE]; ++ UINT32 wifiVer; ++ UINT32 count; ++ UINT32 stop_flag; ++ UINT32 buffer[STP_DBG_CPUPCR_NUM]; ++ UINT8 assert_info[STP_ASSERT_INFO_SIZE]; ++ UINT32 fwTaskId; ++ UINT32 fwRrq; ++ UINT32 fwIsr; ++ STP_DBG_HOST_ASSERT_T host_assert_info; ++ UINT8 assert_type[STP_ASSERT_TYPE_SIZE]; ++ ENUM_STP_FW_ISSUE_TYPE issue_type; ++ OSAL_SLEEPABLE_LOCK lock; ++} STP_DBG_CPUPCR_T, *P_STP_DBG_CPUPCR_T; ++ ++typedef struct stp_dbg_dmaregs_t { ++ UINT32 count; ++ UINT32 dmaIssue[DMA_REGS_MAX][STP_DBG_DMAREGS_NUM]; ++ OSAL_SLEEPABLE_LOCK lock; ++} STP_DBG_DMAREGS_T, *P_STP_DBG_DMAREGS_T; ++ ++typedef enum _ENUM_ASSERT_INFO_PARSER_TYPE_ { ++ STP_DBG_ASSERT_INFO = 0x0, ++ STP_DBG_FW_TASK_ID = 0x1, ++ STP_DBG_FW_ISR = 0x2, ++ STP_DBG_FW_IRQ = 0x3, ++ STP_DBG_ASSERT_TYPE = 0x4, ++ STP_DBG_PARSER_TYPE_MAX ++} ENUM_ASSERT_INFO_PARSER_TYPE, *P_ENUM_ASSERT_INFO_PARSER_TYPE; ++ ++P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout); ++INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp); ++INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len); ++INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 len); ++INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout); ++INT32 wcn_core_dump_timeout(void); ++INT32 wcn_wmtd_timeout_collect_ftrace(void); ++ ++extern INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout); ++extern INT32 wcn_core_dump_deinit_gcoredump(VOID); ++extern INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL is_coredump_timeout); ++extern int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg); ++extern int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg); ++extern MTKSTP_DBG_T *stp_dbg_init(void *); ++extern int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg); ++extern int stp_dbg_dmp_out_ex(char *buf, int *len); ++extern int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len); ++extern int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg); ++extern char stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len); ++ ++extern INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd); ++extern INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len); ++extern int ++stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, ++ int dbg_type, int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body); ++extern int stp_dbg_log_ctrl(unsigned int on); ++extern INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); ++extern INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep); ++extern INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en); ++extern INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer, ++ PUINT8 pPatchBrh); ++extern INT32 stp_dbg_set_wifiver(UINT32 wifiver); ++extern INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 len); ++extern INT32 stp_dbg_set_fw_info(PUINT8 assert_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type); ++extern INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en); ++extern UINT32 stp_dbg_get_host_trigger_assert(VOID); ++#endif /* end of _STP_DEBUG_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h +new file mode 100644 +index 000000000000..5788eb355549 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h +@@ -0,0 +1,71 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#ifndef _WMT_DEV_H_ ++#define _WMT_DEV_H_ ++ ++#include "osal.h" ++ ++#define STP_UART_FULL 0x01 ++#define STP_UART_MAND 0x02 ++#define STP_BTIF_FULL 0x03 ++#define STP_SDIO 0x04 ++ ++#define CFG_WMT_DBG_SUPPORT 1 /* support wmt_dbg or not */ ++#define CFG_WMT_PROC_FOR_AEE 1 ++ ++extern VOID wmt_dev_rx_event_cb(VOID); ++extern INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent); ++extern INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf); ++extern INT32 wmt_dev_patch_put(osal_firmware **ppPatch); ++extern VOID wmt_dev_patch_info_free(VOID); ++extern VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd); ++extern MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID); ++ ++#if CFG_WMT_DBG_SUPPORT ++typedef struct _COEX_BUF { ++ UINT8 buffer[128]; ++ INT32 availSize; ++} COEX_BUF, *P_COEX_BUF; ++ ++typedef enum _ENUM_CMD_TYPE_T { ++ WMTDRV_CMD_ASSERT = 0, ++ WMTDRV_CMD_EXCEPTION = 1, ++ WMTDRV_CMD_COEXDBG_00 = 2, ++ WMTDRV_CMD_COEXDBG_01 = 3, ++ WMTDRV_CMD_COEXDBG_02 = 4, ++ WMTDRV_CMD_COEXDBG_03 = 5, ++ WMTDRV_CMD_COEXDBG_04 = 6, ++ WMTDRV_CMD_COEXDBG_05 = 7, ++ WMTDRV_CMD_COEXDBG_06 = 8, ++ WMTDRV_CMD_COEXDBG_07 = 9, ++ WMTDRV_CMD_COEXDBG_08 = 10, ++ WMTDRV_CMD_COEXDBG_09 = 11, ++ WMTDRV_CMD_COEXDBG_10 = 12, ++ WMTDRV_CMD_COEXDBG_11 = 13, ++ WMTDRV_CMD_COEXDBG_12 = 14, ++ WMTDRV_CMD_COEXDBG_13 = 15, ++ WMTDRV_CMD_COEXDBG_14 = 16, ++ WMTDRV_CMD_COEXDBG_15 = 17, ++ WMTDRV_CMD_NOACK_TEST = 18, ++ WMTDRV_CMD_WARNRST_TEST = 19, ++ WMTDRV_CMD_FWTRACE_TEST = 20, ++ WMTDRV_CMD_MAX ++} ENUM_WMTDRV_CMD_T, *P_ENUM_WMTDRV_CMD_T; ++ ++#endif ++ ++typedef INT32(*WMT_DEV_DBG_FUNC) (INT32 par1, INT32 par2, INT32 par3); ++ ++#endif /*_WMT_DEV_H_*/ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c +new file mode 100644 +index 000000000000..76debb4674f9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c +@@ -0,0 +1,279 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*file: stp_btif, mainly control stp & btif interaction*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[STP-BTIF]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "wmt_exp.h" ++#include "stp_exp.h" ++#include "stp_btif.h" ++ ++#include ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define BTIF_OWNER_NAME "CONSYS_STP" ++ ++#define STP_MAX_PACKAGE_ALLOWED (2000) ++ ++#define STP_BTIF_TX_RTY_LMT (10) ++#define STP_BTIF_TX_RTY_DLY (5) ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++unsigned long stpBtifId = 0; ++unsigned long *pBtifRef = &stpBtifId; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++INT32 mtk_wcn_consys_stp_btif_open(VOID) ++{ ++ INT32 iRet = -1; ++ ++ iRet = mtk_wcn_btif_open(BTIF_OWNER_NAME, pBtifRef); ++ if (iRet) { ++ WMT_WARN_FUNC("STP open btif fail(%d)\n", iRet); ++ return -1; ++ } ++ WMT_DBG_FUNC("STP open bitf OK\n"); ++ ++ mtk_wcn_stp_register_if_tx(STP_BTIF_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_consys_stp_btif_tx); ++ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_close(VOID) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_close(stpBtifId); ++ if (iRet) { ++ WMT_WARN_FUNC("STP close btif fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ stpBtifId = 0; ++ WMT_DBG_FUNC("STP close btif OK\n"); ++ } ++ } ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference\n!"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_rx_cb_register(stpBtifId, rx_cb); ++ if (iRet) { ++ WMT_WARN_FUNC("STP register rxcb to btif fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_DBG_FUNC("STP register rxcb to btif OK\n"); ++ } ++ } ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len) ++{ ++ INT32 retry_left = STP_BTIF_TX_RTY_LMT; ++ INT32 wr_count = 0; ++ INT32 written = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ return -1; ++ } ++ ++ if (len == 0) { ++ *written_len = 0; ++ WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf); ++ return 0; ++ } ++ ++ *written_len = 0; ++ ++ if (len > STP_MAX_PACKAGE_ALLOWED) { ++ WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm); ++ return -2; ++ } ++ wr_count = mtk_wcn_btif_write(stpBtifId, pBuf, len); ++ ++ if (wr_count < 0) { ++ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count); ++ *written_len = 0; ++ return -3; ++ } ++ if (wr_count == len) { ++ /*perfect case */ ++ *written_len = wr_count; ++ return wr_count; ++ } ++ ++ while ((retry_left--) && (wr_count < len)) { ++ osal_sleep_ms(STP_BTIF_TX_RTY_DLY); ++ written = mtk_wcn_btif_write(stpBtifId, pBuf + wr_count, len - wr_count); ++ if (written < 0) { ++ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written); ++ break; ++ } ++ wr_count += written; ++ } ++ ++ if (wr_count == len) { ++ WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left); ++ /*recovered case */ ++ *written_len = wr_count; ++ return wr_count; ++ } ++ ++ WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n", ++ len, wr_count, retry_left, current->pid, current->comm); ++ *written_len = 0; ++ return -wr_count; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_rx(UINT8 *pBuf, UINT32 len) ++{ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_wakeup(VOID) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_wakeup_consys(stpBtifId); ++ if (iRet) { ++ WMT_WARN_FUNC("STP btif wakeup consys fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_DBG_FUNC("STP btif wakeup consys ok\n"); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ mtk_wcn_btif_dpidle_ctrl(stpBtifId, en_flag); ++ WMT_DBG_FUNC("stp btif dpidle ctrl done,en_flag(%d)\n", en_flag); ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_loopback_ctrl(stpBtifId, mode); ++ if (iRet) { ++ WMT_WARN_FUNC("STP btif lpbk ctrl fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_INFO_FUNC("stp btif lpbk ctrl ok,mode(%d)\n", mode); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag) ++{ ++ INT32 iRet = 0; ++ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ iRet = -1; ++ } else { ++ iRet = mtk_wcn_btif_dbg_ctrl(stpBtifId, flag); ++ if (iRet) { ++ WMT_WARN_FUNC("STP btif log dbg ctrl fail(%d)\n", iRet); ++ iRet = -2; ++ } else { ++ WMT_INFO_FUNC("stp btif log dbg ctrl ok,flag(%d)\n", flag); ++ } ++ } ++ ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len) ++{ ++ if (!stpBtifId) { ++ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); ++ return -1; ++ } else { ++ return (INT32) mtk_wcn_btif_parser_wmt_evt(stpBtifId, str, len); ++ } ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c +new file mode 100644 +index 000000000000..fdb610cc3897 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c +@@ -0,0 +1,2061 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++#include /* GFP_KERNEL */ ++#include /* init_timer, add_time, del_timer_sync */ ++#include /* gettimeofday */ ++#include ++#include /* kzalloc */ ++#include /* task's status */ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "osal_typedef.h" ++#include "stp_dbg.h" ++/* #include "stp_btm.h" */ ++#include "btm_core.h" ++#include "wmt_plat.h" ++ ++#define PFX_STP_DBG "[STPDbg]" ++#define STP_DBG_LOG_LOUD 4 ++#define STP_DBG_LOG_DBG 3 ++#define STP_DBG_LOG_INFO 2 ++#define STP_DBG_LOG_WARN 1 ++#define STP_DBG_LOG_ERR 0 ++ ++unsigned int gStpDbgDbgLevel = STP_DBG_LOG_INFO; ++unsigned int gStpDbgLogOut = 0; ++ ++#define STP_DBG_LOUD_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_LOUD) \ ++ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_DBG_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ ++ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_INFO_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_INFO) \ ++ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_WARN_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_WARN) \ ++ pr_warn(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_ERR_FUNC(fmt, arg...) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_ERR) \ ++ pr_err(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ ++} while (0) ++#define STP_DBG_TRC_FUNC(f) \ ++do { \ ++ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ ++ pr_debug(PFX_STP_DBG "<%s> <%d>\n", __func__, __LINE__); \ ++} while (0) ++ ++MTKSTP_DBG_T *g_stp_dbg = NULL; ++ ++#define STP_DBG_FAMILY_NAME "STP_DBG" ++#define MAX_BIND_PROCESS (4) ++#ifdef WMT_PLAT_ALPS ++#define STP_DBG_AEE_EXP_API (1) ++#else ++#define STP_DBG_AEE_EXP_API (0) ++#endif ++enum { ++ __STP_DBG_ATTR_INVALID, ++ STP_DBG_ATTR_MSG, ++ __STP_DBG_ATTR_MAX, ++}; ++#define STP_DBG_ATTR_MAX (__STP_DBG_ATTR_MAX - 1) ++ ++enum { ++ __STP_DBG_COMMAND_INVALID, ++ STP_DBG_COMMAND_BIND, ++ STP_DBG_COMMAND_RESET, ++ __STP_DBG_COMMAND_MAX, ++}; ++#define MTK_WIFI_COMMAND_MAX (__STP_DBG_COMMAND_MAX - 1) ++ ++static struct genl_family stp_dbg_gnl_family = { ++ .id = GENL_ID_GENERATE, ++ .hdrsize = 0, ++ .name = STP_DBG_FAMILY_NAME, ++ .version = 1, ++ .maxattr = STP_DBG_ATTR_MAX, ++}; ++ ++static void stp_dbg_nl_init(void); ++static void stp_dbg_nl_deinit(void); ++static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info); ++static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info); ++ ++/* attribute policy */ ++static struct nla_policy stp_dbg_genl_policy[STP_DBG_ATTR_MAX + 1] = { ++ [STP_DBG_ATTR_MSG] = {.type = NLA_NUL_STRING}, ++}; ++ ++/* operation definition */ ++#if 0 ++static struct genl_ops stp_dbg_gnl_ops_bind = { ++ .cmd = STP_DBG_COMMAND_BIND, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_bind, ++ .dumpit = NULL, ++}; ++ ++static struct genl_ops stp_dbg_gnl_ops_reset = { ++ .cmd = STP_DBG_COMMAND_RESET, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_reset, ++ .dumpit = NULL, ++}; ++#endif ++static struct genl_ops stp_dbg_gnl_ops_array[] = { ++ { ++ .cmd = STP_DBG_COMMAND_BIND, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_bind, ++ .dumpit = NULL, ++ }, ++ { ++ .cmd = STP_DBG_COMMAND_RESET, ++ .flags = 0, ++ .policy = stp_dbg_genl_policy, ++ .doit = stp_dbg_nl_reset, ++ .dumpit = NULL, ++ }, ++}; ++ ++#if 0 ++#define E2S(x) #x ++static char *dmaRegsStr[] = { ++ E2S(CONNSYS_CLK_GATE_STATUS), ++ E2S(CONSYS_EMI_STATUS), ++ E2S(SYSRAM1), ++ E2S(SYSRAM2), ++ E2S(SYSRAM3) ++}; ++#endif ++static unsigned int stp_dbg_seqnum; ++static int num_bind_process; ++static pid_t bind_pid[MAX_BIND_PROCESS]; ++ ++static P_WCN_CORE_DUMP_T g_core_dump; ++ ++static P_STP_DBG_CPUPCR_T g_stp_dbg_cpupcr; ++ ++/* just show in log at present */ ++static P_STP_DBG_DMAREGS_T g_stp_dbg_dmaregs; ++ ++/* core_dump_timeout_handler - handler of coredump timeout ++ * @ data - core dump object's pointer ++ * ++ * No return value ++ */ ++static void core_dump_timeout_handler(/*unsigned long data*/struct timer_list *t) ++{ ++ //P_WCN_CORE_DUMP_T dmp = (P_WCN_CORE_DUMP_T) data; ++ P_WCN_CORE_DUMP_T dmp = from_timer(dmp,t,dmp_timer.timer); ++ ++ STP_DBG_INFO_FUNC(" start\n"); ++ ++ stp_btm_notify_coredump_timeout_wq(g_stp_dbg->btm); ++ ++ STP_DBG_INFO_FUNC(" end\n"); ++ ++ if (dmp) ++ dmp->sm = CORE_DUMP_TIMEOUT; ++} ++ ++/* wcn_core_dump_init - create core dump sys ++ * @ timeout - core dump time out value ++ * ++ * Return object pointer if success, else NULL ++ */ ++P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout) ++{ ++#define KBYTES (1024*sizeof(char)) ++#define L1_BUF_SIZE (32*KBYTES) ++ ++ P_WCN_CORE_DUMP_T core_dmp = NULL; ++ ++ core_dmp = (P_WCN_CORE_DUMP_T) osal_malloc(sizeof(WCN_CORE_DUMP_T)); ++ if (!core_dmp) { ++ STP_DBG_ERR_FUNC("alloc mem failed!\n"); ++ goto fail; ++ } ++ ++ osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T)); ++ ++ core_dmp->compressor = wcn_compressor_init("core_dump_compressor", L1_BUF_SIZE, 18*packet_num*KBYTES); ++ if (!core_dmp->compressor) { ++ STP_DBG_ERR_FUNC("create compressor failed!\n"); ++ goto fail; ++ } ++ wcn_compressor_reset(core_dmp->compressor, 1, GZIP); ++ ++ core_dmp->dmp_timer.timeoutHandler = core_dump_timeout_handler; ++ core_dmp->dmp_timer.timeroutHandlerData = (unsigned long)core_dmp; ++ osal_timer_create(&core_dmp->dmp_timer); ++ core_dmp->timeout = timeout; ++ ++ osal_sleepable_lock_init(&core_dmp->dmp_lock); ++ ++ core_dmp->sm = CORE_DUMP_INIT; ++ STP_DBG_INFO_FUNC("create coredump object OK!\n"); ++ ++ return core_dmp; ++ ++fail: ++ if (core_dmp && core_dmp->compressor) { ++ wcn_compressor_deinit(core_dmp->compressor); ++ core_dmp->compressor = NULL; ++ } ++ if (core_dmp) ++ osal_free(core_dmp); ++ ++ return NULL; ++} ++INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout) ++{ ++ INT32 Ret = 0; ++ ++ g_core_dump = wcn_core_dump_init(packet_num, timeout); ++ if (g_core_dump == NULL) ++ Ret = -1; ++ return Ret; ++} ++ ++/* wcn_core_dump_deinit - destroy core dump object ++ * @ dmp - pointer of object ++ * ++ * Retunr 0 if success, else error code ++ */ ++INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp) ++{ ++ if (dmp && dmp->compressor) { ++ wcn_compressor_deinit(dmp->compressor); ++ dmp->compressor = NULL; ++ } ++ ++ if (dmp) { ++ osal_sleepable_lock_deinit(&dmp->dmp_lock); ++ osal_timer_stop(&dmp->dmp_timer); ++ osal_free(dmp); ++ } ++ ++ return 0; ++} ++ ++INT32 wcn_core_dump_deinit_gcoredump(VOID) ++{ ++ wcn_core_dump_deinit(g_core_dump); ++ return 0; ++} ++ ++static INT32 wcn_core_dump_check_end(PUINT8 buf, INT32 len) ++{ ++ if (strnstr(buf, "coredump end", len)) ++ return 1; ++ else ++ return 0; ++} ++ ++/* wcn_core_dump_in - add a packet to compressor buffer ++ * @ dmp - pointer of object ++ * @ buf - input buffer ++ * @ len - data length ++ * ++ * Retunr 0 if success; return 1 if find end string; else error code ++ */ ++INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) ++{ ++ INT32 ret = 0; ++ INT32 tmp; ++ ++#define INFO_HEAD ";SOC_CONSYS FW CORE, " ++ ++ if ((!dmp) || (!buf)) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); ++ if (ret) { ++ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); ++ return ret; ++ } ++ ++ switch (dmp->sm) { ++ case CORE_DUMP_INIT: ++ wcn_compressor_reset(dmp->compressor, 1, GZIP); ++ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); ++ ++ /* first package, copy to info buffer */ ++ osal_strcpy(&dmp->info[0], INFO_HEAD); ++ ++ if (NULL == (strnstr(buf, "", 32))) { ++ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw warm reset exception...", ++ osal_strlen("Fw warm reset exception...")); ++ dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw warm reset exception...") + 1] = '\0'; ++ } else { ++ char *pStr = buf; ++ char *pDtr = NULL; ++ ++ pDtr = osal_strchr(pStr, '-'); ++ if (NULL != pDtr) { ++ tmp = pDtr - pStr; ++ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); ++ dmp->info[osal_strlen(dmp->info) + 1] = '\0'; ++ } else { ++ tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); ++ tmp = (len > tmp) ? tmp : len; ++ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); ++ dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0'; ++ } ++ ++ } ++ /* show coredump start info on UI */ ++ /* osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); */ ++#if STP_DBG_AEE_EXP_API ++ aee_kernel_dal_show("SOC_CONSYS coredump start ....\n"); ++#endif ++ /* parsing data, and check end srting */ ++ ret = wcn_core_dump_check_end(buf, len); ++ if (ret == 1) { ++ STP_DBG_INFO_FUNC("core dump end!\n"); ++ dmp->sm = CORE_DUMP_DONE; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } else { ++ dmp->sm = CORE_DUMP_DOING; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } ++ break; ++ ++ case CORE_DUMP_DOING: ++ /* parsing data, and check end srting */ ++ ret = wcn_core_dump_check_end(buf, len); ++ if (ret == 1) { ++ STP_DBG_INFO_FUNC("core dump end!\n"); ++ dmp->sm = CORE_DUMP_DONE; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } else { ++ dmp->sm = CORE_DUMP_DOING; ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ } ++ break; ++ ++ case CORE_DUMP_DONE: ++ wcn_compressor_reset(dmp->compressor, 1, GZIP); ++ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); ++ wcn_compressor_in(dmp->compressor, buf, len, 0); ++ dmp->sm = CORE_DUMP_DOING; ++ break; ++ ++ case CORE_DUMP_TIMEOUT: ++ break; ++ default: ++ break; ++ } ++ ++ osal_unlock_sleepable_lock(&dmp->dmp_lock); ++ ++ return ret; ++} ++ ++/* wcn_core_dump_out - get compressed data from compressor buffer ++ * @ dmp - pointer of object ++ * @ pbuf - target buffer's pointer ++ * @ len - data length ++ * ++ * Retunr 0 if success; else error code ++ */ ++INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 plen) ++{ ++ INT32 ret = 0; ++ ++ if ((!dmp) || (!pbuf) || (!plen)) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); ++ if (ret) { ++ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); ++ return ret; ++ } ++ ++ ret = wcn_compressor_out(dmp->compressor, pbuf, plen); ++ ++ osal_unlock_sleepable_lock(&dmp->dmp_lock); ++ ++ return ret; ++} ++ ++/* wcn_core_dump_reset - reset core dump sys ++ * @ dmp - pointer of object ++ * @ timeout - core dump time out value ++ * ++ * Retunr 0 if success, else error code ++ */ ++INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout) ++{ ++ if (!dmp) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ dmp->sm = CORE_DUMP_INIT; ++ dmp->timeout = timeout; ++ osal_timer_stop(&dmp->dmp_timer); ++ wcn_compressor_reset(dmp->compressor, 1, GZIP); ++ osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1); ++ ++ wcn_core_dump_deinit(dmp); ++ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); ++ ++ return 0; ++} ++ ++/* wcn_wmtd_timeout_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define WMTD_TIMEOUT_INFO_HEAD "Wait wmtd complation timeout ,just collect SYS_FTRACE to DB" ++INT32 wcn_wmtd_timeout_collect_ftrace(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Wait wmtd complation timeout"; ++ len = osal_strlen("Wait wmtd complation timeout"); ++ osal_strcpy(&g_core_dump->info[0], WMTD_TIMEOUT_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++/* wcn_psm_flag_trigger_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define PSM_ABNORMAL_FLAG_INFO_HEAD "Abnormal PSM flag be set ,just collect SYS_FTRACE to DB" ++INT32 wcn_psm_flag_trigger_collect_ftrace(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Abnormal PSM flag be set"; ++ len = osal_strlen("Abnormal PSM flag be set"); ++ osal_strcpy(&g_core_dump->info[0], PSM_ABNORMAL_FLAG_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++#if BTIF_RXD_BE_BLOCKED_DETECT ++MTK_WCN_BOOL is_btif_rxd_be_blocked(void) ++{ ++ MTK_WCN_BOOL flag = MTK_WCN_BOOL_FALSE; ++ ++ if (mtk_btif_rxd_be_blocked_flag_get()) ++ flag = MTK_WCN_BOOL_TRUE; ++ return flag; ++} ++/* wcn_btif_rxd_blocked_collect_ftrace - btif rxd be blocked,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define BTIF_RXD_BLOCKED_INFO_HEAD "Btif_rxd thread be blocked too long,just collect SYS_FTRACE to DB" ++INT32 wcn_btif_rxd_blocked_collect_ftrace(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Btif_rxd thread be blocked too long"; ++ len = osal_strlen("Btif_rxd thread be blocked too long"); ++ osal_strcpy(&g_core_dump->info[0], BTIF_RXD_BLOCKED_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++#endif ++/* wcn_core_dump_timeout - wait for FW assert info timeout ,this func can collect SYS_FTRACE ++ * ++ * Retunr 0 if success ++ */ ++#define TIMEOUT_INFO_HEAD "Trigger assert timeout ,just collect SYS_FTRACE to DB" ++INT32 wcn_core_dump_timeout(void) ++{ ++ PUINT8 pbuf; ++ INT32 len; ++ ++ pbuf = "Trigger assert timeout"; ++ len = osal_strlen("Trigger assert timeout"); ++ osal_strcpy(&g_core_dump->info[0], TIMEOUT_INFO_HEAD); ++#ifdef WMT_PLAT_ALPS ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ return 0; ++} ++ ++#define ENABLE_F_TRACE 0 ++/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys ++ * ++ * Retunr 0 if success, else error code ++ */ ++INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout) ++{ ++ PUINT8 pbuf = NULL; ++ INT32 len = 0; ++ ++ if (!g_core_dump) { ++ STP_DBG_ERR_FUNC("invalid pointer!\n"); ++ return -1; ++ } ++ ++ wcn_core_dump_out(g_core_dump, &pbuf, &len); ++ STP_DBG_INFO_FUNC("buf 0x%zx, len %d\n", (SIZE_T) pbuf, len); ++#ifdef WMT_PLAT_ALPS ++ /* show coredump end info on UI */ ++ /* osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); */ ++#if STP_DBG_AEE_EXP_API ++ if (coredump_is_timeout) ++ aee_kernel_dal_show("++ SOC_CONSYS coredump tiemout ,pass received coredump to AEE ++\n"); ++ else ++ aee_kernel_dal_show("++ SOC_CONSYS coredump get successfully ++\n"); ++ /* call AEE driver API */ ++#if ENABLE_F_TRACE ++ aed_combo_exception_api(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info, DB_OPT_FTRACE); ++#else ++ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); ++#endif ++ ++#endif ++ ++#endif // WMT_PLAT_ALPS ++ ++ /* reset */ ++ wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); ++ ++ return 0; ++} ++ ++static INT32 wcn_gzip_compressor(void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, ++ INT32 finish) ++{ ++ INT32 ret = 0; ++ z_stream *stream = NULL; ++ INT32 tmp = *out_sz; ++ ++ STP_DBG_INFO_FUNC("need to compressor :buf 0x%zx, size %d\n", (SIZE_T) in_buf, in_sz); ++ STP_DBG_INFO_FUNC("before compressor,avalible buf: 0x%zx, size %d\n", (SIZE_T) out_buf, tmp); ++ ++ stream = (z_stream *) worker; ++ if (!stream) { ++ STP_DBG_ERR_FUNC("invalid workspace!\n"); ++ return -1; ++ } ++ ++ if (in_sz > 0) { ++#if 0 ++ ret = zlib_deflateReset(stream); ++ if (ret != Z_OK) { ++ STP_DBG_ERR_FUNC("reset failed!\n"); ++ return -2; ++ } ++#endif ++ ++ stream->next_in = in_buf; ++ stream->avail_in = in_sz; ++ stream->next_out = out_buf; ++ stream->avail_out = tmp; ++ ++ zlib_deflate(stream, Z_FULL_FLUSH); ++ ++ if (finish) { ++ while (1) { ++ int val = zlib_deflate(stream, Z_FINISH); ++ ++ if (val == Z_OK) ++ continue; ++ else if (val == Z_STREAM_END) ++ break; ++ STP_DBG_ERR_FUNC("finish operation failed %d\n", val); ++ return -3; ++ } ++ } ++ ++ *out_sz = tmp - stream->avail_out; ++ } ++ ++ STP_DBG_INFO_FUNC("after compressor,avalible buf: 0x%zx, compress rate %d -> %d\n", (SIZE_T) out_buf, in_sz, ++ *out_sz); ++ ++ return ret; ++} ++ ++/* wcn_compressor_init - create a compressor and do init ++ * @ name - compressor's name ++ * @ L1_buf_sz - L1 buffer size ++ * @ L2_buf_sz - L2 buffer size ++ * ++ * Retunr object's pointer if success, else NULL ++ */ ++P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz) ++{ ++ z_stream *pstream = NULL; ++ P_WCN_COMPRESSOR_T compress = NULL; ++ ++ compress = (P_WCN_COMPRESSOR_T) osal_malloc(sizeof(WCN_COMPRESSOR_T)); ++ if (!compress) { ++ STP_DBG_ERR_FUNC("alloc compressor failed!\n"); ++ goto fail; ++ } ++ ++ osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T)); ++ osal_memcpy(compress->name, name, STP_OJB_NAME_SZ); ++ ++ compress->f_compress_en = 0; ++ compress->compress_type = GZIP; ++ ++ if (compress->compress_type == GZIP) { ++ compress->worker = osal_malloc(sizeof(z_stream)); ++ if (!compress->worker) { ++ STP_DBG_ERR_FUNC("alloc stream failed!\n"); ++ goto fail; ++ } ++ pstream = (z_stream *) compress->worker; ++ ++ pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); ++ if (!pstream->workspace) { ++ STP_DBG_ERR_FUNC("alloc workspace failed!\n"); ++ goto fail; ++ } ++ zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ++ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); ++ } ++ ++ compress->handler = wcn_gzip_compressor; ++ compress->L1_buf_sz = L1_buf_sz; ++ compress->L2_buf_sz = L2_buf_sz; ++ compress->L1_pos = 0; ++ compress->L2_pos = 0; ++ compress->uncomp_size = 0; ++ compress->crc32 = 0xffffffffUL; ++ ++ compress->L1_buf = osal_malloc(compress->L1_buf_sz); ++ if (!compress->L1_buf) { ++ STP_DBG_ERR_FUNC("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz); ++ goto fail; ++ } ++ ++ compress->L2_buf = osal_malloc(compress->L2_buf_sz); ++ if (!compress->L2_buf) { ++ STP_DBG_ERR_FUNC("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz); ++ goto fail; ++ } ++ ++ STP_DBG_INFO_FUNC("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz); ++ return compress; ++ ++fail: ++ if (compress) { ++ if (compress->L2_buf) { ++ osal_free(compress->L2_buf); ++ compress->L2_buf = NULL; ++ } ++ ++ if (compress->L1_buf) { ++ osal_free(compress->L1_buf); ++ compress->L1_buf = NULL; ++ } ++ ++ if (compress->worker) { ++ pstream = (z_stream *) compress->worker; ++ if ((compress->compress_type == GZIP) && pstream->workspace) { ++ zlib_deflateEnd(pstream); ++ osal_free(pstream->workspace); ++ } ++ osal_free(compress->worker); ++ compress->worker = NULL; ++ } ++ ++ if (compress->worker) { ++ osal_free(compress->worker); ++ compress->worker = NULL; ++ } ++ ++ osal_free(compress); ++ compress = NULL; ++ } ++ ++ STP_DBG_ERR_FUNC("init failed!\n"); ++ ++ return NULL; ++} ++ ++/* wcn_compressor_deinit - distroy a compressor ++ * @ cprs - compressor's pointer ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T cprs) ++{ ++ z_stream *pstream = NULL; ++ ++ if (cprs) { ++ if (cprs->L2_buf) { ++ osal_free(cprs->L2_buf); ++ cprs->L2_buf = NULL; ++ } ++ ++ if (cprs->L1_buf) { ++ osal_free(cprs->L1_buf); ++ cprs->L1_buf = NULL; ++ } ++ ++ if (cprs->worker) { ++ pstream = (z_stream *) cprs->worker; ++ if ((cprs->compress_type == GZIP) && pstream->workspace) { ++ zlib_deflateEnd(pstream); ++ osal_free(pstream->workspace); ++ } ++ osal_free(cprs->worker); ++ cprs->worker = NULL; ++ } ++ ++ cprs->handler = NULL; ++ ++ osal_free(cprs); ++ } ++ ++ STP_DBG_INFO_FUNC("destroy OK\n"); ++ ++ return 0; ++} ++ ++/* wcn_compressor_in - put in a raw data, and compress L1 buffer if need ++ * @ cprs - compressor's pointer ++ * @ buf - raw data buffer ++ * @ len - raw data length ++ * @ finish - core dump finish or not, 1: finished; 0: not finish ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, INT32 finish) ++{ ++ INT32 tmp_len = 0; ++ INT32 ret = 0; ++ ++ if (!cprs) { ++ STP_DBG_ERR_FUNC("invalid para!\n"); ++ return -1; ++ } ++ ++ cprs->uncomp_size += len; ++ ++ /* check L1 buf valid space */ ++ if (len > (cprs->L1_buf_sz - cprs->L1_pos)) { ++ STP_DBG_INFO_FUNC("L1 buffer full\n"); ++ ++ if (cprs->f_compress_en && cprs->handler) { ++ /* need compress */ ++ /* compress L1 buffer, and put result to L2 buffer */ ++ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; ++ ret = ++ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], ++ &tmp_len, finish); ++ if (!ret) { ++ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); ++ cprs->L2_pos += tmp_len; ++ if (cprs->L2_pos > cprs->L2_buf_sz) ++ STP_DBG_ERR_FUNC("coredump size too large(%d), L2 buf overflow\n", ++ cprs->L2_pos); ++ ++ if (finish) { ++ /* Add 8 byte suffix ++ === ++ 32 bits UNCOMPRESS SIZE ++ 32 bits CRC ++ */ ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; ++ cprs->L2_pos += 8; ++ } ++ STP_DBG_INFO_FUNC("compress OK!\n"); ++ } else ++ STP_DBG_ERR_FUNC("compress error!\n"); ++ } else { ++ /* no need compress */ ++ /* Flush L1 buffer to L2 buffer */ ++ STP_DBG_INFO_FUNC("No need do compress, Put to L2 buf\n"); ++ ++ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; ++ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; ++ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); ++ cprs->L2_pos += tmp_len; ++ } ++ ++ /* reset L1 buf pos */ ++ cprs->L1_pos = 0; ++ ++ /* put curren data to L1 buf */ ++ if (len > cprs->L1_buf_sz) { ++ STP_DBG_ERR_FUNC("len=%d, too long err!\n", len); ++ } else { ++ STP_DBG_INFO_FUNC("L1 Flushed, and Put %d bytes to L1 buf\n", len); ++ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); ++ cprs->L1_pos += len; ++ } ++ } else { ++ /* put to L1 buffer */ ++ STP_DBG_INFO_FUNC("Put %d bytes to L1 buf\n", len); ++ ++ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); ++ cprs->L1_pos += len; ++ } ++ ++ return ret; ++} ++ ++/* wcn_compressor_out - get the result data from L2 buffer ++ * @ cprs - compressor's pointer ++ * @ pbuf - point to L2 buffer ++ * @ plen - out len ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T cprs, PUINT8 *pbuf, PINT32 plen) ++{ ++ INT32 ret = 0; ++ INT32 tmp_len = 0; ++ ++ if ((!cprs) || (!pbuf) || (!plen)) { ++ STP_DBG_ERR_FUNC("invalid para!\n"); ++ return -1; ++ } ++ /* check if there's L1 data need flush to L2 buffer */ ++ if (cprs->L1_pos > 0) { ++ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; ++ ++ if (cprs->f_compress_en && cprs->handler) { ++ /* need compress */ ++ ret = ++ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], ++ &tmp_len, 1); ++ ++ if (!ret) { ++ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); ++ cprs->L2_pos += tmp_len; ++ ++ /* Add 8 byte suffix ++ === ++ 32 bits UNCOMPRESS SIZE ++ 32 bits CRC ++ */ ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); ++ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; ++ cprs->L2_pos += 8; ++ ++ STP_DBG_INFO_FUNC("compress OK!\n"); ++ } else { ++ STP_DBG_ERR_FUNC("compress error!\n"); ++ } ++ } else { ++ /* no need compress */ ++ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; ++ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); ++ cprs->L2_pos += tmp_len; ++ } ++ ++ cprs->L1_pos = 0; ++ } ++ ++ *pbuf = cprs->L2_buf; ++ *plen = cprs->L2_pos; ++ ++ STP_DBG_INFO_FUNC("0x%zx, len %d\n", (SIZE_T)*pbuf, *plen); ++ ++ return 0; ++} ++ ++/* wcn_compressor_reset - reset compressor ++ * @ cprs - compressor's pointer ++ * @ enable - enable/disable compress ++ * @ type - compress algorithm ++ * ++ * Retunr 0 if success, else NULL ++ */ ++INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type) ++{ ++ if (!cprs) { ++ STP_DBG_ERR_FUNC("invalid para!\n"); ++ return -1; ++ } ++ ++ cprs->f_compress_en = enable; ++ /* cprs->f_compress_en = 0; // disable compress for test */ ++ cprs->compress_type = type; ++ cprs->L1_pos = 0; ++ cprs->L2_pos = 0; ++ cprs->uncomp_size = 0; ++ cprs->crc32 = 0xffffffffUL; ++ ++ /* zlib_deflateEnd((z_stream*)cprs->worker); */ ++ ++ STP_DBG_INFO_FUNC("OK! compress algorithm %d\n", type); ++ ++ return 0; ++} ++ ++static void stp_dbg_dump_data(unsigned char *pBuf, char *title, int len) ++{ ++ int k = 0; ++ ++ pr_debug(" %s-len:%d\n", title, len); ++ ++ for (k = 0; k < len; k++) { ++ if (k % 16 == 0 && k != 0) ++ pr_cont("\n "); ++ pr_cont("0x%02x ", pBuf[k]); ++ } ++ pr_debug("--end\n"); ++} ++ ++static int _stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) ++{ ++ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ stp_dbg->pkt_trace_no = 0; ++ stp_dbg->is_enable = 1; ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++static int _stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) ++{ ++ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ stp_dbg->pkt_trace_no = 0; ++ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); ++ stp_dbg->is_enable = 0; ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++static int _stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) ++{ ++ unsigned long flags; ++ STP_DBG_HDR_T *pHdr = NULL; ++ char *pBuf = NULL; ++ unsigned int length = 0; ++ unsigned int internalFlag = stp_dbg->logsys->size < STP_DBG_LOG_ENTRY_NUM; ++ /* #ifdef CONFIG_LOG_STP_INTERNAL */ ++ /* Here we record log in this circle buffer, if buffer is full , ++ select to overlap earlier log, logic should be okay */ ++ internalFlag = 1; ++ /* #endif */ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ ++ if (internalFlag) { ++ stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0; ++ stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len; ++ memset(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), ++ 0, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); ++ memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), ++ buf, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); ++ ++ stp_dbg->logsys->size++; ++ stp_dbg->logsys->size = ++ (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size; ++ ++ if (0 != gStpDbgLogOut) { ++ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]); ++ pBuf = (char *)&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]) + sizeof(STP_DBG_HDR_T); ++ length = stp_dbg->logsys->queue[stp_dbg->logsys->in].len - sizeof(STP_DBG_HDR_T); ++ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", ++ pHdr->sec, ++ pHdr->usec, ++ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", ++ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); ++ if (0 < length) ++ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", length); ++ } ++ stp_dbg->logsys->in = ++ (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->in + 1); ++ STP_DBG_DBG_FUNC("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in); ++ } else { ++ STP_DBG_WARN_FUNC("logsys FULL!\n"); ++ } ++ ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++int stp_gdb_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg) ++{ ++ int retval = 0; ++/* #ifndef CONFIG_LOG_STP_INTERNAL */ ++ ++ if (stp_dbg->btm != NULL) ++ retval += stp_btm_notify_wmt_dmp_wq((MTKSTP_BTM_T *) stp_dbg->btm); ++/* #endif */ ++ ++ return retval; ++} ++ ++int stp_dbg_log_ctrl(unsigned int on) ++{ ++ if (on != 0) { ++ gStpDbgLogOut = 1; ++ pr_debug("STP-DBG: enable pkt log dump out.\n"); ++ } else { ++ gStpDbgLogOut = 0; ++ pr_debug("STP-DBG: disable pkt log dump out.\n"); ++ } ++ return 0; ++} ++ ++int stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) ++{ ++ return _stp_dbg_dmp_in(stp_dbg, buf, len); ++} ++ ++int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg) ++{ ++#define MAX_DMP_NUM 80 ++ unsigned long flags; ++ char *pBuf = NULL; ++ int len = 0; ++ STP_DBG_HDR_T *pHdr = NULL; ++ UINT32 dumpSize = 0; ++ UINT32 inIndex = 0; ++ UINT32 outIndex = 0; ++ ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ /* Not to dequeue from loging system */ ++ inIndex = stp_dbg->logsys->in; ++ dumpSize = stp_dbg->logsys->size; ++ if (STP_DBG_LOG_ENTRY_NUM == dumpSize) ++ outIndex = inIndex; ++ else ++ outIndex = ((inIndex + STP_DBG_LOG_ENTRY_NUM) - dumpSize) % STP_DBG_LOG_ENTRY_NUM; ++ ++ if (dumpSize > MAX_DMP_NUM) { ++ ++ outIndex += (dumpSize - MAX_DMP_NUM); ++ outIndex %= STP_DBG_LOG_ENTRY_NUM; ++ dumpSize = MAX_DMP_NUM; ++ ++ } ++ STP_DBG_INFO_FUNC("loged packet size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); ++ while (dumpSize > 0) { ++ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[outIndex].buffer[0]); ++ pBuf = &(stp_dbg->logsys->queue[outIndex].buffer[0]) + sizeof(STP_DBG_HDR_T); ++ len = stp_dbg->logsys->queue[outIndex].len - sizeof(STP_DBG_HDR_T); ++ len = len > STP_PKT_SZ ? STP_PKT_SZ : len; ++ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", ++ pHdr->sec, ++ pHdr->usec, ++ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", ++ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); ++ ++ if (0 < len) ++ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len); ++ outIndex = (outIndex >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (outIndex + 1); ++ dumpSize--; ++ ++ } ++ ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return 0; ++} ++ ++int stp_dbg_dmp_out_ex(char *buf, int *len) ++{ ++ return stp_dbg_dmp_out(g_stp_dbg, buf, len); ++} ++ ++int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len) ++{ ++ ++ unsigned long flags; ++ int remaining = 0; ++ *len = 0; ++ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); ++ ++ if (stp_dbg->logsys->size > 0) { ++ memcpy(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]), ++ stp_dbg->logsys->queue[stp_dbg->logsys->out].len); ++ ++ (*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len; ++ stp_dbg->logsys->out = ++ (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->out + 1); ++ stp_dbg->logsys->size--; ++ ++ STP_DBG_DBG_FUNC("logsys size = %d, out = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->out); ++ } else { ++ STP_DBG_LOUD_FUNC("logsys EMPTY!\n"); ++ } ++ ++ remaining = (stp_dbg->logsys->size == 0) ? (0) : (1); ++ ++ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); ++ ++ return remaining; ++} ++ ++static int stp_dbg_fill_hdr(struct stp_dbg_pkt_hdr *hdr, int type, int ack, int seq, int crc, int dir, int len, ++ int dbg_type) ++{ ++ ++ struct timeval now; ++ ++ if (!hdr) { ++ STP_DBG_ERR_FUNC("function invalid\n"); ++ return -EINVAL; ++ } ++ do_gettimeofday(&now); ++ hdr->dbg_type = dbg_type; ++ hdr->ack = ack; ++ hdr->seq = seq; ++ hdr->sec = now.tv_sec; ++ hdr->usec = now.tv_usec; ++ hdr->crc = crc; ++ hdr->dir = dir; /* rx */ ++ hdr->dmy = 0xffffffff; ++ hdr->len = len; ++ hdr->type = type; ++ return 0; ++ ++} ++ ++static int stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, struct stp_dbg_pkt_hdr *hdr, const unsigned char *body) ++{ ++ /* fix the frame size large issues. */ ++ static struct stp_dbg_pkt stp_pkt; ++ uint32_t hdr_sz = sizeof(struct stp_dbg_pkt_hdr); ++ uint32_t body_sz = 0; ++ ++ BUG_ON(!stp_dbg); ++ ++ if (hdr->dbg_type == STP_DBG_PKT) ++ body_sz = (hdr->len <= STP_PKT_SZ) ? (hdr->len) : (STP_PKT_SZ); ++ else ++ body_sz = (hdr->len <= STP_DMP_SZ) ? (hdr->len) : (STP_DMP_SZ); ++ ++ hdr->no = stp_dbg->pkt_trace_no++; ++ memcpy((uint8_t *) &stp_pkt.hdr, (uint8_t *) hdr, hdr_sz); ++ if (body != NULL) ++ memcpy((uint8_t *) &stp_pkt.raw[0], body, body_sz); ++ ++ _stp_dbg_dmp_in(stp_dbg, (char *)&stp_pkt, hdr_sz + body_sz); ++ /* Only FW DMP MSG should inform BTM-CORE to dump packet to native process */ ++ if (hdr->dbg_type == STP_DBG_FW_DMP) ++ stp_gdb_notify_btm_dmp_wq(stp_dbg); ++ ++ return 0; ++} ++ ++int stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, int dbg_type, ++ int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body) ++{ ++ ++ struct stp_dbg_pkt_hdr hdr; ++ ++ if (stp_dbg->is_enable == 0) { ++ /*dbg is disable,and not to log */ ++ } else { ++ hdr.no = 0; ++ hdr.chs = 0; ++ stp_dbg_fill_hdr(&hdr, ++ (int)type, (int)ack_no, (int)seq_no, (int)crc, (int)dir, (int)len, (int)dbg_type); ++ ++ stp_dbg_add_pkt(stp_dbg, &hdr, body); ++ } ++ ++ return 0; ++} ++ ++int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) ++{ ++ return _stp_dbg_enable(stp_dbg); ++} ++ ++int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) ++{ ++ return _stp_dbg_disable(stp_dbg); ++} ++ ++static void stp_dbg_nl_init(void) ++{ ++#if 0 ++ if (genl_register_family(&stp_dbg_gnl_family) != 0) { ++ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); ++ } else { ++ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0) ++ STP_DBG_ERR_FUNC("%s(): BIND operation registration fail\n", __func__); ++ ++ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0) ++ STP_DBG_ERR_FUNC("%s(): RESET operation registration fail\n", __func__); ++ ++ } ++#endif ++ if (genl_register_family_with_ops(&stp_dbg_gnl_family, stp_dbg_gnl_ops_array) != 0) ++ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); ++} ++ ++static void stp_dbg_nl_deinit(void) ++{ ++ genl_unregister_family(&stp_dbg_gnl_family); ++} ++ ++static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct nlattr *na; ++ char *mydata; ++ ++ if (info == NULL) ++ goto out; ++ ++ STP_DBG_INFO_FUNC("%s():->\n", __func__); ++ ++ na = info->attrs[STP_DBG_ATTR_MSG]; ++ ++ if (na) ++ mydata = (char *)nla_data(na); ++ ++ if (num_bind_process < MAX_BIND_PROCESS) { ++ bind_pid[num_bind_process] = info->snd_portid; ++ num_bind_process++; ++ STP_DBG_INFO_FUNC("%s():-> pid = %d\n", __func__, info->snd_portid); ++ } else { ++ STP_DBG_ERR_FUNC("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); ++ } ++ ++out: ++ return 0; ++} ++ ++static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info) ++{ ++ STP_DBG_ERR_FUNC("%s(): should not be invoked\n", __func__); ++ ++ return 0; ++} ++ ++INT8 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len) ++{ ++ struct sk_buff *skb = NULL; ++ void *msg_head = NULL; ++ int rc = -1; ++ int i; ++ ++ if (num_bind_process == 0) { ++ /* no listening process */ ++ STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__); ++ return 0; ++ } ++ ++ for (i = 0; i < num_bind_process; i++) { ++ skb = genlmsg_new(2048, GFP_KERNEL); ++ ++ if (skb) { ++ msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd); ++ if (msg_head == NULL) { ++ nlmsg_free(skb); ++ STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__); ++ return -1; ++ } ++ ++ rc = nla_put(skb, STP_DBG_ATTR_MSG, len, aucMsg); ++ if (rc != 0) { ++ nlmsg_free(skb); ++ STP_DBG_ERR_FUNC("%s(): nla_put_string fail...%d\n", __func__, rc); ++ return -1; ++ } ++ ++ /* finalize the message */ ++ genlmsg_end(skb, msg_head); ++ ++ /* sending message */ ++ rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); ++ if (rc != 0) { ++ STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__); ++ return -1; ++ } ++ } else { ++ STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd) ++{ ++ INT32 ret = 0; ++ ++ /* buffered to compressor */ ++ ret = wcn_core_dump_in(g_core_dump, aucMsg, len); ++ if (ret == 1) ++ wcn_core_dump_flush(0, MTK_WCN_BOOL_FALSE); ++ ++ return ret; ++} ++ ++UINT8 *_stp_dbg_id_to_task(UINT32 id) ++{ ++ UINT8 *taskStr[] = { ++ "Task_WMT", ++ "Task_BT", ++ "Task_Wifi", ++ "Task_Tst", ++ "Task_FM", ++ "Task_Idle", ++ "Task_DrvStp", ++ "Task_DrvBtif", ++ "Task_NatBt" ++ }; ++ return taskStr[id]; ++} ++ ++INT32 _stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type) ++{ ++ char *pStr = NULL; ++ char *pDtr = NULL; ++ char *pTemp = NULL; ++ char *pTemp2 = NULL; ++ char tempBuf[64] = { 0 }; ++ UINT32 len = 0; ++ long res; ++ INT32 ret; ++ ++ PUINT8 parser_sub_string[] = { ++ " ", ++ "id=", ++ "isr=", ++ "irq=", ++ "rc=" ++ }; ++ ++ if (!str) { ++ STP_DBG_ERR_FUNC("NULL string source\n"); ++ return -1; ++ } ++ ++ if (!g_stp_dbg_cpupcr) { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -2; ++ } ++ ++ pStr = str; ++ STP_DBG_DBG_FUNC("source infor:%s\n", pStr); ++ switch (type) { ++ case STP_DBG_ASSERT_INFO: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ' '); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@")); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len); ++ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_'; ++ ++ pTemp = osal_strchr(pDtr, '#'); ++ pTemp += 1; ++ ++ pTemp2 = osal_strchr(pTemp, ' '); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, pTemp2 - pTemp); ++ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0'; ++ STP_DBG_INFO_FUNC("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]); ++ break; ++ case STP_DBG_FW_TASK_ID: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ' '); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); ++ return -4; ++ } ++ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("fw task id :%x\n", (UINT32)res); ++ break; ++ case STP_DBG_FW_ISR: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ','); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw isr id fail(%d)\n", ret); ++ return -4; ++ } ++ g_stp_dbg_cpupcr->fwIsr = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("fw isr str:%x\n", (UINT32)res); ++ break; ++ case STP_DBG_FW_IRQ: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ','); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw irq id fail(%d)\n", ret); ++ return -4; ++ } ++ g_stp_dbg_cpupcr->fwRrq = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("fw irq value:%x\n", (UINT32)res); ++ break; ++ case STP_DBG_ASSERT_TYPE: ++ pDtr = osal_strstr(pStr, parser_sub_string[type]); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen(parser_sub_string[type]); ++ pTemp = osal_strchr(pDtr, ','); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); ++ return -3; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ++ if (0 == osal_memcmp(tempBuf, "*", len)) ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", osal_strlen("general assert")); ++ if (0 == osal_memcmp(tempBuf, "Watch Dog Timeout", len)) ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt")); ++ if (0 == osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL"))) { ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len); ++ ++ pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL("); ++ if (NULL != pDtr) { ++ pDtr += osal_strlen("RB_FULL("); ++ pTemp = osal_strchr(pDtr, ')'); ++ } else { ++ STP_DBG_ERR_FUNC("parser str is NULL,substring(RB_FULL()\n"); ++ return -4; ++ } ++ len = pTemp - pDtr; ++ osal_memcpy(&tempBuf[0], pDtr, len); ++ tempBuf[len] = '\0'; ++ ret = osal_strtol(tempBuf, 16, &res); ++ if (ret) { ++ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); ++ return -5; ++ } ++ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; ++ ++ STP_DBG_INFO_FUNC("update fw task id :%x\n", (UINT32)res); ++ } ++ ++ STP_DBG_INFO_FUNC("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type); ++ break; ++ default: ++ STP_DBG_ERR_FUNC("unknown parser type\n"); ++ break; ++ } ++ ++ return 0; ++} ++ ++P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID) ++{ ++ P_STP_DBG_CPUPCR_T pSdCpupcr = NULL; ++ ++ pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T)); ++ if (!pSdCpupcr) { ++ STP_DBG_ERR_FUNC("stp dbg cpupcr allocate memory fail!\n"); ++ return NULL; ++ } ++ ++ osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T)); ++ ++ osal_sleepable_lock_init(&pSdCpupcr->lock); ++ ++ return pSdCpupcr; ++} ++ ++P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID) ++{ ++ P_STP_DBG_DMAREGS_T pDmaRegs = NULL; ++ ++ pDmaRegs = (P_STP_DBG_DMAREGS_T) osal_malloc(osal_sizeof(STP_DBG_DMAREGS_T)); ++ if (!pDmaRegs) { ++ STP_DBG_ERR_FUNC("stp dbg dmareg allocate memory fail!\n"); ++ return NULL; ++ } ++ ++ osal_memset(pDmaRegs, 0, osal_sizeof(STP_DBG_DMAREGS_T)); ++ ++ osal_sleepable_lock_init(&pDmaRegs->lock); ++ ++ return pDmaRegs; ++} ++ ++VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr) ++{ ++ if (pCpupcr) { ++ osal_sleepable_lock_deinit(&pCpupcr->lock); ++ osal_free(pCpupcr); ++ pCpupcr = NULL; ++ } ++} ++ ++VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs) ++{ ++ if (pDmaRegs) { ++ osal_sleepable_lock_deinit(&pDmaRegs->lock); ++ osal_free(pDmaRegs); ++ pDmaRegs = NULL; ++ } ++} ++ ++INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd) ++{ ++ INT32 i = 0; ++ ++ if (!g_stp_dbg_cpupcr) { ++ STP_DBG_ERR_FUNC("NULL reference pointer\n"); ++ return -1; ++ } ++ ++ if (!cmd) { ++ if (g_stp_dbg_cpupcr->count + times > STP_DBG_CPUPCR_NUM) ++ times = STP_DBG_CPUPCR_NUM - g_stp_dbg_cpupcr->count; ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ for (i = 0; i < times; i++) { ++ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); ++ /* osal_memcpy( ++ * &g_stp_dbg_cpupcr->buffer[i], ++ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), ++ * osal_sizeof(UINT32)); ++ */ ++ g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count + i] = wmt_plat_read_cpupcr(); ++ osal_sleep_ms(sleep); ++ } ++ g_stp_dbg_cpupcr->count += times; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_INFO_FUNC("stp-dbg: for proc test polling cpupcr\n"); ++ if (times > STP_DBG_CPUPCR_NUM) ++ times = STP_DBG_CPUPCR_NUM; ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->count = 0; ++ for (i = 0; i < times; i++) { ++ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); ++ /* osal_memcpy( ++ * &g_stp_dbg_cpupcr->buffer[i], ++ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), ++ * osal_sizeof(UINT32)); ++ */ ++ g_stp_dbg_cpupcr->buffer[i] = wmt_plat_read_cpupcr(); ++ osal_sleep_ms(sleep); ++ } ++ g_stp_dbg_cpupcr->count = times; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ } ++ return 0; ++} ++ ++INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep) ++{ ++#if 0 ++ INT32 i = 0; ++ ++ if (!g_stp_dbg_dmaregs) { ++ STP_DBG_ERR_FUNC("NULL reference pointer\n"); ++ return -1; ++ } ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_dmaregs->lock); ++ ++ if (g_stp_dbg_dmaregs->count + times > STP_DBG_DMAREGS_NUM) { ++ if (g_stp_dbg_dmaregs->count > STP_DBG_DMAREGS_NUM) { ++ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count:%d must less than STP_DBG_DMAREGS_NUM:%d\n", ++ g_stp_dbg_dmaregs->count, STP_DBG_DMAREGS_NUM); ++ g_stp_dbg_dmaregs->count = 0; ++ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count be set default value 0\n"); ++ } ++ times = STP_DBG_DMAREGS_NUM - g_stp_dbg_dmaregs->count; ++ } ++ if (times > STP_DBG_DMAREGS_NUM) { ++ STP_DBG_ERR_FUNC("times overflow, set default value:0\n"); ++ times = 0; ++ } ++ STP_DBG_WARN_FUNC("---------Now Polling DMA relative Regs -------------\n"); ++ for (i = 0; i < times; i++) { ++ INT32 k = 0; ++ ++ for (; k < DMA_REGS_MAX; k++) { ++ STP_DBG_WARN_FUNC("times:%d,i:%d reg: %s, regs:%08x\n", times, i, dmaRegsStr[k], ++ wmt_plat_read_dmaregs(k)); ++ /* g_stp_dbg_dmaregs->dmaIssue[k][g_stp_dbg_dmaregs->count + i] = wmt_plat_read_dmaregs(k); */ ++ } ++ osal_sleep_ms(sleep); ++ } ++ STP_DBG_WARN_FUNC("---------Polling DMA relative Regs End-------------\n"); ++ g_stp_dbg_dmaregs->count += times; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_dmaregs->lock); ++#else ++ return 0; ++#endif ++} ++ ++INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en) ++{ ++ ++ STP_DBG_INFO_FUNC("%s polling cpupcr\n", en == 0 ? "start" : "stop"); ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->stop_flag = en; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ return 0; ++} ++ ++INT32 stp_dbg_set_version_info(UINT32 chipid, UINT8 *pRomVer, UINT8 *pPatchVer, UINT8 *pPatchBrh) ++{ ++ if (g_stp_dbg_cpupcr) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->chipId = chipid; ++ ++ if (pRomVer) ++ osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2); ++ if (pPatchVer) ++ osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8); ++ if (pPatchBrh) ++ osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4); ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ STP_DBG_INFO_FUNC("chipid(0x%x),romver(%s),patchver(%s),branchver(%s)\n", g_stp_dbg_cpupcr->chipId, ++ &g_stp_dbg_cpupcr->romVer[0], &g_stp_dbg_cpupcr->patchVer[0], &g_stp_dbg_cpupcr->branchVer[0]); ++ return 0; ++} ++INT32 stp_dbg_set_wifiver(UINT32 wifiver) ++{ ++ if (g_stp_dbg_cpupcr) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ g_stp_dbg_cpupcr->wifiVer = wifiver; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ STP_DBG_INFO_FUNC("wifiver(%x)\n", g_stp_dbg_cpupcr->wifiVer); ++ return 0; ++} ++ ++INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en) ++{ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = en; ++ g_stp_dbg_cpupcr->host_assert_info.drv_type = drv_type; ++ g_stp_dbg_cpupcr->host_assert_info.reason = reason; ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ return 0; ++} ++ ++UINT32 stp_dbg_get_host_trigger_assert(VOID) ++{ ++ return g_stp_dbg_cpupcr->host_assert_info.assert_from_host; ++} ++ ++INT32 stp_dbg_set_fw_info(UINT8 *issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type) ++{ ++ ENUM_ASSERT_INFO_PARSER_TYPE type_index; ++ PUINT8 tempbuf = NULL; ++ UINT32 i = 0; ++ INT32 iRet = 0; ++ ++ if (NULL == issue_info) { ++ STP_DBG_ERR_FUNC("null issue infor\n"); ++ return -1; ++ } ++ STP_DBG_INFO_FUNC("issue type(%d)\n", issue_type); ++ g_stp_dbg_cpupcr->issue_type = issue_type; ++ osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE); ++ ++ /*print patch version when assert happened */ ++ STP_DBG_INFO_FUNC("=======================================\n"); ++ STP_DBG_INFO_FUNC("[consys patch]patch version:%s\n", g_stp_dbg_cpupcr->patchVer); ++ STP_DBG_INFO_FUNC("[consys patch]ALPS branch:%s\n", g_stp_dbg_cpupcr->branchVer); ++ STP_DBG_INFO_FUNC("=======================================\n"); ++ ++ if ((STP_FW_ASSERT_ISSUE == issue_type) || ++ (STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { ++ if ((STP_FW_ASSERT_ISSUE == issue_type) || (STP_HOST_TRIGGER_FW_ASSERT == issue_type)) { ++ tempbuf = osal_malloc(len + 1); ++ if (!tempbuf) ++ return -2; ++ ++ osal_memcpy(&tempbuf[0], issue_info, len); ++ ++ for (i = 0; i < len; i++) { ++ if (tempbuf[i] == '\0') ++ tempbuf[i] = '?'; ++ } ++ ++ tempbuf[len] = '\0'; ++ ++ for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; type_index++) ++ iRet += _stp_dbg_parser_assert_str(&tempbuf[0], type_index); ++ ++ if (iRet) ++ STP_DBG_ERR_FUNC("passert assert infor fail(%d)\n", iRet); ++ ++ } ++ if ((STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { ++ switch (g_stp_dbg_cpupcr->host_assert_info.drv_type) { ++ case 0: ++ STP_DBG_INFO_FUNC("BT trigger assert\n"); ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ if (31 != g_stp_dbg_cpupcr->host_assert_info.reason) ++ /*BT firmware trigger assert */ ++ { ++ g_stp_dbg_cpupcr->fwTaskId = 1; ++ ++ } else ++ /*BT stack trigger assert */ ++ { ++ g_stp_dbg_cpupcr->fwTaskId = 8; ++ } ++ ++ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; ++ /* g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; */ ++ /* g_stp_dbg_cpupcr->host_assert_info.reason = 0; */ ++ ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ break; ++ case 4: ++ STP_DBG_INFO_FUNC("WMT trigger assert\n"); ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ if (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type) ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ ++ if ((38 == g_stp_dbg_cpupcr->host_assert_info.reason) || ++ (39 == g_stp_dbg_cpupcr->host_assert_info.reason) || ++ (40 == g_stp_dbg_cpupcr->host_assert_info.reason)) ++ g_stp_dbg_cpupcr->fwTaskId = 6; /* HOST schedule reason trigger */ ++ else ++ g_stp_dbg_cpupcr->fwTaskId = 0; /* Must be firmware reason */ ++ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ break; ++ default: ++ break; ++ } ++ ++ } ++ osal_free(tempbuf); ++ } else if (STP_FW_NOACK_ISSUE == issue_type) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ g_stp_dbg_cpupcr->fwTaskId = 6; ++ g_stp_dbg_cpupcr->fwRrq = 0; ++ g_stp_dbg_cpupcr->fwIsr = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else if (STP_DBG_PROC_TEST == issue_type) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ g_stp_dbg_cpupcr->fwTaskId = 0; ++ g_stp_dbg_cpupcr->fwRrq = 0; ++ g_stp_dbg_cpupcr->fwIsr = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else if (STP_FW_WARM_RST_ISSUE == issue_type) { ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); ++ g_stp_dbg_cpupcr->fwTaskId = 0; ++ g_stp_dbg_cpupcr->fwRrq = 0; ++ g_stp_dbg_cpupcr->fwIsr = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ } else { ++ STP_DBG_ERR_FUNC("invalid issue type(%d)\n", issue_type); ++ return -3; ++ } ++ ++ return iRet; ++} ++ ++INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 str_len) ++{ ++ UINT32 len = 0; ++ UINT32 i = 0; ++ ++ if (!g_stp_dbg_cpupcr) { ++ STP_DBG_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ ++ /*format common information about issue */ ++ len = osal_sprintf(*buf, "
\n\t"); ++ len += osal_sprintf(*buf + len, "\n\t\tMT%x\n\t\n\t", g_stp_dbg_cpupcr->chipId); ++ len += osal_sprintf(*buf + len, "\n\t\t"); ++ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->romVer); ++ if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", strlen("ALPS")))) ++ len += osal_sprintf(*buf + len, "Internal Dev\n\t\t", g_stp_dbg_cpupcr->branchVer); ++ else ++ len += osal_sprintf(*buf + len, "W%sMP\n\t\t", g_stp_dbg_cpupcr->branchVer); ++ ++ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->patchVer); ++ ++ if (0 == g_stp_dbg_cpupcr->wifiVer) ++ len += osal_sprintf(*buf + len, "NULL\n\t"); ++ else ++ len += osal_sprintf(*buf + len, "0x%X.%X\n\t", ++ (UINT8)((g_stp_dbg_cpupcr->wifiVer & 0xFF00)>>8), (UINT8)(g_stp_dbg_cpupcr->wifiVer & 0xFF)); ++ ++ len += osal_sprintf(*buf + len, "\n\t"); ++ ++ /*format issue information: no ack, assert */ ++ len += osal_sprintf(*buf + len, "\n\t\t\n\t\t\t"); ++ if ((STP_FW_NOACK_ISSUE == g_stp_dbg_cpupcr->issue_type) || ++ (STP_DBG_PROC_TEST == g_stp_dbg_cpupcr->issue_type) || ++ (STP_FW_WARM_RST_ISSUE == g_stp_dbg_cpupcr->issue_type)) { ++ len += ++ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", ++ g_stp_dbg_cpupcr->assert_info); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); ++ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t"); ++ len += ++ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", ++ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); ++ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); ++ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } else if ((STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) || ++ (STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || ++ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { ++ len += ++ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", ++ g_stp_dbg_cpupcr->assert_info); ++ len += osal_sprintf(*buf + len, "%s\n\t\t\n\t\n\t", g_stp_dbg_cpupcr->assert_type); ++ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t"); ++ len += ++ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", ++ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); ++ if (32 == g_stp_dbg_cpupcr->host_assert_info.reason || 33 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 34 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 35 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 36 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 37 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 38 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 39 == g_stp_dbg_cpupcr->host_assert_info.reason ++ || 40 == g_stp_dbg_cpupcr->host_assert_info.reason) { ++ /*handling wmt turn on/off bt cmd has ack but no evt issue */ ++ /*one of both the irqx and irs is nULL, then use task to find MOF */ ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } else { ++ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); ++ } ++ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); ++ ++ if (STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) { ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } ++ ++ if ((STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || ++ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { ++ len += ++ osal_sprintf(*buf + len, "%d\n\t\t\t", ++ g_stp_dbg_cpupcr->host_assert_info.drv_type); ++ len += ++ osal_sprintf(*buf + len, "%d\n\t\t\t", ++ g_stp_dbg_cpupcr->host_assert_info.reason); ++ } ++ } else { ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\t\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); ++ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t"); ++ len += osal_sprintf(*buf + len, "\n\t\t\tNULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); ++ } ++ ++ len += osal_sprintf(*buf + len, ""); ++ STP_DBG_INFO_FUNC("stp-dbg:sub len1 for debug(%d)\n", len); ++ ++ if (!g_stp_dbg_cpupcr->count) ++ len += osal_sprintf(*buf + len, "NULL"); ++ else { ++ for (i = 0; i < g_stp_dbg_cpupcr->count; i++) ++ len += osal_sprintf(*buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]); ++ } ++ STP_DBG_INFO_FUNC("stp-dbg:sub len2 for debug(%d)\n", len); ++ len += osal_sprintf(*buf + len, "\n\t\t\t"); ++ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n
\n"); ++ STP_DBG_INFO_FUNC("buffer len[%d]\n", len); ++ /* STP_DBG_INFO_FUNC("Format infor:\n%s\n",*buf); */ ++ *str_len = len; ++ ++ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); ++ g_stp_dbg_cpupcr->count = 0; ++ g_stp_dbg_cpupcr->host_assert_info.reason = 0; ++ g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; ++ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); ++ ++ return 0; ++ ++} ++ ++MTKSTP_DBG_T *stp_dbg_init(void *btm_half) ++{ ++ ++ MTKSTP_DBG_T *stp_dbg = NULL; ++ ++ STP_DBG_INFO_FUNC("stp-dbg init\n"); ++ ++ stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL); ++ if (stp_dbg == NULL) ++ goto ERR_EXIT1; ++ if (IS_ERR(stp_dbg)) { ++ STP_DBG_ERR_FUNC("-ENOMEM\n"); ++ goto ERR_EXIT1; ++ } ++ ++ stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T)); ++ if (stp_dbg->logsys == NULL) ++ goto ERR_EXIT2; ++ if (IS_ERR(stp_dbg->logsys)) { ++ STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n"); ++ goto ERR_EXIT2; ++ } ++ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); ++ spin_lock_init(&(stp_dbg->logsys->lock)); ++ stp_dbg->pkt_trace_no = 0; ++ stp_dbg->is_enable = 0; ++ g_stp_dbg = stp_dbg; ++ ++ if (btm_half != NULL) ++ stp_dbg->btm = btm_half; ++ else ++ stp_dbg->btm = NULL; ++ ++ ++ /* bind to netlink */ ++ stp_dbg_nl_init(); ++ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); ++ g_stp_dbg_cpupcr = stp_dbg_cpupcr_init(); ++ g_stp_dbg_dmaregs = stp_dbg_dmaregs_init(); ++ ++ return stp_dbg; ++ ++ERR_EXIT2: ++ kfree(stp_dbg); ++ return NULL; ++ ++ERR_EXIT1: ++ kfree(stp_dbg); ++ return NULL; ++} ++ ++int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg) ++{ ++ ++ STP_DBG_INFO_FUNC("stp-dbg deinit\n"); ++ ++ wcn_core_dump_deinit(g_core_dump); ++ ++ stp_dbg_cpupcr_deinit(g_stp_dbg_cpupcr); ++ stp_dbg_dmaregs_deinit(g_stp_dbg_dmaregs); ++ /* unbind with netlink */ ++ stp_dbg_nl_deinit(); ++ ++ if (stp_dbg->logsys) ++ vfree(stp_dbg->logsys); ++ ++ kfree(stp_dbg); ++ ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c +new file mode 100644 +index 000000000000..f7f4aff010d4 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c +@@ -0,0 +1,279 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include /* udelay() */ ++ ++#include ++ ++ ++#include "osal_typedef.h" ++#include "stp_core.h" ++#include "stp_exp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static MTK_WCN_STP_IF_TX stp_uart_if_tx; ++static MTK_WCN_STP_IF_TX stp_sdio_if_tx; ++static MTK_WCN_STP_IF_TX stp_btif_if_tx; ++static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX; ++static MTK_WCN_STP_IF_RX stp_if_rx; ++static MTK_WCN_STP_EVENT_CB event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; ++static MTK_WCN_STP_EVENT_CB tx_event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++INT32 mtk_wcn_sys_if_rx(UINT8 *data, INT32 size) ++{ ++ if (stp_if_rx == 0x0) ++ return -1; ++ ++ (*stp_if_rx) (data, size); ++ return 0; ++} ++ ++static INT32 mtk_wcn_sys_if_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) ++{ ++ ++ if (STP_UART_IF_TX == g_stp_if_type) ++ return stp_uart_if_tx != NULL ? (*stp_uart_if_tx) (data, size, written_size) : -1; ++ else if (STP_SDIO_IF_TX == g_stp_if_type) ++ return stp_sdio_if_tx != NULL ? (*stp_sdio_if_tx) (data, size, written_size) : -1; ++ else if (STP_BTIF_IF_TX == g_stp_if_type) ++ return stp_btif_if_tx != NULL ? (*stp_btif_if_tx) (data, size, written_size) : -1; ++ /*if (g_stp_if_type >= STP_MAX_IF_TX) *//* George: remove ALWAYS TRUE condition */ ++ return -1; ++} ++ ++static INT32 mtk_wcn_sys_event_set(UINT8 function_type) ++{ ++ if ((function_type < MTKSTP_MAX_TASK_NUM) && (event_callback_tbl[function_type] != 0x0)) { ++ (*event_callback_tbl[function_type]) (); ++ } else { ++ /* FIXME: error handling */ ++ pr_err("[%s] STP set event fail. It seems the function is not active.\n", __func__); ++ } ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_sys_event_tx_resume(UINT8 winspace) ++{ ++ int type = 0; ++ ++ for (type = 0; type < MTKSTP_MAX_TASK_NUM; type++) { ++ if (tx_event_callback_tbl[type]) ++ tx_event_callback_tbl[type] (); ++ } ++ ++ return 0; ++} ++ ++static INT32 mtk_wcn_sys_check_function_status(UINT8 type, UINT8 op) ++{ ++ ++ /* op == FUNCTION_ACTIVE, to check if funciton[type] is active ? */ ++ if (!(type < MTKSTP_MAX_TASK_NUM)) ++ return STATUS_FUNCTION_INVALID; ++ ++ if (op == OP_FUNCTION_ACTIVE) { ++ if (event_callback_tbl[type] != 0x0) ++ return STATUS_FUNCTION_ACTIVE; ++ else ++ return STATUS_FUNCTION_INACTIVE; ++ ++ } ++ /* you can define more operation here ..., to queury function's status/information */ ++ ++ return STATUS_OP_INVALID; ++} ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) ++#else ++INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) ++#endif ++{ ++ stp_if_rx = func; ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); ++#endif ++ ++VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type) ++{ ++ static const char * const ifType[] = { ++ "UART", ++ "SDIO", ++ "BTIF", ++ "UNKNOWN" ++ }; ++ g_stp_if_type = stp_if_type; ++ pr_debug("[%s] set STP_IF_TX to %s.\n", __func__, ifType[stp_if_type]); ++} ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) ++#else ++INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) ++#endif ++{ ++ if (STP_UART_IF_TX == stp_if) { ++ stp_uart_if_tx = func; ++ } else if (STP_SDIO_IF_TX == stp_if) { ++ stp_sdio_if_tx = func; ++ } else if (STP_BTIF_IF_TX == stp_if) { ++ stp_btif_if_tx = func; ++ } else { ++ pr_debug("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); ++ return -1; ++ } ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); ++#endif ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#else ++INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#endif ++{ ++ if (type < MTKSTP_MAX_TASK_NUM) { ++ event_callback_tbl[type] = func; ++ ++ /*clear rx queue */ ++ pr_debug("Flush type = %d Rx Queue\n", type); ++ mtk_wcn_stp_flush_rx_queue(type); ++ } ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); ++#endif ++ ++#if STP_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#else ++INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) ++#endif ++{ ++ if (type < MTKSTP_MAX_TASK_NUM) ++ tx_event_callback_tbl[type] = func; ++ else ++ BUG_ON(0); ++ ++ return 0; ++} ++#if !STP_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); ++#endif ++ ++INT32 stp_drv_init(VOID) ++{ ++ INT32 ret = 0; ++ ++ mtkstp_callback cb = { ++ .cb_if_tx = mtk_wcn_sys_if_tx, ++ .cb_event_set = mtk_wcn_sys_event_set, ++ .cb_event_tx_resume = mtk_wcn_sys_event_tx_resume, ++ .cb_check_funciton_status = mtk_wcn_sys_check_function_status ++ }; ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ MTK_WCN_STP_EXP_CB_INFO stpExpCb = { ++ .stp_send_data_cb = _mtk_wcn_stp_send_data, ++ .stp_send_data_raw_cb = _mtk_wcn_stp_send_data_raw, ++ .stp_parser_data_cb = _mtk_wcn_stp_parser_data, ++ .stp_receive_data_cb = _mtk_wcn_stp_receive_data, ++ .stp_is_rxqueue_empty_cb = _mtk_wcn_stp_is_rxqueue_empty, ++ .stp_is_ready_cb = _mtk_wcn_stp_is_ready, ++ .stp_set_bluez_cb = _mtk_wcn_stp_set_bluez, ++ .stp_if_tx_cb = _mtk_wcn_stp_register_if_tx, ++ .stp_if_rx_cb = _mtk_wcn_stp_register_if_rx, ++ .stp_reg_event_cb = _mtk_wcn_stp_register_event_cb, ++ .stp_reg_tx_event_cb = _mtk_wcn_stp_register_tx_event_cb, ++ .stp_coredump_start_get_cb = _mtk_wcn_stp_coredump_start_get, ++ }; ++#endif ++ ++ ret = mtk_wcn_stp_init(&cb); ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_stp_exp_cb_reg(&stpExpCb); ++#endif ++ return ret; ++} ++ ++VOID stp_drv_exit(VOID) ++{ ++ mtk_wcn_stp_deinit(); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ mtk_wcn_stp_exp_cb_unreg(); ++#endif ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c +new file mode 100644 +index 000000000000..f70c88796f09 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c +@@ -0,0 +1,2566 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief brief description ++ ++ Detailed descriptions here. ++ ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-DEV]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "osal_typedef.h" ++#include "osal.h" ++#include "wmt_dev.h" ++#include "wmt_core.h" ++#include "wmt_exp.h" ++#include "wmt_lib.h" ++#include "wmt_conf.h" ++#include "psm_core.h" ++#include "stp_core.h" ++#include "stp_exp.h" ++#include "bgw_desense.h" ++#include ++#include "wmt_idc.h" ++#ifdef CONFIG_COMPAT ++#include ++#endif ++#if WMT_CREATE_NODE_DYNAMIC ++#include ++#endif ++#define BUF_LEN_MAX 384 ++#include ++#ifdef CONFIG_COMPAT ++#define COMPAT_WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, compat_uptr_t) ++#define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t) ++#endif ++ ++#define WMT_IOC_MAGIC 0xa0 ++#define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, char*) ++#define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC, 5, int) ++#define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC, 6, int) ++#define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC, 7, int) ++#define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, char*) ++#define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC, 12, int) ++#define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC, 13, int) ++#define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC, 14, int) ++#define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, char*) ++#define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*) ++#define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*) ++#define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int) ++#define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int) ++#define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int) ++#define WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, char*) ++#define WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, char*) ++#define WMT_IOCTL_FW_DBGLOG_CTRL _IOR(WMT_IOC_MAGIC, 29, int) ++#define WMT_IOCTL_DYNAMIC_DUMP_CTRL _IOR(WMT_IOC_MAGIC, 30, char*) ++ ++#define MTK_WMT_VERSION "SOC Consys WMT Driver - v1.0" ++#define MTK_WMT_DATE "2013/01/20" ++#define WMT_DEV_MAJOR 190 /* never used number */ ++#define WMT_DEV_NUM 1 ++#define WMT_DEV_INIT_TO_MS (2 * 1000) ++#define DYNAMIC_DUMP_BUF 109 ++ ++#if CFG_WMT_DBG_SUPPORT ++#define WMT_DBG_PROCNAME "driver/wmt_dbg" ++#endif ++ ++#define WMT_DRIVER_NAME "mtk_stp_wmt" ++ ++P_OSAL_EVENT gpRxEvent = NULL; ++ ++UINT32 u4RxFlag = 0x0; ++static atomic_t gRxCount = ATOMIC_INIT(0); ++ ++/* Linux UINT8 device */ ++static int gWmtMajor = WMT_DEV_MAJOR; ++static struct cdev gWmtCdev; ++static atomic_t gWmtRefCnt = ATOMIC_INIT(0); ++/* WMT driver information */ ++static UINT8 gLpbkBuf[1024+5] = { 0 }; ++ ++static UINT32 gLpbkBufLog; /* George LPBK debug */ ++static INT32 gWmtInitDone; ++static wait_queue_head_t gWmtInitWq; ++ ++P_WMT_PATCH_INFO pPatchInfo = NULL; ++UINT32 pAtchNum = 0; ++ ++#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) ++#define WMT_EMI_DEBUG_BUF_SIZE (8*1024) ++#else ++#define WMT_EMI_DEBUG_BUF_SIZE (32*1024) ++#endif ++ ++static UINT8 gEmiBuf[WMT_EMI_DEBUG_BUF_SIZE]; ++UINT8 *buf_emi; ++ ++#if CFG_WMT_PROC_FOR_AEE ++static struct proc_dir_entry *gWmtAeeEntry; ++#define WMT_AEE_PROCNAME "driver/wmt_aee" ++#define WMT_PROC_AEE_SIZE 3072 ++static UINT32 g_buf_len; ++static UINT8 *pBuf; ++#endif ++ ++#if WMT_CREATE_NODE_DYNAMIC ++struct class *wmt_class = NULL; ++struct device *wmt_dev = NULL; ++#endif ++ ++#if CFG_WMT_DBG_SUPPORT ++static struct proc_dir_entry *gWmtDbgEntry; ++COEX_BUF gCoexBuf; ++ ++static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd); ++static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3); ++ ++#if CFG_CORE_INTERNAL_TXRX ++static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3); ++#endif ++static INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3); ++static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3); ++#if CONSYS_ENALBE_SET_JTAG ++static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3); ++#endif ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3); ++#endif ++#endif ++static void wmt_dbg_fwinfor_print_buff(UINT32 len) ++{ ++ UINT32 i = 0; ++ UINT32 idx = 0; ++ ++ for (i = 0; i < len; i++) { ++ buf_emi[idx] = gEmiBuf[i]; ++ if (gEmiBuf[i] == '\n') { ++ pr_cont("%s", buf_emi); ++ osal_memset(buf_emi, 0, BUF_LEN_MAX); ++ idx = 0; ++ } else { ++ idx++; ++ } ++ if (idx == BUF_LEN_MAX-1) { ++ buf_emi[idx] = '\0'; ++ pr_cont("%s", buf_emi); ++ osal_memset(buf_emi, 0, BUF_LEN_MAX); ++ idx = 0; ++ } ++ } ++} ++ ++/*LCM on/off ctrl for wmt varabile*/ ++static struct work_struct gPwrOnOffWork; ++UINT32 g_es_lr_flag_for_quick_sleep = 1; /* for ctrl quick sleep flag */ ++UINT32 g_es_lr_flag_for_lpbk_onoff = 0; /* for ctrl lpbk on off */ ++OSAL_SLEEPABLE_LOCK g_es_lr_lock; ++ ++#ifdef CONFIG_EARLYSUSPEND ++ ++static void wmt_dev_early_suspend(struct early_suspend *h) ++{ ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 1; ++ g_es_lr_flag_for_lpbk_onoff = 0; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n"); ++ ++ schedule_work(&gPwrOnOffWork); ++} ++ ++static void wmt_dev_late_resume(struct early_suspend *h) ++{ ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 0; ++ g_es_lr_flag_for_lpbk_onoff = 1; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n"); ++ ++ schedule_work(&gPwrOnOffWork); ++ ++} ++ ++struct early_suspend wmt_early_suspend_handler = { ++ .suspend = wmt_dev_early_suspend, ++ .resume = wmt_dev_late_resume, ++}; ++ ++#else ++ ++static struct notifier_block wmt_fb_notifier; ++static int wmt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) ++{ ++ struct fb_event *evdata = data; ++ INT32 blank; ++ ++ WMT_DBG_FUNC("wmt_fb_notifier_callback\n"); ++ ++ /* If we aren't interested in this event, skip it immediately ... */ ++ if (event != FB_EVENT_BLANK) ++ return 0; ++ ++ blank = *(INT32 *)evdata->data; ++ WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank); ++ ++ switch (blank) { ++ case FB_BLANK_UNBLANK: ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 0; ++ g_es_lr_flag_for_lpbk_onoff = 1; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n"); ++ schedule_work(&gPwrOnOffWork); ++ break; ++ case FB_BLANK_POWERDOWN: ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ g_es_lr_flag_for_quick_sleep = 1; ++ g_es_lr_flag_for_lpbk_onoff = 0; ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n"); ++ schedule_work(&gPwrOnOffWork); ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static void wmt_pwr_on_off_handler(struct work_struct *work) ++{ ++ INT32 retryCounter = 1; ++ ++ WMT_DBG_FUNC("wmt_pwr_on_off_handler start to run\n"); ++ ++ osal_lock_sleepable_lock(&g_es_lr_lock); ++ ++ if (g_es_lr_flag_for_lpbk_onoff) { ++ do { ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) { ++ WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter); ++ retryCounter--; ++ osal_sleep_ms(1000); ++ } else { ++ WMT_INFO_FUNC("WMT turn on LPBK suceed\n"); ++ break; ++ } ++ } while (retryCounter > 0); ++ } else { ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) ++ WMT_WARN_FUNC("WMT turn off LPBK fail\n"); ++ else ++ WMT_DBG_FUNC("WMT turn off LPBK suceed\n"); ++ ++ } ++ ++ osal_unlock_sleepable_lock(&g_es_lr_lock); ++ ++} ++ ++ ++MTK_WCN_BOOL wmt_dev_get_early_suspend_state(void) ++{ ++ MTK_WCN_BOOL bRet = (0 == g_es_lr_flag_for_quick_sleep) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; ++ /* WMT_INFO_FUNC("bRet:%d\n", bRet); */ ++ return bRet; ++} ++ ++#if CFG_WMT_DBG_SUPPORT ++ ++static const WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] = { ++ [0] = wmt_dbg_psm_ctrl, ++ [1] = wmt_dbg_quick_sleep_ctrl, ++ [2] = wmt_dbg_dsns_ctrl, ++ [3] = wmt_dbg_hwver_get, ++ [4] = wmt_dbg_assert_test, ++ [5] = wmt_dbg_inband_rst, ++ [6] = wmt_dbg_chip_rst, ++ [7] = wmt_dbg_func_ctrl, ++ [8] = wmt_dbg_raed_chipid, ++ [9] = wmt_dbg_wmt_dbg_level, ++ [0xa] = wmt_dbg_stp_dbg_level, ++ [0xb] = wmt_dbg_reg_read, ++ [0xc] = wmt_dbg_reg_write, ++ [0xd] = wmt_dbg_coex_test, ++ [0xe] = wmt_dbg_rst_ctrl, ++ [0xf] = wmt_dbg_ut_test, ++ [0x10] = wmt_dbg_efuse_read, ++ [0x11] = wmt_dbg_efuse_write, ++ [0x12] = wmt_dbg_sdio_ctrl, ++ [0x13] = wmt_dbg_stp_dbg_ctrl, ++ [0x14] = wmt_dbg_stp_dbg_log_ctrl, ++ [0x15] = wmt_dbg_wmt_assert_ctrl, ++ [0x16] = wmt_dbg_fwinfor_from_emi, ++ [0x17] = wmt_dbg_set_mcu_clock, ++ [0x18] = wmt_dbg_poll_cpupcr, ++ [0x19] = wmt_dbg_jtag_flag_ctrl, ++#if CFG_WMT_LTE_COEX_HANDLING ++ [0x20] = wmt_dbg_lte_coex_test, ++#endif ++}; ++ ++INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++#if CFG_WMT_PS_SUPPORT ++ if (0 == par2) { ++ wmt_lib_ps_ctrl(0); ++ WMT_INFO_FUNC("disable PSM\n"); ++ } else { ++ par2 = (1 > par2 || 20000 < par2) ? STP_PSM_IDLE_TIME_SLEEP : par2; ++ wmt_lib_ps_set_idle_time(par2); ++ wmt_lib_ps_ctrl(1); ++ WMT_WARN_FUNC("enable PSM, idle to sleep time = %d ms\n", par2); ++ } ++#else ++ WMT_INFO_FUNC("WMT PS not supported\n"); ++#endif ++ return 0; ++} ++ ++INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++#if CFG_WMT_PS_SUPPORT ++ UINT32 en_flag = par2; ++ ++ wmt_lib_quick_sleep_ctrl(en_flag); ++#else ++ WMT_WARN_FUNC("WMT PS not supported\n"); ++#endif ++ return 0; ++} ++ ++INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2) { ++ WMT_INFO_FUNC("DSNS type (%d)\n", par2); ++ mtk_wcn_wmt_dsns_ctrl(par2); ++ } else { ++ WMT_WARN_FUNC("invalid DSNS type\n"); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("query chip version\n"); ++ mtk_wcn_wmt_hwver_get(); ++ return 0; ++} ++ ++INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (0 == par3) { ++ /* par2 = 0: send assert command */ ++ /* par2 != 0: send exception command */ ++ return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1); ++ } else if (1 == par3) { ++ /* send noack command */ ++ return wmt_dbg_cmd_test_api(18); ++ } else if (2 == par3) { ++ /* warn reset test */ ++ return wmt_dbg_cmd_test_api(19); ++ } else if (3 == par3) { ++ /* firmware trace test */ ++ return wmt_dbg_cmd_test_api(20); ++ } ++ { ++ INT32 sec = 8; ++ INT32 times = 0; ++ ++ times = par3; ++ do { ++ WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n"); ++ wmt_dbg_cmd_test_api(0); ++ osal_sleep_ms(sec * 1000); ++ } while (--times); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd) ++{ ++ ++ P_OSAL_OP pOp = NULL; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ ++ pOp->op.opId = WMT_OPID_CMD_TEST; ++ ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ /*this test command should be run with usb cable connected, so no host awake is needed */ ++ /* wmt_lib_host_awake_get(); */ ++ switch (cmd) { ++ case WMTDRV_CMD_ASSERT: ++ pOp->op.au4OpData[0] = 0; ++ break; ++ case WMTDRV_CMD_EXCEPTION: ++ pOp->op.au4OpData[0] = 1; ++ break; ++ case WMTDRV_CMD_NOACK_TEST: ++ pOp->op.au4OpData[0] = 3; ++ break; ++ case WMTDRV_CMD_WARNRST_TEST: ++ pOp->op.au4OpData[0] = 4; ++ break; ++ case WMTDRV_CMD_FWTRACE_TEST: ++ pOp->op.au4OpData[0] = 5; ++ break; ++ default: ++ if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd) { ++ pOp->op.au4OpData[0] = 2; ++ pOp->op.au4OpData[1] = cmd - 2; ++ } else { ++ pOp->op.au4OpData[0] = 0xff; ++ pOp->op.au4OpData[1] = 0xff; ++ } ++ pOp->op.au4OpData[2] = (SIZE_T) gCoexBuf.buffer; ++ pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer); ++ break; ++ } ++ WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]); ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if ((cmd != WMTDRV_CMD_ASSERT) && ++ (cmd != WMTDRV_CMD_EXCEPTION) && ++ (cmd != WMTDRV_CMD_NOACK_TEST) && (cmd != WMTDRV_CMD_WARNRST_TEST) && (cmd != WMTDRV_CMD_FWTRACE_TEST)) { ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ gCoexBuf.availSize = 0; ++ } else { ++ gCoexBuf.availSize = pOp->op.au4OpData[3]; ++ WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize); ++ } ++ } ++ /* wmt_lib_host_awake_put(); */ ++ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", ++ pOp->op.opId, ++ pOp->op.au4OpData[0], ++ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); ++ ++ return 0; ++} ++ ++INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (0 == par2) { ++ WMT_INFO_FUNC("inband reset test!!\n"); ++ mtk_wcn_stp_inband_reset(); ++ } else { ++ WMT_INFO_FUNC("STP context reset in host side!!\n"); ++ mtk_wcn_stp_flush_context(); ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (0 == par2) { ++ if (mtk_wcn_stp_is_ready()) { ++ WMT_INFO_FUNC("whole chip reset test\n"); ++ wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST); ++ } else { ++ WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n"); ++ } ++ } else if (1 == par2) { ++ WMT_INFO_FUNC("chip hardware reset test\n"); ++ wmt_lib_hw_rst(); ++ } else { ++ WMT_INFO_FUNC("chip software reset test\n"); ++ wmt_lib_sw_rst(1); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2) { ++ if (0 == par3) { ++ WMT_INFO_FUNC("function off test, type(%d)\n", par2); ++ mtk_wcn_wmt_func_off(par2); ++ } else { ++ WMT_INFO_FUNC("function on test, type(%d)\n", par2); ++ mtk_wcn_wmt_func_on(par2); ++ } ++ } else { ++ WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2); ++ } ++ return 0; ++} ++ ++INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER)); ++ return 0; ++} ++ ++INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3) ++{ ++ par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO; ++ wmt_lib_dbg_level_set(par2); ++ WMT_INFO_FUNC("set wmt log level to %d\n", par2); ++ return 0; ++} ++ ++INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3) ++{ ++ par2 = (0 <= par2 && 4 >= par2) ? par2 : 2; ++ mtk_wcn_stp_dbg_level(par2); ++ WMT_INFO_FUNC("set stp log level to %d\n", par2); ++ return 0; ++ ++} ++ ++INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->register address */ ++ /* par3-->register mask */ ++ UINT32 value = 0x0; ++ UINT32 iRet = -1; ++#if 0 ++ DISABLE_PSM_MONITOR(); ++ iRet = wmt_core_reg_rw_raw(0, par2, &value, par3); ++ ENABLE_PSM_MONITOR(); ++#endif ++ iRet = wmt_lib_reg_rw(0, par2, &value, par3); ++ WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); ++ return 0; ++} ++ ++INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->register address */ ++ /* par3-->value to set */ ++ UINT32 iRet = -1; ++#if 0 ++ DISABLE_PSM_MONITOR(); ++ iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff); ++ ENABLE_PSM_MONITOR(); ++#endif ++ iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff); ++ WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed"); ++ return 0; ++} ++ ++INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->efuse address */ ++ /* par3-->register mask */ ++ UINT32 value = 0x0; ++ UINT32 iRet = -1; ++ ++ iRet = wmt_lib_efuse_rw(0, par2, &value, par3); ++ WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); ++ return 0; ++} ++ ++INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3) ++{ ++ /* par2-->efuse address */ ++ /* par3-->value to set */ ++ UINT32 iRet = -1; ++ ++ iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff); ++ WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", ++ par2, par3, iRet != 0 ? "failed" : "succeed"); ++ return 0; ++} ++ ++INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++/*remove sdio card detect/remove control because of btif is used*/ ++#if 0 ++ INT32 iRet = -1; ++ ++ iRet = wmt_lib_sdio_ctrl(0 != par2 ? 1 : 0); ++ WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed"); ++#endif ++ return 0; ++} ++ ++INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ if (1 < par2) { ++ mtk_wcn_stp_dbg_dump_package(); ++ return 0; ++ } ++ WMT_INFO_FUNC("%s stp debug function\n", 0 == par2 ? "disable" : "enable"); ++ if (0 == par2) ++ mtk_wcn_stp_dbg_disable(); ++ else if (1 == par2) ++ mtk_wcn_stp_dbg_enable(); ++ ++ return 0; ++} ++ ++INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ mtk_wcn_stp_dbg_log_ctrl(0 != par2 ? 1 : 0); ++ return 0; ++} ++ ++INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ mtk_wcn_stp_coredump_flag_ctrl(0 != par2 ? 1 : 0); ++ return 0; ++} ++ ++INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 offset = 0; ++ UINT32 len = 0; ++ UINT32 *pAddr = NULL; ++ UINT32 cur_idx_pagedtrace; ++ static UINT32 prev_idx_pagedtrace; ++ MTK_WCN_BOOL isBreak = MTK_WCN_BOOL_TRUE; ++ ++ offset = par2; ++ len = par3; ++ ++ buf_emi = kmalloc(sizeof(UINT8) * BUF_LEN_MAX, GFP_KERNEL); ++ if (!buf_emi) { ++ WMT_ERR_FUNC("buf kmalloc memory fail\n"); ++ return 0; ++ } ++ osal_memset(buf_emi, 0, BUF_LEN_MAX); ++ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); ++ wmt_lib_get_fwinfor_from_emi(0, offset, &gEmiBuf[0], 0x100); ++ ++ if (offset == 1) { ++ do { ++ pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24); ++ cur_idx_pagedtrace = *pAddr; ++ ++ if (cur_idx_pagedtrace > prev_idx_pagedtrace) { ++ len = cur_idx_pagedtrace - prev_idx_pagedtrace; ++ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); ++ wmt_dbg_fwinfor_print_buff(len); ++ prev_idx_pagedtrace = cur_idx_pagedtrace; ++ } ++ ++ if (cur_idx_pagedtrace < prev_idx_pagedtrace) { ++ if (prev_idx_pagedtrace >= 0x8000) { ++ pr_debug("++ prev_idx_pagedtrace invalid ...++\n\\n"); ++ prev_idx_pagedtrace = 0x8000 - 1; ++ continue; ++ } ++ ++ len = 0x8000 - prev_idx_pagedtrace - 1; ++ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); ++ pr_debug("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ ++ len = cur_idx_pagedtrace; ++ wmt_lib_get_fwinfor_from_emi(1, 0x0, &gEmiBuf[0], len); ++ pr_debug("\n\n -- CONNSYS paged trace ascii output (end) --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ prev_idx_pagedtrace = cur_idx_pagedtrace; ++ } ++ msleep(100); ++ } while (isBreak); ++ } ++ ++ pr_debug("\n\n -- control word --\n\n"); ++ wmt_dbg_fwinfor_print_buff(256); ++ if (len > 1024 * 4) ++ len = 1024 * 4; ++ ++ WMT_WARN_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n", offset, len); ++ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); ++ wmt_lib_get_fwinfor_from_emi(1, offset, &gEmiBuf[0], len); ++ ++ pr_debug("\n\n -- paged trace hex output --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ pr_debug("\n\n -- paged trace ascii output --\n\n"); ++ wmt_dbg_fwinfor_print_buff(len); ++ kfree(buf_emi); ++ return 0; ++} ++ ++INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("coexistance test cmd!!\n"); ++ return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00); ++} ++ ++INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ WMT_INFO_FUNC("%s audo rst\n", 0 == par2 ? "disable" : "enable"); ++ mtk_wcn_stp_set_auto_rst(0 == par2 ? 0 : 1); ++ return 0; ++} ++ ++INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ ++ INT32 i = 0; ++ INT32 j = 0; ++ INT32 iRet = 0; ++ ++ i = 20; ++ while ((i--) > 0) { ++ WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i); ++ j = 10; ++ while ((j--) > 0) { ++ WMT_INFO_FUNC("#### BT On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### GPS On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### FM On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### WIFI On .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### BT Off .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### GPS Off ....(%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### FM Off .... (%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ WMT_INFO_FUNC("#### WIFI Off ....(%d, %d)\n", i, j); ++ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI); ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ } ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ break; ++ ++ } ++ if (iRet == MTK_WCN_BOOL_FALSE) ++ WMT_INFO_FUNC("#### UT FAIL!!\n"); ++ else ++ WMT_INFO_FUNC("#### UT PASS!!\n"); ++ ++ return iRet; ++} ++ ++#if CFG_CORE_INTERNAL_TXRX ++ ++struct lpbk_package { ++ long payload_length; ++ unsigned char out_payload[2048]; ++ unsigned char in_payload[2048]; ++}; ++ ++static INT32 wmt_internal_loopback(INT32 count, INT32 max) ++{ ++ int ret = 0; ++ int loop; ++ int offset; ++ struct lpbk_package lpbk_buffer; ++ P_OSAL_OP pOp; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ for (loop = 0; loop < count; loop++) { ++ /* <1> init buffer */ ++ osal_memset((void *)&lpbk_buffer, 0, sizeof(struct lpbk_package)); ++ lpbk_buffer.payload_length = max; ++ for (offset = 0; offset < max; offset++) ++ lpbk_buffer.out_payload[offset] = (offset + 1) /*for test use: begin from 1 */ & 0xFF; ++ ++ ++ memcpy(&gLpbkBuf[0], &lpbk_buffer.out_payload[0], max); ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ ret = -1; ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_LPBK; ++ pOp->op.au4OpData[0] = lpbk_buffer.payload_length; /* packet length */ ++ pOp->op.au4OpData[1] = (UINT32) &gLpbkBuf[0]; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ ret = -2; ++ } ++ ++ ret = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == ret) { ++ WMT_WARN_FUNC("OPID(%d) type(%d)fail\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ret = -3; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ memcpy(&lpbk_buffer.in_payload[0], &gLpbkBuf[0], max); ++ ++ ret = pOp->op.au4OpData[0]; ++ /*<3> compare result */ ++ if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) { ++ WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __func__); ++ ret = -4; ++ break; ++ } ++ WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld)\n", __func__, loop, ++ lpbk_buffer.payload_length); ++ ++ } ++ ++ if (loop != count) ++ WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max); ++ ++ ++ return ret; ++} ++ ++INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 count; ++ UINT32 length; ++ ++ count = par1; ++ length = par2; ++ ++ WMT_INFO_FUNC("count[%d],length[%d]\n", count, length); ++ ++ wmt_core_lpbk_do_stp_init(); ++ ++ wmt_internal_loopback(count, length); ++ ++ wmt_core_lpbk_do_stp_deinit(); ++ return 0; ++} ++#endif ++ ++static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3) ++{ ++ int ret = 0; ++ P_OSAL_OP pOp; ++ P_OSAL_SIGNAL pSignal = NULL; ++ UINT32 kind = 0; ++ ++ kind = par2; ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return -1; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_SET_MCU_CLK; ++ pOp->op.au4OpData[0] = kind; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ WMT_INFO_FUNC("OPID(%d) kind(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) kind(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -2; ++ } ++ ++ ret = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == ret) { ++ WMT_WARN_FUNC("OPID(%d) kind(%d)fail(%d)\n", pOp->op.opId, pOp->op.au4OpData[0], ret); ++ return -3; ++ } ++ WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ return ret; ++} ++ ++static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 count = 0; ++ UINT16 sleep = 0; ++ UINT16 toAee = 0; ++ ++ count = par2; ++ sleep = (par3 & 0xF0) >> 4; ++ toAee = (par3 & 0x0F); ++ ++ WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n", count, sleep, toAee); ++ wmt_lib_poll_cpupcr(count, sleep, toAee); ++ ++ return 0; ++} ++ ++#if CONSYS_ENALBE_SET_JTAG ++static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT32 en_flag = par2; ++ ++ wmt_lib_jtag_flag_set(en_flag); ++ return 0; ++} ++#endif ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode, UINT32 msg_len) ++{ ++ ipc_ilm_t ilm; ++ local_para_struct *p_buf_str; ++ INT32 i = 0; ++ INT32 iRet = -1; ++ ++ WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n", opcode, msg_len); ++ p_buf_str = osal_malloc(osal_sizeof(local_para_struct) + msg_len); ++ if (NULL == p_buf_str) { ++ WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n"); ++ return -1; ++ } ++ p_buf_str->msg_len = msg_len; ++ for (i = 0; i < msg_len; i++) ++ p_buf_str->data[i] = i; ++ ++ ilm.local_para_ptr = p_buf_str; ++ ilm.msg_id = opcode; ++ ++ iRet = wmt_lib_handle_idc_msg(&ilm); ++ osal_free(p_buf_str); ++ return iRet; ++ ++} ++ ++static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3) ++{ ++ UINT8 *local_buffer = NULL; ++ UINT32 handle_len; ++ INT32 iRet = -1; ++ static UINT8 wmt_to_lte_test_evt1[] = { 0x02, 0x16, 0x0d, 0x00, ++ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, ++ 0xa, 0xb ++ }; ++ static UINT8 wmt_to_lte_test_evt2[] = { 0x02, 0x16, 0x09, 0x00, ++ 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 ++ }; ++ static UINT8 wmt_to_lte_test_evt3[] = { 0x02, 0x16, 0x02, 0x00, ++ 0x02, 0xff ++ }; ++ static UINT8 wmt_to_lte_test_evt4[] = { 0x02, 0x16, 0x0d, 0x00, ++ 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, ++ 0xa, 0xb ++ }; ++ ++ local_buffer = kmalloc(512, GFP_KERNEL); ++ if (!local_buffer) { ++ WMT_ERR_FUNC("local_buffer kmalloc memory fail\n"); ++ return 0; ++ } ++ ++ if (par2 == 1) { ++ handle_len = ++ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); ++ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1)) { ++ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", ++ handle_len, osal_sizeof(wmt_to_lte_test_evt1)); ++ } else { ++ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 2) { ++ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); ++ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], ++ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); ++ ++ handle_len = ++ wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], ++ osal_sizeof(wmt_to_lte_test_evt1) + ++ osal_sizeof(wmt_to_lte_test_evt2)); ++ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)) { ++ WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", ++ handle_len, osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)); ++ } else { ++ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 3) { ++ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); ++ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], ++ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); ++ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)], ++ &wmt_to_lte_test_evt3[0], osal_sizeof(wmt_to_lte_test_evt3)); ++ ++ handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], osal_sizeof(wmt_to_lte_test_evt1) + ++ osal_sizeof(wmt_to_lte_test_evt2) + ++ osal_sizeof(wmt_to_lte_test_evt3)); ++ if (handle_len != ++ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + ++ osal_sizeof(wmt_to_lte_test_evt3)) { ++ WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", handle_len, ++ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + ++ osal_sizeof(wmt_to_lte_test_evt3)); ++ } else { ++ WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 4) { ++ handle_len = ++ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt4[0], osal_sizeof(wmt_to_lte_test_evt4)); ++ if (handle_len != osal_sizeof(wmt_to_lte_test_evt4)) { ++ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", ++ handle_len, osal_sizeof(wmt_to_lte_test_evt4)); ++ } else { ++ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); ++ } ++ } ++ if (par2 == 5) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 6) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 7) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 8) { ++ if (par3 >= 1024) ++ par3 = 1024; ++ ++ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND, par3); ++ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n", iRet); ++ } ++ if (par2 == 9) { ++ if (par3 > 0) ++ wmt_core_set_flag_for_test(1); ++ else ++ wmt_core_set_flag_for_test(0); ++ } ++ return 0; ++ kfree(local_buffer); ++} ++#endif ++ ++static ssize_t wmt_dev_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ ++ INT32 retval = 0; ++ INT32 i_ret = 0; ++ PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; ++ ++ if (*f_pos > 0) { ++ retval = 0; ++ } else { ++ /*len = sprintf(page, "%d\n", g_psm_enable); */ ++ if (gCoexBuf.availSize <= 0) { ++ WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"); ++ retval = osal_strlen(warn_msg) + 1; ++ if (count < retval) ++ retval = count; ++ ++ i_ret = copy_to_user(buf, warn_msg, retval); ++ if (i_ret) { ++ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ } else { ++ INT32 i = 0; ++ INT32 len = 0; ++ INT8 msg_info[128]; ++ INT32 max_num = 0; ++ /*we do not check page buffer, because there are only ++ * 100 bytes in g_coex_buf, no reason page buffer is not ++ * enough, a bomb is placed here on unexpected condition ++ */ ++ ++ WMT_INFO_FUNC("%d bytes available\n", gCoexBuf.availSize); ++ max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) - 1) / 5; ++ ++ if (max_num > gCoexBuf.availSize) ++ max_num = gCoexBuf.availSize; ++ else ++ WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num); ++ ++ ++ for (i = 0; i < max_num; i++) ++ len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]); ++ ++ ++ len += osal_sprintf(msg_info + len, "\n"); ++ retval = len; ++ ++ i_ret = copy_to_user(buf, msg_info, retval); ++ if (i_ret) { ++ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ ++ } ++ } ++ gCoexBuf.availSize = 0; ++err_exit: ++ ++ return retval; ++} ++ ++static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) ++{ ++ INT8 buf[256]; ++ PINT8 pBuf; ++ ssize_t len = count; ++ INT32 x = 0, y = 0, z = 0; ++ PINT8 pToken = NULL; ++ PINT8 pDelimiter = " \t"; ++ long res; ++ INT32 ret; ++ ++ WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); ++ if (len >= osal_sizeof(buf)) { ++ WMT_ERR_FUNC("input handling fail!\n"); ++ len = osal_sizeof(buf) - 1; ++ return -1; ++ } ++ ++ if (copy_from_user(buf, buffer, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ WMT_INFO_FUNC("write parameter data = %s\n\r", buf); ++ ++ pBuf = buf; ++ pToken = osal_strsep(&pBuf, pDelimiter); ++ ++ if (pToken != NULL) { ++ ret = osal_strtol(pToken, 16, &res); ++ if (ret) { ++ WMT_ERR_FUNC("get x fail(%d)\n", ret); ++ x = 0; ++ } ++ x = res; ++ } else { ++ x = 0; ++ } ++ ++ pToken = osal_strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ ret = osal_strtol(pToken, 16, &res); ++ if (ret) { ++ WMT_ERR_FUNC("get y fail(%d)\n", ret); ++ y = 0; ++ } ++ y = res; ++ WMT_INFO_FUNC("y = 0x%08x\n\r", y); ++ } else { ++ y = 3000; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ y = 0x80000000; ++ ++ } ++ ++ pToken = osal_strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ ret = osal_strtol(pToken, 16, &res); ++ if (ret) { ++ WMT_ERR_FUNC("get z fail(%d)\n", ret); ++ z = 0; ++ } ++ z = res; ++ } else { ++ z = 10; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ z = 0xffffffff; ++ ++ } ++ ++ WMT_WARN_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); ++ ++ if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x]) ++ (*wmt_dev_dbg_func[x]) (x, y, z); ++ else ++ WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x); ++ ++ return len; ++} ++ ++INT32 wmt_dev_dbg_setup(VOID) ++{ ++ static const struct file_operations wmt_dbg_fops = { ++ .owner = THIS_MODULE, ++ .read = wmt_dev_dbg_read, ++ .write = wmt_dev_dbg_write, ++ }; ++ gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops); ++ if (gWmtDbgEntry == NULL) { ++ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); ++ return -1; ++ } ++ return 0; ++} ++ ++INT32 wmt_dev_dbg_remove(VOID) ++{ ++ if (NULL != gWmtDbgEntry) ++ remove_proc_entry(WMT_DBG_PROCNAME, NULL); ++ ++#if CFG_WMT_PS_SUPPORT ++ wmt_lib_ps_deinit(); ++#endif ++ return 0; ++} ++#endif ++ ++#if CFG_WMT_PROC_FOR_AEE ++ ++static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 retval = 0; ++ UINT32 len = 0; ++ ++ WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos); ++ ++ if (0 == *f_pos) { ++ pBuf = wmt_lib_get_cpupcr_xml_format(&len); ++ g_buf_len = len; ++ WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len); ++ } ++ ++ if (g_buf_len >= count) { ++ ++ retval = copy_to_user(buf, pBuf, count); ++ if (retval) { ++ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ ++ *f_pos += count; ++ g_buf_len -= count; ++ pBuf += count; ++ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); ++ ++ retval = count; ++ } else if (0 != g_buf_len) { ++ ++ retval = copy_to_user(buf, pBuf, g_buf_len); ++ if (retval) { ++ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ ++ *f_pos += g_buf_len; ++ len = g_buf_len; ++ g_buf_len = 0; ++ pBuf += len; ++ retval = len; ++ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); ++ } else { ++ WMT_INFO_FUNC("wmt_dev: no data available for aee\n"); ++ retval = 0; ++ } ++err_exit: ++ return retval; ++} ++ ++static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ WMT_TRC_FUNC(); ++ return 0; ++} ++ ++INT32 wmt_dev_proc_for_aee_setup(VOID) ++{ ++ static const struct file_operations wmt_aee_fops = { ++ .owner = THIS_MODULE, ++ .read = wmt_dev_proc_for_aee_read, ++ .write = wmt_dev_proc_for_aee_write, ++ }; ++ ++ gWmtDbgEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops); ++ if (gWmtDbgEntry == NULL) { ++ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++INT32 wmt_dev_proc_for_aee_remove(VOID) ++{ ++ if (NULL != gWmtAeeEntry) ++ remove_proc_entry(WMT_AEE_PROCNAME, NULL); ++ ++ return 0; ++} ++#endif ++ ++VOID wmt_dev_rx_event_cb(VOID) ++{ ++ u4RxFlag = 1; ++ atomic_inc(&gRxCount); ++ if (NULL != gpRxEvent) { ++ /* u4RxFlag = 1; */ ++ /* atomic_inc(&gRxCount); */ ++ wake_up_interruptible(&gpRxEvent->waitQueue); ++ } else { ++ /* WMT_ERR_FUNC("null gpRxEvent, flush rx!\n"); */ ++ /* wmt_lib_flush_rx(); */ ++ } ++} ++ ++INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent) ++{ ++ ++ UINT32 ms = pEvent->timeoutValue; ++ long lRet = 0; ++ ++ gpRxEvent = pEvent; ++ if (0 != ms) ++ lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, msecs_to_jiffies(ms)); ++ else ++ lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0); ++ ++ u4RxFlag = 0; ++/* gpRxEvent = NULL; */ ++ if (atomic_dec_return(&gRxCount)) { ++ WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount)); ++ atomic_set(&gRxCount, 0); ++ } ++ ++ return lRet; ++} ++ ++INT32 wmt_dev_read_file(PUINT8 pName, const PPUINT8 ppBufPtr, INT32 offset, INT32 padSzBuf) ++{ ++ INT32 iRet = -1; ++ struct file *fd; ++ /* ssize_t iRet; */ ++ INT32 file_len; ++ INT32 read_len; ++ PVOID pBuf; ++ mm_segment_t fs; ++ ++ /* struct cred *cred = get_task_cred(current); */ ++ //const struct cred *cred = get_current_cred(); ++ ++ if (!ppBufPtr) { ++ WMT_ERR_FUNC("invalid ppBufptr!\n"); ++ return -1; ++ } ++ *ppBufPtr = NULL; ++ ++ fd = filp_open(pName, O_RDONLY, 0); ++ if (IS_ERR(fd)) { ++ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); ++ return -2; ++ } ++ ++ if(fd->f_op == NULL) { ++ printk(KERN_ERR "invalid file op \r\n"); ++ return -3; ++ } ++ ++#if 0 ++ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { ++ WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d, %d)\n", fd, PTR_ERR(fd), cred->fsuid, cred->fsgid); ++ if (IS_ERR(fd)) ++ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); ++ return -1; ++ } ++#endif ++ file_len = fd->f_path.dentry->d_inode->i_size; ++ file_len = fd->f_op->llseek(fd, 0, 2); ++ fd->f_op->llseek(fd, 0, 0); ++ pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL); ++ if (!pBuf) { ++ WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32) ((file_len + 3) & ~0x3UL)); ++ goto read_file_done; ++ } ++ ++ do { ++ if (fd->f_pos != offset) { ++ if (fd->f_op->llseek) { ++ if (fd->f_op->llseek(fd, offset, 0) != offset) { ++ WMT_ERR_FUNC("failed to seek!!\n"); ++ goto read_file_done; ++ } ++ } else { ++ fd->f_pos = offset; ++ } ++ } ++ ++ fs=get_fs(); ++ read_len = vfs_read(fd, pBuf + padSzBuf, file_len, &fd->f_pos); ++ set_fs(fs); ++ if (read_len != file_len) ++ WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len); ++ ++ } while (false); ++ ++ iRet = 0; ++ *ppBufPtr = pBuf; ++ ++read_file_done: ++ if (iRet) { ++ if (pBuf) ++ vfree(pBuf); ++ ++ } ++ ++ filp_close(fd, NULL); ++ ++ return (iRet) ? iRet : read_len; ++} ++ ++/* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */ ++INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf) ++{ ++ INT32 iRet = -1; ++ osal_firmware *pfw; ++ uid_t orig_uid; ++ gid_t orig_gid; ++ ++ /* struct cred *cred = get_task_cred(current); */ ++ struct cred *cred = (struct cred *)get_current_cred(); ++ ++ mm_segment_t orig_fs = get_fs(); ++ ++ if (*ppPatch) { ++ WMT_WARN_FUNC("f/w patch already exists\n"); ++ if ((*ppPatch)->data) ++ vfree((*ppPatch)->data); ++ ++ kfree(*ppPatch); ++ *ppPatch = NULL; ++ } ++ ++ if (!osal_strlen(pPatchName)) { ++ WMT_ERR_FUNC("empty f/w name\n"); ++ osal_assert((osal_strlen(pPatchName) > 0)); ++ return -1; ++ } ++ ++ pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL */ GFP_ATOMIC); ++ if (!pfw) { ++ WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware)); ++ return -2; ++ } ++ ++ orig_uid = cred->fsuid.val; ++ orig_gid = cred->fsgid.val; ++ cred->fsuid.val = cred->fsgid.val = 0; ++ ++ set_fs(get_ds()); ++ ++ /* load patch file from fs */ ++ iRet = wmt_dev_read_file(pPatchName, (const PPUINT8)&pfw->data, 0, padSzBuf); ++ set_fs(orig_fs); ++ ++ cred->fsuid.val = orig_uid; ++ cred->fsgid.val = orig_gid; ++ ++ ++ if (iRet > 0) { ++ pfw->size = iRet; ++ *ppPatch = pfw; ++ WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data); ++ return 0; ++ } ++ kfree(pfw); ++ *ppPatch = NULL; ++ WMT_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet); ++ return -1; ++} ++ ++INT32 wmt_dev_patch_put(osal_firmware **ppPatch) ++{ ++ if (NULL != *ppPatch) { ++ if ((*ppPatch)->data) ++ vfree((*ppPatch)->data); ++ ++ kfree(*ppPatch); ++ *ppPatch = NULL; ++ } ++ return 0; ++} ++ ++VOID wmt_dev_patch_info_free(VOID) ++{ ++ ++ kfree(pPatchInfo); ++ pPatchInfo = NULL; ++ ++} ++ ++MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName) ++{ ++ struct file *fd = NULL; ++ /* ssize_t iRet; */ ++ INT32 fileLen = -1; ++ const struct cred *cred = get_current_cred(); ++ ++ if (pFileName == NULL) { ++ WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) { ++ WMT_ERR_FUNC("invalid file name(%s)\n", pFileName); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ /* struct cred *cred = get_task_cred(current); */ ++ ++ fd = filp_open(pFileName, O_RDONLY, 0); ++ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { ++ WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd, cred->fsuid, cred->fsgid); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ fileLen = fd->f_path.dentry->d_inode->i_size; ++ filp_close(fd, NULL); ++ fd = NULL; ++ if (fileLen <= 0) { ++ WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen); ++ return true; ++ ++} ++ ++/* static unsigned long count_last_access_sdio = 0; */ ++static unsigned long count_last_access_btif; ++static unsigned long jiffies_last_poll; ++ ++#if 0 ++static INT32 wmt_dev_tra_sdio_update(void) ++{ ++ count_last_access_sdio += 1; ++ /* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */ ++ ++ return 0; ++} ++#endif ++ ++extern INT32 wmt_dev_tra_bitf_update(void) ++{ ++ count_last_access_btif += 1; ++ /* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */ ++ ++ return 0; ++} ++ ++static UINT32 wmt_dev_tra_ahb_poll(void) ++{ ++#define TIME_THRESHOLD_TO_TEMP_QUERY 3000 ++#define COUNT_THRESHOLD_TO_TEMP_QUERY 200 ++ ++ unsigned long ahb_during_count = 0; ++ unsigned long poll_during_time = 0; ++ ++ /* if (jiffies > jiffies_last_poll) */ ++ if (time_after(jiffies, jiffies_last_poll)) ++ poll_during_time = jiffies - jiffies_last_poll; ++ else ++ poll_during_time = 0xffffffff; ++ ++ ++ WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n", jiffies_to_msecs(0xffffffff)); ++ ++ if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { ++ WMT_DBG_FUNC("**poll_during_time = %lu < %lu, not to query\n", ++ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY); ++ return -1; ++ } ++ /* ahb_during_count = count_last_access_sdio; */ ++ if (NULL == mtk_wcn_wlan_bus_tx_cnt) { ++ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n"); ++ return -1; ++ } ++ ahb_during_count = (*mtk_wcn_wlan_bus_tx_cnt) (); ++ ++ if (ahb_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) { ++ WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n", ++ ahb_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY); ++ return -2; ++ } ++ ++ if (NULL == mtk_wcn_wlan_bus_tx_cnt_clr) { ++ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n"); ++ return -3; ++ } ++ (*mtk_wcn_wlan_bus_tx_cnt_clr) (); ++ /* count_last_access_sdio = 0; */ ++ jiffies_last_poll = jiffies; ++ ++ WMT_INFO_FUNC("**poll_during_time = %lu > %lu, ahb_during_count = %lu > %lu, query\n", ++ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY, ++ jiffies_to_msecs(ahb_during_count), COUNT_THRESHOLD_TO_TEMP_QUERY); ++ ++ return 0; ++} ++ ++long wmt_dev_tm_temp_query(void) ++{ ++#define HISTORY_NUM 5 ++#define TEMP_THRESHOLD 65 ++#define REFRESH_TIME 300 /* sec */ ++ ++ static INT32 temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */ ++ static INT32 idx_temp_table; ++ static struct timeval query_time, now_time; ++ ++ INT8 query_cond = 0; ++ INT32 current_temp = 0; ++ INT32 index = 0; ++ long return_temp = 0; ++ /* Query condition 1: */ ++ /* If we have the high temperature records on the past, we continue to query/monitor */ ++ /* the real temperature until cooling */ ++ for (index = 0; index < HISTORY_NUM; index++) { ++ if (temp_table[index] >= TEMP_THRESHOLD) { ++ query_cond = 1; ++ WMT_DBG_FUNC("temperature table is still initial value, we should query temp temperature..\n"); ++ } ++ } ++ ++ do_gettimeofday(&now_time); ++#if 1 ++ /* Query condition 2: */ ++ /* Moniter the ahb bus activity to decide if we have the need to query temperature. */ ++ if (!query_cond) { ++ if (wmt_dev_tra_ahb_poll() == 0) { ++ query_cond = 1; ++ WMT_INFO_FUNC("ahb traffic , we must query temperature..\n"); ++ } else { ++ WMT_DBG_FUNC("ahb idle traffic ....\n"); ++ } ++ ++ /* only WIFI tx power might make temperature varies largely */ ++#if 0 ++ if (!query_cond) { ++ last_access_time = wmt_dev_tra_uart_poll(); ++ if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { ++ query_cond = 1; ++ WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); ++ } else { ++ WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n"); ++ } ++ } ++#endif ++ } ++#endif ++ /* Query condition 3: */ ++ /* If the query time exceeds the a certain of period, refresh temp table. */ ++ /* */ ++ if (!query_cond) { ++ /* time overflow, we refresh temp table again for simplicity! */ ++ if ((now_time.tv_sec < query_time.tv_sec) || ++ ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { ++ query_cond = 1; ++ ++ WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n", ++ REFRESH_TIME); ++ for (index = 0; index < HISTORY_NUM; index++) ++ temp_table[index] = 99; ++ ++ } ++ } ++ ++ if (query_cond) { ++ /* update the temperature record */ ++ mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); ++ current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); ++ mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); ++ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; ++ temp_table[idx_temp_table] = current_temp; ++ do_gettimeofday(&query_time); ++ ++ WMT_INFO_FUNC("[Thermal] current_temp = 0x%x\n", (current_temp & 0xFF)); ++ } else { ++ current_temp = temp_table[idx_temp_table]; ++ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; ++ temp_table[idx_temp_table] = current_temp; ++ } ++ ++ /* */ ++ /* Dump information */ ++ /* */ ++ WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table); ++ WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec, ++ query_time.tv_sec, REFRESH_TIME); ++ ++ WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n", ++ temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]); ++ ++ return_temp = ((current_temp & 0x80) == 0x0) ? current_temp : (-1) * (current_temp & 0x7f); ++ ++ return return_temp; ++} ++ ++ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 iRet = 0; ++ UINT8 wrBuf[NAME_MAX + 1] = { 0 }; ++ INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX; ++ ++ WMT_LOUD_FUNC("count:%d copySize:%d\n", count, copySize); ++ ++ if (copySize > 0) { ++ if (copy_from_user(wrBuf, buf, copySize)) { ++ iRet = -EFAULT; ++ goto write_done; ++ } ++ iRet = copySize; ++ wrBuf[NAME_MAX] = '\0'; ++ ++ if (!strncasecmp(wrBuf, "ok", NAME_MAX)) { ++ WMT_DBG_FUNC("resp str ok\n"); ++ /* pWmtDevCtx->cmd_result = 0; */ ++ wmt_lib_trigger_cmd_signal(0); ++ } else { ++ WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf); ++ /* pWmtDevCtx->cmd_result = -1; */ ++ wmt_lib_trigger_cmd_signal(-1); ++ } ++ /* complete(&pWmtDevCtx->cmd_comp); */ ++ ++ } ++ ++write_done: ++ return iRet; ++} ++ ++ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 iRet = 0; ++ PUINT8 pCmd = NULL; ++ UINT32 cmdLen = 0; ++ ++ pCmd = wmt_lib_get_cmd(); ++ ++ if (pCmd != NULL) { ++ cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX; ++ WMT_DBG_FUNC("cmd str(%s)\n", pCmd); ++ if (copy_to_user(buf, pCmd, cmdLen)) ++ iRet = -EFAULT; ++ else ++ iRet = cmdLen; ++ ++ } ++#if 0 ++ if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) { ++ iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX; ++ /* we got something from STP driver */ ++ WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf); ++ if (copy_to_user(buf, localBuf, iRet)) { ++ iRet = -EFAULT; ++ goto read_done; ++ } ++ } ++#endif ++ return iRet; ++} ++ ++unsigned int WMT_poll(struct file *filp, poll_table *wait) ++{ ++ UINT32 mask = 0; ++ P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event(); ++ ++ poll_wait(filp, &pEvent->waitQueue, wait); ++ /* empty let select sleep */ ++ if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status()) ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ ++#if 0 ++ if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ ++#endif ++ mask |= POLLOUT | POLLWRNORM; /* writable */ ++ return mask; ++} ++ ++/* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */ ++long WMT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ ++ INT32 iRet = 0; ++ UINT8 *pBuffer = NULL; ++ ++ WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); ++ switch (cmd) { ++ case WMT_IOCTL_SET_PATCH_NAME: /* patch location */ ++ { ++ ++ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); ++ if (!pBuffer) { ++ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); ++ return 0; ++ } ++ if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) { ++ iRet = -EFAULT; ++ kfree(pBuffer); ++ break; ++ } ++ pBuffer[NAME_MAX] = '\0'; ++ wmt_lib_set_patch_name(pBuffer); ++ kfree(pBuffer); ++ } ++ break; ++ ++ case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */ ++ ++ /* set hif conf */ ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal = NULL; ++ P_WMT_HIF_CONF pHif = NULL; ++ ++ iRet = wmt_lib_set_hif(arg); ++ if (0 != iRet) { ++ WMT_INFO_FUNC("wmt_lib_set_hif fail\n"); ++ break; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_INFO_FUNC("get_free_lxop fail\n"); ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_HIF_CONF; ++ ++ pHif = wmt_lib_get_hif(); ++ ++ osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF)); ++ pOp->op.u4InfoBit = WMT_OP_HIF_BIT; ++ pSignal->timeoutValue = 0; ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet); ++ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */ ++ ++ do { ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ ++ if (arg & 0x80000000) ++ bRet = mtk_wcn_wmt_func_on(arg & 0xF); ++ else ++ bRet = mtk_wcn_wmt_func_off(arg & 0xF); ++ ++ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_LPBK_POWER_CTRL: ++ /*switch Loopback function on/off ++ arg: bit0 = 1:turn loopback function on ++ bit0 = 0:turn loopback function off ++ */ ++ do { ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ ++ if (arg & 0x01) ++ bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); ++ else ++ bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); ++ ++ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_LPBK_TEST: ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT32 u4Wait; ++ /* UINT8 lpbk_buf[1024] = {0}; */ ++ UINT32 effectiveLen = 0; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) { ++ iRet = -EFAULT; ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ break; ++ } ++ if (effectiveLen > sizeof(gLpbkBuf)) { ++ iRet = -EFAULT; ++ WMT_ERR_FUNC("length is too long\n"); ++ break; ++ } ++ WMT_DBG_FUNC("len = %d\n", effectiveLen); ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ iRet = -EFAULT; ++ break; ++ } ++ u4Wait = 2000; ++ if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) { ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ iRet = -EFAULT; ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_LPBK; ++ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ ++ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; /* packet buffer pointer */ ++ memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4); ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", ++ pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n", ++ pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog); ++ iRet = -1; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ iRet = pOp->op.au4OpData[0]; ++ if (copy_to_user((void *)arg + sizeof(SIZE_T) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) { ++ iRet = -EFAULT; ++ break; ++ } ++ ++ } while (0); ++ ++ break; ++ ++ case WMT_IOCTL_ADIE_LPBK_TEST: ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ iRet = -EFAULT; ++ break; ++ } ++ ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST; ++ pOp->op.au4OpData[0] = 0; ++ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d)abort\n", pOp->op.opId); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); ++ iRet = -1; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ iRet = pOp->op.au4OpData[0]; ++ if (copy_to_user((void *)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) { ++ iRet = -EFAULT; ++ break; ++ } ++ ++ } while (0); ++ ++ break; ++ ++ case 10: ++ { ++ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); ++ if (!pBuffer) { ++ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); ++ return 0; ++ } ++ wmt_lib_host_awake_get(); ++ mtk_wcn_stp_coredump_start_ctrl(1); ++ osal_strcpy(pBuffer, "MT662x f/w coredump start-"); ++ if (copy_from_user ++ (pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) { ++ /* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */ ++ WMT_ERR_FUNC("copy assert string failed\n"); ++ } ++ pBuffer[NAME_MAX] = '\0'; ++ osal_dbg_assert_aee(pBuffer, pBuffer); ++ kfree(pBuffer); ++ } ++ break; ++ case 11: ++ { ++ osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); ++ wmt_lib_host_awake_put(); ++ } ++ break; ++ ++ case WMT_IOCTL_GET_CHIP_INFO: ++ { ++ if (0 == arg) ++ return wmt_lib_get_icinfo(WMTCHIN_CHIPID); ++ else if (1 == arg) ++ return wmt_lib_get_icinfo(WMTCHIN_HWVER); ++ else if (2 == arg) ++ return wmt_lib_get_icinfo(WMTCHIN_FWVER); ++ ++ } ++ break; ++ ++ case WMT_IOCTL_SET_LAUNCHER_KILL:{ ++ if (1 == arg) { ++ WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n"); ++ wmt_lib_set_stp_wmt_last_close(1); ++ } else { ++ wmt_lib_set_stp_wmt_last_close(0); ++ } ++ ++ } ++ break; ++ ++ case WMT_IOCTL_SET_PATCH_NUM:{ ++ pAtchNum = arg; ++ WMT_DBG_FUNC(" get patch num from launcher = %d\n", pAtchNum); ++ wmt_lib_set_patch_num(pAtchNum); ++ pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC); ++ if (!pPatchInfo) { ++ WMT_ERR_FUNC("allocate memory fail!\n"); ++ break; ++ } ++ } ++ break; ++ ++ case WMT_IOCTL_SET_PATCH_INFO:{ ++ WMT_PATCH_INFO wMtPatchInfo; ++ P_WMT_PATCH_INFO pTemp = NULL; ++ UINT32 dWloadSeq; ++ static UINT32 counter; ++ ++ if (!pPatchInfo) { ++ WMT_ERR_FUNC("NULL patch info pointer\n"); ++ break; ++ } ++ ++ if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) { ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ iRet = -EFAULT; ++ break; ++ } ++ ++ dWloadSeq = wMtPatchInfo.dowloadSeq; ++ WMT_DBG_FUNC( ++ "patch dl seq %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n", ++ dWloadSeq, wMtPatchInfo.patchName, ++ wMtPatchInfo.addRess[0], ++ wMtPatchInfo.addRess[1], ++ wMtPatchInfo.addRess[2], ++ wMtPatchInfo.addRess[3]); ++ osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo, sizeof(WMT_PATCH_INFO)); ++ pTemp = pPatchInfo + dWloadSeq - 1; ++ if (++counter == pAtchNum) { ++ wmt_lib_set_patch_info(pPatchInfo); ++ counter = 0; ++ } ++ } ++ break; ++ ++ case WMT_IOCTL_WMT_COREDUMP_CTRL: ++ mtk_wcn_stp_coredump_flag_ctrl(arg); ++ break; ++ case WMT_IOCTL_WMT_QUERY_CHIPID: ++ { ++ iRet = mtk_wcn_wmt_chipid_query(); ++ WMT_WARN_FUNC("chipid = 0x%x\n", iRet); ++ } ++ break; ++ case WMT_IOCTL_SEND_BGW_DS_CMD: ++ do { ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ UINT8 desense_buf[14] = { 0 }; ++ UINT32 effectiveLen = 14; ++ P_OSAL_SIGNAL pSignal = NULL; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ iRet = -EFAULT; ++ break; ++ } ++ if (copy_from_user(&desense_buf[0], (void *)arg, effectiveLen)) { ++ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); ++ iRet = -EFAULT; ++ break; ++ } ++ pSignal = &pOp->signal; ++ pOp->op.opId = WMT_OPID_BGW_DS; ++ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ ++ pOp->op.au4OpData[1] = (SIZE_T) &desense_buf[0]; /* packet buffer pointer */ ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,opid(%d) abort\n", pOp->op.opId); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); ++ iRet = -1; ++ break; ++ } ++ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ iRet = pOp->op.au4OpData[0]; ++ ++ } while (0); ++ ++ break; ++ case WMT_IOCTL_FW_DBGLOG_CTRL: ++ { ++ iRet = wmt_plat_set_dbg_mode(arg); ++ if (iRet == 0) ++ wmt_dbg_fwinfor_from_emi(0, 1, 0); ++ } ++ break; ++ case WMT_IOCTL_DYNAMIC_DUMP_CTRL: ++ { ++ UINT32 i = 0, j = 0, k = 0; ++ UINT8 *pBuf = NULL; ++ UINT32 int_buf[10]; ++ char Buffer[10][11]; ++ ++ pBuf = kmalloc(DYNAMIC_DUMP_BUF + 1, GFP_KERNEL); ++ if (!pBuf) { ++ WMT_ERR_FUNC("pBuf kmalloc memory fail\n"); ++ return 0; ++ } ++ if (copy_from_user(pBuf, (void *)arg, DYNAMIC_DUMP_BUF)) { ++ iRet = -EFAULT; ++ kfree(pBuf); ++ break; ++ } ++ pBuf[DYNAMIC_DUMP_BUF] = '\0'; ++ WMT_INFO_FUNC("get dynamic dump data from property(%s)\n", pBuf); ++ memset(Buffer, 0, 10*11); ++ for (i = 0; i < DYNAMIC_DUMP_BUF; i++) { ++ if (pBuf[i] == '/') { ++ k = 0; ++ j++; ++ } else { ++ Buffer[j][k] = pBuf[i]; ++ k++; ++ } ++ } ++ for (j = 0; j < 10; j++) { ++ iRet = kstrtou32(Buffer[j], 0, &int_buf[j]); ++ if (iRet) { ++ WMT_ERR_FUNC("string convert fail(%d)\n", iRet); ++ break; ++ } ++ WMT_INFO_FUNC("dynamic dump data buf[%d]:(0x%x)\n", j, int_buf[j]); ++ } ++ wmt_plat_set_dynamic_dumpmem(int_buf); ++ kfree(pBuf); ++ } ++ break; ++ default: ++ iRet = -EINVAL; ++ WMT_WARN_FUNC("unknown cmd (%d)\n", cmd); ++ break; ++ } ++ ++ return iRet; ++} ++#ifdef CONFIG_COMPAT ++long WMT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ WMT_INFO_FUNC("cmd[0x%x]\n", cmd); ++ switch (cmd) { ++ case COMPAT_WMT_IOCTL_SET_PATCH_NAME: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_LPBK_TEST: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_SET_PATCH_INFO: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_PORT_NAME: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_WMT_CFG_NAME: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (unsigned long)compat_ptr(arg)); ++ break; ++ case COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD: ++ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SEND_BGW_DS_CMD, (unsigned long)compat_ptr(arg)); ++ break; ++ default: { ++ ret = WMT_unlocked_ioctl(filp, cmd, arg); ++ break; ++ } ++ } ++ return ret; ++} ++#endif ++static int WMT_open(struct inode *inode, struct file *file) ++{ ++ long ret; ++ ++ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ret = wait_event_timeout(gWmtInitWq, gWmtInitDone != 0, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); ++ if (!ret) { ++ WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n", ++ WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); ++ return -EIO; ++ } ++ ++ if (atomic_inc_return(&gWmtRefCnt) == 1) ++ WMT_INFO_FUNC("1st call\n"); ++ ++ return 0; ++} ++ ++static int WMT_close(struct inode *inode, struct file *file) ++{ ++ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); ++ ++ if (atomic_dec_return(&gWmtRefCnt) == 0) ++ WMT_INFO_FUNC("last call\n"); ++ ++ return 0; ++} ++ ++const struct file_operations gWmtFops = { ++ .open = WMT_open, ++ .release = WMT_close, ++ .read = WMT_read, ++ .write = WMT_write, ++/* .ioctl = WMT_ioctl, */ ++ .unlocked_ioctl = WMT_unlocked_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = WMT_compat_ioctl, ++#endif ++ .poll = WMT_poll, ++}; ++ ++void wmt_dev_bgw_desense_init(VOID) ++{ ++ bgw_init_socket(); ++} ++ ++void wmt_dev_bgw_desense_deinit(VOID) ++{ ++ bgw_destroy_netlink_kernel(); ++} ++ ++void wmt_dev_send_cmd_to_daemon(UINT32 cmd) ++{ ++ send_command_to_daemon(cmd); ++} ++ ++static int WMT_init(void) ++{ ++ dev_t devID = MKDEV(gWmtMajor, 0); ++ INT32 cdevErr = -1; ++ INT32 ret = -1; ++ ++ WMT_INFO_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE); ++ /* Prepare a UINT8 device */ ++ /*static allocate chrdev */ ++ gWmtInitDone = 0; ++ init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq); ++ stp_drv_init(); ++ ++ ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME); ++ if (ret) { ++ WMT_ERR_FUNC("fail to register chrdev\n"); ++ return ret; ++ } ++ cdev_init(&gWmtCdev, &gWmtFops); ++ gWmtCdev.owner = THIS_MODULE; ++ cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM); ++ if (cdevErr) { ++ WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); ++ goto error; ++ } ++ WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor); ++#if WMT_CREATE_NODE_DYNAMIC ++ wmt_class = class_create(THIS_MODULE, "stpwmt"); ++ if (IS_ERR(wmt_class)) ++ goto error; ++ wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt"); ++ if (IS_ERR(wmt_dev)) ++ goto error; ++#endif ++ ++#if 0 ++ pWmtDevCtx = wmt_drv_create(); ++ if (!pWmtDevCtx) { ++ WMT_ERR_FUNC("wmt_drv_create() fails\n"); ++ goto error; ++ } ++ ret = wmt_drv_init(pWmtDevCtx); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret); ++ goto error; ++ } ++ WMT_INFO_FUNC("stp_btmcb_reg\n"); ++ wmt_cdev_btmcb_reg(); ++ ret = wmt_drv_start(pWmtDevCtx); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret); ++ goto error; ++ } ++#endif ++ ret = wmt_lib_init(); ++ if (ret) { ++ WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret); ++ goto error; ++ } ++#if CFG_WMT_DBG_SUPPORT ++ wmt_dev_dbg_setup(); ++#endif ++ ++#if CFG_WMT_PROC_FOR_AEE ++ wmt_dev_proc_for_aee_setup(); ++#endif ++ ++ WMT_INFO_FUNC("wmt_dev register thermal cb\n"); ++ wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query); ++ wmt_dev_bgw_desense_init(); ++ gWmtInitDone = 1; ++ wake_up(&gWmtInitWq); ++ osal_sleepable_lock_init(&g_es_lr_lock); ++ INIT_WORK(&gPwrOnOffWork, wmt_pwr_on_off_handler); ++#ifdef CONFIG_EARLYSUSPEND ++ register_early_suspend(&wmt_early_suspend_handler); ++ WMT_INFO_FUNC("register_early_suspend finished\n"); ++#else ++ wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback; ++ ret = fb_register_client(&wmt_fb_notifier); ++ if (ret) ++ WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret); ++ else ++ WMT_INFO_FUNC("wmt register fb_notifier OK!\n"); ++#endif ++ WMT_INFO_FUNC("success\n"); ++ return 0; ++ ++error: ++ wmt_lib_deinit(); ++#if CFG_WMT_DBG_SUPPORT ++ wmt_dev_dbg_remove(); ++#endif ++#if WMT_CREATE_NODE_DYNAMIC ++ if (!(IS_ERR(wmt_dev))) ++ device_destroy(wmt_class, devID); ++ if (!(IS_ERR(wmt_class))) { ++ class_destroy(wmt_class); ++ wmt_class = NULL; ++ } ++#endif ++ ++ if (cdevErr == 0) ++ cdev_del(&gWmtCdev); ++ ++ if (ret == 0) { ++ unregister_chrdev_region(devID, WMT_DEV_NUM); ++ gWmtMajor = -1; ++ } ++ ++ WMT_ERR_FUNC("fail\n"); ++ ++ return -1; ++} ++ ++static void WMT_exit(void) ++{ ++ dev_t dev = MKDEV(gWmtMajor, 0); ++ ++ osal_sleepable_lock_deinit(&g_es_lr_lock); ++#ifdef CONFIG_EARLYSUSPEND ++ unregister_early_suspend(&wmt_early_suspend_handler); ++ WMT_INFO_FUNC("unregister_early_suspend finished\n"); ++#else ++ fb_unregister_client(&wmt_fb_notifier); ++#endif ++ ++ wmt_dev_bgw_desense_deinit(); ++ ++ wmt_lib_register_thermal_ctrl_cb(NULL); ++ ++ wmt_lib_deinit(); ++ ++#if CFG_WMT_DBG_SUPPORT ++ wmt_dev_dbg_remove(); ++#endif ++ ++#if CFG_WMT_PROC_FOR_AEE ++ wmt_dev_proc_for_aee_remove(); ++#endif ++#if WMT_CREATE_NODE_DYNAMIC ++ if (wmt_dev) { ++ device_destroy(wmt_class, dev); ++ wmt_dev = NULL; ++ } ++ if (wmt_class) { ++ class_destroy(wmt_class); ++ wmt_class = NULL; ++ } ++#endif ++ cdev_del(&gWmtCdev); ++ unregister_chrdev_region(dev, WMT_DEV_NUM); ++ gWmtMajor = -1; ++ ++ stp_drv_exit(); ++ ++ WMT_INFO_FUNC("done\n"); ++} ++ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++ ++int mtk_wcn_soc_common_drv_init(void) ++{ ++ return WMT_init(); ++ ++} ++EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init); ++void mtk_wcn_soc_common_drv_exit(void) ++{ ++ return WMT_exit(); ++} ++EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit); ++ ++#else ++module_init(WMT_init); ++module_exit(WMT_exit); ++#endif ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("MediaTek Inc WCN"); ++MODULE_DESCRIPTION("MTK WCN combo driver for WMT function"); ++ ++module_param(gWmtMajor, uint, 0); +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c +new file mode 100644 +index 000000000000..8d5c23732c1c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c +@@ -0,0 +1,610 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-EXP]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++ ++#include ++#include ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++wmt_wlan_probe_cb mtk_wcn_wlan_probe = NULL; ++wmt_wlan_remove_cb mtk_wcn_wlan_remove = NULL; ++wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt = NULL; ++wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr = NULL; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++OSAL_BIT_OP_VAR gBtWifiGpsState; ++OSAL_BIT_OP_VAR gGpsFmState; ++UINT32 gWifiProbed = 0; ++UINT32 gWmtDbgLvl = WMT_LOG_ERR; ++MTK_WCN_BOOL g_pwr_off_flag = MTK_WCN_BOOL_TRUE; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId) ++{ ++ P_OSAL_OP pOp; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ ++ pOp->op.opId = opId; ++ pOp->op.au4OpData[0] = type; ++ if (WMTDRV_TYPE_WIFI == type) ++ pSignal->timeoutValue = 4000; ++ /*donot block system server/init/netd from longer than 5s, in case of ANR happens*/ ++ else ++ pSignal->timeoutValue = (WMT_OPID_FUNC_ON == pOp->op.opId) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME; ++ ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ /*do not check return value, we will do this either way */ ++ wmt_lib_host_awake_get(); ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ wmt_lib_host_awake_put(); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ wmt_lib_host_awake_put(); ++ ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ else ++ WMT_WARN_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ return bRet; ++} ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) ++#endif ++{ ++ MTK_WCN_BOOL ret; ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday("############ BT OFF ====>"); ++ ++ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF); ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday("############ BT OFF <===="); ++ ++ return ret; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_func_off); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) ++#endif ++{ ++ MTK_WCN_BOOL ret; ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday("############ BT ON ====>"); ++ ++ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON); ++ ++ if (type == WMTDRV_TYPE_BT) ++ osal_printtimeofday(" ############BT ON <===="); ++ ++ return ret; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_func_on); ++#endif ++ ++VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type) ++{ ++ if (on) ++ mtk_wcn_wmt_func_on(type); ++ else ++ mtk_wcn_wmt_func_off(type); ++} ++ ++/* ++return value: ++enable/disable thermal sensor function: true(1)/false(0) ++read thermal sensor function:thermal value ++ ++*/ ++#if WMT_EXP_HID_API_EXPORT ++INT8 _mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) ++#else ++INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) ++#endif ++{ ++ P_OSAL_OP pOp; ++ P_WMT_OP pOpData; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ /*parameter validation check */ ++ if (WMTTHERM_MAX < eType || WMTTHERM_ENABLE > eType) { ++ WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ /*check if chip support thermal control function or not */ ++ bRet = wmt_lib_is_therm_ctrl_support(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_ERR_FUNC("thermal ctrl function not supported\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ pOpData = &pOp->op; ++ pOpData->opId = WMT_OPID_THERM_CTRL; ++ /*parameter fill */ ++ pOpData->au4OpData[0] = eType; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return -1; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); ++ /*0xFF means read error occurs */ ++ /*will return to function driver */ ++ pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE; ++ } else { ++ WMT_INFO_FUNC("OPID(%d) type(%d) return(%d) ok\n\n", ++ pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]); ++ } ++ /*return value will be put to lxop->op.au4OpData[1] */ ++ WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08x)\n", eType, pOpData->au4OpData[1]); ++ return (INT8) pOpData->au4OpData[1]; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++ENUM_WMTHWVER_TYPE_T _mtk_wcn_wmt_hwver_get(VOID) ++#else ++ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) ++#endif ++{ ++ /* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ ++ /* TODO: how do we extend for new chip and newer revision? */ ++ /* TODO: This way is hard to extend */ ++ return wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER); ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) ++#endif ++{ ++ P_OSAL_OP pOp; ++ P_WMT_OP pOpData; ++ MTK_WCN_BOOL bRet; ++ P_OSAL_SIGNAL pSignal; ++ ++ if (WMTDSNS_MAX <= eType) { ++ WMT_ERR_FUNC("invalid desense control command (%d)\n", eType); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ /*check if chip support thermal control function or not */ ++ bRet = wmt_lib_is_dsns_ctrl_support(); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_ERR_FUNC("thermal ctrl function not supported\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ pOpData = &pOp->op; ++ pOpData->opId = WMT_OPID_DSNS; ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ /*parameter fill */ ++ if ((WMTDSNS_FM_DISABLE <= eType) && (WMTDSNS_FM_GPS_ENABLE >= eType)) { ++ pOpData->au4OpData[0] = WMTDRV_TYPE_FM; ++ pOpData->au4OpData[1] = eType; ++ } ++ ++ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ if (MTK_WCN_BOOL_FALSE == bRet) ++ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); ++ else ++ WMT_INFO_FUNC("OPID(%d) type(%d) ok\n\n", pOpData->opId, pOpData->au4OpData[0]); ++ ++ return bRet; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++#else ++INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) ++#endif ++{ ++ return (INT32) wmt_lib_msgcb_reg(eType, pCb); ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++#else ++INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) ++#endif ++{ ++ return (INT32) wmt_lib_msgcb_unreg(eType); ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) ++#else ++INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) ++#endif ++{ ++ wmt_lib_ps_set_sdio_psop(own_cb); ++ return 0; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++INT32 _mtk_wcn_stp_wmt_sdio_host_awake(VOID) ++#else ++INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) ++#endif ++{ ++ wmt_lib_ps_irq_cb(); ++ return 0; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); ++#endif ++ ++#if WMT_EXP_HID_API_EXPORT ++MTK_WCN_BOOL _mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) ++#else ++MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) ++#endif ++{ ++ P_OSAL_OP pOp = NULL; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_WARN_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ wmt_lib_set_host_assert_info(type, reason, 1); ++ ++ pSignal = &pOp->signal; ++ ++ pOp->op.opId = WMT_OPID_CMD_TEST; ++ ++ pSignal->timeoutValue = MAX_EACH_WMT_CMD; ++ /*this test command should be run with usb cable connected, so no host awake is needed */ ++ /* wmt_lib_host_awake_get(); */ ++ pOp->op.au4OpData[0] = 0; ++ ++ /*wake up chip first */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed,assert flow abort\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ bRet = wmt_lib_put_act_op(pOp); ++ ENABLE_PSM_MONITOR(); ++ ++ /* wmt_lib_host_awake_put(); */ ++ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", ++ pOp->op.opId, ++ pOp->op.au4OpData[0], ++ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); ++ ++ return bRet; ++} ++#if !WMT_EXP_HID_API_EXPORT ++EXPORT_SYMBOL(mtk_wcn_wmt_assert); ++#endif ++ ++INT8 mtk_wcn_wmt_co_clock_flag_get(void) ++{ ++ return wmt_lib_co_clock_get(); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_co_clock_flag_get); ++ ++INT32 mtk_wcn_wmt_system_state_reset(void) ++{ ++ osal_memset(&gBtWifiGpsState, 0, osal_sizeof(gBtWifiGpsState)); ++ osal_memset(&gGpsFmState, 0, osal_sizeof(gGpsFmState)); ++ ++ return 0; ++} ++ ++INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo) ++{ ++ INT32 iRet = -1; ++ ++ if (!pWmtWlanCbInfo) { ++ WMT_ERR_FUNC("wlan cb info in null!\n"); ++ return -1; ++ } ++ ++ WMT_INFO_FUNC("wmt wlan cb register\n"); ++ mtk_wcn_wlan_probe = pWmtWlanCbInfo->wlan_probe_cb; ++ mtk_wcn_wlan_remove = pWmtWlanCbInfo->wlan_remove_cb; ++ mtk_wcn_wlan_bus_tx_cnt = pWmtWlanCbInfo->wlan_bus_cnt_get_cb; ++ mtk_wcn_wlan_bus_tx_cnt_clr = pWmtWlanCbInfo->wlan_bus_cnt_clr_cb; ++ ++ if (gWifiProbed) { ++ WMT_INFO_FUNC("wlan has been done power on,call probe directly\n"); ++ iRet = (*mtk_wcn_wlan_probe) (); ++ if (!iRet) { ++ WMT_INFO_FUNC("call wlan probe OK when do wlan register to wmt\n"); ++ gWifiProbed = 0; ++ } else { ++ WMT_ERR_FUNC("call wlan probe fail(%d) when do wlan register to wmt\n", iRet); ++ return -2; ++ } ++ } ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wlan_reg); ++ ++INT32 mtk_wcn_wmt_wlan_unreg(void) ++{ ++ WMT_INFO_FUNC("wmt wlan cb unregister\n"); ++ mtk_wcn_wlan_probe = NULL; ++ mtk_wcn_wlan_remove = NULL; ++ mtk_wcn_wlan_bus_tx_cnt = NULL; ++ mtk_wcn_wlan_bus_tx_cnt_clr = NULL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wlan_unreg); ++ ++MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value) ++{ ++ g_pwr_off_flag = value; ++ if (g_pwr_off_flag) ++ WMT_DBG_FUNC("enable connsys power off flag\n"); ++ else ++ WMT_INFO_FUNC("disable connsys power off, maybe need trigger coredump!\n"); ++ return g_pwr_off_flag; ++} ++EXPORT_SYMBOL(mtk_wcn_set_connsys_power_off_flag); ++ ++#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++VOID mtk_wcn_wmt_exp_init(void) ++{ ++ MTK_WCN_WMT_EXP_CB_INFO wmtExpCb = { ++ ++ .wmt_func_on_cb = _mtk_wcn_wmt_func_on, ++ .wmt_func_off_cb = _mtk_wcn_wmt_func_off, ++ .wmt_therm_ctrl_cb = _mtk_wcn_wmt_therm_ctrl, ++ .wmt_hwver_get_cb = _mtk_wcn_wmt_hwver_get, ++ .wmt_dsns_ctrl_cb = _mtk_wcn_wmt_dsns_ctrl, ++ .wmt_msgcb_reg_cb = _mtk_wcn_wmt_msgcb_reg, ++ .wmt_msgcb_unreg_cb = _mtk_wcn_wmt_msgcb_unreg, ++ .wmt_sdio_op_reg_cb = _mtk_wcn_stp_wmt_sdio_op_reg, ++ .wmt_sdio_host_awake_cb = _mtk_wcn_stp_wmt_sdio_host_awake, ++ .wmt_assert_cb = _mtk_wcn_wmt_assert ++ }; ++ ++ mtk_wcn_wmt_exp_cb_reg(&wmtExpCb); ++} ++ ++VOID mtk_wcn_wmt_exp_deinit(void) ++{ ++ mtk_wcn_wmt_exp_cb_unreg(); ++} ++#ifdef CONFIG_MTK_COMBO_ANT ++/* ++ ctrlId: get ram code status opId or ram code download opId ++ pBuf: pointer to ANT ram code ++ length: total length of ANT ram code ++*/ ++ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, ++ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq) ++{ ++ ENUM_WMT_ANT_RAM_STATUS eRet = 0; ++ P_OSAL_OP pOp = NULL; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; ++ P_OSAL_SIGNAL pSignal; ++ ++ /*1. parameter validation check */ ++ /*for WMT_ANT_RAM_GET_STATUS, ignore pBuf and length */ ++ /*for WMT_ANT_RAM_DOWNLOAD, ++ pBuf must not be NULL, kernel space memory pointer ++ length must be large than 0 */ ++ ++ if ((WMT_ANT_RAM_GET_STATUS > ctrlId) || (WMT_ANT_RAM_CTRL_MAX <= ctrlId)) { ++ WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); ++ eRet = WMT_ANT_RAM_PARA_ERR; ++ return eRet; ++ } ++ ++ if ((WMT_ANT_RAM_DOWNLOAD == ctrlId) && ++ ((NULL == pBuf) || ++ (0 >= length) || ++ (1000 < length) || (seq >= WMT_ANT_RAM_SEQ_MAX) || (seq < WMT_ANT_RAM_START_PKT))) { ++ eRet = WMT_ANT_RAM_PARA_ERR; ++ WMT_ERR_FUNC ++ ("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x),seq(%d) .\n", ++ ctrlId, pBuf, length, seq); ++ return eRet; ++ } ++ /*get WMT opId */ ++ pOp = wmt_lib_get_free_op(); ++ if (!pOp) { ++ WMT_DBG_FUNC("get_free_lxop fail\n"); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ ++ pSignal = &pOp->signal; ++ pSignal->timeoutValue = ++ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD; ++ ++ pOp->op.opId = ++ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? WMT_OPID_ANT_RAM_DOWN : WMT_OPID_ANT_RAM_STA_GET; ++ pOp->op.au4OpData[0] = (size_t) pBuf; ++ pOp->op.au4OpData[1] = length; ++ pOp->op.au4OpData[2] = seq; ++ ++ ++ /*disable PSM monitor */ ++ if (DISABLE_PSM_MONITOR()) { ++ WMT_ERR_FUNC("wake up failed\n"); ++ wmt_lib_put_op_to_free_queue(pOp); ++ return MTK_WCN_BOOL_FALSE; ++ } ++ /*wakeup wmtd thread */ ++ bRet = wmt_lib_put_act_op(pOp); ++ ++ /*enable PSM monitor */ ++ ENABLE_PSM_MONITOR(); ++ ++ WMT_DBG_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n", ++ pOp->op.opId, ++ bRet, ++ pOp->op.au4OpData[2], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); ++ ++ /*check return value and return result */ ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ eRet = WMT_ANT_RAM_OP_ERR; ++ } else { ++ eRet = (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? ++ WMT_ANT_RAM_DOWN_OK : ++ ((1 == pOp->op.au4OpData[2]) ? WMT_ANT_RAM_EXIST : WMT_ANT_RAM_NOT_EXIST); ++ } ++ ++ return eRet; ++ ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_ant_ram_ctrl); ++#endif ++ ++#endif ++VOID mtk_wcn_wmt_set_wifi_ver(UINT32 Value) ++{ ++ wmt_lib_soc_set_wifiver(Value); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_set_wifi_ver); +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +new file mode 100644 +index 000000000000..eb37baf87b02 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +@@ -0,0 +1,27 @@ ++ifeq ($(CONFIG_MTK_COMBO), y) ++ ++ccflags-y += \ ++ -I$(src)/../../linux/include \ ++ -I$(src)/../../linux/pri/include \ ++ -I$(src)/../../core/include \ ++ -I$(src)/../../include \ ++ -I$(src)/../include \ ++ -I$(src)/../../../common_detect \ ++ -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach \ ++ -DMTK_BT_HCI=1 ++ ++ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 ++ ++ifeq ($(CONFIG_MTK_TC1_FEATURE), y) ++ ccflags-y += -DCFG_TC1_FEATURE=1 ++else ++ ccflags-y += -DCFG_TC1_FEATURE=0 ++endif ++ ++obj-y += osal.o \ ++ bgw_desense.o \ ++ wmt_idc.o ++obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o ++obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o ++ ++endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c +new file mode 100644 +index 000000000000..11e45aa13087 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c +@@ -0,0 +1,153 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include "bgw_desense.h" ++ ++static struct sock *g_nl_sk; ++/* static struct sockaddr_nl src_addr, des_addr; */ ++/* static struct iovec iov; */ ++static int pid; ++/* static struct msghdr msg; */ ++ ++void bgw_destroy_netlink_kernel(void) ++{ ++ if (g_nl_sk != NULL) { ++ /* sock_release(g_nl_sk->sk_socket); */ ++ netlink_kernel_release(g_nl_sk); ++ MSG("release socket\n"); ++ return; ++ } ++ ERR("no socket yet\n"); ++} ++ ++void send_command_to_daemon(const int command /*struct sk_buff *skb */) ++{ ++/* ++ struct iphdr *iph; ++ struct ethhdr *ehdr; ++ */ ++ struct nlmsghdr *nlh; ++ struct sk_buff *nl_skb; ++ int res; ++ ++ MSG("here we will send command to native daemon\n"); ++/* if(skb == NULL) ++ { ++ ERR("invalid sk_buff\n"); ++ return; ++ } ++*/ ++ if (!g_nl_sk) { ++ ERR("invalid socket\n"); ++ return; ++ } ++ if (pid == 0) { ++ ERR("invalid native process pid\n"); ++ return; ++ } ++ /*alloc data buffer for sending to native */ ++ /*malloc data space at least 1500 bytes, which is ethernet data length */ ++ nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC); ++ if (nl_skb == NULL) { ++ ERR("malloc skb error\n"); ++ return; ++ } ++ MSG("malloc data space done\n"); ++ /* ++ ehdr = eth_hdr(skb); ++ iph = ip_hdr(skb); ++ */ ++ ++/* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */ ++ nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0); ++ if (nlh == NULL) { ++ MSG("nlh is NULL\n"); ++ kfree_skb(nl_skb); ++ return; ++ } ++ NETLINK_CB(nl_skb).portid = 0; ++ ++/* memcpy(NLMSG_DATA(nlh), ACK, 5); */ ++ *(char *)NLMSG_DATA(nlh) = command; ++ res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT); ++ if (res == 0) { ++ MSG("send to user space process error\n"); ++ return; ++ } ++ ERR("send to user space process done, data length = %d\n", res); ++} ++ ++static void nl_data_handler(struct sk_buff *__skb) ++{ ++ struct sk_buff *skb; ++ struct nlmsghdr *nlh; ++ int i; ++ int len; ++ char str[128]; ++ ++ MSG("we got netlink message\n"); ++ len = NLMSG_SPACE(MAX_NL_MSG_LEN); ++ skb = skb_get(__skb); ++ if (skb == NULL) ++ ERR("skb_get return NULL"); ++ if (skb->len >= NLMSG_SPACE(0)) { /*presume there is 5byte payload at leaset */ ++ MSG("length is enough\n"); ++ nlh = nlmsg_hdr(skb); /* point to data which include in skb */ ++ memcpy(str, NLMSG_DATA(nlh), sizeof(str)); ++ for (i = 0; i < 3; i++) ++ MSG("str[%d = %c]", i, str[i]); ++ MSG("str[0] = %d, str[1] = %d, str[2] = %d\n", str[0], str[1], str[2]); ++ if (str[0] == 'B' && str[1] == 'G' && str[2] == 'W') { ++ MSG("got native daemon init command, record it's pid\n"); ++ pid = nlh->nlmsg_pid; /*record the native process PID */ ++ MSG("native daemon pid is %d\n", pid); ++ } else { ++ ERR("this is not BGW message, ignore it\n"); ++ return; ++ } ++ } else { ++ ERR("not engouth data length\n"); ++ return; ++ } ++ ++ kfree_skb(skb); ++ ++ send_command_to_daemon(ACK); ++} ++ ++int bgw_init_socket(void) ++{ ++ struct netlink_kernel_cfg cfg; ++ ++ memset(&cfg, 0, sizeof(cfg)); ++ cfg.input = nl_data_handler; ++ ++ g_nl_sk = __netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg); ++ ++ if (g_nl_sk == NULL) { ++ ERR("netlink_kernel_create error\n"); ++ return -1; ++ } ++ MSG("netlink_kernel_create ok\n"); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c +new file mode 100644 +index 000000000000..959b68de2431 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c +@@ -0,0 +1,1211 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "osal_typedef.h" ++#include "osal.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ ++static UINT16 const crc16_table[256] = { ++ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, ++ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, ++ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, ++ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, ++ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, ++ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, ++ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, ++ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, ++ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, ++ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, ++ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, ++ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, ++ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, ++ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, ++ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, ++ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, ++ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, ++ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, ++ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, ++ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, ++ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, ++ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, ++ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, ++ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, ++ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, ++ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, ++ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, ++ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, ++ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, ++ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, ++ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, ++ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 ++}; ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*string operations*/ ++_osal_inline_ UINT32 osal_strlen(const char *str) ++{ ++ return strlen(str); ++} ++ ++_osal_inline_ INT32 osal_strcmp(const char *dst, const char *src) ++{ ++ return strcmp(dst, src); ++} ++ ++_osal_inline_ INT32 osal_strncmp(const char *dst, const char *src, UINT32 len) ++{ ++ return strncmp(dst, src, len); ++} ++ ++_osal_inline_ char *osal_strcpy(char *dst, const char *src) ++{ ++ return strcpy(dst, src); ++} ++ ++_osal_inline_ char *osal_strncpy(char *dst, const char *src, UINT32 len) ++{ ++ return strncpy(dst, src, len); ++} ++ ++_osal_inline_ char *osal_strcat(char *dst, const char *src) ++{ ++ return strcat(dst, src); ++} ++ ++_osal_inline_ char *osal_strncat(char *dst, const char *src, UINT32 len) ++{ ++ return strncat(dst, src, len); ++} ++ ++_osal_inline_ char *osal_strchr(const char *str, UINT8 c) ++{ ++ return strchr(str, c); ++} ++ ++_osal_inline_ char *osal_strsep(char **str, const char *c) ++{ ++ return strsep(str, c); ++} ++ ++_osal_inline_ int osal_strtol(const char *str, UINT32 adecimal, long *res) ++{ ++ return kstrtol(str, adecimal, res); ++} ++ ++_osal_inline_ char *osal_strstr(char *str1, const char *str2) ++{ ++ return strstr(str1, str2); ++} ++ ++INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...) ++{ ++ INT32 iRet = 0; ++ va_list args; ++ ++ /*va_start(args, fmt); */ ++ va_start(args, fmt); ++ /*iRet = snprintf(buf, len, fmt, args); */ ++ iRet = vsnprintf(buf, len, fmt, args); ++ va_end(args); ++ ++ return iRet; ++} ++ ++INT32 osal_err_print(const char *str, ...) ++{ ++ va_list args; ++ char tempString[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_err("%s", tempString); ++ ++ return 0; ++} ++ ++INT32 osal_dbg_print(const char *str, ...) ++{ ++ va_list args; ++ char tempString[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_debug("%s", tempString); ++ ++ return 0; ++} ++ ++INT32 osal_warn_print(const char *str, ...) ++{ ++ va_list args; ++ char tempString[DBG_LOG_STR_SIZE]; ++ ++ va_start(args, str); ++ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); ++ va_end(args); ++ ++ pr_warn("%s", tempString); ++ ++ return 0; ++} ++ ++INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line) ++{ ++ if (!expr) { ++ pr_warn("%s (%d)\n", file, line); ++ /*BUG_ON(!expr); */ ++#ifdef CFG_COMMON_GPIO_DBG_PIN ++/* package this part */ ++ mt_set_gpio_out(GPIO70, GPIO_OUT_ZERO); ++ pr_warn("toggle GPIO70\n"); ++ udelay(10); ++ mt_set_gpio_out(GPIO70, GPIO_OUT_ONE); ++#endif ++ return 1; ++ } ++ return 0; ++ ++} ++ ++INT32 osal_dbg_assert_aee(const char *module, const char *detail_description) ++{ ++ osal_err_print("[WMT-ASSERT]" "[E][Module]:%s, [INFO]%s\n", module, detail_description); ++ ++#ifdef WMT_PLAT_ALPS ++ /* aee_kernel_warning(module,detail_description); */ ++ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_WCN_ISSUE_INFO, module, detail_description); ++#endif ++ return 0; ++} ++ ++INT32 osal_sprintf(char *str, const char *format, ...) ++{ ++ INT32 iRet = 0; ++ va_list args; ++ ++ va_start(args, format); ++ iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args); ++ va_end(args); ++ ++ return iRet; ++} ++ ++_osal_inline_ VOID *osal_malloc(UINT32 size) ++{ ++ return vmalloc(size); ++} ++ ++_osal_inline_ VOID osal_free(const VOID *dst) ++{ ++ vfree(dst); ++} ++ ++_osal_inline_ VOID *osal_memset(VOID *buf, INT32 i, UINT32 len) ++{ ++ return memset(buf, i, len); ++} ++ ++_osal_inline_ VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len) ++{ ++#ifdef CONFIG_MTK_WCN_ARM64 ++ char *tmp; ++ const char *s; ++ size_t i; ++ ++ tmp = dst; ++ s = src; ++ for (i = 0; i < len; i++) ++ tmp[i] = s[i]; ++ ++ return dst; ++ ++#else ++ return memcpy(dst, src, len); ++#endif ++} ++ ++_osal_inline_ INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len) ++{ ++ return memcmp(buf1, buf2, len); ++} ++ ++_osal_inline_ UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length) ++{ ++ UINT16 crc = 0; ++ UINT32 i = 0; ++ ++ /* FIXME: Add STP checksum feature */ ++ crc = 0; ++ for (i = 0; i < length; i++, buffer++) ++ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; ++ ++ return crc; ++} ++ ++_osal_inline_ VOID osal_thread_show_stack(P_OSAL_THREAD pThread) ++{ ++ return show_stack(pThread->pThread, NULL); ++} ++ ++/* ++ *OSAL layer Thread Opeartion related APIs ++ * ++ * ++*/ ++_osal_inline_ INT32 osal_thread_create(P_OSAL_THREAD pThread) ++{ ++ pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName); ++ if (NULL == pThread->pThread) ++ return -1; ++ ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_thread_run(P_OSAL_THREAD pThread) ++{ ++ if (pThread->pThread) { ++ wake_up_process(pThread->pThread); ++ return 0; ++ } else { ++ return -1; ++ } ++} ++ ++_osal_inline_ INT32 osal_thread_stop(P_OSAL_THREAD pThread) ++{ ++ INT32 iRet; ++ ++ if ((pThread) && (pThread->pThread)) { ++ iRet = kthread_stop(pThread->pThread); ++ /* pThread->pThread = NULL; */ ++ return iRet; ++ } ++ return -1; ++} ++ ++_osal_inline_ INT32 osal_thread_should_stop(P_OSAL_THREAD pThread) ++{ ++ if ((pThread) && (pThread->pThread)) ++ return kthread_should_stop(); ++ else ++ return 1; ++ ++} ++ ++_osal_inline_ INT32 ++osal_thread_wait_for_event(P_OSAL_THREAD pThread, P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker) ++{ ++ /* P_DEV_WMT pDevWmt;*/ ++ ++ if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) { ++ /* pDevWmt = (P_DEV_WMT)(pThread->pThreadData);*/ ++ return wait_event_interruptible(pEvent->waitQueue, (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) || */ ++ osal_thread_should_stop(pThread) ++ || (*pChecker) (pThread))); ++ } ++ return -1; ++} ++ ++_osal_inline_ INT32 osal_thread_destroy(P_OSAL_THREAD pThread) ++{ ++ if (pThread && (pThread->pThread)) { ++ kthread_stop(pThread->pThread); ++ pThread->pThread = NULL; ++ } ++ return 0; ++} ++ ++/* ++ *OSAL layer Signal Opeartion related APIs ++ *initialization ++ *wait for signal ++ *wait for signal timerout ++ *raise signal ++ *destroy a signal ++ * ++*/ ++ ++_osal_inline_ INT32 osal_signal_init(P_OSAL_SIGNAL pSignal) ++{ ++ if (pSignal) { ++ init_completion(&pSignal->comp); ++ return 0; ++ } else { ++ return -1; ++ } ++} ++ ++_osal_inline_ INT32 osal_wait_for_signal(P_OSAL_SIGNAL pSignal) ++{ ++ if (pSignal) { ++ wait_for_completion_interruptible(&pSignal->comp); ++ return 0; ++ } else { ++ return -1; ++ } ++} ++ ++_osal_inline_ INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal) ++{ ++ /* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */ ++ /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. ++ * Avoid using *interruptible" version in order to complete our jobs, such ++ * as function off gracefully. ++ */ ++ return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); ++} ++ ++_osal_inline_ INT32 osal_raise_signal(P_OSAL_SIGNAL pSignal) ++{ ++ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ ++ complete(&pSignal->comp); ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_signal_deinit(P_OSAL_SIGNAL pSignal) ++{ ++ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ ++ pSignal->timeoutValue = 0; ++ return 0; ++} ++ ++/* ++ *OSAL layer Event Opeartion related APIs ++ *initialization ++ *wait for signal ++ *wait for signal timerout ++ *raise signal ++ *destroy a signal ++ * ++*/ ++ ++INT32 osal_event_init(P_OSAL_EVENT pEvent) ++{ ++ init_waitqueue_head(&pEvent->waitQueue); ++ ++ return 0; ++} ++ ++INT32 osal_wait_for_event(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) ++{ ++ return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa)); ++} ++ ++INT32 osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) ++{ ++ return wait_event_interruptible_timeout(pEvent->waitQueue, condition(cond_pa), ++ msecs_to_jiffies(pEvent->timeoutValue)); ++} ++ ++INT32 osal_trigger_event(P_OSAL_EVENT pEvent) ++{ ++ INT32 ret = 0; ++ ++ wake_up_interruptible(&pEvent->waitQueue); ++ return ret; ++} ++ ++INT32 osal_event_deinit(P_OSAL_EVENT pEvent) ++{ ++ return 0; ++} ++ ++_osal_inline_ long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) ++{ ++ UINT32 ms = pEvent->timeoutValue; ++ ++ if (ms != 0) { ++ return wait_event_interruptible_timeout(pEvent->waitQueue, test_bit(bitOffset, pState), ++ msecs_to_jiffies(ms)); ++ } else { ++ return wait_event_interruptible(pEvent->waitQueue, test_bit(bitOffset, pState)); ++ } ++ ++} ++ ++_osal_inline_ long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) ++{ ++ UINT32 ms = pEvent->timeoutValue; ++ ++ if (ms != 0) { ++ return wait_event_interruptible_timeout(pEvent->waitQueue, !test_bit(bitOffset, pState), ++ msecs_to_jiffies(ms)); ++ } else { ++ return wait_event_interruptible(pEvent->waitQueue, !test_bit(bitOffset, pState)); ++ } ++ ++} ++ ++/* ++ *bit test and set/clear operations APIs ++ * ++ * ++*/ ++#if OS_BIT_OPS_SUPPORT ++#define osal_bit_op_lock(x) ++#define osal_bit_op_unlock(x) ++#else ++ ++_osal_inline_ INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) ++{ ++ ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) ++{ ++ ++ return 0; ++} ++#endif ++_osal_inline_ INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ osal_bit_op_lock(&(pData->opLock)); ++ clear_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ osal_bit_op_lock(&(pData->opLock)); ++ set_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return 0; ++} ++ ++_osal_inline_ INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ UINT32 iRet = 0; ++ ++ osal_bit_op_lock(&(pData->opLock)); ++ iRet = test_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return iRet; ++} ++ ++_osal_inline_ INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ UINT32 iRet = 0; ++ ++ osal_bit_op_lock(&(pData->opLock)); ++ iRet = test_and_clear_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return iRet; ++ ++} ++ ++_osal_inline_ INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) ++{ ++ UINT32 iRet = 0; ++ ++ osal_bit_op_lock(&(pData->opLock)); ++ iRet = test_and_set_bit(bitOffset, &pData->data); ++ osal_bit_op_unlock(&(pData->opLock)); ++ return iRet; ++} ++ ++/* ++ *tiemr operations APIs ++ *create ++ *stop ++ * modify ++ *create ++ *delete ++ * ++*/ ++ ++INT32 osal_timer_create(P_OSAL_TIMER pTimer) ++{ ++ struct timer_list *timer = &pTimer->timer; ++ ++ /*init_timer(timer); ++ timer->function = pTimer->timeoutHandler; ++ timer->data = (unsigned long)pTimer->timeroutHandlerData;*/ ++ timer_setup(timer,pTimer->timeoutHandler,0); ++ return 0; ++} ++ ++INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms) ++{ ++ ++ struct timer_list *timer = &pTimer->timer; ++ ++ timer->expires = jiffies + (ms / (1000 / HZ)); ++ add_timer(timer); ++ return 0; ++} ++ ++INT32 osal_timer_stop(P_OSAL_TIMER pTimer) ++{ ++ struct timer_list *timer = &pTimer->timer; ++ ++ del_timer(timer); ++ return 0; ++} ++ ++INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer) ++{ ++ struct timer_list *timer = &pTimer->timer; ++ ++ del_timer_sync(timer); ++ return 0; ++} ++ ++INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms) ++{ ++ ++ mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ)); ++ return 0; ++} ++ ++INT32 _osal_fifo_init(OSAL_FIFO *pFifo, UINT8 *buf, UINT32 size) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = -1; ++ ++ if (!pFifo) { ++ pr_err("pFifo must be !NULL\n"); ++ return -1; ++ } ++ if (pFifo->pFifoBody) { ++ pr_err("pFifo->pFifoBody must be NULL\n"); ++ pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody); ++ return -1; ++ } ++ fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); ++ if (!buf) { ++ /*fifo's buffer is not ready, we allocate automatically */ ++ ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC); ++ } else { ++ if (is_power_of_2(size)) { ++ kfifo_init(fifo, buf, size); ++ ret = 0; ++ } else { ++ kfifo_free(fifo); ++ fifo = NULL; ++ ret = -1; ++ } ++ } ++ ++ pFifo->pFifoBody = fifo; ++ return (ret < 0) ? (-1) : (0); ++} ++ ++INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ kfifo_free(fifo); ++ ++ return 0; ++} ++ ++INT32 _osal_fifo_size(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_size(fifo); ++ ++ return ret; ++} ++ ++/*returns unused bytes in fifo*/ ++INT32 _osal_fifo_avail_size(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_avail(fifo); ++ ++ return ret; ++} ++ ++/*returns used bytes in fifo*/ ++INT32 _osal_fifo_len(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_len(fifo); ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_is_empty(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_is_empty(fifo); ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ ret = kfifo_is_full(fifo); ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_data_in(OSAL_FIFO *pFifo, const VOID *buf, UINT32 len) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) { ++ ret = kfifo_in(fifo, buf, len); ++ } else { ++ pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n", ++ __func__, len, _osal_fifo_avail_size(pFifo), buf); ++ ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, UINT32 len) ++{ ++ struct kfifo *fifo = NULL; ++ INT32 ret = 0; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo && buf && (len <= _osal_fifo_len(pFifo))) { ++ ret = kfifo_out(fifo, buf, len); ++ } else { ++ pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n", ++ __func__, len, _osal_fifo_len(pFifo), buf); ++ ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++INT32 _osal_fifo_reset(OSAL_FIFO *pFifo) ++{ ++ struct kfifo *fifo = NULL; ++ ++ if (!pFifo || !pFifo->pFifoBody) { ++ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ fifo = (struct kfifo *)pFifo->pFifoBody; ++ ++ if (fifo) ++ kfifo_reset(fifo); ++ ++ return 0; ++} ++ ++INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size) ++{ ++ if (!pFifo) { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ return -1; ++ } ++ ++ pFifo->FifoInit = _osal_fifo_init; ++ pFifo->FifoDeInit = _osal_fifo_deinit; ++ pFifo->FifoSz = _osal_fifo_size; ++ pFifo->FifoAvailSz = _osal_fifo_avail_size; ++ pFifo->FifoLen = _osal_fifo_len; ++ pFifo->FifoIsEmpty = _osal_fifo_is_empty; ++ pFifo->FifoIsFull = _osal_fifo_is_full; ++ pFifo->FifoDataIn = _osal_fifo_data_in; ++ pFifo->FifoDataOut = _osal_fifo_data_out; ++ pFifo->FifoReset = _osal_fifo_reset; ++ ++ if (NULL != pFifo->pFifoBody) { ++ pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__); ++ pFifo->FifoDeInit(pFifo->pFifoBody); ++ pFifo->pFifoBody = NULL; ++ } ++ ++ pFifo->FifoInit(pFifo, buffer, size); ++ ++ return 0; ++} ++ ++VOID osal_fifo_deinit(P_OSAL_FIFO pFifo) ++{ ++ if (pFifo) ++ pFifo->FifoDeInit(pFifo); ++ else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ return; ++ } ++ kfree(pFifo->pFifoBody); ++} ++ ++INT32 osal_fifo_reset(P_OSAL_FIFO pFifo) ++{ ++ INT32 ret = -1; ++ ++ if (pFifo) { ++ ret = pFifo->FifoReset(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = -1; ++ } ++ return ret; ++} ++ ++UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoDataIn(pFifo, buffer, size); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoDataOut(pFifo, buffer, size); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_len(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoLen(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoSz(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoAvailSz(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoIsEmpty(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo) ++{ ++ UINT32 ret = 0; ++ ++ if (pFifo) { ++ ret = pFifo->FifoIsFull(pFifo); ++ } else { ++ pr_err("%s:pFifo = NULL, error\n", __func__); ++ ret = 0; ++ } ++ return ret; ++} ++ ++INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ wakeup_source_init(&pLock->wake_lock, pLock->name); ++ #else ++ wake_lock_init(&pLock->wake_lock, WAKE_LOCK_SUSPEND, pLock->name); ++ #endif ++ return 0; ++} ++ ++INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ wakeup_source_trash(&pLock->wake_lock); ++ #else ++ wake_lock_destroy(&pLock->wake_lock); ++ #endif ++ return 0; ++} ++ ++INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_stay_awake(&pLock->wake_lock); ++ #else ++ wake_lock(&pLock->wake_lock); ++ #endif ++ ++ return 0; ++} ++ ++INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock) ++{ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_relax(&pLock->wake_lock); ++ #else ++ wake_unlock(&pLock->wake_lock); ++ #endif ++ ++ return 0; ++ ++} ++ ++INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock) ++{ ++ INT32 count = 0; ++ ++ if (!pLock) ++ return -1; ++ ++ #ifdef CONFIG_PM_WAKELOCKS ++ count = pLock->wake_lock.active; ++ #else ++ count = wake_lock_active(&pLock->wake_lock); ++ #endif ++ return count; ++} ++ ++/* ++ *sleepable lock operations APIs ++ *init ++ *lock ++ *unlock ++ *destroy ++ * ++*/ ++ ++#if !defined(CONFIG_PROVE_LOCKING) ++INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ spin_lock_init(&(pUSL->lock)); ++ return 0; ++} ++#endif ++ ++INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ spin_lock_irqsave(&(pUSL->lock), pUSL->flag); ++ return 0; ++} ++ ++INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); ++ return 0; ++} ++ ++INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL) ++{ ++ return 0; ++} ++ ++/* ++ *unsleepable operations APIs ++ *init ++ *lock ++ *unlock ++ *destroy ++ ++ * ++*/ ++ ++#if !defined(CONFIG_PROVE_LOCKING) ++INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ mutex_init(&pSL->lock); ++ return 0; ++} ++#endif ++ ++INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ return mutex_lock_killable(&pSL->lock); ++} ++ ++INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ mutex_unlock(&pSL->lock); ++ return 0; ++} ++ ++INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL) ++{ ++ mutex_destroy(&pSL->lock); ++ return 0; ++} ++ ++INT32 osal_sleep_ms(UINT32 ms) ++{ ++ msleep(ms); ++ return 0; ++} ++ ++INT32 osal_udelay(UINT32 us) ++{ ++ udelay(us); ++ return 0; ++} ++ ++INT32 osal_gettimeofday(PINT32 sec, PINT32 usec) ++{ ++ INT32 ret = 0; ++ struct timeval now; ++ ++ do_gettimeofday(&now); ++ ++ if (sec != NULL) ++ *sec = now.tv_sec; ++ else ++ ret = -1; ++ ++ if (usec != NULL) ++ *usec = now.tv_usec; ++ else ++ ret = -1; ++ ++ return ret; ++} ++ ++INT32 osal_printtimeofday(const PUINT8 prefix) ++{ ++ INT32 ret; ++ INT32 sec; ++ INT32 usec; ++ ++ ret = osal_gettimeofday(&sec, &usec); ++ ret += osal_dbg_print("%s>sec=%d, usec=%d\n", prefix, sec, usec); ++ ++ return ret; ++} ++ ++VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, const UINT32 len, const UINT32 limit) ++{ ++ INT32 k; ++ UINT32 dump_len; ++ ++ pr_warn("start of dump>[%s] len=%d, limit=%d,", title, len, limit); ++ ++ dump_len = ((0 != limit) && (len > limit)) ? limit : len; ++#if 0 ++ if (limit != 0) ++ len = (len > limit) ? (limit) : (len); ++ ++#endif ++ ++ for (k = 0; k < dump_len; k++) { ++ if ((k != 0) && (k % 16 == 0)) ++ pr_cont("\n"); ++ pr_cont("0x%02x ", buf[k]); ++ } ++ pr_warn("op.opId : 0xFFFFFFFF; ++} ++ ++MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp) ++{ ++ return (pOp && pOp->signal.timeoutValue) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; ++} ++ ++VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result) ++{ ++ if (pOp) { ++ pOp->result = result; ++ osal_raise_signal(&pOp->signal); ++ } ++} ++ ++VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result) ++{ ++ if (pOp) ++ pOp->result = result; ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c +new file mode 100644 +index 000000000000..190fa3944d80 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c +@@ -0,0 +1,899 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if WMT_CREATE_NODE_DYNAMIC ++#include ++#endif ++#include ++ ++#include "osal_typedef.h" ++#include "stp_exp.h" ++#include "wmt_exp.h" ++ ++MODULE_LICENSE("Dual BSD/GPL"); ++ ++#ifdef MTK_BT_HCI ++#define MTK_BT_DEBUG 0 ++#include ++#include ++#endif ++ ++ ++#define BT_DRIVER_NAME "mtk_stp_BT_chrdev" ++#define BT_DEV_MAJOR 192 /* Never used number */ ++ ++#define PFX "[MTK-BT] " ++#define BT_LOG_DBG 3 ++#define BT_LOG_INFO 2 ++#define BT_LOG_WARN 1 ++#define BT_LOG_ERR 0 ++ ++#define COMBO_IOC_MAGIC 0xb0 ++#define COMBO_IOCTL_FW_ASSERT _IOWR(COMBO_IOC_MAGIC, 0, int) ++#define COMBO_IOCTL_BT_IC_HW_VER _IOWR(COMBO_IOC_MAGIC, 1, void*) ++#define COMBO_IOCTL_BT_IC_FW_VER _IOWR(COMBO_IOC_MAGIC, 2, void*) ++#define COMBO_IOC_BT_HWVER _IOWR(COMBO_IOC_MAGIC, 3, void*) ++ ++static UINT32 gDbgLevel = BT_LOG_INFO; ++ ++#define BT_DBG_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_DBG) \ ++ pr_debug(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++#define BT_INFO_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_INFO) \ ++ pr_warn(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++#define BT_WARN_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_WARN) \ ++ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++#define BT_ERR_FUNC(fmt, arg...) \ ++ do { if (gDbgLevel >= BT_LOG_ERR) \ ++ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ ++ } while (0) ++ ++#define VERSION "1.0" ++ ++#ifdef MTK_BT_HCI ++ ++#define NUM_REASSEMBLY 32 ++struct mtk_hci { ++ struct hci_dev *hdev; ++ struct work_struct work; ++ struct sk_buff_head txq; ++ struct sk_buff *reassembly[NUM_REASSEMBLY]; ++}; ++ ++static struct mtk_hci mtk_hci; ++ ++#endif ++ ++#if WMT_CREATE_NODE_DYNAMIC ++struct class *stpbt_class = NULL; ++struct device *stpbt_dev = NULL; ++#endif ++ ++static INT32 BT_devs = 1; /* Device count */ ++static INT32 BT_major = BT_DEV_MAJOR; /* Dynamic allocation */ ++module_param(BT_major, uint, 0); ++static struct cdev BT_cdev; ++ ++#define BT_BUFFER_SIZE 2048 ++static UINT8 i_buf[BT_BUFFER_SIZE]; /* Input buffer of read() */ ++static UINT8 o_buf[BT_BUFFER_SIZE]; /* Output buffer of write() */ ++ ++static struct semaphore wr_mtx, rd_mtx; ++/* Wait queue for poll and read */ ++static wait_queue_head_t inq; ++static DECLARE_WAIT_QUEUE_HEAD(BT_wq); ++static INT32 flag; ++/* Reset flag for whole chip reset senario */ ++static volatile INT32 rstflag; ++ ++#ifdef MTK_BT_HCI ++static int hci_reassembly(struct hci_dev *hdev, int type, void *data, ++ int count, __u8 index) ++{ ++ int len = 0; ++ int hlen = 0; ++ int offset = 0; ++ int remain = count; ++ struct sk_buff *skb; ++ struct bt_skb_cb *scb; ++ u16 opcode = 0; ++ unsigned char *pdata = data; ++ ++ struct mtk_hci *info = NULL; ++ struct hci_event_hdr *ehdr = NULL; ++ struct hci_ev_cmd_complete *ev = NULL; ++ struct hci_rp_read_local_ext_features *ext = NULL; ++ ++ info = hci_get_drvdata(hdev); ++ if ( NULL == info ) { ++ printk(KERN_ERR "mtk_bt_hci: invalid info point\n"); ++ return 0; ++ } ++ ++ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || ++ index >= NUM_REASSEMBLY) ++ return -EILSEQ; ++ ++ skb = info->reassembly[index]; ++ ++ if (!skb) { ++ switch (type) { ++ case HCI_ACLDATA_PKT: ++ len = HCI_MAX_FRAME_SIZE; ++ hlen = HCI_ACL_HDR_SIZE; ++ break; ++ case HCI_EVENT_PKT: ++ len = HCI_MAX_EVENT_SIZE; ++ hlen = HCI_EVENT_HDR_SIZE; ++ break; ++ case HCI_SCODATA_PKT: ++ len = HCI_MAX_SCO_SIZE; ++ hlen = HCI_SCO_HDR_SIZE; ++ break; ++ } ++ ++ skb = bt_skb_alloc(len, GFP_ATOMIC); ++ if (!skb) ++ return -ENOMEM; ++ ++ scb = (void *) skb->cb; ++ scb->expect = hlen; ++ scb->pkt_type = type; ++ ++ info->reassembly[index] = skb; ++ } ++ ++ while (count) { ++ scb = (void *) skb->cb; ++ len = min_t(uint, scb->expect, count); ++ ++ /* ++ * Workaround for MT7623+MT6625 BT: the max page in response of cmd READ_LOCAL_EXT_FEATURES ++ * should be 1, instead of 2, so changing it to 1 here ++ */ ++ ++ if (HCI_EVENT_PKT == type) ++ { ++ ehdr = (void *)pdata; ++ offset = sizeof(struct hci_event_hdr); ++ if ( HCI_EV_CMD_COMPLETE == ehdr->evt) ++ { ++ ev = (struct hci_ev_cmd_complete *)&pdata[offset]; ++ ++ offset += sizeof(struct hci_ev_cmd_complete); ++ ++ opcode = __le16_to_cpu(ev->opcode); ++ if(HCI_OP_READ_LOCAL_EXT_FEATURES == opcode) { ++ ext = (struct hci_rp_read_local_ext_features *) &pdata[offset]; ++ if( !ext->status && ext->max_page >= 2) { ++ pr_info("%s: this workaround is applied for mediatek BT\n", __func__); ++ ext->max_page = 1; ++ } ++ } ++ ++ } ++ } ++ ++ memcpy(skb_put(skb, len), data, len); ++ ++ count -= len; ++ data += len; ++ scb->expect -= len; ++ remain = count; ++ ++ switch (type) { ++ case HCI_EVENT_PKT: ++ if (skb->len == HCI_EVENT_HDR_SIZE) { ++ struct hci_event_hdr *h = hci_event_hdr(skb); ++ ++ scb->expect = h->plen; ++ ++ if (skb_tailroom(skb) < scb->expect) { ++ kfree_skb(skb); ++ info->reassembly[index] = NULL; ++ return -ENOMEM; ++ } ++ } ++ ++ break; ++ ++ case HCI_ACLDATA_PKT: ++ if (skb->len == HCI_ACL_HDR_SIZE) { ++ struct hci_acl_hdr *h = hci_acl_hdr(skb); ++ ++ scb->expect = __le16_to_cpu(h->dlen); ++ ++ if (skb_tailroom(skb) < scb->expect) { ++ kfree_skb(skb); ++ info->reassembly[index] = NULL; ++ return -ENOMEM; ++ } ++ } ++ break; ++ ++ case HCI_SCODATA_PKT: ++ if (skb->len == HCI_SCO_HDR_SIZE) { ++ struct hci_sco_hdr *h = hci_sco_hdr(skb); ++ ++ scb->expect = h->dlen; ++ ++ if (skb_tailroom(skb) < scb->expect) { ++ kfree_skb(skb); ++ info->reassembly[index] = NULL; ++ return -ENOMEM; ++ } ++ } ++ break; ++ } ++ ++ if (scb->expect == 0) { ++ /* Complete frame */ ++ ++ bt_cb(skb)->pkt_type = type; ++ hci_recv_frame(hdev, skb); ++ ++ info->reassembly[index] = NULL; ++ return remain; ++ } ++ } ++ ++ return remain; ++} ++ ++int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) ++{ ++ int rem = 0; ++ ++ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ++ return -EILSEQ; ++ ++ while (count) { ++ rem = hci_reassembly(hdev, type, data, count, type - 1); ++ if (rem < 0) ++ return rem; ++ ++ data += (count - rem); ++ count = rem; ++ } ++ ++ return rem; ++} ++#endif ++ ++#ifdef MTK_BT_HCI ++void ++hex_dump(char *prefix, char *p, int len) ++{ ++ int i; ++ ++ pr_err("%s ", prefix); ++ for (i = 0; i < len; i++) ++ pr_err("%02x ", (*p++ & 0xff)); ++ pr_err("\n"); ++} ++ ++static int ++mtk_bt_hci_open(struct hci_dev *hdev) ++{ ++ int err = 0; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ err = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); ++ if (err != MTK_WCN_BOOL_TRUE) { ++ pr_err("%s func on failed with %d\n", __func__, err); ++ return -ENODEV; ++ } ++ ++ set_bit(HCI_RUNNING, &hdev->flags); ++ ++ mtk_wcn_stp_set_bluez(1); ++ ++ return 0; ++} ++ ++static int ++mtk_bt_hci_close(struct hci_dev *hdev) ++{ ++ int err = 0; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ mtk_wcn_stp_set_bluez(0); ++ ++ clear_bit(HCI_RUNNING, &hdev->flags); ++ ++ err = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); ++ if (err != MTK_WCN_BOOL_TRUE) { ++ pr_err("%s func off failed with %d\n", __func__, err); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static void ++mtk_bt_hci_work(struct work_struct *work) ++{ ++ int err; ++ struct sk_buff *skb; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ while ((skb = skb_dequeue(&mtk_hci.txq))) { ++ skb_push(skb, 1); ++ skb->data[0] = bt_cb(skb)->pkt_type; ++ ++#if MTK_BT_DEBUG == 1 ++ hex_dump(">>", skb->data, skb->len); ++#endif ++ ++ err = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX); ++ if (err < 0) { ++ pr_err("%s err=%d\n", __func__, err); ++ mtk_hci.hdev->stat.err_tx++; ++ skb_queue_head(&mtk_hci.txq, skb); ++ break; ++ } ++ ++ mtk_hci.hdev->stat.byte_tx += skb->len; ++ kfree_skb(skb); ++ } ++} ++ ++static int ++mtk_bt_hci_send(struct hci_dev *hdev, struct sk_buff *skb) ++{ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++#endif ++ ++ if (mtk_hci.hdev && !test_bit(HCI_RUNNING, &mtk_hci.hdev->flags)) ++ return -EBUSY; ++ ++ switch (bt_cb(skb)->pkt_type) { ++ case HCI_COMMAND_PKT: ++ mtk_hci.hdev->stat.cmd_tx++; ++ break; ++ ++ case HCI_ACLDATA_PKT: ++ mtk_hci.hdev->stat.acl_tx++; ++ break; ++ ++ case HCI_SCODATA_PKT: ++ mtk_hci.hdev->stat.sco_tx++; ++ break; ++ ++ default: ++ return -EILSEQ; ++ } ++ ++ skb_queue_tail(&mtk_hci.txq, skb); ++ schedule_work(&mtk_hci.work); ++ ++ return 0; ++} ++ ++static int ++mtk_bt_hci_flush(struct hci_dev *hdev) ++{ ++ pr_err("%s: todo\n", __func__); ++ ++ return 0; ++} ++ ++static void ++mtk_bt_hci_receive(const PUINT8 data, INT32 size) ++{ ++ int err; ++ ++#if MTK_BT_DEBUG == 1 ++ pr_err("# %s\n", __func__); ++ hex_dump("<<", data, size); ++#endif ++ ++ err = hci_recv_fragment(mtk_hci.hdev, data[0], (void *)&data[1], size - 1); ++ if (err < 0) ++ pr_err("%s: hci_recv_fragment failed with %d\n", __func__, err); ++ ++ if (mtk_hci.hdev) ++ mtk_hci.hdev->stat.byte_rx += size - 1; ++} ++ ++static void ++mtk_bt_hci_notify(struct hci_dev *hdev, unsigned int evt) ++{ ++ static const char * const notify_str[] = { ++ "null", ++ "HCI_NOTIFY_CONN_ADD", ++ "HCI_NOTIFY_CONN_DEL", ++ "HCI_NOTIFY_VOICE_SETTING" ++ }; ++ ++ if (evt > HCI_NOTIFY_VOICE_SETTING) ++ pr_info("%s event=0x%x\n", __func__, evt); ++ else ++ pr_info("%s event(%d)=%s\n", __func__, evt, notify_str[evt]); ++} ++#endif ++ ++#ifdef MTK_BT_HCI ++ ++int mtk_bt_hci_init(void) ++{ ++ INT32 hci_err = 0; ++ ++ mtk_hci.hdev = hci_alloc_dev(); ++ if (!(mtk_hci.hdev)) { ++ mtk_hci.hdev = NULL; ++ BT_ERR_FUNC("%s hci_alloc_dev failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ mtk_hci.hdev->bus = HCI_SDIO; ++ mtk_hci.hdev->open = mtk_bt_hci_open; ++ mtk_hci.hdev->close = mtk_bt_hci_close; ++ mtk_hci.hdev->send = mtk_bt_hci_send; ++ mtk_hci.hdev->flush = mtk_bt_hci_flush; ++ mtk_hci.hdev->notify = mtk_bt_hci_notify; ++ SET_HCIDEV_DEV(mtk_hci.hdev, stpbt_dev); ++ ++ hci_set_drvdata(mtk_hci.hdev, &mtk_hci); ++ ++ mtk_wcn_stp_register_if_rx(mtk_bt_hci_receive); ++ ++ hci_err = hci_register_dev(mtk_hci.hdev); ++ if (hci_err) { ++ BT_ERR_FUNC("%s hci_register_dev failed with %d\n", __func__, hci_err); ++ hci_free_dev(mtk_hci.hdev); ++ mtk_hci.hdev = NULL; ++ return hci_err; ++ } ++ ++ skb_queue_head_init(&mtk_hci.txq); ++ INIT_WORK(&mtk_hci.work, mtk_bt_hci_work); ++ ++ return 0; ++} ++#endif ++ ++ ++static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, ++ ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz) ++{ ++ /* ++ Handle whole chip reset messages ++ */ ++ ENUM_WMTRSTMSG_TYPE_T rst_msg; ++ ++ if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) { ++ memcpy((PINT8)&rst_msg, (PINT8)buf, sz); ++ BT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src, ++ dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); ++ if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT) ++ && (type == WMTMSG_TYPE_RESET)) { ++ if (rst_msg == WMTRSTMSG_RESET_START) { ++ BT_INFO_FUNC("BT reset start!\n"); ++ rstflag = 1; ++ wake_up_interruptible(&inq); ++ ++ } else if (rst_msg == WMTRSTMSG_RESET_END) { ++ BT_INFO_FUNC("BT reset end!\n"); ++ rstflag = 2; ++ wake_up_interruptible(&inq); ++ } ++ } ++ } else { ++ /* Invalid message format */ ++ BT_WARN_FUNC("Invalid message format!\n"); ++ } ++} ++ ++VOID BT_event_cb(VOID) ++{ ++ BT_DBG_FUNC("BT_event_cb()\n"); ++ ++ flag = 1; ++ ++ /* ++ * Finally, wake up any reader blocked in poll or read ++ */ ++ wake_up_interruptible(&inq); ++ wake_up(&BT_wq); ++} ++ ++unsigned int BT_poll(struct file *filp, poll_table *wait) ++{ ++ UINT32 mask = 0; ++ ++/* down(&wr_mtx); */ ++ /* ++ * The buffer is circular; it is considered full ++ * if "wp" is right behind "rp". "left" is 0 if the ++ * buffer is empty, and it is "1" if it is completely full. ++ */ ++ if (mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX)) { ++ poll_wait(filp, &inq, wait); ++ ++ if (!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) || rstflag) ++ /* BT Rx queue has valid data, or whole chip reset occurs */ ++ mask |= POLLIN | POLLRDNORM; /* Readable */ ++ } else { ++ mask |= POLLIN | POLLRDNORM; /* Readable */ ++ } ++ ++ /* Do we need condition here? */ ++ mask |= POLLOUT | POLLWRNORM; /* Writable */ ++/* up(&wr_mtx); */ ++ return mask; ++} ++ ++ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 retval = 0; ++ INT32 write_size; ++ INT32 written = 0; ++ ++ down(&wr_mtx); ++ ++ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); ++ if (rstflag) { ++ if (rstflag == 1) { /* Reset start */ ++ retval = -88; ++ BT_INFO_FUNC("%s: detect whole chip reset start\n", __func__); ++ } else if (rstflag == 2) { /* Reset end */ ++ retval = -99; ++ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); ++ } ++ goto OUT; ++ } ++ ++ if (count > 0) { ++ if (count < BT_BUFFER_SIZE) { ++ write_size = count; ++ } else { ++ write_size = BT_BUFFER_SIZE; ++ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); ++ } ++ ++ if (copy_from_user(&o_buf[0], &buf[0], write_size)) { ++ retval = -EFAULT; ++ goto OUT; ++ } ++ ++ written = mtk_wcn_stp_send_data(&o_buf[0], write_size, BT_TASK_INDX); ++ if (0 == written) { ++ retval = -ENOSPC; ++ /* No space is available, native program should not call BT_write with no delay */ ++ BT_ERR_FUNC ++ ("Packet length %zd, sent length %d, retval = %d\n", ++ count, written, retval); ++ } else { ++ retval = written; ++ } ++ ++ } else { ++ retval = -EFAULT; ++ BT_ERR_FUNC("Packet length %zd is not allowed, retval = %d\n", count, retval); ++ } ++ ++OUT: ++ up(&wr_mtx); ++ return retval; ++} ++ ++ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ static int chip_reset_count; ++ INT32 retval = 0; ++ ++ down(&rd_mtx); ++ ++ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); ++ if (rstflag) { ++ if (rstflag == 1) { /* Reset start */ ++ retval = -88; ++ if ((chip_reset_count%500) == 0) ++ BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count); ++ chip_reset_count++; ++ } else if (rstflag == 2) { /* Reset end */ ++ retval = -99; ++ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); ++ chip_reset_count = 0; ++ } ++ goto OUT; ++ } ++ ++ if (count > BT_BUFFER_SIZE) { ++ count = BT_BUFFER_SIZE; ++ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); ++ } ++ ++ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); ++ ++ while (retval == 0) { /* Got nothing, wait for STP's signal */ ++ /* ++ * If nonblocking mode, return directly. ++ * O_NONBLOCK is specified during open() ++ */ ++ if (filp->f_flags & O_NONBLOCK) { ++ BT_DBG_FUNC("Non-blocking BT_read\n"); ++ retval = -EAGAIN; ++ goto OUT; ++ } ++ ++ BT_DBG_FUNC("%s: wait_event 1\n", __func__); ++ wait_event(BT_wq, flag != 0); ++ BT_DBG_FUNC("%s: wait_event 2\n", __func__); ++ flag = 0; ++ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); ++ BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval); ++ } ++ ++ /* Got something from STP driver */ ++ if (copy_to_user(buf, i_buf, retval)) { ++ retval = -EFAULT; ++ goto OUT; ++ } ++ ++OUT: ++ up(&rd_mtx); ++ BT_DBG_FUNC("%s: retval = %d\n", __func__, retval); ++ return retval; ++} ++ ++/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ ++long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ INT32 retval = 0; ++ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE; ++ ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; ++ ++ BT_DBG_FUNC("%s: cmd: 0x%x\n", __func__, cmd); ++ ++ switch (cmd) { ++ case COMBO_IOC_BT_HWVER: ++ /* Get combo HW version */ ++ hw_ver_sym = mtk_wcn_wmt_hwver_get(); ++ BT_INFO_FUNC("%s: HW version = %d, sizeof(hw_ver_sym) = %zd\n", ++ __func__, hw_ver_sym, sizeof(hw_ver_sym)); ++ if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) ++ retval = -EFAULT; ++ break; ++ ++ case COMBO_IOCTL_FW_ASSERT: ++ /* Trigger FW assert for debug */ ++ BT_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg); ++ bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg); ++ if (bRet == MTK_WCN_BOOL_TRUE) { ++ BT_INFO_FUNC("Host trigger FW assert succeed\n"); ++ retval = 0; ++ } else { ++ BT_ERR_FUNC("Host trigger FW assert Failed\n"); ++ retval = (-EBUSY); ++ } ++ break; ++ case COMBO_IOCTL_BT_IC_HW_VER: ++ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); ++ break; ++ case COMBO_IOCTL_BT_IC_FW_VER: ++ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); ++ break; ++ default: ++ retval = -EFAULT; ++ BT_ERR_FUNC("Unknown cmd (%d)\n", cmd); ++ break; ++ } ++ ++ return retval; ++} ++ ++long BT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ return BT_unlocked_ioctl(filp, cmd, arg); ++} ++ ++static int BT_open(struct inode *inode, struct file *file) ++{ ++ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); ++ ++ /* Turn on BT */ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) { ++ BT_WARN_FUNC("WMT turn on BT fail!\n"); ++ return -ENODEV; ++ } ++ ++ BT_INFO_FUNC("WMT turn on BT OK!\n"); ++ rstflag = 0; ++ ++ if (mtk_wcn_stp_is_ready()) { ++ ++ mtk_wcn_stp_set_bluez(0); ++ ++ BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n"); ++ BT_INFO_FUNC("STP is ready!\n"); ++ ++ BT_DBG_FUNC("Register BT event callback!\n"); ++ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb); ++ } else { ++ BT_ERR_FUNC("STP is not ready\n"); ++ mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); ++ return -ENODEV; ++ } ++ ++ BT_DBG_FUNC("Register BT reset callback!\n"); ++ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb); ++ ++ /* init_MUTEX(&wr_mtx); */ ++ sema_init(&wr_mtx, 1); ++ /* init_MUTEX(&rd_mtx); */ ++ sema_init(&rd_mtx, 1); ++ BT_INFO_FUNC("%s: finish\n", __func__); ++ ++ return 0; ++} ++ ++static int BT_close(struct inode *inode, struct file *file) ++{ ++ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); ++ rstflag = 0; ++ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT); ++ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); ++ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) { ++ BT_ERR_FUNC("WMT turn off BT fail!\n"); ++ return -EIO; /* Mostly, native program will not check this return value. */ ++ } ++ ++ BT_INFO_FUNC("WMT turn off BT OK!\n"); ++ ++ return 0; ++} ++ ++const struct file_operations BT_fops = { ++ .open = BT_open, ++ .release = BT_close, ++ .read = BT_read, ++ .write = BT_write, ++ /* .ioctl = BT_ioctl, */ ++ .unlocked_ioctl = BT_unlocked_ioctl, ++ .compat_ioctl = BT_compat_ioctl, ++ .poll = BT_poll ++}; ++ ++ ++ ++static int BT_init(void) ++{ ++ dev_t dev = MKDEV(BT_major, 0); ++ INT32 alloc_ret = 0; ++ INT32 cdev_err = 0; ++ ++ /* Static allocate char device */ ++ alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME); ++ if (alloc_ret) { ++ BT_ERR_FUNC("%s: Failed to register char device\n", __func__); ++ return alloc_ret; ++ } ++ ++ cdev_init(&BT_cdev, &BT_fops); ++ BT_cdev.owner = THIS_MODULE; ++ ++ cdev_err = cdev_add(&BT_cdev, dev, BT_devs); ++ if (cdev_err) ++ goto error; ++ ++#if WMT_CREATE_NODE_DYNAMIC ++ stpbt_class = class_create(THIS_MODULE, "stpbt"); ++ if (IS_ERR(stpbt_class)) ++ goto error; ++ stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt"); ++ if (IS_ERR(stpbt_dev)) ++ goto error; ++#endif ++ ++ BT_INFO_FUNC("%s driver(major %d) installed\n", BT_DRIVER_NAME, BT_major); ++ ++ /* Init wait queue */ ++ init_waitqueue_head(&(inq)); ++ ++#ifdef MTK_BT_HCI ++ mtk_bt_hci_init(); ++#endif ++ ++ return 0; ++ ++error: ++#if WMT_CREATE_NODE_DYNAMIC ++ if (!IS_ERR(stpbt_dev)) ++ device_destroy(stpbt_class, dev); ++ if (!IS_ERR(stpbt_class)) { ++ class_destroy(stpbt_class); ++ stpbt_class = NULL; ++ } ++#endif ++ if (cdev_err == 0) ++ cdev_del(&BT_cdev); ++ ++ if (alloc_ret == 0) ++ unregister_chrdev_region(dev, BT_devs); ++ ++ return -1; ++} ++ ++static void BT_exit(void) ++{ ++ dev_t dev = MKDEV(BT_major, 0); ++ ++#if WMT_CREATE_NODE_DYNAMIC ++ if (stpbt_dev) { ++ device_destroy(stpbt_class, dev); ++ stpbt_dev = NULL; ++ } ++ if (stpbt_class) { ++ class_destroy(stpbt_class); ++ stpbt_class = NULL; ++ } ++#endif ++ ++ cdev_del(&BT_cdev); ++ unregister_chrdev_region(dev, BT_devs); ++ ++ BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME); ++} ++ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++ ++int mtk_wcn_stpbt_drv_init(void) ++{ ++ return BT_init(); ++} ++EXPORT_SYMBOL(mtk_wcn_stpbt_drv_init); ++ ++void mtk_wcn_stpbt_drv_exit(void) ++{ ++ return BT_exit(); ++} ++EXPORT_SYMBOL(mtk_wcn_stpbt_drv_exit); ++ ++#else ++ ++module_init(BT_init); ++module_exit(BT_exit); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +new file mode 100644 +index 000000000000..3c7b2969c98a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +@@ -0,0 +1,668 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "wmt_exp.h" ++#include "stp_exp.h" ++ ++MODULE_LICENSE("Dual BSD/GPL"); ++ ++#define WIFI_DRIVER_NAME "mtk_wmt_WIFI_chrdev" ++#define WIFI_DEV_MAJOR 155 ++ ++#define PFX "[MTK-WIFI] " ++#define WIFI_LOG_DBG 3 ++#define WIFI_LOG_INFO 2 ++#define WIFI_LOG_WARN 1 ++#define WIFI_LOG_ERR 0 ++ ++UINT32 gDbgLevel = WIFI_LOG_DBG; ++ ++#define WIFI_DBG_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_INFO_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_INFO) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_WARN_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_WARN) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_ERR_FUNC(fmt, arg...)\ ++ do {if (gDbgLevel >= WIFI_LOG_ERR) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) ++#define WIFI_TRC_FUNC(f)\ ++ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "<%s> <%d>\n", __func__, __LINE__); } while (0) ++ ++#define VERSION "1.0" ++ ++#define WLAN_IFACE_NAME "wlan0" ++#if CFG_TC1_FEATURE ++#define LEGACY_IFACE_NAME "legacy0" ++#endif ++ ++enum { ++ WLAN_MODE_HALT, ++ WLAN_MODE_AP, ++ WLAN_MODE_STA_P2P, ++ WLAN_MODE_MAX ++}; ++static INT32 wlan_mode = WLAN_MODE_HALT; ++static INT32 powered; ++static INT8 *ifname = WLAN_IFACE_NAME; ++#if CFG_TC1_FEATURE ++volatile INT32 wlan_if_changed = 0; ++EXPORT_SYMBOL(wlan_if_changed); ++#endif ++ ++typedef enum _ENUM_RESET_STATUS_T { ++ RESET_FAIL, ++ RESET_SUCCESS ++} ENUM_RESET_STATUS_T; ++ ++/* ++ * enable = 1, mode = 0 => init P2P network ++ * enable = 1, mode = 1 => init Soft AP network ++ * enable = 0 => uninit P2P/AP network ++ */ ++typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { ++ UINT32 u4Enable; ++ UINT32 u4Mode; ++} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; ++typedef INT32(*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); ++ ++static set_p2p_mode pf_set_p2p_mode; ++VOID register_set_p2p_mode_handler(set_p2p_mode handler) ++{ ++ WIFI_INFO_FUNC("(pid %d) register set p2p mode handler %p\n", current->pid, handler); ++ pf_set_p2p_mode = handler; ++} ++EXPORT_SYMBOL(register_set_p2p_mode_handler); ++ ++/* For dynamical debug level setting */ ++/* copy of debug.h in wlan driver */ ++#define DBG_CLASS_ERROR BIT(0) ++#define DBG_CLASS_WARN BIT(1) ++#define DBG_CLASS_STATE BIT(2) ++#define DBG_CLASS_EVENT BIT(3) ++#define DBG_CLASS_TRACE BIT(4) ++#define DBG_CLASS_INFO BIT(5) ++#define DBG_CLASS_LOUD BIT(6) ++#define DBG_CLASS_TEMP BIT(7) ++#define DBG_CLASS_MASK BITS(0, 7) ++ ++typedef enum _ENUM_DBG_MODULE_T { ++ DBG_INIT_IDX = 0, /* For driver initial */ ++ DBG_HAL_IDX, /* For HAL(HW) Layer */ ++ DBG_INTR_IDX, /* For Interrupt */ ++ DBG_REQ_IDX, ++ DBG_TX_IDX, ++ DBG_RX_IDX, ++ DBG_RFTEST_IDX, /* For RF test mode */ ++ DBG_EMU_IDX, /* Developer specific */ ++ ++ DBG_SW1_IDX, /* Developer specific */ ++ DBG_SW2_IDX, /* Developer specific */ ++ DBG_SW3_IDX, /* Developer specific */ ++ DBG_SW4_IDX, /* Developer specific */ ++ ++ DBG_HEM_IDX, /* HEM */ ++ DBG_AIS_IDX, /* AIS */ ++ DBG_RLM_IDX, /* RLM */ ++ DBG_MEM_IDX, /* RLM */ ++ DBG_CNM_IDX, /* CNM */ ++ DBG_RSN_IDX, /* RSN */ ++ DBG_BSS_IDX, /* BSS */ ++ DBG_SCN_IDX, /* SCN */ ++ DBG_SAA_IDX, /* SAA */ ++ DBG_AAA_IDX, /* AAA */ ++ DBG_P2P_IDX, /* P2P */ ++ DBG_QM_IDX, /* QUE_MGT */ ++ DBG_SEC_IDX, /* SEC */ ++ DBG_BOW_IDX, /* BOW */ ++ DBG_WAPI_IDX, /* WAPI */ ++ DBG_ROAMING_IDX, /* ROAMING */ ++ ++ DBG_MODULE_NUM /* Notice the XLOG check */ ++} ENUM_DBG_MODULE_T; ++/* end */ ++typedef VOID(*set_dbg_level) (UINT8 modules[DBG_MODULE_NUM]); ++ ++UINT8 wlan_dbg_level[DBG_MODULE_NUM]; ++static set_dbg_level pf_set_dbg_level; ++VOID register_set_dbg_level_handler(set_dbg_level handler) ++{ ++ pf_set_dbg_level = handler; ++} ++EXPORT_SYMBOL(register_set_dbg_level_handler); ++ ++static INT32 WIFI_devs = 1; ++static INT32 WIFI_major = WIFI_DEV_MAJOR; ++module_param(WIFI_major, uint, 0); ++static struct cdev WIFI_cdev; ++volatile INT32 retflag = 0; ++static struct semaphore wr_mtx; ++ ++#define WMT_CHECK_DO_CHIP_RESET() \ ++do { \ ++ if (g_IsNeedDoChipReset) { \ ++ g_IsNeedDoChipReset = 0; \ ++ WIFI_ERR_FUNC("Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ ++ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); \ ++ } \ ++} while (0) ++ ++/******************************************************************* ++ * WHOLE CHIP RESET PROCEDURE: ++ * ++ * WMTRSTMSG_RESET_START callback ++ * -> wlanRemove ++ * -> WMTRSTMSG_RESET_END callback ++ * ++ ******************************************************************* ++*/ ++/*-----------------------------------------------------------------*/ ++/* ++ * Receiving RESET_START message ++ */ ++/*-----------------------------------------------------------------*/ ++INT32 wifi_reset_start(VOID) ++{ ++ struct net_device *netdev = NULL; ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ ++ down(&wr_mtx); ++ ++ if (powered == 1) { ++ netdev = dev_get_by_name(&init_net, ifname); ++ if (netdev == NULL) { ++ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); ++ } else { ++ p2pmode.u4Enable = 0; ++ p2pmode.u4Mode = 0; ++ ++ if (pf_set_p2p_mode) { ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) ++ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); ++ else ++ WIFI_INFO_FUNC("Turn off p2p/ap mode"); ++ } ++ dev_put(netdev); ++ netdev = NULL; ++ } ++ } else { ++ /* WIFI is off before whole chip reset, do nothing */ ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(wifi_reset_start); ++ ++/*-----------------------------------------------------------------*/ ++/* ++ * Receiving RESET_END/RESET_END_FAIL message ++ */ ++/*-----------------------------------------------------------------*/ ++INT32 wifi_reset_end(ENUM_RESET_STATUS_T status) ++{ ++ struct net_device *netdev = NULL; ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ INT32 wait_cnt = 0; ++ INT32 ret = -1; ++ ++ if (status == RESET_FAIL) { ++ /* whole chip reset fail, donot recover WIFI */ ++ ret = 0; ++ up(&wr_mtx); ++ } else if (status == RESET_SUCCESS) { ++ WIFI_WARN_FUNC("WIFI state recovering...\n"); ++ ++ if (powered == 1) { ++ /* WIFI is on before whole chip reset, reopen it now */ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); ++ goto done; ++ } else { ++ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); ++ } ++ ++ if (pf_set_p2p_mode == NULL) { ++ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); ++ goto done; ++ } ++ ++ netdev = dev_get_by_name(&init_net, ifname); ++ while (netdev == NULL && wait_cnt < 10) { ++ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); ++ msleep(300); ++ wait_cnt++; ++ netdev = dev_get_by_name(&init_net, ifname); ++ } ++ if (wait_cnt >= 10) { ++ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); ++ goto done; ++ } ++ ++ if (wlan_mode == WLAN_MODE_STA_P2P) { ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 0; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P); ++ ret = 0; ++ } ++ } else if (wlan_mode == WLAN_MODE_AP) { ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 1; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP); ++ ret = 0; ++ } ++ } ++done: ++ if (netdev != NULL) ++ dev_put(netdev); ++ } else { ++ /* WIFI is off before whole chip reset, do nothing */ ++ ret = 0; ++ } ++ up(&wr_mtx); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(wifi_reset_end); ++ ++static int WIFI_open(struct inode *inode, struct file *file) ++{ ++ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); ++ ++ return 0; ++} ++ ++static int WIFI_close(struct inode *inode, struct file *file) ++{ ++ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); ++ retflag = 0; ++ ++ return 0; ++} ++ ++ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) ++{ ++ INT32 retval = -EIO; ++ INT8 local[12] = { 0 }; ++ struct net_device *netdev = NULL; ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ INT32 wait_cnt = 0; ++ ++ down(&wr_mtx); ++ if (count <= 0) { ++ WIFI_ERR_FUNC("WIFI_write invalid param\n"); ++ goto done; ++ } ++ ++ if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { ++ local[11] = 0; ++ WIFI_INFO_FUNC("WIFI_write %s\n", local); ++ ++ if (local[0] == '0') { ++ if (powered == 0) { ++ WIFI_INFO_FUNC("WIFI is already power off!\n"); ++ retval = count; ++ wlan_mode = WLAN_MODE_HALT; ++ goto done; ++ } ++ ++ netdev = dev_get_by_name(&init_net, ifname); ++ if (netdev == NULL) { ++ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); ++ } else { ++ p2pmode.u4Enable = 0; ++ p2pmode.u4Mode = 0; ++ ++ if (pf_set_p2p_mode) { ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); ++ } else { ++ WIFI_INFO_FUNC("Turn off p2p/ap mode"); ++ wlan_mode = WLAN_MODE_HALT; ++ } ++ } ++ dev_put(netdev); ++ netdev = NULL; ++ } ++ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); ++ WMT_CHECK_DO_CHIP_RESET(); ++ } else { ++ WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); ++ powered = 0; ++ retval = count; ++ wlan_mode = WLAN_MODE_HALT; ++#if CFG_TC1_FEATURE ++ ifname = WLAN_IFACE_NAME; ++ wlan_if_changed = 0; ++#endif ++ } ++ } else if (local[0] == '1') { ++ if (powered == 1) { ++ WIFI_INFO_FUNC("WIFI is already power on!\n"); ++ retval = count; ++ goto done; ++ } ++ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); ++ WMT_CHECK_DO_CHIP_RESET(); ++ } else { ++ powered = 1; ++ retval = count; ++ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); ++ wlan_mode = WLAN_MODE_HALT; ++ } ++ } else if (local[0] == 'D') { ++ INT32 k = 0; ++ /* ++ * 0: no debug ++ * 1: common debug output ++ * 2: more detials ++ * 3: verbose ++ */ ++ switch (local[1]) { ++ case '0': ++ for (k = 0; k < DBG_MODULE_NUM; k++) ++ wlan_dbg_level[k] = 0; ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ case '1': ++ for (k = 0; k < DBG_MODULE_NUM; k++) { ++ wlan_dbg_level[k] = DBG_CLASS_ERROR | ++ DBG_CLASS_WARN | ++ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; ++ } ++ wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); ++ wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); ++ wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); ++ wlan_dbg_level[DBG_INTR_IDX] = 0; ++ wlan_dbg_level[DBG_MEM_IDX] = 0; ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ case '2': ++ for (k = 0; k < DBG_MODULE_NUM; k++) { ++ wlan_dbg_level[k] = DBG_CLASS_ERROR | ++ DBG_CLASS_WARN | ++ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; ++ } ++ wlan_dbg_level[DBG_INTR_IDX] = 0; ++ wlan_dbg_level[DBG_MEM_IDX] = 0; ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ case '3': ++ for (k = 0; k < DBG_MODULE_NUM; k++) { ++ wlan_dbg_level[k] = DBG_CLASS_ERROR | ++ DBG_CLASS_WARN | ++ DBG_CLASS_STATE | ++ DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD; ++ } ++ if (pf_set_dbg_level) ++ pf_set_dbg_level(wlan_dbg_level); ++ break; ++ default: ++ break; ++ } ++ } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { ++ if (powered == 0) { ++ /* If WIFI is off, turn on WIFI first */ ++ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { ++ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); ++ WMT_CHECK_DO_CHIP_RESET(); ++ goto done; ++ } else { ++ powered = 1; ++ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); ++ wlan_mode = WLAN_MODE_HALT; ++ } ++ } ++ ++ if (pf_set_p2p_mode == NULL) { ++ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); ++ goto done; ++ } ++ ++ netdev = dev_get_by_name(&init_net, ifname); ++ while (netdev == NULL && wait_cnt < 10) { ++ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); ++ msleep(300); ++ wait_cnt++; ++ netdev = dev_get_by_name(&init_net, ifname); ++ } ++ if (wait_cnt >= 10) { ++ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); ++ goto done; ++ } ++ ++ if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) || ++ (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))) { ++ WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode); ++ retval = count; ++ goto done; ++ } ++ ++ if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || ++ (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) { ++ p2pmode.u4Enable = 0; ++ p2pmode.u4Mode = 0; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); ++ goto done; ++ } ++ } ++ ++ if (local[0] == 'S' || local[0] == 'P') { ++#if CFG_TC1_FEATURE ++ /* Restore NIC name to wlan0 */ ++ rtnl_lock(); ++ if (strcmp(ifname, WLAN_IFACE_NAME) != 0) { ++ if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0) { ++ WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME); ++ rtnl_unlock(); ++ goto done; ++ } else { ++ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, ++ WLAN_IFACE_NAME); ++ ifname = WLAN_IFACE_NAME; ++ wlan_if_changed = 0; ++ } ++ } ++ rtnl_unlock(); ++#endif ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 0; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); ++ wlan_mode = WLAN_MODE_STA_P2P; ++ retval = count; ++ } ++ } else if (local[0] == 'A') { ++#if CFG_TC1_FEATURE ++ /* Change NIC name to legacy0, since wlan0 is used for AP */ ++ rtnl_lock(); ++ if (strcmp(ifname, LEGACY_IFACE_NAME) != 0) { ++ if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0) { ++ WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME); ++ rtnl_unlock(); ++ goto done; ++ } else { ++ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, ++ LEGACY_IFACE_NAME); ++ ifname = LEGACY_IFACE_NAME; ++ wlan_if_changed = 1; ++ } ++ } ++ rtnl_unlock(); ++#endif ++ p2pmode.u4Enable = 1; ++ p2pmode.u4Mode = 1; ++ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { ++ WIFI_ERR_FUNC("Set wlan mode fail\n"); ++ } else { ++ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); ++ wlan_mode = WLAN_MODE_AP; ++ retval = count; ++ } ++ } ++ dev_put(netdev); ++ netdev = NULL; ++ } ++ } ++done: ++ if (netdev != NULL) ++ dev_put(netdev); ++ ++ up(&wr_mtx); ++ return retval; ++} ++ ++const struct file_operations WIFI_fops = { ++ .open = WIFI_open, ++ .release = WIFI_close, ++ .write = WIFI_write, ++}; ++ ++#if WMT_CREATE_NODE_DYNAMIC ++struct class *wmtwifi_class = NULL; ++#endif ++ ++static int WIFI_init(void) ++{ ++ dev_t dev = MKDEV(WIFI_major, 0); ++ INT32 alloc_ret = 0; ++ INT32 cdev_err = 0; ++#if WMT_CREATE_NODE_DYNAMIC ++ struct device *wmtwifi_dev = NULL; ++#endif ++ ++ /* static allocate chrdev */ ++ alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME); ++ if (alloc_ret) { ++ WIFI_ERR_FUNC("Fail to register chrdev\n"); ++ return alloc_ret; ++ } ++ ++ cdev_init(&WIFI_cdev, &WIFI_fops); ++ WIFI_cdev.owner = THIS_MODULE; ++ ++ cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs); ++ if (cdev_err) ++ goto error; ++ ++#if WMT_CREATE_NODE_DYNAMIC /* mknod replace */ ++ wmtwifi_class = class_create(THIS_MODULE, "wmtWifi"); ++ if (IS_ERR(wmtwifi_class)) ++ goto error; ++ wmtwifi_dev = device_create(wmtwifi_class, NULL, dev, NULL, "wmtWifi"); ++ if (wmtwifi_dev == NULL) ++ goto error; ++ if (IS_ERR(wmtwifi_dev)) ++ goto error; ++#endif ++ ++ sema_init(&wr_mtx, 1); ++ ++ WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major); ++ retflag = 0; ++ wlan_mode = WLAN_MODE_HALT; ++ pf_set_p2p_mode = NULL; ++ ++ return 0; ++ ++error: ++#if WMT_CREATE_NODE_DYNAMIC ++ if (!IS_ERR(wmtwifi_dev)) ++ device_destroy(wmtwifi_class, dev); ++ if (!IS_ERR(wmtwifi_class)) { ++ class_destroy(wmtwifi_class); ++ wmtwifi_class = NULL; ++ } ++#endif ++ ++ if (cdev_err == 0) ++ cdev_del(&WIFI_cdev); ++ ++ if (alloc_ret == 0) ++ unregister_chrdev_region(dev, WIFI_devs); ++ ++ return -1; ++} ++ ++static void WIFI_exit(void) ++{ ++ dev_t dev = MKDEV(WIFI_major, 0); ++ ++ retflag = 0; ++ ++#if WMT_CREATE_NODE_DYNAMIC ++ device_destroy(wmtwifi_class, dev); ++ class_destroy(wmtwifi_class); ++ wmtwifi_class = NULL; ++#endif ++ ++ cdev_del(&WIFI_cdev); ++ unregister_chrdev_region(dev, WIFI_devs); ++ ++ WIFI_INFO_FUNC("%s driver removed.\n", WIFI_DRIVER_NAME); ++} ++ ++#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++ ++INT32 mtk_wcn_wmt_wifi_init(VOID) ++{ ++ return WIFI_init(); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wifi_init); ++ ++VOID mtk_wcn_wmt_wifi_exit(VOID) ++{ ++ return WIFI_exit(); ++} ++EXPORT_SYMBOL(mtk_wcn_wmt_wifi_exit); ++ ++#else ++ ++module_init(WIFI_init); ++module_exit(WIFI_exit); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c +new file mode 100644 +index 000000000000..641e516f603d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c +@@ -0,0 +1,307 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++#include "osal_typedef.h" ++#include "wmt_idc.h" ++#include "wmt_lib.h" ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++ ++MTK_WCN_WMT_IDC_INFO gWmtIdcInfo; ++ ++INT32 wmt_idc_init(VOID) ++{ ++ INT32 iRet; ++ ++ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); ++ gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT; ++ gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1; ++ gWmtIdcInfo.iit.sap_id = 0; ++ gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing; ++ ++ iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops); ++ if (iRet) { ++ WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet); ++ return -1; ++ } ++ /* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */ ++ return 0; ++ ++} ++ ++INT32 wmt_idc_deinit(VOID) ++{ ++ INT32 iRet; ++ ++ iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id); ++ if (iRet) ++ WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet); ++ ++ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); ++ ++ return 0; ++} ++ ++INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm) ++{ ++ MTK_WCN_BOOL bRet; ++ ++ if (NULL == ilm) { ++ WMT_ERR_FUNC("NULL pointer\n"); ++ return -1; ++ } ++ if (mtk_wcn_stp_is_ready()) { ++ bRet = wmt_lib_handle_idc_msg(ilm); ++ if (MTK_WCN_BOOL_FALSE == bRet) { ++ WMT_ERR_FUNC("wmt handing idc msg fail\n"); ++ return -2; ++ } ++ } else { ++ WMT_INFO_FUNC("Received LTE msg,but STP is not ready,drop it!\n"); ++ } ++ return 0; ++} ++ ++VOID wmt_idc_dump_debug_msg(UINT8 *str, UINT8 *p_buf, UINT32 buf_len) ++{ ++ UINT32 idx = 0; ++ ++ WMT_DBG_FUNC("%s:, length:%d\n", str, buf_len); ++ ++ WMT_DBG_FUNC("ASCII output:\n"); ++ ++ for (idx = 0; idx < buf_len;) { ++ WMT_DBG_FUNC("%c", p_buf[idx]); ++ idx++; ++ if (0 == idx % 16) ++ WMT_DBG_FUNC("\n"); ++ } ++ ++ WMT_DBG_FUNC("HEX output:\n"); ++ ++ for (idx = 0; idx < buf_len;) { ++ WMT_DBG_FUNC("%02x ", p_buf[idx]); ++ idx++; ++ if (0 == idx % 16) ++ WMT_DBG_FUNC("\n"); ++ } ++} ++ ++INT32 wmt_idc_msg_to_lte_handing(VOID) ++{ ++ UINT32 readlen = 0; ++ local_para_struct *p_lps = NULL; ++ UINT8 *p_data = NULL; ++ UINT8 opcode = 0; ++ UINT16 msg_len = 0; ++ UINT32 handle_len = 0; ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; ++#endif ++ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); ++ if (readlen == 0) { ++ osal_sleep_ms(5); ++ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); ++ } ++ ++ if (readlen > 0) { ++ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); ++ wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen); ++ p_data = &gWmtIdcInfo.buffer[0]; ++ ++ while (handle_len < readlen) { ++ p_data += 2; /*omit direction & opcode 2 bytes */ ++ osal_memcpy(&msg_len, p_data, 2); ++ msg_len -= 1; /*flag byte */ ++ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); ++ ++ p_data += 2; /*length: 2 bytes */ ++ ++ /*how to handle flag(msg type) need to Scott comment */ ++ /************************************************/ ++ ++ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) ++ /*do not need transfer to LTE */ ++ { ++ p_data += 1; /*flag : 1 byte */ ++ /*need to handle these debug message */ ++ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); ++ } else ++ /*need to transfer to LTE */ ++ { ++ p_lps = ++ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + ++ osal_sizeof(UINT8) * msg_len); ++ if (NULL == p_lps) { ++ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); ++ return -1; ++ } ++ ++ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); ++ ++ opcode = *p_data; ++ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); ++ ++ p_data += 1; /*flag : 1 byte */ ++ osal_memcpy(p_lps->data, p_data, msg_len); ++ ++ gWmtIdcInfo.iit.local_para_ptr = p_lps; ++ ++#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING ++ switch (opcode) { ++ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_UART_PIN_SEL: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND; ++ break; ++ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ ++ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ ++ /* break; */ ++ default: ++ unknown_msgid = MTK_WCN_BOOL_TRUE; ++ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); ++ break; ++ } ++ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { ++ /*handling flag value in wmt cmd */ ++ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); ++ } ++#else ++ if (opcode >= LTE_MSG_ID_OFFSET) { ++ gWmtIdcInfo.iit.msg_id = opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1; ++ /*handling flag value in wmt cmd */ ++ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); ++ WMT_DBG_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, gWmtIdcInfo.iit.msg_id); ++ } else { ++ WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", opcode); ++ } ++#endif ++ osal_free(p_lps); ++ } ++ ++ p_data += msg_len; /*point to next package header */ ++ ++ handle_len += (msg_len + 5); ++ } ++ ++ } else { ++ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); ++ } ++ ++ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); ++ ++ return 0; ++} ++ ++UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len) ++{ ++ UINT32 readlen = len; ++ local_para_struct *p_lps = NULL; ++ UINT8 *p_data = NULL; ++ UINT8 opcode = 0; ++ UINT16 msg_len = 0; ++ UINT32 handle_len = 0; ++ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; ++ ++ osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len); ++ ++ if (readlen > 0) { ++ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); ++ p_data = &gWmtIdcInfo.buffer[0]; ++ ++ while (handle_len < readlen) { ++ p_data += 2; /*omit direction & opcode 2 bytes */ ++ osal_memcpy(&msg_len, p_data, 2); ++ msg_len -= 1; /*flag byte */ ++ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); ++ ++ p_data += 2; /*length: 2 bytes */ ++ ++ /*how to handle flag(msg type) need to Scott comment */ ++ /************************************************/ ++ ++ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) ++ /*do not need transfer to LTE */ ++ { ++ p_data += 1; /*flag : 1 byte */ ++ /*need to handle these debug message */ ++ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); ++ } else ++ /*need to transfer to LTE */ ++ { ++ p_lps = ++ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + ++ osal_sizeof(UINT8) * msg_len); ++ if (NULL == p_lps) { ++ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); ++ return -1; ++ } ++ ++ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); ++ ++ opcode = *p_data; ++ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); ++ ++ p_data += 1; /*flag : 1 byte */ ++ osal_memcpy(p_lps->data, p_data, msg_len); ++ ++ gWmtIdcInfo.iit.local_para_ptr = p_lps; ++ ++ switch (opcode) { ++ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; ++ break; ++ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: ++ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; ++ break; ++ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ ++ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ ++ /* break; */ ++ default: ++ unknown_msgid = MTK_WCN_BOOL_TRUE; ++ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); ++ break; ++ } ++ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { ++ /*handling flag value in wmt cmd */ ++ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); ++ } ++ osal_free(p_lps); ++ } ++ ++ p_data += msg_len; /*point to next package header */ ++ ++ handle_len += (msg_len + 5); ++ } ++ ++ } else { ++ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); ++ } ++ ++ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); ++ ++ return handle_len; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile +new file mode 100644 +index 000000000000..c201e8291b8e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile +@@ -0,0 +1,25 @@ ++# WMT HAL driver for MT7623 ++ ++ccflags-y += \ ++ -I$(src)/include \ ++ -I$(src)/../linux/include \ ++ -I$(src)/../include \ ++ -I$(src)/../../common_detect ++ ++ ifeq ($(CONFIG_MTK_CLKMGR),y) ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach ++ endif ++ #ifeq ($(CONFIG_MTK_EMI_MPU),y) ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach ++ #endif ++ ++subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT ++ ++ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) ++ subdir-ccflags-y += -DWMT_IDC_SUPPORT=1 ++else ++ subdir-ccflags-y += -DWMT_IDC_SUPPORT=0 ++endif ++ ++obj-y += mtk_wcn_consys_hw.o ++obj-y += wmt_plat_alps.o +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h +new file mode 100644 +index 000000000000..94d6af9d0b3e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h +@@ -0,0 +1,287 @@ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _MTK_WCN_CONSYS_HW_H_ ++#define _MTK_WCN_CONSYS_HW_H_ ++ ++#include ++/*#include */ ++#include "wmt_plat.h" ++ ++/*device tree mode*/ ++#ifdef CONFIG_OF ++/* #if 1 */ ++#include ++#include ++#include ++#include ++#endif ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CONSYS_BT_WIFI_SHARE_V33 0 ++#define CONSYS_PMIC_CTRL_ENABLE 1 ++#define CONSYS_PMIC_CTRL_UPMU 1 ++#define CONSYS_EMI_MPU_SETTING 0 ++#define CONSYS_AHB_CLK_MAGEMENT 1 ++#define CONSYS_USE_PLATFORM_WRITE 1 ++#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 ++#define CONSYS_CLOCK_BUF_CTRL 0 ++#if defined(CONFIG_MTK_LEGACY) ++#define CONFIG_MTK_PMIC_LEGACY 0 ++#endif ++#define CONFIG_RESET_CONTROL 1 ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/*tag start:new platform need to make sure these define */ ++#define PLATFORM_SOC_CHIP 0x7623 ++/*tag end*/ ++ ++#ifdef CONFIG_OF ++ ++struct CONSYS_BASE_ADDRESS { ++ SIZE_T mcu_base; ++ SIZE_T ap_rgu_base; ++ SIZE_T topckgen_base; ++ SIZE_T spm_base; ++}; ++ ++/*TOPCKGEN_BASE*/ ++#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 ++#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 ++#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 ++#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000800 ++#define CONSYS_EMI_MAPPING_OFFSET 0x00000310 ++/*AP_RGU_BASE*/ ++#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 ++/*SPM_BASE*/ ++#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 ++#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000280 ++#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000060c ++#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000610 ++/*CONN_MCU_CONFIG_BASE*/ ++#define CONSYS_CHIP_ID_OFFSET 0x00000008 ++#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 ++#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 ++#define CONSYS_CPUPCR_OFFSET 0x00000160 ++/*AXI bus*/ ++ ++#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x1220 ++#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x0228 ++#endif ++ ++#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile UINT32*)(REG)) |= ((UINT32)(BITVAL))) ++#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile UINT32*)(REG)) &= ~((UINT32)(BITVAL))) ++#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\ ++ UINT32 val = (*(volatile UINT32*)(REG)); \ ++ val &= ~((UINT32)(BITVAL)); \ ++ val |= ((UINT32)(KEY)); \ ++ (*(volatile UINT32*)(REG)) = val;\ ++} ++#define CONSYS_REG_READ(addr) (*((volatile UINT32*)(addr))) ++#if CONSYS_USE_PLATFORM_WRITE ++#define CONSYS_REG_WRITE(addr, data) mt_reg_sync_writel(data, addr) ++#else ++#define CONSYS_REG_WRITE(addr, data) (*((volatile UINT32*)(addr)) = (UINT32)(data)) ++#endif ++ ++/*tag start: connsys register base address (hard code, no use) */ ++#define AP_RGU_BASE 0xF0007000 ++#define TOPCKGEN_BASE 0xF0000000 ++#define SPM_BASE 0xF0006000 ++#define CONN_MCU_CONFIG_BASE 0xF8070000 ++/*GIC Interrupt ID*/ ++#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 237 ++/*tag end*/ ++ ++/*connsys register offset define(hard code mode)*/ ++#if 1 ++ /*top clock gating control register */ ++#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) ++#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) ++#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) ++ ++ /*SPM clock gating control register */ ++#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) ++#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) ++#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) ++#endif ++ ++#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) ++#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x00000280) ++#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x0000060c) ++#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000610) ++ ++#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) ++#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) ++#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) ++#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) ++#define CONSYS_AFE_REG (CONN_TOP_CR_BASE + 0x00002000) ++#define CONSYS_AFE_REG_DIG_RCK_01 (CONSYS_AFE_REG + 0x00000010) ++#define CONSYS_AFE_REG_WBG_PLL_02 (CONSYS_AFE_REG + 0x00000028) ++#define CONSYS_AFE_REG_WBG_WB_TX_01 (CONSYS_AFE_REG + 0x0000003c) ++#define CONSYS_AFE_REG_DIG_RCK_01_VALUE (0x174b0160) ++#define CONSYS_AFE_REG_WBG_PLL_02_VALUE (0x844083fe) ++#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x7fc39a20) ++ ++#define CONSYS_TOPAXI_PROT_EN (TOPCKGEN_BASE + 0x0220) ++#define CONSYS_TOPAXI_PROT_STA1 (TOPCKGEN_BASE + 0x0228) ++#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14) | (0x1<<15)) /* bit 13, 14, 15 */ ++/*CONSYS_CPU_SW_RST_REG*/ ++#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) ++#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) ++ ++/*CONSYS_TOP1_PWR_CTRL_REG*/ ++#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) ++#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) ++#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) ++#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) ++#define CONSYS_CLK_CTRL_BIT (0x1 << 4) ++#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) ++ ++/*CONSYS_PWR_CONN_ACK_REG*/ ++#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) ++ ++/*CONSYS_PWR_CONN_ACK_S_REG*/ ++#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) ++ ++/*CONSYS_WD_SYS_RST_REG*/ ++#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) ++#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) ++ ++/*CONSYS_MCU_CFG_ACR_REG*/ ++#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) ++ ++/* EMI part mapping & ctrl*/ ++#define KBYTE (1024*sizeof(char)) ++#define CONSYS_EMI_AP_PHY_OFFSET (0x80000) ++#define CONSYS_EMI_AP_PHY_BASE (0x80080000) ++#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) ++#define CONSYS_EMI_MEM_SIZE (343*KBYTE) /*coredump space , 343K is enough */ ++#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) ++#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) ++#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) ++ ++/*cpupcr*/ ++#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) ++/*emi mapping*/ ++#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + 0x1310) ++ ++/*control app2cnn_osc_en*/ ++#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) ++#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 16) ++#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 17) ++ ++/*paged dump address start*/ ++#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) ++#define CONSYS_PAGED_DUMP_SIZE (32*KBYTE) ++ ++/*full dump address start*/ ++#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) ++#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) ++#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) ++#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) ++#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) ++#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) ++ ++/*force fw assert pattern*/ ++#define EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1 (0x19b30bb1) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_EMI_CTRL_STATE_OFFSET_ { ++ EXP_APMEM_CTRL_STATE = 0x0, ++ EXP_APMEM_CTRL_HOST_SYNC_STATE = 0x4, ++ EXP_APMEM_CTRL_HOST_SYNC_NUM = 0x8, ++ EXP_APMEM_CTRL_CHIP_SYNC_STATE = 0xc, ++ EXP_APMEM_CTRL_CHIP_SYNC_NUM = 0x10, ++ EXP_APMEM_CTRL_CHIP_SYNC_ADDR = 0x14, ++ EXP_APMEM_CTRL_CHIP_SYNC_LEN = 0x18, ++ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START = 0x1c, ++ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN = 0x20, ++ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX = 0x24, ++ EXP_APMEM_CTRL_CHIP_INT_STATUS = 0x28, ++ EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END = 0x2c, ++ EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 = 0x30, ++ EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP = 0x48, ++ EXP_APMEM_CTRL_MAX ++} ENUM_EMI_CTRL_STATE_OFFSET, *P_ENUM_EMI_CTRL_STATE_OFFSET; ++ ++#if CONSYS_BT_WIFI_SHARE_V33 ++typedef struct _BT_WIFI_V33_STATUS_ { ++ UINT32 counter; ++ UINT32 flags; ++ spinlock_t lock; ++} BT_WIFI_V33_STATUS; ++ ++#endif ++ ++typedef enum _CONSYS_GPS_CO_CLOCK_TYPE_ { ++ GPS_TCXO_TYPE = 0, ++ GPS_CO_TSX_TYPE = 1, ++ GPS_CO_DCXO_TYPE = 2, ++ GPS_CO_VCTCXO_TYPE = 3, ++ GPS_CO_CLOCK_TYPE_MAX ++} CONSYS_GPS_CO_CLOCK_TYPE, *P_CONSYS_GPS_CO_CLOCK_TYPE; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern struct CONSYS_BASE_ADDRESS conn_reg; ++#if CONSYS_BT_WIFI_SHARE_V33 ++extern BT_WIFI_V33_STATUS gBtWifiV33; ++#endif ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++extern INT32 mtk_wcn_consys_hw_init(VOID); ++extern INT32 mtk_wcn_consys_hw_deinit(VOID); ++extern INT32 mtk_wcn_consys_hw_pwr_off(VOID); ++extern INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type); ++extern INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type); ++extern INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable); ++extern INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable); ++extern INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable); ++extern INT32 mtk_wcn_consys_hw_state_show(VOID); ++extern UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset); ++#if CONSYS_ENALBE_SET_JTAG ++extern UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en); ++#endif ++extern UINT32 mtk_wcn_consys_soc_chipid(VOID); ++#if !defined(CONFIG_MTK_GPIO_LEGACY) ++extern struct pinctrl *mtk_wcn_consys_get_pinctrl(VOID); ++#endif ++extern INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 buf); ++#endif /* _MTK_WCN_CMB_HW_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +new file mode 100644 +index 000000000000..53b69a7b3e87 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +@@ -0,0 +1,738 @@ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-CONSYS-HW]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include "osal_typedef.h" ++#include "mtk_wcn_consys_hw.h" ++#include ++#include ++#include ++#if CONSYS_EMI_MPU_SETTING ++#include ++#endif ++ ++#include ++#include ++#ifdef CONFIG_MTK_HIBERNATION ++#include ++#endif ++ ++#include ++ ++#if CONSYS_CLOCK_BUF_CTRL ++#include ++#endif ++ ++#include ++#include ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static INT32 mtk_wmt_probe(struct platform_device *pdev); ++static INT32 mtk_wmt_remove(struct platform_device *pdev); ++ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++struct CONSYS_BASE_ADDRESS conn_reg; ++static phys_addr_t gConEmiPhyBase; ++static UINT8 __iomem *pEmibaseaddr; ++static struct clk *clk_infra_conn_main; /*ctrl infra_connmcu_bus clk */ ++static struct platform_device *my_pdev; ++static struct reset_control *rstc; ++static struct regulator *reg_VCN18; ++static struct regulator *reg_VCN28; ++static struct regulator *reg_VCN33_BT; ++static struct regulator *reg_VCN33_WIFI; ++static struct pinctrl *consys_pinctrl; ++static struct pinctrl *mt6625_spi_pinctrl; ++static struct pinctrl_state *mt6625_spi_default; ++static struct regmap *pmic_regmap; ++#define DYNAMIC_DUMP_GROUP_NUM 5 ++ ++static const struct of_device_id apwmt_of_ids[] = { ++ {.compatible = "mediatek,mt7623-consys",} ++}; ++MODULE_DEVICE_TABLE(of, apwmt_of_ids); ++ ++static struct platform_driver mtk_wmt_dev_drv = { ++ .probe = mtk_wmt_probe, ++ .remove = mtk_wmt_remove, ++ .driver = { ++ .name = "mt7623consys", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(apwmt_of_ids), ++ }, ++}; ++ ++static INT32 mtk_wmt_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct device_node *node = NULL; ++ ++ pm_runtime_enable(&pdev->dev); ++ my_pdev = pdev; ++ mt6625_spi_pinctrl = devm_pinctrl_get(&pdev->dev); ++ if (IS_ERR(mt6625_spi_pinctrl)) { ++ ret = PTR_ERR(mt6625_spi_pinctrl); ++ WMT_PLAT_ERR_FUNC("Wmt cannot find pinctrl!\n"); ++ goto set_pin_exit; ++ } ++ mt6625_spi_default = pinctrl_lookup_state(mt6625_spi_pinctrl, "consys_pins_default"); ++ if (IS_ERR(mt6625_spi_default)) { ++ ret = PTR_ERR(mt6625_spi_default); ++ WMT_PLAT_ERR_FUNC("Wmt Cannot find pinctrl default!\n"); ++ goto set_pin_exit; ++ } ++ pinctrl_select_state(mt6625_spi_pinctrl, mt6625_spi_default); ++set_pin_exit: ++ ++ node = of_parse_phandle(pdev->dev.of_node, "mediatek,pwrap-regmap", 0); ++ if (node) { ++ pmic_regmap = pwrap_node_to_regmap(node); ++ if (IS_ERR(pmic_regmap)) ++ goto set_pmic_wrap_exit; ++ } else { ++ WMT_PLAT_ERR_FUNC("Pwrap node has not register regmap.\n"); ++ goto set_pmic_wrap_exit; ++ } ++set_pmic_wrap_exit: ++ ++ clk_infra_conn_main = devm_clk_get(&pdev->dev, "consysbus"); ++ if (IS_ERR(clk_infra_conn_main)) { ++ WMT_PLAT_ERR_FUNC("sean debug [CCF]cannot get clk_infra_conn_main clock.\n"); ++ return PTR_ERR(clk_infra_conn_main); ++ } ++ WMT_PLAT_DBG_FUNC("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); ++ ++ reg_VCN18 = devm_regulator_get(&pdev->dev, "vcn18"); ++ if (IS_ERR(reg_VCN18)) { ++ ret = PTR_ERR(reg_VCN18); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN_1V8 fail, ret=%d\n", ret); ++ } ++ reg_VCN28 = devm_regulator_get(&pdev->dev, "vcn28"); ++ if (IS_ERR(reg_VCN28)) { ++ ret = PTR_ERR(reg_VCN28); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN_2V8 fail, ret=%d\n", ret); ++ } ++ reg_VCN33_BT = devm_regulator_get(&pdev->dev, "vcn33_bt"); ++ if (IS_ERR(reg_VCN33_BT)) { ++ ret = PTR_ERR(reg_VCN33_BT); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_BT fail, ret=%d\n", ret); ++ } ++ reg_VCN33_WIFI = devm_regulator_get(&pdev->dev, "vcn33_wifi"); ++ if (IS_ERR(reg_VCN33_WIFI)) { ++ ret = PTR_ERR(reg_VCN33_WIFI); ++ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_WIFI fail, ret=%d\n", ret); ++ } ++ ++ rstc = devm_reset_control_get(&pdev->dev, "connsys"); ++ if (IS_ERR(rstc)) { ++ ret = PTR_ERR(rstc); ++ WMT_PLAT_ERR_FUNC("CanNot get consys reset. ret=%d\n", ret); ++ return PTR_ERR(rstc); ++ } ++ ++ consys_pinctrl = devm_pinctrl_get(&pdev->dev); ++ if (IS_ERR(consys_pinctrl)) { ++ ret = PTR_ERR(consys_pinctrl); ++ WMT_PLAT_ERR_FUNC("CanNot find consys pinctrl. ret=%d\n", ret); ++ return PTR_ERR(consys_pinctrl); ++ } ++ return 0; ++} ++ ++static INT32 mtk_wmt_remove(struct platform_device *pdev) ++{ ++ pm_runtime_disable(&pdev->dev); ++ ++ return 0; ++} ++ ++VOID mtk_wcn_consys_power_on(VOID) ++{ ++ INT32 iRet = -1; ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ iRet = pm_runtime_get_sync(&my_pdev->dev); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("pm_runtime_get_sync() fail(%d)\n", iRet); ++ else ++ WMT_PLAT_INFO_FUNC("pm_runtime_get_sync() CONSYS ok\n"); ++ ++ iRet = device_init_wakeup(&my_pdev->dev, true); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("device_init_wakeup(true) fail.\n"); ++ else ++ WMT_PLAT_INFO_FUNC("device_init_wakeup(true) CONSYS ok\n"); ++} ++ ++VOID mtk_wcn_consys_power_off(VOID) ++{ ++ INT32 iRet = -1; ++ ++ iRet = pm_runtime_put_sync(&my_pdev->dev); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("pm_runtime_put_sync() fail.\n"); ++ else ++ WMT_PLAT_INFO_FUNC("pm_runtime_put_sync() CONSYS ok\n"); ++ ++ iRet = device_init_wakeup(&my_pdev->dev, false); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("device_init_wakeup(false) fail.\n"); ++ else ++ WMT_PLAT_INFO_FUNC("device_init_wakeup(false) CONSYS ok\n"); ++} ++ ++INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_type) ++{ ++ UINT32 retry = 10; ++ UINT32 consysHwChipId = 0; ++ ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),start\n", on); ++ if (on) { ++ WMT_PLAT_DBG_FUNC("++\n"); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ /*need PMIC driver provide new API protocol */ ++ /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ ++ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ /* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */ ++ if (reg_VCN18) { ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ regulator_set_voltage(reg_VCN18, 1800000, 1800000); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (regulator_enable(reg_VCN18)) ++ WMT_PLAT_ERR_FUNC("enable VCN18 fail\n"); ++ else ++ WMT_PLAT_DBG_FUNC("enable VCN18 ok\n"); ++ } ++ udelay(150); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ if (co_clock_type) { ++ /*step0,clk buf ctrl */ ++ WMT_PLAT_INFO_FUNC("co clock type(%d),turn on clk buf\n", co_clock_type); ++#if CONSYS_CLOCK_BUF_CTRL ++ clk_buf_ctrl(CLK_BUF_CONN, 1); ++#endif ++ /*if co-clock mode: */ ++ /*2.set VCN28 to SW control mode (with PMIC_WRAP API) */ ++ /*turn on VCN28 LDO only when FMSYS is activated" */ ++ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ ++ } else { ++ /*if NOT co-clock: */ ++ /*2.1.switch VCN28 to HW control mode (with PMIC_WRAP API) */ ++ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x1 << 14);/*V28*/ ++ /*2.2.turn on VCN28 LDO (with PMIC_WRAP API)" */ ++ /*fix vcn28 not balance warning */ ++ if (reg_VCN28) { ++ regulator_set_voltage(reg_VCN28, 2800000, 2800000); ++ if (regulator_enable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("enable VCN_2V8 fail!\n"); ++ else ++ WMT_PLAT_DBG_FUNC("enable VCN_2V8 ok\n"); ++ } ++ } ++ ++ /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ reset_control_reset(rstc); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ mtk_wcn_consys_power_on(); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ /*11.26M is ready now, delay 10us for mem_pd de-assert */ ++ udelay(10); ++ /*enable AP bus clock : connmcu_bus_pd API: enable_clock() ++?? */ ++ clk_prepare_enable(clk_infra_conn_main); ++printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ++ WMT_PLAT_DBG_FUNC("[CCF]enable clk_infra_conn_main\n"); ++ /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ ++ while (retry-- > 0) { ++ consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET) - 0xf6d; ++ ++ if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { ++ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); ++ break; ++ } ++ if ((consysHwChipId == 0x8163) || (consysHwChipId == 0x8127) || (consysHwChipId == 0x7623)) { ++ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); ++ break; ++ } ++ ++ WMT_PLAT_ERR_FUNC("Read CONSYS chipId(0x%08x)", consysHwChipId); ++ msleep(20); ++ } ++ ++ if ((0 == retry) || (0 == consysHwChipId)) ++ WMT_PLAT_ERR_FUNC("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); ++ ++ msleep(40); ++ ++ } else { ++ ++ clk_disable_unprepare(clk_infra_conn_main); ++ WMT_PLAT_DBG_FUNC("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n"); ++ mtk_wcn_consys_power_off(); ++ ++ if (co_clock_type) { ++ /*VCN28 has been turned off by GPS OR FM */ ++#if CONSYS_CLOCK_BUF_CTRL ++ clk_buf_ctrl(CLK_BUF_CONN, 0); ++#endif ++ } else { ++ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ ++ /*turn off VCN28 LDO (with PMIC_WRAP API)" */ ++ if (reg_VCN28) { ++ if (regulator_disable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("disable VCN_2V8 fail!\n"); ++ else ++ WMT_PLAT_DBG_FUNC("disable VCN_2V8 ok\n"); ++ } ++ } ++ ++ /*AP power off MT6625L VCN_1V8 LDO */ ++ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); ++ if (reg_VCN18) { ++ if (regulator_disable(reg_VCN18)) ++ WMT_PLAT_ERR_FUNC("disable VCN_1V8 fail!\n"); ++ else ++ WMT_PLAT_DBG_FUNC("disable VCN_1V8 ok\n"); ++ } ++ ++ } ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),finish\n", on); ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_gpio_ctrl(UINT32 on) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), start\n", on); ++ ++ if (on) { ++ ++ /* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */ ++ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); */ ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT); ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ registered and disabled\n"); ++ ++ } else { ++ ++ /* set bgf eint/all eint to deinit state, namely input low state */ ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); ++ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ unregistered and disabled\n"); ++ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); */ ++ } ++ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), finish\n", on); ++ return iRet; ++ ++} ++ ++INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, start\n"); ++ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); ++ iRet += mtk_wcn_consys_hw_gpio_ctrl(1); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, finish(%d)\n", iRet); ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_hw_pwr_off(VOID) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, start\n"); ++ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(0, 0); ++ iRet += mtk_wcn_consys_hw_gpio_ctrl(0); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, finish(%d)\n", iRet); ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type) ++{ ++ INT32 iRet = 0; ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst start, eirq should be disabled before this step\n"); ++ ++ /*1. do whole hw power off flow */ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type); ++ ++ /*2. do whole hw power on flow */ ++ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst finish, eirq should be enabled after this step\n"); ++ return iRet; ++} ++ ++#if CONSYS_BT_WIFI_SHARE_V33 ++INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) ++{ ++ /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ ++ if (enable) { ++ if (1 == gBtWifiV33.counter) { ++ gBtWifiV33.counter++; ++ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); ++ } else if (2 == gBtWifiV33.counter) { ++ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); ++ } else { ++#if CONSYS_PMIC_CTRL_ENABLE ++ /*do BT PMIC on,depenency PMIC API ready */ ++ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ ++ /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ ++ hwPowerOn(MT6323_POWER_LDO_VCN33, VOL_3300, "wcn_drv"); ++ upmu_set_vcn33_on_ctrl_bt(1); ++#endif ++ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 on\n"); ++ gBtWifiV33.counter++; ++ } ++ ++ } else { ++ if (1 == gBtWifiV33.counter) { ++ /*do BT PMIC off */ ++ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ ++#if CONSYS_PMIC_CTRL_ENABLE ++ upmu_set_vcn33_on_ctrl_bt(0); ++ hwPowerDown(MT6323_POWER_LDO_VCN33, "wcn_drv"); ++#endif ++ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 off\n"); ++ gBtWifiV33.counter--; ++ } else if (2 == gBtWifiV33.counter) { ++ gBtWifiV33.counter--; ++ WMT_PLAT_DBG_FUNC("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); ++ } else { ++ WMT_PLAT_DBG_FUNC("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); ++ } ++ ++ } ++ /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) ++{ ++ mtk_wcn_consys_hw_bt_paldo_ctrl(enable); ++ return 0; ++} ++ ++#else ++INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) ++{ ++ ++ if (enable) { ++ /*do BT PMIC on,depenency PMIC API ready */ ++ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ ++ if (reg_VCN33_BT) { ++ regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); ++ if (regulator_enable(reg_VCN33_BT)) ++ WMT_PLAT_ERR_FUNC("WMT do BT PMIC on fail!\n"); ++ } ++ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x1 << 5);/*BT*/ ++ WMT_PLAT_INFO_FUNC("WMT do BT PMIC on\n"); ++ } else { ++ /*do BT PMIC off */ ++ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ ++ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x0 << 5);/*BT*/ ++ if (reg_VCN33_BT) ++ if (regulator_disable(reg_VCN33_BT)) ++ WMT_PLAT_ERR_FUNC("WMT do BT PMIC off fail!\n"); ++ WMT_PLAT_INFO_FUNC("WMT do BT PMIC off\n"); ++ } ++ ++ return 0; ++ ++} ++ ++INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) ++{ ++ ++ if (enable) { ++ /*do WIFI PMIC on,depenency PMIC API ready */ ++ /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ ++ if (reg_VCN33_WIFI) { ++ regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); ++ if (regulator_enable(reg_VCN33_WIFI)) ++ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC on fail!\n"); ++ else ++ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on !\n"); ++ } ++ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x1 << 14);/*WIFI*/ ++ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on\n"); ++ } else { ++ /*do WIFI PMIC off */ ++ /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ ++ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x0 << 14);/*WIFI*/ ++ if (reg_VCN33_WIFI) ++ if (regulator_disable(reg_VCN33_WIFI)) ++ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC off fail!\n"); ++ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC off\n"); ++ } ++ ++ return 0; ++} ++ ++#endif ++INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) ++{ ++ if (enable) { ++ /*in co-clock mode,need to turn on vcn28 when fm on */ ++ if (reg_VCN28) { ++ regulator_set_voltage(reg_VCN28, 2800000, 2800000); ++ if (regulator_enable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC on fail!\n"); ++ } ++ WMT_PLAT_INFO_FUNC("turn on vcn28 for fm/gps usage in co-clock mode\n"); ++ } else { ++ /*in co-clock mode,need to turn off vcn28 when fm off */ ++ if (reg_VCN28) ++ if (regulator_disable(reg_VCN28)) ++ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC off fail!\n"); ++ WMT_PLAT_INFO_FUNC("turn off vcn28 for fm/gps usage in co-clock mode\n"); ++ } ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_state_show(VOID) ++{ ++ return 0; ++} ++ ++INT32 mtk_wcn_consys_hw_restore(struct device *device) ++{ ++ UINT32 addrPhy = 0; ++ ++ if (gConEmiPhyBase) { ++ ++#if CONSYS_EMI_MPU_SETTING ++ /*set MPU for EMI share Memory */ ++ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); ++ ++#if 0 ++ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, ++ gConEmiPhyBase + SZ_1M, ++ 5, ++ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); ++ ++ ++#else ++ WMT_PLAT_WARN_FUNC("not define platform config\n"); ++#endif ++ ++#endif ++ /*consys to ap emi remapping register:10001310, cal remapping address */ ++ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; ++ ++ /*enable consys to ap emi remapping bit12 */ ++ addrPhy = addrPhy | 0x1000; ++ ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); ++ ++#if 1 ++ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); ++#else ++ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); ++#endif ++ if (pEmibaseaddr) { ++ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); ++ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); ++ } else { ++ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); ++ } ++ } else { ++ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); ++ } ++ ++ return 0; ++} ++ ++/*Reserved memory by device tree!*/ ++int reserve_memory_consys_fn(struct reserved_mem *rmem) ++{ ++ WMT_PLAT_WARN_FUNC(" name: %s, base: 0x%llx, size: 0x%llx\n", rmem->name, ++ (unsigned long long)rmem->base, (unsigned long long)rmem->size); ++ gConEmiPhyBase = rmem->base; ++ return 0; ++} ++ ++RESERVEDMEM_OF_DECLARE(reserve_memory_test, "mediatek,consys-reserve-memory", reserve_memory_consys_fn); ++ ++ ++INT32 mtk_wcn_consys_hw_init(void) ++{ ++ ++ INT32 iRet = -1; ++ UINT32 addrPhy = 0; ++ INT32 i = 0; ++ struct device_node *node = NULL; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); ++ if (node) { ++ /* registers base address */ ++ conn_reg.mcu_base = (SIZE_T) of_iomap(node, i); ++ WMT_PLAT_DBG_FUNC("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); ++ i++; ++ ++ conn_reg.topckgen_base = (SIZE_T) of_iomap(node, i); ++ WMT_PLAT_DBG_FUNC("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); ++ i++; ++ } else { ++ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); ++ return iRet; ++ } ++ if (gConEmiPhyBase) { ++#if CONSYS_EMI_MPU_SETTING ++ /*set MPU for EMI share Memory */ ++ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); ++ ++#if 0 ++ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, ++ gConEmiPhyBase + SZ_1M, ++ 5, ++ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); ++#else ++ WMT_PLAT_WARN_FUNC("not define platform config\n"); ++#endif ++ ++#endif ++ WMT_PLAT_DBG_FUNC("get consys start phy address(0x%zx)\n", (SIZE_T) gConEmiPhyBase); ++ ++ /*consys to ap emi remapping register:10001310, cal remapping address */ ++ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; ++ ++ /*enable consys to ap emi remapping bit12 */ ++ addrPhy = addrPhy | 0x1000; ++ ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); ++ ++ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump(0x%08x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); ++ ++#if 1 ++ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); ++#else ++ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); ++#endif ++ /* pEmibaseaddr = ioremap_nocache(0x80090400,270*KBYTE); */ ++ if (pEmibaseaddr) { ++ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); ++ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); ++ iRet = 0; ++ } else { ++ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); ++ } ++ } else { ++ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); ++ } ++#ifdef CONFIG_MTK_HIBERNATION ++ WMT_PLAT_INFO_FUNC("register connsys restore cb for complying with IPOH function\n"); ++ register_swsusp_restore_noirq_func(ID_M_CONNSYS, mtk_wcn_consys_hw_restore, NULL); ++#endif ++ iRet = platform_driver_register(&mtk_wmt_dev_drv); ++ if (iRet) ++ WMT_PLAT_ERR_FUNC("WMT platform driver registered failed(%d)\n", iRet); ++ return iRet; ++} ++ ++INT32 mtk_wcn_consys_hw_deinit(void) ++{ ++ if (pEmibaseaddr) { ++ iounmap(pEmibaseaddr); ++ pEmibaseaddr = NULL; ++ } ++#ifdef CONFIG_MTK_HIBERNATION ++ unregister_swsusp_restore_noirq_func(ID_M_CONNSYS); ++#endif ++ ++ platform_driver_unregister(&mtk_wmt_dev_drv); ++ return 0; ++} ++ ++UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset) ++{ ++ UINT8 *p_virtual_addr = NULL; ++ ++ if (!pEmibaseaddr) { ++ WMT_PLAT_ERR_FUNC("EMI base address is NULL\n"); ++ return NULL; ++ } ++ WMT_PLAT_DBG_FUNC("ctrl_state_offset(%08x)\n", ctrl_state_offset); ++ p_virtual_addr = pEmibaseaddr + ctrl_state_offset; ++ ++ return p_virtual_addr; ++} ++ ++UINT32 mtk_wcn_consys_soc_chipid(void) ++{ ++ return PLATFORM_SOC_CHIP; ++} ++ ++struct pinctrl *mtk_wcn_consys_get_pinctrl() ++{ ++ return consys_pinctrl; ++} ++INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 str_buf) ++{ ++ PUINT8 vir_addr = NULL; ++ ++ vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP); ++ if (!vir_addr) { ++ WMT_PLAT_ERR_FUNC("get vir address fail\n"); ++ return -2; ++ } ++ memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8); ++ WMT_PLAT_INFO_FUNC("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); ++ return 0; ++} +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c +new file mode 100644 +index 000000000000..7163dc18a255 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c +@@ -0,0 +1,1071 @@ ++/*! \file ++ \brief Declaration of library functions ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#ifdef DFT_TAG ++#undef DFT_TAG ++#endif ++#define DFT_TAG "[WMT-PLAT]" ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++/* ALPS header files */ ++/*#include */ ++/*#include */ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++#include ++#endif ++#include ++ ++/* MTK_WCN_COMBO header files */ ++#include "osal_typedef.h" ++#include "mtk_wcn_consys_hw.h" ++#include "stp_dbg.h" ++ ++#define CFG_WMT_WAKELOCK_SUPPORT 1 ++ ++#ifdef CONFIG_MTK_MT6306_SUPPORT ++#define MTK_WCN_MT6306_IS_READY 1 ++#else ++#define MTK_WCN_MT6306_IS_READY 0 ++#endif ++ ++#if MTK_WCN_MT6306_IS_READY ++#include ++ ++#ifdef GPIO_GPS_LNA_PIN ++#undef GPIO_GPS_LNA_PIN ++#endif ++ ++#define GPIO_GPS_LNA_PIN GPIO7 ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { ++ .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, ++ .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, ++ .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, ++ .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, ++ .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, ++ .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, ++ .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, ++ .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, ++ .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, ++ .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, ++ .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, ++ .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, ++ .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, ++}; ++ ++CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { ++ .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, ++ .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, ++ .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, ++ .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, ++ .p_ecso = &mtk_wcn_emi_state_off, ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static VOID wmt_plat_bgf_eirq_cb(VOID); ++ ++static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state); ++static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state); ++static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state); ++static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state); ++ ++static INT32 wmt_plat_dump_pin_conf(VOID); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++UINT32 gCoClockFlag = 0; ++BGF_IRQ_BALANCE gbgfIrqBle; ++UINT32 wmtPlatLogLvl = WMT_PLAT_LOG_DBG; ++#if CONSYS_BT_WIFI_SHARE_V33 ++BT_WIFI_V33_STATUS gBtWifiV33; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if CFG_WMT_WAKELOCK_SUPPORT ++static struct mutex gOsSLock; ++#ifdef CONFIG_PM_WAKELOCKS ++static struct wakeup_source wmtWakeLock; ++#else ++static struct wake_lock wmtWakeLock; ++#endif ++#endif ++ ++irq_cb wmt_plat_bgf_irq_cb = NULL; ++device_audio_if_cb wmt_plat_audio_if_cb = NULL; ++func_ctrl_cb wmt_plat_func_ctrl_cb = NULL; ++thermal_query_ctrl_cb wmt_plat_thermal_query_ctrl_cb = NULL; ++deep_idle_ctrl_cb wmt_plat_deep_idle_ctrl_cb = NULL; ++ ++static const fp_set_pin gfp_set_pin_table[] = { ++ [PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl, ++ [PIN_I2S_GRP] = wmt_plat_i2s_ctrl, ++ [PIN_GPS_SYNC] = wmt_plat_gps_sync_ctrl, ++ [PIN_GPS_LNA] = wmt_plat_gps_lna_ctrl, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*! ++ * \brief audio control callback function for CMB_STUB on ALPS ++ * ++ * A platform function required for dynamic binding with CMB_STUB on ALPS. ++ * ++ * \param state desired audio interface state to use ++ * \param flag audio interface control options ++ * ++ * \retval 0 operation success ++ * \retval -1 invalid parameters ++ * \retval < 0 error for operation fail ++ */ ++INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) ++{ ++ INT32 iRet = 0; ++ UINT32 pinShare = 0; ++ ++ /* input sanity check */ ++ if ((CMB_STUB_AIF_MAX <= state) ++ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { ++ return -1; ++ } ++ ++ iRet = 0; ++ ++ /* set host side first */ ++ switch (state) { ++ case CMB_STUB_AIF_0: ++ /* BT_PCM_OFF & FM line in/out */ ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); ++ break; ++ ++ case CMB_STUB_AIF_1: ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); ++ break; ++ ++ case CMB_STUB_AIF_2: ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); ++ break; ++ ++ case CMB_STUB_AIF_3: ++ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); ++ break; ++ ++ default: ++ /* FIXME: move to cust folder? */ ++ WMT_PLAT_ERR_FUNC("invalid state [%d]\n", state); ++ iRet = -1; ++ break; ++ } ++ ++ if (CMB_STUB_AIF_CTRL_EN == ctrl) { ++ WMT_PLAT_INFO_FUNC("call chip aif setting\n"); ++ /* need to control chip side GPIO */ ++ if (NULL != wmt_plat_audio_if_cb) { ++ iRet += (*wmt_plat_audio_if_cb) (state, (pinShare) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); ++ } else { ++ WMT_PLAT_WARN_FUNC("wmt_plat_audio_if_cb is not registered\n"); ++ iRet -= 1; ++ } ++ ++ } else { ++ WMT_PLAT_INFO_FUNC("skip chip aif setting\n"); ++ } ++ ++ return iRet; ++ ++} ++ ++static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on) ++{ ++ if (wmt_plat_func_ctrl_cb) ++ (*wmt_plat_func_ctrl_cb) (on, type); ++} ++ ++static long wmt_plat_thermal_ctrl(VOID) ++{ ++ long temp = 0; ++ ++ if (wmt_plat_thermal_query_ctrl_cb) ++ temp = (*wmt_plat_thermal_query_ctrl_cb) (); ++ ++ return temp; ++} ++ ++static INT32 wmt_plat_deep_idle_ctrl(UINT32 dpilde_ctrl) ++{ ++ INT32 iRet = -1; ++ ++ if (wmt_plat_deep_idle_ctrl_cb) ++ iRet = (*wmt_plat_deep_idle_ctrl_cb) (dpilde_ctrl); ++ ++ return iRet; ++} ++ ++static VOID wmt_plat_bgf_eirq_cb(VOID) ++{ ++#if CFG_WMT_PS_SUPPORT ++/* #error "need to disable EINT here" */ ++ /* wmt_lib_ps_irq_cb(); */ ++ if (NULL != wmt_plat_bgf_irq_cb) ++ (*(wmt_plat_bgf_irq_cb)) (); ++ else ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: wmt_plat_bgf_irq_cb not registered\n"); ++#else ++ return; ++#endif ++ ++} ++ ++irqreturn_t wmt_plat_bgf_irq_isr(INT32 i, VOID *arg) ++{ ++#if CFG_WMT_PS_SUPPORT ++ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); ++ wmt_plat_bgf_eirq_cb(); ++#else ++ WMT_PLAT_INFO_FUNC("skip irq handing because psm is disable"); ++#endif ++ return IRQ_HANDLED; ++} ++ ++VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb) ++{ ++ wmt_plat_bgf_irq_cb = bgf_irq_cb; ++} ++EXPORT_SYMBOL(wmt_plat_irq_cb_reg); ++ ++VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb) ++{ ++ wmt_plat_audio_if_cb = aif_ctrl_cb; ++} ++EXPORT_SYMBOL(wmt_plat_aif_cb_reg); ++ ++VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl) ++{ ++ wmt_plat_func_ctrl_cb = subsys_func_ctrl; ++} ++EXPORT_SYMBOL(wmt_plat_func_ctrl_cb_reg); ++ ++VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl) ++{ ++ wmt_plat_thermal_query_ctrl_cb = thermal_query_ctrl; ++} ++EXPORT_SYMBOL(wmt_plat_thermal_ctrl_cb_reg); ++ ++VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl) ++{ ++ wmt_plat_deep_idle_ctrl_cb = deep_idle_ctrl; ++} ++EXPORT_SYMBOL(wmt_plat_deep_idle_ctrl_cb_reg); ++ ++UINT32 wmt_plat_soc_co_clock_flag_get(VOID) ++{ ++ return gCoClockFlag; ++} ++ ++static UINT32 wmt_plat_soc_co_clock_flag_set(UINT32 flag) ++{ ++ gCoClockFlag = flag; ++ return 0; ++} ++ ++INT32 wmt_plat_init(UINT32 co_clock_type) ++{ ++ CMB_STUB_CB stub_cb; ++ INT32 iret; ++ /*init wmt function ctrl wakelock if wake lock is supported by host platform */ ++ ++ wmt_plat_soc_co_clock_flag_set(co_clock_type); ++ ++ stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; ++ stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; ++ stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl; ++ stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl; ++ stub_cb.size = sizeof(stub_cb); ++ ++ /* register to cmb_stub */ ++ iret = mtk_wcn_cmb_stub_reg(&stub_cb); ++#ifdef CFG_WMT_WAKELOCK_SUPPORT ++#ifdef CONFIG_PM_WAKELOCKS ++ wakeup_source_init(&wmtWakeLock, "wmtFuncCtrl"); ++#else ++ wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl"); ++#endif ++ mutex_init(&gOsSLock); ++#endif ++ ++#if CONSYS_BT_WIFI_SHARE_V33 ++ gBtWifiV33.counter = 0; ++ spin_lock_init(&gBtWifiV33.lock); ++#endif ++ ++ iret += mtk_wcn_consys_hw_init(); ++ ++ spin_lock_init(&gbgfIrqBle.lock); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_init); ++ ++INT32 wmt_plat_deinit(VOID) ++{ ++ INT32 iret = 0; ++ /* 2. unreg to cmb_stub */ ++ iret = mtk_wcn_cmb_stub_unreg(); ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling wmt wakelock deinit\n",__FUNCTION__,__LINE__); ++ /*3. wmt wakelock deinit */ ++#ifdef CFG_WMT_WAKELOCK_SUPPORT ++#ifdef CONFIG_PM_WAKELOCKS ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling wakeup_source_trash\n",__FUNCTION__,__LINE__); ++ wakeup_source_trash(&wmtWakeLock); ++#else ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling wake lock destroy %d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); ++//destroy calls wakeup_source_trash with &lock->ws ++printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock:%d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); ++printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock->ws: %d\n",__FUNCTION__,__LINE__,(int)&(wmtWakeLock.ws)); ++ wake_lock_destroy(&wmtWakeLock); ++#endif ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling mutex_destroy\n",__FUNCTION__,__LINE__); ++ mutex_destroy(&gOsSLock); ++ WMT_PLAT_DBG_FUNC("destroy wmtWakeLock\n"); ++#endif ++printk(KERN_ALERT "DEBUG: Passed %s %d now calling consys hw deinit\n",__FUNCTION__,__LINE__); ++ ++ iret += mtk_wcn_consys_hw_deinit(); ++ ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_deinit); ++ ++static INT32 wmt_plat_dump_pin_conf(VOID) ++{ ++ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration start<=\n"); ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++ ++#ifdef GPIO_COMBO_BGF_EINT_PIN ++ WMT_PLAT_DBG_FUNC("BGF_EINT(GPIO%d)\n", GPIO_COMBO_BGF_EINT_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("BGF_EINT(not defined)\n"); ++#endif ++ ++#ifdef CUST_EINT_COMBO_BGF_NUM ++ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(%d)\n", CUST_EINT_COMBO_BGF_NUM); ++#else ++ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(not defined)\n"); ++#endif ++ ++#ifdef GPIO_COMBO_URXD_PIN ++ WMT_PLAT_DBG_FUNC("UART_RX(GPIO%d)\n", GPIO_COMBO_URXD_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("UART_RX(not defined)\n"); ++#endif ++#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) ++#ifdef GPIO_COMBO_I2S_CK_PIN ++ WMT_PLAT_DBG_FUNC("I2S_CK(GPIO%d)\n", GPIO_COMBO_I2S_CK_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("I2S_CK(not defined)\n"); ++#endif ++#ifdef GPIO_COMBO_I2S_WS_PIN ++ WMT_PLAT_DBG_FUNC("I2S_WS(GPIO%d)\n", GPIO_COMBO_I2S_WS_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("I2S_WS(not defined)\n"); ++#endif ++#ifdef GPIO_COMBO_I2S_DAT_PIN ++ WMT_PLAT_DBG_FUNC("I2S_DAT(GPIO%d)\n", GPIO_COMBO_I2S_DAT_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("I2S_DAT(not defined)\n"); ++#endif ++#else /* FM_ANALOG_INPUT || FM_ANALOG_OUTPUT */ ++ WMT_PLAT_DBG_FUNC("FM digital mode is not set, no need for I2S GPIOs\n"); ++#endif ++#ifdef GPIO_GPS_SYNC_PIN ++ WMT_PLAT_DBG_FUNC("GPS_SYNC(GPIO%d)\n", GPIO_GPS_SYNC_PIN); ++#else ++ WMT_PLAT_DBG_FUNC("GPS_SYNC(not defined)\n"); ++#endif ++ ++#ifdef GPIO_GPS_LNA_PIN ++ WMT_PLAT_INFO_FUNC("GPS_LNA(GPIO%d)\n", GPIO_GPS_LNA_PIN); ++#else ++ WMT_PLAT_INFO_FUNC("GPS_LNA(not defined)\n"); ++#endif ++ ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n"); ++ return 0; ++} ++ ++INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state) ++{ ++ INT32 ret = -1; ++ ++ switch (state) { ++ case FUNC_ON: ++ /* TODO:[ChangeFeature][George] always output this or by request throuth /proc or sysfs? */ ++ wmt_plat_dump_pin_conf(); ++ ret = mtk_wcn_consys_hw_pwr_on(gCoClockFlag); ++ break; ++ ++ case FUNC_OFF: ++ ret = mtk_wcn_consys_hw_pwr_off(); ++ break; ++ ++ case FUNC_RST: ++ ret = mtk_wcn_consys_hw_rst(gCoClockFlag); ++ break; ++ case FUNC_STAT: ++ ret = mtk_wcn_consys_hw_state_show(); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state); ++ break; ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(wmt_plat_pwr_ctrl); ++ ++INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) ++{ ++#ifdef CONFIG_OF ++ struct device_node *node; ++ unsigned int irq_info[3] = { 0, 0, 0 }; ++#endif ++ INT32 iret = -EINVAL; ++ static INT32 bgf_irq_num = -1; ++ static UINT32 bgf_irq_flag; ++ /* TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls */ ++ ++ if ((PIN_STA_INIT != state) ++ && (PIN_STA_DEINIT != state) ++ && (PIN_STA_EINT_EN != state) ++ && (PIN_STA_EINT_DIS != state)) { ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id); ++ return -1; ++ } ++ ++ switch (id) { ++ case PIN_BGF_EINT: ++ ++ if (PIN_STA_INIT == state) { ++#ifdef CONFIG_OF ++ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); ++ if (node) { ++ bgf_irq_num = irq_of_parse_and_map(node, 0); ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ WMT_PLAT_ERR_FUNC("get irq flags from DTS fail!!\n"); ++ return iret; ++ } ++ bgf_irq_flag = irq_info[2]; ++ WMT_PLAT_INFO_FUNC("get irq id(%d) and irq trigger flag(%d) from DT\n", bgf_irq_num, ++ bgf_irq_flag); ++ } else { ++ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); ++ return iret; ++ } ++#else ++ bgf_irq_num = MT_CONN2AP_BTIF_WAKEUP_IRQ_ID; ++ bgf_irq_flag = IRQF_TRIGGER_LOW; ++#endif ++ iret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, bgf_irq_flag, "BTIF_WAKEUP_IRQ", NULL); ++ if (iret) { ++ WMT_PLAT_ERR_FUNC("request_irq fail,irq_no(%d),iret(%d)\n", bgf_irq_num, iret); ++ return iret; ++ } ++ gbgfIrqBle.counter = 1; ++ ++ } else if (PIN_STA_EINT_EN == state) { ++ ++ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ if (gbgfIrqBle.counter) { ++ WMT_PLAT_DBG_FUNC("BGF INT has been enabled,counter(%d)\n", gbgfIrqBle.counter); ++ } else { ++ enable_irq(bgf_irq_num); ++ gbgfIrqBle.counter++; ++ } ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (en)\n"); ++ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ } else if (PIN_STA_EINT_DIS == state) { ++ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ if (!gbgfIrqBle.counter) { ++ WMT_PLAT_INFO_FUNC("BGF INT has been disabled,counter(%d)\n", gbgfIrqBle.counter); ++ } else { ++ disable_irq_nosync(bgf_irq_num); ++ gbgfIrqBle.counter--; ++ } ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (dis)\n"); ++ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); ++ } else { ++ free_irq(bgf_irq_num, NULL); ++ /* de-init: nothing to do in ALPS, such as un-registration... */ ++ } ++ iret = 0; ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id); ++ iret = -1; ++ break; ++ } ++ ++ return iret; ++} ++EXPORT_SYMBOL(wmt_plat_eirq_ctrl); ++ ++INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) ++{ ++ if ((PIN_ID_MAX > id) ++ && (PIN_STA_MAX > state)) { ++ ++ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ ++ if (gfp_set_pin_table[id]) ++ return (*(gfp_set_pin_table[id])) (state); /* .handler */ ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id); ++ return -2; ++ } ++ return -1; ++} ++EXPORT_SYMBOL(wmt_plat_gpio_ctrl); ++ ++INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state) ++{ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++#ifdef GPIO_COMBO_BGF_EINT_PIN ++ switch (state) { ++ case PIN_STA_INIT: ++ /*set to gpio input low, pull down enable */ ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); ++ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); ++ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd)\n"); ++ break; ++ ++ case PIN_STA_MUX: ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); ++ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_UP); ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_EINT); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt mux (eint)\n"); ++ break; ++ ++ case PIN_STA_IN_L: ++ case PIN_STA_DEINIT: ++ /*set to gpio input low, pull down enable */ ++ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); ++ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); ++ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd)\n"); ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state); ++ break; ++ } ++#else ++ WMT_PLAT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n"); ++#endif ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ return 0; ++} ++ ++static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state) ++{ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++ ++#ifdef GPIO_GPS_SYNC_PIN ++#ifndef GPIO_GPS_SYNC_PIN_M_GPS_SYNC ++#ifdef GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC ++#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC ++#else ++#ifdef GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC ++#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC ++#endif ++#endif ++#endif ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_GPS_SYNC_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_GPS_SYNC_PIN, GPIO_OUT_ZERO); ++ break; ++ ++ case PIN_STA_MUX: ++ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPS_SYNC); ++ break; ++ ++ default: ++ break; ++ } ++#endif ++ ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ return 0; ++} ++ ++#if MTK_WCN_MT6306_IS_READY ++/* MT6306 GPIO7 is GPIO_GPS_LNA_EN, for K2 common phone pin modification */ ++static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) ++{ ++#ifdef GPIO_GPS_LNA_PIN ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ WMT_PLAT_ERR_FUNC("Gps LNA pin ctrl %d!\n", state); ++ mt6306_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); ++ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ case PIN_STA_OUT_H: ++ WMT_PLAT_ERR_FUNC("Gps LNA pin output high!\n"); ++ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); ++ break; ++ case PIN_STA_OUT_L: ++ WMT_PLAT_ERR_FUNC("Gps LNA pin output low!\n"); ++ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); ++ break; ++ } ++ return 0; ++#else ++ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); ++ return 0; ++#endif ++} ++#else ++ ++static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) ++{ ++#if !defined(CONFIG_MTK_GPIO_LEGACY) ++ static struct pinctrl_state *gps_lna_init; ++ static struct pinctrl_state *gps_lna_oh; ++ static struct pinctrl_state *gps_lna_ol; ++ static struct pinctrl *consys_pinctrl; ++ ++ WMT_PLAT_DBG_FUNC("ENTER++\n"); ++ consys_pinctrl = mtk_wcn_consys_get_pinctrl(); ++ if (NULL == consys_pinctrl) { ++ WMT_PLAT_ERR_FUNC("get consys pinctrl fail\n"); ++ return -1; ++ } ++ ++ gps_lna_init = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_init"); ++ if (NULL == gps_lna_init) { ++ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin init state!\n"); ++ return -2; ++ } ++ ++ gps_lna_oh = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_oh"); ++ if (NULL == gps_lna_oh) { ++ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin oh state!\n"); ++ return -3; ++ } ++ ++ gps_lna_ol = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_ol"); ++ if (NULL == gps_lna_ol) { ++ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin ol state!\n"); ++ return -4; ++ } ++ ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ pinctrl_select_state(consys_pinctrl, gps_lna_init); ++ WMT_PLAT_INFO_FUNC("set gps lna to init\n"); ++ break; ++ case PIN_STA_OUT_H: ++ pinctrl_select_state(consys_pinctrl, gps_lna_oh); ++ WMT_PLAT_INFO_FUNC("set gps lna to oh\n"); ++ break; ++ case PIN_STA_OUT_L: ++ pinctrl_select_state(consys_pinctrl, gps_lna_ol); ++ WMT_PLAT_INFO_FUNC("set gps lna to ol\n"); ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); ++ break; ++ } ++ return 0; ++#else ++#ifdef GPIO_GPS_LNA_PIN ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_DEINIT: ++ mt_set_gpio_pull_enable(GPIO_GPS_LNA_PIN, GPIO_PULL_DISABLE); ++ mt_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_mode(GPIO_GPS_LNA_PIN, GPIO_GPS_LNA_PIN_M_GPIO); ++ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ case PIN_STA_OUT_H: ++ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); ++ break; ++ case PIN_STA_OUT_L: ++ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); ++ break; ++ ++ default: ++ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); ++ break; ++ } ++ return 0; ++#else ++ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); ++ return 0; ++#endif ++#endif /* !defined(CONFIG_MTK_GPIO_LEGACY) */ ++} ++#endif ++ ++INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state) ++{ ++ /* TODO: [NewFeature][GeorgeKuo]: GPIO_I2Sx is changed according to different project. */ ++ /* TODO: provide a translation table in board_custom.h for different ALPS project customization. */ ++#if defined(CONFIG_MTK_GPIO_LEGACY) ++ ++#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) ++#if defined(GPIO_COMBO_I2S_CK_PIN) ++ switch (state) { ++ case PIN_STA_INIT: ++ case PIN_STA_MUX: ++ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_I2S0_CK); ++ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_I2S0_WS); ++ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_I2S0_DAT); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n"); ++ break; ++ case PIN_STA_IN_L: ++ case PIN_STA_DEINIT: ++ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_I2S_CK_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_COMBO_I2S_CK_PIN, GPIO_OUT_ZERO); ++ ++ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_I2S_WS_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_COMBO_I2S_WS_PIN, GPIO_OUT_ZERO); ++ ++ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_GPIO); ++ mt_set_gpio_dir(GPIO_COMBO_I2S_DAT_PIN, GPIO_DIR_OUT); ++ mt_set_gpio_out(GPIO_COMBO_I2S_DAT_PIN, GPIO_OUT_ZERO); ++ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n"); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", state); ++ break; ++ } ++#else ++ WMT_PLAT_ERR_FUNC("[MT6620]Error:FM digital mode set, but no I2S GPIOs defined\n"); ++#endif ++#else ++ WMT_PLAT_INFO_FUNC ++ ("[MT6620]warnning:FM digital mode is not set, no I2S GPIO settings should be modified by combo driver\n"); ++#endif ++ ++#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ ++#endif ++ return 0; ++} ++ ++INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId) ++{ ++#ifdef CFG_WMT_WAKELOCK_SUPPORT ++ static INT32 counter; ++ INT32 status; ++ INT32 ret = 0; ++ ++ ret = mutex_lock_killable(&gOsSLock); ++ if (ret) { ++ WMT_PLAT_ERR_FUNC("--->lock gOsSLock failed, ret=%d\n", ret); ++ return ret; ++ } ++ ++ if (WL_OP_GET == opId) ++ ++counter; ++ else if (WL_OP_PUT == opId) ++ --counter; ++ ++ mutex_unlock(&gOsSLock); ++ if (WL_OP_GET == opId && counter == 1) { ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_stay_awake(&wmtWakeLock); ++ status = wmtWakeLock.active; ++ #else ++ wake_lock(&wmtWakeLock); ++ status = wake_lock_active(&wmtWakeLock); ++ #endif ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", status, counter); ++ ++ } else if (WL_OP_PUT == opId && counter == 0) { ++ #ifdef CONFIG_PM_WAKELOCKS ++ __pm_relax(&wmtWakeLock); ++ status = wmtWakeLock.active; ++ #else ++ wake_unlock(&wmtWakeLock); ++ status = wake_lock_active(&wmtWakeLock); ++ #endif ++ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", status, counter); ++ } else { ++ #ifdef CONFIG_PM_WAKELOCKS ++ status = wmtWakeLock.active; ++ #else ++ status = wake_lock_active(&wmtWakeLock); ++ #endif ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", status, counter); ++ } ++ return 0; ++#else ++ WMT_PLAT_WARN_FUNC("WMT-PLAT: host awake function is not supported.\n"); ++ return 0; ++ ++#endif ++} ++EXPORT_SYMBOL(wmt_plat_wake_lock_ctrl); ++ ++INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo) ++{ ++ INT32 iRet = 0; ++ ++ switch (ePt) { ++ ++ case BT_PALDO: ++ iRet = mtk_wcn_consys_hw_bt_paldo_ctrl(ePo); ++ break; ++ case WIFI_PALDO: ++ iRet = mtk_wcn_consys_hw_wifi_paldo_ctrl(ePo); ++ break; ++ case FM_PALDO: ++ case GPS_PALDO: ++ iRet = mtk_wcn_consys_hw_vcn28_ctrl(ePo); ++ break; ++ default: ++ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid type(%d) in palod_ctrl\n", ePt); ++ break; ++ } ++ return iRet; ++} ++EXPORT_SYMBOL(wmt_plat_soc_paldo_ctrl); ++ ++UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset) ++{ ++ return mtk_wcn_consys_emi_virt_addr_get(offset); ++} ++EXPORT_SYMBOL(wmt_plat_get_emi_virt_add); ++ ++P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID) ++{ ++ return &mtk_wcn_emi_addr_info; ++} ++EXPORT_SYMBOL(wmt_plat_get_emi_phy_add); ++ ++#if CONSYS_ENALBE_SET_JTAG ++UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en) ++{ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_jtag_flag_ctrl); ++#endif ++ ++#if CFG_WMT_DUMP_INT_STATUS ++VOID wmt_plat_BGF_irq_dump_status(VOID) ++{ ++ WMT_PLAT_INFO_FUNC("this function is null in MT8127\n"); ++} ++EXPORT_SYMBOL(wmt_plat_BGF_irq_dump_status); ++ ++MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID) ++{ ++ return MTK_WCN_BOOL_FALSE; ++} ++EXPORT_SYMBOL(wmt_plat_dump_BGF_irq_status); ++#endif ++ ++UINT32 wmt_plat_read_cpupcr(void) ++{ ++ return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); ++} ++EXPORT_SYMBOL(wmt_plat_read_cpupcr); ++ ++UINT32 wmt_plat_read_dmaregs(UINT32 type) ++{ ++ return 0; ++#if 0 ++ switch (type) { ++ case CONNSYS_CLK_GATE_STATUS: ++ return CONSYS_REG_READ(CONNSYS_CLK_GATE_STATUS_REG); ++ case CONSYS_EMI_STATUS: ++ return CONSYS_REG_READ(CONSYS_EMI_STATUS_REG); ++ case SYSRAM1: ++ return CONSYS_REG_READ(SYSRAM1_REG); ++ case SYSRAM2: ++ return CONSYS_REG_READ(SYSRAM2_REG); ++ case SYSRAM3: ++ return CONSYS_REG_READ(SYSRAM3_REG); ++ default: ++ return 0; ++ } ++#endif ++} ++ ++INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_STATE); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ CONSYS_REG_WRITE(p_virtual_addr, state); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_set_host_dump_state); ++ ++UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ ++ switch (type) { ++ case STP_FORCE_TRG_ASSERT_EMI: ++ ++ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); ++ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); ++ break; ++ case STP_FORCE_TRG_ASSERT_DEBUG_PIN: ++ ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + ++ CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); ++ WMT_PLAT_INFO_FUNC("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); ++ usleep_range(64, 96); ++ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, ++ CONSYS_REG_READ(conn_reg.topckgen_base + ++ CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); ++ WMT_PLAT_INFO_FUNC("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", ++ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); ++ ++ break; ++ default: ++ WMT_PLAT_ERR_FUNC("unknown force trigger assert type\n"); ++ break; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_force_trigger_assert); ++ ++INT32 wmt_plat_update_host_sync_num(VOID) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ UINT32 sync_num = 0; ++ ++ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_NUM); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ ++ sync_num = CONSYS_REG_READ(p_virtual_addr); ++ CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1); ++ ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_update_host_sync_num); ++ ++INT32 wmt_plat_get_dump_info(UINT32 offset) ++{ ++ PUINT8 p_virtual_addr = NULL; ++ ++ p_virtual_addr = wmt_plat_get_emi_virt_add(offset); ++ if (!p_virtual_addr) { ++ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); ++ return -1; ++ } ++ WMT_PLAT_INFO_FUNC("connsys_reg_read (0x%x), (0x%p), (0x%x)\n", CONSYS_REG_READ(p_virtual_addr), p_virtual_addr, ++ offset); ++ return CONSYS_REG_READ(p_virtual_addr); ++} ++EXPORT_SYMBOL(wmt_plat_get_dump_info); ++ ++UINT32 wmt_plat_get_soc_chipid(void) ++{ ++ UINT32 chipId = mtk_wcn_consys_soc_chipid(); ++ ++ WMT_PLAT_INFO_FUNC("current SOC chip:0x%x\n", chipId); ++ return chipId; ++} ++EXPORT_SYMBOL(wmt_plat_get_soc_chipid); ++ ++#if CFG_WMT_LTE_COEX_HANDLING ++INT32 wmt_plat_get_tdm_antsel_index(VOID) ++{ ++ WMT_PLAT_INFO_FUNC("not support LTE in this platform\n"); ++ return 0; ++} ++EXPORT_SYMBOL(wmt_plat_get_tdm_antsel_index); ++#endif ++INT32 wmt_plat_set_dbg_mode(UINT32 flag) ++{ ++ return -1; ++} ++VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf) ++{ ++ mtk_wcn_consys_set_dynamic_dump(buf); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/Makefile b/drivers/misc/mediatek/connectivity/wlan/Makefile +new file mode 100644 +index 000000000000..2961aeb073ea +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/Makefile +@@ -0,0 +1,8 @@ ++ifeq ($(CONFIG_MTK_COMBO_WIFI),y) ++ subdir-ccflags-y += -D MTK_WCN_BUILT_IN_DRIVER ++endif ++ ++ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) ++#$(warning include gen2) ++ obj-y += gen2/ ++endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile +new file mode 100644 +index 000000000000..b86ab49fce3a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile +@@ -0,0 +1,237 @@ ++# --------------------------------------------------- ++# Compile Options ++# --------------------------------------------------- ++ccflags-y += -DLINUX -DMT6628 ++ ++ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=1 ++ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1 ++ccflags-y += -DCFG_P2P_LEGACY_COEX_REVISE=1 ++ccflags-y += -DARP_MONITER_ENABLE=1 ++ ++ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) ++ ccflags-y += -DCFG_SUPPORT_WAPI=1 ++else ++ ccflags-y += -DCFG_SUPPORT_WAPI=0 ++endif ++ ++ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y) ++ ccflags-y += -DCFG_SUPPORT_MCC=1 ++else ++ ccflags-y += -DCFG_SUPPORT_MCC=0 ++endif ++ ++ifeq ($(CONFIG_HAVE_XLOG_FEATURE), y) ++ ccflags-y += -DCFG_SUPPORT_XLOG=1 ++else ++ ccflags-y += -DCFG_SUPPORT_XLOG=0 ++endif ++ ++ifeq ($(CONFIG_MTK_AEE_FEATURE), y) ++ ccflags-y += -DCFG_SUPPORT_AEE=1 ++else ++ ccflags-y += -DCFG_SUPPORT_AEE=0 ++endif ++ ++#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y) ++# ccflags-y += -D_HIF_SDIO=1 ++#endif ++ ++ifeq ($(CONFIG_MTK_PASSPOINT_R1_SUPPORT), y) ++ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=1 ++ ccflags-y += -DCFG_HS20_DEBUG=1 ++ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1 ++else ++ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=0 ++ ccflags-y += -DCFG_HS20_DEBUG=0 ++ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0 ++endif ++ ++MTK_MET_PROFILING_SUPPORT = no ++ifeq ($(MTK_MET_PROFILING_SUPPORT), yes) ++ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=1 ++else ++ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=0 ++endif ++ ++ifeq ($(CONFIG_MTK_TC1_FEATURE), y) ++ifeq ($(CONFIG_MTK_GPT_SCHEME_SUPPORT), y) ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/gpt ++else ++ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/pmt ++endif ++ ccflags-y += -DCFG_TC1_FEATURE=1 ++ ccflags-y += -DCFG_SUPPORT_CFG_FILE=1 ++else ++ ccflags-y += -DCFG_TC1_FEATURE=0 ++endif ++ ++MTK_SRAM_SIZE_OPTION=0 ++ifeq ($(CONFIG_ARCH_MT6755), y) ++ MTK_SRAM_SIZE_OPTION=2 ++endif ++ifeq ($(CONFIG_ARCH_MT6735), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT6735M), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT6753), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT6580), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ifeq ($(CONFIG_ARCH_MT8163), y) ++ MTK_SRAM_SIZE_OPTION=1 ++endif ++ccflags-y += -DCFG_SRAM_SIZE_OPTION=$(MTK_SRAM_SIZE_OPTION) ++ ++ifeq ($(strip $(TRUSTONIC_TEE_SUPPORT)),yes) ++ifeq ($(strip $(MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT)),yes) ++ ccflags-y += -DTRUSTONIC_TEE_SUPPORT ++ ccflags-y += -DMTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT ++endif ++endif ++ ++ccflags-y += -D_HIF_SDIO=1 ++ ++ccflags-y += -DDBG=0 ++ccflags-y += -I$(src)/os -I$(src)/os/linux/include -I$(src)/os/linux/hif/ahb/include ++ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt ++ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include ++ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/ ++ ++MODULE_NAME := wlan_gen2 ++obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o ++#obj-m += $(MODULE_NAME).o if CONFIG_MTK_COMBO_WIFI=m ==> obj-m means ko module, not build in obj-y ++ ++# --------------------------------------------------- ++# Directory List ++# --------------------------------------------------- ++COMMON_DIR := common/ ++OS_DIR := os/linux/ ++HIF_DIR := os/linux/hif/ahb/ ++NIC_DIR := nic/ ++MGMT_DIR := mgmt/ ++DMA_DIR := ../../../../platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/wifi/ ++PLAT_DIR := os/linux/plat/$(MTK_PLATFORM)/ ++HIF_AHB_PDMA := $(HIF_DIR)$(MTK_PLATFORM)/ ++#$(call lc,$(MTK_PLATFORM)) ++ ++ ++# --------------------------------------------------- ++# Objects List ++# --------------------------------------------------- ++ ++COMMON_OBJS := $(COMMON_DIR)dump.o \ ++ $(COMMON_DIR)wlan_lib.o \ ++ $(COMMON_DIR)wlan_oid.o \ ++ $(COMMON_DIR)wlan_bow.o \ ++ $(COMMON_DIR)debug.o ++ ++NIC_OBJS := $(NIC_DIR)nic.o \ ++ $(NIC_DIR)nic_tx.o \ ++ $(NIC_DIR)nic_rx.o \ ++ $(NIC_DIR)nic_pwr_mgt.o \ ++ $(NIC_DIR)cmd_buf.o \ ++ $(NIC_DIR)que_mgt.o \ ++ $(NIC_DIR)nic_cmd_event.o ++ ++OS_OBJS := $(OS_DIR)gl_init.o \ ++ $(OS_DIR)gl_kal.o \ ++ $(OS_DIR)gl_bow.o \ ++ $(OS_DIR)gl_wext.o \ ++ $(OS_DIR)gl_wext_priv.o \ ++ $(OS_DIR)gl_rst.o \ ++ $(OS_DIR)gl_cfg80211.o \ ++ $(OS_DIR)gl_vendor.o \ ++ $(OS_DIR)platform.o \ ++ $(OS_DIR)gl_proc.o ++ ++MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \ ++ $(MGMT_DIR)aaa_fsm.o \ ++ $(MGMT_DIR)assoc.o \ ++ $(MGMT_DIR)auth.o \ ++ $(MGMT_DIR)bss.o \ ++ $(MGMT_DIR)cnm.o \ ++ $(MGMT_DIR)cnm_timer.o \ ++ $(MGMT_DIR)cnm_mem.o \ ++ $(MGMT_DIR)hem_mbox.o \ ++ $(MGMT_DIR)mib.o \ ++ $(MGMT_DIR)privacy.o \ ++ $(MGMT_DIR)rate.o \ ++ $(MGMT_DIR)rlm.o \ ++ $(MGMT_DIR)rlm_domain.o \ ++ $(MGMT_DIR)rlm_obss.o \ ++ $(MGMT_DIR)rlm_protection.o \ ++ $(MGMT_DIR)rsn.o \ ++ $(MGMT_DIR)saa_fsm.o \ ++ $(MGMT_DIR)scan.o \ ++ $(MGMT_DIR)scan_fsm.o \ ++ $(MGMT_DIR)sec_fsm.o \ ++ $(MGMT_DIR)swcr.o \ ++ $(MGMT_DIR)swcr.o \ ++ $(MGMT_DIR)roaming_fsm.o \ ++ $(MGMT_DIR)hs20.o ++ ++# --------------------------------------------------- ++# TDLS Objects List ++# --------------------------------------------------- ++MGMT_OBJS += $(MGMT_DIR)tdls.o \ ++ $(MGMT_DIR)tdls_com.o ++ ++# --------------------------------------------------- ++# STATS Objects List ++# --------------------------------------------------- ++MGMT_OBJS += $(MGMT_DIR)stats.o ++ ++# --------------------------------------------------- ++# P2P Objects List ++# --------------------------------------------------- ++ ++COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o ++ ++NIC_OBJS += $(NIC_DIR)p2p_nic.o ++ ++OS_OBJS += $(OS_DIR)gl_p2p.o \ ++ $(OS_DIR)gl_p2p_cfg80211.o \ ++ $(OS_DIR)gl_p2p_init.o \ ++ $(OS_DIR)gl_p2p_kal.o ++ ++MGMT_OBJS += $(MGMT_DIR)p2p_assoc.o \ ++ $(MGMT_DIR)p2p_bss.o \ ++ $(MGMT_DIR)p2p_fsm.o \ ++ $(MGMT_DIR)p2p_func.o \ ++ $(MGMT_DIR)p2p_rlm.o \ ++ $(MGMT_DIR)p2p_rlm_obss.o \ ++ $(MGMT_DIR)p2p_scan.o \ ++ $(MGMT_DIR)p2p_ie.o \ ++ $(MGMT_DIR)p2p_state.o ++ ++ ++ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) ++MGMT_OBJS += $(MGMT_DIR)wapi.o ++endif ++ ++ifeq ($(WLAN_PROC), y) ++OS_OBJS += gl_proc.o ++endif ++ ++#$(warning $(CONFIG_MACH_MT7623)) ++ ++ifeq ($(CONFIG_MACH_MT7623), y) ++HIF_AHB_PDMA = $(HIF_DIR)mt8127/ ++endif ++HIF_OBJS := $(HIF_DIR)arm.o \ ++ $(HIF_DIR)ahb.o \ ++ $(HIF_AHB_PDMA)ahb_pdma.o ++ifeq ($(CONFIG_ARCH_MT6755), y) ++PLAT_OBJS := $(PLAT_DIR)plat_priv.o ++$(MODULE_NAME)-objs += $(PLAT_OBJS) ++endif ++$(MODULE_NAME)-objs += $(COMMON_OBJS) ++$(MODULE_NAME)-objs += $(NIC_OBJS) ++$(MODULE_NAME)-objs += $(OS_OBJS) ++$(MODULE_NAME)-objs += $(HIF_OBJS) ++$(MODULE_NAME)-objs += $(MGMT_OBJS) ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c +new file mode 100644 +index 000000000000..e31e0b86d231 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c +@@ -0,0 +1,165 @@ ++#include "precomp.h" ++#include "gl_kal.h" ++ ++struct COMMAND { ++ UINT_8 ucCID; ++ BOOLEAN fgSetQuery; ++ BOOLEAN fgNeedResp; ++ UINT_8 ucCmdSeqNum; ++}; ++ ++struct SECURITY_FRAME { ++ UINT_16 u2EthType; ++ UINT_16 u2Reserved; ++}; ++ ++struct MGMT_FRAME { ++ UINT_16 u2FrameCtl; ++ UINT_16 u2DurationID; ++}; ++ ++struct TC_RES_RELEASE_ENTRY { ++ UINT_64 u8RelaseTime; ++ UINT_32 u4RelCID; ++ UINT_8 ucTc4RelCnt; ++ UINT_8 ucAvailableTc4; ++}; ++ ++struct CMD_TRACE_ENTRY { ++ UINT_64 u8TxTime; ++ COMMAND_TYPE eCmdType; ++ union { ++ struct COMMAND rCmd; ++ struct SECURITY_FRAME rSecFrame; ++ struct MGMT_FRAME rMgmtFrame; ++ } u; ++}; ++ ++#define TC_RELEASE_TRACE_BUF_MAX_NUM 100 ++#define TXED_CMD_TRACE_BUF_MAX_NUM 100 ++ ++static struct TC_RES_RELEASE_ENTRY *gprTcReleaseTraceBuffer; ++static struct CMD_TRACE_ENTRY *gprCmdTraceEntry; ++VOID wlanDebugInit(VOID) ++{ ++ /* debug for command/tc4 resource begin */ ++ gprTcReleaseTraceBuffer = ++ kalMemAlloc(TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY), PHY_MEM_TYPE); ++ kalMemZero(gprTcReleaseTraceBuffer, TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); ++ gprCmdTraceEntry = kalMemAlloc(TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY), PHY_MEM_TYPE); ++ kalMemZero(gprCmdTraceEntry, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); ++ /* debug for command/tc4 resource end */ ++} ++ ++VOID wlanDebugUninit(VOID) ++{ ++ /* debug for command/tc4 resource begin */ ++ kalMemFree(gprTcReleaseTraceBuffer, PHY_MEM_TYPE, ++ TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); ++ kalMemFree(gprCmdTraceEntry, PHY_MEM_TYPE, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); ++ /* debug for command/tc4 resource end */ ++} ++ ++VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd) ++{ ++ static UINT_16 u2CurEntry; ++ struct CMD_TRACE_ENTRY *prCurCmd = &gprCmdTraceEntry[u2CurEntry]; ++ ++ prCurCmd->u8TxTime = sched_clock(); ++ prCurCmd->eCmdType = prCmd->eCmdType; ++ if (prCmd->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ P_WLAN_MAC_MGMT_HEADER_T prMgmt = (P_WLAN_MAC_MGMT_HEADER_T)((P_MSDU_INFO_T)prCmd->prPacket)->prPacket; ++ ++ prCurCmd->u.rMgmtFrame.u2FrameCtl = prMgmt->u2FrameCtrl; ++ prCurCmd->u.rMgmtFrame.u2DurationID = prMgmt->u2Duration; ++ } else if (prCmd->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { ++ PUINT_8 pucPkt = (PUINT_8)((struct sk_buff *)prCmd->prPacket)->data; ++ ++ prCurCmd->u.rSecFrame.u2EthType = ++ (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); ++ } else { ++ prCurCmd->u.rCmd.ucCID = prCmd->ucCID; ++ prCurCmd->u.rCmd.ucCmdSeqNum = prCmd->ucCmdSeqNum; ++ prCurCmd->u.rCmd.fgNeedResp = prCmd->fgNeedResp; ++ prCurCmd->u.rCmd.fgSetQuery = prCmd->fgSetQuery; ++ } ++ u2CurEntry++; ++ if (u2CurEntry == TC_RELEASE_TRACE_BUF_MAX_NUM) ++ u2CurEntry = 0; ++} ++ ++VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable) ++{ ++ static UINT_16 u2CurEntry; ++ struct TC_RES_RELEASE_ENTRY *prCurBuf = &gprTcReleaseTraceBuffer[u2CurEntry]; ++ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &prCurBuf->u4RelCID); ++ prCurBuf->u8RelaseTime = sched_clock(); ++ prCurBuf->ucTc4RelCnt = aucTxRlsCnt[TC4_INDEX]; ++ prCurBuf->ucAvailableTc4 = ucAvailable; ++ u2CurEntry++; ++ if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM) ++ u2CurEntry = 0; ++} ++ ++VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen) ++{ ++ UINT_16 i = 0; ++ struct CMD_TRACE_ENTRY *prCmd = gprCmdTraceEntry; ++ struct TC_RES_RELEASE_ENTRY *prTcRel = gprTcReleaseTraceBuffer; ++ ++ if (pucBuf) { ++ int bufLen = 0; ++ ++ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/2; i++) { ++ bufLen = snprintf(pucBuf, maxLen, ++ "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", ++ i*2, prCmd[i*2].u8TxTime, prCmd[i*2].eCmdType, *(PUINT_32)(&prCmd[i*2].u.rCmd.ucCID), ++ i*2+1, prCmd[i*2+1].u8TxTime, prCmd[i*2+1].eCmdType, ++ *(PUINT_32)(&prCmd[i*2+1].u.rCmd.ucCID)); ++ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) ++ break; ++ pucBuf += bufLen; ++ maxLen -= bufLen; ++ } ++ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/2; i++) { ++ bufLen = snprintf(pucBuf, maxLen, ++ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d CID %08x\n", ++ i*2, prTcRel[i*2].u8RelaseTime, prTcRel[i*2].ucTc4RelCnt, prTcRel[i*2].ucAvailableTc4, ++ prTcRel[i*2].u4RelCID, ++ i*2+1, prTcRel[i*2+1].u8RelaseTime, prTcRel[i*2+1].ucTc4RelCnt, ++ prTcRel[i*2+1].ucAvailableTc4, prTcRel[i*2+1].u4RelCID); ++ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) ++ break; ++ pucBuf += bufLen; ++ maxLen -= bufLen; ++ } ++ return; ++ } ++ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/4; i++) { ++ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x; ", ++ i*4, prCmd[i*4].u8TxTime, prCmd[i*4].eCmdType, ++ *(PUINT_32)(&prCmd[i*4].u.rCmd.ucCID), ++ i*4+1, prCmd[i*4+1].u8TxTime, prCmd[i*4+1].eCmdType, ++ *(PUINT_32)(&prCmd[i*4+1].u.rCmd.ucCID)); ++ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", ++ i*4+2, prCmd[i*4+2].u8TxTime, prCmd[i*4+2].eCmdType, ++ *(PUINT_32)(&prCmd[i*4+2].u.rCmd.ucCID), ++ i*4+3, prCmd[i*4+3].u8TxTime, prCmd[i*4+3].eCmdType, ++ *(PUINT_32)(&prCmd[i*4+3].u.rCmd.ucCID)); ++ } ++ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/4; i++) { ++ LOG_FUNC( ++ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x;", ++ i*4, prTcRel[i*4].u8RelaseTime, prTcRel[i*4].ucTc4RelCnt, ++ prTcRel[i*4].ucAvailableTc4, prTcRel[i*4].u4RelCID, ++ i*4+1, prTcRel[i*4+1].u8RelaseTime, prTcRel[i*4+1].ucTc4RelCnt, ++ prTcRel[i*4+1].ucAvailableTc4, prTcRel[i*4+1].u4RelCID); ++ LOG_FUNC( ++ " %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x\n", ++ i*4+2, prTcRel[i*4+2].u8RelaseTime, prTcRel[i*4+2].ucTc4RelCnt, ++ prTcRel[i*4+2].ucAvailableTc4, prTcRel[i*4+2].u4RelCID, ++ i*4+3, prTcRel[i*4+3].u8RelaseTime, prTcRel[i*4+3].ucTc4RelCnt, ++ prTcRel[i*4+3].ucAvailableTc4, prTcRel[i*4+3].u4RelCID); ++ } ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c +new file mode 100644 +index 000000000000..486ba239f16a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c +@@ -0,0 +1,345 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/dump.c#1 ++*/ ++ ++/*! \file "dump.c" ++ \brief Provide memory dump function for debugging. ++ ++ Provide memory dump function for debugging. ++*/ ++ ++/* ++** Log: dump.c ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Using the new XLOG define for dum Memory. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Add dumpMemory8 at XLOG support. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 19:58:51 GMT mtk01426 ++** Init develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dump a segment of memory in bytes. ++* ++* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. ++* \param[in] u4Length Length of the memory to be dumped. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length) ++{ ++ ASSERT(pucStartAddr); ++ ++ LOG_FUNC("DUMP8 ADDRESS: %p, Length: %u\n", pucStartAddr, u4Length); ++ ++ while (u4Length > 0) { ++ if (u4Length >= 16) { ++ LOG_FUNC( ++ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], pucStartAddr[8], ++ pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], pucStartAddr[12], pucStartAddr[13], ++ pucStartAddr[14], pucStartAddr[15]); ++ u4Length -= 16; ++ pucStartAddr += 16; ++ } else { ++ switch (u4Length) { ++ case 1: ++ LOG_FUNC("(%p) %02x\n", pucStartAddr, pucStartAddr[0]); ++ break; ++ case 2: ++ LOG_FUNC("(%p) %02x %02x\n", pucStartAddr, pucStartAddr[0], pucStartAddr[1]); ++ break; ++ case 3: ++ LOG_FUNC("(%p) %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2]); ++ break; ++ case 4: ++ LOG_FUNC("(%p) %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3]); ++ break; ++ case 5: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4]); ++ break; ++ case 6: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5]); ++ break; ++ case 7: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6]); ++ break; ++ case 8: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7]); ++ break; ++ case 9: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8]); ++ break; ++ case 10: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9]); ++ break; ++ case 11: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10]); ++ break; ++ case 12: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11]); ++ break; ++ case 13: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x\n", ++ pucStartAddr, ++ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], ++ pucStartAddr[12]); ++ break; ++ case 14: ++ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], ++ pucStartAddr[12], pucStartAddr[13]); ++ break; ++ case 15: ++ LOG_FUNC( ++ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x\n", ++ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], ++ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], ++ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], ++ pucStartAddr[12], pucStartAddr[13], pucStartAddr[14]); ++ break; ++ /* ++ default: ++ break; ++ */ ++ } ++ u4Length = 0; ++ } ++ } ++ ++ LOG_FUNC("\n"); ++ ++} /* end of dumpMemory8() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dump a segment of memory in double words. ++* ++* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. ++* \param[in] u4Length Length of the memory to be dumped. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length) ++{ ++ PUINT_8 pucAddr; ++ ++ ASSERT(pu4StartAddr); ++ ++ LOG_FUNC("DUMP32 ADDRESS: %p, Length: %u\n", pu4StartAddr, u4Length); ++ ++ if (IS_NOT_ALIGN_4((ULONG) pu4StartAddr)) { ++ UINT_32 u4ProtrudeLen = sizeof(UINT_32) - ((ULONG) pu4StartAddr % 4); ++ ++ u4ProtrudeLen = ((u4Length < u4ProtrudeLen) ? u4Length : u4ProtrudeLen); ++ LOG_FUNC("pu4StartAddr is not at DW boundary.\n"); ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ ++ switch (u4ProtrudeLen) { ++ case 1: ++ LOG_FUNC("(%p) %02x------\n", pu4StartAddr, pucAddr[0]); ++ break; ++ case 2: ++ LOG_FUNC("(%p) %02x%02x----\n", pu4StartAddr, pucAddr[1], pucAddr[0]); ++ break; ++ case 3: ++ LOG_FUNC("(%p) %02x%02x%02x--\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ default: ++ break; ++ } ++ ++ u4Length -= u4ProtrudeLen; ++ pu4StartAddr = (PUINT_32) ((ULONG) pu4StartAddr + u4ProtrudeLen); ++ } ++ ++ while (u4Length > 0) { ++ if (u4Length >= 16) { ++ LOG_FUNC("(%p) %08x %08x %08x %08x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pu4StartAddr[3]); ++ pu4StartAddr += 4; ++ u4Length -= 16; ++ } else { ++ switch (u4Length) { ++ case 1: ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ LOG_FUNC("(%p) ------%02x\n", pu4StartAddr, pucAddr[0]); ++ break; ++ case 2: ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ LOG_FUNC("(%p) ----%02x%02x\n", pu4StartAddr, pucAddr[1], pucAddr[0]); ++ break; ++ case 3: ++ pucAddr = (PUINT_8) &pu4StartAddr[0]; ++ LOG_FUNC("(%p) --%02x%02x%02x\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 4: ++ LOG_FUNC("(%p) %08x\n", pu4StartAddr, pu4StartAddr[0]); ++ break; ++ case 5: ++ pucAddr = (PUINT_8) &pu4StartAddr[1]; ++ LOG_FUNC("(%p) %08x ------%02x\n", pu4StartAddr, pu4StartAddr[0], pucAddr[0]); ++ break; ++ case 6: ++ pucAddr = (PUINT_8) &pu4StartAddr[1]; ++ LOG_FUNC("(%p) %08x ----%02x%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pucAddr[1], pucAddr[0]); ++ break; ++ case 7: ++ pucAddr = (PUINT_8) &pu4StartAddr[1]; ++ LOG_FUNC("(%p) %08x --%02x%02x%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 8: ++ LOG_FUNC("(%p) %08x %08x\n", pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1]); ++ break; ++ case 9: ++ pucAddr = (PUINT_8) &pu4StartAddr[2]; ++ LOG_FUNC("(%p) %08x %08x ------%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[0]); ++ break; ++ case 10: ++ pucAddr = (PUINT_8) &pu4StartAddr[2]; ++ LOG_FUNC("(%p) %08x %08x ----%02x%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[1], pucAddr[0]); ++ break; ++ case 11: ++ pucAddr = (PUINT_8) &pu4StartAddr[2]; ++ LOG_FUNC("(%p) %08x %08x --%02x%02x%02x\n", ++ pu4StartAddr, ++ pu4StartAddr[0], pu4StartAddr[1], pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 12: ++ LOG_FUNC("(%p) %08x %08x %08x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2]); ++ break; ++ case 13: ++ pucAddr = (PUINT_8) &pu4StartAddr[3]; ++ LOG_FUNC("(%p) %08x %08x %08x ------%02x\n", ++ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[0]); ++ break; ++ case 14: ++ pucAddr = (PUINT_8) &pu4StartAddr[3]; ++ LOG_FUNC("(%p) %08x %08x %08x ----%02x%02x\n", ++ pu4StartAddr, ++ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ case 15: ++ pucAddr = (PUINT_8) &pu4StartAddr[3]; ++ LOG_FUNC("(%p) %08x %08x %08x --%02x%02x%02x\n", ++ pu4StartAddr, ++ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], ++ pucAddr[2], pucAddr[1], pucAddr[0]); ++ break; ++ /* ++ default: ++ break; ++ */ ++ } ++ u4Length = 0; ++ } ++ } ++ ++} /* end of dumpMemory32() */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c +new file mode 100644 +index 000000000000..21bd849827e1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c +@@ -0,0 +1,3442 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_bow.c#1 ++*/ ++ ++/*! \file wlan_bow.c ++ \brief This file contains the 802.11 PAL commands processing routines for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_bow.c ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW for 5GHz band. ++ * ++ * 01 09 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * [ALPS00110632] [Rose][LCA42][Cross Feature][Bluetooth]The "KE" pops up after the device reboots automatically.(once) ++ * ++ * Fix bow link disconnected event dereference. ++ * ++ * 09 29 2011 cm.chang ++ * NULL ++ * Change the function prototype of rlmDomainGetChnlList() ++ * ++ * 07 06 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Improve BoW connection establishment speed. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 21 2011 terry.wu ++ * NULL ++ * Fix BoW KE. ++ * ++ * 06 20 2011 terry.wu ++ * NULL ++ * Add BoW Rate Limitation. ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * Add BoW 11N support. ++ * ++ * 06 07 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * aware more compile options. ++ * ++ * 05 25 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW Cancel Scan Request and Turn On deactive network function. ++ * ++ * 05 23 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add some BoW error handling. ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * . ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Only reply probe response to its peer or mached SSID for BoW AP. ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW SAA retry and disable disconnect event when AAA fail . ++ * ++ * 05 21 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Protect BoW connection establishment. ++ * ++ * 05 17 2011 terry.wu ++ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting ++ * Send deauth while disconnecting BoW link. ++ * ++ * 05 17 2011 terry.wu ++ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue ++ * Fix wrong StaRec state of BoW . ++ * ++ * 05 06 2011 terry.wu ++ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue ++ * Fix BoW Multiple Physical Link connect/disconnect issue. ++ * ++ * 05 03 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix prAssocRspSwRfb casting. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 12 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add WMM IE for BOW initiator data. ++ * ++ * 04 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. ++ * ++ * 04 09 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link connection event procedure and change skb length check to 1512 bytes. ++ * ++ * 03 28 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Simplify link disconnected routine, remove link disconnected other routine. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add new feature - multiple physical link support. ++ * ++ * 02 22 2011 wh.su ++ * [WCXRP00000486] [MT6620 Wi-Fi][BOW] Fixed the bow send frame but not encrypted issue ++ * fixed the BOW packet sending without encrypted issue. ++ * ++ * 02 21 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix BOW link disconnection bug. ++ * ++ * 02 16 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting. ++ * ++ * 02 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW channel granted function. ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 ++ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 ++ * with BOW and P2P enabled as default ++ * ++ * 02 08 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. ++ * Update BOW get MAC status, remove returning event for AIS network type. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW Activity Report structure and bug fix. ++ * ++ * 01 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW to support multiple physical link. ++ * ++ * 12 08 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support concurrent networks. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 11 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix BoW timer assert issue. ++ * ++ * 10 18 2010 chinghwa.yu ++ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size ++ * Fix for event returnning Band. ++ * ++ * 10 18 2010 chinghwa.yu ++ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size ++ * Fix wrong BoW event size. ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced ++ * by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 16 2010 chinghwa.yu ++ * NULL ++ * Fix bowResponderScanDone error when prBssDesc is NULL. ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Add bowRunEventAAAComplete. ++ * ++ * 09 14 2010 cp.wu ++ * NULL ++ * indicate correct AIS network information for PAL. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Initialize nicActivateNetwork(prAdapter as soon as bow is starting.. ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add NULL OID implementation for WOL-related OIDs. ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * 1) all BT physical handles shares the same RSSI/Link Quality. ++ * 2) simplify BT command composing ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * 2) command sequence number is now increased atomically ++ * * 3) private data could be hold and taken use for other purpose ++** ++*/ ++ ++/****************************************************************************** ++* C O M P I L E R F L A G S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************* ++*/ ++#include "precomp.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++/****************************************************************************** ++* C O N S T A N T S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* D A T A T Y P E S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P U B L I C D A T A ++******************************************************************************* ++*/ ++ ++static UINT_32 g_u4LinkCount; ++static UINT_32 g_u4Beaconing; ++static BOW_TABLE_T arBowTable[CFG_BOW_PHYSICAL_LINK_NUM]; ++ ++/****************************************************************************** ++* P R I V A T E D A T A ++******************************************************************************* ++*/ ++ ++const BOW_CMD_T arBowCmdTable[] = { ++ {BOW_CMD_ID_GET_MAC_STATUS, bowCmdGetMacStatus}, ++ {BOW_CMD_ID_SETUP_CONNECTION, bowCmdSetupConnection}, ++ {BOW_CMD_ID_DESTROY_CONNECTION, bowCmdDestroyConnection}, ++ {BOW_CMD_ID_SET_PTK, bowCmdSetPTK}, ++ {BOW_CMD_ID_READ_RSSI, bowCmdReadRSSI}, ++ {BOW_CMD_ID_READ_LINK_QUALITY, bowCmdReadLinkQuality}, ++ {BOW_CMD_ID_SHORT_RANGE_MODE, bowCmdShortRangeMode}, ++ {BOW_CMD_ID_GET_CHANNEL_LIST, bowCmdGetChannelList}, ++}; ++ ++/****************************************************************************** ++* M A C R O S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N S ++******************************************************************************* ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command packet generation utility ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucCID Command ID ++* \param[in] fgSetQuery Set or Query ++* \param[in] fgNeedResp Need for response ++* \param[in] pfCmdDoneHandler Function pointer when command is done ++* \param[in] u4SetQueryInfoLen The length of the set/query buffer ++* \param[in] pucInfoBuffer Pointer to set/query buffer ++* ++* ++* \retval WLAN_STATUS_PENDING ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucCID, ++ IN BOOLEAN fgSetQuery, ++ IN BOOLEAN fgNeedResp, ++ IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ IN UINT_32 u4SetQueryInfoLen, IN PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); ++ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_BOW_INDEX; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); ++ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; ++ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = ucCID; ++ prCmdInfo->fgSetQuery = fgSetQuery; ++ prCmdInfo->fgNeedResp = fgNeedResp; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; ++ prCmdInfo->pvInformationBuffer = NULL; ++ prCmdInfo->u4InformationBufferLength = 0; ++ prCmdInfo->u4PrivateData = (UINT_32) ucSeqNumber; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) ++ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dispatch command coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ WLAN_STATUS retval = WLAN_STATUS_FAILURE; ++ UINT_16 i; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < sizeof(arBowCmdTable) / sizeof(BOW_CMD_T); i++) { ++ if ((arBowCmdTable[i].uCmdID == prCmd->rHeader.ucCommandId) && arBowCmdTable[i].pfCmdHandle) { ++ retval = arBowCmdTable[i].pfCmdHandle(prAdapter, prCmd); ++ break; ++ } ++ } ++ ++ return retval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_GET_MAC_STATUS ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_MAC_STATUS prMacStatus; ++ UINT_8 idx = 0; ++ UINT_8 ucPrimaryChannel; ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eBssSCO; ++ UINT_8 ucNumOfChannel = 0; /* MAX_BOW_NUMBER_OF_CHANNEL; */ ++ ++ RF_CHANNEL_INFO_T aucChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; ++ ++ ASSERT(prAdapter); ++ ++ /* 3 <1> If LinkCount != 0 -> OK (optional) */ ++ ++ eBand = BAND_2G4; ++ eBssSCO = CHNL_EXT_SCN; ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return WLAN_STATUS_FAILURE; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_MAC_STATUS; ++ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_MAC_STATUS); ++ ++ /* fill event body */ ++ prMacStatus = (P_BOW_MAC_STATUS) (prEvent->aucPayload); ++ kalMemZero(prMacStatus, sizeof(BOW_MAC_STATUS)); ++ ++ /* 3 <2> Call CNM to decide if BOW available. */ ++ if (cnmBowIsPermitted(prAdapter)) ++ prMacStatus->ucAvailability = TRUE; ++ else ++ prMacStatus->ucAvailability = FALSE; ++ ++ memcpy(prMacStatus->aucMacAddr, prAdapter->rWifiVar.aucDeviceAddress, PARAM_MAC_ADDR_LEN); ++ ++ if (cnmPreferredChannel(prAdapter, &eBand, &ucPrimaryChannel, &eBssSCO)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "bowCmdGetMacStatus, Get preferred channel.\n"); ++#endif ++ ++ prMacStatus->ucNumOfChannel = 1; ++ prMacStatus->arChannelList[0].ucChannelBand = eBand; ++ prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel; ++ } else { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, ++ "bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel); ++#endif ++ ++ rlmDomainGetChnlList(prAdapter, BAND_2G4, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_2G4, ++ &ucNumOfChannel, aucChannelList); ++ ++ if (ucNumOfChannel > 0) { ++ for (idx = 0; idx < ucNumOfChannel; idx++) { ++ prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand; ++ prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum; ++ } ++ ++ prMacStatus->ucNumOfChannel = ucNumOfChannel; ++ } ++ ++ rlmDomainGetChnlList(prAdapter, BAND_5G, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_5G, ++ &ucNumOfChannel, aucChannelList); ++ ++ if (ucNumOfChannel > 0) { ++ for (idx = 0; idx < ucNumOfChannel; idx++) { ++ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelBand = ++ aucChannelList[idx].eBand; ++ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelNum = ++ aucChannelList[idx].ucChannelNum; ++ } ++ ++ prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel; ++ ++ } ++ } ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, ++ "ucNumOfChannel,eBand,aucChannelList,%x,%x,%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ ucNumOfChannel, aucChannelList[0].eBand, aucChannelList[0].ucChannelNum, aucChannelList[1].ucChannelNum, ++ aucChannelList[2].ucChannelNum, aucChannelList[3].ucChannelNum, aucChannelList[4].ucChannelNum, ++ aucChannelList[5].ucChannelNum, aucChannelList[6].ucChannelNum, aucChannelList[7].ucChannelNum, ++ aucChannelList[8].ucChannelNum, aucChannelList[9].ucChannelNum, aucChannelList[10].ucChannelNum, ++ aucChannelList[11].ucChannelNum, aucChannelList[12].ucChannelNum, aucChannelList[13].ucChannelNum, ++ aucChannelList[14].ucChannelNum, aucChannelList[15].ucChannelNum, aucChannelList[16].ucChannelNum, ++ aucChannelList[17].ucChannelNum)); ++ ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->ucNumOfChannel, eBand, %x, %x.\n", ++ prMacStatus->ucNumOfChannel, prMacStatus->arChannelList[0].ucChannelBand); ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->arChannelList, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ prMacStatus->arChannelList[0].ucChannelNum, prMacStatus->arChannelList[1].ucChannelNum, ++ prMacStatus->arChannelList[2].ucChannelNum, prMacStatus->arChannelList[3].ucChannelNum, ++ prMacStatus->arChannelList[4].ucChannelNum, prMacStatus->arChannelList[5].ucChannelNum, ++ prMacStatus->arChannelList[6].ucChannelNum, prMacStatus->arChannelList[7].ucChannelNum, ++ prMacStatus->arChannelList[8].ucChannelNum, prMacStatus->arChannelList[9].ucChannelNum, ++ prMacStatus->arChannelList[10].ucChannelNum, prMacStatus->arChannelList[11].ucChannelNum, ++ prMacStatus->arChannelList[12].ucChannelNum, prMacStatus->arChannelList[13].ucChannelNum, ++ prMacStatus->arChannelList[14].ucChannelNum, prMacStatus->arChannelList[15].ucChannelNum, ++ prMacStatus->arChannelList[16].ucChannelNum, prMacStatus->arChannelList[17].ucChannelNum)); ++ ++ DBGLOG(BOW, TRACE, "prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel); ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand); ++ DBGLOG(BOW, TRACE, ++ "prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum); ++ DBGLOG(BOW, TRACE, "prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability); ++ DBGLOG(BOW, TRACE, "prMacStatus->aucMacAddr, %x:%x:%x:%x:%x:%x.\n", ++ prMacStatus->aucMacAddr[0], ++ prMacStatus->aucMacAddr[1], ++ prMacStatus->aucMacAddr[2], ++ prMacStatus->aucMacAddr[3], prMacStatus->aucMacAddr[4], prMacStatus->aucMacAddr[5])); ++#endif ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS))); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_SETUP_CONNECTION ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_SETUP_CONNECTION prBowSetupConnection; ++ CMD_BT_OVER_WIFI rCmdBtOverWifi; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ BOW_TABLE_T rBowTable; ++ ++ UINT_8 ucBowTableIdx = 0; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBowSetupConnection = (P_BOW_SETUP_CONNECTION) &(prCmd->aucPayload[0]); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SETUP_CONNECTION)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ /* 3 <1> If ucLinkCount >= 4 -> Fail. */ ++ if (g_u4LinkCount >= CFG_BOW_PHYSICAL_LINK_NUM) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* 3 <2> Call CNM, check if BOW is available. */ ++ if (!cnmBowIsPermitted(prAdapter)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* 3 <3> Lookup BOW Table, if Peer MAC address exist and valid -> Fail. */ ++ if (bowCheckBowTableIfVaild(prAdapter, prBowSetupConnection->aucPeerAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (EQUAL_MAC_ADDR(prBowSetupConnection->aucPeerAddress, prAdapter->rWifiVar.aucDeviceAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* fill CMD_BT_OVER_WIFI */ ++ rCmdBtOverWifi.ucAction = BOW_SETUP_CMD; ++ rCmdBtOverWifi.ucChannelNum = prBowSetupConnection->ucChannelNum; ++ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowSetupConnection->aucPeerAddress); ++ rCmdBtOverWifi.u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; ++ rCmdBtOverWifi.ucTimeoutDiscovery = prBowSetupConnection->ucTimeoutDiscovery; ++ rCmdBtOverWifi.ucTimeoutInactivity = prBowSetupConnection->ucTimeoutInactivity; ++ rCmdBtOverWifi.ucRole = prBowSetupConnection->ucRole; ++ rCmdBtOverWifi.PAL_Capabilities = prBowSetupConnection->ucPAL_Capabilities; ++ rCmdBtOverWifi.cMaxTxPower = prBowSetupConnection->cMaxTxPower; ++ ++ if (prBowSetupConnection->ucChannelNum > 14) ++ rCmdBtOverWifi.ucChannelBand = BAND_5G; ++ else ++ rCmdBtOverWifi.ucChannelBand = BAND_2G4; ++ ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowSetupConnection->aucPeerAddress); ++ ++#if CFG_BOW_PHYSICAL_LINK_NUM > 1 ++ /*Channel check for supporting multiple physical link */ ++ if (g_u4LinkCount > 0) { ++ if (prBowSetupConnection->ucChannelNum != prBowFsmInfo->ucPrimaryChannel) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ } ++#endif ++ ++ prBowFsmInfo->ucPrimaryChannel = prBowSetupConnection->ucChannelNum; ++ prBowFsmInfo->eBand = rCmdBtOverWifi.ucChannelBand; ++ prBowFsmInfo->u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; ++ prBowFsmInfo->ucRole = prBowSetupConnection->ucRole; ++ ++ if (prBowSetupConnection->ucPAL_Capabilities > 0) ++ prBowFsmInfo->fgSupportQoS = TRUE; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdSetupConnection.\n"); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Peer address - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], ++ rCmdBtOverWifi.rPeerAddr[1], ++ rCmdBtOverWifi.rPeerAddr[2], ++ rCmdBtOverWifi.rPeerAddr[3], rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities); ++ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower); ++#endif ++ ++ /* 3 <4> Get a free BOW entry, mark as Valid, fill in Peer MAC address, LinkCount += 1, state == Starting. */ ++ if (!bowGetBowTableFreeEntry(prAdapter, &ucBowTableIdx)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ prBowFsmInfo->prTargetBssDesc = NULL; ++ ++ kalMemZero(&rBowTable, sizeof(BOW_TABLE_T)); ++ ++ COPY_MAC_ADDR(rBowTable.aucPeerAddress, prBowSetupConnection->aucPeerAddress); ++ /* owTable.eState = BOW_DEVICE_STATE_ACQUIRING_CHANNEL; */ ++ rBowTable.fgIsValid = TRUE; ++ rBowTable.ucAcquireID = prBowFsmInfo->ucSeqNumOfChReq; ++ /* rBowTable.ucRole = prBowSetupConnection->ucRole; */ ++ /* rBowTable.ucChannelNum = prBowSetupConnection->ucChannelNum; */ ++ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); ++ ++ kalSetBowRole(prAdapter->prGlueInfo, rCmdBtOverWifi.ucRole, prBowSetupConnection->aucPeerAddress); ++ ++ GLUE_INC_REF_CNT(g_u4LinkCount); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ if (g_u4LinkCount == 1) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStarting, cnmTimerInitTimer.\n"); ++ DBGLOG(BOW, EVENT, "prBowFsmInfo->u2BeaconInterval, %d.\n", prBowFsmInfo->u2BeaconInterval); ++#endif ++ cnmTimerInitTimer(prAdapter, ++ &prBowFsmInfo->rStartingBeaconTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) bowSendBeacon, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prBowFsmInfo->rChGrantedTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) bowChGrantedTimeout, (ULONG) NULL); ++ ++ /* Reset Global Variable */ ++ g_u4Beaconing = 0; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdSetupConnection, g_u4LinkCount, %x.\n", g_u4LinkCount); ++ DBGLOG(BOW, EVENT, "kalInitBowDevice, bow0\n"); ++#endif ++#if CFG_BOW_SEPARATE_DATA_PATH ++ kalInitBowDevice(prAdapter->prGlueInfo, BOWDEVNAME); ++#endif ++ ++ /*Active BoW Network */ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ } ++ ++ if (rCmdBtOverWifi.ucRole == BOW_INITIATOR) { ++ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, ++ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); ++ bowRequestCh(prAdapter); ++ } else { ++ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); ++ bowResponderScan(prAdapter); ++ } ++ ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_DESTROY_CONNECTION ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_DESTROY_CONNECTION prBowDestroyConnection; ++ CMD_BT_OVER_WIFI rCmdBtOverWifi; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++#if CFG_BOW_TEST ++ UINT_8 ucIdx; ++#endif ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /* 3 <1> If LinkCount == 0 ->Fail (Optional) */ ++ if (g_u4LinkCount == 0) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_DESTROY_CONNECTION)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ /* 3 <2> Lookup BOW table, check if is not exist (Valid and Peer MAC address) -> Fail */ ++ prBowDestroyConnection = (P_BOW_DESTROY_CONNECTION) &(prCmd->aucPayload[0]); ++ ++ if (!bowCheckBowTableIfVaild(prAdapter, prBowDestroyConnection->aucPeerAddress)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdDestroyConnection, bowCheckIfVaild, not accepted.\n"); ++#endif ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowCmdDestroyConnection, destroy Peer address - %x:%x:%x:%x:%x:%x.\n", ++ prBowDestroyConnection->aucPeerAddress[0], prBowDestroyConnection->aucPeerAddress[1], ++ prBowDestroyConnection->aucPeerAddress[2], prBowDestroyConnection->aucPeerAddress[3], ++ prBowDestroyConnection->aucPeerAddress[4], prBowDestroyConnection->aucPeerAddress[5])); ++#endif ++ ++ /* fill CMD_BT_OVER_WIFI */ ++ rCmdBtOverWifi.ucAction = 2; ++ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowDestroyConnection->aucPeerAddress); ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowDestroyConnection->aucPeerAddress); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowCmdDestroyConnection, rCmdBtOverWifi.rPeerAddr - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], ++ rCmdBtOverWifi.rPeerAddr[1], rCmdBtOverWifi.rPeerAddr[2], rCmdBtOverWifi.rPeerAddr[3], ++ rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); ++#endif ++ ++#if CFG_BOW_TEST ++ for (ucIdx = 0; ucIdx < 11; ucIdx++) { ++ DBGLOG(BOW, EVENT, ++ "BoW receiving PAL packet delta time vs packet number -- %d ms vs %x.\n", ucIdx, ++ g_arBowRevPalPacketTime[ucIdx]); ++ } ++#endif ++ ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, ++ sizeof(CMD_BT_OVER_WIFI), ++ (PUINT_8)&rCmdBtOverWifi, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_SET_PTK ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_SET_PTK prBowSetPTK; ++ CMD_802_11_KEY rCmdKey; ++ ++ ASSERT(prAdapter); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SET_PTK)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prBowSetPTK = (P_BOW_SET_PTK) &(prCmd->aucPayload[0]); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prBowSetPTK->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowSetPTK->aucPeerAddress[0], ++ prBowSetPTK->aucPeerAddress[1], ++ prBowSetPTK->aucPeerAddress[2], ++ prBowSetPTK->aucPeerAddress[3], ++ prBowSetPTK->aucPeerAddress[4], prBowSetPTK->aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "rCmdKey.ucIsAuthenticator, %x.\n", kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress)); ++#endif ++ ++ if (!bowCheckBowTableIfVaild(prAdapter, prBowSetPTK->aucPeerAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (bowGetBowTableState(prAdapter, prBowSetPTK->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); ++ ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ /* fill CMD_802_11_KEY */ ++ rCmdKey.ucAddRemove = 1; /* add */ ++ rCmdKey.ucTxKey = 1; ++ rCmdKey.ucKeyType = 1; ++ rCmdKey.ucIsAuthenticator = kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress); ++ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prBowSetPTK->aucPeerAddress); ++ rCmdKey.ucNetType = NETWORK_TYPE_BOW_INDEX; /* BT Over Wi-Fi */ ++ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ ++ rCmdKey.ucKeyId = 0; ++ rCmdKey.ucKeyLen = 16; /* AES = 128bit */ ++ kalMemCopy(rCmdKey.aucKeyMaterial, prBowSetPTK->aucTemporalKey, 16); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prBowSetPTK->aucTemporalKey, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ prBowSetPTK->aucTemporalKey[0], ++ prBowSetPTK->aucTemporalKey[1], ++ prBowSetPTK->aucTemporalKey[2], ++ prBowSetPTK->aucTemporalKey[3], ++ prBowSetPTK->aucTemporalKey[4], ++ prBowSetPTK->aucTemporalKey[5], ++ prBowSetPTK->aucTemporalKey[6], ++ prBowSetPTK->aucTemporalKey[7], ++ prBowSetPTK->aucTemporalKey[8], ++ prBowSetPTK->aucTemporalKey[9], ++ prBowSetPTK->aucTemporalKey[10], ++ prBowSetPTK->aucTemporalKey[11], ++ prBowSetPTK->aucTemporalKey[12], ++ prBowSetPTK->aucTemporalKey[13], ++ prBowSetPTK->aucTemporalKey[14], prBowSetPTK->aucTemporalKey[15])); ++ ++ DBGLOG(BOW, EVENT, "rCmdKey.aucKeyMaterial, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", ++ rCmdKey.aucKeyMaterial[0], ++ rCmdKey.aucKeyMaterial[1], ++ rCmdKey.aucKeyMaterial[2], ++ rCmdKey.aucKeyMaterial[3], ++ rCmdKey.aucKeyMaterial[4], ++ rCmdKey.aucKeyMaterial[5], ++ rCmdKey.aucKeyMaterial[6], ++ rCmdKey.aucKeyMaterial[7], ++ rCmdKey.aucKeyMaterial[8], ++ rCmdKey.aucKeyMaterial[9], ++ rCmdKey.aucKeyMaterial[10], ++ rCmdKey.aucKeyMaterial[11], ++ rCmdKey.aucKeyMaterial[12], ++ rCmdKey.aucKeyMaterial[13], rCmdKey.aucKeyMaterial[14], rCmdKey.aucKeyMaterial[15])); ++#endif ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_ADD_REMOVE_KEY, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventSetCommon, ++ wlanbowCmdTimeoutHandler, ++ sizeof(CMD_802_11_KEY), (PUINT_8)&rCmdKey, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_READ_RSSI ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_READ_RSSI prBowReadRSSI; ++ ++ ASSERT(prAdapter); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_READ_RSSI)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prBowReadRSSI = (P_BOW_READ_RSSI) &(prCmd->aucPayload[0]); ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ wlanbowCmdEventReadRssi, ++ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_READ_LINK_QUALITY ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_READ_LINK_QUALITY prBowReadLinkQuality; ++ ++ ASSERT(prAdapter); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(P_BOW_READ_LINK_QUALITY)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prBowReadLinkQuality = (P_BOW_READ_LINK_QUALITY) &(prCmd->aucPayload[0]); ++ ++ return wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ wlanbowCmdEventReadLinkQuality, ++ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_SHORT_RANGE_MODE ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ P_BOW_SHORT_RANGE_MODE prBowShortRangeMode; ++ CMD_TX_PWR_T rTxPwrParam; ++ ++ ASSERT(prAdapter); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode.\n"); ++#endif ++ ++ prBowShortRangeMode = (P_BOW_SHORT_RANGE_MODE) &(prCmd->aucPayload[0]); ++ ++ /* parameter size check */ ++ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SHORT_RANGE_MODE)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (!bowCheckBowTableIfVaild(prAdapter, prBowShortRangeMode->aucPeerAddress)) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (bowGetBowTableState(prAdapter, prBowShortRangeMode->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prBowShortRangeMode->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowShortRangeMode->aucPeerAddress[0], ++ prBowShortRangeMode->aucPeerAddress[1], ++ prBowShortRangeMode->aucPeerAddress[2], ++ prBowShortRangeMode->aucPeerAddress[3], ++ prBowShortRangeMode->aucPeerAddress[4], prBowShortRangeMode->aucPeerAddress[5])); ++#endif ++ ++ rTxPwrParam.cTxPwr2G4Cck = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4OFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4OFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4OFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4OFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4OFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4HT20_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr2G4HT40_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr2G4HT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr5GOFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GOFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); ++ ++ rTxPwrParam.cTxPwr5GHT20_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_BPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_QPSK = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_16QAM = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); ++ rTxPwrParam.cTxPwr5GHT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); ++ ++ if (nicUpdateTxPower(prAdapter, &rTxPwrParam) == WLAN_STATUS_SUCCESS) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode, %x.\n", WLAN_STATUS_SUCCESS); ++#endif ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); ++ return WLAN_STATUS_SUCCESS; ++ } ++ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is command handler for BOW_CMD_ID_GET_CHANNEL_LIST ++* coming from 802.11 PAL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmd Pointer to the buffer that holds the command ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) ++{ ++ ASSERT(prAdapter); ++ ++ /* not supported yet */ ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is generic command done handler ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ ++ ASSERT(prAdapter); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ ++ prBowCmdStatus->ucStatus = ucEventBuf; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is generic command done handler ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ ++ ASSERT(prAdapter); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ ++ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_LINK_CONNECTED prBowLinkConnected; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); ++ ++ /* fill event body */ ++ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prEvent->aucPayload); ++ kalMemZero(prBowLinkConnected, sizeof(BOW_LINK_CONNECTED)); ++ prBowLinkConnected->rChannel.ucChannelNum = prBssInfo->ucPrimaryChannel; ++ prBowLinkConnected->rChannel.ucChannelBand = prBssInfo->eBand; ++ COPY_MAC_ADDR(prBowLinkConnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); ++ DBGLOG(BOW, EVENT, ++ "prBowLinkConnected->rChannel.ucChannelNum, 0x%x\n", prBowLinkConnected->rChannel.ucChannelNum); ++ DBGLOG(BOW, EVENT, ++ "prBowLinkConnected->rChannel.ucChannelBand, 0x%x\n", prBowLinkConnected->rChannel.ucChannelBand); ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkConnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkConnected, prBowLinkConnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowLinkConnected->aucPeerAddress[0], prBowLinkConnected->aucPeerAddress[1], ++ prBowLinkConnected->aucPeerAddress[2], prBowLinkConnected->aucPeerAddress[3], ++ prBowLinkConnected->aucPeerAddress[4], prBowLinkConnected->aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkConnected, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ /*Indicate Event to PAL */ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED))); ++ ++ /*Release channel if granted */ ++ if (prBowFsmInfo->fgIsChannelGranted) { ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); ++ /* bowReleaseCh(prAdapter); */ ++ /*Requested, not granted yet */ ++ } else if (prBowFsmInfo->fgIsChannelRequested) { ++ prBowFsmInfo->fgIsChannelRequested = FALSE; ++ } ++ ++ /* set to connected status */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTED); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ BOW_TABLE_T rBowTable; ++ UINT_8 ucBowTableIdx; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ BOOLEAN fgSendDeauth = FALSE; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { ++ /*do nothing */ ++ return; ++ } ++ /*Cancel scan */ ++ else if (eFsmState == BOW_DEVICE_STATE_SCANNING && !(prBowFsmInfo->fgIsChannelRequested)) { ++ bowResponderCancelScan(prAdapter, FALSE); ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_DISCONNECTING); ++ return; ++ } ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; ++ if ((prCmdInfo->u4PrivateData)) ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ else ++ prEvent->rHeader.ucSeqNumber = 0; ++ ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); ++ ++ /* fill event body */ ++ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prEvent->aucPayload); ++ kalMemZero(prBowLinkDisconnected, sizeof(BOW_LINK_DISCONNECTED)); ++ prBowLinkDisconnected->ucReason = 0x0; ++ COPY_MAC_ADDR(prBowLinkDisconnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); ++ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); ++ ++ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkDisconnected, prBowLinkDisconnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowLinkDisconnected->aucPeerAddress[0], prBowLinkDisconnected->aucPeerAddress[1], ++ prBowLinkDisconnected->aucPeerAddress[2], prBowLinkDisconnected->aucPeerAddress[3], ++ prBowLinkDisconnected->aucPeerAddress[4], prBowLinkDisconnected->aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ /*Indicate BoW event to PAL */ ++#if 0 ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); ++#endif ++ ++ /* set to disconnected status */ ++ prBowFsmInfo->prTargetStaRec = ++ cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_BOW_INDEX, prBowLinkDisconnected->aucPeerAddress); ++ if (!(prBowFsmInfo->prTargetStaRec)) { ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); ++ ASSERT(FALSE); ++ return; ++ } ++ ++ /*Release channel if granted */ ++ if (prBowFsmInfo->fgIsChannelGranted) { ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); ++ bowReleaseCh(prAdapter); ++ /*Requested, not granted yet */ ++ } else if (prBowFsmInfo->fgIsChannelRequested) { ++ prBowFsmInfo->fgIsChannelRequested = FALSE; ++ /* bowReleaseCh(prAdapter); */ ++ } ++#if 1 ++ /*Send Deauth to connected peer */ ++ if (eFsmState == BOW_DEVICE_STATE_CONNECTED && (prBowFsmInfo->prTargetStaRec->ucStaState == STA_STATE_3)) { ++ fgSendDeauth = TRUE; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "wlanbowCmdEventLinkDisconnected, bowGetBowTableState, %x.\n", ++ bowGetBowTableState(prAdapter, prBowLinkDisconnected->aucPeerAddress)); ++#endif ++ authSendDeauthFrame(prAdapter, ++ prBowFsmInfo->prTargetStaRec, ++ (P_SW_RFB_T) NULL, ++ REASON_CODE_DEAUTH_LEAVING_BSS, (PFN_TX_DONE_HANDLER) bowDisconnectLink); ++ } ++#endif ++ ++#if 0 ++ /* 3 <3>Stop this link; flush Tx; ++ * send deAuthentication -> abort. SAA, AAA. need to check BOW table state == Connected. ++ */ ++ if (prAdapter->prGlueInfo->i4TxPendingFrameNum > 0) ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* flush pending security frames */ ++ if (prAdapter->prGlueInfo->i4TxPendingSecurityFrameNum > 0) ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++#endif ++ ++ /*Update BoW table */ ++ bowGetBowTableEntryByPeerAddress(prAdapter, prBowLinkDisconnected->aucPeerAddress, &ucBowTableIdx); ++ rBowTable.fgIsValid = FALSE; ++ rBowTable.eState = BOW_DEVICE_STATE_DISCONNECTED; ++ kalMemZero(rBowTable.aucPeerAddress, sizeof(rBowTable.aucPeerAddress)); ++ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); ++ ++ /*Indicate BoW event to PAL */ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); ++ ++ /*Decrease link count */ ++ GLUE_DEC_REF_CNT(g_u4LinkCount); ++ ++ /*If no need to send deauth, DO disconnect now */ ++ /*If need to send deauth, DO disconnect at deauth Tx done */ ++ if (!fgSendDeauth) ++ bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_BT_OVER_WIFI prCmdBtOverWifi; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /* restore original command for rPeerAddr */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prCmdBtOverWifi = (P_CMD_BT_OVER_WIFI) (prWifiCmd->aucBuffer); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; ++ ++ /*Indicate BoW event to PAL */ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++ ++ /* set to starting status */ ++ kalSetBowState(prAdapter->prGlueInfo, BOW_DEVICE_STATE_STARTING, prCmdBtOverWifi->rPeerAddr); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is the command done handler for BOW_CMD_ID_READ_LINK_QUALITY ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_AMPC_EVENT prEvent; ++ P_BOW_LINK_QUALITY prBowLinkQuality; ++ ++ ASSERT(prAdapter); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_QUALITY; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_QUALITY); ++ ++ /* fill event body */ ++ prBowLinkQuality = (P_BOW_LINK_QUALITY) (prEvent->aucPayload); ++ kalMemZero(prBowLinkQuality, sizeof(BOW_LINK_QUALITY)); ++ prBowLinkQuality->ucLinkQuality = (UINT_8) prLinkQuality->cLinkQuality; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is the command done handler for BOW_CMD_ID_READ_RSSI ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* \param[in] pucEventBuf Pointer to the set buffer OR event buffer ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_AMPC_EVENT prEvent; ++ P_BOW_RSSI prBowRssi; ++ ++ ASSERT(prAdapter); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_RSSI; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_RSSI); ++ ++ /* fill event body */ ++ prBowRssi = (P_BOW_RSSI) (prEvent->aucPayload); ++ kalMemZero(prBowRssi, sizeof(BOW_RSSI)); ++ prBowRssi->cRssi = (INT_8) prLinkQuality->cRssi; ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is the default command timeout handler ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] prCmdInfo Pointer to the buffer that holds the command info ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ P_AMPC_EVENT prEvent; ++ P_BOW_COMMAND_STATUS prBowCmdStatus; ++ ++ ASSERT(prAdapter); ++ ++ /* fill event header */ ++ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); ++ if (!prEvent) { ++ ASSERT(FALSE); ++ return; ++ } ++ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; ++ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; ++ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); ++ ++ /* fill event body */ ++ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); ++ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); ++ ++ prBowCmdStatus->ucStatus = BOWCMD_STATUS_TIMEOUT; /* timeout */ ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); ++ ++ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); ++ ++} ++ ++VOID bowStopping(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBowBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStoping.\n"); ++ DBGLOG(BOW, EVENT, "bowStoping, SSID %s.\n", prBowBssInfo->aucSSID); ++ DBGLOG(BOW, EVENT, "bowStoping, prBowBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", ++ prBowBssInfo->aucBSSID[0], ++ prBowBssInfo->aucBSSID[1], ++ prBowBssInfo->aucBSSID[2], ++ prBowBssInfo->aucBSSID[3], prBowBssInfo->aucBSSID[4], prBowBssInfo->aucBSSID[5])); ++ DBGLOG(BOW, EVENT, "bowStoping, prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", ++ prBowBssInfo->aucOwnMacAddr[0], ++ prBowBssInfo->aucOwnMacAddr[1], ++ prBowBssInfo->aucOwnMacAddr[2], ++ prBowBssInfo->aucOwnMacAddr[3], ++ prBowBssInfo->aucOwnMacAddr[4], prBowBssInfo->aucOwnMacAddr[5])); ++ DBGLOG(BOW, EVENT, "bowStoping, prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", ++ prAdapter->rWifiVar.aucDeviceAddress[0], ++ prAdapter->rWifiVar.aucDeviceAddress[1], ++ prAdapter->rWifiVar.aucDeviceAddress[2], ++ prAdapter->rWifiVar.aucDeviceAddress[3], ++ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); ++ DBGLOG(BOW, EVENT, "bowStopping, g_u4LinkCount, %x.\n", g_u4LinkCount); ++ DBGLOG(BOW, EVENT, "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ kalPrint("BoW Stoping,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); ++#endif ++ ++ if (g_u4LinkCount == 0) { ++ /*Stop beaconing */ ++ GLUE_DEC_REF_CNT(g_u4Beaconing); ++ ++ /*Deactive BoW network */ ++ /* prBowBssInfo->fgIsNetActive = FALSE; */ ++ /* prBowBssInfo->fgIsBeaconActivated = FALSE; */ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ /*temp solution for FW hal_pwr_mgt.c#3037 ASSERT */ ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ } ++ ++} ++ ++VOID bowStarting(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (g_u4LinkCount == 1) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "BoW Starting.\n"); ++ DBGLOG(BOW, EVENT, "BoW channel granted.\n"); ++#endif ++ ++#if 0 ++ /*Active BoW Network */ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#endif ++ ++ /* 3 <1> Update BSS_INFO_T per Network Basis */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBssInfo->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prBssInfo->eCurrentOPMode = OP_MODE_BOW; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress); ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); ++ prBssInfo->ucSSIDLen = BOW_SSID_LEN; ++ bowAssignSsid(prBssInfo->aucSSID, prBssInfo->aucOwnMacAddr); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "SSID %s.\n", prBssInfo->aucSSID); ++ DBGLOG(BOW, EVENT, "prBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", ++ prBssInfo->aucBSSID[0], ++ prBssInfo->aucBSSID[1], ++ prBssInfo->aucBSSID[2], ++ prBssInfo->aucBSSID[3], prBssInfo->aucBSSID[4], prBssInfo->aucBSSID[5])); ++ DBGLOG(BOW, EVENT, "prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", ++ prBssInfo->aucOwnMacAddr[0], ++ prBssInfo->aucOwnMacAddr[1], ++ prBssInfo->aucOwnMacAddr[2], ++ prBssInfo->aucOwnMacAddr[3], ++ prBssInfo->aucOwnMacAddr[4], prBssInfo->aucOwnMacAddr[5])); ++ DBGLOG(BOW, EVENT, "prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", ++ prAdapter->rWifiVar.aucDeviceAddress[0], ++ prAdapter->rWifiVar.aucDeviceAddress[1], ++ prAdapter->rWifiVar.aucDeviceAddress[2], ++ prAdapter->rWifiVar.aucDeviceAddress[3], ++ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); ++#endif ++ ++ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ ++ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prBssInfo->u2AssocId = 0; ++ ++ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ ++ prBssInfo->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; ++ if (prBowFsmInfo->eBand == BAND_2G4) ++ prBssInfo->eBand = BAND_2G4; ++ else ++ prBssInfo->eBand = BAND_5G; ++ ++#if CFG_BOW_SUPPORT_11N ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; ++ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prBssInfo->u2OperationalRateSet = ++ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); ++ ++#else ++ if (prBssInfo->eBand == BAND_2G4) { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; ++ ++ /* RATE_SET_ERP; */ ++ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; ++ prBssInfo->u2OperationalRateSet = RATE_SET_ERP; ++ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; ++ } else { ++ /* Depend on eBand */ ++ /* prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; */ ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ /* prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; */ ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; ++ ++ /* RATE_SET_ERP; */ ++ /* prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; */ ++ /* prBssInfo->u2OperationalRateSet = RATE_SET_ERP; */ ++ ++ /* RATE_SET_ERP; */ ++ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM; ++ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; ++ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; ++ } ++ ++#endif ++ prBssInfo->fgErpProtectMode = FALSE; ++ ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prBssInfo->u2BeaconInterval = prBowFsmInfo->u2BeaconInterval; ++ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; ++ prBssInfo->u2ATIMWindow = 0; ++ prBssInfo->ucBeaconTimeoutCount = 0; ++ if (prBowFsmInfo->fgSupportQoS) { ++ prAdapter->rWifiVar.fgSupportQoS = TRUE; ++ prBssInfo->fgIsQBSS = TRUE; ++ } ++ /* 3 <2> Update BSS_INFO_T common part */ ++#if CFG_SUPPORT_AAA ++ bssInitForAP(prAdapter, prBssInfo, TRUE); ++ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#endif /* CFG_SUPPORT_AAA */ ++ prBssInfo->fgIsNetActive = TRUE; ++ prBssInfo->fgIsBeaconActivated = TRUE; ++ ++ /* 3 <3> Set MAC HW */ ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BOW_BSS_INFO_INIT(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], ++ prBowFsmInfo->aucPeerAddress[5])); ++#endif ++ ++ /* 4 <3.1> use command packets to inform firmware */ ++ rlmBssInitForAPandIbss(prAdapter, prBssInfo); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /* 4 <3.2> Update AdHoc PM parameter */ ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /* 4 <3.1> Reset HW TSF Update Mode and Beacon Mode */ ++ ++ /* 4 <3.2> Setup BSSID */ ++ /* TODO: rxmSetRxFilterBSSID0 */ ++/* rxmSetRxFilterBSSID0(prBssInfo->ucHwBssidId, prBssInfo->aucBSSID); */ ++ ++ /* 4 <3.3> Setup RX Filter to accept Probe Request */ ++ /* TODO: f get/set RX filter. */ ++ ++#if 0 ++ { ++ UINT_32 u4RxFilter; ++ ++ if (halMacRxGetRxFilters(&u4RxFilter) == HAL_STATUS_SUCCESS) { ++ ++ u4RxFilter &= ~BIT(RXFILTER_DROP_PROBE_REQ); ++ ++ halMacRxSetRxFilters(u4RxFilter); ++ } ++ } ++#endif ++ } ++ ++ /*Update BoW Table */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_STARTING); ++ ++#if CFG_BOW_TEST ++ kalPrint("BoW Starting,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); ++ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); ++#endif ++ ++ /*Start beaconing */ ++ if (g_u4Beaconing < 1) { ++ GLUE_INC_REF_CNT(g_u4Beaconing); ++ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); ++ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); ++ } ++#if 0 ++ /*Responder: Start to scan Initiator */ ++ if (prBowFsmInfo->ucRole == BOW_RESPONDER) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowStarting responder, start scan result searching.\n"); ++#endif ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); ++ bowReleaseCh(prAdapter); ++ bowResponderScan(prAdapter); ++ } ++ /*Initiator: Request channel, wait for responder */ ++ else { ++ /* Todo:: Nothing*/ ++ /* bowRequestCh(prAdapter); */ ++ } ++#endif ++ ++} ++ ++VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 puOwnMacAddr) ++{ ++ UINT_8 i; ++ UINT_8 aucSSID[] = BOW_WILDCARD_SSID; ++ ++ kalMemCopy(pucSsid, aucSSID, BOW_WILDCARD_SSID_LEN); ++ ++ for (i = 0; i < 6; i++) { ++ pucSsid[(3 * i) + 3] = 0x2D; ++ if ((*(puOwnMacAddr + i) >> 4) < 0xA) ++ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x30; ++ else ++ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x57; ++ ++ if ((*(puOwnMacAddr + i) & 0x0F) < 0xA) ++ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x30; ++ else ++ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x57; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ BOOLEAN fgReplyProbeResp = FALSE; ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu4ControlFlags); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++#if 0 /* CFG_BOW_TEST */ ++ DBGLOG(BOW, EVENT, "bowValidateProbeReq.\n"); ++#endif ++ ++ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_SSID == IE_ID(pucIE)) { ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_SSID == IE_ID(pucIE)) { ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* 4 <2> Check network conditions */ ++ /*If BoW AP is beaconing */ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW && g_u4Beaconing > 0) { ++ ++ /*Check the probe requset sender is our peer */ ++ if (bowCheckBowTableIfVaild(prAdapter, prMgtHdr->aucSrcAddr)) ++ fgReplyProbeResp = TRUE; ++ /*Check the probe request target SSID is our SSID */ ++ else if ((prIeSsid) && ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength)) ++ fgReplyProbeResp = TRUE; ++ else ++ fgReplyProbeResp = FALSE; ++ } ++ ++ return fgReplyProbeResp; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if ((g_u4Beaconing != 0) && (g_u4LinkCount > 0) && (g_u4LinkCount < CFG_BOW_PHYSICAL_LINK_NUM)) { ++ /* Send beacon */ ++ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); ++ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); ++ } ++#if CFG_BOW_TEST ++ else ++ kalPrint("BoW Send Beacon,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderScan(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_SCN_SCAN_REQ prScanReqMsg; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowResponderScan.\n"); ++ kalPrint("BOW SCAN [REQ:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq + 1); ++#endif ++ ++ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); ++ ++ if (!prScanReqMsg) { ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ return; ++ } ++ ++ /*Fill scan message */ ++ prScanReqMsg->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_REQ; ++ prScanReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfScanReq; ++ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_BOW_INDEX; ++ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ prScanReqMsg->ucSSIDLength = BOW_SSID_LEN; ++ bowAssignSsid(prScanReqMsg->aucSSID, prBowFsmInfo->aucPeerAddress); ++ prScanReqMsg->ucChannelListNum = 1; ++ ++ if (prBowFsmInfo->eBand == BAND_2G4) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; ++ prScanReqMsg->arChnlInfoList[0].eBand = BAND_2G4; ++ } else { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; ++ prScanReqMsg->arChnlInfoList[0].eBand = BAND_5G; ++ } ++ ++ prScanReqMsg->arChnlInfoList[0].ucChannelNum = prBowFsmInfo->ucPrimaryChannel; ++ prScanReqMsg->u2IELen = 0; ++ ++ /*Send scan message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); ++ ++ /*Change state to SCANNING */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); ++ ++ /* prBowFsmInfo->fgTryScan = FALSE; */ /* Will enable background sleep for infrastructure */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_DESC_T prBssDesc; ++ UINT_8 ucSeqNumOfCompMsg; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ENUM_SCAN_STATUS eScanStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ ASSERT(prScanDoneMsg->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX); ++ ++ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; ++ eScanStatus = prScanDoneMsg->eScanStatus; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowResponderScanDone.\n"); ++ kalPrint("BOW SCAN [DONE:%d]\n", ucSeqNumOfCompMsg); ++#endif ++ ++ if (eScanStatus == SCAN_STATUS_CANCELLED) { ++#if CFG_BOW_TEST ++ kalPrint("BOW SCAN [CANCELLED:%d]\n", ucSeqNumOfCompMsg); ++#endif ++ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTING) { ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ } ++ return; ++ } else if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { ++ /* bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); */ ++ return; ++ } else if (ucSeqNumOfCompMsg != prBowFsmInfo->ucSeqNumOfScanReq) { ++ DBGLOG(BOW, EVENT, "Sequence no. of BOW Responder scan done is not matched.\n"); ++ return; ++ } ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prBowFsmInfo->aucPeerAddress); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "End scan result searching.\n"); ++#endif ++ ++ /* Initiator is FOUND */ ++ if (prBssDesc != NULL) { ++ /* (prBssDesc->aucBSSID != NULL)) */ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Search Bow Peer address - %x:%x:%x:%x:%x:%x.\n", prBssDesc->aucBSSID[0], ++ prBssDesc->aucBSSID[1], ++ prBssDesc->aucBSSID[2], ++ prBssDesc->aucBSSID[3], prBssDesc->aucBSSID[4], prBssDesc->aucBSSID[5]); ++ DBGLOG(BOW, EVENT, "Starting to join initiator.\n"); ++#endif ++ /*Set target BssDesc */ ++ prBowFsmInfo->prTargetBssDesc = prBssDesc; ++ /*Request channel to do JOIN */ ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, ++ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); ++ bowRequestCh(prAdapter); ++ } ++ /*Initiator is NOT FOUND */ ++ else { ++ /*Scan again, until PAL timeout */ ++ bowResponderScan(prAdapter); ++#if 0 ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++#endif ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Function for cancelling scan request. There is another option to extend channel privilige ++* for another purpose. ++* ++* @param fgIsChannelExtention - Keep the channel previlege, but can cancel scan timer. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention) ++{ ++ ++ P_MSG_SCN_SCAN_CANCEL prScanCancel = (P_MSG_SCN_SCAN_CANCEL) NULL; ++ P_BOW_FSM_INFO_T prBowFsmInfo = (P_BOW_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("bowResponderCancelScan()"); ++ ++ do { ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (TRUE) { ++#if CFG_BOW_TEST ++ kalPrint("BOW SCAN [CANCEL:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq); ++#endif ++ /* There is a channel privilege on hand. */ ++ ++ DBGLOG(P2P, TRACE, "BOW Cancel Scan\n"); ++ ++ prScanCancel = ++ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancel) { ++ /* Buffer not enough, can not cancel scan request. */ ++ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prScanCancel->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_CANCEL; ++ prScanCancel->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prScanCancel->ucSeqNum = prBowFsmInfo->ucSeqNumOfScanReq; ++#if CFG_ENABLE_WIFI_DIRECT ++ prScanCancel->fgIsChannelExt = fgIsChannelExtention; ++#endif ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancel, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ } while (FALSE); ++ ++} /* bowResponderCancelScan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialization of JOIN STATE ++* ++* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_MSG_JOIN_REQ_T prJoinReqMsg; ++ ++ ASSERT(prBssDesc); ++ ASSERT(prAdapter); ++ ++ DBGLOG(BOW, EVENT, "Starting bowResponderJoin.\n"); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> We are going to connect to this BSS. */ ++ prBssDesc->fgIsConnecting = TRUE; ++ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTING); ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ /*Support First JOIN and retry */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_BOW_AP, NETWORK_TYPE_BOW_INDEX, prBssDesc); ++ if (!prStaRec) ++ return; ++ ++ prBowFsmInfo->prTargetStaRec = prStaRec; ++ ++ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ ++ prStaRec->fgIsReAssoc = FALSE; ++ prBowFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; ++ ++ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ ++ if (prBowFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { ++ ++ DBGLOG(BOW, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); ++ prBowFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else { ++ ASSERT(0); ++ } ++ ++ /* 4 <4.1> sync. to firmware domain */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy */ ++ if (prBssDesc->ucSSIDLen) { ++ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prBssDesc->aucSSID); ++ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prConnSettings->aucSSID); ++#endif ++ } ++ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ return; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_BOW_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ prBssInfo->prStaRecOfAP = prStaRec; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "prStaRec->eStaType, %x.\n", prStaRec->eStaType); ++ DBGLOG(BOW, INFO, "BoW trigger SAA [%pM]\n", prStaRec->aucMacAddr); ++#endif ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Join Complete Event from SAA FSM for BOW FSM ++* ++* @param[in] prMsgHdr Message of Join Complete of SAA FSM. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_JOIN_COMP_T prJoinCompMsg; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prAssocRspSwRfb; ++ P_BSS_INFO_T prBssInfo; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; ++ prStaRec = prJoinCompMsg->prStaRec; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete.\n"); ++ DBGLOG(BOW, EVENT, "bowfsmRunEventJoinComplete ptr check\n"); ++ DBGLOG(BOW, EVENT, "prMsgHdr %x\n", prMsgHdr); ++ DBGLOG(BOW, EVENT, "prAdapter %x\n", prAdapter); ++ DBGLOG(BOW, EVENT, "prBowFsmInfo %x\n", prBowFsmInfo); ++ DBGLOG(BOW, EVENT, "prStaRec %x\n", prStaRec); ++#endif ++ ++ ASSERT(prStaRec); ++ ASSERT(prBowFsmInfo); ++ ++ /* Check SEQ NUM */ ++ if (prJoinCompMsg->ucSeqNum == prBowFsmInfo->ucSeqNumOfReqMsg) { ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); ++ ++ /* 4 <1> JOIN was successful */ ++ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { ++ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - ++ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - ++ WLAN_MAC_MGMT_HEADER_LEN)); ++ pucIE = prAssocRspFrame->aucInfoElem; ++ ++ prStaRec->eStaType = STA_TYPE_BOW_AP; ++ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; ++#if CFG_BOW_RATE_LIMITATION ++ /* 4 <1.2>Update Rate Set */ ++ /*Limit Rate Set to 24M, 48M, 54M */ ++ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); ++ /*If peer cannot support the above rate set, fix on the available highest rate */ ++ if (prStaRec->u2DesiredNonHTRateSet == 0) { ++ UINT_8 ucHighestRateIndex; ++ ++ if (rateGetHighestRateIndexFromRateSet ++ (prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) { ++ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); ++ } ++ } ++#endif ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ /* 4 <1.2> Update HT information and set channel */ ++ /* Record HT related parameters in rStaRec and rBssInfo ++ * Note: it shall be called before nicUpdateBss() ++ */ ++#if CFG_BOW_SUPPORT_11N ++ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++#endif ++ ++ /* 4 <1.3> Update BSS_INFO_T */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Finish bowUpdateBssInfoForJOIN.\n"); ++#endif ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowFsmRunEventJoinComplete, qmActivateStaRec.\n"); ++#endif ++ ++ /* 4 <1.7> Set the Next State of BOW FSM */ ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ } ++ /* 4 <2> JOIN was not successful */ ++ else { ++ /*Retry */ ++ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); ++#if 0 ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++#endif ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete -- Join failed.\n"); ++ DBGLOG(BOW, INFO, "BoW trigger SAA REJOIN\n"); ++#endif ++ } ++ } ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Media State to HOST ++* ++* @param[in] eConnectionState Current Media State ++* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN BOOLEAN fgDelayIndication) ++{ ++ EVENT_CONNECTION_STATUS rEventConnStatus; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prBssInfo; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /* NOTE(Kevin): Move following line to bowChangeMediaState() macro per CM's request. */ ++ /* prBowBssInfo->eConnectionState = eConnectionState; */ ++ ++ /* For indicating the Disconnect Event only if current media state is ++ * disconnected and we didn't do indication yet. ++ */ ++ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ if (prBssInfo->eConnectionStateIndicated == eConnectionState) ++ return; ++ } ++ ++ if (!fgDelayIndication) { ++ /* 4 <0> Cancel Delay Timer */ ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rIndicationOfDisconnectTimer); ++ ++ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ ++ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; ++ ++ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; ++ rEventConnStatus.u2AID = prBssInfo->u2AssocId; ++ rEventConnStatus.u2ATIMWindow = 0; ++ } else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; ++ rEventConnStatus.u2AID = 0; ++ rEventConnStatus.u2ATIMWindow = prBssInfo->u2ATIMWindow; ++ } else { ++ ASSERT(0); ++ } ++ ++ COPY_SSID(rEventConnStatus.aucSsid, ++ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prBssInfo->aucBSSID); ++ ++ rEventConnStatus.u2BeaconPeriod = prBssInfo->u2BeaconInterval; ++ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prBssInfo->ucPrimaryChannel); ++ ++ switch (prBssInfo->ucNonHTBasicPhyType) { ++ case PHY_TYPE_HR_DSSS_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ ++ case PHY_TYPE_ERP_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; ++ break; ++ ++ case PHY_TYPE_OFDM_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; ++ break; ++ ++ default: ++ ASSERT(0); ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ } ++ } else { ++#if CFG_PRIVACY_MIGRATION ++ /* Clear the pmkid cache while media disconnect */ ++ secClearPmkid(prAdapter); ++#endif ++ ++ rEventConnStatus.ucReasonOfDisconnect = prBssInfo->ucReasonOfDisconnect; ++ ++ } ++ ++ /* 4 <2> Indication */ ++ nicMediaStateChange(prAdapter, NETWORK_TYPE_BOW_INDEX, &rEventConnStatus); ++ prBssInfo->eConnectionStateIndicated = eConnectionState; ++ } else { ++ /* NOTE: Only delay the Indication of Disconnect Event */ ++ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ DBGLOG(BOW, INFO, "Postpone the indication of Disconnect for %d seconds\n", ++ prConnSettings->ucDelayTimeOfDisconnectEvent); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prBowFsmInfo->rIndicationOfDisconnectTimer, ++ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Tx Fail of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowRunEventAAATxFail , bssRemoveStaRecFromClientList.\n"); ++ DBGLOG(BOW, INFO, "BoW AAA TxFail, target state %d\n", prStaRec->ucStaState + 1); ++#endif ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Successful Completion of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ++ ASSERT(prStaRec); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowRunEventAAAComplete, cnmStaRecChangeState, STA_STATE_3.\n"); ++ DBGLOG(BOW, INFO, "BoW AAA complete [%pM]\n", prStaRec->aucMacAddr); ++#endif ++ ++ /*Update BssInfo to connected */ ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /*Update StaRec to State3 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ /*Connected */ ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, FALSE, wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle RxDeauth ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBowBssInfo; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ if (!IS_STA_IN_BOW(prStaRec)) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ ++ eFsmState = bowGetBowTableState(prAdapter, prStaRec->aucMacAddr); ++ ++ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { ++ /*do nothing */ ++ return WLAN_STATUS_NOT_ACCEPTED; ++ } ++ ++ if (prStaRec->ucStaState > STA_STATE_1) { ++ ++ if (STA_STATE_3 == prStaRec->ucStaState) { ++ /* P_MSG_AIS_ABORT_T prAisAbortMsg; */ ++ ++ /* NOTE(Kevin): Change state immediately to avoid starvation of ++ * MSG buffer because of too many deauth frames before changing ++ * the STA state. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++ ++ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); ++ ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ return WLAN_STATUS_NOT_ACCEPTED; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function handle BoW Link disconnect. ++* ++* \param[in] pMsduInfo Pointer to the Msdu Info ++* \param[in] rStatus The Tx done status ++* ++* \return - ++* ++* \note after receive deauth frame, callback function call this ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ /*Free target StaRec */ ++ if (prMsduInfo) ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ else ++ prStaRec = prBowFsmInfo->prTargetStaRec; ++ ++ if (prStaRec) ++ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ kalPrint("bowDisconnectLink\n"); ++ /*No one connected */ ++ if (g_u4LinkCount == 0 && g_u4Beaconing != 0) { ++ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer); ++ bowStopping(prAdapter); ++ kalPrint("bowStopping\n"); ++ /*Restore TxPower from Short range mode */ ++#if CFG_SUPPORT_NVRAM && 0 ++ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); ++#endif ++ /*Uninit BoW Interface */ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ kalUninitBowDevice(prAdapter->prGlueInfo); ++#endif ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Assoc Req Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Assoc Resp ++* @retval FALSE Don't reply the Assoc Resp ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAssocResp = FALSE; ++ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; ++ OS_SYSTIME rCurrentTime; ++ static OS_SYSTIME rLastRejectAssocTime; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prAssocReqFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", ++ prAssocReqFrame->aucSrcAddr[0], ++ prAssocReqFrame->aucSrcAddr[1], ++ prAssocReqFrame->aucSrcAddr[2], ++ prAssocReqFrame->aucSrcAddr[3], ++ prAssocReqFrame->aucSrcAddr[4], prAssocReqFrame->aucSrcAddr[5])); ++#endif ++ ++ /*Assoc Accept */ ++ while (EQUAL_MAC_ADDR(prAssocReqFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAssocReq, return wlanbowCmdEventLinkConnected.\n"); ++#endif ++ /*Update StaRec */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ (UINT_8) NETWORK_TYPE_BOW_INDEX, prAssocReqFrame->aucSrcAddr); ++ if (!prStaRec) ++ break; ++ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; ++ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; ++ ++#if CFG_BOW_RATE_LIMITATION ++ /*Limit Rate Set to 24M, 48M, 54M */ ++ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); ++ /*If peer cannot support the above rate set, fix on the available highest rate */ ++ if (prStaRec->u2DesiredNonHTRateSet == 0) { ++ UINT_8 ucHighestRateIndex; ++ ++ if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) ++ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); ++ else { ++ /*If no available rate is found, DECLINE the association */ ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++ } ++#endif ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ ++ /*Undpate BssInfo to FW */ ++ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ ++ /*reply successful */ ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ fgReplyAssocResp = TRUE; ++ break; ++ } ++ ++ /*Reject Assoc */ ++ if (*pu2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ /*Reply Assoc with reject every 5s */ ++ rCurrentTime = kalGetTimeTick(); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAssocTime, MSEC_TO_SYSTIME(5000)) || ++ rLastRejectAssocTime == 0) { ++ fgReplyAssocResp = TRUE; ++ rLastRejectAssocTime = rCurrentTime; ++ } ++ } ++ ++ return fgReplyAssocResp; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Auth Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Auth ++* @retval FALSE Don't reply the Auth ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++bowValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAuth = FALSE; ++ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; ++ OS_SYSTIME rCurrentTime; ++ static OS_SYSTIME rLastRejectAuthTime; ++ ++ /* TODO(Kevin): Call BoW functions to check .. ++ 1. Check we are BoW now. ++ 2. Check we can accept connection from thsi peer ++ 3. Check Black List here. ++ */ ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ prBowFsmInfo->aucPeerAddress[0], ++ prBowFsmInfo->aucPeerAddress[1], ++ prBowFsmInfo->aucPeerAddress[2], ++ prBowFsmInfo->aucPeerAddress[3], ++ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prAuthFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", ++ prAuthFrame->aucSrcAddr[0], ++ prAuthFrame->aucSrcAddr[1], ++ prAuthFrame->aucSrcAddr[2], ++ prAuthFrame->aucSrcAddr[3], prAuthFrame->aucSrcAddr[4], prAuthFrame->aucSrcAddr[5])); ++#endif ++ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX, prAuthFrame->aucSrcAddr); ++ if (!prStaRec) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecAlloc.\n"); ++#endif ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX); ++ ++ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for ++ * exhausted case and do removal of unused STA_RECORD_T. ++ */ ++ if (!prStaRec) ++ return fgReplyAuth; ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++ prBowBssInfo->prStaRecOfAP = prStaRec; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecChangeState.\n"); ++#endif ++ } else { ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucIndex, %x.\n", prStaRec->ucIndex); ++#endif ++ bssRemoveStaRecFromClientList(prAdapter, prBowBssInfo, prStaRec); ++ } ++ ++ if (EQUAL_MAC_ADDR(prAuthFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { ++ ++ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->eStaType, %x.\n", prStaRec->eStaType); ++ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucNetTypeIndex, %x.\n", prStaRec->ucNetTypeIndex); ++#endif ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ prStaRec->ucJoinFailureCount = 0; ++ *pprStaRec = prStaRec; ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ fgReplyAuth = TRUE; ++ } else { ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ /*Reply auth with reject every 5s */ ++ rCurrentTime = kalGetTimeTick(); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAuthTime, MSEC_TO_SYSTIME(5000)) || ++ rLastRejectAuthTime == 0) { ++ fgReplyAuth = TRUE; ++ rLastRejectAuthTime = rCurrentTime; ++ } ++ } ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowValidateAuth, fgReplyAuth, %x.\n", fgReplyAuth); ++#endif ++ return fgReplyAuth; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is invoked when CNM granted channel privilege ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prBowBssInfo; ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_CH_GRANT_T prMsgChGrant; ++ UINT_8 ucTokenID; ++ UINT_32 u4GrantInterval; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; ++ ucTokenID = prMsgChGrant->ucTokenID; ++ u4GrantInterval = prMsgChGrant->u4GrantInterval; ++ ++ /* 1. free message */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ prBowFsmInfo->fgIsChannelGranted = TRUE; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Entering bowRunEventChGrant.\n"); ++#endif ++ ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ /*Release channel */ ++ if ((!prBowFsmInfo->fgIsChannelRequested) || ++ (prBowFsmInfo->ucSeqNumOfChReq != ucTokenID) || ++ (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) || (eFsmState == BOW_DEVICE_STATE_DISCONNECTING)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW Channel [GIVE UP:%d]\n", ucTokenID); ++ DBGLOG(BOW, INFO, "[Requested:%d][ucSeqNumOfChReq:%d][eFsmState:%d]\n", ++ prBowFsmInfo->fgIsChannelRequested, prBowFsmInfo->ucSeqNumOfChReq, eFsmState); ++#endif ++ bowReleaseCh(prAdapter); ++ return; ++ } ++ ++ /* 2. channel privilege has been approved */ ++ prBowFsmInfo->u4ChGrantedInterval = u4GrantInterval; ++ ++#if 0 ++ cnmTimerStartTimer(prAdapter, ++ &prBowFsmInfo->rChGrantedTimer, ++ prBowFsmInfo->u4ChGrantedInterval - BOW_JOIN_CH_GRANT_THRESHOLD); ++#else ++ cnmTimerStartTimer(prAdapter, ++ &prBowFsmInfo->rChGrantedTimer, BOW_JOIN_CH_REQUEST_INTERVAL - BOW_JOIN_CH_GRANT_THRESHOLD); ++#endif ++ ++ /* 3.2 set local variable to indicate join timer is ticking */ ++ prBowFsmInfo->fgIsInfraChannelFinished = FALSE; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW Channel [GRANTED:%d].\n", ucTokenID); ++#endif ++ ++ if (eFsmState == BOW_DEVICE_STATE_ACQUIRING_CHANNEL) { ++ bowStarting(prAdapter); ++ bowReleaseCh(prAdapter); ++ if (prBowFsmInfo->ucRole == BOW_RESPONDER) ++ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); ++ } else { ++ /*update bssinfo */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); ++ bowReleaseCh(prAdapter); ++ } ++ ++} /* end of aisFsmRunEventChGrant() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform CNM for channel privilege requesting ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowRequestCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_CH_REQ_T prMsgChReq; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (prBowFsmInfo->fgIsChannelGranted == FALSE) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW channel [REQUEST:%d], %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq + 1, ++ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); ++#endif ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ return; ++ } ++ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prMsgChReq->ucTokenID = ++prBowFsmInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++#if 0 ++ prMsgChReq->u4MaxInterval = BOW_JOIN_CH_REQUEST_INTERVAL; ++#else ++ prMsgChReq->u4MaxInterval = 1; ++#endif ++ /* prBowFsmInfo->prTargetBssDesc->ucChannelNum; */ ++ prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; ++ /* prBowFsmInfo->prTargetBssDesc->eSco; */ ++ prMsgChReq->eRfSco = CHNL_EXT_SCN; ++ /* prBowFsmInfo->prTargetBssDesc->eBand; */ ++ prMsgChReq->eRfBand = prBowFsmInfo->eBand; ++ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prBowFsmInfo->aucPeerAddress); ++ ++ prBowFsmInfo->fgIsChannelRequested = TRUE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform BOW that channel privilege is granted ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowReleaseCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ P_MSG_CH_ABORT_T prMsgChAbort; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++ if (prBowFsmInfo->fgIsChannelGranted != FALSE || prBowFsmInfo->fgIsChannelRequested != FALSE) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW channel [RELEASE:%d] %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq, ++ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); ++#endif ++ ++ prBowFsmInfo->fgIsChannelRequested = FALSE; ++ prBowFsmInfo->fgIsChannelGranted = FALSE; ++ ++ /* 1. return channel privilege to CNM immediately */ ++ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); ++ if (!prMsgChAbort) { ++ ASSERT(0); /* Can't release Channel to CNM */ ++ return; ++ } ++ ++ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; ++ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ prMsgChAbort->ucTokenID = prBowFsmInfo->ucSeqNumOfChReq; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); ++ } ++ ++} /* end of aisFsmReleaseCh() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) ++{ ++ P_BOW_FSM_INFO_T prBowFsmInfo; ++ ENUM_BOW_DEVICE_STATE eFsmState; ++ ++ ASSERT(prAdapter); ++ ++ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "BoW Channel [TIMEOUT]\n"); ++#endif ++#if 1 ++ /* bowReleaseCh(prAdapter); */ ++ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); ++ ++ /*If connecting is not completed, request CH again */ ++ if ((eFsmState == BOW_DEVICE_STATE_CONNECTING) || (eFsmState == BOW_DEVICE_STATE_STARTING)) ++ bowRequestCh(prAdapter); ++#endif ++} ++ ++BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucBowTableIdx = 0; ++ CMD_INFO_T rCmdInfo; ++ ++ ASSERT(prAdapter); ++ ++ kalMemZero(&rCmdInfo, sizeof(CMD_INFO_T)); ++ ++ while (ucBowTableIdx < CFG_BOW_PHYSICAL_LINK_NUM) { ++ if (arBowTable[ucBowTableIdx].fgIsValid) { ++ COPY_MAC_ADDR(prAdapter->rWifiVar.rBowFsmInfo.aucPeerAddress, ++ arBowTable[ucBowTableIdx].aucPeerAddress); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowNotifyAllLinkDisconnected, arBowTable[%x].aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ ucBowTableIdx, arBowTable[ucBowTableIdx].aucPeerAddress[0], ++ arBowTable[ucBowTableIdx].aucPeerAddress[1], ++ arBowTable[ucBowTableIdx].aucPeerAddress[2], ++ arBowTable[ucBowTableIdx].aucPeerAddress[3], ++ arBowTable[ucBowTableIdx].aucPeerAddress[4], ++ arBowTable[ucBowTableIdx].aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "bowNotifyAllLinkDisconnected, arBowTable[%x].fgIsValid, %x.\n", ucBowTableIdx, ++ arBowTable[ucBowTableIdx].fgIsValid); ++#endif ++#if 1 ++ wlanoidSendSetQueryBowCmd(prAdapter, ++ CMD_ID_CMD_BT_OVER_WIFI, ++ TRUE, ++ FALSE, ++ wlanbowCmdEventLinkDisconnected, ++ wlanbowCmdTimeoutHandler, 0, NULL, 0); ++#else ++ wlanbowCmdEventLinkDisconnected(prAdapter, &rCmdInfo, NULL); ++#endif ++ } ++ ++ ucBowTableIdx += 1; ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer ++* ++* \param[in] ++* prGlueInfo ++* rPeerAddr ++* \return ++* ENUM_BOW_DEVICE_STATE ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], ++ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], ++ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, ++ arBowTable[idx].fgIsValid); ++ ++#endif ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ return TRUE; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ return FALSE; ++} ++ ++BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable) ++{ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ if (arBowTable[ucBowTableIdx].fgIsValid) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowGetBowTableContent, arBowTable[idx].fgIsValid, %x, %x.\n", ucBowTableIdx, ++ arBowTable[ucBowTableIdx].fgIsValid); ++ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[ucBowTableIdx].eState); ++#endif ++ prBowTable = &(arBowTable[ucBowTableIdx]); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return TRUE; ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return FALSE; ++} ++ ++BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable) ++{ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ COPY_MAC_ADDR(arBowTable[ucBowTableIdx].aucPeerAddress, prBowTable->aucPeerAddress); ++ arBowTable[ucBowTableIdx].eState = prBowTable->eState; ++ arBowTable[ucBowTableIdx].fgIsValid = prBowTable->fgIsValid; ++ arBowTable[ucBowTableIdx].ucAcquireID = prBowTable->ucAcquireID; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ kalSetBowState(prAdapter->prGlueInfo, prBowTable->eState, prBowTable->aucPeerAddress); ++ /* kalSetBowRole(prAdapter->prGlueInfo, prBowTable->ucRole, prBowTable->aucPeerAddress); */ ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "SET State [%d]\n", arBowTable[ucBowTableIdx].eState); ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[ucBowTableIdx].fgIsValid, %x, %x.\n", ucBowTableIdx, ++ arBowTable[ucBowTableIdx].fgIsValid); ++#endif ++ ++ return TRUE; ++ ++} ++ ++BOOLEAN ++bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], ++ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], ++ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, ++ arBowTable[idx].fgIsValid); ++#endif ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ *pucBowTableIdx = idx; ++ ++ return TRUE; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return FALSE; ++} ++ ++BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (!arBowTable[idx].fgIsValid) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, ++ "bowGetBowTableFreeEntry, arBowTable[idx].fgIsValid, %x, %x.\n", idx, ++ arBowTable[idx].fgIsValid); ++#endif ++ *pucBowTableIdx = idx; ++ arBowTable[idx].fgIsValid = TRUE; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return TRUE; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return FALSE; ++} ++ ++ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 idx; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { ++ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "bowGetState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, "bowGetState, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, ++ arBowTable[idx].aucPeerAddress[0], ++ arBowTable[idx].aucPeerAddress[1], ++ arBowTable[idx].aucPeerAddress[2], ++ arBowTable[idx].aucPeerAddress[3], ++ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); ++ DBGLOG(BOW, EVENT, ++ "bowGetState, arBowTable[idx].fgIsValid, %x, %x.\n", idx, arBowTable[idx].fgIsValid); ++ DBGLOG(BOW, EVENT, ++ "bowGetState, arBowTable[idx].eState;, %x, %x.\n", idx, arBowTable[idx].eState); ++ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[idx].eState); ++#endif ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return arBowTable[idx].eState; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ return BOW_DEVICE_STATE_DISCONNECTED; ++} ++ ++BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState) ++{ ++ UINT_8 ucBowTableIdx; ++ ++ if (bowGetBowTableEntryByPeerAddress(prAdapter, aucPeerAddress, &ucBowTableIdx)) { ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ arBowTable[ucBowTableIdx].eState = eState; ++#if CFG_BOW_TEST ++ DBGLOG(BOW, INFO, "SET State [%d]\n", eState); ++#endif ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); ++ ++ kalSetBowState(prAdapter->prGlueInfo, eState, aucPeerAddress); ++ return TRUE; ++ } ++ return FALSE; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c +new file mode 100644 +index 000000000000..1c59f861047e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c +@@ -0,0 +1,6240 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_lib.c#2 ++*/ ++/*! \file wlan_lib.c ++ \brief Internal driver stack will export the required procedures here for GLUE Layer. ++ ++ This file contains all routines which are exported from MediaTek 802.11 Wireless ++ LAN driver stack to GLUE Layer. ++*/ ++ ++/* ++** Log: wlan_lib.c ++** ++** 08 15 2012 eason.tsai ++** [ALPS00338170] [Need Patch] [Volunteer Patch] modify build warning ++** fix build waring for codechange ++ * ++ * 07 13 2012 cp.wu ++ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for termination ++ * after SDIO error has happened ++ * [driver domain] add force reset by host-to-device interrupt mechanism ++ * ++ * 06 11 2012 cp.wu ++ * [WCXRP00001252] [MT6620 Wi-Fi][Driver] Add debug message while encountering firmware response timeout ++ * output message while timeout event occurs ++ * ++ * 06 11 2012 eason.tsai ++ * NULL ++ * change from binay to hex code ++ * ++ * 06 08 2012 eason.tsai ++ * NULL ++ * Nvram context covert from 6620 to 6628 for old 6620 meta tool ++ * ++ * 05 11 2012 cp.wu ++ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience ++ * show MAC address & source while initiliazation ++ * ++ * 03 29 2012 eason.tsai ++ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define ++ * add conditional define. ++ * ++ * 03 04 2012 eason.tsai ++ * NULL ++ * modify the cal fail report code. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 cp.wu ++ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band ++ * configuration with corresponding network configuration correct scan result removing policy. ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with ++ * corresponding network configuration add wlanSetPreferBandByNetwork() for glue layer to invoke ++ * for setting preferred band configuration corresponding to network type. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 11 28 2011 cp.wu ++ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment ++ * when returining to ROM code ++ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware ++ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not ++ * ++ * 11 14 2011 cm.chang ++ * [WCXRP00001104] [All Wi-Fi][FW] Show init process by HW mail-box register ++ * Show FW initial ID when timeout to wait for ready bit ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 10 18 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * when powering off, always clear pending interrupts, then wait for RDY to be de-asserted ++ * ++ * 10 14 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * shorten the packet length for firmware download if no more than 2048 bytes. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 10 03 2011 cp.wu ++ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware downloading aggregated path. ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 09 20 2011 cp.wu ++ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized ++ * 1. always show error message for SDIO bus errors. ++ * 2. reset bus error flag when re-initialization ++ * ++ * 08 26 2011 cm.chang ++ * [WCXRP00000952] [MT5931 Wi-Fi][FW] Handshake with BWCS before DPD/TX power calibration ++ * Fix compiling error for WinXP MT5931 driver ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS Sync ready for WinXP. ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add DFS switch. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 19 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * escape from normal path if any error is occurred. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a ++ * disconnecting device issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 24 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * if there is no valid address in chip, generate a new one from driver domain instead of firmware domain ++ * due to sufficient randomness ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * disable whole-chip resetting mechanism due to the need of further ECO to work as expected. ++ * ++ * 05 31 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * changed to use non-zero checking for valid bit in NVRAM content ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain ++ * pass PHY_PARAM in NVRAM from driver to firmware. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * correct assertion. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 05 11 2011 cm.chang ++ * [WCXRP00000717] [MT5931 Wi-Fi][Driver] Handle wrong NVRAM content about AP bandwidth setting ++ * . ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * change delay from 100ms to 120ms upon DE's suggestion. ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add delay after whole-chip resetting for MT5931 E1 ASIC. ++ * ++ * 04 22 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space ++ * process for RESET_START and RESET_END events skip power-off handshaking when RESET indication is received. ++ * ++ * 04 22 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * . ++ * ++ * 04 18 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * 1) add API for glue layer to query ACPI state ++ * 2) Windows glue should not access to hardware after switched into D3 state ++ * ++ * 04 15 2011 cp.wu ++ * [WCXRP00000654] [MT6620 Wi-Fi][Driver] Add loop termination criterion for wlanAdapterStop(). ++ * add loop termination criteria for wlanAdapterStop(). ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing ++ * frame dropping cases for TC4 path ++ * 1. add nicTxGetResource() API for QM to make decisions. ++ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. ++ * ++ * 04 06 2011 cp.wu ++ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure ++ * happend inside wlanAdapterStart invoke nicReleaseAdapterMemory() as failure handling in case ++ * wlanAdapterStart() failed unexpectedly ++ * ++ * 03 29 2011 wh.su ++ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error ++ * fixed the kclocwork error. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically ++ * continuous memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 02 25 2011 cp.wu ++ * [WCXRP00000496] [MT5931][Driver] Apply host-triggered chip reset before initializing firmware download procedures ++ * apply host-triggered chip reset mechanism before initializing firmware download procedures. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 16 2011 cm.chang ++ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism ++ * . ++ * ++ * 02 01 2011 george.huang ++ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers ++ * init variable for CTIA. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Support current measure mode, assigned by registry (XP only). ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer when the ++ * corresponding BSS is disconnected due to beacon timeout remove from scanning result when the BSS ++ * is disconnected due to beacon timeout. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ++ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous ++ * and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * while being unloaded, clear all pending interrupt then set LP-own to firmware ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay ++ * to avoid blocking to system scheduling change to use msleep() and shorten waiting interval ++ * to reduce blocking to other task while Wi-Fi driver is being loaded ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 22 2010 eddie.chen ++ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry ++ * Remove controling auto rate from initial setting. The initial setting is defined by FW code. ++ * ++ * 12 15 2010 cp.wu ++ * NULL ++ * sync. with ALPS code by enabling interrupt just before leaving wlanAdapterStart() ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in ++ * Change Param name for invitation connection. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 03 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * 1) use 8 buffers for MT5931 which is equipped with less memory ++ * 2) modify MT5931 debug level to TRACE when download is successful ++ * ++ * 11 02 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * for MT5931, adapter initialization is done *after* firmware is downloaded. ++ * ++ * 11 02 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * correct MT5931 firmware download procedure: ++ * MT5931 will download firmware first then acquire LP-OWN ++ * ++ * 11 02 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * 1) update MT5931 firmware encryption tool. (using 64-bytes unit) ++ * 2) update MT5931 firmware download procedure ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying ++ * current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function ++ * for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add option for enable/disable TX PWR gain adjustment (default: off) ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 15 2010 cp.wu ++ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A ++ * bugfix: always reset pointer to IEbuf to zero when keeping scanning result for the connected AP ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced ++ * by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate unused variables which lead gcc to argue ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with ++ * AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 13 2010 cp.wu ++ * NULL ++ * acquire & release power control in oid handing wrapper. ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * move IE to buffer head when the IE pointer is not pointed at head. ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add AT GO test configure mode under WinXP. ++ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cp.wu ++ * NULL ++ * 1) initialize variable for enabling short premable/short time slot. ++ * 2) add compile option for disabling online scan ++ * ++ * 08 13 2010 cp.wu ++ * NULL ++ * correction issue: desired phy type not initialized as ABGN mode. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 10 2010 cm.chang ++ * NULL ++ * Support EEPROM read/write in RF test mode ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 13 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Reduce unnecessary type casting ++ * ++ * 07 13 2010 cp.wu ++ * ++ * use multiple queues to keep 1x/MMPDU/CMD's strict order even when there is incoming 1x frames. ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent ++ * network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) for event packet, no need to fill RFB. ++ * 2) when wlanAdapterStart() failed, no need to initialize state machines ++ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan uninitialization procedure ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * initialize mbox & ais_fsm in wlanAdapterStart() ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * simplify timer usage. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 28 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * disable interrupt then send power control command packet. ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) when stopping adapter, wait til RDY bit has been cleaerd. ++ * 2) set TASK_OFFLOAD as driver-core OIDs ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add CFG_STARTUP_DEBUG for debugging starting up issue. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * roll-back to rev.60. ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove redundant firmware image unloading ++ * 2) use compile-time macros to separate logic related to accquiring own ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always set fw-own before driver is unloaded. ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * 2) command sequence number is now increased atomically ++ * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * are done in adapter layer. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * ePowerCtrl is not necessary as a glue variable. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add timeout check in the kalOidComplete ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * 2) add 2 kal API for later integration ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) eliminate unused definitions ++ * 2) ready bit will be polled for limited iteration ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * kalOidComplete is not necessary in linux ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use pass-in prRegInfo instead of accessing prGlueInfo directly ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use WIFI_TCM_ALWAYS_ON as firmware image ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding none-glue code portability ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding non-glue code portability ++ * ++ * 03 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve non-glue code portability ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * firmware download load address & start address are now configured from config.h ++ * due to the different configurations on FPGA and ASIC ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * only send CMD_NIC_POWER_CTRL in wlanAdapterStop() when card is not removed and is not in D3 state ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always send CMD_NIC_POWER_CTRL packet when nic is being halted ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++* 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when starting adapter, read local adminsitrated address from registry and send to firmware via CMD_BASIC_CONFIG. ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 03 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add command/event definitions for initial states ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added code for QM_TEST_MODE ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct function name .. ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * separate wlanProcesQueuePacket() into 2 APIs upon request ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct wlanAdapterStart ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. add logic for firmware download ++ * 2. firmware image filename and start/load address are now retrieved from registry ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * 2) firmware image length is now retrieved via NdisFileOpen ++ * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * 4) nicRxWaitResponse() revised ++ * 5) another set of TQ counter default value is added for fw-download state ++ * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * 2. follow MSDN defined behavior when associates to another AP ++ * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * wlanoidSetFrequency is now implemented by RF test command. ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * QueryRssi is no longer w/o hardware access, it is now implemented by command/event handling loop ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. clear prPendingCmdInfo properly ++ * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. ++ * ++ * 01 28 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * allow MCR read/write OIDs in RF test mode ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) implement timeout mechanism when OID is pending for longer than 1 second ++ * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * 2. block TX/ordinary OID when RF test mode is engaged ++ * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * 4. correct some HAL implementation ++ * ++ * 01 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer ++** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-12-10 16:54:36 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-12-09 20:04:59 GMT mtk02752 ++** only report as connected when CFG_HIF_EMULATION_TEST is set to 1 ++** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-12-08 17:39:41 GMT mtk02752 ++** wlanoidRftestQueryAutoTest could be executed without touching hardware ++** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-12-03 16:10:26 GMT mtk01461 ++** Add debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-02 22:05:33 GMT mtk02752 ++** kalOidComplete() will decrease i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-01 23:02:36 GMT mtk02752 ++** remove unnecessary spinlock ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-01 22:50:38 GMT mtk02752 ++** use TC4 for command, maintein i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-27 12:45:34 GMT mtk02752 ++** prCmdInfo should be freed when invoking wlanReleasePendingOid() to clear pending oid ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-24 19:55:51 GMT mtk02752 ++** wlanSendPacket & wlanRetransmitOfPendingFrames is only used in old data path ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-23 17:59:55 GMT mtk02752 ++** clear prPendingOID inside wlanSendCommand() when the OID didn't need to be replied. ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-23 14:45:29 GMT mtk02752 ++** add another version of wlanSendCommand() for command-sending only without blocking for response ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-17 22:40:44 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 10:14:56 GMT mtk01084 ++** modify place to invoke wlanIst ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-10-30 18:17:07 GMT mtk01084 ++** fix compiler warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-10-29 19:46:15 GMT mtk01084 ++** invoke interrupt process routine ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-10-13 21:58:24 GMT mtk01084 ++** modify for new HW architecture ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-09-09 17:26:01 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-05-20 12:21:27 GMT mtk01461 ++** Add SeqNum check when process Event Packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-05-19 10:38:44 GMT mtk01461 ++** Add wlanReleasePendingOid() for mpReset() if there is a pending OID and no available TX resource to send it. ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-04-29 15:41:34 GMT mtk01461 ++** Add handle of EVENT of CMD Result in wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-04-22 09:11:23 GMT mtk01461 ++** Fix wlanSendCommand() for Driver Domain CR ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-04-21 09:33:56 GMT mtk01461 ++** Update wlanSendCommand() for Driver Domain Response and handle Event Packet, ++** wlanQuery/SetInformation() for enqueue CMD_INFO_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-17 20:00:08 GMT mtk01461 ++** Update wlanImageSectionDownload for optimized CMD process ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-14 20:50:51 GMT mtk01426 ++** Fixed compile error ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-13 16:38:40 GMT mtk01084 ++** add wifi start function ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-13 14:26:44 GMT mtk01084 ++** modify a parameter about FW download length ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-10 21:53:42 GMT mtk01461 ++** Update wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-08 16:51:04 GMT mtk01084 ++** Update for the image download part ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-01 10:32:47 GMT mtk01461 ++** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-03-23 21:44:13 GMT mtk01461 ++** Refine TC assignment for WmmAssoc flag ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 16:51:57 GMT mtk01084 ++** modify the input argument of caller to RECLAIM_POWER_CONTROL_TO_PM() ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:27:13 GMT mtk01461 ++** Add reference code of FW Image Download ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:37 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:08 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 16:28:45 GMT mtk01426 ++** Init develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++#include "mgmt/ais_fsm.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* 6.1.1.2 Interpretation of priority parameter in MAC service primitives */ ++/* Static convert the Priority Parameter/TID(User Priority/TS Identifier) to Traffic Class */ ++const UINT_8 aucPriorityParam2TC[] = { ++ TC1_INDEX, ++ TC0_INDEX, ++ TC0_INDEX, ++ TC1_INDEX, ++ TC2_INDEX, ++ TC2_INDEX, ++ TC3_INDEX, ++ TC3_INDEX ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _CODE_MAPPING_T { ++ UINT_32 u4RegisterValue; ++ INT_32 i4TxpowerOffset; ++} CODE_MAPPING_T, *P_CODE_MAPPING_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++BOOLEAN fgIsBusAccessFailed = FALSE; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define SIGNED_EXTEND(n, _sValue) \ ++ (((_sValue) & BIT((n)-1)) ? ((_sValue) | BITS(n, 31)) : \ ++ ((_sValue) & ~BITS(n, 31))) ++ ++/* TODO: Check */ ++/* OID set handlers without the need to access HW register */ ++PFN_OID_HANDLER_FUNC apfnOidSetHandlerWOHwAccess[] = { ++ wlanoidSetChannel, ++ wlanoidSetBeaconInterval, ++ wlanoidSetAtimWindow, ++ wlanoidSetFrequency, ++}; ++ ++/* TODO: Check */ ++/* OID query handlers without the need to access HW register */ ++PFN_OID_HANDLER_FUNC apfnOidQueryHandlerWOHwAccess[] = { ++ wlanoidQueryBssid, ++ wlanoidQuerySsid, ++ wlanoidQueryInfrastructureMode, ++ wlanoidQueryAuthMode, ++ wlanoidQueryEncryptionStatus, ++ wlanoidQueryPmkid, ++ wlanoidQueryNetworkTypeInUse, ++ wlanoidQueryBssidList, ++ wlanoidQueryAcpiDevicePowerState, ++ wlanoidQuerySupportedRates, ++ wlanoidQueryDesiredRates, ++ wlanoidQuery802dot11PowerSaveProfile, ++ wlanoidQueryBeaconInterval, ++ wlanoidQueryAtimWindow, ++ wlanoidQueryFrequency, ++}; ++ ++/* OID set handlers allowed in RF test mode */ ++PFN_OID_HANDLER_FUNC apfnOidSetHandlerAllowedInRFTest[] = { ++ wlanoidRftestSetTestMode, ++ wlanoidRftestSetAbortTestMode, ++ wlanoidRftestSetAutoTest, ++ wlanoidSetMcrWrite, ++ wlanoidSetEepromWrite ++}; ++ ++/* OID query handlers allowed in RF test mode */ ++PFN_OID_HANDLER_FUNC apfnOidQueryHandlerAllowedInRFTest[] = { ++ wlanoidRftestQueryAutoTest, ++ wlanoidQueryMcrRead, ++ wlanoidQueryEepromRead ++} ++ ++; ++ ++PFN_OID_HANDLER_FUNC apfnOidWOTimeoutCheck[] = { ++ wlanoidRftestSetTestMode, ++ wlanoidRftestSetAbortTestMode, ++ wlanoidSetAcpiDevicePowerState, ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if 0 /* no use */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is a private routine, which is used to check if HW access is needed ++* for the OID query/ set handlers. ++* ++* \param[IN] pfnOidHandler Pointer to the OID handler. ++* \param[IN] fgSetInfo It is a Set information handler. ++* ++* \retval TRUE This function needs HW access ++* \retval FALSE This function does not need HW access ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) ++{ ++ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOHwAccess; ++ UINT_32 i; ++ UINT_32 u4NumOfElem; ++ ++ if (fgSetInfo) { ++ apfnOidHandlerWOHwAccess = apfnOidSetHandlerWOHwAccess; ++ u4NumOfElem = sizeof(apfnOidSetHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); ++ } else { ++ apfnOidHandlerWOHwAccess = apfnOidQueryHandlerWOHwAccess; ++ u4NumOfElem = sizeof(apfnOidQueryHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); ++ } ++ ++ for (i = 0; i < u4NumOfElem; i++) { ++ if (apfnOidHandlerWOHwAccess[i] == pfnOidHandler) ++ return FALSE; ++ } ++ ++ return TRUE; ++} /* wlanIsHandlerNeedHwAccess */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set flag for later handling card ++* ejected event. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++* ++* \note When surprised removal happens, Glue layer should invoke this ++* function to notify WPDD not to do any hw access. ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanCardEjected(IN P_ADAPTER_T prAdapter) ++{ ++ DEBUGFUNC("wlanCardEjected"); ++ /* INITLOG(("\n")); */ ++ ++ ASSERT(prAdapter); ++ ++ /* mark that the card is being ejected, NDIS will shut us down soon */ ++ nicTxRelease(prAdapter); ++ ++} /* wlanCardEjected */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Create adapter object ++* ++* \param prAdapter This routine is call to allocate the driver software objects. ++* If fails, return NULL. ++* \retval NULL If it fails, NULL is returned. ++* \retval NOT NULL If the adapter was initialized successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_ADAPTER_T prAdpater = (P_ADAPTER_T) NULL; ++ ++ DEBUGFUNC("wlanAdapterCreate"); ++ ++ do { ++ prAdpater = (P_ADAPTER_T) kalMemAlloc(sizeof(ADAPTER_T), VIR_MEM_TYPE); ++ ++ if (!prAdpater) { ++ DBGLOG(INIT, ERROR, "Allocate ADAPTER memory ==> FAILED\n"); ++ break; ++ } ++ ++ kalMemZero(prAdpater, sizeof(ADAPTER_T)); ++ prAdpater->prGlueInfo = prGlueInfo; ++ ++ } while (FALSE); ++ ++ return prAdpater; ++} /* wlanAdapterCreate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Destroy adapter object ++* ++* \param prAdapter This routine is call to destroy the driver software objects. ++* If fails, return NULL. ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter) ++{ ++ ++ if (!prAdapter) ++ return; ++ ++ kalMemFree(prAdapter, VIR_MEM_TYPE, sizeof(ADAPTER_T)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Initialize the adapter. The sequence is ++* 1. Disable interrupt ++* 2. Read adapter configuration from EEPROM and registry, verify chip ID. ++* 3. Create NIC Tx/Rx resource. ++* 4. Initialize the chip ++* 5. Initialize the protocol ++* 6. Enable Interrupt ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanAdapterStart(IN P_ADAPTER_T prAdapter, ++ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_32 i, u4Value = 0; ++ UINT_32 u4WHISR = 0; ++ UINT_8 aucTxCount[8]; ++#if CFG_ENABLE_FW_DOWNLOAD ++ UINT_32 u4FwLoadAddr, u4ImgSecSize; ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ UINT_32 j; ++ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; ++ BOOLEAN fgValidHead; ++ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); ++#endif ++#endif ++ enum Adapter_Start_Fail_Reason { ++ ALLOC_ADAPTER_MEM_FAIL, ++ DRIVER_OWN_FAIL, ++ INIT_ADAPTER_FAIL, ++ RAM_CODE_DOWNLOAD_FAIL, ++ WAIT_FIRMWARE_READY_FAIL, ++ FAIL_REASON_MAX ++ } eFailReason; ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanAdapterStart"); ++ ++ eFailReason = FAIL_REASON_MAX; ++ /* 4 <0> Reset variables in ADAPTER_T */ ++ prAdapter->fgIsFwOwn = TRUE; ++ prAdapter->fgIsEnterD3ReqIssued = FALSE; ++ ++ QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); ++ ++ /* Initialize rWlanInfo */ ++ kalMemSet(&(prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); ++ ++ /* 4 <0.1> reset fgIsBusAccessFailed */ ++ fgIsBusAccessFailed = FALSE; ++ prAdapter->ulSuspendFlag = 0; ++ ++ do { ++ u4Status = nicAllocateAdapterMemory(prAdapter); ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "nicAllocateAdapterMemory Error!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = ALLOC_ADAPTER_MEM_FAIL; ++ break; ++ } ++ ++ prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; ++ ++ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Acquiring LP-OWN %d\n", fgIsResetting); ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++#if !CFG_ENABLE_FULL_PM ++ nicpmSetDriverOwn(prAdapter); ++#endif ++ ++ if (prAdapter->fgIsFwOwn == TRUE) { ++ DBGLOG(INIT, ERROR, "nicpmSetDriverOwn() failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = DRIVER_OWN_FAIL; ++ break; ++ } ++ /* 4 <1> Initialize the Adapter */ ++ u4Status = nicInitializeAdapter(prAdapter); ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "nicInitializeAdapter failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = INIT_ADAPTER_FAIL; ++ break; ++ } ++ ++ /* init wake lock before interrupt enable and tx thread */ ++ KAL_WAKE_LOCK_INIT(prAdapter, &prAdapter->rTxThreadWakeLock, "WLAN TX THREAD"); ++ ++ /* 4 <2> Initialize System Service (MGMT Memory pool and STA_REC) */ ++ nicInitSystemService(prAdapter); ++ ++ /* 4 <3> Initialize Tx */ ++ nicTxInitialize(prAdapter); ++ wlanDefTxPowerCfg(prAdapter); ++ ++ /* 4 <4> Initialize Rx */ ++ nicRxInitialize(prAdapter); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ if (pvFwImageMapFile == NULL) { ++ DBGLOG(INIT, ERROR, "No Firmware found!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = RAM_CODE_DOWNLOAD_FAIL; ++ break; ++ } ++ ++ /* 1. disable interrupt, download is done by polling mode only */ ++ nicDisableInterrupt(prAdapter); ++ ++ /* 2. Initialize Tx Resource to fw download state */ ++ nicTxInitResetResource(prAdapter); ++ ++ /* 3. FW download here */ ++ u4FwLoadAddr = prRegInfo->u4LoadAddress; ++ ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ /* 3a. parse file header for decision of divided firmware download or not */ ++ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; ++ ++ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && ++ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, ++ u4FwImageFileLength - u4CRCOffset)) { ++ fgValidHead = TRUE; ++ } else { ++ fgValidHead = FALSE; ++ } ++ ++ /* 3b. engage divided firmware downloading */ ++ if (fgValidHead == TRUE) { ++ DBGLOG(INIT, TRACE, "wlanAdapterStart(): fgValidHead == TRUE\n"); ++ ++ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { ++ ++#if CFG_START_ADDRESS_IS_1ST_SECTION_ADDR ++ if (i == 0) { ++ prRegInfo->u4StartAddress = prFwHead->arSection[i].u4DestAddr; ++ DBGLOG(INIT, TRACE, ++ "wlanAdapterStart(): FW start address 0x%08x\n", ++ prRegInfo->u4StartAddress); ++ } ++#endif ++ ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ prFwHead->arSection[i].u4DestAddr, ++ prFwHead->arSection[i].u4Length, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ prFwHead->arSection[i].u4DestAddr + j, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset + j) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, ++ "Firmware scatter download failed %d!\n", (int)i); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ ++ /* escape from loop if any pending error occurs */ ++ if (u4Status == WLAN_STATUS_FAILURE) ++ break; ++ } ++ } else ++#endif ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ u4FwLoadAddr, ++ u4FwImageFileLength, ++ (PUINT_8) pvFwImageMapFile) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (i = 0; i < u4FwImageFileLength; i += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImageFileLength) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = u4FwImageFileLength - i; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ u4FwLoadAddr + i, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + i) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ eFailReason = RAM_CODE_DOWNLOAD_FAIL; ++ break; ++ } ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ ++ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Firmware download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++#endif ++ ++ /* 4. send Wi-Fi Start command */ ++ DBGLOG(INIT, INFO, " send Wi-Fi Start command\n"); ++#if CFG_OVERRIDE_FW_START_ADDRESS ++ wlanConfigWifiFunc(prAdapter, TRUE, prRegInfo->u4StartAddress); ++#else ++ wlanConfigWifiFunc(prAdapter, FALSE, 0); ++#endif ++#endif ++ ++ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); ++ /* 4 <5> check Wi-Fi FW asserts ready bit */ ++ i = 0; ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ DBGLOG(INIT, TRACE, "Ready bit asserted\n"); ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = WAIT_FIRMWARE_READY_FAIL; ++ break; ++ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { ++ UINT_32 u4MailBox0; ++ ++ nicGetMailbox(prAdapter, 0, &u4MailBox0); ++ DBGLOG(INIT, ERROR, "Waiting for Ready bit: Timeout, ID=%u\n", ++ (u4MailBox0 & 0x0000FFFF)); ++ u4Status = WLAN_STATUS_FAILURE; ++ eFailReason = WAIT_FIRMWARE_READY_FAIL; ++ break; ++ } ++ i++; ++ kalMsleep(10); ++ } ++ ++ if (u4Status == WLAN_STATUS_SUCCESS) { ++ /* 1. reset interrupt status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ ++ /* 2. reset TX Resource for normal operation */ ++ nicTxResetResource(prAdapter); ++ ++ /* 3. query for permanent address by polling */ ++ wlanQueryPermanentAddress(prAdapter); ++ ++#if (CFG_SUPPORT_NIC_CAPABILITY == 1) ++ /* 4. query for NIC capability */ ++ wlanQueryNicCapability(prAdapter); ++#endif ++ /* 4.1 query for compiler flags */ ++ wlanQueryCompileFlags(prAdapter); ++ ++ /* 5. Override network address */ ++ wlanUpdateNetworkAddress(prAdapter); ++ ++ /* 6. indicate disconnection as default status */ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ } ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ eFailReason = WAIT_FIRMWARE_READY_FAIL; ++ break; ++ } ++ ++ /* OID timeout timer initialize */ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rOidTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) wlanReleasePendingOid, (ULONG) NULL); ++ ++ /* Return Indicated Rfb list timer */ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rReturnIndicatedRfbListTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) wlanReturnIndicatedPacketsTimeOut, (ULONG) NULL); ++ ++ /* Power state initialization */ ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ prAdapter->rAcpiState = ACPI_STATE_D0; ++ ++ /* Online scan option */ ++ if (prRegInfo->fgDisOnlineScan == 0) ++ prAdapter->fgEnOnlineScan = TRUE; ++ else ++ prAdapter->fgEnOnlineScan = FALSE; ++ ++ /* Beacon lost detection option */ ++ if (prRegInfo->fgDisBcnLostDetection != 0) ++ prAdapter->fgDisBcnLostDetection = TRUE; ++ ++ /* Load compile time constant */ ++ prAdapter->rWlanInfo.u2BeaconPeriod = CFG_INIT_ADHOC_BEACON_INTERVAL; ++ prAdapter->rWlanInfo.u2AtimWindow = CFG_INIT_ADHOC_ATIM_WINDOW; ++ ++#if 1 /* set PM parameters */ ++ prAdapter->fgEnArpFilter = prRegInfo->fgEnArpFilter; ++ prAdapter->u4PsCurrentMeasureEn = prRegInfo->u4PsCurrentMeasureEn; ++ ++ prAdapter->u4UapsdAcBmp = prRegInfo->u4UapsdAcBmp; ++ ++ prAdapter->u4MaxSpLen = prRegInfo->u4MaxSpLen; ++ ++ DBGLOG(INIT, TRACE, "[1] fgEnArpFilter:0x%x, u4UapsdAcBmp:0x%x, u4MaxSpLen:0x%x", ++ prAdapter->fgEnArpFilter, prAdapter->u4UapsdAcBmp, prAdapter->u4MaxSpLen); ++ ++ prAdapter->fgEnCtiaPowerMode = FALSE; ++ ++#if CFG_SUPPORT_DBG_POWERMODE ++ prAdapter->fgEnDbgPowerMode = FALSE; ++#endif ++ ++#endif ++ ++ /* MGMT Initialization */ ++ nicInitMGMT(prAdapter, prRegInfo); ++ ++ /* Enable WZC Disassociation */ ++ prAdapter->rWifiVar.fgSupportWZCDisassociation = TRUE; ++ ++ /* Apply Rate Setting */ ++ if ((ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate) < FIXED_RATE_NUM) ++ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate); ++ else ++ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; ++ ++ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) { ++ /* Enable Auto (Long/Short) Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; ++ } else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) ++ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) { ++ /* Force Short Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; ++ } else { ++ /* Force Long Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; ++ } ++ ++ /* Disable Hidden SSID Join */ ++ prAdapter->rWifiVar.fgEnableJoinToHiddenSSID = FALSE; ++ ++ /* Enable Short Slot Time */ ++ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable = TRUE; ++ ++ /* configure available PHY type set */ ++ nicSetAvailablePhyTypeSet(prAdapter); ++ ++#if 1 /* set PM parameters */ ++ { ++#if CFG_SUPPORT_PWR_MGT ++ prAdapter->u4PowerMode = prRegInfo->u4PowerMode; ++ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucNetTypeIndex = ++ NETWORK_TYPE_P2P_INDEX; ++ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile = ENUM_PSP_FAST_SWITCH; ++#else ++ prAdapter->u4PowerMode = ENUM_PSP_CONTINUOUS_ACTIVE; ++#endif ++ ++ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, /* FIXIT */ ++ prAdapter->u4PowerMode, FALSE); ++ } ++ ++#endif ++ ++#if CFG_SUPPORT_NVRAM ++ /* load manufacture data */ ++ wlanLoadManufactureData(prAdapter, prRegInfo); ++#endif ++ ++#ifdef CONFIG_MTK_TC1_FEATURE /* 1 //keep alive packet time change from default 30secs to 20secs. //TC01// */ ++ { ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ ++ rCmdSwCtrl.u4Id = 0x90100000; ++ rCmdSwCtrl.u4Data = 30; ++ DBGLOG(INIT, TRACE, "wlanAdapterStart Keepaliveapcket 0x%x, %d\n", ++ rCmdSwCtrl.u4Id, rCmdSwCtrl.u4Data); ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8) (&rCmdSwCtrl), NULL, 0); ++ } ++#endif ++ ++#if 0 ++ /* Update Auto rate parameters in FW */ ++ nicRlmArUpdateParms(prAdapter, ++ prRegInfo->u4ArSysParam0, ++ prRegInfo->u4ArSysParam1, prRegInfo->u4ArSysParam2, prRegInfo->u4ArSysParam3); ++#endif ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ /* clock gating workaround */ ++ prAdapter->fgIsClockGatingEnabled = FALSE; ++#endif ++ ++ } while (FALSE); ++ ++ if (u4Status == WLAN_STATUS_SUCCESS) { ++ /* restore to hardware default */ ++ HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter); ++ HAL_SET_MAILBOX_READ_CLEAR(prAdapter, FALSE); ++ ++ /* Enable interrupt */ ++ nicEnableInterrupt(prAdapter); ++ ++ } else { ++ /* release allocated memory */ ++ switch (eFailReason) { ++ case WAIT_FIRMWARE_READY_FAIL: ++ DBGLOG(INIT, ERROR, "Wait firmware ready fail, FailReason: %d\n", ++ eFailReason); ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Wait firmware ready fail!]", __func__); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ nicRxUninitialize(prAdapter); ++ nicTxRelease(prAdapter); ++ /* System Service Uninitialization */ ++ nicUninitSystemService(prAdapter); ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case RAM_CODE_DOWNLOAD_FAIL: ++ DBGLOG(INIT, ERROR, "Ram code download fail, FailReason: %d\n", ++ eFailReason); ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Ram code download fail!]", __func__); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ nicRxUninitialize(prAdapter); ++ nicTxRelease(prAdapter); ++ /* System Service Uninitialization */ ++ nicUninitSystemService(prAdapter); ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case INIT_ADAPTER_FAIL: ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case DRIVER_OWN_FAIL: ++ nicReleaseAdapterMemory(prAdapter); ++ break; ++ case ALLOC_ADAPTER_MEM_FAIL: ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return u4Status; ++} /* wlanAdapterStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Uninitialize the adapter ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4Value = 0; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ ++ /* MGMT - unitialization */ ++ nicUninitMGMT(prAdapter); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D0 && ++#if (CFG_CHIP_RESET_SUPPORT == 1) ++ kalIsResetting() == FALSE && ++#endif ++ kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { ++ ++ /* 0. Disable interrupt, this can be done without Driver own */ ++ nicDisableInterrupt(prAdapter); ++ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* 1. Set CMD to FW to tell WIFI to stop (enter power off state) */ ++ /* the command must be issue to firmware even in wlanRemove() */ ++ if (prAdapter->fgIsFwOwn == FALSE && wlanSendNicPowerCtrlCmd(prAdapter, 1) == WLAN_STATUS_SUCCESS) { ++ /* 2. Clear pending interrupt */ ++ i = 0; ++ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { ++ i++; ++ }; ++ ++ /* 3. Wait til RDY bit has been cleaerd */ ++ i = 0; ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if ((u4Value & WCIR_WLAN_READY) == 0) ++ break; ++ else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE ++ || fgIsBusAccessFailed == TRUE || i >= CFG_RESPONSE_POLLING_TIMEOUT) { ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Read WCIR_WLAN_READY fail!]", __func__); ++ break; ++ } ++ i++; ++ kalMsleep(10); ++ } ++ } ++ ++ /* 4. Set Onwership to F/W */ ++ nicpmSetFWOwn(prAdapter, FALSE); ++ ++#if CFG_FORCE_RESET_UNDER_BUS_ERROR ++ if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == TRUE) { ++ /* force acquire firmware own */ ++ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ ++ /* delay for 10ms */ ++ kalMdelay(10); ++ ++ /* force firmware reset via software interrupt */ ++ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WSICR, WSICR_H2D_SW_INT_SET); ++ ++ /* force release firmware own */ ++ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); ++ } ++#endif ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ } ++ ++ nicRxUninitialize(prAdapter); ++ ++ nicTxRelease(prAdapter); ++ ++ /* System Service Uninitialization */ ++ nicUninitSystemService(prAdapter); ++ ++ nicReleaseAdapterMemory(prAdapter); ++ ++#if defined(_HIF_SPI) ++ /* Note: restore the SPI Mode Select from 32 bit to default */ ++ nicRestoreSpiDefMode(prAdapter); ++#endif ++ ++ return u4Status; ++} /* wlanAdapterStop */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by ISR (interrupt). ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \retval TRUE: NIC's interrupt ++* \retval FALSE: Not NIC's interrupt ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl) ++{ ++ ASSERT(prAdapter); ++ ++ if (fgGlobalIntrCtrl) { ++ nicDisableInterrupt(prAdapter); ++ ++ /* wlanIST(prAdapter); */ ++ } ++ ++ return TRUE; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by IST (task_let). ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanIST(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* wake up CONNSYS */ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* handle interrupts */ ++ nicProcessIST(prAdapter); ++ ++ /* re-enable HIF interrupts */ ++ nicEnableInterrupt(prAdapter); ++ ++ /* CONNSYS can decide to sleep */ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will check command queue to find out if any could be dequeued ++* and/or send to HIF to MT6620 ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param prCmdQue Pointer of Command Queue (in Glue Layer) ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue) ++{ ++ WLAN_STATUS rStatus; ++ QUE_T rTempCmdQue, rMergeCmdQue, rStandInCmdQue; ++ P_QUE_T prTempCmdQue, prMergeCmdQue, prStandInCmdQue; ++ P_QUE_ENTRY_T prQueueEntry; ++ P_CMD_INFO_T prCmdInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ ENUM_FRAME_ACTION_T eFrameAction = FRAME_ACTION_DROP_PKT; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(prCmdQue); ++ ++ /* init */ ++ prTempCmdQue = &rTempCmdQue; ++ prMergeCmdQue = &rMergeCmdQue; ++ prStandInCmdQue = &rStandInCmdQue; ++ ++ QUEUE_INITIALIZE(prTempCmdQue); ++ QUEUE_INITIALIZE(prMergeCmdQue); ++ QUEUE_INITIALIZE(prStandInCmdQue); ++ ++ /* 4 <1> Move whole list of CMD_INFO to the temp queue */ ++ /* copy all commands to prTempCmdQue and empty prCmdQue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ ++ /* 4 <2> Dequeue from head and check it is able to be sent */ ++ /* remove the first one */ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ /* check how to handle the command: drop, queue, or tx */ ++ switch (prCmdInfo->eCmdType) { ++ case COMMAND_TYPE_GENERAL_IOCTL: ++ case COMMAND_TYPE_NETWORK_IOCTL: ++ /* command packet will be always sent */ ++ eFrameAction = FRAME_ACTION_TX_PKT; ++ break; ++ ++ case COMMAND_TYPE_SECURITY_FRAME: ++ /* inquire with QM */ ++ eFrameAction = qmGetFrameAction(prAdapter, ++ prCmdInfo->eNetworkType, ++ prCmdInfo->ucStaRecIndex, NULL, FRAME_TYPE_802_1X); ++ break; ++ ++ case COMMAND_TYPE_MANAGEMENT_FRAME: ++ /* inquire with QM */ ++ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); ++ ++ eFrameAction = qmGetFrameAction(prAdapter, ++ prMsduInfo->ucNetworkType, ++ prMsduInfo->ucStaRecIndex, prMsduInfo, FRAME_TYPE_MMPDU); ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++ /* 4 <3> handling upon dequeue result */ ++ if (eFrameAction == FRAME_ACTION_DROP_PKT) { ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) ++ DBGLOG(TX, WARN, "Drop Security frame seqNo=%d\n", ++ prCmdInfo->ucCmdSeqNum); ++ wlanReleaseCommand(prAdapter, prCmdInfo); ++ } else if (eFrameAction == FRAME_ACTION_QUEUE_PKT) { ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) ++ DBGLOG(TX, INFO, "Queue Security frame seqNo=%d\n", ++ prCmdInfo->ucCmdSeqNum); ++ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); ++ } else if (eFrameAction == FRAME_ACTION_TX_PKT) { ++ /* 4 <4> Send the command */ ++ rStatus = wlanSendCommand(prAdapter, prCmdInfo); ++ ++ if (rStatus == WLAN_STATUS_RESOURCES) { ++ /* no more TC4 resource for further transmission */ ++ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); ++ DBGLOG(TX, EVENT, "No TC4 resource to send cmd, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", ++ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, ++ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); ++ break; ++ } else if (rStatus == WLAN_STATUS_PENDING) { ++ /* command packet which needs further handling upon response */ ++ /* i.e. we need to wait for FW's response */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ QUEUE_INSERT_TAIL(&(prAdapter->rPendingCmdQueue), prQueueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ } else { ++ /* send success or fail */ ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ /* send success */ ++ if (prCmdInfo->pfCmdDoneHandler) { ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, ++ prCmdInfo->pucInfoBuffer); ++ } ++ } else { ++ /* send fail */ ++ if (prCmdInfo->fgIsOid) { ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, ++ prCmdInfo->u4SetInfoLen, rStatus); ++ } ++ DBGLOG(TX, WARN, "Send CMD, status=%u, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", ++ rStatus, prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, ++ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); ++ } ++ ++ /* free the command memory */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ } else { ++ ++ /* impossible, wrong eFrameAction */ ++ ASSERT(0); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ /* 4 <3> Merge back to original queue */ ++ /* 4 <3.1> Merge prMergeCmdQue & prTempCmdQue */ ++ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prTempCmdQue); ++ ++ /* 4 <3.2> Move prCmdQue to prStandInQue, due to prCmdQue might differ due to incoming 802.1X frames */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ ++ /* ??? here, prCmdQue shall be empty, why QUEUE_MOVE_ALL ??? */ ++ QUEUE_MOVE_ALL(prStandInCmdQue, prCmdQue); ++ ++ /* 4 <3.3> concatenate prStandInQue to prMergeCmdQue */ ++ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prStandInCmdQue); ++ ++ /* 4 <3.4> then move prMergeCmdQue to prCmdQue */ ++ QUEUE_MOVE_ALL(prCmdQue, prMergeCmdQue); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanProcessCommandQueue() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will take CMD_INFO_T which carry some information of ++* incoming OID and notify the NIC_TX to send CMD. ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param prCmdInfo Pointer of P_CMD_INFO_T ++* ++* \retval WLAN_STATUS_SUCCESS : CMD was written to HIF and be freed(CMD Done) immediately. ++* \retval WLAN_STATUS_RESOURCE : No resource for current command, need to wait for previous ++* frame finishing their transmission. ++* \retval WLAN_STATUS_FAILURE : Get failure while access HIF or been rejected. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ UINT_8 ucTC; /* "Traffic Class" SW(Driver) resource classification */ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ BOOLEAN pfgIsSecOrMgmt = FALSE; ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* init */ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* DbgPrint("wlanSendCommand()\n"); */ ++ /* */ ++ /* */ ++#if DBG && 0 ++ LOG_FUNC("wlanSendCommand()\n"); ++ LOG_FUNC("CmdType %u NetworkType %u StaRecIndex %u Oid %u CID 0x%x SetQuery %u NeedResp %u CmdSeqNum %u\n", ++ prCmdInfo->eCmdType, ++ prCmdInfo->eNetworkType, ++ prCmdInfo->ucStaRecIndex, ++ prCmdInfo->fgIsOid, ++ prCmdInfo->ucCID, prCmdInfo->fgSetQuery, prCmdInfo->fgNeedResp, prCmdInfo->ucCmdSeqNum); ++#endif ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ ++ do { ++ /* <0> card removal check */ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ rStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ /* <1> Normal case of sending CMD Packet */ ++ if (!prCmdInfo->fgDriverDomainMCR) { ++ /* <1.1> Assign Traffic Class(TC) = TC4. */ ++ ucTC = TC4_INDEX; ++ ++ if ((prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) || ++ (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME)) ++ pfgIsSecOrMgmt = TRUE; ++ ++ /* <1.2> Check if pending packet or resource was exhausted */ ++ rStatus = nicTxAcquireResource(prAdapter, ucTC, pfgIsSecOrMgmt); ++ if (rStatus == WLAN_STATUS_RESOURCES) { ++ DbgPrint("NO Resource:%d\n", ucTC); ++ break; ++ } ++ /* <1.3> Forward CMD_INFO_T to NIC Layer */ ++ rStatus = nicTxCmd(prAdapter, prCmdInfo, ucTC); ++ ++ /* <1.4> Set Pending in response to Query Command/Need Response */ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) ++ rStatus = WLAN_STATUS_PENDING; ++ } ++ } ++ /* <2> "Special case" for access Driver Domain MCR */ ++ else { ++ ++ P_CMD_ACCESS_REG prCmdAccessReg; ++ ++ prCmdAccessReg = (P_CMD_ACCESS_REG) (prCmdInfo->pucInfoBuffer + CMD_HDR_SIZE); ++ ++ if (prCmdInfo->fgSetQuery) { ++ /* address is in DWORD unit */ ++ HAL_MCR_WR(prAdapter, (prCmdAccessReg->u4Address & BITS(2, 31)), ++ prCmdAccessReg->u4Data); ++ } else { ++ P_CMD_ACCESS_REG prEventAccessReg; ++ UINT_32 u4Address; ++ ++ u4Address = prCmdAccessReg->u4Address; ++ prEventAccessReg = (P_CMD_ACCESS_REG) prCmdInfo->pucInfoBuffer; ++ prEventAccessReg->u4Address = u4Address; ++ /* address is in DWORD unit */ ++ HAL_MCR_RD(prAdapter, prEventAccessReg->u4Address & BITS(2, 31), ++ &prEventAccessReg->u4Data); ++ } ++ } ++ ++ } while (FALSE); ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ nicEnableClockGating(prAdapter); ++#endif ++ ++ return rStatus; ++} /* end of wlanSendCommand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This function will release thd CMD_INFO upon its attribution ++ * ++ * \param prAdapter Pointer of Adapter Data Structure ++ * \param prCmdInfo Pointer of CMD_INFO_T ++ * ++ * \return (none) ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ switch (prCmdInfo->eCmdType) { ++ case COMMAND_TYPE_GENERAL_IOCTL: ++ case COMMAND_TYPE_NETWORK_IOCTL: ++ if (prCmdInfo->fgIsOid) { ++ /* for OID command, we need to do complete() to wake up kalIoctl() */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_FAILURE); ++ } ++ break; ++ ++ case COMMAND_TYPE_SECURITY_FRAME: ++ /* free packets in kalSecurityFrameSendComplete() */ ++ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); ++ break; ++ ++ case COMMAND_TYPE_MANAGEMENT_FRAME: ++ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; ++ ++ /* invoke callbacks */ ++ if (prMsduInfo->pfTxDoneHandler != NULL) ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); ++ ++ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ break; ++ ++ default: ++ /* impossible, shall not be here */ ++ ASSERT(0); ++ break; ++ } ++ ++ /* free command buffer and return the command header to command pool */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++} /* end of wlanReleaseCommand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will search the CMD Queue to look for the pending OID and ++* compelete it immediately when system request a reset. ++* ++* \param prAdapter ointer of Adapter Data Structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("wlanReleasePendingOid"); ++ ++ ASSERT(prAdapter); ++ ++ DBGLOG(OID, ERROR, "OID Timeout! Releasing pending OIDs ..\n"); ++ ++ do { ++ /* 1: Handle OID commands in pending queue */ ++ /* Clear Pending OID in prAdapter->rPendingCmdQueue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ /* move all pending commands to prTempCmdQue and empty prCmdQue */ ++ prCmdQue = &prAdapter->rPendingCmdQueue; ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ /* get first pending command */ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->fgIsOid) { ++ if (prCmdInfo->pfCmdTimeoutHandler) { ++ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); ++ } else { ++ /* send complete() to wake up kalIoctl() */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++ } ++ ++ /* free command memory */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } else { ++ /* nothing to do so re-queue it to prCmdQue */ ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ /* 2: Clear pending OID staying in command queue */ ++ kalOidCmdClearance(prAdapter->prGlueInfo); ++ ++ /* 3: Do complete(), do we need this? because we have completed in kalOidComplete */ ++ kalOidClearance(prAdapter->prGlueInfo); ++ ++ } while (FALSE); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will search the CMD Queue to look for the pending CMD/OID for specific ++* NETWORK TYPE and compelete it immediately when system request a reset. ++* ++* \param prAdapter ointer of Adapter Data Structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ /* only free commands from the network interface, AIS, P2P, or BOW */ ++ ++ do { ++ /* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ prCmdQue = &prAdapter->rPendingCmdQueue; ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ DBGLOG(P2P, TRACE, "Pending CMD for Network Type:%d\n", prCmdInfo->eNetworkType); ++ ++ if (prCmdInfo->eNetworkType == eNetworkType) { ++ if (prCmdInfo->pfCmdTimeoutHandler) { ++ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); ++ } else ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ } while (FALSE); ++ ++} /* wlanReleasePendingCMDbyNetwork */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return the packet buffer and reallocate one to the RFB ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param pvPacket Pointer of returned packet ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("wlanReturnPacket"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ /* free the packet */ ++ if (pvPacket) { ++ kalPacketFree(prAdapter->prGlueInfo, pvPacket); ++ RX_ADD_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT, 1); ++#if CFG_NATIVE_802_11 ++ if (GLUE_TEST_FLAG(prAdapter->prGlueInfo, GLUE_FLAG_HALT)) { ++ /*Todo:: nothing*/ ++ /*Todo:: nothing*/ ++ } ++#endif ++ } ++ ++ /* free the packet control block */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ if (!prSwRfb) { ++ ASSERT(0); ++ return; ++ } ++ ++ if (nicRxSetupRFB(prAdapter, prSwRfb)) { ++ ASSERT(0); ++ /* return; // Don't return here or it would lost SwRfb --kc */ ++ if (!timerPendingTimer(&prAdapter->rReturnIndicatedRfbListTimer)) { ++ DBGLOG(RX, WARN, ++ "wlanReturnPacket, Start ReturnIndicatedRfbList Timer (%ds)\n", ++ RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); ++ cnmTimerStartTimer(prAdapter, &prAdapter->rReturnIndicatedRfbListTimer, ++ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); ++ } ++ } ++ nicRxReturnRFB(prAdapter, prSwRfb); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return the indicated packet buffer and reallocate one to the RFB ++* ++* \param prAdapter Pointer of Adapter Data Structure ++* \param pvPacket Pointer of returned packet ++* ++* \retval WLAN_STATUS_SUCCESS: Success ++* \retval WLAN_STATUS_FAILURE: Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_QUE_T prQueList; ++ ++ DEBUGFUNC("wlanReturnIndicatedPacketsTimeOut"); ++ DBGLOG(RX, WARN, "wlanReturnIndicatedPacketsTimeOut"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ prQueList = &prRxCtrl->rIndicatedRfbList; ++ DBGLOG(RX, WARN, "IndicatedRfbList num = %u\n", (unsigned int)prQueList->u4NumElem); ++ ++ while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rIndicatedRfbList)) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (nicRxSetupRFB(prAdapter, prSwRfb)) { ++ status = WLAN_STATUS_RESOURCES; ++ ASSERT(0); ++ } ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ if (status == WLAN_STATUS_RESOURCES) ++ break; ++ } ++ if (status == WLAN_STATUS_RESOURCES) { ++ DBGLOG(RX, WARN, "Start ReturnIndicatedRfbList Timer (%ds)\n", RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); ++ /* restart timer */ ++ cnmTimerStartTimer(prAdapter, ++ &prAdapter->rReturnIndicatedRfbListTimer, ++ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a required function that returns information about ++* the capabilities and status of the driver and/or its network adapter. ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] pfnOidQryHandler Function pointer for the OID query handler. ++* \param[IN] pvInfoBuf Points to a buffer for return the query information. ++* \param[IN] u4QueryBufferLen Specifies the number of bytes at pvInfoBuf. ++* \param[OUT] pu4QueryInfoLen Points to the number of bytes it written or is needed. ++* ++* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanQueryInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfnOidQryHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen) ++{ ++ WLAN_STATUS status = WLAN_STATUS_FAILURE; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QryInfoLen); ++ ++ /* ignore any OID request after connected, under PS current measurement mode */ ++ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for ++ * blocking OIDs during current measurement ++ */ ++ if (prAdapter->u4PsCurrentMeasureEn && ++ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) ++ return WLAN_STATUS_SUCCESS; ++#if 1 ++ /* most OID handler will just queue a command packet */ ++ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); ++#else ++ if (wlanIsHandlerNeedHwAccess(pfnOidQryHandler, FALSE)) { ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* Reset sleepy state */ ++ if (prAdapter->fgWiFiInSleepyState == TRUE) ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ ++ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ } else ++ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); ++#endif ++ ++ return status; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a required function that allows bound protocol drivers, ++* or NDIS, to request changes in the state information that the miniport ++* maintains for particular object identifiers, such as changes in multicast ++* addresses. ++* ++* \param[IN] prAdapter Pointer to the Glue info structure. ++* \param[IN] pfnOidSetHandler Points to the OID set handlers. ++* \param[IN] pvInfoBuf Points to a buffer containing the OID-specific data for the set. ++* \param[IN] u4InfoBufLen Specifies the number of bytes at prSetBuffer. ++* \param[OUT] pu4SetInfoLen Points to the number of bytes it read or is needed. ++* ++* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanSetInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfnOidSetHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status = WLAN_STATUS_FAILURE; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* ignore any OID request after connected, under PS current measurement mode */ ++ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking ++ * OIDs during current measurement ++ */ ++ if (prAdapter->u4PsCurrentMeasureEn && ++ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) ++ return WLAN_STATUS_SUCCESS; ++#if 1 ++ /* most OID handler will just queue a command packet ++ * for power state transition OIDs, handler will acquire power control by itself ++ */ ++ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); ++#else ++ if (wlanIsHandlerNeedHwAccess(pfnOidSetHandler, TRUE)) { ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* Reset sleepy state */ ++ if (prAdapter->fgWiFiInSleepyState == TRUE) ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ ++ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ } else { ++ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); ++ } ++#endif ++ ++ return status; ++} ++ ++#if CFG_SUPPORT_WAPI ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a used to query driver's config wapi mode or not ++* ++* \param[IN] prAdapter Pointer to the Glue info structure. ++* ++* \retval TRUE for use wapi mode ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->rWifiVar.rConnSettings.fgWapiMode; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to set RX filter to Promiscuous Mode. ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] fgEnablePromiscuousMode Enable/ disable RX Promiscuous Mode. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode) ++{ ++ ASSERT(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to set RX filter to allow to receive ++* broadcast address packets. ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast) ++{ ++ ASSERT(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to send out CMD_NIC_POWER_CTRL command packet ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] ucPowerMode refer to CMD/EVENT document ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode) ++{ ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucTC, ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* 1. Prepare CMD */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL))); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* 2.1 increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* 2.2 Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL)); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_NIC_POWER_CTRL; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_NIC_POWER_CTRL); ++ ++ /* 2.3 Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ kalMemZero(prWifiCmd->aucBuffer, sizeof(CMD_NIC_POWER_CTRL)); ++ ((P_CMD_NIC_POWER_CTRL) (prWifiCmd->aucBuffer))->ucPowerMode = ucPowerMode; ++ ++ /* 3. Issue CMD for entering specific power mode */ ++ ucTC = TC4_INDEX; ++ ++ while (1) { ++ /* 3.0 Removal check */ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ /* 3.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ ++ /* wait and poll tx resource */ ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ continue; ++ } ++ /* 3.2 Send CMD Info Packet */ ++ if (nicTxCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Fail to transmit CMD_NIC_POWER_CTRL command\n"); ++ status = WLAN_STATUS_FAILURE; ++ } ++ ++ break; ++ }; ++ ++ /* 4. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ /* 5. Add flag */ ++ if (ucPowerMode == 1) ++ prAdapter->fgIsEnterD3ReqIssued = TRUE; ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to check if it is RF test mode and ++* the OID is allowed to be called or not ++* ++* \param[IN] prAdapter Pointer to the Adapter structure. ++* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) ++{ ++ PFN_OID_HANDLER_FUNC *apfnOidHandlerAllowedInRFTest; ++ UINT_32 i; ++ UINT_32 u4NumOfElem; ++ ++ if (fgSetInfo) { ++ apfnOidHandlerAllowedInRFTest = apfnOidSetHandlerAllowedInRFTest; ++ u4NumOfElem = sizeof(apfnOidSetHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); ++ } else { ++ apfnOidHandlerAllowedInRFTest = apfnOidQueryHandlerAllowedInRFTest; ++ u4NumOfElem = sizeof(apfnOidQueryHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); ++ } ++ ++ for (i = 0; i < u4NumOfElem; i++) { ++ if (apfnOidHandlerAllowedInRFTest[i] == pfnOidHandler) ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to download FW image in an aggregated way ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) ++{ ++#if defined(MT6620) || defined(MT6628) ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; ++ UINT_8 ucTC, ucCmdSeqNum; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_32 u4PktCnt, u4Offset, u4Length; ++ UINT_32 u4TotalLength; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucImgSecBuf); ++ ++ pucOutputBuf = prAdapter->rTxCtrl.pucTxCoalescingBufPtr; ++ ++ DEBUGFUNC("wlanImageSectionDownloadAggregated"); ++ ++ if (u4ImgSecSize == 0) ++ return WLAN_STATUS_SUCCESS; ++ /* 1. Allocate CMD Info Packet and Pre-fill Headers */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, ++ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + ++ CMD_PKT_SIZE_FOR_IMAGE); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + CMD_PKT_SIZE_FOR_IMAGE; ++ ++ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->ucEtherTypeOffset = 0; ++ prInitHifTxHeader->ucCSflags = 0; ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; ++ ++ /* 4. Setup CMD_DOWNLOAD_BUF */ ++ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); ++ prInitCmdDownloadBuf->u4DataMode = 0 ++#if CFG_ENABLE_FW_ENCRYPTION ++ | DOWNLOAD_BUF_ENCRYPTION_MODE ++#endif ++ ; ++ ++ /* 5.0 reset loop control variable */ ++ u4TotalLength = 0; ++ u4Offset = u4PktCnt = 0; ++ ++ /* 5.1 main loop for maximize transmission count per access */ ++ while (u4Offset < u4ImgSecSize) { ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_SUCCESS) { ++ /* 5.1.1 calculate u4Length */ ++ if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < u4ImgSecSize) ++ u4Length = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4Length = u4ImgSecSize - u4Offset; ++ ++ /* 5.1.1 increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ /* 5.1.2 update HIF TX hardware header */ ++ prInitHifTxHeader->u2TxByteCount = ++ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4Length); ++ ++ /* 5.1.3 fill command header */ ++ prInitCmdDownloadBuf->u4Address = u4DestAddr + u4Offset; ++ prInitCmdDownloadBuf->u4Length = u4Length; ++ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf + u4Offset, u4Length); ++ ++ /* 5.1.4.1 copy header to coalescing buffer */ ++ kalMemCopy(pucOutputBuf + u4TotalLength, ++ (PVOID) prCmdInfo->pucInfoBuffer, ++ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF)); ++ ++ /* 5.1.4.2 copy payload to coalescing buffer */ ++ kalMemCopy(pucOutputBuf + u4TotalLength + sizeof(INIT_HIF_TX_HEADER_T) + ++ sizeof(INIT_CMD_DOWNLOAD_BUF), pucImgSecBuf + u4Offset, u4Length); ++ ++ /* 5.1.4.3 update length and other variables */ ++ u4TotalLength += ++ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4Length); ++ u4Offset += u4Length; ++ u4PktCnt++; ++ ++ if (u4Offset < u4ImgSecSize) ++ continue; ++ } else if (u4PktCnt == 0) { ++ /* no resource, so get some back */ ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ } ++ ++ if (u4PktCnt != 0) { ++ /* start transmission */ ++ HAL_WRITE_TX_PORT(prAdapter, ++ 0, ++ u4TotalLength, (PUINT_8) pucOutputBuf, prAdapter->u4CoalescingBufCachedSize); ++ ++ /* reset varaibles */ ++ u4PktCnt = 0; ++ u4TotalLength = 0; ++ } ++ } ++ ++ /* 8. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++ ++#else ++#error "Only MT6620/MT6628/MT6582 supports firmware download in an aggregated way" ++ ++ return WLAN_STATUS_FAILURE; ++ ++#endif ++} ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to download FW image. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; ++ UINT_8 ucTC, ucCmdSeqNum; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucImgSecBuf); ++ ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE); ++ ++ DEBUGFUNC("wlanImageSectionDownload"); ++ ++ if (u4ImgSecSize == 0) ++ return WLAN_STATUS_SUCCESS; ++ /* 1. Allocate CMD Info Packet and its Buffer. */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, ++ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4ImgSecSize); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4ImgSecSize; ++ ++ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* 4. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ /* 5. Setup CMD_DOWNLOAD_BUF */ ++ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); ++ prInitCmdDownloadBuf->u4Address = u4DestAddr; ++ prInitCmdDownloadBuf->u4Length = u4ImgSecSize; ++ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf, u4ImgSecSize); ++ ++ prInitCmdDownloadBuf->u4DataMode = 0 ++#if CFG_ENABLE_FW_DOWNLOAD_ACK ++ | DOWNLOAD_BUF_ACK_OPTION /* ACK needed */ ++#endif ++#if CFG_ENABLE_FW_ENCRYPTION ++ | DOWNLOAD_BUF_ENCRYPTION_MODE ++#endif ++ ; ++ ++ kalMemCopy(prInitCmdDownloadBuf->aucBuffer, pucImgSecBuf, u4ImgSecSize); ++ ++ /* 6. Send FW_Download command */ ++ while (1) { ++ /* 6.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ continue; ++ } ++ /* 6.2 Send CMD Info Packet */ ++ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); ++ } ++ ++ break; ++ }; ++ ++#if CFG_ENABLE_FW_DOWNLOAD_ACK ++ /* 7. Wait for INIT_EVENT_ID_CMD_RESULT */ ++ u4Status = wlanImageSectionDownloadStatus(prAdapter, ucCmdSeqNum); ++#endif ++ ++ /* 8. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++} ++ ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to confirm previously firmware download is done without error ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR)]; ++ UINT_32 u4RxPktLength; ++ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; ++ P_INIT_EVENT_PENDING_ERROR prEventPendingError; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_8 ucTC, ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanImageQueryStatus"); ++ ++ /* 1. Allocate CMD Info Packet and it Buffer. */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ kalMemZero(prCmdInfo, sizeof(INIT_HIF_TX_HEADER_T)); ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T); ++ ++ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* 4. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_QUERY_PENDING_ERROR; ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ /* 5. Send command */ ++ while (1) { ++ /* 5.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ continue; ++ } ++ /* 5.2 Send CMD Info Packet */ ++ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); ++ } ++ ++ break; ++ }; ++ ++ /* 6. Wait for INIT_EVENT_ID_PENDING_ERROR */ ++ do { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else if (nicRxWaitResponse(prAdapter, ++ 0, ++ aucBuffer, ++ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR), ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; ++ ++ /* EID / SeqNum check */ ++ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_PENDING_ERROR) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ prEventPendingError = ++ (P_INIT_EVENT_PENDING_ERROR) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); ++ if (prEventPendingError->ucStatus != 0) { /* 0 for download success */ ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ u4Status = WLAN_STATUS_SUCCESS; ++ } ++ } ++ } ++ } while (FALSE); ++ ++ /* 7. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++} ++ ++#else ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to confirm the status of ++* previously downloaded firmware scatter ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ucCmdSeqNum Sequence number of previous firmware scatter ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum) ++{ ++ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT)]; ++ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; ++ P_INIT_EVENT_CMD_RESULT prEventCmdResult; ++ UINT_32 u4RxPktLength; ++ WLAN_STATUS u4Status; ++ ++ ASSERT(prAdapter); ++ ++ do { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ DBGLOG(INIT, ERROR, "kalIsCardRemoved or fgIsBusAccessFailed\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } else if (nicRxWaitResponse(prAdapter, ++ 0, ++ aucBuffer, ++ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT),/* 4B + 4B */ ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "nicRxWaitResponse fail\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; ++ ++ /* EID / SeqNum check */ ++ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT) { ++ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Check EID error!]", __func__); ++ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { ++ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucSeqNum != ucCmdSeqNum\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ g_IsNeedDoChipReset = 1; ++ kalSendAeeWarning("[Check SeqNum error!]", __func__); ++ } else { ++ prEventCmdResult = ++ (P_INIT_EVENT_CMD_RESULT) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); ++ if (prEventCmdResult->ucStatus != 0) { /* 0 for download success */ ++ /* ++ 0: success ++ 1: rejected by invalid param ++ 2: rejected by incorrect CRC ++ 3: rejected by decryption failure ++ 4: unknown CMD ++ */ ++ DBGLOG(INIT, ERROR, "Read Response status error = %d\n", ++ prEventCmdResult->ucStatus); ++ u4Status = WLAN_STATUS_FAILURE; ++ } else { ++ u4Status = WLAN_STATUS_SUCCESS; ++ } ++ } ++ } ++ } while (FALSE); ++ ++ return u4Status; ++} ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to start FW normal operation. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; ++ P_INIT_CMD_WIFI_START prInitCmdWifiStart; ++ UINT_8 ucTC, ucCmdSeqNum; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanConfigWifiFunc"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer. */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ kalMemZero(prCmdInfo->pucInfoBuffer, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); ++ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START); ++ ++ /* 2. Always use TC0 */ ++ ucTC = TC0_INDEX; ++ ++ /* 3. increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* 4. Setup common CMD Info Packet */ ++ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); ++ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_WIFI_START; ++ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; ++ ++ prInitCmdWifiStart = (P_INIT_CMD_WIFI_START) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); ++ prInitCmdWifiStart->u4Override = (fgEnable == TRUE ? 1 : 0); ++ prInitCmdWifiStart->u4Address = u4StartAddress; ++ ++ /* 5. Seend WIFI start command */ ++ while (1) { ++ /* 5.1 Acquire TX Resource */ ++ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { ++ ++ /* wait and poll tx resource */ ++ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); ++ break; ++ } ++ ++ continue; ++ } ++ /* 5.2 Send CMD Info Packet */ ++ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { ++ u4Status = WLAN_STATUS_FAILURE; ++ DBGLOG(INIT, ERROR, "Fail to transmit WIFI start command\n"); ++ } ++ ++ break; ++ }; ++ ++ /* 6. Free CMD Info Packet. */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate CRC32 checksum ++* ++* @param buf Pointer to the data. ++* @param len data length ++* ++* @return crc32 value ++*/ ++/*----------------------------------------------------------------------------*/ ++static const UINT_32 crc32_ccitt_table[256] = { ++ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, ++ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, ++ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, ++ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, ++ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, ++ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, ++ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, ++ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, ++ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, ++ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, ++ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, ++ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, ++ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, ++ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, ++ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, ++ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, ++ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, ++ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, ++ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, ++ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, ++ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, ++ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, ++ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, ++ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, ++ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, ++ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, ++ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, ++ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, ++ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, ++ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, ++ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, ++ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, ++ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, ++ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, ++ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, ++ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, ++ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, ++ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, ++ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, ++ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, ++ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, ++ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, ++ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, ++ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, ++ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, ++ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, ++ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, ++ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, ++ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, ++ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, ++ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, ++ 0x2d02ef8d ++ }; ++ ++UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len) ++{ ++ UINT_32 i, crc32 = 0xFFFFFFFF; ++ ++ for (i = 0; i < len; i++) ++ crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8); ++ ++ return ~crc32; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to process queued RX packets ++* ++* @param prAdapter Pointer to the Adapter structure. ++* prSwRfbListHead Pointer to head of RX packets link list ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) ++{ ++ P_SW_RFB_T prSwRfb, prNextSwRfb; ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfbListHead); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ prSwRfb = prSwRfbListHead; ++ ++ do { ++ /* save next first */ ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); ++ ++ switch (prSwRfb->eDst) { ++ case RX_PKT_DESTINATION_HOST: ++ /* to host */ ++ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_FORWARD: ++ /* need ot forward */ ++ nicRxProcessForwardPkt(prAdapter, prSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: ++ /* to host and forward */ ++ nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_NULL: ++ /* free it */ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ break; ++ ++ default: ++ break; ++ } ++ ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4DequeuedCnt++; ++#endif ++ ++ /* check next queued packet */ ++ prSwRfb = prNextSwRfb; ++ } while (prSwRfb); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to purge queued TX packets ++* by indicating failure to OS and returned to free list ++* ++* @param prAdapter Pointer to the Adapter structure. ++* prMsduInfoListHead Pointer to head of TX packets link list ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfoListHead); ++ ++ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); ++ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if the OID handler needs timeout ++* ++* @param prAdapter Pointer to the Adapter structure. ++* pfnOidHandler Pointer to the OID handler ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler) ++{ ++ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOTimeoutCheck; ++ UINT_32 i; ++ UINT_32 u4NumOfElem; ++ ++ apfnOidHandlerWOTimeoutCheck = apfnOidWOTimeoutCheck; ++ u4NumOfElem = sizeof(apfnOidWOTimeoutCheck) / sizeof(PFN_OID_HANDLER_FUNC); ++ ++ /* skip some OID timeout checks ? */ ++ for (i = 0; i < u4NumOfElem; i++) { ++ if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler) ++ return FALSE; ++ } ++ ++ /* set timer if need timeout check */ ++ /* cnmTimerStartTimer(prAdapter, */ ++ /* &(prAdapter->rOidTimeoutTimer), */ ++ /* 1000); */ ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rOidTimeoutTimer), 2000); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to clear any pending OID timeout check ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rOidTimeoutTimer)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update network address in firmware domain ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return WLAN_STATUS_FAILURE The request could not be processed ++* WLAN_STATUS_PENDING The request has been queued for later processing ++* WLAN_STATUS_SUCCESS The request has been processed ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter) ++{ ++ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ PARAM_MAC_ADDRESS rMacAddr = {0}; ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_BASIC_CONFIG prCmdBasicConfig; ++ UINT_32 u4SysTime; ++ ++ DEBUGFUNC("wlanUpdateNetworkAddress"); ++ ++ ASSERT(prAdapter); ++ ++ if (kalRetrieveNetworkAddress(prAdapter->prGlueInfo, &rMacAddr) == FALSE || IS_BMCAST_MAC_ADDR(rMacAddr) ++ || EQUAL_MAC_ADDR(aucZeroMacAddr, rMacAddr)) { ++ /* eFUSE has a valid address, don't do anything */ ++ if (prAdapter->fgIsEmbbededMacAddrValid == TRUE) { ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, INFO, "Using embedded MAC address"); ++#endif ++ return WLAN_STATUS_SUCCESS; ++ } ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, TRACE, "Using dynamically generated MAC address"); ++#endif ++ /* dynamic generate */ ++ u4SysTime = kalGetTimeTick(); ++ ++ rMacAddr[0] = 0x00; ++ rMacAddr[1] = 0x08; ++ rMacAddr[2] = 0x22; ++ ++ kalMemCopy(&rMacAddr[3], &u4SysTime, 3); ++ } else { ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, INFO, "Using host-supplied MAC address"); ++#endif ++ } ++ ++ /* allocate command memory */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* configure CMD_BASIC_CONFIG */ ++ prCmdBasicConfig = (P_CMD_BASIC_CONFIG) (prWifiCmd->aucBuffer); ++ kalMemCopy(&(prCmdBasicConfig->rMyMacAddr), &rMacAddr, PARAM_MAC_ADDR_LEN); ++ prCmdBasicConfig->ucNative80211 = 0; ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum = 0; ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum = 0; ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(2); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(1); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) ++ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(0); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(2); ++ ++ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(1); ++ ++ if (prAdapter->u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) ++ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(0); ++#endif ++ ++ /* send the command to FW */ ++ if (wlanSendCommand(prAdapter, prCmdInfo) == WLAN_STATUS_RESOURCES) { ++ ++ /* backup the command to wait response */ ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryAddress; ++ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ return WLAN_STATUS_PENDING; ++ } ++ /* send ok without response */ ++ nicCmdEventQueryAddress(prAdapter, prCmdInfo, (PUINT_8) prCmdBasicConfig); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if the device is in RF test mode ++* ++* @param pfnOidHandler Pointer to the OID handler ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->fgTestMode; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to identify 802.1x and Bluetooth-over-Wi-Fi ++* security frames, and queued into command queue for strict ordering ++* due to 802.1x frames before add-key OIDs are not to be encrypted ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prPacket Pointer of native packet ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket) ++{ ++ UINT_8 ucPriorityParam; ++ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; ++ BOOLEAN fgIs1x = FALSE; ++ BOOLEAN fgIsPAL = FALSE; ++ UINT_32 u4PacketLen; ++ ULONG u4SysTime; ++ UINT_8 ucNetworkType; ++ P_CMD_INFO_T prCmdInfo; ++ UINT_8 ucCmdSeqNo = 0; ++ ++ /* 1x data packets */ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prPacket); ++ ++ /* retrieve some information for packet classification */ ++ if (kalQoSFrameClassifierAndPacketInfo(prAdapter->prGlueInfo, ++ prPacket, ++ &ucPriorityParam, ++ &u4PacketLen, ++ aucEthDestAddr, ++ &fgIs1x, ++ &fgIsPAL, ++ &ucNetworkType, ++ &ucCmdSeqNo) == TRUE) { ++ /* almost TRUE except frame length < 14B */ ++ ++ if (fgIs1x == FALSE) ++ return FALSE; ++ ++ /* get a free command entry */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ if (prCmdInfo) { ++ P_STA_RECORD_T prStaRec; ++ ++ /* fill arrival time */ ++ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); ++ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); ++ ++ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); ++ ++ prCmdInfo->eCmdType = COMMAND_TYPE_SECURITY_FRAME; ++ prCmdInfo->u2InfoBufLen = (UINT_16) u4PacketLen; ++ prCmdInfo->pucInfoBuffer = NULL; ++ prCmdInfo->prPacket = prPacket; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNo; ++#if 0 ++ prCmdInfo->ucStaRecIndex = qmGetStaRecIdx(prAdapter, ++ aucEthDestAddr, ++ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType); ++#endif ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType, ++ aucEthDestAddr); ++ if (prStaRec) ++ prCmdInfo->ucStaRecIndex = prStaRec->ucIndex; ++ else ++ prCmdInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; ++ ++ prCmdInfo->eNetworkType = (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType; ++ prCmdInfo->pfCmdDoneHandler = wlanSecurityFrameTxDone; ++ prCmdInfo->pfCmdTimeoutHandler = wlanSecurityFrameTxTimeout; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ ++ /* ++ queue the 1x packet and we will send the packet to CONNSYS by ++ using command queue ++ */ ++ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* TRUE: means we have already handled it in the function */ ++ return TRUE; ++ } ++ ++ /* no memory, why assert ? can skip the packet ? */ ++ ASSERT(0); ++ return FALSE; ++ } ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi ++* security frames has been sent to firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prCmdInfo Pointer of CMD_INFO_T ++* @param pucEventBuf meaningless, only for API compatibility ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->eNetworkType == NETWORK_TYPE_AIS_INDEX && ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure) { ++ ++ /* AIS counter measure so change RSN FSM to SEND_DEAUTH state */ ++ P_STA_RECORD_T prSta = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); ++ ++ if (prSta) { ++ kalMsleep(10); ++ secFsmEventEapolTxDone(prAdapter, prSta, TX_RESULT_SUCCESS); ++ } ++ } ++ ++ /* free the packet */ ++ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_SUCCESS); ++ DBGLOG(TX, INFO, "Security frame tx done, SeqNum: %d\n", prCmdInfo->ucCmdSeqNum); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi ++* security frames has failed sending to firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prCmdInfo Pointer of CMD_INFO_T ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* free the packet */ ++ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called before AIS is starting a new scan ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter) ++{ ++ BOOLEAN fgKeepCurrOne = FALSE; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ /* clear scanning result except current one */ ++ /* copy current one to prAdapter->rWlanInfo.arScanResult[0] */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { ++ fgKeepCurrOne = TRUE; ++ ++ if (i != 0) { ++ /* copy structure */ ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[0]), ++ &(prAdapter->rWlanInfo.arScanResult[i]), ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ } ++ ++ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { ++ if (prAdapter->rWlanInfo.apucScanResultIEs[i] != ++ &(prAdapter->rWlanInfo.aucScanIEBuf[0])) { ++ /* move IEs to head */ ++ kalMemCopy(prAdapter->rWlanInfo.aucScanIEBuf, ++ prAdapter->rWlanInfo.apucScanResultIEs[i], ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength); ++ } ++ /* modify IE pointer */ ++ prAdapter->rWlanInfo.apucScanResultIEs[0] = ++ &(prAdapter->rWlanInfo.aucScanIEBuf[0]); ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[0] = NULL; ++ } ++ ++ break; ++ } ++ } ++ } ++ ++ if (fgKeepCurrOne == TRUE) { ++ prAdapter->rWlanInfo.u4ScanResultNum = 1; ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage = ALIGN_4(prAdapter->rWlanInfo.arScanResult[0].u4IELength); ++ } else { ++ prAdapter->rWlanInfo.u4ScanResultNum = 0; ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage = 0; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when AIS received a beacon timeout event ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param arBSSID MAC address of the specified BSS ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID) ++{ ++ UINT_32 i, j, u4IELength = 0, u4IEMoveLength; ++ PUINT_8 pucIEPtr; ++ ++ ASSERT(prAdapter); ++ ++ /* clear the scanning result for arBSSID */ ++ i = 0; ++ while (1) { ++ if (i >= prAdapter->rWlanInfo.u4ScanResultNum) ++ break; ++ ++ if (EQUAL_MAC_ADDR(arBSSID, prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { ++ ++ /* backup current IE length */ ++ u4IELength = ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4IELength); ++ pucIEPtr = prAdapter->rWlanInfo.apucScanResultIEs[i]; ++ ++ /* removed from middle */ ++ for (j = i + 1; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[j - 1]), ++ &(prAdapter->rWlanInfo.arScanResult[j]), ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[j - 1] = ++ prAdapter->rWlanInfo.apucScanResultIEs[j]; ++ } ++ ++ prAdapter->rWlanInfo.u4ScanResultNum--; ++ ++ /* remove IE buffer if needed := move rest of IE buffer */ ++ if (u4IELength > 0) { ++ u4IEMoveLength = prAdapter->rWlanInfo.u4ScanIEBufferUsage - ++ (((ULONG) pucIEPtr) + (ULONG) u4IELength - ++ ((ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])))); ++ ++ kalMemCopy(pucIEPtr, pucIEPtr + u4IELength, u4IEMoveLength); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4IELength; ++ ++ /* correction of pointers to IE buffer */ ++ for (j = 0; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { ++ if (prAdapter->rWlanInfo.apucScanResultIEs[j] > pucIEPtr) { ++ prAdapter->rWlanInfo.apucScanResultIEs[j] = ++ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[j]) - ++ u4IELength); ++ } ++ } ++ } ++ } ++ ++ i++; ++ } ++ ++} ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter) ++{ ++#if 0 ++ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; ++ ++ prMsgFuncSwitch = ++ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ if (!prMsgFuncSwitch) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prMsgFuncSwitch->fgIsFuncOn = TRUE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ ++} ++ ++VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter) ++{ ++ ++ P_MSG_P2P_CONNECTION_REQUEST_T prMsgConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; ++ ++ prMsgConnReq = ++ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ if (!prMsgConnReq) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prMsgConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; ++ ++ /*=====Param Modified for test=====*/ ++ COPY_MAC_ADDR(prMsgConnReq->aucDeviceID, aucTargetDeviceID); ++ prMsgConnReq->fgIsTobeGO = TRUE; ++ prMsgConnReq->fgIsPersistentGroup = FALSE; ++ ++ /*=====Param Modified for test=====*/ ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgConnReq, MSG_SEND_METHOD_BUF); ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve permanent address from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_EVENT_BASIC_CONFIG prEventBasicConfig; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanQueryPermanentAddress"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* send the command */ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ /* wait for response */ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG), /* 8B + 12B */ ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ if (prEvent->ucEID != EVENT_ID_BASIC_CONFIG) ++ return WLAN_STATUS_FAILURE; ++ ++ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (prEvent->aucBuffer); ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, &(prEventBasicConfig->rMyMacAddr)); ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, &(prEventBasicConfig->rMyMacAddr)); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve NIC capability from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_32 u4FwIDVersion = 0; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_EVENT_NIC_CAPABILITY prEventNicCapability; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanQueryNicCapability"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY)); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = 0; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* send the command */ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ /* wait for FW response */ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY), ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY) ++ return WLAN_STATUS_FAILURE; ++ ++ prEventNicCapability = (P_EVENT_NIC_CAPABILITY) (prEvent->aucBuffer); ++ ++ prAdapter->rVerInfo.u2FwProductID = prEventNicCapability->u2ProductID; ++ prAdapter->rVerInfo.u2FwOwnVersion = prEventNicCapability->u2FwVersion; ++ prAdapter->rVerInfo.u2FwPeerVersion = prEventNicCapability->u2DriverVersion; ++ prAdapter->fgIsHw5GBandDisabled = (BOOLEAN) prEventNicCapability->ucHw5GBandDisabled; ++ prAdapter->fgIsEepromUsed = (BOOLEAN) prEventNicCapability->ucEepromUsed; ++ prAdapter->fgIsEfuseValid = (BOOLEAN) prEventNicCapability->ucEfuseValid; ++ prAdapter->fgIsEmbbededMacAddrValid = (BOOLEAN) prEventNicCapability->ucMacAddrValid; ++ ++ u4FwIDVersion = (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); ++ mtk_wcn_wmt_set_wifi_ver(u4FwIDVersion); ++#if (CFG_SUPPORT_TDLS == 1) ++ if (prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_TDLS)) ++ prAdapter->fgTdlsIsSup = TRUE; ++ DBGLOG(TDLS, TRACE, " support flag: 0x%x\n", prEventNicCapability->ucFeatureSet); ++#else ++ prAdapter->fgTdlsIsSup = 0; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ if (!(prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_5G_SUPPORT))) ++ prAdapter->fgEnable5GBand = FALSE; /* firmware does not support */ ++ ++#if CFG_ENABLE_CAL_LOG ++ DBGLOG(INIT, LOUD, " RF CAL FAIL = (%d),BB CAL FAIL = (%d)\n", ++ prEventNicCapability->ucRfCalFail, prEventNicCapability->ucBbCalFail); ++#endif ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve NIC capability from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC("wlanQueryDebugCode"); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE; ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_GET_DEBUG_CODE; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = 0; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* send the command */ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to retrieve compiler flag from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryCompileFlag(IN P_ADAPTER_T prAdapter, IN UINT_32 u4QueryID, OUT PUINT_32 pu4CompilerFlag) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_CMD_SW_DBG_CTRL_T prCmdNicCompileFlag, prEventNicCompileFlag; ++ ++ ASSERT(prAdapter); ++ ++ DEBUGFUNC(__func__); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T)); ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_SW_DBG_CTRL; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = 0; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ /* Fill up SW CR */ ++ prCmdNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prWifiCmd->aucBuffer); ++ ++ prCmdNicCompileFlag->u4Id = u4QueryID; ++ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T), ++ &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ if (prEvent->ucEID != EVENT_ID_SW_DBG_CTRL) ++ return WLAN_STATUS_FAILURE; ++ ++ prEventNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prEvent->aucBuffer); ++ ++ *pu4CompilerFlag = prEventNicCompileFlag->u4Data; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter) ++{ ++ wlanQueryCompileFlag(prAdapter, 0xA0240000, &prAdapter->u4FwCompileFlag0); ++ wlanQueryCompileFlag(prAdapter, 0xA0240001, &prAdapter->u4FwCompileFlag1); ++ ++ DBGLOG(INIT, TRACE, ++ "Compile Flags: 0x%08x 0x%08x\n", prAdapter->u4FwCompileFlag0, prAdapter->u4FwCompileFlag1); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if defined(MT6628) ++static INT_32 wlanChangeCodeWord(INT_32 au4Input) ++{ ++ ++ UINT_16 i; ++#if TXPWR_USE_PDSLOPE ++ CODE_MAPPING_T arCodeTable[] = { ++ {0X100, -40}, ++ {0X104, -35}, ++ {0X128, -30}, ++ {0X14C, -25}, ++ {0X170, -20}, ++ {0X194, -15}, ++ {0X1B8, -10}, ++ {0X1DC, -5}, ++ {0, 0}, ++ {0X24, 5}, ++ {0X48, 10}, ++ {0X6C, 15}, ++ {0X90, 20}, ++ {0XB4, 25}, ++ {0XD8, 30}, ++ {0XFC, 35}, ++ {0XFF, 40}, ++ ++ }; ++#else ++ CODE_MAPPING_T arCodeTable[] = { ++ {0X100, 0x80}, ++ {0X104, 0x80}, ++ {0X128, 0x80}, ++ {0X14C, 0x80}, ++ {0X170, 0x80}, ++ {0X194, 0x94}, ++ {0X1B8, 0XB8}, ++ {0X1DC, 0xDC}, ++ {0, 0}, ++ {0X24, 0x24}, ++ {0X48, 0x48}, ++ {0X6C, 0x6c}, ++ {0X90, 0x7F}, ++ {0XB4, 0x7F}, ++ {0XD8, 0x7F}, ++ {0XFC, 0x7F}, ++ {0XFF, 0x7F}, ++ ++ }; ++#endif ++ ++ for (i = 0; i < sizeof(arCodeTable) / sizeof(CODE_MAPPING_T); i++) { ++ ++ if (arCodeTable[i].u4RegisterValue == au4Input) ++ return arCodeTable[i].i4TxpowerOffset; ++ } ++ ++ return 0; ++} ++#endif ++ ++#if TXPWR_USE_PDSLOPE ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo) ++{ ++ UINT_8 ucCmdSeqNum; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_32 u4RxPktLength; ++ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG)]; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_WIFI_EVENT_T prEvent; ++ P_CMD_ACCESS_REG prCmdMcrQuery; ++ ++ ASSERT(prAdapter); ++ ++ /* 1. Allocate CMD Info Packet and its Buffer */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_ACCESS_REG; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_ACCESS_REG); ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ kalMemCopy(prWifiCmd->aucBuffer, prMcrRdInfo, sizeof(CMD_ACCESS_REG)); ++ ++ wlanSendCommand(prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ ++ if (nicRxWaitResponse(prAdapter, ++ 1, ++ aucBuffer, ++ sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG), &u4RxPktLength) != WLAN_STATUS_SUCCESS) ++ return WLAN_STATUS_FAILURE; ++ /* header checking .. */ ++ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; ++ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) ++ return WLAN_STATUS_FAILURE; ++ ++ prEvent = (P_WIFI_EVENT_T) aucBuffer; ++ ++ if (prEvent->ucEID != EVENT_ID_ACCESS_REG) ++ return WLAN_STATUS_FAILURE; ++ ++ prCmdMcrQuery = (P_CMD_ACCESS_REG) (prEvent->aucBuffer); ++ prMcrRdInfo->u4McrOffset = prCmdMcrQuery->u4Address; ++ prMcrRdInfo->u4McrData = prCmdMcrQuery->u4Data; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++static INT_32 wlanIntRound(INT_32 au4Input) ++{ ++ ++ if (au4Input >= 0) { ++ if ((au4Input % 10) == 5) { ++ au4Input = au4Input + 5; ++ return au4Input; ++ } ++ } ++ ++ if (au4Input < 0) { ++ if ((au4Input % 10) == -5) { ++ au4Input = au4Input - 5; ++ return au4Input; ++ } ++ } ++ ++ return au4Input; ++} ++ ++static INT_32 wlanCal6628EfuseForm(IN P_ADAPTER_T prAdapter, INT_32 au4Input) ++{ ++ ++ PARAM_MCR_RW_STRUCT_T rMcrRdInfo; ++ INT_32 au4PdSlope, au4TxPwrOffset, au4TxPwrOffset_Round; ++ INT_8 auTxPwrOffset_Round; ++ ++ rMcrRdInfo.u4McrOffset = 0x60205c68; ++ rMcrRdInfo.u4McrData = 0; ++ au4TxPwrOffset = au4Input; ++ wlanQueryPdMcr(prAdapter, &rMcrRdInfo); ++ ++ au4PdSlope = (rMcrRdInfo.u4McrData) & BITS(0, 6); ++ au4TxPwrOffset_Round = wlanIntRound((au4TxPwrOffset * au4PdSlope)) / 10; ++ ++ au4TxPwrOffset_Round = -au4TxPwrOffset_Round; ++ ++ if (au4TxPwrOffset_Round < -128) ++ au4TxPwrOffset_Round = 128; ++ else if (au4TxPwrOffset_Round < 0) ++ au4TxPwrOffset_Round += 256; ++ else if (au4TxPwrOffset_Round > 127) ++ au4TxPwrOffset_Round = 127; ++ ++ auTxPwrOffset_Round = (UINT8) au4TxPwrOffset_Round; ++ ++ return au4TxPwrOffset_Round; ++} ++ ++#endif ++ ++#if defined(MT6628) ++static VOID wlanChangeNvram6620to6628(PUINT_8 pucEFUSE) ++{ ++ ++#define EFUSE_CH_OFFSET1_L_MASK_6620 BITS(0, 8) ++#define EFUSE_CH_OFFSET1_L_SHIFT_6620 0 ++#define EFUSE_CH_OFFSET1_M_MASK_6620 BITS(9, 17) ++#define EFUSE_CH_OFFSET1_M_SHIFT_6620 9 ++#define EFUSE_CH_OFFSET1_H_MASK_6620 BITS(18, 26) ++#define EFUSE_CH_OFFSET1_H_SHIFT_6620 18 ++#define EFUSE_CH_OFFSET1_VLD_MASK_6620 BIT(27) ++#define EFUSE_CH_OFFSET1_VLD_SHIFT_6620 27 ++ ++#define EFUSE_CH_OFFSET1_L_MASK_5931 BITS(0, 7) ++#define EFUSE_CH_OFFSET1_L_SHIFT_5931 0 ++#define EFUSE_CH_OFFSET1_M_MASK_5931 BITS(8, 15) ++#define EFUSE_CH_OFFSET1_M_SHIFT_5931 8 ++#define EFUSE_CH_OFFSET1_H_MASK_5931 BITS(16, 23) ++#define EFUSE_CH_OFFSET1_H_SHIFT_5931 16 ++#define EFUSE_CH_OFFSET1_VLD_MASK_5931 BIT(24) ++#define EFUSE_CH_OFFSET1_VLD_SHIFT_5931 24 ++#define EFUSE_ALL_CH_OFFSET1_MASK_5931 BITS(25, 27) ++#define EFUSE_ALL_CH_OFFSET1_SHIFT_5931 25 ++ ++ INT_32 au4ChOffset; ++ INT_16 au2ChOffsetL, au2ChOffsetM, au2ChOffsetH; ++ ++ au4ChOffset = *(UINT_32 *) (pucEFUSE + 72); ++ ++ if ((au4ChOffset & EFUSE_CH_OFFSET1_VLD_MASK_6620) && ((*(UINT_32 *) (pucEFUSE + 28)) == 0)) { ++ ++ au2ChOffsetL = ((au4ChOffset & EFUSE_CH_OFFSET1_L_MASK_6620) >> EFUSE_CH_OFFSET1_L_SHIFT_6620); ++ ++ au2ChOffsetM = ((au4ChOffset & EFUSE_CH_OFFSET1_M_MASK_6620) >> EFUSE_CH_OFFSET1_M_SHIFT_6620); ++ ++ au2ChOffsetH = ((au4ChOffset & EFUSE_CH_OFFSET1_H_MASK_6620) >> EFUSE_CH_OFFSET1_H_SHIFT_6620); ++ ++ au2ChOffsetL = wlanChangeCodeWord(au2ChOffsetL); ++ au2ChOffsetM = wlanChangeCodeWord(au2ChOffsetM); ++ au2ChOffsetH = wlanChangeCodeWord(au2ChOffsetH); ++ ++ au4ChOffset = 0; ++ au4ChOffset |= *(UINT_32 *) (pucEFUSE + 72) ++ >> (EFUSE_CH_OFFSET1_VLD_SHIFT_6620 - ++ EFUSE_CH_OFFSET1_VLD_SHIFT_5931) & EFUSE_CH_OFFSET1_VLD_MASK_5931; ++ ++ au4ChOffset |= ++ ((((UINT_32) au2ChOffsetL) << EFUSE_CH_OFFSET1_L_SHIFT_5931) & EFUSE_CH_OFFSET1_L_MASK_5931); ++ au4ChOffset |= ++ ((((UINT_32) au2ChOffsetM) << EFUSE_CH_OFFSET1_M_SHIFT_5931) & EFUSE_CH_OFFSET1_M_MASK_5931); ++ au4ChOffset |= ++ ((((UINT_32) au2ChOffsetH) << EFUSE_CH_OFFSET1_H_SHIFT_5931) & EFUSE_CH_OFFSET1_H_MASK_5931); ++ ++ *((INT_32 *) ((pucEFUSE + 28))) = au4ChOffset; ++ ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to load manufacture data from NVRAM ++* if available and valid ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param prRegInfo Pointer of REG_INFO_T ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) ++{ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ CMD_RDD_CH_T rRddParam; ++#endif ++ ++ ASSERT(prAdapter); ++ ++ /* 1. Version Check */ ++ kalGetConfigurationVersion(prAdapter->prGlueInfo, ++ &(prAdapter->rVerInfo.u2Part1CfgOwnVersion), ++ &(prAdapter->rVerInfo.u2Part1CfgPeerVersion), ++ &(prAdapter->rVerInfo.u2Part2CfgOwnVersion), ++ &(prAdapter->rVerInfo.u2Part2CfgPeerVersion)); ++ ++#if (CFG_SW_NVRAM_VERSION_CHECK == 1) ++ if (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion ++ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION ++ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION) { ++ return WLAN_STATUS_FAILURE; ++ } ++#endif ++ ++ /* MT6620 E1/E2 would be ignored directly */ ++ if (prAdapter->rVerInfo.u2Part1CfgOwnVersion == 0x0001) { ++ prRegInfo->ucTxPwrValid = 1; ++ } else { ++ /* 2. Load TX power gain parameters if valid */ ++ if (prRegInfo->ucTxPwrValid != 0) { ++ /* send to F/W */ ++ nicUpdateTxPower(prAdapter, (P_CMD_TX_PWR_T) (&(prRegInfo->rTxPwr))); ++ } ++ } ++ ++ /* Workaround for supporting 5G */ ++ prRegInfo->ucEnable5GBand = 1; ++ prRegInfo->ucSupport5GBand = 1; ++ ++ /* 3. Check if needs to support 5GHz */ ++ /* if(prRegInfo->ucEnable5GBand) { // Frank workaround */ ++ if (1) { ++ /* check if it is disabled by hardware */ ++ if (prAdapter->fgIsHw5GBandDisabled || prRegInfo->ucSupport5GBand == 0) ++ prAdapter->fgEnable5GBand = FALSE; ++ else ++ prAdapter->fgEnable5GBand = TRUE; ++ } else ++ prAdapter->fgEnable5GBand = FALSE; ++ /* Workaround for supporting 5G */ ++ prAdapter->fgEnable5GBand = TRUE; ++/* ++ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d)\n", ++ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled); ++*/ ++ /* 4. Send EFUSE data */ ++#if defined(MT6628) ++ wlanChangeNvram6620to6628(prRegInfo->aucEFUSE); ++#endif ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PHY_PARAM, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_PHY_PARAM_T), (PUINT_8) (prRegInfo->aucEFUSE), NULL, 0); ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ rRddParam.ucRddTestMode = (UINT_8) prRegInfo->u4RddTestMode; ++ rRddParam.ucRddShutCh = (UINT_8) prRegInfo->u4RddShutFreq; ++ rRddParam.ucRddStartCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStartFreq); ++ rRddParam.ucRddStopCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStopFreq); ++ rRddParam.ucRddDfs = (UINT_8) prRegInfo->u4RddDfs; ++ prAdapter->ucRddStatus = 0; ++ nicUpdateRddTestMode(prAdapter, (P_CMD_RDD_CH_T) (&rRddParam)); ++#endif ++ ++ /* 5. Get 16-bits Country Code and Bandwidth */ ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode = ++ (((UINT_16) prRegInfo->au2CountryCode[0]) << 8) | (((UINT_16) prRegInfo->au2CountryCode[1]) & BITS(0, 7)); ++ ++ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d) CountryCode(0x%x 0x%x)\n", ++ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled, ++ prRegInfo->au2CountryCode[0], prRegInfo->au2CountryCode[1]); ++ ++#if 0 /* Bandwidth control will be controlled by GUI. 20110930 ++ * So ignore the setting from registry/NVRAM ++ */ ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = ++ prRegInfo->uc2G4BwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; ++ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = ++ prRegInfo->uc5GBwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; ++#endif ++ ++ /* 6. Set domain and channel information to chip */ ++ rlmDomainSendCmd(prAdapter, FALSE); ++ /* Update supported channel list in channel table */ ++ wlanUpdateChannelTable(prAdapter->prGlueInfo); ++ ++ /* 7. Set band edge tx power if available */ ++ if (prRegInfo->fg2G4BandEdgePwrUsed) { ++ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; ++ ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK = prRegInfo->cBandEdgeMaxPwrCCK; ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 = prRegInfo->cBandEdgeMaxPwrOFDM20; ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 = prRegInfo->cBandEdgeMaxPwrOFDM40; ++ ++ DBGLOG(INIT, TRACE, "NVRAM 2G Bandedge CCK(%d) HT20(%d)HT40(%d)\n", ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK, ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_EDGE_TXPWR_LIMIT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); ++ } ++ /* 8. set 5G band edge tx power if available (add for 6625) */ ++ if (prAdapter->fgEnable5GBand) { ++#define NVRAM_5G_TX_BANDEDGE_VALID_OFFSET 10 ++#define NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET 11 ++#define NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET 12 ++ ++ if (prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_VALID_OFFSET]) { ++ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; ++ ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 ++ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET]; ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 ++ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET]; ++ ++ DBGLOG(INIT, TRACE, "NVRAM 5G Bandedge HT20(%d)HT40(%d)\n", ++ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); ++ } ++ } ++ /* 9. set RSSI compensation */ ++ /* DBGLOG(INIT, INFO, ("[frank] RSSI valid(%d) 2G(%d) 5G(%d)", ++ prRegInfo->fgRssiCompensationValidbit, ++ prRegInfo->uc2GRssiCompensation, ++ prRegInfo->uc5GRssiCompensation)); */ ++ if (prRegInfo->fgRssiCompensationValidbit) { ++ CMD_RSSI_COMPENSATE_T rCmdRssiCompensate; ++ ++ rCmdRssiCompensate.uc2GRssiCompensation = prRegInfo->uc2GRssiCompensation; ++ rCmdRssiCompensate.uc5GRssiCompensation = prRegInfo->uc5GRssiCompensation; ++ ++ DBGLOG(INIT, LOUD, "NVRAM RSSI Comp. 2G(%d)5G(%d)\n", ++ rCmdRssiCompensate.uc2GRssiCompensation, rCmdRssiCompensate.uc5GRssiCompensation); ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RSSI_COMPENSATE, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_RSSI_COMPENSATE_T), (PUINT_8)&rCmdRssiCompensate, NULL, 0); ++ } ++ /* 10. notify FW Band Support 5G */ ++ if (prAdapter->fgEnable5GBand) { ++ CMD_BAND_SUPPORT_T rCmdBandSupport; ++ ++ rCmdBandSupport.uc5GBandSupport = TRUE; ++ DBGLOG(INIT, TRACE, "NVRAM 5G BandSupport\n"); ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BAND_SUPPORT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_BAND_SUPPORT_T), (PUINT_8)&rCmdBandSupport, NULL, 0); ++ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check ++* Media Stream Mode is set to non-default value or not, ++* and clear to default value if above criteria is met ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return TRUE ++* The media stream mode was non-default value and has been reset ++* FALSE ++* The media stream mode is default value ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode != 0) { ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; ++ ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if any pending timer has expired ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* check timer status */ ++ cnmTimerDoTimeOutCheck(prAdapter); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to check if any pending mailbox message ++* to be handled ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { /* MBOX_ID_TOTAL_NUM = 1 */ ++ mboxRcvAllMsg(prAdapter, (ENUM_MBOX_ID_T) i); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to enqueue a single TX packet into CORE ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* prNativePacket Pointer of Native Packet ++* ++* @return WLAN_STATUS_SUCCESS ++* WLAN_STATUS_RESOURCES ++* WLAN_STATUS_INVALID_PACKET ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* get a free packet header */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ if (prMsduInfo == NULL) ++ return WLAN_STATUS_RESOURCES; ++ ++ prMsduInfo->eSrc = TX_PACKET_OS; ++ ++ if (nicTxFillMsduInfo(prAdapter, prMsduInfo, prNativePacket) == FALSE) { ++ /* packet is not extractable */ ++ ++ /* fill fails */ ++ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_INVALID_PACKET); ++ ++ nicTxReturnMsduInfo(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_INVALID_PACKET; ++ } ++ /* enqueue to QM */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to flush pending TX packets in CORE ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return nicTxFlush(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief this function sends pending MSDU_INFO_T to MT6620 ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param pfgHwAccess Pointer for tracking LP-OWN status ++* ++* @retval WLAN_STATUS_SUCCESS Reset is done successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ ASSERT(pfgHwAccess); ++ ++ /* <1> dequeue packets by txDequeuTxPackets() */ ++ /* Note: prMsduInfo is a packet list queue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prMsduInfo = qmDequeueTxPackets(prAdapter, &prTxCtrl->rTc); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ if (prMsduInfo != NULL) { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { ++ /* <2> Acquire LP-OWN if necessary */ ++ if (*pfgHwAccess == FALSE) { ++ *pfgHwAccess = TRUE; ++ ++ wlanAcquirePowerControl(prAdapter); ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ /* <3> send packet"s" to HIF */ ++ nicTxMsduInfoList(prAdapter, prMsduInfo); ++ ++ /* <4> update TC by txAdjustTcQuotas() */ ++ nicTxAdjustTcq(prAdapter); ++ } else ++ wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); /* free the packet */ ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ nicEnableClockGating(prAdapter); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to acquire power control from firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* do driver own */ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++ ++ /* Reset sleepy state *//* no use */ ++ if (prAdapter->fgWiFiInSleepyState == TRUE) ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to release power control to firmware ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* do FW own */ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to report currently pending TX frames count ++* (command packets are not included) ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return number of pending TX frames ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ UINT_32 u4Num; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* number in prTxQueue + number in RX forward */ ++ u4Num = kalGetTxPendingFrameCount(prAdapter->prGlueInfo) + (UINT_32) (prTxCtrl->i4PendingFwdFrameCount); ++ ++ return u4Num; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to report current ACPI state ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return ACPI_STATE_D0 Normal Operation Mode ++* ACPI_STATE_D3 Suspend Mode ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->rAcpiState; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to update current ACPI state only ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param ePowerState ACPI_STATE_D0 Normal Operation Mode ++* ACPI_STATE_D3 Suspend Mode ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState) ++{ ++ ASSERT(prAdapter); ++ ASSERT(ePowerState <= ACPI_STATE_D3); ++ ++ prAdapter->rAcpiState = ePowerState; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to query ECO version from HIFSYS CR ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return zero Unable to retrieve ECO version information ++* non-zero ECO version (1-based) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ if (nicVerifyChipID(prAdapter) == TRUE) ++ return prAdapter->ucRevID + 1; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to setting the default Tx Power configuration ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return zero Unable to retrieve ECO version information ++* non-zero ECO version (1-based) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 i; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ P_SET_TXPWR_CTRL_T prTxpwr; ++ ++ ASSERT(prGlueInfo); ++ ++ prTxpwr = &prGlueInfo->rTxPwr; ++ ++ prTxpwr->c2GLegacyStaPwrOffset = 0; ++ prTxpwr->c2GHotspotPwrOffset = 0; ++ prTxpwr->c2GP2pPwrOffset = 0; ++ prTxpwr->c2GBowPwrOffset = 0; ++ prTxpwr->c5GLegacyStaPwrOffset = 0; ++ prTxpwr->c5GHotspotPwrOffset = 0; ++ prTxpwr->c5GP2pPwrOffset = 0; ++ prTxpwr->c5GBowPwrOffset = 0; ++ prTxpwr->ucConcurrencePolicy = 0; ++ for (i = 0; i < 3; i++) ++ prTxpwr->acReserved1[i] = 0; ++ ++ for (i = 0; i < 14; i++) ++ prTxpwr->acTxPwrLimit2G[i] = 63; ++ ++ for (i = 0; i < 4; i++) ++ prTxpwr->acTxPwrLimit5G[i] = 63; ++ ++ for (i = 0; i < 2; i++) ++ prTxpwr->acReserved2[i] = 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* set preferred band configuration corresponding to network type ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param eBand Given band ++* @param eNetTypeIndex Given Network Type ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eBand <= BAND_NUM); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ /* 1. set prefer band according to network type */ ++ prAdapter->aePreferBand[eNetTypeIndex] = eBand; ++ ++ /* 2. remove buffered BSS descriptors correspondingly */ ++ if (eBand == BAND_2G4) ++ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_5G, eNetTypeIndex); ++ else if (eBand == BAND_5G) ++ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_2G4, eNetTypeIndex); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* get channel information corresponding to specified network type ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param eNetTypeIndex Given Network Type ++* ++* @return channel number ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ return prBssInfo->ucPrimaryChannel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* get BSS descriptor information corresponding to specified network type ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* @param eNetTypeIndex Given Network Type ++* ++* @return pointer to BSS_DESC_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ switch (eNetTypeIndex) { ++ case NETWORK_TYPE_AIS_INDEX: ++ return prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; ++ ++ case NETWORK_TYPE_P2P_INDEX: ++ return NULL; ++ ++ case NETWORK_TYPE_BOW_INDEX: ++ return prAdapter->rWifiVar.rBowFsmInfo.prTargetBssDesc; ++ ++ default: ++ return NULL; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to ++* check unconfigured system properties and generate related message on ++* scan list to notify users ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter) ++{ ++#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1) ++ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ const UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ BOOLEAN fgIsConfExist = TRUE; ++ BOOLEAN fgGenErrMsg = FALSE; ++ P_REG_INFO_T prRegInfo = NULL; ++ P_WLAN_BEACON_FRAME_T prBeacon = NULL; ++ P_IE_SSID_T prSsid = NULL; ++ UINT_32 u4ErrCode = 0; ++ UINT_8 aucErrMsg[32]; ++ PARAM_SSID_T rSsid; ++ PARAM_802_11_CONFIG_T rConfiguration; ++ PARAM_RATES_EX rSupportedRates; ++#endif ++ ++ DEBUGFUNC("wlanCheckSystemConfiguration"); ++ ++ ASSERT(prAdapter); ++ ++#if (CFG_NVRAM_EXISTENCE_CHECK == 1) ++ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) { ++ fgIsConfExist = FALSE; ++ fgGenErrMsg = TRUE; ++ } ++#endif ++ ++#if (CFG_SW_NVRAM_VERSION_CHECK == 1) ++ prRegInfo = kalGetConfiguration(prAdapter->prGlueInfo); ++ ++ if (fgIsConfExist == TRUE && (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion ++ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION ++ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion ++ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ || prAdapter->fgIsPowerLimitTableValid == FALSE ++#endif ++ || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && ++ (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) ++ || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) ++ || prRegInfo->ucTxPwrValid == 0)) ++ fgGenErrMsg = TRUE; ++#endif ++ ++ if (fgGenErrMsg == TRUE) { ++ prBeacon = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); ++ if (!prBeacon) { ++ ASSERT(FALSE); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* initialization */ ++ kalMemZero(prBeacon, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); ++ ++ /* prBeacon initialization */ ++ prBeacon->u2FrameCtrl = MAC_FRAME_BEACON; ++ COPY_MAC_ADDR(prBeacon->aucDestAddr, aucBCAddr); ++ COPY_MAC_ADDR(prBeacon->aucSrcAddr, aucZeroMacAddr); ++ COPY_MAC_ADDR(prBeacon->aucBSSID, aucZeroMacAddr); ++ prBeacon->u2BeaconInterval = 100; ++ prBeacon->u2CapInfo = CAP_INFO_ESS; ++ ++ /* prSSID initialization */ ++ prSsid = (P_IE_SSID_T) (&prBeacon->aucInfoElem[0]); ++ prSsid->ucId = ELEM_ID_SSID; ++ ++ /* rConfiguration initialization */ ++ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); ++ rConfiguration.u4BeaconPeriod = 100; ++ rConfiguration.u4ATIMWindow = 1; ++ rConfiguration.u4DSConfig = 2412; ++ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); ++ ++ /* rSupportedRates initialization */ ++ kalMemZero(rSupportedRates, sizeof(PARAM_RATES_EX)); ++ } ++#if (CFG_NVRAM_EXISTENCE_CHECK == 1) ++#define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01" ++ if ((kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) && (prBeacon) && (prSsid)) { ++ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBeacon, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + prSsid->ucLength, ++ 1, 0); ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); ++ nicAddScanResult(prAdapter, ++ prBeacon->aucBSSID, ++ &rSsid, ++ 0, ++ 0, ++ PARAM_NETWORK_TYPE_FH, ++ &rConfiguration, ++ NET_TYPE_INFRA, ++ rSupportedRates, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + prSsid->ucLength - ++ WLAN_MAC_MGMT_HEADER_LEN, (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); ++ } ++#endif ++ ++#if (CFG_SW_NVRAM_VERSION_CHECK == 1) ++#define VER_ERR_MSG "NVRAM WARNING: Err = 0x%02X" ++ if ((fgIsConfExist == TRUE) && (prBeacon) && (prSsid)) { ++ if ((CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion ++ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION ++ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ ++ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion ++ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION)) ++ u4ErrCode |= NVRAM_ERROR_VERSION_MISMATCH; ++ ++ if (prRegInfo->ucTxPwrValid == 0) ++ u4ErrCode |= NVRAM_ERROR_INVALID_TXPWR; ++ ++ if (prAdapter->fgIsEmbbededMacAddrValid == FALSE && (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) ++ || EQUAL_MAC_ADDR(aucZeroMacAddr, ++ prRegInfo->aucMacAddr))) ++ u4ErrCode |= NVRAM_ERROR_INVALID_MAC_ADDR; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ if (prAdapter->fgIsPowerLimitTableValid == FALSE) ++ u4ErrCode |= NVRAM_POWER_LIMIT_TABLE_INVALID; ++#endif ++ if (u4ErrCode != 0) { ++ sprintf(aucErrMsg, VER_ERR_MSG, (unsigned int)u4ErrCode); ++ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, aucErrMsg, strlen(aucErrMsg)); ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBeacon, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + ++ prSsid->ucLength, 1, 0); ++ ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); ++ nicAddScanResult(prAdapter, ++ prBeacon->aucBSSID, ++ &rSsid, ++ 0, ++ 0, ++ PARAM_NETWORK_TYPE_FH, ++ &rConfiguration, ++ NET_TYPE_INFRA, ++ rSupportedRates, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, ++ aucSSID) + ++ prSsid->ucLength - WLAN_MAC_MGMT_HEADER_LEN, ++ (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); ++ } ++ } ++#endif ++ ++ if (fgGenErrMsg == TRUE) ++ cnmMemFree(prAdapter, prBeacon); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++ P_STA_RECORD_T prStaRec, prTempStaRec; ++ P_PARAM_GET_STA_STATISTICS prQueryStaStatistics; ++ UINT_8 ucStaRecIdx; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ CMD_GET_STA_STATISTICS_T rQueryCmdStaStatistics; ++ UINT_8 ucIdx; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ do { ++ ASSERT(pvQueryBuffer); ++ ++ /* 4 1. Sanity test */ ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ if (u4QueryBufferLen < sizeof(PARAM_GET_STA_STA_STATISTICS)) { ++ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); ++ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++ ++ prQueryStaStatistics = (P_PARAM_GET_STA_STATISTICS) pvQueryBuffer; ++ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); ++ ++ /* 4 5. Get driver global QM counter */ ++ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { ++ prQueryStaStatistics->au4TcAverageQueLen[ucIdx] = prQM->au4AverageQueLen[ucIdx]; ++ prQueryStaStatistics->au4TcCurrentQueLen[ucIdx] = prQM->au4CurrentTcResource[ucIdx]; ++ } ++ ++ /* 4 2. Get StaRec by MAC address */ ++ prStaRec = NULL; ++ ++ for (ucStaRecIdx = 0; ucStaRecIdx < CFG_NUM_OF_STA_RECORD; ucStaRecIdx++) { ++ prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]); ++ if (prTempStaRec->fgIsValid && prTempStaRec->fgIsInUse) { ++ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prQueryStaStatistics->aucMacAddr)) { ++ prStaRec = prTempStaRec; ++ break; ++ } ++ } ++ } ++ ++ if (!prStaRec) { ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ prQueryStaStatistics->u4Flag |= BIT(0); ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ /* 4 3. Get driver statistics */ ++ DBGLOG(TX, INFO, "skbToDriver %lld, skbFreed: %lld\n", ++ prAdapter->prGlueInfo->u8SkbToDriver, ++ prAdapter->prGlueInfo->u8SkbFreed); ++ prAdapter->prGlueInfo->u8SkbFreed = 0; ++ prAdapter->prGlueInfo->u8SkbToDriver = 0; ++ ++ prQueryStaStatistics->u4TxTotalCount = prStaRec->u4TotalTxPktsNumber; ++ prQueryStaStatistics->u4TxExceedThresholdCount = prStaRec->u4ThresholdCounter; ++ prQueryStaStatistics->u4TxMaxTime = prStaRec->u4MaxTxPktsTime; ++ prQueryStaStatistics->u4TxMaxHifTime = prStaRec->u4MaxTxPktsHifTime; ++ if (prStaRec->u4TotalTxPktsNumber) { ++ prQueryStaStatistics->u4TxAverageProcessTime = ++ (prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber); ++ prQueryStaStatistics->u4TxAverageHifTime = ++ (prStaRec->u4TotalTxPktsHifTime / prStaRec->u4TotalTxPktsNumber); ++ } else ++ prQueryStaStatistics->u4TxAverageProcessTime = 0; ++ ++ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { ++ prQueryStaStatistics->au4TcResourceEmptyCount[ucIdx] = ++ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx]; ++ /* Reset */ ++ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx] = 0; ++ prQueryStaStatistics->au4TcResourceBackCount[ucIdx] = ++ prQM->au4QmTcResourceBackCounter[ucIdx]; ++ prQM->au4QmTcResourceBackCounter[ucIdx] = 0; ++ ++ prQueryStaStatistics->au4DequeueNoTcResource[ucIdx] = ++ prQM->au4DequeueNoTcResourceCounter[ucIdx]; ++ prQM->au4DequeueNoTcResourceCounter[ucIdx] = 0; ++ prQueryStaStatistics->au4TcResourceUsedCount[ucIdx] = ++ prQM->au4ResourceUsedCounter[ucIdx]; ++ prQM->au4ResourceUsedCounter[ucIdx] = 0; ++ prQueryStaStatistics->au4TcResourceWantedCount[ucIdx] = ++ prQM->au4ResourceWantedCounter[ucIdx]; ++ prQM->au4ResourceWantedCounter[ucIdx] = 0; ++ } ++ ++ prQueryStaStatistics->u4EnqueueCounter = prQM->u4EnqeueuCounter; ++ prQueryStaStatistics->u4DequeueCounter = prQM->u4DequeueCounter; ++ prQueryStaStatistics->u4EnqueueStaCounter = prStaRec->u4EnqeueuCounter; ++ prQueryStaStatistics->u4DequeueStaCounter = prStaRec->u4DeqeueuCounter; ++ ++ prQueryStaStatistics->IsrCnt = prGlueInfo->IsrCnt - prGlueInfo->IsrPreCnt; ++ prQueryStaStatistics->IsrPassCnt = prGlueInfo->IsrPassCnt - prGlueInfo->IsrPrePassCnt; ++ prQueryStaStatistics->TaskIsrCnt = prGlueInfo->TaskIsrCnt - prGlueInfo->TaskPreIsrCnt; ++ ++ prQueryStaStatistics->IsrAbnormalCnt = prGlueInfo->IsrAbnormalCnt; ++ prQueryStaStatistics->IsrSoftWareCnt = prGlueInfo->IsrSoftWareCnt; ++ prQueryStaStatistics->IsrRxCnt = prGlueInfo->IsrRxCnt; ++ prQueryStaStatistics->IsrTxCnt = prGlueInfo->IsrTxCnt; ++ ++ /* 4 4.1 Reset statistics */ ++ prStaRec->u4ThresholdCounter = 0; ++ prStaRec->u4TotalTxPktsNumber = 0; ++ prStaRec->u4TotalTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsHifTime = 0; ++ ++ prStaRec->u4EnqeueuCounter = 0; ++ prStaRec->u4DeqeueuCounter = 0; ++ ++ prQM->u4EnqeueuCounter = 0; ++ prQM->u4DequeueCounter = 0; ++ ++ prGlueInfo->IsrPreCnt = prGlueInfo->IsrCnt; ++ prGlueInfo->IsrPrePassCnt = prGlueInfo->IsrPassCnt; ++ prGlueInfo->TaskPreIsrCnt = prGlueInfo->TaskIsrCnt; ++ prGlueInfo->IsrAbnormalCnt = 0; ++ prGlueInfo->IsrSoftWareCnt = 0; ++ prGlueInfo->IsrRxCnt = 0; ++ prGlueInfo->IsrTxCnt = 0; ++#endif ++ ++ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) ++ prQueryStaStatistics->au4TcQueLen[ucIdx] = prStaRec->arTxQueue[ucIdx].u4NumElem; ++ ++ rResult = WLAN_STATUS_SUCCESS; ++ ++ /* 4 6. Ensure FW supports get station link status */ ++ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { ++ ++ rQueryCmdStaStatistics.ucIndex = prStaRec->ucIndex; ++ COPY_MAC_ADDR(rQueryCmdStaStatistics.aucMacAddr, prQueryStaStatistics->aucMacAddr); ++ rQueryCmdStaStatistics.ucReadClear = TRUE; ++ ++ rResult = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STA_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryStaStatistics, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_GET_STA_STATISTICS_T), ++ (PUINT_8)&rQueryCmdStaStatistics, ++ pvQueryBuffer, u4QueryBufferLen); ++ ++ prQueryStaStatistics->u4Flag |= BIT(1); ++ } else { ++ rResult = WLAN_STATUS_NOT_SUPPORTED; ++ } ++ ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pVersion */ ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++/* 4 Auto Channel Selection */ ++WLAN_STATUS ++wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++ /* P_PARAM_GET_CHN_LOAD prQueryChnLoad; */ ++ P_PARAM_GET_LTE_MODE prLteMode; ++ CMD_GET_LTE_SAFE_CHN_T rQuery_LTE_SAFE_CHN; ++ ++ DBGLOG(P2P, INFO, "[Auto Channel]wlanoidQueryACSChannelList\n"); ++ do { ++ ASSERT(pvQueryBuffer); ++ ++ /* 4 1. Sanity test */ ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ prLteMode = (P_PARAM_GET_LTE_MODE) pvQueryBuffer; ++ ++ /* 4 3. Ensure FW supports get station link status */ ++#if 0 ++ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++ rCmdAccessReg.u4Address = 0xFFFFFFFF; ++ rCmdAccessReg.u4Data = ELEM_RM_TYPE_ACS_CHN; ++ ++ rResult = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ TRUE, ++ TRUE, ++ /* The handler to receive firmware notification */ ++ nicCmdEventQueryChannelLoad, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8)&rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); ++ ++ prQueryChnLoad->u4Flag |= BIT(1); ++ } else { ++ rResult = WLAN_STATUS_NOT_SUPPORTED; ++ } ++#endif ++ /* 4 4.Avoid LTE Channels */ ++ prLteMode->u4Flags &= BIT(0); ++ /*if(prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) */ { ++ ++ rResult = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LTE_CHN, ++ FALSE, ++ TRUE, ++ /* Query ID */ ++ TRUE, ++ /* The handler to receive firmware notification */ ++ nicCmdEventQueryLTESafeChn, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_GET_LTE_SAFE_CHN_T), ++ (PUINT_8)&rQuery_LTE_SAFE_CHN, ++ pvQueryBuffer, u4QueryBufferLen); ++ ++ DBGLOG(P2P, INFO, "[Auto Channel] Get LTE Channels\n"); ++ prLteMode->u4Flags |= BIT(1); ++ } ++ ++ /* 4 5. Calc the value */ ++ ++ DBGLOG(P2P, INFO, "[Auto Channel] Candidated Channels\n"); ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pVersion */ ++#endif ++#if CFG_SUPPORT_CFG_FILE ++ ++P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_32 i; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ASSERT(pucKey); ++ ++ prWlanCfgEntry = NULL; ++ ++ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { ++ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; ++ if (prWlanCfgEntry->aucKey[0] != '\0') { ++ DBGLOG(INIT, LOUD, "compare key %s saved key %s\n", pucKey, prWlanCfgEntry->aucKey); ++ if (kalStrniCmp(pucKey, prWlanCfgEntry->aucKey, WLAN_CFG_KEY_LEN_MAX - 1) == 0) ++ return prWlanCfgEntry; ++ } ++ } ++ ++ DBGLOG(INIT, LOUD, "wifi config there is no entry \'%s\'\n", pucKey); ++ return NULL; ++ ++} ++ ++WLAN_STATUS wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ASSERT(pucValue); ++ ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ kalStrnCpy(pucValue, prWlanCfgEntry->aucValue, WLAN_CFG_VALUE_LEN_MAX - 1); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (pucValueDef) ++ kalStrnCpy(pucValue, pucValueDef, WLAN_CFG_VALUE_LEN_MAX - 1); ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef) ++{ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_32 u4Value; ++ INT_32 u4Ret; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ++ u4Value = u4ValueDef; ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ u4Ret = kalkStrtou32(prWlanCfgEntry->aucValue, 0, &u4Value); ++ if (u4Ret) ++ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue u4Ret=%u\n", u4Ret); ++ /* u4Value = kalStrtoul(prWlanCfgEntry->aucValue, NULL, 0); */ ++ } ++ ++ return u4Value; ++} ++ ++INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef) ++{ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ INT_32 i4Value; ++ INT_32 i4Ret; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ++ i4Value = i4ValueDef; ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ i4Ret = kalkStrtos32(prWlanCfgEntry->aucValue, 0, &i4Value); ++ /* i4Ret = kalStrtol(prWlanCfgEntry->aucValue, NULL, 0); */ ++ if (i4Ret) ++ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue i4Ret=%u\n\r", i4Ret); ++ } ++ ++ return i4Value; ++} ++ ++WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_32 u4EntryIndex; ++ UINT_32 i; ++ UINT_8 ucExist; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ASSERT(prWlanCfg); ++ ASSERT(pucKey); ++ ++ /* Find the exist */ ++ ucExist = 0; ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (!prWlanCfgEntry) { ++ /* Find the empty */ ++ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { ++ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; ++ if (prWlanCfgEntry->aucKey[0] == '\0') ++ break; ++ } ++ ++ u4EntryIndex = i; ++ if (u4EntryIndex < WLAN_CFG_ENTRY_NUM_MAX) { ++ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[u4EntryIndex]; ++ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); ++ } else { ++ prWlanCfgEntry = NULL; ++ DBGLOG(INIT, ERROR, "wifi config there is no empty entry\n"); ++ } ++ } /* !prWlanCfgEntry */ ++ else ++ ucExist = 1; ++ ++ if (prWlanCfgEntry) { ++ if (ucExist == 0) { ++ kalStrnCpy(prWlanCfgEntry->aucKey, pucKey, WLAN_CFG_KEY_LEN_MAX - 1); ++ prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0'; ++ } ++ ++ if (pucValue && pucValue[0] != '\0') { ++ kalStrnCpy(prWlanCfgEntry->aucValue, pucValue, WLAN_CFG_VALUE_LEN_MAX - 1); ++ prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = '\0'; ++ ++ if (ucExist) { ++ if (prWlanCfgEntry->pfSetCb) ++ prWlanCfgEntry->pfSetCb(prAdapter, ++ prWlanCfgEntry->aucKey, ++ prWlanCfgEntry->aucValue, prWlanCfgEntry->pPrivate, 0); ++ } ++ } else { ++ /* Call the pfSetCb if value is empty ? */ ++ /* remove the entry if value is empty */ ++ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); ++ } ++ ++ } ++ /* prWlanCfgEntry */ ++ if (prWlanCfgEntry) { ++ DBGLOG(INIT, LOUD, "Set wifi config exist %u \'%s\' \'%s\'\n", ++ ucExist, prWlanCfgEntry->aucKey, prWlanCfgEntry->aucValue); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (pucKey) ++ DBGLOG(INIT, ERROR, "Set wifi config error key \'%s\'\n", pucKey); ++ if (pucValue) ++ DBGLOG(INIT, ERROR, "Set wifi config error value \'%s\'\n", pucValue); ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++WLAN_STATUS ++wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags) ++{ ++ ++ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; ++ P_WLAN_CFG_T prWlanCfg; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ASSERT(prWlanCfg); ++ ++ /* Find the exist */ ++ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); ++ ++ if (prWlanCfgEntry) { ++ prWlanCfgEntry->pfSetCb = pfSetCb; ++ prWlanCfgEntry->pPrivate = pPrivate; ++ } ++ ++ if (prWlanCfgEntry) ++ return WLAN_STATUS_SUCCESS; ++ else ++ return WLAN_STATUS_FAILURE; ++ ++} ++ ++WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value) ++{ ++ ++ P_WLAN_CFG_T prWlanCfg; ++ UINT_8 aucBuf[WLAN_CFG_VALUE_LEN_MAX]; ++ ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ ASSERT(prWlanCfg); ++ ++ kalMemZero(aucBuf, sizeof(aucBuf)); ++ ++ kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", (unsigned int)u4Value); ++ ++ return wlanCfgSet(prAdapter, pucKey, aucBuf, 0); ++} ++ ++enum { ++ STATE_EOF = 0, ++ STATE_TEXT = 1, ++ STATE_NEWLINE = 2 ++}; ++ ++struct WLAN_CFG_PARSE_STATE_S { ++ CHAR *ptr; ++ CHAR *text; ++ INT_32 nexttoken; ++ UINT_32 maxSize; ++}; ++ ++INT_32 wlanCfgFindNextToken(struct WLAN_CFG_PARSE_STATE_S *state) ++{ ++ CHAR *x = state->ptr; ++ CHAR *s; ++ ++ if (state->nexttoken) { ++ INT_32 t = state->nexttoken; ++ ++ state->nexttoken = 0; ++ return t; ++ } ++ ++ for (;;) { ++ switch (*x) { ++ case 0: ++ state->ptr = x; ++ return STATE_EOF; ++ case '\n': ++ x++; ++ state->ptr = x; ++ return STATE_NEWLINE; ++ case ' ': ++ case '\t': ++ case '\r': ++ x++; ++ continue; ++ case '#': ++ while (*x && (*x != '\n')) ++ x++; ++ if (*x == '\n') { ++ state->ptr = x + 1; ++ return STATE_NEWLINE; ++ } ++ state->ptr = x; ++ return STATE_EOF; ++ default: ++ goto text; ++ } ++ } ++ ++textdone: ++ state->ptr = x; ++ *s = 0; ++ return STATE_TEXT; ++text: ++ state->text = s = x; ++textresume: ++ for (;;) { ++ switch (*x) { ++ case 0: ++ goto textdone; ++ case ' ': ++ case '\t': ++ case '\r': ++ x++; ++ goto textdone; ++ case '\n': ++ state->nexttoken = STATE_NEWLINE; ++ x++; ++ goto textdone; ++ case '"': ++ x++; ++ for (;;) { ++ switch (*x) { ++ case 0: ++ /* unterminated quoted thing */ ++ state->ptr = x; ++ return STATE_EOF; ++ case '"': ++ x++; ++ goto textresume; ++ default: ++ *s++ = *x++; ++ } ++ } ++ break; ++ case '\\': ++ x++; ++ switch (*x) { ++ case 0: ++ goto textdone; ++ case 'n': ++ *s++ = '\n'; ++ break; ++ case 'r': ++ *s++ = '\r'; ++ break; ++ case 't': ++ *s++ = '\t'; ++ break; ++ case '\\': ++ *s++ = '\\'; ++ break; ++ case '\r': ++ /* \ -> line continuation */ ++ if (x[1] != '\n') { ++ x++; ++ continue; ++ } ++ case '\n': ++ /* \ -> line continuation */ ++ x++; ++ /* eat any extra whitespace */ ++ while ((*x == ' ') || (*x == '\t')) ++ x++; ++ continue; ++ default: ++ /* unknown escape -- just copy */ ++ *s++ = *x++; ++ } ++ continue; ++ default: ++ *s++ = *x++; ++ } ++ } ++ return STATE_EOF; ++} ++ ++WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]) ++{ ++ struct WLAN_CFG_PARSE_STATE_S state; ++ CHAR **args; ++ INT_32 nargs; ++ ++ if (cmdLine == NULL || argc == NULL || argv == NULL) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ args = argv; ++ nargs = 0; ++ state.ptr = cmdLine; ++ state.nexttoken = 0; ++ state.maxSize = 0; ++ ++ if (kalStrnLen(cmdLine, 512) >= 512) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ for (;;) { ++ switch (wlanCfgFindNextToken(&state)) { ++ case STATE_EOF: ++ goto exit; ++ case STATE_NEWLINE: ++ goto exit; ++ case STATE_TEXT: ++ if (nargs < WLAN_CFG_ARGV_MAX) ++ args[nargs++] = state.text; ++ break; ++ } ++ } ++ ++exit: ++ *argc = nargs; ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanCfgParseAddEntry(IN P_ADAPTER_T prAdapter, ++ PUINT_8 pucKeyHead, PUINT_8 pucKeyTail, PUINT_8 pucValueHead, PUINT_8 pucValueTail) ++{ ++ ++ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; ++ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++ UINT_32 u4Len; ++ ++ kalMemZero(aucKey, sizeof(aucKey)); ++ kalMemZero(aucValue, sizeof(aucValue)); ++ ++ if ((pucKeyHead == NULL) ++ || (pucValueHead == NULL) ++ ) ++ return WLAN_STATUS_FAILURE; ++ ++ if (pucKeyTail) { ++ if (pucKeyHead > pucKeyTail) ++ return WLAN_STATUS_FAILURE; ++ u4Len = pucKeyTail - pucKeyHead + 1; ++ } else ++ u4Len = kalStrnLen(pucKeyHead, WLAN_CFG_KEY_LEN_MAX - 1); ++ ++ if (u4Len >= WLAN_CFG_KEY_LEN_MAX) ++ u4Len = WLAN_CFG_KEY_LEN_MAX - 1; ++ ++ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) ++ kalStrnCpy(aucKey, pucKeyHead, u4Len); ++ else ++ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); ++ ++ if (pucValueTail) { ++ if (pucValueHead > pucValueTail) ++ return WLAN_STATUS_FAILURE; ++ u4Len = pucValueTail - pucValueHead + 1; ++ } else ++ u4Len = kalStrnLen(pucValueHead, WLAN_CFG_VALUE_LEN_MAX - 1); ++ ++ if (u4Len >= WLAN_CFG_VALUE_LEN_MAX) ++ u4Len = WLAN_CFG_VALUE_LEN_MAX - 1; ++ ++ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) ++ kalStrnCpy(aucValue, pucValueHead, u4Len); ++ else ++ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); ++ ++ return wlanCfgSet(prAdapter, aucKey, aucValue, 0); ++} ++ ++enum { ++ WAIT_KEY_HEAD = 0, ++ WAIT_KEY_TAIL, ++ WAIT_VALUE_HEAD, ++ WAIT_VALUE_TAIL, ++ WAIT_COMMENT_TAIL ++}; ++ ++WLAN_STATUS wlanCfgParse(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen) ++{ ++ ++ struct WLAN_CFG_PARSE_STATE_S state; ++ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; ++ CHAR **args; ++ INT_32 nargs; ++ ++ if (pucConfigBuf == NULL) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ if (kalStrnLen(pucConfigBuf, 4000) >= 4000) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ if (u4ConfigBufLen == 0) ++ return WLAN_STATUS_FAILURE; ++ args = apcArgv; ++ nargs = 0; ++ state.ptr = pucConfigBuf; ++ state.nexttoken = 0; ++ state.maxSize = u4ConfigBufLen; ++ ++ for (;;) { ++ switch (wlanCfgFindNextToken(&state)) { ++ case STATE_EOF: ++ if (nargs > 1) ++ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); ++ goto exit; ++ case STATE_NEWLINE: ++ if (nargs > 1) ++ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); ++ nargs = 0; ++ break; ++ case STATE_TEXT: ++ if (nargs < WLAN_CFG_ARGV_MAX) ++ args[nargs++] = state.text; ++ break; ++ } ++ } ++ ++exit: ++ return WLAN_STATUS_SUCCESS; ++ ++#if 0 ++ /* Old version */ ++ UINT_32 i; ++ UINT_8 c; ++ PUINT_8 pbuf; ++ UINT_8 ucState; ++ PUINT_8 pucKeyTail = NULL; ++ PUINT_8 pucKeyHead = NULL; ++ PUINT_8 pucValueHead = NULL; ++ PUINT_8 pucValueTail = NULL; ++ ++ ucState = WAIT_KEY_HEAD; ++ pbuf = pucConfigBuf; ++ ++ for (i = 0; i < u4ConfigBufLen; i++) { ++ c = pbuf[i]; ++ if (c == '\r' || c == '\n') { ++ ++ if (ucState == WAIT_VALUE_TAIL) { ++ /* Entry found */ ++ if (pucValueHead) ++ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, ++ pucValueHead, pucValueTail); ++ } ++ ucState = WAIT_KEY_HEAD; ++ pucKeyTail = NULL; ++ pucKeyHead = NULL; ++ pucValueHead = NULL; ++ pucValueTail = NULL; ++ ++ } else if (c == '=') { ++ if (ucState == WAIT_KEY_TAIL) { ++ pucKeyTail = &pbuf[i - 1]; ++ ucState = WAIT_VALUE_HEAD; ++ } ++ } else if (c == ' ' || c == '\t') { ++ if (ucState == WAIT_KEY_HEAD) ++ ; ++ else if (ucState == WAIT_KEY_TAIL) { ++ pucKeyTail = &pbuf[i - 1]; ++ ucState = WAIT_VALUE_HEAD; ++ } ++ } else { ++ ++ if (c == '#') { ++ /* comments */ ++ if (ucState == WAIT_KEY_HEAD) ++ ucState = WAIT_COMMENT_TAIL; ++ else if (ucState == WAIT_VALUE_TAIL) ++ pucValueTail = &pbuf[i]; ++ ++ } else { ++ if (ucState == WAIT_KEY_HEAD) { ++ pucKeyHead = &pbuf[i]; ++ pucKeyTail = &pbuf[i]; ++ ucState = WAIT_KEY_TAIL; ++ } else if (ucState == WAIT_VALUE_HEAD) { ++ pucValueHead = &pbuf[i]; ++ pucValueTail = &pbuf[i]; ++ ucState = WAIT_VALUE_TAIL; ++ } else if (ucState == WAIT_VALUE_TAIL) ++ pucValueTail = &pbuf[i]; ++ } ++ } ++ ++ } /* for */ ++ ++ if (ucState == WAIT_VALUE_TAIL) { ++ /* Entry found */ ++ if (pucValueTail) ++ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, pucValueHead, pucValueTail); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++#endif ++ ++#if CFG_SUPPORT_CFG_FILE ++WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags) ++{ ++ P_WLAN_CFG_T prWlanCfg; ++ /* P_WLAN_CFG_ENTRY_T prWlanCfgEntry; */ ++ prAdapter->prWlanCfg = &prAdapter->rWlanCfg; ++ prWlanCfg = prAdapter->prWlanCfg; ++ ++ kalMemZero(prWlanCfg, sizeof(WLAN_CFG_T)); ++ ASSERT(prWlanCfg); ++ prWlanCfg->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX; ++ prWlanCfg->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX; ++ prWlanCfg->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX; ++#if 0 ++ DBGLOG(INIT, INFO, "Init wifi config len %u max entry %u\n", u4ConfigBufLen, prWlanCfg->u4WlanCfgEntryNumMax); ++#endif ++ /* self test */ ++ wlanCfgSet(prAdapter, "ConfigValid", "0x123", 0); ++ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 0x123) ++ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); ++ wlanCfgSet(prAdapter, "ConfigValid", "1", 0); ++ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 1) ++ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); ++#if 0 /* soc chip didn't support these parameters now */ ++ /* Add initil config */ ++ /* use g,wlan,p2p,ap as prefix */ ++ /* Don't set cb here , overwrite by another api */ ++ wlanCfgSet(prAdapter, "TxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "RxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "RxBeamformee", "1", 0); ++ wlanCfgSet(prAdapter, "RoamTh1", "100", 0); ++ wlanCfgSet(prAdapter, "RoamTh2", "150", 0); ++ wlanCfgSet(prAdapter, "wlanRxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "apRxLdpc", "1", 0); ++ wlanCfgSet(prAdapter, "p2pRxLdpc", "1", 0); ++#endif ++ /* Parse the pucConfigBuff */ ++ ++ if (pucConfigBuf && (u4ConfigBufLen > 0)) ++ wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to initialize WLAN feature options ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanCfgApply(IN P_ADAPTER_T prAdapter) ++{ ++#define STR2BYTE(s) (((((PUINT_8)s)[0]-'0')*10)+(((PUINT_8)s)[1]-'0')) ++ CHAR aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; ++ P_REG_INFO_T prRegInfo = &prAdapter->prGlueInfo->rRegInfo; ++ P_TX_PWR_PARAM_T prTxPwr = &prRegInfo->rTxPwr; ++ ++ kalMemZero(aucValue, sizeof(aucValue)); ++ DBGLOG(INIT, LOUD, "CFG_FILE: Apply Config File\n"); ++ /* Apply COUNTRY Config */ ++ if (wlanCfgGet(prAdapter, "country", aucValue, "", 0) == WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Found Country Key, Value=%s\n", aucValue); ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode = ++ (((UINT_16) aucValue[0]) << 8) | ((UINT_16) aucValue[1]); ++ prRegInfo->au2CountryCode[0] = aucValue[0]; ++ prRegInfo->au2CountryCode[1] = aucValue[1]; ++ } ++ prWifiVar->ucApWpsMode = (UINT_8) wlanCfgGetUint32(prAdapter, "ApWpsMode", 0); ++ prWifiVar->ucCert11nMode = (UINT_8)wlanCfgGetUint32(prAdapter, "Cert11nMode", 0); ++ DBGLOG(INIT, LOUD, "CFG_FILE: ucApWpsMode = %u, ucCert11nMode = %u\n", ++ prWifiVar->ucApWpsMode, prWifiVar->ucCert11nMode); ++ if (prWifiVar->ucCert11nMode == 1) ++ nicWriteMcr(prAdapter, 0x11111115 , 1); ++ ++ if (wlanCfgGet(prAdapter, "5G_support", aucValue, "", 0) == WLAN_STATUS_SUCCESS) ++ prRegInfo->ucSupport5GBand = (*aucValue == 'y') ? 1 : 0; ++ if (wlanCfgGet(prAdapter, "TxPower2G4CCK", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 2) { ++ prTxPwr->cTxPwr2G4Cck = STR2BYTE(aucValue); ++ DBGLOG(INIT, LOUD, "2.4G cck=%d\n", prTxPwr->cTxPwr2G4Cck); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower2G4OFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS && ++ kalStrLen(aucValue) == 10) { ++ prTxPwr->cTxPwr2G4OFDM_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr2G4OFDM_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr2G4OFDM_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr2G4OFDM_48Mbps = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr2G4OFDM_54Mbps = STR2BYTE(aucValue + 8); ++ DBGLOG(INIT, LOUD, "2.4G OFDM=%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr2G4OFDM_BPSK, prTxPwr->cTxPwr2G4OFDM_QPSK, ++ prTxPwr->cTxPwr2G4OFDM_16QAM, prTxPwr->cTxPwr2G4OFDM_48Mbps, ++ prTxPwr->cTxPwr2G4OFDM_54Mbps); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower2G4HT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS && ++ kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr2G4HT20_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr2G4HT20_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr2G4HT20_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr2G4HT20_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr2G4HT20_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr2G4HT20_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "2.4G HT20=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr2G4HT20_BPSK, prTxPwr->cTxPwr2G4HT20_QPSK, ++ prTxPwr->cTxPwr2G4HT20_16QAM, prTxPwr->cTxPwr2G4HT20_MCS5, ++ prTxPwr->cTxPwr2G4HT20_MCS6, prTxPwr->cTxPwr2G4HT20_MCS7); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower2G4HT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS && ++ kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr2G4HT40_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr2G4HT40_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr2G4HT40_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr2G4HT40_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr2G4HT40_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr2G4HT40_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "2.4G HT40=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr2G4HT40_BPSK, prTxPwr->cTxPwr2G4HT40_QPSK, ++ prTxPwr->cTxPwr2G4HT40_16QAM, prTxPwr->cTxPwr2G4HT40_MCS5, ++ prTxPwr->cTxPwr2G4HT40_MCS6, prTxPwr->cTxPwr2G4HT40_MCS7); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower5GOFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 10) { ++ prTxPwr->cTxPwr5GOFDM_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr5GOFDM_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr5GOFDM_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr5GOFDM_48Mbps = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr5GOFDM_54Mbps = STR2BYTE(aucValue + 8); ++ DBGLOG(INIT, LOUD, "5G OFDM=%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr5GOFDM_BPSK, prTxPwr->cTxPwr5GOFDM_QPSK, ++ prTxPwr->cTxPwr5GOFDM_16QAM, prTxPwr->cTxPwr5GOFDM_48Mbps, ++ prTxPwr->cTxPwr5GOFDM_54Mbps); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower5GHT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr5GHT20_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr5GHT20_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr5GHT20_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr5GHT20_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr5GHT20_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr5GHT20_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "5G HT20=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr5GHT20_BPSK, prTxPwr->cTxPwr5GHT20_QPSK, ++ prTxPwr->cTxPwr5GHT20_16QAM, prTxPwr->cTxPwr5GHT20_MCS5, prTxPwr->cTxPwr5GHT20_MCS6, ++ prTxPwr->cTxPwr5GHT20_MCS7); ++ } ++ if (wlanCfgGet(prAdapter, "TxPower5GHT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS ++ && kalStrLen(aucValue) == 12) { ++ prTxPwr->cTxPwr5GHT40_BPSK = STR2BYTE(aucValue); ++ prTxPwr->cTxPwr5GHT40_QPSK = STR2BYTE(aucValue + 2); ++ prTxPwr->cTxPwr5GHT40_16QAM = STR2BYTE(aucValue + 4); ++ prTxPwr->cTxPwr5GHT40_MCS5 = STR2BYTE(aucValue + 6); ++ prTxPwr->cTxPwr5GHT40_MCS6 = STR2BYTE(aucValue + 8); ++ prTxPwr->cTxPwr5GHT40_MCS7 = STR2BYTE(aucValue + 10); ++ DBGLOG(INIT, LOUD, "5G HT40=%d,%d,%d,%d,%d,%d\n", ++ prTxPwr->cTxPwr5GHT40_BPSK, prTxPwr->cTxPwr5GHT40_QPSK, ++ prTxPwr->cTxPwr5GHT40_16QAM, prTxPwr->cTxPwr5GHT40_MCS5, prTxPwr->cTxPwr5GHT40_MCS6, ++ prTxPwr->cTxPwr5GHT40_MCS7); ++ } ++ /* TODO: Apply other Config */ ++} ++#endif /* CFG_SUPPORT_CFG_FILE */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c +new file mode 100644 +index 000000000000..993ff061ed20 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c +@@ -0,0 +1,11050 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_oid.c#5 ++*/ ++ ++/*! \file wlanoid.c ++ \brief This file contains the WLAN OID processing routines of Windows driver for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_oid.c ++** ++** 09 05 2013 cp.wu ++** isolate logic regarding roaming & reassociation ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 09 02 2013 cp.wu ++** add path to handle reassociation request ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 06 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * using the wlanSendSetQueryCmd to set the tx power control cmd. ++ * ++ * 01 06 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * change the set tx power cmd name. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 12 20 2011 cp.wu ++ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information ++ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO ++ * to expose version information ++ * ++ * 12 05 2011 cp.wu ++ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path ++ * add CONNECT_BY_BSSID policy ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to ++ * asynchronous approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state ++ * without join timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 11 21 2011 cp.wu ++ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing ++ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer ++ * add more checking for such cases ++ * ++ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. ++ * add some tweaking to protect such cases because that net device has become invalid. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters of bb and ar for xlog. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 11 09 2011 george.huang ++ * [WCXRP00000871] [MT6620 Wi-Fi][FW] Include additional wakeup condition, which is by ++ * consequent DTIM unicast indication add XLOG for Set PS mode entry ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 11 02 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add RDD certification features. ++ * ++ * 10 21 2011 eddie.chen ++ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout ++ * Add switch to ignore the STA aging timeout. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 15 2011 tsaiyuan.hsu ++ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA ++ * correct fifo full control from query to set operation for CTIA. ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 17 2011 tsaiyuan.hsu ++ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA ++ * add system config for CTIA. ++ * ++ * 08 15 2011 george.huang ++ * [MT6620 Wi-Fi][FW] handle TSF drift for connection detection ++ * . ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 11 2011 wh.su ++ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, ++ * for customer not enable WAPI ++ * For make sure wapi initial value is set. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 05 02 2011 eddie.chen ++ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control ++ * Fix compile warning. ++ * ++ * 04 29 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * . ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * add more debug message ++ * ++ * 04 26 2011 eddie.chen ++ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control ++ * Add rx path profiling. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 03 31 2011 puff.wen ++ * NULL ++ * . ++ * ++ * 03 29 2011 puff.wen ++ * NULL ++ * Add chennel switch for stress test ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning ++ * surpress klock warning with code path rewritten ++ * ++ * 03 24 2011 wh.su ++ * [WCXRP00000595] [MT6620 Wi-Fi][Driver] at CTIA indicate disconnect to make the ps profile can apply ++ * use disconnect event instead of ais abort for CTIA testing. ++ * ++ * 03 23 2011 george.huang ++ * [WCXRP00000586] [MT6620 Wi-Fi][FW] Modify for blocking absence request right after connected ++ * revise for CTIA power mode setting ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 17 2011 yarco.yang ++ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage ++ * . ++ * ++ * 03 15 2011 george.huang ++ * [WCXRP00000557] [MT6620 Wi-Fi] Support current consumption test mode commands ++ * Support current consumption measurement mode command ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 04 2011 cp.wu ++ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection ++ * surpress compile warning occurred when compiled by GNU compiler collection. ++ * ++ * 03 03 2011 wh.su ++ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue ++ * fixed the enter ctia test mode issue. ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Update sigma CAPI for U-APSD setting ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Support UAPSD/OppPS/NoA parameter setting ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as ++ * initial RSSI right after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting ++ * Support CTIA power mode setting. ++ * ++ * 01 26 2011 wh.su ++ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux ++ * adding the SW cmd ioctl support, use set/get structure ioctl. ++ * ++ * 01 25 2011 cp.wu ++ * [WCXRP00000394] [MT6620 Wi-Fi][Driver] Count space needed for generating error message in ++ * scanning list into buffer size checking ++ * when doing size prechecking, check illegal MAC address as well ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * Add Stress test ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * check if allow to switch to IBSS mode via concurrent module before setting to IBSS mode ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000342] [MT6620 Wi-Fi][Driver] show error code in scanning list when MAC address is not ++ * correctly configured in NVRAM ++ * show error code 0x10 when MAC address in NVRAM is not configured correctly. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations ++ * to ease physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 28 2010 george.huang ++ * [WCXRP00000232] [MT5931 Wi-Fi][FW] Modifications for updated HW power on sequence and related design ++ * support WMM-PS U-APSD AC assignment. ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 16 2010 cp.wu ++ * [WCXRP00000268] [MT6620 Wi-Fi][Driver] correction for WHQL failed items ++ * correction for OID_802_11_NETWORK_TYPES_SUPPORTED handlers ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork ++ * suppress warning reported by Klockwork. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 30 2010 cp.wu ++ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 ++ * . ++ * ++ * 11 26 2010 cp.wu ++ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only ++ * with necessary data field checking ++ * 1. NVRAM error is now treated as warning only, thus normal operation is still available ++ * but extra scan result used to indicate user is attached ++ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown ++ * ++ * 11 25 2010 cp.wu ++ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM ++ * add scanning with specified SSID facility to AIS-FSM ++ * ++ * 11 21 2010 wh.su ++ * [WCXRP00000192] [MT6620 Wi-Fi][Driver] Fixed fail trying to build connection with Security ++ * AP while enable WAPI message check ++ * Not set the wapi mode while the wapi assoc info set non-wapi ie. ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value ++ * fixed the.pmkid value mismatch issue ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying ++ * current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 22 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * dos2unix conversion. ++ * ++ * 10 20 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * use OID_CUSTOM_TEST_MODE as indication for driver reset ++ * by dropping pending TX packets ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version ++ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android complete ++ * implementation of Android NVRAM access ++ * ++ * 10 06 2010 yuche.tsai ++ * NULL ++ * Update SLT 5G Test Channel Set. ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 06 2010 yuche.tsai ++ * NULL ++ * Update For SLT 5G Test Channel Selection Rule. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form ++ * Query buffer size needs to be enlarged due to result is filled in 4-bytes alignment boundary ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and ++ * replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form ++ * Extend result length to multiples of 4-bytes ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate unused variables which lead gcc to argue ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Update SLT due to API change of SCAN module. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * Androi/Linux: return current operating channel information ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * 1) initialize for correct parameter even for disassociation. ++ * 2) AIS-FSM should have a limit on trials to build connection ++ * ++ * 09 03 2010 yuche.tsai ++ * NULL ++ * Refine SLT IO control handler. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 30 2010 chinglan.wang ++ * NULL ++ * Modify the rescan condition. ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 27 2010 chinglan.wang ++ * NULL ++ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cp.wu ++ * NULL ++ * 1) initialize variable for enabling short premable/short time slot. ++ * 2) add compile option for disabling online scan ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * . ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * update params defined in CMD_SET_NETWORK_ADDRESS_LIST ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * fix for check build WHQL testing: ++ * 1) do not assert query buffer if indicated buffer length is zero ++ * 2) sdio.c has bugs which cause freeing same pointer twice ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 08 04 2010 george.huang ++ * NULL ++ * handle change PS mode OID/ CMD ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * bypass u4FuncData for RF-Test query request as well. ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 26 2010 cp.wu ++ * ++ * re-commit code logic being overwriten. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one ++ * 2) refine disconnection behaviour when issued during BG-SCAN process ++ * ++ * 07 19 2010 wh.su ++ * ++ * modify the auth and encry status variable. ++ * ++ * 07 16 2010 cp.wu ++ * ++ * remove work-around in case SCN is not available. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. ++ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add SCN compilation option. ++ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement SCAN-REQUEST oid as mailbox message dispatching. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * adding the compiling flag for oid pmkid. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move timer callback to glue layer. ++ * ++ * 05 28 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * simplify cmd packet sending for RF test and MCR access OIDs ++ * ++ * 05 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * disable radio even when STA is not associated. ++ * ++ * 05 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct 2 OID behaviour to meet WHQL requirement. ++ * ++ * 05 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) Modify set mac address code ++ * 2) remove power management macro ++ * ++ * 05 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct BSSID_LIST oid when radio if turned off. ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll ++ * 2) correct address list parsing ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * disable wlanoidSetNetworkAddress() temporally. ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * some OIDs should be DRIVER_CORE instead of GLUE_EXTENSION ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. ++ * 2) finish statistics OIDs ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change OID behavior to meet WHQL requirement. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement Wakeup-on-LAN except firmware integration part ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct wlanoidSet802dot11PowerSaveProfile implementation. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) enable CMD/EVENT ver 0.9 definition. ++ * 2) abandon use of ENUM_MEDIA_STATE ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_DISASSOCIATE handling. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add dissassocation support for wpa supplicant ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct return value. ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add NULL OID implementation for WOL-related OIDs. ++ * ++ * 05 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * for disassociation, still use parameter with current setting. ++ * ++ * 05 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * for disassociation, generate a WZC-compatible invalid SSID. ++ * ++ * 05 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * associate to illegal SSID when handling OID_802_11_DISASSOCIATE ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * reserve field of privacy filter and RTS threshold setting. ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support ++ * enable RX filter OID ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add ioctl of power management ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * 2) command sequence number is now increased atomically ++ * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_CONFIGURATION query for infrastructure mode. ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) remove unused spin lock declaration ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * are done in adapter layer. ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)improve none-glue code portability ++ * (2) disable set Multicast address during atomic context ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * ePowerCtrl is not necessary as a glue variable. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * statistics information OIDs are now handled by querying from firmware domain ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve glue code portability ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * the frequency is used for adhoc connection only ++ * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list ++ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result ++ * ++ * 03 19 2010 wh.su ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * adding the check for pass WHQL test item. ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++* 03 16 2010 wh.su ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * fixed some whql pre-test fail case. ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. ++ * ++ * 02 24 2010 wh.su ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * Don't needed to check the auth mode, WHQL testing not specific at auth wpa2. ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * do not check SSID validity anymore. ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * 2. follow MSDN defined behavior when associates to another AP ++ * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move ucCmdSeqNum as instance variable ++ * ++ * 02 04 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when OID_CUSTOM_OID_INTERFACE_VERSION is queried, do modify connection states ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) implement timeout mechanism when OID is pending for longer than 1 second ++ * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * 4. correct some HAL implementation ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * OID_802_11_RSSI, ++ * OID_802_11_RSSI_TRIGGER, ++ * OID_802_11_STATISTICS, ++ * OID_802_11_DISASSOCIATE, ++ * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * do not fill ucJoinOnly currently ++ * ++ * 01 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * enable to connect to ad-hoc network ++ * ++ * 01 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * .implement Set/Query BeaconInterval/AtimWindow ++ * ++ * 01 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * .Set/Get AT Info is not blocked even when driver is not in fg test mode ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * and result is retrieved by get ATInfo instead ++ * 2) add 4 counter for recording aggregation statistics ++ * ++ * 12 28 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate redundant variables for connection_state ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-16 22:13:36 GMT mtk02752 ++** change hard-coded MAC address to match with FW (temporally) ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-10 16:49:50 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-08 17:38:49 GMT mtk02752 ++** + add OID for RF test ++** * MCR RD/WR are modified to match with cmd/event definition ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-12-08 11:32:20 GMT mtk02752 ++** add skeleton for RF test implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-12-03 16:43:24 GMT mtk01461 ++** Modify query SCAN list oid by adding prEventScanResult ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-03 16:39:27 GMT mtk01461 ++** Sync CMD data structure in set ssid oid ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-03 16:28:22 GMT mtk01461 ++** Add invalid check of set SSID oid and fix query scan list oid ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-30 17:33:08 GMT mtk02752 ++** implement wlanoidSetInfrastructureMode/wlanoidQueryInfrastructureMode ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-30 10:53:49 GMT mtk02752 ++** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-30 09:22:48 GMT mtk02752 ++** correct wifi cmd length mismatch ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-25 21:34:33 GMT mtk02752 ++** sync EVENT_SCAN_RESULT_T with firmware ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 21:03:27 GMT mtk02752 ++** implement wlanoidQueryBssidList() ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-25 18:17:17 GMT mtk02752 ++** refine GL_WLAN_INFO_T for buffering scan result ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-23 20:28:51 GMT mtk02752 ++** some OID will be set to WLAN_STATUS_PENDING until it is sent via wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-23 17:56:36 GMT mtk02752 ++** implement wlanoidSetBssidListScan(), wlanoidSetBssid() and wlanoidSetSsid() ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-13 17:20:53 GMT mtk02752 ++** add Set BSSID/SSID path but disabled temporally due to FW is not ready yet ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 12:28:58 GMT mtk02752 ++** add wlanoidSetBssidListScan -> cmd_info path ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-09 22:48:07 GMT mtk01084 ++** modify test cases entry ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-04 14:10:58 GMT mtk01084 ++** add new test interfaces ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-30 18:17:10 GMT mtk01084 ++** fix compiler warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:46:26 GMT mtk01084 ++** add test functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:07:56 GMT mtk01084 ++** include new file ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:29 GMT mtk01084 ++** modify for new HW architecture ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-02 13:48:49 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-09-09 17:26:04 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-21 12:09:50 GMT mtk01461 ++** Update for MCR Write OID ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:35:18 GMT mtk01461 ++** Update wlanoidQueryMcrRead() for composing CMD_INFO_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 18:09:51 GMT mtk01426 ++** Remove kalIndicateStatusAndComplete() in wlanoidQueryOidInterfaceVersion() ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-14 15:51:50 GMT mtk01426 ++** Add MCR read/write support ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:40 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:06:31 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/****************************************************************************** ++* C O M P I L E R F L A G S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************* ++*/ ++#include "precomp.h" ++#include "mgmt/rsn.h" ++ ++#include ++ ++/****************************************************************************** ++* C O N S T A N T S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* D A T A T Y P E S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P U B L I C D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P R I V A T E D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* M A C R O S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N S ++******************************************************************************* ++*/ ++#if CFG_ENABLE_STATISTICS_BUFFERING ++static BOOLEAN IsBufferedStatisticsUsable(P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsStatValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= CFG_STATISTICS_VALID_CYCLE) ++ return TRUE; ++ else ++ return FALSE; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the supported physical layer network ++* type that can be used by the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ UINT_32 u4NumItem = 0; ++ ENUM_PARAM_NETWORK_TYPE_T eSupportedNetworks[PARAM_NETWORK_TYPE_NUM]; ++ PPARAM_NETWORK_TYPE_LIST prSupported; ++ ++ /* The array of all physical layer network subtypes that the driver supports. */ ++ ++ DEBUGFUNC("wlanoidQueryNetworkTypesSupported"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ /* Init. */ ++ for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; u4NumItem++) ++ eSupportedNetworks[u4NumItem] = 0; ++ ++ u4NumItem = 0; ++ ++ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS; ++ u4NumItem++; ++ ++ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24; ++ u4NumItem++; ++ ++ *pu4QueryInfoLen = ++ (UINT_32) OFFSET_OF(PARAM_NETWORK_TYPE_LIST, eNetworkType) + ++ (u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prSupported = (PPARAM_NETWORK_TYPE_LIST) pvQueryBuffer; ++ prSupported->NumberOfItems = u4NumItem; ++ kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); ++ ++ DBGLOG(OID, TRACE, "NDIS supported network type list: %u\n", prSupported->NumberOfItems); ++ DBGLOG_MEM8(OID, TRACE, prSupported, *pu4QueryInfoLen); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryNetworkTypesSupported */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current physical layer network ++* type used by the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ /* TODO: need to check the OID handler content again!! */ ++ ++ ENUM_PARAM_NETWORK_TYPE_T rCurrentNetworkTypeInUse = PARAM_NETWORK_TYPE_OFDM24; ++ ++ DEBUGFUNC("wlanoidQueryNetworkTypeInUse"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) ++ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkType); ++ else ++ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkTypeInUse); ++ ++ *(P_ENUM_PARAM_NETWORK_TYPE_T) pvQueryBuffer = rCurrentNetworkTypeInUse; ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ ++ DBGLOG(OID, TRACE, "Network type in use: %d\n", rCurrentNetworkTypeInUse); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryNetworkTypeInUse */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the physical layer network type used ++* by the driver. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns the ++* amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted. ++* \retval WLAN_STATUS_INVALID_DATA The given network type is not in the ++* supported list. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ /* TODO: need to check the OID handler content again!! */ ++ ++ ENUM_PARAM_NETWORK_TYPE_T eNewNetworkType; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidSetNetworkTypeInUse"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ eNewNetworkType = *(P_ENUM_PARAM_NETWORK_TYPE_T) pvSetBuffer; ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); ++ ++ DBGLOG(OID, INFO, "New network type: %d mode\n", eNewNetworkType); ++ ++ switch (eNewNetworkType) { ++ ++ case PARAM_NETWORK_TYPE_DS: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ ++ case PARAM_NETWORK_TYPE_OFDM5: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; ++ break; ++ ++ case PARAM_NETWORK_TYPE_OFDM24: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; ++ break; ++ ++ case PARAM_NETWORK_TYPE_AUTOMODE: ++ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_AUTOMODE; ++ break; ++ ++ case PARAM_NETWORK_TYPE_FH: ++ DBGLOG(OID, INFO, "Not support network type: %d\n", eNewNetworkType); ++ rStatus = WLAN_STATUS_NOT_SUPPORTED; ++ break; ++ ++ default: ++ DBGLOG(OID, INFO, "Unknown network type: %d\n", eNewNetworkType); ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ /* Verify if we support the new network type. */ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(OID, WARN, "Unknown network type: %d\n", eNewNetworkType); ++ ++ return rStatus; ++} /* wlanoidSetNetworkTypeInUse */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current BSSID. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidQueryBssid"); ++ ++ ASSERT(prAdapter); ++ ++ if (u4QueryBufferLen < MAC_ADDR_LEN) { ++ ASSERT(pu4QueryInfoLen); ++ *pu4QueryInfoLen = MAC_ADDR_LEN; ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) ++ kalMemCopy(pvQueryBuffer, prAdapter->rWlanInfo.rCurrBssId.arMacAddress, MAC_ADDR_LEN); ++ else if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS) { ++ PARAM_MAC_ADDRESS aucTemp; /*!< BSSID */ ++ ++ COPY_MAC_ADDR(aucTemp, prAdapter->rWlanInfo.rCurrBssId.arMacAddress); ++ aucTemp[0] &= ~BIT(0); ++ aucTemp[1] |= BIT(1); ++ COPY_MAC_ADDR(pvQueryBuffer, aucTemp); ++ } else ++ rStatus = WLAN_STATUS_ADAPTER_NOT_READY; ++ ++ *pu4QueryInfoLen = MAC_ADDR_LEN; ++ return rStatus; ++} /* wlanoidQueryBssid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the list of all BSSIDs detected by ++* the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 i, u4BssidListExLen; ++ P_PARAM_BSSID_LIST_EX_T prList; ++ P_PARAM_BSSID_EX_T prBssidEx; ++ PUINT_8 cp; ++ ++ DEBUGFUNC("wlanoidQueryBssidList"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) { ++ ASSERT(pvQueryBuffer); ++ ++ if (!pvQueryBuffer) ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ u4BssidListExLen = 0; ++ ++ if (prAdapter->fgIsRadioOff == FALSE) { ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) ++ u4BssidListExLen += ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4Length); ++ } ++ ++ if (u4BssidListExLen) ++ u4BssidListExLen += 4; /* u4NumberOfItems. */ ++ else ++ u4BssidListExLen = sizeof(PARAM_BSSID_LIST_EX_T); ++ ++ *pu4QueryInfoLen = u4BssidListExLen; ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* Clear the buffer */ ++ kalMemZero(pvQueryBuffer, u4BssidListExLen); ++ ++ prList = (P_PARAM_BSSID_LIST_EX_T) pvQueryBuffer; ++ cp = (PUINT_8) &prList->arBssid[0]; ++ ++ if (prAdapter->fgIsRadioOff == FALSE && prAdapter->rWlanInfo.u4ScanResultNum > 0) { ++ /* fill up for each entry */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ prBssidEx = (P_PARAM_BSSID_EX_T) cp; ++ ++ /* copy structure */ ++ kalMemCopy(prBssidEx, ++ &(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /*For WHQL test, Rssi should be in range -10 ~ -200 dBm */ ++ if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ ++ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { ++ /* copy IEs */ ++ kalMemCopy(prBssidEx->aucIEs, ++ prAdapter->rWlanInfo.apucScanResultIEs[i], ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength); ++ } ++ /* 4-bytes alignement */ ++ prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length); ++ ++ cp += prBssidEx->u4Length; ++ prList->u4NumberOfItems++; ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryBssidList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to perform ++* scanning. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_SSID_T prSsid; ++ PARAM_SSID_T rSsid; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidSetBssidListScan()"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = 0; ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(OID, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ DBGLOG(OID, TRACE, "Scan\n"); ++ ++ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, u4SetBufferLen); ++ prSsid = &rSsid; ++ } else { ++ prSsid = NULL; ++ } ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { ++ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); ++ } else { ++ /* reject the scan request */ ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else { ++ /* reject the scan request */ ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else ++#endif ++ { ++ if (prAdapter->fgEnOnlineScan == TRUE) { ++ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); ++ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); ++ } else { ++ /* reject the scan request */ ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ return rStatus; ++} /* wlanoidSetBssidListScan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to perform ++* scanning with attaching information elements(IEs) specified from user space ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_SCAN_REQUEST_EXT_T prScanRequest; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_PARAM_SSID_T prSsid; ++ PUINT_8 pucIe; ++ UINT_32 u4IeLength; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_8 ucScanTime = AIS_SCN_DONE_TIMEOUT_SEC; ++ ++ DEBUGFUNC("wlanoidSetBssidListScanExt()"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, ERROR, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (prAdapter->fgTestMode) { ++ DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)) { ++ DBGLOG(OID, ERROR, "u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(OID, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ DBGLOG(OID, TRACE, "ScanEx\n"); ++ ++ /* clear old scan backup results if exists */ ++ { ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); ++ prBssDesc->u2RawLength = 0; ++ } ++ } ++ } ++ ++ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { ++ prScanRequest = (P_PARAM_SCAN_REQUEST_EXT_T) pvSetBuffer; ++ prSsid = &(prScanRequest->rSsid); ++ pucIe = prScanRequest->pucIE; ++ u4IeLength = prScanRequest->u4IELength; ++ } else { ++ prScanRequest = NULL; ++ prSsid = NULL; ++ pucIe = NULL; ++ u4IeLength = 0; ++ } ++ ++/* P_AIS_FSM_INFO_T prAisFsmInfo; */ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++/* #if CFG_SUPPORT_WFD */ ++#if 0 ++ if ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.ucWfdEnable) && ++ ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == ++ PARAM_MEDIA_STATE_CONNECTED) { ++ DBGLOG(OID, TRACE, "Twice the Scan Time for WFD\n"); ++ ucScanTime *= 2; ++ } ++ } ++#endif /* CFG_SUPPORT_WFD */ ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer, SEC_TO_MSEC(ucScanTime)); ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { ++ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); ++ } else { ++ /* reject the scan request */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else { ++ /* reject the scan request */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else ++#endif ++ { ++ if (prAdapter->fgEnOnlineScan == TRUE) { ++ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); ++ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); ++ } else { ++ /* reject the scan request */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ rStatus = WLAN_STATUS_FAILURE; ++ DBGLOG(OID, WARN, "ScanEx fail %d!\n", prAdapter->fgEnOnlineScan); ++ } ++ } ++ ++ return rStatus; ++} /* wlanoidSetBssidListScanWithIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine will initiate the join procedure to attempt to associate ++* with the specified BSSID. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_UINT_8 pAddr; ++ UINT_32 i; ++ INT_32 i4Idx = -1; ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ UINT_8 ucReasonOfDisconnect; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = MAC_ADDR_LEN; ++ if (u4SetBufferLen != MAC_ADDR_LEN) { ++ *pu4SetInfoLen = MAC_ADDR_LEN; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ pAddr = (P_UINT_8) pvSetBuffer; ++ ++ /* re-association check */ ++ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) { ++ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); ++ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; ++ } else { ++ DBGLOG(OID, TRACE, "DisByBssid\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ } ++ } else { ++ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ } ++ ++ /* check if any scanned result matchs with the BSSID */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { ++ i4Idx = (INT_32) i; ++ break; ++ } ++ } ++ ++ /* prepare message to AIS */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS ++ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { ++ /* IBSS *//* beacon period */ ++ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; ++ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; ++ } ++ ++ /* Set Connection Request Issued Flag */ ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; ++ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_BSSID; ++ ++ /* Send AIS Abort Message */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect; ++ ++ /* Update the information to CONNECTION_SETTINGS_T */ ++ prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0; ++ prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0'; ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr); ++ ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) ++ prAisAbortMsg->fgDelayIndication = TRUE; ++ else ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ DBGLOG(OID, INFO, "SetBssid\n"); ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetBssid() */ ++ ++WLAN_STATUS ++wlanoidSetConnect(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_CONNECT_T pParamConn; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_32 i; ++ /*INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;*/ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ BOOLEAN fgIsValidSsid = TRUE; ++ BOOLEAN fgEqualSsid = FALSE; ++ BOOLEAN fgEqualBssid = FALSE; ++ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* MSDN: ++ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE ++ */ ++ if (prAdapter->fgIsRadioOff == TRUE) ++ prAdapter->fgIsRadioOff = FALSE; ++ ++ if (u4SetBufferLen != sizeof(PARAM_CONNECT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ else if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ ++ pParamConn = (P_PARAM_CONNECT_T) pvSetBuffer; ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ ++ if (pParamConn->u4SsidLen > 32) { ++ cnmMemFree(prAdapter, prAisAbortMsg); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (!pParamConn->pucBssid && !pParamConn->pucSsid) { ++ cnmMemFree(prAdapter, prAisAbortMsg); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ kalMemZero(prConnSettings->aucSSID, sizeof(prConnSettings->aucSSID)); ++ kalMemZero(prConnSettings->aucBSSID, sizeof(prConnSettings->aucBSSID)); ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; ++ prConnSettings->fgIsConnByBssidIssued = FALSE; ++ ++ if (pParamConn->pucSsid) { ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ COPY_SSID(prConnSettings->aucSSID, ++ prConnSettings->ucSSIDLen, pParamConn->pucSsid, (UINT_8) pParamConn->u4SsidLen); ++ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, ++ pParamConn->pucSsid, pParamConn->u4SsidLen)) ++ fgEqualSsid = TRUE; ++ } ++ if (pParamConn->pucBssid) { ++ if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) { ++ prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID; ++ prConnSettings->fgIsConnByBssidIssued = TRUE; ++ COPY_MAC_ADDR(prConnSettings->aucBSSID, pParamConn->pucBssid); ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pParamConn->pucBssid)) ++ fgEqualBssid = TRUE; ++ } else ++ DBGLOG(OID, TRACE, "wrong bssid %pM to connect\n", pParamConn->pucBssid); ++ } else ++ DBGLOG(OID, TRACE, "No Bssid set\n"); ++ prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq; ++ ++ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ ++ /* re-association check */ ++ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (fgEqualSsid) { ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_ROAMING; ++ if (fgEqualBssid) { ++ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; ++ } ++ } else { ++ DBGLOG(OID, TRACE, "DisBySsid\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ } ++ } else ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++#if 0 ++ /* check if any scanned result matchs with the SSID */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; ++ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; ++ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; ++ ++ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, pParamConn->u4SsidLen) && ++ i4RSSI >= i4MaxRSSI) { ++ i4Idx = (INT_32) i; ++ i4MaxRSSI = i4RSSI; ++ } ++ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { ++ i4Idx = (INT_32) i; ++ break; ++ } ++ } ++#endif ++ /* prepare message to AIS */ ++ if (prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { ++ /* IBSS *//* beacon period */ ++ prConnSettings->u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; ++ prConnSettings->u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; ++ } ++ ++ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { ++ if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) { ++ fgIsValidSsid = FALSE; ++ ++ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { ++ if (pParamConn->pucSsid) { ++ if (!((0 < pParamConn->pucSsid[i]) && (pParamConn->pucSsid[i] <= 0x1F))) { ++ fgIsValidSsid = TRUE; ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ /* Set Connection Request Issued Flag */ ++ if (fgIsValidSsid) ++ prConnSettings->fgIsConnReqIssued = TRUE; ++ else ++ prConnSettings->fgIsConnReqIssued = FALSE; ++ ++ if (fgEqualSsid || fgEqualBssid) ++ prAisAbortMsg->fgDelayIndication = TRUE; ++ else ++ /* Update the information to CONNECTION_SETTINGS_T */ ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ DBGLOG(OID, INFO, "ssid %s, bssid %pM, conn policy %d, disc reason %d\n", ++ prConnSettings->aucSSID, prConnSettings->aucBSSID, ++ prConnSettings->eConnectionPolicy, prAisAbortMsg->ucReasonOfDisconnect); ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine will initiate the join procedure to attempt ++* to associate with the new SSID. If the previous scanning ++* result is aged, we will scan the channels at first. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_SSID_T pParamSsid; ++ UINT_32 i; ++ INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN; ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ BOOLEAN fgIsValidSsid = TRUE; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* MSDN: ++ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE ++ */ ++ if (prAdapter->fgIsRadioOff == TRUE) ++ prAdapter->fgIsRadioOff = FALSE; ++ ++ if (u4SetBufferLen < sizeof(PARAM_SSID_T) || u4SetBufferLen > sizeof(PARAM_SSID_T)) { ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ pParamSsid = (P_PARAM_SSID_T) pvSetBuffer; ++ ++ if (pParamSsid->u4SsidLen > 32) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ ++ /* re-association check */ ++ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, ++ pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { ++ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); ++ } else { ++ DBGLOG(OID, TRACE, "DisBySsid\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ } ++ } ++ /* check if any scanned result matchs with the SSID */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; ++ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; ++ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; ++ ++ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, pParamSsid->u4SsidLen) && ++ i4RSSI >= i4MaxRSSI) { ++ i4Idx = (INT_32) i; ++ i4MaxRSSI = i4RSSI; ++ } ++ } ++ ++ /* prepare message to AIS */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS ++ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { ++ /* IBSS *//* beacon period */ ++ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; ++ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; ++ } ++ ++ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { ++ if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) { ++ fgIsValidSsid = FALSE; ++ ++ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { ++ if (!((0 < pParamSsid->aucSsid[i]) && (pParamSsid->aucSsid[i] <= 0x1F))) { ++ fgIsValidSsid = TRUE; ++ break; ++ } ++ } ++ } ++ } ++ ++ /* Set Connection Request Issued Flag */ ++ if (fgIsValidSsid) { ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; ++ ++ if (pParamSsid->u4SsidLen) { ++ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ } else { ++ /* wildcard SSID */ ++ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_ANY; ++ } ++ } else { ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ } ++ ++ /* Send AIS Abort Message */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ ++ COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, ++ prAdapter->rWifiVar.rConnSettings.ucSSIDLen, pParamSsid->aucSsid, (UINT_8) pParamSsid->u4SsidLen); ++ ++ prAdapter->rWifiVar.rConnSettings.u4FreqInKHz = pParamSsid->u4CenterFreq; ++ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { ++ prAisAbortMsg->fgDelayIndication = TRUE; ++ } else { ++ /* Update the information to CONNECTION_SETTINGS_T */ ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ } ++ DBGLOG(SCN, INFO, "SSID %s\n", prAdapter->rWifiVar.rConnSettings.aucSSID); ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wlanoidSetSsid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the currently associated SSID. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_SSID_T prAssociatedSsid; ++ ++ DEBUGFUNC("wlanoidQuerySsid"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_SSID_T); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prAssociatedSsid = (P_PARAM_SSID_T) pvQueryBuffer; ++ ++ kalMemZero(prAssociatedSsid->aucSsid, sizeof(prAssociatedSsid->aucSsid)); ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ prAssociatedSsid->u4SsidLen = prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen; ++ ++ if (prAssociatedSsid->u4SsidLen) { ++ kalMemCopy(prAssociatedSsid->aucSsid, ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, prAssociatedSsid->u4SsidLen); ++ } ++ } else { ++ prAssociatedSsid->u4SsidLen = 0; ++ ++ DBGLOG(OID, TRACE, "Null SSID\n"); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQuerySsid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current 802.11 network type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryInfrastructureMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eOPMode; ++ ++ /* ++ ** According to OID_802_11_INFRASTRUCTURE_MODE ++ ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE, ++ ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned. ++ */ ++#if DBG ++ switch (*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer) { ++ case NET_TYPE_IBSS: ++ DBGLOG(OID, INFO, "IBSS mode\n"); ++ break; ++ case NET_TYPE_INFRA: ++ DBGLOG(OID, INFO, "Infrastructure mode\n"); ++ break; ++ default: ++ DBGLOG(OID, INFO, "Automatic mode\n"); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryInfrastructureMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set mode to infrastructure or ++* IBSS, or automatic switch between the two. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid ++* length of the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ ++ DEBUGFUNC("wlanoidSetInfrastructureMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ eOpMode = *(P_ENUM_PARAM_OP_MODE_T) pvSetBuffer; ++ /* Verify the new infrastructure mode. */ ++ if (eOpMode >= NET_TYPE_NUM) { ++ DBGLOG(OID, TRACE, "Invalid mode value %d\n", eOpMode); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* check if possible to switch to AdHoc mode */ ++ if (eOpMode == NET_TYPE_IBSS || eOpMode == NET_TYPE_DEDICATED_IBSS) { ++ if (cnmAisIbssIsPermitted(prAdapter) == FALSE) { ++ DBGLOG(OID, TRACE, "Mode value %d unallowed\n", eOpMode); ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ /* Save the new infrastructure mode setting. */ ++ prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode; ++ ++ /* Clean up the Tx key flag */ ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; ++ ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; ++#if CFG_SUPPORT_WAPI ++ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; ++ kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42); ++#endif ++ ++#if CFG_SUPPORT_802_11W ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = FALSE; ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++ kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200); ++ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INFRASTRUCTURE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, nicOidCmdTimeoutCommon, 0, NULL, pvSetBuffer, u4SetBufferLen); ++ ++} /* wlanoidSetInfrastructureMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current 802.11 authentication ++* mode. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryAuthMode"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eAuthMode; ++ ++#if DBG ++ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer) { ++ case AUTH_MODE_OPEN: ++ DBGLOG(OID, INFO, "Current auth mode: Open\n"); ++ break; ++ ++ case AUTH_MODE_SHARED: ++ DBGLOG(OID, INFO, "Current auth mode: Shared\n"); ++ break; ++ ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(OID, INFO, "Current auth mode: Auto-switch\n"); ++ break; ++ ++ case AUTH_MODE_WPA: ++ DBGLOG(OID, INFO, "Current auth mode: WPA\n"); ++ break; ++ ++ case AUTH_MODE_WPA_PSK: ++ DBGLOG(OID, INFO, "Current auth mode: WPA PSK\n"); ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ DBGLOG(OID, INFO, "Current auth mode: WPA None\n"); ++ break; ++ ++ case AUTH_MODE_WPA2: ++ DBGLOG(OID, INFO, "Current auth mode: WPA2\n"); ++ break; ++ ++ case AUTH_MODE_WPA2_PSK: ++ DBGLOG(OID, INFO, "Current auth mode: WPA2 PSK\n"); ++ break; ++ ++ default: ++ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); ++ break; ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryAuthMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the IEEE 802.11 authentication mode ++* to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 i, u4AkmSuite; ++ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; ++ ++ DEBUGFUNC("wlanoidSetAuthMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* RF Test */ ++ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ ++ /* return WLAN_STATUS_SUCCESS; */ ++ /* } */ ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ /* Check if the new authentication mode is valid. */ ++ if (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer >= AUTH_MODE_NUM) { ++ DBGLOG(OID, TRACE, "Invalid auth mode %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer) { ++ case AUTH_MODE_WPA: ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA2: ++ case AUTH_MODE_WPA2_PSK: ++ /* infrastructure mode only */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_INFRA) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ /* ad hoc mode only */ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_IBSS) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Save the new authentication mode. */ ++ prAdapter->rWifiVar.rConnSettings.eAuthMode = *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer; ++ ++#if DBG ++ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { ++ case AUTH_MODE_OPEN: ++ DBGLOG(RSN, TRACE, "New auth mode: open\n"); ++ break; ++ ++ case AUTH_MODE_SHARED: ++ DBGLOG(RSN, TRACE, "New auth mode: shared\n"); ++ break; ++ ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n"); ++ break; ++ ++ case AUTH_MODE_WPA: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA\n"); ++ break; ++ ++ case AUTH_MODE_WPA_PSK: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n"); ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA None\n"); ++ break; ++ ++ case AUTH_MODE_WPA2: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA2\n"); ++ break; ++ ++ case AUTH_MODE_WPA2_PSK: ++ DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n"); ++ break; ++ ++ default: ++ DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", prAdapter->rWifiVar.rConnSettings.eAuthMode); ++ } ++#endif ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA) { ++ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { ++ case AUTH_MODE_WPA: ++ u4AkmSuite = WPA_AKM_SUITE_802_1X; ++ break; ++ ++ case AUTH_MODE_WPA_PSK: ++ u4AkmSuite = WPA_AKM_SUITE_PSK; ++ break; ++ ++ case AUTH_MODE_WPA_NONE: ++ u4AkmSuite = WPA_AKM_SUITE_NONE; ++ break; ++ ++ case AUTH_MODE_WPA2: ++ u4AkmSuite = RSN_AKM_SUITE_802_1X; ++ break; ++ ++ case AUTH_MODE_WPA2_PSK: ++ u4AkmSuite = RSN_AKM_SUITE_PSK; ++ break; ++ ++ default: ++ u4AkmSuite = 0; ++ } ++ } else { ++ u4AkmSuite = 0; ++ } ++ ++ /* Enable the specific AKM suite only. */ ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { ++ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; ++ ++ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite) ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE; ++#if CFG_SUPPORT_802_11W ++ if (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) { ++ if ((u4AkmSuite == RSN_AKM_SUITE_PSK) && ++ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_PSK_SHA256) { ++ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n"); ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; ++ ++ } ++ if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) && ++ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_802_1X_SHA256) { ++ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n"); ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; ++ } ++ } ++#endif ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetAuthMode */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current 802.11 privacy filter ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryPrivacyFilter"); ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); ++ ++ if (u4QueryBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer = prAdapter->rWlanInfo.ePrivacyFilter; ++ ++#if DBG ++ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer) { ++ case PRIVACY_FILTER_ACCEPT_ALL: ++ DBGLOG(OID, INFO, "Current privacy mode: open mode\n"); ++ break; ++ ++ case PRIVACY_FILTER_8021xWEP: ++ DBGLOG(OID, INFO, "Current privacy mode: filtering mode\n"); ++ break; ++ ++ default: ++ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryPrivacyFilter */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the IEEE 802.11 privacy filter ++* to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DEBUGFUNC("wlanoidSetPrivacyFilter"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); ++ ++ if (u4SetBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ /* Check if the new authentication mode is valid. */ ++ if (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer >= PRIVACY_FILTER_NUM) { ++ DBGLOG(OID, TRACE, "Invalid privacy filter %d\n", *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer) { ++ default: ++ break; ++ } ++ ++ /* Save the new authentication mode. */ ++ prAdapter->rWlanInfo.ePrivacyFilter = *(ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetPrivacyFilter */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to reload the available default settings for ++* the specified type field. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; ++ UINT_32 u4Len; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanoidSetReloadDefaults"); ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = sizeof(PARAM_RELOAD_DEFAULTS); ++ ++ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ ++ /* return WLAN_STATUS_SUCCESS; */ ++ /* } */ ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ /* Verify the available reload options and reload the settings. */ ++ switch (*(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer) { ++ case ENUM_RELOAD_WEP_KEYS: ++ /* Reload available default WEP keys from the permanent ++ storage. */ ++ prAdapter->rWifiVar.rConnSettings.eAuthMode = AUTH_MODE_OPEN; ++ /* ENUM_ENCRYPTION_DISABLED; */ ++ prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; ++ { ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_802_11_KEY prCmdKey; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_802_11_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 0; /* Remove */ ++ prCmdKey->ucKeyId = 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & 0x000000ff); */ ++ kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, MAC_ADDR_LEN); ++ ++ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); ++ ++ prCmdKey->ucKeyType = 0; ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++ } ++ ++ break; ++ ++ default: ++ DBGLOG(OID, TRACE, "Invalid reload option %d\n", *(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer); ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */ ++ eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE; ++ wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, sizeof(eNetworkType), &u4Len); ++ ++ return rStatus; ++} /* wlanoidSetReloadDefaults */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a WEP key to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++#ifdef LINUX ++UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; ++UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++#endif ++WLAN_STATUS ++wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#ifndef LINUX ++ UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++#endif ++ P_PARAM_WEP_T prNewWepKey; ++ P_PARAM_KEY_T prParamKey = (P_PARAM_KEY_T) keyBuffer; ++ UINT_32 u4KeyId, u4SetLen; ++ ++ DEBUGFUNC("wlanoidSetAddWep"); ++ ++ ASSERT(prAdapter); ++ ++ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); ++ ++ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)) { ++ ASSERT(pu4SetInfoLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prNewWepKey = (P_PARAM_WEP_T) pvSetBuffer; ++ ++ /* Verify the total buffer for minimum length. */ ++ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial) + prNewWepKey->u4KeyLength) { ++ DBGLOG(OID, WARN, "Invalid total buffer length (%d) than minimum length (%d)\n", ++ (UINT_8) u4SetBufferLen, (UINT_8) OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)); ++ ++ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Verify the key structure length. */ ++ if (prNewWepKey->u4Length > u4SetBufferLen) { ++ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewWepKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Verify the key material length for maximum key material length:16 */ ++ if (prNewWepKey->u4KeyLength > 16 /* LEGACY_KEY_MAX_LEN */) { ++ DBGLOG(OID, WARN, "Invalid key material length (%d) greater than maximum key material length (16)\n", ++ (UINT_8) prNewWepKey->u4KeyLength); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, 29) /* WEP_KEY_ID_FIELD */; ++ ++ /* Verify whether key index is valid or not, current version ++ driver support only 4 global WEP keys setting by this OID */ ++ if (u4KeyId > MAX_KEY_NUM - 1) { ++ DBGLOG(OID, ERROR, "Error, invalid WEP key ID: %d\n", (UINT_8) u4KeyId); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ prParamKey->u4KeyIndex = u4KeyId; ++ ++ /* Transmit key */ ++ if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY) ++ prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY; ++ ++ /* Per client key */ ++ if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY) ++ prParamKey->u4KeyIndex |= IS_UNICAST_KEY; ++ ++ prParamKey->u4KeyLength = prNewWepKey->u4KeyLength; ++ ++ kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN); ++ ++ kalMemCopy(prParamKey->aucKeyMaterial, prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength); ++ ++ prParamKey->u4Length = OFFSET_OF(PARAM_KEY_T, aucKeyMaterial) + prNewWepKey->u4KeyLength; ++ ++ wlanoidSetAddKey(prAdapter, (PVOID) prParamKey, prParamKey->u4Length, &u4SetLen); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetAddWep */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to remove the WEP key ++* at the specified key index. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 u4KeyId, u4SetLen; ++ PARAM_REMOVE_KEY_T rRemoveKey; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ ++ DEBUGFUNC("wlanoidSetRemoveWep"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_KEY_INDEX); ++ ++ if (u4SetBufferLen < sizeof(PARAM_KEY_INDEX)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ u4KeyId = *(PUINT_32) pvSetBuffer; ++ ++ /* Dump PARAM_WEP content. */ ++ DBGLOG(OID, INFO, "Set: Dump PARAM_KEY_INDEX content\n"); ++ DBGLOG(OID, INFO, "Index : 0x%08x\n", u4KeyId); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (u4KeyId & IS_TRANSMIT_KEY) { ++ /* Bit 31 should not be set */ ++ DBGLOG(OID, ERROR, "Invalid WEP key index: 0x%08x\n", u4KeyId); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ u4KeyId &= BITS(0, 7); ++ ++ /* Verify whether key index is valid or not. Current version ++ driver support only 4 global WEP keys. */ ++ if (u4KeyId > MAX_KEY_NUM - 1) { ++ DBGLOG(OID, ERROR, "invalid WEP key ID %u\n", u4KeyId); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); ++ rRemoveKey.u4KeyIndex = *(PUINT_32) pvSetBuffer; ++ ++ kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN); ++ ++ wlanoidSetRemoveKey(prAdapter, (PVOID)&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T), &u4SetLen); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetRemoveWep */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a key to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_PARAM_KEY_T prNewKey; ++ P_CMD_802_11_KEY prCmdKey; ++ UINT_8 ucCmdSeqNum; ++ ++#if 0 ++ DEBUGFUNC("wlanoidSetAddKey"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++#endif ++ ++ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; ++ ++#if 0 ++ /* Verify the key structure length. */ ++ if (prNewKey->u4Length > u4SetBufferLen) { ++ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ /* Verify the key material length for key material buffer */ ++ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { ++ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Exception check */ ++ if (prNewKey->u4KeyIndex & 0x0fffff00) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || ++ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { ++ if (((prNewKey->u4KeyIndex & 0xff) != 0) || ++ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) ++ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) ++ && (prNewKey->arBSSID[5] == 0xff))) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++#endif ++ ++ /* Dump PARAM_KEY content. */ ++ DBGLOG(OID, TRACE, "Set: PARAM_KEY Length: 0x%08x, Key Index: 0x%08x, Key Length: 0x%08x\n", ++ prNewKey->u4Length, prNewKey->u4KeyIndex, prNewKey->u4KeyLength); ++ DBGLOG(OID, TRACE, "BSSID:\n"); ++ DBGLOG_MEM8(OID, TRACE, prNewKey->arBSSID, sizeof(PARAM_MAC_ADDRESS)); ++ DBGLOG(OID, TRACE, "Key RSC:\n"); ++ DBGLOG_MEM8(OID, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC)); ++ DBGLOG(OID, TRACE, "Key Material:\n"); ++ DBGLOG_MEM8(OID, TRACE, prNewKey->aucKeyMaterial, prNewKey->u4KeyLength); ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { ++ /* Todo:: Store the legacy wep key for OID_802_11_RELOAD_DEFAULTS */ ++ /* Todo:: Nothing */ ++ } ++ ++ if (prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = TRUE; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(OID, TRACE, "ucCmdSeqNum = %d\n", ucCmdSeqNum); ++ ++ /* compose CMD_802_11_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = fgIsOid; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetBufferLen; ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 1; /* Add */ ++ ++ prCmdKey->ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; ++ prCmdKey->ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; ++ prCmdKey->ucIsAuthenticator = ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) ? 1 : 0; ++ ++ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->arBSSID, MAC_ADDR_LEN); ++ ++ prCmdKey->ucNetType = 0; /* AIS */ ++ ++ prCmdKey->ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); ++ ++ /* Note: adjust the key length for WPA-None */ ++ prCmdKey->ucKeyLen = (UINT_8) prNewKey->u4KeyLength; ++ ++ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen); ++ ++ if (prNewKey->u4KeyLength == 5) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40; ++ } else if (prNewKey->u4KeyLength == 13) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104; ++ } else if (prNewKey->u4KeyLength == 16) { ++ if ((ucAlgorithmId != CIPHER_SUITE_CCMP) && ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA)) ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128; ++ else { ++#if CFG_SUPPORT_802_11W ++ if (prCmdKey->ucKeyId >= 4) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_BIP; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ prAisSpecBssInfo->fgBipKeyInstalled = TRUE; ++ } else ++#endif ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; ++ if (rsnCheckPmkidCandicate(prAdapter)) { ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ DBGLOG(RSN, TRACE, ++ "Add key: Prepare a timer to indicate candidate PMKID Candidate\n"); ++ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); ++ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, ++ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); ++ } ++ } ++ } else if (prNewKey->u4KeyLength == 32) { ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; ++ else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) { ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; ++ prCmdKey->ucKeyLen = CCMP_KEY_LEN; ++ } ++ } else ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; ++ } ++ ++ DBGLOG(RSN, TRACE, "prCmdKey->ucAlgorithmId=%d, key len=%d\n", ++ prCmdKey->ucAlgorithmId, (UINT32) prNewKey->u4KeyLength); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} ++ ++WLAN_STATUS ++wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_KEY_T prNewKey; ++ ++ DEBUGFUNC("wlanoidSetAddKey"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; ++ ++ /* Verify the key structure length. */ ++ if (prNewKey->u4Length > u4SetBufferLen) { ++ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ /* Verify the key material length for key material buffer */ ++ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { ++ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Exception check */ ++ if (prNewKey->u4KeyIndex & 0x0fffff00) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { ++ if (((prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN) && ++ (prNewKey->u4KeyIndex & 0xff) != 0) || ++ EQUAL_MAC_ADDR(prNewKey->arBSSID, "\xff\xff\xff\xff\xff\xff")) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ } else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || ++ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* ++ supplicant will set key before updating station & enabling the link so we need to ++ backup the key information and set key when link is enabled ++ */ ++ if (TdlsexKeyHandle(prAdapter, prNewKey) == TDLS_STATUS_SUCCESS) ++ return WLAN_STATUS_SUCCESS; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ return _wlanoidSetAddKey(prAdapter, pvSetBuffer, u4SetBufferLen, TRUE, CIPHER_SUITE_NONE, pu4SetInfoLen); ++} /* wlanoidSetAddKey */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request the driver to remove the key at ++* the specified key index. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_PARAM_REMOVE_KEY_T prRemovedKey; ++ P_CMD_802_11_KEY prCmdKey; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanoidSetRemoveKey"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; ++ ++ /* Dump PARAM_REMOVE_KEY content. */ ++ DBGLOG(OID, TRACE, "Set: Dump PARAM_REMOVE_KEY content\n"); ++ DBGLOG(OID, TRACE, "Length : 0x%08x\n", prRemovedKey->u4Length); ++ DBGLOG(OID, TRACE, "Key Index : 0x%08x\n", prRemovedKey->u4KeyIndex); ++ DBGLOG(OID, TRACE, "BSSID:\n"); ++ DBGLOG_MEM8(OID, TRACE, prRemovedKey->arBSSID, MAC_ADDR_LEN); ++ ++ /* Check bit 31: this bit should always 0 */ ++ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { ++ /* Bit 31 should not be set */ ++ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Check bits 8 ~ 29 should always be 0 */ ++ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { ++ /* Bit 31 should not be set */ ++ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Clean up the Tx key flag */ ++ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_802_11_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 0; /* Remove */ ++ prCmdKey->ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); ++ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); ++ ++#if CFG_SUPPORT_802_11W ++ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM + 2); ++#else ++ /* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */ ++#endif ++ ++ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) ++ prCmdKey->ucKeyType = 1; ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetRemoveKey */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current encryption status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ BOOLEAN fgTransmitKeyAvailable = TRUE; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus = 0; ++ ++ DEBUGFUNC("wlanoidQueryEncryptionStatus"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); ++ ++ fgTransmitKeyAvailable = prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist; ++ ++ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { ++ case ENUM_ENCRYPTION3_ENABLED: ++ if (fgTransmitKeyAvailable) ++ eEncStatus = ENUM_ENCRYPTION3_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT; ++ break; ++ ++ case ENUM_ENCRYPTION2_ENABLED: ++ if (fgTransmitKeyAvailable) { ++ eEncStatus = ENUM_ENCRYPTION2_ENABLED; ++ break; ++ } ++ eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT; ++ break; ++ ++ case ENUM_ENCRYPTION1_ENABLED: ++ if (fgTransmitKeyAvailable) ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; ++ break; ++ ++ case ENUM_ENCRYPTION_DISABLED: ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ break; ++ ++ default: ++ DBGLOG(OID, ERROR, "Unknown Encryption Status Setting:%d\n", ++ prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ } ++ ++#if DBG ++ DBGLOG(OID, INFO, ++ "Encryption status: %d Return:%d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus); ++#endif ++ ++ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvQueryBuffer = eEncStatus; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryEncryptionStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the encryption status to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_NOT_SUPPORTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEewEncrypt; ++ ++ DEBUGFUNC("wlanoidSetEncryptionStatus"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ *pu4SetInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); ++ ++ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ ++ /* return WLAN_STATUS_SUCCESS; */ ++ /* } */ ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ eEewEncrypt = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; ++ DBGLOG(OID, TRACE, "ENCRYPTION_STATUS %d\n", eEewEncrypt); ++ ++ switch (eEewEncrypt) { ++ case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */ ++ DBGLOG(RSN, TRACE, "Disable Encryption\n"); ++ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); ++ break; ++ ++ case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */ ++ DBGLOG(RSN, TRACE, "Enable Encryption1\n"); ++ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); ++ break; ++ ++ case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */ ++ secSetCipherSuite(prAdapter, ++ CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP); ++ DBGLOG(RSN, TRACE, "Enable Encryption2\n"); ++ break; ++ ++ case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */ ++ secSetCipherSuite(prAdapter, ++ CIPHER_FLAG_WEP40 | ++ CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP); ++ DBGLOG(RSN, TRACE, "Enable Encryption3\n"); ++ break; ++ ++ default: ++ DBGLOG(RSN, WARN, "Unacceptible encryption status: %d\n", ++ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer); ++ ++ rStatus = WLAN_STATUS_NOT_SUPPORTED; ++ } ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ /* Save the new encryption status. */ ++ prAdapter->rWifiVar.rConnSettings.eEncStatus = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; ++ ++ DBGLOG(RSN, TRACE, "wlanoidSetEncryptionStatus to %d\n", ++ prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ } ++ ++ return rStatus; ++} /* wlanoidSetEncryptionStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to test the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_802_11_TEST_T prTest; ++ PVOID pvTestData; ++ PVOID pvStatusBuffer; ++ UINT_32 u4StatusBufferSize; ++ ++ DEBUGFUNC("wlanoidSetTest"); ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ prTest = (P_PARAM_802_11_TEST_T) pvSetBuffer; ++ ++ DBGLOG(OID, TRACE, "Test - Type %u\n", prTest->u4Type); ++ ++ switch (prTest->u4Type) { ++ case 1: /* Type 1: generate an authentication event */ ++ pvTestData = (PVOID) &prTest->u.AuthenticationEvent; ++ pvStatusBuffer = (PVOID) prAdapter->aucIndicationEventBuffer; ++ u4StatusBufferSize = prTest->u4Length - 8; ++ if (u4StatusBufferSize > sizeof(PARAM_AUTH_EVENT_T)) { ++ DBGLOG(OID, TRACE, "prTest->u4Length error %u\n", u4StatusBufferSize); ++ ASSERT(FALSE); ++ } ++ break; ++ ++ case 2: /* Type 2: generate an RSSI status indication */ ++ pvTestData = (PVOID) &prTest->u.RssiTrigger; ++ pvStatusBuffer = (PVOID) &prAdapter->rWlanInfo.rCurrBssId.rRssi; ++ u4StatusBufferSize = sizeof(PARAM_RSSI); ++ break; ++ ++ default: ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ ASSERT(u4StatusBufferSize <= 180); ++ if (u4StatusBufferSize > 180) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* Get the contents of the StatusBuffer from the test structure. */ ++ kalMemCopy(pvStatusBuffer, pvTestData, u4StatusBufferSize); ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, pvStatusBuffer, u4StatusBufferSize); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetTest */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the driver's WPA2 status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CAPABILITY_T prCap; ++ P_PARAM_AUTH_ENCRYPTION_T prAuthenticationEncryptionSupported; ++ ++ DEBUGFUNC("wlanoidQueryCapability"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = 4 * sizeof(UINT_32) + 14 * sizeof(PARAM_AUTH_ENCRYPTION_T); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prCap = (P_PARAM_CAPABILITY_T) pvQueryBuffer; ++ ++ prCap->u4Length = *pu4QueryInfoLen; ++ prCap->u4Version = 2; /* WPA2 */ ++ prCap->u4NoOfPMKIDs = CFG_MAX_PMKID_CACHE; ++ prCap->u4NoOfAuthEncryptPairsSupported = 14; ++ ++ prAuthenticationEncryptionSupported = &prCap->arAuthenticationEncryptionSupported[0]; ++ ++ /* fill 14 entries of supported settings */ ++ prAuthenticationEncryptionSupported[0].eAuthModeSupported = AUTH_MODE_OPEN; ++ ++ prAuthenticationEncryptionSupported[0].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; ++ ++ prAuthenticationEncryptionSupported[1].eAuthModeSupported = AUTH_MODE_OPEN; ++ prAuthenticationEncryptionSupported[1].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; ++ ++ prAuthenticationEncryptionSupported[2].eAuthModeSupported = AUTH_MODE_SHARED; ++ prAuthenticationEncryptionSupported[2].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; ++ ++ prAuthenticationEncryptionSupported[3].eAuthModeSupported = AUTH_MODE_SHARED; ++ prAuthenticationEncryptionSupported[3].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; ++ ++ prAuthenticationEncryptionSupported[4].eAuthModeSupported = AUTH_MODE_WPA; ++ prAuthenticationEncryptionSupported[4].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[5].eAuthModeSupported = AUTH_MODE_WPA; ++ prAuthenticationEncryptionSupported[5].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[6].eAuthModeSupported = AUTH_MODE_WPA_PSK; ++ prAuthenticationEncryptionSupported[6].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[7].eAuthModeSupported = AUTH_MODE_WPA_PSK; ++ prAuthenticationEncryptionSupported[7].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[8].eAuthModeSupported = AUTH_MODE_WPA_NONE; ++ prAuthenticationEncryptionSupported[8].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[9].eAuthModeSupported = AUTH_MODE_WPA_NONE; ++ prAuthenticationEncryptionSupported[9].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[10].eAuthModeSupported = AUTH_MODE_WPA2; ++ prAuthenticationEncryptionSupported[10].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[11].eAuthModeSupported = AUTH_MODE_WPA2; ++ prAuthenticationEncryptionSupported[11].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ prAuthenticationEncryptionSupported[12].eAuthModeSupported = AUTH_MODE_WPA2_PSK; ++ prAuthenticationEncryptionSupported[12].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; ++ ++ prAuthenticationEncryptionSupported[13].eAuthModeSupported = AUTH_MODE_WPA2_PSK; ++ prAuthenticationEncryptionSupported[13].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryCapability */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the PMKID in the PMK cache. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ UINT_32 i; ++ P_PARAM_PMKID_T prPmkid; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("wlanoidQueryPmkid"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ *pu4QueryInfoLen = OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo) + ++ prAisSpecBssInfo->u4PmkidCacheCount * sizeof(PARAM_BSSID_INFO_T); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prPmkid = (P_PARAM_PMKID_T) pvQueryBuffer; ++ ++ prPmkid->u4Length = *pu4QueryInfoLen; ++ prPmkid->u4BSSIDInfoCount = prAisSpecBssInfo->u4PmkidCacheCount; ++ ++ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { ++ kalMemCopy(prPmkid->arBSSIDInfo[i].arBSSID, ++ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, sizeof(PARAM_MAC_ADDRESS)); ++ kalMemCopy(prPmkid->arBSSIDInfo[i].arPMKID, ++ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryPmkid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the PMKID to the PMK cache in the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 i, j; ++ P_PARAM_PMKID_T prPmkid; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("wlanoidSetPmkid"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* It's possibble BSSIDInfoCount is zero, because OS wishes to clean PMKID */ ++ if (u4SetBufferLen < OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ ASSERT(pvSetBuffer); ++ prPmkid = (P_PARAM_PMKID_T) pvSetBuffer; ++ ++ if (u4SetBufferLen < ++ ((prPmkid->u4BSSIDInfoCount * sizeof(PARAM_BSSID_INFO_T)) + OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo))) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ DBGLOG(OID, TRACE, "Count %u\n", prPmkid->u4BSSIDInfoCount); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ /* This OID replace everything in the PMKID cache. */ ++ if (prPmkid->u4BSSIDInfoCount == 0) { ++ prAisSpecBssInfo->u4PmkidCacheCount = 0; ++ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); ++ } ++ if ((prAisSpecBssInfo->u4PmkidCacheCount + prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)) { ++ prAisSpecBssInfo->u4PmkidCacheCount = 0; ++ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); ++ } ++ ++ /* ++ The driver can only clear its PMKID cache whenever it make a media disconnect ++ indication. Otherwise, it must change the PMKID cache only when set through this OID. ++ */ ++#if CFG_RSN_MIGRATION ++ for (i = 0; i < prPmkid->u4BSSIDInfoCount; i++) { ++ /* Search for desired BSSID. If desired BSSID is found, ++ then set the PMKID */ ++ if (!rsnSearchPmkidEntry(prAdapter, (PUINT_8) prPmkid->arBSSIDInfo[i].arBSSID, &j)) { ++ /* No entry found for the specified BSSID, so add one entry */ ++ if (prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE - 1) { ++ j = prAisSpecBssInfo->u4PmkidCacheCount; ++ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, ++ prPmkid->arBSSIDInfo[i].arBSSID, sizeof(PARAM_MAC_ADDRESS)); ++ prAisSpecBssInfo->u4PmkidCacheCount++; ++ } else { ++ j = CFG_MAX_PMKID_CACHE; ++ } ++ } ++ ++ if (j < CFG_MAX_PMKID_CACHE) { ++ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID, ++ prPmkid->arBSSIDInfo[i].arPMKID, sizeof(PARAM_PMKID_VALUE)); ++ DBGLOG(RSN, TRACE, "Add BSSID %pM idx=%d PMKID value %pM\n", ++ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID), (UINT_32) j, ++ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID)); ++ prAisSpecBssInfo->arPmkidCache[j].fgPmkidExist = TRUE; ++ } ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetPmkid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the set of supported data rates that ++* the radio is capable of running ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query ++* \param[in] u4QueryBufferLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number ++* of bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ PARAM_RATES eRate = { ++ /* BSSBasicRateSet for 802.11n Non-HT rates */ ++ 0x8C, /* 6M */ ++ 0x92, /* 9M */ ++ 0x98, /* 12M */ ++ 0xA4, /* 18M */ ++ 0xB0, /* 24M */ ++ 0xC8, /* 36M */ ++ 0xE0, /* 48M */ ++ 0xEC /* 54M */ ++ }; ++ ++ DEBUGFUNC("wlanoidQuerySupportedRates"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ kalMemCopy(pvQueryBuffer, (PVOID) &eRate, sizeof(PARAM_RATES)); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQuerySupportedRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current desired rates. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryDesiredRates"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ kalMemCopy(pvQueryBuffer, (PVOID) &(prAdapter->rWlanInfo.eDesiredRates), sizeof(PARAM_RATES)); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wlanoidQueryDesiredRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to Set the desired rates. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 i; ++ ++ DEBUGFUNC("wlanoidSetDesiredRates"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(PARAM_RATES)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = sizeof(PARAM_RATES); ++ ++ if (u4SetBufferLen < sizeof(PARAM_RATES)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ kalMemCopy((PVOID) &(prAdapter->rWlanInfo.eDesiredRates), pvSetBuffer, sizeof(PARAM_RATES)); ++ ++ prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = PARAM_MAX_LEN_RATES; ++ for (i = 0; i < PARAM_MAX_LEN_RATES; i++) ++ prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = (UINT_16) (prAdapter->rWlanInfo.eDesiredRates[i]); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_LINK_ATTRIB, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_LINK_ATTRIB), ++ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); ++ ++} /* end of wlanoidSetDesiredRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the maximum frame size in bytes, ++* not including the header. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryMaxFrameSize"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - ETHERNET_HEADER_SZ; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryMaxFrameSize */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the maximum total packet length ++* in bytes. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryMaxTotalSize"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryMaxTotalSize */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the vendor ID of the NIC. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++#if DBG ++ PUINT_8 cp; ++#endif ++ DEBUGFUNC("wlanoidQueryVendorId"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3); ++ *((PUINT_8) pvQueryBuffer + 3) = 1; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++#if DBG ++ cp = (PUINT_8) pvQueryBuffer; ++ DBGLOG(OID, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], cp[1], cp[2], cp[3]); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryVendorId */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current RSSI value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call failed due to invalid length of ++* the query buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRssi"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (prAdapter->fgIsLinkQualityValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { ++ PARAM_RSSI rRssi; ++ ++ rRssi = (PARAM_RSSI) prAdapter->rLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ ++ ++ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ ++ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); ++ return WLAN_STATUS_SUCCESS; ++ } ++#ifdef LINUX ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, ++ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); ++#else ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++#endif ++} /* end of wlanoidQueryRssi() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current RSSI trigger value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call failed due to invalid length of ++* the query buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRssiTrigger"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_NONE) ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ *(PARAM_RSSI *) pvQueryBuffer = prAdapter->rWlanInfo.rRssiTriggerValue; ++ DBGLOG(OID, INFO, "RSSI trigger: %d dBm\n", *(PARAM_RSSI *) pvQueryBuffer); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryRssiTrigger */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a trigger value of the RSSI event. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns the ++* amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PARAM_RSSI rRssiTriggerValue; ++ ++ DEBUGFUNC("wlanoidSetRssiTrigger"); ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_RSSI); ++ rRssiTriggerValue = *(PARAM_RSSI *) pvSetBuffer; ++ ++ if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM) ++ return ++ /* Save the RSSI trigger value to the Adapter structure */ ++ prAdapter->rWlanInfo.rRssiTriggerValue = rRssiTriggerValue; ++ ++ /* If the RSSI trigger value is equal to the current RSSI value, the ++ * indication triggers immediately. We need to indicate the protocol ++ * that an RSSI status indication event triggers. */ ++ if (rRssiTriggerValue == (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) &prAdapter->rWlanInfo.rRssiTriggerValue, sizeof(PARAM_RSSI)); ++ } else if (rRssiTriggerValue < (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_GREATER; ++ else if (rRssiTriggerValue > (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_LESS; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetRssiTrigger */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a suggested value for the number of ++* bytes of received packet data that will be indicated to the protocol ++* driver. We just accept the set and ignore this value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ DEBUGFUNC("wlanoidSetCurrentLookahead"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) { ++ *pu4SetInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetCurrentLookahead */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames that the driver ++* receives but does not indicate to the protocols due to errors. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvError"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvError, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvError */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the number of frames that the NIC ++* cannot receive due to lack of NIC receive buffer space. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS If success; ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvNoBuffer"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) 0; /* @FIXME */ ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) 0; /* @FIXME */ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvNoBuffer, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvNoBuffer */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the number of frames that the NIC ++* received and it is CRC error. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS If success; ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvCrcError"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvCrcError, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvCrcError */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the current 802.11 statistics. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; ++ ++ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; ++ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; ++ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; ++ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; ++ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; ++ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; ++ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; ++ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; ++ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; ++ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; ++ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; ++ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; ++ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; ++ prStatistics->rTKIPICVErrors.QuadPart = 0; ++ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; ++ prStatistics->rTKIPReplays.QuadPart = 0; ++ prStatistics->rCCMPFormatErrors.QuadPart = 0; ++ prStatistics->rCCMPReplays.QuadPart = 0; ++ prStatistics->rCCMPDecryptErrors.QuadPart = 0; ++ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; ++ prStatistics->rWEPUndecryptableCount.QuadPart = 0; ++ prStatistics->rWEPICVErrorCount.QuadPart = 0; ++ prStatistics->rDecryptSuccessCount.QuadPart = 0; ++ prStatistics->rDecryptFailureCount.QuadPart = 0; ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS_PL, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryStatistics, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryStatistics */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the current 802.11 statistics. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryStatistics"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { ++ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; ++ ++ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; ++ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; ++ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; ++ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; ++ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; ++ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; ++ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; ++ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; ++ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; ++ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; ++ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; ++ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; ++ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; ++ prStatistics->rTKIPICVErrors.QuadPart = 0; ++ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; ++ prStatistics->rTKIPReplays.QuadPart = 0; ++ prStatistics->rCCMPFormatErrors.QuadPart = 0; ++ prStatistics->rCCMPReplays.QuadPart = 0; ++ prStatistics->rCCMPDecryptErrors.QuadPart = 0; ++ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; ++ prStatistics->rWEPUndecryptableCount.QuadPart = 0; ++ prStatistics->rWEPICVErrorCount.QuadPart = 0; ++ prStatistics->rDecryptSuccessCount.QuadPart = 0; ++ prStatistics->rDecryptFailureCount.QuadPart = 0; ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryStatistics, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryStatistics */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query current media streaming status. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryMediaStreamMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); ++ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *(P_ENUM_MEDIA_STREAM_MODE) pvQueryBuffer = ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryMediaStreamMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to enter media streaming mode or exit media streaming mode ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ENUM_MEDIA_STREAM_MODE eStreamMode; ++ ++ DEBUGFUNC("wlanoidSetMediaStreamMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(ENUM_MEDIA_STREAM_MODE)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); ++ ++ eStreamMode = *(P_ENUM_MEDIA_STREAM_MODE) pvSetBuffer; ++ ++ if (eStreamMode == ENUM_MEDIA_STREAM_OFF) ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; ++ else ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_LINK_ATTRIB, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetMediaStreamMode, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_LINK_ATTRIB), ++ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); ++} /* wlanoidSetMediaStreamMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the permanent MAC address of the NIC. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryPermanentAddr"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < MAC_ADDR_LEN) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ COPY_MAC_ADDR(pvQueryBuffer, prAdapter->rWifiVar.aucPermanentAddress); ++ *pu4QueryInfoLen = MAC_ADDR_LEN; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryPermanentAddr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the MAC address the NIC is currently using. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ CMD_BASIC_CONFIG rCmdBasicConfig; ++ ++ DEBUGFUNC("wlanoidQueryCurrentAddr"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < MAC_ADDR_LEN) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BASIC_CONFIG, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryAddress, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_BASIC_CONFIG), ++ (PUINT_8) &rCmdBasicConfig, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryCurrentAddr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query NIC link speed. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryLinkSpeed"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (prAdapter->fgIsLinkRateValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { ++ *(PUINT_32) pvQueryBuffer = prAdapter->rLinkQuality.u2LinkSpeed * 5000; /* change to unit of 100bps */ ++ return WLAN_STATUS_SUCCESS; ++ } else { ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkSpeed, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ } ++} /* end of wlanoidQueryLinkSpeed() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query MCR value. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++ DEBUGFUNC("wlanoidQueryMcrRead"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvQueryBuffer; ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++#if CFG_SUPPORT_SWCR ++ if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) { ++ swCrReadWriteCmd(prAdapter, ++ SWCR_READ, ++ (UINT_16) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), &prMcrRdInfo->u4McrData); ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif /* CFG_SUPPORT_SWCR */ ++ ++ /* Check if access F/W Domain MCR (due to WiFiSYS is placed from 0x6000-0000 */ ++ if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) { ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = 0; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryMcrRead, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); ++ } else { ++ HAL_MCR_RD(prAdapter, prMcrRdInfo->u4McrOffset & BITS(2, 31), /* address is in DWORD unit */ ++ &prMcrRdInfo->u4McrData); ++ ++ DBGLOG(OID, TRACE, "MCR Read: Offset = %#08x, Data = %#08x\n", ++ prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); ++ return WLAN_STATUS_SUCCESS; ++ } ++} /* end of wlanoidQueryMcrRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write MCR and enable specific function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrWrInfo; ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++#if CFG_STRESS_TEST_SUPPORT ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); ++ P_STA_RECORD_T prStaRec = prBssInfo->prStaRecOfAP; ++ UINT_32 u4McrOffset, u4McrData; ++#endif ++ ++ DEBUGFUNC("wlanoidSetMcrWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prMcrWrInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvSetBuffer; ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++ /* 0xFFFE reserved for FW */ ++ ++ /* -- Puff Stress Test Begin */ ++#if CFG_STRESS_TEST_SUPPORT ++ ++ /* 0xFFFFFFFE for Control Rate */ ++ if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) { ++ if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM && prMcrWrInfo->u4McrData > 0) ++ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prMcrWrInfo->u4McrData); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n"); ++ DBGLOG(OID, TRACE, ++ "[Stress Test] Rate is Changed to index %d...\n", prAdapter->rWifiVar.eRateSetting); ++ } ++ /* 0xFFFFFFFD for Switch Channel */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) { ++ if (prMcrWrInfo->u4McrData <= 11 && prMcrWrInfo->u4McrData >= 1) ++ prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData; ++ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); ++ DBGLOG(OID, TRACE, "[Stress Test] Channel is switched to %d ...\n", prBssInfo->ucPrimaryChannel); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* 0xFFFFFFFFC for Control RF Band and SCO */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) { ++ /* Band */ ++ if (prMcrWrInfo->u4McrData & 0x80000000) { ++ /* prBssInfo->eBand = BAND_5G; */ ++ /* prBssInfo->ucPrimaryChannel = 52; // Bond to Channel 52 */ ++ } else { ++ prBssInfo->eBand = BAND_2G4; ++ prBssInfo->ucPrimaryChannel = 8; /* Bond to Channel 6 */ ++ } ++ ++ /* Bandwidth */ ++ if (prMcrWrInfo->u4McrData & 0x00010000) { ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ ++ if (prMcrWrInfo->u4McrData == 0x00010002) { ++ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* U20 */ ++ prBssInfo->ucPrimaryChannel += 2; ++ } else if (prMcrWrInfo->u4McrData == 0x00010001) { ++ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* L20 */ ++ prBssInfo->ucPrimaryChannel -= 2; ++ } else { ++ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* 40 */ ++ } ++ } ++ ++ if (prMcrWrInfo->u4McrData & 0x00000000) { ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; ++ prBssInfo->eBssSCO = CHNL_EXT_SCN; ++ } ++ rlmBssInitForAPandIbss(prAdapter, prBssInfo); ++ } ++ /* 0xFFFFFFFB for HT Capability */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) { ++ /* Enable HT Capability */ ++ if (prMcrWrInfo->u4McrData & 0x00000001) { ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; ++ DEBUGFUNC("[Stress Test]Enable HT capability...\n"); ++ } else { ++ prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF); ++ DEBUGFUNC("[Stress Test]Disable HT capability...\n"); ++ } ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ } ++ /* 0xFFFFFFFA for Enable Random Rx Reset */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_RANDOM_RX_RESET_EN, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ /* 0xFFFFFFF9 for Disable Random Rx Reset */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_RANDOM_RX_RESET_DE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ /* 0xFFFFFFF8 for Enable SAPP */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SAPP_EN, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ /* 0xFFFFFFF7 for Disable SAPP */ ++ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) { ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SAPP_DE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++ ++ else ++#endif ++ /* -- Puff Stress Test End */ ++ ++ /* Check if access F/W Domain MCR */ ++ if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) { ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++#if CFG_SUPPORT_SWCR ++ if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) { ++ swCrReadWriteCmd(prAdapter, ++ SWCR_WRITE, ++ (UINT_16) (prMcrWrInfo->u4McrOffset & BITS(0, 15)), &prMcrWrInfo->u4McrData); ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif /* CFG_SUPPORT_SWCR */ ++ ++#if 1 ++ /* low power test special command */ ++ if (prMcrWrInfo->u4McrOffset == 0x11111110) { ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ /* DbgPrint("Enter test mode\n"); */ ++ prAdapter->fgTestMode = TRUE; ++ return rStatus; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111111) { ++ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ ++ ++ nicpmSetAcpiPowerD3(prAdapter); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111112) { ++ ++ /* DbgPrint("LP enter sleep\n"); */ ++ ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++#endif ++ ++#if 1 ++ /* low power test special command */ ++ if (prMcrWrInfo->u4McrOffset == 0x11111110) { ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ /* DbgPrint("Enter test mode\n"); */ ++ prAdapter->fgTestMode = TRUE; ++ return rStatus; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111111) { ++ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ ++ ++ nicpmSetAcpiPowerD3(prAdapter); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); ++ return WLAN_STATUS_SUCCESS; ++ } ++ if (prMcrWrInfo->u4McrOffset == 0x11111112) { ++ ++ /* DbgPrint("LP enter sleep\n"); */ ++ ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } ++#endif ++ /* fill command */ ++ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; ++ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_REG), ++ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); ++ } else { ++ HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, 31)), /* address is in DWORD unit */ ++ prMcrWrInfo->u4McrData); ++ ++ DBGLOG(OID, TRACE, "MCR Write: Offset = %#08x, Data = %#08x\n", ++ prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++} /* wlanoidSetMcrWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query SW CTRL ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; ++ WLAN_STATUS rWlanStatus; ++ UINT_16 u2Id, u2SubId; ++ UINT_32 u4Data; ++ ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ ++ DEBUGFUNC("wlanoidQuerySwCtrlRead"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvQueryBuffer; ++ ++ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); ++ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); ++ u4Data = 0; ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ switch (u2Id) { ++ /* 0x9000 - 0x9EFF reserved for FW */ ++ /* 0xFFFE reserved for FW */ ++ ++#if CFG_SUPPORT_SWCR ++ case 0x9F00: ++ swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */ , ++ (UINT_16) u2SubId, &u4Data); ++ break; ++#endif /* CFG_SUPPORT_SWCR */ ++ ++ case 0xFFFF: ++ { ++ u4Data = 0x5AA56620; ++ } ++ break; ++ ++ case 0x9000: ++ default: ++ { ++ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; ++ rCmdSwCtrl.u4Data = 0; ++ rWlanStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQuerySwCtrlRead, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_SW_DBG_CTRL_T), ++ (PUINT_8) &rCmdSwCtrl, pvQueryBuffer, u4QueryBufferLen); ++ } ++ } /* switch(u2Id) */ ++ ++ prSwCtrlInfo->u4Data = u4Data; ++ ++ return rWlanStatus; ++ ++} ++ ++ /* end of wlanoidQuerySwCtrlRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write SW CTRL ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ WLAN_STATUS rWlanStatus; ++ UINT_16 u2Id, u2SubId; ++ UINT_32 u4Data; ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ P_GLUE_INFO_T prGlueInfo; ++ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; ++#endif ++ ++ DEBUGFUNC("wlanoidSetSwCtrlWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ prGlueInfo = prAdapter->prGlueInfo; ++#endif ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvSetBuffer; ++ ++ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); ++ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); ++ u4Data = prSwCtrlInfo->u4Data; ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ switch (u2Id) { ++ ++ /* 0x9000 - 0x9EFF reserved for FW */ ++ /* 0xFFFE reserved for FW */ ++ ++#if CFG_SUPPORT_SWCR ++ case 0x9F00: ++ swCrReadWriteCmd(prAdapter, SWCR_WRITE, (UINT_16) u2SubId, &u4Data); ++ break; ++#endif /* CFG_SUPPORT_SWCR */ ++ ++ case 0x1000: ++ if (u2SubId == 0x8000) { ++ /* CTIA power save mode setting (code: 0x10008000) */ ++ prAdapter->u4CtiaPowerMode = u4Data; ++ prAdapter->fgEnCtiaPowerMode = TRUE; ++ ++ /* */ ++ { ++ PARAM_POWER_MODE ePowerMode; ++ ++ if (prAdapter->u4CtiaPowerMode == 0) ++ /* force to keep in CAM mode */ ++ ePowerMode = Param_PowerModeCAM; ++ else if (prAdapter->u4CtiaPowerMode == 1) ++ ePowerMode = Param_PowerModeMAX_PSP; ++ else ++ ePowerMode = Param_PowerModeFast_PSP; ++ ++ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); ++ } ++ } ++ break; ++ case 0x1001: ++ if (u2SubId == 0x0) ++ prAdapter->fgEnOnlineScan = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x1) ++ prAdapter->fgDisBcnLostDetection = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x2) ++ prAdapter->rWifiVar.fgSupportUAPSD = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x3) { ++ prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15); ++ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpDeliveryAC = ++ (UINT_8) prAdapter->u4UapsdAcBmp; ++ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpTriggerAC = ++ (UINT_8) prAdapter->u4UapsdAcBmp; ++ } else if (u2SubId == 0x4) ++ prAdapter->fgDisStaAgingTimeoutDetection = (BOOLEAN) u4Data; ++ else if (u2SubId == 0x5) ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = (UINT_8) u4Data; ++ else if (u2SubId == 0x0100) ++ prAdapter->rWifiVar.u8SupportRxGf = (UINT_8) u4Data; ++ else if (u2SubId == 0x0101) { ++ prAdapter->rWifiVar.u8SupportRxSgi20 = (UINT_8) u4Data; ++ prAdapter->rWifiVar.u8SupportRxSgi40 = (UINT_8) u4Data; ++ } else if (u2SubId == 0x0102) ++ prAdapter->rWifiVar.u8SupportRxSTBC = (UINT_8) u4Data; ++ break; ++ ++#if CFG_SUPPORT_SWCR ++ case 0x1002: ++ if (u2SubId == 0x0) { ++ if (u4Data) ++ u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT); ++ swCrFrameCheckEnable(prAdapter, u4Data); ++ } else if (u2SubId == 0x1) { ++ BOOLEAN fgIsEnable; ++ UINT_8 ucType; ++ UINT_32 u4Timeout; ++ ++ fgIsEnable = (BOOLEAN) (u4Data & 0xff); ++ ucType = 0; /* ((u4Data>>4) & 0xf); */ ++ u4Timeout = ((u4Data >> 8) & 0xff); ++ swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, u4Timeout); ++ } ++ break; ++#endif ++ ++#if CFG_SUPPORT_802_11W ++ case 0x2000: ++ DBGLOG(RSN, TRACE, "802.11w test 0x%x\n", u2SubId); ++ if (u2SubId == 0x0) ++ rsnStartSaQuery(prAdapter); ++ if (u2SubId == 0x1) ++ rsnStopSaQuery(prAdapter); ++ if (u2SubId == 0x2) ++ rsnSaQueryRequest(prAdapter, NULL); ++ if (u2SubId == 0x3) { ++ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); ++ ++ authSendDeauthFrame(prAdapter, prBssInfo->prStaRecOfAP, NULL, 7, NULL); ++ } ++ /* wext_set_mode */ ++ /* ++ if (u2SubId == 0x3) { ++ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_DISABLED; ++ } ++ if (u2SubId == 0x4) { ++ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL; ++ } ++ if (u2SubId == 0x5) { ++ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_REQUIRED; ++ } ++ */ ++ break; ++#endif ++ case 0xFFFF: ++ { ++/* CMD_ACCESS_REG rCmdAccessReg; */ ++#if 1 /* CFG_MT6573_SMT_TEST */ ++ if (u2SubId == 0x0123) { ++ ++ DBGLOG(HAL, TRACE, "set smt fixed rate: %u\n", u4Data); ++ ++ if ((ENUM_REGISTRY_FIXED_RATE_T) (u4Data) < FIXED_RATE_NUM) ++ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (u4Data); ++ else ++ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; ++ ++ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) ++ /* Enable Auto (Long/Short) Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; ++ else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) ++ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && ++ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) ++ /* Force Short Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; ++ else ++ /* Force Long Preamble */ ++ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; ++ ++ /* abort to re-connect */ ++#if 1 ++ DBGLOG(OID, TRACE, "DisBySwC\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++#else ++ aisBssBeaconTimeout(prAdapter); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++ ++ } else if (u2SubId == 0x1234) { ++ /* 1. Disable On-Lin Scan */ ++ /* 3. Disable FIFO FULL no ack */ ++ /* 4. Disable Roaming */ ++ /* Disalbe auto tx power */ ++ /* 2. Keep at CAM mode */ ++ /* 5. Disable Beacon Timeout Detection */ ++ rWlanStatus = nicEnterCtiaMode(prAdapter, TRUE, TRUE); ++ } else if (u2SubId == 0x1235) { ++ /* 1. Enaable On-Lin Scan */ ++ /* 3. Enable FIFO FULL no ack */ ++ /* 4. Enable Roaming */ ++ /* Enable auto tx power */ ++ /* 2. Keep at Fast PS */ ++ /* 5. Enable Beacon Timeout Detection */ ++ rWlanStatus = nicEnterCtiaMode(prAdapter, FALSE, TRUE); ++ } ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ else if (u2SubId == 0x1240) { ++ DBGLOG(P2P, TRACE, "Disable Hotspot Optimization!\n"); ++ ++ arHotspotOptimizationCfg.fgHotspotOptimizationEn = FALSE; ++ arHotspotOptimizationCfg.u4Level = 0; ++ wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ NULL, ++ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), ++ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); ++ } else if (u2SubId == 0x1241) { ++ DBGLOG(P2P, TRACE, "Enable Hotspot Optimization!\n"); ++ ++ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; ++ arHotspotOptimizationCfg.u4Level = 5; ++ wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ NULL, ++ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), ++ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); ++ } ++#endif /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ ++ else if (u2SubId == 0x1250) { ++ DBGLOG(OID, TRACE, "LTE_COEX: SW SET DUAL BAND\n"); ++ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_NULL; ++ } else if (u2SubId == 0x1251) { ++ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 2.4G BAND\n"); ++ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_2G4; ++ } else if (u2SubId == 0x1252) { ++ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 5G BAND\n"); ++ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_5G; ++ } ++#endif ++ } ++ break; ++ ++ case 0x9000: ++ default: ++ { ++ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; ++ rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data; ++ rWlanStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_SW_DBG_CTRL_T), ++ (PUINT_8) &rCmdSwCtrl, pvSetBuffer, u4SetBufferLen); ++ } ++ } /* switch(u2Id) */ ++ ++ return rWlanStatus; ++} ++ ++ /* wlanoidSetSwCtrlWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query EEPROM value. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; ++ CMD_ACCESS_EEPROM rCmdAccessEeprom; ++ ++ DEBUGFUNC("wlanoidQueryEepromRead"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvQueryBuffer; ++ ++ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); ++ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_EEPROM, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryEepromRead, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_EEPROM), ++ (PUINT_8) &rCmdAccessEeprom, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryEepromRead */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write EEPROM value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; ++ CMD_ACCESS_EEPROM rCmdAccessEeprom; ++ ++ DEBUGFUNC("wlanoidSetEepromWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); ++ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; ++ rCmdAccessEeprom.u2Data = prEepromRwInfo->u2EepromData; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_EEPROM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ACCESS_EEPROM), ++ (PUINT_8) &rCmdAccessEeprom, pvSetBuffer, u4SetBufferLen); ++ ++} /* wlanoidSetEepromWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of the successfully transmitted ++* packets. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitOk"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitOk, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryXmitOk */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of the successfully received ++* packets. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRcvOk"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryRecvOk, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryRcvOk */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames that the driver ++* fails to transmit. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitError"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitError, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryXmitError */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames successfully ++* transmitted after exactly one collision. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitOneCollision"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) ++ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - ++ prAdapter->rStatStruct.rRetryCount.QuadPart); ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) ++ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - ++ prAdapter->rStatStruct.rRetryCount.QuadPart); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitOneCollision, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* wlanoidQueryXmitOneCollision */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames successfully ++* transmitted after more than one collision. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitMoreCollisions"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitMoreCollisions, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++} /* wlanoidQueryXmitMoreCollisions */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the number of frames ++* not transmitted due to excessive collisions. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryXmitMaxCollisions"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } else if (u4QueryBufferLen < sizeof(UINT_32) ++ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++#if CFG_ENABLE_STATISTICS_BUFFERING ++ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { ++ if (u4QueryBufferLen == sizeof(UINT_32)) { ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } else { ++ *pu4QueryInfoLen = sizeof(UINT_64); ++ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_STATISTICS, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryXmitMaxCollisions, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++} /* wlanoidQueryXmitMaxCollisions */ ++ ++#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00006620 /* for WPDWifi DLL */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current the OID interface version, ++* which is the interface between the application and driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryOidInterfaceVersion"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *(PUINT_32) pvQueryBuffer = MTK_CUSTOM_OID_INTERFACE_VERSION; ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ DBGLOG(OID, WARN, "Custom OID interface version: %#08X\n", *(PUINT_32) pvQueryBuffer); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryOidInterfaceVersion */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current Multicast Address List. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++#ifndef LINUX ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_MAC_MCAST_ADDR, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryMcastAddr, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++#else ++ return WLAN_STATUS_SUCCESS; ++#endif ++} /* end of wlanoidQueryMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Multicast Address List. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_8 ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Caller should provide this information */ ++ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* The data must be a multiple of the Ethernet address size. */ ++ if ((u4SetBufferLen % MAC_ADDR_LEN)) { ++ DBGLOG(OID, WARN, "Invalid MC list length %u\n", u4SetBufferLen); ++ ++ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; ++ ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* Verify if we can support so many multicast addresses. */ ++ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { ++ DBGLOG(OID, WARN, "Too many MC addresses\n"); ++ ++ return WLAN_STATUS_MULTICAST_FULL; ++ } ++ ++ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && ++ * pvSetBuffer == NULL to clear exist Multicast List. ++ */ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; ++ rCmdMacMcastAddr.ucNetTypeIndex = ucNetTypeIndex; ++ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_MAC_MCAST_ADDR, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_MAC_MCAST_ADDR), ++ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); ++} /* end of wlanoidSetMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Packet Filter. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_NOT_SUPPORTED ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 u4NewPacketFilter; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) { ++ *pu4SetInfoLen = sizeof(UINT_32); ++ DBGLOG(OID, INFO, "iput buffer is too small"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ASSERT(pvSetBuffer); ++ ++ /* Set the new packet filter. */ ++ u4NewPacketFilter = *(PUINT_32) pvSetBuffer; ++ ++ DBGLOG(OID, TRACE, "New packet filter: %#08x\n", u4NewPacketFilter); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ do { ++ /* Verify the bits of the new packet filter. If any bits are set that ++ we don't support, leave. */ ++ if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) { ++ rStatus = WLAN_STATUS_NOT_SUPPORTED; ++ break; ++ } ++#if DBG ++ /* Need to enable or disable promiscuous support depending on the new ++ filter. */ ++ if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS) ++ DBGLOG(OID, TRACE, "Enable promiscuous mode\n"); ++ else ++ DBGLOG(OID, TRACE, "Disable promiscuous mode\n"); ++ ++ if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) ++ DBGLOG(OID, TRACE, "Enable all-multicast mode\n"); ++ else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) ++ DBGLOG(OID, TRACE, "Enable multicast\n"); ++ else ++ DBGLOG(OID, TRACE, "Disable multicast\n"); ++ ++ if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) ++ DBGLOG(OID, TRACE, "Enable Broadcast\n"); ++ else ++ DBGLOG(OID, TRACE, "Disable Broadcast\n"); ++#endif ++ } while (FALSE); ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) { ++ /* Store the packet filter */ ++ ++ prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK; ++ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RX_FILTER, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(UINT_32), ++ (PUINT_8) &prAdapter->u4OsPacketFilter, pvSetBuffer, u4SetBufferLen); ++ } else { ++ return rStatus; ++ } ++} /* wlanoidSetCurrentPacketFilter */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current packet filter. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryCurrentPacketFilter"); ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen >= sizeof(UINT_32)) { ++ ASSERT(pvQueryBuffer); ++ *(PUINT_32) pvQueryBuffer = prAdapter->u4OsPacketFilter; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidQueryCurrentPacketFilter */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query ACPI device power state. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++#if DBG ++ PPARAM_DEVICE_POWER_STATE prPowerState; ++#endif ++ ++ DEBUGFUNC("wlanoidQueryAcpiDevicePowerState"); ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); ++ ++#if DBG ++ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvQueryBuffer; ++ switch (*prPowerState) { ++ case ParamDeviceStateD0: ++ DBGLOG(OID, INFO, "Query Power State: D0\n"); ++ break; ++ case ParamDeviceStateD1: ++ DBGLOG(OID, INFO, "Query Power State: D1\n"); ++ break; ++ case ParamDeviceStateD2: ++ DBGLOG(OID, INFO, "Query Power State: D2\n"); ++ break; ++ case ParamDeviceStateD3: ++ DBGLOG(OID, INFO, "Query Power State: D3\n"); ++ break; ++ default: ++ break; ++ } ++#endif ++ ++ /* Since we will disconnect the newwork, therefore we do not ++ need to check queue empty */ ++ *(PPARAM_DEVICE_POWER_STATE) pvQueryBuffer = ParamDeviceStateD3; ++ /* WARNLOG(("Ready to transition to D3\n")); */ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* pwrmgtQueryPower */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set ACPI device power state. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PPARAM_DEVICE_POWER_STATE prPowerState; ++ BOOLEAN fgRetValue = TRUE; ++ ++ DEBUGFUNC("wlanoidSetAcpiDevicePowerState"); ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); ++ ++ ASSERT(pvSetBuffer); ++ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvSetBuffer; ++ switch (*prPowerState) { ++ case ParamDeviceStateD0: ++ DBGLOG(OID, INFO, "Set Power State: D0\n"); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD0); ++ fgRetValue = nicpmSetAcpiPowerD0(prAdapter); ++ break; ++ case ParamDeviceStateD1: ++ DBGLOG(OID, INFO, "Set Power State: D1\n"); ++ /* no break here */ ++ case ParamDeviceStateD2: ++ DBGLOG(OID, INFO, "Set Power State: D2\n"); ++ /* no break here */ ++ case ParamDeviceStateD3: ++ DBGLOG(OID, INFO, "Set Power State: D3\n"); ++ fgRetValue = nicpmSetAcpiPowerD3(prAdapter); ++ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); ++ break; ++ default: ++ break; ++ } ++ ++ if (fgRetValue == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ else ++ return WLAN_STATUS_FAILURE; ++} /* end of wlanoidSetAcpiDevicePowerState() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current fragmentation threshold. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryFragThreshold"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ DBGLOG(OID, LOUD, "\n"); ++ ++#if CFG_TX_FRAGMENT ++ ++ return WLAN_STATUS_SUCCESS; ++ ++#else ++ ++ return WLAN_STATUS_NOT_SUPPORTED; ++#endif /* CFG_TX_FRAGMENT */ ++ ++} /* end of wlanoidQueryFragThreshold() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a new fragmentation threshold to the ++* driver. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#if CFG_TX_FRAGMENT ++ ++ return WLAN_STATUS_SUCCESS; ++ ++#else ++ ++ return WLAN_STATUS_NOT_SUPPORTED; ++#endif /* CFG_TX_FRAGMENT */ ++ ++} /* end of wlanoidSetFragThreshold() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the current RTS threshold. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryRtsThreshold"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ DBGLOG(OID, LOUD, "\n"); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { ++ *pu4QueryInfoLen = sizeof(PARAM_RTS_THRESHOLD); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ *((PARAM_RTS_THRESHOLD *) pvQueryBuffer) = prAdapter->rWlanInfo.eRtsThreshold; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidQueryRtsThreshold */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a new RTS threshold to the driver. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PARAM_RTS_THRESHOLD *prRtsThreshold; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_RTS_THRESHOLD); ++ if (u4SetBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prRtsThreshold = (PARAM_RTS_THRESHOLD *) pvSetBuffer; ++ *prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* wlanoidSetRtsThreshold */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to turn radio off. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ ++ DEBUGFUNC("wlanoidSetDisassociate"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 0; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ /* prepare message to AIS */ ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ ++ /* Send AIS Abort Message */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; ++ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ /* indicate for disconnection */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ DBGLOG(OID, INFO, "DisconnectByOid\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, 0); ++ } ++#if !defined(LINUX) ++ prAdapter->fgIsRadioOff = TRUE; ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} /* wlanoidSetDisassociate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query the power save profile. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen != 0) { ++ ASSERT(pvQueryBuffer); ++ ++/* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE)(prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); */ ++ *(PPARAM_POWER_MODE) pvQueryBuffer = ++ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_AIS_INDEX].ucPsProfile); ++ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); ++ ++ /* hack for CTIA power mode setting function */ ++ if (prAdapter->fgEnCtiaPowerMode) { ++ /* set to non-zero value (to prevent MMI query 0, before it intends to set 0, */ ++ /* which will skip its following state machine) */ ++ *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) 2; ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the power save profile. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status; ++ PARAM_POWER_MODE ePowerMode; ++ ++ DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); ++ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { ++ /* WARNLOG(("Invalid power mode %d\n", */ ++ /* *(PPARAM_POWER_MODE) pvSetBuffer)); */ ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; ++ ++ if (prAdapter->fgEnCtiaPowerMode) { ++ if (ePowerMode == Param_PowerModeCAM) ++ ; ++ else { ++ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ ++ ++ if (prAdapter->u4CtiaPowerMode == 0) ++ /* force to keep in CAM mode */ ++ ePowerMode = Param_PowerModeCAM; ++ else if (prAdapter->u4CtiaPowerMode == 1) ++ ePowerMode = Param_PowerModeMAX_PSP; ++ else if (prAdapter->u4CtiaPowerMode == 2) ++ ePowerMode = Param_PowerModeFast_PSP; ++ } ++ } ++ ++ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); ++ ++ switch (ePowerMode) { ++ case Param_PowerModeCAM: ++ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to CAM (%d)\n", ePowerMode); ++ break; ++ case Param_PowerModeMAX_PSP: ++ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to MAX PS (%d)\n", ePowerMode); ++ break; ++ case Param_PowerModeFast_PSP: ++ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to FAST PS (%d)\n", ePowerMode); ++ break; ++ default: ++ DBGLOG(OID, INFO, "invalid Wi-Fi PS mode setting (%d)\n", ePowerMode); ++ break; ++ } ++ ++ return status; ++ ++} /* end of wlanoidSetAcpiDevicePowerStateMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current status of AdHoc Mode. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQueryAdHocMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set AdHoc Mode. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetAdHocMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query RF frequency. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryFrequency"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) { ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ *(PUINT_32) pvQueryBuffer = ++ nicChannelNum2Freq(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].ucPrimaryChannel); ++ } else { ++ *(PUINT_32) pvQueryBuffer = 0; ++ } ++ } else { ++ *(PUINT_32) pvQueryBuffer = nicChannelNum2Freq(prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQueryFrequency() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set RF frequency by User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4FreqInKHz; ++ ++ DEBUGFUNC("wlanoidSetFrequency"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ pu4FreqInKHz = (PUINT_32) pvSetBuffer; ++ ++ prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(*pu4FreqInKHz); ++ prAdapter->rWifiVar.rConnSettings.eAdHocBand = *pu4FreqInKHz < 5000000 ? BAND_2G4 : BAND_5G; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetFrequency() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set 802.11 channel of the radio frequency. ++* This is a proprietary function call to Lunux currently. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetChannel(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(0); /* // */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the Beacon Interval from User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryBeaconInterval"); ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) ++ *(PUINT_32) pvQueryBuffer = prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod; ++ else ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; ++ } else { ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) ++ *(PUINT_32) pvQueryBuffer = 0; ++ else ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidQueryBeaconInterval() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the Beacon Interval to User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4BeaconInterval; ++ ++ DEBUGFUNC("wlanoidSetBeaconInterval"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ pu4BeaconInterval = (PUINT_32) pvSetBuffer; ++ ++ if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) { ++ DBGLOG(OID, TRACE, "Invalid Beacon Interval = %u\n", *pu4BeaconInterval); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ prAdapter->rWlanInfo.u2BeaconPeriod = (UINT_16) *pu4BeaconInterval; ++ ++ DBGLOG(OID, INFO, "Set beacon interval: %d\n", prAdapter->rWlanInfo.u2BeaconPeriod); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetBeaconInterval() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the ATIM window from User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryAtimWindow"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) ++ *(PUINT_32) pvQueryBuffer = 0; ++ else ++ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2AtimWindow; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wlanoidQueryAtimWindow() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the ATIM window to User Settings. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4AtimWindow; ++ ++ DEBUGFUNC("wlanoidSetAtimWindow"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ pu4AtimWindow = (PUINT_32) pvSetBuffer; ++ ++ prAdapter->rWlanInfo.u2AtimWindow = (UINT_16) *pu4AtimWindow; ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetAtimWindow() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to Set the MAC address which is currently used by the NIC. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(0); /* // */ ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of wlanoidSetCurrentAddr() */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setting the checksum offload function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ UINT_32 i, u4CSUMFlags; ++ CMD_BASIC_CONFIG rCmdBasicConfig; ++ ++ DEBUGFUNC("wlanoidSetCSUMOffload"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ u4CSUMFlags = *(PUINT_32) pvSetBuffer; ++ ++ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); ++ ++ for (i = 0; i < 6; i++) { /* set to broadcast address for not-specified */ ++ rCmdBasicConfig.rMyMacAddr[i] = 0xff; ++ } ++ ++ rCmdBasicConfig.ucNative80211 = 0; /* @FIXME: for Vista */ ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) ++ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) ++ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) ++ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) ++ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2); ++ ++ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) ++ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1); ++ ++ if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) ++ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0); ++ ++ prAdapter->u4CSUMFlags = u4CSUMFlags; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BASIC_CONFIG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_BASIC_CONFIG), (PUINT_8) &rCmdBasicConfig, pvSetBuffer, u4SetBufferLen); ++} ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setting the IP address for pattern search function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 i, j; ++ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; ++ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; ++ P_PARAM_NETWORK_ADDRESS prNetworkAddress; ++ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; ++ UINT_32 u4IpAddressCount, u4CmdSize; ++ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ UINT_32 u4IpV4AddrListSize; ++ P_BSS_INFO_T prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++#endif ++ ++ DEBUGFUNC("wlanoidSetNetworkAddress"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 4; ++ ++ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ *pu4SetInfoLen = 0; ++ u4IpAddressCount = 0; ++ ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ u4IpAddressCount++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ /* construct payload of command packet */ ++ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + ++ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; ++ if (u4IpAddressCount == 0) ++ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); ++ ++ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); ++ ++ if (prCmdNetworkAddressList == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ u4IpV4AddrListSize = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + ++ (u4IpAddressCount * sizeof(IPV4_NETWORK_ADDRESS)); ++ if (prBssInfo->prIpV4NetAddrList) ++ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); ++ prBssInfo->prIpV4NetAddrList = (P_IPV4_NETWORK_ADDRESS_LIST) kalMemAlloc(u4IpV4AddrListSize, VIR_MEM_TYPE); ++ if (prBssInfo->prIpV4NetAddrList == NULL) { ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return WLAN_STATUS_FAILURE; ++ } ++ prBssInfo->prIpV4NetAddrList->ucAddrCount = (UINT_8) u4IpAddressCount; ++#endif ++ ++ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ ++ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ ++ /* only to set IP address to FW once ARP filter is enabled */ ++ if (prAdapter->fgEnArpFilter) { ++ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ ++ DBGLOG(OID, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); ++ ++ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; ++ ++ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ kalMemCopy(prBssInfo->prIpV4NetAddrList->arNetAddr[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++#endif ++ ++ j++; ++ ++ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; ++ DBGLOG(OID, INFO, ++ "prNetAddrIp->in_addr:%d:%d:%d:%d\n", pucBuf[0], pucBuf[1], pucBuf[2], ++ pucBuf[3]); ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ } ++ ++ } else { ++ prCmdNetworkAddressList->ucAddressCount = 0; ++ } ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_IP_ADDRESS, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetIpAddress, ++ nicOidCmdTimeoutCommon, ++ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); ++ ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set driver to switch into RF test mode ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, ++* should be NULL ++* \param[in] u4SetBufferLen The length of the set buffer, should be 0 ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_DATA ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus; ++ CMD_TEST_CTRL_T rCmdTestCtrl; ++ ++ DEBUGFUNC("wlanoidRftestSetTestMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen == 0) { ++ if (prAdapter->fgTestMode == FALSE) { ++ /* switch to RF Test mode */ ++ rCmdTestCtrl.ucAction = 0; /* Switch mode */ ++ rCmdTestCtrl.u.u4OpMode = 1; /* RF test mode */ ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TEST_MODE, ++ TRUE, ++ TRUE, ++ TRUE, ++ nicCmdEventEnterRfTest, ++ nicOidCmdEnterRFTestTimeout, ++ sizeof(CMD_TEST_CTRL_T), ++ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); ++ } else { ++ /* already in test mode .. */ ++ rStatus = WLAN_STATUS_SUCCESS; ++ } ++ } else { ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ } ++ DBGLOG(OID, INFO, "Enter TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", ++ u4SetBufferLen, prAdapter->fgTestMode, rStatus); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set driver to switch into normal operation mode from RF test mode ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* should be NULL ++* \param[in] u4SetBufferLen The length of the set buffer, should be 0 ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_DATA ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus; ++ CMD_TEST_CTRL_T rCmdTestCtrl; ++ ++ DEBUGFUNC("wlanoidRftestSetTestMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen == 0) { ++ if (prAdapter->fgTestMode == TRUE) { ++ /* switch to normal mode */ ++ rCmdTestCtrl.ucAction = 0; /* Switch mode */ ++ rCmdTestCtrl.u.u4OpMode = 0; /* normal mode */ ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TEST_MODE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventLeaveRfTest, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_TEST_CTRL_T), ++ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); ++ } else { ++ /* already in normal mode .. */ ++ rStatus = WLAN_STATUS_SUCCESS; ++ } ++ } else { ++ rStatus = WLAN_STATUS_INVALID_DATA; ++ } ++ DBGLOG(OID, INFO, "Abort TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", ++ u4SetBufferLen, prAdapter->fgTestMode, rStatus); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief query for RF test parameter ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++* \retval WLAN_STATUS_NOT_SUPPORTED ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidRftestQueryAutoTest"); ++ ++ ASSERT(prAdapter); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); ++ ++ if (u4QueryBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { ++ DBGLOG(OID, ERROR, "Invalid data. QueryBufferLen: %u.\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvQueryBuffer; ++ rStatus = rftestQueryATInfo(prAdapter, ++ prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData, pvQueryBuffer, u4QueryBufferLen); ++ ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set RF test parameter ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidRftestSetAutoTest"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); ++ ++ if (u4SetBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { ++ DBGLOG(OID, ERROR, "Invalid data. SetBufferLen: %u.\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvSetBuffer; ++ rStatus = rftestSetATInfo(prAdapter, prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData); ++ ++ return rStatus; ++} ++ ++/* RF test OID set handler */ ++WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_TEST_CTRL_T pCmdTestCtrl; ++ UINT_8 ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_TEST_MODE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pvInformationBuffer = NULL; ++ prCmdInfo->u4InformationBufferLength = 0; ++ ++ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); ++ pCmdTestCtrl->ucAction = 1; /* Set ATInfo */ ++ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; ++ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prAdapter->prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} ++ ++WLAN_STATUS ++rftestQueryATInfo(IN P_ADAPTER_T prAdapter, ++ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_CMD_TEST_CTRL_T pCmdTestCtrl; ++ UINT_8 ucCmdSeqNum; ++ P_EVENT_TEST_STATUS prTestStatus; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) { ++ /* driver implementation */ ++ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; ++ ++ prTestStatus->rATInfo.u4FuncData = ++ (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); ++ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); ++ ++ return WLAN_STATUS_SUCCESS; ++ } else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) { ++ /* driver implementation */ ++ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; ++ ++ prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION; ++ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_TEST_MODE; ++ prCmdInfo->fgSetQuery = FALSE; ++ prCmdInfo->fgNeedResp = TRUE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); ++ prCmdInfo->pvInformationBuffer = pvQueryBuffer; ++ prCmdInfo->u4InformationBufferLength = u4QueryBufferLen; ++ ++ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); ++ pCmdTestCtrl->ucAction = 2; /* Get ATInfo */ ++ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; ++ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prAdapter->prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} ++ ++WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen) ++{ ++ CMD_TEST_CTRL_T rCmdTestCtrl; ++ ++ ASSERT(prAdapter); ++ ++ rCmdTestCtrl.ucAction = 5; /* Set Channel Frequency */ ++ rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TEST_MODE, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, sizeof(CMD_TEST_CTRL_T), (PUINT_8) &rCmdTestCtrl, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command packet generation utility ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucCID Command ID ++* \param[in] fgSetQuery Set or Query ++* \param[in] fgNeedResp Need for response ++* \param[in] pfCmdDoneHandler Function pointer when command is done ++* \param[in] u4SetQueryInfoLen The length of the set/query buffer ++* \param[in] pucInfoBuffer Pointer to set/query buffer ++* ++* ++* \retval WLAN_STATUS_PENDING ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); ++ ++ DEBUGFUNC("wlanSendSetQueryCmd"); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(OID, TRACE, "ucCmdSeqNum =%d, ucCID =%d\n", ucCmdSeqNum, ucCID); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); ++ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; ++ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; ++ prCmdInfo->fgIsOid = fgIsOid; ++ prCmdInfo->ucCID = ucCID; ++ prCmdInfo->fgSetQuery = fgSetQuery; ++ prCmdInfo->fgNeedResp = fgNeedResp; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; ++ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) ++ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++#if CFG_SUPPORT_WAPI ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WAPI ui to set wapi mode, which is needed to info the the driver ++* to operation at WAPI mode while driver initialize. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ DEBUGFUNC("wlanoidSetWapiMode"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ASSERT(pvSetBuffer); ++ ++ /* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi assoc ie at the check point */ ++ /* The Adapter Connection setting fgUseWapi will cleat whil oid set mode (infra), */ ++ /* And set fgUseWapi True while set wapi assoc ie */ ++ /* policay selection, add key all depend on this flag, */ ++ /* The fgUseWapi may remove later */ ++ if (*(PUINT_32) pvSetBuffer) ++ prAdapter->fgUseWapi = TRUE; ++ else ++ prAdapter->fgUseWapi = FALSE; ++ ++#if 0 ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + 4)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_BUILD_CONNECTION cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4; ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_WAPI_MODE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetBufferLen; ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ cp = (PUINT_8) (prWifiCmd->aucBuffer); ++ ++ kalMemCopy(cp, (PUINT_8) pvSetBuffer, 4); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++#else ++ return WLAN_STATUS_SUCCESS; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WAPI to set the assoc info, which is needed to add to ++* Association request frame while join WAPI AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_WAPI_INFO_ELEM_T prWapiInfo; ++ PUINT_8 cp; ++ UINT_16 u2AuthSuiteCount = 0; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_32 u4AuthKeyMgtSuite = 0; ++ UINT_32 u4PairSuite = 0; ++ UINT_32 u4GroupSuite = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DEBUGFUNC("wlanoidSetWapiAssocInfo"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ if (u4SetBufferLen < 20 /* From EID to Group cipher */) { ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; ++ DBGLOG(SEC, INFO, "fgWapiMode = FALSE due to u4SetBufferLen %u < 20!\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = TRUE; ++ ++ /* if (prWapiInfo->ucElemId != ELEM_ID_WAPI) */ ++ /* DBGLOG(SEC, TRACE, ("Not WAPI IE ?!\n")); */ ++ ++ /* if (prWapiInfo->ucLength < 18) */ ++ /* return WLAN_STATUS_INVALID_LENGTH; */ ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ prWapiInfo = (P_WAPI_INFO_ELEM_T) pvSetBuffer; ++ ++ if (prWapiInfo->ucElemId != ELEM_ID_WAPI) { ++ DBGLOG(SEC, INFO, "Not WAPI IE ?! u4SetBufferLen = %u\n", u4SetBufferLen); ++ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (prWapiInfo->ucLength < 18) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* Skip Version check */ ++ cp = (PUINT_8) &prWapiInfo->u2AuthKeyMgtSuiteCount; ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ ++ if (u2AuthSuiteCount > 1) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ cp = (PUINT_8) &prWapiInfo->aucAuthKeyMgtSuite1[0]; ++ WLAN_GET_FIELD_32(cp, &u4AuthKeyMgtSuite); ++ ++ DBGLOG(SEC, TRACE, "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n", ++ u2AuthSuiteCount, ++ (UCHAR) (u4AuthKeyMgtSuite & 0x000000FF), ++ (UCHAR) ((u4AuthKeyMgtSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4AuthKeyMgtSuite >> 16) & 0x000000FF), ++ (UCHAR) ((u4AuthKeyMgtSuite >> 24) & 0x000000FF)); ++ ++ if (u4AuthKeyMgtSuite != WAPI_AKM_SUITE_802_1X && u4AuthKeyMgtSuite != WAPI_AKM_SUITE_PSK) ++ ASSERT(FALSE); ++ ++ cp += 4; ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ if (u2PairSuiteCount > 1) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ cp += 2; ++ WLAN_GET_FIELD_32(cp, &u4PairSuite); ++ DBGLOG(SEC, TRACE, "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ u2PairSuiteCount, ++ (UCHAR) (u4PairSuite & 0x000000FF), ++ (UCHAR) ((u4PairSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4PairSuite >> 16) & 0x000000FF), (UCHAR) ((u4PairSuite >> 24) & 0x000000FF)); ++ ++ if (u4PairSuite != WAPI_CIPHER_SUITE_WPI) ++ ASSERT(FALSE); ++ ++ cp += 4; ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ DBGLOG(SEC, TRACE, "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n", ++ (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (u4GroupSuite != WAPI_CIPHER_SUITE_WPI) ++ ASSERT(FALSE); ++ ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite = u4AuthKeyMgtSuite; ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher = u4PairSuite; ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher = u4GroupSuite; ++ ++ kalMemCopy(prAdapter->prGlueInfo->aucWapiAssocInfoIEs, pvSetBuffer, u4SetBufferLen); ++ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = (UINT_16) u4SetBufferLen; ++ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the wpi key to the driver. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ P_PARAM_WPI_KEY_T prNewKey; ++ P_CMD_802_11_KEY prCmdKey; ++ PUINT_8 pc; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanoidSetWapiKey"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ prNewKey = (P_PARAM_WPI_KEY_T) pvSetBuffer; ++ ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) pvSetBuffer, 560); ++ pc = (PUINT_8) pvSetBuffer; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* Exception check */ ++ if (prNewKey->ucKeyID != 0x1 || prNewKey->ucKeyID != 0x0) { ++ prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0); ++ /* DBGLOG(SEC, INFO, ("Invalid WAPI key ID (%d)\r\n", prNewKey->ucKeyID)); */ ++ } ++ ++ /* Dump P_PARAM_WPI_KEY_T content. */ ++ DBGLOG(OID, TRACE, "Set: Dump P_PARAM_WPI_KEY_T content\r\n"); ++ DBGLOG(OID, TRACE, "TYPE : %d\r\n", prNewKey->eKeyType); ++ DBGLOG(OID, TRACE, "Direction : %d\r\n", prNewKey->eDirection); ++ DBGLOG(OID, TRACE, "KeyID : %d\r\n", prNewKey->ucKeyID); ++ DBGLOG(OID, TRACE, "AddressIndex:\r\n"); ++ DBGLOG_MEM8(OID, TRACE, prNewKey->aucAddrIndex, 12); ++ prNewKey->u4LenWPIEK = 16; ++ ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPIEK, (UINT_8) prNewKey->u4LenWPIEK); ++ prNewKey->u4LenWPICK = 16; ++ ++ DBGLOG(OID, TRACE, "CK Key(%d):\r\n", (UINT_8) prNewKey->u4LenWPICK); ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPICK, (UINT_8) prNewKey->u4LenWPICK); ++ DBGLOG(OID, TRACE, "PN:\r\n"); ++ if (prNewKey->eKeyType == 0) { ++ prNewKey->aucPN[0] = 0x5c; ++ prNewKey->aucPN[1] = 0x36; ++ prNewKey->aucPN[2] = 0x5c; ++ prNewKey->aucPN[3] = 0x36; ++ prNewKey->aucPN[4] = 0x5c; ++ prNewKey->aucPN[5] = 0x36; ++ prNewKey->aucPN[6] = 0x5c; ++ prNewKey->aucPN[7] = 0x36; ++ prNewKey->aucPN[8] = 0x5c; ++ prNewKey->aucPN[9] = 0x36; ++ prNewKey->aucPN[10] = 0x5c; ++ prNewKey->aucPN[11] = 0x36; ++ prNewKey->aucPN[12] = 0x5c; ++ prNewKey->aucPN[13] = 0x36; ++ prNewKey->aucPN[14] = 0x5c; ++ prNewKey->aucPN[15] = 0x36; ++ } ++ ++ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucPN, 16); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetBufferLen)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ ++ /* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; ++ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); ++ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; ++ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; ++ prCmdInfo->fgIsOid = TRUE; ++ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetBufferLen; ++ prCmdInfo->pvInformationBuffer = pvSetBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; ++ ++ /* Setup WIFI_CMD_T */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); ++ ++ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ prCmdKey->ucAddRemove = 1; /* Add */ ++ ++ if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) { ++ prCmdKey->ucTxKey = 1; ++ prCmdKey->ucKeyType = 1; ++ } ++ ++ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->aucAddrIndex, MAC_ADDR_LEN); ++ ++ prCmdKey->ucNetType = 0; /* AIS */ ++ ++ prCmdKey->ucKeyId = prNewKey->ucKeyID; ++ ++ prCmdKey->ucKeyLen = 32; ++ ++ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI; ++ ++ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucWPIEK, 16); ++ ++ kalMemCopy(prCmdKey->aucKeyMaterial + 16, (PUINT_8) prNewKey->aucWPICK, 16); ++ ++ kalMemCopy(prCmdKey->aucKeyRsc, (PUINT_8) prNewKey->aucPN, 16); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ ++ return WLAN_STATUS_PENDING; ++} /* wlanoidSetAddKey */ ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WSC to set the assoc info, which is needed to add to ++* Association request frame while join WPS AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DEBUGFUNC("wlanoidSetWSCAssocInfo"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ kalMemCopy(prAdapter->prGlueInfo->aucWSCAssocInfoIE, pvSetBuffer, u4SetBufferLen); ++ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = (UINT_16) u4SetBufferLen; ++ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++#endif ++ ++#if CFG_ENABLE_WAKEUP_ON_LAN ++WLAN_STATUS ++wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_PM_PACKET_PATTERN prPacketPattern; ++ ++ DEBUGFUNC("wlanoidSetAddWakeupPattern"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); ++ ++ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; ++ ++ /* FIXME: ++ * Send the struct to firmware */ ++ ++ return WLAN_STATUS_FAILURE; ++} ++ ++WLAN_STATUS ++wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_PM_PACKET_PATTERN prPacketPattern; ++ ++ DEBUGFUNC("wlanoidSetAddWakeupPattern"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); ++ ++ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; ++ ++ /* FIXME: ++ * Send the struct to firmware */ ++ ++ return WLAN_STATUS_FAILURE; ++} ++ ++WLAN_STATUS ++wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ PUINT_32 pu4WakeupEventEnable; ++ ++ DEBUGFUNC("wlanoidQueryEnableWakeup"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ if (u4QueryBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ ++ pu4WakeupEventEnable = (PUINT_32) pvQueryBuffer; ++ ++ *pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4WakeupEventEnable; ++ ++ DEBUGFUNC("wlanoidSetEnableWakup"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ ++ if (u4SetBufferLen < sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ pu4WakeupEventEnable = (PUINT_32) pvSetBuffer; ++ prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable; ++ ++ /* FIXME: ++ * Send Command Event for setting wakeup-pattern / Magic Packet to firmware ++ * */ ++ ++ return WLAN_STATUS_FAILURE; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to configure PS related settings for WMM-PS test. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T prWmmPsTestInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ CMD_SET_WMM_PS_TEST_STRUCT_T rSetWmmPsTestParam; ++ UINT_16 u2CmdBufLen; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("wlanoidSetWiFiWmmPsTest"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T); ++ ++ prWmmPsTestInfo = (P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T) pvSetBuffer; ++ ++ rSetWmmPsTestParam.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ rSetWmmPsTestParam.bmfgApsdEnAc = prWmmPsTestInfo->bmfgApsdEnAc; ++ rSetWmmPsTestParam.ucIsEnterPsAtOnce = prWmmPsTestInfo->ucIsEnterPsAtOnce; ++ rSetWmmPsTestParam.ucIsDisableUcTrigger = prWmmPsTestInfo->ucIsDisableUcTrigger; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[rSetWmmPsTestParam.ucNetTypeIndex]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ prPmProfSetupInfo->ucBmpDeliveryAC = (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3); ++ prPmProfSetupInfo->ucBmpTriggerAC = rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3); ++ ++ u2CmdBufLen = sizeof(CMD_SET_WMM_PS_TEST_STRUCT_T); ++ ++#if 0 ++ /* it will apply the disable trig or not immediately */ ++ if (prPmInfo->ucWmmPsDisableUcPoll && prPmInfo->ucWmmPsConnWithTrig) ++ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); */ ++ else ++ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); */ ++#endif ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_WMM_PS_TEST_PARMS, TRUE, FALSE, TRUE, NULL, /* TODO? */ ++ NULL, u2CmdBufLen, (PUINT_8) &rSetWmmPsTestParam, NULL, 0); ++ ++ return rStatus; ++} /* wlanoidSetWiFiWmmPsTest */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to configure enable/disable TX A-MPDU feature. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ CMD_TX_AMPDU_T rTxAmpdu; ++ UINT_16 u2CmdBufLen; ++ PBOOLEAN pfgEnable; ++ ++ DEBUGFUNC("wlanoidSetTxAmpdu"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(BOOLEAN); ++ ++ pfgEnable = (PBOOLEAN) pvSetBuffer; ++ ++ rTxAmpdu.fgEnable = *pfgEnable; ++ ++ u2CmdBufLen = sizeof(CMD_TX_AMPDU_T); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TX_AMPDU, ++ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rTxAmpdu, NULL, 0); ++ ++ return rStatus; ++} /* wlanoidSetTxAmpdu */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to configure reject/accept ADDBA Request. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ CMD_ADDBA_REJECT_T rAddbaReject; ++ UINT_16 u2CmdBufLen; ++ PBOOLEAN pfgEnable; ++ ++ DEBUGFUNC("wlanoidSetAddbaReject"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(BOOLEAN); ++ ++ pfgEnable = (PBOOLEAN) pvSetBuffer; ++ ++ rAddbaReject.fgEnable = *pfgEnable; ++ ++ u2CmdBufLen = sizeof(CMD_ADDBA_REJECT_T); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ADDBA_REJECT, ++ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rAddbaReject, NULL, 0); ++ ++ return rStatus; ++} /* wlanoidSetAddbaReject */ ++ ++#if CFG_SLT_SUPPORT ++ ++WLAN_STATUS ++wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; ++ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; ++ ++ DEBUGFUNC("wlanoidQuerySLTStatus"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvQueryBuffer); ++ ++ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvQueryBuffer; ++ ++ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); ++ ++ switch (prMtkSltInfo->rSltFuncIdx) { ++ case ENUM_MTK_SLT_FUNC_LP_SET: ++ { ++ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); ++ ++ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt; ++ } ++ break; ++ default: ++ /* TBD... */ ++ break; ++ } ++ ++ return rWlanStatus; ++} /* wlanoidQuerySLTStatus */ ++ ++WLAN_STATUS ++wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; ++ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; ++ ++ /* 1. Action: Update or Initial Set ++ * 2. Role. ++ * 3. Target MAC address. ++ * 4. RF BW & Rate Settings ++ */ ++ ++ DEBUGFUNC("wlanoidUpdateSLTMode"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvSetBuffer; ++ ++ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ switch (prMtkSltInfo->rSltFuncIdx) { ++ case ENUM_MTK_SLT_FUNC_INITIAL: /* Initialize */ ++ { ++ P_PARAM_MTK_SLT_INITIAL_STRUCT_T prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_INITIAL_STRUCT_T)); ++ ++ prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ if (prSltInfo->prPseudoStaRec != NULL) { ++ /* The driver has been initialized. */ ++ prSltInfo->prPseudoStaRec = NULL; ++ } ++ ++ prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc(prAdapter, ++ BSS_TYPE_IBSS, ++ prMtkSltInit->aucTargetMacAddr, ++ prMtkSltInit->aucTargetMacAddr); ++ ++ prSltInfo->u2SiteID = prMtkSltInit->u2SiteID; ++ ++ /* Bandwidth 2.4G: Channel 1~14 ++ * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64, ++ * *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, ++ * 149, 153, *157, 161, ++ * 184, 188, 192, 196, 200, 204, 208, 212, *216 ++ */ ++ prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5; ++ ++ switch (prSltInfo->ucChannel2G4) { ++ case 1: ++ prSltInfo->ucChannel5G = 36; ++ break; ++ case 6: ++ prSltInfo->ucChannel5G = 52; ++ break; ++ case 11: ++ prSltInfo->ucChannel5G = 104; ++ break; ++ case 16: ++ prSltInfo->ucChannel2G4 = 14; ++ prSltInfo->ucChannel5G = 161; ++ break; ++ default: ++ ASSERT(FALSE); ++ } ++ ++ if (prSltInfo->prPseudoBssDesc == NULL) { ++ do { ++ prSltInfo->prPseudoBssDesc = scanAllocateBssDesc(prAdapter); ++ ++ if (prSltInfo->prPseudoBssDesc == NULL) { ++ rWlanStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ prBssDesc = prSltInfo->prPseudoBssDesc; ++ } while (FALSE); ++ } else { ++ prBssDesc = prSltInfo->prPseudoBssDesc; ++ } ++ ++ if (prBssDesc) { ++ prBssDesc->eBSSType = BSS_TYPE_IBSS; ++ ++ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prMtkSltInit->aucTargetMacAddr); ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); ++ ++ prBssDesc->u2BeaconInterval = 100; ++ prBssDesc->u2ATIMWindow = 0; ++ prBssDesc->ucDTIMPeriod = 1; ++ ++ prBssDesc->u2IELength = 0; ++ ++ prBssDesc->fgIsERPPresent = TRUE; ++ prBssDesc->fgIsHTPresent = TRUE; ++ ++ prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX); ++ prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX); ++ prBssDesc->fgIsUnknownBssBasicRate = FALSE; ++ ++ prBssDesc->fgIsLargerTSF = TRUE; ++ ++ prBssDesc->eBand = BAND_2G4; ++ ++ prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4; ++ ++ prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN; ++ ++ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); ++ } ++ } ++ break; ++ case ENUM_MTK_SLT_FUNC_RATE_SET: /* Update RF Settings. */ ++ if (prSltInfo->prPseudoStaRec == NULL) { ++ rWlanStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++ P_PARAM_MTK_SLT_TR_TEST_STRUCT_T prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_TR_TEST_STRUCT_T)); ++ ++ prStaRec = prSltInfo->prPseudoStaRec; ++ prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { ++ prBssInfo->eBand = BAND_5G; ++ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel5G; ++ } ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM24) { ++ prBssInfo->eBand = BAND_2G4; ++ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel2G4; ++ } ++ ++ if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) { ++ /* RF 40 */ ++ /* It would controls RFBW capability in WTBL. */ ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ /* This controls RF BW, RF BW would be 40 only if */ ++ /* 1. PHY_TYPE_BIT_HT is TRUE. */ ++ /* 2. SCO is SCA/SCB. */ ++ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ ++ /* U20/L20 Control. */ ++ switch (prTRSetting->u4FixedRate & 0xC000) { ++ case FIXED_EXT_CHNL_U20: ++ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* +2 */ ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) ++ prBssInfo->ucPrimaryChannel += 2; ++ else { ++ /* For channel 1, testing L20 at channel 8. */ ++ if (prBssInfo->ucPrimaryChannel < 5) ++ prBssInfo->ucPrimaryChannel = 8; ++ } ++ break; ++ case FIXED_EXT_CHNL_L20: ++ default: /* 40M */ ++ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* -2 */ ++ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { ++ prBssInfo->ucPrimaryChannel -= 2; ++ } else { ++ /* For channel 11 / 14. testing U20 at channel 3. */ ++ if (prBssInfo->ucPrimaryChannel > 10) ++ prBssInfo->ucPrimaryChannel = 3; ++ } ++ break; ++ } ++ } else { ++ /* RF 20 */ ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; ++ prBssInfo->eBssSCO = CHNL_EXT_SCN; ++ } ++ ++ prBssInfo->fgErpProtectMode = FALSE; ++ prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; ++ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; ++ ++ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); ++ ++ prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++ ++ switch (prTRSetting->u4FixedRate & 0xFF) { ++ case RATE_OFDM_54M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_54M_INDEX); ++ break; ++ case RATE_OFDM_48M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_48M_INDEX); ++ break; ++ case RATE_OFDM_36M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); ++ break; ++ case RATE_OFDM_24M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_24M_INDEX); ++ break; ++ case RATE_OFDM_6M: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_6M_INDEX); ++ break; ++ case RATE_CCK_11M_LONG: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_11M_INDEX); ++ break; ++ case RATE_CCK_1M_LONG: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_1M_INDEX); ++ break; ++ case RATE_GF_MCS_0: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; ++ break; ++ case RATE_MM_MCS_7: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; ++#if 0 /* Only for Current Measurement Mode. */ ++ prStaRec->u2HtCapInfo |= (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++#endif ++ break; ++ case RATE_GF_MCS_7: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; ++ break; ++ default: ++ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); ++ break; ++ } ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ break; ++ case ENUM_MTK_SLT_FUNC_LP_SET: /* Reset LP Test Result. */ ++ { ++ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; ++ ++ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); ++ ++ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; ++ ++ if (prSltInfo->prPseudoBssDesc == NULL) { ++ /* Please initial SLT Mode first. */ ++ break; ++ } ++ prBssDesc = prSltInfo->prPseudoBssDesc; ++ ++ switch (prLpSetting->rLpTestMode) { ++ case ENUM_MTK_LP_TEST_NORMAL: ++ /* In normal mode, we would use target MAC address to be the BSSID. */ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); ++ prSltInfo->fgIsDUT = FALSE; ++ break; ++ case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE: ++ /* 1. Lower AIFS of BCN queue. ++ * 2. Fixed Random Number tobe 0. ++ */ ++ prSltInfo->fgIsDUT = FALSE; ++ /* In LP test mode, we would use MAC address of Golden Sample to be the BSSID. */ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); ++ break; ++ case ENUM_MTK_LP_TEST_DUT: ++ /* 1. Enter Sleep Mode. ++ * 2. Fix random number a large value & enlarge AIFN of BCN queue. ++ */ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssDesc->aucSrcAddr); ++ prSltInfo->u4BeaconReceiveCnt = 0; ++ prSltInfo->fgIsDUT = TRUE; ++ break; ++ } ++ ++ } ++ ++ break; ++ default: ++ break; ++ } ++ ++ return WLAN_STATUS_FAILURE; ++ ++ return rWlanStatus; ++} /* wlanoidUpdateSLTMode */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query NVRAM value. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; ++ UINT_16 u2Data; ++ BOOLEAN fgStatus; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidQueryNvramRead"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvQueryBuffer; ++ ++ if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_READ) { ++ /* change to byte offset */ ++ fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, ++ prNvramRwInfo->ucEepromIndex << 1, ++ &u2Data); ++ ++ if (fgStatus) { ++ prNvramRwInfo->u2EepromData = u2Data; ++ DBGLOG(OID, INFO, "NVRAM Read: index=%#X, data=%#02X\r\n", ++ prNvramRwInfo->ucEepromIndex, u2Data); ++ } else { ++ DBGLOG(OID, ERROR, "NVRAM Read Failed: index=%#x.\r\n", prNvramRwInfo->ucEepromIndex); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ } else if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_GETSIZE) { ++ prNvramRwInfo->u2EepromData = CFG_FILE_WIFI_REC_SIZE; ++ DBGLOG(OID, INFO, "EEPROM size =%d\r\n", prNvramRwInfo->u2EepromData); ++ } ++ ++ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ return rStatus; ++} /* wlanoidQueryNvramRead */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to write NVRAM value. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; ++ BOOLEAN fgStatus; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ DEBUGFUNC("wlanoidSetNvramWrite"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvSetBuffer; ++ ++ /* change to byte offset */ ++ fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, ++ prNvramRwInfo->ucEepromIndex << 1, ++ prNvramRwInfo->u2EepromData); ++ ++ if (fgStatus == FALSE) { ++ DBGLOG(OID, ERROR, "NVRAM Write Failed.\r\n"); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ ++ return rStatus; ++} /* wlanoidSetNvramWrite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get the config data source type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ ASSERT(prAdapter); ++ ++ *pu4QueryInfoLen = sizeof(ENUM_CFG_SRC_TYPE_T); ++ ++ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) ++ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_NVRAM; ++ else ++ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_EEPROM; ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get the config data source type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ ASSERT(prAdapter); ++ ++ *pu4QueryInfoLen = sizeof(P_ENUM_EEPROM_TYPE_T); ++ ++#if CFG_SUPPORT_NIC_CAPABILITY ++ if (prAdapter->fgIsEepromUsed == TRUE) ++ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_PRESENT; ++ else ++ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; ++#else ++ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get the config data source type. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_8 pucCountry; ++ UINT_16 u2CountryCode; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(u4SetBufferLen == 2); ++ ++ *pu4SetInfoLen = 2; ++ ++ pucCountry = pvSetBuffer; ++ u2CountryCode = (((UINT_16) pucCountry[0]) << 8) | ((UINT_16) pucCountry[1]); ++ ++ /* previous country code == FF : ignore country code, current country code == FE : resume */ ++ if (prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup == COUNTRY_CODE_FF) { ++ if (u2CountryCode != COUNTRY_CODE_FE) { ++ DBGLOG(OID, INFO, "Skip country code cmd (0x%04x)\n", u2CountryCode); ++ return WLAN_STATUS_SUCCESS; ++ } ++ DBGLOG(OID, INFO, "Resume handle country code cmd (0x%04x)\n", u2CountryCode); ++ } ++ ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode = u2CountryCode; ++ prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ DBGLOG(OID, LOUD, "u2CountryCodeBakup=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup); ++ ++ /* Force to re-search country code in country domains */ ++ prAdapter->prDomainInfo = NULL; ++ rlmDomainSendCmd(prAdapter, TRUE); ++ ++ /* Update supported channel list in channel table based on current country domain */ ++ wlanUpdateChannelTable(prAdapter->prGlueInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if 0 ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; ++ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; ++ ++ DEBUGFUNC("wlanoidSetNoaParam"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); ++ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; ++ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; ++ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); ++} ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; ++ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; ++ ++ DEBUGFUNC("wlanoidSetOppPsParam"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_OPPPS_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); ++} ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; ++ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("wlanoidSetUApsdParam"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ ++ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; ++ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; ++ ++ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; ++ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; ++ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; ++ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; ++ prPmProfSetupInfo->ucBmpDeliveryAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ prPmProfSetupInfo->ucBmpTriggerAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ ++ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; ++ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_UAPSD_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set BT profile or BT information and the ++* driver will set the built-in PTA configuration into chip. ++* ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ++ P_PTA_IPC_T prPtaIpc; ++ ++ DEBUGFUNC("wlanoidSetBT.\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PTA_IPC_T); ++ if (u4SetBufferLen != sizeof(PTA_IPC_T)) { ++ WARNLOG(("Invalid length %u\n", u4SetBufferLen)); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail to set BT profile because of ACPI_D3\n"); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ prPtaIpc = (P_PTA_IPC_T) pvSetBuffer; ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(OID, INFO, ++ "BCM BWCS CMD: BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", ++ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], ++ prPtaIpc->u.aucBTPParams[3]; ++ ++#endif ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BWCS, ++ TRUE, FALSE, FALSE, NULL, NULL, sizeof(PTA_IPC_T), (PUINT_8) prPtaIpc, NULL, 0); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query current BT profile and BTCR values ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBT(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++/* P_PARAM_PTA_IPC_T prPtaIpc; */ ++/* UINT_32 u4QueryBuffLen; */ ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PTA_IPC_T); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen != sizeof(PTA_IPC_T)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ ASSERT(pvQueryBuffer); ++/* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */ ++/* prPtaIpc->ucCmd = BT_CMD_PROFILE; */ ++/* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */ ++/* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if 0 ++WLAN_STATUS ++wlanoidQueryBtSingleAntenna(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PTA_INFO_T prPtaInfo; ++ PUINT_32 pu4SingleAntenna; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen != sizeof(UINT_32)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ ASSERT(pvQueryBuffer); ++ ++ prPtaInfo = &prAdapter->rPtaInfo; ++ pu4SingleAntenna = (PUINT_32) pvQueryBuffer; ++ ++ if (prPtaInfo->fgSingleAntenna) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 1\r\n")); */ ++ *pu4SingleAntenna = 1; ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 0\r\n")); */ ++ *pu4SingleAntenna = 0; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidSetBtSingleAntenna(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ++ PUINT_32 pu4SingleAntenna; ++ UINT_32 u4SingleAntenna; ++ P_PTA_INFO_T prPtaInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ prPtaInfo = &prAdapter->rPtaInfo; ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ if (u4SetBufferLen != sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) ++ return WLAN_STATUS_SUCCESS; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail to set antenna because of ACPI_D3\n"); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ pu4SingleAntenna = (PUINT_32) pvSetBuffer; ++ u4SingleAntenna = *pu4SingleAntenna; ++ ++ if (u4SingleAntenna == 0) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 0\r\n")); */ ++ prPtaInfo->fgSingleAntenna = FALSE; ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 1\r\n")); */ ++ prPtaInfo->fgSingleAntenna = TRUE; ++ } ++ ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++WLAN_STATUS ++wlanoidQueryPta(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PTA_INFO_T prPtaInfo; ++ PUINT_32 pu4Pta; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen != sizeof(UINT_32)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ ASSERT(pvQueryBuffer); ++ ++ prPtaInfo = &prAdapter->rPtaInfo; ++ pu4Pta = (PUINT_32) pvQueryBuffer; ++ ++ if (prPtaInfo->fgEnabled) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */ ++ *pu4Pta = 1; ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */ ++ *pu4Pta = 0; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS ++wlanoidSetPta(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ PUINT_32 pu4PtaCtrl; ++ UINT_32 u4PtaCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(UINT_32); ++ if (u4SetBufferLen != sizeof(UINT_32)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) ++ return WLAN_STATUS_SUCCESS; ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(OID, WARN, "Fail to set BT setting because of ACPI_D3\n"); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pvSetBuffer); ++ pu4PtaCtrl = (PUINT_32) pvSetBuffer; ++ u4PtaCtrl = *pu4PtaCtrl; ++ ++ if (u4PtaCtrl == 0) { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); */ ++ nicPtaSetFunc(prAdapter, FALSE); ++ } else { ++ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); */ ++ nicPtaSetFunc(prAdapter, TRUE); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++#endif ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Tx power profile. ++* ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ /* P_SET_TXPWR_CTRL_T pTxPwr = (P_SET_TXPWR_CTRL_T)pvSetBuffer; */ ++ /* UINT_32 i; */ ++ WLAN_STATUS rStatus; ++ ++ DEBUGFUNC("wlanoidSetTxPower"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ++#if 0 ++ DBGLOG(OID, INFO, "c2GLegacyStaPwrOffset=%d\n", pTxPwr->c2GLegacyStaPwrOffset); ++ DBGLOG(OID, INFO, "c2GHotspotPwrOffset=%d\n", pTxPwr->c2GHotspotPwrOffset); ++ DBGLOG(OID, INFO, "c2GP2pPwrOffset=%d\n", pTxPwr->c2GP2pPwrOffset); ++ DBGLOG(OID, INFO, "c2GBowPwrOffset=%d\n", pTxPwr->c2GBowPwrOffset); ++ DBGLOG(OID, INFO, "c5GLegacyStaPwrOffset=%d\n", pTxPwr->c5GLegacyStaPwrOffset); ++ DBGLOG(OID, INFO, "c5GHotspotPwrOffset=%d\n", pTxPwr->c5GHotspotPwrOffset); ++ DBGLOG(OID, INFO, "c5GP2pPwrOffset=%d\n", pTxPwr->c5GP2pPwrOffset); ++ DBGLOG(OID, INFO, "c5GBowPwrOffset=%d\n", pTxPwr->c5GBowPwrOffset); ++ DBGLOG(OID, INFO, "ucConcurrencePolicy=%d\n", pTxPwr->ucConcurrencePolicy); ++ ++ for (i = 0; i < 14; i++) ++ DBGLOG(OID, INFO, "acTxPwrLimit2G[%d]=%d\n", i, pTxPwr->acTxPwrLimit2G[i]); ++ ++ for (i = 0; i < 4; i++) ++ DBGLOG(OID, INFO, "acTxPwrLimit5G[%d]=%d\n", i, pTxPwr->acTxPwrLimit5G[i]); ++#endif ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_TXPWR_CTRL, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ TRUE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ u4SetBufferLen, /* u4SetQueryInfoLen */ ++ (PUINT_8) pvSetBuffer, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ return rStatus; ++ ++} ++ ++WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) ++{ ++ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; ++ P_CMD_DUMP_MEM prCmdDumpMem; ++ CMD_DUMP_MEM rCmdDumpMem; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; ++ ++ UINT_32 u4RemainLeng = 0; ++ UINT_32 u4CurAddr = 0; ++ UINT_8 ucFragNum = 0; ++ ++ prCmdDumpMem = &rCmdDumpMem; ++ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; ++ ++ u4RemainLeng = prMemDumpInfo->u4RemainLength; ++ u4CurAddr = prMemDumpInfo->u4Address + prMemDumpInfo->u4Length; ++ ucFragNum = prMemDumpInfo->ucFragNum + 1; ++ ++ /* Query. If request length is larger than max length, do it as ping pong. ++ * Send a command and wait for a event. Send next command while the event is received. ++ * ++ */ ++ do { ++ UINT_32 u4CurLeng = 0; ++ ++ if (u4RemainLeng > u4MemSize) { ++ u4CurLeng = u4MemSize; ++ u4RemainLeng -= u4MemSize; ++ } else { ++ u4CurLeng = u4RemainLeng; ++ u4RemainLeng = 0; ++ } ++ ++ prCmdDumpMem->u4Address = u4CurAddr; ++ prCmdDumpMem->u4Length = u4CurLeng; ++ prCmdDumpMem->u4RemainLength = u4RemainLeng; ++ prCmdDumpMem->ucFragNum = ucFragNum; ++ ++ DBGLOG(OID, TRACE, "[%d] 0x%X, len %u, remain len %u\n", ++ ucFragNum, ++ prCmdDumpMem->u4Address, prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_DUMP_MEM, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryMemDump, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_DUMP_MEM), ++ (PUINT_8) prCmdDumpMem, pvQueryBuffer, u4QueryBufferLen); ++ ++ } while (FALSE); ++ ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to dump memory. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; ++ ++ DEBUGFUNC("wlanoidQueryMemDump"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_32); ++ ++ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; ++ DBGLOG(OID, TRACE, "Dump 0x%X, len %u\n", prMemDumpInfo->u4Address, prMemDumpInfo->u4Length); ++ ++ prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length; ++ prMemDumpInfo->u4Length = 0; ++ prMemDumpInfo->ucFragNum = 0; ++ ++ return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* end of wlanoidQueryMcrRead() */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the p2p mode. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_PARAM_CUSTOM_P2P_SET_STRUCT_T prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) NULL; ++ /* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T)NULL; */ ++ DEBUGFUNC("wlanoidSetP2pMode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T); ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T)) { ++ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) pvSetBuffer; ++ ++ DBGLOG(P2P, INFO, "Set P2P enable %p [%u] mode[%u]\n", prSetP2P, prSetP2P->u4Enable, prSetP2P->u4Mode); ++ ++ /* ++ * enable = 1, mode = 0 => init P2P network ++ * enable = 1, mode = 1 => init Soft AP network ++ * enable = 0 => uninit P2P/AP network ++ */ ++ ++ if (prSetP2P->u4Enable) { ++ p2pSetMode((prSetP2P->u4Mode == 1) ? TRUE : FALSE); ++ ++ if (p2pLaunch(prAdapter->prGlueInfo)) ++ ASSERT(prAdapter->fgIsP2PRegistered); ++ ++ } else { ++ DBGLOG(P2P, TRACE, "prAdapter->fgIsP2PRegistered = %d\n", prAdapter->fgIsP2PRegistered); ++ ++ if (prAdapter->fgIsP2PRegistered) { ++ DBGLOG(P2P, INFO, "p2pRemove\n"); ++ p2pRemove(prAdapter->prGlueInfo); ++ } ++ ++ } ++ ++#if 0 ++ prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_NETDEV_REGISTER_T))); ++ ++ if (prP2pNetdevRegMsg == NULL) { ++ ASSERT(FALSE); ++ status = WLAN_STATUS_RESOURCES; ++ return status; ++ } ++ ++ prP2pNetdevRegMsg->rMsgHdr.eMsgId = MID_MNY_P2P_NET_DEV_REGISTER; ++ prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? TRUE : FALSE; ++ prP2pNetdevRegMsg->ucMode = (UINT_8) prSetP2P->u4Mode; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF); ++#endif ++ ++ return status; ++} ++#endif ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query build date code information from firmware ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ CMD_GET_BUILD_DATE_CODE rCmdGetBuildDateCode; ++ ++ DEBUGFUNC("wlanoidQueryBuildDateCode"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(UINT_8) * 16; ++ ++ if (u4QueryBufferLen < sizeof(UINT_8) * 16) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_BUILD_DATE_CODE, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventBuildDateCode, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_GET_BUILD_DATE_CODE), ++ (PUINT_8) &rCmdGetBuildDateCode, pvQueryBuffer, u4QueryBufferLen); ++ ++} /* end of wlanoidQueryBuildDateCode() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query BSS info from firmware ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ EVENT_AIS_BSS_INFO_T rCmdBSSInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); ++ ++ if (u4QueryBufferLen < sizeof(EVENT_AIS_BSS_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ kalMemZero(&rCmdBSSInfo, sizeof(EVENT_AIS_BSS_INFO_T)); ++ /* ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_BSS_INFO, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventGetBSSInfo, ++ nicOidCmdTimeoutCommon, ++ sizeof(P_EVENT_AIS_BSS_INFO_T), ++ (PUINT_8) &rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); ++ */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_BSS_INFO, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventGetBSSInfo, ++ nicOidCmdTimeoutCommon, ++ sizeof(EVENT_AIS_BSS_INFO_T), ++ (PUINT_8) & rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); ++ ++ return rStatus; ++} /* wlanoidSetWiFiWmmPsTest */ ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ ++#define CMD_WLS_BATCHING "WLS_BATCHING" ++ ++#define BATCHING_SET "SET" ++#define BATCHING_GET "GET" ++#define BATCHING_STOP "STOP" ++ ++#define PARAM_SCANFREQ "SCANFREQ" ++#define PARAM_MSCAN "MSCAN" ++#define PARAM_BESTN "BESTN" ++#define PARAM_CHANNEL "CHANNEL" ++#define PARAM_RTT "RTT" ++ ++WLAN_STATUS ++batchSetCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4WritenLen) ++{ ++ P_CHANNEL_INFO_T prRfChannelInfo; ++ CMD_BATCH_REQ_T rCmdBatchReq; ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ PCHAR head, p, p2; ++ UINT_32 tokens; ++ INT_32 scanfreq, mscan, bestn, rtt; ++ ++ DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", (PCHAR) pvSetBuffer, (UINT_32) u4SetBufferLen); ++ ++ if (!pu4WritenLen) ++ return -EINVAL; ++ *pu4WritenLen = 0; ++ ++ if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) { ++ DBGLOG(SCN, TRACE, "[BATCH] invalid len %u\n", (UINT_32) u4SetBufferLen); ++ return -EINVAL; ++ } ++ ++ head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1; ++ kalMemSet(&rCmdBatchReq, 0, sizeof(CMD_BATCH_REQ_T)); ++ ++ if (!kalStrnCmp(head, BATCHING_SET, kalStrLen(BATCHING_SET))) { ++ ++ DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n"); ++ ++ head += kalStrLen(BATCHING_SET) + 1; ++ ++ /* SCANFREQ, MSCAN, BESTN */ ++ tokens = kalSScanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", &scanfreq, &mscan, &bestn); ++ if (tokens != 3) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, SCANFREQ=%d MSCAN=%d BESTN=%d\n", ++ (UINT_32) tokens, scanfreq, mscan, bestn); ++ return -EINVAL; ++ } ++ /* RTT */ ++ p = kalStrStr(head, PARAM_RTT); ++ if (!p) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", head); ++ return -EINVAL; ++ } ++ tokens = kalSScanf(p, "RTT=%d", &rtt); ++ if (tokens != 1) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, rtt=%d\n", (UINT_32) tokens, rtt); ++ return -EINVAL; ++ } ++ /* CHANNEL */ ++ p = kalStrStr(head, PARAM_CHANNEL); ++ if (!p) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n"); ++ return -EINVAL; ++ } ++ head = p; ++ p = kalStrChr(head, '>'); ++ if (!p) { ++ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n"); ++ return -EINVAL; ++ } ++ /* else { ++ *p = '.'; // remove '>' because sscanf can not parse <%s> ++ }*/ ++ /*tokens = kalSScanf(head, "CHANNEL=<%s", c_channel); ++ if (tokens != 1) { ++ DBGLOG(SCN, TRACE, ("[BATCH] Parse fail: tokens=%d, CHANNEL=<%s>\n", ++ tokens, c_channel)); ++ return -EINVAL; ++ } */ ++ rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED; ++ rCmdBatchReq.ucChannelListNum = 0; ++ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; ++ p = head + kalStrLen(PARAM_CHANNEL) + 2; /* c_channel; */ ++ while ((p2 = kalStrSep((char **)&p, ",")) != NULL) { ++ if (p2 == NULL || *p2 == 0) ++ break; ++ if (*p2 == '\0') ++ continue; ++ if (*p2 == 'A') { ++ rCmdBatchReq.ucChannelType = ++ rCmdBatchReq.ucChannelType == ++ SCAN_CHANNEL_2G4 ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G; ++ } else if (*p2 == 'B') { ++ rCmdBatchReq.ucChannelType = ++ rCmdBatchReq.ucChannelType == ++ SCAN_CHANNEL_5G ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4; ++ } else { ++ ++ /* Translate Freq from MHz to channel number. */ ++ prRfChannelInfo->ucChannelNum = kalStrtol(p2, NULL, 0); ++ DBGLOG(SCN, TRACE, "Scanning Channel:%u, freq: %d\n", ++ (UINT_32) prRfChannelInfo->ucChannelNum, ++ (UINT_32) nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); ++ prRfChannelInfo->ucBand = prRfChannelInfo->ucChannelNum < 15 ? BAND_2G4 : BAND_5G; ++ ++ rCmdBatchReq.ucChannelListNum++; ++ if (rCmdBatchReq.ucChannelListNum >= 32) ++ break; ++ prRfChannelInfo++; ++ } ++ } ++ ++ /* set channel for test */ ++#if 0 ++ rCmdBatchReq.ucChannelType = 4; /* SCAN_CHANNEL_SPECIFIED; */ ++ rCmdBatchReq.ucChannelListNum = 0; ++ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; ++ for (i = 1; i <= 14; i++) { ++ ++ /* filter out some */ ++ if (i == 1 || i == 5 || i == 11) ++ continue; ++ ++ /* Translate Freq from MHz to channel number. */ ++ prRfChannelInfo->ucChannelNum = i; ++ DBGLOG(SCN, TRACE, "Scanning Channel:%d, freq: %d\n", ++ prRfChannelInfo->ucChannelNum, ++ nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); ++ prRfChannelInfo->ucBand = BAND_2G4; ++ ++ rCmdBatchReq.ucChannelListNum++; ++ prRfChannelInfo++; ++ } ++#endif ++#if 0 ++ rCmdBatchReq.ucChannelType = 0; /* SCAN_CHANNEL_FULL; */ ++#endif ++ ++ rCmdBatchReq.u4Scanfreq = scanfreq; ++ rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? CFG_BATCH_MAX_MSCAN : mscan; ++ rCmdBatchReq.ucBestn = bestn; ++ rCmdBatchReq.ucRtt = rtt; ++ DBGLOG(SCN, TRACE, "[BATCH] SCANFREQ=%u MSCAN=%u BESTN=%u RTT=%u\n", ++ (UINT_32) rCmdBatchReq.u4Scanfreq, ++ (UINT_32) rCmdBatchReq.ucMScan, ++ (UINT_32) rCmdBatchReq.ucBestn, (UINT_32) rCmdBatchReq.ucRtt; ++ ++ if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) { ++ DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n", ++ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? "FULL" : ++ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all"); ++ } else { ++ DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n"); ++ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; ++ for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; tokens++) { ++ DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n", ++ prRfChannelInfo->ucBand == BAND_2G4 ? "2.4G" : "5G", ++ prRfChannelInfo->ucChannelNum); ++ prRfChannelInfo++; ++ } ++ } ++ ++ rCmdBatchReq.ucSeqNum = 1; ++ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START; ++ ++ *pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", rCmdBatchReq.ucMScan); ++ ++ } else if (!kalStrnCmp(head, BATCHING_STOP, kalStrLen(BATCHING_STOP))) { ++ ++ DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n"); ++ ++ rCmdBatchReq.ucSeqNum = 1; ++ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP; ++ } else { ++ return -EINVAL; ++ } ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BATCH_REQ, ++ TRUE, FALSE, TRUE, NULL, NULL, sizeof(CMD_BATCH_REQ_T), (PUINT_8) &rCmdBatchReq, NULL, 0); ++ ++ /* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */ ++ /* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */ ++ ++ return rStatus; ++} ++ ++WLAN_STATUS ++batchGetCmd(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ CMD_BATCH_REQ_T rCmdBatchReq; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_EVENT_BATCH_RESULT_T prEventBatchResult; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pvQueryBuffer; ++ ++ DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%u) XXX\n", (UINT_32) prEventBatchResult->ucScanCount); ++ ++ *pu4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); ++ ++ rCmdBatchReq.ucSeqNum = 2; ++ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT; ++ rCmdBatchReq.ucMScan = prEventBatchResult->ucScanCount; /* Get which round result */ ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BATCH_REQ, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventBatchScanResult, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_BATCH_REQ_T), ++ (PUINT_8) &rCmdBatchReq, (PVOID) pvQueryBuffer, u4QueryBufferLen); ++ ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, pu4SetInfoLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ return batchGetCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen, pu4QueryInfoLen); ++ ++} /* end of wlanoidQueryBatchScanResult() */ ++ ++#endif /* CFG_SUPPORT_BATCH_SCAN */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request starting of schedule scan ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; ++ ++ DEBUGFUNC("wlanoidSetStartSchedScan()"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ ASSERT(pu4SetInfoLen); ++ *pu4SetInfoLen = 0; ++ ++ if (u4SetBufferLen != sizeof(PARAM_SCHED_SCAN_REQUEST)) { ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ return WLAN_STATUS_INVALID_DATA; ++ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED && ++ prAdapter->fgEnOnlineScan == FALSE) { ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) pvSetBuffer; ++ ++ if (scnFsmSchedScanRequest(prAdapter, ++ (UINT_8) (prSchedScanRequest->u4SsidNum), ++ prSchedScanRequest->arSsid, ++ prSchedScanRequest->u4IELength, ++ prSchedScanRequest->pucIE, prSchedScanRequest->u2ScanInterval) == TRUE) { ++ return WLAN_STATUS_SUCCESS; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request termination of schedule scan ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(prAdapter); ++ ++ /* ask SCN module to stop scan request */ ++ if (scnFsmSchedScanStopRequest(prAdapter) == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ else ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a periodically scan action ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_CMD_SET_PSCAN_ENABLE prCmdPscnAction; ++ P_SCAN_INFO_T prScanInfo; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ DBGLOG(SCN, TRACE, "wlanoidSetGSCNAction\n"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (u4SetBufferLen != sizeof(CMD_SET_PSCAN_ENABLE)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ else if (pvSetBuffer == NULL) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prCmdPscnAction = (P_CMD_SET_PSCAN_ENABLE) pvSetBuffer; ++ ++ if (prCmdPscnAction->ucPscanAct == ENABLE) { ++#if 0 ++ DBGLOG(OID, INFO, "set PCSN ENABLE\n"); ++ if (scnFsmPSCNAction(prAdapter, (UINT_8) (prCmdPscnAction->ucPscanAct)) == TRUE) { ++ ++ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); ++ return WLAN_STATUS_PENDING; ++ } ++ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); ++ return WLAN_STATUS_FAILURE; ++ ++#endif ++ scnPSCNFsm(prAdapter, PSCN_SCANNING, NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, TRUE); ++ } else if (prCmdPscnAction->ucPscanAct == DISABLE) { ++#if 0 ++ DBGLOG(OID, INFO, "disable PCSN\n"); ++ scnFsmPSCNAction(prAdapter, (UINT_8) DISABLE); ++ ++ DBGLOG(OID, TRACE, "set new PCSN\n"); ++ scnCombineParamsIntoPSCN(prAdapter, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE); ++ ++ DBGLOG(OID, INFO, "ENABLE or disable PCSN\n"); ++ if (!prScanInfo->fgPscnOnnning) { ++ DBGLOG(OID, INFO, "ENABLE PCSN\n"); ++ scnFsmPSCNAction(prAdapter, ENABLE); ++ } else { ++ DBGLOG(OID, INFO, "All PCSN is disabled...\n"); ++ } ++#endif ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE, FALSE); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a periodically scan action ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam; ++ /*UINT_8 i, j = 0;*/ ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam v1\n"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { ++ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(P_PARAM_WIFI_GSCAN_CMD_PARAMS))\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prCmdGscnParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; ++ /* KC-XXX memcpy(prCmdGscnParam, */ ++ /* (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer, */ ++ /* sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS) ); */ ++ DBGLOG(SCN, INFO, ++ "prCmdGscnParam : base_period[%u], max_ap_per_scan[%u] num_buckets[%u], report_threshold[%u]\n", ++ prCmdGscnParam->base_period, prCmdGscnParam->max_ap_per_scan, prCmdGscnParam->num_buckets, ++ prCmdGscnParam->report_threshold); ++#if 0 ++ for (i = 0; i < prCmdGscnParam->num_buckets; i++) { ++ ++ DBGLOG(OID, INFO, ++ "prCmdGscnParam->buckets : band[%u], bucket[%u] num_buckets[%u], period[%u] report_events[%u]\n", ++ prCmdGscnParam->buckets[i].band, prCmdGscnParam->buckets[i].bucket, ++ prCmdGscnParam->buckets[i].num_channels, prCmdGscnParam->buckets[i].period, ++ prCmdGscnParam->buckets[i].report_events)); ++ DBGLOG(OID, INFO, "prCmdGscnParam->buckets[%d] has channel: ", i); ++ for (j = 0; j < prCmdGscnParam->buckets[i].num_channels; j++) ++ DBGLOG(OID, INFO, " %d, ", prCmdGscnParam->buckets[i].channels[j].channel); ++ DBGLOG(OID, INFO, "\n"); ++ } ++#endif ++ if (scnSetGSCNParam(prAdapter, prCmdGscnParam) == TRUE) { ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); ++ return WLAN_STATUS_PENDING; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set configure gscan PARAMs ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS ++wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnScnConfigParam; ++ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; ++ ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAConfig v1\n"); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { ++ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer\n"); ++ prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; ++ memcpy(prCmdGscnScnConfigParam, (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer, ++ sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam assign prCmdGscnScnConfig\n"); ++ rCmdGscnScnConfig.u4BufferThreshold = prCmdGscnScnConfigParam->report_threshold; ++ rCmdGscnScnConfig.ucNumApPerScn = prCmdGscnScnConfigParam->max_ap_per_scan; ++ rCmdGscnScnConfig.u4NumScnToCache = prCmdGscnScnConfigParam->num_scans; ++ DBGLOG(SCN, INFO, " report_threshold %d report_threshold %d num_scans %d\n", ++ rCmdGscnScnConfig.u4BufferThreshold, ++ rCmdGscnScnConfig.ucNumApPerScn, rCmdGscnScnConfig.u4NumScnToCache); ++ if (scnFsmSetGSCNConfig(prAdapter, &rCmdGscnScnConfig) == TRUE) { ++ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); ++ return WLAN_STATUS_PENDING; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get a gscan result ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++* ++* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS prGetGscnScnResultParm; ++ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; ++ ++ DEBUGFUNC("wlanoidGetGSCNResult()"); ++ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult v1\n"); ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS)) { ++ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (pvSetBuffer == NULL) { ++ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ if (prAdapter->fgIsRadioOff) { ++ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_SUCCESS; ++ } ++ ++ prGetGscnScnResultParm = (P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) pvSetBuffer; ++ /* memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultParm, sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) ); */ ++ ++ rGetGscnScnResultCmd.u4Num = prGetGscnScnResultParm->get_num; ++ rGetGscnScnResultCmd.ucFlush = prGetGscnScnResultParm->flush; ++ rGetGscnScnResultCmd.ucVersion = PSCAN_VERSION; ++ kalMemZero(rGetGscnScnResultCmd.aucReserved, sizeof(rGetGscnScnResultCmd.aucReserved)); ++ ++ if (scnFsmGetGSCNResult(prAdapter, &rGetGscnScnResultCmd) == TRUE) { ++ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult --->scnFsmGetGSCNResult\n"); ++ return WLAN_STATUS_PENDING; ++ } else { ++ return WLAN_STATUS_FAILURE; ++ } ++ ++} ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by HS2.0 to set the assoc info, which is needed to add to ++* Association request frame while join HS2.0 AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_IE_HS20_INDICATION_T prHS20IndicationIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DEBUGFUNC("wlanoidSetHS20AssocInfo"); ++ DBGLOG(OID, LOUD, "\r\n"); ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pvSetBuffer; ++ ++ prAdapter->prGlueInfo->ucHotspotConfig = prHS20IndicationIe->ucHotspotConfig; ++ prAdapter->prGlueInfo->fgConnectHS20AP = TRUE; ++ ++ DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen); ++ ++ kalMemCopy(prAdapter->prGlueInfo->aucHS20AssocInfoIE, pvSetBuffer, u4SetBufferLen); ++ prAdapter->prGlueInfo->u2HS20AssocInfoIELen = (UINT_16) u4SetBufferLen; ++ DBGLOG(SEC, TRACE, "HS20 Assoc Info IE sz %u\n", u4SetBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WSC to set the assoc info, which is needed to add to ++* Association request frame while join WPS AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#if 0 ++ P_HS20_INFO_T prHS20Info = NULL; ++ P_IE_INTERWORKING_T prInterWorkingIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ ++ DEBUGFUNC("wlanoidSetInterworkingInfo"); ++ DBGLOG(OID, TRACE, "\r\n"); ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ prInterWorkingIe = (P_IE_INTERWORKING_T) pvSetBuffer; ++ ++ prHS20Info->ucAccessNetworkOptions = prInterWorkingIe->ucAccNetOpt; ++ prHS20Info->ucVenueGroup = prInterWorkingIe->ucVenueGroup; ++ prHS20Info->ucVenueType = prInterWorkingIe->ucVenueType; ++ COPY_MAC_ADDR(prHS20Info->aucHESSID, prInterWorkingIe->aucHESSID); ++ ++ DBGLOG(SEC, TRACE, "IW IE sz %ld\n", u4SetBufferLen); ++#endif ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called by WSC to set the Roaming Consortium IE info, which is needed to ++* add to Association request frame while join WPS AP. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++#if 0 ++ P_HS20_INFO_T prHS20Info = NULL; ++ P_PARAM_HS20_ROAMING_CONSORTIUM_INFO prRCInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ ++ /* DEBUGFUNC("wlanoidSetRoamingConsortiumInfo"); */ ++ /* DBGLOG(HS2, TRACE, ("\r\n")); */ ++ ++ if (u4SetBufferLen == 0) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ prRCInfo = (P_PARAM_HS20_ROAMING_CONSORTIUM_INFO) pvSetBuffer; ++ ++ kalMemCopy(&(prHS20Info->rRCInfo), prRCInfo, sizeof(PARAM_HS20_ROAMING_CONSORTIUM_INFO)); ++ ++ /* DBGLOG(HS2, TRACE, ("RoamingConsortium IE sz %ld\n", u4SetBufferLen)); */ ++#endif ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set_bssid_pool ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (u4SetBufferLen < sizeof(PARAM_HS20_SET_BSSID_POOL)) { ++ *pu4SetInfoLen = sizeof(PARAM_HS20_SET_BSSID_POOL); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, NETWORK_TYPE_AIS_INDEX); ++ ++ return rWlanStatus; ++} /* end of wlanoidSendHS20GASRequest() */ ++ ++#endif ++ ++#if CFG_SUPPORT_ROAMING_ENC ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the MAC address the NIC is currently using. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_ROAMING_INFO_T *prCmdRoamingInfo; ++ ++ DEBUGFUNC("wlanoidSetRoamingInfo"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(CMD_ROAMING_INFO_T); ++ ++ if (u4SetBufferLen < sizeof(CMD_ROAMING_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prCmdRoamingInfo = (CMD_ROAMING_INFO_T *) pvSetBuffer; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_ROAMING_INFO, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_ROAMING_INFO_T), (PUINT_8) prCmdRoamingInfo, NULL, 0); ++} ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set chip ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T prChipConfigInfo; ++ CMD_CHIP_CONFIG_T rCmdChipConfig; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE); ++ DEBUGFUNC("wlanoidSetChipConfig"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prChipConfigInfo = (P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T) pvSetBuffer; ++ kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); ++ ++ rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; ++ rCmdChipConfig.ucType = prChipConfigInfo->ucType; ++ rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; ++ rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; ++ if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { ++ DBGLOG(OID, INFO, "Chip config Msg Size %u is not valid (set)\n", rCmdChipConfig.u2MsgSize); ++ rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; ++ } ++ kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, rCmdChipConfig.u2MsgSize); ++ ++ DBGLOG(OID, TRACE, "rCmdChipConfig.aucCmd=%s\n", rCmdChipConfig.aucCmd); ++#if 1 ++ rWlanStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_CHIP_CONFIG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CHIP_CONFIG_T), ++ (PUINT_8) &rCmdChipConfig, pvSetBuffer, u4SetBufferLen); ++#endif ++ return rWlanStatus; ++} /* wlanoidSetChipConfig */ ++ ++WLAN_STATUS ++wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_CMD_WFD_DEBUG_MODE_INFO_T prCmdWfdDebugModeInfo; ++ ++ DEBUGFUNC("wlanoidSetWFDDebugMode"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(CMD_WFD_DEBUG_MODE_INFO_T); ++ ++ if (u4SetBufferLen < sizeof(CMD_WFD_DEBUG_MODE_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prCmdWfdDebugModeInfo = (CMD_WFD_DEBUG_MODE_INFO_T *) pvSetBuffer; ++ ++ DBGLOG(OID, INFO, "New WFD Debug: %d mode and period=0x%x\n", prCmdWfdDebugModeInfo->ucDebugMode, ++ prCmdWfdDebugModeInfo->u2PeriodInteval); ++ ++ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode = (UINT_8) prCmdWfdDebugModeInfo->ucDebugMode; ++ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.u2WfdSNShowPeiroid = ++ (UINT_16) prCmdWfdDebugModeInfo->u2PeriodInteval; ++ ++ return WLAN_STATUS_SUCCESS; ++} /*wlanoidSetWfdDebugMode */ ++ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to query the MAC address the NIC is currently using. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the ++* query buffer ++* \param[in] u4QueryBufLen The length of the query buffer ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_BUFFER_TOO_SHORT ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetTxRateInfo( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_RLM_INFO_T *prCmdTxRInfo; ++ ++ DEBUGFUNC("wlanoidSetTxRateInfo"); ++ DBGLOG(OID, LOUD, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(CMD_RLM_INFO_T); ++ ++ if (u4SetBufferLen < sizeof(CMD_RLM_INFO_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prCmdTxRInfo = (CMD_RLM_INFO_T *)pvSetBuffer; ++ ++ DBGLOG(OID, INFO, " command = %u %u %u %u %d %u %u\n", ++ prCmdTxRInfo->u4Version, ++ prCmdTxRInfo->fgIsErrRatioEnhanceApplied, ++ prCmdTxRInfo->ucErrRatio2LimitMinRate, ++ prCmdTxRInfo->ucMinLegacyRateIdx, ++ prCmdTxRInfo->cMinRssiThreshold, ++ prCmdTxRInfo->fgIsRtsApplied, ++ prCmdTxRInfo->ucRecoverTime)); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_TX_AR_ERR_CONFIG, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_RLM_INFO_T), ++ (PUINT_8)prCmdTxRInfo, ++ NULL, ++ 0 ++ ); ++} ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ ++WLAN_STATUS ++wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WIFI_SYSTEM_SUSPEND_CMD_T rSuspendCmd; ++ ++ if (!prAdapter || !pvSetBuffer) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ rSuspendCmd.fgIsSystemSuspend = *(PBOOLEAN)pvSetBuffer; ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_SYSTEM_SUSPEND, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(BOOLEAN), ++ (PUINT_8)&rSuspendCmd, ++ NULL, ++ 0); ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c +new file mode 100644 +index 000000000000..7ca7ee48922e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c +@@ -0,0 +1,1654 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/common/wlan_p2p.c#8 ++*/ ++ ++/*! \file wlan_bow.c ++ \brief This file contains the Wi-Fi Direct commands processing routines for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_p2p.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 24 2011 yuche.tsai ++ * NULL ++ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Update RSSI link quality of P2P Network query method. (Bug fix) ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support ++ * for service discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix Multicast Issue of P2P. ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * Support P2P ARP filter setting on early suspend/ late resume ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 17 2011 wh.su ++ * [WCXRP00000571] [MT6620 Wi-Fi] [Driver] Not check the p2p role during set key ++ * Skip the p2p role for adding broadcast key issue. ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * fixed compiling error while enable dbg. ++ * ++ * 03 08 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format ++ * issue[WCXRP00000509] [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. ++ * . ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 03 02 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix SD Request Query Length issue. ++ * ++ * 03 02 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Service Discovery Request. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Wlan OID related function. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Related wlanoid function. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Indication Related code. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Function. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ioctl implementations for P2P Service Discovery ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ++ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous ++ * and physically-continuous type to ease slab system pressure ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add subroutines for P2P to set multicast list. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * . ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * support wlanoidSetP2pPowerSaveProfile() in P2P ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * Support wlanoidSetNetworkAddress() for P2P ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++** ++*/ ++ ++/****************************************************************************** ++* C O M P I L E R F L A G S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************* ++*/ ++#include "precomp.h" ++#include "gl_p2p_ioctl.h" ++ ++/****************************************************************************** ++* C O N S T A N T S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* D A T A T Y P E S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P U B L I C D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* P R I V A T E D A T A ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* M A C R O S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************* ++*/ ++ ++/****************************************************************************** ++* F U N C T I O N S ++******************************************************************************* ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief command packet generation utility ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucCID Command ID ++* \param[in] fgSetQuery Set or Query ++* \param[in] fgNeedResp Need for response ++* \param[in] pfCmdDoneHandler Function pointer when command is done ++* \param[in] u4SetQueryInfoLen The length of the set/query buffer ++* \param[in] pucInfoBuffer Pointer to set/query buffer ++* ++* ++* \retval WLAN_STATUS_PENDING ++* \retval WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ASSERT(prGlueInfo); ++ ++ DEBUGFUNC("wlanoidSendSetQueryP2PCmd"); ++ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); ++ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); ++ ++ if (!prCmdInfo) { ++ DBGLOG(P2P, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = NETWORK_TYPE_P2P_INDEX; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); ++ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; ++ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; ++ prCmdInfo->fgIsOid = fgIsOid; ++ prCmdInfo->ucCID = ucCID; ++ prCmdInfo->fgSetQuery = fgSetQuery; ++ prCmdInfo->fgNeedResp = fgNeedResp; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; ++ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; ++ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) ++ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set a key to Wi-Fi Direct driver ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_802_11_KEY rCmdKey; ++ P_PARAM_KEY_T prNewKey; ++ ++ DEBUGFUNC("wlanoidSetAddP2PKey"); ++ DBGLOG(REQ, INFO, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; ++ ++ /* Verify the key structure length. */ ++ if (prNewKey->u4Length > u4SetBufferLen) { ++ DBGLOG(REQ, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", ++ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ /* Verify the key material length for key material buffer */ ++ else if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { ++ DBGLOG(REQ, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); ++ *pu4SetInfoLen = u4SetBufferLen; ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ /* Exception check */ ++ else if (prNewKey->u4KeyIndex & 0x0fffff00) ++ return WLAN_STATUS_INVALID_DATA; ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) { ++ return WLAN_STATUS_INVALID_DATA; ++ } else if (!(prNewKey->u4KeyLength == CCMP_KEY_LEN) && !(prNewKey->u4KeyLength == TKIP_KEY_LEN)) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ /* Exception check, pairwise key must with transmit bit enabled */ ++ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { ++ if (((prNewKey->u4KeyIndex & 0xff) != 0) || ++ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) ++ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) ++ && (prNewKey->arBSSID[5] == 0xff))) { ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* fill CMD_802_11_KEY */ ++ kalMemZero(&rCmdKey, sizeof(CMD_802_11_KEY)); ++ rCmdKey.ucAddRemove = 1; /* add */ ++ rCmdKey.ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; ++ rCmdKey.ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; ++ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ ++ rCmdKey.ucIsAuthenticator = 0; ++ } else { /* group owner */ ++ rCmdKey.ucIsAuthenticator = 1; ++ } ++ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prNewKey->arBSSID); ++ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; ++ if (prNewKey->u4KeyLength == CCMP_KEY_LEN) ++ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ ++ else if (prNewKey->u4KeyLength == TKIP_KEY_LEN) ++ rCmdKey.ucAlgorithmId = CIPHER_SUITE_TKIP; /* TKIP */ ++ rCmdKey.ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); ++ rCmdKey.ucKeyLen = (UINT_8) prNewKey->u4KeyLength; ++ kalMemCopy(rCmdKey.aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, rCmdKey.ucKeyLen); ++ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_ADD_REMOVE_KEY, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ NULL, ++ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to request Wi-Fi Direct driver to remove keys ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_802_11_KEY rCmdKey; ++ P_PARAM_REMOVE_KEY_T prRemovedKey; ++ ++ DEBUGFUNC("wlanoidSetRemoveP2PKey"); ++ ASSERT(prAdapter); ++ ++ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; ++ ++ /* Check bit 31: this bit should always 0 */ ++ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { ++ /* Bit 31 should not be set */ ++ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* Check bits 8 ~ 29 should always be 0 */ ++ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { ++ /* Bit 31 should not be set */ ++ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ /* There should not be any key operation for P2P Device */ ++ if (kalP2PGetRole(prAdapter->prGlueInfo) == 0) ++ ; /* return WLAN_STATUS_NOT_ACCEPTED; */ ++ ++ kalMemZero((PUINT_8) &rCmdKey, sizeof(CMD_802_11_KEY)); ++ ++ rCmdKey.ucAddRemove = 0; /* remove */ ++ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ ++ rCmdKey.ucIsAuthenticator = 0; ++ } else { /* group owner */ ++ rCmdKey.ucIsAuthenticator = 1; ++ } ++ kalMemCopy(rCmdKey.aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); ++ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; ++ rCmdKey.ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); ++ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_ADD_REMOVE_KEY, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ NULL, ++ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setting the IP address for pattern search function. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++* \return WLAN_STATUS_ADAPTER_NOT_READY ++* \return WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 i, j; ++ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; ++ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; ++ P_PARAM_NETWORK_ADDRESS prNetworkAddress; ++ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; ++ UINT_32 u4IpAddressCount, u4CmdSize; ++ ++ DEBUGFUNC("wlanoidSetP2pNetworkAddress"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 4; ++ ++ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ *pu4SetInfoLen = 0; ++ u4IpAddressCount = 0; ++ ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ u4IpAddressCount++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ /* construct payload of command packet */ ++ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + ++ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; ++ ++ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); ++ ++ if (prCmdNetworkAddressList == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ ++ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; ++ ++ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++ ++ j++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_IP_ADDRESS, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetIpAddress, ++ nicOidCmdTimeoutCommon, ++ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); ++ ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return rStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to query the power save profile. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuf A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryP2pPowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen != 0) { ++ ASSERT(pvQueryBuffer); ++ ++ *(PPARAM_POWER_MODE) pvQueryBuffer = ++ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile); ++ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the power save profile. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status; ++ PARAM_POWER_MODE ePowerMode; ++ ++ DEBUGFUNC("wlanoidSetP2pPowerSaveProfile"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); ++ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { ++ DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); ++ return WLAN_STATUS_INVALID_LENGTH; ++ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { ++ WARNLOG(("Invalid power mode %d\n", *(PPARAM_POWER_MODE) pvSetBuffer)); ++ return WLAN_STATUS_INVALID_DATA; ++ } ++ ++ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; ++ ++ if (prAdapter->fgEnCtiaPowerMode) { ++ if (ePowerMode == Param_PowerModeCAM) { ++ /*Todo:: Nothing*/ ++ /*Todo:: Nothing*/ ++ } else { ++ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ ++ ++ if (prAdapter->u4CtiaPowerMode == 0) { ++ /* force to keep in CAM mode */ ++ ePowerMode = Param_PowerModeCAM; ++ } else if (prAdapter->u4CtiaPowerMode == 1) { ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else if (prAdapter->u4CtiaPowerMode == 2) { ++ ePowerMode = Param_PowerModeFast_PSP; ++ } ++ } ++ } ++ ++ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_P2P_INDEX, ePowerMode, TRUE); ++ return status; ++} /* end of wlanoidSetP2pPowerSaveProfile() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the power save profile. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 i, j; ++ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; ++ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; ++ P_PARAM_NETWORK_ADDRESS prNetworkAddress; ++ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; ++ UINT_32 u4IpAddressCount, u4CmdSize; ++ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; ++ ++ DEBUGFUNC("wlanoidSetP2pSetNetworkAddress"); ++ DBGLOG(P2P, TRACE, "\n"); ++ DBGLOG(P2P, INFO, "wlanoidSetP2pSetNetworkAddress (%d)\n", (INT_16) u4SetBufferLen); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = 4; ++ ++ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ *pu4SetInfoLen = 0; ++ u4IpAddressCount = 0; ++ ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ u4IpAddressCount++; ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); ++ } ++ ++ /* construct payload of command packet */ ++ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + ++ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; ++ ++ if (u4IpAddressCount == 0) ++ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); ++ ++ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); ++ ++ if (prCmdNetworkAddressList == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ ++ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ ++ /* only to set IP address to FW once ARP filter is enabled */ ++ if (prAdapter->fgEnArpFilter) { ++ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; ++ prNetworkAddress = prNetworkAddressList->arAddress; ++ ++ DBGLOG(P2P, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); ++ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { ++ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && ++ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { ++ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; ++ ++ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, ++ &(prNetAddrIp->in_addr), sizeof(UINT_32)); ++ ++ j++; ++ ++ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; ++ DBGLOG(P2P, INFO, "prNetAddrIp->in_addr:%d:%d:%d:%d\n", ++ (UINT_8) pucBuf[0], (UINT_8) pucBuf[1], ++ (UINT_8) pucBuf[2], (UINT_8) pucBuf[3]); ++ } ++ ++ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + ++ (ULONG) (prNetworkAddress->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ } ++ ++ } else { ++ prCmdNetworkAddressList->ucAddressCount = 0; ++ } ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_IP_ADDRESS, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetIpAddress, ++ nicOidCmdTimeoutCommon, ++ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); ++ ++ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); ++ return rStatus; ++} /* end of wlanoidSetP2pSetNetworkAddress() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Multicast Address List. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ /* The data must be a multiple of the Ethernet address size. */ ++ if ((u4SetBufferLen % MAC_ADDR_LEN)) { ++ DBGLOG(REQ, WARN, "Invalid MC list length %u\n", u4SetBufferLen); ++ ++ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; ++ ++ return WLAN_STATUS_INVALID_LENGTH; ++ } ++ ++ *pu4SetInfoLen = u4SetBufferLen; ++ ++ /* Verify if we can support so many multicast addresses. */ ++ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { ++ DBGLOG(REQ, WARN, "Too many MC addresses\n"); ++ ++ return WLAN_STATUS_MULTICAST_FULL; ++ } ++ ++ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && ++ * pvSetBuffer == NULL to clear exist Multicast List. ++ */ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(REQ, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; ++ rCmdMacMcastAddr.ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); ++ ++ /* This CMD response is no need to complete the OID. Or the event would unsync. */ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, CMD_ID_MAC_MCAST_ADDR, TRUE, FALSE, FALSE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_MAC_MCAST_ADDR), ++ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); ++ ++} /* end of wlanoidSetP2PMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send GAS frame for P2P Service Discovery Request ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_REQUEST)) { ++ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_REQUEST); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++/* rWlanStatus = p2pFsmRunEventSDRequest(prAdapter, (P_PARAM_P2P_SEND_SD_REQUEST)pvSetBuffer); */ ++ ++ return rWlanStatus; ++} /* end of wlanoidSendP2PSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send GAS frame for P2P Service Discovery Response ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_RESPONSE)) { ++ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_RESPONSE); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++/* rWlanStatus = p2pFsmRunEventSDResponse(prAdapter, (P_PARAM_P2P_SEND_SD_RESPONSE)pvSetBuffer); */ ++ ++ return rWlanStatus; ++} /* end of wlanoidGetP2PSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get GAS frame for P2P Service Discovery Request ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ /*PUINT_8 pucPacketBuffer = NULL, pucTA = NULL;*/ ++/* PUINT_8 pucChannelNum = NULL; */ ++ /*PUINT_16 pu2PacketLength = NULL;*/ ++ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ ++ /*UINT_8 ucVersionNum = 0;*/ ++/* UINT_8 ucChannelNum = 0, ucSeqNum = 0; */ ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_REQUEST)) { ++ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_REQUEST); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ DBGLOG(P2P, TRACE, "Get Service Discovery Request\n"); ++#if 0 ++ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); ++ if (ucVersionNum == 0) { ++ P_PARAM_P2P_GET_SD_REQUEST prP2pGetSdReq = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; ++ ++ pucPacketBuffer = prP2pGetSdReq->aucPacketContent; ++ pu2PacketLength = &prP2pGetSdReq->u2PacketLength; ++ pucTA = &prP2pGetSdReq->rTransmitterAddr; ++ } else { ++ P_PARAM_P2P_GET_SD_REQUEST_EX prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST_EX) NULL; ++ ++ prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; ++ pucPacketBuffer = prP2pGetSdReqEx->aucPacketContent; ++ pu2PacketLength = &prP2pGetSdReqEx->u2PacketLength; ++ pucTA = &prP2pGetSdReqEx->rTransmitterAddr; ++ pucChannelNum = &prP2pGetSdReqEx->ucChannelNum; ++ ucSeqNum = prP2pGetSdReqEx->ucSeqNum; ++ } ++ ++ rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, ++ pucPacketBuffer, ++ (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_REQUEST)), ++ (PUINT_32) pu2PacketLength, pucChannelNum, ucSeqNum); ++#else ++ *pu4QueryInfoLen = 0; ++ return rWlanStatus; ++#endif ++ /* ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketBuffer; ++ ++ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); ++ ++ if (pu4QueryInfoLen) { ++ if (ucVersionNum == 0) ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST) + (*pu2PacketLength)); ++ else ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST_EX) + (*pu2PacketLength)); ++ ++ } ++ ++ return rWlanStatus; ++ */ ++} /* end of wlanoidGetP2PSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get GAS frame for P2P Service Discovery Response ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ ++ /* UINT_8 ucSeqNum = 0, */ ++ /*UINT_8 ucVersionNum = 0;*/ ++ /*PUINT_8 pucPacketContent = (PUINT_8) NULL, pucTA = (PUINT_8) NULL;*/ ++ /*PUINT_16 pu2PacketLength = (PUINT_16) NULL;*/ ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_RESPONSE)) { ++ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_RESPONSE); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ DBGLOG(P2P, TRACE, "Get Service Discovery Response\n"); ++ ++#if 0 ++ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); ++ if (ucVersionNum == 0) { ++ P_PARAM_P2P_GET_SD_RESPONSE prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_RESPONSE) NULL; ++ ++ prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; ++ pucPacketContent = prP2pGetSdRsp->aucPacketContent; ++ pucTA = &prP2pGetSdRsp->rTransmitterAddr; ++ pu2PacketLength = &prP2pGetSdRsp->u2PacketLength; ++ } else { ++ P_PARAM_P2P_GET_SD_RESPONSE_EX prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) NULL; ++ ++ prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) pvQueryBuffer; ++ pucPacketContent = prP2pGetSdRspEx->aucPacketContent; ++ pucTA = &prP2pGetSdRspEx->rTransmitterAddr; ++ pu2PacketLength = &prP2pGetSdRspEx->u2PacketLength; ++ ucSeqNum = prP2pGetSdRspEx->ucSeqNum; ++ } ++ ++/* rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, */ ++/* pucPacketContent, */ ++/* (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_RESPONSE)), */ ++/* (PUINT_32)pu2PacketLength, */ ++/* NULL, */ ++/* ucSeqNum); */ ++#else ++ *pu4QueryInfoLen = 0; ++ return rWlanStatus; ++#endif ++ /* ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketContent; ++ ++ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); ++ ++ if (pu4QueryInfoLen) { ++ if (ucVersionNum == 0) ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE) + *pu2PacketLength); ++ else ++ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE_EX) + *pu2PacketLength); ++ } ++ ++ return rWlanStatus; ++ */ ++} /* end of wlanoidGetP2PSDResponse() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to terminate P2P Service Discovery Phase ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_P2P_TERMINATE_SD_PHASE prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) NULL; ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ ++ do { ++ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) ++ break; ++ ++ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) ++ break; ++ ++ if (u4SetBufferLen < sizeof(PARAM_P2P_TERMINATE_SD_PHASE)) { ++ *pu4SetInfoLen = sizeof(PARAM_P2P_TERMINATE_SD_PHASE); ++ rWlanStatus = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++ ++ prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) pvSetBuffer; ++ ++ if (EQUAL_MAC_ADDR(prP2pTerminateSD->rPeerAddr, aucNullAddr)) { ++ DBGLOG(P2P, TRACE, "Service Discovery Version 2.0\n"); ++/* p2pFuncSetVersionNumOfSD(prAdapter, 2); */ ++ } ++ /* rWlanStatus = p2pFsmRunEventSDAbort(prAdapter); */ ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* end of wlanoidSetP2PTerminateSDPhase() */ ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (u4SetBufferLen) ++ ASSERT(pvSetBuffer); ++ ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SEC_CHECK, ++ FALSE, ++ TRUE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ u4SetBufferLen, (PUINT_8) pvSetBuffer, pvSetBuffer, u4SetBufferLen); ++ ++} /* end of wlanoidSetSecCheckRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of ++* the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++* \retval WLAN_STATUS_MULTICAST_FULL ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ /* P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL; */ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ if (u4QueryBufferLen > 256) ++ u4QueryBufferLen = 256; ++ ++ *pu4QueryInfoLen = u4QueryBufferLen; ++ ++#if DBG ++ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); ++#endif ++ kalMemCopy((PUINT_8) (pvQueryBuffer + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer)), ++ prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); ++ ++ return rWlanStatus; ++} /* end of wlanoidGetSecCheckResponse() */ ++#endif ++ ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; ++ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; ++ ++ DEBUGFUNC("wlanoidSetNoaParam"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); ++ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; ++ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; ++ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; ++ ++#if 0 ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); ++#else ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); ++ ++#endif ++ ++} ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; ++ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; ++ ++ DEBUGFUNC("wlanoidSetOppPsParam"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; ++ ++#if 0 ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_OPPPS_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); ++#else ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_NOA_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); ++ ++#endif ++ ++} ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; ++ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("wlanoidSetUApsdParam"); ++ DBGLOG(P2P, TRACE, "\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); ++ ++ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvSetBuffer); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ ++ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; ++ ++ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); ++ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; ++ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; ++ ++ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; ++ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; ++ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; ++ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; ++ prPmProfSetupInfo->ucBmpDeliveryAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ prPmProfSetupInfo->ucBmpTriggerAC = ++ ((prUapsdParam->fgEnAPSD_AcBe << 0) | ++ (prUapsdParam->fgEnAPSD_AcBk << 1) | ++ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); ++ ++ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; ++ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; ++ ++#if 0 ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_UAPSD_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); ++#else ++ return wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_UAPSD_PARAM, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), ++ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); ++ ++#endif ++} ++ ++WLAN_STATUS ++wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++/* PUINT_8 pucOpChnl = (PUINT_8)pvQueryBuffer; */ ++ ++ do { ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ if (u4QueryBufferLen < sizeof(UINT_8)) { ++ *pu4QueryInfoLen = sizeof(UINT_8); ++ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++#if 0 ++ if (!p2pFuncGetCurrentOpChnl(prAdapter, pucOpChnl)) { ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++#else ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++#endif ++ /* ++ *pu4QueryInfoLen = sizeof(UINT_8); ++ rResult = WLAN_STATUS_SUCCESS; ++ */ ++ ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pOpChannel */ ++ ++WLAN_STATUS ++wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++/* PUINT_8 pucVersionNum = (PUINT_8)pvQueryBuffer; */ ++ ++ do { ++ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) ++ break; ++ ++ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) ++ break; ++ ++ if (u4QueryBufferLen < sizeof(UINT_8)) { ++ *pu4QueryInfoLen = sizeof(UINT_8); ++ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidQueryP2pVersion */ ++ ++WLAN_STATUS ++wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; ++ UINT_8 ucVersionNum; ++ ++ do { ++ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) { ++ ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) { ++ rResult = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ *pu4SetInfoLen = sizeof(UINT_8); ++ ++ if (u4SetBufferLen < sizeof(UINT_8)) { ++ rResult = WLAN_STATUS_INVALID_LENGTH; ++ break; ++ } ++ ++ ucVersionNum = *((PUINT_8) pvSetBuffer); ++ ++ rResult = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rResult; ++} /* wlanoidSetP2pSupplicantVersion */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set the WPS mode. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS status; ++ UINT_32 u4IsWPSmode = 0; ++ ++ DEBUGFUNC("wlanoidSetP2pWPSmode"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4SetInfoLen); ++ ++ if (pvSetBuffer) ++ u4IsWPSmode = *(PUINT_32) pvSetBuffer; ++ else ++ u4IsWPSmode = 0; ++ ++ if (u4IsWPSmode) ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 1; ++ else ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 0; ++ ++ status = nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ return status; ++} /* end of wlanoidSetP2pWPSmode() */ ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++WLAN_STATUS ++wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ DEBUGFUNC("wlanoidQueryP2pRssi"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4QueryInfoLen); ++ if (u4QueryBufferLen) ++ ASSERT(pvQueryBuffer); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ /* Check for query buffer length */ ++ if (u4QueryBufferLen < *pu4QueryInfoLen) { ++ DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen); ++ return WLAN_STATUS_BUFFER_TOO_SHORT; ++ } ++ ++ if (prAdapter->fgIsP2pLinkQualityValid == TRUE && ++ (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { ++ PARAM_RSSI rRssi; ++ ++ rRssi = (PARAM_RSSI) prAdapter->rP2pLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ ++ ++ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ ++ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); ++ return WLAN_STATUS_SUCCESS; ++ } ++#ifdef LINUX ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, ++ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); ++#else ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_LINK_QUALITY, ++ FALSE, ++ TRUE, ++ TRUE, ++ nicCmdEventQueryLinkQuality, ++ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); ++ ++#endif ++} /* wlanoidQueryP2pRssi */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h +new file mode 100644 +index 000000000000..89de18c89c1c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h +@@ -0,0 +1,238 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/CFG_Wifi_File.h#1 ++*/ ++ ++/*! \file CFG_Wifi_File.h ++ \brief Collection of NVRAM structure used for YuSu project ++ ++ In this file we collect all compiler flags and detail the driver behavior if ++ enable/disable such switch or adjust numeric parameters. ++*/ ++ ++/* ++** Log: CFG_Wifi_File.h ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 08 09 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * update NVRAM data structure definition. ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition ++ * follow-up for CMD_5G_PWR_OFFSET_T definition change ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++*/ ++ ++#ifndef _CFG_WIFI_FILE_H ++#define _CFG_WIFI_FILE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++/* duplicated from nic_cmd_event.h to avoid header dependency */ ++typedef struct _TX_PWR_PARAM_T { ++ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ ++ INT_8 acReserved[3]; /* form MT6628 acReserved[0]=cTxPwr2G4Dsss */ ++ INT_8 cTxPwr2G4OFDM_BPSK; ++ INT_8 cTxPwr2G4OFDM_QPSK; ++ INT_8 cTxPwr2G4OFDM_16QAM; ++ INT_8 cTxPwr2G4OFDM_Reserved; ++ INT_8 cTxPwr2G4OFDM_48Mbps; ++ INT_8 cTxPwr2G4OFDM_54Mbps; ++ ++ INT_8 cTxPwr2G4HT20_BPSK; ++ INT_8 cTxPwr2G4HT20_QPSK; ++ INT_8 cTxPwr2G4HT20_16QAM; ++ INT_8 cTxPwr2G4HT20_MCS5; ++ INT_8 cTxPwr2G4HT20_MCS6; ++ INT_8 cTxPwr2G4HT20_MCS7; ++ ++ INT_8 cTxPwr2G4HT40_BPSK; ++ INT_8 cTxPwr2G4HT40_QPSK; ++ INT_8 cTxPwr2G4HT40_16QAM; ++ INT_8 cTxPwr2G4HT40_MCS5; ++ INT_8 cTxPwr2G4HT40_MCS6; ++ INT_8 cTxPwr2G4HT40_MCS7; ++ ++ INT_8 cTxPwr5GOFDM_BPSK; ++ INT_8 cTxPwr5GOFDM_QPSK; ++ INT_8 cTxPwr5GOFDM_16QAM; ++ INT_8 cTxPwr5GOFDM_Reserved; ++ INT_8 cTxPwr5GOFDM_48Mbps; ++ INT_8 cTxPwr5GOFDM_54Mbps; ++ ++ INT_8 cTxPwr5GHT20_BPSK; ++ INT_8 cTxPwr5GHT20_QPSK; ++ INT_8 cTxPwr5GHT20_16QAM; ++ INT_8 cTxPwr5GHT20_MCS5; ++ INT_8 cTxPwr5GHT20_MCS6; ++ INT_8 cTxPwr5GHT20_MCS7; ++ ++ INT_8 cTxPwr5GHT40_BPSK; ++ INT_8 cTxPwr5GHT40_QPSK; ++ INT_8 cTxPwr5GHT40_16QAM; ++ INT_8 cTxPwr5GHT40_MCS5; ++ INT_8 cTxPwr5GHT40_MCS6; ++ INT_8 cTxPwr5GHT40_MCS7; ++} TX_PWR_PARAM_T, *P_TX_PWR_PARAM_T; ++ ++typedef struct _PWR_5G_OFFSET_T { ++ INT_8 cOffsetBand0; /* 4.915-4.980G */ ++ INT_8 cOffsetBand1; /* 5.000-5.080G */ ++ INT_8 cOffsetBand2; /* 5.160-5.180G */ ++ INT_8 cOffsetBand3; /* 5.200-5.280G */ ++ INT_8 cOffsetBand4; /* 5.300-5.340G */ ++ INT_8 cOffsetBand5; /* 5.500-5.580G */ ++ INT_8 cOffsetBand6; /* 5.600-5.680G */ ++ INT_8 cOffsetBand7; /* 5.700-5.825G */ ++} PWR_5G_OFFSET_T, *P_PWR_5G_OFFSET_T; ++ ++typedef struct _PWR_PARAM_T { ++ UINT_32 au4Data[28]; ++ UINT_32 u4RefValue1; ++ UINT_32 u4RefValue2; ++} PWR_PARAM_T, *P_PWR_PARAM_T; ++ ++typedef struct _MT6620_CFG_PARAM_STRUCT { ++ /* 256 bytes of MP data */ ++ UINT_16 u2Part1OwnVersion; ++ UINT_16 u2Part1PeerVersion; ++ UINT_8 aucMacAddress[6]; ++ UINT_8 aucCountryCode[2]; ++ TX_PWR_PARAM_T rTxPwr; ++ UINT_8 aucEFUSE[144]; ++ UINT_8 ucTxPwrValid; ++ UINT_8 ucSupport5GBand; ++ UINT_8 fg2G4BandEdgePwrUsed; ++ INT_8 cBandEdgeMaxPwrCCK; ++ INT_8 cBandEdgeMaxPwrOFDM20; ++ INT_8 cBandEdgeMaxPwrOFDM40; ++ ++ UINT_8 ucRegChannelListMap; ++ UINT_8 ucRegChannelListIndex; ++ UINT_8 aucRegSubbandInfo[36]; ++ ++ UINT_8 aucReserved2[256 - 240]; ++ ++ /* 256 bytes of function data */ ++ UINT_16 u2Part2OwnVersion; ++ UINT_16 u2Part2PeerVersion; ++ UINT_8 uc2G4BwFixed20M; ++ UINT_8 uc5GBwFixed20M; ++ UINT_8 ucEnable5GBand; ++ UINT_8 aucPreTailReserved; ++ UINT_8 uc2GRssiCompensation; ++ UINT_8 uc5GRssiCompensation; ++ UINT_8 fgRssiCompensationValidbit; ++ UINT_8 ucRxAntennanumber; ++ UINT_8 aucTailReserved[256 - 12]; ++} MT6620_CFG_PARAM_STRUCT, *P_MT6620_CFG_PARAM_STRUCT, WIFI_CFG_PARAM_STRUCT, *P_WIFI_CFG_PARAM_STRUCT; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#ifndef DATA_STRUCT_INSPECTING_ASSERT ++#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ ++{ \ ++ switch (0) {case 0: case (expr): default:; } \ ++} ++#endif ++ ++#define CFG_FILE_WIFI_REC_SIZE sizeof(WIFI_CFG_PARAM_STRUCT) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* We don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this to guarantee the same member order in different structures ++ * to simply handling effort in some functions. ++ */ ++static inline VOID nvramOffsetCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion) == 256); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(WIFI_CFG_PARAM_STRUCT) == 512); ++ ++ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) & 0x0001) == 0); ++ ++ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) & 0x0001) == 0); ++} ++#endif ++ ++#endif /* _CFG_WIFI_FILE_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h +new file mode 100644 +index 000000000000..a52053d5752d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h +@@ -0,0 +1,1628 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/config.h#2 ++*/ ++ ++/*! \file "config.h" ++ \brief This file includes the various configurable parameters for customers ++ ++ This file ncludes the configurable parameters except the parameters indicate the turning-on/off of some features ++*/ ++ ++/* ++** Log: config.h ++ * ++ * 07 13 2012 cp.wu ++ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for ++ * termination after SDIO error has happened ++ * [driver domain] add force reset by host-to-device interrupt mechanism ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 06 05 2012 tsaiyuan.hsu ++ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" ++ * resolve build waring for "WNM_UNIT_TEST not defined".. ++ * ++ * 06 04 2012 cp.wu ++ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development ++ * discussed with WH, privacy bit in associate response is not necessary to be checked, ++ * and identified as association failure when mismatching with beacon/probe response ++ * ++ * 05 11 2012 cp.wu ++ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience ++ * show MAC address & source while initiliazation ++ * ++ * 04 20 2012 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * correct macro ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ * ++ * 03 29 2012 eason.tsai ++ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define ++ * add conditional define. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Enable CFG80211 Support. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 11 23 2011 cp.wu ++ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection ++ * add compile option to disable beacon content change detection. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 10 28 2011 cp.wu ++ * [MT6620 Wi-Fi][Win32 Driver] Enable 5GHz support as default ++ * enable 5GHz as default for DaVinci trunk and V2.1 driver release . ++ * ++ * 10 18 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * surpress compiler warning for MT6628 build ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * enable divided firmware downloading. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 10 03 2011 cp.wu ++ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware downloading aggregated path. ++ * ++ * 09 28 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * enlarge window size only by 4. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. ++ * ++ * 08 12 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. ++ * ++ * 08 09 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS definition for MT6620. ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Refine compile flag. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Add wifi direct connection enhancement method I, II & VI. ++ * ++ * 06 24 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * increase RX buffer number to have a 2:1 ping-pong ratio ++ * ++ * 06 23 2011 eddie.chen ++ * [WCXRP00000810] [MT5931][DRV/FW] Adjust TxRx Buffer number and Rx buffer size ++ * 1. Different TX RX buffer ++ * 2. Enlarge RX buffer and increase the number 8->11 ++ * 3. Separate the WINSZIE and RX buffer number ++ * 4. Fix RX maximum size in MAC ++ * ++ * 06 20 2011 terry.wu ++ * NULL ++ * Add BoW Rate Limitation. ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * . ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * Add BoW 11N support. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Add compile flag for persistent group support. ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Limit AIS to fixed channel same with BOW ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * Enable RX STBC capability ++ * ++ * 04 11 2011 george.huang ++ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF ++ * . ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 04 08 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. correction: RX aggregation is not limited to SDIO but for all host interface options ++ * 2. add forward declarations for DBG-only symbols ++ * ++ * 04 06 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port ++ * 2. update perm_addr as well for MAC address ++ * 3. not calling check_mem_region() anymore for eHPI ++ * 4. correct MSC_CS macro for 0-based notation ++ * ++ * 04 01 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface ++ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR ++ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with ++ * user space process for RESET_START and RESET_END events ++ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 18 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the Anti_piracy check at driver . ++ * ++ * 03 17 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * enable roaming feature. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one ++ * to reduce physically continuous memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 03 01 2011 george.huang ++ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames ++ * Fix compile issue ++ * ++ * 02 25 2011 george.huang ++ * [WCXRP00000497] [MT6620 Wi-Fi][FW] Change default UAPSD AC assignment ++ * Assign all AC default to be U-APSD enabled. ++ * ++ * 02 14 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * Let the privacy check at hotspot mode default enable. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 02 08 2011 cp.wu ++ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number ++ * change version number to v1.2.0.0 for preparing v1.2 software package release. ++ * ++ * 02 01 2011 yarco.yang ++ * [WCXRP00000417] [MT6620 Driver] Change CFG_HANDLE_IST_IN_SDIO_CALLBACK from 1 to 0 for Interoperability ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 19 2011 wh.su ++ * [WCXRP00000370] [MT6620 Wi-Fi][Driver] Disable Rx RDG for workaround pre-N ccmp issue ++ * Not announce support Rx RDG for wokaround pre-N ccmp construct AAD issue.. ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * Add Stress test ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause ++ * hardware header translation needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW only for Linux. ++ * ++ * 01 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Enable BOW and 4 physical links. ++ * ++ * 01 08 2011 yuche.tsai ++ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, ++ * but the SSID length is still invalid. ++ * Modify CFG_SLT_SUPPORT default value. ++ * ++ * 01 08 2011 yuche.tsai ++ * [WCXRP00000341] [MT6620][SLT] Create Branch for SLT SW. ++ * Update configure flag. ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 15 2010 yuche.tsai ++ * NULL ++ * Update SLT Descriptor number configure in driver. ++ * ++ * 12 13 2010 chinglan.wang ++ * NULL ++ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. ++ * ++ * 11 23 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB ++ * Enable PM function by default ++ * ++ * 11 15 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * use config.mk WAPI config define. ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * use the config.mk define. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add option for enable/disable TX PWR gain adjustment (default: off) ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function ++ * enable the WAPI compiling flag as default ++ * ++ * 10 19 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android ++ * Add a define CFG_TEST_ANDROID_DIRECT_GO compiling flag ++ * ++ * 10 08 2010 cm.chang ++ * NULL ++ * Remove unused compiling flags (TX_RDG and TX_SGI) ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 05 2010 yarco.yang ++ * [WCXRP00000082] [MT6620 Wi-Fi][Driver]High throughput performance tuning ++ * Change CFG_IST_LOOP_COUNT from 2 to 1 to reduce unnecessary SDIO bus access ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE ++ * ++ * 09 20 2010 cm.chang ++ * NULL ++ * Disable RX STBC by BB HEC based on MT6620E1_PHY_BUG v05.docx ++ * ++ * 09 17 2010 chinglan.wang ++ * NULL ++ * Add performance test option ++ * ++ * 09 10 2010 chinglan.wang ++ * NULL ++ * Modify for Software Migration Phase 2.10 for E2 FPGA ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a CFG for max common IE buffer size. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * restore configuration as before. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 chinglan.wang ++ * NULL ++ * Enable the MT6620_FPGA_BWCS value. ++ * ++ * 08 30 2010 chinglan.wang ++ * NULL ++ * Disable the FW encryption. ++ * ++ * 08 27 2010 chinglan.wang ++ * NULL ++ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add AT GO test configure mode under WinXP. ++ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add option for enabling AIS 5GHz scan ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cp.wu ++ * NULL ++ * 1) initialize variable for enabling short premable/short time slot. ++ * 2) add compile option for disabling online scan ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Disable BOW Test. ++ * ++ * 08 23 2010 jeffrey.chang ++ * NULL ++ * fix config.h typo ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 21 2010 jeffrey.chang ++ * NULL ++ * 1) add sdio two setting ++ * 2) bug fix of sdio glue ++ * ++ * 08 09 2010 wh.su ++ * NULL ++ * let the firmware download default enabled. ++ * ++ * 08 07 2010 wh.su ++ * NULL ++ * adding the privacy related code for P2P network ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Add a configure flag for P2P unitest. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) enable Ad-Hoc ++ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Add for SLT support. ++ * ++ * 07 16 2010 cp.wu ++ * ++ * remove work-around in case SCN is not available. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor ++ * underflow under concurrent network operation ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * for first connection, if connecting failed do not enter into scan state. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add SCN compilation option. ++ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * set default compiling flag for security disable. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add config option for cfg80211. ++ * ++ * 05 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * set ATIMwindow default value to zero. ++ * ++ * 05 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add option for FPGA_BWCS & FPGA_V5 ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) enable CMD/EVENT ver 0.9 definition. ++ * 2) abandon use of ENUM_MEDIA_STATE ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add CFG_STARTUP_DEBUG for debugging starting up issue. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change firmware name to WIFI_RAM_CODE. ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * disable bt-over-wifi configuration, turn it on after firmware finished implementation ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * re-enable power management ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * enable TCP/IP checksum offloading by default. ++ * ++ * 04 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * set CFG_ENABLE_FULL_PM to 1 as default to ++ * 1) acquire own before hardware access ++ * 2) set own back after hardware access ++ * ++ * 04 15 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * change firmware name ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver ++ * disable RX-enhanced response temporally, it seems the CQ is not resolved yet. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver ++ * re-enable RX enhanced mode as WPD00003827 is resolved. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * turn off RX_ENHANCE mode by default. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) eliminate unused definitions ++ * * 2) ready bit will be polled for limited iteration ++ * ++ * 04 02 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * firmware download: Linux uses different firmware path ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use WIFI_TCM_ALWAYS_ON as firmware image ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * firmware download load address & start address are now configured from config.h ++ * * due to the different configurations on FPGA and ASIC ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add options for full PM support. ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * turn on FW-DOWNLOAD as default for release. ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * build up basic data structure and definitions to support BT-over-WiFi ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 05 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * change CFG_NUM_OF_QM_RX_PKT_NUM to 120 ++ * ++ * 03 04 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * . ++ * ++ * 03 04 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * increase RX buffer number to avoid RX buffer starvation. ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Changed the number of STA_RECs to 20 ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. add logic for firmware download ++ * * 2. firmware image filename and start/load address are now retrieved from registry ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * and result is retrieved by get ATInfo instead ++ * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-16 22:12:28 GMT mtk02752 ++** enable interrupt enhanced response, TX/RX Aggregation as default ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:38:43 GMT mtk02752 ++** eliminate compile options which are obsolete or for emulation purpose ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 13:56:26 GMT MTK02468 ++** Added RX buffer reordering configurations ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-12-04 12:09:09 GMT mtk02752 ++** once enhanced intr/rx response is taken, RX must be access in aggregated basis ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 17:54:50 GMT mtk02752 ++** correct a typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:47 GMT mtk01084 ++** add defines ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:33:37 GMT mtk02752 ++** add coalescing buffer definition for SD1_SD3_DATAPATH_INTEGRATION ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 20:32:40 GMT mtk02752 ++** add CFG_TX_MAX_PKT_NUM for limiting queued TX packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 13:34:44 GMT mtk02752 ++** add SD1_SD3_DATAPATH_INTEGRATION define for source control ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 13:54:11 GMT mtk01084 ++** enable INT enhance mode by default ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-30 18:17:14 GMT mtk01084 ++** add new define ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-10-29 19:47:36 GMT mtk01084 ++** not use HIF loopback mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-13 21:58:33 GMT mtk01084 ++** update for new macro define ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-09-09 17:26:08 GMT mtk01084 ++** add CFG_TEST_WITH_MT5921 ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:02:30 GMT mtk01426 ++** Update CFG_RX_COALESCING_BUFFER_SIZE ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-21 09:35:51 GMT mtk01461 ++** Add CFG_TX_DBG_MGT_BUF to debug MGMT Buffer depth ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:52:21 GMT mtk01426 ++** Add OOB_DATA_PRE_FIXED_LEN define ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-08 16:51:08 GMT mtk01084 ++** update for FW download part ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:33:37 GMT mtk01461 ++** Add SW pre test flag CFG_HIF_LOOPBACK_PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 00:29:18 GMT mtk01461 ++** Fix CFG_COALESCING_BUFFER_SIZE if enable the CFG_TX_FRAGMENT ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-18 20:58:34 GMT mtk01426 ++** Add CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-17 20:17:36 GMT mtk01426 ++** Add CMD/Response related configure ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:21 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:21 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _CONFIG_H ++#define _CONFIG_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#ifdef MT6620 ++#undef MT6620 ++#endif ++ ++#ifndef MT6628 ++#define MT6628 ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* 2 Flags for OS capability */ ++ ++#define MTK_WCN_SINGLE_MODULE 0 /* 1: without WMT */ ++ ++#ifdef LINUX ++#ifdef CONFIG_X86 ++#define MTK_WCN_HIF_SDIO 0 ++#else ++#define MTK_WCN_HIF_SDIO 0 /* samp */ ++#endif ++#else ++#define MTK_WCN_HIF_SDIO 0 ++#endif ++ ++#if (CFG_SUPPORT_AEE == 1) ++#define CFG_ENABLE_AEE_MSG 1 ++#else ++#define CFG_ENABLE_AEE_MSG 0 ++#endif ++ ++#if CFG_ENABLE_AEE_MSG ++#include ++#endif ++ ++/* 2 Flags for Driver Features */ ++#define CFG_TX_FRAGMENT 1 /*!< 1: Enable TX fragmentation ++ 0: Disable */ ++#define CFG_SUPPORT_PERFORMANCE_TEST 0 /*Only for performance Test */ ++ ++#define CFG_COUNTRY_CODE NULL /* "US" */ ++ ++#ifndef LINUX ++#define CFG_FW_FILENAME L"WIFI_RAM_CODE" ++#define CFG_FW_FILENAME_E6 L"WIFI_RAM_CODE_E6" ++#else ++#define CFG_FW_FILENAME "WIFI_RAM_CODE" ++#endif ++#ifndef LINUX ++#define CFG_SUPPORT_CFG_FILE 0 ++#else ++#define CFG_SUPPORT_CFG_FILE 1 ++#endif ++ ++#define CFG_SUPPORT_CE_FCC_TXPWR_LIMIT 0 /* Support CE FCC Tx Power limit */ ++ ++#define CFG_SUPPORT_802_11D 1 /*!< 1(default): Enable 802.11d ++ 0: Disable */ ++ ++#define CFG_SUPPORT_RRM 0 /* Radio Reasource Measurement (802.11k) */ ++#define CFG_SUPPORT_DFS 1 /* DFS (802.11h) */ ++ ++#if (CFG_SUPPORT_DFS == 1) /* Add by Enlai */ ++#define CFG_SUPPORT_QUIET 1 /* Quiet (802.11h) */ ++#define CFG_SUPPORT_SPEC_MGMT 1 /* Spectrum Management (802.11h): TPC and DFS */ ++#else ++#define CFG_SUPPORT_QUIET 0 /* Quiet (802.11h) */ ++#define CFG_SUPPORT_SPEC_MGMT 0 /* Spectrum Management (802.11h): TPC and DFS */ ++#endif ++ ++#define CFG_SUPPORT_RX_RDG 0 /* 11n feature. RX RDG capability */ ++#define CFG_SUPPORT_MFB 0 /* 802.11n MCS Feedback responder */ ++#define CFG_SUPPORT_RX_STBC 1 /* 802.11n RX STBC (1SS) */ ++#define CFG_SUPPORT_RX_SGI 1 /* 802.11n RX short GI for both 20M and 40M BW */ ++#define CFG_SUPPORT_RX_HT_GF 1 /* 802.11n RX HT green-field capability */ ++ ++#define CFG_SUPPORT_ROAMING_ENC 0 /* enahnced roaming */ ++ ++#define CFG_SUPPORT_TDLS 1 /* IEEE802.11z TDLS */ ++#define CFG_SUPPORT_TDLS_DBG 0 /* TDLS debug */ ++#define CFG_SUPPORT_STATISTICS 1 ++#define CFG_SUPPORT_DBG_POWERMODE 1 /* for debugging power always active mode */ ++ ++#define CFG_SUPPORT_GSCN 1 ++ ++#define CFG_SUPPORT_TXR_ENC 0 /* enhanced tx rate switch */ ++ ++#define CFG_SUPPORT_PERSIST_NETDEV 0 /* create NETDEV when system bootup */ ++ ++#define CFG_FORCE_USE_20BW 1 ++/*------------------------------------------------------------------------------ ++ * SLT Option ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SLT_SUPPORT 0 ++ ++#define MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE 0 ++ ++#if defined(MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE) ++#define CFG_AUTO_CHANNEL_SEL_SUPPORT 1 ++#else ++#define CFG_AUTO_CHANNEL_SEL_SUPPORT 0 ++#endif ++ ++#ifdef NDIS60_MINIPORT ++#define CFG_NATIVE_802_11 1 ++ ++#define CFG_TX_MAX_PKT_SIZE 2304 ++#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 /* !< 1: Enable TCP/IP header checksum offload ++ 0: Disable */ ++#define CFG_TCP_IP_CHKSUM_OFFLOAD 0 ++#define CFG_WHQL_DOT11_STATISTICS 1 ++#define CFG_WHQL_ADD_REMOVE_KEY 1 ++#define CFG_WHQL_CUSTOM_IE 1 ++#define CFG_WHQL_SAFE_MODE_ENABLED 1 ++ ++#else ++#define CFG_TCP_IP_CHKSUM_OFFLOAD 1 /* !< 1: Enable TCP/IP header checksum offload ++ 0: Disable */ ++#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 ++#define CFG_TX_MAX_PKT_SIZE 1600 ++#define CFG_NATIVE_802_11 0 ++#endif ++ ++/* 2 Flags for Driver Parameters */ ++/*------------------------------------------------------------------------------ ++ * Flags for EHPI Interface in Colibri Platform ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_EHPI_FASTER_BUS_TIMING 0 /*!< 1: Do workaround for faster bus timing ++ 0(default): Disable */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags for HIFSYS Interface ++ *------------------------------------------------------------------------------ ++ */ ++#ifdef _lint ++#define _HIF_SDIO 0 /* samp */ ++#endif ++ ++#define CFG_SDIO_INTR_ENHANCE 1 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode ++ 0: Disable */ ++#define CFG_SDIO_RX_ENHANCE 0 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode ++ 0: Disable */ ++#define CFG_SDIO_TX_AGG 1 /*!< 1: Enable SDIO TX enhance ++ mode(Multiple frames in single BLOCK CMD) ++ 0(default): Disable */ ++ ++#define CFG_SDIO_RX_AGG 1 /*!< 1: Enable SDIO RX enhance ++ mode(Multiple frames in single BLOCK CMD) ++ 0(default): Disable */ ++ ++#if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0) ++#error "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1" ++#elif (CFG_SDIO_INTR_ENHANCE == 1 || CFG_SDIO_RX_ENHANCE == 1) && (CFG_SDIO_RX_AGG == 0) ++#error "CFG_SDIO_RX_AGG should be 1 once CFG_SDIO_INTR_ENHANCE and/or CFG_SDIO_RX_ENHANCE equals to 1" ++#endif ++ ++#define CFG_SDIO_MAX_RX_AGG_NUM 0 /*!< 1: Setting the maximum RX aggregation number ++ 0(default): no limited */ ++ ++#ifdef WINDOWS_CE ++#define CFG_SDIO_PATHRU_MODE 1 /*!< 1: Support pass through (PATHRU) mode ++ 0: Disable */ ++#else ++#define CFG_SDIO_PATHRU_MODE 0 /*!< 0: Always disable if WINDOWS_CE is not defined */ ++#endif ++ ++#define CFG_MAX_RX_ENHANCE_LOOP_COUNT 3 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Integration ++ *------------------------------------------------------------------------------ ++ */ ++#if defined(MT6620) ++#define MT6620_FPGA_BWCS 0 ++#define MT6620_FPGA_V5 0 ++ ++#if (MT6620_FPGA_BWCS == 1) && (MT6620_FPGA_V5 == 1) ++#error ++#endif ++ ++#if (MTK_WCN_HIF_SDIO == 1) ++#define CFG_MULTI_ECOVER_SUPPORT 1 ++#elif !defined(LINUX) ++#define CFG_MULTI_ECOVER_SUPPORT 1 ++#else ++#define CFG_MULTI_ECOVER_SUPPORT 0 ++#endif ++ ++#define CFG_ENABLE_CAL_LOG 0 ++#define CFG_REPORT_RFBB_VERSION 0 ++ ++#elif defined(MT6628) ++ ++#define CFG_MULTI_ECOVER_SUPPORT 0 ++ ++#define CFG_ENABLE_CAL_LOG 1 ++#define CFG_REPORT_RFBB_VERSION 1 ++ ++#endif ++ ++#define CFG_CHIP_RESET_SUPPORT 1 ++ ++#if defined(MT6628) ++#define CFG_EMBED_FIRMWARE_BUILD_DATE_CODE 1 ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * Flags for workaround ++ *------------------------------------------------------------------------------ ++ */ ++#if defined(MT6620) && (MT6620_FPGA_BWCS == 0) && (MT6620_FPGA_V5 == 0) ++#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 ++#else ++#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 ++#endif ++ ++/* SPM issue: suspend current is higher than deep idle */ ++#define CFG_SPM_WORKAROUND_FOR_HOTSPOT 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags for driver version ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_DRV_OWN_VERSION \ ++ ((UINT_16)((NIC_DRIVER_MAJOR_VERSION << 8) | (NIC_DRIVER_MINOR_VERSION))) ++#define CFG_DRV_PEER_VERSION ((UINT_16)0x0000) ++ ++/*------------------------------------------------------------------------------ ++ * Flags for TX path which are OS dependent ++ *------------------------------------------------------------------------------ ++ */ ++/*! NOTE(Kevin): If the Network buffer is non-scatter-gather like structure(without ++ * NETIF_F_FRAGLIST in LINUX), then we can set CFG_TX_BUFFER_IS_SCATTER_LIST to "0" ++ * for zero copy TX packets. ++ * For scatter-gather like structure, we set "1", driver will do copy frame to ++ * internal coalescing buffer before write it to FIFO. ++ */ ++#if defined(LINUX) ++#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 /*!< 1: Do frame copy before write to TX FIFO. ++ Used when Network buffer is scatter-gather. ++ 0(default): Do not copy frame */ ++#else /* WINDOWS/WINCE */ ++#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 ++#endif /* LINUX */ ++ ++#if CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST ++#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE * NIC_TX_BUFF_SUM) ++#else ++#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE) ++#endif /* CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for TX path ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*! Maximum number of SW TX packet queue */ ++#define CFG_TX_MAX_PKT_NUM 512 /* 256 must >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * 2; ++ or wmm will fail when queue is full */ ++ ++/*! Maximum number of SW TX CMD packet buffer */ ++#define CFG_TX_MAX_CMD_PKT_NUM 32 ++ ++/*! Maximum number of associated STAs */ ++#define CFG_NUM_OF_STA_RECORD 20 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for RX path ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*! Max. descriptor number - sync. with firmware */ ++#if CFG_SLT_SUPPORT ++#define CFG_NUM_OF_RX0_HIF_DESC 42 ++#else ++#define CFG_NUM_OF_RX0_HIF_DESC 16 ++#endif ++#define CFG_NUM_OF_RX1_HIF_DESC 2 ++ ++/*! Max. buffer hold by QM */ ++#define CFG_NUM_OF_QM_RX_PKT_NUM 120 ++ ++/*! Maximum number of SW RX packet buffer */ ++#define CFG_RX_MAX_PKT_NUM ((CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC) * 3 \ ++ + CFG_NUM_OF_QM_RX_PKT_NUM) ++ ++#define CFG_RX_REORDER_Q_THRESHOLD 8 ++ ++#ifndef LINUX ++#define CFG_RX_RETAINED_PKT_THRESHOLD \ ++ (CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC + CFG_NUM_OF_QM_RX_PKT_NUM) ++#else ++#define CFG_RX_RETAINED_PKT_THRESHOLD 0 ++#endif ++ ++/*! Maximum RX packet size, if exceed this value, drop incoming packet */ ++/* 7.2.3 Maganement frames */ ++#define CFG_RX_MAX_PKT_SIZE (28 + 2312 + 12 /*HIF_RX_HEADER_T*/) /* TODO: it should be ++ 4096 under emulation mode */ ++ ++/*! Minimum RX packet size, if lower than this value, drop incoming packet */ ++#define CFG_RX_MIN_PKT_SIZE 10 /*!< 802.11 Control Frame is 10 bytes */ ++ ++#if CFG_SDIO_RX_AGG ++ /* extra size for CS_STATUS and enhanced response */ ++#define CFG_RX_COALESCING_BUFFER_SIZE ((CFG_NUM_OF_RX0_HIF_DESC + 1) \ ++ * CFG_RX_MAX_PKT_SIZE) ++#else ++#define CFG_RX_COALESCING_BUFFER_SIZE (CFG_RX_MAX_PKT_SIZE) ++#endif ++ ++/*! RX BA capability */ ++#define CFG_NUM_OF_RX_BA_AGREEMENTS 8 ++#define CFG_RX_BA_MAX_WINSIZE 16 ++#define CFG_RX_BA_INC_SIZE 4 ++#define CFG_RX_MAX_BA_TID_NUM 8 ++#define CFG_RX_REORDERING_ENABLED 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for CMD/RESPONSE ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_RESPONSE_POLLING_TIMEOUT 512 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Protocol Stack ++ *------------------------------------------------------------------------------ ++ */ ++/*! Maximum number of BSS in the SCAN list */ ++#define CFG_MAX_NUM_BSS_LIST 64 ++ ++#define CFG_MAX_COMMON_IE_BUF_LEN ((1500 * CFG_MAX_NUM_BSS_LIST) / 3) ++ ++/*! Maximum size of Header buffer of each SCAN record */ ++#define CFG_RAW_BUFFER_SIZE 1024 ++ ++/*! Maximum size of IE buffer of each SCAN record */ ++#define CFG_IE_BUFFER_SIZE 512 ++ ++/*! Maximum number of STA records */ ++#define CFG_MAX_NUM_STA_RECORD 32 ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Power management ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_FULL_PM 1 ++#define CFG_ENABLE_WAKEUP_ON_LAN 0 ++#if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || \ ++ defined(CONFIG_ARCH_MT6753) || defined(CONFIG_ARCH_MT6580) ++#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 1 /* debug which packet wake up host */ ++#else ++#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 0 /* debug which packet wake up host */ ++#endif ++#define CFG_INIT_POWER_SAVE_PROF ENUM_PSP_FAST_SWITCH ++ ++#define CFG_INIT_ENABLE_PATTERN_FILTER_ARP 0 ++ ++#define CFG_INIT_UAPSD_AC_BMP 0 /* (BIT(3) | BIT(2) | BIT(1) | BIT(0)) */ ++ ++/* #define CFG_SUPPORT_WAPI 0 */ ++#define CFG_SUPPORT_WPS 1 ++#define CFG_SUPPORT_WPS2 1 ++ ++/*------------------------------------------------------------------------------ ++ * 802.11i RSN Pre-authentication PMKID cahce maximun number ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_MAX_PMKID_CACHE 16 /*!< max number of PMKID cache ++ 16(default) : The Max PMKID cache */ ++/*------------------------------------------------------------------------------ ++ * Auto Channel Selection Maximun Channel Number ++ *------------------------------------------------------------------------------ ++ */ ++ ++#define MAX_AUTO_CHAL_NUM 23 /* Ch1~Ch14,Ch36,Ch40,Ch44, ++ Ch48,Ch149,Ch153,Ch157,Ch161 */ ++/*------------------------------------------------------------------------------ ++ * FAST SCAN ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_FAST_SCAN 0 ++#define CFG_CN_SUPPORT_CLASS121 0 /* Add Class 121, 5470-5725MHz, support for China domain */ ++#if CFG_ENABLE_FAST_SCAN ++ #define CFG_FAST_SCAN_DWELL_TIME 40 ++ #define CFG_FAST_SCAN_REG_DOMAIN_DEF_IDX 10 ++#endif ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Ad-Hoc ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_INIT_ADHOC_FREQ (2462000) ++#define CFG_INIT_ADHOC_MODE AD_HOC_MODE_MIXED_11BG ++#define CFG_INIT_ADHOC_BEACON_INTERVAL (100) ++#define CFG_INIT_ADHOC_ATIM_WINDOW (0) ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Maximum Scan SSID number ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SCAN_SSID_MAX_NUM (4) ++#define CFG_SCAN_SSID_MATCH_MAX_NUM (16) ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Load Setup Default ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags for enable 802.11A Band setting ++ *------------------------------------------------------------------------------ ++ */ ++ ++/*------------------------------------------------------------------------------ ++ * Flags and Parameters for Interrupt Process ++ *------------------------------------------------------------------------------ ++ */ ++#if defined(_HIF_SDIO) && defined(WINDOWS_CE) ++#define CFG_IST_LOOP_COUNT 8 ++#else ++#define CFG_IST_LOOP_COUNT 8 ++#endif /* _HIF_SDIO */ ++ ++#define CFG_INT_WRITE_CLEAR 0 ++ ++#if defined(LINUX) ++#define CFG_DBG_GPIO_PINS 0 /* if 1, use MT6516 GPIO pin to log TX behavior */ ++#endif ++ ++/* 2 Flags for Driver Debug Options */ ++/*------------------------------------------------------------------------------ ++ * Flags of TX Debug Option. NOTE(Kevin): Confirm with SA before modifying following flags. ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_DBG_MGT_BUF 1 /*!< 1: Debug statistics usage of MGMT Buffer ++ 0: Disable */ ++ ++#define CFG_HIF_STATISTICS 0 ++ ++#define CFG_HIF_RX_STARVATION_WARNING 0 ++ ++#define CFG_STARTUP_DEBUG 0 ++ ++#define CFG_RX_PKTS_DUMP 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Firmware Download Option. ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_FW_DOWNLOAD 1 ++ ++#define CFG_ENABLE_FW_DOWNLOAD_ACK 1 ++#define CFG_ENABLE_FW_ENCRYPTION 1 ++ ++#if defined(MT6628) ++#define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION 0 ++#define CFG_ENABLE_FW_DIVIDED_DOWNLOAD 1 ++#endif ++ ++#if defined(MT6620) ++#if MT6620_FPGA_BWCS ++#define CFG_FW_LOAD_ADDRESS 0x10014000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 0 ++#define CFG_FW_START_ADDRESS 0x10014001 ++#elif MT6620_FPGA_V5 ++#define CFG_FW_LOAD_ADDRESS 0x10008000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 0 ++#define CFG_FW_START_ADDRESS 0x10008001 ++#else ++#define CFG_FW_LOAD_ADDRESS 0x10008000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 0 ++#define CFG_FW_START_ADDRESS 0x10008001 ++#endif ++#elif defined(MT6628) ++#define CFG_FW_LOAD_ADDRESS 0x00060000 ++#define CFG_OVERRIDE_FW_START_ADDRESS 1 ++#define CFG_FW_START_ADDRESS 0x00060000 ++#define CFG_START_ADDRESS_IS_1ST_SECTION_ADDR 1 ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Bluetooth-over-WiFi (BT 3.0 + HS) support ++ *------------------------------------------------------------------------------ ++ */ ++ ++#ifdef LINUX ++#ifdef CONFIG_X86 ++#define CFG_ENABLE_BT_OVER_WIFI 0 ++#else ++#define CFG_ENABLE_BT_OVER_WIFI 1 ++#endif ++#else ++#define CFG_ENABLE_BT_OVER_WIFI 0 ++#endif ++ ++#define CFG_BOW_SEPARATE_DATA_PATH 1 ++ ++#define CFG_BOW_PHYSICAL_LINK_NUM 4 ++ ++#define CFG_BOW_TEST 0 ++ ++#define CFG_BOW_LIMIT_AIS_CHNL 1 ++ ++#define CFG_BOW_SUPPORT_11N 0 ++ ++#define CFG_BOW_RATE_LIMITATION 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Wi-Fi Direct support ++ *------------------------------------------------------------------------------ ++ */ ++#ifdef LINUX ++#ifdef CONFIG_X86 ++#define CFG_ENABLE_WIFI_DIRECT 0 ++#define CFG_SUPPORT_802_11W 0 ++#else ++#define CFG_ENABLE_WIFI_DIRECT 1 ++#define CFG_SUPPORT_802_11W 0 /*!< 0(default): Disable 802.11W */ ++#endif ++#else ++#define CFG_ENABLE_WIFI_DIRECT 0 ++#define CFG_SUPPORT_802_11W 0 /* Not support at WinXP */ ++#endif ++ ++#define CFG_SUPPORT_PERSISTENT_GROUP 0 ++ ++#define CFG_TEST_WIFI_DIRECT_GO 0 ++ ++#define CFG_TEST_ANDROID_DIRECT_GO 0 ++ ++#define CFG_UNITEST_P2P 0 ++ ++/* ++ * Enable cfg80211 option after Android 2.2(Froyo) is suggested, ++ * cfg80211 on linux 2.6.29 is not mature yet ++ */ ++#define CFG_ENABLE_WIFI_DIRECT_CFG_80211 1 ++ ++#define CFG_SUPPORT_HOTSPOT_OPTIMIZATION 1 ++#define CFG_HOTSPOT_OPTIMIZATION_BEACON_INTERVAL 300 ++#define CFG_HOTSPOT_OPTIMIZATION_DTIM 1 ++ ++/*------------------------------------------------------------------------------ ++ * Configuration Flags (Linux Only) ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_EXT_CONFIG 0 ++ ++/*------------------------------------------------------------------------------ ++ * Statistics Buffering Mechanism ++ *------------------------------------------------------------------------------ ++ */ ++#if CFG_SUPPORT_PERFORMANCE_TEST ++#define CFG_ENABLE_STATISTICS_BUFFERING 1 ++#else ++#define CFG_ENABLE_STATISTICS_BUFFERING 0 ++#endif ++#define CFG_STATISTICS_VALID_CYCLE 2000 ++#define CFG_LINK_QUALITY_VALID_PERIOD 5000 ++ ++/*------------------------------------------------------------------------------ ++ * Migration Option ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_ADHOC 0 ++#define CFG_SUPPORT_AAA 1 ++ ++#define CFG_SUPPORT_BCM 0 ++#define CFG_SUPPORT_BCM_BWCS 0 ++#define CFG_SUPPORT_BCM_BWCS_DEBUG 0 ++ ++#define CFG_SUPPORT_RDD_TEST_MODE 0 ++ ++#define CFG_SUPPORT_PWR_MGT 1 ++ ++#define CFG_RSN_MIGRATION 1 ++ ++#define CFG_PRIVACY_MIGRATION 1 ++ ++#define CFG_ENABLE_HOTSPOT_PRIVACY_CHECK 1 ++ ++#define CFG_MGMT_FRAME_HANDLING 1 ++ ++#define CFG_MGMT_HW_ACCESS_REPLACEMENT 0 ++ ++#if CFG_SUPPORT_PERFORMANCE_TEST ++ ++#else ++ ++#endif ++ ++#define CFG_SUPPORT_AIS_5GHZ 1 ++#define CFG_SUPPORT_BEACON_CHANGE_DETECTION 0 ++ ++/*------------------------------------------------------------------------------ ++ * Option for NVRAM and Version Checking ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_NVRAM 1 ++#define CFG_NVRAM_EXISTENCE_CHECK 1 ++#define CFG_SW_NVRAM_VERSION_CHECK 1 ++#define CFG_SUPPORT_NIC_CAPABILITY 1 ++ ++/*------------------------------------------------------------------------------ ++ * CONFIG_TITLE : Stress Test Option ++ * OWNER : Puff Wen ++ * Description : For stress test only. DO NOT enable it while normal operation ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_STRESS_TEST_SUPPORT 0 ++ ++/*------------------------------------------------------------------------------ ++ * Flags for LINT ++ *------------------------------------------------------------------------------ ++ */ ++#define LINT_SAVE_AND_DISABLE /*lint -save -e* */ ++ ++#define LINT_RESTORE /*lint -restore */ ++ ++#define LINT_EXT_HEADER_BEGIN LINT_SAVE_AND_DISABLE ++ ++#define LINT_EXT_HEADER_END LINT_RESTORE ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Features ++ *------------------------------------------------------------------------------ ++ */ ++ ++#define CFG_SUPPORT_QOS 1 /* Enable/disable QoS TX, AMPDU */ ++#define CFG_SUPPORT_AMPDU_TX 1 ++#define CFG_SUPPORT_AMPDU_RX 1 ++#define CFG_SUPPORT_TSPEC 0 /* Enable/disable TS-related Action frames handling */ ++#define CFG_SUPPORT_UAPSD 1 ++#define CFG_SUPPORT_UL_PSMP 0 ++ ++#define CFG_SUPPORT_ROAMING 1 /* Roaming System */ ++#define CFG_SUPPORT_SWCR 1 ++ ++#define CFG_SUPPORT_ANTI_PIRACY 1 ++ ++#define CFG_SUPPORT_OSC_SETTING 1 ++ ++#define CFG_SUPPORT_P2P_RSSI_QUERY 0 ++ ++#define CFG_SHOW_MACADDR_SOURCE 1 ++ ++#define CFG_SUPPORT_802_11V 0 /* Support 802.11v Wireless Network Management */ ++#define CFG_SUPPORT_802_11V_TIMING_MEASUREMENT 0 ++#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (CFG_SUPPORT_802_11V == 0) ++#error "CFG_SUPPORT_802_11V should be 1 once CFG_SUPPORT_802_11V_TIMING_MEASUREMENT equals to 1" ++#endif ++#if (CFG_SUPPORT_802_11V == 0) ++#define WNM_UNIT_TEST 0 ++#endif ++ ++#define CFG_DRIVER_COMPOSE_ASSOC_REQ 1 ++ ++#define CFG_STRICT_CHECK_CAPINFO_PRIVACY 0 ++ ++#define CFG_SUPPORT_WFD 1 ++ ++#define CFG_SUPPORT_WFD_COMPOSE_IE 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Packet Lifetime Profiling Mechanism ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_ENABLE_PKT_LIFETIME_PROFILE 1 ++ ++#define CFG_ENABLE_PER_STA_STATISTICS 1 ++ ++#define CFG_PRINT_RTP_PROFILE 0 /* If want to enable WFD Debug, please change it to 1. */ ++#define CFG_PRINT_RTP_SN_SKIP 0 ++ ++#define CFG_SUPPORT_PWR_LIMIT_COUNTRY 1 ++/*------------------------------------------------------------------------------ ++ * Flags of bus error tolerance ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_FORCE_RESET_UNDER_BUS_ERROR 0 ++ ++/*------------------------------------------------------------------------------ ++ * Build Date Code Integration ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_BUILD_DATE_CODE 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags for prepare the FW compile flag ++ *------------------------------------------------------------------------------ ++ */ ++#define COMPILE_FLAG0_GET_STA_LINK_STATUS (1<<0) ++#define COMPILE_FLAG0_WFD_ENHANCEMENT_PROTECT (1<<1) ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Batch Scan SUPPORT ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_BATCH_SCAN 0 ++#define CFG_BATCH_MAX_MSCAN 2 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of Channel Environment SUPPORT ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_SUPPORT_GET_CH_ENV 1 ++ ++/*------------------------------------------------------------------------------ ++ * Flags of THERMO_THROTTLING SUPPORT ++ *------------------------------------------------------------------------------ ++ */ ++ ++#define CFG_SUPPORT_THERMO_THROTTLING 1 ++#define WLAN_INCLUDE_PROC 1 ++ ++#define CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE 1 ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _CONFIG_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h +new file mode 100644 +index 000000000000..af586063c21a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h +@@ -0,0 +1,466 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/debug.h#1 ++*/ ++ ++/*! \file debug.h ++ \brief Definition of SW debugging level. ++ ++ In this file, it describes the definition of various SW debugging levels and ++ assert functions. ++*/ ++ ++/* ++** Log: debug.h ++ * ++ * 12 16 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * fixed the Windows DDK free build compiling error. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Using the new XLOG define for dum Memory. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Add dumpMemory8 at XLOG support. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 07 2011 wh.su ++ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! ++ * . ++ * ++ * 09 23 2010 cp.wu ++ * NULL ++ * add BOW index for debugging message and passing compilation ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add one more debug moduel for P2P. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add debug module index for cnm and ais. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add CFG_STARTUP_DEBUG for debugging starting up issue. ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-29 19:47:50 GMT mtk01084 ++** add emu category ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-17 18:12:04 GMT mtk01426 ++** Don't use dynamic memory allocate for debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:29 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _DEBUG_H ++#define _DEBUG_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#ifndef BUILD_QA_DBG ++#define BUILD_QA_DBG 0 ++#endif ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++extern UINT_8 aucDebugModule[]; ++extern UINT_32 u4DebugModule; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Define debug category (class): ++ * (1) ERROR (2) WARN (3) STATE (4) EVENT (5) TRACE (6) INFO (7) LOUD (8) TEMP ++ */ ++#define DBG_CLASS_ERROR BIT(0) ++#define DBG_CLASS_WARN BIT(1) ++#define DBG_CLASS_STATE BIT(2) ++#define DBG_CLASS_EVENT BIT(3) ++#define DBG_CLASS_TRACE BIT(4) ++#define DBG_CLASS_INFO BIT(5) ++#define DBG_CLASS_LOUD BIT(6) ++#define DBG_CLASS_TEMP BIT(7) ++#define DBG_CLASS_MASK BITS(0, 7) ++ ++#if defined(LINUX) ++#define DBG_PRINTF_64BIT_DEC "lld" ++ ++#else /* Windows */ ++#define DBG_PRINTF_64BIT_DEC "I64d" ++ ++#endif ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Define debug module index */ ++typedef enum _ENUM_DBG_MODULE_T { ++ DBG_INIT_IDX = 0, /* For driver initial */ ++ DBG_HAL_IDX, /* For HAL(HW) Layer */ ++ DBG_INTR_IDX, /* For Interrupt */ ++ DBG_REQ_IDX, ++ DBG_TX_IDX, ++ DBG_RX_IDX, ++ DBG_RFTEST_IDX, /* For RF test mode */ ++ DBG_EMU_IDX, /* Developer specific */ ++ ++ DBG_SW1_IDX, /* Developer specific */ ++ DBG_SW2_IDX, /* Developer specific */ ++ DBG_SW3_IDX, /* Developer specific */ ++ DBG_SW4_IDX, /* Developer specific */ ++ ++ DBG_HEM_IDX, /* HEM */ ++ DBG_AIS_IDX, /* AIS */ ++ DBG_RLM_IDX, /* RLM */ ++ DBG_MEM_IDX, /* RLM */ ++ DBG_CNM_IDX, /* CNM */ ++ DBG_RSN_IDX, /* RSN */ ++ DBG_BSS_IDX, /* BSS */ ++ DBG_SCN_IDX, /* SCN */ ++ DBG_SAA_IDX, /* SAA */ ++ DBG_AAA_IDX, /* AAA */ ++ DBG_P2P_IDX, /* P2P */ ++ DBG_QM_IDX, /* QUE_MGT */ ++ DBG_SEC_IDX, /* SEC */ ++ DBG_BOW_IDX, /* BOW */ ++ DBG_WAPI_IDX, /* WAPI */ ++ DBG_ROAMING_IDX, /* ROAMING */ ++ DBG_TDLS_IDX, /* TDLS *//* CFG_SUPPORT_TDLS */ ++ DBG_OID_IDX, ++ DBG_NIC_IDX, ++ ++ DBG_MODULE_NUM /* Notice the XLOG check */ ++} ENUM_DBG_MODULE_T; ++ ++/* XLOG */ ++/* #define XLOG_DBG_MODULE_IDX 28 */ /* DBG_MODULE_NUM */ ++/* #if (XLOG_DBG_MODULE_IDX != XLOG_DBG_MODULE_IDX) */ ++/* #error "Please modify the DBG_MODULE_NUM and make sure this include at XLOG" */ ++/* #endif */ ++ ++/* Define who owns developer specific index */ ++#define DBG_YARCO_IDX DBG_SW1_IDX ++#define DBG_KEVIN_IDX DBG_SW2_IDX ++#define DBG_CMC_IDX DBG_SW3_IDX ++#define DBG_GEORGE_IDX DBG_SW4_IDX ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Debug print format string for the OS system time */ ++#define OS_SYSTIME_DBG_FORMAT "0x%08x" ++ ++/* Debug print argument for the OS system time */ ++#define OS_SYSTIME_DBG_ARGUMENT(systime) (systime) ++ ++/* Debug print format string for the MAC Address */ ++#define MACSTR "%pM" ++/* "%02x:%02x:%02x:%02x:%02x:%02x" */ ++ ++/* Debug print argument for the MAC Address */ ++#define MAC2STR(a) a ++/* ((PUINT_8)a)[0], ((PUINT_8)a)[1], ((PUINT_8)a)[2], ((PUINT_8)a)[3], ((PUINT_8)a)[4], ((PUINT_8)a)[5] */ ++ ++/* The pre-defined format to dump the value of a varaible with its name shown. */ ++#define DUMPVAR(variable, format) (#variable " = " format "\n", variable) ++ ++/* The pre-defined format to dump the MAC type value with its name shown. */ ++#define DUMPMACADDR(addr) (#addr " = %pM\n", (addr)) ++ ++/* Basiclly, we just do renaming of KAL functions although they should ++ * be defined as "Nothing to do" if DBG=0. But in some compiler, the macro ++ * syntax does not support #define LOG_FUNC(x,...) ++ * ++ * A caller shall not invoke these three macros when DBG=0. ++ */ ++ ++/*LOG_FUNC("[wlan]%s:(" #_Module " " #_Class ") "_Fmt, __func__, ##__VA_ARGS__);*/ ++ ++#define LOG_FUNC kalPrint ++ ++#if defined(LINUX) ++#define DBGLOG(_Module, _Class, _Fmt, ...) \ ++ do { \ ++ if ((aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) == 0) \ ++ break; \ ++ LOG_FUNC("%s:(" #_Module " " #_Class ")"_Fmt, __func__, ##__VA_ARGS__); \ ++ } while (0) ++#else ++#define DBGLOG(_Module, _Class, _Fmt) ++#endif ++ ++#if DBG ++ ++#define TMP_BUF_LEN 256 ++#define TMP_WBUF_LEN (TMP_BUF_LEN * 2) ++ ++extern PINT_16 g_wbuf_p; ++extern PINT_8 g_buf_p; ++ ++ /* If __FUNCTION__ is already defined by compiler, we just use it. */ ++#if defined(__func__) ++#define DEBUGFUNC(_Func) ++#else ++#define DEBUGFUNC(_Func) \ ++ static const char __func__[] = _Func ++#endif ++ ++#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \ ++ { \ ++ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ ++ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ ++ dumpMemory8((PUINT_8) (_StartAddr), (UINT_32) (_Length)); \ ++ } \ ++ } ++ ++#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) \ ++ { \ ++ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ ++ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ ++ dumpMemory32((PUINT_32) (_StartAddr), (UINT_32) (_Length)); \ ++ } \ ++ } ++ /*lint -restore */ ++ ++ /*lint -save -e961 use of '#undef' is discouraged */ ++#undef ASSERT ++ /*lint -restore */ ++ ++#ifdef _lint ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp)) { \ ++ do {} while (1); \ ++ } \ ++ } ++#else ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ ++ kalBreakPoint(); \ ++ } \ ++ } ++#endif /* _lint */ ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ ++ LOG_FUNC _fmt; \ ++ kalBreakPoint(); \ ++ } \ ++ } ++ ++#define DISP_STRING(_str) _str ++ ++#else /* !DBG */ ++ ++#define DEBUGFUNC(_Func) ++#define INITLOG(_Fmt) ++#define ERRORLOG(_Fmt) ++#define WARNLOG(_Fmt) ++ ++#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) ++#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) ++ ++#undef ASSERT ++ ++#if BUILD_QA_DBG ++#if defined(LINUX) /* For debugging in Linux w/o GDB */ ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ ++ kalBreakPoint(); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ ++ LOG_FUNC _fmt; \ ++ kalBreakPoint(); \ ++ } \ ++ } ++#else ++#ifdef WINDOWS_CE ++#define UNICODE_TEXT(_msg) TEXT(_msg) ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ TCHAR rUbuf[256]; \ ++ kalBreakPoint(); \ ++ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ ++ UNICODE_TEXT(__FILE__), \ ++ __LINE__, \ ++ UNICODE_TEXT(#_exp)); \ ++ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ TCHAR rUbuf[256]; \ ++ kalBreakPoint(); \ ++ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ ++ UNICODE_TEXT(__FILE__), \ ++ __LINE__, \ ++ UNICODE_TEXT(#_exp)); \ ++ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ ++ } \ ++ } ++#else ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ kalBreakPoint(); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ kalBreakPoint(); \ ++ } \ ++ } ++#endif /* WINDOWS_CE */ ++#endif /* LINUX */ ++#else ++#define ASSERT(_exp) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ ++ } \ ++ } ++ ++#define ASSERT_REPORT(_exp, _fmt) \ ++ { \ ++ if (!(_exp) && !fgIsBusAccessFailed) { \ ++ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ ++ LOG_FUNC _fmt; \ ++ } \ ++ } ++#endif /* BUILD_QA_DBG */ ++ ++#define DISP_STRING(_str) "" ++ ++#endif /* DBG */ ++ ++#if CFG_STARTUP_DEBUG ++#if defined(LINUX) ++#define DBGPRINTF kalPrint ++#else ++#define DBGPRINTF DbgPrint ++#endif ++#else ++#define DBGPRINTF(...) ++#endif ++ ++/* The following macro is used for debugging packed structures. */ ++#ifndef DATA_STRUCT_INSPECTING_ASSERT ++#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ ++{ \ ++ switch (0) {case 0: case (expr): default:; } \ ++} ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length); ++ ++VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length); ++ ++VOID wlanDebugInit(VOID); ++VOID wlanDebugUninit(VOID); ++VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable); ++VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd); ++VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _DEBUG_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h +new file mode 100644 +index 000000000000..108860c80e2d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h +@@ -0,0 +1,368 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1 ++*/ ++ ++/*! \file link.h ++ \brief Definition for simple doubly linked list operations. ++ ++ In this file we define the simple doubly linked list data structure and its ++ operation MACROs and INLINE functions. ++*/ ++ ++/* ++** Log: link.h ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * [WPD00003833] [MT6620 and MT5931] Driver migration ++ * . ++ * ++ * ++ * ++ * ++ * May 4 2009 mtk01084 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * add WIFI to BORA source control ++** \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461 ++** Update driver to fix lint warning ++** \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461 ++** Add macro for checking valid list ++** \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461 ++** Add LINK_IS_INVALID macro ++** Revision 1.1.1.1 2007/06/22 08:09:05 MTK01461 ++** no message ++** ++*/ ++ ++#ifndef _LINK_H ++#define _LINK_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* May cause page fault & unalignment issue (data abort) */ ++#define INVALID_LINK_POISON1 ((VOID *) 0x00100101) ++/* Used to verify that nonbody uses non-initialized link entries. */ ++#define INVALID_LINK_POISON2 ((VOID *) 0x00100201) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Simple Doubly Linked List Structures - Entry Part */ ++typedef struct _LINK_ENTRY_T { ++ struct _LINK_ENTRY_T *prNext, *prPrev; ++} LINK_ENTRY_T, *P_LINK_ENTRY_T; ++ ++/* Simple Doubly Linked List Structures - List Part */ ++typedef struct _LINK_T { ++ P_LINK_ENTRY_T prNext; ++ P_LINK_ENTRY_T prPrev; ++ UINT_32 u4NumElem; ++} LINK_T, *P_LINK_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#if 0 /* No one use it, temporarily mark it for [Lint - Info 773] */ ++#define LINK_ADDR(rLink) { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 } ++ ++#define LINK_DECLARATION(rLink) \ ++ struct _LINK_T rLink = LINK_ADDR(rLink) ++#endif ++ ++#define LINK_INITIALIZE(prLink) \ ++ do { \ ++ ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \ ++ ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \ ++ ((P_LINK_T)(prLink))->u4NumElem = 0; \ ++ } while (0) ++ ++#define LINK_ENTRY_INITIALIZE(prEntry) \ ++ do { \ ++ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \ ++ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \ ++ } while (0) ++ ++#define LINK_ENTRY_INVALID(prEntry) \ ++ do { \ ++ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \ ++ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \ ++ } while (0) ++ ++#define LINK_IS_EMPTY(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink)) ++ ++/* NOTE: We should do memory zero before any LINK been initiated, so we can check ++ * if it is valid before parsing the LINK. ++ */ ++#define LINK_IS_INVALID(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL) ++ ++#define LINK_IS_VALID(prLink) (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL) ++ ++#define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member) ++ ++/* Insert an entry into a link list's head */ ++#define LINK_INSERT_HEAD(prLink, prEntry) \ ++ { \ ++ linkAdd(prEntry, prLink); \ ++ ((prLink)->u4NumElem)++; \ ++ } ++ ++/* Append an entry into a link list's tail */ ++#define LINK_INSERT_TAIL(prLink, prEntry) \ ++ { \ ++ linkAddTail(prEntry, prLink); \ ++ ((prLink)->u4NumElem)++; \ ++ } ++ ++/* Peek head entry, but keep still in link list */ ++#define LINK_PEEK_HEAD(prLink, _type, _member) \ ++ ( \ ++ LINK_IS_EMPTY(prLink) ? \ ++ NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \ ++ ) ++ ++/* Peek tail entry, but keep still in link list */ ++#define LINK_PEEK_TAIL(prLink, _type, _member) \ ++ ( \ ++ LINK_IS_EMPTY(prLink) ? \ ++ NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \ ++ ) ++ ++/* Get first entry from a link list */ ++/* NOTE: We assume the link entry located at the beginning of "prEntry Type", ++ * so that we can cast the link entry to other data type without doubts. ++ * And this macro also decrease the total entry count at the same time. ++ */ ++#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \ ++ { \ ++ ASSERT(prLink); \ ++ if (LINK_IS_EMPTY(prLink)) { \ ++ prEntry = (_P_TYPE)NULL; \ ++ } \ ++ else { \ ++ prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \ ++ linkDel((P_LINK_ENTRY_T)prEntry); \ ++ ((prLink)->u4NumElem)--; \ ++ } \ ++ } ++ ++/* Assume the link entry located at the beginning of prEntry Type. ++ * And also decrease the total entry count. ++ */ ++#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \ ++ { \ ++ ASSERT(prLink); \ ++ ASSERT(prEntry); \ ++ linkDel((P_LINK_ENTRY_T)prEntry); \ ++ ((prLink)->u4NumElem)--; \ ++ } ++ ++/* Iterate over a link list */ ++#define LINK_FOR_EACH(prEntry, prLink) \ ++ for (prEntry = (prLink)->prNext; \ ++ prEntry != (P_LINK_ENTRY_T)(prLink); \ ++ prEntry = (P_LINK_ENTRY_T)prEntry->prNext) ++ ++/* Iterate over a link list backwards */ ++#define LINK_FOR_EACH_PREV(prEntry, prLink) \ ++ for (prEntry = (prLink)->prPrev; \ ++ prEntry != (P_LINK_ENTRY_T)(prLink); \ ++ prEntry = (P_LINK_ENTRY_T)prEntry->prPrev) ++ ++/* Iterate over a link list safe against removal of link entry */ ++#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \ ++ for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \ ++ prEntry != (P_LINK_ENTRY_T)(prLink); \ ++ prEntry = prNextEntry, prNextEntry = prEntry->prNext) ++ ++/* Iterate over a link list of given type */ ++#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \ ++ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \ ++ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ ++ prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember)) ++ ++/* Iterate backwards over a link list of given type */ ++#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \ ++ for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \ ++ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ ++ prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember)) ++ ++/* Iterate over a link list of given type safe against removal of link entry */ ++#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \ ++ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \ ++ prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \ ++ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ ++ prObj = prNextObj, \ ++ prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is only for internal link list manipulation. ++* ++* \param[in] prNew Pointer of new link head ++* \param[in] prPrev Pointer of previous link head ++* \param[in] prNext Pointer of next link head ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID __linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) ++{ ++ prNext->prPrev = prNew; ++ prNew->prNext = prNext; ++ prNew->prPrev = prPrev; ++ prPrev->prNext = prNew; ++ ++} /* end of __linkAdd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will add a new entry after the specified link head. ++* ++* \param[in] prNew New entry to be added ++* \param[in] prHead Specified link head to add it after ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) ++{ ++ __linkAdd(prNew, (P_LINK_ENTRY_T) prLink, prLink->prNext); ++ ++} /* end of linkAdd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will add a new entry before the specified link head. ++* ++* \param[in] prNew New entry to be added ++* \param[in] prHead Specified link head to add it before ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkAddTail(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) ++{ ++ __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T) prLink); ++ ++} /* end of linkAddTail() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is only for internal link list manipulation. ++* ++* \param[in] prPrev Pointer of previous link head ++* \param[in] prNext Pointer of next link head ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID __linkDel(IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) ++{ ++ prNext->prPrev = prPrev; ++ prPrev->prNext = prNext; ++ ++} /* end of __linkDel() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will delete a specified entry from link list. ++* NOTE: the entry is in an initial state. ++* ++* \param prEntry Specified link head(entry) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkDel(IN P_LINK_ENTRY_T prEntry) ++{ ++ __linkDel(prEntry->prPrev, prEntry->prNext); ++ ++ LINK_ENTRY_INITIALIZE(prEntry); ++ ++} /* end of linkDel() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will delete a specified entry from link list and then add it ++* after the specified link head. ++* ++* \param[in] prEntry Specified link head(entry) ++* \param[in] prOtherHead Another link head to add it after ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkMove(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) ++{ ++ __linkDel(prEntry->prPrev, prEntry->prNext); ++ linkAdd(prEntry, prLink); ++ ++} /* end of linkMove() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will delete a specified entry from link list and then add it ++* before the specified link head. ++* ++* \param[in] prEntry Specified link head(entry) ++* \param[in] prOtherHead Another link head to add it before ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID linkMoveTail(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) ++{ ++ __linkDel(prEntry->prPrev, prEntry->prNext); ++ linkAddTail(prEntry, prLink); ++ ++} /* end of linkMoveTail() */ ++ ++#endif /* _LINK_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h +new file mode 100644 +index 000000000000..fd83c79ffe10 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h +@@ -0,0 +1,188 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/aa_fsm.h#1 ++*/ ++ ++/*! \file aa_fsm.h ++ \brief Declaration of functions and finite state machine for SAA/AAA Module. ++ ++ Declaration of functions and finite state machine for SAA/AAA Module. ++*/ ++ ++/* ++** Log: aa_fsm.h ++ * ++ * 10 13 2011 cp.wu ++ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS ++ * 1. short join failure count limit to 2 ++ * 2. treat join timeout as kind of join failure as well ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _AA_FSM_H ++#define _AA_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Retry interval for retransmiting authentication-request MMPDU. */ ++#define TX_AUTHENTICATION_RETRY_TIMEOUT_TU 100 /* TU. */ ++ ++/* Retry interval for retransmiting association-request MMPDU. */ ++#define TX_ASSOCIATION_RETRY_TIMEOUT_TU 100 /* TU. */ ++ ++/* Wait for a response to a transmitted authentication-request MMPDU. */ ++#define DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ ++ ++/* Wait for a response to a transmitted association-request MMPDU. */ ++#define DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ ++ ++/* The maximum time to wait for JOIN process complete. */ ++#define JOIN_FAILURE_TIMEOUT_BEACON_INTERVAL 20 /* Beacon Interval, 20 * 100TU = 2 sec. */ ++ ++/* Retry interval for next JOIN request. */ ++#define JOIN_RETRY_INTERVAL_SEC 10 /* Seconds */ ++ ++/* Maximum Retry Count for accept a JOIN request. */ ++#define JOIN_MAX_RETRY_FAILURE_COUNT 2 /* Times */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_AA_STATE_T { ++ AA_STATE_IDLE = 0, ++ SAA_STATE_SEND_AUTH1, ++ SAA_STATE_WAIT_AUTH2, ++ SAA_STATE_SEND_AUTH3, ++ SAA_STATE_WAIT_AUTH4, ++ SAA_STATE_SEND_ASSOC1, ++ SAA_STATE_WAIT_ASSOC2, ++ AAA_STATE_SEND_AUTH2, ++ AAA_STATE_SEND_AUTH4, /* We may not use, because P2P GO didn't support WEP and 11r */ ++ AAA_STATE_SEND_ASSOC2, ++ AA_STATE_RESOURCE, /* A state for debugging the case of out of msg buffer. */ ++ AA_STATE_NUM ++} ENUM_AA_STATE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in saa_fsm.c */ ++/*----------------------------------------------------------------------------*/ ++VOID ++saaFsmSteps(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb); ++ ++WLAN_STATUS ++saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, ++ WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb); ++ ++VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++WLAN_STATUS ++saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines in aaa_fsm.c */ ++/*----------------------------------------------------------------------------*/ ++VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _AA_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h +new file mode 100644 +index 000000000000..b771bdacf2c6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h +@@ -0,0 +1,573 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/ais_fsm.h#1 ++*/ ++ ++/*! \file ais_fsm.h ++ \brief Declaration of functions and finite state machine for AIS Module. ++ ++ Declaration of functions and finite state machine for AIS Module. ++*/ ++ ++/* ++** Log: ais_fsm.h ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition ++ * from synchronous to asynchronous approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS ++ * is in Normal TR state without join timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 04 25 2011 cp.wu ++ * [WCXRP00000676] [MT6620 Wi-Fi][Driver] AIS to reduce request channel period from 5 seconds to 2 seconds ++ * channel interval for joining is shortened to 2 seconds to avoid interruption of concurrent operating network. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 02 22 2011 cp.wu ++ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with ++ * a queue-based approach to improve response time for scanning request ++ * handle SCAN and RECONNECT with a FIFO approach. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 14 2011 cp.wu ++ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent ++ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. ++ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. ++ * ++ * 11 25 2010 cp.wu ++ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM ++ * add scanning with specified SSID facility to AIS-FSM ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * 1) initialize for correct parameter even for disassociation. ++ * 2) AIS-FSM should have a limit on trials to build connection ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, RLM/CNM will handle ++ * the channel switching when BSS information is updated ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, ++ * just pend it til 5-sec. period finishes ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet ++ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * separate AIS-FSM states into different cases of channel request. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Refine AIS-FSM by divided into more states ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 23 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * reduce the background ssid idle time min and max value ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * and will send Null frame to diagnose connection ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Support dynamic channel selection ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Media disconnect indication and related postpone functions ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aisFsmRunEventJoinComplete() ++ * ++ * Nov 25 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Virtual CMD & RESP for testing CMD PATH ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * add aisFsmInitializeConnectionSettings() ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_MGMT_FSM for aisFsmTest() ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function prototype of aisFsmInit() ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _AIS_FSM_H ++#define _AIS_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define AIS_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ ++#define AIS_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ ++ ++#define AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4 2 /* 2.4G scan need about 0.5s, so delay 2s to reconnect is enough */ ++#define AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND 5 /* 2.4G scan need about 3.3s, so delay 5s to reconnect is enough */ ++ ++#define AIS_IBSS_ALONE_TIMEOUT_SEC 20 /* seconds */ ++ ++#define AIS_BEACON_TIMEOUT_COUNT_ADHOC 30 ++#define AIS_BEACON_TIMEOUT_COUNT_INFRA 10 ++#define AIS_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ ++ ++#define AIS_BEACON_MAX_TIMEOUT_TU 100 ++#define AIS_BEACON_MIN_TIMEOUT_TU 5 ++#define AIS_BEACON_MAX_TIMEOUT_VALID TRUE ++#define AIS_BEACON_MIN_TIMEOUT_VALID TRUE ++ ++#define AIS_BMC_MAX_TIMEOUT_TU 100 ++#define AIS_BMC_MIN_TIMEOUT_TU 5 ++#define AIS_BMC_MAX_TIMEOUT_VALID TRUE ++#define AIS_BMC_MIN_TIMEOUT_VALID TRUE ++ ++#define AIS_JOIN_CH_GRANT_THRESHOLD 10 ++#define AIS_JOIN_CH_REQUEST_INTERVAL 3000 ++ ++#define AIS_SCN_DONE_TIMEOUT_SEC 30 /* 15 for 2.4G + 5G */ /* 5 */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_AIS_STATE_T { ++ AIS_STATE_IDLE = 0, ++ AIS_STATE_SEARCH, ++ AIS_STATE_SCAN, ++ AIS_STATE_ONLINE_SCAN, ++ AIS_STATE_LOOKING_FOR, ++ AIS_STATE_WAIT_FOR_NEXT_SCAN, ++ AIS_STATE_REQ_CHANNEL_JOIN, ++ AIS_STATE_JOIN, ++ AIS_STATE_IBSS_ALONE, ++ AIS_STATE_IBSS_MERGE, ++ AIS_STATE_NORMAL_TR, ++ AIS_STATE_DISCONNECTING, ++ AIS_STATE_REQ_REMAIN_ON_CHANNEL, ++ AIS_STATE_REMAIN_ON_CHANNEL, ++ AIS_STATE_NUM ++} ENUM_AIS_STATE_T; ++ ++typedef struct _MSG_AIS_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucReasonOfDisconnect; ++ BOOLEAN fgDelayIndication; ++} MSG_AIS_ABORT_T, *P_MSG_AIS_ABORT_T; ++ ++typedef struct _MSG_AIS_IBSS_PEER_FOUND_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ BOOLEAN fgIsMergeIn; /* TRUE: Merge In, FALSE: Merge Out */ ++ P_STA_RECORD_T prStaRec; ++} MSG_AIS_IBSS_PEER_FOUND_T, *P_MSG_AIS_IBSS_PEER_FOUND_T; ++ ++typedef enum _ENUM_AIS_REQUEST_TYPE_T { ++ AIS_REQUEST_SCAN, ++ AIS_REQUEST_RECONNECT, ++ AIS_REQUEST_ROAMING_SEARCH, ++ AIS_REQUEST_ROAMING_CONNECT, ++ AIS_REQUEST_REMAIN_ON_CHANNEL, ++ AIS_REQUEST_NUM ++} ENUM_AIS_REQUEST_TYPE_T; ++ ++typedef struct _AIS_REQ_HDR_T { ++ LINK_ENTRY_T rLinkEntry; ++ ENUM_AIS_REQUEST_TYPE_T eReqType; ++} AIS_REQ_HDR_T, *P_AIS_REQ_HDR_T; ++ ++typedef struct _AIS_REQ_CHNL_INFO { ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eSco; ++ UINT_8 ucChannelNum; ++ UINT_32 u4DurationMs; ++ UINT_64 u8Cookie; ++} AIS_REQ_CHNL_INFO, *P_AIS_REQ_CHNL_INFO; ++ ++typedef struct _AIS_MGMT_TX_REQ_INFO_T { ++ BOOLEAN fgIsMgmtTxRequested; ++ P_MSDU_INFO_T prMgmtTxMsdu; ++ UINT_64 u8Cookie; ++} AIS_MGMT_TX_REQ_INFO_T, *P_AIS_MGMT_TX_REQ_INFO_T; ++ ++typedef struct _AIS_FSM_INFO_T { ++ ENUM_AIS_STATE_T ePreviousState; ++ ENUM_AIS_STATE_T eCurrentState; ++ ++ BOOLEAN fgTryScan; ++ ++ BOOLEAN fgIsInfraChannelFinished; ++ BOOLEAN fgIsChannelRequested; ++ BOOLEAN fgIsChannelGranted; ++ ++#if CFG_SUPPORT_ROAMING ++ BOOLEAN fgIsRoamingScanPending; ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ ++ ++ P_BSS_DESC_T prTargetBssDesc; /* For destination */ ++ ++ P_STA_RECORD_T prTargetStaRec; /* For JOIN Abort */ ++ ++ UINT_32 u4SleepInterval; ++ ++ TIMER_T rBGScanTimer; ++ ++ TIMER_T rIbssAloneTimer; ++ ++ TIMER_T rIndicationOfDisconnectTimer; ++ ++ TIMER_T rJoinTimeoutTimer; ++ ++ TIMER_T rChannelTimeoutTimer; ++ ++ TIMER_T rScanDoneTimer; ++ ++ TIMER_T rDeauthDoneTimer; ++ ++ UINT_8 ucSeqNumOfReqMsg; ++ UINT_8 ucSeqNumOfChReq; ++ UINT_8 ucSeqNumOfScanReq; ++ ++ UINT_32 u4ChGrantedInterval; ++ ++ UINT_8 ucConnTrialCount; ++ ++ UINT_8 ucScanSSIDLen; ++ UINT_8 aucScanSSID[ELEM_MAX_LEN_SSID]; ++ ++ UINT_32 u4ScanIELength; ++ UINT_8 aucScanIEBuf[MAX_IE_LENGTH]; ++ ++ /* Pending Request List */ ++ LINK_T rPendingReqList; ++ ++ /* Join Request Timestamp */ ++ OS_SYSTIME rJoinReqTime; ++ ++ /* for cfg80211 REMAIN_ON_CHANNEL support */ ++ AIS_REQ_CHNL_INFO rChReqInfo; ++ ++ /* Mgmt tx related. */ ++ AIS_MGMT_TX_REQ_INFO_T rMgmtTxInfo; ++ ++ /* Packet filter for AIS module. */ ++ UINT_32 u4AisPacketFilter; ++ ++} AIS_FSM_INFO_T, *P_AIS_FSM_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define aisChangeMediaState(_prAdapter, _eNewMediaState) \ ++ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState = (_eNewMediaState)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); ++ ++VOID aisFsmInit(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmUninit(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication); ++ ++VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter); ++#if 0 ++VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState); ++#endif ++VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++/*----------------------------------------------------------------------------*/ ++/* Handling for Ad-Hoc Network */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++/*----------------------------------------------------------------------------*/ ++/* Handling of Incoming Mailbox Message from CNM */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++/*----------------------------------------------------------------------------*/ ++/* Generating Outgoing Mailbox Message to CNM */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Event Indication */ ++/*----------------------------------------------------------------------------*/ ++VOID ++aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); ++ ++VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb); ++ ++VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter); ++ ++VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++WLAN_STATUS ++aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Disconnection Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication); ++ ++/*----------------------------------------------------------------------------*/ ++/* Event Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter); ++ ++VOID aisBssSecurityChanged(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++#if CFG_SUPPORT_ROAMING ++VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan); ++ ++ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter); ++ ++VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec); ++ ++VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); ++#endif /*CFG_SUPPORT_ROAMING */ ++ ++/*----------------------------------------------------------------------------*/ ++/* Timeout Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID/IOCTL Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength); ++ ++/*----------------------------------------------------------------------------*/ ++/* Internal State Checking */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove); ++ ++P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType); ++ ++VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); ++ ++VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) ++VOID aisTest(VOID); ++#endif /* CFG_TEST_MGMT_FSM */ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _AIS_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h +new file mode 100644 +index 000000000000..70b32bca102b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h +@@ -0,0 +1,112 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/assoc.h#1 ++*/ ++ ++/*! \file assoc.h ++ \brief This file contains the ASSOC REQ/RESP of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: assoc.h ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add assocCheckTxReAssocRespFrame() proto type for P2P usage. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++*/ ++ ++#ifndef _ASSOC_H ++#define _ASSOC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in assoc.c */ ++/*----------------------------------------------------------------------------*/ ++UINT_16 assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++WLAN_STATUS ++assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode); ++ ++WLAN_STATUS ++assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); ++ ++WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _ASSOC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h +new file mode 100644 +index 000000000000..4f76f03324dd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h +@@ -0,0 +1,125 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/auth.h#1 ++*/ ++ ++/*! \file auth.h ++ \brief This file contains the authentication REQ/RESP of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: auth.h ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++*/ ++ ++#ifndef _AUTH_H ++#define _AUTH_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in auth.c */ ++/*----------------------------------------------------------------------------*/ ++VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo); ++ ++#if !CFG_SUPPORT_AAA ++WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum); ++#else ++WLAN_STATUS ++authSendAuthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode); ++#endif /* CFG_SUPPORT_AAA */ ++ ++WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum); ++ ++WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode); ++ ++VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr); ++ ++WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++authSendDeauthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); ++ ++WLAN_STATUS ++authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN UINT_8 aucExpectedBSSID[], ++ IN UINT_16 u2ExpectedAuthAlgNum, ++ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _AUTH_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h +new file mode 100644 +index 000000000000..5995d133a6cd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h +@@ -0,0 +1,184 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/bow_fsm.h#1 ++*/ ++ ++/*! \file bow_fsm.h ++ \brief Declaration of functions and finite state machine for BOW Module. ++ ++ Declaration of functions and finite state machine for BOW Module. ++*/ ++ ++/* ++** Log: bow_fsm.h ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Submit missing BoW header files. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 02 16 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add channel previledge into _BOW_FSM_INFO_T. ++ * ++ * 09 16 2010 chinghwa.yu ++ * NULL ++ * update bowChangeMediaState. ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ */ ++ ++#ifndef _BOW_FSM_H ++#define _BOW_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define BOW_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ ++#define BOW_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ ++ ++#define BOW_DELAY_TIME_OF_DISCONNECT_SEC 10 ++ ++#define BOW_BEACON_TIMEOUT_COUNT_STARTING 10 ++#define BOW_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ ++ ++#define BOW_BEACON_MAX_TIMEOUT_TU 100 ++#define BOW_BEACON_MIN_TIMEOUT_TU 5 ++#define BOW_BEACON_MAX_TIMEOUT_VALID TRUE ++#define BOW_BEACON_MIN_TIMEOUT_VALID TRUE ++ ++#define BOW_BMC_MAX_TIMEOUT_TU 100 ++#define BOW_BMC_MIN_TIMEOUT_TU 5 ++#define BOW_BMC_MAX_TIMEOUT_VALID TRUE ++#define BOW_BMC_MIN_TIMEOUT_VALID TRUE ++ ++#define BOW_JOIN_CH_GRANT_THRESHOLD 10 ++#define BOW_JOIN_CH_REQUEST_INTERVAL 2000 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_BOW_STATE_T { ++ BOW_STATE_IDLE = 0, ++ BOW_STATE_SEARCH, ++ BOW_STATE_SCAN, ++ BOW_STATE_ONLINE_SCAN, ++ BOW_STATE_LOOKING_FOR, ++ BOW_STATE_WAIT_FOR_NEXT_SCAN, ++ BOW_STATE_REQ_CHANNEL_JOIN, ++ BOW_STATE_REQ_CHANNEL_ALONE, ++ BOW_STATE_REQ_CHANNEL_MERGE, ++ BOW_STATE_JOIN, ++ BOW_STATE_IBSS_ALONE, ++ BOW_STATE_IBSS_MERGE, ++ BOW_STATE_NORMAL_TR, ++ BOW_STATE_NUM ++} ENUM_BOW_STATE_T; ++ ++typedef struct _BOW_FSM_INFO_T { ++ ENUM_BOW_STATE_T ePreviousState; ++ ENUM_BOW_STATE_T eCurrentState; ++ ++ BOOLEAN fgTryScan; ++ ++ /* Channel Privilege */ ++ ++ BOOLEAN fgIsInfraChannelFinished; ++ BOOLEAN fgIsChannelRequested; ++ BOOLEAN fgIsChannelGranted; ++ BOOLEAN fgIsScanPending; ++ UINT_32 u4ChGrantedInterval; ++ ++ UINT_8 ucPrimaryChannel; ++ ENUM_BAND_T eBand; ++ UINT_16 u2BeaconInterval; ++ ++ ENUM_BOW_STATE_T eReturnState; /* Return state after current activity finished or abort. */ ++ ENUM_BOW_STATE_T eForwardState; /* Step to next state if ACTION frame is TX successfully. */ ++ ++ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ ++ ++ P_STA_RECORD_T prTargetStaRec; ++ P_BSS_DESC_T prTargetBssDesc; /* For destination */ ++ ++ UINT_8 aucPeerAddress[6]; ++ ++ UINT_8 ucRole; ++ ++ BOOLEAN fgSupportQoS; ++ ++ BOOLEAN fgIsRsponseProbe; /* Indicate if BOW can response probe request frame. */ ++ ++ /* Sequence number of requested message. */ ++ UINT_8 ucSeqNumOfChReq; ++ UINT_8 ucSeqNumOfReqMsg; ++ UINT_8 ucSeqNumOfScnMsg; ++ UINT_8 ucSeqNumOfScanReq; ++ ++ UINT_8 ucSeqNumOfCancelMsg; ++ ++ UINT_8 ucDialogToken; ++ ++ /* Timer */ ++ TIMER_T rStartingBeaconTimer; /* For device discovery time of each discovery request from user. */ ++ TIMER_T rStartingDiscoveryTimer; ++ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ ++ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ ++ TIMER_T rIndicationOfDisconnectTimer; ++ TIMER_T rChGrantedTimer; ++ ++ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ ++ ++} BOW_FSM_INFO_T, *P_BOW_FSM_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define bowChangeMediaState(_prAdapter, _eNewMediaState) \ ++ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].eConnectionState = (_eNewMediaState)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h +new file mode 100644 +index 000000000000..0597132b970e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h +@@ -0,0 +1,265 @@ ++/* ++** Id: @(#) bss.h ++*/ ++ ++/*! \file "bss.h" ++ \brief In this file we define the function prototype used in BSS/IBSS. ++ ++ The file contains the function declarations and defines for used in BSS/IBSS. ++*/ ++ ++/* ++** Log: bss.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * Add code to send beacon and probe response WSC IE at Auto GO. ++ * ++ * 02 23 2011 eddie.chen ++ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap ++ * Fix parsing WMM INFO and bmp delivery bitmap definition. ++ * ++ * 01 31 2011 george.huang ++ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers ++ * Extend TIM PVB, from 2 to 3 octets. ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for ++ * initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Update bssProcessProbeRequest() and bssSendBeaconProbeResponse() declarations ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * when IBSS is being merged-in, send command packet to PM for connected indication ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add CTRL FLAGS for Probe Response. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Remove unused typedef. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix file merge error ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * * and will send Null frame to diagnose connection ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add DTIM count update while TX Beacon ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++#ifndef _BSS_H ++#define _BSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* NOTE(Kevin): change define for george */ ++/* #define MAX_LEN_TIM_PARTIAL_BMP (((MAX_ASSOC_ID + 1) + 7) / 8) */ /* Required bits = (MAX_ASSOC_ID + 1) */ ++#define MAX_LEN_TIM_PARTIAL_BMP ((CFG_STA_REC_NUM + 7) / 8) ++/* reserve length greater than maximum size of STA_REC */ /* obsoleted: Assume we only use AID:1~15 */ ++ ++/* CTRL FLAGS for Probe Response */ ++#define BSS_PROBE_RESP_USE_P2P_DEV_ADDR BIT(0) ++#define BSS_PROBE_RESP_INCLUDE_P2P_IE BIT(1) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define bssAssignAssocID(_prStaRec) ((_prStaRec)->ucIndex + 1) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines for all Operation Modes */ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T ++bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_STA_TYPE_T eStaType, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc); ++ ++VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec); ++ ++VOID ++bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP); ++ ++WLAN_STATUS ++bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++WLAN_STATUS ++bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for both IBSS(AdHoc) and BSS(AP) */ ++/*----------------------------------------------------------------------------*/ ++VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID ++bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr); ++ ++VOID ++bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN PUINT_8 pucDestAddr, ++ IN PUINT_8 pucOwnMACAddress, ++ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo); ++ ++WLAN_STATUS ++bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags); ++ ++WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); ++ ++VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); ++ ++VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for IBSS(AdHoc) only */ ++/*----------------------------------------------------------------------------*/ ++VOID ++ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI); ++ ++WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); ++ ++WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for BSS(AP) only */ ++/*----------------------------------------------------------------------------*/ ++VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate); ++ ++VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId); ++ ++P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr); ++ ++/*link function to p2p module for txBcnIETable*/ ++ ++/* WMM-2.2.2 WMM ACI to AC coding */ ++typedef enum _ENUM_ACI_T { ++ ACI_BE = 0, ++ ACI_BK = 1, ++ ACI_VI = 2, ++ ACI_VO = 3, ++ ACI_NUM ++} ENUM_ACI_T, *P_ENUM_ACI_T; ++ ++typedef enum _ENUM_AC_PRIORITY_T { ++ AC_BK_PRIORITY = 0, ++ AC_BE_PRIORITY, ++ AC_VI_PRIORITY, ++ AC_VO_PRIORITY ++} ENUM_AC_PRIORITY_T, *P_ENUM_AC_PRIORITY_T; ++ ++#endif /* _BSS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h +new file mode 100644 +index 000000000000..81b16b588867 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h +@@ -0,0 +1,258 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm.h#1 ++*/ ++ ++/*! \file "cnm.h" ++ \brief ++*/ ++ ++/* ++** Log: cnm.h ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Provide function to decide if BSS can be activated or not ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 13 2010 cm.chang ++ * ++ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Need bandwidth info when requesting channel privilege ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add a new function to send abort message ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support partial part about cmd basic configuration ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add prototype of cnmFsmEventInit() ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_H ++#define _CNM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _ENUM_CH_REQ_TYPE_T { ++ CH_REQ_TYPE_JOIN, ++ CH_REQ_TYPE_P2P_LISTEN, ++ ++ CH_REQ_TYPE_NUM ++} ENUM_CH_REQ_TYPE_T, *P_ENUM_CH_REQ_TYPE_T; ++ ++typedef struct _MSG_CH_REQ_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucPrimaryChannel; ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ENUM_CH_REQ_TYPE_T eReqType; ++ UINT_32 u4MaxInterval; /* In unit of ms */ ++ UINT_8 aucBSSID[6]; ++ UINT_8 aucReserved[2]; ++} MSG_CH_REQ_T, *P_MSG_CH_REQ_T; ++ ++typedef struct _MSG_CH_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++} MSG_CH_ABORT_T, *P_MSG_CH_ABORT_T; ++ ++typedef struct _MSG_CH_GRANT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucPrimaryChannel; ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ENUM_CH_REQ_TYPE_T eReqType; ++ UINT_32 u4GrantInterval; /* In unit of ms */ ++} MSG_CH_GRANT_T, *P_MSG_CH_GRANT_T; ++ ++typedef struct _MSG_CH_REOCVER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucPrimaryChannel; ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ENUM_CH_REQ_TYPE_T eReqType; ++} MSG_CH_RECOVER_T, *P_MSG_CH_RECOVER_T; ++ ++typedef struct _CNM_INFO_T { ++ UINT_32 u4Reserved; ++} CNM_INFO_T, *P_CNM_INFO_T; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/* Moved from p2p_fsm.h */ ++typedef struct _DEVICE_TYPE_T { ++ UINT_16 u2CategoryId; /* Category ID */ ++ UINT_8 aucOui[4]; /* OUI */ ++ UINT_16 u2SubCategoryId; /* Sub Category ID */ ++} __KAL_ATTRIB_PACKED__ DEVICE_TYPE_T, *P_DEVICE_TYPE_T; ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID cnmInit(P_ADAPTER_T prAdapter); ++ ++VOID cnmUninit(P_ADAPTER_T prAdapter); ++ ++VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent); ++ ++BOOLEAN ++cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO); ++ ++BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); ++ ++VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter); ++ ++BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); ++#if CFG_P2P_LEGACY_COEX_REVISE ++BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* We don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this to guarantee the same member order in different structures ++ * to simply handling effort in some functions. ++ */ ++static inline VOID cnmMsgDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == 0); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == OFFSET_OF(MSG_CH_RECOVER_T, rMsgHdr)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucNetTypeIndex) == ++ OFFSET_OF(MSG_CH_RECOVER_T, ucNetTypeIndex)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucTokenID) == OFFSET_OF(MSG_CH_RECOVER_T, ucTokenID)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucPrimaryChannel) == ++ OFFSET_OF(MSG_CH_RECOVER_T, ucPrimaryChannel)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfSco) == OFFSET_OF(MSG_CH_RECOVER_T, eRfSco)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfBand) == OFFSET_OF(MSG_CH_RECOVER_T, eRfBand)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eReqType) == OFFSET_OF(MSG_CH_RECOVER_T, eReqType)); ++ ++} ++#endif /* _lint */ ++ ++#endif /* _CNM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h +new file mode 100644 +index 000000000000..c8f25b1b29a9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h +@@ -0,0 +1,1164 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_mem.h#1 ++*/ ++ ++/*! \file "cnm_mem.h" ++ \brief In this file we define the structure of the control unit of ++ packet buffer and MGT/MSG Memory Buffer. ++*/ ++ ++/* ++** Log: cnm_mem.h ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Resize the Secondary Device Type array when WiFi Direct is enabled. ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the protected while at P2P start GO, and skip some security check . ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 11 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add per STA flow control when STA is in PS mode ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 29 2010 cm.chang ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for ++ * initial TX rate selection of auto-rate algorithm ++ * Sync RCPI of STA_REC to FW as reference of initial TX rate ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD ++ * when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 12 2010 cp.wu ++ * ++ * SAA will take a record for tracking request sequence number. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support state of STA record change from 1 to 1 ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error for P2P related defination. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P related fields. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [BORA00000678] [MT6620]WiFi LP integration ++ * 1. add u8TimeStamp in MSDU_INFO ++ * 2. move fgIsRxTSFUpdated/fgIsTxTSFUpdated from static to BSS_INFO ++ * 3. add new member for supporting PM in STA_RECORD, which is for AP PS mode ++ * ++ * 05 31 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support checking of duplicated buffer free ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set ++ * ++ * 05 19 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fixed MAC RX Desc be overwritten issue ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 05 10 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support Rx header translation for A-MSDU subframe ++ * ++ * 05 07 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * add more sanity check about setting timer ++ * ++ * 04 29 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * modify the compiling flag for RAM usage ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Modified some MQM-related data structures (SN counter, TX/RX BA table) ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Added new TX/RX BA tables in STA_REC ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 04 09 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * [BORA00000644] WiFi phase 4 integration ++ * Added per-TID SN cache in STA_REC ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support power control ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 11 2010 yuche.tsai ++ * [BORA00000343][MT6620] Emulation For TX ++ * . ++ * ++ * 03 05 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove Emulation definition ++ * ++ * 03 04 2010 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * eliminate HIF_EMULATION in cnm_mem.h ++ * ++ * 03 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add cnmStaRecChangeState() declaration. ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove compiling warning for some emulation flags ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * To store field AMPDU Parameters in STA_REC ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsWmmSupported in STA_RECORD_T. ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsUapsdSupported in STA_RECORD_T ++ * ++ * 02 13 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added arTspecTable in STA_REC for TSPEC management ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable mgmt buffer debug by default ++ * ++ * 02 12 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added BUFFER_SOURCE_BCN ++ * ++ * 02 10 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Renamed MSDU_INFO.ucFixedRateIndex as MSDU_INFO.ucFixedRateCode ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 02 02 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added SN info in MSDU_INFO_T ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h ++ * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem ++ * 3) use cnmMemAlloc() instead to allocate SRAM buffer ++ * ++ * 12 31 2009 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1) surpress debug message emitted from hal_hif.c ++ * 2) add two set of field for recording buffer process time ++ * ++ * 12 31 2009 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1. move wifi task initialization from wifi_task.c(rom) to wifi_init.c (TCM) for integrating F/W download later ++ * * * * * 2. WIFI_Event_Dispatcher() prototype changed to return to suspend mode from normal operation mode ++ * * * * * 2. HIF emulation logic revised ++ * ++ * 12 29 2009 yuche.tsai ++ * [BORA00000343][MT6620] Emulation For TX ++ * .Using global buffer declaring by SD1 instead of using another one. ++ * ++ * 12 25 2009 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) ++ * * MQM: BA handling ++ * * TXM: Macros updates ++ * * RXM: Macros/Duplicate Removal updates ++ * ++ * 12 24 2009 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * 12 23 2009 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * allocating SRAM for emulation purpose by ruducing MEM_BANK3_BUF_SZ ++ * ++ * 12 21 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove individual DATA_BUF_BLOCK_NUM definition for emulation compiling flagsu1rwduu`wvpghlqg|fh+fmdkb ++ * ++ * 12 21 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support several data buffer banks. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * .For new FPGA memory size ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * 12 17 2009 george.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 17 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Modified the DATA_BLOCK_SIZE from 1620 to 2048 ++ * ++ * Dec 16 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_SEC_EMULATION flag ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add HT cap to sta record ++ * ++ * Dec 9 2009 mtk02752 ++ * [BORA00000368] Integrate HIF part into BORA ++ * add cnmDataPktFree() for emulation loopback purpose ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * add the buffer for key handshake 1x and cmd key order issue ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * move the tx call back function proto type to typedef.h ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add cnmGetStaRecByAddress() and modify variable in STA_RECORD_T ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * rename the port block flag ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add variables to STA_RECORD_T for assoc/auth ++ * ++ * Nov 23 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Fixed the value of STA_WAIT_QUEUE_NUM (from 7 to 5) ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Removed u2FrameLength from SW_RFB ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Fixed indenting ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Updated MSDU_INFO and SW_RFB ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * update the variable for security ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * remove the variable to make the compiler ok ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * add the variable for security module ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo in define of MSG_BUF_BLOCK_SIZE ++ * ++ * Nov 13 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Let typedef STA_REC_T precede typedef MSDU_INFO_T and SW_RFB_T ++ * ++ * Nov 13 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Modified MSDU_INFO and STA_REC for TXM and MQM ++ * ++ * Nov 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename STA_REC_T to STA_RECORD_T and add ucIndex member ++ * ++ * Nov 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Make sure ucBufferSource the same offset in MSDU_INFO and SW_RFB ++ * ++ * Nov 6 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Nov 5 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update comment ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add draft content of MSDU_INFO_T and SW_RFB_T ++ * ++ * Oct 30 2009 mtk01084 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * Oct 21 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_RX_EMULATION flag ++ * ++ * Oct 20 2009 mtk01426 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 9 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added field ucTC to MSDU_INFO_T and field pucHifRxPacket to SW_RFB_T ++ * ++ * Oct 8 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_MEM_H ++#define _CNM_MEM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#ifndef POWER_OF_2 ++#define POWER_OF_2(n) BIT(n) ++#endif ++ ++/* Size of a basic management buffer block in power of 2 */ ++#define MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2 7 /* 7 to the power of 2 = 128 */ ++#define MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2 5 /* 5 to the power of 2 = 32 */ ++ ++/* Size of a basic management buffer block */ ++#define MGT_BUF_BLOCK_SIZE POWER_OF_2(MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++#define MSG_BUF_BLOCK_SIZE POWER_OF_2(MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++ ++/* Total size of (n) basic management buffer blocks */ ++#define MGT_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++#define MSG_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) ++ ++/* Number of management buffer block */ ++#define MAX_NUM_OF_BUF_BLOCKS 32 /* Range: 1~32 */ ++ ++/* Size of overall management frame buffer */ ++#define MGT_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MGT_BUF_BLOCK_SIZE) ++#define MSG_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MSG_BUF_BLOCK_SIZE) ++ ++/* STA_REC related definitions */ ++#define STA_REC_INDEX_BMCAST 0xFF ++#define STA_REC_INDEX_NOT_FOUND 0xFE ++#define STA_WAIT_QUEUE_NUM 5 /* Number of SW queues in each STA_REC: AC0~AC4 */ ++#define SC_CACHE_INDEX_NUM 5 /* Number of SC caches in each STA_REC: AC0~AC4 */ ++ ++/* P2P related definitions */ ++#ifdef CFG_ENABLE_WIFI_DIRECT ++/* Moved from p2p_fsm.h */ ++#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ ++#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if ((MAX_NUM_OF_BUF_BLOCKS > 32) || (MAX_NUM_OF_BUF_BLOCKS <= 0)) ++#error > #define MAX_NUM_OF_MGT_BUF_BLOCKS : Out of boundary ! ++#elif MAX_NUM_OF_BUF_BLOCKS > 16 ++typedef UINT_32 BUF_BITMAP; ++#elif MAX_NUM_OF_BUF_BLOCKS > 8 ++typedef UINT_16 BUF_BITMAP; ++#else ++typedef UINT_8 BUF_BITMAP; ++#endif /* MAX_NUM_OF_MGT_BUF_BLOCKS */ ++ ++/* Control variable of TX management memory pool */ ++typedef struct _BUF_INFO_T { ++ PUINT_8 pucBuf; ++ ++#if CFG_DBG_MGT_BUF ++ UINT_32 u4AllocCount; ++ UINT_32 u4FreeCount; ++ UINT_32 u4AllocNullCount; ++#endif /* CFG_DBG_MGT_BUF */ ++ ++ BUF_BITMAP rFreeBlocksBitmap; ++ UINT_8 aucAllocatedBlockNum[MAX_NUM_OF_BUF_BLOCKS]; ++} BUF_INFO_T, *P_BUF_INFO_T; ++ ++/* Wi-Fi divides RAM into three types ++ * MSG: Mailbox message (Small size) ++ * BUF: HW DMA buffers (HIF/MAC) ++ */ ++typedef enum _ENUM_RAM_TYPE_T { ++ RAM_TYPE_MSG = 0, ++ RAM_TYPE_BUF ++} ENUM_RAM_TYPE_T, P_ENUM_RAM_TYPE_T; ++ ++typedef enum _ENUM_BUFFER_SOURCE_T { ++ BUFFER_SOURCE_HIF_TX0 = 0, ++ BUFFER_SOURCE_HIF_TX1, ++ BUFFER_SOURCE_MAC_RX, ++ BUFFER_SOURCE_MNG, ++ BUFFER_SOURCE_BCN, ++ BUFFER_SOURCE_NUM ++} ENUM_BUFFER_SOURCE_T, *P_ENUM_BUFFER_SOURCE_T; ++ ++typedef enum _ENUM_SEC_STATE_T { ++ SEC_STATE_INIT, ++ SEC_STATE_INITIATOR_PORT_BLOCKED, ++ SEC_STATE_RESPONDER_PORT_BLOCKED, ++ SEC_STATE_CHECK_OK, ++ SEC_STATE_SEND_EAPOL, ++ SEC_STATE_SEND_DEAUTH, ++ SEC_STATE_COUNTERMEASURE, ++ SEC_STATE_NUM ++} ENUM_SEC_STATE_T; ++ ++typedef struct _TSPEC_ENTRY_T { ++ UINT_8 ucStatus; ++ UINT_8 ucToken; /* Dialog Token in ADDTS_REQ or ADDTS_RSP */ ++ UINT_16 u2MediumTime; ++ UINT_32 u4TsInfo; ++ /* PARAM_QOS_TS_INFO rParamTsInfo; */ ++ /* Add other retained QoS parameters below */ ++} TSPEC_ENTRY_T, *P_TSPEC_ENTRY_T, TSPEC_TABLE_ENTRY_T, *P_TSPEC_TABLE_ENTRY_T; ++ ++typedef struct _SEC_INFO_T { ++ ++ ENUM_SEC_STATE_T ePreviousState; ++ ENUM_SEC_STATE_T eCurrentState; ++ ++ BOOLEAN fg2nd1xSend; ++ BOOLEAN fgKeyStored; ++ ++ UINT_8 aucStoredKey[64]; ++ ++ BOOLEAN fgAllowOnly1x; ++} SEC_INFO_T, *P_SEC_INFO_T; ++ ++#define MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS 3 ++ ++#define UPDATE_BSS_RSSI_INTERVAL_SEC 3 /* Seconds */ ++ ++/* Fragment information structure */ ++typedef struct _FRAG_INFO_T { ++ UINT_16 u2NextFragSeqCtrl; ++ PUINT_8 pucNextFragStart; ++ P_SW_RFB_T pr1stFrag; ++ OS_SYSTIME rReceiveLifetimeLimit; /* The receive time of 1st fragment */ ++} FRAG_INFO_T, *P_FRAG_INFO_T; ++ ++typedef struct _STAT_CNT_INFO_FW_T { ++ UINT32 u4NumOfTx; /* number of packets sent from host */ ++ UINT32 u4NumOfTxOK; /* number of packets sent to air OK */ ++ UINT32 u4NumOfTxRetry; /* number of packets sent to air RETRY */ ++ UINT32 u4TxDoneAirTimeMax; /* maximum tx done air time */ ++ ++ UINT32 u4NumOfPtiRspTxOk; /* number of PTI RSP sent to air OK */ ++ UINT32 u4NumOfPtiRspTxErr; /* number of PTI RSP sent to air ERROR */ ++ ++ UINT32 u4NumOfTxErr; /* number of packets sent to air ERROR */ ++ ++ UINT32 u4NumOfRx; /* number of received packets */ ++ UINT32 u4NumOfPtiRspRx; /* number of PTI RSP rcv */ ++ ++#define STAT_CNT_INFO_TX_ERR_FLUSHED 0x00000001 ++#define STAT_CNT_INFO_TX_ERR_AGE_TIMEOUT 0x00000002 ++#define STAT_CNT_INFO_TX_ERR_MPDU 0x00000004 ++#define STAT_CNT_INFO_TX_ERR_RTS 0x00000010 ++#define STAT_CNT_INFO_TX_ERR_LIFETIME 0x00000020 ++#define STAT_CNT_INFO_TX_ERR_UNKNOWN 0x80000000 ++ UINT32 u4TxErrBitmap; /* TX error type */ ++ ++#define STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM 10 /* TX OK history */ ++ UINT8 aucTxRateOkHis[STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM][2]; ++ UINT32 u4TxRateOkHisId; ++ ++#define STAT_CNT_INFO_MAX_RATE_ID (32) /* MCS0 ~ MCS31 */ ++ UINT32 aucTxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; ++ UINT32 aucRxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; ++ ++ UINT8 aucStateHis[100][3]; /* State history */ ++ UINT32 u4StateHisId; /* history ID */ ++} STAT_CNT_INFO_FW_T; ++ ++typedef struct _STAT_CNT_INFO_DRV_T { ++ ++ UINT32 u4NumOfTxFromOs; /* number of packets sent from OS */ ++ UINT32 u4NumOfTxQueFull; /* number of packets dropped due to queue full */ ++ UINT32 u4NumOfTxToFw; /* number of packets sent to firmware */ ++ ++ STAT_CNT_INFO_FW_T rFw; ++} STAT_CNT_INFO_DRV_T; ++ ++/* Define STA record structure */ ++struct _STA_RECORD_T { ++ LINK_ENTRY_T rLinkEntry; ++ UINT_8 ucIndex; /* Not modify it except initializing */ ++ ++ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; /* MAC address */ ++ ++ /* SAA/AAA */ ++ ENUM_AA_STATE_T eAuthAssocState; /* Store STATE Value used in SAA/AAA */ ++ UINT_8 ucAuthAssocReqSeqNum; ++ ++ ENUM_STA_TYPE_T eStaType; /* Indicate the role of this STA in ++ * the network (for example, P2P GO) ++ */ ++ ++ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ ++ ++ UINT_8 ucStaState; /* STATE_1,2,3 */ ++ ++ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer ++ * (may deduced from received BSS_DESC_T) ++ */ ++ UINT_8 ucDesiredPhyTypeSet; /* The match result by AND operation of peer's ++ * PhyTypeSet and ours. ++ */ ++ BOOLEAN fgHasBasicPhyType; /* A flag to indicate a Basic Phy Type which ++ * is used to generate some Phy Attribute IE ++ * (e.g. capability, MIB) during association. ++ */ ++ UINT_8 ucNonHTBasicPhyType; /* The Basic Phy Type chosen among the ++ * ucDesiredPhyTypeSet. ++ */ ++ ++ UINT_16 u2CapInfo; /* For Infra Mode, to store Capability Info. from Association Resp(SAA). ++ * For AP Mode, to store Capability Info. from Association Req(AAA). ++ */ ++ UINT_16 u2AssocId; /* For Infra Mode, to store AID from Association Resp(SAA). ++ * For AP Mode, to store the Assigned AID(AAA). ++ */ ++ ++ UINT_16 u2ListenInterval; /* Listen Interval from STA(AAA) */ ++ ++ UINT_16 u2DesiredNonHTRateSet; /* Our Current Desired Rate Set after ++ * match with STA's Operational Rate Set ++ */ ++ ++ UINT_16 u2OperationalRateSet; /* Operational Rate Set of peer BSS */ ++ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of peer BSS */ ++ ++ BOOLEAN fgIsMerging; /* For IBSS Mode, to indicate that Merge is ongoing */ ++ ++ BOOLEAN fgDiagnoseConnection; /* For Infra/AP Mode, to diagnose the Connection with ++ * this peer by sending ProbeReq/Null frame */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* 802.11n HT capabilities when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) is true */ ++ /* They have the same definition with fields of information element */ ++ /*------------------------------------------------------------------------------------------*/ ++ UINT_8 ucMcsSet; /* MCS0~7 rate set of peer BSS */ ++ BOOLEAN fgSupMcs32; /* MCS32 is supported by peer BSS */ ++ UINT_16 u2HtCapInfo; /* HT cap info field by HT cap IE */ ++ UINT_8 ucAmpduParam; /* Field A-MPDU Parameters in HT cap IE */ ++ UINT_16 u2HtExtendedCap; /* HT extended cap field by HT cap IE */ ++ UINT_32 u4TxBeamformingCap; /* TX beamforming cap field by HT cap IE */ ++ UINT_8 ucAselCap; /* ASEL cap field by HT cap IE */ ++ ++ UINT_8 ucRCPI; /* RCPI of peer */ ++ ++ UINT_8 ucDTIMPeriod; /* Target BSS's DTIM Period, we use this ++ * value for setup Listen Interval ++ * TODO(Kevin): TBD ++ */ ++ UINT_8 ucAuthAlgNum; /* For Infra/AP Mode, the Auth Algorithm Num used in Authentication(SAA/AAA) */ ++ BOOLEAN fgIsReAssoc; /* For Infra/AP Mode, to indicate ReAssoc Frame was in used(SAA/AAA) */ ++ ++ UINT_8 ucTxAuthAssocRetryCount; /* For Infra Mode, the Retry Count of TX Auth/Assod Frame(SAA) */ ++ UINT_8 ucTxAuthAssocRetryLimit; /* For Infra Mode, the Retry Limit of TX Auth/Assod Frame(SAA) */ ++ ++ UINT_16 u2StatusCode; /* Status of Auth/Assoc Req */ ++ UINT_16 u2ReasonCode; /* Reason that been Deauth/Disassoc */ ++ ++ P_IE_CHALLENGE_TEXT_T prChallengeText; /* Point to an allocated buffer for storing Challenge Text ++ * for Shared Key Authentication ++ */ ++ ++ TIMER_T rTxReqDoneOrRxRespTimer; /* For Infra Mode, a timer used to send a timeout event ++ * while waiting for TX request done or RX response. ++ */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* Power Management related fields (for STA/ AP/ P2P/ BOW power saving mode) */ ++ /*------------------------------------------------------------------------------------------*/ ++ BOOLEAN fgSetPwrMgtBit; /* For Infra Mode, to indicate that outgoing frame need toggle ++ * the Pwr Mgt Bit in its Frame Control Field. ++ */ ++ ++ BOOLEAN fgIsInPS; /* For AP Mode, to indicate the client PS state(PM). ++ * TRUE: In PS Mode; FALSE: In Active Mode. */ ++ ++ BOOLEAN fgIsInPsPollSP; /* For Infra Mode, to indicate we've sent a PS POLL to AP and start ++ * the PS_POLL Service Period(LP) ++ */ ++ ++ BOOLEAN fgIsInTriggerSP; /* For Infra Mode, to indicate we've sent a Trigger Frame to AP and start ++ * the Delivery Service Period(LP) ++ */ ++ ++ UINT_8 ucBmpDeliveryAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ ++ ++ UINT_8 ucBmpTriggerAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ ++ ++ UINT_8 ucUapsdSp; /* Max SP length */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ ++ BOOLEAN fgIsRtsEnabled; ++ ++ OS_SYSTIME rUpdateTime; /* (4) System Timestamp of Successful TX and RX */ ++ ++ OS_SYSTIME rLastJoinTime; /* (4) System Timestamp of latest JOIN process */ ++ ++ UINT_8 ucJoinFailureCount; /* Retry Count of JOIN process */ ++ ++ LINK_T arStaWaitQueue[STA_WAIT_QUEUE_NUM]; /* For TXM to defer pkt forwarding to MAC TX DMA */ ++ ++ UINT_16 au2CachedSeqCtrl[TID_NUM + 1]; /* Duplicate removal for HT STA on a per-TID basis ++ * ("+1" is for MMPDU and non-QoS) ++ */ ++ ++#if 0 ++ /* RXM */ ++ P_RX_BA_ENTRY_T aprRxBaTable[TID_NUM]; ++ ++ /* TXM */ ++ P_TX_BA_ENTRY_T aprTxBaTable[TID_NUM]; ++#endif ++ ++ FRAG_INFO_T rFragInfo[MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS]; ++ ++ SEC_INFO_T rSecInfo; /* The security state machine */ ++ ++ BOOLEAN fgPortBlock; /* The 802.1x Port Control flag */ ++ ++ BOOLEAN fgTransmitKeyExist; /* Unicast key exist for this STA */ ++ ++ UINT_8 ucWTEntry; ++ ++ BOOLEAN fgTxAmpduEn; /* Enable TX AMPDU for this Peer */ ++ BOOLEAN fgRxAmpduEn; /* Enable RX AMPDU for this Peer */ ++ ++ PUINT_8 pucAssocReqIe; ++ UINT_16 u2AssocReqIeLen; ++ /*------------------------------------------------------------------------------------------*/ ++ /* WMM/QoS related fields */ ++ /*------------------------------------------------------------------------------------------*/ ++ BOOLEAN fgIsQoS; /* If the STA is associated as a QSTA or QAP (for TX/RX) */ ++ BOOLEAN fgIsWmmSupported; /* If the peer supports WMM, set to TRUE (for association) */ ++ BOOLEAN fgIsUapsdSupported; /* Set according to the scan result (for association) */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* P2P related fields */ ++ /*------------------------------------------------------------------------------------------*/ ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_8 u2DevNameLen; ++ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; ++ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ ++ UINT_16 u2ConfigMethods; ++ ++ UINT_8 ucDeviceCap; ++ ++ UINT_8 ucSecondaryDevTypeCount; ++ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; ++ ++ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT]; ++#endif /* CFG_SUPPORT_P2P */ ++ ++ /*------------------------------------------------------------------------------------------*/ ++ /* QM related fields */ ++ /*------------------------------------------------------------------------------------------*/ ++ ++ UINT_8 ucFreeQuota; /* Per Sta flow controal. Valid when fgIsInPS is TRUE. ++ Change it for per Queue flow control */ ++ /* UINT_8 aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES]; */ /* used in future */ ++ UINT_8 ucFreeQuotaForDelivery; ++ UINT_8 ucFreeQuotaForNonDelivery; ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE && CFG_ENABLE_PER_STA_STATISTICS ++ UINT_32 u4TotalTxPktsNumber; ++ UINT_32 u4TotalTxPktsTime; ++ UINT_32 u4TotalTxPktsHifTime; ++ ++ UINT_32 u4MaxTxPktsTime; ++ UINT_32 u4MaxTxPktsHifTime; ++ ++ UINT_32 u4ThresholdCounter; ++ UINT_32 u4EnqeueuCounter; ++ UINT_32 u4DeqeueuCounter; ++ UINT_32 u4PrevIntCount; ++ UINT_32 u4ThisIntCount; ++ UINT_32 u4NoTcResource; ++#endif ++ ++#if 1 ++ /*------------------------------------------------------------------------------------------*/ ++ /* To be removed, this is to make que_mgt compilation success only */ ++ /*------------------------------------------------------------------------------------------*/ ++ /* When this STA_REC is in use, set to TRUE. */ ++ BOOLEAN fgIsValid; ++ ++ /* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ ++ QUE_T arTxQueue[NUM_OF_PER_STA_TX_QUEUES]; ++ ++ /* When this STA is in PS Mode, set to TRUE. */ ++ /* BOOLEAN fgIsPS; */ ++ ++ /* When this STA enters Power-Saving, FW will notify the driver with a Session ID */ ++ UINT_8 ucPsSessionID; ++ ++ BOOLEAN fgIsAp; ++ ++ /* Reorder Parameter reference table */ ++ P_RX_BA_ENTRY_T aprRxReorderParamRefTbl[CFG_RX_MAX_BA_TID_NUM]; ++#endif ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++ TIMINGMSMT_PARAM_T rWNMTimingMsmt; ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ ++ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ ++ ++ BOOLEAN flgTdlsIsInitiator; /* TRUE: the peer is the initiator */ ++ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ ++ BOOLEAN fgTdlsInSecurityMode; /* TRUE: security mode */ ++ PARAM_KEY_T rTdlsKeyTemp; /* temp to queue the key information */ ++ ++#define TDLS_SETUP_TIMEOUT_SEC 5 /* unit: second */ ++ OS_SYSTIME rTdlsSetupStartTime; /* time when link setup is started */ ++ ++ OS_SYSTIME rTdlsTxQuotaEmptyTime; /* time when TX quota is 0 */ ++ ++ STAT_CNT_INFO_DRV_T rTdlsStatistics; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#if (CFG_SUPPORT_STATISTICS == 1) ++#define STATS_ENV_TIMEOUT_SEC 10 /* unit: second */ ++ OS_SYSTIME rStatsEnvTxPeriodLastTime; ++ ++#define STATS_ENV_TX_CNT_REPORT_TRIGGER 2500 /* 6Mbps */ ++#define STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC 5 /* unit: second */ ++ OS_SYSTIME rStatsEnvTxLastTime; ++ UINT32 u4StatsEnvTxCnt; ++ ++ UINT32 u4NumOfNoTxQuota; ++ ++ UINT32 u4RxReorderFallAheadCnt; ++ UINT32 u4RxReorderFallBehindCnt; ++ UINT32 u4RxReorderHoleCnt; ++ UINT32 u4RxReorderHoleTimeoutCnt; ++ ++ UINT32 u4StatsRxPassToOsCnt; ++ ++ /* delay from HIF to pass to OS: us */ ++#define STATS_STAY_INT_BYTE_THRESHOLD 500 ++ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; ++ ++ UINT8 ucStatsGenDisplayCnt; ++#endif /* CFG_SUPPORT_STATISTICS */ ++}; ++ ++#if 0 ++/* use nic_tx.h instead */ ++/* MSDU_INFO and SW_RFB structure */ ++typedef struct _MSDU_INFO_T { ++ ++ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ ++ ++ LINK_ENTRY_T rLinkEntry; ++ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ ++ ++ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ ++ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ ++ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ ++ UINT_8 ucTID; /* Traffic Identification */ ++ ++ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ ++ UINT_8 ucMacHeaderLength; ++ UINT_16 u2PayloadLength; ++ PUINT_8 pucMacHeader; /* 802.11 header */ ++ PUINT_8 pucPayload; /* 802.11 payload */ ++ ++ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ ++ P_STA_RECORD_T prStaRec; ++ ++#if CFG_PROFILE_BUFFER_TRACING ++ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; ++ UINT_32 rActivityTime[2]; ++#endif ++#if DBG && CFG_BUFFER_FREE_CHK ++ BOOLEAN fgBufferInSource; ++#endif ++ ++ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ ++ ++ /* 4 -----------------------Non-Common ------------------------- */ ++ /* TODO: move flags to ucControlFlag */ ++ ++ BOOLEAN fgIs1xFrame; /* Set to TRUE for 802.1x frame */ ++ ++ /* TXM: For TX Done handling, callback function & parameter (5) */ ++ BOOLEAN fgIsTxFailed; /* Set to TRUE if transmission failure */ ++ ++ PFN_TX_DONE_HANDLER pfTxDoneHandler; ++ ++ UINT_64 u8TimeStamp; /* record the TX timestamp */ ++ ++ /* TXM: For PS forwarding control (per-STA flow control) */ ++ UINT_8 ucPsForwardingType; /* Delivery-enabled, non-delivery-enabled, non-PS */ ++ UINT_8 ucPsSessionID; /* The Power Save session id for PS forwarding control */ ++ ++ /* TXM: For MAC TX DMA operations */ ++ UINT_8 ucMacTxQueIdx; /* MAC TX queue: AC0-AC6, BCM, or BCN */ ++ BOOLEAN fgNoAck; /* Set to true if Ack is not required for this packet */ ++ BOOLEAN fgBIP; /* Set to true if BIP is used for this packet */ ++ UINT_8 ucFragTotalCount; ++ UINT_8 ucFragFinishedCount; ++ UINT_16 u2FragThreshold; /* Fragmentation threshold without WLAN Header & FCS */ ++ BOOLEAN fgFixedRate; /* If a fixed rate is used, set to TRUE. */ ++ UINT_8 ucFixedRateCode; /* The rate code copied to MAC TX Desc */ ++ UINT_8 ucFixedRateRetryLimit; /* The retry limit when a fixed rate is used */ ++ BOOLEAN fgIsBmcQueueEnd; /* Set to true if this packet is the end of BMC */ ++ ++ /* TXM: For flushing ACL frames */ ++ UINT_16 u2PalLLH; /* 802.11 PAL LLH */ ++ /* UINT_16 u2LLH; */ ++ UINT_16 u2ACLSeq; /* u2LLH+u2ACLSeq for AM HCI flush ACL frame */ ++ ++ /* TXM for retransmitting a flushed packet */ ++ BOOLEAN fgIsSnAssigned; ++ UINT_16 u2SequenceNumber; /* To remember the Sequence Control field of this MPDU */ ++ ++} MSDU_INFO_T, *P_MSDU_INFO_T; ++#endif ++ ++#if 0 ++/* nic_rx.h */ ++typedef struct _SW_RFB_T { ++ ++ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ ++ ++ LINK_ENTRY_T rLinkEntry; ++ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ ++ ++ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ ++ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ ++ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ ++ UINT_8 ucTID; /* Traffic Identification */ ++ ++ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ ++ UINT_8 ucMacHeaderLength; ++ UINT_16 u2PayloadLength; ++ PUINT_8 pucMacHeader; /* 802.11 header */ ++ PUINT_8 pucPayload; /* 802.11 payload */ ++ ++ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ ++ P_STA_RECORD_T prStaRec; ++ ++#if CFG_PROFILE_BUFFER_TRACING ++ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; ++ UINT_32 rActivityTime[2]; ++#endif ++#if DBG && CFG_BUFFER_FREE_CHK ++ BOOLEAN fgBufferInSource; ++#endif ++ ++ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ ++ ++ /* 4 -----------------------Non-Common ------------------------- */ ++ ++ /* For composing the HIF RX Header (TODO: move flags to ucControlFlag) */ ++ PUINT_8 pucHifRxPacket; /* Pointer to the Response packet to HIF RX0 or RX1 */ ++ UINT_16 u2HifRxPacketLength; ++ UINT_8 ucHeaderOffset; ++ UINT_8 ucHifRxPortIndex; ++ ++ UINT_16 u2SequenceControl; ++ BOOLEAN fgIsA4Frame; /* (For MAC RX packet parsing) set to TRUE if 4 addresses are present */ ++ BOOLEAN fgIsBAR; ++ BOOLEAN fgIsQoSData; ++ BOOLEAN fgIsAmsduSubframe; /* Set to TRUE for A-MSDU Subframe */ ++ ++ /* For HIF RX DMA Desc */ ++ BOOLEAN fgTUChecksumCheckRequired; ++ BOOLEAN fgIPChecksumCheckRequired; ++ UINT_8 ucEtherTypeOffset; ++ ++} SW_RFB_T, *P_SW_RFB_T; ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++P_MSDU_INFO_T cnmMgtPktAlloc(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); ++ ++VOID cnmMgtPktFree(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID cnmMemInit(IN P_ADAPTER_T prAdapter); ++ ++PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length); ++ ++VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory); ++ ++VOID cnmStaRecInit(IN P_ADAPTER_T prAdapter); ++ ++VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter); ++ ++P_STA_RECORD_T cnmStaRecAlloc(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex); ++ ++VOID cnmStaRecFree(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSyncToChip); ++ ++VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip); ++ ++P_STA_RECORD_T cnmGetStaRecByIndex(IN P_ADAPTER_T prAdapter, IN UINT_8 ucIndex); ++ ++P_STA_RECORD_T cnmGetStaRecByAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex, IN UINT_8 aucPeerMACAddress[]); ++ ++VOID cnmStaRecResetStatus(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++VOID cnmStaRecChangeState(IN P_ADAPTER_T prAdapter, IN OUT P_STA_RECORD_T prStaRec, IN UINT_8 ucNewState); ++ ++P_STA_RECORD_T ++cnmStaTheTypeGet(P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this for porting driver to different RTOS. ++ */ ++static inline VOID cnmMemDataTypeCheck(VOID) ++{ ++#if 0 ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == 0); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == OFFSET_OF(SW_RFB_T, rLinkEntry)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucBuffer) == OFFSET_OF(SW_RFB_T, pucBuffer)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucBufferSource) == OFFSET_OF(SW_RFB_T, ucBufferSource)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucMacHeader) == OFFSET_OF(SW_RFB_T, pucMacHeader)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucMacHeaderLength) == ++ OFFSET_OF(SW_RFB_T, ucMacHeaderLength)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucPayload) == OFFSET_OF(SW_RFB_T, pucPayload)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, u2PayloadLength) == OFFSET_OF(SW_RFB_T, u2PayloadLength)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, prStaRec) == OFFSET_OF(SW_RFB_T, prStaRec)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucNetworkTypeIndex) == ++ OFFSET_OF(SW_RFB_T, ucNetworkTypeIndex)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTID) == OFFSET_OF(SW_RFB_T, ucTID)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgIs802_11Frame) == OFFSET_OF(SW_RFB_T, fgIs802_11Frame)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucControlFlag) == OFFSET_OF(SW_RFB_T, ucControlFlag)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rArrivalTime) == OFFSET_OF(SW_RFB_T, rArrivalTime)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTC) == OFFSET_OF(SW_RFB_T, ucTC)); ++ ++#if CFG_PROFILE_BUFFER_TRACING ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, eActivity[0]) == OFFSET_OF(SW_RFB_T, eActivity[0])); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rActivityTime[0]) == ++ OFFSET_OF(SW_RFB_T, rActivityTime[0])); ++#endif ++ ++#if DBG && CFG_BUFFER_FREE_CHK ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgBufferInSource) == ++ OFFSET_OF(SW_RFB_T, fgBufferInSource)); ++#endif ++ ++ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(STA_RECORD_T, rLinkEntry) == 0); ++ ++ return; ++#endif ++} ++#endif /* _lint */ ++ ++#endif /* _CNM_MEM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h +new file mode 100644 +index 000000000000..cc5d0fa1adfc +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h +@@ -0,0 +1,169 @@ ++/* ++** Id: @(#) ++*/ ++ ++/*! \file "cnm_scan.h" ++ \brief ++ ++*/ ++ ++/* ++** Log: cnm_scan.h ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * remove unused definitions. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function prototype of cnmScanInit() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_SCAN_H ++#define _CNM_SCAN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define SCN_CHANNEL_DWELL_TIME_MIN_MSEC 12 ++#define SCN_CHANNEL_DWELL_TIME_EXT_MSEC 98 ++ ++#define SCN_TOTAL_PROBEREQ_NUM_FOR_FULL 3 ++#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_FULL 1 ++ ++#define SCN_TOTAL_PROBEREQ_NUM_FOR_PARTIAL 2 ++#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_PARTIAL 1 ++ ++#define SCN_INTERLACED_CHANNEL_GROUPS_NUM 3 /* Used by partial scan */ ++ ++#define SCN_PARTIAL_SCAN_NUM 3 ++ ++#define SCN_PARTIAL_SCAN_IDLE_MSEC 100 ++ ++#define MAXIMUM_OPERATION_CHANNEL_LIST 46 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* The type of Scan Source */ ++typedef enum _ENUM_SCN_REQ_SOURCE_T { ++ SCN_REQ_SOURCE_HEM = 0, ++ SCN_REQ_SOURCE_NET_FSM, ++ SCN_REQ_SOURCE_ROAMING, /* ROAMING Module is independent of AIS FSM */ ++ SCN_REQ_SOURCE_OBSS, /* 2.4G OBSS scan */ ++ SCN_REQ_SOURCE_NUM ++} ENUM_SCN_REQ_SOURCE_T, *P_ENUM_SCN_REQ_SOURCE_T; ++ ++typedef enum _ENUM_SCAN_PROFILE_T { ++ SCAN_PROFILE_FULL = 0, ++ SCAN_PROFILE_PARTIAL, ++ SCAN_PROFILE_VOIP, ++ SCAN_PROFILE_FULL_2G4, ++ SCAN_PROFILE_NUM ++} ENUM_SCAN_PROFILE_T, *P_ENUM_SCAN_PROFILE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if 0 ++VOID cnmScanInit(VOID); ++ ++VOID cnmScanRunEventScanRequest(IN P_MSG_HDR_T prMsgHdr); ++ ++BOOLEAN cnmScanRunEventScanAbort(IN P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmScanProfileSelection(VOID); ++ ++VOID cnmScanProcessStart(VOID); ++ ++VOID cnmScanProcessStop(VOID); ++ ++VOID cnmScanRunEventReqAISAbsDone(IN P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmScanRunEventCancelAISAbsDone(IN P_MSG_HDR_T prMsgHdr); ++ ++VOID cnmScanPartialScanTimeout(UINT_32 u4Param); ++ ++VOID cnmScanRunEventScnFsmComplete(IN P_MSG_HDR_T prMsgHdr); ++#endif ++ ++#endif /* _CNM_SCAN_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h +new file mode 100644 +index 000000000000..a2ed9cd02fed +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h +@@ -0,0 +1,235 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_timer.h#1 ++*/ ++ ++/*! \file cnm_timer.h ++ \brief Declaration of timer obj and related timer macro for setup time out ++ event. ++ ++ In this file we declare the timer object and provide several macro for ++ Protocol functional blocks to setup their own time out event. ++*/ ++ ++/* ++** Log: cnm_timer.h ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Return timer token back to COS when entering wait off state ++ * ++ * 01 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb ++ * ++ * 01 06 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix system time is 32KHz instead of 1ms ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * add the copy time function ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix LINT warnning ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++#ifndef _CNM_TIMER_H ++#define _CNM_TIMER_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#undef MSEC_PER_SEC ++#define MSEC_PER_SEC 1000 ++#undef USEC_PER_MSEC ++#define USEC_PER_MSEC 1000 ++#define USEC_PER_TU 1024 /* microsecond */ ++ ++#define MSEC_PER_MIN (60 * MSEC_PER_SEC) ++ ++#define MGMT_MAX_TIMEOUT_INTERVAL ((UINT_32)0x7fffffff) ++ ++#define WAKE_LOCK_MAX_TIME 5 /* Unit: sec */ ++ ++/* If WAKE_LOCK_MAX_TIME is too large, the whole system may always keep awake ++ * because of periodic timer of OBSS scanning ++ */ ++#if (WAKE_LOCK_MAX_TIME >= OBSS_SCAN_MIN_INTERVAL) ++#error WAKE_LOCK_MAX_TIME is too large ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef VOID(*PFN_MGMT_TIMEOUT_FUNC) (P_ADAPTER_T, ULONG); ++ ++typedef struct _TIMER_T { ++ LINK_ENTRY_T rLinkEntry; ++ OS_SYSTIME rExpiredSysTime; ++ UINT_16 u2Minutes; ++ UINT_16 u2Reserved; ++ ULONG ulData; ++ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; ++} TIMER_T, *P_TIMER_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Check if time "a" is before time "b" */ ++/* In 32-bit variable, 0x00000001~0x7fffffff -> positive number, ++ * 0x80000000~0xffffffff -> negative number ++ */ ++#define TIME_BEFORE_64bit(a, b) (a < b) ++ ++#define TIME_BEFORE(a, b) ((UINT_32)((UINT_32)(a) - (UINT_32)(b)) > 0x7fffffff) ++ ++/* #define TIME_BEFORE(a,b) ((INT_32)((INT_32)(b) - (INT_32)(a)) > 0) ++ * may cause UNexpect result between Free build and Check build for WinCE ++ */ ++ ++#define TIME_AFTER(a, b) TIME_BEFORE(b, a) ++ ++#define SYSTIME_TO_SEC(_systime) ((_systime) / KAL_HZ) ++#define SEC_TO_SYSTIME(_sec) ((_sec) * KAL_HZ) ++ ++/* The macros to convert second & millisecond */ ++#define MSEC_TO_SEC(_msec) ((_msec) / MSEC_PER_SEC) ++#define SEC_TO_MSEC(_sec) ((UINT_32)(_sec) * MSEC_PER_SEC) ++ ++/* The macros to convert millisecond & microsecond */ ++#define USEC_TO_MSEC(_usec) ((_usec) / USEC_PER_MSEC) ++#define MSEC_TO_USEC(_msec) ((UINT_32)(_msec) * USEC_PER_MSEC) ++ ++/* The macros to convert TU & microsecond, TU & millisecond */ ++#define TU_TO_USEC(_tu) ((_tu) * USEC_PER_TU) ++#define TU_TO_MSEC(_tu) USEC_TO_MSEC(TU_TO_USEC(_tu)) ++ ++/* The macros to convert TU & & OS system time, round up by 0.5 */ ++#define TU_TO_SYSTIME(_tu) MSEC_TO_SYSTIME(TU_TO_MSEC(_tu)) ++#define SYSTIME_TO_TU(_systime) \ ++ ((SYSTIME_TO_USEC(_systime) + ((USEC_PER_TU / 2) - 1)) / USEC_PER_TU) ++ ++/* The macros to convert OS system time & microsecond */ ++#define SYSTIME_TO_USEC(_systime) (SYSTIME_TO_MSEC(_systime) * USEC_PER_MSEC) ++ ++/* The macro to get the current OS system time */ ++#define GET_CURRENT_SYSTIME(_systime_p) {*(_systime_p) = kalGetTimeTick(); } ++ ++/* The macro to copy the system time */ ++#define COPY_SYSTIME(_destTime, _srcTime) {(_destTime) = (_srcTime); } ++ ++/* The macro to get the system time difference between t1 and t2 (t1 - t2) */ ++/* #define GET_SYSTIME_DIFFERENCE(_time1, _time2, _diffTime) \ ++ (_diffTime) = (_time1) - (_time2) */ ++ ++/* The macro to check for the expiration, if TRUE means _currentTime >= _expirationTime */ ++#define CHECK_FOR_EXPIRATION(_currentTime, _expirationTime) \ ++ (((UINT_32)(_currentTime) - (UINT_32)(_expirationTime)) <= 0x7fffffffUL) ++ ++/* The macro to check for the timeout */ ++#define CHECK_FOR_TIMEOUT(_currentTime, _timeoutStartingTime, _timeout) \ ++ CHECK_FOR_EXPIRATION((_currentTime), ((_timeoutStartingTime) + (_timeout))) ++ ++/* The macro to set the expiration time with a specified timeout *//* Watch out for round up. */ ++#define SET_EXPIRATION_TIME(_expirationTime, _timeout) \ ++ { \ ++ GET_CURRENT_SYSTIME(&(_expirationTime)); \ ++ (_expirationTime) += (OS_SYSTIME)(_timeout); \ ++ } ++ ++#define timerRenewTimer(adapter, tmr, interval) \ ++ timerStartTimer(adapter, tmr, interval, (tmr)->function, (tmr)->data) ++ ++#define MGMT_INIT_TIMER(_adapter_p, _timer, _callbackFunc) \ ++ timerInitTimer(_adapter_p, &(_timer), (ULONG)(_callbackFunc)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter); ++ ++VOID ++cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData); ++ ++VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer); ++ ++VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs); ++ ++VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++static inline INT_32 timerPendingTimer(IN P_TIMER_T prTimer) ++{ ++ ASSERT(prTimer); ++ ++ return prTimer->rLinkEntry.prNext != NULL; ++} ++ ++#endif /* _CNM_TIMER_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h +new file mode 100644 +index 000000000000..868de4a6c40a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h +@@ -0,0 +1,446 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/hem_mbox.h#2 ++*/ ++ ++/*! \file hem_mbox.h ++ \brief ++ ++*/ ++ ++/* ++** Log: hem_mbox.h ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for ++ * more than one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID ++ * support as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. ++ * cnm_timer[WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Add invitation support. ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * eliminate unused parameters for SAA-FSM ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Remove unused message ID ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some message ID for P2P FSM under provisioning phase. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add Message Event ID for P2P Module. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Check-in P2P Device Discovery Feature. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * remove unused mailbox message definitions. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * message table should not be commented out by compilation option without modifying header file ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_QOS_ACTION_FRAME ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Develop partial DPD code ++ * ++ * 02 11 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added MID_RXM_MQM_QOS_ACTION_FRAME for RXM to indicate QoS Action frames to MQM ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename the parameter of mboxDummy() ++ * ++ * Dec 2 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove Dummy MSG ID ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add JOIN REQ related MSG ID ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add AIS ABORT MSG ID ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add SCN MSG IDs ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _HEM_MBOX_H ++#define _HEM_MBOX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Message IDs */ ++typedef enum _ENUM_MSG_ID_T { ++ MID_MNY_CNM_CH_REQ, /* MANY notify CNM to obtain channel privilege */ ++ MID_MNY_CNM_CH_ABORT, /* MANY notify CNM to abort/release channel privilege */ ++ ++ MID_CNM_AIS_CH_GRANT, /* CNM notify AIS for indicating channel granted */ ++ MID_CNM_P2P_CH_GRANT, /* CNM notify P2P for indicating channel granted */ ++ MID_CNM_BOW_CH_GRANT, /* CNM notify BOW for indicating channel granted */ ++ ++ /*--------------------------------------------------*/ ++ /* SCN Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_AIS_SCN_SCAN_REQ, /* AIS notify SCN for starting scan */ ++ MID_AIS_SCN_SCAN_REQ_V2, /* AIS notify SCN for starting scan with multiple SSID support */ ++ MID_AIS_SCN_SCAN_CANCEL, /* AIS notify SCN for cancelling scan */ ++ MID_P2P_SCN_SCAN_REQ, /* P2P notify SCN for starting scan */ ++ MID_P2P_SCN_SCAN_REQ_V2, /* P2P notify SCN for starting scan with multiple SSID support */ ++ MID_P2P_SCN_SCAN_CANCEL, /* P2P notify SCN for cancelling scan */ ++ MID_BOW_SCN_SCAN_REQ, /* BOW notify SCN for starting scan */ ++ MID_BOW_SCN_SCAN_REQ_V2, /* BOW notify SCN for starting scan with multiple SSID support */ ++ MID_BOW_SCN_SCAN_CANCEL, /* BOW notify SCN for cancelling scan */ ++ MID_RLM_SCN_SCAN_REQ, /* RLM notify SCN for starting scan (OBSS-SCAN) */ ++ MID_RLM_SCN_SCAN_REQ_V2, /* RLM notify SCN for starting scan (OBSS-SCAN) with multiple SSID support */ ++ MID_RLM_SCN_SCAN_CANCEL, /* RLM notify SCN for cancelling scan (OBSS-SCAN) */ ++ MID_SCN_AIS_SCAN_DONE, /* SCN notify AIS for scan completion */ ++ MID_SCN_P2P_SCAN_DONE, /* SCN notify P2P for scan completion */ ++ MID_SCN_BOW_SCAN_DONE, /* SCN notify BOW for scan completion */ ++ MID_SCN_RLM_SCAN_DONE, /* SCN notify RLM for scan completion (OBSS-SCAN) */ ++ ++ /*--------------------------------------------------*/ ++ /* AIS Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_OID_AIS_FSM_JOIN_REQ, /* OID/IOCTL notify AIS for join */ ++ MID_OID_AIS_FSM_ABORT, /* OID/IOCTL notify AIS for abort */ ++ MID_AIS_SAA_FSM_START, /* AIS notify SAA for Starting authentication/association fsm */ ++ MID_AIS_SAA_FSM_ABORT, /* AIS notify SAA for Aborting authentication/association fsm */ ++ MID_SAA_AIS_JOIN_COMPLETE, /* SAA notify AIS for indicating join complete */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /*--------------------------------------------------*/ ++ /* BOW Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_BOW_SAA_FSM_START, /* BOW notify SAA for Starting authentication/association fsm */ ++ MID_BOW_SAA_FSM_ABORT, /* BOW notify SAA for Aborting authentication/association fsm */ ++ MID_SAA_BOW_JOIN_COMPLETE, /* SAA notify BOW for indicating join complete */ ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /*--------------------------------------------------*/ ++ /* P2P Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ MID_P2P_SAA_FSM_START, /* P2P notify SAA for Starting authentication/association fsm */ ++ MID_P2P_SAA_FSM_ABORT, /* P2P notify SAA for Aborting authentication/association fsm */ ++ MID_SAA_P2P_JOIN_COMPLETE, /* SAA notify P2P for indicating join complete */ ++ ++ MID_MNY_P2P_FUN_SWITCH, /* Enable P2P FSM. */ ++ MID_MNY_P2P_DEVICE_DISCOVERY, /* Start device discovery. */ ++ MID_MNY_P2P_CONNECTION_REQ, /* Connection request. */ ++ MID_MNY_P2P_CONNECTION_ABORT, /* Abort connection request, P2P FSM return to IDLE. */ ++ MID_MNY_P2P_BEACON_UPDATE, ++ MID_MNY_P2P_STOP_AP, ++ MID_MNY_P2P_CHNL_REQ, ++ MID_MNY_P2P_CHNL_ABORT, ++ MID_MNY_P2P_MGMT_TX, ++ MID_MNY_P2P_GROUP_DISSOLVE, ++ MID_MNY_P2P_MGMT_FRAME_REGISTER, ++ MID_MNY_P2P_NET_DEV_REGISTER, ++ MID_MNY_P2P_START_AP, ++ MID_MNY_P2P_MGMT_FRAME_UPDATE, ++ MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, ++#if CFG_SUPPORT_WFD ++ MID_MNY_P2P_WFD_CFG_UPDATE, ++#endif ++#endif ++ ++#if CFG_SUPPORT_ADHOC ++ MID_SCN_AIS_FOUND_IBSS, /* SCN notify AIS that an IBSS Peer has been found and can merge into */ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ MID_SAA_AIS_FSM_ABORT, /* SAA notify AIS for indicating deauthentication/disassociation */ ++ ++ /*--------------------------------------------------*/ ++ /* AIS MGMT-TX Support */ ++ /*--------------------------------------------------*/ ++ MID_MNY_AIS_REMAIN_ON_CHANNEL, ++ MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, ++ MID_MNY_AIS_MGMT_TX, ++ ++ MID_TOTAL_NUM ++} ENUM_MSG_ID_T, *P_ENUM_MSG_ID_T; ++ ++/* Message header of inter-components */ ++struct _MSG_HDR_T { ++ LINK_ENTRY_T rLinkEntry; ++ ENUM_MSG_ID_T eMsgId; ++}; ++ ++typedef VOID(*PFN_MSG_HNDL_FUNC) (P_ADAPTER_T, P_MSG_HDR_T); ++ ++typedef struct _MSG_HNDL_ENTRY { ++ ENUM_MSG_ID_T eMsgId; ++ PFN_MSG_HNDL_FUNC pfMsgHndl; ++} MSG_HNDL_ENTRY_T, *P_MSG_HNDL_ENTRY_T; ++ ++typedef enum _EUNM_MSG_SEND_METHOD_T { ++ MSG_SEND_METHOD_BUF = 0, /* Message is put in the queue and will be ++ executed when mailbox is checked. */ ++ MSG_SEND_METHOD_UNBUF /* The handler function is called immediately ++ in the same context of the sender */ ++} EUNM_MSG_SEND_METHOD_T, *P_EUNM_MSG_SEND_METHOD_T; ++ ++typedef enum _ENUM_MBOX_ID_T { ++ MBOX_ID_0 = 0, ++ MBOX_ID_TOTAL_NUM ++} ENUM_MBOX_ID_T, *P_ENUM_MBOX_ID_T; ++ ++/* Define Mailbox structure */ ++typedef struct _MBOX_T { ++ LINK_T rLinkHead; ++} MBOX_T, *P_MBOX_T; ++ ++typedef struct _MSG_SAA_FSM_START_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ P_STA_RECORD_T prStaRec; ++} MSG_SAA_FSM_START_T, *P_MSG_SAA_FSM_START_T; ++ ++typedef struct _MSG_SAA_FSM_COMP_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ WLAN_STATUS rJoinStatus; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prSwRfb; ++} MSG_SAA_FSM_COMP_T, *P_MSG_SAA_FSM_COMP_T; ++ ++typedef struct _MSG_SAA_FSM_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ P_STA_RECORD_T prStaRec; ++} MSG_SAA_FSM_ABORT_T, *P_MSG_SAA_FSM_ABORT_T; ++ ++typedef struct _MSG_CONNECTION_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucNetTypeIndex; ++} MSG_CONNECTION_ABORT_T, *P_MSG_CONNECTION_ABORT_T; ++ ++typedef struct _MSG_REMAIN_ON_CHANNEL_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eSco; ++ UINT_8 ucChannelNum; ++ UINT_32 u4DurationMs; ++ UINT_64 u8Cookie; ++} MSG_REMAIN_ON_CHANNEL_T, *P_MSG_REMAIN_ON_CHANNEL_T; ++ ++typedef struct _MSG_CANCEL_REMAIN_ON_CHANNEL_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_64 u8Cookie; ++} MSG_CANCEL_REMAIN_ON_CHANNEL_T, *P_MSG_CANCEL_REMAIN_ON_CHANNEL_T; ++ ++typedef struct _MSG_MGMT_TX_REQUEST_T { ++ MSG_HDR_T rMsgHdr; ++ P_MSDU_INFO_T prMgmtMsduInfo; ++ UINT_64 u8Cookie; /* For indication. */ ++ BOOLEAN fgNoneCckRate; ++ BOOLEAN fgIsWaitRsp; ++} MSG_MGMT_TX_REQUEST_T, *P_MSG_MGMT_TX_REQUEST_T; ++ ++/* specific message data types */ ++typedef MSG_SAA_FSM_START_T MSG_JOIN_REQ_T, *P_MSG_JOIN_REQ_T; ++typedef MSG_SAA_FSM_COMP_T MSG_JOIN_COMP_T, *P_MSG_JOIN_COMP_T; ++typedef MSG_SAA_FSM_ABORT_T MSG_JOIN_ABORT_T, *P_MSG_JOIN_ABORT_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); ++ ++VOID ++mboxSendMsg(IN P_ADAPTER_T prAdapter, ++ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod); ++ ++VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); ++ ++VOID mboxInitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID mboxDestroy(IN P_ADAPTER_T prAdapter); ++ ++VOID mboxDummy(IN P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _HEM_MBOX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h +new file mode 100644 +index 000000000000..88b99222133f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h +@@ -0,0 +1,148 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/include/mgmt/hs20.h#2 ++*/ ++ ++/*! \file hs20.h ++ \brief This file contains the function declaration for hs20.c. ++*/ ++ ++/* ++** Log: ++ * ++ */ ++ ++#ifndef _HS20_H ++#define _HS20_H ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define BSSID_POOL_MAX_SIZE 8 ++#define HS20_SIGMA_SCAN_RESULT_TIMEOUT 30 /* sec */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++/*For GTK Frame Filter*/ ++typedef struct _IPV4_NETWORK_ADDRESS_LIST { ++ UINT_8 ucAddrCount; ++ IPV4_NETWORK_ADDRESS arNetAddr[1]; ++} IPV4_NETWORK_ADDRESS_LIST, *P_IPV4_NETWORK_ADDRESS_LIST; ++#endif ++ ++/* Entry of BSSID Pool - For SIGMA Test */ ++typedef struct _BSSID_ENTRY_T { ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++} BSSID_ENTRY_T, P_HS20_BSSID_POOL_ENTRY_T; ++ ++struct _HS20_INFO_T { ++ ++ /*Hotspot 2.0 Information */ ++ UINT_8 aucHESSID[MAC_ADDR_LEN]; ++ UINT_8 ucAccessNetworkOptions; ++ UINT_8 ucVenueGroup; /* VenueInfo - Group */ ++ UINT_8 ucVenueType; ++ UINT_8 ucHotspotConfig; ++ ++ /*Roaming Consortium Information */ ++ /* PARAM_HS20_ROAMING_CONSORTIUM_INFO rRCInfo; */ ++ ++ /*Hotspot 2.0 dummy AP Info */ ++ ++ /*Time Advertisement Information */ ++ /* UINT_32 u4UTCOffsetTime; */ ++ /* UINT_8 aucTimeZone[ELEM_MAX_LEN_TIME_ZONE]; */ ++ /* UINT_8 ucLenTimeZone; */ ++ ++ /* For SIGMA Test */ ++ /* BSSID Pool */ ++ BSSID_ENTRY_T arBssidPool[BSSID_POOL_MAX_SIZE]; ++ UINT_8 ucNumBssidPoolEntry; ++ BOOLEAN fgIsHS2SigmaMode; ++ ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/*For GTK Frame Filter*/ ++#if DBG ++#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ ++ { \ ++ UINT_32 u4Size = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + \ ++ (((_prAddrList)->ucAddrCount) * sizeof(IPV4_NETWORK_ADDRESS)); \ ++ kalMemFree((_prAddrList), VIR_MEM_TYPE, u4Size); \ ++ (_prAddrList) = NULL; \ ++ } ++#else ++#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ ++ { \ ++ kalMemFree((_prAddrList), VIR_MEM_TYPE, 0); \ ++ (_prAddrList) = NULL; \ ++ } ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); ++ ++VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); ++ ++UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID); ++ ++WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE); ++ ++BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); ++ ++BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); ++#endif ++ ++BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); ++ ++BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); ++ ++WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); ++ ++#endif ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h +new file mode 100644 +index 000000000000..cb89fd8793ee +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h +@@ -0,0 +1,153 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/mib.h#1 ++*/ ++ ++/*! \file mib.h ++ \brief This file contains the IEEE 802.11 family related MIB definition ++ for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: mib.h ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++#ifndef _MIB_H ++#define _MIB_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Entry in SMT AuthenticationAlgorithms Table: dot11AuthenticationAlgorithmsEntry */ ++typedef struct _DOT11_AUTHENTICATION_ALGORITHMS_ENTRY { ++ BOOLEAN dot11AuthenticationAlgorithmsEnable; /* dot11AuthenticationAlgorithmsEntry 3 */ ++} DOT11_AUTHENTICATION_ALGORITHMS_ENTRY, *P_DOT11_AUTHENTICATION_ALGORITHMS_ENTRY; ++ ++/* Entry in SMT dot11RSNAConfigPairwiseCiphersTalbe Table: dot11RSNAConfigPairwiseCiphersEntry */ ++typedef struct _DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY { ++ UINT_32 dot11RSNAConfigPairwiseCipher; /* dot11RSNAConfigPairwiseCiphersEntry 2 */ ++ BOOLEAN dot11RSNAConfigPairwiseCipherEnabled; /* dot11RSNAConfigPairwiseCiphersEntry 3 */ ++} DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY, *P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY; ++ ++/* Entry in SMT dot11RSNAConfigAuthenticationSuitesTalbe Table: dot11RSNAConfigAuthenticationSuitesEntry */ ++typedef struct _DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY { ++ UINT_32 dot11RSNAConfigAuthenticationSuite; /* dot11RSNAConfigAuthenticationSuitesEntry 2 */ ++ BOOLEAN dot11RSNAConfigAuthenticationSuiteEnabled; /* dot11RSNAConfigAuthenticationSuitesEntry 3 */ ++} DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY, *P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY; ++ ++/* ----- IEEE 802.11 MIB Major sections ----- */ ++typedef struct _IEEE_802_11_MIB_T { ++ /* dot11PrivacyTable (dot11smt 5) */ ++ UINT_8 dot11WEPDefaultKeyID; /* dot11PrivacyEntry 2 */ ++ BOOLEAN dot11TranmitKeyAvailable; ++ UINT_32 dot11WEPICVErrorCount; /* dot11PrivacyEntry 5 */ ++ UINT_32 dot11WEPExcludedCount; /* dot11PrivacyEntry 6 */ ++ ++ /* dot11RSNAConfigTable (dot11smt 8) */ ++ UINT_32 dot11RSNAConfigGroupCipher; /* dot11RSNAConfigEntry 4 */ ++ ++ /* dot11RSNAConfigPairwiseCiphersTable (dot11smt 9) */ ++ DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY dot11RSNAConfigPairwiseCiphersTable[MAX_NUM_SUPPORTED_CIPHER_SUITES]; ++ ++ /* dot11RSNAConfigAuthenticationSuitesTable (dot11smt 10) */ ++ DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY ++ dot11RSNAConfigAuthenticationSuitesTable[MAX_NUM_SUPPORTED_AKM_SUITES]; ++ ++#if 0 /* SUPPORT_WAPI */ ++ BOOLEAN fgWapiKeyInstalled; ++ PARAM_WPI_KEY_T rWapiPairwiseKey[2]; ++ BOOLEAN fgPairwiseKeyUsed[2]; ++ UINT_8 ucWpiActivedPWKey; /* Must be 0 or 1, by wapi spec */ ++ PARAM_WPI_KEY_T rWapiGroupKey[2]; ++ BOOLEAN fgGroupKeyUsed[2]; ++#endif ++} IEEE_802_11_MIB_T, *P_IEEE_802_11_MIB_T; ++ ++/* ------------------ IEEE 802.11 non HT PHY characteristics ---------------- */ ++typedef const struct _NON_HT_PHY_ATTRIBUTE_T { ++ UINT_16 u2SupportedRateSet; ++ ++ BOOLEAN fgIsShortPreambleOptionImplemented; ++ ++ BOOLEAN fgIsShortSlotTimeOptionImplemented; ++ ++} NON_HT_PHY_ATTRIBUTE_T, *P_NON_HT_PHY_ATTRIBUTE_T; ++ ++typedef const struct _NON_HT_ADHOC_MODE_ATTRIBUTE_T { ++ ++ ENUM_PHY_TYPE_INDEX_T ePhyTypeIndex; ++ ++ UINT_16 u2BSSBasicRateSet; ++ ++} NON_HT_ADHOC_MODE_ATTRIBUTE_T, *P_NON_HT_ADHOC_MODE_ATTRIBUTE_T; ++ ++typedef NON_HT_ADHOC_MODE_ATTRIBUTE_T NON_HT_AP_MODE_ATTRIBUTE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[]; ++extern NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[]; ++extern NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[]; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _MIB_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h +new file mode 100644 +index 000000000000..11145c31dbfa +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h +@@ -0,0 +1,55 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_assoc.h#1 ++*/ ++ ++/*! \file p2p_assoc.h ++ \brief This file contains the Wi-Fi Direct ASSOC REQ/RESP of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++#ifndef _P2P_ASSOC_H ++#define _P2P_ASSOC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h +new file mode 100644 +index 000000000000..869d7bf0ee61 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h +@@ -0,0 +1,56 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_bss.h#2 ++*/ ++ ++/*! \file "p2p_bss.h" ++ \brief In this file we define the function prototype used in p2p BSS/IBSS. ++ ++ The file contains the function declarations and defines for used in BSS/IBSS. ++*/ ++ ++#ifndef _P2P_BSS_H ++#define _P2P_BSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++UINT_32 p2pGetTxProbRspIeTableSize(VOID); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h +new file mode 100644 +index 000000000000..2541e1d2883e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h +@@ -0,0 +1,2190 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_fsm.h#23 ++*/ ++ ++/*! \file p2p_fsm.h ++ \brief Declaration of functions and finite state machine for P2P Module. ++ ++ Declaration of functions and finite state machine for P2P Module. ++*/ ++ ++/* ++** Log: p2p_fsm.h ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** Fix compile error. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 18 2012 yuche.tsai ++ * NULL ++ * add one file. ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Resolve class 3 error issue under AP mode. ++ * ++ * data frame may TX before Assoc Response TX. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix default device name issue. ++ * ++ * 11 09 2011 yuche.tsai ++ * [WCXRP00001093] [Need Patch][Volunteer Patch] Service Discovery 2.0 state transition issue. ++ * Fix SD2.0 issue which may cause KE. (Monkey test) ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version ++ * query & set support for service discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 09 01 2011 yuche.tsai ++ * NULL ++ * Fix channel stay interval. ++ * Sync channel stay interval & channel request interval under AP mode.. ++ * ++ * 08 30 2011 yuche.tsai ++ * [WCXRP00000953] [Volunteer Patch][Driver] Hot Spot Channel ASSERT issue. ++ * Fix hot spot FW assert issue when under concurrent case. (DBG enable only) ++ * ++ * 08 16 2011 cp.wu ++ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence ++ * auto channel decision for 2.4GHz hot spot mode ++ * ++ * 08 16 2011 yuche.tsai ++ * NULL ++ * Fix scan policy for Active LISTEN scan. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, ++ * TX deauth to a disconnecting device issue. ++ * Support TX Deauth Issue. ++ * ++ * 07 26 2011 yuche.tsai ++ * [WCXRP00000875] [Volunteer Patch][WiFi Direct][Driver] MT6620 IOT issue with realtek test bed solution. ++ * Turn off persistent group support for V2.0 release. ++ * ++ * 07 18 2011 yuche.tsai ++ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. ++ * Fix compile error. ++ * ++ * 07 18 2011 yuche.tsai ++ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. ++ * Fix MT6620 WiFi Direct IOT Issue with BCM solution. ++ * ++ * 07 11 2011 yuche.tsai ++ * [WCXRP00000845] [Volunteer Patch][WiFi Direct] WiFi Direct Device Connection Robustness ++ * Enhance Connection Robustness. ++ * ++ * 07 08 2011 yuche.tsai ++ * [WCXRP00000841] [Volunteer Patch][WiFi Direct] Group Owner Setting. ++ * Update GO configure parameter. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Disable enhancement II for debugging. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Refine compile flag. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Add wifi direct connection enhancement method I, II & VI. ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. ++ * Fix connection indication twice issue. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Fix RX SD request under AP mode issue. ++ * ++ * 05 04 2011 yuche.tsai ++ * NULL ++ * Support partial persistent group function. ++ * ++ * 04 20 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Improve some error handleing. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * 1.Shorten the LISTEN interval. ++ * 2. Fix IF address issue when we are GO ++ * 3. Fix LISTEN channel issue. ++ * ++ * 03 21 2011 yuche.tsai ++ * NULL ++ * Change P2P Connection Request Flow. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow ++ * Modify connection flow after Group Formation Complete, or device connect to a GO. ++ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix some configure method issue. ++ * ++ * 03 10 2011 yuche.tsai ++ * NULL ++ * Add P2P API. ++ * ++ * 03 07 2011 yuche.tsai ++ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. ++ * . ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation ++ * Update channel issue when doing GO formation.. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Related wlanoid function. ++ * ++ * 02 18 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * fixed the ioctl setting that index not map to spec defined config method. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue ++ * Fix WSC IE BE format issue. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * append the WSC IE config method attribute at provision discovery request. ++ * ++ * 02 11 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add two function prototype. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Support Disassoc & Deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++ ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Indication Related code. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add Support for MLME deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Fix Client Limit Issue. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++ ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Function. ++ * ++ * 01 25 2011 terry.wu ++ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter ++ * Add a new module parameter to indicate current runnig mode, P2P or AP. ++ * ++ * 01 19 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Null NOA attribute setting when no related parameters. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify some behavior of AP mode. ++ * ++ * 12 22 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix Compile Error. ++ * ++ * 12 15 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Refine Connection Flow. ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. ++ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client ++ * by checking the P2P IE in assoc req frame. ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation. ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation & Provision Discovery. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ ++ * ++ * 11 29 2010 yuche.tsai ++ * NULL ++ * Update P2P related function for INVITATION & PROVISION DISCOVERY. ++ * ++ * 11 26 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Update P2P PS for NOA function. ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update Code for Invitation Related Function. ++ * ++ * 11 17 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] ++ * Set the Tx lowest rate at wlan table for normal operation ++ * fixed some ASSERT check. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * fixed compiling error while enable p2p. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at WinXP. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add connection abort message event prototype. ++ * ++ * 08 20 2010 kevin.huang ++ * NULL ++ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Fix P2P Intended Interface Address Bug. ++ * Extend GO Nego Timeout Time. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Extend Listen Interval default value & remove deprecated variable. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add function prototype for join complete. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some function proto type for P2P FSM under provisioning phase.. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Change P2P data structure for supporting ++ * 1. P2P Device discovery. ++ * 2. P2P Group Negotiation. ++ * 3. P2P JOIN ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Check-in P2P Device Discovery Feature. ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Update P2P FSM header file. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * P2P/RSN/WAPI IEs need to be declared with compact structure. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Update P2P FSM header file. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix some P2P function prototype. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * First draft for migration P2P FSM from FW to Driver. ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Rename CFG flag for P2P ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify parameter of p2pStartGO ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add Wi-Fi Direct SSID and P2P GO Test Mode ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++#ifndef _P2P_FSM_H ++#define _P2P_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CID52_53_54 0 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_P2P_STATE_T { ++ P2P_STATE_IDLE = 0, ++ P2P_STATE_SCAN, ++ P2P_STATE_AP_CHANNEL_DETECT, ++ P2P_STATE_REQING_CHANNEL, ++ P2P_STATE_CHNL_ON_HAND, /* Requesting Channel to Send Specific Frame. */ ++ P2P_STATE_GC_JOIN, /* Sending Specific Frame. May extending channel by other event. */ ++ P2P_STATE_NUM ++} ENUM_P2P_STATE_T, *P_ENUM_P2P_STATE_T; ++ ++enum _ENUM_P2P_DEV_EXT_LISTEN_T { ++ P2P_DEV_NOT_EXT_LISTEN, ++ P2P_DEV_EXT_LISTEN_ING, ++ P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT, ++ P2P_DEV_EXT_LISTEN_NUM ++}; ++ ++typedef enum _ENUM_CHANNEL_REQ_TYPE_T { ++ CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL, ++ CHANNEL_REQ_TYPE_GC_JOIN_REQ, ++ CHANNEL_REQ_TYPE_GO_START_BSS ++} ENUM_CHANNEL_REQ_TYPE_T, *P_ENUM_CHANNEL_REQ_TYPE_T; ++ ++typedef enum _ENUM_BUFFER_TYPE_T { ++ ENUM_FRAME_TYPE_EXTRA_IE_BEACON, ++ ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP, ++ ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP, ++ ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE, ++ ENUM_FRAME_TYPE_BEACON_TEMPLATE, ++ ENUM_FRAME_IE_NUM ++} ENUM_BUFFER_TYPE_T, *P_ENUM_BUFFER_TYPE_T; ++ ++typedef enum _ENUM_HIDDEN_SSID_TYPE_T { ++ ENUM_HIDDEN_SSID_NONE, ++ ENUM_HIDDEN_SSID_LEN, ++ ENUM_HIDDEN_SSID_ZERO_CONTENT, ++ ENUM_HIDDEN_SSID_NUM ++} ENUM_HIDDEN_SSID_TYPE_T, *P_ENUM_HIDDEN_SSID_TYPE_T; ++ ++typedef struct _P2P_SSID_STRUCT_T { ++ UINT_8 aucSsid[32]; ++ UINT_8 ucSsidLen; ++} P2P_SSID_STRUCT_T, *P_P2P_SSID_STRUCT_T; ++ ++typedef struct _P2P_STATION_INFO_T { ++ UINT_32 u4InactiveTime; ++ UINT_32 u4RxBytes; /* TODO: */ ++ UINT_32 u4TxBytes; /* TODO: */ ++ UINT_32 u4RxPackets; /* TODO: */ ++ UINT_32 u4TxPackets; /* TODO: */ ++ /* TODO: Add more for requirement. */ ++} P2P_STATION_INFO_T, *P_P2P_STATION_INFO_T; ++ ++typedef struct _AP_CRYPTO_SETTINGS_T { ++ UINT_32 u4WpaVersion; ++ UINT_32 u4CipherGroup; ++ INT_32 i4NumOfCiphers; ++ UINT_32 aucCiphersPairwise[5]; ++ INT_32 i4NumOfAkmSuites; ++ UINT_32 aucAkmSuites[2]; ++ BOOLEAN fgIsControlPort; ++ UINT_16 u2ControlPortBE; ++ BOOLEAN fgIsControlPortEncrypt; ++} AP_CRYPTO_SETTINGS_T, *P_AP_CRYPTO_SETTINGS_T; ++ ++/*-------------------- P2P FSM ACTION STRUCT ---------------------*/ ++typedef struct _P2P_CHNL_REQ_INFO_T { ++ BOOLEAN fgIsChannelRequested; ++ UINT_8 ucSeqNumOfChReq; ++ UINT_64 u8Cookie; ++ UINT_8 ucReqChnlNum; ++ ENUM_BAND_T eBand; ++ ENUM_CHNL_EXT_T eChnlSco; ++ UINT_32 u4MaxInterval; ++ ENUM_CHANNEL_REQ_TYPE_T eChannelReqType; ++ ++ UINT_8 ucOriChnlNum; ++ ENUM_BAND_T eOriBand; ++ ENUM_CHNL_EXT_T eOriChnlSco; ++ UINT_32 NFC_BEAM; /*NFC Beam + Indication */ ++} P2P_CHNL_REQ_INFO_T, *P_P2P_CHNL_REQ_INFO_T; ++ ++typedef struct _P2P_SCAN_REQ_INFO_T { ++ ENUM_SCAN_TYPE_T eScanType; ++ ENUM_SCAN_CHANNEL eChannelSet; ++ UINT_16 u2PassiveDewellTime; ++ UINT_8 ucSeqNumOfScnMsg; ++ BOOLEAN fgIsAbort; ++ BOOLEAN fgIsScanRequest; ++ UINT_8 ucNumChannelList; ++ RF_CHANNEL_INFO_T arScanChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_32 u4BufLength; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++ P2P_SSID_STRUCT_T rSsidStruct; /* Currently we can only take one SSID scan request */ ++ BOOLEAN fgIsGOInitialDone; ++} P2P_SCAN_REQ_INFO_T, *P_P2P_SCAN_REQ_INFO_T; ++ ++typedef struct _P2P_CONNECTION_REQ_INFO_T { ++ ++ BOOLEAN fgIsConnRequest; ++ P2P_SSID_STRUCT_T rSsidStruct; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ /* For ASSOC Req. */ ++ UINT_32 u4BufLength; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++} P2P_CONNECTION_REQ_INFO_T, *P_P2P_CONNECTION_REQ_INFO_T; ++ ++typedef struct _P2P_MGMT_TX_REQ_INFO_T { ++ BOOLEAN fgIsMgmtTxRequested; ++ P_MSDU_INFO_T prMgmtTxMsdu; ++ UINT_64 u8Cookie; ++} P2P_MGMT_TX_REQ_INFO_T, *P_P2P_MGMT_TX_REQ_INFO_T; ++ ++struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T { ++ MSG_HDR_T rMsgHdr; ++ UINT_32 wait; /* interval supplicant expected to stay in listen interval */ ++}; ++ ++typedef struct _P2P_BEACON_UPDATE_INFO_T { ++ PUINT_8 pucBcnHdr; ++ UINT_32 u4BcnHdrLen; ++ PUINT_8 pucBcnBody; ++ UINT_32 u4BcnBodyLen; ++} P2P_BEACON_UPDATE_INFO_T, *P_P2P_BEACON_UPDATE_INFO_T; ++ ++typedef struct _P2P_PROBE_RSP_UPDATE_INFO_T { ++ P_MSDU_INFO_T prProbeRspMsduTemplate; ++} P2P_PROBE_RSP_UPDATE_INFO_T, *P_P2P_PROBE_RSP_UPDATE_INFO_T; ++ ++typedef struct _P2P_ASSOC_RSP_UPDATE_INFO_T { ++ PUINT_8 pucAssocRspExtIE; ++ UINT_16 u2AssocIELen; ++} P2P_ASSOC_RSP_UPDATE_INFO_T, *P_P2P_ASSOC_RSP_UPDATE_INFO_T; ++ ++typedef struct _P2P_JOIN_INFO_T { ++ UINT_32 ucSeqNumOfReqMsg; ++ UINT_8 ucAvailableAuthTypes; ++ P_STA_RECORD_T prTargetStaRec; ++ P2P_SSID_STRUCT_T rSsidStruct; ++ BOOLEAN fgIsJoinComplete; ++ /* For ASSOC Rsp. */ ++ UINT_32 u4BufLength; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++} P2P_JOIN_INFO_T, *P_P2P_JOIN_INFO_T; ++ ++#if CFG_SUPPORT_WFD ++ ++#define WFD_FLAGS_DEV_INFO_VALID BIT(0) /* 1. WFD_DEV_INFO, 2. WFD_CTRL_PORT, 3. WFD_MAT_TP. */ ++#define WFD_FLAGS_SINK_INFO_VALID BIT(1) /* 1. WFD_SINK_STATUS, 2. WFD_SINK_MAC. */ ++#define WFD_FLAGS_ASSOC_MAC_VALID BIT(2) /* 1. WFD_ASSOC_MAC. */ ++#define WFD_FLAGS_EXT_CAPABILITY_VALID BIT(3) /* 1. WFD_EXTEND_CAPABILITY. */ ++ ++struct _WFD_CFG_SETTINGS_T { ++ UINT_32 u4WfdCmdType; ++ UINT_8 ucWfdEnable; ++ UINT_8 ucWfdCoupleSinkStatus; ++ UINT_8 ucWfdSessionAvailable; /* 0: NA 1:Set 2:Clear */ ++ UINT_8 ucWfdSigmaMode; ++ UINT_16 u2WfdDevInfo; ++ UINT_16 u2WfdControlPort; ++ UINT_16 u2WfdMaximumTp; ++ UINT_16 u2WfdExtendCap; ++ UINT_8 aucWfdCoupleSinkAddress[MAC_ADDR_LEN]; ++ UINT_8 aucWfdAssociatedBssid[MAC_ADDR_LEN]; ++ UINT_8 aucWfdVideoIp[4]; ++ UINT_8 aucWfdAudioIp[4]; ++ UINT_16 u2WfdVideoPort; ++ UINT_16 u2WfdAudioPort; ++ UINT_32 u4WfdFlag; ++ UINT_32 u4WfdPolicy; ++ UINT_32 u4WfdState; ++ UINT_8 aucWfdSessionInformationIE[24 * 8]; ++ UINT_16 u2WfdSessionInformationIELen; ++ UINT_8 aucReserved1[2]; ++ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; ++ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; ++ UINT_32 u4WfdAdvancedFlag; ++ /* Group 1 64 bytes */ ++ UINT_8 aucWfdLocalIp[4]; ++ UINT_16 u2WfdLifetimeAc2; /* Unit is 2 TU */ ++ UINT_16 u2WfdLifetimeAc3; /* Unit is 2 TU */ ++ UINT_16 u2WfdCounterThreshold; /* Unit is ms */ ++ UINT_8 aucReverved2[54]; ++ /* Group 2 64 bytes */ ++ UINT_8 aucReverved3[64]; ++ /* Group 3 64 bytes */ ++ UINT_8 aucReverved4[64]; ++ ++}; ++ ++struct _WFD_DBG_CFG_SETTINGS_T { ++ UINT_8 ucWfdDebugMode; ++ UINT_16 u2WfdSNShowPeiroid; ++ UINT_8 Reserved; ++ ++}; ++ ++#endif ++ ++struct _P2P_FSM_INFO_T { ++ /* State related. */ ++ ENUM_P2P_STATE_T ePreviousState; ++ ENUM_P2P_STATE_T eCurrentState; ++ ++ /* Channel related. */ ++ P2P_CHNL_REQ_INFO_T rChnlReqInfo; ++ ++ /* Scan related. */ ++ P2P_SCAN_REQ_INFO_T rScanReqInfo; ++ ++ /* Connection related. */ ++ P2P_CONNECTION_REQ_INFO_T rConnReqInfo; ++ ++ /* Mgmt tx related. */ ++ P2P_MGMT_TX_REQ_INFO_T rMgmtTxInfo; ++ ++ /* Beacon related. */ ++ P2P_BEACON_UPDATE_INFO_T rBcnContentInfo; ++ ++ /* Probe Response related. */ ++ P2P_PROBE_RSP_UPDATE_INFO_T rProbeRspContentInfo; ++ ++ /* Assoc Rsp related. */ ++ P2P_ASSOC_RSP_UPDATE_INFO_T rAssocRspContentInfo; ++ ++ /* GC Join related. */ ++ P2P_JOIN_INFO_T rJoinInfo; ++ ++ /* FSM Timer */ ++/* TIMER_T rP2pFsmTimeoutTimer; */ ++ ++ /* GC Target BSS. */ ++ P_BSS_DESC_T prTargetBss; ++ ++ /* GC Connection Request. */ ++ BOOLEAN fgIsConnectionRequested; ++ ++ BOOLEAN fgIsApMode; ++ ++ /* Channel grant interval. */ ++ UINT_32 u4GrantInterval; ++ ++ /* Packet filter for P2P module. */ ++ UINT_32 u4P2pPacketFilter; ++ ++ /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Prepare for use vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ ++ /* Msg event queue. */ ++ LINK_T rMsgEventQueue; ++ ++#if CFG_SUPPORT_WFD ++ WFD_CFG_SETTINGS_T rWfdConfigureSettings; ++ WFD_DBG_CFG_SETTINGS_T rWfdDebugSetting; ++#endif ++ ++ BOOLEAN fgIsWPSMode; ++ ++ enum _ENUM_P2P_DEV_EXT_LISTEN_T eListenExted; ++}; ++ ++/*---------------- Messages -------------------*/ ++typedef struct _MSG_P2P_SCAN_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ P_P2P_SSID_STRUCT_T prSSID; ++ INT_32 i4SsidNum; ++ UINT_32 u4NumChannel; ++ PUINT_8 pucIEBuf; ++ UINT_32 u4IELen; ++ BOOLEAN fgIsAbort; ++ RF_CHANNEL_INFO_T arChannelListInfo[1]; ++} MSG_P2P_SCAN_REQUEST_T, *P_MSG_P2P_SCAN_REQUEST_T; ++ ++typedef struct _MSG_P2P_CHNL_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_64 u8Cookie; ++ UINT_32 u4Duration; ++ ENUM_CHNL_EXT_T eChnlSco; ++ RF_CHANNEL_INFO_T rChannelInfo; ++} MSG_P2P_CHNL_REQUEST_T, *P_MSG_P2P_CHNL_REQUEST_T; ++ ++typedef struct _MSG_P2P_CHNL_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_64 u8Cookie; ++} MSG_P2P_CHNL_ABORT_T, *P_MSG_P2P_CHNL_ABORT_T; ++ ++typedef struct _MSG_P2P_CONNECTION_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ P2P_SSID_STRUCT_T rSsid; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ ENUM_CHNL_EXT_T eChnlSco; ++ RF_CHANNEL_INFO_T rChannelInfo; ++ UINT_32 u4IELen; ++ UINT_8 aucIEBuf[1]; ++ /* TODO: Auth Type, OPEN, SHARED, FT, EAP... */ ++} MSG_P2P_CONNECTION_REQUEST_T, *P_MSG_P2P_CONNECTION_REQUEST_T; ++ ++typedef struct _MSG_P2P_CONNECTION_ABORT_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member. */ ++ UINT_8 aucTargetID[MAC_ADDR_LEN]; ++ UINT_16 u2ReasonCode; ++ BOOLEAN fgSendDeauth; ++} MSG_P2P_CONNECTION_ABORT_T, *P_MSG_P2P_CONNECTION_ABORT_T; ++ ++typedef struct _MSG_P2P_MGMT_TX_REQUEST_T { ++ MSG_HDR_T rMsgHdr; ++ P_MSDU_INFO_T prMgmtMsduInfo; ++ UINT_64 u8Cookie; /* For indication. */ ++ BOOLEAN fgNoneCckRate; ++ BOOLEAN fgIsWaitRsp; ++} MSG_P2P_MGMT_TX_REQUEST_T, *P_MSG_P2P_MGMT_TX_REQUEST_T; ++ ++typedef struct _MSG_P2P_START_AP_T { ++ MSG_HDR_T rMsgHdr; ++ UINT_32 u4DtimPeriod; ++ UINT_32 u4BcnInterval; ++ UINT_8 aucSsid[32]; ++ UINT_16 u2SsidLen; ++ UINT_8 ucHiddenSsidType; ++ BOOLEAN fgIsPrivacy; ++ AP_CRYPTO_SETTINGS_T rEncryptionSettings; ++ INT_32 i4InactiveTimeout; ++} MSG_P2P_START_AP_T, *P_MSG_P2P_START_AP_T; ++ ++typedef struct _MSG_P2P_BEACON_UPDATE_T { ++ MSG_HDR_T rMsgHdr; ++ UINT_32 u4BcnHdrLen; ++ UINT_32 u4BcnBodyLen; ++ PUINT_8 pucBcnHdr; ++ PUINT_8 pucBcnBody; ++ UINT_8 aucBuffer[1]; /* Header & Body are put here. */ ++} MSG_P2P_BEACON_UPDATE_T, *P_MSG_P2P_BEACON_UPDATE_T; ++ ++typedef struct _MSG_P2P_MGMT_FRAME_UPDATE_T { ++ MSG_HDR_T rMsgHdr; ++ ENUM_BUFFER_TYPE_T eBufferType; ++ UINT_32 u4BufferLen; ++ UINT_8 aucBuffer[1]; ++} MSG_P2P_MGMT_FRAME_UPDATE_T, *P_MSG_P2P_MGMT_FRAME_UPDATE_T; ++ ++typedef struct _MSG_P2P_SWITCH_OP_MODE_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ ENUM_OP_MODE_T eOpMode; ++} MSG_P2P_SWITCH_OP_MODE_T, *P_MSG_P2P_SWITCH_OP_MODE_T; ++ ++typedef struct _MSG_P2P_MGMT_FRAME_REGISTER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_16 u2FrameType; ++ BOOLEAN fgIsRegister; ++} MSG_P2P_MGMT_FRAME_REGISTER_T, *P_MSG_P2P_MGMT_FRAME_REGISTER_T; ++ ++typedef struct _MSG_P2P_NETDEV_REGISTER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ BOOLEAN fgIsEnable; ++ UINT_8 ucMode; ++} MSG_P2P_NETDEV_REGISTER_T, *P_MSG_P2P_NETDEV_REGISTER_T; ++ ++#if CFG_SUPPORT_WFD ++typedef struct _MSG_WFD_CONFIG_SETTINGS_CHANGED_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings; ++} MSG_WFD_CONFIG_SETTINGS_CHANGED_T, *P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T; ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++WLAN_STATUS ++p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++#if CFG_SUPPORT_WFD ++VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++#endif ++ ++#if 0 ++/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ///////////////////////////////////////////////////////////////////////////////////// */ ++/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ ++#endif ++ ++/* 3 --------------- WFA P2P DEFAULT PARAMETERS --------------- */ ++#define P2P_WILDCARD_SSID "DIRECT-" ++#define P2P_WILDCARD_SSID_LEN 7 ++#define P2P_GROUP_ID_LEN 9 ++ ++#define P2P_DRIVER_VERSION 2 /* Update when needed. */ ++ ++#define P2P_DEFAULT_DEV_NAME "Wireless Client" ++#define P2P_DEFAULT_DEV_NAME_LEN 15 ++#define P2P_DEFAULT_PRIMARY_CATEGORY_ID 10 ++#define P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID 5 ++#define P2P_DEFAULT_CONFIG_METHOD \ ++ (WPS_ATTRI_CFG_METHOD_PUSH_BUTTON | WPS_ATTRI_CFG_METHOD_KEYPAD | WPS_ATTRI_CFG_METHOD_DISPLAY) ++#define P2P_DEFAULT_LISTEN_CHANNEL 1 ++ ++#define P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT 0 /* NOTE(Kevin): Shall <= 16 */ ++#define P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT 13 ++ ++#define P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE 51 /* Contains 6 sub-band. */ ++ ++#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ ++ ++#define P2P_MAXIMUM_CLIENT_COUNT 8 ++#define P2P_MAXIMUM_NOA_COUNT 8 ++ ++#define P2P_MAXIMUM_ATTRIBUTE_LEN 251 ++ ++#define P2P_CTWINDOW_DEFAULT 25 /* in TU=(1024usec) */ ++ ++#define P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE 768 ++ ++/* P2P 3.1.2.1.3 - Find Phase */ ++#define P2P_MAX_DISCOVERABLE_INTERVAL 8 /* 3 */ ++#define P2P_MIN_DISCOVERABLE_INTERVAL 5 /* 1 */ ++ ++#define P2P_LISTEN_SCAN_UNIT 100 /* MS */ ++ ++/* FSM Time Related constrain. */ ++#define P2P_SERACH_STATE_PERIOD_MS 1000 /* Deprecated. */ ++ ++#define P2P_GO_CHANNEL_STAY_INTERVAL 1000 ++ ++#define P2P_GO_NEGO_TIMEOUT_MS 500 ++#define P2P_CONNECTION_TIMEOUT_SEC 120 ++ ++#define P2P_INVITAION_TIMEOUT_MS 500 /* Timeout Wait Invitation Resonse. */ ++#define P2P_PROVISION_DISCOVERY_TIMEOUT_MS 500 /* Timeout Wait Provision Discovery Resonse. */ ++ ++/* 3 --------------- WFA P2P IE --------------- */ ++/* P2P 4.1.1 - P2P IE format */ ++#define P2P_OUI_TYPE_LEN 4 ++#define P2P_IE_OUI_HDR (ELEM_HDR_LEN + P2P_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, ++ aucP2PAttributes[0]) */ ++ ++/* P2P 4.1.1 - General P2P Attribute */ ++#define P2P_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ ++#define P2P_ATTRI_LEN_NOTICE_OF_ABSENCE (P2P_ATTRI_HDR_LEN + 2) /* 5 */ ++ ++/* P2P 4.1.1 - P2P Attribute ID definitions */ ++#define P2P_ATTRI_ID_STATUS 0 ++#define P2P_ATTRI_ID_REASON_CODE 1 ++#define P2P_ATTRI_ID_P2P_CAPABILITY 2 ++#define P2P_ATTRI_ID_P2P_DEV_ID 3 ++#define P2P_ATTRI_ID_GO_INTENT 4 ++#define P2P_ATTRI_ID_CFG_TIMEOUT 5 ++#define P2P_ATTRI_ID_LISTEN_CHANNEL 6 ++#define P2P_ATTRI_ID_P2P_GROUP_BSSID 7 ++#define P2P_ATTRI_ID_EXT_LISTEN_TIMING 8 ++#define P2P_ATTRI_ID_INTENDED_P2P_IF_ADDR 9 ++#define P2P_ATTRI_ID_P2P_MANAGEABILITY 10 ++#define P2P_ATTRI_ID_CHANNEL_LIST 11 ++#define P2P_ATTRI_ID_NOTICE_OF_ABSENCE 12 ++#define P2P_ATTRI_ID_P2P_DEV_INFO 13 ++#define P2P_ATTRI_ID_P2P_GROUP_INFO 14 ++#define P2P_ATTRI_ID_P2P_GROUP_ID 15 ++#define P2P_ATTRI_ID_P2P_INTERFACE 16 ++#define P2P_ATTRI_ID_OPERATING_CHANNEL 17 ++#define P2P_ATTRI_ID_INVITATION_FLAG 18 ++#define P2P_ATTRI_ID_VENDOR_SPECIFIC 221 ++ ++/* Maximum Length of P2P Attributes */ ++#define P2P_ATTRI_MAX_LEN_STATUS 1 /* 0 */ ++#define P2P_ATTRI_MAX_LEN_REASON_CODE 1 /* 1 */ ++#define P2P_ATTRI_MAX_LEN_P2P_CAPABILITY 2 /* 2 */ ++#define P2P_ATTRI_MAX_LEN_P2P_DEV_ID 6 /* 3 */ ++#define P2P_ATTRI_MAX_LEN_GO_INTENT 1 /* 4 */ ++#define P2P_ATTRI_MAX_LEN_CFG_TIMEOUT 2 /* 5 */ ++#if CID52_53_54 ++#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ ++#else ++#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ ++#endif ++#define P2P_ATTRI_MAX_LEN_P2P_GROUP_BSSID 6 /* 7 */ ++#define P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING 4 /* 8 */ ++#define P2P_ATTRI_MAX_LEN_INTENDED_P2P_IF_ADDR 6 /* 9 */ ++#define P2P_ATTRI_MAX_LEN_P2P_MANAGEABILITY 1 /* 10 */ ++/* #define P2P_ATTRI_MAX_LEN_CHANNEL_LIST 3 + (n* (2 + num_of_ch)) */ /* 11 */ ++#define P2P_ATTRI_LEN_CHANNEL_LIST 3 /* 11 */ ++#define P2P_ATTRI_LEN_CHANNEL_ENTRY 2 /* 11 */ ++ ++/* #define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE 2 + (n* (13)) */ /* 12 */ ++#define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE (2 + (P2P_MAXIMUM_NOA_COUNT*(13))) /* 12 */ ++ ++#define P2P_ATTRI_MAX_LEN_P2P_DEV_INFO (17 + (8 * (8)) + 36) /* 13 */ ++/* #define P2P_ATTRI_MAX_LEN_P2P_GROUP_INFO n* (25 + (m* (8)) + 32) */ /* 14 */ ++#define P2P_ATTRI_MAX_LEN_P2P_GROUP_ID 38 /* 15 */ ++#define P2P_ATTRI_MAX_LEN_P2P_INTERFACE 253 /* 7 + 6* [0~41] */ /* 16 */ ++#if CID52_53_54 ++#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ ++#else ++#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ ++#endif ++#define P2P_ATTRI_MAX_LEN_INVITATION_FLAGS 1 /* 18 */ ++ ++/* P2P 4.1.2 - P2P Status definitions */ ++#define P2P_STATUS_SUCCESS 0 ++#define P2P_STATUS_FAIL_INFO_IS_CURRENTLY_UNAVAILABLE 1 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 2 ++#define P2P_STATUS_FAIL_LIMIT_REACHED 3 ++#define P2P_STATUS_FAIL_INVALID_PARAM 4 ++#define P2P_STATUS_FAIL_UNABLE_ACCOMMODATE_REQ 5 ++#define P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR 6 ++#define P2P_STATUS_FAIL_NO_COMMON_CHANNELS 7 ++#define P2P_STATUS_FAIL_UNKNOWN_P2P_GROUP 8 ++#define P2P_STATUS_FAIL_SAME_INTENT_VALUE_15 9 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVISION_METHOD 10 ++#define P2P_STATUS_FAIL_REJECTED_BY_USER 11 ++ ++/* P2P 4.1.3 - P2P Minor Reason Code definitions */ ++#define P2P_REASON_SUCCESS 0 ++#define P2P_REASON_DISASSOCIATED_DUE_CROSS_CONNECTION 1 ++#define P2P_REASON_DISASSOCIATED_DUE_UNMANAGEABLE 2 ++#define P2P_REASON_DISASSOCIATED_DUE_NO_P2P_COEXIST_PARAM 3 ++#define P2P_REASON_DISASSOCIATED_DUE_MANAGEABLE 4 ++ ++/* P2P 4.1.4 - Device Capability Bitmap definitions */ ++#define P2P_DEV_CAPABILITY_SERVICE_DISCOVERY BIT(0) ++#define P2P_DEV_CAPABILITY_CLIENT_DISCOVERABILITY BIT(1) ++#define P2P_DEV_CAPABILITY_CONCURRENT_OPERATION BIT(2) ++#define P2P_DEV_CAPABILITY_P2P_INFRA_MANAGED BIT(3) ++#define P2P_DEV_CAPABILITY_P2P_DEVICE_LIMIT BIT(4) ++#define P2P_DEV_CAPABILITY_P2P_INVITATION_PROCEDURE BIT(5) ++ ++/* P2P 4.1.4 - Group Capability Bitmap definitions */ ++#define P2P_GROUP_CAPABILITY_P2P_GROUP_OWNER BIT(0) ++#define P2P_GROUP_CAPABILITY_PERSISTENT_P2P_GROUP BIT(1) ++#define P2P_GROUP_CAPABILITY_P2P_GROUP_LIMIT BIT(2) ++#define P2P_GROUP_CAPABILITY_INTRA_BSS_DISTRIBUTION BIT(3) ++#define P2P_GROUP_CAPABILITY_CROSS_CONNECTION BIT(4) ++#define P2P_GROUP_CAPABILITY_PERSISTENT_RECONNECT BIT(5) ++#define P2P_GROUP_CAPABILITY_GROUP_FORMATION BIT(6) ++ ++/* P2P 4.1.6 - GO Intent field definitions */ ++#define P2P_GO_INTENT_TIE_BREAKER_FIELD BIT(0) ++#define P2P_GO_INTENT_VALUE_MASK BITS(1, 7) ++#define P2P_GO_INTENT_VALUE_OFFSET 1 ++ ++/* P2P 4.1.12 - Manageability Bitmap definitions */ ++#define P2P_DEVICE_MANAGEMENT BIT(0) ++ ++/* P2P 4.1.14 - CTWindow and OppPS Parameters definitions */ ++#define P2P_CTW_OPPPS_PARAM_OPPPS_FIELD BIT(7) ++#define P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK BITS(0, 6) ++ ++#define ELEM_MAX_LEN_P2P_FOR_PROBE_REQ \ ++ (P2P_OUI_TYPE_LEN + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_ID) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL)) ++ ++#define ELEM_MAX_LEN_P2P_FOR_ASSOC_REQ \ ++ (P2P_OUI_TYPE_LEN + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING) + \ ++ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_INFO)) ++ ++/* P2P 4.1.16 - P2P Client Infor Descriptor */ ++#define P2P_CLIENT_INFO_DESC_HDR_LEN 1 /* Length(1 octets) */ ++ ++/* P2P 4.1.20 - P2P Invitation Flags Attribute*/ ++#define P2P_INVITATION_FLAGS_INVITATION_TYPE BIT(0) ++#define P2P_INVITATION_TYPE_INVITATION 0 ++#define P2P_INVITATION_TYPE_REINVOKE 1 ++/* 3 --------------- WPS Data Element Definitions --------------- */ ++/* P2P 4.2.2 - General WSC Attribute */ ++#define WSC_ATTRI_HDR_LEN 4 /* ID(2 octet) + Length(2 octets) */ ++#define WSC_ATTRI_MAX_LEN_VERSION 1 ++#define WSC_ATTRI_MAX_LEN_DEVICE_PASSWORD_ID 2 ++#define WSC_ATTRI_LEN_CONFIG_METHOD 2 ++ ++/* WPS 11 - Data Element Definitions */ ++#define WPS_ATTRI_ID_VERSION 0x104A ++#define WPS_ATTRI_ID_CONFIGURATION_METHODS 0x1008 ++#define WPS_ATTRI_ID_DEVICE_PASSWORD 0x1012 ++#define WPS_ATTRI_ID_DEVICE_NAME 0x1011 ++#define WPS_ATTRI_ID_PRI_DEVICE_TYPE 0x1054 ++#define WPS_ATTRI_ID_SEC_DEVICE_TYPE 0x1055 ++ ++#define WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE 300 ++ ++#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ ++ ++#define WPS_ATTRI_CFG_METHOD_USBA BIT(0) ++#define WPS_ATTRI_CFG_METHOD_ETHERNET BIT(1) ++#define WPS_ATTRI_CFG_METHOD_LABEL BIT(2) ++#define WPS_ATTRI_CFG_METHOD_DISPLAY BIT(3) ++#define WPS_ATTRI_CFG_METHOD_EXT_NFC BIT(4) ++#define WPS_ATTRI_CFG_METHOD_INT_NFC BIT(5) ++#define WPS_ATTRI_CFG_METHOD_NFC_IF BIT(6) ++#define WPS_ATTRI_CFG_METHOD_PUSH_BUTTON BIT(7) ++#define WPS_ATTRI_CFG_METHOD_KEYPAD BIT(8) ++ ++#define P2P_FLAGS_PROVISION_COMPLETE 0x00000001 ++#define P2P_FLAGS_PROVISION_DISCOVERY_COMPLETE 0x00000002 ++#define P2P_FLAGS_PROVISION_DISCOVERY_WAIT_RESPONSE 0x00000004 ++#define P2P_FLAGS_PROVISION_DISCOVERY_RESPONSE_WAIT 0x00000008 ++#define P2P_FLAGS_MASK_PROVISION 0x00000017 ++#define P2P_FLAGS_MASK_PROVISION_COMPLETE 0x00000015 ++#define P2P_FLAGS_PROVISION_DISCOVERY_INDICATED 0x00000010 ++#define P2P_FLAGS_INVITATION_TOBE_GO 0x00000100 ++#define P2P_FLAGS_INVITATION_TOBE_GC 0x00000200 ++#define P2P_FLAGS_INVITATION_SUCCESS 0x00000400 ++#define P2P_FLAGS_INVITATION_WAITING_TARGET 0x00000800 ++#define P2P_FLAGS_MASK_INVITATION 0x00000F00 ++#define P2P_FLAGS_FORMATION_ON_GOING 0x00010000 ++#define P2P_FLAGS_FORMATION_LOCAL_PWID_RDY 0x00020000 ++#define P2P_FLAGS_FORMATION_TARGET_PWID_RDY 0x00040000 ++#define P2P_FLAGS_FORMATION_COMPLETE 0x00080000 ++#define P2P_FLAGS_MASK_FORMATION 0x000F0000 ++#define P2P_FLAGS_DEVICE_DISCOVER_REQ 0x00100000 ++#define P2P_FLAGS_DEVICE_DISCOVER_DONE 0x00200000 ++#define P2P_FLAGS_DEVICE_INVITATION_WAIT 0x00400000 ++#define P2P_FLAGS_DEVICE_SERVICE_DISCOVER_WAIT 0x00800000 ++#define P2P_FLAGS_MASK_DEVICE_DISCOVER 0x00F00000 ++ ++#define P2P_FLAGS_DEVICE_FORMATION_REQUEST 0x01000000 ++ ++/* MACRO for flag operation */ ++#define SET_FLAGS(_FlagsVar, _BitsToSet) \ ++ {(_FlagsVar) = ((_FlagsVar) | (_BitsToSet))} ++ ++#define TEST_FLAGS(_FlagsVar, _BitsToCheck) \ ++ (((_FlagsVar) & (_BitsToCheck)) == (_BitsToCheck)) ++ ++#define CLEAR_FLAGS(_FlagsVar, _BitsToClear) \ ++ {(_FlagsVar) &= ~(_BitsToClear)} ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_I 0 ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_II 0 ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_III 0 ++ ++#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_IV 0 ++ ++#define CFG_DISABLE_DELAY_PROVISION_DISCOVERY 0 ++ ++#define CFG_CONNECTION_POLICY_2_0 0 ++ ++/* Device Password ID */ ++enum wps_dev_password_id { ++ DEV_PW_DEFAULT = 0x0000, ++ DEV_PW_USER_SPECIFIED = 0x0001, ++ DEV_PW_MACHINE_SPECIFIED = 0x0002, ++ DEV_PW_REKEY = 0x0003, ++ DEV_PW_PUSHBUTTON = 0x0004, ++ DEV_PW_REGISTRAR_SPECIFIED = 0x0005 ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack(1) ++#endif ++ ++/* 3 --------------- WFA P2P IE and Attributes --------------- */ ++ ++/* P2P 4.1.1 - P2P Information Element */ ++typedef struct _IE_P2P_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 aucP2PAttributes[1]; /* P2P Attributes */ ++} __KAL_ATTRIB_PACKED__ IE_P2P_T, *P_IE_P2P_T; ++ ++/* P2P 4.1.1 - General P2P Attribute */ ++typedef struct _P2P_ATTRIBUTE_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBody[1]; /* Body field */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRIBUTE_T, ATTRIBUTE_HDR_T, *P_P2P_ATTRIBUTE_T, *P_ATTRIBUTE_HDR_T; ++ ++/* P2P 4.1.2 - P2P Status Attribute */ ++typedef struct _P2P_ATTRI_STATUS_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucStatusCode; /* Status Code */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_STATUS_T, *P_P2P_ATTRI_STATUS_T; ++ ++/* P2P 4.1.3 - P2P Minor Reason Code Attribute */ ++typedef struct _P2P_ATTRI_REASON_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucMinorReasonCode; /* Minor Reason Code */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_REASON_T, *P_P2P_ATTRI_REASON_T; ++ ++/* P2P 4.1.4 - P2P Capability Attribute */ ++typedef struct _P2P_ATTRI_CAPABILITY_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ ++ UINT_8 ucGroupCap; /* Group Capability Bitmap */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CAPABILITY_T, *P_P2P_ATTRI_CAPABILITY_T; ++ ++/* P2P 4.1.5 - P2P Device ID Attribute */ ++typedef struct _P2P_ATTRI_DEV_ID_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_ID_T, *P_P2P_ATTRI_DEV_ID_T; ++ ++/* P2P 4.1.6 - Group Owner Intent Attribute */ ++typedef struct _P2P_ATTRI_GO_INTENT_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucGOIntent; /* Group Owner Intent */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GO_INTENT_T, *P_P2P_ATTRI_GO_INTENT_T; ++ ++/* P2P 4.1.7 - Configuration Timeout Attribute */ ++typedef struct _P2P_ATTRI_CFG_TIMEOUT_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucGOCfgTimeout; /* GO Configuration Timeout */ ++ UINT_8 ucClientCfgTimeout; /* Client Configuration Timeout */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CFG_TIMEOUT_T, *P_P2P_ATTRI_CFG_TIMEOUT_T; ++ ++/* P2P 4.1.8 - Listen Channel Attribute */ ++typedef struct _P2P_ATTRI_LISTEN_CHANNEL_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucCountryString[3]; /* Country String */ ++ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ ++ UINT_8 ucChannelNumber; /* Channel Number */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_LISTEN_CHANNEL_T, *P_P2P_ATTRI_LISTEN_CHANNEL_T; ++ ++/* P2P 4.1.9 - P2P Group BSSID Attribute */ ++typedef struct _P2P_ATTRI_GROUP_BSSID_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBssid[MAC_ADDR_LEN]; /* P2P Group BSSID */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_BSSID_T, *P_P2P_ATTRI_GROUP_BSSID_T; ++ ++/* P2P 4.1.10 - Extended Listen Timing Attribute */ ++typedef struct _P2P_ATTRI_EXT_LISTEN_TIMING_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_16 u2AvailPeriod; /* Availability Period */ ++ UINT_16 u2AvailInterval; /* Availability Interval */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_EXT_LISTEN_TIMING_T, *P_P2P_ATTRI_EXT_LISTEN_TIMING_T; ++ ++/* P2P 4.1.11 - Intended P2P Interface Address Attribute */ ++typedef struct _P2P_ATTRI_INTENDED_IF_ADDR_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTENDED_IF_ADDR_T, *P_P2P_ATTRI_INTENDED_IF_ADDR_T; ++ ++/* P2P 4.1.12 - P2P Manageability Attribute */ ++typedef struct _P2P_ATTRI_MANAGEABILITY_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucManageability; /* P2P Manageability Bitmap */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_MANAGEABILITY_T, *P_P2P_ATTRI_MANAGEABILITY_T; ++ ++/* P2P 4.1.13 - Channel List Attribute */ ++typedef struct _P2P_ATTRI_CHANNEL_LIST_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucCountryString[3]; /* Country String */ ++ UINT_8 aucChannelEntry[1]; /* Channel Entry List */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CHANNEL_T, *P_P2P_ATTRI_CHANNEL_T; ++ ++typedef struct _CHANNEL_ENTRY_FIELD_T { ++ UINT_8 ucRegulatoryClass; /* Regulatory Class */ ++ UINT_8 ucNumberOfChannels; /* Number Of Channels */ ++ UINT_8 aucChannelList[1]; /* Channel List */ ++} __KAL_ATTRIB_PACKED__ CHANNEL_ENTRY_FIELD_T, *P_CHANNEL_ENTRY_FIELD_T; ++ ++/* P2P 4.1.14 - Notice of Absence Attribute */ ++typedef struct _P2P_ATTRI_NOA_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucIndex; /* Index */ ++ UINT_8 ucCTWOppPSParam; /* CTWindow and OppPS Parameters */ ++ UINT_8 aucNoADesc[1]; /* NoA Descriptor */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_NOA_T, *P_P2P_ATTRI_NOA_T; ++ ++typedef struct _NOA_DESCRIPTOR_T { ++ UINT_8 ucCountType; /* Count/Type */ ++ UINT_32 u4Duration; /* Duration */ ++ UINT_32 u4Interval; /* Interval */ ++ UINT_32 u4StartTime; /* Start Time */ ++} __KAL_ATTRIB_PACKED__ NOA_DESCRIPTOR_T, *P_NOA_DESCRIPTOR_T; ++ ++typedef struct _P2P_ATTRI_DEV_INFO_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_16 u2ConfigMethodsBE; /* Config Method */ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ ++ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ ++ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_INFO_T, *P_P2P_ATTRI_DEV_INFO_T; ++ ++/* WPS 7.1 & 11 WPS TLV Data Format - Device Name */ ++typedef struct _DEVICE_NAME_TLV_T { ++ UINT_16 u2Id; /* WPS Attribute Type */ ++ UINT_16 u2Length; /* Data Length */ ++ UINT_8 aucName[32]; /* Device Name */ /* TODO: Fixme */ ++} __KAL_ATTRIB_PACKED__ DEVICE_NAME_TLV_T, *P_DEVICE_NAME_TLV_T; ++ ++/* P2P 4.1.16 - P2P Group Info Attribute */ ++typedef struct _P2P_CLIENT_INFO_DESC_T { ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ ++ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ ++ UINT_16 u2ConfigMethodsBE; /* Config Method */ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ ++ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ ++ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ ++} __KAL_ATTRIB_PACKED__ P2P_CLIENT_INFO_DESC_T, *P_P2P_CLIENT_INFO_DESC_T; ++ ++typedef struct _P2P_ATTRI_GROUP_INFO_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ P2P_CLIENT_INFO_DESC_T arClientDesc[1]; /* P2P Client Info Descriptors */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_INFO_T, *P_P2P_ATTRI_GROUP_INFO_T; ++ ++/* P2P 4.1.17 - P2P Group ID Attribute */ ++typedef struct _P2P_ATTRI_GROUP_ID_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_ID_T, *P_P2P_ATTRI_GROUP_ID_T; ++ ++/* P2P 4.1.18 - P2P Interface Attribute */ ++typedef struct _P2P_ATTRI_INTERFACE_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ ++ UINT_8 ucIfAddrCount; /* P2P Interface Address Count */ ++ UINT_8 aucIfAddrList[MAC_ADDR_LEN]; /* P2P Interface Address List */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTERFACE_T, *P_P2P_ATTRI_INTERFACE_T; ++ ++/* P2P 4.1.19 - Operating Channel Attribute */ ++typedef struct _P2P_ATTRI_OPERATING_CHANNEL_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucCountryString[3]; /* Country String */ ++ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ ++ UINT_8 ucChannelNumber; /* Channel Number */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_OPERATING_CHANNEL_T, *P_P2P_ATTRI_OPERATING_CHANNEL_T; ++ ++/* P2P 4.1.20 - Invitation Flags Attribute */ ++typedef struct _P2P_ATTRI_INVITATION_FLAG_T { ++ UINT_8 ucId; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucInviteFlagsBitmap; /* Invitation Flags Bitmap */ ++} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INVITATION_FLAG_T, *P_P2P_ATTRI_INVITATION_FLAG_T; ++ ++/* P2P 4.1.1 - General WSC Attribute */ ++typedef struct _WSC_ATTRIBUTE_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBody[1]; /* Body field */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRIBUTE_T, *P_WSC_ATTRIBUTE_T; ++ ++/* WSC 1.0 Table 28 */ ++typedef struct _WSC_ATTRI_VERSION_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 ucVersion; /* Version 1.0 or 1.1 */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRI_VERSION_T, *P_WSC_ATTRI_VERSION_T; ++ ++typedef struct _WSC_ATTRI_DEVICE_PASSWORD_ID_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_16 u2DevPasswordId; /* Device Password ID */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRI_DEVICE_PASSWORD_ID_T, *P_WSC_ATTRI_DEVICE_PASSWORD_ID_T; ++ ++typedef struct _WSC_ATTRI_CONFIGURATION_METHOD_T { ++ UINT_16 u2Id; /* Attribute ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_16 u2ConfigMethods; /* Configure Methods */ ++} __KAL_ATTRIB_PACKED__ WSC_ATTRI_CONFIGURATION_METHOD_T, *P_WSC_ATTRI_CONFIGURATION_METHOD_T; ++ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack() ++#endif ++ ++/* 3 --------------- WFA P2P Attributes Handler prototype --------------- */ ++typedef UINT_32(*PFN_APPEND_ATTRI_FUNC) (P_ADAPTER_T, BOOLEAN, PUINT_16, PUINT_8, UINT_16); ++ ++typedef VOID(*PFN_HANDLE_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T); ++ ++typedef VOID(*PFN_VERIFY_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T, PUINT_16); ++ ++typedef UINT_32(*PFN_CALCULATE_VAR_ATTRI_LEN_FUNC) (P_ADAPTER_T, P_STA_RECORD_T); ++ ++typedef struct _APPEND_VAR_ATTRI_ENTRY_T { ++ UINT_16 u2EstimatedFixedAttriLen; /* For fixed length */ ++ PFN_CALCULATE_VAR_ATTRI_LEN_FUNC pfnCalculateVariableAttriLen; ++ PFN_APPEND_ATTRI_FUNC pfnAppendAttri; ++} APPEND_VAR_ATTRI_ENTRY_T, *P_APPEND_VAR_ATTRI_ENTRY_T; ++ ++typedef enum _ENUM_CONFIG_METHOD_SEL { ++ ENUM_CONFIG_METHOD_SEL_AUTO, ++ ENUM_CONFIG_METHOD_SEL_USER, ++ ENUM_CONFIG_METHOD_SEL_NUM ++} ENUM_CONFIG_METHOD_SEL, *P_ENUM_CONFIG_METHOD_SEL; ++ ++typedef enum _ENUM_P2P_FORMATION_POLICY { ++ ENUM_P2P_FORMATION_POLICY_AUTO = 0, ++ ENUM_P2P_FORMATION_POLICY_PASSIVE, /* Device would wait GO NEGO REQ instead of sending it actively. */ ++ ENUM_P2P_FORMATION_POLICY_NUM ++} ENUM_P2P_FORMATION_POLICY, P_ENUM_P2P_FORMATION_POLICY; ++ ++typedef enum _ENUM_P2P_INVITATION_POLICY { ++ ENUM_P2P_INVITATION_POLICY_USER = 0, ++ ENUM_P2P_INVITATION_POLICY_ACCEPT_FIRST, ++ ENUM_P2P_INVITATION_POLICY_DENY_ALL, ++ ENUM_P2P_INVITATION_POLICY_NUM ++} ENUM_P2P_INVITATION_POLICY, P_ENUM_P2P_INVITATION_POLICY; ++ ++/* 3 --------------- Data Structure for P2P Operation --------------- */ ++/* 3 Session for CONNECTION SETTINGS of P2P */ ++struct _P2P_CONNECTION_SETTINGS_T { ++ UINT_8 ucDevNameLen; ++ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; ++ ++ DEVICE_TYPE_T rPrimaryDevTypeBE; ++ ++ ENUM_P2P_FORMATION_POLICY eFormationPolicy; /* Formation Policy. */ ++ ++ /*------------WSC Related Param---------------*/ ++ UINT_16 u2ConfigMethodsSupport; /* Preferred configure method. ++ * Some device may not have keypad. ++ */ ++ ENUM_CONFIG_METHOD_SEL eConfigMethodSelType; ++ UINT_16 u2TargetConfigMethod; /* Configure method selected by user or auto. */ ++ UINT_16 u2LocalConfigMethod; /* Configure method of target. */ ++ BOOLEAN fgIsPasswordIDRdy; ++ /*------------WSC Related Param---------------*/ ++ ++ UINT_8 ucClientConfigTimeout; ++ UINT_8 ucGoConfigTimeout; ++ ++ UINT_8 ucSecondaryDevTypeCount; ++#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT ++ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT]; ++#endif ++ ++#if 0 ++ UINT_8 ucRfChannelListCount; ++#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT ++ UINT_8 aucChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering ++ depends on 802.11mb Annex J. */ ++ ++#endif ++#else ++ UINT_8 ucRfChannelListSize; ++#if P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE ++ UINT_8 aucChannelEntriesField[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE]; ++#endif ++#endif ++ ++ /* Go Intent */ ++ UINT_8 ucTieBreaker; ++ UINT_8 ucGoIntent; ++ ++ /* For Device Capability */ ++ BOOLEAN fgSupportServiceDiscovery; ++ BOOLEAN fgSupportClientDiscoverability; ++ BOOLEAN fgSupportConcurrentOperation; ++ BOOLEAN fgSupportInfraManaged; ++ BOOLEAN fgSupportInvitationProcedure; ++ ++ /* For Group Capability */ ++ BOOLEAN fgSupportPersistentP2PGroup; ++ BOOLEAN fgSupportIntraBSSDistribution; ++ BOOLEAN fgSupportCrossConnection; ++ BOOLEAN fgSupportPersistentReconnect; ++ ++ BOOLEAN fgP2pGroupLimit; ++ ++ BOOLEAN fgSupportOppPS; ++ UINT_16 u2CTWindow; ++ ++ BOOLEAN fgIsScanReqIssued; ++ BOOLEAN fgIsServiceDiscoverIssued; ++ ++ /*============ Target Device Connection Settings ============*/ ++ ++ /* Discover Target Device Info. */ ++ BOOLEAN fgIsDevId; ++ BOOLEAN fgIsDevType; ++ ++ /* Encryption mode of Target Device */ ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ ++ /* SSID ++ * 1. AP Mode, this is the desired SSID user specified. ++ * 2. Client Mode, this is the target SSID to be connected to. ++ */ ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ UINT_8 ucSSIDLen; ++ ++ /* Operating channel requested. */ ++ UINT_8 ucOperatingChnl; ++ ENUM_BAND_T eBand; ++ ++ /* Linten channel requested. */ ++ UINT_8 ucListenChnl; ++ ++ /* For device discover address/type. */ ++ UINT_8 aucTargetDevAddr[MAC_ADDR_LEN]; /* P2P Device Address, for P2P Device Discovery & P2P Connection. */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ P_P2P_DEVICE_DESC_T prTargetP2pDesc; ++#endif ++ ++ UINT_8 ucLastStatus; /* P2P FSM would append status attribute according to this field. */ ++ ++#if !CFG_DISABLE_DELAY_PROVISION_DISCOVERY ++ UINT_8 ucLastDialogToken; ++ UINT_8 aucIndicateDevAddr[MAC_ADDR_LEN]; ++#endif ++ ++#if 0 ++ UINT_8 ucTargetRfChannelListCount; ++#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT ++ UINT_8 aucTargetChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering ++ depends on 802.11mb Annex J. */ ++#endif ++#endif ++ ++}; ++ ++typedef struct _NOA_TIMING_T { ++ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ ++ UINT_8 ucCount; /* Count */ ++ ++ UINT_8 aucReserved[2]; ++ ++ UINT_32 u4Duration; /* Duration */ ++ UINT_32 u4Interval; /* Interval */ ++ UINT_32 u4StartTime; /* Start Time */ ++} NOA_TIMING_T, *P_NOA_TIMING_T; ++ ++typedef enum _ENUM_P2P_IOCTL_T { ++ P2P_IOCTL_IDLE = 0, ++ P2P_IOCTL_DEV_DISCOVER, ++ P2P_IOCTL_INVITATION_REQ, ++ P2P_IOCTL_SERV_DISCOVER, ++ P2P_IOCTL_WAITING, ++ P2P_IOCTL_NUM ++} ENUM_P2P_IOCTL_T; ++ ++/*---------------- Service Discovery Related -------------------*/ ++typedef enum _ENUM_SERVICE_TX_TYPE_T { ++ ENUM_SERVICE_TX_TYPE_BY_DA, ++ ENUM_SERVICE_TX_TYPE_BY_CHNL, ++ ENUM_SERVICE_TX_TYPE_NUM ++} ENUM_SERVICE_TX_TYPE_T; ++ ++typedef struct _SERVICE_DISCOVERY_FRAME_DATA_T { ++ QUE_ENTRY_T rQueueEntry; ++ P_MSDU_INFO_T prSDFrame; ++ ENUM_SERVICE_TX_TYPE_T eServiceType; ++ UINT_8 ucSeqNum; ++ union { ++ ++ UINT_8 ucChannelNum; ++ UINT_8 aucPeerAddr[MAC_ADDR_LEN]; ++ } uTypeData; ++ BOOLEAN fgIsTxDoneIndicate; ++} SERVICE_DISCOVERY_FRAME_DATA_T, *P_SERVICE_DISCOVERY_FRAME_DATA_T; ++ ++struct _P2P_FSM_INFO_T_DEPRECATED { ++ /* P2P FSM State */ ++ ENUM_P2P_STATE_T eCurrentState; ++ ++ /* Channel */ ++ BOOLEAN fgIsChannelRequested; ++ ++ ENUM_P2P_STATE_T ePreviousState; ++ ++ ENUM_P2P_STATE_T eReturnState; /* Return state after current activity finished or abort. */ ++ ++ UINT_8 aucTargetIfAddr[PARAM_MAC_ADDR_LEN]; ++ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ ++ ++ P_STA_RECORD_T prTargetStaRec; ++ ++ BOOLEAN fgIsRsponseProbe; /* Indicate if P2P FSM can response probe request frame. */ ++ ++ /* Sequence number of requested message. */ ++ UINT_8 ucSeqNumOfReqMsg; /* Used for SAA FSM request message. */ ++ ++ /* Channel Privilege */ ++ UINT_8 ucSeqNumOfChReq; /* Used for Channel Request message. */ ++ ++ UINT_8 ucSeqNumOfScnMsg; /* Used for SCAN FSM request message. */ ++ UINT_8 ucSeqNumOfCancelMsg; ++ ++ UINT_8 ucDialogToken; ++ UINT_8 ucRxDialogToken; ++ ++ /* Timer */ ++ TIMER_T rDeviceDiscoverTimer; /* For device discovery time of each discovery request from user. */ ++ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ ++ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ ++ ++ TIMER_T rRejoinTimer; /* A timer used for Action frame timeout usage. */ ++ ++ /* Flag to indicate Provisioning */ ++ BOOLEAN fgIsConnectionRequested; ++ ++ /* Current IOCTL. */ ++ ENUM_P2P_IOCTL_T eP2pIOCTL; ++ ++ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ ++ ++ /*--------SERVICE DISCOVERY--------*/ ++ QUE_T rQueueGASRx; /* Input Request/Response. */ ++ QUE_T rQueueGASTx; /* Output Response. */ ++ P_SERVICE_DISCOVERY_FRAME_DATA_T prSDRequest; ++ UINT_8 ucVersionNum; /* GAS packet sequence number for...Action Frame? */ ++ UINT_8 ucGlobalSeqNum; /* Sequence Number of RX SD packet. */ ++ /*--------Service DISCOVERY--------*/ ++ ++ /*--------DEVICE DISCOVERY---------*/ ++ UINT_8 aucTargetGroupID[PARAM_MAC_ADDR_LEN]; ++ UINT_16 u2TargetGroupSsidLen; ++ UINT_8 aucTargetSsid[32]; ++ UINT_8 aucSearchingP2pDevice[PARAM_MAC_ADDR_LEN]; ++ UINT_8 ucDLToken; ++ /*----------------------------------*/ ++ ++ /* Indicating Peer Status. */ ++ UINT_32 u4Flags; ++ ++ /*Indicating current running mode. */ ++ BOOLEAN fgIsApMode; ++ ++ /*------------INVITATION------------*/ ++ ENUM_P2P_INVITATION_POLICY eInvitationRspPolicy; ++ /*----------------------------------*/ ++ ++}; ++ ++struct _P2P_SPECIFIC_BSS_INFO_T { ++ /* For GO(AP) Mode - Compose TIM IE */ ++ UINT_16 u2SmallestAID; ++ UINT_16 u2LargestAID; ++ UINT_8 ucBitmapCtrl; ++ /* UINT_8 aucPartialVirtualBitmap[MAX_LEN_TIM_PARTIAL_BMP]; */ ++ ++ /* For GC/GO OppPS */ ++ BOOLEAN fgEnableOppPS; ++ UINT_16 u2CTWindow; ++ ++ /* For GC/GO NOA */ ++ UINT_8 ucNoAIndex; ++ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ ++ NOA_TIMING_T arNoATiming[P2P_MAXIMUM_NOA_COUNT]; ++ ++ BOOLEAN fgIsNoaAttrExisted; ++ ++ /* For P2P Device */ ++ UINT_8 ucRegClass; /* Regulatory Class for channel. */ ++ UINT_8 ucListenChannel; /* Linten Channel only on channels 1, 6 and 11 in the 2.4 GHz. */ ++ ++ UINT_8 ucPreferredChannel; /* Operating Channel, should be one of channel list ++ in p2p connection settings. */ ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_BAND_T eRfBand; ++ ++ /* Extended Listen Timing. */ ++ UINT_16 u2AvailabilityPeriod; ++ UINT_16 u2AvailabilityInterval; ++ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++ UINT_16 u2IELenForBCN; ++ UINT_8 aucBeaconIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++ ++/* UINT_16 u2IELenForProbeRsp; */ ++/* UINT_8 aucProbeRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; */ ++ ++ UINT_16 u2IELenForAssocRsp; ++ UINT_8 aucAssocRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++ ++#else ++ UINT_16 u2AttributeLen; ++ UINT_8 aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++ ++ UINT_16 u2WscAttributeLen; ++ UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; ++#endif ++ UINT_8 aucGroupID[MAC_ADDR_LEN]; ++ UINT_16 u2GroupSsidLen; ++ UINT_8 aucGroupSsid[ELEM_MAX_LEN_SSID]; ++ ++ PARAM_CUSTOM_NOA_PARAM_STRUCT_T rNoaParam; ++ PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T rOppPsParam; ++ ++ UINT_16 u2WpaIeLen; ++ UINT_8 aucWpaIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_WPA]; ++}; ++ ++typedef struct _MSG_P2P_DEVICE_DISCOVER_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_32 u4DevDiscoverTime; /* 0: Infinite, 1~X: in unit of MS. */ ++ BOOLEAN fgIsSpecificType; ++#if CFG_ENABLE_WIFI_DIRECT ++ P2P_DEVICE_TYPE_T rTargetDeviceType; ++#endif ++ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN]; ++} MSG_P2P_DEVICE_DISCOVER_T, *P_MSG_P2P_DEVICE_DISCOVER_T; ++ ++typedef struct _MSG_P2P_INVITATION_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 aucDeviceID[MAC_ADDR_LEN]; /* Target Device ID to be invited. */ ++} MSG_P2P_INVITATION_REQUEST_T, *P_MSG_P2P_INVITATION_REQUEST_T; ++ ++typedef struct _MSG_P2P_FUNCTION_SWITCH_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ BOOLEAN fgIsFuncOn; ++} MSG_P2P_FUNCTION_SWITCH_T, *P_MSG_P2P_FUNCTION_SWITCH_T; ++ ++typedef struct _MSG_P2P_SERVICE_DISCOVERY_REQUEST_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 aucDeviceID[MAC_ADDR_LEN]; ++ BOOLEAN fgNeedTxDoneIndicate; ++ UINT_8 ucSeqNum; ++} MSG_P2P_SERVICE_DISCOVERY_REQUEST_T, *P_MSG_P2P_SERVICE_DISCOVERY_REQUEST_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define p2pChangeMediaState(_prAdapter, _eNewMediaState) \ ++do { \ ++ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState = (_eNewMediaState));\ ++ wfdChangeMediaState((_prAdapter), NETWORK_TYPE_P2P_INDEX, (_eNewMediaState)); \ ++} while (0) ++ ++#define ATTRI_ID(_fp) (((P_P2P_ATTRIBUTE_T) _fp)->ucId) ++#define ATTRI_LEN(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[0]) | \ ++ ((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[1] << 8)) ++ ++#define ATTRI_SIZE(_fp) (P2P_ATTRI_HDR_LEN + ATTRI_LEN(_fp)) ++ ++#define P2P_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ ++ (_u2Offset) += ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += ATTRI_SIZE(_pucAttriBuf))) ++ ++#define P2P_IE(_fp) ((P_IE_P2P_T) _fp) ++ ++#define WSC_ATTRI_ID(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[0] << 8) | \ ++ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[1])) ++ ++#define WSC_ATTRI_LEN(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ ++ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[1])) ++ ++#define WSC_ATTRI_SIZE(_fp) (WSC_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp)) ++ ++#define WSC_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ ++ (_u2Offset) += WSC_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WSC_ATTRI_SIZE(_pucAttriBuf))) ++ ++#define WSC_IE(_fp) ((P_IE_P2P_T) _fp) ++ ++#define WFD_ATTRI_ID(_fp) (((P_WFD_ATTRIBUTE_T) _fp)->ucElemID) ++ ++#define WFD_ATTRI_LEN(_fp) \ ++ (((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ ++ ((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[1])) ++ ++#define WFD_ATTRI_SIZE(_fp) (WFD_ATTRI_HDR_LEN + WFD_ATTRI_LEN(_fp)) ++ ++#define WFD_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ ++ (_u2Offset) += WFD_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WFD_ATTRI_SIZE(_pucAttriBuf))) ++ ++#if DBG ++#define ASSERT_BREAK(_exp) \ ++ { \ ++ if (!(_exp)) { \ ++ ASSERT(FALSE); \ ++ break; \ ++ } \ ++ } ++ ++#else ++#define ASSERT_BREAK(_exp) ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*======P2P State======*/ ++VOID ++p2pStateInit_LISTEN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_SPECIFIC_BSS_INFO_T prSP2pBssInfo, IN UINT_8 ucListenChannel); ++ ++VOID p2pStateAbort_LISTEN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); ++ ++VOID p2pStateAbort_SEARCH_SCAN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); ++ ++VOID p2pStateAbort_GO_OPERATION(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pStateAbort_GC_OPERATION(IN P_ADAPTER_T prAdapter); ++ ++VOID ++p2pStateInit_CONFIGURATION(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecBssInfo); ++ ++VOID p2pStateAbort_CONFIGURATION(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pStateInit_JOIN(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pStateAbort_JOIN(IN P_ADAPTER_T prAdapter); ++ ++/*====== P2P Functions ======*/ ++ ++VOID p2pFuncInitGO(IN P_ADAPTER_T prAdapter); ++ ++VOID ++p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); ++ ++VOID ++p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW); ++ ++VOID p2pFuncRunEventProvisioningComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++WLAN_STATUS p2pFuncSetGroupID(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucGroupID, IN PUINT_8 pucSsid, IN UINT_8 ucSsidLen); ++ ++WLAN_STATUS ++p2pFuncSendDeviceDiscoverabilityReqFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); ++ ++WLAN_STATUS ++p2pFuncSendDeviceDiscoverabilityRspFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); ++ ++UINT_8 p2pFuncGetVersionNumOfSD(IN P_ADAPTER_T prAdapter); ++ ++/*====== P2P FSM ======*/ ++VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventDeviceDiscoveryRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventDeviceDiscoveryAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventRxGroupNegotiationReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS ++p2pFsmRunEventGroupNegotiationRequestTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventGroupNegotiationResponseTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventGroupNegotiationConfirmTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventProvisionDiscoveryRequestTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventProvisionDiscoveryResponseTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++WLAN_STATUS ++p2pFsmRunEventInvitationRequestTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++#if 1 ++#endif ++ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/* //////////////////////////////////////////////////////////////////////// */ ++/*======Mail Box Event Message=====*/ ++ ++VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventConnectionTrigger(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventP2PFunctionSwitch(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventConnectionPause(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID ++p2pIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN UINT_8 aucTargetAddr[]); ++ ++VOID p2pUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); ++ ++/*======Mail Box Event Message=====*/ ++ ++VOID p2pFsmInit(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pStartGO(IN P_ADAPTER_T prAdapter); ++ ++VOID p2pAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); ++ ++VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID p2pFsmRunEventIOReqTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); ++ ++VOID p2pFsmRunEventSearchPeriodTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); ++ ++VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG u4Param); ++ ++VOID p2pFsmRunEventRejoinTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Parm); ++ ++/*=============== P2P Function Related ================*/ ++ ++/*=============== P2P Function Related ================*/ ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++VOID p2pTest(IN P_ADAPTER_T prAdapter); ++#endif /* CFG_TEST_WIFI_DIRECT_GO */ ++ ++VOID p2pGenerateP2P_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID p2pGenerateP2P_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID ++p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pCalculateP2P_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pCalculateP2P_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pGenerateWSC_IEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID ++p2pGenerateWSC_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_16 p2pCalculateWSC_IELenForProbeReq(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++UINT_32 ++p2pCalculateWSC_IELenForProbeResp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriStatus(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriCapability(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriGoIntent(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriCfgTimeout(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriGroupBssid(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceIDForBeacon(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceIDForProbeReq(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceIDForDeviceDiscoveryReq(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriListenChannel(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriIntendP2pIfAddr(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriChannelList(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 p2pCalculateAttriLenChannelList(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriNoA(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriDeviceInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 p2pCalculateAttriLenDeviceInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriGroupInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 p2pCalculateAttriLenGroupInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++p2pAppendAttriP2pGroupID(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriOperatingChannel(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriInvitationFlag(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++VOID ++p2pGenerateWscIE(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); ++ ++UINT_32 ++p2pAppendAttriWSCConfigMethod(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriWSCVersion(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriWSCGONegReqDevPasswordId(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pAppendAttriWSCGONegRspDevPasswordId(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++WLAN_STATUS ++p2pGetWscAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); ++ ++WLAN_STATUS ++p2pGetAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); ++ ++VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS p2pSendProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++BOOLEAN p2pFsmRunEventRxProbeRequestFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc); ++ ++WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxGroupNegotiationRspFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID p2pFsmRunEventRxGroupNegotiationCfmFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++#if 0 /* frog */ ++BOOLEAN scanMatchFilterOfP2P(IN P_SW_RFB_T prSWRfb, IN PP_BSS_DESC_T pprBssDesc); ++#endif /* frog */ ++ ++VOID ++p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); ++ ++VOID p2pFuncCompleteIOCTL(IN P_ADAPTER_T prAdapter, IN WLAN_STATUS rWlanStatus); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#ifndef _lint ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this for porting driver to different RTOS. ++ */ ++static inline VOID p2pDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(IE_P2P_T) == (2 + 4 + 1)); /* all UINT_8 */ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRIBUTE_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_STATUS_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_REASON_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CAPABILITY_T) == (3 + 2)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_ID_T) == (3 + 6)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GO_INTENT_T) == (3 + 1)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CFG_TIMEOUT_T) == (3 + 2)); ++#if CID52_53_54 ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); ++#else ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); ++#endif ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_BSSID_T) == (3 + 6)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_EXT_LISTEN_TIMING_T) == (3 + 4)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTENDED_IF_ADDR_T) == (3 + 6)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_MANAGEABILITY_T) == (3 + 1)); ++ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CHANNEL_T) == (3 + 4)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(CHANNEL_ENTRY_FIELD_T) == 3); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_NOA_T) == (3 + 3)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(NOA_DESCRIPTOR_T) == 13); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_TYPE_T) == 8); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_INFO_T) == (3 + 6 + 2 + 8 + 1 + 8)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_NAME_TLV_T) == (4 + 32)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_CLIENT_INFO_DESC_T) == (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_INFO_T) == (3 + (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8))); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_ID_T) == (3 + 38)); ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTERFACE_T) == (3 + 13)); ++#if CID52_53_54 ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); ++#else ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); ++#endif ++ ++} ++#endif /* _lint */ ++ ++#endif /* _P2P_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h +new file mode 100644 +index 000000000000..1ac1770debca +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h +@@ -0,0 +1,155 @@ ++#ifndef _P2P_FUNC_H ++#define _P2P_FUNC_H ++ ++#define P2P_EXT_LISTEN_TIME_MS 600 ++#define P2P_OFF_CHNL_TX_DEFAULT_TIME_MS 1000 ++ ++VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); ++ ++VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); ++ ++VOID ++p2pFuncStartGO(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, ++ IN PUINT_8 pucSsidBuf, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP); ++ ++VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); ++ ++VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); ++ ++VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo); ++ ++BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo); ++ ++VOID ++p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); ++ ++WLAN_STATUS ++p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); ++ ++WLAN_STATUS ++p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, ++ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, ++ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen); ++ ++BOOLEAN ++p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); ++ ++BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings); ++ ++BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); ++ ++BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID ++p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen); ++ ++P_BSS_DESC_T ++p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, ++ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); ++ ++VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID ++p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, ++ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter); ++ ++VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter); ++ ++VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo); ++ ++BOOLEAN ++p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); ++ ++P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu); ++ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++UINT_32 ++p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#else ++UINT_32 ++p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++#endif ++UINT_32 ++p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_STA_RECORD_T prStaRec, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); ++ ++VOID ++p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); ++ ++UINT_32 ++p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++VOID ++p2pFuncDissolve(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); ++ ++P_IE_HDR_T ++p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore); ++ ++P_ATTRIBUTE_HDR_T ++p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID); ++ ++WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ++ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h +new file mode 100644 +index 000000000000..efb75855695f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h +@@ -0,0 +1,156 @@ ++#ifndef _P2P_IE_H ++#define _P2P_IE_H ++ ++#if CFG_SUPPORT_WFD ++ ++#define ELEM_MAX_LEN_WFD 62 /* TODO: Move to appropriate place */ ++ ++/*---------------- WFD Data Element Definitions ----------------*/ ++/* WFD 4.1.1 - WFD IE format */ ++#define WFD_OUI_TYPE_LEN 4 ++#define WFD_IE_OUI_HDR (ELEM_HDR_LEN + WFD_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, ++ aucP2PAttributes[0]) */ ++ ++/* WFD 4.1.1 - General WFD Attribute */ ++#define WFD_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ ++ ++/* WFD Attribute Code */ ++#define WFD_ATTRI_ID_DEV_INFO 0 ++#define WFD_ATTRI_ID_ASSOC_BSSID 1 ++#define WFD_ATTRI_ID_COUPLED_SINK_INFO 6 ++#define WFD_ATTRI_ID_EXT_CAPABILITY 7 ++#define WFD_ATTRI_ID_SESSION_INFO 9 ++#define WFD_ATTRI_ID_ALTER_MAC_ADDRESS 10 ++ ++/* Maximum Length of WFD Attributes */ ++#define WFD_ATTRI_MAX_LEN_DEV_INFO 6 /* 0 */ ++#define WFD_ATTRI_MAX_LEN_ASSOC_BSSID 6 /* 1 */ ++#define WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO 7 /* 6 */ ++#define WFD_ATTRI_MAX_LEN_EXT_CAPABILITY 2 /* 7 */ ++#define WFD_ATTRI_MAX_LEN_SESSION_INFO 0 /* 9 */ /* 24 * #Clients */ ++#define WFD_ATTRI_MAX_LEN_ALTER_MAC_ADDRESS 6 /* 10 */ ++ ++/* WFD 1.10 5.1.1 */ ++typedef struct _IE_WFD_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 aucWFDAttributes[1]; /* WFD Subelement */ ++} __KAL_ATTRIB_PACKED__ IE_WFD_T, *P_IE_WFD_T; ++ ++typedef struct _WFD_ATTRIBUTE_T { ++ UINT_8 ucElemID; /* Subelement ID */ ++ UINT_16 u2Length; /* Length */ ++ UINT_8 aucBody[1]; /* Body field */ ++} __KAL_ATTRIB_PACKED__ WFD_ATTRIBUTE_T, *P_WFD_ATTRIBUTE_T; ++ ++typedef struct _WFD_DEVICE_INFORMATION_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_16 u2WfdDevInfo; ++ UINT_16 u2SessionMgmtCtrlPort; ++ UINT_16 u2WfdDevMaxSpeed; ++} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_IE_T, *P_WFD_DEVICE_INFORMATION_IE_T; ++ ++typedef struct _WFD_ASSOCIATED_BSSID_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WFD_ASSOCIATED_BSSID_IE_T, *P_WFD_ASSOCIATED_BSSID_IE_T; ++ ++typedef struct _WFD_COUPLE_SINK_INFORMATION_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_8 ucCoupleSinkStatusBp; ++ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WFD_COUPLE_SINK_INFORMATION_IE_T, *P_WFD_COUPLE_SINK_INFORMATION_IE_T; ++ ++typedef struct _WFD_EXTENDED_CAPABILITY_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ UINT_16 u2WfdExtCapabilityBp; ++} __KAL_ATTRIB_PACKED__ WFD_EXTENDED_CAPABILITY_IE_T, *P_WFD_EXTENDED_CAPABILITY_IE_T; ++ ++typedef struct _WFD_SESSION_INFORMATION_IE_T { ++ UINT_8 ucElemID; ++ UINT_16 u2Length; ++ PUINT_8 pucWfdDevInfoDesc[1]; ++} __KAL_ATTRIB_PACKED__ WFD_SESSION_INFORMATION_IE_T, *P_WFD_SESSION_INFORMATION_IE_T; ++ ++typedef struct _WFD_DEVICE_INFORMATION_DESCRIPTOR_T { ++ UINT_8 ucLength; ++ UINT_8 aucDevAddr[MAC_ADDR_LEN]; ++ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; ++ UINT_16 u2WfdDevInfo; ++ UINT_16 u2WfdDevMaxSpeed; ++ UINT_8 ucCoupleSinkStatusBp; ++ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_DESCRIPTOR_T, *P_WFD_DEVICE_INFORMATION_DESCRIPTOR_T; ++ ++#endif ++ ++UINT_32 ++p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#if CFG_SUPPORT_WFD ++ ++UINT_32 ++wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_32 ++wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForProbeResp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForAssocReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++VOID wfdFuncGenerateWfdIEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#endif ++ ++UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec); ++ ++VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h +new file mode 100644 +index 000000000000..32bc14c10959 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h +@@ -0,0 +1,74 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm.h#1 ++*/ ++ ++/*! \file "rlm.h" ++ \brief ++*/ ++ ++#ifndef _P2P_RLM_H ++#define _P2P_RLM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); ++ ++VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter); ++ ++VOID ++rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, ++ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize); ++ ++UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum); ++ ++BOOLEAN ++rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucCheckChnl, ++ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel); ++ ++ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h +new file mode 100644 +index 000000000000..5b6e756f48dd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h +@@ -0,0 +1,64 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm_obss.h#1 ++*/ ++ ++/*! \file "rlm_obss.h" ++ \brief ++*/ ++ ++#ifndef _P2P_RLM_OBSS_H ++#define _P2P_RLM_OBSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); ++ ++UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h +new file mode 100644 +index 000000000000..8db6aa5c31e0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h +@@ -0,0 +1,81 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_scan.h#1 ++*/ ++ ++/*! \file "scan.h" ++ \brief ++ ++*/ ++ ++#ifndef _P2P_SCAN_H ++#define _P2P_SCAN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); ++ ++P_P2P_DEVICE_DESC_T ++scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc); ++ ++P_P2P_DEVICE_DESC_T ++scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, ++ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound); ++ ++P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum); ++ ++BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID ++scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN P_WLAN_STATUS prStatus, ++ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); ++ ++VOID scanRemoveAllP2pBssDesc(P_ADAPTER_T prAdapter); ++ ++VOID scanRemoveP2pBssDesc(P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++P_BSS_DESC_T ++scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h +new file mode 100644 +index 000000000000..8f0c4c1564a8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h +@@ -0,0 +1,43 @@ ++#ifndef _P2P_STATE_H ++#define _P2P_STATE_H ++ ++BOOLEAN ++p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState); ++ ++VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID ++p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID ++p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++VOID ++p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID ++p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++VOID ++p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc); ++ ++VOID ++p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h +new file mode 100644 +index 000000000000..c80430ae4eb5 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h +@@ -0,0 +1,230 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/privacy.h#1 ++*/ ++ ++/*! \file privacy.h ++ \brief This file contains the function declaration for privacy.c. ++*/ ++ ++/* ++** Log: privacy.h ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * For support the WHQL test, do the remove key code refine. ++ * ++ * Dec 10 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the cmd return type ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function declaration for auth mode and encryption status setting from build connection command ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function declaration for wapi ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the tx done callback handle function ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function declaration for mac header privacy bit setting ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the structure for parsing the EAPoL frame ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the class error function parameter ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some security function declaration ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the ap selection structure ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++#ifndef _PRIVACY_H ++#define _PRIVACY_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define MAX_KEY_NUM 4 ++#define WEP_40_LEN 5 ++#define WEP_104_LEN 13 ++#define LEGACY_KEY_MAX_LEN 16 ++#define CCMP_KEY_LEN 16 ++#define TKIP_KEY_LEN 32 ++#define MAX_KEY_LEN 32 ++#define MIC_RX_KEY_OFFSET 16 ++#define MIC_TX_KEY_OFFSET 24 ++#define MIC_KEY_LEN 8 ++ ++#define WEP_KEY_ID_FIELD BITS(0, 29) ++#define KEY_ID_FIELD BITS(0, 7) ++ ++#define IS_TRANSMIT_KEY BIT(31) ++#define IS_UNICAST_KEY BIT(30) ++#define IS_AUTHENTICATOR BIT(28) ++ ++#define CIPHER_SUITE_NONE 0 ++#define CIPHER_SUITE_WEP40 1 ++#define CIPHER_SUITE_TKIP 2 ++#define CIPHER_SUITE_TKIP_WO_MIC 3 ++#define CIPHER_SUITE_CCMP 4 ++#define CIPHER_SUITE_WEP104 5 ++#define CIPHER_SUITE_BIP 6 ++#define CIPHER_SUITE_WEP128 7 ++#define CIPHER_SUITE_WPI 8 ++ ++#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */ ++#define WPA_KEY_INFO_MIC BIT(8) ++#define WPA_KEY_INFO_SECURE BIT(9) ++ ++#define MASK_2ND_EAPOL (WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _IEEE_802_1X_HDR { ++ UINT_8 ucVersion; ++ UINT_8 ucType; ++ UINT_16 u2Length; ++ /* followed by length octets of data */ ++} IEEE_802_1X_HDR, *P_IEEE_802_1X_HDR; ++ ++typedef struct _EAPOL_KEY { ++ UINT_8 ucType; ++ /* Note: key_info, key_length, and key_data_length are unaligned */ ++ UINT_8 aucKeyInfo[2]; /* big endian */ ++ UINT_8 aucKeyLength[2]; /* big endian */ ++ UINT_8 aucReplayCounter[8]; ++ UINT_8 aucKeyNonce[16]; ++ UINT_8 aucKeyIv[16]; ++ UINT_8 aucKeyRsc[8]; ++ UINT_8 aucKeyId[8]; /* Reserved in IEEE 802.11i/RSN */ ++ UINT_8 aucKeyMic[16]; ++ UINT_8 aucKeyDataLength[2]; /* big endian */ ++ /* followed by key_data_length bytes of key_data */ ++} EAPOL_KEY, *P_EAPOL_KEY; ++ ++/* WPA2 PMKID candicate structure */ ++typedef struct _PMKID_CANDICATE_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_32 u4PreAuthFlags; ++} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; ++ ++#if 0 ++/* WPA2 PMKID cache structure */ ++typedef struct _PMKID_ENTRY_T { ++ PARAM_BSSID_INFO_T rBssidInfo; ++ BOOLEAN fgPmkidExist; ++} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx); ++ ++VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPort); ++ ++BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec); ++ ++BOOLEAN secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec); ++ ++BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); ++ ++VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags); ++ ++BOOLEAN ++secProcessEAPOL(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, ++ IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen); ++ ++VOID ++secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T pMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus); ++ ++BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec); ++ ++VOID secClearPmkid(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _PRIVACY_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h +new file mode 100644 +index 000000000000..123dbebdacaf +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h +@@ -0,0 +1,93 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rate.h#1 ++*/ ++ ++/*! \file rate.h ++ \brief This file contains the rate utility function of ++ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: rate.h ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++*/ ++ ++#ifndef _RATE_H ++#define _RATE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in rate.c */ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, ++ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, ++ OUT PUINT_16 pu2OperationalRateSet, ++ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate); ++ ++VOID ++rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, ++ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen); ++ ++BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex); ++ ++BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RATE_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h +new file mode 100644 +index 000000000000..1af3841ecec2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h +@@ -0,0 +1,396 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm.h#2 ++*/ ++ ++/*! \file "rlm.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Refine function when rcv a 20/40M public action frame ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * Use SCO of BSS_INFO to replace user-defined setting variables ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 18 2010 cm.chang ++ * [WCXRP00000114] [MT6620 Wi-Fi] [Driver] Fix compiling warning in Linux about RLM network index checking ++ * Enum member cannot be used as compiling option decision in Linux ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX HT GF compiling option ++ * ++ * 06 02 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Roll back to remove CFG_SUPPORT_BCM_TEST. ++ * ++ * 06 01 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Update BCM Test and RW configuration. ++ * ++ * 05 31 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add some compiling options to control 11n functions ++ * ++ * 05 18 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Ad-hoc Beacon should not carry HT OP and OBSS IEs ++ * ++ * 05 17 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * MT6620 does not support L-SIG TXOP ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Different invoking order for WTBL entry of associated AP ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Move default value of HT capability to rlm.h ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * ++ * Modify the prototype of rlmRecAssocRspHtInfo() ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add several function prototypes for HT operation ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++** ++*/ ++ ++#ifndef _RLM_H ++#define _RLM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define ELEM_EXT_CAP_DEFAULT_VAL \ ++ (ELEM_EXT_CAP_20_40_COEXIST_SUPPORT /*| ELEM_EXT_CAP_PSMP_CAP*/) ++ ++#if CFG_SUPPORT_RX_STBC ++#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_1_SS ++#else ++#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_NO_SUPPORTED ++#endif ++ ++#if CFG_SUPPORT_RX_SGI ++#define FIELD_HT_CAP_INFO_SGI_20M HT_CAP_INFO_SHORT_GI_20M ++#define FIELD_HT_CAP_INFO_SGI_40M HT_CAP_INFO_SHORT_GI_40M ++#else ++#define FIELD_HT_CAP_INFO_SGI_20M 0 ++#define FIELD_HT_CAP_INFO_SGI_40M 0 ++#endif ++ ++#if CFG_SUPPORT_RX_HT_GF ++#define FIELD_HT_CAP_INFO_HT_GF HT_CAP_INFO_HT_GF ++#else ++#define FIELD_HT_CAP_INFO_HT_GF 0 ++#endif ++ ++#define HT_CAP_INFO_DEFAULT_VAL \ ++ (HT_CAP_INFO_SUP_CHNL_WIDTH | FIELD_HT_CAP_INFO_HT_GF | \ ++ FIELD_HT_CAP_INFO_SGI_20M | FIELD_HT_CAP_INFO_SGI_40M | \ ++ FIELD_HT_CAP_INFO_RX_STBC | HT_CAP_INFO_DSSS_CCK_IN_40M) ++ ++#define AMPDU_PARAM_DEFAULT_VAL \ ++ (AMPDU_PARAM_MAX_AMPDU_LEN_64K | AMPDU_PARAM_MSS_NO_RESTRICIT) ++ ++#define SUP_MCS_TX_DEFAULT_VAL \ ++ SUP_MCS_TX_SET_DEFINED /* TX defined and TX/RX equal (TBD) */ ++ ++#if CFG_SUPPORT_MFB ++#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_BOTH ++#else ++#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_NO_FB ++#endif ++ ++#if CFG_SUPPORT_RX_RDG ++#define FIELD_HT_EXT_CAP_RDR HT_EXT_CAP_RD_RESPONDER ++#else ++#define FIELD_HT_EXT_CAP_RDR 0 ++#endif ++ ++#if CFG_SUPPORT_MFB || CFG_SUPPORT_RX_RDG ++#define FIELD_HT_EXT_CAP_HTC HT_EXT_CAP_HTC_SUPPORT ++#else ++#define FIELD_HT_EXT_CAP_HTC 0 ++#endif ++ ++#define HT_EXT_CAP_DEFAULT_VAL \ ++ (HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE | \ ++ FIELD_HT_EXT_CAP_MFB | FIELD_HT_EXT_CAP_HTC | \ ++ FIELD_HT_EXT_CAP_RDR) ++ ++#define TX_BEAMFORMING_CAP_DEFAULT_VAL 0 ++#define ASEL_CAP_DEFAULT_VAL 0 ++ ++/* Define bandwidth from user setting */ ++#define CONFIG_BW_20_40M 0 ++#define CONFIG_BW_20M 1 /* 20MHz only */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* It is used for RLM module to judge if specific network is valid ++ * Note: Ad-hoc mode of AIS is not included now. (TBD) ++ */ ++#define RLM_NET_PARAM_VALID(_prBssInfo) \ ++ (IS_BSS_ACTIVE(_prBssInfo) && \ ++ ((_prBssInfo)->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || \ ++ (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT || \ ++ (_prBssInfo)->eCurrentOPMode == OP_MODE_IBSS || \ ++ RLM_NET_IS_BOW(_prBssInfo)) \ ++ ) ++ ++#define RLM_NET_IS_11N(_prBssInfo) \ ++ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11N) ++#define RLM_NET_IS_11GN(_prBssInfo) \ ++ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11GN) ++ ++/* This macro is used to sweep all 3 networks */ ++#define RLM_NET_FOR_EACH(_ucNetIdx) \ ++ for ((_ucNetIdx) = 0; \ ++ (_ucNetIdx) < NETWORK_TYPE_INDEX_NUM; \ ++ (_ucNetIdx)++) ++ ++/* This macro is used to sweep all networks excluding BOW */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /* Note: value of enum NETWORK_TYPE_BOW_INDEX is validated in ++ * rlmStuctureCheck(). ++ */ ++#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) \ ++ for ((_ucNetIdx) = 0; \ ++ (_ucNetIdx) < NETWORK_TYPE_BOW_INDEX; \ ++ (_ucNetIdx)++) ++ ++#define RLM_NET_IS_BOW(_prBssInfo) \ ++ ((_prBssInfo)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++ ++#else ++#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) RLM_NET_FOR_EACH(_ucNetIdx) ++#define RLM_NET_IS_BOW(_prBssInfo) (FALSE) ++ ++#endif /* end of CFG_ENABLE_BT_OVER_WIFI */ ++ ++/* The bandwidth modes are not used anymore. They represent if AP ++ * can use 20/40 bandwidth, not all modes. (20110411) ++ */ ++#define RLM_AP_IS_BW_40_ALLOWED(_prAdapter, _prBssInfo) \ ++ (((_prBssInfo)->eBand == BAND_2G4 && \ ++ (_prAdapter)->rWifiVar.rConnSettings.uc2G4BandwidthMode \ ++ == CONFIG_BW_20_40M) || \ ++ ((_prBssInfo)->eBand == BAND_5G && \ ++ (_prAdapter)->rWifiVar.rConnSettings.uc5GBandwidthMode \ ++ == CONFIG_BW_20_40M)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID rlmFsmEventInit(P_ADAPTER_T prAdapter); ++ ++VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter); ++ ++VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++UINT32 ++rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, ++ BOOLEAN fgShortGIDisabled, ++ UINT_8 u8SupportRxSgi20, ++ UINT_8 u8SupportRxSgi40, ++ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf); ++ ++UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme); ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE); ++#endif ++ ++VOID ++rlmTxRateEnhanceConfig( ++ P_ADAPTER_T prAdapter ++ ); ++ ++VOID ++rlmCmd( ++ P_GLUE_INFO_T prGlueInfo, ++ UINT_8 *prInBuf, ++ UINT_32 u4InBufLen ++ ); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#ifndef _lint ++static inline VOID rlmDataTypeCheck(VOID) ++{ ++#if CFG_ENABLE_BT_OVER_WIFI ++ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_AIS_INDEX < NETWORK_TYPE_BOW_INDEX); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_P2P_INDEX < NETWORK_TYPE_BOW_INDEX); ++#endif ++#endif ++ ++} ++#endif /* _lint */ ++ ++#endif /* _RLM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h +new file mode 100644 +index 000000000000..65e907041a28 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h +@@ -0,0 +1,557 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_domain.h#1 ++*/ ++ ++/*! \file "rlm_domain.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_domain.h ++ * ++ * 09 29 2011 cm.chang ++ * NULL ++ * Change the function prototype of rlmDomainGetChnlList() ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Provide legal channel function based on domain ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 01 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Provide query function about full channel list. ++ * ++ * Dec 1 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Declare public rDomainInfo ++ * ++** ++*/ ++ ++#ifndef _RLM_DOMAIN_H ++#define _RLM_DOMAIN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define MAX_SUBBAND_NUM 6 ++#define MAX_SUBBAND_NUM_5G 8 ++ ++#define COUNTRY_CODE_NULL ((UINT_16)0x0) ++ ++/* ISO/IEC 3166-1 two-character country codes */ ++ ++#define COUNTRY_CODE_AD (((UINT_16) 'A' << 8) | (UINT_16) 'D') /* Andorra */ ++#define COUNTRY_CODE_AE (((UINT_16) 'A' << 8) | (UINT_16) 'E') /* UAE */ ++#define COUNTRY_CODE_AF (((UINT_16) 'A' << 8) | (UINT_16) 'F') /* Afghanistan */ ++#define COUNTRY_CODE_AG (((UINT_16) 'A' << 8) | (UINT_16) 'G') /* Antigua & Barbuda */ ++#define COUNTRY_CODE_AI (((UINT_16) 'A' << 8) | (UINT_16) 'I') /* Anguilla */ ++#define COUNTRY_CODE_AL (((UINT_16) 'A' << 8) | (UINT_16) 'L') /* Albania */ ++#define COUNTRY_CODE_AM (((UINT_16) 'A' << 8) | (UINT_16) 'M') /* Armenia */ ++#define COUNTRY_CODE_AN (((UINT_16) 'A' << 8) | (UINT_16) 'N') /* Netherlands Antilles */ ++#define COUNTRY_CODE_AO (((UINT_16) 'A' << 8) | (UINT_16) 'O') /* Angola */ ++#define COUNTRY_CODE_AR (((UINT_16) 'A' << 8) | (UINT_16) 'R') /* Argentina */ ++#define COUNTRY_CODE_AS (((UINT_16) 'A' << 8) | (UINT_16) 'S') /* American Samoa (USA) */ ++#define COUNTRY_CODE_AT (((UINT_16) 'A' << 8) | (UINT_16) 'T') /* Austria */ ++#define COUNTRY_CODE_AU (((UINT_16) 'A' << 8) | (UINT_16) 'U') /* Australia */ ++#define COUNTRY_CODE_AW (((UINT_16) 'A' << 8) | (UINT_16) 'W') /* Aruba */ ++#define COUNTRY_CODE_AZ (((UINT_16) 'A' << 8) | (UINT_16) 'Z') /* Azerbaijan */ ++#define COUNTRY_CODE_BA (((UINT_16) 'B' << 8) | (UINT_16) 'A') /* Bosnia and Herzegovina */ ++#define COUNTRY_CODE_BB (((UINT_16) 'B' << 8) | (UINT_16) 'B') /* Barbados */ ++#define COUNTRY_CODE_BD (((UINT_16) 'B' << 8) | (UINT_16) 'D') /* Bangladesh */ ++#define COUNTRY_CODE_BE (((UINT_16) 'B' << 8) | (UINT_16) 'E') /* Belgium */ ++#define COUNTRY_CODE_BF (((UINT_16) 'B' << 8) | (UINT_16) 'F') /* Burkina Faso */ ++#define COUNTRY_CODE_BG (((UINT_16) 'B' << 8) | (UINT_16) 'G') /* Bulgaria */ ++#define COUNTRY_CODE_BH (((UINT_16) 'B' << 8) | (UINT_16) 'H') /* Bahrain */ ++#define COUNTRY_CODE_BI (((UINT_16) 'B' << 8) | (UINT_16) 'I') /* Burundi */ ++#define COUNTRY_CODE_BJ (((UINT_16) 'B' << 8) | (UINT_16) 'J') /* Benin */ ++#define COUNTRY_CODE_BM (((UINT_16) 'B' << 8) | (UINT_16) 'M') /* Bermuda */ ++#define COUNTRY_CODE_BN (((UINT_16) 'B' << 8) | (UINT_16) 'N') /* Brunei */ ++#define COUNTRY_CODE_BO (((UINT_16) 'B' << 8) | (UINT_16) 'O') /* Bolivia */ ++#define COUNTRY_CODE_BR (((UINT_16) 'B' << 8) | (UINT_16) 'R') /* Brazil */ ++#define COUNTRY_CODE_BS (((UINT_16) 'B' << 8) | (UINT_16) 'S') /* Bahamas */ ++#define COUNTRY_CODE_BT (((UINT_16) 'B' << 8) | (UINT_16) 'T') /* Bhutan */ ++#define COUNTRY_CODE_BW (((UINT_16) 'B' << 8) | (UINT_16) 'W') /* Botswana */ ++#define COUNTRY_CODE_BY (((UINT_16) 'B' << 8) | (UINT_16) 'Y') /* Belarus */ ++#define COUNTRY_CODE_BZ (((UINT_16) 'B' << 8) | (UINT_16) 'Z') /* Belize */ ++#define COUNTRY_CODE_CA (((UINT_16) 'C' << 8) | (UINT_16) 'A') /* Canada */ ++#define COUNTRY_CODE_CD (((UINT_16) 'C' << 8) | (UINT_16) 'D') /* Congo. Democratic Republic of the */ ++#define COUNTRY_CODE_CF (((UINT_16) 'C' << 8) | (UINT_16) 'F') /* Central African Republic */ ++#define COUNTRY_CODE_CG (((UINT_16) 'C' << 8) | (UINT_16) 'G') /* Congo. Republic of the */ ++#define COUNTRY_CODE_CH (((UINT_16) 'C' << 8) | (UINT_16) 'H') /* Switzerland */ ++#define COUNTRY_CODE_CI (((UINT_16) 'C' << 8) | (UINT_16) 'I') /* Cote d'lvoire */ ++#define COUNTRY_CODE_CK (((UINT_16) 'C' << 8) | (UINT_16) 'K') /* Cook Island */ ++#define COUNTRY_CODE_CL (((UINT_16) 'C' << 8) | (UINT_16) 'L') /* Chile */ ++#define COUNTRY_CODE_CM (((UINT_16) 'C' << 8) | (UINT_16) 'M') /* Cameroon */ ++#define COUNTRY_CODE_CN (((UINT_16) 'C' << 8) | (UINT_16) 'N') /* China */ ++#define COUNTRY_CODE_CO (((UINT_16) 'C' << 8) | (UINT_16) 'O') /* Columbia */ ++#define COUNTRY_CODE_CR (((UINT_16) 'C' << 8) | (UINT_16) 'R') /* Costa Rica */ ++#define COUNTRY_CODE_CU (((UINT_16) 'C' << 8) | (UINT_16) 'U') /* Cuba */ ++#define COUNTRY_CODE_CV (((UINT_16) 'C' << 8) | (UINT_16) 'V') /* Cape Verde */ ++#define COUNTRY_CODE_CX (((UINT_16) 'C' << 8) | (UINT_16) 'X') /* "Christmas Island(Australia) */ ++#define COUNTRY_CODE_CY (((UINT_16) 'C' << 8) | (UINT_16) 'Y') /* Cyprus */ ++#define COUNTRY_CODE_CZ (((UINT_16) 'C' << 8) | (UINT_16) 'Z') /* Czech */ ++#define COUNTRY_CODE_DE (((UINT_16) 'D' << 8) | (UINT_16) 'E') /* Germany */ ++#define COUNTRY_CODE_DJ (((UINT_16) 'D' << 8) | (UINT_16) 'J') /* Djibouti */ ++#define COUNTRY_CODE_DK (((UINT_16) 'D' << 8) | (UINT_16) 'K') /* Denmark */ ++#define COUNTRY_CODE_DM (((UINT_16) 'D' << 8) | (UINT_16) 'M') /* Dominica */ ++#define COUNTRY_CODE_DO (((UINT_16) 'D' << 8) | (UINT_16) 'O') /* Dominican Republic */ ++#define COUNTRY_CODE_DZ (((UINT_16) 'D' << 8) | (UINT_16) 'Z') /* Algeria */ ++#define COUNTRY_CODE_EC (((UINT_16) 'E' << 8) | (UINT_16) 'C') /* Ecuador */ ++#define COUNTRY_CODE_EE (((UINT_16) 'E' << 8) | (UINT_16) 'E') /* Estonia */ ++#define COUNTRY_CODE_EG (((UINT_16) 'E' << 8) | (UINT_16) 'G') /* Egypt */ ++#define COUNTRY_CODE_EH (((UINT_16) 'E' << 8) | (UINT_16) 'H') /* Western Sahara (Morocco) */ ++#define COUNTRY_CODE_ER (((UINT_16) 'E' << 8) | (UINT_16) 'R') /* Eritrea */ ++#define COUNTRY_CODE_ES (((UINT_16) 'E' << 8) | (UINT_16) 'S') /* Spain */ ++#define COUNTRY_CODE_ET (((UINT_16) 'E' << 8) | (UINT_16) 'T') /* Ethiopia */ ++#define COUNTRY_CODE_EU (((UINT_16) 'E' << 8) | (UINT_16) 'U') /* Europe */ ++#define COUNTRY_CODE_FI (((UINT_16) 'F' << 8) | (UINT_16) 'I') /* Finland */ ++#define COUNTRY_CODE_FJ (((UINT_16) 'F' << 8) | (UINT_16) 'J') /* Fiji */ ++#define COUNTRY_CODE_FK (((UINT_16) 'F' << 8) | (UINT_16) 'K') /* Falkland Island */ ++#define COUNTRY_CODE_FM (((UINT_16) 'F' << 8) | (UINT_16) 'M') /* Micronesia */ ++#define COUNTRY_CODE_FO (((UINT_16) 'F' << 8) | (UINT_16) 'O') /* Faroe Island */ ++#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* France */ ++#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* Wallis and Futuna (France) */ ++#define COUNTRY_CODE_GA (((UINT_16) 'G' << 8) | (UINT_16) 'A') /* Gabon */ ++#define COUNTRY_CODE_GB (((UINT_16) 'G' << 8) | (UINT_16) 'B') /* United Kingdom */ ++#define COUNTRY_CODE_GD (((UINT_16) 'G' << 8) | (UINT_16) 'D') /* Grenada */ ++#define COUNTRY_CODE_GE (((UINT_16) 'G' << 8) | (UINT_16) 'E') /* Georgia */ ++#define COUNTRY_CODE_GF (((UINT_16) 'G' << 8) | (UINT_16) 'F') /* French Guiana */ ++#define COUNTRY_CODE_GG (((UINT_16) 'G' << 8) | (UINT_16) 'G') /* Guernsey */ ++#define COUNTRY_CODE_GH (((UINT_16) 'G' << 8) | (UINT_16) 'H') /* Ghana */ ++#define COUNTRY_CODE_GI (((UINT_16) 'G' << 8) | (UINT_16) 'I') /* Gibraltar */ ++#define COUNTRY_CODE_GM (((UINT_16) 'G' << 8) | (UINT_16) 'M') /* Gambia */ ++#define COUNTRY_CODE_GN (((UINT_16) 'G' << 8) | (UINT_16) 'N') /* Guinea */ ++#define COUNTRY_CODE_GP (((UINT_16) 'G' << 8) | (UINT_16) 'P') /* Guadeloupe */ ++#define COUNTRY_CODE_GQ (((UINT_16) 'G' << 8) | (UINT_16) 'Q') /* Equatorial Guinea */ ++#define COUNTRY_CODE_GR (((UINT_16) 'G' << 8) | (UINT_16) 'R') /* Greece */ ++#define COUNTRY_CODE_GT (((UINT_16) 'G' << 8) | (UINT_16) 'T') /* Guatemala */ ++#define COUNTRY_CODE_GU (((UINT_16) 'G' << 8) | (UINT_16) 'U') /* Guam */ ++#define COUNTRY_CODE_GW (((UINT_16) 'G' << 8) | (UINT_16) 'W') /* Guinea-Bissau */ ++#define COUNTRY_CODE_GY (((UINT_16) 'G' << 8) | (UINT_16) 'Y') /* Guyana */ ++#define COUNTRY_CODE_HK (((UINT_16) 'H' << 8) | (UINT_16) 'K') /* Hong Kong */ ++#define COUNTRY_CODE_HN (((UINT_16) 'H' << 8) | (UINT_16) 'N') /* Honduras */ ++#define COUNTRY_CODE_HR (((UINT_16) 'H' << 8) | (UINT_16) 'R') /* Croatia */ ++#define COUNTRY_CODE_HT (((UINT_16) 'H' << 8) | (UINT_16) 'T') /* Haiti */ ++#define COUNTRY_CODE_HU (((UINT_16) 'H' << 8) | (UINT_16) 'U') /* Hungary */ ++#define COUNTRY_CODE_ID (((UINT_16) 'I' << 8) | (UINT_16) 'D') /* Indonesia */ ++#define COUNTRY_CODE_IE (((UINT_16) 'I' << 8) | (UINT_16) 'E') /* Ireland */ ++#define COUNTRY_CODE_IL (((UINT_16) 'I' << 8) | (UINT_16) 'L') /* Israel */ ++#define COUNTRY_CODE_IM (((UINT_16) 'I' << 8) | (UINT_16) 'M') /* Isle of Man */ ++#define COUNTRY_CODE_IN (((UINT_16) 'I' << 8) | (UINT_16) 'N') /* India */ ++#define COUNTRY_CODE_IQ (((UINT_16) 'I' << 8) | (UINT_16) 'Q') /* Iraq */ ++#define COUNTRY_CODE_IR (((UINT_16) 'I' << 8) | (UINT_16) 'R') /* Iran */ ++#define COUNTRY_CODE_IS (((UINT_16) 'I' << 8) | (UINT_16) 'S') /* Iceland */ ++#define COUNTRY_CODE_IT (((UINT_16) 'I' << 8) | (UINT_16) 'T') /* Italy */ ++#define COUNTRY_CODE_JE (((UINT_16) 'J' << 8) | (UINT_16) 'E') /* Jersey */ ++#define COUNTRY_CODE_JM (((UINT_16) 'J' << 8) | (UINT_16) 'M') /* Jameica */ ++#define COUNTRY_CODE_JO (((UINT_16) 'J' << 8) | (UINT_16) 'O') /* Jordan */ ++#define COUNTRY_CODE_JP (((UINT_16) 'J' << 8) | (UINT_16) 'P') /* Japan */ ++#define COUNTRY_CODE_KE (((UINT_16) 'K' << 8) | (UINT_16) 'E') /* Kenya */ ++#define COUNTRY_CODE_KG (((UINT_16) 'K' << 8) | (UINT_16) 'G') /* Kyrgyzstan */ ++#define COUNTRY_CODE_KH (((UINT_16) 'K' << 8) | (UINT_16) 'H') /* Cambodia */ ++#define COUNTRY_CODE_KI (((UINT_16) 'K' << 8) | (UINT_16) 'I') /* Kiribati */ ++#define COUNTRY_CODE_KM (((UINT_16) 'K' << 8) | (UINT_16) 'M') /* Comoros */ ++#define COUNTRY_CODE_KN (((UINT_16) 'K' << 8) | (UINT_16) 'N') /* Saint Kitts and Nevis */ ++#define COUNTRY_CODE_KP (((UINT_16) 'K' << 8) | (UINT_16) 'P') /* North Korea */ ++#define COUNTRY_CODE_KR (((UINT_16) 'K' << 8) | (UINT_16) 'R') /* South Korea */ ++#define COUNTRY_CODE_KW (((UINT_16) 'K' << 8) | (UINT_16) 'W') /* Kuwait */ ++#define COUNTRY_CODE_KY (((UINT_16) 'K' << 8) | (UINT_16) 'Y') /* Cayman Islands */ ++#define COUNTRY_CODE_KZ (((UINT_16) 'K' << 8) | (UINT_16) 'Z') /* Kazakhstan */ ++#define COUNTRY_CODE_LA (((UINT_16) 'L' << 8) | (UINT_16) 'A') /* Laos */ ++#define COUNTRY_CODE_LB (((UINT_16) 'L' << 8) | (UINT_16) 'B') /* Lebanon */ ++#define COUNTRY_CODE_LC (((UINT_16) 'L' << 8) | (UINT_16) 'C') /* Saint Lucia */ ++#define COUNTRY_CODE_LI (((UINT_16) 'L' << 8) | (UINT_16) 'I') /* Liechtenstein */ ++#define COUNTRY_CODE_LK (((UINT_16) 'L' << 8) | (UINT_16) 'K') /* Sri Lanka */ ++#define COUNTRY_CODE_LR (((UINT_16) 'L' << 8) | (UINT_16) 'R') /* Liberia */ ++#define COUNTRY_CODE_LS (((UINT_16) 'L' << 8) | (UINT_16) 'S') /* Lesotho */ ++#define COUNTRY_CODE_LT (((UINT_16) 'L' << 8) | (UINT_16) 'T') /* Lithuania */ ++#define COUNTRY_CODE_LU (((UINT_16) 'L' << 8) | (UINT_16) 'U') /* Luxemburg */ ++#define COUNTRY_CODE_LV (((UINT_16) 'L' << 8) | (UINT_16) 'V') /* Latvia */ ++#define COUNTRY_CODE_LY (((UINT_16) 'L' << 8) | (UINT_16) 'Y') /* Libya */ ++#define COUNTRY_CODE_MA (((UINT_16) 'M' << 8) | (UINT_16) 'A') /* Morocco */ ++#define COUNTRY_CODE_MC (((UINT_16) 'M' << 8) | (UINT_16) 'C') /* Monaco */ ++#define COUNTRY_CODE_MD (((UINT_16) 'M' << 8) | (UINT_16) 'D') /* Moldova */ ++#define COUNTRY_CODE_ME (((UINT_16) 'M' << 8) | (UINT_16) 'E') /* Montenegro */ ++#define COUNTRY_CODE_MF (((UINT_16) 'M' << 8) | (UINT_16) 'F') /* Saint Martin / Sint Marteen ++ (Added on window's list) */ ++#define COUNTRY_CODE_MG (((UINT_16) 'M' << 8) | (UINT_16) 'G') /* Madagascar */ ++#define COUNTRY_CODE_MH (((UINT_16) 'M' << 8) | (UINT_16) 'H') /* Marshall Islands */ ++#define COUNTRY_CODE_MK (((UINT_16) 'M' << 8) | (UINT_16) 'K') /* Macedonia */ ++#define COUNTRY_CODE_ML (((UINT_16) 'M' << 8) | (UINT_16) 'L') /* Mali */ ++#define COUNTRY_CODE_MM (((UINT_16) 'M' << 8) | (UINT_16) 'M') /* Myanmar */ ++#define COUNTRY_CODE_MN (((UINT_16) 'M' << 8) | (UINT_16) 'N') /* Mongolia */ ++#define COUNTRY_CODE_MO (((UINT_16) 'M' << 8) | (UINT_16) 'O') /* Macao */ ++#define COUNTRY_CODE_MP (((UINT_16) 'M' << 8) | (UINT_16) 'P') /* Northern Mariana Islands (Rota Island. ++ Saipan and Tinian Island) */ ++#define COUNTRY_CODE_MQ (((UINT_16) 'M' << 8) | (UINT_16) 'Q') /* Martinique (France) */ ++#define COUNTRY_CODE_MR (((UINT_16) 'M' << 8) | (UINT_16) 'R') /* Mauritania */ ++#define COUNTRY_CODE_MS (((UINT_16) 'M' << 8) | (UINT_16) 'S') /* Montserrat (UK) */ ++#define COUNTRY_CODE_MT (((UINT_16) 'M' << 8) | (UINT_16) 'T') /* Malta */ ++#define COUNTRY_CODE_MU (((UINT_16) 'M' << 8) | (UINT_16) 'U') /* Mauritius */ ++#define COUNTRY_CODE_MV (((UINT_16) 'M' << 8) | (UINT_16) 'V') /* Maldives */ ++#define COUNTRY_CODE_MW (((UINT_16) 'M' << 8) | (UINT_16) 'W') /* Malawi */ ++#define COUNTRY_CODE_MX (((UINT_16) 'M' << 8) | (UINT_16) 'X') /* Mexico */ ++#define COUNTRY_CODE_MY (((UINT_16) 'M' << 8) | (UINT_16) 'Y') /* Malaysia */ ++#define COUNTRY_CODE_MZ (((UINT_16) 'M' << 8) | (UINT_16) 'Z') /* Mozambique */ ++#define COUNTRY_CODE_NA (((UINT_16) 'N' << 8) | (UINT_16) 'A') /* Namibia */ ++#define COUNTRY_CODE_NC (((UINT_16) 'N' << 8) | (UINT_16) 'C') /* New Caledonia */ ++#define COUNTRY_CODE_NE (((UINT_16) 'N' << 8) | (UINT_16) 'E') /* Niger */ ++#define COUNTRY_CODE_NF (((UINT_16) 'N' << 8) | (UINT_16) 'F') /* Norfolk Island */ ++#define COUNTRY_CODE_NG (((UINT_16) 'N' << 8) | (UINT_16) 'G') /* Nigeria */ ++#define COUNTRY_CODE_NI (((UINT_16) 'N' << 8) | (UINT_16) 'I') /* Nicaragua */ ++#define COUNTRY_CODE_NL (((UINT_16) 'N' << 8) | (UINT_16) 'L') /* Netherlands */ ++#define COUNTRY_CODE_NO (((UINT_16) 'N' << 8) | (UINT_16) 'O') /* Norway */ ++#define COUNTRY_CODE_NP (((UINT_16) 'N' << 8) | (UINT_16) 'P') /* Nepal */ ++#define COUNTRY_CODE_NR (((UINT_16) 'N' << 8) | (UINT_16) 'R') /* Nauru */ ++#define COUNTRY_CODE_NU (((UINT_16) 'N' << 8) | (UINT_16) 'U') /* Niue */ ++#define COUNTRY_CODE_NZ (((UINT_16) 'N' << 8) | (UINT_16) 'Z') /* New Zealand */ ++#define COUNTRY_CODE_OM (((UINT_16) 'O' << 8) | (UINT_16) 'M') /* Oman */ ++#define COUNTRY_CODE_PA (((UINT_16) 'P' << 8) | (UINT_16) 'A') /* Panama */ ++#define COUNTRY_CODE_PE (((UINT_16) 'P' << 8) | (UINT_16) 'E') /* Peru */ ++#define COUNTRY_CODE_PF (((UINT_16) 'P' << 8) | (UINT_16) 'F') /* "French Polynesia */ ++#define COUNTRY_CODE_PG (((UINT_16) 'P' << 8) | (UINT_16) 'G') /* Papua New Guinea */ ++#define COUNTRY_CODE_PH (((UINT_16) 'P' << 8) | (UINT_16) 'H') /* Philippines */ ++#define COUNTRY_CODE_PK (((UINT_16) 'P' << 8) | (UINT_16) 'K') /* Pakistan */ ++#define COUNTRY_CODE_PL (((UINT_16) 'P' << 8) | (UINT_16) 'L') /* Poland */ ++#define COUNTRY_CODE_PM (((UINT_16) 'P' << 8) | (UINT_16) 'M') /* Saint Pierre and Miquelon */ ++#define COUNTRY_CODE_PN (((UINT_16) 'P' << 8) | (UINT_16) 'N') /* Pitcairn Islands */ ++#define COUNTRY_CODE_PR (((UINT_16) 'P' << 8) | (UINT_16) 'R') /* Puerto Rico (USA) */ ++#define COUNTRY_CODE_PS (((UINT_16) 'P' << 8) | (UINT_16) 'S') /* Palestinian Authority */ ++#define COUNTRY_CODE_PT (((UINT_16) 'P' << 8) | (UINT_16) 'T') /* Portugal */ ++#define COUNTRY_CODE_PW (((UINT_16) 'P' << 8) | (UINT_16) 'W') /* Palau */ ++#define COUNTRY_CODE_PY (((UINT_16) 'P' << 8) | (UINT_16) 'Y') /* Paraguay */ ++#define COUNTRY_CODE_QA (((UINT_16) 'Q' << 8) | (UINT_16) 'A') /* Qatar */ ++#define COUNTRY_CODE_RE (((UINT_16) 'R' << 8) | (UINT_16) 'E') /* Reunion (France) */ ++#define COUNTRY_CODE_RKS (((UINT_16) 'R' << 8) | (UINT_16) 'K') /* Kosvo (Added on window's list) */ ++#define COUNTRY_CODE_RO (((UINT_16) 'R' << 8) | (UINT_16) 'O') /* Romania */ ++#define COUNTRY_CODE_RS (((UINT_16) 'R' << 8) | (UINT_16) 'S') /* Serbia */ ++#define COUNTRY_CODE_RU (((UINT_16) 'R' << 8) | (UINT_16) 'U') /* Russia */ ++#define COUNTRY_CODE_RW (((UINT_16) 'R' << 8) | (UINT_16) 'W') /* Rwanda */ ++#define COUNTRY_CODE_SA (((UINT_16) 'S' << 8) | (UINT_16) 'A') /* Saudi Arabia */ ++#define COUNTRY_CODE_SB (((UINT_16) 'S' << 8) | (UINT_16) 'B') /* Solomon Islands */ ++#define COUNTRY_CODE_SC (((UINT_16) 'S' << 8) | (UINT_16) 'C') /* Seychelles */ ++#define COUNTRY_CODE_SD (((UINT_16) 'S' << 8) | (UINT_16) 'D') /* Sudan */ ++#define COUNTRY_CODE_SE (((UINT_16) 'S' << 8) | (UINT_16) 'E') /* Sweden */ ++#define COUNTRY_CODE_SG (((UINT_16) 'S' << 8) | (UINT_16) 'G') /* Singapole */ ++#define COUNTRY_CODE_SI (((UINT_16) 'S' << 8) | (UINT_16) 'I') /* Slovenia */ ++#define COUNTRY_CODE_SK (((UINT_16) 'S' << 8) | (UINT_16) 'K') /* Slovakia */ ++#define COUNTRY_CODE_SL (((UINT_16) 'S' << 8) | (UINT_16) 'L') /* Sierra Leone */ ++#define COUNTRY_CODE_SM (((UINT_16) 'S' << 8) | (UINT_16) 'M') /* San Marino */ ++#define COUNTRY_CODE_SN (((UINT_16) 'S' << 8) | (UINT_16) 'N') /* Senegal */ ++#define COUNTRY_CODE_SO (((UINT_16) 'S' << 8) | (UINT_16) 'O') /* Somalia */ ++#define COUNTRY_CODE_SR (((UINT_16) 'S' << 8) | (UINT_16) 'R') /* Suriname */ ++#define COUNTRY_CODE_SS (((UINT_16) 'S' << 8) | (UINT_16) 'S') /* South_Sudan */ ++#define COUNTRY_CODE_ST (((UINT_16) 'S' << 8) | (UINT_16) 'T') /* Sao Tome and Principe */ ++#define COUNTRY_CODE_SV (((UINT_16) 'S' << 8) | (UINT_16) 'V') /* El Salvador */ ++#define COUNTRY_CODE_SY (((UINT_16) 'S' << 8) | (UINT_16) 'Y') /* Syria */ ++#define COUNTRY_CODE_SZ (((UINT_16) 'S' << 8) | (UINT_16) 'Z') /* Swaziland */ ++#define COUNTRY_CODE_TC (((UINT_16) 'T' << 8) | (UINT_16) 'C') /* Turks and Caicos Islands (UK) */ ++#define COUNTRY_CODE_TD (((UINT_16) 'T' << 8) | (UINT_16) 'D') /* Chad */ ++#define COUNTRY_CODE_TF (((UINT_16) 'T' << 8) | (UINT_16) 'F') /* French Southern and Antarctic Lands */ ++#define COUNTRY_CODE_TG (((UINT_16) 'T' << 8) | (UINT_16) 'G') /* Togo */ ++#define COUNTRY_CODE_TH (((UINT_16) 'T' << 8) | (UINT_16) 'H') /* Thailand */ ++#define COUNTRY_CODE_TJ (((UINT_16) 'T' << 8) | (UINT_16) 'J') /* Tajikistan */ ++#define COUNTRY_CODE_TL (((UINT_16) 'T' << 8) | (UINT_16) 'L') /* East Timor */ ++#define COUNTRY_CODE_TM (((UINT_16) 'T' << 8) | (UINT_16) 'M') /* Turkmenistan */ ++#define COUNTRY_CODE_TN (((UINT_16) 'T' << 8) | (UINT_16) 'N') /* Tunisia */ ++#define COUNTRY_CODE_TO (((UINT_16) 'T' << 8) | (UINT_16) 'O') /* Tonga */ ++#define COUNTRY_CODE_TR (((UINT_16) 'T' << 8) | (UINT_16) 'R') /* Turkey */ ++#define COUNTRY_CODE_TT (((UINT_16) 'T' << 8) | (UINT_16) 'T') /* Trinidad and Tobago */ ++#define COUNTRY_CODE_TV (((UINT_16) 'T' << 8) | (UINT_16) 'V') /* Tuvalu */ ++#define COUNTRY_CODE_TW (((UINT_16) 'T' << 8) | (UINT_16) 'W') /* Taiwan */ ++#define COUNTRY_CODE_TZ (((UINT_16) 'T' << 8) | (UINT_16) 'Z') /* Tanzania */ ++#define COUNTRY_CODE_UA (((UINT_16) 'U' << 8) | (UINT_16) 'A') /* Ukraine */ ++#define COUNTRY_CODE_UG (((UINT_16) 'U' << 8) | (UINT_16) 'G') /* Ugnada */ ++#define COUNTRY_CODE_US (((UINT_16) 'U' << 8) | (UINT_16) 'S') /* US */ ++#define COUNTRY_CODE_UY (((UINT_16) 'U' << 8) | (UINT_16) 'Y') /* Uruguay */ ++#define COUNTRY_CODE_UZ (((UINT_16) 'U' << 8) | (UINT_16) 'Z') /* Uzbekistan */ ++#define COUNTRY_CODE_VA (((UINT_16) 'V' << 8) | (UINT_16) 'A') /* Vatican (Holy See) */ ++#define COUNTRY_CODE_VC (((UINT_16) 'V' << 8) | (UINT_16) 'C') /* Saint Vincent and the Grenadines */ ++#define COUNTRY_CODE_VE (((UINT_16) 'V' << 8) | (UINT_16) 'E') /* Venezuela */ ++#define COUNTRY_CODE_VG (((UINT_16) 'V' << 8) | (UINT_16) 'G') /* British Virgin Islands */ ++#define COUNTRY_CODE_VI (((UINT_16) 'V' << 8) | (UINT_16) 'I') /* US Virgin Islands */ ++#define COUNTRY_CODE_VN (((UINT_16) 'V' << 8) | (UINT_16) 'N') /* Vietnam */ ++#define COUNTRY_CODE_VU (((UINT_16) 'V' << 8) | (UINT_16) 'U') /* Vanuatu */ ++#define COUNTRY_CODE_WS (((UINT_16) 'W' << 8) | (UINT_16) 'S') /* Samoa */ ++#define COUNTRY_CODE_YE (((UINT_16) 'Y' << 8) | (UINT_16) 'E') /* Yemen */ ++#define COUNTRY_CODE_YT (((UINT_16) 'Y' << 8) | (UINT_16) 'T') /* Mayotte (France) */ ++#define COUNTRY_CODE_ZA (((UINT_16) 'Z' << 8) | (UINT_16) 'A') /* South Africa */ ++#define COUNTRY_CODE_ZM (((UINT_16) 'Z' << 8) | (UINT_16) 'M') /* Zambia */ ++#define COUNTRY_CODE_ZW (((UINT_16) 'Z' << 8) | (UINT_16) 'W') /* Zimbabwe */ ++ ++#define COUNTRY_CODE_DF (((UINT_16) 'D' << 8) | (UINT_16) 'F') /* Default country domain */ ++#define COUNTRY_CODE_UDF (((UINT_16) 'U' << 8) | (UINT_16) 'D') /* User defined supported channel list ++ and passive scan channel list */ ++ ++#define COUNTRY_CODE_FF (((UINT_16) 'F' << 8) | (UINT_16) 'F') /* enable open for all channel for Certification */ ++#define COUNTRY_CODE_FE (((UINT_16) 'F' << 8) | (UINT_16) 'E') /* disable open for all channel for Certification */ ++ ++/* dot11RegDomainsSupportValue */ ++#define MIB_REG_DOMAIN_FCC 0x10 /* FCC (US) */ ++#define MIB_REG_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ ++#define MIB_REG_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ ++#define MIB_REG_DOMAIN_SPAIN 0x31 /* Spain */ ++#define MIB_REG_DOMAIN_FRANCE 0x32 /* France */ ++#define MIB_REG_DOMAIN_JAPAN 0x40 /* MPHPT (Japan) */ ++#define MIB_REG_DOMAIN_OTHER 0x00 /* other */ ++ ++/*2.4G*/ ++#define BAND_2G4_LOWER_BOUND 1 ++#define BAND_2G4_UPPER_BOUND 14 ++/*5G SubBand FCC spec*/ ++#define UNII1_LOWER_BOUND 36 ++#define UNII1_UPPER_BOUND 48 ++#define UNII2A_LOWER_BOUND 52 ++#define UNII2A_UPPER_BOUND 64 ++#define UNII2C_LOWER_BOUND 100 ++#define UNII2C_UPPER_BOUND 144 ++#define UNII3_LOWER_BOUND 149 ++#define UNII3_UPPER_BOUND 173 ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++#define POWER_LIMIT_TABLE_NULL 0xFFFF ++#define MAX_TX_POWER 63 ++#define MIN_TX_POWER -64 ++#define MAX_CMD_SUPPORT_CHANNEL_NUM 64 ++ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++typedef enum _ENUM_POWER_LIMIT_T { ++ PWR_LIMIT_CCK, ++ PWR_LIMIT_20M, ++ PWR_LIMIT_40M, ++ PWR_LIMIT_80M, ++ PWR_LIMIT_160M, ++ PWR_LIMIT_NUM ++} ENUM_POWER_LIMIT_T, *P_ENUM_POWER_LIMIT_T; ++ ++#endif ++ ++typedef enum _ENUM_POWER_LIMIT_SUBBAND_T { ++ POWER_LIMIT_2G4, ++ POWER_LIMIT_UNII1, ++ POWER_LIMIT_UNII2A, ++ POWER_LIMIT_UNII2C, ++ POWER_LIMIT_UNII3, ++ POWER_LIMIT_SUBAND_NUM ++} ENUM_POWER_LIMIT_SUBBAND_T, *P_ENUM_POWER_LIMIT_SUBBAND_T; ++ ++/* Define channel offset in unit of 5MHz bandwidth */ ++typedef enum _ENUM_CHNL_SPAN_T { ++ CHNL_SPAN_5 = 1, ++ CHNL_SPAN_10 = 2, ++ CHNL_SPAN_20 = 4, ++ CHNL_SPAN_40 = 8 ++} ENUM_CHNL_SPAN_T, *P_ENUM_CHNL_SPAN_T; ++ ++/* Define BSS operating bandwidth */ ++typedef enum _ENUM_CHNL_BW_T { ++ CHNL_BW_20, ++ CHNL_BW_20_40, ++ CHNL_BW_10, ++ CHNL_BW_5 ++} ENUM_CHNL_BW_T, *P_ENUM_CHNL_BW_T; ++ ++/* In all bands, the first channel will be SCA and the second channel is SCB, ++ * then iteratively. ++ * Note the final channel will not be SCA. ++ */ ++typedef struct _DOMAIN_SUBBAND_INFO { ++ /* Note1: regulation class depends on operation bandwidth and RF band. ++ * For example: 2.4GHz, 1~13, 20MHz ==> regulation class = 81 ++ * 2.4GHz, 1~13, SCA ==> regulation class = 83 ++ * 2.4GHz, 1~13, SCB ==> regulation class = 84 ++ * Note2: TX power limit is not specified here because path loss is unknown ++ */ ++ UINT_8 ucRegClass; /* Regulation class for 20MHz */ ++ UINT_8 ucBand; /* Type: ENUM_BAND_T */ ++ UINT_8 ucChannelSpan; /* Type: ENUM_CHNL_SPAN_T */ ++ UINT_8 ucFirstChannelNum; ++ UINT_8 ucNumChannels; ++ UINT_8 fgDfs; /* Type: BOOLEAN */ ++} DOMAIN_SUBBAND_INFO, *P_DOMAIN_SUBBAND_INFO; ++ ++/* Use it as all available channel list for STA */ ++typedef struct _DOMAIN_INFO_ENTRY { ++ PUINT_16 pu2CountryGroup; ++ UINT_32 u4CountryNum; ++ ++ /* If different attributes, put them into different rSubBands. ++ * For example, DFS shall be used or not. ++ */ ++ DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM]; ++} DOMAIN_INFO_ENTRY, *P_DOMAIN_INFO_ENTRY; ++ ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++typedef struct _CHANNEL_POWER_LIMIT { ++ UINT_8 ucCentralCh; ++ INT_8 cPwrLimitCCK; ++ INT_8 cPwrLimit20; ++ INT_8 cPwrLimit40; ++ INT_8 cPwrLimit80; ++ INT_8 cPwrLimit160; ++ UINT_8 ucFlag; ++ UINT_8 aucReserved[1]; ++} CHANNEL_POWER_LIMIT, *P_CHANNEL_POWER_LIMIT; ++ ++typedef struct _COUNTRY_CHANNEL_POWER_LIMIT { ++ UINT_8 aucCountryCode[2]; ++ UINT_8 ucCountryFlag; ++ UINT_8 ucChannelNum; ++ UINT_8 aucReserved[4]; ++ CHANNEL_POWER_LIMIT rChannelPowerLimit[80]; ++} COUNTRY_CHANNEL_POWER_LIMIT, *P_COUNTRY_CHANNEL_POWER_LIMIT; ++ ++#define CHANNEL_PWR_LIMIT(_channel, _pwrLimit_cck, _pwrLimit_bw20, \ ++ _pwrLimit_bw40, _pwrLimit_bw80, _pwrLimit_bw160, _ucFlag) \ ++ { \ ++ .ucCentralCh = (_channel), \ ++ .cPwrLimitCCK = (_pwrLimit_cck), \ ++ .cPwrLimit20 = (_pwrLimit_bw20), \ ++ .cPwrLimit40 = (_pwrLimit_bw40), \ ++ .cPwrLimit80 = (_pwrLimit_bw80), \ ++ .cPwrLimit160 = (_pwrLimit_bw160), \ ++ .ucFlag = (_ucFlag), \ ++ .aucReserved = {0} \ ++} ++ ++typedef struct _COUNTRY_POWER_LIMIT_TABLE_DEFAULT { ++ UINT_8 aucCountryCode[2]; ++ /* 0: ch 1 ~14 , 1: ch 36 ~48, 2: ch 52 ~64, 3: ch 100 ~144, 4: ch 149 ~165 */ ++ INT_8 aucPwrLimitSubBand[POWER_LIMIT_SUBAND_NUM]; ++ /* bit0: cPwrLimit2G4, bit1: cPwrLimitUnii1; bit2: cPwrLimitUnii2A; ++ * bit3: cPwrLimitUnii2C; bit4: cPwrLimitUnii3; mW: 0, mW\MHz : 1 */ ++ UINT_8 ucPwrUnit; ++} COUNTRY_POWER_LIMIT_TABLE_DEFAULT, *P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT; ++ ++typedef struct _COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION { ++ UINT_8 aucCountryCode[2]; ++ UINT_8 ucCentralCh; ++ INT_8 aucPwrLimit[PWR_LIMIT_NUM]; ++} COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION, *P_COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION; ++ ++typedef struct _SUBBAND_CHANNEL_T { ++ UINT_8 ucStartCh; ++ UINT_8 ucEndCh; ++ UINT_8 ucInterval; ++ UINT_8 ucReserved; ++} SUBBAND_CHANNEL_T, *P_SUBBAND_CHANNEL_T; ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define CAL_CH_OFFSET_80M(_PRIMARY_CH, _CENTRAL_CH) \ ++ (((_PRIMARY_CH - _CENTRAL_CH) + 6) >> 2) ++ ++#define CAL_CH_OFFSET_160M(_PRIMARY_CH, _CENTRAL_CH) \ ++ (((_PRIMARY_CH - _CENTRAL_CH) + 14) >> 2) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter); ++ ++VOID ++rlmDomainGetChnlList(P_ADAPTER_T prAdapter, ++ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, ++ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList); ++ ++VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); ++ ++VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); ++ ++VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); ++ ++BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel); ++ ++UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf); ++ ++BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh); ++ ++UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++BOOLEAN rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, ++ UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend, ++ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2); ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++BOOLEAN ++rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, ++ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, ++ UINT_8 ucPwrLimitNum); ++ ++VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter); ++ ++UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode); ++ ++VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_DOMAIN_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h +new file mode 100644 +index 000000000000..7f29dba4ce06 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h +@@ -0,0 +1,150 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_obss.h#1 ++*/ ++ ++/*! \file "rlm_obss.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_obss.h ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ++ * ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Refine function when rcv a 20/40M public action frame ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 05 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process 20/40 coexistence public action frame in AP mode ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add virtual test for OBSS scan ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++#ifndef _RLM_OBSS_H ++#define _RLM_OBSS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define CHNL_LIST_SZ_2G 14 ++#define CHNL_LIST_SZ_5G 14 ++ ++#define CHNL_LEVEL0 0 ++#define CHNL_LEVEL1 1 ++#define CHNL_LEVEL2 2 ++ ++#define AFFECTED_CHNL_OFFSET 5 ++ ++#define OBSS_SCAN_MIN_INTERVAL 10 /* In unit of sec */ ++ ++#define PUBLIC_ACTION_MAX_LEN 200 /* In unit of byte */ ++ ++/* P2P GO only */ ++/* Define default OBSS Scan parameters (from MIB in spec.) */ ++#define dot11OBSSScanPassiveDwell 20 ++#define dot11OBSSScanActiveDwell 10 ++#define dot11OBSSScanPassiveTotalPerChannel 200 ++#define dot11OBSSScanActiveTotalPerChannel 20 ++#define dot11BSSWidthTriggerScanInterval 300 /* Unit: sec */ ++#define dot11BSSWidthChannelTransitionDelayFactor 5 ++#define dot11OBSSScanActivityThreshold 25 ++ ++#define OBSS_20_40M_TIMEOUT (dot11BSSWidthTriggerScanInterval + 10) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* Control MAC PCO function */ ++typedef enum _ENUM_SYS_PCO_PHASE_T { ++ SYS_PCO_PHASE_DISABLED = 0, ++ SYS_PCO_PHASE_20M, ++ SYS_PCO_PHASE_40M ++} ENUM_SYS_PCO_PHASE_T, *P_ENUM_SYS_PCO_PHASE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID rlmObssInit(P_ADAPTER_T prAdapter); ++ ++VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); ++ ++VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_OBSS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h +new file mode 100644 +index 000000000000..8665e48569ba +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h +@@ -0,0 +1,122 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_protection.h#1 ++*/ ++ ++/*! \file "rlm_protection.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_protection.h ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++#ifndef _RLM_PROTECTION_H ++#define _RLM_PROTECTION_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_SYS_PROTECT_MODE_T { ++ SYS_PROTECT_MODE_NONE = 0, /* Mode 0 */ ++ SYS_PROTECT_MODE_ERP, /* Mode 1 */ ++ SYS_PROTECT_MODE_NON_HT, /* Mode 2 */ ++ SYS_PROTECT_MODE_20M, /* Mode 3 */ ++ ++ SYS_PROTECT_MODE_NUM ++} ENUM_SYS_PROTECT_MODE_T, *P_ENUM_SYS_PROTECT_MODE_T; ++ ++/* This definition follows HT Protection field of HT Operation IE */ ++typedef enum _ENUM_HT_PROTECT_MODE_T { ++ HT_PROTECT_MODE_NONE = 0, ++ HT_PROTECT_MODE_NON_MEMBER, ++ HT_PROTECT_MODE_20M, ++ HT_PROTECT_MODE_NON_HT, ++ ++ HT_PROTECT_MODE_NUM ++} ENUM_HT_PROTECT_MODE_T, *P_ENUM_HT_PROTECT_MODE_T; ++ ++typedef enum _ENUM_GF_MODE_T { ++ GF_MODE_NORMAL = 0, ++ GF_MODE_PROTECT, ++ GF_MODE_DISALLOWED, ++ ++ GF_MODE_NUM ++} ENUM_GF_MODE_T, *P_ENUM_GF_MODE_T; ++ ++typedef enum _ENUM_RIFS_MODE_T { ++ RIFS_MODE_NORMAL = 0, ++ RIFS_MODE_DISALLOWED, ++ ++ RIFS_MODE_NUM ++} ENUM_RIFS_MODE_T, *P_ENUM_RIFS_MODE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_PROTECTION_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h +new file mode 100644 +index 000000000000..d01c6e01e83f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h +@@ -0,0 +1,1213 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_txpwr_init.h#1 ++*/ ++ ++/*! \file "rlm_txpwr_init.h" ++ \brief ++*/ ++ ++/* ++** Log: rlm_txpwr_init.h ++*/ ++ ++ ++#ifndef _RLM_TXPWR_INIT_H ++#define _RLM_TXPWR_INIT_H ++ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/*Support Tx Power Range : 63~ -64 (unit : 0.5dBm)*/ ++ ++#define PWR_LIMIT_2G4_IN_MW_MHZ BIT(0) ++#define PWR_LIMIT_UNII1_IN_MW_MHZ BIT(1) ++#define PWR_LIMIT_UNII2A_IN_MW_MHZ BIT(2) ++#define PWR_LIMIT_UNII2C_IN_MW_MHZ BIT(3) ++#define PWR_LIMIT_UNII3_IN_MW_MHZ BIT(4) ++ ++#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT ++#define CE_FCC_TXPWR_LIMIT_CCK 30 /* 15 dBm */ ++#define CE_FCC_TXPWR_LIMIT_OFDM 20 /* 10 dBm */ ++#define CE_FCC_TXPWR_LIMIT_HT40 18 /* 9 dBm */ ++#endif ++ ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++COUNTRY_POWER_LIMIT_TABLE_DEFAULT g_rRlmPowerLimitDefault[] = { ++ ++ {{'A', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'Z'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'T'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'B', 'I'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'F'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'D'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'K', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'D'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'I'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'D', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'Q'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'E', 'R'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'F', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'A'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'N'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'W'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'R', 'K'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'K', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'L', 'Y'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'M', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'M', 'L'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'R'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'C'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'T'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'C'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'L'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'B'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'R'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'Z'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'J'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'G'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'O'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'M'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'V'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'V', 'U'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'Y', 'E'} ++ , {40, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'A', 'S'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'A', 'I'} ++ , {60, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'B', 'M'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'C', 'A'} ++ , {60, 46, 48, 48, 60} ++ , 0} ++ , ++ {{'K', 'Y'} ++ , {60, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'G', 'U'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'F', 'M'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'P', 'R'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'U', 'S'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'V', 'I'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'A', 'R'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'A', 'U'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'Z'} ++ , {40, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'B', 'W'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'K', 'H'} ++ , {40, 46, 46, 48, 60} ++ , 0} ++ , ++ {{'C', 'X'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'O'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'C', 'R'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'E', 'C'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'G', 'D'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'G', 'T'} ++ , {40, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'H', 'K'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'K', 'I'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'B'} ++ , {40, 46, 46, 46, 46} ++ , 0} ++ , ++ {{'L', 'R'} ++ , {60, 46, 60, 63, 63} ++ , 0} ++ , ++ {{'M', 'N'} ++ , {46, 32, 46, 46, 58} ++ , 0} ++ , ++ {{'A', 'N'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'N', 'Z'} ++ , {63, 46, 60, 48, 63} ++ , 0} ++ , ++ {{'N', 'I'} ++ , {60, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'P', 'W'} ++ , {60, 60, 60, 60, 60} ++ , 0} ++ , ++ {{'P', 'Y'} ++ , {60, 46, 46, 48, 60} ++ , 0} ++ , ++ {{'P', 'E'} ++ , {54, 46, 48, 42, 48} ++ , 0} ++ , ++ {{'P', 'H'} ++ , {40, 46, 46, 48, 48} ++ , 0} ++ , ++ {{'W', 'S'} ++ , {40, 40, 40, 40, 60} ++ , 0} ++ , ++ {{'S', 'G'} ++ , {46, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'L', 'K'} ++ , {46, 46, 46, 46, 46} ++ , 0} ++ , ++ {{'T', 'H'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'T', 'T'} ++ , {60, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'U', 'Y'} ++ , {63, 46, 46, 46, 46} ++ , 0} ++ , ++ {{'V', 'N'} ++ , {46, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'A', 'W'} ++ , {60, 46, 60, 60, 63} ++ , 0} ++ , ++ {{'L', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'A'} ++ , {40, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'A', 'E'} ++ , {40, 46, 46, 60, 46} ++ , 0} ++ , ++ {{'U', 'G'} ++ , {40, 46, 46, 48, 60} ++ , 0} ++ , ++ {{'M', 'M'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'L'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'D', 'Z'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'D'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'Y'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'V', 'G'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'B', 'G'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'V'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'H', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'Y'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'Z'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'D', 'K'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'E', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'E', 'T'} ++ , {40, 40, 40, 40, 63} ++ , 0} ++ , ++ {{'F', 'I'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'F', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'P', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'T', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'D', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'H'} ++ , {40, 34, 48, 60, 63} ++ , 0} ++ , ++ {{'G', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'P'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'H', 'U'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'Q'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'I', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'K', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'V'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'I'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'L', 'U'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'K'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'Q'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'R'} ++ , {40, 46, 46, 46, 63} ++ , 0} ++ , ++ {{'M', 'U'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'Y', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'D'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'C'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'N', 'L'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'N', 'O'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'O', 'M'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'P', 'L'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'P', 'T'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'R', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'R', 'O'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'M', 'F'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'M'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'N'} ++ , {40, 40, 40, 60, 63} ++ , 0} ++ , ++ {{'R', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'K'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'I'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'Z', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'E', 'S'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'S', 'E'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'C', 'H'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'T', 'R'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'T', 'C'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'G', 'B'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'V', 'A'} ++ , {40, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'A', 'M'} ++ , {40, 40, 40, 63, 63} ++ , 0} ++ , ++ {{'I', 'L'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'K', 'W'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'M', 'A'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'N', 'E'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'T', 'N'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'E', 'H'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'N', 'P'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'A', 'F'} ++ , {40, 46, 63, 63, 63} ++ , 0} ++ , ++ {{'A', 'G'} ++ , {40, 46, 48, 63, 54} ++ , 0} ++ , ++ {{'B', 'S'} ++ , {63, 46, 60, 63, 63} ++ , 0} ++ , ++ {{'B', 'H'} ++ , {40, 46, 46, 63, 63} ++ , 0} ++ , ++ {{'B', 'B'} ++ , {40, 46, 48, 63, 54} ++ , 0} ++ , ++ {{'B', 'N'} ++ , {46, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'C', 'L'} ++ , {40, 44, 44, 63, 44} ++ , 0} ++ , ++ {{'C', 'N'} ++ , {40, 46, 46, 63, 54} ++ , 0} ++ , ++ {{'E', 'G'} ++ , {40, 46, 46, 63, 46} ++ , 0} ++ , ++ {{'S', 'V'} ++ , {60, 34, 48, 63, 60} ++ , 0} ++ , ++ {{'I', 'N'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'M', 'Y'} ++ , {54, 60, 60, 63, 60} ++ , 0} ++ , ++ {{'M', 'V'} ++ , {40, 46, 46, 63, 40} ++ , 0} ++ , ++ {{'P', 'A'} ++ , {60, 34, 48, 63, 60} ++ , 0} ++ , ++ {{'V', 'E'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'Z', 'M'} ++ , {60, 46, 46, 63, 60} ++ , 0} ++ , ++ {{'J', 'O'} ++ , {40, 46, 63, 63, 46} ++ , 0} ++ , ++ {{'P', 'G'} ++ , {40, 46, 63, 63, 60} ++ , 0} ++ , ++ {{'B', 'F'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'G', 'Y'} ++ , {60, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'H', 'T'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'H', 'N'} ++ , {60, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'J', 'M'} ++ , {54, 63, 63, 63, 57} ++ , 0} ++ , ++ {{'M', 'O'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'M', 'W'} ++ , {60, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'P', 'K'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'Q', 'A'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'R', 'W'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'K', 'N'} ++ , {40, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'T', 'Z'} ++ , {40, 63, 63, 63, 40} ++ , 0} ++ , ++ {{'I', 'D'} ++ , {46, 63, 63, 63, 60} ++ , 0} ++ , ++ {{'N', 'G'} ++ , {40, 63, 46, 63, 60} ++ , 0} ++ , ++ {{'B', 'D'} ++ , {40, 46, 46, 60, 28} ++ , 0} ++ , ++ {{'B', 'R'} ++ , {52, 46, 46, 60, 60} ++ , 0} ++ , ++ {{'D', 'M'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'D', 'O'} ++ , {63, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'F', 'K'} ++ , {40, 46, 46, 60, 28} ++ , 0} ++ , ++ {{'K', 'Z'} ++ , {40, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'M', 'X'} ++ , {60, 34, 48, 60, 63} ++ , 0} ++ , ++ {{'M', 'Z'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'N', 'A'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'R', 'U'} ++ , {40, 34, 48, 60, 60} ++ , 0} ++ , ++ {{'L', 'C'} ++ , {40, 34, 48, 48, 60} ++ , 0} ++ , ++ {{'V', 'C'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'U', 'A'} ++ , {40, 46, 46, 46, 48} ++ , 0} ++ , ++ {{'U', 'Z'} ++ , {40, 48, 48, 48, 60} ++ , 0} ++ , ++ {{'Z', 'W'} ++ , {40, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'M', 'P'} ++ , {60, 34, 46, 48, 60} ++ , 0} ++ , ++ {{'T', 'W'} ++ , {60, 63, 34, 48, 60} ++ , 0} ++ , ++ {{'C', 'K'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'C', 'U'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'T', 'L'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'F', 'O'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'I'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'G', 'G'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'I', 'R'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'I', 'M'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'J', 'E'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'K', 'P'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'M', 'H'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'U'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'N', 'F'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'P', 'S'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'P', 'N'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'P', 'M'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'S'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'D'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'S', 'Y'} ++ , {63, 63, 63, 63, 63} ++ , 0} ++ , ++ {{'J', 'P'} ++ , {46, 46, 46, 60, 63} ++ , 0} ++ , ++ {{'K', 'R'} ++ , {46, 34, 46, 46, 46} ++ , PWR_LIMIT_UNII1_IN_MW_MHZ} ++ , ++ ++/*Default*/ ++ {{0, 0} ++ , {63, 63, 63, 63, 63} ++ , 0} ++}; ++ ++COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION g_rRlmPowerLimitConfiguration[] = { ++ ++ {{'A', 'I'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'A', 'Z'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'B', 'W'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'G', 'D'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'L', 'B'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'L', 'R'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'W', 'S'} ++ , 165, {40, 40, 40, 40, 40} ++ } ++ , ++ {{'V', 'N'} ++ , 144, {48, 48, 48, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 1, {38, 30, 60, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 3, {60, 60, 26, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 9, {60, 60, 26, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 11, {38, 30, 60, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 36, {34, 34, 34, 34, 34} ++ } ++ , ++ {{'U', 'S'} ++ , 38, {34, 34, 34, 34, 34} ++ } ++ , ++ {{'U', 'S'} ++ , 42, {34, 34, 34, 31, 34} ++ } ++ , ++ {{'U', 'S'} ++ , 58, {48, 48, 48, 31, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 62, {48, 48, 34, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 64, {37, 37, 48, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 100, {37, 37, 48, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 102, {48, 48, 34, 48, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 106, {48, 48, 48, 31, 48} ++ } ++ , ++ {{'U', 'S'} ++ , 155, {60, 60, 60, 31, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 159, {60, 60, 34, 60, 60} ++ } ++ , ++ {{'U', 'S'} ++ , 165, {37, 37, 60, 60, 60} ++ } ++ , ++ ++/*Default*/ ++ {{0, 0} ++ , 165, {63, 63, 63, 63, 63} ++ } ++}; ++ ++#if 0 ++COUNTRY_CHANNEL_POWER_LIMIT g_rRlmCountryPowerLimitTable[] = { ++ { ++ {'A', 'O'} ++ , 0, 0, {0, 0, 0, 0} ++ , ++ { ++ CHANNEL_PWR_LIMIT(1, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(2, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(3, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(4, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(5, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(6, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(7, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(8, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(9, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(10, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(11, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(12, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(13, 40, 40, 40, 40, 40, 0), ++ CHANNEL_PWR_LIMIT(14, 40, 40, 40, 40, 40, 0), ++ ++ CHANNEL_PWR_LIMIT(36, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(38, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(40, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(42, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(44, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(46, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(48, 63, 63, 63, 63, 63, 0), ++ ++ CHANNEL_PWR_LIMIT(52, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(54, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(56, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(58, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(60, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(62, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(64, 63, 63, 63, 63, 63, 0), ++ ++ CHANNEL_PWR_LIMIT(100, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(102, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(104, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(106, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(108, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(110, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(112, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(114, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(116, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(118, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(120, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(122, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(124, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(126, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(128, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(130, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(132, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(134, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(136, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(138, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(140, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(142, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(144, 63, 63, 63, 63, 63, 0), ++ ++ CHANNEL_PWR_LIMIT(149, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(151, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(153, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(155, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(157, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(159, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(161, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(163, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(165, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(167, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(169, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(171, 63, 63, 63, 63, 63, 0), ++ CHANNEL_PWR_LIMIT(173, 63, 63, 63, 63, 63, 0) ++ } ++ } ++ , ++ { ++ /*Used to check the end of country entry */ ++ {0, 0} ++ , 0, 0, {0, 0, 0, 0} ++ , ++ { ++ /*Used to check the end of channel power limit */ ++ CHANNEL_PWR_LIMIT(ENDCH, 0, 0, 0, 0, 0, 0) ++ } ++ } /*end of CountryTable */ ++}; ++#endif ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RLM_TXPWR_INIT_H */ ++ ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h +new file mode 100644 +index 000000000000..0df4ec3e0828 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h +@@ -0,0 +1,171 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "roaming_fsm.h" ++ \brief This file defines the FSM for Roaming MODULE. ++ ++ This file defines the FSM for Roaming MODULE. ++*/ ++ ++/* ++** Log: roaming_fsm.h ++ * ++ * 08 31 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * remove obsolete code. ++ * ++ * 08 15 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * add swcr in driver reg, 0x9fxx0000, to disable roaming . ++ * ++ * 03 16 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * remove obsolete definition and unused variables. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++*/ ++ ++#ifndef _ROAMING_FSM_H ++#define _ROAMING_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Roaming Discovery interval, SCAN result need to be updated */ ++#define ROAMING_DISCOVERY_TIMEOUT_SEC 5 /* Seconds. */ ++ ++/* #define ROAMING_NO_SWING_RCPI_STEP 5 //rcpi */ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_ROAMING_FAIL_REASON_T { ++ ROAMING_FAIL_REASON_CONNLIMIT = 0, ++ ROAMING_FAIL_REASON_NOCANDIDATE, ++ ROAMING_FAIL_REASON_NUM ++} ENUM_ROAMING_FAIL_REASON_T; ++ ++/* events of roaming between driver and firmware */ ++typedef enum _ENUM_ROAMING_EVENT_T { ++ ROAMING_EVENT_START = 0, ++ ROAMING_EVENT_DISCOVERY, ++ ROAMING_EVENT_ROAM, ++ ROAMING_EVENT_FAIL, ++ ROAMING_EVENT_ABORT, ++ ROAMING_EVENT_NUM ++} ENUM_ROAMING_EVENT_T; ++ ++#define ROAMING_EVENT_REASON_TX_ERR BIT(0) ++#define ROAMING_EVENT_REASON_RCPI BIT(1) ++ ++typedef struct _ROAMING_PARAM_T { ++ UINT_16 u2Event; ++ UINT_16 u2Data; ++ UINT_16 u2Reason; ++} ROAMING_PARAM_T, *P_ROAMING_PARAM_T; ++ ++ /**/ typedef enum _ENUM_ROAMING_STATE_T { ++ ROAMING_STATE_IDLE = 0, ++ ROAMING_STATE_DECISION, ++ ROAMING_STATE_DISCOVERY, ++ ROAMING_STATE_ROAM, ++ ROAMING_STATE_NUM ++} ENUM_ROAMING_STATE_T; ++ ++typedef struct _ROAMING_INFO_T { ++ BOOLEAN fgIsEnableRoaming; ++ ++ ENUM_ROAMING_STATE_T eCurrentState; ++ ++ OS_SYSTIME rRoamingDiscoveryUpdateTime; ++ ++#define ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX 2 ++ UINT_32 RoamingEntryTimeoutSkipCount; ++ ++} ROAMING_INFO_T, *P_ROAMING_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if CFG_SUPPORT_ROAMING ++#define IS_ROAMING_ACTIVE(prAdapter) \ ++ (prAdapter->rWifiVar.rRoamingInfo.eCurrentState == ROAMING_STATE_ROAM) ++#else ++#define IS_ROAMING_ACTIVE(prAdapter) FALSE ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID roamingFsmInit(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); ++ ++VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState); ++ ++VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); ++ ++VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter); ++ ++VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Reason); ++ ++VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _ROAMING_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h +new file mode 100644 +index 000000000000..20ab14251f65 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h +@@ -0,0 +1,271 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rsn.h#1 ++*/ ++ ++/*! \file rsn.h ++ \brief The wpa/rsn related define, macro and structure are described here. ++*/ ++ ++/* ++** Log: rsn.h ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 wh.su ++ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h ++ * and let the sw structure not align at byte ++ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, ++ * Notice needed update P2P.ko. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value ++ * fixed the.pmkid value mismatch issue ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * add a kal function for set cipher. ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 30 2010 wh.su ++ * NULL ++ * remove non-used code. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, and modify ++ * the security related callback function prototype. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function prototype for generate wap/rsn ie ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function input parameter ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some event function declaration ++ * ++ * Nov 26 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * move the internal data structure for pmkid to rsn.h ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the port control and class error function ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the pmkid candidate ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++#ifndef _RSN_H ++#define _RSN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* ----- Definitions for Cipher Suite Selectors ----- */ ++#define RSN_CIPHER_SUITE_USE_GROUP_KEY 0x00AC0F00 ++#define RSN_CIPHER_SUITE_WEP40 0x01AC0F00 ++#define RSN_CIPHER_SUITE_TKIP 0x02AC0F00 ++#define RSN_CIPHER_SUITE_CCMP 0x04AC0F00 ++#define RSN_CIPHER_SUITE_WEP104 0x05AC0F00 ++#if CFG_SUPPORT_802_11W ++#define RSN_CIPHER_SUITE_AES_128_CMAC 0x06AC0F00 ++#endif ++ ++#define WPA_CIPHER_SUITE_NONE 0x00F25000 ++#define WPA_CIPHER_SUITE_WEP40 0x01F25000 ++#define WPA_CIPHER_SUITE_TKIP 0x02F25000 ++#define WPA_CIPHER_SUITE_CCMP 0x04F25000 ++#define WPA_CIPHER_SUITE_WEP104 0x05F25000 ++ ++/* ----- Definitions for Authentication and Key Management Suite Selectors ----- */ ++#define RSN_AKM_SUITE_NONE 0x00AC0F00 ++#define RSN_AKM_SUITE_802_1X 0x01AC0F00 ++#define RSN_AKM_SUITE_PSK 0x02AC0F00 ++#if CFG_SUPPORT_802_11W ++#define RSN_AKM_SUITE_802_1X_SHA256 0x05AC0F00 ++#define RSN_AKM_SUITE_PSK_SHA256 0x06AC0F00 ++#endif ++ ++#define WPA_AKM_SUITE_NONE 0x00F25000 ++#define WPA_AKM_SUITE_802_1X 0x01F25000 ++#define WPA_AKM_SUITE_PSK 0x02F25000 ++ ++#define ELEM_ID_RSN_LEN_FIXED 20 /* The RSN IE len for associate request */ ++ ++#define ELEM_ID_WPA_LEN_FIXED 22 /* The RSN IE len for associate request */ ++ ++#define MASK_RSNIE_CAP_PREAUTH BIT(0) ++ ++#define GET_SELECTOR_TYPE(x) ((UINT_8)(((x) >> 24) & 0x000000FF)) ++#define SET_SELECTOR_TYPE(x, y) {x = (((x) & 0x00FFFFFF) | (((UINT_32)(y) << 24) & 0xFF000000))} ++ ++#define AUTH_CIPHER_CCMP 0x00000008 ++ ++/* Cihpher suite flags */ ++#define CIPHER_FLAG_NONE 0x00000000 ++#define CIPHER_FLAG_WEP40 0x00000001 /* BIT 1 */ ++#define CIPHER_FLAG_TKIP 0x00000002 /* BIT 2 */ ++#define CIPHER_FLAG_CCMP 0x00000008 /* BIT 4 */ ++#define CIPHER_FLAG_WEP104 0x00000010 /* BIT 5 */ ++#define CIPHER_FLAG_WEP128 0x00000020 /* BIT 6 */ ++ ++#define WAIT_TIME_IND_PMKID_CANDICATE_SEC 6 /* seconds */ ++#define TKIP_COUNTERMEASURE_SEC 60 /* seconds */ ++ ++#if CFG_SUPPORT_802_11W ++#define RSN_AUTH_MFP_DISABLED 0 /* MFP disabled */ ++#define RSN_AUTH_MFP_OPTIONAL 1 /* MFP optional */ ++#define RSN_AUTH_MFP_REQUIRED 2 /* MFP required */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* Flags for PMKID Candidate list structure */ ++#define EVENT_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 ++ ++#define CONTROL_FLAG_UC_MGMT_NO_ENC BIT(5) ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define RSN_IE(fp) ((P_RSN_INFO_ELEM_T) fp) ++#define WPA_IE(fp) ((P_WPA_INFO_ELEM_T) fp) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo); ++ ++BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo); ++ ++BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index); ++ ++BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index); ++ ++BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); ++ ++VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++BOOLEAN ++rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion); ++ ++BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo); ++ ++#if CFG_SUPPORT_AAA ++void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode); ++#endif ++ ++VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType); ++ ++VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex); ++ ++BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter); ++ ++VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); ++ ++VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter); ++ ++VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); ++#if CFG_SUPPORT_WPS2 ++VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++#endif ++ ++#if CFG_SUPPORT_802_11W ++UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter); ++ ++void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter); ++ ++void rsnStartSaQuery(IN P_ADAPTER_T prAdapter); ++ ++void rsnStopSaQuery(IN P_ADAPTER_T prAdapter); ++ ++void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype); ++#endif ++BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _RSN_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h +new file mode 100644 +index 000000000000..c08b2244be6c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h +@@ -0,0 +1,988 @@ ++/* ++** Id: @(#) ++*/ ++ ++/*! \file "scan.h" ++ \brief ++ ++*/ ++ ++/* ++** Log: scan.h ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration ++ * with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting ++ * preferred band configuration corresponding to network type. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID ++ * in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID ++ * support as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings ++ * to work around some tricky AP which use space character as hidden SSID ++ * allow to have a single BSSID with multiple SSID to be presented in scanning result ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module ++ * with structure miss-align pointer issue ++ * always pre-allio WAPI related structure for align p2p module. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix compile error. ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add a functio prototype to find p2p descriptor of a bss descriptor directly. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add function prototype for return channel. ++ * modify data structure for scan specific device ID or TYPE. (Move from P2P Connection Settings to Scan Param) ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Check-in P2P Device Discovery Feature. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add a option for channel time extension in scan abort command. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Scan status "FIND" is used for P2P FSM find state. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * SCN module is now able to handle multiple concurrent scanning requests ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * pass band with channel number information as scan parameter ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * remove timer in DRV-SCN. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, other request ++ * will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan uninitialization procedure ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P related field in SCAN_PARAM_T. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 13 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * ++ * Add new HW CH macro support ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify scanBuildProbeReqFrameCommonIEs() to support P2P SCAN ++ * ++ * 02 23 2010 wh.su ++ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver ++ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * Simplify the process of Beacon during SCAN and remove redundant variable in PRE_BSS_DESC_T ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding variable for wapi ap ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * remove non-used secuirty variavle ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Refine data structure of BSS_DESC_T and PRE_BSS_DESC_T ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add eNetType to rScanParam and revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add ucAvailablePhyTypeSet to BSS_DESC_T ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aucSrcAddress to SCAN_PARAM_T for P2P's Device Address ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the security related variable ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the security ie filed for scan parsing ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add scanSearchBssDescByPolicy() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function declarations of scan_fsm.c ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add scan.h to source control ++** ++*/ ++ ++#ifndef _SCAN_H ++#define _SCAN_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "gl_vendor.h" ++ ++/* TDLS test purpose */ ++extern BOOLEAN flgTdlsTestExtCapElm; ++extern UINT8 aucTdlsTestExtCapElm[]; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/*! Maximum buffer size of SCAN list */ ++#define SCN_MAX_BUFFER_SIZE (CFG_MAX_NUM_BSS_LIST * ALIGN_4(sizeof(BSS_DESC_T))) ++ ++#define SCN_RM_POLICY_EXCLUDE_CONNECTED BIT(0) /* Remove SCAN result except the connected one. */ ++#define SCN_RM_POLICY_TIMEOUT BIT(1) /* Remove the timeout one */ ++#define SCN_RM_POLICY_OLDEST_HIDDEN BIT(2) /* Remove the oldest one with hidden ssid */ ++#define SCN_RM_POLICY_SMART_WEAKEST BIT(3) /* If there are more than half BSS which has the ++ * same ssid as connection setting, remove the ++ * weakest one from them ++ * Else remove the weakest one. ++ */ ++#define SCN_RM_POLICY_ENTIRE BIT(4) /* Remove entire SCAN result */ ++ ++#define SCN_BSS_DESC_SAME_SSID_THRESHOLD 3 /* This is used by POLICY SMART WEAKEST, ++ * If exceed this value, remove weakest BSS_DESC_T ++ * with same SSID first in large network. ++ */ ++ ++/* the scan time in WFD mode + 2.4G/5G is about 9s so we need to enlarge the value */ ++#define SCN_BSS_DESC_REMOVE_TIMEOUT_SEC 15 /* Second. */ ++ /* This is used by POLICY TIMEOUT, ++ * If exceed this value, remove timeout BSS_DESC_T. ++ */ ++ ++#define SCN_PROBE_DELAY_MSEC 0 ++ ++#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC 5 /* Second. */ ++ ++#define SCN_NLO_NETWORK_CHANNEL_NUM (4) ++ ++/*----------------------------------------------------------------------------*/ ++/* MSG_SCN_SCAN_REQ */ ++/*----------------------------------------------------------------------------*/ ++#define SCAN_REQ_SSID_WILDCARD BIT(0) ++#define SCAN_REQ_SSID_P2P_WILDCARD BIT(1) ++#define SCAN_REQ_SSID_SPECIFIED BIT(2) ++ ++/*----------------------------------------------------------------------------*/ ++/* Support Multiple SSID SCAN */ ++/*----------------------------------------------------------------------------*/ ++#define SCN_SSID_MAX_NUM CFG_SCAN_SSID_MAX_NUM ++#define SCN_SSID_MATCH_MAX_NUM CFG_SCAN_SSID_MATCH_MAX_NUM ++ ++#define SWC_NUM_BSSID_THRESHOLD_DEFAULT 8 ++#define SWC_RSSI_WINDSIZE_DEFAULT 8 ++#define LOST_AP_WINDOW 16 ++#define MAX_CHANNEL_NUM_PER_BUCKETS 8 ++ ++#define SCN_BSS_JOIN_FAIL_THRESOLD 4 ++#define SCN_BSS_JOIN_FAIL_CNT_RESET_SEC 15 ++#define SCN_BSS_JOIN_FAIL_RESET_STEP 2 ++ ++#if CFG_SUPPORT_BATCH_SCAN ++/*----------------------------------------------------------------------------*/ ++/* SCAN_BATCH_REQ */ ++/*----------------------------------------------------------------------------*/ ++#define SCAN_BATCH_REQ_START BIT(0) ++#define SCAN_BATCH_REQ_STOP BIT(1) ++#define SCAN_BATCH_REQ_RESULT BIT(2) ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_SCAN_TYPE_T { ++ SCAN_TYPE_PASSIVE_SCAN = 0, ++ SCAN_TYPE_ACTIVE_SCAN, ++ SCAN_TYPE_NUM ++} ENUM_SCAN_TYPE_T, *P_ENUM_SCAN_TYPE_T; ++ ++typedef enum _ENUM_SCAN_STATE_T { ++ SCAN_STATE_IDLE = 0, ++ SCAN_STATE_SCANNING, ++ SCAN_STATE_NUM ++} ENUM_SCAN_STATE_T; ++ ++typedef enum _ENUM_SCAN_CHANNEL_T { ++ SCAN_CHANNEL_FULL = 0, ++ SCAN_CHANNEL_2G4, ++ SCAN_CHANNEL_5G, ++ SCAN_CHANNEL_P2P_SOCIAL, ++ SCAN_CHANNEL_SPECIFIED, ++ SCAN_CHANNEL_NUM ++} ENUM_SCAN_CHANNEL, *P_ENUM_SCAN_CHANNEL; ++ ++typedef struct _MSG_SCN_FSM_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_32 u4Dummy; ++} MSG_SCN_FSM_T, *P_MSG_SCN_FSM_T; ++ ++typedef enum _ENUM_PSCAN_STATE_T { ++ PSCN_IDLE = 1, ++ PSCN_SCANNING, ++ PSCN_RESET, ++ PSCAN_STATE_T_NUM ++} ENUM_PSCAN_STATE_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* BSS Descriptors */ ++/*----------------------------------------------------------------------------*/ ++struct _BSS_DESC_T { ++ LINK_ENTRY_T rLinkEntry; ++ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ ++ ++ BOOLEAN fgIsConnecting; /* If we are going to connect to this BSS ++ * (JOIN or ROAMING to another BSS), don't ++ * remove this record from BSS List. ++ */ ++ BOOLEAN fgIsConnected; /* If we have connected to this BSS (NORMAL_TR), ++ * don't removed this record from BSS list. ++ */ ++ ++ BOOLEAN fgIsHiddenSSID; /* When this flag is TRUE, means the SSID ++ * of this BSS is not known yet. ++ */ ++ UINT_8 ucSSIDLen; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ ++ OS_SYSTIME rUpdateTime; ++ ++ ENUM_BSS_TYPE_T eBSSType; ++ ++ UINT_16 u2CapInfo; ++ ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2ATIMWindow; ++ ++ UINT_16 u2OperationalRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ ++ BOOLEAN fgIsERPPresent; ++ BOOLEAN fgIsHTPresent; ++ ++ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this BSS */ ++ ++ UINT_8 ucChannelNum; ++ ++ ENUM_CHNL_EXT_T eSco; /* Record bandwidth for association process ++ Some AP will send association resp by 40MHz BW */ ++ ENUM_BAND_T eBand; ++ ++ UINT_8 ucDTIMPeriod; ++ ++ BOOLEAN fgIsLargerTSF; /* This BSS's TimeStamp is larger than us(TCL == 1 in RX_STATUS_T) */ ++ ++ UINT_8 ucRCPI; ++ ++ UINT_8 ucWmmFlag; /* A flag to indicate this BSS's WMM capability */ ++ ++ /*! \brief The srbiter Search State will matched the scan result, ++ and saved the selected cipher and akm, and report the score, ++ for arbiter join state, join module will carry this target BSS ++ to rsn generate ie function, for gen wpa/rsn ie */ ++ UINT_32 u4RsnSelectedGroupCipher; ++ UINT_32 u4RsnSelectedPairwiseCipher; ++ UINT_32 u4RsnSelectedAKMSuite; ++ ++ UINT_16 u2RsnCap; ++ ++ RSN_INFO_T rRSNInfo; ++ RSN_INFO_T rWPAInfo; ++#if 1 /* CFG_SUPPORT_WAPI */ ++ WAPI_INFO_T rIEWAPI; ++ BOOLEAN fgIEWAPI; ++#endif ++ BOOLEAN fgIERSN; ++ BOOLEAN fgIEWPA; ++ ++ /*! \brief RSN parameters selected for connection */ ++ /*! \brief The Select score for final AP selection, ++ 0, no sec, 1,2,3 group cipher is WEP, TKIP, CCMP */ ++ UINT_8 ucEncLevel; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsP2PPresent; ++ BOOLEAN fgIsP2PReport; /* TRUE: report to upper layer */ ++ P_P2P_DEVICE_DESC_T prP2pDesc; ++ ++ UINT_8 aucIntendIfAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ ++/* UINT_8 ucDevCapabilityBitmap; */ /* Device Capability Attribute. (P2P_DEV_CAPABILITY_XXXX) */ ++/* UINT_8 ucGroupCapabilityBitmap; */ /* Group Capability Attribute. (P2P_GROUP_CAPABILITY_XXXX) */ ++ ++ LINK_T rP2pDeviceList; ++ ++/* P_LINK_T prP2pDeviceList; */ ++ ++ /* For ++ * 1. P2P Capability. ++ * 2. P2P Device ID. ( in aucSrcAddr[] ) ++ * 3. NOA (TODO:) ++ * 4. Extend Listen Timing. (Probe Rsp) (TODO:) ++ * 5. P2P Device Info. (Probe Rsp) ++ * 6. P2P Group Info. (Probe Rsp) ++ */ ++#endif ++ ++ BOOLEAN fgIsIEOverflow; /* The received IE length exceed the maximum IE buffer size */ ++ UINT_16 u2RawLength; /* The byte count of aucRawBuf[] */ ++ UINT_16 u2IELength; /* The byte count of aucIEBuf[] */ ++ ++ ULARGE_INTEGER u8TimeStamp; /* Place u8TimeStamp before aucIEBuf[1] to force DW align */ ++ UINT_8 aucRawBuf[CFG_RAW_BUFFER_SIZE]; ++ UINT_8 aucIEBuf[CFG_IE_BUFFER_SIZE]; ++ UINT_8 ucJoinFailureCount; ++ OS_SYSTIME rJoinFailTime; ++}; ++ ++typedef struct _SCAN_PARAM_T { /* Used by SCAN FSM */ ++ /* Active or Passive */ ++ ENUM_SCAN_TYPE_T eScanType; ++ ++ /* Network Type */ ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ ++ /* Specified SSID Type */ ++ UINT_8 ucSSIDType; ++ UINT_8 ucSSIDNum; ++ ++ /* Length of Specified SSID */ ++ UINT_8 ucSpecifiedSSIDLen[SCN_SSID_MAX_NUM]; ++ ++ /* Specified SSID */ ++ UINT_8 aucSpecifiedSSID[SCN_SSID_MAX_NUM][ELEM_MAX_LEN_SSID]; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgFindSpecificDev; /* P2P: Discovery Protocol */ ++ UINT_8 aucDiscoverDevAddr[MAC_ADDR_LEN]; ++ BOOLEAN fgIsDevType; ++ P2P_DEVICE_TYPE_T rDiscoverDevType; ++ ++ UINT_16 u2PassiveListenInterval; ++ /* TODO: Find Specific Device Type. */ ++#endif /* CFG_SUPPORT_P2P */ ++ ++ BOOLEAN fgIsObssScan; ++ BOOLEAN fgIsScanV2; ++ ++ /* Run time flags */ ++ UINT_16 u2ProbeDelayTime; ++ ++ /* channel information */ ++ ENUM_SCAN_CHANNEL eScanChannel; ++ UINT_8 ucChannelListNum; ++ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ ++ /* Feedback information */ ++ UINT_8 ucSeqNum; ++ ++ /* Information Element */ ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++ ++} SCAN_PARAM_T, *P_SCAN_PARAM_T; ++ ++typedef struct _NLO_PARAM_T { /* Used by SCAN FSM */ ++ SCAN_PARAM_T rScanParam; ++ ++ /* NLO */ ++ BOOLEAN fgStopAfterIndication; ++ UINT_8 ucFastScanIteration; ++ UINT_16 u2FastScanPeriod; ++ UINT_16 u2SlowScanPeriod; ++ ++ /* Match SSID */ ++ UINT_8 ucMatchSSIDNum; ++ UINT_8 ucMatchSSIDLen[SCN_SSID_MATCH_MAX_NUM]; ++ UINT_8 aucMatchSSID[SCN_SSID_MATCH_MAX_NUM][ELEM_MAX_LEN_SSID]; ++ ++ UINT_8 aucCipherAlgo[SCN_SSID_MATCH_MAX_NUM]; ++ UINT_16 au2AuthAlgo[SCN_SSID_MATCH_MAX_NUM]; ++ UINT_8 aucChannelHint[SCN_SSID_MATCH_MAX_NUM][SCN_NLO_NETWORK_CHANNEL_NUM]; ++ P_BSS_DESC_T aprPendingBssDescToInd[SCN_SSID_MATCH_MAX_NUM]; ++} NLO_PARAM_T, *P_NLO_PARAM_T; ++ ++#if 1 ++ ++typedef struct _GSCN_CHANNEL_INFO_T { ++ UINT_8 ucBand; ++ UINT_8 ucChannel; /* frequency */ ++ UINT_8 ucPassive; /* 0 => active, 1 => passive scan; ignored for DFS */ ++ UINT_8 aucReserved[1]; ++ ++ UINT_32 u4DwellTimeMs; /* dwell time hint */ ++ /* Add channel class */ ++} GSCN_CHANNEL_INFO_T, *P_GSCN_CHANNEL_INFO_T; ++ ++typedef struct _GSCAN_CHANNEL_BUCKET_T { ++ ++ UINT_16 u2BucketIndex; /* bucket index, 0 based */ ++ UINT_8 ucBucketFreqMultiple; /* desired period, in millisecond; ++ * if this is too low, the firmware should choose to generate ++ * results as fast as it can instead of failing the command */ ++ /* report_events semantics - ++ * 0 => report only when scan history is % full ++ * 1 => same as 0 + report a scan completion event after scanning this bucket ++ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL ++ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to ++ supplicant as well (optional) . */ ++ UINT_8 ucReportFlag; ++ UINT_8 ucNumChannels; ++ UINT_8 aucReserved[3]; ++ WIFI_BAND eBand; /* when UNSPECIFIED, use channel list */ ++ GSCN_CHANNEL_INFO_T arChannelList[GSCAN_MAX_CHANNELS]; /* channels to scan; these may include DFS channels */ ++} GSCAN_CHANNEL_BUCKET_T, *P_GSCAN_CHANNEL_BUCKET_T; ++ ++typedef struct _CMD_GSCN_REQ_T { ++ UINT_8 ucFlags; ++ UINT_8 ucNumScnToCache; ++ UINT_8 aucReserved[2]; ++ UINT_32 u4BufferThreshold; ++ UINT_32 u4BasePeriod; /* base timer period in ms */ ++ UINT_32 u4NumBuckets; ++ UINT_32 u4MaxApPerScan; /* number of APs to store in each scan in the */ ++ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ ++ ++ GSCAN_CHANNEL_BUCKET_T arChannelBucket[GSCAN_MAX_BUCKETS]; ++} CMD_GSCN_REQ_T, *P_CMD_GSCN_REQ_T; ++ ++#endif ++ ++typedef struct _CMD_GSCN_SCN_COFIG_T { ++ UINT_8 ucNumApPerScn; /* GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN */ ++ UINT_32 u4NumScnToCache; /* GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE */ ++ UINT_32 u4BufferThreshold; /* GSCAN_ATTRIBUTE_REPORT_THRESHOLD */ ++} CMD_GSCN_SCN_COFIG_T, *P_CMD_GSCN_SCN_COFIG_T; ++ ++typedef struct _CMD_GET_GSCAN_RESULT { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[2]; ++ UINT_8 ucFlush; ++ UINT_32 u4Num; ++} CMD_GET_GSCAN_RESULT_T, *P_CMD_GET_GSCAN_RESULT_T; ++ ++typedef struct _CMD_BATCH_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucCmd; /* Start/ Stop */ ++ UINT_8 ucMScan; /* an integer number of scans per batch */ ++ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ ++ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd like ++ approximate distance reported */ ++ UINT_8 ucChannel; /* channels */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ ++ CHANNEL_INFO_T arChannelList[32]; /* channels */ ++} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; ++ ++typedef struct _PSCN_PARAM_T { ++ UINT_8 ucVersion; ++ CMD_NLO_REQ rCurrentCmdNloReq; ++ CMD_BATCH_REQ_T rCurrentCmdBatchReq; ++ CMD_GSCN_REQ_T rCurrentCmdGscnReq; ++ BOOLEAN fgNLOScnEnable; ++ BOOLEAN fgBatchScnEnable; ++ BOOLEAN fgGScnEnable; ++ UINT_32 u4BasePeriod; /* GSCAN_ATTRIBUTE_BASE_PERIOD */ ++} PSCN_PARAM_T, *P_PSCN_PARAM_T; ++ ++typedef struct _SCAN_INFO_T { ++ ENUM_SCAN_STATE_T eCurrentState; /* Store the STATE variable of SCAN FSM */ ++ ++ OS_SYSTIME rLastScanCompletedTime; ++ ++ SCAN_PARAM_T rScanParam; ++ NLO_PARAM_T rNloParam; ++ ++ UINT_32 u4NumOfBssDesc; ++ ++ UINT_8 aucScanBuffer[SCN_MAX_BUFFER_SIZE]; ++ ++ LINK_T rBSSDescList; ++ ++ LINK_T rFreeBSSDescList; ++ ++ LINK_T rPendingMsgList; ++ ++ /* Sparse Channel Detection */ ++ BOOLEAN fgIsSparseChannelValid; ++ RF_CHANNEL_INFO_T rSparseChannel; ++ ++ /* NLO scanning state tracking */ ++ BOOLEAN fgNloScanning; ++ BOOLEAN fgPscnOnnning; ++ BOOLEAN fgGScnConfigSet; ++ BOOLEAN fgGScnParamSet; ++ P_PSCN_PARAM_T prPscnParam; ++ ENUM_PSCAN_STATE_T eCurrentPSCNState; ++ ++} SCAN_INFO_T, *P_SCAN_INFO_T; ++ ++/* Incoming Mailbox Messages */ ++typedef struct _MSG_SCN_SCAN_REQ_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ ENUM_SCAN_TYPE_T eScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDLength; ++ UINT_8 aucSSID[PARAM_MAX_LEN_SSID]; ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ ++#endif ++ ENUM_SCAN_CHANNEL eScanChannel; ++ UINT_8 ucChannelListNum; ++ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} MSG_SCN_SCAN_REQ, *P_MSG_SCN_SCAN_REQ; ++ ++typedef struct _MSG_SCN_SCAN_REQ_V2_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ ENUM_SCAN_TYPE_T eScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDNum; ++ P_PARAM_SSID_T prSsid; ++ UINT_16 u2ProbeDelay; ++ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ ++ ENUM_SCAN_CHANNEL eScanChannel; ++ UINT_8 ucChannelListNum; ++ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} MSG_SCN_SCAN_REQ_V2, *P_MSG_SCN_SCAN_REQ_V2; ++ ++typedef struct _MSG_SCN_SCAN_CANCEL_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsChannelExt; ++#endif ++} MSG_SCN_SCAN_CANCEL, *P_MSG_SCN_SCAN_CANCEL; ++ ++/* Outgoing Mailbox Messages */ ++typedef enum _ENUM_SCAN_STATUS_T { ++ SCAN_STATUS_DONE = 0, ++ SCAN_STATUS_CANCELLED, ++ SCAN_STATUS_FAIL, ++ SCAN_STATUS_BUSY, ++ SCAN_STATUS_NUM ++} ENUM_SCAN_STATUS, *P_ENUM_SCAN_STATUS; ++ ++typedef struct _MSG_SCN_SCAN_DONE_T { ++ MSG_HDR_T rMsgHdr; /* Must be the first member */ ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ ENUM_SCAN_STATUS eScanStatus; ++} MSG_SCN_SCAN_DONE, *P_MSG_SCN_SCAN_DONE; ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++typedef enum { ++ AGPS_PHY_A, ++ AGPS_PHY_B, ++ AGPS_PHY_G, ++} AP_PHY_TYPE; ++ ++typedef struct _AGPS_AP_INFO_T { ++ UINT_8 aucBSSID[6]; ++ INT_16 i2ApRssi; /* -127..128 */ ++ UINT_16 u2Channel; /* 0..256 */ ++ AP_PHY_TYPE ePhyType; ++} AGPS_AP_INFO_T, *P_AGPS_AP_INFO_T; ++ ++typedef struct _AGPS_AP_LIST_T { ++ UINT_8 ucNum; ++ AGPS_AP_INFO_T arApInfo[32]; ++} AGPS_AP_LIST_T, *P_AGPS_AP_LIST_T; ++#endif ++ ++typedef struct _CMD_SET_PSCAN_PARAM { ++ UINT_8 ucVersion; ++ CMD_NLO_REQ rCmdNloReq; ++ CMD_BATCH_REQ_T rCmdBatchReq; ++ CMD_GSCN_REQ_T rCmdGscnReq; ++ BOOLEAN fgNLOScnEnable; ++ BOOLEAN fgBatchScnEnable; ++ BOOLEAN fgGScnEnable; ++ UINT_32 u4BasePeriod; ++} CMD_SET_PSCAN_PARAM, *P_CMD_SET_PSCAN_PARAM; ++ ++typedef struct _CMD_SET_PSCAN_ADD_HOTLIST_BSSID { ++ UINT_8 aucMacAddr[6]; ++ UINT_8 ucFlags; ++ UINT_8 aucReserved[5]; ++} CMD_SET_PSCAN_ADD_HOTLIST_BSSID, *P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID; ++ ++typedef struct _CMD_SET_PSCAN_ADD_SWC_BSSID { ++ INT_32 i4RssiLowThreshold; ++ INT_32 i4RssiHighThreshold; ++ UINT_8 aucMacAddr[6]; ++ UINT_8 aucReserved[6]; ++} CMD_SET_PSCAN_ADD_SWC_BSSID, *P_CMD_SET_PSCAN_ADD_SWC_BSSID; ++ ++typedef struct _CMD_SET_PSCAN_MAC_ADDR { ++ UINT_8 ucVersion; ++ UINT_8 ucFlags; ++ UINT_8 aucMacAddr[6]; ++ UINT_8 aucReserved[8]; ++} CMD_SET_PSCAN_MAC_ADDR, *P_CMD_SET_PSCAN_MAC_ADDR; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in scan.c */ ++/*----------------------------------------------------------------------------*/ ++VOID scnInit(IN P_ADAPTER_T prAdapter); ++ ++VOID scnUninit(IN P_ADAPTER_T prAdapter); ++ ++/* BSS-DESC Search */ ++P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++ ++P_BSS_DESC_T ++scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); ++ ++P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]); ++ ++P_BSS_DESC_T ++scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++#endif ++ ++/* BSS-DESC Search - Alternative */ ++P_BSS_DESC_T ++scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]); ++ ++P_BSS_DESC_T ++scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, ++ IN UINT_8 aucBSSID[], ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); ++ ++/* BSS-DESC Allocation */ ++P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter); ++ ++/* BSS-DESC Removal */ ++VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy); ++ ++VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++ ++VOID ++scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/* BSS-DESC State Change */ ++VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); ++ ++#if 0 ++/* BSS-DESC Insertion */ ++P_BSS_DESC_T scanAddToInternalScanResult(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb, IN P_BSS_DESC_T prBssDesc); ++#endif ++ ++/* BSS-DESC Insertion - ALTERNATIVE */ ++P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); ++ ++VOID ++scanBuildProbeReqFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, ++ IN PUINT_8 pucDesiredSsid, IN UINT_32 u4DesiredSsidLen, IN UINT_16 u2SupportedRateSet); ++ ++WLAN_STATUS scanSendProbeReqFrames(IN P_ADAPTER_T prAdapter, IN P_SCAN_PARAM_T prScanParam); ++ ++VOID scanUpdateBssDescForSearch(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); ++ ++P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); ++ ++VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines in scan_fsm.c */ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState); ++ ++/*----------------------------------------------------------------------------*/ ++/* Command Routines */ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter); ++ ++VOID scnSendScanReq(IN P_ADAPTER_T prAdapter); ++ ++VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter); ++ ++VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* RX Event Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone); ++ ++VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg); ++ ++VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg); ++ ++VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Generation */ ++/*----------------------------------------------------------------------------*/ ++VOID ++scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Query for sparse channel */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID/IOCTL Handling */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSsidNum, ++ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval); ++ ++BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct); ++ ++BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); ++ ++BOOLEAN scnFsmGSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); ++ ++#if 0 ++ ++BOOLEAN scnFsmGSCNSetRssiSignificatn(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); ++#endif ++ ++BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId); ++ ++BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr); ++ ++#if 1 /* CFG_SUPPORT_GSCN_NONSYNC_BROADCOM */ ++BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam); ++ ++#else ++BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_REQ_T prCmdGscnParam); ++ ++#endif ++ ++BOOLEAN ++scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_NLO_REQ prCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN); ++ ++BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig); ++ ++BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd); ++ ++VOID ++scnPSCNFsm(IN P_ADAPTER_T prAdapter, ++ ENUM_PSCAN_STATE_T eNextPSCNState, ++ IN P_CMD_NLO_REQ prCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN); ++ ++#endif /* _SCAN_H */ ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter); ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h +new file mode 100644 +index 000000000000..c6c468e06c4a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h +@@ -0,0 +1,233 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/sec_fsm.h#1 ++*/ ++ ++/*! \file sec_fsm.h ++ \brief Declaration of functions and finite state machine for SECURITY Module. ++ ++ Function declaration for privacy.c and SEC_STATE for SECURITY FSM. ++*/ ++ ++/* ++** Log: sec_fsm.h ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 20 2010 wh.su ++ * NULL ++ * adding the eapol callback setting. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 03 04 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Code refine, and remove non-used code. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, and modify the security ++ * related callback function prototype. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * fixed the deauth Tx done callback parameter ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the reference function declaration ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * delete non-used code ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function prototype ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function declaration ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the security variable ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** \main\maintrunk.MT5921\14 2009-04-06 15:35:47 GMT mtk01088 ++** add the variable to set the disable AP selection for privacy check, for wps open networking. ++** \main\maintrunk.MT5921\13 2008-11-19 11:46:01 GMT mtk01088 ++** rename some variable with pre-fix to avoid the misunderstanding ++** \main\maintrunk.MT5921\12 2008-08-28 20:37:11 GMT mtk01088 ++** remove non-used code ++** ++** \main\maintrunk.MT5921\11 2008-03-18 09:51:52 GMT mtk01088 ++** Add function declaration for timer to indicate pmkid candidate ++** \main\maintrunk.MT5921\10 2008-02-29 15:12:08 GMT mtk01088 ++** add variable for sw port control ++** \main\maintrunk.MT5921\9 2008-02-29 12:37:30 GMT mtk01088 ++** rename the security related function declaration ++** \main\maintrunk.MT5921\8 2007-12-27 13:59:08 GMT mtk01088 ++** adjust the wlan table and sec fsm init timing ++** \main\maintrunk.MT5921\7 2007-11-20 10:39:49 GMT mtk01088 ++** add function timer for wait EAPoL Error timeout ++** \main\maintrunk.MT5921\6 2007-11-06 20:39:08 GMT mtk01088 ++** rename the counter measure timer ++** \main\maintrunk.MT5921\5 2007-11-06 20:14:31 GMT mtk01088 ++** add a abort function ++** Revision 1.5 2007/07/16 02:33:42 MTK01088 ++** change the ENUM declaration structure prefix from r to e ++** ++** Revision 1.4 2007/07/09 06:23:10 MTK01088 ++** update ++** ++** Revision 1.3 2007/07/04 10:09:04 MTK01088 ++** adjust the state for security fsm ++** change function name ++** ++** Revision 1.2 2007/07/03 08:13:22 MTK01088 ++** change the sec fsm state ++** add the event for sec fsm ++** ++** Revision 1.1 2007/06/27 06:20:35 MTK01088 ++** add the sec fsm header file ++** ++** ++*/ ++#ifndef _SEC_FSM_H ++#define _SEC_FSM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* TKIP CounterMeasure interval for Rejoin to Network. */ ++#define COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC 60 ++ ++/* Timeout to wait the EAPoL Error Report frame Send out. */ ++#define EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC 1 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef UINT_32 SEC_STATUS, *P_SEC_STATUS; ++ ++#if 0 ++/* WPA2 PMKID candicate structure */ ++typedef struct _PMKID_CANDICATE_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; /* MAC address */ ++ UINT_32 u4PreAuthFlags; ++} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; ++#endif ++ ++typedef SEC_STATUS(*PFN_SEC_FSM_STATE_HANDLER) (VOID); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define SEC_STATE_TRANSITION_FLAG fgIsTransition ++#define SEC_NEXT_STATE_VAR eNextState ++ ++#define SEC_STATE_TRANSITION(prAdapter, prSta, eFromState, eToState) \ ++ { secFsmTrans_ ## eFromState ## _to_ ## eToState(prAdapter, prSta); \ ++ SEC_NEXT_STATE_VAR = SEC_STATE_ ## eToState; \ ++ SEC_STATE_TRANSITION_FLAG = (BOOLEAN)TRUE; \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*--------------------------------------------------------------*/ ++/* Routines to handle the sec check */ ++/*--------------------------------------------------------------*/ ++/***** Routines in sec_fsm.c *****/ ++VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID ++secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); ++ ++VOID ++secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); ++ ++VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _SEC_FSM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h +new file mode 100644 +index 000000000000..1c0f9a76e119 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h +@@ -0,0 +1,368 @@ ++/* ++** Id: stats.h#1 ++*/ ++ ++/*! \file stats.h ++ \brief This file includes statistics support. ++*/ ++ ++/* ++** Log: stats.h ++ * ++ * 07 17 2014 samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++extern UINT_64 u8DrvOwnStart, u8DrvOwnEnd; ++extern UINT32 u4DrvOwnMax; ++extern BOOLEAN fgIsUnderSuspend; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* Command to TDLS core module */ ++typedef enum _STATS_CMD_CORE_ID { ++ STATS_CORE_CMD_ENV_REQUEST = 0x00 ++} STATS_CMD_CORE_ID; ++ ++typedef enum _STATS_EVENT_HOST_ID { ++ STATS_HOST_EVENT_ENV_REPORT = 0x00, ++ STATS_HOST_EVENT_RX_DROP ++} STATS_EVENT_HOST_ID; ++ ++#define CFG_ARP BIT(0) ++#define CFG_DNS BIT(1) ++#define CFG_TCP BIT(2) ++#define CFG_UDP BIT(3) ++#define CFG_EAPOL BIT(4) ++#define CFG_DHCP BIT(5) ++#define CFG_ICMP BIT(6) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _STATS_CMD_CORE_T { ++ ++ UINT32 u4Command; /* STATS_CMD_CORE_ID */ ++ ++ UINT8 ucStaRecIdx; ++ UINT8 ucReserved[3]; ++ ++ UINT32 u4Reserved[4]; ++ ++#define STATS_CMD_CORE_RESERVED_SIZE 50 ++ union { ++ UINT8 Reserved[STATS_CMD_CORE_RESERVED_SIZE]; ++ } Content; ++ ++} STATS_CMD_CORE_T; ++ ++typedef struct _STATS_INFO_ENV_T { ++ ++ BOOLEAN fgIsUsed; /* TRUE: used */ ++ ++ /* ------------------- TX ------------------- */ ++ BOOLEAN fgTxIsRtsUsed; /* TRUE: we use RTS/CTS currently */ ++ BOOLEAN fgTxIsRtsEverUsed; /* TRUE: we ever use RTS/CTS */ ++ BOOLEAN fgTxIsCtsSelfUsed; /* TRUE: we use CTS-self */ ++ ++#define STATS_INFO_TX_PARAM_HW_BW40_OFFSET 0 ++#define STATS_INFO_TX_PARAM_HW_SHORT_GI20_OFFSET 1 ++#define STATS_INFO_TX_PARAM_HW_SHORT_GI40_OFFSET 2 ++#define STATS_INFO_TX_PARAM_USE_BW40_OFFSET 3 ++#define STATS_INFO_TX_PARAM_USE_SHORT_GI_OFFSET 4 ++#define STATS_INFO_TX_PARAM_NO_ACK_OFFSET 5 ++ UINT_8 ucTxParam; ++ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucReserved1[2]; ++ ++ UINT32 u4TxDataCntAll; /* total tx count from host */ ++ UINT32 u4TxDataCntOK; /* total tx ok count to air */ ++ UINT32 u4TxDataCntErr; /* total tx err count to air */ ++ ++ /* WLAN_STATUS_BUFFER_RETAINED ~ WLAN_STATUS_PACKET_LIFETIME_ERROR */ ++ UINT32 u4TxDataCntErrType[6]; /* total tx err count for different type to air */ ++ ++ UINT_8 ucTxRate1NonHTMax; ++ UINT_8 ucTxRate1HTMax; ++ UINT32 u4TxRateCntNonHT[16]; /* tx done rate */ ++ UINT32 u4TxRateCntHT[16]; /* tx done rate */ ++ ++ UINT_8 ucTxAggBitmap; /* TX BA sessions TID0 ~ TID7 */ ++ UINT_8 ucTxPeerAggMaxSize; ++ ++ /* ------------------- RX ------------------- */ ++ BOOLEAN fgRxIsRtsUsed; /* TRUE: peer uses RTS/CTS currently */ ++ BOOLEAN fgRxIsRtsEverUsed; /* TRUE: peer ever uses RTS/CTS */ ++ ++ UINT_8 ucRcvRcpi; ++ UINT_8 ucHwChanNum; ++ BOOLEAN fgRxIsShortGI; ++ UINT_8 ucReserved2[1]; ++ ++ UINT32 u4RxDataCntAll; /* total rx count from peer */ ++ UINT32 u4RxDataCntErr; /* total rx err count */ ++ UINT32 u4RxRateCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ ++ ++ UINT_8 ucRxAggBitmap; /* RX BA sessions TID0 ~ TID7 */ ++ UINT_8 ucRxAggMaxSize; ++ ++#define STATS_INFO_PHY_MODE_CCK 0 ++#define STATS_INFO_PHY_MODE_OFDM 1 ++#define STATS_INFO_PHY_MODE_HT 2 ++#define STATS_INFO_PHY_MODE_VHT 3 ++ UINT_8 ucBssSupPhyMode; /* CCK, OFDM, HT, or VHT BSS */ ++ ++ UINT_8 ucVersion; /* the version of statistics info environment */ ++ ++ /* ------------------- Delay ------------------- */ ++#define STATS_AIR_DELAY_INT 500 /* 500 byte */ ++ ++ /* delay in firmware from host to MAC */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxH2M[3], u4StayIntMinH2M[3], u4StayIntAvgH2M[3]; ++ ++ /* delay in firmware from MAC to TX done */ ++ /* unit: 32us, for 500B, 1000B, max */ ++ UINT32 u4AirDelayMax[3], u4AirDelayMin[3], u4AirDelayAvg[3]; ++ ++ /* delay in firmware from host to TX done */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMax[3], u4StayIntMin[3], u4StayIntAvg[3]; ++ UINT32 u4StayIntMaxSysTime[3]; ++ ++ /* delay in firmware from driver to TX done */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxD2T[3], u4StayIntMinD2T[3], u4StayIntAvgD2T[3]; ++ ++ /* delay count in firmware from host to TX done */ ++ /* u4StayIntByConst: divide 4 fix partitions to count each delay in firmware */ ++#define STATS_STAY_INT_CONST 1 /* 1ms */ ++#define STATS_STAY_INT_CONST_2 5 ++#define STATS_STAY_INT_CONST_3 10 ++#define STATS_STAY_INT_CONST_4 15 ++#define STATS_STAY_INT_CONST_NUM 4 ++ UINT32 u4StayIntByConst[STATS_STAY_INT_CONST_NUM]; ++ ++ /* ++ u4StayIntMaxPast: past maximum delay in firmware ++ u4StayIntCnt[]: divide 4 partitions to count each delay in firmware ++ */ ++#define STATS_STAY_INT_NUM 4 ++ UINT32 u4StayIntMaxPast; ++ UINT32 u4StayIntCnt[STATS_STAY_INT_NUM + 1]; ++ ++ /* delay count in firmware from driver to HIF */ ++ /* u4StayIntD2HByConst: divide 4 fix partitions to count each delay in firmware */ ++#define STATS_STAY_INT_D2H_CONST 10 /* 10ms */ ++#define STATS_STAY_INT_D2H_CONST_2 20 ++#define STATS_STAY_INT_D2H_CONST_3 30 ++#define STATS_STAY_INT_D2H_CONST_4 40 ++#define STATS_STAY_INT_D2H_CONST_NUM 4 ++ UINT32 u4StayIntD2HByConst[STATS_STAY_INT_D2H_CONST_NUM]; ++ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; ++ ++ /* ------------------- Others ------------------- */ ++ UINT32 u4NumOfChanChange; /* total channel change count */ ++ UINT32 u4NumOfRetryCnt; /* total TX retry count */ ++ UINT32 u4RxFifoFullCnt; /* counter of the number of the packets which ++ pass RFCR but are dropped due to FIFO full. */ ++ UINT32 u4PsIntMax; /* maximum time from ps to active */ ++ UINT_8 ucNumOfPsChange; /* peer power save change count */ ++ UINT_8 ucReserved3[3]; ++ ++ UINT32 u4ReportSysTime; /* firmware system time */ ++ UINT32 u4RxDataCntOk; /* total rx count to hif */ ++ ++ /* V4 */ ++ UINT32 u4RxRateRetryCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ ++ UINT32 au4ChanIdleCnt[10]; /* past Channel idle count in unit of slot */ ++ ++ /* V5 */ ++ UINT32 u4BtContUseTime; /* the air time that BT continuous occypy */ ++ ++ /* V6 */ ++ UINT32 u4LastTxOkTime; /* last time we tx ok to the station */ ++ ++ /* V7 */ ++ UINT_8 ucBtWfCoexGrantCnt[8]; /* [0]:WF Rx Grant Cnt[1]: WF Tx Grant Cnt[2]: WF Grant with Priority1 */ ++ /* [4]:BT Rx Grant Cnt[5]: BT Tx Grant Cnt[6]: BT Grant with Priority1 */ ++ ++ /* V8 */ ++ UINT_32 u4RxMacFreeDescCnt[6]; ++ UINT_32 u4RxHifFreeDescCnt[6]; ++ ++ /* V9 */ ++#define STATS_MAX_RX_DROP_TYPE 20 ++ UINT32 u4NumOfRxDrop[STATS_MAX_RX_DROP_TYPE]; ++ ++ /* V10 */ ++ UINT_32 u4NumOfTxDone; /* number of all packets (data/man/ctrl) tx done */ ++ UINT_32 u4NumOfTxDoneFixRate; /* number of done rate = 0 */ ++ UINT_32 u4NumOfTxDoneErrRate; /* number of error done rate */ ++ UINT_32 u4NumOfNullTxDone; /* number of null tx done */ ++ UINT_32 u4NumOfQoSNullTxDone; /* number of QoS-null tx done */ ++ ++ /* V11 */ ++ /* delay in firmware from HIF RX to HIF RX Done */ ++ /* unit: us, for 500B, 1000B, max */ ++ UINT32 u4StayIntMaxHR2HRD[3], u4StayIntMinHR2HRD[3], u4StayIntAvgHR2HRD[3]; ++ ++ /* V12 */ ++ UINT32 u4AirDelayTotal; /* agg all the air delay */ ++ ++ /* V13 */ ++ UINT32 u4CurrChnlInfo; /* add current channel information */ ++ ++ UINT_8 ucReserved_rate[4]; /* the field must be the last one */ ++} STATS_INFO_ENV_T; ++ ++/******************************************************************************* ++* M A C R O D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#if (CFG_SUPPORT_STATISTICS == 1) ++ ++#define STATS_ENV_REPORT_DETECT statsEnvReportDetect ++ ++#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) \ ++{ \ ++ (__StaRec__)->u4RxReorderFallAheadCnt++; \ ++} ++ ++#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) \ ++{ \ ++ (__StaRec__)->u4RxReorderFallBehindCnt++; \ ++} ++ ++#define STATS_RX_REORDER_HOLE_INC(__StaRec__) \ ++{ \ ++ (__StaRec__)->u4RxReorderHoleCnt++; \ ++} ++ ++#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) \ ++{ \ ++ if ((__IsTimeout__) == TRUE) \ ++ (__StaRec__)->u4RxReorderHoleTimeoutCnt++; \ ++} ++ ++#define STATS_RX_ARRIVE_TIME_RECORD(__SwRfb__) \ ++{ \ ++ (__SwRfb__)->rRxTime = StatsEnvTimeGet(); \ ++} ++ ++#define STATS_RX_PASS2OS_INC StatsEnvRxDone ++ ++#define STATS_RX_PKT_INFO_DISPLAY StatsRxPktInfoDisplay ++ ++#define STATS_TX_TIME_ARRIVE(__Skb__) \ ++do { \ ++ UINT_64 __SysTime; \ ++ __SysTime = StatsEnvTimeGet(); /* us */ \ ++ GLUE_SET_PKT_XTIME(__Skb__, __SysTime); \ ++} while (FALSE) ++ ++#define STATS_TX_TIME_TO_HIF StatsEnvTxTime2Hif ++ ++#define STATS_TX_PKT_CALLBACK StatsTxPktCallBack ++#define STATS_TX_PKT_DONE_INFO_DISPLAY StatsTxPktDoneInfoDisplay ++ ++#define STATS_DRIVER_OWN_RESET() \ ++{ \ ++ u4DrvOwnMax = 0; \ ++} ++#define STATS_DRIVER_OWN_START_RECORD() \ ++{ \ ++ u8DrvOwnStart = StatsEnvTimeGet(); \ ++} ++#define STATS_DRIVER_OWN_END_RECORD() \ ++{ \ ++ u8DrvOwnEnd = StatsEnvTimeGet(); \ ++} ++#define STATS_DRIVER_OWN_STOP() \ ++do { \ ++ UINT32 __Diff; \ ++ __Diff = (UINT32)(u8DrvOwnEnd - u8DrvOwnStart); \ ++ if (__Diff > u4DrvOwnMax) \ ++ u4DrvOwnMax = __Diff; \ ++} while (FALSE) ++ ++#else ++ ++#define STATS_ENV_REPORT_DETECT(__Adapter__, __StaRecIndex__) ++ ++#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) ++#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) ++#define STATS_RX_REORDER_HOLE_INC(__StaRec__) ++#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) ++#define STATS_RX_PASS2OS_INC(__StaRec__, __SwRfb__) ++#define STATS_RX_PKT_INFO_DISPLAY(__Pkt__) ++ ++#define STATS_TX_TIME_ARRIVE(__Skb__) ++#define STATS_TX_TIME_TO_HIF(__MsduInfo__, __HwTxHeader__) ++#define STATS_TX_PKT_CALLBACK(__Pkt__, __fgIsNeedAck__) ++#define STATS_TX_PKT_DONE_INFO_DISPLAY(__Adapter__, __Event__) ++ ++#define STATS_DRIVER_OWN_RESET() ++#define STATS_DRIVER_OWN_START_RECORD() ++#define STATS_DRIVER_OWN_END_RECORD() ++#define STATS_DRIVER_OWN_STOP() ++#endif /* CFG_SUPPORT_STATISTICS */ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex); ++ ++VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb); ++ ++UINT_64 StatsEnvTimeGet(VOID); ++ ++VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader); ++ ++VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++VOID StatsRxPktInfoDisplay(UINT_8 *pPkt); ++ ++VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo); ++ ++VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf); ++ ++VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet); ++ ++UINT_16 StatsGetCfgTxDone(VOID); ++ ++/* End of stats.h */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h +new file mode 100644 +index 000000000000..50c4b558c2cd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h +@@ -0,0 +1,187 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/swcr.h#1 ++*/ ++ ++/*! \file "swcr.h" ++ \brief ++*/ ++ ++/* ++ * ++ */ ++ ++#ifndef _SWCR_H ++#define _SWCR_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "nic_cmd_event.h" ++ ++#if 0 ++extern SWCR_MAP_ENTRY_T g_arRlmArSwCrMap[]; ++#endif ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define SWCR_VAR(x) ((VOID *)&x) ++#define SWCR_FUNC(x) ((VOID *)x) ++ ++#define SWCR_T_FUNC BIT(7) ++ ++#define SWCR_L_32 3 ++#define SWCR_L_16 2 ++#define SWCR_L_8 1 ++ ++#define SWCR_READ 0 ++#define SWCR_WRITE 1 ++ ++#define SWCR_MAP_NUM(x) (sizeof(x)/sizeof(x[0])) ++ ++#define SWCR_CR_NUM 7 ++ ++#define SWCR_GET_RW_INDEX(action, rw, index) \ ++do { \ ++ index = action & 0x7F; \ ++ rw = action >> 7; \ ++} while (0) ++ ++extern UINT_32 g_au4SwCr[]; /*: 0: command other: data */ ++ ++typedef VOID(*PFN_SWCR_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); ++typedef VOID(*PFN_CMD_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++ ++typedef struct _SWCR_MAP_ENTRY_T { ++ UINT_16 u2Type; ++ PVOID u4Addr; ++} SWCR_MAP_ENTRY_T, *P_SWCR_MAP_ENTRY_T; ++ ++typedef struct _SWCR_MOD_MAP_ENTRY_T { ++ UINT_8 ucMapNum; ++ P_SWCR_MAP_ENTRY_T prSwCrMap; ++} SWCR_MOD_MAP_ENTRY_T, *P_SWCR_MOD_MAP_ENTRY_T; ++ ++typedef enum _ENUM_SWCR_DBG_TYPE_T { ++ SWCR_DBG_TYPE_ALL = 0, ++ SWCR_DBG_TYPE_TXRX, ++ SWCR_DBG_TYPE_RX_RATES, ++ SWCR_DBG_TYPE_PS, ++ SWCR_DBG_TYPE_NUM ++} ENUM_SWCR_DBG_TYPE_T; ++ ++typedef enum _ENUM_SWCR_DBG_ALL_T { ++ SWCR_DBG_ALL_TX_CNT = 0, ++ SWCR_DBG_ALL_TX_BCN_CNT, ++ SWCR_DBG_ALL_TX_FAILED_CNT, ++ SWCR_DBG_ALL_TX_RETRY_CNT, ++ SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT, ++ SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT, ++ SWCR_DBG_ALL_TX_MGNT_DROP_CNT, ++ SWCR_DBG_ALL_TX_ERROR_CNT, ++ ++ SWCR_DBG_ALL_RX_CNT, ++ SWCR_DBG_ALL_RX_DROP_CNT, ++ SWCR_DBG_ALL_RX_DUP_DROP_CNT, ++ SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT, ++ ++ SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT, ++ SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT, ++ ++ SWCR_DBG_ALL_RX_FCSERR_CNT, ++ SWCR_DBG_ALL_RX_FIFOFULL_CNT, ++ SWCR_DBG_ALL_RX_PFDROP_CNT, ++ ++ SWCR_DBG_ALL_PWR_PS_POLL_CNT, ++ SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT, ++ SWCR_DBG_ALL_PWR_BCN_IND_CNT, ++ SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT, ++ SWCR_DBG_ALL_PWR_PM_STATE0, ++ SWCR_DBG_ALL_PWR_PM_STATE1, ++ SWCR_DBG_ALL_PWR_CUR_PS_PROF0, ++ SWCR_DBG_ALL_PWR_CUR_PS_PROF1, ++ ++ SWCR_DBG_ALL_AR_STA0_RATE, ++ SWCR_DBG_ALL_AR_STA0_BWGI, ++ SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI, ++ ++ SWCR_DBG_ALL_ROAMING_ENABLE, ++ SWCR_DBG_ALL_ROAMING_ROAM_CNT, ++ SWCR_DBG_ALL_ROAMING_INT_CNT, ++ ++ SWCR_DBG_ALL_BB_RX_MDRDY_CNT, ++ SWCR_DBG_ALL_BB_RX_FCSERR_CNT, ++ SWCR_DBG_ALL_BB_CCK_PD_CNT, ++ SWCR_DBG_ALL_BB_OFDM_PD_CNT, ++ SWCR_DBG_ALL_BB_CCK_SFDERR_CNT, ++ SWCR_DBG_ALL_BB_CCK_SIGERR_CNT, ++ SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT, ++ SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT, ++ ++ SWCR_DBG_ALL_NUM ++} ENUM_SWCR_DBG_ALL_T; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++void testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); ++VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); ++ ++/* Support Debug */ ++VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl); ++VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); ++ ++/* Debug Support */ ++VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType); ++VOID swCrDebugInit(P_ADAPTER_T prAdapter); ++VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout); ++VOID swCrDebugUninit(P_ADAPTER_T prAdapter); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h +new file mode 100644 +index 000000000000..3b6991131d05 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h +@@ -0,0 +1,262 @@ ++/* ++** Id: include/tdls.h#1 ++*/ ++ ++/*! \file "tdls.h" ++ \brief This file contains the internal used in TDLS modules ++ for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: tdls.h ++ * ++ * 11 18 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ * ++ ** ++ */ ++ ++#ifndef _TDLS_H ++#define _TDLS_H ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define TDLS_CFG_CMD_TEST 1 ++#define TDLS_CFG_HT_SUP 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); ++extern BOOLEAN flgTdlsTestExtCapElm; ++extern UINT8 aucTdlsTestExtCapElm[]; ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++typedef struct _TDLS_LINK_HIS_OTHERS_T { ++ BOOLEAN fgIsHt; /* TRUE: HT device */ ++ ++} TDLS_LINK_HIS_OTHERS_T; ++ ++/* command */ ++typedef enum _TDLS_CMD_ID { ++ TDLS_CMD_TEST_TX_FRAME = 0x00, ++ TDLS_CMD_TEST_RCV_FRAME = 0x01, ++ TDLS_CMD_TEST_PEER_ADD = 0x02, ++ TDLS_CMD_TEST_PEER_UPDATE = 0x03, ++ TDLS_CMD_TEST_DATA_FRAME = 0x04, ++ TDLS_CMD_TEST_RCV_NULL = 0x05, ++ TDLS_CMD_MIB_UPDATE = 0x06, ++ TDLS_CMD_TEST_SKIP_TX_FAIL = 0x07, ++ TDLS_CMD_UAPSD_CONF = 0x08, ++ TDLS_CMD_CH_SW_CONF = 0x09, ++ TDLS_CMD_TEST_SKIP_KEEP_ALIVE = 0x0a, ++ TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT = 0x0b, ++ TDLS_CMD_TEST_TX_TDLS_FRAME = 0x0c, ++ TDLS_CMD_TEST_PROHIBIT_SET_IN_AP = 0x0d, ++ TDLS_CMD_TEST_SCAN_DISABLE = 0x0e, ++ TDLS_CMD_TEST_DATA_FRAME_CONT = 0x0f, ++ TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP = 0x10, ++ TDLS_CMD_SETUP_CONF = 0x11, ++ TDLS_CMD_INFO = 0x12, ++ TDLS_CMD_TEST_DELAY = 0x13, ++ TDLS_CMD_KEY_INFO = 0x14, ++ TDLS_CMD_TEST_PTI_TX_FAIL = 0x15 ++} TDLS_CMD_ID; ++ ++typedef enum _TDLS_EVENT_HOST_ID { ++ TDLS_HOST_EVENT_TEAR_DOWN = 0x00, /* TDLS_EVENT_HOST_SUBID_TEAR_DOWN */ ++ TDLS_HOST_EVENT_TX_DONE, ++ TDLS_HOST_EVENT_FME_STATUS, /* TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME */ ++ TDLS_HOST_EVENT_STATISTICS ++} TDLS_EVENT_HOST_ID; ++ ++typedef enum _TDLS_EVENT_HOST_SUBID_TEAR_DOWN { ++ TDLS_HOST_EVENT_TD_PTI_TIMEOUT = 0x00, ++ TDLS_HOST_EVENT_TD_AGE_TIMEOUT, ++ TDLS_HOST_EVENT_TD_PTI_SEND_FAIL, ++ TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL, ++ TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX, ++ TDLS_HOST_EVENT_TD_NON_STATE3, ++ TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN ++} TDLS_EVENT_HOST_SUBID_TEAR_DOWN; ++ ++typedef enum _TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME { ++ TDLS_HOST_EVENT_SF_BA, ++ TDLS_HOST_EVENT_SF_BA_OK, ++ TDLS_HOST_EVENT_SF_BA_DECLINE, ++ TDLS_HOST_EVENT_SF_BA_PEER, ++ TDLS_HOST_EVENT_SF_BA_RSP_OK, ++ TDLS_HOST_EVENT_SF_BA_RSP_DECLINE ++} TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME; ++ ++/* payload specific type in the LLC/SNAP header */ ++#define TDLS_FRM_PAYLOAD_TYPE 2 ++ ++#define TDLS_FRM_CATEGORY 12 ++ ++typedef enum _TDLS_FRM_ACTION_ID { ++ TDLS_FRM_ACTION_SETUP_REQ = 0x00, ++ TDLS_FRM_ACTION_SETUP_RSP, ++ TDLS_FRM_ACTION_CONFIRM, ++ TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_FRM_ACTION_PTI, ++ TDLS_FRM_ACTION_CHAN_SWITCH_REQ, ++ TDLS_FRM_ACTION_CHAN_SWITCH_RSP, ++ TDLS_FRM_ACTION_PEER_PSM_REQ, ++ TDLS_FRM_ACTION_PEER_PSM_RSP, ++ TDLS_FRM_ACTION_PTI_RSP, /* 0x09 */ ++ TDLS_FRM_ACTION_DISCOVERY_REQ, ++ ++ TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT = 0x30, ++ ++ TDLS_FRM_DATA_TEST_DATA = 0x80 ++} TDLS_FRM_ACTION_ID; ++ ++#define TDLS_FRM_ACTION_DISCOVERY_RESPONSE 14 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* 7.3.2.62 Link Identifier element */ ++#define ELEM_ID_LINK_IDENTIFIER 101 ++#define ELEM_LEN_LINK_IDENTIFIER 18 ++ ++typedef struct _IE_LINK_IDENTIFIER_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aBSSID[6]; ++ UINT_8 aInitiator[6]; ++ UINT_8 aResponder[6]; ++} __KAL_ATTRIB_PACKED__ IE_LINK_IDENTIFIER_T; ++ ++#define TDLS_LINK_IDENTIFIER_IE(__ie__) ((IE_LINK_IDENTIFIER_T *)(__ie__)) ++ ++/* test command use */ ++typedef struct _PARAM_CUSTOM_TDLS_CMD_STRUCT_T { ++ ++ UINT_8 ucFmeType; /* TDLS_FRM_ACTION_ID */ ++ ++ UINT_8 ucToken; ++ UINT_16 u2Cap; ++ ++ /* bit0: TDLS, bit1: Peer U-APSD Buffer, bit2: Channel Switching */ ++#define TDLS_EX_CAP_PEER_UAPSD BIT(0) ++#define TDLS_EX_CAP_CHAN_SWITCH BIT(1) ++#define TDLS_EX_CAP_TDLS BIT(2) ++ UINT_8 ucExCap; ++ ++ UINT_8 arSupRate[4]; ++ UINT_8 arSupChan[4]; ++ ++ UINT_32 u4Timeout; ++ ++#define TDLS_FME_MAC_ADDR_LEN 6 ++ UINT_8 arRspAddr[TDLS_FME_MAC_ADDR_LEN]; ++ UINT_8 arBssid[TDLS_FME_MAC_ADDR_LEN]; ++ ++/* ++ Linux Kernel-3.10 ++ struct station_parameters { ++ const u8 *supported_rates; ++ struct net_device *vlan; ++ u32 sta_flags_mask, sta_flags_set; ++ u32 sta_modify_mask; ++ int listen_interval; ++ u16 aid; ++ u8 supported_rates_len; ++ u8 plink_action; ++ u8 plink_state; ++ const struct ieee80211_ht_cap *ht_capa; ++ const struct ieee80211_vht_cap *vht_capa; ++ u8 uapsd_queues; ++ u8 max_sp; ++ enum nl80211_mesh_power_mode local_pm; ++ u16 capability; ++ const u8 *ext_capab; ++ u8 ext_capab_len; ++ }; ++*/ ++ struct ieee80211_ht_cap rHtCapa; ++ struct ieee80211_vht_cap rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ ++ struct station_parameters rPeerInfo; ++ ++} PARAM_CUSTOM_TDLS_CMD_STRUCT_T; ++ ++typedef struct _TDLS_MGMT_TX_INFO { ++ UINT8 aucPeer[6]; ++ UINT8 ucActionCode; ++ UINT8 ucDialogToken; ++ UINT16 u2StatusCode; ++ UINT32 u4SecBufLen; ++ UINT8 aucSecBuf[1000]; ++} TDLS_MGMT_TX_INFO; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* check any TDLS link */ ++#define TDLS_IS_NO_LINK_GOING(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt == 0) ++ ++/* increase TDLS link count */ ++#define TDLS_LINK_INCREASE(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt++) ++ ++/* decrease TDLS link count */ ++#define TDLS_LINK_DECREASE(__GlueInfo__) \ ++do { \ ++ if ((__GlueInfo__)->rTdlsLink.cLinkCnt > 0) \ ++ (__GlueInfo__)->rTdlsLink.cLinkCnt--; \ ++} while (0) ++ ++/* get TDLS link count */ ++#define TDLS_LINK_COUNT(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt) ++ ++/* reset TDLS link count */ ++#define TDLS_LINK_COUNT_RESET(__GlueInfo__) \ ++ ((__GlueInfo__)->rTdlsLink.cLinkCnt = 0) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* Note: these functions are used only in tdls module, not other modules */ ++UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt); ++ ++TDLS_STATUS ++TdlsDataFrameSend(ADAPTER_T *prAdapter, ++ STA_RECORD_T *prStaRec, ++ UINT_8 *pPeerMac, ++ UINT_8 ucActionCode, ++ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#endif /* _TDLS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h +new file mode 100644 +index 000000000000..12c9359f2e8f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h +@@ -0,0 +1,104 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wapi.h#1 ++*/ ++ ++/*! \file wapi.h ++ \brief The wapi related define, macro and structure are described here. ++*/ ++ ++/* ++** Log: wapi.h ++ * ++ * 07 20 2010 wh.su ++ * ++ * . ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the wapi function name and adding the generate wapi ie function ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some wapi structure define ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** \main\maintrunk.MT5921\1 2009-10-09 17:06:29 GMT mtk01088 ++** ++*/ ++ ++#ifndef _WAPI_H ++#define _WAPI_H ++ ++#if CFG_SUPPORT_WAPI ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define WAPI_CIPHER_SUITE_WPI 0x01721400 /* WPI_SMS4 */ ++#define WAPI_AKM_SUITE_802_1X 0x01721400 /* WAI */ ++#define WAPI_AKM_SUITE_PSK 0x02721400 /* WAI_PSK */ ++ ++#define ELEM_ID_WAPI 68 /* WAPI IE */ ++ ++#define WAPI_IE(fp) ((P_WAPI_INFO_ELEM_T) fp) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo); ++ ++BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); ++ ++/* BOOLEAN */ ++/* wapiUpdateTxKeyIdx ( */ ++/* IN P_STA_RECORD_T prStaRec, */ ++/* IN UINT_8 ucWlanIdx */ ++/* ); */ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif ++#endif /* _WAPI_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h +new file mode 100644 +index 000000000000..5dc969f1cc05 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h +@@ -0,0 +1,87 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wlan_typedef.h#1 ++*/ ++ ++/*! \file wlan_typedef.h ++ \brief Declaration of data type and return values of internal protocol stack. ++ ++ In this file we declare the data type and return values which will be exported ++ to all MGMT Protocol Stack. ++*/ ++ ++/* ++** Log: wlan_typedef.h ++*/ ++ ++#ifndef _WLAN_TYPEDEF_H ++#define _WLAN_TYPEDEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Type definition for BSS_INFO_T structure, to describe the attributes used in a ++ * common BSS. ++ */ ++typedef struct _BSS_INFO_T BSS_INFO_T, *P_BSS_INFO_T; ++ ++typedef BSS_INFO_T AIS_BSS_INFO_T, *P_AIS_BSS_INFO_T; ++typedef BSS_INFO_T P2P_BSS_INFO_T, *P_P2P_BSS_INFO_T; ++typedef BSS_INFO_T BOW_BSS_INFO_T, *P_BOW_BSS_INFO_T; ++ ++typedef struct _AIS_SPECIFIC_BSS_INFO_T AIS_SPECIFIC_BSS_INFO_T, *P_AIS_SPECIFIC_BSS_INFO_T; ++typedef struct _P2P_SPECIFIC_BSS_INFO_T P2P_SPECIFIC_BSS_INFO_T, *P_P2P_SPECIFIC_BSS_INFO_T; ++typedef struct _BOW_SPECIFIC_BSS_INFO_T BOW_SPECIFIC_BSS_INFO_T, *P_BOW_SPECIFIC_BSS_INFO_T; ++/* CFG_SUPPORT_WFD */ ++typedef struct _WFD_CFG_SETTINGS_T WFD_CFG_SETTINGS_T, *P_WFD_CFG_SETTINGS_T; ++ ++typedef struct _WFD_DBG_CFG_SETTINGS_T WFD_DBG_CFG_SETTINGS_T, *P_WFD_DBG_CFG_SETTINGS_T; ++ ++/* BSS related structures */ ++/* Type definition for BSS_DESC_T structure, to describe parameter sets of a particular BSS */ ++typedef struct _BSS_DESC_T BSS_DESC_T, *P_BSS_DESC_T, **PP_BSS_DESC_T; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++typedef struct _HS20_INFO_T HS20_INFO_T, *P_HS20_INFO_T; ++#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _WLAN_TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h +new file mode 100644 +index 000000000000..09bc0b5d5151 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h +@@ -0,0 +1,95 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/mgmt/wnm.h#1 ++*/ ++ ++/*! \file wnm.h ++ \brief This file contains the IEEE 802.11 family related 802.11v network management ++ for MediaTek 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wnm.h ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * ++*/ ++ ++#ifndef _WNM_H ++#define _WNM_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _TIMINGMSMT_PARAM_T { ++ BOOLEAN fgInitiator; ++ UINT_8 ucTrigger; ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ ++ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ ++ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ ++} TIMINGMSMT_PARAM_T, *P_TIMINGMSMT_PARAM_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++WLAN_STATUS ++wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++VOID ++wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); ++ ++VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA); ++ ++#define WNM_UNIT_TEST 1 ++ ++#if WNM_UNIT_TEST ++VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WNM_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h +new file mode 100644 +index 000000000000..d34f2c9c36a8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h +@@ -0,0 +1,1506 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/adapter.h#3 ++*/ ++ ++/*! \file adapter.h ++ \brief Definition of internal data structure for driver manipulation. ++ ++ In this file we define the internal data structure - ADAPTER_T which stands ++ for MiniPort ADAPTER(From Windows point of view) or stands for Network ADAPTER. ++*/ ++ ++/* ++** Log: adapter.h ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have ++** connected to AP previously,one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration ++ * with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration ++ * corresponding to network type. ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Resolve inorder issue under AP mode. ++ * ++ * data frame may TX before assoc response frame. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 10 21 2011 eddie.chen ++ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout ++ * Add switch to ignore the STA aging timeout. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Remove ERP member in adapter structure ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * Action frame callback for GO Device Discoverability Req. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support for WiFi Direct Network. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically ++ * continuous memory shortage after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce ++ * physically continuous memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 10 2011 yuche.tsai ++ * [WCXRP00000533] [Volunteer Patch][MT6620][Driver] Provide a P2P function API for Legacy WiFi to query AP mode. ++ * Provide an API for Legacy WiFi to query the operation mode.. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * Add code to send beacon and probe response WSC IE at Auto GO. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as ++ * initial RSSI right after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid ++ * using a uninitialized MAC-RX RCPI. ++ * ++ * 02 21 2011 terry.wu ++ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P ++ * Clean P2P scan list while removing P2P. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 16 2011 cm.chang ++ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism ++ * . ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add RX deauthentication & disassociation process under Hot-Spot mode. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module ++ * with structure miss-align pointer issue ++ * always pre-allio WAPI related structure for align p2p module. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to ++ * target station for AAA module. ++ * Provide disconnect function for AAA module. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting ++ * Support CTIA power mode setting. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Support current measure mode, assigned by registry (XP only). ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add WMM parameter for broadcast. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add CWMin CWMax for AP to generate IE. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a common IE buffer in P2P INFO structure. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * restore configuration as before. ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add an intend mode for BSS info. ++ * It is used to let P2P BSS Info to know which OP Mode it is going to become. ++ * ++ * 08 04 2010 george.huang ++ * NULL ++ * handle change PS mode OID/ CMD ++ * ++ * 08 02 2010 cp.wu ++ * NULL ++ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Remove BSS info which is redonedent in Wifi Var.. ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P FSM Info in adapter. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P related field, additional include p2p_fsm.h if p2p is enabled. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change OID behavior to meet WHQL requirement. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement Wakeup-on-LAN except firmware integration part ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * reserve field of privacy filter and RTS threshold setting. ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * are done in adapter layer. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * * * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move ucCmdSeqNum as instance variable ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * 4. correct some HAL implementation ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * and result is retrieved by get ATInfo instead ++ * * * 2) add 4 counter for recording aggregation statistics ++ * ++ * 12 28 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate redundant variables for connection_state ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-16 18:02:03 GMT mtk02752 ++** add external reference to avoid compilation error ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:40:26 GMT mtk02752 ++** eliminate unused member ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-08 17:36:08 GMT mtk02752 ++** add RF test data members into P_ADAPTER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:45 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-28 10:29:57 GMT mtk01461 ++** Add read WTSR for SDIO_STATUS_ENHANCE mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:37:35 GMT mtk01461 ++** Add prPendingCmdInfoOfOID for temporarily saving the CMD_INFO_T before en-queue to rCmdQueue ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:57:51 GMT mtk01461 ++** Add MGMT Buffer Info ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:34:12 GMT mtk01461 ++** Add SW pre test CFG_HIF_LOOPBACK_PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:41:48 GMT mtk01461 ++** Add fgIsWmmAssoc flag for TC assignment ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:51 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:51:52 GMT mtk01426 ++** Add #if CFG_SDIO_RX_ENHANCE related data structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:17 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _ADAPTER_H ++#define _ADAPTER_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++#include "hs20.h" ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _ENHANCE_MODE_DATA_STRUCT_T SDIO_CTRL_T, *P_SDIO_CTRL_T; ++ ++typedef struct _WLAN_INFO_T { ++ PARAM_BSSID_EX_T rCurrBssId; ++ ++ /* Scan Result */ ++ PARAM_BSSID_EX_T arScanResult[CFG_MAX_NUM_BSS_LIST]; ++ PUINT_8 apucScanResultIEs[CFG_MAX_NUM_BSS_LIST]; ++ UINT_32 u4ScanResultNum; ++ ++ /* IE pool for Scanning Result */ ++ UINT_8 aucScanIEBuf[CFG_MAX_COMMON_IE_BUF_LEN]; ++ UINT_32 u4ScanIEBufferUsage; ++ ++ OS_SYSTIME u4SysTime; ++ ++ /* connection parameter (for Ad-Hoc) */ ++ UINT_16 u2BeaconPeriod; ++ UINT_16 u2AtimWindow; ++ ++ PARAM_RATES eDesiredRates; ++ CMD_LINK_ATTRIB eLinkAttr; ++/* CMD_PS_PROFILE_T ePowerSaveMode; */ ++ CMD_PS_PROFILE_T arPowerSaveMode[NETWORK_TYPE_INDEX_NUM]; ++ ++ /* trigger parameter */ ++ ENUM_RSSI_TRIGGER_TYPE eRssiTriggerType; ++ PARAM_RSSI rRssiTriggerValue; ++ ++ /* Privacy Filter */ ++ ENUM_PARAM_PRIVACY_FILTER_T ePrivacyFilter; ++ ++ /* RTS Threshold */ ++ PARAM_RTS_THRESHOLD eRtsThreshold; ++ ++ /* Network Type */ ++ UINT_8 ucNetworkType; ++ ++ /* Network Type In Use */ ++ UINT_8 ucNetworkTypeInUse; ++ ++} WLAN_INFO_T, *P_WLAN_INFO_T; ++ ++/* Session for CONNECTION SETTINGS */ ++typedef struct _CONNECTION_SETTINGS_T { ++ ++ UINT_8 aucMacAddress[MAC_ADDR_LEN]; ++ ++ UINT_8 ucDelayTimeOfDisconnectEvent; ++ ++ BOOLEAN fgIsConnByBssidIssued; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ ++ BOOLEAN fgIsConnReqIssued; ++ BOOLEAN fgIsDisconnectedByNonRequest; ++ ++ UINT_8 ucSSIDLen; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ ++ ENUM_PARAM_OP_MODE_T eOPMode; ++ ++ ENUM_PARAM_CONNECTION_POLICY_T eConnectionPolicy; ++ ++ ENUM_PARAM_AD_HOC_MODE_T eAdHocMode; ++ ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ++ BOOLEAN fgIsScanReqIssued; ++ ++ /* MIB attributes */ ++ UINT_16 u2BeaconPeriod; ++ ++ UINT_16 u2RTSThreshold; /* User desired setting */ ++ ++ UINT_16 u2DesiredNonHTRateSet; /* User desired setting */ ++ ++ UINT_8 ucAdHocChannelNum; /* For AdHoc */ ++ ++ ENUM_BAND_T eAdHocBand; /* For AdHoc */ ++ ++ UINT_32 u4FreqInKHz; /* Center frequency */ ++ ++ /* ATIM windows using for IBSS power saving function */ ++ UINT_16 u2AtimWindow; ++ ++ /* Features */ ++ BOOLEAN fgIsEnableRoaming; ++ ++ BOOLEAN fgIsAdHocQoSEnable; ++ ++ ENUM_PARAM_PHY_CONFIG_T eDesiredPhyConfig; ++ ++ /* Used for AP mode for desired channel and bandwidth */ ++ UINT_16 u2CountryCode; ++ UINT_16 u2CountryCodeBakup; ++ UINT_8 uc2G4BandwidthMode; /* 20/40M or 20M only */ ++ UINT_8 uc5GBandwidthMode; /* 20/40M or 20M only */ ++ ++ BOOLEAN fgTxShortGIDisabled; ++ BOOLEAN fgRxShortGIDisabled; ++ ++#if CFG_SUPPORT_802_11D ++ BOOLEAN fgMultiDomainCapabilityEnabled; ++#endif /* CFG_SUPPORT_802_11D */ ++ ++#if 1 /* CFG_SUPPORT_WAPI */ ++ BOOLEAN fgWapiMode; ++ UINT_32 u4WapiSelectedGroupCipher; ++ UINT_32 u4WapiSelectedPairwiseCipher; ++ UINT_32 u4WapiSelectedAKMSuite; ++#endif ++ ++ /* CR1486, CR1640 */ ++ /* for WPS, disable the privacy check for AP selection policy */ ++ BOOLEAN fgPrivacyCheckDisable; ++ ++ /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ ++ UINT_8 bmfgApsdEnAc; ++ ++ /* for RSN info store, when upper layer set rsn info */ ++ RSN_INFO_T rRsnInfo; ++ ++} CONNECTION_SETTINGS_T, *P_CONNECTION_SETTINGS_T; ++ ++struct _BSS_INFO_T { ++ ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ ++ ENUM_PARAM_MEDIA_STATE_T eConnectionStateIndicated; /* The Media State that report to HOST */ ++ ++ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ ++#if CFG_ENABLE_WIFI_DIRECT ++ ENUM_OP_MODE_T eIntendOPMode; ++#endif ++ ++ BOOLEAN fgIsNetActive; /* TRUE if this network has been activated */ ++ ++ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ ++ ++ UINT_8 ucReasonOfDisconnect; /* Used by media state indication */ ++ ++ UINT_8 ucSSIDLen; /* Length of SSID */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ENUM_HIDDEN_SSID_TYPE_T eHiddenSsidType; /* For Hidden SSID usage. */ ++#endif ++ ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID used in this BSS */ ++ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* The BSSID of the associated BSS */ ++ ++ UINT_8 aucOwnMacAddr[MAC_ADDR_LEN]; /* Owned MAC Address used in this BSS */ ++ ++ P_STA_RECORD_T prStaRecOfAP; /* For Infra Mode, and valid only if ++ * eConnectionState == MEDIA_STATE_CONNECTED ++ */ ++ LINK_T rStaRecOfClientList; /* For IBSS/AP Mode, all known STAs in current BSS */ ++ ++ UINT_16 u2CapInfo; /* Change Detection */ ++ ++ UINT_16 u2BeaconInterval; /* The Beacon Interval of this BSS */ ++ ++ UINT_16 u2ATIMWindow; /* For IBSS Mode */ ++ ++ UINT_16 u2AssocId; /* For Infra Mode, it is the Assoc ID assigned by AP. ++ */ ++ ++ UINT_8 ucDTIMPeriod; /* For Infra/AP Mode */ ++ ++ UINT_8 ucDTIMCount; /* For AP Mode, it is the DTIM value we should carried in ++ * the Beacon of next TBTT. ++ */ ++ ++ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer ++ * (This is deduced from received BSS_DESC_T) ++ */ ++ ++ UINT_8 ucNonHTBasicPhyType; /* The Basic PHY Type Index, used to setup Phy Capability */ ++ ++ UINT_8 ucConfigAdHocAPMode; /* The configuration of AdHoc/AP Mode. e.g. 11g or 11b */ ++ ++ UINT_8 ucBeaconTimeoutCount; /* For Infra/AP Mode, it is a threshold of Beacon Lost Count to ++ confirm connection was lost */ ++ ++ BOOLEAN fgHoldSameBssidForIBSS; /* For IBSS Mode, to keep use same BSSID to extend the life cycle of an IBSS */ ++ ++ BOOLEAN fgIsBeaconActivated; /* For AP/IBSS Mode, it is used to indicate that Beacon is sending */ ++ ++ P_MSDU_INFO_T prBeacon; /* For AP/IBSS Mode - Beacon Frame */ ++ ++ BOOLEAN fgIsIBSSMaster; /* For IBSS Mode - To indicate that we can reply ProbeResp Frame. ++ In current TBTT interval */ ++ ++ BOOLEAN fgIsShortPreambleAllowed; /* From Capability Info. of AssocResp Frame ++ AND of Beacon/ProbeResp Frame */ ++ BOOLEAN fgUseShortPreamble; /* Short Preamble is enabled in current BSS. */ ++ BOOLEAN fgUseShortSlotTime; /* Short Slot Time is enabled in current BSS. */ ++ ++ UINT_16 u2OperationalRateSet; /* Operational Rate Set of current BSS */ ++ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of current BSS */ ++ ++ UINT_8 ucAllSupportedRatesLen; /* Used for composing Beacon Frame in AdHoc or AP Mode */ ++ UINT_8 aucAllSupportedRates[RATE_NUM]; ++ ++ UINT_8 ucAssocClientCnt; /* TODO(Kevin): Number of associated clients */ ++ ++ BOOLEAN fgIsProtection; ++ BOOLEAN fgIsQBSS; /* fgIsWmmBSS; *//* For Infra/AP/IBSS Mode, it is used to indicate if we support WMM in ++ * current BSS. */ ++ BOOLEAN fgIsNetAbsent; /* TRUE: BSS is absent, FALSE: BSS is present */ ++ ++ UINT_32 u4RsnSelectedGroupCipher; ++ UINT_32 u4RsnSelectedPairwiseCipher; ++ UINT_32 u4RsnSelectedAKMSuite; ++ UINT_16 u2RsnSelectedCapInfo; ++ ++ /*------------------------------------------------------------------------*/ ++ /* Power Management related information */ ++ /*------------------------------------------------------------------------*/ ++ PM_PROFILE_SETUP_INFO_T rPmProfSetupInfo; ++ ++ /*------------------------------------------------------------------------*/ ++ /* WMM/QoS related information */ ++ /*------------------------------------------------------------------------*/ ++ UINT_8 ucWmmParamSetCount; /* Used to detect the change of EDCA parameters. For AP mode, ++ the value is used in WMM IE */ ++ ++ AC_QUE_PARMS_T arACQueParms[WMM_AC_INDEX_NUM]; ++ ++ UINT_8 aucCWminLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWminLog2 */ ++ UINT_8 aucCWmaxLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWmaxLog2 */ ++ AC_QUE_PARMS_T arACQueParmsForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the value */ ++ ++ /*------------------------------------------------------------------------*/ ++ /* 802.11n HT operation IE when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) */ ++ /* is true. They have the same definition with fields of */ ++ /* information element (CM) */ ++ /*------------------------------------------------------------------------*/ ++ ENUM_BAND_T eBand; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucHtOpInfo1; ++ UINT_16 u2HtOpInfo2; ++ UINT_16 u2HtOpInfo3; ++ ++ /*------------------------------------------------------------------------*/ ++ /* Required protection modes (CM) */ ++ /*------------------------------------------------------------------------*/ ++ BOOLEAN fgErpProtectMode; ++ ENUM_HT_PROTECT_MODE_T eHtProtectMode; ++ ENUM_GF_MODE_T eGfOperationMode; ++ ENUM_RIFS_MODE_T eRifsOperationMode; ++ ++ BOOLEAN fgObssErpProtectMode; /* GO only */ ++ ENUM_HT_PROTECT_MODE_T eObssHtProtectMode; /* GO only */ ++ ENUM_GF_MODE_T eObssGfOperationMode; /* GO only */ ++ BOOLEAN fgObssRifsOperationMode; /* GO only */ ++ ++ /*------------------------------------------------------------------------*/ ++ /* OBSS to decide if 20/40M bandwidth is permitted. */ ++ /* The first member indicates the following channel list length. */ ++ /*------------------------------------------------------------------------*/ ++ BOOLEAN fgAssoc40mBwAllowed; ++ BOOLEAN fg40mBwAllowed; ++ ENUM_CHNL_EXT_T eBssSCO; /* Real setting for HW ++ * 20/40M AP mode will always set 40M, ++ * but its OP IE can be changed. ++ */ ++ UINT_8 auc2G_20mReqChnlList[CHNL_LIST_SZ_2G + 1]; ++ UINT_8 auc2G_NonHtChnlList[CHNL_LIST_SZ_2G + 1]; ++ UINT_8 auc2G_PriChnlList[CHNL_LIST_SZ_2G + 1]; ++ UINT_8 auc2G_SecChnlList[CHNL_LIST_SZ_2G + 1]; ++ ++ UINT_8 auc5G_20mReqChnlList[CHNL_LIST_SZ_5G + 1]; ++ UINT_8 auc5G_NonHtChnlList[CHNL_LIST_SZ_5G + 1]; ++ UINT_8 auc5G_PriChnlList[CHNL_LIST_SZ_5G + 1]; ++ UINT_8 auc5G_SecChnlList[CHNL_LIST_SZ_5G + 1]; ++ ++ TIMER_T rObssScanTimer; ++ UINT_16 u2ObssScanInterval; /* in unit of sec */ ++ ++ BOOLEAN fgObssActionForcedTo20M; /* GO only */ ++ BOOLEAN fgObssBeaconForcedTo20M; /* GO only */ ++ ++ /*------------------------------------------------------------------------*/ ++ /* HW Related Fields (Kevin) */ ++ /*------------------------------------------------------------------------*/ ++ UINT_8 ucHwDefaultFixedRateCode; /* The default rate code copied to MAC TX Desc */ ++ UINT_16 u2HwLPWakeupGuardTimeUsec; ++ ++ UINT_8 ucBssFreeQuota; /* The value is updated from FW */ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ P_IPV4_NETWORK_ADDRESS_LIST prIpV4NetAddrList; ++#endif ++ UINT_16 u2DeauthReason; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ ++ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ ++#endif /* CFG_SUPPORT_TDLS */ ++}; ++ ++struct _AIS_SPECIFIC_BSS_INFO_T { ++ UINT_8 ucRoamingAuthTypes; /* This value indicate the roaming type used in AIS_JOIN */ ++ ++ BOOLEAN fgIsIBSSActive; ++ ++ /*! \brief Global flag to let arbiter stay at standby and not connect to any network */ ++ BOOLEAN fgCounterMeasure; ++ UINT_8 ucWEPDefaultKeyID; ++ BOOLEAN fgTransmitKeyExist; /* Legacy wep Transmit key exist or not */ ++ ++ /* While Do CounterMeasure procedure, check the EAPoL Error report have send out */ ++ BOOLEAN fgCheckEAPoLTxDone; ++ ++ UINT_32 u4RsnaLastMICFailTime; ++ ++ /* Stored the current bss wpa rsn cap filed, used for roaming policy */ ++ /* UINT_16 u2RsnCap; */ ++ TIMER_T rPreauthenticationTimer; ++ ++ /* By the flow chart of 802.11i, ++ wait 60 sec before associating to same AP ++ or roaming to a new AP ++ or sending data in IBSS, ++ keep a timer for handle the 60 sec counterMeasure */ ++ TIMER_T rRsnaBlockTrafficTimer; ++ TIMER_T rRsnaEAPoLReportTimeoutTimer; ++ ++ /* For Keep the Tx/Rx Mic key for TKIP SW Calculate Mic */ ++ /* This is only one for AIS/AP */ ++ UINT_8 aucTxMicKey[8]; ++ UINT_8 aucRxMicKey[8]; ++ ++ /* Buffer for WPA2 PMKID */ ++ /* The PMKID cache lifetime is expire by media_disconnect_indication */ ++ UINT_32 u4PmkidCandicateCount; ++ PMKID_CANDICATE_T arPmkidCandicate[CFG_MAX_PMKID_CACHE]; ++ UINT_32 u4PmkidCacheCount; ++ PMKID_ENTRY_T arPmkidCache[CFG_MAX_PMKID_CACHE]; ++ BOOLEAN fgIndicatePMKID; ++#if CFG_SUPPORT_802_11W ++ BOOLEAN fgMgmtProtection; ++ UINT_32 u4SaQueryStart; ++ UINT_32 u4SaQueryCount; ++ UINT_8 ucSaQueryTimedOut; ++ PUINT_8 pucSaQueryTransId; ++ TIMER_T rSaQueryTimer; ++ BOOLEAN fgBipKeyInstalled; ++#endif ++}; ++ ++struct _BOW_SPECIFIC_BSS_INFO_T { ++ UINT_16 u2Reserved; /* Reserved for Data Type Check */ ++}; ++ ++#if CFG_SLT_SUPPORT ++typedef struct _SLT_INFO_T { ++ ++ P_BSS_DESC_T prPseudoBssDesc; ++ UINT_16 u2SiteID; ++ UINT_8 ucChannel2G4; ++ UINT_8 ucChannel5G; ++ BOOLEAN fgIsDUT; ++ UINT_32 u4BeaconReceiveCnt; ++ /* ///////Deprecated///////// */ ++ P_STA_RECORD_T prPseudoStaRec; ++} SLT_INFO_T, *P_SLT_INFO_T; ++#endif ++ ++/* Major member variables for WiFi FW operation. ++ Variables within this region will be ready for access after WIFI function is enabled. ++*/ ++typedef struct _WIFI_VAR_T { ++ BOOLEAN fgIsRadioOff; ++ ++ BOOLEAN fgIsEnterD3ReqIssued; ++ ++ BOOLEAN fgDebugCmdResp; ++ ++ CONNECTION_SETTINGS_T rConnSettings; ++ ++ SCAN_INFO_T rScanInfo; ++ ++#if CFG_SUPPORT_ROAMING ++ ROAMING_INFO_T rRoamingInfo; ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ AIS_FSM_INFO_T rAisFsmInfo; ++ ++ ENUM_PWR_STATE_T aePwrState[NETWORK_TYPE_INDEX_NUM]; ++ ++ BSS_INFO_T arBssInfo[NETWORK_TYPE_INDEX_NUM]; ++ ++ AIS_SPECIFIC_BSS_INFO_T rAisSpecificBssInfo; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings; ++ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo; ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ BOW_SPECIFIC_BSS_INFO_T rBowSpecificBssInfo; ++ BOW_FSM_INFO_T rBowFsmInfo; ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ DEAUTH_INFO_T arDeauthInfo[MAX_DEAUTH_INFO_COUNT]; ++ ++ /* Current Wi-Fi Settings and Flags */ ++ UINT_8 aucPermanentAddress[MAC_ADDR_LEN]; ++ UINT_8 aucMacAddress[MAC_ADDR_LEN]; ++ UINT_8 aucDeviceAddress[MAC_ADDR_LEN]; ++ UINT_8 aucInterfaceAddress[MAC_ADDR_LEN]; ++ ++ UINT_8 ucAvailablePhyTypeSet; ++ ++ ENUM_PHY_TYPE_INDEX_T eNonHTBasicPhyType2G4; /* Basic Phy Type used by SCN according ++ * to the set of Available PHY Types ++ */ ++ ++ ENUM_PARAM_PREAMBLE_TYPE_T ePreambleType; ++ ENUM_REGISTRY_FIXED_RATE_T eRateSetting; ++ ++ BOOLEAN fgIsShortSlotTimeOptionEnable; ++ /* User desired setting, but will honor the capability of AP */ ++ ++ BOOLEAN fgEnableJoinToHiddenSSID; ++ BOOLEAN fgSupportWZCDisassociation; ++ ++ BOOLEAN fgSupportQoS; ++ BOOLEAN fgSupportAmpduTx; ++ BOOLEAN fgSupportAmpduRx; ++ BOOLEAN fgSupportTspec; ++ BOOLEAN fgSupportUAPSD; ++ BOOLEAN fgSupportULPSMP; ++ UINT_8 u8SupportRxSgi20; /* 0: default 1: enable 2:disble */ ++ UINT_8 u8SupportRxSgi40; ++ UINT_8 u8SupportRxGf; ++ UINT_8 u8SupportRxSTBC; ++#if CFG_SUPPORT_CFG_FILE ++ UINT_8 ucApWpsMode; ++ UINT_8 ucCert11nMode; ++#endif ++#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT ++ UINT_8 ucCeFccTxPwrLimit; ++ UINT_8 ucCeFccTxPwrLimitCck; ++ UINT_8 ucCeFccTxPwrLimitOfdmHt20; ++ UINT_8 ucCeFccTxPwrLimitHt40; ++#endif ++ ++#if CFG_SLT_SUPPORT ++ SLT_INFO_T rSltInfo; ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ HS20_INFO_T rHS20Info; ++#endif ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ PARAM_GET_CHN_LOAD rChnLoadInfo; ++#endif ++ ++} WIFI_VAR_T, *P_WIFI_VAR_T; /* end of _WIFI_VAR_T */ ++ ++/* cnm_timer module */ ++typedef struct { ++ LINK_T rLinkHead; ++ OS_SYSTIME rNextExpiredSysTime; ++ KAL_WAKE_LOCK_T rWakeLock; ++ BOOLEAN fgWakeLocked; ++} ROOT_TIMER, *P_ROOT_TIMER; ++ ++/* FW/DRV/NVRAM version information */ ++typedef struct { ++ ++ /* NVRAM or Registry */ ++ UINT_16 u2Part1CfgOwnVersion; ++ UINT_16 u2Part1CfgPeerVersion; ++ UINT_16 u2Part2CfgOwnVersion; ++ UINT_16 u2Part2CfgPeerVersion; ++ ++ /* Firmware */ ++ UINT_16 u2FwProductID; ++ UINT_16 u2FwOwnVersion; ++ UINT_16 u2FwPeerVersion; ++ ++} WIFI_VER_INFO_T, *P_WIFI_VER_INFO_T; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/* ++* p2p function pointer structure ++*/ ++ ++typedef struct _P2P_FUNCTION_LINKER { ++ P2P_REMOVE prP2pRemove; ++/* NIC_P2P_MEDIA_STATE_CHANGE prNicP2pMediaStateChange; */ ++/* SCAN_UPDATE_P2P_DEVICE_DESC prScanUpdateP2pDeviceDesc; */ ++/* P2P_FSM_RUN_EVENT_RX_PROBE_RESPONSE_FRAME prP2pFsmRunEventRxProbeResponseFrame; */ ++ P2P_GENERATE_P2P_IE prP2pGenerateWSC_IEForBeacon; ++/* P2P_CALCULATE_WSC_IE_LEN_FOR_PROBE_RSP prP2pCalculateWSC_IELenForProbeRsp; */ ++/* P2P_GENERATE_WSC_IE_FOR_PROBE_RSP prP2pGenerateWSC_IEForProbeRsp; */ ++/* SCAN_REMOVE_P2P_BSS_DESC prScanRemoveP2pBssDesc; */ ++/* P2P_HANDLE_SEC_CHECK_RSP prP2pHandleSecCheckRsp; */ ++ P2P_NET_REGISTER prP2pNetRegister; ++ P2P_NET_UNREGISTER prP2pNetUnregister; ++ P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocReq; /* All IEs generated from supplicant. */ ++ P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocReq; /* All IEs generated from supplicant. */ ++} P2P_FUNCTION_LINKER, *P_P2P_FUNCTION_LINKER; ++ ++#endif ++ ++/* ++ *State Machine: ++ *-->STOP: Turn on/off WiFi ++ *-->DISABLE: Screen was off (wlanHandleSystemSuspend) ++ *-->ENABLE: Screen was on (wlanHandleSystemResume) ++ *----->clear DISABLE ++ *-->RUNNING: Screen was on && Tx/Rx was ongoing (wlanHardStartXmit/kalRxIndicatePkts) ++*/ ++struct GL_PER_MON_T { ++ TIMER_T rPerfMonTimer; ++ ULONG ulPerfMonFlag; ++ ULONG ulLastTxBytes; ++ ULONG ulLastRxBytes; ++ ULONG ulP2PLastTxBytes; ++ ULONG ulP2PLastRxBytes; ++ /*in bps*/ ++ ULONG ulThroughput; ++ /*in ms*/ ++ UINT32 u4UpdatePeriod; ++ UINT32 u4TarPerfLevel; ++ UINT32 u4CurrPerfLevel; ++}; ++ ++/* ++ * Major ADAPTER structure ++ * Major data structure for driver operation ++ */ ++struct _ADAPTER_T { ++ UINT_8 ucRevID; ++ ++ UINT_16 u2NicOpChnlNum; ++ ++ BOOLEAN fgIsEnableWMM; ++ BOOLEAN fgIsWmmAssoc; /* This flag is used to indicate that WMM is enable in current BSS */ ++ ++ UINT_32 u4OsPacketFilter; /* packet filter used by OS */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ UINT_32 u4CSUMFlags; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ ENUM_BAND_T aePreferBand[NETWORK_TYPE_INDEX_NUM]; ++ ++ /* ADAPTER flags */ ++ UINT_32 u4Flags; ++ UINT_32 u4HwFlags; ++ ++ BOOLEAN fgIsRadioOff; ++ ++ BOOLEAN fgIsEnterD3ReqIssued; ++ ++ UINT_8 aucMacAddress[MAC_ADDR_LEN]; ++ ++ ENUM_PHY_TYPE_INDEX_T eCurrentPhyType; /* Current selection basing on the set of Available PHY Types */ ++ ++#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG ++ UINT_32 u4CoalescingBufCachedSize; ++ PUINT_8 pucCoalescingBufCached; ++#endif /* CFG_COALESCING_BUFFER_SIZE */ ++ ++ /* Buffer for CMD_INFO_T, Mgt packet and mailbox message */ ++ BUF_INFO_T rMgtBufInfo; ++ BUF_INFO_T rMsgBufInfo; ++ PUINT_8 pucMgtBufCached; ++ UINT_32 u4MgtBufCachedSize; ++ UINT_8 aucMsgBuf[MSG_BUFFER_SIZE]; ++#if CFG_DBG_MGT_BUF ++ UINT_32 u4MemAllocDynamicCount; /* Debug only */ ++ UINT_32 u4MemFreeDynamicCount; /* Debug only */ ++#endif ++ ++ STA_RECORD_T arStaRec[CFG_STA_REC_NUM]; ++ ++ /* Element for TX PATH */ ++ TX_CTRL_T rTxCtrl; ++ QUE_T rFreeCmdList; ++ CMD_INFO_T arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM]; ++ ++ /* Element for RX PATH */ ++ RX_CTRL_T rRxCtrl; ++ ++ P_SDIO_CTRL_T prSDIOCtrl; ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ /* Element for MT6620 E1 HIFSYS workaround */ ++ BOOLEAN fgIsClockGatingEnabled; ++#endif ++ ++ /* Buffer for Authentication Event */ ++ /* Move to glue layer and refine the kal function */ ++ /* Reference to rsnGeneratePmkidIndication function at rsn.c */ ++ UINT_8 aucIndicationEventBuffer[(CFG_MAX_PMKID_CACHE * 20) + 8]; ++ ++ UINT_32 u4IntStatus; ++ ++ ENUM_ACPI_STATE_T rAcpiState; ++ ++ BOOLEAN fgIsIntEnable; ++ BOOLEAN fgIsIntEnableWithLPOwnSet; ++ ++ BOOLEAN fgIsFwOwn; ++ BOOLEAN fgWiFiInSleepyState; ++ ++ UINT_32 u4PwrCtrlBlockCnt; ++ ++ QUE_T rPendingCmdQueue; ++ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ UINT_8 ucCmdSeqNum; ++ UINT_8 ucTxSeqNum; ++ ++#if 1 /* CFG_SUPPORT_WAPI */ ++ BOOLEAN fgUseWapi; ++#endif ++ ++ /* RF Test flags */ ++ BOOLEAN fgTestMode; ++ ++ /* WLAN Info for DRIVER_CORE OID query */ ++ WLAN_INFO_T rWlanInfo; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsP2PRegistered; ++ ENUM_NET_REG_STATE_T rP2PNetRegState; ++ BOOLEAN fgIsWlanLaunched; ++ P_P2P_INFO_T prP2pInfo; ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ OS_SYSTIME rP2pLinkQualityUpdateTime; ++ BOOLEAN fgIsP2pLinkQualityValid; ++ EVENT_LINK_QUALITY rP2pLinkQuality; ++#endif ++ ++ /* FSM Timer */ ++ TIMER_T rP2pFsmTimeoutTimer; ++#endif ++ ++ /* Online Scan Option */ ++ BOOLEAN fgEnOnlineScan; ++ ++ /* Online Scan Option */ ++ BOOLEAN fgDisBcnLostDetection; ++ ++ /* MAC address */ ++ PARAM_MAC_ADDRESS rMyMacAddr; ++ ++ /* Wake-up Event for WOL */ ++ UINT_32 u4WakeupEventEnable; ++ ++ /* Event Buffering */ ++ EVENT_STATISTICS rStatStruct; ++ OS_SYSTIME rStatUpdateTime; ++ BOOLEAN fgIsStatValid; ++ ++ EVENT_LINK_QUALITY rLinkQuality; ++ OS_SYSTIME rLinkQualityUpdateTime; ++ BOOLEAN fgIsLinkQualityValid; ++ OS_SYSTIME rLinkRateUpdateTime; ++ BOOLEAN fgIsLinkRateValid; ++ ++ /* WIFI_VAR_T */ ++ WIFI_VAR_T rWifiVar; ++ ++ /* MTK WLAN NIC driver IEEE 802.11 MIB */ ++ IEEE_802_11_MIB_T rMib; ++ ++ /* Mailboxs for inter-module communication */ ++ MBOX_T arMbox[MBOX_ID_TOTAL_NUM]; ++ ++ /* Timers for OID Pending Handling */ ++ TIMER_T rOidTimeoutTimer; ++ ++ TIMER_T rReturnIndicatedRfbListTimer; ++ ++ /* Root Timer for cnm_timer module */ ++ ROOT_TIMER rRootTimer; ++ ++ /* RLM maintenance */ ++ ENUM_CHNL_EXT_T eRfSco; ++ ENUM_SYS_PROTECT_MODE_T eSysProtectMode; ++ ENUM_GF_MODE_T eSysHtGfMode; ++ ENUM_RIFS_MODE_T eSysTxRifsMode; ++ ENUM_SYS_PCO_PHASE_T eSysPcoPhase; ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++ /* QM */ ++ QUE_MGT_T rQM; ++ ++ CNM_INFO_T rCnmInfo; ++ ++ UINT_32 u4PowerMode; ++ ++ UINT_32 u4CtiaPowerMode; ++ BOOLEAN fgEnCtiaPowerMode; ++ ++ UINT_32 fgEnArpFilter; ++ ++ UINT_32 u4UapsdAcBmp; ++ ++ UINT_32 u4MaxSpLen; ++ ++ UINT_32 u4PsCurrentMeasureEn; ++ ++ /* Version Information */ ++ WIFI_VER_INFO_T rVerInfo; ++ ++ /* 5GHz support (from F/W) */ ++ BOOLEAN fgIsHw5GBandDisabled; ++ BOOLEAN fgEnable5GBand; ++ BOOLEAN fgIsEepromUsed; ++ BOOLEAN fgIsEfuseValid; ++ BOOLEAN fgIsEmbbededMacAddrValid; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ BOOLEAN fgIsPowerLimitTableValid; ++#endif ++ ++ /* Packet Forwarding Tracking */ ++ INT_32 i4PendingFwdFrameCount; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ UINT_8 ucRddStatus; ++#endif ++ ++ BOOLEAN fgDisStaAgingTimeoutDetection; ++#if CFG_SUPPORT_CFG_FILE ++ P_WLAN_CFG_T prWlanCfg; ++ WLAN_CFG_T rWlanCfg; ++#endif ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ KAL_WAKE_LOCK_T rApWakeLock; ++#endif ++ UINT_32 u4FwCompileFlag0; ++ UINT_32 u4FwCompileFlag1; ++ KAL_WAKE_LOCK_T rTxThreadWakeLock; ++ KAL_WAKE_LOCK_T rAhbIsrWakeLock; ++ ++#if CFG_SUPPORT_ROAMING_ENC ++ BOOLEAN fgIsRoamingEncEnabled; ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ BOOLEAN fgTdlsIsSup; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ UINT_8 ucScanTime; ++ ++#if CFG_SUPPORT_DBG_POWERMODE ++ BOOLEAN fgEnDbgPowerMode; /* dbg privilege power mode, always keep in active */ ++#endif ++ ++ UINT_32 u4AirDelayTotal; /* dbg privilege power mode, always keep in active */ ++ ULONG ulSuspendFlag; ++ struct GL_PER_MON_T rPerMonitor; ++}; /* end of _ADAPTER_T */ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) ++#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for BSS_INFO_T - Flag of Net Active */ ++/*----------------------------------------------------------------------------*/ ++#define IS_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ (_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive) ++#define IS_BSS_ACTIVE(_prBssInfo) ((_prBssInfo)->fgIsNetActive) ++ ++#define IS_AIS_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_AIS_INDEX) ++#define IS_P2P_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_P2P_INDEX) ++#define IS_BOW_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_BOW_INDEX) ++ ++#define SET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = TRUE; } ++ ++#define UNSET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = FALSE; } ++ ++#define BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ ++ { UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; \ ++ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ ++ \ ++ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; \ ++ _prBssInfo->fgIsNetActive = FALSE; \ ++ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ ++ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ ++ COPY_MAC_ADDR(_prBssInfo->aucBSSID, _aucZeroMacAddr); \ ++ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ ++ _prBssInfo->fgIsBeaconActivated = FALSE; \ ++ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ ++ _prBssInfo->fgIsNetAbsent = FALSE; \ ++ } ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#define BOW_BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ ++ { \ ++ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ ++ \ ++ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ ++ _prBssInfo->eCurrentOPMode = OP_MODE_BOW; \ ++ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ ++ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ ++ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ ++ _prBssInfo->fgIsBeaconActivated = TRUE; \ ++ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ ++ _prBssInfo->fgIsNetAbsent = FALSE; \ ++ } ++#endif ++ ++#define PERF_MON_DISABLE_BIT_OFF (0) ++#define PERF_MON_STOP_BIT_OFF (1) ++#define PERF_MON_RUNNING_BIT_OFF (2) ++ ++#define THROUGHPUT_L1_THRESHOLD (20*1024*1024) ++#define THROUGHPUT_L2_THRESHOLD (60*1024*1024) ++#define THROUGHPUT_L3_THRESHOLD (135*1024*1024) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for Power State */ ++/*----------------------------------------------------------------------------*/ ++#define SET_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_IDLE; } ++ ++#define SET_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_ACTIVE; } ++ ++#define SET_NET_PWR_STATE_PS(_prAdapter, _NetTypeIndex) \ ++ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_PS; } ++ ++#define IS_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ ++ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_ACTIVE) ++ ++#define IS_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ ++ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_IDLE) ++ ++#define IS_SCN_PWR_STATE_ACTIVE(_prAdapter) \ ++ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_ACTIVE) ++ ++#define IS_SCN_PWR_STATE_IDLE(_prAdapter) \ ++ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_IDLE) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _ADAPTER_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h +new file mode 100644 +index 000000000000..6c4c1b76622b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h +@@ -0,0 +1,322 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/bow.h#1 ++*/ ++ ++/* ++** Log: bow.h ++ * ++ * 01 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW for 5GHz band. ++ * ++ * 05 25 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW Cancel Scan Request and Turn On deactive network function. ++ * ++ * 05 22 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Submit missing BoW header files. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW structure. ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 ++ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 ++ * with BOW and P2P enabled as default ++ * ++ * 02 08 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. ++ * Update BOW get MAC status, remove returning event for AIS network type. ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add Activity Report definition. ++ * ++ * 10 18 2010 chinghwa.yu ++ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size ++ * Fix wrong BoW event size. ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * 1) all BT physical handles shares the same RSSI/Link Quality. ++ * 2) simplify BT command composing ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * basic implementation for EVENT_BT_OVER_WIFI ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * sync. with design document for interface change. ++ * ++ * 04 02 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * Wi-Fi driver no longer needs to implement 802.11 PAL, thus replaced by wrapping command/event definitions ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * correct typo. ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * update for all command/event needed to be supported by 802.11 PAL. ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * build up basic data structure and definitions to support BT-over-WiFi ++ * ++*/ ++ ++#ifndef _BOW_H_ ++#define _BOW_H_ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define BOWDEVNAME "bow0" ++ ++#define MAX_BOW_NUMBER_OF_CHANNEL_2G4 14 ++#define MAX_BOW_NUMBER_OF_CHANNEL_5G 4 ++/* (MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) */ ++#define MAX_BOW_NUMBER_OF_CHANNEL 18 ++ ++#define MAX_ACTIVITY_REPORT 2 ++#define MAX_ACTIVITY_REPROT_TIME 660 ++ ++#define ACTIVITY_REPORT_STATUS_SUCCESS 0 ++#define ACTIVITY_REPORT_STATUS_FAILURE 1 ++#define ACTIVITY_REPORT_STATUS_TIME_INVALID 2 ++#define ACTIVITY_REPORT_STATUS_OTHERS 3 ++ ++#define ACTIVITY_REPORT_SCHEDULE_UNKNOWN 0 /* Does not know the schedule of the interference */ ++#define ACTIVITY_REPORT_SCHEDULE_KNOWN 1 ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _BT_OVER_WIFI_COMMAND_HEADER_T { ++ UINT_8 ucCommandId; ++ UINT_8 ucSeqNumber; ++ UINT_16 u2PayloadLength; ++} AMPC_COMMAND_HEADER_T, *P_AMPC_COMMAND_HEADER_T; ++ ++typedef struct _BT_OVER_WIFI_COMMAND { ++ AMPC_COMMAND_HEADER_T rHeader; ++ UINT_8 aucPayload[0]; ++} AMPC_COMMAND, *P_AMPC_COMMAND; ++ ++typedef struct _BT_OVER_WIFI_EVENT_HEADER_T { ++ UINT_8 ucEventId; ++ UINT_8 ucSeqNumber; ++ UINT_16 u2PayloadLength; ++} AMPC_EVENT_HEADER_T, *P_AMPC_EVENT_HEADER_T; ++ ++typedef struct _BT_OVER_WIFI_EVENT { ++ AMPC_EVENT_HEADER_T rHeader; ++ UINT_8 aucPayload[0]; ++} AMPC_EVENT, *P_AMPC_EVENT; ++ ++typedef struct _CHANNEL_DESC_T { ++ UINT_8 ucChannelBand; ++ UINT_8 ucChannelNum; ++} CHANNEL_DESC, P_CHANNEL_DESC; ++ ++/* Command Structures */ ++typedef struct _BOW_SETUP_CONNECTION { ++/* Fixed to 2.4G */ ++ UINT_8 ucChannelNum; ++ UINT_8 ucReserved1; ++ UINT_8 aucPeerAddress[6]; ++ UINT_16 u2BeaconInterval; ++ UINT_8 ucTimeoutDiscovery; ++ UINT_8 ucTimeoutInactivity; ++ UINT_8 ucRole; ++ UINT_8 ucPAL_Capabilities; ++ INT_8 cMaxTxPower; ++ UINT_8 ucReserved2; ++ ++/* Pending, for future BOW 5G supporting. */ ++/* UINT_8 aucPeerAddress[6]; ++ UINT_16 u2BeaconInterval; ++ UINT_8 ucTimeoutDiscovery; ++ UINT_8 ucTimeoutInactivity; ++ UINT_8 ucRole; ++ UINT_8 ucPAL_Capabilities; ++ INT_8 cMaxTxPower; ++ UINT_8 ucChannelListNum; ++ CHANNEL_DESC arChannelList[1]; ++*/ ++} BOW_SETUP_CONNECTION, *P_BOW_SETUP_CONNECTION; ++ ++typedef struct _BOW_DESTROY_CONNECTION { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++} BOW_DESTROY_CONNECTION, *P_BOW_DESTROY_CONNECTION; ++ ++typedef struct _BOW_SET_PTK { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++ UINT_8 aucTemporalKey[16]; ++} BOW_SET_PTK, *P_BOW_SET_PTK; ++ ++typedef struct _BOW_READ_RSSI { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++} BOW_READ_RSSI, *P_BOW_READ_RSSI; ++ ++typedef struct _BOW_READ_LINK_QUALITY { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 aucReserved[2]; ++} BOW_READ_LINK_QUALITY, *P_BOW_READ_LINK_QUALITY; ++ ++typedef struct _BOW_SHORT_RANGE_MODE { ++ UINT_8 aucPeerAddress[6]; ++ INT_8 cTxPower; ++ UINT_8 ucReserved; ++} BOW_SHORT_RANGE_MODE, *P_BOW_SHORT_RANGE_MODE; ++ ++/* Event Structures */ ++typedef struct _BOW_COMMAND_STATUS { ++ UINT_8 ucStatus; ++ UINT_8 ucReserved[3]; ++} BOW_COMMAND_STATUS, *P_BOW_COMMAND_STATUS; ++ ++typedef struct _BOW_MAC_STATUS { ++ UINT_8 aucMacAddr[6]; ++ UINT_8 ucAvailability; ++ UINT_8 ucNumOfChannel; ++ CHANNEL_DESC arChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; ++} BOW_MAC_STATUS, *P_BOW_MAC_STATUS; ++ ++typedef struct _BOW_LINK_CONNECTED { ++ CHANNEL_DESC rChannel; ++ UINT_8 aucReserved; ++ UINT_8 aucPeerAddress[6]; ++} BOW_LINK_CONNECTED, *P_BOW_LINK_CONNECTED; ++ ++typedef struct _BOW_LINK_DISCONNECTED { ++ UINT_8 ucReason; ++ UINT_8 aucReserved; ++ UINT_8 aucPeerAddress[6]; ++} BOW_LINK_DISCONNECTED, *P_BOW_LINK_DISCONNECTED; ++ ++typedef struct _BOW_RSSI { ++ INT_8 cRssi; ++ UINT_8 aucReserved[3]; ++} BOW_RSSI, *P_BOW_RSSI; ++ ++typedef struct _BOW_LINK_QUALITY { ++ UINT_8 ucLinkQuality; ++ UINT_8 aucReserved[3]; ++} BOW_LINK_QUALITY, *P_BOW_LINK_QUALITY; ++ ++typedef enum _ENUM_BOW_CMD_ID_T { ++ BOW_CMD_ID_GET_MAC_STATUS = 1, ++ BOW_CMD_ID_SETUP_CONNECTION, ++ BOW_CMD_ID_DESTROY_CONNECTION, ++ BOW_CMD_ID_SET_PTK, ++ BOW_CMD_ID_READ_RSSI, ++ BOW_CMD_ID_READ_LINK_QUALITY, ++ BOW_CMD_ID_SHORT_RANGE_MODE, ++ BOW_CMD_ID_GET_CHANNEL_LIST, ++} ENUM_BOW_CMD_ID_T, *P_ENUM_BOW_CMD_ID_T; ++ ++typedef enum _ENUM_BOW_EVENT_ID_T { ++ BOW_EVENT_ID_COMMAND_STATUS = 1, ++ BOW_EVENT_ID_MAC_STATUS, ++ BOW_EVENT_ID_LINK_CONNECTED, ++ BOW_EVENT_ID_LINK_DISCONNECTED, ++ BOW_EVENT_ID_RSSI, ++ BOW_EVENT_ID_LINK_QUALITY, ++ BOW_EVENT_ID_CHANNEL_LIST, ++ BOW_EVENT_ID_CHANNEL_SELECTED, ++} ENUM_BOW_EVENT_ID_T, *P_ENUM_BOW_EVENT_ID_T; ++ ++typedef enum _ENUM_BOW_DEVICE_STATE { ++ BOW_DEVICE_STATE_DISCONNECTED = 0, ++ BOW_DEVICE_STATE_DISCONNECTING, ++ BOW_DEVICE_STATE_ACQUIRING_CHANNEL, ++ BOW_DEVICE_STATE_STARTING, ++ BOW_DEVICE_STATE_SCANNING, ++ BOW_DEVICE_STATE_CONNECTING, ++ BOW_DEVICE_STATE_CONNECTED, ++ BOW_DEVICE_STATE_NUM ++} ENUM_BOW_DEVICE_STATE, *P_ENUM_BOW_DEVICE_STATE; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#endif /*_BOW_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h +new file mode 100644 +index 000000000000..c1ecb303b877 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h +@@ -0,0 +1,150 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "cmd_buf.h" ++ \brief In this file we define the structure for Command Packet. ++ ++ In this file we define the structure for Command Packet and the control unit ++ of MGMT Memory Pool. ++*/ ++ ++/* ++** Log: cmd_buf.h ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow ++ * under concurrent network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Enable change log ++*/ ++ ++#ifndef _CMD_BUF_H ++#define _CMD_BUF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _COMMAND_TYPE { ++ COMMAND_TYPE_GENERAL_IOCTL, ++ COMMAND_TYPE_NETWORK_IOCTL, ++ COMMAND_TYPE_SECURITY_FRAME, ++ COMMAND_TYPE_MANAGEMENT_FRAME, ++ COMMAND_TYPE_NUM ++} COMMAND_TYPE, *P_COMMAND_TYPE; ++ ++typedef VOID(*PFN_CMD_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++typedef VOID(*PFN_CMD_TIMEOUT_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++struct _CMD_INFO_T { ++ QUE_ENTRY_T rQueEntry; ++ ++ COMMAND_TYPE eCmdType; ++ ++ UINT_16 u2InfoBufLen; /* This is actual CMD buffer length */ ++ PUINT_8 pucInfoBuffer; /* May pointer to structure in prAdapter */ ++ P_NATIVE_PACKET prPacket; /* only valid when it's a security frame */ ++ ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkType; ++ UINT_8 ucStaRecIndex; /* only valid when it's a security frame */ ++ ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler; ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler; ++ ++ BOOLEAN fgIsOid; /* Used to check if we need indicate */ ++ ++ UINT_8 ucCID; ++ BOOLEAN fgSetQuery; ++ BOOLEAN fgNeedResp; ++ BOOLEAN fgDriverDomainMCR; /* Access Driver Domain MCR, for CMD_ID_ACCESS_REG only */ ++ UINT_8 ucCmdSeqNum; ++ UINT_32 u4SetInfoLen; /* Indicate how many byte we read for Set OID */ ++ ++ /* information indicating by OID/ioctl */ ++ PVOID pvInformationBuffer; ++ UINT_32 u4InformationBufferLength; ++ ++ /* private data */ ++ UINT_32 u4PrivateData; ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter); ++ ++P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); ++ ++VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for CMDs */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); ++VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _CMD_BUF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h +new file mode 100644 +index 000000000000..0fdb9dcadeef +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h +@@ -0,0 +1,618 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hal.h#1 ++*/ ++ ++/*! \file "hal.h" ++ \brief The declaration of hal functions ++ ++ N/A ++*/ ++ ++/* ++** Log: hal.h ++ * ++ * 04 01 2011 tsaiyuan.hsu ++ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues ++ * fix the klocwork issues, 57500, 57501, 57502 and 57503. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change zero-padding for TX port access to HAL. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * 4. correct some HAL implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-16 18:02:26 GMT mtk02752 ++** include precomp.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:16 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 13:54:15 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-11 10:36:01 GMT mtk01084 ++** modify HAL functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-09 22:56:28 GMT mtk01084 ++** modify HW access routines ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:50:09 GMT mtk01084 ++** add new macro HAL_TX_PORT_WR ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:08:10 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:50 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-05-18 14:28:10 GMT mtk01084 ++** fix issue in HAL_DRIVER_OWN_BY_SDIO_CMD52() ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-11 17:26:33 GMT mtk01084 ++** modify the bit definition to check driver own status ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:30:22 GMT mtk01461 ++** Fix typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:50:34 GMT mtk01461 ++** Redefine HAL_PORT_RD/WR macro for SW pre test ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-24 09:46:49 GMT mtk01084 ++** fix LINT error ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 16:53:38 GMT mtk01084 ++** add HAL_DRIVER_OWN_BY_SDIO_CMD52() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:53:13 GMT mtk01426 ++** Fixed lint warn ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:20 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _HAL_H ++#define _HAL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* Macros for flag operations for the Adapter structure */ ++#define HAL_SET_FLAG(_M, _F) ((_M)->u4HwFlags |= (_F)) ++#define HAL_CLEAR_FLAG(_M, _F) ((_M)->u4HwFlags &= ~(_F)) ++#define HAL_TEST_FLAG(_M, _F) ((_M)->u4HwFlags & (_F)) ++#define HAL_TEST_FLAGS(_M, _F) (((_M)->u4HwFlags & (_F)) == (_F)) ++ ++#if defined(_HIF_SDIO) ++#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ ++do { \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ /* DBGLOG(HAL, ERROR, ("HAL_MCR_RD access fail! 0x%x: 0x%x\n", */ \ ++ /* (UINT32)_u4Offset, (UINT32)*_pu4Value)); */ \ ++ } \ ++ } else { \ ++ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_RD access! 0x%x\n", (UINT32)_u4Offset)); */ \ ++ } \ ++} while (0) ++ ++#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ ++do { \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ /* DBGLOG(HAL, ERROR, ("HAL_MCR_WR access fail! 0x%x: 0x%x\n", */ \ ++ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ ++ } \ ++ } else { \ ++ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_WR access! 0x%x: 0x%x\n", */ \ ++ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ ++ } \ ++} while (0) ++ ++#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ /*fgResult = FALSE; */\ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "HAL_PORT_RD access fail! 0x%x\n", _u4Port); \ ++ } \ ++ else { \ ++ /*fgResult = TRUE;*/ } \ ++ } else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_PORT_RD access! 0x%x\n", _u4Port); \ ++ } \ ++} ++ ++#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ /*fgResult = FALSE; */\ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "HAL_PORT_WR access fail! 0x%x\n", _u4Port); \ ++ } \ ++ else { \ ++ /*fgResult = TRUE;*/ } \ ++ } else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_PORT_WR access! 0x%x\n", _u4Port); \ ++ } \ ++} ++ ++#if 0 /* only for SDIO */ ++#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf) == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "HAL_BYTE_WR access fail! 0x%x\n", _u4Port); \ ++ } \ ++ else { \ ++ /* Todo:: Nothing*/ \ ++ } \ ++ } \ ++ else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_BYTE_WR access! 0x%x\n", _u4Port); \ ++ } \ ++} ++#endif ++ ++#define HAL_DRIVER_OWN_BY_SDIO_CMD52(_prAdapter, _pfgDriverIsOwnReady) \ ++{ \ ++ UINT_8 ucBuf = BIT(1); \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ ++ if (kalDevReadAfterWriteWithSdioCmd52(_prAdapter->prGlueInfo, MCR_WHLPCR_BYTE1, &ucBuf, 1) \ ++ == FALSE) {\ ++ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ ++ fgIsBusAccessFailed = TRUE; \ ++ DBGLOG(HAL, ERROR, "kalDevReadAfterWriteWithSdioCmd52 access fail!\n"); \ ++ } \ ++ else { \ ++ *_pfgDriverIsOwnReady = (ucBuf & BIT(0)) ? TRUE : FALSE; \ ++ } \ ++ } else { \ ++ DBGLOG(HAL, WARN, "ignore HAL_DRIVER_OWN_BY_SDIO_CMD52 access!\n"); \ ++ } \ ++} ++ ++#else /* #if defined(_HIF_SDIO) */ ++#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ ++ == FALSE) \ ++ fgIsBusAccessFailed = TRUE; \ ++} ++ ++#if 0 /* only for SDIO */ ++#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ ++{ \ ++ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ ++ ASSERT(0); \ ++ } \ ++kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf); \ ++} ++#endif ++ ++#endif /* #if defined(_HIF_SDIO) */ ++ ++#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \ ++{ \ ++ ASSERT(u4PortId < 2); \ ++ HAL_PORT_RD(prAdapter, \ ++ ((u4PortId == 0) ? MCR_WRDR0 : MCR_WRDR1), \ ++ u4Len, \ ++ pvBuf, \ ++ _u4ValidBufSize/*temp!!*//*4Kbyte*/); \ ++} ++ ++#define HAL_WRITE_TX_PORT(_prAdapter, _ucTxPortIdx, _u4Len, _pucBuf, _u4ValidBufSize) \ ++{ \ ++ ASSERT(_ucTxPortIdx < 2); \ ++ if ((_u4ValidBufSize - _u4Len) >= sizeof(UINT_32)) { \ ++ /* fill with single dword of zero as TX-aggregation termination */ \ ++ *(PUINT_32) (&((_pucBuf)[ALIGN_4(_u4Len)])) = 0; \ ++ } \ ++ HAL_PORT_WR(_prAdapter, \ ++ (_ucTxPortIdx == 0) ? MCR_WTDR0 : MCR_WTDR1, \ ++ _u4Len, \ ++ _pucBuf, \ ++ _u4ValidBufSize/*temp!!*//*4KByte*/); \ ++} ++ ++/* The macro to read the given MCR several times to check if the wait ++ condition come true. */ ++#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, _waitCondition, _waitDelay, _waitCount, _status) \ ++{ \ ++ UINT_32 count; \ ++ (_status) = FALSE; \ ++ for (count = 0; count < (_waitCount); count++) { \ ++ HAL_MCR_RD((_pAdapter), (_offset), (_pReadValue)); \ ++ if ((_waitCondition)) { \ ++ (_status) = TRUE; \ ++ break; \ ++ } \ ++ kalUdelay((_waitDelay)); \ ++ } \ ++} ++ ++/* The macro to write 1 to a R/S bit and read it several times to check if the ++ command is done */ ++#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, _busyMask, _waitDelay, _waitCount, _status) \ ++{ \ ++ UINT_32 u4Temp; \ ++ UINT_32 u4Count = _waitCount; \ ++ (_status) = FALSE; \ ++ HAL_MCR_WR((_pAdapter), (_offset), (_writeValue)); \ ++ do { \ ++ kalUdelay((_waitDelay)); \ ++ HAL_MCR_RD((_pAdapter), (_offset), &u4Temp); \ ++ if (!(u4Temp & (_busyMask))) { \ ++ (_status) = TRUE; \ ++ break; \ ++ } \ ++ u4Count--; \ ++ } while (u4Count); \ ++} ++ ++#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WCIR, \ ++ &u4Value); \ ++ *pu2ChipId = (UINT_16)(u4Value & WCIR_CHIP_ID); \ ++ *pu2Version = (UINT_16)(u4Value & WCIR_REVISION_ID) >> 16; \ ++} ++ ++#define HAL_WAIT_WIFI_FUNC_READY(_prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ UINT_32 i; \ ++ for (i = 0; i < 100; i++) { \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WCIR, \ ++ &u4Value); \ ++ if (u4Value & WCIR_WLAN_READY) { \ ++ break; \ ++ } \ ++ NdisMSleep(10); \ ++ } \ ++} ++ ++#define HAL_INTR_DISABLE(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_INT_EN_CLR) ++ ++#define HAL_INTR_ENABLE(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_INT_EN_SET) ++ ++#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ (WHLPCR_INT_EN_SET | WHLPCR_FW_OWN_REQ_SET)) ++ ++#define HAL_LP_OWN_SET(_prAdapter) \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_FW_OWN_REQ_SET) ++ ++#define HAL_LP_OWN_CLR_OK(_prAdapter, _pfgResult) \ ++{ \ ++ UINT_32 i; \ ++ UINT_32 u4RegValue; \ ++ UINT_32 u4LoopCnt = 2048 / 8; \ ++ *_pfgResult = TRUE; \ ++ /* Software get LP ownership */ \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHLPCR, \ ++ WHLPCR_FW_OWN_REQ_CLR) \ ++ for (i = 0; i < u4LoopCnt; i++) { \ ++ HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ ++ if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ ++ break; \ ++ } \ ++ else { \ ++ kalUdelay(8); \ ++ } \ ++ } \ ++ if (i == u4LoopCnt) { \ ++ *_pfgResult = FALSE; \ ++ /*ERRORLOG(("LP cannot be own back (%ld)", u4LoopCnt));*/ \ ++ /* check the time of LP instructions need to perform from Sleep to On */ \ ++ /*ASSERT(0); */ \ ++ } \ ++} ++ ++#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) \ ++{ \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WASR, \ ++ pu4AbnormalReason); \ ++} ++ ++#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHCR, \ ++ u4Value & ~WHCR_RX_ENHANCE_MODE_EN); \ ++} ++ ++#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHCR, \ ++ u4Value | WHCR_RX_ENHANCE_MODE_EN); \ ++} ++ ++#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) \ ++{ \ ++ UINT_32 u4Value, ucNum; \ ++ ucNum = ((_ucNumOfRxLen >= 16) ? 0 : _ucNumOfRxLen); \ ++ u4Value = 0; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ u4Value &= ~WHCR_MAX_HIF_RX_LEN_NUM; \ ++ u4Value |= ((((UINT_32)ucNum) << 4) & WHCR_MAX_HIF_RX_LEN_NUM); \ ++ HAL_MCR_WR(_prAdapter, \ ++ MCR_WHCR, \ ++ u4Value); \ ++} ++ ++#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(prAdapter, \ ++ MCR_WHCR, \ ++ u4Value & ~WHCR_W_INT_CLR_CTRL); \ ++ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = TRUE;\ ++} ++ ++#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(prAdapter, \ ++ MCR_WHCR, \ ++ &u4Value); \ ++ HAL_MCR_WR(prAdapter, \ ++ MCR_WHCR, \ ++ u4Value | WHCR_W_INT_CLR_CTRL); \ ++ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = FALSE;\ ++} ++ ++/* Note: enhance mode structure may also carried inside the buffer, ++ if the length of the buffer is long enough */ ++#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) \ ++ HAL_PORT_RD(prAdapter, \ ++ MCR_WHISR, \ ++ length, \ ++ pvBuf, \ ++ length) ++ ++#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, aucTxReleaseCount) \ ++{ \ ++ PUINT_32 pu4Value = (PUINT_32)aucTxReleaseCount; \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WTSR0, \ ++ &pu4Value[0]); \ ++ HAL_MCR_RD(_prAdapter, \ ++ MCR_WTSR1, \ ++ &pu4Value[1]); \ ++} ++ ++#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) \ ++{ \ ++ UINT_32 u4Value; \ ++ u4Value = 0; \ ++ HAL_MCR_RD(prAdapter, \ ++ MCR_WRPLR, \ ++ &u4Value); \ ++ *pu2Rx0Len = (UINT_16)u4Value; \ ++ *pu2Rx1Len = (UINT_16)(u4Value >> 16); \ ++} ++ ++#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, u2Len, pu4Status) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvBuf; \ ++ *pu4Status = pu4Buf[0]; \ ++} ++ ++#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4BufOut, u4LenBufOut) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ ++ ASSERT(u4LenBufOut >= 8); \ ++ pu4BufOut[0] = pu4Buf[1]; \ ++ pu4BufOut[1] = pu4Buf[2]; \ ++} ++ ++#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ ++ ASSERT((sizeof(au2Rx0Len) / sizeof(UINT_16)) >= 16); \ ++ ASSERT((sizeof(au2Rx1Len) / sizeof(UINT_16)) >= 16); \ ++ *pu2Rx0Num = (UINT_16)pu4Buf[3]; \ ++ *pu2Rx1Num = (UINT_16)(pu4Buf[3] >> 16); \ ++ kalMemCopy(au2Rx0Len, &pu4Buf[4], 8); \ ++ kalMemCopy(au2Rx1Len, &pu4Buf[12], 8); \ ++} ++ ++#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4Mailbox0, pu4Mailbox1) \ ++{ \ ++ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ ++ *pu4Mailbox0 = (UINT_16)pu4Buf[21]; \ ++ *pu4Mailbox1 = (UINT_16)pu4Buf[22]; \ ++} ++ ++#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & WHISR_TX_DONE_INT) ? TRUE : FALSE) ++ ++#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & (WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)) ? TRUE : FALSE) ++ ++#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & WHISR_ABNORMAL_INT) ? TRUE : FALSE) ++ ++#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) \ ++ ((u4IntrStatus & WHISR_FW_OWN_BACK_INT) ? TRUE : FALSE) ++ ++#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) \ ++{ \ ++ ASSERT(u4MboxId < 2); \ ++ HAL_MCR_WR(prAdapter, \ ++ ((u4MboxId == 0) ? MCR_H2DSM0R : MCR_H2DSM1R), \ ++ u4Data); \ ++} ++ ++#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) \ ++{ \ ++ ASSERT(u4MboxId < 2); \ ++ HAL_MCR_RD(prAdapter, \ ++ ((u4MboxId == 0) ? MCR_D2HRM0R : MCR_D2HRM1R), \ ++ pu4Data); \ ++} ++ ++#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \ ++{ \ ++ UINT_32 u4Value; \ ++ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);\ ++ HAL_MCR_WR(prAdapter, MCR_WHCR, \ ++ (fgEnableReadClear) ? \ ++ (u4Value | WHCR_W_MAILBOX_RD_CLR_EN) : \ ++ (u4Value & ~WHCR_W_MAILBOX_RD_CLR_EN)); \ ++ prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\ ++} ++ ++#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _HAL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h +new file mode 100644 +index 000000000000..b9aa154b097e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h +@@ -0,0 +1,220 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_rx.h#1 ++*/ ++ ++/*! \file "hif_rx.h" ++ \brief Provide HIF RX Header Information between F/W and Driver ++ ++ N/A ++*/ ++ ++/* ++** Log: hif_rx.h ++ * ++ * 09 01 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * follow-ups for HIF_RX_HEADER_T update: ++ * 1) add TCL ++ * 2) add RCPI ++ * 3) add ChannelNumber ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:44:00 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-09 13:59:20 GMT MTK02468 ++** Added HIF_RX_HDR parsing macros ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 19:54:54 GMT mtk02752 ++** adopt HIF_RX_HEADER_T in new data path ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-29 19:51:19 GMT mtk01084 ++** modify FW/ driver interface ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:33:58 GMT mtk01461 ++** Add define of HW_APPENED_LEN ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:51:02 GMT mtk01461 ++** Rename ENUM_HIF_RX_PKT_TYPE_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 12:05:03 GMT mtk01426 ++** Remove __KAL_ATTRIB_PACKED__ and add hifDataTypeCheck() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:18:52 GMT mtk01426 ++** Add comment to HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:23 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _HIF_RX_H ++#define _HIF_RX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/*! HIF_RX_HEADER_T */ ++/* DW 0, Byte 1 */ ++#define HIF_RX_HDR_PACKET_TYPE_MASK BITS(0, 1) ++#define HIF_RX_HDR_SEC_MODE_MASK BITS(2, 5) ++#define HIF_RX_HDR_SEC_MODE_OFFSET 2 ++ ++/* DW 1, Byte 0 */ ++#define HIF_RX_HDR_HEADER_LEN BITS(2, 7) ++#define HIF_RX_HDR_HEADER_LEN_OFFSET 2 ++#define HIF_RX_HDR_HEADER_OFFSET_MASK BITS(0, 1) ++ ++/* DW 1, Byte 1 */ ++#define HIF_RX_HDR_80211_HEADER_FORMAT BIT(0) ++#define HIF_RX_HDR_DO_REORDER BIT(1) ++#define HIF_RX_HDR_PAL BIT(2) ++#define HIF_RX_HDR_TCL BIT(3) ++#define HIF_RX_HDR_NETWORK_IDX_MASK BITS(4, 7) ++#define HIF_RX_HDR_NETWORK_IDX_OFFSET 4 ++ ++/* DW 1, Byte 2, 3 */ ++#define HIF_RX_HDR_SEQ_NO_MASK BITS(0, 11) ++#define HIF_RX_HDR_TID_MASK BITS(12, 14) ++#define HIF_RX_HDR_TID_OFFSET 12 ++#define HIF_RX_HDR_BAR_FRAME BIT(15) ++ ++#define HIF_RX_HDR_FLAG_AMP_WDS BIT(0) ++#define HIF_RX_HDR_FLAG_802_11_FORMAT BIT(1) ++#define HIF_RX_HDR_FLAG_BAR_FRAME BIT(2) ++#define HIF_RX_HDR_FLAG_DO_REORDERING BIT(3) ++#define HIF_RX_HDR_FLAG_CTRL_WARPPER_FRAME BIT(4) ++ ++#define HIF_RX_HW_APPENDED_LEN 4 ++ ++/* For DW 2, Byte 3 - ucHwChannelNum */ ++#define HW_CHNL_NUM_MAX_2G4 14 ++#define HW_CHNL_NUM_MAX_4G_5G (255 - HW_CHNL_NUM_MAX_2G4) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef struct _HIF_RX_HEADER_T { ++ UINT_16 u2PacketLen; ++ UINT_16 u2PacketType; ++ UINT_8 ucHerderLenOffset; ++ UINT_8 uc80211_Reorder_PAL_TCL; ++ UINT_16 u2SeqNoTid; ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucRcpi; ++ UINT_8 ucHwChannelNum; ++ UINT_8 ucReserved; ++} HIF_RX_HEADER_T, *P_HIF_RX_HEADER_T; ++ ++typedef enum _ENUM_HIF_RX_PKT_TYPE_T { ++ HIF_RX_PKT_TYPE_DATA = 0, ++ HIF_RX_PKT_TYPE_EVENT, ++ HIF_RX_PKT_TYPE_TX_LOOPBACK, ++ HIF_RX_PKT_TYPE_MANAGEMENT, ++ HIF_RX_PKT_TYPE_NUM ++} ENUM_HIF_RX_PKT_TYPE_T, *P_ENUM_HIF_RX_PKT_TYPE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define HIF_RX_HDR_SIZE sizeof(HIF_RX_HEADER_T) ++ ++#define HIF_RX_HDR_GET_80211_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_80211_HEADER_FORMAT) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_REORDER_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_DO_REORDER) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_PAL_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_PAL) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_TCL_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_TCL) ? TRUE : FALSE)) ++#define HIF_RX_HDR_GET_NETWORK_IDX(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_NETWORK_IDX_MASK)\ ++ >> HIF_RX_HDR_NETWORK_IDX_OFFSET) ++ ++#define HIF_RX_HDR_GET_SEC_MODE(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->u2PacketType) & HIF_RX_HDR_SEC_MODE_MASK) >> HIF_RX_HDR_SEC_MODE_OFFSET) ++ ++#define HIF_RX_HDR_GET_TID(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_TID_MASK)\ ++ >> HIF_RX_HDR_TID_OFFSET) ++#define HIF_RX_HDR_GET_SN(_prHifRxHdr) \ ++ (((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_SEQ_NO_MASK) ++#define HIF_RX_HDR_GET_BAR_FLAG(_prHifRxHdr) \ ++ (((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_BAR_FRAME) ? TRUE : FALSE)) ++ ++#define HIF_RX_HDR_GET_CHNL_NUM(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->ucHwChannelNum) > HW_CHNL_NUM_MAX_4G_5G) ? \ ++ (((_prHifRxHdr)->ucHwChannelNum) - HW_CHNL_NUM_MAX_4G_5G) : \ ++ ((_prHifRxHdr)->ucHwChannelNum)) ++ ++/* To do: support more bands other than 2.4G and 5G */ ++#define HIF_RX_HDR_GET_RF_BAND(_prHifRxHdr) \ ++ ((((_prHifRxHdr)->ucHwChannelNum) <= HW_CHNL_NUM_MAX_2G4) ? \ ++ BAND_2G4 : BAND_5G) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static inline VOID hifDataTypeCheck(VOID); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ * We'll need this for porting driver to different RTOS. ++ */ ++static inline VOID hifDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_RX_HEADER_T) == 12); ++ ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h +new file mode 100644 +index 000000000000..17252f2c7760 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h +@@ -0,0 +1,214 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_tx.h#1 ++*/ ++ ++/* ++** Log: hif_tx.h ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill extra information for revised HIF_TX_HEADER. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate ++ * 2) add packet type for indicating management frames ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++ * ++ * 01 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:40 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-24 19:55:11 GMT mtk02752 ++** adopt HIF_TX_HEADER_T in new data path ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-23 17:54:13 GMT mtk02752 ++** CMD_HDR_SIZE = (sizeof(WIFI_CMD_T)) to follow up CM's CMD/EVENT documentation ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-17 22:41:10 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-17 17:34:07 GMT mtk02752 ++** remove HIF_TX_BUFF_COUNT_TC0 (move to nic_tx.h) ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-17 12:14:12 GMT mtk02752 ++** add initial value for HIF_TX_BUFF_COUNT_TC5 ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-13 13:54:18 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-04 14:11:14 GMT mtk01084 ++** modify SW TX data format ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-29 19:51:53 GMT mtk01084 ++** modify FW/ driver interface ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-20 12:22:46 GMT mtk01461 ++** Add SeqNum field to CMD Header ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:40:52 GMT mtk01461 ++** Update the Log Sign ++*/ ++ ++#ifndef _HIF_TX_H ++#define _HIF_TX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Maximum buffer size for individual HIF TCQ Buffer */ ++#define HIF_TX_BUFF_MAX_SIZE 1552 /* Reserved field was not included */ ++ ++/* Maximum buffer count for individual HIF TCQ */ ++#define HIF_TX_BUFF_COUNT_TC0 3 ++#define HIF_TX_BUFF_COUNT_TC1 3 ++#define HIF_TX_BUFF_COUNT_TC2 3 ++#define HIF_TX_BUFF_COUNT_TC3 3 ++#define HIF_TX_BUFF_COUNT_TC4 2 ++ ++#define TX_HDR_SIZE sizeof(HIF_TX_HEADER_T) ++ ++#define CMD_HDR_SIZE sizeof(WIFI_CMD_T) ++ ++#define CMD_PKT_SIZE_FOR_IMAGE 2048 /* !< 2048 Bytes CMD payload buffer */ ++ ++/*! NIC_HIF_TX_HEADER_T */ ++/* DW 0, Byte 0,1 */ ++#define HIF_TX_HDR_TX_BYTE_COUNT_MASK BITS(0, 11) ++#define HIF_TX_HDR_USER_PRIORITY_OFFSET 12 ++ ++/* DW 0, Byte 2 */ ++#define HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK BITS(0, 7) ++ ++/* DW 0, Byte 3 */ ++#define HIF_TX_HDR_IP_CSUM BIT(0) ++#define HIF_TX_HDR_TCP_CSUM BIT(1) ++#define HIF_TX_HDR_RESOURCE_MASK BITS(2, 5) ++#define HIF_TX_HDR_RESOURCE_OFFSET 2 ++#define HIF_TX_HDR_PACKET_TYPE_MASK BITS(6, 7) ++#define HIF_TX_HDR_PACKET_TYPE_OFFSET 6 ++ ++/* DW 1, Byte 0 */ ++#define HIF_TX_HDR_WLAN_HEADER_LEN_MASK BITS(0, 5) ++ ++/* DW 1, Byte 1 */ ++#define HIF_TX_HDR_FORMAT_ID_MASK BITS(0, 2) ++#define HIF_TX_HDR_NETWORK_TYPE_MASK BITS(4, 5) ++#define HIF_TX_HDR_NETWORK_TYPE_OFFSET 4 ++#define HIF_TX_HDR_FLAG_1X_FRAME_MASK BIT(6) ++#define HIF_TX_HDR_FLAG_1X_FRAME_OFFSET 6 ++#define HIF_TX_HDR_FLAG_802_11_FORMAT_MASK BIT(7) ++#define HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET 7 ++ ++/* DW2, Byte 3 */ ++#define HIF_TX_HDR_PS_FORWARDING_TYPE_MASK BITS(0, 1) ++#define HIF_TX_HDR_PS_SESSION_ID_MASK BITS(2, 4) ++#define HIF_TX_HDR_PS_SESSION_ID_OFFSET 2 ++#define HIF_TX_HDR_BURST_END_MASK BIT(5) ++#define HIF_TX_HDR_BURST_END_OFFSET 5 ++ ++/* DW3, Byte 1 */ ++#define HIF_TX_HDR_NEED_ACK BIT(0) ++#define HIF_TX_HDR_BIP BIT(1) ++#define HIF_TX_HDR_BASIC_RATE BIT(2) ++#define HIF_TX_HDR_NEED_TX_DONE_STATUS BIT(3) ++#define HIF_TX_HDR_RTS BIT(4) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _HIF_HW_TX_HEADER_T { ++ UINT_16 u2TxByteCount; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucCSflags; ++ UINT_8 aucBuffer[0]; ++} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T; ++ ++typedef struct _HIF_TX_HEADER_T { ++ UINT_16 u2TxByteCount_UserPriority; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucResource_PktType_CSflags; ++ UINT_8 ucWlanHeaderLength; ++ UINT_8 ucPktFormtId_Flags; ++ UINT_16 u2LLH; /* for BOW */ ++ UINT_16 u2SeqNo; /* for BOW */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucForwardingType_SessionID_Reserved; ++ UINT_8 ucPacketSeqNo; ++ UINT_8 ucAck_BIP_BasicRate; ++ UINT_8 aucReserved[2]; ++} HIF_TX_HEADER_T, *P_HIF_TX_HEADER_T; ++ ++typedef enum _ENUM_HIF_TX_PKT_TYPE_T { ++ HIF_TX_PKT_TYPE_DATA = 0, ++ HIF_TX_PKT_TYPE_CMD, ++ HIF_TX_PKT_TYPE_HIF_LOOPBACK, ++ HIF_TX_PKT_TYPE_MANAGEMENT, ++ HIF_TX_PKT_TYPE_NUM ++} ENUM_HIF_TX_PKT_TYPE_T, *P_ENUM_HIF_TX_PKT_TYPE_T; ++ ++typedef enum _ENUM_HIF_OOB_CTRL_PKT_TYPE_T { ++ HIF_OOB_CTRL_PKT_TYPE_LOOPBACK = 1, ++ HIF_OOB_CTRL_PKT_TYP_NUM ++} ENUM_HIF_OOB_CTRL_PKT_TYPE_T, *P_ENUM_HIF_OOB_CTRL_PKT_TYPE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define TFCB_FRAME_PAD_TO_DW(u2Length) ALIGN_4(u2Length) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* Kevin: we don't have to call following function to inspect the data structure. ++ * It will check automatically while at compile time. ++ */ ++static inline VOID hif_txDataTypeCheck(VOID); ++ ++static inline VOID hif_txDataTypeCheck(VOID) ++{ ++ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_TX_HEADER_T) == 16); ++ ++} ++ ++#endif /*_HIF_TX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h +new file mode 100644 +index 000000000000..ff38d30c3cf2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h +@@ -0,0 +1,2323 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/mac.h#1 ++*/ ++ ++/*! \file "mac.h" ++ \brief Brief description. ++ ++ Detail description. ++*/ ++ ++/* ++** Log: mac.h ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 wh.su ++ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h ++ * and let the sw structure not align at byte ++ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, ++ * Notice needed update P2P.ko. ++ * ++ * 05 06 2011 wh.su ++ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send ++ * the wrong beacon make driver got incorrect support rate set ++ * Add the length check before access the ie length filed. ++ * ++ * 05 06 2011 wh.su ++ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send ++ * the wrong beacon make driver got incorrect support rate set ++ * adding the length check before processing next ie.. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discover ability support. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Some action frame define is not belong to P2P. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Add some service discovery MAC define, phase I. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork ++ * suppress warning reported by Klockwork. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * revert to previous revision. (this file is not necessary to be changed) ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * 1. Add P2P MAC define. ++ * 2. Add scan device found event ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add WFA specific OUI. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P IE ID & Vendor OUI TYPE for P2P. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge MAC.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added OFFSET_BAR_SSC_SN ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:00:24 GMT MTK02468 ++** Added offsets and masks for the BA Parameter Set filed ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:26 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _MAC_H ++#define _MAC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* 3 --------------- Constants for Ethernet/802.11 MAC --------------- */ ++/* MAC Address */ ++#define MAC_ADDR_LEN 6 ++ ++#define MAC_ADDR_LOCAL_ADMIN BIT(1) ++ ++#define ETH_P_IPV4 0x0800 ++#define ETH_P_IPX 0x8137 /* Novell IPX */ ++#define ETH_P_AARP 0x80F3 /* AppleTalk Address Resolution Protocol (AARP) */ ++#define ETH_P_IPV6 0x86DD ++ ++#define IP_VERSION_4 4 ++#define IP_VERSION_6 6 ++ ++#define IP_PROTOCOL_TCP 6 ++#define IP_PROTOCOL_UDP 17 ++ ++#define IPV4_HDR_IP_IDENTIFICATION_OFFSET 4 ++#define IPV4_HDR_IP_PROTOCOL_OFFSET 9 ++#define IPV4_HDR_IP_CSUM_OFFSET 10 ++#define IPV4_HDR_IP_SRC_ADDR_OFFSET 12 ++#define IPV4_HDR_IP_DST_ADDR_OFFSET 16 ++ ++#define IPV6_HDR_IP_PROTOCOL_OFFSET 6 ++#define IPV6_HDR_IP_SRC_ADDR_OFFSET 8 ++#define IPV6_HDR_IP_DST_ADDR_OFFSET 24 ++#define IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET 32 ++#define IPV6_HDR_IP_DST_ADDR_MAC_LOW_OFFSET 37 ++#define IPV6_PROTOCOL_ICMPV6 0x3A ++#define IPV6_ADDR_LEN 16 ++#define IPV6_HDR_LEN 40 ++ ++#define ARP_OPERATION_OFFSET 6 ++#define ARP_SNEDER_MAC_OFFSET 8 ++#define ARP_SENDER_IP_OFFSET 14 ++#define ARP_TARGET_MAC_OFFSET 18 ++#define ARP_TARGET_IP_OFFSET 24 ++#define ARP_OPERATION_REQUEST 0x0001 ++#define ARP_OPERATION_RESPONSE 0x0002 ++ ++#define ICMPV6_TYPE_OFFSET 0 ++#define ICMPV6_FLAG_OFFSET 4 ++#define ICMPV6_TARGET_ADDR_OFFSET 8 ++#define ICMPV6_TARGET_LL_ADDR_TYPE_OFFSET 24 ++#define ICMPV6_TARGET_LL_ADDR_LEN_OFFSET 25 ++#define ICMPV6_TARGET_LL_ADDR_TA_OFFSET 26 ++ ++#define ICMPV6_FLAG_ROUTER_BIT BIT(7) ++#define ICMPV6_FLAG_SOLICITED_BIT BIT(6) ++#define ICMPV6_FLAG_OVERWRITE_BIT BIT(5) ++#define ICMPV6_TYPE_NEIGHBOR_SOLICITATION 0x87 ++#define ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 ++ ++#define TCP_HDR_TCP_CSUM_OFFSET 16 ++#define UDP_HDR_UDP_CSUM_OFFSET 6 ++ ++#define LLC_LEN 8 /* LLC(3) + SNAP(3) + EtherType(2) */ ++ ++#define NULL_MAC_ADDR {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} ++#define BC_MAC_ADDR {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} ++ ++/* Ethernet Frame Field Size, in byte */ ++#define ETHER_HEADER_LEN 14 ++#define ETHER_TYPE_LEN 2 ++#define ETHER_MIN_PKT_SZ 60 ++#define ETHER_MAX_PKT_SZ 1514 ++ ++/* IEEE 802.11 WLAN Frame Field Size, in byte */ ++#define WLAN_MAC_HEADER_LEN 24 /* Address 4 excluded */ ++#define WLAN_MAC_HEADER_A4_LEN 30 /* Address 4 included */ ++#define WLAN_MAC_HEADER_QOS_LEN 26 /* QoS Control included */ ++#define WLAN_MAC_HEADER_QOS_HTC_LEN 30 /* QoS Control and HTC included */ ++#define WLAN_MAC_HEADER_A4_QOS_LEN 32 /* Address 4 and QoS Control included */ ++#define WLAN_MAC_HEADER_A4_QOS_HTC_LEN 36 /* Address 4, QoS Control and HTC included */ ++#define WLAN_MAC_MGMT_HEADER_LEN 24 /* Address 4 excluded */ ++#define WLAN_MAC_MGMT_HEADER_HTC_LEN 28 /* HTC included */ ++ ++#define QOS_CTRL_LEN 2 ++#define HT_CTRL_LEN 4 ++ ++#define WLAN_MAC_CTS_ACK_LEN (WLAN_MAC_CTS_ACK_FRAME_HEADER_LEN + FCS_LEN) ++ ++/* 6.2.1.1.2 Semantics of the service primitive */ ++#define MSDU_MAX_LENGTH 2304 ++ ++/* 7.1.3.3.3 Broadcast BSSID */ ++#define BC_BSSID BC_MAC_ADDR ++ ++/* 7.1.3.7 FCS field */ ++#define FCS_LEN 4 ++ ++/* 7.3.1.6 Listen Interval field */ ++#define DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD 2 /* In unit of AP's DTIM interval, */ ++#define DEFAULT_LISTEN_INTERVAL 10 ++ ++/* 7.3.2.1 Broadcast(Wildcard) SSID */ ++#define BC_SSID "" ++#define BC_SSID_LEN 0 ++ ++/* 7.3.2.2 Data Rate Value */ ++#define RATE_1M 2 /* 1M in unit of 500kb/s */ ++#define RATE_2M 4 /* 2M */ ++#define RATE_5_5M 11 /* 5.5M */ ++#define RATE_11M 22 /* 11M */ ++#define RATE_22M 44 /* 22M */ ++#define RATE_33M 66 /* 33M */ ++#define RATE_6M 12 /* 6M */ ++#define RATE_9M 18 /* 9M */ ++#define RATE_12M 24 /* 12M */ ++#define RATE_18M 36 /* 18M */ ++#define RATE_24M 48 /* 24M */ ++#define RATE_36M 72 /* 36M */ ++#define RATE_48M 96 /* 48M */ ++#define RATE_54M 108 /* 54M */ ++/* 7.3.2.14 BSS membership selector */ ++#define RATE_HT_PHY 127 /* BSS Selector - Clause 20. HT PHY */ ++#define RATE_MASK BITS(0, 6) /* mask bits for the rate */ ++#define RATE_BASIC_BIT BIT(7) /* mask bit for the rate belonging to the BSSBasicRateSet */ ++ ++/* 8.3.2.2 TKIP MPDU formats */ ++#define TKIP_MIC_LEN 8 ++ ++/* 9.2.10 DIFS */ ++#define DIFS 2 /* 2 x aSlotTime */ ++ ++/* 11.3 STA Authentication and Association */ ++#define STA_STATE_1 0 /* Accept Class 1 frames */ ++#define STA_STATE_2 1 /* Accept Class 1 & 2 frames */ ++#define STA_STATE_3 2 /* Accept Class 1,2 & 3 frames */ ++ ++/* 15.4.8.5 802.11k RCPI-dBm mapping*/ ++#define NDBM_LOW_BOUND_FOR_RCPI 110 ++#define RCPI_LOW_BOUND 0 ++#define RCPI_HIGH_BOUND 220 ++#define RCPI_MEASUREMENT_NOT_AVAILABLE 255 ++ ++/* PHY characteristics */ ++/* 17.4.4/18.3.3/19.8.4 Slot Time (aSlotTime) */ ++#define SLOT_TIME_LONG 20 /* Long Slot Time */ ++#define SLOT_TIME_SHORT 9 /* Short Slot Time */ ++ ++#define SLOT_TIME_HR_DSSS SLOT_TIME_LONG /* 802.11b aSlotTime */ ++#define SLOT_TIME_OFDM SLOT_TIME_SHORT /* 802.11a aSlotTime(20M Spacing) */ ++#define SLOT_TIME_OFDM_10M_SPACING 13 /* 802.11a aSlotTime(10M Spacing) */ ++#define SLOT_TIME_ERP_LONG SLOT_TIME_LONG /* 802.11g aSlotTime(Long) */ ++#define SLOT_TIME_ERP_SHORT SLOT_TIME_SHORT /* 802.11g aSlotTime(Short) */ ++ ++/* 17.4.4/18.3.3/19.8.4 Contention Window (aCWmin & aCWmax) */ ++#define CWMIN_OFDM 15 /* 802.11a aCWmin */ ++#define CWMAX_OFDM 1023 /* 802.11a aCWmax */ ++ ++#define CWMIN_HR_DSSS 31 /* 802.11b aCWmin */ ++#define CWMAX_HR_DSSS 1023 /* 802.11b aCWmax */ ++ ++#define CWMIN_ERP_0 31 /* 802.11g aCWmin(0) - for only have 1/2/5/11Mbps Rates */ ++#define CWMIN_ERP_1 15 /* 802.11g aCWmin(1) */ ++#define CWMAX_ERP 1023 /* 802.11g aCWmax */ ++ ++/* Short Inter-Frame Space (aSIFSTime) */ ++/* 15.3.3 802.11b aSIFSTime */ ++#define SIFS_TIME_HR_DSSS 10 ++/* 17.4.4 802.11a aSIFSTime */ ++#define SIFS_TIME_OFDM 16 ++/* 19.8.4 802.11g aSIFSTime */ ++#define SIFS_TIME_ERP 10 ++ ++/* 15.4.6.2 Number of operating channels */ ++#define CH_1 0x1 ++#define CH_2 0x2 ++#define CH_3 0x3 ++#define CH_4 0x4 ++#define CH_5 0x5 ++#define CH_6 0x6 ++#define CH_7 0x7 ++#define CH_8 0x8 ++#define CH_9 0x9 ++#define CH_10 0xa ++#define CH_11 0xb ++#define CH_12 0xc ++#define CH_13 0xd ++#define CH_14 0xe ++ ++#define MAXIMUM_OPERATION_CHANNEL_LIST 46 ++ ++/* 3 --------------- IEEE 802.11 PICS --------------- */ ++/* Annex D - dot11OperationEntry 2 */ ++#define DOT11_RTS_THRESHOLD_MIN 0 ++#define DOT11_RTS_THRESHOLD_MAX 2347 /* from Windows DDK */ ++/* #define DOT11_RTS_THRESHOLD_MAX 3000 // from Annex D */ ++ ++#define DOT11_RTS_THRESHOLD_DEFAULT \ ++ DOT11_RTS_THRESHOLD_MAX ++ ++/* Annex D - dot11OperationEntry 5 */ ++#define DOT11_FRAGMENTATION_THRESHOLD_MIN 256 ++#define DOT11_FRAGMENTATION_THRESHOLD_MAX 2346 /* from Windows DDK */ ++/* #define DOT11_FRAGMENTATION_THRESHOLD_MAX 3000 // from Annex D */ ++ ++#define DOT11_FRAGMENTATION_THRESHOLD_DEFAULT \ ++ DOT11_FRAGMENTATION_THRESHOLD_MAX ++ ++/* Annex D - dot11OperationEntry 6 */ ++#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MIN 1 ++#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MAX 0xFFFFffff ++#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_DEFAULT 4095 /* 802.11 define 512 */ ++ /* MT5921 only aceept N <= 4095 */ ++ ++/* Annex D - dot11OperationEntry 7 */ ++#define DOT11_RECEIVE_LIFETIME_TU_MIN 1 ++#define DOT11_RECEIVE_LIFETIME_TU_MAX 0xFFFFffff ++#define DOT11_RECEIVE_LIFETIME_TU_DEFAULT 4096 /* 802.11 define 512 */ ++ ++/* Annex D - dot11StationConfigEntry 12 */ ++#define DOT11_BEACON_PERIOD_MIN 1 /* TU. */ ++#define DOT11_BEACON_PERIOD_MAX 0xffff /* TU. */ ++#define DOT11_BEACON_PERIOD_DEFAULT 100 /* TU. */ ++ ++/* Annex D - dot11StationConfigEntry 13 */ ++#define DOT11_DTIM_PERIOD_MIN 1 /* TU. */ ++#define DOT11_DTIM_PERIOD_MAX 255 /* TU. */ ++#define DOT11_DTIM_PERIOD_DEFAULT 1 /* TU. */ ++ ++/* Annex D - dot11RegDomainsSupportValue */ ++#define REGULATION_DOMAIN_FCC 0x10 /* FCC (US) */ ++#define REGULATION_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ ++#define REGULATION_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ ++#define REGULATION_DOMAIN_SPAIN 0x31 /* Spain */ ++#define REGULATION_DOMAIN_FRANCE 0x32 /* France */ ++#define REGULATION_DOMAIN_JAPAN 0x40 /* MKK (Japan) */ ++#define REGULATION_DOMAIN_CHINA 0x50 /* China */ ++#define REGULATION_DOMAIN_OTHER 0x00 /* Other */ ++ ++/* 3 --------------- IEEE 802.11 MAC header fields --------------- */ ++/* 7.1.3.1 Masks for the subfields in the Frame Control field */ ++#define MASK_FC_PROTOCOL_VER BITS(0, 1) ++#define MASK_FC_TYPE BITS(2, 3) ++#define MASK_FC_SUBTYPE BITS(4, 7) ++#define MASK_FC_SUBTYPE_QOS_DATA BIT(7) ++#define MASK_FC_TO_DS BIT(8) ++#define MASK_FC_FROM_DS BIT(9) ++#define MASK_FC_MORE_FRAG BIT(10) ++#define MASK_FC_RETRY BIT(11) ++#define MASK_FC_PWR_MGT BIT(12) ++#define MASK_FC_MORE_DATA BIT(13) ++#define MASK_FC_PROTECTED_FRAME BIT(14) ++#define MASK_FC_ORDER BIT(15) ++ ++#define MASK_FRAME_TYPE (MASK_FC_TYPE | MASK_FC_SUBTYPE) ++#define MASK_TO_DS_FROM_DS (MASK_FC_TO_DS | MASK_FC_FROM_DS) ++ ++#define MAX_NUM_OF_FC_SUBTYPES 16 ++#define OFFSET_OF_FC_SUBTYPE 4 ++ ++/* 7.1.3.1.2 MAC frame types and subtypes */ ++#define MAC_FRAME_TYPE_MGT 0 ++#define MAC_FRAME_TYPE_CTRL BIT(2) ++#define MAC_FRAME_TYPE_DATA BIT(3) ++#define MAC_FRAME_TYPE_QOS_DATA (MAC_FRAME_TYPE_DATA | MASK_FC_SUBTYPE_QOS_DATA) ++ ++#define MAC_FRAME_ASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0000) ++#define MAC_FRAME_ASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0010) ++#define MAC_FRAME_REASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0020) ++#define MAC_FRAME_REASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0030) ++#define MAC_FRAME_PROBE_REQ (MAC_FRAME_TYPE_MGT | 0x0040) ++#define MAC_FRAME_PROBE_RSP (MAC_FRAME_TYPE_MGT | 0x0050) ++#define MAC_FRAME_BEACON (MAC_FRAME_TYPE_MGT | 0x0080) ++#define MAC_FRAME_ATIM (MAC_FRAME_TYPE_MGT | 0x0090) ++#define MAC_FRAME_DISASSOC (MAC_FRAME_TYPE_MGT | 0x00A0) ++#define MAC_FRAME_AUTH (MAC_FRAME_TYPE_MGT | 0x00B0) ++#define MAC_FRAME_DEAUTH (MAC_FRAME_TYPE_MGT | 0x00C0) ++#define MAC_FRAME_ACTION (MAC_FRAME_TYPE_MGT | 0x00D0) ++#define MAC_FRAME_ACTION_NO_ACK (MAC_FRAME_TYPE_MGT | 0x00E0) ++ ++#define MAC_FRAME_CONTRL_WRAPPER (MAC_FRAME_TYPE_CTRL | 0x0070) ++#define MAC_FRAME_BLOCK_ACK_REQ (MAC_FRAME_TYPE_CTRL | 0x0080) ++#define MAC_FRAME_BLOCK_ACK (MAC_FRAME_TYPE_CTRL | 0x0090) ++#define MAC_FRAME_PS_POLL (MAC_FRAME_TYPE_CTRL | 0x00A0) ++#define MAC_FRAME_RTS (MAC_FRAME_TYPE_CTRL | 0x00B0) ++#define MAC_FRAME_CTS (MAC_FRAME_TYPE_CTRL | 0x00C0) ++#define MAC_FRAME_ACK (MAC_FRAME_TYPE_CTRL | 0x00D0) ++#define MAC_FRAME_CF_END (MAC_FRAME_TYPE_CTRL | 0x00E0) ++#define MAC_FRAME_CF_END_CF_ACK (MAC_FRAME_TYPE_CTRL | 0x00F0) ++ ++#define MAC_FRAME_DATA (MAC_FRAME_TYPE_DATA | 0x0000) ++#define MAC_FRAME_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0010) ++#define MAC_FRAME_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0020) ++#define MAC_FRAME_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0030) ++#define MAC_FRAME_NULL (MAC_FRAME_TYPE_DATA | 0x0040) ++#define MAC_FRAME_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0050) ++#define MAC_FRAME_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0060) ++#define MAC_FRAME_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0070) ++#define MAC_FRAME_QOS_DATA (MAC_FRAME_TYPE_DATA | 0x0080) ++#define MAC_FRAME_QOS_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0090) ++#define MAC_FRAME_QOS_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00A0) ++#define MAC_FRAME_QOS_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00B0) ++#define MAC_FRAME_QOS_NULL (MAC_FRAME_TYPE_DATA | 0x00C0) ++#define MAC_FRAME_QOS_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00E0) ++#define MAC_FRAME_QOS_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00F0) ++ ++/* 7.1.3.2 Mask for the AID value in the Duration/ID field */ ++#define MASK_DI_DURATION BITS(0, 14) ++#define MASK_DI_AID BITS(0, 13) ++#define MASK_DI_AID_MSB BITS(14, 15) ++#define MASK_DI_CFP_FIXED_VALUE BIT(15) ++ ++/* 7.1.3.4 Masks for the subfields in the Sequence Control field */ ++#define MASK_SC_SEQ_NUM BITS(4, 15) ++#define MASK_SC_SEQ_NUM_OFFSET 4 ++#define MASK_SC_FRAG_NUM BITS(0, 3) ++#define INVALID_SEQ_CTRL_NUM 0x000F /* According to 6.2.1.1.2 ++ * FRAG_NUM won't equal to 15 ++ */ ++ ++/* 7.1.3.5 QoS Control field */ ++#define TID_NUM 16 ++#define TID_MASK BITS(0, 3) ++#define EOSP BIT(4) ++#define ACK_POLICY BITS(5, 6) ++#define A_MSDU_PRESENT BIT(7) ++ ++#define MASK_QC_TID BITS(0, 3) ++#define MASK_QC_EOSP BIT(4) ++#define MASK_QC_EOSP_OFFSET 4 ++#define MASK_QC_ACK_POLICY BITS(5, 6) ++#define MASK_QC_ACK_POLICY_OFFSET 5 ++#define MASK_QC_A_MSDU_PRESENT BIT(7) ++ ++/* 7.1.3.5a HT Control field */ ++#define HT_CTRL_LINK_ADAPTATION_CTRL BITS(0, 15) ++#define HT_CTRL_CALIBRATION_POSITION BITS(16, 17) ++#define HT_CTRL_CALIBRATION_SEQUENCE BITS(18, 19) ++#define HT_CTRL_CSI_STEERING BITS(22, 23) ++#define HT_CTRL_NDP_ANNOUNCEMENT BIT(24) ++#define HT_CTRL_AC_CONSTRAINT BIT(30) ++#define HT_CTRL_RDG_MORE_PPDU BIT(31) ++ ++#define LINK_ADAPTATION_CTRL_TRQ BIT(1) ++#define LINK_ADAPTATION_CTRL_MAI_MRQ BIT(2) ++#define LINK_ADAPTATION_CTRL_MAI_MSI BITS(3, 5) ++#define LINK_ADAPTATION_CTRL_MFSI BITS(6, 8) ++#define LINK_ADAPTATION_CTRL_MFB_ASELC_CMD BITS(9, 11) ++#define LINK_ADAPTATION_CTRL_MFB_ASELC_DATA BITS(12, 15) ++ ++/* 7.1.3.5.3 Ack Policy subfield*/ ++#define ACK_POLICY_NORMAL_ACK_IMPLICIT_BA_REQ 0 ++#define ACK_POLICY_NO_ACK 1 ++#define ACK_POLICY_NO_EXPLICIT_ACK_PSMP_ACK 2 ++#define ACK_POLICY_BA 3 ++ ++/* 7.1.3.7 FCS field */ ++#define FCS_LEN 4 ++ ++/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ ++#define PSPOLL_FRAME_LEN 16 /* w/o FCS */ ++ ++/* 7.2.7.1 BAR */ ++#define OFFSET_BAR_SSC_SN 4 ++ ++/* 8.3.2.2 TKIP MPDU formats */ ++#define TKIP_MIC_LEN 8 ++ ++/* 2009.11.30 mtk02468: Moved these definitions to the right place */ ++#if 0 ++/* Block Ack Parameter Set field */ ++#define BA_PARM_BA_POLICY BIT(1) ++#define BA_PARM_TID BITS(2, 5) ++#define BA_PARM_BUFFER_SIZE BITS(6, 15) ++#endif ++ ++#define BA_POLICY_IMMEDIATE BIT(1) ++ ++/* Block Ack Starting Sequence Control field */ ++#define BA_START_SEQ_CTL_FRAG_NUM BITS(0, 3) ++#define BA_START_SEQ_CTL_SSN BITS(4, 15) ++ ++/* BAR Control field */ ++#define BAR_CONTROL_NO_ACK_POLICY BIT(0) ++#define BAR_CONTROL_MULTI_TID BIT(1) ++#define BAR_CONTROL_COMPRESSED_BA BIT(2) ++#define BAR_CONTROL_TID_INFO BITS(12, 15) ++#define BAR_CONTROL_TID_INFO_OFFSET 12 ++ ++/* TID Value */ ++#define BAR_INFO_TID_VALUE BITS(12, 15) ++ ++#define BAR_COMPRESSED_VARIANT_FRAME_LEN (16 + 4) ++ ++/* 3 --------------- IEEE 802.11 frame body fields --------------- */ ++/* 3 Management frame body components (I): Fixed Fields. */ ++/* 7.3.1.1 Authentication Algorithm Number field */ ++#define AUTH_ALGORITHM_NUM_FIELD_LEN 2 ++ ++#define AUTH_ALGORITHM_NUM_OPEN_SYSTEM 0 /* Open System */ ++#define AUTH_ALGORITHM_NUM_SHARED_KEY 1 /* Shared Key */ ++#define AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION 2 /* Fast BSS Transition */ ++ ++/* 7.3.1.2 Authentication Transaction Sequence Number field */ ++#define AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN 2 ++#define AUTH_TRANSACTION_SEQ_1 1 ++#define AUTH_TRANSACTION_SEQ_2 2 ++#define AUTH_TRANSACTION_SEQ_3 3 ++#define AUTH_TRANSACTION_SEQ_4 4 ++ ++/* 7.3.1.3 Beacon Interval field */ ++#define BEACON_INTERVAL_FIELD_LEN 2 ++ ++/* 7.3.1.4 Capability Information field */ ++#define CAP_INFO_FIELD_LEN 2 ++#define CAP_INFO_ESS BIT(0) ++#define CAP_INFO_IBSS BIT(1) ++#define CAP_INFO_BSS_TYPE (CAP_INFO_ESS | CAP_INFO_IBSS) ++#define CAP_INFO_CF_POLLABLE BIT(2) ++#define CAP_INFO_CF_POLL_REQ BIT(3) ++#define CAP_INFO_CF (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) ++#define CAP_INFO_PRIVACY BIT(4) ++#define CAP_INFO_SHORT_PREAMBLE BIT(5) ++#define CAP_INFO_PBCC BIT(6) ++#define CAP_INFO_CH_AGILITY BIT(7) ++#define CAP_INFO_SPEC_MGT BIT(8) ++#define CAP_INFO_QOS BIT(9) ++#define CAP_INFO_SHORT_SLOT_TIME BIT(10) ++#define CAP_INFO_APSD BIT(11) ++#define CAP_INFO_RESERVED BIT(12) ++#define CAP_INFO_DSSS_OFDM BIT(13) ++#define CAP_INFO_DELAYED_BLOCK_ACK BIT(14) ++#define CAP_INFO_IMM_BLOCK_ACK BIT(15) ++/* STA usage of CF-Pollable and CF-Poll Request subfields */ ++/* STA: not CF-Pollable */ ++#define CAP_CF_STA_NOT_POLLABLE 0x0000 ++/* STA: CF-Pollable, not requesting on the CF-Polling list */ ++#define CAP_CF_STA_NOT_ON_LIST CAP_INFO_CF_POLL_REQ ++/* STA: CF-Pollable, requesting on the CF-Polling list */ ++#define CAP_CF_STA_ON_LIST CAP_INFO_CF_POLLABLE ++/* STA: CF-Pollable, requesting never to be polled */ ++#define CAP_CF_STA_NEVER_POLLED (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) ++ ++/* AP usage of CF-Pollable and CF-Poll Request subfields */ ++/* AP: No point coordinator (PC) */ ++#define CAP_CF_AP_NO_PC 0x0000 ++/* AP: PC at AP for delivery only (no polling) */ ++#define CAP_CF_AP_DELIVERY_ONLY CAP_INFO_CF_POLL_REQ ++/* AP: PC at AP for delivery and polling */ ++#define CAP_CF_AP_DELIVERY_POLLING CAP_INFO_CF_POLLABLE ++ ++/* 7.3.1.5 Current AP Address field */ ++#define CURR_AP_ADDR_FIELD_LEN MAC_ADDR_LEN ++ ++/* 7.3.1.6 Listen Interval field */ ++#define LISTEN_INTERVAL_FIELD_LEN 2 ++ ++/* 7.3.1.7 Reason Code field */ ++#define REASON_CODE_FIELD_LEN 2 ++ ++#define REASON_CODE_RESERVED 0 /* Reseved */ ++#define REASON_CODE_UNSPECIFIED 1 /* Unspecified reason */ ++#define REASON_CODE_PREV_AUTH_INVALID 2 /* Previous auth no longer valid */ ++#define REASON_CODE_DEAUTH_LEAVING_BSS 3 /* Deauth because sending STA is leaving BSS */ ++#define REASON_CODE_DISASSOC_INACTIVITY 4 /* Disassoc due to inactivity */ ++#define REASON_CODE_DISASSOC_AP_OVERLOAD 5 /* Disassoc because AP is unable to handle all assoc STAs */ ++#define REASON_CODE_CLASS_2_ERR 6 /* Class 2 frame rx from nonauth STA */ ++#define REASON_CODE_CLASS_3_ERR 7 /* Class 3 frame rx from nonassoc STA */ ++#define REASON_CODE_DISASSOC_LEAVING_BSS 8 /* Disassoc because sending STA is leaving BSS */ ++#define REASON_CODE_ASSOC_BEFORE_AUTH 9 /* STA requesting (re)assoc is not auth with responding STA */ ++#define REASON_CODE_DISASSOC_PWR_CAP_UNACCEPTABLE 10 /* Disassoc because the info in Power Capability is ++ unacceptable */ ++#define REASON_CODE_DISASSOC_SUP_CHS_UNACCEPTABLE 11 /* Disassoc because the info in Supported Channels is ++ unacceptable */ ++#define REASON_CODE_INVALID_INFO_ELEM 13 /* Invalid information element */ ++#define REASON_CODE_MIC_FAILURE 14 /* MIC failure */ ++#define REASON_CODE_4_WAY_HANDSHAKE_TIMEOUT 15 /* 4-way handshake timeout */ ++#define REASON_CODE_GROUP_KEY_UPDATE_TIMEOUT 16 /* Group key update timeout */ ++#define REASON_CODE_DIFFERENT_INFO_ELEM 17 /* Info element in 4-way handshake different from ++ (Re-)associate request/Probe response/Beacon */ ++#define REASON_CODE_MULTICAST_CIPHER_NOT_VALID 18 /* Multicast Cipher is not valid */ ++#define REASON_CODE_UNICAST_CIPHER_NOT_VALID 19 /* Unicast Cipher is not valid */ ++#define REASON_CODE_AKMP_NOT_VALID 20 /* AKMP is not valid */ ++#define REASON_CODE_UNSUPPORTED_RSNE_VERSION 21 /* Unsupported RSNE version */ ++#define REASON_CODE_INVALID_RSNE_CAPABILITIES 22 /* Invalid RSNE Capabilities */ ++#define REASON_CODE_IEEE_802_1X_AUTH_FAILED 23 /* IEEE 802.1X Authentication failed */ ++#define REASON_CODE_CIPHER_REJECT_SEC_POLICY 24 /* Cipher suite rejected because of the security policy */ ++#define REASON_CODE_DISASSOC_UNSPECIFIED_QOS 32 /* Disassoc for unspecified, QoS-related reason */ ++#define REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH 33 /* Disassoc because QAP lacks sufficient bandwidth ++ for this QSTA */ ++#define REASON_CODE_DISASSOC_ACK_LOST_POOR_CHANNEL 34 /* Disassoc because of too many ACKs lost for AP transmissions ++ and/or poor channel conditions */ ++#define REASON_CODE_DISASSOC_TX_OUTSIDE_TXOP_LIMIT 35 /* Disassoc because QSTA is transmitting outside the limits of ++ its TXOPs */ ++#define REASON_CODE_PEER_WHILE_LEAVING 36 /* QSTA is leaving the QBSS or resetting */ ++#define REASON_CODE_PEER_REFUSE_DLP 37 /* Peer does not want to use this mechanism */ ++#define REASON_CODE_PEER_SETUP_REQUIRED 38 /* Frames received but a setup is reqired */ ++#define REASON_CODE_PEER_TIME_OUT 39 /* Time out */ ++#define REASON_CODE_PEER_CIPHER_UNSUPPORTED 45 /* Peer does not support the requested cipher suite */ ++#define REASON_CODE_BEACON_TIMEOUT 100 /* for beacon timeout, defined by mediatek */ ++#define REASON_CODE_BSS_SECURITY_CHANGE 101 /* for BSS security change, defined by mediatek */ ++/* 7.3.1.8 AID field */ ++#define AID_FIELD_LEN 2 ++#define AID_MASK BITS(0, 13) ++#define AID_MSB BITS(14, 15) ++#define AID_MIN_VALUE 1 ++#define AID_MAX_VALUE 2007 ++ ++/* 7.3.1.9 Status Code field */ ++#define STATUS_CODE_FIELD_LEN 2 ++ ++#define STATUS_CODE_RESERVED 0 /* Reserved - Used by TX Auth */ ++#define STATUS_CODE_SUCCESSFUL 0 /* Successful */ ++#define STATUS_CODE_UNSPECIFIED_FAILURE 1 /* Unspecified failure */ ++#define STATUS_CODE_CAP_NOT_SUPPORTED 10 /* Cannot support all requested cap in the Cap Info field */ ++#define STATUS_CODE_REASSOC_DENIED_WITHOUT_ASSOC 11 /* Reassoc denied due to inability to confirm that ++ assoc exists */ ++#define STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD 12 /* Assoc denied due to reason outside the scope of this std. */ ++#define STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED 13 /* Responding STA does not support the specified ++ auth algorithm */ ++#define STATUS_CODE_AUTH_OUT_OF_SEQ 14 /* Rx an auth frame with auth transaction seq num ++ out of expected seq */ ++#define STATUS_CODE_AUTH_REJECTED_CHAL_FAIL 15 /* Auth rejected because of challenge failure */ ++#define STATUS_CODE_AUTH_REJECTED_TIMEOUT 16 /* Auth rejected due to timeout waiting for next frame ++ in sequence */ ++#define STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD 17 /* Assoc denied because AP is unable to handle additional ++ assoc STAs */ ++#define STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED 18 /* Assoc denied due to requesting STA not supporting ++ all of basic rates */ ++#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_PREAMBLE 19 /* Assoc denied due to requesting STA not supporting short ++ preamble */ ++#define STATUS_CODE_ASSOC_DENIED_NO_PBCC 20 /* Assoc denied due to requesting STA not supporting PBCC */ ++#define STATUS_CODE_ASSOC_DENIED_NO_CH_AGILITY 21 /* Assoc denied due to requesting STA not supporting channel ++ agility */ ++#define STATUS_CODE_ASSOC_REJECTED_NO_SPEC_MGT 22 /* Assoc rejected because Spectrum Mgt capability is required */ ++#define STATUS_CODE_ASSOC_REJECTED_PWR_CAP 23 /* Assoc rejected because the info in Power Capability ++ is unacceptable */ ++#define STATUS_CODE_ASSOC_REJECTED_SUP_CHS 24 /* Assoc rejected because the info in Supported Channels ++ is unacceptable */ ++#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 /* Assoc denied due to requesting STA not supporting ++ short slot time */ ++#define STATUS_CODE_ASSOC_DENIED_NO_DSSS_OFDM 26 /* Assoc denied due to requesting STA not supporting ++ DSSS-OFDM */ ++#if CFG_SUPPORT_802_11W ++#define STATUS_CODE_ASSOC_REJECTED_TEMPORARILY 30 /* IEEE 802.11w, Assoc denied due to the SA query */ ++#define STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 /* IEEE 802.11w, Assoc denied due to the MFP select ++ policy */ ++#endif ++#define STATUS_CODE_UNSPECIFIED_QOS_FAILURE 32 /* Unspecified, QoS-related failure */ ++#define STATUS_CODE_ASSOC_DENIED_BANDWIDTH 33 /* Assoc denied due to insufficient bandwidth to handle another ++ QSTA */ ++#define STATUS_CODE_ASSOC_DENIED_POOR_CHANNEL 34 /* Assoc denied due to excessive frame loss rates and/or poor ++ channel conditions */ ++#define STATUS_CODE_ASSOC_DENIED_NO_QOS_FACILITY 35 /* Assoc denied due to requesting STA not supporting QoS ++ facility */ ++#define STATUS_CODE_REQ_DECLINED 37 /* Request has been declined */ ++#define STATUS_CODE_REQ_INVALID_PARAMETER_VALUE 38 /* Request has not been successful as one or more parameters ++ have invalid values */ ++#define STATUS_CODE_REQ_NOT_HONORED_TSPEC 39 /* TS not created because request cannot be honored. ++ Suggested TSPEC provided. */ ++#define STATUS_CODE_INVALID_INFO_ELEMENT 40 /* Invalid information element */ ++#define STATUS_CODE_INVALID_GROUP_CIPHER 41 /* Invalid group cipher */ ++#define STATUS_CODE_INVALID_PAIRWISE_CIPHER 42 /* Invalid pairwise cipher */ ++#define STATUS_CODE_INVALID_AKMP 43 /* Invalid AKMP */ ++#define STATUS_CODE_UNSUPPORTED_RSN_IE_VERSION 44 /* Unsupported RSN information element version */ ++#define STATUS_CODE_INVALID_RSN_IE_CAP 45 /* Invalid RSN information element capabilities */ ++#define STATUS_CODE_CIPHER_SUITE_REJECTED 46 /* Cipher suite rejected because of security policy */ ++#define STATUS_CODE_REQ_NOT_HONORED_TS_DELAY 47 /* TS not created because request cannot be honored. ++ Attempt to create a TS later. */ ++#define STATUS_CODE_DIRECT_LINK_NOT_ALLOWED 48 /* Direct Link is not allowed in the BSS by policy */ ++#define STATUS_CODE_DESTINATION_STA_NOT_PRESENT 49 /* Destination STA is not present within this QBSS */ ++#define STATUS_CODE_DESTINATION_STA_NOT_QSTA 50 /* Destination STA is not a QSTA */ ++#define STATUS_CODE_ASSOC_DENIED_LARGE_LIS_INTERVAL 51 /* Association denied because the ListenInterval is too large */ ++ ++/* proprietary definition of reserved field of Status Code */ ++#define STATUS_CODE_JOIN_FAILURE 0xFFF0 /* Join failure */ ++#define STATUS_CODE_JOIN_TIMEOUT 0xFFF1 /* Join timeout */ ++#define STATUS_CODE_AUTH_TIMEOUT 0xFFF2 /* Authentication timeout */ ++#define STATUS_CODE_ASSOC_TIMEOUT 0xFFF3 /* (Re)Association timeout */ ++#define STATUS_CODE_CCX_CCKM_REASSOC_FAILURE 0xFFF4 /* CCX CCKM reassociation failure */ ++ ++/* 7.3.1.10 Timestamp field */ ++#define TIMESTAMP_FIELD_LEN 8 ++ ++/* 7.3.1.11 Category of Action field */ ++#define CATEGORY_SPEC_MGT 0 ++#define CATEGORY_QOS_ACTION 1 /* QoS action */ ++#define CATEGORY_DLS_ACTION 2 /* Direct Link Protocol (DLP) action */ ++#define CATEGORY_BLOCK_ACK_ACTION 3 /* Block ack action */ ++#define CATEGORY_PUBLIC_ACTION 4 /* Public action */ ++#define CATEGORY_RM_ACTION 5 /* Radio measurement action */ ++#define CATEGORY_HT_ACTION 7 ++#if CFG_SUPPORT_802_11W ++#define CATEGORY_SA_QUERT_ACTION 8 ++#endif ++#define CATEGORY_WNM_ACTION 10 /* 802.11v Wireless Network Management */ ++#define CATEGORY_UNPROTECTED_WNM_ACTION 11 /* 802.11v Wireless Network Management */ ++#define CATEGORY_WME_MGT_NOTIFICATION 17 /* WME management notification */ ++#define CATEGORY_VENDOR_SPECIFIC_ACTION 127 ++ ++/* 7.3.1.14 Block Ack Parameter Set field */ ++#define BA_PARAM_SET_ACK_POLICY_MASK BIT(1) ++#define BA_PARAM_SET_ACK_POLICY_MASK_OFFSET 1 ++#define BA_PARAM_SET_TID_MASK BITS(2, 5) ++#define BA_PARAM_SET_TID_MASK_OFFSET 2 ++#define BA_PARAM_SET_BUFFER_SIZE_MASK BITS(6, 15) ++#define BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET 6 ++ ++#define BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA 1 ++#define BA_PARAM_SET_ACK_POLICY_DELAYED_BA 0 ++ ++/* 3 Management frame body components (II): Information Elements. */ ++/* 7.3.2 Element IDs of information elements */ ++#define ELEM_HDR_LEN 2 ++ ++#define ELEM_ID_SSID 0 /* SSID */ ++#define ELEM_ID_SUP_RATES 1 /* Supported rates */ ++#define ELEM_ID_FH_PARAM_SET 2 /* FH parameter set */ ++#define ELEM_ID_DS_PARAM_SET 3 /* DS parameter set */ ++#define ELEM_ID_CF_PARAM_SET 4 /* CF parameter set */ ++#define ELEM_ID_TIM 5 /* TIM */ ++#define ELEM_ID_IBSS_PARAM_SET 6 /* IBSS parameter set */ ++#define ELEM_ID_COUNTRY_INFO 7 /* Country information */ ++#define ELEM_ID_HOPPING_PATTERN_PARAM 8 /* Hopping pattern parameters */ ++#define ELEM_ID_HOPPING_PATTERN_TABLE 9 /* Hopping pattern table */ ++#define ELEM_ID_REQUEST 10 /* Request */ ++#define ELEM_ID_BSS_LOAD 11 /* BSS load */ ++#define ELEM_ID_EDCA_PARAM_SET 12 /* EDCA parameter set */ ++#define ELEM_ID_TSPEC 13 /* Traffic specification (TSPEC) */ ++#define ELEM_ID_TCLAS 14 /* Traffic classification (TCLAS) */ ++#define ELEM_ID_SCHEDULE 15 /* Schedule */ ++#define ELEM_ID_CHALLENGE_TEXT 16 /* Challenge text */ ++ ++#define ELEM_ID_PWR_CONSTRAINT 32 /* Power constraint */ ++#define ELEM_ID_PWR_CAP 33 /* Power capability */ ++#define ELEM_ID_TPC_REQ 34 /* TPC request */ ++#define ELEM_ID_TPC_REPORT 35 /* TPC report */ ++#define ELEM_ID_SUP_CHS 36 /* Supported channels */ ++#define ELEM_ID_CH_SW_ANNOUNCEMENT 37 /* Channel switch announcement */ ++#define ELEM_ID_MEASUREMENT_REQ 38 /* Measurement request */ ++#define ELEM_ID_MEASUREMENT_REPORT 39 /* Measurement report */ ++#define ELEM_ID_QUIET 40 /* Quiet */ ++#define ELEM_ID_IBSS_DFS 41 /* IBSS DFS */ ++#define ELEM_ID_ERP_INFO 42 /* ERP information */ ++#define ELEM_ID_TS_DELAY 43 /* TS delay */ ++#define ELEM_ID_TCLAS_PROCESSING 44 /* TCLAS processing */ ++#define ELEM_ID_HT_CAP 45 /* HT Capabilities subelement */ ++#define ELEM_ID_QOS_CAP 46 /* QoS capability */ ++#define ELEM_ID_RSN 48 /* RSN IE */ ++#define ELEM_ID_EXTENDED_SUP_RATES 50 /* Extended supported rates */ ++#define ELEM_ID_TIMEOUT_INTERVAL 56 /* 802.11w SA Timeout interval */ ++#define ELEM_ID_SUP_OPERATING_CLASS 59 /* Supported Operating Classes */ ++#define ELEM_ID_HT_OP 61 /* HT Operation */ ++#define ELEM_ID_SCO 62 /* Secondary Channel Offset */ ++#define ELEM_ID_RRM_ENABLED_CAP 70 /* Radio Resource Management Enabled Capabilities */ ++#define ELEM_ID_20_40_BSS_COEXISTENCE 72 /* 20/40 BSS Coexistence */ ++#define ELEM_ID_20_40_INTOLERANT_CHNL_REPORT 73 /* 20/40 BSS Intolerant Channel Report */ ++#define ELEM_ID_OBSS_SCAN_PARAMS 74 /* Overlapping BSS Scan Parameters */ ++#define ELEM_ID_INTERWORKING 107 /* Interworking with External Network */ ++#define ELEM_ID_ADVERTISEMENT_PROTOCOL 108 /* Advertisement Protocol */ ++#define ELEM_ID_ROAMING_CONSORTIUM 111 /* Roaming Consortium */ ++#define ELEM_ID_EXTENDED_CAP 127 /* Extended capabilities */ ++ ++#define ELEM_ID_VENDOR 221 /* Vendor specific IE */ ++#define ELEM_ID_WPA ELEM_ID_VENDOR /* WPA IE */ ++#define ELEM_ID_WMM ELEM_ID_VENDOR /* WMM IE */ ++#define ELEM_ID_P2P ELEM_ID_VENDOR /* WiFi Direct */ ++#define ELEM_ID_WFD ELEM_ID_VENDOR /* WiFi Direct */ ++#define ELEM_ID_WSC ELEM_ID_VENDOR /* WSC IE */ ++ ++#define ELEM_ID_RESERVED 255 /* Reserved */ ++ ++/* 7.3.2.1 SSID element */ ++#define ELEM_MAX_LEN_SSID 32 ++ ++/* 7.3.2.2 Supported Rates */ ++#define ELEM_MAX_LEN_SUP_RATES 8 ++ ++/* 7.3.2.4 DS Parameter Set */ ++#define ELEM_MAX_LEN_DS_PARAMETER_SET 1 ++ ++/* 7.3.2.5 CF Parameter Set */ ++#define ELEM_CF_PARM_LEN 8 ++ ++/* 7.3.2.6 TIM */ ++#define ELEM_MIX_LEN_TIM 4 ++#define ELEM_MAX_LEN_TIM 254 ++ ++/* 7.3.2.7 IBSS Parameter Set element */ ++#define ELEM_MAX_LEN_IBSS_PARAMETER_SET 2 ++ ++/* 7.3.2.8 Challenge Text element */ ++#define ELEM_MIN_LEN_CHALLENGE_TEXT 1 ++#define ELEM_MAX_LEN_CHALLENGE_TEXT 253 ++ ++/* 7.3.2.9 Country Information element */ ++/* Country IE should contain at least 3-bytes country code string and one subband triplet. */ ++#define ELEM_MIN_LEN_COUNTRY_INFO 6 ++ ++#define ELEM_ID_COUNTRY_INFO_TRIPLET_LEN_FIXED 3 ++#define ELEM_ID_COUNTRY_INFO_SUBBAND_TRIPLET_LEN_FIXED 3 ++#define ELEM_ID_COUNTRY_INFO_REGULATORY_TRIPLET_LEN_FIXED 3 ++ ++/* 7.3.2.13 ERP Information element */ ++#define ELEM_MAX_LEN_ERP 1 ++/* -- bits in the ERP Information element */ ++#define ERP_INFO_NON_ERP_PRESENT BIT(0) /* NonERP_Present bit */ ++#define ERP_INFO_USE_PROTECTION BIT(1) /* Use_Protection bit */ ++#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) /* Barker_Preamble_Mode bit */ ++ ++/* 7.3.2.14 Extended Supported Rates */ ++#define ELEM_MAX_LEN_EXTENDED_SUP_RATES 255 ++ ++#if CFG_SUPPORT_DFS ++/* 7.3.2.19 Supported Channels element */ ++#define ELEM_MAX_LEN_SUPPORTED_CHANNELS 7 ++#endif ++ ++/* 7.3.2.21 Measurement Request element */ ++#define ELEM_RM_TYPE_BASIC_REQ 0 ++#define ELEM_RM_TYPE_CCA_REQ 1 ++#define ELEM_RM_TYPE_RPI_HISTOGRAM_REQ 2 ++#define ELEM_RM_TYPE_CHNL_LOAD_REQ 3 ++#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REQ 4 ++#define ELEM_RM_TYPE_BEACON_REQ 5 ++#define ELEM_RM_TYPE_FRAME_REQ 6 ++#define ELEM_RM_TYPE_STA_STATISTICS_REQ 7 ++#define ELEM_RM_TYPE_LCI_REQ 8 ++#define ELEM_RM_TYPE_TS_REQ 9 ++#define ELEM_RM_TYPE_MEASURE_PAUSE_REQ 255 ++ ++/* 7.3.2.22 Measurement Report element */ ++#define ELEM_RM_TYPE_BASIC_REPORT 0 ++#define ELEM_RM_TYPE_CCA_REPORT 1 ++#define ELEM_RM_TYPE_RPI_HISTOGRAM_REPORT 2 ++#define ELEM_RM_TYPE_CHNL_LOAD_REPORT 3 ++#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REPORT 4 ++#define ELEM_RM_TYPE_BEACON_REPORT 5 ++#define ELEM_RM_TYPE_FRAME_REPORT 6 ++#define ELEM_RM_TYPE_STA_STATISTICS_REPORT 7 ++#define ELEM_RM_TYPE_LCI_REPORT 8 ++#define ELEM_RM_TYPE_TS_REPORT 9 ++/*Auto Channel Selection*/ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++#define ELEM_RM_TYPE_ACS_CHN 1 ++#define ELEM_RM_TYPE_LTE_CHN 2 ++#endif ++ ++/* 7.3.2.25 RSN information element */ ++#define ELEM_MAX_LEN_WPA 34 /* one pairwise, one AKM suite, one PMKID */ ++#define ELEM_MAX_LEN_RSN 38 /* one pairwise, one AKM suite, one PMKID */ ++#define ELEM_MAX_LEN_WAPI 38 /* one pairwise, one AKM suite, one BKID */ ++#define ELEM_MAX_LEN_WSC 200 /* one pairwise, one AKM suite, one BKID */ ++ ++#if CFG_SUPPORT_802_11W ++#define ELEM_WPA_CAP_MFPR BIT(6) ++#define ELEM_WPA_CAP_MFPC BIT(7) ++#endif ++ ++/* 7.3.2.27 Extended Capabilities information element */ ++#define ELEM_EXT_CAP_20_40_COEXIST_SUPPORT BIT(0) ++#define ELEM_EXT_CAP_PSMP_CAP BIT(4) ++#define ELEM_EXT_CAP_SERVICE_INTERVAL_GRANULARITY BIT(5) ++#define ELEM_EXT_CAP_SCHEDULE_PSMP BIT(6) ++ ++#define ELEM_EXT_CAP_BSS_TRANSITION_BIT 19 ++#define ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT 27 ++#define ELEM_EXT_CAP_INTERWORKING_BIT 31 ++#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT 46 ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++#define ELEM_MAX_LEN_EXT_CAP (6) ++#else ++#define ELEM_MAX_LEN_EXT_CAP (3 - ELEM_HDR_LEN) ++#endif ++ ++/* 7.3.2.30 TSPEC element */ ++#define TS_INFO_TRAFFIC_TYPE_MASK BIT(0) /* WMM: 0 (Asynchronous TS of low-duty cycles) */ ++#define TS_INFO_TID_OFFSET 1 ++#define TS_INFO_TID_MASK BITS(1, 4) ++#define TS_INFO_DIRECTION_OFFSET 5 ++#define TS_INFO_DIRECTION_MASK BITS(5, 6) ++#define TS_INFO_ACCESS_POLICY_OFFSET 7 ++#define TS_INFO_ACCESS_POLICY_MASK BITS(7, 8) ++#define TS_INFO_AGGREGATION_MASK BIT(9) /* WMM: 0 */ ++#define TS_INFO_APSD_MASK BIT(10) ++#define TS_INFO_UP_OFFSET 11 ++#define TS_INFO_UP_MASK BITS(11, 13) ++#define TS_INFO_ACK_POLICY_OFFSET 14 ++#define TS_INFO_ACK_POLICY_MASK BITS(14, 15) ++#define TS_INFO_SCHEDULE_MASK 16 ++ ++/* 7.3.2.56 HT capabilities element */ ++#define ELEM_MAX_LEN_HT_CAP (28 - ELEM_HDR_LEN) /* sizeof(IE_HT_CAP_T)-2 */ ++ ++/* 7.3.2.56.2 HT capabilities Info field */ ++#define HT_CAP_INFO_LDPC_CAP BIT(0) ++#define HT_CAP_INFO_SUP_CHNL_WIDTH BIT(1) ++#define HT_CAP_INFO_SM_POWER_SAVE BITS(2, 3) ++#define HT_CAP_INFO_HT_GF BIT(4) ++#define HT_CAP_INFO_SHORT_GI_20M BIT(5) ++#define HT_CAP_INFO_SHORT_GI_40M BIT(6) ++#define HT_CAP_INFO_TX_STBC BIT(7) ++#define HT_CAP_INFO_RX_STBC BITS(8, 9) ++#define HT_CAP_INFO_HT_DELAYED_BA BIT(10) ++#define HT_CAP_INFO_MAX_AMSDU_LEN BIT(11) ++#define HT_CAP_INFO_DSSS_CCK_IN_40M BIT(12) ++#define HT_CAP_INFO_40M_INTOLERANT BIT(14) ++#define HT_CAP_INFO_LSIG_TXOP_SUPPORT BIT(15) ++ ++#define HT_CAP_INFO_RX_STBC_NO_SUPPORTED 0 ++#define HT_CAP_INFO_RX_STBC_1_SS BIT(8) ++#define HT_CAP_INFO_RX_STBC_2_SS BIT(9) ++#define HT_CAP_INFO_RX_STBC_3_SS HT_CAP_INFO_RX_STBC ++ ++/* 7.3.2.56.3 A-MPDU Parameters field */ ++#define AMPDU_PARAM_MAX_AMPDU_LEN_EXP BITS(0, 1) ++#define AMPDU_PARAM_MIN_START_SPACING BITS(2, 4) ++ ++#define AMPDU_PARAM_MAX_AMPDU_LEN_8K 0 ++#define AMPDU_PARAM_MAX_AMPDU_LEN_16K BIT(0) ++#define AMPDU_PARAM_MAX_AMPDU_LEN_32K BIT(1) ++#define AMPDU_PARAM_MAX_AMPDU_LEN_64K BITS(0, 1) ++ ++#define AMPDU_PARAM_MSS_NO_RESTRICIT 0 ++#define AMPDU_PARAM_MSS_1_4_US BIT(2) ++#define AMPDU_PARAM_MSS_1_2_US BIT(3) ++#define AMPDU_PARAM_MSS_1_US BITS(2, 3) ++#define AMPDU_PARAM_MSS_2_US BIT(4) ++#define AMPDU_PARAM_MSS_4_US (BIT(4) | BIT(2)) ++#define AMPDU_PARAM_MSS_8_US (BIT(4) | BIT(3)) ++#define AMPDU_PARAM_MSS_16_US BITS(2, 4) ++ ++/* 7.3.2.56.4 Supported MCS Set field (TX rate: octects 12~15) */ ++#define SUP_MCS_TX_SET_DEFINED BIT(0) ++#define SUP_MCS_TX_RX_SET_NOT_EQUAL BIT(1) ++#define SUP_MCS_TX_MAX_NUM_SS BITS(2, 3) ++#define SUP_MCS_TX_UNEQUAL_MODULATION BIT(4) ++ ++#define SUP_MCS_TX_MAX_NUM_1_SS 0 ++#define SUP_MCS_TX_MAX_NUM_2_SS BIT(2) ++#define SUP_MCS_TX_MAX_NUM_3_SS BIT(3) ++#define SUP_MCS_TX_MAX_NUM_4_SS BITS(2, 3) ++ ++#define SUP_MCS_RX_BITMASK_OCTET_NUM 10 ++#define SUP_MCS_RX_DEFAULT_HIGHEST_RATE 0 /* Not specify */ ++ ++/* 7.3.2.56.5 HT Extended Capabilities field */ ++#define HT_EXT_CAP_PCO BIT(0) ++#define HT_EXT_CAP_PCO_TRANSITION_TIME BITS(1, 2) ++#define HT_EXT_CAP_MCS_FEEDBACK BITS(8, 9) ++#define HT_EXT_CAP_HTC_SUPPORT BIT(10) ++#define HT_EXT_CAP_RD_RESPONDER BIT(11) ++ ++#define HT_EXT_CAP_PCO_TRANS_TIME_NONE 0 ++#define HT_EXT_CAP_PCO_TRANS_TIME_400US BIT(1) ++#define HT_EXT_CAP_PCO_TRANS_TIME_1_5MS BIT(2) ++#define HT_EXT_CAP_PCO_TRANS_TIME_5MS BITS(1, 2) ++ ++#define HT_EXT_CAP_MCS_FEEDBACK_NO_FB 0 ++#define HT_EXT_CAP_MCS_FEEDBACK_UNSOLICITED BIT(9) ++#define HT_EXT_CAP_MCS_FEEDBACK_BOTH BITS(8, 9) ++ ++/* 7.3.2.56.6 Transmit Beamforming Capabilities field */ ++ ++/* 7.3.2.56.7 Antenna Selection Capability field */ ++#define ASEL_CAP_CAPABLE BIT(0) ++#define ASEL_CAP_CSI_FB_BY_TX_ASEL_CAPABLE BIT(1) ++#define ASEL_CAP_ANT_INDICES_FB_BY_TX_ASEL_CAPABLE BIT(2) ++#define ASEL_CAP_EXPLICIT_CSI_FB_CAPABLE BIT(3) ++#define ASEL_CAP_ANT_INDICES_CAPABLE BIT(4) ++#define ASEL_CAP_RX_ASEL_CAPABLE BIT(5) ++#define ASEL_CAP_TX_SOUNDING_CAPABLE BIT(6) ++ ++/* 7.3.2.57 HT Operation element */ ++#define ELEM_MAX_LEN_HT_OP (24 - ELEM_HDR_LEN) /* sizeof(IE_HT_OP_T)-2 */ ++ ++#define HT_OP_INFO1_SCO BITS(0, 1) ++#define HT_OP_INFO1_STA_CHNL_WIDTH BIT(2) ++#define HT_OP_INFO1_RIFS_MODE BIT(3) ++ ++#define HT_OP_INFO2_HT_PROTECTION BITS(0, 1) ++#define HT_OP_INFO2_NON_GF_HT_STA_PRESENT BIT(2) ++#define HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT BIT(4) ++ ++#define HT_OP_INFO3_DUAL_BEACON BIT(6) ++#define HT_OP_INFO3_DUAL_CTS_PROTECTION BIT(7) ++#define HT_OP_INFO3_STBC_BEACON BIT(8) ++#define HT_OP_INFO3_LSIG_TXOP_FULL_SUPPORT BIT(9) ++#define HT_OP_INFO3_PCO_ACTIVE BIT(10) ++#define HT_OP_INFO3_PCO_PHASE BIT(11) ++ ++/* 7.3.2.59 OBSS Scan Parameter element */ ++#define ELEM_MAX_LEN_OBSS_SCAN (16 - ELEM_HDR_LEN) ++ ++/* 7.3.2.60 20/40 BSS Coexistence element */ ++#define ELEM_MAX_LEN_20_40_BSS_COEXIST (3 - ELEM_HDR_LEN) ++ ++#define BSS_COEXIST_INFO_REQ BIT(0) ++#define BSS_COEXIST_40M_INTOLERANT BIT(1) ++#define BSS_COEXIST_20M_REQ BIT(2) ++#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ BIT(3) ++#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_GRANT BIT(4) ++ ++/* 802.11u 7.3.2.92 Interworking IE */ ++#define ELEM_MAX_LEN_INTERWORKING (11 - ELEM_HDR_LEN) ++ ++/* 802.11u 7.3.2.93 Advertisement Protocol IE */ ++#define ELEM_MAX_LEN_ADV_PROTOCOL (4 - ELEM_HDR_LEN) ++ ++/* 802.11u 7.3.2.96 Roaming Consortium IE */ ++#define ELEM_MAX_LEN_ROAMING_CONSORTIUM (19 - ELEM_HDR_LEN) ++ ++#define IW_IE_LENGTH_ANO 1 ++#define IW_IE_LENGTH_ANO_VENUE 3 ++#define IW_IE_LENGTH_ANO_HESSID 7 ++#define IW_IE_LENGTH_ANO_VENUE_HESSID 9 ++ ++/* 3 Management frame body components (III): 7.4 Action frame format details. */ ++/* 7.4.1 Spectrum Measurement Action frame details */ ++#define ACTION_MEASUREMENT_REQ 0 /* Spectrum measurement request */ ++#define ACTION_MEASUREMENT_REPORT 1 /* Spectrum measurement report */ ++#define ACTION_TPC_REQ 2 /* TPC request */ ++#define ACTION_TPC_REPORT 3 /* TPC report */ ++#define ACTION_CHNL_SWITCH 4 /* Channel Switch Announcement */ ++ ++/* 7.4.2 QoS Action frame details */ ++#define ACTION_ADDTS_REQ 0 /* ADDTS request */ ++#define ACTION_ADDTS_RSP 1 /* ADDTS response */ ++#define ACTION_DELTS 2 /* DELTS */ ++#define ACTION_SCHEDULE 3 /* Schedule */ ++ ++#define ACTION_ADDTS_REQ_FRAME_LEN (24+3+63) /* WMM TSPEC IE: 63 */ ++#define ACTION_ADDTS_RSP_FRAME_LEN (24+4+63) /* WMM Status Code: 1; WMM TSPEC IE: 63 */ ++ ++/* 7.4.3 DLS Action frame details */ ++#define ACTION_DLS_REQ 0 /* DLS request */ ++#define ACTION_DLS_RSP 1 /* DLS response */ ++#define ACTION_DLS_TEARDOWN 2 /* DLS teardown */ ++ ++/* 7.4.4 Block ack Action frame details */ ++#define ACTION_ADDBA_REQ 0 /* ADDBA request */ ++#define ACTION_ADDBA_RSP 1 /* ADDBA response */ ++#define ACTION_DELBA 2 /* DELBA */ ++ ++#define ACTION_ADDBA_REQ_FRAME_LEN (24+9) ++#define ACTION_ADDBA_RSP_FRAME_LEN (24+9) ++ ++#define ACTION_DELBA_INITIATOR_MASK BIT(11) ++#define ACTION_DELBA_TID_MASK BITS(12, 15) ++#define ACTION_DELBA_TID_OFFSET 12 ++#define ACTION_DELBA_FRAME_LEN (24+6) ++ ++/* 7.4.6 Radio Measurement Action frame details */ ++#define ACTION_RM_REQ 0 /* Radio measurement request */ ++#define ACTION_RM_REPORT 1 /* Radio measurement report */ ++#define ACTION_LM_REQ 2 /* Link measurement request */ ++#define ACTION_LM_REPORT 3 /* Link measurement report */ ++#define ACTION_NEIGHBOR_REPORT_REQ 4 /* Neighbor report request */ ++#define ACTION_NEIGHBOR_REPORT_RSP 5 /* Neighbor report response */ ++ ++/* 7.4.7 Public Action frame details */ ++#define ACTION_PUBLIC_20_40_COEXIST 0 /* 20/40 BSS coexistence */ ++ ++#if CFG_SUPPORT_802_11W ++/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ ++#define ACTION_SA_QUERY_REQUEST 0 ++#define ACTION_SA_QUERY_RESPONSE 1 ++ ++#define ACTION_SA_QUERY_TR_ID_LEN 2 ++ ++/* Timeout Interval Type */ ++#define ACTION_SA_TIMEOUT_REASSOC_DEADLINE 1 ++#define ACTION_SA_TIMEOUT_KEY_LIFETIME 2 ++#define ACTION_SA_TIMEOUT_ASSOC_COMEBACK 3 ++#endif ++ ++/* 7.4.10.1 HT action frame details */ ++#define ACTION_HT_NOTIFY_CHANNEL_WIDTH 0 /* Notify Channel Width */ ++#define ACTION_HT_SM_POWER_SAVE 1 /* SM Power Save */ ++#define ACTION_HT_PSMP 2 /* PSMP */ ++#define ACTION_HT_SET_PCO_PHASE 3 /* Set PCO Phase */ ++#define ACTION_HT_CSI 4 /* CSI */ ++#define ACTION_HT_NON_COMPRESSED_BEAMFORM 5 /* Non-compressed Beamforming */ ++#define ACTION_HT_COMPRESSED_BEAMFORM 6 /* Compressed Beamforming */ ++#define ACTION_HT_ANT_SEL_INDICES_FB 7 /* Antenna Selection Indices Feedback */ ++ ++/* 802.11v Wireless Network Management */ ++#define ACTION_WNM_TIMING_MEASUREMENT_REQUEST 27 ++ ++#define ACTION_UNPROTECTED_WNM_TIM 0 ++#define ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT 1 ++ ++#define ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN 12 ++ ++/* 3 --------------- WFA frame body fields --------------- */ ++#define VENDOR_OUI_WFA { 0x00, 0x50, 0xF2 } ++#define VENDOR_OUI_WFA_SPECIFIC { 0x50, 0x6F, 0x9A } ++#define VENDOR_OUI_TYPE_WPA 1 ++#define VENDOR_OUI_TYPE_WMM 2 ++#define VENDOR_OUI_TYPE_WPS 4 ++#define VENDOR_OUI_TYPE_P2P 9 ++#define VENDOR_OUI_TYPE_WFD 10 ++#define VENDOR_OUI_TYPE_HS20 16 ++ ++#define VENDOR_OUI_TYPE_LEN 4 /* Length of OUI and Type */ ++ ++/* VERSION(2 octets for WPA) / SUBTYPE(1 octet)-VERSION(1 octet) fields for WMM in WFA IE */ ++#define VERSION_WPA 0x0001 /* Little Endian Format */ ++#define VENDOR_OUI_SUBTYPE_VERSION_WMM_INFO 0x0100 ++#define VENDOR_OUI_SUBTYPE_VERSION_WMM_PARAM 0x0101 ++ ++/* SUBTYPE(1 octet) for WMM */ ++#define VENDOR_OUI_SUBTYPE_WMM_INFO 0x00 /* WMM Spec version 1.1 */ ++#define VENDOR_OUI_SUBTYPE_WMM_PARAM 0x01 ++#define VENDOR_OUI_SUBTYPE_WMM_TSPEC 0x02 ++ ++/* VERSION(1 octet) for WMM */ ++#define VERSION_WMM 0x01 /* WMM Spec version 1.1 */ ++ ++/* WMM-2.1.6 QoS Control Field */ ++#define WMM_QC_UP_MASK BITS(0, 2) ++#define WMM_QC_EOSP BIT(4) ++#define WMM_QC_ACK_POLICY_MASK BITS(5, 6) ++#define WMM_QC_ACK_POLICY_OFFSET 5 ++#define WMM_QC_ACK_POLICY_ACKNOWLEDGE 0 ++#define WMM_QC_ACK_POLICY_NOT_ACKNOWLEDGE (1 << WMM_QC_ACK_POLICY_OFFSET) ++ ++/* WMM-2.2.1 WMM Information Element */ ++#define ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE 6 ++ ++/* HOTSPOT 2.0 Indication IE*/ ++#define ELEM_MAX_LEN_HS20_INDICATION 5 ++#define ELEM_MIN_LEN_HS20_INDICATION 4 ++ ++/* Hotspot Configuration*/ ++#define ELEM_HS_CONFIG_DGAF_DISABLED_MASK BIT(0) /* Downstream Group-Addressed Forwarding */ ++ ++/* 3 Control frame body */ ++/* 7.2.1.7 BlockAckReq */ ++#define CTRL_BAR_BAR_CONTROL_OFFSET 16 ++#define CTRL_BAR_BAR_INFORMATION_OFFSET 18 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack(1) ++#endif ++ ++typedef struct _LLC_SNAP_HEADER_T { ++ UINT_8 ucDSAP; ++ UINT_8 ucSSAP; ++ UINT_8 ucControl; ++ UINT_8 aucCode[3]; ++ UINT_16 u2Type; ++} __KAL_ATTRIB_PACKED__ LLC_SNAP_HEADER_T, *P_LLC_SNAP_HEADER_T; ++ ++/* 3 MAC Header. */ ++/* Ethernet Frame Header */ ++typedef struct _ETH_FRAME_HEADER_T { ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; ++ UINT_16 u2TypeLen; ++} __KAL_ATTRIB_PACKED__ ETH_FRAME_HEADER_T, *P_ETH_FRAME_HEADER_T; ++ ++/* Ethernet Frame Structure */ ++typedef struct _ETH_FRAME_T { ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; ++ UINT_16 u2TypeLen; ++ UINT_8 aucData[1]; ++} __KAL_ATTRIB_PACKED__ ETH_FRAME_T, *P_ETH_FRAME_T; ++ ++/* IEEE 802.11 WLAN Frame Structure */ ++/* WLAN MAC Header (without Address 4 and QoS Control fields) */ ++typedef struct _WLAN_MAC_HEADER_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_T, *P_WLAN_MAC_HEADER_T; ++ ++/* WLAN MAC Header (QoS Control fields included) */ ++typedef struct _WLAN_MAC_HEADER_QOS_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_16 u2QosCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_QOS_T, *P_WLAN_MAC_HEADER_QOS_T; ++ ++/* WLAN MAC Header (HT Control fields included) */ ++typedef struct _WLAN_MAC_HEADER_HT_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_16 u2QosCtrl; ++ UINT_32 u4HtCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_HT_T, *P_WLAN_MAC_HEADER_HT_T; ++ ++/* WLAN MAC Header (Address 4 included) */ ++typedef struct _WLAN_MAC_HEADER_A4_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_8 aucAddr4[MAC_ADDR_LEN]; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_T, *P_WLAN_MAC_HEADER_A4_T; ++ ++/* WLAN MAC Header (Address 4 and QoS Control fields included) */ ++typedef struct _WLAN_MAC_HEADER_A4_QOS_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_8 aucAddr4[MAC_ADDR_LEN]; ++ UINT_16 u2QosCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_QOS_T, *P_WLAN_MAC_HEADER_A4_QOS_T; ++ ++typedef struct _WLAN_MAC_HEADER_A4_HT_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_8 aucAddr4[MAC_ADDR_LEN]; ++ UINT_16 u2QosCtrl; ++ UINT_32 u4HtCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_HT_T, *P_WLAN_MAC_HEADER_A4_HT_T; ++ ++/* 7.2.3 WLAN MAC Header for Management Frame - MMPDU */ ++typedef struct _WLAN_MAC_MGMT_HEADER_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2Duration; ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_T, *P_WLAN_MAC_MGMT_HEADER_T; ++ ++/* WLAN MAC Header for Management Frame (HT Control fields included) */ ++typedef struct _WLAN_MAC_MGMT_HEADER_HT_T { ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2DurationID; ++ UINT_8 aucAddr1[MAC_ADDR_LEN]; ++ UINT_8 aucAddr2[MAC_ADDR_LEN]; ++ UINT_8 aucAddr3[MAC_ADDR_LEN]; ++ UINT_16 u2SeqCtrl; ++ UINT_32 u4HtCtrl; ++} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_HT_T, *P_WLAN_MAC_MGMT_HEADER_HT_T; ++ ++/* 3 WLAN CONTROL Frame */ ++/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ ++typedef struct _CTRL_PSPOLL_FRAME_T { ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2AID; /* AID */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_8 aucTA[MAC_ADDR_LEN]; /* TA */ ++} __KAL_ATTRIB_PACKED__ CTRL_PSPOLL_FRAME_T, *P_CTRL_PSPOLL_FRAME_T; ++ ++/* BAR */ ++typedef struct _CTRL_BAR_FRAME_T { ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* RA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* TA */ ++ UINT_16 u2BarControl; ++ UINT_8 aucBarInfo[2]; /* Variable size */ ++} __KAL_ATTRIB_PACKED__ CTRL_BAR_FRAME_T, *P_CTRL_BAR_FRAME_T; ++ ++/* 3 WLAN Management Frame. */ ++/* 7.2.3.1 WLAN Management Frame - Beacon Frame */ ++typedef struct _WLAN_BEACON_FRAME_T { ++ /* Beacon header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Beacon frame body */ ++ UINT_32 au4Timestamp[2]; /* Timestamp */ ++ UINT_16 u2BeaconInterval; /* Beacon Interval */ ++ UINT_16 u2CapInfo; /* Capability */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ ++} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_T, *P_WLAN_BEACON_FRAME_T; ++ ++typedef struct _WLAN_BEACON_FRAME_BODY_T { ++ /* Beacon frame body */ ++ UINT_32 au4Timestamp[2]; /* Timestamp */ ++ UINT_16 u2BeaconInterval; /* Beacon Interval */ ++ UINT_16 u2CapInfo; /* Capability */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ ++} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_BODY_T, *P_WLAN_BEACON_FRAME_BODY_T; ++ ++/* 7.2.3.3 WLAN Management Frame - Disassociation Frame */ ++typedef struct _WLAN_DISASSOC_FRAME_T { ++ /* Authentication MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Disassociation frame body */ ++ UINT_16 u2ReasonCode; /* Reason code */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ ++} __KAL_ATTRIB_PACKED__ WLAN_DISASSOC_FRAME_T, *P_WLAN_DISASSOC_FRAME_T; ++ ++/* 7.2.3.4 WLAN Management Frame - Association Request frame */ ++typedef struct _WLAN_ASSOC_REQ_FRAME_T { ++ /* Association Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Association Request frame body */ ++ UINT_16 u2CapInfo; /* Capability information */ ++ UINT_16 u2ListenInterval; /* Listen interval */ ++ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ ++} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_REQ_FRAME_T, *P_WLAN_ASSOC_REQ_FRAME_T; ++ ++/* 7.2.3.5 WLAN Management Frame - Association Response frame */ ++typedef struct _WLAN_ASSOC_RSP_FRAME_T { ++ /* Association Response MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Association Response frame body */ ++ UINT_16 u2CapInfo; /* Capability information */ ++ UINT_16 u2StatusCode; /* Status code */ ++ UINT_16 u2AssocId; /* Association ID */ ++ UINT_8 aucInfoElem[1]; /* Information elements, such as ++ supported rates, and etc. */ ++} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_RSP_FRAME_T, *P_WLAN_ASSOC_RSP_FRAME_T; ++ ++/* 7.2.3.6 WLAN Management Frame - Reassociation Request frame */ ++typedef struct _WLAN_REASSOC_REQ_FRAME_T { ++ /* Reassociation Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Reassociation Request frame body */ ++ UINT_16 u2CapInfo; /* Capability information */ ++ UINT_16 u2ListenInterval; /* Listen interval */ ++ UINT_8 aucCurrentAPAddr[MAC_ADDR_LEN]; /* Current AP address */ ++ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ ++} __KAL_ATTRIB_PACKED__ WLAN_REASSOC_REQ_FRAME_T, *P_WLAN_REASSOC_REQ_FRAME_T; ++ ++/* 7.2.3.7 WLAN Management Frame - Reassociation Response frame ++ (the same as Association Response frame) */ ++typedef WLAN_ASSOC_RSP_FRAME_T WLAN_REASSOC_RSP_FRAME_T, *P_WLAN_REASSOC_RSP_FRAME_T; ++ ++/* 7.2.3.9 WLAN Management Frame - Probe Response Frame */ ++typedef WLAN_BEACON_FRAME_T WLAN_PROBE_RSP_FRAME_T, *P_WLAN_PROBE_RSP_FRAME_T; ++ ++/* 7.2.3.10 WLAN Management Frame - Authentication Frame */ ++typedef struct _WLAN_AUTH_FRAME_T { ++ /* Authentication MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Authentication frame body */ ++ UINT_16 u2AuthAlgNum; /* Authentication algorithm number */ ++ UINT_16 u2AuthTransSeqNo; /* Authentication transaction sequence number */ ++ UINT_16 u2StatusCode; /* Status code */ ++ UINT_8 aucInfoElem[1]; /* Various IEs for Fast BSS Transition */ ++} __KAL_ATTRIB_PACKED__ WLAN_AUTH_FRAME_T, *P_WLAN_AUTH_FRAME_T; ++ ++/* 7.2.3.11 WLAN Management Frame - Deauthentication Frame */ ++typedef struct _WLAN_DEAUTH_FRAME_T { ++ /* Authentication MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Deauthentication frame body */ ++ UINT_16 u2ReasonCode; /* Reason code */ ++ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ ++} __KAL_ATTRIB_PACKED__ WLAN_DEAUTH_FRAME_T, *P_WLAN_DEAUTH_FRAME_T; ++ ++/* 3 Information Elements. */ ++/* 7.3.2 Generic element format */ ++typedef struct _IE_HDR_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucInfo[1]; ++} __KAL_ATTRIB_PACKED__ IE_HDR_T, *P_IE_HDR_T; ++ ++/* 7.3.2.1 SSID element */ ++typedef struct _IE_SSID_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++} __KAL_ATTRIB_PACKED__ IE_SSID_T, *P_IE_SSID_T; ++ ++/* 7.3.2.2 Supported Rates element */ ++typedef struct _IE_SUPPORTED_RATE_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucSupportedRates[ELEM_MAX_LEN_SUP_RATES]; ++} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_RATE_T, *P_IE_SUPPORTED_RATE_T; ++ ++/* 7.3.2.4 DS Parameter Set element */ ++typedef struct _IE_DS_PARAM_SET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCurrChnl; ++} __KAL_ATTRIB_PACKED__ IE_DS_PARAM_SET_T, *P_IE_DS_PARAM_SET_T; ++ ++/* 7.3.2.5 CF Parameter Set element */ ++typedef struct _IE_CF_PARAM_SET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCFPCount; ++ UINT_8 ucCFPPeriod; ++ UINT_16 u2CFPMaxDur; ++ UINT_16 u2DurRemaining; ++} __KAL_ATTRIB_PACKED__ IE_CF_PARAM_SET_T, *P_IE_CF_PARAM_SET_T; ++ ++/* 7.3.2.6 TIM */ ++typedef struct _IE_TIM_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucDTIMCount; ++ UINT_8 ucDTIMPeriod; ++ UINT_8 ucBitmapControl; ++ UINT_8 aucPartialVirtualMap[1]; ++} __KAL_ATTRIB_PACKED__ IE_TIM_T, *P_IE_TIM_T; ++ ++/* 7.3.2.7 IBSS Parameter Set element */ ++typedef struct _IE_IBSS_PARAM_SET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_16 u2ATIMWindow; ++} __KAL_ATTRIB_PACKED__ IE_IBSS_PARAM_SET_T, *P_IE_IBSS_PARAM_SET_T; ++ ++/* 7.3.2.8 Challenge Text element */ ++typedef struct _IE_CHALLENGE_TEXT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucChallengeText[ELEM_MAX_LEN_CHALLENGE_TEXT]; ++} __KAL_ATTRIB_PACKED__ IE_CHALLENGE_TEXT_T, *P_IE_CHALLENGE_TEXT_T; ++ ++/* 7.3.2.9 Country information element */ ++#if CFG_SUPPORT_802_11D ++/*! \brief COUNTRY_INFO_TRIPLET is defined for the COUNTRY_INFO_ELEM structure. */ ++typedef struct _COUNTRY_INFO_TRIPLET_T { ++ UINT_8 ucParam1; /*!< If param1 >= 201, this triplet is referred to as ++ Regulatory Triplet in 802_11J. */ ++ UINT_8 ucParam2; ++ UINT_8 ucParam3; ++} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_TRIPLET_T, *P_COUNTRY_INFO_TRIPLET_T; ++ ++typedef struct _COUNTRY_INFO_SUBBAND_TRIPLET_T { ++ UINT_8 ucFirstChnlNum; /*!< First Channel Number */ ++ UINT_8 ucNumOfChnl; /*!< Number of Channels */ ++ INT_8 cMaxTxPwrLv; /*!< Maximum Transmit Power Level */ ++} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_SUBBAND_TRIPLET_T, *P_COUNTRY_INFO_SUBBAND_TRIPLET_T; ++ ++typedef struct _COUNTRY_INFO_REGULATORY_TRIPLET_T { ++ UINT_8 ucRegExtId; /*!< Regulatory Extension Identifier, should ++ be greater than or equal to 201 */ ++ UINT_8 ucRegClass; /*!< Regulatory Class */ ++ UINT_8 ucCoverageClass; /*!< Coverage Class, unsigned 1-octet value 0~31 ++ , 32~255 reserved */ ++} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_REGULATORY_TRIPLET_T, *P_COUNTRY_INFO_REGULATORY_TRIPLET_T; ++ ++typedef struct _IE_COUNTRY_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCountryStr[3]; ++ COUNTRY_INFO_SUBBAND_TRIPLET_T arCountryStr[1]; ++} __KAL_ATTRIB_PACKED__ IE_COUNTRY_T, *P_IE_COUNTRY_T; ++#endif /* CFG_SUPPORT_802_11D */ ++ ++/* 7.3.2.13 ERP element */ ++typedef struct _IE_ERP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucERP; ++} __KAL_ATTRIB_PACKED__ IE_ERP_T, *P_IE_ERP_T; ++ ++/* 7.3.2.14 Extended Supported Rates element */ ++typedef struct _IE_EXT_SUPPORTED_RATE_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucExtSupportedRates[ELEM_MAX_LEN_EXTENDED_SUP_RATES]; ++} __KAL_ATTRIB_PACKED__ IE_EXT_SUPPORTED_RATE_T, *P_IE_EXT_SUPPORTED_RATE_T; ++ ++/* 7.3.2.15 Power Constraint element */ ++typedef struct _IE_POWER_CONSTRAINT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucLocalPowerConstraint; /* Unit: dBm */ ++} __KAL_ATTRIB_PACKED__ IE_POWER_CONSTRAINT_T, *P_IE_POWER_CONSTRAINT_T; ++ ++/* 7.3.2.16 Power Capability element */ ++typedef struct _IE_POWER_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ INT_8 cMinTxPowerCap; /* Unit: dBm */ ++ INT_8 cMaxTxPowerCap; /* Unit: dBm */ ++} __KAL_ATTRIB_PACKED__ IE_POWER_CAP_T, *P_IE_POWER_CAP_T; ++ ++/* 7.3.2.17 TPC request element */ ++typedef struct _IE_TPC_REQ_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++} __KAL_ATTRIB_PACKED__ IE_TPC_REQ_T, *P_IE_TPC_REQ_T; ++ ++/* 7.3.2.18 TPC report element */ ++typedef struct _IE_TPC_REPORT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ INT_8 cTxPower; /* Unit: dBm */ ++ INT_8 cLinkMargin; /* Unit: dB */ ++} __KAL_ATTRIB_PACKED__ IE_TPC_REPORT_T, *P_IE_TPC_REPORT_T; ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++/* 7.3.2.19 Supported Channels element*/ ++typedef struct _IE_SUPPORTED_CHANNELS_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucChannelNum[ELEM_MAX_LEN_SUPPORTED_CHANNELS * 2]; ++} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_CHANNELS_T, *P_IE_SUPPORTED_CHANNELS_T; ++ ++/* 7.3.2.20 Channel Switch Announcement element*/ ++typedef struct _IE_CHANNEL_SWITCH_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucChannelSwitchMode; ++ UINT_8 ucNewChannelNum; ++ UINT_8 ucChannelSwitchCount; ++} __KAL_ATTRIB_PACKED__ IE_CHANNEL_SWITCH_T, *P_IE_CHANNEL_SWITCH_T; ++#endif ++ ++/* 7.3.2.21 Measurement Request element */ ++typedef struct _IE_MEASUREMENT_REQ_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucToken; ++ UINT_8 ucRequestMode; ++ UINT_8 ucMeasurementType; ++ UINT_8 aucRequestFields[1]; ++} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REQ_T, *P_IE_MEASUREMENT_REQ_T; ++ ++typedef struct _SM_BASIC_REQ_T { ++ UINT_8 ucChannel; ++ UINT_32 au4StartTime[2]; ++ UINT_16 u2Duration; ++} __KAL_ATTRIB_PACKED__ SM_BASIC_REQ_T, *P_SM_BASIC_REQ_T; ++ ++/* SM_COMMON_REQ_T is not specified in Spec. Use it as common structure of SM */ ++typedef SM_BASIC_REQ_T SM_REQ_COMMON_T, *P_SM_REQ_COMMON_T; ++typedef SM_BASIC_REQ_T SM_CCA_REQ_T, *P_SM_CCA_REQ_T; ++typedef SM_BASIC_REQ_T SM_RPI_HISTOGRAM_REQ_T, *P_SM_RPI_HISTOGRAM_REQ_T; ++ ++typedef struct _RM_CHNL_LOAD_REQ_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REQ_T, *P_RM_CHNL_LOAD_REQ_T; ++ ++typedef RM_CHNL_LOAD_REQ_T RM_NOISE_HISTOGRAM_REQ_T, *P_RM_NOISE_HISTOGRAM_REQ_T; ++ ++typedef struct _RM_BCN_REQ_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 ucMeasurementMode; ++ UINT_8 aucBssid[6]; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_BCN_REQ_T, *P_RM_BCN_REQ_T; ++ ++typedef struct _RM_FRAME_REQ_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 ucFrameReqType; ++ UINT_8 aucMacAddr[6]; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_FRAME_REQ_T, *P_RM_FRAME_REQ_T; ++ ++typedef struct _RM_STA_STATS_REQ_T { ++ UINT_8 aucPeerMacAddr[6]; ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 ucGroupID; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_STA_STATS_REQ_T, *P_RM_STA_STATS_REQ_T; ++ ++typedef struct _RM_LCI_REQ_T { ++ UINT_8 ucLocationSubject; ++ UINT_8 ucLatitudeResolution; ++ UINT_8 ucLongitudeResolution; ++ UINT_8 ucAltitudeResolution; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_LCI_REQ_T, *P_RM_LCI_REQ_T; ++ ++typedef struct _RM_TS_MEASURE_REQ_T { ++ UINT_16 u2RandomInterval; ++ UINT_16 u2Duration; ++ UINT_8 aucPeerStaAddr[6]; ++ UINT_8 ucTrafficID; ++ UINT_8 ucBin0Range; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_TS_MEASURE_REQ_T, *P_RM_TS_MEASURE_REQ_T; ++ ++typedef struct _RM_MEASURE_PAUSE_REQ_T { ++ UINT_16 u2PauseTime; ++ UINT_8 aucSubElements[1]; ++} __KAL_ATTRIB_PACKED__ RM_MEASURE_PAUSE_REQ_T, *P_RM_MEASURE_PAUSE_REQ_T; ++ ++/* 7.3.2.22 Measurement Report element */ ++typedef struct _IE_MEASUREMENT_REPORT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucToken; ++ UINT_8 ucReportMode; ++ UINT_8 ucMeasurementType; ++ UINT_8 aucReportFields[1]; ++} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REPORT_T, *P_IE_MEASUREMENT_REPORT_T; ++ ++typedef struct _SM_BASIC_REPORT_T { ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucMap; ++} __KAL_ATTRIB_PACKED__ SM_BASIC_REPORT_T, *P_SM_BASIC_REPORT_T; ++ ++typedef struct _SM_CCA_REPORT_T { ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucCcaBusyFraction; ++} __KAL_ATTRIB_PACKED__ SM_CCA_REPORT_T, *P_SM_CCA_REPORT_T; ++ ++typedef struct _SM_RPI_REPORT_T { ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 aucRPI[8]; ++} __KAL_ATTRIB_PACKED__ SM_RPI_REPORT_T, *P_SM_RPI_REPORT_T; ++ ++typedef struct _RM_CHNL_LOAD_REPORT_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucChnlLoad; ++} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REPORT_T, *P_RM_CHNL_LOAD_REPORT_T; ++ ++typedef struct _RM_IPI_REPORT_T { ++ UINT_8 ucRegulatoryClass; ++ UINT_8 ucChannel; ++ UINT_32 u4StartTime[2]; ++ UINT_16 u2Duration; ++ UINT_8 ucAntennaId; ++ INT_8 cANPI; ++ UINT_8 aucIPI[11]; ++} __KAL_ATTRIB_PACKED__ RM_IPI_REPORT_T, *P_RM_IPI_REPORT_T; ++ ++/* 7.3.2.23 Quiet element */ ++typedef struct _IE_QUIET_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCount; ++ UINT_8 ucPeriod; ++ UINT_16 u2Duration; ++ UINT_16 u2Offset; ++} __KAL_ATTRIB_PACKED__ IE_QUIET_T, *P_IE_QUIET_T; ++ ++/* 7.3.2.27 Extended Capabilities element */ ++typedef struct _IE_EXT_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCapabilities[5]; ++} __KAL_ATTRIB_PACKED__ IE_EXT_CAP_T, *P_EXT_CAP_T; ++ ++/* 7.3.2.27 hs20 Extended Capabilities element */ ++typedef struct _IE_HS20_EXT_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCapabilities[6]; ++} __KAL_ATTRIB_PACKED__ IE_HS20_EXT_CAP_T, *P_HS20_EXT_CAP_T; ++ ++ ++/* 7.3.2.27 Extended Capabilities element */ ++typedef struct _IE_RRM_ENABLED_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucCap[5]; ++} __KAL_ATTRIB_PACKED__ IE_RRM_ENABLED_CAP_T, *P_IE_RRM_ENABLED_CAP_T; ++ ++/* 7.3.2.51 Timeout Interval element (TIE) */ ++typedef struct _IE_TIMEOUT_INTERVAL_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++#define IE_TIMEOUT_INTERVAL_TYPE_RESERVED 0 ++#define IE_TIMEOUT_INTERVAL_TYPE_REASSOC 1 ++#define IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME 2 ++#define IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK 3 ++ UINT_8 ucType; ++ UINT_32 u4Value; ++} __KAL_ATTRIB_PACKED__ IE_TIMEOUT_INTERVAL_T; ++ ++/* 7.3.2.56 HT Capabilities element */ ++typedef struct _SUP_MCS_SET_FIELD { ++ UINT_8 aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM]; ++ UINT_16 u2RxHighestSupportedRate; ++ UINT_32 u4TxRateInfo; ++} __KAL_ATTRIB_PACKED__ SUP_MCS_SET_FIELD, *P_SUP_MCS_SET_FIELD; ++ ++typedef struct _IE_HT_CAP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_16 u2HtCapInfo; ++ UINT_8 ucAmpduParam; ++ SUP_MCS_SET_FIELD rSupMcsSet; ++ UINT_16 u2HtExtendedCap; ++ UINT_32 u4TxBeamformingCap; ++ UINT_8 ucAselCap; ++} __KAL_ATTRIB_PACKED__ IE_HT_CAP_T, *P_IE_HT_CAP_T; ++ ++/* 7.3.2.57 HT Operation element */ ++typedef struct _IE_HT_OP_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucInfo1; ++ UINT_16 u2Info2; ++ UINT_16 u2Info3; ++ UINT_8 aucBasicMcsSet[16]; ++} __KAL_ATTRIB_PACKED__ IE_HT_OP_T, *P_IE_HT_OP_T; ++ ++/* 7.3.2.25 RSN Information element format */ ++typedef struct _RSN_INFO_ELEM_T { ++ UCHAR ucElemId; ++ UCHAR ucLength; ++ UINT_16 u2Version; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_16 u2PairwiseKeyCipherSuiteCount; ++ UCHAR aucPairwiseKeyCipherSuite1[4]; ++} __KAL_ATTRIB_PACKED__ RSN_INFO_ELEM_T, *P_RSN_INFO_ELEM_T; ++ ++/* 7.3.2.26 WPA Information element format */ ++typedef struct _WPA_INFO_ELEM_T { ++ UCHAR ucElemId; ++ UCHAR ucLength; ++ UCHAR aucOui[3]; ++ UCHAR ucOuiType; ++ UINT_16 u2Version; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_16 u2PairwiseKeyCipherSuiteCount; ++ UCHAR aucPairwiseKeyCipherSuite1[4]; ++} __KAL_ATTRIB_PACKED__ WPA_INFO_ELEM_T, *P_WPA_INFO_ELEM_T; ++ ++/* 7.3.2.58 20/40 BSS Intolerant Channel Report element */ ++typedef struct _IE_INTOLERANT_CHNL_REPORT_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucRegulatoryClass; ++ UINT_8 aucChannelList[1]; ++} __KAL_ATTRIB_PACKED__ IE_INTOLERANT_CHNL_REPORT_T, *P_IE_INTOLERANT_CHNL_REPORT_T; ++ ++/* 7.3.2.59 OBSS Scan Parameters element */ ++typedef struct _IE_OBSS_SCAN_PARAM_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_16 u2ScanPassiveDwell; ++ UINT_16 u2ScanActiveDwell; ++ UINT_16 u2TriggerScanInterval; ++ UINT_16 u2ScanPassiveTotalPerChnl; ++ UINT_16 u2ScanActiveTotalPerChnl; ++ UINT_16 u2WidthTransDelayFactor; ++ UINT_16 u2ScanActivityThres; ++} __KAL_ATTRIB_PACKED__ IE_OBSS_SCAN_PARAM_T, *P_IE_OBSS_SCAN_PARAM_T; ++ ++/* 7.3.2.60 20/40 BSS Coexistence element */ ++typedef struct _IE_20_40_COEXIST_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucData; ++} __KAL_ATTRIB_PACKED__ IE_20_40_COEXIST_T, *P_IE_20_40_COEXIST_T; ++ ++/* 7.3.2.60 20/40 BSS Coexistence element */ ++typedef struct _IE_SUP_OPERATING_CLASS_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 ucCur; ++ UINT_8 ucSup[255]; ++} __KAL_ATTRIB_PACKED__ IE_SUP_OPERATING_CLASS_T, *P_IE_SUP_OPERATING_CLASS_T; ++ ++/* 3 7.4 Action Frame. */ ++/* 7.4 Action frame format */ ++typedef struct _WLAN_ACTION_FRAME { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucActionDetails[1]; /* Action details */ ++} __KAL_ATTRIB_PACKED__ WLAN_ACTION_FRAME, *P_WLAN_ACTION_FRAME; ++ ++/* 7.4.1.1 Spectrum Measurement Request frame format */ ++typedef struct _ACTION_SM_REQ_FRAME { ++ /* ADDTS Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 aucInfoElem[1]; /* Information elements */ ++} __KAL_ATTRIB_PACKED__ ACTION_SM_REQ_FRAME, *P_ACTION_SM_REQ_FRAME; ++ ++/* 7.4.1.2 Spectrum Measurement Report frame format */ ++typedef ACTION_SM_REQ_FRAME ACTION_SM_REPORT_FRAME, *P_ACTION_SM_REPORT_FRAME; ++ ++/* 7.4.1.5 Channel Switch Announcement frame format */ ++typedef struct _ACTION_CHANNEL_SWITCH_FRAME { ++ /* ADDTS Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 aucInfoElem[5]; /* Information elements */ ++} __KAL_ATTRIB_PACKED__ _ACTION_CHANNEL_SWITCH_FRAME, *P_ACTION_CHANNEL_SWITCH_FRAME; ++ ++/* 7.4.2.1 ADDTS Request frame format */ ++typedef struct _ACTION_ADDTS_REQ_FRAME { ++ /* ADDTS Request MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 aucInfoElem[1]; /* Information elements, such as ++ TS Delay, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_REQ_FRAME, *P_ACTION_ADDTS_REQ_FRAME; ++ ++/* 7.4.2.2 ADDTS Response frame format */ ++typedef struct _ACTION_ADDTS_RSP_FRAME { ++ /* ADDTS Response MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* ADDTS Response frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 ucStatusCode; /* WMM Status Code is of one byte */ ++ UINT_8 aucInfoElem[1]; /* Information elements, such as ++ TS Delay, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_RSP_FRAME, *P_ACTION_ADDTS_RSP_FRAME; ++ ++/* 7.4.2.3 DELTS frame format */ ++typedef struct _ACTION_DELTS_FRAME { ++ /* DELTS MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* DELTS frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 aucTsInfo[3]; /* TS Info */ ++} __KAL_ATTRIB_PACKED__ ACTION_DELTS_FRAME, *P_ACTION_DELTS_FRAME; ++ ++/* 7.4.4.1 ADDBA Request frame format */ ++typedef struct _ACTION_ADDBA_REQ_FRAME_T { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ ++ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ ++ UINT_8 aucBATimeoutValue[2]; ++ UINT_8 aucBAStartSeqCtrl[2]; /* SSN */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_FRAME_T, *P_ACTION_ADDBA_REQ_FRAME_T; ++ ++typedef struct _ACTION_ADDBA_REQ_BODY_T { ++ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ ++ UINT_16 u2BATimeoutValue; ++ UINT_16 u2BAStartSeqCtrl; /* SSN */ ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_BODY_T, *P_ACTION_ADDBA_REQ_BODY_T; ++ ++/* 7.4.4.2 ADDBA Response frame format */ ++typedef struct _ACTION_ADDBA_RSP_FRAME_T { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ ++ UINT_8 aucStatusCode[2]; ++ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ ++ UINT_8 aucBATimeoutValue[2]; ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_FRAME_T, *P_ACTION_ADDBA_RSP_FRAME_T; ++ ++typedef struct _ACTION_ADDBA_RSP_BODY_T { ++ UINT_16 u2StatusCode; ++ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ ++ UINT_16 u2BATimeoutValue; ++} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_BODY_T, *P_ACTION_ADDBA_RSP_BODY_T; ++ ++/* 7.4.4.3 DELBA frame format */ ++typedef struct _ACTION_DELBA_FRAME_T { ++ /* Action MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2DurationID; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Action frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_16 u2DelBaParameterSet; /* Bit 11 Initiator, Bits 12-15 TID */ ++ UINT_16 u2ReasonCode; /* 7.3.1.7 */ ++} __KAL_ATTRIB_PACKED__ ACTION_DELBA_FRAME_T, *P_ACTION_DELBA_FRAME_T; ++ ++/* 7.4.6.1 Radio Measurement Request frame format */ ++typedef struct _ACTION_RM_REQ_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Radio Measurement Request frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_16 u2Repetitions; /* Number of repetitions */ ++ UINT_8 aucInfoElem[1]; /* Measurement Request elements, such as ++ channel load request, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_RM_REQ_FRAME, *P_ACTION_RM_REQ_FRAME; ++ ++/* 7.4.6.2 Radio Measurement Report frame format */ ++typedef struct _ACTION_RM_REPORT_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Radio Measurement Report frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 aucInfoElem[1]; /* Measurement Report elements, such as ++ channel load report, and etc. */ ++} __KAL_ATTRIB_PACKED__ ACTION_RM_REPORT_FRAME, *P_ACTION_RM_REPORT_FRAME; ++ ++/* 7.4.7.1a 20/40 BSS Coexistence Management frame format */ ++typedef struct _ACTION_20_40_COEXIST_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* BSS Coexistence Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ ++ IE_20_40_COEXIST_T rBssCoexist; /* 20/40 BSS coexistence element */ ++ IE_INTOLERANT_CHNL_REPORT_T rChnlReport; /* Intolerant channel report */ ++ ++} __KAL_ATTRIB_PACKED__ ACTION_20_40_COEXIST_FRAME, *P_ACTION_20_40_COEXIST_FRAME; ++ ++#if CFG_SUPPORT_802_11W ++/* 7.4.9 SA Query Management frame format */ ++typedef struct _ACTION_SA_QUERY_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* BSS Coexistence Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ ++ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; /* Transaction id */ ++ ++} __KAL_ATTRIB_PACKED__ ACTION_SA_QUERY_FRAME, *P_ACTION_SA_QUERY_FRAME; ++#endif ++ ++/* 7.4.10 Notify Channel Width Management frame format */ ++typedef struct _ACTION_NOTIFY_CHNL_WIDTH_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* BSS Coexistence Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucChannelWidth; /* Channel Width */ ++} __KAL_ATTRIB_PACKED__ ACTION_NOTIFY_CHNL_WIDTH_FRAME, *P_ACTION_NOTIFY_CHNL_WIDTH_FRAME; ++ ++/* 802.11v Wireless Network Management: Timing Measurement Request */ ++typedef struct _ACTION_WNM_TIMING_MEAS_REQ_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Timing Measurement Request Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucTrigger; /* Trigger */ ++} __KAL_ATTRIB_PACKED__ ACTION_WNM_TIMING_MEAS_REQ_FRAME, *P_ACTION_WNM_TIMING_MEAS_REQ_FRAME; ++ ++/* 802.11v Wireless Network Management: Timing Measurement */ ++typedef struct _ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* Timing Measurement Management frame body */ ++ UINT_8 ucCategory; /* Category */ ++ UINT_8 ucAction; /* Action Value */ ++ UINT_8 ucDialogToken; /* Dialog Token */ ++ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ ++ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ ++ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ ++ UINT_8 ucMaxToDErr; /* Maximum of ToD Error [10ns] */ ++ UINT_8 ucMaxToAErr; /* Maximum of ToA Error [10ns] */ ++} __KAL_ATTRIB_PACKED__ ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME, *P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME; ++ ++/* 3 Information Elements from WFA. */ ++typedef struct _IE_WFA_T { ++ UINT_8 ucId; ++ UINT_8 ucLength; ++ UINT_8 aucOui[3]; ++ UINT_8 ucOuiType; ++ UINT_8 aucOuiSubTypeVersion[2]; ++ /*!< Please be noted. WPA defines a 16 bit field version ++ instead of one subtype field and one version field */ ++} __KAL_ATTRIB_PACKED__ IE_WFA_T, *P_IE_WFA_T; ++ ++/* HS20 3.1 - HS 2.0 Indication Information Element */ ++typedef struct _IE_HS20_INDICATION_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucType; /* Type */ ++ UINT_8 ucHotspotConfig; /* Hotspot Configuration */ ++} __KAL_ATTRIB_PACKED__ IE_HS20_INDICATION_T, *P_IE_HS20_INDICATION_T; ++ ++/* WAPI Information element format */ ++typedef struct _WAPI_INFO_ELEM_T { ++ UCHAR ucElemId; ++ UCHAR ucLength; ++ UINT_16 u2Version; ++ UINT_16 u2AuthKeyMgtSuiteCount; ++ UCHAR aucAuthKeyMgtSuite1[4]; ++} __KAL_ATTRIB_PACKED__ WAPI_INFO_ELEM_T, *P_WAPI_INFO_ELEM_T; ++ ++#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) ++#pragma pack() ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Convert the ECWmin(max) to CWmin(max) */ ++#define ECW_TO_CW(_ECW) ((1 << (_ECW)) - 1) ++ ++/* Convert the RCPI to dBm */ ++#define RCPI_TO_dBm(_rcpi) \ ++ ((PARAM_RSSI)(((_rcpi) > RCPI_HIGH_BOUND ? RCPI_HIGH_BOUND : (_rcpi)) >> 1) - NDBM_LOW_BOUND_FOR_RCPI) ++ ++/* Convert the dBm to RCPI */ ++#define dBm_TO_RCPI(_dbm) \ ++ (RCPI)(((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) > RCPI_HIGH_BOUND) ? RCPI_HIGH_BOUND : \ ++ ((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) < RCPI_LOW_BOUND ? RCPI_LOW_BOUND : \ ++ (((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1))) ++ ++/* Convert an unsigned char pointer to an information element pointer */ ++#define IE_ID(fp) (((P_IE_HDR_T) fp)->ucId) ++#define IE_LEN(fp) (((P_IE_HDR_T) fp)->ucLength) ++#define IE_SIZE(fp) (ELEM_HDR_LEN + IE_LEN(fp)) ++ ++#define SSID_IE(fp) ((P_IE_SSID_T) fp) ++ ++#define SUP_RATES_IE(fp) ((P_IE_SUPPORTED_RATE_T) fp) ++ ++#define DS_PARAM_IE(fp) ((P_IE_DS_PARAM_SET_T) fp) ++ ++#define TIM_IE(fp) ((P_IE_TIM_T) fp) ++ ++#define IBSS_PARAM_IE(fp) ((P_IE_IBSS_PARAM_SET_T) fp) ++ ++#define ERP_INFO_IE(fp) ((P_IE_ERP_T) fp) ++ ++#define EXT_SUP_RATES_IE(fp) ((P_IE_EXT_SUPPORTED_RATE_T) fp) ++ ++#define WFA_IE(fp) ((P_IE_WFA_T) fp) ++ ++#if CFG_SUPPORT_802_11D ++#define COUNTRY_IE(fp) ((P_IE_COUNTRY_T) fp) ++#endif ++ ++#define EXT_CAP_IE(fp) ((P_EXT_CAP_T) fp) ++ ++#define HT_CAP_IE(fp) ((P_IE_HT_CAP_T) fp) ++ ++#define HT_OP_IE(fp) ((P_IE_HT_OP_T) fp) ++ ++#define OBSS_SCAN_PARAM_IE(fp) ((P_IE_OBSS_SCAN_PARAM_T) fp) ++ ++#define BSS_20_40_COEXIST_IE(fp) ((P_IE_20_40_COEXIST_T) fp) ++ ++#define SUP_OPERATING_CLASS_IE(fp) ((P_IE_SUP_OPERATING_CLASS_T) fp) ++ ++#define QUIET_IE(fp) ((P_IE_QUIET_T) fp) ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++#define SUPPORTED_CHANNELS_IE(fp) ((P_IE_SUPPORTED_CHANNELS_T)fp) ++#endif ++ ++#define TIMEOUT_INTERVAL_IE(fp) ((IE_TIMEOUT_INTERVAL_T *)fp) ++ ++/* The macro to check if the MAC address is B/MCAST Address */ ++#define IS_BMCAST_MAC_ADDR(_pucDestAddr) \ ++ ((BOOLEAN) (((PUINT_8)(_pucDestAddr))[0] & BIT(0))) ++ ++/* The macro to check if the MAC address is UCAST Address */ ++#define IS_UCAST_MAC_ADDR(_pucDestAddr) \ ++ ((BOOLEAN) !(((PUINT_8)(_pucDestAddr))[0] & BIT(0))) ++ ++/* The macro to copy the MAC address */ ++#define COPY_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ ++ kalMemCopy(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN) ++ ++/* The macro to check if two MAC addresses are equal */ ++#define EQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ ++ (!kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) ++ ++/* The macro to check if two MAC addresses are not equal */ ++#define UNEQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ ++ (kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) ++ ++/* The macro to check whether two SSIDs are equal */ ++#define EQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ ++ ((ucSsidLen1 <= ELEM_MAX_LEN_SSID) && \ ++ (ucSsidLen2 <= ELEM_MAX_LEN_SSID) && \ ++ ((ucSsidLen1) == (ucSsidLen2)) && \ ++ !kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) ++ ++/* The macro to check whether two SSIDs are equal */ ++#define UNEQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ ++ ((ucSsidLen1 > ELEM_MAX_LEN_SSID) || \ ++ (ucSsidLen2 > ELEM_MAX_LEN_SSID) || \ ++ ((ucSsidLen1) != (ucSsidLen2)) || \ ++ kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) ++ ++/* The macro to copy the SSID, the length of pucDestSsid should have at least 32 bytes */ ++#define COPY_SSID(pucDestSsid, ucDestSsidLen, pucSrcSsid, ucSrcSsidLen) \ ++ do { \ ++ ucDestSsidLen = ucSrcSsidLen; \ ++ if (ucSrcSsidLen) { \ ++ ASSERT(ucSrcSsidLen <= ELEM_MAX_LEN_SSID); \ ++ kalMemCopy(pucDestSsid, \ ++ pucSrcSsid, \ ++ ((ucSrcSsidLen > ELEM_MAX_LEN_SSID) ? ELEM_MAX_LEN_SSID : ucSrcSsidLen)); \ ++ } \ ++ } while (FALSE) ++ ++/* The macro to copy the IE */ ++#define COPY_IE(pucDestIE, pucSrcIE) \ ++ do { \ ++ kalMemCopy((PUINT_8)pucDestIE, \ ++ (PUINT_8)pucSrcIE,\ ++ IE_SIZE(pucSrcIE)); \ ++ } while (FALSE) ++ ++#define IE_FOR_EACH(_pucIEsBuf, _u2IEsBufLen, _u2Offset) \ ++ for ((_u2Offset) = 0;\ ++ ((((_u2Offset) + 2) <= (_u2IEsBufLen)) && (((_u2Offset) + IE_SIZE(_pucIEsBuf)) <= (_u2IEsBufLen))); \ ++ (_u2Offset) += IE_SIZE(_pucIEsBuf), (_pucIEsBuf) += IE_SIZE(_pucIEsBuf)) ++ ++#define SET_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ ++ do { \ ++ if ((_ucBit) < ((_ucFieldLength) * 8)) { \ ++ PUINT_8 aucExtCap = (PUINT_8)(_aucField); \ ++ ((aucExtCap)[(_ucBit) / 8]) |= BIT((_ucBit) % 8); \ ++ } \ ++ } while (FALSE) ++ ++#define TEST_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ ++ ((((_ucFieldLength) * 8) > (_ucBit)) && (((_aucField)[(_ucBit) / 8]) & BIT((_ucBit) % 8))) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _MAC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h +new file mode 100644 +index 000000000000..583923aed010 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h +@@ -0,0 +1,272 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/nic/mtreg.h#2 ++*/ ++ ++/*! \file "mtreg.h" ++ \brief The common register definition of mt5931 ++ ++ N/A ++*/ ++ ++/* ++** Log: mtreg.h ++ * ++ * 01 28 2013 samp.lin ++ * [WCXRP00000851] [MT6582 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6582-specific definitions. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 07 13 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add initial version for MT6628 driver support. ++ * ++*/ ++ ++#ifndef _MTREG_H ++#define _MTREG_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/* 1 MT6628 MCR Definition */ ++ ++/* 2 Host Interface */ ++ ++/* 4 CHIP ID Register */ ++#define MCR_WCIR 0x0000 ++ ++/* 4 HIF Low Power Control Register */ ++#define MCR_WHLPCR 0x0004 ++ ++/* 4 Control Status Register */ ++#define MCR_WSDIOCSR 0x0008 ++#define MCR_WSPICSR 0x0008 ++ ++/* 4 HIF Control Register */ ++#define MCR_WHCR 0x000C ++ ++/* 4 HIF Interrupt Status Register */ ++#define MCR_WHISR 0x0010 ++ ++/* 4 HIF Interrupt Enable Register */ ++#define MCR_WHIER 0x0014 ++ ++/* 4 Abnormal Status Register */ ++#define MCR_WASR 0x0018 ++ ++/* 4 WLAN Software Interrupt Control Register */ ++#define MCR_WSICR 0x001C ++ ++/* 4 WLAN TX Status Register */ ++#define MCR_WTSR0 0x0020 ++ ++/* 4 WLAN TX Status Register */ ++#define MCR_WTSR1 0x0024 ++ ++/* 4 WLAN TX Data Register 0 */ ++#define MCR_WTDR0 0x0028 ++ ++/* 4 WLAN TX Data Register 1 */ ++#define MCR_WTDR1 0x002C ++ ++/* 4 WLAN RX Data Register 0 */ ++#define MCR_WRDR0 0x0030 ++ ++/* 4 WLAN RX Data Register 1 */ ++#define MCR_WRDR1 0x0034 ++ ++/* 4 Host to Device Send Mailbox 0 Register */ ++#define MCR_H2DSM0R 0x0038 ++ ++/* 4 Host to Device Send Mailbox 1 Register */ ++#define MCR_H2DSM1R 0x003c ++ ++/* 4 Device to Host Receive Mailbox 0 Register */ ++#define MCR_D2HRM0R 0x0040 ++ ++/* 4 Device to Host Receive Mailbox 1 Register */ ++#define MCR_D2HRM1R 0x0044 ++ ++/* 4 Device to Host Receive Mailbox 2 Register */ ++#define MCR_D2HRM2R 0x0048 ++ ++/* 4 WLAN RX Packet Length Register */ ++#define MCR_WRPLR 0x0050 ++ ++/* 4 HSIF Transaction Count Register */ ++#define MCR_HSTCR 0x0058 ++ ++/* #if CFG_SDIO_INTR_ENHANCE */ ++typedef struct _ENHANCE_MODE_DATA_STRUCT_T { ++ UINT_32 u4WHISR; ++ union { ++ struct { ++ UINT_8 ucTQ0Cnt; ++ UINT_8 ucTQ1Cnt; ++ UINT_8 ucTQ2Cnt; ++ UINT_8 ucTQ3Cnt; ++ UINT_8 ucTQ4Cnt; ++ UINT_8 ucTQ5Cnt; ++ UINT_16 u2Rsrv; ++ } u; ++ UINT_32 au4WTSR[2]; ++ } rTxInfo; ++ union { ++ struct { ++ UINT_16 u2NumValidRx0Len; ++ UINT_16 u2NumValidRx1Len; ++ UINT_16 au2Rx0Len[16]; ++ UINT_16 au2Rx1Len[16]; ++ } u; ++ UINT_32 au4RxStatusRaw[17]; ++ } rRxInfo; ++ UINT_32 u4RcvMailbox0; ++ UINT_32 u4RcvMailbox1; ++} ENHANCE_MODE_DATA_STRUCT_T, *P_ENHANCE_MODE_DATA_STRUCT_T; ++/* #endif */ /* ENHANCE_MODE_DATA_STRUCT_T */ ++ ++/* 2 Definition in each register */ ++/* 3 WCIR 0x0000 */ ++#define WCIR_WLAN_READY BIT(21) ++#define WCIR_POR_INDICATOR BIT(20) ++#define WCIR_REVISION_ID BITS(16, 19) ++#define WCIR_CHIP_ID BITS(0, 15) ++ ++#define MTK_CHIP_REV_72 0x00006572 ++#define MTK_CHIP_REV_82 0x00006582 ++#define MTK_CHIP_REV_92 0x00006592 ++#define MTK_CHIP_MP_REVERSION_ID 0x0 ++ ++/* 3 WHLPCR 0x0004 */ ++#define WHLPCR_FW_OWN_REQ_CLR BIT(9) ++#define WHLPCR_FW_OWN_REQ_SET BIT(8) ++#define WHLPCR_IS_DRIVER_OWN BIT(8) ++#define WHLPCR_INT_EN_CLR BIT(1) ++#define WHLPCR_INT_EN_SET BIT(0) ++ ++/* 3 WSDIOCSR 0x0008 */ ++#define WSDIOCSR_SDIO_RE_INIT_EN BIT(0) ++ ++/* 3 WSPICSR 0x0008 */ ++#define WCSR_SPI_MODE_SEL BITS(3, 4) ++#define WCSR_SPI_ENDIAN_BIG BIT(2) ++#define WCSR_SPI_INT_OUT_MODE BIT(1) ++#define WCSR_SPI_DATA_OUT_MODE BIT(0) ++ ++/* 3 WHCR 0x000C */ ++#define WHCR_RX_ENHANCE_MODE_EN BIT(16) ++#define WHCR_MAX_HIF_RX_LEN_NUM BITS(4, 7) ++#define WHCR_W_MAILBOX_RD_CLR_EN BIT(2) ++#define WHCR_W_INT_CLR_CTRL BIT(1) ++#define WHCR_MCU_DBG_EN BIT(0) ++#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM 4 ++ ++/* 3 WHISR 0x0010 */ ++#define WHISR_D2H_SW_INT BITS(8, 31) ++#define WHISR_D2H_SW_ASSERT_INFO_INT BIT(31) ++#define WHISR_FW_OWN_BACK_INT BIT(4) ++#define WHISR_ABNORMAL_INT BIT(3) ++#define WHISR_RX1_DONE_INT BIT(2) ++#define WHISR_RX0_DONE_INT BIT(1) ++#define WHISR_TX_DONE_INT BIT(0) ++ ++/* 3 WHIER 0x0014 */ ++#define WHIER_D2H_SW_INT BITS(8, 31) ++#define WHIER_FW_OWN_BACK_INT_EN BIT(4) ++#define WHIER_ABNORMAL_INT_EN BIT(3) ++#define WHIER_RX1_DONE_INT_EN BIT(2) ++#define WHIER_RX0_DONE_INT_EN BIT(1) ++#define WHIER_TX_DONE_INT_EN BIT(0) ++#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \ ++ WHIER_RX1_DONE_INT_EN | \ ++ WHIER_TX_DONE_INT_EN | \ ++ WHIER_ABNORMAL_INT_EN | \ ++ WHIER_D2H_SW_INT \ ++ ) ++ ++/* 3 WASR 0x0018 */ ++#define WASR_FW_OWN_INVALID_ACCESS BIT(4) ++#define WASR_RX1_UNDER_FLOW BIT(3) ++#define WASR_RX0_UNDER_FLOW BIT(2) ++#define WASR_TX1_OVER_FLOW BIT(1) ++#define WASR_TX0_OVER_FLOW BIT(0) ++ ++/* 3 WSICR 0x001C */ ++#define WSICR_H2D_SW_INT_SET BITS(16, 31) ++ ++/* 3 WRPLR 0x0050 */ ++#define WRPLR_RX1_PACKET_LENGTH BITS(16, 31) ++#define WRPLR_RX0_PACKET_LENGTH BITS(0, 15) ++ ++/* 3 HSTCR 0x0058 */ ++#define HSTCR_AFF_BURST_LEN BITS(24, 25) ++#define HSTCR_AFF_BURST_LEN_OFFSET 24 ++#define HSTCR_TRANS_TARGET BITS(20, 22) ++#define HSTCR_TRANS_TARGET_OFFSET 20 ++#define HSTCR_HSIF_TRANS_CNT BITS(2, 19) ++#define HSTCR_HSIF_TRANS_CNT_OFFSET 2 ++ ++/* HSTCR_TRANS_TARGET */ ++typedef enum _eTransTarget { ++ TRANS_TARGET_TXD0 = 0, ++ TRANS_TARGET_TXD1, ++ TRANS_TARGET_RXD0, ++ TRANS_TARGET_RXD1, ++ TRANS_TARGET_WHISR, ++ NUM_TRANS_TARGET ++} E_TRANS_TARGET_T; ++ ++typedef enum _E_AFF_BURST_LEN { ++ BURST_1_DW = 0, ++ BURST_4_DW, ++ BURST_8_DW, ++ BURST_RSV, ++ NUM_AFF_BURST_LEN ++} E_AFF_BURST_LEN; ++ ++#endif /* _MTREG_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h +new file mode 100644 +index 000000000000..c059b707aee8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h +@@ -0,0 +1,498 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic.h#1 ++*/ ++ ++/*! \file "nic.h" ++ \brief The declaration of nic functions ++ ++ Detail description. ++*/ ++ ++/* ++** Log: nic.h ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. ++ * If disconnect the AP and flush all the data frame in the TX queue, WPS ++ * cannot do the 4-way handshake to connect to the AP.. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 04 11 2011 yuche.tsai ++ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. ++ * Fix kernel panic issue when MMPDU of P2P is pending in driver. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right ++ * after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * add HT (802.11n) fixed rate support. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced ++ * by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test ++ * with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * STA-REC is maintained by CNM only. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement TX_DONE callback path. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add channel frequency <-> number conversion ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always process TX interrupt first then RX interrupt. ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-10-13 21:58:58 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-24 21:12:55 GMT mtk01104 ++** Add function prototype nicRestoreSpiDefMode() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:54 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:32 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _NIC_H ++#define _NIC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++struct _REG_ENTRY_T { ++ UINT_32 u4Offset; ++ UINT_32 u4Value; ++}; ++ ++struct _TABLE_ENTRY_T { ++ P_REG_ENTRY_T pu4TablePtr; ++ UINT_16 u2Size; ++}; ++ ++/*! INT status to event map */ ++typedef struct _INT_EVENT_MAP_T { ++ UINT_32 u4Int; ++ UINT_32 u4Event; ++} INT_EVENT_MAP_T, *P_INT_EVENT_MAP_T; ++ ++enum ENUM_INT_EVENT_T { ++ INT_EVENT_ABNORMAL, ++ INT_EVENT_SW_INT, ++ INT_EVENT_TX, ++ INT_EVENT_RX, ++ INT_EVENT_NUM ++}; ++ ++typedef enum _ENUM_IE_UPD_METHOD_T { ++ IE_UPD_METHOD_UPDATE_RANDOM, ++ IE_UPD_METHOD_UPDATE_ALL, ++ IE_UPD_METHOD_DELETE_ALL, ++} ENUM_IE_UPD_METHOD_T, *P_ENUM_IE_UPD_METHOD_T; ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern BOOLEAN fgIsResetting; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in nic.c */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter); ++ ++VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter); ++ ++VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus); ++ ++WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter); ++ ++VOID nicMCRInit(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter); ++ ++#if CFG_SDIO_INTR_ENHANCE ++VOID nicSDIOInit(IN P_ADAPTER_T prAdapter); ++ ++VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus); ++#endif ++ ++BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter); ++ ++VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt); ++ ++BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter); ++ ++#if defined(_HIF_SPI) ++void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter); ++#endif ++ ++VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data); ++ ++VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data); ++ ++VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap); ++ ++P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); ++ ++P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); ++ ++P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx); ++ ++VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); ++ ++UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter); ++ ++UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter); ++ ++/* Media State Change */ ++WLAN_STATUS ++nicMediaStateChange(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); ++ ++/* Utility function for channel number conversion */ ++UINT_32 nicChannelNum2Freq(IN UINT_32 u4ChannelNum); ++ ++UINT_32 nicFreq2ChannelNum(IN UINT_32 u4FreqInKHz); ++ ++/* firmware command wrapper */ ++ /* NETWORK (WIFISYS) */ ++WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++ /* BSS-INFO */ ++WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++ /* BSS-INFO Indication (PM) */ ++WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++ /* Beacon Template Update */ ++WLAN_STATUS ++nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, ++ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen); ++ ++WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam); ++ ++/*----------------------------------------------------------------------------*/ ++/* Calibration Control */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam); ++ ++WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset); ++ ++WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult); ++ ++/*----------------------------------------------------------------------------*/ ++/* PHY configuration */ ++/*----------------------------------------------------------------------------*/ ++VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* MGMT and System Service Control */ ++/*----------------------------------------------------------------------------*/ ++VOID nicInitSystemService(IN P_ADAPTER_T prAdapter); ++ ++VOID nicResetSystemService(IN P_ADAPTER_T prAdapter); ++ ++VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter); ++ ++VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); ++ ++VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent); ++ ++WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent); ++/*----------------------------------------------------------------------------*/ ++/* Scan Result Processing */ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicAddScanResult(IN P_ADAPTER_T prAdapter, ++ IN PARAM_MAC_ADDRESS rMacAddr, ++ IN P_PARAM_SSID_T prSsid, ++ IN UINT_32 u4Privacy, ++ IN PARAM_RSSI rRssi, ++ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, ++ IN P_PARAM_802_11_CONFIG_T prConfiguration, ++ IN ENUM_PARAM_OP_MODE_T eOpMode, ++ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf); ++ ++VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx); ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++/*----------------------------------------------------------------------------*/ ++/* Workaround Control */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* Fixed Rate Hacking */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicUpdateRateParams(IN P_ADAPTER_T prAdapter, ++ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, ++ IN PUINT_8 pucDesiredPhyTypeSet, ++ IN PUINT_16 pu2DesiredNonHTRateSet, ++ IN PUINT_16 pu2BSSBasicRateSet, ++ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 u2HtCapInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Write registers */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value); ++ ++/*----------------------------------------------------------------------------*/ ++/* Update auto rate */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4ArSysParam0, ++ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3); ++ ++/*----------------------------------------------------------------------------*/ ++/* Enable/Disable Roaming */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming); ++ ++VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Link Quality Updating */ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality); ++ ++VOID ++nicUpdateRSSI(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); ++ ++VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed); ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam); ++#endif ++ ++#endif /* _NIC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h +new file mode 100644 +index 000000000000..86e2c84b07ff +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h +@@ -0,0 +1,420 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_rx.h#1 ++*/ ++ ++/*! \file "nic_rx.h" ++ \brief The declaration of the nic rx functions ++ ++*/ ++ ++/* ++** Log: nic_rx.h ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add delay after whole-chip resetting for MT5931 E1 ASIC. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode ++ * and stop ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Change prototype of API of adding P2P device to scan result. ++ * Additional IE buffer is saved. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Modify data structure for P2P Scan result. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * newly added P2P API should be declared in header file. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * 4) nicRxWaitResponse() revised ++ * * 5) another set of TQ counter default value is added for fw-download state ++ * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * and result is retrieved by get ATInfo instead ++ * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:49:09 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 14:02:37 GMT MTK02468 ++** Added ucStaRecIdx in SW_RFB_T and HALF_SEQ_NO_COUNT definition (to replace HALF_SEQ_NO_CNOUT) ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-27 11:07:54 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 18:18:09 GMT mtk02752 ++** modify nicRxAddScanResult() ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-24 22:42:22 GMT mtk02752 ++** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-24 19:57:06 GMT mtk02752 ++** adopt P_HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 21:43:04 GMT mtk02752 ++** correct ENUM_RX_PKT_DESTINATION_T definitions ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 15:28:25 GMT mtk02752 ++** add ucQueuedPacketNum for indicating how many packet are queued by RX reordering buffer/forwarding path ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 15:05:01 GMT mtk02752 ++** add eTC for SW_RFB_T and structure RX_MAILBOX ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 21:16:57 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-13 16:59:30 GMT mtk02752 ++** add handler for event packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-13 13:45:50 GMT mtk02752 ++** add port param for nicRxEnhanceReadBuffer() ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-11 10:12:31 GMT mtk02752 ++** nicSDIOReadIntStatus() always read sizeof(ENHANCE_MODE_DATA_STRUCT_T) for int response, ++** thus the number should be set to 0(:=16) instead of 10 ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-29 19:53:32 GMT mtk01084 ++** modify structure naming ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-23 16:08:23 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:01 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-20 12:23:33 GMT mtk01461 ++** Add u4MaxEventBufferLen parameter to nicRxWaitResponse() ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-18 21:00:48 GMT mtk01426 ++** Update SDIO_MAXIMUM_RX_STATUS value ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:36:15 GMT mtk01461 ++** Remove unused define - SDIO_MAXIMUM_TX_STATUS ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:17 GMT mtk01461 ++** Add function for HIF_LOOPBACK_PRE_TEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:56:19 GMT mtk01426 ++** Add to support CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:19:56 GMT mtk01426 ++** Add nicRxWaitResponse function proto type ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:35 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _NIC_RX_H ++#define _NIC_RX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern P_SW_RFB_T g_arGscnResultsTempBuffer[]; ++extern UINT_8 g_GscanResultsTempBufferIndex; ++extern UINT_8 g_arGscanResultsIndicateNumber[]; ++extern UINT_8 g_GetResultsBufferedCnt; ++extern UINT_8 g_GetResultsCmdCnt; ++extern void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define MAX_SEQ_NO 4095 ++#define MAX_SEQ_NO_COUNT 4096 ++#define HALF_SEQ_NO_CNOUT 2048 ++ ++#define HALF_SEQ_NO_COUNT 2048 ++ ++#define MT6620_FIXED_WIN_SIZE 64 ++#define CFG_RX_MAX_BA_ENTRY 4 ++#define CFG_RX_MAX_BA_TID_NUM 8 ++ ++#define RX_STATUS_FLAG_MORE_PACKET BIT(30) ++#define RX_STATUS_CHKSUM_MASK BITS(0, 10) ++ ++#define RX_RFB_LEN_FIELD_LEN 4 ++#define RX_HEADER_OFFSET 2 ++ ++#define RX_RETURN_INDICATED_RFB_TIMEOUT_SEC 3 ++ ++#if defined(_HIF_SDIO) && defined(WINDOWS_DDK) ++/*! On XP, maximum Tx+Rx Statue <= 64-4(HISR)*/ ++#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ ++#else ++#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_RX_STATISTIC_COUNTER_T { ++ RX_MPDU_TOTAL_COUNT = 0, ++ RX_SIZE_ERR_DROP_COUNT, ++ ++ RX_DATA_INDICATION_COUNT, ++ RX_DATA_RETURNED_COUNT, ++ RX_DATA_RETAINED_COUNT, ++ ++ RX_DROP_TOTAL_COUNT, ++ RX_TYPE_ERR_DROP_COUNT, ++ RX_CLASS_ERR_DROP_COUNT, ++ RX_DST_NULL_DROP_COUNT, ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++ RX_CSUM_TCP_FAILED_COUNT, ++ RX_CSUM_UDP_FAILED_COUNT, ++ RX_CSUM_IP_FAILED_COUNT, ++ RX_CSUM_TCP_SUCCESS_COUNT, ++ RX_CSUM_UDP_SUCCESS_COUNT, ++ RX_CSUM_IP_SUCCESS_COUNT, ++ RX_CSUM_UNKNOWN_L4_PKT_COUNT, ++ RX_CSUM_UNKNOWN_L3_PKT_COUNT, ++ RX_IP_V6_PKT_CCOUNT, ++#endif ++ RX_STATISTIC_COUNTER_NUM ++} ENUM_RX_STATISTIC_COUNTER_T; ++ ++typedef enum _ENUM_RX_PKT_DESTINATION_T { ++ RX_PKT_DESTINATION_HOST, /* to OS */ ++ RX_PKT_DESTINATION_FORWARD, /* to TX queue for forward, AP mode */ ++ RX_PKT_DESTINATION_HOST_WITH_FORWARD, /* to both TX and OS, AP mode broadcast packet */ ++ RX_PKT_DESTINATION_NULL, /* packet to be freed */ ++ RX_PKT_DESTINATION_NUM ++} ENUM_RX_PKT_DESTINATION_T; ++ ++struct _SW_RFB_T { ++ QUE_ENTRY_T rQueEntry; ++ PVOID pvPacket; /*!< ptr to rx Packet Descriptor */ ++ PUINT_8 pucRecvBuff; /*!< ptr to receive data buffer */ ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_32 u4HifRxHdrFlag; ++ PVOID pvHeader; ++ UINT_16 u2PacketLen; ++ UINT_16 u2HeaderLen; ++ UINT_16 u2SSN; ++ UINT_8 ucTid; ++ UINT_8 ucWlanIdx; ++ UINT_8 ucPacketType; ++ UINT_8 ucStaRecIdx; ++ ++ ENUM_CSUM_RESULT_T aeCSUM[CSUM_TYPE_NUM]; ++ ENUM_RX_PKT_DESTINATION_T eDst; ++ ENUM_TRAFFIC_CLASS_INDEX_T eTC; /* only valid when eDst == FORWARD */ ++ ++ UINT_64 rRxTime; ++}; ++ ++/*! RX configuration type structure */ ++typedef struct _RX_CTRL_T { ++ UINT_32 u4RxCachedSize; ++ PUINT_8 pucRxCached; ++ QUE_T rFreeSwRfbList; ++ QUE_T rReceivedRfbList; ++ QUE_T rIndicatedRfbList; ++ ++#if CFG_SDIO_RX_AGG ++ PUINT_8 pucRxCoalescingBufPtr; ++#endif ++ ++ PVOID apvIndPacket[CFG_RX_MAX_PKT_NUM]; ++ PVOID apvRetainedPacket[CFG_RX_MAX_PKT_NUM]; ++ ++ UINT_8 ucNumIndPacket; ++ UINT_8 ucNumRetainedPacket; ++ UINT_64 au8Statistics[RX_STATISTIC_COUNTER_NUM]; /*!< RX Counters */ ++ ++#if CFG_HIF_STATISTICS ++ UINT_32 u4TotalRxAccessNum; ++ UINT_32 u4TotalRxPacketNum; ++#endif ++ ++#if CFG_HIF_RX_STARVATION_WARNING ++ UINT_32 u4QueuedCnt; ++ UINT_32 u4DequeuedCnt; ++#endif ++ ++#if CFG_RX_PKTS_DUMP ++ UINT_32 u4RxPktsDumpTypeMask; ++#endif ++ ++} RX_CTRL_T, *P_RX_CTRL_T; ++ ++typedef struct _RX_MAILBOX_T { ++ UINT_32 u4RxMailbox[2]; /* for Device-to-Host Mailbox */ ++} RX_MAILBOX_T, *P_RX_MAILBOX_T; ++ ++typedef WLAN_STATUS(*PROCESS_RX_MGT_FUNCTION) (P_ADAPTER_T, P_SW_RFB_T); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define RX_INC_CNT(prRxCtrl, eCounter) \ ++ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]++; } ++ ++#define RX_ADD_CNT(prRxCtrl, eCounter, u8Amount) \ ++ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter] += (UINT_64)u8Amount; } ++ ++#define RX_GET_CNT(prRxCtrl, eCounter) \ ++ (((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]) ++ ++#define RX_RESET_ALL_CNTS(prRxCtrl) \ ++ {kalMemZero(&prRxCtrl->au8Statistics[0], sizeof(prRxCtrl->au8Statistics)); } ++ ++#define RX_STATUS_TEST_MORE_FLAG(flag) \ ++ ((BOOLEAN)((flag & RX_STATUS_FLAG_MORE_PACKET) ? TRUE : FALSE)) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID nicRxInitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter); ++ ++#if !CFG_SDIO_INTR_ENHANCE ++VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++#else ++VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS ++nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++#if CFG_SDIO_RX_AGG ++VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter); ++#endif ++ ++WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); ++ ++VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); ++ ++VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus); ++ ++VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]); ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); ++ ++VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); ++ ++WLAN_STATUS ++nicRxWaitResponse(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length); ++ ++VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter); ++ ++VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++#endif /* _NIC_RX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h +new file mode 100644 +index 000000000000..e516468fcb16 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h +@@ -0,0 +1,642 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 ++*/ ++ ++/*! \file nic_tx.h ++ \brief Functions that provide TX operation in NIC's point of view. ++ ++ This file provides TX functions which are responsible for both Hardware and ++ Software Resource Management and keep their Synchronization. ++ ++*/ ++ ++/* ++** Log: nic_tx.h ++ * ++ * 11 18 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add log counter for tx ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add TX_DONE status detail information. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing ++ * frame dropping cases for TC4 path ++ * 1. add nicTxGetResource() API for QM to make decisions. ++ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 02 16 2011 cp.wu ++ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking ++ * available count and modify behavior ++ * 1. add new API: nicTxGetFreeCmdCount() ++ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 12 15 2010 yuche.tsai ++ * NULL ++ * Update SLT Descriptor number configure in driver. ++ * ++ * 11 16 2010 yarco.yang ++ * [WCXRP00000177] [MT5931 F/W] Performance tuning for 1st connection ++ * Update TX buffer count ++ * ++ * 11 03 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * 1) use 8 buffers for MT5931 which is equipped with less memory ++ * 2) modify MT5931 debug level to TRACE when download is successful ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * API added: nicTxPendingPackets(), for simplifying porting layer ++ * ++ * 07 26 2010 cp.wu ++ * ++ * change TC4 initial value from 2 to 4. ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under ++ * concurrent network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add MGMT Packet type for HIF_TX_HEADER ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * TX descriptors are now allocated once for reducing allocation overhead ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate ++ * 2) add packet type for indicating management frames ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add TX_PACKET_MGMT to indicate the frame is coming from management modules ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * * ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 02 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Redistributed the initial TC resources for normal operation ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * 4) nicRxWaitResponse() revised ++ * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * 4. correct some HAL implementation ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * and result is retrieved by get ATInfo instead ++ * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:53:28 GMT mtk02752 ++** remove unused API ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-27 11:08:00 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-24 19:56:49 GMT mtk02752 ++** remove redundant eTC ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 22:01:08 GMT mtk02468 ++** Added MSDU_INFO fields for composing HIF TX header ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:51 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:35:05 GMT mtk02752 ++** + nicTxMsduInfoList() for sending MsduInfoList ++** + NIC_TX_BUFF_COUNT_TC[0~5] ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-17 11:07:00 GMT mtk02752 ++** add nicTxAdjustTcq() API ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 22:28:30 GMT mtk02752 ++** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 21:44:50 GMT mtk02752 ++** + nicTxReturnMsduInfo() ++** + nicTxFillMsduInfo() ++** + rFreeMsduInfoList field in TX_CTRL ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-16 18:00:43 GMT mtk02752 ++** use P_PACKET_INFO_T for prPacket to avoid inventing another new structure for packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-16 15:28:49 GMT mtk02752 ++** add ucQueuedPacketNum for indicating how many packets are queued by per STA/AC queue ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-16 10:52:01 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-14 23:39:24 GMT mtk02752 ++** interface structure redefine ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-13 21:17:03 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-29 19:53:10 GMT mtk01084 ++** remove strange code by Frog ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:04 GMT mtk01084 ++** update for new HW architecture design ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-02 13:53:03 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:36:50 GMT mtk01461 ++** Add declaration of nicTxReleaseResource() ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:58:39 GMT mtk01461 ++** Move CMD_INFO_T related define and function to cmd_buf.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:53 GMT mtk01461 ++** Add function for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:33:27 GMT mtk01461 ++** Define constants for TX PATH and add nicTxPollingResource ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:32 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:38 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _NIC_TX_H ++#define _NIC_TX_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define NIC_TX_RESOURCE_POLLING_TIMEOUT 256 ++#define NIC_TX_RESOURCE_POLLING_DELAY_MSEC 50 ++ ++/* Maximum buffer count for individual HIF TCQ */ ++ ++#if defined(MT6620) ++#if CFG_SLT_SUPPORT ++ /* 20101215 mtk01725 Redistributed the initial TC resources for SLT operation */ ++#define NIC_TX_BUFF_COUNT_TC0 0 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 16 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 0 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 0 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 0 /* First connection: 0 */ ++#else ++ /* 20100302 mtk02468 Redistributed the initial TC resources for normal operation */ ++#define NIC_TX_BUFF_COUNT_TC0 6 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 8 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 8 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 8 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 2 /* First connection: 0 */ ++#endif ++#elif defined(MT6628) ++#if (CFG_SRAM_SIZE_OPTION == 0) ++#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 20 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ ++#elif (CFG_SRAM_SIZE_OPTION == 1) ++#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 36 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ ++#elif (CFG_SRAM_SIZE_OPTION == 2) ++#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC1 48 /* First connection: 32 */ ++#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ ++#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ ++#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ ++#else ++#error "> Set TX_BUFF_COUNT_TC error!" ++#endif ++#endif ++ ++#define NIC_TX_BUFF_SUM (NIC_TX_BUFF_COUNT_TC0 + \ ++ NIC_TX_BUFF_COUNT_TC1 + \ ++ NIC_TX_BUFF_COUNT_TC2 + \ ++ NIC_TX_BUFF_COUNT_TC3 + \ ++ NIC_TX_BUFF_COUNT_TC4 + \ ++ NIC_TX_BUFF_COUNT_TC5) ++#if CFG_ENABLE_FW_DOWNLOAD ++ ++#define NIC_TX_INIT_BUFF_COUNT_TC0 8 ++#define NIC_TX_INIT_BUFF_COUNT_TC1 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC2 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC3 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC4 0 ++#define NIC_TX_INIT_BUFF_COUNT_TC5 0 ++ ++#define NIC_TX_INIT_BUFF_SUM (NIC_TX_INIT_BUFF_COUNT_TC0 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC1 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC2 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC3 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC4 + \ ++ NIC_TX_INIT_BUFF_COUNT_TC5) ++ ++#endif ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++#define NIC_TX_TIME_THRESHOLD 100 /* in unit of ms */ ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* 3 Session for TX QUEUES */ ++/* The definition in this ENUM is used to categorize packet's Traffic Class according ++ * to the their TID(User Priority). ++ * In order to achieve QoS goal, a particular TC should not block the process of ++ * another packet with different TC. ++ * In current design we will have 5 categories(TCs) of SW resource. ++ */ ++typedef enum _ENUM_TRAFFIC_CLASS_INDEX_T { ++ TC0_INDEX = 0, /* HIF TX0: AC0 packets */ ++ TC1_INDEX, /* HIF TX0: AC1 packets & non-QoS packets */ ++ TC2_INDEX, /* HIF TX0: AC2 packets */ ++ TC3_INDEX, /* HIF TX0: AC3 packets */ ++ TC4_INDEX, /* HIF TX1: Command packets or 802.1x packets */ ++ TC5_INDEX, /* HIF TX0: BMCAST packets */ ++ TC_NUM /* Maximum number of Traffic Classes. */ ++} ENUM_TRAFFIC_CLASS_INDEX_T; ++ ++typedef enum _ENUM_TX_STATISTIC_COUNTER_T { ++ TX_MPDU_TOTAL_COUNT = 0, ++ TX_INACTIVE_BSS_DROP, ++ TX_INACTIVE_STA_DROP, ++ TX_FORWARD_OVERFLOW_DROP, ++ TX_AP_BORADCAST_DROP, ++ TX_STATISTIC_COUNTER_NUM ++} ENUM_TX_STATISTIC_COUNTER_T; ++ ++typedef struct _TX_TCQ_STATUS_T { ++ UINT_8 aucFreeBufferCount[TC_NUM]; ++ UINT_8 aucMaxNumOfBuffer[TC_NUM]; ++} TX_TCQ_STATUS_T, *P_TX_TCQ_STATUS_T; ++ ++typedef struct _TX_TCQ_ADJUST_T { ++ INT_8 acVariation[TC_NUM]; ++} TX_TCQ_ADJUST_T, *P_TX_TCQ_ADJUST_T; ++ ++typedef struct _TX_CTRL_T { ++ UINT_32 u4TxCachedSize; ++ PUINT_8 pucTxCached; ++ ++/* Elements below is classified according to TC (Traffic Class) value. */ ++ ++ TX_TCQ_STATUS_T rTc; ++ ++ PUINT_8 pucTxCoalescingBufPtr; ++ ++ QUE_T rFreeMsduInfoList; ++ ++ /* Management Frame Tracking */ ++ /* number of management frames to be sent */ ++ INT_32 i4TxMgmtPendingNum; ++ ++ /* to tracking management frames need TX done callback */ ++ QUE_T rTxMgmtTxingQueue; ++ ++#if CFG_HIF_STATISTICS ++ UINT_32 u4TotalTxAccessNum; ++ UINT_32 u4TotalTxPacketNum; ++#endif ++ UINT_32 au4Statistics[TX_STATISTIC_COUNTER_NUM]; ++ ++ /* Number to track forwarding frames */ ++ INT_32 i4PendingFwdFrameCount; ++ ++} TX_CTRL_T, *P_TX_CTRL_T; ++ ++typedef enum _ENUM_TX_PACKET_SRC_T { ++ TX_PACKET_OS, ++ TX_PACKET_OS_OID, ++ TX_PACKET_FORWARDING, ++ TX_PACKET_MGMT, ++ TX_PACKET_NUM ++} ENUM_TX_PACKET_SRC_T; ++ ++typedef enum _ENUM_HIF_TX_PACKET_TYPE_T { ++ HIF_TX_PACKET_TYPE_DATA = 0, ++ HIF_TX_PACKET_TYPE_COMMAND, ++ HIF_TX_PACKET_TYPE_HIF_LB, ++ HIF_TX_PACKET_TYPE_MGMT ++} ENUM_HIF_TX_PACKET_TYPE_T, *P_ENUM_HIF_TX_PACKET_TYPE_T; ++ ++typedef enum _ENUM_TX_RESULT_CODE_T { ++ TX_RESULT_SUCCESS = 0, ++ TX_RESULT_LIFE_TIMEOUT, ++ TX_RESULT_RTS_ERROR, ++ TX_RESULT_MPDU_ERROR, ++ TX_RESULT_AGING_TIMEOUT, ++ TX_RESULT_FLUSHED, ++ TX_RESULT_DROPPED_IN_DRIVER = 32, ++ TX_RESULT_NUM ++} ENUM_TX_RESULT_CODE_T, *P_ENUM_TX_RESULT_CODE_T; ++ ++struct _WLAN_CFG_ENTRY_T { ++ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; ++ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++ WLAN_CFG_SET_CB pfSetCb; ++ PVOID pPrivate; ++ UINT_32 u4Flags; ++}; ++ ++struct _WLAN_CFG_T { ++ UINT_32 u4WlanCfgEntryNumMax; ++ UINT_32 u4WlanCfgKeyLenMax; ++ UINT_32 u4WlanCfgValueLenMax; ++ WLAN_CFG_ENTRY_T arWlanCfgBuf[WLAN_CFG_ENTRY_NUM_MAX]; ++}; ++ ++/* TX Call Back Function */ ++typedef WLAN_STATUS(*PFN_TX_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++typedef struct _PKT_PROFILE_T { ++ BOOLEAN fgIsValid; ++#if CFG_PRINT_RTP_PROFILE ++ BOOLEAN fgIsPrinted; ++ UINT_16 u2IpSn; ++ UINT_16 u2RtpSn; ++ UINT_8 ucTcxFreeCount; ++#endif ++ OS_SYSTIME rHardXmitArrivalTimestamp; ++ OS_SYSTIME rEnqueueTimestamp; ++ OS_SYSTIME rDequeueTimestamp; ++ OS_SYSTIME rHifTxDoneTimestamp; ++} PKT_PROFILE_T, *P_PKT_PROFILE_T; ++#endif ++ ++/* TX transactions could be divided into 4 kinds: ++ * ++ * 1) 802.1X / Bluetooth-over-Wi-Fi Security Frames ++ * [CMD_INFO_T] - [prPacket] - in skb or NDIS_PACKET form ++ * ++ * 2) MMPDU ++ * [CMD_INFO_T] - [prPacket] - [MSDU_INFO_T] - [prPacket] - direct buffer for frame body ++ * ++ * 3) Command Packets ++ * [CMD_INFO_T] - [pucInfoBuffer] - direct buffer for content of command packet ++ * ++ * 4) Normal data frame ++ * [MSDU_INFO_T] - [prPacket] - in skb or NDIS_PACKET form ++ */ ++ ++/* PS_FORWARDING_TYPE_NON_PS means that the receiving STA is in Active Mode ++* from the perspective of host driver (maybe not synchronized with FW --> SN is needed) ++*/ ++ ++struct _MSDU_INFO_T { ++ QUE_ENTRY_T rQueEntry; ++ P_NATIVE_PACKET prPacket; ++ ++ ENUM_TX_PACKET_SRC_T eSrc; /* specify OS/FORWARD packet */ ++ UINT_8 ucUserPriority; ++ ++ /* For composing HIF TX header */ ++ UINT_8 ucTC; /* Traffic Class: 0~4 (HIF TX0), 5 (HIF TX1) */ ++ UINT_8 ucPacketType; /* 0: Data, 1: Command, 2: HIF Loopback 3: Management Frame */ ++ UINT_8 ucStaRecIndex; ++ UINT_8 ucNetworkType; /* See ENUM_NETWORK_TYPE_T */ ++ UINT_8 ucFormatID; /* 0: MAUI, Linux, Windows NDIS 5.1 */ ++ BOOLEAN fgIs802_1x; /* TRUE: 802.1x frame */ ++ BOOLEAN fgIs802_11; /* TRUE: 802.11 header is present */ ++ UINT_16 u2PalLLH; /* PAL Logical Link Header (for BOW network) */ ++ UINT_16 u2AclSN; /* ACL Sequence Number (for BOW network) */ ++ UINT_8 ucPsForwardingType; /* See ENUM_PS_FORWARDING_TYPE_T */ ++ UINT_8 ucPsSessionID; /* PS Session ID specified by the FW for the STA */ ++ BOOLEAN fgIsBurstEnd; /* TRUE means this is the last packet of the burst for (STA, TID) */ ++ BOOLEAN fgIsBIP; /* Management Frame Protection */ ++ BOOLEAN fgIsBasicRate; /* Force Basic Rate Transmission */ ++ ++ /* flattened from PACKET_INFO_T */ ++ UINT_8 ucMacHeaderLength; ++ UINT_8 ucLlcLength; /* w/o EtherType */ ++ UINT_16 u2FrameLength; ++ UINT_8 aucEthDestAddr[MAC_ADDR_LEN]; /* Ethernet Destination Address */ ++ ++ /* for TX done tracking */ ++ UINT_8 ucTxSeqNum; ++ PFN_TX_DONE_HANDLER pfTxDoneHandler; ++ BOOLEAN fgNeedTxDoneStatus; ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ PKT_PROFILE_T rPktProfile; ++#endif ++ COMMAND_TYPE eCmdType; ++ UINT_8 ucCID; ++ UINT_32 u4InqueTime; ++}; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define TX_INC_CNT(prTxCtrl, eCounter) \ ++ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]++; } ++ ++#define TX_ADD_CNT(prTxCtrl, eCounter, u8Amount) \ ++ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter] += (UINT_32)u8Amount; } ++ ++#define TX_GET_CNT(prTxCtrl, eCounter) \ ++ (((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]) ++ ++#define TX_RESET_ALL_CNTS(prTxCtrl) \ ++ {kalMemZero(&prTxCtrl->au4Statistics[0], sizeof(prTxCtrl->au4Statistics)); } ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++#define PRINT_PKT_PROFILE(_pkt_profile, _note) \ ++{ \ ++ if (!(_pkt_profile)->fgIsPrinted) { \ ++ DBGLOG(TX, TRACE, "X[%u] E[%u] D[%u] HD[%u] B[%d] RTP[%d] %s\n", \ ++ (UINT_32)((_pkt_profile)->rHardXmitArrivalTimestamp), \ ++ (UINT_32)((_pkt_profile)->rEnqueueTimestamp), \ ++ (UINT_32)((_pkt_profile)->rDequeueTimestamp), \ ++ (UINT_32)((_pkt_profile)->rHifTxDoneTimestamp), \ ++ (UINT_8)((_pkt_profile)->ucTcxFreeCount), \ ++ (UINT_16)((_pkt_profile)->u2RtpSn), \ ++ (_note)); \ ++ (_pkt_profile)->fgIsPrinted = TRUE; \ ++ } \ ++} ++ ++#define CHK_PROFILES_DELTA(_pkt1, _pkt2, _delta) \ ++ (CHECK_FOR_TIMEOUT((_pkt1)->rHardXmitArrivalTimestamp, (_pkt2)->rHardXmitArrivalTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt1)->rEnqueueTimestamp, (_pkt2)->rEnqueueTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt1)->rDequeueTimestamp, (_pkt2)->rDequeueTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt1)->rHifTxDoneTimestamp, (_pkt2)->rHifTxDoneTimestamp, (_delta))) ++ ++#define CHK_PROFILE_DELTA(_pkt, _delta) \ ++ (CHECK_FOR_TIMEOUT((_pkt)->rEnqueueTimestamp, (_pkt)->rHardXmitArrivalTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt)->rDequeueTimestamp, (_pkt)->rEnqueueTimestamp, (_delta)) || \ ++ CHECK_FOR_TIMEOUT((_pkt)->rHifTxDoneTimestamp, (_pkt)->rDequeueTimestamp, (_delta))) ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID nicTxInitialize(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt); ++ ++WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); ++ ++BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_8 *aucTxRlsCnt); ++ ++WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter); ++ ++UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); ++ ++WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue); ++ ++WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); ++ ++VOID nicTxRelease(IN P_ADAPTER_T prAdapter); ++ ++VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter); ++ ++VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prNdisPacket); ++ ++WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); ++ ++WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter); ++#endif ++ ++WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _NIC_TX_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h +new file mode 100644 +index 000000000000..d518aaf10eb5 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h +@@ -0,0 +1,192 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p.h#3 ++*/ ++ ++/* ++** Log: p2p.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * p2p interface revised to be sync. with HAL ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add parameter to control: ++ * 1) auto group owner ++ * 2) P2P-PS parameter (CTWindow, NoA descriptors) ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * correct WPS Device Password ID definition. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement get scan result. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * ++*/ ++ ++#ifndef _P2P_H ++#define _P2P_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* refer to 'Config Methods' in WPS */ ++#define WPS_CONFIG_USBA 0x0001 ++#define WPS_CONFIG_ETHERNET 0x0002 ++#define WPS_CONFIG_LABEL 0x0004 ++#define WPS_CONFIG_DISPLAY 0x0008 ++#define WPS_CONFIG_EXT_NFC 0x0010 ++#define WPS_CONFIG_INT_NFC 0x0020 ++#define WPS_CONFIG_NFC 0x0040 ++#define WPS_CONFIG_PBC 0x0080 ++#define WPS_CONFIG_KEYPAD 0x0100 ++ ++/* refer to 'Device Password ID' in WPS */ ++#define WPS_DEV_PASSWORD_ID_PIN 0x0000 ++#define WPS_DEV_PASSWORD_ID_USER 0x0001 ++#define WPS_DEV_PASSWORD_ID_MACHINE 0x0002 ++#define WPS_DEV_PASSWORD_ID_REKEY 0x0003 ++#define WPS_DEV_PASSWORD_ID_PUSHBUTTON 0x0004 ++#define WPS_DEV_PASSWORD_ID_REGISTRAR 0x0005 ++ ++#define P2P_DEVICE_TYPE_NUM 2 ++#define P2P_DEVICE_NAME_LENGTH 32 ++#define P2P_NETWORK_NUM 8 ++#define P2P_MEMBER_NUM 8 ++ ++#define P2P_WILDCARD_SSID "DIRECT-" ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++struct _P2P_INFO_T { ++ UINT_32 u4DeviceNum; ++ EVENT_P2P_DEV_DISCOVER_RESULT_T arP2pDiscoverResult[CFG_MAX_NUM_BSS_LIST]; ++ PUINT_8 pucCurrIePtr; ++ UINT_8 aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]; /* A common pool for IE of all scan results. */ ++}; ++ ++typedef enum { ++ ENUM_P2P_PEER_GROUP, ++ ENUM_P2P_PEER_DEVICE, ++ ENUM_P2P_PEER_NUM ++} ENUM_P2P_PEER_TYPE, *P_ENUM_P2P_PEER_TYPE; ++ ++typedef struct _P2P_DEVICE_INFO { ++ UINT_8 aucDevAddr[PARAM_MAC_ADDR_LEN]; ++ UINT_8 aucIfAddr[PARAM_MAC_ADDR_LEN]; ++ UINT_8 ucDevCapabilityBitmap; ++ INT_32 i4ConfigMethod; ++ UINT_8 aucPrimaryDeviceType[8]; ++ UINT_8 aucSecondaryDeviceType[8]; ++ UINT_8 aucDeviceName[P2P_DEVICE_NAME_LENGTH]; ++} P2P_DEVICE_INFO, *P_P2P_DEVICE_INFO; ++ ++typedef struct _P2P_GROUP_INFO { ++ PARAM_SSID_T rGroupID; ++ P2P_DEVICE_INFO rGroupOwnerInfo; ++ UINT_8 ucMemberNum; ++ P2P_DEVICE_INFO arMemberInfo[P2P_MEMBER_NUM]; ++} P2P_GROUP_INFO, *P_P2P_GROUP_INFO; ++ ++typedef struct _P2P_NETWORK_INFO { ++ ENUM_P2P_PEER_TYPE eNodeType; ++ ++ union { ++ P2P_GROUP_INFO rGroupInfo; ++ P2P_DEVICE_INFO rDeviceInfo; ++ } node; ++ ++} P2P_NETWORK_INFO, *P_P2P_NETWORK_INFO; ++ ++typedef struct _P2P_NETWORK_LIST { ++ UINT_8 ucNetworkNum; ++ P2P_NETWORK_INFO rP2PNetworkInfo[P2P_NETWORK_NUM]; ++} P2P_NETWORK_LIST, *P_P2P_NETWORK_LIST; ++ ++typedef struct _P2P_DISCONNECT_INFO { ++ UINT_8 ucRole; ++ UINT_8 ucRsv[3]; ++} P2P_DISCONNECT_INFO, *P_P2P_DISCONNECT_INFO; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#endif /*_P2P_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h +new file mode 100644 +index 000000000000..7f7a92584c7c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h +@@ -0,0 +1,83 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "p2p_cmd_buf.h" ++ \brief In this file we define the structure for Command Packet. ++ ++ In this file we define the structure for Command Packet and the control unit ++ of MGMT Memory Pool. ++*/ ++ ++/* ++** Log: p2p_cmd_buf.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++*/ ++ ++#ifndef _P2P_CMD_BUF_H ++#define _P2P_CMD_BUF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*--------------------------------------------------------------*/ ++/* Firmware Command Packer */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ BOOLEAN fgIsOid, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, ++ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); ++ ++#endif /* _P2P_CMD_BUF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h +new file mode 100644 +index 000000000000..76115dabe1a1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h +@@ -0,0 +1,207 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_mac.h#2 ++*/ ++ ++/*! \file "p2p_mac.h" ++ \brief Brief description. ++ ++ Detail description. ++*/ ++ ++#ifndef _P2P_MAC_H ++#define _P2P_MAC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define ACTION_PUBLIC_WIFI_DIRECT 9 ++#define ACTION_GAS_INITIAL_REQUEST 10 ++#define ACTION_GAS_INITIAL_RESPONSE 11 ++#define ACTION_GAS_COMEBACK_REQUEST 12 ++#define ACTION_GAS_COMEBACK_RESPONSE 13 ++ ++/* P2P 4.2.8.1 - P2P Public Action Frame Type. */ ++#define P2P_PUBLIC_ACTION_GO_NEGO_REQ 0 ++#define P2P_PUBLIC_ACTION_GO_NEGO_RSP 1 ++#define P2P_PUBLIC_ACTION_GO_NEGO_CFM 2 ++#define P2P_PUBLIC_ACTION_INVITATION_REQ 3 ++#define P2P_PUBLIC_ACTION_INVITATION_RSP 4 ++#define P2P_PUBLIC_ACTION_DEV_DISCOVER_REQ 5 ++#define P2P_PUBLIC_ACTION_DEV_DISCOVER_RSP 6 ++#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_REQ 7 ++#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_RSP 8 ++ ++/* P2P 4.2.9.1 - P2P Action Frame Type */ ++#define P2P_ACTION_NOTICE_OF_ABSENCE 0 ++#define P2P_ACTION_P2P_PRESENCE_REQ 1 ++#define P2P_ACTION_P2P_PRESENCE_RSP 2 ++#define P2P_ACTION_GO_DISCOVER_REQ 3 ++ ++#define P2P_PUBLIC_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+8) ++#define P2P_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+7) ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/* P2P 4.2.8.2 P2P Public Action Frame Format */ ++typedef struct _P2P_PUBLIC_ACTION_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ ++ UINT_8 ucOuiType; /* 0x09 */ ++ UINT_8 ucOuiSubtype; /* GO Nego Req/Rsp/Cfm, P2P Invittion Req/Rsp, Device Discoverability Req/Rsp */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_8 aucInfoElem[1]; /* P2P IE, WSC IE. */ ++} __KAL_ATTRIB_PACKED__ P2P_PUBLIC_ACTION_FRAME_T, *P_P2P_PUBLIC_ACTION_FRAME_T; ++ ++/* P2P 4.2.9.1 - General Action Frame Format. */ ++typedef struct _P2P_ACTION_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Action Frame Body */ ++ UINT_8 ucCategory; /* 0x7F */ ++ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ ++ UINT_8 ucOuiType; /* 0x09 */ ++ UINT_8 ucOuiSubtype; /* */ ++ UINT_8 ucDialogToken; ++ UINT_8 aucInfoElem[1]; ++} __KAL_ATTRIB_PACKED__ P2P_ACTION_FRAME_T, *P_P2P_ACTION_FRAME_T; ++ ++/* P2P C.1 GAS Public Action Initial Request Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T; ++ ++/* P2P C.2 GAS Public Action Initial Response Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_16 u2StatusCode; /* Initial Response. */ ++ UINT_16 u2ComebackDelay; /* Initial Response. *//* In unit of TU. */ ++ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T; ++ ++/* P2P C.3-1 GAS Public Action Comeback Request Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T; ++ ++/* P2P C.3-2 GAS Public Action Comeback Response Frame Format */ ++typedef struct _GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T { ++ /* MAC header */ ++ UINT_16 u2FrameCtrl; /* Frame Control */ ++ UINT_16 u2Duration; /* Duration */ ++ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ ++ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ ++ UINT_16 u2SeqCtrl; /* Sequence Control */ ++ /* P2P Public Action Frame Body */ ++ UINT_8 ucCategory; /* Category, 0x04 */ ++ UINT_8 ucAction; /* Action Value, 0x09 */ ++ UINT_8 ucDialogToken; /* Dialog Token. */ ++ UINT_16 u2StatusCode; /* Comeback Response. */ ++ UINT_8 ucFragmentID; /*Comeback Response. */ ++ UINT_16 u2ComebackDelay; /* Comeback Response. */ ++ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ ++} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T; ++ ++typedef struct _P2P_SD_VENDER_SPECIFIC_CONTENT_T { ++ /* Service Discovery Vendor-specific Content. */ ++ UINT_8 ucOuiSubtype; /* 0x09 */ ++ UINT_16 u2ServiceUpdateIndicator; ++ UINT_8 aucServiceTLV[1]; ++} __KAL_ATTRIB_PACKED__ P2P_SD_VENDER_SPECIFIC_CONTENT_T, *P_P2P_SD_VENDER_SPECIFIC_CONTENT_T; ++ ++typedef struct _P2P_SERVICE_REQUEST_TLV_T { ++ UINT_16 u2Length; ++ UINT_8 ucServiceProtocolType; ++ UINT_8 ucServiceTransID; ++ UINT_8 aucQueryData[1]; ++} __KAL_ATTRIB_PACKED__ P2P_SERVICE_REQUEST_TLV_T, *P_P2P_SERVICE_REQUEST_TLV_T; ++ ++typedef struct _P2P_SERVICE_RESPONSE_TLV_T { ++ UINT_16 u2Length; ++ UINT_8 ucServiceProtocolType; ++ UINT_8 ucServiceTransID; ++ UINT_8 ucStatusCode; ++ UINT_8 aucResponseData[1]; ++} __KAL_ATTRIB_PACKED__ P2P_SERVICE_RESPONSE_TLV_T, *P_P2P_SERVICE_RESPONSE_TLV_T; ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h +new file mode 100644 +index 000000000000..0a87bd457a92 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h +@@ -0,0 +1,62 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic.h#1 ++*/ ++ ++/*! \file "p2p_nic.h" ++ \brief The declaration of nic functions ++ ++ Detail description. ++*/ ++ ++#ifndef _P2P_NIC_H ++#define _P2P_NIC_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++VOID ++nicP2pMediaStateChange(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); ++ ++VOID ++nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, ++ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h +new file mode 100644 +index 000000000000..cea77414ce35 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h +@@ -0,0 +1,70 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic_cmd_event.h#1 ++*/ ++ ++/*! \file p2p_nic_cmd_event.h ++ \brief ++*/ ++ ++#ifndef _P2P_NIC_CMD_EVENT_H ++#define _P2P_NIC_CMD_EVENT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++typedef struct _EVENT_P2P_DEV_DISCOVER_RESULT_T { ++/* UINT_8 aucCommunicateAddr[MAC_ADDR_LEN]; // Deprecated. */ ++ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ ++ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Device Address. */ ++ UINT_8 ucDeviceCapabilityBitmap; ++ UINT_8 ucGroupCapabilityBitmap; ++ UINT_16 u2ConfigMethod; /* Configure Method. */ ++ P2P_DEVICE_TYPE_T rPriDevType; ++ UINT_8 ucSecDevTypeNum; ++ P2P_DEVICE_TYPE_T arSecDevType[2]; ++ UINT_16 u2NameLength; ++ UINT_8 aucName[32]; ++ PUINT_8 pucIeBuf; ++ UINT_16 u2IELength; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ /* TODO: Service Information or PasswordID valid? */ ++} EVENT_P2P_DEV_DISCOVER_RESULT_T, *P_EVENT_P2P_DEV_DISCOVER_RESULT_T; ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h +new file mode 100644 +index 000000000000..dbfb90d94ee4 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h +@@ -0,0 +1,971 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/que_mgt.h#1 ++*/ ++ ++/*! \file "que_mgt.h" ++ \brief TX/RX queues management header file ++ ++ The main tasks of queue management include TC-based HIF TX flow control, ++ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save ++ forwarding control, RX packet reordering, and RX BA agreement management. ++*/ ++ ++/* ++** Log: que_mgt.h ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 07 26 2011 eddie.chen ++ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter ++ * API for query the RX reorder queued packets counter. ++ * ++ * 06 14 2011 eddie.chen ++ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 ++ * Change the parameter for WMM pass. ++ * ++ * 05 31 2011 eddie.chen ++ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 ++ * Fix the QM quota in MT5931. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 04 14 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Check the SW RFB free. Fix the compile warning.. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW ++ * Fix wmm parameters in beacon for BOW. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 01 12 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * 1) Check Bss if support QoS before adding WMMIE ++ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 07 22 2010 george.huang ++ * ++ * Update fgIsQoS information in BSS INFO by CMD ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 13 2010 yarco.yang ++ * ++ * [WPD00003849] ++ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 30 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled adaptive TC resource control ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 19 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * By default enabling dynamic STA_REC activation and decactivation ++ * ++ * 03 17 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) ++ * ++ * 03 11 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Fixed buffer leak when processing BAR frames ++ * ++ * 02 25 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled multi-STA TX path with fairness ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled dynamically activating and deactivating STA_RECs ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added code for dynamic activating and deactivating STA_RECs. ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:04:53 GMT MTK02468 ++** Added RX buffer reordering function prototypes ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-02 22:08:44 GMT MTK02468 ++** Added macro QM_INIT_STA_REC for initialize a STA_REC ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 21:58:43 GMT mtk02468 ++** Initial version ++** ++*/ ++ ++#ifndef _QUE_MGT_H ++#define _QUE_MGT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* Queue Manager Features */ ++/* 1: Indicate the last TX packet to the FW for each burst */ ++#define QM_BURST_END_INFO_ENABLED 1 ++/* 1: To fairly share TX resource among active STAs */ ++#define QM_FORWARDING_FAIRNESS 1 ++/* 1: To adaptively adjust resource for each TC */ ++#define QM_ADAPTIVE_TC_RESOURCE_CTRL 1 ++/* 1: To print TC resource adjustment results */ ++#define QM_PRINT_TC_RESOURCE_CTRL 0 ++/* 1: If pkt with SSN is missing, auto advance the RX reordering window */ ++#define QM_RX_WIN_SSN_AUTO_ADVANCING 1 ++/* 1: Indicate the packets falling behind to OS before the frame with SSN is received */ ++#define QM_RX_INIT_FALL_BEHIND_PASS 1 ++/* 1: Count times of TC resource empty happened */ ++#define QM_TC_RESOURCE_EMPTY_COUNTER 1 ++/* Parameters */ ++ ++/* ++ In TDLS or AP mode, peer maybe enter "sleep mode". ++ ++ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, ++ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets ++ u4TimeToAdjustTcResource = 3, ++ then we will adjust TC resouce for VI or VO. ++ ++ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, ++ we will to wait about 12 seconds to collect 180 packets. ++ but the test time is only 20 seconds. ++*/ ++#define QM_INIT_TIME_TO_UPDATE_QUE_LEN 60 /* p: Update queue lengths when p TX packets are enqueued */ ++#define QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN 5 ++ ++#define QM_INIT_TIME_TO_ADJUST_TC_RSC 3 /* s: Adjust the TC resource every s updates of queue lengths */ ++#define QM_QUE_LEN_MOVING_AVE_FACTOR 3 /* Factor for Que Len averaging */ ++ ++#define QM_MIN_RESERVED_TC0_RESOURCE 1 ++#define QM_MIN_RESERVED_TC1_RESOURCE 1 ++#define QM_MIN_RESERVED_TC2_RESOURCE 1 ++#define QM_MIN_RESERVED_TC3_RESOURCE 1 ++#define QM_MIN_RESERVED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ ++#define QM_MIN_RESERVED_TC5_RESOURCE 1 ++ ++#if defined(MT6620) ++ ++#define QM_GUARANTEED_TC0_RESOURCE 4 ++#define QM_GUARANTEED_TC1_RESOURCE 4 ++#define QM_GUARANTEED_TC2_RESOURCE 9 ++#define QM_GUARANTEED_TC3_RESOURCE 11 ++#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ ++#define QM_GUARANTEED_TC5_RESOURCE 4 ++ ++#elif defined(MT6628) ++ ++#define QM_GUARANTEED_TC0_RESOURCE 4 ++#define QM_GUARANTEED_TC1_RESOURCE 4 ++#define QM_GUARANTEED_TC2_RESOURCE 6 ++#define QM_GUARANTEED_TC3_RESOURCE 6 ++#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ ++#define QM_GUARANTEED_TC5_RESOURCE 4 ++ ++#else ++#error ++#endif ++ ++#define QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY 0 ++ ++#define QM_TOTAL_TC_RESOURCE (\ ++ NIC_TX_BUFF_COUNT_TC0 + NIC_TX_BUFF_COUNT_TC1 +\ ++ NIC_TX_BUFF_COUNT_TC2 + NIC_TX_BUFF_COUNT_TC3 +\ ++ NIC_TX_BUFF_COUNT_TC5) ++#define QM_AVERAGE_TC_RESOURCE 6 ++ ++/* Note: QM_INITIAL_RESIDUAL_TC_RESOURCE shall not be less than 0 */ ++/* for 6628: QM_TOTAL_TC_RESOURCE = 28, RESIDUAL = 4 4 6 6 2 4 = 26 */ ++#define QM_INITIAL_RESIDUAL_TC_RESOURCE (QM_TOTAL_TC_RESOURCE - \ ++ (QM_GUARANTEED_TC0_RESOURCE +\ ++ QM_GUARANTEED_TC1_RESOURCE +\ ++ QM_GUARANTEED_TC2_RESOURCE +\ ++ QM_GUARANTEED_TC3_RESOURCE +\ ++ QM_GUARANTEED_TC5_RESOURCE \ ++ )) ++ ++/* Hard-coded network type for Phase 3: NETWORK_TYPE_AIS/P2P/BOW */ ++#define QM_OPERATING_NETWORK_TYPE NETWORK_TYPE_AIS ++ ++#define QM_TEST_MODE 0 ++#define QM_TEST_TRIGGER_TX_COUNT 50 ++#define QM_TEST_STA_REC_DETERMINATION 0 ++#define QM_TEST_STA_REC_DEACTIVATION 0 ++#define QM_TEST_FAIR_FORWARDING 0 ++ ++#define QM_DEBUG_COUNTER 0 ++ ++/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ ++/* Per-Type Queues: [0] BMCAST */ ++#define NUM_OF_PER_STA_TX_QUEUES 5 ++#define NUM_OF_PER_TYPE_TX_QUEUES 1 ++ ++/* These two constants are also used for FW to verify the STA_REC index */ ++#define STA_REC_INDEX_BMCAST 0xFF ++#define STA_REC_INDEX_NOT_FOUND 0xFE ++ ++/* TX Queue Index */ ++#define TX_QUEUE_INDEX_BMCAST 0 ++#define TX_QUEUE_INDEX_NO_STA_REC 0 ++#define TX_QUEUE_INDEX_AC0 0 ++#define TX_QUEUE_INDEX_AC1 1 ++#define TX_QUEUE_INDEX_AC2 2 ++#define TX_QUEUE_INDEX_AC3 3 ++#define TX_QUEUE_INDEX_802_1X 4 ++#define TX_QUEUE_INDEX_NON_QOS 1 ++ ++/* 1 WMM-related */ ++/* WMM FLAGS */ ++#define WMM_FLAG_SUPPORT_WMM BIT(0) ++#define WMM_FLAG_SUPPORT_WMMSA BIT(1) ++#define WMM_FLAG_AC_PARAM_PRESENT BIT(2) ++#define WMM_FLAG_SUPPORT_UAPSD BIT(3) ++ ++/* WMM Admission Control Mandatory FLAGS */ ++#define ACM_FLAG_ADM_NOT_REQUIRED 0 ++#define ACM_FLAG_ADM_GRANTED BIT(0) ++#define ACM_FLAG_ADM_REQUIRED BIT(1) ++ ++/* WMM Power Saving FLAGS */ ++#define AC_FLAG_TRIGGER_ENABLED BIT(1) ++#define AC_FLAG_DELIVERY_ENABLED BIT(2) ++ ++/* WMM-2.2.1 WMM Information Element */ ++#define ELEM_MAX_LEN_WMM_INFO 7 ++ ++/* WMM-2.2.2 WMM Parameter Element */ ++#define ELEM_MAX_LEN_WMM_PARAM 24 ++ ++/* WMM-2.2.1 WMM QoS Info field */ ++#define WMM_QOS_INFO_PARAM_SET_CNT BITS(0, 3) /* Sent by AP */ ++#define WMM_QOS_INFO_UAPSD BIT(7) ++ ++#define WMM_QOS_INFO_VO_UAPSD BIT(0) /* Sent by non-AP STA */ ++#define WMM_QOS_INFO_VI_UAPSD BIT(1) ++#define WMM_QOS_INFO_BK_UAPSD BIT(2) ++#define WMM_QOS_INFO_BE_UAPSD BIT(3) ++#define WMM_QOS_INFO_MAX_SP_LEN_MASK BITS(5, 6) ++#define WMM_QOS_INFO_MAX_SP_ALL 0 ++#define WMM_QOS_INFO_MAX_SP_2 BIT(5) ++#define WMM_QOS_INFO_MAX_SP_4 BIT(6) ++#define WMM_QOS_INFO_MAX_SP_6 BITS(5, 6) ++ ++/* -- definitions for Max SP length field */ ++#define WMM_MAX_SP_LENGTH_ALL 0 ++#define WMM_MAX_SP_LENGTH_2 2 ++#define WMM_MAX_SP_LENGTH_4 4 ++#define WMM_MAX_SP_LENGTH_6 6 ++ ++/* WMM-2.2.2 WMM ACI/AIFSN field */ ++/* -- subfields in the ACI/AIFSN field */ ++#define WMM_ACIAIFSN_AIFSN BITS(0, 3) ++#define WMM_ACIAIFSN_ACM BIT(4) ++#define WMM_ACIAIFSN_ACI BITS(5, 6) ++#define WMM_ACIAIFSN_ACI_OFFSET 5 ++ ++/* -- definitions for ACI field */ ++#define WMM_ACI_AC_BE 0 ++#define WMM_ACI_AC_BK BIT(5) ++#define WMM_ACI_AC_VI BIT(6) ++#define WMM_ACI_AC_VO BITS(5, 6) ++ ++#define WMM_ACI(_AC) (_AC << WMM_ACIAIFSN_ACI_OFFSET) ++ ++/* -- definitions for ECWmin/ECWmax field */ ++#define WMM_ECW_WMIN_MASK BITS(0, 3) ++#define WMM_ECW_WMAX_MASK BITS(4, 7) ++#define WMM_ECW_WMAX_OFFSET 4 ++ ++#define TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME 0 /* Unit: 64 us */ ++ ++#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS (1000) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++enum { ++ QM_DBG_CNT_00 = 0, ++ QM_DBG_CNT_01, ++ QM_DBG_CNT_02, ++ QM_DBG_CNT_03, ++ QM_DBG_CNT_04, ++ QM_DBG_CNT_05, ++ QM_DBG_CNT_06, ++ QM_DBG_CNT_07, ++ QM_DBG_CNT_08, ++ QM_DBG_CNT_09, ++ QM_DBG_CNT_10, ++ QM_DBG_CNT_11, ++ QM_DBG_CNT_12, ++ QM_DBG_CNT_13, ++ QM_DBG_CNT_14, ++ QM_DBG_CNT_15, ++ QM_DBG_CNT_16, ++ QM_DBG_CNT_17, ++ QM_DBG_CNT_18, ++ QM_DBG_CNT_19, ++ QM_DBG_CNT_20, ++ QM_DBG_CNT_21, ++ QM_DBG_CNT_22, ++ QM_DBG_CNT_23, ++ QM_DBG_CNT_24, ++ QM_DBG_CNT_25, ++ QM_DBG_CNT_26, ++ QM_DBG_CNT_27, ++ QM_DBG_CNT_28, ++ QM_DBG_CNT_29, ++ QM_DBG_CNT_30, ++ QM_DBG_CNT_31, ++ QM_DBG_CNT_NUM ++}; ++ ++/* Used for MAC TX */ ++typedef enum _ENUM_MAC_TX_QUEUE_INDEX_T { ++ MAC_TX_QUEUE_AC0_INDEX = 0, ++ MAC_TX_QUEUE_AC1_INDEX, ++ MAC_TX_QUEUE_AC2_INDEX, ++ MAC_TX_QUEUE_AC3_INDEX, ++ MAC_TX_QUEUE_AC4_INDEX, ++ MAC_TX_QUEUE_AC5_INDEX, ++ MAC_TX_QUEUE_AC6_INDEX, ++ MAC_TX_QUEUE_BCN_INDEX, ++ MAC_TX_QUEUE_BMC_INDEX, ++ MAC_TX_QUEUE_NUM ++} ENUM_MAC_TX_QUEUE_INDEX_T; ++ ++typedef struct _RX_BA_ENTRY_T { ++ BOOLEAN fgIsValid; ++ QUE_T rReOrderQue; ++ UINT_16 u2WinStart; ++ UINT_16 u2WinEnd; ++ UINT_16 u2WinSize; ++ ++ /* For identifying the RX BA agreement */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucTid; ++ ++ BOOLEAN fgIsWaitingForPktWithSsn; ++ ++ /* UINT_8 ucTxBufferSize; */ ++ /* BOOL fgIsAcConstrain; */ ++ /* BOOL fgIsBaEnabled; */ ++} RX_BA_ENTRY_T, *P_RX_BA_ENTRY_T; ++ ++/* The mailbox message (could be used for Host-To-Device or Device-To-Host Mailbox) */ ++typedef struct _MAILBOX_MSG_T { ++ UINT_32 u4Msg[2]; /* [0]: D2HRM0R or H2DRM0R, [1]: D2HRM1R or H2DRM1R */ ++} MAILBOX_MSG_T, *P_MAILBOX_MSG_T; ++ ++/* Used for adaptively adjusting TC resources */ ++typedef struct _TC_RESOURCE_CTRL_T { ++ /* TC0, TC1, TC2, TC3, TC5 */ ++ UINT_32 au4AverageQueLen[TC_NUM - 1]; ++} TC_RESOURCE_CTRL_T, *P_TC_RESOURCE_CTRL_T; ++ ++typedef struct _QUE_MGT_T { /* Queue Management Control Info */ ++ ++ /* Per-Type Queues: [0] BMCAST or UNKNOWN-STA packets */ ++ QUE_T arTxQueue[NUM_OF_PER_TYPE_TX_QUEUES]; ++ ++#if 0 ++ /* For TX Scheduling */ ++ UINT_8 arRemainingTxOppt[NUM_OF_PER_STA_TX_QUEUES]; ++ UINT_8 arCurrentTxStaIndex[NUM_OF_PER_STA_TX_QUEUES]; ++ ++#endif ++ ++ /* Reordering Queue Parameters */ ++ RX_BA_ENTRY_T arRxBaTable[CFG_NUM_OF_RX_BA_AGREEMENTS]; ++ ++ /* Current number of activated RX BA agreements <= CFG_NUM_OF_RX_BA_AGREEMENTS */ ++ UINT_8 ucRxBaCount; ++ ++#if QM_TEST_MODE ++ UINT_32 u4PktCount; ++ P_ADAPTER_T prAdapter; ++ ++#if QM_TEST_FAIR_FORWARDING ++ UINT_32 u4CurrentStaRecIndexToEnqueue; ++#endif ++ ++#endif ++ ++#if QM_FORWARDING_FAIRNESS ++ /* The current TX count for a STA with respect to a TC index */ ++ UINT_32 au4ForwardCount[NUM_OF_PER_STA_TX_QUEUES]; ++ ++ /* The current serving STA with respect to a TC index */ ++ UINT_32 au4HeadStaRecIndex[NUM_OF_PER_STA_TX_QUEUES]; ++#endif ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ UINT_32 au4AverageQueLen[TC_NUM]; ++ UINT_32 au4CurrentTcResource[TC_NUM]; ++ UINT_32 au4MinReservedTcResource[TC_NUM]; /* The minimum amount of resource no matter busy or idle */ ++ UINT_32 au4GuaranteedTcResource[TC_NUM]; /* The minimum amount of resource when extremely busy */ ++ ++ UINT_32 u4TimeToAdjustTcResource; ++ UINT_32 u4TimeToUpdateQueLen; ++ UINT_32 u4TxNumOfVi, u4TxNumOfVo; /* number of VI/VO packets */ ++ ++ /* Set to TRUE if the last TC adjustment has not been completely applied (i.e., waiting more TX-Done events ++ to align the TC quotas to the TC resource assignment) */ ++ BOOLEAN fgTcResourcePostAnnealing; ++ ++#endif ++ ++#if QM_DEBUG_COUNTER ++ UINT_32 au4QmDebugCounters[QM_DBG_CNT_NUM]; ++#endif ++#if QM_TC_RESOURCE_EMPTY_COUNTER ++ UINT_32 au4QmTcResourceEmptyCounter[NET_TYPE_NUM][TC_NUM]; ++ UINT_32 au4QmTcResourceBackCounter[TC_NUM]; ++ UINT_32 au4DequeueNoTcResourceCounter[TC_NUM]; ++ ++ UINT_32 au4ResourceUsedCounter[TC_NUM]; ++ ++ UINT_32 au4ResourceWantedCounter[TC_NUM]; ++ ++ UINT_32 u4EnqeueuCounter; ++ UINT_32 u4DequeueCounter; ++#endif ++} QUE_MGT_T, *P_QUE_MGT_T; ++ ++typedef struct _EVENT_RX_ADDBA_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Fields not present in the received ADDBA_REQ */ ++ UINT_8 ucStaRecIdx; ++ ++ /* Fields that are present in the received ADDBA_REQ */ ++ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ ++ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ ++ UINT_16 u2BATimeoutValue; ++ UINT_16 u2BAStartSeqCtrl; /* SSN */ ++ ++} EVENT_RX_ADDBA_T, *P_EVENT_RX_ADDBA_T; ++ ++typedef struct _EVENT_RX_DELBA_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Fields not present in the received ADDBA_REQ */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucTid; ++} EVENT_RX_DELBA_T, *P_EVENT_RX_DELBA_T; ++ ++typedef struct _EVENT_BSS_ABSENCE_PRESENCE_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Event Body */ ++ UINT_8 ucNetTypeIdx; ++ BOOLEAN fgIsAbsent; ++ UINT_8 ucBssFreeQuota; ++ UINT_8 aucReserved[1]; ++} EVENT_BSS_ABSENCE_PRESENCE_T, *P_EVENT_BSS_ABSENCE_PRESENCE_T; ++ ++typedef struct _EVENT_STA_CHANGE_PS_MODE_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Event Body */ ++ UINT_8 ucStaRecIdx; ++ BOOLEAN fgIsInPs; ++ UINT_8 ucUpdateMode; ++ UINT_8 ucFreeQuota; ++} EVENT_STA_CHANGE_PS_MODE_T, *P_EVENT_STA_CHANGE_PS_MODE_T; ++ ++/* The free quota is used by PS only now */ ++/* The event may be used by per STA flow conttrol in general */ ++typedef struct _EVENT_STA_UPDATE_FREE_QUOTA_T { ++ /* Event header */ ++ UINT_16 u2Length; ++ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ /* Event Body */ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucUpdateMode; ++ UINT_8 ucFreeQuota; ++ UINT_8 aucReserved[1]; ++} EVENT_STA_UPDATE_FREE_QUOTA_T, *P_EVENT_STA_UPDATE_FREE_QUOTA_T; ++ ++/* WMM-2.2.1 WMM Information Element */ ++typedef struct _IE_WMM_INFO_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ UINT_8 ucQosInfo; /* QoS Info field */ ++ UINT_8 ucDummy[3]; /* Dummy for pack */ ++} IE_WMM_INFO_T, *P_IE_WMM_INFO_T; ++ ++/* WMM-2.2.2 WMM Parameter Element */ ++typedef struct _IE_WMM_PARAM_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ ++ /* IE Body */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ ++ /* WMM IE Body */ ++ UINT_8 ucQosInfo; /* QoS Info field */ ++ UINT_8 ucReserved; ++ ++ /* AC Parameters */ ++ UINT_8 ucAciAifsn_BE; ++ UINT_8 ucEcw_BE; ++ UINT_8 aucTxopLimit_BE[2]; ++ ++ UINT_8 ucAciAifsn_BG; ++ UINT_8 ucEcw_BG; ++ UINT_8 aucTxopLimit_BG[2]; ++ ++ UINT_8 ucAciAifsn_VI; ++ UINT_8 ucEcw_VI; ++ UINT_8 aucTxopLimit_VI[2]; ++ ++ UINT_8 ucAciAifsn_VO; ++ UINT_8 ucEcw_VO; ++ UINT_8 aucTxopLimit_VO[2]; ++ ++} IE_WMM_PARAM_T, *P_IE_WMM_PARAM_T; ++ ++typedef struct _IE_WMM_TSPEC_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ /* WMM TSPEC body */ ++ UINT_8 aucTsInfo[3]; /* TS Info */ ++ UINT_8 aucTspecBodyPart[1]; /* Note: Utilize PARAM_QOS_TSPEC to fill (memory copy) */ ++} IE_WMM_TSPEC_T, *P_IE_WMM_TSPEC_T; ++ ++typedef struct _IE_WMM_HDR_T { ++ UINT_8 ucId; /* Element ID */ ++ UINT_8 ucLength; /* Length */ ++ UINT_8 aucOui[3]; /* OUI */ ++ UINT_8 ucOuiType; /* OUI Type */ ++ UINT_8 ucOuiSubtype; /* OUI Subtype */ ++ UINT_8 ucVersion; /* Version */ ++ UINT_8 aucBody[1]; /* IE body */ ++} IE_WMM_HDR_T, *P_IE_WMM_HDR_T; ++ ++typedef struct _AC_QUE_PARMS_T { ++ UINT_16 u2CWmin; /*!< CWmin */ ++ UINT_16 u2CWmax; /*!< CWmax */ ++ UINT_16 u2TxopLimit; /*!< TXOP limit */ ++ UINT_16 u2Aifsn; /*!< AIFSN */ ++ UINT_8 ucGuradTime; /*!< GuardTime for STOP/FLUSH. */ ++ BOOLEAN fgIsACMSet; ++} AC_QUE_PARMS_T, *P_AC_QUE_PARMS_T; ++ ++/* WMM ACI (AC index) */ ++typedef enum _ENUM_WMM_ACI_T { ++ WMM_AC_BE_INDEX = 0, ++ WMM_AC_BK_INDEX, ++ WMM_AC_VI_INDEX, ++ WMM_AC_VO_INDEX, ++ WMM_AC_INDEX_NUM ++} ENUM_WMM_ACI_T, *P_ENUM_WMM_ACI_T; ++ ++/* Used for CMD Queue Operation */ ++typedef enum _ENUM_FRAME_ACTION_T { ++ FRAME_ACTION_DROP_PKT = 0, ++ FRAME_ACTION_QUEUE_PKT, ++ FRAME_ACTION_TX_PKT, ++ FRAME_ACTION_NUM ++} ENUM_FRAME_ACTION_T; ++ ++typedef enum _ENUM_FRAME_TYPE_IN_CMD_Q_T { ++ FRAME_TYPE_802_1X = 0, ++ FRAME_TYPE_MMPDU, ++ FRAME_TYPE_NUM ++} ENUM_FRAME_TYPE_IN_CMD_Q_T; ++ ++typedef enum _ENUM_FREE_QUOTA_MODET_T { ++ FREE_QUOTA_UPDATE_MODE_INIT = 0, ++ FREE_QUOTA_UPDATE_MODE_OVERWRITE, ++ FREE_QUOTA_UPDATE_MODE_INCREASE, ++ FREE_QUOTA_UPDATE_MODE_DECREASE ++} ENUM_FREE_QUOTA_MODET_T, *P_ENUM_FREE_QUOTA_MODET_T; ++ ++typedef struct _CMD_UPDATE_WMM_PARMS_T { ++ AC_QUE_PARMS_T arACQueParms[AC_NUM]; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 fgIsQBSS; ++ UINT_8 aucReserved[2]; ++} CMD_UPDATE_WMM_PARMS_T, *P_CMD_UPDATE_WMM_PARMS_T; ++ ++typedef struct _CMD_TX_AMPDU_T { ++ BOOLEAN fgEnable; ++ UINT_8 aucReserved[3]; ++} CMD_TX_AMPDU_T, *P_CMD_TX_AMPDU_T; ++ ++typedef struct _CMD_ADDBA_REJECT { ++ BOOLEAN fgEnable; ++ UINT_8 aucReserved[3]; ++} CMD_ADDBA_REJECT_T, *P_CMD_ADDBA_REJECT_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#define QM_TX_SET_NEXT_MSDU_INFO(_prMsduInfoPreceding, _prMsduInfoNext) \ ++ ((((_prMsduInfoPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prMsduInfoNext)) ++ ++#define QM_TX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ ++ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) ++ ++#define QM_TX_GET_NEXT_MSDU_INFO(_prMsduInfo) \ ++ ((P_MSDU_INFO_T)(((_prMsduInfo)->rQueEntry).prNext)) ++ ++#define QM_RX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ ++ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) ++ ++#define QM_RX_GET_NEXT_SW_RFB(_prSwRfb) \ ++ ((P_SW_RFB_T)(((_prSwRfb)->rQueEntry).prNext)) ++ ++#if 0 ++#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ ++ ((((_ucIndex) != STA_REC_INDEX_BMCAST) && ((_ucIndex) != STA_REC_INDEX_NOT_FOUND)) ?\ ++ &(_prAdapter->arStaRec[_ucIndex]) : NULL) ++#endif ++ ++#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ ++ cnmGetStaRecByIndex(_prAdapter, _ucIndex) ++ ++#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(\ ++ _prMsduInfo,\ ++ _ucTC,\ ++ _ucPacketType,\ ++ _ucFormatID,\ ++ _fgIs802_1x,\ ++ _fgIs802_11,\ ++ _u2PalLLH,\ ++ _u2AclSN,\ ++ _ucPsForwardingType,\ ++ _ucPsSessionID\ ++ ) \ ++{\ ++ ASSERT(_prMsduInfo);\ ++ (_prMsduInfo)->ucTC = (_ucTC);\ ++ (_prMsduInfo)->ucPacketType = (_ucPacketType);\ ++ (_prMsduInfo)->ucFormatID = (_ucFormatID);\ ++ (_prMsduInfo)->fgIs802_1x = (_fgIs802_1x);\ ++ (_prMsduInfo)->fgIs802_11 = (_fgIs802_11);\ ++ (_prMsduInfo)->u2PalLLH = (_u2PalLLH);\ ++ (_prMsduInfo)->u2AclSN = (_u2AclSN);\ ++ (_prMsduInfo)->ucPsForwardingType = (_ucPsForwardingType);\ ++ (_prMsduInfo)->ucPsSessionID = (_ucPsSessionID);\ ++ (_prMsduInfo)->fgIsBurstEnd = (FALSE);\ ++} ++ ++#define QM_INIT_STA_REC(\ ++ _prStaRec,\ ++ _fgIsValid,\ ++ _fgIsQoS,\ ++ _pucMacAddr\ ++ )\ ++{\ ++ ASSERT(_prStaRec);\ ++ (_prStaRec)->fgIsValid = (_fgIsValid);\ ++ (_prStaRec)->fgIsQoS = (_fgIsQoS);\ ++ (_prStaRec)->fgIsInPS = FALSE; \ ++ (_prStaRec)->ucPsSessionID = 0xFF;\ ++ COPY_MAC_ADDR((_prStaRec)->aucMacAddr, (_pucMacAddr));\ ++} ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++#define QM_GET_TX_QUEUE_LEN(_prAdapter, _u4QueIdx) \ ++ ((_prAdapter->rQM.au4AverageQueLen[(_u4QueIdx)] >> QM_QUE_LEN_MOVING_AVE_FACTOR)) ++#endif ++ ++#define WMM_IE_OUI_TYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiType) ++#define WMM_IE_OUI_SUBTYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiSubtype) ++#define WMM_IE_OUI(fp) (((P_IE_WMM_HDR_T)(fp))->aucOui) ++ ++#if QM_DEBUG_COUNTER ++#define QM_DBG_CNT_INC(_prQM, _index) { (_prQM)->au4QmDebugCounters[(_index)]++; } ++#else ++#define QM_DBG_CNT_INC(_prQM, _index) {} ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Queue Management and STA_REC Initialization */ ++/*----------------------------------------------------------------------------*/ ++ ++VOID qmInit(IN P_ADAPTER_T prAdapter); ++ ++#if QM_TEST_MODE ++VOID qmTestCases(IN P_ADAPTER_T prAdapter); ++#endif ++ ++VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); ++ ++/*----------------------------------------------------------------------------*/ ++/* TX-Related Queue Management */ ++/*----------------------------------------------------------------------------*/ ++ ++P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter); ++ ++P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); ++ ++P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus); ++ ++VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus); ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter); ++ ++VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* RX-Related Queue Management */ ++/*----------------------------------------------------------------------------*/ ++ ++VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter); ++ ++P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter); ++ ++P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); ++ ++VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); ++ ++VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); ++ ++VOID ++qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); ++ ++VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); ++ ++BOOLEAN ++qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout); ++ ++VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); ++ ++VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg); ++ ++BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater); ++ ++VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid); ++ ++BOOLEAN ++qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize); ++ ++VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost); ++ ++VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); ++ ++VOID ++mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride); ++ ++VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams); ++ ++VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec); ++ ++/* Utility function: for deciding STA-REC index */ ++UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); ++ ++UINT_32 ++mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, ++ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf); ++ ++VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode); ++ ++VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++ENUM_FRAME_ACTION_T ++qmGetFrameAction(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, ++ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType); ++ ++VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); ++ ++VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); ++ ++VOID ++qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone); ++ ++VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter); ++ ++#if ARP_MONITER_ENABLE ++VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++VOID qmResetArpDetect(VOID); ++VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++#endif ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _QUE_MGT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h +new file mode 100644 +index 000000000000..2804b0387f5f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h +@@ -0,0 +1,1010 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/wlan_def.h#1 ++*/ ++ ++/*! \file "wlan_def.h" ++ \brief This file includes the basic definition of WLAN ++ ++*/ ++ ++/* ++** Log: wlan_def.h ++** ++** 09 02 2013 cp.wu ++** add path to handle reassociation request ++ * ++ * 12 05 2011 cp.wu ++ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path ++ * add CONNECT_BY_BSSID policy ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 wh.su ++ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h and let the sw ++ * structure not align at byte ++ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, ++ * Notice needed update P2P.ko. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Resize the Secondary Device Type array when WiFi Direct is enabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Add new station type MACRO. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 11 2010 kevin.huang ++ * [WCXRP00000068] [MT6620 Wi-Fi][Driver][FW] Fix STA RECORD sync issue and remove unused code ++ * Update ENUM_STA_ROLE_INDEX_T by using a fixed base value ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Update OP_MODE_BOW and include bow_fsm.h. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Change P2P Descriptor List to a pointer and allocate it dynamically to avoid structure corrupt by BssDescriptor free. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add a pointer in BSS Descriptor for P2P Descriptor. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add an Interface in BSS Descriptor. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Modify data structure for P2P Scan result. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add an operation mode for P2P device. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * P2P/RSN/WAPI IEs need to be declared with compact structure. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly ++ * dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Add P2P present boolean flag in BSS & Pre-BSS descriptor. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * move bss related data types to wlan_def.h to avoid recursive dependency. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:40 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _WLAN_DEF_H ++#define _WLAN_DEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* disconnect reason */ ++#define DISCONNECT_REASON_CODE_RESERVED 0 ++#define DISCONNECT_REASON_CODE_RADIO_LOST 1 ++#define DISCONNECT_REASON_CODE_DEAUTHENTICATED 2 ++#define DISCONNECT_REASON_CODE_DISASSOCIATED 3 ++#define DISCONNECT_REASON_CODE_NEW_CONNECTION 4 ++#define DISCONNECT_REASON_CODE_REASSOCIATION 5 ++#define DISCONNECT_REASON_CODE_ROAMING 6 ++ ++/* The rate definitions */ ++#define TX_MODE_CCK 0x00 ++#define TX_MODE_OFDM 0x40 ++#define TX_MODE_HT_MM 0x80 ++#define TX_MODE_HT_GF 0xC0 ++ ++#define RATE_CCK_SHORT_PREAMBLE 0x10 ++#define RATE_OFDM 0x20 ++ ++#define PHY_RATE_1M 0x0 ++#define PHY_RATE_2M 0x1 ++#define PHY_RATE_5_5M 0x2 ++#define PHY_RATE_11M 0x3 ++#define PHY_RATE_6M 0xB ++#define PHY_RATE_9M 0xF ++#define PHY_RATE_12M 0xA ++#define PHY_RATE_18M 0xE ++#define PHY_RATE_24M 0x9 ++#define PHY_RATE_36M 0xD ++#define PHY_RATE_48M 0x8 ++#define PHY_RATE_54M 0xC ++#define PHY_RATE_MCS0 0x0 ++#define PHY_RATE_MCS1 0x1 ++#define PHY_RATE_MCS2 0x2 ++#define PHY_RATE_MCS3 0x3 ++#define PHY_RATE_MCS4 0x4 ++#define PHY_RATE_MCS5 0x5 ++#define PHY_RATE_MCS6 0x6 ++#define PHY_RATE_MCS7 0x7 ++#define PHY_RATE_MCS32 0x20 ++ ++#define RATE_CCK_1M_LONG (TX_MODE_CCK | PHY_RATE_1M) ++#define RATE_CCK_2M_LONG (TX_MODE_CCK | PHY_RATE_2M) ++#define RATE_CCK_5_5M_LONG (TX_MODE_CCK | PHY_RATE_5_5M) ++#define RATE_CCK_11M_LONG (TX_MODE_CCK | PHY_RATE_11M) ++#define RATE_CCK_2M_SHORT (TX_MODE_CCK | PHY_RATE_2M | RATE_CCK_SHORT_PREAMBLE) ++#define RATE_CCK_5_5M_SHORT (TX_MODE_CCK | PHY_RATE_5_5M | RATE_CCK_SHORT_PREAMBLE) ++#define RATE_CCK_11M_SHORT (TX_MODE_CCK | PHY_RATE_11M | RATE_CCK_SHORT_PREAMBLE) ++#define RATE_OFDM_6M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_6M) ++#define RATE_OFDM_9M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_9M) ++#define RATE_OFDM_12M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_12M) ++#define RATE_OFDM_18M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_18M) ++#define RATE_OFDM_24M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_24M) ++#define RATE_OFDM_36M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_36M) ++#define RATE_OFDM_48M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_48M) ++#define RATE_OFDM_54M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_54M) ++ ++#define RATE_MM_MCS_0 (TX_MODE_HT_MM | PHY_RATE_MCS0) ++#define RATE_MM_MCS_1 (TX_MODE_HT_MM | PHY_RATE_MCS1) ++#define RATE_MM_MCS_2 (TX_MODE_HT_MM | PHY_RATE_MCS2) ++#define RATE_MM_MCS_3 (TX_MODE_HT_MM | PHY_RATE_MCS3) ++#define RATE_MM_MCS_4 (TX_MODE_HT_MM | PHY_RATE_MCS4) ++#define RATE_MM_MCS_5 (TX_MODE_HT_MM | PHY_RATE_MCS5) ++#define RATE_MM_MCS_6 (TX_MODE_HT_MM | PHY_RATE_MCS6) ++#define RATE_MM_MCS_7 (TX_MODE_HT_MM | PHY_RATE_MCS7) ++#define RATE_MM_MCS_32 (TX_MODE_HT_MM | PHY_RATE_MCS32) ++ ++#define RATE_GF_MCS_0 (TX_MODE_HT_GF | PHY_RATE_MCS0) ++#define RATE_GF_MCS_1 (TX_MODE_HT_GF | PHY_RATE_MCS1) ++#define RATE_GF_MCS_2 (TX_MODE_HT_GF | PHY_RATE_MCS2) ++#define RATE_GF_MCS_3 (TX_MODE_HT_GF | PHY_RATE_MCS3) ++#define RATE_GF_MCS_4 (TX_MODE_HT_GF | PHY_RATE_MCS4) ++#define RATE_GF_MCS_5 (TX_MODE_HT_GF | PHY_RATE_MCS5) ++#define RATE_GF_MCS_6 (TX_MODE_HT_GF | PHY_RATE_MCS6) ++#define RATE_GF_MCS_7 (TX_MODE_HT_GF | PHY_RATE_MCS7) ++#define RATE_GF_MCS_32 (TX_MODE_HT_GF | PHY_RATE_MCS32) ++ ++#define RATE_TX_MODE_MASK BITS(6, 7) ++#define RATE_TX_MODE_OFFSET 6 ++#define RATE_CODE_GET_TX_MODE(_ucRateCode) ((_ucRateCode & RATE_TX_MODE_MASK) >> RATE_TX_MODE_OFFSET) ++#define RATE_PHY_RATE_MASK BITS(0, 5) ++#define RATE_PHY_RATE_OFFSET 0 ++#define RATE_CODE_GET_PHY_RATE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_MASK) >> RATE_PHY_RATE_OFFSET) ++#define RATE_PHY_RATE_SHORT_PREAMBLE BIT(4) ++#define RATE_CODE_IS_SHORT_PREAMBLE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_SHORT_PREAMBLE)?TRUE:FALSE) ++ ++#define CHNL_LIST_SZ_2G 14 ++#define CHNL_LIST_SZ_5G 14 ++ ++/*! CNM(STA_RECORD_T) related definition */ ++#define CFG_STA_REC_NUM 20 ++ ++/* PHY TYPE bit definitions */ ++#define PHY_TYPE_BIT_HR_DSSS BIT(PHY_TYPE_HR_DSSS_INDEX) /* HR/DSSS PHY (clause 18) */ ++#define PHY_TYPE_BIT_ERP BIT(PHY_TYPE_ERP_INDEX) /* ERP PHY (clause 19) */ ++#define PHY_TYPE_BIT_OFDM BIT(PHY_TYPE_OFDM_INDEX) /* OFDM 5 GHz PHY (clause 17) */ ++#define PHY_TYPE_BIT_HT BIT(PHY_TYPE_HT_INDEX) /* HT PHY (clause 20) */ ++ ++/* PHY TYPE set definitions */ ++#define PHY_TYPE_SET_802_11ABGN (PHY_TYPE_BIT_OFDM | \ ++ PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11BGN (PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11GN (PHY_TYPE_BIT_ERP | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11AN (PHY_TYPE_BIT_OFDM | \ ++ PHY_TYPE_BIT_HT) ++ ++#define PHY_TYPE_SET_802_11ABG (PHY_TYPE_BIT_OFDM | \ ++ PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP) ++ ++#define PHY_TYPE_SET_802_11BG (PHY_TYPE_BIT_HR_DSSS | \ ++ PHY_TYPE_BIT_ERP) ++ ++#define PHY_TYPE_SET_802_11A (PHY_TYPE_BIT_OFDM) ++ ++#define PHY_TYPE_SET_802_11G (PHY_TYPE_BIT_ERP) ++ ++#define PHY_TYPE_SET_802_11B (PHY_TYPE_BIT_HR_DSSS) ++ ++#define PHY_TYPE_SET_802_11N (PHY_TYPE_BIT_HT) ++ ++/* Rate set bit definitions */ ++#define RATE_SET_BIT_1M BIT(RATE_1M_INDEX) /* Bit 0: 1M */ ++#define RATE_SET_BIT_2M BIT(RATE_2M_INDEX) /* Bit 1: 2M */ ++#define RATE_SET_BIT_5_5M BIT(RATE_5_5M_INDEX) /* Bit 2: 5.5M */ ++#define RATE_SET_BIT_11M BIT(RATE_11M_INDEX) /* Bit 3: 11M */ ++#define RATE_SET_BIT_22M BIT(RATE_22M_INDEX) /* Bit 4: 22M */ ++#define RATE_SET_BIT_33M BIT(RATE_33M_INDEX) /* Bit 5: 33M */ ++#define RATE_SET_BIT_6M BIT(RATE_6M_INDEX) /* Bit 6: 6M */ ++#define RATE_SET_BIT_9M BIT(RATE_9M_INDEX) /* Bit 7: 9M */ ++#define RATE_SET_BIT_12M BIT(RATE_12M_INDEX) /* Bit 8: 12M */ ++#define RATE_SET_BIT_18M BIT(RATE_18M_INDEX) /* Bit 9: 18M */ ++#define RATE_SET_BIT_24M BIT(RATE_24M_INDEX) /* Bit 10: 24M */ ++#define RATE_SET_BIT_36M BIT(RATE_36M_INDEX) /* Bit 11: 36M */ ++#define RATE_SET_BIT_48M BIT(RATE_48M_INDEX) /* Bit 12: 48M */ ++#define RATE_SET_BIT_54M BIT(RATE_54M_INDEX) /* Bit 13: 54M */ ++#define RATE_SET_BIT_HT_PHY BIT(RATE_HT_PHY_INDEX) /* Bit 14: BSS Selector */ ++ ++/* Rate set definitions */ ++#define RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M) ++ ++#define RATE_SET_ERP (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_18M | \ ++ RATE_SET_BIT_24M | \ ++ RATE_SET_BIT_36M | \ ++ RATE_SET_BIT_48M | \ ++ RATE_SET_BIT_54M) ++ ++#define RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_18M | \ ++ RATE_SET_BIT_24M | \ ++ RATE_SET_BIT_36M | \ ++ RATE_SET_BIT_48M | \ ++ RATE_SET_BIT_54M) ++ ++#define RATE_SET_OFDM (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_18M | \ ++ RATE_SET_BIT_24M | \ ++ RATE_SET_BIT_36M | \ ++ RATE_SET_BIT_48M | \ ++ RATE_SET_BIT_54M) ++ ++#define RATE_SET_HT (RATE_SET_ERP) ++/* #define RATE_SET_HT (RATE_SET_ERP | RATE_SET_BIT_HT_PHY) *//* NOTE(Kevin): TBD */ ++ ++#define RATE_SET_ALL_ABG RATE_SET_ERP ++ ++#define BASIC_RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M) ++ ++#define BASIC_RATE_SET_HR_DSSS_ERP (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M) ++ ++#define BASIC_RATE_SET_ERP (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define BASIC_RATE_SET_OFDM (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define BASIC_RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define INITIAL_RATE_SET_RCPI_100 RATE_SET_ALL_ABG ++ ++#define INITIAL_RATE_SET_RCPI_80 (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M | \ ++ RATE_SET_BIT_9M | \ ++ RATE_SET_BIT_12M | \ ++ RATE_SET_BIT_24M) ++ ++#define INITIAL_RATE_SET_RCPI_60 (RATE_SET_BIT_1M | \ ++ RATE_SET_BIT_2M | \ ++ RATE_SET_BIT_5_5M | \ ++ RATE_SET_BIT_11M | \ ++ RATE_SET_BIT_6M) ++ ++#define INITIAL_RATE_SET(_rcpi) (INITIAL_RATE_SET_ ## _rcpi) ++ ++#define RCPI_100 100 /* -60 dBm */ ++#define RCPI_80 80 /* -70 dBm */ ++#define RCPI_60 60 /* -80 dBm */ ++ ++/* The number of RCPI records used to calculate their average value */ ++#define MAX_NUM_RCPI_RECORDS 10 ++ ++/* The number of RCPI records used to calculate their average value */ ++#define NO_RCPI_RECORDS -128 ++#define MAX_RCPI_DBM 0 ++#define MIN_RCPI_DBM -100 ++ ++#define MAC_TX_RESERVED_FIELD 0 /* NOTE(Kevin): Should defined in tx.h */ ++ ++#define MAX_ASSOC_ID (CFG_STA_REC_NUM) /* Available AID: 1 ~ 20(STA_REC_NUM) */ ++ ++#define MAX_DEAUTH_INFO_COUNT 4 /* NOTE(Kevin): Used in auth.c */ ++#define MIN_DEAUTH_INTERVAL_MSEC 500 /* The minimum interval if continuously send Deauth Frame */ ++ ++/* Authentication Type */ ++#define AUTH_TYPE_OPEN_SYSTEM BIT(AUTH_ALGORITHM_NUM_OPEN_SYSTEM) ++#define AUTH_TYPE_SHARED_KEY BIT(AUTH_ALGORITHM_NUM_SHARED_KEY) ++#define AUTH_TYPE_FAST_BSS_TRANSITION BIT(AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) ++ ++/* Authentication Retry Limit */ ++#define TX_AUTH_ASSOCI_RETRY_LIMIT 2 ++#define TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING 1 ++ ++/* WMM-2.2.1 WMM Information Element */ ++#define ELEM_MAX_LEN_WMM_INFO 7 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef UINT_16 PHY_TYPE, *P_PHY_TYPE; ++typedef UINT_8 RCPI, *P_RCPI; ++typedef UINT_8 ALC_VAL, *P_ALC_VAL; ++ ++typedef enum _ENUM_HW_BSSID_T { ++ BSSID_0 = 0, ++ BSSID_1, ++ BSSID_NUM ++} ENUM_HW_BSSID_T; ++ ++typedef enum _ENUM_HW_MAC_ADDR_T { ++ MAC_ADDR_0 = 0, ++ MAC_ADDR_1, ++ MAC_ADDR_NUM ++} ENUM_HW_MAC_ADDR_T; ++ ++typedef enum _ENUM_HW_OP_MODE_T { ++ HW_OP_MODE_STA = 0, ++ HW_OP_MODE_AP, ++ HW_OP_MODE_ADHOC, ++ HW_OP_MODE_NUM ++} ENUM_HW_OP_MODE_T; ++ ++typedef enum _ENUM_TSF_T { ++ ENUM_LOCAL_TSF_0, ++ ENUM_LOCAL_TSF_1, ++ ENUM_LOCAL_TSF_NUM ++} ENUM_LOCAL_TSF_T, *P_ENUM_LOCAL_TSF_T; ++ ++typedef enum _HAL_TS_HW_UPDATE_MODE { ++ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME, ++ HAL_TSF_HW_UPDATE_BY_TICK_ONLY, ++ HAL_TSF_HW_UPDATE_BY_RECEIVED_FRAME_ONLY, ++ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME_AD_HOC ++} HAL_TSF_HW_UPDATE_MODE; ++ ++typedef enum _ENUM_AC_T { ++ AC0 = 0, ++ AC1, ++ AC2, ++ AC3, ++ AC_NUM ++} ENUM_AC_T, *P_ENUM_AC_T; ++ ++/* The Type of Network been activated */ ++typedef enum _ENUM_NETWORK_TYPE_INDEX_T { ++ NETWORK_TYPE_AIS_INDEX = 0, ++ NETWORK_TYPE_P2P_INDEX, ++ NETWORK_TYPE_BOW_INDEX, ++ NETWORK_TYPE_INDEX_NUM ++} ENUM_NETWORK_TYPE_INDEX_T; ++ ++/* The Type of STA Type. */ ++typedef enum _ENUM_STA_TYPE_INDEX_T { ++ STA_TYPE_LEGACY_INDEX = 0, ++ STA_TYPE_P2P_INDEX, ++ STA_TYPE_BOW_INDEX, ++ STA_TYPE_INDEX_NUM ++} ENUM_STA_TYPE_INDEX_T; ++ ++#define STA_ROLE_BASE_INDEX 4 ++ ++typedef enum _ENUM_STA_ROLE_INDEX_T { ++ STA_ROLE_ADHOC_INDEX = STA_ROLE_BASE_INDEX, /* 4 */ ++ STA_ROLE_CLIENT_INDEX, ++ STA_ROLE_AP_INDEX, ++ STA_ROLE_TDLS_INDEX, ++ STA_ROLE_DLS_INDEX /* Note: need to extend P_CMD_UPDATE_STA_RECORD_T */ ++} ENUM_STA_ROLE_INDEX_T; ++ ++/* The Power State of a specific Network */ ++typedef enum _ENUM_PWR_STATE_T { ++ PWR_STATE_IDLE = 0, ++ PWR_STATE_ACTIVE, ++ PWR_STATE_PS, ++ PWR_STATE_NUM ++} ENUM_PWR_STATE_T; ++ ++typedef enum _ENUM_PHY_TYPE_INDEX_T { ++ /* PHY_TYPE_DSSS_INDEX, *//* DSSS PHY (clause 15) -- Not used anymore */ ++ PHY_TYPE_HR_DSSS_INDEX = 0, /* HR/DSSS PHY (clause 18) */ ++ PHY_TYPE_ERP_INDEX, /* ERP PHY (clause 19) */ ++ PHY_TYPE_ERP_P2P_INDEX, /* ERP PHY (clause 19) w/o HR/DSSS */ ++ PHY_TYPE_OFDM_INDEX, /* OFDM 5 GHz PHY (clause 17) */ ++ PHY_TYPE_HT_INDEX, /* HT PHY (clause 20) */ ++ PHY_TYPE_INDEX_NUM /* 5 */ ++} ENUM_PHY_TYPE_INDEX_T, *P_ENUM_PHY_TYPE_INDEX_T; ++ ++typedef enum _ENUM_ACPI_STATE_T { ++ ACPI_STATE_D0 = 0, ++ ACPI_STATE_D1, ++ ACPI_STATE_D2, ++ ACPI_STATE_D3 ++} ENUM_ACPI_STATE_T; ++ ++/* The operation mode of a specific Network */ ++typedef enum _ENUM_OP_MODE_T { ++ OP_MODE_INFRASTRUCTURE = 0, /* Infrastructure/GC */ ++ OP_MODE_IBSS, /* AdHoc */ ++ OP_MODE_ACCESS_POINT, /* For GO */ ++ OP_MODE_P2P_DEVICE, /* P2P Device */ ++ OP_MODE_BOW, ++ OP_MODE_NUM ++} ENUM_OP_MODE_T, *P_ENUM_OP_MODE_T; ++ ++typedef enum _ENUM_CHNL_EXT_T { ++ CHNL_EXT_SCN = 0, ++ CHNL_EXT_SCA = 1, ++ CHNL_EXT_RES = 2, ++ CHNL_EXT_SCB = 3 ++} ENUM_CHNL_EXT_T, *P_ENUM_CHNL_EXT_T; ++ ++/* This starting freq of the band is unit of kHz */ ++typedef enum _ENUM_BAND_T { ++ BAND_NULL, ++ BAND_2G4, ++ BAND_5G, ++ BAND_NUM ++} ENUM_BAND_T, *P_ENUM_BAND_T; ++ ++/* Provide supported channel list to other components in array format */ ++typedef struct _RF_CHANNEL_INFO_T { ++ ENUM_BAND_T eBand; ++ UINT_8 ucChannelNum; ++} RF_CHANNEL_INFO_T, *P_RF_CHANNEL_INFO_T; ++ ++typedef enum _ENUM_RATE_INDEX_T { ++ RATE_1M_INDEX = 0, /* 1M */ ++ RATE_2M_INDEX, /* 2M */ ++ RATE_5_5M_INDEX, /* 5.5M */ ++ RATE_11M_INDEX, /* 11M */ ++ RATE_22M_INDEX, /* 22M */ ++ RATE_33M_INDEX, /* 33M */ ++ RATE_6M_INDEX, /* 6M */ ++ RATE_9M_INDEX, /* 9M */ ++ RATE_12M_INDEX, /* 12M */ ++ RATE_18M_INDEX, /* 18M */ ++ RATE_24M_INDEX, /* 24M */ ++ RATE_36M_INDEX, /* 36M */ ++ RATE_48M_INDEX, /* 48M */ ++ RATE_54M_INDEX, /* 54M */ ++ RATE_HT_PHY_INDEX, /* BSS Selector - HT PHY */ ++ RATE_NUM /* 15 */ ++} ENUM_RATE_INDEX_T, *P_ENUM_RATE_INDEX_T; ++ ++typedef enum _ENUM_HT_RATE_INDEX_T { ++ HT_RATE_MCS0_INDEX = 0, ++ HT_RATE_MCS1_INDEX, ++ HT_RATE_MCS2_INDEX, ++ HT_RATE_MCS3_INDEX, ++ HT_RATE_MCS4_INDEX, ++ HT_RATE_MCS5_INDEX, ++ HT_RATE_MCS6_INDEX, ++ HT_RATE_MCS7_INDEX, ++ HT_RATE_MCS32_INDEX, ++ HT_RATE_NUM /* 9 */ ++} ENUM_HT_RATE_INDEX_T, *P_ENUM_HT_RATE_INDEX_T; ++ ++typedef enum _ENUM_PREMABLE_OPTION_T { ++ PREAMBLE_DEFAULT_LONG_NONE = 0, /* LONG for PHY_TYPE_HR_DSSS, NONE for PHY_TYPE_OFDM */ ++ PREAMBLE_OPTION_SHORT, /* SHORT mandatory for PHY_TYPE_ERP, SHORT option for PHY_TYPE_HR_DSSS */ ++ PREAMBLE_HT_MIXED_MODE, ++ PREAMBLE_HT_GREEN_FIELD, ++ PREAMBLE_OPTION_NUM ++} ENUM_PREMABLE_OPTION_T, *P_ENUM_PREMABLE_OPTION_T; ++ ++typedef enum _ENUM_CHANNEL_WIDTH_T { ++ CW_20_40MHZ = 0, ++ CW_80MHZ = 1, ++ CW_160MHZ = 2, ++ CW_80P80MHZ = 3 ++} ENUM_CHANNEL_WIDTH_T, *P_ENUM_CHANNEL_WIDTH_P; ++ ++typedef enum _ENUM_MODULATION_SYSTEM_T { ++ MODULATION_SYSTEM_CCK = 0, ++ MODULATION_SYSTEM_OFDM, ++ MODULATION_SYSTEM_HT20, ++ MODULATION_SYSTEM_HT40, ++ MODULATION_SYSTEM_NUM ++} ENUM_MODULATION_SYSTEM_T, *P_ENUM_MODULATION_SYSTEM_T; ++ ++typedef enum _ENUM_MODULATION_TYPE_T { ++ MODULATION_TYPE_CCK_BPSK = 0, ++ MODULATION_TYPE_QPSK, ++ MODULATION_TYPE_16QAM, ++ MODULATION_TYPE_64QAM, ++ MODULATION_TYPE_NUM ++} ENUM_MODULATION_TYPE_T, *P_ENUM_MODULATION_TYPE_T; ++ ++typedef enum _ENUM_PS_FORWARDING_TYPE_T { ++ PS_FORWARDING_TYPE_NON_PS = 0, ++ PS_FORWARDING_TYPE_DELIVERY_ENABLED, ++ PS_FORWARDING_TYPE_NON_DELIVERY_ENABLED, ++ PS_FORWARDING_MORE_DATA_ENABLED, ++ PS_FORWARDING_TYPE_NUM ++} ENUM_PS_FORWARDING_TYPE_T, *P_ENUM_PS_FORWARDING_TYPE_T; ++ ++typedef struct _DEAUTH_INFO_T { ++ UINT_8 aucRxAddr[MAC_ADDR_LEN]; ++ OS_SYSTIME rLastSendTime; ++} DEAUTH_INFO_T, *P_DEAUTH_INFO_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* Information Element (IE) handlers */ ++/*----------------------------------------------------------------------------*/ ++typedef VOID(*PFN_APPEND_IE_FUNC) (P_ADAPTER_T, P_MSDU_INFO_T); ++typedef VOID(*PFN_HANDLE_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T); ++typedef VOID(*PFN_VERIFY_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T, PUINT_16); ++typedef UINT_32(*PFN_CALCULATE_VAR_IE_LEN_FUNC) (P_ADAPTER_T, ENUM_NETWORK_TYPE_INDEX_T, P_STA_RECORD_T); ++ ++typedef struct _APPEND_IE_ENTRY_T { ++ UINT_16 u2EstimatedIELen; ++ PFN_APPEND_IE_FUNC pfnAppendIE; ++} APPEND_IE_ENTRY_T, *P_APPEND_IE_ENTRY_T; ++ ++typedef struct _APPEND_VAR_IE_ENTRY_T { ++ UINT_16 u2EstimatedFixedIELen; /* For Fixed Length */ ++ PFN_CALCULATE_VAR_IE_LEN_FUNC pfnCalculateVariableIELen; ++ PFN_APPEND_IE_FUNC pfnAppendIE; ++} APPEND_VAR_IE_ENTRY_T, *P_APPEND_VAR_IE_ENTRY_T; ++ ++typedef struct _HANDLE_IE_ENTRY_T { ++ UINT_8 ucElemID; ++ PFN_HANDLE_IE_FUNC pfnHandleIE; ++} HANDLE_IE_ENTRY_T, *P_HANDLE_IE_ENTRY_T; ++ ++typedef struct _VERIFY_IE_ENTRY_T { ++ UINT_8 ucElemID; ++ PFN_VERIFY_IE_FUNC pfnVarifyIE; ++} VERIFY_IE_ENTRY_T, *P_VERIFY_IE_ENTRY_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* Parameters of User Configuration */ ++/*----------------------------------------------------------------------------*/ ++typedef enum _ENUM_PARAM_CONNECTION_POLICY_T { ++ CONNECT_BY_SSID_BEST_RSSI = 0, ++ CONNECT_BY_SSID_GOOD_RSSI_MIN_CH_LOAD, ++ CONNECT_BY_SSID_ANY, /* NOTE(Kevin): Needed by WHQL */ ++ CONNECT_BY_BSSID, ++ CONNECT_BY_CUSTOMIZED_RULE /* NOTE(Kevin): TBD */ ++} ENUM_PARAM_CONNECTION_POLICY_T, *P_ENUM_PARAM_CONNECTION_POLICY_T; ++ ++typedef enum _ENUM_PARAM_PREAMBLE_TYPE_T { ++ PREAMBLE_TYPE_LONG = 0, ++ PREAMBLE_TYPE_SHORT, ++ PREAMBLE_TYPE_AUTO /*!< Try preamble short first, if fail tray preamble long. */ ++} ENUM_PARAM_PREAMBLE_TYPE_T, *P_ENUM_PARAM_PREAMBLE_TYPE_T; ++ ++/* This is enum defined for user to select a phy config listed in combo box */ ++typedef enum _ENUM_PARAM_PHY_CONFIG_T { ++ /*!< Can associated with 802.11abg AP but without n capability, Scan dual band. */ ++ PHY_CONFIG_802_11ABG = 0, ++ PHY_CONFIG_802_11BG, /*!< Can associated with 802_11bg AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11G, /*!< Can associated with 802_11g only AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11A, /*!< Can associated with 802_11a only AP, Scan single band and not report 2.4G BSSs. */ ++ PHY_CONFIG_802_11B, /*!< Can associated with 802_11b only AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11ABGN, /*!< Can associated with 802.11abgn AP, Scan dual band. */ ++ PHY_CONFIG_802_11BGN, /*!< Can associated with 802_11bgn AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_802_11AN, /*!< Can associated with 802_11an AP, Scan single band and not report 2.4G BSSs. */ ++ PHY_CONFIG_802_11GN, /*!< Can associated with 802_11gn AP, Scan single band and not report 5G BSSs. */ ++ PHY_CONFIG_NUM /* 9 */ ++} ENUM_PARAM_PHY_CONFIG_T, *P_ENUM_PARAM_PHY_CONFIG_T; ++ ++/* This is enum defined for user to select an AP Mode */ ++typedef enum _ENUM_PARAM_AP_MODE_T { ++ AP_MODE_11B = 0, /*!< Create 11b BSS if we support 802.11abg/802.11bg. */ ++ AP_MODE_MIXED_11BG, /*!< Create 11bg mixed BSS if we support 802.11abg/802.11bg/802.11g. */ ++ AP_MODE_11G, /*!< Create 11g only BSS if we support 802.11abg/802.11bg/802.11g. */ ++ AP_MODE_11G_P2P, /*!< Create 11g only BSS for P2P if we support 802.11abg/802.11bg/802.11g. */ ++ AP_MODE_11A, /*!< Create 11a only BSS if we support 802.11abg. */ ++ AP_MODE_NUM /* 4 */ ++} ENUM_PARAM_AP_MODE_T, *P_ENUM_PARAM_AP_MODE_T; ++ ++/* Masks for determining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ ++#define NETWORK_TYPE_AIS_MASK BIT(NETWORK_TYPE_AIS_INDEX) ++#define NETWORK_TYPE_P2P_MASK BIT(NETWORK_TYPE_P2P_INDEX) ++#define NETWORK_TYPE_BOW_MASK BIT(NETWORK_TYPE_BOW_INDEX) ++#define STA_TYPE_LEGACY_MASK BIT(STA_TYPE_LEGACY_INDEX) ++#define STA_TYPE_P2P_MASK BIT(STA_TYPE_P2P_INDEX) ++#define STA_TYPE_BOW_MASK BIT(STA_TYPE_BOW_INDEX) ++#define STA_TYPE_ADHOC_MASK BIT(STA_ROLE_ADHOC_INDEX) ++#define STA_TYPE_CLIENT_MASK BIT(STA_ROLE_CLIENT_INDEX) ++#define STA_TYPE_AP_MASK BIT(STA_ROLE_AP_INDEX) ++#define STA_TYPE_DLS_MASK BIT(STA_ROLE_DLS_INDEX) ++#define STA_TYPE_TDLS_MASK BIT(STA_ROLE_TDLS_INDEX) ++ ++/* Macros for obtaining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ ++#define IS_STA_IN_AIS(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) ++#define IS_STA_IN_P2P(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++#define IS_STA_IN_BOW(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++#define IS_STA_LEGACY_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_LEGACY_MASK) ++#define IS_STA_P2P_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_P2P_MASK) ++#define IS_STA_BOW_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_BOW_MASK) ++#define IS_ADHOC_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_ADHOC_MASK) ++#define IS_CLIENT_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_CLIENT_MASK) ++#define IS_AP_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_AP_MASK) ++#define IS_DLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_DLS_MASK) ++#define IS_TDLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_TDLS_MASK) ++ ++/* The ENUM_STA_TYPE_T accounts for ENUM_NETWORK_TYPE_T and ENUM_STA_ROLE_INDEX_T. ++ * * It is a merged version of Network Type and STA Role. ++ * */ ++typedef enum _ENUM_STA_TYPE_T { ++ STA_TYPE_LEGACY_AP = (STA_TYPE_LEGACY_MASK | STA_TYPE_AP_MASK), ++ STA_TYPE_LEGACY_CLIENT = (STA_TYPE_LEGACY_MASK | STA_TYPE_CLIENT_MASK), ++ STA_TYPE_ADHOC_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_ADHOC_MASK), ++#if CFG_ENABLE_WIFI_DIRECT ++ STA_TYPE_P2P_GO = (STA_TYPE_P2P_MASK | STA_TYPE_AP_MASK), ++ STA_TYPE_P2P_GC = (STA_TYPE_P2P_MASK | STA_TYPE_CLIENT_MASK), ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ STA_TYPE_BOW_AP = (STA_TYPE_BOW_MASK | STA_TYPE_AP_MASK), ++ STA_TYPE_BOW_CLIENT = (STA_TYPE_BOW_MASK | STA_TYPE_CLIENT_MASK), ++#endif ++ STA_TYPE_DLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_DLS_MASK), ++ STA_TYPE_TDLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_TDLS_MASK) ++} ENUM_STA_TYPE_T, *P_ENUM_STA_TYPE_T; ++ ++/* The type of BSS we discovered */ ++typedef enum _ENUM_BSS_TYPE_T { ++ BSS_TYPE_INFRASTRUCTURE = 1, ++ BSS_TYPE_IBSS, ++ BSS_TYPE_P2P_DEVICE, ++ BSS_TYPE_BOW_DEVICE, ++ BSS_TYPE_NUM ++} ENUM_BSS_TYPE_T, *P_ENUM_BSS_TYPE_T; ++ ++/*----------------------------------------------------------------------------*/ ++/* RSN structures */ ++/*----------------------------------------------------------------------------*/ ++/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ ++/* #pragma pack(1) */ ++/* #endif */ ++ ++#define MAX_NUM_SUPPORTED_CIPHER_SUITES 8 /* max number of supported cipher suites */ ++#if CFG_SUPPORT_802_11W ++#define MAX_NUM_SUPPORTED_AKM_SUITES 8 /* max number of supported AKM suites */ ++#else ++#define MAX_NUM_SUPPORTED_AKM_SUITES 6 /* max number of supported AKM suites */ ++#endif ++ ++/* Structure of RSN Information */ ++typedef struct _RSN_INFO_T { ++ UINT_8 ucElemId; ++ UINT_16 u2Version; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_32 u4PairwiseKeyCipherSuiteCount; ++ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_CIPHER_SUITES]; ++ UINT_32 u4AuthKeyMgtSuiteCount; ++ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_AKM_SUITES]; ++ UINT_16 u2RsnCap; ++ BOOLEAN fgRsnCapPresent; ++} /*__KAL_ATTRIB_PACKED__*/ RSN_INFO_T, *P_RSN_INFO_T; ++ ++#define MAX_NUM_SUPPORTED_WAPI_AKM_SUITES 1 /* max number of supported AKM suites */ ++#define MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES 1 /* max number of supported cipher suites */ ++ ++/* Structure of WAPI Information */ ++typedef struct _WAPI_INFO_T { ++ UINT_8 ucElemId; ++ UCHAR ucLength; ++ UINT_16 u2Version; ++ UINT_32 u4AuthKeyMgtSuiteCount; ++ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_WAPI_AKM_SUITES]; ++ UINT_32 u4PairwiseKeyCipherSuiteCount; ++ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES]; ++ UINT_32 u4GroupKeyCipherSuite; ++ UINT_16 u2WapiCap; ++ UINT_16 u2Bkid; ++ UINT_8 aucBkid[1][16]; ++} /* __KAL_ATTRIB_PACKED__ */ WAPI_INFO_T, *P_WAPI_INFO_T; ++ ++/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ ++/* #pragma pack() */ ++/* #endif */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++typedef struct _P2P_DEVICE_TYPE_T { ++ UINT_16 u2CategoryID; ++ UINT_16 u2SubCategoryID; ++} P2P_DEVICE_TYPE_T, *P_P2P_DEVICE_TYPE_T; ++ ++typedef struct _P2P_DEVICE_DESC_T { ++ LINK_ENTRY_T rLinkEntry; ++ BOOLEAN fgDevInfoValid; ++ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ ++ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Interface Address. */ ++ UINT_8 ucDeviceCapabilityBitmap; ++ UINT_8 ucGroupCapabilityBitmap; ++ UINT_16 u2ConfigMethod; /* Configure Method support. */ ++ P2P_DEVICE_TYPE_T rPriDevType; ++ UINT_8 ucSecDevTypeNum; ++ P2P_DEVICE_TYPE_T arSecDevType[8]; /* Reference to P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT */ ++ UINT_16 u2NameLength; ++ UINT_8 aucName[32]; /* Reference to WPS_ATTRI_MAX_LEN_DEVICE_NAME */ ++ /* TODO: Service Information or PasswordID valid? */ ++} P2P_DEVICE_DESC_T, *P_P2P_DEVICE_DESC_T; ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static const UINT_8 aucRateIndex2RateCode[PREAMBLE_OPTION_NUM][RATE_NUM] = { ++ { /* Long Preamble */ ++ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ ++ RATE_CCK_2M_LONG, /* RATE_2M_INDEX */ ++ RATE_CCK_5_5M_LONG, /* RATE_5_5M_INDEX */ ++ RATE_CCK_11M_LONG, /* RATE_11M_INDEX */ ++ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ ++ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ ++ RATE_OFDM_6M, /* RATE_6M_INDEX */ ++ RATE_OFDM_9M, /* RATE_9M_INDEX */ ++ RATE_OFDM_12M, /* RATE_12M_INDEX */ ++ RATE_OFDM_18M, /* RATE_18M_INDEX */ ++ RATE_OFDM_24M, /* RATE_24M_INDEX */ ++ RATE_OFDM_36M, /* RATE_36M_INDEX */ ++ RATE_OFDM_48M, /* RATE_48M_INDEX */ ++ RATE_OFDM_54M, /* RATE_54M_INDEX */ ++ }, ++ { /* Short Preamble */ ++ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ ++ RATE_CCK_2M_SHORT, /* RATE_2M_INDEX */ ++ RATE_CCK_5_5M_SHORT, /* RATE_5_5M_INDEX */ ++ RATE_CCK_11M_SHORT, /* RATE_11M_INDEX */ ++ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ ++ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ ++ RATE_OFDM_6M, /* RATE_6M_INDEX */ ++ RATE_OFDM_9M, /* RATE_9M_INDEX */ ++ RATE_OFDM_12M, /* RATE_12M_INDEX */ ++ RATE_OFDM_18M, /* RATE_18M_INDEX */ ++ RATE_OFDM_24M, /* RATE_24M_INDEX */ ++ RATE_OFDM_36M, /* RATE_36M_INDEX */ ++ RATE_OFDM_48M, /* RATE_48M_INDEX */ ++ RATE_OFDM_54M, /* RATE_54M_INDEX */ ++ }, ++ { /* Mixed Mode(Option) */ ++ RATE_MM_MCS_0, /* RATE_MCS0_INDEX, */ ++ RATE_MM_MCS_1, /* RATE_MCS1_INDEX, */ ++ RATE_MM_MCS_2, /* RATE_MCS2_INDEX, */ ++ RATE_MM_MCS_3, /* RATE_MCS3_INDEX, */ ++ RATE_MM_MCS_4, /* RATE_MCS4_INDEX, */ ++ RATE_MM_MCS_5, /* RATE_MCS5_INDEX, */ ++ RATE_MM_MCS_6, /* RATE_MCS6_INDEX, */ ++ RATE_MM_MCS_7, /* RATE_MCS7_INDEX, */ ++ RATE_MM_MCS_32 /* RATE_MCS32_INDEX, */ ++ }, ++ { /* Green Field(Option) */ ++ RATE_GF_MCS_0, /* RATE_MCS0_INDEX, */ ++ RATE_GF_MCS_1, /* RATE_MCS1_INDEX, */ ++ RATE_GF_MCS_2, /* RATE_MCS2_INDEX, */ ++ RATE_GF_MCS_3, /* RATE_MCS3_INDEX, */ ++ RATE_GF_MCS_4, /* RATE_MCS4_INDEX, */ ++ RATE_GF_MCS_5, /* RATE_MCS5_INDEX, */ ++ RATE_GF_MCS_6, /* RATE_MCS6_INDEX, */ ++ RATE_GF_MCS_7, /* RATE_MCS7_INDEX, */ ++ RATE_GF_MCS_32 /* RATE_MCS32_INDEX, */ ++ } ++}; ++ ++static const UINT_8 aucRateTableSize[PREAMBLE_OPTION_NUM] = { ++ RATE_HT_PHY_INDEX, ++ RATE_HT_PHY_INDEX, ++ HT_RATE_NUM, ++ HT_RATE_NUM ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Macros to get and set the wireless LAN frame fields those are 16/32 bits in ++ length. */ ++#define WLAN_GET_FIELD_16(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0]) | ((UINT_16) __cp[1] << 8); \ ++ } ++ ++#define WLAN_GET_FIELD_BE16(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0] << 8) | ((UINT_16) __cp[1]); \ ++ } ++ ++#define WLAN_GET_FIELD_32(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_32)(_value_p) = ((UINT_32) __cp[0]) | ((UINT_32) __cp[1] << 8) | \ ++ ((UINT_32) __cp[2] << 16) | ((UINT_32) __cp[3] << 24); \ ++ } ++ ++#define WLAN_GET_FIELD_64(_memAddr_p, _value_p) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ *(PUINT_64)(_value_p) = \ ++ ((UINT_64) __cp[0]) | ((UINT_64) __cp[1] << 8) | \ ++ ((UINT_64) __cp[2] << 16) | ((UINT_64) __cp[3] << 24) | \ ++ ((UINT_64) __cp[4] << 32) | ((UINT_64) __cp[5] << 40) | \ ++ ((UINT_64) __cp[6] << 48) | ((UINT_64) __cp[7] << 56); \ ++ } ++ ++#define WLAN_SET_FIELD_16(_memAddr_p, _value) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ __cp[0] = (UINT_8) (_value); \ ++ __cp[1] = (UINT_8) ((_value) >> 8); \ ++ } ++ ++#define WLAN_SET_FIELD_BE16(_memAddr_p, _value) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ __cp[0] = (UINT_8) ((_value) >> 8); \ ++ __cp[1] = (UINT_8) (_value); \ ++ } ++ ++#define WLAN_SET_FIELD_32(_memAddr_p, _value) \ ++ { \ ++ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ ++ __cp[0] = (UINT_8) (_value); \ ++ __cp[1] = (UINT_8) ((_value) >> 8); \ ++ __cp[2] = (UINT_8) ((_value) >> 16); \ ++ __cp[3] = (UINT_8) ((_value) >> 24); \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _WLAN_DEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h +new file mode 100644 +index 000000000000..aba2e040c194 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h +@@ -0,0 +1,2290 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_cmd_event.h#1 ++*/ ++ ++/*! \file "nic_cmd_event.h" ++ \brief This file contains the declairation file of the WLAN OID processing routines ++ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: nic_cmd_event.h ++ * ++ * 03 29 2012 eason.tsai ++ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define ++ * add conditional define. ++ * ++ * 03 04 2012 eason.tsai ++ * NULL ++ * modify the cal fail report code. ++ * ++ * 01 06 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * redefine the CMD_ID_SET_TXPWR_CTRL value. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 11 30 2011 cm.chang ++ * [WCXRP00001128] [MT5931 Wi-Fi][FW] Update BB/RF setting based on RF doc v0.7 for LGE spec ++ * 1. Add a new CMD for driver to set device mode ++ * 2. Update calibration parameters ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add TX_DONE status detail information. ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 10 26 2011 cp.wu ++ * [WCXRP00001065] [MT6620 Wi-Fi][MT5931][FW][DRV] Adding parameter for controlling ++ * minimum channel dwell time for scanning ++ * add interface for control minimum channel dwell time for scanning. ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * New CMD definition about RLM parameters ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add DFS switch. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 08 09 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * add osc stable time command structure ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than ++ * one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID ++ * support as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content ++ * check with firmware for valid MAC address. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 31 2011 chinglan.wang ++ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. ++ * . ++ * ++ * 03 18 2011 cm.chang ++ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command ++ * As CR title ++ * ++ * 03 17 2011 yarco.yang ++ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage ++ * . ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Support UAPSD/OppPS/NoA parameter setting ++ * ++ * 02 16 2011 cm.chang ++ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism ++ * . ++ * ++ * 02 10 2011 cp.wu ++ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers ++ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Update cmd format of BSS INFO, always sync OwnMac to FW no matter P2P is enabled or not.. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * Add Stress test ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * Sync HT operation element information from host to FW ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * report EEPROM used flag via NIC_CAPABILITY ++ * ++ * 12 28 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 29 2010 cm.chang ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for ++ * initial TX rate selection of auto-rate algorithm ++ * Sync RCPI of STA_REC to FW as reference of initial TX rate ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 cp.wu ++ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition ++ * follow-up for CMD_5G_PWR_OFFSET_T definition change ++ * ++ * 10 20 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * use OID_CUSTOM_TEST_MODE as indication for driver reset ++ * by dropping pending TX packets ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 15 2010 cm.chang ++ * NULL ++ * Add new CMD for TX power, 5G power offset and power parameters ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a pointer in P2P SCAN RESULT structure. This pointer ++ * is pointed to a IE buffer for this P2p device. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * add new CMD ID definition ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add a field in BSS INFO cmd to change interface address for P2P. (switching between Device Addr & Interface Addr) ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add interface address indication when indicate connection status. ++ * It is requested by supplicant to do 4 way handshake. ++ * ++ * 08 07 2010 wh.su ++ * NULL ++ * adding the privacy related code for P2P network ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Change data structure for P2P Device scan result, all channel time for scan command. ++ * ++ * 08 04 2010 george.huang ++ * NULL ++ * handle change PS mode OID/ CMD ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add P2P Device Found Event. ++ * Channel extension option in scan abort command. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add for P2P Scan Result Parsing & Saving. ++ * ++ * 07 20 2010 george.huang ++ * ++ * DWORD align for the CMD data structure ++ * ++ * 07 20 2010 cp.wu ++ * ++ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * pass band with channel number information as scan parameter ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 09 2010 cp.wu ++ * ++ * reorder members of CMD_SET_BSS_INFO. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * update prStaRecOfAP with BSS-INFO. ++ * ++ * 07 07 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support state of STA record change from 1 to 1 ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 28 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add BSS/STA_REC commands for integration. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add TX Done Event handle entry ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_DISASSOCIATE handling. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * sync statistics data structure definition with firmware implementation ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * statistics information OIDs are now handled by querying from firmware domain ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * * the frequency is used for adhoc connection only ++ * * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list ++ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 15 2010 kevin.huang ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * Add event for activate STA_RECORD_T ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 02 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c ++ * 'cause it involves OS dependent data structure handling ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * 4. correct some HAL implementation ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * OID_802_11_RSSI, ++ * * * OID_802_11_RSSI_TRIGGER, ++ * * * OID_802_11_STATISTICS, ++ * * * OID_802_11_DISASSOCIATE, ++ * * * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-12-11 18:35:07 GMT mtk02752 ++** add CMD added in CMD/EVEN document v0.8 ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-12-10 16:39:37 GMT mtk02752 ++** eliminate unused definitions ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-12-10 09:55:11 GMT mtk02752 ++** command ID/event ID revised ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-09 13:57:37 GMT MTK02468 ++** Added event ids (EVENT_ID_RX_ADDBA and EVENT_ID_RX_DELBA) ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-08 17:35:39 GMT mtk02752 ++** + add event ID for EVENT_ID_TEST_STATUS (rf test) ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-12-07 23:01:09 GMT mtk02752 ++** add data structure for RF_TEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-12-03 16:22:56 GMT mtk01461 ++** Modify the element - i4RSSI in EVENT of SCAN RESULT ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-30 10:54:44 GMT mtk02752 ++** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T, while 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-26 10:16:58 GMT mtk02752 ++** resync EVENT_CONNECTION_STATUS ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-25 21:34:01 GMT mtk02752 ++** sync. EVENT_SCAN_RESULT_T with firmware ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-25 21:03:48 GMT mtk02752 ++** refine MGMT_FRAME ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-25 18:17:47 GMT mtk02752 ++** refine GL_WLAN_INFO_T for buffering scan result and presume max. ie length = 600 bytes ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 22:41:20 GMT mtk02752 ++** add EVENT_SCAN_RESULT_T definition ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-11-23 20:29:16 GMT mtk02752 ++** fix typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-11-23 14:46:01 GMT mtk02752 ++** add new command/event structure upon CM@SD1's documentation ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-13 15:13:40 GMT mtk02752 ++** add command definition for CMD_BUILD_CONNECTION and EVENT_CONNECTION_STATUS ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-20 12:22:22 GMT mtk01461 ++** Add SeqNum field to Event Header ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:11 GMT mtk01461 ++** Update structure of HIF_EVENT_HEADER_T and EVENT_HDR_SIZE ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 12:10:36 GMT mtk01461 ++** Add Common Set CMD Callback for MCR Write and other Set OID ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:17 GMT mtk01461 ++** Command Done Handler ++*/ ++#ifndef _NIC_CMD_EVENT_H ++#define _NIC_CMD_EVENT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define CMD_STATUS_SUCCESS 0 ++#define CMD_STATUS_REJECTED 1 ++#define CMD_STATUS_UNKNOWN 2 ++ ++#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) ++ ++#define MAX_IE_LENGTH (600) ++#define MAX_WSC_IE_LENGTH (400) ++ ++/* Action field in structure CMD_CH_PRIVILEGE_T */ ++#define CMD_CH_ACTION_REQ 0 ++#define CMD_CH_ACTION_ABORT 1 ++ ++/* Status field in structure EVENT_CH_PRIVILEGE_T */ ++#define EVENT_CH_STATUS_GRANT 0 ++ ++#define SCN_PSCAN_SWC_RSSI_WIN_MAX 75 ++#define SCN_PSCAN_SWC_MAX_NUM 8 ++#define SCN_PSCAN_HOTLIST_REPORT_MAX_NUM 8 ++ ++typedef enum _ENUM_CMD_ID_T { ++ CMD_ID_TEST_MODE = 1, /* 0x01 (Set) */ ++ CMD_ID_RESET_REQUEST, /* 0x02 (Set) */ ++ CMD_ID_BUILD_CONNECTION, /* 0x03 (Set) */ ++ CMD_ID_SCAN_REQ_V2, /* 0x04 (Set) */ ++ CMD_ID_NIC_POWER_CTRL, /* 0x05 (Set) */ ++ CMD_ID_POWER_SAVE_MODE, /* 0x06 (Set) */ ++ CMD_ID_LINK_ATTRIB, /* 0x07 (Set) */ ++ CMD_ID_ADD_REMOVE_KEY, /* 0x08 (Set) */ ++ CMD_ID_DEFAULT_KEY_ID, /* 0x09 (Set) */ ++ CMD_ID_INFRASTRUCTURE, /* 0x0a (Set) */ ++ CMD_ID_SET_RX_FILTER, /* 0x0b (Set) */ ++ CMD_ID_DOWNLOAD_BUF, /* 0x0c (Set) */ ++ CMD_ID_WIFI_START, /* 0x0d (Set) */ ++ CMD_ID_CMD_BT_OVER_WIFI, /* 0x0e (Set) */ ++ CMD_ID_SET_MEDIA_CHANGE_DELAY_TIME, /* 0x0f (Set) */ ++ CMD_ID_SEND_ADDBA_RSP, /* 0x10 (Set) */ ++ CMD_ID_WAPI_MODE, /* 0x11 (Set) (obsolete) */ ++ CMD_ID_WAPI_ASSOC_INFO, /* 0x12 (Set) (obsolete) */ ++ CMD_ID_SET_DOMAIN_INFO, /* 0x13 (Set) */ ++ CMD_ID_SET_IP_ADDRESS, /* 0x14 (Set) */ ++ CMD_ID_BSS_ACTIVATE_CTRL, /* 0x15 (Set) */ ++ CMD_ID_SET_BSS_INFO, /* 0x16 (Set) */ ++ CMD_ID_UPDATE_STA_RECORD, /* 0x17 (Set) */ ++ CMD_ID_REMOVE_STA_RECORD, /* 0x18 (Set) */ ++ CMD_ID_INDICATE_PM_BSS_CREATED, /* 0x19 (Set) */ ++ CMD_ID_INDICATE_PM_BSS_CONNECTED, /* 0x1a (Set) */ ++ CMD_ID_INDICATE_PM_BSS_ABORT, /* 0x1b (Set) */ ++ CMD_ID_UPDATE_BEACON_CONTENT, /* 0x1c (Set) */ ++ CMD_ID_SET_BSS_RLM_PARAM, /* 0x1d (Set) */ ++ CMD_ID_SCAN_REQ, /* 0x1e (Set) */ ++ CMD_ID_SCAN_CANCEL, /* 0x1f (Set) */ ++ CMD_ID_CH_PRIVILEGE, /* 0x20 (Set) */ ++ CMD_ID_UPDATE_WMM_PARMS, /* 0x21 (Set) */ ++ CMD_ID_SET_WMM_PS_TEST_PARMS, /* 0x22 (Set) */ ++ CMD_ID_TX_AMPDU, /* 0x23 (Set) */ ++ CMD_ID_ADDBA_REJECT, /* 0x24 (Set) */ ++ CMD_ID_SET_PS_PROFILE_ADV, /* 0x25 (Set) */ ++ CMD_ID_SET_RAW_PATTERN, /* 0x26 (Set) */ ++ CMD_ID_CONFIG_PATTERN_FUNC, /* 0x27 (Set) */ ++ CMD_ID_SET_TX_PWR, /* 0x28 (Set) */ ++ CMD_ID_SET_5G_PWR_OFFSET, /* 0x29 (Set) */ ++ CMD_ID_SET_PWR_PARAM, /* 0x2A (Set) */ ++ CMD_ID_P2P_ABORT, /* 0x2B (Set) */ ++#if CFG_STRESS_TEST_SUPPORT ++ CMD_ID_RANDOM_RX_RESET_EN = 0x2C, /* 0x2C (Set ) */ ++ CMD_ID_RANDOM_RX_RESET_DE = 0x2D, /* 0x2D (Set ) */ ++ CMD_ID_SAPP_EN = 0x2E, /* 0x2E (Set ) */ ++ CMD_ID_SAPP_DE = 0x2F, /* 0x2F (Set ) */ ++#endif ++ CMD_ID_ROAMING_TRANSIT = 0x30, /* 0x30 (Set) */ ++ CMD_ID_SET_PHY_PARAM, /* 0x31 (Set) */ ++ CMD_ID_SET_NOA_PARAM, /* 0x32 (Set) */ ++ CMD_ID_SET_OPPPS_PARAM, /* 0x33 (Set) */ ++ CMD_ID_SET_UAPSD_PARAM, /* 0x34 (Set) */ ++ CMD_ID_SET_SIGMA_STA_SLEEP, /* 0x35 (Set) */ ++ CMD_ID_SET_EDGE_TXPWR_LIMIT, /* 0x36 (Set) */ ++ CMD_ID_SET_DEVICE_MODE, /* 0x37 (Set) */ ++ CMD_ID_SET_TXPWR_CTRL, /* 0x38 (Set) */ ++ CMD_ID_SET_AUTOPWR_CTRL, /* 0x39 (Set) */ ++ CMD_ID_SET_WFD_CTRL, /* 0x3A (Set) */ ++ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, /* 0x3B (Set) */ ++ CMD_ID_SET_RSSI_COMPENSATE, /* 0x3C (Set) */ ++ CMD_ID_SET_BAND_SUPPORT = 0x3D, /* 0x3D (Set) */ ++ CMD_ID_SET_NLO_REQ, /* 0x3E (Set) */ ++ CMD_ID_SET_NLO_CANCEL, /* 0x3F (Set) */ ++ CMD_ID_SET_BATCH_REQ, /* 0x40 (Set) */ ++ CMD_ID_SET_WOWLAN, /* 0x41 (Set) */ /*CFG_SUPPORT_WOWLAN */ ++ CMD_ID_GET_PSCAN_CAPABILITY = 0x42, /* 0x42 (Set) */ ++ CMD_ID_SET_PSCN_ENABLE = 0x43, /* 0x43 (Set) */ ++ CMD_ID_SET_PSCAN_PARAM = 0x44, /* 0x44 (Set) */ ++ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID = 0x45, /* 0x45 (Set) */ ++ CMD_ID_SET_PSCN_ADD_SW_BSSID = 0x46, /* 0x46 (Set) */ ++ CMD_ID_SET_PSCN_MAC_ADDR = 0x47, /* 0x47 (Set) */ ++ CMD_ID_GET_GSCN_SCN_RESULT = 0x48, /* 0x48 (Get) */ ++ CMD_ID_SET_COUNTRY_POWER_LIMIT = 0x4A, /* 0x4A (Set) */ ++ CMD_ID_SET_SYSTEM_SUSPEND = 0x60, /* 0x60 (Set) */ ++ CMD_ID_GET_NIC_CAPABILITY = 0x80, /* 0x80 (Query) */ ++ CMD_ID_GET_LINK_QUALITY, /* 0x81 (Query) */ ++ CMD_ID_GET_STATISTICS, /* 0x82 (Query) */ ++ CMD_ID_GET_CONNECTION_STATUS, /* 0x83 (Query) */ ++ CMD_ID_GET_ASSOC_INFO, /* 0x84 (Query) (obsolete) */ ++ CMD_ID_GET_STA_STATISTICS = 0x85, /* 0x85 (Query) */ ++ CMD_ID_GET_DEBUG_CODE = 0x86, /* 0x86 (Query) */ ++ CMD_ID_GET_LTE_CHN = 0x87, /* 0x87 (Query) */ ++ CMD_ID_GET_CHN_LOADING = 0x88, /* 0x88 (Query) */ ++ CMD_ID_GET_STATISTICS_PL = 0x89, /* 0x87 (Query) */ ++ CMD_ID_BASIC_CONFIG = 0xc1, /* 0xc1 (Set / Query) */ ++ CMD_ID_ACCESS_REG, /* 0xc2 (Set / Query) */ ++ CMD_ID_MAC_MCAST_ADDR, /* 0xc3 (Set / Query) */ ++ CMD_ID_802_11_PMKID, /* 0xc4 (Set / Query) */ ++ CMD_ID_ACCESS_EEPROM, /* 0xc5 (Set / Query) */ ++ CMD_ID_SW_DBG_CTRL, /* 0xc6 (Set / Query) */ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ CMD_ID_SEC_CHECK, /* 0xc7 (Set / Query) */ ++#endif ++ CMD_ID_DUMP_MEM, /* 0xc8 (Query) */ ++ ++ CMD_ID_CHIP_CONFIG = 0xCA, /* 0xca (Set / Query) */ ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ CMD_ID_SET_RDD_CH = 0xE1, ++#endif ++ ++ CMD_ID_SET_BWCS = 0xF1, ++ CMD_ID_SET_ROAMING_INFO = 0xF3, ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++ CMD_ID_GET_BUILD_DATE_CODE = 0xF8, ++#endif ++ CMD_ID_GET_BSS_INFO = 0xF9, ++#if 1 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION = 0xFA, /* 0xFA (Set) */ ++#endif ++ ++ CMD_ID_TDLS_CORE = 0xFC, ++ CMD_ID_STATS = 0xFD, ++ CMD_ID_TX_AR_ERR_CONFIG = 0xFF ++} ENUM_CMD_ID_T, *P_ENUM_CMD_ID_T; ++ ++typedef enum _ENUM_EVENT_ID_T { ++ EVENT_ID_CMD_RESULT = 1, /* 0x01 (Query) */ ++ EVENT_ID_NIC_CAPABILITY, /* 0x02 (Query) */ ++ EVENT_ID_CONNECTION_STATUS, /* 0x03 (Query / Unsolicited) (obsolete) */ ++ EVENT_ID_SCAN_RESULT, /* 0x04 (Query / Unsolicited) (obselete) */ ++ EVENT_ID_LINK_QUALITY, /* 0x05 (Query / Unsolicited) */ ++ EVENT_ID_STATISTICS, /* 0x06 (Query) */ ++ EVENT_ID_MIC_ERR_INFO, /* 0x07 (Unsolicited) */ ++ EVENT_ID_ASSOC_INFO, /* 0x08 (Query - CMD_ID_GET_ASSOC_INFO) */ ++ EVENT_ID_BASIC_CONFIG, /* 0x09 (Query - CMD_ID_BASIC_CONFIG) */ ++ EVENT_ID_ACCESS_REG, /* 0x0a (Query - CMD_ID_ACCESS_REG) */ ++ EVENT_ID_MAC_MCAST_ADDR, /* 0x0b (Query - CMD_ID_MAC_MCAST_ADDR) */ ++ EVENT_ID_802_11_PMKID, /* 0x0c (Query - CMD_ID_802_11_PMKID) */ ++ EVENT_ID_ACCESS_EEPROM, /* 0x0d (Query - CMD_ID_ACCESS_EEPROM) */ ++ EVENT_ID_SLEEPY_NOTIFY, /* 0x0e (Query) */ ++ EVENT_ID_BT_OVER_WIFI, /* 0x0f (Unsolicited) */ ++ EVENT_ID_TEST_STATUS, /* 0x10 (Query - CMD_ID_TEST_MODE) */ ++ EVENT_ID_RX_ADDBA, /* 0x11 (Unsolicited) (obsolete) */ ++ EVENT_ID_RX_DELBA, /* 0x12 (Unsolicited) (obsolete) */ ++ EVENT_ID_ACTIVATE_STA_REC_T, /* 0x13 (Unsolicited) */ ++ EVENT_ID_DEACTIVATE_STA_REC_T, /* 0x14 (Unsolicited) */ ++ EVENT_ID_SCAN_DONE, /* 0x15 (Unsoiicited) */ ++ EVENT_ID_RX_FLUSH, /* 0x16 (Unsolicited) */ ++ EVENT_ID_TX_DONE, /* 0x17 (Unsolicited) */ ++ EVENT_ID_CH_PRIVILEGE, /* 0x18 (Unsolicited) */ ++ EVENT_ID_BSS_ABSENCE_PRESENCE = 0x19, /* 0x19 (Unsolicited) */ ++ EVENT_ID_STA_CHANGE_PS_MODE, /* 0x1A (Unsolicited) */ ++ EVENT_ID_BSS_BEACON_TIMEOUT, /* 0x1B (Unsolicited) */ ++ EVENT_ID_UPDATE_NOA_PARAMS, /* 0x1C (Unsolicited) */ ++ EVENT_ID_AP_OBSS_STATUS, /* 0x1D (Unsolicited) */ ++ EVENT_ID_STA_UPDATE_FREE_QUOTA, /* 0x1E (Unsolicited) */ ++ EVENT_ID_SW_DBG_CTRL, /* 0x1F (Query - CMD_ID_SW_DBG_CTRL) */ ++ EVENT_ID_ROAMING_STATUS, /* 0x20 (Unsolicited) */ ++ EVENT_ID_STA_AGING_TIMEOUT, /* 0x21 (Unsolicited) */ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ EVENT_ID_SEC_CHECK_RSP, /* 0x22 (Unsolicited) */ ++#endif ++ EVENT_ID_SEND_DEAUTH, /* 0x23 (Unsolicited) */ ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ EVENT_ID_UPDATE_RDD_STATUS, /* 0x24 (Unsolicited) */ ++#endif ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ EVENT_ID_UPDATE_BWCS_STATUS = 0x25, /* 0x25 (Unsolicited) */ ++ EVENT_ID_UPDATE_BCM_DEBUG, /* 0x26 (Unsolicited) */ ++#endif ++ EVENT_ID_RX_ERR, ++ EVENT_ID_DUMP_MEM, ++ EVENT_ID_STA_STATISTICS = 0x29, /* 0x29 (Query ) */ ++ EVENT_ID_STA_STATISTICS_UPDATE, /* 0x2A (Unsolicited) */ ++ EVENT_ID_NLO_DONE = 0x2b, ++ ++ EVENT_ID_GSCAN_CAPABILITY = 0x30, ++ EVENT_ID_GSCAN_SCAN_COMPLETE = 0x31, ++ EVENT_ID_GSCAN_FULL_RESULT = 0x32, ++ EVENT_ID_GSCAN_SIGNIFICANT_CHANGE = 0x33, ++ EVENT_ID_GSCAN_GEOFENCE_FOUND = 0x34, ++ EVENT_ID_GSCAN_SCAN_AVAILABLE = 0x35, ++ EVENT_ID_GSCAN_RESULT = 0x36, ++ EVENT_ID_BATCH_RESULT = 0x37, ++ ++ EVENT_ID_TDLS = 0x80, ++ EVENT_ID_STATS_ENV = 0x81, ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++ EVENT_ID_BUILD_DATE_CODE = 0xF8, ++#endif ++ EVENT_ID_GET_AIS_BSS_INFO = 0xF9, ++ EVENT_ID_DEBUG_CODE = 0xFB, ++ EVENT_ID_RFTEST_READY = 0xFC, /* 0xFC */ ++ EVENT_ID_TX_DONE_STATUS = 0xFD, ++ EVENT_ID_FW_LOG_ENV = 0xFE, /* 0xFE, FW real time debug log */ ++} ENUM_EVENT_ID_T, *P_ENUM_EVENT_ID_T; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#ifndef LINUX ++typedef UINT_8 CMD_STATUS; ++#endif ++ ++typedef struct _EVENT_TX_DONE_STATUS_T { ++ UINT_8 ucPacketSeq; ++ UINT_8 ucStatus; ++ UINT_16 u2SequenceNumber; ++ UINT_32 au4Reserved1; ++ UINT_32 au4Reserved2; ++ UINT_32 au4Reserved3; ++ UINT_32 u4PktBufInfo; ++ UINT_8 aucPktBuf[200]; ++} EVENT_TX_DONE_STATUS_T, *P_EVENT_TX_DONE_STATUS_T; ++ ++/* for Event Packet (via HIF-RX) */ ++ /* following CM's documentation v0.7 */ ++typedef struct _WIFI_CMD_T { ++ UINT_16 u2TxByteCount_UserPriority; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucResource_PktType_CSflags; ++ UINT_8 ucCID; ++ UINT_8 ucSetQuery; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2; ++ ++ UINT_8 aucBuffer[0]; ++} WIFI_CMD_T, *P_WIFI_CMD_T; ++ ++/* for Command Packet (via HIF-TX) */ ++ /* following CM's documentation v0.7 */ ++typedef struct _WIFI_EVENT_T { ++ UINT_16 u2PacketLen; ++ UINT_16 u2PacketType; ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved2[2]; ++ ++ UINT_8 aucBuffer[0]; ++} WIFI_EVENT_T, *P_WIFI_EVENT_T; ++ ++/* CMD_ID_TEST_MODE */ ++typedef struct _CMD_TEST_CTRL_T { ++ UINT_8 ucAction; ++ UINT_8 aucReserved[3]; ++ union { ++ UINT_32 u4OpMode; ++ UINT_32 u4ChannelFreq; ++ PARAM_MTK_WIFI_TEST_STRUCT_T rRfATInfo; ++ } u; ++} CMD_TEST_CTRL_T, *P_CMD_TEST_CTRL_T; ++ ++/* EVENT_TEST_STATUS */ ++typedef struct _PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T { ++ UINT_32 u4PktSentStatus; ++ UINT_32 u4PktSentCount; ++ UINT_16 u2AvgAlc; ++ UINT_8 ucCckGainControl; ++ UINT_8 ucOfdmGainControl; ++} PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T { ++ UINT_32 u4IntRxOk; /*!< number of packets that Rx ok from interrupt */ ++ UINT_32 u4IntCrcErr; /*!< number of packets that CRC error from interrupt */ ++ UINT_32 u4IntShort; /*!< number of packets that is short preamble from interrupt */ ++ UINT_32 u4IntLong; /*!< number of packets that is long preamble from interrupt */ ++ UINT_32 u4PauRxPktCount; /*!< number of packets that Rx ok from PAU */ ++ UINT_32 u4PauCrcErrCount; /*!< number of packets that CRC error from PAU */ ++ UINT_32 u4PauRxFifoFullCount; /*!< number of packets that is short preamble from PAU */ ++ UINT_32 u4PauCCACount; /*!< CCA rising edge count */ ++} PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T; ++ ++typedef union _EVENT_TEST_STATUS { ++ PARAM_MTK_WIFI_TEST_STRUCT_T rATInfo; ++/* PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T rTxStatus; */ ++/* PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T rRxStatus; */ ++} EVENT_TEST_STATUS, *P_EVENT_TEST_STATUS; ++ ++/* CMD_BUILD_CONNECTION */ ++typedef struct _CMD_BUILD_CONNECTION { ++ UINT_8 ucInfraMode; ++ UINT_8 ucAuthMode; ++ UINT_8 ucEncryptStatus; ++ UINT_8 ucSsidLen; ++ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; ++ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; ++ ++ /* Ad-hoc mode */ ++ UINT_16 u2BeaconPeriod; ++ UINT_16 u2ATIMWindow; ++ UINT_8 ucJoinOnly; ++ UINT_8 ucReserved; ++ UINT_32 u4FreqInKHz; ++ ++ /* for faster connection */ ++ UINT_8 aucScanResult[0]; ++} CMD_BUILD_CONNECTION, *P_CMD_BUILD_CONNECTION; ++ ++/* CMD_ADD_REMOVE_KEY */ ++typedef struct _CMD_802_11_KEY { ++ UINT_8 ucAddRemove; ++ UINT_8 ucTxKey; ++ UINT_8 ucKeyType; ++ UINT_8 ucIsAuthenticator; ++ UINT_8 aucPeerAddr[6]; ++ UINT_8 ucNetType; ++ UINT_8 ucAlgorithmId; ++ UINT_8 ucKeyId; ++ UINT_8 ucKeyLen; ++ UINT_8 aucReverved[2]; ++ UINT_8 aucKeyMaterial[32]; ++ UINT_8 aucKeyRsc[16]; ++} CMD_802_11_KEY, *P_CMD_802_11_KEY; ++ ++/* WPA2 PMKID cache structure */ ++typedef struct _PMKID_ENTRY_T { ++ PARAM_BSSID_INFO_T rBssidInfo; ++ BOOLEAN fgPmkidExist; ++} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; ++ ++typedef struct _CMD_802_11_PMKID { ++ ULONG u4BSSIDInfoCount; ++ P_PMKID_ENTRY_T arPMKIDInfo[1]; ++} CMD_802_11_PMKID, *P_CMD_802_11_PMKID; ++ ++/* CMD_BASIC_CONFIG */ ++typedef struct _CMD_CSUM_OFFLOAD { ++ UINT_16 u2RxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ ++ UINT_16 u2TxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ ++} CMD_CSUM_OFFLOAD, *P_CMD_CSUM_OFFLOAD; ++ ++typedef struct _CMD_BASIC_CONFIG { ++ PARAM_MAC_ADDRESS rMyMacAddr; ++ UINT_8 ucNative80211; ++ UINT_8 aucReserved[1]; ++ ++ CMD_CSUM_OFFLOAD rCsumOffload; ++} CMD_BASIC_CONFIG, *P_CMD_BASIC_CONFIG, EVENT_BASIC_CONFIG, *P_EVENT_BASIC_CONFIG; ++ ++/* CMD_MAC_MCAST_ADDR */ ++typedef struct _CMD_MAC_MCAST_ADDR { ++ UINT_32 u4NumOfGroupAddr; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[3]; ++ PARAM_MAC_ADDRESS arAddress[MAX_NUM_GROUP_ADDR]; ++} CMD_MAC_MCAST_ADDR, *P_CMD_MAC_MCAST_ADDR, EVENT_MAC_MCAST_ADDR, *P_EVENT_MAC_MCAST_ADDR; ++ ++/* CMD_ACCESS_EEPROM */ ++typedef struct _CMD_ACCESS_EEPROM { ++ UINT_16 u2Offset; ++ UINT_16 u2Data; ++} CMD_ACCESS_EEPROM, *P_CMD_ACCESS_EEPROM, EVENT_ACCESS_EEPROM, *P_EVENT_ACCESS_EEPROM; ++ ++typedef struct _CMD_CUSTOM_NOA_PARAM_STRUCT_T { ++ UINT_32 u4NoaDurationMs; ++ UINT_32 u4NoaIntervalMs; ++ UINT_32 u4NoaCount; ++} CMD_CUSTOM_NOA_PARAM_STRUCT_T, *P_CMD_CUSTOM_NOA_PARAM_STRUCT_T; ++ ++typedef struct _CMD_CUSTOM_OPPPS_PARAM_STRUCT_T { ++ UINT_32 u4CTwindowMs; ++} CMD_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_CMD_CUSTOM_OPPPS_PARAM_STRUCT_T; ++ ++typedef struct _CMD_CUSTOM_UAPSD_PARAM_STRUCT_T { ++ UINT_8 fgEnAPSD; ++ UINT_8 fgEnAPSD_AcBe; ++ UINT_8 fgEnAPSD_AcBk; ++ UINT_8 fgEnAPSD_AcVo; ++ UINT_8 fgEnAPSD_AcVi; ++ UINT_8 ucMaxSpLen; ++ UINT_8 aucResv[2]; ++} CMD_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_CMD_CUSTOM_UAPSD_PARAM_STRUCT_T; ++ ++/* EVENT_CONNECTION_STATUS */ ++typedef struct _EVENT_CONNECTION_STATUS { ++ UINT_8 ucMediaStatus; ++ UINT_8 ucReasonOfDisconnect; ++ ++ UINT_8 ucInfraMode; ++ UINT_8 ucSsidLen; ++ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; ++ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; ++ UINT_8 ucAuthenMode; ++ UINT_8 ucEncryptStatus; ++ UINT_16 u2BeaconPeriod; ++ UINT_16 u2AID; ++ UINT_16 u2ATIMWindow; ++ UINT_8 ucNetworkType; ++ UINT_8 aucReserved[1]; ++ UINT_32 u4FreqInKHz; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_8 aucInterfaceAddr[PARAM_MAC_ADDR_LEN]; ++#endif ++ ++} EVENT_CONNECTION_STATUS, *P_EVENT_CONNECTION_STATUS; ++ ++/* EVENT_NIC_CAPABILITY */ ++typedef struct _EVENT_NIC_CAPABILITY { ++ UINT_16 u2ProductID; ++ UINT_16 u2FwVersion; ++ UINT_16 u2DriverVersion; ++ UINT_8 ucHw5GBandDisabled; ++ UINT_8 ucEepromUsed; ++ UINT_8 ucEfuseValid; ++ UINT_8 ucMacAddrValid; ++#if CFG_REPORT_RFBB_VERSION ++ UINT_8 ucRfVersion; ++ UINT_8 ucPhyVersion; ++#endif ++#if CFG_ENABLE_CAL_LOG ++ UINT_8 ucRfCalFail; ++ UINT_8 ucBbCalFail; ++#endif ++ ++#define FEATURE_SET_OFFSET_TDLS 0 ++#define FEATURE_SET_OFFSET_5G_SUPPORT 1 ++ UINT_8 ucFeatureSet; /* bit0: TDLS */ ++ ++ UINT_8 aucReserved[1]; ++#if CFG_EMBED_FIRMWARE_BUILD_DATE_CODE ++ UINT_8 aucDateCode[16]; ++#endif ++} EVENT_NIC_CAPABILITY, *P_EVENT_NIC_CAPABILITY; ++ ++/* modified version of WLAN_BEACON_FRAME_BODY_T for simplier buffering */ ++typedef struct _WLAN_BEACON_FRAME_BODY_T_LOCAL { ++ /* Beacon frame body */ ++ UINT_32 au4Timestamp[2]; /* Timestamp */ ++ UINT_16 u2BeaconInterval; /* Beacon Interval */ ++ UINT_16 u2CapInfo; /* Capability */ ++ UINT_8 aucInfoElem[MAX_IE_LENGTH]; /* Various IEs, start from SSID */ ++ UINT_16 u2IELength; /* This field is *NOT* carried by F/W but caculated by nic_rx */ ++} WLAN_BEACON_FRAME_BODY_T_LOCAL, *P_WLAN_BEACON_FRAME_BODY_T_LOCAL; ++ ++/* EVENT_SCAN_RESULT */ ++typedef struct _EVENT_SCAN_RESULT_T { ++ INT_32 i4RSSI; ++ UINT_32 u4LinkQuality; ++ UINT_32 u4DSConfig; /* Center frequency */ ++ UINT_32 u4DomainInfo; /* Require CM opinion */ ++ UINT_32 u4Reserved; ++ UINT_8 ucNetworkType; ++ UINT_8 ucOpMode; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; ++ WLAN_BEACON_FRAME_BODY_T_LOCAL rBeaconFrameBody; ++} EVENT_SCAN_RESULT_T, *P_EVENT_SCAN_RESULT_T; ++ ++/* event of tkip mic error */ ++typedef struct _EVENT_MIC_ERR_INFO { ++ UINT_32 u4Flags; ++} EVENT_MIC_ERR_INFO, *P_EVENT_MIC_ERR_INFO; ++ ++typedef struct _EVENT_PMKID_CANDIDATE_LIST_T { ++ UINT_32 u4Version; /*!< Version */ ++ UINT_32 u4NumCandidates; /*!< How many candidates follow */ ++ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; ++} EVENT_PMKID_CANDIDATE_LIST_T, *P_EVENT_PMKID_CANDIDATE_LIST_T; ++ ++typedef struct _EVENT_CMD_RESULT { ++ UINT_8 ucCmdID; ++ UINT_8 ucStatus; ++ UINT_8 aucReserved[2]; ++} EVENT_CMD_RESULT, *P_EVENT_CMD_RESULT; ++ ++/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ ++typedef struct _CMD_ACCESS_REG { ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++} CMD_ACCESS_REG, *P_CMD_ACCESS_REG; ++ ++/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++typedef struct _CMD_ACCESS_CHN_LOAD { ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++ UINT_16 u2Channel; ++ UINT_8 aucReserved[2]; ++} CMD_ACCESS_CHN_LOAD, *P_ACCESS_CHN_LOAD; ++ ++#endif ++/* CMD_DUMP_MEMORY */ ++typedef struct _CMD_DUMP_MEM { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4RemainLength; ++ UINT_8 ucFragNum; ++} CMD_DUMP_MEM, *P_CMD_DUMP_MEM; ++ ++typedef struct _EVENT_DUMP_MEM_T { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4RemainLength; ++ UINT_8 ucFragNum; ++ UINT_8 aucBuffer[1]; ++} EVENT_DUMP_MEM_T, *P_EVENT_DUMP_MEM_T; ++ ++typedef struct _CMD_SW_DBG_CTRL_T { ++ UINT_32 u4Id; ++ UINT_32 u4Data; ++ /* Debug Support */ ++ UINT_32 u4DebugCnt[64]; ++} CMD_SW_DBG_CTRL_T, *P_CMD_SW_DBG_CTRL_T; ++ ++/* CMD_ID_LINK_ATTRIB */ ++typedef struct _CMD_LINK_ATTRIB { ++ INT_8 cRssiTrigger; ++ UINT_8 ucDesiredRateLen; ++ UINT_16 u2DesiredRate[32]; ++ UINT_8 ucMediaStreamMode; ++ UINT_8 aucReserved[1]; ++} CMD_LINK_ATTRIB, *P_CMD_LINK_ATTRIB; ++ ++/* CMD_ID_NIC_POWER_CTRL */ ++typedef struct _CMD_NIC_POWER_CTRL { ++ UINT_8 ucPowerMode; ++ UINT_8 aucReserved[3]; ++} CMD_NIC_POWER_CTRL, *P_CMD_NIC_POWER_CTRL; ++ ++/* CMD_ID_POWER_SAVE_MODE */ ++typedef struct _CMD_PS_PROFILE_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucPsProfile; ++ UINT_8 aucReserved[2]; ++} CMD_PS_PROFILE_T, *P_CMD_PS_PROFILE_T; ++ ++/* EVENT_LINK_QUALITY */ ++typedef struct _EVENT_LINK_QUALITY { ++ INT_8 cRssi; ++ INT_8 cLinkQuality; ++ UINT_16 u2LinkSpeed; ++ UINT_8 ucMediumBusyPercentage; ++} EVENT_LINK_QUALITY, *P_EVENT_LINK_QUALITY; ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++/* EVENT_LINK_QUALITY */ ++typedef struct _EVENT_LINK_QUALITY_EX { ++ INT_8 cRssi; ++ INT_8 cLinkQuality; ++ UINT_16 u2LinkSpeed; ++ UINT_8 ucMediumBusyPercentage; ++ UINT_8 ucIsLQ0Rdy; ++ INT_8 cRssiP2P; /* For P2P Network. */ ++ INT_8 cLinkQualityP2P; ++ UINT_16 u2LinkSpeedP2P; ++ UINT_8 ucMediumBusyPercentageP2P; ++ UINT_8 ucIsLQ1Rdy; ++} EVENT_LINK_QUALITY_EX, *P_EVENT_LINK_QUALITY_EX; ++#endif ++ ++/* EVENT_ID_STATISTICS */ ++typedef struct _EVENT_STATISTICS { ++ LARGE_INTEGER rTransmittedFragmentCount; ++ LARGE_INTEGER rMulticastTransmittedFrameCount; ++ LARGE_INTEGER rFailedCount; ++ LARGE_INTEGER rRetryCount; ++ LARGE_INTEGER rMultipleRetryCount; ++ LARGE_INTEGER rRTSSuccessCount; ++ LARGE_INTEGER rRTSFailureCount; ++ LARGE_INTEGER rACKFailureCount; ++ LARGE_INTEGER rFrameDuplicateCount; ++ LARGE_INTEGER rReceivedFragmentCount; ++ LARGE_INTEGER rMulticastReceivedFrameCount; ++ LARGE_INTEGER rFCSErrorCount; ++} EVENT_STATISTICS, *P_EVENT_STATISTICS; ++ ++/* EVENT_ID_FW_SLEEPY_NOTIFY */ ++typedef struct _EVENT_SLEEPY_NOTIFY { ++ UINT_8 ucSleepyState; ++ UINT_8 aucReserved[3]; ++} EVENT_SLEEPY_NOTIFY, *P_EVENT_SLEEPY_NOTIFY; ++ ++typedef struct _EVENT_ACTIVATE_STA_REC_T { ++ UINT_8 aucMacAddr[6]; ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucNetworkTypeIndex; ++ BOOLEAN fgIsQoS; ++ BOOLEAN fgIsAP; ++ UINT_8 aucReserved[2]; ++} EVENT_ACTIVATE_STA_REC_T, *P_EVENT_ACTIVATE_STA_REC_T; ++ ++typedef struct _EVENT_DEACTIVATE_STA_REC_T { ++ UINT_8 ucStaRecIdx; ++ UINT_8 aucReserved[3]; ++} EVENT_DEACTIVATE_STA_REC_T, *P_EVENT_DEACTIVATE_STA_REC_T; ++ ++/* CMD_BT_OVER_WIFI */ ++typedef struct _CMD_BT_OVER_WIFI { ++ UINT_8 ucAction; /* 0: query, 1: setup, 2: destroy */ ++ UINT_8 ucChannelNum; ++ PARAM_MAC_ADDRESS rPeerAddr; ++ UINT_16 u2BeaconInterval; ++ UINT_8 ucTimeoutDiscovery; ++ UINT_8 ucTimeoutInactivity; ++ UINT_8 ucRole; ++ UINT_8 PAL_Capabilities; ++ UINT_8 cMaxTxPower; ++ UINT_8 ucChannelBand; ++ UINT_8 ucReserved[1]; ++} CMD_BT_OVER_WIFI, *P_CMD_BT_OVER_WIFI; ++ ++/* EVENT_BT_OVER_WIFI */ ++typedef struct _EVENT_BT_OVER_WIFI { ++ UINT_8 ucLinkStatus; ++ UINT_8 ucSelectedChannel; ++ INT_8 cRSSI; ++ UINT_8 ucReserved[1]; ++} EVENT_BT_OVER_WIFI, *P_EVENT_BT_OVER_WIFI; ++ ++/* Same with DOMAIN_SUBBAND_INFO */ ++typedef struct _CMD_SUBBAND_INFO { ++ UINT_8 ucRegClass; ++ UINT_8 ucBand; ++ UINT_8 ucChannelSpan; ++ UINT_8 ucFirstChannelNum; ++ UINT_8 ucNumChannels; ++ UINT_8 aucReserved[3]; ++} CMD_SUBBAND_INFO, *P_CMD_SUBBAND_INFO; ++ ++/* CMD_SET_DOMAIN_INFO */ ++typedef struct _CMD_SET_DOMAIN_INFO_T { ++ UINT_16 u2CountryCode; ++ UINT_16 u2IsSetPassiveScan; /* 0: set channel domain; 1: set passive scan channel domain */ ++ CMD_SUBBAND_INFO rSubBand[6]; ++ ++ UINT_8 uc2G4Bandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ ++ UINT_8 uc5GBandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ ++ UINT_8 aucReserved[2]; ++} CMD_SET_DOMAIN_INFO_T, *P_CMD_SET_DOMAIN_INFO_T; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++/* CMD_SET_PWR_LIMIT_TABLE */ ++typedef struct _CMD_CHANNEL_POWER_LIMIT { ++ UINT_8 ucCentralCh; ++ INT_8 cPwrLimitCCK; ++ INT_8 cPwrLimit20; ++ INT_8 cPwrLimit40; ++ INT_8 cPwrLimit80; ++ INT_8 cPwrLimit160; ++ UINT_8 ucFlag; ++ UINT_8 aucReserved[1]; ++} CMD_CHANNEL_POWER_LIMIT, *P_CMD_CHANNEL_POWER_LIMIT; ++ ++typedef struct _CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T { ++ UINT_16 u2CountryCode; ++ UINT_8 ucCountryFlag; ++ UINT_8 ucNum; ++ UINT_8 aucReserved[4]; ++ CMD_CHANNEL_POWER_LIMIT rChannelPowerLimit[1]; ++} CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T, *P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T; ++ ++#endif ++ ++/* CMD_SET_IP_ADDRESS */ ++typedef struct _IPV4_NETWORK_ADDRESS { ++ UINT_8 aucIpAddr[4]; ++} IPV4_NETWORK_ADDRESS, *P_IPV4_NETWORK_ADDRESS; ++ ++typedef struct _CMD_SET_NETWORK_ADDRESS_LIST { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucAddressCount; ++ UINT_8 ucReserved[2]; ++ IPV4_NETWORK_ADDRESS arNetAddress[1]; ++} CMD_SET_NETWORK_ADDRESS_LIST, *P_CMD_SET_NETWORK_ADDRESS_LIST; ++ ++typedef struct _PATTERN_DESCRIPTION { ++ UINT_8 fgCheckBcA1; ++ UINT_8 fgCheckMcA1; ++ UINT_8 ePatternHeader; ++ UINT_8 fgAndOp; ++ UINT_8 fgNotOp; ++ UINT_8 ucPatternMask; ++ UINT_16 ucPatternOffset; ++ UINT_8 aucPattern[8]; ++} PATTERN_DESCRIPTION, *P_PATTERN_DESCRIPTION; ++ ++typedef struct _CMD_RAW_PATTERN_CONFIGURATION_T { ++ PATTERN_DESCRIPTION arPatternDesc[4]; ++} CMD_RAW_PATTERN_CONFIGURATION_T, *P_CMD_RAW_PATTERN_CONFIGURATION_T; ++ ++typedef struct _CMD_PATTERN_FUNC_CONFIG { ++ BOOLEAN fgBcA1En; ++ BOOLEAN fgMcA1En; ++ BOOLEAN fgBcA1MatchDrop; ++ BOOLEAN fgMcA1MatchDrop; ++} CMD_PATTERN_FUNC_CONFIG, *P_CMD_PATTERN_FUNC_CONFIG; ++ ++typedef struct _EVENT_TX_DONE_T { ++ UINT_8 ucPacketSeq; ++ UINT_8 ucStatus; ++ UINT_16 u2SequenceNumber; ++ UINT_32 au4Reserved1; ++ UINT_32 au4Reserved2; ++ UINT_32 au4Reserved3; ++} EVENT_TX_DONE_T, *P_EVENT_TX_DONE_T; ++ ++typedef struct _CMD_BSS_ACTIVATE_CTRL { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucActive; ++ UINT_8 aucReserved[2]; ++} CMD_BSS_ACTIVATE_CTRL, *P_CMD_BSS_ACTIVATE_CTRL; ++ ++typedef struct _CMD_SET_BSS_RLM_PARAM_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucRfBand; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucRfSco; ++ UINT_8 ucErpProtectMode; ++ UINT_8 ucHtProtectMode; ++ UINT_8 ucGfOperationMode; ++ UINT_8 ucTxRifsMode; ++ UINT_16 u2HtOpInfo3; ++ UINT_16 u2HtOpInfo2; ++ UINT_8 ucHtOpInfo1; ++ UINT_8 ucUseShortPreamble; ++ UINT_8 ucUseShortSlotTime; ++ UINT_8 ucCheckId; /* Fixed value: 0x72 */ ++} CMD_SET_BSS_RLM_PARAM_T, *P_CMD_SET_BSS_RLM_PARAM_T; ++ ++typedef struct _CMD_SET_BSS_INFO { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucConnectionState; ++ UINT_8 ucCurrentOPMode; ++ UINT_8 ucSSIDLen; ++ UINT_8 aucSSID[32]; ++ UINT_8 aucBSSID[6]; ++ UINT_8 ucIsQBSS; ++ UINT_8 ucReserved1; ++ UINT_16 u2OperationalRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ UINT_8 ucStaRecIdxOfAP; ++ UINT_8 ucReserved2; ++ UINT_8 ucReserved3; ++ UINT_8 ucNonHTBasicPhyType; /* For Slot Time and CWmin */ ++ UINT_8 ucAuthMode; ++ UINT_8 ucEncStatus; ++ UINT_8 ucPhyTypeSet; ++ UINT_8 aucOwnMac[6]; ++ UINT_8 fgWapiMode; ++ UINT_8 fgIsApMode; ++ UINT_8 fgHiddenSsidMode; ++ CMD_SET_BSS_RLM_PARAM_T rBssRlmParam; ++} CMD_SET_BSS_INFO, *P_CMD_SET_BSS_INFO; ++ ++typedef struct _CMD_UPDATE_STA_RECORD_T { ++ UINT_8 ucIndex; ++ UINT_8 ucStaType; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ UINT_16 u2AssocId; ++ UINT_16 u2ListenInterval; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucDesiredPhyTypeSet; ++ UINT_16 u2DesiredNonHTRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ UINT_8 ucIsQoS; ++ UINT_8 ucIsUapsdSupported; ++ UINT_8 ucStaState; ++ UINT_8 ucMcsSet; ++ UINT_8 ucSupMcs32; ++ UINT_8 ucAmpduParam; ++ UINT_16 u2HtCapInfo; ++ UINT_16 u2HtExtendedCap; ++ UINT_32 u4TxBeamformingCap; ++ UINT_8 ucAselCap; ++ UINT_8 ucRCPI; ++ UINT_8 ucNeedResp; ++ UINT_8 ucUapsdAc; /* b0~3: Trigger enabled, b4~7: Delivery enabled */ ++ UINT_8 ucUapsdSp; /* 0: all, 1: max 2, 2: max 4, 3: max 6 */ ++ UINT_8 aucReserved[3]; ++ /* TBD */ ++} CMD_UPDATE_STA_RECORD_T, *P_CMD_UPDATE_STA_RECORD_T; ++ ++typedef struct _CMD_REMOVE_STA_RECORD_T { ++ UINT_8 ucIndex; ++ UINT_8 ucReserved; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++} CMD_REMOVE_STA_RECORD_T, *P_CMD_REMOVE_STA_RECORD_T; ++ ++typedef struct _CMD_INDICATE_PM_BSS_CREATED_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucDtimPeriod; ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2AtimWindow; ++ UINT_8 aucReserved[2]; ++} CMD_INDICATE_PM_BSS_CREATED, *P_CMD_INDICATE_PM_BSS_CREATED; ++ ++typedef struct _CMD_INDICATE_PM_BSS_CONNECTED_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucDtimPeriod; ++ UINT_16 u2AssocId; ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2AtimWindow; ++ UINT_8 fgIsUapsdConnection; ++ UINT_8 ucBmpDeliveryAC; ++ UINT_8 ucBmpTriggerAC; ++ UINT_8 aucReserved[1]; ++} CMD_INDICATE_PM_BSS_CONNECTED, *P_CMD_INDICATE_PM_BSS_CONNECTED; ++ ++typedef struct _CMD_INDICATE_PM_BSS_ABORT { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[3]; ++} CMD_INDICATE_PM_BSS_ABORT, *P_CMD_INDICATE_PM_BSS_ABORT; ++ ++typedef struct _CMD_BEACON_TEMPLATE_UPDATE { ++ UINT_8 ucUpdateMethod; /* 0: update randomly, ++ * 1: update all, ++ * 2: delete all (1 and 2 will update directly without search) ++ */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[2]; ++ UINT_16 u2Capability; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_BEACON_TEMPLATE_UPDATE, *P_CMD_BEACON_TEMPLATE_UPDATE; ++ ++typedef struct _CMD_SET_WMM_PS_TEST_STRUCT_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ ++ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ ++ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ ++} CMD_SET_WMM_PS_TEST_STRUCT_T, *P_CMD_SET_WMM_PS_TEST_STRUCT_T; ++ ++/* Definition for CHANNEL_INFO.ucBand: ++ * 0: Reserved ++ * 1: BAND_2G4 ++ * 2: BAND_5G ++ * Others: Reserved ++ */ ++typedef struct _CHANNEL_INFO_T { ++ UINT_8 ucBand; ++ UINT_8 ucChannelNum; ++} CHANNEL_INFO_T, *P_CHANNEL_INFO_T; ++ ++typedef struct _CMD_SCAN_REQ_EXT_CH_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDLength; ++ UINT_8 aucReserved[1]; ++ UINT_16 u2ChannelMinDwellTime; ++ UINT_8 aucSSID[32]; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ_EXT_CH, *P_CMD_SCAN_REQ_EXT_CH; ++ ++typedef struct _CMD_SCAN_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ ++ UINT_8 ucSSIDLength; ++ UINT_8 aucReserved[1]; ++ UINT_16 u2ChannelMinDwellTime; ++ UINT_8 aucSSID[32]; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[32]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ, *P_CMD_SCAN_REQ; ++ ++typedef struct _CMD_SCAN_REQ_V2_EXT_CH_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; ++ PARAM_SSID_T arSSID[4]; ++ UINT_16 u2ProbeDelayTime; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ_V2_EXT_CH, *P_CMD_SCAN_REQ_V2_EXT_CH; ++ ++typedef struct _CMD_SCAN_REQ_V2_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetworkType; ++ UINT_8 ucScanType; ++ UINT_8 ucSSIDType; ++ PARAM_SSID_T arSSID[4]; ++ UINT_16 u2ProbeDelayTime; ++ UINT_16 u2ChannelDwellTime; /* For P2P */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ CHANNEL_INFO_T arChannelList[32]; ++ UINT_16 u2IELen; ++ UINT_8 aucIE[MAX_IE_LENGTH]; ++} CMD_SCAN_REQ_V2, *P_CMD_SCAN_REQ_V2; ++ ++typedef struct _CMD_SCAN_CANCEL_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucIsExtChannel; /* For P2P channel extension. */ ++ UINT_8 aucReserved[2]; ++} CMD_SCAN_CANCEL, *P_CMD_SCAN_CANCEL; ++ ++typedef struct _EVENT_SCAN_DONE_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucSparseChannelValid; ++ CHANNEL_INFO_T rSparseChannel; ++} EVENT_SCAN_DONE, *P_EVENT_SCAN_DONE; ++ ++#if CFG_SUPPORT_GET_CH_ENV ++typedef struct _CH_ENV_T { ++ UINT_8 ucChNum; ++ UINT_8 ucApNum; ++} CH_ENV_T, *P_CH_ENV_T; ++#endif ++ ++#if 0 /* CFG_SUPPORT_BATCH_SCAN */ ++typedef struct _CMD_BATCH_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucCmd; /* Start/ Stop */ ++ UINT_8 ucMScan; /* an integer number of scans per batch */ ++ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ ++ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd ++ like approximate distance reported */ ++ UINT_8 ucChannel; /* channels */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ ++ CHANNEL_INFO_T arChannelList[32]; /* channels */ ++} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; ++ ++typedef struct _EVENT_BATCH_RESULT_ENTRY_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ UINT_8 ucSSIDLen; ++ INT_8 cRssi; ++ UINT_32 ucFreq; ++ UINT_32 u4Age; ++ UINT_32 u4Dist; ++ UINT_32 u4Distsd; ++} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; ++ ++typedef struct _EVENT_BATCH_RESULT_T { ++ UINT_8 ucScanCount; ++ UINT_8 aucReserved[3]; ++ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ ++} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; ++#endif ++ ++typedef struct _CMD_CH_PRIVILEGE_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucAction; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucRfSco; ++ UINT_8 ucRfBand; ++ UINT_8 ucReqType; ++ UINT_8 ucReserved; ++ UINT_32 u4MaxInterval; /* In unit of ms */ ++ UINT_8 aucBSSID[6]; ++ UINT_8 aucReserved[2]; ++} CMD_CH_PRIVILEGE_T, *P_CMD_CH_PRIVILEGE_T; ++ ++typedef struct _CMD_TX_PWR_T { ++ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ ++#if defined(MT6620) ++ INT_8 acReserved[3]; ++#elif defined(MT6628) ++ INT_8 cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ ++ INT_8 acReserved[2]; ++#else ++#error "No valid definition!" ++#endif ++ ++ INT_8 cTxPwr2G4OFDM_BPSK; ++ INT_8 cTxPwr2G4OFDM_QPSK; ++ INT_8 cTxPwr2G4OFDM_16QAM; ++ INT_8 cTxPwr2G4OFDM_Reserved; ++ INT_8 cTxPwr2G4OFDM_48Mbps; ++ INT_8 cTxPwr2G4OFDM_54Mbps; ++ ++ INT_8 cTxPwr2G4HT20_BPSK; ++ INT_8 cTxPwr2G4HT20_QPSK; ++ INT_8 cTxPwr2G4HT20_16QAM; ++ INT_8 cTxPwr2G4HT20_MCS5; ++ INT_8 cTxPwr2G4HT20_MCS6; ++ INT_8 cTxPwr2G4HT20_MCS7; ++ ++ INT_8 cTxPwr2G4HT40_BPSK; ++ INT_8 cTxPwr2G4HT40_QPSK; ++ INT_8 cTxPwr2G4HT40_16QAM; ++ INT_8 cTxPwr2G4HT40_MCS5; ++ INT_8 cTxPwr2G4HT40_MCS6; ++ INT_8 cTxPwr2G4HT40_MCS7; ++ ++ INT_8 cTxPwr5GOFDM_BPSK; ++ INT_8 cTxPwr5GOFDM_QPSK; ++ INT_8 cTxPwr5GOFDM_16QAM; ++ INT_8 cTxPwr5GOFDM_Reserved; ++ INT_8 cTxPwr5GOFDM_48Mbps; ++ INT_8 cTxPwr5GOFDM_54Mbps; ++ ++ INT_8 cTxPwr5GHT20_BPSK; ++ INT_8 cTxPwr5GHT20_QPSK; ++ INT_8 cTxPwr5GHT20_16QAM; ++ INT_8 cTxPwr5GHT20_MCS5; ++ INT_8 cTxPwr5GHT20_MCS6; ++ INT_8 cTxPwr5GHT20_MCS7; ++ ++ INT_8 cTxPwr5GHT40_BPSK; ++ INT_8 cTxPwr5GHT40_QPSK; ++ INT_8 cTxPwr5GHT40_16QAM; ++ INT_8 cTxPwr5GHT40_MCS5; ++ INT_8 cTxPwr5GHT40_MCS6; ++ INT_8 cTxPwr5GHT40_MCS7; ++} CMD_TX_PWR_T, *P_CMD_TX_PWR_T; ++ ++typedef struct _CMD_5G_PWR_OFFSET_T { ++ INT_8 cOffsetBand0; /* 4.915-4.980G */ ++ INT_8 cOffsetBand1; /* 5.000-5.080G */ ++ INT_8 cOffsetBand2; /* 5.160-5.180G */ ++ INT_8 cOffsetBand3; /* 5.200-5.280G */ ++ INT_8 cOffsetBand4; /* 5.300-5.340G */ ++ INT_8 cOffsetBand5; /* 5.500-5.580G */ ++ INT_8 cOffsetBand6; /* 5.600-5.680G */ ++ INT_8 cOffsetBand7; /* 5.700-5.825G */ ++} CMD_5G_PWR_OFFSET_T, *P_CMD_5G_PWR_OFFSET_T; ++ ++typedef struct _CMD_PWR_PARAM_T { ++ UINT_32 au4Data[28]; ++ UINT_32 u4RefValue1; ++ UINT_32 u4RefValue2; ++} CMD_PWR_PARAM_T, *P_CMD_PWR_PARAM_T; ++ ++typedef struct _CMD_PHY_PARAM_T { ++ UINT_8 aucData[144]; /* eFuse content */ ++} CMD_PHY_PARAM_T, *P_CMD_PHY_PARAM_T; ++ ++typedef struct _CMD_AUTO_POWER_PARAM_T { ++ UINT_8 ucType; /* 0: Disable 1: Enalbe 0x10: Change parameters */ ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[2]; ++ UINT_8 aucLevelRcpiTh[3]; ++ UINT_8 aucReserved2[1]; ++ INT_8 aicLevelPowerOffset[3]; /* signed, in unit of 0.5dBm */ ++ UINT_8 aucReserved3[1]; ++ UINT_8 aucReserved4[8]; ++} CMD_AUTO_POWER_PARAM_T, *P_CMD_AUTO_POWER_PARAM_T; ++ ++typedef struct _EVENT_CH_PRIVILEGE_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucTokenID; ++ UINT_8 ucStatus; ++ UINT_8 ucPrimaryChannel; ++ UINT_8 ucRfSco; ++ UINT_8 ucRfBand; ++ UINT_8 ucReqType; ++ UINT_8 ucReserved; ++ UINT_32 u4GrantInterval; /* In unit of ms */ ++} EVENT_CH_PRIVILEGE_T, *P_EVENT_CH_PRIVILEGE_T; ++ ++typedef enum _ENUM_BEACON_TIMEOUT_TYPE_T { ++ BEACON_TIMEOUT_LOST_BEACON = 0, ++ BEACON_TIMEOUT_AGE, ++ BEACON_TIMEOUT_CONNECT, ++ BEACON_TIMEOUT_BEACON_INTERVAL, ++ BEACON_TIMEOUT_ABORT, ++ BEACON_TIMEOUT_TX_ERROR, ++ BEACON_TIMEOUT_TYPE_NUM ++} ENUM_BEACON_TIMEOUT_TYPE_T, *P_ENUM_BEACON_TIMEOUT_TYPE_T; ++ ++typedef struct _EVENT_BSS_BEACON_TIMEOUT_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucReason; /* ENUM_BEACON_TIMEOUT_TYPE_T */ ++ UINT_8 aucReserved[2]; ++} EVENT_BSS_BEACON_TIMEOUT_T, *P_EVENT_BSS_BEACON_TIMEOUT_T; ++ ++typedef struct _EVENT_STA_AGING_TIMEOUT_T { ++ UINT_8 ucStaRecIdx; ++ UINT_8 aucReserved[3]; ++} EVENT_STA_AGING_TIMEOUT_T, *P_EVENT_STA_AGING_TIMEOUT_T; ++ ++typedef struct _EVENT_NOA_TIMING_T { ++ UINT_8 fgIsInUse; /* Indicate if this entry is in use or not */ ++ UINT_8 ucCount; /* Count */ ++ UINT_8 aucReserved[2]; ++ ++ UINT_32 u4Duration; /* Duration */ ++ UINT_32 u4Interval; /* Interval */ ++ UINT_32 u4StartTime; /* Start Time */ ++} EVENT_NOA_TIMING_T, *P_EVENT_NOA_TIMING_T; ++ ++typedef struct _EVENT_UPDATE_NOA_PARAMS_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 aucReserved[2]; ++ UINT_8 fgEnableOppPS; ++ UINT_16 u2CTWindow; ++ ++ UINT_8 ucNoAIndex; ++ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ ++ EVENT_NOA_TIMING_T arEventNoaTiming[8 /*P2P_MAXIMUM_NOA_COUNT */]; ++} EVENT_UPDATE_NOA_PARAMS_T, *P_EVENT_UPDATE_NOA_PARAMS_T; ++ ++typedef struct _EVENT_AP_OBSS_STATUS_T { ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucObssErpProtectMode; ++ UINT_8 ucObssHtProtectMode; ++ UINT_8 ucObssGfOperationMode; ++ UINT_8 ucObssRifsOperationMode; ++ UINT_8 ucObssBeaconForcedTo20M; ++ UINT_8 aucReserved[2]; ++} EVENT_AP_OBSS_STATUS_T, *P_EVENT_AP_OBSS_STATUS_T; ++ ++typedef struct _CMD_EDGE_TXPWR_LIMIT_T { ++ INT_8 cBandEdgeMaxPwrCCK; ++ INT_8 cBandEdgeMaxPwrOFDM20; ++ INT_8 cBandEdgeMaxPwrOFDM40; ++ INT_8 cReserved; ++} CMD_EDGE_TXPWR_LIMIT_T, *P_CMD_EDGE_TXPWR_LIMIT_T; ++ ++typedef struct _CMD_RSSI_COMPENSATE_T { ++ UINT_8 uc2GRssiCompensation; ++ UINT_8 uc5GRssiCompensation; ++ UINT_8 ucRssiCompensationValidbit; ++ UINT_8 cReserved; ++} CMD_RSSI_COMPENSATE_T, *P_CMD_RSSI_COMPENSATE_T; ++ ++typedef struct _CMD_BAND_SUPPORT_T { ++ UINT_8 uc5GBandSupport; ++ UINT_8 cReserved[3]; ++} CMD_BAND_SUPPORT_T, *P_CMD_BAND_SUPPORT_T; ++ ++typedef struct _CMD_TX_PWR_CE_T { ++ INT_8 cTxPwrCckLmt; /* signed, in unit of 0.5dBm */ ++ INT_8 cTxPwrOfdmLmt; /* signed, in unit of 0.5dBm */ ++ INT_8 cTxPwrHt20Lmt; ++ INT_8 cTxPwrHt40Lmt; ++} CMD_TX_PWR_CE_T, *P_CMD_TX_PWR_CE_T; ++ ++typedef struct _CMD_SET_DEVICE_MODE_T { ++ UINT_16 u2ChipID; ++ UINT_16 u2Mode; ++} CMD_SET_DEVICE_MODE_T, *P_CMD_SET_DEVICE_MODE_T; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++typedef struct _CMD_RDD_CH_T { ++ UINT_8 ucRddTestMode; ++ UINT_8 ucRddShutCh; ++ UINT_8 ucRddStartCh; ++ UINT_8 ucRddStopCh; ++ UINT_8 ucRddDfs; ++ UINT_8 ucReserved; ++ UINT_8 ucReserved1; ++ UINT_8 ucReserved2; ++} CMD_RDD_CH_T, *P_CMD_RDD_CH_T; ++ ++typedef struct _EVENT_RDD_STATUS_T { ++ UINT_8 ucRddStatus; ++ UINT_8 aucReserved[3]; ++} EVENT_RDD_STATUS_T, *P_EVENT_RDD_STATUS_T; ++#endif ++ ++typedef struct _EVENT_AIS_BSS_INFO_T { ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ ++ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ ++ BOOLEAN fgIsNetActive; /* TRUE if this network has been actived */ ++ UINT_8 ucReserved[3]; ++} EVENT_AIS_BSS_INFO_T, *P_EVENT_AIS_BSS_INFO_T; ++ ++typedef struct _CMD_SET_TXPWR_CTRL_T { ++ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c2GHotspotPwrOffset; ++ INT_8 c2GP2pPwrOffset; ++ INT_8 c2GBowPwrOffset; ++ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c5GHotspotPwrOffset; ++ INT_8 c5GP2pPwrOffset; ++ INT_8 c5GBowPwrOffset; ++ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence ++ in the same channel ++ 0: Highest power has priority ++ 1: Lowest power has priority */ ++ INT_8 acReserved1[3]; /* Must be zero */ ++ ++ /* Power limit by channel for all data rates */ ++ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ ++ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ ++ INT_8 acReserved2[2]; /* Must be zero */ ++} CMD_SET_TXPWR_CTRL_T, *P_CMD_SET_TXPWR_CTRL_T; ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++typedef struct _CMD_GET_BUILD_DATE_CODE { ++ UINT_8 aucReserved[4]; ++} CMD_GET_BUILD_DATE_CODE, *P_CMD_GET_BUILD_DATE_CODE; ++ ++typedef struct _EVENT_BUILD_DATE_CODE { ++ UINT_8 aucDateCode[16]; ++} EVENT_BUILD_DATE_CODE, *P_EVENT_BUILD_DATE_CODE; ++#endif ++ ++typedef struct _CMD_GET_STA_STATISTICS_T { ++ UINT_8 ucIndex; ++ UINT_8 ucFlags; ++ UINT_8 ucReadClear; ++ UINT_8 aucReserved0[1]; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ UINT_8 aucReserved1[2]; ++ UINT_8 aucReserved2[16]; ++} CMD_GET_STA_STATISTICS_T, *P_CMD_GET_STA_STATISTICS_T; ++ ++/* CFG_SUPPORT_WFD */ ++typedef struct _EVENT_STA_STATISTICS_T { ++ /* Event header */ ++ /* UINT_16 u2Length; */ ++ /* UINT_16 u2Reserved1; *//* Must be filled with 0x0001 (EVENT Packet) */ ++ /* UINT_8 ucEID; */ ++ /* UINT_8 ucSeqNum; */ ++ /* UINT_8 aucReserved2[2]; */ ++ ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ UINT_8 ucStaRecIdx; ++ UINT_8 ucNetworkTypeIndex; ++ UINT_8 ucWTEntry; ++ UINT_8 aucReserved4[1]; ++ ++ UINT_8 ucMacAddr[MAC_ADDR_LEN]; ++ UINT_8 ucPer; /* base: 128 */ ++ UINT_8 ucRcpi; ++ ++ UINT_32 u4PhyMode; /* SGI BW */ ++ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ ++ UINT_8 ucLinkQuality; ++ UINT_8 ucLinkReserved; ++ ++ UINT_32 u4TxCount; ++ UINT_32 u4TxFailCount; ++ UINT_32 u4TxLifeTimeoutCount; ++ UINT_32 u4TxDoneAirTime; ++ ++ UINT_8 aucReserved[64]; ++} EVENT_STA_STATISTICS_T, *P_EVENT_STA_STATISTICS_T; ++ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++typedef struct _CMD_HOTSPOT_OPTIMIZATION_CONFIG { ++ UINT_32 fgHotspotOptimizationEn; ++ UINT_32 u4Level; ++} CMD_HOTSPOT_OPTIMIZATION_CONFIG, *P_HOTSPOT_OPTIMIZATION_CONFIG; ++#endif ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++/* 4 Auto Channel Selection */ ++ ++typedef struct _CMD_GET_CHN_LOAD_T { ++ UINT_8 ucIndex; ++ UINT_8 ucFlags; ++ UINT_8 ucReadClear; ++ UINT_8 aucReserved0[1]; ++ ++ UINT_8 ucChannel; ++ UINT_16 u2ChannelLoad; ++ UINT_8 aucReserved1[1]; ++ UINT_8 aucReserved2[16]; ++} CMD_GET_CHN_LOAD_T, *P_CMD_GET_CHN_LOAD_T; ++/* 4 Auto Channel Selection */ ++ ++typedef struct _EVENT_CHN_LOAD_T { ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ UINT_8 ucChannel; ++ UINT_16 u2ChannelLoad; ++ UINT_8 aucReserved4[1]; ++ ++ UINT_8 aucReserved[64]; ++ ++} EVENT_CHN_LOAD_T, *P_EVENT_CHN_LOAD_T; ++typedef struct _CMD_GET_LTE_SAFE_CHN_T { ++ UINT_8 ucIndex; ++ UINT_8 ucFlags; ++ UINT_8 aucReserved0[2]; ++ ++ UINT_8 aucReserved2[16]; ++} CMD_GET_LTE_SAFE_CHN_T, *P_CMD_GET_LTE_SAFE_CHN_T; ++ ++typedef struct _EVENT_LTE_MODE_T { ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ LTE_SAFE_CH_INFO_T rLteSafeChn; ++ UINT_8 aucReserved4[3]; ++ ++ UINT_8 aucReserved[4]; ++ ++} EVENT_LTE_MODE_T, *P_EVENT_LTE_MODE_T; ++#endif ++typedef struct _CMD_ROAMING_INFO_T { ++ UINT_32 fgIsFastRoamingApplied; ++ UINT_32 Reserved[9]; ++} CMD_ROAMING_INFO_T; ++ ++typedef struct _CMD_WFD_DEBUG_MODE_INFO_T { ++ UINT_8 ucDebugMode; ++ UINT_16 u2PeriodInteval; ++ UINT_8 Reserved; ++} CMD_WFD_DEBUG_MODE_INFO_T, *P_CMD_WFD_DEBUG_MODE_INFO_T; ++ ++typedef struct _EVENT_FW_LOG_T { ++ UINT_8 fileName[64]; ++ UINT_32 lineNo; ++ UINT_32 WifiUpTime; ++ UINT_8 log[896]; /* total size is aucBuffer in WIFI_EVENT_T */ ++} EVENT_FW_LOG_T, *P_EVENT_FW_LOG_T; ++ ++typedef enum _ENUM_NLO_CIPHER_ALGORITHM { ++ NLO_CIPHER_ALGO_NONE = 0x00, ++ NLO_CIPHER_ALGO_WEP40 = 0x01, ++ NLO_CIPHER_ALGO_TKIP = 0x02, ++ NLO_CIPHER_ALGO_CCMP = 0x04, ++ NLO_CIPHER_ALGO_WEP104 = 0x05, ++ NLO_CIPHER_ALGO_WPA_USE_GROUP = 0x100, ++ NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100, ++ NLO_CIPHER_ALGO_WEP = 0x101, ++} ENUM_NLO_CIPHER_ALGORITHM, *P_ENUM_NLO_CIPHER_ALGORITHM; ++ ++typedef enum _ENUM_NLO_AUTH_ALGORITHM { ++ NLO_AUTH_ALGO_80211_OPEN = 1, ++ NLO_AUTH_ALGO_80211_SHARED_KEY = 2, ++ NLO_AUTH_ALGO_WPA = 3, ++ NLO_AUTH_ALGO_WPA_PSK = 4, ++ NLO_AUTH_ALGO_WPA_NONE = 5, ++ NLO_AUTH_ALGO_RSNA = 6, ++ NLO_AUTH_ALGO_RSNA_PSK = 7, ++} ENUM_NLO_AUTH_ALGORITHM, *P_ENUM_NLO_AUTH_ALGORITHM; ++ ++typedef struct _NLO_NETWORK { ++ UINT_8 ucNumChannelHint[4]; ++ UINT_8 ucSSIDLength; ++ UINT_8 ucCipherAlgo; ++ UINT_16 u2AuthAlgo; ++ UINT_8 aucSSID[32]; ++} NLO_NETWORK, *P_NLO_NETWORK; ++ ++typedef struct _CMD_NLO_REQ { ++ UINT_8 ucSeqNum; ++ UINT_8 ucBssIndex; ++ UINT_8 ucNetworkType; ++ UINT_8 fgStopAfterIndication; ++ UINT_8 ucFastScanIteration; ++ UINT_16 u2FastScanPeriod; ++ UINT_16 u2SlowScanPeriod; ++ UINT_8 ucEntryNum; ++ UINT_8 ucReserved; ++ UINT_16 u2IELen; ++ NLO_NETWORK arNetworkList[16]; ++ UINT_8 aucIE[0]; ++ UINT_8 ucScanType; ++} CMD_NLO_REQ, *P_CMD_NLO_REQ; ++ ++typedef struct _CMD_NLO_CANCEL_T { ++ UINT_8 ucSeqNum; ++ UINT_8 aucReserved[3]; ++} CMD_NLO_CANCEL, *P_CMD_NLO_CANCEL; ++ ++typedef struct _EVENT_NLO_DONE_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucStatus; ++ UINT_8 aucReserved[2]; ++} EVENT_NLO_DONE_T, *P_EVENT_NLO_DONE_T; ++ ++typedef struct _EVENT_GSCAN_CAPABILITY_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4MaxScanCacheSize; ++ UINT_32 u4MaxScanBuckets; ++ UINT_32 u4MaxApCachePerScan; ++ UINT_32 u4MaxRssiSampleSize; ++ UINT_32 u4MaxScanReportingThreshold; ++ UINT_32 u4MaxHotlistAps; ++ UINT_32 u4MaxSignificantWifiChangeAps; ++ UINT_32 au4Reserved[4]; ++} EVENT_GSCAN_CAPABILITY_T, *P_EVENT_GSCAN_CAPABILITY_T; ++ ++typedef struct _EVENT_GSCAN_SCAN_AVAILABLE_T { ++ UINT_16 u2Num; ++ UINT_8 aucReserved[2]; ++} EVENT_GSCAN_SCAN_AVAILABLE_T, *P_EVENT_GSCAN_SCAN_AVAILABLE_T; ++ ++typedef struct _EVENT_GSCAN_SCAN_COMPLETE_T { ++ UINT_8 ucScanState; ++ UINT_8 aucReserved[3]; ++} EVENT_GSCAN_SCAN_COMPLETE_T, *P_EVENT_GSCAN_SCAN_COMPLETE_T; ++ ++typedef struct WIFI_GSCAN_RESULT { ++ UINT_64 u8Ts; /* Time of discovery */ ++ UINT_8 arSsid[ELEM_MAX_LEN_SSID + 1]; /* null terminated */ ++ UINT_8 arMacAddr[6]; /* BSSID */ ++ UINT_32 u4Channel; /* channel frequency in MHz */ ++ INT_32 i4Rssi; /* in db */ ++ UINT_64 u8Rtt; /* in nanoseconds */ ++ UINT_64 u8RttSd; /* standard deviation in rtt */ ++ UINT_16 u2BeaconPeriod; /* units are Kusec */ ++ UINT_16 u2Capability; /* Capability information */ ++ UINT_32 u4IeLength; /* byte length of Information Elements */ ++ UINT_8 ucIeData[1]; /* IE data to follow */ ++} WIFI_GSCAN_RESULT_T, *P_WIFI_GSCAN_RESULT_T; ++ ++typedef struct _EVENT_GSCAN_RESULT_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ UINT_16 u2ScanId; ++ UINT_16 u2ScanFlags; ++ UINT_16 u2NumOfResults; ++ WIFI_GSCAN_RESULT_T rResult[1]; ++} EVENT_GSCAN_RESULT_T, *P_EVENT_GSCAN_RESULT_T; ++ ++typedef struct _EVENT_GSCAN_FULL_RESULT_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ WIFI_GSCAN_RESULT_T rResult; ++} EVENT_GSCAN_FULL_RESULT_T, *P_EVENT_GSCAN_FULL_RESULT_T; ++ ++typedef struct GSCAN_SWC_NET { ++ UINT_16 u2Flags; ++ UINT_16 u2Channel; ++ UINT_8 arBssid[6]; ++ INT_8 aicRssi[SCN_PSCAN_SWC_RSSI_WIN_MAX]; ++} GSCAN_SWC_NET_T, P_GSCAN_SWC_NET_T; ++ ++typedef struct _EVENT_GSCAN_SIGNIFICANT_CHANGE_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ GSCAN_SWC_NET_T arNet[SCN_PSCAN_SWC_MAX_NUM]; ++} EVENT_GSCAN_SIGNIFICANT_CHANGE_T, *P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T; ++ ++typedef struct _EVENT_GSCAN_GEOFENCE_FOUND_T { ++ UINT_8 ucVersion; ++ UINT_8 aucReserved[3]; ++ WIFI_GSCAN_RESULT_T rResult[SCN_PSCAN_HOTLIST_REPORT_MAX_NUM]; ++} EVENT_GSCAN_GEOFENCE_FOUND_T, *P_EVENT_GSCAN_GEOFENCE_FOUND_T; ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ ++#if 0 /* !CFG_SUPPORT_GSCN */ ++typedef struct _CMD_BATCH_REQ_T { ++ UINT_8 ucSeqNum; ++ UINT_8 ucNetTypeIndex; ++ UINT_8 ucCmd; /* Start/ Stop */ ++ UINT_8 ucMScan; /* an integer number of scans per batch */ ++ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ ++ UINT_8 ucRtt; /* an integer number of highest-strength AP for which ++ we'd like approximate distance reported */ ++ UINT_8 ucChannel; /* channels */ ++ UINT_8 ucChannelType; ++ UINT_8 ucChannelListNum; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ ++ CHANNEL_INFO_T arChannelList[32]; /* channels */ ++} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; ++ ++#endif ++ ++typedef struct _EVENT_BATCH_RESULT_ENTRY_T { ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; ++ UINT_8 ucSSIDLen; ++ INT_8 cRssi; ++ UINT_32 ucFreq; ++ UINT_32 u4Age; ++ UINT_32 u4Dist; ++ UINT_32 u4Distsd; ++} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; ++ ++typedef struct _EVENT_BATCH_RESULT_T { ++ UINT_8 ucScanCount; ++ UINT_8 aucReserved[3]; ++ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ ++} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; ++#endif ++ ++typedef struct _CMD_RLM_INFO_T { ++ UINT_32 u4Version; ++ UINT_32 fgIsErrRatioEnhanceApplied; ++ UINT_8 ucErrRatio2LimitMinRate; ++ /* ++ 0:1M, 1:2M, 2:5.5M, 3:11M, 6:6M, 7:9M, 8:12M, 9:18M, 10:24M, 11:36M, 12:48M, 13:54M ++ */ ++ UINT_8 ucMinLegacyRateIdx; ++ INT_8 cMinRssiThreshold; ++ BOOLEAN fgIsRtsApplied; ++ UINT_8 ucRecoverTime; ++ ++ UINT_32 u4Reserved[0]; ++} CMD_RLM_INFO_T; ++ ++typedef struct _WIFI_SYSTEM_SUSPEND_CMD_T { ++ BOOLEAN fgIsSystemSuspend; ++ UINT_8 reserved[3]; ++} WIFI_SYSTEM_SUSPEND_CMD_T, *P_WIFI_SYSTEM_SUSPEND_CMD_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++/* Statistics responder */ ++VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++/* for timeout check */ ++VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++#endif ++ ++VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++/* 4 Auto Channel Selection */ ++VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++#endif ++ ++#if CFG_SUPPORT_BATCH_SCAN ++VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++#endif ++ ++VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _NIC_CMD_EVENT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h +new file mode 100644 +index 000000000000..994c589190de +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h +@@ -0,0 +1,177 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_init_cmd_event.h#1 ++*/ ++ ++/*! \file "nic_init_cmd_event.h" ++ \brief This file contains the declairation file of the WLAN initialization routines ++ for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: nic_init_cmd_event.h ++ * ++ * 09 26 2011 cp.wu ++ * [WCXRP00001011] [MT6628 Wi-Fi] Firmware Download Agent: make CRC validation as an optional feature ++ * add definition for disabling CRC32 validation (for MT6628 only) ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 03 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add command/event definitions for initial states ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++*/ ++#ifndef _NIC_INIT_CMD_EVENT_H ++#define _NIC_INIT_CMD_EVENT_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define INIT_CMD_STATUS_SUCCESS 0 ++#define INIT_CMD_STATUS_REJECTED_INVALID_PARAMS 1 ++#define INIT_CMD_STATUS_REJECTED_CRC_ERROR 2 ++#define INIT_CMD_STATUS_REJECTED_DECRYPT_FAIL 3 ++#define INIT_CMD_STATUS_UNKNOWN 4 ++ ++#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) ++ ++typedef enum _ENUM_INIT_CMD_ID { ++ INIT_CMD_ID_DOWNLOAD_BUF = 1, ++ INIT_CMD_ID_WIFI_START, ++ INIT_CMD_ID_ACCESS_REG, ++ INIT_CMD_ID_QUERY_PENDING_ERROR ++} ENUM_INIT_CMD_ID, *P_ENUM_INIT_CMD_ID; ++ ++typedef enum _ENUM_INIT_EVENT_ID { ++ INIT_EVENT_ID_CMD_RESULT = 1, ++ INIT_EVENT_ID_ACCESS_REG, ++ INIT_EVENT_ID_PENDING_ERROR ++} ENUM_INIT_EVENT_ID, *P_ENUM_INIT_EVENT_ID; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef UINT_8 CMD_STATUS; ++ ++/* commands */ ++typedef struct _INIT_WIFI_CMD_T { ++ UINT_8 ucCID; ++ UINT_8 ucSeqNum; ++ UINT_16 u2Reserved; ++ UINT_8 aucBuffer[0]; ++} INIT_WIFI_CMD_T, *P_INIT_WIFI_CMD_T; ++ ++typedef struct _INIT_HIF_TX_HEADER_T { ++ UINT_16 u2TxByteCount; ++ UINT_8 ucEtherTypeOffset; ++ UINT_8 ucCSflags; ++ INIT_WIFI_CMD_T rInitWifiCmd; ++} INIT_HIF_TX_HEADER_T, *P_INIT_HIF_TX_HEADER_T; ++ ++#define DOWNLOAD_BUF_ENCRYPTION_MODE BIT(0) ++#define DOWNLOAD_BUF_NO_CRC_CHECKING BIT(30) ++#define DOWNLOAD_BUF_ACK_OPTION BIT(31) ++typedef struct _INIT_CMD_DOWNLOAD_BUF { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4CRC32; ++ UINT_32 u4DataMode; ++ UINT_8 aucBuffer[0]; ++} INIT_CMD_DOWNLOAD_BUF, *P_INIT_CMD_DOWNLOAD_BUF; ++ ++typedef struct _INIT_CMD_WIFI_START { ++ UINT_32 u4Override; ++ UINT_32 u4Address; ++} INIT_CMD_WIFI_START, *P_INIT_CMD_WIFI_START; ++ ++typedef struct _INIT_CMD_ACCESS_REG { ++ UINT_8 ucSetQuery; ++ UINT_8 aucReserved[3]; ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++} INIT_CMD_ACCESS_REG, *P_INIT_CMD_ACCESS_REG; ++ ++/* Events */ ++typedef struct _INIT_WIFI_EVENT_T { ++ UINT_16 u2RxByteCount; ++ UINT_8 ucEID; ++ UINT_8 ucSeqNum; ++ UINT_8 aucBuffer[0]; ++} INIT_WIFI_EVENT_T, *P_INIT_WIFI_EVENT_T; ++ ++typedef struct _INIT_HIF_RX_HEADER_T { ++ INIT_WIFI_EVENT_T rInitWifiEvent; ++} INIT_HIF_RX_HEADER_T, *P_INIT_HIF_RX_HEADER_T; ++ ++typedef struct _INIT_EVENT_CMD_RESULT { ++ UINT_8 ucStatus; /* 0: success */ ++ /* 1: rejected by invalid param */ ++ /* 2: rejected by incorrect CRC */ ++ /* 3: rejected by decryption failure */ ++ /* 4: unknown CMD */ ++ UINT_8 aucReserved[3]; ++} INIT_EVENT_CMD_RESULT, *P_INIT_EVENT_CMD_RESULT, INIT_EVENT_PENDING_ERROR, *P_INIT_EVENT_PENDING_ERROR; ++ ++typedef struct _INIT_EVENT_ACCESS_REG { ++ UINT_32 u4Address; ++ UINT_32 u4Data; ++} INIT_EVENT_ACCESS_REG, *P_INIT_EVENT_ACCESS_REG; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _NIC_INIT_CMD_EVENT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h +new file mode 100644 +index 000000000000..85af819f4e62 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h +@@ -0,0 +1,201 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/p2p_precomp.h#1 ++*/ ++ ++/*! \file p2p_precomp.h ++ \brief Collection of most compiler flags for p2p driver are described here. ++ ++ In this file we collect all compiler flags and detail the p2p driver behavior if ++ enable/disable such switch or adjust numeric parameters. ++*/ ++ ++#ifndef _P2P_PRECOMP_H ++#define _P2P_PRECOMP_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" /* Include "config.h" */ ++ ++#include "gl_p2p_os.h" ++ ++#include "debug.h" ++ ++#include "link.h" ++#include "queue.h" ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++#include "wlan_typedef.h" ++ ++#include "mac.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "wlan_def.h" ++ ++#include "roaming_fsm.h" ++ ++/*------------------------------------------------------------------------------ ++ * .\include\nic ++ *------------------------------------------------------------------------------ ++ */ ++/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ ++#include "cmd_buf.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "nic_cmd_event.h" ++ ++/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ ++#include "nic.h" ++ ++#include "nic_init_cmd_event.h" ++ ++#include "hif_rx.h" ++#include "hif_tx.h" ++ ++#include "nic_tx.h" ++ ++/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ ++#include "nic_rx.h" ++ ++#include "que_mgt.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "p2p_typedef.h" ++#include "p2p_cmd_buf.h" ++#include "p2p_nic_cmd_event.h" ++#include "p2p_mac.h" ++#include "p2p_nic.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++ ++#include "hem_mbox.h" ++ ++#include "scan.h" ++#include "bss.h" ++ ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "wlan_bow.h" ++ ++#include "wlan_p2p.h" ++ ++#include "hal.h" ++ ++#if defined(MT6620) ++#include "mt6620_reg.h" ++#endif ++ ++#include "rlm.h" ++#include "rlm_domain.h" ++#include "rlm_protection.h" ++#include "rlm_obss.h" ++#include "rate.h" ++ ++#include "aa_fsm.h" ++ ++#include "cnm_timer.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#include "bow.h" ++#include "bow_fsm.h" ++#endif ++ ++#include "pwr_mgt.h" ++ ++#include "cnm.h" ++/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ ++#include "cnm_mem.h" ++#include "cnm_scan.h" ++ ++#include "p2p_rlm_obss.h" ++#include "p2p_bss.h" ++#include "p2p.h" ++/* Dependency: cnm_timer.h (TIMER_T) */ ++#include "p2p_fsm.h" ++#include "p2p_scan.h" ++#include "p2p_state.h" ++#include "p2p_func.h" ++#include "p2p_rlm.h" ++#include "p2p_assoc.h" ++#include "p2p_ie.h" ++ ++#include "privacy.h" ++ ++#include "mib.h" ++ ++#include "auth.h" ++#include "assoc.h" ++ ++#include "ais_fsm.h" ++ ++#include "adapter.h" ++ ++#include "que_mgt.h" ++#include "rftest.h" ++ ++#if CFG_RSN_MIGRATION ++#include "rsn.h" ++#include "sec_fsm.h" ++#endif ++ ++#if CFG_SUPPORT_WAPI ++#include "wapi.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * NVRAM structure ++ *------------------------------------------------------------------------------ ++ */ ++#include "CFG_Wifi_File.h" ++ ++#include "gl_p2p_kal.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /*_P2P_PRECOMP_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h +new file mode 100644 +index 000000000000..a02d391d3643 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h +@@ -0,0 +1,165 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/p2p_typedef.h#1 ++*/ ++ ++/*! \file p2p_typedef.h ++ \brief Declaration of data type and return values of internal protocol stack. ++ ++ In this file we declare the data type and return values which will be exported ++ to all MGMT Protocol Stack. ++*/ ++ ++#ifndef _P2P_TYPEDEF_H ++#define _P2P_TYPEDEF_H ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* ++* type definition of pointer to p2p structure ++*/ ++/* typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; */ ++typedef struct _P2P_INFO_T P2P_INFO_T, *P_P2P_INFO_T; ++ ++typedef struct _P2P_FSM_INFO_T P2P_FSM_INFO_T, *P_P2P_FSM_INFO_T; ++ ++typedef struct _P2P_CONNECTION_SETTINGS_T P2P_CONNECTION_SETTINGS_T, *P_P2P_CONNECTION_SETTINGS_T; ++ ++/* Type definition for function pointer to p2p function*/ ++typedef BOOLEAN(*P2P_LAUNCH) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*P2P_REMOVE) (P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsWlanLaunched); ++ ++typedef BOOLEAN(*KAL_P2P_GET_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*KAL_P2P_GET_TKIP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*KAL_P2P_GET_CCMP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef BOOLEAN(*KAL_P2P_GET_WSC_MODE) (IN P_GLUE_INFO_T prGlueInfo); ++ ++typedef struct net_device *(*KAL_P2P_GET_DEV_HDLR) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*KAL_P2P_SET_MULTICAST_WORK_ITEM) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*P2P_NET_REGISTER) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*P2P_NET_UNREGISTER) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef VOID(*KAL_P2P_UPDATE_ASSOC_INFO) (IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, ++ IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); ++ ++typedef BOOLEAN(*P2P_VALIDATE_AUTH) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); ++ ++typedef BOOLEAN(*P2P_VALIDATE_ASSOC_REQ) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu4ControlFlags); ++ ++typedef VOID(*P2P_RUN_EVENT_AAA_TX_FAIL) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++typedef BOOLEAN(*P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM) (IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); ++ ++typedef WLAN_STATUS(*P2P_RUN_EVENT_AAA_COMPLETE) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++typedef VOID(*P2P_PROCESS_EVENT_UPDATE_NOA_PARAM) (IN P_ADAPTER_T prAdapter, ++ UINT_8 ucNetTypeIndex, ++ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); ++ ++typedef VOID(*SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN P_WLAN_STATUS prStatus, ++ IN P_BSS_DESC_T prBssDesc, ++ IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); ++ ++typedef VOID(*P2P_RX_PUBLIC_ACTION_FRAME) (P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*RLM_RSP_GENERATE_OBSS_SCAN_IE) (P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); ++ ++typedef VOID(*RLM_UPDATE_BW_BY_CH_LIST_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++typedef VOID(*RLM_PROCESS_PUBLIC_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*RLM_PROCESS_HT_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*RLM_UPDATE_PARAMS_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); ++ ++typedef VOID(*RLM_HANDLE_OBSS_STATUS_EVENT_PKT) (P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); ++ ++typedef BOOLEAN(*P2P_FUNC_VALIDATE_PROBE_REQ) (IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++typedef VOID(*RLM_BSS_INIT_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++typedef UINT_32(*P2P_GET_PROB_RSP_IE_TABLE_SIZE) (VOID); ++ ++typedef PUINT_8(*P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES) (IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); ++ ++typedef VOID(*P2P_FUNC_DISCONNECT) (IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); ++ ++typedef VOID(*P2P_FSM_RUN_EVENT_RX_DEAUTH) (IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*P2P_FSM_RUN_EVENT_RX_DISASSOC) (IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++typedef BOOLEAN(*P2P_FUN_IS_AP_MODE) (IN P_P2P_FSM_INFO_T prP2pFsmInfo); ++ ++typedef VOID(*P2P_FSM_RUN_EVENT_BEACON_TIMEOUT) (IN P_ADAPTER_T prAdapter); ++ ++typedef VOID(*P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER) (IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); ++ ++typedef VOID(*P2P_GENERATE_P2P_IE) (IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++typedef UINT_32(*P2P_CALCULATE_P2P_IE_LEN) (IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /*CFG_ENABLE_WIFI_DIRECT */ ++ ++#endif /* _P2P_TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h +new file mode 100644 +index 000000000000..1b7e7ede66e1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h +@@ -0,0 +1,388 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/precomp.h#2 ++*/ ++ ++/*! \file precomp.h ++ \brief Collection of most compiler flags are described here. ++ ++ In this file we collect all compiler flags and detail the driver behavior if ++ enable/disable such switch or adjust numeric parameters. ++*/ ++ ++/* ++** Log: precomp.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628-specific definitions. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Fix BOW_FSM_INFO_T dependence. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 28 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * 1st draft code for RLM module ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge cnm_scan.h and hem_mbox.h ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 03 16 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * build up basic data structure and definitions to support BT-over-WiFi ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 11:30:58 GMT mtk02752 ++** add rftest.h for implementing RF test mode in driver land ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-23 22:02:00 GMT mtk02468 ++** Added que_mgt.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-13 21:58:36 GMT mtk01084 ++** update for new macro define ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:40:11 GMT mtk01461 ++** Add nic_cmd_event.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 20:00:26 GMT mtk01461 ++** Add cmd_buf.h ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:44 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:25 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:38 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _PRECOMP_H ++#define _PRECOMP_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" /* Include "config.h" */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "gl_p2p_os.h" ++#endif ++ ++#include "debug.h" ++ ++#include "link.h" ++#include "queue.h" ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++#include "wlan_typedef.h" ++ ++#include "mac.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "wlan_def.h" ++ ++#if CFG_SUPPORT_SWCR ++#include "swcr.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * .\include\nic ++ *------------------------------------------------------------------------------ ++ */ ++/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ ++#include "cmd_buf.h" ++ ++/* Dependency: mac.h (MAC_ADDR_LEN) */ ++#include "nic_cmd_event.h" ++ ++/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ ++#include "nic.h" ++ ++#include "nic_init_cmd_event.h" ++ ++#include "hif_rx.h" ++#include "hif_tx.h" ++ ++#include "nic_tx.h" ++ ++/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ ++#include "nic_rx.h" ++ ++#include "que_mgt.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "p2p_typedef.h" ++#include "p2p_cmd_buf.h" ++#include "p2p_nic_cmd_event.h" ++#include "p2p_mac.h" ++#include "p2p_nic.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * .\include\mgmt ++ *------------------------------------------------------------------------------ ++ */ ++ ++#include "hem_mbox.h" ++ ++#include "scan.h" ++#include "bss.h" ++ ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "wlan_bow.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "wlan_p2p.h" ++#endif ++ ++#include "hal.h" ++ ++#if defined(MT6620) ++#include "mt6620_reg.h" ++#elif defined(MT6628) ++/* #include "mt6628_reg.h" */ ++#include "mtreg.h" ++#endif ++ ++#include "rlm.h" ++#include "rlm_domain.h" ++#include "rlm_protection.h" ++#include "rlm_obss.h" ++#include "rate.h" ++#if CFG_SUPPORT_802_11V ++#include "wnm.h" ++#endif ++ ++#include "aa_fsm.h" ++ ++#include "cnm_timer.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#include "bow.h" ++#include "bow_fsm.h" ++#endif ++ ++#include "pwr_mgt.h" ++ ++#if (CFG_SUPPORT_STATISTICS == 1) ++#include "stats.h" ++#endif /* CFG_SUPPORT_STATISTICS */ ++ ++#include "cnm.h" ++/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ ++#include "cnm_mem.h" ++#include "cnm_scan.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "p2p_rlm_obss.h" ++#include "p2p_bss.h" ++#include "p2p.h" ++#include "p2p_fsm.h" ++#include "p2p_scan.h" ++#include "p2p_state.h" ++#include "p2p_func.h" ++#include "p2p_rlm.h" ++#include "p2p_assoc.h" ++#include "p2p_ie.h" ++#endif ++ ++#include "privacy.h" ++ ++#include "mib.h" ++ ++#include "auth.h" ++#include "assoc.h" ++ ++#if CFG_SUPPORT_ROAMING ++#include "roaming_fsm.h" ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++#include "ais_fsm.h" ++ ++#include "adapter.h" ++ ++#include "que_mgt.h" ++#include "rftest.h" ++ ++#if CFG_RSN_MIGRATION ++#include "rsn.h" ++#include "sec_fsm.h" ++#endif ++ ++#if CFG_SUPPORT_WAPI ++#include "wapi.h" ++#endif ++ ++/*------------------------------------------------------------------------------ ++ * NVRAM structure ++ *------------------------------------------------------------------------------ ++ */ ++#include "CFG_Wifi_File.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++#include "gl_p2p_kal.h" ++#endif ++ ++typedef int (*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); ++typedef void (*set_dbg_level) (unsigned char modules[DBG_MODULE_NUM]); ++ ++extern void wlanRegisterNotifier(void); ++extern void wlanUnregisterNotifier(void); ++extern void register_set_p2p_mode_handler(set_p2p_mode handler); ++extern void register_set_dbg_level_handler(set_dbg_level handler); ++ ++#if CFG_TC1_FEATURE ++#define NIC_INF_NAME_IN_AP_MODE "legacy%d" ++extern volatile int wlan_if_changed; ++#endif ++extern BOOLEAN fgIsResetting; ++ ++extern UINT_8 g_aucBufIpAddr[32]; ++extern UINT_8 aucDebugModule[]; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _PRECOMP_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h +new file mode 100644 +index 000000000000..40f52dcc9d68 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h +@@ -0,0 +1,141 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/pwr_mgt.h#1 ++*/ ++ ++/*! \file "pwr_mgt.h" ++ \brief In this file we define the STATE and EVENT for Power Management FSM. ++ ++ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter ++ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail ++ description. ++*/ ++ ++/* ++** Log: pwr_mgt.h ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL ++ * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. ++ ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * firmware download load address & start address are now configured from config.h ++ * * * due to the different configurations on FPGA and ASIC ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-10 16:39:10 GMT mtk02752 ++** disable PM macros temporally ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-29 19:48:37 GMT mtk01084 ++** temp remove power management macro ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-08 16:51:11 GMT mtk01084 ++** update for power management control macro ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-03 14:59:58 GMT mtk01426 ++** Add #if CFG_HIF_LOOPBACK_PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:53:10 GMT mtk01084 ++** modify ACQUIRE_POWER_CONTROL_FROM_PM() and RECLAIM_POWER_CONTROL_TO_PM() macro ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:32:47 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:20 GMT mtk01084 ++** Initial version ++** ++*/ ++ ++#ifndef _PWR_MGT_H ++#define _PWR_MGT_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define PM_UAPSD_AC0 (BIT(0)) ++#define PM_UAPSD_AC1 (BIT(1)) ++#define PM_UAPSD_AC2 (BIT(2)) ++#define PM_UAPSD_AC3 (BIT(3)) ++ ++#define PM_UAPSD_ALL (PM_UAPSD_AC0 | PM_UAPSD_AC1 | PM_UAPSD_AC2 | PM_UAPSD_AC3) ++#define PM_UAPSD_NONE 0 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _PM_PROFILE_SETUP_INFO_T { ++ /* Profile setup */ ++ UINT_8 ucBmpDeliveryAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ ++ UINT_8 ucBmpTriggerAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ ++ ++ UINT_8 ucUapsdSp; /* Number of triggered packets in UAPSD */ ++ ++} PM_PROFILE_SETUP_INFO_T, *P_PM_PROFILE_SETUP_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if !CFG_ENABLE_FULL_PM ++#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) ++#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) ++#else ++#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) \ ++ { \ ++ if (_prAdapter->fgIsFwOwn) { \ ++ nicpmSetDriverOwn(_prAdapter); \ ++ } \ ++ /* Increase Block to Enter Low Power Semaphore count */ \ ++ GLUE_INC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ ++ } ++ ++#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) \ ++ { \ ++ ASSERT(_prAdapter->u4PwrCtrlBlockCnt != 0); \ ++ /* Decrease Block to Enter Low Power Semaphore count */ \ ++ GLUE_DEC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ ++ if (_prAdapter->fgWiFiInSleepyState && (_prAdapter->u4PwrCtrlBlockCnt == 0)) { \ ++ nicpmSetFWOwn(_prAdapter, _fgEnableGINT_in_IST); \ ++ } \ ++ } ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _PWR_MGT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h +new file mode 100644 +index 000000000000..a9e74b58a8c9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h +@@ -0,0 +1,195 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/queue.h#1 ++*/ ++ ++/*! \file queue.h ++ \brief Definition for singly queue operations. ++ ++ In this file we define the singly queue data structure and its ++ queue operation MACROs. ++*/ ++ ++/* ++** Log: queue.h ++ * ++ * 07 16 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * bugfix for SCN migration ++ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue ++ * 2) before AIS issues scan request, network(BSS) needs to be activated first ++ * 3) only invoke COPY_SSID when using specified SSID for scan ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:46 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _QUEUE_H ++#define _QUEUE_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Singly Queue Structures - Entry Part */ ++typedef struct _QUE_ENTRY_T { ++ struct _QUE_ENTRY_T *prNext; ++ struct _QUE_ENTRY_T *prPrev; /* For Rx buffer reordering used only */ ++} QUE_ENTRY_T, *P_QUE_ENTRY_T; ++ ++/* Singly Queue Structures - Queue Part */ ++typedef struct _QUE_T { ++ P_QUE_ENTRY_T prHead; ++ P_QUE_ENTRY_T prTail; ++ UINT_32 u4NumElem; ++} QUE_T, *P_QUE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/* ++ * To resolve compiler warning of address check -Waddress ++ * Redefine a ASSERT dedicate for queue operation ++ */ ++#if DBG ++#define QUE_ASSERT ASSERT ++#else ++#define QUE_ASSERT(_exp) ++#endif ++ ++#define QUEUE_INITIALIZE(prQueue) \ ++ { \ ++ (prQueue)->prHead = (P_QUE_ENTRY_T)NULL; \ ++ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ ++ (prQueue)->u4NumElem = 0; \ ++ } ++ ++#define QUEUE_IS_EMPTY(prQueue) (((P_QUE_T)(prQueue))->prHead == (P_QUE_ENTRY_T)NULL) ++ ++#define QUEUE_IS_NOT_EMPTY(prQueue) ((prQueue)->u4NumElem > 0) ++ ++#define QUEUE_GET_HEAD(prQueue) ((prQueue)->prHead) ++ ++#define QUEUE_GET_TAIL(prQueue) ((prQueue)->prTail) ++ ++#define QUEUE_GET_NEXT_ENTRY(prQueueEntry) ((prQueueEntry)->prNext) ++ ++#define QUEUE_INSERT_HEAD(prQueue, prQueueEntry) \ ++ { \ ++ QUE_ASSERT(prQueue); \ ++ QUE_ASSERT(prQueueEntry); \ ++ (prQueueEntry)->prNext = (prQueue)->prHead; \ ++ (prQueue)->prHead = (prQueueEntry); \ ++ if ((prQueue)->prTail == (P_QUE_ENTRY_T)NULL) { \ ++ (prQueue)->prTail = (prQueueEntry); \ ++ } \ ++ ((prQueue)->u4NumElem)++; \ ++ } ++ ++#define QUEUE_INSERT_TAIL(prQueue, prQueueEntry) \ ++ { \ ++ QUE_ASSERT(prQueue); \ ++ QUE_ASSERT(prQueueEntry); \ ++ (prQueueEntry)->prNext = (P_QUE_ENTRY_T)NULL; \ ++ if ((prQueue)->prTail) { \ ++ ((prQueue)->prTail)->prNext = (prQueueEntry); \ ++ } else { \ ++ (prQueue)->prHead = (prQueueEntry); \ ++ } \ ++ (prQueue)->prTail = (prQueueEntry); \ ++ ((prQueue)->u4NumElem)++; \ ++ } ++ ++/* NOTE: We assume the queue entry located at the beginning of "prQueueEntry Type", ++ * so that we can cast the queue entry to other data type without doubts. ++ * And this macro also decrease the total entry count at the same time. ++ */ ++#define QUEUE_REMOVE_HEAD(prQueue, prQueueEntry, _P_TYPE) \ ++ { \ ++ QUE_ASSERT(prQueue); \ ++ prQueueEntry = (_P_TYPE)((prQueue)->prHead); \ ++ if (prQueueEntry) { \ ++ (prQueue)->prHead = ((P_QUE_ENTRY_T)(prQueueEntry))->prNext; \ ++ if ((prQueue)->prHead == (P_QUE_ENTRY_T)NULL) { \ ++ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ ++ } \ ++ ((P_QUE_ENTRY_T)(prQueueEntry))->prNext = (P_QUE_ENTRY_T)NULL; \ ++ ((prQueue)->u4NumElem)--; \ ++ } \ ++ } ++ ++#define QUEUE_MOVE_ALL(prDestQueue, prSrcQueue) \ ++ { \ ++ QUE_ASSERT(prDestQueue); \ ++ QUE_ASSERT(prSrcQueue); \ ++ *(P_QUE_T)prDestQueue = *(P_QUE_T)prSrcQueue; \ ++ QUEUE_INITIALIZE(prSrcQueue); \ ++ } ++ ++#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \ ++ { \ ++ QUE_ASSERT(prDestQueue); \ ++ QUE_ASSERT(prSrcQueue); \ ++ if (prSrcQueue->u4NumElem > 0) { \ ++ if ((prDestQueue)->prTail) { \ ++ ((prDestQueue)->prTail)->prNext = (prSrcQueue)->prHead; \ ++ } else { \ ++ (prDestQueue)->prHead = (prSrcQueue)->prHead; \ ++ } \ ++ (prDestQueue)->prTail = (prSrcQueue)->prTail; \ ++ ((prDestQueue)->u4NumElem) += ((prSrcQueue)->u4NumElem); \ ++ QUEUE_INITIALIZE(prSrcQueue); \ ++ } \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _QUEUE_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h +new file mode 100644 +index 000000000000..4489e5601302 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h +@@ -0,0 +1,294 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/rftest.h#1 ++*/ ++ ++/*! \file "rftest.h" ++ \brief definitions for RF Productino test ++ ++*/ ++ ++/* ++** Log: rftest.h ++ * ++ * 12 20 2011 cp.wu ++ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information ++ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO ++ * to expose version information ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-08 17:35:11 GMT mtk02752 ++** * comment out RF test which is not supported on MT6620 ++** + API decalre for rftest ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-12-08 11:29:07 GMT mtk02752 ++** definitions for RF test mode ++** ++*/ ++#ifndef _RFTEST_H ++#define _RFTEST_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Table Version */ ++#define RF_AUTO_TEST_FUNCTION_TABLE_VERSION 0x01000001 ++ ++/* Power */ ++#define RF_AT_PARAM_POWER_MASK BITS(0, 7) ++#define RF_AT_PARAM_POWER_MAX RF_AT_PARAM_POWER_MASK ++ ++/* Rate */ ++#define RF_AT_PARAM_RATE_MCS_MASK BIT(31) ++#define RF_AT_PARAM_RATE_MASK BITS(0, 7) ++#define RF_AT_PARAM_RATE_CCK_MAX 3 ++#define RF_AT_PARAM_RATE_1M 0 ++#define RF_AT_PARAM_RATE_2M 1 ++#define RF_AT_PARAM_RATE_5_5M 2 ++#define RF_AT_PARAM_RATE_11M 3 ++#define RF_AT_PARAM_RATE_6M 4 ++#define RF_AT_PARAM_RATE_9M 5 ++#define RF_AT_PARAM_RATE_12M 6 ++#define RF_AT_PARAM_RATE_18M 7 ++#define RF_AT_PARAM_RATE_24M 8 ++#define RF_AT_PARAM_RATE_36M 9 ++#define RF_AT_PARAM_RATE_48M 10 ++#define RF_AT_PARAM_RATE_54M 11 ++ ++/* Antenna */ ++#define RF_AT_PARAM_ANTENNA_ID_MASK BITS(0, 7) ++#define RF_AT_PARAM_ANTENNA_ID_MAX 1 ++ ++/* Packet Length */ ++#define RF_AT_PARAM_TX_80211HDR_BYTE_MAX (32) ++#define RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX (2048) ++ ++#define RF_AT_PARAM_TX_PKTLEN_BYTE_DEFAULT 1024 ++#define RF_AT_PARAM_TX_PKTLEN_BYTE_MAX \ ++ ((UINT_16)(RF_AT_PARAM_TX_80211HDR_BYTE_MAX + RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX)) ++ ++/* Packet Count */ ++#define RF_AT_PARAM_TX_PKTCNT_DEFAULT 1000 ++#define RF_AT_PARAM_TX_PKTCNT_UNLIMITED 0 ++ ++/* Packet Interval */ ++#define RF_AT_PARAM_TX_PKT_INTERVAL_US_DEFAULT 50 ++ ++/* ALC */ ++#define RF_AT_PARAM_ALC_DISABLE 0 ++#define RF_AT_PARAM_ALC_ENABLE 1 ++ ++/* TXOP */ ++#define RF_AT_PARAM_TXOP_DEFAULT 0 ++#define RF_AT_PARAM_TXOPQUE_QMASK BITS(16, 31) ++#define RF_AT_PARAM_TXOPQUE_TMASK BITS(0, 15) ++#define RF_AT_PARAM_TXOPQUE_AC0 (0<<16) ++#define RF_AT_PARAM_TXOPQUE_AC1 (1<<16) ++#define RF_AT_PARAM_TXOPQUE_AC2 (2<<16) ++#define RF_AT_PARAM_TXOPQUE_AC3 (3<<16) ++#define RF_AT_PARAM_TXOPQUE_AC4 (4<<16) ++#define RF_AT_PARAM_TXOPQUE_QOFFSET 16 ++ ++/* Retry Limit */ ++#define RF_AT_PARAM_TX_RETRY_DEFAULT 0 ++#define RF_AT_PARAM_TX_RETRY_MAX 6 ++ ++/* QoS Queue */ ++#define RF_AT_PARAM_QOSQUE_AC0 0 ++#define RF_AT_PARAM_QOSQUE_AC1 1 ++#define RF_AT_PARAM_QOSQUE_AC2 2 ++#define RF_AT_PARAM_QOSQUE_AC3 3 ++#define RF_AT_PARAM_QOSQUE_AC4 4 ++#define RF_AT_PARAM_QOSQUE_DEFAULT RF_AT_PARAM_QOSQUE_AC0 ++ ++/* Bandwidth */ ++#define RF_AT_PARAM_BANDWIDTH_20MHZ 0 ++#define RF_AT_PARAM_BANDWIDTH_40MHZ 1 ++#define RF_AT_PARAM_BANDWIDTH_U20_IN_40MHZ 2 ++#define RF_AT_PARAM_BANDWIDTH_D20_IN_40MHZ 3 ++#define RF_AT_PARAM_BANDWIDTH_DEFAULT RF_AT_PARAM_BANDWIDTH_20MHZ ++ ++/* GI (Guard Interval) */ ++#define RF_AT_PARAM_GI_800NS 0 ++#define RF_AT_PARAM_GI_400NS 1 ++#define RF_AT_PARAM_GI_DEFAULT RF_AT_PARAM_GI_800NS ++ ++/* STBC */ ++#define RF_AT_PARAM_STBC_DISABLE 0 ++#define RF_AT_PARAM_STBC_ENABLE 1 ++ ++/* RIFS */ ++#define RF_AT_PARAM_RIFS_DISABLE 0 ++#define RF_AT_PARAM_RIFS_ENABLE 1 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Function ID List */ ++typedef enum _ENUM_RF_AT_FUNCID_T { ++ RF_AT_FUNCID_VERSION = 0, ++ RF_AT_FUNCID_COMMAND, ++ RF_AT_FUNCID_POWER, ++ RF_AT_FUNCID_RATE, ++ RF_AT_FUNCID_PREAMBLE, ++ RF_AT_FUNCID_ANTENNA, ++ RF_AT_FUNCID_PKTLEN, ++ RF_AT_FUNCID_PKTCNT, ++ RF_AT_FUNCID_PKTINTERVAL, ++ RF_AT_FUNCID_TEMP_COMPEN, ++ RF_AT_FUNCID_TXOPLIMIT, ++ RF_AT_FUNCID_ACKPOLICY, ++ RF_AT_FUNCID_PKTCONTENT, ++ RF_AT_FUNCID_RETRYLIMIT, ++ RF_AT_FUNCID_QUEUE, ++ RF_AT_FUNCID_BANDWIDTH, ++ RF_AT_FUNCID_GI, ++ RF_AT_FUNCID_STBC, ++ RF_AT_FUNCID_CHNL_FREQ, ++ RF_AT_FUNCID_RIFS, ++ RF_AT_FUNCID_TRSW_TYPE, ++ RF_AT_FUNCID_RF_SX_SHUTDOWN, ++ RF_AT_FUNCID_PLL_SHUTDOWN, ++ RF_AT_FUNCID_SLOW_CLK_MODE, ++ RF_AT_FUNCID_ADC_CLK_MODE, ++ RF_AT_FUNCID_MEASURE_MODE, ++ RF_AT_FUNCID_VOLT_COMPEN, ++ RF_AT_FUNCID_DPD_TX_GAIN, ++ RF_AT_FUNCID_DPD_MODE, ++ RF_AT_FUNCID_TSSI_MODE, ++ RF_AT_FUNCID_TX_GAIN_CODE, ++ RF_AT_FUNCID_TX_PWR_MODE, ++ ++ /* Query command */ ++ RF_AT_FUNCID_TXED_COUNT = 32, ++ RF_AT_FUNCID_TXOK_COUNT, ++ RF_AT_FUNCID_RXOK_COUNT, ++ RF_AT_FUNCID_RXERROR_COUNT, ++ RF_AT_FUNCID_RESULT_INFO, ++ RF_AT_FUNCID_TRX_IQ_RESULT, ++ RF_AT_FUNCID_TSSI_RESULT, ++ RF_AT_FUNCID_DPD_RESULT, ++ RF_AT_FUNCID_RXV_DUMP, ++ RF_AT_FUNCID_RX_PHY_STATIS, ++ RF_AT_FUNCID_MEASURE_RESULT, ++ RF_AT_FUNCID_TEMP_SENSOR, ++ RF_AT_FUNCID_VOLT_SENSOR, ++ RF_AT_FUNCID_READ_EFUSE, ++ RF_AT_FUNCID_RX_RSSI, ++ RF_AT_FUNCID_FW_INFO, ++ RF_AT_FUNCID_DRV_INFO, ++ ++ /* Set command */ ++ RF_AT_FUNCID_SET_DPD_RESULT = 64, ++ RF_AT_FUNCID_SET_CW_MODE, ++ RF_AT_FUNCID_SET_JAPAN_CH14_FILTER, ++ RF_AT_FUNCID_WRITE_EFUSE, ++ RF_AT_FUNCID_SET_MAC_ADDRESS ++} ENUM_RF_AT_FUNCID_T; ++ ++/* Command */ ++typedef enum _ENUM_RF_AT_COMMAND_T { ++ RF_AT_COMMAND_STOPTEST = 0, ++ RF_AT_COMMAND_STARTTX, ++ RF_AT_COMMAND_STARTRX, ++ RF_AT_COMMAND_RESET, ++ RF_AT_COMMAND_OUTPUT_POWER, /* Payload */ ++ RF_AT_COMMAND_LO_LEAKAGE, /* Local freq is renamed to Local leakage */ ++ RF_AT_COMMAND_CARRIER_SUPPR, /* OFDM (LTF/STF), CCK (PI,PI/2) */ ++ RF_AT_COMMAND_TRX_IQ_CAL, ++ RF_AT_COMMAND_TSSI_CAL, ++ RF_AT_COMMAND_DPD_CAL, ++ RF_AT_COMMAND_CW, ++ RF_AT_COMMAND_NUM ++} ENUM_RF_AT_COMMAND_T; ++ ++/* Preamble */ ++typedef enum _ENUM_RF_AT_PREAMBLE_T { ++ RF_AT_PREAMBLE_NORMAL = 0, ++ RF_AT_PREAMBLE_CCK_SHORT, ++ RF_AT_PREAMBLE_11N_MM, ++ RF_AT_PREAMBLE_11N_GF, ++ RF_AT_PREAMBLE_NUM ++} ENUM_RF_AT_PREAMBLE_T; ++ ++/* Ack Policy */ ++typedef enum _ENUM_RF_AT_ACK_POLICY_T { ++ RF_AT_ACK_POLICY_NORMAL = 0, ++ RF_AT_ACK_POLICY_NOACK, ++ RF_AT_ACK_POLICY_NOEXPLICTACK, ++ RF_AT_ACK_POLICY_BLOCKACK, ++ RF_AT_ACK_POLICY_NUM ++} ENUM_RF_AT_ACK_POLICY_T; ++ ++typedef enum _ENUM_RF_AUTOTEST_STATE_T { ++ RF_AUTOTEST_STATE_STANDBY = 0, ++ RF_AUTOTEST_STATE_TX, ++ RF_AUTOTEST_STATE_RX, ++ RF_AUTOTEST_STATE_RESET, ++ RF_AUTOTEST_STATE_OUTPUT_POWER, ++ RF_AUTOTEST_STATE_LOCA_FREQUENCY, ++ RF_AUTOTEST_STATE_CARRIER_SUPRRESION, ++ RF_AUTOTEST_STATE_NUM ++} ENUM_RF_AUTOTEST_STATE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData); ++ ++WLAN_STATUS ++rftestQueryATInfo(IN P_ADAPTER_T prAdapter, ++ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); ++ ++WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen); ++ ++#endif /* _RFTEST_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h +new file mode 100644 +index 000000000000..8ee184591fc2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h +@@ -0,0 +1,427 @@ ++/* ++** Id: include/tdls_extr.h#1 ++*/ ++ ++/*! \file "tdls_extr.h" ++ \brief This file contains the external used in other modules ++ for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: tdls_extr.h ++ * ++ * 11 18 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ * ++ ** ++ */ ++ ++#ifndef _TDLS_EXTR_H ++#define _TDLS_EXTR_H ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#define TDLS_TX_QUOTA_EMPTY_TIMEOUT 10 ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* protocol */ ++#define TDLS_FRM_PROT_TYPE 0x890d ++ ++/* TDLS uses Ethertype 89-0d frames. The UP shall be AC_VI, unless otherwise specified. */ ++#define USER_PRIORITY_TDLS 5 ++ ++/* Status code */ ++#define TDLS_STATUS WLAN_STATUS ++ ++#define TDLS_STATUS_SUCCESS WLAN_STATUS_SUCCESS ++#define TDLS_STATUS_FAILURE WLAN_STATUS_FAILURE ++#define TDLS_STATUS_INVALID_LENGTH WLAN_STATUS_INVALID_LENGTH ++#define TDLS_STATUS_RESOURCES WLAN_STATUS_RESOURCES ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#define TDLS_U32 UINT32 ++#define TDLS_U16 UINT16 ++#define TDLS_U8 UINT8 ++ ++typedef enum _TDLS_REASON_CODE { ++ TDLS_REASON_CODE_UNREACHABLE = 25, ++ TDLS_REASON_CODE_UNSPECIFIED = 26, ++ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN = 0x80, /* 128 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WIFI_OFF = 0x81, /* 129 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING = 0x82, /* 130 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT = 0x83, /* 131 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT = 0x84, /* 132 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY = 0x85, /* 133 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL = 0x86, /* 134 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL = 0x87, /* 135 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX = 0x88, /* 136 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3 = 0x89, /* 137 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY = 0x8a, /* 138 */ ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN = 0x8b /* 139 */ ++} TDLS_REASON_CODE; ++ ++/* TDLS FSM */ ++typedef struct _TDLS_CMD_PEER_ADD_T { ++ ++ TDLS_U8 aucPeerMac[6]; ++ ++#if 0 ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ UINT_16 u2CapInfo; ++ ++ UINT_16 u2OperationalRateSet; ++ UINT_16 u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ ++ UINT_8 ucPhyTypeSet; ++#endif ++} TDLS_CMD_PEER_ADD_T; ++ ++typedef struct _TDLS_CMD_LINK_T { ++ ++ TDLS_U8 aucPeerMac[6]; ++ BOOLEAN fgIsEnabled; ++} TDLS_CMD_LINK_T; ++ ++typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T { ++ TDLS_U8 arRxMask[10]; ++ TDLS_U16 u2RxHighest; ++ TDLS_U8 ucTxParams; ++ TDLS_U8 Reserved[3]; ++} TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T; ++ ++typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_T { ++ TDLS_U16 u2CapInfo; ++ TDLS_U8 ucAmpduParamsInfo; ++ ++ /* 16 bytes MCS information */ ++ TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T rMCS; ++ ++ TDLS_U16 u2ExtHtCapInfo; ++ TDLS_U32 u4TxBfCapInfo; ++ TDLS_U8 ucAntennaSelInfo; ++} TDLS_CMD_PEER_UPDATE_HT_CAP_T; ++ ++typedef struct _TDLS_CMD_PEER_UPDATE_T { ++ ++ TDLS_U8 aucPeerMac[6]; ++ ++#define TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX 50 ++ TDLS_U8 aucSupChan[TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX]; ++ ++ TDLS_U16 u2StatusCode; ++ ++#define TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX 50 ++ TDLS_U8 aucSupRate[TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX]; ++ TDLS_U16 u2SupRateLen; ++ ++ TDLS_U8 UapsdBitmap; ++ TDLS_U8 UapsdMaxSp; /* MAX_SP */ ++ ++ TDLS_U16 u2Capability; ++#define TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN 5 ++ TDLS_U8 aucExtCap[TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN]; ++ TDLS_U16 u2ExtCapLen; ++ ++ TDLS_CMD_PEER_UPDATE_HT_CAP_T rHtCap; ++ BOOLEAN fgIsSupHt; ++ ++} TDLS_CMD_PEER_UPDATE_T; ++ ++/* Command to TDLS core module */ ++typedef enum _TDLS_CMD_CORE_ID { ++ TDLS_CORE_CMD_TEST_NULL_RCV = 0x00, ++ TDLS_CORE_CMD_TEST_PTI_RSP = 0x01, ++ TDLS_CORE_CMD_MIB_UPDATE = 0x02, ++ TDLS_CORE_CMD_TEST_TX_FAIL_SKIP = 0x03, ++ TDLS_CORE_CMD_UAPSD_CONF = 0x04, ++ TDLS_CORE_CMD_TEST_DATA_RCV = 0x05, ++ TDLS_CORE_CMD_TEST_PTI_REQ = 0x06, ++ TDLS_CORE_CMD_TEST_CHSW_REQ = 0x07, ++ TDLS_CORE_CMD_CHSW_CONF = 0x08, ++ TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP = 0x09, ++ TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP = 0x0a, ++ TDLS_CORE_CMD_TEST_CHSW_RSP = 0x0b, ++ TDLS_CORE_CMD_TEST_SCAN_SKIP = 0x0c, ++ TDLS_CORE_CMD_SETUP_CONF = 0x0d, ++ TDLS_CORE_CMD_TEST_TEAR_DOWN = 0x0e, ++ TDLS_CORE_CMD_KEY_INFO = 0x0f, ++ TDLS_CORE_CMD_TEST_PTI_TX_FAIL = 0x10 ++} TDLS_CMD_CORE_ID; ++ ++typedef struct _TDLS_CMD_CORE_TEST_NULL_RCV_T { ++ ++ TDLS_U32 u4PM; ++} TDLS_CMD_CORE_TEST_NULL_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T { ++ ++ TDLS_U32 u4DialogToken; ++} TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T { ++ ++ TDLS_U32 u4DialogToken; ++ TDLS_U32 u4PM; ++} TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T { ++ ++ TDLS_U32 u4ReasonCode; ++} TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T { ++ ++ TDLS_U32 u4Chan; ++ TDLS_U32 u4RegClass; ++ TDLS_U32 u4SecChanOff; ++ TDLS_U32 u4SwitchTime; ++ TDLS_U32 u4SwitchTimeout; ++} TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T { ++ ++ TDLS_U32 u4Chan; ++ TDLS_U32 u4SwitchTime; ++ TDLS_U32 u4SwitchTimeout; ++ TDLS_U32 u4StatusCode; ++} TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_DATA_RCV_T { ++ ++ TDLS_U32 u4PM; ++ TDLS_U32 u4UP; ++ TDLS_U32 u4EOSP; ++ TDLS_U32 u4IsNull; ++} TDLS_CMD_CORE_TEST_DATA_RCV_T; ++ ++typedef struct _TDLS_CMD_CORE_MIB_PARAM_UPDATE_T { ++ ++ BOOLEAN Tdlsdot11TunneledDirectLinkSetupImplemented; ++ BOOLEAN Tdlsdot11TDLSPeerUAPSDBufferSTAActivated; ++ BOOLEAN Tdlsdot11TDLSPeerPSMActivated; ++ TDLS_U16 Tdlsdot11TDLSPeerUAPSDIndicationWindow; ++ BOOLEAN Tdlsdot11TDLSChannelSwitchingActivated; ++ TDLS_U8 Tdlsdot11TDLSPeerSTAMissingAckRetryLimit; ++ TDLS_U8 Tdlsdot11TDLSResponseTimeout; ++ TDLS_U16 Tdlsdot11TDLSProbeDelay; ++ TDLS_U8 Tdlsdot11TDLSDiscoveryRequestWindow; ++ TDLS_U8 Tdlsdot11TDLSACDeterminationInterval; ++} TDLS_CMD_CORE_MIB_PARAM_UPDATE_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_UAPSD_CONFIG_T { ++ ++ BOOLEAN fgIsSpTimeoutSkip; ++ BOOLEAN fgIsPtiTimeoutSkip; ++} TDLS_CMD_CORE_UAPSD_CONFIG_T; ++ ++typedef struct _TDLS_CMD_CORE_SETUP_CONFIG_T { ++ ++ BOOLEAN fgIs2040Supported; ++} TDLS_CMD_CORE_SETUP_CONFIG_T; ++ ++typedef struct _TDLS_CMD_CORE_CHSW_CONFIG_T { ++ ++ TDLS_U8 ucNetTypeIndex; ++ BOOLEAN fgIsChSwEnabled; ++ BOOLEAN fgIsChSwStarted; ++ TDLS_U8 ucRegClass; ++ TDLS_U8 ucTargetChan; ++ TDLS_U8 ucSecChanOff; ++ BOOLEAN fgIsChSwRegular; ++} TDLS_CMD_CORE_CHSW_CONFIG_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PROHIBIT_T { ++ ++ BOOLEAN fgIsEnable; ++ BOOLEAN fgIsSet; ++} TDLS_CMD_CORE_TEST_PROHIBIT_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_SCAN_SKIP_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_SCAN_SKIP_T; ++ ++typedef struct _TDLS_CMD_CORE_INFO_DISPLAY_T { ++ ++ BOOLEAN fgIsToClearAllHistory; ++} TDLS_CMD_CORE_INFO_DISPLAY_T; ++ ++typedef struct _TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T { ++ ++ BOOLEAN fgIsEnable; ++} TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T; ++ ++typedef struct _TDLS_CMD_CORE_T { ++ ++ TDLS_U32 u4Command; /* TDLS_CMD_CORE_ID */ ++ ++ TDLS_U8 aucPeerMac[6]; ++ TDLS_U8 ucNetTypeIndex; ++ ++#define TDLS_CMD_CORE_RESERVED_SIZE 50 ++ union { ++ TDLS_CMD_CORE_TEST_NULL_RCV_T rCmdNullRcv; ++ TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T rCmdPtiReqRcv; ++ TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T rCmdPtiRspRcv; ++ TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T rCmdTearDownRcv; ++ TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T rCmdChStReqRcv; ++ TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T rCmdChStRspRcv; ++ TDLS_CMD_CORE_TEST_DATA_RCV_T rCmdDatRcv; ++ TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T rCmdTxFailSkip; ++ TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T rCmdKeepAliveSkip; ++ TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T rCmdChSwTimeoutSkip; ++ TDLS_CMD_CORE_TEST_PROHIBIT_T rCmdProhibit; ++ TDLS_CMD_CORE_TEST_SCAN_SKIP_T rCmdScanSkip; ++ TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T rCmdPtiTxFail; ++ ++ TDLS_CMD_CORE_MIB_PARAM_UPDATE_T rCmdMibUpdate; ++ TDLS_CMD_CORE_UAPSD_CONFIG_T rCmdUapsdConf; ++ TDLS_CMD_CORE_CHSW_CONFIG_T rCmdChSwConf; ++ TDLS_CMD_CORE_SETUP_CONFIG_T rCmdSetupConf; ++ TDLS_CMD_CORE_INFO_DISPLAY_T rCmdInfoDisplay; ++ TDLS_U8 Reserved[TDLS_CMD_CORE_RESERVED_SIZE]; ++ } Content; ++} TDLS_CMD_CORE_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* ++ assign station record idx for the packet only when STA_STATE_3 ++ Or we will try to send data frame when the TDLS peer's state is STA_STATE_1 ++ EX: ++ 1. mtk_cfg80211_add_station: First create the STA_RECORD_T; ++ 2. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. ++ 3. mtk_cfg80211_add_station: Change state to STA_STATE_1. ++ 4. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. ++*/ ++#define TDLSEX_STA_REC_IDX_GET(__prAdapter__, __MsduInfo__) \ ++{ \ ++ STA_RECORD_T *__StaRec__; \ ++ __MsduInfo__->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; \ ++ __StaRec__ = cnmGetStaRecByAddress(__prAdapter__, \ ++ (UINT_8) NETWORK_TYPE_AIS_INDEX, \ ++ __MsduInfo__->aucEthDestAddr); \ ++ if ((__StaRec__ != NULL) && \ ++ ((__StaRec__)->ucStaState == STA_STATE_3) && \ ++ (IS_TDLS_STA(__StaRec__))) { \ ++ __MsduInfo__->ucStaRecIndex = __StaRec__->ucIndex; \ ++ } \ ++} ++ ++/* fill wiphy flag */ ++#define TDLSEX_WIPHY_FLAGS_INIT(__fgFlag__)\ ++{ \ ++ __fgFlag__ |= (WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP);\ ++} ++ ++/* assign user priority of a TDLS action frame */ ++/* ++ According to 802.11z: Setup req/resp are sent in AC_BK, otherwise we should default ++ to AC_VI. ++*/ ++#define TDLSEX_UP_ASSIGN(__UserPriority__) \ ++{ \ ++ __UserPriority__ = USER_PRIORITY_TDLS; \ ++} ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++int ++TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, u8 action_code, u8 dialog_token, ++ u16 status_code, u32 peer_capability, ++ bool initiator, const u8 *buf, size_t len); ++ ++int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, enum nl80211_tdls_operation oper); ++ ++VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE); ++ ++VOID TdlsexEventHandle(P_GLUE_INFO_T prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey); ++ ++VOID TdlsexInit(ADAPTER_T *prAdapter); ++ ++BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter); ++ ++TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++VOID ++TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode); ++ ++TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++TDLS_STATUS TdlsexPeerAdd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); ++ ++TDLS_STATUS TdlsexPeerUpdate(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); ++ ++BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt); ++ ++VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen); ++ ++TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo); ++ ++VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota); ++ ++VOID TdlsexUninit(ADAPTER_T *prAdapter); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#endif /* _TDLS_EXTR_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h +new file mode 100644 +index 000000000000..7ab62dae8813 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h +@@ -0,0 +1,244 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/typedef.h#1 ++*/ ++ ++/*! \file typedef.h ++ \brief Declaration of data type and return values of internal protocol stack. ++ ++ In this file we declare the data type and return values which will be exported ++ to the GLUE Layer. ++*/ ++ ++/* ++** Log: typedef.h ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * host driver not to set FW-own when there is still pending interrupts ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add necessary changes to driver data paths. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add definitions for module migration. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move timer callback to glue layer. ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add Ethernet destination address information in packet info for TX ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:41:37 GMT mtk01461 ++** Update PACKET_INFO_INIT for TX Path ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:30:17 GMT mtk01461 ++** Add parameter in PACKET_INFO_T for HIF Loopback ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:22 GMT mtk01461 ++** Fix LINT warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:28 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:54 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _TYPEDEF_H ++#define _TYPEDEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/* ieee80211.h of linux has duplicated definitions */ ++#if defined(WLAN_STATUS_SUCCESS) ++#undef WLAN_STATUS_SUCCESS ++#endif ++ ++#define WLAN_STATUS_SUCCESS ((WLAN_STATUS) 0x00000000L) ++#define WLAN_STATUS_PENDING ((WLAN_STATUS) 0x00000103L) ++#define WLAN_STATUS_NOT_ACCEPTED ((WLAN_STATUS) 0x00010003L) ++ ++#define WLAN_STATUS_MEDIA_CONNECT ((WLAN_STATUS) 0x4001000BL) ++#define WLAN_STATUS_MEDIA_DISCONNECT ((WLAN_STATUS) 0x4001000CL) ++#define WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ((WLAN_STATUS) 0x4001000DL) ++ ++#define WLAN_STATUS_MEDIA_SPECIFIC_INDICATION ((WLAN_STATUS) 0x40010012L) ++ ++#define WLAN_STATUS_SCAN_COMPLETE ((WLAN_STATUS) 0x60010001L) ++#define WLAN_STATUS_MSDU_OK ((WLAN_STATUS) 0x60010002L) ++ ++/* TODO(Kevin): double check if 0x60010001 & 0x60010002 is proprietary */ ++#define WLAN_STATUS_ROAM_OUT_FIND_BEST ((WLAN_STATUS) 0x60010101L) ++#define WLAN_STATUS_ROAM_DISCOVERY ((WLAN_STATUS) 0x60010102L) ++ ++#define WLAN_STATUS_FAILURE ((WLAN_STATUS) 0xC0000001L) ++#define WLAN_STATUS_RESOURCES ((WLAN_STATUS) 0xC000009AL) ++#define WLAN_STATUS_NOT_SUPPORTED ((WLAN_STATUS) 0xC00000BBL) ++ ++#define WLAN_STATUS_MULTICAST_FULL ((WLAN_STATUS) 0xC0010009L) ++#define WLAN_STATUS_INVALID_PACKET ((WLAN_STATUS) 0xC001000FL) ++#define WLAN_STATUS_ADAPTER_NOT_READY ((WLAN_STATUS) 0xC0010011L) ++#define WLAN_STATUS_NOT_INDICATING ((WLAN_STATUS) 0xC0010013L) ++#define WLAN_STATUS_INVALID_LENGTH ((WLAN_STATUS) 0xC0010014L) ++#define WLAN_STATUS_INVALID_DATA ((WLAN_STATUS) 0xC0010015L) ++#define WLAN_STATUS_BUFFER_TOO_SHORT ((WLAN_STATUS) 0xC0010016L) ++ ++#define WLAN_STATUS_BWCS_UPDATE ((WLAN_STATUS) 0xC0010017L) ++ ++#define WLAN_STATUS_CONNECT_INDICATION ((WLAN_STATUS) 0xC0010018L) ++ ++/* NIC status flags */ ++#define ADAPTER_FLAG_HW_ERR 0x00400000 ++ ++/* Type Length */ ++#define TL_IPV4 0x0008 ++#define TL_IPV6 0xDD86 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Type definition for GLUE_INFO structure */ ++typedef struct _GLUE_INFO_T GLUE_INFO_T, *P_GLUE_INFO_T; ++ ++/* Type definition for WLAN STATUS */ ++typedef UINT_32 WLAN_STATUS, *P_WLAN_STATUS; ++ ++/* Type definition for ADAPTER structure */ ++typedef struct _ADAPTER_T ADAPTER_T, *P_ADAPTER_T; ++ ++/* Type definition for MESSAGE HEADER structure */ ++typedef struct _MSG_HDR_T MSG_HDR_T, *P_MSG_HDR_T; ++ ++/* Type definition for WLAN configuration */ ++typedef struct _WLAN_CFG_T WLAN_CFG_T, *P_WLAN_CFG_T; ++ ++/* Type definition for WLAN configuration entry */ ++typedef struct _WLAN_CFG_ENTRY_T WLAN_CFG_ENTRY_T, *P_WLAN_CFG_ENTRY_T; ++ ++/* Type definition for WLAN configuration callback */ ++typedef WLAN_STATUS(*WLAN_CFG_SET_CB) (P_ADAPTER_T prAdapter, ++ PUINT_8 pucKey, PUINT_8 pucValue, PVOID pPrivate, UINT_32 u4Flags); ++ ++/* Type definition for Pointer to OS Native Packet */ ++typedef void *P_NATIVE_PACKET; ++ ++/* Type definition for STA_RECORD_T structure to handle the connectivity and packet reception ++ * for a particular STA. ++ */ ++typedef struct _STA_RECORD_T STA_RECORD_T, *P_STA_RECORD_T, **PP_STA_RECORD_T; ++ ++/* CMD_INFO_T is used by Glue Layer to send a cluster of Command(OID) information to ++ * the TX Path to reduce the parameters of a function call. ++ */ ++typedef struct _CMD_INFO_T CMD_INFO_T, *P_CMD_INFO_T; ++ ++/* Following typedef should be removed later, because Glue Layer should not ++ * be aware of following data type. ++ */ ++typedef struct _SW_RFB_T SW_RFB_T, *P_SW_RFB_T, **PP_SW_RFB_T; ++ ++typedef struct _MSDU_INFO_T MSDU_INFO_T, *P_MSDU_INFO_T; ++ ++typedef struct _REG_ENTRY_T REG_ENTRY_T, *P_REG_ENTRY_T; ++ ++/* IST handler definition */ ++typedef VOID(*IST_EVENT_FUNCTION) (P_ADAPTER_T); ++ ++/* Type definition for function pointer of timer handler */ ++typedef VOID(*PFN_TIMER_CALLBACK) (IN P_GLUE_INFO_T); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h +new file mode 100644 +index 000000000000..e8937166dc4f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h +@@ -0,0 +1,352 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_bow.h#1 ++*/ ++ ++/*! \file "wlan_bow.h" ++ \brief This file contains the declairations of 802.11 PAL ++ command processing routines for ++ MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_bow.h ++ * ++ * 05 25 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add BoW Cancel Scan Request and Turn On deactive network function. ++ * ++ * 05 23 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Add some BoW error handling. ++ * ++ * 05 21 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Protect BoW connection establishment. ++ * ++ * 05 17 2011 terry.wu ++ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting ++ * Send deauth while disconnecting BoW link. ++ * ++ * 05 06 2011 terry.wu ++ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue ++ * Fix BoW Multiple Physical Link connect/disconnect issue. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW table. ++ * ++ * 02 16 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update bowString and channel grant. ++ * ++ * 01 11 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update BOW Activity Report structure and bug fix. ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Add bowRunEventAAAComplete. ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * 1) all BT physical handles shares the same RSSI/Link Quality. ++ * 2) simplify BT command composing ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++** ++*/ ++ ++#ifndef _WLAN_BOW_H ++#define _WLAN_BOW_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "nic/bow.h" ++#include "nic/cmd_buf.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++#if CFG_BOW_TEST ++extern UINT_32 g_arBowRevPalPacketTime[32]; ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define BOWCMD_STATUS_SUCCESS 0 ++#define BOWCMD_STATUS_FAILURE 1 ++#define BOWCMD_STATUS_UNACCEPTED 2 ++#define BOWCMD_STATUS_INVALID 3 ++#define BOWCMD_STATUS_TIMEOUT 4 ++ ++#define BOW_WILDCARD_SSID "AMP" ++#define BOW_WILDCARD_SSID_LEN 3 ++#define BOW_SSID_LEN 21 ++ ++ /* 0: query, 1: setup, 2: destroy */ ++#define BOW_QUERY_CMD 0 ++#define BOW_SETUP_CMD 1 ++#define BOW_DESTROY_CMD 2 ++ ++#define BOW_INITIATOR 0 ++#define BOW_RESPONDER 1 ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++typedef struct _BOW_TABLE_T { ++ UINT_8 ucAcquireID; ++ BOOLEAN fgIsValid; ++ ENUM_BOW_DEVICE_STATE eState; ++ UINT_8 aucPeerAddress[6]; ++ /* UINT_8 ucRole; */ ++ /* UINT_8 ucChannelNum; */ ++ UINT_16 u2Reserved; ++} BOW_TABLE_T, *P_BOW_TABLE_T; ++ ++typedef WLAN_STATUS(*PFN_BOW_CMD_HANDLE) (P_ADAPTER_T, P_AMPC_COMMAND); ++ ++typedef struct _BOW_CMD_T { ++ UINT_8 uCmdID; ++ PFN_BOW_CMD_HANDLE pfCmdHandle; ++} BOW_CMD_T, *P_BOW_CMD_T; ++ ++typedef struct _BOW_EVENT_ACTIVITY_REPORT_T { ++ UINT_8 ucReason; ++ UINT_8 aucReserved; ++ UINT_8 aucPeerAddress[6]; ++} BOW_EVENT_ACTIVITY_REPORT_T, *P_BOW_EVENT_ACTIVITY_REPORT_T; ++ ++/* ++ucReason: 0: success ++ 1: general failure ++ 2: too much time (> 2/3 second totally) requested for scheduling. ++ Others: reserved. ++*/ ++ ++typedef struct _BOW_EVENT_SYNC_TSF_T { ++ UINT_64 u4TsfTime; ++ UINT_32 u4TsfSysTime; ++ UINT_32 u4ScoTime; ++ UINT_32 u4ScoSysTime; ++} BOW_EVENT_SYNC_TSF_T, *P_BOW_EVENT_SYNC_TSF_T; ++ ++typedef struct _BOW_ACTIVITY_REPORT_BODY_T { ++ UINT_32 u4StartTime; ++ UINT_32 u4Duration; ++ UINT_32 u4Periodicity; ++} BOW_ACTIVITY_REPORT_BODY_T, *P_BOW_ACTIVITY_REPORT_BODY_T; ++ ++typedef struct _BOW_ACTIVITY_REPORT_T { ++ UINT_8 aucPeerAddress[6]; ++ UINT_8 ucScheduleKnown; ++ UINT_8 ucNumReports; ++ BOW_ACTIVITY_REPORT_BODY_T arBowActivityReportBody[MAX_ACTIVITY_REPORT]; ++} BOW_ACTIVITY_REPORT_T, *P_BOW_ACTIVITY_REPORT_T; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*--------------------------------------------------------------*/ ++/* Firmware Command Packer */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucCID, ++ BOOLEAN fgSetQuery, ++ BOOLEAN fgNeedResp, ++ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, ++ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, ++ UINT_32 u4SetQueryInfoLen, PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber); ++ ++/*--------------------------------------------------------------*/ ++/* Command Dispatcher */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++/*--------------------------------------------------------------*/ ++/* Routines to handle command */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); ++ ++VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf); ++ ++/*--------------------------------------------------------------*/ ++/* Callbacks for event indication */ ++/*--------------------------------------------------------------*/ ++VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID bowStopping(IN P_ADAPTER_T prAdapter); ++ ++VOID bowStarting(IN P_ADAPTER_T prAdapter); ++ ++VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); ++ ++BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); ++ ++VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++ ++VOID bowResponderScan(IN P_ADAPTER_T prAdapter); ++ ++VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention); ++ ++VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); ++ ++VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID ++bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); ++ ++VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); ++ ++WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); ++ ++VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); ++ ++BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); ++ ++BOOLEAN ++bowValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); ++ ++VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); ++ ++VOID bowRequestCh(IN P_ADAPTER_T prAdapter); ++ ++VOID bowReleaseCh(IN P_ADAPTER_T prAdapter); ++ ++VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam); ++ ++BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); ++ ++BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable); ++ ++BOOLEAN ++bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx); ++ ++BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx); ++ ++ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); ++ ++BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState); ++ ++BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif ++#endif /* _WLAN_BOW_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h +new file mode 100644 +index 000000000000..87259397a93d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h +@@ -0,0 +1,1001 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_lib.h#1 ++*/ ++ ++/*! \file "wlan_lib.h" ++ \brief The declaration of the functions of the wlanAdpater objects ++ ++ Detail description. ++*/ ++ ++/* ++** Log: wlan_lib.h ++ * ++ * 06 08 2012 eason.tsai ++ * NULL ++ * Nvram context covert from 6620 to 6628 for old 6620 meta tool ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for ++ * preferred band configuration with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for ++ * setting preferred band configuration corresponding to network type. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * eliminate win32 native data types. ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 10 03 2011 cp.wu ++ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware downloading aggregated path. ++ * ++ * 09 20 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * change window registry of driver for roaming. ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 25 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add DFS switch. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, ++ * TX deauth to a disconnecting device issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 22 2011 jeffrey.chang ++ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time ++ * modify driver to set OSC stable time after f/w download ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 04 18 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * 1) add API for glue layer to query ACPI state ++ * 2) Windows glue should not access to hardware after switched into D3 state ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Support current measure mode, assigned by registry (XP only). ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result ++ * in OID handling layer when the corresponding BSS is disconnected due to beacon timeout ++ * remove from scanning result when the BSS is disconnected due to beacon timeout. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to ++ * disable Beacon Timeout function for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature ++ * Modify online scan as a run-time adjustable option (for Windows, in registry) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add AT GO test configure mode under WinXP. ++ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * . ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid ++ * descriptor underflow under concurrent network operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * simplify timer usage. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add extra 64 adjustable parameters for CoEX scenario. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * * 2) add 2 kal API for later integration ++ * ++ * 04 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change to use WIFI_TCM_ALWAYS_ON as firmware image ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always send CMD_NIC_POWER_CTRL packet when nic is being halted ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add two option for ACK and ENCRYPTION for firmware download ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * separate wlanProcesQueuePacket() into 2 APIs upon request ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add new API: wlanProcessQueuedPackets() ++ * ++ * 02 11 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. add logic for firmware download ++ * * * 2. firmware image filename and start/load address are now retrieved from registry ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * * 4) nicRxWaitResponse() revised ++ * * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * * 4. correct some HAL implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:39:55 GMT mtk02752 ++** eliminate unused API ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:58:41 GMT mtk01084 ++** update for new macro define ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-19 10:43:06 GMT mtk01461 ++** Add wlanReleasePendingOid() ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-13 16:38:44 GMT mtk01084 ++** add WIFI start function ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-08 16:51:14 GMT mtk01084 ++** Update for the image download part ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:57:38 GMT mtk01461 ++** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:31:02 GMT mtk01461 ++** Add declaration of FW Image download reference code ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:31 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:04 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _WLAN_LIB_H ++#define _WLAN_LIB_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "CFG_Wifi_File.h" ++#include "rlm_domain.h" ++#include "wlan_typedef.h" ++ ++ ++extern BOOLEAN fgIsResetting; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define MAX_NUM_GROUP_ADDR 32 /* max number of group addresses */ ++ ++#define TX_CS_TCP_UDP_GEN BIT(1) ++#define TX_CS_IP_GEN BIT(0) ++ ++#define CSUM_OFFLOAD_EN_TX_TCP BIT(0) ++#define CSUM_OFFLOAD_EN_TX_UDP BIT(1) ++#define CSUM_OFFLOAD_EN_TX_IP BIT(2) ++#define CSUM_OFFLOAD_EN_RX_TCP BIT(3) ++#define CSUM_OFFLOAD_EN_RX_UDP BIT(4) ++#define CSUM_OFFLOAD_EN_RX_IPv4 BIT(5) ++#define CSUM_OFFLOAD_EN_RX_IPv6 BIT(6) ++#define CSUM_OFFLOAD_EN_TX_MASK BITS(0, 2) ++#define CSUM_OFFLOAD_EN_ALL BITS(0, 6) ++ ++/* TCP, UDP, IP Checksum */ ++#define RX_CS_TYPE_UDP BIT(7) ++#define RX_CS_TYPE_TCP BIT(6) ++#define RX_CS_TYPE_IPv6 BIT(5) ++#define RX_CS_TYPE_IPv4 BIT(4) ++ ++#define RX_CS_STATUS_UDP BIT(3) ++#define RX_CS_STATUS_TCP BIT(2) ++#define RX_CS_STATUS_IP BIT(0) ++ ++#define CSUM_NOT_SUPPORTED 0x0 ++ ++#define TXPWR_USE_PDSLOPE 0 ++ ++/* NVRAM error code definitions */ ++#define NVRAM_ERROR_VERSION_MISMATCH BIT(1) ++#define NVRAM_ERROR_INVALID_TXPWR BIT(2) ++#define NVRAM_ERROR_INVALID_DPD BIT(3) ++#define NVRAM_ERROR_INVALID_MAC_ADDR BIT(4) ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++#define NVRAM_POWER_LIMIT_TABLE_INVALID BIT(5) ++#endif ++ ++#define NUM_TC_RESOURCE_TO_STATISTICS 4 ++ ++#define WLAN_CFG_ARGV_MAX 8 ++#define WLAN_CFG_ENTRY_NUM_MAX 128 ++#define WLAN_CFG_KEY_LEN_MAX 32 /* include \x00 EOL */ ++#define WLAN_CFG_VALUE_LEN_MAX 32 /* include \x00 EOL */ ++#define WLAN_CFG_FLAG_SKIP_CB BIT(0) ++#define WLAN_CFG_FILE_BUF_SIZE 2048 ++ ++#define WLAN_CFG_SET_CHIP_LEN_MAX 10 ++#define WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX 10 ++#define WLAN_CFG_SET_SW_CTRL_LEN_MAX 10 ++ ++#define WLAN_OID_TIMEOUT_THRESHOLD 2000 /* OID timeout (in ms) */ ++#define WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING 300 /* OID timeout during chip-resetting (in ms) */ ++ ++#define WLAN_OID_NO_ACK_THRESHOLD 3 ++ ++#define WLAN_TX_THREAD_TASK_PRIORITY 0 /* If not setting the priority, 0 is the default */ ++#define WLAN_TX_THREAD_TASK_NICE (-10) /* If not setting the nice, -10 is the default */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC) (IN P_ADAPTER_T prAdapter, ++ IN PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); ++ ++typedef enum _ENUM_CSUM_TYPE_T { ++ CSUM_TYPE_IPV4, ++ CSUM_TYPE_IPV6, ++ CSUM_TYPE_TCP, ++ CSUM_TYPE_UDP, ++ CSUM_TYPE_NUM ++} ENUM_CSUM_TYPE_T, *P_ENUM_CSUM_TYPE_T; ++ ++typedef enum _ENUM_CSUM_RESULT_T { ++ CSUM_RES_NONE, ++ CSUM_RES_SUCCESS, ++ CSUM_RES_FAILED, ++ CSUM_RES_NUM ++} ENUM_CSUM_RESULT_T, *P_ENUM_CSUM_RESULT_T; ++ ++typedef enum _ENUM_PHY_MODE_T { ++ ENUM_PHY_2G4_CCK, ++ ENUM_PHY_2G4_OFDM_BPSK, ++ ENUM_PHY_2G4_OFDM_QPSK, ++ ENUM_PHY_2G4_OFDM_16QAM, ++ ENUM_PHY_2G4_OFDM_48M, ++ ENUM_PHY_2G4_OFDM_54M, ++ ENUM_PHY_2G4_HT20_BPSK, ++ ENUM_PHY_2G4_HT20_QPSK, ++ ENUM_PHY_2G4_HT20_16QAM, ++ ENUM_PHY_2G4_HT20_MCS5, ++ ENUM_PHY_2G4_HT20_MCS6, ++ ENUM_PHY_2G4_HT20_MCS7, ++ ENUM_PHY_2G4_HT40_BPSK, ++ ENUM_PHY_2G4_HT40_QPSK, ++ ENUM_PHY_2G4_HT40_16QAM, ++ ENUM_PHY_2G4_HT40_MCS5, ++ ENUM_PHY_2G4_HT40_MCS6, ++ ENUM_PHY_2G4_HT40_MCS7, ++ ENUM_PHY_5G_OFDM_BPSK, ++ ENUM_PHY_5G_OFDM_QPSK, ++ ENUM_PHY_5G_OFDM_16QAM, ++ ENUM_PHY_5G_OFDM_48M, ++ ENUM_PHY_5G_OFDM_54M, ++ ENUM_PHY_5G_HT20_BPSK, ++ ENUM_PHY_5G_HT20_QPSK, ++ ENUM_PHY_5G_HT20_16QAM, ++ ENUM_PHY_5G_HT20_MCS5, ++ ENUM_PHY_5G_HT20_MCS6, ++ ENUM_PHY_5G_HT20_MCS7, ++ ENUM_PHY_5G_HT40_BPSK, ++ ENUM_PHY_5G_HT40_QPSK, ++ ENUM_PHY_5G_HT40_16QAM, ++ ENUM_PHY_5G_HT40_MCS5, ++ ENUM_PHY_5G_HT40_MCS6, ++ ENUM_PHY_5G_HT40_MCS7, ++ ENUM_PHY_MODE_NUM ++} ENUM_PHY_MODE_T, *P_ENUM_PHY_MODE_T; ++ ++typedef enum _ENUM_POWER_SAVE_POLL_MODE_T { ++ ENUM_POWER_SAVE_POLL_DISABLE, ++ ENUM_POWER_SAVE_POLL_LEGACY_NULL, ++ ENUM_POWER_SAVE_POLL_QOS_NULL, ++ ENUM_POWER_SAVE_POLL_NUM ++} ENUM_POWER_SAVE_POLL_MODE_T, *P_ENUM_POWER_SAVE_POLL_MODE_T; ++ ++typedef enum _ENUM_AC_TYPE_T { ++ ENUM_AC_TYPE_AC0, ++ ENUM_AC_TYPE_AC1, ++ ENUM_AC_TYPE_AC2, ++ ENUM_AC_TYPE_AC3, ++ ENUM_AC_TYPE_AC4, ++ ENUM_AC_TYPE_AC5, ++ ENUM_AC_TYPE_AC6, ++ ENUM_AC_TYPE_BMC, ++ ENUM_AC_TYPE_NUM ++} ENUM_AC_TYPE_T, *P_ENUM_AC_TYPE_T; ++ ++typedef enum _ENUM_ADV_AC_TYPE_T { ++ ENUM_ADV_AC_TYPE_RX_NSW, ++ ENUM_ADV_AC_TYPE_RX_PTA, ++ ENUM_ADV_AC_TYPE_RX_SP, ++ ENUM_ADV_AC_TYPE_TX_PTA, ++ ENUM_ADV_AC_TYPE_TX_RSP, ++ ENUM_ADV_AC_TYPE_NUM ++} ENUM_ADV_AC_TYPE_T, *P_ENUM_ADV_AC_TYPE_T; ++ ++typedef enum _ENUM_REG_CH_MAP_T { ++ REG_CH_MAP_COUNTRY_CODE, ++ REG_CH_MAP_TBL_IDX, ++ REG_CH_MAP_CUSTOMIZED, ++ REG_CH_MAP_NUM ++} ENUM_REG_CH_MAP_T, *P_ENUM_REG_CH_MAP_T; ++ ++#define CHIP_CONFIG_RESP_SIZE 320 ++enum { ++ CHIP_CONFIG_TYPE_WO_RESPONSE = 0x00, ++ CHIP_CONFIG_TYPE_MEM8 = 0x01, ++ CHIP_CONFIG_TYPE_MEM32 = 0x02, ++ CHIP_CONFIG_TYPE_ASCII = 0x03, ++ CHIP_CONFIG_TYPE_BINARY = 0x04, ++ CHIP_CONFIG_TYPE_DRV_PASSTHROUGH = 0x05, ++ CHIP_CONFIG_TYPE_END ++}; ++ ++typedef struct _SET_TXPWR_CTRL_T { ++ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c2GHotspotPwrOffset; ++ INT_8 c2GP2pPwrOffset; ++ INT_8 c2GBowPwrOffset; ++ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ ++ INT_8 c5GHotspotPwrOffset; ++ INT_8 c5GP2pPwrOffset; ++ INT_8 c5GBowPwrOffset; ++ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence ++ in the same channel ++ 0: Highest power has priority ++ 1: Lowest power has priority */ ++ INT_8 acReserved1[3]; /* Must be zero */ ++ ++ /* Power limit by channel for all data rates */ ++ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ ++ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ ++ INT_8 acReserved2[2]; /* Must be zero */ ++} SET_TXPWR_CTRL_T, *P_SET_TXPWR_CTRL_T; ++ ++/* For storing driver initialization value from glue layer */ ++typedef struct _REG_INFO_T { ++ UINT_32 u4SdBlockSize; /* SDIO block size */ ++ UINT_32 u4SdBusWidth; /* SDIO bus width. 1 or 4 */ ++ UINT_32 u4SdClockRate; /* SDIO clock rate. (in unit of HZ) */ ++ UINT_32 u4StartAddress; /* Starting address of Wi-Fi Firmware */ ++ UINT_32 u4LoadAddress; /* Load address of Wi-Fi Firmware */ ++ UINT_16 aucFwImgFilename[65]; /* Firmware filename */ ++ UINT_16 aucFwImgFilenameE6[65]; /* Firmware filename for E6 */ ++ UINT_32 u4StartFreq; /* Start Frequency for Ad-Hoc network : in unit of KHz */ ++ UINT_32 u4AdhocMode; /* Default mode for Ad-Hoc network : ENUM_PARAM_AD_HOC_MODE_T */ ++ UINT_32 u4RddStartFreq; ++ UINT_32 u4RddStopFreq; ++ UINT_32 u4RddTestMode; ++ UINT_32 u4RddShutFreq; ++ UINT_32 u4RddDfs; ++ INT_32 i4HighRssiThreshold; ++ INT_32 i4MediumRssiThreshold; ++ INT_32 i4LowRssiThreshold; ++ INT_32 au4TxPriorityTag[ENUM_AC_TYPE_NUM]; ++ INT_32 au4RxPriorityTag[ENUM_AC_TYPE_NUM]; ++ INT_32 au4AdvPriorityTag[ENUM_ADV_AC_TYPE_NUM]; ++ UINT_32 u4FastPSPoll; ++ UINT_32 u4PTA; /* 0: disable, 1: enable */ ++ UINT_32 u4TXLimit; /* 0: disable, 1: enable */ ++ UINT_32 u4SilenceWindow; /* range: 100 - 625, unit: us */ ++ UINT_32 u4TXLimitThreshold; /* range: 250 - 1250, unit: us */ ++ UINT_32 u4PowerMode; ++ UINT_32 fgEnArpFilter; ++ UINT_32 u4PsCurrentMeasureEn; ++ UINT_32 u4UapsdAcBmp; ++ UINT_32 u4MaxSpLen; ++ UINT_32 fgDisOnlineScan; /* 0: enable online scan, non-zero: disable online scan */ ++ UINT_32 fgDisBcnLostDetection; /* 0: enable online scan, non-zero: disable online scan */ ++ UINT_32 u4FixedRate; /* 0: automatic, non-zero: fixed rate */ ++ UINT_32 u4ArSysParam0; ++ UINT_32 u4ArSysParam1; ++ UINT_32 u4ArSysParam2; ++ UINT_32 u4ArSysParam3; ++ UINT_32 fgDisRoaming; /* 0:enable roaming 1:disable */ ++ ++ /* NVRAM - MP Data -START- */ ++ UINT_8 aucMacAddr[6]; ++ UINT_16 au2CountryCode[4]; /* Country code (in ISO 3166-1 expression, ex: "US", "TW") */ ++ TX_PWR_PARAM_T rTxPwr; ++ UINT_8 aucEFUSE[144]; ++ UINT_8 ucTxPwrValid; ++ UINT_8 ucSupport5GBand; ++ UINT_8 fg2G4BandEdgePwrUsed; ++ INT_8 cBandEdgeMaxPwrCCK; ++ INT_8 cBandEdgeMaxPwrOFDM20; ++ INT_8 cBandEdgeMaxPwrOFDM40; ++ ENUM_REG_CH_MAP_T eRegChannelListMap; ++ UINT_8 ucRegChannelListIndex; ++ DOMAIN_INFO_ENTRY rDomainInfo; ++ /* NVRAM - MP Data -END- */ ++ ++ /* NVRAM - Functional Data -START- */ ++ UINT_8 uc2G4BwFixed20M; ++ UINT_8 uc5GBwFixed20M; ++ UINT_8 ucEnable5GBand; ++ UINT_8 uc2GRssiCompensation; ++ UINT_8 uc5GRssiCompensation; ++ UINT_8 fgRssiCompensationValidbit; ++ UINT_8 ucRxAntennanumber; ++ /* NVRAM - Functional Data -END- */ ++ ++} REG_INFO_T, *P_REG_INFO_T; ++ ++/* for divided firmware loading */ ++typedef struct _FWDL_SECTION_INFO_T { ++ UINT_32 u4Offset; ++ UINT_32 u4Reserved; ++ UINT_32 u4Length; ++ UINT_32 u4DestAddr; ++} FWDL_SECTION_INFO_T, *P_FWDL_SECTION_INFO_T; ++ ++typedef struct _FIRMWARE_DIVIDED_DOWNLOAD_T { ++ UINT_32 u4Signature; ++ UINT_32 u4CRC; /* CRC calculated without first 8 bytes included */ ++ UINT_32 u4NumOfEntries; ++ UINT_32 u4Reserved; ++ FWDL_SECTION_INFO_T arSection[]; ++} FIRMWARE_DIVIDED_DOWNLOAD_T, *P_FIRMWARE_DIVIDED_DOWNLOAD_T; ++ ++typedef struct _PARAM_MCR_RW_STRUCT_T { ++ UINT_32 u4McrOffset; ++ UINT_32 u4McrData; ++} PARAM_MCR_RW_STRUCT_T, *P_PARAM_MCR_RW_STRUCT_T; ++ ++typedef struct _PARAM_GET_STA_STATISTICS { ++ UINT_8 ucInvalid; ++ UINT_8 ucVersion; ++ /* Per-STA statistic */ ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ UINT_32 u4LinkScore; ++ UINT_32 u4Flag; ++ ++ /* From FW */ ++ UINT_8 ucPer; /* base: 128 */ ++ UINT_8 ucRcpi; ++ UINT_32 u4PhyMode; ++ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ ++ ++ UINT_32 u4TxFailCount; ++ UINT_32 u4TxLifeTimeoutCount; ++ UINT_32 u4TxAverageAirTime; ++ ++ /* From driver */ ++ UINT_32 u4TxTotalCount; ++ UINT_32 u4TxExceedThresholdCount; ++ UINT_32 u4TxAverageProcessTime; ++ ++ UINT_32 u4TxMaxTime; ++ UINT_32 u4TxMaxHifTime; ++ UINT_32 u4TxAverageHifTime; ++ ++ /* ++ * How many packages Enqueue/Deqeue during statistics interval ++ */ ++ UINT_32 u4EnqueueCounter; ++ UINT_32 u4DequeueCounter; ++ ++ UINT_32 u4EnqueueStaCounter; ++ UINT_32 u4DequeueStaCounter; ++ ++ UINT_32 IsrCnt; ++ UINT_32 IsrPassCnt; ++ UINT_32 TaskIsrCnt; ++ ++ UINT_32 IsrAbnormalCnt; ++ UINT_32 IsrSoftWareCnt; ++ UINT_32 IsrRxCnt; ++ UINT_32 IsrTxCnt; ++ ++ UINT_32 au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4DequeueNoTcResource[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4TcResourceBackCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ ++ UINT_32 au4TcResourceUsedCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4TcResourceWantedCount[NUM_TC_RESOURCE_TO_STATISTICS]; ++ ++ UINT_32 au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; ++ /* Global queue management statistic */ ++ UINT_32 au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; ++ UINT_32 au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; ++ ++ /* Reserved fields */ ++ UINT_8 au4Reserved[32]; ++} PARAM_GET_STA_STA_STATISTICS, *P_PARAM_GET_STA_STATISTICS; ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR { ++ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, ++ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ ++ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, ++} ENUM_TESTMODE_AVAILABLE_CHAN_ATTR; ++ ++typedef struct _LTE_SAFE_CH_INFO_T { ++ UINT_32 au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1]; ++} LTE_SAFE_CH_INFO_T, *P_CMD_LTE_SAFE_CH_INFO_T; ++ ++ /* Record Each CH Load */ ++typedef struct _PARAM_CHN_LOAD_INFO { ++ /* Per-CHN Load */ ++ UINT_32 u4Flag; ++ ++ UINT_8 ucChannel; ++ UINT_16 u2ChannelLoad; ++ UINT_8 au4Reserved[1]; ++ ++ UINT_16 u2APNum; ++ UINT_16 u2APNumTmpCountingBuf; ++ ++ /* Reserved fields */ ++ UINT_8 au4Reserved1[8]; ++} PARAM_CHN_LOAD_INFO, *P_PARAM_CHN_LOAD_INFO; ++ ++typedef struct _PARAM_GET_CHN_LOAD { ++ LTE_SAFE_CH_INFO_T rLteSafeChnList; ++ PARAM_CHN_LOAD_INFO rEachChnLoad[MAX_AUTO_CHAL_NUM]; ++ BOOLEAN fgDataReadyBit; ++ UINT_8 au4Reserved1[3]; ++} PARAM_GET_CHN_LOAD, *P_PARAM_GET_CHN_LOAD; ++ ++typedef struct _PARAM_PREFER_CHN_INFO { ++ ++ UINT_8 ucChannel; ++ UINT_16 u2APNum; ++ UINT_8 au4Reserved1[1]; ++} PARAM_PREFER_CHN_INFO, *P_PARAM_PREFER_CHN_INFO; ++ ++typedef struct _PARAM_GET_LTE_MODE { ++ /* Event Body */ ++ UINT_8 ucVersion; ++ UINT_8 aucReserved1[3]; ++ UINT_32 u4Flags; /* Bit0: valid */ ++ ++ LTE_SAFE_CH_INFO_T LTE_MODE; ++ UINT_8 aucReserved4[3]; ++ ++ UINT_8 aucReserved[4]; ++ ++} PARAM_GET_LTE_MODE, *P_PARAM_GET_LTE_MODE; ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define BUILD_SIGN(ch0, ch1, ch2, ch3) \ ++ ((UINT_32)(UINT_8)(ch0) | ((UINT_32)(UINT_8)(ch1) << 8) | \ ++ ((UINT_32)(UINT_8)(ch2) << 16) | ((UINT_32)(UINT_8)(ch3) << 24)) ++ ++#define MTK_WIFI_SIGNATURE BUILD_SIGN('M', 'T', 'K', 'W') ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanCardEjected(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanIST(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl); ++ ++WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue); ++ ++WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData); ++ ++VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); ++ ++VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket); ++ ++VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData); ++ ++WLAN_STATUS ++wlanQueryInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfOidQryHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen); ++ ++WLAN_STATUS ++wlanSetInformation(IN P_ADAPTER_T prAdapter, ++ IN PFN_OID_HANDLER_FUNC pfOidSetHandler, ++ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanAdapterStart(IN P_ADAPTER_T prAdapter, ++ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength); ++ ++WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter); ++ ++#if CFG_SUPPORT_WAPI ++BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter); ++#endif ++ ++VOID wlanReturnRxPacket(IN PVOID pvAdapter, IN PVOID pvPacket); ++ ++VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast); ++ ++BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); ++ ++VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++WLAN_STATUS ++wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); ++#endif ++ ++WLAN_STATUS ++wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); ++ ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter); ++#else ++WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum); ++#endif ++ ++WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress); ++ ++UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len); ++ ++#endif ++ ++WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode); ++ ++BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); ++ ++WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); ++ ++WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); ++ ++BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler); ++ ++VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter); ++ ++BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter); ++ ++/* Security Frame Handling */ ++BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket); ++ ++VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); ++ ++VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID/IOCTL Handling */ ++/*----------------------------------------------------------------------------*/ ++VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID); ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* Address Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* NIC Capability Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* NIC Capability Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Compiler Flags Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* PD MCR Retrieve by Polling */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, IN P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo); ++/*----------------------------------------------------------------------------*/ ++/* Loading Manufacture Data */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Media Stream Mode */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Timer Timeout Check (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Mailbox Message Check (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* TX Pending Packets Handling (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket); ++ ++WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess); ++ ++/*----------------------------------------------------------------------------*/ ++/* Low Power Acquire/Release (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* Pending Packets Number Reporting (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* ACPI state inquiry (for Glue Layer) */ ++/*----------------------------------------------------------------------------*/ ++ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter); ++ ++VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState); ++ ++VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* get ECO version from Revision ID register (for Win32) */ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* set preferred band configuration corresponding to network type */ ++/*----------------------------------------------------------------------------*/ ++VOID ++wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* get currently operating channel information */ ++/*----------------------------------------------------------------------------*/ ++UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* get BSS Descriptor information */ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); ++ ++/*----------------------------------------------------------------------------*/ ++/* check for system configuration to generate message on scan list */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter); ++ ++/*----------------------------------------------------------------------------*/ ++/* query sta statistics information from driver and firmware */ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]); ++ ++P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey); ++ ++WLAN_STATUS ++wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags); ++ ++UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef); ++ ++INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef); ++ ++WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value); ++ ++WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags); ++ ++WLAN_STATUS ++wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags); ++ ++#if CFG_SUPPORT_CFG_FILE ++WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags); ++ ++VOID wlanCfgApply(IN P_ADAPTER_T prAdapter); ++#endif /* CFG_SUPPORT_CFG_FILE */ ++ ++extern VOID mtk_wcn_wmt_set_wifi_ver(UINT_32 Value); ++ ++#endif /* _WLAN_LIB_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h +new file mode 100644 +index 000000000000..45919df996e9 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h +@@ -0,0 +1,1715 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_oid.h#2 ++*/ ++ ++/*! \file "wlan_oid.h" ++ \brief This file contains the declairation file of the WLAN OID processing routines ++ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_oid.h ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 02 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * Support UAPSD/OppPS/NoA parameter setting ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move timer callback to glue layer. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 18 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement Wakeup-on-LAN except firmware integration part ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. ++ * ++ ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add NULL OID implementation for WOL-related OIDs. ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support ++ * enable RX filter OID ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) implement timeout mechanism when OID is pending for longer than 1 second ++ * * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * * OID_802_11_RSSI, ++ * * * * OID_802_11_RSSI_TRIGGER, ++ * * * * OID_802_11_STATISTICS, ++ * * * * OID_802_11_DISASSOCIATE, ++ * * * * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-08 11:38:11 GMT mtk02752 ++** add declares for RF test related APIs ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-24 22:41:53 GMT mtk02752 ++** remove u4SysTime, MSDN 10-second will be implemented in FW side ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 20:30:13 GMT mtk02752 ++** add u4SysTime field in PARAM_BSSID_EX_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-12 19:48:35 GMT mtk02752 ++** allow upper layer to set a packet filter with PROMISCUOUS mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:12 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _WLAN_OID_H ++#define _WLAN_OID_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#if DBG ++extern UINT_8 aucDebugModule[DBG_MODULE_NUM]; ++extern UINT_32 u4DebugModule; ++UINT_32 u4DebugModuleTemp; ++#endif /* DBG */ ++extern int sprintf(char *buf, const char *fmt, ...); ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define PARAM_MAX_LEN_SSID 32 ++ ++#define PARAM_MAC_ADDR_LEN 6 ++ ++#define ETHERNET_HEADER_SZ 14 ++#define ETHERNET_MIN_PKT_SZ 60 ++#define ETHERNET_MAX_PKT_SZ 1514 ++ ++#define PARAM_MAX_LEN_RATES 8 ++#define PARAM_MAX_LEN_RATES_EX 16 ++ ++#define PARAM_AUTH_REQUEST_REAUTH 0x01 ++#define PARAM_AUTH_REQUEST_KEYUPDATE 0x02 ++#define PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 ++#define PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E ++ ++#define PARAM_EEPROM_READ_METHOD_READ 1 ++#define PARAM_EEPROM_READ_METHOD_GETSIZE 0 ++ ++#define PARAM_WHQL_RSSI_MAX_DBM (-10) ++#define PARAM_WHQL_RSSI_MIN_DBM (-200) ++ ++#define PARAM_DEVICE_WAKE_UP_ENABLE 0x00000001 ++#define PARAM_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 ++#define PARAM_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 ++ ++#define PARAM_WAKE_UP_MAGIC_PACKET 0x00000001 ++#define PARAM_WAKE_UP_PATTERN_MATCH 0x00000002 ++#define PARAM_WAKE_UP_LINK_CHANGE 0x00000004 ++ ++/* Packet filter bit definitioin (UINT_32 bit-wise definition) */ ++#define PARAM_PACKET_FILTER_DIRECTED 0x00000001 ++#define PARAM_PACKET_FILTER_MULTICAST 0x00000002 ++#define PARAM_PACKET_FILTER_ALL_MULTICAST 0x00000004 ++#define PARAM_PACKET_FILTER_BROADCAST 0x00000008 ++#define PARAM_PACKET_FILTER_PROMISCUOUS 0x00000020 ++#define PARAM_PACKET_FILTER_ALL_LOCAL 0x00000080 ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#define PARAM_PACKET_FILTER_P2P_MASK 0xC0000000 ++#define PARAM_PACKET_FILTER_PROBE_REQ 0x80000000 ++#define PARAM_PACKET_FILTER_ACTION_FRAME 0x40000000 ++#endif ++ ++#if CFG_SLT_SUPPORT ++#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ ++ PARAM_PACKET_FILTER_MULTICAST | \ ++ PARAM_PACKET_FILTER_BROADCAST | \ ++ PARAM_PACKET_FILTER_ALL_MULTICAST) ++#else ++#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ ++ PARAM_PACKET_FILTER_MULTICAST | \ ++ PARAM_PACKET_FILTER_BROADCAST) ++#endif ++ ++#define PARAM_MEM_DUMP_MAX_SIZE 2048 ++ ++#define BT_PROFILE_PARAM_LEN 8 ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Parameters of User Configuration which match to NDIS5.1 */ ++/*----------------------------------------------------------------------------*/ ++/* NDIS_802_11_AUTHENTICATION_MODE */ ++typedef enum _ENUM_PARAM_AUTH_MODE_T { ++ AUTH_MODE_OPEN, /*!< Open system */ ++ AUTH_MODE_SHARED, /*!< Shared key */ ++ AUTH_MODE_AUTO_SWITCH, /*!< Either open system or shared key */ ++ AUTH_MODE_WPA, ++ AUTH_MODE_WPA_PSK, ++ AUTH_MODE_WPA_NONE, /*!< For Ad hoc */ ++ AUTH_MODE_WPA2, ++ AUTH_MODE_WPA2_PSK, ++ AUTH_MODE_NUM /*!< Upper bound, not real case */ ++} ENUM_PARAM_AUTH_MODE_T, *P_ENUM_PARAM_AUTH_MODE_T; ++ ++/* NDIS_802_11_ENCRYPTION_STATUS *//* Encryption types */ ++typedef enum _ENUM_WEP_STATUS_T { ++ ENUM_WEP_ENABLED, ++ ENUM_ENCRYPTION1_ENABLED = ENUM_WEP_ENABLED, ++ ENUM_WEP_DISABLED, ++ ENUM_ENCRYPTION_DISABLED = ENUM_WEP_DISABLED, ++ ENUM_WEP_KEY_ABSENT, ++ ENUM_ENCRYPTION1_KEY_ABSENT = ENUM_WEP_KEY_ABSENT, ++ ENUM_WEP_NOT_SUPPORTED, ++ ENUM_ENCRYPTION_NOT_SUPPORTED = ENUM_WEP_NOT_SUPPORTED, ++ ENUM_ENCRYPTION2_ENABLED, ++ ENUM_ENCRYPTION2_KEY_ABSENT, ++ ENUM_ENCRYPTION3_ENABLED, ++ ENUM_ENCRYPTION3_KEY_ABSENT ++} ENUM_PARAM_ENCRYPTION_STATUS_T, *P_ENUM_PARAM_ENCRYPTION_STATUS_T; ++ ++typedef UINT_8 PARAM_MAC_ADDRESS[PARAM_MAC_ADDR_LEN]; ++ ++typedef UINT_32 PARAM_KEY_INDEX; ++typedef UINT_64 PARAM_KEY_RSC; ++typedef INT_32 PARAM_RSSI; ++ ++typedef UINT_32 PARAM_FRAGMENTATION_THRESHOLD; ++typedef UINT_32 PARAM_RTS_THRESHOLD; ++ ++typedef UINT_8 PARAM_RATES[PARAM_MAX_LEN_RATES]; ++typedef UINT_8 PARAM_RATES_EX[PARAM_MAX_LEN_RATES_EX]; ++ ++typedef enum _ENUM_PARAM_PHY_TYPE_T { ++ PHY_TYPE_802_11ABG = 0, /*!< Can associated with 802.11abg AP, ++ Scan dual band. */ ++ PHY_TYPE_802_11BG, /*!< Can associated with 802_11bg AP, ++ Scan single band and not report 802_11a BSSs. */ ++ PHY_TYPE_802_11G, /*!< Can associated with 802_11g only AP, ++ Scan single band and not report 802_11ab BSSs. */ ++ PHY_TYPE_802_11A, /*!< Can associated with 802_11a only AP, ++ Scan single band and not report 802_11bg BSSs. */ ++ PHY_TYPE_802_11B, /*!< Can associated with 802_11b only AP, ++ Scan single band and not report 802_11ag BSSs. */ ++ PHY_TYPE_NUM /* 5 */ ++} ENUM_PARAM_PHY_TYPE_T, *P_ENUM_PARAM_PHY_TYPE_T; ++ ++typedef enum _ENUM_PARAM_OP_MODE_T { ++ NET_TYPE_IBSS = 0, /*!< Try to merge/establish an AdHoc, do periodic SCAN for merging. */ ++ NET_TYPE_INFRA, /*!< Try to join an Infrastructure, do periodic SCAN for joining. */ ++ NET_TYPE_AUTO_SWITCH, /*!< Try to join an Infrastructure, if fail then try to merge or ++ establish an AdHoc, do periodic SCAN for joining or merging. */ ++ NET_TYPE_DEDICATED_IBSS, /*!< Try to merge an AdHoc first, ++ if fail then establish AdHoc permanently, no more SCAN. */ ++ NET_TYPE_NUM /* 4 */ ++} ENUM_PARAM_OP_MODE_T, *P_ENUM_PARAM_OP_MODE_T; ++ ++typedef struct _PARAM_SSID_T { ++ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ ++ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; ++ UINT_32 u4CenterFreq; ++} PARAM_SSID_T, *P_PARAM_SSID_T; ++ ++typedef struct _PARAM_CONNECT_T { ++ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ ++ UINT_8 *pucSsid; ++ UINT_8 *pucBssid; ++ UINT_32 u4CenterFreq; ++} PARAM_CONNECT_T, *P_PARAM_CONNECT_T; ++ ++/* This is enum defined for user to select an AdHoc Mode */ ++typedef enum _ENUM_PARAM_AD_HOC_MODE_T { ++ AD_HOC_MODE_11B = 0, /*!< Create 11b IBSS if we support 802.11abg/802.11bg. */ ++ AD_HOC_MODE_MIXED_11BG, /*!< Create 11bg mixed IBSS if we support 802.11abg/802.11bg/802.11g. */ ++ AD_HOC_MODE_11G, /*!< Create 11g only IBSS if we support 802.11abg/802.11bg/802.11g. */ ++ AD_HOC_MODE_11A, /*!< Create 11a only IBSS if we support 802.11abg. */ ++ AD_HOC_MODE_NUM /* 4 */ ++} ENUM_PARAM_AD_HOC_MODE_T, *P_ENUM_PARAM_AD_HOC_MODE_T; ++ ++typedef enum _ENUM_PARAM_MEDIA_STATE_T { ++ PARAM_MEDIA_STATE_CONNECTED, ++ PARAM_MEDIA_STATE_DISCONNECTED, ++ PARAM_MEDIA_STATE_TO_BE_INDICATED /* for following MSDN re-association behavior */ ++} ENUM_PARAM_MEDIA_STATE_T, *P_ENUM_PARAM_MEDIA_STATE_T; ++ ++typedef enum _ENUM_PARAM_NETWORK_TYPE_T { ++ PARAM_NETWORK_TYPE_FH, ++ PARAM_NETWORK_TYPE_DS, ++ PARAM_NETWORK_TYPE_OFDM5, ++ PARAM_NETWORK_TYPE_OFDM24, ++ PARAM_NETWORK_TYPE_AUTOMODE, ++ PARAM_NETWORK_TYPE_NUM /*!< Upper bound, not real case */ ++} ENUM_PARAM_NETWORK_TYPE_T, *P_ENUM_PARAM_NETWORK_TYPE_T; ++ ++typedef struct _PARAM_NETWORK_TYPE_LIST { ++ UINT_32 NumberOfItems; /*!< At least 1 */ ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkType[1]; ++} PARAM_NETWORK_TYPE_LIST, *PPARAM_NETWORK_TYPE_LIST; ++ ++typedef enum _ENUM_PARAM_PRIVACY_FILTER_T { ++ PRIVACY_FILTER_ACCEPT_ALL, ++ PRIVACY_FILTER_8021xWEP, ++ PRIVACY_FILTER_NUM ++} ENUM_PARAM_PRIVACY_FILTER_T, *P_ENUM_PARAM_PRIVACY_FILTER_T; ++ ++typedef enum _ENUM_RELOAD_DEFAULTS { ++ ENUM_RELOAD_WEP_KEYS ++} PARAM_RELOAD_DEFAULTS, *P_PARAM_RELOAD_DEFAULTS; ++ ++typedef struct _PARAM_PM_PACKET_PATTERN { ++ UINT_32 Priority; /* Importance of the given pattern. */ ++ UINT_32 Reserved; /* Context information for transports. */ ++ UINT_32 MaskSize; /* Size in bytes of the pattern mask. */ ++ UINT_32 PatternOffset; /* Offset from beginning of this */ ++ /* structure to the pattern bytes. */ ++ UINT_32 PatternSize; /* Size in bytes of the pattern. */ ++ UINT_32 PatternFlags; /* Flags (TBD). */ ++} PARAM_PM_PACKET_PATTERN, *P_PARAM_PM_PACKET_PATTERN; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief Struct definition to indicate specific event. */ ++/*--------------------------------------------------------------*/ ++typedef enum _ENUM_STATUS_TYPE_T { ++ ENUM_STATUS_TYPE_AUTHENTICATION, ++ ENUM_STATUS_TYPE_MEDIA_STREAM_MODE, ++ ENUM_STATUS_TYPE_CANDIDATE_LIST, ++ ENUM_STATUS_TYPE_NUM /*!< Upper bound, not real case */ ++} ENUM_STATUS_TYPE_T, *P_ENUM_STATUS_TYPE_T; ++ ++typedef struct _PARAM_802_11_CONFIG_FH_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4HopPattern; /*!< Defined as 802.11 */ ++ UINT_32 u4HopSet; /*!< to one if non-802.11 */ ++ UINT_32 u4DwellTime; /*!< In unit of Kusec */ ++} PARAM_802_11_CONFIG_FH_T, *P_PARAM_802_11_CONFIG_FH_T; ++ ++typedef struct _PARAM_802_11_CONFIG_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4BeaconPeriod; /*!< In unit of Kusec */ ++ UINT_32 u4ATIMWindow; /*!< In unit of Kusec */ ++ UINT_32 u4DSConfig; /*!< Channel frequency in unit of kHz */ ++ PARAM_802_11_CONFIG_FH_T rFHConfig; ++} PARAM_802_11_CONFIG_T, *P_PARAM_802_11_CONFIG_T; ++ ++typedef struct _PARAM_STATUS_INDICATION_T { ++ ENUM_STATUS_TYPE_T eStatusType; ++} PARAM_STATUS_INDICATION_T, *P_PARAM_STATUS_INDICATION_T; ++ ++typedef struct _PARAM_AUTH_REQUEST_T { ++ UINT_32 u4Length; /*!< Length of this struct */ ++ PARAM_MAC_ADDRESS arBssid; ++ UINT_32 u4Flags; /*!< Definitions are as follows */ ++} PARAM_AUTH_REQUEST_T, *P_PARAM_AUTH_REQUEST_T; ++ ++typedef struct _PARAM_AUTH_EVENT_T { ++ PARAM_STATUS_INDICATION_T rStatus; ++ PARAM_AUTH_REQUEST_T arRequest[1]; ++} PARAM_AUTH_EVENT_T, *P_PARAM_AUTH_EVENT_T; ++ ++/*! \brief Capabilities, privacy, rssi and IEs of each BSSID */ ++typedef struct _PARAM_BSSID_EX_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ PARAM_MAC_ADDRESS arMacAddress; /*!< BSSID */ ++ UINT_8 Reserved[2]; ++ PARAM_SSID_T rSsid; /*!< SSID */ ++ UINT_32 u4Privacy; /*!< Need WEP encryption */ ++ PARAM_RSSI rRssi; /*!< in dBm */ ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkTypeInUse; ++ PARAM_802_11_CONFIG_T rConfiguration; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ PARAM_RATES_EX rSupportedRates; ++ UINT_32 u4IELength; ++ UINT_8 aucIEs[1]; ++} PARAM_BSSID_EX_T, *P_PARAM_BSSID_EX_T; ++ ++typedef struct _PARAM_BSSID_LIST_EX { ++ UINT_32 u4NumberOfItems; /*!< at least 1 */ ++ PARAM_BSSID_EX_T arBssid[1]; ++} PARAM_BSSID_LIST_EX_T, *P_PARAM_BSSID_LIST_EX_T; ++ ++typedef struct _PARAM_WEP_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< 0: pairwise key, others group keys */ ++ UINT_32 u4KeyLength; /*!< Key length in bytes */ ++ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ ++} PARAM_WEP_T, *P_PARAM_WEP_T; ++ ++/*! \brief Key mapping of BSSID */ ++typedef struct _PARAM_KEY_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< KeyID */ ++ UINT_32 u4KeyLength; /*!< Key length in bytes */ ++ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ ++ PARAM_KEY_RSC rKeyRSC; ++ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ ++} PARAM_KEY_T, *P_PARAM_KEY_T; ++ ++typedef struct _PARAM_REMOVE_KEY_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< KeyID */ ++ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ ++} PARAM_REMOVE_KEY_T, *P_PARAM_REMOVE_KEY_T; ++ ++#if CFG_SUPPORT_WAPI ++typedef enum _ENUM_KEY_TYPE { ++ ENUM_WPI_PAIRWISE_KEY = 0, ++ ENUM_WPI_GROUP_KEY ++} ENUM_KEY_TYPE; ++ ++typedef enum _ENUM_WPI_PROTECT_TYPE { ++ ENUM_WPI_NONE, ++ ENUM_WPI_RX, ++ ENUM_WPI_TX, ++ ENUM_WPI_RX_TX ++} ENUM_WPI_PROTECT_TYPE; ++ ++typedef struct _PARAM_WPI_KEY_T { ++ ENUM_KEY_TYPE eKeyType; ++ ENUM_WPI_PROTECT_TYPE eDirection; ++ UINT_8 ucKeyID; ++ UINT_8 aucRsv[3]; ++ UINT_8 aucAddrIndex[12]; ++ UINT_32 u4LenWPIEK; ++ UINT_8 aucWPIEK[256]; ++ UINT_32 u4LenWPICK; ++ UINT_8 aucWPICK[256]; ++ UINT_8 aucPN[16]; ++} PARAM_WPI_KEY_T, *P_PARAM_WPI_KEY_T; ++#endif ++ ++typedef enum _PARAM_POWER_MODE { ++ Param_PowerModeCAM, ++ Param_PowerModeMAX_PSP, ++ Param_PowerModeFast_PSP, ++#if CFG_SUPPORT_DBG_POWERMODE ++ Param_PowerModeKeepActiveOn, /* privilege mode, always active */ ++ Param_PowerModeKeepActiveOff, /* to leave privilege mode */ ++#endif ++ Param_PowerModeMax /* Upper bound, not real case */ ++} PARAM_POWER_MODE, *PPARAM_POWER_MODE; ++ ++typedef enum _PARAM_DEVICE_POWER_STATE { ++ ParamDeviceStateUnspecified = 0, ++ ParamDeviceStateD0, ++ ParamDeviceStateD1, ++ ParamDeviceStateD2, ++ ParamDeviceStateD3, ++ ParamDeviceStateMaximum ++} PARAM_DEVICE_POWER_STATE, *PPARAM_DEVICE_POWER_STATE; ++ ++#if CFG_SUPPORT_802_11D ++ ++/*! \brief The enumeration definitions for OID_IPN_MULTI_DOMAIN_CAPABILITY */ ++typedef enum _PARAM_MULTI_DOMAIN_CAPABILITY { ++ ParamMultiDomainCapDisabled, ++ ParamMultiDomainCapEnabled ++} PARAM_MULTI_DOMAIN_CAPABILITY, *P_PARAM_MULTI_DOMAIN_CAPABILITY; ++#endif ++ ++typedef struct _COUNTRY_STRING_ENTRY { ++ UINT_8 aucCountryCode[2]; ++ UINT_8 aucEnvironmentCode[2]; ++} COUNTRY_STRING_ENTRY, *P_COUNTRY_STRING_ENTRY; ++ ++/* Power management related definition and enumerations */ ++#define UAPSD_NONE 0 ++#define UAPSD_AC0 (BIT(0) | BIT(4)) ++#define UAPSD_AC1 (BIT(1) | BIT(5)) ++#define UAPSD_AC2 (BIT(2) | BIT(6)) ++#define UAPSD_AC3 (BIT(3) | BIT(7)) ++#define UAPSD_ALL (UAPSD_AC0 | UAPSD_AC1 | UAPSD_AC2 | UAPSD_AC3) ++ ++typedef enum _ENUM_POWER_SAVE_PROFILE_T { ++ ENUM_PSP_CONTINUOUS_ACTIVE = 0, ++ ENUM_PSP_CONTINUOUS_POWER_SAVE, ++ ENUM_PSP_FAST_SWITCH, ++ ENUM_PSP_NUM ++} ENUM_POWER_SAVE_PROFILE_T, *PENUM_POWER_SAVE_PROFILE_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief Set/Query testing type. */ ++/*--------------------------------------------------------------*/ ++typedef struct _PARAM_802_11_TEST_T { ++ UINT_32 u4Length; ++ UINT_32 u4Type; ++ union { ++ PARAM_AUTH_EVENT_T AuthenticationEvent; ++ PARAM_RSSI RssiTrigger; ++ } u; ++} PARAM_802_11_TEST_T, *P_PARAM_802_11_TEST_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief Set/Query authentication and encryption capability. */ ++/*--------------------------------------------------------------*/ ++typedef struct _PARAM_AUTH_ENCRYPTION_T { ++ ENUM_PARAM_AUTH_MODE_T eAuthModeSupported; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncryptStatusSupported; ++} PARAM_AUTH_ENCRYPTION_T, *P_PARAM_AUTH_ENCRYPTION_T; ++ ++typedef struct _PARAM_CAPABILITY_T { ++ UINT_32 u4Length; ++ UINT_32 u4Version; ++ UINT_32 u4NoOfPMKIDs; ++ UINT_32 u4NoOfAuthEncryptPairsSupported; ++ PARAM_AUTH_ENCRYPTION_T arAuthenticationEncryptionSupported[1]; ++} PARAM_CAPABILITY_T, *P_PARAM_CAPABILITY_T; ++ ++typedef UINT_8 PARAM_PMKID_VALUE[16]; ++ ++typedef struct _PARAM_BSSID_INFO_T { ++ PARAM_MAC_ADDRESS arBSSID; ++ PARAM_PMKID_VALUE arPMKID; ++} PARAM_BSSID_INFO_T, *P_PARAM_BSSID_INFO_T; ++ ++typedef struct _PARAM_PMKID_T { ++ UINT_32 u4Length; ++ UINT_32 u4BSSIDInfoCount; ++ PARAM_BSSID_INFO_T arBSSIDInfo[1]; ++} PARAM_PMKID_T, *P_PARAM_PMKID_T; ++ ++/*! \brief PMKID candidate lists. */ ++typedef struct _PARAM_PMKID_CANDIDATE_T { ++ PARAM_MAC_ADDRESS arBSSID; ++ UINT_32 u4Flags; ++} PARAM_PMKID_CANDIDATE_T, *P_PARAM_PMKID_CANDIDATE_T; ++ ++/* #ifdef LINUX */ ++typedef struct _PARAM_PMKID_CANDIDATE_LIST_T { ++ UINT_32 u4Version; /*!< Version */ ++ UINT_32 u4NumCandidates; /*!< How many candidates follow */ ++ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; ++} PARAM_PMKID_CANDIDATE_LIST_T, *P_PARAM_PMKID_CANDIDATE_LIST_T; ++/* #endif */ ++ ++typedef struct _PARAM_CUSTOM_MCR_RW_STRUCT_T { ++ UINT_32 u4McrOffset; ++ UINT_32 u4McrData; ++} PARAM_CUSTOM_MCR_RW_STRUCT_T, *P_PARAM_CUSTOM_MCR_RW_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_MEM_DUMP_STRUCT_T { ++ UINT_32 u4Address; ++ UINT_32 u4Length; ++ UINT_32 u4RemainLength; ++ UINT_8 ucFragNum; ++} PARAM_CUSTOM_MEM_DUMP_STRUCT_T, *P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_SW_CTRL_STRUCT_T { ++ UINT_32 u4Id; ++ UINT_32 u4Data; ++} PARAM_CUSTOM_SW_CTRL_STRUCT_T, *P_PARAM_CUSTOM_SW_CTRL_STRUCT_T; ++ ++typedef struct _CMD_CHIP_CONFIG_T { ++ UINT_16 u2Id; ++ UINT_8 ucType; ++ UINT_8 ucRespType; ++ UINT_16 u2MsgSize; ++ UINT_8 aucReserved0[2]; ++ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; ++} CMD_CHIP_CONFIG_T, *P_CMD_CHIP_CONFIG_T; ++ ++typedef struct _PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T { ++ UINT_16 u2Id; ++ UINT_8 ucType; ++ UINT_8 ucRespType; ++ UINT_16 u2MsgSize; ++ UINT_8 aucReserved0[2]; ++ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; ++} PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T, *P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_KEY_CFG_STRUCT_T { ++ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; ++ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; ++} PARAM_CUSTOM_KEY_CFG_STRUCT_T, *P_PARAM_CUSTOM_KEY_CFG_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_EEPROM_RW_STRUCT_T { ++ UINT_8 ucEepromMethod; /* For read only read: 1, query size: 0 */ ++ UINT_8 ucEepromIndex; ++ UINT_8 reserved; ++ UINT_16 u2EepromData; ++} PARAM_CUSTOM_EEPROM_RW_STRUCT_T, *P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T, ++PARAM_CUSTOM_NVRAM_RW_STRUCT_T, *P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T { ++ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ ++ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ ++ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ ++ UINT_8 reserved; ++} PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T, *P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_NOA_PARAM_STRUCT_T { ++ UINT_32 u4NoaDurationMs; ++ UINT_32 u4NoaIntervalMs; ++ UINT_32 u4NoaCount; ++} PARAM_CUSTOM_NOA_PARAM_STRUCT_T, *P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T { ++ UINT_32 u4CTwindowMs; ++} PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T { ++ UINT_8 fgEnAPSD; ++ UINT_8 fgEnAPSD_AcBe; ++ UINT_8 fgEnAPSD_AcBk; ++ UINT_8 fgEnAPSD_AcVo; ++ UINT_8 fgEnAPSD_AcVi; ++ UINT_8 ucMaxSpLen; ++ UINT_8 aucResv[2]; ++} PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T; ++ ++typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { ++ UINT_32 u4Enable; ++ UINT_32 u4Mode; ++} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; ++ ++typedef enum _ENUM_CFG_SRC_TYPE_T { ++ CFG_SRC_TYPE_EEPROM, ++ CFG_SRC_TYPE_NVRAM, ++ CFG_SRC_TYPE_UNKNOWN, ++ CFG_SRC_TYPE_NUM ++} ENUM_CFG_SRC_TYPE_T, *P_ENUM_CFG_SRC_TYPE_T; ++ ++typedef enum _ENUM_EEPROM_TYPE_T { ++ EEPROM_TYPE_NO, ++ EEPROM_TYPE_PRESENT, ++ EEPROM_TYPE_NUM ++} ENUM_EEPROM_TYPE_T, *P_ENUM_EEPROM_TYPE_T; ++ ++typedef struct _PARAM_QOS_TSINFO { ++ UINT_8 ucTrafficType; /* Traffic Type: 1 for isochronous 0 for asynchronous */ ++ UINT_8 ucTid; /* TSID: must be between 8 ~ 15 */ ++ UINT_8 ucDirection; /* direction */ ++ UINT_8 ucAccessPolicy; /* access policy */ ++ UINT_8 ucAggregation; /* aggregation */ ++ UINT_8 ucApsd; /* APSD */ ++ UINT_8 ucuserPriority; /* user priority */ ++ UINT_8 ucTsInfoAckPolicy; /* TSINFO ACK policy */ ++ UINT_8 ucSchedule; /* Schedule */ ++} PARAM_QOS_TSINFO, *P_PARAM_QOS_TSINFO; ++ ++typedef struct _PARAM_QOS_TSPEC { ++ PARAM_QOS_TSINFO rTsInfo; /* TS info field */ ++ UINT_16 u2NominalMSDUSize; /* nominal MSDU size */ ++ UINT_16 u2MaxMSDUsize; /* maximum MSDU size */ ++ UINT_32 u4MinSvcIntv; /* minimum service interval */ ++ UINT_32 u4MaxSvcIntv; /* maximum service interval */ ++ UINT_32 u4InactIntv; /* inactivity interval */ ++ UINT_32 u4SpsIntv; /* suspension interval */ ++ UINT_32 u4SvcStartTime; /* service start time */ ++ UINT_32 u4MinDataRate; /* minimum Data rate */ ++ UINT_32 u4MeanDataRate; /* mean data rate */ ++ UINT_32 u4PeakDataRate; /* peak data rate */ ++ UINT_32 u4MaxBurstSize; /* maximum burst size */ ++ UINT_32 u4DelayBound; /* delay bound */ ++ UINT_32 u4MinPHYRate; /* minimum PHY rate */ ++ UINT_16 u2Sba; /* surplus bandwidth allowance */ ++ UINT_16 u2MediumTime; /* medium time */ ++} PARAM_QOS_TSPEC, *P_PARAM_QOS_TSPEC; ++ ++typedef struct _PARAM_QOS_ADDTS_REQ_INFO { ++ PARAM_QOS_TSPEC rTspec; ++} PARAM_QOS_ADDTS_REQ_INFO, *P_PARAM_QOS_ADDTS_REQ_INFO; ++ ++typedef struct _PARAM_VOIP_CONFIG { ++ UINT_32 u4VoipTrafficInterval; /* 0: disable VOIP configuration */ ++} PARAM_VOIP_CONFIG, *P_PARAM_VOIP_CONFIG; ++ ++/*802.11 Statistics Struct*/ ++typedef struct _PARAM_802_11_STATISTICS_STRUCT_T { ++ UINT_32 u4Length; /* Length of structure */ ++ LARGE_INTEGER rTransmittedFragmentCount; ++ LARGE_INTEGER rMulticastTransmittedFrameCount; ++ LARGE_INTEGER rFailedCount; ++ LARGE_INTEGER rRetryCount; ++ LARGE_INTEGER rMultipleRetryCount; ++ LARGE_INTEGER rRTSSuccessCount; ++ LARGE_INTEGER rRTSFailureCount; ++ LARGE_INTEGER rACKFailureCount; ++ LARGE_INTEGER rFrameDuplicateCount; ++ LARGE_INTEGER rReceivedFragmentCount; ++ LARGE_INTEGER rMulticastReceivedFrameCount; ++ LARGE_INTEGER rFCSErrorCount; ++ LARGE_INTEGER rTKIPLocalMICFailures; ++ LARGE_INTEGER rTKIPICVErrors; ++ LARGE_INTEGER rTKIPCounterMeasuresInvoked; ++ LARGE_INTEGER rTKIPReplays; ++ LARGE_INTEGER rCCMPFormatErrors; ++ LARGE_INTEGER rCCMPReplays; ++ LARGE_INTEGER rCCMPDecryptErrors; ++ LARGE_INTEGER rFourWayHandshakeFailures; ++ LARGE_INTEGER rWEPUndecryptableCount; ++ LARGE_INTEGER rWEPICVErrorCount; ++ LARGE_INTEGER rDecryptSuccessCount; ++ LARGE_INTEGER rDecryptFailureCount; ++} PARAM_802_11_STATISTICS_STRUCT_T, *P_PARAM_802_11_STATISTICS_STRUCT_T; ++ ++/* Linux Network Device Statistics Struct */ ++typedef struct _PARAM_LINUX_NETDEV_STATISTICS_T { ++ UINT_32 u4RxPackets; ++ UINT_32 u4TxPackets; ++ UINT_32 u4RxBytes; ++ UINT_32 u4TxBytes; ++ UINT_32 u4RxErrors; ++ UINT_32 u4TxErrors; ++ UINT_32 u4Multicast; ++} PARAM_LINUX_NETDEV_STATISTICS_T, *P_PARAM_LINUX_NETDEV_STATISTICS_T; ++ ++typedef struct _PARAM_MTK_WIFI_TEST_STRUCT_T { ++ UINT_32 u4FuncIndex; ++ UINT_32 u4FuncData; ++} PARAM_MTK_WIFI_TEST_STRUCT_T, *P_PARAM_MTK_WIFI_TEST_STRUCT_T; ++ ++/* 802.11 Media stream constraints */ ++typedef enum _ENUM_MEDIA_STREAM_MODE { ++ ENUM_MEDIA_STREAM_OFF, ++ ENUM_MEDIA_STREAM_ON ++} ENUM_MEDIA_STREAM_MODE, *P_ENUM_MEDIA_STREAM_MODE; ++ ++/* for NDIS 5.1 Media Streaming Change */ ++typedef struct _PARAM_MEDIA_STREAMING_INDICATION { ++ PARAM_STATUS_INDICATION_T rStatus; ++ ENUM_MEDIA_STREAM_MODE eMediaStreamMode; ++} PARAM_MEDIA_STREAMING_INDICATION, *P_PARAM_MEDIA_STREAMING_INDICATION; ++ ++#define PARAM_PROTOCOL_ID_DEFAULT 0x00 ++#define PARAM_PROTOCOL_ID_TCP_IP 0x02 ++#define PARAM_PROTOCOL_ID_IPX 0x06 ++#define PARAM_PROTOCOL_ID_NBF 0x07 ++#define PARAM_PROTOCOL_ID_MAX 0x0F ++#define PARAM_PROTOCOL_ID_MASK 0x0F ++ ++/* for NDIS OID_GEN_NETWORK_LAYER_ADDRESSES */ ++typedef struct _PARAM_NETWORK_ADDRESS_IP { ++ UINT_16 sin_port; ++ UINT_32 in_addr; ++ UINT_8 sin_zero[8]; ++} PARAM_NETWORK_ADDRESS_IP, *P_PARAM_NETWORK_ADDRESS_IP; ++ ++typedef struct _PARAM_NETWORK_ADDRESS { ++ UINT_16 u2AddressLength; /* length in bytes of Address[] in this */ ++ UINT_16 u2AddressType; /* type of this address (PARAM_PROTOCOL_ID_XXX above) */ ++ UINT_8 aucAddress[1]; /* actually AddressLength bytes long */ ++} PARAM_NETWORK_ADDRESS, *P_PARAM_NETWORK_ADDRESS; ++ ++/* The following is used with OID_GEN_NETWORK_LAYER_ADDRESSES to set network layer addresses on an interface */ ++ ++typedef struct _PARAM_NETWORK_ADDRESS_LIST { ++ UINT_32 u4AddressCount; /* number of addresses following */ ++ UINT_16 u2AddressType; /* type of this address (NDIS_PROTOCOL_ID_XXX above) */ ++ PARAM_NETWORK_ADDRESS arAddress[1]; /* actually AddressCount elements long */ ++} PARAM_NETWORK_ADDRESS_LIST, *P_PARAM_NETWORK_ADDRESS_LIST; ++ ++#if CFG_SLT_SUPPORT ++ ++#define FIXED_BW_LG20 0x0000 ++#define FIXED_BW_UL20 0x2000 ++#define FIXED_BW_DL40 0x3000 ++ ++#define FIXED_EXT_CHNL_U20 0x4000 /* For AGG register. */ ++#define FIXED_EXT_CHNL_L20 0xC000 /* For AGG regsiter. */ ++ ++typedef enum _ENUM_MTK_LP_TEST_MODE_T { ++ ENUM_MTK_LP_TEST_NORMAL, ++ ENUM_MTK_LP_TEST_GOLDEN_SAMPLE, ++ ENUM_MTK_LP_TEST_DUT, ++ ENUM_MTK_LP_TEST_MODE_NUM ++} ENUM_MTK_LP_TEST_MODE_T, *P_ENUM_MTK_LP_TEST_MODE_T; ++ ++typedef enum _ENUM_MTK_SLT_FUNC_IDX_T { ++ ENUM_MTK_SLT_FUNC_DO_NOTHING, ++ ENUM_MTK_SLT_FUNC_INITIAL, ++ ENUM_MTK_SLT_FUNC_RATE_SET, ++ ENUM_MTK_SLT_FUNC_LP_SET, ++ ENUM_MTK_SLT_FUNC_NUM ++} ENUM_MTK_SLT_FUNC_IDX_T, *P_ENUM_MTK_SLT_FUNC_IDX_T; ++ ++typedef struct _PARAM_MTK_SLT_LP_TEST_STRUCT_T { ++ ENUM_MTK_LP_TEST_MODE_T rLpTestMode; ++ UINT_32 u4BcnRcvNum; ++} PARAM_MTK_SLT_LP_TEST_STRUCT_T, *P_PARAM_MTK_SLT_LP_TEST_STRUCT_T; ++ ++typedef struct _PARAM_MTK_SLT_TR_TEST_STRUCT_T { ++ ENUM_PARAM_NETWORK_TYPE_T rNetworkType; /* Network Type OFDM5G or OFDM2.4G */ ++ UINT_32 u4FixedRate; /* Fixed Rate including BW */ ++} PARAM_MTK_SLT_TR_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TR_TEST_STRUCT_T; ++ ++typedef struct _PARAM_MTK_SLT_INITIAL_STRUCT_T { ++ UINT_8 aucTargetMacAddr[PARAM_MAC_ADDR_LEN]; ++ UINT_16 u2SiteID; ++} PARAM_MTK_SLT_INITIAL_STRUCT_T, *P_PARAM_MTK_SLT_INITIAL_STRUCT_T; ++ ++typedef struct _PARAM_MTK_SLT_TEST_STRUCT_T { ++ ENUM_MTK_SLT_FUNC_IDX_T rSltFuncIdx; ++ UINT_32 u4Length; /* Length of structure, ++ including myself */ ++ UINT_32 u4FuncInfoLen; /* Include following content ++ field and myself */ ++ union { ++ PARAM_MTK_SLT_INITIAL_STRUCT_T rMtkInitTest; ++ PARAM_MTK_SLT_LP_TEST_STRUCT_T rMtkLpTest; ++ PARAM_MTK_SLT_TR_TEST_STRUCT_T rMtkTRTest; ++ } unFuncInfoContent; ++ ++} PARAM_MTK_SLT_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TEST_STRUCT_T; ++ ++#endif ++ ++/*--------------------------------------------------------------*/ ++/*! \brief For Fixed Rate Configuration (Registry) */ ++/*--------------------------------------------------------------*/ ++typedef enum _ENUM_REGISTRY_FIXED_RATE_T { ++ FIXED_RATE_NONE, ++ FIXED_RATE_1M, ++ FIXED_RATE_2M, ++ FIXED_RATE_5_5M, ++ FIXED_RATE_11M, ++ FIXED_RATE_6M, ++ FIXED_RATE_9M, ++ FIXED_RATE_12M, ++ FIXED_RATE_18M, ++ FIXED_RATE_24M, ++ FIXED_RATE_36M, ++ FIXED_RATE_48M, ++ FIXED_RATE_54M, ++ FIXED_RATE_MCS0_20M_800NS, ++ FIXED_RATE_MCS1_20M_800NS, ++ FIXED_RATE_MCS2_20M_800NS, ++ FIXED_RATE_MCS3_20M_800NS, ++ FIXED_RATE_MCS4_20M_800NS, ++ FIXED_RATE_MCS5_20M_800NS, ++ FIXED_RATE_MCS6_20M_800NS, ++ FIXED_RATE_MCS7_20M_800NS, ++ FIXED_RATE_MCS0_20M_400NS, ++ FIXED_RATE_MCS1_20M_400NS, ++ FIXED_RATE_MCS2_20M_400NS, ++ FIXED_RATE_MCS3_20M_400NS, ++ FIXED_RATE_MCS4_20M_400NS, ++ FIXED_RATE_MCS5_20M_400NS, ++ FIXED_RATE_MCS6_20M_400NS, ++ FIXED_RATE_MCS7_20M_400NS, ++ FIXED_RATE_MCS0_40M_800NS, ++ FIXED_RATE_MCS1_40M_800NS, ++ FIXED_RATE_MCS2_40M_800NS, ++ FIXED_RATE_MCS3_40M_800NS, ++ FIXED_RATE_MCS4_40M_800NS, ++ FIXED_RATE_MCS5_40M_800NS, ++ FIXED_RATE_MCS6_40M_800NS, ++ FIXED_RATE_MCS7_40M_800NS, ++ FIXED_RATE_MCS32_800NS, ++ FIXED_RATE_MCS0_40M_400NS, ++ FIXED_RATE_MCS1_40M_400NS, ++ FIXED_RATE_MCS2_40M_400NS, ++ FIXED_RATE_MCS3_40M_400NS, ++ FIXED_RATE_MCS4_40M_400NS, ++ FIXED_RATE_MCS5_40M_400NS, ++ FIXED_RATE_MCS6_40M_400NS, ++ FIXED_RATE_MCS7_40M_400NS, ++ FIXED_RATE_MCS32_400NS, ++ FIXED_RATE_NUM ++} ENUM_REGISTRY_FIXED_RATE_T, *P_ENUM_REGISTRY_FIXED_RATE_T; ++ ++typedef enum _ENUM_BT_CMD_T { ++ BT_CMD_PROFILE = 0, ++ BT_CMD_UPDATE, ++ BT_CMD_NUM ++} ENUM_BT_CMD_T; ++ ++typedef enum _ENUM_BT_PROFILE_T { ++ BT_PROFILE_CUSTOM = 0, ++ BT_PROFILE_SCO, ++ BT_PROFILE_ACL, ++ BT_PROFILE_MIXED, ++ BT_PROFILE_NO_CONNECTION, ++ BT_PROFILE_NUM ++} ENUM_BT_PROFILE_T; ++ ++typedef struct _PTA_PROFILE_T { ++ ENUM_BT_PROFILE_T eBtProfile; ++ union { ++ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; ++ /* 0: sco reserved slot time, ++ 1: sco idle slot time, ++ 2: acl throughput, ++ 3: bt tx power, ++ 4: bt rssi ++ 5: VoIP interval ++ 6: BIT(0) Use this field, BIT(1) 0 apply single/ 1 dual PTA setting. ++ */ ++ UINT_32 au4Btcr[4]; ++ } u; ++} PTA_PROFILE_T, *P_PTA_PROFILE_T; ++ ++typedef struct _PTA_IPC_T { ++ UINT_8 ucCmd; ++ UINT_8 ucLen; ++ union { ++ PTA_PROFILE_T rProfile; ++ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; ++ } u; ++} PARAM_PTA_IPC_T, *P_PARAM_PTA_IPC_T, PTA_IPC_T, *P_PTA_IPC_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief CFG80211 Scan Request Container */ ++/*--------------------------------------------------------------*/ ++ ++typedef struct _PARAM_SCAN_REQUEST_EXT_T { ++ PARAM_SSID_T rSsid; ++ UINT_32 u4IELength; ++ PUINT_8 pucIE; ++} PARAM_SCAN_REQUEST_EXT_T, *P_PARAM_SCAN_REQUEST_EXT_T; ++ ++/*--------------------------------------------------------------*/ ++/*! \brief CFG80211 Scheduled Scan Request Container */ ++/*--------------------------------------------------------------*/ ++typedef struct _PARAM_SCHED_SCAN_REQUEST_T { ++ UINT_32 u4SsidNum; ++ PARAM_SSID_T arSsid[CFG_SCAN_SSID_MATCH_MAX_NUM]; ++ UINT_32 u4IELength; ++ PUINT_8 pucIE; ++ UINT_16 u2ScanInterval; /* in milliseconds */ ++} PARAM_SCHED_SCAN_REQUEST, *P_PARAM_SCHED_SCAN_REQUEST; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++typedef struct _PARAM_HS20_SET_BSSID_POOL { ++ BOOLEAN fgIsEnable; ++ UINT_8 ucNumBssidPool; ++ PARAM_MAC_ADDRESS arBSSID[8]; ++} PARAM_HS20_SET_BSSID_POOL, *P_PARAM_HS20_SET_BSSID_POOL; ++ ++#endif ++ ++typedef struct _PARAM_CUSTOM_WFD_DEBUG_STRUCT_T { ++ UINT_8 ucWFDDebugMode; /* 0: Disable ++ 1:Enable but only show inqueue skb ether SN ++ 2.show skb ether SN and the statistics of skb inqueue time */ ++ UINT_16 u2SNPeriod; /* The Ether SN Period */ ++ ++ UINT_8 reserved; ++} PARAM_CUSTOM_WFD_DEBUG_STRUCT_T, *P_PARAM_CUSTOM_WFD_DEBUG_STRUCT_T; ++ ++typedef struct _CMD_GET_PSCAN_CAPABILITY { ++/* TBD */ ++} CMD_GET_GSCAN_CAPABILITY, *P_CMD_GET_GSCAN_CAPABILITY; ++ ++typedef struct _CMD_SET_PSCAN_ENABLE { ++ UINT_8 ucPscanAct; ++ UINT_8 aucReserved[3]; ++} CMD_SET_PSCAN_ENABLE, *P_CMD_SET_PSCAN_ENABLE; ++ ++typedef enum _ENUM_PSCAN_ACT_T { ++ ENABLE, ++ DISABLE, ++ SUSPEND, ++ CLEAR ++} ENUM_PSCAN_ACT_T, *P_ENUM_PSCAN_ACT_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*--------------------------------------------------------------*/ ++/* Routines to set parameters or query information. */ ++/*--------------------------------------------------------------*/ ++/***** Routines in wlan_oid.c *****/ ++WLAN_STATUS ++wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetConnect(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if 0 ++WLAN_STATUS ++wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetChannel(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID prSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRfTestRxStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRfTestTxStatus(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++WLAN_STATUS ++wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#ifdef LINUX ++ ++WLAN_STATUS ++wlanoidQueryStatisticsForLinux(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#endif ++ ++WLAN_STATUS ++wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++WLAN_STATUS ++wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++WLAN_STATUS ++wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++/* RF Test related APIs */ ++WLAN_STATUS ++wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if CFG_SUPPORT_WAPI ++WLAN_STATUS ++wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++WLAN_STATUS ++wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++#if CFG_ENABLE_WAKEUP_ON_LAN ++WLAN_STATUS ++wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 u4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); ++ ++#if CFG_SLT_SUPPORT ++ ++WLAN_STATUS ++wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#endif ++ ++#if 0 ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBT(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++WLAN_STATUS ++wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#endif ++ ++/* ++WLAN_STATUS ++wlanoidQueryBtSingleAntenna ( ++ IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, ++ IN UINT_32 u4QueryBufferLen, ++ OUT PUINT_32 pu4QueryInfoLen ++ ); ++ ++WLAN_STATUS ++wlanoidSetBtSingleAntenna ( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen ++ ); ++ ++WLAN_STATUS ++wlanoidSetPta ( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen ++ ); ++ ++WLAN_STATUS ++wlanoidQueryPta ( ++ IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, ++ IN UINT_32 u4QueryBufferLen, ++ OUT PUINT_32 pu4QueryInfoLen ++ ); ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++WLAN_STATUS ++wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++#if CFG_SUPPORT_BATCH_SCAN ++WLAN_STATUS ++wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++WLAN_STATUS ++wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetTxRateInfo( ++ IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen ++ ); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++WLAN_STATUS ++wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++WLAN_STATUS ++wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, ++ IN UINT_32 u4SetBufferLen, ++ OUT PUINT_32 pu4SetInfoLen); ++ ++#endif /* _WLAN_OID_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h +new file mode 100644 +index 000000000000..0b558d64034d +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h +@@ -0,0 +1,307 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/wlan_p2p.h#3 ++*/ ++ ++/*! \file "wlan_p2p.h" ++ \brief This file contains the declairations of Wi-Fi Direct command ++ processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: wlan_p2p.h ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version ++ * query & set support for service discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * Support P2P ARP filter setting on early suspend/ late resume ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface ++ * for supporting Wi-Fi Direct Service Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add subroutines for P2P to set multicast list. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * support wlanoidSetP2pPowerSaveProfile() in P2P ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * Support wlanoidSetNetworkAddress() for P2P ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. ++ * ++ ++ * ++** ++*/ ++ ++#ifndef _WLAN_P2P_H ++#define _WLAN_P2P_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* Service Discovery */ ++typedef struct _PARAM_P2P_SEND_SD_RESPONSE { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucChannelNum; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_SEND_SD_RESPONSE, *P_PARAM_P2P_SEND_SD_RESPONSE; ++ ++typedef struct _PARAM_P2P_GET_SD_REQUEST { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_REQUEST, *P_PARAM_P2P_GET_SD_REQUEST; ++ ++typedef struct _PARAM_P2P_GET_SD_REQUEST_EX { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 ucChannelNum; /* Channel Number Where SD Request is received. */ ++ UINT_8 ucSeqNum; /* Get SD Request by sequence number. */ ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_REQUEST_EX, *P_PARAM_P2P_GET_SD_REQUEST_EX; ++ ++typedef struct _PARAM_P2P_SEND_SD_REQUEST { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucVersionNum; /* Indicate the Service Discovery Supplicant Version. */ ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_SEND_SD_REQUEST, *P_PARAM_P2P_SEND_SD_REQUEST; ++ ++/* Service Discovery 1.0. */ ++typedef struct _PARAM_P2P_GET_SD_RESPONSE { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_RESPONSE, *P_PARAM_P2P_GET_SD_RESPONSE; ++ ++/* Service Discovery 2.0. */ ++typedef struct _PARAM_P2P_GET_SD_RESPONSE_EX { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 ucSeqNum; /* Get SD Response by sequence number. */ ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} PARAM_P2P_GET_SD_RESPONSE_EX, *P_PARAM_P2P_GET_SD_RESPONSE_EX; ++ ++typedef struct _PARAM_P2P_TERMINATE_SD_PHASE { ++ PARAM_MAC_ADDRESS rPeerAddr; ++} PARAM_P2P_TERMINATE_SD_PHASE, *P_PARAM_P2P_TERMINATE_SD_PHASE; ++ ++/*! \brief Key mapping of BSSID */ ++typedef struct _P2P_PARAM_KEY_T { ++ UINT_32 u4Length; /*!< Length of structure */ ++ UINT_32 u4KeyIndex; /*!< KeyID */ ++ UINT_32 u4KeyLength; /*!< Key length in bytes */ ++ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ ++ PARAM_KEY_RSC rKeyRSC; ++ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ ++} P2P_PARAM_KEY_T, *P_P2P_PARAM_KEY_T; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/*--------------------------------------------------------------*/ ++/* Routines to handle command */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++/*--------------------------------------------------------------*/ ++/* Service Discovery Subroutines */ ++/*--------------------------------------------------------------*/ ++WLAN_STATUS ++wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 puQueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++WLAN_STATUS ++wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++#endif ++ ++WLAN_STATUS ++wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++WLAN_STATUS ++wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++WLAN_STATUS ++wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++#endif ++ ++/*--------------------------------------------------------------*/ ++/* Callbacks for event indication */ ++/*--------------------------------------------------------------*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif ++#endif /* _WLAN_P2P_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c +new file mode 100644 +index 000000000000..f2324f13280e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c +@@ -0,0 +1,1303 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/aaa_fsm.c#2 ++*/ ++ ++/*! \file "aaa_fsm.c" ++ \brief This file defines the FSM for AAA MODULE. ++ ++ This file defines the FSM for AAA MODULE. ++*/ ++ ++/* ++** Log: aaa_fsm.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 02 22 2012 yuche.tsai ++ * NULL ++ * Solve sigma test 5.1.3 issue, assoc response should have P2P IE. ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Resolve inorder issue under AP mode. ++ * ++ * data frame may TX before assoc response frame. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 06 17 2011 terry.wu ++ * NULL ++ * Add BoW 11N support. ++ * ++ * 06 02 2011 eddie.chen ++ * [WCXRP00000759] [MT6620 Wi-Fi][DRV] Update RCPI in AAA ++ * Update RCPI when receiving Assoc request. ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 09 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link connection event procedure and change skb length check to 1512 bytes. ++ * ++ * 03 09 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * Skip to call p2pRunEventAAAComplete to avoid indicate STA connect twice. ++ * ++ * 03 04 2011 terry.wu ++ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection ++ * Remove unused variable. ++ * ++ * 02 16 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Add more check after RX assoc frame under Hot-Spot mode. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Fix Client Limit Issue. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 15 2011 puff.wen ++ * NULL ++ * [On behalf of Frog] Add CFG_ENABLE_WIFI_DIRECT to p2pRunEventAAAComplete ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify AAA flow according to CM's comment. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Fix Compile warning, type cast from UINT_32 to UINT_16. ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * In P2P AT GO test mode under WinXP, we would not indicate connected event to host. ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 kevin.huang ++ * NULL ++ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() ++ * ++ * 08 17 2010 yuche.tsai ++ * NULL ++ * Fix bug while enabling P2P GO. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * modify due to P2P functino call prototype change. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * First draft for migration P2P FSM from FW to Driver. ++ * ++ * 04 02 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify CFG flags ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * add support of Driver STA_RECORD_T activation ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Event to AIS/BOW/P2P ++* ++* @param[in] rJoinStatus To indicate JOIN success or failure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prSwRfb Pointer to the SW_RFB_T ++ ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS aaaFsmSendEventJoinComplete(WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb) ++{ ++ P_MSG_SAA_JOIN_COMP_T prJoinCompMsg; ++ ++ ASSERT(prStaRec); ++ ++ prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T)); ++ if (!prJoinCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ if (IS_STA_IN_AIS(prStaRec)) ++ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; ++ else if (IS_STA_IN_P2P(prStaRec)) ++ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; ++ else if (IS_STA_IN_BOW(prStaRec)) ++ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; ++ else ++ ASSERT(0); ++ ++ prJoinCompMsg->rJoinStatus = rJoinStatus; ++ prJoinCompMsg->prStaRec = prStaRec; ++ prJoinCompMsg->prSwRfb = prSwRfb; ++ ++ mboxSendMsg(MBOX_ID_0, (P_MSG_HDR_T) prJoinCompMsg, MSG_SEND_METHOD_BUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of saaFsmSendEventJoinComplete() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Start Event to AAA FSM. ++* ++* @param[in] prMsgHdr Message of Join Request for a particular STA. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aaaFsmRunEventStart(IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SAA_JOIN_REQ_T prJoinReqMsg; ++ P_STA_RECORD_T prStaRec; ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prMsgHdr); ++ ++ prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr; ++ prStaRec = prJoinReqMsg->prStaRec; ++ ++ ASSERT(prStaRec); ++ ++ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n"); ++ ++ cnmMemFree(prMsgHdr); ++ ++ /* 4 <1> Validation of SAA Start Event */ ++ if (!IS_AP_STA(prStaRec->eStaType)) { ++ ++ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); ++ ++ /* Ignore the return value because don't care the prSwRfb */ ++ saaFsmSendEventJoinComplete(WLAN_STATUS_FAILURE, prStaRec, NULL); ++ ++ return; ++ } ++ /* 4 <2> The previous JOIN process is not completed ? */ ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ } ++ /* 4 <3> Reset Status Code and Time */ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); ++ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ if (prStaRec->prChallengeText) { ++ cnmMemFree(prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ ++ cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ prStaRec->ucStaState = STA_STATE_1; ++ ++ /* Trigger SAA MODULE */ ++ saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); ++ ++} /* end of saaFsmRunEventStart() */ ++#endif ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Auth Request Frame and then ++* trigger AAA FSM. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ UINT_16 u2StatusCode; ++ BOOLEAN fgReplyAuth = FALSE; ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ ++ ASSERT(prAdapter); ++ ++ do { ++ ++ /* 4 <1> Check P2P network conditions */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prBssInfo->fgIsNetActive) { ++ ++ /* 4 <1.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ ++ if (WLAN_STATUS_SUCCESS == ++ authProcessRxAuth1Frame(prAdapter, ++ prSwRfb, ++ prBssInfo->aucBSSID, ++ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, ++ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ /* 4 <1.2> Validate Auth Frame for Network Specific Conditions */ ++ fgReplyAuth = p2pFuncValidateAuth(prAdapter, ++ prSwRfb, &prStaRec, &u2StatusCode); ++ } else { ++ fgReplyAuth = TRUE; ++ } ++ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* 4 <2> Check BOW network conditions */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { ++ ++ /* 4 <2.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ ++ /* Check if for this BSSID */ ++ if (WLAN_STATUS_SUCCESS == ++ authProcessRxAuth1Frame(prAdapter, ++ prSwRfb, ++ prBssInfo->aucBSSID, ++ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, ++ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ ++ /* 4 <2.2> Validate Auth Frame for Network Specific Conditions */ ++ fgReplyAuth = ++ bowValidateAuth(prAdapter, prSwRfb, &prStaRec, &u2StatusCode); ++ ++ } else { ++ ++ fgReplyAuth = TRUE; ++ } ++ eNetTypeIndex = NETWORK_TYPE_BOW_INDEX; ++ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ return; ++ } while (FALSE); ++ ++ if (prStaRec) { ++ /* update RCPI */ ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ } ++ /* 4 <3> Update STA_RECORD_T and reply Auth_2(Response to Auth_1) Frame */ ++ if (fgReplyAuth) { ++ ++ if (prStaRec) { ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++ DBGLOG(AAA, WARN, "Previous AuthAssocState (%d) != IDLE.\n", ++ prStaRec->eAuthAssocState); ++ } ++ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ } else { ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ ++ /* NOTE(Kevin): Change to STATE_1 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ prStaRec->ucAuthAlgNum = AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else { ++ /* NOTE(Kevin): We should have STA_RECORD_T if the status code was successful */ ++ ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL)); ++ } ++ ++ /* NOTE: Ignore the return status for AAA */ ++ /* 4 <4> Reply Auth */ ++ authSendAuthFrame(prAdapter, prStaRec, eNetTypeIndex, prSwRfb, AUTH_TRANSACTION_SEQ_2, u2StatusCode); ++ ++ } ++ ++} /* end of aaaFsmRunEventRxAuth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx (Re)Association Request Frame and then ++* trigger AAA FSM. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always return success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ UINT_16 u2StatusCode = STATUS_CODE_RESERVED; ++ BOOLEAN fgReplyAssocResp = FALSE; ++ ++ ASSERT(prAdapter); ++ ++ do { ++ ++ /* 4 <1> Check if we have the STA_RECORD_T for incoming Assoc Req */ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ /* We should have the corresponding Sta Record. */ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { ++ ASSERT(0); /* Only for debug phase */ ++ break; ++ } ++ ++ if (!IS_CLIENT_STA(prStaRec)) ++ break; ++ ++ if (prStaRec->ucStaState == STA_STATE_3) { ++ /* Do Reassocation */ ++ } else if ((prStaRec->ucStaState == STA_STATE_2) && ++ (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) { ++ /* Normal case */ ++ } else { ++ DBGLOG(AAA, INFO, "Previous AuthAssocState (%d) != SEND_AUTH2, ucStaState:%d.\n", ++ prStaRec->eAuthAssocState, ++ prStaRec->ucStaState); ++ /* TODO: Why assoc req event is faster than tx done of auth */ ++ if (prStaRec->eAuthAssocState != AAA_STATE_SEND_AUTH2) ++ break; ++ } ++ ++ /* update RCPI */ ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ ++ /* 4 <2> Check P2P network conditions */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prBssInfo->fgIsNetActive) { ++ ++ /* 4 <2.1> Validate Assoc Req Frame and get Status Code */ ++ /* Check if for this BSSID */ ++ if (WLAN_STATUS_SUCCESS == ++ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ /* 4 <2.2> Validate Assoc Req Frame for Network Specific Conditions */ ++ fgReplyAssocResp = p2pFuncValidateAssocReq(prAdapter, ++ prSwRfb, ++ (PUINT_16)&u2StatusCode); ++ } else { ++ fgReplyAssocResp = TRUE; ++ } ++ ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* 4 <3> Check BOW network conditions */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_STA_IN_BOW(prStaRec)) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); ++ ++ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { ++ ++ /* 4 <3.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ ++ /* Check if for this BSSID */ ++ if (WLAN_STATUS_SUCCESS == ++ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { ++ ++ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { ++ ++ /* 4 <3.2> Validate Auth Frame for Network Specific Conditions */ ++ fgReplyAssocResp = ++ bowValidateAssocReq(prAdapter, prSwRfb, &u2StatusCode); ++ ++ } else { ++ ++ fgReplyAssocResp = TRUE; ++ } ++ ++ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ ++ break; ++ } ++ } ++ } ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ return WLAN_STATUS_SUCCESS; /* To release the SW_RFB_T */ ++ } while (FALSE); ++ ++ /* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */ ++ if (fgReplyAssocResp) { ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ ++ if ((((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) == ++ MAC_FRAME_REASSOC_REQ) { ++ ++ u2IELength = prSwRfb->u2PacketLen - ++ (UINT_16) OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]); ++ ++ pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; ++ } else { ++ u2IELength = prSwRfb->u2PacketLen - (UINT_16) OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]); ++ ++ pucIE = ((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; ++ } ++ ++ rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength); ++ ++ /* 4 <4.1> Assign Association ID */ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ if (p2pRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { ++ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); ++ /* prStaRec->eAuthAssocState = AA_STATE_IDLE; */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;/* NOTE(Kevin): for TX done */ ++ ++ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ ++ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ ++ } else { ++ /* Client List FULL. */ ++ u2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ prStaRec->u2AssocId = 0; /* Invalid Association ID */ ++ ++ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if ((IS_STA_IN_BOW(prStaRec))) { ++ /* if (bowRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { */ ++ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2; /* NOTE(Kevin): for TX done */ ++ ++ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ ++ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ ++ } ++#if 0 ++ else { ++ /* Client List FULL. */ ++ u2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ prStaRec->u2AssocId = 0; /* Invalid Association ID */ ++ ++ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } ++ } ++#endif ++#endif ++ } else { ++ prStaRec->u2AssocId = 0; /* Invalid Association ID */ ++ ++ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ /* NOTE: Ignore the return status for AAA */ ++ /* 4 <4.2> Reply Assoc Resp */ ++ assocSendReAssocRespFrame(prAdapter, prStaRec); ++ ++} ++ ++return WLAN_STATUS_SUCCESS; ++ ++} /* end of aaaFsmRunEventRxAssoc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. ++* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. ++* ++* @retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ DBGLOG(AAA, LOUD, "EVENT-TX DONE: Current Time = %lu\n", (unsigned long)kalGetTimeTick()); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { ++ DBGLOG(AAA, INFO, "EVENT-TX DONE: Invalid StaRec"); ++ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ ++ } ++ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ DBGLOG(AAA, INFO, "TX DONE status: %d, AuthAssocState: %d, SeqNo: %d\n", ++ rTxDoneStatus, prStaRec->eAuthAssocState, ++ prMsduInfo->ucTxSeqNum); ++ ++ switch (prStaRec->eAuthAssocState) { ++ case AAA_STATE_SEND_AUTH2: ++ { ++ /* Strictly check the outgoing frame is matched with current AA STATE */ ++ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_2) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { ++ if (TX_RESULT_SUCCESS == rTxDoneStatus) { ++ ++ /* NOTE(Kevin): Change to STATE_2 at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ } else { ++ ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ ++ /* NOTE(Kevin): Change to STATE_1 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ p2pRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ } ++ ++ } ++ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ ++ ++ } ++ break; ++ ++ case AAA_STATE_SEND_ASSOC2: ++ { ++ /* Strictly check the outgoing frame is matched with current SAA STATE */ ++ if (assocCheckTxReAssocRespFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { ++ if (TX_RESULT_SUCCESS == rTxDoneStatus) { ++ ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ ++ /* NOTE(Kevin): Change to STATE_3 at TX Done */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ p2pRunEventAAASuccess(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++ if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventAAAComplete(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ } else { ++ ++ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; ++ ++ /* NOTE(Kevin): Change to STATE_2 */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ p2pRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventAAATxFail(prAdapter, prStaRec); ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++ } ++ } ++ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of aaaFsmRunEventTxDone() */ ++#endif /* CFG_SUPPORT_AAA */ ++ ++#if 0 /* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will send ABORT Event to JOIN FSM. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventAbort(IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("joinFsmRunEventAbort"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ ++ DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n"); ++ ++ /* NOTE(Kevin): when reach here, the ARB_STATE should be in ARB_STATE_JOIN. */ ++ ASSERT(prJoinInfo->prBssDesc); ++ ++ /* 4 <1> Update Flags and Elements of JOIN Module. */ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prJoinInfo->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel all JOIN relative Timer */ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer); ++ ++ /* 4 <2> Update the associated STA_RECORD_T during JOIN. */ ++ /* Get a Station Record if possible, TA == BSSID for AP */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); ++ if (prStaRec) ++ prStaRec->ucStaState = STA_STATE_1; /* Update Station Record - Class 1 Flag */ ++#if DBG ++ else ++ ASSERT(0); /* Shouldn't happened, because we already add this STA_RECORD_T at JOIN_STATE_INIT */ ++#endif /* DBG */ ++ ++ /* 4 <3> Pull back to IDLE. */ ++ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); ++ ++ /* 4 <4> If we are in Roaming, recover the settings of previous BSS. */ ++ /* NOTE: JOIN FAIL - ++ * Restore original setting from current BSS_INFO_T. ++ */ ++ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) ++ joinAdoptParametersFromCurrentBss(prAdapter); ++ ++} /* end of joinFsmRunEventAbort() */ ++#endif ++ ++/* TODO(Kevin): following code will be modified and move to AIS FSM */ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will send Join Timeout Event to JOIN FSM. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ ++ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); ++ ++ /* Get a Station Record if possible, TA == BSSID for AP */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); ++ ++ /* We have renew this Sta Record when in JOIN_STATE_INIT */ ++ ASSERT(prStaRec); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; ++ ++ /* Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prJoinInfo->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel other JOIN relative Timer */ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); ++ ++ /* Restore original setting from current BSS_INFO_T */ ++ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) ++ joinAdoptParametersFromCurrentBss(prAdapter); ++ ++ /* Pull back to IDLE */ ++ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); ++ ++ return WLAN_STATUS_FAILURE; ++ ++} /* end of joinFsmRunEventJoinTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from Peer BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ DEBUGFUNC("joinAdoptParametersFromPeerBss"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ ++ /* 4 <1> Adopt Peer BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; ++ ++ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", ++ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); ++ ++ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); ++ ++ prJoinInfo->fgIsParameterAdopted = TRUE; ++ ++} /* end of joinAdoptParametersFromPeerBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from current associated BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) ++{ ++ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ prBssInfo = &prAdapter->rBssInfo; ++ ++ /* 4 <1> Adopt current BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; ++ ++ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); ++ ++} /* end of joinAdoptParametersFromCurrentBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will update all the SW variables and HW MCR registers after ++* the association with target BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinComplete(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ P_PEER_BSS_INFO_T prPeerBssInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SUPPORT_802_11D ++ P_IE_COUNTRY_T prIECountry; ++#endif ++ ++ DEBUGFUNC("joinComplete"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ prPeerBssInfo = &prAdapter->rPeerBssInfo; ++ prBssInfo = &prAdapter->rBssInfo; ++ prConnSettings = &prAdapter->rConnSettings; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ ++ /* Remove previous AP's Connection Flags if have */ ++ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); ++ ++ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ ++ ++ if (prBssDesc->fgIsHiddenSSID) { ++ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't ++ * broadcast SSID on its Beacon Frame. ++ */ ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); ++ ++ if (prBssDesc->ucSSIDLen) ++ prBssDesc->fgIsHiddenSSID = FALSE; ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); ++ } ++/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ ++ /* 4 <2.A> PHY Type */ ++ prBssInfo->ePhyType = prBssDesc->ePhyType; ++ ++ /* 4 <2.B> BSS Type */ ++ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ ++ /* 4 <2.C> BSSID */ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); ++ ++ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); ++ ++ /* 4 <2.D> SSID */ ++ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ ++ /* 4 <2.E> Channel / Band information. */ ++ prBssInfo->eBand = prBssDesc->eBand; ++ prBssInfo->ucChnl = prBssDesc->ucChannelNum; ++ ++ /* 4 <2.F> RSN/WPA information. */ ++ secFsmRunEventStart(prAdapter); ++ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; ++ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; ++ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; ++ ++ if (secRsnKeyHandshakeEnabled()) ++ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; ++ else ++ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; ++ ++ /* 4 <2.G> Beacon interval. */ ++ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ ++ /* 4 <2.H> DTIM period. */ ++ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; ++ ++ /* 4 <2.I> ERP Information */ ++ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ ++ (prBssDesc->fgIsERPPresent)) { ++ ++ prBssInfo->fgIsERPPresent = TRUE; ++ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ ++ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ ++ prBssInfo->fgIsERPPresent = FALSE; ++ prBssInfo->ucERP = 0; ++ } ++ ++#if CFG_SUPPORT_802_11D ++ /* 4 <2.J> Country inforamtion of the associated AP */ ++ if (prConnSettings->fgMultiDomainCapabilityEnabled) { ++ DOMAIN_INFO_ENTRY rDomainInfo; ++ ++ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { ++ if (prBssDesc->prIECountry) { ++ prIECountry = prBssDesc->prIECountry; ++ ++ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); ++ ++ /* use the domain get from the BSS info */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); ++ } else { ++ /* use the domain get from the scan result */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); ++ } ++ } ++ } ++#endif ++ ++ /* 4 <2.K> Signal Power of the associated AP */ ++ prBssInfo->rRcpi = prBssDesc->rRcpi; ++ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); ++ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); ++ ++ /* 4 <2.L> Capability Field of the associated AP */ ++ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; ++ ++ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", ++ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); ++ ++/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ ++ /* 4 <3.A> Association ID */ ++ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; ++ ++ /* 4 <3.B> WMM Information */ ++ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { ++ ++ prBssInfo->fgIsWmmAssoc = TRUE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; ++ ++ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); ++ ++ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { ++ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } else { ++ kalMemCopy(&prBssInfo->rWmmInfo, ++ &prPeerBssInfo->rWmmInfo, ++ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); ++ } ++ } else { ++ prBssInfo->fgIsWmmAssoc = FALSE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; ++ ++ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } ++ ++ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ ++ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; ++ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; ++ ++ /* 4 <3.D> Short Preamble */ ++ if (prBssInfo->fgIsERPPresent) { ++ ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE FALSE(shouldn't have such case, ++ * use the AssocResp) ++ * TRUE FALSE TRUE FALSE ++ * FALSE FALSE FALSE FALSE(shouldn't have such case, ++ * use the AssocResp) ++ * FALSE FALSE TRUE FALSE ++ * TRUE TRUE FALSE TRUE(follow ERP) ++ * TRUE TRUE TRUE FALSE(follow ERP) ++ * FALSE TRUE FALSE FALSE(shouldn't have such case, ++ * and we should set to FALSE) ++ * FALSE TRUE TRUE FALSE(we should set to FALSE) ++ */ ++ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && ++ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { ++ ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ ++ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) ++ prBssInfo->fgUseShortPreamble = FALSE; ++ else ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ } else { ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE ++ * FALSE FALSE FALSE ++ * TRUE TRUE TRUE ++ * FALSE TRUE(status success) TRUE ++ * --> Honor the result of prPeerBssInfo. ++ */ ++ ++ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = ++ prPeerBssInfo->fgIsShortPreambleAllowed; ++ } ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", ++ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); ++ ++ /* 4 <3.E> Short Slot Time */ ++ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); ++ ++ nicSetSlotTime(prAdapter, ++ prBssInfo->ePhyType, ++ ((prConnSettings->fgIsShortSlotTimeOptionEnable && ++ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); ++ ++ /* 4 <3.F> Update Tx Rate for Control Frame */ ++ bssUpdateTxRateForControlFrame(prAdapter); ++ ++ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ ++ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ ++ { ++ ++ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; ++ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; ++ ++ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; ++ ++ /* Set the stable time of the associated BSS. We won't do roaming decision ++ * during the stable time. ++ */ ++ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, ++ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); ++ } ++ ++ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ ++#if CFG_TX_FRAGMENT ++ txFragInfoUpdate(prAdapter); ++#endif /* CFG_TX_FRAGMENT */ ++ ++/* 4 <4> Update STA_RECORD_T */ ++ /* Get a Station Record if possible */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); ++ ++ if (prStaRec) { ++ UINT_16 u2OperationalRateSet, u2DesiredRateSet; ++ ++ /* 4 <4.A> Desired Rate Set */ ++ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & ++ prBssInfo->u2OperationalRateSet); ++ ++ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); ++ if (u2DesiredRateSet) { ++ prStaRec->u2DesiredRateSet = u2DesiredRateSet; ++ } else { ++ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ ++ prStaRec->u2DesiredRateSet = u2OperationalRateSet; ++ } ++ ++ /* Try to set the best initial rate for this entry */ ++ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, ++ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { ++ ++ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) ++ ASSERT(0); ++ } ++ ++ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); ++ ++ /* 4 <4.B> Preamble Mode */ ++ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; ++ ++ /* 4 <4.C> QoS Flag */ ++ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; ++ } ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++/* 4 <5> Update NIC */ ++ /* 4 <5.A> Update BSSID & Operation Mode */ ++ nicSetupBSS(prAdapter, prBssInfo); ++ ++ /* 4 <5.B> Update WLAN Table. */ ++ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) ++ ASSERT(FALSE); ++ /* 4 <5.C> Update Desired Rate Set for BT. */ ++#if CFG_TX_FRAGMENT ++ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) ++ txRateSetInitForBT(prAdapter, prStaRec); ++#endif /* CFG_TX_FRAGMENT */ ++ ++ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ ++ if (prBssInfo->fgIsWmmAssoc) { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, FALSE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); ++ } else { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, TRUE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); ++ ++ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); ++ } ++ ++#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN ++ { ++ prTxCtrl->fgBlockTxDuringJoin = FALSE; ++ ++#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ ++ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxRetransmitOfSendWaitQue(prAdapter); ++ ++ if (prTxCtrl->fgIsPacketInOsSendQueue) ++ nicTxRetransmitOfOsSendQue(prAdapter); ++#if CFG_SDIO_TX_ENHANCE ++ halTxLeftClusteredMpdu(prAdapter); ++#endif /* CFG_SDIO_TX_ENHANCE */ ++ ++ } ++#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ ++ ++/* 4 <6> Setup CONNECTION flag. */ ++ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; ++ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; ++ ++ if (prJoinInfo->fgIsReAssoc) ++ prAdapter->fgBypassPortCtrlForRoaming = TRUE; ++ else ++ prAdapter->fgBypassPortCtrlForRoaming = FALSE; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); ++ ++} /* end of joinComplete() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c +new file mode 100644 +index 000000000000..7b5a49a5ba63 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c +@@ -0,0 +1,5039 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ais_fsm.c#1 ++*/ ++ ++/*! \file "aa_fsm.c" ++ \brief This file defines the FSM for SAA and AAA MODULE. ++ ++ This file defines the FSM for SAA and AAA MODULE. ++*/ ++ ++/* ++** Log: ais_fsm.c ++** ++** 09 06 2013 cp.wu ++** always paste SSID information to SAA-FSM ++** ++** 09 06 2013 cp.wu ++** add error handling when reassociation request failed to locate bss descriptor ++** ++** 09 05 2013 cp.wu ++** isolate logic regarding roaming & reassociation ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++ * ++ * 04 20 2012 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * correct macro ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with ++ * corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration ++ * corresponding to network type. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous ++ * to asynchronous approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state ++ * without join timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED ++ * cases as an explicit trigger for Android framework ++ * correct reference to BSSID field in Association-Response frame. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED ++ * cases as an explicit trigger for Android framework ++ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. ++ * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT ++ * indication to Android Wi-Fi framework ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 10 26 2011 tsaiyuan.hsu ++ * [WCXRP00001064] [MT6620 Wi-Fi][DRV]] add code with roaming awareness when disconnecting AIS network ++ * be aware roaming when disconnecting AIS network. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * STA_REC shall be NULL for Beacon's MSDU ++ * ++ * 10 13 2011 cp.wu ++ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS ++ * 1. short join failure count limit to 2 ++ * 2. treat join timeout as kind of join failure as well ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 09 20 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * change window registry of driver for roaming. ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Handle client mode about preamble type and slot time ++ * ++ * 09 08 2011 tsaiyuan.hsu ++ * [WCXRP00000972] [MT6620 Wi-Fi][DRV]] check if roaming occurs after join failure to avoid state incosistence. ++ * check if roaming occurs after join failure to avoid deactivation of network. ++ * ++ * 08 24 2011 chinghwa.yu ++ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Update RDD test mode cases. ++ * ++ * 08 16 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * EnableRoaming in registry is deprecated. ++ * ++ * 08 16 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * use registry to enable or disable roaming. ++ * ++ * 07 07 2011 cp.wu ++ * [WCXRP00000840] [MT6620 Wi-Fi][Driver][AIS] Stop timer for joining when channel is released ++ * due to join failure count exceeding limit ++ * stop timer when joining operation is failed due to try count exceeds limitation ++ * ++ * 06 28 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work ++ * around some tricky AP which use space character as hidden SSID ++ * do not handle SCAN request immediately after connected to increase the probability of receiving 1st beacon frame. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * ensure DEAUTH is always sent before establish a new connection ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * typo fix: a right brace is missed. ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * When RECONNECT request is identified as disconnected, it is necessary to check for pending scan request. ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels ++ * mark fgIsTransition as TRUE for state rolling. ++ * ++ * 06 16 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * always check for pending scan after switched into NORMAL_TR state. ++ * ++ * 06 14 2011 cp.wu ++ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout ++ * always treat connection request at higher priority over scanning request ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * eliminate unused parameters for SAA-FSM ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state ++ * when DEAUTH frame is dropped due to bss disconnection ++ * change SCAN handling behavior when followed by a CONNECT/DISCONNECT requests by pending instead of dropping. ++ * ++ * 05 17 2011 cp.wu ++ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state ++ * when DEAUTH frame is dropped due to bss disconnection ++ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 13 2011 george.huang ++ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF ++ * remove assert ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000575] [MT6620 Wi-Fi][Driver][AIS] reduce memory usage when generating mailbox message for scan request ++ * when there is no IE needed for probe request, then request a smaller memory for mailbox message ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 16 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * remove obsolete definition and unused variables. ++ * ++ * 03 11 2011 cp.wu ++ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently ++ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel ++ * ++ * 03 09 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * avoid clearing fgIsScanReqIssued so as to add scan results. ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 04 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * reset retry conter of attemp to connect to ap after completion of join. ++ * ++ * 03 04 2011 cp.wu ++ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection ++ * surpress compile warning occurred when compiled by GNU compiler collection. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right ++ * after connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 02 23 2011 cp.wu ++ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach to ++ * improve response time for scanning request ++ * when handling reconnect request, set fgTryScan as TRUE ++ * ++ * 02 22 2011 cp.wu ++ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach ++ * to improve response time for scanning request ++ * handle SCAN and RECONNECT with a FIFO approach. ++ * ++ * 02 09 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * Check if prRegInfo is null or not before initializing roaming parameters. ++ * ++ * 02 01 2011 cp.wu ++ * [WCXRP00000416] [MT6620 Wi-Fi][Driver] treat "unable to find BSS" as connection trial ++ * to prevent infinite reconnection trials ++ * treat "unable to find BSS" as connection trial to prevent infinite reconnection trials. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 14 2011 cp.wu ++ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent ++ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. ++ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. ++ * ++ * 01 11 2011 cp.wu ++ * [WCXRP00000307] [MT6620 Wi-Fi][SQA]WHQL test .2c_wlan_adhoc case fail. ++ * [IBSS] when merged in, the bss state should be updated to firmware to pass WHQL adhoc failed item ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer ++ * when the corresponding BSS is disconnected due to beacon timeout ++ * remove from scanning result when the BSS is disconnected due to beacon timeout. ++ * ++ * 01 03 2011 cp.wu ++ * [WCXRP00000337] [MT6620 Wi-FI][Driver] AIS-FSM not to invoke cnmStaRecResetStatus ++ * directly 'cause it frees all belonging STA-RECs ++ * do not invoke cnmStaRecResetStatus() directly, nicUpdateBss will do the things after bss is disconnected ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged ++ * do not need to manipulate prStaRec after indicating BSS disconnection to firmware, ++ * 'cause all STA-RECs belongs to BSS has been freed already ++ * ++ * 12 27 2010 cp.wu ++ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release ++ * add DEBUGFUNC() macro invoking for more detailed debugging information ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 12 17 2010 cp.wu ++ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged ++ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update SLT Function for QoS Support and not be affected by fixed rate function. ++ * ++ * 11 25 2010 cp.wu ++ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM ++ * add scanning with specified SSID facility to AIS-FSM ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with ++ * Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate ++ * from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000097] [MT6620 Wi-Fi] [Driver] Fixed the P2P not setting the fgIsChannelExt value make scan not abort ++ * initial the fgIsChannelExt value. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. ++ * correct erroneous logic: specifying eBand with incompatible eSco ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000049] [MT6620 Wi-Fi][Driver] Adhoc cannot be created successfully. ++ * keep IBSS-ALONE state retrying until further instruction is received ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD ++ * when entering RF test with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 09 2010 yuche.tsai ++ * NULL ++ * Fix NULL IE Beacon issue. Sync Beacon Content to FW before enable beacon. ++ * Both in IBSS Create & IBSS Merge ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * frequency is in unit of KHz thus no need to divide 1000 once more. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * 1) initialize for correct parameter even for disassociation. ++ * 2) AIS-FSM should have a limit on trials to build connection ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add option for enabling AIS 5GHz scan ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, ++ * RLM/CNM will handle the channel switching when BSS information is updated ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * check-in missed files. ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 09 2010 cp.wu ++ * NULL ++ * reset fgIsScanReqIssued when abort request is received right after join completion. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 02 2010 cp.wu ++ * NULL ++ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * allocate on MGMT packet for IBSS beaconing. ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * [AIS-FSM] fix: when join failed, release channel privilege as well ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * reuse join-abort sub-procedure to reduce code size. ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, ++ * just pend it til 5-sec. period finishes ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet ++ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found ++ * ++ * 07 26 2010 cp.wu ++ * ++ * re-commit code logic being overwriten. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) enable Ad-Hoc ++ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * indicate scan done for linux wireless extension ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 22 2010 cp.wu ++ * ++ * 1) refine AIS-FSM indent. ++ * 2) when entering RF Test mode, flush 802.1X frames as well ++ * 3) when entering D3 state, flush 802.1X frames as well ++ * ++ * 07 21 2010 cp.wu ++ * ++ * separate AIS-FSM states into different cases of channel request. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one ++ * 2) refine disconnection behaviour when issued during BG-SCAN process ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) bugfix: do not stop timer for join after switched into normal_tr state, ++ * for providing chance for DHCP handshasking ++ * 2) modify rsnPerformPolicySelection() invoking ++ * ++ * 07 19 2010 cp.wu ++ * ++ * 1) init AIS_BSS_INFO as channel number = 1 with band = 2.4GHz ++ * 2) correct typo ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * when IBSS is being merged-in, send command packet to PM for connected indication ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 16 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * bugfix for SCN migration ++ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue ++ * 2) before AIS issues scan request, network(BSS) needs to be activated first ++ * 3) only invoke COPY_SSID when using specified SSID for scan ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * for AIS scanning, driver specifies no extra IE for probe request ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * driver no longer generates probe request frames ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * Remove CFG_MQM_MIGRATION ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Refine AIS-FSM by divided into more states ++ * ++ * 07 13 2010 cm.chang ++ * ++ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * for first connection, if connecting failed do not enter into scan state. ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * once STA-REC is allocated and updated, invoke cnmStaRecChangeState() to sync. with firmware. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * STA-REC is maintained by CNM only. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * remove unused definitions. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RLM APIs by CFG_RLM_MIGRATION. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * RSN/PRIVACY compilation flag awareness correction ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change to enqueue TX frame infinitely. ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 01 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add conditionial compiling flag to choose default available bandwidth ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix compile error if CFG_CMD_EVENT_VER_009 == 0 for prEventConnStatus->ucNetworkType. ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set ++ * ++ * 05 17 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Call pmAbort() and add ucNetworkType field in EVENT_CONNECTION_STATUS ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix compile warning - define of MQM_WMM_PARSING was removed ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed the use of compiling flag MQM_WMM_PARSING ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * ++ * Fix typo ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Send Deauth for Class 3 Error and Leave Network Support ++ * ++ * 04 15 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the protected bit at cap info for ad-hoc. ++ * ++ * 04 13 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add new HW CH macro support ++ * ++ * 04 07 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Add TX Power Control RCPI function. ++ * ++ * 03 29 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * move the wlan table alloc / free to change state function. ++ * ++ * 03 25 2010 wh.su ++ * [BORA00000676][MT6620] Support the frequency setting and query at build connection / connection event ++ * modify the build connection and status event structure bu CMD_EVENT doc 0.09 draft, default is disable. ++ * ++ * 03 24 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * fixed some WHQL testing error. ++ * ++ * 03 24 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Set / Unset POWER STATE in AIS Network ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 03 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add PHY_CONFIG to change Phy Type ++ * ++ * 03 03 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Use bcmWiFiNotify to replace wifi_send_msg to pass information to BCM module. ++ * ++ * 03 03 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Remove wmt_task definition and add PTA function. ++ * ++ * 03 02 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Init TXM and MQM testing procedures in aisFsmRunEventJoinComplete() ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Modified aisUpdateBssInfo() to call TXM's functions for setting WTBL TX parameters ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * clear the pmkid cache while indicate media disconnect. ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * . ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Enabled MQM parsing WMM IEs for non-AP mode ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * use the Rx0 dor event indicate. ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Support dynamic channel selection ++ * ++ * 02 23 2010 wh.su ++ * [BORA00000621][MT6620 Wi-Fi] Add the RSSI indicate to avoid XP stalled for query rssi value ++ * Adding the RSSI event support, ++ * using the HAL function to get the rcpi value and tranlsate to RSSI and indicate to driver ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Revise data structure to share the same BSS_INFO_T for avoiding coding error ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Set max AMDPU size supported by the peer to 64 KB, ++ * removed mqmInit() and mqmTxSendAddBaReq() function calls in aisUpdateBssInfo() ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 20 2010 kevin.huang ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags ++ * ++ * 01 15 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Configured the AMPDU factor to 3 for the APu1rwduu`wvpghlqg|q`mpdkb+ilp ++ * ++ * 01 14 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Add WiFi BCM module for the 1st time. ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * Refine JOIN Complete and separate the function of Media State indication ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 10 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the sample code to update the wlan table rate, ++ * ++ * Dec 10 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Different function prototype of wifi_send_msg() ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Call rlm related function to process HT info when join complete ++ * ++ * Dec 9 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * default the acquired wlan table entry code off ++ * ++ * Dec 9 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code to acquired the wlan table entry, and a sample code to update the BA bit at table ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix the problem of prSwRfb overwrited by event packet in aisFsmRunEventJoinComplete() ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code to integrate the security related code ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove redundant declaration ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add code for JOIN init and JOIN complete ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename u4RSSI to i4RSSI ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise ENUM_MEDIA_STATE to ENUM_PARAM_MEDIA_STATE ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add fgIsScanReqIssued to CONNECTION_SETTINGS_T ++ * ++ * Nov 26 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise Virtual CMD handler due to structure changed ++ * ++ * Nov 25 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Virtual CMD & RESP for testing CMD PATH ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aisFsmInitializeConnectionSettings() ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add CFG_TEST_MGMT_FSM flag for aisFsmTest() ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define AIS_ROAMING_CONNECTION_TRIAL_LIMIT 2 ++#define AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME 80 ++ ++#define CTIA_MAGIC_SSID "ctia_test_only_*#*#3646633#*#*" ++#define CTIA_MAGIC_SSID_LEN 30 ++ ++#define AIS_JOIN_TIMEOUT 7 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugAisState[AIS_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("AIS_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("AIS_STATE_SEARCH"), ++ (PUINT_8) DISP_STRING("AIS_STATE_SCAN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_ONLINE_SCAN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_LOOKING_FOR"), ++ (PUINT_8) DISP_STRING("AIS_STATE_WAIT_FOR_NEXT_SCAN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_REQ_CHANNEL_JOIN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_JOIN"), ++ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_ALONE"), ++ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_MERGE"), ++ (PUINT_8) DISP_STRING("AIS_STATE_NORMAL_TR"), ++ (PUINT_8) DISP_STRING("AIS_STATE_DISCONNECTING"), ++ (PUINT_8) DISP_STRING("AIS_STATE_REQ_REMAIN_ON_CHANNEL"), ++ (PUINT_8) DISP_STRING("AIS_STATE_REMAIN_ON_CHANNEL") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief the function is used to initialize the value of the connection settings for ++* AIS network ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_8 aucAnyBSSID[] = BC_BSSID; ++ UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; ++ int i = 0; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* Setup default values for operation */ ++ COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr); ++ ++ if (prRegInfo) ++ prConnSettings->ucDelayTimeOfDisconnectEvent = ++ (!prAdapter->fgIsHw5GBandDisabled && prRegInfo->ucSupport5GBand) ? ++ AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND : AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; ++ else ++ prConnSettings->ucDelayTimeOfDisconnectEvent = AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; ++ ++ COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID); ++ prConnSettings->fgIsConnByBssidIssued = FALSE; ++ ++ prConnSettings->fgIsConnReqIssued = FALSE; ++ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; ++ ++ prConnSettings->ucSSIDLen = 0; ++ ++ prConnSettings->eOPMode = NET_TYPE_INFRA; ++ ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ ++ if (prRegInfo) { ++ prConnSettings->ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4StartFreq); ++ prConnSettings->eAdHocBand = prRegInfo->u4StartFreq < 5000000 ? BAND_2G4 : BAND_5G; ++ prConnSettings->eAdHocMode = (ENUM_PARAM_AD_HOC_MODE_T) (prRegInfo->u4AdhocMode); ++ } ++ ++ prConnSettings->eAuthMode = AUTH_MODE_OPEN; ++ ++ prConnSettings->eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ ++ /* MIB attributes */ ++ prConnSettings->u2BeaconPeriod = DOT11_BEACON_PERIOD_DEFAULT; ++ ++ prConnSettings->u2RTSThreshold = DOT11_RTS_THRESHOLD_DEFAULT; ++ ++ prConnSettings->u2DesiredNonHTRateSet = RATE_SET_ALL_ABG; ++ ++ /* prConnSettings->u4FreqInKHz; */ /* Center frequency */ ++ ++ /* Set U-APSD AC */ ++ prConnSettings->bmfgApsdEnAc = PM_UAPSD_NONE; ++ ++ secInit(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* Features */ ++ prConnSettings->fgIsEnableRoaming = FALSE; ++#if CFG_SUPPORT_ROAMING ++ if (prRegInfo) ++ prConnSettings->fgIsEnableRoaming = ((prRegInfo->fgDisRoaming > 0) ? (FALSE) : (TRUE)); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ prConnSettings->fgIsAdHocQoSEnable = FALSE; ++ ++ prConnSettings->eDesiredPhyConfig = PHY_CONFIG_802_11ABGN; ++ ++ /* Set default bandwidth modes */ ++ prConnSettings->uc2G4BandwidthMode = CONFIG_BW_20M; ++ prConnSettings->uc5GBandwidthMode = CONFIG_BW_20_40M; ++ ++ prConnSettings->rRsnInfo.ucElemId = 0x30; ++ prConnSettings->rRsnInfo.u2Version = 0x0001; ++ prConnSettings->rRsnInfo.u4GroupKeyCipherSuite = 0; ++ prConnSettings->rRsnInfo.u4PairwiseKeyCipherSuiteCount = 0; ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) ++ prConnSettings->rRsnInfo.au4PairwiseKeyCipherSuite[i] = 0; ++ prConnSettings->rRsnInfo.u4AuthKeyMgtSuiteCount = 0; ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) ++ prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[i] = 0; ++ prConnSettings->rRsnInfo.u2RsnCap = 0; ++ prConnSettings->rRsnInfo.fgRsnCapPresent = FALSE; ++ ++} /* end of aisFsmInitializeConnectionSettings() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief the function is used to initialize the value in AIS_FSM_INFO_T for ++* AIS FSM operation ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ucScanTimeoutTimes = 0; ++VOID aisFsmInit(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ ++ DEBUGFUNC("aisFsmInit()"); ++ DBGLOG(SW1, TRACE, "->aisFsmInit()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ ++ /* 4 <1> Initiate FSM */ ++ prAisFsmInfo->ePreviousState = AIS_STATE_IDLE; ++ prAisFsmInfo->eCurrentState = AIS_STATE_IDLE; ++ ++ prAisFsmInfo->ucAvailableAuthTypes = 0; ++ ++ prAisFsmInfo->prTargetBssDesc = (P_BSS_DESC_T) NULL; ++ ++ prAisFsmInfo->ucSeqNumOfReqMsg = 0; ++ prAisFsmInfo->ucSeqNumOfChReq = 0; ++ prAisFsmInfo->ucSeqNumOfScanReq = 0; ++ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++#if CFG_SUPPORT_ROAMING ++ prAisFsmInfo->fgIsRoamingScanPending = FALSE; ++#endif /* CFG_SUPPORT_ROAMING */ ++ prAisFsmInfo->fgIsChannelRequested = FALSE; ++ prAisFsmInfo->fgIsChannelGranted = FALSE; ++ ++ /* 4 <1.1> Initiate FSM - Timer INIT */ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rBGScanTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventBGSleepTimeOut, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rIbssAloneTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventIbssAloneTimeOut, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rIndicationOfDisconnectTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisPostponedEventOfDisconnTimeout, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rJoinTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventJoinTimeout, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rScanDoneTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventScanDoneTimeOut, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rChannelTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventChannelTimeout, (ULONG) NULL); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisFsmInfo->rDeauthDoneTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventDeauthTimeout, (ULONG) NULL); ++ ++ /* 4 <1.2> Initiate PWR STATE */ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); ++ ++ /* 4 <3> Initiate BSS_INFO_T - private part */ ++ /* TODO */ ++ prAisBssInfo->eBand = BAND_2G4; ++ prAisBssInfo->ucPrimaryChannel = 1; ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ ++ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ ++ prAisBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); ++ ++ if (prAisBssInfo->prBeacon) { ++ prAisBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; ++ prAisBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ ++ } else { ++ ASSERT(0); ++ } ++ ++#if 0 ++ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; ++ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; ++ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; ++#else ++ if (prAdapter->u4UapsdAcBmp == 0) { ++ prAdapter->u4UapsdAcBmp = CFG_INIT_UAPSD_AC_BMP; ++ /* ASSERT(prAdapter->u4UapsdAcBmp); */ ++ } ++ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; ++#endif ++ ++ /* request list initialization */ ++ LINK_INITIALIZE(&prAisFsmInfo->rPendingReqList); ++ ++ /* DBGPRINTF("[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", */ ++ /* prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, */ ++ /* prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, */ ++ /* prAisBssInfo->rPmProfSetupInfo.ucUapsdSp); */ ++ ++ /*reset ucScanTimeoutTimes value*/ ++ ucScanTimeoutTimes = 0; ++ ++} /* end of aisFsmInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief the function is used to uninitialize the value in AIS_FSM_INFO_T for ++* AIS FSM operation ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ ++ DEBUGFUNC("aisFsmUninit()"); ++ DBGLOG(SW1, INFO, "->aisFsmUninit()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ ++ /* 4 <1> Stop all timers */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); /* Add by Enlai */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ ++ /* 4 <2> flush pending request */ ++ aisFsmFlushRequest(prAdapter); ++ ++ /* 4 <3> Reset driver-domain BSS-INFO */ ++ if (prAisBssInfo->prBeacon) { ++ cnmMgtPktFree(prAdapter, prAisBssInfo->prBeacon); ++ prAisBssInfo->prBeacon = NULL; ++ } ++#if CFG_SUPPORT_802_11W ++ rsnStopSaQuery(prAdapter); ++#endif ++ ++} /* end of aisFsmUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialization of JOIN STATE ++* ++* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_MSG_JOIN_REQ_T prJoinReqMsg; ++ ++ DEBUGFUNC("aisFsmStateInit_JOIN()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ ASSERT(prBssDesc); ++ ++ /* 4 <1> We are going to connect to this BSS. */ ++ prBssDesc->fgIsConnecting = TRUE; ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_LEGACY_AP, NETWORK_TYPE_AIS_INDEX, prBssDesc); ++ if (prStaRec == NULL) { ++ DBGLOG(AIS, WARN, "Create station record fail\n"); ++ return; ++ } ++ ++ prAisFsmInfo->prTargetStaRec = prStaRec; ++ ++ /* 4 <2.1> sync. to firmware domain */ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ prStaRec->fgIsReAssoc = FALSE; ++ ++ switch (prConnSettings->eAuthMode) { ++ case AUTH_MODE_OPEN: /* Note: Omit break here. */ ++ case AUTH_MODE_WPA: ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA2: ++ case AUTH_MODE_WPA2_PSK: ++ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ break; ++ ++ case AUTH_MODE_SHARED: ++ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; ++ break; ++ ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(AIS, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); ++ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | AUTH_TYPE_SHARED_KEY); ++ break; ++ ++ default: ++ ASSERT(!(prConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); ++ DBGLOG(AIS, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", ++ prConnSettings->eAuthMode); ++ /* TODO(Kevin): error handling ? */ ++ return; ++ } ++ ++ /* TODO(tyhsu): Assume that Roaming Auth Type is equal to ConnSettings eAuthMode */ ++ prAisSpecificBssInfo->ucRoamingAuthTypes = prAisFsmInfo->ucAvailableAuthTypes; ++ ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; ++ ++ } else { ++ ASSERT(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE); ++ ASSERT(!prBssDesc->fgIsConnected); ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: AUTH TYPE = %d for Roaming\n", ++ prAisSpecificBssInfo->ucRoamingAuthTypes); ++ ++ prStaRec->fgIsReAssoc = TRUE; /* We do roaming while the medium is connected */ ++ ++ /* TODO(Kevin): We may call a sub function to acquire the Roaming Auth Type */ ++ prAisFsmInfo->ucAvailableAuthTypes = prAisSpecificBssInfo->ucRoamingAuthTypes; ++ ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING; ++ } ++ ++ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ ++ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { ++ ++ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); ++ ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; ++ } else { ++ ASSERT(0); ++ } ++ ++ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ ++ if (prBssDesc->ucSSIDLen) ++ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ return; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ if (1) { ++ int j; ++ P_FRAG_INFO_T prFragInfo; ++ ++ for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) { ++ prFragInfo = &prStaRec->rFragInfo[j]; ++ ++ if (prFragInfo->pr1stFrag) { ++ /* nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); */ ++ prFragInfo->pr1stFrag = (P_SW_RFB_T) NULL; ++ } ++ } ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++} /* end of aisFsmInit_JOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval TRUE We will retry JOIN ++* @retval FALSE We will not retry JOIN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_JOIN_REQ_T prJoinReqMsg; ++ ++ DEBUGFUNC("aisFsmStateInit_RetryJOIN()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* Retry other AuthType if possible */ ++ if (!prAisFsmInfo->ucAvailableAuthTypes) ++ return FALSE; ++ ++ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(AIS, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else { ++ DBGLOG(AIS, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); ++ ASSERT(0); ++ } ++ ++ prAisFsmInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ ++ ++ /* Trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ return FALSE; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++ return TRUE; ++ ++} /* end of aisFsmRetryJOIN() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief State Initialization of AIS_STATE_IBSS_ALONE ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> Check if IBSS was created before ? */ ++ if (prAisBssInfo->fgIsBeaconActivated) { ++ ++ /* 4 <2> Start IBSS Alone Timer for periodic SCAN and then SEARCH */ ++#if !CFG_SLT_SUPPORT ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); ++#endif ++ } ++ ++ aisFsmCreateIBSS(prAdapter); ++ ++} /* end of aisFsmStateInit_IBSS_ALONE() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief State Initialization of AIS_STATE_IBSS_MERGE ++* ++* @param[in] prBssDesc The pointer of BSS_DESC_T which is the IBSS we will try to merge with. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ ASSERT(prBssDesc); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> We will merge with to this BSS immediately. */ ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); ++ if (prStaRec == NULL) { ++ DBGLOG(AIS, WARN, "Create station record fail\n"); ++ return; ++ } ++ ++ prStaRec->fgIsMerging = TRUE; ++ ++ prAisFsmInfo->prTargetStaRec = prStaRec; ++ ++ /* 4 <2.1> sync. to firmware domain */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* 4 <3> IBSS-Merge */ ++ aisFsmMergeIBSS(prAdapter, prStaRec); ++ ++} /* end of aisFsmStateInit_IBSS_MERGE() */ ++ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of JOIN Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_JOIN_ABORT_T prJoinAbortMsg; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* 1. Abort JOIN process */ ++ prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); ++ if (!prJoinAbortMsg) { ++ ++ ASSERT(0); /* Can't abort SAA FSM */ ++ return; ++ } ++ ++ prJoinAbortMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_ABORT; ++ prJoinAbortMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfReqMsg; ++ prJoinAbortMsg->prStaRec = prAisFsmInfo->prTargetStaRec; ++ ++ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ /* 2. Return channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 3.1 stop join timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ ++ /* 3.2 reset local variable */ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ ++} /* end of aisFsmAbortJOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of SCAN Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* Abort JOIN process. */ ++ prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancelMsg) { ++ ++ ASSERT(0); /* Can't abort SCN FSM */ ++ return; ++ } ++ ++ prScanCancelMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_CANCEL; ++ prScanCancelMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfScanReq; ++ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ prScanCancelMsg->fgIsChannelExt = FALSE; ++#endif ++ ++ /* unbuffered message to guarantee scan is cancelled in sequence */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_UNBUF); ++ ++} /* end of aisFsmAbortSCAN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of NORMAL_TR Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ DBGLOG(AIS, TRACE, "aisFsmStateAbort_NORMAL_TR\n"); ++ ++ /* TODO(Kevin): Do abort other MGMT func */ ++ ++ /* 1. Release channel to CNM */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2.1 stop join timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ ++ /* 2.2 reset local variable */ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ ++} /* end of aisFsmAbortNORMAL_TR() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of NORMAL_TR Abort ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* reset BSS-DESC */ ++ if (prAisFsmInfo->prTargetStaRec) { ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); ++ ++ if (prBssDesc) { ++ prBssDesc->fgIsConnected = FALSE; ++ prBssDesc->fgIsConnecting = FALSE; ++ } ++ } ++ /* release channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ ++} ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The Core FSM engine of AIS(Ad-hoc, Infra STA) ++* ++* @param[in] eNextState Enum value of next AIS STATE ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_DESC_T prBssDesc; ++ P_MSG_CH_REQ_T prMsgChReq; ++ P_MSG_SCN_SCAN_REQ prScanReqMsg; ++ P_AIS_REQ_HDR_T prAisReq; ++ ENUM_BAND_T eBand; ++ UINT_8 ucChannel; ++ UINT_16 u2ScanIELen; ++ ENUM_AIS_STATE_T eOriPreState; ++ ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("aisFsmSteps()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ eOriPreState = prAisFsmInfo->ePreviousState; ++ ++ do { ++ ++ /* Do entering Next State */ ++ prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(AIS, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugAisState[prAisFsmInfo->eCurrentState], apucDebugAisState[eNextState]); ++#else ++ DBGLOG(AIS, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, eNextState); ++#endif ++ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ ++ prAisFsmInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ ++ /* Do tasks of the State that we just entered */ ++ switch (prAisFsmInfo->eCurrentState) { ++ /* NOTE(Kevin): we don't have to rearrange the sequence of following ++ * switch case. Instead I would like to use a common lookup table of array ++ * of function pointer to speed up state search. ++ */ ++ case AIS_STATE_IDLE: ++ ++ prAisReq = aisFsmGetNextRequest(prAdapter); ++ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ ++ if (prAisReq == NULL || prAisReq->eReqType == AIS_REQUEST_RECONNECT) { ++ if (prConnSettings->fgIsConnReqIssued == TRUE && ++ prConnSettings->fgIsDisconnectedByNonRequest == FALSE) { ++ ++ prAisFsmInfo->fgTryScan = TRUE; ++ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* sync with firmware */ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* reset trial count */ ++ prAisFsmInfo->ucConnTrialCount = 0; ++ ++ eNextState = AIS_STATE_SEARCH; ++ fgIsTransition = TRUE; ++ } else { ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* sync with firmware */ ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* check for other pending request */ ++ if (prAisReq && ++ (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE)) { ++ ++ wlanClearScanningResult(prAdapter); ++ eNextState = AIS_STATE_SCAN; ++ ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ if (prAisReq) { ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } ++ } else if (prAisReq->eReqType == AIS_REQUEST_SCAN) { ++#if CFG_SUPPORT_ROAMING ++ prAisFsmInfo->fgIsRoamingScanPending = FALSE; ++#endif /* CFG_SUPPORT_ROAMING */ ++ wlanClearScanningResult(prAdapter); ++ ++ eNextState = AIS_STATE_SCAN; ++ fgIsTransition = TRUE; ++ ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } else if (prAisReq->eReqType == AIS_REQUEST_ROAMING_CONNECT ++ || prAisReq->eReqType == AIS_REQUEST_ROAMING_SEARCH) { ++ /* ignore */ ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } else if (prAisReq->eReqType == AIS_REQUEST_REMAIN_ON_CHANNEL) { ++ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; ++ fgIsTransition = TRUE; ++ ++ /* free the message */ ++ cnmMemFree(prAdapter, prAisReq); ++ } ++ ++ prAisFsmInfo->u4SleepInterval = AIS_BG_SCAN_INTERVAL_MIN_SEC; ++ ++ break; ++ ++ case AIS_STATE_SEARCH: ++ /* 4 <1> Search for a matched candidate and save it to prTargetBssDesc. */ ++#if CFG_SLT_SUPPORT ++ prBssDesc = prAdapter->rWifiVar.rSltInfo.prPseudoBssDesc; ++#else ++ prBssDesc = scanSearchBssDescByPolicy(prAdapter, NETWORK_TYPE_AIS_INDEX); ++#endif ++ /* every time BSS join failure count is integral multiples of SCN_BSS_JOIN_FAIL_THRESOLD, ++ we need to scan again to find if a new BSS is here in the ESS, ++ this can also avoid too frequency to retry the rejected AP */ ++ if (prAisFsmInfo->ePreviousState == AIS_STATE_LOOKING_FOR || ++ ((eOriPreState == AIS_STATE_ONLINE_SCAN || ++ eOriPreState == AIS_STATE_SCAN) && prAisFsmInfo->ePreviousState != eOriPreState)) { ++ /* if previous state is scan/online scan/looking for, don't try to scan again */ ++ } else if (prBssDesc && prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD && ++ ((prBssDesc->ucJoinFailureCount - SCN_BSS_JOIN_FAIL_THRESOLD) % ++ SCN_BSS_JOIN_FAIL_THRESOLD) == 0) ++ prBssDesc = NULL; ++ ++ /* we are under Roaming Condition. */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ if (prAisFsmInfo->ucConnTrialCount > AIS_ROAMING_CONNECTION_TRIAL_LIMIT) { ++#if CFG_SUPPORT_ROAMING ++ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_CONNLIMIT); ++#endif /* CFG_SUPPORT_ROAMING */ ++ /* reset retry count */ ++ prAisFsmInfo->ucConnTrialCount = 0; ++ ++ /* abort connection trial */ ++ prConnSettings->fgIsConnReqIssued = FALSE; ++ ++ eNextState = AIS_STATE_NORMAL_TR; ++ fgIsTransition = TRUE; ++ ++ break; ++ } ++ } ++ /* 4 <2> We are not under Roaming Condition. */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ /* 4 <2.a> If we have the matched one */ ++ if (prBssDesc) { ++ ++ /* 4
Stored the Selected BSS security cipher. ++ For later asoc req compose IE */ ++ prAisBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; ++ prAisBssInfo->u4RsnSelectedPairwiseCipher = ++ prBssDesc->u4RsnSelectedPairwiseCipher; ++ prAisBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; ++ ++ /* 4 Do STATE transition and update current Operation Mode. */ ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; ++ ++ /* Record the target BSS_DESC_T for next STATE. */ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* Transit to channel acquire */ ++ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; ++ fgIsTransition = TRUE; ++ ++ /* increase connection trial count */ ++ prAisFsmInfo->ucConnTrialCount++; ++ } ++#if CFG_SUPPORT_ADHOC ++ else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ ++ /* Record the target BSS_DESC_T for next STATE. */ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ eNextState = AIS_STATE_IBSS_MERGE; ++ fgIsTransition = TRUE; ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ else { ++ ASSERT(0); ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ fgIsTransition = TRUE; ++ } ++ } ++ /* 4 <2.b> If we don't have the matched one */ ++ else { ++ ++ /* increase connection trial count for infrastructure connection */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) ++ prAisFsmInfo->ucConnTrialCount++; ++ /* 4 Try to SCAN */ ++ if (prAisFsmInfo->fgTryScan) { ++ eNextState = AIS_STATE_LOOKING_FOR; ++ ++ fgIsTransition = TRUE; ++ break; ++ } ++ /* 4 We've do SCAN already, now wait in some STATE. */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { ++ ++ /* issue reconnect request, ++ * and retreat to idle state for scheduling */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ eNextState = AIS_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } ++#if CFG_SUPPORT_ADHOC ++ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) ++ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) ++ || (prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ prAisFsmInfo->prTargetBssDesc = NULL; ++ ++ eNextState = AIS_STATE_IBSS_ALONE; ++ fgIsTransition = TRUE; ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ else { ++ ASSERT(0); ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ fgIsTransition = TRUE; ++ } ++ } ++ } ++ /* 4 <3> We are under Roaming Condition. */ ++ else { /* prAdapter->eConnectionState == MEDIA_STATE_CONNECTED. */ ++ ++ /* 4 <3.a> This BSS_DESC_T is our AP. */ ++ /* NOTE(Kevin 2008/05/16): Following cases will go back to NORMAL_TR. ++ * CASE I: During Roaming, APP(WZC/NDISTEST) change the connection ++ * settings. That make we can NOT match the original AP, so the ++ * prBssDesc is NULL. ++ * CASE II: The same reason as CASE I. Because APP change the ++ * eOPMode to other network type in connection setting ++ * (e.g. NET_TYPE_IBSS), so the BssDesc become the IBSS node. ++ * (For CASE I/II, before WZC/NDISTEST set the OID_SSID, it will change ++ * other parameters in connection setting first. So if we do roaming ++ * at the same time, it will hit these cases.) ++ * ++ * CASE III: Normal case, we can't find other candidate to roam ++ * out, so only the current AP will be matched. ++ * ++ * CASE IV: Timestamp of the current AP might be reset ++ */ ++ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION && ++ ((!prBssDesc) || /* CASE I */ ++ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) || /* CASE II */ ++ (prBssDesc->fgIsConnected) || /* CASE III */ ++ (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID))) /* CASE IV */) { ++#if DBG ++ if ((prBssDesc) && (prBssDesc->fgIsConnected)) ++ ASSERT(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); ++#endif /* DBG */ ++ /* We already associated with it, go back to NORMAL_TR */ ++ /* TODO(Kevin): Roaming Fail */ ++#if CFG_SUPPORT_ROAMING ++ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* Retreat to NORMAL_TR state */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ fgIsTransition = TRUE; ++ break; ++ } ++ ++ /* 4 <3.b> Try to roam out for JOIN this BSS_DESC_T. */ ++ if (prBssDesc == NULL) { ++ /* increase connection trial count for infrastructure connection */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) ++ prAisFsmInfo->ucConnTrialCount++; ++ /* 4 Try to SCAN */ ++ if (prAisFsmInfo->fgTryScan) { ++ eNextState = AIS_STATE_LOOKING_FOR; ++ ++ fgIsTransition = TRUE; ++ break; ++ } ++ ++ /* 4 We've do SCAN already, now wait in some STATE. */ ++ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { ++ ++ /* issue reconnect request, and retreat to idle state ++ * for scheduling */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ eNextState = AIS_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } ++#if CFG_SUPPORT_ADHOC ++ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) ++ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) ++ || (prConnSettings->eOPMode == ++ NET_TYPE_DEDICATED_IBSS)) { ++ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ prAisFsmInfo->prTargetBssDesc = NULL; ++ ++ eNextState = AIS_STATE_IBSS_ALONE; ++ fgIsTransition = TRUE; ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ else { ++ ASSERT(0); ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ fgIsTransition = TRUE; ++ } ++ } else { ++#if DBG ++ if (prAisBssInfo->ucReasonOfDisconnect != ++ DISCONNECT_REASON_CODE_REASSOCIATION) { ++ ASSERT(UNEQUAL_MAC_ADDR ++ (prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); ++ } ++#endif /* DBG */ ++ ++ /* 4 Record the target BSS_DESC_T for next STATE. */ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* tyhsu: increase connection trial count */ ++ prAisFsmInfo->ucConnTrialCount++; ++ ++ /* Transit to channel acquire */ ++ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ break; ++ ++ case AIS_STATE_WAIT_FOR_NEXT_SCAN: ++ ++ DBGLOG(AIS, LOUD, "SCAN: Idle Begin - Current Time = %u\n", kalGetTimeTick()); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prAisFsmInfo->rBGScanTimer, SEC_TO_MSEC(prAisFsmInfo->u4SleepInterval)); ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ if (prAisFsmInfo->u4SleepInterval < AIS_BG_SCAN_INTERVAL_MAX_SEC) ++ prAisFsmInfo->u4SleepInterval <<= 1; ++ break; ++ ++ case AIS_STATE_SCAN: ++ case AIS_STATE_ONLINE_SCAN: ++ case AIS_STATE_LOOKING_FOR: ++ ++ if (!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) { ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* sync with firmware */ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ } ++ ++ /* IE length decision */ ++ if (prAisFsmInfo->u4ScanIELength > 0) { ++ u2ScanIELen = (UINT_16) prAisFsmInfo->u4ScanIELength; ++ } else { ++#if CFG_SUPPORT_WPS2 ++ u2ScanIELen = prAdapter->prGlueInfo->u2WSCIELen; ++#else ++ u2ScanIELen = 0; ++#endif ++ } ++ ++ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ OFFSET_OF(MSG_SCN_SCAN_REQ, ++ aucIE) + u2ScanIELen); ++ if (!prScanReqMsg) { ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ return; ++ } ++ ++ prScanReqMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_REQ; ++ prScanReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfScanReq; ++ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ prScanReqMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN; ++#else ++ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++#endif ++ ++#if CFG_SUPPORT_ROAMING_ENC ++ if (prAdapter->fgIsRoamingEncEnabled == TRUE) { ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR && ++ prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ prScanReqMsg->u2ChannelDwellTime = AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME; ++ } ++ } ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN ++ || prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { ++ if (prAisFsmInfo->ucScanSSIDLen == 0) { ++ /* Scan for all available SSID */ ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; ++ } else { ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ COPY_SSID(prScanReqMsg->aucSSID, ++ prScanReqMsg->ucSSIDLength, ++ prAisFsmInfo->aucScanSSID, prAisFsmInfo->ucScanSSIDLen); ++ } ++ } else { ++ /* Scan for determined SSID */ ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ COPY_SSID(prScanReqMsg->aucSSID, ++ prScanReqMsg->ucSSIDLength, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ } ++ ++ /* check if tethering is running and need to fix on specific channel */ ++ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; ++ prScanReqMsg->ucChannelListNum = 1; ++ prScanReqMsg->arChnlInfoList[0].eBand = eBand; ++ prScanReqMsg->arChnlInfoList[0].ucChannelNum = ucChannel; ++ } else { ++#if 0 ++ aisFsmSetChannelInfo(prAdapter, prScanReqMsg, prAisFsmInfo->eCurrentState); ++#endif ++ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_NULL) { ++ if (prAdapter->fgEnable5GBand == TRUE) ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ else ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_2G4) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_5G) { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; ++ } else { ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ ASSERT(0); ++ } ++ ++ } ++ ++ if (prAisFsmInfo->u4ScanIELength > 0) { ++ kalMemCopy(prScanReqMsg->aucIE, prAisFsmInfo->aucScanIEBuf, ++ prAisFsmInfo->u4ScanIELength); ++ } else { ++#if CFG_SUPPORT_WPS2 ++ if (prAdapter->prGlueInfo->u2WSCIELen > 0) { ++ kalMemCopy(prScanReqMsg->aucIE, &prAdapter->prGlueInfo->aucWSCIE, ++ prAdapter->prGlueInfo->u2WSCIELen); ++ } ++ } ++#endif ++ ++ prScanReqMsg->u2IELen = u2ScanIELen; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); ++ DBGLOG(AIS, TRACE, "SendSR%d\n", prScanReqMsg->ucSeqNum); ++ prAisFsmInfo->fgTryScan = FALSE; /* Will enable background sleep for infrastructure */ ++ ++ prAdapter->ucScanTime++; ++ break; ++ ++ case AIS_STATE_REQ_CHANNEL_JOIN: ++ /* send message to CNM for acquiring channel */ ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ return; ++ } ++ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++ prMsgChReq->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; ++ ++ if (prAisFsmInfo->prTargetBssDesc != NULL) { ++ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; ++ prMsgChReq->eRfSco = prAisFsmInfo->prTargetBssDesc->eSco; ++ prMsgChReq->eRfBand = prAisFsmInfo->prTargetBssDesc->eBand; ++ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prAisFsmInfo->prTargetBssDesc->aucBSSID); ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ ++ prAisFsmInfo->fgIsChannelRequested = TRUE; ++ break; ++ ++ case AIS_STATE_JOIN: ++ aisFsmStateInit_JOIN(prAdapter, prAisFsmInfo->prTargetBssDesc); ++ break; ++ ++#if CFG_SUPPORT_ADHOC ++ case AIS_STATE_IBSS_ALONE: ++ aisFsmStateInit_IBSS_ALONE(prAdapter); ++ break; ++ ++ case AIS_STATE_IBSS_MERGE: ++ aisFsmStateInit_IBSS_MERGE(prAdapter, prAisFsmInfo->prTargetBssDesc); ++ break; ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ case AIS_STATE_NORMAL_TR: ++ if (prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { ++ /* Don't do anything when rJoinTimeoutTimer is still ticking */ ++ } else { ++ /* 1. Process for pending scan */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { ++ wlanClearScanningResult(prAdapter); ++ eNextState = AIS_STATE_ONLINE_SCAN; ++ fgIsTransition = TRUE; ++ } ++ /* 2. Process for pending roaming scan */ ++ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE) == TRUE) { ++ eNextState = AIS_STATE_LOOKING_FOR; ++ fgIsTransition = TRUE; ++ } ++ /* 3. Process for pending roaming scan */ ++ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE) == TRUE) { ++ eNextState = AIS_STATE_SEARCH; ++ fgIsTransition = TRUE; ++ } else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE) == ++ TRUE) { ++ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ break; ++ ++ case AIS_STATE_DISCONNECTING: ++ /* send for deauth frame for disconnection */ ++ authSendDeauthFrame(prAdapter, ++ prAisBssInfo->prStaRecOfAP, ++ (P_SW_RFB_T) NULL, REASON_CODE_DEAUTH_LEAVING_BSS, aisDeauthXmitComplete); ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer, 100); ++ break; ++ ++ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: ++ /* send message to CNM for acquiring channel */ ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ return; ++ } ++ ++ /* zero-ize */ ++ kalMemZero(prMsgChReq, sizeof(MSG_CH_REQ_T)); ++ ++ /* filling */ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++ prMsgChReq->u4MaxInterval = prAisFsmInfo->rChReqInfo.u4DurationMs; ++ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->rChReqInfo.ucChannelNum; ++ prMsgChReq->eRfSco = prAisFsmInfo->rChReqInfo.eSco; ++ prMsgChReq->eRfBand = prAisFsmInfo->rChReqInfo.eBand; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ ++ prAisFsmInfo->fgIsChannelRequested = TRUE; ++ ++ break; ++ ++ case AIS_STATE_REMAIN_ON_CHANNEL: ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ /* sync with firmware */ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ break; ++ ++ default: ++ ASSERT(0); /* Make sure we have handle all STATEs */ ++ break; ++ ++ } ++ } while (fgIsTransition); ++ ++ return; ++ ++} /* end of aisFsmSteps() */ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState) ++{ ++ /*get scan channel infro from prAdapter->prGlueInfo->prScanRequest*/ ++ struct cfg80211_scan_request *scan_req_t = NULL; ++ struct ieee80211_channel *channel_tmp = NULL; ++ int i = 0; ++ int j = 0; ++ UINT_8 channel_num = 0; ++ UINT_8 channel_counts = 0; ++ ++ if ((prAdapter == NULL) || (ScanReqMsg == NULL)) ++ return; ++ if ((CurrentState == AIS_STATE_SCAN) || (CurrentState == AIS_STATE_ONLINE_SCAN)) { ++ if (prAdapter->prGlueInfo->prScanRequest != NULL) { ++ scan_req_t = prAdapter->prGlueInfo->prScanRequest; ++ if ((scan_req_t != NULL) && (scan_req_t->n_channels != 0) && ++ (scan_req_t->channels != NULL)) { ++ channel_counts = scan_req_t->n_channels; ++ DBGLOG(AIS, TRACE, "channel_counts=%d\n", channel_counts); ++ ++ while (j < channel_counts) { ++ channel_tmp = scan_req_t->channels[j]; ++ if (channel_tmp == NULL) ++ break; ++ ++ DBGLOG(AIS, TRACE, "set channel band=%d\n", channel_tmp->band); ++ if (channel_tmp->band >= IEEE80211_BAND_60GHZ) { ++ j++; ++ continue; ++ } ++ if (i >= MAXIMUM_OPERATION_CHANNEL_LIST) ++ break; ++ if (channel_tmp->band == IEEE80211_BAND_2GHZ) ++ ScanReqMsg->arChnlInfoList[i].eBand = BAND_2G4; ++ else if (channel_tmp->band == IEEE80211_BAND_5GHZ) ++ ScanReqMsg->arChnlInfoList[i].eBand = BAND_5G; ++ ++ DBGLOG(AIS, TRACE, "set channel channel_rer =%d\n", ++ channel_tmp->center_freq); ++ ++ channel_num = (UINT_8)nicFreq2ChannelNum( ++ channel_tmp->center_freq * 1000); ++ ++ DBGLOG(AIS, TRACE, "set channel channel_num=%d\n", ++ channel_num); ++ ScanReqMsg->arChnlInfoList[i].ucChannelNum = channel_num; ++ ++ j++; ++ i++; ++ } ++ } ++ } ++ } ++ ++ DBGLOG(AIS, INFO, "set channel i=%d\n", i); ++ if (i > 0) { ++ ScanReqMsg->ucChannelListNum = i; ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; ++ ++ return; ++ } ++ ++ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_NULL) { ++ if (prAdapter->fgEnable5GBand == TRUE) ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ else ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_2G4) { ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] ++ == BAND_5G) { ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; ++ } else { ++ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; ++ ASSERT(0); ++ } ++ ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ UINT_8 ucSeqNumOfCompMsg; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("aisFsmRunEventScanDone()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ ucScanTimeoutTimes = 0; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ ASSERT(prScanDoneMsg->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX); ++ ++ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ if (ucSeqNumOfCompMsg != prAisFsmInfo->ucSeqNumOfScanReq) { ++ DBGLOG(AIS, WARN, "SEQ NO of AIS SCN DONE MSG is not matched %d %d.\n", ++ ucSeqNumOfCompMsg, prAisFsmInfo->ucSeqNumOfScanReq); ++ } else { ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_SCAN: ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ ++ /* reset scan IE buffer */ ++ prAisFsmInfo->u4ScanIELength = 0; ++ ++ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); ++ eNextState = AIS_STATE_IDLE; ++#if CFG_SUPPORT_AGPS_ASSIST ++ scanReportScanResultToAgps(prAdapter); ++#endif ++ break; ++ ++ case AIS_STATE_ONLINE_SCAN: ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ ++ /* reset scan IE buffer */ ++ prAisFsmInfo->u4ScanIELength = 0; ++ ++ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); ++#if CFG_SUPPORT_ROAMING ++ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); ++#else ++ eNextState = AIS_STATE_NORMAL_TR; ++#endif /* CFG_SUPPORT_ROAMING */ ++#if CFG_SUPPORT_AGPS_ASSIST ++ scanReportScanResultToAgps(prAdapter); ++#endif ++ break; ++ ++ case AIS_STATE_LOOKING_FOR: ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ scanReportBss2Cfg80211(prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); ++#if CFG_SUPPORT_ROAMING ++ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); ++#else ++ eNextState = AIS_STATE_SEARCH; ++#endif /* CFG_SUPPORT_ROAMING */ ++ break; ++ ++ default: ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ break; ++ ++ } ++ } ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmRunEventScanDone() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ UINT_8 ucReasonOfDisconnect; ++ BOOLEAN fgDelayIndication; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("aisFsmRunEventAbort()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> Extract information of Abort Message and then free memory. */ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) prMsgHdr; ++ ucReasonOfDisconnect = prAisAbortMsg->ucReasonOfDisconnect; ++ fgDelayIndication = prAisAbortMsg->fgDelayIndication; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++#if DBG ++ DBGLOG(AIS, STATE, "EVENT-ABORT: Current State %s %d\n", ++ apucDebugAisState[prAisFsmInfo->eCurrentState], ucReasonOfDisconnect); ++#else ++ DBGLOG(AIS, STATE, "[%d] EVENT-ABORT: Current State [%d %d]\n", ++ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, ucReasonOfDisconnect); ++#endif ++ ++ GET_CURRENT_SYSTIME(&(prAisFsmInfo->rJoinReqTime)); ++ ++ /* 4 <2> clear previous pending connection request and insert new one */ ++ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DEAUTHENTICATED ++ || ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DISASSOCIATED) { ++ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; ++ } else { ++ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; ++ } ++ /* to support user space triggered roaming */ ++ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING && ++ prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && ++ prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { ++ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); ++ } else { ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_ROAMING_CONNECT); ++ } ++ return; ++ } ++ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ if (prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { ++ /* 4 <3> invoke abort handler */ ++ aisFsmStateAbort(prAdapter, ucReasonOfDisconnect, fgDelayIndication); ++ } ++ ++} /* end of aisFsmRunEventAbort() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function handles AIS-FSM abort event/command ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ucReasonOfDisconnect Reason for disonnection ++* fgDelayIndication Option to delay disconnection indication ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ BOOLEAN fgIsCheckConnected; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ fgIsCheckConnected = FALSE; ++ ++ /* 4 <1> Save information of Abort Message and then free memory. */ ++ prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect; ++ ++ /* 4 <2> Abort current job. */ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IDLE: ++ case AIS_STATE_SEARCH: ++ break; ++ ++ case AIS_STATE_WAIT_FOR_NEXT_SCAN: ++ /* Do cancel timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_SCAN: ++ /* Do abort SCAN */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* queue for later handling */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ ++ break; ++ ++ case AIS_STATE_LOOKING_FOR: ++ /* Do abort SCAN */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_REQ_CHANNEL_JOIN: ++ /* Release channel to CNM */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_JOIN: ++ /* Do abort JOIN */ ++ aisFsmStateAbort_JOIN(prAdapter); ++ ++ /* in case roaming is triggered */ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++#if CFG_SUPPORT_ADHOC ++ case AIS_STATE_IBSS_ALONE: ++ case AIS_STATE_IBSS_MERGE: ++ aisFsmStateAbort_IBSS(prAdapter); ++ break; ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ case AIS_STATE_ONLINE_SCAN: ++ /* Do abort SCAN */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* queue for later handling */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_NORMAL_TR: ++ fgIsCheckConnected = TRUE; ++ break; ++ ++ case AIS_STATE_DISCONNECTING: ++ /* Do abort NORMAL_TR */ ++ aisFsmStateAbort_NORMAL_TR(prAdapter); ++ ++ break; ++ ++ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: ++ /* release channel */ ++ aisFsmReleaseCh(prAdapter); ++ break; ++ ++ case AIS_STATE_REMAIN_ON_CHANNEL: ++ /* 1. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2. stop channel timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (fgIsCheckConnected && (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState)) { ++ ++ /* switch into DISCONNECTING state for sending DEAUTH if necessary */ ++ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && ++ prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_NEW_CONNECTION && ++ prAisBssInfo->prStaRecOfAP && prAisBssInfo->prStaRecOfAP->fgIsInUse) { ++ aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING); ++ ++ return; ++ } ++ /* Do abort NORMAL_TR */ ++ aisFsmStateAbort_NORMAL_TR(prAdapter); ++ ++ } ++ ++ aisFsmDisconnect(prAdapter, fgDelayIndication); ++ ++ ++} /* end of aisFsmStateAbort() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Join Complete Event from SAA FSM for AIS FSM ++* ++* @param[in] prMsgHdr Message of Join Complete of SAA FSM. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_JOIN_COMP_T prJoinCompMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prAssocRspSwRfb; ++ P_BSS_INFO_T prAisBssInfo; ++ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; ++ OS_SYSTIME rCurrentTime; ++ ++ DEBUGFUNC("aisFsmRunEventJoinComplete()"); ++ ++ ASSERT(prMsgHdr); ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; ++ prStaRec = prJoinCompMsg->prStaRec; ++ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ DBGLOG(AIS, TRACE, "AISOK\n"); ++ ++ /* Check State and SEQ NUM */ ++ do { ++ if (prAisFsmInfo->eCurrentState != AIS_STATE_JOIN) ++ break; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* Check SEQ NUM */ ++ if (prJoinCompMsg->ucSeqNum == prAisFsmInfo->ucSeqNumOfReqMsg) { ++ ++ /* 4 <1> JOIN was successful */ ++ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { ++ ++ /* 1. Reset retry count */ ++ prAisFsmInfo->ucConnTrialCount = 0; ++ ++ /* Completion of roaming */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ ++#if CFG_SUPPORT_ROAMING ++ /* 2. Deactivate previous BSS */ ++ aisFsmRoamingDisconnectPrevAP(prAdapter, prStaRec); ++ ++ /* 3. Update bss based on roaming staRec */ ++ aisUpdateBssInfoForRoamingAP(prAdapter, prStaRec, prAssocRspSwRfb); ++#endif /* CFG_SUPPORT_ROAMING */ ++ } else { ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if ((prAisBssInfo->prStaRecOfAP) && ++ (prAisBssInfo->prStaRecOfAP != prStaRec) && ++ (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { ++ ++ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, ++ STA_STATE_1); ++ } ++ /* 4 <1.3> Update BSS_INFO_T */ ++ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); ++ ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ /* 4 <1.5> Update RSSI if necessary */ ++ nicUpdateRSSI(prAdapter, NETWORK_TYPE_AIS_INDEX, ++ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); ++ ++ /* 4 <1.6> Indicate Connected Event to Host immediately. */ ++ /* Require BSSID, Association ID, Beacon Interval.. */ ++ /* from AIS_BSS_INFO_T */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, ++ FALSE); ++ ++ /* add for ctia mode */ ++ if (EQUAL_SSID ++ (aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, ++ prAisBssInfo->ucSSIDLen)) { ++ nicEnterCtiaMode(prAdapter, TRUE, FALSE); ++ } ++ } ++ ++#if CFG_SUPPORT_ROAMING ++ /* if bssid is given, it means we no need fw roaming */ ++ if (prAdapter->rWifiVar.rConnSettings.eConnectionPolicy != CONNECT_BY_BSSID) ++ roamingFsmRunEventStart(prAdapter); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* 4 <1.7> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ } ++ /* 4 <2> JOIN was not successful */ ++ else { ++ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ ++ if (aisFsmStateInit_RetryJOIN(prAdapter, prStaRec) == FALSE) { ++ P_BSS_DESC_T prBssDesc; ++ ++ /* 1. Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ /* 2. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 3.1 stop join timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); ++ ++ /* 3.2 reset local variable */ ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prStaRec->aucMacAddr); ++ ++ if (prBssDesc == NULL) { ++ /* it maybe NULL when wlanRemove */ ++ /* ++ (1) UI does wifi off during SAA does auth/assoc procedure. ++ (2) We will do LINK_INITIALIZE(&prScanInfo->rBSSDescList); ++ in nicUninitMGMT(). ++ (3) We will handle prMsduInfo->pfTxDoneHandler ++ in nicTxRelease(). ++ (4) prMsduInfo->pfTxDoneHandler will point to ++ saaFsmRunEventTxDone(). ++ (5) Then jump to saaFsmSteps() -> saaFsmSendEventJoinComplete() ++ (6) Finally mboxSendMsg() -> aisFsmRunEventJoinComplete(). ++ (7) In aisFsmRunEventJoinComplete(), we will check ++ "prBssDesc = scanSearchBssDescByBssid(prAdapter, ++ prStaRec->aucMacAddr);" ++ (8) And prBssDesc will be NULL and hangs in ++ "ASSERT(prBssDesc->fgIsConnecting);" when DBG=0. ++ ASSERT(prBssDesc); ++ ASSERT(prBssDesc->fgIsConnecting); ++ */ ++ break; ++ } ++ /* ASSERT(prBssDesc); */ ++ /* ASSERT(prBssDesc->fgIsConnecting); */ ++ prBssDesc->ucJoinFailureCount++; ++ if (prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { ++ GET_CURRENT_SYSTIME(&prBssDesc->rJoinFailTime); ++ DBGLOG(AIS, INFO, ++ "Bss %pM join fail %d times,temp disable it at time:%u\n", ++ prBssDesc->aucBSSID, ++ SCN_BSS_JOIN_FAIL_THRESOLD, prBssDesc->rJoinFailTime); ++ } ++ ++ if (prBssDesc) ++ prBssDesc->fgIsConnecting = FALSE; ++ ++ /* 3.3 Free STA-REC */ ++ if (prStaRec != prAisBssInfo->prStaRecOfAP) ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++#if CFG_SUPPORT_ROAMING ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++#endif /* CFG_SUPPORT_ROAMING */ ++ } else if (CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, ++ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { ++ /* abort connection trial */ ++ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_CONNECT_INDICATION, NULL, 0); ++ ++ eNextState = AIS_STATE_IDLE; ++ } else { ++ /* 4.b send reconnect request */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ ++ eNextState = AIS_STATE_IDLE; ++ } ++ } ++ } ++ } ++#if DBG ++ else ++ DBGLOG(AIS, WARN, "SEQ NO of AIS JOIN COMP MSG is not matched.\n"); ++#endif /* DBG */ ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ } while (FALSE); ++ ++ if (prAssocRspSwRfb) ++ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* end of aisFsmRunEventJoinComplete() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Grant Msg of IBSS Create which was sent by ++* CNM to indicate that channel was changed for creating IBSS. ++* ++* @param[in] prAdapter Pointer of ADAPTER_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ do { ++ /* Check State */ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_IBSS_ALONE) ++ aisUpdateBssInfoForCreateIBSS(prAdapter); ++ } while (FALSE); ++ ++} /* end of aisFsmCreateIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Grant Msg of IBSS Merge which was sent by ++* CNM to indicate that channel was changed for merging IBSS. ++* ++* @param[in] prAdapter Pointer of ADAPTER_T ++* @param[in] prStaRec Pointer of STA_RECORD_T for merge ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ do { ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IBSS_MERGE: ++ { ++ P_BSS_DESC_T prBssDesc; ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous Peers' STA_RECORD_T in Driver if have. */ ++ bssClearClientList(prAdapter, prAisBssInfo); ++ ++ /* 4 <1.3> Unmark connection flag of previous BSS_DESC_T. */ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ if (prBssDesc != NULL) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = FALSE; ++ } ++ /* 4 <1.4> Update BSS_INFO_T */ ++ aisUpdateBssInfoForMergeIBSS(prAdapter, prStaRec); ++ ++ /* 4 <1.5> Add Peers' STA_RECORD_T to Client List */ ++ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); ++ ++ /* 4 <1.6> Activate current Peer's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ prStaRec->fgIsMerging = FALSE; ++ ++ /* 4 <1.7> Enable other features */ ++ ++ /* 4 <1.8> Indicate Connected Event to Host immediately. */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); ++ ++ /* 4 <1.9> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ ++ /* 4 <1.10> Release channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ ++#if CFG_SLT_SUPPORT ++ prAdapter->rWifiVar.rSltInfo.prPseudoStaRec = prStaRec; ++#endif ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++ } while (FALSE); ++ ++} /* end of aisFsmMergeIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Notification of existing IBSS was found ++* from SCN. ++* ++* @param[in] prMsgHdr Message of Notification of an IBSS was present. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prAisBssInfo; ++ P_BSS_DESC_T prBssDesc; ++ BOOLEAN fgIsMergeIn; ++ ++ ASSERT(prMsgHdr); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) prMsgHdr; ++ ++ ASSERT(prAisIbssPeerFoundMsg->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX); ++ ++ prStaRec = prAisIbssPeerFoundMsg->prStaRec; ++ ASSERT(prStaRec); ++ ++ fgIsMergeIn = prAisIbssPeerFoundMsg->fgIsMergeIn; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IBSS_ALONE: ++ { ++ /* 4 <1> An IBSS Peer 'merged in'. */ ++ if (fgIsMergeIn) { ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Add Peers' STA_RECORD_T to Client List */ ++ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); ++ ++#if CFG_SLT_SUPPORT ++ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ if (prBssDesc != NULL) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ } else { ++ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ ++ } ++ ++ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ ++#else ++ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ if (prBssDesc != NULL) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ } else { ++ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ ++ } ++ ++ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ ++ ++#endif ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ prStaRec->fgIsMerging = FALSE; ++ ++ /* 4 <1.6> sync. to firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <1.7> Indicate Connected Event to Host immediately. */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); ++ ++ /* 4 <1.8> indicate PM for connected */ ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <1.9> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_NORMAL_TR; ++ ++ /* 4 <1.10> Release channel privilege */ ++ aisFsmReleaseCh(prAdapter); ++ } ++ /* 4 <2> We need 'merge out' to this IBSS */ ++ else { ++ ++ /* 4 <2.1> Get corresponding BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* 4 <2.2> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_IBSS_MERGE; ++ } ++ } ++ break; ++ ++ case AIS_STATE_NORMAL_TR: ++ { ++ ++ /* 4 <3> An IBSS Peer 'merged in'. */ ++ if (fgIsMergeIn) { ++ ++ /* 4 <3.1> Add Peers' STA_RECORD_T to Client List */ ++ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); ++ ++#if CFG_SLT_SUPPORT ++ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ ++#else ++ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ ++ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ ++#endif ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ prStaRec->fgIsMerging = FALSE; ++ ++ } ++ /* 4 <4> We need 'merge out' to this IBSS */ ++ else { ++ ++ /* 4 <4.1> Get corresponding BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ ++ prAisFsmInfo->prTargetBssDesc = prBssDesc; ++ ++ /* 4 <4.2> Set the Next State of AIS FSM */ ++ eNextState = AIS_STATE_IBSS_MERGE; ++ ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmRunEventFoundIBSSPeer() */ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Media State to HOST ++* ++* @param[in] eConnectionState Current Media State ++* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, ++ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication) ++{ ++ EVENT_CONNECTION_STATUS rEventConnStatus; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ DEBUGFUNC("aisIndicationOfMediaStateToHost()"); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* NOTE(Kevin): Move following line to aisChangeMediaState() macro per CM's request. */ ++ /* prAisBssInfo->eConnectionState = eConnectionState; */ ++ ++ /* For indicating the Disconnect Event only if current media state is ++ * disconnected and we didn't do indication yet. ++ */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ if (prAisBssInfo->eConnectionStateIndicated == eConnectionState) ++ return; ++ } ++ ++ if (!fgDelayIndication) { ++ /* 4 <0> Cancel Delay Timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); ++ ++ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ ++ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; ++ ++ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; ++ ++ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; ++ rEventConnStatus.u2AID = prAisBssInfo->u2AssocId; ++ rEventConnStatus.u2ATIMWindow = 0; ++ } else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; ++ rEventConnStatus.u2AID = 0; ++ rEventConnStatus.u2ATIMWindow = prAisBssInfo->u2ATIMWindow; ++ } else { ++ ASSERT(0); ++ } ++ ++ COPY_SSID(rEventConnStatus.aucSsid, ++ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prAisBssInfo->aucBSSID); ++ ++ rEventConnStatus.u2BeaconPeriod = prAisBssInfo->u2BeaconInterval; ++ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prAisBssInfo->ucPrimaryChannel); ++ ++ switch (prAisBssInfo->ucNonHTBasicPhyType) { ++ case PHY_TYPE_HR_DSSS_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ ++ case PHY_TYPE_ERP_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; ++ break; ++ ++ case PHY_TYPE_OFDM_INDEX: ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; ++ break; ++ ++ default: ++ ASSERT(0); ++ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; ++ break; ++ } ++ } else { ++ /* Deactivate previous Peers' STA_RECORD_T in Driver if have. */ ++ bssClearClientList(prAdapter, prAisBssInfo); ++ ++#if CFG_PRIVACY_MIGRATION ++ /* Clear the pmkid cache while media disconnect */ ++ secClearPmkid(prAdapter); ++#endif ++ ++ rEventConnStatus.ucReasonOfDisconnect = prAisBssInfo->ucReasonOfDisconnect; ++ } ++ ++ /* 4 <2> Indication */ ++ nicMediaStateChange(prAdapter, NETWORK_TYPE_AIS_INDEX, &rEventConnStatus); ++ prAisBssInfo->eConnectionStateIndicated = eConnectionState; ++ } else { ++ /* NOTE: Only delay the Indication of Disconnect Event */ ++ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ DBGLOG(AIS, INFO, "Postpone the indication of Disconnect for %d seconds\n", ++ prConnSettings->ucDelayTimeOfDisconnectEvent); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prAisFsmInfo->rIndicationOfDisconnectTimer, ++ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); ++ } ++ ++} /* end of aisIndicationOfMediaStateToHost() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Media Disconnect" to HOST ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if (prAisBssInfo->prStaRecOfAP) { ++ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ ++ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ } ++ /* 4 <2> Remove pending connection request */ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); ++ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; ++ prAisBssInfo->u2DeauthReason = REASON_CODE_BEACON_TIMEOUT; ++ /* 4 <3> Indicate Disconnected Event to Host immediately. */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE); ++ ++} /* end of aisPostponedEventOfDisconnTimeout() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the association was completed. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ P_BSS_DESC_T prBssDesc; ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ ++ DEBUGFUNC("aisUpdateBssInfoForJOIN()"); ++ ++ ASSERT(prStaRec); ++ ASSERT(prAssocRspSwRfb); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; ++ ++ DBGLOG(AIS, TRACE, "Update AIS_BSS_INFO_T and apply settings to MAC\n"); ++ ++ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ /* 4 <1.3> Setup Channel, Band */ ++ prAisBssInfo->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; ++ prAisBssInfo->eBand = prAisFsmInfo->prTargetBssDesc->eBand; ++ ++ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ ++ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ ++ prAisBssInfo->prStaRecOfAP = prStaRec; ++ prAisBssInfo->u2AssocId = prStaRec->u2AssocId; ++ ++ /* 4 <2.2> Setup Capability */ ++ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ ++ ++ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) ++ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; ++ else ++ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* init the TDLS flags */ ++ prAisBssInfo->fgTdlsIsProhibited = prStaRec->fgTdlsIsProhibited; ++ prAisBssInfo->fgTdlsIsChSwProhibited = prStaRec->fgTdlsIsChSwProhibited; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ ++ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; ++ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ ++ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ ++ /* 4 <3.1> Setup BSSID */ ++ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); ++ ++ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - ++ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); ++ pucIE = prAssocRspFrame->aucInfoElem; ++ ++ /* 4 <3.2> Parse WMM and setup QBSS flag */ ++ /* Parse WMM related IEs and configure HW CRs accordingly */ ++ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ prAisBssInfo->fgIsQBSS = prStaRec->fgIsQoS; ++ ++ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAssocRspFrame->aucBSSID); ++ if (prBssDesc) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ prBssDesc->ucJoinFailureCount = 0; ++ ++ /* 4 <4.1> Setup MIB for current BSS */ ++ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ } else { ++ /* should never happen */ ++ ASSERT(0); ++ } ++ ++ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ ++ prAisBssInfo->ucDTIMPeriod = 0; ++ prAisBssInfo->u2ATIMWindow = 0; ++ ++ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; ++ ++ /* 4 <4.2> Update HT information and set channel */ ++ /* Record HT related parameters in rStaRec and rBssInfo ++ * Note: it shall be called before nicUpdateBss() ++ */ ++ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ /* 4 <4.3> Sync with firmware for BSS-INFO */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ ++ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ ++ ++} /* end of aisUpdateBssInfoForJOIN() */ ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will create an Ad-Hoc network and start sending Beacon Frames. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ if (prAisBssInfo->fgIsBeaconActivated) ++ return; ++ /* 3 <1> Update BSS_INFO_T per Network Basis */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prAisBssInfo->u2AssocId = 0; ++ ++ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ ++ prAisBssInfo->ucPrimaryChannel = prConnSettings->ucAdHocChannelNum; ++ prAisBssInfo->eBand = prConnSettings->eAdHocBand; ++ ++ if (prAisBssInfo->eBand == BAND_2G4) { ++ /* Depend on eBand */ ++ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG; ++ } else { ++ /* Depend on eBand */ ++ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN; ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A; ++ } ++ ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prAisBssInfo->u2BeaconInterval = prConnSettings->u2BeaconPeriod; ++ prAisBssInfo->ucDTIMPeriod = 0; ++ prAisBssInfo->u2ATIMWindow = prConnSettings->u2AtimWindow; ++ ++ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; ++ ++#if CFG_PRIVACY_MIGRATION ++ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED || ++ prConnSettings->eEncStatus == ENUM_ENCRYPTION2_ENABLED || ++ prConnSettings->eEncStatus == ENUM_ENCRYPTION3_ENABLED) { ++ prAisBssInfo->fgIsProtection = TRUE; ++ } else { ++ prAisBssInfo->fgIsProtection = FALSE; ++ } ++#else ++ prAisBssInfo->fgIsProtection = FALSE; ++#endif ++ ++ /* 3 <2> Update BSS_INFO_T common part */ ++ ibssInitForAdHoc(prAdapter, prAisBssInfo); ++ ++ /* 3 <3> Set MAC HW */ ++ /* 4 <3.1> Setup channel and bandwidth */ ++ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); ++ ++ /* 4 <3.2> use command packets to inform firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <3.3> enable beaconing */ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <3.4> Update AdHoc PM parameter */ ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 3 <4> Set ACTIVE flag. */ ++ prAisBssInfo->fgIsBeaconActivated = TRUE; ++ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; ++ ++ /* 3 <5> Start IBSS Alone Timer */ ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); ++ ++ return; ++ ++} /* end of aisCreateIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the existing IBSS was found. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_DESC_T prBssDesc; ++ /* UINT_16 u2IELength; */ ++ /* PUINT_8 pucIE; */ ++ ++ ASSERT(prStaRec); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); ++ ++ if (!prAisBssInfo->fgIsBeaconActivated) { ++ ++ /* 3 <1> Update BSS_INFO_T per Network Basis */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prAisBssInfo->aucSSID, ++ prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prAisBssInfo->u2AssocId = 0; ++ } ++ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ ++ /* 4 <2.1> Setup Capability */ ++ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use Peer's Cap Info as IBSS Cap Info */ ++ ++ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) { ++ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; ++ prAisBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prAisBssInfo->fgUseShortPreamble = FALSE; ++ } ++ ++ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ ++ prAisBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ ++ prAisBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; ++ ++ if (prAisBssInfo->u2CapInfo & CAP_INFO_PRIVACY) ++ prAisBssInfo->fgIsProtection = TRUE; ++ else ++ prAisBssInfo->fgIsProtection = FALSE; ++ ++ /* 4 <2.2> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ ++ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; ++ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ ++ rateGetDataRatesFromRateSet(prAisBssInfo->u2OperationalRateSet, ++ prAisBssInfo->u2BSSBasicRateSet, ++ prAisBssInfo->aucAllSupportedRates, &prAisBssInfo->ucAllSupportedRatesLen); ++ ++ /* 3 <3> X Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ ++ ++ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ ++ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); ++ if (prBssDesc) { ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ ++ /* 4 <4.1> Setup BSSID */ ++ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prBssDesc->aucBSSID); ++ ++ /* 4 <4.2> Setup Channel, Band */ ++ prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; ++ prAisBssInfo->eBand = prBssDesc->eBand; ++ ++ /* 4 <4.3> Setup MIB for current BSS */ ++ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ prAisBssInfo->ucDTIMPeriod = 0; ++ prAisBssInfo->u2ATIMWindow = 0; /* TBD(Kevin) */ ++ ++ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; ++ } else { ++ /* should never happen */ ++ ASSERT(0); ++ } ++ ++ /* 3 <5> Set MAC HW */ ++ /* 4 <5.1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ ++ { ++ UINT_8 ucLowestBasicRateIndex; ++ ++ if (!rateGetLowestRateIndexFromRateSet(prAisBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) { ++ ++ if (prAisBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_OFDM) ++ ucLowestBasicRateIndex = RATE_6M_INDEX; ++ else ++ ucLowestBasicRateIndex = RATE_1M_INDEX; ++ } ++ ++ prAisBssInfo->ucHwDefaultFixedRateCode = ++ aucRateIndex2RateCode[prAisBssInfo->fgUseShortPreamble][ucLowestBasicRateIndex]; ++ } ++ ++ /* 4 <5.2> Setup channel and bandwidth */ ++ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); ++ ++ /* 4 <5.3> use command packets to inform firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <5.4> enable beaconing */ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 4 <5.5> Update AdHoc PM parameter */ ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* 3 <6> Set ACTIVE flag. */ ++ prAisBssInfo->fgIsBeaconActivated = TRUE; ++ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; ++ ++} /* end of aisUpdateBssInfoForMergeIBSS() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ BOOLEAN fgReplyProbeResp = FALSE; ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu4ControlFlags); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) prSwRfb->pvHeader + prSwRfb->u2HeaderLen; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_SSID == IE_ID(pucIE)) { ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* 4 <2> Check network conditions */ ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ ++ if ((prIeSsid) && ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, /* CURRENT SSID */ ++ prIeSsid->aucSSID, prIeSsid->ucLength))) { ++ fgReplyProbeResp = TRUE; ++ } ++ } ++ ++ return fgReplyProbeResp; ++ ++} /* end of aisValidateProbeReq() */ ++ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will modify and update necessary information to firmware ++* for disconnection handling ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* ++* @retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++#if CFG_SUPPORT_ADHOC ++ if (prAisBssInfo->fgIsBeaconActivated) { ++ nicUpdateBeaconIETemplate(prAdapter, IE_UPD_METHOD_DELETE_ALL, NETWORK_TYPE_AIS_INDEX, 0, NULL, 0); ++ ++ prAisBssInfo->fgIsBeaconActivated = FALSE; ++ } ++#endif ++ ++ rlmBssAborted(prAdapter, prAisBssInfo); ++ ++ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ ++ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { ++ /* add for ctia mode */ ++ { ++ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; ++ ++ if (EQUAL_SSID(aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) ++ nicEnterCtiaMode(prAdapter, FALSE, FALSE); ++ } ++ ++ if (prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_RADIO_LOST) { ++ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ ++ /* remove from scanning results as well */ ++ wlanClearBssInScanningResult(prAdapter, prAisBssInfo->aucBSSID); ++ ++ /* trials for re-association */ ++ if (fgDelayIndication) { ++ DBGLOG(AIS, INFO, "try to do re-association due to radio lost!\n"); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); ++ } ++ } else { ++ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ } ++ ++ if (fgDelayIndication) { ++ if (OP_MODE_IBSS != prAisBssInfo->eCurrentOPMode) ++ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; ++ } else { ++ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; ++ } ++ } else { ++ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; ++ } ++ ++ /* 4 <4> Change Media State immediately. */ ++ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION) { ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ /* 4 <4.1> sync. with firmware */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ } ++ ++ if (!fgDelayIndication) { ++ /* 4 <5> Deactivate previous AP's STA_RECORD_T or all Clients in Driver if have. */ ++ if (prAisBssInfo->prStaRecOfAP) { ++ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ ++ ++ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ } ++ } ++#if CFG_SUPPORT_ROAMING ++ roamingFsmRunEventAbort(prAdapter); ++ ++ /* clear pending roaming connection request */ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* 4 <6> Indicate Disconnected Event to Host */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, fgDelayIndication); ++ ++ /* 4 <7> Trigger AIS FSM */ ++ aisFsmSteps(prAdapter, AIS_STATE_IDLE); ++ ++} /* end of aisFsmDisconnect() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of Scan done Time-Out to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 IsrCnt = 0, IsrPassCnt = 0, TaskIsrCnt = 0; ++VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++#define SCAN_DONE_TIMEOUT_TIMES_LIMIT 20 ++ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4FwCnt; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DEBUGFUNC("aisFsmRunEventScanDoneTimeOut()"); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ HifInfo = &prAdapter->prGlueInfo->rHifInfo; ++ ++ DBGLOG(AIS, WARN, "aisFsmRunEventScanDoneTimeOut Current[%d], ucScanTimeoutTimes=%d\n", ++ prAisFsmInfo->eCurrentState, ucScanTimeoutTimes); ++ DBGLOG(AIS, WARN, "Isr/task %u %u %u (0x%x)\n", prGlueInfo->IsrCnt, prGlueInfo->IsrPassCnt, ++ prGlueInfo->TaskIsrCnt, prAdapter->fgIsIntEnable); ++ ++ /* dump firmware program counter */ ++ DBGLOG(AIS, WARN, "CONNSYS FW CPUINFO:\n"); ++ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) ++ DBGLOG(AIS, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); ++ ++ ucScanTimeoutTimes++; ++ if (ucScanTimeoutTimes > SCAN_DONE_TIMEOUT_TIMES_LIMIT) { ++ kalSendAeeWarning("[Scan done timeout more than 20 times!]", __func__); ++ glDoChipReset(); ++ } ++#if 0 /* ALPS02018734: remove trigger assert */ ++ if (prAdapter->fgTestMode == FALSE) { ++ /* Titus - xxx */ ++ /* assert if and only if in normal mode */ ++ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); ++ } ++#endif ++ /* report all scanned frames to upper layer to avoid scanned frame is timeout */ ++ /* must be put before kalScanDone */ ++/* scanReportBss2Cfg80211(prAdapter,BSS_TYPE_INFRASTRUCTURE,NULL); */ ++ ++ prConnSettings->fgIsScanReqIssued = FALSE; ++ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_SCAN: ++ prAisFsmInfo->u4ScanIELength = 0; ++ eNextState = AIS_STATE_IDLE; ++ break; ++ case AIS_STATE_ONLINE_SCAN: ++ /* reset scan IE buffer */ ++ prAisFsmInfo->u4ScanIELength = 0; ++#if CFG_SUPPORT_ROAMING ++ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); ++#else ++ eNextState = AIS_STATE_NORMAL_TR; ++#endif /* CFG_SUPPORT_ROAMING */ ++ break; ++ default: ++ break; ++ } ++ ++ /* try to stop scan in CONNSYS */ ++ aisFsmStateAbort_SCAN(prAdapter); ++ ++ /* wlanQueryDebugCode(prAdapter); */ /* display current SCAN FSM in FW, debug use */ ++ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmBGSleepTimeout() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Background Scan Time-Out" to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ ++ DEBUGFUNC("aisFsmRunEventBGSleepTimeOut()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_WAIT_FOR_NEXT_SCAN: ++ DBGLOG(AIS, LOUD, "EVENT - SCAN TIMER: Idle End - Current Time = %u\n", kalGetTimeTick()); ++ ++ eNextState = AIS_STATE_LOOKING_FOR; ++ ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Call aisFsmSteps() when we are going to change AIS STATE */ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmBGSleepTimeout() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "IBSS ALONE Time-Out" to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ ++ DEBUGFUNC("aisFsmRunEventIbssAloneTimeOut()"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_IBSS_ALONE: ++ ++ /* There is no one participate in our AdHoc during this TIMEOUT Interval ++ * so go back to search for a valid IBSS again. ++ */ ++ ++ DBGLOG(AIS, LOUD, "EVENT-IBSS ALONE TIMER: Start pairing\n"); ++ ++ prAisFsmInfo->fgTryScan = TRUE; ++ ++ /* abort timer */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* Pull back to SEARCH to find candidate again */ ++ eNextState = AIS_STATE_SEARCH; ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Call aisFsmSteps() when we are going to change AIS STATE */ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisIbssAloneTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Join Time-Out" to AIS FSM. ++* ++* @param[in] u4Param Unused timer parameter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ OS_SYSTIME rCurrentTime; ++ ++ DEBUGFUNC("aisFsmRunEventJoinTimeout()"); ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ eNextState = prAisFsmInfo->eCurrentState; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ switch (prAisFsmInfo->eCurrentState) { ++ case AIS_STATE_JOIN: ++ DBGLOG(AIS, LOUD, "EVENT- JOIN TIMEOUT\n"); ++ ++ /* 1. Do abort JOIN */ ++ aisFsmStateAbort_JOIN(prAdapter); ++ ++ /* 2. Increase Join Failure Count */ ++ prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount++; ++/* For JB nl802.11 */ ++ if (prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) { ++ /* 3.1 Retreat to AIS_STATE_SEARCH state for next try */ ++ eNextState = AIS_STATE_SEARCH; ++ } else if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ } else if (!CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, ++ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { ++ /* 3.3 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ ++ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; ++ } else { ++ /* 3.4 Retreat to AIS_STATE_JOIN_FAILURE to terminate join operation */ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_CONNECT_INDICATION, NULL, 0); ++ eNextState = AIS_STATE_IDLE; ++ } ++ break; ++ ++ case AIS_STATE_NORMAL_TR: ++ /* 1. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; ++ ++ /* 2. process if there is pending scan */ ++ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { ++ wlanClearScanningResult(prAdapter); ++ eNextState = AIS_STATE_ONLINE_SCAN; ++ } ++ ++ break; ++ ++ default: ++ /* release channel */ ++ aisFsmReleaseCh(prAdapter); ++ break; ++ ++ } ++ ++ /* Call aisFsmSteps() when we are going to change AIS STATE */ ++ if (eNextState != prAisFsmInfo->eCurrentState) ++ aisFsmSteps(prAdapter, eNextState); ++ ++} /* end of aisFsmRunEventJoinTimeout() */ ++ ++VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ aisDeauthXmitComplete(prAdapter, NULL, TX_RESULT_LIFE_TIMEOUT); ++} ++ ++#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisTest(VOID) ++{ ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_8 aucSSID[] = "pci-11n"; ++ UINT_8 ucSSIDLen = 7; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* Set Connection Request Issued Flag */ ++ prConnSettings->fgIsConnReqIssued = TRUE; ++ prConnSettings->ucSSIDLen = ucSSIDLen; ++ kalMemCopy(prConnSettings->aucSSID, aucSSID, ucSSIDLen); ++ ++ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) { ++ ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ return; ++ } ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_HEM_AIS_FSM_ABORT; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ wifi_send_msg(INDX_WIFI, MSG_ID_WIFI_IST, 0); ++ ++} ++#endif /* CFG_TEST_MGMT_FSM */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle OID_802_11_BSSID_LIST_SCAN ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] prSsid Pointer of SSID_T if specified ++* \param[in] pucIe Pointer to buffer of extra information elements to be attached ++* \param[in] u4IeLength Length of information elements ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ DEBUGFUNC("aisFsmScanRequest()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(u4IeLength <= MAX_IE_LENGTH); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ if (!prConnSettings->fgIsScanReqIssued) { ++ prConnSettings->fgIsScanReqIssued = TRUE; ++ ++ if (prSsid == NULL) { ++ prAisFsmInfo->ucScanSSIDLen = 0; ++ } else { ++ COPY_SSID(prAisFsmInfo->aucScanSSID, ++ prAisFsmInfo->ucScanSSIDLen, prSsid->aucSsid, (UINT_8) prSsid->u4SsidLen); ++ } ++ ++ if (u4IeLength > 0 && u4IeLength <= MAX_IE_LENGTH) { ++ prAisFsmInfo->u4ScanIELength = u4IeLength; ++ kalMemCopy(prAisFsmInfo->aucScanIEBuf, pucIe, u4IeLength); ++ } else { ++ prAisFsmInfo->u4ScanIELength = 0; ++ } ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { ++ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE ++ && prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { ++ /* 802.1x might not finished yet, pend it for later handling .. */ ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ } else { ++ if (prAisFsmInfo->fgIsChannelGranted == TRUE) { ++ DBGLOG(AIS, WARN, ++ "Scan Request with channel granted for join operation: %d, %d", ++ prAisFsmInfo->fgIsChannelGranted, prAisFsmInfo->fgIsChannelRequested); ++ } ++ ++ /* start online scan */ ++ wlanClearScanningResult(prAdapter); ++ aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN); ++ } ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) { ++ wlanClearScanningResult(prAdapter); ++ aisFsmSteps(prAdapter, AIS_STATE_SCAN); ++ } else { ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); ++ } ++ } else { ++ DBGLOG(AIS, WARN, "Scan Request dropped. (state: %d)\n", prAisFsmInfo->eCurrentState); ++ } ++ ++} /* end of aisFsmScanRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is invoked when CNM granted channel privilege ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_CH_GRANT_T prMsgChGrant; ++ UINT_8 ucTokenID; ++ UINT_32 u4GrantInterval; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; ++ ++ ucTokenID = prMsgChGrant->ucTokenID; ++ u4GrantInterval = prMsgChGrant->u4GrantInterval; ++ ++ /* 1. free message */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { ++ /* 2. channel privilege has been approved */ ++ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; ++ ++ /* 3. state transition to join/ibss-alone/ibss-merge */ ++ /* 3.1 set timeout timer in cases join could not be completed */ ++ cnmTimerStartTimer(prAdapter, ++ &prAisFsmInfo->rJoinTimeoutTimer, ++ prAisFsmInfo->u4ChGrantedInterval - AIS_JOIN_CH_GRANT_THRESHOLD); ++ /* 3.2 set local variable to indicate join timer is ticking */ ++ prAisFsmInfo->fgIsInfraChannelFinished = FALSE; ++ ++ /* 3.3 switch to join state */ ++ aisFsmSteps(prAdapter, AIS_STATE_JOIN); ++ ++ prAisFsmInfo->fgIsChannelGranted = TRUE; ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL && ++ prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { ++ /* 2. channel privilege has been approved */ ++ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; ++ ++ /* 3.1 set timeout timer in cases upper layer cancel_remain_on_channel never comes */ ++ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer, prAisFsmInfo->u4ChGrantedInterval); ++ ++ /* 3.2 switch to remain_on_channel state */ ++ aisFsmSteps(prAdapter, AIS_STATE_REMAIN_ON_CHANNEL); ++ ++ /* 3.3. indicate upper layer for channel ready */ ++ kalReadyOnChannel(prAdapter->prGlueInfo, ++ prAisFsmInfo->rChReqInfo.u8Cookie, ++ prAisFsmInfo->rChReqInfo.eBand, ++ prAisFsmInfo->rChReqInfo.eSco, ++ prAisFsmInfo->rChReqInfo.ucChannelNum, prAisFsmInfo->rChReqInfo.u4DurationMs); ++ ++ prAisFsmInfo->fgIsChannelGranted = TRUE; ++ } else { /* mismatched grant */ ++ /* 2. return channel privilege to CNM immediately */ ++ aisFsmReleaseCh(prAdapter); ++ } ++ ++} /* end of aisFsmRunEventChGrant() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform CNM that channel privilege ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_CH_ABORT_T prMsgChAbort; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ if (prAisFsmInfo->fgIsChannelGranted == TRUE || prAisFsmInfo->fgIsChannelRequested == TRUE) { ++ ++ prAisFsmInfo->fgIsChannelRequested = FALSE; ++ prAisFsmInfo->fgIsChannelGranted = FALSE; ++ ++ /* 1. return channel privilege to CNM immediately */ ++ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); ++ if (!prMsgChAbort) { ++ ASSERT(0); /* Can't release Channel to CNM */ ++ return; ++ } ++ ++ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; ++ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prMsgChAbort->ucTokenID = prAisFsmInfo->ucSeqNumOfChReq; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); ++ } ++ ++} /* end of aisFsmReleaseCh() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform AIS that corresponding beacon has not ++* been received for a while and probing is not successful ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ BOOLEAN fgDoAbortIndication = FALSE; ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1> Diagnose Connection for Beacon Timeout Event */ ++ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { ++ if (OP_MODE_INFRASTRUCTURE == prAisBssInfo->eCurrentOPMode) { ++ P_STA_RECORD_T prStaRec = prAisBssInfo->prStaRecOfAP; ++ ++ if (prStaRec) ++ fgDoAbortIndication = TRUE; ++ } else if (OP_MODE_IBSS == prAisBssInfo->eCurrentOPMode) { ++ fgDoAbortIndication = TRUE; ++ } ++ } ++ /* 4 <2> invoke abort handler */ ++ if (fgDoAbortIndication) { ++#if 0 ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; ++#endif ++ ++ DBGLOG(AIS, INFO, "Beacon Timeout, Remove BSS [%pM]\n", prAisBssInfo->aucBSSID); ++ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ ++ /* ++ Note: Cannot change TRUE to FALSE; or you will suffer the problem in ++ ALPS01270257/ ALPS01804173 ++ */ ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, TRUE); ++ } ++ ++} /* end of aisBssBeaconTimeout() */ ++ ++VOID aisBssSecurityChanged(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ prAdapter->rWifiVar.rConnSettings.fgIsDisconnectedByNonRequest = TRUE; ++ prAisBssInfo->u2DeauthReason = REASON_CODE_BSS_SECURITY_CHANGE; ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_DEAUTHENTICATED, FALSE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform AIS that DEAUTH frame has been ++* sent and thus state machine could go ahead ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] prMsduInfo Pointer of MSDU_INFO_T for DEAUTH frame ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer); ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) { ++ if (rTxDoneStatus != TX_RESULT_DROPPED_IN_DRIVER) ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_NEW_CONNECTION, FALSE); ++ } else { ++ DBGLOG(AIS, WARN, "DEAUTH frame transmitted without further handling"); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of aisDeauthXmitComplete() */ ++ ++#if CFG_SUPPORT_ROAMING ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate an Event of "Looking for a candidate due to weak signal" to AIS FSM. ++* ++* @param[in] u4ReqScan Requesting Scan or not ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ENUM_AIS_REQUEST_TYPE_T eAisRequest; ++ ++ DBGLOG(AIS, LOUD, "aisFsmRunEventRoamingDiscovery()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* search candidates by best rssi */ ++ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; ++ ++#if CFG_SUPPORT_WFD ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ /* Check WFD is running */ ++ P_BSS_INFO_T prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ if (prAdapter->fgIsP2PRegistered && ++ IS_BSS_ACTIVE(prP2pBssInfo) && ++ (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || ++ prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)) { ++ DBGLOG(ROAMING, INFO, "Handle roaming when P2P is GC or GO.\n"); ++ if (prAdapter->rWifiVar.prP2pFsmInfo) { ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ if ((prWfdCfgSettings->ucWfdEnable == 1) && ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { ++ DBGLOG(ROAMING, INFO, "WFD is running. Stop roaming.\n"); ++ roamingFsmRunEventRoam(prAdapter); ++ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); ++ return; ++ } ++ } else { ++ ASSERT(0); ++ } ++ } /* fgIsP2PRegistered */ ++ } ++#endif ++#endif ++ ++ /* results are still new */ ++ if (!u4ReqScan) { ++ roamingFsmRunEventRoam(prAdapter); ++ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; ++ } else { ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN ++ || prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { ++ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; ++ } else { ++ eAisRequest = AIS_REQUEST_ROAMING_SEARCH; ++ } ++ } ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { ++ if (eAisRequest == AIS_REQUEST_ROAMING_SEARCH) ++ aisFsmSteps(prAdapter, AIS_STATE_LOOKING_FOR); ++ else ++ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); ++ } else { ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); ++ ++ aisFsmInsertRequest(prAdapter, eAisRequest); ++ } ++ ++} /* end of aisFsmRunEventRoamingDiscovery() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update the time of ScanDone for roaming and transit to Roam state. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_AIS_STATE_T eNextState; ++ ++ DBGLOG(AIS, LOUD, "->aisFsmRoamingScanResultsUpdate()\n"); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ roamingFsmScanResultsUpdate(prAdapter); ++ ++ eNextState = prAisFsmInfo->eCurrentState; ++ if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) { ++ roamingFsmRunEventRoam(prAdapter); ++ eNextState = AIS_STATE_SEARCH; ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { ++ eNextState = AIS_STATE_SEARCH; ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { ++ eNextState = AIS_STATE_NORMAL_TR; ++ } ++ ++ return eNextState; ++} /* end of aisFsmRoamingScanResultsUpdate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will modify and update necessary information to firmware ++* for disconnection of last AP before switching to roaming bss. ++* ++* @param IN prAdapter Pointer to the Adapter structure. ++* prTargetStaRec Target of StaRec of roaming ++* ++* @retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ DBGLOG(AIS, LOUD, "aisFsmRoamingDisconnectPrevAP()"); ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ /* Not invoke rlmBssAborted() here to avoid prAisBssInfo->fg40mBwAllowed ++ * to be reset. RLM related parameters will be reset again when handling ++ * association response in rlmProcessAssocRsp(). 20110413 ++ */ ++ /* rlmBssAborted(prAdapter, prAisBssInfo); */ ++ ++ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ ++ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) ++ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ /* 4 <4> Change Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ /* 4 <4.1> sync. with firmware */ ++ prTargetStaRec->ucNetTypeIndex = 0xff; /* Virtial NetType */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ prTargetStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Virtial NetType */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, prAisBssInfo->aucBSSID, ++ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++} /* end of aisFsmRoamingDisconnectPrevAP() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the roaming was completed. ++* ++* @param IN prAdapter Pointer to the Adapter structure. ++* prStaRec StaRec of roaming AP ++* prAssocRspSwRfb ++* ++* @retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ DBGLOG(AIS, LOUD, "aisUpdateBssInfoForRoamingAP()"); ++ ++ ASSERT(prAdapter); ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if ((prAisBssInfo->prStaRecOfAP) && ++ (prAisBssInfo->prStaRecOfAP != prStaRec) && (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { ++ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); ++ } ++ /* 4 <1.3> Update BSS_INFO_T */ ++ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); ++ ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ /* 4 <1.6> Indicate Connected Event to Host immediately. */ ++ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ ++ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); ++ ++} /* end of aisFsmRoamingUpdateBss() */ ++ ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Check if there is any pending request and remove it (optional) ++* ++* @param prAdapter ++* eReqType ++* bRemove ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_AIS_REQ_HDR_T prPendingReqHdr, prPendingReqHdrNext; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ /* traverse through pending request list */ ++ LINK_FOR_EACH_ENTRY_SAFE(prPendingReqHdr, ++ prPendingReqHdrNext, &(prAisFsmInfo->rPendingReqList), rLinkEntry, AIS_REQ_HDR_T) { ++ /* check for specified type */ ++ if (prPendingReqHdr->eReqType == eReqType) { ++ /* check if need to remove */ ++ if (bRemove == TRUE) { ++ LINK_REMOVE_KNOWN_ENTRY(&(prAisFsmInfo->rPendingReqList), ++ &(prPendingReqHdr->rLinkEntry)); ++ ++ cnmMemFree(prAdapter, prPendingReqHdr); ++ } ++ ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Get next pending request ++* ++* @param prAdapter ++* ++* @return P_AIS_REQ_HDR_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_AIS_REQ_HDR_T prPendingReqHdr; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ LINK_REMOVE_HEAD(&(prAisFsmInfo->rPendingReqList), prPendingReqHdr, P_AIS_REQ_HDR_T); ++ ++ return prPendingReqHdr; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Insert a new request ++* ++* @param prAdapter ++* eReqType ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType) ++{ ++ P_AIS_REQ_HDR_T prAisReq; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ prAisReq = (P_AIS_REQ_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(AIS_REQ_HDR_T)); ++ ++ if (!prAisReq) { ++ ASSERT(0); /* Can't generate new message */ ++ return FALSE; ++ } ++ ++ prAisReq->eReqType = eReqType; ++ ++ /* attach request into pending request list */ ++ LINK_INSERT_TAIL(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Flush all pending requests ++* ++* @param prAdapter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_REQ_HDR_T prAisReq; ++ ++ ASSERT(prAdapter); ++ ++ while ((prAisReq = aisFsmGetNextRequest(prAdapter)) != NULL) ++ cnmMemFree(prAdapter, prAisReq); ++ ++} ++ ++VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_REMAIN_ON_CHANNEL_T prRemainOnChannel; ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ prRemainOnChannel = (P_MSG_REMAIN_ON_CHANNEL_T) prMsgHdr; ++ ++ /* record parameters */ ++ prAisFsmInfo->rChReqInfo.eBand = prRemainOnChannel->eBand; ++ prAisFsmInfo->rChReqInfo.eSco = prRemainOnChannel->eSco; ++ prAisFsmInfo->rChReqInfo.ucChannelNum = prRemainOnChannel->ucChannelNum; ++ prAisFsmInfo->rChReqInfo.u4DurationMs = prRemainOnChannel->u4DurationMs; ++ prAisFsmInfo->rChReqInfo.u8Cookie = prRemainOnChannel->u8Cookie; ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE || prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { ++ /* transit to next state */ ++ aisFsmSteps(prAdapter, AIS_STATE_REQ_REMAIN_ON_CHANNEL); ++ } else { ++ aisFsmInsertRequest(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL); ++ } ++ ++ /* free messages */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prCancelRemainOnChannel; ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ prCancelRemainOnChannel = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) prMsgHdr; ++ ++ /* 1. Check the cookie first */ ++ if (prCancelRemainOnChannel->u8Cookie == prAisFsmInfo->rChReqInfo.u8Cookie) { ++ ++ /* 2. release channel privilege/request */ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL) { ++ /* 2.1 elease channel */ ++ aisFsmReleaseCh(prAdapter); ++ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { ++ /* 2.1 release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2.2 stop channel timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ } ++ ++ /* 3. clear pending request of remain_on_channel */ ++ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE); ++ ++ /* 4. decide which state to retreat */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); ++ else ++ aisFsmSteps(prAdapter, AIS_STATE_IDLE); ++ } ++ ++ /* 5. free message */ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_MSG_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ /* prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); */ ++ ++ if (prAisFsmInfo == NULL) ++ break; ++ prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) prMsgHdr; ++ ++ aisFuncTxMgmtFrame(prAdapter, ++ &prAisFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* aisFsmRunEventMgmtFrameTx */ ++ ++VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); ++ ++ ASSERT(prAdapter); ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { ++ /* 1. release channel */ ++ aisFsmReleaseCh(prAdapter); ++ ++ /* 2. stop channel timeout timer */ ++ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); ++ ++ /* 3. expiration indication to upper layer */ ++ kalRemainOnChannelExpired(prAdapter->prGlueInfo, ++ prAisFsmInfo->rChReqInfo.u8Cookie, ++ prAisFsmInfo->rChReqInfo.eBand, ++ prAisFsmInfo->rChReqInfo.eSco, prAisFsmInfo->rChReqInfo.ucChannelNum); ++ ++ /* 4. decide which state to retreat */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); ++ else ++ aisFsmSteps(prAdapter, AIS_STATE_IDLE); ++ } else { ++ DBGLOG(AIS, WARN, "Unexpected remain_on_channel timeout event\n"); ++#if DBG ++ DBGLOG(AIS, STATE, "CURRENT State: [%s]\n", apucDebugAisState[prAisFsmInfo->eCurrentState]); ++#else ++ DBGLOG(AIS, STATE, "[%d] CURRENT State: [%d]\n", DBG_AIS_IDX, prAisFsmInfo->eCurrentState); ++#endif ++ } ++ ++} ++ ++WLAN_STATUS ++aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_AIS_MGMT_TX_REQ_INFO_T) NULL; ++ BOOLEAN fgIsSuccess = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo); ++ ++ if (rTxDoneStatus != TX_RESULT_SUCCESS) { ++ DBGLOG(AIS, ERROR, "Mgmt Frame TX Fail, Status:%d.\n", rTxDoneStatus); ++ } else { ++ fgIsSuccess = TRUE; ++ /* printk("Mgmt Frame TX Done.\n"); */ ++ } ++ ++ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { ++ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ fgIsSuccess, prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); ++ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ } ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* aisFsmRunEventMgmtFrameTxDone */ ++ ++WLAN_STATUS ++aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); ++ ++ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { ++ ++ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ ++ /* Packet on driver, not done yet, drop it. */ ++ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; ++ if (prTxMsduInfo != NULL) { ++ ++ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ FALSE, ++ prTxMsduInfo->prPacket, (UINT_32) prTxMsduInfo->u2FrameLength); ++ ++ /* Leave it to TX Done handler. */ ++ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ } ++ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ ++ /* Packet transmitted, wait tx done. (cookie issue) */ ++ } ++ ++ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); ++ ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanHdr->aucAddr1); ++ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++ ++ prMgmtTxReqInfo->u8Cookie = u8Cookie; ++ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; ++ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; ++ ++ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; ++ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); ++ if (prStaRec != NULL) { ++ /* Do nothing */ ++ /* printk("Mgmt with station record: %pM .\n", prStaRec->aucMacAddr); */ ++ } ++ ++ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ ++ prMgmtTxMsdu->fgIs802_1x = FALSE; ++ prMgmtTxMsdu->fgIs802_11 = TRUE; ++ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMgmtTxMsdu->pfTxDoneHandler = aisFsmRunEventMgmtFrameTxDone; ++ prMgmtTxMsdu->fgIsBasicRate = TRUE; ++ DBGLOG(AIS, TRACE, "Mgmt seq NO. %d .\n", prMgmtTxMsdu->ucTxSeqNum); ++ ++ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* aisFuncTxMgmtFrame */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Action Frame and indicate to uppoer layer ++* if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("aisFuncValidateRxActionFrame"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); ++ ++ if (1 /* prAisFsmInfo->u4AisPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME */) { ++ /* Leave the action frame to wpa_supplicant. */ ++ kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* aisFuncValidateRxActionFrame */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c +new file mode 100644 +index 000000000000..f02d7c3bb5b2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c +@@ -0,0 +1,1932 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#3 ++*/ ++ ++/*! \file "assoc.c" ++ \brief This file includes the association-related functions. ++ ++ This file includes the association-related functions. ++*/ ++ ++/*\ ++** Log: assoc.c ++** ++** 07 27 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Fix wifi direct connection issue. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 06 08 2012 cp.wu ++ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development ++ * add a pair of brace for compilation success. ++ * ++ * 06 04 2012 cp.wu ++ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development ++ * discussed with WH, privacy bit in associate response is not necessary to be checked, ++ * and identified as association failure when mismatching with beacon/probe response ++ * ++ * 03 14 2012 wh.su ++ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting ++ * Add code from 2.2 ++ * ++ * 03 09 2012 terry.wu ++ * NULL ++ * Fix build error. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 yuche.tsai ++ * NULL ++ * Update Driver for wifi driect gc join IE update issue. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Fix PhyTypeSet in STA_REC in AP mode ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 19 2011 yuche.tsai ++ * NULL ++ * Fix KE when enable hot-spot & any one client connect to this hot-spot. ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 07 15 2011 terry.wu ++ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment ++ * Update workaround for Kingnet AP. ++ * ++ * 07 15 2011 terry.wu ++ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment ++ * Workaround for Kingnet 710 AP wrong AID assignment. ++ * ++ * 05 02 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning[WCXRP00000672] [MT6620 Wi-Fi][FW] ++ * Fix the PS event allocation ++ * Check STA when rx assoc. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the protected while at P2P start GO, and skip some security check . ++ * ++ * 03 14 2011 wh.su ++ * [WCXRP00000545] [MT6620 Wi-Fi] [Driver] Fixed the p2p not enable, received a assoc rsp ++ * cause the rx assoc execute a null function ++ * Modify file for avoid assert at BOW receive a assoc response frame but no p2p function. ++ * ++ * 03 08 2011 terry.wu ++ * [WCXRP00000524] [MT6620 Wi-Fi][Driver] Fix p2p assoc request containing wrong IE format ++ * Fix p2p assoc request containing wrong IE format. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add code to let the beacon and probe response for Auto GO WSC . ++ * ++ * 02 15 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Fix RX disassoc issue under Hot-spot mode. ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, ++ * but if the P2P device is connected, 11b rate is not allowed. ++ * ++ * 01 11 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Update Desired Non-HT Rate Set. ++ * ++ * 12 30 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Recover the code that was coverwritted.. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add SSID IE in assoc req frame which is sent by P2P GC. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RSN IE generation by CFG_RSN_MIGRATION compilation flag. ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * revised. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update assocProcessRxAssocReqFrame() to avoid redundant SSID IE {0,0} for IOT. ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix compile warning - macro > 10 line, initial value of an array ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * * * * * * * and will send Null frame to diagnose connection ++ * ++ * 04 16 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the wpa-none for ibss beacon. ++ * ++ * 03 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove compiling warning ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 28 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * fixed the compiling warning.u1rwduu`wvpghlqg|rm+vp ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update Assoc ID for PS ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Use new constant definition ELEM_MAX_LEN_EXT_CAP ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Modify assoc req IE talbe for HT cap IE ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * update the assocComposeReAssocReqFrameHeader() and fix the u2EstimatedFrameLen in assocSendReAssocReqFrame() ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * remove some space line ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the sending disassoc frame function ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the txassocReq IE table, adding for WPA/RSN ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix eNetType not init in send AssocReq function ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Integrate the send Assoc with TXM ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code to indicate the assoc request and assoc response (now disable) ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove unused variables ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++APPEND_VAR_IE_ENTRY_T txAssocReqIETable[] = { ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmReqGenerateHtCapIE} ++ , /* 45 */ ++#if CFG_SUPPORT_WPS2 ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WSC), NULL, rsnGenerateWSCIE} ++ , /* 221 */ ++#endif ++#if CFG_RSN_MIGRATION ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} ++ , /* 48 */ ++#endif ++#if CFG_SUPPORT_WAPI ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI), NULL, wapiGenerateWAPIIE} ++ , /* 68 */ ++#endif ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_INTERWORKING), NULL, hs20GenerateInterworkingIE} ++ , /* 107 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ROAMING_CONSORTIUM), NULL, hs20GenerateRoamingConsortiumIE} ++ , /* 111 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE} ++ , /* 127 */ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HS20_INDICATION), NULL, hs20GenerateHS20IE} ++ , /* 221 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE} ++ , /* 221 */ ++#if CFG_RSN_MIGRATION ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE} ++ , /* 221 */ ++#endif ++}; ++ ++#if CFG_SUPPORT_AAA ++VERIFY_IE_ENTRY_T rxAssocReqIETable[] = { ++ {ELEM_ID_RESERVED, NULL} /* 255 */ ++}; ++ ++APPEND_VAR_IE_ENTRY_T txAssocRespIETable[] = { ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} ++ , /* 42 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} ++ , /* 45 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} ++ , /* 61 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} ++ , /* 74 */ ++ {(0), p2pFuncCalculateP2p_IELenForAssocRsp, p2pFuncGenerateP2p_IEForAssocRsp} ++ , /* 221 */ ++#if CFG_SUPPORT_WFD ++ {(0), wfdFuncCalculateWfdIELenForAssocRsp, wfdFuncGenerateWfdIEForAssocRsp} ++ , /* 221 */ ++#endif ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} ++ , /* 127 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} ++ , /* 221 */ ++ ++ {(0), p2pFuncCalculateWSC_IELenForAssocRsp, p2pFuncGenerateWSC_IEForAssocRsp} /* 221 */ ++ ++}; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose the Capability Info Field. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval Capability Info Field ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_16 ++assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ UINT_32 u4NonHTPhyType; ++ UINT_16 u2CapInfo; ++ ++ /* Set up our requested capabilities. */ ++ u2CapInfo = CAP_INFO_ESS; ++ u2CapInfo |= CAP_CF_STA_NOT_POLLABLE; ++ ++ if (prStaRec == NULL) ++ u2CapInfo |= CAP_INFO_PRIVACY; ++ else { ++ if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ++ u2CapInfo |= CAP_INFO_PRIVACY; ++ } ++ ++ /* 7.3.1.4 */ ++ if (prStaRec == NULL) { ++ if ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||/* ShortPreambleOptionEnable is TRUE */ ++ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO)) ++ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ if (prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) ++ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ } else if (prStaRec->fgHasBasicPhyType) { ++ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ if ((rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) && ++ /* Short Preamble Option Enable is TRUE */ ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) && ++ (prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { ++ ++ /* Case I: Implemented == TRUE and Short Preamble Option Enable == TRUE. ++ * Case II: Implemented == TRUE and Short Preamble == AUTO (depends on ++ * BSS_DESC_T's capability) ++ */ ++ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ } ++#if CFG_SUPPORT_SPEC_MGMT /*Add by Enlai */ ++ /* Support 802.11h */ ++ if (prStaRec->u2CapInfo & CAP_INFO_SPEC_MGT) { ++ /* ++ 1. The Power Capability element shall be present if ++ dot11SpectrumManagementRequired is true. ++ ++ 2. A STA shall set dot11SpectrumManagementRequired to TRUE before ++ associating with a BSS or IBSS in which the Spectrum Management ++ bit is set to 1 in the Capability Information field in Beacon frames ++ and Probe Response frames received from the BSS or IBSS. ++ */ ++ if (prAdapter->fgEnable5GBand == TRUE) ++ u2CapInfo |= CAP_INFO_SPEC_MGT; ++ } ++#endif ++ ++ if (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented && ++ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) { ++ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ } ++ } ++ ++ if (prStaRec) { ++ DBGLOG(SAA, LOUD, "ASSOC REQ: Compose Capability = 0x%04x for Target BSS [%pM].\n", ++ u2CapInfo, prStaRec->aucMacAddr); ++ } ++ ++ return u2CapInfo; ++ ++} /* end of assocBuildCapabilityInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for Association ++* Request Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID assocBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ PUINT_8 pucBuffer; ++ UINT_16 u2SupportedRateSet; ++ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; ++ UINT_8 ucAllSupportedRatesLen; ++ UINT_8 ucSupRatesLen; ++ UINT_8 ucExtSupRatesLen; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ if (IS_STA_IN_AIS(prStaRec)) { ++ ++ /* Fill the SSID element. */ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ ++ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of ++ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. ++ */ ++ ++ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, ++ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) ++ pucBuffer = p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, pucBuffer); ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (IS_STA_IN_BOW(prStaRec)) { ++ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ ++ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of ++ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. ++ */ ++ ++ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, ++ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++#endif ++ else { ++ /* Do nothing */ ++ /* TODO(Kevin): For other network */ ++ } ++ ++ /* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication - ++ * SupportedRates - The set of data rates that are supported by the STA ++ * that is requesting association. ++ * Original(Portable Driver): Only send the Rates that we'll support. ++ * New: Send the Phy Rates if the result of following & operation == NULL. ++ */ ++ /* rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet & */ ++ /* rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet), */ ++ ++ if (prStaRec->fgHasBasicPhyType) { ++ UINT_32 u4NonHTPhyType; ++ ++ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ u2SupportedRateSet = (prStaRec->u2OperationalRateSet & ++ rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet); ++ ++ ASSERT(u2SupportedRateSet); ++ ++ if (!u2SupportedRateSet) ++ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; ++ ++ /* TODO(Kevin): For P2P, we shouldn't send support rate set which contains 11b rate */ ++ ++ rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen); ++ ++ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? ++ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); ++ ++ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; ++ ++ /* Fill the Supported Rates element. */ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ ++ /* Fill the Extended Supported Rates element. */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, ++ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ ++ /* 7.3.2.19 Supported Channels element */ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++ if (prAdapter->fgEnable5GBand == TRUE) { ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucLength = 8; ++ ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[0] = 36; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[1] = 4; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[2] = 52; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[3] = 4; ++/* Not China --- Start */ ++ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 100; */ ++ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 11; */ ++/* Not China --- End */ ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 149; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 4; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[6] = 165; ++ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[7] = 1; ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++#endif ++ } ++ ++} /* end of assocBuildReAssocReqFrameCommonIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the (Re)Association Request frame header and ++* its fixed fields ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in out] pu2PayloadLen Return the length of the composed fixed fields ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocComposeReAssocReqFrameHeaderAndFF(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN OUT PUINT_16 pu2PayloadLen) ++{ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; ++ BOOLEAN fgIsReAssoc; ++ ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2CapInfo; ++ UINT_16 u2ListenInterval; ++ ++ ASSERT(prStaRec); ++ ASSERT(pucBuffer); ++ ASSERT(aucMACAddress); ++ ASSERT(pu2PayloadLen); ++ ++ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) pucBuffer; ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ ++ /* Fill the Frame Control field. */ ++ if (fgIsReAssoc) ++ u2FrameCtrl = MAC_FRAME_REASSOC_REQ; ++ else ++ u2FrameCtrl = MAC_FRAME_ASSOC_REQ; ++ WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress); ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prAssocFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); ++ ++ /* Fill the Capability Information field. */ ++ WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); ++ ++ /* Calculate the listen interval for the maximum power mode. Currently, we ++ set it to the value 2 times DTIM period. */ ++ if (prStaRec->ucDTIMPeriod) { ++ u2ListenInterval = prStaRec->ucDTIMPeriod * DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD; ++ } else { ++ DBGLOG(SAA, TRACE, "Use default listen interval\n"); ++ u2ListenInterval = DEFAULT_LISTEN_INTERVAL; ++ } ++ prStaRec->u2ListenInterval = u2ListenInterval; ++ ++ /* Fill the Listen Interval field. */ ++ WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval); ++ ++ /* 4 <3> Compose the Current AP Address field for ReAssociation Request frame. */ ++ /* Fill the Current AP Address field. */ ++ if (prStaRec->fgIsReAssoc) { ++ if (IS_STA_IN_AIS(prStaRec)) { ++ ++ P_AIS_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ P_WLAN_REASSOC_REQ_FRAME_T prReAssocFrame = (P_WLAN_REASSOC_REQ_FRAME_T) prAssocFrame; ++ ++ COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, prAisBssInfo->aucBSSID); ++ } else { ++ ASSERT(0); /* We don't support ReAssociation for other network */ ++ } ++ ++ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + CURR_AP_ADDR_FIELD_LEN); ++ } else { ++ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN); ++ } ++ ++} /* end of assocComposeReAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the (Re)Association Request frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ ++ UINT_16 u2PayloadLen; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ BOOLEAN fgIsReAssoc; ++ UINT_32 i; ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ ++ if (fgIsReAssoc) { ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + ++ LISTEN_INTERVAL_FIELD_LEN + ++ CURR_AP_ADDR_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); ++ } else { ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + ++ LISTEN_INTERVAL_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); ++ } ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ if ((prAdapter->fgIsP2PRegistered)) { ++ u2EstimatedExtraIELen = p2pCalculate_IEForAssocReq(prAdapter, ++ prStaRec->ucNetTypeIndex, prStaRec); ++ } else { ++ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); ++ ASSERT(FALSE); ++ } ++ } else { ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { ++ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; ++ } else { ++ u2EstimatedExtraIELen += ++ (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, ++ prStaRec->ucNetTypeIndex, ++ prStaRec); ++ } ++ } ++ } ++#else ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { ++ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; ++ } else { ++ u2EstimatedExtraIELen += (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, ++ prStaRec->ucNetTypeIndex, ++ prStaRec); ++ } ++ } ++#endif ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Request.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Compose Header and Fixed Field */ ++ assocComposeReAssocReqFrameHeaderAndFF(prAdapter, ++ prStaRec, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prBssInfo->aucOwnMacAddr, &u2PayloadLen); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ ++ assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo); ++ ++ /* 4 <5> Compose IEs in MSDU_INFO_T */ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ if ((prAdapter->fgIsP2PRegistered)) { ++ p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo); ++ } else { ++ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); ++ ASSERT(FALSE); ++ } ++ } else { ++ /* Append IE */ ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].pfnAppendIE) ++ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ } ++#else ++ /* Append IE */ ++ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocReqIETable[i].pfnAppendIE) ++ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++#endif ++ ++ /* 4 <6> Update the (Re)association request information */ ++ if (IS_STA_IN_AIS(prStaRec)) { ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; ++ ++ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++#if CFG_RSN_MIGRATION ++ kalUpdateReAssocReqInfo(prAdapter->prGlueInfo, ++ (PUINT_8) &prAssocFrame->u2CapInfo, ++ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), ++ fgIsReAssoc); ++#endif ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; ++ ++ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, ++ (PUINT_8) &prAssocFrame->u2CapInfo, ++ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), ++ fgIsReAssoc); ++ } ++#endif ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ ++ DBGLOG(SAA, INFO, "Sending (Re)Assoc Request, network: %d seqNo: %d\n", ++ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of assocSendReAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will strictly check the TX (Re)Association Request frame for ++* SAA event handling. ++* ++* @param[in] prMsduInfo Pointer of MSDU_INFO_T ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TxFrameCtrl; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) (prMsduInfo->prPacket); ++ ASSERT(prAssocReqFrame); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl) */ ++ u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2TxFrameCtrl &= MASK_FRAME_TYPE; ++ if (prStaRec->fgIsReAssoc) { ++ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ) ++ return WLAN_STATUS_FAILURE; ++ } else { ++ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ) ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocCheckTxReAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will strictly check the TX (Re)Association Response frame for ++* AAA event handling. ++* ++* @param[in] prMsduInfo Pointer of MSDU_INFO_T ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TxFrameCtrl; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) (prMsduInfo->prPacket); ++ ASSERT(prAssocRspFrame); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl) */ ++ u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2TxFrameCtrl &= MASK_FRAME_TYPE; ++ if (prStaRec->fgIsReAssoc) { ++ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } else { ++ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocCheckTxReAssocRespFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the incoming (Re)Association Frame and take out ++* the status code. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ UINT_16 u2RxFrameCtrl; ++ UINT_16 u2RxCapInfo; ++ UINT_16 u2RxStatusCode; ++ UINT_16 u2RxAssocId; ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu2StatusCode); ++ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + ++ STATUS_CODE_FIELD_LEN + AID_FIELD_LEN)) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ DBGLOG(SAA, LOUD, "prSwRfb->u2PayloadLength = %d\n", prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* 4 <1> locate the (Re)Association Resp Frame. */ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of (Re)Association Resp Frame. */ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl); */ ++ u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2RxFrameCtrl &= MASK_FRAME_TYPE; ++ if (prStaRec->fgIsReAssoc) { ++ if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } else { ++ if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP) ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* 4 <3> Parse the Fixed Fields of (Re)Association Resp Frame Body. */ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo); */ ++ u2RxCapInfo = prAssocRspFrame->u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode); */ ++ u2RxStatusCode = prAssocRspFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* 4 <4> Check CAP_INFO */ ++ /* NOTE(Kevin): CM suggest to add MGMT workaround for those APs didn't check ++ * the CAP Privacy Bit to overcome a corner case that the Privacy Bit ++ * of our SCAN result didn't consist with AP's Association Resp. ++ */ ++ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { ++#if CFG_SUPPORT_WAPI ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { ++ /* WAPI AP allow the customer use WZC to join mode, the privacy bit is 0 */ ++ /* even at WAI & WAPI_PSK mode, but the assoc respose set the privacy bit set 1 */ ++ DBGLOG(SEC, TRACE, "Workaround the WAPI AP allow the customer to use WZC to join\n"); ++ } else ++#endif ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && 1) { ++ /* Todo:: Fixed this */ ++ } else ++#endif ++ { ++ } ++ ++#if CFG_STRICT_CHECK_CAPINFO_PRIVACY ++ if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY)) ++ u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; ++#endif ++ } ++ ++ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { ++#if CFG_RSN_MIGRATION ++ /* Update the information in the structure used to query and set ++ OID_802_11_ASSOCIATION_INFORMATION. */ ++ kalUpdateReAssocRspInfo(prAdapter->prGlueInfo, ++ (PUINT_8) &prAssocRspFrame->u2CapInfo, (UINT_32) (prSwRfb->u2PacketLen)); ++#endif ++ } ++ /* 4 <5> Update CAP_INFO and ASSOC_ID */ ++ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { ++ prStaRec->u2CapInfo = u2RxCapInfo; ++ ++ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, &u2RxAssocId); */ ++ u2RxAssocId = prAssocRspFrame->u2AssocId; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* 20110715 Workaround for Kingnet 710 AP (Realtek 8186) ++ * This AP raises the bit 6&7 not bit 14&15 in AID field. ++ * It cause wrong AID assignment. ++ * For AID = 2 ++ * Normal case: 0xC002(1100 0000 0000 0010) => 2 ++ * Kingnet 710: 0x00C2(0000 0000 1100 0010) => 194 ++ * workaround: mask bit 6&7 for this AP ++ */ ++ if ((u2RxAssocId & BIT(6)) && (u2RxAssocId & BIT(7)) && !(u2RxAssocId & BITS(8, 15))) { ++ prStaRec->u2AssocId = u2RxAssocId & ~BITS(6, 7); ++ } else { ++ prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB; ++#if CFG_SUPPORT_802_11W ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ prBssSpecInfo->ucSaQueryTimedOut = 0; ++ } ++#endif ++ } ++ } ++#if CFG_SUPPORT_802_11W ++ if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) { ++ DBGLOG(SAA, INFO, "AP rejected due the authentication algorithm not support\n"); ++ } else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { ++ PUINT_8 pucIE, pucTime; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_TIMEOUT_INTERVAL == IE_ID(pucIE) && IE_LEN(pucIE) == 5) { ++ pucTime = ((P_IE_HDR_T) pucIE)->aucInfo; ++ if (pucTime[0] == ACTION_SA_TIMEOUT_ASSOC_COMEBACK) { ++ UINT_32 tu; ++ ++ WLAN_GET_FIELD_32(pucTime + 1, &tu); ++ DBGLOG(SAA, INFO, ++ "AP rejected association temporarily;comeback duration %u TU (%u ms)\n", ++ tu, TU_TO_MSEC(tu)); ++ if (tu > TX_ASSOCIATION_RETRY_TIMEOUT_TU) { ++ DBGLOG(SAA, INFO, "Update timer based on comeback duration\n"); ++ /* ieee80211_reschedule_timer(wpa_s, ms); */ ++ } ++ } ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ } ++#endif ++ *pu2StatusCode = u2RxStatusCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocCheckRxReAssocRspFrameStatus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will compose the Disassociation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in] u2ReasonCode The reason code of disassociation ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocComposeDisassocFrame(IN P_STA_RECORD_T prStaRec, ++ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN UINT_16 u2ReasonCode) ++{ ++ P_WLAN_DISASSOC_FRAME_T prDisAssocFrame; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(pucBuffer); ++ ASSERT(aucMACAddress); ++ ++ prDisAssocFrame = (P_WLAN_DISASSOC_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the DisAssociation frame. */ ++ /* Fill the Frame Control field. */ ++ u2FrameCtrl = MAC_FRAME_DISASSOC; ++ ++ WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl); ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress); ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prDisAssocFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's fixed field part of the Disassociation frame. */ ++ /* Fill the Reason Code field. */ ++ WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode); ++ ++} /* end of assocComposeDisassocFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Disassociation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u2ReasonCode The reason code of disassociation ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode) ++{ ++ PUINT_8 pucMacAddress; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2PayloadLen; ++ UINT_16 u2EstimatedFrameLen; ++ /* UINT_32 u4Status = WLAN_STATUS_SUCCESS; */ ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending DisAssoc.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Disassociation frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ pucMacAddress = prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].aucOwnMacAddr; ++ ++ /* Compose Header and Fixed Field */ ++ assocComposeDisassocFrame(prStaRec, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucMacAddress, u2ReasonCode); ++ ++#if CFG_SUPPORT_802_11W ++ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; ++ ++ prDisassocFrame = ++ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ DBGLOG(TX, WARN, "assocSendDisAssocFrame with protection\n"); ++ } ++#endif ++ ++ u2PayloadLen = REASON_CODE_FIELD_LEN; ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Enqueue the frame to send this (Re)Association request frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of assocSendDisAssocFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Disassociation frame ++* if the given BSSID is matched. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] aucBSSID Given BSSID ++* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) ++{ ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; ++ UINT_16 u2RxReasonCode; ++ ++ ASSERT(prSwRfb); ++ ASSERT(aucBSSID); ++ ASSERT(pu2ReasonCode); ++ ++ /* 4 <1> locate the Disassociation Frame. */ ++ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Disassociation Frame. */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Check if this Disassoc Frame is coming from Target BSSID */ ++ if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) { ++ DBGLOG(SAA, LOUD, "Ignore Disassoc Frame from other BSS [ %pM ]\n", ++ prDisassocFrame->aucSrcAddr); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ ++ WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode); ++ *pu2ReasonCode = u2RxReasonCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocProcessRxDisassocFrame() */ ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Association Req frame ++* and return a Status Code. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode Pointer to store the Status Code for carried in Association Response. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ P_RSN_INFO_ELEM_T prIeRsn = (P_RSN_INFO_ELEM_T) NULL; ++ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; ++ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; ++ PUINT_8 pucIE, pucIEStart; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ UINT_16 u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ UINT_16 u2RxFrameCtrl; ++ UINT_16 u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pu2StatusCode); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prStaRec == NULL) ++ return WLAN_STATUS_FAILURE; ++ /* 4 <1> locate the Association Req Frame. */ ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Association Req Frame. */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN)) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Check if this Disassoc Frame is coming from Target BSSID */ ++ if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID)) ++ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ ++ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2RxFrameCtrl); */ ++ u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2RxFrameCtrl &= MASK_FRAME_TYPE; ++ if (MAC_FRAME_REASSOC_REQ == u2RxFrameCtrl) { ++ prStaRec->fgIsReAssoc = TRUE; ++ ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) (OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); ++ ++ pucIEStart = pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; ++ } else { ++ prStaRec->fgIsReAssoc = FALSE; ++ ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) (OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); ++ ++ pucIEStart = pucIE = prAssocReqFrame->aucInfoElem; ++ } ++ ++ /* 4 <3> Parse the Fixed Fields of Assoc Req Frame Body. */ ++ prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo; ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) && !kalP2PGetCipher(prAdapter->prGlueInfo))) { ++ u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; ++ DBGLOG(RSN, TRACE, "STA Assoc req privacy bit check fail\n"); ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++#endif ++ ++ prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval; ++ prStaRec->ucPhyTypeSet = 0; ++ ++ /* Might be legacy client or p2p gc. */ ++ prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT; ++ ++ /* 4 <4> Parse the IE of Assoc Req Frame Body. */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if ((!prIeSsid) && /* NOTE(Kevin): Get SSID once */ ++ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ } ++ break; ++ ++ case ELEM_ID_SUP_RATES: ++ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) ++ prIeSupportedRate = SUP_RATES_IE(pucIE); ++ break; ++ ++ case ELEM_ID_EXTENDED_SUP_RATES: ++ if (!prIeExtSupportedRate) ++ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); ++ break; ++ case ELEM_ID_HT_CAP: ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; ++ kalMemCopy(&prStaRec->u2HtCapInfo, &(HT_CAP_IE(pucIE)->u2HtCapInfo), 2); ++ break; ++ case ELEM_ID_RSN: ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ prIeRsn = RSN_IE(pucIE); ++ rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode); ++ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ *pu2StatusCode = u2StatusCode; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++#endif ++ break; ++ case ELEM_ID_VENDOR: ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ if ((prAdapter->fgIsP2PRegistered)) { ++ UINT_8 ucOuiType = 0; ++ ++ p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType); ++ ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ DBGLOG(P2P, TRACE, "Target Client is a P2P group client\n"); ++ prStaRec->eStaType = STA_TYPE_P2P_GC; ++ } ++ } ++ } ++#endif ++ break; ++ default: ++ for (i = 0; i < (sizeof(rxAssocReqIETable) / sizeof(VERIFY_IE_ENTRY_T)); i++) { ++ ++ if ((IE_ID(pucIE)) == rxAssocReqIETable[i].ucElemID) { ++ rxAssocReqIETable[i].pfnVarifyIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIE, ++ &u2StatusCode); ++ ++ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ *pu2StatusCode = u2StatusCode; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++ } ++ ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* parsing for WMM related information (2010/12/21) */ ++ mqmProcessAssocReq(prAdapter, prSwRfb, pucIEStart, u2IELength); ++ ++ do { ++ if (prIeSsid) { ++ if (UNEQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, ++ prIeSsid->aucSSID, prIeSsid->ucLength)) { ++ ++ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; ++ break; ++ } ++ } else { ++ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; ++ break; ++ } ++ ++ prStaRec->u2OperationalRateSet = 0; ++ prStaRec->u2BSSBasicRateSet = 0; ++ ++ if (prIeSupportedRate || prIeExtSupportedRate) { ++ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, &prStaRec->u2OperationalRateSet, ++ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ ++ &fgIsUnknownBssBasicRate); ++ ++ if ((prBssInfo->u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) != ++ prBssInfo->u2BSSBasicRateSet) { ++ ++ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++ ++ /* Accpet the Sta, update BSSBasicRateSet from Bss */ ++ ++ prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; ++ ++ prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG); ++ ++ if (BAND_2G4 == HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr)) { ++#if 0 /* Marked by CMC 20111024 */ ++ /* check if support 11n */ ++ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { ++ ++ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; ++ ++ if ((!(u2BSSBasicRateSet & RATE_SET_OFDM)) && ++ (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS)) { ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; ++ ++ } ++ ++ } ++#else ++ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; ++ if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; ++#endif ++ } else { /* (BAND_5G == prBssDesc->eBande) */ ++#if 0 /* Marked by CMC 20111024 */ ++ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; ++ ASSERT((prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) == 0); ++#else ++ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; ++#endif ++ } ++ ++ } else { ++ ASSERT(0); ++ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ if (prIeRsn) { ++ if (!kalP2PGetCipher(prAdapter->prGlueInfo)) { ++ u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED; ++ break; ++ } ++ } else { ++ prStaRec->rSecInfo.fgAllowOnly1x = FALSE; ++ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { ++ /* Only Allow 1x */ ++ prStaRec->rSecInfo.fgAllowOnly1x = TRUE; ++ break; ++ } ++ } ++ } ++#endif ++ ++ } while (FALSE); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++#if 1 /* ICS */ ++ { ++ PUINT_8 cp = (PUINT_8) &prAssocReqFrame->u2CapInfo; ++ P_UINT_8 prNewAssocReqIe = NULL; ++ ++ if (u2IELength) { ++ prNewAssocReqIe = kalMemAlloc(u2IELength, VIR_MEM_TYPE); ++ if (NULL == prNewAssocReqIe) { ++ DBGLOG(AIS, WARN, "allocate memory for (Re)assocReqIe fail!\n"); ++ u2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ if (prStaRec->fgIsReAssoc) ++ cp += 10; ++ else ++ cp += 4; ++ if (prStaRec->pucAssocReqIe) { ++ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); ++ prStaRec->pucAssocReqIe = NULL; ++ } ++ prStaRec->u2AssocReqIeLen = u2IELength; ++ if (u2IELength) { ++ prStaRec->pucAssocReqIe = prNewAssocReqIe; /* kalMemAlloc(u2IELength, VIR_MEM_TYPE); */ ++ kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength); ++ } ++ } ++#endif ++ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8) &prAssocReqFrame->u2CapInfo, ++ u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc); ++ } ++#endif ++ ++ *pu2StatusCode = u2StatusCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocProcessRxAssocReqFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for Association ++* Response Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocBuildReAssocRespFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo) ++{ ++ PUINT_8 pucBuffer; ++ P_STA_RECORD_T prStaRec; ++ UINT_8 ucSupRatesLen; ++ UINT_8 ucExtSupRatesLen; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) { ++ ++ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; ++ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; ++ } else { ++ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; ++ ucExtSupRatesLen = 0; ++ } ++ ++ /* Fill the Supported Rates element. */ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ ++ /* Fill the Extended Supported Rates element. */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, ++ &prBssInfo->aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* end of assocBuildReAssocRespFrameCommonIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the (Re)Association Response frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucBssid Given BSSID. ++* @param[in] u2CapInfo Capability Field of current BSS. ++* @param[in out] pu2PayloadLen Return the length of the composed fixed fields ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++assocComposeReAssocRespFrameHeaderAndFF(IN P_STA_RECORD_T prStaRec, ++ IN PUINT_8 pucBuffer, ++ IN UINT_8 aucBSSID[], IN UINT_16 u2CapInfo, IN OUT PUINT_16 pu2PayloadLen) ++{ ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; ++ BOOLEAN fgIsReAssoc; ++ ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(prStaRec); ++ ASSERT(pucBuffer); ++ ASSERT(aucBSSID); ++ ASSERT(pu2PayloadLen); ++ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) pucBuffer; ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ ++ /* Fill the Frame Control field. */ ++ if (fgIsReAssoc) ++ u2FrameCtrl = MAC_FRAME_REASSOC_RSP; ++ else ++ u2FrameCtrl = MAC_FRAME_ASSOC_RSP; ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prAssocRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with Target MAC Address. */ ++ COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr); ++ ++ /* Fill the SA field with current BSSID. */ ++ COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID); ++ ++ /* Fill the BSSID field with current BSSID. */ ++ COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prAssocRspFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ ++ /* Fill the Capability Information field. */ ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); */ ++ prAssocRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, prStaRec->u2StatusCode); */ ++ prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, ((prStaRec->u2AssocId & AID_MASK) | AID_MSB)); */ ++ prAssocRspFrame->u2AssocId = ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); /* NOTE(Kevin): Optimized for ARM */ ++ ++ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); ++ ++} /* end of assocComposeReAssocRespFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the (Re)Association Resp frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ UINT_16 u2PayloadLen; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ BOOLEAN fgIsReAssoc; ++ UINT_32 i; ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ fgIsReAssoc = prStaRec->fgIsReAssoc; ++ ++ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + ++ STATUS_CODE_FIELD_LEN + ++ AID_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) { ++ u2EstimatedExtraIELen += txAssocRespIETable[i].u2EstimatedFixedIELen; ++ } else if (txAssocRespIETable[i].pfnCalculateVariableIELen != NULL) { ++ u2EstimatedExtraIELen += (UINT_16) txAssocRespIETable[i].pfnCalculateVariableIELen(prAdapter, ++ prStaRec->ucNetTypeIndex, ++ prStaRec); ++ } ++ ++ } ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(AAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Response.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex != NETWORK_TYPE_AIS_INDEX); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Compose Header and Fixed Field */ ++ assocComposeReAssocRespFrameHeaderAndFF(prStaRec, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prBssInfo->aucBSSID, prBssInfo->u2CapInfo, &u2PayloadLen); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = aaaFsmRunEventTxDone; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ ++ assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo); ++ ++ /* 4 <5> Compose IEs in MSDU_INFO_T */ ++ ++ /* Append IE */ ++ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txAssocRespIETable[i].pfnAppendIE) ++ txAssocRespIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ ++ DBGLOG(SAA, INFO, "Sending (Re)Assoc Response, network: %d seqNo: %d\n", ++ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of assocSendReAssocRespFrame() */ ++#endif /* CFG_SUPPORT_AAA */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c +new file mode 100644 +index 000000000000..43b91d72bd43 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c +@@ -0,0 +1,1211 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1 ++*/ ++ ++/*! \file "auth.c" ++ \brief This file includes the authentication-related functions. ++ ++ This file includes the authentication-related functions. ++*/ ++ ++/* ++** Log: auth.c ++ * ++ * 02 13 2012 cp.wu ++ * NULL ++ * show error message only instead of raise assertion when ++ * received authentication frame is carrying illegal parameters. ++ * ++ * 11 09 2011 yuche.tsai ++ * NULL ++ * Fix a network index & station record index issue when TX deauth frame. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 22 2011 yuche.tsai ++ * NULL ++ * Fix coding error. ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature. ++ * BC deauth support. ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * 1. Fix Service Disocvery Logical issue. ++ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 21 2011 terry.wu ++ * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode ++ * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Check Net is active before sending Deauth frame. ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Send Deauth for Class 3 Error and Leave Network Support ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Fix compile warning ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add debug message for abnormal authentication frame from AP ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * Fix the Debug Label ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update the authComposeAuthFrameHeader() ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the send deauth frame function ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Integrate send Auth with TXM ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++APPEND_IE_ENTRY_T txAuthIETable[] = { ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText} ++}; ++ ++HANDLE_IE_ENTRY_T rxAuthIETable[] = { ++ {ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText} ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Authentication frame header and fixed fields. ++* ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucPeerMACAddress Given Peer MAC Address. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in] u2AuthAlgNum Authentication Algorithm Number ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* @param[in] u2StatusCode Status Code ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN UINT_8 aucPeerMACAddress[], ++ IN UINT_8 aucMACAddress[], ++ IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(aucPeerMACAddress); ++ ASSERT(aucMACAddress); ++ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the Authentication frame. */ ++ /* Fill the Frame Control field. */ ++ u2FrameCtrl = MAC_FRAME_AUTH; ++ ++ /* If this frame is the third frame in the shared key authentication ++ * sequence, it shall be encrypted. ++ */ ++ if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) ++ u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prAuthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress); ++ ++ switch (u2TransactionSeqNum) { ++ case AUTH_TRANSACTION_SEQ_1: ++ case AUTH_TRANSACTION_SEQ_3: ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress); ++ break; ++ ++ case AUTH_TRANSACTION_SEQ_2: ++ case AUTH_TRANSACTION_SEQ_4: ++ ++ /* Fill the BSSID field with Current BSSID. */ ++ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress); ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ /* Clear the SEQ/FRAG_NO field. */ ++ prAuthFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ ++ /* Fill the Authentication Algorithm Number field. */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */ ++ prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Authentication Transaction Sequence Number field. */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */ ++ prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Status Code field. */ ++ /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */ ++ prAuthFrame->u2StatusCode = u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++} /* end of authComposeAuthFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will append Challenge Text IE to the Authentication frame ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TransactionSeqNum; ++ ++ ASSERT(prMsduInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) ++ return; ++ ++ ASSERT(prStaRec); ++ ++ /* For Management, frame header and payload are in a continuous buffer */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket; ++ ++ WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) ++ ++ /* Only consider SEQ_3 for Challenge Text */ ++ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) && ++ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) { ++ ++ COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText); ++ } ++ ++ return; ++ ++} /* end of authAddIEChallengeText() */ ++ ++#if !CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Authenticiation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ UINT_16 u2PayloadLen; ++ UINT_32 i; ++ ++ DBGLOG(SAA, LOUD, "Send Auth Frame\n"); ++ ++ ASSERT(prStaRec); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields */ ++ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ AUTH_ALGORITHM_NUM_FIELD_LEN + ++ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) ++ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Compose Header and some Fixed Fields */ ++ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prStaRec->aucMacAddr, ++ prBssInfo->aucOwnMacAddr, ++ prStaRec->ucAuthAlgNum, u2TransactionSeqNum, STATUS_CODE_RESERVED); ++ ++ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose IEs in MSDU_INFO_T */ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { ++ if (txAuthIETable[i].pfnAppendIE) ++ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Inform TXM to send this Authentication frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of authSendAuthFrame() */ ++ ++#else ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Authenticiation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authSendAuthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) ++{ ++ PUINT_8 pucReceiveAddr; ++ PUINT_8 pucTransmitAddr; ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ /*get from input parameter */ ++ /* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */ ++ PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedExtraIELen; ++ UINT_16 u2PayloadLen; ++ UINT_16 ucAuthAlgNum; ++ UINT_32 i; ++ ++ DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields */ ++ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ AUTH_ALGORITHM_NUM_FIELD_LEN + ++ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) ++ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ ++ if (prStaRec) { ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ pucTransmitAddr = prBssInfo->aucOwnMacAddr; ++ ++ pucReceiveAddr = prStaRec->aucMacAddr; ++ ++ ucAuthAlgNum = prStaRec->ucAuthAlgNum; ++ ++ switch (u2TransactionSeqNum) { ++ case AUTH_TRANSACTION_SEQ_1: ++ case AUTH_TRANSACTION_SEQ_3: ++ pfTxDoneHandler = saaFsmRunEventTxDone; ++ break; ++ ++ case AUTH_TRANSACTION_SEQ_2: ++ case AUTH_TRANSACTION_SEQ_4: ++ pfTxDoneHandler = aaaFsmRunEventTxDone; ++ break; ++ } ++ ++ } else { /* For Error Status Code */ ++ P_WLAN_AUTH_FRAME_T prFalseAuthFrame; ++ ++ ASSERT(prFalseAuthSwRfb); ++ prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader; ++ ++ ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL); ++ ++ pucTransmitAddr = prFalseAuthFrame->aucDestAddr; ++ ++ pucReceiveAddr = prFalseAuthFrame->aucSrcAddr; ++ ++ ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum; ++ ++ u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1); ++ } ++ ++ /* Compose Header and some Fixed Fields */ ++ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucReceiveAddr, ++ pucTransmitAddr, ucAuthAlgNum, u2TransactionSeqNum, u2StatusCode); ++ ++ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ if (prStaRec) ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ else ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; /* false Auth frame */ ++ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose IEs in MSDU_INFO_T */ ++ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { ++ if (txAuthIETable[i].pfnAppendIE) ++ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Inform TXM to send this Authentication frame. */ ++ DBGLOG(SAA, INFO, "network: %d Send Auth Frame %d, Status Code = %d seq num %d\n", ++ eNetTypeIndex, u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum); ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of authSendAuthFrame() */ ++ ++#endif /* CFG_SUPPORT_AAA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will strictly check the TX Authentication frame for SAA/AAA event ++* handling. ++* ++* @param[in] prMsduInfo Pointer of MSDU_INFO_T ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TxFrameCtrl; ++ UINT_16 u2TxAuthAlgNum; ++ UINT_16 u2TxTransactionSeqNum; ++ ++ ASSERT(prMsduInfo); ++ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) (prMsduInfo->prPacket); ++ ASSERT(prAuthFrame); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */ ++ u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ u2TxFrameCtrl &= MASK_FRAME_TYPE; ++ if (u2TxFrameCtrl != MAC_FRAME_AUTH) ++ return WLAN_STATUS_FAILURE; ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */ ++ u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2TxAuthAlgNum != (UINT_16) (prStaRec->ucAuthAlgNum)) ++ return WLAN_STATUS_FAILURE; ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum) */ ++ u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2TxTransactionSeqNum != u2TransactionSeqNum) ++ return WLAN_STATUS_FAILURE; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authCheckTxAuthFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the incoming Auth Frame's Transaction Sequence ++* Number before delivering it to the corresponding SAA or AAA Module. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always not retain authentication frames ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2RxTransactionSeqNum; ++ ++ ASSERT(prSwRfb); ++ ++ /* 4 <1> locate the Authentication Frame. */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Authentication Frame. */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN + ++ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + ++ STATUS_CODE_FIELD_LEN)) { ++ ASSERT(0); ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ ++ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ switch (u2RxTransactionSeqNum) { ++ case AUTH_TRANSACTION_SEQ_2: ++ case AUTH_TRANSACTION_SEQ_4: ++ saaFsmRunEventRxAuth(prAdapter, prSwRfb); ++ break; ++ ++ case AUTH_TRANSACTION_SEQ_1: ++ case AUTH_TRANSACTION_SEQ_3: ++#if CFG_SUPPORT_AAA ++ aaaFsmRunEventRxAuth(prAdapter, prSwRfb); ++#endif /* CFG_SUPPORT_AAA */ ++ break; ++ ++ default: ++ DBGLOG(SAA, WARN, "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n", ++ u2RxTransactionSeqNum, prAuthFrame->u2StatusCode); ++ break; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authCheckRxAuthFrameTransSeq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the incoming Authentication Frame and take ++* the status code out. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] u2TransactionSeqNum Transaction Sequence Number ++* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2RxAuthAlgNum; ++ UINT_16 u2RxTransactionSeqNum; ++ /* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */ ++ ++ ASSERT(prSwRfb); ++ ASSERT(pu2StatusCode); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ /* 4 <1> locate the Authentication Frame. */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */ ++ u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2RxAuthAlgNum != (UINT_16) prStaRec->ucAuthAlgNum) { ++ DBGLOG(SAA, WARN, "Discard Auth frame with auth type = %d, current = %d\n", ++ u2RxAuthAlgNum, prStaRec->ucAuthAlgNum); ++ *pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ ++ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ if (u2RxTransactionSeqNum != u2TransactionSeqNum) { ++ DBGLOG(SAA, WARN, "Discard Auth frame with Transaction Seq No = %d\n", u2RxTransactionSeqNum); ++ *pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; ++ return WLAN_STATUS_SUCCESS; ++ } ++ /* 4 <3> Get the Status code */ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */ ++ /* *pu2StatusCode = u2RxStatusCode; */ ++ *pu2StatusCode = prAuthFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authCheckRxAuthFrameStatus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Challenge Text IE from the Authentication frame ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] prIEHdr Pointer to start address of IE ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2TransactionSeqNum; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prIEHdr); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return; ++ ++ /* For Management, frame header and payload are in a continuous buffer */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) */ ++ u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Only consider SEQ_2 for Challenge Text */ ++ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) && ++ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) { ++ ++ /* Free previous allocated TCM memory */ ++ if (prStaRec->prChallengeText) { ++ ASSERT(0); ++ cnmMemFree(prAdapter, prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ ++ prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)); ++ if (prStaRec->prChallengeText == NULL) ++ return; ++ ++ /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */ ++ COPY_IE(prStaRec->prChallengeText, prIEHdr); ++ } ++ ++ return; ++ ++} /* end of authAddIEChallengeText() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Authentication frame. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ PUINT_8 pucIEsBuffer; ++ UINT_16 u2IEsLen; ++ UINT_16 u2Offset; ++ UINT_8 ucIEID; ++ UINT_32 i; ++ ++ ASSERT(prSwRfb); ++ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ pucIEsBuffer = &prAuthFrame->aucInfoElem[0]; ++ u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); ++ ++ IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) { ++ ucIEID = IE_ID(pucIEsBuffer); ++ ++ for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) { ++ ++ if (ucIEID == rxAuthIETable[i].ucElemID) ++ rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIEsBuffer); ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authProcessRxAuth2_Auth4Frame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Deauthentication frame ++* ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] aucPeerMACAddress Given Peer MAC Address. ++* @param[in] aucMACAddress Given Our MAC Address. ++* @param[in] u2StatusCode Status Code ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID ++authComposeDeauthFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN UINT_8 aucPeerMACAddress[], ++ IN UINT_8 aucMACAddress[], IN UINT_8 aucBssid[], IN UINT_16 u2ReasonCode) ++{ ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(aucPeerMACAddress); ++ ASSERT(aucMACAddress); ++ ASSERT(aucBssid); ++ ++ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the Deauthentication frame. */ ++ /* Fill the Frame Control field. */ ++ u2FrameCtrl = MAC_FRAME_DEAUTH; ++ ++ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prDeauthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with Target BSSID. */ ++ COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress); ++ ++ /* Fill the BSSID field with Target BSSID. */ ++ COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prDeauthFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ ++ /* Fill the Status Code field. */ ++ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */ ++ prDeauthFrame->u2ReasonCode = u2ReasonCode; /* NOTE(Kevin): Optimized for ARM */ ++ ++} /* end of authComposeDeauthFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send the Deauthenticiation frame ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prClassErrSwRfb Pointer to the SW_RFB_T which is Class Error. ++* @param[in] u2ReasonCode A reason code to indicate why to leave BSS. ++* @param[in] pfTxDoneHandler TX Done call back function ++* ++* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. ++* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module ++* @retval WLAN_STATUS_FAILURE Didn't send Deauth frame for various reasons. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authSendDeauthFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_WLAN_MAC_HEADER_A4_T prWlanMacHeader = NULL; ++ PUINT_8 pucReceiveAddr; ++ PUINT_8 pucTransmitAddr; ++ PUINT_8 pucBssid = NULL; ++ ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2RxFrameCtrl; ++ P_BSS_INFO_T prBssInfo; ++ ++ P_DEAUTH_INFO_T prDeauthInfo; ++ OS_SYSTIME rCurrentTime; ++ INT_32 i4NewEntryIndex, i; ++ UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ UINT_8 aucBMC[] = BC_MAC_ADDR; ++#endif ++ ++ /* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data ++ * frame ++ */ ++ /* 4 <1> Find the Receiver Address first. */ ++ if (prClassErrSwRfb) { ++ BOOLEAN fgIsAbleToSendDeauth = FALSE; ++ ++ prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader; ++ ++ /* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl); */ ++ u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */ ++ if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0) ++ return WLAN_STATUS_FAILURE; ++ ++ /* Check if corresponding BSS is able to send Deauth */ ++ for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]); ++ ++ if (IS_NET_ACTIVE(prAdapter, i) && ++ (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) { ++ { ++ fgIsAbleToSendDeauth = TRUE; ++ eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) i; ++ break; ++ } ++ } ++ } ++ ++ if (!fgIsAbleToSendDeauth) ++ return WLAN_STATUS_FAILURE; ++ ++ pucReceiveAddr = prWlanMacHeader->aucAddr2; ++ ++ } else if (prStaRec) { ++ ++ pucReceiveAddr = prStaRec->aucMacAddr; ++ } else { ++#if CFG_ENABLE_WIFI_DIRECT ++ pucReceiveAddr = aucBMC; ++#else ++ return WLAN_STATUS_FAILURE; ++#endif ++ } ++ ++ /* 4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC */ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ i4NewEntryIndex = -1; ++ for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) { ++ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]); ++ ++ /* For continuously sending Deauth frame, the minimum interval is ++ * MIN_DEAUTH_INTERVAL_MSEC. ++ */ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, ++ prDeauthInfo->rLastSendTime, MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) { ++ ++ i4NewEntryIndex = i; ++ } else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) && (!pfTxDoneHandler)) { ++ ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++ /* 4 <3> Update information. */ ++ if (i4NewEntryIndex > 0) { ++ ++ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]); ++ ++ COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr); ++ prDeauthInfo->rLastSendTime = rCurrentTime; ++ } else { ++ /* NOTE(Kevin): for the case of AP mode, we may encounter this case ++ * if deauth all the associated clients. ++ */ ++ DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n"); ++ } ++ ++ /* 4 <4> Allocate a PKT_INFO_T for Deauthentication Frame */ ++ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ ++ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN); ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Deauth Request.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <5> Find the Transmitter Address and BSSID. */ ++ if (prClassErrSwRfb) { ++ ++ /* The TA of Deauth is the A1 of RX frame */ ++ pucTransmitAddr = prWlanMacHeader->aucAddr1; ++ ++ switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) { ++ ++ case MASK_FC_FROM_DS: ++ /* The BSSID of Deauth is the A2 of RX frame */ ++ pucBssid = prWlanMacHeader->aucAddr2; ++ break; ++ ++ case MASK_FC_TO_DS: ++ /* The BSSID of Deauth is the A1 of RX frame */ ++ pucBssid = prWlanMacHeader->aucAddr1; ++ break; ++ ++ case MASK_TO_DS_FROM_DS: ++ /* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth ++ * to the A2 of RX frame for temporary solution. ++ */ ++ pucBssid = prWlanMacHeader->aucAddr2; ++ break; ++ ++ /* No Default */ ++ } ++ ++ } else if (prStaRec) { ++ eNetTypeIndex = prStaRec->ucNetTypeIndex; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ pucTransmitAddr = prBssInfo->aucOwnMacAddr; ++ ++ pucBssid = prBssInfo->aucBSSID; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else { ++ if (prAdapter->fgIsP2PRegistered) { ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ ucStaRecIdx = STA_REC_INDEX_BMCAST; ++ ++ pucTransmitAddr = prBssInfo->aucOwnMacAddr; ++ ++ pucBssid = prBssInfo->aucBSSID; ++ ++ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ } else { ++ /* 20130122: free packet by samplin */ ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ return WLAN_STATUS_FAILURE; ++ } ++ } ++ ++#endif ++ ++ /* 4 <6> compose Deauthentication frame header and some fixed fields */ ++ authComposeDeauthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucReceiveAddr, pucTransmitAddr, pucBssid, u2ReasonCode); ++ ++#if CFG_SUPPORT_802_11W ++ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ ++ prDeauthFrame = ++ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ DBGLOG(TX, WARN, "authSendDeauthFrame with protection\n"); ++ } ++#endif ++ ++ /* 4 <7> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = ((prStaRec == NULL) ? ucStaRecIdx : prStaRec->ucIndex); ++ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ DBGLOG(SAA, INFO, "Sending Deauth, network: %d, seqNo %d\n", ++ eNetTypeIndex, prMsduInfo->ucTxSeqNum); ++ ++ /* 4 <8> Inform TXM to send this Deauthentication frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of authSendDeauthFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Deauthentication frame ++* if the given BSSID is matched. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] aucBSSID Given BSSID ++* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. ++* ++* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) ++{ ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ UINT_16 u2RxReasonCode; ++ ++ ASSERT(prSwRfb); ++ ASSERT(aucBSSID); ++ ASSERT(pu2ReasonCode); ++ ++ /* 4 <1> locate the Deauthentication Frame. */ ++ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Parse the Header of Deauthentication Frame. */ ++#if 0 /* Kevin: Seems redundant */ ++ WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl) ++ u2RxFrameCtrl &= MASK_FRAME_TYPE; ++ if (u2RxFrameCtrl != MAC_FRAME_DEAUTH) ++ return WLAN_STATUS_FAILURE; ++#endif ++ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Check if this Deauth Frame is coming from Target BSSID */ ++ if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) { ++ DBGLOG(SAA, LOUD, "Ignore Deauth Frame from other BSS [ %pM ]\n", ++ prDeauthFrame->aucSrcAddr); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ ++ WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode); ++ *pu2ReasonCode = u2RxReasonCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authProcessRxDeauthFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will parse and process the incoming Authentication frame. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] aucExpectedBSSID Given Expected BSSID. ++* @param[in] u2ExpectedAuthAlgNum Given Expected Authentication Algorithm Number ++* @param[in] u2ExpectedTransSeqNum Given Expected Transaction Sequence Number. ++* @param[out] pu2ReturnStatusCode Return Status Code. ++* ++* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. ++* @retval WLAN_STATUS_FAILURE The frame we will ignore. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN UINT_8 aucExpectedBSSID[], ++ IN UINT_16 u2ExpectedAuthAlgNum, ++ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode) ++{ ++ P_WLAN_AUTH_FRAME_T prAuthFrame; ++ UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ ASSERT(prSwRfb); ++ ASSERT(aucExpectedBSSID); ++ ASSERT(pu2ReturnStatusCode); ++ ++ /* 4 <1> locate the Authentication Frame. */ ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ /* 4 <2> Check the BSSID */ ++ if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID)) ++ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ ++ /* 4 <3> Check the SA, which should not be MC/BC */ ++ if (prAuthFrame->aucSrcAddr[0] & BIT(0)) { ++ DBGLOG(P2P, WARN, "Invalid STA MAC with MC/BC bit set: %pM\n", ++ prAuthFrame->aucSrcAddr); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */ ++ if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum) ++ u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; ++ ++ if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum) ++ u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; ++ ++ *pu2ReturnStatusCode = u2ReturnStatusCode; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of authProcessRxAuth1Frame() */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c +new file mode 100644 +index 000000000000..160779583655 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c +@@ -0,0 +1,2521 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/bss.c#3 ++*/ ++ ++/*! \file "bss.c" ++ \brief This file contains the functions for creating BSS(AP)/IBSS(AdHoc). ++ ++ This file contains the functions for BSS(AP)/IBSS(AdHoc). We may create a BSS/IBSS ++ network, or merge with exist IBSS network and sending Beacon Frame or reply ++ the Probe Response Frame for received Probe Request Frame. ++*/ ++ ++/* ++** Log: bss.c ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 14 2012 chinglan.wang ++ * NULL ++ * Fix the losing of the HT IE in assoc request.. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 08 2012 yuche.tsai ++ * NULL ++ * Fix FW assert when start Hot-Spot. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 01 20 2012 chinglan.wang ++ * 03 02 2012 terry.wu ++ * NULL ++ * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug. ++ * ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 15 2012 yuche.tsai ++ * NULL ++ * Fix wrong basic rate issue. ++ * ++ * 01 13 2012 yuche.tsai ++ * NULL ++ * WiFi Hot Spot Tethering for ICS ALPHA testing version. ++ * ++ * 11 03 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Always set short slot time to TRUE initially in AP mode ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 09 14 2011 yuche.tsai ++ * NULL ++ * Add P2P IE in assoc response. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 29 2011 eddie.chen ++ * [WCXRP00000608] [MT6620 Wi-Fi][DRV] Change wmm parameters in beacon ++ * Change wmm parameters in beacon. ++ * ++ * 03 29 2011 yuche.tsai ++ * [WCXRP00000607] [Volunteer Patch][MT6620][Driver] Coding Style Fix for klocwork scan. ++ * Fix klocwork issue. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Make assoc req to append P2P IE if wifi direct is enabled. ++ * ++ * 03 11 2011 chinglan.wang ++ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. ++ * . ++ * ++ * 03 03 2011 george.huang ++ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated ++ * . ++ * ++ * 03 03 2011 george.huang ++ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated ++ * modify to handle if beacon MSDU been released when BSS deactivated ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add code to let the beacon and probe response for Auto GO WSC . ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * Add code to send beacon and probe response WSC IE at Auto GO. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 12 2011 yuche.tsai ++ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. ++ * bss should create station record type according to callers input. ++ * ++ * 02 11 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * In p2p link function, check networktype before calling p2p function. ++ * ++ * 02 11 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * Modify p2p link function to avoid assert. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 25 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Fix the compile error in windows. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Add destination decision in AP mode. ++ * ++ * 01 24 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * .Fix typo and missing entry ++ * ++ * 12 30 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Fix prBssInfo->aucCWminLog to prBssInfo->aucCWminLogForBcast ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++ ++Add per station flow control when STA is in PS ++ ++ * Add WMM parameter for broadcast. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * Finish SLT TX/RX & Rate Changing Support. ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Before composing Beacon IE, assign network type index for msdu info, ++ * this information is needed by RLM module while composing some RLM related IE field. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Fix undefined pucDestAddr in bssUpdateBeaconContent() ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 11 2010 cp.wu ++ * NULL ++ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) ++ * 2) extending scanning result to 64 instead of 48 ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 08 02 2010 george.huang ++ * NULL ++ * add WMM-PS test related OID/ CMD handlers ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add support to RX probe response for P2P. ++ * ++ * 07 20 2010 cp.wu ++ * ++ * 1) bugfix: do not stop timer for join after switched into normal_tr state, for providing chance for DHCP handshasking ++ * 2) modify rsnPerformPolicySelection() invoking ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * when IBSS is being merged-in, send command packet to PM for connected indication ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error while enable WIFI_DIRECT support. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct when ADHOC support is turned on. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * auth.c is migrated. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fix compilation error when WIFI_DIRECT is turned on ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add bss.c. ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update bssProcessProbeRequest() to avoid redundant SSID IE {0,0} for IOT. ++ * ++ * 05 21 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set ++ * ++ * 05 18 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Ad-hoc Beacon should not carry HT OP and OBSS IEs ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Use TX MGMT Frame API for sending PS NULL frame to avoid the TX Burst Mechanism in TX FW Frame API ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Separate Beacon and ProbeResp IE array ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed the use of compiling flag MQM_WMM_PARSING ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 20 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Fix restart Beacon Timeout Func after connection diagnosis ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 04 16 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the wpa-none for ibss beacon. ++ * ++ * 04 15 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the protected bit at cap info for ad-hoc. ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Rename the CFG flags ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Update outgoing beacon's TX data rate ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add DTIM count update while TX Beacon ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify code due to define - BAND_24G and specific BSS_INFO_T was changed ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Revise data structure to share the same BSS_INFO_T for avoiding coding error ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) ++APPEND_VAR_IE_ENTRY_T txBcnIETable[] = { ++ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}, /* 221 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE}, /* 221 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++ {0, p2pFuncCalculateExtra_IELenForBeacon, p2pFuncGenerateExtra_IEForBeacon}, /* 221 */ ++#else ++ {0, p2pFuncCalculateP2p_IELenForBeacon, p2pFuncGenerateP2p_IEForBeacon}, /* 221 */ ++ {0, p2pFuncCalculateWSC_IELenForBeacon, p2pFuncGenerateWSC_IEForBeacon}, /* 221 */ ++ {0, p2pFuncCalculateP2P_IE_NoA, p2pFuncGenerateP2P_IE_NoA}, /* 221 */ ++#endif ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++}; ++ ++APPEND_VAR_IE_ENTRY_T txProbRspIETable[] = { ++ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ ++#if CFG_ENABLE_WIFI_DIRECT ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ ++#endif ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ ++ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ ++}; ++ ++#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines for all Operation Modes */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T for ++* Infrastructure or AdHoc Mode. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eStaType Assign STA Type for this STA_RECORD_T ++* @param[in] eNetTypeIndex Assign Net Type Index for this STA_RECORD_T ++* @param[in] prBssDesc Received Beacon/ProbeResp from this STA ++* ++* @retval Pointer to STA_RECORD_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T ++bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_STA_TYPE_T eStaType, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_8 ucNonHTPhyTypeSet; ++ ++ ASSERT(prBssDesc); ++ ++ /* 4 <1> Get a valid STA_RECORD_T */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); ++ if (!prStaRec) { ++ ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) eNetTypeIndex); ++ ++ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for ++ * exhausted case and do removal of unused STA_RECORD_T. ++ */ ++ ++ if (!prStaRec) { ++ ASSERT(FALSE); ++ return NULL; ++ } ++ ++ ASSERT(prStaRec); ++ ++ prStaRec->ucStaState = STA_STATE_1; ++ prStaRec->ucJoinFailureCount = 0; ++ /* TODO(Kevin): If this is an old entry, we may also reset the ucJoinFailureCount to 0. ++ */ ++ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prBssDesc->aucSrcAddr); ++ } ++ /* 4 <2> Setup STA TYPE and NETWORK */ ++ prStaRec->eStaType = eStaType; ++ ++ prStaRec->ucNetTypeIndex = eNetTypeIndex; ++ ++ /* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */ ++ prStaRec->u2CapInfo = prBssDesc->u2CapInfo; ++ ++ prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet; ++ prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet; ++ ++ prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet; ++ if (IS_STA_IN_AIS(prStaRec)) { ++ if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) || ++ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) || ++ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED) || ++ (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz))) { ++ DBGLOG(BSS, TRACE, "Ignore the HT Bit for TKIP as pairwise cipher configured!\n"); ++ prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; ++ } ++ } else { ++ DBGLOG(BSS, TRACE, "P2P skip TKIP limitation for HT Hit!\n"); ++ } ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet; ++ ++ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; ++ ++ /* Check for Target BSS's non HT Phy Types */ ++ if (ucNonHTPhyTypeSet) { ++ ++ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; ++ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; ++ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ ++ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++ prStaRec->fgHasBasicPhyType = TRUE; ++ } else { ++ /* Use mandatory for 11N only BSS */ ++ ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); ++ ++ { ++ /* TODO(Kevin): which value should we set for 11n ? ERP ? */ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++ prStaRec->fgHasBasicPhyType = FALSE; ++ } ++ ++ /* Update non HT Desired Rate Set */ ++ { ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ prStaRec->u2DesiredNonHTRateSet = ++ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); ++ } ++ ++ /* 4 <4> Update information from BSS_DESC_T to current P_STA_RECORD_T */ ++ if (IS_AP_STA(prStaRec)) { ++ /* do not need to parse IE for DTIM, ++ * which have been parsed before inserting into BSS_DESC_T ++ */ ++ if (prBssDesc->ucDTIMPeriod) ++ prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; ++ else ++ prStaRec->ucDTIMPeriod = 0; /* Means that TIM was not parsed. */ ++ } ++ /* 4 <5> Update default value */ ++ prStaRec->fgDiagnoseConnection = FALSE; ++ ++ /* 4 <6> Update default value for other Modules */ ++ /* Determine fgIsWmmSupported and fgIsUapsdSupported in STA_REC */ ++ mqmProcessScanResult(prAdapter, prBssDesc, prStaRec); ++ ++ return prStaRec; ++ ++} /* end of bssCreateStaRecFromBssDesc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Null Data frame. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] prStaRec Pointer to the STA_RECORD_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec) ++{ ++ P_WLAN_MAC_HEADER_T prNullFrame; ++ P_BSS_INFO_T prBssInfo; ++ UINT_16 u2FrameCtrl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ ASSERT(prBssInfo); ++ ++ prNullFrame = (P_WLAN_MAC_HEADER_T) pucBuffer; ++ ++ /* 4 <1> Decide the Frame Control Field */ ++ u2FrameCtrl = MAC_FRAME_NULL; ++ ++ if (IS_AP_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_TO_DS; ++ ++ if (prStaRec->fgSetPwrMgtBit) ++ u2FrameCtrl |= MASK_FC_PWR_MGT; ++ } else if (IS_CLIENT_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_FROM_DS; ++ } else if (IS_DLS_STA(prStaRec)) { ++ /* TODO(Kevin) */ ++ } else { ++ /* NOTE(Kevin): We won't send Null frame for IBSS */ ++ ASSERT(0); ++ return; ++ } ++ ++ /* 4 <2> Compose the Null frame */ ++ /* Fill the Frame Control field. */ ++ /* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Address 1 field with Target Peer Address. */ ++ COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr); ++ ++ /* Fill the Address 2 field with our MAC Address. */ ++ COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); ++ ++ /* Fill the Address 3 field with Target BSSID. */ ++ COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prNullFrame->u2SeqCtrl = 0; ++ ++ return; ++ ++} /* end of bssComposeNullFrameHeader() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the QoS Null Data frame. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] prStaRec Pointer to the STA_RECORD_T. ++* @param[in] ucUP User Priority. ++* @param[in] fgSetEOSP Set the EOSP bit. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP) ++{ ++ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; ++ P_BSS_INFO_T prBssInfo; ++ UINT_16 u2FrameCtrl; ++ UINT_16 u2QosControl; ++ ++ ASSERT(pucBuffer); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ ASSERT(prBssInfo); ++ ++ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) pucBuffer; ++ ++ /* 4 <1> Decide the Frame Control Field */ ++ u2FrameCtrl = MAC_FRAME_QOS_NULL; ++ ++ if (IS_AP_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_TO_DS; ++ ++ if (prStaRec->fgSetPwrMgtBit) ++ u2FrameCtrl |= MASK_FC_PWR_MGT; ++ } else if (IS_CLIENT_STA(prStaRec)) { ++ u2FrameCtrl |= MASK_FC_FROM_DS; ++ } else if (IS_DLS_STA(prStaRec)) { ++ /* TODO(Kevin) */ ++ } else { ++ /* NOTE(Kevin): We won't send QoS Null frame for IBSS */ ++ ASSERT(0); ++ return; ++ } ++ ++ /* 4 <2> Compose the QoS Null frame */ ++ /* Fill the Frame Control field. */ ++ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prQoSNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Address 1 field with Target Peer Address. */ ++ COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr); ++ ++ /* Fill the Address 2 field with our MAC Address. */ ++ COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); ++ ++ /* Fill the Address 3 field with Target BSSID. */ ++ COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prQoSNullFrame->u2SeqCtrl = 0; ++ ++ u2QosControl = (UINT_16) (ucUP & WMM_QC_UP_MASK); ++ ++ if (fgSetEOSP) ++ u2QosControl |= WMM_QC_EOSP; ++ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */ ++ prQoSNullFrame->u2QosCtrl = u2QosControl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ return; ++ ++} /* end of bssComposeQoSNullFrameHeader() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send the Null Frame ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pfTxDoneHandler TX Done call back function ++* ++* @retval WLAN_STATUS_RESOURCE No available resources to send frame. ++* @retval WLAN_STATUS_SUCCESS Succe]ss. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ ++ /* Init with MGMT Header Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ ++ bssComposeNullFrame(prAdapter, (PUINT_8) ((ULONG) prMsduInfo->prPacket + MAC_TX_RESERVED_FIELD), prStaRec); ++#if 0 ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ TXM_SET_DATA_PACKET( ++ /* STA_REC ptr */ prStaRec, ++ /* MSDU_INFO ptr */ prMsduInfo, ++ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), ++ /* MAC HDR length */ WLAN_MAC_HEADER_LEN, ++ /* PAYLOAD ptr */ ++ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN), ++ /* PAYLOAD length */ 0, ++ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, ++ /* TID */ 0 /* BE: AC1 */ , ++ /* Flag 802.11 */ TRUE, ++ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , ++ /* Resource TC */ 0 /* Irrelevant */ , ++ /* Flag 802.1x */ FALSE, ++ /* TX-done callback */ pfTxDoneHandler, ++ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, ++ /* PS Session ID */ 0 /* Irrelevant */ , ++ /* Flag fixed rate */ TRUE, ++ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, ++ /* Fixed-rate retry */ BSS_DEFAULT_CONN_TEST_NULL_FRAME_RETRY_LIMIT, ++ /* PAL LLH */ 0 /* Irrelevant */ , ++ /* ACL SN */ 0 /* Irrelevant */ , ++ /* Flag No Ack */ FALSE ++ ); ++ ++ /* Terminate with a NULL pointer */ ++ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* Indicate the packet to TXM */ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ txmSendFwDataPackets(prMsduInfo); ++#endif ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssSendNullFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send the QoS Null Frame ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] pfTxDoneHandler TX Done call back function ++* ++* @retval WLAN_STATUS_RESOURCE No available resources to send frame. ++* @retval WLAN_STATUS_SUCCESS Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ ++ /* Init with MGMT Header Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ ++ bssComposeQoSNullFrame(prAdapter, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prStaRec, ucUP, FALSE); ++#if 0 ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ TXM_SET_DATA_PACKET( ++ /* STA_REC ptr */ prStaRec, ++ /* MSDU_INFO ptr */ prMsduInfo, ++ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), ++ /* MAC HDR length */ WLAN_MAC_HEADER_QOS_LEN, ++ /* PAYLOAD ptr */ ++ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN), ++ /* PAYLOAD length */ 0, ++ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, ++ /* TID */ 0 /* BE: AC1 */ , ++ /* Flag 802.11 */ TRUE, ++ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , ++ /* Resource TC */ 0 /* Irrelevant */ , ++ /* Flag 802.1x */ FALSE, ++ /* TX-done callback */ pfTxDoneHandler, ++ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, ++ /* PS Session ID */ 0 /* Irrelevant */ , ++ /* Flag fixed rate */ TRUE, ++ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, ++ /* Fixed-rate retry */ TXM_DEFAULT_DATA_FRAME_RETRY_LIMIT, ++ /* PAL LLH */ 0 /* Irrelevant */ , ++ /* ACL SN */ 0 /* Irrelevant */ , ++ /* Flag No Ack */ FALSE ++ ); ++ ++ /* Terminate with a NULL pointer */ ++ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* Indicate the packet to TXM */ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ txmSendFwDataPackets(prMsduInfo); ++#endif ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssSendQoSNullFrame() */ ++ ++#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) ++/*----------------------------------------------------------------------------*/ ++/* Routines for both IBSS(AdHoc) and BSS(AP) */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate Information Elements of Extended ++* Support Rate ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ PUINT_8 pucBuffer; ++ UINT_8 ucExtSupRatesLen; ++ ++ ASSERT(prMsduInfo); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); ++ ASSERT(prBssInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ++ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; ++ else ++ ucExtSupRatesLen = 0; ++ ++ /* Fill the Extended Supported Rates element. */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, ++ &prBssInfo->aucAllSupportedRates[ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* end of bssGenerateExtSuppRate_IE() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for Beacon ++* or Probe Response Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr) ++{ ++ PUINT_8 pucBuffer; ++ UINT_8 ucSupRatesLen; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prBssInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ASSERT(pucBuffer); ++ ++ /* Compose the frame body of the Probe Response frame. */ ++ /* 4 <1> Fill the SSID element. */ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ if (prBssInfo->eHiddenSsidType == ENUM_HIDDEN_SSID_LEN) { ++ if ((!pucDestAddr) && /* For Beacon only */ ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { ++ SSID_IE(pucBuffer)->ucLength = 0; ++ } else { /* Probe response */ ++ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; ++ if (prBssInfo->ucSSIDLen) ++ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ } ++ } else { ++ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; ++ if (prBssInfo->ucSSIDLen) ++ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ } ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ /* 4 <2> Fill the Supported Rates element. */ ++ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ++ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; ++ else ++ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; ++ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ /* 4 <3> Fill the DS Parameter Set element. */ ++ if (prBssInfo->eBand == BAND_2G4) { ++ DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET; ++ DS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_DS_PARAMETER_SET; ++ DS_PARAM_IE(pucBuffer)->ucCurrChnl = prBssInfo->ucPrimaryChannel; ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ /* 4 <4> IBSS Parameter Set element, ID: 6 */ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET; ++ IBSS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_IBSS_PARAMETER_SET; ++ WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), prBssInfo->u2ATIMWindow); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ } ++ /* 4 <5> TIM element, ID: 5 */ ++ if ((!pucDestAddr) && /* For Beacon only. */ ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /*no fgIsP2PRegistered protect */ ++ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++#if 0 ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ UINT_8 ucBitmapControl = 0; ++ UINT_32 u4N1, u4N2; ++ ++ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); ++ ++ /* Clear existing value. */ ++ prP2pSpecificBssInfo->ucBitmapCtrl = 0; ++ kalMemZero(prP2pSpecificBssInfo->aucPartialVirtualBitmap, ++ sizeof(prP2pSpecificBssInfo->aucPartialVirtualBitmap)); ++ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ TIM_IE(pucBuffer)->ucDTIMCount = prBssInfo->ucDTIMCount; ++ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; ++ ++ /* Setup DTIM Count for next TBTT. */ ++ if (prBssInfo->ucDTIMCount == 0) { ++ /*Do nothing*/ ++ /* 3 *** pmQueryBufferedBCAST(); */ ++ } ++ /* 3 *** pmQueryBufferedPSNode(); */ ++ /* TODO(Kevin): Call PM Module here to loop all STA_RECORD_Ts and it ++ * will call bssSetTIMBitmap to toggle the Bitmap. ++ */ ++ ++ /* Set Virtual Bitmap for UCAST */ ++ u4N1 = (prP2pSpecificBssInfo->u2SmallestAID >> 4) << 1; /* Find the largest even number. */ ++ u4N2 = prP2pSpecificBssInfo->u2LargestAID >> 3; /* Find the smallest number. */ ++ ++ ASSERT(u4N2 >= u4N1); ++ ++ kalMemCopy(TIM_IE(pucBuffer)->aucPartialVirtualMap, ++ &prP2pSpecificBssInfo->aucPartialVirtualBitmap[u4N1], ((u4N2 - u4N1) + 1)); ++ ++ /* Set Virtual Bitmap for BMCAST */ ++ /* BMC bit only indicated when DTIM count == 0. */ ++ if (prBssInfo->ucDTIMCount == 0) ++ ucBitmapControl = prP2pSpecificBssInfo->ucBitmapCtrl; ++ TIM_IE(pucBuffer)->ucBitmapControl = ucBitmapControl | (UINT_8) u4N1; ++ ++ TIM_IE(pucBuffer)->ucLength = ((u4N2 - u4N1) + 4); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++#else ++ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ ++ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP); /*((u4N2 - u4N1) + 4) */ ++ /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucDTIMCount = 0; /*prBssInfo->ucDTIMCount */ ++ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; ++ /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucBitmapControl = 0; /*ucBitmapControl | (UINT_8)u4N1 */ ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ ++#endif ++ ++ } else ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ { ++ /* NOTE(Kevin): 1. AIS - Didn't Support AP Mode. ++ * 2. BOW - Didn't Support BCAST and PS. ++ */ ++ } ++ ++ } ++ ++} /* end of bssBuildBeaconProbeRespFrameCommonIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Beacon/Probe Response frame header and ++* its fixed fields. ++* ++* @param[in] pucBuffer Pointer to the frame buffer. ++* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. ++* @param[in] pucOwnMACAddress Given Our MAC Address. ++* @param[in] pucBSSID Given BSSID of the BSS. ++* @param[in] u2BeaconInterval Given Beacon Interval. ++* @param[in] u2CapInfo Given Capability Info. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, ++ IN PUINT_8 pucDestAddr, ++ IN PUINT_8 pucOwnMACAddress, ++ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo) ++{ ++ P_WLAN_BEACON_FRAME_T prBcnProbRspFrame; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ UINT_16 u2FrameCtrl; ++ ++ DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF"); ++ /* DBGLOG(INIT, LOUD, ("\n")); */ ++ ++ ASSERT(pucBuffer); ++ ASSERT(pucOwnMACAddress); ++ ASSERT(pucBSSID); ++ ++ prBcnProbRspFrame = (P_WLAN_BEACON_FRAME_T) pucBuffer; ++ ++ /* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */ ++ /* Fill the Frame Control field. */ ++ if (pucDestAddr) { ++ u2FrameCtrl = MAC_FRAME_PROBE_RSP; ++ } else { ++ u2FrameCtrl = MAC_FRAME_BEACON; ++ pucDestAddr = aucBCAddr; ++ } ++ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */ ++ prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */ ++ COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr); ++ ++ /* Fill the SA field with our MAC Address. */ ++ COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress); ++ ++ /* Fill the BSSID field with current BSSID. */ ++ COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID); ++ ++ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ ++ prBcnProbRspFrame->u2SeqCtrl = 0; ++ ++ /* 4 <2> Compose the frame body's common fixed field part of the Beacon /ProbeResp frame. */ ++ /* MAC will update TimeStamp field */ ++ ++ /* Fill the Beacon Interval field. */ ++ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, u2BeaconInterval); */ ++ prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval; /* NOTE(Kevin): Optimized for ARM */ ++ ++ /* Fill the Capability Information field. */ ++ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */ ++ prBcnProbRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ ++ ++} /* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eNetTypeIndex Specify which network reply the Probe Response. ++* ++* @retval WLAN_STATUS_SUCCESS Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_WLAN_BEACON_FRAME_T prBcnFrame; ++ UINT_32 i; ++ ++ DEBUGFUNC("bssUpdateBeaconContent"); ++ DBGLOG(BSS, LOUD, "\n"); ++ ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */ ++ /* Allocate a MSDU_INFO_T */ ++ /* For Beacon */ ++ prMsduInfo = prBssInfo->prBeacon; ++ ++ /* beacon prMsduInfo will be NULLify once BSS deactivated, so skip if it is */ ++ if (prMsduInfo == NULL) ++ return WLAN_STATUS_SUCCESS; ++ /* 4 <2> Compose header */ ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ NULL, ++ prBssInfo->aucOwnMacAddr, ++ prBssInfo->aucBSSID, ++ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); ++ ++ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + ++ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); ++ ++ prMsduInfo->ucNetworkType = eNetTypeIndex; ++ ++ /* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */ ++ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL); ++ ++ /* 4 <4> Compose IEs in MSDU_INFO_T */ ++ ++ /* Append IE for Beacon */ ++ for (i = 0; i < sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { ++ if (txBcnIETable[i].pfnAppendIE) ++ txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; ++ ++ return nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ eNetTypeIndex, ++ prBssInfo->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)); ++ ++} /* end of bssUpdateBeaconContent() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to the given ++* Destination Address. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eNetTypeIndex Specify which network reply the Probe Response. ++* @param[in] pucDestAddr Pointer to the Destination Address to reply ++* @param[in] u4ControlFlags Control flags for information on Probe Response. ++* ++* @retval WLAN_STATUS_RESOURCE No available resources to send frame. ++* @retval WLAN_STATUS_SUCCESS Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ UINT_16 u2EstimatedFixedIELen; ++ UINT_16 u2EstimatedExtraIELen; ++ P_APPEND_VAR_IE_ENTRY_T prIeArray = NULL; ++ UINT_32 u4IeArraySize = 0; ++ UINT_32 i; ++ ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if (!pucDestAddr) { /* For Beacon */ ++ prIeArray = &txBcnIETable[0]; ++ u4IeArraySize = sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); ++ } else { ++ prIeArray = &txProbRspIETable[0]; ++ u4IeArraySize = sizeof(txProbRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); ++ } ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */ ++ /* Allocate a MSDU_INFO_T */ ++ ++ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Fields */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + ++ WLAN_MAC_MGMT_HEADER_LEN + ++ TIMESTAMP_FIELD_LEN + ++ BEACON_INTERVAL_FIELD_LEN + ++ CAP_INFO_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP)); ++ ++ /* + Extra IE Length */ ++ u2EstimatedExtraIELen = 0; ++ ++ for (i = 0; i < u4IeArraySize; i++) { ++ u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen; ++ ++ if (u2EstimatedFixedIELen) { ++ u2EstimatedExtraIELen += u2EstimatedFixedIELen; ++ } else { ++ ASSERT(prIeArray[i].pfnCalculateVariableIELen); ++ ++ u2EstimatedExtraIELen += (UINT_16) ++ prIeArray[i].pfnCalculateVariableIELen(prAdapter, eNetTypeIndex, NULL); ++ } ++ } ++ ++ u2EstimatedFrameLen += u2EstimatedExtraIELen; ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", ((!pucDestAddr) ? "Beacon" : "Probe Response")); ++ return WLAN_STATUS_RESOURCES; ++ } ++ /* 4 <2> Compose Beacon/Probe Response frame header and fixed fields in MSDU_INfO_T. */ ++ /* Compose Header and Fixed Field */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) { ++ if (prAdapter->fgIsP2PRegistered) { ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ++ ((ULONG) (prMsduInfo->prPacket) + ++ MAC_TX_RESERVED_FIELD), pucDestAddr, ++ prAdapter->rWifiVar.aucDeviceAddress, ++ prAdapter->rWifiVar.aucDeviceAddress, ++ DOT11_BEACON_PERIOD_DEFAULT, ++ (prBssInfo->u2CapInfo & ++ ~(CAP_INFO_ESS | CAP_INFO_IBSS))); ++ } ++ } else ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ { ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ pucDestAddr, prBssInfo->aucOwnMacAddr, prBssInfo->aucBSSID, ++ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); ++ } ++ ++ /* 4 <3> Update information of MSDU_INFO_T */ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = 0xFF; ++ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + ++ TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ /* 4 <4> Compose the frame body's Common IEs of the Beacon/ProbeResp frame. */ ++ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, pucDestAddr); ++ ++ /* 4 <5> Compose IEs in MSDU_INFO_T */ ++ ++ /* Append IE */ ++ for (i = 0; i < u4IeArraySize; i++) { ++ if (prIeArray[i].pfnAppendIE) ++ prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo); ++ } ++ ++ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ ++ ++ /* 4 <6> Inform TXM to send this Beacon /Probe Response frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssSendBeaconProbeResponse() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Probe Request Frame and then send ++* back the corresponding Probe Response Frame if the specified conditions ++* were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always return success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BSS_INFO_T prBssInfo; ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ UINT_8 aucBCBSSID[] = BC_BSSID; ++ BOOLEAN fgIsBcBssid; ++ BOOLEAN fgReplyProbeResp; ++ UINT_32 u4CtrlFlagsForProbeResp = 0; ++ ENUM_BAND_T eBand; ++ UINT_8 ucHwChannelNum; ++ ++ ASSERT(prSwRfb); ++ ++ /* 4 <1> Parse Probe Req and Get BSSID */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID)) ++ fgIsBcBssid = TRUE; ++ else ++ fgIsBcBssid = FALSE; ++ ++ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ ++ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { ++ ++ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) ++ continue; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if ((!fgIsBcBssid) && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) ++ continue; ++ ++ eBand = HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr); ++ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); ++ ++ if (prBssInfo->eBand != eBand) ++ continue; ++ ++ if (prBssInfo->ucPrimaryChannel != ucHwChannelNum) ++ continue; ++ ++ fgReplyProbeResp = FALSE; ++ ++ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { ++ ++#if CFG_SUPPORT_ADHOC ++ fgReplyProbeResp = aisValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); ++#endif ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex)) { ++ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { ++ /* Resource margin is enough */ ++ fgReplyProbeResp = ++ p2pFuncValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); ++ } ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) ++ fgReplyProbeResp = bowValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); ++#endif ++ ++ if (fgReplyProbeResp) { ++ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { ++ /* Resource margin is enough */ ++ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr, ++ u4CtrlFlagsForProbeResp); ++ } ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssProcessProbeRequest() */ ++ ++#if 0 /* NOTE(Kevin): condition check should move to P2P_FSM.c */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Probe Request Frame and then send ++* back the corresponding Probe Response Frame if the specified conditions ++* were matched. ++* ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always return success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; ++ P_BSS_INFO_T prBssInfo; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; ++ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ UINT_8 aucBCBSSID[] = BC_BSSID; ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ BOOLEAN fgReplyProbeResp; ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgP2PTargetDeviceFound; ++ UINT_8 aucP2PWildcardSSID[] = P2P_WILDCARD_SSID; ++#endif ++ ++ ASSERT(prSwRfb); ++ ++ /* 4 <1> Parse Probe Req and Get SSID IE ptr */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; ++ pucIE = (PUINT_8) ((UINT_32) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); ++ ++ prIeSsid = (P_IE_SSID_T) NULL; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ break; ++ ++ case ELEM_ID_SUP_RATES: ++ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. ++ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), ++ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" ++ */ ++ /* if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SUP_RATES) { */ ++ if (IE_LEN(pucIE) <= RATE_NUM) ++ prIeSupportedRate = SUP_RATES_IE(pucIE); ++ break; ++ ++ case ELEM_ID_EXTENDED_SUP_RATES: ++ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); ++ break; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* TODO: P2P IE & WCS IE parsing for P2P. */ ++ case ELEM_ID_P2P: ++ ++ break; ++#endif ++ ++ /* no default */ ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ ++ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { ++ ++ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) ++ continue; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if (UNEQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID) && ++ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) { ++ /* BSSID not Wildcard BSSID. */ ++ continue; ++ } ++ ++ fgReplyProbeResp = FALSE; ++ ++ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ ++ /* TODO(Kevin): Check if we are IBSS Master. */ ++ if (TRUE && prIeSsid) { ++ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, ++ prIeSsid->aucSSID, prIeSsid->ucLength)) { ++ fgReplyProbeResp = TRUE; ++ } ++ } ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex) { ++ ++ /* TODO(Kevin): Move following lines to p2p_fsm.c */ ++ ++ if ((prIeSsid) && ++ ((prIeSsid->ucLength == BC_SSID_LEN) || ++ (EQUAL_SSID(aucP2PWildcardSSID, ++ P2P_WILDCARD_SSID_LEN, prIeSsid->aucSSID, prIeSsid->ucLength)))) { ++ /* if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prMgtHdr->aucSrcAddr, ++ pucIE, u2IELength)) { */ ++ if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prSwRfb)) { ++ /* Extand channel request time & cancel scan request. */ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ /* TODO: RX probe request may not caused by LISTEN state. */ ++ /* TODO: It can be GO. */ ++ /* Generally speaking, cancel a non-exist scan request is fine. ++ * We can check P2P FSM here for only LISTEN state. ++ */ ++ ++ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ /* Abort JOIN process. */ ++ prScanCancelMsg = ++ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancelMsg) { ++ ASSERT(0); /* Can't abort SCN FSM */ ++ continue; ++ } ++ ++ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; ++ prScanCancelMsg->ucSeqNum = prP2pFsmInfo->ucSeqNumOfScnMsg; ++ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; ++ prScanCancelMsg->fgIsChannelExt = TRUE; ++ ++ mboxSendMsg(prAdapter, ++ MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); ++ } ++ } else { ++ /* 1. Probe Request without SSID. ++ * 2. Probe Request with SSID not Wildcard SSID & not P2P Wildcard SSID. ++ */ ++ continue; ++ } ++ ++#if 0 /* Frog */ ++ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_LISTEN) { ++ /* P2P 2.4.1 - P2P Devices shall not respond to Probe Request frames ++ which only contain 11b rates only. */ ++ if (prIeSupportedRate || prIeExtSupportedRate) { ++ UINT_16 u2OperationalRateSet, u2BSSBasicRateSet; ++ BOOLEAN fgIsUnknownBssBasicRate; ++ ++ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, ++ &u2OperationalRateSet, ++ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ ++ &fgIsUnknownBssBasicRate); ++ ++ if (u2OperationalRateSet & ~RATE_SET_HR_DSSS) ++ continue; ++ } ++ } ++ /* TODO: Check channel time before first check point to: */ ++ /* If Target device is selected: ++ * 1. Send XXXX request frame. ++ * else ++ * 1. Send Probe Response frame. ++ */ ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ /* TODO(Kevin): During PROVISION state, can we reply Probe Response ? */ ++ ++ /* TODO(Kevin): ++ * If we are GO, accept legacy client --> accept Wildcard SSID ++ * If we are in Listen State, accept only P2P Device --> check P2P IE and WPS IE ++ */ ++ if (TRUE /* We are GO */ && prIeSsid) { ++ UINT_8 aucSSID[] = P2P_WILDCARD_SSID; ++ ++ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ ++ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, ++ prIeSsid->aucSSID, prIeSsid->ucLength) || ++ EQUAL_SSID(aucSSID, P2P_WILDCARD_SSID_LEN, ++ prIeSsid->aucSSID, prIeSsid->ucLength)) { ++ fgReplyProbeResp = TRUE; ++ } ++ } ++/* else if (FALSE) { */ /* We are in Listen State */ ++/* } */ ++ ++ /* TODO(Kevin): Check P2P IE and WPS IE */ ++ } ++#endif ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) { ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ /* Do nothing */ ++ /* TODO(Kevin): TBD */ ++ } ++ } ++#endif ++ else ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ if (fgReplyProbeResp) ++ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr); ++ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of bssProcessProbeRequest() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to clear the client list for AdHoc or AP Mode ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prBssInfo Given related BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prPeerStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prPeerStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ cnmStaRecChangeState(prAdapter, prPeerStaRec, STA_STATE_1); ++ } ++ ++ LINK_INITIALIZE(prStaRecOfClientList); ++ } ++ ++} /* end of bssClearClientList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to Add a STA_RECORD_T to the client list for AdHoc or AP Mode ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prBssInfo Given related BSS_INFO_T. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ ++ if (prCurrStaRec == prStaRec) { ++ DBGLOG(BSS, WARN, ++ "Current Client List already contains that STA_RECORD_T[%pM]\n", ++ prStaRec->aucMacAddr); ++ return; ++ } ++ } ++ } ++ ++ LINK_INSERT_TAIL(prStaRecOfClientList, &prStaRec->rLinkEntry); ++ ++} /* end of bssAddStaRecToClientList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to Remove a STA_RECORD_T from the client list for AdHoc or AP Mode ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ ++#if 0 ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ ++ if (prCurrStaRec == prStaRec) { ++ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); ++ ++ return; ++ } ++ } ++ } ++#endif ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ if ((ULONG) prStaRec == (ULONG) prLinkEntry) { ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); ++ return; ++ } ++ } ++ } ++ ++ DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T[%pM] before removing.\n", ++ prStaRec->aucMacAddr); ++ ++} /* end of bssRemoveStaRecFromClientList() */ ++#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Get station record by Address for AP mode ++* ++* @param[in] prBssInfo Pointer to BSS_INFO_T. ++* @param[in] pucMacAddr Pointer to target mac address ++* ++* @return pointer of STA_RECORD_T if found, otherwise, return NULL ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr) ++{ ++ P_LINK_T prStaRecOfClientList; ++ ++ ASSERT(prBssInfo); ++ ASSERT(pucMacAddr); ++ ++ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; ++ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMacAddr)) ++ return prCurrStaRec; ++ } ++ } ++ return NULL; ++} ++ ++#if CFG_SUPPORT_ADHOC ++/*----------------------------------------------------------------------------*/ ++/* Routines for IBSS(AdHoc) only */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to process Beacons from current Ad-Hoc network peers. ++* We also process Beacons from other Ad-Hoc network during SCAN. If it has ++* the same SSID and we'll decide to merge into it if it has a larger TSF. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* @param[in] prBSSDesc Pointer to the BSS Descriptor. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI) ++{ ++ P_STA_RECORD_T prStaRec = NULL; ++ ++ BOOLEAN fgIsCheckCapability = FALSE; ++ BOOLEAN fgIsCheckTSF = FALSE; ++ BOOLEAN fgIsGoingMerging = FALSE; ++ BOOLEAN fgIsSameBSSID; ++ ++ ASSERT(prBssInfo); ++ ASSERT(prBssDesc); ++ ++ /* 4 <1> Process IBSS Beacon only after we create or merge with other IBSS. */ ++ if (!prBssInfo->fgIsBeaconActivated) ++ return; ++ /* 4 <2> Get the STA_RECORD_T of TA. */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prBssDesc->aucSrcAddr); ++ ++ fgIsSameBSSID = UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID) ? FALSE : TRUE; ++ ++ /* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */ ++ if (fgIsSameBSSID) { ++ ++ /* Same BSSID: ++ * Case I. This is a new TA and it has decide to merged with us. ++ * a) If fgIsMerging == FALSE - we will send msg to notify AIS. ++ * b) If fgIsMerging == TRUE - already notify AIS. ++ * Case II. This is an old TA and we've already merged together. ++ */ ++ if (!prStaRec) { ++ ++ /* For Case I - Check this IBSS's capability first before adding this Sta Record. */ ++ fgIsCheckCapability = TRUE; ++ ++ /* If check is passed, then we perform merging with this new IBSS */ ++ fgIsGoingMerging = TRUE; ++ ++ } else { ++ ++ ASSERT((prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) && IS_ADHOC_STA(prStaRec)); ++ ++ if (prStaRec->ucStaState != STA_STATE_3) { ++ ++ if (!prStaRec->fgIsMerging) { ++ ++ /* For Case I - Check this IBSS's capability first ++ * before adding this Sta Record. */ ++ fgIsCheckCapability = TRUE; ++ ++ /* If check is passed, then we perform merging with this new IBSS */ ++ fgIsGoingMerging = TRUE; ++ } else { ++ /* For Case II - Update rExpirationTime of Sta Record */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ } ++ } else { ++ /* For Case II - Update rExpirationTime of Sta Record */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ } ++ ++ } ++ } else { ++ ++ /* Unequal BSSID: ++ * Case III. This is a new TA and we need to compare the TSF and get the winner. ++ * Case IV. This is an old TA and it merge into a new IBSS before we do the same thing. ++ * We need to compare the TSF to get the winner. ++ * Case V. This is an old TA and it restart a new IBSS. We also need to ++ * compare the TSF to get the winner. ++ */ ++ ++ /* For Case III, IV & V - We'll always check this new IBSS's capability first ++ * before merging into new IBSS. ++ */ ++ fgIsCheckCapability = TRUE; ++ ++ /* If check is passed, we need to perform TSF check to decide the major BSSID */ ++ fgIsCheckTSF = TRUE; ++ ++ /* For Case IV & V - We won't update rExpirationTime of Sta Record */ ++ } ++ ++ /* 4 <7> Check this BSS_DESC_T's capability. */ ++ if (fgIsCheckCapability) { ++ BOOLEAN fgIsCapabilityMatched = FALSE; ++ ++ do { ++ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Unsupported Phy.\n", ++ prBssDesc->aucSrcAddr); ++ ++ break; ++ } ++ ++ if (prBssDesc->fgIsUnknownBssBasicRate) { ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Unknown Basic Rate.\n", ++ prBssDesc->aucSrcAddr); ++ ++ break; ++ } ++ ++ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", ++ prBssDesc->aucSrcAddr); ++ ++ break; ++ } ++ ++ fgIsCapabilityMatched = TRUE; ++ } while (FALSE); ++ ++ if (!fgIsCapabilityMatched) { ++ ++ if (prStaRec) { ++ /* For Case II - We merge this STA_RECORD in RX Path. ++ * Case IV & V - They change their BSSID after we merge with them. ++ */ ++ ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", ++ prBssDesc->aucSrcAddr); ++ } ++ ++ return; ++ } ++ ++ DBGLOG(BSS, LOUD, ++ "IBSS MERGE: Peer MAC: %pM - Check capability was passed.\n", ++ prBssDesc->aucSrcAddr); ++ } ++ ++ if (fgIsCheckTSF) { ++#if CFG_SLT_SUPPORT ++ fgIsGoingMerging = TRUE; ++#else ++ if (prBssDesc->fgIsLargerTSF) ++ fgIsGoingMerging = TRUE; ++ else ++ return; ++#endif ++ } ++ ++ if (fgIsGoingMerging) { ++ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; ++ ++ /* 4 <1> We will merge with to this BSS immediately. */ ++ prBssDesc->fgIsConnecting = TRUE; ++ prBssDesc->fgIsConnected = FALSE; ++ ++ /* 4 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, ++ STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); ++ ++ if (!prStaRec) { ++ /* no memory ? */ ++ return; ++ } ++ ++ prStaRec->fgIsMerging = TRUE; ++ ++ /* update RCPI */ ++ prStaRec->ucRCPI = ucRCPI; ++ ++ /* 4 <3> Send Merge Msg to CNM to obtain the channel privilege. */ ++ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_IBSS_PEER_FOUND_T)); ++ ++ if (!prAisIbssPeerFoundMsg) { ++ ++ ASSERT(0); /* Can't send Merge Msg */ ++ return; ++ } ++ ++ prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS; ++ prAisIbssPeerFoundMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; ++ prAisIbssPeerFoundMsg->prStaRec = prStaRec; ++ ++ /* Inform AIS to do STATE TRANSITION ++ * For Case I - If AIS in IBSS_ALONE, let it jump to NORMAL_TR after we know the new member. ++ * For Case III, IV - Now this new BSSID wins the TSF, follow it. ++ */ ++ if (fgIsSameBSSID) { ++ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; ++ } else { ++#if CFG_SLT_SUPPORT ++ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; ++#else ++ prAisIbssPeerFoundMsg->fgIsMergeIn = (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE; ++#endif ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisIbssPeerFoundMsg, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++} /* end of ibssProcessMatchedBeacon() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the Capability for Ad-Hoc to decide if we are ++* able to merge with(same capability). ++* ++* @param[in] prBSSDesc Pointer to the BSS Descriptor. ++* ++* @retval WLAN_STATUS_FAILURE Can't pass the check of Capability. ++* @retval WLAN_STATUS_SUCCESS Pass the check of Capability. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ ++ ASSERT(prBssDesc); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ do { ++ /* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */ ++ if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) && ++ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) { ++ break; ++ } else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) && ++ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) { ++ break; ++ } ++ /* 4 <2> Check the Short Slot Time. */ ++#if 0 /* Do not check ShortSlotTime until Wi-Fi define such policy */ ++ if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) { ++ if (((prConnSettings->fgIsShortSlotTimeOptionEnable) && ++ !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) || ++ (!(prConnSettings->fgIsShortSlotTimeOptionEnable) && ++ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))) { ++ break; ++ } ++ } ++#endif ++ ++ /* 4 <3> Check the ATIM window setting. */ ++ if (prBssDesc->u2ATIMWindow) { ++ DBGLOG(BSS, INFO, "AdHoc PS was not supported(ATIM Window: %d)\n", prBssDesc->u2ATIMWindow); ++ break; ++ } ++#if CFG_RSN_MIGRATION ++ /* 4 <4> Check the Security setting. */ ++ if (!rsnPerformPolicySelection(prAdapter, prBssDesc)) ++ break; ++#endif ++ ++ rStatus = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rStatus; ++ ++} /* end of ibssCheckCapabilityForAdHocMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will initial the BSS_INFO_T for IBSS Mode. ++* ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) ++{ ++ UINT_8 ucLowestBasicRateIndex; ++ UINT_8 aucBSSID[MAC_ADDR_LEN]; ++ PUINT_16 pu2BSSID = (PUINT_16) &aucBSSID[0]; ++ UINT_32 i; ++ ++ ASSERT(prBssInfo); ++ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_IBSS); ++ ++ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); ++ ++ /* 4 <2> Setup BSSID */ ++ if (!prBssInfo->fgHoldSameBssidForIBSS) { ++ ++ for (i = 0; i < sizeof(aucBSSID) / sizeof(UINT_16); i++) ++ pu2BSSID[i] = (UINT_16) (kalRandomNumber() & 0xFFFF); ++ ++ aucBSSID[0] &= ~0x01; /* 7.1.3.3.3 - The individual/group bit of the address is set to 0. */ ++ aucBSSID[0] |= 0x02; /* 7.1.3.3.3 - The universal/local bit of the address is set to 1. */ ++ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID); ++ } ++ /* 4 <3> Setup Capability - Short Preamble */ ++ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ ++ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ ++ /* 4 <4> Setup Capability - Short Slot Time */ ++ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ ++ prBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ ++ ++ /* 4 <5> Compoase Capability */ ++ prBssInfo->u2CapInfo = CAP_INFO_IBSS; ++ ++ if (prBssInfo->fgIsProtection) ++ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; ++ ++ if (prBssInfo->fgIsShortPreambleAllowed) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ ++ if (prBssInfo->fgUseShortSlotTime) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ ++ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); ++ ++ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; ++ ++} /* end of ibssInitForAdHoc() */ ++ ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++#if CFG_SUPPORT_AAA ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines for BSS(AP) only */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will initial the BSS_INFO_T for AP Mode. ++* ++* @param[in] prBssInfo Given related BSS_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate) ++{ ++ UINT_8 ucLowestBasicRateIndex; ++ ++ P_AC_QUE_PARMS_T prACQueParms; ++ ++ ENUM_WMM_ACI_T eAci; ++ ++ UINT_8 auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; ++ UINT_8 auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 }; ++ UINT_8 auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 }; ++ UINT_8 auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ ++ ++ UINT_8 auCWminLog2[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; ++ UINT_8 auCWmaxLog2[WMM_AC_INDEX_NUM] = { 7, 10, 4, 3 }; ++ UINT_8 auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 }; ++ UINT_8 auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ ++ ++ DEBUGFUNC("bssInitForAP"); ++ DBGLOG(BSS, LOUD, "\n"); ++ ++ ASSERT(prBssInfo); ++ ASSERT((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || (prBssInfo->eCurrentOPMode == OP_MODE_BOW)); ++ ++#if 0 ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M; ++ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M; ++#endif ++ ++ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ if (fgIsRateUpdate) { ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); ++ } ++ /* 4 <2> Setup BSSID */ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr); ++ ++ /* 4 <3> Setup Capability - Short Preamble */ ++ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && ++ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ ++ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ ++ /* 4 <4> Setup Capability - Short Slot Time */ ++ prBssInfo->fgUseShortSlotTime = TRUE; ++ ++ /* 4 <5> Compoase Capability */ ++ prBssInfo->u2CapInfo = CAP_INFO_ESS; ++ ++ if (prBssInfo->fgIsProtection) ++ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; ++ ++ if (prBssInfo->fgIsShortPreambleAllowed) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; ++ ++ if (prBssInfo->fgUseShortSlotTime) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ ++ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); ++ ++ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; ++ ++ /* 4 <7> Fill the EDCA */ ++ ++ prACQueParms = prBssInfo->arACQueParmsForBcast; ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prACQueParms[eAci].fgIsACMSet = FALSE; ++ prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci]; ++ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1; ++ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1; ++ prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci]; ++ ++ prBssInfo->aucCWminLog2ForBcast[eAci] = auCWminLog2ForBcast[eAci]; /* used to send WMM IE */ ++ prBssInfo->aucCWmaxLog2ForBcast[eAci] = auCWmaxLog2ForBcast[eAci]; ++ ++ DBGLOG(BSS, INFO, "Bcast: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", ++ eAci, prACQueParms[eAci].fgIsACMSet, ++ prACQueParms[eAci].u2Aifsn, ++ prACQueParms[eAci].u2CWmin, ++ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); ++ ++ } ++ ++ prACQueParms = prBssInfo->arACQueParms; ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prACQueParms[eAci].fgIsACMSet = FALSE; ++ prACQueParms[eAci].u2Aifsn = auAifs[eAci]; ++ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1; ++ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1; ++ prACQueParms[eAci].u2TxopLimit = auTxop[eAci]; ++ ++ DBGLOG(BSS, INFO, "eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", ++ eAci, prACQueParms[eAci].fgIsACMSet, ++ prACQueParms[eAci].u2Aifsn, ++ prACQueParms[eAci].u2CWmin, ++ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); ++ } ++ ++ /* Note: Caller should update the EDCA setting to HW by nicQmUpdateWmmParms() it there is no AIS network */ ++ /* Note: In E2, only 4 HW queues. The the Edca parameters should be folow by AIS network */ ++ /* Note: In E3, 8 HW queues. the Wmm parameters should be updated to right queues according to BSS */ ++ ++} /* end of bssInitForAP() */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update DTIM Count ++* ++* @param[in] eNetTypeIndex Specify which network to update ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ ++ /* Setup DTIM Count for next TBTT. */ ++ if (prBssInfo->ucDTIMCount > 0) { ++ prBssInfo->ucDTIMCount--; ++ } else { ++ ++ ASSERT(prBssInfo->ucDTIMPeriod > 0); ++ ++ prBssInfo->ucDTIMCount = prBssInfo->ucDTIMPeriod - 1; ++ } ++ } ++ ++} /* end of bssUpdateDTIMIE() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to set the Virtual Bitmap in TIM Information Elements ++* ++* @param[in] prBssInfo Pointer to the BSS_INFO_T. ++* @param[in] u2AssocId The association id to set in Virtual Bitmap. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId) ++{ ++ ++ ASSERT(prBssInfo); ++ ++ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ ++ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); ++ ++ /* Use Association ID == 0 for BMCAST indication */ ++ if (u2AssocId == 0) { ++ ++ prP2pSpecificBssInfo->ucBitmapCtrl |= (UINT_8) BIT(0); ++ } else { ++ PUINT_8 pucPartialVirtualBitmap; ++ UINT_8 ucBitmapToSet; ++ ++ /* (u2AssocId / 8) */ ++ pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)]; ++ ucBitmapToSet = (UINT_8) BIT((u2AssocId % 8)); ++ ++ if (*pucPartialVirtualBitmap & ucBitmapToSet) { ++ /* The virtual bitmap has been set */ ++ return; ++ } ++ ++ *pucPartialVirtualBitmap |= ucBitmapToSet; ++ ++ /* Update u2SmallestAID and u2LargestAID */ ++ if ((u2AssocId < prP2pSpecificBssInfo->u2SmallestAID) || ++ (prP2pSpecificBssInfo->u2SmallestAID == 0)) { ++ prP2pSpecificBssInfo->u2SmallestAID = u2AssocId; ++ } ++ ++ if ((u2AssocId > prP2pSpecificBssInfo->u2LargestAID) || ++ (prP2pSpecificBssInfo->u2LargestAID == 0)) { ++ prP2pSpecificBssInfo->u2LargestAID = u2AssocId; ++ } ++ } ++ } ++ ++} /* end of bssSetTIMBitmap() */ ++#endif ++ ++#endif /* CFG_SUPPORT_AAA */ ++ ++VOID bssCreateStaRecFromAuth(IN P_ADAPTER_T prAdapter) ++{ ++ ++} ++ ++VOID bssUpdateStaRecFromAssocReq(IN P_ADAPTER_T prAdapter) ++{ ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c +new file mode 100644 +index 000000000000..39af02df2af2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c +@@ -0,0 +1,738 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm.c#2 ++*/ ++ ++/*! \file "cnm.c" ++ \brief Module of Concurrent Network Management ++ ++ Module of Concurrent Network Management ++*/ ++ ++/* ++** Log: cnm.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Fix possible wrong message when P2P is unregistered ++ * ++ * 11 14 2011 yuche.tsai ++ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. ++ * Fix large network type index assert in FW issue. ++ * ++ * 11 10 2011 cm.chang ++ * NULL ++ * Modify debug message for XLOG ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 11 01 2011 cm.chang ++ * [WCXRP00001077] [All Wi-Fi][Driver] Fix wrong preferred channel for AP and BOW ++ * Only check AIS channel for P2P and BOW ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Extension channel of some 5G AP will not follow regulation requirement ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * . ++ * ++ * 09 01 2011 cm.chang ++ * [WCXRP00000937] [MT6620 Wi-Fi][Driver][FW] cnm.c line #848 assert when doing monkey test ++ * Print message only in Linux platform for monkey testing ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Limit AIS to fixed channel same with BOW ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Check if P2P network index is Tethering AP ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel ++ * ++ * 02 17 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * When P2P registried, invoke BOW deactivate function ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Provide function to decide if BSS can be activated or not ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 10 13 2010 cm.chang ++ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. ++ * Add exception handle when cmd buffer is not available ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Fix wrong message ID for channel grant to requester ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Set 20/40M bandwidth of AP HT OP before association process ++ * ++ * 05 31 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling ++ * ++ * 05 21 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support TCP/UDP/IP Checksum offload feature ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add a new function to send abort message ++ * ++ * 04 27 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * BMC mac address shall be ignored in basic config command ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support change of MAC address by host command ++ * ++ * 04 16 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the wpa-none for ibss beacon. ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix bug for OBSS scan ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * use the Rx0 dor event indicate. ++ * ++ * 02 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support partial part about cmd basic configuration ++ * ++ * Dec 10 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove conditional compiling FPGA_V5 ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add function cnmFsmEventInit() ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in CNM_INFO_T. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmInit(P_ADAPTER_T prAdapter) ++{ ++ ++} /* end of cnmInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in CNM_INFO_T. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmUninit(P_ADAPTER_T prAdapter) ++{ ++ ++} /* end of cnmUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Before handle the message from other module, it need to obtain ++* the Channel privilege from Channel Manager ++* ++* @param[in] prMsgHdr The message need to be handled. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_CH_REQ_T prMsgChReq; ++ P_CMD_CH_PRIVILEGE_T prCmdBody; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prMsgChReq = (P_MSG_CH_REQ_T) prMsgHdr; ++ ++ prCmdBody = (P_CMD_CH_PRIVILEGE_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); ++ ASSERT(prCmdBody); ++ ++ /* To do: exception handle */ ++ if (!prCmdBody) { ++ DBGLOG(CNM, ERROR, "ChReq: fail to get buf (net=%d, token=%d)\n", ++ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ DBGLOG(CNM, INFO, "ChReq net=%d token=%d b=%d c=%d s=%d\n", ++ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID, ++ prMsgChReq->eRfBand, prMsgChReq->ucPrimaryChannel, prMsgChReq->eRfSco); ++ ++ prCmdBody->ucNetTypeIndex = prMsgChReq->ucNetTypeIndex; ++ prCmdBody->ucTokenID = prMsgChReq->ucTokenID; ++ prCmdBody->ucAction = CMD_CH_ACTION_REQ; /* Request */ ++ prCmdBody->ucPrimaryChannel = prMsgChReq->ucPrimaryChannel; ++ prCmdBody->ucRfSco = (UINT_8) prMsgChReq->eRfSco; ++ prCmdBody->ucRfBand = (UINT_8) prMsgChReq->eRfBand; ++ prCmdBody->ucReqType = (UINT_8) prMsgChReq->eReqType; ++ prCmdBody->ucReserved = 0; ++ prCmdBody->u4MaxInterval = prMsgChReq->u4MaxInterval; ++ COPY_MAC_ADDR(prCmdBody->aucBSSID, prMsgChReq->aucBSSID); ++ ++ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ /* For monkey testing 20110901 */ ++ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) ++ DBGLOG(CNM, ERROR, "CNM: ChReq with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_CH_PRIVILEGE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdBody, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdBody); ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* end of cnmChMngrRequestPrivilege() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Before deliver the message to other module, it need to release ++* the Channel privilege to Channel Manager. ++* ++* @param[in] prMsgHdr The message need to be delivered ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_CH_ABORT_T prMsgChAbort; ++ P_CMD_CH_PRIVILEGE_T prCmdBody; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prMsgChAbort = (P_MSG_CH_ABORT_T) prMsgHdr; ++ ++ prCmdBody = (P_CMD_CH_PRIVILEGE_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); ++ ASSERT(prCmdBody); ++ ++ /* To do: exception handle */ ++ if (!prCmdBody) { ++ DBGLOG(CNM, ERROR, "ChAbort: fail to get buf (net=%d, token=%d)\n", ++ prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ DBGLOG(CNM, INFO, "ChAbort net=%d token=%d\n", prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); ++ ++ prCmdBody->ucNetTypeIndex = prMsgChAbort->ucNetTypeIndex; ++ prCmdBody->ucTokenID = prMsgChAbort->ucTokenID; ++ prCmdBody->ucAction = CMD_CH_ACTION_ABORT; /* Abort */ ++ ++ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ /* For monkey testing 20110901 */ ++ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) ++ DBGLOG(CNM, ERROR, "CNM: ChAbort with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_CH_PRIVILEGE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdBody, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdBody); ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* end of cnmChMngrAbortPrivilege() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_CH_PRIVILEGE_T prEventBody; ++ P_MSG_CH_GRANT_T prChResp; ++ ++ ASSERT(prAdapter); ++ ASSERT(prEvent); ++ ++ prEventBody = (P_EVENT_CH_PRIVILEGE_T) (prEvent->aucBuffer); ++ prChResp = (P_MSG_CH_GRANT_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_GRANT_T)); ++ ASSERT(prChResp); ++ ++ /* To do: exception handle */ ++ if (!prChResp) { ++ DBGLOG(CNM, ERROR, "ChGrant: fail to get buf (net=%d, token=%d)\n", ++ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID); ++ ++ return; ++ } ++ ++ DBGLOG(CNM, INFO, "ChGrant net=%d token=%d ch=%d sco=%d\n", ++ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID, ++ prEventBody->ucPrimaryChannel, prEventBody->ucRfSco); ++ ++ ASSERT(prEventBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ASSERT(prEventBody->ucStatus == EVENT_CH_STATUS_GRANT); ++ ++ /* Decide message ID based on network and response status */ ++ if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) ++ prChResp->rMsgHdr.eMsgId = MID_CNM_AIS_CH_GRANT; ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (prEventBody->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) ++ prChResp->rMsgHdr.eMsgId = MID_CNM_P2P_CH_GRANT; ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++ prChResp->rMsgHdr.eMsgId = MID_CNM_BOW_CH_GRANT; ++#endif ++ else { ++ cnmMemFree(prAdapter, prChResp); ++ return; ++ } ++ ++ prChResp->ucNetTypeIndex = prEventBody->ucNetTypeIndex; ++ prChResp->ucTokenID = prEventBody->ucTokenID; ++ prChResp->ucPrimaryChannel = prEventBody->ucPrimaryChannel; ++ prChResp->eRfSco = (ENUM_CHNL_EXT_T) prEventBody->ucRfSco; ++ prChResp->eRfBand = (ENUM_BAND_T) prEventBody->ucRfBand; ++ prChResp->eReqType = (ENUM_CH_REQ_TYPE_T) prEventBody->ucReqType; ++ prChResp->u4GrantInterval = prEventBody->u4GrantInterval; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prChResp, MSG_SEND_METHOD_BUF); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is invoked for P2P or BOW networks ++* ++* @param (none) ++* ++* @return TRUE: suggest to adopt the returned preferred channel ++* FALSE: No suggestion. Caller should adopt its preference ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBand); ++ ASSERT(pucPrimaryChannel); ++ ASSERT(prBssSCO); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ if (RLM_NET_PARAM_VALID(prBssInfo)) { ++ *prBand = prBssInfo->eBand; ++ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ *prBssSCO = prBssInfo->eBssSCO; ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: available channel is limited to return value ++* FALSE: no limited ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) ++{ ++#if CFG_ENABLE_WIFI_DIRECT || (CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL) ++ P_BSS_INFO_T prBssInfo; ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { ++ ++ ASSERT(prAdapter->fgIsP2PRegistered); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ *prBand = prBssInfo->eBand; ++ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ ++ return TRUE; ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; ++ ++ *prBand = prBssInfo->eBand; ++ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ ++ return TRUE; ++ } ++#endif ++ ++ return FALSE; ++} ++ ++#if CFG_P2P_LEGACY_COEX_REVISE ++BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) ++{ ++ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; ++ P_BSS_INFO_T prP2PBssInfo = &prWifiVar->arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && ++ (prP2PBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || ++ (prP2PBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && prP2PBssInfo->eIntendOPMode == OP_MODE_NUM))) { ++ *prBand = prP2PBssInfo->eBand; ++ *pucPrimaryChannel = prP2PBssInfo->ucPrimaryChannel; ++#if CFG_SUPPORT_MCC ++ if (nicFreq2ChannelNum(prWifiVar->rConnSettings.u4FreqInKHz * 1000) != *pucPrimaryChannel) { ++ DBGLOG(CNM, INFO, "p2p is running on Channel %d, but supplicant try to run as MCC\n", ++ *pucPrimaryChannel); ++ return FALSE; ++ } ++#endif ++ DBGLOG(CNM, INFO, "p2p is running on Channel %d, supplicant try to run as SCC\n", ++ *pucPrimaryChannel); ++ return TRUE; ++ } ++#endif ++ return FALSE; ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter) ++{ ++#if CFG_ENABLE_BT_OVER_WIFI ++ P_BSS_INFO_T prAisBssInfo, prBowBssInfo; ++ ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prBowBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; ++ ++ if (RLM_NET_PARAM_VALID(prAisBssInfo) && RLM_NET_PARAM_VALID(prBowBssInfo)) { ++ if (prAisBssInfo->eBand != prBowBssInfo->eBand || ++ prAisBssInfo->ucPrimaryChannel != prBowBssInfo->ucPrimaryChannel) { ++ ++ /* Notify BOW to do deactivation */ ++ bowNotifyAllLinkDisconnected(prAdapter); ++ } ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter) ++{ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) ++ return FALSE; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) ++ return FALSE; ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) ++ return FALSE; ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { ++ /* Notify BOW to do deactivation */ ++ bowNotifyAllLinkDisconnected(prAdapter); ++ } ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) ++ return FALSE; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) ++ return FALSE; ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param (none) ++* ++* @return TRUE: permitted ++* FALSE: Not permitted ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 i; ++ P_BSS_DESC_T prBssDesc = NULL; ++ ++ /* Note: To support real-time decision instead of current activated-time, ++ * the STA roaming case shall be considered about synchronization ++ * problem. Another variable fgAssoc40mBwAllowed is added to ++ * represent HT capability when association ++ */ ++ for (i = 0; i < NETWORK_TYPE_INDEX_NUM; i++) { ++ if (i != (UINT_8) eNetTypeIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[i]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo) && (prBssInfo->fg40mBwAllowed || prBssInfo->fgAssoc40mBwAllowed)) ++ return FALSE; ++ } ++ } ++ ++ if (eNetTypeIdx == NETWORK_TYPE_AIS_INDEX) ++ prBssDesc = prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; ++ else if ((eNetTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->rWifiVar.prP2pFsmInfo)) ++ prBssDesc = prAdapter->rWifiVar.prP2pFsmInfo->prTargetBss; ++ if (prBssDesc) { ++#if (CFG_FORCE_USE_20BW == 1) ++ if (prBssDesc->eBand == BAND_2G4) ++ return FALSE; ++#endif ++ if (prBssDesc->eSco == CHNL_EXT_SCN) ++ return FALSE; ++ } ++ ++ return TRUE; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c +new file mode 100644 +index 000000000000..05bd0ff35f7a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c +@@ -0,0 +1,1236 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#2 ++*/ ++ ++/*! \file "cnm_mem.c" ++ \brief This file contain the management function of packet buffers and ++ generic memory alloc/free functioin for mailbox message. ++ ++ A data packet has a fixed size of buffer, but a management ++ packet can be equipped with a variable size of buffer. ++*/ ++ ++/* ++** Log: cnm_mem.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 14 2012 wh.su ++ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting ++ * Add code from 2.2 ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * initialize fgNeedResp. ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * avoid deactivating staRec when changing state from 3 to 3. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 11 29 2010 cm.chang ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * Sync RCPI of STA_REC to FW as reference of initial TX rate ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update SLT Function for QoS Support and not be affected by fixed rate function. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete ++ * and might leads to BSOD when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 10 13 2010 cm.chang ++ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. ++ * Add exception handle when cmd buffer is not available ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * add HT (802.11n) fixed rate support. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD ++ * when entering RF test with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 07 07 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support state of STA record change from 1 to 1 ++ * ++ * 07 05 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Fix correct structure size in cnmStaSendDeactivateCmd() ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * spin lock target revised ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change inner loop index from i to k. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 05 31 2010 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support checking of duplicated buffer free ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the ad-hoc wpa-none send non-encrypted frame issue. ++ * ++ * 05 28 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 28 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Modified some MQM-related data structures (SN counter, TX/RX BA table) ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Added new TX/RX BA tables in STA_REC ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Notify MQM, TXM, and RXM upon disconnection . ++ * ++ * 04 26 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Call mqm, txm, rxm functions upon disconnection ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support ++ * * * * * * * * * * and will send Null frame to diagnose connection ++ * ++ * 04 09 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * [BORA00000644] WiFi phase 4 integration ++ * * Added per-TID SN cache in STA_REC ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Different invoking order for WTBL entry of associated AP ++ * ++ * 03 29 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * move the wlan table alloc / free to change state function. ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support power control ++ * ++ * 03 03 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Initialize StaRec->arStaWaitQueue ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add debug message when no available pkt buffer ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k] ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsWmmSupported in STA_RECORD_T. ++ * ++ * 02 26 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added fgIsUapsdSupported in STA_RECORD_T ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * add support of Driver STA_RECORD_T activation ++ * ++ * 02 13 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added arTspecTable in STA_REC for TSPEC management ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable mgmt buffer debug by default ++ * ++ * 02 12 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Added BUFFER_SOURCE_BCN ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 cp.wu ++ * [BORA00000368]Integrate HIF part into BORA ++ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h ++ * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem ++ * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer ++ * ++ * 12 25 2009 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) ++ * * * * * * * MQM: BA handling ++ * * * * * * * TXM: Macros updates ++ * * * * * * * RXM: Macros/Duplicate Removal updates ++ * ++ * 12 24 2009 yarco.yang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * 12 21 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support several data buffer banks. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * .For new FPGA memory size ++ * ++ * Dec 9 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Removed DBGPRINT ++ * ++ * Dec 9 2009 mtk02752 ++ * [BORA00000368] Integrate HIF part into BORA ++ * add cnmDataPktFree() for emulation loopback purpose ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix warning of null pointer ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T ++ * ++ * Nov 23 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Assign ucBufferSource in function cnmMgtPktAlloc() ++ * ++ * Nov 23 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added packet redispatch function calls ++ * ++ * Nov 13 2009 mtk01084 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * enable packet re-usable in current emulation driver ++ * ++ * Nov 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * 1. Add new function cnmGetStaRecByIndex() ++ * 2. Rename STA_REC_T to STA_RECORD_T ++ * ++ * Nov 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Call cnmDataPktDispatch() in cnmPktFree() ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove definition of pragma section code ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * Oct 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo ++ * ++ * Oct 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++ * Oct 8 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf); ++ ++static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp); ++ ++static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T cnmMgtPktAlloc(P_ADAPTER_T prAdapter, UINT_32 u4Length) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_QUE_T prQueList; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; ++ ++ /* Get a free MSDU_INFO_T */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ if (prMsduInfo) { ++ prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ ++ if (prMsduInfo->prPacket == NULL) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ prMsduInfo = NULL; ++ } ++ if (prMsduInfo) { ++ prMsduInfo->eCmdType = COMMAND_TYPE_NUM; ++ prMsduInfo->ucCID = 0xff; ++ prMsduInfo->u4InqueTime = 0; ++ prMsduInfo->ucPacketType = TX_PACKET_NUM; ++ } ++ } else { ++ P_QUE_T prTxingQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_TX_TCQ_STATUS_T pTc = (P_TX_TCQ_STATUS_T) NULL; ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ pTc = &(prAdapter->rTxCtrl.rTc); ++ ++ DBGLOG(MEM, LOUD, "++dump TxPendingMsdu=%u, Tc0=%d Tc1=%d Tc2=%d Tc3=%d, Tc4=%d Tc5=%d\n", ++ prTxingQue->u4NumElem, pTc->aucFreeBufferCount[TC0_INDEX], ++ pTc->aucFreeBufferCount[TC1_INDEX], pTc->aucFreeBufferCount[TC2_INDEX], ++ pTc->aucFreeBufferCount[TC3_INDEX], pTc->aucFreeBufferCount[TC4_INDEX], ++ pTc->aucFreeBufferCount[TC5_INDEX]); ++ ++ prQueueEntry = QUEUE_GET_HEAD(prTxingQue); ++ ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ DBGLOG(MEM, LOUD, ++ "msdu type=%u, ucid=%u, type=%d, time=%u, seq=%u, sta=%u\n", ++ prMsduInfo->ucPacketType, ++ prMsduInfo->ucCID, ++ prMsduInfo->eCmdType, ++ prMsduInfo->u4InqueTime, prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex); ++ prQueueEntry = QUEUE_GET_NEXT_ENTRY(prQueueEntry); ++ } ++ DBGLOG(MEM, LOUD, "--end dump\n"); ++ } ++ ++#if DBG ++ if (prMsduInfo == NULL) { ++ DBGLOG(MEM, WARN, "MgtDesc#=%u\n", prQueList->u4NumElem); ++ ++#if CFG_DBG_MGT_BUF ++ DBGLOG(MEM, WARN, "rMgtBufInfo: alloc#=%u, free#=%u, null#=%u\n", ++ prAdapter->rMgtBufInfo.u4AllocCount, ++ prAdapter->rMgtBufInfo.u4FreeCount, prAdapter->rMgtBufInfo.u4AllocNullCount); ++#endif ++ ++ DBGLOG(MEM, WARN, "\n"); ++ } ++#endif ++ ++ return prMsduInfo; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmMgtPktFree(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_QUE_T prQueList; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; ++ ++ ASSERT(prMsduInfo->prPacket); ++ if (prMsduInfo->prPacket) { ++ cnmMemFree(prAdapter, prMsduInfo->prPacket); ++ prMsduInfo->prPacket = NULL; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ prMsduInfo->fgIsBasicRate = FALSE; ++ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry) ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to initial the MGMT/MSG memory pool. ++* ++* \param (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmMemInit(P_ADAPTER_T prAdapter) ++{ ++ P_BUF_INFO_T prBufInfo; ++ ++ /* Initialize Management buffer pool */ ++ prBufInfo = &prAdapter->rMgtBufInfo; ++ kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo)); ++ prBufInfo->pucBuf = prAdapter->pucMgtBufCached; ++ ++ /* Setup available memory blocks. 1 indicates FREE */ ++ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); ++ ++ /* Initialize Message buffer pool */ ++ prBufInfo = &prAdapter->rMsgBufInfo; ++ kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo)); ++ prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0]; ++ ++ /* Setup available memory blocks. 1 indicates FREE */ ++ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); ++ ++ return; ++ ++} /* end of cnmMemInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Allocate MGMT/MSG memory pool. ++* ++* \param[in] eRamType Target RAM type. ++* TCM blk_sz= 16bytes, BUF blk_sz= 256bytes ++* \param[in] u4Length Length of the buffer to allocate. ++* ++* \retval !NULL Pointer to the start address of allocated memory. ++* \retval NULL Fail to allocat memory ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 u4MemAllocCnt = 0, u4MemFreeCnt = 0; ++PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length) ++{ ++ P_BUF_INFO_T prBufInfo; ++ BUF_BITMAP rRequiredBitmap; ++ UINT_32 u4BlockNum; ++ UINT_32 i, u4BlkSzInPower; ++ PVOID pvMemory; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(u4Length); ++ ++ u4MemAllocCnt++; ++ ++ if (eRamType == RAM_TYPE_MSG && u4Length <= 256) { ++ prBufInfo = &prAdapter->rMsgBufInfo; ++ u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ u4Length += (MSG_BUF_BLOCK_SIZE - 1); ++ u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); ++ } else { ++ eRamType = RAM_TYPE_BUF; ++ ++ prBufInfo = &prAdapter->rMgtBufInfo; ++ u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ u4Length += (MGT_BUF_BLOCK_SIZE - 1); ++ u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ++ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); ++ } ++ ++#if CFG_DBG_MGT_BUF ++ prBufInfo->u4AllocCount++; ++#endif ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) { ++ ++ /* Convert number of block into bit cluster */ ++ rRequiredBitmap = BITS(0, u4BlockNum - 1); ++ ++ for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) { ++ ++ /* Have available memory blocks */ ++ if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap) ++ == rRequiredBitmap) { ++ ++ /* Clear corresponding bits of allocated memory blocks */ ++ prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap; ++ ++ /* Store how many blocks be allocated */ ++ prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, ++ eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ /* Return the start address of allocated memory */ ++ return (PVOID) (prBufInfo->pucBuf + (i << u4BlkSzInPower)); ++ ++ } ++ ++ rRequiredBitmap <<= 1; ++ } ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ /* cannot move the allocation between spin_lock_irqsave and spin_unlock_irqrestore */ ++#ifdef LINUX ++ pvMemory = (PVOID) kalMemAlloc(u4Length, VIR_MEM_TYPE); ++ if (pvMemory) ++ kalMemZero(pvMemory, u4Length); ++#else ++ pvMemory = (PVOID) NULL; ++#endif ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++#if CFG_DBG_MGT_BUF ++ prBufInfo->u4AllocNullCount++; ++ ++ if (pvMemory) ++ prAdapter->u4MemAllocDynamicCount++; ++#endif ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ return pvMemory; ++ ++} /* end of cnmMemAlloc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Release memory to MGT/MSG memory pool. ++* ++* \param pucMemory Start address of previous allocated memory ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory) ++{ ++ P_BUF_INFO_T prBufInfo; ++ UINT_32 u4BlockIndex; ++ BUF_BITMAP rAllocatedBlocksBitmap; ++ ENUM_RAM_TYPE_T eRamType; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(pvMemory); ++ if (!pvMemory) ++ return; ++ ++ u4MemFreeCnt++; ++ ++ /* Judge it belongs to which RAM type */ ++ if (((ULONG) pvMemory >= (ULONG)&prAdapter->aucMsgBuf[0]) && ++ ((ULONG) pvMemory <= (ULONG)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE - 1])) { ++ ++ prBufInfo = &prAdapter->rMsgBufInfo; ++ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) ++ >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); ++ eRamType = RAM_TYPE_MSG; ++ } else if (((ULONG) pvMemory >= (ULONG) prAdapter->pucMgtBufCached) && ++ ((ULONG) pvMemory <= ((ULONG) prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE - 1))) { ++ prBufInfo = &prAdapter->rMgtBufInfo; ++ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) ++ >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; ++ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); ++ eRamType = RAM_TYPE_BUF; ++ } else { ++#ifdef LINUX ++ /* For Linux, it is supported because size is not needed */ ++ kalMemFree(pvMemory, VIR_MEM_TYPE, 0); ++#else ++ /* For Windows, it is not supported because of no size argument */ ++ ASSERT(0); ++#endif ++ ++#if CFG_DBG_MGT_BUF ++ prAdapter->u4MemFreeDynamicCount++; ++#endif ++ return; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++#if CFG_DBG_MGT_BUF ++ prBufInfo->u4FreeCount++; ++#endif ++ ++ /* Convert number of block into bit cluster */ ++ ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0); ++ ++ rAllocatedBlocksBitmap = BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1); ++ rAllocatedBlocksBitmap <<= u4BlockIndex; ++ ++ /* Clear saved block count for this memory segment */ ++ prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0; ++ ++ /* Set corresponding bit of released memory block */ ++ prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); ++ ++ return; ++ ++} /* end of cnmMemFree() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecInit(P_ADAPTER_T prAdapter) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ prStaRec->ucIndex = (UINT_8) i; ++ prStaRec->fgIsInUse = FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse) ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T cnmStaRecAlloc(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i, k; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (!prStaRec->fgIsInUse) { ++ /*---- Initialize STA_REC_T here ----*/ ++ kalMemZero(prStaRec, sizeof(STA_RECORD_T)); ++ prStaRec->ucIndex = (UINT_8) i; ++ prStaRec->ucNetTypeIndex = ucNetTypeIndex; ++ prStaRec->fgIsInUse = TRUE; ++ ++ if (prStaRec->pucAssocReqIe) { ++ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); ++ prStaRec->pucAssocReqIe = NULL; ++ prStaRec->u2AssocReqIeLen = 0; ++ } ++ ++ /* Initialize the SN caches for duplicate detection */ ++ for (k = 0; k < TID_NUM + 1; k++) ++ prStaRec->au2CachedSeqCtrl[k] = 0xFFFF; ++ ++ /* Initialize SW TX queues in STA_REC */ ++ for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) ++ LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]); ++ ++ /* Default enable TX/RX AMPDU */ ++ prStaRec->fgTxAmpduEn = TRUE; ++ prStaRec->fgRxAmpduEn = TRUE; ++ ++#if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE ++ prStaRec->u4TotalTxPktsNumber = 0; ++ prStaRec->u4TotalTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsTime = 0; ++#endif ++ ++ for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) ++ QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]); ++ ++ break; ++ } ++ } ++ ++ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecFree(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgSyncToChip) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ /* To do: free related resources, e.g. timers, buffers, etc */ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ prStaRec->fgTransmitKeyExist = FALSE; ++ prStaRec->fgSetPwrMgtBit = FALSE; ++ ++ if (prStaRec->pucAssocReqIe) { ++ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); ++ prStaRec->pucAssocReqIe = NULL; ++ prStaRec->u2AssocReqIeLen = 0; ++ } ++ ++ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); ++ ++ if (fgSyncToChip) ++ cnmStaSendRemoveCmd(prAdapter, prStaRec); ++ ++ prStaRec->fgIsInUse = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse && prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) ++ cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip); ++ } /* end of for loop */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T cnmGetStaRecByIndex(P_ADAPTER_T prAdapter, UINT_8 ucIndex) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ++ prStaRec = (ucIndex < CFG_STA_REC_NUM) ? &prAdapter->arStaRec[ucIndex] : NULL; ++ ++ if (prStaRec && prStaRec->fgIsInUse == FALSE) ++ prStaRec = NULL; ++ ++ return prStaRec; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Get STA_RECORD_T by Peer MAC Address(Usually TA). ++* ++* @param[in] pucPeerMacAddr Given Peer MAC Address. ++* ++* @retval Pointer to STA_RECORD_T, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_STA_RECORD_T cnmGetStaRecByAddress(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex, PUINT_8 pucPeerMacAddr) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucPeerMacAddr); ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse && ++ prStaRec->ucNetTypeIndex == ucNetTypeIndex && ++ EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) { ++ break; ++ } ++ } ++ ++ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Reset the Status and Reason Code Field to 0 of all Station Records for ++* the specified Network Type ++* ++* @param[in] eNetType Specify Network Type ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecResetStatus(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE); ++ ++#if 0 ++ P_STA_RECORD_T prStaRec; ++ UINT_16 i; ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse) { ++ if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) && IS_STA_IN_AIS(prStaRec->eStaType)) { ++ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; ++ prStaRec->ucJoinFailureCount = 0; ++ prStaRec->fgTransmitKeyExist = FALSE; ++ ++ prStaRec->fgSetPwrMgtBit = FALSE; ++ } ++ ++ /* TODO(Kevin): For P2P and BOW */ ++ } ++ } ++ ++ return; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will change the ucStaState of STA_RECORD_T and also do ++* event indication to HOST to sync the STA_RECORD_T in driver. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] u4NewState New STATE to change. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmStaRecChangeState(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, UINT_8 ucNewState) ++{ ++ BOOLEAN fgNeedResp; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->fgIsInUse); ++ ++ /* Do nothing when following state transitions happen, ++ * other 6 conditions should be sync to FW, including 1-->1, 3-->3 ++ */ ++ if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) || ++ (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) { ++ prStaRec->ucStaState = ucNewState; ++ return; ++ } ++ ++ fgNeedResp = FALSE; ++ if (ucNewState == STA_STATE_3) { ++ secFsmEventStart(prAdapter, prStaRec); ++ if (ucNewState != prStaRec->ucStaState) ++ fgNeedResp = TRUE; ++ } else { ++ if (ucNewState != prStaRec->ucStaState && prStaRec->ucStaState == STA_STATE_3) ++ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); ++ fgNeedResp = FALSE; ++ } ++ prStaRec->ucStaState = ucNewState; ++ ++ cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* To do: Confirm if it is invoked here or other location, but it should ++ * be invoked after state sync of STA_REC ++ * Update system operation parameters for AP mode ++ */ ++ if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) { ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); ++ } ++#endif ++} ++ ++P_STA_RECORD_T ++cnmStaTheTypeGet(P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx) ++{ ++ P_STA_RECORD_T prStaRec = NULL; ++ UINT_16 i; ++ ++ for (i = *pu4StartIdx; i < CFG_STA_REC_NUM; i++) { ++ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; ++ ++ if (prStaRec->fgIsInUse && ++ prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex && prStaRec->eStaType == eStaType) { ++ i++; ++ break; ++ } ++ ++ prStaRec = NULL; /* reset */ ++ } /* end of for loop */ ++ ++ *pu4StartIdx = i; ++ return prStaRec; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf) ++{ ++ P_EVENT_ACTIVATE_STA_REC_T prEventContent; ++ P_STA_RECORD_T prStaRec; ++ ++ prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx); ++ ++ if (prStaRec && prStaRec->ucStaState == STA_STATE_3 && ++ !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0], MAC_ADDR_LEN)) { ++ ++ qmActivateStaRec(prAdapter, prStaRec); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp) ++{ ++ P_CMD_UPDATE_STA_RECORD_T prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ASSERT(prStaRec->fgIsInUse); ++ ++ /* To do: come out a mechanism to limit one STA_REC sync once for AP mode ++ * to avoid buffer empty case when many STAs are associated ++ * simultaneously. ++ */ ++ ++ /* To do: how to avoid 2 times of allocated memory. Use Stack? ++ * One is here, the other is in wlanSendQueryCmd() ++ */ ++ prCmdContent = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T)); ++ ASSERT(prCmdContent); ++ ++ /* To do: exception handle */ ++ if (!prCmdContent) ++ return; ++ ++ prCmdContent->ucIndex = prStaRec->ucIndex; ++ prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType; ++ kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); ++ prCmdContent->u2AssocId = prStaRec->u2AssocId; ++ prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval; ++ prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex; ++ ++ prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet; ++ prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ prCmdContent->ucMcsSet = prStaRec->ucMcsSet; ++ prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32; ++ prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo; ++ prCmdContent->ucNeedResp = (UINT_8) fgNeedResp; ++ ++#if !CFG_SLT_SUPPORT ++ if (prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) { ++ /* override rate configuration */ ++ nicUpdateRateParams(prAdapter, ++ prAdapter->rWifiVar.eRateSetting, ++ &(prCmdContent->ucDesiredPhyTypeSet), ++ &(prCmdContent->u2DesiredNonHTRateSet), ++ &(prCmdContent->u2BSSBasicRateSet), ++ &(prCmdContent->ucMcsSet), ++ &(prCmdContent->ucSupMcs32), &(prCmdContent->u2HtCapInfo)); ++ } ++#endif ++ ++ prCmdContent->ucIsQoS = prStaRec->fgIsQoS; ++ prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported; ++ prCmdContent->ucStaState = prStaRec->ucStaState; ++ ++ prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam; ++ prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap; ++ prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap; ++ prCmdContent->ucAselCap = prStaRec->ucAselCap; ++ prCmdContent->ucRCPI = prStaRec->ucRCPI; ++ ++ prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4); ++ prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp; ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_UPDATE_STA_RECORD, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ fgNeedResp, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ fgNeedResp ? cnmStaRecHandleEventPkt : NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdContent); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) ++{ ++ CMD_REMOVE_STA_RECORD_T rCmdContent; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ rCmdContent.ucIndex = prStaRec->ucIndex; ++ kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_REMOVE_STA_RECORD, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) &rCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c +new file mode 100644 +index 000000000000..8cc9ef9078fe +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c +@@ -0,0 +1,482 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1 ++*/ ++ ++/*! \file "cnm_timer.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: cnm_timer.c ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation ++ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms ++ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support sleep notification to host ++ * ++ * 05 19 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add some checking assertions ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Return timer token back to COS when entering wait off state ++ * ++ * 01 11 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Remove compiling warning ++ * ++ * 01 08 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb ++ * ++ * 01 06 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix system time is 32KHz instead of 1ms ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Place rRootTimer.rNextExpiredSysTime = rExpiredSysTime; before set timer ++ * ++ * Oct 30 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * In cnmTimerInitialize(), just stop timer if it was already created. ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Move the external reference for Lint to precomp.h ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the time to do the time out check. ++* ++* \param[in] rTimeout Time out interval from current time. ++* ++* \retval TRUE Success. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN cnmTimerSetTimer(IN P_ADAPTER_T prAdapter, IN OS_SYSTIME rTimeout) ++{ ++ P_ROOT_TIMER prRootTimer; ++ BOOLEAN fgNeedWakeLock; ++ ++ ASSERT(prAdapter); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ kalSetTimer(prAdapter->prGlueInfo, rTimeout); ++ ++ if (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME)) { ++ fgNeedWakeLock = TRUE; ++ ++ if (!prRootTimer->fgWakeLocked) { ++ KAL_WAKE_LOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = TRUE; ++ } ++ } else { ++ fgNeedWakeLock = FALSE; ++ } ++ ++ return fgNeedWakeLock; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to initialize a root timer. ++* ++* \param[in] prAdapter ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROOT_TIMER prRootTimer; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ /* Note: glue layer have configured timer */ ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ LINK_INITIALIZE(&prRootTimer->rLinkHead); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ KAL_WAKE_LOCK_INIT(prAdapter, &prRootTimer->rWakeLock, "WLAN Timer"); ++ prRootTimer->fgWakeLocked = FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to destroy a root timer. ++* When WIFI is off, the token shall be returned back to system. ++* ++* \param[in] ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROOT_TIMER prRootTimer; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ if (prRootTimer->fgWakeLocked) { ++ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = FALSE; ++ } ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prRootTimer->rWakeLock); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ LINK_INITIALIZE(&prRootTimer->rLinkHead); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ /* Note: glue layer will be responsible for timer destruction */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to initialize a timer. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* \param[in] pfnFunc Pointer to the call back function. ++* \param[in] u4Data Parameter for call back function. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData) ++{ ++ ASSERT(prAdapter); ++ ++ ASSERT(prTimer); ++ ++#if DBG ++ /* Note: NULL function pointer is permitted for HEM POWER */ ++ if (pfFunc == NULL) ++ DBGLOG(CNM, WARN, "Init timer with NULL callback function!\n"); ++#endif ++ ++#if DBG ++ ASSERT(prAdapter->rRootTimer.rLinkHead.prNext); ++ { ++ P_LINK_T prTimerList; ++ P_LINK_ENTRY_T prLinkEntry; ++ P_TIMER_T prPendingTimer; ++ ++ prTimerList = &(prAdapter->rRootTimer.rLinkHead); ++ ++ LINK_FOR_EACH(prLinkEntry, prTimerList) { ++ prPendingTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); ++ ASSERT(prPendingTimer); ++ ASSERT(prPendingTimer != prTimer); ++ } ++ } ++#endif ++ ++ LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry); ++ ++ prTimer->pfMgmtTimeOutFunc = pfFunc; ++ prTimer->ulData = ulData; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to stop a timer. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID cnmTimerStopTimer_impl(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN BOOLEAN fgAcquireSpinlock) ++{ ++ P_ROOT_TIMER prRootTimer; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prTimer); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ ++ if (fgAcquireSpinlock) ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ if (timerPendingTimer(prTimer)) { ++ LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead, &prTimer->rLinkEntry); ++ ++ /* Reduce dummy timeout for power saving, especially HIF activity. ++ * If two or more timers exist and being removed timer is smallest, ++ * this dummy timeout will still happen, but it is OK. ++ */ ++ if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) { ++ kalCancelTimer(prAdapter->prGlueInfo); ++ ++ if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) { ++ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = FALSE; ++ } ++ } ++ } ++ ++ if (fgAcquireSpinlock) ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to stop a timer. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prTimer); ++ ++ cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to start a timer with wake_lock. ++* ++* \param[in] prTimer Pointer to a timer structure. ++* \param[in] u4TimeoutMs Timeout to issue the timer and call back function ++* (unit: ms). ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs) ++{ ++ P_ROOT_TIMER prRootTimer; ++ P_LINK_T prTimerList; ++ OS_SYSTIME rExpiredSysTime, rTimeoutSystime; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prTimer); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ prTimerList = &prRootTimer->rLinkHead; ++ ++ /* If timeout interval is larger than 1 minute, the mod value is set ++ * to the timeout value first, then per minutue. ++ */ ++ if (u4TimeoutMs > MSEC_PER_MIN) { ++ ASSERT(u4TimeoutMs <= ((UINT_32) 0xFFFF * MSEC_PER_MIN)); ++ ++ prTimer->u2Minutes = (UINT_16) (u4TimeoutMs / MSEC_PER_MIN); ++ u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN); ++ if (u4TimeoutMs == 0) { ++ u4TimeoutMs = MSEC_PER_MIN; ++ prTimer->u2Minutes--; ++ } ++ } else { ++ prTimer->u2Minutes = 0; ++ } ++ ++ /* The assertion check if MSEC_TO_SYSTIME() may be overflow. */ ++ ASSERT(u4TimeoutMs < (((UINT_32) 0x80000000 - MSEC_PER_SEC) / KAL_HZ)); ++ rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs); ++ rExpiredSysTime = kalGetTimeTick() + rTimeoutSystime; ++ ++ /* If no timer pending or the fast time interval is used. */ ++ if (LINK_IS_EMPTY(prTimerList) || TIME_BEFORE(rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { ++ ++ prRootTimer->rNextExpiredSysTime = rExpiredSysTime; ++ cnmTimerSetTimer(prAdapter, rTimeoutSystime); ++ } ++ ++ /* Add this timer to checking list */ ++ prTimer->rExpiredSysTime = rExpiredSysTime; ++ ++ if (!timerPendingTimer(prTimer)) ++ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routines is called to check the timer list. ++* ++* \param[in] ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROOT_TIMER prRootTimer; ++ P_LINK_T prTimerList; ++ P_LINK_ENTRY_T prLinkEntry; ++ P_TIMER_T prTimer; ++ OS_SYSTIME rCurSysTime; ++ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; ++ ULONG ulTimeoutData; ++ BOOLEAN fgNeedWakeLock; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ /* acquire spin lock */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ ++ prRootTimer = &prAdapter->rRootTimer; ++ prTimerList = &prRootTimer->rLinkHead; ++ ++ rCurSysTime = kalGetTimeTick(); ++ ++ /* Set the permitted max timeout value for new one */ ++ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; ++ ++ LINK_FOR_EACH(prLinkEntry, prTimerList) { ++ prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); ++ ASSERT(prTimer); ++ ++ /* Check if this entry is timeout. */ ++ if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) { ++ cnmTimerStopTimer_impl(prAdapter, prTimer, FALSE); ++ ++ pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc; ++ ulTimeoutData = prTimer->ulData; ++ ++ if (prTimer->u2Minutes > 0) { ++ prTimer->u2Minutes--; ++ prTimer->rExpiredSysTime = rCurSysTime + MSEC_TO_SYSTIME(MSEC_PER_MIN); ++ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); ++ } else if (pfMgmtTimeOutFunc) { ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ (pfMgmtTimeOutFunc) (prAdapter, ulTimeoutData); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++ } ++ ++ /* Search entire list again because of nest del and add timers ++ * and current MGMT_TIMER could be volatile after stopped ++ */ ++ prLinkEntry = (P_LINK_ENTRY_T) prTimerList; ++ ++ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; ++ } else if (TIME_BEFORE(prTimer->rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { ++ prRootTimer->rNextExpiredSysTime = prTimer->rExpiredSysTime; ++ } ++ } /* end of for loop */ ++ ++ /* Setup the prNext timeout event. It is possible the timer was already ++ * set in the above timeout callback function. ++ */ ++ fgNeedWakeLock = FALSE; ++ if (!LINK_IS_EMPTY(prTimerList)) { ++ ASSERT(TIME_AFTER(prRootTimer->rNextExpiredSysTime, rCurSysTime)); ++ ++ fgNeedWakeLock = cnmTimerSetTimer(prAdapter, (OS_SYSTIME) ++ ((INT_32) prRootTimer->rNextExpiredSysTime - (INT_32) rCurSysTime)); ++ } ++ ++ if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) { ++ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); ++ prRootTimer->fgWakeLocked = FALSE; ++ } ++ ++ /* release spin lock */ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c +new file mode 100644 +index 000000000000..c7a23eb018b6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c +@@ -0,0 +1,816 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/hem_mbox.c#3 ++*/ ++ ++/*! \file "hem_mbox.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: hem_mbox.c ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device ++** have connected to AP previously,one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 05 03 2012 cp.wu ++ * [WCXRP00001231] [MT6620 Wi-Fi][MT5931][Driver] Correct SCAN_V2 related debugging facilities within hem_mbox.c ++ * correct for debug message string table by adding missed scan_v2 related definitions. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 17 2012 yuche.tsai ++ * NULL ++ * Update mgmt frame filter setting. ++ * Please also update FW 2.1 ++ * ++ * 01 13 2012 yuche.tsai ++ * NULL ++ * WiFi Hot Spot Tethering for ICS ALPHA testing version. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Add exception handle for NULL function pointer of mailbox message ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search ++ * for more than one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support ++ * as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Add invitation support. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 29 2011 cm.chang ++ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning ++ * As CR title ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation ++ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms ++ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update bowString and channel grant. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 12 08 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support concurrent networks. ++ * ++ * 11 08 2010 cm.chang ++ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID ++ * Remove CNM channel reover message ID ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Remove unused message ID ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add P2P Connection Abort Event Message handler. ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 yarco.yang ++ * NULL ++ * Fixed Driver ASSERT at mboxInitMsgMap() ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. ++ * Update saa_fsm for BOW. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Add CFG_ENABLE_BT_OVER_WIFI. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add debug message for newly add P2P message. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some function entry for P2P FSM under provisioning phase.. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add some events to P2P Module. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Add message box event for P2P device switch on & device discovery. ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * remove unused mailbox message definitions. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * message table should not be commented out by compilation option without modifying header file ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Add wifi direct scan done callback. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * change handler of MID_MNY_CNM_CONNECTION_ABORT from NULL to mboxDummy. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Modify CNM message handler for new flow ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable currently migrated message call-backs. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * restore utility function invoking via hem_mbox to direct calls ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add buildable & linkable ais_fsm.c ++ * ++ * related reference are still waiting to be resolved ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * hem_mbox is migrated. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Fix file merge error ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_QOS_ACTION_FRAME ++ * ++ * 04 29 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Removed MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * 04 27 2010 tehuang.liu ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Develop partial DPD code ++ * ++ * 02 11 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Updated arMsgMapTable for MID_RXM_MQM_QOS_ACTION_FRAME ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * Dec 9 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add hemRunEventScanDone() to arMsgMapTable[] ++ * ++ * Dec 4 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix mboxDummy() didn't free prMsgHdr ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add saaAisJoinComplete event handler ++ * ++ * Dec 2 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Fixed the handler function name in arMsgMapTable for MID_RXM_MQM_BA_ACTION_FRAME ++ * ++ * Dec 2 2009 MTK02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Added MID_RXM_MQM_BA_ACTION_FRAME to MsgMapTable ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MSG Handler (remove dummy and add for SAA) ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add aisFsmRunEventAbort() event handler ++ * ++ * Nov 11 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo ++ * ++ * Nov 10 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add more MSG_HNDL_ENTRY_T to avoid ASSERT() in mboxInitMsgMap() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add SCN message and function entry to arMsgMapTable[] ++ * ++ * Nov 2 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix sorting algorithm in mboxInitMsgMap() ++ * ++ * Oct 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugMsg[] = { ++ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_REQ"), ++ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_ABORT"), ++ (PUINT_8) DISP_STRING("MID_CNM_AIS_CH_GRANT"), ++ (PUINT_8) DISP_STRING("MID_CNM_P2P_CH_GRANT"), ++ (PUINT_8) DISP_STRING("MID_CNM_BOW_CH_GRANT"), ++ ++ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ"), ++ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ_V2"), ++ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_CANCEL"), ++ (PUINT_8) DISP_STRING("MID_SCN_AIS_SCAN_DONE"), ++ (PUINT_8) DISP_STRING("MID_SCN_P2P_SCAN_DONE"), ++ (PUINT_8) DISP_STRING("MID_SCN_BOW_SCAN_DONE"), ++ (PUINT_8) DISP_STRING("MID_SCN_RLM_SCAN_DONE"), ++ ++ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_JOIN_REQ"), ++ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_START"), ++ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_SAA_AIS_JOIN_COMPLETE"), ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_START"), ++ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_SAA_BOW_JOIN_COMPLETE"), ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_START"), ++ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_SAA_P2P_JOIN_COMPLETE"), ++ ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_FUN_SWITCH"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_DEVICE_DISCOVERY"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_REQ"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_ABORT"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_BEACON_UPDATE"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_STOP_AP"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_REQ"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_ABORT"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_TX"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_GROUP_DISSOLVE"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_REGISTER"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_NET_DEV_REGISTER"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_START_AP"), ++ (PUINT_8) DISP_STRING("MID_MNY_P2P_UPDATE_IE_BUF"), ++#endif ++ ++#if CFG_SUPPORT_ADHOC ++ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_CREATE_IBSS_REQ"), */ ++ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_CREATE_IBSS_GRANT"), */ ++ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_MERGE_IBSS_REQ"), */ ++ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_MERGE_IBSS_GRANT"), */ ++ (PUINT_8) DISP_STRING("MID_SCN_AIS_FOUND_IBSS"), ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ (PUINT_8) DISP_STRING("MID_SAA_AIS_FSM_ABORT"), ++ (PUINT_8) DISP_STRING("MID_MNY_AIS_REMAIN_ON_CHANNEL"), ++ (PUINT_8) DISP_STRING("MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL"), ++ (PUINT_8) DISP_STRING("MID_MNY_AIS_MGMT_TX") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/* This message entry will be re-ordered based on the message ID order ++ * by invoking mboxInitMsgMap() ++ */ ++static MSG_HNDL_ENTRY_T arMsgMapTable[] = { ++ {MID_MNY_CNM_CH_REQ, cnmChMngrRequestPrivilege}, ++ {MID_MNY_CNM_CH_ABORT, cnmChMngrAbortPrivilege}, ++ {MID_CNM_AIS_CH_GRANT, aisFsmRunEventChGrant}, ++#if CFG_ENABLE_WIFI_DIRECT ++ {MID_CNM_P2P_CH_GRANT, p2pFsmRunEventChGrant}, /*set in gl_p2p_init.c */ ++#else ++ {MID_CNM_P2P_CH_GRANT, mboxDummy}, ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ {MID_CNM_BOW_CH_GRANT, bowRunEventChGrant}, ++#else ++ {MID_CNM_BOW_CH_GRANT, mboxDummy}, ++#endif ++ ++ /*--------------------------------------------------*/ ++ /* SCN Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ {MID_AIS_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_AIS_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_AIS_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_P2P_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_P2P_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_P2P_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_BOW_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_BOW_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_BOW_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_RLM_SCN_SCAN_REQ, scnFsmMsgStart}, ++ {MID_RLM_SCN_SCAN_REQ_V2, scnFsmMsgStart}, ++ {MID_RLM_SCN_SCAN_CANCEL, scnFsmMsgAbort}, ++ {MID_SCN_AIS_SCAN_DONE, aisFsmRunEventScanDone}, ++#if CFG_ENABLE_WIFI_DIRECT ++ {MID_SCN_P2P_SCAN_DONE, p2pFsmRunEventScanDone}, /*set in gl_p2p_init.c */ ++#else ++ {MID_SCN_P2P_SCAN_DONE, mboxDummy}, ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ {MID_SCN_BOW_SCAN_DONE, bowResponderScanDone}, ++#else ++ {MID_SCN_BOW_SCAN_DONE, mboxDummy}, ++#endif ++ {MID_SCN_RLM_SCAN_DONE, rlmObssScanDone}, ++ ++ /*--------------------------------------------------*/ ++ /* AIS Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ {MID_OID_AIS_FSM_JOIN_REQ, aisFsmRunEventAbort}, ++ {MID_OID_AIS_FSM_ABORT, aisFsmRunEventAbort}, ++ {MID_AIS_SAA_FSM_START, saaFsmRunEventStart}, ++ {MID_AIS_SAA_FSM_ABORT, saaFsmRunEventAbort}, ++ {MID_SAA_AIS_JOIN_COMPLETE, aisFsmRunEventJoinComplete}, ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /*--------------------------------------------------*/ ++ /* BOW Module Mailbox Messages */ ++ /*--------------------------------------------------*/ ++ {MID_BOW_SAA_FSM_START, saaFsmRunEventStart}, ++ {MID_BOW_SAA_FSM_ABORT, saaFsmRunEventAbort}, ++ {MID_SAA_BOW_JOIN_COMPLETE, bowFsmRunEventJoinComplete}, ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT /*set in gl_p2p_init.c */ ++ {MID_P2P_SAA_FSM_START, saaFsmRunEventStart}, ++ {MID_P2P_SAA_FSM_ABORT, saaFsmRunEventAbort}, ++ {MID_SAA_P2P_JOIN_COMPLETE, p2pFsmRunEventJoinComplete}, /* TODO: p2pFsmRunEventJoinComplete */ ++ ++ {MID_MNY_P2P_FUN_SWITCH, p2pFsmRunEventSwitchOPMode}, ++ {MID_MNY_P2P_DEVICE_DISCOVERY, p2pFsmRunEventScanRequest}, ++ {MID_MNY_P2P_CONNECTION_REQ, p2pFsmRunEventConnectionRequest}, ++ {MID_MNY_P2P_CONNECTION_ABORT, p2pFsmRunEventConnectionAbort}, ++ {MID_MNY_P2P_BEACON_UPDATE, p2pFsmRunEventBeaconUpdate}, ++ {MID_MNY_P2P_STOP_AP, p2pFsmRunEventStopAP}, ++ {MID_MNY_P2P_CHNL_REQ, p2pFsmRunEventChannelRequest}, ++ {MID_MNY_P2P_CHNL_ABORT, p2pFsmRunEventChannelAbort}, ++ {MID_MNY_P2P_MGMT_TX, p2pFsmRunEventMgmtFrameTx}, ++ {MID_MNY_P2P_GROUP_DISSOLVE, p2pFsmRunEventDissolve}, ++ {MID_MNY_P2P_MGMT_FRAME_REGISTER, p2pFsmRunEventMgmtFrameRegister}, ++ {MID_MNY_P2P_NET_DEV_REGISTER, p2pFsmRunEventNetDeviceRegister}, ++ {MID_MNY_P2P_START_AP, p2pFsmRunEventStartAP}, ++ {MID_MNY_P2P_MGMT_FRAME_UPDATE, p2pFsmRunEventUpdateMgmtFrame}, ++ {MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, p2pFsmRunEventExtendListen}, ++#if CFG_SUPPORT_WFD ++ {MID_MNY_P2P_WFD_CFG_UPDATE, p2pFsmRunEventWfdSettingUpdate}, ++#endif ++ ++#endif ++ ++#if CFG_SUPPORT_ADHOC ++ {MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer}, ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ {MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort}, ++ {MID_MNY_AIS_REMAIN_ON_CHANNEL, aisFsmRunEventRemainOnChannel}, ++ {MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, aisFsmRunEventCancelRemainOnChannel}, ++ {MID_MNY_AIS_MGMT_TX, aisFsmRunEventMgmtFrameTx} ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++#if DBG ++#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ ++ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ ++ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ ++ DBGLOG(CNM, LOUD, "DO MSG [%d: %s]\n", prMsg->eMsgId, apucDebugMsg[prMsg->eMsgId]); \ ++ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ ++ } \ ++ else { \ ++ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ ++ cnmMemFree(prAdapter, prMsg); \ ++ } \ ++} while (0) ++#else ++#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ ++ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ ++ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ ++ DBGLOG(CNM, LOUD, "DO MSG [%d]\n", prMsg->eMsgId); \ ++ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ ++ } \ ++ else { \ ++ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ ++ cnmMemFree(prAdapter, prMsg); \ ++ } \ ++} while (0) ++#endif ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxInitMsgMap(VOID) ++{ ++ UINT_32 i, idx; ++ MSG_HNDL_ENTRY_T rTempEntry; ++ ++ ASSERT((sizeof(arMsgMapTable) / sizeof(MSG_HNDL_ENTRY_T)) == MID_TOTAL_NUM); ++ ++ for (i = 0; i < MID_TOTAL_NUM; i++) { ++ if (arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i) ++ continue; ++ for (idx = i + 1; idx < MID_TOTAL_NUM; idx++) { ++ if (arMsgMapTable[idx].eMsgId == (ENUM_MSG_ID_T) i) ++ break; ++ } ++ ASSERT(idx < MID_TOTAL_NUM); ++ if (idx >= MID_TOTAL_NUM) ++ continue; ++ ++ /* Swap target entry and current entry */ ++ rTempEntry.eMsgId = arMsgMapTable[idx].eMsgId; ++ rTempEntry.pfMsgHndl = arMsgMapTable[idx].pfMsgHndl; ++ ++ arMsgMapTable[idx].eMsgId = arMsgMapTable[i].eMsgId; ++ arMsgMapTable[idx].pfMsgHndl = arMsgMapTable[i].pfMsgHndl; ++ ++ arMsgMapTable[i].eMsgId = rTempEntry.eMsgId; ++ arMsgMapTable[i].pfMsgHndl = rTempEntry.pfMsgHndl; ++ } ++ ++ /* Verify the correctness of final message map */ ++ for (i = 0; i < MID_TOTAL_NUM; i++) { ++ ASSERT(arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i); ++ while (arMsgMapTable[i].eMsgId != (ENUM_MSG_ID_T) i) ++ ; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId) ++{ ++ P_MBOX_T prMbox; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); ++ ASSERT(prAdapter); ++ ++ prMbox = &(prAdapter->arMbox[eMboxId]); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_INITIALIZE(&prMbox->rLinkHead); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++mboxSendMsg(IN P_ADAPTER_T prAdapter, ++ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod) ++{ ++ P_MBOX_T prMbox; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); ++ ASSERT(prMsg); ++ ASSERT(prAdapter); ++ ++ prMbox = &(prAdapter->arMbox[eMboxId]); ++ ++ switch (eMethod) { ++ case MSG_SEND_METHOD_BUF: ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_INSERT_TAIL(&prMbox->rLinkHead, &prMsg->rLinkEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ ++ /* to wake up main service thread */ ++ GLUE_SET_EVENT(prAdapter->prGlueInfo); ++ ++ break; ++ ++ case MSG_SEND_METHOD_UNBUF: ++ MBOX_HNDL_MSG(prAdapter, prMsg); ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, ENUM_MBOX_ID_T eMboxId) ++{ ++ P_MBOX_T prMbox; ++ P_MSG_HDR_T prMsg; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); ++ ASSERT(prAdapter); ++ ++ prMbox = &(prAdapter->arMbox[eMboxId]); ++ ++ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ ++ ASSERT(prMsg); ++ MBOX_HNDL_MSG(prAdapter, prMsg); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ /* Initialize Mailbox */ ++ mboxInitMsgMap(); ++ ++ /* Setup/initialize each mailbox */ ++ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) ++ mboxSetup(prAdapter, i); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxDestroy(IN P_ADAPTER_T prAdapter) ++{ ++ P_MBOX_T prMbox; ++ P_MSG_HDR_T prMsg; ++ UINT_8 i; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { ++ prMbox = &(prAdapter->arMbox[i]); ++ ++ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); ++ ++ ASSERT(prMsg); ++ cnmMemFree(prAdapter, prMsg); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This is dummy function to prevent empty arMsgMapTable[] for compiling. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mboxDummy(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ASSERT(prAdapter); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c +new file mode 100644 +index 000000000000..7fb71a199ccf +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c +@@ -0,0 +1,498 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2 ++*/ ++ ++/*! \file "hs20.c" ++ \brief This file including the hotspot 2.0 related function. ++ ++ This file provided the macros and functions library support for the ++ protocol layer hotspot 2.0 related function. ++ ++*/ ++ ++/* ++** Log: hs20.c ++ * ++ */ ++ ++ /******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to generate Interworking IE for Probe Rsp, Bcn, Assoc Req/Rsp. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] prMsduInfo Pointer of the Msdu Info ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) ++{ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to generate Roaming Consortium IE for Probe Rsp, Bcn, Assoc Req/Rsp. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] prMsduInfo Pointer of the Msdu Info ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) ++{ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to generate HS2.0 IE for Probe Rsp, Bcn, Assoc Req/Rsp. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] prMsduInfo Pointer of the Msdu Info ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ /* ASSOC INFO IE ID: 221 :0xDD */ ++ if (prAdapter->prGlueInfo->u2HS20AssocInfoIELen) { ++ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucHS20AssocInfoIE, ++ prAdapter->prGlueInfo->u2HS20AssocInfoIELen); ++ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2HS20AssocInfoIELen; ++ } ++ ++} ++ ++VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_HS20_EXT_CAP_T prExtCap; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ /* Add Extended Capabilities IE */ ++ prExtCap = (P_HS20_EXT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; ++ else ++ prExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ ++ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); ++ ++ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); ++ ++ /* For R2 WNM-Notification */ ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); ++ } ++ kalPrint("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP); ++ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to fill up the content of Ext Cap IE bit 31. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] pucIE Pointer of the IE buffer ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) ++{ ++ P_HS20_EXT_CAP_T prExtCap; ++ ++ ASSERT(prAdapter); ++ ++ /* Add Extended Capabilities IE */ ++ prExtCap = (P_HS20_EXT_CAP_T) pucIE; ++ ++ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; ++ else ++ prExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ ++ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); ++ ++ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); ++ ++ /* For R2 WNM-Notification */ ++ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to fill up the content of HS2.0 IE. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[out] pucIE Pointer of the IE buffer ++* ++* \return VOID ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) ++{ ++ P_IE_HS20_INDICATION_T prHS20IndicationIe; ++ /* P_HS20_INFO_T prHS20Info; */ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ ++ /* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */ ++ ++ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pucIE; ++ ++ prHS20IndicationIe->ucId = ELEM_ID_VENDOR; ++ prHS20IndicationIe->ucLength = sizeof(IE_HS20_INDICATION_T) - ELEM_HDR_LEN; ++ prHS20IndicationIe->aucOui[0] = aucWfaOui[0]; ++ prHS20IndicationIe->aucOui[1] = aucWfaOui[1]; ++ prHS20IndicationIe->aucOui[2] = aucWfaOui[2]; ++ prHS20IndicationIe->ucType = VENDOR_OUI_TYPE_HS20; ++ prHS20IndicationIe->ucHotspotConfig = 0x00; /* prHS20Info->ucHotspotConfig; */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called while calculating length of hotspot 2.0 indication IE for Probe Request. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] pucTargetBSSID Pointer of target HESSID ++* ++* \return the length of composed HS20 IE ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID) ++{ ++ UINT_32 u4IeLength; ++ ++ if (0) /* Todo:: Not HS20 STA */ ++ return 0; ++ ++ u4IeLength = ++ sizeof(IE_HS20_INDICATION_T) + /* sizeof(IE_INTERWORKING_T) */ + (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP); ++ ++ if (!pucTargetBSSID) { ++ /* Do nothing */ ++ /* u4IeLength -= MAC_ADDR_LEN; */ ++ } ++ ++ return u4IeLength; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called while composing hotspot 2.0 indication IE for Probe Request. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* \param[in] pucTargetBSSID Pointer of target HESSID ++* \param[out] prIE Pointer of the IE buffer ++* ++* \return the wlan status ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE) ++{ ++ if (0) /* Todo:: Not HS20 STA */ ++ return 0; ++#if 0 ++ P_HS20_INFO_T prHS20Info; ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ ++ /* ++ * Generate 802.11u Interworking IE (107) ++ */ ++ hs20FillInterworkingIE(prAdapter, ++ prHS20Info->ucAccessNetworkOptions, ++ prHS20Info->ucVenueGroup, prHS20Info->ucVenueType, pucTargetBSSID, prIE); ++ prIE += IE_SIZE(prIE); ++#endif ++ /* ++ * Generate Ext Cap IE (127) ++ */ ++ hs20FillProreqExtCapIE(prAdapter, prIE); ++ prIE += IE_SIZE(prIE); ++ ++ /* ++ * Generate HS2.0 Indication IE (221) ++ */ ++ hs20FillHS20IE(prAdapter, prIE); ++ prIE += IE_SIZE(prIE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ PUINT_8 pucSenderIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET; ++ PUINT_8 pucTargetIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET; ++ PUINT_8 pucSenderMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SNEDER_MAC_OFFSET); ++#if CFG_HS20_DEBUG && 0 ++/* UINT_8 aucIpAllZero[4] = {0,0,0,0}; */ ++/* UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */ ++ PUINT_8 pucTargetMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET); ++#endif ++ ++#if CFG_HS20_DEBUG && 0 ++ PUINT_16 pu2ArpOper = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET); ++ ++ kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper)); ++ kalPrint("SENDER[ %pM ] [%pI4]\n", pucSenderMac, pucSenderIP); ++ kalPrint("TARGET[ %pM ] [%pI4]\n", pucTargetMac, pucTargetIP); ++#endif ++ ++ /* IsGratuitousArp */ ++ if (!kalMemCmp(pucSenderIP, pucTargetIP, 4)) { ++ kalPrint("Drop Gratuitous ARP from [ %pM ] [%pI4]\n", pucSenderMac, pucTargetIP); ++ return TRUE; ++ } ++ return FALSE; ++} ++ ++BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ PUINT_8 pucIpv6Protocol = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_PROTOCOL_OFFSET); ++ ++ /* kalPrint("pucIpv6Protocol [%02X:%02X]\n", *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); */ ++ if (*pucIpv6Protocol == IPV6_PROTOCOL_ICMPV6) { ++ PUINT_8 pucICMPv6Type = ++ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_TYPE_OFFSET); ++ /* kalPrint("pucICMPv6Type [%02X:%02X]\n", *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); */ ++ if (*pucICMPv6Type == ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT) { ++ PUINT_8 pucICMPv6Flag = ++ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_FLAG_OFFSET); ++ PUINT_8 pucSrcMAC = ((PUINT_8) prCurrSwRfb->pvHeader + MAC_ADDR_LEN); ++ ++#if CFG_HS20_DEBUG ++ kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n", ++ *pucICMPv6Flag, ++ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_ROUTER_BIT) >> 7, ++ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT) >> 6, ++ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_OVERWRITE_BIT) >> 5); ++#endif ++ if (!(*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT)) { ++ kalPrint("Drop Unsolicited Neighbor Advertisement from [%pM]\n", pucSrcMAC); ++ return TRUE; ++ } ++ } ++ } ++ ++ return FALSE; ++} ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ /* ++ P_CONNECTION_SETTINGS_T prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ PUINT_8 pucEthDestAddr = prCurrSwRfb->pvHeader; ++ */ ++ /* 3 TODO: Need to verify this function before enable it */ ++ return FALSE; ++ /* ++ if ((prConnSettings->eEncStatus != ENUM_ENCRYPTION_DISABLED) && IS_BMCAST_MAC_ADDR(pucEthDestAddr)) { ++ UINT_8 ucIdx = 0; ++ PUINT_32 prIpAddr, prPacketDA; ++ PUINT_16 pu2PktIpVer = ++ (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); ++ ++ if (*pu2PktIpVer == htons(ETH_P_IPV4)) { ++ if (!prBssInfo->prIpV4NetAddrList) ++ return FALSE; ++ for (ucIdx = 0; ucIdx < prBssInfo->prIpV4NetAddrList->ucAddrCount; ucIdx++) { ++ prIpAddr = (PUINT_32) &prBssInfo->prIpV4NetAddrList->arNetAddr[ucIdx].aucIpAddr[0]; ++ prPacketDA = ++ (PUINT_32) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ++ IPV4_HDR_IP_DST_ADDR_OFFSET); ++ ++ if (kalMemCmp(prIpAddr, prPacketDA, 4) == 0) { ++ kalPrint("Drop FORGED IPv4 packet\n"); ++ return TRUE; ++ } ++ } ++ } ++#ifdef CONFIG_IPV6 ++ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) { ++ UINT_8 aucIPv6Mac[MAC_ADDR_LEN]; ++ PUINT_8 pucIdx = ++ prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET; ++ ++ kalMemCopy(&aucIPv6Mac[0], pucIdx, 3); ++ pucIdx += 5; ++ kalMemCopy(&aucIPv6Mac[3], pucIdx, 3); ++ kalPrint("Get IPv6 frame Dst IP MAC part %pM\n", aucIPv6Mac); ++ if (EQUAL_MAC_ADDR(aucIPv6Mac, prBssInfo->aucOwnMacAddr)) { ++ kalPrint("Drop FORGED IPv6 packet\n"); ++ return TRUE; ++ } ++ } ++#endif ++ } ++ ++ return FALSE; ++ */ ++} ++#endif ++ ++BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) ++{ ++ PUINT_16 pu2PktIpVer = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); ++ ++ /* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */ ++#if CFG_HS20_DEBUG & 0 ++ UINT_8 i = 0; ++ ++ kalPrint("==============================================="); ++ for (i = 0; i < 96; i++) { ++ if (!(i % 16)) ++ kalPrint("\n"); ++ kalPrint("%02X ", *((PUINT_8) prCurrSwRfb->pvHeader + i)); ++ } ++ kalPrint("\n"); ++#endif ++ ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ if (hs20IsForgedGTKFrame(prAdapter, prBssInfo, prCurrSwRfb)) ++ return TRUE; ++ ++#endif ++ if (*pu2PktIpVer == htons(ETH_P_ARP)) ++ return hs20IsGratuitousArp(prAdapter, prCurrSwRfb); ++ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) ++ return hs20IsUnsolicitedNeighborAdv(prAdapter, prCurrSwRfb); ++ ++ return FALSE; ++} ++ ++BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) ++{ ++#if 1 ++ if (prAdapter->prGlueInfo->fgConnectHS20AP) ++ return TRUE; ++#else ++ PARAM_SSID_T rParamSsid; ++ P_BSS_DESC_T prBssDesc; ++ ++ rParamSsid.u4SsidLen = prBssInfo->ucSSIDLen; ++ COPY_SSID(rParamSsid.aucSsid, rParamSsid.u4SsidLen, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ ++ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, prBssInfo->aucBSSID, TRUE, &rParamSsid); ++ if (!prBssDesc) ++ return FALSE; ++ ++ if (prBssDesc->fgIsSupportHS20) { ++ if (!(prBssDesc->ucHotspotConfig & ELEM_HS_CONFIG_DGAF_DISABLED_MASK)) ++ return TRUE; ++ ++ /* Disable frame filter only if DGAF == 1 */ ++ return FALSE; ++ ++ } ++#endif ++ ++ /* For Now, always return true to run hs20 check even for legacy AP */ ++ return TRUE; ++} ++ ++WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) ++{ ++ P_PARAM_HS20_SET_BSSID_POOL prParamBssidPool = (P_PARAM_HS20_SET_BSSID_POOL) pvBuffer; ++ P_HS20_INFO_T prHS20Info; ++ UINT_8 ucIdx; ++ ++ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); ++ kalPrint("[%s]Set Bssid Pool! enable[%d] num[%d]\n", __func__, prParamBssidPool->fgIsEnable, ++ prParamBssidPool->ucNumBssidPool); ++ for (ucIdx = 0; ucIdx < prParamBssidPool->ucNumBssidPool; ucIdx++) { ++ COPY_MAC_ADDR(prHS20Info->arBssidPool[ucIdx].aucBSSID, &prParamBssidPool->arBSSID[ucIdx]); ++ kalPrint("[%s][%d][ %pM ]\n", __func__, ucIdx, (prHS20Info->arBssidPool[ucIdx].aucBSSID)); ++ } ++ prHS20Info->fgIsHS2SigmaMode = prParamBssidPool->fgIsEnable; ++ prHS20Info->ucNumBssidPoolEntry = prParamBssidPool->ucNumBssidPool; ++ ++#if 0 ++ wlanClearScanningResult(prAdapter); ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c +new file mode 100644 +index 000000000000..469a48ebe9c1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c +@@ -0,0 +1,111 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/mib.c#1 ++*/ ++ ++/*! \file "mib.c" ++ \brief This file includes the mib default vale and functions. ++*/ ++ ++/* ++** Log: mib.c ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add mib.c. ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[] = { ++ {RATE_SET_HR_DSSS, TRUE, FALSE} ++ , /* For PHY_TYPE_HR_DSSS_INDEX(0) */ ++ {RATE_SET_ERP, TRUE, TRUE} ++ , /* For PHY_TYPE_ERP_INDEX(1) */ ++ {RATE_SET_ERP_P2P, TRUE, TRUE} ++ , /* For PHY_TYPE_ERP_P2P_INDEX(2) */ ++ {RATE_SET_OFDM, FALSE, FALSE} ++ , /* For PHY_TYPE_OFDM_INDEX(3) */ ++}; ++ ++NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[AD_HOC_MODE_NUM] = { ++ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} ++ , /* For AD_HOC_MODE_11B(0) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} ++ , /* For AD_HOC_MODE_MIXED_11BG(1) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} ++ , /* For AD_HOC_MODE_11G(2) */ ++ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} ++ , /* For AD_HOC_MODE_11A(3) */ ++}; ++ ++NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[AP_MODE_NUM] = { ++ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} ++ , /* For AP_MODE_11B(0) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} ++ , /* For AP_MODE_MIXED_11BG(1) */ ++ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} ++ , /* For AP_MODE_11G(2) */ ++ {PHY_TYPE_ERP_P2P_INDEX, BASIC_RATE_SET_ERP_P2P} ++ , /* For AP_MODE_11G_P2P(3) */ ++ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} ++ , /* For AP_MODE_11A(4) */ ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c +new file mode 100644 +index 000000000000..cb5fbebedd49 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c +@@ -0,0 +1,87 @@ ++/* ++** Id: @(#) p2p_assoc.c@@ ++*/ ++ ++/*! \file "p2p_assoc.c" ++ \brief This file includes the Wi-Fi Direct association-related functions. ++ ++ This file includes the association-related functions. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to compose Common Information Elements for P2P Association ++* Request Frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ /* Fill the SSID element. */ ++ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; ++ ++ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of ++ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. ++ */ ++ ++ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, ++ SSID_IE(pucBuffer)->ucLength, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ return pucBuffer; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c +new file mode 100644 +index 000000000000..72a20a322cee +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c +@@ -0,0 +1,58 @@ ++/* ++** Id: @(#) p2p_bss.c@@ ++*/ ++ ++/*! \file "p2p_bss.c" ++ \brief This file contains the functions for creating p2p BSS(AP). ++ ++ This file contains the functions for BSS(AP). We may create a BSS ++ network, or merge with exist IBSS network and sending Beacon Frame or reply ++ the Probe Response Frame for received Probe Request Frame. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c +new file mode 100644 +index 000000000000..f8c09e2aa9de +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c +@@ -0,0 +1,3139 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/mgmt/p2p_fsm.c#61 ++*/ ++ ++/*! \file "p2p_fsm.c" ++ \brief This file defines the FSM for P2P Module. ++ ++ This file defines the FSM for P2P Module. ++*/ ++ ++/* ++** Log: p2p_fsm.c ++** ++** 12 20 2012 yuche.tsai ++** [ALPS00410124] [Rose][Free Test][KE][rlmUpdateParamsForAP]The device reboot automatically ++** and then "Fatal/Kernel" pops up during use data service.(Once) ++** Fix possible NULL station record cause KE under AP mode. ++** May due to variable uninitial. ++** Review: http://mtksap20:8080/go?page=NewReview&reviewid=49970 ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected ++**to AP previously,one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 08 21 2012 yuche.tsai ++** NULL ++** fix disconnect indication. ++** ++** 08 16 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** Fix p2p bug find on ALPS.JB trunk. ++** ++** 07 27 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update for driver unload KE issue. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Fix the compile flag of enhancement. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000808] [Volunteer Patch][MT6620][Driver/FW] Device discoverability issue fix ++ * Change device discoverability methodology. From driver SCAN to FW lock channel. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Add wifi direct connection enhancement method I, II & VI. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000833] [Volunteer Patch][WiFi Direct][Driver] Service Discovery Frame RX Indicate Issue ++ * Fix Service Discovery Race Condition Issue. ++ * ++ * 06 23 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * change parameter name from PeerAddr to BSSID ++ * ++ * 06 21 2011 yuche.tsai ++ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. ++ * Fix an issue of accepting connection of GO. ++ * ++ * 06 21 2011 yuche.tsai ++ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability ++ * Drop GAS frame when SD is not enabled. ++ * ++ * 06 20 2011 yuche.tsai ++ * NULL ++ * Fix compile error. ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. ++ * Fix connection indication twice issue. ++ * ++ * 06 20 2011 cp.wu ++ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module ++ * 1. specify target's BSSID when requesting channel privilege. ++ * 2. pass BSSID information to firmware domain ++ * ++ * 06 20 2011 yuche.tsai ++ * [WCXRP00000795] [Volunteer Patch][MT6620][Driver] GO can not connect second device issue ++ * Solve P2P GO can not formation with second device issue. ++ * ++ * 06 14 2011 yuche.tsai ++ * NULL ++ * Change disconnect feature. ++ * ++ * 06 10 2011 yuche.tsai ++ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability[WCXRP00000776] ++ * [Need Patch][MT6620][Driver] MT6620 response probe request of P2P device with P2P IE under Hot Spot mode. ++ * 1. Dynamic enable SD capability after P2P supplicant ready. ++ * 2. Avoid response probe respone with p2p IE when under hot spot mode. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Fix RX SD request under AP mode issue. ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction ++ * eliminate unused parameters for SAA-FSM ++ * ++ * 05 26 2011 yuche.tsai ++ * [WCXRP00000745] Support accepting connection after one Group Connection Lost. ++ ++After Group Formation & lost connection, if MT6620 behave as: ++ ++1. GO: It would keep under GO state until been dissolved by supplicant. ++ ++ At this time, other P2P device can use join method to join this group. ++ ++2. GC: It would keep on searching target GO or target device until been dissolved by supplicant. ++ ++At this time, it would ignore other P2P device formation request. ++ ++-- ++ ++Modification: Make driver to accept GO NEGO REQ at this time, to let user decide to accept new connection or not. ++ ++ * [Volunteer Patch][MT6620][Driver] ++ * Driver would indicate connection request, if password ID is not ready but connection request is issued. ++ * ++ * 05 18 2011 yuche.tsai ++ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. ++ * A solution for both connection request & IO control. ++ * ++ * 05 16 2011 yuche.tsai ++ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. ++ * Fix SD request can not send out issue. ++ * ++ * 05 09 2011 terry.wu ++ * [WCXRP00000711] [MT6620 Wi-Fi][Driver] Set Initial value of StaType in StaRec for Hotspot Client ++ * Set initial value of StaType in StaRec for hotspot client. ++ * ++ * 05 04 2011 yuche.tsai ++ * [WCXRP00000697] [Volunteer Patch][MT6620][Driver] ++ * Bug fix for p2p descriptor is NULL if BSS descriptor is found first. ++ * ++ * 05 04 2011 yuche.tsai ++ * NULL ++ * Support partial persistent group function. ++ * ++ * 05 02 2011 yuche.tsai ++ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. ++ * Clear formation flag after formation timeout. ++ * ++ * 04 20 2011 yuche.tsai ++ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition ++ * when add scan & query scan result at the same time. ++ * Fix side effect while starting ATGO. ++ * ++ * 04 20 2011 yuche.tsai ++ * NULL ++ * Fix ASSERT issue in FW, side effect of last change. ++ * ++ * 04 19 2011 yuche.tsai ++ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition ++ * when add scan & query scan result at the same time. ++ * Workaround for multiple device connection, before invitation ready. ++ * ++ * 04 19 2011 yuche.tsai ++ * [WCXRP00000665] [Wifi Direct][MT6620 E4] When use Ralink's dongle to establish wifi direct connection with PBC. ++ * But 6573 always not pop accept option to establish connection. ++ * Support connection indication when GO NEGO REQ doesn't have configure method, instead it has PasswordID. ++ * ++ * 04 18 2011 yuche.tsai ++ * NULL ++ * Fix error. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Fix a connection issue. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Fix the channel issue of AP mode. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Connection flow refine for Sigma test. ++ * ++ * 04 09 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Fix Device discoverability related issue. ++ * ++ * 04 09 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Fix bug for Device Discoverability. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Fix compile error. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * ++ * 03 28 2011 yuche.tsai ++ * NULL ++ * Fix a possible issue for retry join when media status connected. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Improve some error handleing. ++ * ++ * 03 24 2011 yuche.tsai ++ * NULL ++ * Assign AID before change STA_REC state to state 3. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix Response Rate Issue when TX Auth Rsp Frame under P2P Mode. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix issue of connection to one GC. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix ASSERT issue when starting Hot-spot. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * When Target Information is not available, change to passive mode. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Fix one connection issue while using Keypad to connect a GO. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * 1. Fix two issues that may cause kernel panic. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Fix GC connect to other device issue. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * 1.Shorten the LISTEN interval. ++ * 2. Fix IF address issue when we are GO ++ * 3. Fix LISTEN channel issue. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Modify formation policy setting. ++ * ++ * 03 21 2011 yuche.tsai ++ * NULL ++ * Solve Listen State doesn't response probe response issue. ++ * ++ * 03 21 2011 yuche.tsai ++ * NULL ++ * Change P2P Connection Request Flow. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue ++ * Indicate the correct Group SSID when join on Group. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue ++ * Support the third P2P device to join GO/GC group. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue ++ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000578] [Volunteer Patch][MT6620][Driver] Separate Connection Request from general IOCTL ++ * Separate connection request from general IOCTL. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow ++ * Modify connection flow after Group Formation Complete, or device connect to a GO. ++ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * When AIS is connect to an AP, Hot Spot would be enabled under fixed same channel. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Solve the Group Info IE in Probe Response incorrect issue. ++ * ++ * 03 17 2011 yuche.tsai ++ * NULL ++ * Release Channel after Join Complete. ++ * ++ * 03 16 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the protected while at P2P start GO, and skip some security check . ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix local configure method issue. ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix some configure method issue. ++ * ++ * 03 14 2011 yuche.tsai ++ * NULL ++ * . ++ * ++ * 03 14 2011 yuche.tsai ++ * NULL ++ * Fix password ID issue. ++ * ++ * 03 10 2011 yuche.tsai ++ * NULL ++ * Add P2P API. ++ * ++ * 03 08 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue[WCXRP00000509] ++ * [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. ++ * . ++ * ++ * 03 07 2011 yuche.tsai ++ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. ++ * . ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 04 2011 wh.su ++ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue ++ * fixed the p2p action frame type check for device request indication. ++ * ++ * 03 02 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix Service Discovery RX packet buffer pointer. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation ++ * Update channel issue when doing GO formation.. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Update Service Discovery Related wlanoid function. ++ * ++ * 02 21 2011 yuche.tsai ++ * [WCXRP00000481] [Volunteer Patch][MT6620][FW] Scan hang under concurrent case. ++ * Fix all BE issue of WSC or P2P IE. ++ * ++ * 02 18 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * fixed the wsc config method mapping to driver used config method issue. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000479] [Volunteer Patch][MT6620][Driver] Probe Response of P2P using 11b rate. ++ * Update basic rate to FW, after P2P is initialed. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame during search ++ * phase do not contain P2P wildcard SSID. ++ * Use P2P Wildcard SSID when scan type of P2P_WILDCARD_SSID is set. ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue ++ * Fix WSC IE BE format issue. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * append the WSC IE config method attribute at provision discovery request. ++ * ++ * 02 16 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * fixed the probe request send out without WSC IE issue (at P2P). ++ * ++ * 02 16 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * If two station connected to the Hot-Spot and one disconnect, FW would get into an infinite loop ++ * ++ * 02 15 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Fix re-connection issue after RX deauthentication. ++ * ++ * 02 15 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Fix conneciton issue after disconnect with AP. ++ * ++ * 02 12 2011 yuche.tsai ++ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. ++ * P2P Create Station Type according to Target BSS capability. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Support Disassoc & Deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Indication Related code. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add Support for MLME deauthentication for Hot-Spot. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue ++ * Fix Client Limit Issue. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect ++ * to target station for AAA module. ++ * Disconnect every station client when disolve on P2P group. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * 1. Fix Service Disocvery Logical issue. ++ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect ++ * to target station for AAA module. ++ * Workaround of disable P2P network. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue ++ * 1. Fixed SSID wrong length issue. ++ * 2. Under Hot Spot configuration, there won't be any P2P IE. ++ * 3. Under Hot Spot configuration, P2P FSM won't get into LISTEN state first. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Modify Start GO flow. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Fix desire phy type set issue. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Add desire phy type set phase I. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix P2P Disconnect Issue. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Add Service Discovery Function. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix compile error when DBG is disabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type Definition. ++ * ++ * 01 19 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Add P2P QoS Support. ++ * ++ * 01 19 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Null NOA attribute setting when no related parameters. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify AAA flow according to CM's comment. ++ * ++ * 01 13 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Resolve Channel ZERO issue. (Uninitialized default channel) ++ * ++ * 01 13 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Update P2P State Debug Message. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Fix bug when allocating message buffer. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update ++ * when STA record is created under AP Mode. ++ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, ++ * but if the P2P device is connected, 11b rate is not allowed. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. ++ * 2. Call cnmP2pIsPermit() before active P2P network. ++ * 3. Add channel selection support for AP mode. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix Bug of reference to NULL pointer. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Modify some behavior of AP mode. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix bug of wrong pointer check. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix Compile Error. ++ * ++ * 01 11 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Add station record into client list before change it state from STATE_2 to STATE_3. ++ * ++ * 01 05 2011 yuche.tsai ++ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, ++ * but the SSID length is still invalid. ++ * Specify SSID Type when issue a scan request. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations ++ * to ease physically continuous memory demands ++ * correct typo ++ * ++ * 01 05 2011 george.huang ++ * [WCXRP00000343] [MT6620 Wi-Fi] Add TSF reset path for concurrent operation ++ * modify NOA update path for preventing assertion false alarm. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations ++ * to ease physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 01 03 2011 wh.su ++ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! ++ * let the p2p ap mode acept a legacy device join. ++ * ++ * 12 22 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Fix Compile Error. ++ * ++ * 12 15 2010 yuche.tsai ++ * [WCXRP00000245] 1. Invitation Request/Response. ++2. Provision Discovery Request/Response ++ ++ * Refine Connection Flow. ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in ++ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. ++ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client ++ * by checking the P2P IE in assoc req frame. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * The order of invoking nicUpdateBss() and rlm functions ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation. ++ * ++ * 12 02 2010 yuche.tsai ++ * NULL ++ * Update P2P Connection Policy for Invitation & Provision Discovery. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Update RCIP value when RX assoc request frame. ++ * ++ * 11 29 2010 yuche.tsai ++ * NULL ++ * Update P2P related function for INVITATION & PROVISION DISCOVERY. ++ * ++ * 11 26 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Update P2P PS for NOA function. ++ * ++ * 11 25 2010 yuche.tsai ++ * NULL ++ * Update Code for Invitation Related Function. ++ * ++ * 11 17 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] ++ * Set the Tx lowest rate at wlan table for normal operation ++ * fixed some ASSERT check. ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * fixed the p2p role code error. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * fixed the ASSERT check error ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 10 19 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state ++ * machine[WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android ++ * fixed the compiling error. ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android ++ * adding a code to support Direct GO with a compiling flag . ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. ++ * correct erroneous logic: specifying eBand with incompatible eSco ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * fixed the compiling error. ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at WinXP. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Reset Common IE Buffer of P2P INFO when scan request is issued. ++ * If an action frame other than public action frame is received, return direcly. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Add P2P Connection Abort Event Message handler. ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 yuche.tsai ++ * NULL ++ * 1. Fix Interface Address from GO Nego Req/Rsp is not correct. ++ * 2. Fix GO mode does not change media state after station connected. ++ * 3. Fix STA don't response probe request when there is a connection request. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 20 2010 kevin.huang ++ * NULL ++ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Add Glue Layer indication. ++ * ++ * 08 17 2010 yuche.tsai ++ * NULL ++ * Fix compile warning under Linux. ++ * ++ * 08 17 2010 yuche.tsai ++ * NULL ++ * Fix some P2P FSM bug. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add random Interface Address Generation support. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Fix some P2P FSM bug. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Update P2P FSM code for GO Nego. ++ * ++ * 08 16 2010 kevin.huang ++ * NULL ++ * Refine AAA functions ++ * ++ * 08 12 2010 kevin.huang ++ * NULL ++ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Join complete indication. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add two boolean in connection request. ++ * Based on these two boolean value, P2P FSM should ++ * decide to do invitation or group formation or start a GO directly. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Update P2P FSM, currently P2P Device Discovery is verified. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Update P2P FSM for group formation. ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * limit build always needs spin-lock declaration. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add P2P FSM code check in. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 yuche.tsai ++ * ++ * Update P2P FSM. ++ * ++ * 07 09 2010 george.huang ++ * ++ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error while enable WIFI_DIRECT support. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Update P2P Function call. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * First draft for migration P2P FSM from FW to Driver. ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Rename CFG flag for P2P ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add code to test P2P GO ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add Wi-Fi Direct SSID and P2P GO Test Mode ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Modify code due to BAND_24G define was changed ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Revise data structure to share the same BSS_INFO_T for avoiding coding error ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugP2pState[P2P_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("P2P_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("P2P_STATE_SCAN"), ++ (PUINT_8) DISP_STRING("P2P_STATE_AP_CHANNEL_DETECT"), ++ (PUINT_8) DISP_STRING("P2P_STATE_REQING_CHANNEL"), ++ (PUINT_8) DISP_STRING("P2P_STATE_CHNL_ON_HAND"), ++ (PUINT_8) DISP_STRING("P2P_STATE_GC_JOIN") ++}; ++ ++/*lint -restore */ ++#else ++static UINT_8 apucDebugP2pState[P2P_STATE_NUM] = { ++ P2P_STATE_IDLE, ++ P2P_STATE_SCAN, ++ P2P_STATE_AP_CHANNEL_DETECT, ++ P2P_STATE_REQING_CHANNEL, ++ P2P_STATE_CHNL_ON_HAND, ++ P2P_STATE_GC_JOIN ++}; ++ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/* p2pStateXXX : Processing P2P FSM related action. ++ * p2pFSMXXX : Control P2P FSM flow. ++ * p2pFuncXXX : Function for doing one thing. ++ */ ++VOID p2pFsmInit(IN P_ADAPTER_T prAdapter) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ ASSERT_BREAK(prP2pFsmInfo != NULL); ++ ++ LINK_INITIALIZE(&(prP2pFsmInfo->rMsgEventQueue)); ++ LINK_INITIALIZE(&(prP2pBssInfo->rStaRecOfClientList)); ++ ++ prP2pFsmInfo->eCurrentState = prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE; ++ prP2pFsmInfo->prTargetBss = NULL; ++ prP2pFsmInfo->fgIsWPSMode = 0; ++ ++ cnmTimerInitTimer(prAdapter, ++ &(prAdapter->rP2pFsmTimeoutTimer), ++ (PFN_MGMT_TIMEOUT_FUNC) p2pFsmRunEventFsmTimeout, (ULONG) prP2pFsmInfo); ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* 4 <2.1> Initiate BSS_INFO_T - Setup HW ID */ ++ prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; ++ prP2pBssInfo->ucHwDefaultFixedRateCode = RATE_OFDM_6M; ++ ++ prP2pBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prP2pBssInfo->u2BSSBasicRateSet = ++ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ ++ prP2pBssInfo->u2OperationalRateSet = ++ rNonHTPhyAttributes[prP2pBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet, ++ prP2pBssInfo->u2BSSBasicRateSet, ++ prP2pBssInfo->aucAllSupportedRates, &prP2pBssInfo->ucAllSupportedRatesLen); ++ ++ prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, ++ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); ++ ++ if (prP2pBssInfo->prBeacon) { ++ prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; ++ prP2pBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ ++ prP2pBssInfo->prBeacon->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ } else { ++ /* Out of memory. */ ++ ASSERT(FALSE); ++ } ++ ++ prP2pBssInfo->eCurrentOPMode = OP_MODE_NUM; ++ ++ prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; ++ prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; ++ prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; ++ prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL; ++ prP2pBssInfo->eBand = BAND_2G4; ++ prP2pBssInfo->eBssSCO = CHNL_EXT_SCN; ++ ++ if (prAdapter->rWifiVar.fgSupportQoS) ++ prP2pBssInfo->fgIsQBSS = TRUE; ++ else ++ prP2pBssInfo->fgIsQBSS = FALSE; ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } while (FALSE); ++ ++} /* p2pFsmInit */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function is used to uninitialize the value in P2P_FSM_INFO_T for ++* P2P FSM operation ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ DEBUGFUNC("p2pFsmUninit()"); ++ DBGLOG(P2P, INFO, "->p2pFsmUninit()\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, OP_MODE_P2P_DEVICE, TRUE); ++ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM); ++ ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ wlanAcquirePowerControl(prAdapter); ++ ++ /* Release all pending CMD queue. */ ++ DBGLOG(P2P, TRACE, "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n", ++ (UINT_32) prAdapter->prGlueInfo->rCmdQueue.u4NumElem); ++ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); ++ ++ wlanReleasePowerControl(prAdapter); ++ ++ /* Release pending mgmt frame, ++ * mgmt frame may be pending by CMD without resource. ++ */ ++ kalClearMgmtFramesByNetType(prAdapter->prGlueInfo, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Clear PendingCmdQue */ ++ wlanReleasePendingCMDbyNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ if (prP2pBssInfo->prBeacon) { ++ cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); ++ prP2pBssInfo->prBeacon = NULL; ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* end of p2pFsmUninit() */ ++ ++VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ BOOLEAN fgIsTransOut = (BOOLEAN) FALSE; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (!IS_BSS_ACTIVE(prP2pBssInfo)) { ++ if (!cnmP2PIsPermitted(prAdapter)) ++ return; ++ ++ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ fgIsTransOut = fgIsTransOut ? FALSE : TRUE; ++ ++ if (!fgIsTransOut) { ++#if DBG ++ DBGLOG(P2P, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugP2pState[prP2pFsmInfo->eCurrentState], ++ apucDebugP2pState[eNextState]); ++#else ++ DBGLOG(P2P, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_P2P_IDX, apucDebugP2pState[prP2pFsmInfo->eCurrentState], ++ apucDebugP2pState[eNextState]); ++#endif ++ ++ /* Transition into current state. */ ++ prP2pFsmInfo->ePreviousState = prP2pFsmInfo->eCurrentState; ++ prP2pFsmInfo->eCurrentState = eNextState; ++ } ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_IDLE: ++ if (fgIsTransOut) ++ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, eNextState); ++ else ++ fgIsTransOut = p2pStateInit_IDLE(prAdapter, prP2pFsmInfo, prP2pBssInfo, &eNextState); ++ break; ++ case P2P_STATE_SCAN: ++ if (fgIsTransOut) { ++ /* Scan done / scan canceled. */ ++ p2pStateAbort_SCAN(prAdapter, prP2pFsmInfo, eNextState); ++ } else { ++ /* Initial scan request. */ ++ p2pStateInit_SCAN(prAdapter, prP2pFsmInfo); ++ } ++ ++ break; ++ case P2P_STATE_AP_CHANNEL_DETECT: ++ if (fgIsTransOut) { ++ /* Scan done */ ++ /* Get sparse channel result. */ ++ p2pStateAbort_AP_CHANNEL_DETECT(prAdapter, ++ prP2pFsmInfo, prP2pSpecificBssInfo, eNextState); ++ } ++ ++ else { ++ /* Initial passive scan request. */ ++ p2pStateInit_AP_CHANNEL_DETECT(prAdapter, prP2pFsmInfo); ++ } ++ ++ break; ++ case P2P_STATE_REQING_CHANNEL: ++ if (fgIsTransOut) { ++ /* Channel on hand / Channel canceled. */ ++ p2pStateAbort_REQING_CHANNEL(prAdapter, prP2pFsmInfo, eNextState); ++ } else { ++ /* Initial channel request. */ ++ p2pFuncAcquireCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ } ++ ++ break; ++ case P2P_STATE_CHNL_ON_HAND: ++ if (fgIsTransOut) { ++ p2pStateAbort_CHNL_ON_HAND(prAdapter, prP2pFsmInfo, prP2pBssInfo, eNextState); ++ } else { ++ /* Initial channel ready. */ ++ /* Send channel ready event. */ ++ /* Start a FSM timer. */ ++ p2pStateInit_CHNL_ON_HAND(prAdapter, prP2pBssInfo, prP2pFsmInfo); ++ } ++ ++ break; ++ case P2P_STATE_GC_JOIN: ++ if (fgIsTransOut) { ++ /* Join complete / join canceled. */ ++ p2pStateAbort_GC_JOIN(prAdapter, prP2pFsmInfo, &(prP2pFsmInfo->rJoinInfo), eNextState); ++ } else { ++ if (prP2pFsmInfo->prTargetBss == NULL) { ++ ASSERT(FALSE); ++ } else { ++ /* Send request to SAA module. */ ++ p2pStateInit_GC_JOIN(prAdapter, ++ prP2pFsmInfo, ++ prP2pBssInfo, ++ &(prP2pFsmInfo->rJoinInfo), prP2pFsmInfo->prTargetBss); ++ } ++ } ++ ++ break; ++ default: ++ break; ++ } ++ ++ } while (fgIsTransOut); ++ ++} /* p2pFsmStateTransition */ ++ ++VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchOpMode = (P_MSG_P2P_SWITCH_OP_MODE_T) prMsgHdr; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwitchOpMode != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventSwitchOPMode\n"); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prSwitchOpMode->eOpMode >= OP_MODE_NUM) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ /* P2P Device / GC. */ ++ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, prSwitchOpMode->eOpMode, TRUE); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventSwitchOPMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle scan done event during Device Discovery. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) NULL; ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ /* This scan done event is either for "SCAN" phase or "SEARCH" state or "LISTEN" state. ++ * The scan done for SCAN phase & SEARCH state doesn't imply Device ++ * Discovery over. ++ */ ++ DBGLOG(P2P, TRACE, "P2P Scan Done Event\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ ++ if (prScanDoneMsg->ucSeqNum != prScanReqInfo->ucSeqNumOfScnMsg) { ++ /* Scan Done message sequence number mismatch. ++ * Ignore this event. (P2P FSM issue two scan events.) ++ */ ++ /* The scan request has been cancelled. ++ * Ignore this message. It is possible. ++ */ ++ DBGLOG(P2P, TRACE, "P2P Scan Don SeqNum:%d <-> P2P Fsm SCAN Msg:%d\n", ++ prScanDoneMsg->ucSeqNum, prScanReqInfo->ucSeqNumOfScnMsg); ++ ++ break; ++ } ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_SCAN: ++ { ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ ++ prScanReqInfo->fgIsAbort = FALSE; ++ ++ if (prConnReqInfo->fgIsConnRequest) { ++ prP2pFsmInfo->prTargetBss = p2pFuncKeepOnConnection(prAdapter, ++ &prP2pFsmInfo->rConnReqInfo, ++ &prP2pFsmInfo->rChnlReqInfo, ++ &prP2pFsmInfo->rScanReqInfo); ++ if (prP2pFsmInfo->prTargetBss == NULL) ++ eNextState = P2P_STATE_SCAN; ++ else ++ eNextState = P2P_STATE_REQING_CHANNEL; ++ } else { ++ eNextState = P2P_STATE_IDLE; ++ } ++ ++ } ++ break; ++ case P2P_STATE_AP_CHANNEL_DETECT: ++ eNextState = P2P_STATE_REQING_CHANNEL; ++ break; ++ default: ++ /* Unexpected channel scan done event without being chanceled. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prScanReqInfo->fgIsScanRequest = FALSE; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventScanDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is call when channel is granted by CNM module from FW. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_MSG_CH_GRANT_T prMsgChGrant = (P_MSG_CH_GRANT_T) NULL; ++ UINT_8 ucTokenID = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "P2P Run Event Channel Grant\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; ++ ucTokenID = prMsgChGrant->ucTokenID; ++ prP2pFsmInfo->u4GrantInterval = prMsgChGrant->u4GrantInterval; ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ if (ucTokenID == prChnlReqInfo->ucSeqNumOfChReq) { ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_REQING_CHANNEL: ++ switch (prChnlReqInfo->eChannelReqType) { ++ case CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL: ++ eNextState = P2P_STATE_CHNL_ON_HAND; ++ break; ++ case CHANNEL_REQ_TYPE_GC_JOIN_REQ: ++ eNextState = P2P_STATE_GC_JOIN; ++ break; ++ case CHANNEL_REQ_TYPE_GO_START_BSS: ++ eNextState = P2P_STATE_IDLE; ++ break; ++ default: ++ break; ++ } ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); ++ break; ++ default: ++ /* Channel is granted under unexpected state. ++ * Driver should cancel channel privileagea before leaving the states. ++ */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } else { ++ /* Channel requsted, but released. */ ++ /* ASSERT(!prChnlReqInfo->fgIsChannelRequested); */ ++ DBGLOG(P2P, TRACE, "Channel requsted, but released\n"); ++ } ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventChGrant */ ++ ++VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_MSG_P2P_CHNL_REQUEST_T prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) prMsgHdr; ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelRequest\n"); ++ ++ /* Special case of time renewing for same frequency. */ ++ if ((prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) && ++ (prChnlReqInfo->ucReqChnlNum == prP2pChnlReqMsg->rChannelInfo.ucChannelNum) && ++ (prChnlReqInfo->eBand == prP2pChnlReqMsg->rChannelInfo.eBand) && ++ (prChnlReqInfo->eChnlSco == prP2pChnlReqMsg->eChnlSco)) { ++ ++ ASSERT(prChnlReqInfo->fgIsChannelRequested == TRUE); ++ ASSERT(prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL); ++ ++ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; ++ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; ++ ++ /* Re-enter the state. */ ++ eNextState = P2P_STATE_CHNL_ON_HAND; ++ } else { ++ ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ /* Cookie can only be assign after abort.(for indication) */ ++ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; ++ prChnlReqInfo->ucReqChnlNum = prP2pChnlReqMsg->rChannelInfo.ucChannelNum; ++ prChnlReqInfo->eBand = prP2pChnlReqMsg->rChannelInfo.eBand; ++ prChnlReqInfo->eChnlSco = prP2pChnlReqMsg->eChnlSco; ++ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL; ++ ++ eNextState = P2P_STATE_REQING_CHANNEL; ++ } ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventChannelRequest */ ++ ++VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_MSG_P2P_CHNL_ABORT_T prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) NULL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) prMsgHdr; ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelAbort\n"); ++ ++ if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) && (prChnlReqInfo->fgIsChannelRequested)) { ++ ++ ASSERT((prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL || ++ (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND))); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventChannelAbort */ ++ ++VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_MSG_P2P_SCAN_REQUEST_T prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) NULL; ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ UINT_32 u4ChnlListSize = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) prMsgHdr; ++ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanRequest\n"); ++ ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ ASSERT(prScanReqInfo->fgIsScanRequest == FALSE); ++ ++ prScanReqInfo->fgIsAbort = TRUE; ++ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; ++ ++ /* Channel List */ ++ prScanReqInfo->ucNumChannelList = prP2pScanReqMsg->u4NumChannel; ++ DBGLOG(P2P, TRACE, "Scan Request Channel List Number: %d\n", prScanReqInfo->ucNumChannelList); ++ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) { ++ DBGLOG(P2P, TRACE, "Channel List Number Overloaded: %d, change to: %d\n", ++ prScanReqInfo->ucNumChannelList, MAXIMUM_OPERATION_CHANNEL_LIST); ++ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; ++ } ++ ++ u4ChnlListSize = sizeof(RF_CHANNEL_INFO_T) * prScanReqInfo->ucNumChannelList; ++ kalMemCopy(prScanReqInfo->arScanChannelList, prP2pScanReqMsg->arChannelListInfo, u4ChnlListSize); ++ ++ /* TODO: I only take the first SSID. Multiple SSID may be needed in the future. */ ++ /* SSID */ ++ if (prP2pScanReqMsg->i4SsidNum >= 1) ++ kalMemCopy(&(prScanReqInfo->rSsidStruct), prP2pScanReqMsg->prSSID, sizeof(P2P_SSID_STRUCT_T)); ++ else ++ prScanReqInfo->rSsidStruct.ucSsidLen = 0; ++ ++ /* IE Buffer */ ++ kalMemCopy(prScanReqInfo->aucIEBuf, prP2pScanReqMsg->pucIEBuf, prP2pScanReqMsg->u4IELen); ++ ++ prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventScanRequest */ ++ ++VOID p2pFsmRunEventScanAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanAbort\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ prScanReqInfo->fgIsAbort = TRUE; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventScanAbort */ ++ ++VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventAbort\n"); ++ ++ if (prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { ++ ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { ++ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ prScanReqInfo->fgIsAbort = TRUE; ++ } else if (prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL) { ++ /* 2012/08/06: frog ++ * Prevent Start GO. ++ */ ++ prP2pBssInfo->eIntendOPMode = OP_MODE_NUM; ++ } ++ /* For other state, is there any special action that should be take before leaving? */ ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } else { ++ /* P2P State IDLE. */ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ if (prChnlReqInfo->fgIsChannelRequested) ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFsmRunEventAbort */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle FSM Timeout. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) ulParam; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ DBGLOG(P2P, TRACE, "P2P FSM Timeout Event\n"); ++ ++ switch (prP2pFsmInfo->eCurrentState) { ++ case P2P_STATE_IDLE: ++ { ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ if (prChnlReqInfo->fgIsChannelRequested) { ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ } else if (IS_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { ++ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } ++ break; ++ ++/* case P2P_STATE_SCAN: */ ++/* break; */ ++/* case P2P_STATE_AP_CHANNEL_DETECT: */ ++/* break; */ ++/* case P2P_STATE_REQING_CHANNEL: */ ++/* break; */ ++ case P2P_STATE_CHNL_ON_HAND: ++ switch (prP2pFsmInfo->eListenExted) { ++ case P2P_DEV_NOT_EXT_LISTEN: ++ case P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT: ++ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", ++ prP2pFsmInfo->eListenExted); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; ++ break; ++ case P2P_DEV_EXT_LISTEN_ING: ++ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", ++ prP2pFsmInfo->eListenExted); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_CHNL_ON_HAND); ++ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT; ++ break; ++ default: ++ ASSERT(FALSE); ++ DBGLOG(P2P, ERROR, ++ "Current P2P State %d is unexpected for FSM timeout event.\n", ++ prP2pFsmInfo->eCurrentState); ++ } ++ break; ++/* case P2P_STATE_GC_JOIN: */ ++/* break; */ ++ default: ++ break; ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFsmRunEventFsmTimeout */ ++ ++VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_MSG_P2P_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventMgmtFrameTx\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) prMsgHdr; ++ ++ p2pFuncTxMgmtFrame(prAdapter, ++ &prP2pFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventMgmtTx */ ++ ++VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventStartAP\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) prMsgHdr; ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (prP2pStartAPMsg->u4BcnInterval) { ++ DBGLOG(P2P, TRACE, "Beacon interval updated to :%u\n", prP2pStartAPMsg->u4BcnInterval); ++ prP2pBssInfo->u2BeaconInterval = (UINT_16) prP2pStartAPMsg->u4BcnInterval; ++ } else if (prP2pBssInfo->u2BeaconInterval == 0) { ++ prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT; ++ } ++ ++ if (prP2pStartAPMsg->u4DtimPeriod) { ++ DBGLOG(P2P, TRACE, "DTIM interval updated to :%u\n", prP2pStartAPMsg->u4DtimPeriod); ++ prP2pBssInfo->ucDTIMPeriod = (UINT_8) prP2pStartAPMsg->u4DtimPeriod; ++ } else if (prP2pBssInfo->ucDTIMPeriod == 0) { ++ prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; ++ } ++ ++ if (prP2pStartAPMsg->u2SsidLen != 0) { ++ kalMemCopy(prP2pBssInfo->aucSSID, prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen); ++ kalMemCopy(prP2pSpecificBssInfo->aucGroupSsid, prP2pStartAPMsg->aucSsid, ++ prP2pStartAPMsg->u2SsidLen); ++ prP2pBssInfo->ucSSIDLen = prP2pSpecificBssInfo->u2GroupSsidLen = prP2pStartAPMsg->u2SsidLen; ++ } ++ ++ prP2pBssInfo->eHiddenSsidType = prP2pStartAPMsg->ucHiddenSsidType; ++ ++ /* TODO: JB */ ++ /* Privacy & inactive timeout. */ ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { ++ UINT_8 ucPreferedChnl = 0; ++ ENUM_BAND_T eBand = BAND_NULL; ++ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; ++ ENUM_P2P_STATE_T eNextState = P2P_STATE_SCAN; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prP2pFsmInfo->eCurrentState != P2P_STATE_SCAN && ++ prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ } ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; ++ DBGLOG(P2P, INFO, ++ "NFC:p2pFsmRunEventStartAP,fgIsGOInitialDone[%d]\n", ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); ++ ++ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ ++ /* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ /* Leave IDLE state. */ ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* sync with firmware */ ++ /* DBGLOG(P2P, INFO, ("Activate P2P Network.\n")); */ ++ /* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ /* Key to trigger P2P FSM to allocate channel for AP mode. */ ++ prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT; ++ ++ /* Sparse Channel to decide which channel to use. */ ++ if ((cnmPreferredChannel(prAdapter, ++ &eBand, ++ &ucPreferedChnl, ++ &eSco) == FALSE) && (prP2pConnSettings->ucOperatingChnl == 0)) { ++ /* Sparse Channel Detection using passive mode. */ ++ eNextState = P2P_STATE_AP_CHANNEL_DETECT; ++ } else { ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = ++ prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++#if 1 ++ /* 2012-01-27: frog - Channel set from upper layer is the first priority. */ ++ /* Because the channel & beacon is decided by p2p_supplicant. */ ++ if (prP2pConnSettings->ucOperatingChnl != 0) { ++ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; ++ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; ++ } ++ ++ else { ++ ASSERT(ucPreferedChnl != 0); ++ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; ++ prP2pSpecificBssInfo->eRfBand = eBand; ++ } ++#else ++ if (ucPreferedChnl) { ++ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; ++ prP2pSpecificBssInfo->eRfBand = eBand; ++ } else { ++ ASSERT(prP2pConnSettings->ucOperatingChnl != 0); ++ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; ++ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; ++ } ++ ++#endif ++ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel; ++ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; ++ ++ DBGLOG(P2P, INFO, "p2pFsmRunEventStartAP GO Scan\n"); ++ } ++ ++ /* If channel is specified, use active scan to shorten the scan time. */ ++ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, eNextState); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventStartAP */ ++ ++VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_P2P_NETDEV_REGISTER_T prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) NULL; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventNetDeviceRegister\n"); ++ ++ prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) prMsgHdr; ++ ++ if (prNetDevRegisterMsg->fgIsEnable) { ++ p2pSetMode((prNetDevRegisterMsg->ucMode == 1) ? TRUE : FALSE); ++ ++ if (p2pLaunch(prAdapter->prGlueInfo)) ++ ASSERT(prAdapter->fgIsP2PRegistered); ++ ++ } else { ++ if (prAdapter->fgIsP2PRegistered) ++ p2pRemove(prAdapter->prGlueInfo); ++ ++ } ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventNetDeviceRegister */ ++ ++VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_P2P_MGMT_FRAME_UPDATE_T prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventUpdateMgmtFrame\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) prMsgHdr; ++ ++ switch (prP2pMgmtFrameUpdateMsg->eBufferType) { ++ case ENUM_FRAME_TYPE_EXTRA_IE_BEACON: ++ break; ++ case ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP: ++ break; ++ case ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP: ++ break; ++ case ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE: ++ break; ++ case ENUM_FRAME_TYPE_BEACON_TEMPLATE: ++ break; ++ default: ++ break; ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventUpdateMgmtFrame */ ++ ++VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_BEACON_UPDATE_T prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconUpdate\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) prMsgHdr; ++ ++ p2pFuncBeaconUpdate(prAdapter, ++ prP2pBssInfo, ++ &prP2pFsmInfo->rBcnContentInfo, ++ prBcnUpdateMsg->pucBcnHdr, ++ prBcnUpdateMsg->u4BcnHdrLen, ++ prBcnUpdateMsg->pucBcnBody, prBcnUpdateMsg->u4BcnBodyLen); ++ ++ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && ++ (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { ++ /* AP is created, Beacon Update. */ ++ /* nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventBeaconUpdate */ ++ ++VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventStopAP\n"); ++ ++ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ && (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { ++ /* AP is created, Beacon Update. */ ++ ++ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); ++ ++ DBGLOG(P2P, TRACE, "Stop Beaconing\n"); ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Reset RLM related field of BSSINFO. */ ++ rlmBssAborted(prAdapter, prP2pBssInfo); ++ } ++ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ ++ /* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ /* Enter IDLE state. */ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ DBGLOG(P2P, INFO, "Re activate P2P Network.\n"); ++ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++#if CFG_SUPPORT_WFD ++ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); ++#endif ++ ++ /* p2pFsmRunEventAbort(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo); */ ++ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventStopAP */ ++ ++VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) prMsgHdr; ++ ++ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionRequest\n"); ++ ++ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ break; ++ ++ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Make sure the state is in IDLE state. */ ++ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); ++ ++ /* Update connection request information. */ ++ prConnReqInfo->fgIsConnRequest = TRUE; ++ COPY_MAC_ADDR(prConnReqInfo->aucBssid, prConnReqMsg->aucBssid); ++ kalMemCopy(&(prConnReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); ++ kalMemCopy(prConnReqInfo->aucIEBuf, prConnReqMsg->aucIEBuf, prConnReqMsg->u4IELen); ++ prConnReqInfo->u4BufLength = prConnReqMsg->u4IELen; ++ ++ /* Find BSS Descriptor first. */ ++ prP2pFsmInfo->prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); ++ ++ if (prP2pFsmInfo->prTargetBss == NULL) { ++ /* Update scan parameter... to scan target device. */ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest,Trigger New Scan\n"); ++ ++ prScanReqInfo->ucNumChannelList = 1; ++ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; ++ prScanReqInfo->arScanChannelList[0].ucChannelNum = prConnReqMsg->rChannelInfo.ucChannelNum; ++ kalMemCopy(&(prScanReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); ++ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ ++ prScanReqInfo->fgIsAbort = TRUE; ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); ++ } else { ++ prChnlReqInfo->u8Cookie = 0; ++ prChnlReqInfo->ucReqChnlNum = prConnReqMsg->rChannelInfo.ucChannelNum; ++ prChnlReqInfo->eBand = prConnReqMsg->rChannelInfo.eBand; ++ prChnlReqInfo->eChnlSco = prConnReqMsg->eChnlSco; ++ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; ++ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest, Report the Connecting BSS Again.\n"); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_REQING_CHANNEL); ++ } ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventConnectionRequest */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to handle Connection Request from Supplicant. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ /* P_STA_RECORD_T prTargetStaRec = (P_STA_RECORD_T)NULL; */ ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionAbort: Connection Abort.\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) prMsgHdr; ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ { ++ UINT_8 aucBCBSSID[] = BC_BSSID; ++ ++ if (!prP2pBssInfo->prStaRecOfAP) { ++ DBGLOG(P2P, TRACE, "GO's StaRec is NULL\n"); ++ break; ++ } ++ if (UNEQUAL_MAC_ADDR(prP2pBssInfo->prStaRecOfAP->aucMacAddr, prDisconnMsg->aucTargetID) ++ && UNEQUAL_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCBSSID)) { ++ DBGLOG(P2P, TRACE, ++ "Unequal MAC ADDR [ %pM : %pM ]\n", ++ prP2pBssInfo->prStaRecOfAP->aucMacAddr, ++ prDisconnMsg->aucTargetID); ++ break; ++ } ++ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, NULL, 0, 0, ++ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); ++ ++ /* Stop rejoin timer if it is started. */ ++ /* TODO: If it has. */ ++ ++ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, prDisconnMsg->fgSendDeauth, ++ prDisconnMsg->u2ReasonCode); ++ ++ /* prTargetStaRec = prP2pBssInfo->prStaRecOfAP; */ ++ ++ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). */ ++ /* hit prStaRecOfAP == NULL. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } ++ break; ++ case OP_MODE_ACCESS_POINT: ++ { ++ P_LINK_T prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ /* Search specific client device, and disconnect. */ ++ /* 1. Send deauthentication frame. */ ++ /* 2. Indication: Device disconnect. */ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; ++ ++ DBGLOG(P2P, TRACE, ++ "Disconnecting with Target ID: %pM\n", ++ prDisconnMsg->aucTargetID); ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); ++ ++ ASSERT(prCurrStaRec); ++ ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prDisconnMsg->aucTargetID)) { ++ ++ DBGLOG(P2P, TRACE, ++ "Disconnecting: %pM\n", ++ prCurrStaRec->aucMacAddr); ++ ++ /* Remove STA from client list. */ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, ++ &prCurrStaRec->rLinkEntry); ++ ++ /* Glue layer indication. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ ++ ++ /* Send deauth & do indication. */ ++ p2pFuncDisconnect(prAdapter, prCurrStaRec, prDisconnMsg->fgSendDeauth, ++ prDisconnMsg->u2ReasonCode); ++ ++ /* prTargetStaRec = prCurrStaRec; */ ++ ++ break; ++ } ++ } ++ ++ } ++ break; ++ case OP_MODE_P2P_DEVICE: ++ default: ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } while (FALSE); ++ ++ /* 20120830 moved into p2pFuncDisconnect() */ ++ /* if ((!prDisconnMsg->fgSendDeauth) && (prTargetStaRec)) { */ ++ /* cnmStaRecFree(prAdapter, prTargetStaRec, TRUE); */ ++ /* } */ ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventConnectionAbort */ ++ ++VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ ++ /* TODO: */ ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventDissolve\n"); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++WLAN_STATUS ++p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ DBGLOG(P2P, INFO, "Deauth TX Done Status: %d, seqNo %d\n", ++ rTxDoneStatus, prMsduInfo->ucTxSeqNum); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (prStaRec == NULL) { ++ DBGLOG(P2P, TRACE, "Station Record NULL, Index:%d\n", prMsduInfo->ucStaRecIndex); ++ break; ++ } ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ eOriMediaStatus = prP2pBssInfo->eConnectionState; ++ /* Change station state. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* Reset Station Record Status. */ ++ p2pFuncResetStaRecStatus(prAdapter, prStaRec); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ ++ /**/ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { ++ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ } ++ ++ /* Because the eConnectionState is changed before Deauth TxDone. Dont Check eConnectionState */ ++ /* if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { */ ++ /* Update Disconnected state to FW. */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ /* } */ ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* p2pFsmRunEventDeauthTxDone */ ++ ++WLAN_STATUS ++p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_P2P_MGMT_TX_REQ_INFO_T) NULL; ++ BOOLEAN fgIsSuccess = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prMgmtTxReqInfo = &(prP2pFsmInfo->rMgmtTxInfo); ++ ++ if (rTxDoneStatus != TX_RESULT_SUCCESS) { ++ DBGLOG(P2P, INFO, "Mgmt Frame TX Fail, Status: %d, seq NO. %d, Cookie: 0x%llx\n", ++ rTxDoneStatus, prMsduInfo->ucTxSeqNum, prMgmtTxReqInfo->u8Cookie); ++ } else { ++ fgIsSuccess = TRUE; ++ DBGLOG(P2P, TRACE, "Mgmt Frame TX Done.\n"); ++ } ++ ++ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { ++ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ fgIsSuccess, ++ prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); ++ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ } ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* p2pFsmRunEventMgmtFrameTxDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called when JOIN complete message event is received from SAA. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; ++ P_MSG_JOIN_COMP_T prJoinCompMsg = (P_MSG_JOIN_COMP_T) NULL; ++ P_SW_RFB_T prAssocRspSwRfb = (P_SW_RFB_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ DBGLOG(P2P, TRACE, "P2P Join Complete\n"); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ if (prP2pFsmInfo == NULL) { ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); ++ if (prMsgHdr == NULL) ++ return; ++ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; ++ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ prStaRec = prJoinCompMsg->prStaRec; ++ ++ /* Check SEQ NUM */ ++ if (prJoinCompMsg->ucSeqNum == prJoinInfo->ucSeqNumOfReqMsg) { ++ ASSERT(prStaRec == prJoinInfo->prTargetStaRec); ++ prJoinInfo->fgIsJoinComplete = TRUE; ++ ++ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { ++ ++ /* 4 <1.1> Change FW's Media State immediately. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ ++ if ((prP2pBssInfo->prStaRecOfAP) && (prP2pBssInfo->prStaRecOfAP != prStaRec)) { ++ cnmStaRecChangeState(prAdapter, prP2pBssInfo->prStaRecOfAP, ++ STA_STATE_1); ++ ++ cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ } ++ /* 4 <1.3> Update BSS_INFO_T */ ++ p2pFuncUpdateBssInfoForJOIN(prAdapter, prP2pFsmInfo->prTargetBss, prStaRec, ++ prAssocRspSwRfb); ++ ++ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ DBGLOG(P2P, INFO, "P2P GC Join Success\n"); ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ /* <1.5> Update RSSI if necessary */ ++ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, ++ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); ++#endif ++ ++ /* 4 <1.6> Indicate Connected Event to Host immediately. */ ++ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ ++ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, */ ++ /* prStaRec->aucMacAddr); */ ++ if (prP2pFsmInfo->prTargetBss) ++ scanReportBss2Cfg80211(prAdapter, OP_MODE_P2P_DEVICE, ++ prP2pFsmInfo->prTargetBss); ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ &prP2pFsmInfo->rConnReqInfo, ++ prJoinInfo->aucIEBuf, prJoinInfo->u4BufLength, ++ prStaRec->u2StatusCode, ++ WLAN_STATUS_MEDIA_CONNECT); ++ ++ } else { ++ /* Join Fail */ ++ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ ++ if (p2pFuncRetryJOIN(prAdapter, prStaRec, prJoinInfo) == FALSE) { ++ P_BSS_DESC_T prBssDesc; ++ ++ /* Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ prBssDesc = prP2pFsmInfo->prTargetBss; ++ ++ ASSERT(prBssDesc); ++ ASSERT(prBssDesc->fgIsConnecting); ++ ++ prBssDesc->fgIsConnecting = FALSE; ++ ++ if (prStaRec->ucJoinFailureCount >= 3) { ++ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ &prP2pFsmInfo->rConnReqInfo, ++ prJoinInfo->aucIEBuf, ++ prJoinInfo->u4BufLength, ++ prStaRec->u2StatusCode, ++ WLAN_STATUS_MEDIA_CONNECT); ++ } else { ++ /* Sometime the GO is not ready to response auth. */ ++ /* Connect it again */ ++ prP2pFsmInfo->prTargetBss = NULL; ++ } ++ DBGLOG(P2P, INFO, "P2P GC Join Failed\n"); ++ ++ } ++ ++ } ++ } ++ } ++ ++ if (prAssocRspSwRfb) ++ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); ++ ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_GC_JOIN) { ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == ++ PARAM_MEDIA_STATE_CONNECTED) { ++ /* Return to IDLE state. */ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } else { ++ /* p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); */ ++ /* one more scan */ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); ++ } ++ } ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} /* p2pFsmRunEventJoinComplete */ ++ ++VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) prMsgHdr; ++ ++ p2pFuncMgmtFrameRegister(prAdapter, ++ prMgmtFrameRegister->u2FrameType, ++ prMgmtFrameRegister->fgIsRegister, &prP2pFsmInfo->u4P2pPacketFilter); ++ ++ } while (FALSE); ++ ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ return; ++ ++} /* p2pFsmRunEventMgmtFrameRegister */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is call when RX deauthentication frame from the AIR. ++* If we are under STA mode, we would go back to P2P Device. ++* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ UINT_16 u2ReasonCode = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ if (prStaRec == NULL) ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ if (!prStaRec) ++ break; ++ ++ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ break; ++ ++ DBGLOG(P2P, TRACE, "RX Deauth\n"); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ if (authProcessRxDeauthFrame(prSwRfb, ++ prStaRec->aucMacAddr, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; ++ UINT_16 u2IELength = 0; ++ ++ if (prP2pBssInfo->prStaRecOfAP != prStaRec) ++ break; ++ ++ prStaRec->u2ReasonCode = u2ReasonCode; ++ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); ++ ++ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); ++ ++ /* Indicate disconnect to Host. */ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, ++ prDeauthFrame->aucInfoElem, u2IELength, u2ReasonCode, ++ WLAN_STATUS_MEDIA_DISCONNECT); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ DBGLOG(P2P, INFO, "GC RX Deauth Reason: %d\n", u2ReasonCode); ++ ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ } ++ break; ++ case OP_MODE_ACCESS_POINT: ++ /* Delete client from client list. */ ++ if (authProcessRxDeauthFrame(prSwRfb, ++ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; ++ ++ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); ++ ++ ASSERT(prCurrStaRec); ++ ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { ++ ++ /* Remove STA from client list. */ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, ++ &prCurrStaRec->rLinkEntry); ++ ++ /* Indicate to Host. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ ++ ++ /* Indicate disconnect to Host. */ ++ DBGLOG(P2P, INFO, "GO RX Deauth Reason: %d\n", u2ReasonCode); ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); ++ ++ break; ++ } ++ } ++ } ++ break; ++ case OP_MODE_P2P_DEVICE: ++ default: ++ /* Findout why someone sent deauthentication frame to us. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "Deauth Reason:%d\n", u2ReasonCode); ++ ++ } while (FALSE); ++} /* p2pFsmRunEventRxDeauthentication */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is call when RX deauthentication frame from the AIR. ++* If we are under STA mode, we would go back to P2P Device. ++* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ UINT_16 u2ReasonCode = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo == NULL) ++ break; ++ ++ if (prStaRec == NULL) { ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if (prStaRec == NULL) ++ break; ++ } ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ break; ++ ++ DBGLOG(P2P, TRACE, "RX Disassoc\n"); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ if (assocProcessRxDisassocFrame(prAdapter, ++ prSwRfb, ++ prStaRec->aucMacAddr, ++ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; ++ UINT_16 u2IELength = 0; ++ ++ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); ++ ++ if (prP2pBssInfo->prStaRecOfAP != prStaRec) ++ break; ++ ++ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); ++ ++ /* Indicate disconnect to Host. */ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, ++ prDisassocFrame->aucInfoElem, ++ u2IELength, prStaRec->u2ReasonCode, ++ WLAN_STATUS_MEDIA_DISCONNECT); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ DBGLOG(P2P, INFO, "GC RX Disassoc Reason %d\n", prStaRec->u2ReasonCode); ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, prStaRec->u2ReasonCode); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } ++ break; ++ case OP_MODE_ACCESS_POINT: ++ /* Delete client from client list. */ ++ if (assocProcessRxDisassocFrame(prAdapter, ++ prSwRfb, ++ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; ++ ++ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); ++ ++ ASSERT(prCurrStaRec); ++ ++ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { ++ ++ /* Remove STA from client list. */ ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, ++ &prCurrStaRec->rLinkEntry); ++ ++ /* Indicate to Host. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ ++ ++ /* Indicate disconnect to Host. */ ++ DBGLOG(P2P, INFO, "GO RX Disassoc Reason %d\n", u2ReasonCode); ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); ++ ++ break; ++ } ++ } ++ } ++ break; ++ case OP_MODE_P2P_DEVICE: ++ default: ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } while (FALSE); ++} /* p2pFsmRunEventRxDisassociation */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called when a probe request frame is received. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return boolean value if probe response frame is accepted & need cancel scan request. ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (prBssDesc != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ /* There is a connection request. */ ++ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; ++ ++ } while (FALSE); ++ ++} /* p2pFsmRunEventRxProbeResponseFrame */ ++ ++VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconTimeout: Beacon Timeout\n"); ++ ++ /* Only client mode would have beacon lost event. */ ++ ASSERT(prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE); ++ ++ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* Indicate disconnect to Host. */ ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, NULL, 0, REASON_CODE_DISASSOC_INACTIVITY, ++ WLAN_STATUS_MEDIA_DISCONNECT); ++ ++ if (prP2pBssInfo->prStaRecOfAP != NULL) { ++ P_STA_RECORD_T prStaRec = prP2pBssInfo->prStaRecOfAP; ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_DISASSOC_LEAVING_BSS); ++ ++ /* 20120830 moved into p2pFuncDisconnect() */ ++ /* cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); ++ ++ } ++ } ++ } while (FALSE); ++ ++} /* p2pFsmRunEventBeaconTimeout */ ++ ++VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = NULL; ++ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prExtListenMsg = NULL; ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); ++ ++ prExtListenMsg = (struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *) prMsgHdr; ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ASSERT_BREAK(prP2pFsmInfo); ++ ++ if (!prExtListenMsg->wait) { ++ DBGLOG(P2P, INFO, "reset listen interval\n"); ++ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ if (prP2pFsmInfo && (prP2pFsmInfo->eListenExted == P2P_DEV_NOT_EXT_LISTEN)) { ++ DBGLOG(P2P, INFO, "try to ext listen, p2p state: %d\n", prP2pFsmInfo->eCurrentState); ++ if (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) { ++ DBGLOG(P2P, INFO, "here to ext listen interval\n"); ++ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_ING; ++ } ++ } ++ if (prMsgHdr) ++ cnmMemFree(prAdapter, prMsgHdr); ++} /* p2pFsmRunEventUpdateMgmtFrame */ ++ ++#if CFG_SUPPORT_WFD ++VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; ++ WLAN_STATUS rStatus; ++ ++ DBGLOG(P2P, INFO, "p2pFsmRunEventWfdSettingUpdate\n"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL)); ++ ++ if (prMsgHdr != NULL) { ++ prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) prMsgHdr; ++ prWfdCfgSettings = prMsgWfdCfgSettings->prWfdCfgSettings; ++ } else { ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ } ++ ++ DBGLOG(P2P, INFO, "WFD Enalbe %x info %x state %x flag %x adv %x\n", ++ prWfdCfgSettings->ucWfdEnable, ++ prWfdCfgSettings->u2WfdDevInfo, ++ (UINT_32) prWfdCfgSettings->u4WfdState, ++ (UINT_32) prWfdCfgSettings->u4WfdFlag, ++ (UINT_32) prWfdCfgSettings->u4WfdAdvancedFlag); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_WFD_CTRL, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(WFD_CFG_SETTINGS_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prWfdCfgSettings, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ } while (FALSE); ++ ++ return; ++ ++} ++ ++/* p2pFsmRunEventWfdSettingUpdate */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Beacon frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (prStaRec != NULL) { ++ if (IS_STA_P2P_TYPE(prStaRec)) { ++ /* Do nothing */ ++ /* TODO: */ ++ } ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* end of p2pGenerateP2P_IEForAssocReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Probe Request frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ ASSERT(prAdapter); ++ ASSERT(pucBuf); ++ ++ /* TODO: */ ++ ++ return; ++ ++} /* end of p2pGenerateP2P_IEForProbReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to calculate P2P IE length for Beacon frame. ++* ++* @param[in] eNetTypeIndex Specify which network ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return The length of P2P IE added ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ++p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ /* TODO: */ ++ ++ return 0; ++ ++} /* end of p2pCalculateP2P_IELenForProbeReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Tx Fail of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); ++ ++ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_UNSPECIFIED); ++ ++ /* 20120830 moved into p2puUncDisconnect. */ ++ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ ++ ++} /* p2pRunEventAAATxFail */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Successful Completion of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ENUM_PARAM_MEDIA_STATE_T eOriMediaState; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ eOriMediaState = prP2pBssInfo->eConnectionState; ++ ++ if (prStaRec != NULL) ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ else ++ break; ++ ++ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || ++ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { ++ rStatus = WLAN_STATUS_RESOURCES; ++ break; ++ } ++ ++ bssAddStaRecToClientList(prAdapter, prP2pBssInfo, prStaRec); ++ ++ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); ++ ++ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || ++ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { ++ rStatus = WLAN_STATUS_RESOURCES; ++ break; ++ } ++ DBGLOG(P2P, INFO, "P2P GO Join Complete\n"); ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); ++ ++ /* Update Connected state to FW. */ ++ if (eOriMediaState != prP2pBssInfo->eConnectionState) ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ } while (FALSE); ++ ++ return rStatus; ++} /* p2pRunEventAAAComplete */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will indicate the Event of Successful Completion of AAA Module. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ /* Glue layer indication. */ ++ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, TRUE); ++ ++ } while (FALSE); ++ ++ return rStatus; ++} /* p2pRunEventAAASuccess */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_P2P_PUBLIC_ACTION_FRAME_T prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prAdapter); ++ ++ prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) prSwRfb->pvHeader; ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ DBGLOG(P2P, TRACE, "RX Public Action Frame Token:%d.\n", prPublicActionFrame->ucDialogToken); ++ ++ if (prPublicActionFrame->ucCategory != CATEGORY_PUBLIC_ACTION) ++ return rWlanStatus; ++ ++ switch (prPublicActionFrame->ucAction) { ++ case ACTION_PUBLIC_WIFI_DIRECT: ++ break; ++ case ACTION_GAS_INITIAL_REQUEST: ++ case ACTION_GAS_INITIAL_RESPONSE: ++ case ACTION_GAS_COMEBACK_REQUEST: ++ case ACTION_GAS_COMEBACK_RESPONSE: ++ break; ++ default: ++ break; ++ } ++ ++ return rWlanStatus; ++} /* p2pRxPublicActionFrame */ ++ ++WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_P2P_ACTION_FRAME_T prP2pActionFrame = (P_P2P_ACTION_FRAME_T) NULL; ++ UINT_8 aucOui[3] = VENDOR_OUI_WFA_SPECIFIC; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prP2pActionFrame = (P_P2P_ACTION_FRAME_T) prSwRfb->pvHeader; ++ ++ if (prP2pActionFrame->ucCategory != CATEGORY_VENDOR_SPECIFIC_ACTION) { ++ DBGLOG(P2P, TRACE, "RX Action Frame but not vendor specific.\n"); ++ break; ++ } ++ ++ if ((prP2pActionFrame->ucOuiType != VENDOR_OUI_TYPE_P2P) || ++ (prP2pActionFrame->aucOui[0] != aucOui[0]) || ++ (prP2pActionFrame->aucOui[1] != aucOui[1]) || (prP2pActionFrame->aucOui[2] != aucOui[2])) { ++ DBGLOG(P2P, TRACE, "RX Vendor Specific Action Frame but not P2P Type or not WFA OUI.\n"); ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pRxActionFrame */ ++ ++VOID ++p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, ++ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam) ++{ ++ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ UINT_32 i; ++ BOOLEAN fgNoaAttrExisted = FALSE; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIndex]); ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ prP2pSpecificBssInfo->fgEnableOppPS = prEventUpdateNoaParam->fgEnableOppPS; ++ prP2pSpecificBssInfo->u2CTWindow = prEventUpdateNoaParam->u2CTWindow; ++ prP2pSpecificBssInfo->ucNoAIndex = prEventUpdateNoaParam->ucNoAIndex; ++ prP2pSpecificBssInfo->ucNoATimingCount = prEventUpdateNoaParam->ucNoATimingCount; ++ ++ fgNoaAttrExisted |= prP2pSpecificBssInfo->fgEnableOppPS; ++ ++ DBGLOG(P2P, INFO, "Update NoA Count=%d.\n", prEventUpdateNoaParam->ucNoATimingCount); ++ ++ ASSERT(prP2pSpecificBssInfo->ucNoATimingCount <= P2P_MAXIMUM_NOA_COUNT); ++ ++ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { ++ /* in used */ ++ prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse = prEventUpdateNoaParam->arEventNoaTiming[i].fgIsInUse; ++ /* count */ ++ prP2pSpecificBssInfo->arNoATiming[i].ucCount = prEventUpdateNoaParam->arEventNoaTiming[i].ucCount; ++ /* duration */ ++ prP2pSpecificBssInfo->arNoATiming[i].u4Duration = prEventUpdateNoaParam->arEventNoaTiming[i].u4Duration; ++ /* interval */ ++ prP2pSpecificBssInfo->arNoATiming[i].u4Interval = prEventUpdateNoaParam->arEventNoaTiming[i].u4Interval; ++ /* start time */ ++ prP2pSpecificBssInfo->arNoATiming[i].u4StartTime = ++ prEventUpdateNoaParam->arEventNoaTiming[i].u4StartTime; ++ ++ fgNoaAttrExisted |= prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse; ++ } ++ ++ prP2pSpecificBssInfo->fgIsNoaAttrExisted = fgNoaAttrExisted; ++ ++ /* update beacon content by the change */ ++ bssUpdateBeaconContent(prAdapter, ucNetTypeIndex); ++} ++ ++#endif /* CFG_ENABLE_WIFI_DIRECT */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c +new file mode 100644 +index 000000000000..586a74721b3b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c +@@ -0,0 +1,3796 @@ ++#include "precomp.h" ++#include ++ ++#ifdef __GNUC__ ++#pragma GCC diagnostic ignored "-Wformat" ++#endif ++ ++APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = { ++ {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS), NULL, p2pFuncAppendAttriStatusForAssocRsp} /* 0 */ ++ , {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING), NULL, p2pFuncAppendAttriExtListenTiming} /* 8 */ ++}; ++ ++APPEND_VAR_IE_ENTRY_T txProbeRspIETable[] = { ++ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE} /* 50 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} /* 42 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} /* 45 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} /* 61 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} /* 48 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} /* 74 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} /* 127 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE} /* 221 */ ++ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Function for requesting scan. There is an option to do ACTIVE or PASSIVE scan. ++* ++* @param eScanType - Specify the scan type of the scan request. It can be an ACTIVE/PASSIVE ++* Scan. ++* eChannelSet - Specify the preferred channel set. ++* A FULL scan would request a legacy full channel normal scan.(usually ACTIVE). ++* A P2P_SOCIAL scan would scan 1+6+11 channels.(usually ACTIVE) ++* A SPECIFIC scan would only 1/6/11 channels scan. (Passive Listen/Specific Search) ++* ucChannelNum - A specific channel number. (Only when channel is specified) ++* eBand - A specific band. (Only when channel is specified) ++* ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) ++{ ++ ++ P_MSG_SCN_SCAN_REQ prScanReq = (P_MSG_SCN_SCAN_REQ) NULL; ++ /*NFC Beam + Indication */ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ BOOLEAN fgIsPureAP = FALSE; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; ++ ++ DEBUGFUNC("p2pFuncRequestScan()"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL)); ++ ++ if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) { ++ ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0); ++ DBGLOG(P2P, LOUD, ++ "P2P Scan Request Channel:%d\n", prScanReqInfo->arScanChannelList[0].ucChannelNum); ++ } ++ ++ prScanReq = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); ++ if (!prScanReq) { ++ ASSERT(0); /* Can't trigger SCAN FSM */ ++ break; ++ } ++ ++ prScanReq->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_REQ; ++ prScanReq->ucSeqNum = ++prScanReqInfo->ucSeqNumOfScnMsg; ++ prScanReq->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; ++ prScanReq->eScanType = prScanReqInfo->eScanType; ++ prScanReq->eScanChannel = prScanReqInfo->eChannelSet; ++ prScanReq->u2IELen = 0; ++ ++ /* Copy IE for Probe Request. */ ++ if (prScanReqInfo->u4BufLength > MAX_IE_LENGTH) ++ prScanReqInfo->u4BufLength = MAX_IE_LENGTH; ++ kalMemCopy(prScanReq->aucIE, prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength); ++ prScanReq->u2IELen = (UINT_16) prScanReqInfo->u4BufLength; ++ ++ prScanReq->u2ChannelDwellTime = prScanReqInfo->u2PassiveDewellTime; ++ ++ switch (prScanReqInfo->eChannelSet) { ++ case SCAN_CHANNEL_SPECIFIED: ++ { ++ UINT_32 u4Idx = 0; ++ P_RF_CHANNEL_INFO_T prDomainInfo = ++ (P_RF_CHANNEL_INFO_T) prScanReqInfo->arScanChannelList; ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ ++ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) ++ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; ++ ++ for (u4Idx = 0; u4Idx < prScanReqInfo->ucNumChannelList; u4Idx++) { ++ prScanReq->arChnlInfoList[u4Idx].ucChannelNum = prDomainInfo->ucChannelNum; ++ prScanReq->arChnlInfoList[u4Idx].eBand = prDomainInfo->eBand; ++ prDomainInfo++; ++ } ++ ++ prScanReq->ucChannelListNum = prScanReqInfo->ucNumChannelList; ++ ++ /*NFC Beam + Indication */ ++ prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; ++ if (prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_GO_START_BSS && ++ prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && ++ !fgIsPureAP) { ++ prScanReq->ucChannelListNum = 1; ++ prScanReq->arChnlInfoList[0].ucChannelNum = prChnlReqInfo->ucReqChnlNum; ++ prScanReq->arChnlInfoList[0].eBand = prChnlReqInfo->eBand; ++ ++ DBGLOG(P2P, INFO, ++ "NFC:GO Skip Scan and Only Froce on %s[%d]\n", ++ prChnlReqInfo->eBand == 1 ? "2.4G" : "5G", ++ prChnlReqInfo->ucReqChnlNum); ++ } ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ ++ } ++ break; ++ ++ case SCAN_CHANNEL_FULL: ++ { ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ } ++ break; ++ ++ case SCAN_CHANNEL_2G4: ++ { ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ } ++ break; ++ ++ case SCAN_CHANNEL_P2P_SOCIAL: ++ { ++ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; ++ ++ COPY_SSID(prScanReq->aucSSID, ++ prScanReq->ucSSIDLength, ++ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); ++ ++ /* For compatible. */ ++ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, ++ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; ++ } else if (prScanReq->ucSSIDLength != 0) { ++ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; ++ } ++ } ++ break; ++ default: ++ /* Currently there is no other scan channel set. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReq, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++} /* p2pFuncRequestScan */ ++ ++VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanInfo) ++{ ++ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prScanInfo != NULL)); ++ ++ if (!prScanInfo->fgIsScanRequest) ++ break; ++ ++ if (prScanInfo->ucSeqNumOfScnMsg) { ++ /* There is a channel privilege on hand. */ ++ DBGLOG(P2P, TRACE, "P2P Cancel Scan\n"); ++ ++ prScanCancelMsg = ++ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); ++ if (!prScanCancelMsg) { ++ /* Buffer not enough, can not cancel scan request. */ ++ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; ++ prScanCancelMsg->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prScanCancelMsg->ucSeqNum = prScanInfo->ucSeqNumOfScnMsg++; ++ prScanCancelMsg->fgIsChannelExt = FALSE; ++ prScanInfo->fgIsScanRequest = FALSE; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFuncCancelScan */ ++ ++VOID ++p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW) ++{ ++ if (!prAdapter) ++ return; ++ if (!prAdapter->prGlueInfo) ++ return; ++ if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT) ++ return; ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (eOpMode < OP_MODE_NUM)); ++ ++ if (prP2pBssInfo->eCurrentOPMode != eOpMode) { ++ DBGLOG(P2P, TRACE, ++ "p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", prP2pBssInfo->eCurrentOPMode, ++ eOpMode); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_ACCESS_POINT: ++ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); ++ ++ p2pFsmRunEventStopAP(prAdapter, NULL); ++ break; ++ default: ++ break; ++ } ++ ++ prP2pBssInfo->eIntendOPMode = eOpMode; ++ prP2pBssInfo->eCurrentOPMode = eOpMode; ++ switch (eOpMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to Client.\n"); ++ case OP_MODE_ACCESS_POINT: ++/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ ++/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* } */ ++ ++ /* Change interface address. */ ++ if (eOpMode == OP_MODE_ACCESS_POINT) { ++ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to AP.\n"); ++ prP2pBssInfo->ucSSIDLen = 0; ++ } ++ ++ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucInterfaceAddress); ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucInterfaceAddress); ++ ++ break; ++ case OP_MODE_P2P_DEVICE: ++ { ++ /* Change device address. */ ++ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch back to P2P Device.\n"); ++ ++/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ ++/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* } */ ++ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, ++ prAdapter->rWifiVar.aucDeviceAddress); ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); ++ ++ } ++ break; ++ default: ++/* if (IS_BSS_ACTIVE(prP2pBssInfo)) { */ ++/* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++/* nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++/* } */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ if (1) { ++ P2P_DISCONNECT_INFO rP2PDisInfo; ++ ++ rP2PDisInfo.ucRole = 2; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_P2P_ABORT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(P2P_DISCONNECT_INFO), (PUINT_8)&rP2PDisInfo, NULL, 0); ++ } ++ ++ DBGLOG(P2P, TRACE, ++ "The device address is changed to %pM\n", ++ prP2pBssInfo->aucOwnMacAddr); ++ DBGLOG(P2P, TRACE, "The BSSID is changed to %pM\n", prP2pBssInfo->aucBSSID); ++ ++ /* Update BSS INFO to FW. */ ++ if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFuncSwitchOPMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will start a P2P Group Owner and send Beacon Frames. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncStartGO(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, ++ IN PUINT_8 pucSsidBuf, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP) ++{ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL)); ++ ++ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); ++ ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 1; ++ DBGLOG(P2P, INFO, ++ "p2pFuncStartGO:NFC Done[%d]\n", ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); ++ /* AP mode started. */ ++ p2pFuncSwitchOPMode(prAdapter, prBssInfo, prBssInfo->eIntendOPMode, FALSE); ++ ++ prBssInfo->eIntendOPMode = OP_MODE_NUM; ++ ++ /* 4 <1.1> Assign SSID */ ++ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, pucSsidBuf, ucSsidLen); ++ ++ DBGLOG(P2P, TRACE, "GO SSID:%s\n", prBssInfo->aucSSID); ++ ++ /* 4 <1.2> Clear current AP's STA_RECORD_T and current AID */ ++ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ prBssInfo->u2AssocId = 0; ++ ++ /* 4 <1.3> Setup Channel, Band and Phy Attributes */ ++ prBssInfo->ucPrimaryChannel = ucChannelNum; ++ prBssInfo->eBand = eBand; ++ prBssInfo->eBssSCO = eSco; ++ ++ DBGLOG(P2P, TRACE, "GO Channel:%d\n", ucChannelNum); ++ ++ if (prBssInfo->eBand == BAND_5G) { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN); ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; ++ } else if (fgIsPureAP) { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN); ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; ++ } else { ++ /* Depend on eBand */ ++ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN); ++ /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; ++ } ++ ++ prBssInfo->ucNonHTBasicPhyType = (UINT_8) ++ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; ++ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; ++ prBssInfo->u2OperationalRateSet = ++ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; ++ ++ if (prBssInfo->ucAllSupportedRatesLen == 0) { ++ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, ++ prBssInfo->u2BSSBasicRateSet, ++ prBssInfo->aucAllSupportedRates, ++ &prBssInfo->ucAllSupportedRatesLen); ++ } ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prBssInfo->u2ATIMWindow = 0; ++ prBssInfo->ucBeaconTimeoutCount = 0; ++ ++ /* 3 <2> Update BSS_INFO_T common part */ ++#if CFG_SUPPORT_AAA ++ if (!fgIsPureAP) { ++ prBssInfo->fgIsProtection = TRUE; /* Always enable protection at P2P GO */ ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); ++ } else { ++ if (kalP2PGetCipher(prAdapter->prGlueInfo)) ++ prBssInfo->fgIsProtection = TRUE; ++ } ++ ++ /* 20120106 frog: I want separate OP_Mode & Beacon TX Function. */ ++ /* p2pFuncSwitchOPMode(prAdapter, prBssInfo, OP_MODE_ACCESS_POINT, FALSE); */ ++ ++ bssInitForAP(prAdapter, prBssInfo, FALSE); ++ ++ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_P2P_INDEX); ++#endif /* CFG_SUPPORT_AAA */ ++ ++ /* 3 <3> Set MAC HW */ ++ /* 4 <3.1> Setup channel and bandwidth */ ++ rlmBssInitForAPandIbss(prAdapter, prBssInfo); ++ ++ /* 4 <3.2> Reset HW TSF Update Mode and Beacon Mode */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* 4 <3.3> Update Beacon again for network phy type confirmed. */ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++#if 0 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ ++ { ++ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; ++ ++ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; ++ arHotspotOptimizationCfg.u4Level = (0x3) << 8 | 0x5; ++ wlanoidSendSetQueryP2PCmd(prAdapter, ++ CMD_ID_SET_HOTSPOT_OPTIMIZATION, ++ TRUE, ++ FALSE, ++ TRUE, ++ NULL, ++ NULL, ++ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), ++ (PUINT_8)&arHotspotOptimizationCfg, NULL, 0); ++ } ++#endif ++ ++ /* 4 <3.4> Setup BSSID */ ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ } while (FALSE); ++ ++} /* p2pFuncStartGO() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to inform CNM that channel privilege ++* has been released ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) ++{ ++ P_MSG_CH_ABORT_T prMsgChRelease = (P_MSG_CH_ABORT_T) NULL; ++ ++ DEBUGFUNC("p2pFuncReleaseCh()"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); ++ ++ if (!prChnlReqInfo->fgIsChannelRequested) ++ break; ++ ++ DBGLOG(P2P, TRACE, "P2P Release Channel\n"); ++ prChnlReqInfo->fgIsChannelRequested = FALSE; ++ ++ /* 1. return channel privilege to CNM immediately */ ++ prMsgChRelease = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); ++ if (!prMsgChRelease) { ++ ASSERT(0); /* Can't release Channel to CNM */ ++ break; ++ } ++ ++ prMsgChRelease->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; ++ prMsgChRelease->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prMsgChRelease->ucTokenID = prChnlReqInfo->ucSeqNumOfChReq++; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChRelease, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++} /* p2pFuncReleaseCh */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) ++{ ++ P_MSG_CH_REQ_T prMsgChReq = (P_MSG_CH_REQ_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); ++ ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ ++ /* send message to CNM for acquiring channel */ ++ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); ++ ++ if (!prMsgChReq) { ++ ASSERT(0); /* Can't indicate CNM for channel acquiring */ ++ break; ++ } ++ ++ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; ++ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ prMsgChReq->ucTokenID = ++prChnlReqInfo->ucSeqNumOfChReq; ++ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; ++ if (prChnlReqInfo->u4MaxInterval < P2P_EXT_LISTEN_TIME_MS) ++ prMsgChReq->u4MaxInterval = P2P_EXT_LISTEN_TIME_MS; ++ else ++ prMsgChReq->u4MaxInterval = prChnlReqInfo->u4MaxInterval; ++ ++ prMsgChReq->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; ++ prMsgChReq->eRfSco = prChnlReqInfo->eChnlSco; ++ prMsgChReq->eRfBand = prChnlReqInfo->eBand; ++ ++ kalMemZero(prMsgChReq->aucBSSID, MAC_ADDR_LEN); ++ ++ /* Channel request join BSSID. */ ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); ++ ++ prChnlReqInfo->fgIsChannelRequested = TRUE; ++ ++ } while (FALSE); ++ ++} /* p2pFuncAcquireCh */ ++ ++#if 0 ++WLAN_STATUS ++p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBcnHdr, ++ IN UINT_32 u4HdrLen, ++ IN PUINT_8 pucBcnBody, IN UINT_32 u4BodyLen, IN UINT_32 u4DtimPeriod, IN UINT_32 u4BcnInterval) ++{ ++ WLAN_STATUS rResultStatus = WLAN_STATUS_INVALID_DATA; ++ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; ++ PUINT_8 pucTIMBody = (PUINT_8) NULL; ++ UINT_16 u2FrameLength = 0, UINT_16 u2OldBodyLen = 0; ++ UINT_8 aucIEBuf[MAX_IE_LENGTH]; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prBcnMsduInfo = prP2pBssInfo->prBeacon ASSERT_BREAK(prBcnMsduInfo != NULL); ++ ++ /* TODO: Find TIM IE pointer. */ ++ prBcnFrame = prBcnMsduInfo->prPacket; ++ ++ ASSERT_BREAK(prBcnFrame != NULL); ++ ++ do { ++ /* Ori header. */ ++ UINT_16 u2IELength = 0, u2Offset = 0; ++ PUINT_8 pucIEBuf = prBcnFrame->aucInfoElem; ++ ++ u2IELength = prBcnMsduInfo->u2FrameLength - prBcnMsduInfo->ucMacHeaderLength; ++ ++ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { ++ if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) || ((IE_ID(pucIEBuf) > ELEM_ID_IBSS_PARAM_SET))) { ++ pucTIMBody = pucIEBuf; ++ break; ++ } ++ u2FrameLength += IE_SIZE(pucIEBuf); ++ } ++ ++ if (pucTIMBody == NULL) ++ pucTIMBody = pucIEBuf; ++ ++ /* Body not change. */ ++ u2OldBodyLen = (UINT_16) ((UINT_32) pucTIMBody - (UINT_32) prBcnFrame->aucInfoElem); ++ /* Move body. */ ++ kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen); ++ } while (FALSE); ++ ++ if (pucBcnHdr) { ++ kalMemCopy(prBcnMsduInfo->prPacket, pucBcnHdr, u4HdrLen); ++ pucTIMBody = (PUINT_8) ((UINT_32) prBcnMsduInfo->prPacket + u4HdrLen); ++ prBcnMsduInfo->ucMacHeaderLength = (WLAN_MAC_MGMT_HEADER_LEN + ++ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); ++ u2FrameLength = u4HdrLen; /* Header + Partial Body. */ ++ } else { ++ /* Header not change. */ ++ u2FrameLength += prBcnMsduInfo->ucMacHeaderLength; ++ } ++ ++ if (pucBcnBody) { ++ kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen); ++ u2FrameLength += (UINT_16) u4BodyLen; ++ } else { ++ kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen); ++ u2FrameLength += u2OldBodyLen; ++ } ++ ++ /* Frame Length */ ++ prBcnMsduInfo->u2FrameLength = u2FrameLength; ++ prBcnMsduInfo->fgIs802_11 = TRUE; ++ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ prP2pBssInfo->u2BeaconInterval = (UINT_16) u4BcnInterval; ++ prP2pBssInfo->ucDTIMPeriod = (UINT_8) u4DtimPeriod; ++ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; ++ prBcnMsduInfo->ucPacketType = 3; ++ rResultStatus = nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ NETWORK_TYPE_P2P_INDEX, ++ prP2pBssInfo->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ prBcnMsduInfo->u2FrameLength - ++ OFFSET_OF(WLAN_BEACON_FRAME_T, ++ aucInfoElem)); ++ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ /* AP is created, Beacon Update. */ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } while (FALSE); ++ return rResultStatus; ++} /* p2pFuncBeaconUpdate */ ++ ++#else ++WLAN_STATUS ++ p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, ++ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, ++ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen) ++{ ++WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; ++PUINT_8 pucIEBuf = (PUINT_8) NULL; ++PUINT_8 paucIEBuf = (PUINT_8) NULL;/*[MAX_IE_LENGTH]; aucIEBuf*/ ++ ++do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (prBcnUpdateInfo != NULL)); ++ ++ prBcnMsduInfo = prP2pBssInfo->prBeacon; ++ ++#if DBG ++ if (prBcnUpdateInfo->pucBcnHdr != NULL) { ++ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnHdr == ++ ((UINT_32) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD)); ++ } ++ ++ if (prBcnUpdateInfo->pucBcnBody != NULL) { ++ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnBody == ++ ((UINT_32) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen)); ++ } ++#endif ++ prBcnFrame = (P_WLAN_BEACON_FRAME_T) ((ULONG) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD); ++ ++ if (!pucNewBcnBody) { ++ /* Old body. */ ++ pucNewBcnBody = prBcnUpdateInfo->pucBcnBody; ++ ASSERT(u4NewBodyLen == 0); ++ u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen; ++ } else { ++ prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen; ++ } ++ ++ paucIEBuf = kalMemAlloc(MAX_IE_LENGTH, VIR_MEM_TYPE); ++ if (paucIEBuf == NULL) { ++ DBGLOG(P2P, TRACE, "p2p alloc paucIEBuf fail\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Temp buffer body part. */ ++ kalMemCopy(paucIEBuf, pucNewBcnBody, u4NewBodyLen); ++ ++ if (pucNewBcnHdr) { ++ kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen); ++ prBcnUpdateInfo->pucBcnHdr = (PUINT_8) prBcnFrame; ++ prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen; ++ } ++ ++ pucIEBuf = (PUINT_8) ((ULONG) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen); ++ kalMemCopy(pucIEBuf, paucIEBuf, u4NewBodyLen); ++ kalMemFree(paucIEBuf, VIR_MEM_TYPE, MAX_IE_LENGTH); ++ prBcnUpdateInfo->pucBcnBody = pucIEBuf; ++ ++ /* Frame Length */ ++ prBcnMsduInfo->u2FrameLength = (UINT_16) (prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen); ++ ++ prBcnMsduInfo->ucPacketType = 3; ++ prBcnMsduInfo->fgIs802_11 = TRUE; ++ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ ++ /* Update BSS INFO related information. */ ++ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr); ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID); ++ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; ++ ++ p2pFuncParseBeaconContent(prAdapter, ++ prP2pBssInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); ++ ++#if 1 ++ /* bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++#else ++ nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ NETWORK_TYPE_P2P_INDEX, ++ prBcnFrame->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); ++#endif ++} while (FALSE); ++ ++return rWlanStatus; ++} /* p2pFuncBeaconUpdate */ ++ ++#endif ++ ++/* TODO: We do not apply IE in deauth frame set from upper layer now. */ ++WLAN_STATUS ++p2pFuncDeauth(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucPeerMacAddr, ++ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDeauth) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; ++ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ BOOLEAN fgIsStaFound = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_ACCESS_POINT: ++ { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); ++ fgIsStaFound = TRUE; ++ break; ++ } ++ } ++ ++ } ++ break; ++ case OP_MODE_INFRASTRUCTURE: ++ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); ++ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) ++ break; ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ fgIsStaFound = TRUE; ++ break; ++ default: ++ break; ++ } ++ ++ if (fgIsStaFound) ++ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDeauth, u2ReasonCode); ++ ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncDeauth */ ++ ++/* TODO: We do not apply IE in disassoc frame set from upper layer now. */ ++WLAN_STATUS ++p2pFuncDisassoc(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucPeerMacAddr, ++ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDisassoc) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; ++ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ BOOLEAN fgIsStaFound = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_ACCESS_POINT: ++ { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); ++ ++ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { ++ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { ++ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); ++ fgIsStaFound = TRUE; ++ /* p2pFuncDisconnect(prAdapter, prCliStaRec, ++ * fgSendDisassoc, u2ReasonCode); */ ++ break; ++ } ++ } ++ ++ } ++ break; ++ case OP_MODE_INFRASTRUCTURE: ++ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); ++ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) ++ break; ++ /* p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); */ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ fgIsStaFound = TRUE; ++ break; ++ default: ++ break; ++ } ++ ++ if (fgIsStaFound) { ++ ++ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); ++ /* 20120830 moved into p2pFuncDisconnect(). */ ++ /* cnmStaRecFree(prAdapter, prCliStaRec, TRUE); */ ++ ++ } ++ ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncDisassoc */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) ++* 1. GC: Disconnect from AP. (Send Deauth) ++* 2. GO: Disconnect all STA ++* ++* @param[in] prAdapter Pointer to the adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncDissolve(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) ++{ ++ DEBUGFUNC("p2pFuncDissolve()"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); ++ ++ switch (prP2pBssInfo->eCurrentOPMode) { ++ case OP_MODE_INFRASTRUCTURE: ++ /* Reset station record status. */ ++ if (prP2pBssInfo->prStaRecOfAP) { ++ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, ++ NULL, NULL, 0, REASON_CODE_DEAUTH_LEAVING_BSS, ++ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); ++ ++ /* 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL. */ ++ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, fgSendDeauth, u2ReasonCode); ++ } ++ ++ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). ++ * hit prStaRecOfAP == NULL. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ prP2pBssInfo->prStaRecOfAP = NULL; ++ ++ break; ++ case OP_MODE_ACCESS_POINT: ++ /* Under AP mode, we would net send deauthentication frame to each STA. ++ * We only stop the Beacon & let all stations timeout. ++ */ ++ { ++ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; ++ ++ /* Send deauth. */ ++ authSendDeauthFrame(prAdapter, ++ NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL); ++ ++ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; ++ ++ while (!LINK_IS_EMPTY(prStaRecOfClientList)) { ++ P_STA_RECORD_T prCurrStaRec; ++ ++ LINK_REMOVE_HEAD(prStaRecOfClientList, prCurrStaRec, P_STA_RECORD_T); ++ ++ /* Indicate to Host. */ ++ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ ++ ++ p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode); ++ ++ } ++ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; ++ } ++ ++ break; ++ default: ++ return; /* 20110420 -- alreay in Device Mode. */ ++ } ++ ++ /* Make the deauth frame send to FW ASAP. */ ++ wlanAcquirePowerControl(prAdapter); ++ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); ++ wlanReleasePowerControl(prAdapter); ++ ++ kalMdelay(100); ++ ++ /* Change Connection Status. */ ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ ++ } while (FALSE); ++ ++} /* p2pFuncDissolve */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) ++* 1. GC: Disconnect from AP. (Send Deauth) ++* 2. GO: Disconnect all STA ++* ++* @param[in] prAdapter Pointer to the adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ eOriMediaStatus = prP2pBssInfo->eConnectionState; ++ ++ /* Indicate disconnect. */ ++ /* TODO: */ ++ /* kalP2PGOStationUpdate */ ++ /* kalP2PGCIndicateConnectionStatus */ ++ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, prStaRec->aucMacAddr); */ ++ DBGLOG(P2P, INFO, "p2pFuncDisconnect, eCurrentOPMode: %d, sendDeauth: %s\n", ++ prP2pBssInfo->eCurrentOPMode, fgSendDeauth ? "True" : "False"); ++ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); ++ ++ if (fgSendDeauth) { ++ /* Send deauth. */ ++ authSendDeauthFrame(prAdapter, ++ prStaRec, ++ (P_SW_RFB_T) NULL, ++ u2ReasonCode, (PFN_TX_DONE_HANDLER) p2pFsmRunEventDeauthTxDone); ++ } else { ++ /* Change station state. */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* Reset Station Record Status. */ ++ p2pFuncResetStaRecStatus(prAdapter, prStaRec); ++ ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { ++ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); ++ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); ++ } ++ ++ if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { ++ /* Update Disconnected state to FW. */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ } ++ ++ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { ++ /* GO: It would stop Beacon TX. GC: Stop all BSS related PS function. */ ++ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* Reset RLM related field of BSSINFO. */ ++ rlmBssAborted(prAdapter, prP2pBssInfo); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pFuncDisconnect */ ++ ++/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ ++#define WLAN_ACTION_SPECTRUM_MGMT 0 ++#define WLAN_ACTION_QOS 1 ++#define WLAN_ACTION_DLS 2 ++#define WLAN_ACTION_BLOCK_ACK 3 ++#define WLAN_ACTION_PUBLIC 4 ++#define WLAN_ACTION_RADIO_MEASUREMENT 5 ++#define WLAN_ACTION_FT 6 ++#define WLAN_ACTION_HT 7 ++#define WLAN_ACTION_SA_QUERY 8 ++#define WLAN_ACTION_PROTECTED_DUAL 9 ++#define WLAN_ACTION_WNM 10 ++#define WLAN_ACTION_UNPROTECTED_WNM 11 ++#define WLAN_ACTION_TDLS 12 ++#define WLAN_ACTION_SELF_PROTECTED 15 ++#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ ++#define WLAN_ACTION_VENDOR_SPECIFIC 127 ++ ++/* Public action codes */ ++#define WLAN_PA_20_40_BSS_COEX 0 ++#define WLAN_PA_VENDOR_SPECIFIC 9 ++#define WLAN_PA_GAS_INITIAL_REQ 10 ++#define WLAN_PA_GAS_INITIAL_RESP 11 ++#define WLAN_PA_GAS_COMEBACK_REQ 12 ++#define WLAN_PA_GAS_COMEBACK_RESP 13 ++#define WLAN_TDLS_DISCOVERY_RESPONSE 14 ++ ++/* P2P public action frames */ ++enum p2p_action_frame_type { ++ P2P_GO_NEG_REQ = 0, ++ P2P_GO_NEG_RESP = 1, ++ P2P_GO_NEG_CONF = 2, ++ P2P_INVITATION_REQ = 3, ++ P2P_INVITATION_RESP = 4, ++ P2P_DEV_DISC_REQ = 5, ++ P2P_DEV_DISC_RESP = 6, ++ P2P_PROV_DISC_REQ = 7, ++ P2P_PROV_DISC_RESP = 8 ++}; ++ ++const char *p2p_to_string(enum p2p_action_frame_type p2p_action) ++{ ++ switch (p2p_action) { ++ case P2P_GO_NEG_REQ: ++ return "GO_NEG_REQ"; ++ case P2P_GO_NEG_RESP: ++ return "GO_NEG_RESP"; ++ case P2P_GO_NEG_CONF: ++ return "GO_NEG_CONF"; ++ case P2P_INVITATION_REQ: ++ return "INVITATION_REQ"; ++ case P2P_INVITATION_RESP: ++ return "INVITATION_RESP"; ++ case P2P_DEV_DISC_REQ: ++ return "DEV_DISC_REQ"; ++ case P2P_DEV_DISC_RESP: ++ return "DEV_DISC_RESP"; ++ case P2P_PROV_DISC_REQ: ++ return "PROV_DISC_REQ"; ++ case P2P_PROV_DISC_RESP: ++ return "PROV_DISC_RESP"; ++ } ++ ++ return "UNKNOWN P2P Public Action"; ++} ++const char *pa_to_string(int pa_action) ++{ ++ switch (pa_action) { ++ case WLAN_PA_20_40_BSS_COEX: ++ return "PA_20_40_BSS_COEX"; ++ case WLAN_PA_VENDOR_SPECIFIC: ++ return "PA_VENDOR_SPECIFIC"; ++ case WLAN_PA_GAS_INITIAL_REQ: ++ return "PA_GAS_INITIAL_REQ"; ++ case WLAN_PA_GAS_INITIAL_RESP: ++ return "PA_GAS_INITIAL_RESP"; ++ case WLAN_PA_GAS_COMEBACK_REQ: ++ return "PA_GAS_COMEBACK_REQ"; ++ case WLAN_PA_GAS_COMEBACK_RESP: ++ return "PA_GAS_COMEBACK_RESP"; ++ case WLAN_TDLS_DISCOVERY_RESPONSE: ++ return "TDLS_DISCOVERY_RESPONSE"; ++ } ++ ++ return "UNKNOWN Public Action"; ++} ++ ++const char *action_to_string(int wlan_action) ++{ ++ switch (wlan_action) { ++ case WLAN_ACTION_SPECTRUM_MGMT: ++ return "SPECTRUM_MGMT"; ++ case WLAN_ACTION_QOS: ++ return "QOS"; ++ case WLAN_ACTION_DLS: ++ return "DLS"; ++ case WLAN_ACTION_BLOCK_ACK: ++ return "BLOCK_ACK"; ++ case WLAN_ACTION_PUBLIC: ++ return "PUBLIC"; ++ case WLAN_ACTION_RADIO_MEASUREMENT: ++ return "RADIO_MEASUREMENT"; ++ case WLAN_ACTION_FT: ++ return "FT"; ++ case WLAN_ACTION_HT: ++ return "HT"; ++ case WLAN_ACTION_SA_QUERY: ++ return "SA_QUERY"; ++ case WLAN_ACTION_PROTECTED_DUAL: ++ return "PROTECTED_DUAL"; ++ case WLAN_ACTION_WNM: ++ return "WNM"; ++ case WLAN_ACTION_UNPROTECTED_WNM: ++ return "UNPROTECTED_WNM"; ++ case WLAN_ACTION_TDLS: ++ return "TDLS"; ++ case WLAN_ACTION_SELF_PROTECTED: ++ return "SELF_PROTECTED"; ++ case WLAN_ACTION_WMM: ++ return "WMM"; ++ case WLAN_ACTION_VENDOR_SPECIFIC: ++ return "VENDOR_SPECIFIC"; ++ } ++ ++ return "UNKNOWN Action Frame"; ++} ++ ++VOID p2pFuncTagActionActionP2PFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, ++ IN P_WLAN_ACTION_FRAME prActFrame, ++ IN UINT_8 ucP2pAction, IN UINT_64 u8Cookie) ++{ ++ DBGLOG(P2P, INFO, "Found P2P_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNO: %d\n", ++ p2p_to_string(ucP2pAction), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++} ++ ++VOID p2pFuncTagActionActionFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, ++ IN P_WLAN_ACTION_FRAME prActFrame, ++ IN UINT_8 ucAction, IN UINT_64 u8Cookie) ++{ ++ PUINT_8 pucVendor = NULL; ++ ++ DBGLOG(P2P, INFO, "Found WLAN_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNo: %d\n", ++ pa_to_string(ucAction), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++ ++ if (ucAction == WLAN_PA_VENDOR_SPECIFIC) { ++ pucVendor = (PUINT_8)prActFrame + 26; ++ if (*(pucVendor + 0) == 0x50 && ++ *(pucVendor + 1) == 0x6f && ++ *(pucVendor + 2) == 0x9a) { ++ if (*(pucVendor + 3) == 0x09) ++ /* found p2p IE */ ++ p2pFuncTagActionActionP2PFrame(prMgmtTxMsdu, ++ prActFrame, *(pucVendor + 4), u8Cookie); ++ else if (*(pucVendor + 3) == 0x0a) ++ /* found WFD IE */ ++ DBGLOG(P2P, INFO, "Found WFD IE, SA: %pM - DA: %pM\n", ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr); ++ else ++ DBGLOG(P2P, INFO, "Found Other vendor 0x%x, SA: %pM - DA: %pM\n", ++ *(pucVendor + 3), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr); ++ } ++ } ++} ++ ++VOID p2pFuncTagActionCategoryFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, ++ P_WLAN_ACTION_FRAME prActFrame, ++ IN UINT_8 ucCategory, ++ IN UINT_64 u8Cookie) ++{ ++ ++ UINT_8 ucAction = 0; ++ ++ DBGLOG(P2P, INFO, "Found WLAN_ACTION_%s, SA: %pM - DA: %pM, u8Cookie: 0x%llx, SeqNO: %d\n", ++ action_to_string(ucCategory), ++ prActFrame->aucSrcAddr, ++ prActFrame->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++ ++ if (ucCategory == WLAN_ACTION_PUBLIC) { ++ ucAction = prActFrame->ucAction; ++ p2pFuncTagActionActionFrame(prMgmtTxMsdu, prActFrame, ucAction, u8Cookie); ++ ++ } ++} ++ ++/* ++ * used to debug p2p mgmt frame: ++ * GO Nego Req ++ * GO Nego Res ++ * GO Nego Confirm ++ * GO Invite Req ++ * GO Invite Res ++ * Device Discoverability Req ++ * Device Discoverability Res ++ * Provision Discovery Req ++ * Provision Discovery Res ++ */ ++ ++VOID ++p2pFuncTagMgmtFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) ++{ ++ /* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */ ++ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; ++ P_WLAN_PROBE_RSP_FRAME_T prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T)NULL; ++ UINT_16 u2TxFrameCtrl; ++ P_WLAN_ACTION_FRAME prActFrame; ++ UINT_8 ucCategory; ++ ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ /* ++ * mgmt frame MASK_FC_TYPE = 0 ++ * use MASK_FRAME_TYPE is oK for frame type/subtype judge ++ */ ++ u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; ++ ++ switch (u2TxFrameCtrl) { ++ case MAC_FRAME_PROBE_RSP: ++ ++ prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T) prWlanHdr; ++ DBGLOG(P2P, INFO, "TX Probe Response Frame, SA: %pM - DA: %pM, cookie: 0x%llx, seqNo: %d\n", ++ prProbRspHdr->aucSrcAddr, prProbRspHdr->aucDestAddr, ++ u8Cookie, ++ prMgmtTxMsdu->ucTxSeqNum); ++ ++ break; ++ ++ case MAC_FRAME_ACTION: ++ ++ prActFrame = (P_WLAN_ACTION_FRAME)prWlanHdr; ++ ucCategory = prActFrame->ucCategory; ++ p2pFuncTagActionCategoryFrame(prMgmtTxMsdu, prActFrame, ++ ucCategory, u8Cookie); ++ ++ break; ++ default: ++ DBGLOG(P2P, INFO, "MGMT:, un-tagged frame type: 0x%x, A1: %pM, A2: %pM, A3: %pM seqNo: %d\n", ++ u2TxFrameCtrl, ++ prWlanHdr->aucAddr1, ++ prWlanHdr->aucAddr2, ++ prWlanHdr->aucAddr3, ++ prMgmtTxMsdu->ucTxSeqNum); ++ break; ++ } ++} ++ ++WLAN_STATUS ++p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ BOOLEAN fgIsProbrsp = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); ++ ++ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { ++ ++ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ ++ /* Packet on driver, not done yet, drop it. */ ++ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; ++ if (prTxMsduInfo != NULL) { ++ ++ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, ++ prMgmtTxReqInfo->u8Cookie, ++ FALSE, ++ prTxMsduInfo->prPacket, ++ (UINT_32) prTxMsduInfo->u2FrameLength); ++ ++ /* Leave it to TX Done handler. */ ++ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ ++ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; ++ DBGLOG(P2P, INFO, "p2pFuncTxMgmtFrame: Drop MGMT cookie: 0x%llx\n", ++ prMgmtTxReqInfo->u8Cookie); ++ } ++ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ ++ /* Packet transmitted, wait tx done. (cookie issue) */ ++ /* 20120105 frog - use another u8cookie to store this value. */ ++ } ++ ++ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); ++ ++ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, prWlanHdr->aucAddr1); ++ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_P2P_INDEX; ++ ++ switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) { ++ case MAC_FRAME_PROBE_RSP: ++ DBGLOG(P2P, TRACE, "p2pFuncTxMgmtFrame: TX MAC_FRAME_PROBE_RSP\n"); ++ fgIsProbrsp = TRUE; ++ prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, prMgmtTxMsdu); ++ break; ++ default: ++ break; ++ } ++ ++ prMgmtTxReqInfo->u8Cookie = u8Cookie; ++ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; ++ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; ++ ++ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; ++ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); ++ if (prStaRec != NULL) ++ DBGLOG(P2P, TRACE, "Mgmt with station record: %pM.\n", prStaRec->aucMacAddr); ++ ++ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ ++ prMgmtTxMsdu->fgIs802_1x = FALSE; ++ prMgmtTxMsdu->fgIs802_11 = TRUE; ++ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMgmtTxMsdu->pfTxDoneHandler = p2pFsmRunEventMgmtFrameTxDone; ++ prMgmtTxMsdu->fgIsBasicRate = TRUE; ++ ++ p2pFuncTagMgmtFrame(prMgmtTxMsdu, u8Cookie); ++ ++ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncTxMgmtFrame */ ++ ++VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL)); ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ prP2pConnSettings->ucOperatingChnl = prRfChannelInfo->ucChannelNum; ++ prP2pConnSettings->eBand = prRfChannelInfo->eBand; ++ ++ } while (FALSE); ++ ++} ++ ++/* p2pFuncSetChannel */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @retval TRUE We will retry JOIN ++* @retval FALSE We will not retry JOIN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo) ++{ ++ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; ++ BOOLEAN fgRetValue = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL) && (prJoinInfo != NULL)); ++ ++ /* Retry other AuthType if possible */ ++ if (!prJoinInfo->ucAvailableAuthTypes) ++ break; ++ ++ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(P2P, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else { ++ DBGLOG(P2P, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); ++ ASSERT(0); ++ break; ++ } ++ ++ prJoinInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ ++ ++ /* Trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ if (!prJoinReqMsg) { ++ ASSERT(0); /* Can't trigger SAA FSM */ ++ break; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++ fgRetValue = TRUE; ++ } while (FALSE); ++ ++ return fgRetValue; ++ ++} /* end of p2pFuncRetryJOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will update the contain of BSS_INFO_T for AIS network once ++* the association was completed. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; ++ UINT_16 u2IELength; ++ PUINT_8 pucIE; ++ ++ DEBUGFUNC("p2pUpdateBssInfoForJOIN()"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prStaRec); ++ ASSERT(prAssocRspSwRfb); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; ++ ++ DBGLOG(P2P, INFO, "Update P2P_BSS_INFO_T and apply settings to MAC\n"); ++ ++ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ ++ /* 4 <1.1> Setup Operation Mode */ ++ prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; ++ ++ /* 4 <1.2> Setup SSID */ ++ COPY_SSID(prP2pBssInfo->aucSSID, ++ prP2pBssInfo->ucSSIDLen, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); ++ ++ if (prBssDesc == NULL) { ++ /* Target BSS NULL. */ ++ DBGLOG(P2P, TRACE, "Target BSS NULL\n"); ++ return; ++ } ++ ++ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAssocRspFrame->aucBSSID)) ++ ASSERT(FALSE); ++ /* 4 <1.3> Setup Channel, Band */ ++ prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; ++ prP2pBssInfo->eBand = prBssDesc->eBand; ++ ++ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ ++ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ ++ prP2pBssInfo->prStaRecOfAP = prStaRec; ++ prP2pBssInfo->u2AssocId = prStaRec->u2AssocId; ++ ++ /* 4 <2.2> Setup Capability */ ++ prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ ++ ++ if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) ++ prP2pBssInfo->fgIsShortPreambleAllowed = TRUE; ++ else ++ prP2pBssInfo->fgIsShortPreambleAllowed = FALSE; ++ ++ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ ++ prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; ++ ++ prP2pBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; ++ ++ prP2pBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; ++ prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; ++ ++ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ ++ /* 4 <3.1> Setup BSSID */ ++ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); ++ ++ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - ++ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); ++ pucIE = prAssocRspFrame->aucInfoElem; ++ ++ /* 4 <3.2> Parse WMM and setup QBSS flag */ ++ /* Parse WMM related IEs and configure HW CRs accordingly */ ++ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS; ++ ++ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ ++ ASSERT(prBssDesc); ++ ++ prBssDesc->fgIsConnecting = FALSE; ++ prBssDesc->fgIsConnected = TRUE; ++ ++ /* 4 <4.1> Setup MIB for current BSS */ ++ prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ ++ prP2pBssInfo->ucDTIMPeriod = 0; ++ prP2pBssInfo->u2ATIMWindow = 0; ++ ++ prP2pBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; ++ ++ /* 4 <4.2> Update HT information and set channel */ ++ /* Record HT related parameters in rStaRec and rBssInfo ++ * Note: it shall be called before nicUpdateBss() ++ */ ++ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); ++ ++ /* 4 <4.3> Sync with firmware for BSS-INFO */ ++ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ ++ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ ++ ++} /* end of p2pUpdateBssInfoForJOIN() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Auth Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Auth ++* @retval FALSE Don't reply the Auth ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAuth = TRUE; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; ++ ++ DBGLOG(P2P, INFO, "p2pValidate Authentication Frame\n"); ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prSwRfb != NULL) && (pprStaRec != NULL) && (pu2StatusCode != NULL)); ++ ++ /* P2P 3.2.8 */ ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; ++ ++ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ++ || (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { ++ /* We are not under AP Mode yet. */ ++ fgReplyAuth = FALSE; ++ DBGLOG(P2P, WARN, ++ "Current OP mode is not under AP mode. (%d)\n", prP2pBssInfo->eCurrentOPMode); ++ break; ++ } ++ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX, prAuthFrame->aucSrcAddr); ++ ++ if (!prStaRec) { ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX); ++ ++ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for ++ * exhausted case and do removal of unused STA_RECORD_T. ++ */ ++ /* Sent a message event to clean un-used STA_RECORD_T. */ ++ ASSERT(prStaRec); ++ if (!prStaRec) { ++ DBGLOG(AAA, INFO, "Station Limit Full. Decline a new Authentication.\n"); ++ break; ++ } ++ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); ++ ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++ ++ prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet; ++ ++ prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P; ++ ++ prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P; ++ prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN; ++ prStaRec->eStaType = STA_TYPE_P2P_GC; ++ ++ /* NOTE(Kevin): Better to change state here, not at TX Done */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } else { ++ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; ++ ++ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_STA_IN_P2P(prStaRec))) { ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ p2pFuncResetStaRecStatus(prAdapter, prStaRec); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ } ++ ++ } ++ ++ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem >= P2P_MAXIMUM_CLIENT_COUNT || ++ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { ++ /* GROUP limit full. */ ++ /* P2P 3.2.8 */ ++ DBGLOG(P2P, WARN, ++ "Group Limit Full. (%d)\n", (INT_16) prP2pBssInfo->rStaRecOfClientList.u4NumElem); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); ++ ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++ fgReplyAuth = TRUE; ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD; ++ break; ++ } ++ /* Hotspot Blacklist */ ++ if (prAuthFrame->aucSrcAddr) { ++ if (kalP2PCmpBlackList(prAdapter->prGlueInfo, prAuthFrame->aucSrcAddr)) { ++ fgReplyAuth = TRUE; ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD; ++ return fgReplyAuth; ++ } ++ } ++ ++ /* prStaRec->eStaType = STA_TYPE_INFRA_CLIENT; */ ++ prStaRec->eStaType = STA_TYPE_P2P_GC; ++ ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; ++ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ prStaRec->ucJoinFailureCount = 0; ++ ++ *pprStaRec = prStaRec; ++ ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ } while (FALSE); ++ ++ return fgReplyAuth; ++ ++} /* p2pFuncValidateAuth */ ++ ++VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ do { ++ if ((prAdapter == NULL) || (prStaRec == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; ++ prStaRec->ucJoinFailureCount = 0; ++ prStaRec->fgTransmitKeyExist = FALSE; ++ ++ prStaRec->fgSetPwrMgtBit = FALSE; ++ ++ } while (FALSE); ++ ++} /* p2pFuncResetStaRecStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function is used to initialize the value of the connection settings for ++* P2P network ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings) ++{ ++ P_DEVICE_TYPE_T prDevType; ++ UINT_8 aucDefaultDevName[] = P2P_DEFAULT_DEV_NAME; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++#if CFG_SUPPORT_CFG_FILE ++ P_WIFI_VAR_T prWifiVar = NULL; ++#endif ++ ++ ASSERT(prP2PConnSettings); ++#if CFG_SUPPORT_CFG_FILE ++ prWifiVar = &(prAdapter->rWifiVar); ++ ASSERT(prWifiVar); ++#endif ++ ++ /* Setup Default Device Name */ ++ prP2PConnSettings->ucDevNameLen = P2P_DEFAULT_DEV_NAME_LEN; ++ kalMemCopy(prP2PConnSettings->aucDevName, aucDefaultDevName, sizeof(aucDefaultDevName)); ++ ++ /* Setup Primary Device Type (Big-Endian) */ ++ prDevType = &prP2PConnSettings->rPrimaryDevTypeBE; ++ ++ prDevType->u2CategoryId = HTONS(P2P_DEFAULT_PRIMARY_CATEGORY_ID); ++ prDevType->u2SubCategoryId = HTONS(P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID); ++ ++ prDevType->aucOui[0] = aucWfaOui[0]; ++ prDevType->aucOui[1] = aucWfaOui[1]; ++ prDevType->aucOui[2] = aucWfaOui[2]; ++ prDevType->aucOui[3] = VENDOR_OUI_TYPE_WPS; ++ ++ /* Setup Secondary Device Type */ ++ prP2PConnSettings->ucSecondaryDevTypeCount = 0; ++ ++ /* Setup Default Config Method */ ++ prP2PConnSettings->eConfigMethodSelType = ENUM_CONFIG_METHOD_SEL_AUTO; ++ prP2PConnSettings->u2ConfigMethodsSupport = P2P_DEFAULT_CONFIG_METHOD; ++ prP2PConnSettings->u2TargetConfigMethod = 0; ++ prP2PConnSettings->u2LocalConfigMethod = 0; ++ prP2PConnSettings->fgIsPasswordIDRdy = FALSE; ++ ++ /* For Device Capability */ ++ prP2PConnSettings->fgSupportServiceDiscovery = FALSE; ++ prP2PConnSettings->fgSupportClientDiscoverability = TRUE; ++ prP2PConnSettings->fgSupportConcurrentOperation = TRUE; ++ prP2PConnSettings->fgSupportInfraManaged = FALSE; ++ prP2PConnSettings->fgSupportInvitationProcedure = FALSE; ++ ++ /* For Group Capability */ ++#if CFG_SUPPORT_PERSISTENT_GROUP ++ prP2PConnSettings->fgSupportPersistentP2PGroup = TRUE; ++#else ++ prP2PConnSettings->fgSupportPersistentP2PGroup = FALSE; ++#endif ++ prP2PConnSettings->fgSupportIntraBSSDistribution = TRUE; ++ prP2PConnSettings->fgSupportCrossConnection = TRUE; ++ prP2PConnSettings->fgSupportPersistentReconnect = FALSE; ++ ++ prP2PConnSettings->fgSupportOppPS = FALSE; ++ prP2PConnSettings->u2CTWindow = P2P_CTWINDOW_DEFAULT; ++ ++ /* For Connection Settings. */ ++ prP2PConnSettings->eAuthMode = AUTH_MODE_OPEN; ++ ++ prP2PConnSettings->prTargetP2pDesc = NULL; ++ prP2PConnSettings->ucSSIDLen = 0; ++ ++ /* Misc */ ++ prP2PConnSettings->fgIsScanReqIssued = FALSE; ++ prP2PConnSettings->fgIsServiceDiscoverIssued = FALSE; ++ prP2PConnSettings->fgP2pGroupLimit = FALSE; ++ prP2PConnSettings->ucOperatingChnl = 0; ++ prP2PConnSettings->ucListenChnl = 0; ++ prP2PConnSettings->ucTieBreaker = (UINT_8) (kalRandomNumber() & 0x1); ++ ++ prP2PConnSettings->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; ++#if CFG_SUPPORT_CFG_FILE ++ /* prP2PConnSettings->fgIsWPSMode = prWifiVar->ucApWpsMode; */ ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = prWifiVar->ucApWpsMode; ++#endif ++} /* p2pFuncInitConnectionSettings */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Assoc Req Frame and then return ++* the status code to AAA to indicate if need to perform following actions ++* when the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu2StatusCode The Status Code of Validation Result ++* ++* @retval TRUE Reply the Assoc Resp ++* @retval FALSE Don't reply the Assoc Resp ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) ++{ ++ BOOLEAN fgReplyAssocResp = TRUE; ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_WFD_ATTRIBUTE_T prWfdAttribute = (P_WFD_ATTRIBUTE_T) NULL; ++ BOOLEAN fgNeedFree = FALSE; ++#endif ++ /* UINT_16 u2AttriListLen = 0; */ ++ UINT_16 u2WfdDevInfo = 0; ++ P_WFD_DEVICE_INFORMATION_IE_T prAttriWfdDevInfo; ++ ++ /* TODO(Kevin): Call P2P functions to check .. ++ 2. Check we can accept connection from thsi peer ++ a. If we are in PROVISION state, only accept the peer we do the GO formation previously. ++ b. If we are in OPERATION state, only accept the other peer when P2P_GROUP_LIMIT is 0. ++ 3. Check Black List here. ++ */ ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (pu2StatusCode != NULL)); ++ ++ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prStaRec == NULL) { ++ /* Station record should be ready while RX AUTH frame. */ ++ fgReplyAssocResp = FALSE; ++ ASSERT(FALSE); ++ break; ++ } ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ ++ prStaRec->u2DesiredNonHTRateSet &= prP2pBssInfo->u2OperationalRateSet; ++ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet; ++ ++ if (prStaRec->ucDesiredPhyTypeSet == 0) { ++ /* The station only support 11B rate. */ ++ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; ++ break; ++ } ++#if CFG_SUPPORT_WFD && 1 ++ /* LOG_FUNC("Skip check WFD IE because some API is not ready\n"); */ ++ if (!prAdapter->rWifiVar.prP2pFsmInfo) { ++ fgReplyAssocResp = FALSE; ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ DBGLOG(P2P, INFO, "AssocReq, wfd_en %u wfd_info 0x%x wfd_policy 0x%x wfd_flag 0x%x\n", ++ prWfdCfgSettings->ucWfdEnable, prWfdCfgSettings->u2WfdDevInfo, ++ prWfdCfgSettings->u4WfdPolicy, prWfdCfgSettings->u4WfdFlag); /* Eddie */ ++ if (prWfdCfgSettings->ucWfdEnable) { ++ if (prWfdCfgSettings->u4WfdPolicy & BIT(6)) { ++ /* Rejected all. */ ++ break; ++ } ++ ++ /* fgNeedFree = p2pFuncGetAttriList(prAdapter, */ ++ /* VENDOR_OUI_TYPE_WFD, */ ++ /* (PUINT_8)prAssocReqFrame->aucInfoElem, */ ++ /* (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), */ ++ /* (PPUINT_8)&prWfdAttribute, */ ++ /* &u2AttriListLen); */ ++ ++ prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) ++ p2pFuncGetSpecAttri(prAdapter, ++ VENDOR_OUI_TYPE_WFD, ++ (PUINT_8) prAssocReqFrame->aucInfoElem, ++ (prSwRfb->u2PacketLen - ++ OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), ++ WFD_ATTRI_ID_DEV_INFO); ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(5)) && (prAttriWfdDevInfo != NULL)) { ++ /* Rejected with WFD IE. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(0)) && (prAttriWfdDevInfo == NULL)) { ++ /* Rejected without WFD IE. */ ++ break; ++ } ++ ++ if (prAttriWfdDevInfo == NULL) { ++ /* ++ * Without WFD IE. ++ * Do nothing. Accept the connection request. ++ */ ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ break; ++ } ++ ++ /* prAttriWfdDevInfo = */ ++ /* (P_WFD_DEVICE_INFORMATION_IE_T)p2pFuncGetSpecAttri(prAdapter, */ ++ /* VENDOR_OUI_TYPE_WFD, */ ++ /* (PUINT_8)prWfdAttribute, */ ++ /* u2AttriListLen, */ ++ /* WFD_ATTRI_ID_DEV_INFO); */ ++ /* if (prAttriWfdDevInfo == NULL) { */ ++ /* No such attribute. */ ++ /* break; */ ++ /* } */ ++ ++ WLAN_GET_FIELD_BE16(&prAttriWfdDevInfo->u2WfdDevInfo, &u2WfdDevInfo); ++ DBGLOG(P2P, INFO, "RX Assoc Req WFD Info:0x%x.\n", u2WfdDevInfo); ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(1)) && ((u2WfdDevInfo & 0x3) == 0x0)) { ++ /* Rejected because of SOURCE. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(2)) && ((u2WfdDevInfo & 0x3) == 0x1)) { ++ /* Rejected because of Primary Sink. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(3)) && ((u2WfdDevInfo & 0x3) == 0x2)) { ++ /* Rejected because of Secondary Sink. */ ++ break; ++ } ++ ++ if ((prWfdCfgSettings->u4WfdPolicy & BIT(4)) && ((u2WfdDevInfo & 0x3) == 0x3)) { ++ /* Rejected because of Source & Primary Sink. */ ++ break; ++ } ++ ++ /* Check role */ ++ ++ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) && ++ ((prWfdCfgSettings->u2WfdDevInfo & BITS(0, 1)) == 0x3)) { ++ /* P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = ++ * (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T)NULL; */ ++ UINT_16 u2DevInfo = prWfdCfgSettings->u2WfdDevInfo; ++ ++ /* We may change role here if we are dual role */ ++ ++ if ((u2WfdDevInfo & BITS(0, 1)) == 0x00 /* Peer is Source */) { ++ DBGLOG(P2P, INFO, "WFD: Switch role to primary sink\n"); ++ ++ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); ++ prWfdCfgSettings->u2WfdDevInfo |= 0x1; ++ ++ /* event to annonce the role is chanaged to P-Sink */ ++ ++ } else if ((u2WfdDevInfo & BITS(0, 1)) == 0x01 /* Peer is P-Sink */) { ++ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); ++ ++ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); ++ /* event to annonce the role is chanaged to Source */ ++ } else { ++ DBGLOG(P2P, INFO, "WFD: Peer role is wrong type(dev 0x%x)\n", ++ (u2DevInfo)); ++ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); ++ ++ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); ++ /* event to annonce the role is chanaged to Source */ ++ } ++ ++ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); ++ ++ } /* Dual role p2p->wfd_params->WfdDevInfo */ ++ ++ /* WFD_FLAG_DEV_INFO_VALID */ ++ } ++ /* ucWfdEnable */ ++#endif ++ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; ++ } while (FALSE); ++ ++#if CFG_SUPPORT_WFD ++ if ((prWfdAttribute) && (fgNeedFree)) ++ kalMemFree(prWfdAttribute, VIR_MEM_TYPE, WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE); ++#endif ++ ++ return fgReplyAssocResp; ++ ++} /* p2pFuncValidateAssocReq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to check the P2P IE ++* ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType) ++{ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ P_IE_WFA_T prWfaIE = (P_IE_WFA_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pucOuiType != NULL)); ++ ++ prWfaIE = (P_IE_WFA_T) pucBuf; ++ ++ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { ++ break; ++ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || ++ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { ++ break; ++ } ++ ++ *pucOuiType = prWfaIE->ucOuiType; ++ ++ return TRUE; ++ } while (FALSE); ++ ++ return FALSE; ++} /* p2pFuncParseCheckForP2PInfoElem */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) ++{ ++ BOOLEAN fgIsReplyProbeRsp = FALSE; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("p2pFuncValidateProbeReq"); ++ DBGLOG(P2P, TRACE, "p2pFuncValidateProbeReq\n"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) { ++ ++ DBGLOG(P2P, TRACE, "report probe req to OS\n"); ++ /* Leave the probe response to p2p_supplicant. */ ++ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); ++ } ++ ++ } while (FALSE); ++ ++ return fgIsReplyProbeRsp; ++ ++} /* end of p2pFuncValidateProbeReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will validate the Rx Probe Request Frame and then return ++* result to BSS to indicate if need to send the corresponding Probe Response ++* Frame if the specified conditions were matched. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to SW RFB data structure. ++* @param[out] pu4ControlFlags Control flags for replying the Probe Response ++* ++* @retval TRUE Reply the Probe Response ++* @retval FALSE Don't reply the Probe Response ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ ++ DEBUGFUNC("p2pFuncValidateProbeReq"); ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME) { ++ /* Leave the probe response to p2p_supplicant. */ ++ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pFuncValidateRxMgmtFrame */ ++ ++BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ if (prP2pFsmInfo) { ++ if (prP2pFsmInfo->fgIsWPSMode == 1) ++ return FALSE; ++ return prP2pFsmInfo->fgIsApMode; ++ } else { ++ return FALSE; ++ } ++} ++ ++/* p2pFuncIsAPMode */ ++ ++VOID ++p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen) ++{ ++ PUINT_8 pucIE = (PUINT_8) NULL; ++ UINT_16 u2Offset = 0; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ BOOLEAN ucNewSecMode = FALSE; ++ BOOLEAN ucOldSecMode = FALSE; ++ UINT_8 ucOuiType; ++ UINT_16 u2SubTypeVersion; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); ++ ++ if (u4IELen == 0) ++ break; ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pSpecificBssInfo->u2AttributeLen = 0; ++ ++ ASSERT_BREAK(pucIEInfo != NULL); ++ ++ pucIE = pucIEInfo; ++ ++ ucOldSecMode = kalP2PGetCipher(prAdapter->prGlueInfo); ++ ++ IE_FOR_EACH(pucIE, u4IELen, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ { ++ /* 0 */ /* V */ /* Done */ ++ /* DBGLOG(P2P, TRACE, ("SSID update\n")); */ ++ /* SSID is saved when start AP/GO */ ++ /* SSID IE set in beacon from supplicant will not always be */ ++ /* the true since hidden SSID case */ ++ /* ++ COPY_SSID(prP2pBssInfo->aucSSID, ++ prP2pBssInfo->ucSSIDLen, ++ SSID_IE(pucIE)->aucSSID, ++ SSID_IE(pucIE)->ucLength); ++ ++ COPY_SSID(prP2pSpecificBssInfo->aucGroupSsid, ++ prP2pSpecificBssInfo->u2GroupSsidLen, ++ SSID_IE(pucIE)->aucSSID, ++ SSID_IE(pucIE)->ucLength); ++ */ ++ } ++ break; ++ case ELEM_ID_SUP_RATES: ++ { ++ /* 1 */ /* V */ /* Done */ ++ DBGLOG(P2P, TRACE, "Support Rate IE\n"); ++ kalMemCopy(prP2pBssInfo->aucAllSupportedRates, ++ SUP_RATES_IE(pucIE)->aucSupportedRates, ++ SUP_RATES_IE(pucIE)->ucLength); ++ ++ prP2pBssInfo->ucAllSupportedRatesLen = SUP_RATES_IE(pucIE)->ucLength; ++ ++ DBGLOG_MEM8(P2P, TRACE, SUP_RATES_IE(pucIE)->aucSupportedRates, ++ SUP_RATES_IE(pucIE)->ucLength); ++ } ++ break; ++ case ELEM_ID_DS_PARAM_SET: ++ { ++ /* 3 */ /* V */ /* Done */ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = ++ prAdapter->rWifiVar.prP2PConnSettings; ++ ++ DBGLOG(P2P, TRACE, "DS PARAM IE\n"); ++ ++ ASSERT(prP2pConnSettings->ucOperatingChnl == DS_PARAM_IE(pucIE)->ucCurrChnl); ++ ++ if (prP2pConnSettings->eBand != BAND_2G4) { ++ ASSERT(FALSE); ++ break; ++ } ++ /* prP2pBssInfo->ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; */ ++ ++ /* prP2pBssInfo->eBand = BAND_2G4; */ ++ } ++ break; ++ case ELEM_ID_TIM: /* 5 */ /* V */ ++ DBGLOG(P2P, TRACE, "TIM IE\n"); ++ TIM_IE(pucIE)->ucDTIMPeriod = prP2pBssInfo->ucDTIMPeriod; ++ break; ++ case ELEM_ID_ERP_INFO: /* 42 */ /* V */ ++ { ++#if 1 ++ /* This IE would dynamic change due to FW detection change is required. */ ++ DBGLOG(P2P, TRACE, "ERP IE will be over write by driver\n"); ++ DBGLOG(P2P, TRACE, " ucERP: %x.\n", ERP_INFO_IE(pucIE)->ucERP); ++ ++#else ++ /* This IE would dynamic change due to FW detection change is required. */ ++ DBGLOG(P2P, TRACE, "ERP IE.\n"); ++ ++ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11GN; ++ ++ ASSERT(prP2pBssInfo->eBand == BAND_2G4); ++ ++ prP2pBssInfo->fgObssErpProtectMode = ++ ((ERP_INFO_IE(pucIE)->ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE); ++ ++ prP2pBssInfo->fgErpProtectMode = ++ ((ERP_INFO_IE(pucIE)->ucERP & ++ (ERP_INFO_USE_PROTECTION | ERP_INFO_NON_ERP_PRESENT)) ? TRUE : FALSE); ++#endif ++ ++ } ++ break; ++ case ELEM_ID_HT_CAP: /* 45 */ /* V */ ++ { ++#if 1 ++ DBGLOG(P2P, TRACE, "HT CAP IE would be overwritten by driver\n"); ++ ++ DBGLOG(P2P, TRACE, ++ "HT Cap Info:%x, AMPDU Param:%x\n", HT_CAP_IE(pucIE)->u2HtCapInfo, ++ HT_CAP_IE(pucIE)->ucAmpduParam); ++ ++ DBGLOG(P2P, TRACE, ++ "HT Extended Cap Info%x,TX Beamforming Cap Info%x,Ant Selection Cap Info%x\n", ++ HT_CAP_IE(pucIE)->u2HtExtendedCap, HT_CAP_IE(pucIE)->u4TxBeamformingCap, ++ HT_CAP_IE(pucIE)->ucAselCap); ++#else ++ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ ++ /* u2HtCapInfo */ ++ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & ++ (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | ++ HT_CAP_INFO_DSSS_CCK_IN_40M)) == 0) { ++ prP2pBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } else { ++ prP2pBssInfo->fgAssoc40mBwAllowed = TRUE; ++ } ++ ++ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & ++ (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M)) == 0) { ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; ++ } else { ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = FALSE; ++ } ++ ++ /* ucAmpduParam */ ++ DBGLOG(P2P, TRACE, ++ "AMPDU setting from supplicant:0x%x, & default value:0x%x\n", ++ (UINT_8) HT_CAP_IE(pucIE)->ucAmpduParam, ++ (UINT_8) AMPDU_PARAM_DEFAULT_VAL); ++ ++ /* rSupMcsSet */ ++ /* Can do nothing. the field is default value from other configuration. */ ++ /* HT_CAP_IE(pucIE)->rSupMcsSet; */ ++ ++ /* u2HtExtendedCap */ ++ ASSERT(HT_CAP_IE(pucIE)->u2HtExtendedCap == ++ (HT_EXT_CAP_DEFAULT_VAL & ++ ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE))); ++ ++ /* u4TxBeamformingCap */ ++ ASSERT(HT_CAP_IE(pucIE)->u4TxBeamformingCap == TX_BEAMFORMING_CAP_DEFAULT_VAL); ++ ++ /* ucAselCap */ ++ ASSERT(HT_CAP_IE(pucIE)->ucAselCap == ASEL_CAP_DEFAULT_VAL); ++#endif ++ } ++ break; ++ case ELEM_ID_RSN: /* 48 */ /* V */ ++ { ++ RSN_INFO_T rRsnIe; ++ ++ DBGLOG(P2P, TRACE, "RSN IE\n"); ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); ++ ucNewSecMode = TRUE; ++ ++ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) { ++ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; ++ prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; ++ prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap; ++ } ++ } ++ break; ++ case ELEM_ID_EXTENDED_SUP_RATES: /* 50 */ /* V */ ++ /* Be attention, ++ * ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */ ++ DBGLOG(P2P, TRACE, "Ex Support Rate IE\n"); ++ kalMemCopy(&(prP2pBssInfo->aucAllSupportedRates[prP2pBssInfo->ucAllSupportedRatesLen]), ++ EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, ++ EXT_SUP_RATES_IE(pucIE)->ucLength); ++ ++ DBGLOG_MEM8(P2P, TRACE, EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, ++ EXT_SUP_RATES_IE(pucIE)->ucLength); ++ ++ prP2pBssInfo->ucAllSupportedRatesLen += EXT_SUP_RATES_IE(pucIE)->ucLength; ++ break; ++ case ELEM_ID_HT_OP: ++ { ++ /* 61 */ /* V */ /* TODO: */ ++#if 1 ++ DBGLOG(P2P, TRACE, "HT OP IE would be overwritten by driver\n"); ++ ++ DBGLOG(P2P, TRACE, ++ " Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n", ++ HT_OP_IE(pucIE)->ucPrimaryChannel, HT_OP_IE(pucIE)->ucInfo1, ++ HT_OP_IE(pucIE)->u2Info2, HT_OP_IE(pucIE)->u2Info3); ++#else ++ UINT_16 u2Info2 = 0; ++ ++ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ ++ DBGLOG(P2P, TRACE, "HT OP IE\n"); ++ ++ /* ucPrimaryChannel. */ ++ ASSERT(HT_OP_IE(pucIE)->ucPrimaryChannel == prP2pBssInfo->ucPrimaryChannel); ++ ++ /* ucInfo1 */ ++ prP2pBssInfo->ucHtOpInfo1 = HT_OP_IE(pucIE)->ucInfo1; ++ ++ /* u2Info2 */ ++ u2Info2 = HT_OP_IE(pucIE)->u2Info2; ++ ++ if (u2Info2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) { ++ ASSERT(prP2pBssInfo->eGfOperationMode != GF_MODE_NORMAL); ++ u2Info2 &= ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT; ++ } ++ ++ if (u2Info2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) { ++ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; ++ u2Info2 &= ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; ++ } ++ ++ switch (u2Info2 & HT_OP_INFO2_HT_PROTECTION) { ++ case HT_PROTECT_MODE_NON_HT: ++ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NON_HT; ++ break; ++ case HT_PROTECT_MODE_NON_MEMBER: ++ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; ++ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; ++ break; ++ default: ++ prP2pBssInfo->eHtProtectMode = HT_OP_IE(pucIE)->u2Info2; ++ break; ++ } ++ ++ /* u2Info3 */ ++ prP2pBssInfo->u2HtOpInfo3 = HT_OP_IE(pucIE)->u2Info3; ++ ++ /* aucBasicMcsSet */ ++ DBGLOG_MEM8(P2P, TRACE, HT_OP_IE(pucIE)->aucBasicMcsSet, 16); ++#endif ++ } ++ break; ++ case ELEM_ID_OBSS_SCAN_PARAMS: /* 74 */ /* V */ ++ { ++ DBGLOG(P2P, TRACE, ++ "ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n"); ++ } ++ break; ++ case ELEM_ID_EXTENDED_CAP: /* 127 */ /* V */ ++ { ++ DBGLOG(P2P, TRACE, "ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n"); ++ } ++ break; ++ case ELEM_ID_VENDOR: /* 221 */ /* V */ ++ DBGLOG(P2P, TRACE, "Vender Specific IE\n"); ++ if (rsnParseCheckForWFAInfoElem ++ (prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { ++ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) ++ && (u2SubTypeVersion == VERSION_WPA)) { ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP); ++ ucNewSecMode = TRUE; ++ kalMemCopy(prP2pSpecificBssInfo->aucWpaIeBuffer, pucIE, ++ IE_SIZE(pucIE)); ++ prP2pSpecificBssInfo->u2WpaIeLen = IE_SIZE(pucIE); ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 0, pucIE, ++ IE_SIZE(pucIE)); ++ } ++ /* WMM here. */ ++ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { ++ /* TODO Store the whole P2P IE & generate later. */ ++ /* Be aware that there may be one or more P2P IE. */ ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache ++ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, ++ IE_SIZE(pucIE)); ++ ++ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache ++ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, ++ IE_SIZE(pucIE)); ++ ++ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); ++ } ++ } else { ++ ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache ++ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, ++ IE_SIZE(pucIE)); ++ ++ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); ++ DBGLOG(P2P, TRACE, "Driver unprocessed Vender Specific IE\n"); ++ ASSERT(FALSE); ++ } ++ ++ /* TODO: Store other Vender IE except for WMM Param. */ ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Unprocessed element ID:%d\n", IE_ID(pucIE)); ++ break; ++ } ++ } ++ ++ if (!ucNewSecMode && ucOldSecMode) ++ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_NONE); ++ ++ } while (FALSE); ++ ++} /* p2pFuncParseBeaconContent */ ++ ++P_BSS_DESC_T ++p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, ++ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) ++{ ++ P_BSS_DESC_T prTargetBss = (P_BSS_DESC_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prConnReqInfo != NULL) && (prChnlReqInfo != NULL) && (prScanReqInfo != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ break; ++ /* Update connection request information. */ ++ ASSERT(prConnReqInfo->fgIsConnRequest == TRUE); ++ ++ /* Find BSS Descriptor first. */ ++ prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); ++ ++ if (prTargetBss == NULL) { ++ /* Update scan parameter... to scan target device. */ ++ prScanReqInfo->ucNumChannelList = 1; ++ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; ++ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ ++ prScanReqInfo->fgIsAbort = TRUE; ++ } else { ++ prChnlReqInfo->u8Cookie = 0; ++ prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum; ++ prChnlReqInfo->eBand = prTargetBss->eBand; ++ prChnlReqInfo->eChnlSco = prTargetBss->eSco; ++ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; ++ } ++ ++ } while (FALSE); ++ ++ return prTargetBss; ++} /* p2pFuncKeepOnConnection */ ++ ++/* Currently Only for ASSOC Response Frame. */ ++VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; ++ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; ++ INT_16 i2IELen = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); ++ ++ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; ++ ++ if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP) ++ break; ++ ++ i2IELen = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + ++ CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); ++ ++ if (i2IELen <= 0) ++ break; ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); ++ prJoinInfo->u4BufLength = (UINT_32) i2IELen; ++ ++ kalMemCopy(prJoinInfo->aucIEBuf, prAssocRspFrame->aucInfoElem, prJoinInfo->u4BufLength); ++ ++ } while (FALSE); ++ ++} /* p2pFuncStoreAssocRspIEBuffer */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set Packet Filter. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_NOT_SUPPORTED ++* \retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, ++ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter) ++{ ++ UINT_32 u4NewPacketFilter = 0; ++ ++ DEBUGFUNC("p2pFuncMgmtFrameRegister"); ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ if (pu4P2pPacketFilter) ++ u4NewPacketFilter = *pu4P2pPacketFilter; ++ ++ switch (u2FrameType) { ++ case MAC_FRAME_PROBE_REQ: ++ if (fgIsRegistered) { ++ u4NewPacketFilter |= PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); ++ } else { ++ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); ++ } ++ break; ++ case MAC_FRAME_ACTION: ++ if (fgIsRegistered) { ++ u4NewPacketFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); ++ } else { ++ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); ++ } ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Ask frog to add code for mgmt:%x\n", u2FrameType); ++ break; ++ } ++ ++ if (pu4P2pPacketFilter) ++ *pu4P2pPacketFilter = u4NewPacketFilter; ++ ++ /* u4NewPacketFilter |= prAdapter->u4OsPacketFilter; */ ++ ++ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; ++ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; ++ ++ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RX_FILTER, ++ TRUE, ++ FALSE, ++ FALSE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(UINT_32), ++ (PUINT_8) &prAdapter->u4OsPacketFilter, ++ &u4NewPacketFilter, sizeof(u4NewPacketFilter) ++ ); ++ ++ } while (FALSE); ++ ++} /* p2pFuncMgmtFrameRegister */ ++ ++VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter) ++{ ++ ++ do { ++ ++ prAdapter->rWifiVar.prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter; ++ ++ if ((prAdapter->u4OsPacketFilter & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) { ++ ++ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; ++ ++ prAdapter->u4OsPacketFilter |= (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RX_FILTER, ++ TRUE, ++ FALSE, ++ FALSE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(UINT_32), ++ (PUINT_8) &prAdapter->u4OsPacketFilter, &u4OsFilter, sizeof(u4OsFilter) ++ ); ++ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pFuncUpdateMgmtFrameRegister */ ++ ++VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo) ++{ ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucMacAddr != NULL) && (prStaInfo != NULL)); ++ ++ prStaInfo->u4InactiveTime = 0; ++ prStaInfo->u4RxBytes = 0; ++ prStaInfo->u4TxBytes = 0; ++ prStaInfo->u4RxPackets = 0; ++ prStaInfo->u4TxPackets = 0; ++ /* TODO: */ ++ ++ } while (FALSE); ++ ++} /* p2pFuncGetStationInfo */ ++ ++BOOLEAN ++p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, ++ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen) ++{ ++ BOOLEAN fgIsAllocMem = FALSE; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_16 u2Offset = 0; ++ P_IE_P2P_T prIe = (P_IE_P2P_T) NULL; ++ PUINT_8 pucAttriListStart = (PUINT_8) NULL; ++ UINT_16 u2AttriListLen = 0, u2BufferSize = 0; ++ BOOLEAN fgBackupAttributes = FALSE; ++ UINT_16 u2CopyLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucIE); ++ ASSERT(ppucAttriList); ++ ASSERT(pu2AttriListLen); ++ ++ if (ppucAttriList) ++ *ppucAttriList = NULL; ++ if (pu2AttriListLen) ++ *pu2AttriListLen = 0; ++ ++ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ aucWfaOui[0] = 0x00; ++ aucWfaOui[1] = 0x50; ++ aucWfaOui[2] = 0xF2; ++ } else if ((ucOuiType != VENDOR_OUI_TYPE_P2P) ++#if CFG_SUPPORT_WFD ++ && (ucOuiType != VENDOR_OUI_TYPE_WFD) ++#endif ++ ) { ++ DBGLOG(P2P, INFO, "Not supported OUI Type to parsing 0x%x\n", ucOuiType); ++ return fgIsAllocMem; ++ } ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ if (ELEM_ID_VENDOR != IE_ID(pucIE)) ++ continue; ++ ++ prIe = (P_IE_P2P_T) pucIE; ++ ++ if (prIe->ucLength <= P2P_OUI_TYPE_LEN) ++ continue; ++ ++ if ((prIe->aucOui[0] == aucWfaOui[0]) && ++ (prIe->aucOui[1] == aucWfaOui[1]) && ++ (prIe->aucOui[2] == aucWfaOui[2]) && (ucOuiType == prIe->ucOuiType)) { ++ ++ if (!pucAttriListStart) { ++ pucAttriListStart = &prIe->aucP2PAttributes[0]; ++ if (prIe->ucLength > P2P_OUI_TYPE_LEN) ++ u2AttriListLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); ++ else ++ ASSERT(FALSE); ++ continue; ++ } ++/* More than 2 attributes. */ ++ ++ if (FALSE == fgBackupAttributes) { ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = ++ prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ fgBackupAttributes = TRUE; ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[0], ++ pucAttriListStart, u2AttriListLen); ++ ++ pucAttriListStart = ++ &prP2pSpecificBssInfo->aucAttributesCache[0]; ++ ++ u2BufferSize = P2P_MAXIMUM_ATTRIBUTE_LEN; ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ kalMemCopy(&prP2pSpecificBssInfo->aucWscAttributesCache ++ [0], pucAttriListStart, u2AttriListLen); ++ pucAttriListStart = ++ &prP2pSpecificBssInfo->aucWscAttributesCache[0]; ++ ++ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; ++ } ++#if CFG_SUPPORT_WFD ++ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ PUINT_8 pucTmpBuf = (PUINT_8) NULL; ++ ++ pucTmpBuf = (PUINT_8) ++ kalMemAlloc(WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE, ++ VIR_MEM_TYPE); ++ ++ if (pucTmpBuf != NULL) { ++ fgIsAllocMem = TRUE; ++ } else { ++ /* Can't alloca memory for WFD IE relocate. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ kalMemCopy(pucTmpBuf, ++ pucAttriListStart, u2AttriListLen); ++ ++ pucAttriListStart = pucTmpBuf; ++ ++ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; ++ } ++#endif ++ else ++ fgBackupAttributes = FALSE; ++ } ++ ++ u2CopyLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); ++ ++ if ((u2AttriListLen + u2CopyLen) > u2BufferSize) { ++ u2CopyLen = u2BufferSize - u2AttriListLen; ++ DBGLOG(P2P, WARN, ++ "Length of received P2P attributes > maximum cache size.\n"); ++ } ++ ++ if (u2CopyLen) { ++ kalMemCopy((PUINT_8) ++ ((ULONG) pucAttriListStart + ++ (UINT_32) u2AttriListLen), ++ &prIe->aucP2PAttributes[0], u2CopyLen); ++ ++ u2AttriListLen += u2CopyLen; ++ } ++ } /* prIe->aucOui */ ++ } /* IE_FOR_EACH */ ++ ++ if (pucAttriListStart) { ++ PUINT_8 pucAttribute = pucAttriListStart; ++ ++ DBGLOG(P2P, LOUD, "Checking Attribute Length.\n"); ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ P2P_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset); ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ /* Do nothing */ ++ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ /* Big Endian: WSC, WFD. */ ++ WSC_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset) { ++ DBGLOG(P2P, LOUD, "Attribute ID:%d, Length:%d.\n", ++ WSC_ATTRI_ID(pucAttribute), WSC_ATTRI_LEN(pucAttribute)); ++ } ++ } else { ++ } ++ ++ ASSERT(u2Offset == u2AttriListLen); ++ ++ if (ppucAttriList) ++ *ppucAttriList = pucAttriListStart; ++ if (pu2AttriListLen) ++ *pu2AttriListLen = u2AttriListLen; ++ ++ } else { ++ if (ppucAttriList) ++ *ppucAttriList = (PUINT_8) NULL; ++ if (pu2AttriListLen) ++ *pu2AttriListLen = 0; ++ } ++ ++ return fgIsAllocMem; ++} /* p2pFuncGetAttriList */ ++ ++P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu) ++{ ++ P_MSDU_INFO_T prRetMsduInfo = prMgmtTxMsdu; ++ P_WLAN_PROBE_RSP_FRAME_T prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ UINT_16 u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0; ++ BOOLEAN fgIsP2PIE = FALSE, fgIsWSCIE = FALSE; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ UINT_16 u2EstimateSize = 0, u2EstimatedExtraIELen = 0; ++ UINT_32 u4IeArraySize = 0, u4Idx = 0; ++ UINT_8 ucOuiType = 0; ++ UINT_16 u2SubTypeVersion = 0; ++ ++ BOOLEAN fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ /* 3 Make sure this is probe response frame. */ ++ prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); ++ ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP); ++ ++ if (prP2pBssInfo->u2BeaconInterval) ++ prProbeRspFrame->u2BeaconInterval = prP2pBssInfo->u2BeaconInterval; ++ ++ /* 3 Get the importent P2P IE. */ ++ u2ProbeRspHdrLen = ++ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); ++ pucIEBuf = prProbeRspFrame->aucInfoElem; ++ u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen; ++ ++#if CFG_SUPPORT_WFD ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen = 0; ++#endif ++ ++ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { ++ switch (IE_ID(pucIEBuf)) { ++ case ELEM_ID_SSID: ++ { ++ ++ COPY_SSID(prP2pBssInfo->aucSSID, ++ prP2pBssInfo->ucSSIDLen, ++ SSID_IE(pucIEBuf)->aucSSID, SSID_IE(pucIEBuf)->ucLength); ++ } ++ break; ++ case ELEM_ID_VENDOR: ++#if !CFG_SUPPORT_WFD ++ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 2, pucIEBuf, ++ IE_SIZE(pucIEBuf)); ++ fgIsWSCIE = TRUE; ++ } ++ ++ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIEBuf, &ucOuiType)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ /* 2 Note(frog): I use WSC IE buffer for Probe Request to ++ * store the P2P IE for Probe Response. */ ++ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 1, pucIEBuf, ++ IE_SIZE(pucIEBuf)); ++ fgIsP2PIE = TRUE; ++ } ++ ++ } else { ++ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + ++ IE_SIZE(pucIEBuf)) < 512) { ++ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, ++ pucIEBuf, IE_SIZE(pucIEBuf)); ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += ++ IE_SIZE(pucIEBuf); ++ } ++ } ++#else ++ /* Eddie May be WFD */ ++ if (rsnParseCheckForWFAInfoElem ++ (prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_WMM) ++ break; ++ ++ } ++ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + IE_SIZE(pucIEBuf)) < ++ 1024) { ++ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE + ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen, pucIEBuf, ++ IE_SIZE(pucIEBuf)); ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf); ++ } ++#endif ++ break; ++ default: ++ break; ++ } ++ ++ } ++ ++ /* 3 Check the total size & current frame. */ ++ u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN + ++ TIMESTAMP_FIELD_LEN + ++ BEACON_INTERVAL_FIELD_LEN + ++ CAP_INFO_FIELD_LEN + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + ++ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET); ++ ++ u2EstimatedExtraIELen = 0; ++ ++ u4IeArraySize = sizeof(txProbeRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); ++ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { ++ if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) { ++ u2EstimatedExtraIELen += txProbeRspIETable[u4Idx].u2EstimatedFixedIELen; ++ } ++ ++ else { ++ ASSERT(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen); ++ ++ u2EstimatedExtraIELen += ++ (UINT_16) (txProbeRspIETable[u4Idx].pfnCalculateVariableIELen ++ (prAdapter, NETWORK_TYPE_P2P_INDEX, NULL)); ++ } ++ ++ } ++ ++ if (fgIsWSCIE) ++ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); ++ ++ if (fgIsP2PIE) { ++ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); ++ u2EstimatedExtraIELen += p2pFuncCalculateP2P_IE_NoA(prAdapter, 0, NULL); ++ } ++#if CFG_SUPPORT_WFD ++ u2EstimatedExtraIELen += prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; ++#endif ++ ++ u2EstimateSize += u2EstimatedExtraIELen; ++ if (u2EstimateSize > (prRetMsduInfo->u2FrameLength)) { ++ prRetMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimateSize); ++ ++ if (prRetMsduInfo == NULL) { ++ DBGLOG(P2P, WARN, "No packet for sending new probe response, use original one\n"); ++ prRetMsduInfo = prMgmtTxMsdu; ++ break; ++ } ++ ++ prRetMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ } ++ /* 3 Compose / Re-compose probe response frame. */ ++ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ++ ((ULONG) (prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prProbeRspFrame->aucDestAddr, prProbeRspFrame->aucSrcAddr, ++ prProbeRspFrame->aucBSSID, prProbeRspFrame->u2BeaconInterval, ++ fgIsPureAP ? prP2pBssInfo-> ++ u2CapInfo : prProbeRspFrame->u2CapInfo); ++ ++ prRetMsduInfo->u2FrameLength = ++ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); ++ ++ bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo, prP2pBssInfo, prProbeRspFrame->aucDestAddr); ++ ++ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { ++ if (txProbeRspIETable[u4Idx].pfnAppendIE) ++ txProbeRspIETable[u4Idx].pfnAppendIE(prAdapter, prRetMsduInfo); ++ ++ } ++ ++ if (fgIsWSCIE) { ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, ++ 2, ++ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + ++ (UINT_32) prRetMsduInfo->u2FrameLength)); ++ ++ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); ++ } ++ ++ if (fgIsP2PIE) { ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, ++ 1, ++ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + ++ (UINT_32) prRetMsduInfo->u2FrameLength)); ++ ++ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); ++ p2pFuncGenerateP2P_IE_NoA(prAdapter, prRetMsduInfo); ++ } ++#if CFG_SUPPORT_WFD ++ if (prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen > 0) { ++ kalMemCopy((PUINT_8) ((ULONG) prRetMsduInfo->prPacket + (UINT_32) prRetMsduInfo->u2FrameLength), ++ prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, ++ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen); ++ prRetMsduInfo->u2FrameLength += (UINT_16) prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; ++ } ++#endif ++ ++ } while (FALSE); ++ ++ if (prRetMsduInfo != prMgmtTxMsdu) ++ cnmMgtPktFree(prAdapter, prMgmtTxMsdu); ++ ++ return prRetMsduInfo; ++} /* p2pFuncProcessP2pProbeRsp */ ++ ++#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ ++UINT_32 ++p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ UINT_32 u4IELen = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ u4IELen = prP2pSpeBssInfo->u2IELenForBCN; ++ ++ } while (FALSE); ++ ++ return u4IELen; ++} /* p2pFuncCalculateP2p_IELenForBeacon */ ++ ++VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ pucIEBuf = (PUINT_8) ((UINT_32) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucBeaconIECache, prP2pSpeBssInfo->u2IELenForBCN); ++ ++ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN; ++ ++ } while (FALSE); ++ ++} /* p2pFuncGenerateExtra_IEForBeacon */ ++ ++#else ++UINT_32 ++p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ UINT_32 u4IELen = 0; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); ++ ++ if (!prAdapter->fgIsP2PRegistered) ++ break; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ u4IELen = prP2pSpeBssInfo->u2AttributeLen; ++ ++ } while (FALSE); ++ ++ return u4IELen; ++} /* p2pFuncCalculateP2p_IELenForBeacon */ ++ ++VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ if (!prAdapter->fgIsP2PRegistered) ++ break; ++ ++ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ break; ++ ++ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen); ++ ++ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen; ++ ++ } while (FALSE); ++ ++} /* p2pFuncGenerateP2p_IEForBeacon */ ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ ++ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++} /* p2pFuncCalculateP2p_IELenForBeacon */ ++ ++VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ UINT_16 u2IELen = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) ++ return; ++ ++ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ /* TODO: Check P2P FSM State. */ ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); ++ ++ prMsduInfo->u2FrameLength += u2IELen; ++ ++} /* p2pFuncGenerateP2p_IEForBeacon */ ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to calculate P2P IE length for Beacon frame. ++* ++* @param[in] eNetTypeIndex Specify which network ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return The length of P2P IE added ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ++p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ ++ return p2pFuncCalculateP2P_IELen(prAdapter, ++ eNetTypeIndex, ++ prStaRec, ++ txAssocRspAttributesTable, ++ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ ++} /* p2pFuncCalculateP2p_IELenForAssocRsp */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Beacon frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ if (!prStaRec) ++ break; ++ ++ if (IS_STA_P2P_TYPE(prStaRec)) { ++ DBGLOG(P2P, TRACE, "Generate NULL P2P IE for Assoc Rsp.\n"); ++ ++ p2pFuncGenerateP2P_IE(prAdapter, ++ TRUE, ++ &prMsduInfo->u2FrameLength, ++ prMsduInfo->prPacket, ++ 1500, ++ txAssocRspAttributesTable, ++ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ } else { ++ ++ DBGLOG(P2P, TRACE, "Legacy device, no P2P IE.\n"); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pFuncGenerateP2p_IEForAssocRsp */ ++ ++UINT_32 ++p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ DBGLOG(P2P, TRACE, "p2pFuncCalculateWSC_IELenForAssocRsp\n"); ++ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) ++ return 0; ++ ++ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++} /* p2pFuncCalculateP2p_IELenForAssocRsp */ ++ ++VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ UINT_16 u2IELen = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) ++ return; ++ DBGLOG(P2P, TRACE, "p2pFuncGenerateWSC_IEForAssocRsp\n"); ++ ++ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ /* TODO: Check P2P FSM State. */ ++ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); ++ ++ prMsduInfo->u2FrameLength += u2IELen; ++ ++} ++ ++/* p2pFuncGenerateP2p_IEForAssocRsp */ ++ ++UINT_32 ++p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN P_STA_RECORD_T prStaRec, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) ++{ ++ ++ UINT_32 u4OverallAttriLen, u4Dummy; ++ UINT_16 u2EstimatedFixedAttriLen; ++ UINT_32 i; ++ ++ /* Overall length of all Attributes */ ++ u4OverallAttriLen = 0; ++ ++ for (i = 0; i < u4AttriTableSize; i++) { ++ u2EstimatedFixedAttriLen = arAppendAttriTable[i].u2EstimatedFixedAttriLen; ++ ++ if (u2EstimatedFixedAttriLen) { ++ u4OverallAttriLen += u2EstimatedFixedAttriLen; ++ } else { ++ ASSERT(arAppendAttriTable[i].pfnCalculateVariableAttriLen); ++ ++ u4OverallAttriLen += arAppendAttriTable[i].pfnCalculateVariableAttriLen(prAdapter, prStaRec); ++ } ++ } ++ ++ u4Dummy = u4OverallAttriLen; ++ u4OverallAttriLen += P2P_IE_OUI_HDR; ++ ++ for (; (u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) { ++ u4OverallAttriLen += P2P_IE_OUI_HDR; ++ u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN; ++ } ++ ++ return u4OverallAttriLen; ++} /* p2pFuncCalculateP2P_IELen */ ++ ++VOID ++p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) ++{ ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ P_IE_P2P_T prIeP2P = (P_IE_P2P_T) NULL; ++ UINT_32 u4OverallAttriLen; ++ UINT_32 u4AttriLen; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; ++ UINT_32 i; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ /* Check buffer length is still enough. */ ++ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR); ++ ++ prIeP2P = (P_IE_P2P_T) pucBuffer; ++ ++ prIeP2P->ucId = ELEM_ID_P2P; ++ ++ prIeP2P->aucOui[0] = aucWfaOui[0]; ++ prIeP2P->aucOui[1] = aucWfaOui[1]; ++ prIeP2P->aucOui[2] = aucWfaOui[2]; ++ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; ++ ++ (*pu2Offset) += P2P_IE_OUI_HDR; ++ ++ /* Overall length of all Attributes */ ++ u4OverallAttriLen = 0; ++ ++ for (i = 0; i < u4AttriTableSize; i++) { ++ ++ if (arAppendAttriTable[i].pfnAppendAttri) { ++ u4AttriLen = ++ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, ++ u2BufSize); ++ ++ u4OverallAttriLen += u4AttriLen; ++ ++ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { ++ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; ++ ++ prIeP2P->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); ++ ++ pucBuffer = ++ (PUINT_8) ((ULONG) prIeP2P + ++ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)); ++ ++ prIeP2P = (P_IE_P2P_T) ((ULONG) prIeP2P + ++ (ELEM_HDR_LEN + ++ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN))); ++ ++ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); ++ ++ prIeP2P->ucId = ELEM_ID_P2P; ++ ++ prIeP2P->aucOui[0] = aucWfaOui[0]; ++ prIeP2P->aucOui[1] = aucWfaOui[1]; ++ prIeP2P->aucOui[2] = aucWfaOui[2]; ++ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; ++ ++ kalMemCopy(prIeP2P->aucP2PAttributes, aucTempBuffer, u4OverallAttriLen); ++ (*pu2Offset) += P2P_IE_OUI_HDR; ++ } ++ ++ } ++ ++ } ++ ++ prIeP2P->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); ++ ++ } while (FALSE); ++ ++} /* p2pFuncGenerateP2P_IE */ ++ ++UINT_32 ++p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ PUINT_8 pucBuffer; ++ P_P2P_ATTRI_STATUS_T prAttriStatus; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_32 u4AttriLen = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucBuf); ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (fgIsAssocFrame) ++ return u4AttriLen; ++ /* TODO: For assoc request P2P IE check in driver & return status in P2P IE. */ ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT(pucBuffer); ++ prAttriStatus = (P_P2P_ATTRI_STATUS_T) pucBuffer; ++ ++ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); ++ ++ prAttriStatus->ucId = P2P_ATTRI_ID_STATUS; ++ WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS); ++ ++ prAttriStatus->ucStatusCode = P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR; ++ ++ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} /* p2pFuncAppendAttriStatusForAssocRsp */ ++ ++UINT_32 ++p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ P_P2P_ATTRI_EXT_LISTEN_TIMING_T prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ PUINT_8 pucBuffer = NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(pucBuf); ++ ++ if (fgIsAssocFrame) ++ return u4AttriLen; ++ /* TODO: For extend listen timing. */ ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); ++ ++ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT(pucBuffer); ++ ++ prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) pucBuffer; ++ ++ prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING; ++ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); ++ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, prP2pSpecificBssInfo->u2AvailabilityInterval); ++ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, prP2pSpecificBssInfo->u2AvailabilityPeriod); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} /* p2pFuncAppendAttriExtListenTiming */ ++ ++P_IE_HDR_T ++p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore) ++{ ++ P_IE_HDR_T prTargetIE = (P_IE_HDR_T) NULL; ++ PUINT_8 pucIE = (PUINT_8) NULL; ++ UINT_16 u2Offset = 0; ++ ++ if (pfgIsMore) ++ *pfgIsMore = FALSE; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) ++ && (pucIEBuf != NULL)); ++ ++ pucIE = pucIEBuf; ++ ++ IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) { ++ if (IE_ID(pucIE) == ucElemID) { ++ if ((prTargetIE) && (pfgIsMore)) { ++ ++ *pfgIsMore = TRUE; ++ break; ++ } ++ prTargetIE = (P_IE_HDR_T) pucIE; ++ ++ if (pfgIsMore == NULL) ++ break; ++ ++ } ++ } ++ ++ } while (FALSE); ++ ++ return prTargetIE; ++} /* p2pFuncGetSpecIE */ ++ ++P_ATTRIBUTE_HDR_T ++p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID) ++{ ++ P_IE_P2P_T prP2pIE = (P_IE_P2P_T) NULL; ++ P_ATTRIBUTE_HDR_T prTargetAttri = (P_ATTRIBUTE_HDR_T) NULL; ++ BOOLEAN fgIsMore = FALSE; ++ PUINT_8 pucIE = (PUINT_8) NULL, pucAttri = (PUINT_8) NULL; ++ UINT_16 u2OffsetAttri = 0; ++ UINT_16 u2BufferLenLeft = 0; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ ++ DBGLOG(P2P, INFO, "Check AssocReq Oui type %u attri %u for len %u\n", ucOuiType, u2AttriID, u2BufferLen); ++ ++ ASSERT(prAdapter); ++ ASSERT(pucIEBuf); ++ ++ u2BufferLenLeft = u2BufferLen; ++ pucIE = pucIEBuf; ++ do { ++ fgIsMore = FALSE; ++ prP2pIE = (P_IE_P2P_T) p2pFuncGetSpecIE(prAdapter, ++ pucIE, u2BufferLenLeft, ELEM_ID_VENDOR, &fgIsMore); ++ if (prP2pIE == NULL) ++ continue; ++ ++ ASSERT((ULONG) prP2pIE >= (ULONG) pucIE); ++ ++ u2BufferLenLeft = u2BufferLen - (UINT_16) (((ULONG) prP2pIE) - ((ULONG) pucIEBuf)); ++ ++ DBGLOG(P2P, INFO, "Find vendor id %u len %u oui %u more %u LeftLen %u\n", ++ IE_ID(prP2pIE), IE_LEN(prP2pIE), prP2pIE->ucOuiType, fgIsMore, ++ u2BufferLenLeft); ++ ++ if ((IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) && (prP2pIE->ucOuiType == ucOuiType)) { ++ switch (ucOuiType) { ++ case VENDOR_OUI_TYPE_WPS: ++ aucWfaOui[0] = 0x00; ++ aucWfaOui[1] = 0x50; ++ aucWfaOui[2] = 0xF2; ++ break; ++ case VENDOR_OUI_TYPE_P2P: ++ break; ++ case VENDOR_OUI_TYPE_WPA: ++ case VENDOR_OUI_TYPE_WMM: ++ case VENDOR_OUI_TYPE_WFD: ++ default: ++ break; ++ } ++ ++ if ((prP2pIE->aucOui[0] != aucWfaOui[0]) ++ || (prP2pIE->aucOui[1] != aucWfaOui[1]) ++ || (prP2pIE->aucOui[2] != aucWfaOui[2])) ++ continue; ++ ++ u2OffsetAttri = 0; ++ pucAttri = prP2pIE->aucP2PAttributes; ++ ++ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { ++ WSC_ATTRI_FOR_EACH(pucAttri, ++ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { ++ /* LOG_FUNC("WSC: attri id=%u len=%u\n", ++ * WSC_ATTRI_ID(pucAttri), ++ * WSC_ATTRI_LEN(pucAttri)); */ ++ if (WSC_ATTRI_ID(pucAttri) == u2AttriID) { ++ prTargetAttri = ++ (P_ATTRIBUTE_HDR_T) pucAttri; ++ break; ++ } ++ } ++ ++ } else if (ucOuiType == VENDOR_OUI_TYPE_P2P) { ++ P2P_ATTRI_FOR_EACH(pucAttri, ++ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { ++ /* LOG_FUNC("P2P: attri id=%u len=%u\n", ++ * ATTRI_ID(pucAttri), ATTRI_LEN(pucAttri)); */ ++ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { ++ prTargetAttri = (P_ATTRIBUTE_HDR_T) pucAttri; ++ break; ++ } ++ } ++ } ++#if CFG_SUPPORT_WFD ++ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { ++ WFD_ATTRI_FOR_EACH(pucAttri, ++ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { ++ /* DBGLOG(P2P, INFO, ("WFD: attri id=%u ++ * len=%u\n",WFD_ATTRI_ID(pucAttri), ++ * WFD_ATTRI_LEN(pucAttri))); */ ++ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { ++ prTargetAttri = ++ (P_ATTRIBUTE_HDR_T) pucAttri; ++ break; ++ } ++ } ++ } ++#endif ++ /* Do nothing */ ++ /* Possible or else. */ ++ } /* ucOuiType */ ++ /* P2P_OUI_TYPE_LEN */ ++ pucIE = (PUINT_8) (((ULONG) prP2pIE) + IE_SIZE(prP2pIE)); ++ /* prP2pIE */ ++ } while (prP2pIE && fgIsMore && u2BufferLenLeft); ++ ++ return prTargetAttri; ++} ++ ++/* p2pFuncGetSpecAttri */ ++ ++WLAN_STATUS ++p2pFuncGenerateBeaconProbeRsp(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_INFO_T prBssInfo, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgIsProbeRsp) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++/* P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = (P_APPEND_VAR_IE_ENTRY_T)NULL; */ ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL) && (prMsduInfo != NULL)); ++ ++/* txBcnIETable */ ++ ++/* txProbeRspIETable */ ++ ++ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; ++ ++ return nicUpdateBeaconIETemplate(prAdapter, ++ IE_UPD_METHOD_UPDATE_ALL, ++ NETWORK_TYPE_P2P_INDEX, ++ prBssInfo->u2CapInfo, ++ (PUINT_8) prBcnFrame->aucInfoElem, ++ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, ++ aucInfoElem)); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++} /* p2pFuncGenerateBeaconProbeRsp */ ++ ++WLAN_STATUS ++p2pFuncComposeBeaconProbeRspTemplate(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBcnBuffer, ++ IN UINT_32 u4BcnBufLen, ++ IN BOOLEAN fgIsProbeRsp, ++ IN P_P2P_PROBE_RSP_UPDATE_INFO_T prP2pProbeRspInfo, IN BOOLEAN fgSynToFW) ++{ ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ P_WLAN_MAC_HEADER_T prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBcnBuffer != NULL)); ++ ++ prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) pucBcnBuffer; ++ ++ if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) && (!fgIsProbeRsp)) { ++ rWlanStatus = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) { ++ rWlanStatus = WLAN_STATUS_INVALID_DATA; ++ break; ++ } ++ ++ if (fgIsProbeRsp) { ++ ASSERT_BREAK(prP2pProbeRspInfo != NULL); ++ ++ if (prP2pProbeRspInfo->prProbeRspMsduTemplate) ++ cnmMgtPktFree(prAdapter, prP2pProbeRspInfo->prProbeRspMsduTemplate); ++ ++ prP2pProbeRspInfo->prProbeRspMsduTemplate = cnmMgtPktAlloc(prAdapter, u4BcnBufLen); ++ ++ prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate; ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ prMsduInfo->ucStaRecIndex = 0xFF; ++ prMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ ++ } else { ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prMsduInfo = prP2pBssInfo->prBeacon; ++ ++ if (prMsduInfo == NULL) { ++ rWlanStatus = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++ if (u4BcnBufLen > (OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH)) { ++ /* Unexpected error, buffer overflow. */ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen); ++ ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = (UINT_16) u4BcnBufLen; ++ ++ if (fgSynToFW && prP2pBssInfo) ++ rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, prP2pBssInfo, prMsduInfo, fgIsProbeRsp); ++ ++ } while (FALSE); ++ ++ return rWlanStatus; ++ ++} /* p2pFuncComposeBeaconTemplate */ ++ ++#if CFG_SUPPORT_WFD ++WLAN_STATUS wfdAdjustResource(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) ++{ ++#if 1 ++ /* The API shall be called in tx_thread */ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); ++ if (fgEnable) { ++ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; ++ if (QM_GUARANTEED_TC0_RESOURCE > 2) { ++ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE - 2; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; ++ } ++ if (QM_GUARANTEED_TC1_RESOURCE > 2) { ++ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE - 2; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; ++ } ++ } else { ++ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} ++ ++WLAN_STATUS wfdAdjustThread(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) ++{ ++#define WFD_TX_THREAD_PRIORITY 70 ++ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); ++ if (prAdapter->prGlueInfo->main_thread != NULL) { ++ if (fgEnable) { ++#ifdef LINUX ++ /* TODO the change schedule API shall be provided by OS glue layer */ ++ /* Or the API shall be put in os glue layer */ ++ struct sched_param param = {.sched_priority = WFD_TX_THREAD_PRIORITY }; ++ ++ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_RR, ¶m); ++#endif ++ } else { ++#ifdef LINUX ++ /* TODO the change schedule API shall be provided by OS glue layer */ ++ struct sched_param param = {.sched_priority = 0 }; ++ ++ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_NORMAL, ¶m); ++#endif ++ } ++ } else { ++ ++ DBGLOG(P2P, WARN, "main_thread is null, please check if the wlanRemove is called in advance\n"); ++ } ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#endif /* CFG_SUPPORT_WFD */ ++ ++WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ENUM_PARAM_MEDIA_STATE_T eConnectionState) ++{ ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ if (prAdapter->fgIsP2PRegistered == FALSE) ++ return WLAN_STATUS_SUCCESS; ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ ++ if ((prWfdCfgSettings->ucWfdEnable) && ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == ++ PARAM_MEDIA_STATE_CONNECTED) { ++ wfdAdjustResource(prAdapter, TRUE); ++ wfdAdjustThread(prAdapter, TRUE); ++ } else { ++ wfdAdjustResource(prAdapter, FALSE); ++ wfdAdjustThread(prAdapter, FALSE); ++ } ++ ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c +new file mode 100644 +index 000000000000..991861f73608 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c +@@ -0,0 +1,612 @@ ++#include "p2p_precomp.h" ++ ++#if CFG_SUPPORT_WFD ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++#if 0 ++APPEND_VAR_ATTRI_ENTRY_T txProbeRspWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_EXT_CAPABILITY), NULL, wfdFuncAppendAttriExtCapability} /* 7 */ ++ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ ++}; ++ ++APPEND_VAR_ATTRI_ENTRY_T txBeaconWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++}; ++ ++APPEND_VAR_ATTRI_ENTRY_T txAssocReqWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++}; ++#endif ++ ++APPEND_VAR_ATTRI_ENTRY_T txAssocRspWFDAttributesTable[] = { ++ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ ++ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ ++ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ ++ ++}; ++ ++#endif ++ ++UINT_32 ++p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; ++ UINT_32 u4RetValue = 0; ++ ++ do { ++ ASSERT_BREAK((eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) && (prAdapter != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ ++ u4RetValue = prConnReqInfo->u4BufLength; ++ ++ /* ADD HT Capability */ ++ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP); ++ ++ /* ADD WMM Information Element */ ++ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO); ++ ++ } while (FALSE); ++ ++ return u4RetValue; ++} /* p2pCalculate_IEForAssocReq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to generate P2P IE for Beacon frame. ++* ++* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; ++ PUINT_8 pucIEBuf = (PUINT_8) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); ++ ++ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); ++ ++ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, prConnReqInfo->u4BufLength); ++ ++ prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength; ++ ++ rlmReqGenerateHtCapIE(prAdapter, prMsduInfo); ++ mqmGenerateWmmInfoIE(prAdapter, prMsduInfo); ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pGenerate_IEForAssocReq */ ++ ++UINT_32 ++wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_DEVICE_INFORMATION_IE_T prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) pucBuffer; ++ ++ prWfdDevInfo->ucElemID = WFD_ATTRI_ID_DEV_INFO; ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevInfo, prWfdCfgSettings->u2WfdDevInfo); ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2SessionMgmtCtrlPort, prWfdCfgSettings->u2WfdControlPort); ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevMaxSpeed, prWfdCfgSettings->u2WfdMaximumTp); ++ ++ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2Length, WFD_ATTRI_MAX_LEN_DEV_INFO); ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_DEV_INFO + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriDevInfo */ ++ ++UINT_32 ++wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_ASSOCIATED_BSSID_IE_T prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_BSS_INFO_T prAisBssInfo = (P_BSS_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if (prWfdCfgSettings->ucWfdEnable == 0) ++ break; ++ ++ /* AIS network. */ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if ((!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) || ++ (prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) pucBuffer; ++ ++ prWfdAssocBssid->ucElemID = WFD_ATTRI_ID_ASSOC_BSSID; ++ ++ WLAN_SET_FIELD_BE16(&prWfdAssocBssid->u2Length, WFD_ATTRI_MAX_LEN_ASSOC_BSSID); ++ ++ COPY_MAC_ADDR(prWfdAssocBssid->aucAssocBssid, prAisBssInfo->aucBSSID); ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_ASSOC_BSSID + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriAssocBssid */ ++ ++UINT_32 ++wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_COUPLE_SINK_INFORMATION_IE_T prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_SINK_INFO_VALID) == 0)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) pucBuffer; ++ ++ prWfdCoupleSinkInfo->ucElemID = WFD_ATTRI_ID_COUPLED_SINK_INFO; ++ ++ WLAN_SET_FIELD_BE16(&prWfdCoupleSinkInfo->u2Length, WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO); ++ ++ COPY_MAC_ADDR(prWfdCoupleSinkInfo->aucCoupleSinkMac, prWfdCfgSettings->aucWfdCoupleSinkAddress); ++ ++ prWfdCoupleSinkInfo->ucCoupleSinkStatusBp = prWfdCfgSettings->ucWfdCoupleSinkStatus; ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriCoupledSinkInfo */ ++ ++UINT_32 ++wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_EXTENDED_CAPABILITY_IE_T prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || ++ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_EXT_CAPABILITY_VALID) == 0)) { ++ break; ++ } ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) pucBuffer; ++ ++ prWfdExtCapability->ucElemID = WFD_ATTRI_ID_EXT_CAPABILITY; ++ ++ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2Length, WFD_ATTRI_MAX_LEN_EXT_CAPABILITY); ++ ++ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2WfdExtCapabilityBp, prWfdCfgSettings->u2WfdExtendCap); ++ ++ u4AttriLen = WFD_ATTRI_MAX_LEN_EXT_CAPABILITY + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriExtCapability */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to calculate length of Channel List Attribute ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return The length of Attribute added ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ UINT_16 u2AttriLen = 0; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ if (prWfdCfgSettings->ucWfdEnable == 0) ++ break; ++ ++ u2AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ return (UINT_32) u2AttriLen; ++ ++} /* wfdFuncCalculateAttriLenSessionInfo */ ++ ++UINT_32 ++wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) ++{ ++ UINT_32 u4AttriLen = 0; ++ PUINT_8 pucBuffer = NULL; ++ P_WFD_SESSION_INFORMATION_IE_T prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) NULL; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ ASSERT_BREAK((prWfdCfgSettings != NULL)); ++ ++ if ((prWfdCfgSettings->ucWfdEnable == 0) || (prWfdCfgSettings->u2WfdSessionInformationIELen == 0)) ++ break; ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) pucBuffer; ++ ++ prWfdSessionInfo->ucElemID = WFD_ATTRI_ID_SESSION_INFO; ++ ++ /* TODO: Check endian issue? */ ++ kalMemCopy(prWfdSessionInfo->pucWfdDevInfoDesc, prWfdCfgSettings->aucWfdSessionInformationIE, ++ prWfdCfgSettings->u2WfdSessionInformationIELen); ++ ++ WLAN_SET_FIELD_16(&prWfdSessionInfo->u2Length, prWfdCfgSettings->u2WfdSessionInformationIELen); ++ ++ u4AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; ++ ++ } while (FALSE); ++ ++ (*pu2Offset) += (UINT_16) u4AttriLen; ++ ++ return u4AttriLen; ++} ++ ++/* wfdFuncAppendAttriSessionInfo */ ++ ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++VOID ++wfdFuncGenerateWfd_IE(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgIsAssocFrame, ++ IN PUINT_16 pu2Offset, ++ IN PUINT_8 pucBuf, ++ IN UINT_16 u2BufSize, ++ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) ++{ ++ ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ P_IE_WFD_T prIeWFD = (P_IE_WFD_T) NULL; ++ UINT_32 u4OverallAttriLen; ++ UINT_32 u4AttriLen; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; ++ UINT_32 i; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); ++ ++ ASSERT_BREAK(pucBuffer != NULL); ++ ++ /* Check buffer length is still enough. */ ++ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= WFD_IE_OUI_HDR); ++ ++ prIeWFD = (P_IE_WFD_T) pucBuffer; ++ ++ prIeWFD->ucId = ELEM_ID_WFD; ++ ++ prIeWFD->aucOui[0] = aucWfaOui[0]; ++ prIeWFD->aucOui[1] = aucWfaOui[1]; ++ prIeWFD->aucOui[2] = aucWfaOui[2]; ++ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; ++ ++ (*pu2Offset) += WFD_IE_OUI_HDR; ++ ++ /* Overall length of all Attributes */ ++ u4OverallAttriLen = 0; ++ ++ for (i = 0; i < u4AttriTableSize; i++) { ++ ++ if (arAppendAttriTable[i].pfnAppendAttri) { ++ u4AttriLen = ++ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, ++ u2BufSize); ++ ++ u4OverallAttriLen += u4AttriLen; ++ ++ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { ++ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; ++ ++ prIeWFD->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); ++ ++ pucBuffer = ++ (PUINT_8) ((ULONG) prIeWFD + (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); ++ ++ prIeWFD = ++ (P_IE_WFD_T) ((ULONG) prIeWFD + ++ (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); ++ ++ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); ++ ++ prIeWFD->ucId = ELEM_ID_WFD; ++ ++ prIeWFD->aucOui[0] = aucWfaOui[0]; ++ prIeWFD->aucOui[1] = aucWfaOui[1]; ++ prIeWFD->aucOui[2] = aucWfaOui[2]; ++ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; ++ ++ kalMemCopy(prIeWFD->aucWFDAttributes, aucTempBuffer, u4OverallAttriLen); ++ (*pu2Offset) += WFD_IE_OUI_HDR; ++ } ++ ++ } ++ ++ } ++ ++ prIeWFD->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); ++ ++ } while (FALSE); ++ ++} /* wfdFuncGenerateWfd_IE */ ++ ++#endif /* CFG_SUPPORT_WFD_COMPOSE_IE */ ++ ++UINT_32 ++wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) ++{ ++ ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ if (!IS_STA_P2P_TYPE(prStaRec) || (prWfdCfgSettings->ucWfdEnable == 0)) ++ return 0; ++ ++ return p2pFuncCalculateP2P_IELen(prAdapter, ++ eNetTypeIndex, ++ prStaRec, ++ txAssocRspWFDAttributesTable, ++ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ ++#else ++ return 0; ++#endif ++} /* wfdFuncCalculateWfdIELenForAssocRsp */ ++ ++VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ ++#if CFG_SUPPORT_WFD_COMPOSE_IE ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_STA_RECORD_T prStaRec; ++ ++ do { ++ ASSERT_BREAK((prMsduInfo != NULL) && (prAdapter != NULL)); ++ ++ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) { ++ ASSERT(FALSE); ++ } else if (IS_STA_P2P_TYPE(prStaRec)) { ++ ++ if (prWfdCfgSettings->ucWfdEnable == 0) ++ break; ++ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0) ++ break; ++ ++ wfdFuncGenerateWfd_IE(prAdapter, ++ FALSE, ++ &prMsduInfo->u2FrameLength, ++ prMsduInfo->prPacket, ++ 1500, ++ txAssocRspWFDAttributesTable, ++ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); ++ } ++ } while (FALSE); ++ ++ return; ++#else ++ ++ return; ++#endif ++} /* wfdFuncGenerateWfdIEForAssocRsp */ ++ ++VOID p2pFuncComposeNoaAttribute(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ ++ P_IE_P2P_T prIeP2P; ++ P_P2P_ATTRI_NOA_T prNoaAttr = NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; ++ P_NOA_DESCRIPTOR_T prNoaDesc = NULL; ++ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; ++ UINT_32 u4AttributeLen; ++ UINT_32 u4NumOfNoaDesc = 0; ++ UINT_32 i = 0; ++ /*P2P IE format */ ++ prIeP2P = (P_IE_P2P_T) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ prIeP2P->ucId = ELEM_ID_P2P; ++ prIeP2P->aucOui[0] = aucWfaOui[0]; ++ prIeP2P->aucOui[1] = aucWfaOui[1]; ++ prIeP2P->aucOui[2] = aucWfaOui[2]; ++ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ /*P2P Attribute--NoA */ ++ prNoaAttr = (P_P2P_ATTRI_NOA_T) prIeP2P->aucP2PAttributes; ++ ++ prNoaAttr->ucId = P2P_ATTRI_ID_NOTICE_OF_ABSENCE; ++ prNoaAttr->ucIndex = prP2pSpecificBssInfo->ucNoAIndex; ++ /*OPP*/ if (prP2pSpecificBssInfo->fgEnableOppPS) { ++ prNoaAttr->ucCTWOppPSParam = P2P_CTW_OPPPS_PARAM_OPPPS_FIELD | ++ (prP2pSpecificBssInfo->u2CTWindow & P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK); ++ } else { ++ prNoaAttr->ucCTWOppPSParam = 0; ++ } ++ /*NoA Description */ ++ DBGLOG(P2P, INFO, "Compose NoA count=%d.\n", prP2pSpecificBssInfo->ucNoATimingCount); ++ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { ++ if (prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse) { ++ ++ prNoaDesc = (P_NOA_DESCRIPTOR_T) &prNoaAttr->aucNoADesc[u4NumOfNoaDesc]; ++ ++ prNoaDesc->ucCountType = prP2pSpecificBssInfo->arNoATiming[i].ucCount; ++ prNoaDesc->u4Duration = prP2pSpecificBssInfo->arNoATiming[i].u4Duration; ++ prNoaDesc->u4Interval = prP2pSpecificBssInfo->arNoATiming[i].u4Interval; ++ prNoaDesc->u4StartTime = prP2pSpecificBssInfo->arNoATiming[i].u4StartTime; ++ ++ u4NumOfNoaDesc++; ++ } ++ } ++ ++ /* include "index" + "OppPs Params" + "NOA descriptors" */ ++ prNoaAttr->u2Length = 2 + u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T); ++ u4NumOfNoaDesc++; ++ ++ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ ++ u4AttributeLen = P2P_ATTRI_HDR_LEN + prNoaAttr->u2Length; ++ ++ prIeP2P->ucLength = VENDOR_OUI_TYPE_LEN + u4AttributeLen; ++ prMsduInfo->u2FrameLength += (ELEM_HDR_LEN + prIeP2P->ucLength); ++ ++} ++ ++UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec) ++{ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; ++ UINT_8 ucIdx; ++ UINT_32 u4NumOfNoaDesc = 0; ++ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) ++ return 0; ++ ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ for (ucIdx = 0; ucIdx < prP2pSpecificBssInfo->ucNoATimingCount; ucIdx++) { ++ if (prP2pSpecificBssInfo->arNoATiming[ucIdx].fgIsInUse) ++ u4NumOfNoaDesc++; ++ } ++ ++ /* include "index" + "OppPs Params" + "NOA descriptors" */ ++ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ ++ ++ return P2P_ATTRI_LEN_NOTICE_OF_ABSENCE + (u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T)); ++} ++ ++VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { /* Hotspot */ ++ return; ++ } ++ ++ /* Compose NoA attribute */ ++ p2pFuncComposeNoaAttribute(prAdapter, ++ prMsduInfo /*prMsduInfo->ucBssIndex, prIeP2P->aucP2PAttributes, &u4AttributeLen */); ++ ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c +new file mode 100644 +index 000000000000..f25df82d9ca7 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c +@@ -0,0 +1,905 @@ ++/* ++** Id: @(#) p2p_rlm.c@@ ++*/ ++ ++/*! \file "p2p_rlm.c" ++ \brief ++ ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Init AP Bss ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ENUM_BAND_T eBand; ++ UINT_8 ucChannel; ++ ENUM_CHNL_EXT_T eSCO; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ++ return; ++ ++ /* Operation band, channel shall be ready before invoking this function. ++ * Bandwidth may be ready if other network is connected ++ */ ++ prBssInfo->fg40mBwAllowed = FALSE; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ prBssInfo->eBssSCO = CHNL_EXT_SCN; ++ ++ if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) { ++ /* In this case, the first BSS's SCO is 40MHz and known, so AP can ++ * apply 40MHz bandwidth, but the first BSS's SCO may be changed ++ * later if its Beacon lost timeout occurs ++ */ ++ if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) && ++ eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) { ++ prBssInfo->eBssSCO = eSCO; ++ } else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) { ++ prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo); ++ } ++ ++ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { ++ prBssInfo->fg40mBwAllowed = TRUE; ++ prBssInfo->fgAssoc40mBwAllowed = TRUE; ++ ++ prBssInfo->ucHtOpInfo1 = (UINT_8) ++ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); ++ ++ rlmUpdateBwByChListForAP(prAdapter, prBssInfo); ++ } ++ } ++ ++ DBGLOG(RLM, INFO, "WLAN AP SCO=%d\n", prBssInfo->eBssSCO); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_IE_OBSS_SCAN_PARAM_T prObssScanIe; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) && ++ prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) && ++ prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) { ++ ++ prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ /* Add 20/40 BSS coexistence IE */ ++ prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS; ++ prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN; ++ ++ prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell; ++ prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell; ++ prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval; ++ prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel; ++ prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel; ++ prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor; ++ prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold; ++ ++ ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P GO. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ UINT_8 ucLevel; ++ BOOLEAN fgBwChange; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ fgBwChange = FALSE; ++ ++ if (prBssInfo->eBssSCO == CHNL_EXT_SCN) ++ return fgBwChange; ++ ++ ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO); ++ ++ if (ucLevel == CHNL_LEVEL0) { ++ /* Forced to 20MHz, so extended channel is SCN and STA width is zero */ ++ prBssInfo->fgObssActionForcedTo20M = TRUE; ++ ++ if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) { ++ prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; ++ fgBwChange = TRUE; ++ } ++ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC); ++ } ++ ++ /* Clear up all channel lists */ ++ prBssInfo->auc2G_20mReqChnlList[0] = 0; ++ prBssInfo->auc2G_NonHtChnlList[0] = 0; ++ prBssInfo->auc2G_PriChnlList[0] = 0; ++ prBssInfo->auc2G_SecChnlList[0] = 0; ++ prBssInfo->auc5G_20mReqChnlList[0] = 0; ++ prBssInfo->auc5G_NonHtChnlList[0] = 0; ++ prBssInfo->auc5G_PriChnlList[0] = 0; ++ prBssInfo->auc5G_SecChnlList[0] = 0; ++ ++ return fgBwChange; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_20_40_COEXIST_FRAME prRxFrame; ++ P_IE_20_40_COEXIST_T prCoexist; ++ P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport; ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ PUINT_8 pucIE; ++ UINT_16 u2IELength, u2Offset; ++ UINT_8 i, j; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST || ++ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || ++ prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) || ++ HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != NETWORK_TYPE_P2P_INDEX) { ++ return; ++ } ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ASSERT(prBssInfo); ++ ++ if (!IS_BSS_ACTIVE(prBssInfo) || ++ prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) { ++ return; ++ } ++ ++ prCoexist = &prRxFrame->rBssCoexist; ++ if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) { ++ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel; ++ prBssInfo->auc2G_20mReqChnlList[0]++; ++ } ++ } ++ ++ /* Process intolerant channel report IE */ ++ pucIE = (PUINT_8) &prRxFrame->rChnlReport; ++ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5); ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT: ++ prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE; ++ ++ if (prChnlReport->ucLength <= 1) ++ break; ++ ++ /* To do: process regulatory class. Now we assume 2.4G band */ ++ ++ for (j = 0; j < prChnlReport->ucLength - 1; j++) { ++ /* Update non-HT channel list */ ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j]) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j]; ++ prBssInfo->auc2G_NonHtChnlList[0]++; ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++ } /* end of IE_FOR_EACH */ ++ ++ if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) { ++ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); ++ rlmSyncOperationParams(prAdapter, prBssInfo); ++ } ++ ++ /* Check if OBSS scan exemption response should be sent */ ++ if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) ++ rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH || ++ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || ++ prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) { ++ return; ++ } ++ ++ /* To do: depending regulation class 13 and 14 based on spec ++ * Note: (ucChannelWidth==1) shall restored back to original capability, ++ * not current setting to 40MHz BW here ++ */ ++ if (prRxFrame->ucChannelWidth == 0) ++ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; ++ else if (prRxFrame->ucChannelWidth == 1) ++ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prObssStatus); ++ ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex]; ++ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); ++ ++ prBssInfo->fgObssErpProtectMode = (BOOLEAN) prObssStatus->ucObssErpProtectMode; ++ prBssInfo->eObssHtProtectMode = (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode; ++ prBssInfo->eObssGfOperationMode = (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode; ++ prBssInfo->fgObssRifsOperationMode = (BOOLEAN) prObssStatus->ucObssRifsOperationMode; ++ prBssInfo->fgObssBeaconForcedTo20M = (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M; ++ ++ /* Check if Beacon content need to be updated */ ++ rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon) ++{ ++ P_LINK_T prStaList; ++ P_STA_RECORD_T prStaRec; ++ BOOLEAN fgErpProtectMode, fgSta40mIntolerant; ++ BOOLEAN fgUseShortPreamble, fgUseShortSlotTime; ++ ENUM_HT_PROTECT_MODE_T eHtProtectMode; ++ ENUM_GF_MODE_T eGfOperationMode; ++ UINT_8 ucHtOpInfo1; ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ P_GLUE_INFO_T prGlueInfo; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ++ return; ++ ++ fgErpProtectMode = FALSE; ++ eHtProtectMode = HT_PROTECT_MODE_NONE; ++ eGfOperationMode = GF_MODE_NORMAL; ++ fgSta40mIntolerant = FALSE; ++ fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; ++ fgUseShortSlotTime = TRUE; ++ ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; ++ ++ prStaList = &prBssInfo->rStaRecOfClientList; ++ ++ LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) { ++ /* ASSERT(prStaRec); */ ++ if (!prStaRec) { ++ DBGLOG(P2P, TRACE, "prStaRec is NULL in rlmUpdateParamsForAP()\n"); ++ break; ++ } ++ if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 && ++ prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) { ++ if (!(prStaRec->ucPhyTypeSet & (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) { ++ /* B-only mode, so mode 1 (ERP protection) */ ++ fgErpProtectMode = TRUE; ++ } ++ ++ if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { ++ /* BG-only or A-only */ ++ eHtProtectMode = HT_PROTECT_MODE_NON_HT; ++ } else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) { ++ /* 20MHz-only */ ++ /* ++ The HT Protection field may be set to 20 MHz protection ++ mode only if the following are true: ++ \A1X All STAs detected (by any means) in the primary channel ++ and all STAs detected (by any means) in the secondary ++ channel are HT STAs and all STAs that are members of ++ this BSS are HT STAs, and ++ \A1X This BSS is a 20/40 MHz BSS, and ++ \A1X There is at least one 20 MHz HT STA associated with this BSS. ++ */ ++ if (eHtProtectMode == HT_PROTECT_MODE_NONE && prBssInfo->fgAssoc40mBwAllowed) ++ eHtProtectMode = HT_PROTECT_MODE_20M; ++ } ++ ++ if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) ++ eGfOperationMode = GF_MODE_PROTECT; ++ ++ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) ++ fgUseShortPreamble = FALSE; ++ ++ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) ++ fgUseShortSlotTime = FALSE; ++ ++ if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) ++ fgSta40mIntolerant = TRUE; ++ } ++ } /* end of LINK_FOR_EACH_ENTRY */ ++ ++ /* Check if HT operation IE about 20/40M bandwidth shall be updated */ ++ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { ++ if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant && ++ !prBssInfo->fgObssActionForcedTo20M && !prBssInfo->fgObssBeaconForcedTo20M) { ++ ++ ucHtOpInfo1 = (UINT_8) ++ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); ++ } ++ } ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ prGlueInfo = prAdapter->prGlueInfo; ++ if (prGlueInfo->prP2PInfo->u4PsLevel & BITS(8, 15)) ++ fgErpProtectMode = TRUE; ++#endif ++ ++ /* Check if any new parameter may be updated */ ++ if (prBssInfo->fgErpProtectMode != fgErpProtectMode || ++ prBssInfo->eHtProtectMode != eHtProtectMode || ++ prBssInfo->eGfOperationMode != eGfOperationMode || ++ prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 || ++ prBssInfo->fgUseShortPreamble != fgUseShortPreamble || ++ prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) { ++ ++ prBssInfo->fgErpProtectMode = fgErpProtectMode; ++ prBssInfo->eHtProtectMode = eHtProtectMode; ++ prBssInfo->eGfOperationMode = eGfOperationMode; ++ prBssInfo->ucHtOpInfo1 = ucHtOpInfo1; ++ prBssInfo->fgUseShortPreamble = fgUseShortPreamble; ++ prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime; ++ ++ if (fgUseShortSlotTime) ++ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; ++ else ++ prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; ++ ++ rlmSyncOperationParams(prAdapter, prBssInfo); ++ fgUpdateBeacon = TRUE; ++ } ++ ++ /* Update Beacon content if related IE content is changed */ ++ if (fgUpdateBeacon) ++ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Initial the channel list from the domain information. ++* This function is called after P2P initial and Domain information changed. ++* Make sure the device is disconnected while changing domain information. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return boolean value if probe response frame is ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY) NULL; ++ P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO) NULL; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ UINT_32 u4Idx = 0, u4IdxII = 0; ++ UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE; ++#if 0 ++ UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0; ++#endif ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++#if 0 ++ ucAutoChnl = prP2pConnSetting->ucOperatingChnl; ++#endif ++ ++ prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter); ++ ++ ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL)); ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) { ++ prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx]; ++ ++ if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) || ++ (prDomainSubBand->ucBand == BAND_NULL)) { ++ continue; ++ } ++ ++ if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) { ++ /* Buffer is not enough to include all supported channels. */ ++ break; /* for */ ++ } ++ ++ prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass; ++ prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels; ++ ++ for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) { ++ prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum + ++ (u4IdxII * prDomainSubBand->ucChannelSpan); ++ ++#if 0 ++ switch (prChannelEntryField->aucChannelList[u4IdxII]) { ++ case 1: ++ ucSocialChnlSupport = 1; ++ break; ++ case 6: ++ ucSocialChnlSupport = 6; ++ break; ++ case 11: ++ ucSocialChnlSupport = 11; ++ break; ++ default: ++ break; ++ } ++ ++#endif ++ } ++ ++ if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels)) ++ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); ++ else ++ break; ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) ++ prChannelEntryField->ucNumberOfChannels); ++ ++ } ++ ++#if 0 ++ if (prP2pConnSetting->ucListenChnl == 0) { ++ prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL; ++ ++ if (ucSocialChnlSupport != 0) { ++ /* 1. User Not Set LISTEN channel. ++ * 2. Social channel is not empty. ++ */ ++ prP2pConnSetting->ucListenChnl = ucSocialChnlSupport; ++ } ++ } ++#endif ++ ++ /* TODO: 20110921 frog - */ ++ /* If LISTEN channel is not set, ++ * a random supported channel would be set. ++ * If no social channel is supported, DEFAULT channel would be set. ++ */ ++ ++ prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize; ++ ++#if 0 ++ if (prP2pConnSetting->ucOperatingChnl == 0) { /* User not set OPERATE channel. */ ++ ++ if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) ++ break; /* while */ ++ ++ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ while (ucBufferSize != 0) { ++ if (prChannelEntryField->ucNumberOfChannels != 0) { ++ ucAutoChnl = prChannelEntryField->aucChannelList[0]; ++ break; /* while */ ++ } ++ ++ else { ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((UINT_32) prChannelEntryField + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (UINT_32)prChannelEntryField->ucNumberOfChannels); ++ ++ ucBufferSize -= ++ (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); ++ } ++ ++ } ++ ++ } ++#endif ++ /* We assume user would not set a channel not in the channel list. ++ * If so, the operating channel still depends on target device supporting capability. ++ */ ++ ++ /* TODO: 20110921 frog - */ ++ /* If the Operating channel is not set, a channel from supported channel list is set automatically. ++ * If there is no supported channel in channel list, a DEFAULT channel is set. ++ */ ++ ++ } while (FALSE); ++ ++#if 0 ++ prP2pConnSetting->ucOperatingChnl = ucAutoChnl; ++#endif ++ ++} /* rlmFuncInitialChannelList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find a common channel list from the local channel list info & target channel list info. ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return boolean value if probe response frame is ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, ++ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize) ++{ ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) NULL, prChannelEntryIII = ++ (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE] = {0}; ++ UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0; ++ ++ do { ++ ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) aucCommonChannelList; ++ ++ while (ucChannelListSize > 0) { ++ ++ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize; ++ ++ while (ucOriChnlSize > 0) { ++ if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) { ++ prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass; ++ /* TODO: Currently we assume that the regulatory class the same, ++ * the channels are the same. */ ++ kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList, ++ prChannelEntryII->ucNumberOfChannels); ++ prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels; ++ ++ ucNewChnlSize += ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels; ++ ++ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryIII + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG)prChannelEntryIII->ucNumberOfChannels); ++ } ++ ++ ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels); ++ ++ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryI + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) ++ prChannelEntryI->ucNumberOfChannels); ++ ++ } ++ ++ ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels); ++ ++ prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryII + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) prChannelEntryII->ucNumberOfChannels); ++ ++ } ++ ++ kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize); ++ prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize; ++ ++ } while (FALSE); ++ ++} /* rlmFuncCommonChannelList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum) ++{ ++ UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ UINT_32 u4Idx = 0; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ while (ucBufferSize != 0) { ++ ++ for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) { ++ if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) { ++ ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass; ++ break; ++ } ++ ++ } ++ ++ if (ucRegulatoryClass != 0) ++ break; /* while */ ++ ++ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG)prChannelEntryField->ucNumberOfChannels); ++ ++ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); ++ ++ } ++ ++ } while (FALSE); ++ ++ return ucRegulatoryClass; ++} /* rlmFuncFindOperatingClass */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucCheckChnl, ++ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel) ++{ ++ BOOLEAN fgIsResultAvailable = FALSE; ++ P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0; ++ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ if (fgIsDefaultChannel) ++ ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL; ++ ++ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; ++ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; ++ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; ++ ++ while ((ucBufferSize != 0) && (!fgIsResultAvailable)) { ++ ++ for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) { ++ if ((!fgIsSocialChannel) || ++ (prChannelEntry->aucChannelList[ucIdx] == 1) || ++ (prChannelEntry->aucChannelList[ucIdx] == 6) || ++ (prChannelEntry->aucChannelList[ucIdx] == 11)) { ++ ++ if (prChannelEntry->aucChannelList[ucIdx] <= 11) { ++ /* 2.4G. */ ++ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; ++ } else if ((prChannelEntry->aucChannelList[ucIdx] < 52) && ++ (prChannelEntry->aucChannelList[ucIdx] > 14)) { ++ /* 2.4G + 5G. */ ++ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; ++ } ++ ++ if (ucChannelSelected == ucCheckChnl) { ++ fgIsResultAvailable = TRUE; ++ break; ++ } ++ } ++ ++ } ++ ++ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels); ++ ++ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntry + ++ P2P_ATTRI_LEN_CHANNEL_ENTRY + ++ (ULONG) prChannelEntry->ucNumberOfChannels); ++ ++ } ++ ++ if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) { ++ DBGLOG(P2P, TRACE, ++ "The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl, ++ ucChannelSelected); ++ /* Given a suggested channel. */ ++ *pucSuggestChannel = ucChannelSelected; ++ } ++ ++ } while (FALSE); ++ ++ return fgIsResultAvailable; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ P_DOMAIN_SUBBAND_INFO prSubband; ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ UINT_8 ucSecondChannel, i, j; ++ ENUM_CHNL_EXT_T eSCO; ++ ++ eSCO = CHNL_EXT_SCN; ++ ++ if (prBssInfo->eBand == BAND_2G4) { ++ if (prBssInfo->ucPrimaryChannel != 14) ++ eSCO = (prBssInfo->ucPrimaryChannel > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA; ++ } else { ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubband = &prDomainInfo->rSubBand[i]; ++ if (prSubband->ucBand == prBssInfo->eBand) { ++ for (j = 0; j < prSubband->ucNumChannels; j++) { ++ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) ++ == prBssInfo->ucPrimaryChannel) { ++ eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA; ++ break; ++ } ++ } ++ ++ if (j < prSubband->ucNumChannels) ++ break; /* Found */ ++ } ++ } ++ } ++ ++ /* Check if it is boundary channel and 40MHz BW is permitted */ ++ if (eSCO != CHNL_EXT_SCN) { ++ ucSecondChannel = (eSCO == CHNL_EXT_SCA) ? ++ (prBssInfo->ucPrimaryChannel + 4) : (prBssInfo->ucPrimaryChannel - 4); ++ ++ if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel)) ++ eSCO = CHNL_EXT_SCN; ++ } ++ ++ return eSCO; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c +new file mode 100644 +index 000000000000..154f1e5db0f7 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c +@@ -0,0 +1,313 @@ ++/* ++** Id: @(#) gl_p2p_cfg80211.c@@ ++*/ ++ ++/*! \file gl_p2p_cfg80211.c ++ \brief Main routines of Linux driver interface for Wi-Fi Direct ++ using cfg80211 interface ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Different concurrent network has itself channel lists, and ++* concurrent networks should have been recorded in channel lists. ++* If role of active P2P is GO, assume associated AP of AIS will ++* record our Beacon for P2P GO because of same channel. ++* ++* Note: If we have scenario of different channel in the future, ++* the internal FW communication channel shall be established. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 ucChannelLevel; ++ ++ ASSERT(prBssInfo); ++ ++ if (eBand == BAND_2G4) { ++ ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend); ++ ++ /* (TBD) If concurrent networks permit different channel, extra ++ * channel judgement should be added. Please refer to ++ * previous version of this file. ++ */ ++ } else if (eBand == BAND_5G) { ++ ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend); ++ ++ /* (TBD) If concurrent networks permit different channel, extra ++ * channel judgement should be added. Please refer to ++ * previous version of this file. ++ */ ++ } else { ++ ucChannelLevel = CHNL_LEVEL0; ++ } ++ ++ return ucChannelLevel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 i, ucChannelLevel; ++ UINT_8 ucSecChannel, ucCenterChannel; ++ UINT_8 ucAffectedChnl_L, ucAffectedChnl_H; ++ ++ ASSERT(prBssInfo); ++ ++ ucChannelLevel = CHNL_LEVEL2; ++ ++ /* Calculate center channel for 2.4G band */ ++ if (eExtend == CHNL_EXT_SCA) { ++ ucCenterChannel = ucPriChannel + 2; ++ ucSecChannel = ucPriChannel + 4; ++ } else if (eExtend == CHNL_EXT_SCB) { ++ ucCenterChannel = ucPriChannel - 2; ++ ucSecChannel = ucPriChannel - 4; ++ } else { ++ return CHNL_LEVEL0; ++ } ++ ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14); ++ ++ /* Calculated low/upper channels in affected freq range */ ++ ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ? 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET); ++ ++ ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ? ++ 14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET); ++ ++ /* Check intolerant (Non-HT) channel list */ ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) && ++ prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++ /* Check 20M BW request channel list */ ++ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++ /* Check 2.4G primary channel list */ ++ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) && ++ prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++ /* Check 2.4G secondary channel list */ ++ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L && ++ prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) && ++ prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_2G4_level_end; ++ } ++ } ++ ++L_2G4_level_end: ++ ++ return ucChannelLevel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 i, ucChannelLevel; ++ UINT_8 ucSecChannel; ++ ++ ASSERT(prBssInfo); ++ ++ ucChannelLevel = CHNL_LEVEL2; ++ ++ /* Calculate center channel for 2.4G band */ ++ if (eExtend == CHNL_EXT_SCA) ++ ucSecChannel = ucPriChannel + 4; ++ else if (eExtend == CHNL_EXT_SCB) ++ ucSecChannel = ucPriChannel - 4; ++ else ++ return CHNL_LEVEL0; ++ ASSERT(ucSecChannel >= 36); ++ ++ /* Check 5G primary channel list */ ++ ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G); ++ for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { ++ if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_5G_level_end; ++ } else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) { ++ ucChannelLevel = CHNL_LEVEL1; ++ } ++ } ++ ++ /* Check non-HT channel list */ ++ ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G); ++ for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { ++ if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_5G_level_end; ++ } else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) { ++ ucChannelLevel = CHNL_LEVEL1; ++ } ++ } ++ ++ /* Check secondary channel list */ ++ ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G); ++ for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { ++ if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) { ++ ++ ucChannelLevel = CHNL_LEVEL0; ++ goto L_5G_level_end; ++ } ++ } ++ ++L_5G_level_end: ++ ++ return ucChannelLevel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_20_40_COEXIST_FRAME prTxFrame; ++ ++ /* To do: need an algorithm to do judgement. Now always reject request */ ++ ++ prMsduInfo = (P_MSDU_INFO_T)cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); ++ if (prMsduInfo == NULL) ++ return; ++ ++ DBGLOG(RLM, INFO, "Send 20/40 coexistence rsp frame!\n"); ++ ++ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket; ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; ++ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; ++ ++ /* To do: find correct algorithm */ ++ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; ++ prTxFrame->rBssCoexist.ucLength = 1; ++ prTxFrame->rBssCoexist.ucData = 0; ++ ++ ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN); ++ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfo->ucStaRecIndex = prSwRfb->ucStaRecIdx; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* Send them to HW queue */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c +new file mode 100644 +index 000000000000..b5bd23965fe3 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c +@@ -0,0 +1,756 @@ ++/* ++** Id: @(#) p2p_scan.c@@ ++*/ ++ ++/*! \file "p2p_scan.c" ++ \brief This file defines the p2p scan profile and the processing function of ++ scan result for SCAN Module. ++ ++ The SCAN Profile selection is part of SCAN MODULE and responsible for defining ++ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. ++ In this file we also define the process of SCAN Result including adding, searching ++ and removing SCAN record from the list. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++P_P2P_DEVICE_DESC_T ++scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc) ++{ ++ ++ P_P2P_DEVICE_DESC_T prTargetP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucDeviceID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* 4 <1> The outer loop to search for a candidate. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ /* Loop for each prBssDesc */ ++ prTargetP2pDesc = scanFindP2pDeviceDesc(prAdapter, prBssDesc, aucDeviceID, TRUE, FALSE); ++ ++ if (prTargetP2pDesc != NULL) ++ break; ++ } ++ ++ if ((pprBssDesc) && (prTargetP2pDesc != NULL)) { ++ /* Only valid if prTargetP2pDesc is not NULL. */ ++ *pprBssDesc = prBssDesc; ++ } ++ ++ return prTargetP2pDesc; ++} /* scanSearchTargetP2pDesc */ ++ ++VOID scanInvalidAllP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ ++ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ if (prTargetDesc->fgDevInfoValid) ++ prTargetDesc->fgDevInfoValid = FALSE; ++ } ++ ++} /* scanRenewP2pClientDevice */ ++ ++VOID scanRemoveInvalidP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL, prNexEntry = (P_LINK_ENTRY_T) NULL; ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ LINK_FOR_EACH_SAFE(prLinkEntry, prNexEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ if (!prTargetDesc->fgDevInfoValid) { ++ LINK_REMOVE_KNOWN_ENTRY(&prBssDesc->rP2pDeviceList, prLinkEntry); ++ if ((prP2pConnSettings) && (prP2pConnSettings->prTargetP2pDesc == prTargetDesc)) ++ prP2pConnSettings->prTargetP2pDesc = NULL; ++ kalMemFree(prTargetDesc, VIR_MEM_TYPE, sizeof(P2P_DEVICE_DESC_T)); ++ } ++ } ++ ++} /* scanRenewP2pClientDevice */ ++ ++P_P2P_DEVICE_DESC_T ++scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, ++ IN P_BSS_DESC_T prBssDesc, ++ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound) ++{ ++ ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prBssDesc != NULL) && (aucMacAddr != NULL)); ++ ++ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ if (fgIsDeviceAddr) { ++ if (EQUAL_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr)) ++ break; ++ } else { ++ if (EQUAL_MAC_ADDR(prTargetDesc->aucInterfaceAddr, aucMacAddr)) ++ break; ++ } ++ ++ prTargetDesc = NULL; ++ } ++ ++ if ((fgAddIfNoFound) && (prTargetDesc == NULL)) { ++ /* Target Not Found. */ ++ /* TODO: Use memory pool in the future. */ ++ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); ++ ++ if (prTargetDesc) { ++ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); ++ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); ++ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr); ++ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); ++ prTargetDesc->fgDevInfoValid = TRUE; ++ } else { ++ ASSERT(FALSE); ++ } ++ } ++ ++ } while (FALSE); ++ ++ return prTargetDesc; ++} /* scanFindP2pDeviceDesc */ ++ ++P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssDesc); ++ ++ if (prBssDesc->prP2pDesc == NULL) { ++ ++ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); ++ ++ if (prTargetDesc) { ++ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); ++ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); ++ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); ++ prTargetDesc->fgDevInfoValid = TRUE; ++ prBssDesc->prP2pDesc = prTargetDesc; ++ /* We are not sure the SrcAddr is Device Address or Interface Address. */ ++ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, prBssDesc->aucSrcAddr); ++ COPY_MAC_ADDR(prTargetDesc->aucInterfaceAddr, prBssDesc->aucSrcAddr); ++ } else { ++ ++ ASSERT(FALSE); ++ } ++ } else { ++ prTargetDesc = prBssDesc->prP2pDesc; ++ } ++ ++ return prTargetDesc; ++ ++} /* scanFindP2pDeviceDesc */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. ++* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_P2P_DEVICE_DESC_T prP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; ++ UINT_16 u2AttributeLen = 0; ++ UINT_32 u4Idx = 0; ++ BOOLEAN fgUpdateDevInfo = FALSE; ++ ++ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; ++ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; ++ ++ ASSERT(prAdapter); ++ ++ prP2pDesc = scanGetP2pDeviceDesc(prAdapter, prBssDesc); ++ ++ if (!prP2pDesc) { ++ ASSERT(FALSE); ++ return fgUpdateDevInfo; ++ } ++ ++ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, ++ &u2AttributeLen); ++ ++ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { ++ switch (prP2pAttribute->ucId) { ++ case P2P_ATTRI_ID_P2P_CAPABILITY: /* Beacon, Probe Response */ ++ { ++ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; ++ ++ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; ++ ASSERT(prP2pAttriCapability->u2Length == 2); ++ ++ prP2pDesc->ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; ++ prP2pDesc->ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_ID: /* Beacon */ ++ { ++ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; ++ ++ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; ++ ASSERT(prP2pAttriDevID->u2Length == P2P_ATTRI_MAX_LEN_P2P_DEV_ID); ++ ++ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_INFO: /* Probe Response */ ++ { ++ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ UINT_16 u2NameLen = 0, u2Id = 0; ++ ++ fgUpdateDevInfo = TRUE; ++ ++ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; ++ ++ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN); ++ ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); ++ ++ prP2pDevType = &prP2pDesc->rPriDevType; ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ ++ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= ++ P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); ++ /* TODO: Fixme if secondary device type is more than 2. */ ++ prP2pDesc->ucSecDevTypeNum = 0; ++ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { ++ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { ++ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> ++ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> ++ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ prP2pDesc->ucSecDevTypeNum++; ++ } ++ ++ } ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) ((PUINT_8) prP2pAttriDevInfo->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &u2NameLen); ++ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Id, &u2Id); ++ ASSERT(u2Id == WPS_ATTRI_ID_DEVICE_NAME); ++ if (u2NameLen > WPS_ATTRI_MAX_LEN_DEVICE_NAME) ++ u2NameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; ++ prP2pDesc->u2NameLength = u2NameLen; ++ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_GROUP_INFO: /* Probe Response */ ++ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; ++ break; ++ case P2P_ATTRI_ID_NOTICE_OF_ABSENCE: ++ break; ++ case P2P_ATTRI_ID_EXT_LISTEN_TIMING: ++ /* TODO: Not implement yet. */ ++ /* ASSERT(FALSE); */ ++ break; ++ default: ++ break; ++ } ++ ++ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); ++ ++ prP2pAttribute = ++ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); ++ ++ } ++ ++ if (prP2pAttriGroupInfo != NULL) { ++ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ ++ scanInvalidAllP2pClientDevice(prAdapter, prBssDesc); ++ ++ /* GO/Device itself. */ ++ prP2pDesc->fgDevInfoValid = TRUE; ++ ++ prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) prP2pAttriGroupInfo->arClientDesc; ++ u2AttributeLen = prP2pAttriGroupInfo->u2Length; ++ ++ while (u2AttributeLen > 0) { ++ prP2pDesc = ++ scanFindP2pDeviceDesc(prAdapter, prBssDesc, prClientInfoDesc->aucDevAddr, TRUE, TRUE); ++ ++ if (!prP2pDesc) { ++ ASSERT(FALSE); ++ break; /* while */ ++ } ++ ++ prP2pDesc->fgDevInfoValid = TRUE; ++ ++ /* Basic size for P2P client info descriptor. */ ++ ASSERT(u2AttributeLen >= 25); ++ if (u2AttributeLen < 25) { ++ DBGLOG(P2P, WARN, "Length incorrect warning.\n"); ++ break; ++ } ++ COPY_MAC_ADDR(prP2pDesc->aucInterfaceAddr, prClientInfoDesc->aucIfAddr); ++ ++ prP2pDesc->ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; ++ ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); ++ ++ prP2pDevType = &(prP2pDesc->rPriDevType); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ ++ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); ++ prP2pDesc->ucSecDevTypeNum = 0; ++ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { ++ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { ++ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> ++ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, ++ &prP2pDevType->u2CategoryID); ++ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> ++ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, ++ &prP2pDevType->u2SubCategoryID); ++ prP2pDesc->ucSecDevTypeNum++; ++ } ++ ++ } ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &prP2pDesc->u2NameLength); ++ if (prP2pDesc->u2NameLength > WPS_ATTRI_MAX_LEN_DEVICE_NAME) ++ prP2pDesc->u2NameLength = WPS_ATTRI_MAX_LEN_DEVICE_NAME; ++ ++ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); ++ ++ u2AttributeLen -= (prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN); ++ prClientInfoDesc = ++ (P_P2P_CLIENT_INFO_DESC_T) ((UINT_32) prClientInfoDesc + ++ (UINT_32) prClientInfoDesc->ucLength + ++ P2P_CLIENT_INFO_DESC_HDR_LEN); ++ } ++ ++ scanRemoveInvalidP2pClientDevice(prAdapter, prBssDesc); ++ } ++ ++ return fgUpdateDevInfo; ++} /* end of scanAddP2pDeviceInfo() */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. ++* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) ++{ ++ EVENT_P2P_DEV_DISCOVER_RESULT_T rEventDevInfo; ++#if 1 ++ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; ++ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; ++ ++ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { ++ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); ++ ++ COPY_MAC_ADDR(rEventDevInfo.aucDeviceAddr, prTargetDesc->aucDeviceAddr); ++ COPY_MAC_ADDR(rEventDevInfo.aucInterfaceAddr, prTargetDesc->aucInterfaceAddr); ++ ++ rEventDevInfo.ucDeviceCapabilityBitmap = prTargetDesc->ucDeviceCapabilityBitmap; ++ rEventDevInfo.ucGroupCapabilityBitmap = prTargetDesc->ucGroupCapabilityBitmap; ++ rEventDevInfo.u2ConfigMethod = prTargetDesc->u2ConfigMethod; ++ ++ kalMemCopy(&rEventDevInfo.rPriDevType, &prTargetDesc->rPriDevType, sizeof(P2P_DEVICE_TYPE_T)); ++ ++ kalMemCopy(rEventDevInfo.arSecDevType, ++ prTargetDesc->arSecDevType, (prTargetDesc->ucSecDevTypeNum * sizeof(P2P_DEVICE_TYPE_T))); ++ ++ rEventDevInfo.ucSecDevTypeNum = prTargetDesc->ucSecDevTypeNum; ++ ++ rEventDevInfo.u2NameLength = prTargetDesc->u2NameLength; ++ kalMemCopy(rEventDevInfo.aucName, prTargetDesc->aucName, prTargetDesc->u2NameLength); ++ ++ COPY_MAC_ADDR(rEventDevInfo.aucBSSID, prBssDesc->aucBSSID); ++ ++ if (prTargetDesc == prBssDesc->prP2pDesc) ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, prBssDesc->aucIEBuf, prBssDesc->u2IELength); ++ else ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, NULL, 0); ++ } ++ ++ kalP2PIndicateFound(prAdapter->prGlueInfo); ++ ++#else ++ ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; ++ UINT_16 u2AttributeLen = 0; ++ UINT_32 u4Idx = 0; ++ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; ++ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; ++ ++ ASSERT(prAdapter); ++ ++ prP2pSpecificBssInfo = &prAdapter->rWifiVar.rP2pSpecificBssInfo; ++ ++#if 1 ++ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, ++ &u2AttributeLen); ++#else ++ prP2pAttribute = (P_P2P_ATTRIBUTE_T) &prP2pSpecificBssInfo->aucAttributesCache[0]; ++ u2AttributeLen = prP2pSpecificBssInfo->u2AttributeLen; ++#endif ++ rEventDevInfo.fgDevInfoValid = FALSE; ++ ++ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { ++ switch (prP2pAttribute->ucId) { ++ case P2P_ATTRI_ID_P2P_CAPABILITY: ++ { ++ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; ++ ++ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; ++ ASSERT(prP2pAttriCapability->u2Length == 2); ++ rEventDevInfo.ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; ++ rEventDevInfo.ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_ID: ++ { ++ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; ++ ++ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; ++ ASSERT(prP2pAttriDevID->u2Length == 6); ++ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_DEV_INFO: ++ { ++ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ ++ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; ++ rEventDevInfo.fgDevInfoValid = TRUE; ++ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevInfo->aucDevAddr, ++ MAC_ADDR_LEN); ++ rEventDevInfo.u2ConfigMethod = prP2pAttriDevInfo->u2ConfigMethodsBE; ++ ++ prP2pDevType = &rEventDevInfo.rPriDevType; ++ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; ++ prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; ++ ++ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= 2); ++ /* TODO: Fixme if secondary device type is more than 2. */ ++ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { ++ /* TODO: Current sub device type can only support 2. */ ++ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; ++ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; ++ prP2pDevType->u2SubCategoryID = ++ prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; ++ } ++ ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) (prP2pAttriDevInfo->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ ASSERT(prP2pDevName->u2Id == 0x1011); ++ ASSERT(prP2pDevName->u2Length <= 32); ++ /* TODO: Fixme if device name length is longer than 32 bytes. */ ++ kalMemCopy(rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); ++ } ++ break; ++ case P2P_ATTRI_ID_P2P_GROUP_INFO: ++ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; ++ break; ++ } ++ ++ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); ++ ++ prP2pAttribute = ++ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); ++ ++ } ++ ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); ++ ++ if (prP2pAttriGroupInfo != NULL) { ++ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; ++ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; ++ ++ prClientInfoDesc = prP2pAttriGroupInfo->arClientDesc; ++ u2AttributeLen = prP2pAttriGroupInfo->u2Length; ++ ++ while (u2AttributeLen > 0) { ++ /* Basic size for P2P client info descriptor. */ ++ ASSERT(u2AttributeLen >= 25); ++ rEventDevInfo.fgDevInfoValid = TRUE; ++ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prClientInfoDesc->aucIfAddr, MAC_ADDR_LEN); ++ rEventDevInfo.ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; ++ rEventDevInfo.u2ConfigMethod = prClientInfoDesc->u2ConfigMethodsBE; ++ ++ prP2pDevType = &rEventDevInfo.rPriDevType; ++ prP2pDevType->u2CategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId; ++ prP2pDevType->u2SubCategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId; ++ ++ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= 2); ++ /* TODO: Fixme if secondary device type is more than 2. */ ++ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { ++ /* TODO: Current sub device type can only support 2. */ ++ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; ++ prP2pDevType->u2CategoryID = ++ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId; ++ prP2pDevType->u2SubCategoryID = ++ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId; ++ } ++ ++ prP2pDevName = ++ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + ++ (u4Idx * sizeof(DEVICE_TYPE_T))); ++ ASSERT(prP2pDevName->u2Id == 0x1011); ++ ASSERT(prP2pDevName->u2Length <= 32); ++ /* TODO: Fixme if device name length is longer than 32 bytes. */ ++ kalMemCopy(&rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); ++ ++ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); ++ ++ u2AttributeLen -= prP2pAttriGroupInfo->u2Length; ++ prP2pAttriGroupInfo = prP2pAttriGroupInfo + prP2pAttriGroupInfo->u2Length + 1; ++ } ++ ++ } ++#endif ++ return WLAN_STATUS_SUCCESS; ++} /* scanSendDeviceDiscoverEvent */ ++ ++VOID ++scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, ++ IN P_WLAN_STATUS prStatus, ++ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame) ++{ ++ BOOLEAN fgIsSkipThisBeacon; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ fgIsSkipThisBeacon = FALSE; ++ if (prBssDesc->fgIsP2PPresent) { ++ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && /* P2P GC */ ++ (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && /* Connected */ ++ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { /* TX Beacon */ ++ ++ fgIsSkipThisBeacon = TRUE; ++ } ++ ++ if ((!prP2pBssInfo->ucDTIMPeriod) && /* First time. */ ++ fgIsSkipThisBeacon && (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, ++ prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen))) { /* SSID Match */ ++ prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++ ++ do { ++ RF_CHANNEL_INFO_T rChannelInfo; ++ ++ ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL)); ++ ++ if (((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_PROBE_RSP)) { ++ /* Only report Probe Response frame to supplicant. */ ++ /* Probe response collect much more information. */ ++ ++ if (fgIsSkipThisBeacon || prBssDesc->eBand == BAND_2G4) ++ break; ++ } ++ ++ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; ++ rChannelInfo.eBand = prBssDesc->eBand; ++ prBssDesc->fgIsP2PReport = TRUE; ++ ++ DBGLOG(P2P, INFO, "indicate %s [%d]\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prSwRfb->pvHeader, ++ (UINT_32) prSwRfb->u2PacketLen, ++ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ ++ } while (FALSE); ++ } ++} ++ ++VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum) ++{ ++ ++ CMD_SCAN_CANCEL rCmdScanCancel; ++ ++ /* send cancel message to firmware domain */ ++ rCmdScanCancel.ucSeqNum = ucScnSeqNum; ++ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_CANCEL, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8)&rCmdScanCancel, NULL, 0); ++ ++} /* scnEventReturnChannel */ ++ ++VOID scanRemoveAllP2pBssDesc(IN P_ADAPTER_T prAdapter) ++{ ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prBSSDescNext; ++ ++ ASSERT(prAdapter); ++ ++ prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ scanRemoveP2pBssDesc(prAdapter, prBssDesc); ++ } ++} /* scanRemoveAllP2pBssDesc */ ++ ++VOID scanRemoveP2pBssDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ ++ ++} /* scanRemoveP2pBssDesc */ ++ ++P_BSS_DESC_T ++scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo) ++{ ++ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL, prBssDesc = (P_BSS_DESC_T) NULL; ++ P_LINK_T prBssDescList = (P_LINK_T) NULL; ++ ++ do { ++ if ((prAdapter == NULL) || (prP2pBssInfo == NULL) || (prConnReqInfo == NULL)) ++ break; ++ ++ prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); ++ ++ DBGLOG(P2P, LOUD, "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); ++ DBGLOG(P2P, LOUD, "Connecting to SSID:%s, length:%d\n", ++ prConnReqInfo->rSsidStruct.aucSsid, prConnReqInfo->rSsidStruct.ucSsidLen); ++ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, rLinkEntry, BSS_DESC_T) { ++ DBGLOG(P2P, LOUD, "Checking BSS: %pM\n", prBssDesc->aucBSSID); ++ ++ if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) { ++ DBGLOG(P2P, LOUD, "Ignore mismatch BSS type.\n"); ++ continue; ++ } ++ ++ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnReqInfo->aucBssid)) { ++ DBGLOG(P2P, LOUD, "Ignore mismatch BSSID.\n"); ++ continue; ++ } ++ ++ /* SSID should be the same? SSID is vary for each connection. so... */ ++ if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid, ++ prConnReqInfo->rSsidStruct.ucSsidLen, ++ prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) { ++ ++ DBGLOG(P2P, TRACE, ++ "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); ++ DBGLOG(P2P, TRACE, ++ "Connecting to SSID:%s, length:%d\n", prConnReqInfo->rSsidStruct.aucSsid, ++ prConnReqInfo->rSsidStruct.ucSsidLen); ++ DBGLOG(P2P, TRACE, ++ "Checking SSID:%s, length:%d\n", prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ DBGLOG(P2P, TRACE, "Ignore mismatch SSID, (But BSSID match).\n"); ++ ASSERT(FALSE); ++ continue; ++ } ++ ++ if (!prBssDesc->fgIsP2PPresent) { ++ DBGLOG(P2P, ERROR, "SSID, BSSID, BSSTYPE match, but no P2P IE present.\n"); ++ continue; ++ } ++ ++ /* Final decision. */ ++ prCandidateBssDesc = prBssDesc; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return prCandidateBssDesc; ++} /* scanP2pSearchDesc */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c +new file mode 100644 +index 000000000000..befb9978f473 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c +@@ -0,0 +1,466 @@ ++#include "p2p_precomp.h" ++ ++BOOLEAN ++p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState) ++{ ++ BOOLEAN fgIsTransOut = FALSE; ++/* P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL; */ ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (peNextState != NULL)); ++ ++ if ((prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) ++ && IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ fgIsTransOut = TRUE; ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; ++ ++ DBGLOG(P2P, INFO, "p2pStateInit_IDLE GO Scan\n"); ++ *peNextState = P2P_STATE_REQING_CHANNEL; ++ ++ } else { ++#if 0 ++ else ++ if (IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { ++ ++ ASSERT((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || ++ (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)); ++ ++ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ if (prChnlReqInfo->fgIsChannelRequested) { ++ /* Start a timer for return channel. */ ++ DBGLOG(P2P, TRACE, "start a GO channel timer.\n"); ++ } ++ ++ } ++#endif ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), 5000); ++ } ++ ++ } while (FALSE); ++ ++ return fgIsTransOut; ++} /* p2pStateInit_IDLE */ ++ ++VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; ++ ++ if (prChnlReqInfo->fgIsChannelRequested) { ++ /* Release channel before timeout. */ ++ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); ++ } ++ ++ /* Stop timer for leaving this state. */ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ ++ } while (FALSE); ++ ++} /* p2pStateAbort_IDLE */ ++ ++VOID p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ /* Store the original channel info. */ ++ prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; ++ prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; ++ prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; ++ ++ /* RX Probe Request would check primary channel. */ ++ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; ++ prP2pBssInfo->eBand = prChnlReqInfo->eBand; ++ prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; ++ ++ DBGLOG(P2P, TRACE, "start a channel on hand timer.\n"); ++ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING) { ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), ++ prChnlReqInfo->u4MaxInterval); ++ ++ kalP2PIndicateChannelReady(prAdapter->prGlueInfo, ++ prChnlReqInfo->u8Cookie, ++ prChnlReqInfo->ucReqChnlNum, ++ prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval); ++ } else ++ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), ++ (P2P_EXT_LISTEN_TIME_MS - prChnlReqInfo->u4MaxInterval)); ++ } while (FALSE); ++ ++} /* p2pStateInit_CHNL_ON_HAND */ ++ ++VOID ++p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ ++ /* Restore the original channel info. */ ++ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum; ++ prP2pBssInfo->eBand = prChnlReqInfo->eOriBand; ++ prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco; ++ ++ DBGLOG(P2P, INFO, "p2p state trans abort chann on hand, eListenExted: %d, eNextState: %d\n", ++ prP2pFsmInfo->eListenExted, eNextState); ++ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING || ++ eNextState != P2P_STATE_CHNL_ON_HAND) { ++ /* Here maybe have a bug, when it's extlistening, a new remain_on_channel ++ was sent to driver? need to verify */ ++ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; ++ /* Indicate channel return. */ ++ kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo); ++ ++ /* Return Channel. */ ++ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ } ++ ++ } while (FALSE); ++} /* p2pStateAbort_CHNL_ON_HAND */ ++ ++VOID ++p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (eNextState < P2P_STATE_NUM)); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ if (eNextState == P2P_STATE_IDLE) { ++ if (prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) { ++ /* Intend to be AP. */ ++ /* Setup for AP mode. */ ++ p2pFuncStartGO(prAdapter, ++ prP2pBssInfo, ++ prP2pSpecificBssInfo->aucGroupSsid, ++ prP2pSpecificBssInfo->u2GroupSsidLen, ++ prP2pSpecificBssInfo->ucPreferredChannel, ++ prP2pSpecificBssInfo->eRfBand, ++ prP2pSpecificBssInfo->eRfSco, prP2pFsmInfo->fgIsApMode); ++ ++ } else { ++ /* Return Channel. */ ++ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ } ++ ++ } ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_AP_CHANNEL_DETECT */ ++ ++VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); ++ ++ prScanReqInfo->eScanType = SCAN_TYPE_PASSIVE_SCAN; ++ prScanReqInfo->eChannelSet = SCAN_CHANNEL_2G4; ++ prScanReqInfo->u2PassiveDewellTime = 50; /* 50ms for passive channel load detection */ ++ prScanReqInfo->fgIsAbort = TRUE; ++ prScanReqInfo->fgIsScanRequest = TRUE; ++ prScanReqInfo->ucNumChannelList = 0; ++ prScanReqInfo->u4BufLength = 0; ++ prScanReqInfo->rSsidStruct.ucSsidLen = 0; ++ ++ p2pFuncRequestScan(prAdapter, prScanReqInfo); ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_AP_CHANNEL_DETECT */ ++ ++VOID ++p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ++ if (eNextState == P2P_STATE_REQING_CHANNEL) { ++ UINT_8 ucPreferedChnl = 0; ++ ENUM_BAND_T eBand = BAND_NULL; ++ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; ++ ++ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); ++ ++ /* Determine the channel for AP. */ ++ if (cnmPreferredChannel(prAdapter, &eBand, &ucPreferedChnl, &eSco) == FALSE) { ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ucPreferedChnl = prP2pConnSettings->ucOperatingChnl; ++ if (ucPreferedChnl == 0) { ++ ++ if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) { ++ ++ /* What to do? */ ++ ASSERT(FALSE); ++ /* TODO: Pick up a valid channel from channel list. */ ++ ucPreferedChnl = 1; ++ eBand = BAND_2G4; ++ } ++ } ++ } ++ ++ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; ++ ++ DBGLOG(P2P, INFO, "p2pStateAbort_AP_CHANNEL_DETECT GO Scan\n"); ++ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; ++ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand; ++ prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco; ++ } else { ++ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); ++ } ++ ++ } while (FALSE); ++ ++} /* p2pStateAbort_AP_CHANNEL_DETECT */ ++ ++VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) ++{ ++ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; ++ ++ do { ++ ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); ++ ++ prScanReqInfo = &prP2pFsmInfo->rScanReqInfo; ++ ++ prScanReqInfo->fgIsScanRequest = TRUE; ++ ++ p2pFuncRequestScan(prAdapter, prScanReqInfo); ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_SCAN */ ++ ++VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ do { ++ ASSERT_BREAK(prAdapter != NULL); ++ ++ /* 1. Scan cancel. (Make sure the scan request is invalid. */ ++ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); ++ ++ /* Scan done indication. */ ++ kalP2PIndicateScanDone(prAdapter->prGlueInfo, prP2pFsmInfo->rScanReqInfo.fgIsAbort); ++ } while (FALSE); ++ ++} /* p2pStateAbort_SCAN */ ++ ++VOID ++p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, ++ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && ++ (prP2pFsmInfo != NULL) && ++ (prP2pBssInfo != NULL) && (prJoinInfo != NULL) && (prBssDesc != NULL)); ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prBssDesc->ucSSIDLen) { ++ COPY_SSID(prP2pConnSettings->aucSSID, ++ prP2pConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ } ++ /* Setup a join timer. */ ++ DBGLOG(P2P, TRACE, "Start a join init timer\n"); ++ cnmTimerStartTimer(prAdapter, ++ &(prAdapter->rP2pFsmTimeoutTimer), ++ (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD)); ++ ++ /* 2 <1> We are goin to connect to this BSS */ ++ prBssDesc->fgIsConnecting = TRUE; ++ ++ /* 2 <2> Setup corresponding STA_RECORD_T */ ++ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, ++ (prBssDesc->fgIsP2PPresent ? (STA_TYPE_P2P_GO) ++ : (STA_TYPE_LEGACY_AP)), NETWORK_TYPE_P2P_INDEX, prBssDesc); ++ ++ if (prStaRec == NULL) { ++ DBGLOG(P2P, TRACE, "Create station record fail\n"); ++ break; ++ } ++ ++ prJoinInfo->prTargetStaRec = prStaRec; ++ prJoinInfo->fgIsJoinComplete = FALSE; ++ prJoinInfo->u4BufLength = 0; ++ ++ /* 2 <2.1> Sync. to FW domain */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ prStaRec->fgIsReAssoc = FALSE; ++ ++ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ switch (prP2pConnSettings->eAuthMode) { ++ case AUTH_MODE_OPEN: /* Note: Omit break here. */ ++ case AUTH_MODE_WPA: ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA2: ++ case AUTH_MODE_WPA2_PSK: ++ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ break; ++ case AUTH_MODE_SHARED: ++ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; ++ break; ++ case AUTH_MODE_AUTO_SWITCH: ++ DBGLOG(P2P, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); ++ prJoinInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | ++ AUTH_TYPE_SHARED_KEY); ++ break; ++ default: ++ ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); ++ DBGLOG(P2P, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", ++ prP2pConnSettings->eAuthMode); ++ /* TODO(Kevin): error handling ? */ ++ return; ++ } ++ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; ++ } else { ++ ASSERT(FALSE); ++ /* TODO: Shall we considering ROAMIN case for P2P Device?. */ ++ } ++ ++ /* 2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes. */ ++ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { ++ ++ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; ++ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { ++ ++ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; ++ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { ++ ++ DBGLOG(P2P, TRACE, ++ "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); ++ ++ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; ++ ++ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; ++ } else { ++ ASSERT(0); ++ } ++ ++ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ ++ if (prBssDesc->ucSSIDLen) { ++ COPY_SSID(prJoinInfo->rSsidStruct.aucSsid, ++ prJoinInfo->rSsidStruct.ucSsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ } ++ /* 2 <5> Backup desired channel. */ ++ ++ /* 2 <6> Send a Msg to trigger SAA to start JOIN process. */ ++ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); ++ ++ if (!prJoinReqMsg) { ++ DBGLOG(P2P, TRACE, "Allocation Join Message Fail\n"); ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; ++ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; ++ prJoinReqMsg->prStaRec = prStaRec; ++ ++ /* TODO: Consider fragmentation info in station record. */ ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++} /* p2pStateInit_GC_JOIN */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process of JOIN Abort. Leave JOIN State & Abort JOIN. ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, ++ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState) ++{ ++ P_MSG_JOIN_ABORT_T prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prJoinInfo != NULL)); ++ ++ if (prJoinInfo->fgIsJoinComplete == FALSE) { ++ ++ prJoinAbortMsg = ++ (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); ++ if (!prJoinAbortMsg) { ++ DBGLOG(P2P, TRACE, "Fail to allocate join abort message buffer\n"); ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT; ++ prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg; ++ prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ /* Stop Join Timer. */ ++ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); ++ ++ /* Release channel requested. */ ++ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* p2pStateAbort_GC_JOIN */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c +new file mode 100644 +index 000000000000..72fa52e761da +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c +@@ -0,0 +1,915 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/privacy.c#1 ++*/ ++ ++/*! \file "privacy.c" ++ \brief This file including the protocol layer privacy function. ++ ++ This file provided the macros and functions library support for the ++ protocol layer security setting from rsn.c and nic_privacy.c ++ ++*/ ++ ++/* ++** Log: privacy.c ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 20 2011 terry.wu ++ * NULL ++ * Fix Hotspot deauth send failed. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 06 28 2011 tsaiyuan.hsu ++ * [WCXRP00000819] [MT6620 Wi-Fi][Driver] check if staRec is NULL or not in secCheckClassError ++ * check if staRec is NULL or not in secCheckClassError. ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 20 2010 wh.su ++ * ++ * adding the wapi code. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * adding the compiling flag for migration. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the ad-hoc wpa-none send non-encrypted frame issue. ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 04 29 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * adjsut the pre-authentication code. ++ * ++ * 04 22 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the wpi same key id rx issue and fixed the remove wep key issue. ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Send Deauth for Class 3 Error and Leave Network Support ++ * ++ * 04 15 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * remove the assert code for allow ad-hoc pkt. ++ * ++ * 04 13 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the Klocwork error and refine the class error message. ++ * ++ * 03 04 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Code refine, and remove non-used code. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 02 26 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * change the waning message shown level, and clear the global transmit flag for CMD INFRASTRUCTURE. ++ * ++ * 02 25 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * For support the WHQL test, do the remove key code refine. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 12 25 2009 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) ++ * * * * * * * * * MQM: BA handling ++ * * * * * * * * * TXM: Macros updates ++ * * * * * * * * * RXM: Macros/Duplicate Removal updates ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 11 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * modify the cmd with result return ++ * ++ * Dec 11 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * fixed the value not initialize issue ++ * ++ * Dec 10 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the cmd return type ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function to update the auth mode and encryption status for cmd build connection ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some code for wapi mode ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the call to check the 4th and eapol error report frame ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * rename the function name ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code for parsing the EAPoL frame, and do some code refine ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the class error check ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the cmd_802_11_pmkid code ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * doing some function rename, and adding the code for cmd CMD_ADD_REMOVE_KEY ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the clear pmkid function ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix eStaType check for AIS ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the ap selection related code ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_PRIVACY_MIGRATION ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to initialize the privacy-related ++* parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] ucNetTypeIdx Pointer to netowrk type index ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx) ++{ ++ UINT_8 i; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("secInit"); ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ prBssInfo->u4RsnSelectedGroupCipher = 0; ++ prBssInfo->u4RsnSelectedPairwiseCipher = 0; ++ prBssInfo->u4RsnSelectedAKMSuite = 0; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; ++ ++ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; ++#endif ++ ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[0].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP40; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[1].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_TKIP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[2].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_CCMP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[3].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP104; ++ ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[4].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP40; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[5].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_TKIP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[6].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_CCMP; ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[7].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP104; ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) ++ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[0].dot11RSNAConfigAuthenticationSuite = ++ WPA_AKM_SUITE_NONE; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[1].dot11RSNAConfigAuthenticationSuite = ++ WPA_AKM_SUITE_802_1X; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[2].dot11RSNAConfigAuthenticationSuite = ++ WPA_AKM_SUITE_PSK; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[3].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_NONE; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[4].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_802_1X; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[5].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_PSK; ++ ++#if CFG_SUPPORT_802_11W ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[6].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_802_1X_SHA256; ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[7].dot11RSNAConfigAuthenticationSuite = ++ RSN_AKM_SUITE_PSK_SHA256; ++#endif ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { ++ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i].dot11RSNAConfigAuthenticationSuiteEnabled = ++ FALSE; ++ } ++ ++ secClearPmkid(prAdapter); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAisSpecBssInfo->rPreauthenticationTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) rsnIndicatePmkidCand, (ULONG) NULL); ++ ++#if CFG_SUPPORT_802_11W ++ cnmTimerInitTimer(prAdapter, ++ &prAisSpecBssInfo->rSaQueryTimer, (PFN_MGMT_TIMEOUT_FUNC) rsnStartSaQueryTimer, (ULONG) NULL); ++#endif ++ ++ prAisSpecBssInfo->fgCounterMeasure = FALSE; ++ prAisSpecBssInfo->ucWEPDefaultKeyID = 0; ++ ++#if 0 ++ for (i = 0; i < WTBL_SIZE; i++) { ++ g_prWifiVar->arWtbl[i].fgUsed = FALSE; ++ g_prWifiVar->arWtbl[i].prSta = NULL; ++ g_prWifiVar->arWtbl[i].ucNetTypeIdx = NETWORK_TYPE_INDEX_NUM; ++ ++ } ++ nicPrivacyInitialize((UINT_8) NETWORK_TYPE_INDEX_NUM); ++#endif ++} /* secInit */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Rx Class Error" to SEC_FSM for ++* JOIN Module. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSwRfb Pointer to the SW RFB. ++* ++* \return FALSE Class Error ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec) ++{ ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (!prStaRec) ++ return FALSE; ++ ++ eNetTypeIndex = prStaRec->ucNetTypeIndex; ++ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) ++ return FALSE; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]; ++ if ((STA_STATE_3 != prStaRec->ucStaState) && prBssInfo->fgIsNetAbsent == FALSE) { ++ /*(IS_AP_STA(prStaRec) || IS_CLIENT_STA(prStaRec))) { */ ++ ++#if 0 /* by scott's suggestions, do not put work-around in JB2,we need to find the root cause */ ++ /* work-around for CR ALPS00816361 */ ++ if (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ DBGLOG(RSN, INFO, ++ "p2p> skip to send Deauth to MAC:[%pM] for Rx Class 3.\n", ++ prStaRec->aucMacAddr); ++ return TRUE; ++ } ++#endif ++ ++ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, ++ prStaRec, ++ NULL, ++ REASON_CODE_CLASS_3_ERR, ++ (PFN_TX_DONE_HANDLER) NULL)) ++ ++ DBGLOG(RSN, INFO, "Send Deauth to [ %pM ] for Rx Class 3 Error.\n", ++ prStaRec->aucMacAddr); ++ else ++ DBGLOG(RSN, INFO, "Host sends Deauth to [ %pM ] for Rx Class 3 fail.\n", ++ prStaRec->aucMacAddr); ++ return FALSE; ++ } ++ ++ return secRxPortControlCheck(prAdapter, prSwRfb); ++} /* end of secCheckClassError() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to setting the sta port status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSta Pointer to the sta ++* \param[in] fgPortBlock The port status ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPortBlock) ++{ ++ if (prSta == NULL) ++ return; ++ ++ prSta->fgPortBlock = fgPortBlock; ++ ++ DBGLOG(RSN, TRACE, ++ "The STA %pM port %s\n", prSta->aucMacAddr, fgPortBlock == TRUE ? "BLOCK" : " OPEN"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to report the sta port status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSta Pointer to the sta ++* \param[out] fgPortBlock The port status ++* ++* \return TRUE sta exist, FALSE sta not exist ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secGetPortStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, OUT PBOOLEAN pfgPortStatus) ++{ ++ if (prSta == NULL) ++ return FALSE; ++ ++ *pfgPortStatus = prSta->fgPortBlock; ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle Peer device Tx Security process MSDU. ++* ++* \param[in] prMsduInfo pointer to the packet info pointer ++* ++* \retval TRUE Accept the packet ++* \retval FALSE Refuse the MSDU packet due port blocked ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN /* ENUM_PORT_CONTROL_RESULT */ ++secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) { ++ ++ /* Todo:: */ ++ if (prMsduInfo->fgIs802_1x) ++ return TRUE; ++ ++ if (prStaRec->fgPortBlock == TRUE) { ++ DBGLOG(SEC, TRACE, "Drop Tx packet due Port Control!\n"); ++ return FALSE; ++ } ++#if CFG_SUPPORT_WAPI ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) ++ return TRUE; ++#endif ++ if (IS_STA_IN_AIS(prStaRec)) { ++ if (!prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist && ++ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED)) { ++ DBGLOG(SEC, TRACE, "Drop Tx packet due the key is removed!!!\n"); ++ return FALSE; ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle The Rx Security process MSDU. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSWRfb SW rfb pinter ++* ++* \retval TRUE Accept the packet ++* \retval FALSE Refuse the MSDU packet due port control ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb) ++{ ++ ASSERT(prSWRfb); ++ ++#if 0 ++ /* whsu:Todo: Process MGMT and DATA */ ++ if (prSWRfb->prStaRec) { ++ if (prSWRfb->prStaRec->fgPortBlock == TRUE) { ++ if (1 /* prSWRfb->fgIsDataFrame and not 1x */ && ++ (g_prWifiVar->rConnSettings.eAuthMode >= AUTH_MODE_WPA)) { ++ /* DBGLOG(SEC, WARN, ("Drop Rx data due port control !\r\n")); */ ++ return TRUE; /* Todo: whsu FALSE; */ ++ } ++ /* if (!RX_STATUS_IS_PROTECT(prSWRfb->prRxStatus)) { */ ++ /* DBGLOG(RSN, WARN, ("Drop rcv non-encrypted data frame!\n")); */ ++ /* return FALSE; */ ++ /* } */ ++ } ++ } else { ++ } ++#endif ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine will enable/disable the cipher suite ++* ++* \param[in] prAdapter Pointer to the adapter object data area. ++* \param[in] u4CipherSuitesFlags flag for cipher suite ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags) ++{ ++ UINT_32 i; ++ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; ++ P_IEEE_802_11_MIB_T prMib; ++ ++ ASSERT(prAdapter); ++ ++ prMib = &prAdapter->rMib; ++ ++ ASSERT(prMib); ++ ++ if (u4CipherSuitesFlags == CIPHER_FLAG_NONE) { ++ /* Disable all the pairwise cipher suites. */ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) ++ prMib->dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ ++ /* Update the group cipher suite. */ ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; ++ ++ return; ++ } ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { ++ prEntry = &prMib->dot11RSNAConfigPairwiseCiphersTable[i]; ++ ++ switch (prEntry->dot11RSNAConfigPairwiseCipher) { ++ case WPA_CIPHER_SUITE_WEP40: ++ case RSN_CIPHER_SUITE_WEP40: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP40) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ ++ case WPA_CIPHER_SUITE_TKIP: ++ case RSN_CIPHER_SUITE_TKIP: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_TKIP) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ ++ case WPA_CIPHER_SUITE_CCMP: ++ case RSN_CIPHER_SUITE_CCMP: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_CCMP) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ ++ case WPA_CIPHER_SUITE_WEP104: ++ case RSN_CIPHER_SUITE_WEP104: ++ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP104) ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; ++ else ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* Update the group cipher suite. */ ++ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_CCMP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_TKIP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP104; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP40; ++ else ++ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; ++ ++} /* secSetCipherSuite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle The 2nd Tx EAPoL Frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prMsduInfo pointer to the packet info pointer ++* \param[in] pucPayload pointer to the 1x hdr ++* \param[in] u2PayloadLen the 1x payload length ++* ++* \retval TRUE Accept the packet ++* \retval FALSE Refuse the MSDU packet due port control ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++secProcessEAPOL(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen) ++{ ++ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; ++ P_IEEE_802_1X_HDR pr1xHdr; ++ UINT_16 u2KeyInfo; ++ ++ ASSERT(prMsduInfo); ++ ASSERT(prStaRec); ++ ++ /* prStaRec = &(g_arStaRec[prMsduInfo->ucStaRecIndex]); */ ++ ASSERT(prStaRec); ++ ++ if (prStaRec && IS_AP_STA(prStaRec)) { ++ pr1xHdr = (P_IEEE_802_1X_HDR) pucPayload; ++ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { ++ prEapol = (P_EAPOL_KEY) ((PUINT_32) (pucPayload + 4)); ++ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); ++ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { ++ if (u2KeyInfo & WPA_KEY_INFO_SECURE) { ++ /* 4th EAPoL check at secHandleTxDoneCallback() */ ++ /* DBGLOG(RSN, TRACE, ("Tx 4th EAPoL frame\r\n")); */ ++ } else if (u2PayloadLen == 123 /* Not include LLC */) { ++ DBGLOG(RSN, INFO, "Tx 2nd EAPoL frame\r\n"); ++ secFsmEvent2ndEapolTx(prAdapter, prStaRec); ++ } ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will handle the 4th EAPoL Tx done and mic Error Report frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pMsduInfo Pointer to the Msdu Info ++* \param[in] rStatus The Tx done status ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus) ++{ ++ PUINT_8 pucPayload; ++ P_IEEE_802_1X_HDR pr1xHdr = (P_IEEE_802_1X_HDR) NULL; ++ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; ++ UINT_16 u2KeyInfo; ++ UINT_16 u2PayloadLen; ++ ++ DEBUGFUNC("secHandleTxDoneCallback"); ++ ++ ASSERT(prMsduInfo); ++ /* Todo:: Notice if using the TX free immediate after send to firmware, the payload may not correcttly!!!! */ ++ ++ ASSERT(prStaRec); ++ ++ /* Todo:: This call back may not need because the order of set key and send 4th 1x can be make sure */ ++ /* Todo:: Notice the LLC offset */ ++#if 1 ++ pucPayload = (PUINT_8) prMsduInfo->prPacket; ++ ASSERT(pucPayload); ++ ++ u2PayloadLen = prMsduInfo->u2FrameLength; ++ ++ if (0 /* prMsduInfo->fgIs1xFrame */) { ++ ++ if (prStaRec && IS_AP_STA(prStaRec)) { ++ pr1xHdr = (P_IEEE_802_1X_HDR) (PUINT_32) (pucPayload + 8); ++ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { ++ prEapol = (P_EAPOL_KEY) (PUINT_32) (pucPayload + 12); ++ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); ++ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { ++ if (prStaRec->rSecInfo.fg2nd1xSend == TRUE ++ && u2PayloadLen == ++ 107 /* include LLC *//* u2KeyInfo & WPA_KEY_INFO_SECURE */) { ++ DBGLOG(RSN, INFO, "Tx 4th EAPoL frame\r\n"); ++ secFsmEvent4ndEapolTxDone(prAdapter, prStaRec); ++ } else if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone) { ++ DBGLOG(RSN, INFO, "Tx EAPoL Error report frame\r\n"); ++ /* secFsmEventEapolTxDone(prAdapter, (UINT_32)prMsduInfo->prStaRec); */ ++ } ++ } ++ } ++ } ++ ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to initialize the pmkid parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secClearPmkid(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("secClearPmkid"); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ DBGLOG(RSN, TRACE, "secClearPmkid\n"); ++ prAisSpecBssInfo->u4PmkidCandicateCount = 0; ++ prAisSpecBssInfo->u4PmkidCacheCount = 0; ++ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCandicate, sizeof(PMKID_CANDICATE_T) * CFG_MAX_PMKID_CACHE); ++ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Whether WPA, or WPA2 but not WPA-None is enabled. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval BOOLEAN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ ++ ASSERT(prConnSettings); ++ ++ ASSERT(prConnSettings->eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); ++ ++ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION_DISABLED) ++ return FALSE; ++ ++ ASSERT(prConnSettings->eAuthMode < AUTH_MODE_NUM); ++ if ((prConnSettings->eAuthMode >= AUTH_MODE_WPA) && (prConnSettings->eAuthMode != AUTH_MODE_WPA_NONE)) ++ return TRUE; ++ ++ return FALSE; ++} /* secRsnKeyHandshakeEnabled */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return whether the transmit key alread installed. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prSta Pointer the sta record ++* ++* \retval TRUE Default key or Transmit key installed ++* FALSE Default key or Transmit key not installed ++* ++* \note: ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ASSERT(prSta); ++ ++ if (prSta->fgTransmitKeyExist) ++ return TRUE; ++ else ++ return FALSE; ++} /* secTransmitKeyExist */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Whether 802.11 privacy is enabled. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval BOOLEAN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter) ++{ ++ DEBUGFUNC("secEnabled"); ++ ++ ASSERT(prAdapter->rWifiVar.rConnSettings.eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); ++ ++ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { ++ case ENUM_ENCRYPTION_DISABLED: ++ return FALSE; ++ case ENUM_ENCRYPTION1_ENABLED: ++ case ENUM_ENCRYPTION2_ENABLED: ++ case ENUM_ENCRYPTION3_ENABLED: ++ return TRUE; ++ default: ++ DBGLOG(RSN, TRACE, "Unknown encryption setting %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ break; ++ } ++ return FALSE; ++} /* secEnabled */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the privacy bit at mac header for TxM ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] prMsdu the msdu for known the sta record ++* ++* \return TRUE the privacy need to set ++* FALSE the privacy no need to set ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec) ++{ ++ ASSERT(prAdapter); ++ ++ ASSERT(prMsdu); ++ ++ ASSERT(prStaRec); ++ /* prStaRec = &(g_arStaRec[prMsdu->ucStaRecIndex]); */ ++ ++ if (prStaRec == NULL) { ++ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) ++ return TRUE; ++ return FALSE; /* No privacy bit */ ++ } ++ ++ /* Todo:: */ ++ if (0 /* prMsdu->fgIs1xFrame */) { ++ if (IS_STA_IN_AIS(prStaRec) && prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { ++ DBGLOG(RSN, LOUD, "For AIS Legacy 1x, always not encryped\n"); ++ return FALSE; ++ } else if (!prStaRec->fgTransmitKeyExist) { ++ DBGLOG(RSN, LOUD, "1x Not Protected.\n"); ++ return FALSE; ++ } else if (prStaRec->rSecInfo.fgKeyStored) { ++ DBGLOG(RSN, LOUD, "1x not Protected due key stored!\n"); ++ return FALSE; ++ } ++ DBGLOG(RSN, LOUD, "1x Protected.\n"); ++ return TRUE; ++ } ++ if (!prStaRec->fgTransmitKeyExist) { ++ /* whsu , check for AIS only */ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA && ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) { ++ DBGLOG(RSN, LOUD, "Protected\n"); ++ return TRUE; ++ } ++ } else { ++ DBGLOG(RSN, LOUD, "Protected.\n"); ++ return TRUE; ++ } ++ ++ /* No sec or key is removed!!! */ ++ return FALSE; ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c +new file mode 100644 +index 000000000000..fd0a8772a666 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c +@@ -0,0 +1,497 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1 ++*/ ++ ++/*! \file "rate.c" ++ \brief This file contains the transmission rate handling routines. ++ ++ This file contains the transmission rate handling routines for setting up ++ ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do ++ conversion between Rate Set and Data Rates. ++*/ ++ ++/* ++** Log: rate.c ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add rate.c. ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update comments ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix DBGLOG ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461 ++** Fix the problem that do not ASSERT the length of Supported Rate IE == 8 ++** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088 ++** fixed the lint "possible using null pointer" warning ++** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461 ++** Revise GEN Link Speed OID ++** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461 ++** Add rateGetRateSetFromDataRates() for set desired rate OID ++** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461 ++** Add adopt operational rate as ACK rate if BasicRateSet was not found ++** Add comments ++** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461 ++** Add initial rate according rx signal quality support ++** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461 ++** Fix typo of rate adaptation of CtrlResp Frame ++** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461 ++** Add VOIP SCAN Support & Refine Roaming ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* The list of valid data rates. */ ++const UINT_8 aucDataRate[] = { ++ RATE_1M, /* RATE_1M_INDEX = 0 */ ++ RATE_2M, /* RATE_2M_INDEX */ ++ RATE_5_5M, /* RATE_5_5M_INDEX */ ++ RATE_11M, /* RATE_11M_INDEX */ ++ RATE_22M, /* RATE_22M_INDEX */ ++ RATE_33M, /* RATE_33M_INDEX */ ++ RATE_6M, /* RATE_6M_INDEX */ ++ RATE_9M, /* RATE_9M_INDEX */ ++ RATE_12M, /* RATE_12M_INDEX */ ++ RATE_18M, /* RATE_18M_INDEX */ ++ RATE_24M, /* RATE_24M_INDEX */ ++ RATE_36M, /* RATE_36M_INDEX */ ++ RATE_48M, /* RATE_48M_INDEX */ ++ RATE_54M, /* RATE_54M_INDEX */ ++ RATE_HT_PHY /* RATE_HT_PHY_INDEX */ ++}; ++ ++static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = { ++ RATE_1M_INDEX, /* RATE_1M_INDEX = 0 */ ++ RATE_2M_INDEX, /* RATE_2M_INDEX */ ++ RATE_5_5M_INDEX, /* RATE_5_5M_INDEX */ ++ RATE_11M_INDEX, /* RATE_11M_INDEX */ ++ RATE_1M_INDEX, /* RATE_22M_INDEX - Not supported */ ++ RATE_1M_INDEX, /* RATE_33M_INDEX - Not supported */ ++ RATE_6M_INDEX, /* RATE_6M_INDEX */ ++ RATE_6M_INDEX, /* RATE_9M_INDEX */ ++ RATE_12M_INDEX, /* RATE_12M_INDEX */ ++ RATE_12M_INDEX, /* RATE_18M_INDEX */ ++ RATE_24M_INDEX, /* RATE_24M_INDEX */ ++ RATE_24M_INDEX, /* RATE_36M_INDEX */ ++ RATE_24M_INDEX, /* RATE_48M_INDEX */ ++ RATE_24M_INDEX /* RATE_54M_INDEX */ ++}; ++ ++const BOOLEAN afgIsOFDMRate[RATE_NUM] = { ++ FALSE, /* RATE_1M_INDEX = 0 */ ++ FALSE, /* RATE_2M_INDEX */ ++ FALSE, /* RATE_5_5M_INDEX */ ++ FALSE, /* RATE_11M_INDEX */ ++ FALSE, /* RATE_22M_INDEX - Not supported */ ++ FALSE, /* RATE_33M_INDEX - Not supported */ ++ TRUE, /* RATE_6M_INDEX */ ++ TRUE, /* RATE_9M_INDEX */ ++ TRUE, /* RATE_12M_INDEX */ ++ TRUE, /* RATE_18M_INDEX */ ++ TRUE, /* RATE_24M_INDEX */ ++ TRUE, /* RATE_36M_INDEX */ ++ TRUE, /* RATE_48M_INDEX */ ++ TRUE /* RATE_54M_INDEX */ ++}; ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the given Supported Rate & Extended Supported Rate IE to the ++* Operational Rate Set and Basic Rate Set, and also check if any Basic ++* Rate Code is unknown by driver. ++* ++* @param[in] prIeSupportedRate Pointer to the Supported Rate IE ++* @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE ++* @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set ++* @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set ++* @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic ++* Rate Set has unknown Rate Code ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, ++ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, ++ OUT PUINT_16 pu2OperationalRateSet, ++ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate) ++{ ++ UINT_16 u2OperationalRateSet = 0; ++ UINT_16 u2BSSBasicRateSet = 0; ++ BOOLEAN fgIsUnknownBSSBasicRate = FALSE; ++ UINT_8 ucRate; ++ UINT_32 i, j; ++ ++ ASSERT(pu2OperationalRateSet); ++ ASSERT(pu2BSSBasicRateSet); ++ ASSERT(pfgIsUnknownBSSBasicRate); ++ ++ if (prIeSupportedRate) { ++ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. ++ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), ++ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" ++ */ ++ /* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */ ++ ASSERT(prIeSupportedRate->ucLength <= RATE_NUM); ++ ++ for (i = 0; i < prIeSupportedRate->ucLength; i++) { ++ ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK; ++ ++ /* Search all valid data rates */ ++ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { ++ if (ucRate == aucDataRate[j]) { ++ u2OperationalRateSet |= BIT(j); ++ ++ if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) ++ u2BSSBasicRateSet |= BIT(j); ++ ++ break; ++ } ++ } ++ ++ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && ++ (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) { ++ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ ++ } ++ } ++ } ++ ++ if (prIeExtSupportedRate) { ++ /* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */ ++ ++ for (i = 0; i < prIeExtSupportedRate->ucLength; i++) { ++ ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK; ++ ++ /* Search all valid data rates */ ++ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { ++ if (ucRate == aucDataRate[j]) { ++ u2OperationalRateSet |= BIT(j); ++ ++ if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) ++ u2BSSBasicRateSet |= BIT(j); ++ ++ break; ++ } ++ } ++ ++ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && ++ (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) { ++ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ ++ } ++ } ++ } ++ ++ *pu2OperationalRateSet = u2OperationalRateSet; ++ *pu2BSSBasicRateSet = u2BSSBasicRateSet; ++ *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate; ++ ++ return; ++ ++} /* end of rateGetRateSetFromIEs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code ++* Format for used in (Ext)Supportec Rate IE. ++* ++* @param[in] u2OperationalRateSet Operational Rate Set ++* @param[in] u2BSSBasicRateSet Basic Rate Set ++* @param[out] pucDataRates Pointer to the Data Rate Buffer ++* @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, ++ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen) ++{ ++ UINT_32 i, j; ++ ++ ASSERT(pucDataRates); ++ ASSERT(pucDataRatesLen); ++ ++ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); ++ ++ for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) { ++ if (u2OperationalRateSet & BIT(i)) { ++ ++ *(pucDataRates + j) = aucDataRate[i]; ++ ++ if (u2BSSBasicRateSet & BIT(i)) ++ *(pucDataRates + j) |= RATE_BASIC_BIT; ++ ++ j++; ++ } ++ } ++ ++ *pucDataRatesLen = (UINT_8) j; ++ ++ return; ++ ++} /* end of rateGetDataRatesFromRateSet() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the highest rate from given Rate Set. ++* ++* \param[in] u2RateSet Rate Set ++* \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index ++* ++* \retval TRUE Highest Rate Index was found ++* \retval FALSE Highest Rate Index was not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex) ++{ ++ INT_32 i; ++ ++ ASSERT(pucHighestRateIndex); ++ ++ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { ++ if (u2RateSet & BIT(i)) { ++ *pucHighestRateIndex = (UINT_8) i; ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++ ++} /* end of rateGetHighestRateIndexFromRateSet() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the lowest rate from given Rate Set. ++* ++* \param[in] u2RateSet Rate Set ++* \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index ++* ++* \retval TRUE Lowest Rate Index was found ++* \retval FALSE Lowest Rate Index was not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex) ++{ ++ UINT_32 i; ++ ++ ASSERT(pucLowestRateIndex); ++ ++ for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) { ++ if (u2RateSet & BIT(i)) { ++ *pucLowestRateIndex = (UINT_8) i; ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++ ++} /* end of rateGetLowestRateIndexFromRateSet() */ ++ ++#if 0 /* NOTE(Kevin): For reference */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Convert the given Data Rates to the Rate Set. ++* ++* \param[in] pucDataRates Pointer to the Data Rates ++* \param[in] ucDataRatesLen Length of given Data Rates ++* \param[out] pu2RateSet Pointer to the Rate Set ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates, IN UINT_8 ucDataRatesLen, OUT PUINT_16 pu2RateSet) ++{ ++ UINT_16 u2RateSet = 0; ++ UINT_8 ucRate; ++ UINT_32 i, j; ++ ++ ASSERT(pucDataRates); ++ ASSERT(pu2RateSet); ++ ++ if (pucDataRates) { ++ for (i = 0; i < ucDataRatesLen; i++) { ++ ucRate = pucDataRates[i] & RATE_MASK; ++ ++ /* Search all valid data rates */ ++ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { ++ if (ucRate == aucDataRate[j]) { ++ u2RateSet |= BIT(j); ++ break; ++ } ++ } ++ } ++ } ++ ++ *pu2RateSet = u2RateSet; ++ ++ return; ++ ++} /* end of rateGetRateSetFromDataRates() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding ++* ACK/CTS(Respnose) TX Rates. ++* ++* \param[in] u2OperationalRateSet Operational Rate Set ++* \param[in] u2BSSBasicRateSet Basic Rate Set ++* \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, ++ IN UINT_16 u2BSSBasicRateSet, IN OUT UINT_8 aucAckCtsRateIndex[]) ++{ ++ INT_32 i, j; ++ ++ ASSERT(aucAckCtsRateIndex); ++ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); ++ ++ /* Setup default ACK/CTS response rate */ ++ kalMemCopy(aucAckCtsRateIndex, (PVOID) aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex)); ++ ++ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { ++ if (u2OperationalRateSet & BIT(i)) { ++ for (j = i; j >= RATE_1M_INDEX; j--) { ++ if (u2BSSBasicRateSet & BIT(j)) { ++ /* Reply ACK Frame at the same Modulation Scheme. */ ++ if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || ++ (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) ++ aucAckCtsRateIndex[i] = (UINT_8) j; ++ break; ++ } ++ } ++ ++ /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has ++ * NULL BasicRateSet. ++ * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL. ++ * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"]. ++ * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M], ++ * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still ++ * use highest mandatory rate as default. ++ */ ++ if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */ ++ if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet)) ++ aucAckCtsRateIndex[i] = (UINT_8) i; ++ } ++ } ++ } ++ ++ return; ++ ++} /* end of rateSetAckCtsDataRatesFromRateSet() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the proper initial rate from Rate Set according to given RCPI value ++* ++* \param[in] u2RateSet Rate Set ++* \param[in] rRcpi RCPI value from AP or Peer STA ++* \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index ++* ++* \retval TRUE Initial Rate Index was found ++* \retval FALSE Initial Rate Index was not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rateGetBestInitialRateIndex(IN UINT_16 u2RateSet, IN RCPI rRcpi, OUT PUINT_8 pucInitialRateIndex) ++{ ++ UINT_16 u2InitRateSet; ++ INT_32 i; ++ ++ ASSERT(pucInitialRateIndex); ++ ++ DBGLOG(MGT, TRACE, "rRcpi = %d\n", rRcpi); ++ ++ if (rRcpi >= RCPI_100) { /* Best Signal */ ++ u2InitRateSet = INITIAL_RATE_SET(RCPI_100); ++ } else if (rRcpi >= RCPI_80) { /* Better Signal */ ++ u2InitRateSet = INITIAL_RATE_SET(RCPI_80); ++ } else if (rRcpi >= RCPI_60) { /* Good Signal */ ++ u2InitRateSet = INITIAL_RATE_SET(RCPI_60); ++ } else { /* Worse Signal */ ++ /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index ++ * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in ++ * function - bssUpdateTxRateForControlFrame(). ++ */ ++ return FALSE; ++ } ++ ++ u2RateSet &= u2InitRateSet; ++ ++ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { ++ if (u2RateSet & BIT(i)) { ++ *pucInitialRateIndex = (UINT_8) i; ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++ ++} /* end of rateGetBestInitialRateIndex() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c +new file mode 100644 +index 000000000000..244346983f40 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c +@@ -0,0 +1,1858 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#2 ++*/ ++ ++/*! \file "rlm.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Check length HT cap IE about RX associate request frame ++ * ++ * 11 10 2011 cm.chang ++ * NULL ++ * Modify debug message for XLOG ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 11 03 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Fix preamble type of STA mode ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Not send ERP IE if peer STA is 802.11b-only ++ * ++ * 10 11 2011 cm.chang ++ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter ++ * Ignore HT OP IE if its length field is not valid ++ * ++ * 09 28 2011 cm.chang ++ * NULL ++ * Add length check to reduce possibility to adopt wrong IE ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * Handle client mode about preamble type and slot time ++ * ++ * 09 01 2011 cm.chang ++ * [WCXRP00000971] [MT6620 Wi-Fi][Driver][FW] Not set Beacon timeout interval when CPTT ++ * Final channel number only adopts the field from assoc response ++ * ++ * 06 10 2011 cm.chang ++ * [WCXRP00000773] [MT6620 Wi-Fi][Driver] Workaround some AP fill primary channel field with its secondary channel ++ * If DS IE exists, ignore the primary channel field in HT OP IE ++ * ++ * 05 03 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Fix compiling error ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Refine range of valid channel number ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Check if channel is valided before record ing BSS channel ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 29 2011 cm.chang ++ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning ++ * As CR title ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode ++ * and stop ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 10 15 2010 cm.chang ++ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. ++ * Add exception handle when no mgmt buffer in free build ++ * ++ * 10 08 2010 cm.chang ++ * NULL ++ * When 20M only setting, ignore OBSS IE ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Temporary add rlmUpdateParamByStaForBow() and rlmBssInitForBow(). ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Add CFG_ENABLE_BT_OVER_WIFI. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * P2P Group Negotiation Code Check in. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Fix compile error while enabling WiFi Direct function. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 06 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix channel ID definition in RFB status to primary channel instead of center channel ++ * ++ * 06 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add TX short GI compiling option ++ * ++ * 06 02 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Roll back to remove CFG_SUPPORT_BCM_TEST. ++ * ++ * 06 01 2010 chinghwa.yu ++ * [BORA00000563]Add WiFi CoEx BCM module ++ * Update BCM Test and RW configuration. ++ * ++ * 05 31 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add some compiling options to control 11n functions ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Set RTS threshold of 2K bytes initially ++ * ++ * 05 18 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Ad-hoc Beacon should not carry HT OP and OBSS IEs ++ * ++ * 05 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process 20/40 coexistence public action frame in AP mode ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 04 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Utilize status of swRfb to know channel number and band ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Different invoking order for WTBL entry of associated AP ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add virtual test for OBSS scan ++ * ++ * 04 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process Beacon only ready for infra STA now ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 03 24 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * fixed some WHQL testing error. ++ * ++ * 03 15 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Provide draft measurement and quiet functions ++ * ++ * 03 09 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * If bss is not 11n network, zero WTBL HT parameters ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * To support CFG_SUPPORT_BCM_STP ++ * ++ * 03 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Generate HT IE only depending on own phyTypeSet ++ * ++ * 03 02 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not fill HT related IE if BssInfo does not include 11n phySet ++ * ++ * 03 01 2010 tehuang.liu ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * To store field AMPDU Parameters in STA_REC ++ * ++ * 02 26 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable RDG RX, but disable RDG TX for IOT and LongNAV ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 07 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Modify the parameter of rlmRecAssocRspHtInfo function ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix prBssInfo->ucPrimaryChannel handle for assoc resp ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add some function to process HT operation ++ * ++ * Nov 28 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Call rlmStatisticsInit() to handle MIB counters ++ * ++ * Nov 18 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); ++ ++static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++static BOOLEAN ++rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++static BOOLEAN ++rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); ++ ++static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFsmEventInit(P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* Note: assume TIMER_T structures are reset to zero or stopped ++ * before invoking this function. ++ */ ++ ++ /* Initialize OBSS FSM */ ++ rlmObssInit(prAdapter); ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ rlmDomainCheckCountryPowerLimitTable(prAdapter); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 ucNetIdx; ++ ++ ASSERT(prAdapter); ++ ++ RLM_NET_FOR_EACH(ucNetIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; ++ ASSERT(prBssInfo); ++ ++ /* Note: all RLM timers will also be stopped. ++ * Now only one OBSS scan timer. ++ */ ++ rlmBssReset(prAdapter, prBssInfo); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe request, association request ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe request, association request ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ else if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ hs20FillExtCapIE(prAdapter, prBssInfo, prMsduInfo); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) ++ rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief For probe response (GO, IBSS) and association response ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ P_IE_ERP_T prErpIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; ++ ASSERT(prBssInfo); ++ ++ if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 && ++ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) { ++ prErpIe = (P_IE_ERP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ /* Add ERP IE */ ++ prErpIe->ucId = ELEM_ID_ERP_INFO; ++ prErpIe->ucLength = 1; ++ ++ prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ? ERP_INFO_USE_PROTECTION : 0; ++ ++ if (prBssInfo->fgErpProtectMode) ++ prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION); ++ ++ /* Handle barker preamble */ ++ if (!prBssInfo->fgUseShortPreamble) ++ prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE; ++ ++ ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prErpIe); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT32 ++rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, ++ BOOLEAN fgShortGIDisabled, ++ UINT_8 u8SupportRxSgi20, ++ UINT_8 u8SupportRxSgi40, ++ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf) ++{ ++ P_IE_HT_CAP_T prHtCap; ++ P_SUP_MCS_SET_FIELD prSupMcsSet; ++ ++ ASSERT(pOutBuf); ++ ++ prHtCap = (P_IE_HT_CAP_T) pOutBuf; ++ ++ /* Add HT capabilities IE */ ++ prHtCap->ucId = ELEM_ID_HT_CAP; ++ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; ++ ++ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; ++ if (!fg40mAllowed) { ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | ++ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); ++ } ++ if (fgShortGIDisabled) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++ ++ if (u8SupportRxSgi20 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); ++ if (u8SupportRxSgi40 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); ++ if (u8SupportRxGf == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); ++ if (u8SupportRxSTBC == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_RX_STBC_1_SS); ++ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; ++ ++ prSupMcsSet = &prHtCap->rSupMcsSet; ++ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); ++ ++ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); ++ ++ if (fg40mAllowed) ++ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ ++ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; ++ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; ++ ++ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; ++ if (!fg40mAllowed || eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); ++ ++ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; ++ ++ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; ++ ++ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); ++ ++ return IE_SIZE(prHtCap); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++ P_IE_HT_CAP_T prHtCap; ++/* P_SUP_MCS_SET_FIELD prSupMcsSet; */ ++ BOOLEAN fg40mAllowed; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ASSERT(prMsduInfo); ++ ++ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; ++ ++ prHtCap = (P_IE_HT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++#if 0 ++ /* Add HT capabilities IE */ ++ prHtCap->ucId = ELEM_ID_HT_CAP; ++ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; ++ ++ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; ++ if (!fg40mAllowed) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | ++ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); ++ if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); ++ ++ if (prAdapter->rWifiVar.u8SupportRxSgi20 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); ++ if (prAdapter->rWifiVar.u8SupportRxSgi40 == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); ++ if (prAdapter->rWifiVar.u8SupportRxGf == 2) ++ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); ++ ++ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; ++ ++ prSupMcsSet = &prHtCap->rSupMcsSet; ++ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); ++ ++ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); ++ ++ if (fg40mAllowed) ++ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ ++ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; ++ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; ++ ++ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; ++ if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); ++ ++ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; ++ ++ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; ++ ++ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prHtCap); ++#else ++ ++ prMsduInfo->u2FrameLength += rlmFillHtCapIEByParams(fg40mAllowed, ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, ++ prAdapter->rWifiVar.u8SupportRxSgi20, ++ prAdapter->rWifiVar.u8SupportRxSgi40, ++ prAdapter->rWifiVar.u8SupportRxGf, ++ prAdapter->rWifiVar.u8SupportRxSTBC, ++ prBssInfo->eCurrentOPMode, (UINT_8 *) prHtCap); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ P_HS20_EXT_CAP_T prHsExtCap; ++#else ++ P_EXT_CAP_T prExtCap; ++#endif ++ BOOLEAN fg40mAllowed; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ prHsExtCap = (P_HS20_EXT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ prHsExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) ++ prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; ++ else ++ prHsExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ ++ kalMemZero(prHsExtCap->aucCapabilities, sizeof(prHsExtCap->aucCapabilities)); ++ ++ prHsExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (!fg40mAllowed) ++ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; ++ ++ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { ++ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); ++ ++ /* For R2 WNM-Notification */ ++ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); ++ } ++ ++ ASSERT(IE_SIZE(prHsExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prHsExtCap); ++ ++#else ++ /* Add Extended Capabilities IE */ ++ prExtCap = (P_EXT_CAP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; ++ ++ prExtCap->ucLength = 3 - ELEM_HDR_LEN; ++ kalMemZero(prExtCap->aucCapabilities, sizeof(prExtCap->aucCapabilities)); ++ ++ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; ++ ++ if (!fg40mAllowed) ++ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; ++ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; ++ ++ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme) ++{ ++ P_IE_HT_OP_T prHtOp; ++ UINT_16 i; ++ ++ prHtOp = (P_IE_HT_OP_T) pFme; ++ ++ /* Add HT operation IE */ ++ prHtOp->ucId = ELEM_ID_HT_OP; ++ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; ++ ++ /* RIFS and 20/40 bandwidth operations are included */ ++ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; ++ ++ /* Decide HT protection mode field */ ++ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; ++ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; ++ else { ++ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ ++ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; ++ } ++ ++ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { ++ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED ++ * Note: it will also be set in ad-hoc network ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; ++ } ++ ++ if (0 /* Regulatory class 16 */ && ++ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { ++ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection ++ * although it is possible to have no protection by spec. ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; ++ } ++ ++ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ ++ ++ /* No basic MCSx are needed temporarily */ ++ for (i = 0; i < 16; i++) ++ prHtOp->aucBasicMcsSet[i] = 0; ++ ++ return sizeof(IE_HT_OP_T); ++} ++ ++static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) ++{ ++/* P_IE_HT_OP_T prHtOp; */ ++/* UINT_16 i; */ ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ASSERT(prMsduInfo); ++ ++ prMsduInfo->u2FrameLength += rlmFillHtOpIeBody(prBssInfo, ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength)); ++#if 0 ++ prHtOp = (P_IE_HT_OP_T) ++ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); ++ ++ /* Add HT operation IE */ ++ prHtOp->ucId = ELEM_ID_HT_OP; ++ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; ++ ++ /* RIFS and 20/40 bandwidth operations are included */ ++ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; ++ ++ /* Decide HT protection mode field */ ++ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; ++ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) ++ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; ++ else { ++ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ ++ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; ++ } ++ ++ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { ++ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED ++ * Note: it will also be set in ad-hoc network ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; ++ } ++ ++ if (0 /* Regulatory class 16 */ && ++ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { ++ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection ++ * although it is possible to have no protection by spec. ++ */ ++ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; ++ } ++ ++ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ ++ ++ /* No basic MCSx are needed temporarily */ ++ for (i = 0; i < 16; i++) ++ prHtOp->aucBasicMcsSet[i] = 0; ++ ++ ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP)); ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(prHtOp); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked to update parameters of associated AP. ++* (Association response and Beacon) ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ UINT_16 u2Offset; ++ P_STA_RECORD_T prStaRec; ++ P_IE_HT_CAP_T prHtCap; ++ P_IE_HT_OP_T prHtOp; ++ P_IE_OBSS_SCAN_PARAM_T prObssScnParam; ++ UINT_8 ucERP, ucPrimaryChannel; ++#if CFG_SUPPORT_QUIET && 0 ++ BOOLEAN fgHasQuietIE = FALSE; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ASSERT(pucIE); ++ ++ prStaRec = prBssInfo->prStaRecOfAP; ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return 0; ++ ++ prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; ++ ucPrimaryChannel = 0; ++ prObssScnParam = NULL; ++ ++ /* Note: HT-related members in staRec may not be zero before, so ++ * if following IE does not exist, they are still not zero. ++ * These HT-related parameters are valid only when the corresponding ++ * BssInfo supports 802.11n, i.e., RLM_NET_IS_11N() ++ */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_HT_CAP: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) ++ break; ++ prHtCap = (P_IE_HT_CAP_T) pucIE; ++ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; ++ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; ++ ++ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; ++ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; ++ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; ++ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; ++ prStaRec->ucAselCap = prHtCap->ucAselCap; ++ break; ++ ++ case ELEM_ID_HT_OP: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) ++ break; ++ prHtOp = (P_IE_HT_OP_T) pucIE; ++ /* Workaround that some APs fill primary channel field by its ++ * secondary channel, but its DS IE is correct 20110610 ++ */ ++ if (ucPrimaryChannel == 0) ++ ucPrimaryChannel = prHtOp->ucPrimaryChannel; ++ prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1; ++ prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2; ++ prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3; ++ ++ if (!prBssInfo->fg40mBwAllowed) ++ prBssInfo->ucHtOpInfo1 &= ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH); ++ ++ if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) ++ prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)(prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO); ++ ++ prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T) ++ (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION); ++ ++ /* To do: process regulatory class 16 */ ++ if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) ++ && 0 /* && regulatory class is 16 */) ++ prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED; ++ else if (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) ++ prBssInfo->eGfOperationMode = GF_MODE_PROTECT; ++ else ++ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; ++ ++ prBssInfo->eRifsOperationMode = ++ (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ? RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED; ++ ++ break; ++ ++ case ELEM_ID_20_40_BSS_COEXISTENCE: ++ if (!RLM_NET_IS_11N(prBssInfo)) ++ break; ++ /* To do: store if scanning exemption grant to BssInfo */ ++ break; ++ ++ case ELEM_ID_OBSS_SCAN_PARAMS: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) ++ break; ++ /* Store OBSS parameters to BssInfo */ ++ prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE; ++ break; ++ ++ case ELEM_ID_EXTENDED_CAP: ++ if (!RLM_NET_IS_11N(prBssInfo)) ++ break; ++ /* To do: store extended capability (PSMP, coexist) to BssInfo */ ++ break; ++ ++ case ELEM_ID_ERP_INFO: ++ if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) || prBssInfo->eBand != BAND_2G4) ++ break; ++ ucERP = ERP_INFO_IE(pucIE)->ucERP; ++ prBssInfo->fgErpProtectMode = (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE; ++ ++ if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) ++ prBssInfo->fgUseShortPreamble = FALSE; ++ break; ++ ++ case ELEM_ID_DS_PARAM_SET: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) ++ ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; ++ break; ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++ case ELEM_ID_CH_SW_ANNOUNCEMENT: ++ { ++ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) pucIE); ++ } ++ break; ++ ++#if CFG_SUPPORT_QUIET && 0 ++ /* Note: RRM code should be moved to independent RRM function by ++ * component design rule. But we attach it to RLM temporarily ++ */ ++ case ELEM_ID_QUIET: ++ rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE); ++ fgHasQuietIE = TRUE; ++ break; ++#endif ++#endif ++ ++ default: ++ break; ++ } /* end of switch */ ++ } /* end of IE_FOR_EACH */ ++ ++ /* Some AP will have wrong channel number (255) when running time. ++ * Check if correct channel number information. 20110501 ++ */ ++ if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) || ++ (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14))) ++ ucPrimaryChannel = 0; ++#if CFG_SUPPORT_QUIET && 0 ++ if (!fgHasQuietIE) ++ rrmQuietIeNotExist(prAdapter, prBssInfo); ++#endif ++ ++ /* Check if OBSS scan process will launch */ ++ if (!prAdapter->fgEnOnlineScan || !prObssScnParam || ++ !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) || ++ prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) { ++ ++ /* Note: it is ok not to stop rObssScanTimer() here */ ++ prBssInfo->u2ObssScanInterval = 0; ++ } else { ++ if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) ++ prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL; ++ if (prBssInfo->u2ObssScanInterval != prObssScnParam->u2TriggerScanInterval) { ++ ++ prBssInfo->u2ObssScanInterval = prObssScnParam->u2TriggerScanInterval; ++ ++ /* Start timer to trigger OBSS scanning */ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, ++ prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); ++ } ++ } ++ ++ return ucPrimaryChannel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief AIS or P2P GC. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN ++rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ UINT_16 u2Offset, i; ++ UINT_8 ucPriChannel, ucSecChannel; ++ ENUM_CHNL_EXT_T eSCO; ++ BOOLEAN fgHtBss, fg20mReq; ++ ++ if ((prAdapter == NULL) ++ || (pucIE == NULL) ++ || (prBssInfo == NULL) ++ || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ /* Record it to channel list to change 20/40 bandwidth */ ++ ucPriChannel = 0; ++ eSCO = CHNL_EXT_SCN; ++ ++ fgHtBss = FALSE; ++ fg20mReq = FALSE; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_HT_CAP: ++ { ++ P_IE_HT_CAP_T prHtCap; ++ ++ if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) ++ break; ++ ++ prHtCap = (P_IE_HT_CAP_T) pucIE; ++ if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) ++ fg20mReq = TRUE; ++ fgHtBss = TRUE; ++ break; ++ } ++ case ELEM_ID_HT_OP: ++ { ++ P_IE_HT_OP_T prHtOp; ++ ++ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) ++ break; ++ ++ prHtOp = (P_IE_HT_OP_T) pucIE; ++ /* Workaround that some APs fill primary channel field by its ++ * secondary channel, but its DS IE is correct 20110610 ++ */ ++ if (ucPriChannel == 0) ++ ucPriChannel = prHtOp->ucPrimaryChannel; ++ ++ if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) ++ eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO); ++ break; ++ } ++ case ELEM_ID_20_40_BSS_COEXISTENCE: ++ { ++ P_IE_20_40_COEXIST_T prCoexist; ++ ++ if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) ++ break; ++ ++ prCoexist = (P_IE_20_40_COEXIST_T) pucIE; ++ if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) ++ fg20mReq = TRUE; ++ break; ++ } ++ case ELEM_ID_DS_PARAM_SET: ++ if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) ++ break; ++ ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* To do: Update channel list and 5G band. All channel lists have the same ++ * update procedure. We should give it the entry pointer of desired ++ * channel list. ++ */ ++ if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) ++ return FALSE; ++ ++ if (ucPriChannel == 0 || ucPriChannel > 14) ++ ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); ++ ++ if (fgHtBss) { ++ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_PriChnlList[i] = ucPriChannel; ++ prBssInfo->auc2G_PriChnlList[0]++; ++ } ++ ++ /* Update secondary channel */ ++ if (eSCO != CHNL_EXT_SCN) { ++ ucSecChannel = (eSCO == CHNL_EXT_SCA) ? (ucPriChannel + 4) : (ucPriChannel - 4); ++ ++ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_SecChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_SecChnlList[i] = ucSecChannel; ++ prBssInfo->auc2G_SecChnlList[0]++; ++ } ++ } ++ ++ /* Update 20M bandwidth request channels */ ++ if (fg20mReq) { ++ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel; ++ prBssInfo->auc2G_20mReqChnlList[0]++; ++ } ++ } ++ } else { ++ /* Update non-HT channel list */ ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { ++ if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) ++ break; ++ } ++ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { ++ prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel; ++ prBssInfo->auc2G_NonHtChnlList[0]++; ++ } ++ ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief AIS or P2P GC. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN ++rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ if ((prAdapter == NULL) ++ || (pucIE == NULL) ++ || (prBssInfo == NULL) ++ || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++#if 0 /* SW migration 2010/8/20 */ ++ /* Note: we shall not update parameters when scanning, otherwise ++ * channel and bandwidth will not be correct or asserted failure ++ * during scanning. ++ * Note: remove channel checking. All received Beacons should be processed ++ * if measurement or other actions are executed in adjacent channels ++ * and Beacon content checking mechanism is not disabled. ++ */ ++ if (IS_SCAN_ACTIVE() ++ /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */ ++ ) { ++ return FALSE; ++ } ++#endif ++ ++ /* Handle change of slot time */ ++ prBssInfo->u2CapInfo = ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->u2CapInfo; ++ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; ++ ++ rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ P_BSS_INFO_T prBssInfo; ++ BOOLEAN fgNewParameter; ++ UINT_8 ucNetIdx; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ fgNewParameter = FALSE; ++ ++ /* When concurrent networks exist, GO shall have the same handle as ++ * the other BSS, so the Beacon shall be processed for bandwidth and ++ * protection mechanism. ++ * Note1: we do not have 2 AP (GO) cases simultaneously now. ++ * Note2: If we are GO, concurrent AIS AP should detect it and reflect ++ * action in its Beacon, so AIS STA just follows Beacon from AP. ++ */ ++ RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; ++ ASSERT(prBssInfo); ++ ++ if (IS_BSS_ACTIVE(prBssInfo)) { ++ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && ++ prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* P2P client or AIS infra STA */ ++ if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, ((P_WLAN_MAC_MGMT_HEADER_T) ++ (prSwRfb->pvHeader))->aucBSSID)) { ++ ++ fgNewParameter = rlmRecBcnInfoForClient(prAdapter, ++ prBssInfo, prSwRfb, pucIE, u2IELength); ++ } else { ++ fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter, ++ prBssInfo, prSwRfb, pucIE, ++ u2IELength); ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered && ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || ++ prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) { ++ /* AP scan to check if 20/40M bandwidth is permitted */ ++ rlmRecBcnFromNeighborForClient(prAdapter, prBssInfo, prSwRfb, pucIE, u2IELength); ++ } ++#endif ++ else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { ++ /* Do nothing */ ++ /* To do: Ad-hoc */ ++ } ++ ++ /* Appy new parameters if necessary */ ++ if (fgNewParameter) { ++ DBGLOG(RLM, TRACE, "rlmProcessBcn\n"); ++ rlmSyncOperationParams(prAdapter, prBssInfo); ++ fgNewParameter = FALSE; ++ } ++ } /* end of IS_BSS_ACTIVE() */ ++ } /* end of RLM_NET_FOR_EACH_NO_BOW */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked after judging successful association. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ UINT_8 ucPriChannel; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ASSERT(prStaRec == prBssInfo->prStaRecOfAP); ++ ++ /* To do: the invoked function is used to clear all members. It may be ++ * done by center mechanism in invoker. ++ */ ++ rlmBssReset(prAdapter, prBssInfo); ++ ++ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; ++ ++ ucPriChannel = rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); ++ if (ucPriChannel > 0) ++ prBssInfo->ucPrimaryChannel = ucPriChannel; ++ ++ if (!RLM_NET_IS_11N(prBssInfo) || !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) ++ prBssInfo->fg40mBwAllowed = FALSE; ++ ++ /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which ++ * shall be invoked afterwards. ++ * Update channel, bandwidth and protection mode by nicUpdateBss() ++ */ ++#if 1 ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ ++ DBGLOG(P2P, WARN, "Force P2P BW to 20\n"); ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked after judging successful association. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prCmdBody && prBssInfo); ++ if (!prCmdBody || !prBssInfo) ++ return; ++ ++ prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; ++ prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand; ++ prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; ++ prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO; ++ prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode; ++ prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode; ++ prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode; ++ prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode; ++ prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3; ++ prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2; ++ prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1; ++ prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble; ++ prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime; ++ prCmdBody->ucCheckId = 0x72; ++ ++ if (RLM_NET_PARAM_VALID(prBssInfo)) { ++ DBGLOG(RLM, INFO, "N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n", ++ prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand, ++ prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco, ++ prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode, ++ prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime, ++ prCmdBody->ucUseShortPreamble); ++ } else { ++ DBGLOG(RLM, TRACE, "N=%d closed\n", prCmdBody->ucNetTypeIndex); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will operation parameters based on situations of ++* concurrent networks. Channel, bandwidth, protection mode, supported ++* rate will be modified. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ P_CMD_SET_BSS_RLM_PARAM_T prCmdBody; ++ WLAN_STATUS rStatus; ++ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T) ++ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T)); ++ ASSERT(prCmdBody); ++ ++ /* To do: exception handle */ ++ if (!prCmdBody) { ++ DBGLOG(RLM, WARN, "No buf for sync RLM params (Net=%d)\n", prBssInfo->ucNetTypeIndex); ++ return; ++ } ++ ++ rlmFillSyncCmdParam(prCmdBody, prBssInfo); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_BSS_RLM_PARAM, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SET_BSS_RLM_PARAM_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdBody, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++ cnmMemFree(prAdapter, prCmdBody); ++} ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function should be invoked after judging successful association. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ P_IE_HT_CAP_T prHtCap; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_HT_CAP: ++ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) ++ break; ++ prHtCap = (P_IE_HT_CAP_T) pucIE; ++ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; ++ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; ++ ++ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; ++ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; ++ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; ++ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; ++ prStaRec->ucAselCap = prHtCap->ucAselCap; ++ break; ++ ++ default: ++ break; ++ } /* end of switch */ ++ } /* end of IE_FOR_EACH */ ++} ++#endif /* CFG_SUPPORT_AAA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief It is for both STA and AP modes ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) ++ rlmBssInitForAP(prAdapter, prBssInfo); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief It is for both STA and AP modes ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ rlmBssReset(prAdapter, prBssInfo); ++ ++ prBssInfo->fg40mBwAllowed = FALSE; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ ++ /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so ++ * the sync CMD is not needed here. ++ */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief All RLM timers will also be stopped. ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prBssInfo); ++ ++ /* HT related parameters */ ++ prBssInfo->ucHtOpInfo1 = 0; /* RIFS disabled. 20MHz */ ++ prBssInfo->u2HtOpInfo2 = 0; ++ prBssInfo->u2HtOpInfo3 = 0; ++ ++ prBssInfo->eBssSCO = 0; ++ prBssInfo->fgErpProtectMode = 0; ++ prBssInfo->eHtProtectMode = 0; ++ prBssInfo->eGfOperationMode = 0; ++ prBssInfo->eRifsOperationMode = 0; ++ ++ /* OBSS related parameters */ ++ prBssInfo->auc2G_20mReqChnlList[0] = 0; ++ prBssInfo->auc2G_NonHtChnlList[0] = 0; ++ prBssInfo->auc2G_PriChnlList[0] = 0; ++ prBssInfo->auc2G_SecChnlList[0] = 0; ++ prBssInfo->auc5G_20mReqChnlList[0] = 0; ++ prBssInfo->auc5G_NonHtChnlList[0] = 0; ++ prBssInfo->auc5G_PriChnlList[0] = 0; ++ prBssInfo->auc5G_SecChnlList[0] = 0; ++ ++ /* All RLM timers will also be stopped */ ++ cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer); ++ prBssInfo->u2ObssScanInterval = 0; ++ ++ prBssInfo->fgObssErpProtectMode = 0; /* GO only */ ++ prBssInfo->eObssHtProtectMode = 0; /* GO only */ ++ prBssInfo->eObssGfOperationMode = 0; /* GO only */ ++ prBssInfo->fgObssRifsOperationMode = 0; /* GO only */ ++ prBssInfo->fgObssActionForcedTo20M = 0; /* GO only */ ++ prBssInfo->fgObssBeaconForcedTo20M = 0; /* GO only */ ++} ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function handle spectrum management action frame ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_CHANNEL_SWITCH_FRAME prRxFrame; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ DBGLOG(RLM, INFO, "[5G DFS]rlmProcessSpecMgtAction \r\n"); ++ ++ prRxFrame = (P_ACTION_CHANNEL_SWITCH_FRAME) prSwRfb->pvHeader; ++ DBGLOG(RLM, INFO, "[5G DFS]prRxFrame->ucAction[%d] \r\n", prRxFrame->ucAction); ++ if (prRxFrame->ucAction == ACTION_CHNL_SWITCH) ++ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) prRxFrame->aucInfoElem); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function process Channel Switch IE ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE) ++{ ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prChannelSwitchIE); ++ ++ DBGLOG(RLM, INFO, "[5G DFS] rlmProcessChannelSwitchIE \r\n"); ++ DBGLOG(RLM, INFO, "[5G DFS] ucChannelSwitchMode[%d], ucChannelSwitchCount[%d], ucNewChannelNum[%d] \r\n", ++ prChannelSwitchIE->ucChannelSwitchMode, ++ prChannelSwitchIE->ucChannelSwitchCount, prChannelSwitchIE->ucNewChannelNum); ++ if (prChannelSwitchIE->ucChannelSwitchMode == 1) { ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ DBGLOG(RLM, INFO, "[5G DFS] switch channel [%d]->[%d] \r\n", prAisBssInfo->ucPrimaryChannel, ++ prChannelSwitchIE->ucNewChannelNum); ++ prAisBssInfo->ucPrimaryChannel = prChannelSwitchIE->ucNewChannelNum; ++ nicUpdateBss(prAdapter, prAisBssInfo->ucNetTypeIndex); ++ } ++ ++} ++ ++#endif ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++VOID ++rlmTxRateEnhanceConfig( ++ P_ADAPTER_T prAdapter ++ ) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ CMD_RLM_INFO_T rTxRInfo; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ++ /* init */ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* suggestion from Tsaiyuan.Hsu */ ++ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); ++ rTxRInfo.fgIsErrRatioEnhanceApplied = TRUE; ++ rTxRInfo.ucErrRatio2LimitMinRate = 3; ++ rTxRInfo.ucMinLegacyRateIdx = 2; ++ rTxRInfo.cMinRssiThreshold = -60; ++ rTxRInfo.fgIsRtsApplied = TRUE; ++ rTxRInfo.ucRecoverTime = 60; ++ ++ DBGLOG(RLM, INFO, "Enable tx rate enhance function\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetTxRateInfo, ++ &rTxRInfo, ++ sizeof(rTxRInfo), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(RLM, WARN, "set tx rate advance info fail 0x%lx\n", rStatus); ++} ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a command to TX Auto Rate module. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ UINT_32 u4Subcmd; ++ ++ ++ /* parse TAR sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(RLM, INFO, " sub command = %u\n", (UINT32)u4Subcmd); ++ ++ /* handle different sub-command */ ++ switch (u4Subcmd) { ++ case 0x00: /* configure */ ++ /* iwpriv wlan0 set_str_cmd 1_0_0_1_3_2_60_1_60 */ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ CMD_RLM_INFO_T rTxRInfo; ++ UINT_32 u4SetInfoLen = 0; ++ ++ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); ++ rTxRInfo.u4Version = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.fgIsErrRatioEnhanceApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.ucErrRatio2LimitMinRate = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.ucMinLegacyRateIdx = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.cMinRssiThreshold = 0 - CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.fgIsRtsApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rTxRInfo.ucRecoverTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(RLM, INFO, " rlmCmd = %u %u %u %u %d %u %u\n", ++ rTxRInfo.u4Version, ++ rTxRInfo.fgIsErrRatioEnhanceApplied, ++ rTxRInfo.ucErrRatio2LimitMinRate, ++ rTxRInfo.ucMinLegacyRateIdx, ++ rTxRInfo.cMinRssiThreshold, ++ rTxRInfo.fgIsRtsApplied, ++ rTxRInfo.ucRecoverTime)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetTxRateInfo, ++ &rTxRInfo, ++ sizeof(rTxRInfo), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4SetInfoLen); ++ break; ++ ++ default: ++ break; ++ } ++} ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c +new file mode 100644 +index 000000000000..5e127488ea49 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c +@@ -0,0 +1,1791 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_domain.c#1 ++*/ ++ ++/*! \file "rlm_domain.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm_domain.c ++ * ++ * 11 10 2011 cm.chang ++ * NULL ++ * Modify debug message for XLOG ++ * ++ * 09 29 2011 cm.chang ++ * NULL ++ * Change the function prototype of rlmDomainGetChnlList() ++ * ++ * 09 23 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Let channel number to zero if band is illegal ++ * ++ * 09 22 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Exclude channel list with illegal band ++ * ++ * 09 15 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use defined country group to have a change to add new group ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 06 01 2011 cm.chang ++ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function ++ * Provide legal channel function based on domain ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support for WiFi Direct Network. ++ * ++ * 03 02 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Export rlmDomainGetDomainInfo for p2p driver. ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 03 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Filter out not supported RF freq when reporting available chnl list ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Provide query function about full channel list. ++ * ++ * Dec 1 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++#include "rlm_txpwr_init.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* The following country or domain shall be set from host driver. ++ * And host driver should pass specified DOMAIN_INFO_ENTRY to MT6620 as ++ * the channel list of being a STA to do scanning/searching AP or being an ++ * AP to choose an adequate channel if auto-channel is set. ++ */ ++ ++/* Define mapping tables between country code and its channel set ++ */ ++static const UINT_16 g_u2CountryGroup0[] = { ++ COUNTRY_CODE_AO, COUNTRY_CODE_BZ, COUNTRY_CODE_BJ, COUNTRY_CODE_BT, ++ COUNTRY_CODE_BO, COUNTRY_CODE_BI, COUNTRY_CODE_CM, COUNTRY_CODE_CF, ++ COUNTRY_CODE_TD, COUNTRY_CODE_KM, COUNTRY_CODE_CD, COUNTRY_CODE_CG, ++ COUNTRY_CODE_CI, COUNTRY_CODE_DJ, COUNTRY_CODE_GQ, COUNTRY_CODE_ER, ++ COUNTRY_CODE_FJ, COUNTRY_CODE_GA, COUNTRY_CODE_GM, COUNTRY_CODE_GN, ++ COUNTRY_CODE_GW, COUNTRY_CODE_RKS, COUNTRY_CODE_KG, COUNTRY_CODE_LY, ++ COUNTRY_CODE_MG, COUNTRY_CODE_ML, COUNTRY_CODE_NR, COUNTRY_CODE_NC, ++ COUNTRY_CODE_ST, COUNTRY_CODE_SC, COUNTRY_CODE_SL, COUNTRY_CODE_SB, ++ COUNTRY_CODE_SO, COUNTRY_CODE_SR, COUNTRY_CODE_SZ, COUNTRY_CODE_TJ, ++ COUNTRY_CODE_TG, COUNTRY_CODE_TO, COUNTRY_CODE_TM, COUNTRY_CODE_TV, ++ COUNTRY_CODE_VU, COUNTRY_CODE_YE ++}; ++ ++static const UINT_16 g_u2CountryGroup1[] = { ++ COUNTRY_CODE_AS, COUNTRY_CODE_AI, COUNTRY_CODE_BM, COUNTRY_CODE_CA, ++ COUNTRY_CODE_KY, COUNTRY_CODE_GU, COUNTRY_CODE_FM, COUNTRY_CODE_PR, ++ COUNTRY_CODE_US, COUNTRY_CODE_VI ++}; ++ ++static const UINT_16 g_u2CountryGroup2[] = { ++ COUNTRY_CODE_AR, COUNTRY_CODE_AU, COUNTRY_CODE_AZ, COUNTRY_CODE_BW, ++ COUNTRY_CODE_KH, COUNTRY_CODE_CX, COUNTRY_CODE_CO, COUNTRY_CODE_CR, ++#if (CFG_CN_SUPPORT_CLASS121 == 1) ++ COUNTRY_CODE_CN, ++#endif ++ COUNTRY_CODE_EC, COUNTRY_CODE_GD, COUNTRY_CODE_GT, COUNTRY_CODE_HK, ++ COUNTRY_CODE_KI, COUNTRY_CODE_LB, COUNTRY_CODE_LR, COUNTRY_CODE_MN, ++ COUNTRY_CODE_AN, COUNTRY_CODE_NZ, COUNTRY_CODE_NI, COUNTRY_CODE_PW, ++ COUNTRY_CODE_PY, COUNTRY_CODE_PE, COUNTRY_CODE_PH, COUNTRY_CODE_WS, ++ COUNTRY_CODE_SG, COUNTRY_CODE_LK, COUNTRY_CODE_TH, COUNTRY_CODE_TT, ++ COUNTRY_CODE_UY, COUNTRY_CODE_VN ++}; ++ ++static const UINT_16 g_u2CountryGroup3[] = { ++ COUNTRY_CODE_AW, COUNTRY_CODE_LA, COUNTRY_CODE_SA, COUNTRY_CODE_AE, ++ COUNTRY_CODE_UG ++}; ++ ++static const UINT_16 g_u2CountryGroup4[] = { COUNTRY_CODE_MM }; ++ ++static const UINT_16 g_u2CountryGroup5[] = { ++ COUNTRY_CODE_AL, COUNTRY_CODE_DZ, COUNTRY_CODE_AD, COUNTRY_CODE_AT, ++ COUNTRY_CODE_BY, COUNTRY_CODE_BE, COUNTRY_CODE_BA, COUNTRY_CODE_VG, ++ COUNTRY_CODE_BG, COUNTRY_CODE_CV, COUNTRY_CODE_HR, COUNTRY_CODE_CY, ++ COUNTRY_CODE_CZ, COUNTRY_CODE_DK, COUNTRY_CODE_EE, COUNTRY_CODE_ET, ++ COUNTRY_CODE_FI, COUNTRY_CODE_FR, COUNTRY_CODE_GF, COUNTRY_CODE_PF, ++ COUNTRY_CODE_TF, COUNTRY_CODE_GE, COUNTRY_CODE_DE, COUNTRY_CODE_GH, ++ COUNTRY_CODE_GR, COUNTRY_CODE_GP, COUNTRY_CODE_HU, COUNTRY_CODE_IS, ++ COUNTRY_CODE_IQ, COUNTRY_CODE_IE, COUNTRY_CODE_IT, COUNTRY_CODE_KE, ++ COUNTRY_CODE_LV, COUNTRY_CODE_LS, COUNTRY_CODE_LI, COUNTRY_CODE_LT, ++ COUNTRY_CODE_LU, COUNTRY_CODE_MK, COUNTRY_CODE_MT, COUNTRY_CODE_MQ, ++ COUNTRY_CODE_MR, COUNTRY_CODE_MU, COUNTRY_CODE_YT, COUNTRY_CODE_MD, ++ COUNTRY_CODE_MC, COUNTRY_CODE_ME, COUNTRY_CODE_MS, COUNTRY_CODE_NL, ++ COUNTRY_CODE_NO, COUNTRY_CODE_OM, COUNTRY_CODE_PL, COUNTRY_CODE_PT, ++ COUNTRY_CODE_RE, COUNTRY_CODE_RO, COUNTRY_CODE_MF, COUNTRY_CODE_SM, ++ COUNTRY_CODE_SN, COUNTRY_CODE_RS, COUNTRY_CODE_SK, COUNTRY_CODE_SI, ++ COUNTRY_CODE_ZA, COUNTRY_CODE_ES, COUNTRY_CODE_SE, COUNTRY_CODE_CH, ++ COUNTRY_CODE_TR, COUNTRY_CODE_TC, COUNTRY_CODE_GB, COUNTRY_CODE_VA, ++ COUNTRY_CODE_EU ++}; ++ ++static const UINT_16 g_u2CountryGroup6[] = { COUNTRY_CODE_JP }; ++ ++static const UINT_16 g_u2CountryGroup7[] = { ++ COUNTRY_CODE_AM, COUNTRY_CODE_IL, COUNTRY_CODE_KW, COUNTRY_CODE_MA, ++ COUNTRY_CODE_NE, COUNTRY_CODE_TN, COUNTRY_CODE_MA ++}; ++ ++static const UINT_16 g_u2CountryGroup8[] = { COUNTRY_CODE_NP }; ++ ++static const UINT_16 g_u2CountryGroup9[] = { COUNTRY_CODE_AF }; ++ ++static const UINT_16 g_u2CountryGroup10[] = { ++ COUNTRY_CODE_AG, COUNTRY_CODE_BS, COUNTRY_CODE_BH, COUNTRY_CODE_BB, ++ COUNTRY_CODE_BN, COUNTRY_CODE_CL, COUNTRY_CODE_EG, ++#if (CFG_CN_SUPPORT_CLASS121 == 0) ++ COUNTRY_CODE_CN, ++#endif ++ COUNTRY_CODE_SV, COUNTRY_CODE_IN, COUNTRY_CODE_MY, COUNTRY_CODE_MV, ++ COUNTRY_CODE_PA, COUNTRY_CODE_VE, COUNTRY_CODE_ZM ++}; ++ ++static const UINT_16 g_u2CountryGroup11[] = { COUNTRY_CODE_JO, COUNTRY_CODE_PG }; ++ ++static const UINT_16 g_u2CountryGroup12[] = { ++ COUNTRY_CODE_BF, COUNTRY_CODE_GY, COUNTRY_CODE_HT, COUNTRY_CODE_HN, ++ COUNTRY_CODE_JM, COUNTRY_CODE_MO, COUNTRY_CODE_MW, COUNTRY_CODE_PK, ++ COUNTRY_CODE_QA, COUNTRY_CODE_RW, COUNTRY_CODE_KN, COUNTRY_CODE_TZ ++}; ++ ++static const UINT_16 g_u2CountryGroup13[] = { COUNTRY_CODE_ID }; ++ ++static const UINT_16 g_u2CountryGroup14[] = { COUNTRY_CODE_KR }; ++ ++static const UINT_16 g_u2CountryGroup15[] = { COUNTRY_CODE_NG }; ++ ++static const UINT_16 g_u2CountryGroup16[] = { ++ COUNTRY_CODE_BD, COUNTRY_CODE_BR, COUNTRY_CODE_DM, COUNTRY_CODE_DO, ++ COUNTRY_CODE_FK, COUNTRY_CODE_KZ, COUNTRY_CODE_MX, COUNTRY_CODE_MZ, ++ COUNTRY_CODE_NA, COUNTRY_CODE_RU, COUNTRY_CODE_LC, COUNTRY_CODE_VC, ++ COUNTRY_CODE_UA, COUNTRY_CODE_UZ, COUNTRY_CODE_ZW ++}; ++ ++static const UINT_16 g_u2CountryGroup17[] = { COUNTRY_CODE_MP }; ++ ++static const UINT_16 g_u2CountryGroup18[] = { COUNTRY_CODE_TW }; ++ ++static const UINT_16 g_u2CountryGroup19[] = { ++ COUNTRY_CODE_CK, COUNTRY_CODE_CU, COUNTRY_CODE_TL, COUNTRY_CODE_FO, ++ COUNTRY_CODE_GI, COUNTRY_CODE_GG, COUNTRY_CODE_IR, COUNTRY_CODE_IM, ++ COUNTRY_CODE_JE, COUNTRY_CODE_KP, COUNTRY_CODE_MH, COUNTRY_CODE_NU, ++ COUNTRY_CODE_NF, COUNTRY_CODE_PS, COUNTRY_CODE_PN, COUNTRY_CODE_PM, ++ COUNTRY_CODE_SS, COUNTRY_CODE_SD, COUNTRY_CODE_SY ++}; ++ ++static const UINT_16 g_u2CountryGroup20[] = { ++ COUNTRY_CODE_DF, COUNTRY_CODE_FF ++ /* When country code is not found and no matched NVRAM setting, ++ * this domain info will be used. ++ */ ++}; ++ ++static const UINT_16 g_u2CountryGroup21[] = { ++ COUNTRY_CODE_UDF ++}; ++ ++DOMAIN_INFO_ENTRY arSupportedRegDomains[] = { ++ { ++ (PUINT_16) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_NA */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} ++ , /* CH_SET_2G4_1_11 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup2, sizeof(g_u2CountryGroup2) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ {82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE} ++ , /* CH_SET_2G4_14_14 */ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup7, sizeof(g_u2CountryGroup7) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup8, sizeof(g_u2CountryGroup8) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_UPPER_NA */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup10, sizeof(g_u2CountryGroup10) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup11, sizeof(g_u2CountryGroup11) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_NA */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_NA */ ++ {118, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_MID_NA */ ++ {121, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_WW_NA */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup14, sizeof(g_u2CountryGroup14) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 8, FALSE} ++ , /* CH_SET_UNII_WW_100_128 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} ++ , /* CH_SET_UNII_UPPER_149_161 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup15, sizeof(g_u2CountryGroup15) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_NULL, 0, 0, 0, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup16, sizeof(g_u2CountryGroup16) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup17, sizeof(g_u2CountryGroup17) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} ++ , /* CH_SET_2G4_1_11 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup18, sizeof(g_u2CountryGroup18) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} ++ , /* CH_SET_2G4_1_11 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 11, FALSE} ++ , /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ (PUINT_16) g_u2CountryGroup19, sizeof(g_u2CountryGroup19) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ /* Note: Default group if no matched country code */ ++ (PUINT_16) g_u2CountryGroup20, sizeof(g_u2CountryGroup20) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} ++ , /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} ++ , /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} ++ , /* CH_SET_UNII_WW_100_144 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} ++ , /* CH_SET_UNII_UPPER_149_165 */ ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++ , ++ { ++ /* Note: for customer configured their own scanning list and passive scan list */ ++ (PUINT_16) g_u2CountryGroup21, sizeof(g_u2CountryGroup21) / 2, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 1, 12, FALSE} ++ , /* CH_SET_2G4_1_13 */ ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE} ++ , ++ {118, BAND_5G, CHNL_SPAN_20, 52, 0, FALSE} ++ , ++ {121, BAND_5G, CHNL_SPAN_20, 100, 0, FALSE} ++ , ++ {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE} ++ , ++ {0, BAND_NULL, 0, 0, 0, FALSE} ++ } ++ } ++}; ++ ++static UINT_16 g_u2CountryGroup0_Passive[] = { ++ COUNTRY_CODE_UDF ++}; ++ ++DOMAIN_INFO_ENTRY arSupportedRegDomains_Passive[] = { ++ { ++ /* Default passive scan channel table is empty */ ++ COUNTRY_CODE_NULL, 0, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 11, 0, 0}, /* CH_SET_2G4_1_14 */ ++ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ ++ } ++ }, ++ { ++ /* User Defined passive scan channel table */ ++ g_u2CountryGroup0_Passive, 0, ++ { ++ {81, BAND_2G4, CHNL_SPAN_5, 12, 1, 0}, /* CH_SET_2G4_1_14 */ ++ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, ++ ++ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ ++ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ ++ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ ++ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ ++ } ++ } ++}; ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++SUBBAND_CHANNEL_T g_rRlmSubBand[] = { ++ ++ {BAND_2G4_LOWER_BOUND, BAND_2G4_UPPER_BOUND, 1, 0} ++ , /* 2.4G */ ++ {UNII1_LOWER_BOUND, UNII1_UPPER_BOUND, 2, 0} ++ , /* ch36,38,40,..,48 */ ++ {UNII2A_LOWER_BOUND, UNII2A_UPPER_BOUND, 2, 0} ++ , /* ch52,54,56,..,64 */ ++ {UNII2C_LOWER_BOUND, UNII2C_UPPER_BOUND, 2, 0} ++ , /* ch100,102,104,...,144 */ ++ {UNII3_LOWER_BOUND, UNII3_UPPER_BOUND, 2, 0} ++ /* ch149,151,153,....,173 */ ++}; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter) ++{ ++#define REG_DOMAIN_DEF_IDX 20 /* Default country domain */ ++#define REG_DOMAIN_GROUP_NUM \ ++ (sizeof(arSupportedRegDomains) / sizeof(DOMAIN_INFO_ENTRY)) ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ P_REG_INFO_T prRegInfo; ++ UINT_16 u2TargetCountryCode; ++ UINT_16 i, j; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->prDomainInfo) ++ return prAdapter->prDomainInfo; ++ ++ prRegInfo = &prAdapter->prGlueInfo->rRegInfo; ++ ++ DBGLOG(RLM, TRACE, "eRegChannelListMap=%d, u2CountryCode=0x%04x\n", ++ prRegInfo->eRegChannelListMap, ++ prAdapter->rWifiVar.rConnSettings.u2CountryCode); ++ ++ /* ++ * Domain info can be specified by given idx of arSupportedRegDomains table, ++ * customized, or searched by country code, ++ * only one is set among these three methods in NVRAM. ++ */ ++ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX && ++ prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) { ++ /* by given table idx */ ++ DBGLOG(RLM, TRACE, "ucRegChannelListIndex=%d\n", prRegInfo->ucRegChannelListIndex); ++ prDomainInfo = &arSupportedRegDomains[prRegInfo->ucRegChannelListIndex]; ++ } else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { ++ /* by customized */ ++ prDomainInfo = &prRegInfo->rDomainInfo; ++ } else { ++ /* by country code */ ++ u2TargetCountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ ++ for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) { ++ prDomainInfo = &arSupportedRegDomains[i]; ++ ++ if ((prDomainInfo->u4CountryNum && prDomainInfo->pu2CountryGroup) || ++ prDomainInfo->u4CountryNum == 0) { ++ for (j = 0; j < prDomainInfo->u4CountryNum; j++) { ++ if (prDomainInfo->pu2CountryGroup[j] == u2TargetCountryCode) ++ break; ++ } ++ if (j < prDomainInfo->u4CountryNum) ++ break; /* Found */ ++ } ++ } ++ ++ /* If no matched country code, use the default country domain */ ++ if (i >= REG_DOMAIN_GROUP_NUM) { ++ DBGLOG(RLM, INFO, "No matched country code, use the default country domain\n"); ++ prDomainInfo = &arSupportedRegDomains[REG_DOMAIN_DEF_IDX]; ++ } ++ } ++ ++ prAdapter->prDomainInfo = prDomainInfo; ++ return prDomainInfo; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] The input variable pointed by pucNumOfChannel is the max ++* arrary size. The return value indciates meaning list size. ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++rlmDomainGetChnlList(P_ADAPTER_T prAdapter, ++ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, ++ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList) ++{ ++ UINT_8 i, j, ucNum; ++ P_DOMAIN_SUBBAND_INFO prSubband; ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(paucChannelList); ++ ASSERT(pucNumOfChannel); ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ ucNum = 0; ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubband = &prDomainInfo->rSubBand[i]; ++ ++ if (prSubband->ucBand == BAND_NULL || prSubband->ucBand >= BAND_NUM || ++ (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand)) ++ continue; ++ ++ if (fgNoDfs == TRUE && prSubband->fgDfs == TRUE) ++ continue; ++ ++ if (eSpecificBand == BAND_NULL || prSubband->ucBand == eSpecificBand) { ++ for (j = 0; j < prSubband->ucNumChannels; j++) { ++ if (ucNum >= ucMaxChannelNum) ++ break; ++ paucChannelList[ucNum].eBand = prSubband->ucBand; ++ paucChannelList[ucNum].ucChannelNum = ++ prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan; ++ ucNum++; ++ } ++ } ++ } ++ ++ *pucNumOfChannel = ucNum; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) ++{ ++ rlmDomainSendDomainInfoCmd(prAdapter, fgIsOid); ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ rlmDomainSendPwrLimitCmd(prAdapter); ++#endif ++ rlmDomainSendPassiveScanInfoCmd(prAdapter, fgIsOid); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) ++{ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ P_CMD_SET_DOMAIN_INFO_T prCmd; ++ P_DOMAIN_SUBBAND_INFO prSubBand; ++ UINT_8 i; ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); ++ return; ++ } ++ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ ++ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ prCmd->u2IsSetPassiveScan = 0; ++ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; ++ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; ++ prCmd->aucReserved[0] = 0; ++ prCmd->aucReserved[1] = 0; ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubBand = &prDomainInfo->rSubBand[i]; ++ ++ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; ++ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; ++ ++ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { ++ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; ++ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; ++ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; ++ } ++ } ++ ++ /* Set domain info to chip */ ++ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ fgIsOid, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ ++ (PUINT_8)prCmd, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ cnmMemFree(prAdapter, prCmd); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) ++{ ++#define REG_DOMAIN_PASSIVE_DEF_IDX 0 ++#define REG_DOMAIN_PASSIVE_UDF_IDX 1 ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ P_CMD_SET_DOMAIN_INFO_T prCmd; ++ P_DOMAIN_SUBBAND_INFO prSubBand; ++ UINT_8 i; ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); ++ return; ++ } ++ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); ++ ++ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; ++ prCmd->u2IsSetPassiveScan = 1; ++ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; ++ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; ++ prCmd->aucReserved[0] = 0; ++ prCmd->aucReserved[1] = 0; ++ ++ DBGLOG(RLM, TRACE, "u2CountryCode=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCode); ++ ++ if (prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_UDF) ++ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_UDF_IDX]; ++ else ++ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_DEF_IDX]; ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubBand = &prDomainInfo->rSubBand[i]; ++ ++ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; ++ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; ++ ++ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { ++ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; ++ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; ++ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; ++ } ++ } ++ ++ /* Set passive scan channel info to chip */ ++ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ fgIsOid, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmd, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ cnmMemFree(prAdapter, prCmd); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] ++* ++* \return TRUE Legal channel ++* FALSE Illegal channel for current regulatory domain ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel) ++{ ++ UINT_8 i, j; ++ P_DOMAIN_SUBBAND_INFO prSubband; ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); ++ ASSERT(prDomainInfo); ++ ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ prSubband = &prDomainInfo->rSubBand[i]; ++ ++ if (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand) ++ continue; ++ ++ if (prSubband->ucBand == eBand) { ++ for (j = 0; j < prSubband->ucNumChannels; j++) { ++ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) ++ == ucChannel) { ++ return TRUE; ++ } ++ } ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in/out] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf) ++{ ++ /* ++ The Country element should only be included for Status Code 0 (Successful). ++ */ ++ UINT_32 u4IeLen; ++ UINT_8 aucClass[12] = { 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, ++ 0x1c, 0x1e, 0x20, 0x21 ++ }; ++ ++ /* ++ The Supported Operating Classes element is used by a STA to advertise the ++ operating classes that it is capable of operating with in this country. ++ ++ The Country element (see 8.4.2.10) allows a STA to configure its PHY and MAC ++ for operation when the operating triplet of Operating Extension Identifier, ++ Operating Class, and Coverage Class fields is present. ++ */ ++ SUP_OPERATING_CLASS_IE(pBuf)->ucId = ELEM_ID_SUP_OPERATING_CLASS; ++ SUP_OPERATING_CLASS_IE(pBuf)->ucLength = 1 + sizeof(aucClass); ++ SUP_OPERATING_CLASS_IE(pBuf)->ucCur = 0x0c; /* 0x51 */ ++ kalMemCopy(SUP_OPERATING_CLASS_IE(pBuf)->ucSup, aucClass, sizeof(aucClass)); ++ u4IeLen = (SUP_OPERATING_CLASS_IE(pBuf)->ucLength + 2); ++ pBuf += u4IeLen; ++ ++ COUNTRY_IE(pBuf)->ucId = ELEM_ID_COUNTRY_INFO; ++ COUNTRY_IE(pBuf)->ucLength = 6; ++ COUNTRY_IE(pBuf)->aucCountryStr[0] = 0x55; ++ COUNTRY_IE(pBuf)->aucCountryStr[1] = 0x53; ++ COUNTRY_IE(pBuf)->aucCountryStr[2] = 0x20; ++ COUNTRY_IE(pBuf)->arCountryStr[0].ucFirstChnlNum = 1; ++ COUNTRY_IE(pBuf)->arCountryStr[0].ucNumOfChnl = 11; ++ COUNTRY_IE(pBuf)->arCountryStr[0].cMaxTxPwrLv = 0x1e; ++ u4IeLen += (COUNTRY_IE(pBuf)->ucLength + 2); ++ ++ return u4IeLen; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (fgValid) : 0 -> inValid, 1 -> Valid ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh) ++{ ++ BOOLEAN fgValid = FALSE; ++ UINT_8 ucTemp = 0; ++ UINT_8 i; ++ /*Check Power limit table channel efficient or not */ ++ ++ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { ++ if ((ucCentralCh >= g_rRlmSubBand[i].ucStartCh) && (ucCentralCh <= g_rRlmSubBand[i].ucEndCh)) ++ ucTemp = (ucCentralCh - g_rRlmSubBand[i].ucStartCh) % g_rRlmSubBand[i].ucInterval; ++ } ++ ++#if 0 ++ /*2.4G, ex 1, 2, 3 */ ++ if (ucCentralCh >= BAND_2G4_LOWER_BOUND && ucCentralCh <= BAND_2G4_UPPER_BOUND) ++ ucTemp = 0; ++ /*FCC- Spec : Band UNII-1, ex 36, 38, 40.... */ ++ else if (ucCentralCh >= UNII1_LOWER_BOUND && ucCentralCh <= UNII1_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII1_LOWER_BOUND) % 2; ++ /*FCC- Spec : Band UNII-2A, ex 52, 54, 56.... */ ++ else if (ucCentralCh >= UNII2A_LOWER_BOUND && ucCentralCh <= UNII2A_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII2A_LOWER_BOUND) % 2; ++ /*FCC- Spec : Band UNII-2C, ex 100, 102, 104.... */ ++ else if (ucCentralCh >= UNII2C_LOWER_BOUND && ucCentralCh <= UNII2C_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII2C_LOWER_BOUND) % 2; ++ /*FCC- Spec : Band UNII-3, ex 149, 151, 153... */ ++ else if (ucCentralCh >= UNII3_LOWER_BOUND && ucCentralCh <= UNII3_UPPER_BOUND) ++ ucTemp = (ucCentralCh - UNII3_LOWER_BOUND) % 2; ++#endif ++ if (ucTemp == 0) ++ fgValid = TRUE; ++ return fgValid; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) ++{ ++ UINT_8 ucCenterChannel; ++ ++ if (eExtend == CHNL_EXT_SCA) ++ ucCenterChannel = ucPriChannel + 2; ++ else if (eExtend == CHNL_EXT_SCB) ++ ucCenterChannel = ucPriChannel - 2; ++ else ++ ucCenterChannel = ucPriChannel; ++ ++ return ucCenterChannel; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ++ ENUM_BAND_T eBand, ++ UINT_8 ucPriChannel, ++ ENUM_CHNL_EXT_T eExtend, ++ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2) ++{ ++ UINT_8 ucCenterChannel; ++ BOOLEAN fgValidChannel = TRUE; ++ BOOLEAN fgValidBW = TRUE; ++ BOOLEAN fgValidRfSetting = TRUE; ++ UINT_32 u4PrimaryOffset; ++ ++ /*DBG msg for Channel InValid */ ++ if (eChannelWidth == CW_20_40MHZ) { ++ ucCenterChannel = rlmDomainGetCenterChannel(eBand, ucPriChannel, eExtend); ++ ++ /* Check Central Channel Valid or Not */ ++ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); ++ if (fgValidChannel == FALSE) ++ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); ++ } else if (eChannelWidth == CW_80MHZ) { ++ ucCenterChannel = ucChannelS1; ++ ++ /* Check Central Channel Valid or Not */ ++ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); ++ if (fgValidChannel == FALSE) ++ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); ++ } else if (eChannelWidth == CW_160MHZ) { ++ ucCenterChannel = ucChannelS2; ++ ++ /* Check Central Channel Valid or Not */ ++ /*TODo */ ++ } ++ ++ /* Check BW Setting Correct or Not */ ++ if (eBand == BAND_2G4) { ++ if (eChannelWidth != CW_20_40MHZ) { ++ fgValidBW = FALSE; ++ DBGLOG(RLM, WARN, "Rf: B=%d, W=%d\n", eBand, eChannelWidth); ++ } ++ } else { ++ if (eChannelWidth == CW_80MHZ) { ++ u4PrimaryOffset = CAL_CH_OFFSET_80M(ucPriChannel, ucCenterChannel); ++ if (u4PrimaryOffset > 4) { ++ fgValidBW = FALSE; ++ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); ++ } ++ } else if (eChannelWidth == CW_160MHZ) { ++ u4PrimaryOffset = CAL_CH_OFFSET_160M(ucPriChannel, ucCenterChannel); ++ if (u4PrimaryOffset > 8) { ++ fgValidBW = FALSE; ++ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); ++ } ++ } ++ } ++ ++ if ((fgValidBW == FALSE) || (fgValidChannel == FALSE)) ++ fgValidRfSetting = FALSE; ++ ++ return fgValidRfSetting; ++ ++} ++ ++#if CFG_SUPPORT_PWR_LIMIT_COUNTRY ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (fgValid) : 0 -> inValid, 1 -> Valid ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, ++ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, ++ UINT_8 ucPwrLimitNum) ++{ ++ UINT_8 i; ++ BOOLEAN fgValid = TRUE; ++ PINT_8 prPwrLimit; ++ ++ prPwrLimit = &rPowerLimitTableConfiguration.aucPwrLimit[0]; ++ ++ for (i = 0; i < ucPwrLimitNum; i++, prPwrLimit++) { ++ if (*prPwrLimit > MAX_TX_POWER || *prPwrLimit < MIN_TX_POWER) { ++ fgValid = FALSE; ++ break; /*Find out Wrong Power limit */ ++ } ++ } ++ return fgValid; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter) ++{ ++ UINT_8 i, j; ++ UINT_16 u2CountryCodeTable, u2CountryCodeCheck; ++ BOOLEAN fgChannelValid = FALSE; ++ BOOLEAN fgPowerLimitValid = FALSE; ++ BOOLEAN fgEntryRepetetion = FALSE; ++ BOOLEAN fgTableValid = TRUE; ++ ++ /*Configuration Table Check */ ++ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { ++ /*Table Country Code */ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ /*Repetition Entry Check */ ++ for (j = i + 1; ++ j < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); ++ j++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[j].aucCountryCode[0], &u2CountryCodeCheck); ++ if (((g_rRlmPowerLimitConfiguration[i].ucCentralCh) == ++ g_rRlmPowerLimitConfiguration[j].ucCentralCh) ++ && (u2CountryCodeTable == u2CountryCodeCheck)) { ++ fgEntryRepetetion = TRUE; ++ DBGLOG(RLM, LOUD, "Domain: Configuration Repetition CC=%c%c, Ch=%d\n", ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], ++ g_rRlmPowerLimitConfiguration[i].ucCentralCh); ++ } ++ } ++ ++ /*Channel Number Check */ ++ fgChannelValid = ++ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); ++ ++ /*Power Limit Check */ ++ fgPowerLimitValid = ++ rlmDomainCheckPowerLimitValid(prAdapter, g_rRlmPowerLimitConfiguration[i], PWR_LIMIT_NUM); ++ ++ if (fgChannelValid == FALSE || fgPowerLimitValid == FALSE) { ++ fgTableValid = FALSE; ++ DBGLOG(RLM, LOUD, "Domain: CC=%c%c, Ch=%d, Limit: %d,%d,%d,%d,%d\n", ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], ++ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], ++ g_rRlmPowerLimitConfiguration[i].ucCentralCh, ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M], ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]); ++ } ++ ++ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { ++ DBGLOG(RLM, LOUD, "Domain: Full search down\n"); ++ break; /*End of country table entry */ ++ } ++ ++ } ++ ++ if (fgEntryRepetetion == FALSE) ++ DBGLOG(RLM, TRACE, "Domain: Configuration Table no Repetiton.\n"); ++ ++ /*Configuration Table no error */ ++ if (fgTableValid == TRUE) ++ prAdapter->fgIsPowerLimitTableValid = TRUE; ++ else ++ prAdapter->fgIsPowerLimitTableValid = FALSE; ++ ++ /*Default Table Check */ ++ fgEntryRepetetion = FALSE; ++ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ for (j = i + 1; j < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); j++) { ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[j].aucCountryCode[0], &u2CountryCodeCheck); ++ if (u2CountryCodeTable == u2CountryCodeCheck) { ++ fgEntryRepetetion = TRUE; ++ DBGLOG(RLM, LOUD, ++ "Domain: Default Repetition CC=%c%c\n", ++ g_rRlmPowerLimitDefault[j].aucCountryCode[0], ++ g_rRlmPowerLimitDefault[j].aucCountryCode[1]); ++ } ++ } ++ } ++ if (fgEntryRepetetion == FALSE) ++ DBGLOG(RLM, TRACE, "Domain: Default Table no Repetiton.\n"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (u2TableIndex) : if 0xFFFF -> No Table Match ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode) ++{ ++ ++ UINT_16 i; ++ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; ++ UINT_16 u2TableIndex = POWER_LIMIT_TABLE_NULL; /* No Table Match */ ++ ++ /*Default Table Index */ ++ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ if (u2CountryCodeTable == u2CountryCode) { ++ u2TableIndex = i; ++ break; /*match country code */ ++ } else if (u2CountryCodeTable == COUNTRY_CODE_NULL) { ++ u2TableIndex = i; ++ break; /*find last one country- Default */ ++ } ++ } ++ ++ DBGLOG(RLM, TRACE, "Domain: Default Table Index = %d\n", u2TableIndex); ++ ++ return u2TableIndex; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainBuildCmdByDefaultTable(P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd, UINT_16 u2DefaultTableIndex) ++{ ++ UINT_8 i, k; ++ P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT prPwrLimitSubBand; ++ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; ++ ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ prPwrLimitSubBand = &g_rRlmPowerLimitDefault[u2DefaultTableIndex]; ++ ++ /*Build power limit cmd by default table information */ ++ ++ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[i] < MAX_TX_POWER) { ++ for (k = g_rRlmSubBand[i].ucStartCh; k <= g_rRlmSubBand[i].ucEndCh; ++ k += g_rRlmSubBand[i].ucInterval) { ++ if ((prPwrLimitSubBand->ucPwrUnit & BIT(i)) == 0) { ++ prCmdPwrLimit->ucCentralCh = k; ++ prCmdPwrLimit->cPwrLimitCCK = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit20 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit40 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit80 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit160 = ++ prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ ++ } else { ++ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 ++ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ ++ prCmdPwrLimit->ucCentralCh = k; ++ prCmdPwrLimit->cPwrLimitCCK = prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit20 = prPwrLimitSubBand->aucPwrLimitSubBand[i]; ++ prCmdPwrLimit->cPwrLimit40 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 6; ++ if (prCmdPwrLimit->cPwrLimit40 > MAX_TX_POWER) ++ prCmdPwrLimit->cPwrLimit40 = MAX_TX_POWER; ++ prCmdPwrLimit->cPwrLimit80 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 12; ++ if (prCmdPwrLimit->cPwrLimit80 > MAX_TX_POWER) ++ prCmdPwrLimit->cPwrLimit80 = MAX_TX_POWER; ++ prCmdPwrLimit->cPwrLimit160 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 18; ++ if (prCmdPwrLimit->cPwrLimit160 > MAX_TX_POWER) ++ prCmdPwrLimit->cPwrLimit160 = MAX_TX_POWER; ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ } ++ } ++ ++#if 0 ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4] < MAX_TX_POWER) { ++ for (i = BAND_2G4_LOWER_BOUND; i <= BAND_2G4_UPPER_BOUND; i++) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4], ++ PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1] < MAX_TX_POWER) { ++ if (prCmd->u2CountryCode != COUNTRY_CODE_KR) { ++ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } else { ++ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { ++ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 ++ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ ++ prCmdPwrLimit->ucCentralCh = i; ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 6; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 12; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 18; ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ } ++ ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A] < MAX_TX_POWER) { ++ for (i = UNII2A_LOWER_BOUND; i <= UNII2A_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C] < MAX_TX_POWER) { ++ for (i = UNII2C_LOWER_BOUND; i <= UNII2C_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3] < MAX_TX_POWER) { ++ for (i = UNII3_LOWER_BOUND; i <= UNII3_UPPER_BOUND; i += 2) { ++ prCmdPwrLimit->ucCentralCh = i; ++ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, ++ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3], PWR_LIMIT_NUM); ++ prCmdPwrLimit++; ++ prCmd->ucNum++; ++ } ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainBuildCmdByConfigTable(P_ADAPTER_T prAdapter, P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd) ++{ ++ UINT_8 i, k; ++ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; ++ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; ++ BOOLEAN fgChannelValid; ++ ++ /*Build power limit cmd by configuration table information */ ++ ++ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); ++ ++ fgChannelValid = ++ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); ++ ++ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { ++ DBGLOG(RLM, TRACE, "Domain: full search configuration table done.\n"); ++ break; /*end of configuration table */ ++ } else if ((u2CountryCodeTable == prCmd->u2CountryCode) && (fgChannelValid == TRUE)) { ++ ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ ++ if (prCmd->ucNum != 0) { ++ for (k = 0; k < prCmd->ucNum; k++) { ++ if (prCmdPwrLimit->ucCentralCh == ++ g_rRlmPowerLimitConfiguration[i].ucCentralCh) { ++ ++ /*Cmd setting (Default table information) and ++ Configuration table has repetition channel entry, ++ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, ++ Configuration table (ex: ch1, limit = 22dBm) --> ch 1 = 22 dBm ++ Cmd final setting --> ch1 = 22dBm, ch12~14 = 20dBm ++ */ ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; ++ ++ DBGLOG(RLM, LOUD, ++ "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ ((prCmd->u2CountryCode & 0xff00) >> 8), ++ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, ++ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, ++ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, ++ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); ++ ++ break; ++ } ++ prCmdPwrLimit++; ++ } ++ if (k == prCmd->ucNum) { ++ ++ /*Full search cmd (Default table setting) no match channey, ++ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, ++ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm ++ Cmd final setting --> ch1~14 = 20dBm, ch36= 22dBm ++ */ ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; ++ prCmd->ucNum++; ++ ++ DBGLOG(RLM, LOUD, ++ "Domain: Full CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ ((prCmd->u2CountryCode & 0xff00) >> 8), (prCmd->u2CountryCode & 0x00ff), ++ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, ++ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, ++ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, ++ prCmdPwrLimit->ucFlag); ++ ++ } ++ } else { ++ ++ /*Default table power limit value are 63--> cmd table no channel entry ++ ex : Default table (ex: 2.4G, limit = 63Bm) --> no channel entry in cmd, ++ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm ++ Cmd final setting --> ch36= 22dBm ++ */ ++ prCmdPwrLimit->ucCentralCh = g_rRlmPowerLimitConfiguration[i].ucCentralCh; ++ prCmdPwrLimit->cPwrLimitCCK = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; ++ prCmdPwrLimit->cPwrLimit20 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; ++ prCmdPwrLimit->cPwrLimit40 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; ++ prCmdPwrLimit->cPwrLimit80 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; ++ prCmdPwrLimit->cPwrLimit160 = ++ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; ++ prCmd->ucNum++; ++ ++ DBGLOG(RLM, LOUD, "Domain: Default table power limit value are 63.\n"); ++ DBGLOG(RLM, LOUD, "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ ((prCmd->u2CountryCode & 0xff00) >> 8), ++ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, ++ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, ++ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, ++ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); ++ ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param[in] ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter) ++{ ++ P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd; ++ UINT_8 i; ++ UINT_16 u2DefaultTableIndex; ++ UINT_32 u4SetCmdTableMaxSize; ++ UINT_32 u4SetQueryInfoLen; ++ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; /* for print usage */ ++ ++ u4SetCmdTableMaxSize = ++ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + ++ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); ++ ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); ++ return; ++ } ++ kalMemZero(prCmd, u4SetCmdTableMaxSize); ++ ++ u2DefaultTableIndex = ++ rlmDomainPwrLimitDefaultTableDecision(prAdapter, prAdapter->rWifiVar.rConnSettings.u2CountryCode); ++ ++ if (u2DefaultTableIndex != POWER_LIMIT_TABLE_NULL) { ++ ++ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[u2DefaultTableIndex].aucCountryCode[0], ++ &prCmd->u2CountryCode); ++ ++ prCmd->ucNum = 0; ++ ++ if (prCmd->u2CountryCode != COUNTRY_CODE_NULL) { ++ /*Command - default table information */ ++ rlmDomainBuildCmdByDefaultTable(prCmd, u2DefaultTableIndex); ++ ++ /*Command - configuration table information */ ++ rlmDomainBuildCmdByConfigTable(prAdapter, prCmd); ++ } ++ } ++#if 0 ++ u4SetCmdTableMaxSize = ++ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + ++ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); ++ ++ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); ++ ASSERT(prCmd); ++ ++ /* To do: exception handle */ ++ if (!prCmd) { ++ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); ++ return; ++ } ++ kalMemZero(prCmd, u4SetCmdTableMaxSize); /* TODO memzero */ ++ ++ if (u2TableIndex != POWER_LIMIT_TABLE_NULL && u2TableIndex < MAX_DEFAULT_TABLE_COUNTRY_NUM) { ++ ++ prCmd->u2CountryCode = (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[0]) << 8) | ++ (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[1]) & BITS(0, 7)); ++ prChPwrLimit = &g_rRlmCountryPowerLimitTable[u2TableIndex].rChannelPowerLimit[0]; ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ prCmd->ucNum = 0; ++ for (i = 0; i < MAX_CMD_SUPPORT_CHANNEL_NUM; i++) { ++ ++ if (prChPwrLimit->ucCentralCh != ENDCH) { ++ ++ /*Check Power limit table channel efficient or not */ ++ fgChannelValid = rlmDomainCheckChannelEntryValid(prAdapter, prChPwrLimit->ucCentralCh); ++ ++ /*Cmd set up */ ++ if (fgChannelValid) { ++ kalMemCopy(prCmdPwrLimit, prChPwrLimit, sizeof(CMD_CHANNEL_POWER_LIMIT)); ++ DBGLOG(RLM, INFO, ++ "Domain: ValidCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, ++ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, ++ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, ++ prCmdPwrLimit->ucFlag); ++ prCmd->ucNum++; ++ prCmdPwrLimit++; ++ } else { ++ DBGLOG(RLM, INFO, ++ "Domain: Non-Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", ++ prChPwrLimit->ucCentralCh, prChPwrLimit->cPwrLimitCCK, ++ prChPwrLimit->cPwrLimit20, prChPwrLimit->cPwrLimit40, ++ prChPwrLimit->cPwrLimit80, prChPwrLimit->cPwrLimit160, ++ prChPwrLimit->ucFlag); ++ } ++ prChPwrLimit++; ++ } else { ++ /*End of the chanel entry */ ++ break; ++ } ++ }; ++ } ++#endif ++ ++ if (prCmd->u2CountryCode != 0) { ++ DBGLOG(RLM, INFO, ++ "Domain: ValidCC =%c%c, ChNum=%d\n", ((prCmd->u2CountryCode & 0xff00) >> 8), ++ (prCmd->u2CountryCode & 0x00ff), prCmd->ucNum); ++ } else { ++ DBGLOG(RLM, INFO, "Domain: ValidCC =0x%04x, ucNum=%d\n", prCmd->u2CountryCode, prCmd->ucNum); ++ } ++ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; ++ ++ for (i = 0; i < prCmd->ucNum; i++) { ++ DBGLOG(RLM, TRACE, "Domain: Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", prCmdPwrLimit->ucCentralCh, ++ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, ++ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); ++ prCmdPwrLimit++; ++ } ++ ++ u4SetQueryInfoLen = ++ (sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + (prCmd->ucNum) * sizeof(CMD_CHANNEL_POWER_LIMIT)); ++ ++ /* Update domain info to chip */ ++ if (prCmd->ucNum <= MAX_CMD_SUPPORT_CHANNEL_NUM) { ++ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ u4SetQueryInfoLen, /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmd, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ } else ++ DBGLOG(RLM, ERROR, "Domain: illegal power limit table"); ++ ++ cnmMemFree(prAdapter, prCmd); ++ ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c +new file mode 100644 +index 000000000000..8450124a3f38 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c +@@ -0,0 +1,436 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2 ++*/ ++ ++/*! \file "rlm_obss.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm_obss.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Avoid possible OBSS scan when BSS is switched ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * Regulation class is changed to 81 in 20_40_coexistence action frame ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 29 2011 cm.chang ++ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning ++ * As CR title ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame ++ * in AP mode and stop ampdu timer when sta_rec is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Refine function when rcv a 20/40M public action frame ++ * ++ * 01 13 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * Use SCO of BSS_INFO to replace user-defined setting variables ++ * ++ * 01 12 2011 cm.chang ++ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting ++ * User-defined bandwidth is for 2.4G and 5G individually ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * use definition macro to replace hard-coded constant ++ * ++ * 09 16 2010 cm.chang ++ * NULL ++ * Change conditional compiling options for BOW ++ * ++ * 09 10 2010 cm.chang ++ * NULL ++ * Always update Beacon content if FW sync OBSS info ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Fix compile error while enabling WiFi Direct function. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 05 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Process 20/40 coexistence public action frame in AP mode ++ * ++ * 05 05 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft support for 20/40M bandwidth for AP mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add more ASSERT to check exception ++ * ++ * 04 07 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add virtual test for OBSS scan ++ * ++ * 03 30 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support 2.4G OBSS scan ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * To support CFG_SUPPORT_BCM_STP ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 02 05 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssInit(P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 ucNetIdx; ++ ++ RLM_NET_FOR_EACH(ucNetIdx) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; ++ ASSERT(prBssInfo); ++ ++ cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, rlmObssScanTimeout, (ULONG) prBssInfo); ++ } /* end of RLM_NET_FOR_EACH */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rlmObssUpdateChnlLists(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_20_40_COEXIST_FRAME prTxFrame; ++ UINT_16 i, u2PayloadLen; ++ ++ ASSERT(prMsgHdr); ++ ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; ++ ASSERT(prBssInfo); ++ ++ DBGLOG(RLM, INFO, "OBSS Scan Done (NetIdx=%d, Mode=%d)\n", ++ prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* AP mode */ ++ if ((prAdapter->fgIsP2PRegistered) && ++ (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && ++ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { ++ return; ++ } ++#endif ++ ++ /* STA mode */ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || ++ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { ++ DBGLOG(RLM, WARN, "OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); ++ return; ++ } ++ ++ /* To do: check 2.4G channel list to decide if obss mgmt should be ++ * sent to associated AP. Note: how to handle concurrent network? ++ * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence ++ * management frame is needed. ++ */ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && prMsduInfo != NULL) { ++ DBGLOG(RLM, INFO, "Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", ++ prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0]); ++ ++ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; ++ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; ++ ++ /* To do: find correct algorithm */ ++ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; ++ prTxFrame->rBssCoexist.ucLength = 1; ++ prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; ++ ++ u2PayloadLen = 2 + 3; ++ ++ if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { ++ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); ++ ++ prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; ++ prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; ++ prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ ++ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) ++ prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i + 1]; ++ ++ u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); ++ } ++ ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); ++ ++ /* Clear up channel lists in 2.4G band */ ++ prBssInfo->auc2G_20mReqChnlList[0] = 0; ++ prBssInfo->auc2G_NonHtChnlList[0] = 0; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ } ++ /* end of prMsduInfo != NULL */ ++ if (prBssInfo->u2ObssScanInterval > 0) { ++ DBGLOG(RLM, INFO, "Set OBSS timer (NetIdx=%d, %d sec)\n", ++ prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval); ++ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ prBssInfo = (P_BSS_INFO_T) ulData; ++ ASSERT(prBssInfo); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex))) { ++ ++ /* AP mode */ ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ ++ prBssInfo->fgObssActionForcedTo20M = FALSE; ++ ++ /* Check if Beacon content need to be updated */ ++ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); ++ ++ return; ++ } ++#if CFG_SUPPORT_WFD ++ /* WFD streaming */ ++ else { ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = ++ &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ P_BSS_INFO_T prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; ++ ++ /* If WFD is enabled & connected */ ++ if (prWfdCfgSettings->ucWfdEnable && ++ (prWfdCfgSettings->u4WfdFlag & BIT(0)) && RLM_NET_PARAM_VALID(prP2pBssInfo)) { ++ ++ /* Skip OBSS scan */ ++ prBssInfo->u2ObssScanInterval = 0; ++ ++ DBGLOG(RLM, INFO, "WFD is running. Stop net[%u] OBSS scan.\n", ++ (UINT_32) prBssInfo->ucNetTypeIndex); ++ ++ return; ++ } ++ } ++#endif ++ } ++#endif /* end of CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* STA mode */ ++ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || ++ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { ++ DBGLOG(RLM, WARN, "OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); ++ return; ++ } ++ ++ rlmObssTriggerScan(prAdapter, prBssInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ P_MSG_SCN_SCAN_REQ prScanReqMsg; ++ ++ ASSERT(prBssInfo); ++ ++ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) ++ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); ++ ASSERT(prScanReqMsg); ++ ++ if (!prScanReqMsg) { ++ DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); ++ ++ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); ++ return; ++ } ++ ++ /* It is ok that ucSeqNum is set to fixed value because the same network ++ * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) ++ * and scan module don't care seqNum of OBSS scanning ++ */ ++ prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ; ++ prScanReqMsg->ucSeqNum = 0x33; ++ prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; ++ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; ++ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; ++ prScanReqMsg->ucSSIDLength = 0; ++ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; ++ prScanReqMsg->u2IELen = 0; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); ++ ++ DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c +new file mode 100644 +index 000000000000..d3c513397095 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c +@@ -0,0 +1,105 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_protection.c#1 ++*/ ++ ++/*! \file "rlm_protection.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: rlm_protection.c ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Check draft RLM code for HT cap ++ * ++ * 05 28 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Set RTS threshold of 2K bytes initially ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * First draft code to support protection in AP mode ++ * ++ * 03 31 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Enable RTS threshold temporarily for AMPDU ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 03 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * To support CFG_SUPPORT_BCM_STP ++ * ++ * 02 13 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support PCO in STA mode ++ * ++ * 02 12 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Use bss info array for concurrent handle ++ * ++ * 01 25 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c +new file mode 100644 +index 000000000000..3f088c283993 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c +@@ -0,0 +1,539 @@ ++/* ++** Id: ++*/ ++ ++/*! \file "roaming_fsm.c" ++ \brief This file defines the FSM for Roaming MODULE. ++ ++ This file defines the FSM for Roaming MODULE. ++*/ ++ ++/* ++** Log: roaming_fsm.c ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 08 31 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * remove obsolete code. ++ * ++ * 08 15 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * add swcr in driver reg, 0x9fxx0000, to disable roaming . ++ * ++ * 03 16 2011 tsaiyuan.hsu ++ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming ++ * remove obsolete definition and unused variables. ++ * ++ * 02 26 2011 tsaiyuan.hsu ++ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support ++ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_ROAMING ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugRoamingState[ROAMING_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("ROAMING_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("ROAMING_STATE_DECISION"), ++ (PUINT_8) DISP_STRING("ROAMING_STATE_DISCOVERY"), ++ (PUINT_8) DISP_STRING("ROAMING_STATE_ROAM") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* ++#define ROAMING_ENABLE_CHECK(_roam) \ ++{ \ ++ if (!(_roam->fgIsEnableRoaming)) \ ++ return; \ ++} ++*/ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmInit(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmInit(): Current Time = %u\n", kalGetTimeTick()); ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ /* 4 <1> Initiate FSM */ ++ prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming; ++ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; ++ prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0; ++ ++} /* end of roamingFsmInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmUninit(): Current Time = %u\n", kalGetTimeTick()); ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; ++ ++} /* end of roamingFsmUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Send commands to firmware ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* [IN P_ROAMING_PARAM_T] prParam ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ WLAN_STATUS rStatus; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmSendCmd(): Current Time = %u\n", kalGetTimeTick()); ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_ROAMING_TRANSIT, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(ROAMING_PARAM_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prParam, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++} /* end of roamingFsmSendCmd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Update the recent time when ScanDone occurred ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, LOUD, "->roamingFsmScanResultsUpdate(): Current Time = %u", kalGetTimeTick()); ++ ++ GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime); ++ ++} /* end of roamingFsmScanResultsUpdate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The Core FSM engine of ROAMING for AIS Infra. ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T ePreviousState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ do { ++ ++ /* Do entering Next State */ ++#if DBG ++ DBGLOG(ROAMING, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugRoamingState[prRoamingFsmInfo->eCurrentState], ++ apucDebugRoamingState[eNextState]); ++#else ++ DBGLOG(ROAMING, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_ROAMING_IDX, prRoamingFsmInfo->eCurrentState, eNextState); ++#endif ++ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ ++ ePreviousState = prRoamingFsmInfo->eCurrentState; ++ prRoamingFsmInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ ++ /* Do tasks of the State that we just entered */ ++ switch (prRoamingFsmInfo->eCurrentState) { ++ /* NOTE(Kevin): we don't have to rearrange the sequence of following ++ * switch case. Instead I would like to use a common lookup table of array ++ * of function pointer to speed up state search. ++ */ ++ case ROAMING_STATE_IDLE: ++ case ROAMING_STATE_DECISION: ++ break; ++ ++ case ROAMING_STATE_DISCOVERY: ++ { ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prRoamingFsmInfo->rRoamingDiscoveryUpdateTime, ++ SEC_TO_SYSTIME(ROAMING_DISCOVERY_TIMEOUT_SEC))) { ++ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Timeout"); ++ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); ++ } else { ++ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Updated"); ++#if CFG_SUPPORT_ROAMING_ENC ++ if (prAdapter->fgIsRoamingEncEnabled == TRUE) ++ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); ++ else ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ aisFsmRunEventRoamingDiscovery(prAdapter, FALSE); ++ } ++ } ++ break; ++ ++ case ROAMING_STATE_ROAM: ++ break; ++ ++ default: ++ ASSERT(0); /* Make sure we have handle all STATEs */ ++ } ++ } while (fgIsTransition); ++ ++ return; ++ ++} /* end of roamingFsmSteps() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Decision state after join completion ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ P_BSS_INFO_T prAisBssInfo; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING START: Current Time = %u\n", kalGetTimeTick()); ++ ++ /* IDLE, ROAM -> DECISION */ ++ /* Errors as DECISION, DISCOVERY -> DECISION */ ++ if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE || ++ prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) ++ return; ++ ++ eNextState = ROAMING_STATE_DECISION; ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_START; ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventStart() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Discovery state when deciding to find a candidate ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING DISCOVERY: Current Time = %u Reason = %u\n", ++ kalGetTimeTick(), prParam->u2Reason); ++ ++ /* DECISION -> DISCOVERY */ ++ /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */ ++ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) ++ return; ++#if CFG_SUPPORT_ROAMING_ENC ++ prRoamingFsmInfo->RoamingEntryTimeoutSkipCount = 0; ++#endif ++ ++ eNextState = ROAMING_STATE_DISCOVERY; ++ /* DECISION -> DISCOVERY */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ P_BSS_INFO_T prAisBssInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ /* sync. rcpi with firmware */ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); ++ if (prBssDesc) ++ prBssDesc->ucRCPI = (UINT_8) (prParam->u2Data & 0xff); ++ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventDiscovery() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Roam state after Scan Done ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ROAM: Current Time = %u\n", kalGetTimeTick()); ++ ++ /* IDLE, ROAM -> DECISION */ ++ /* Errors as IDLE, DECISION, ROAM -> ROAM */ ++ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY) ++ return; ++ ++ eNextState = ROAMING_STATE_ROAM; ++ /* DISCOVERY -> ROAM */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_ROAM; ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventRoam() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Decision state as being failed to find out any candidate ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ /* Check Roaming Conditions */ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING FAIL: reason %x Current Time = %u\n", u4Param, kalGetTimeTick()); ++ ++ /* IDLE, ROAM -> DECISION */ ++ /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */ ++ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) ++ return; ++ ++ eNextState = ROAMING_STATE_DECISION; ++ /* ROAM -> DECISION */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_FAIL; ++ rParam.u2Data = (UINT_16) (u4Param & 0xffff); ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventFail() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Transit to Idle state as beging aborted by other moduels, AIS ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter) ++{ ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ENUM_ROAMING_STATE_T eNextState; ++ ROAMING_PARAM_T rParam; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ ++ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) ++ return; ++ ++ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ABORT: Current Time = %u\n", kalGetTimeTick()); ++ ++ eNextState = ROAMING_STATE_IDLE; ++ /* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */ ++ if (eNextState != prRoamingFsmInfo->eCurrentState) { ++ rParam.u2Event = ROAMING_EVENT_ABORT; ++ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); ++ ++ /* Step to next state */ ++ roamingFsmSteps(prAdapter, eNextState); ++ } ++ ++} /* end of roamingFsmRunEventAbort() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process events from firmware ++* ++* @param [IN P_ADAPTER_T] prAdapter ++* [IN P_ROAMING_PARAM_T] prParam ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) ++{ ++ DBGLOG(ROAMING, LOUD, "ROAMING Process Events: Current Time = %u\n", kalGetTimeTick()); ++ ++ if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) ++ roamingFsmRunEventDiscovery(prAdapter, prParam); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c +new file mode 100644 +index 000000000000..eedd8d12f2fd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c +@@ -0,0 +1,2533 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#2 ++*/ ++ ++/*! \file "rsn.c" ++ \brief This file including the 802.11i, wpa and wpa2(rsn) related function. ++ ++ This file provided the macros and functions library support the wpa/rsn ie parsing, ++ cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support. ++*/ ++ ++/* ++** Log: rsn.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 09 2012 chinglan.wang ++ * NULL ++ * Fix the condition error. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode ++ * adding the code for check STA privacy bit at AP mode, . ++ * ++ * 12 24 2010 chinglan.wang ++ * NULL ++ * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function. ++ * ++ * 12 13 2010 cp.wu ++ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver ++ * create branch for Wi-Fi driver v1.1 ++ * ++ * 11 05 2010 wh.su ++ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value ++ * fixed the.pmkid value mismatch issue ++ * ++ * 11 03 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Refine the HT rate disallow TKIP pairwise cipher . ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T ++ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 29 2010 yuche.tsai ++ * NULL ++ * Fix compile error, remove unused pointer in rsnGenerateRSNIE(). ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 08 30 2010 wh.su ++ * NULL ++ * remove non-used code. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * enable RX management frame handling. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * [WPD00003840] [MT6620 5931] Security migration ++ * migration from firmware. ++ * ++ * 05 27 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * not indicate pmkid candidate while no new one scanned. ++ * ++ * 04 29 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * adjsut the pre-authentication code. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * change the name ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * using the Rx0 port to indicate event ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * refine the code for generate the WPA/RSN IE for assoc req ++ * ++ * Dec 3 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust code for pmkid event ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the code for event (mic error and pmkid indicate) and do some function rename ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some security function ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding some security feature, including pmkid ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_RSN_MIGRATION ++ ++/* extern PHY_ATTRIBUTE_T rPhyAttributes[]; */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to parse RSN IE. ++* ++* \param[in] prInfoElem Pointer to the RSN IE ++* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the ++** RSN information from the given RSN IE ++* ++* \retval TRUE - Succeeded ++* \retval FALSE - Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo) ++{ ++ UINT_32 i; ++ INT_32 u4RemainRsnIeLen; ++ UINT_16 u2Version; ++ UINT_16 u2Cap = 0; ++ UINT_32 u4GroupSuite = RSN_CIPHER_SUITE_CCMP; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_16 u2AuthSuiteCount = 0; ++ PUINT_8 pucPairSuite = NULL; ++ PUINT_8 pucAuthSuite = NULL; ++ PUINT_8 cp; ++ ++ DEBUGFUNC("rsnParseRsnIE"); ++ ++ ASSERT(prInfoElem); ++ ASSERT(prRsnInfo); ++ ++ /* Verify the length of the RSN IE. */ ++ if (prInfoElem->ucLength < 2) { ++ DBGLOG(RSN, TRACE, "RSN IE length too short (length=%d)\n", prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ /* Check RSN version: currently, we only support version 1. */ ++ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); ++ if (u2Version != 1) { ++ DBGLOG(RSN, TRACE, "Unsupported RSN IE version: %d\n", u2Version); ++ return FALSE; ++ } ++ ++ cp = (PUCHAR) & prInfoElem->u4GroupKeyCipherSuite; ++ u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2; ++ ++ do { ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the Group Key Cipher Suite field. */ ++ if (u4RemainRsnIeLen < 4) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in group cipher suite (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ cp += 4; ++ u4RemainRsnIeLen -= 4; ++ ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the Pairwise Key Cipher Suite Count field. */ ++ if (u4RemainRsnIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ cp += 2; ++ u4RemainRsnIeLen -= 2; ++ ++ /* Parse the Pairwise Key Cipher Suite List field. */ ++ i = (UINT_32) u2PairSuiteCount * 4; ++ if (u4RemainRsnIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucPairSuite = cp; ++ ++ cp += i; ++ u4RemainRsnIeLen -= (INT_32) i; ++ ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the Authentication and Key Management Cipher Suite Count field. */ ++ if (u4RemainRsnIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ cp += 2; ++ u4RemainRsnIeLen -= 2; ++ ++ /* Parse the Authentication and Key Management Cipher Suite List ++ field. */ ++ i = (UINT_32) u2AuthSuiteCount * 4; ++ if (u4RemainRsnIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucAuthSuite = cp; ++ ++ cp += i; ++ u4RemainRsnIeLen -= (INT_32) i; ++ ++ if (u4RemainRsnIeLen == 0) ++ break; ++ ++ /* Parse the RSN u2Capabilities field. */ ++ if (u4RemainRsnIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2Cap); ++ } while (FALSE); ++ ++ /* Save the RSN information for the BSS. */ ++ prRsnInfo->ucElemId = ELEM_ID_RSN; ++ ++ prRsnInfo->u2Version = u2Version; ++ ++ prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite; ++ ++ DBGLOG(RSN, LOUD, "RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", ++ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (pucPairSuite) { ++ /* The information about the pairwise key cipher suites is present. */ ++ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) ++ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; ++ ++ prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucPairSuite, &prRsnInfo->au4PairwiseKeyCipherSuite[i]); ++ pucPairSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the pairwise key cipher suites is not present. ++ Use the default chipher suite for RSN: CCMP. */ ++ prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1; ++ prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP; ++ ++ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (pucAuthSuite) { ++ /* The information about the authentication and key management suites ++ is present. */ ++ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) ++ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; ++ ++ prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]); ++ pucAuthSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the authentication and key management suites ++ is not present. Use the default AKM suite for RSN. */ ++ prRsnInfo->u4AuthKeyMgtSuiteCount = 1; ++ prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X; ++ ++ DBGLOG(RSN, LOUD, "RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ prRsnInfo->u2RsnCap = u2Cap; ++#if CFG_SUPPORT_802_11W ++ prRsnInfo->fgRsnCapPresent = TRUE; ++#endif ++ DBGLOG(RSN, LOUD, "RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap); ++ ++ return TRUE; ++} /* rsnParseRsnIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to parse WPA IE. ++* ++* \param[in] prInfoElem Pointer to the WPA IE. ++* \param[out] prWpaInfo Pointer to the BSSDescription structure to store the ++* WPA information from the given WPA IE. ++* ++* \retval TRUE Succeeded. ++* \retval FALSE Failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo) ++{ ++ UINT_32 i; ++ INT_32 u4RemainWpaIeLen; ++ UINT_16 u2Version; ++ UINT_16 u2Cap = 0; ++ UINT_32 u4GroupSuite = WPA_CIPHER_SUITE_TKIP; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_16 u2AuthSuiteCount = 0; ++ PUCHAR pucPairSuite = NULL; ++ PUCHAR pucAuthSuite = NULL; ++ PUCHAR cp; ++ BOOLEAN fgCapPresent = FALSE; ++ ++ DEBUGFUNC("rsnParseWpaIE"); ++ ++ ASSERT(prInfoElem); ++ ASSERT(prWpaInfo); ++ ++ /* Verify the length of the WPA IE. */ ++ if (prInfoElem->ucLength < 6) { ++ DBGLOG(RSN, TRACE, "WPA IE length too short (length=%d)\n", prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ /* Check WPA version: currently, we only support version 1. */ ++ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); ++ if (u2Version != 1) { ++ DBGLOG(RSN, TRACE, "Unsupported WPA IE version: %d\n", u2Version); ++ return FALSE; ++ } ++ ++ cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite; ++ u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6; ++ ++ do { ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* WPA_OUI : 4 ++ Version : 2 ++ GroupSuite : 4 ++ PairwiseCount: 2 ++ PairwiseSuite: 4 * pairSuiteCount ++ AuthCount : 2 ++ AuthSuite : 4 * authSuiteCount ++ Cap : 2 */ ++ ++ /* Parse the Group Key Cipher Suite field. */ ++ if (u4RemainWpaIeLen < 4) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in group cipher suite (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ cp += 4; ++ u4RemainWpaIeLen -= 4; ++ ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* Parse the Pairwise Key Cipher Suite Count field. */ ++ if (u4RemainWpaIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ cp += 2; ++ u4RemainWpaIeLen -= 2; ++ ++ /* Parse the Pairwise Key Cipher Suite List field. */ ++ i = (UINT_32) u2PairSuiteCount * 4; ++ if (u4RemainWpaIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucPairSuite = cp; ++ ++ cp += i; ++ u4RemainWpaIeLen -= (INT_32) i; ++ ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* Parse the Authentication and Key Management Cipher Suite Count ++ field. */ ++ if (u4RemainWpaIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ cp += 2; ++ u4RemainWpaIeLen -= 2; ++ ++ /* Parse the Authentication and Key Management Cipher Suite List ++ field. */ ++ i = (UINT_32) u2AuthSuiteCount * 4; ++ if (u4RemainWpaIeLen < (INT_32) i) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucAuthSuite = cp; ++ ++ cp += i; ++ u4RemainWpaIeLen -= (INT_32) i; ++ ++ if (u4RemainWpaIeLen == 0) ++ break; ++ ++ /* Parse the WPA u2Capabilities field. */ ++ if (u4RemainWpaIeLen < 2) { ++ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in WPA capabilities (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ fgCapPresent = TRUE; ++ WLAN_GET_FIELD_16(cp, &u2Cap); ++ u4RemainWpaIeLen -= 2; ++ } while (FALSE); ++ ++ /* Save the WPA information for the BSS. */ ++ ++ prWpaInfo->ucElemId = ELEM_ID_WPA; ++ ++ prWpaInfo->u2Version = u2Version; ++ ++ prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite; ++ ++ DBGLOG(RSN, LOUD, "WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", ++ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (pucPairSuite) { ++ /* The information about the pairwise key cipher suites is present. */ ++ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) ++ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; ++ ++ prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucPairSuite, &prWpaInfo->au4PairwiseKeyCipherSuite[i]); ++ pucPairSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the pairwise key cipher suites is not present. ++ Use the default chipher suite for WPA: TKIP. */ ++ prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1; ++ prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP; ++ ++ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (pucAuthSuite) { ++ /* The information about the authentication and key management suites ++ is present. */ ++ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) ++ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; ++ ++ prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]); ++ pucAuthSuite += 4; ++ ++ DBGLOG(RSN, LOUD, "WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the authentication and key management suites ++ is not present. Use the default AKM suite for WPA. */ ++ prWpaInfo->u4AuthKeyMgtSuiteCount = 1; ++ prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X; ++ ++ DBGLOG(RSN, LOUD, "WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (fgCapPresent) { ++ prWpaInfo->fgRsnCapPresent = TRUE; ++ prWpaInfo->u2RsnCap = u2Cap; ++ DBGLOG(RSN, LOUD, "WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap); ++ } else { ++ prWpaInfo->fgRsnCapPresent = FALSE; ++ prWpaInfo->u2RsnCap = 0; ++ } ++ ++ return TRUE; ++} /* rsnParseWpaIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to search the desired pairwise ++* cipher suite from the MIB Pairwise Cipher Suite ++* configuration table. ++* ++* \param[in] u4Cipher The desired pairwise cipher suite to be searched ++* \param[out] pu4Index Pointer to the index of the desired pairwise cipher in ++* the table ++* ++* \retval TRUE - The desired pairwise cipher suite is found in the table. ++* \retval FALSE - The desired pairwise cipher suite is not found in the ++* table. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index) ++{ ++ UINT_8 i; ++ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; ++ ++ DEBUGFUNC("rsnSearchSupportedCipher"); ++ ++ ASSERT(pu4Index); ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { ++ prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i]; ++ if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher && ++ prEntry->dot11RSNAConfigPairwiseCipherEnabled) { ++ *pu4Index = i; ++ return TRUE; ++ } ++ } ++ return FALSE; ++} /* rsnSearchSupportedCipher */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Whether BSS RSN is matched from upper layer set. ++* ++* \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information ++* ++* \retval BOOLEAN ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo) ++{ ++ UINT_8 i = 0; ++ ++ DEBUGFUNC("rsnIsSuitableBSS"); ++ ++ do { ++ ++ if ((prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite & 0x000000FF) != ++ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)) { ++ DBGLOG(RSN, TRACE, "Break by GroupKeyCipherSuite\n"); ++ break; ++ } ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] & 0x000000FF) != ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])) ++ && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1)) { ++ DBGLOG(RSN, TRACE, "Break by PairwiseKeyCipherSuite\n"); ++ break; ++ } ++ } ++ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { ++ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] & 0x000000FF) != ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0])) ++ && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)) { ++ DBGLOG(RSN, TRACE, "Break by AuthKeyMgtSuite\n"); ++ break; ++ } ++ } ++ return TRUE; ++ } while (FALSE); ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to search the desired ++* authentication and key management (AKM) suite from the ++* MIB Authentication and Key Management Suites table. ++* ++* \param[in] u4AkmSuite The desired AKM suite to be searched ++* \param[out] pu4Index Pointer to the index of the desired AKM suite in the ++* table ++* ++* \retval TRUE The desired AKM suite is found in the table. ++* \retval FALSE The desired AKM suite is not found in the table. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index) ++{ ++ UINT_8 i; ++ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; ++ ++ DEBUGFUNC("rsnSearchAKMSuite"); ++ ++ ASSERT(pu4Index); ++ ++ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { ++ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; ++ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite && ++ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) { ++ *pu4Index = i; ++ return TRUE; ++ } ++ } ++ return FALSE; ++} /* rsnSearchAKMSuite */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to perform RSNA or TSN policy ++* selection for a given BSS. ++* ++* \param[in] prBss Pointer to the BSS description ++* ++* \retval TRUE - The RSNA/TSN policy selection for the given BSS is ++* successful. The selected pairwise and group cipher suites ++* are returned in the BSS description. ++* \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed. ++* The driver shall not attempt to join the given BSS. ++* ++* \note The Encrypt status matched score will save to bss for final ap select. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) ++{ ++#if CFG_SUPPORT_802_11W ++ INT_32 i; ++ UINT_32 j; ++#else ++ UINT_32 i, j; ++#endif ++ BOOLEAN fgSuiteSupported; ++ UINT_32 u4PairwiseCipher = 0; ++ UINT_32 u4GroupCipher = 0; ++ UINT_32 u4AkmSuite = 0; ++ P_RSN_INFO_T prBssRsnInfo; ++ ENUM_NETWORK_TYPE_INDEX_T eNetwotkType; ++ BOOLEAN fgIsWpsActive = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("rsnPerformPolicySelection"); ++ ++ ASSERT(prBss); ++ ++ DBGLOG(RSN, TRACE, "rsnPerformPolicySelection\n"); ++ /* Todo:: */ ++ eNetwotkType = NETWORK_TYPE_AIS_INDEX; ++ ++ prBss->u4RsnSelectedPairwiseCipher = 0; ++ prBss->u4RsnSelectedGroupCipher = 0; ++ prBss->u4RsnSelectedAKMSuite = 0; ++ prBss->ucEncLevel = 0; ++ ++#if CFG_SUPPORT_WPS ++ fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo); ++ ++ /* CR1640, disable the AP select privacy check */ ++ if (fgIsWpsActive && ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) && ++ (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) { ++ DBGLOG(RSN, TRACE, "-- Skip the Protected BSS check\n"); ++ return TRUE; ++ } ++#endif ++ ++ /* Protection is not required in this BSS. */ ++ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) { ++ ++ if (secEnabledInAis(prAdapter) == FALSE) { ++ DBGLOG(RSN, TRACE, "-- No Protected BSS\n"); ++ return TRUE; ++ } ++ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); ++ return FALSE; ++ ++ } ++ ++ /* Protection is required in this BSS. */ ++ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) { ++ if (secEnabledInAis(prAdapter) == FALSE) { ++ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); ++ return FALSE; ++ } ++ } ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA || ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK || ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { ++ ++ if (prBss->fgIEWPA) { ++ prBssRsnInfo = &prBss->rWPAInfo; ++ } else { ++ DBGLOG(RSN, TRACE, "WPA Information Element does not exist.\n"); ++ return FALSE; ++ } ++ } else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 || ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) { ++ ++ if (prBss->fgIERSN) { ++ prBssRsnInfo = &prBss->rRSNInfo; ++ } else { ++ DBGLOG(RSN, TRACE, "RSN Information Element does not exist.\n"); ++ return FALSE; ++ } ++ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) { ++ /* If the driver is configured to use WEP only, ignore this BSS. */ ++ DBGLOG(RSN, TRACE, "-- Not WEP-only legacy BSS %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ return FALSE; ++ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) { ++ /* If the driver is configured to use WEP only, use this BSS. */ ++ DBGLOG(RSN, TRACE, "-- WEP-only legacy BSS, fgIERSN %d, fgIEWPA %d\n", ++ prBss->fgIERSN, prBss->fgIEWPA); ++ /* if this BSS was configured to WPA/WPA2, don't select this AP */ ++ return (prBss->fgIERSN || prBss->fgIEWPA) ? FALSE : TRUE; ++ } ++ ++ if (!rsnIsSuitableBSS(prAdapter, prBssRsnInfo)) { ++ DBGLOG(RSN, TRACE, "RSN info check no matched\n"); ++ return FALSE; ++ } ++ ++ if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 && ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == CIPHER_SUITE_NONE) { ++ /* Since the pairwise cipher use the same cipher suite as the group ++ cipher in the BSS, we check the group cipher suite against the ++ current encryption status. */ ++ fgSuiteSupported = FALSE; ++ ++ switch (prBssRsnInfo->u4GroupKeyCipherSuite) { ++ case WPA_CIPHER_SUITE_CCMP: ++ case RSN_CIPHER_SUITE_CCMP: ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) ++ fgSuiteSupported = TRUE; ++ break; ++ ++ case WPA_CIPHER_SUITE_TKIP: ++ case RSN_CIPHER_SUITE_TKIP: ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) ++ fgSuiteSupported = TRUE; ++ break; ++ ++ case WPA_CIPHER_SUITE_WEP40: ++ case WPA_CIPHER_SUITE_WEP104: ++ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) ++ fgSuiteSupported = TRUE; ++ break; ++ } ++ ++ if (fgSuiteSupported) { ++ u4PairwiseCipher = WPA_CIPHER_SUITE_NONE; ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ } ++#if DBG ++ else { ++ DBGLOG(RSN, TRACE, "Inproper encryption status %d for group-key-only BSS\n", ++ prAdapter->rWifiVar.rConnSettings.eEncStatus); ++ } ++#endif ++ } else { ++ fgSuiteSupported = FALSE; ++ ++ DBGLOG(RSN, TRACE, "eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, ++ (UINT_32) prBssRsnInfo->u4PairwiseKeyCipherSuiteCount, ++ (UINT_32) prBssRsnInfo->au4PairwiseKeyCipherSuite[0]); ++ /* Select pairwise/group ciphers */ ++ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { ++ case ENUM_ENCRYPTION3_ENABLED: ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_CCMP) { ++ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ break; ++ ++ case ENUM_ENCRYPTION2_ENABLED: ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_TKIP) { ++ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_CCMP) ++ DBGLOG(RSN, TRACE, "Cannot join CCMP BSS\n"); ++ else ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ break; ++ ++ case ENUM_ENCRYPTION1_ENABLED: ++ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_WEP40 || ++ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ == CIPHER_SUITE_WEP104) { ++ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == ++ CIPHER_SUITE_CCMP || ++ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) { ++ DBGLOG(RSN, TRACE, "Cannot join CCMP/TKIP BSS\n"); ++ } else { ++ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* Exception handler */ ++ /* If we cannot find proper pairwise and group cipher suites to join the ++ BSS, do not check the supported AKM suites. */ ++ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { ++ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((prAdapter->fgIsP2PRegistered) && (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) { ++ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || ++ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { ++ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher for P2P network (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) { ++ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || ++ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { ++ /* Do nothing */ ++ } ++ DBGLOG(RSN, TRACE, ++ "Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++#endif ++ ++ /* Verify if selected pairwisse cipher is supported */ ++ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i); ++ ++ /* Verify if selected group cipher is supported */ ++ if (fgSuiteSupported) ++ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i); ++ ++ if (!fgSuiteSupported) { ++ DBGLOG(RSN, TRACE, "Failed to support selected pairwise/group cipher (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++ ++ /* Select AKM */ ++ /* If the driver cannot support any authentication suites advertised in ++ the given BSS, we fail to perform RSNA policy selection. */ ++ /* Attempt to find any overlapping supported AKM suite. */ ++#if CFG_SUPPORT_802_11W ++ if (i != 0) ++ for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--) { ++#else ++ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { ++#endif ++ if (rsnSearchAKMSuite(prAdapter, prBssRsnInfo->au4AuthKeyMgtSuite[i], &j)) { ++ u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i]; ++ break; ++ } ++ } ++ ++ if (u4AkmSuite == 0) { ++ DBGLOG(RSN, TRACE, "Cannot support any AKM suites\n"); ++ return FALSE; ++ } ++ ++ DBGLOG(RSN, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4PairwiseCipher & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), ++ (UINT_8) (u4GroupCipher & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); ++ ++ DBGLOG(RSN, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4AkmSuite & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); ++ ++#if CFG_SUPPORT_802_11W ++ DBGLOG(RSN, TRACE, "MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)); ++ ++ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) { ++ if (!prBssRsnInfo->fgRsnCapPresent) { ++ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability.\n"); ++ return FALSE; ++ } else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) { ++ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required\n"); ++ return FALSE; ++ } ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ } else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) { ++ if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) || ++ (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; ++ } else { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; ++ } ++ } else { ++ if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) { ++ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability\n"); ++ return FALSE; ++ } ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; ++ } ++ DBGLOG(RSN, TRACE, "fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection); ++#endif ++ ++ if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) { ++ prBss->ucEncLevel = 3; ++ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) { ++ prBss->ucEncLevel = 2; ++ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 || ++ GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) { ++ prBss->ucEncLevel = 1; ++ } else { ++ ASSERT(FALSE); ++ } ++ prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher; ++ prBss->u4RsnSelectedGroupCipher = u4GroupCipher; ++ prBss->u4RsnSelectedAKMSuite = u4AkmSuite; ++ ++ return TRUE; ++ ++} /* rsnPerformPolicySelection */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to generate WPA IE for beacon frame. ++* ++* \param[in] pucIeStartAddr Pointer to put the generated WPA IE. ++* ++* \return The append WPA-None IE length ++* \note ++* Called by: JOIN module, compose beacon IE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_32 i; ++ P_WPA_INFO_ELEM_T prWpaIE; ++ UINT_32 u4Suite; ++ UINT_16 u2SuiteCount; ++ PUINT_8 cp, cp2; ++ UINT_8 ucExpendedLen = 0; ++ PUINT_8 pucBuffer; ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; ++ ++ DEBUGFUNC("rsnGenerateWpaNoneIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) ++ return; ++ ++ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; ++ ++ if (eNetworkId != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ prWpaIE = (P_WPA_INFO_ELEM_T) (pucBuffer); ++ ++ /* Start to construct a WPA IE. */ ++ /* Fill the Element ID field. */ ++ prWpaIE->ucElemId = ELEM_ID_WPA; ++ ++ /* Fill the OUI and OUI Type fields. */ ++ prWpaIE->aucOui[0] = 0x00; ++ prWpaIE->aucOui[1] = 0x50; ++ prWpaIE->aucOui[2] = 0xF2; ++ prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA; ++ ++ /* Fill the Version field. */ ++ WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1); /* version 1 */ ++ ucExpendedLen = 6; ++ ++ /* Fill the Pairwise Key Cipher Suite List field. */ ++ u2SuiteCount = 0; ++ cp = (PUINT_8) &prWpaIE->aucPairwiseKeyCipherSuite1[0]; ++ ++ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) ++ u4Suite = WPA_CIPHER_SUITE_CCMP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) ++ u4Suite = WPA_CIPHER_SUITE_TKIP; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) ++ u4Suite = WPA_CIPHER_SUITE_WEP104; ++ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) ++ u4Suite = WPA_CIPHER_SUITE_WEP40; ++ else ++ u4Suite = WPA_CIPHER_SUITE_TKIP; ++ ++ WLAN_SET_FIELD_32(cp, u4Suite); ++ u2SuiteCount++; ++ ucExpendedLen += 4; ++ cp += 4; ++ ++ /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */ ++ WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite); ++ ucExpendedLen += 4; ++ ++ /* Fill the Pairwise Key Cipher Suite Count field. */ ++ WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount); ++ ucExpendedLen += 2; ++ ++ cp2 = cp; ++ ++ /* Fill the Authentication and Key Management Suite List field. */ ++ u2SuiteCount = 0; ++ cp += 2; ++ ++ if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) ++ u4Suite = WPA_AKM_SUITE_802_1X; ++ else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) ++ u4Suite = WPA_AKM_SUITE_PSK; ++ else ++ u4Suite = WPA_AKM_SUITE_NONE; ++ ++ /* This shall be the only available value for current implementation */ ++ ASSERT(u4Suite == WPA_AKM_SUITE_NONE); ++ ++ WLAN_SET_FIELD_32(cp, u4Suite); ++ u2SuiteCount++; ++ ucExpendedLen += 4; ++ cp += 4; ++ ++ /* Fill the Authentication and Key Management Suite Count field. */ ++ WLAN_SET_FIELD_16(cp2, u2SuiteCount); ++ ucExpendedLen += 2; ++ ++ /* Fill the Length field. */ ++ prWpaIE->ucLength = (UINT_8) ucExpendedLen; ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ ++} /* rsnGenerateWpaNoneIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate WPA IE for ++* associate request frame. ++* ++* \param[in] prCurrentBss The Selected BSS description ++* ++* \retval The append WPA IE length ++* ++* \note ++* Called by: AIS module, Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUCHAR cp; ++ PUINT_8 pucBuffer; ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; ++ ++ DEBUGFUNC("rsnGenerateWPAIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ /* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */ ++ /* return; */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if ((1 /* prCurrentBss->fgIEWPA */ && ++ ((prAdapter->fgIsP2PRegistered) && ++ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && ++ (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || ++ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) { ++#else ++ if ((1 /* prCurrentBss->fgIEWPA */ && ++ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) { ++#endif ++ if (prP2pSpecificBssInfo->u2WpaIeLen != 0) { ++ kalMemCopy(pucBuffer, prP2pSpecificBssInfo->aucWpaIeBuffer, prP2pSpecificBssInfo->u2WpaIeLen); ++ prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen; ++ return; ++ } ++ ++ /* Construct a WPA IE for association request frame. */ ++ WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA; ++ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; ++ WPA_IE(pucBuffer)->aucOui[0] = 0x00; ++ WPA_IE(pucBuffer)->aucOui[1] = 0x50; ++ WPA_IE(pucBuffer)->aucOui[2] = 0xF2; ++ WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA; ++ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { ++ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP); ++ } else ++#endif ++ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, ++ prAdapter->rWifiVar. ++ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher); ++ ++ cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; ++ ++ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { ++ WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP); ++ } else ++#endif ++ WLAN_SET_FIELD_32(cp, ++ prAdapter->rWifiVar. ++ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher); ++ cp += 4; ++ ++ WLAN_SET_FIELD_16(cp, 1); ++ cp += 2; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { ++ WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK); ++ } else ++#endif ++ WLAN_SET_FIELD_32(cp, ++ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite); ++ cp += 4; ++ ++ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; ++ ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* rsnGenerateWPAIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate RSN IE for ++* associate request frame. ++* ++* \param[in] prMsduInfo The Selected BSS description ++* ++* \retval The append RSN IE length ++* ++* \note ++* Called by: AIS module, P2P module, BOW module Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_32 u4Entry; ++ PUCHAR cp; ++ /* UINT_8 ucExpendedLen = 0; */ ++ PUINT_8 pucBuffer; ++ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("rsnGenerateRSNIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ ASSERT(pucBuffer); ++ ++ /* Todo:: network id */ ++ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; ++ ++ if ( ++#if CFG_ENABLE_WIFI_DIRECT ++ ((prAdapter->fgIsP2PRegistered) && ++ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) || ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ (eNetworkId == NETWORK_TYPE_BOW_INDEX) || ++#endif ++ (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ && ++ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) || ++ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK)))) { ++ /* Construct a RSN IE for association request frame. */ ++ RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN; ++ RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED; ++ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); /* Version */ ++ WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite, ++ prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); /* Group key suite */ ++ cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; ++ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); ++ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher); ++ cp += 4; ++ WLAN_SET_FIELD_16(cp, 1); /* AKM suite count */ ++ cp += 2; ++ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); /* AKM suite */ ++ cp += 4; ++ WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo);/* Capabilities */ ++#if CFG_SUPPORT_802_11W ++ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) { ++ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) ++ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); /* Capabilities */ ++ else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) ++ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); /* Capabilities */ ++ } ++#endif ++ cp += 2; ++ ++ if (eNetworkId == NETWORK_TYPE_AIS_INDEX) { ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ if (!prStaRec) { ++ DBGLOG(RSN, TRACE, "rsnGenerateRSNIE: prStaRec is NULL\n"); ++ return; ++ } ++ } ++ ++ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && ++ rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) { ++ /* DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); */ ++ /* DBGLOG(RSN, TRACE, ("addr %pM PMKID %pM\n", */ ++ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID),*/ ++ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID))); */ ++ if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) { ++ RSN_IE(pucBuffer)->ucLength = 38; ++ WLAN_SET_FIELD_16(cp, 1); /* PMKID count */ ++ cp += 2; ++ DBGLOG(RSN, TRACE, ++ "BSSID %pM ind=%d\n", prStaRec->aucMacAddr, (UINT_32) u4Entry); ++ DBGLOG(RSN, TRACE, "use PMKID %pM\n", ++ (prAdapter->rWifiVar.rAisSpecificBssInfo. ++ arPmkidCache[u4Entry].rBssidInfo.arPMKID)); ++ kalMemCopy(cp, ++ (PVOID) prAdapter->rWifiVar.rAisSpecificBssInfo. ++ arPmkidCache[u4Entry].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); ++ /* ucExpendedLen = 40; */ ++ } else { ++ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ ++ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ ++#if CFG_SUPPORT_802_11W ++ cp += 2; ++ RSN_IE(pucBuffer)->ucLength += 2; ++#endif ++ } ++ } else { ++ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ ++ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ ++#if CFG_SUPPORT_802_11W ++ cp += 2; ++ RSN_IE(pucBuffer)->ucLength += 2; ++#endif ++ } ++ ++#if CFG_SUPPORT_802_11W ++ if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) ++ && (kalGetMfpSetting(prAdapter->prGlueInfo) != ++ RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */) { ++ WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC); ++ cp += 4; ++ RSN_IE(pucBuffer)->ucLength += 4; ++ } ++#endif ++ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); ++ } ++ ++} /* rsnGenerateRSNIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Parse the given IE buffer and check if it is WFA IE and return Type and ++* SubType for further process. ++* ++* \param[in] pucBuf Pointer to the buffer of WFA Information Element. ++* \param[out] pucOuiType Pointer to the storage of OUI Type. ++* \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version. ++ ++* \retval TRUE Parse IE ok ++* \retval FALSE Parse IE fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, ++ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion) ++{ ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ P_IE_WFA_T prWfaIE; ++ ++ ASSERT(pucBuf); ++ ASSERT(pucOuiType); ++ ASSERT(pu2SubTypeVersion); ++ prWfaIE = (P_IE_WFA_T) pucBuf; ++ ++ do { ++ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { ++ break; ++ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || ++ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { ++ break; ++ } ++ ++ *pucOuiType = prWfaIE->ucOuiType; ++ WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion); ++ ++ return TRUE; ++ } while (FALSE); ++ ++ return FALSE; ++ ++} /* end of rsnParseCheckForWFAInfoElem() */ ++ ++#if CFG_SUPPORT_AAA ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK ++* ++* \param[in] prAdapter Pointer to Adapter ++* \param[in] prSwRfb Pointer to the rx buffer ++* \param[in] pIE Pointer rthe buffer of Information Element. ++* \param[out] prStatusCode Pointer to the return status code. ++ ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode) ++{ ++ ++ RSN_INFO_T rRsnIe; ++ ++ ASSERT(prAdapter); ++ ASSERT(prIe); ++ ASSERT(pu2StatusCode); ++ ++ *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; ++ ++ if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) { ++ if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) ++ || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) { ++ *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER; ++ return; ++ } ++ if (rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP) { ++ *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER; ++ return; ++ } ++ if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) { ++ *pu2StatusCode = STATUS_CODE_INVALID_AKMP; ++ return; ++ } ++ ++ DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n"); ++ *pu2StatusCode = WLAN_STATUS_SUCCESS; ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to generate an authentication event to NDIS. ++* ++* \param[in] u4Flags Authentication event: \n ++* PARAM_AUTH_REQUEST_REAUTH 0x01 \n ++* PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n ++* PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n ++* PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenMicErrorEvent(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgFlags) ++{ ++ P_PARAM_AUTH_EVENT_T prAuthEvent; ++ ++ DEBUGFUNC("rsnGenMicErrorEvent"); ++ ++ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; ++ ++ /* Status type: Authentication Event */ ++ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; ++ ++ /* Authentication request */ ++ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); ++ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, ++ (PVOID) prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN); ++ ++ if (fgFlags == TRUE) ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; ++ else ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAuthEvent, ++ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); ++ ++} /* rsnGenMicErrorEvent */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to handle TKIP MIC failures. ++* ++* \param[in] adapter_p Pointer to the adapter object data area. ++* \param[in] prSta Pointer to the STA which occur MIC Error ++* \param[in] fgErrorKeyType type of error key ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType) ++{ ++ /* UINT_32 u4RsnaCurrentMICFailTime; */ ++ /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */ ++ ++ DEBUGFUNC("rsnTkipHandleMICFailure"); ++ ++ ASSERT(prAdapter); ++#if 1 ++ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); ++ ++ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, Param_PowerModeCAM, FALSE); ++ ++ /* Generate authentication request event. */ ++ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); ++#else ++ ASSERT(prSta); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ /* Record the MIC error occur time. */ ++ GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime); ++ ++ /* Generate authentication request event. */ ++ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); ++ ++ /* If less than 60 seconds have passed since a previous TKIP MIC failure, ++ disassociate from the AP and wait for 60 seconds before (re)associating ++ with the same AP. */ ++ if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 && ++ !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime, ++ prAisSpecBssInfo->u4RsnaLastMICFailTime, SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) { ++ /* If less than 60 seconds expired since last MIC error, we have to ++ block traffic. */ ++ ++ DBGLOG(RSN, INFO, "Start blocking traffic!\n"); ++ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); ++ ++ secFsmEventStartCounterMeasure(prAdapter, prSta); ++ } else { ++ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); ++ DBGLOG(RSN, INFO, "First TKIP MIC error!\n"); ++ } ++ ++ COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime); ++#endif ++} /* rsnTkipHandleMICFailure */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to select a list of BSSID from ++* the scan results for PMKID candidate list. ++* ++* \param[in] prBssDesc the BSS Desc at scan result list ++* \param[out] pu4CandidateCount Pointer to the number of selected candidates. ++* It is set to zero if no BSSID matches our requirement. ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ DEBUGFUNC("rsnSelectPmkidCandidateList"); ++ ++ ASSERT(prBssDesc); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ++ /* Search a BSS with the same SSID from the given BSS description set. */ ++ /* DBGLOG(RSN, TRACE, ("Check scan result [%pM]\n", */ ++ /* prBssDesc->aucBSSID)); */ ++ ++ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { ++ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); ++ return; ++ } ++#if 0 ++ if ((prBssDesc->u2BSSBasicRateSet & ++ ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) || prBssDesc->fgIsUnknownBssBasicRate) { ++ DBGLOG(RSN, TRACE, "-- Rate set not matched\n"); ++ return; ++ } ++ ++ if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher || */ ++ prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*|| ++ prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) { ++ DBGLOG(RSN, TRACE, "-- Encrypt status not matched for PMKID\n"); ++ return; ++ } ++#endif ++ ++ rsnUpdatePmkidCandidateList(prAdapter, prBssDesc); ++ ++} /* rsnSelectPmkidCandidateList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to select a list of BSSID from ++* the scan results for PMKID candidate list. ++* ++* \param[in] prBssDesc the BSS DESC at scan result list ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) ++{ ++ UINT_32 i; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("rsnUpdatePmkidCandidateList"); ++ ++ ASSERT(prBssDesc); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { ++ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); ++ return; ++ } ++ ++ for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) { ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)) ++ return; ++ } ++ ++ /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16), ++ then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */ ++ if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1) > CFG_MAX_PMKID_CACHE) ++ prAisSpecBssInfo->u4PmkidCandicateCount--; ++ ++ i = prAisSpecBssInfo->u4PmkidCandicateCount; ++ ++ COPY_MAC_ADDR((PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, (PVOID) prBssDesc->aucBSSID); ++ ++ if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) { ++ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1; ++ DBGLOG(RSN, TRACE, "Add %pM with pre-auth to candidate list\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); ++ } else { ++ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0; ++ DBGLOG(RSN, TRACE, "Add %pM without pre-auth to candidate list\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); ++ } ++ ++ prAisSpecBssInfo->u4PmkidCandicateCount++; ++ ++} /* rsnUpdatePmkidCandidateList */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to search the desired entry in ++* PMKID cache according to the BSSID ++* ++* \param[in] pucBssid Pointer to the BSSID ++* \param[out] pu4EntryIndex Pointer to place the found entry index ++* ++* \retval TRUE, if found one entry for specified BSSID ++* \retval FALSE, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex) ++{ ++ UINT_32 i; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ DEBUGFUNC("rsnSearchPmkidEntry"); ++ ++ ASSERT(pucBssid); ++ ASSERT(pu4EntryIndex); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) ++ return FALSE; ++ ++ ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE); ++ ++ /* Search for desired BSSID */ ++ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { ++ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid, MAC_ADDR_LEN)) ++ break; ++ } ++ ++ /* If desired BSSID is found, then set the PMKID */ ++ if (i < prAisSpecBssInfo->u4PmkidCacheCount) { ++ *pu4EntryIndex = i; ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} /* rsnSearchPmkidEntry */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to check if there is difference ++* between PMKID candicate list and PMKID cache. If there ++* is new candicate that no cache entry is available, then ++* add a new entry for the new candicate in the PMKID cache ++* and set the PMKID indication flag to TRUE. ++* ++* \retval TRUE, if new member in the PMKID candicate list ++* \retval FALSe, if no new member in the PMKID candicate list ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ UINT_32 i; /* Index for PMKID candicate */ ++ UINT_32 j; /* Indix for PMKID cache */ ++ BOOLEAN status = FALSE; ++ ++ DEBUGFUNC("rsnCheckPmkidCandicate"); ++ ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ /* Check for each candicate */ ++ for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) { ++ for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) { ++ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, ++ prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN)) { ++ /* DBGLOG(RSN, TRACE, ("%pM at PMKID cache!!\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); */ ++ break; ++ } ++ } ++ ++ /* No entry found in PMKID cache for the candicate, add new one */ ++ if (j == prAisSpecBssInfo->u4PmkidCacheCount ++ && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) { ++ DBGLOG(RSN, TRACE, ++ "Add %pM to PMKID cache!!\n", ++ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); ++ kalMemCopy((PVOID) prAisSpecBssInfo-> ++ arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID, ++ (PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN); ++ prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE; ++ prAisSpecBssInfo->u4PmkidCacheCount++; ++ ++ status = TRUE; ++ } ++ } ++ ++ return status; ++} /* rsnCheckPmkidCandicate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to wait a duration to indicate the pre-auth AP candicate ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) ++{ ++ DBGLOG(RSN, EVENT, "Security - Time to indicate the PMKID cand.\n"); ++ ++ /* If the authentication mode is WPA2 and indication PMKID flag ++ is available, then we indicate the PMKID candidate list to NDIS and ++ clear the flag, indicatePMKID */ ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED && ++ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { ++ rsnGeneratePmkidIndication(prAdapter); ++ } ++ ++} /* end of rsnIndicatePmkidCand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to check the BSS Desc at scan result ++* with pre-auth cap at wpa2 mode. If there ++* is candicate that no cache entry is available, then ++* add a new entry for the new candicate in the PMKID cache ++* and set the PMKID indication flag to TRUE. ++* ++* \param[in] prBss The BSS Desc at scan result ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) ++{ ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ DEBUGFUNC("rsnCheckPmkidCandicate"); ++ ++ ASSERT(prBss); ++ ++ prConnSettings = &prAdapter->rWifiVar.rConnSettings; ++ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && ++ (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) { ++ rsnSelectPmkidCandidateList(prAdapter, prBss); ++ ++ /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection() ++ will indicate this later */ ++ if (rsnCheckPmkidCandicate(prAdapter)) { ++ DBGLOG(RSN, TRACE, "Prepare a timer to indicate candidate PMKID Candidate\n"); ++ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); ++ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, ++ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to generate an PMKID candidate list ++* indication to NDIS. ++* ++* \param[in] prAdapter Pointer to the adapter object data area. ++* \param[in] u4Flags PMKID candidate list event: ++* PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter) ++{ ++ P_PARAM_STATUS_INDICATION_T prStatusEvent; ++ P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; ++ UINT_8 i, j = 0, count = 0; ++ UINT_32 u4LenOfUsedBuffer; ++ ++ DEBUGFUNC("rsnGeneratePmkidIndication"); ++ ++ ASSERT(prAdapter); ++ ++ prStatusEvent = (P_PARAM_STATUS_INDICATION_T) prAdapter->aucIndicationEventBuffer; ++ ++ /* Status type: PMKID Candidatelist Event */ ++ prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; ++ ASSERT(prStatusEvent); ++ ++ prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T) (&prStatusEvent->eStatusType + 1); ++ ASSERT(prPmkidEvent); ++ ++ prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prAisSpecificBssInfo); ++ ++ for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) { ++ for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) { ++ if (EQUAL_MAC_ADDR(prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, ++ prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) && ++ (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)) { ++ break; ++ } ++ } ++ if (count >= CFG_MAX_PMKID_CACHE) ++ break; ++ ++ if (j == prAisSpecificBssInfo->u4PmkidCacheCount) { ++ kalMemCopy((PVOID) prPmkidEvent->arCandidateList[count].arBSSID, ++ (PVOID) prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid, PARAM_MAC_ADDR_LEN); ++ prPmkidEvent->arCandidateList[count].u4Flags = ++ prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags; ++ DBGLOG(RSN, TRACE, "%pM %d\n", (prPmkidEvent->arCandidateList[count].arBSSID), ++ (UINT_32) prPmkidEvent->arCandidateList[count].u4Flags); ++ count++; ++ } ++ } ++ ++ /* PMKID Candidate List */ ++ prPmkidEvent->u4Version = 1; ++ prPmkidEvent->u4NumCandidates = count; ++ DBGLOG(RSN, TRACE, "rsnGeneratePmkidIndication #%d\n", (UINT_32) prPmkidEvent->u4NumCandidates); ++ u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) + ++ (count * sizeof(PARAM_PMKID_CANDIDATE_T)); ++ /* dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); */ ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); ++ ++} /* rsnGeneratePmkidIndication */ ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate WSC IE for ++* associate request frame. ++* ++* \param[in] prCurrentBss The Selected BSS description ++* ++* \retval The append WSC IE length ++* ++* \note ++* Called by: AIS module, Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); ++ ++ /* ASSOC INFO IE ID: 221 :0xDD */ ++ if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) { ++ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, ++ prAdapter->prGlueInfo->u2WSCAssocInfoIELen); ++ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen; ++ } ++ ++} ++#endif ++ ++#if CFG_SUPPORT_802_11W ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if the Bip Key installed or not ++* ++* \param[in] ++* prAdapter ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX) ++ return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled; ++ else ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to check the Sa query timeout. ++* ++* ++* \note ++* Called by: AIS module, Handle by Sa Quert timeout ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ UINT_32 now; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ GET_CURRENT_SYSTIME(&now); ++ ++ if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, TU_TO_MSEC(1000))) { ++ LOG_FUNC("association SA Query timed out\n"); ++ ++ prBssSpecInfo->ucSaQueryTimedOut = 1; ++ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ prBssSpecInfo->pucSaQueryTransId = NULL; ++ prBssSpecInfo->u4SaQueryCount = 0; ++ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); ++ /* Re-connect */ ++ DBGLOG(RSN, TRACE, "DisBy11w\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to start the 802.11w sa query timer. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_SA_QUERY_FRAME prTxFrame; ++ UINT_16 u2PayloadLen; ++ PUINT_8 pucTmp = NULL; ++ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ASSERT(prBssInfo); ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ LOG_FUNC("MFP: Start Sa Query\n"); ++ ++ if (prBssSpecInfo->u4SaQueryCount > 0 && rsnCheckSaQueryTimeout(prAdapter)) { ++ LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount); ++ return; ++ } ++ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ ++ if (!prMsduInfo) ++ return; ++ ++ prTxFrame = (P_ACTION_SA_QUERY_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; ++ prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST; ++ ++ if (prBssSpecInfo->u4SaQueryCount == 0) ++ GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart); ++ ++ if (prBssSpecInfo->u4SaQueryCount) { ++ pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); ++ if (!pucTmp) { ++ DBGLOG(RSN, ERROR, "MFP: Fail to alloc tmp buffer for backup sa query id\n"); ++ return; ++ } ++ kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ } ++ ++ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ ++ ucTransId[0] = (UINT_8) (kalRandomNumber() & 0xFF); ++ ucTransId[1] = (UINT_8) (kalRandomNumber() & 0xFF); ++ ++ kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ prBssSpecInfo->u4SaQueryCount++; ++ ++ prBssSpecInfo->pucSaQueryTransId = ++ kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); ++ if (!prBssSpecInfo->pucSaQueryTransId) { ++ DBGLOG(RSN, ERROR, "MFP: Fail to alloc buffer for sa query id list\n"); ++ return; ++ } ++ ++ if (pucTmp) { ++ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, ++ (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); ++ kalMemCopy(&prBssSpecInfo->pucSaQueryTransId ++ [(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN], ucTransId, ++ ACTION_SA_QUERY_TR_ID_LEN); ++ kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); ++ } else { ++ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ } ++ ++ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ DBGLOG(RSN, TRACE, ++ "Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval); ++ ++ cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, TU_TO_MSEC(201)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to start the 802.11w sa query. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnStartSaQuery(IN P_ADAPTER_T prAdapter) ++{ ++ rsnStartSaQueryTimer(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to stop the 802.11w sa query. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnStopSaQuery(IN P_ADAPTER_T prAdapter) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); ++ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, ++ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); ++ prBssSpecInfo->pucSaQueryTransId = NULL; ++ prBssSpecInfo->u4SaQueryCount = 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11w sa query action frame. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_ACTION_SA_QUERY_FRAME prRxFrame = NULL; ++ UINT_16 u2PayloadLen; ++ P_STA_RECORD_T prStaRec; ++ P_ACTION_SA_QUERY_FRAME prTxFrame; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; ++ ASSERT(prBssInfo); ++ ++ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; ++ if (!prRxFrame) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Request from %pM\n", prStaRec->aucMacAddr); ++ ++ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Ignore SA Query Request from unassociated STA %pM\n", ++ prStaRec->aucMacAddr); ++ return; ++ } ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Sending SA Query Response to %pM\n", prStaRec->aucMacAddr); ++ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ ++ if (!prMsduInfo) ++ return; ++ ++ prTxFrame = (P_ACTION_SA_QUERY_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ /* SA Query always with protected */ ++ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; ++ ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; ++ prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE; ++ ++ kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11w sa query action frame. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; ++ P_ACTION_SA_QUERY_FRAME prRxFrame; ++ P_STA_RECORD_T prStaRec; ++ UINT_32 i; ++ ++ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ASSERT(prBssSpecInfo); ++ ++ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Too short SA Query Action frame (len=%u)\n", ++ prSwRfb->u2PacketLen); ++ return; ++ } ++ ++ if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) { ++ rsnSaQueryRequest(prAdapter, prSwRfb); ++ return; ++ } ++ ++ if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Unexpected SA Query " "Action %d\n", prRxFrame->ucAction); ++ return; ++ } ++ ++ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Response from %pM\n", prStaRec->aucMacAddr); ++ ++ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); ++ ++ /* MLME-SAQuery.confirm */ ++ ++ for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) { ++ if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId + ++ i * ACTION_SA_QUERY_TR_ID_LEN, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0) ++ break; ++ } ++ ++ if (i >= prBssSpecInfo->u4SaQueryCount) { ++ DBGLOG(RSN, TRACE, "IEEE 802.11: No matching SA Query " "transaction identifier found\n"); ++ return; ++ } ++ ++ DBGLOG(RSN, TRACE, "Reply to pending SA Query received\n"); ++ ++ rsnStopSaQuery(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11w mgmt frame. ++* ++* ++* \note ++* Called by: AIS module, Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype) ++{ ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ BOOLEAN fgUnicast = TRUE; ++ BOOLEAN fgRobustAction = FALSE; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ++ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) && ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { ++ ++ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; ++ ++ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; ++ ++ if (prAssocReqFrame->aucDestAddr[0] & BIT(0)) ++ fgUnicast = FALSE; ++ ++ LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved, ++ (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype); ++ ++ if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) { ++ /* "Dropped unprotected Robust Action frame from an MFP STA" */ ++ /* exclude Public Action */ ++ if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */) { ++ UINT_8 ucAction = *prSwRfb->pucRecvBuff; ++ ++ if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) { ++#if DBG && CFG_RX_PKTS_DUMP ++ LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction); ++#endif ++ fgRobustAction = TRUE; ++ return TRUE; ++ } ++ } ++ if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) ++ || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) { ++ LOG_FUNC("QM RX MGT: rsnStartSaQuery\n"); ++ /* MFP test plan 5.3.3.5 */ ++ rsnStartSaQuery(prAdapter); ++ return TRUE; ++ } ++ } ++#if 0 ++ else { ++ if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) { ++ /* This done by function handler */ ++ /* kalIndicateStatusAndComplete(prAdapter->prGlueInfo, */ ++ /* WLAN_STATUS_MEDIA_DISCONNECT, */ ++ /* NULL, */ ++ /* 0); */ ++ } ++ } ++#endif ++ } ++ return FALSE; ++} ++#endif ++ ++#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE ++static BOOLEAN rsnCheckWpaRsnInfo(P_BSS_INFO_T prBss, P_RSN_INFO_T prWpaRsnInfo) ++{ ++ UINT_32 i = 0; ++ ++ if (prWpaRsnInfo->u4GroupKeyCipherSuite != prBss->u4RsnSelectedGroupCipher) { ++ DBGLOG(RSN, INFO, "GroupCipherSuite change, old=0x%04x, new=0x%04x\n", ++ prBss->u4RsnSelectedGroupCipher, prWpaRsnInfo->u4GroupKeyCipherSuite); ++ return TRUE; ++ } ++ for (; i < prWpaRsnInfo->u4AuthKeyMgtSuiteCount; i++) ++ if (prBss->u4RsnSelectedAKMSuite == prWpaRsnInfo->au4AuthKeyMgtSuite[i]) ++ break; ++ if (i == prWpaRsnInfo->u4AuthKeyMgtSuiteCount) { ++ DBGLOG(RSN, INFO, "KeyMgmt change, not find 0x%04x in new beacon\n", prBss->u4RsnSelectedAKMSuite); ++ return TRUE; ++ } ++ ++ for (i = 0; i < prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) ++ if (prBss->u4RsnSelectedPairwiseCipher == prWpaRsnInfo->au4PairwiseKeyCipherSuite[i]) ++ break; ++ if (i == prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount) { ++ DBGLOG(RSN, INFO, "Pairwise Cipher change, not find 0x%04x in new beacon\n", ++ prBss->u4RsnSelectedPairwiseCipher); ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc) ++{ ++ ENUM_PARAM_AUTH_MODE_T eAuthMode = prAdapter->rWifiVar.rConnSettings.eAuthMode; ++ ++ switch (eAuthMode) { ++ case AUTH_MODE_OPEN: /* original is open system */ ++ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) && !prAdapter->prGlueInfo->rWpaInfo.fgPrivacyInvoke) { ++ DBGLOG(RSN, INFO, "security change, open->privacy\n"); ++ return TRUE; ++ } ++ break; ++ case AUTH_MODE_SHARED: /* original is WEP */ ++ case AUTH_MODE_AUTO_SWITCH: ++ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) == 0) { ++ DBGLOG(RSN, INFO, "security change, WEP->open\n"); ++ return TRUE; ++ } else if (prBssDesc->fgIERSN || prBssDesc->fgIEWPA) { ++ DBGLOG(RSN, INFO, "security change, WEP->WPA/WPA2\n"); ++ return TRUE; ++ } ++ break; ++ case AUTH_MODE_WPA: /*original is WPA */ ++ case AUTH_MODE_WPA_PSK: ++ case AUTH_MODE_WPA_NONE: ++ if (prBssDesc->fgIEWPA) ++ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rWPAInfo); ++ DBGLOG(RSN, INFO, "security change, WPA->%s\n", ++ prBssDesc->fgIERSN ? "WPA2" : ++ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); ++ return TRUE; ++ case AUTH_MODE_WPA2: /*original is WPA2 */ ++ case AUTH_MODE_WPA2_PSK: ++ if (prBssDesc->fgIERSN) ++ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rRSNInfo); ++ DBGLOG(RSN, INFO, "security change, WPA2->%s\n", ++ prBssDesc->fgIEWPA ? "WPA" : ++ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); ++ return TRUE; ++ default: ++ DBGLOG(RSN, WARN, "unknowned eAuthMode=%d\n", eAuthMode); ++ break; ++ } ++ /*DBGLOG(RSN, INFO, ("rsnCheckSecurityModeChanged, eAuthMode=%d, u2CapInfo=0x%02x, fgIEWPA=%d, fgIERSN=%d\n", ++ eAuthMode, prBssDesc->u2CapInfo, prBssDesc->fgIEWPA, prBssDesc->fgIERSN)); */ ++ return FALSE; ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c +new file mode 100644 +index 000000000000..596ede60d788 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c +@@ -0,0 +1,1788 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2 ++*/ ++ ++/*! \file "saa_fsm.c" ++ \brief This file defines the FSM for SAA MODULE. ++ ++ This file defines the FSM for SAA MODULE. ++*/ ++ ++/* ++** Log: saa_fsm.c ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 04 20 2012 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * correct macro ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT ++ * for REASSOCIATED cases as an explicit trigger for Android framework ++ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. ++ * 2. (Android only) when reassociation-and-non-roaming cases happened, ++ * indicate an extra DISCONNECT indication to Android Wi-Fi framework ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 09 30 2011 cm.chang ++ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band ++ * Add debug message about 40MHz bandwidth allowed ++ * ++ * 05 12 2011 cp.wu ++ * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC ++ * has been invalidated before SAA-FSM starts to roll ++ * check for valid STA-REC before SAA-FSM starts to roll. ++ * ++ * 04 21 2011 terry.wu ++ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame ++ * Add network type parameter to authSendAuthFrame. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 03 31 2011 puff.wen ++ * NULL ++ * . ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add RX deauthentication & disassociation process under Hot-Spot mode. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix compile error of after Station Type Macro modification. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete ++ * and might leads to BSOD when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. ++ * Update saa_fsm for BOW. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * Add support for P2P join event start. ++ * ++ * 07 12 2010 cp.wu ++ * ++ * SAA will take a record for tracking request sequence number. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * AIS-FSM integration with CNM channel request messages ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with main branch for resetting to state 1 when associating with another AP ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration the security related function from firmware. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error when enable WiFi Direct function. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * ++ * * * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support of Driver STA_RECORD_T activation ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 12 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Fix compile warning due to declared but not used ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Refine Debug Label ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update comment ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * rename the function ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugAAState[AA_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("AA_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH1"), ++ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH2"), ++ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH3"), ++ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH4"), ++ (PUINT_8) DISP_STRING("SAA_STATE_SEND_ASSOC1"), ++ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_ASSOC2"), ++ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH2"), ++ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH4"), ++ (PUINT_8) DISP_STRING("AAA_STATE_SEND_ASSOC2"), ++ (PUINT_8) DISP_STRING("AA_STATE_RESOURCE") ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The Core FSM engine of SAA Module. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] eNextState The value of Next State ++* @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN Success ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++saaFsmSteps(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb) ++{ ++ ENUM_AA_STATE_T ePreviousState; ++ BOOLEAN fgIsTransition; ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) { ++ return; ++ } ++ ++ do { ++ ++#if DBG ++ DBGLOG(SAA, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugAAState[prStaRec->eAuthAssocState], apucDebugAAState[eNextState]); ++#else ++ DBGLOG(SAA, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_SAA_IDX, prStaRec->eAuthAssocState, eNextState); ++#endif ++ ePreviousState = prStaRec->eAuthAssocState; ++ ++ /* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */ ++ prStaRec->eAuthAssocState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ switch (prStaRec->eAuthAssocState) { ++ case AA_STATE_IDLE: ++ if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */ ++ ++ if (prRetainedSwRfb) { ++ if (saaFsmSendEventJoinComplete(prAdapter, ++ WLAN_STATUS_SUCCESS, ++ prStaRec, ++ prRetainedSwRfb) == WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ } else { ++ eNextState = AA_STATE_RESOURCE; ++ fgIsTransition = TRUE; ++ } ++ } else { ++ if (saaFsmSendEventJoinComplete(prAdapter, ++ WLAN_STATUS_FAILURE, ++ prStaRec, ++ NULL) == WLAN_STATUS_RESOURCES) { ++ eNextState = AA_STATE_RESOURCE; ++ fgIsTransition = TRUE; ++ } ++ } ++ ++ } ++ ++ /* Free allocated TCM memory */ ++ if (prStaRec->prChallengeText) { ++ cnmMemFree(prAdapter, prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ break; ++ ++ case SAA_STATE_SEND_AUTH1: ++ { ++ /* Do tasks in INIT STATE */ ++ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ eNextState = AA_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } else { ++ prStaRec->ucTxAuthAssocRetryCount++; ++ ++ /* Update Station Record - Class 1 Flag */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++#if !CFG_SUPPORT_AAA ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) { ++#else ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, ++ prStaRec->ucNetTypeIndex, ++ NULL, ++ AUTH_TRANSACTION_SEQ_1, ++ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { ++#endif /* CFG_SUPPORT_AAA */ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); ++ } ++ } ++ } ++ break; ++ ++ case SAA_STATE_WAIT_AUTH2: ++ break; ++ ++ case SAA_STATE_SEND_AUTH3: ++ { ++ /* Do tasks in INIT STATE */ ++ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ eNextState = AA_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } else { ++ prStaRec->ucTxAuthAssocRetryCount++; ++ ++#if !CFG_SUPPORT_AAA ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) { ++#else ++ if (authSendAuthFrame(prAdapter, ++ prStaRec, ++ prStaRec->ucNetTypeIndex, ++ NULL, ++ AUTH_TRANSACTION_SEQ_3, ++ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { ++#endif /* CFG_SUPPORT_AAA */ ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); ++ } ++ } ++ } ++ break; ++ ++ case SAA_STATE_WAIT_AUTH4: ++ break; ++ ++ case SAA_STATE_SEND_ASSOC1: ++ /* Do tasks in INIT STATE */ ++ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; ++ ++ eNextState = AA_STATE_IDLE; ++ fgIsTransition = TRUE; ++ } else { ++ prStaRec->ucTxAuthAssocRetryCount++; ++ ++ if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU)); ++ } ++ } ++ ++ break; ++ ++ case SAA_STATE_WAIT_ASSOC2: ++ break; ++ ++ case AA_STATE_RESOURCE: ++ /* TODO(Kevin) Can setup a timer and send message later */ ++ break; ++ ++ default: ++ DBGLOG(SAA, ERROR, "Unknown AA STATE\n"); ++ ASSERT(0); ++ break; ++ } ++ ++ } while (fgIsTransition); ++ ++ return; ++ ++} /* end of saaFsmSteps() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Event to AIS/BOW/P2P ++* ++* @param[in] rJoinStatus To indicate JOIN success or failure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* @param[in] prSwRfb Pointer to the SW_RFB_T ++ ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, ++ IN WLAN_STATUS rJoinStatus, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return WLAN_STATUS_INVALID_PACKET; ++ ++ /* Store limitation about 40Mhz bandwidth capability during association */ ++ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ if (rJoinStatus == WLAN_STATUS_SUCCESS) ++ prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++ ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; ++ ++ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); ++ if (!prSaaFsmCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; ++ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; ++ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; ++ prSaaFsmCompMsg->prStaRec = prStaRec; ++ prSaaFsmCompMsg->prSwRfb = prSwRfb; ++ ++ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { ++ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; ++ ++ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); ++ if (!prSaaFsmCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; ++ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; ++ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; ++ prSaaFsmCompMsg->prStaRec = prStaRec; ++ prSaaFsmCompMsg->prSwRfb = prSwRfb; ++ ++ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { ++ /* @TODO: BOW handler */ ++ ++ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; ++ ++ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); ++ if (!prSaaFsmCompMsg) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; ++ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; ++ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; ++ prSaaFsmCompMsg->prStaRec = prStaRec; ++ prSaaFsmCompMsg->prSwRfb = prSwRfb; ++ ++ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); ++ ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ else { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++} /* end of saaFsmSendEventJoinComplete() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Start Event to SAA FSM. ++* ++* @param[in] prMsgHdr Message of Join Request for a particular STA. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SAA_FSM_START_T prSaaFsmStartMsg; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsgHdr); ++ ++ prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T) prMsgHdr; ++ prStaRec = prSaaFsmStartMsg->prStaRec; ++ ++ if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ ASSERT(prStaRec); ++ ++ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n"); ++ ++ /* record sequence number of request message */ ++ prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ /* 4 <1> Validation of SAA Start Event */ ++ if (!IS_AP_STA(prStaRec)) { ++ ++ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); ++ ++ /* Ignore the return value because don't care the prSwRfb */ ++ saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL); ++ ++ return; ++ } ++ /* 4 <2> The previous JOIN process is not completed ? */ ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++ } ++ /* 4 <3> Reset Status Code and Time */ ++ /* Update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; ++ ++ /* Update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); ++ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ if (prStaRec->prChallengeText) { ++ cnmMemFree(prAdapter, prStaRec->prChallengeText); ++ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; ++ } ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++#if CFG_PRIVACY_MIGRATION ++ /* 4 <4> Init the sec fsm */ ++ secFsmInit(prAdapter, prStaRec); ++#endif ++ ++ /* 4 <5> Reset the STA STATE */ ++ /* Update Station Record - Class 1 Flag */ ++ /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue - ++ * We won't deactivate the same STA_RECORD_T and then activate it again for the ++ * case of reconnection. ++ */ ++ /* cnmStaRecChangeState(prStaRec, STA_STATE_1); */ ++ ++ /* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */ ++ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ++ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) ++ && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { ++ prBssInfo->fgAssoc40mBwAllowed = cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex); ++ } else { ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++ DBGLOG(RLM, INFO, "STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed); ++ } ++ /* 4 <7> Trigger SAA FSM */ ++ if (prStaRec->ucStaState == STA_STATE_1) ++ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); ++ else if (prStaRec->ucStaState == STA_STATE_2 || prStaRec->ucStaState == STA_STATE_3) ++ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, (P_SW_RFB_T) NULL); ++ ++} /* end of saaFsmRunEventStart() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM. ++* ++* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. ++* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. ++* ++* @retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ ++ P_STA_RECORD_T prStaRec; ++ ENUM_AA_STATE_T eNextState; ++ ++ ASSERT(prMsduInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) { ++ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status %d, Invalid StaRec\n", rTxDoneStatus); ++ return WLAN_STATUS_INVALID_PACKET; ++ } ++ ++ ASSERT(prStaRec); ++ ++ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status: %d, eAuthAssocState: %d , SeqNO: %d ", ++ rTxDoneStatus, prStaRec->eAuthAssocState, ++ prMsduInfo->ucTxSeqNum); ++ ++ eNextState = prStaRec->eAuthAssocState; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_AUTH1: ++ { ++ /* Strictly check the outgoing frame is matched with current AA STATE */ ++ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) { ++ eNextState = SAA_STATE_WAIT_AUTH2; ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); ++ } ++ ++ /* if TX was successful, change to next state. ++ * if TX was failed, do retry if possible. ++ */ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ case SAA_STATE_SEND_AUTH3: ++ { ++ /* Strictly check the outgoing frame is matched with current JOIN STATE */ ++ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) { ++ eNextState = SAA_STATE_WAIT_AUTH4; ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); ++ } ++ ++ /* if TX was successful, change to next state. ++ * if TX was failed, do retry if possible. ++ */ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ case SAA_STATE_SEND_ASSOC1: ++ { ++ /* Strictly check the outgoing frame is matched with current SAA STATE */ ++ if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) ++ break; ++ ++ if (rTxDoneStatus == TX_RESULT_SUCCESS) { ++ eNextState = SAA_STATE_WAIT_ASSOC2; ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prStaRec->rTxReqDoneOrRxRespTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, ++ (ULONG) prStaRec); ++ ++ cnmTimerStartTimer(prAdapter, ++ &(prStaRec->rTxReqDoneOrRxRespTimer), ++ TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU)); ++ } ++ /* if TX was successful, change to next state. ++ * if TX was failed, do retry if possible. ++ */ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of saaFsmRunEventTxDone() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Tx Request Timeout Event to SAA FSM. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ++ DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %u\n", kalGetTimeTick()); ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_AUTH1: ++ case SAA_STATE_SEND_AUTH3: ++ case SAA_STATE_SEND_ASSOC1: ++ saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T) NULL); ++ break; ++ ++ default: ++ return; ++ } ++ ++} /* end of saaFsmRunEventTxReqTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will send Rx Response Timeout Event to SAA FSM. ++* ++* @param[in] prStaRec Pointer to the STA_RECORD_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ ENUM_AA_STATE_T eNextState; ++ ++ DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %u\n", kalGetTimeTick()); ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) ++ return; ++ ++ eNextState = prStaRec->eAuthAssocState; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_WAIT_AUTH2: ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ /* Pull back to earlier state to do retry */ ++ eNextState = SAA_STATE_SEND_AUTH1; ++ break; ++ ++ case SAA_STATE_WAIT_AUTH4: ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; ++ ++ /* Pull back to earlier state to do retry */ ++ eNextState = SAA_STATE_SEND_AUTH3; ++ break; ++ ++ case SAA_STATE_WAIT_ASSOC2: ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; ++ ++ /* Pull back to earlier state to do retry */ ++ eNextState = SAA_STATE_SEND_ASSOC1; ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ if (eNextState != prStaRec->eAuthAssocState) ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ ++} /* end of saaFsmRunEventRxRespTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx Auth Response Frame and then ++* trigger SAA FSM. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2StatusCode; ++ ENUM_AA_STATE_T eNextState; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ /* We should have the corresponding Sta Record. */ ++ if (!prStaRec) { ++ /* Peter: we can handle the packet without station record */ ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ if (!IS_AP_STA(prStaRec)) ++ return; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_AUTH1: ++ case SAA_STATE_WAIT_AUTH2: ++ /* Check if the incoming frame is what we are waiting for */ ++ if (authCheckRxAuthFrameStatus(prAdapter, ++ prSwRfb, AUTH_TRANSACTION_SEQ_2, &u2StatusCode) == WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); ++ ++ if (prStaRec->ucAuthAlgNum == (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY) { ++ ++ eNextState = SAA_STATE_SEND_AUTH3; ++ } else { ++ /* Update Station Record - Class 2 Flag */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++ eNextState = SAA_STATE_SEND_ASSOC1; ++ } ++ } else { ++ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", ++ (prStaRec->aucMacAddr), u2StatusCode); ++ ++ eNextState = AA_STATE_IDLE; ++ } ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ case SAA_STATE_SEND_AUTH3: ++ case SAA_STATE_WAIT_AUTH4: ++ /* Check if the incoming frame is what we are waiting for */ ++ if (authCheckRxAuthFrameStatus(prAdapter, ++ prSwRfb, AUTH_TRANSACTION_SEQ_4, &u2StatusCode) == WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */ ++ ++ /* Update Station Record - Class 2 Flag */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++ eNextState = SAA_STATE_SEND_ASSOC1; ++ } else { ++ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", ++ (prStaRec->aucMacAddr), u2StatusCode); ++ ++ eNextState = AA_STATE_IDLE; ++ } ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++} /* end of saaFsmRunEventRxAuth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will process the Rx (Re)Association Response Frame and then ++* trigger SAA FSM. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS if the status code was not success ++* @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2StatusCode; ++ ENUM_AA_STATE_T eNextState; ++ P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T) NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ /* We should have the corresponding Sta Record. */ ++ if (!prStaRec) { ++ ASSERT(0); ++ return rStatus; ++ } ++ ++ if (!IS_AP_STA(prStaRec)) ++ return rStatus; ++ ++ switch (prStaRec->eAuthAssocState) { ++ case SAA_STATE_SEND_ASSOC1: ++ case SAA_STATE_WAIT_ASSOC2: ++ /* TRUE if the incoming frame is what we are waiting for */ ++ if (assocCheckRxReAssocRspFrameStatus(prAdapter, prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) { ++ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = u2StatusCode; ++ ++ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { ++ ++ /* Update Station Record - Class 3 Flag */ ++ /* NOTE(Kevin): Moved to AIS FSM for roaming issue - ++ * We should deactivate the STA_RECORD_T of previous AP before ++ * activate new one in Driver. ++ */ ++ /* cnmStaRecChangeState(prStaRec, STA_STATE_3); */ ++ ++ prStaRec->ucJoinFailureCount = 0; /* Clear history. */ ++ ++ prRetainedSwRfb = prSwRfb; ++ rStatus = WLAN_STATUS_PENDING; ++ } else { ++ DBGLOG(SAA, INFO, "Assoc Req was rejected by [ %pM ], Status Code = %d\n", ++ (prStaRec->aucMacAddr), u2StatusCode); ++ } ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ /* update RCPI */ ++ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; ++ ++ eNextState = AA_STATE_IDLE; ++ ++ saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb); ++ } ++ break; ++ ++ default: ++ break; /* Ignore other cases */ ++ } ++ ++ return rStatus; ++ ++} /* end of saaFsmRunEventRxAssoc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the incoming Deauth Frame. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if (prStaRec == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; ++ DBGLOG(SAA, INFO, "Rx Deauth frame from BSSID=[ %pM ].\n", prDeauthFrame->aucBSSID); ++ ++ do { ++ if (IS_STA_IN_AIS(prStaRec)) { ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ if (!IS_AP_STA(prStaRec)) ++ break; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prStaRec->ucStaState <= STA_STATE_1) ++ break; ++ ++ /* Check if this is the AP we are associated or associating with */ ++ if (authProcessRxDeauthFrame(prSwRfb, ++ prStaRec->aucMacAddr, ++ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ ++ DBGLOG(SAA, INFO, "Deauth reason = %d\n", prStaRec->u2ReasonCode); ++ ++ if (STA_STATE_2 <= prStaRec->ucStaState) { ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ ++ /* NOTE(Kevin): Change state immediately to avoid starvation of ++ * MSG buffer because of too many deauth frames before changing ++ * the STA state. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ prAisAbortMsg = ++ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) ++ break; ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; ++ prAisAbortMsg->ucReasonOfDisconnect = ++ DISCONNECT_REASON_CODE_DEAUTHENTICATED; ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, ++ MBOX_ID_0, ++ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ } else { ++ ++ /* TODO(Kevin): Joining Abort */ ++ } ++ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; ++ ++ } ++ ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ /* TODO(Kevin) */ ++ p2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb); ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (IS_STA_IN_BOW(prStaRec)) ++ bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb); ++#endif ++ else ++ ASSERT(0); ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of saaFsmRunEventRxDeauth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will check the incoming Disassociation Frame. ++* ++* @param[in] prSwRfb Pointer to the SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; ++ ++ ASSERT(prSwRfb); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if (prStaRec == NULL) ++ return WLAN_STATUS_FAILURE; ++ ++ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; ++ DBGLOG(SAA, INFO, "Rx Disassoc frame from BSSID=[ %pM ].\n", (prDisassocFrame->aucBSSID)); ++ ++ do { ++ if (IS_STA_IN_AIS(prStaRec)) { ++ P_AIS_BSS_INFO_T prAisBssInfo; ++ ++ if (!IS_AP_STA(prStaRec)) ++ break; ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prStaRec->ucStaState <= STA_STATE_1) ++ break; ++ ++ /* Check if this is the AP we are associated or associating with */ ++ if (assocProcessRxDisassocFrame(prAdapter, ++ prSwRfb, ++ prStaRec->aucMacAddr, ++ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { ++ ++ DBGLOG(SAA, INFO, "Disassoc reason = %d\n", prStaRec->u2ReasonCode); ++ ++ if (STA_STATE_3 <= prStaRec->ucStaState) { ++ P_MSG_AIS_ABORT_T prAisAbortMsg; ++ /* NOTE(Chaozhong): Change state immediately to avoid starvation of ++ * MSG buffer because of too many disassoc frames before changing ++ * the STA state. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); ++ ++ prAisAbortMsg = ++ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_AIS_ABORT_T)); ++ if (!prAisAbortMsg) ++ break; ++ ++ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; ++ prAisAbortMsg->ucReasonOfDisconnect = ++ DISCONNECT_REASON_CODE_DISASSOCIATED; ++ prAisAbortMsg->fgDelayIndication = FALSE; ++ ++ mboxSendMsg(prAdapter, ++ MBOX_ID_0, ++ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); ++ } else { ++ ++ /* TODO(Kevin): Joining Abort */ ++ } ++ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; ++ ++ } ++ ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { ++ /* TODO(Kevin) */ ++ p2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb); ++ } ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (IS_STA_IN_BOW(prStaRec)) { ++ /* Do nothing */ ++ /* TODO(Kevin) */ ++ } ++#endif ++ else ++ ASSERT(0); ++ ++ } while (FALSE); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of saaFsmRunEventRxDisassoc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle the Abort Event to SAA FSM. ++* ++* @param[in] prMsgHdr Message of Abort Request for a particular STA. ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg; ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prMsgHdr); ++ ++ prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T) prMsgHdr; ++ prStaRec = prSaaFsmAbortMsg->prStaRec; ++ ++ ASSERT(prStaRec); ++ if (!prStaRec) { ++ cnmMemFree(prAdapter, prMsgHdr); ++ return; ++ } ++ ++ DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n"); ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prStaRec->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel JOIN relative Timer */ ++ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); ++ ++ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { ++#if DBG ++ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %s.\n", ++ apucDebugAAState[prStaRec->eAuthAssocState]); ++#else ++ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %d.\n", prStaRec->eAuthAssocState); ++#endif ++ } ++#if 0 ++ /* For the Auth/Assoc State to IDLE */ ++ prStaRec->eAuthAssocState = AA_STATE_IDLE; ++#else ++ /* Free this StaRec */ ++ cnmStaRecFree(prAdapter, prStaRec, FALSE); ++#endif ++ ++} /* end of saaFsmRunEventAbort() */ ++ ++/* TODO(Kevin): following code will be modified and move to AIS FSM */ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will send Join Timeout Event to JOIN FSM. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ ++ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); ++ ++ /* Get a Station Record if possible, TA == BSSID for AP */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); ++ ++ /* We have renew this Sta Record when in JOIN_STATE_INIT */ ++ ASSERT(prStaRec); ++ ++ /* Record the Status Code of Authentication Request */ ++ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; ++ ++ /* Increase Failure Count */ ++ prStaRec->ucJoinFailureCount++; ++ ++ /* Reset Send Auth/(Re)Assoc Frame Count */ ++ prJoinInfo->ucTxAuthAssocRetryCount = 0; ++ ++ /* Cancel other JOIN relative Timer */ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); ++ ++ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); ++ ++ /* Restore original setting from current BSS_INFO_T */ ++ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) ++ joinAdoptParametersFromCurrentBss(prAdapter); ++ ++ /* Pull back to IDLE */ ++ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); ++ ++ return WLAN_STATUS_FAILURE; ++ ++} /* end of joinFsmRunEventJoinTimeOut() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from Peer BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ ++ DEBUGFUNC("joinAdoptParametersFromPeerBss"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ ++ /* 4 <1> Adopt Peer BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; ++ ++ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", ++ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); ++ ++ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); ++ ++ prJoinInfo->fgIsParameterAdopted = TRUE; ++ ++} /* end of joinAdoptParametersFromPeerBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will adopt the parameters from current associated BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) ++{ ++ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ prBssInfo = &prAdapter->rBssInfo; ++ ++ /* 4 <1> Adopt current BSS' PHY TYPE */ ++ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; ++ ++ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ ++ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); ++ ++ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); ++} /* end of joinAdoptParametersFromCurrentBss() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will update all the SW variables and HW MCR registers after ++* the association with target BSS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID joinComplete(IN P_ADAPTER_T prAdapter) ++{ ++ P_JOIN_INFO_T prJoinInfo; ++ P_BSS_DESC_T prBssDesc; ++ P_PEER_BSS_INFO_T prPeerBssInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_STA_RECORD_T prStaRec; ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SUPPORT_802_11D ++ P_IE_COUNTRY_T prIECountry; ++#endif ++ ++ DEBUGFUNC("joinComplete"); ++ ++ ASSERT(prAdapter); ++ prJoinInfo = &prAdapter->rJoinInfo; ++ prBssDesc = prJoinInfo->prBssDesc; ++ prPeerBssInfo = &prAdapter->rPeerBssInfo; ++ prBssInfo = &prAdapter->rBssInfo; ++ prConnSettings = &prAdapter->rConnSettings; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ ++ /* Remove previous AP's Connection Flags if have */ ++ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); ++ ++ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ ++ ++ if (prBssDesc->fgIsHiddenSSID) { ++ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't ++ * broadcast SSID on its Beacon Frame. ++ */ ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); ++ ++ if (prBssDesc->ucSSIDLen) ++ prBssDesc->fgIsHiddenSSID = FALSE; ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); ++ } ++/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ ++ /* 4 <2.A> PHY Type */ ++ prBssInfo->ePhyType = prBssDesc->ePhyType; ++ ++ /* 4 <2.B> BSS Type */ ++ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ ++ /* 4 <2.C> BSSID */ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); ++ ++ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); ++ ++ /* 4 <2.D> SSID */ ++ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ ++ /* 4 <2.E> Channel / Band information. */ ++ prBssInfo->eBand = prBssDesc->eBand; ++ prBssInfo->ucChnl = prBssDesc->ucChannelNum; ++ ++ /* 4 <2.F> RSN/WPA information. */ ++ secFsmRunEventStart(prAdapter); ++ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; ++ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; ++ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; ++ ++ if (secRsnKeyHandshakeEnabled()) ++ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; ++ else ++ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; ++ ++ /* 4 <2.G> Beacon interval. */ ++ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; ++ ++ /* 4 <2.H> DTIM period. */ ++ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; ++ ++ /* 4 <2.I> ERP Information */ ++ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ ++ (prBssDesc->fgIsERPPresent)) { ++ ++ prBssInfo->fgIsERPPresent = TRUE; ++ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ ++ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ ++ prBssInfo->fgIsERPPresent = FALSE; ++ prBssInfo->ucERP = 0; ++ } ++ ++#if CFG_SUPPORT_802_11D ++ /* 4 <2.J> Country inforamtion of the associated AP */ ++ if (prConnSettings->fgMultiDomainCapabilityEnabled) { ++ DOMAIN_INFO_ENTRY rDomainInfo; ++ ++ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { ++ if (prBssDesc->prIECountry) { ++ prIECountry = prBssDesc->prIECountry; ++ ++ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); ++ ++ /* use the domain get from the BSS info */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); ++ } else { ++ /* use the domain get from the scan result */ ++ prBssInfo->fgIsCountryInfoPresent = TRUE; ++ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); ++ } ++ } ++ } ++#endif ++ ++ /* 4 <2.K> Signal Power of the associated AP */ ++ prBssInfo->rRcpi = prBssDesc->rRcpi; ++ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); ++ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); ++ ++ /* 4 <2.L> Capability Field of the associated AP */ ++ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; ++ ++ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", ++ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); ++ ++/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ ++ /* 4 <3.A> Association ID */ ++ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; ++ ++ /* 4 <3.B> WMM Information */ ++ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { ++ ++ prBssInfo->fgIsWmmAssoc = TRUE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; ++ ++ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); ++ ++ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { ++ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } else { ++ kalMemCopy(&prBssInfo->rWmmInfo, ++ &prPeerBssInfo->rWmmInfo, ++ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); ++ } ++ } else { ++ prBssInfo->fgIsWmmAssoc = FALSE; ++ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; ++ ++ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); ++ } ++ ++ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ ++ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; ++ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; ++ ++ /* 4 <3.D> Short Preamble */ ++ if (prBssInfo->fgIsERPPresent) { ++ ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) ++ * TRUE FALSE TRUE FALSE ++ * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) ++ * FALSE FALSE TRUE FALSE ++ * TRUE TRUE FALSE TRUE(follow ERP) ++ * TRUE TRUE TRUE FALSE(follow ERP) ++ * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) ++ * FALSE TRUE TRUE FALSE(we should set to FALSE) ++ */ ++ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || ++ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && ++ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { ++ ++ prBssInfo->fgIsShortPreambleAllowed = TRUE; ++ ++ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) ++ prBssInfo->fgUseShortPreamble = FALSE; ++ else ++ prBssInfo->fgUseShortPreamble = TRUE; ++ } else { ++ prBssInfo->fgIsShortPreambleAllowed = FALSE; ++ prBssInfo->fgUseShortPreamble = FALSE; ++ } ++ } else { ++ /* NOTE(Kevin 2007/12/24): Truth Table. ++ * Short Preamble Bit in ++ * Final Driver Setting(Short) ++ * TRUE FALSE FALSE ++ * FALSE FALSE FALSE ++ * TRUE TRUE TRUE ++ * FALSE TRUE(status success) TRUE ++ * --> Honor the result of prPeerBssInfo. ++ */ ++ ++ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = ++ prPeerBssInfo->fgIsShortPreambleAllowed; ++ } ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", ++ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); ++ ++ /* 4 <3.E> Short Slot Time */ ++ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ ++ ++ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); ++ ++ nicSetSlotTime(prAdapter, ++ prBssInfo->ePhyType, ++ ((prConnSettings->fgIsShortSlotTimeOptionEnable && ++ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); ++ ++ /* 4 <3.F> Update Tx Rate for Control Frame */ ++ bssUpdateTxRateForControlFrame(prAdapter); ++ ++ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ ++ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ ++ { ++ ++ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; ++ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) ++ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; ++ ++ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; ++ ++ /* Set the stable time of the associated BSS. We won't do roaming decision ++ * during the stable time. ++ */ ++ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, ++ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); ++ } ++ ++ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ ++#if CFG_TX_FRAGMENT ++ txFragInfoUpdate(prAdapter); ++#endif /* CFG_TX_FRAGMENT */ ++ ++/* 4 <4> Update STA_RECORD_T */ ++ /* Get a Station Record if possible */ ++ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); ++ ++ if (prStaRec) { ++ UINT_16 u2OperationalRateSet, u2DesiredRateSet; ++ ++ /* 4 <4.A> Desired Rate Set */ ++ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & ++ prBssInfo->u2OperationalRateSet); ++ ++ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); ++ if (u2DesiredRateSet) { ++ prStaRec->u2DesiredRateSet = u2DesiredRateSet; ++ } else { ++ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ ++ prStaRec->u2DesiredRateSet = u2OperationalRateSet; ++ } ++ ++ /* Try to set the best initial rate for this entry */ ++ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, ++ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { ++ ++ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) ++ ASSERT(0); ++ } ++ ++ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); ++ ++ /* 4 <4.B> Preamble Mode */ ++ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; ++ ++ /* 4 <4.C> QoS Flag */ ++ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; ++ } ++#if DBG ++ else ++ ASSERT(0); ++#endif /* DBG */ ++ ++/* 4 <5> Update NIC */ ++ /* 4 <5.A> Update BSSID & Operation Mode */ ++ nicSetupBSS(prAdapter, prBssInfo); ++ ++ /* 4 <5.B> Update WLAN Table. */ ++ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) ++ ASSERT(FALSE); ++ /* 4 <5.C> Update Desired Rate Set for BT. */ ++#if CFG_TX_FRAGMENT ++ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) ++ txRateSetInitForBT(prAdapter, prStaRec); ++#endif /* CFG_TX_FRAGMENT */ ++ ++ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ ++ if (prBssInfo->fgIsWmmAssoc) { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, FALSE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); ++ } else { ++ ++#if CFG_TX_AGGREGATE_HW_FIFO ++ nicTxAggregateTXQ(prAdapter, TRUE); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); ++ ++ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); ++ } ++ ++#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN ++ { ++ prTxCtrl->fgBlockTxDuringJoin = FALSE; ++ ++#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ ++ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); ++#endif /* CFG_TX_AGGREGATE_HW_FIFO */ ++ ++ nicTxRetransmitOfSendWaitQue(prAdapter); ++ ++ if (prTxCtrl->fgIsPacketInOsSendQueue) ++ nicTxRetransmitOfOsSendQue(prAdapter); ++#if CFG_SDIO_TX_ENHANCE ++ halTxLeftClusteredMpdu(prAdapter); ++#endif /* CFG_SDIO_TX_ENHANCE */ ++ ++ } ++#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ ++ ++/* 4 <6> Setup CONNECTION flag. */ ++ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; ++ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; ++ ++ if (prJoinInfo->fgIsReAssoc) ++ prAdapter->fgBypassPortCtrlForRoaming = TRUE; ++ else ++ prAdapter->fgBypassPortCtrlForRoaming = FALSE; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); ++ ++} /* end of joinComplete() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c +new file mode 100644 +index 000000000000..2c9ccbe82dd1 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c +@@ -0,0 +1,3103 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3 ++*/ ++ ++/*! \file "scan.c" ++ \brief This file defines the scan profile and the processing function of ++ scan result for SCAN Module. ++ ++ The SCAN Profile selection is part of SCAN MODULE and responsible for defining ++ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. ++ In this file we also define the process of SCAN Result including adding, searching ++ and removing SCAN record from the list. ++*/ ++ ++/* ++** Log: scan.c ++** ++** 01 30 2013 yuche.tsai ++** [ALPS00451578] [JB2][WFD][Case Fail][JE][MR1]?????????[Java (JE),660,-1361051648,99, ++** /data/core/,0,system_server_crash,system_server]JE happens when try to connect WFD.(4/5) ++** Fix possible old scan result indicate to supplicant after formation. ++** ++** 01 16 2013 yuche.tsai ++** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect ++** Fix possible FW assert issue. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 25 2012 cp.wu ++ * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target ++ * drop off scan result which is older than 5 seconds when choosing which BSS to join ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 16 2012 cp.wu ++ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band ++ * configuration with corresponding network configuration ++ * correct typo. ++ * ++ * 01 16 2012 cp.wu ++ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration ++ * with corresponding network configuration ++ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred ++ * band configuration corresponding to network type. ++ * ++ * 12 05 2011 cp.wu ++ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path ++ * add CONNECT_BY_BSSID policy ++ * ++ * 11 23 2011 cp.wu ++ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection ++ * add compile option to disable beacon content change detection. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp ++ * is reset with received beacon/probe response frames ++ * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before ++ * ++ * 10 11 2011 cm.chang ++ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter ++ * Ignore HT OP IE if its length field is not valid ++ * ++ * 09 30 2011 cp.wu ++ * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode ++ * correct type casting issue. ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix multicast address list issue. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 08 10 2011 cp.wu ++ * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing ++ * traverse whole BSS-DESC list because BSSID is not unique anymore. ++ * ++ * 07 12 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * for multiple BSS descriptior detecting issue: ++ * 1) check BSSID for infrastructure network ++ * 2) check SSID for AdHoc network ++ * ++ * 07 12 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * check for BSSID for beacons used to update DTIM ++ * ++ * 07 12 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * do not check BSS descriptor for connected flag due to linksys's hidden ++ * SSID will use another BSS descriptor and never connected ++ * ++ * 07 11 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * just pass beacons with the same BSSID. ++ * ++ * 07 11 2011 wh.su ++ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define ++ * for make sure the value is initialize, for customer not enable WAPI ++ * For make sure wapi initial value is set. ++ * ++ * 06 28 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * Do not check for SSID as beacon content change due to the existence of ++ * single BSSID with multiple SSID AP configuration ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple ++ * SSID settings to work around some tricky AP which use space character as hidden SSID ++ * 1. correct logic ++ * 2. replace only BSS-DESC which doesn't have a valid SSID. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID ++ * settings to work around some tricky AP which use space character as hidden SSID ++ * remove unused temporal variable reference. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID ++ * settings to work around some tricky AP which use space character as hidden SSID ++ * allow to have a single BSSID with multiple SSID to be presented in scanning result ++ * ++ * 06 02 2011 cp.wu ++ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels ++ * filter out BSS in disallowed channel by ++ * 1. do not add to scan result array if BSS is at disallowed channel ++ * 2. do not allow to search for BSS-DESC in disallowed channels ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Refine range of valid channel number ++ * ++ * 05 02 2011 cp.wu ++ * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of ++ * hardware channel number passed from firmware domain ++ * take parsed result for generating scanning result with channel information. ++ * ++ * 05 02 2011 cm.chang ++ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number ++ * Check if channel is valided before record ing BSS channel ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Always update Bss Type, for Bss Type for P2P Network is changing every time. ++ * ++ * 03 23 2011 yuche.tsai ++ * NULL ++ * Fix concurrent issue when AIS scan result would overwrite p2p scan result. ++ * ++ * 03 14 2011 cp.wu ++ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently ++ * filtering out other BSS coming from adjacent channels ++ * ++ * 03 11 2011 chinglan.wang ++ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. ++ * . ++ * ++ * 03 11 2011 cp.wu ++ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently ++ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() ++ * won't sleep long enough for specified interval such as 500ms ++ * implement beacon change detection by checking SSID and supported rate. ++ * ++ * 02 22 2011 yuche.tsai ++ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue ++ * Fix WSC big endian issue. ++ * ++ * 02 21 2011 terry.wu ++ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P ++ * Clean P2P scan list while removing P2P. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Fix scan channel extension issue when p2p module is not registered. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 21 2011 cp.wu ++ * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered ++ * BSS_DESC_T rather than using beacon-carried information ++ * SSID should come from buffered prBssDesc rather than beacon-carried information ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Fix compile error. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Memfree for P2P Descriptor & P2P Descriptor List. ++ * ++ * 01 14 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * Free P2P Descriptor List & Descriptor under BSS Descriptor. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc ++ * and vmalloc implementations to ease physically continuous memory demands ++ * 1) correct typo in scan.c ++ * 2) TX descriptors, RX descriptos and management buffer should use virtually ++ * continuous buffer instead of physically continuous one ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc ++ * and vmalloc implementations to ease physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * while being unloaded, clear all pending interrupt then set LP-own to firmware ++ * ++ * 12 21 2010 cp.wu ++ * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module ++ * SCN: enable BEST RSSI selection policy support ++ * ++ * 11 29 2010 cp.wu ++ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC ++ * for initial TX rate selection of auto-rate algorithm ++ * update ucRcpi of STA_RECORD_T for AIS when ++ * 1) Beacons for IBSS merge is received ++ * 2) Associate Response for a connecting peer is received ++ * ++ * 11 03 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Refine the HT rate disallow TKIP pairwise cipher . ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out ++ * beacons which is received on the folding frequency ++ * trust HT IE if available for 5GHz band ++ * ++ * 10 11 2010 cp.wu ++ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out ++ * beacons which is received on the folding frequency ++ * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels ++ * ++ * 10 08 2010 wh.su ++ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine ++ * update the frog's new p2p state machine. ++ * ++ * 10 01 2010 yuche.tsai ++ * NULL ++ * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV. ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate unused variables which lead gcc to argue ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * When indicate scan result, append IE buffer information in the scan result. ++ * ++ * 09 03 2010 yuche.tsai ++ * NULL ++ * 1. Update Beacon RX count when running SLT. ++ * 2. Ignore Beacon when running SLT, would not update information from Beacon. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 29 2010 yuche.tsai ++ * NULL ++ * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free. ++ * 2.. Fix P2P Device Name Length BE issue. ++ * ++ * 08 23 2010 yuche.tsai ++ * NULL ++ * Add P2P Device Found Indication to supplicant ++ * ++ * 08 20 2010 cp.wu ++ * NULL ++ * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured. ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Workaround for P2P Descriptor Infinite loop issue. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Modify code of processing Probe Resonse frame for P2P. ++ * ++ * 08 12 2010 yuche.tsai ++ * NULL ++ * Add function to get P2P descriptor of BSS descriptor directly. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Modify Scan result processing for P2P module. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Update P2P Device Discovery result add function. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add support for Probe Request & Response parsing. ++ * ++ * 07 21 2010 cp.wu ++ * ++ * 1) change BG_SCAN to ONLINE_SCAN for consistent term ++ * 2) only clear scanning result when scan is permitted to do ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Fix compile error for SCAN module while disabling P2P feature. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 wh.su ++ * ++ * update for security supporting. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * SCN module is now able to handle multiple concurrent scanning requests ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * driver no longer generates probe request frames ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * remove timer in DRV-SCN. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct BSS_DESC_T initialization after allocated. ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) for event packet, no need to fill RFB. ++ * 2) when wlanAdapterStart() failed, no need to initialize state machines ++ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan uninitialization procedure ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available, ++ * trust IE instead of RMAC information ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 28 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * send MMPDU in basic rate. ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * modify Beacon/ProbeResp to complete parsing, ++ * because host software has looser memory usage restriction ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * integrate . ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RLM APIs by CFG_RLM_MIGRATION. ++ * ++ * 06 21 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Update P2P Function call. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * RSN/PRIVACY compilation flag awareness correction ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * specify correct value for management frames. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 18 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * migration from MT6620 firmware. ++ * ++ * 06 17 2010 yuche.tsai ++ * [WPD00003839][MT6620 5931][P2P] Feature migration ++ * Fix compile error when enable P2P function. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct when ADHOC support is turned on. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan.c. ++ * ++ * 06 04 2010 george.huang ++ * [BORA00000678][MT6620]WiFi LP integration ++ * [PM] Support U-APSD for STA mode ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * adding the TKIP disallow join a HT AP code. ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add more chance of JOIN retry for BG_SCAN ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 04 29 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * adjsut the pre-authentication code. ++ * ++ * 04 27 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 19 2010 kevin.huang ++ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support ++ * Add Beacon Timeout Support and will send Null frame to diagnose connection ++ * ++ * 04 13 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add new HW CH macro support ++ * ++ * 04 06 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the firmware return the broadcast frame at wrong tc. ++ * ++ * 03 29 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * let the rsn wapi IE always parsing. ++ * ++ * 03 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Not carry HT cap when being associated with b/g only AP ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Solve the compile warning for 'return non-void' function ++ * ++ * 03 16 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Add AdHoc Mode ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * ++ * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Fix No PKT_INFO_T issue ++ * ++ * 02 26 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Update outgoing ProbeRequest Frame's TX data rate ++ * ++ * 02 23 2010 wh.su ++ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver ++ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 02 04 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 22 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Support protection and bandwidth switch ++ * ++ * 01 20 2010 kevin.huang ++ * [BORA00000569][WIFISYS] Phase 2 Integration Test ++ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags ++ * ++ * 01 11 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add Deauth and Disassoc Handler ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * ++ * Refine Beacon processing, add read RF channel from RX Status ++ * ++ * 01 04 2010 tehuang.liu ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * For working out the first connection Chariot-verified version ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 12 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Modify u2EstimatedExtraIELen for probe request ++ * ++ * Dec 9 2009 mtk01104 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add HT cap IE to probe request ++ * ++ * Dec 7 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix lint warning ++ * ++ * ++ * Dec 3 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update the process of SCAN Result by adding more Phy Attributes ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function and code for meet the new define ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Rename u4RSSI to i4RSSI ++ * ++ * Nov 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Report event of scan result to host ++ * ++ * Nov 26 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix SCAN Record update ++ * ++ * Nov 24 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Revise MGMT Handler with Retain Status and Integrate with TXM ++ * ++ * Nov 23 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add (Ext)Support Rate Set IE to ProbeReq ++ * ++ * Nov 20 2009 mtk02468 ++ * [BORA00000337] To check in codes for FPGA emulation ++ * Removed the use of SW_RFB->u2FrameLength ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix uninitial aucMacAddress[] for ProbeReq ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add scanSearchBssDescByPolicy() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Add Send Probe Request Frame ++ * ++ * Oct 30 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define REPLICATED_BEACON_TIME_THRESHOLD (3000) ++#define REPLICATED_BEACON_FRESH_PERIOD (10000) ++#define REPLICATED_BEACON_STRENGTH_THRESHOLD (32) ++ ++#define ROAMING_NO_SWING_RCPI_STEP (10) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used by SCN to initialize its variables ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnInit(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_BSS_DESC_T prBSSDesc; ++ PUINT_8 pucBSSBuff; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ pucBSSBuff = &prScanInfo->aucScanBuffer[0]; ++ ++ DBGLOG(SCN, INFO, "->scnInit()\n"); ++ ++ /* 4 <1> Reset STATE and Message List */ ++ prScanInfo->eCurrentState = SCAN_STATE_IDLE; ++ ++ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; ++ ++ LINK_INITIALIZE(&prScanInfo->rPendingMsgList); ++ ++ /* 4 <2> Reset link list of BSS_DESC_T */ ++ kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE); ++ ++ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); ++ LINK_INITIALIZE(&prScanInfo->rBSSDescList); ++ ++ for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) { ++ ++ prBSSDesc = (P_BSS_DESC_T) pucBSSBuff; ++ ++ LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry); ++ ++ pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T)); ++ } ++ /* Check if the memory allocation consist with this initialization function */ ++ ASSERT(((ULONG) pucBSSBuff - (ULONG)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE); ++ ++ /* reset freest channel information */ ++ prScanInfo->fgIsSparseChannelValid = FALSE; ++ ++ /* reset NLO state */ ++ prScanInfo->fgNloScanning = FALSE; ++ prScanInfo->fgPscnOnnning = FALSE; ++ ++ prScanInfo->prPscnParam = kalMemAlloc(sizeof(PSCN_PARAM_T), VIR_MEM_TYPE); ++ if (prScanInfo->prPscnParam) ++ kalMemZero(prScanInfo->prPscnParam, sizeof(PSCN_PARAM_T)); ++ ++} /* end of scnInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used by SCN to uninitialize its variables ++* ++* @param (none) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnUninit(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ DBGLOG(SCN, INFO, "->scnUninit()\n"); ++ ++ /* 4 <1> Reset STATE and Message List */ ++ prScanInfo->eCurrentState = SCAN_STATE_IDLE; ++ ++ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; ++ ++ /* NOTE(Kevin): Check rPendingMsgList ? */ ++ ++ /* 4 <2> Reset link list of BSS_DESC_T */ ++ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); ++ LINK_INITIALIZE(&prScanInfo->rBSSDescList); ++ ++ kalMemFree(prScanInfo->prPscnParam, VIR_MEM_TYPE, sizeof(PSCN_PARAM_T)); ++ ++} /* end of scnUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given BSSID ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given BSSID ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ if (fgCheckSsid == FALSE || prSsid == NULL) ++ return prBssDesc; ++ ++ if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { ++ return prBssDesc; ++ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { ++ prDstBssDesc = prBssDesc; ++ } else { ++ /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, ++ * SSID must be updated. */ ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen); ++ return prBssDesc; ++ } ++ } ++ } ++ ++ return prDstBssDesc; ++ ++} /* end of scanSearchBssDescByBssid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucSrcAddr Given Source Address(TA). ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]) ++{ ++ return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucSrcAddr Given Source Address(TA). ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucSrcAddr); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) { ++ if (fgCheckSsid == FALSE || prSsid == NULL) ++ return prBssDesc; ++ ++ if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { ++ return prBssDesc; ++ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { ++ prDstBssDesc = prBssDesc; ++ } ++ ++ } ++ } ++ ++ return prDstBssDesc; ++ ++} /* end of scanSearchBssDescByTA() */ ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to given BSSID ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; ++ OS_SYSTIME rLatestUpdateTime = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ if (!rLatestUpdateTime || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, rLatestUpdateTime)) { ++ prDstBssDesc = prBssDesc; ++ COPY_SYSTIME(rLatestUpdateTime, prBssDesc->rUpdateTime); ++ } ++ } ++ } ++ ++ return prDstBssDesc; ++ ++} /* end of scanSearchBssDescByBssid() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to ++* given eBSSType, BSSID and Transmitter Address ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. ++* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. ++* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]) ++{ ++ return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Find the corresponding BSS Descriptor according to ++* given eBSSType, BSSID and Transmitter Address ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. ++* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. ++* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. ++* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) ++* @param[in] prSsid Specified SSID ++* ++* @return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T ++scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BSS_TYPE_T eBSSType, ++ IN UINT_8 aucBSSID[], ++ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_BSS_DESC_T prBssDesc, prIBSSBssDesc; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ ++ ++ ASSERT(prAdapter); ++ ASSERT(aucSrcAddr); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ switch (eBSSType) { ++ case BSS_TYPE_P2P_DEVICE: ++ fgCheckSsid = FALSE; ++ case BSS_TYPE_INFRASTRUCTURE: ++ case BSS_TYPE_BOW_DEVICE: ++ { ++ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); ++ ++ /* if (eBSSType == prBssDesc->eBSSType) */ ++ ++ return prBssDesc; ++ } ++ ++ case BSS_TYPE_IBSS: ++ { ++ prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); ++ prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid); ++ ++ /* NOTE(Kevin): ++ * Rules to maintain the SCAN Result: ++ * For AdHoc - ++ * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2 ++ * -> Update TA1 entry's BSSID. ++ * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again ++ * -> Update TA1 entry's contain. ++ * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or ++ * later, TA2 merge into TA1, we get TA2(BSSID1) ++ * -> Remove TA2 first and then replace TA1 entry's TA with TA2, ++ * Still have only one entry of BSSID. ++ * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1. ++ * -> Replace TA1 entry's TA with TA2, Still have only one entry. ++ * CASE V New IBSS ++ * -> Add this one to SCAN result. ++ */ ++ if (prBssDesc) { ++ if ((!prIBSSBssDesc) || /* CASE I */ ++ (prBssDesc == prIBSSBssDesc)) { /* CASE II */ ++ ++ return prBssDesc; ++ } /* CASE III */ ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ ++ return prIBSSBssDesc; ++ } ++ ++ if (prIBSSBssDesc) { /* CASE IV */ ++ ++ return prIBSSBssDesc; ++ } ++ /* CASE V */ ++ break; /* Return NULL; */ ++ } ++ ++ default: ++ break; ++ } ++ ++ return (P_BSS_DESC_T) NULL; ++ ++} /* end of scanSearchExistingBssDesc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Delete BSS Descriptors from current list according to given Remove Policy. ++* ++* @param[in] u4RemovePolicy Remove Policy. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ /* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */ ++ /* prBSSDescList->u4NumElem)); */ ++ ++ if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) { ++ P_BSS_DESC_T prBSSDescNext; ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { ++ ++ /* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): ++ * MAC: %pM, Current Time = %08lx, Update Time = %08lx\n", */ ++ /* prBssDesc, prBssDesc->aucBSSID, rCurrentTime, prBssDesc->rUpdateTime)); */ ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ } ++ } else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) { ++ P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ if (!prBssDesc->fgIsHiddenSSID) ++ continue; ++ ++ if (!prBssDescOldest) { /* 1st element */ ++ prBssDescOldest = prBssDesc; ++ continue; ++ } ++ ++ if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) ++ prBssDescOldest = prBssDesc; ++ } ++ ++ if (prBssDescOldest) { ++ ++ /* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): ++ * MAC: %pM, Update Time = %08lx\n", */ ++ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry); ++ } ++ } else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) { ++ P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL; ++ UINT_32 u4SameSSIDCount = 0; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ if ((!prBssDesc->fgIsHiddenSSID) && ++ (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) { ++ ++ u4SameSSIDCount++; ++ ++ if (!prBssDescWeakestSameSSID) ++ prBssDescWeakestSameSSID = prBssDesc; ++ else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) ++ prBssDescWeakestSameSSID = prBssDesc; ++ } ++ ++ if (!prBssDescWeakest) { /* 1st element */ ++ prBssDescWeakest = prBssDesc; ++ continue; ++ } ++ ++ if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) ++ prBssDescWeakest = prBssDesc; ++ ++ } ++ ++ if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) && (prBssDescWeakestSameSSID)) ++ prBssDescWeakest = prBssDescWeakestSameSSID; ++ ++ if (prBssDescWeakest) { ++ ++ /* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: %pM, Update Time = %08lx\n", */ ++ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry); ++ } ++ } else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) { ++ P_BSS_DESC_T prBSSDescNext; ++ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && ++ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { ++ /* Don't remove the one currently we are connected. */ ++ continue; ++ } ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ ++ } ++ ++ return; ++ ++} /* end of scanRemoveBssDescsByPolicy() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Delete BSS Descriptors from current list according to given BSSID. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] aucBSSID Given BSSID. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prBSSDescNext; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ /* Check if such BSS Descriptor exists in a valid list */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ ++ /* BSSID is not unique, so need to traverse whols link-list */ ++ } ++ } ++ ++} /* end of scanRemoveBssDescByBssid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Delete BSS Descriptors from current list according to given band configuration ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] eBand Given band ++* @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS ++* BOW - Remove BOW BSS ++* P2P - Remove P2P BSS ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, ++ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prBSSDescNext; ++ BOOLEAN fgToRemove; ++ ++ ASSERT(prAdapter); ++ ASSERT(eBand <= BAND_NUM); ++ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ if (eBand == BAND_NULL) ++ return; /* no need to do anything, keep all scan result */ ++ ++ /* Check if such BSS Descriptor exists in a valid list */ ++ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ fgToRemove = FALSE; ++ ++ if (prBssDesc->eBand == eBand) { ++ switch (eNetTypeIndex) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) ++ || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) { ++ fgToRemove = TRUE; ++ } ++ break; ++ ++ case NETWORK_TYPE_P2P_INDEX: ++ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) ++ fgToRemove = TRUE; ++ break; ++ ++ case NETWORK_TYPE_BOW_INDEX: ++ if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) ++ fgToRemove = TRUE; ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ } ++ ++ if (fgToRemove == TRUE) { ++ /* Remove this BSS Desc from the BSS Desc list */ ++ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); ++ ++ /* Return this BSS Desc to the free BSS Desc list. */ ++ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ } ++ ++} /* end of scanRemoveBssDescByBand() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Clear the CONNECTION FLAG of a specified BSS Descriptor. ++* ++* @param[in] aucBSSID Given BSSID. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ ++ ASSERT(prAdapter); ++ ASSERT(aucBSSID); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { ++ prBssDesc->fgIsConnected = FALSE; ++ prBssDesc->fgIsConnecting = FALSE; ++ ++ /* BSSID is not unique, so need to traverse whols link-list */ ++ } ++ } ++ ++ return; ++ ++} /* end of scanRemoveConnectionFlagOfBssDescByBssid() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Allocate new BSS_DESC_T ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* ++* @return Pointer to BSS Descriptor, if has free space. NULL, if has no space. ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prFreeBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; ++ ++ LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T); ++ ++ if (prBssDesc) { ++ P_LINK_T prBSSDescList; ++ ++ kalMemZero(prBssDesc, sizeof(BSS_DESC_T)); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList)); ++ prBssDesc->fgIsP2PPresent = FALSE; ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be ++ * inserted to BSSDescList immediately. ++ */ ++ LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry); ++ } ++ ++ return prBssDesc; ++ ++} /* end of scanAllocateBssDesc() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T ++* with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prSwRfb Pointer to the receiving frame buffer. ++* ++* @return Pointer to BSS Descriptor ++* NULL if the Beacon/ProbeResp frame is invalid ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_BSS_DESC_T prBssDesc = NULL; ++ UINT_16 u2CapInfo; ++ ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset = 0; ++ ++ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; ++ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; ++ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_8 ucHwChannelNum = 0; ++ UINT_8 ucIeDsChannelNum = 0; ++ UINT_8 ucIeHtChannelNum = 0; ++ BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE; ++ PARAM_SSID_T rSsid; ++ UINT_64 u8Timestamp; ++ BOOLEAN fgIsNewBssDesc = FALSE; ++ ++ UINT_32 i; ++ UINT_8 ucSSIDChar; ++ ++ UINT_8 ucOuiType; ++ UINT_16 u2SubTypeVersion; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; ++ ++ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo); ++ WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp); ++ ++ /* decide BSS type */ ++ switch (u2CapInfo & CAP_INFO_BSS_TYPE) { ++ case CAP_INFO_ESS: ++ /* It can also be Group Owner of P2P Group. */ ++ eBSSType = BSS_TYPE_INFRASTRUCTURE; ++ break; ++ ++ case CAP_INFO_IBSS: ++ eBSSType = BSS_TYPE_IBSS; ++ break; ++ case 0: ++ /* The P2P Device shall set the ESS bit of the Capabilities field ++ * in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */ ++ eBSSType = BSS_TYPE_P2P_DEVICE; ++ break; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ /* @TODO: add rule to identify BOW beacons */ ++#endif ++ ++ default: ++ DBGLOG(SCN, ERROR, "wrong bss type %d\n", (INT_32)(u2CapInfo & CAP_INFO_BSS_TYPE)); ++ return NULL; ++ } ++ ++ /* 4 <1.1> Pre-parse SSID IE */ ++ pucIE = prWlanBeaconFrame->aucInfoElem; ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); ++ ++ if (u2IELength > CFG_IE_BUFFER_SIZE) ++ u2IELength = CFG_IE_BUFFER_SIZE; ++ kalMemZero(&rSsid, sizeof(rSsid)); ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) { ++ ucSSIDChar = '\0'; ++ ++ /* D-Link DWL-900AP+ */ ++ if (IE_LEN(pucIE) == 0) ++ fgIsValidSsid = FALSE; ++ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ ++ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && ++ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ ++ else { ++ for (i = 0; i < IE_LEN(pucIE); i++) ++ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; ++ ++ if (ucSSIDChar) ++ fgIsValidSsid = TRUE; ++ } ++ ++ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ ++ if (fgIsValidSsid == TRUE) { ++ COPY_SSID(rSsid.aucSsid, ++ rSsid.u4SsidLen, SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); ++ } ++ } ++ fgEscape = TRUE; ++ break; ++ default: ++ break; ++ } ++ ++ if (fgEscape == TRUE) ++ break; ++ } ++ if (fgIsValidSsid) ++ DBGLOG(SCN, EVENT, "%s %pM channel %d\n", rSsid.aucSsid, prWlanBeaconFrame->aucBSSID, ++ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); ++ else ++ DBGLOG(SCN, EVENT, "hidden ssid, %pM channel %d\n", prWlanBeaconFrame->aucBSSID, ++ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); ++ /* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */ ++ prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter, ++ eBSSType, ++ (PUINT_8) prWlanBeaconFrame->aucBSSID, ++ (PUINT_8) prWlanBeaconFrame->aucSrcAddr, ++ fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL); ++ ++ if (prBssDesc == (P_BSS_DESC_T) NULL) { ++ fgIsNewBssDesc = TRUE; ++ ++ do { ++ /* 4 <1.2.1> First trial of allocation */ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (prBssDesc) ++ break; ++ /* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */ ++ scanRemoveBssDescsByPolicy(prAdapter, ++ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN)); ++ ++ /* 4 <1.2.3> Second tail of allocation */ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (prBssDesc) ++ break; ++ /* 4 <1.2.4> Remove the weakest one */ ++ /* If there are more than half of BSS which has the same ssid as connection ++ * setting, remove the weakest one from them. ++ * Else remove the weakest one. ++ */ ++ scanRemoveBssDescsByPolicy(prAdapter, ++ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST)); ++ ++ /* 4 <1.2.5> reallocation */ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (prBssDesc) ++ break; ++ /* 4 <1.2.6> no space, should not happen */ ++ DBGLOG(SCN, ERROR, "no bss desc available after remove policy\n"); ++ return NULL; ++ ++ } while (FALSE); ++ ++ } else { ++ OS_SYSTIME rCurrentTime; ++ ++ /* WCXRP00000091 */ ++ /* if the received strength is much weaker than the original one, */ ++ /* ignore it due to it might be received on the folding frequency */ ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ if (prBssDesc->eBSSType != eBSSType) { ++ prBssDesc->eBSSType = eBSSType; ++ } else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum && ++ prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) { ++ /* for signal strength is too much weaker and previous beacon is not stale */ ++ if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD && ++ (rCurrentTime - prBssDesc->rUpdateTime) <= REPLICATED_BEACON_FRESH_PERIOD) { ++ DBGLOG(SCN, EVENT, "rssi is too much weaker and previous one is fresh\n"); ++ return prBssDesc; ++ } ++ /* for received beacons too close in time domain */ ++ else if (rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) { ++ DBGLOG(SCN, EVENT, "receive beacon/probe reponses too close\n"); ++ return prBssDesc; ++ } ++ } ++ ++ /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */ ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) { ++ BOOLEAN fgIsConnected, fgIsConnecting; ++ ++ /* set flag for indicating this is a new BSS-DESC */ ++ fgIsNewBssDesc = TRUE; ++ ++ /* backup 2 flags for APs which reset timestamp unexpectedly */ ++ fgIsConnected = prBssDesc->fgIsConnected; ++ fgIsConnecting = prBssDesc->fgIsConnecting; ++ scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID); ++ ++ prBssDesc = scanAllocateBssDesc(prAdapter); ++ if (!prBssDesc) ++ return NULL; ++ ++ /* restore */ ++ prBssDesc->fgIsConnected = fgIsConnected; ++ prBssDesc->fgIsConnecting = fgIsConnecting; ++ } ++ } ++#if 1 ++ ++ prBssDesc->u2RawLength = prSwRfb->u2PacketLen; ++ if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE) ++ prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE; ++ kalMemCopy(prBssDesc->aucRawBuf, prWlanBeaconFrame, prBssDesc->u2RawLength); ++#endif ++ ++ /* NOTE: Keep consistency of Scan Record during JOIN process */ ++ if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) { ++ DBGLOG(SCN, INFO, "we're connecting this BSS(%pM) now, don't update it\n", ++ prBssDesc->aucBSSID); ++ return prBssDesc; ++ } ++ /* 4 <2> Get information from Fixed Fields */ ++ prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */ ++ ++ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr); ++ ++ COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID); ++ ++ prBssDesc->u8TimeStamp.QuadPart = u8Timestamp; ++ ++ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval); ++ ++ prBssDesc->u2CapInfo = u2CapInfo; ++ ++ /* 4 <2.1> Retrieve IEs for later parsing */ ++ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); ++ ++ if (u2IELength > CFG_IE_BUFFER_SIZE) { ++ u2IELength = CFG_IE_BUFFER_SIZE; ++ prBssDesc->fgIsIEOverflow = TRUE; ++ } else { ++ prBssDesc->fgIsIEOverflow = FALSE; ++ } ++ prBssDesc->u2IELength = u2IELength; ++ ++ kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength); ++ ++ /* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */ ++ prBssDesc->fgIsERPPresent = FALSE; ++ prBssDesc->fgIsHTPresent = FALSE; ++ prBssDesc->eSco = CHNL_EXT_SCN; ++ prBssDesc->fgIEWAPI = FALSE; ++#if CFG_RSN_MIGRATION ++ prBssDesc->fgIERSN = FALSE; ++#endif ++#if CFG_PRIVACY_MIGRATION ++ prBssDesc->fgIEWPA = FALSE; ++#endif ++ ++ /* 4 <3.1> Full IE parsing on SW_RFB_T */ ++ pucIE = prWlanBeaconFrame->aucInfoElem; ++ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_SSID: ++ if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */ ++ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { ++ BOOLEAN fgIsHiddenSSID = FALSE; ++ ++ ucSSIDChar = '\0'; ++ ++ prIeSsid = (P_IE_SSID_T) pucIE; ++ ++ /* D-Link DWL-900AP+ */ ++ if (IE_LEN(pucIE) == 0) ++ fgIsHiddenSSID = TRUE; ++ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ ++ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && ++ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ ++ else { ++ for (i = 0; i < IE_LEN(pucIE); i++) ++ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; ++ ++ if (!ucSSIDChar) ++ fgIsHiddenSSID = TRUE; ++ } ++ ++ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ ++ if (!fgIsHiddenSSID) { ++ COPY_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, ++ SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); ++ } ++#if 0 ++ /* ++ After we connect to a hidden SSID, prBssDesc->aucSSID[] will ++ not be empty and prBssDesc->ucSSIDLen will not be 0, ++ so maybe we need to empty prBssDesc->aucSSID[] and set ++ prBssDesc->ucSSIDLen to 0 in prBssDesc to avoid that ++ UI still displays hidden SSID AP in scan list after ++ we disconnect the hidden SSID AP. ++ */ ++ else { ++ prBssDesc->aucSSID[0] = '\0'; ++ prBssDesc->ucSSIDLen = 0; ++ } ++#endif ++ ++ } ++ break; ++ ++ case ELEM_ID_SUP_RATES: ++ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. ++ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), ++ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" ++ */ ++ /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */ ++ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) ++ prIeSupportedRate = SUP_RATES_IE(pucIE); ++ break; ++ ++ case ELEM_ID_DS_PARAM_SET: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) ++ ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl; ++ break; ++ ++ case ELEM_ID_TIM: ++ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) ++ prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod; ++ break; ++ ++ case ELEM_ID_IBSS_PARAM_SET: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET) ++ prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow; ++ break; ++ ++#if 0 /* CFG_SUPPORT_802_11D */ ++ case ELEM_ID_COUNTRY_INFO: ++ prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE; ++ break; ++#endif ++ ++ case ELEM_ID_ERP_INFO: ++ if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) ++ prBssDesc->fgIsERPPresent = TRUE; ++ break; ++ ++ case ELEM_ID_EXTENDED_SUP_RATES: ++ if (!prIeExtSupportedRate) ++ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); ++ break; ++ ++#if CFG_RSN_MIGRATION ++ case ELEM_ID_RSN: ++ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) { ++ prBssDesc->fgIERSN = TRUE; ++ prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap; ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) ++ rsnCheckPmkidCache(prAdapter, prBssDesc); ++ } ++ break; ++#endif ++ ++ case ELEM_ID_HT_CAP: ++ prBssDesc->fgIsHTPresent = TRUE; ++ break; ++ ++ case ELEM_ID_HT_OP: ++ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) ++ break; ++ ++ if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) { ++ prBssDesc->eSco = (ENUM_CHNL_EXT_T) ++ (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO); ++ } ++ ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel; ++ ++ break; ++ ++#if CFG_SUPPORT_WAPI ++ case ELEM_ID_WAPI: ++ if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) ++ prBssDesc->fgIEWAPI = TRUE; ++ break; ++#endif ++ ++ case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */ ++#if CFG_PRIVACY_MIGRATION ++ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { ++ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && (u2SubTypeVersion == VERSION_WPA)) { ++ ++ if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) ++ prBssDesc->fgIEWPA = TRUE; ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { ++ if (ucOuiType == VENDOR_OUI_TYPE_P2P) ++ prBssDesc->fgIsP2PPresent = TRUE; ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ break; ++ ++ /* no default */ ++ } ++ } ++ ++ /* 4 <3.2> Save information from IEs - SSID */ ++ /* Update Flag of Hidden SSID for used in SEARCH STATE. */ ++ ++ /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent ++ * all cases of hidden SSID. ++ * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with ++ * valid SSID. ++ */ ++ if (prBssDesc->ucSSIDLen == 0) ++ prBssDesc->fgIsHiddenSSID = TRUE; ++ else ++ prBssDesc->fgIsHiddenSSID = FALSE; ++ ++ /* 4 <3.3> Check rate information in related IEs. */ ++ if (prIeSupportedRate || prIeExtSupportedRate) { ++ rateGetRateSetFromIEs(prIeSupportedRate, ++ prIeExtSupportedRate, ++ &prBssDesc->u2OperationalRateSet, ++ &prBssDesc->u2BSSBasicRateSet, &prBssDesc->fgIsUnknownBssBasicRate); ++ } ++ /* 4 <4> Update information from HIF RX Header */ ++ { ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ++ ASSERT(prHifRxHdr); ++ ++ /* 4 <4.1> Get TSF comparison result */ ++ prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr); ++ ++ /* 4 <4.2> Get Band information */ ++ prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr); ++ ++ /* 4 <4.2> Get channel and RCPI information */ ++ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr); ++ ++ if (BAND_2G4 == prBssDesc->eBand) { ++ ++ /* Update RCPI if in right channel */ ++ if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) { ++ ++ /* Receive Beacon/ProbeResp frame from adjacent channel. */ ++ if ((ucIeDsChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ /* trust channel information brought by IE */ ++ prBssDesc->ucChannelNum = ucIeDsChannelNum; ++ } else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) { ++ /* Receive Beacon/ProbeResp frame from adjacent channel. */ ++ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ /* trust channel information brought by IE */ ++ prBssDesc->ucChannelNum = ucIeHtChannelNum; ++ } else { ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ ++ prBssDesc->ucChannelNum = ucHwChannelNum; ++ } ++ } ++ /* 5G Band */ ++ else { ++ if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) { ++ /* Receive Beacon/ProbeResp frame from adjacent channel. */ ++ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ /* trust channel information brought by IE */ ++ prBssDesc->ucChannelNum = ucIeHtChannelNum; ++ } else { ++ /* Always update RCPI */ ++ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; ++ ++ prBssDesc->ucChannelNum = ucHwChannelNum; ++ } ++ } ++ } ++ ++ /* 4 <5> PHY type setting */ ++ prBssDesc->ucPhyTypeSet = 0; ++ ++ if (BAND_2G4 == prBssDesc->eBand) { ++ /* check if support 11n */ ++ if (prBssDesc->fgIsHTPresent) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; ++ ++ /* if not 11n only */ ++ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { ++ /* check if support 11g */ ++ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) || prBssDesc->fgIsERPPresent) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; ++ ++ /* if not 11g only */ ++ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) { ++ /* check if support 11b */ ++ if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; ++ } ++ } ++ } else { /* (BAND_5G == prBssDesc->eBande) */ ++ /* check if support 11n */ ++ if (prBssDesc->fgIsHTPresent) ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; ++ ++ /* if not 11n only */ ++ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { ++ /* Support 11a definitely */ ++ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; ++ ++ ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)); ++ } ++ } ++ ++ /* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */ ++ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); ++ ++ return prBssDesc; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. ++* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; ++ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame; ++ PARAM_MAC_ADDRESS rMacAddr; ++ PARAM_SSID_T rSsid; ++ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; ++ PARAM_802_11_CONFIG_T rConfiguration; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ UINT_8 ucRateLen = 0; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prBssDesc->eBand == BAND_2G4) { ++ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) ++ || prBssDesc->fgIsERPPresent) { ++ eNetworkType = PARAM_NETWORK_TYPE_OFDM24; ++ } else { ++ eNetworkType = PARAM_NETWORK_TYPE_DS; ++ } ++ } else { ++ ASSERT(prBssDesc->eBand == BAND_5G); ++ eNetworkType = PARAM_NETWORK_TYPE_OFDM5; ++ } ++ ++ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) { ++ /* NOTE(Kevin): Not supported by WZC(TBD) */ ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; ++ COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID); ++ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); ++ ++ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); ++ rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval; ++ rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow; ++ rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum); ++ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); ++ ++ rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen); ++ ++ /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0. ++ * from OID_802_11_BSSID_LIST ++ */ ++ for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++) ++ aucRatesEx[i] = 0; ++ ++ switch (prBssDesc->eBSSType) { ++ case BSS_TYPE_IBSS: ++ eOpMode = NET_TYPE_IBSS; ++ break; ++ ++ case BSS_TYPE_INFRASTRUCTURE: ++ case BSS_TYPE_P2P_DEVICE: ++ case BSS_TYPE_BOW_DEVICE: ++ default: ++ eOpMode = NET_TYPE_INFRA; ++ break; ++ } ++ ++ DBGLOG(SCN, TRACE, "ind %s %d\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ { ++ if (flgTdlsTestExtCapElm == TRUE) { ++ /* only for RALINK AP */ ++ UINT8 *pucElm = (UINT8 *) (prSwRfb->pvHeader + prSwRfb->u2PacketLen); ++ ++ kalMemCopy(pucElm - 9, aucTdlsTestExtCapElm, 7); ++ prSwRfb->u2PacketLen -= 2; ++/* prSwRfb->u2PacketLen += 7; */ ++ ++ DBGLOG(TDLS, INFO, ++ " %s: append ext cap element to %pM\n", ++ __func__, prBssDesc->aucBSSID); ++ } ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ if (prAdapter->rWifiVar.rScanInfo.fgNloScanning && ++ test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag)) { ++ UINT_8 i = 0; ++ P_BSS_DESC_T *pprPendBssDesc = &prScanInfo->rNloParam.aprPendingBssDescToInd[0]; ++ ++ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { ++ if (pprPendBssDesc[i]) ++ continue; ++ DBGLOG(SCN, INFO, ++ "indicate bss[%pM] before wiphy resume, need to indicate again after wiphy resume\n", ++ prBssDesc->aucBSSID); ++ pprPendBssDesc[i] = prBssDesc; ++ break; ++ } ++ } ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prSwRfb->pvHeader, ++ prSwRfb->u2PacketLen, prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ ++ nicAddScanResult(prAdapter, ++ rMacAddr, ++ &rSsid, ++ prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0, ++ RCPI_TO_dBm(prBssDesc->ucRCPI), ++ eNetworkType, ++ &rConfiguration, ++ eOpMode, ++ aucRatesEx, ++ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen, ++ (PUINT_8) ((ULONG) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN)); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of scanAddScanResult() */ ++ ++#if 1 ++ ++BOOLEAN scanCheckBssIsLegal(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) ++{ ++ BOOLEAN fgAddToScanResult = FALSE; ++ ENUM_BAND_T eBand = 0; ++ UINT_8 ucChannel = 0; ++ ++ ASSERT(prAdapter); ++ /* check the channel is in the legal doamin */ ++ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) { ++ /* check ucChannelNum/eBand for adjacement channel filtering */ ++ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE && ++ (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) { ++ fgAddToScanResult = FALSE; ++ } else { ++ fgAddToScanResult = TRUE; ++ } ++ } ++ return fgAddToScanResult; ++ ++} ++ ++VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc) ++{ ++ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; ++ P_LINK_T prBSSDescList = (P_LINK_T) NULL; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ RF_CHANNEL_INFO_T rChannelInfo; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ DBGLOG(SCN, TRACE, "scanReportBss2Cfg80211\n"); ++ ++ if (SpecificprBssDesc) { ++ { ++ /* check BSSID is legal channel */ ++ if (!scanCheckBssIsLegal(prAdapter, SpecificprBssDesc)) { ++ DBGLOG(SCN, TRACE, "Remove specific SSID[%s %d]\n", ++ SpecificprBssDesc->aucSSID, SpecificprBssDesc->ucChannelNum); ++ return; ++ } ++ ++ DBGLOG(SCN, TRACE, "Report Specific SSID[%s]\n", SpecificprBssDesc->aucSSID); ++ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) SpecificprBssDesc->aucRawBuf, ++ SpecificprBssDesc->u2RawLength, ++ SpecificprBssDesc->ucChannelNum, ++ RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); ++ } else { ++ ++ rChannelInfo.ucChannelNum = SpecificprBssDesc->ucChannelNum; ++ rChannelInfo.eBand = SpecificprBssDesc->eBand; ++ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) SpecificprBssDesc->aucRawBuf, ++ SpecificprBssDesc->u2RawLength, ++ &rChannelInfo, RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); ++ ++ } ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ SpecificprBssDesc->fgIsP2PReport = FALSE; ++#endif ++ } ++ } else { ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ /* 4 Auto Channel Selection:Record the AP Number */ ++ P_PARAM_CHN_LOAD_INFO prChnLoad; ++ UINT_8 ucIdx = 0; ++ ++ if (((prBssDesc->ucChannelNum > 0) && (prBssDesc->ucChannelNum <= 48)) ++ || (prBssDesc->ucChannelNum >= 147) /*non-DFS Channel */) { ++ if (prBssDesc->ucChannelNum <= HW_CHNL_NUM_MAX_2G4) { ++ ucIdx = prBssDesc->ucChannelNum - 1; ++ } else if (prBssDesc->ucChannelNum <= 48) { ++ ucIdx = (UINT_8) (HW_CHNL_NUM_MAX_2G4 + (prBssDesc->ucChannelNum - 34) / 4); ++ } else { ++ ucIdx = ++ (UINT_8) (HW_CHNL_NUM_MAX_2G4 + 4 + (prBssDesc->ucChannelNum - 149) / 4); ++ } ++ ++ if (ucIdx < MAX_AUTO_CHAL_NUM) { ++ prChnLoad = (P_PARAM_CHN_LOAD_INFO) & ++ (prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]); ++ prChnLoad->ucChannel = prBssDesc->ucChannelNum; ++ prChnLoad->u2APNum++; ++ } else { ++ DBGLOG(SCN, WARN, "ACS: ChIdx > MAX_AUTO_CHAL_NUM\n"); ++ } ++ ++ } ++#endif ++ /* check BSSID is legal channel */ ++ if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) { ++ DBGLOG(SCN, TRACE, "Remove SSID[%s %d]\n", ++ prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++ continue; ++ } ++ ++ if ((prBssDesc->eBSSType == eBSSType) ++#if CFG_ENABLE_WIFI_DIRECT ++ || ((eBSSType == BSS_TYPE_P2P_DEVICE) && (prBssDesc->fgIsP2PReport == TRUE)) ++#endif ++ ) { ++ ++ DBGLOG(SCN, TRACE, "Report ALL SSID[%s %d]\n", ++ prBssDesc->aucSSID, prBssDesc->ucChannelNum); ++ ++ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++ if (prBssDesc->u2RawLength != 0) { ++ kalIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBssDesc->aucRawBuf, ++ prBssDesc->u2RawLength, ++ prBssDesc->ucChannelNum, ++ RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); ++ prBssDesc->u2RawLength = 0; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ prBssDesc->fgIsP2PReport = FALSE; ++#endif ++ } ++ } else { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prBssDesc->fgIsP2PReport == TRUE) { ++#endif ++ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; ++ rChannelInfo.eBand = prBssDesc->eBand; ++ ++ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, ++ (PUINT_8) prBssDesc->aucRawBuf, ++ prBssDesc->u2RawLength, ++ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); ++ ++ /* do not clear it then we can pass the bss in Specific report */ ++ /* kalMemZero(prBssDesc->aucRawBuf,CFG_RAW_BUFFER_SIZE); */ ++ ++ /* ++ the BSS entry will not be cleared after scan done. ++ So if we dont receive the BSS in next scan, we cannot ++ pass it. We use u2RawLength for the purpose. ++ */ ++ /* prBssDesc->u2RawLength=0; */ ++#if CFG_ENABLE_WIFI_DIRECT ++ prBssDesc->fgIsP2PReport = FALSE; ++ } ++#endif ++ } ++ } ++ ++ } ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = TRUE; ++#endif ++ ++ } ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse the content of given Beacon or ProbeResp Frame. ++* ++* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. ++* ++* @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host ++* @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_BSS_INFO_T prAisBssInfo; ++ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; ++#if CFG_SLT_SUPPORT ++ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ /* 4 <0> Ignore invalid Beacon Frame */ ++ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < ++ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) { ++ /* to debug beacon length too small issue */ ++ UINT_32 u4MailBox0; ++ ++ nicGetMailbox(prAdapter, 0, &u4MailBox0); ++ DBGLOG(SCN, WARN, "if conn sys also get less length (0x5a means yes) %x\n", (UINT_32) u4MailBox0); ++ DBGLOG(SCN, WARN, "u2PacketLen %d, u2HeaderLen %d, payloadLen %d\n", ++ prSwRfb->u2PacketLen, prSwRfb->u2HeaderLen, ++ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); ++ /* dumpMemory8(prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ ++ ++#ifndef _lint ++ ASSERT(0); ++#endif /* _lint */ ++ return rStatus; ++ } ++#if CFG_SLT_SUPPORT ++ prSltInfo = &prAdapter->rWifiVar.rSltInfo; ++ ++ if (prSltInfo->fgIsDUT) { ++ DBGLOG(SCN, INFO, "\n\rBCN: RX\n"); ++ prSltInfo->u4BeaconReceiveCnt++; ++ return WLAN_STATUS_SUCCESS; ++ } else { ++ return WLAN_STATUS_SUCCESS; ++ } ++#endif ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; ++ ++ /*ALPS01475157: don't show SSID on scan list for multicast MAC AP */ ++ if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr)) { ++ DBGLOG(SCN, WARN, "received beacon/probe response from multicast AP\n"); ++ return rStatus; ++ } ++ ++ /* 4 <1> Parse and add into BSS_DESC_T */ ++ prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb); ++ ++ if (prBssDesc) { ++ /* 4 <1.1> Beacon Change Detection for Connected BSS */ ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED && ++ ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) ++ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) && ++ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && ++ EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, ++ prAisBssInfo->ucSSIDLen)) { ++ BOOLEAN fgNeedDisconnect = FALSE; ++ ++#if CFG_SUPPORT_BEACON_CHANGE_DETECTION ++ /* <1.1.2> check if supported rate differs */ ++ if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) ++ fgNeedDisconnect = TRUE; ++#endif ++#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE ++ if ( ++#if CFG_SUPPORT_WAPI ++ (prAdapter->rWifiVar.rConnSettings.fgWapiMode == TRUE && ++ !wapiPerformPolicySelection(prAdapter, prBssDesc)) || ++#endif ++ rsnCheckSecurityModeChanged(prAdapter, prAisBssInfo, prBssDesc)) { ++ DBGLOG(SCN, INFO, "Beacon security mode change detected\n"); ++ fgNeedDisconnect = FALSE; ++ aisBssSecurityChanged(prAdapter); ++ } ++#endif ++ ++ /* <1.1.3> beacon content change detected, disconnect immediately */ ++ if (fgNeedDisconnect == TRUE) ++ aisBssBeaconTimeout(prAdapter); ++ } ++ /* 4 <1.1> Update AIS_BSS_INFO */ ++ if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) ++ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) { ++ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* *not* checking prBssDesc->fgIsConnected anymore, ++ * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */ ++ if ((!prAisBssInfo->ucDTIMPeriod) && ++ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && ++ (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && ++ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { ++ ++ prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; ++ ++ /* sync with firmware for beacon information */ ++ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); ++ } ++ } ++#if CFG_SUPPORT_ADHOC ++ if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, ++ prConnSettings->ucSSIDLen) && ++ (prBssDesc->eBSSType == BSS_TYPE_IBSS) && (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) { ++ ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, ++ prSwRfb->prHifRxHdr->ucRcpi); ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ } ++ ++ rlmProcessBcn(prAdapter, ++ prSwRfb, ++ ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem, ++ (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - ++ (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]))); ++ ++ /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */ ++ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE || prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ /* for AIS, send to host */ ++ if (prConnSettings->fgIsScanReqIssued || prAdapter->rWifiVar.rScanInfo.fgNloScanning) { ++ BOOLEAN fgAddToScanResult; ++ ++ fgAddToScanResult = scanCheckBssIsLegal(prAdapter, prBssDesc); ++ ++ if (fgAddToScanResult == TRUE) ++ rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb); ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, &rStatus, prBssDesc, prWlanBeaconFrame); ++#endif ++ } ++ ++ return rStatus; ++ ++} /* end of scanProcessBeaconAndProbeResp() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or ++* MERGE(AdHoc) according to current Connection Policy. ++* ++* \return Pointer to BSS Descriptor, if found. NULL, if not found ++*/ ++/*----------------------------------------------------------------------------*/ ++P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ P_BSS_INFO_T prBssInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ P_SCAN_INFO_T prScanInfo; ++ ++ P_LINK_T prBSSDescList; ++ ++ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL; ++ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL; ++ ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ P_STA_RECORD_T prPrimaryStaRec; ++ P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL; ++ ++ OS_SYSTIME rCurrentTime; ++ ++ /* The first one reach the check point will be our candidate */ ++ BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE; ++ ++ BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE; ++ BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE; ++ /* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */ ++ ++ /* TODO(Kevin): Support Min Channel Load */ ++ /* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */ ++ ++ BOOLEAN fgIsFixedChannel; ++ ENUM_BAND_T eBand = 0; ++ UINT_8 ucChannel = 0; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); ++ ++ prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ ++ /* check for fixed channel operation */ ++ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++#if CFG_P2P_LEGACY_COEX_REVISE ++ fgIsFixedChannel = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel); ++#else ++ fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); ++#endif ++ } else { ++ fgIsFixedChannel = FALSE; ++ } ++ ++#if DBG ++ if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) ++ prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0'; ++#endif ++ ++ DBGLOG(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, %pM Band=%d, channel=%d\n", ++ (UINT_32) prBSSDescList->u4NumElem, prConnSettings->aucSSID, ++ (prConnSettings->aucBSSID), eBand, ucChannel); ++ ++ /* 4 <1> The outer loop to search for a candidate. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ ++ /* TODO(Kevin): Update Minimum Channel Load Information here */ ++ ++ DBGLOG(SCN, TRACE, "SEARCH: [ %pM ], SSID:%s\n", ++ prBssDesc->aucBSSID, prBssDesc->aucSSID); ++ ++ /* 4 <2> Check PHY Type and attributes */ ++ /* 4 <2.1> Check Unsupported BSS PHY Type */ ++ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { ++ DBGLOG(SCN, TRACE, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", prBssDesc->ucPhyTypeSet); ++ continue; ++ } ++ /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */ ++ if (prBssDesc->fgIsUnknownBssBasicRate) ++ continue; ++ /* 4 <2.3> Check if fixed operation cases should be aware */ ++ if (fgIsFixedChannel == TRUE && (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) ++ continue; ++ /* 4 <2.4> Check if the channel is legal under regulatory domain */ ++ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) ++ continue; ++ /* 4 <2.5> Check if this BSS_DESC_T is stale */ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { ++ ++ BOOLEAN fgIsNeedToCheckTimeout = TRUE; ++ ++#if CFG_SUPPORT_ROAMING ++ P_ROAMING_INFO_T prRoamingFsmInfo; ++ ++ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); ++ if ((prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) || ++ (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) { ++ if (++prRoamingFsmInfo->RoamingEntryTimeoutSkipCount < ++ ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX) { ++ fgIsNeedToCheckTimeout = FALSE; ++ DBGLOG(SCN, INFO, "SEARCH: Romaing skip SCN_BSS_DESC_REMOVE_TIMEOUT_SEC\n"); ++ } ++ } ++#endif ++ ++ if (fgIsNeedToCheckTimeout == TRUE) { ++ DBGLOG(SCN, TRACE, "Ignore stale bss %pM\n", prBssDesc->aucBSSID); ++ continue; ++ } ++ } ++ /* 4 <3> Check if reach the excessive join retry limit */ ++ /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); ++ ++ if (prStaRec) { ++ /* NOTE(Kevin): ++ * The Status Code is the result of a Previous Connection Request, ++ * we use this as SCORE for choosing a proper ++ * candidate (Also used for compare see <6>) ++ * The Reason Code is an indication of the reason why AP reject us, ++ * we use this Code for "Reject" ++ * a SCAN result to become our candidate(Like a blacklist). ++ */ ++#if 0 /* TODO(Kevin): */ ++ if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) { ++ DBGLOG(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n", ++ prStaRec->u2ReasonCode); ++ continue; ++ } else ++#endif ++ if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ /* NOTE(Kevin): greedy association - after timeout, we'll still ++ * try to associate to the AP whose STATUS of conection attempt ++ * was not success. ++ * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for ++ * time bound. ++ */ ++ if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) || ++ (CHECK_FOR_TIMEOUT(rCurrentTime, ++ prStaRec->rLastJoinTime, ++ SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) { ++ ++ /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry ++ * JOIN_MAX_RETRY_FAILURE_COUNT times. ++ */ ++ if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) ++ prStaRec->ucJoinFailureCount = 0; ++ DBGLOG(SCN, INFO, ++ "SEARCH: Try to join BSS again,Status Code=%d (Curr=%u/Last Join=%u)\n", ++ prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime); ++ } else { ++ DBGLOG(SCN, INFO, ++ "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n", ++ JOIN_MAX_RETRY_FAILURE_COUNT); ++ continue; ++ } ++ ++ } ++ } ++ /* 4 <4> Check for various NETWORK conditions */ ++ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ ++ /* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */ ++ /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */ ++ if (((prConnSettings->eOPMode == NET_TYPE_INFRA) && ++ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) ++#if CFG_SUPPORT_ADHOC ++ || ((prConnSettings->eOPMode == NET_TYPE_IBSS ++ || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) ++ && (prBssDesc->eBSSType != BSS_TYPE_IBSS)) ++#endif ++ ) { ++ ++ DBGLOG(SCN, TRACE, "Cur OPMode %d, Ignore eBSSType = %d\n", ++ prConnSettings->eOPMode, prBssDesc->eBSSType); ++ continue; ++ } ++ /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */ ++ if ((prConnSettings->fgIsConnByBssidIssued) && ++ (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) { ++ ++ if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) { ++ ++ DBGLOG(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n"); ++ continue; ++ } ++ } ++#if CFG_SUPPORT_ADHOC ++ /* 4 <4.3> Check for AdHoc Mode */ ++ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ OS_SYSTIME rCurrentTime; ++ ++ /* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */ ++ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it ++ * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one. ++ * For BSS, if the old record was matched, however it won't be able to pass ++ * the Join Process later. ++ */ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) { ++ DBGLOG(SCN, LOUD, ++ "SEARCH: Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", ++ prBssDesc->aucBSSID); ++ continue; ++ } ++ /* 4 <4.3.2> Check Peer's capability */ ++ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { ++ ++ if (prPrimaryBssDesc) ++ DBGLOG(SCN, INFO, ++ "SEARCH: BSS DESC MAC: %pM, not supported AdHoc Mode.\n", ++ prPrimaryBssDesc->aucBSSID); ++ ++ continue; ++ } ++ /* 4 <4.3.3> Compare TSF */ ++ if (prBssInfo->fgIsBeaconActivated && ++ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) { ++ ++ DBGLOG(SCN, LOUD, ++ "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", prBssDesc->fgIsLargerTSF); ++ ++ if (!prBssDesc->fgIsLargerTSF) { ++ DBGLOG(SCN, INFO, ++ "SEARCH: Ignore BSS DESC MAC: [ %pM ], Smaller TSF\n", ++ prBssDesc->aucBSSID); ++ continue; ++ } ++ } ++ } ++#endif /* CFG_SUPPORT_ADHOC */ ++ ++ } ++#if 0 /* TODO(Kevin): For IBSS */ ++ /* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */ ++ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it ++ * create the IBSS, so we need to make sure we get the new one. ++ * For BSS, if the old record was matched, however it won't be able to pass ++ * the Join Process later. ++ */ ++ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { ++ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", ++ prBssDesc->aucBSSID); ++ continue; ++ } ++ } ++ ++ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) && ++ (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) { ++ OS_SYSTIME rCurrentTime; ++ ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, ++ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { ++ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", ++ (prBssDesc->aucBSSID)); ++ continue; ++ } ++ } ++ /* 4 <4B> Check for IBSS AdHoc Mode. */ ++ /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */ ++ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) { ++ /* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */ ++ if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) { ++ ++ DBGLOG(SCAN, TRACE, ++ "Ignore BSS DESC MAC: %pM, Capability not supported for AdHoc Mode.\n", ++ prPrimaryBssDesc->aucBSSID); ++ ++ continue; ++ } ++ /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */ ++ if (prAdapter->fgIsIBSSActive && ++ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) { ++ ++ if (!fgIsLocalTSFRead) { ++ NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf); ++ ++ DBGLOG(SCAN, TRACE, ++ "\n\nCurrent TSF : %08lx-%08lx\n\n", ++ rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart); ++ } ++ ++ if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) { ++ DBGLOG(SCAN, TRACE, ++ "Ignore BSS DESC MAC: [%pM], Current BSSID: [%pM].\n", ++ prPrimaryBssDesc->aucBSSID, prBssInfo->aucBSSID); ++ ++ DBGLOG(SCAN, TRACE, ++ "\n\nBSS's TSF : %08lx-%08lx\n\n", ++ prPrimaryBssDesc->u8TimeStamp.u.HighPart, ++ prPrimaryBssDesc->u8TimeStamp.u.LowPart); ++ ++ prPrimaryBssDesc->fgIsLargerTSF = FALSE; ++ continue; ++ } else { ++ prPrimaryBssDesc->fgIsLargerTSF = TRUE; ++ } ++ ++ } ++ } ++ /* 4 <5> Check the Encryption Status. */ ++ if (rsnPerformPolicySelection(prPrimaryBssDesc)) { ++ ++ if (prPrimaryBssDesc->ucEncLevel > 0) { ++ fgIsFindBestEncryptionLevel = TRUE; ++ ++ fgIsFindFirst = FALSE; ++ } ++ } else { ++ /* Can't pass the Encryption Status Check, get next one */ ++ continue; ++ } ++ ++ /* For RSN Pre-authentication, update the PMKID canidate list for ++ same SSID and encrypt status */ ++ /* Update PMKID candicate list. */ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { ++ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); ++ if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) ++ prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate(); ++ } ++#endif ++ ++ prPrimaryBssDesc = (P_BSS_DESC_T) NULL; ++ ++ /* 4 <6> Check current Connection Policy. */ ++ switch (prConnSettings->eConnectionPolicy) { ++ case CONNECT_BY_SSID_BEST_RSSI: ++ /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */ ++ if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) { ++ /* NOTE(Kevin): following if () statement means that ++ * If Target is hidden, then we won't connect when user specify SSID_ANY policy. ++ */ ++ if (prConnSettings->ucSSIDLen) { ++ prPrimaryBssDesc = prBssDesc; ++ fgIsFindBestRSSI = TRUE; ++ } ++ ++ } else if (EQUAL_SSID(prBssDesc->aucSSID, ++ prBssDesc->ucSSIDLen, ++ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { ++ prPrimaryBssDesc = prBssDesc; ++ fgIsFindBestRSSI = TRUE; ++ ++ DBGLOG(SCN, TRACE, "SEARCH: fgIsFindBestRSSI=TRUE, %d, prPrimaryBssDesc=[ %pM ]\n", ++ prBssDesc->ucRCPI, prPrimaryBssDesc->aucBSSID); ++ } ++ break; ++ ++ case CONNECT_BY_SSID_ANY: ++ /* NOTE(Kevin): In this policy, we don't know the desired ++ * SSID from user, so we should exclude the Hidden SSID from scan list. ++ * And because we refuse to connect to Hidden SSID node at the beginning, so ++ * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE, ++ * then the Connection Settings must be valid without doubt. ++ */ ++ if (!prBssDesc->fgIsHiddenSSID) { ++ prPrimaryBssDesc = prBssDesc; ++ fgIsFindFirst = TRUE; ++ } ++ break; ++ ++ case CONNECT_BY_BSSID: ++ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) ++ prPrimaryBssDesc = prBssDesc; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Primary Candidate was not found */ ++ if (prPrimaryBssDesc == NULL) ++ continue; ++ /* 4 <7> Check the Encryption Status. */ ++ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { ++#if CFG_SUPPORT_WAPI ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { ++ DBGLOG(SCN, TRACE, "SEARCH: fgWapiMode == 1\n"); ++ ++ if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { ++ fgIsFindFirst = TRUE; ++ } else { ++ /* Can't pass the Encryption Status Check, get next one */ ++ DBGLOG(SCN, TRACE, "SEARCH: WAPI cannot pass the Encryption Status Check!\n"); ++ continue; ++ } ++ } else ++#endif ++#if CFG_RSN_MIGRATION ++ if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { ++ if (prAisSpecBssInfo->fgCounterMeasure) { ++ DBGLOG(RSN, INFO, "Skip while at counter measure period!!!\n"); ++ continue; ++ } ++ ++ if (prPrimaryBssDesc->ucEncLevel > 0) { ++ fgIsFindBestEncryptionLevel = TRUE; ++ fgIsFindFirst = FALSE; ++ } ++#if 0 ++ /* Update PMKID candicate list. */ ++ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { ++ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); ++ if (prAisSpecBssInfo->u4PmkidCandicateCount) { ++ if (rsnCheckPmkidCandicate()) { ++ DBGLOG(RSN, WARN, ++ "Prepare a timer to indicate candidate %pM\n", ++ (prAisSpecBssInfo->arPmkidCache ++ [prAisSpecBssInfo->u4PmkidCacheCount]. ++ rBssidInfo.aucBssid))); ++ cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer); ++ cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer, ++ SEC_TO_MSEC ++ (WAIT_TIME_IND_PMKID_CANDICATE_SEC)); ++ } ++ } ++ } ++#endif ++ } else { ++ /* Can't pass the Encryption Status Check, get next one */ ++ continue; ++ } ++#endif ++ } else { ++ /* Todo:: P2P and BOW Policy Selection */ ++ } ++ ++ prPrimaryStaRec = prStaRec; ++ ++ /* 4 <8> Compare the Candidate and the Primary Scan Record. */ ++ if (!prCandidateBssDesc) { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ ++ /* 4 <8.1> Condition - Get the first matched one. */ ++ if (fgIsFindFirst) ++ break; ++ } else { ++#if 0 /* TODO(Kevin): For security(TBD) */ ++ /* 4 <6B> Condition - Choose the one with best Encryption Score. */ ++ if (fgIsFindBestEncryptionLevel) { ++ if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) { ++ ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++ ++ /* If reach here, that means they have the same Encryption Score. ++ */ ++ ++ /* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */ ++ /* For roaming, only compare the candidates other than current associated BSSID. */ ++ if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) { ++ if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) && ++ (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { ++ ++ DBGLOG(SCAN, TRACE, ++ "So far -BSS DESC MAC: %pM has nonzero Status Code = %d\n", ++ prCandidateBssDesc->aucBSSID, ++ prCandidateStaRec->u2StatusCode); ++ ++ if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) { ++ if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { ++ ++ /* Give opportunity to the one with smaller rLastJoinTime */ ++ if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime, ++ prPrimaryStaRec->rLastJoinTime)) { ++ continue; ++ } ++ /* We've connect to CANDIDATE recently, ++ * let us try PRIMARY now */ ++ else { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++ /* PRIMARY's u2StatusCode = 0 */ ++ else { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++ /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */ ++ else { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else { ++ if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) && ++ (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { ++ continue; ++ } ++ } ++ } ++#endif ++ ++ /* 4 <6D> Condition - Visible SSID win Hidden SSID. */ ++ if (prCandidateBssDesc->fgIsHiddenSSID) { ++ if (!prPrimaryBssDesc->fgIsHiddenSSID) { ++ prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */ ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else { ++ if (prPrimaryBssDesc->fgIsHiddenSSID) ++ continue; ++ } ++ ++ /* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */ ++ if (fgIsFindBestRSSI) { ++ /* TODO(Kevin): We shouldn't compare the actual value, we should ++ * allow some acceptable tolerance of some RSSI percentage here. ++ */ ++ DBGLOG(SCN, TRACE, ++ "Candidate [%pM]: RCPI = %d, joinFailCnt=%d, Primary [%pM]: RCPI = %d, joinFailCnt=%d\n", ++ prCandidateBssDesc->aucBSSID, ++ prCandidateBssDesc->ucRCPI, prCandidateBssDesc->ucJoinFailureCount, ++ prPrimaryBssDesc->aucBSSID, ++ prPrimaryBssDesc->ucRCPI, prPrimaryBssDesc->ucJoinFailureCount); ++ ++ ASSERT(!(prCandidateBssDesc->fgIsConnected && prPrimaryBssDesc->fgIsConnected)); ++ if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { ++ /* give a chance to do join if join fail before ++ * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC seconds ++ */ ++ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rJoinFailTime, ++ SEC_TO_SYSTIME(SCN_BSS_JOIN_FAIL_CNT_RESET_SEC))) { ++ prBssDesc->ucJoinFailureCount = SCN_BSS_JOIN_FAIL_THRESOLD - ++ SCN_BSS_JOIN_FAIL_RESET_STEP; ++ DBGLOG(SCN, INFO, ++ "decrease join fail count for Bss %pM to %u, timeout second %d\n", ++ prBssDesc->aucBSSID, prBssDesc->ucJoinFailureCount, ++ SCN_BSS_JOIN_FAIL_CNT_RESET_SEC); ++ } ++ } ++ ++ /* NOTE: To prevent SWING, ++ * we do roaming only if target AP has at least 5dBm larger than us. */ ++ if (prCandidateBssDesc->fgIsConnected) { ++ if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= ++ prPrimaryBssDesc->ucRCPI && ++ prPrimaryBssDesc->ucJoinFailureCount < SCN_BSS_JOIN_FAIL_THRESOLD) { ++ ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else if (prPrimaryBssDesc->fgIsConnected) { ++ if (prCandidateBssDesc->ucRCPI < ++ (prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) || ++ (prCandidateBssDesc->ucJoinFailureCount >= ++ SCN_BSS_JOIN_FAIL_THRESOLD)) { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } else if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) ++ continue; ++ else if (prCandidateBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD || ++ prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) { ++ prCandidateBssDesc = prPrimaryBssDesc; ++ prCandidateStaRec = prPrimaryStaRec; ++ continue; ++ } ++ } ++#if 0 ++ /* If reach here, that means they have the same Encryption Score, and ++ * both RSSI value are close too. ++ */ ++ /* 4 <6F> Seek the minimum Channel Load for less interference. */ ++ if (fgIsFindMinChannelLoad) { ++ /* Do nothing */ ++ /* TODO(Kevin): Check which one has minimum channel load in its channel */ ++ } ++#endif ++ } ++ } ++ ++ ++ if (prCandidateBssDesc != NULL) { ++ DBGLOG(SCN, INFO, ++ "SEARCH: Candidate BSS: %pM\n", prCandidateBssDesc->aucBSSID); ++ } ++ ++ return prCandidateBssDesc; ++ ++} /* end of scanSearchBssDescByPolicy() */ ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter) ++{ ++ P_LINK_T prBSSDescList = &prAdapter->rWifiVar.rScanInfo.rBSSDescList; ++ P_BSS_DESC_T prBssDesc = NULL; ++ P_AGPS_AP_LIST_T prAgpsApList; ++ P_AGPS_AP_INFO_T prAgpsInfo; ++ P_SCAN_INFO_T prScanInfo = &prAdapter->rWifiVar.rScanInfo; ++ UINT_8 ucIndex = 0; ++ ++ prAgpsApList = kalMemAlloc(sizeof(AGPS_AP_LIST_T), VIR_MEM_TYPE); ++ if (!prAgpsApList) ++ return; ++ ++ prAgpsInfo = &prAgpsApList->arApInfo[0]; ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime) ++ continue; ++ COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID); ++ prAgpsInfo->ePhyType = AGPS_PHY_G; ++ prAgpsInfo->u2Channel = prBssDesc->ucChannelNum; ++ prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); ++ prAgpsInfo++; ++ ucIndex++; ++ if (ucIndex == 32) ++ break; ++ } ++ prAgpsApList->ucNum = ucIndex; ++ GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime); ++ /* DBGLOG(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */ ++ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, (PUINT_8) prAgpsApList, sizeof(AGPS_AP_LIST_T)); ++ kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(AGPS_AP_LIST_T)); ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c +new file mode 100644 +index 000000000000..fac9f94428dd +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c +@@ -0,0 +1,2136 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#1 ++*/ ++ ++/*! \file "scan_fsm.c" ++ \brief This file defines the state transition function for SCAN FSM. ++ ++ The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN ++ behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 . ++*/ ++ ++/* ++** Log: scan_fsm.c ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 14 2011 yuche.tsai ++ * [WCXRP00001095] [Volunteer Patch][Driver] Always Scan before enable Hot-Spot. ++ * Fix bug when unregister P2P network.. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search ++ * for more than one SSID in a single scanning request ++ * free mailbox message afte parsing is completed. ++ * ++ * 07 18 2011 cp.wu ++ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search ++ * for more than one SSID in a single scanning request ++ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support ++ * as well as uProbeDelay in NDIS 6.x driver model ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning ++ * surpress klock warning with code path rewritten ++ * ++ * 03 18 2011 cm.chang ++ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command ++ * As CR title ++ * ++ * 02 18 2011 yuche.tsai ++ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame ++ * during search phase do not contain P2P wildcard SSID. ++ * Take P2P wildcard SSID into consideration. ++ * ++ * 01 27 2011 yuche.tsai ++ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. ++ * Fix scan channel extension issue when p2p module is not registered. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add interface for RLM to trigger OBSS-SCAN. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Fix bug for processing queued scan request. ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add a function for returning channel. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Update SCAN FSM for support P2P Device discovery scan. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Add option of channel extension while cancelling scan request. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 20 2010 cp.wu ++ * ++ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * due to FW/DRV won't be sync. precisely, some strict assertions should be eased. ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * SCN module is now able to handle multiple concurrent scanning requests ++ * ++ * 07 16 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * bugfix for SCN migration ++ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue ++ * 2) before AIS issues scan request, network(BSS) needs to be activated first ++ * 3) only invoke COPY_SSID when using specified SSID for scan ++ * ++ * 07 15 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * driver no longer generates probe request frames ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * pass band with channel number information as scan parameter ++ * ++ * 07 14 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * remove timer in DRV-SCN. ++ * ++ * 07 09 2010 cp.wu ++ * ++ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) ++ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass ++ * 3) implment DRV-SCN module, currently only accepts single scan request, ++ * other request will be directly dropped by returning BUSY ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * take use of RLM module for parsing/generating HT IEs for 11n capability ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * when returning to SCAN_IDLE state, send a correct message to source FSM. ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * comment out RLM APIs by CFG_RLM_MIGRATION. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add scan_fsm into building. ++ * ++ * 05 14 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine the order of Stop TX Queue and Switch Channel ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Update pause/resume/flush API to new Bitmap API ++ * ++ * 05 12 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Add Power Management - Legacy PS-POLL support. ++ * ++ * 03 18 2010 kevin.huang ++ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support ++ * Ignore the PROBE_DELAY state if the value of Probe Delay == 0 ++ * ++ * 03 10 2010 kevin.huang ++ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support ++ * Add Channel Manager for arbitration of JOIN and SCAN Req ++ * ++ * 02 23 2010 kevin.huang ++ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support ++ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb ++ * ++ * 01 08 2010 kevin.huang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * Add set RX Filter to receive BCN from different BSSID during SCAN ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Nov 25 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Remove flag of CFG_TEST_MGMT_FSM ++ * ++ * Nov 20 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Change parameter of scanSendProbeReqFrames() ++ * ++ * Nov 16 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Update scnFsmSteps() ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * Fix typo ++ * ++ * Nov 5 2009 mtk01461 ++ * [BORA00000018] Integrate WIFI part into BORA for the 1st time ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("SCAN_STATE_IDLE"), ++ (PUINT_8) DISP_STRING("SCAN_STATE_SCANNING"), ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++#define CURRENT_PSCN_VERSION 1 ++#define RSSI_MARGIN_DEFAULT 5 ++#define MAX_PERIOD 200000 ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ P_MSG_HDR_T prMsgHdr; ++ ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ do { ++ ++#if DBG ++ DBGLOG(SCN, STATE, "TRANSITION: [%s] -> [%s]\n", ++ apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState]); ++#else ++ DBGLOG(SCN, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", ++ DBG_SCN_IDX, prScanInfo->eCurrentState, eNextState); ++#endif ++ ++ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ ++ prScanInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++ ++ switch (prScanInfo->eCurrentState) { ++ case SCAN_STATE_IDLE: ++ /* check for pending scanning requests */ ++ if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { ++ /* load next message from pending list as scan parameters */ ++ LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T); ++ ++ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { ++ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); ++ } else { ++ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); ++ } ++ ++ /* switch to next state */ ++ eNextState = SCAN_STATE_SCANNING; ++ fgIsTransition = TRUE; ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ } ++ break; ++ ++ case SCAN_STATE_SCANNING: ++ if (prScanParam->fgIsScanV2 == FALSE) ++ scnSendScanReq(prAdapter); ++ else ++ scnSendScanReqV2(prAdapter); ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ ++ } ++ } while (fgIsTransition); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ_EXT_CH rCmdScanReq;*/ ++ P_CMD_SCAN_REQ_EXT_CH prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_EXT_CH), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) ++ return; ++ ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_EXT_CH)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ if (prScanParam->ucSSIDNum == 1) { ++ COPY_SSID(prCmdScanReq->aucSSID, ++ prCmdScanReq->ucSSIDLength, ++ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); ++ } ++ ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++ ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ_EXT_CH, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ else if (prCmdScanReq->ucSSIDLength > 32) ++ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_EXT_CH)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReq(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ rCmdScanReq;*/ ++ P_CMD_SCAN_REQ prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanParam->ucChannelListNum > 32) { ++ scnSendScanReqExtCh(prAdapter); ++ } else { ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) { ++ DBGLOG(SCN, INFO, "alloc CmdScanReq fail"); ++ return; ++ } ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ if (prScanParam->ucSSIDNum == 1) { ++ COPY_SSID(prCmdScanReq->aucSSID, ++ prCmdScanReq->ucSSIDLength, ++ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); ++ } ++ ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. ++ * (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++#if CFG_ENABLE_FAST_SCAN ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = CFG_FAST_SCAN_DWELL_TIME; ++#endif ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ else if (prCmdScanReq->ucSSIDLength > 32) ++ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ)); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ_V2 command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ_V2_EXT_CH rCmdScanReq;*/ ++ P_CMD_SCAN_REQ_V2_EXT_CH prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2_EXT_CH), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) ++ return; ++ ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ for (i = 0; i < prScanParam->ucSSIDNum; i++) { ++ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, ++ prCmdScanReq->arSSID[i].u4SsidLen, ++ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); ++ } ++ ++ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++ ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ_V2, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ_V2_EXT_CH, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Generate CMD_ID_SCAN_REQ_V2 command ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ /*CMD_SCAN_REQ_V2 rCmdScanReq;*/ ++ P_CMD_SCAN_REQ_V2 prCmdScanReq; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanParam->ucChannelListNum > 32) { ++ scnSendScanReqV2ExtCh(prAdapter); ++ } else { ++ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2), VIR_MEM_TYPE); ++ if (prCmdScanReq == NULL) { ++ DBGLOG(SCN, INFO, "alloc CmdScanReq v2 fail"); ++ return; ++ } ++ /* send command packet for scan */ ++ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2)); ++ ++ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; ++ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; ++ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; ++ ++ for (i = 0; i < prScanParam->ucSSIDNum; i++) { ++ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, ++ prCmdScanReq->arSSID[i].u4SsidLen, ++ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); ++ } ++ ++ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; ++ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; ++ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ /* P2P would use: ++ * 1. Specified Listen Channel of passive scan for LISTEN state. ++ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. ++ * (Target != NULL) ++ */ ++ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; ++ ++ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { ++ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; ++ ++ prCmdScanReq->arChannelList[i].ucChannelNum = ++ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; ++#endif ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdScanReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdScanReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_REQ_V2, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + prCmdScanReq->u2IELen, ++ (PUINT_8) prCmdScanReq, NULL, 0); ++ /* sanity check for some scan parameters */ ++ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) ++ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); ++ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) ++ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); ++ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && ++ prCmdScanReq->ucChannelListNum != 0) ++ kalSendAeeWarning("wlan", ++ "channel list is not NULL but channel type is not specified"); ++ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) ++ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); ++ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ ++ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); ++ ++ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2)); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ ++ ASSERT(prMsgHdr); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) { ++ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ ++ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { ++ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); ++ } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 ++ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 ++ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 ++ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { ++ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); ++ } else { ++ /* should not deliver to this function */ ++ ASSERT(0); ++ } ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ scnFsmSteps(prAdapter, SCAN_STATE_SCANNING); ++ } else { ++ LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) ++{ ++ P_MSG_SCN_SCAN_CANCEL prScanCancel; ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ CMD_SCAN_CANCEL rCmdScanCancel; ++ ++ ASSERT(prMsgHdr); ++ ++ prScanCancel = (P_MSG_SCN_SCAN_CANCEL) prMsgHdr; ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { ++ if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum && ++ prScanCancel->ucNetTypeIndex == (UINT_8) prScanParam->eNetTypeIndex) { ++ /* send cancel message to firmware domain */ ++ rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt; ++ else ++ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; ++#endif ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SCAN_CANCEL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8) &rCmdScanCancel, NULL, 0); ++ ++ /* generate scan-done event for caller */ ++ scnFsmGenerateScanDoneMsg(prAdapter, ++ prScanParam->ucSeqNum, ++ (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_CANCELLED); ++ ++ /* switch to next pending scan */ ++ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); ++ } else { ++ scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucNetTypeIndex); ++ } ++ } ++ ++ cnmMemFree(prAdapter, prMsgHdr); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Scan Message Parsing (Legacy) ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prScanReqMsg); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prScanParam->eScanType = prScanReqMsg->eScanType; ++ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; ++ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; ++ if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) { ++ prScanParam->ucSSIDNum = 1; ++ ++ COPY_SSID(prScanParam->aucSpecifiedSSID[0], ++ prScanParam->ucSpecifiedSSIDLen[0], prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength); ++ ++ /* reset SSID length to zero for rest array entries */ ++ for (i = 1; i < SCN_SSID_MAX_NUM; i++) ++ prScanParam->ucSpecifiedSSIDLen[i] = 0; ++ } else { ++ prScanParam->ucSSIDNum = 0; ++ ++ for (i = 0; i < SCN_SSID_MAX_NUM; i++) ++ prScanParam->ucSpecifiedSSIDLen[i] = 0; ++ } ++ ++ prScanParam->u2ProbeDelayTime = 0; ++ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) ++ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; ++ else ++ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; ++ ++ kalMemCopy(prScanParam->arChnlInfoList, ++ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); ++ } ++ ++ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) ++ prScanParam->u2IELen = prScanReqMsg->u2IELen; ++ else ++ prScanParam->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; ++#endif ++ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; ++ ++ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) ++ prScanParam->fgIsObssScan = TRUE; ++ else ++ prScanParam->fgIsObssScan = FALSE; ++ ++ prScanParam->fgIsScanV2 = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Scan Message Parsing - V2 with multiple SSID support ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ASSERT(prScanReqMsg); ++ ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ prScanParam->eScanType = prScanReqMsg->eScanType; ++ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; ++ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; ++ prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum; ++ ++ for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) { ++ COPY_SSID(prScanParam->aucSpecifiedSSID[i], ++ prScanParam->ucSpecifiedSSIDLen[i], ++ prScanReqMsg->prSsid[i].aucSsid, (UINT_8) prScanReqMsg->prSsid[i].u4SsidLen); ++ } ++ ++ prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay; ++ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { ++ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) ++ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; ++ else ++ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; ++ ++ kalMemCopy(prScanParam->arChnlInfoList, ++ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); ++ } ++ ++ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) ++ prScanParam->u2IELen = prScanReqMsg->u2IELen; ++ else ++ prScanParam->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) ++ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; ++#endif ++ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; ++ ++ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) ++ prScanParam->fgIsObssScan = TRUE; ++ else ++ prScanParam->fgIsObssScan = FALSE; ++ ++ prScanParam->fgIsScanV2 = TRUE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Remove pending scan request ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL; ++ P_LINK_ENTRY_T prRemoveLinkEntry = NULL; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ /* traverse through rPendingMsgList for removal */ ++ LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr, ++ prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), rLinkEntry, MSG_HDR_T) { ++ if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ ++ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ ++ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ ++ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { ++ P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) prPendingMsgHdr; ++ ++ if (ucSeqNum == prScanReqMsg->ucSeqNum && ucNetTypeIndex == prScanReqMsg->ucNetTypeIndex) { ++ prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry); ++ prRemoveMsgHdr = prPendingMsgHdr; ++ } ++ } else if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 ++ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 ++ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 ++ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { ++ P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2) prPendingMsgHdr; ++ ++ if (ucSeqNum == prScanReqMsgV2->ucSeqNum && ucNetTypeIndex == prScanReqMsgV2->ucNetTypeIndex) { ++ prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry); ++ prRemoveMsgHdr = prPendingMsgHdr; ++ } ++ } ++ ++ if (prRemoveLinkEntry) { ++ /* generate scan-done event for caller */ ++ scnFsmGenerateScanDoneMsg(prAdapter, ucSeqNum, ucNetTypeIndex, SCAN_STATUS_CANCELLED); ++ ++ /* remove from pending list */ ++ LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry); ++ cnmMemFree(prAdapter, prRemoveMsgHdr); ++ ++ break; ++ } ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ /* buffer empty channel information */ ++ if (prScanParam->eScanChannel == SCAN_CHANNEL_FULL || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) { ++ if (prScanDone->ucSparseChannelValid) { ++ prScanInfo->fgIsSparseChannelValid = TRUE; ++ prScanInfo->rSparseChannel.eBand = (ENUM_BAND_T) prScanDone->rSparseChannel.ucBand; ++ prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum; ++ } else { ++ prScanInfo->fgIsSparseChannelValid = FALSE; ++ } ++ } ++ ++ if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING && prScanDone->ucSeqNum == prScanParam->ucSeqNum) { ++ /* generate scan-done event for caller */ ++ scnFsmGenerateScanDoneMsg(prAdapter, ++ prScanParam->ucSeqNum, (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_DONE); ++ ++ /* switch to next pending scan */ ++ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); ++ } else { ++ DBGLOG(SCN, WARN, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", ++ prScanDone->ucSeqNum, prScanInfo->eCurrentState); ++ } ++ ++} /* end of scnEventScanDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_SCAN_PARAM_T prScanParam; ++ P_MSG_SCN_SCAN_DONE prScanDoneMsg; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prScanParam = &prScanInfo->rScanParam; ++ ++ DBGLOG(SCN, INFO, "Rcv Scan Done, NetIdx %d, Obss %d, Status %d, Seq %d\n", ++ ucNetTypeIndex, prScanParam->fgIsObssScan, eScanStatus, ucSeqNum); ++ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE)); ++ if (!prScanDoneMsg) { ++ ASSERT(0); /* Can't indicate SCAN FSM Complete */ ++ return; ++ } ++ ++ if (prScanParam->fgIsObssScan == TRUE) { ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE; ++ } else { ++ switch ((ENUM_NETWORK_TYPE_INDEX_T) ucNetTypeIndex) { ++ case NETWORK_TYPE_AIS_INDEX: ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE; ++ break; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ case NETWORK_TYPE_P2P_INDEX: ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE; ++ break; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ case NETWORK_TYPE_BOW_INDEX: ++ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE; ++ break; ++#endif ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ } ++ ++ prScanDoneMsg->ucSeqNum = ucSeqNum; ++ prScanDoneMsg->ucNetTypeIndex = ucNetTypeIndex; ++ prScanDoneMsg->eScanStatus = eScanStatus; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanDoneMsg, MSG_SEND_METHOD_BUF); ++ ++} /* end of scnFsmGenerateScanDoneMsg() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Query for most sparse channel ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prScanInfo->fgIsSparseChannelValid == TRUE) { ++ if (prSparseBand) ++ *prSparseBand = prScanInfo->rSparseChannel.eBand; ++ ++ if (pucSparseChannel) ++ *pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum; ++ ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Event handler for NLO done event ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_NLO_PARAM_T prNloParam; ++ P_SCAN_PARAM_T prScanParam; ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prNloParam = &prScanInfo->rNloParam; ++ prScanParam = &prNloParam->rScanParam; ++ ++ if (prScanInfo->fgNloScanning == TRUE) { ++ DBGLOG(SCN, INFO, "scnEventNloDone Current State = %d\n", prScanInfo->eCurrentState); ++ ++ kalSchedScanResults(prAdapter->prGlueInfo); ++ ++ if (prNloParam->fgStopAfterIndication == TRUE) ++ prScanInfo->fgNloScanning = FALSE; ++ ++ kalMemZero(&prNloParam->aprPendingBssDescToInd[0], ++ CFG_SCAN_SSID_MATCH_MAX_NUM * sizeof(P_BSS_DESC_T)); ++ } else { ++ DBGLOG(SCN, INFO, "Unexpected NLO-DONE event\n"); ++ } ++ ++} ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for starting scheduled scan ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucSsidNum, ++ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_NLO_PARAM_T prNloParam; ++ P_SCAN_PARAM_T prScanParam; ++ P_CMD_NLO_REQ prCmdNloReq; ++ UINT_32 i, j; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prNloParam = &prScanInfo->rNloParam; ++ prScanParam = &prNloParam->rScanParam; ++ ++ if (prScanInfo->fgNloScanning) { ++ DBGLOG(SCN, INFO, "prScanInfo->fgNloScanning == TRUE already scanning\n"); ++ return TRUE; ++ } ++ ++ prScanInfo->fgNloScanning = TRUE; ++ ++ /* 1. load parameters */ ++ prScanParam->ucSeqNum++; ++ /* prScanParam->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex; */ ++ ++ prNloParam->fgStopAfterIndication = TRUE; ++ prNloParam->ucFastScanIteration = 0; ++ prNloParam->u2FastScanPeriod = u2Interval; ++ prNloParam->u2SlowScanPeriod = u2Interval; ++ ++ if (prScanParam->ucSSIDNum > CFG_SCAN_SSID_MAX_NUM) ++ prScanParam->ucSSIDNum = CFG_SCAN_SSID_MAX_NUM; ++ else ++ prScanParam->ucSSIDNum = ucSsidNum; ++ ++ if (prNloParam->ucMatchSSIDNum > CFG_SCAN_SSID_MATCH_MAX_NUM) ++ prNloParam->ucMatchSSIDNum = CFG_SCAN_SSID_MATCH_MAX_NUM; ++ else ++ prNloParam->ucMatchSSIDNum = ucSsidNum; ++ ++ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { ++ if (i < CFG_SCAN_SSID_MAX_NUM) { ++ COPY_SSID(prScanParam->aucSpecifiedSSID[i], ++ prScanParam->ucSpecifiedSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); ++ } ++ ++ COPY_SSID(prNloParam->aucMatchSSID[i], ++ prNloParam->ucMatchSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); ++ ++ prNloParam->aucCipherAlgo[i] = 0; ++ prNloParam->au2AuthAlgo[i] = 0; ++ ++ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) ++ prNloParam->aucChannelHint[i][j] = 0; ++ } ++ ++ /* 2. prepare command for sending */ ++ prCmdNloReq = (P_CMD_NLO_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_NLO_REQ) + prScanParam->u2IELen); ++ ++ if (!prCmdNloReq) { ++ ASSERT(0); /* Can't initiate NLO operation */ ++ return FALSE; ++ } ++ ++ /* 3. send command packet for NLO operation */ ++ kalMemZero(prCmdNloReq, sizeof(CMD_NLO_REQ)); ++ ++ prCmdNloReq->ucSeqNum = prScanParam->ucSeqNum; ++ /* prCmdNloReq->ucBssIndex = prScanParam->ucBssIndex; */ ++ ++ prCmdNloReq->ucNetworkType = prScanParam->eNetTypeIndex; ++ prCmdNloReq->ucScanType = (UINT_8) prScanParam->eScanType; ++ ++ prCmdNloReq->fgStopAfterIndication = prNloParam->fgStopAfterIndication; ++ prCmdNloReq->ucFastScanIteration = prNloParam->ucFastScanIteration; ++ prCmdNloReq->u2FastScanPeriod = prNloParam->u2FastScanPeriod; ++ prCmdNloReq->u2SlowScanPeriod = prNloParam->u2SlowScanPeriod; ++ prCmdNloReq->ucEntryNum = prNloParam->ucMatchSSIDNum; ++ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { ++ COPY_SSID(prCmdNloReq->arNetworkList[i].aucSSID, ++ prCmdNloReq->arNetworkList[i].ucSSIDLength, ++ prNloParam->aucMatchSSID[i], prNloParam->ucMatchSSIDLen[i]); ++ ++ prCmdNloReq->arNetworkList[i].ucCipherAlgo = prNloParam->aucCipherAlgo[i]; ++ prCmdNloReq->arNetworkList[i].u2AuthAlgo = prNloParam->au2AuthAlgo[i]; ++ ++ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) ++ prCmdNloReq->arNetworkList[i].ucNumChannelHint[j] = prNloParam->aucChannelHint[i][j]; ++ } ++ ++ if (prScanParam->u2IELen <= MAX_IE_LENGTH) ++ prCmdNloReq->u2IELen = prScanParam->u2IELen; ++ else ++ prCmdNloReq->u2IELen = MAX_IE_LENGTH; ++ ++ if (prScanParam->u2IELen) ++ kalMemCopy(prCmdNloReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdNloReq->u2IELen); ++#if !CFG_SUPPORT_GSCN ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NLO_REQ, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetCommon, ++ nicOidCmdTimeoutCommon, ++ sizeof(CMD_NLO_REQ) + prCmdNloReq->u2IELen, (PUINT_8) prCmdNloReq, NULL, 0); ++ ++#else ++ scnPSCNFsm(prAdapter, PSCN_RESET, prCmdNloReq, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE); ++#endif ++ cnmMemFree(prAdapter, (PVOID) prCmdNloReq); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for stopping scheduled scan ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ P_NLO_PARAM_T prNloParam; ++ P_SCAN_PARAM_T prScanParam; ++ CMD_NLO_CANCEL rCmdNloCancel; ++ ++ ASSERT(prAdapter); ++ ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prNloParam = &prScanInfo->rNloParam; ++ prScanParam = &prNloParam->rScanParam; ++ ++ /* send cancel message to firmware domain */ ++ rCmdNloCancel.ucSeqNum = prScanParam->ucSeqNum; ++ ++#if !CFG_SUPPORT_GSCN ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_NLO_CANCEL, ++ TRUE, ++ FALSE, ++ TRUE, ++ nicCmdEventSetStopSchedScan, ++ nicOidCmdTimeoutCommon, sizeof(CMD_NLO_CANCEL), (PUINT_8)(&rCmdNloCancel), NULL, 0); ++#else ++ ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE); ++#endif ++ ++ prScanInfo->fgNloScanning = FALSE; ++ ++ return TRUE; ++} ++ ++#if CFG_SUPPORT_GSCN ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set PSCN action ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct) ++{ ++ CMD_SET_PSCAN_ENABLE rCmdPscnAction; ++ P_SCAN_INFO_T prScanInfo; ++ ++ DBGLOG(SCN, TRACE, "scnFsmPSCNAction Act = %d\n", ucPscanAct); ++ ++ rCmdPscnAction.ucPscanAct = ucPscanAct; ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (ucPscanAct == DISABLE) ++ prScanInfo->fgPscnOnnning = FALSE; ++ if (ucPscanAct == ENABLE) ++ prScanInfo->fgPscnOnnning = TRUE; ++ ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_ENABLE, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_ENABLE), (PUINT_8) &rCmdPscnAction, NULL, 0); ++ ++ DBGLOG(SCN, INFO, "scnFsmPSCNAction Act = %d is Set to FW\n", ucPscanAct); ++ return TRUE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set PSCN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ UINT_8 i, j; ++ ++ i = 0; ++ j = 0; ++ ++ ASSERT(prAdapter); ++ /*prCmdPscnParam->u4BasePeriod = prCmdPscnParam->u4BasePeriod;*/ ++#if 0 ++ DBGLOG(SCN, TRACE, ++ "rCmdPscnParam: Period[%u],NumCache[%u],Threshold[%u],NumBkts[%u],fgGSCN[%d] fgNLO[%d] fgBatch[%d]\n", ++ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, ++ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, prCmdPscnParam->fgBatchScnEnable)); ++ ++ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { ++ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); ++ DBGLOG(SCN, TRACE, ++ "band[%u], Index[%u] NumChannels[%u], ucBktFreqMultiple[%u] Flag[%u]\n", ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); ++ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) ++ DBGLOG(SCN, TRACE, ++ " %d, ", prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); ++ DBGLOG(SCN, TRACE, "\n"); ++ } ++#endif ++ ++ if (1 /*prScanInfo->fgPscnOnnning == FALSE */) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCAN_PARAM, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_PARAM), (PUINT_8) prCmdPscnParam, NULL, 0); ++ ++ DBGLOG(SCN, TRACE, "CMD_ID_SET_PSCAN_PARAM is set to FW !!!!!!!!!!\n"); ++ return TRUE; ++ } ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set hotlist ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID prCmdPscnAddHotlist) ++{ ++ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ memcpy(&rCmdPscnAddHotlist.aucMacAddr, &(prCmdPscnAddHotlist->aucMacAddr), sizeof(MAC_ADDR_LEN)); ++ ++ /* rCmdPscnAddHotlist.aucMacAddr = prCmdPscnAddHotlist->aucMacAddr; */ ++ rCmdPscnAddHotlist.ucFlags = prCmdPscnAddHotlist->ucFlags; ++ ++ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_SET_PSCAN_ADD_HOTLIST_BSSID), (PUINT_8) &rCmdPscnAddHotlist, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_ADD_SW_BSSID ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId) ++{ ++ CMD_SET_PSCAN_ADD_SWC_BSSID rCmdPscnAddSWCBssId; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ memcpy(&rCmdPscnAddSWCBssId.aucMacAddr, &(prCmdPscnAddSWCBssId->aucMacAddr), sizeof(MAC_ADDR_LEN)); ++ ++ /* rCmdPscnAddSWCBssId.aucMacAddr = prCmdPscnAddSWCBssId->aucMacAddr; */ ++ rCmdPscnAddSWCBssId.i4RssiHighThreshold = prCmdPscnAddSWCBssId->i4RssiHighThreshold; ++ rCmdPscnAddSWCBssId.i4RssiLowThreshold = prCmdPscnAddSWCBssId->i4RssiLowThreshold; ++ ++ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_ADD_SW_BSSID, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_SET_PSCAN_ADD_SWC_BSSID), (PUINT_8) &rCmdPscnAddSWCBssId, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr) ++{ ++ CMD_SET_PSCAN_MAC_ADDR rCmdPscnSetMacAddr; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ /* rCmdPscnSetMacAddr.aucMacAddr = prCmdPscnSetMacAddr->aucMacAddr; */ ++ memcpy(&rCmdPscnSetMacAddr.aucMacAddr, &(prCmdPscnSetMacAddr->aucMacAddr), sizeof(MAC_ADDR_LEN)); ++ ++ rCmdPscnSetMacAddr.ucFlags = prCmdPscnSetMacAddr->ucFlags; ++ rCmdPscnSetMacAddr.ucVersion = prCmdPscnSetMacAddr->ucVersion; ++ ++ if (1 /* (prScanInfo->fgPscnOnnning == TRUE */) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PSCN_MAC_ADDR, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_SET_PSCAN_MAC_ADDR), (PUINT_8) &rCmdPscnSetMacAddr, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set GSCN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam) ++{ ++ /*CMD_GSCN_REQ_T rCmdGscnParam;*/ ++ P_CMD_GSCN_REQ_T rCmdGscnParamp; ++ P_SCAN_INFO_T prScanInfo; ++ UINT_8 ucChannelBuckIndex; ++ UINT_8 i; ++ ++ ASSERT(prAdapter); ++ rCmdGscnParamp = kalMemAlloc(sizeof(CMD_GSCN_REQ_T), VIR_MEM_TYPE); ++ if (rCmdGscnParamp == NULL) { ++ DBGLOG(SCN, INFO, "alloc CmdGscnParam fail\n"); ++ return TRUE; ++ } ++ kalMemZero(rCmdGscnParamp, sizeof(CMD_GSCN_REQ_T)); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ rCmdGscnParamp->u4NumBuckets = prCmdGscnParam->num_buckets; ++ rCmdGscnParamp->u4BasePeriod = prCmdGscnParam->base_period; ++ DBGLOG(SCN, INFO, ++ "u4BasePeriod[%d], u4NumBuckets[%d]\n", rCmdGscnParamp->u4BasePeriod, rCmdGscnParamp->u4NumBuckets); ++ for (ucChannelBuckIndex = 0; ucChannelBuckIndex < prCmdGscnParam->num_buckets; ucChannelBuckIndex++) { ++ DBGLOG(SCN, TRACE, "assign channels to bucket[%d]\n", ucChannelBuckIndex); ++ for (i = 0; i < prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; i++) { ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel = ++ (UINT_8) nicFreq2ChannelNum(prCmdGscnParam->buckets[ucChannelBuckIndex]. ++ channels[i].channel * 1000); ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive = ++ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].passive; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs = ++ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].dwellTimeMs; ++ ++ DBGLOG(SCN, TRACE, "[ucChannel %d, ucPassive %d, u4DwellTimeMs %d\n", ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel, ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive, ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs); ++ ++ } ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].u2BucketIndex = ++ (UINT_16) prCmdGscnParam->buckets[ucChannelBuckIndex].bucket; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].eBand = ++ prCmdGscnParam->buckets[ucChannelBuckIndex].band; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucBucketFreqMultiple = ++ (prCmdGscnParam->buckets[ucChannelBuckIndex].period / prCmdGscnParam->base_period); ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucNumChannels = ++ prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; ++ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucReportFlag = ++ prCmdGscnParam->buckets[ucChannelBuckIndex].report_events; ++ ++ /* printk("\n"); */ ++ } ++ ++ DBGLOG(SCN, INFO, "scnSetGSCNParam ---> scnPSCNFsm PSCN_RESET\n"); ++ ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, rCmdGscnParamp, NULL, FALSE, FALSE, FALSE, FALSE); ++ kalMemFree(rCmdGscnParamp, VIR_MEM_TYPE, sizeof(CMD_GSCN_REQ_T)); ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine PNO Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnSubCombineNLOtoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_NLO_REQ prNewCmdNloReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prNewCmdNloReq) { ++ prCmdPscnParam->fgNLOScnEnable = TRUE; ++ memcpy(&prCmdPscnParam->rCmdNloReq, prNewCmdNloReq, sizeof(CMD_NLO_REQ)); ++ } else if (prScanInfo->prPscnParam->fgNLOScnEnable) { ++ memcpy(&prCmdPscnParam->rCmdNloReq, &prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); ++ } else ++ prCmdPscnParam->fgNLOScnEnable = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine Batcht Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnSubCombineBatchSCNtoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ if (prNewCmdBatchReq) { ++ prCmdPscnParam->fgBatchScnEnable = TRUE; ++ memcpy(&prCmdPscnParam->rCmdBatchReq, prNewCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); ++ } else if (prScanInfo->prPscnParam->fgBatchScnEnable) { ++ memcpy(&prCmdPscnParam->rCmdBatchReq, &prScanInfo->prPscnParam->rCurrentCmdBatchReq, ++ sizeof(CMD_BATCH_REQ_T)); ++ } else ++ prCmdPscnParam->fgBatchScnEnable = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine GSCN Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnSubCombineGSCNtoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ UINT_32 ucPeriodMin = MAX_PERIOD; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prCmdPscnParam->fgGScnEnable = FALSE; ++ ++ DBGLOG(SCN, TRACE, "scnSubCombineGSCNtoPSCN fgGScnParamSet %d fgGScnConfigSet %d\n", ++ prScanInfo->fgGScnParamSet, prScanInfo->fgGScnConfigSet); ++ ++ if (prNewCmdGscnReq) { ++ DBGLOG(SCN, INFO, "setup prNewCmdGscnReq\n"); ++ prScanInfo->fgGScnParamSet = TRUE; ++ memcpy(&prCmdPscnParam->rCmdGscnReq, prNewCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); ++ if (ucPeriodMin > prNewCmdGscnReq->u4BasePeriod) ++ prCmdPscnParam->u4BasePeriod = prNewCmdGscnReq->u4BasePeriod; ++ } else if (prScanInfo->fgGScnParamSet) { ++ DBGLOG(SCN, INFO, "no new prNewCmdGscnReq but there is a old one\n"); ++ memcpy(&prCmdPscnParam->rCmdGscnReq, &prScanInfo->prPscnParam->rCurrentCmdGscnReq, ++ sizeof(CMD_GSCN_REQ_T)); ++ prCmdPscnParam->u4BasePeriod = prScanInfo->prPscnParam->u4BasePeriod; ++ } else ++ prScanInfo->fgGScnParamSet = FALSE; ++ ++ if (prNewCmdGscnConfig) { ++ DBGLOG(SCN, INFO, "set up prNewCmdGscnConfig\n"); ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prScanInfo->fgGScnConfigSet = TRUE; ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = prNewCmdGscnConfig->u4BufferThreshold; ++ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = (UINT_8) prNewCmdGscnConfig->u4NumScnToCache; ++ } else if (prScanInfo->fgGScnConfigSet) { ++ DBGLOG(SCN, INFO, "no new prNewCmdGscnConfig but there is a old one\n"); ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = ++ prScanInfo->prPscnParam->rCurrentCmdGscnReq.u4BufferThreshold; ++ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = ++ (UINT_8) prScanInfo->prPscnParam->rCurrentCmdGscnReq.ucNumScnToCache; ++ } else ++ prScanInfo->fgGScnConfigSet = FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine GSCN Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID ++scnRemoveFromPSCN(IN P_ADAPTER_T prAdapter, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, ++ IN BOOLEAN fgRemoveGSCNfromPSCN, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ UINT_8 ucPscanAct = DISABLE; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ { ++ DBGLOG(SCN, INFO, "remove NLO or Batch or GSCN from PSCN--->NLO=%d, BSN=%d, GSN=%d\n", ++ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); ++ ++ if (fgRemoveNLOfromPSCN) { ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->fgNLOScnEnable = FALSE; ++ kalMemZero(&prCmdPscnParam->rCmdNloReq, sizeof(CMD_NLO_REQ)); ++ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); ++ } ++ if (fgRemoveBatchSCNfromPSCN) { ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->fgBatchScnEnable = FALSE; ++ kalMemZero(&prCmdPscnParam->rCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); ++ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); ++ } ++ if (fgRemoveGSCNfromPSCN) { ++ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ prCmdPscnParam->fgGScnEnable = FALSE; ++ prScanInfo->fgGScnParamSet = FALSE; ++ kalMemZero(&prCmdPscnParam->rCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); ++ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); ++ } ++ ++ if (!fgRemoveNLOfromPSCN && !fgRemoveBatchSCNfromPSCN && !fgRemoveGSCNfromPSCN) { ++ /* prCmdPscnParam->fgIsPeriodicallyScn = FALSE; */ ++ prScanInfo->fgPscnOnnning = FALSE; ++ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); ++ scnFsmPSCNAction(prAdapter, ucPscanAct); ++ } else { ++ /* prCmdPscnParam->fgIsPeriodicallyScn = TRUE; */ ++ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); ++ DBGLOG(SCN, INFO, " disable NLO or GSCN or Batch but fgIsPeriodicallyScn = TRUE <-----\n"); ++ } ++ } ++ ++} ++ ++#if 1 ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Combine GSCN , Batch, PNO Scan params into PSCAN param ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++BOOLEAN ++scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, ++ IN P_CMD_NLO_REQ prNewCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ /* CMD_SET_PSCAN_PARAM rCmdPscnParam; */ ++ P_CMD_SET_PSCAN_PARAM prCmdPscnParam; ++ /* UINT_8 i, j = 0; */ ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ prCmdPscnParam = (P_CMD_SET_PSCAN_PARAM) kalMemAlloc(sizeof(CMD_SET_PSCAN_PARAM), VIR_MEM_TYPE); ++ if (!prCmdPscnParam) { ++ DBGLOG(SCN, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); ++ return -ENOMEM; ++ } ++ kalMemZero(prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ ++ prCmdPscnParam->ucVersion = CURRENT_PSCN_VERSION; ++ ++ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { ++ scnRemoveFromPSCN(prAdapter, ++ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN, prCmdPscnParam); ++ } else { ++ DBGLOG(SCN, INFO, "combine GSCN or Batch or NLO to PSCN --->\n"); ++ ++ scnSubCombineNLOtoPSCN(prAdapter, prNewCmdNloReq, prCmdPscnParam); ++ scnSubCombineBatchSCNtoPSCN(prAdapter, prNewCmdBatchReq, prCmdPscnParam); ++ if (prNewCmdGscnReq) ++ scnSubCombineGSCNtoPSCN(prAdapter, prNewCmdGscnReq, NULL, prCmdPscnParam); ++ if (prNewCmdGscnConfig) ++ scnSubCombineGSCNtoPSCN(prAdapter, NULL, prNewCmdGscnConfig, prCmdPscnParam); ++ /* scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); */ ++ ++#if 0 ++ DBGLOG(SCN, TRACE, "combine GSCN or Batch or NLO to PSCN <--- rCmdPscnParam\n"); ++ DBGLOG(SCN, TRACE, ++ "Period[%u], NumCache[%u], Threshold[%u], NumBuckets[%u],GSCNEn[%d] NLOEn[%d] BatchEn[%d]\n", ++ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, ++ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, ++ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, ++ prCmdPscnParam->fgBatchScnEnable)); ++ ++ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { ++ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); ++ DBGLOG(SCN, TRACE, ++ "band[%u], ChnBkt[%u] NumChns[%u], BktFreqMltpl[%u] Flag[%u]\n", ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); ++ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) { ++ DBGLOG(SCN, TRACE, " %d, ", ++ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); ++ } ++ DBGLOG(SCN, TRACE, "\n"); ++ } ++#endif ++ } ++ ++ memcpy(prScanInfo->prPscnParam, prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); ++ kalMemFree(prCmdPscnParam, VIR_MEM_TYPE, sizeof(CMD_SET_PSCAN_PARAM)); ++ return TRUE; ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig) ++{ ++ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; ++ ++ ASSERT(prAdapter); ++ memcpy(&rCmdGscnScnConfig, prCmdGscnScnConfig, sizeof(CMD_GSCN_SCN_COFIG_T)); ++ DBGLOG(SCN, TRACE, "rCmdGscnScnConfig: u4BufferThreshold; [%d] ucNumApPerScn [%d] ucNumScnToCache [%d]\n", ++ rCmdGscnScnConfig.u4BufferThreshold, ++ rCmdGscnScnConfig.ucNumApPerScn, ++ rCmdGscnScnConfig.u4NumScnToCache); ++ ++ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, &rCmdGscnScnConfig, FALSE, FALSE, FALSE, FALSE); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR ++* ++* \param[in] ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd) ++{ ++ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; ++ P_SCAN_INFO_T prScanInfo; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultCmd, sizeof(CMD_GET_GSCAN_RESULT_T)); ++ DBGLOG(SCN, INFO, "rGetGscnScnResultCmd: ucGetNum [%d] fgFlush [%d]\n", ++ rGetGscnScnResultCmd.u4Num, rGetGscnScnResultCmd.ucFlush); ++ ++ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_GET_GSCN_SCN_RESULT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_GET_GSCAN_RESULT_T), (PUINT_8) &rGetGscnScnResultCmd, NULL, 0); ++ return TRUE; ++ } ++ /* debug msg, No PSCN, Sched SCAN GSCN ongoing ??? */ ++ return FALSE; ++ ++} ++ ++VOID ++scnPSCNFsm(IN P_ADAPTER_T prAdapter, ++ ENUM_PSCAN_STATE_T eNextPSCNState, ++ IN P_CMD_NLO_REQ prCmdNloReq, ++ IN P_CMD_BATCH_REQ_T prCmdBatchReq, ++ IN P_CMD_GSCN_REQ_T prCmdGscnReq, ++ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, ++ IN BOOLEAN fgRemoveNLOfromPSCN, ++ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN) ++{ ++ P_SCAN_INFO_T prScanInfo; ++ BOOLEAN fgTransitionState = FALSE; ++ ++ ASSERT(prAdapter); ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ ++ do { ++ fgTransitionState = FALSE; ++ ++ DBGLOG(SCN, STATE, "eCurrentPSCNState=%d, eNextPSCNState=%d\n", ++ prScanInfo->eCurrentPSCNState, eNextPSCNState); ++ ++ switch (prScanInfo->eCurrentPSCNState) { ++ case PSCN_IDLE: ++ if (eNextPSCNState == PSCN_RESET) { ++ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { ++ DBGLOG(SCN, TRACE, "Unexpected remove NLO/BATCH/GSCN request\n"); ++ eNextPSCNState = PSCN_IDLE; ++ break; ++ } ++ ++ if (prCmdNloReq || prCmdBatchReq) { ++ DBGLOG(SCN, TRACE, "PSCN_IDLE->PSCN_RESET,.... scnFsmPSCNActionDISABLE\n"); ++ /*TBD check PSCAN is ongoing */ ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ break; ++ } ++ ++ } else if (eNextPSCNState == PSCN_SCANNING) { ++ if (fgEnableGSCN) { ++ if (prScanInfo->fgPscnOnnning) ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ if (prScanInfo->fgGScnParamSet) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_IDLE->PSCN_SCANNING,.... scnFsmPSCNActionENABLE\n"); ++ prScanInfo->prPscnParam->fgGScnEnable = TRUE; ++ scnFsmPSCNSetParam(prAdapter, ++ (P_CMD_SET_PSCAN_PARAM)prScanInfo->prPscnParam); ++ scnFsmPSCNAction(prAdapter, ENABLE); ++ eNextPSCNState = PSCN_SCANNING; ++ } ++ } ++ } ++ break; ++ ++ case PSCN_RESET: ++ scnCombineParamsIntoPSCN(prAdapter, ++ prCmdNloReq, ++ prCmdBatchReq, ++ prCmdGscnReq, ++ prNewCmdGscnConfig, ++ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); ++ ++ if (!prScanInfo->prPscnParam->fgNLOScnEnable && !prScanInfo->prPscnParam->fgBatchScnEnable ++ && !prScanInfo->prPscnParam->fgGScnEnable) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_RESET->PSCN_IDLE,.... fgNLOScnEnable/fgBatchScnEnable/fgGScnEnable false\n"); ++ eNextPSCNState = PSCN_IDLE; ++ } else { ++ if (prScanInfo->prPscnParam->fgNLOScnEnable ++ || prScanInfo->prPscnParam->fgBatchScnEnable) { ++ scnFsmPSCNSetParam(prAdapter, (P_CMD_SET_PSCAN_PARAM) prScanInfo->prPscnParam); ++ scnFsmPSCNAction(prAdapter, ENABLE); ++ eNextPSCNState = PSCN_SCANNING; ++ DBGLOG(SCN, TRACE, ++ "PSCN_RESET->PSCN_SCANNING,.... fgNLOScnEnable/fgBatchScnEnable ENABLE\n"); ++ } ++ } ++ break; ++ ++ case PSCN_SCANNING: ++ if (eNextPSCNState == PSCN_RESET) { ++ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_RESET,.... fgRemoveNLOfromPSCN/fgRemoveBatchSCNfromPSCN/fgRemoveGSCNfromPSCN\n"); ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ break; ++ } ++ ++ if (prCmdNloReq || prCmdBatchReq || prCmdGscnReq || prNewCmdGscnConfig) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_RESET,.... prCmdNloReq/prCmdBatchReq/prCmdGscnReq/prNewCmdGscnConfig\n"); ++ scnFsmPSCNAction(prAdapter, DISABLE); ++ break; ++ } ++ ++ } else if (eNextPSCNState == PSCN_SCANNING) { ++ if (fgEnableGSCN) { ++ if (prScanInfo->prPscnParam->fgGScnEnable && (!prScanInfo->fgPscnOnnning)) { ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); ++ /* scnFsmPSCNAction(prAdapter, ENABLE); */ ++ eNextPSCNState = PSCN_SCANNING; ++ } else { ++ ++ DBGLOG(SCN, TRACE, ++ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); ++ } ++ } ++ } ++ eNextPSCNState = PSCN_SCANNING; ++ break; ++ ++ default: ++ DBGLOG(SCN, WARN, "Unexpected state\n"); ++ ASSERT(0); ++ break; ++ } ++ ++ DBGLOG(SCN, STATE, "eCurrentState %d , eNextPSCNState %d\n", ++ prScanInfo->eCurrentPSCNState, eNextPSCNState); ++ if (prScanInfo->eCurrentPSCNState != eNextPSCNState) ++ fgTransitionState = TRUE; ++ ++ prScanInfo->eCurrentPSCNState = eNextPSCNState; ++ } while (fgTransitionState); ++ ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c +new file mode 100644 +index 000000000000..29eb8d4e7d92 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c +@@ -0,0 +1,1112 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/sec_fsm.c#1 ++*/ ++ ++/*! \file "sec_fsm.c" ++ \brief This is the file implement security check state machine. ++ ++ In security module, do the port control check after success join to an AP, ++ and the path to NORMAL TR, the state machine handle these state transition. ++*/ ++ ++/* ++** Log: sec_fsm.c ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Adjust code for DBG and CONFIG_XLOG. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 03 29 2011 wh.su ++ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error ++ * fixed the kclocwork error. ++ * ++ * 01 26 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * . ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Fix Compile Error when DBG is disabled. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 20 2010 wh.su ++ * NULL ++ * adding the eapol callback setting. ++ * ++ * 08 19 2010 wh.su ++ * NULL ++ * adding the tx pkt call back handle for countermeasure. ++ * ++ * 07 19 2010 wh.su ++ * ++ * fixed the compilng error at debug mode. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * modify some code for concurrent network. ++ * ++ * 06 19 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * consdier the concurrent network setting. ++ * ++ * 05 28 2010 wh.su ++ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing ++ * fixed the ad-hoc wpa-none send non-encrypted frame issue. ++ * ++ * 05 24 2010 kevin.huang ++ * [BORA00000794][WIFISYS][New Feature]Power Management Support ++ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. ++ * ++ * 04 24 2010 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW ++ * ++ * 04 13 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the Klocwork error and refine the class error message. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * Fixed the pre-authentication timer not correctly init issue, ++ * and modify the security related callback function prototype. ++ * ++ * 03 01 2010 wh.su ++ * [BORA00000605][WIFISYS] Phase3 Integration ++ * Refine the variable and parameter for security. ++ * ++ * 01 27 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * add and fixed some security function. ++ * ++ * 01 13 2010 wh.su ++ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code ++ * fixed the compiling warning ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * refine some code ++ * ++ * Dec 4 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * refine the code ++ * ++ * Dec 1 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * code refine ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the function name ++ * ++ * Nov 19 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adjust the state machine, to meet the firmware security design v1.1 ++ * ++ * Nov 18 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_RSN_MIGRATION ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if DBG ++/*lint -save -e64 Type mismatch */ ++static PUINT_8 apucDebugSecState[SEC_STATE_NUM] = { ++ (PUINT_8) DISP_STRING("SEC_STATE_INIT"), ++ (PUINT_8) DISP_STRING("SEC_STATE_INITIATOR_PORT_BLOCKED"), ++ (PUINT_8) DISP_STRING("SEC_STATE_RESPONDER_PORT_BLOCKED"), ++ (PUINT_8) DISP_STRING("SEC_STATE_CHECK_OK"), ++ (PUINT_8) DISP_STRING("SEC_STATE_SEND_EAPOL"), ++ (PUINT_8) DISP_STRING("SEC_STATE_SEND_DEAUTH"), ++ (PUINT_8) DISP_STRING("SEC_STATE_COUNTERMEASURE"), ++}; ++ ++/*lint -restore */ ++#endif /* DBG */ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do initialization of Security FSM and all variables in ++* SEC_INFO_T. ++* ++* \param[in] prSta Pointer to the STA record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ ++#if 1 /* MT6620 */ ++ /* At MT5921, is ok, but at MT6620, firmware base ASIC, the firmware */ ++ /* will lost these data, thus, driver have to keep the wep material and */ ++ /* setting to firmware while awake from D3. */ ++#endif ++ ++ prSecInfo->eCurrentState = SEC_STATE_INIT; ++ ++ prSecInfo->fg2nd1xSend = FALSE; ++ prSecInfo->fgKeyStored = FALSE; ++ ++ if (IS_STA_IN_AIS(prSta)) { ++ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ prAisSpecBssInfo->u4RsnaLastMICFailTime = 0; ++ prAisSpecBssInfo->fgCheckEAPoLTxDone = FALSE; ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEapolTxTimeout, (ULONG) prSta); ++ ++ cnmTimerInitTimer(prAdapter, ++ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEndOfCounterMeasure, (ULONG) prSta); ++ ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do uninitialization of Security FSM and all variables in ++* SEC_INFO_T. ++* ++* \param[in] prSta Pointer to the STA record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID /* whsu:Todo: */ ++secFsmUnInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ ++ prSecInfo->fg2nd1xSend = FALSE; ++ prSecInfo->fgKeyStored = FALSE; ++ ++ /* nicPrivacyRemoveWlanTable(prSta->ucWTEntry); */ ++ ++ if (IS_STA_IN_AIS(prSta)) { ++ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); ++ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* STANDBY to CHECK_OK. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INIT_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ secSetPortBlocked(prAdapter, prSta, FALSE); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* INIT to INITIATOR_PORT_BLOCKED. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INIT_to_INITIATOR_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* INIT to RESPONDER_PORT_BLOCKED. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INIT_to_RESPONDER_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* INITIATOR_PORT_BLOCKED to CHECK_OK. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_INITIATOR_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ secSetPortBlocked(prAdapter, prSta, FALSE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* RESPONDER_PORT_BLOCKED to CHECK_OK. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_RESPONDER_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ secSetPortBlocked(prAdapter, prSta, FALSE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* CHECK_OK to SEND_EAPOL ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_CHECK_OK_to_SEND_EAPOL(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(prSta); ++ ++ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ ASSERT(prAisBssInfo); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prAisBssInfo->fgCheckEAPoLTxDone = TRUE; ++ ++ /* cnmTimerStartTimer(prAdapter, */ ++ /* &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer, */ ++ /* SEC_TO_MSEC(EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC)); */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* SEND_EAPOL to SEND_DEAUTH. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_SEND_EAPOL_to_SEND_DEAUTH(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Compose deauth frame to AP, a call back function for tx done */ ++ if (authSendDeauthFrame(prAdapter, ++ prSta, ++ (P_SW_RFB_T) NULL, ++ REASON_CODE_MIC_FAILURE, ++ (PFN_TX_DONE_HANDLER) secFsmEventDeauthTxDone) != WLAN_STATUS_SUCCESS) { ++ ASSERT(FALSE); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* SEND_DEAUTH to COUNTERMEASURE. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_SEND_DEAUTH_to_COUNTERMEASURE(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prSta); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ /* Start the 60 sec timer */ ++ cnmTimerStartTimer(prAdapter, ++ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, ++ SEC_TO_MSEC(COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do action part while in STATE transition of ++* SEND_DEAUTH to COUNTERMEASURE. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline VOID secFsmTrans_COUNTERMEASURE_to_INIT(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ ++ /* Clear the counter measure flag */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The Core FSM engine of security module. ++* ++* \param[in] prSta Pointer to the Sta record ++* \param[in] eNextState Enum value of next sec STATE ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmSteps(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN ENUM_SEC_STATE_T eNextState) ++{ ++ P_SEC_INFO_T prSecInfo; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ ASSERT(prSecInfo); ++ ++ DEBUGFUNC("secFsmSteps"); ++ do { ++ /* Do entering Next State */ ++ prSecInfo->ePreviousState = prSecInfo->eCurrentState; ++ ++ /* Do entering Next State */ ++#if DBG ++ DBGLOG(RSN, STATE, "\n %pM TRANSITION: [%s] -> [%s]\n\n", ++ prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState], apucDebugSecState[eNextState]); ++#else ++ DBGLOG(RSN, STATE, "\n %pM [%d] TRANSITION: [%d] -> [%d]\n\n", ++ prSta->aucMacAddr, DBG_RSN_IDX, prSecInfo->eCurrentState, eNextState); ++#endif ++ prSecInfo->eCurrentState = eNextState; ++ ++ fgIsTransition = (BOOLEAN) FALSE; ++#if 0 ++ /* Do tasks of the State that we just entered */ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INIT: ++ break; ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ break; ++ case SEC_STATE_RESPONDER_PORT_BLOCKED: ++ break; ++ case SEC_STATE_CHECK_OK: ++ break; ++ case SEC_STATE_SEND_EAPOL: ++ break; ++ case SEC_STATE_SEND_DEAUTH: ++ break; ++ case SEC_STATE_COUNTERMEASURE: ++ break; ++ default: ++ ASSERT(0); /* Make sure we have handle all STATEs */ ++ break; ++ } ++#endif ++ } while (fgIsTransition); ++ ++ return; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do initialization of Security FSM and all variables in ++* SEC_INFO_T. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ENUM_SEC_STATE_T eNextState; ++ ++ DBGLOG(RSN, TRACE, "secFsmRunEventStart\n"); ++ ++ ASSERT(prSta); ++ ++ if (!prSta) ++ return; ++ ++ if (!IS_STA_IN_AIS(prSta)) ++ return; ++ ++ DBGLOG(RSN, TRACE, "secFsmRunEventStart for sta %pM network %d\n", ++ prSta->aucMacAddr, prSta->ucNetTypeIndex); ++ ++ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; ++ ++ eNextState = prSecInfo->eCurrentState; ++ ++ secSetPortBlocked(prAdapter, prSta, TRUE); ++ ++ /* prSta->fgTransmitKeyExist = FALSE; */ ++ /* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */ ++ ++#if 1 /* Since the 1x and key can set to firmware in order, always enter the check ok state */ ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); ++#else ++ if (IS_STA_IN_AIS(prSta->eStaType)) { ++ if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE ++#if CFG_SUPPORT_WAPI ++ || (prAdapter->rWifiVar.rConnSettings.fgWapiMode) ++#endif ++ ) { ++ prSta->fgTransmitKeyExist = FALSE; ++ /* nicPrivacyInitialize(prSta->ucNetTypeIndex); */ ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); ++ } else { ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI ++ else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC)) { ++#elif CFG_ENABLE_WIFI_DIRECT ++ else if (prSta->eStaType == STA_TYPE_P2P_GC) { ++#elif CFG_ENABLE_BT_OVER_WIFI ++ else if (prSta->eStaType == STA_TYPE_BOW_CLIENT) { ++#endif ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED); ++ } ++#endif ++ else ++ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); ++#endif ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++} /* secFsmRunEventStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function called by reset procedure to force the sec fsm enter ++* idle state ++* ++* \param[in] ucNetTypeIdx The Specific Network type index ++* \param[in] prSta Pointer to the Sta record ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ++ DBGLOG(RSN, TRACE, "secFsmEventAbort for sta %pM network %d\n", ++ prSta->aucMacAddr, prSta->ucNetTypeIndex); ++ ++ ASSERT(prSta); ++ ++ if (!prSta) ++ return; ++ ++ if (!IS_STA_IN_AIS(prSta)) ++ return; ++ ++ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; ++ ++ prSta->fgTransmitKeyExist = FALSE; ++ ++ secSetPortBlocked(prAdapter, prSta, TRUE); ++ ++ if (prSecInfo == NULL) ++ return; ++ ++ if (IS_STA_IN_AIS(prSta)) { ++ ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; ++ ++ if (prSecInfo->eCurrentState == SEC_STATE_SEND_EAPOL) { ++ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone == FALSE) { ++ DBGLOG(RSN, TRACE, "EAPOL STATE not match the flag\n"); ++ /* cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar. ++ * rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); */ ++ } ++ } ++ } ++ prSecInfo->eCurrentState = SEC_STATE_INIT; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "2nd EAPoL Tx is sending" to Sec FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ /* BOOLEAN fgIsTransition = (BOOLEAN)FALSE; */ ++ ++ DEBUGFUNC("secFsmRunEvent2ndEapolTx"); ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ case SEC_STATE_CHECK_OK: ++ prSecInfo->fg2nd1xSend = TRUE; ++ break; ++ default: ++#if DBG ++ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState); ++#endif ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return; ++ ++} /* secFsmRunEvent2ndEapolTx */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "4th EAPoL Tx is Tx done" to Sec FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ P_CMD_802_11_KEY prStoredKey; ++ ++ DEBUGFUNC("secFsmRunEvent4ndEapolTx"); ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ case SEC_STATE_CHECK_OK: ++ prSecInfo->fg2nd1xSend = FALSE; ++ if (prSecInfo->fgKeyStored) { ++ prStoredKey = (P_CMD_802_11_KEY) prSecInfo->aucStoredKey; ++ ++ /* prSta = rxmLookupStaRecIndexFromTA(prStoredKey->aucPeerAddr); */ ++ /* if (nicPrivacySetKeyEntry(prStoredKey, prSta->ucWTEntry) == FALSE) */ ++ /* DBGLOG(RSN, WARN, ("nicPrivacySetKeyEntry() fail,..\n")); */ ++ ++ /* key update */ ++ prSecInfo->fgKeyStored = FALSE; ++ prSta->fgTransmitKeyExist = TRUE; ++ } ++ if (prSecInfo->eCurrentState == SEC_STATE_INITIATOR_PORT_BLOCKED) ++ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); ++ break; ++ default: ++ ++#if DBG ++ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at [%d]\n", prSecInfo->eCurrentState); ++#endif ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return; ++ ++} /* secFsmRunEvent4ndEapolTx */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Pairwise key installed" to SEC FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \retval TRUE The key can be installed to HW ++* \retval FALSE The kay conflict with the current key, abort it ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgStatus = TRUE; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ ASSERT(prSta); ++ ++ prSecInfo = &prSta->rSecInfo; ++ if (prSecInfo == NULL) ++ return TRUE; /* Not PTK */ ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAdd), ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ eNextState = prSecInfo->eCurrentState; ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_INIT: ++ /* Legacy wep, wpa-none */ ++ break; ++ ++ case SEC_STATE_INITIATOR_PORT_BLOCKED: ++ if (prSecInfo->fg2nd1xSend) ++ ; ++ else ++ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); ++ break; ++ ++ case SEC_STATE_RESPONDER_PORT_BLOCKED: ++ SEC_STATE_TRANSITION(prAdapter, prSta, RESPONDER_PORT_BLOCKED, CHECK_OK); ++ break; ++ ++ case SEC_STATE_CHECK_OK: ++ break; ++ ++ default: ++ fgStatus = FALSE; ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return fgStatus; ++ ++} /* end of secFsmRunEventPTKInstalled() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Counter Measure" to SEC FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("secFsmRunEventStartCounterMeasure"); ++ ++ ASSERT(prSta); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prSecInfo = &prSta->rSecInfo; ++ ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ prAdapter->rWifiVar.rAisSpecificBssInfo.u4RsnaLastMICFailTime = 0; ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_CHECK_OK: ++ { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = TRUE; ++ ++ /* dls port control */ ++ SEC_STATE_TRANSITION(prAdapter, prSta, CHECK_OK, SEND_EAPOL); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Call arbFsmSteps() when we are going to change ARB STATE */ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++ return; ++ ++} /* secFsmRunEventStartCounterMeasure */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "802.1x EAPoL Tx Done" to Sec FSM. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; ++ ++ DEBUGFUNC("secFsmRunEventEapolTxDone"); ++ ++ ASSERT(prStaRec); ++ ++ if (rTxDoneStatus != TX_RESULT_SUCCESS) { ++ DBGLOG(RSN, INFO, "Error EAPoL fram fail to send!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ if (!IS_STA_IN_AIS(prStaRec)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; ++ ++ ASSERT(prAisBssInfo); ++ ++ prSecInfo = &prStaRec->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_SEND_EAPOL: ++ if (prAisBssInfo->fgCheckEAPoLTxDone == FALSE) ++ ASSERT(0); ++ ++ prAisBssInfo->fgCheckEAPoLTxDone = FALSE; ++ /* cnmTimerStopTimer(prAdapter, &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer); */ ++ ++ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_EAPOL, SEND_DEAUTH); ++ break; ++ default: ++ break; ++ } ++ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prStaRec, eNextState); ++ ++ return; ++ ++} /* secFsmRunEventEapolTxDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will indicate an Event of "Deauth frame Tx Done" to Sec FSM. ++* ++* \param[in] pMsduInfo Pointer to the Msdu Info ++* \param[in] rStatus The Tx done status ++* ++* \return - ++* ++* \note after receive deauth frame, callback function call this ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_STA_RECORD_T prStaRec; ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("secFsmRunEventDeauthTxDone"); ++ ++ ASSERT(prMsduInfo); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ ASSERT(prStaRec); ++ ++ if (!prStaRec) ++ return; ++ ++ if (!IS_STA_IN_AIS(prStaRec)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prSecInfo = (P_SEC_INFO_T) &prStaRec->rSecInfo; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_SEND_DEAUTH: ++ ++ DBGLOG(RSN, TRACE, "Set timer %d\n", COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC); ++ ++ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_DEAUTH, COUNTERMEASURE); ++ ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++} /* secFsmRunEventDeauthTxDone */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will check the eapol error frame fail to send issue. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("secFsmRunEventEapolTxTimeout"); ++ ++ prStaRec = (P_STA_RECORD_T) ulParm; ++ ++ ASSERT(prStaRec); ++ ++ /* Todo:: How to handle the Eapol Error fail to send case? */ ++ ASSERT(0); ++ ++ return; ++ ++} /* secFsmEventEapolTxTimeout */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will stop the counterMeasure duration. ++* ++* \param[in] prSta Pointer to the Sta record ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, ULONG ulParm) ++{ ++ P_STA_RECORD_T prSta; ++ P_SEC_INFO_T prSecInfo; ++ ENUM_SEC_STATE_T eNextState; ++ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; ++ ++ DEBUGFUNC("secFsmRunEventEndOfCounterMeasure"); ++ ++ prSta = (P_STA_RECORD_T) ulParm; ++ ++ ASSERT(prSta); ++ ++ if (!IS_STA_IN_AIS(prSta)) { ++ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ prSecInfo = &prSta->rSecInfo; ++ eNextState = prSecInfo->eCurrentState; ++ ++#if DBG ++ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, ++ apucDebugSecState[prSecInfo->eCurrentState]); ++#else ++ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); ++#endif ++ ++ switch (prSecInfo->eCurrentState) { ++ case SEC_STATE_SEND_DEAUTH: ++ { ++ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = FALSE; ++ ++ SEC_STATE_TRANSITION(prAdapter, prSta, COUNTERMEASURE, INIT); ++ } ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ /* Call arbFsmSteps() when we are going to change ARB STATE */ ++ if (prSecInfo->eCurrentState != eNextState) ++ secFsmSteps(prAdapter, prSta, eNextState); ++ ++} /* end of secFsmRunEventEndOfCounterMeasure */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c +new file mode 100644 +index 000000000000..ab3fcc028375 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c +@@ -0,0 +1,1342 @@ ++/* ++** Id: stats.c#1 ++*/ ++ ++/*! \file stats.c ++ \brief This file includes statistics support. ++*/ ++ ++/* ++** Log: stats.c ++ * ++ * 07 17 2014 samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++#include "precomp.h" ++ ++enum EVENT_TYPE { ++ EVENT_RX, ++ EVENT_TX, ++ EVENT_TX_DONE ++}; ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++static WLAN_STATUS ++statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++UINT_64 u8DrvOwnStart, u8DrvOwnEnd; ++UINT32 u4DrvOwnMax = 0; ++#define CFG_USER_LOAD 0 ++static UINT_16 su2TxDoneCfg = CFG_DHCP | CFG_ICMP | CFG_EAPOL; ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display all environment log. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ P_ADAPTER_T prAdapter; ++ STA_RECORD_T *prStaRec; ++ UINT32 u4NumOfInfo, u4InfoId; ++ UINT32 u4RxErrBitmap; ++ STATS_INFO_ENV_T *prInfo; ++ UINT32 u4Total, u4RateId; ++ ++/* ++[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 ++[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) ++ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, ++ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) ++ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) ++ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) ++ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) ++ ERR (1st: total number of tx err, 2nd ~ 7st: total number of ++ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, ++ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) ++ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) ++ RX (1st: latest RCPI, 2nd: chan num) ++ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) ++ OK (number of rx packets without error, number of rx packets to OS) ++ ERR (number of rx packets with error) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ CCK MODE (1 2 5.5 11M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) ++ MIXED MODE (number of rx packets with MCS0 ~ MCS15) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) ++ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) ++ delay from MAC start TX to MAC TX done ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) ++ delay from HIF to MAC TX done (min, avg, max_system time for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) ++ delay from driver to MAC TX done (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) ++ delay from MAC to HIF (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) ++ delay from HIF to Driver OS (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) ++ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) ++ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) ++ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) ++ Channel idle time, scan count, channel change count, empty tx quota count, ++ power save change count from active to PS, maximum delay from PS to active ++*/ ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ /*prInfo = &rStatsInfoEnv;*/ ++ prInfo = kalMemAlloc(sizeof(STATS_INFO_ENV_T), VIR_MEM_TYPE); ++ if (prInfo == NULL) { ++ DBGLOG(RX, INFO, "prInfo alloc fail"); ++ return; ++ } ++ ++ kalMemZero(prInfo, sizeof(STATS_INFO_ENV_T)); ++ ++ if (u4InBufLen > sizeof(STATS_INFO_ENV_T)) ++ u4InBufLen = sizeof(STATS_INFO_ENV_T); ++ ++ /* parse */ ++ u4NumOfInfo = *(UINT32 *) prInBuf; ++ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); ++ ++ /* print */ ++ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { ++ /* ++ use u4InBufLen, not sizeof(rStatsInfoEnv) ++ because the firmware version maybe not equal to driver version ++ */ ++ kalMemCopy(prInfo, prInBuf + 8, u4InBufLen); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prInfo->ucStaRecIdx); ++ if (prStaRec == NULL) ++ continue; ++ ++ DBGLOG(RX, INFO, " Display stats for [%pM]: %uB\n", ++ prStaRec->aucMacAddr, (UINT32) sizeof(STATS_INFO_ENV_T)); ++ ++ if (prStaRec->ucStatsGenDisplayCnt++ > 10) { ++ /* display general statistics information every 10 * (5 or 10s) */ ++ DBGLOG(RX, INFO, " TBA(0x%x %u) RBA(0x%x %u)\n", ++ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, ++ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize); ++ prStaRec->ucStatsGenDisplayCnt = 0; ++ } ++ ++ if (prInfo->u4TxDataCntErr == 0) { ++ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u)\n", ++ (UINT32) prGlueInfo->rNetDevStats.tx_packets, ++ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK); ++ } else { ++ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u) ERR(%u)\n", ++ (UINT32) prGlueInfo->rNetDevStats.tx_packets, ++ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, prInfo->u4TxDataCntErr); ++ DBGLOG(RX, INFO, " ERR type(%u %u %u %u %u %u)\n", ++ prInfo->u4TxDataCntErrType[0], prInfo->u4TxDataCntErrType[1], ++ prInfo->u4TxDataCntErrType[2], prInfo->u4TxDataCntErrType[3], ++ prInfo->u4TxDataCntErrType[4], prInfo->u4TxDataCntErrType[5]); ++ } ++ ++ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4TxRateCntNonHT[u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, " non-HT TRATE (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], ++ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], ++ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], ++ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], ++ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], ++ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], ++ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], ++ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15]); ++ } ++ if (prInfo->u4TxRateCntNonHT[0] > 0) { ++ DBGLOG(RX, INFO, " HT TRATE (1M %u) (%u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntNonHT[0], ++ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], ++ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], ++ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], ++ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); ++ } else { ++ DBGLOG(RX, INFO, " HT TRATE (%u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], ++ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], ++ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], ++ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); ++ } ++ ++ if ((prStaRec->u4RxReorderFallAheadCnt != 0) || ++ (prStaRec->u4RxReorderFallBehindCnt != 0) || (prStaRec->u4RxReorderHoleCnt != 0)) { ++ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", ++ prStaRec->u4RxReorderFallAheadCnt, ++ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); ++ } ++ ++ if (prInfo->u4RxDataCntErr == 0) { ++ DBGLOG(RX, INFO, " ROK(%u %u)\n", ++ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt); ++ } else { ++ DBGLOG(RX, INFO, " ROK(%u %u) ERR(%u)\n", ++ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, ++ prInfo->u4RxDataCntErr); ++ } ++ ++ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateCnt[0][u4RateId] + prInfo->u4RxRateRetryCnt[0][u4RateId]; ++ if (u4Total > 0) { ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateRetryCnt[0][u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, ++ " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], ++ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], ++ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], ++ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], ++ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], ++ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], ++ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], ++ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], ++ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], ++ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], ++ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], ++ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], ++ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], ++ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], ++ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], ++ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15]); ++ } else { ++ DBGLOG(RX, INFO, " RCCK (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4RxRateCnt[0][0], ++ prInfo->u4RxRateCnt[0][1], ++ prInfo->u4RxRateCnt[0][2], ++ prInfo->u4RxRateCnt[0][3], ++ prInfo->u4RxRateCnt[0][4], ++ prInfo->u4RxRateCnt[0][5], ++ prInfo->u4RxRateCnt[0][6], ++ prInfo->u4RxRateCnt[0][7], ++ prInfo->u4RxRateCnt[0][8], ++ prInfo->u4RxRateCnt[0][9], ++ prInfo->u4RxRateCnt[0][10], ++ prInfo->u4RxRateCnt[0][11], ++ prInfo->u4RxRateCnt[0][12], ++ prInfo->u4RxRateCnt[0][13], ++ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateCnt[0][15]); ++ } ++ } else { ++ if ((prInfo->u4RxRateCnt[0][0] + prInfo->u4RxRateRetryCnt[0][0]) > 0) { ++ DBGLOG(RX, INFO, " RCCK (%u %u)\n", ++ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0]); ++ } ++ } ++ ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateCnt[1][u4RateId] + prInfo->u4RxRateRetryCnt[1][u4RateId]; ++ if (u4Total > 0) { ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateRetryCnt[1][u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, ++ " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], ++ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], ++ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], ++ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], ++ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], ++ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], ++ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], ++ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], ++ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], ++ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], ++ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], ++ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], ++ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], ++ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], ++ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], ++ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15]); ++ } else { ++ DBGLOG(RX, INFO, " ROFDM (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4RxRateCnt[1][0], ++ prInfo->u4RxRateCnt[1][1], ++ prInfo->u4RxRateCnt[1][2], ++ prInfo->u4RxRateCnt[1][3], ++ prInfo->u4RxRateCnt[1][4], ++ prInfo->u4RxRateCnt[1][5], ++ prInfo->u4RxRateCnt[1][6], ++ prInfo->u4RxRateCnt[1][7], ++ prInfo->u4RxRateCnt[1][8], ++ prInfo->u4RxRateCnt[1][9], ++ prInfo->u4RxRateCnt[1][10], ++ prInfo->u4RxRateCnt[1][11], ++ prInfo->u4RxRateCnt[1][12], ++ prInfo->u4RxRateCnt[1][13], ++ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateCnt[1][15]); ++ } ++ } ++ ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateCnt[2][u4RateId] + prInfo->u4RxRateRetryCnt[2][u4RateId]; ++ if (u4Total > 0) { ++ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) ++ u4Total += prInfo->u4RxRateRetryCnt[2][u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, " RHT\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], ++ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], ++ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], ++ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], ++ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], ++ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], ++ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], ++ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7]); ++ } else { ++ DBGLOG(RX, INFO, " RHT (%u %u %u %u %u %u %u %u)\n", ++ prInfo->u4RxRateCnt[2][0], ++ prInfo->u4RxRateCnt[2][1], ++ prInfo->u4RxRateCnt[2][2], ++ prInfo->u4RxRateCnt[2][3], ++ prInfo->u4RxRateCnt[2][4], ++ prInfo->u4RxRateCnt[2][5], ++ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateCnt[2][7]); ++ } ++ } ++ ++ /* RX drop counts */ ++ for (u4RateId = 0, u4Total = 0; u4RateId < 20; u4RateId++) ++ u4Total += prInfo->u4NumOfRxDrop[u4RateId]; ++ if (u4Total > 0) { ++ DBGLOG(RX, INFO, " RX Drop Count: (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n" ++ " (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", ++ prInfo->u4NumOfRxDrop[0], prInfo->u4NumOfRxDrop[1], ++ prInfo->u4NumOfRxDrop[2], prInfo->u4NumOfRxDrop[3], ++ prInfo->u4NumOfRxDrop[4], prInfo->u4NumOfRxDrop[5], ++ prInfo->u4NumOfRxDrop[6], prInfo->u4NumOfRxDrop[7], ++ prInfo->u4NumOfRxDrop[8], prInfo->u4NumOfRxDrop[9], ++ prInfo->u4NumOfRxDrop[10], prInfo->u4NumOfRxDrop[11], ++ prInfo->u4NumOfRxDrop[12], prInfo->u4NumOfRxDrop[13], ++ prInfo->u4NumOfRxDrop[14], prInfo->u4NumOfRxDrop[15], ++ prInfo->u4NumOfRxDrop[16], prInfo->u4NumOfRxDrop[17], ++ prInfo->u4NumOfRxDrop[18], prInfo->u4NumOfRxDrop[19]); ++ } ++ ++ /* delay from HIF RX to HIF RX Done */ ++ if (((prInfo->u4StayIntMinHR2HRD[1] + prInfo->u4StayIntAvgHR2HRD[1] + ++ prInfo->u4StayIntMaxHR2HRD[1]) > 0) || ++ ((prInfo->u4StayIntMinHR2HRD[2] + prInfo->u4StayIntAvgHR2HRD[2] + ++ prInfo->u4StayIntMaxHR2HRD[2]) > 0)) { ++ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], ++ prInfo->u4StayIntMaxHR2HRD[0], ++ prInfo->u4StayIntMinHR2HRD[1], prInfo->u4StayIntAvgHR2HRD[1], ++ prInfo->u4StayIntMaxHR2HRD[1], ++ prInfo->u4StayIntMinHR2HRD[2], prInfo->u4StayIntAvgHR2HRD[2], ++ prInfo->u4StayIntMaxHR2HRD[2]); ++ } else { ++ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u)\n", ++ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], ++ prInfo->u4StayIntMaxHR2HRD[0]); ++ } ++ ++ /* others */ ++ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%x)\n", ++ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, ++ prInfo->u4NumOfChanChange, prInfo->u4CurrChnlInfo); ++#if CFG_SUPPORT_THERMO_THROTTLING ++ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; ++#endif ++ /* reset */ ++ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); ++ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); ++ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); ++ prStaRec->u4StatsRxPassToOsCnt = 0; ++ prStaRec->u4RxReorderFallAheadCnt = 0; ++ prStaRec->u4RxReorderFallBehindCnt = 0; ++ prStaRec->u4RxReorderHoleCnt = 0; ++ } ++ ++ STATS_DRIVER_OWN_RESET(); ++ kalMemFree(prInfo, VIR_MEM_TYPE, sizeof(STATS_INFO_ENV_T)); ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display all environment log. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ P_ADAPTER_T prAdapter; ++ STA_RECORD_T *prStaRec; ++ UINT32 u4NumOfInfo, u4InfoId; ++ UINT32 u4RxErrBitmap; ++ STATS_INFO_ENV_T rStatsInfoEnv, *prInfo; ++ ++/* ++[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event ++[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 ++[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) ++ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, ++ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) ++ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) ++ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) ++ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) ++ ERR (1st: total number of tx err, 2nd ~ 7st: total number of ++ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, ++ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) ++ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) ++ RX (1st: latest RCPI, 2nd: chan num) ++ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) ++ OK (number of rx packets without error, number of rx packets to OS) ++ ERR (number of rx packets with error) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ CCK MODE (1 2 5.5 11M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ++ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) ++[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) ++ MIXED MODE (number of rx packets with MCS0 ~ MCS15) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) ++ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) ++ delay from MAC start TX to MAC TX done ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) ++ delay from HIF to MAC TX done (min, avg, max_system time for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) ++ delay from driver to MAC TX done (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) ++ delay from MAC to HIF (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) ++ delay from HIF to Driver OS (min, avg, max for 500B) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) ++ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) ++ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) ++ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) ++ ++[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) ++ Channel idle time, scan count, channel change count, empty tx quota count, ++ power save change count from active to PS, maximum delay from PS to active ++*/ ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ prInfo = &rStatsInfoEnv; ++ kalMemZero(&rStatsInfoEnv, sizeof(rStatsInfoEnv)); ++ ++ if (u4InBufLen > sizeof(rStatsInfoEnv)) ++ u4InBufLen = sizeof(rStatsInfoEnv); ++ ++ /* parse */ ++ u4NumOfInfo = *(UINT32 *) prInBuf; ++ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); ++ ++ /* print */ ++ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { ++ /* ++ use u4InBufLen, not sizeof(rStatsInfoEnv) ++ because the firmware version maybe not equal to driver version ++ */ ++ kalMemCopy(&rStatsInfoEnv, prInBuf + 8, u4InBufLen); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, rStatsInfoEnv.ucStaRecIdx); ++ if (prStaRec == NULL) ++ continue; ++ ++ DBGLOG(RX, INFO, " Display stats V%d.%d for [%pM]: %uB %ums\n", ++ prInfo->ucFwVer[0], prInfo->ucFwVer[1], ++ (prStaRec->aucMacAddr), (UINT32) sizeof(STATS_INFO_ENV_T), ++ prInfo->u4ReportSysTime); ++ DBGLOG(RX, INFO, "TPAM(0x%x)RTS(%u %u)BA(0x%x %u)OS(%u)OK(%u %u)ERR(%u %u %u %u %u %u %u)\n", ++ prInfo->ucTxParam, ++ prInfo->fgTxIsRtsUsed, prInfo->fgTxIsRtsEverUsed, ++ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, ++ (UINT32) prGlueInfo->rNetDevStats.tx_packets, ++ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, ++ prInfo->u4TxDataCntErr, prInfo->u4TxDataCntErrType[0], ++ prInfo->u4TxDataCntErrType[1], prInfo->u4TxDataCntErrType[2], ++ prInfo->u4TxDataCntErrType[3], prInfo->u4TxDataCntErrType[4], ++ prInfo->u4TxDataCntErrType[5])); ++ ++ DBGLOG(RX, INFO, "TRATE(%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", ++ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], ++ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], ++ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], ++ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], ++ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], ++ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], ++ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], ++ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15], ++ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], ++ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], ++ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], ++ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7])); ++ ++ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", ++ prStaRec->u4RxReorderFallAheadCnt, ++ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); ++ ++ DBGLOG(RX, INFO, " RX(%u %u %u) BA(0x%x %u) OK(%u %u) ERR(%u)\n", ++ prInfo->ucRcvRcpi, prInfo->ucHwChanNum, prInfo->fgRxIsShortGI, ++ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize, ++ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, prInfo->u4RxDataCntErr); ++ ++ DBGLOG(RX, INFO, " RX Free MAC DESC(%u %u %u %u %u %u) Free HIF DESC(%u %u %u %u %u %u)\n", ++ prInfo->u4RxMacFreeDescCnt[0], prInfo->u4RxMacFreeDescCnt[1], ++ prInfo->u4RxMacFreeDescCnt[2], prInfo->u4RxMacFreeDescCnt[3], ++ prInfo->u4RxMacFreeDescCnt[4], prInfo->u4RxMacFreeDescCnt[5], ++ prInfo->u4RxHifFreeDescCnt[0], prInfo->u4RxHifFreeDescCnt[1], ++ prInfo->u4RxHifFreeDescCnt[2], prInfo->u4RxHifFreeDescCnt[3], ++ prInfo->u4RxHifFreeDescCnt[4], prInfo->u4RxHifFreeDescCnt[5])); ++ ++ DBGLOG(RX, INFO, " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], ++ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], ++ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], ++ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], ++ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], ++ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], ++ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], ++ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], ++ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], ++ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], ++ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], ++ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], ++ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], ++ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], ++ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], ++ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15])); ++ DBGLOG(RX, INFO, " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], ++ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], ++ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], ++ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], ++ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], ++ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], ++ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], ++ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], ++ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], ++ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], ++ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], ++ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], ++ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], ++ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], ++ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], ++ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15])); ++ DBGLOG(RX, INFO, " RHT (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" ++ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", ++ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], ++ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], ++ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], ++ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], ++ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], ++ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], ++ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], ++ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7], ++ prInfo->u4RxRateCnt[2][8], prInfo->u4RxRateRetryCnt[2][8], ++ prInfo->u4RxRateCnt[2][9], prInfo->u4RxRateRetryCnt[2][9], ++ prInfo->u4RxRateCnt[2][10], prInfo->u4RxRateRetryCnt[2][10], ++ prInfo->u4RxRateCnt[2][11], prInfo->u4RxRateRetryCnt[2][11], ++ prInfo->u4RxRateCnt[2][12], prInfo->u4RxRateRetryCnt[2][12], ++ prInfo->u4RxRateCnt[2][13], prInfo->u4RxRateRetryCnt[2][13], ++ prInfo->u4RxRateCnt[2][14], prInfo->u4RxRateRetryCnt[2][14], ++ prInfo->u4RxRateCnt[2][15], prInfo->u4RxRateRetryCnt[2][15])); ++ ++ /* delay from HIF to MAC */ ++ DBGLOG(RX, INFO, " StayIntH2M us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinH2M[0], prInfo->u4StayIntAvgH2M[0], ++ prInfo->u4StayIntMaxH2M[0], ++ prInfo->u4StayIntMinH2M[1], prInfo->u4StayIntAvgH2M[1], ++ prInfo->u4StayIntMaxH2M[1], ++ prInfo->u4StayIntMinH2M[2], prInfo->u4StayIntAvgH2M[2], ++ prInfo->u4StayIntMaxH2M[2])); ++ /* delay from MAC to TXDONE */ ++ DBGLOG(RX, INFO, " AirTime us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4AirDelayMin[0] << 5, prInfo->u4AirDelayAvg[0] << 5, ++ prInfo->u4AirDelayMax[0] << 5, ++ prInfo->u4AirDelayMin[1] << 5, prInfo->u4AirDelayAvg[1] << 5, ++ prInfo->u4AirDelayMax[1] << 5, ++ prInfo->u4TxDataCntAll, (prInfo->u4AirDelayAvg[2] << 5) / (prInfo->u4TxDataCntAll), ++ (prInfo->u4AirDelayAvg[2] << 5) / 400000)); ++ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; ++ /* delay from HIF to TXDONE */ ++ DBGLOG(RX, INFO, " StayInt us (%u %u %u_%u) (%u %u %u_%u) (%u %u %u_%u)\n", ++ prInfo->u4StayIntMin[0], prInfo->u4StayIntAvg[0], ++ prInfo->u4StayIntMax[0], prInfo->u4StayIntMaxSysTime[0], ++ prInfo->u4StayIntMin[1], prInfo->u4StayIntAvg[1], ++ prInfo->u4StayIntMax[1], prInfo->u4StayIntMaxSysTime[1], ++ prInfo->u4StayIntMin[2], prInfo->u4StayIntAvg[2], ++ prInfo->u4StayIntMax[2], prInfo->u4StayIntMaxSysTime[2])); ++ /* delay from Driver to TXDONE */ ++ DBGLOG(RX, INFO, " StayIntD2T us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinD2T[0], prInfo->u4StayIntAvgD2T[0], ++ prInfo->u4StayIntMaxD2T[0], ++ prInfo->u4StayIntMinD2T[1], prInfo->u4StayIntAvgD2T[1], ++ prInfo->u4StayIntMaxD2T[1], ++ prInfo->u4StayIntMinD2T[2], prInfo->u4StayIntAvgD2T[2], ++ prInfo->u4StayIntMaxD2T[2])); ++ ++ /* delay from RXDONE to HIF */ ++ DBGLOG(RX, INFO, " StayIntR_M2H us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prInfo->u4StayIntMinRx[0], prInfo->u4StayIntAvgRx[0], ++ prInfo->u4StayIntMaxRx[0], ++ prInfo->u4StayIntMinRx[1], prInfo->u4StayIntAvgRx[1], ++ prInfo->u4StayIntMaxRx[1], ++ prInfo->u4StayIntMinRx[2], prInfo->u4StayIntAvgRx[2], prInfo->u4StayIntMaxRx[2])); ++ /* delay from HIF to OS */ ++ DBGLOG(RX, INFO, " StayIntR_H2D us (%u %u %u) (%u %u %u) (%u %u %u)\n", ++ prStaRec->u4StayIntMinRx[0], prStaRec->u4StayIntAvgRx[0], ++ prStaRec->u4StayIntMaxRx[0], ++ prStaRec->u4StayIntMinRx[1], prStaRec->u4StayIntAvgRx[1], ++ prStaRec->u4StayIntMaxRx[1], ++ prStaRec->u4StayIntMinRx[2], prStaRec->u4StayIntAvgRx[2], ++ prStaRec->u4StayIntMaxRx[2])); ++ ++ /* count based on delay from OS to HIF */ ++ DBGLOG(RX, INFO, " StayCntD2H unit:%dms (%d %d %d %d)\n", ++ STATS_STAY_INT_D2H_CONST, ++ prInfo->u4StayIntD2HByConst[0], prInfo->u4StayIntD2HByConst[1], ++ prInfo->u4StayIntD2HByConst[2], prInfo->u4StayIntD2HByConst[3]); ++ ++ /* count based on different delay from HIF to TX DONE */ ++ DBGLOG(RX, INFO, " StayCnt unit:%dms (%d %d %d %d)\n", ++ STATS_STAY_INT_CONST, ++ prInfo->u4StayIntByConst[0], prInfo->u4StayIntByConst[1], ++ prInfo->u4StayIntByConst[2], prInfo->u4StayIntByConst[3]); ++ DBGLOG(RX, INFO, " StayCnt (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~:%d)\n", ++ 0, prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntCnt[0], ++ prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntCnt[1], ++ prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntMaxPast * 3 / 4, ++ prInfo->u4StayIntCnt[2], prInfo->u4StayIntMaxPast * 3 / 4, prInfo->u4StayIntMaxPast, ++ prInfo->u4StayIntCnt[3], prInfo->u4StayIntMaxPast, prInfo->u4StayIntCnt[4])); ++ ++ /* channel idle time */ ++ DBGLOG(RX, INFO, " Idle Time (slot): (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", ++ prInfo->au4ChanIdleCnt[0], prInfo->au4ChanIdleCnt[1], ++ prInfo->au4ChanIdleCnt[2], prInfo->au4ChanIdleCnt[3], ++ prInfo->au4ChanIdleCnt[4], prInfo->au4ChanIdleCnt[5], ++ prInfo->au4ChanIdleCnt[6], prInfo->au4ChanIdleCnt[7], ++ prInfo->au4ChanIdleCnt[8], prInfo->au4ChanIdleCnt[9])); ++ ++ /* BT coex */ ++ DBGLOG(RX, INFO, " BT coex (0x%x)\n", prInfo->u4BtContUseTime); ++ ++ /* others */ ++ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%u) (%u) (%ums) (%uus)\n", ++ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, ++ prInfo->u4NumOfChanChange, prStaRec->u4NumOfNoTxQuota, ++ prInfo->ucNumOfPsChange, prInfo->u4PsIntMax, u4DrvOwnMax / 1000); ++ ++ /* reset */ ++ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); ++ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); ++ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); ++ prStaRec->u4StatsRxPassToOsCnt = 0; ++ prStaRec->u4RxReorderFallAheadCnt = 0; ++ prStaRec->u4RxReorderFallBehindCnt = 0; ++ prStaRec->u4RxReorderHoleCnt = 0; ++ } ++ ++ STATS_DRIVER_OWN_RESET(); ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to request firmware to feedback statistics. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ STATS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* sanity check */ ++ if (fgIsUnderSuspend == true) ++ return WLAN_STATUS_SUCCESS; /* do not request stats after early suspend */ ++ ++ /* init command buffer */ ++ prCmdContent = (STATS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = STATS_CORE_CMD_ENV_REQUEST; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_STATS, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(STATS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(RX, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return WLAN_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(RX, INFO, "%s cmd ok.\n", __func__); ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle any statistics event. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ UINT32 u4EventId; ++ ++ /* sanity check */ ++/* DBGLOG(RX, INFO, */ ++/* (" %s: Rcv a event\n", __FUNCTION__)); */ ++ ++ if ((prGlueInfo == NULL) || (prInBuf == NULL)) ++ return; /* shall not be here */ ++ ++ /* handle */ ++ u4EventId = *(UINT32 *) prInBuf; ++ u4InBufLen -= 4; ++ ++/* DBGLOG(RX, INFO, */ ++/* (" %s: Rcv a event: %d\n", __FUNCTION__, u4EventId)); */ ++ ++ switch (u4EventId) { ++ case STATS_HOST_EVENT_ENV_REPORT: ++ statsInfoEnvDisplay(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to detect if we can request firmware to feedback statistics. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] ucStaRecIndex The station index ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex) ++{ ++ STA_RECORD_T *prStaRec; ++ OS_SYSTIME rCurTime; ++ STATS_CMD_CORE_T rCmd; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); ++ if (prStaRec == NULL) ++ return; ++ ++ prStaRec->u4StatsEnvTxCnt++; ++ GET_CURRENT_SYSTIME(&rCurTime); ++ ++ if (prStaRec->rStatsEnvTxPeriodLastTime == 0) { ++ prStaRec->rStatsEnvTxLastTime = rCurTime; ++ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; ++ return; ++ } ++ ++ if (prStaRec->u4StatsEnvTxCnt > STATS_ENV_TX_CNT_REPORT_TRIGGER) { ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxLastTime, ++ SEC_TO_SYSTIME(STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC))) { ++ rCmd.ucStaRecIdx = ucStaRecIndex; ++ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); ++ ++ prStaRec->rStatsEnvTxLastTime = rCurTime; ++ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; ++ prStaRec->u4StatsEnvTxCnt = 0; ++ return; ++ } ++ } ++ ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxPeriodLastTime, SEC_TO_SYSTIME(STATS_ENV_TIMEOUT_SEC))) { ++ rCmd.ucStaRecIdx = ucStaRecIndex; ++ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); ++ ++ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle rx done. ++* ++* \param[in] prStaRec Pointer to the STA_RECORD_T structure ++* \param[in] prSwRfb Pointer to the received packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb) ++{ ++ UINT32 u4LenId; ++ UINT32 u4CurTime, u4DifTime; ++ ++ /* sanity check */ ++ if (prStaRec == NULL) ++ return; ++ ++ /* stats: rx done count */ ++ prStaRec->u4StatsRxPassToOsCnt++; ++ ++ /* get length partition ID */ ++ u4LenId = 0; ++ if (prSwRfb->u2PacketLen < STATS_STAY_INT_BYTE_THRESHOLD) { ++ u4LenId = 0; ++ } else { ++ if ((STATS_STAY_INT_BYTE_THRESHOLD <= prSwRfb->u2PacketLen) && ++ (prSwRfb->u2PacketLen < (STATS_STAY_INT_BYTE_THRESHOLD << 1))) { ++ u4LenId = 1; ++ } else ++ u4LenId = 2; ++ } ++ ++ /* stats: rx delay */ ++ u4CurTime = kalGetTimeTick(); ++ ++ if ((u4CurTime > prSwRfb->rRxTime) && (prSwRfb->rRxTime != 0)) { ++ u4DifTime = u4CurTime - prSwRfb->rRxTime; ++ ++ if (prStaRec->u4StayIntMinRx[u4LenId] == 0) /* impossible */ ++ prStaRec->u4StayIntMinRx[u4LenId] = 0xffffffff; ++ ++ if (u4DifTime > prStaRec->u4StayIntMaxRx[u4LenId]) ++ prStaRec->u4StayIntMaxRx[u4LenId] = u4DifTime; ++ else if (u4DifTime < prStaRec->u4StayIntMinRx[u4LenId]) ++ prStaRec->u4StayIntMinRx[u4LenId] = u4DifTime; ++ ++ prStaRec->u4StayIntAvgRx[u4LenId] += u4DifTime; ++ if (prStaRec->u4StayIntAvgRx[u4LenId] != u4DifTime) ++ prStaRec->u4StayIntAvgRx[u4LenId] >>= 1; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle rx done. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_64 StatsEnvTimeGet(VOID) ++{ ++ /* TODO: use better API to get time to save time, jiffies unit is 10ms, too large */ ++ ++/* struct timeval tv; */ ++ ++/* do_gettimeofday(&tv); */ ++/* return tv.tv_usec + tv.tv_sec * (UINT_64)1000000; */ ++ ++ UINT_64 u8Clk; ++/* UINT32 *pClk = &u8Clk; */ ++ ++ u8Clk = sched_clock(); /* unit: naro seconds */ ++/* printk(" sched_clock() = %x %x %u\n", pClk[0], pClk[1], sizeof(jiffies)); */ ++ ++ return (UINT_64) u8Clk; /* sched_clock *//* jiffies size = 4B */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle rx done. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader) ++{ ++ UINT_64 u8SysTime, u8SysTimeIn; ++ UINT32 u4TimeDiff; ++ ++ u8SysTime = StatsEnvTimeGet(); ++ u8SysTimeIn = GLUE_GET_PKT_XTIME(prMsduInfo->prPacket); ++ ++/* printk(" hif: 0x%x %u %u %u\n", */ ++/* prMsduInfo->prPacket, StatsEnvTimeGet(), u8SysTime, GLUE_GET_PKT_XTIME(prMsduInfo->prPacket)); */ ++ ++ if ((u8SysTimeIn > 0) && (u8SysTime > u8SysTimeIn)) { ++ u8SysTime = u8SysTime - u8SysTimeIn; ++ u4TimeDiff = (UINT32) u8SysTime; ++ u4TimeDiff = u4TimeDiff / 1000; /* ns to us */ ++ ++ /* pass the delay between OS to us and we to HIF */ ++ if (u4TimeDiff > 0xFFFF) ++ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) 0xFFFF; /* 65535 us */ ++ else ++ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) u4TimeDiff; ++ ++/* printk(" u4TimeDiff: %u\n", u4TimeDiff); */ ++ } else { ++ prHwTxHeader->aucReserved[0] = 0; ++ prHwTxHeader->aucReserved[1] = 0; ++ } ++} ++ ++static VOID statsParsePktInfo(PUINT_8 pucPkt, UINT_8 status, UINT_8 eventType, P_MSDU_INFO_T prMsduInfo) ++{ ++ /* get ethernet protocol */ ++ UINT_16 u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); ++ PUINT_8 pucEthBody = &pucPkt[ETH_HLEN]; ++ ++ switch (u2EtherType) { ++ case ETH_P_ARP: ++ { ++ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; ++ if (eventType == EVENT_TX) ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ if ((su2TxDoneCfg & CFG_ARP) == 0) ++ break; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(RX, INFO, " Arp Req From IP: %d.%d.%d.%d\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(RX, INFO, " Arp Rsp from IP: %d.%d.%d.%d\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ break; ++ case EVENT_TX: ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", status, ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", status, ++ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); ++ break; ++ } ++ break; ++ } ++ case ETH_P_IP: ++ { ++ UINT_8 ucIpProto = pucEthBody[9]; /* IP header without options */ ++ UINT_8 ucIpVersion = (pucEthBody[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ UINT_16 u2IpId = pucEthBody[4]<<8 | pucEthBody[5]; ++ ++ if (ucIpVersion != IPVERSION) ++ break; ++ ++ switch (ucIpProto) { ++ case IP_PRO_ICMP: ++ { ++ /* the number of ICMP packets is seldom so we print log here */ ++ UINT_8 ucIcmpType; ++ UINT_16 u2IcmpId, u2IcmpSeq; ++ PUINT_8 pucIcmp = &pucEthBody[20]; ++ ++ ucIcmpType = pucIcmp[0]; ++ /* don't log network unreachable packet */ ++ if (((su2TxDoneCfg & CFG_ICMP) == 0) || ucIcmpType == 3) ++ break; ++ u2IcmpId = *(UINT_16 *) &pucIcmp[4]; ++ u2IcmpSeq = *(UINT_16 *) &pucIcmp[6]; ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " ICMP: Type %d, Id BE 0x%04x, Seq BE 0x%04x\n", ++ ucIcmpType, u2IcmpId, u2IcmpSeq); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " ICMP: Type %d, Id 0x04%x, Seq BE 0x%04x\n", ++ ucIcmpType, u2IcmpId, u2IcmpSeq); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " Type %d, Id 0x%04x, Seq 0x%04x\n", ++ status, ucIcmpType, u2IcmpId, u2IcmpSeq); ++ break; ++ } ++ break; ++ } ++ case IP_PRO_UDP: ++ { ++ /* the number of DHCP packets is seldom so we print log here */ ++ PUINT_8 pucUdp = &pucEthBody[20]; ++ PUINT_8 pucUdpPayload = &pucUdp[8]; ++ UINT_16 u2UdpDstPort; ++ UINT_16 u2UdpSrcPort; ++ ++ u2UdpDstPort = (pucUdp[2] << 8) | pucUdp[3]; ++ u2UdpSrcPort = (pucUdp[0] << 8) | pucUdp[1]; ++ /* dhcp */ ++ if ((u2UdpDstPort == UDP_PORT_DHCPS) || (u2UdpDstPort == UDP_PORT_DHCPC)) { ++ UINT_32 u4TransID = pucUdpPayload[4]<<24 | pucUdpPayload[5]<<16 | ++ pucUdpPayload[6]<<8 | pucUdpPayload[7]; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", ++ u2IpId, pucUdpPayload[0], u4TransID); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", ++ u2IpId, pucUdpPayload[0], u4TransID); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, ++ " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", ++ status, u2IpId, pucUdpPayload[0], u4TransID); ++ break; ++ } ++ } else if (u2UdpDstPort == UDP_PORT_DNS) { /* tx dns */ ++ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; ++ if (eventType == EVENT_TX) ++ prMsduInfo->fgIsBasicRate = TRUE; ++ ++ if ((su2TxDoneCfg & CFG_DNS) == 0) ++ break; ++ if (eventType == EVENT_TX) { ++ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ } else if (eventType == EVENT_TX_DONE) ++ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", ++ status, u2IpId, u2TransId); ++ } else if (u2UdpSrcPort == UDP_PORT_DNS && eventType == EVENT_RX) { /* rx dns */ ++ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; ++ ++ if ((su2TxDoneCfg & CFG_DNS) == 0) ++ break; ++ DBGLOG(RX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); ++ } else if ((su2TxDoneCfg & CFG_UDP) != 0) { ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " UDP: IPID 0x%04x\n", u2IpId); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", u2IpId); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", status, u2IpId); ++ break; ++ } ++ } ++ break; ++ } ++ case IP_PRO_TCP: ++ if ((su2TxDoneCfg & CFG_TCP) == 0) ++ break; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " TCP: IPID 0x%04x\n", u2IpId); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", u2IpId); ++ prMsduInfo->fgNeedTxDoneStatus = TRUE; ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", status, u2IpId); ++ break; ++ } ++ break; ++ } ++ break; ++ } ++ case ETH_P_PRE_1X: ++ DBGLOG(RX, INFO, "pre-1x\n"); ++ case ETH_P_1X: ++ { ++ PUINT_8 pucEapol = pucEthBody; ++ UINT_8 ucEapolType = pucEapol[1]; ++ ++ switch (ucEapolType) { ++ case 0: /* eap packet */ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " EAP Packet: code %d, id %d, type %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7]); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7]); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", ++ status, pucEapol[4], pucEapol[5], pucEapol[7]); ++ break; ++ } ++ break; ++ case 1: /* eapol start */ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " EAPOL: start\n"); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " EAPOL: start\n"); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " EAPOL: start\n", status); ++ break; ++ } ++ break; ++ case 3: /* key */ ++ { ++ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", ++ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", ++ u2KeyInfo, ++ pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", ++ status, u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], ++ pucEapol[20], pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); ++ break; ++ } ++ ++ break; ++ } ++ } ++ break; ++ } ++ case ETH_WPI_1X: ++ { ++ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ ++ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; ++ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; ++ ++ switch (eventType) { ++ case EVENT_RX: ++ DBGLOG(RX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ ucSubType, u2Length, u2Seq); ++ break; ++ case EVENT_TX: ++ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ ucSubType, u2Length, u2Seq); ++ break; ++ case EVENT_TX_DONE: ++ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ status, ucSubType, u2Length, u2Seq); ++ break; ++ } ++ break; ++ } ++ } ++} ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display rx packet information. ++* ++* \param[in] pPkt Pointer to the packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsRxPktInfoDisplay(UINT_8 *pPkt) ++{ ++ statsParsePktInfo(pPkt, 0, EVENT_RX, NULL); ++#if 0 /* carefully! too many ARP */ ++ if (pucIpHdr[0] == 0x00) { /* ARP */ ++ UINT_8 *pucDstIp = (UINT_8 *) pucIpHdr; ++ ++ if (pucDstIp[7] == ARP_PRO_REQ) { ++ DBGLOG(RX, TRACE, " OS rx a arp req from %d.%d.%d.%d\n", ++ pucDstIp[14], pucDstIp[15], pucDstIp[16], pucDstIp[17]); ++ } else if (pucDstIp[7] == ARP_PRO_RSP) { ++ DBGLOG(RX, TRACE, " OS rx a arp rsp from %d.%d.%d.%d\n", ++ pucDstIp[24], pucDstIp[25], pucDstIp[26], pucDstIp[27]); ++ } ++ } ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display tx packet information. ++* ++* \param[in] pPkt Pointer to the packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_16 u2EtherTypeLen; ++ ++ u2EtherTypeLen = (pPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pPkt[ETH_TYPE_LEN_OFFSET + 1]); ++ statsParsePktInfo(pPkt, 0, EVENT_TX, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to handle display tx packet tx done information. ++* ++* \param[in] pPkt Pointer to the packet ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf) ++{ ++ EVENT_TX_DONE_STATUS_T *prTxDone; ++ ++ prTxDone = (EVENT_TX_DONE_STATUS_T *) pucEvtBuf; ++ /* ++ * Why 65 Bytes: ++ * 8B + wlanheader(40B) + hif_tx_header(16B) + 6B + 6B(LLC) - 12B ++ */ ++ statsParsePktInfo(&prTxDone->aucPktBuf[64], prTxDone->ucStatus, EVENT_TX_DONE, NULL); ++} ++ ++VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet) ++{ ++ if (fgSet) ++ su2TxDoneCfg |= u2Cfg; ++ else ++ su2TxDoneCfg &= ~u2Cfg; ++} ++ ++UINT_16 StatsGetCfgTxDone(VOID) ++{ ++ return su2TxDoneCfg; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c +new file mode 100644 +index 000000000000..67eccbda9fa8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c +@@ -0,0 +1,1170 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/swcr.c#1 ++*/ ++ ++/*! \file "swcr.c" ++ \brief ++ ++*/ ++ ++/* ++** Log: swcr.c ++ * ++ * 06 04 2012 tsaiyuan.hsu ++ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" ++ * resolve build waring for "WNM_UNIT_TEST not defined". ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 11 22 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * keep debug counter setting after wake up. ++ * ++ * 11 15 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * fix debug counters of rx in driver. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters of bb and ar for xlog. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters, eCurPsProf, for PS. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 08 31 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * remove obsolete code. ++ * ++ * 08 15 2011 tsaiyuan.hsu ++ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver ++ * add swcr in driver reg, 0x9fxx0000, to disable roaming . ++ * ++ * 05 11 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Fix dest type when GO packet copying. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 04 14 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Check the SW RFB free. Fix the compile warning.. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Fix Klockwork warning. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 01 11 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * Add swcr for test. ++ * ++* ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_SWCR ++ ++#ifdef __GNUC__ ++#pragma GCC diagnostic ignored "-Wformat" ++#endif ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if 0 ++SWCR_MOD_MAP_ENTRY_T g_arSwCrAllMaps[] = { ++ {SWCR_MAP_NUM(g_arRlmArSwCrMap), g_arRlmArSwCrMap}, /* 0x00nn */ ++ {0, NULL} ++}; ++#endif ++ ++UINT_32 g_au4SwCr[SWCR_CR_NUM]; /*: 0: command other: data */ ++ ++/* JB mDNS Filter*/ ++UINT_32 g_u4mDNSRXFilter = 0; /* [31] 0: stop 1: start, [3] IPv6 [2] IPv4 */ ++ ++static TIMER_T g_rSwcrDebugTimer; ++static BOOLEAN g_fgSwcrDebugTimer = FALSE; ++static UINT_32 g_u4SwcrDebugCheckTimeout; ++static ENUM_SWCR_DBG_TYPE_T g_ucSwcrDebugCheckType; ++static UINT_32 g_u4SwcrDebugFrameDumpType; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#define TEST_PS 1 ++ ++static const PFN_CMD_RW_T g_arSwCtrlCmd[] = { ++ swCtrlCmdCategory0, ++ swCtrlCmdCategory1 ++#if TEST_PS ++ , testPsCmdCategory0, testPsCmdCategory1 ++#endif ++#if CFG_SUPPORT_802_11V ++#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) ++ , testWNMCmdCategory0 ++#endif ++#endif ++}; ++ ++const PFN_SWCR_RW_T g_arSwCrModHandle[] = { ++ swCtrlSwCr, ++ NULL ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++enum { ++ SWCTRL_MAGIC, ++ SWCTRL_DEBUG, ++ SWCTRL_WIFI_VAR, ++ SWCTRL_ENABLE_INT, ++ SWCTRL_DISABLE_INT, ++ SWCTRL_TXM_INFO, ++ SWCTRL_RXM_INFO, ++ SWCTRL_DUMP_BSS, ++ SWCTRL_QM_INFO, ++ SWCTRL_DUMP_ALL_QUEUE_LEN, ++ SWCTRL_DUMP_MEM, ++ SWCTRL_TX_CTRL_INFO, ++ SWCTRL_DUMP_QUEUE, ++ SWCTRL_DUMP_QM_DBG_CNT, ++ SWCTRL_QM_DBG_CNT, ++ SWCTRL_RX_PKTS_DUMP, ++ SWCTRL_RX_MDNS_FILTER, ++ SWCTRL_CATA0_INDEX_NUM ++}; ++ ++enum { ++ SWCTRL_STA_INFO, ++ SWCTRL_DUMP_STA, ++ SWCTRL_STA_QUE_INFO, ++ SWCTRL_CATA1_INDEX_NUM ++}; ++ ++/* JB mDNS Filter*/ ++#define RX_MDNS_FILTER_START (1<<31) ++#define RX_MDNS_FILTER_IPV4 (1<<2) ++#define RX_MDNS_FILTER_IPV6 (1<<3) ++typedef enum _ENUM_SWCR_RX_MDNS_FILTER_CMD_T { ++ SWCR_RX_MDNS_FILTER_CMD_STOP = 0, ++ SWCR_RX_MDNS_FILTER_CMD_START, ++ SWCR_RX_MDNS_FILTER_CMD_ADD, ++ SWCR_RX_MDNS_FILTER_CMD_REMOVE, ++ SWCR_RX_MDNS_FILTER_NUM ++} ENUM_SWCR_RX_MDNS_FILTER_CMD_T; ++ ++#if TEST_PS ++enum { ++ TEST_PS_MAGIC, ++ TEST_PS_SETUP_BSS, ++ TEST_PS_ENABLE_BEACON, ++ TEST_PS_TRIGGER_BMC, ++ TEST_PS_SEND_NULL, ++ TEST_PS_BUFFER_BMC, ++ TEST_PS_UPDATE_BEACON, ++ TEST_PS_CATA0_INDEX_NUM ++}; ++ ++enum { ++ TEST_PS_STA_PS, ++ TEST_PS_STA_ENTER_PS, ++ TEST_PS_STA_EXIT_PS, ++ TEST_PS_STA_TRIGGER_PSPOLL, ++ TEST_PS_STA_TRIGGER_FRAME, ++ TEST_PS_CATA1_INDEX_NUM ++}; ++#endif ++ ++#if CFG_SUPPORT_802_11V ++#if WNM_UNIT_TEST ++enum { ++ TEST_WNM_TIMING_MEAS, ++ TEST_WNM_CATA0_INDEX_NUM ++}; ++#endif ++#endif ++ ++#define _SWCTRL_MAGIC 0x66201642 ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++void dumpQueue(P_ADAPTER_T prAdapter) ++{ ++ ++ P_TX_CTRL_T prTxCtrl; ++ P_QUE_MGT_T prQM; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 i; ++ UINT_32 j; ++ ++ DEBUGFUNC("dumpQueue"); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prQM = &prAdapter->rQM; ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ for (i = TC0_INDEX; i <= TC5_INDEX; i++) { ++ DBGLOG(SW4, INFO, "TC %u\n", i); ++ DBGLOG(SW4, INFO, "Max %u Free %u\n", ++ prTxCtrl->rTc.aucMaxNumOfBuffer[i], prTxCtrl->rTc.aucFreeBufferCount[i]); ++ ++ DBGLOG(SW4, INFO, "Average %u minReserved %u CurrentTcResource %u GuaranteedTcResource %u\n", ++ QM_GET_TX_QUEUE_LEN(prAdapter, i), ++ prQM->au4MinReservedTcResource[i], ++ prQM->au4CurrentTcResource[i], prQM->au4GuaranteedTcResource[i]); ++ ++ } ++ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { ++ DBGLOG(SW4, INFO, ++ "TC %u HeadStaIdx %u ForwardCount %u\n", i, prQM->au4HeadStaRecIndex[i], ++ prQM->au4ForwardCount[i]); ++ } ++ ++ DBGLOG(SW4, INFO, "BMC or unknown TxQueue Len %u\n", prQM->arTxQueue[0].u4NumElem); ++ DBGLOG(SW4, INFO, "Pending %d\n", prGlueInfo->i4TxPendingFrameNum); ++ DBGLOG(SW4, INFO, "Pending Security %d\n", prGlueInfo->i4TxPendingSecurityFrameNum); ++#if defined(LINUX) ++ for (i = 0; i < 4; i++) { ++ for (j = 0; j < CFG_MAX_TXQ_NUM; j++) { ++ DBGLOG(SW4, INFO, ++ "Pending Q[%u][%u] %d\n", i, j, prGlueInfo->ai4TxPendingFrameNumPerQueue[i][j]); ++ } ++ } ++#endif ++ ++ DBGLOG(SW4, INFO, " rFreeSwRfbList %u\n", prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ DBGLOG(SW4, INFO, " rReceivedRfbList %u\n", prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem); ++ DBGLOG(SW4, INFO, " rIndicatedRfbList %u\n", prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem); ++ DBGLOG(SW4, INFO, " ucNumIndPacket %u\n", prAdapter->rRxCtrl.ucNumIndPacket); ++ DBGLOG(SW4, INFO, " ucNumRetainedPacket %u\n", prAdapter->rRxCtrl.ucNumRetainedPacket); ++ ++} ++ ++void dumpSTA(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) ++{ ++ UINT_8 ucWTEntry; ++ UINT_32 i; ++ P_BSS_INFO_T prBssInfo; ++ ++ DEBUGFUNC("dumpSTA"); ++ ++ ASSERT(prStaRec); ++ ucWTEntry = prStaRec->ucWTEntry; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ASSERT(prBssInfo); ++ ++ DBGLOG(SW4, INFO, "Mac address: %pM Rcpi %u" "\n", prStaRec->aucMacAddr, prStaRec->ucRCPI); ++ ++ DBGLOG(SW4, INFO, "Idx %u Wtbl %u Used %u State %u Bss Phy 0x%x Sta DesiredPhy 0x%x\n", ++ prStaRec->ucIndex, ucWTEntry, ++ prStaRec->fgIsInUse, prStaRec->ucStaState, ++ prBssInfo->ucPhyTypeSet, prStaRec->ucDesiredPhyTypeSet); ++ ++ DBGLOG(SW4, INFO, "Sta Operation 0x%x DesiredNontHtRateSet 0x%x Mcs 0x%x u2HtCapInfo 0x%x\n", ++ prStaRec->u2OperationalRateSet, prStaRec->u2DesiredNonHTRateSet, prStaRec->ucMcsSet, ++ prStaRec->u2HtCapInfo); ++ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) ++ DBGLOG(SW4, INFO, "TC %u Queue Len %u\n", i, prStaRec->arTxQueue[i].u4NumElem); ++ ++ DBGLOG(SW4, INFO, "BmpDeliveryAC %x\n", prStaRec->ucBmpDeliveryAC); ++ DBGLOG(SW4, INFO, "BmpTriggerAC %x\n", prStaRec->ucBmpTriggerAC); ++ DBGLOG(SW4, INFO, "UapsdSpSupproted %u\n", prStaRec->fgIsUapsdSupported); ++ DBGLOG(SW4, INFO, "IsQoS %u\n", prStaRec->fgIsQoS); ++ DBGLOG(SW4, INFO, "AssocId %u\n", prStaRec->u2AssocId); ++ ++ DBGLOG(SW4, INFO, "fgIsInPS %u\n", prStaRec->fgIsInPS); ++ DBGLOG(SW4, INFO, "ucFreeQuota %u\n", prStaRec->ucFreeQuota); ++ DBGLOG(SW4, INFO, "ucFreeQuotaForDelivery %u\n", prStaRec->ucFreeQuotaForDelivery); ++ DBGLOG(SW4, INFO, "ucFreeQuotaForNonDelivery %u\n", prStaRec->ucFreeQuotaForNonDelivery); ++ ++#if 0 ++ DBGLOG(SW4, INFO, "IsQmmSup %u\n", prStaRec->fgIsWmmSupported); ++ DBGLOG(SW4, INFO, "IsUapsdSup %u\n", prStaRec->fgIsUapsdSupported); ++ DBGLOG(SW4, INFO, "AvailabaleDeliverPkts %u\n", prStaRec->ucAvailableDeliverPkts); ++ DBGLOG(SW4, INFO, "BmpDeliverPktsAC %u\n", prStaRec->u4BmpDeliverPktsAC); ++ DBGLOG(SW4, INFO, "BmpBufferAC %u\n", prStaRec->u4BmpBufferAC); ++ DBGLOG(SW4, INFO, "BmpNonDeliverPktsAC %u\n", prStaRec->u4BmpNonDeliverPktsAC); ++#endif ++ ++ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { ++ if (prStaRec->aprRxReorderParamRefTbl[i]) { ++ DBGLOG(SW4, INFO, ++ "RxReorder fgIsValid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->fgIsValid); ++ DBGLOG(SW4, INFO, "RxReorder Tid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->ucTid); ++ DBGLOG(SW4, INFO, ++ "RxReorder rReOrderQue Len: %u\n", ++ prStaRec->aprRxReorderParamRefTbl[i]->rReOrderQue.u4NumElem); ++ DBGLOG(SW4, INFO, ++ "RxReorder WinStart: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinStart); ++ DBGLOG(SW4, INFO, "RxReorder WinEnd: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinEnd); ++ DBGLOG(SW4, INFO, "RxReorder WinSize: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinSize); ++ } ++ } ++ ++} ++ ++VOID dumpBss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) ++{ ++ ++ DBGLOG(SW4, INFO, "SSID %s\n", prBssInfo->aucSSID); ++ DBGLOG(SW4, INFO, "OWN %pM\n", prBssInfo->aucOwnMacAddr); ++ DBGLOG(SW4, INFO, "BSSID %pM\n", prBssInfo->aucBSSID); ++ DBGLOG(SW4, INFO, "ucNetTypeIndex %u\n", prBssInfo->ucNetTypeIndex); ++ DBGLOG(SW4, INFO, "eConnectionState %u\n", prBssInfo->eConnectionState); ++ DBGLOG(SW4, INFO, "eCurrentOPMode %u\n", prBssInfo->eCurrentOPMode); ++ DBGLOG(SW4, INFO, "fgIsQBSS %u\n", prBssInfo->fgIsQBSS); ++ DBGLOG(SW4, INFO, "fgIsShortPreambleAllowed %u\n", prBssInfo->fgIsShortPreambleAllowed); ++ DBGLOG(SW4, INFO, "fgUseShortPreamble %u\n", prBssInfo->fgUseShortPreamble); ++ DBGLOG(SW4, INFO, "fgUseShortSlotTime %u\n", prBssInfo->fgUseShortSlotTime); ++ DBGLOG(SW4, INFO, "ucNonHTBasicPhyType %x\n", prBssInfo->ucNonHTBasicPhyType); ++ DBGLOG(SW4, INFO, "u2OperationalRateSet %x\n", prBssInfo->u2OperationalRateSet); ++ DBGLOG(SW4, INFO, "u2BSSBasicRateSet %x\n", prBssInfo->u2BSSBasicRateSet); ++ DBGLOG(SW4, INFO, "ucPhyTypeSet %x\n", prBssInfo->ucPhyTypeSet); ++ DBGLOG(SW4, INFO, "rStaRecOfClientList %d\n", prBssInfo->rStaRecOfClientList.u4NumElem); ++ DBGLOG(SW4, INFO, "u2CapInfo %x\n", prBssInfo->u2CapInfo); ++ DBGLOG(SW4, INFO, "u2ATIMWindow %x\n", prBssInfo->u2ATIMWindow); ++ DBGLOG(SW4, INFO, "u2AssocId %x\n", prBssInfo->u2AssocId); ++ DBGLOG(SW4, INFO, "ucDTIMPeriod %x\n", prBssInfo->ucDTIMPeriod); ++ DBGLOG(SW4, INFO, "ucDTIMCount %x\n", prBssInfo->ucDTIMCount); ++ DBGLOG(SW4, INFO, "fgIsNetAbsent %x\n", prBssInfo->fgIsNetAbsent); ++ DBGLOG(SW4, INFO, "eBand %d\n", prBssInfo->eBand); ++ DBGLOG(SW4, INFO, "ucPrimaryChannel %d\n", prBssInfo->ucPrimaryChannel); ++ DBGLOG(SW4, INFO, "ucHtOpInfo1 %d\n", prBssInfo->ucHtOpInfo1); ++ DBGLOG(SW4, INFO, "ucHtOpInfo2 %d\n", prBssInfo->u2HtOpInfo2); ++ DBGLOG(SW4, INFO, "ucHtOpInfo3 %d\n", prBssInfo->u2HtOpInfo3); ++ DBGLOG(SW4, INFO, "fgErpProtectMode %d\n", prBssInfo->fgErpProtectMode); ++ DBGLOG(SW4, INFO, "eHtProtectMode %d\n", prBssInfo->eHtProtectMode); ++ DBGLOG(SW4, INFO, "eGfOperationMode %d\n", prBssInfo->eGfOperationMode); ++ DBGLOG(SW4, INFO, "eRifsOperationMode %d\n", prBssInfo->eRifsOperationMode); ++ DBGLOG(SW4, INFO, "fgObssErpProtectMode %d\n", prBssInfo->fgObssErpProtectMode); ++ DBGLOG(SW4, INFO, "eObssHtProtectMode %d\n", prBssInfo->eObssHtProtectMode); ++ DBGLOG(SW4, INFO, "eObssGfProtectMode %d\n", prBssInfo->eObssGfOperationMode); ++ DBGLOG(SW4, INFO, "fgObssRifsOperationMode %d\n", prBssInfo->fgObssRifsOperationMode); ++ DBGLOG(SW4, INFO, "fgAssoc40mBwAllowed %d\n", prBssInfo->fgAssoc40mBwAllowed); ++ DBGLOG(SW4, INFO, "fg40mBwAllowed %d\n", prBssInfo->fg40mBwAllowed); ++ DBGLOG(SW4, INFO, "eBssSCO %d\n", prBssInfo->eBssSCO); ++ ++} ++ ++VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ UINT_32 i; ++ ++ DEBUGFUNC("swCtrlCmdCategory0"); ++ ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ i = 0; ++ ++ if (ucIndex >= SWCTRL_CATA0_INDEX_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ switch (ucIndex) { ++ case SWCTRL_DEBUG: ++#if DBG ++ aucDebugModule[ucOpt0] = (UINT_8) g_au4SwCr[1]; ++#endif ++ break; ++ case SWCTRL_WIFI_VAR: ++ break; ++ ++#if QM_DEBUG_COUNTER ++ case SWCTRL_DUMP_QM_DBG_CNT: ++ for (i = 0; i < QM_DBG_CNT_NUM; i++) ++ prAdapter->rQM.au4QmDebugCounters[i] = 0; ++ break; ++ case SWCTRL_QM_DBG_CNT: ++ prAdapter->rQM.au4QmDebugCounters[ucOpt0] = g_au4SwCr[1]; ++ ++ break; ++#endif ++#if CFG_RX_PKTS_DUMP ++ case SWCTRL_RX_PKTS_DUMP: ++ /* DBGLOG(SW4, INFO,("SWCTRL_RX_PKTS_DUMP: mask %x\n", g_au4SwCr[1])); */ ++ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = g_au4SwCr[1]; ++ break; ++#endif ++ case SWCTRL_RX_MDNS_FILTER: ++ { ++ UINT_32 u4rxfilter; ++ BOOLEAN fgUpdate = FALSE; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_STOP) { ++ g_u4mDNSRXFilter &= ~(RX_MDNS_FILTER_START); ++ ++ u4rxfilter = prAdapter->u4OsPacketFilter; ++ fgUpdate = TRUE; ++ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_START) { ++ g_u4mDNSRXFilter |= (RX_MDNS_FILTER_START); ++ ++ u4rxfilter = prAdapter->u4OsPacketFilter; ++ if ((g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV4) || ++ (g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV6)) { ++ u4rxfilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; ++ } ++ fgUpdate = TRUE; ++ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_ADD) { ++ if (ucOpt1 < 31) ++ g_u4mDNSRXFilter |= (1 << ucOpt1); ++ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_REMOVE) { ++ if (ucOpt1 < 31) ++ g_u4mDNSRXFilter &= ~(1 << ucOpt1); ++ } ++ ++ if (fgUpdate == TRUE) { ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SET_RX_FILTER, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, /* pfCmdDoneHandler */ ++ NULL, /* pfCmdTimeoutHandler */ ++ sizeof(UINT_32), /* u4SetQueryInfoLen */ ++ (PUINT_8)&u4rxfilter, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* un4SetQueryBufferLen */ ++ ); ++ } ++/* DBGLOG(SW4, INFO,("SWCTRL_RX_MDNS_FILTER: g_u4mDNSRXFilter %x ucOpt0 %x ucOpt1 %x fgUpdate %x u4rxfilter %x, */ ++/* rStatus %x\n", g_u4mDNSRXFilter, ucOpt0, ucOpt1, fgUpdate, u4rxfilter, rStatus)); */ ++ } ++ break; ++ default: ++ break; ++ } ++ } else { ++ switch (ucIndex) { ++ case SWCTRL_DEBUG: ++#if DBG ++ g_au4SwCr[1] = aucDebugModule[ucOpt0]; ++#endif ++ break; ++ case SWCTRL_MAGIC: ++ g_au4SwCr[1] = _SWCTRL_MAGIC; ++ /* DBGLOG(SW4, INFO, "BUILD TIME: %s %s\n", __DATE__, __TIME__); */ ++ break; ++ case SWCTRL_QM_INFO: ++ { ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ switch (ucOpt0) { ++ case 0: ++ g_au4SwCr[1] = (QM_GET_TX_QUEUE_LEN(prAdapter, ucOpt1)); ++ g_au4SwCr[2] = prQM->au4MinReservedTcResource[ucOpt1]; ++ g_au4SwCr[3] = prQM->au4CurrentTcResource[ucOpt1]; ++ g_au4SwCr[4] = prQM->au4GuaranteedTcResource[ucOpt1]; ++ break; ++ ++ case 1: ++ g_au4SwCr[1] = prQM->au4ForwardCount[ucOpt1]; ++ g_au4SwCr[2] = prQM->au4HeadStaRecIndex[ucOpt1]; ++ break; ++ ++ case 2: ++ g_au4SwCr[1] = prQM->arTxQueue[ucOpt1].u4NumElem; /* only one */ ++ ++ break; ++ } ++ ++ } ++ break; ++ case SWCTRL_TX_CTRL_INFO: ++ { ++ P_TX_CTRL_T prTxCtrl; ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ switch (ucOpt0) { ++ case 0: ++ g_au4SwCr[1] = prAdapter->rTxCtrl.rTc.aucFreeBufferCount[ucOpt1]; ++ g_au4SwCr[2] = prAdapter->rTxCtrl.rTc.aucMaxNumOfBuffer[ucOpt1]; ++ break; ++ } ++ ++ } ++ break; ++ case SWCTRL_DUMP_QUEUE: ++ dumpQueue(prAdapter); ++ ++ break; ++#if QM_DEBUG_COUNTER ++ case SWCTRL_DUMP_QM_DBG_CNT: ++ for (i = 0; i < QM_DBG_CNT_NUM; i++) ++ DBGLOG(SW4, INFO, "QM:DBG %u %u\n", i, prAdapter->rQM.au4QmDebugCounters[i]); ++ break; ++ ++ case SWCTRL_QM_DBG_CNT: ++ g_au4SwCr[1] = prAdapter->rQM.au4QmDebugCounters[ucOpt0]; ++ break; ++#endif ++ case SWCTRL_DUMP_BSS: ++ { ++ dumpBss(prAdapter, &(prAdapter->rWifiVar.arBssInfo[ucOpt0])); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ } ++} ++ ++VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ UINT_8 ucWTEntry; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("swCtrlCmdCategory1"); ++ ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ if (ucOpt0 >= CFG_STA_REC_NUM) ++ return; ++ ++ /* prStaRec = cnmGetStaRecByIndex (prAdapter, ucOpt0); */ ++ prStaRec = &prAdapter->arStaRec[ucOpt0]; ++ ucWTEntry = prStaRec->ucWTEntry; ++ if (ucRead == SWCR_WRITE) { ++ /* Do nothing */ ++ } else { ++ /* Read */ ++ switch (ucIndex) { ++ case SWCTRL_STA_QUE_INFO: ++ { ++ g_au4SwCr[1] = prStaRec->arTxQueue[ucOpt1].u4NumElem; ++ } ++ break; ++ case SWCTRL_STA_INFO: ++ switch (ucOpt1) { ++ case 0: ++ g_au4SwCr[1] = prStaRec->fgIsInPS; ++ break; ++ } ++ ++ break; ++ ++ case SWCTRL_DUMP_STA: ++ { ++ dumpSTA(prAdapter, prStaRec); ++ } ++ break; ++ ++ default: ++ ++ break; ++ } ++ } ++ ++} ++ ++#if TEST_PS ++ ++VOID ++testPsSendQoSNullFrame(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, ++ IN UINT_8 ucUP, ++ IN UINT_8 ucNetTypeIndex, ++ IN BOOLEAN fgBMC, ++ IN BOOLEAN fgIsBurstEnd, IN BOOLEAN ucPacketType, IN BOOLEAN ucPsSessionID, IN BOOLEAN fgSetEOSP) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_16 u2EstimatedFrameLen; ++ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; ++ ++ DEBUGFUNC("testPsSendQoSNullFrame"); ++ DBGLOG(SW4, LOUD, "\n"); ++ ++ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ ++ /* Init with MGMT Header Length */ ++ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; ++ ++ /* Allocate a MSDU_INFO_T */ ++ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); ++ if (prMsduInfo == NULL) { ++ DBGLOG(SW4, WARN, "No PKT_INFO_T for sending Null Frame.\n"); ++ return; ++ } ++ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ ++ bssComposeQoSNullFrame(prAdapter, ++ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), ++ prStaRec, ucUP, fgSetEOSP); ++ ++ prMsduInfo->eSrc = TX_PACKET_MGMT; ++ /* prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; */ ++ prMsduInfo->ucPacketType = ucPacketType; ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = NULL; ++ prMsduInfo->fgIsBasicRate = TRUE; ++ prMsduInfo->fgIsBurstEnd = fgIsBurstEnd; ++ prMsduInfo->ucUserPriority = ucUP; ++ prMsduInfo->ucPsSessionID = ucPsSessionID /* 0~7 Test 7 means NOACK */; ++ ++ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) (((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD)); ++ ++ if (fgBMC) ++ prQoSNullFrame->aucAddr1[0] = 0xfd; ++ else ++ prQoSNullFrame->aucAddr1[5] = 0xdd; ++ ++ /* 4 <4> Inform TXM to send this Null frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++} ++ ++VOID testPsSetupBss(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetworkTypeIndex) ++{ ++ P_BSS_INFO_T prBssInfo; ++ UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; ++ ++ DEBUGFUNC("testPsSetupBss()"); ++ DBGLOG(SW4, INFO, "index %d\n", ucNetworkTypeIndex); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetworkTypeIndex]); ++ ++ /* 4 <1.2> Initiate PWR STATE */ ++ /* SET_NET_PWR_STATE_IDLE(prAdapter, ucNetworkTypeIndex); */ ++ ++ /* 4 <2> Initiate BSS_INFO_T - common part */ ++ BSS_INFO_INIT(prAdapter, ucNetworkTypeIndex); ++ ++ prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; ++ prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; ++ prBssInfo->eCurrentOPMode = OP_MODE_ACCESS_POINT; ++ prBssInfo->fgIsNetActive = TRUE; ++ prBssInfo->ucNetTypeIndex = (ucNetworkTypeIndex); ++ prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; ++ ++ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; /* Depend on eBand */ ++ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ ++ prBssInfo->u2BSSBasicRateSet = RATE_SET_ERP; ++ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; ++ prBssInfo->fgErpProtectMode = FALSE; ++ prBssInfo->fgIsQBSS = TRUE; ++ ++ /* 4 <1.5> Setup MIB for current BSS */ ++ prBssInfo->u2BeaconInterval = 100; ++ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; ++ prBssInfo->u2ATIMWindow = 0; ++ ++ prBssInfo->ucBeaconTimeoutCount = 0; ++ ++ bssInitForAP(prAdapter, prBssInfo, TRUE); ++ ++ COPY_MAC_ADDR(prBssInfo->aucBSSID, _aucZeroMacAddr); ++ LINK_INITIALIZE(&prBssInfo->rStaRecOfClientList); ++ prBssInfo->fgIsBeaconActivated = TRUE; ++ prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; ++ ++ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); ++ ++ /* 4 <3> Initiate BSS_INFO_T - private part */ ++ /* TODO */ ++ prBssInfo->eBand = BAND_2G4; ++ prBssInfo->ucPrimaryChannel = 1; ++ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; ++ ++ /* prBssInfo->fgErpProtectMode = eErpProectMode; */ ++ /* prBssInfo->eHtProtectMode = eHtProtectMode; */ ++ /* prBssInfo->eGfOperationMode = eGfOperationMode; */ ++ ++ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ ++ prBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); ++ ++ if (prBssInfo->prBeacon) { ++ prBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; ++ prBssInfo->prBeacon->ucNetworkType = ucNetworkTypeIndex; ++ } else { ++ DBGLOG(SW4, INFO, "prBeacon allocation fail\n"); ++ } ++ ++#if 0 ++ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; ++ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; ++ prBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; ++#else ++ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; ++ prBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; ++#endif ++ ++#if 0 ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prBssInfo->arACQueParms[eAci].fgIsACMSet = FALSE; ++ prBssInfo->arACQueParms[eAci].u2Aifsn = (UINT_16) eAci; ++ prBssInfo->arACQueParms[eAci].u2CWmin = 7; ++ prBssInfo->arACQueParms[eAci].u2CWmax = 31; ++ prBssInfo->arACQueParms[eAci].u2TxopLimit = eAci + 1; ++ DBGLOG(SW4, INFO, "MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", ++ eAci, prBssInfo->arACQueParms[eAci].fgIsACMSet, ++ prBssInfo->arACQueParms[eAci].u2Aifsn, ++ prBssInfo->arACQueParms[eAci].u2CWmin, ++ prBssInfo->arACQueParms[eAci].u2CWmax, prBssInfo->arACQueParms[eAci].u2TxopLimit)); ++ ++ } ++#endif ++ ++ DBGLOG(SW4, INFO, "[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", ++ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, ++ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, prBssInfo->rPmProfSetupInfo.ucUapsdSp); ++ ++} ++ ++VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("testPsCmdCategory0"); ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ DBGLOG(SW4, LOUD, "Read %u Index %u\n", ucRead, ucIndex); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, 0); ++ ++ if (ucIndex >= TEST_PS_CATA0_INDEX_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ switch (ucIndex) { ++ case TEST_PS_SETUP_BSS: ++ testPsSetupBss(prAdapter, ucOpt0); ++ break; ++ ++ case TEST_PS_ENABLE_BEACON: ++ break; ++ ++ case TEST_PS_TRIGGER_BMC: ++ /* txmForwardQueuedBmcPkts (ucOpt0); */ ++ break; ++ case TEST_PS_SEND_NULL: ++ { ++ ++ testPsSendQoSNullFrame(prAdapter, prStaRec, (UINT_8) (g_au4SwCr[1] & 0xFF), /* UP */ ++ ucOpt0, (BOOLEAN) ((g_au4SwCr[1] >> 8) & 0xFF), /* BMC */ ++ (BOOLEAN) ((g_au4SwCr[1] >> 16) & 0xFF), /* BurstEnd */ ++ (BOOLEAN) ((g_au4SwCr[1] >> 24) & 0xFF), /* Packet type */ ++ (UINT_8) ((g_au4SwCr[2]) & 0xFF), /* PS sesson ID 7: NOACK */ ++ FALSE /* EOSP */ ++ ); ++ } ++ break; ++ case TEST_PS_BUFFER_BMC: ++ /* g_aprBssInfo[ucOpt0]->fgApToBufferBMC = (g_au4SwCr[1] & 0xFF); */ ++ break; ++ case TEST_PS_UPDATE_BEACON: ++ bssUpdateBeaconContent(prAdapter, ucOpt0 /*networktype */); ++ break; ++ ++ default: ++ break; ++ } ++ } else { ++ switch (ucIndex) { ++ ++ case TEST_PS_MAGIC: ++ g_au4SwCr[1] = 0x88660011; ++ break; ++ ++ } ++ } ++} ++ ++#endif /* TEST_PS */ ++ ++#if TEST_PS ++ ++VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ UINT_8 ucWTEntry; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("testPsCmdCategory1"); ++ ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ if (ucOpt0 >= CFG_STA_REC_NUM) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucOpt0); ++ if (!prStaRec) ++ return; ++ ucWTEntry = prStaRec->ucWTEntry; ++ if (ucRead == SWCR_WRITE) { ++ ++ switch (ucIndex) { ++ case TEST_PS_STA_PS: ++ prStaRec->fgIsInPS = (BOOLEAN) (g_au4SwCr[1] & 0x1); ++ prStaRec->fgIsQoS = (BOOLEAN) (g_au4SwCr[1] >> 8 & 0xFF); ++ prStaRec->fgIsUapsdSupported = (BOOLEAN) (g_au4SwCr[1] >> 16 & 0xFF); ++ prStaRec->ucBmpDeliveryAC = (BOOLEAN) (g_au4SwCr[1] >> 24 & 0xFF); ++ break; ++ ++ } ++ ++ } else { ++ /* Read */ ++ switch (ucIndex) { ++ default: ++ break; ++ } ++ } ++ ++} ++ ++#endif /* TEST_PS */ ++ ++#if CFG_SUPPORT_802_11V ++#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) ++VOID testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) ++{ ++ UINT_8 ucIndex, ucRead; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("testWNMCmdCategory0"); ++ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); ++ ++ DBGLOG(SW4, INFO, "Read %u Index %u\n", ucRead, ucIndex); ++ ++ if (ucIndex >= TEST_WNM_CATA0_INDEX_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ switch (ucIndex) { ++ case TEST_WNM_TIMING_MEAS: ++ wnmTimingMeasUnitTest1(prAdapter, ucOpt0); ++ break; ++ ++ default: ++ break; ++ } ++ } ++} ++#endif /* TEST_WNM */ ++#endif /* CFG_SUPPORT_802_11V */ ++ ++VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) ++{ ++ /* According other register STAIDX */ ++ UINT_8 ucOffset; ++ ++ ucOffset = (u2Addr >> 2) & 0x3F; ++ ++ if (ucOffset >= SWCR_CR_NUM) ++ return; ++ ++ if (ucRead == SWCR_WRITE) { ++ g_au4SwCr[ucOffset] = *pu4Data; ++ if (ucOffset == 0x0) { ++ /* Commmand [31:24]: Category */ ++ /* Commmand [23:23]: 1(W) 0(R) */ ++ /* Commmand [22:16]: Index */ ++ /* Commmand [15:08]: Option0 */ ++ /* Commmand [07:00]: Option1 */ ++ UINT_8 ucCate; ++ UINT_32 u4Cmd; ++ ++ u4Cmd = g_au4SwCr[0]; ++ ucCate = (UINT_8) (u4Cmd >> 24); ++ if (ucCate < sizeof(g_arSwCtrlCmd) / sizeof(g_arSwCtrlCmd[0])) { ++ if (g_arSwCtrlCmd[ucCate] != NULL) { ++ g_arSwCtrlCmd[ucCate] (prAdapter, ucCate, (UINT_8) (u4Cmd >> 16 & 0xFF), ++ (UINT_8) ((u4Cmd >> 8) & 0xFF), (UINT_8) (u4Cmd & 0xFF)); ++ } ++ } ++ } ++ } else { ++ *pu4Data = g_au4SwCr[ucOffset]; ++ } ++} ++ ++VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) ++{ ++ UINT_8 ucMod; ++ ++ ucMod = u2Addr >> 8; ++ /* Address [15:8] MOD ID */ ++ /* Address [7:0] OFFSET */ ++ ++ DEBUGFUNC("swCrReadWriteCmd"); ++ DBGLOG(SW4, TRACE, "%u addr 0x%x data 0x%x\n", ucRead, u2Addr, *pu4Data); ++ ++ if (ucMod < (sizeof(g_arSwCrModHandle) / sizeof(g_arSwCrModHandle[0]))) { ++ ++ if (g_arSwCrModHandle[ucMod] != NULL) ++ g_arSwCrModHandle[ucMod] (prAdapter, ucRead, u2Addr, pu4Data); ++ } /* ucMod */ ++} ++ ++/* Debug Support */ ++VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType) ++{ ++ g_u4SwcrDebugFrameDumpType = u4DumpType; ++ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = u4DumpType; ++} ++ ++VOID swCrDebugInit(P_ADAPTER_T prAdapter) ++{ ++ /* frame dump */ ++ if (g_u4SwcrDebugFrameDumpType) ++ swCrFrameCheckEnable(prAdapter, g_u4SwcrDebugFrameDumpType); ++ /* debug counter */ ++ g_fgSwcrDebugTimer = FALSE; ++ ++ cnmTimerInitTimer(prAdapter, &g_rSwcrDebugTimer, (PFN_MGMT_TIMEOUT_FUNC) swCrDebugCheckTimeout, (ULONG) NULL); ++ ++ if (g_u4SwcrDebugCheckTimeout) ++ swCrDebugCheckEnable(prAdapter, TRUE, g_ucSwcrDebugCheckType, g_u4SwcrDebugCheckTimeout); ++} ++ ++VOID swCrDebugUninit(P_ADAPTER_T prAdapter) ++{ ++ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); ++ ++ g_fgSwcrDebugTimer = FALSE; ++} ++ ++VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout) ++{ ++ if (fgIsEnable) { ++ g_ucSwcrDebugCheckType = ucType; ++ g_u4SwcrDebugCheckTimeout = u4Timeout; ++ if (g_fgSwcrDebugTimer == FALSE) ++ swCrDebugCheckTimeout(prAdapter, 0); ++ } else { ++ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); ++ g_u4SwcrDebugCheckTimeout = 0; ++ } ++ ++ g_fgSwcrDebugTimer = fgIsEnable; ++} ++ ++VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ /* dump counters */ ++ if (prCmdSwCtrl) { ++ if (prCmdSwCtrl->u4Data == SWCR_DBG_TYPE_ALL) { ++ ++ /* TX Counter from fw */ ++ DBGLOG(SW4, INFO, "TX0\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_BCN_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_FAILED_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_RETRY_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_MGNT_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_ERROR_CNT]); ++#if 1 ++ /* TX Counter from drv */ ++ DBGLOG(SW4, INFO, "TX1\n" ++ "%08x %08x %08x %08x\n", ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_BSS_DROP), ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_STA_DROP), ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_FORWARD_OVERFLOW_DROP), ++ (UINT_32) TX_GET_CNT(prTxCtrl, TX_AP_BORADCAST_DROP)); ++#endif ++ ++ /* RX Counter */ ++ DBGLOG(SW4, INFO, "RX0\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DUP_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FCSERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FIFOFULL_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_PFDROP_CNT]); ++ ++ DBGLOG(SW4, INFO, "RX1\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT), ++ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT)); ++ ++ DBGLOG(SW4, INFO, "PWR\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PS_POLL_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_IND_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE0], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE1], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF0], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF1]); ++ ++ DBGLOG(SW4, INFO, "ARM\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RATE], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_BWGI], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ENABLE], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ROAM_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_INT_CNT]); ++ ++ DBGLOG(SW4, INFO, "BB\n" ++ "%08x %08x %08x %08x\n" ++ "%08x %08x %08x %08x\n", ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_MDRDY_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_FCSERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_PD_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_PD_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SFDERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SIGERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT], ++ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT]); ++ ++ } ++ } ++ /* start the next check */ ++ if (g_u4SwcrDebugCheckTimeout) ++ cnmTimerStartTimer(prAdapter, &g_rSwcrDebugTimer, g_u4SwcrDebugCheckTimeout * MSEC_PER_SEC); ++} ++ ++VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ WLAN_STATUS rStatus; ++ ++ rCmdSwCtrl.u4Id = (0xb000 << 16) + g_ucSwcrDebugCheckType; ++ rCmdSwCtrl.u4Data = 0; ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_SW_DBG_CTRL, /* ucCID */ ++ FALSE, /* fgSetQuery */ ++ TRUE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ swCrDebugQuery, /* pfCmdDoneHandler */ ++ swCrDebugQueryTimeout, /* pfCmdTimeoutHandler */ ++ sizeof(CMD_SW_DBG_CTRL_T), /* u4SetQueryInfoLen */ ++ (PUINT_8)&rCmdSwCtrl, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ ASSERT(rStatus == WLAN_STATUS_PENDING); ++ ++} ++ ++VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ++ swCrDebugCheck(prAdapter, (P_CMD_SW_DBG_CTRL_T) (pucEventBuf)); ++} ++ ++VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ++ swCrDebugCheck(prAdapter, NULL); ++} ++ ++#endif /* CFG_SUPPORT_SWCR */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c +new file mode 100644 +index 000000000000..96293c57e2b0 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c +@@ -0,0 +1,5199 @@ ++/* ++** Id: tdls.c#1 ++*/ ++ ++/*! \file tdls.c ++ \brief This file includes IEEE802.11z TDLS support. ++*/ ++ ++/* ++** Log: tdls.c ++ * ++ * 11 13 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++#include "precomp.h" ++ ++#if (CFG_SUPPORT_TDLS == 1) ++#include "gl_wext.h" ++#include "tdls.h" ++#include "gl_cfg80211.h" ++#include ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb); ++ ++#if TDLS_CFG_CMD_TEST ++static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static TDLS_STATUS ++TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd); ++ ++static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param); ++ ++static TDLS_STATUS ++TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++ ++static TDLS_STATUS ++TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static VOID ++TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, ++ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers); ++ ++static VOID ++TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, ++ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo); ++ ++static TDLS_STATUS ++TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static TDLS_STATUS ++TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); ++ ++static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); ++ ++#endif /* TDLS_CFG_CMD_TEST */ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static BOOLEAN fgIsPtiTimeoutSkip = FALSE; ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to indicate packets to upper layer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prSkb A pointer to the received packet ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb) ++{ ++ struct net_device *prNetDev; ++ ++ /* init */ ++ prNetDev = prGlueInfo->prDevHandler; ++ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; ++ prGlueInfo->rNetDevStats.rx_packets++; ++ ++ /* pass to upper layer */ ++ //prNetDev->last_rx = jiffies; ++ prSkb->protocol = eth_type_trans(prSkb, prNetDev); ++ prSkb->dev = prNetDev; ++ ++ if (!in_interrupt()) ++ netif_rx_ni(prSkb); /* only in non-interrupt context */ ++ else ++ netif_rx(prSkb); ++} ++ ++#if TDLS_CFG_CMD_TEST ++ ++#define LR_TDLS_FME_FIELD_FILL(__Len) \ ++do { \ ++ pPkt += __Len; \ ++ u4PktLen += __Len; \ ++} while (0) ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to add a TDLS peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_2_[Responder MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_2_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ struct wireless_dev *prWdev; ++ ++ /* reset */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); ++ ++ /* init */ ++ rCmd.rPeerInfo.supported_rates = NULL; ++ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; ++ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ ++ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); ++ ++ /* send command to wifi task to handle */ ++ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; ++ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_16_[Enable/Disable]_[Set/Clear] ++ ++ iwpriv wlan0 set_str_cmd 0_16_1_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ TDLS_CMD_CORE_T rCmd; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); ++ ++ /* command to do this */ ++ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; ++ ++ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; ++ aucTdlsTestExtCapElm[1] = 5; ++ aucTdlsTestExtCapElm[2] = 0; ++ aucTdlsTestExtCapElm[3] = 0; ++ aucTdlsTestExtCapElm[4] = 0; ++ aucTdlsTestExtCapElm[5] = 0; ++ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 7); /* bit39 */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a channel switch request from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_5_[TDLS Peer MAC]_[Chan]_[RegulatoryClass]_ ++ [SecondaryChannelOffset]_[SwitchTime]_[SwitchTimeout] ++ ++ iwpriv wlan0 set_str_cmd 0_1_5_00:11:22:33:44:01_1_255_0_15000_30000 ++ ++ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) ++ Secondary Channel Offset: 0 (SCN - no secondary channel) ++ 1 (SCA - secondary channel above) ++ 2 (SCB - secondary channel below) ++ SwitchTime: units of microseconds ++ ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdChStReqRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4RegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4SecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s:[%pM]u4Chan=%u u4RegClass=%u u4SecChanOff=%u u4SwitchTime=%u u4SwitchTimeout=%u\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4Chan, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4RegClass, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SecChanOff, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTime, ++ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestChStReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a channel switch response from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_6_[TDLS Peer MAC]_[Chan]_ ++ [SwitchTime]_[SwitchTimeout]_[StatusCode] ++ ++ iwpriv wlan0 set_str_cmd 0_1_6_00:11:22:33:44:01_11_15000_30000_0 ++ ++ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) ++ Secondary Channel Offset: 0 (SCN - no secondary channel) ++ 1 (SCA - secondary channel above) ++ 2 (SCB - secondary channel below) ++ SwitchTime: units of microseconds ++ ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdChStRspRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStRspRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChStRspRcv.u4StatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4Chan=%u u4SwitchTime=%u u4SwitchTimeout=%u u4StatusCode=%u\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4Chan, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTime, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout, ++ (UINT32) rCmd.Content.rCmdChStRspRcv.u4StatusCode); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestChStRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip channel switch timeout function. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_11_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsTestChSwTimeoutSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a data frame to the peer periodically. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TIMER_T rTdlsTimerTestDataSend; ++static UINT_8 aucTdlsTestDataSPeerMac[6]; ++static UINT_16 u2TdlsTestDataSInterval; ++ ++static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ BOOLEAN fgIsEnabled; ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucTdlsTestDataSPeerMac); ++ u2TdlsTestDataSInterval = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ fgIsEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); ++ ++ if (fgIsEnabled == FALSE) { ++ /* stop test timer */ ++ return; ++ } ++ ++ /* re-init test timer */ ++ cnmTimerInitTimer(prAdapter, ++ &rTdlsTimerTestDataSend, (PFN_MGMT_TIMEOUT_FUNC) TdlsTimerTestDataContSend, (ULONG) NULL); ++ ++ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a data frame from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_0_x80_[TDLS Peer MAC]_[PM]_[UP]_[EOSP]_[IsNull] ++ ++ iwpriv wlan0 set_str_cmd 0_1_x80_00:11:22:33:44:01_0_0_0_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ rCmd.Content.rCmdDatRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdDatRcv.u4UP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdDatRcv.u4EOSP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdDatRcv.u4IsNull = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: [%pM] PM(%u) UP(%u) EOSP(%u) NULL(%u)\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdDatRcv.u4PM, ++ (UINT32) rCmd.Content.rCmdDatRcv.u4UP, ++ (UINT32) rCmd.Content.rCmdDatRcv.u4EOSP, (UINT32) rCmd.Content.rCmdDatRcv.u4IsNull); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestDataRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a data frame to the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_4_[Responder MAC]_[tx status] ++ ++ iwpriv wlan0 set_str_cmd 0_4_00:11:22:33:44:01_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ P_ADAPTER_T prAdapter; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *prPkt; ++ UINT_8 MAC[6]; ++ UINT_8 ucTxStatus; ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, MAC); ++ ucTxStatus = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ /* allocate a data frame */ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); ++ return; ++ } ++ ++ /* init dev */ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* init packet */ ++ prMsduInfo->len = 1000; ++ kalMemZero(prMsduInfo->data, 100); /* for QoS field */ ++ kalMemCopy(prMsduInfo->data, MAC, 6); ++ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); ++ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; ++ ++ /* simulate OS to send the packet */ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_16_[mili seconds] ++ ++ iwpriv wlan0 set_str_cmd 0_19_1000 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ UINT32 u4Delay; ++ ++ u4Delay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, "%s: Delay = %d\n", __func__, u4Delay); ++ ++ kalMdelay(u4Delay); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test discovery request frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_10_[DialogToken]_[Peer MAC]_[BSSID] ++ ++ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01 ++ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01_00:22:33:44:11:22 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); ++ kalMemZero(aucBSSID, sizeof(aucBSSID)); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_DISCOVERY_REQ; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; ++ ++ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ else ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip keep alive function. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_10_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_10_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsTestKeepAliveSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]_[Set/Clear] ++ ++ iwpriv wlan0 set_str_cmd 0_13_1_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ TDLS_CMD_CORE_T rCmd; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); ++ ++ /* command to do this */ ++ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; ++ ++ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; ++ aucTdlsTestExtCapElm[1] = 5; ++ aucTdlsTestExtCapElm[2] = 0; ++ aucTdlsTestExtCapElm[3] = 0; ++ aucTdlsTestExtCapElm[4] = 0; ++ aucTdlsTestExtCapElm[5] = 0; ++ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 6); /* bit38 */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI request from the AP. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_4_[TDLS Peer MAC]_[Dialog Token] ++ ++ iwpriv wlan0 set_str_cmd 0_1_4_00:11:22:33:44:01_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4DialogToken = %u\n", ++ __func__, rCmd.aucPeerMac, (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI response from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_9_[TDLS Peer MAC]_[Dialog Token]_[PM] ++ ++ iwpriv wlan0 set_str_cmd 0_1_9_00:11:22:33:44:01_0_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdPtiRspRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [%pM] u4DialogToken = %u %u\n", ++ __func__, rCmd.aucPeerMac, ++ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken, ++ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4PM); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to simulate PTI tx done fail case. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_21_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_21_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdPtiTxFail.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdPtiTxFail.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiTxFail, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test frame. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++/* PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; */ ++/* TDLS_STATUS u4Status; */ ++ UINT_32 u4Subcmd; ++/* UINT_32 u4BufLen; */ ++ ++ /* parse sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " test rv frame sub command = %u\n", (UINT32) u4Subcmd); ++ ++ /* parse command arguments */ ++ switch (u4Subcmd) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ /* simulate to receive a setup request frame */ ++ TdlsCmdTestSetupReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ /* simulate to receive a setup response frame */ ++ TdlsCmdTestSetupRspRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_CONFIRM: ++ /* simulate to receive a setup confirm frame */ ++ TdlsCmdTestSetupConfirmRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_TEARDOWN: ++ /* simulate to receive a tear down frame */ ++ TdlsCmdTestTearDownRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_PTI: ++ /* simulate to receive a PTI request frame */ ++ TdlsCmdTestPtiReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_PTI_RSP: ++ /* simulate to receive a PTI response frame */ ++ TdlsCmdTestPtiRspRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_DATA_TEST_DATA: ++ /* simulate to receive a DATA frame */ ++ TdlsCmdTestDataRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_CHAN_SWITCH_REQ: ++ /* simulate to receive a channel switch request frame */ ++ TdlsCmdTestChSwReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_CHAN_SWITCH_RSP: ++ /* simulate to receive a channel switch response frame */ ++ TdlsCmdTestChSwRspRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ case TDLS_FRM_ACTION_DISCOVERY_REQ: ++ /* simulate to receive a discovery request frame */ ++ TdlsCmdTestDiscoveryReqRecv(prGlueInfo, prInBuf, u4InBufLen); ++ break; ++ ++ default: ++ DBGLOG(TDLS, ERROR, " wrong test rv frame sub command\n"); ++ return; ++ } ++ ++/* if (u4Status != TDLS_STATUS_SUCCESS) */ ++ { ++/* DBGLOG(TDLS, ERROR, (" command parse fail\n")); */ ++/* return; */ ++ } ++ ++ /* send command to wifi task to handle */ ++#if 0 ++ kalIoctl(prGlueInfo, ++ TdlsTestFrameSend, ++ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test setup confirm frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_2_[DialogToken]_[StatusCode]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_1_2_1_0_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d StatusCode=%d from %pM\n", ++ __func__, ucDialogToken, ucStatusCode, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_CONFIRM; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Status Code */ ++ *pPkt = ucStatusCode; ++ *(pPkt + 1) = 0x00; ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 3. Frame Formation - (4) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (17) WMM Information element */ ++ if (prAdapter->rWifiVar.fgSupportQoS) { ++ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test setup request frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_0_[DialogToken]_[Peer MAC]_[BSSID] ++ ++ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01 ++ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01_00:22:33:44:11:22 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; ++ UINT_16 u2CapInfo; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); ++ kalMemZero(aucBSSID, sizeof(aucBSSID)); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_SETUP_REQ; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (4) Capability */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); ++ WLAN_SET_FIELD_16(pPkt, u2CapInfo); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (10) Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ /* TDLS_EX_CAP_PEER_UAPSD */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ /* TDLS_EX_CAP_CHAN_SWITCH */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ /* TDLS_EX_CAP_TDLS */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; ++ ++ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ else ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test setup response frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_1_[DialogToken]_[StatusCode]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_1_1_1_0_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; ++ UINT_16 u2CapInfo; ++ ++ /* parse arguments */ ++ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: DialogToken=%d StatusCode=%d from %pM\n", ++ __func__, ucDialogToken, ucStatusCode, aucPeerMac); ++ ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_SETUP_RSP; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Status Code */ ++ *pPkt = ucStatusCode; ++ *(pPkt + 1) = 0x00; ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 3. Frame Formation - (4) Dialog token */ ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (5) Capability */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); ++ WLAN_SET_FIELD_16(pPkt, u2CapInfo); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (10) Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ /* TDLS_EX_CAP_PEER_UAPSD */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ /* TDLS_EX_CAP_CHAN_SWITCH */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ /* TDLS_EX_CAP_TDLS */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip channel switch timeout function. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_14_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_14_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdScanSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdScanSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestScanSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a test tear down frame command. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_1_3_[IsInitiator]_[ReasonCode]_[Peer MAC]_[Where] ++ ++ Where 0 (From driver) or 1 (From FW) ++ ++ iwpriv wlan0 set_str_cmd 0_1_3_1_26_00:11:22:33:44:01_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ ADAPTER_T *prAdapter; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ BOOLEAN fgIsInitiator; ++ UINT_8 ucReasonCode, aucPeerMac[6]; ++ BOOLEAN fgIsFromWhich; ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ fgIsInitiator = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ucReasonCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); ++ fgIsFromWhich = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, ++ " %s: ReasonCode=%d from %pM %d\n", ++ __func__, ucReasonCode, aucPeerMac, fgIsFromWhich); ++ ++ if (fgIsFromWhich == 0) { ++ /* allocate/init packet */ ++ prAdapter = prGlueInfo->prAdapter; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = TDLS_FRM_ACTION_TEARDOWN; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Reason Code */ ++ *pPkt = ucReasonCode; ++ *(pPkt + 1) = 0x00; ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ if (fgIsInitiator == 1) { ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); ++ } else { ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); ++ } ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* pass to OS */ ++ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); ++ } else { ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ kalMemCopy(rCmd.aucPeerMac, aucPeerMac, 6); ++ rCmd.Content.rCmdTearDownRcv.u4ReasonCode = (UINT32) ucReasonCode; ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsTestTearDownRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to inform firmware to skip tx fail case. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_7_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_7_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ rCmd.Content.rCmdTxFailSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdTxFailSkip.fgIsEnable); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestTxFailSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a test frame command to wifi task. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 ++* ++* EX: iwpriv wlan0 set_str_cmd 0_12_2_[FrameType]_[DialogToken]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_12_2_0_1_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ UINT32 u4Subcmd; ++ UINT_32 u4BufLen; ++ ++ /* parse sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " test tx tdls frame sub command = %u\n", u4Subcmd); ++ ++ /* parse command arguments */ ++ rCmd.ucFmeType = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); ++ ++ switch (u4Subcmd) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_CONFIRM: ++ rCmd.ucToken = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); ++ ++ DBGLOG(TDLS, INFO, " setup FmeType=%d Token=%d to [%pM]\n", ++ rCmd.ucFmeType, rCmd.ucToken, rCmd.arRspAddr); ++ break; ++ ++ default: ++ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); ++ return; ++ } ++ ++ /* send command to wifi task to handle */ ++ kalIoctl(prGlueInfo, ++ TdlsTestTdlsFrameSend, ++ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a test frame command to wifi task. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ ++ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ ++ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ ++ [Timeout]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ TDLS_STATUS u4Status; ++ UINT_32 u4Subcmd; ++ UINT_32 u4BufLen; ++ ++ /* parse sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " test tx frame sub command = %u\n", (UINT32) u4Subcmd); ++ ++ /* parse command arguments */ ++ switch (u4Subcmd) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ u4Status = TdlsCmdTestTxFmeSetupReqBufTranslate(prInBuf, u4InBufLen, &rCmd); ++ break; ++ ++ default: ++ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); ++ return; ++ } ++ ++ if (u4Status != TDLS_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, " command parse fail\n"); ++ return; ++ } ++ ++ /* send command to wifi task to handle */ ++ kalIoctl(prGlueInfo, ++ TdlsTestFrameSend, ++ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse the TDLS test frame command, setup request ++* ++* @param CmdBuf Pointer to the buffer. ++* @param BufLen Record buffer length. ++* @param CmdTspec Pointer to the structure. ++* ++* @retval WLAN_STATUS_SUCCESS: Translate OK. ++* @retval WLAN_STATUS_FAILURE: Translate fail. ++* @usage iwpriv wlan0 set_str_cmd [tdls]_[command] ++* ++* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ ++ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ ++ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ ++ [Timeout]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd) ++{ ++/* dumpMemory8(ANDROID_LOG_INFO, pCmdBuf, u4BufLen); */ ++ ++ prCmd->ucFmeType = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->ucToken = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->u2Cap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->ucExCap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupRate[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->arSupChan[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ prCmd->u4Timeout = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); ++ CmdStringMacParse(pCmdBuf, &pCmdBuf, &u4BufLen, prCmd->arRspAddr); ++ ++ DBGLOG(TDLS, INFO, " command content =\n"); ++ DBGLOG(TDLS, INFO, "\tPeer MAC = %pM\n", (prCmd->arRspAddr)); ++ DBGLOG(TDLS, INFO, "\tToken = %u, Cap = 0x%x, ExCap = 0x%x, Timeout = %us FrameType = %u\n", ++ (UINT32) prCmd->ucToken, prCmd->u2Cap, prCmd->ucExCap, ++ (UINT32) prCmd->u4Timeout, (UINT32) prCmd->ucFmeType); ++ DBGLOG(TDLS, INFO, "\tSupRate = 0x%x %x %x %x\n", ++ prCmd->arSupRate[0], prCmd->arSupRate[1], prCmd->arSupRate[2], prCmd->arSupRate[3]); ++ DBGLOG(TDLS, INFO, "\tSupChan = %d %d %d %d\n", ++ prCmd->arSupChan[0], prCmd->arSupChan[1], prCmd->arSupChan[2], prCmd->arSupChan[3]); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update a TDLS peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_3_[Responder MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_3_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; ++ struct wireless_dev *prWdev; ++ ++ /* reset */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); ++ ++ /* init */ ++ rCmd.rPeerInfo.supported_rates = rCmd.arSupRate; ++ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; ++ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ ++ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); ++ rCmd.rPeerInfo.uapsd_queues = 0xf; /* all AC */ ++ rCmd.rPeerInfo.max_sp = 0; /* delivery all packets */ ++ ++ /* send command to wifi task to handle */ ++ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; ++ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); ++ ++ /* update */ ++ TdlsexCfg80211TdlsOper(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, NL80211_TDLS_ENABLE_LINK); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Null frame from the peer. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++* EX: iwpriv wlan0 set_str_cmd 0_5_[Responder MAC]_[PM bit] ++ ++ iwpriv wlan0 set_str_cmd 0_5_00:11:22:33:44:01_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ rCmd.Content.rCmdNullRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: [%pM] u4PM = %u\n", ++ __func__, (rCmd.aucPeerMac), (UINT32) rCmd.Content.rCmdNullRcv.u4PM); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsTestNullRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a data frame to the peer periodically. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] u4Param no use ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_15_[Responder MAC]_[Interval: ms]_[Enable/Disable] ++ ++ iwpriv wlan0 set_str_cmd 0_15_00:11:22:33:44:01_5000_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *prPkt; ++ ++ /* init */ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* allocate a data frame */ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); ++ return; ++ } ++ ++ /* init dev */ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return; ++ } ++ ++ /* init packet */ ++ prMsduInfo->len = 1000; ++ kalMemCopy(prMsduInfo->data, aucTdlsTestDataSPeerMac, 6); ++ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); ++ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; ++ ++ DBGLOG(TDLS, INFO, " %s try to send a data frame to %pM\n", ++ __func__, aucTdlsTestDataSPeerMac); ++ ++ /* simulate OS to send the packet */ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++ ++ /* restart test timer */ ++ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Channel Switch Request frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_REQ; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Channel Switch Response frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_RSP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send a test frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; ++ P_BSS_INFO_T prBssInfo; ++ struct sk_buff *prMsduInfo; ++ UINT_8 *pPkt; ++ UINT_32 u4PktLen, u4IeLen; ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if (u4SetBufferLen == 0) ++ return TDLS_STATUS_INVALID_LENGTH; ++ ++ /* allocate/init packet */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ *pu4SetInfoLen = u4SetBufferLen; ++ u4PktLen = 0; ++ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* make up frame content */ ++ /* 1. 802.3 header */ ++ kalMemCopy(pPkt, prCmd->arRspAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = prCmd->ucFmeType; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ *pPkt = prCmd->ucToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (4) Capability */ ++ WLAN_SET_FIELD_16(pPkt, prCmd->u2Cap); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (10) Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */ ++ TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL; ++ TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5; ++ ++ TIMEOUT_INTERVAL_IE(pPkt)->ucType = IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; ++ TIMEOUT_INTERVAL_IE(pPkt)->u4Value = htonl(prCmd->u4Timeout); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 3. Frame Formation - (16) Link identifier element */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prCmd->arRspAddr, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 4. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ /* 5. send the data frame */ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a NULL frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_NULL_RCV; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_REQ; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a PTI response frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_RSP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a Tear Down frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TEAR_DOWN; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to receive a data frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_DATA_RCV; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip PTI tx fail status. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_TX_FAIL; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send a TDLS action frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] ++ ++ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; ++ struct wireless_dev *prWdev; ++ ++ /* sanity check */ ++ ASSERT(prAdapter); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if (u4SetBufferLen == 0) ++ return TDLS_STATUS_INVALID_LENGTH; ++ ++ /* allocate/init packet */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; ++ prWdev = (struct wireless_dev *)prGlueInfo->prDevHandler->ieee80211_ptr; ++ ++ TdlsexCfg80211TdlsMgmt(prWdev->wiphy, NULL, ++ prCmd->arRspAddr, prCmd->ucFmeType, 1, ++ 0, 0, /* open/none */ ++ FALSE, NULL, 0); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip tx fail status. So always success in tx done in firmware. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TX_FAIL_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip to do keep alive function in firmware. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip channel switch timeout. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to skip scan request. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_SCAN_SKIP; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++#endif /* TDLS_CFG_CMD_TEST */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure channel switch parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_CHSW_CONF; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update channel switch parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_9_[TDLS Peer MAC]_ ++ [NetworkTypeIndex]_[1 (Enable) or (0) Disable]_[1 (Start) or 0 (Stop)]_ ++ [RegClass]_[Chan]_[SecChanOff]_[1 (Reqular) or (0) One Shot] ++ ++ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) ++ Secondary Channel Offset: 0 (SCN - no secondary channel) ++ 1 (SCA - secondary channel above) ++ 2 (SCB - secondary channel below) ++ SwitchTime: units of microseconds ++ ++ iwpriv wlan0 set_str_cmd 0_9_00:11:22:33:44:01_0_1_0_0_1_0_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ ++ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.fgIsChSwStarted = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.ucRegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.ucTargetChan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.ucSecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdChSwConf.fgIsChSwRegular = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: %pM ucNetTypeIndex=%d, fgIsChSwEnabled=%d, fgIsChSwStarted=%d", ++ __func__, (rCmd.aucPeerMac), ++ rCmd.Content.rCmdChSwConf.ucNetTypeIndex, ++ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled, ++ rCmd.Content.rCmdChSwConf.fgIsChSwStarted); ++ DBGLOG(TDLS, INFO, " RegClass=%d, TargetChan=%d, SecChanOff=%d, Regular=%d\n", ++ rCmd.Content.rCmdChSwConf.ucRegClass, ++ rCmd.Content.rCmdChSwConf.ucTargetChan, ++ rCmd.Content.rCmdChSwConf.ucSecChanOff, rCmd.Content.rCmdChSwConf.fgIsChSwRegular); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsChSwConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display TDLS related information. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_18_[Peer MAC]_[Network Interface ID]_[IsClear] ++ ++ Network Interface ID: reference to ENUM_NETWORK_TYPE_INDEX_T ++ ++ typedef enum _ENUM_NETWORK_TYPE_INDEX_T { ++ NETWORK_TYPE_AIS_INDEX = 0, ++ NETWORK_TYPE_P2P_INDEX, ++ NETWORK_TYPE_BOW_INDEX, ++ NETWORK_TYPE_INDEX_NUM ++ } ENUM_NETWORK_TYPE_INDEX_T; ++ ++ iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); ++ rCmd.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdInfoDisplay.fgIsToClearAllHistory = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, " %s: Command PeerMac=%pM in BSS%u\n", ++ __func__, (rCmd.aucPeerMac), rCmd.ucNetTypeIndex); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display key related information. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_20 ++ ++ iwpriv wlan0 set_str_cmd 0_20 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsKeyInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update MIB parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_6_[TdlsEn]_[UapsdEn]_[PsmEn]_[PtiWin]_[CWCap]_ ++ [AckMisRetry]_[RspTimeout]_[CWPbDelay]_[DRWin]_[LowestAcInt] ++ ++ iwpriv wlan0 set_str_cmd 0_6_1_1_0_1_1_3_5_1000_2_1 ++ ++ reference to TDLS_CMD_CORE_MIB_PARAM_UPDATE_T ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* reset */ ++ kalMemZero(&rCmd, sizeof(rCmd)); ++ ++ /* parse arguments */ ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval = ++ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, " MIB param = %d %d %d %d %d %d %d %d %d %d\n", ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow, ++ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsMibParamUpdate, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update setup parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_17_[20/40 Support] ++ ++ iwpriv wlan0 set_str_cmd 0_17_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ ++ rCmd.Content.rCmdSetupConf.fgIs2040Supported = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ ++ DBGLOG(TDLS, INFO, "%s: rCmdSetupConf=%d\n", __func__, rCmd.Content.rCmdSetupConf.fgIs2040Supported); ++ ++ /* command to do this */ ++ prGlueInfo->rTdlsLink.fgIs2040Sup = rCmd.Content.rCmdSetupConf.fgIs2040Supported; ++ ++ rStatus = kalIoctl(prGlueInfo, TdlsSetupConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update UAPSD parameters. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++* EX: iwpriv wlan0 set_str_cmd 0_8_[SP timeout skip]_[PTI timeout skip] ++ ++ iwpriv wlan0 set_str_cmd 0_8_1_1 ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ WLAN_STATUS rStatus; ++ TDLS_CMD_CORE_T rCmd; ++ UINT_32 u4BufLen; ++ ++ /* parse arguments */ ++ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); ++ ++ /* UAPSD Service Period */ ++ rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ /* PTI Service Period */ ++ fgIsPtiTimeoutSkip = rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip; ++ ++ DBGLOG(TDLS, INFO, "%s: fgIsSpTimeoutSkip=%d, fgIsPtiTimeoutSkip=%d\n", ++ __func__, rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip, fgIsPtiTimeoutSkip); ++ ++ /* command to do this */ ++ rStatus = kalIoctl(prGlueInfo, TdlsUapsdConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); ++ return; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display TDLS all information. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++* iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_CORE_T *prCmdContent; ++ STA_RECORD_T *prStaRec; ++ TDLS_INFO_LINK_T *prLink; ++ UINT32 u4StartIdx; ++ UINT32 u4PeerNum; ++ BOOLEAN fgIsListAll; ++ UINT8 ucMacZero[6]; ++ UINT32 u4HisIdx; ++ UINT8 ucNetTypeIndex; ++ ++ /* init */ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ u4StartIdx = 0; ++ u4PeerNum = 1; ++ fgIsListAll = TRUE; ++ kalMemZero(ucMacZero, sizeof(ucMacZero)); ++ ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ ++ /* display common information */ ++ DBGLOG(TDLS, TRACE, "TDLS common:\n"); ++ DBGLOG(TDLS, TRACE, "\t\trFreeSwRfbList=%u\n", (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ DBGLOG(TDLS, TRACE, "\t\tjiffies=%u %ums (HZ=%d)\n", (UINT32) jiffies, (UINT32) kalGetTimeTick(), HZ); ++ ++ /* display disconnection history information */ ++ DBGLOG(TDLS, TRACE, "TDLS link history: %d\n", prGlueInfo->rTdlsLink.u4LinkIdx); ++ ++ for (u4HisIdx = prGlueInfo->rTdlsLink.u4LinkIdx + 1; u4HisIdx < TDLS_LINK_HISTORY_MAX; u4HisIdx++) { ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; ++ ++ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) ++ continue; /* skip all zero */ ++ ++ DBGLOG(TDLS, TRACE, ++ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", ++ u4HisIdx, prLink->aucPeerMac, ++ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), ++ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), ++ prLink->ucReasonCode, ++ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); ++ ++ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { ++ DBGLOG(TDLS, TRACE, ++ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", ++ prLink->ucHtBa[0], prLink->ucHtBa[1], ++ prLink->ucHtBa[2], prLink->ucHtBa[3], ++ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); ++ } ++ } ++ for (u4HisIdx = 0; u4HisIdx <= prGlueInfo->rTdlsLink.u4LinkIdx; u4HisIdx++) { ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; ++ ++ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) ++ continue; /* skip all zero, use continue, not break */ ++ ++ DBGLOG(TDLS, TRACE, ++ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", ++ u4HisIdx, (prLink->aucPeerMac), ++ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), ++ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), ++ prLink->ucReasonCode, ++ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); ++ ++ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { ++ DBGLOG(TDLS, TRACE, ++ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", ++ prLink->ucHtBa[0], prLink->ucHtBa[1], ++ prLink->ucHtBa[2], prLink->ucHtBa[3], ++ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); ++ } ++ } ++ DBGLOG(TDLS, TRACE, "\n"); ++ ++ /* display link information */ ++ if (prCmdContent != NULL) { ++ if (kalMemCmp(prCmdContent->aucPeerMac, ucMacZero, 6) != 0) { ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ prCmdContent->ucNetTypeIndex, prCmdContent->aucPeerMac); ++ if (prStaRec == NULL) ++ fgIsListAll = TRUE; ++ } ++ ++ ucNetTypeIndex = prCmdContent->ucNetTypeIndex; ++ } ++ ++ while (1) { ++ if (fgIsListAll == TRUE) { ++ /* list all TDLS peers */ ++ prStaRec = cnmStaTheTypeGet(prAdapter, ucNetTypeIndex, STA_TYPE_TDLS_PEER, &u4StartIdx); ++ if (prStaRec == NULL) ++ break; ++ } ++ ++ DBGLOG(TDLS, TRACE, "-------- TDLS %d: 0x %pM\n", u4PeerNum, (prStaRec->aucMacAddr)); ++ DBGLOG(TDLS, TRACE, "\t\t\t State %d, PM %d, Cap 0x%x\n", ++ prStaRec->ucStaState, prStaRec->fgIsInPS, prStaRec->u2CapInfo); ++ DBGLOG(TDLS, TRACE, "\t\t\t SetupDisable %d, ChSwDisable %d\n", ++ prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); ++ ++ if (fgIsListAll == FALSE) ++ break; /* only list one */ ++ } ++ ++ /* check if we need to clear all histories */ ++ if ((prCmdContent != NULL) && (prCmdContent->Content.rCmdInfoDisplay.fgIsToClearAllHistory == TRUE)) { ++ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); ++ prGlueInfo->rTdlsLink.u4LinkIdx = TDLS_LINK_HISTORY_MAX - 1; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to display key information. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_KEY_INFO; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to record a disconnection event. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure ++* \param[in] fgIsTearDown TRUE: the link is torn down ++* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] fgIsFromUs TRUE: tear down is from us ++* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, ++ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers) ++{ ++ TDLS_INFO_LINK_T *prLink; ++ ++ DBGLOG(TDLS, INFO, ++ " %s: record history for %pM %d %d %d %d\n", ++ __func__, pucPeerMac, prGlueInfo->rTdlsLink.u4LinkIdx, ++ fgIsTearDown, fgIsFromUs, u2ReasonCode); ++ ++ /* check duplicate one */ ++ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) { ++ DBGLOG(TDLS, ERROR, " %s: u4LinkIdx >= TDLS_LINK_HISTORY_MAX\n", __func__); ++ ++ /* reset to 0 */ ++ prGlueInfo->rTdlsLink.u4LinkIdx = 0; ++ } ++ ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; ++ ++ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) == 0) { ++ if ((prLink->ucReasonCode == u2ReasonCode) && (prLink->fgIsFromUs == fgIsFromUs)) { ++ /* same Peer MAC, Reason Code, Trigger source */ ++ if (fgIsTearDown == TRUE) { ++ if (prLink->jiffies_end != 0) { ++ /* already torn down */ ++ prLink->ucDupCount++; ++ return; ++ } ++ } else { ++ /* already built */ ++ prLink->ucDupCount++; ++ return; ++ } ++ } ++ } ++ ++ /* search old entry */ ++ if (fgIsTearDown == TRUE) { ++ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ ++ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { ++ /* error! can not find the link entry */ ++ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); ++ return; ++ } ++ ++ prLink->jiffies_end = jiffies; ++ prLink->ucReasonCode = (UINT8) u2ReasonCode; ++ prLink->fgIsFromUs = fgIsFromUs; ++ } else { ++ /* record new one */ ++ prGlueInfo->rTdlsLink.u4LinkIdx++; ++ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) ++ prGlueInfo->rTdlsLink.u4LinkIdx = 0; ++ ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; ++ ++ prLink->jiffies_start = jiffies; ++ prLink->jiffies_end = 0; ++ kalMemCopy(&prLink->aucPeerMac, pucPeerMac, 6); ++ prLink->ucReasonCode = 0; ++ prLink->fgIsFromUs = (UINT8) fgIsFromUs; ++ prLink->ucDupCount = 0; ++ ++ if (prOthers != NULL) { ++ /* record other parameters */ ++ TDLS_LINK_HIS_OTHERS_T *prHisOthers; ++ ++ prHisOthers = (TDLS_LINK_HIS_OTHERS_T *) prOthers; ++ if (prHisOthers->fgIsHt == TRUE) ++ prLink->ucHtCap |= TDLS_INFO_LINK_HT_CAP_SUP; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update a disconnection event. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure ++* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] eFmeStatus TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME ++* \param[in] pInfo other information ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, ++ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo) ++{ ++ TDLS_INFO_LINK_T *prLink; ++ UINT32 u4LinkIdx; ++ UINT32 u4Tid; ++ ++ /* sanity check */ ++ if ((eFmeStatus < TDLS_HOST_EVENT_SF_BA) || (eFmeStatus > TDLS_HOST_EVENT_SF_BA_RSP_DECLINE)) { ++ /* do not care these frames */ ++ return; ++ } ++ ++ DBGLOG(TDLS, INFO, ++ " %s: update history for %pM %d %d\n", ++ __func__, (pucPeerMac), prGlueInfo->rTdlsLink.u4LinkIdx, eFmeStatus); ++ ++ /* init */ ++ u4LinkIdx = prGlueInfo->rTdlsLink.u4LinkIdx; ++ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4LinkIdx]; ++ ++ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ ++ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { ++ /* error! can not find the link entry */ ++ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); ++ return; ++ } ++ ++ /* update */ ++ u4Tid = *(UINT32 *) pInfo; ++ switch (eFmeStatus) { ++ case TDLS_HOST_EVENT_SF_BA: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_OK: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_OK; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_DECLINE: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_DECLINE; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_PEER: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_PEER; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_RSP_OK: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_OK; ++ break; ++ ++ case TDLS_HOST_EVENT_SF_BA_RSP_DECLINE: ++ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_DECLINE; ++ break; ++ } ++ ++ /* display TDLS link history */ ++ TdlsInfoDisplay(prGlueInfo->prAdapter, NULL, 0, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure TDLS MIB parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_MIB_UPDATE; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure TDLS SETUP parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_SETUP_CONF; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to configure UAPSD parameters. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static TDLS_STATUS ++TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ TDLS_CMD_CORE_T *prCmdContent; ++ WLAN_STATUS rStatus; ++ ++ /* init command buffer */ ++ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; ++ prCmdContent->u4Command = TDLS_CORE_CMD_UAPSD_CONF; ++ ++ /* send the command */ ++ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ ++ CMD_ID_TDLS_CORE, /* ucCID */ ++ TRUE, /* fgSetQuery */ ++ FALSE, /* fgNeedResp */ ++ FALSE, /* fgIsOid */ ++ NULL, NULL, /* pfCmdTimeoutHandler */ ++ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ ++ (PUINT_8) prCmdContent, /* pucInfoBuffer */ ++ NULL, /* pvSetQueryBuffer */ ++ 0 /* u4SetQueryBufferLen */ ++ ); ++ ++ if (rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to update frame status. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventFmeStatus(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus; ++ STA_RECORD_T *prStaRec; ++ UINT32 u4Tid; ++ ++ /* init */ ++ u4Tid = *(UINT32 *) prInBuf; ++ prInBuf += 4; /* skip u4EventSubId */ ++ ++ /* sanity check */ ++ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); ++ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) ++ return; ++ prInBuf++; ++ ++ /* update status */ ++ eFmeStatus = *prInBuf; ++ TdlsLinkHistoryRecordUpdate(prGlueInfo, prStaRec->aucMacAddr, eFmeStatus, &u4Tid); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to collect TDLS statistics from firmware. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ STA_RECORD_T *prStaRec; ++ STAT_CNT_INFO_FW_T *prStat; ++ UINT32 u4RateId; ++ ++ /* init */ ++ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); ++ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) ++ return; ++ ++ prInBuf += 4; /* skip prStaRec->ucIndex */ ++ ++ /* update statistics */ ++ kalMemCopy(&prStaRec->rTdlsStatistics.rFw, prInBuf, sizeof(prStaRec->rTdlsStatistics.rFw)); ++ ++ /* display statistics */ ++ prStat = &prStaRec->rTdlsStatistics.rFw; ++ ++ DBGLOG(TDLS, TRACE, " peer [%pM] statistics:\n", (prStaRec->aucMacAddr)); ++ DBGLOG(TDLS, TRACE, "\t\tT%d %d %d (P%d %d) (%dus) - E%d 0x%x - R%d (P%d)\n", ++ prStat->u4NumOfTx, prStat->u4NumOfTxOK, prStat->u4NumOfTxRetry, ++ prStat->u4NumOfPtiRspTxOk, prStat->u4NumOfPtiRspTxErr, ++ prStat->u4TxDoneAirTimeMax, ++ prStat->u4NumOfTxErr, prStat->u4TxErrBitmap, prStat->u4NumOfRx, prStat->u4NumOfPtiRspRx); ++ ++ DBGLOG(TDLS, TRACE, "\t\t"); ++ ++ for (u4RateId = prStat->u4TxRateOkHisId; u4RateId < STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM; u4RateId++) ++ DBGLOG(TDLS, TRACE, ++ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); ++ for (u4RateId = 0; u4RateId < prStat->u4TxRateOkHisId; u4RateId++) ++ DBGLOG(TDLS, TRACE, ++ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); ++ ++ DBGLOG(TDLS, TRACE, "\n\n"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to do tear down. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ STA_RECORD_T *prStaRec; ++ UINT16 u2ReasonCode; ++ UINT32 u4TearDownSubId; ++ UINT8 *pMac, aucZeroMac[6]; ++ ++ /* init */ ++ u4TearDownSubId = *(UINT32 *) prInBuf; ++ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); ++ pMac = aucZeroMac; ++ ++ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4)); ++ if (prStaRec != NULL) ++ pMac = prStaRec->aucMacAddr; ++ ++ /* handle */ ++ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { ++ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=PTI timeout\n", ++ __func__, pMac); ++ } else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) { ++ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=AGE timeout\n", ++ __func__, pMac); ++ } else { ++ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=%d\n", ++ __func__, pMac, u4TearDownSubId); ++ } ++ ++ /* sanity check */ ++ if (prStaRec == NULL) ++ return; ++ ++ if (fgIsPtiTimeoutSkip == TRUE) { ++ /* skip PTI timeout event */ ++ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { ++ DBGLOG(TDLS, WARN, " %s: skip PTI timeout\n", __func__); ++ return; ++ } ++ } ++ ++ /* record history */ ++ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_FAIL) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_NON_STATE3) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3; ++ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN) ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN; ++ else { ++ /* shall not be here */ ++ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN; ++ } ++ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, TRUE, u2ReasonCode, NULL); ++ ++ /* correct correct reason code for PTI or AGE timeout to supplicant */ ++ if ((u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT) || ++ (u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT)) { ++ u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE; ++ } ++ ++ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ ++ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN, u2ReasonCode, GFP_ATOMIC); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to do tx down. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static void TdlsEventTxDone(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ /* UINT32 u4FmeIdx; */ ++ UINT8 *pucFmeHdr; ++ UINT8 ucErrStatus; ++ ++ ucErrStatus = *(UINT32 *) prInBuf; ++ ++ pucFmeHdr = prInBuf + 4; /* skip ucErrStatus */ ++ ++ if (ucErrStatus == 0) ++ DBGLOG(TDLS, TRACE, " %s: OK to tx a TDLS action:", __func__); ++ else ++ DBGLOG(TDLS, TRACE, " %s: fail to tx a TDLS action (err=0x%x):", __func__, ucErrStatus); ++ #if 0 ++ /* dump TX packet content from wlan header */ ++ for (u4FmeIdx = 0; u4FmeIdx < (u4InBufLen - 4); u4FmeIdx++) { ++ if ((u4FmeIdx % 16) == 0) ++ DBGLOG(TDLS, TRACE, "\n"); ++ ++ DBGLOG(TDLS, TRACE, "%02x ", *pucFmeHdr++); ++ } ++ DBGLOG(TDLS, TRACE, "\n\n"); ++ #endif ++} ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to parse TDLS Extended Capabilities element. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE) ++{ ++ UINT_8 *pucIeExtCap; ++ ++ /* sanity check */ ++ if ((prStaRec == NULL) || (pucIE == NULL)) ++ return; ++ ++ if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP) ++ return; ++ ++ /* ++ from bit0 ~ ++ ++ bit 38: TDLS Prohibited ++ The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The ++ field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is ++ allowed. ++ */ ++ if (IE_LEN(pucIE) < 5) ++ return; /* we need 39/8 = 5 bytes */ ++ ++ /* init */ ++ prStaRec->fgTdlsIsProhibited = FALSE; ++ prStaRec->fgTdlsIsChSwProhibited = FALSE; ++ ++ /* parse */ ++ pucIeExtCap = pucIE + 2; ++ pucIeExtCap += 4; /* shift to the byte we care about */ ++ ++ if ((*pucIeExtCap) & BIT(38 - 32)) ++ prStaRec->fgTdlsIsProhibited = TRUE; ++ if ((*pucIeExtCap) & BIT(39 - 32)) ++ prStaRec->fgTdlsIsChSwProhibited = TRUE; ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: AP [%pM] tdls prohibit bit=%d %d\n", ++ __func__, ++ prStaRec->aucMacAddr, prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to transmit a TDLS data frame from nl80211. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] ++* \param[in] ++* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, u8 action_code, u8 dialog_token, ++ u16 status_code, u32 peer_capability, ++ bool initiator, const u8 *buf, size_t len) ++{ ++ ADAPTER_T *prAdapter; ++ GLUE_INFO_T *prGlueInfo; ++ BSS_INFO_T *prAisBssInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ TDLS_MGMT_TX_INFO *prMgmtTxInfo; ++ ++ /* ++ Have correct behavior for STAUT receiving TDLS Setup Request after sending TDLS ++ Set Request and before receiving TDLS Setup Response: ++ -- Source Address of received Request is higher than own MAC address ++ -- Source Address of received Request is lower than own MAC address ++ ++ ==> STA with larger MAC address will send the response frame. ++ ++ Supplicant will do this in wpa_tdls_process_tpk_m1(). ++ */ ++ ++ /* sanity check */ ++ if ((wiphy == NULL) || (peer == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: wrong 0x%p 0x%p!\n", __func__, wiphy, peer); ++ return -EINVAL; ++ } ++ ++ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d %d 0x%p %u\n", ++ __func__, peer, action_code, dialog_token, status_code, buf, (UINT32) len); ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); ++ return -EINVAL; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ if (prAdapter->fgTdlsIsSup == FALSE) { ++ DBGLOG(TDLS, ERROR, " %s: firmware TDLS is not supported!\n", __func__); ++ return -EBUSY; ++ } ++ ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (prAisBssInfo->fgTdlsIsProhibited == TRUE) { ++ /* do not send anything if TDLS is prohibited in the BSS */ ++ return 0; ++ } ++ ++ prMgmtTxInfo = kalMemAlloc(sizeof(TDLS_MGMT_TX_INFO), VIR_MEM_TYPE); ++ if (prMgmtTxInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate fail!\n", __func__); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); ++ ++ if (peer != NULL) ++ kalMemCopy(prMgmtTxInfo->aucPeer, peer, 6); ++ prMgmtTxInfo->ucActionCode = action_code; ++ prMgmtTxInfo->ucDialogToken = dialog_token; ++ prMgmtTxInfo->u2StatusCode = status_code; ++ ++ if (buf != NULL) { ++ if (len > sizeof(prMgmtTxInfo->aucSecBuf)) { ++ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); ++ return -EINVAL; ++ } ++ prMgmtTxInfo->u4SecBufLen = len; ++ kalMemCopy(prMgmtTxInfo->aucSecBuf, buf, len); ++ } ++ ++ /* send the TDLS action data frame */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexMgmtCtrl, ++ prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ /* ++ clear all content to avoid any bug if we dont yet execute TdlsexMgmtCtrl() ++ then kalIoctl finishes ++ */ ++ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); ++ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); ++ return -EINVAL; ++ } ++ ++ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to enable or disable TDLS link from upper layer. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] ++* \param[in] ++* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *peer, enum nl80211_tdls_operation oper) ++{ ++ ADAPTER_T *prAdapter; ++ GLUE_INFO_T *prGlueInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ TDLS_CMD_LINK_T rCmdLink; ++ ++ /* sanity check */ ++ if (peer == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: peer == NULL!\n", __func__); ++ return -EINVAL; ++ } ++ ++ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d\n", ++ __func__, peer, oper, (wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)); ++ ++ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) ++ return -ENOTSUPP; ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); ++ return -EINVAL; ++ } ++ prAdapter = prGlueInfo->prAdapter; ++ kalMemCopy(rCmdLink.aucPeerMac, peer, sizeof(rCmdLink.aucPeerMac)); ++ rCmdLink.fgIsEnabled = FALSE; ++ ++ /* ++ enum nl80211_tdls_operation { ++ NL80211_TDLS_DISCOVERY_REQ, ++ NL80211_TDLS_SETUP, ++ NL80211_TDLS_TEARDOWN, ++ NL80211_TDLS_ENABLE_LINK, ++ NL80211_TDLS_DISABLE_LINK, ++ }; ++ */ ++ ++ switch (oper) { ++ case NL80211_TDLS_ENABLE_LINK: ++ rCmdLink.fgIsEnabled = TRUE; ++ break; ++ ++ case NL80211_TDLS_DISABLE_LINK: ++ rCmdLink.fgIsEnabled = FALSE; ++ break; ++ ++ case NL80211_TDLS_TEARDOWN: ++ case NL80211_TDLS_SETUP: ++ case NL80211_TDLS_DISCOVERY_REQ: ++ /* we do not support setup/teardown/discovery from driver */ ++ return -ENOTSUPP; ++ ++ default: ++ return -ENOTSUPP; ++ } ++ ++ /* enable or disable TDLS link */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexLinkCtrl, &rCmdLink, sizeof(TDLS_CMD_LINK_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a command to TDLS module. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) ++{ ++ UINT_32 u4Subcmd; ++ static void (*TdlsCmdTestFunc)(P_GLUE_INFO_T, UINT_8 *, UINT_32); ++ ++ /* parse TDLS sub-command */ ++ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); ++ DBGLOG(TDLS, INFO, " sub command = %u\n", (UINT32) u4Subcmd); ++ TdlsCmdTestFunc = NULL; ++ ++ /* handle different sub-command */ ++ switch (u4Subcmd) { ++#if TDLS_CFG_CMD_TEST /* only for unit test */ ++ case TDLS_CMD_TEST_TX_FRAME: ++ /* simulate to send a TDLS frame */ ++ /* TdlsCmdTestTxFrame(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestTxFrame; ++ break; ++ ++ case TDLS_CMD_TEST_TX_TDLS_FRAME: ++ /* simulate to send a TDLS frame from supplicant */ ++ /* TdlsCmdTestTxTdlsFrame(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestTxTdlsFrame; ++ break; ++ ++ case TDLS_CMD_TEST_RCV_FRAME: ++ /* simulate to receive a TDLS frame */ ++ /* TdlsCmdTestRvFrame(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestRvFrame; ++ break; ++ ++ case TDLS_CMD_TEST_PEER_ADD: ++ /* simulate to add a TDLS peer */ ++ /* TdlsCmdTestAddPeer(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestAddPeer; ++ break; ++ ++ case TDLS_CMD_TEST_PEER_UPDATE: ++ /* simulate to update a TDLS peer */ ++ /* TdlsCmdTestUpdatePeer(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestUpdatePeer; ++ break; ++ ++ case TDLS_CMD_TEST_DATA_FRAME: ++ /* simulate to send a data frame to the peer */ ++ /* TdlsCmdTestDataSend(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestDataSend; ++ break; ++ ++ case TDLS_CMD_TEST_RCV_NULL: ++ /* simulate to receive a QoS null frame from the peer */ ++ /* TdlsCmdTestNullRecv(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestNullRecv; ++ break; ++ ++ case TDLS_CMD_TEST_SKIP_TX_FAIL: ++ /* command firmware to skip tx fail case */ ++ /* TdlsCmdTestTxFailSkip(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestTxFailSkip; ++ break; ++ ++ case TDLS_CMD_TEST_SKIP_KEEP_ALIVE: ++ /* command firmware to skip keep alive function */ ++ /* TdlsCmdTestKeepAliveSkip(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestKeepAliveSkip; ++ break; ++ ++ case TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT: ++ /* command firmware to skip channel switch timeout function */ ++ /* TdlsCmdTestChSwTimeoutSkip(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestChSwTimeoutSkip; ++ break; ++ ++ case TDLS_CMD_TEST_PROHIBIT_SET_IN_AP: ++ /* simulate to set Prohibited Bit in AP */ ++ /* TdlsCmdTestProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestProhibitedBitSet; ++ break; ++ ++ case TDLS_CMD_TEST_SCAN_DISABLE: ++ /* command to disable scan request to do channel switch */ ++ /* TdlsCmdTestScanCtrl(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestScanCtrl; ++ break; ++ ++ case TDLS_CMD_TEST_DATA_FRAME_CONT: ++ /* simulate to send a data frame to the peer periodically */ ++ /* TdlsCmdTestDataContSend(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestDataContSend; ++ break; ++ ++ case TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP: ++ /* simulate to set channel switch Prohibited Bit in AP */ ++ /* TdlsCmdTestChSwProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestChSwProhibitedBitSet; ++ break; ++ ++ case TDLS_CMD_TEST_DELAY: ++ /* delay a where */ ++ /* TdlsCmdTestDelay(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestDelay; ++ break; ++ ++ case TDLS_CMD_TEST_PTI_TX_FAIL: ++ /* simulate the tx done fail for PTI */ ++ /* TdlsCmdTestPtiTxDoneFail(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdTestPtiTxDoneFail; ++ break; ++#endif /* TDLS_CFG_CMD_TEST */ ++ ++ case TDLS_CMD_MIB_UPDATE: ++ /* update MIB parameters */ ++ /* TdlsCmdMibParamUpdate(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdMibParamUpdate; ++ break; ++ ++ case TDLS_CMD_UAPSD_CONF: ++ /* config UAPSD parameters */ ++ /* TdlsCmdUapsdConf(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdUapsdConf; ++ break; ++ ++ case TDLS_CMD_CH_SW_CONF: ++ /* enable or disable or start or stop channel switch function */ ++ /* TdlsCmdChSwConf(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdChSwConf; ++ break; ++ ++ case TDLS_CMD_SETUP_CONF: ++ /* config setup parameters */ ++ /* TdlsCmdSetupConf(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdSetupConf; ++ break; ++ ++ case TDLS_CMD_INFO: ++ /* display all TDLS information */ ++ /* TdlsCmdInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdInfoDisplay; ++ break; ++ ++ case TDLS_CMD_KEY_INFO: ++ /* display key information */ ++ /* TdlsCmdKeyInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ ++ TdlsCmdTestFunc = TdlsCmdKeyInfoDisplay; ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (TdlsCmdTestFunc != NULL) ++ TdlsCmdTestFunc(prGlueInfo, prInBuf, u4InBufLen); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to record a disconnection event. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure ++* \param[in] fgIsTearDown TRUE: tear down ++* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] fgIsFromUs TRUE: tear down is from us ++* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, ++ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode) ++{ ++ /* sanity check */ ++ if ((prGlueInfo == NULL) || (pucPeerMac == NULL)) ++ return; ++ ++ DBGLOG(TDLS, INFO, ++ " %s: Rcv a inform from %pM %d %d\n", ++ __func__, pucPeerMac, fgIsFromUs, u2ReasonCode); ++ ++ /* record */ ++ TdlsLinkHistoryRecord(prGlueInfo, fgIsTearDown, pucPeerMac, fgIsFromUs, u2ReasonCode, NULL); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to send a command to TDLS module. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) ++{ ++ UINT32 u4EventId; ++ ++ /* sanity check */ ++ if ((prGlueInfo == NULL) || (prInBuf == NULL)) ++ return; /* shall not be here */ ++ ++ /* handle */ ++ u4EventId = *(UINT32 *) prInBuf; ++ u4InBufLen -= 4; ++ ++ DBGLOG(TDLS, INFO, " %s: Rcv a event: %d\n", __func__, u4EventId); ++ ++ switch (u4EventId) { ++ case TDLS_HOST_EVENT_TEAR_DOWN: ++ TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ case TDLS_HOST_EVENT_TX_DONE: ++ TdlsEventTxDone(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ case TDLS_HOST_EVENT_FME_STATUS: ++ TdlsEventFmeStatus(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ ++ case TDLS_HOST_EVENT_STATISTICS: ++ TdlsEventStatistics(prGlueInfo, prInBuf + 4, u4InBufLen); ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in TDLS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return TDLS_STATUS_SUCCESS: do not set key and key infor. is queued ++ TDLS_STATUS_FAILURE: set key ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey) ++{ ++ STA_RECORD_T *prStaRec; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (prNewKey == NULL)) ++ return TDLS_STATUS_FAILURE; ++ ++ /* ++ supplicant will set key before updating station & enabling the link so we need to ++ backup the key information and set key when link is enabled ++ */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prNewKey->arBSSID); ++ if ((prStaRec != NULL) && IS_TDLS_STA(prStaRec)) { ++ DBGLOG(TDLS, TRACE, " %s: [%pM] queue key (len=%d) until link is enabled\n", ++ __func__, prNewKey->arBSSID, (UINT32) prNewKey->u4KeyLength); ++ ++ if (prStaRec->ucStaState == STA_STATE_3) { ++ DBGLOG(TDLS, TRACE, " %s: [%pM] tear down the link due to STA_STATE_3\n", ++ __func__, prNewKey->arBSSID); ++ ++ /* re-key */ ++ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, ++ prStaRec->aucMacAddr, TRUE, ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); ++ ++ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ ++ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); ++ return TDLS_STATUS_SUCCESS; ++ } ++ ++ /* backup the key */ ++ kalMemCopy(&prStaRec->rTdlsKeyTemp, prNewKey, sizeof(prStaRec->rTdlsKeyTemp)); ++ return TDLS_STATUS_SUCCESS; ++ } ++ ++ return TDLS_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initialize variables in TDLS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexInit(ADAPTER_T *prAdapter) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ ++ /* reset */ ++ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to get any peer is in power save. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \retval TRUE (at least one peer is in power save) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter) ++{ ++ STA_RECORD_T *prStaRec; ++ UINT32 u4StaId, u4StartIdx; ++ ++ for (u4StaId = 0, u4StartIdx = 0; u4StaId < CFG_STA_REC_NUM; u4StaId++) { ++ /* list all TDLS peers */ ++ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); ++ if (prStaRec == NULL) ++ break; ++ ++ if (prStaRec->fgIsInPS == TRUE) { ++ DBGLOG(TDLS, TRACE, " yes, at least one peer is in ps\n"); ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to enable or disable a TDLS link. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_LINK_T *prCmd; ++ BSS_INFO_T *prBssInfo; ++ STA_RECORD_T *prStaRec; ++ TDLS_LINK_HIS_OTHERS_T rHisOthers; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_CMD_LINK_T); ++ prCmd = (TDLS_CMD_LINK_T *) pvSetBuffer; ++ ++ /* search old entry */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); ++ if (prStaRec == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: cannot find the peer! %pM\n", ++ __func__, prCmd->aucPeerMac); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ if (prCmd->fgIsEnabled == TRUE) { ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); ++ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_ENABLE_LINK\n", __func__); ++ ++ /* update key information after cnmStaRecChangeState(STA_STATE_3) */ ++ prStaRec->fgTdlsInSecurityMode = FALSE; ++ ++ if (prStaRec->rTdlsKeyTemp.u4Length > 0) { ++ UINT_32 u4BufLen; /* no use */ ++ ++ DBGLOG(TDLS, INFO, " %s: key len=%d\n", ++ __func__, (UINT32) prStaRec->rTdlsKeyTemp.u4Length); ++ ++ /* ++ reminder the function that we are CIPHER_SUITE_CCMP, ++ do not change cipher type to CIPHER_SUITE_WEP128 ++ */ ++ _wlanoidSetAddKey(prAdapter, &prStaRec->rTdlsKeyTemp, ++ prStaRec->rTdlsKeyTemp.u4Length, FALSE, CIPHER_SUITE_CCMP, &u4BufLen); ++ ++ /* clear the temp key */ ++ prStaRec->fgTdlsInSecurityMode = TRUE; ++ kalMemZero(&prStaRec->rTdlsKeyTemp, sizeof(prStaRec->rTdlsKeyTemp)); ++ } ++ ++ /* check if we need to disable channel switch function */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ if (prBssInfo->fgTdlsIsChSwProhibited == TRUE) { ++ TDLS_CMD_CORE_T rCmd; ++ ++ kalMemZero(&rCmd, sizeof(TDLS_CMD_CORE_T)); ++ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = prStaRec->ucNetTypeIndex; ++ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = FALSE; ++ kalMemCopy(rCmd.aucPeerMac, prStaRec->aucMacAddr, 6); ++ TdlsChSwConf(prAdapter, &rCmd, 0, 0); ++ ++ DBGLOG(TDLS, INFO, " %s: disable channel switch\n", __func__); ++ } ++ ++ TDLS_LINK_INCREASE(prGlueInfo); ++ ++ /* record link */ ++ if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N) ++ rHisOthers.fgIsHt = TRUE; ++ else ++ rHisOthers.fgIsHt = FALSE; ++ ++ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, FALSE, ++ prStaRec->aucMacAddr, !prStaRec->flgTdlsIsInitiator, 0, &rHisOthers); ++ } else { ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); /* release to other TDLS peers */ ++ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_DISABLE_LINK\n", __func__); ++ ++ TDLS_LINK_DECREASE(prGlueInfo); ++/* while(1); //sample debug */ ++ } ++ ++ /* work-around link count */ ++ if ((TDLS_LINK_COUNT(prGlueInfo) < 0) || (TDLS_LINK_COUNT(prGlueInfo) > 1)) { ++ /* ERROR case: work-around to recount by searching all station records */ ++ UINT32 u4Idx; ++ ++ TDLS_LINK_COUNT_RESET(prGlueInfo); ++ ++ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { ++ prStaRec = &prAdapter->arStaRec[u4Idx]; ++ ++ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) ++ TDLS_LINK_INCREASE(prGlueInfo); ++ } ++ ++ if (TDLS_LINK_COUNT(prGlueInfo) > 1) { ++ /* number of links is still > 1 */ ++ DBGLOG(TDLS, INFO, " %s: cTdlsLinkCnt %d > 1?\n", ++ __func__, TDLS_LINK_COUNT(prGlueInfo)); ++ ++ TDLS_LINK_COUNT_RESET(prGlueInfo); ++ ++ /* free all TDLS links */ ++ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { ++ prStaRec = &prAdapter->arStaRec[u4Idx]; ++ ++ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ } ++ ++ /* maybe inform supplicant ? */ ++ } ++ } ++ ++ /* display TDLS link history */ ++ TdlsInfoDisplay(prAdapter, NULL, 0, NULL); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to send a TDLS action data frame. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_MGMT_TX_INFO *prMgmtTxInfo; ++ STA_RECORD_T *prStaRec; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_MGMT_TX_INFO); ++ prMgmtTxInfo = (TDLS_MGMT_TX_INFO *) pvSetBuffer; ++ ++ switch (prMgmtTxInfo->ucActionCode) { ++ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: ++ prStaRec = NULL; ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); ++ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3)) { ++ /* rekey? we reject re-setup link currently */ ++ /* TODO: Still can setup link during rekey */ ++ ++ /* ++ return success to avoid supplicant clear TDLS entry; ++ Or we cannot send out any TDLS tear down frame to the peer ++ */ ++ DBGLOG(TDLS, TRACE, " %s: skip new setup on the exist link!\n", __func__); ++ return TDLS_STATUS_SUCCESS; ++ } ++ ++ prStaRec = NULL; ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_CONFIRM: ++ case TDLS_FRM_ACTION_TEARDOWN: ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); ++#if 0 /* in some cases, the prStaRec is still NULL */ ++ /* ++ EX: if a peer sends us a TDLS setup request with wrong BSSID, ++ supplicant will not call TdlsexPeerAdd() to create prStaRec and ++ supplicant will send a TDLS setup response with status code 7. ++ ++ So in the case, prStaRec will be NULL. ++ */ ++ if (prStaRec == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); ++ return -EINVAL; ++ } ++#endif ++ break; ++ ++ /* ++ TODO: Discovery response frame ++ Note that the TDLS Discovery Response frame is not a TDLS frame but a 11 ++ Public Action frame. ++ In WiFi TDLS Tech Minutes June 8 2010.doc, ++ a public action frame (i.e. it is no longer an encapsulated data frame) ++ */ ++ ++ default: ++ DBGLOG(TDLS, ERROR, ++ " %s: wrong action_code %d!\n", __func__, prMgmtTxInfo->ucActionCode); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* send the TDLS data frame */ ++ if (prStaRec != NULL) { ++ DBGLOG(TDLS, INFO, " %s: [%pM] ps=%d status=%d\n", ++ __func__, prStaRec->aucMacAddr, ++ prStaRec->fgIsInPS, prMgmtTxInfo->u2StatusCode); ++ ++ if (prMgmtTxInfo->ucActionCode == TDLS_FRM_ACTION_TEARDOWN) { ++ /* record disconnect history */ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prMgmtTxInfo->aucPeer, ++ TRUE, prMgmtTxInfo->u2StatusCode, NULL); ++ } ++ } ++ ++ return TdlsDataFrameSend(prAdapter, ++ prStaRec, ++ prMgmtTxInfo->aucPeer, ++ prMgmtTxInfo->ucActionCode, ++ prMgmtTxInfo->ucDialogToken, ++ prMgmtTxInfo->u2StatusCode, ++ (UINT_8 *) prMgmtTxInfo->aucSecBuf, prMgmtTxInfo->u4SecBufLen); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to add a peer record. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexPeerAdd(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_PEER_ADD_T *prCmd; ++ BSS_INFO_T *prAisBssInfo; ++ STA_RECORD_T *prStaRec; ++ UINT_8 ucNonHTPhyTypeSet; ++ UINT32 u4StartIdx; ++ OS_SYSTIME rCurTime; ++ ++ /* sanity check */ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); ++ prCmd = (TDLS_CMD_PEER_ADD_T *) pvSetBuffer; ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ u4StartIdx = 0; ++ ++ /* search old entry */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); ++ ++ /* check if any TDLS link exists because we only support one TDLS link currently */ ++ if (prStaRec == NULL) { ++ /* the MAC is new peer */ ++ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); ++ ++ if (prStaRec != NULL) { ++ /* a building TDLS link exists */ ++ DBGLOG(TDLS, ERROR, ++ " %s: one TDLS link setup [%pM] is going...\n", ++ __func__, prStaRec->aucMacAddr); ++ ++ if (prStaRec->ucStaState != STA_STATE_3) { ++ /* check timeout */ ++ GET_CURRENT_SYSTIME(&rCurTime); ++ ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsSetupStartTime, ++ SEC_TO_SYSTIME(TDLS_SETUP_TIMEOUT_SEC))) { ++ /* free the StaRec */ ++ cnmStaRecFree(prAdapter, prStaRec, TRUE); ++ ++ DBGLOG(TDLS, ERROR, ++ " %s: free going TDLS link setup [%pM]\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ /* handle new setup */ ++ prStaRec = NULL; ++ } else ++ return TDLS_STATUS_FAILURE; ++ } else { ++ /* the TDLS is built and works fine, reject new one */ ++ return TDLS_STATUS_FAILURE; ++ } ++ } ++ } else { ++ if (prStaRec->ucStaState == STA_STATE_3) { ++ /* the peer exists, maybe TPK lifetime expired, supplicant wants to renew key */ ++ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, ++ prStaRec->aucMacAddr, TRUE, ++ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); ++ ++ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ ++ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: re-setup link for [%pM] maybe re-key?\n", ++ __func__, (prStaRec->aucMacAddr)); ++ return TDLS_STATUS_FAILURE; ++ } ++ } ++ ++ /* ++ create new entry if not exist ++ ++ 1. we are initiator ++ (1) send TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) got TDLS setup response and send TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ ++ 2. we are responder ++ (1) got TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) send TDLS setup response ++ (3) got TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ */ ++ if (prStaRec == NULL) { ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); ++ ++ if (prStaRec == NULL) { ++ /* shall not be here */ ++ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ /* init the prStaRec */ ++ /* prStaRec will be zero first in cnmStaRecAlloc() */ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, prCmd->aucPeerMac); ++ ++/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); */ ++ } else { ++#if 0 ++ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_TDLS_STA(prStaRec))) { ++ /* ++ test plan: The STAUT should locally tear down existing TDLS direct link and ++ respond with Set up Response frame. ++ */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++#endif ++ } ++ ++ /* reference to bssCreateStaRecFromBssDesc() and use our best capability */ ++ /* reference to assocBuildReAssocReqFrameCommonIEs() to fill elements */ ++ ++ /* prStaRec->u2CapInfo */ ++ /* TODO: Need to parse elements from setup request frame */ ++ prStaRec->u2OperationalRateSet = prAisBssInfo->u2OperationalRateSet; ++ prStaRec->u2BSSBasicRateSet = prAisBssInfo->u2BSSBasicRateSet; ++ prStaRec->u2DesiredNonHTRateSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet; ++ prStaRec->ucPhyTypeSet = prAisBssInfo->ucPhyTypeSet; ++ prStaRec->eStaType = STA_TYPE_TDLS_PEER; ++ ++ prStaRec->ucDesiredPhyTypeSet = /*prStaRec->ucPhyTypeSet & */ ++ prAdapter->rWifiVar.ucAvailablePhyTypeSet; ++ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; ++ ++ /* check for Target BSS's non HT Phy Types */ ++ if (ucNonHTPhyTypeSet) { ++ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; ++ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; ++ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ ++ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++ prStaRec->fgHasBasicPhyType = TRUE; ++ } else { ++ /* use mandatory for 11N only BSS */ ++/* ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); */ ++ ++ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; ++ prStaRec->fgHasBasicPhyType = FALSE; ++ } ++ ++ /* update non HT Desired Rate Set */ ++ { ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prStaRec->u2DesiredNonHTRateSet = ++ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); ++ } ++ ++#if 0 /* TdlsexPeerAdd() will be called before we receive setup rsp in TdlsexRxFrameHandle() */ ++ /* check if the add is from the same peer in the 1st unhandled setup request frame */ ++ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", ++ __func__, prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac); ++ ++ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { ++ /* copy the HT capability from its setup request */ ++ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); ++ ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); ++ ++ /* reset backup */ ++ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); ++ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); ++ ++ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); ++ } ++#endif ++ ++ /* update WMM: must support due to UAPSD in TDLS link */ ++ prStaRec->fgIsWmmSupported = TRUE; ++ prStaRec->fgIsUapsdSupported = TRUE; ++ ++ /* update station record to firmware */ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ ++ /* update time */ ++ GET_CURRENT_SYSTIME(&prStaRec->rTdlsSetupStartTime); ++ ++ DBGLOG(TDLS, INFO, " %s: create a peer [%pM]\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to update a peer record. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexPeerUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ TDLS_CMD_PEER_UPDATE_T *prCmd; ++ BSS_INFO_T *prAisBssInfo; ++ STA_RECORD_T *prStaRec; ++ IE_HT_CAP_T *prHtCap; ++ ++ /* sanity check */ ++ DBGLOG(TDLS, INFO, " %s\n", __func__); ++ ++ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { ++ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); ++ prCmd = (TDLS_CMD_PEER_UPDATE_T *) pvSetBuffer; ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ /* search old entry */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); ++ ++ /* ++ create new entry if not exist ++ ++ 1. we are initiator ++ (1) send TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) got TDLS setup response and send TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ ++ 2. we are responder ++ (1) got TDLS setup request ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); ++ create a station record with STA_STATE_1. ++ (2) send TDLS setup response ++ (3) got TDLS setup confirm ++ wpa_tdls_enable_link() ++ update a station record with STA_STATE_3. ++ */ ++ if ((prStaRec == NULL) || (prStaRec->fgIsInUse == 0)) { ++ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ DBGLOG(TDLS, INFO, " %s: update a peer [%pM] %d -> %d, 0x%x\n", ++ __func__, (prStaRec->aucMacAddr), ++ prStaRec->ucStaState, STA_STATE_3, prStaRec->eStaType); ++ ++ if (!IS_TDLS_STA(prStaRec)) { ++ DBGLOG(TDLS, ERROR, " %s: peer is not TDLS one!\n", __func__); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* check if the add is from the same peer in the 1st unhandled setup request frame */ ++ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", ++ __func__, (prGlueInfo->aucTdlsHtPeerMac), (prCmd->aucPeerMac)); ++ ++ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { ++ /* copy the HT capability from its setup request */ ++ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); ++ ++ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); ++ ++ /* reset backup */ ++ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); ++ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); ++ ++ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); ++ } ++ ++ /* update the record join time. */ ++ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); ++ ++ /* update Station Record - Status/Reason Code */ ++ prStaRec->u2StatusCode = prCmd->u2StatusCode; ++ ++ /* prStaRec->ucStaState shall be STA_STATE_1 */ ++ ++ prStaRec->u2CapInfo = prCmd->u2Capability; ++/* prStaRec->u2OperationalRateSet */ ++ prStaRec->u2AssocId = 0; /* no use */ ++ prStaRec->u2ListenInterval = 0; /* unknown */ ++/* prStaRec->ucDesiredPhyTypeSet */ ++/* prStaRec->u2DesiredNonHTRateSet */ ++/* prStaRec->u2BSSBasicRateSet */ ++/* prStaRec->ucMcsSet */ ++/* prStaRec->fgSupMcs32 */ ++/* prStaRec->u2HtCapInfo */ ++ prStaRec->fgIsQoS = TRUE; ++ prStaRec->fgIsUapsdSupported = (prCmd->UapsdBitmap == 0) ? FALSE : TRUE; ++/* prStaRec->ucAmpduParam */ ++/* prStaRec->u2HtExtendedCap */ ++ prStaRec->u4TxBeamformingCap = 0; /* no use */ ++ prStaRec->ucAselCap = 0; /* no use */ ++ prStaRec->ucRCPI = 0; ++ prStaRec->ucBmpTriggerAC = prCmd->UapsdBitmap; ++ prStaRec->ucBmpDeliveryAC = prCmd->UapsdBitmap; ++ prStaRec->ucUapsdSp = prCmd->UapsdMaxSp; ++ ++ /* update HT */ ++#if (TDLS_CFG_HT_SUP == 1) ++ if (prCmd->fgIsSupHt == FALSE) { ++ /* no HT IE is from supplicant so we use the backup */ ++ prHtCap = (IE_HT_CAP_T *) &prStaRec->rTdlsHtCap; ++ ++ DBGLOG(TDLS, INFO, " %s: [%pM] update ht ie 0x%x\n", ++ __func__, (prStaRec->aucMacAddr), prHtCap->ucId); ++ ++ if (prHtCap->ucId == ELEM_ID_HT_CAP) { ++ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; ++ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; ++ ++ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; ++ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; ++ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; ++ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; ++ prStaRec->ucAselCap = prHtCap->ucAselCap; ++ prStaRec->ucDesiredPhyTypeSet |= PHY_TYPE_SET_802_11N; ++ } ++ } else { ++ /* TODO: use the HT IE from supplicant */ ++ } ++#endif /* TDLS_CFG_HT_SUP */ ++ ++ DBGLOG(TDLS, INFO, " %s: UAPSD 0x%x %d MCS=0x%x\n", ++ __func__, prCmd->UapsdBitmap, prCmd->UapsdMaxSp, prStaRec->ucMcsSet); ++ ++/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ ++ ++ DBGLOG(TDLS, INFO, " %s: update a peer [%pM]\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to check if we need to drop a TDLS action frame. ++* ++* \param[in] *pPkt Pointer to the struct sk_buff->data. ++* \param[in] ++* \param[in] ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt) ++{ ++ ADAPTER_T *prAdapter; ++ UINT8 ucActionId; ++ ++ /* sanity check */ ++ if ((pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) ++ return FALSE; /* not TDLS data frame htons(0x890d) */ ++ ++#if 0 /* supplicant handles this check */ ++ if (prStaRec == NULL) ++ return FALSE; /* shall not be here */ ++ ++ DBGLOG(TDLS, INFO, ++ " %s: Rcv a TDLS action frame (id=%d) %d %d\n", ++ __func__, *(pPkt + 13 + 4), prStaRec->fgTdlsIsProhibited, fgIsPtiTimeoutSkip); ++ ++ /* check if TDLS Prohibited bit is set in AP's beacon */ ++ if (prStaRec->fgTdlsIsProhibited == TRUE) ++ return TRUE; ++#endif ++ ++ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ ++ ++ if (fgIsPtiTimeoutSkip == TRUE) { ++ /* also skip any tear down frame from the peer */ ++ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) ++ return TRUE; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ DBGLOG(TDLS, INFO, ++ " %s: Rcv a TDLS action frame %d (%u)\n", ++ __func__, ucActionId, (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ ++ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) { ++ DBGLOG(TDLS, WARN, " %s: Rcv a TDLS tear down frame %d, will DISABLE link\n", ++ __func__, *(pPkt + 13 + 4)); /* reason code */ ++ ++ /* record disconnect history */ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, pPkt + 6, FALSE, *(pPkt + 13 + 4), NULL); ++ ++ /* inform tear down to supplicant only in OPEN/NONE mode */ ++ /* ++ we need to tear down the link manually; or supplicant will display ++ "No FTIE in TDLS Teardown" and it will not tear down the link ++ */ ++ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, ++ pPkt + 6, TDLS_FRM_ACTION_TEARDOWN, *(pPkt + 13 + 4), GFP_ATOMIC); ++ } ++#if 0 /* pass all to supplicant except same thing is handled in supplicant */ ++ if (((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI) || ++ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_REQ) || ++ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_RSP) || ++ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI_RSP)) { ++ return TRUE; ++ } ++#endif ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to parse some IEs in the setup frame from the peer. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] pPkt Pointer to the ethernet packet ++* ++* \retval None ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen) ++{ ++ ADAPTER_T *prAdapter; ++ STA_RECORD_T *prStaRec; ++ UINT8 ucActionId; ++ UINT8 *pucPeerMac, ucElmId, ucElmLen; ++ INT16 s2FmeLen; ++ ++ /* sanity check */ ++ if ((prGlueInfo == NULL) || (pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) ++ return; ++ ++ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ ++ ++ if ((ucActionId != TDLS_FRM_ACTION_SETUP_REQ) && (ucActionId != TDLS_FRM_ACTION_SETUP_RSP)) ++ return; ++ ++ /* init */ ++ prAdapter = prGlueInfo->prAdapter; ++ pucPeerMac = pPkt + 6; ++ s2FmeLen = (INT16) u2PktLen; ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: get a setup frame %d from %pM\n", ++ __func__, ucActionId, (pucPeerMac)); ++ ++ if (ucActionId == TDLS_FRM_ACTION_SETUP_REQ) ++ pPkt += 12 + 2 + 2 + 1 + 1 + 2; /* skip action, dialog token, capability */ ++ else ++ pPkt += 12 + 2 + 2 + 1 + 2 + 1 + 2; /* skip action, status code, dialog token, capability */ ++ ++ /* check station record */ ++ prStaRec = cnmGetStaRecByAddress(prGlueInfo->prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, pucPeerMac); ++ ++ if (prStaRec == NULL) { ++ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); ++ ++ if (prStaRec == NULL) { ++ /* TODO: only one TDLS entry, need to free old one if timeout */ ++ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); ++ return; ++ } ++ ++ /* init the prStaRec */ ++ /* prStaRec will be zero first in cnmStaRecAlloc() */ ++ COPY_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMac); ++ ++ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); ++ } ++ ++ /* backup HT IE to station record */ ++ /* TODO: Maybe our TDLS only supports non-11n */ ++ while (s2FmeLen > 0) { ++ ucElmId = *pPkt++; ++ ucElmLen = *pPkt++; ++ ++ switch (ucElmId) { ++ case ELEM_ID_HT_CAP: /* 0x2d */ ++ /* backup the HT IE of 1st unhandled setup request frame */ ++ if (prGlueInfo->rTdlsHtCap.ucId == 0x00) { ++ kalMemCopy(prGlueInfo->aucTdlsHtPeerMac, pucPeerMac, 6); ++ kalMemCopy(&prGlueInfo->rTdlsHtCap, pPkt - 2, ucElmLen + 2); ++ ++ /* ++ cannot backup in prStaRec; or ++ ++ 1. we build a TDLS link ++ 2. peer re-sends setup req ++ 3. we backup HT cap element ++ 4. supplicant disables the link ++ 5. we clear the prStaRec ++ */ ++ ++ DBGLOG(TDLS, TRACE, ++ " %s: %pM: find a HT IE\n", ++ __func__, (pucPeerMac)); ++ } ++ return; ++ ++ case ELEM_ID_EXTENDED_CAP: ++ /* TODO: backup the extended capability IE */ ++ break; ++ } ++ ++ pPkt += ucElmLen; ++ s2FmeLen -= (2 + ucElmLen); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! \brief This routine is called to get the TDLS station record. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure ++* \param[in] prInBuf A pointer to the command string buffer ++* \param[in] u4InBufLen The length of the buffer ++* \param[out] None ++* ++* \retval TDLS_STATUS_SUCCESS: this is TDLS packet ++* TDLS_STATUS_FAILURE: this is not TDLS packet ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo) ++{ ++ BSS_INFO_T *prBssInfo; ++ STA_RECORD_T *prStaRec; ++ TDLS_STATUS Status; ++ ++ /* sanity check */ ++ if ((prAdapter == NULL) || (prMsduInfo == NULL)) ++ return TDLS_STATUS_FAILURE; ++ ++ if (prAdapter->prGlueInfo == NULL) ++ return TDLS_STATUS_FAILURE; ++ if (TDLS_IS_NO_LINK_GOING(prAdapter->prGlueInfo)) ++ return TDLS_STATUS_FAILURE; ++ ++ /* init */ ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; ++ Status = TDLS_STATUS_SUCCESS; ++ ++ /* get record by ether dest */ ++ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMsduInfo->aucEthDestAddr); ++ ++ /* ++ TDLS Setup Request frames, TDLS Setup Response frames and TDLS Setup Confirm ++ frames shall be transmitted through the AP and shall not be transmitted to a group ++ address. ++ ++ 1. In first time, prStaRec == NULL or prStaRec->ucStaState != STA_STATE_3, ++ we will send them to AP; ++ 2. When link is still on, if you command to send TDLS setup from supplicant, ++ supplicant will DISABLE LINK first, prStaRec will be NULL then send TDLS ++ setup frame to the peer. ++ */ ++ ++ do { ++ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3) && (IS_TDLS_STA(prStaRec))) { ++ /* ++ TDLS Test Case 5.3 Tear Down ++ Automatically sends TDLS Teardown frame to STA 2 via AP ++ ++ 11.21.5 TDLS Direct Link Teardown ++ The TDLS Teardown frame shall be sent over the direct path and the reason ++ code shall be set to "TDLS 40 direct link teardown for unspecified reason", ++ except when the TDLS peer STA is unreachable via the TDLS direct link, ++ in which case, the TDLS Teardown frame shall be sent through the AP and ++ the reason code shall be set to "TDLS direct link teardown due to TDLS peer ++ STA unreachable via the TDLS direct link". ++ */ ++ /* if (prStaRec->fgIsInPS == TRUE) */ ++ /* ++ check if the packet is tear down: ++ we do not want to use PTI to indicate the tear down and ++ we want to send the tear down to AP then AP help us to send it ++ */ ++ struct sk_buff *prSkb; ++ UINT8 *pEth; ++ UINT_16 u2EtherTypeLen; ++ ++ prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ if (prSkb != NULL) { ++ UINT8 ucActionCode, ucReasonCode; ++ ++ /* init */ ++ pEth = prSkb->data; ++ u2EtherTypeLen = (pEth[ETH_TYPE_LEN_OFFSET] << 8) | ++ (pEth[ETH_TYPE_LEN_OFFSET + 1]); ++ ucActionCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 3]; ++ ucReasonCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] | ++ (pEth[ETH_TYPE_LEN_OFFSET + 1 + 5] << 8); ++ ++ /* TDLS_REASON_CODE_UNREACHABLE: keep alive fail or PTI timeout */ ++ if ((u2EtherTypeLen == TDLS_FRM_PROT_TYPE) && ++ (ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && ++ (ucReasonCode == TDLS_REASON_CODE_UNREACHABLE)) { ++ /* ++ when we cannot reach the peer, ++ we need AP's help to send the tear down frame ++ */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prStaRec = prBssInfo->prStaRecOfAP; ++ if (prStaRec == NULL) { ++ Status = TDLS_STATUS_FAILURE; ++ break; ++ } ++#if 0 ++ /* change status code */ ++ pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] = TDLS_REASON_CODE_UNREACHABLE; ++#endif ++ } ++ } ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ } ++ } while (FALSE); ++ ++ DBGLOG(TDLS, INFO, " %s: (Status=%x) [%pM] ucStaRecIndex = %d!\n", ++ __func__, (INT32) Status, (prMsduInfo->aucEthDestAddr), ++ prMsduInfo->ucStaRecIndex); ++ return Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to check if we suffer timeout for TX quota empty case. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota) ++{ ++ OS_SYSTIME rCurTime; ++ ++ /* sanity check */ ++ if (!IS_TDLS_STA(prStaRec)) ++ return; ++ ++ if (FreeQuota != 0) { ++ /* reset timeout */ ++ prStaRec->rTdlsTxQuotaEmptyTime = 0; ++ return; ++ } ++ ++ /* work-around: check if the no free quota case is too long */ ++ GET_CURRENT_SYSTIME(&rCurTime); ++ ++ if (prStaRec->rTdlsTxQuotaEmptyTime == 0) { ++ prStaRec->rTdlsTxQuotaEmptyTime = rCurTime; ++ } else { ++ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsTxQuotaEmptyTime, ++ SEC_TO_SYSTIME(TDLS_TX_QUOTA_EMPTY_TIMEOUT))) { ++ /* tear down the link */ ++ DBGLOG(TDLS, WARN, ++ " %s: [%pM] TX quota empty timeout!\n", ++ __func__, (prStaRec->aucMacAddr)); ++ ++ /* record disconnect history */ ++ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, ++ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY, NULL); ++ ++ /* inform tear down to supplicant only in OPEN/NONE mode */ ++ /* ++ we need to tear down the link manually; or supplicant will display ++ "No FTIE in TDLS Teardown" and it will not tear down the link ++ */ ++ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, ++ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, ++ TDLS_REASON_CODE_UNREACHABLE, GFP_ATOMIC); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to un-initialize variables in TDLS. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID TdlsexUninit(ADAPTER_T *prAdapter) ++{ ++#if TDLS_CFG_CMD_TEST ++ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); ++#endif /* TDLS_CFG_CMD_TEST */ ++} ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++/* End of tdls.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c +new file mode 100644 +index 000000000000..5450cbb65183 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c +@@ -0,0 +1,741 @@ ++/* ++** Id: tdls_com.c#1 ++*/ ++ ++/*! \file tdls_com.c ++ \brief This file includes IEEE802.11z TDLS main support. ++*/ ++ ++/* ++** Log: tdls_com.c ++ * ++ * 11 13 2013 vend_samp.lin ++ * NULL ++ * Initial version. ++ */ ++ ++/******************************************************************************* ++ * C O M P I L E R F L A G S ++ ******************************************************************************** ++ */ ++ ++/******************************************************************************* ++ * E X T E R N A L R E F E R E N C E S ++ ******************************************************************************** ++ */ ++ ++#include "precomp.h" ++ ++#if (CFG_SUPPORT_TDLS == 1) ++#include "tdls.h" ++ ++ /******************************************************************************* ++ * C O N S T A N T S ++ ******************************************************************************** ++ */ ++ ++ /******************************************************************************* ++ * F U N C T I O N D E C L A R A T I O N S ++ ******************************************************************************** ++ */ ++ ++ /******************************************************************************* ++ * P R I V A T E D A T A ++ ******************************************************************************** ++ */ ++ ++ /******************************************************************************* ++ * P R I V A T E F U N C T I O N S ++ ******************************************************************************** ++ */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to append general IEs. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] prStaRec Pointer to the STA_RECORD_T structure. ++* \param[in] u2StatusCode Status code. ++* \param[in] pPkt Pointer to the frame body ++* ++* \retval append length ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt) ++{ ++ GLUE_INFO_T *prGlueInfo; ++ BSS_INFO_T *prBssInfo; ++ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; ++ UINT_32 u4NonHTPhyType; ++ UINT_16 u2SupportedRateSet; ++ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; ++ UINT_8 ucAllSupportedRatesLen; ++ UINT_8 ucSupRatesLen; ++ UINT_8 ucExtSupRatesLen; ++ UINT_32 u4PktLen, u4IeLen; ++ BOOLEAN fg40mAllowed; ++ ++ /* reference to assocBuildReAssocReqFrameCommonIEs() */ ++ ++ /* init */ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ u4PktLen = 0; ++ ++ /* 3. Frame Formation - (5) Supported Rates element */ ++ /* use all sup rate we can support */ ++ if (prStaRec != NULL) ++ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; ++ else ++ u4NonHTPhyType = PHY_TYPE_ERP_INDEX; /* default */ ++ ++ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; ++ ++ if (prStaRec != NULL) { ++ u2SupportedRateSet &= prStaRec->u2OperationalRateSet; ++ ++ if (u2SupportedRateSet == 0) ++ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; ++ } ++ ++ rateGetDataRatesFromRateSet(u2SupportedRateSet, ++ prBssInfo->u2BSSBasicRateSet, aucAllSupportedRates, &ucAllSupportedRatesLen); ++ ++ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? ++ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); ++ ++ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; ++ ++ if (ucSupRatesLen) { ++ SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES; ++ SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen; ++ kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (7) Extended sup rates element */ ++ if (ucExtSupRatesLen) { ++ ++ EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES; ++ EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen; ++ ++ kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates, ++ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (8) Supported channels element */ ++ /* ++ The Supported channels element is included in Request frame and also in Response ++ frame if Status Code 0 (successful). ++ */ ++ if (u2StatusCode == 0) { ++ SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 11; ++ ++#if CFG_SUPPORT_DFS ++ if (prAdapter->fgEnable5GBand == TRUE) { ++ /* 5G support */ ++ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165; ++ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 4; ++ } ++#endif /* CFG_SUPPORT_DFS */ ++ ++ u4IeLen = IE_SIZE(pPkt); ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (14) HT capabilities element */ ++ ++ /* no need to check AP capability */ ++/* if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && */ ++ ++ /* ++ after we set ucPhyTypeSet to PHY_TYPE_SET_802_11N in TdlsexRxFrameHandle(), ++ supplicant will disable link if exists and we will clear prStaRec. ++ ++ finally, prStaRec->ucPhyTypeSet will also be 0 ++ ++ so we have a fix in TdlsexPeerAdd(). ++ */ ++ if (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { ++ /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */ ++#if 0 /* always support */ ++ if (prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode == CONFIG_BW_20M) ++ fg40mAllowed = FALSE; ++ else ++#endif ++ fg40mAllowed = TRUE; ++ ++ u4IeLen = rlmFillHtCapIEByParams(fg40mAllowed, ++ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, ++ prAdapter->rWifiVar.u8SupportRxSgi20, ++ prAdapter->rWifiVar.u8SupportRxSgi40, ++ prAdapter->rWifiVar.u8SupportRxGf, ++ prAdapter->rWifiVar.u8SupportRxSTBC, prBssInfo->eCurrentOPMode, pPkt); ++ ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ /* 3. Frame Formation - (17) WMM Information element */ ++ ++ /* always support */ ++/* if (prAdapter->rWifiVar.fgSupportQoS) */ ++ ++ { ++ /* force to support all UAPSD in TDLS link */ ++ u4IeLen = mqmGenerateWmmInfoIEByParam(TRUE /*prAdapter->rWifiVar.fgSupportUAPSD */ , ++ 0xf /*prPmProfSetupInfo->ucBmpDeliveryAC */ , ++ 0xf /*prPmProfSetupInfo->ucBmpTriggerAC */ , ++ WMM_MAX_SP_LENGTH_ALL /*prPmProfSetupInfo->ucUapsdSp */ , ++ pPkt); ++ ++ pPkt += u4IeLen; ++ u4PktLen += u4IeLen; ++ } ++ ++ return u4PktLen; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to transmit a TDLS data frame (setup req/rsp/confirm and tear down). ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* \param[in] prStaRec Pointer to the STA_RECORD_T structure. ++* \param[in] pPeerMac Pointer to the MAC of the TDLS peer ++* \param[in] ucActionCode TDLS Action ++* \param[in] ucDialogToken Dialog token ++* \param[in] u2StatusCode Status code ++* \param[in] pAppendIe Others IEs (here are security IEs from supplicant) ++* \param[in] AppendIeLen IE length of others IEs ++* ++* \retval TDLS_STATUS_xx ++*/ ++/*----------------------------------------------------------------------------*/ ++TDLS_STATUS ++TdlsDataFrameSend(ADAPTER_T *prAdapter, ++ STA_RECORD_T *prStaRec, ++ UINT_8 *pPeerMac, ++ UINT_8 ucActionCode, ++ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen) ++{ ++#define LR_TDLS_FME_FIELD_FILL(__Len) \ ++do { \ ++ pPkt += __Len; \ ++ u4PktLen += __Len; \ ++} while (0) ++ ++ GLUE_INFO_T *prGlueInfo; ++ BSS_INFO_T *prBssInfo; ++ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; ++ struct sk_buff *prMsduInfo; ++ MSDU_INFO_T *prMsduInfoMgmt; ++ UINT8 *pPkt, *pucInitiator, *pucResponder; ++ UINT32 u4PktLen, u4IeLen; ++ UINT16 u2CapInfo; ++/* UINT8 *pPktTemp; */ ++ ++ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; ++ ++ DBGLOG(TDLS, INFO, " %s: 2040=%d\n", __func__, prGlueInfo->rTdlsLink.fgIs2040Sup); ++ ++ /* sanity check */ ++ if (prStaRec != NULL) { ++ if (prStaRec->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { ++ DBGLOG(TDLS, ERROR, ++ " %s: net index %d fail\n", __func__, prStaRec->ucNetTypeIndex); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ } else { ++ /* prStaRec maybe NULL in setup request */ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ } ++ ++ /* allocate/init packet */ ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ u4PktLen = 0; ++ prMsduInfo = NULL; ++ prMsduInfoMgmt = NULL; ++ ++ /* make up frame content */ ++ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { ++ /* ++ The STAUT will not respond to a TDLS Discovery Request Frame with different BSSID. ++ Supplicant will check this in wpa_tdls_process_discovery_request(). ++ */ ++ ++ /* TODO: reduce 1600 to correct size */ ++ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); ++ if (prMsduInfo == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ prMsduInfo->dev = prGlueInfo->prDevHandler; ++ if (prMsduInfo->dev == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); ++ kalPacketFree(prGlueInfo, prMsduInfo); ++ return TDLS_STATUS_FAILURE; ++ } ++ ++ /* 1. 802.3 header */ ++/* pPktTemp = pPkt; */ ++ kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); ++ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 2. payload type */ ++ *pPkt = TDLS_FRM_PAYLOAD_TYPE; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - (1) Category */ ++ *pPkt = TDLS_FRM_CATEGORY; ++ LR_TDLS_FME_FIELD_FILL(1); ++ } else { ++ /* discovery response */ ++ WLAN_MAC_HEADER_T *prHdr; ++ ++ prMsduInfoMgmt = (MSDU_INFO_T *) ++ cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); ++ if (prMsduInfoMgmt == NULL) { ++ DBGLOG(TDLS, ERROR, " %s: allocate mgmt pkt fail\n", __func__); ++ return TDLS_STATUS_RESOURCES; ++ } ++ ++ pPkt = (UINT8 *) prMsduInfoMgmt->prPacket; ++ prHdr = (WLAN_MAC_HEADER_T *) pPkt; ++ ++ /* 1. 802.11 header */ ++ prHdr->u2FrameCtrl = MAC_FRAME_ACTION; ++ prHdr->u2DurationID = 0; ++ kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); ++ kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN); ++ prHdr->u2SeqCtrl = 0; ++ LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T)); ++ ++ /* Frame Formation - (1) Category */ ++ *pPkt = CATEGORY_PUBLIC_ACTION; ++ LR_TDLS_FME_FIELD_FILL(1); ++ } ++ ++ /* 3. Frame Formation - (2) Action */ ++ *pPkt = ucActionCode; ++ LR_TDLS_FME_FIELD_FILL(1); ++ ++ /* 3. Frame Formation - Status Code */ ++ switch (ucActionCode) { ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_CONFIRM: ++ case TDLS_FRM_ACTION_TEARDOWN: ++ WLAN_SET_FIELD_16(pPkt, u2StatusCode); ++ LR_TDLS_FME_FIELD_FILL(2); ++ break; ++ } ++ ++ /* 3. Frame Formation - (3) Dialog token */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ *pPkt = ucDialogToken; ++ LR_TDLS_FME_FIELD_FILL(1); ++ } ++ ++ /* Fill elements */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ /* ++ Capability ++ ++ Support Rates ++ Extended Support Rates ++ Supported Channels ++ HT Capabilities ++ WMM Information Element ++ ++ Extended Capabilities ++ Link Identifier ++ ++ RSNIE ++ FTIE ++ Timeout Interval ++ */ ++ if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) { ++ /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */ ++ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); ++ WLAN_SET_FIELD_16(pPkt, u2CapInfo); ++ LR_TDLS_FME_FIELD_FILL(2); ++ ++ /* 4. Append general IEs */ ++ /* ++ TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode ++ must be CONFIG_BW_20_40M. ++ ++ TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if ++ Tdls 20/40 is enabled. ++ */ ++ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, u2StatusCode, pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 5. Frame Formation - Extended capabilities element */ ++ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; ++ EXT_CAP_IE(pPkt)->ucLength = 5; ++ ++ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ ++ ++ /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); ++ /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); ++ /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */ ++ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } else { ++ /* 5. Frame Formation - WMM Parameter element */ ++ if (prAdapter->rWifiVar.fgSupportQoS) { ++ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, ++ prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); ++ ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } ++ } ++ } ++ ++ /* 6. Frame Formation - 20/40 BSS Coexistence */ ++ /* ++ Follow WiFi test plan, add 20/40 element to request/response/confirm. ++ */ ++/* if (prGlueInfo->rTdlsLink.fgIs2040Sup == TRUE) */ /* force to enable */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ /* ++ bit0 = 1: The Information Request field is used to indicate that a ++ transmitting STA is requesting the recipient to transmit a 20/40 BSS ++ Coexistence Management frame with the transmitting STA as the ++ recipient. ++ ++ bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP ++ that receives this information or reports of this information from ++ operating a 20/40 MHz BSS. ++ ++ bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit ++ a receiving AP from operating its BSS as a 20/40 MHz BSS. ++ */ ++ BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE; ++ BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; ++ BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; ++ LR_TDLS_FME_FIELD_FILL(3); ++ } ++ ++ /* 6. Frame Formation - HT Operation element */ ++/* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */ ++/* LR_TDLS_FME_FIELD_FILL(u4IeLen); */ ++ ++ /* 7. Frame Formation - Link identifier element */ ++ /* Note1: Link ID sequence must be correct; Or the calculated MIC will be error */ ++ /* ++ Note2: When we receive a setup request with link ID, Marvell will send setup response ++ to the peer in link ID, not the SA in the WLAN header. ++ */ ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; ++ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); ++ ++ switch (ucActionCode) { ++ case TDLS_FRM_ACTION_SETUP_REQ: ++ case TDLS_FRM_ACTION_CONFIRM: ++ default: ++ /* we are initiator */ ++ pucInitiator = prBssInfo->aucOwnMacAddr; ++ pucResponder = pPeerMac; ++ ++ if (prStaRec != NULL) ++ prStaRec->flgTdlsIsInitiator = TRUE; ++ break; ++ ++ case TDLS_FRM_ACTION_SETUP_RSP: ++ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: ++ /* peer is initiator */ ++ pucInitiator = pPeerMac; ++ pucResponder = prBssInfo->aucOwnMacAddr; ++ ++ if (prStaRec != NULL) ++ prStaRec->flgTdlsIsInitiator = FALSE; ++ break; ++ ++ case TDLS_FRM_ACTION_TEARDOWN: ++ if (prStaRec != NULL) { ++ if (prStaRec->flgTdlsIsInitiator == TRUE) { ++ /* we are initiator */ ++ pucInitiator = prBssInfo->aucOwnMacAddr; ++ pucResponder = pPeerMac; ++ } else { ++ /* peer is initiator */ ++ pucInitiator = pPeerMac; ++ pucResponder = prBssInfo->aucOwnMacAddr; ++ } ++ } else { ++ /* peer is initiator */ ++ pucInitiator = pPeerMac; ++ pucResponder = prBssInfo->aucOwnMacAddr; ++ } ++ break; ++ } ++ ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6); ++ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6); ++ ++ u4IeLen = IE_SIZE(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ ++ /* 8. Append security IEs */ ++ /* ++ 11.21.5 TDLS Direct Link Teardown ++ If the STA has security enabled on the link 37 with the AP, then the FTIE shall be ++ included in the TDLS Teardown frame. ++ ++ For ralink station, it can accept our tear down without FTIE but marvell station. ++ */ ++/* if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) */ ++ if (pAppendIe != NULL) { ++ if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) || ++ ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && ++ (prStaRec != NULL) && (prStaRec->fgTdlsInSecurityMode == TRUE))) { ++ kalMemCopy(pPkt, pAppendIe, AppendIeLen); ++ LR_TDLS_FME_FIELD_FILL(AppendIeLen); ++ } ++ } ++ ++ /* 7. Append Supported Operating Classes IE */ ++ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { ++ /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */ ++ u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); ++ LR_TDLS_FME_FIELD_FILL(u4IeLen); ++ } ++ ++ /* 11. send the data or management frame */ ++ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { ++#if 0 ++ /* ++ Note1: remember to modify our MAC & AP MAC & peer MAC in LINK ID ++ Note2: dialog token in rsp & confirm must be same as sender. ++ */ ++ ++#if 1 ++ /* example for Ralink's and Broadcom's TDLS setup request frame in open/none */ ++ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { ++#if 0 ++ /* mediatek */ ++ char buffer[] = { 0x31, 0x04, ++ 0x01, 0x08, 0x02, 0x04, 0x0b, 0x16, 0xc, 0x12, 0x18, 0x24, ++ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, ++ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, ++ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, ++ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, ++ 0x48, 0x01, 0x01, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e ++ }; ++#endif ++ ++#if 1 ++ /* ralink *//* from capability */ ++ char buffer[] = { 0x21, 0x04, ++ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, ++ 0x32, 0x04, 0x0c, 0x18, 0x30, 0x60, ++ 0x24, 0x06, 0x01, 0x0b, 0x24, 0x08, 0x95, 0x04, ++ 0x7f, 0x05, 0x01, 0x00, 0x00, 0x50, 0x20, ++ 0x3b, 0x10, 0x20, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19, ++ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, ++ 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x48, 0x01, 0x01, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f ++ }; ++#endif ++#if 0 ++ /* 6630 */ ++ char buffer[] = { 0x01, 0x01, ++ 0x01, 0x04, 0x02, 0x04, 0x0b, 0x16, ++ 0x24, 0x02, 0x01, 0x0d, ++ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0xff, ++ 0x2d, 0x1a, 0x61, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, ++ 0x48, 0x01, 0x01, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, ++ 0x00, 0x00, 0x00, ++ 0xbf, 0x0c, 0x30, 0x01, 0x80, 0x03, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, ++ 0x00, 0x00 ++ }; ++#endif ++ ++ pPktTemp += 18; ++ memcpy(pPktTemp, buffer, sizeof(buffer)); ++ u4PktLen = 18 + sizeof(buffer); ++ } ++#endif ++ ++#if 1 ++ if (ucActionCode == TDLS_FRM_ACTION_CONFIRM) { ++ /* Note: dialog token must be same as request */ ++#if 1 ++ /* ralink */ ++ char buffer[] = { 0x00, ++ 0x01, 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x00, 0x03, ++ 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, ++ 0x62, 0x32, 0x2f, 0x00 ++ }; ++#endif ++ ++#if 0 ++ /* 6630 */ ++ char buffer[] = { 0x00, ++ 0x01, ++ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, ++ 0x48, 0x01, 0x01, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x3f, 0x00, 0x00, ++ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, ++ 0x00, 0x00, 0x00 ++ }; ++#endif ++ ++#if 0 ++ /* A/D die */ ++ char buffer[] = { 0x00, ++ 0x01, ++ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x6b, 0x00, 0x00, ++ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, ++ 0x00, 0x00, 0x00 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0x38, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, ++ 0x1c, 0x1e, 0x20, 0x21, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e ++ }; ++#endif ++ ++ pPktTemp += 18; ++ memcpy(pPktTemp, buffer, sizeof(buffer)); ++ u4PktLen = 18 + sizeof(buffer); ++ } ++#endif ++ ++#else ++ ++#if 0 ++ /* for test in open/none */ ++ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { ++ char buffer[] = { 0x01, 0x04, ++ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, ++ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, ++ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, ++ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, ++ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, ++ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, ++ 0x48, 0x01, 0x01, ++ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, ++ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, ++ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, ++ 0x1b, 0x1c, 0x1e, 0x20, 0x21 ++ }; ++ ++ pPktTemp += 18; ++ memcpy(pPktTemp, buffer, sizeof(buffer)); ++ u4PktLen = 18 + sizeof(buffer); ++ } ++#endif ++#endif /* 0 */ ++ ++ /* 9. Update packet length */ ++ prMsduInfo->len = u4PktLen; ++ dumpMemory8(prMsduInfo->data, u4PktLen); ++ ++ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); ++ } else { ++ /* ++ A TDLS capable STA that receives a TDLS Discovery Request frame is required to ++ send the response "to the requesting STA, via the direct path." ++ However, prior to establishment of the direct link, the responding STA may not ++ know the rate capabilities of the requesting STA. In this case, the responding ++ STA shall send the TDLS Discovery Response frame using a rate from the ++ BSSBasicRateSet of the BSS to which the STA is currently associated. ++ */ ++ prMsduInfoMgmt->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; ++ prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; ++ prMsduInfoMgmt->ucNetworkType = prBssInfo->ucNetTypeIndex; ++ prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfoMgmt->fgIs802_1x = FALSE; ++ prMsduInfoMgmt->fgIs802_11 = TRUE; ++ prMsduInfoMgmt->u2FrameLength = u4PktLen; ++ prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfoMgmt->pfTxDoneHandler = NULL; ++ prMsduInfoMgmt->fgIsBasicRate = TRUE; /* use basic rate */ ++ ++ /* Send them to HW queue */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt); ++ } ++ ++ return TDLS_STATUS_SUCCESS; ++} ++ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* End of tdls_com.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c +new file mode 100644 +index 000000000000..af66ef95d17c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c +@@ -0,0 +1,491 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1 ++*/ ++ ++/*! \file "wapi.c" ++ \brief This file including the WAPI related function. ++ ++ This file provided the macros and functions library support the wapi ie parsing, ++ cipher and AKM check to help the AP seleced deciding. ++*/ ++ ++/* ++** Log: wapi.c ++** ++** 10 24 2012 wh.su ++** [ALPS00376392] [klocwork 9.1] in wapi.c, line 344 ++** Use MAX_NUM_SUPPORTED_WAPI_AKM_SUITESfor avoid Klocwork warning. ++** ++** 10 24 2012 wh.su ++** [ALPS00376391] [klocwork 9.1] in wapi.c, line 311 ++** Use the MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES for avoid Klccwork waring. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the debug module level. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function ++ * fixed the network type ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 07 20 2010 wh.su ++ * ++ * . ++ * ++ * 04 06 2010 wh.su ++ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query ++ * fixed the firmware return the broadcast frame at wrong tc. ++ * ++ * 03 03 2010 wh.su ++ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize ++ * move the AIS specific variable for security to AIS specific structure. ++ * ++ * 12 18 2009 cm.chang ++ * [BORA00000018]Integrate WIFI part into BORA for the 1st time ++ * . ++ * ++ * Dec 8 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the function to check and update the default wapi tx ++ * ++ * Dec 7 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * adding the generate wapi ie function, and replace the tabe by space ++ * ++ * Nov 23 2009 mtk01088 ++ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++#if CFG_SUPPORT_WAPI ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to generate WPA IE for ++* associate request frame. ++* ++* \param[in] prCurrentBss The Selected BSS description ++* ++* \retval The append WPA IE length ++* ++* \note ++* Called by: AIS module, Associate request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ PUINT_8 pucBuffer; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) ++ return; ++ ++ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); ++ ++ /* ASSOC INFO IE ID: 68 :0x44 */ ++ if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) { ++ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs, ++ prAdapter->prGlueInfo->u2WapiAssocInfoIESz); ++ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to parse WAPI IE. ++* ++* \param[in] prInfoElem Pointer to the RSN IE ++* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the ++** WAPI information from the given WAPI IE ++* ++* \retval TRUE - Succeeded ++* \retval FALSE - Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo) ++{ ++ UINT_32 i; ++ INT_32 u4RemainWapiIeLen; ++ UINT_16 u2Version; ++ UINT_16 u2Cap = 0; ++ UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI; ++ UINT_16 u2PairSuiteCount = 0; ++ UINT_16 u2AuthSuiteCount = 0; ++ PUCHAR pucPairSuite = NULL; ++ PUCHAR pucAuthSuite = NULL; ++ PUCHAR cp; ++ ++ DEBUGFUNC("wapiParseWapiIE"); ++ ++ ASSERT(prInfoElem); ++ ASSERT(prWapiInfo); ++ ++ /* Verify the length of the WAPI IE. */ ++ if (prInfoElem->ucLength < 6) { ++ DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ /* Check WAPI version: currently, we only support version 1. */ ++ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); ++ if (u2Version != 1) { ++ DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", u2Version); ++ return FALSE; ++ } ++ ++ cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount; ++ u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2; ++ ++ do { ++ if (u4RemainWapiIeLen == 0) ++ break; ++ ++ /* ++ AuthCount : 2 ++ AuthSuite : 4 * authSuiteCount ++ PairwiseCount: 2 ++ PairwiseSuite: 4 * pairSuiteCount ++ GroupSuite : 4 ++ Cap : 2 */ ++ ++ /* Parse the Authentication and Key Management Cipher Suite Count ++ field. */ ++ if (u4RemainWapiIeLen < 2) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); ++ cp += 2; ++ u4RemainWapiIeLen -= 2; ++ ++ /* Parse the Authentication and Key Management Cipher Suite List ++ field. */ ++ i = (UINT_32) u2AuthSuiteCount * 4; ++ if (u4RemainWapiIeLen < (INT_32) i) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucAuthSuite = cp; ++ ++ cp += i; ++ u4RemainWapiIeLen -= (INT_32) i; ++ ++ if (u4RemainWapiIeLen == 0) ++ break; ++ ++ /* Parse the Pairwise Key Cipher Suite Count field. */ ++ if (u4RemainWapiIeLen < 2) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); ++ cp += 2; ++ u4RemainWapiIeLen -= 2; ++ ++ /* Parse the Pairwise Key Cipher Suite List field. */ ++ i = (UINT_32) u2PairSuiteCount * 4; ++ if (u4RemainWapiIeLen < (INT_32) i) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ pucPairSuite = cp; ++ ++ cp += i; ++ u4RemainWapiIeLen -= (INT_32) i; ++ ++ /* Parse the Group Key Cipher Suite field. */ ++ if (u4RemainWapiIeLen < 4) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_32(cp, &u4GroupSuite); ++ cp += 4; ++ u4RemainWapiIeLen -= 4; ++ ++ /* Parse the WAPI u2Capabilities field. */ ++ if (u4RemainWapiIeLen < 2) { ++ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n", ++ prInfoElem->ucLength); ++ return FALSE; ++ } ++ ++ WLAN_GET_FIELD_16(cp, &u2Cap); ++ u4RemainWapiIeLen -= 2; ++ ++ /* Todo:: BKID support */ ++ } while (FALSE); ++ ++ /* Save the WAPI information for the BSS. */ ++ ++ prWapiInfo->ucElemId = ELEM_ID_WAPI; ++ ++ prWapiInfo->u2Version = u2Version; ++ ++ prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite; ++ ++ DBGLOG(SEC, LOUD, "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", ++ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), ++ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); ++ ++ if (pucPairSuite) { ++ /* The information about the pairwise key cipher suites is present. */ ++ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES) ++ u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES; ++ ++ prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucPairSuite, &prWapiInfo->au4PairwiseKeyCipherSuite[i]); ++ pucPairSuite += 4; ++ ++ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the pairwise key cipher suites is not present. ++ Use the default chipher suite for WAPI: WPI. */ ++ prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1; ++ prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI; ++ ++ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ if (pucAuthSuite) { ++ /* The information about the authentication and key management suites ++ is present. */ ++ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES) ++ u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES; ++ ++ prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; ++ ++ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { ++ WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]); ++ pucAuthSuite += 4; ++ ++ DBGLOG(SEC, LOUD, "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n", ++ (UINT_8) i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); ++ } ++ } else { ++ /* The information about the authentication and key management suites ++ is not present. Use the default AKM suite for WAPI. */ ++ prWapiInfo->u4AuthKeyMgtSuiteCount = 1; ++ prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X; ++ ++ DBGLOG(SEC, LOUD, "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n", ++ (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), ++ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); ++ } ++ ++ prWapiInfo->u2WapiCap = u2Cap; ++ DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap); ++ ++ return TRUE; ++} /* wapiParseWapiIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to perform WAPI policy selection for a given BSS. ++* ++* \param[in] prAdapter Pointer to the adapter object data area. ++* \param[in] prBss Pointer to the BSS description ++* ++* \retval TRUE - The WAPI policy selection for the given BSS is ++* successful. The selected pairwise and group cipher suites ++* are returned in the BSS description. ++* \retval FALSE - The WAPI policy selection for the given BSS is failed. ++* The driver shall not attempt to join the given BSS. ++* ++* \note The Encrypt status matched score will save to bss for final ap select. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) ++{ ++ UINT_32 i; ++ UINT_32 u4PairwiseCipher = 0; ++ UINT_32 u4GroupCipher = 0; ++ UINT_32 u4AkmSuite = 0; ++ P_WAPI_INFO_T prBssWapiInfo; ++ P_WLAN_INFO_T prWlanInfo; ++ ++ DEBUGFUNC("wapiPerformPolicySelection"); ++ ++ ASSERT(prBss); ++ ++ /* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */ ++ prWlanInfo = &prAdapter->rWlanInfo; ++ ++ if (prBss->fgIEWAPI) { ++ prBssWapiInfo = &prBss->rIEWAPI; ++ } else { ++ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) { ++ DBGLOG(SEC, TRACE, "-- No Protected BSS\n"); ++ return TRUE; ++ } ++ DBGLOG(SEC, TRACE, "WAPI Information Element does not exist.\n"); ++ return FALSE; ++ } ++ ++ /* Select pairwise/group ciphers */ ++ for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) { ++ if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] == ++ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) { ++ u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i]; ++ } ++ } ++ if (prBssWapiInfo->u4GroupKeyCipherSuite == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher) ++ u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite; ++ ++ /* Exception handler */ ++ /* If we cannot find proper pairwise and group cipher suites to join the ++ BSS, do not check the supported AKM suites. */ ++ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { ++ DBGLOG(SEC, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", ++ u4PairwiseCipher, u4GroupCipher); ++ return FALSE; ++ } ++ ++ /* Select AKM */ ++ /* If the driver cannot support any authentication suites advertised in ++ the given BSS, we fail to perform RSNA policy selection. */ ++ /* Attempt to find any overlapping supported AKM suite. */ ++ for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) { ++ if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) { ++ u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i]; ++ break; ++ } ++ } ++ ++ if (u4AkmSuite == 0) { ++ DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n"); ++ return FALSE; ++ } ++ ++ DBGLOG(SEC, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4PairwiseCipher & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), ++ (UINT_8) (u4GroupCipher & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), ++ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); ++ ++ DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", ++ (UINT_8) (u4AkmSuite & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), ++ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); ++ ++ return TRUE; ++} /* wapiPerformPolicySelection */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 . ++* ++* \param[in] prStaRec Pointer to the Sta record ++* \param[out] ucWlanIdx The Rx status->wlanidx field ++* ++* \retval TRUE - Succeeded ++* \retval FALSE - Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wapiUpdateTxKeyIdx(IN P_STA_RECORD_T prStaRec, IN UINT_8 ucWlanIdx) ++{ ++ UINT_8 ucKeyId; ++ ++ if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) { ++ ++ ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4); ++ ++ if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) { ++ DBGLOG(RSN, STATE, ++ "Change wapi key index from %d->%d\n", ++ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId); ++ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId; ++ ++ prStaRec->ucWTEntry = ++ (ucKeyId == ++ WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1; ++ } ++ } ++} ++#endif ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c +new file mode 100644 +index 000000000000..f54d22941148 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c +@@ -0,0 +1,301 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1 ++*/ ++ ++/*! \file "wnm.c" ++ \brief This file includes the 802.11v default vale and functions. ++*/ ++ ++/* ++** Log: wnm.c ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_802_11V ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define WNM_MAX_TOD_ERROR 0 ++#define WNM_MAX_TOA_ERROR 0 ++#define MICRO_TO_10NANO(x) ((x)*100) ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++static UINT_8 ucTimingMeasToken; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11v wnm category action frame. ++* ++* ++* \note ++* Called by: Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_ACTION_FRAME prRxFrame; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++ if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) { ++ wnmTimingMeasRequest(prAdapter, prSwRfb); ++ return; ++ } ++#endif ++ ++ DBGLOG(WNM, TRACE, "Unsupport WNM action frame: %d\n", prRxFrame->ucAction); ++} ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to report timing measurement data. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); ++ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return; ++ ++ DBGLOG(WNM, TRACE, "wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA); ++ ++ if (!prStaRec->rWNMTimingMsmt.ucTrigger) ++ return; ++ ++ prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD); ++ prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will handle TxDone(TimingMeasurement) Event. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. ++* @param[in] rTxDoneStatus Return TX status of the Timing Measurement frame. ++* ++* @retval WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ DBGLOG(WNM, LOUD, "EVENT-TX DONE: Current Time = %u\n", kalGetTimeTick()); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ ++ ++ DBGLOG(WNM, TRACE, "wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x", ++ prStaRec->rWNMTimingMsmt.ucDialogToken, ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken, ++ prStaRec->rWNMTimingMsmt.u4ToD, prStaRec->rWNMTimingMsmt.u4ToA); ++ ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; ++ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; ++ ++ wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of wnmRunEventTimgingMeasTxDone() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will compose the Timing Measurement frame. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] prStaRec Pointer to the STA_RECORD_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame; ++ UINT_16 u2PayloadLen; ++ ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; ++ ASSERT(prBssInfo); ++ ++ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); ++ ++ if (!prMsduInfo) ++ return; ++ ++ prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME) ++ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); ++ ++ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; ++ ++ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); ++ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); ++ ++ prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION; ++ prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT; ++ ++ /* 3 Compose the frame body's frame. */ ++ prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; ++ prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken; ++ prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD; ++ prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA; ++ prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR; ++ prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR; ++ ++ u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN; ++ ++ /* 4 Update information of MSDU_INFO_T */ ++ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ ++ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; ++ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; ++ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; ++ prMsduInfo->fgIs802_1x = FALSE; ++ prMsduInfo->fgIs802_11 = TRUE; ++ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; ++ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); ++ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; ++ prMsduInfo->fgIsBasicRate = FALSE; ++ ++ DBGLOG(WNM, TRACE, "wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n", ++ prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, ++ prTxFrame->u4ToD, prTxFrame->u4ToA); ++ ++ /* 4 Enqueue the frame to send this action frame. */ ++ nicTxEnqueueMsdu(prAdapter, prMsduInfo); ++ ++ return; ++ ++} /* end of wnmComposeTimingMeasFrame() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* ++* \brief This routine is called to process the 802.11v timing measurement request. ++* ++* ++* \note ++* Handle Rx mgmt request ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL; ++ P_STA_RECORD_T prStaRec; ++ ++ prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME) prSwRfb->pvHeader; ++ if (!prRxFrame) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return; ++ ++ DBGLOG(WNM, TRACE, "IEEE 802.11: Received Timing Measuremen Request from %pM\n" ++ prStaRec->aucMacAdd); ++ ++ /* reset timing msmt */ ++ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; ++ prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger; ++ if (!prRxFrame->ucTrigger) ++ return; ++ ++ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; ++ ++ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); ++} ++ ++#if WNM_UNIT_TEST ++VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex) ++{ ++ P_STA_RECORD_T prStaRec; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); ++ if ((!prStaRec) || (!prStaRec->fgIsInUse)) ++ return; ++ ++ DBGLOG(WNM, INFO, "IEEE 802.11v: Test Timing Measuremen Request from %pM\n", ++ prStaRec->aucMacAddr); ++ ++ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; ++ prStaRec->rWNMTimingMsmt.ucTrigger = 1; ++ ++ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; ++ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; ++ ++ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); ++} ++#endif ++ ++#endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */ ++ ++#endif /* CFG_SUPPORT_802_11V */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c +new file mode 100644 +index 000000000000..6f1bb6fd771e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c +@@ -0,0 +1,254 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/cmd_buf.c#1 ++*/ ++ ++/*! \file "cmd_buf.c" ++ \brief This file contain the management function of internal Command Buffer ++ for CMD_INFO_T. ++ ++ We'll convert the OID into Command Packet and then send to FW. Thus we need ++ to copy the OID information to Command Buffer for following reasons. ++ 1. The data structure of OID information may not equal to the data structure of ++ Command, we cannot use the OID buffer directly. ++ 2. If the Command was not generated by driver we also need a place to store the ++ information. ++ 3. Because the CMD is NOT FIFO when doing memory allocation (CMD will be generated ++ from OID or interrupt handler), thus we'll use the Block style of Memory Allocation ++ here. ++*/ ++ ++/* ++** Log: cmd_buf.c ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 02 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. clear prPendingCmdInfo properly ++ * * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-13 21:59:08 GMT mtk01084 ++** remove un-neceasary spaces ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-05-20 12:24:26 GMT mtk01461 ++** Increase CMD Buffer - HIF_RX_HW_APPENDED_LEN when doing CMD_INFO_T allocation ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 09:41:08 GMT mtk01461 ++** Add init of Driver Domain MCR flag and fix lint MTK WARN ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-17 19:51:45 GMT mtk01461 ++** allocation function of CMD_INFO_T ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static BOOLEAN fgCmdDumpIsDone = FALSE; ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to initial the MGMT memory pool for CMD Packet. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ QUEUE_INITIALIZE(&prAdapter->rFreeCmdList); ++ ++ for (i = 0; i < CFG_TX_MAX_CMD_PKT_NUM; i++) { ++ prCmdInfo = &prAdapter->arHifCmdDesc[i]; ++ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); ++ } ++ fgCmdDumpIsDone = FALSE; ++} /* end of cmdBufInitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief dump CMD queue and print to trace, for debug use only ++* @param[in] prQueue Pointer to the command Queue to be dumped ++* @param[in] quename Name of the queue ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName) ++{ ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_HEAD(prQueue); ++ ++ DBGLOG(NIC, INFO, "Dump CMD info for %s, Elem number:%u\n", queName, prQueue->u4NumElem); ++ while (prCmdInfo) { ++ P_CMD_INFO_T prCmdInfo1, prCmdInfo2, prCmdInfo3; ++ ++ prCmdInfo1 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo); ++ if (!prCmdInfo1) { ++ DBGLOG(NIC, INFO, "CID:%d SEQ:%d\n", prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); ++ break; ++ } ++ prCmdInfo2 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo1); ++ if (!prCmdInfo2) { ++ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, ++ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum); ++ break; ++ } ++ prCmdInfo3 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo2); ++ if (!prCmdInfo3) { ++ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, ++ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum, ++ prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum); ++ break; ++ } ++ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", ++ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, ++ prCmdInfo1->ucCmdSeqNum, prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum, ++ prCmdInfo3->ucCID, prCmdInfo3->ucCmdSeqNum); ++ prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo3); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Allocate CMD_INFO_T from a free list and MGMT memory pool. ++* ++* @param[in] prAdapter Pointer to the Adapter structure. ++* @param[in] u4Length Length of the frame buffer to allocate. ++* ++* @retval NULL Pointer to the valid CMD Packet handler ++* @retval !NULL Fail to allocat CMD Packet ++*/ ++/*----------------------------------------------------------------------------*/ ++P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("cmdBufAllocateCmdInfo"); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ if (prCmdInfo) { ++ /* Setup initial value in CMD_INFO_T */ ++ /* Start address of allocated memory */ ++ prCmdInfo->pucInfoBuffer = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); ++ ++ if (prCmdInfo->pucInfoBuffer == NULL) { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ prCmdInfo = NULL; ++ ++ DBGLOG(NIC, ERROR, "Allocate prCmdInfo->pucInfoBuffer fail!\n"); ++ } else { ++ prCmdInfo->u2InfoBufLen = 0; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ } ++ fgCmdDumpIsDone = FALSE; ++ } else if (!fgCmdDumpIsDone) { ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ P_QUE_T prCmdQue = &prGlueInfo->rCmdQueue; ++ P_QUE_T prPendingCmdQue = &prAdapter->rPendingCmdQueue; ++ P_TX_TCQ_STATUS_T prTc = &prAdapter->rTxCtrl.rTc; ++ ++ fgCmdDumpIsDone = TRUE; ++ cmdBufDumpCmdQueue(prCmdQue, "waiting Tx CMD queue"); ++ cmdBufDumpCmdQueue(prPendingCmdQue, "waiting response CMD queue"); ++ DBGLOG(NIC, INFO, "Tc4 number:%d\n", prTc->aucFreeBufferCount[TC4_INDEX]); ++ if (prTc->aucFreeBufferCount[TC4_INDEX] != 0) ++ glDoChipReset(); ++ } ++ ++ return prCmdInfo; ++ ++} /* end of cmdBufAllocateCmdInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to free the CMD Packet to the MGMT memory pool. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo CMD Packet handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("cmdBufFreeCmdInfo"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo) { ++ if (prCmdInfo->pucInfoBuffer) { ++ cnmMemFree(prAdapter, prCmdInfo->pucInfoBuffer); ++ prCmdInfo->pucInfoBuffer = NULL; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ } ++ ++ return; ++ ++} /* end of cmdBufFreeCmdPacket() */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c +new file mode 100644 +index 000000000000..dfaaedd118bf +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c +@@ -0,0 +1,4062 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#2 ++*/ ++ ++/*! \file nic.c ++ \brief Functions that provide operation in NIC's (Network Interface Card) point of view. ++ ++ This file includes functions which unite multiple hal(Hardware) operations ++ and also take the responsibility of Software Resource Management in order ++ to keep the synchronization with Hardware Manipulation. ++*/ ++ ++/* ++** Log: nic.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 05 02 2012 terry.wu ++ * NULL ++ * Set the default value of AP StaRec index to "STA_REC_INDEX_NOT_FOUND" in update firmware bss command. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 11 28 2011 cp.wu ++ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when ++ * returining to ROM code ++ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware ++ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not ++ * ++ * 11 22 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * keep debug counter setting after wake up. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 04 2011 cp.wu ++ * [WCXRP00001079] [MT5931][Driver] Release pending MMPDU only when BSS is being deactivated ++ * pre-check for NULL before calling MMPDU free function ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. ++ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to ++ * the AP.. ++ * ++ * 10 11 2011 terry.wu ++ * NULL ++ * Rewrite Assert Dump Function for Portability. ++ * ++ * 09 20 2011 cm.chang ++ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time ++ * New CMD definition about RLM parameters ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 08 03 2011 terry.wu ++ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode ++ * Reply Probe Rsp in FW for Hotspot Mode. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device ++ * issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 07 11 2011 wh.su ++ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for ++ * customer not enable WAPI ++ * For make sure wapi initial value is set. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky ++ * AP which use space character as hidden SSID ++ * 1. correct logic ++ * 2. replace only BSS-DESC which doesn't have a valid SSID. ++ * ++ * 06 27 2011 cp.wu ++ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky ++ * AP which use space character as hidden SSID ++ * allow to have a single BSSID with multiple SSID to be presented in scanning result ++ * ++ * 05 12 2011 puff.wen ++ * NULL ++ * FW Assert information dump to driver ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 15 2011 cp.wu ++ * [WCXRP00000651] [MT6620 Wi-Fi][Driver] Refine RSSI buffering mechanism ++ * ROLLBACK due to the special design is to workaround incorrect initial RCPI value coming from firmware domain. ++ * ++ * 04 14 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 14 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected ++ * 2. add dummy function for both Win32 and Linux part. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for ++ * dedicated network type ++ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected ++ * ++ * 04 12 2011 wh.su ++ * NULL ++ * enable the p2p check the cipher to set the bssInfo auth mode. ++ * ++ * 04 12 2011 wh.su ++ * NULL ++ * prepare the code for sync the auth mode and encryption status for P2P and BOW. ++ * ++ * 04 11 2011 yuche.tsai ++ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. ++ * Fix kernel panic issue when MMPDU of P2P is pending in driver. ++ * ++ * 04 10 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * Fix compiler issue. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 04 07 2011 cp.wu ++ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside ++ * wlanAdapterStart ++ * . ++ * ++ * 04 07 2011 cp.wu ++ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside ++ * wlanAdapterStart ++ * implementation of internal error handling of nicAllocateAdapterMemory. ++ * ++ * 03 31 2011 chinglan.wang ++ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. ++ * . ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 10 2011 cm.chang ++ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module ++ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 08 2011 terry.wu ++ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log ++ * Use kalPrint to print firmware assert info. ++ * ++ * 02 01 2011 terry.wu ++ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log ++ * . ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 31 2011 terry.wu ++ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log ++ * Print firmware ASSERT info at Android kernel log, driver side ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 19 2011 cp.wu ++ * [WCXRP00000372] [MT6620 Wi-Fi][Driver] Check bus access failure inside nicProcessIST() ++ * check bus error and/or card removal when retrieving interrupt status from HAL ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * 1) correct typo in scan.c ++ * 2) TX descriptors, RX descriptos and management buffer should use virtually continuous buffer instead of ++ * physically contineous one ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * host driver not to set FW-own when there is still pending interrupts ++ * ++ * 12 17 2010 cp.wu ++ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged ++ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk ++ * 1. BSSINFO include RLM parameter ++ * 2. free all sta records when network is disconnected ++ * ++ * 12 02 2010 eddie.chen ++ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry ++ * Add more control value but dont use it now. ++ * ++ * 11 30 2010 eddie.chen ++ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry ++ * Add auto rate check window in registry ++ * ++ * 11 10 2010 eddie.chen ++ * [WCXRP00000156] [MT6620][FW] Change Auto rate window to 64 and add throughput swcr ++ * Use autorate parameter 1 as phy rate mask. ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 10 26 2010 eddie.chen ++ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB ++ * Add auto rate parameter in registry. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to ++ * BSOD when entering RF test with AIS associated ++ * 1. remove redundant variables in STA_REC structure ++ * 2. add STA-REC uninitialization routine for clearing pending events ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A ++ * reset ptrs when IEs are going to be dropped ++ * ++ * 10 12 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * add HT (802.11n) fixed rate support. ++ * ++ * 10 08 2010 cp.wu ++ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test ++ * adding fixed rate support for distance test. (from registry setting) ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test ++ * with AIS associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * Androi/Linux: return current operating channel information ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 26 2010 yuche.tsai ++ * NULL ++ * Fix someones coding error while enable WIFI_DIRECT. ++ * ++ * 08 25 2010 george.huang ++ * NULL ++ * update OID/ registry control path for PM related settings ++ * ++ * 08 24 2010 cm.chang ++ * NULL ++ * Support RLM initail channel of Ad-hoc, P2P and BOW ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 08 23 2010 chinghwa.yu ++ * NULL ++ * Update for BOW. ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Add state change indication. ++ * ++ * 08 16 2010 yuche.tsai ++ * NULL ++ * Add support for P2P BSS update info. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [removing debugging] not to dump beacon content. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 11 2010 cp.wu ++ * NULL ++ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) ++ * 2) extending scanning result to 64 instead of 48 ++ * ++ * 08 04 2010 yarco.yang ++ * NULL ++ * Add TX_AMPDU and ADDBA_REJECT command ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo ++ * 2) change nicMediaStateChange() API prototype ++ * ++ * 07 28 2010 cp.wu ++ * NULL ++ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 23 2010 cp.wu ++ * ++ * FIX: structure of CMD_SET_BSS_INFO has been changed but no follow-ups are done. ++ * ++ * 07 22 2010 george.huang ++ * ++ * . ++ * ++ * 07 22 2010 george.huang ++ * ++ * Update fgIsQoS information in BSS INFO by CMD ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * update prStaRecOfAP with BSS-INFO. ++ * ++ * 07 06 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Update arguments for nicUpdateBeaconIETemplate() ++ * ++ * 07 06 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * STA-REC is maintained by CNM only. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) ignore RSN checking when RSN is not turned on. ++ * 2) set STA-REC deactivation callback as NULL ++ * 3) add variable initialization API based on PHY configuration ++ * ++ * 07 01 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Support sync command of STA_REC ++ * ++ * 06 30 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync. with CMD/EVENT document ver0.07. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. ++ * ++ * 06 29 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) sync to. CMD/EVENT document v0.03 ++ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. ++ * 3) send command packet to indicate FW-PM after ++ * a) 1st beacon is received after AIS has connected to an AP ++ * b) IBSS-ALONE has been created ++ * c) IBSS-MERGE has occurred ++ * ++ * 06 25 2010 george.huang ++ * [WPD00001556]Basic power managemenet function ++ * Create beacon update path, with expose bssUpdateBeaconContent() ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill fgIsUapsdConnection when indicating BSS-CREATE with AIS-STA mode. ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement TX_DONE callback path. ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * TX descriptors are now allocated once for reducing allocation overhead ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add channel frequency <-> number conversion ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver ++ * correct nicProcessIST_impl() for interrupt status brought up by RX enhanced response ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response ++ * ++ * 03 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always process TX interrupt first then RX interrupt. ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add checksum offloading support. ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-16 18:03:43 GMT mtk02752 ++** handling enhanced response which fields are fetched at different moments ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-15 17:00:29 GMT mtk02752 ++** if RX enhanced response is used, D2H interrupt status should be coming from buffered result as well ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-15 12:01:55 GMT mtk02752 ++** if TX_DONE bit is not set but WTSR0/WTSR1 is non-zero, then set TX_DONE ++** bit due to time latency of interrupt status enhanced response ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:52:52 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-24 20:51:01 GMT mtk02752 ++** integrate with SD1 by invoking qmHandleMailboxRxMessage() ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-16 17:32:33 GMT mtk02752 ++** prepare code for invoking rxHandleMailboxRxMessage() ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:08 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-09 22:56:41 GMT mtk01084 ++** modify HW access routines ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:20 GMT mtk01084 ++** prevent warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:54:57 GMT mtk01084 ++** init HIF ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:30 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:12 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-09-09 17:26:15 GMT mtk01084 ++** modify for CFG_TEST_WITH_MT5921 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-19 10:55:22 GMT mtk01461 ++** Unmask the unused HISR ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-18 15:59:13 GMT mtk01084 ++** remove debug purpose code ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 14:05:02 GMT mtk01084 ++** update for WIFI ownback part on initial ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-04 21:32:57 GMT mtk01084 ++** add temporarily code to set driver own on adapter initialization ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:35:41 GMT mtk01461 ++** Add init of TX aggregation and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-24 21:12:10 GMT mtk01104 ++** Add function nicRestoreSpiDefMode() ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:43:31 GMT mtk01461 ++** Revise for MTK coding style - nicInitializeAdapter() ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:52:47 GMT mtk01461 ++** Update allocate Adapter Memory for MGMT Memory pool ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:57:08 GMT mtk01461 ++** Refine the order of release memory from pucRxCoalescingBufCached ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-19 18:32:57 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:00:14 GMT mtk01426 ++** Add CFG_SDIO_RX_ENHANCE support ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:27 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:25:59 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++const UINT_8 aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] = { ++ PHY_TYPE_SET_802_11ABG, /* PHY_CONFIG_802_11ABG */ ++ PHY_TYPE_SET_802_11BG, /* PHY_CONFIG_802_11BG */ ++ PHY_TYPE_SET_802_11G, /* PHY_CONFIG_802_11G */ ++ PHY_TYPE_SET_802_11A, /* PHY_CONFIG_802_11A */ ++ PHY_TYPE_SET_802_11B, /* PHY_CONFIG_802_11B */ ++ PHY_TYPE_SET_802_11ABGN, /* PHY_CONFIG_802_11ABGN */ ++ PHY_TYPE_SET_802_11BGN, /* PHY_CONFIG_802_11BGN */ ++ PHY_TYPE_SET_802_11AN, /* PHY_CONFIG_802_11AN */ ++ PHY_TYPE_SET_802_11GN /* PHY_CONFIG_802_11GN */ ++}; ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++#define REQ_GATING_ENABLE_H2D_INT BIT(31) ++#define REQ_GATING_DISABLE_H2D_INT BIT(30) ++#define ACK_GATING_ENABLE_D2H_INT BIT(31) ++#define ACK_GATING_DISABLE_D2H_INT BIT(30) ++ ++#define GATING_CONTROL_POLL_LIMIT 64 ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++static INT_EVENT_MAP_T arIntEventMapTable[] = { ++ {WHISR_ABNORMAL_INT, INT_EVENT_ABNORMAL}, ++ {WHISR_D2H_SW_INT, INT_EVENT_SW_INT}, ++ {WHISR_TX_DONE_INT, INT_EVENT_TX}, ++ {(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX} ++}; ++ ++static const UINT_8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T)); ++ ++static IST_EVENT_FUNCTION apfnEventFuncTable[] = { ++ nicProcessAbnormalInterrupt, /*!< INT_EVENT_ABNORMAL */ ++ nicProcessSoftwareInterrupt, /*!< INT_EVENT_SW_INT */ ++ nicProcessTxInterrupt, /*!< INT_EVENT_TX */ ++ nicProcessRxInterrupt, /*!< INT_EVENT_RX */ ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory() ++ * and also enhance the readability. ++ */ ++#define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \ ++ { \ ++ DBGLOG(NIC, INFO, "Allocating %u bytes for %s.\n", u4Size, pucComment); \ ++ pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType); \ ++ if (pucMem == (PUINT_8)NULL) { \ ++ DBGLOG(NIC, ERROR, "Could not allocate %u bytes for %s.\n", u4Size, pucComment); \ ++ break; \ ++ } \ ++ ASSERT(((ULONG)pucMem % 4) == 0); \ ++ DBGLOG(NIC, TRACE, "Virtual Address = %p for %s.\n", pucMem, pucComment); \ ++ } ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter) ++{ ++ dumpMemory32((PUINT_32)prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++} ++ ++VOID HifRegDump(P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ UINT_32 RegVal = 0; ++ ++ for (i = 0; i <= 0x58; i += 4) { ++ if ((i != MCR_WTDR0) && (i != MCR_WTDR1) && (i != MCR_WRDR0) && ++ (i != MCR_WRDR1) && (i != MCR_WSDIOCSR) && (i != MCR_WRPLR)) { ++ HAL_MCR_RD(prAdapter, i, &RegVal); ++ DBGLOG(NIC, WARN, "HIF Reg 0x%x = 0x%x\n", i, RegVal); ++ } ++ } ++ DBGLOG(NIC, WARN, "\n\n"); ++} ++ ++BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter) ++{ ++ return prAdapter->fgIsFwOwn; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is responsible for the allocation of the data structures ++* inside the Adapter structure, include: ++* 1. SW_RFB_Ts ++* 2. Common coalescing buffer for TX PATH. ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @retval WLAN_STATUS_SUCCESS - Has enough memory. ++* @retval WLAN_STATUS_RESOURCES - Memory is not enough. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS status = WLAN_STATUS_RESOURCES; ++ P_RX_CTRL_T prRxCtrl; ++ P_TX_CTRL_T prTxCtrl; ++ ++ DEBUGFUNC("nicAllocateAdapterMemory"); ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ do { ++ /* 4 <0> Reset all Memory Handler */ ++#if CFG_DBG_MGT_BUF ++ prAdapter->u4MemFreeDynamicCount = 0; ++ prAdapter->u4MemAllocDynamicCount = 0; ++#endif ++ prAdapter->pucMgtBufCached = (PUINT_8) NULL; ++ prRxCtrl->pucRxCached = (PUINT_8) NULL; ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; ++ ++ /* 4 <1> Memory for Management Memory Pool and CMD_INFO_T */ ++ /* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */ ++ prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE; ++ ++ LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached, ++ prAdapter->u4MgtBufCachedSize, VIR_MEM_TYPE, "COMMON MGMT MEMORY POOL"); ++ ++ /* 4 <2> Memory for RX Descriptor */ ++ /* Initialize the number of rx buffers we will have in our queue. */ ++ /* We may setup ucRxPacketDescriptors by GLUE Layer, and using ++ * this variable directly. ++ */ ++ /* Allocate memory for the SW receive structures. */ ++ prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * ALIGN_4(sizeof(SW_RFB_T)); ++ ++ LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize, VIR_MEM_TYPE, "SW_RFB_T"); ++ ++ /* 4 <3> Memory for TX DEscriptor */ ++ prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * ALIGN_4(sizeof(MSDU_INFO_T)); ++ ++ LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, prTxCtrl->u4TxCachedSize, VIR_MEM_TYPE, "MSDU_INFO_T"); ++ ++ /* 4 <4> Memory for Common Coalescing Buffer */ ++#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG ++ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; ++ ++ /* Allocate memory for the common coalescing buffer. */ ++ prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ? ++ CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE; ++ ++ prAdapter->pucCoalescingBufCached = kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize); ++ ++ if (prAdapter->pucCoalescingBufCached == NULL) { ++ DBGLOG(NIC, ERROR, ++ "Could not allocate %u bytes for coalescing buffer.\n", ++ prAdapter->u4CoalescingBufCachedSize); ++ break; ++ } ++#endif /* CFG_COALESCING_BUFFER_SIZE */ ++ ++ /* 4 <5> Memory for enhanced interrupt response */ ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) ++ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ ++ if (prAdapter->prSDIOCtrl == NULL) { ++ DBGLOG(NIC, ERROR, ++ "Could not allocate %zu bytes for interrupt response.\n", ++ sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ break; ++ } ++ ++ status = WLAN_STATUS_SUCCESS; ++ ++ } while (FALSE); ++ ++ if (status != WLAN_STATUS_SUCCESS) ++ nicReleaseAdapterMemory(prAdapter); ++ ++ return status; ++ ++} /* end of nicAllocateAdapterMemory() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is responsible for releasing the allocated memory by ++* nicAllocatedAdapterMemory(). ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ /* 4 <5> Memory for enhanced interrupt response */ ++ if (prAdapter->prSDIOCtrl) { ++ kalReleaseIOBuffer((PVOID) prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; ++ } ++ /* 4 <4> Memory for Common Coalescing Buffer */ ++#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG ++ if (prAdapter->pucCoalescingBufCached) { ++ kalReleaseIOBuffer((PVOID) prAdapter->pucCoalescingBufCached, prAdapter->u4CoalescingBufCachedSize); ++ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; ++ } ++#endif /* CFG_COALESCING_BUFFER_SIZE */ ++ ++ /* 4 <3> Memory for TX Descriptor */ ++ if (prTxCtrl->pucTxCached) { ++ kalMemFree((PVOID) prTxCtrl->pucTxCached, VIR_MEM_TYPE, prTxCtrl->u4TxCachedSize); ++ prTxCtrl->pucTxCached = (PUINT_8) NULL; ++ } ++ /* 4 <2> Memory for RX Descriptor */ ++ if (prRxCtrl->pucRxCached) { ++ kalMemFree((PVOID) prRxCtrl->pucRxCached, VIR_MEM_TYPE, prRxCtrl->u4RxCachedSize); ++ prRxCtrl->pucRxCached = (PUINT_8) NULL; ++ } ++ /* 4 <1> Memory for Management Memory Pool */ ++ if (prAdapter->pucMgtBufCached) { ++ kalMemFree((PVOID) prAdapter->pucMgtBufCached, VIR_MEM_TYPE, prAdapter->u4MgtBufCachedSize); ++ prAdapter->pucMgtBufCached = (PUINT_8) NULL; ++ } ++#if CFG_DBG_MGT_BUF ++ /* Check if all allocated memories are free */ ++ ASSERT(prAdapter->u4MemFreeDynamicCount == prAdapter->u4MemAllocDynamicCount); ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief disable global interrupt ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ prAdapter->fgIsIntEnable = FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief enable global interrupt ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ BOOLEAN fgIsIntEnableCache; ++ ++ ASSERT(prAdapter); ++ fgIsIntEnableCache = prAdapter->fgIsIntEnable; ++ ++ prAdapter->fgIsIntEnable = TRUE; /* NOTE(Kevin): It must be placed before MCR GINT write. */ ++ ++ /* If need enable INT and also set LPOwn at the same time. */ ++ if (prAdapter->fgIsIntEnableWithLPOwnSet) { ++ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; /* NOTE(Kevin): It's better to place it ++ * before MCR GINT write. ++ */ ++ /* If INT was enabled, only set LPOwn */ ++ if (fgIsIntEnableCache) { ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); ++ prAdapter->fgIsFwOwn = TRUE; ++ } ++ /* If INT was not enabled, enable it and also set LPOwn now */ ++ else { ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET | WHLPCR_INT_EN_SET); ++ prAdapter->fgIsFwOwn = TRUE; ++ } ++ } ++ /* If INT was not enabled, enable it now */ ++ else if (!fgIsIntEnableCache) ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++} /* end of nicEnableInterrupt() */ ++ ++#if CFG_SDIO_INTR_ENHANCE ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief For SDIO enhance mode, set the max rx len and tx status ++* ++* @param prAdapter a pointer to adapter private data structure. ++* ++* @return - none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicSDIOInit(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4Value = 0; ++ ++ ASSERT(prAdapter); ++ ++ /* 4 <1> Check STATUS Buffer is DW alignment. */ ++ ASSERT(IS_ALIGN_4((ULONG)&prAdapter->prSDIOCtrl->u4WHISR)); ++ ++ /* 4 <2> Setup STATUS count. */ ++ { ++ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value); ++ ++ /* 4 <2.1> Setup the number of maximum RX length to be report */ ++ u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM); ++ u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM)); ++ ++ /* 4 <2.2> Setup RX enhancement mode */ ++#if CFG_SDIO_RX_ENHANCE ++ u4Value |= WHCR_RX_ENHANCE_MODE_EN; ++#else ++ u4Value &= ~WHCR_RX_ENHANCE_MODE_EN; ++#endif /* CFG_SDIO_RX_AGG */ ++ ++ HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value); ++ } ++ ++ return; ++ ++} /* end of nicSDIOInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read interrupt status from hardware ++* ++* @param prAdapter pointer to the Adapter handler ++* @param the interrupts ++* ++* @return N/A ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus) ++{ ++ P_SDIO_CTRL_T prSDIOCtrl; ++ ++ DEBUGFUNC("nicSDIOReadIntStatus"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pu4IntStatus); ++ ++ /* ++ prSDIOCtrl is from IO buffer. ++ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) ++ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ */ ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++ ASSERT(prSDIOCtrl); ++ ++ HAL_PORT_RD(prAdapter, ++ MCR_WHISR, ++ sizeof(ENHANCE_MODE_DATA_STRUCT_T), (PUINT_8) prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ *pu4IntStatus = 0; ++ return; ++ } ++ ++ /* workaround */ ++ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && ++ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { ++ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; ++ } ++ ++ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && ++ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && ++ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { ++ prSDIOCtrl->u4WHISR |= BIT(31); ++ } ++ ++ *pu4IntStatus = prSDIOCtrl->u4WHISR; ++ ++} /* end of nicSDIOReadIntStatus() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function used to read interrupt status and then invoking ++* dispatching procedure for the appropriate functions ++* corresponding to specific interrupt bits ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @retval WLAN_STATUS_SUCCESS ++* @retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_32 u4IntStatus = 0; ++ UINT_32 i; ++ ++ DEBUGFUNC("nicProcessIST"); ++ /* DBGLOG(NIC, LOUD, ("\n")); */ ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->rAcpiState == ACPI_STATE_D3) { ++ DBGLOG(REQ, WARN, "Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n", ++ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ nicDisableClockGating(prAdapter); ++#endif ++ ++ for (i = 0; i < CFG_IST_LOOP_COUNT; i++) { /* CFG_IST_LOOP_COUNT = 1 */ ++ ++#if CFG_SDIO_INTR_ENHANCE ++ nicSDIOReadIntStatus(prAdapter, &u4IntStatus); ++#else ++ HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++/* DBGLOG(NIC, TRACE, ("u4IntStatus: 0x%x\n", u4IntStatus)); */ ++ ++ if (u4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) { ++ DBGLOG(INTR, WARN, "Un-handled HISR %#x, HISR = %#x (HIER:0x%x)\n", ++ (UINT_32) (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus, ++ (UINT_32) WHIER_DEFAULT); ++ u4IntStatus &= WHIER_DEFAULT; ++ } ++ ++ nicProcessIST_impl(prAdapter, u4IntStatus); ++ ++ if (u4IntStatus == 0) { ++ if (i == 0) ++ u4Status = WLAN_STATUS_NOT_INDICATING; ++ break; ++ } ++ } ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ nicEnableClockGating(prAdapter); ++#endif ++ ++ return u4Status; ++} /* end of nicProcessIST() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief The function used to dispatch the appropriate functions for specific ++* interrupt bits ++* ++* @param prAdapter pointer to the Adapter handler ++* u4IntStatus interrupt status bits ++* ++* @retval WLAN_STATUS_SUCCESS ++* @retval WLAN_STATUS_ADAPTER_NOT_READY ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus) ++{ ++ UINT_32 u4IntCount = 0; ++ P_INT_EVENT_MAP_T prIntEventMap = NULL; ++ ++ ASSERT(prAdapter); ++ ++ prAdapter->u4IntStatus = u4IntStatus; ++ ++ /* Process each of the interrupt status consequently */ ++ prIntEventMap = &arIntEventMapTable[0]; ++ for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) { ++ if (prIntEventMap->u4Int & prAdapter->u4IntStatus) { ++ if (prIntEventMap->u4Event == INT_EVENT_RX && prAdapter->fgIsEnterD3ReqIssued == TRUE) { ++ /* ignore */ ++ } else if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) { ++ apfnEventFuncTable[prIntEventMap->u4Event] (prAdapter); ++ } else { ++ DBGLOG(INTR, WARN, ++ "Empty INTR handler! ISAR bit#: %u, event:%u, func: %p\n", ++ prIntEventMap->u4Int, prIntEventMap->u4Event, ++ apfnEventFuncTable[prIntEventMap->u4Event]); ++ ++ ASSERT(0); /* to trap any NULL interrupt handler */ ++ } ++ prAdapter->u4IntStatus &= ~prIntEventMap->u4Int; ++ } ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of nicProcessIST_impl() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Verify the CHIP ID ++* ++* @param prAdapter a pointer to adapter private data structure. ++* ++* ++* @retval TRUE CHIP ID is the same as the setting compiled ++* @retval FALSE CHIP ID is different from the setting compiled ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4CIR = 0; ++ ++ ASSERT(prAdapter); ++ ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR); ++ ++ DBGLOG(NIC, TRACE, "Chip ID: 0x%x\n", (UINT_32) (u4CIR & WCIR_CHIP_ID)); ++ DBGLOG(NIC, TRACE, "Revision ID: 0x%x\n", (UINT_32) ((u4CIR & WCIR_REVISION_ID) >> 16)); ++ ++#if 0 ++ if (((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_72) && ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_82)) ++ return FALSE; ++#endif ++ ++ prAdapter->ucRevID = (UINT_8) (((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the MCR to the appropriate init value, and verify the init ++* value ++* ++* @param prAdapter a pointer to adapter private data structure. ++* ++* @return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicMCRInit(IN P_ADAPTER_T prAdapter) ++{ ++ ++ ASSERT(prAdapter); ++ ++ /* 4 <0> Initial value */ ++} ++ ++VOID nicHifInit(IN P_ADAPTER_T prAdapter) ++{ ++ ++ ASSERT(prAdapter); ++#if 0 ++ /* reset event */ ++ nicPutMailbox(prAdapter, 0, 0x52455345); /* RESE */ ++ nicPutMailbox(prAdapter, 1, 0x545F5746); /* T_WF */ ++ nicSetSwIntr(prAdapter, BIT(16)); ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the Adapter soft variable ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prAdapter); ++ ++ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; ++ ++ do { ++ if (!nicVerifyChipID(prAdapter)) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ /* 4 <1> MCR init */ ++ nicMCRInit(prAdapter); ++ ++#if CFG_SDIO_INTR_ENHANCE ++ nicSDIOInit(prAdapter); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT); ++ ++ /* 4 <2> init FW HIF */ ++ nicHifInit(prAdapter); ++ } while (FALSE); ++ ++ return u4Status; ++} ++ ++#if defined(_HIF_SPI) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Restore the SPI Mode Select to default mode, ++* this is important while driver is unload, and this must be last mcr ++* since the operation will let the hif use 8bit mode access ++* ++* \param[in] prAdapter a pointer to adapter private data structure. ++* \param[in] eGPIO2_Mode GPIO2 operation mode ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA); ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process rx interrupt. When the rx ++* Interrupt is asserted, it means there are frames in queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4Value = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ prGlueInfo->IsrAbnormalCnt++; ++ HAL_MCR_RD(prAdapter, MCR_WASR, &u4Value); ++ DBGLOG(REQ, WARN, "MCR_WASR: 0x%x\n", u4Value); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief . ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessFwOwnBackInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ ++} /* end of nicProcessFwOwnBackInterrupt() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief . ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4IntrBits; ++ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31); ++ ++ prGlueInfo->IsrSoftWareCnt++; ++ ++ if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) { ++ nicPrintFirmwareAssertInfo(prAdapter); ++#if CFG_CHIP_RESET_SUPPORT ++ glSendResetRequest(); ++#endif ++ } ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++ ASSERT((u4IntrBits & (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)) ++ != (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)); ++ ++ if (u4IntrBits & ACK_GATING_ENABLE_D2H_INT) ++ prAdapter->fgIsClockGatingEnabled = TRUE; ++ ++ if (u4IntrBits & ACK_GATING_DISABLE_D2H_INT) { ++ prAdapter->fgIsClockGatingEnabled = FALSE; ++ ++ /* Indicate Service Thread for TX */ ++ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ } ++#endif ++ ++ DBGLOG(REQ, WARN, "u4IntrBits: 0x%x\n", u4IntrBits); ++} /* end of nicProcessSoftwareInterrupt() */ ++ ++VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data) ++{ ++ if (u4MailboxNum == 0) { ++ /* HAL_MCR_WR */ ++ HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data); ++ } else if (u4MailboxNum == 1) { ++ /* HAL_MCR_WR */ ++ HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data) ++{ ++ if (u4MailboxNum == 0) { ++ /* HAL_MCR_RD */ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data); ++ } else if (u4MailboxNum == 1) { ++ /* HAL_MCR_RD */ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data); ++ } else { ++ ASSERT(0); ++ } ++} ++ ++VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap) ++{ ++ /* NOTE: ++ * SW interrupt in HW bit 16 is mapping to SW bit 0 (shift 16bit in HW transparancy) ++ * SW interrupt valid from b0~b15 ++ */ ++ ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0); ++/* DBGLOG(NIC, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap)); */ ++ ++ HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue ++* with specified sequential number ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ucSeqNum Sequential Number ++* ++* @retval - P_CMD_INFO_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ prCmdQue = &prAdapter->rPendingCmdQueue; ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->ucCmdSeqNum == ucSeqNum) ++ break; ++ ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ ++ prCmdInfo = NULL; ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); ++ ++ return prCmdInfo; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to dequeue from prAdapter->rTxCtrl.rTxMgmtTxingQueue ++* with specified sequential number ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ucSeqNum Sequential Number ++* ++* @retval - P_MSDU_INFO_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) ++{ ++ P_QUE_T prTxingQue; ++ QUE_T rTempQue; ++ P_QUE_T prTempQue = &rTempQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ QUEUE_MOVE_ALL(prTempQue, prTxingQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ if (prMsduInfo->ucTxSeqNum == ucSeqNum) ++ break; ++ ++ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); ++ ++ prMsduInfo = NULL; ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ return prMsduInfo; ++} ++ ++P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx) ++{ ++ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; ++ P_QUE_T prTxingQue = (P_QUE_T) NULL; ++ QUE_T rTempQue; ++ P_QUE_T prTempQue = &rTempQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ if (prAdapter == NULL) { ++ ASSERT(FALSE); ++ return NULL; ++ } ++ ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ do { ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ QUEUE_MOVE_ALL(prTempQue, prTxingQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ if ((prMsduInfo->ucStaRecIndex == ucStaRecIdx) && (prMsduInfo->pfTxDoneHandler != NULL)) { ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfo, prMsduInfoListHead); ++ prMsduInfoListHead = prMsduInfo; ++ } else { ++ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); ++ ++ prMsduInfo = NULL; ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ } while (FALSE); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ return prMsduInfoListHead; ++} /* nicGetPendingStaMMPDU */ ++ ++VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) ++{ ++ P_QUE_T prTxingQue; ++ QUE_T rTempQue; ++ P_QUE_T prTempQue = &rTempQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; ++ P_MSDU_INFO_T prMsduInfoListTail = (P_MSDU_INFO_T) NULL; ++ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); ++ QUEUE_MOVE_ALL(prTempQue, prTxingQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; ++ ++ if ((ENUM_NETWORK_TYPE_INDEX_T) (prMsduInfo->ucNetworkType) == eNetworkType) { ++ if (prMsduInfoListHead == NULL) { ++ prMsduInfoListHead = prMsduInfoListTail = prMsduInfo; ++ } else { ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, prMsduInfo); ++ prMsduInfoListTail = prMsduInfo; ++ } ++ } else { ++ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); ++ ++ prMsduInfo = NULL; ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ /* free */ ++ if (prMsduInfoListHead) ++ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); ++ ++ return; ++ ++} /* end of nicFreePendingTxMsduInfoByNetwork() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to retrieve a CMD sequence number atomically ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval - UINT_8 ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucRetval; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); ++ ++ prAdapter->ucCmdSeqNum++; ++ ucRetval = prAdapter->ucCmdSeqNum; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); ++ ++ return ucRetval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This procedure is used to retrieve a TX sequence number atomically ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval - UINT_8 ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucRetval; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); ++ ++ prAdapter->ucTxSeqNum++; ++ ucRetval = prAdapter->ucTxSeqNum; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); ++ ++ return ucRetval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to handle ++* media state change event ++* ++* @param ++* ++* @retval ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicMediaStateChange(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ ASSERT(prAdapter); ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ switch (eNetworkType) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { /* disconnected */ ++ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ DBGLOG(NIC, TRACE, "DisByMC\n"); ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ } ++ ++ /* reset buffered link quality information */ ++ prAdapter->fgIsLinkQualityValid = FALSE; ++ prAdapter->fgIsLinkRateValid = FALSE; ++ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { /* connected */ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ ++ /* fill information for association result */ ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ prConnectionStatus->aucBssid, MAC_ADDR_LEN); ++ prAdapter->rWlanInfo.rCurrBssId.u4Privacy ++ = prConnectionStatus->ucEncryptStatus; /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse ++ = PARAM_NETWORK_TYPE_AUTOMODE; /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod ++ = prConnectionStatus->u2BeaconPeriod; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow = prConnectionStatus->u2ATIMWindow; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig = prConnectionStatus->u4FreqInKHz; ++ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode ++ = (ENUM_PARAM_OP_MODE_T) prConnectionStatus->ucInfraMode; ++ ++ /* always indicate to OS according to MSDN (re-association/roaming) */ ++ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); ++ } else { ++ /* connected -> connected : roaming ? */ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_ROAM_OUT_FIND_BEST, NULL, 0); ++ } ++ } ++ break; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ case NETWORK_TYPE_BOW_INDEX: ++ break; ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ case NETWORK_TYPE_P2P_INDEX: ++ break; ++#endif ++ default: ++ ASSERT(0); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} /* nicMediaStateChange */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to convert between ++* frequency and channel number ++* ++* @param u4ChannelNum ++* ++* @retval - Frequency in unit of KHz, 0 for invalid channel number ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 nicChannelNum2Freq(UINT_32 u4ChannelNum) ++{ ++ UINT_32 u4ChannelInMHz; ++ ++ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) ++ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; ++ else if (u4ChannelNum == 14) ++ u4ChannelInMHz = 2484; ++ else if (u4ChannelNum == 133) ++ u4ChannelInMHz = 3665; /* 802.11y */ ++ else if (u4ChannelNum == 137) ++ u4ChannelInMHz = 3685; /* 802.11y */ ++ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) ++ u4ChannelInMHz = 5000 + u4ChannelNum * 5; ++ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) ++ u4ChannelInMHz = 4000 + u4ChannelNum * 5; ++ else ++ u4ChannelInMHz = 0; ++ ++ return 1000 * u4ChannelInMHz; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to convert between ++* frequency and channel number ++* ++* @param u4FreqInKHz ++* ++* @retval - Frequency Number, 0 for invalid freqency ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 nicFreq2ChannelNum(UINT_32 u4FreqInKHz) ++{ ++ switch (u4FreqInKHz) { ++ case 2412000: ++ return 1; ++ case 2417000: ++ return 2; ++ case 2422000: ++ return 3; ++ case 2427000: ++ return 4; ++ case 2432000: ++ return 5; ++ case 2437000: ++ return 6; ++ case 2442000: ++ return 7; ++ case 2447000: ++ return 8; ++ case 2452000: ++ return 9; ++ case 2457000: ++ return 10; ++ case 2462000: ++ return 11; ++ case 2467000: ++ return 12; ++ case 2472000: ++ return 13; ++ case 2484000: ++ return 14; ++ case 3665000: ++ return 133; /* 802.11y */ ++ case 3685000: ++ return 137; /* 802.11y */ ++ case 4915000: ++ return 183; ++ case 4920000: ++ return 184; ++ case 4925000: ++ return 185; ++ case 4930000: ++ return 186; ++ case 4935000: ++ return 187; ++ case 4940000: ++ return 188; ++ case 4945000: ++ return 189; ++ case 4960000: ++ return 192; ++ case 4980000: ++ return 196; ++ case 5170000: ++ return 34; ++ case 5180000: ++ return 36; ++ case 5190000: ++ return 38; ++ case 5200000: ++ return 40; ++ case 5210000: ++ return 42; ++ case 5220000: ++ return 44; ++ case 5230000: ++ return 46; ++ case 5240000: ++ return 48; ++ case 5250000: ++ return 50; ++ case 5260000: ++ return 52; ++ case 5270000: ++ return 54; ++ case 5280000: ++ return 56; ++ case 5290000: ++ return 58; ++ case 5300000: ++ return 60; ++ case 5320000: ++ return 64; ++ case 5500000: ++ return 100; ++ case 5520000: ++ return 104; ++ case 5540000: ++ return 108; ++ case 5560000: ++ return 112; ++ case 5580000: ++ return 116; ++ case 5600000: ++ return 120; ++ case 5620000: ++ return 124; ++ case 5640000: ++ return 128; ++ case 5660000: ++ return 132; ++ case 5680000: ++ return 136; ++ case 5700000: ++ return 140; ++ case 5745000: ++ return 149; ++ case 5765000: ++ return 153; ++ case 5785000: ++ return 157; ++ case 5805000: ++ return 161; ++ case 5825000: ++ return 165; ++ case 5845000: ++ return 169; ++ case 5865000: ++ return 173; ++ default: ++ return 0; ++ } ++} ++ ++/* firmware command wrapper */ ++/* NETWORK (WIFISYS) */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to activate WIFISYS for specified network ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of network type ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; ++ P_BSS_INFO_T prBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdActivateCtrl.ucActive = 1; ++ ++ if (((UINT_8) eNetworkTypeIdx) < NETWORK_TYPE_INDEX_NUM) { ++ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]; ++ prBssInfo->fg40mBwAllowed = FALSE; ++ prBssInfo->fgAssoc40mBwAllowed = FALSE; ++ } ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BSS_ACTIVATE_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to deactivate WIFISYS for specified network ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of network type ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ WLAN_STATUS u4Status; ++ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdActivateCtrl.ucActive = 0; ++ ++ u4Status = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_BSS_ACTIVATE_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); ++ ++ /* free all correlated station records */ ++ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); ++ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); ++ nicFreePendingTxMsduInfoByNetwork(prAdapter, eNetworkTypeIdx); ++ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); ++ ++ return u4Status; ++} ++ ++/* BSS-INFO */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to sync bss info with firmware ++* when a new BSS has been connected or disconnected ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO type ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ WLAN_STATUS u4Status; ++ P_BSS_INFO_T prBssInfo; ++ CMD_SET_BSS_INFO rCmdSetBssInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ ++ kalMemZero(&rCmdSetBssInfo, sizeof(CMD_SET_BSS_INFO)); ++ ++ rCmdSetBssInfo.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdSetBssInfo.ucConnectionState = (UINT_8) prBssInfo->eConnectionState; ++ rCmdSetBssInfo.ucCurrentOPMode = (UINT_8) prBssInfo->eCurrentOPMode; ++ rCmdSetBssInfo.ucSSIDLen = (UINT_8) prBssInfo->ucSSIDLen; ++ kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); ++ COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID); ++ rCmdSetBssInfo.ucIsQBSS = (UINT_8) prBssInfo->fgIsQBSS; ++ rCmdSetBssInfo.ucNonHTBasicPhyType = prBssInfo->ucNonHTBasicPhyType; ++ rCmdSetBssInfo.u2OperationalRateSet = prBssInfo->u2OperationalRateSet; ++ rCmdSetBssInfo.u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; ++ rCmdSetBssInfo.ucPhyTypeSet = prBssInfo->ucPhyTypeSet; ++ rCmdSetBssInfo.fgHiddenSsidMode = prBssInfo->eHiddenSsidType; ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ COPY_MAC_ADDR(rCmdSetBssInfo.aucOwnMac, prBssInfo->aucOwnMacAddr); ++#endif ++ ++ rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, prBssInfo); ++ ++ rCmdSetBssInfo.fgWapiMode = (UINT_8) FALSE; ++ ++ if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) prConnSettings->eAuthMode; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) prConnSettings->eEncStatus; ++ rCmdSetBssInfo.fgWapiMode = (UINT_8) prConnSettings->fgWapiMode; ++ } ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { ++ /* P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); */ ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; ++ } ++#endif ++ else { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; ++ } else { ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_OPEN; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION_DISABLED; ++ } ++ /* Need the probe response to detect the PBC overlap */ ++ rCmdSetBssInfo.fgIsApMode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); ++ } ++#else ++ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; ++ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; ++#endif ++ } ++ ++ if (eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX && ++ prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && prBssInfo->prStaRecOfAP != NULL) { ++ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; ++ ++ cnmAisInfraConnectNotify(prAdapter); ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && ++ (eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && ++ (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && (prBssInfo->prStaRecOfAP != NULL)) { ++ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ else if (eNetworkTypeIdx == NETWORK_TYPE_BOW_INDEX && ++ prBssInfo->eCurrentOPMode == OP_MODE_BOW && prBssInfo->prStaRecOfAP != NULL) { ++ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; ++ } ++#endif ++ else ++ rCmdSetBssInfo.ucStaRecIdxOfAP = STA_REC_INDEX_NOT_FOUND; ++ ++ u4Status = wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_BSS_INFO, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_SET_BSS_INFO), (PUINT_8)&rCmdSetBssInfo, NULL, 0); ++ ++ /* if BSS-INFO is going to be disconnected state, free all correlated station records */ ++ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ /* clear client list */ ++ bssClearClientList(prAdapter, prBssInfo); ++ ++ /* free all correlated station records */ ++ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); ++ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); ++ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); ++#if CFG_ENABLE_GTK_FRAME_FILTER ++ if (prBssInfo->prIpV4NetAddrList) ++ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); ++#endif ++ } ++ ++ return u4Status; ++} ++ ++/* BSS-INFO Indication (PM) */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate PM that ++* a BSS has been created. (for AdHoc / P2P-GO) ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ ++ rCmdIndicatePmBssCreated.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdIndicatePmBssCreated.ucDtimPeriod = prBssInfo->ucDTIMPeriod; ++ rCmdIndicatePmBssCreated.u2BeaconInterval = prBssInfo->u2BeaconInterval; ++ rCmdIndicatePmBssCreated.u2AtimWindow = prBssInfo->u2ATIMWindow; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INDICATE_PM_BSS_CREATED, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_INDICATE_PM_BSS_CREATED), (PUINT_8)&rCmdIndicatePmBssCreated, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate PM that ++* a BSS has been connected ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ CMD_INDICATE_PM_BSS_CONNECTED rCmdIndicatePmBssConnected; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ ++ rCmdIndicatePmBssConnected.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ rCmdIndicatePmBssConnected.ucDtimPeriod = prBssInfo->ucDTIMPeriod; ++ rCmdIndicatePmBssConnected.u2AssocId = prBssInfo->u2AssocId; ++ rCmdIndicatePmBssConnected.u2BeaconInterval = prBssInfo->u2BeaconInterval; ++ rCmdIndicatePmBssConnected.u2AtimWindow = prBssInfo->u2ATIMWindow; ++ ++ rCmdIndicatePmBssConnected.ucBmpDeliveryAC = prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC; ++ rCmdIndicatePmBssConnected.ucBmpTriggerAC = prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC; ++ ++ /* DBGPRINTF("nicPmIndicateBssConnected: ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x", */ ++ /* rCmdIndicatePmBssConnected.ucBmpDeliveryAC, */ ++ /* rCmdIndicatePmBssConnected.ucBmpTriggerAC); */ ++ ++ if ((eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX) ++#if CFG_ENABLE_WIFI_DIRECT ++ || ((eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->fgIsP2PRegistered)) ++#endif ++ ) { ++ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ rCmdIndicatePmBssConnected.fgIsUapsdConnection = ++ (UINT_8) prBssInfo->prStaRecOfAP->fgIsUapsdSupported; ++ } else { ++ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; /* @FIXME */ ++ } ++ } else { ++ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; ++ } ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INDICATE_PM_BSS_CONNECTED, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_INDICATE_PM_BSS_CONNECTED), ++ (PUINT_8)&rCmdIndicatePmBssConnected, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate PM that ++* a BSS has been disconnected ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ rCmdIndicatePmBssAbort.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_INDICATE_PM_BSS_ABORT, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, ++ NULL, ++ sizeof(CMD_INDICATE_PM_BSS_ABORT), (PUINT_8)&rCmdIndicatePmBssAbort, NULL, 0); ++} ++ ++WLAN_STATUS ++nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, ++ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent) ++{ ++ DEBUGFUNC("nicConfigPowerSaveProfile"); ++ DBGLOG(NIC, TRACE, "eNetTypeIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n", ++ eNetTypeIndex, ePwrMode, fgEnCmdEvent); ++ ++ ASSERT(prAdapter); ++ ++ if (eNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { ++ ASSERT(0); ++ return WLAN_STATUS_NOT_SUPPORTED; ++ } ++/* prAdapter->rWlanInfo.ePowerSaveMode.ucNetTypeIndex = eNetTypeIndex; */ ++/* prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile = (UINT_8)ePwrMode; */ ++ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucNetTypeIndex = eNetTypeIndex; ++ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucPsProfile = (UINT_8) ePwrMode; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_POWER_SAVE_MODE, ++ TRUE, ++ FALSE, ++ (fgEnCmdEvent ? TRUE : FALSE), ++ (fgEnCmdEvent ? nicCmdEventSetCommon : NULL), ++ (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL), ++ sizeof(CMD_PS_PROFILE_T), ++ (PUINT_8)&(prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex]), ++ NULL, sizeof(PARAM_POWER_MODE) ++ ); ++ ++} /* end of wlanoidSetAcpiDevicePowerStateMode() */ ++ ++WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent) ++{ ++ CMD_SW_DBG_CTRL_T rCmdSwCtrl; ++ CMD_ACCESS_REG rCmdAccessReg; ++ WLAN_STATUS rWlanStatus; ++ ++ DEBUGFUNC("nicEnterCtiaMode"); ++ DBGLOG(NIC, TRACE, "nicEnterCtiaMode: %d\n", fgEnterCtia); ++ ++ ASSERT(prAdapter); ++ ++ rWlanStatus = WLAN_STATUS_SUCCESS; ++ ++ if (fgEnterCtia) { ++ /* 1. Disable On-Lin Scan */ ++ prAdapter->fgEnOnlineScan = FALSE; ++ ++ /* 3. Disable FIFO FULL no ack */ ++ rCmdAccessReg.u4Address = 0x60140028; ++ rCmdAccessReg.u4Data = 0x904; ++ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ ++ FALSE, /* TRUE, */ ++ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); ++ ++ /* 4. Disable Roaming */ ++ rCmdSwCtrl.u4Id = 0x90000204; ++ rCmdSwCtrl.u4Data = 0x0; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ rCmdSwCtrl.u4Id = 0x90000200; ++ rCmdSwCtrl.u4Data = 0x820000; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* Disalbe auto tx power */ ++ rCmdSwCtrl.u4Id = 0xa0100003; ++ rCmdSwCtrl.u4Data = 0x0; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* 2. Keep at CAM mode */ ++ { ++ PARAM_POWER_MODE ePowerMode; ++ ++ prAdapter->u4CtiaPowerMode = 0; ++ prAdapter->fgEnCtiaPowerMode = TRUE; ++ ++ ePowerMode = Param_PowerModeCAM; ++ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); ++ } ++ ++ /* 5. Disable Beacon Timeout Detection */ ++ prAdapter->fgDisBcnLostDetection = TRUE; ++ } else { ++ /* 1. Enaable On-Lin Scan */ ++ prAdapter->fgEnOnlineScan = TRUE; ++ ++ /* 3. Enable FIFO FULL no ack */ ++ rCmdAccessReg.u4Address = 0x60140028; ++ rCmdAccessReg.u4Data = 0x905; ++ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ ++ FALSE, /* TRUE, */ ++ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); ++ ++ /* 4. Enable Roaming */ ++ rCmdSwCtrl.u4Id = 0x90000204; ++ rCmdSwCtrl.u4Data = 0x1; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ rCmdSwCtrl.u4Id = 0x90000200; ++ rCmdSwCtrl.u4Data = 0x820000; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* Enable auto tx power */ ++ /* */ ++ ++ rCmdSwCtrl.u4Id = 0xa0100003; ++ rCmdSwCtrl.u4Data = 0x1; ++ wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SW_DBG_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); ++ ++ /* 2. Keep at Fast PS */ ++ { ++ PARAM_POWER_MODE ePowerMode; ++ ++ prAdapter->u4CtiaPowerMode = 2; ++ prAdapter->fgEnCtiaPowerMode = TRUE; ++ ++ ePowerMode = Param_PowerModeFast_PSP; ++ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); ++ } ++ ++ /* 5. Enable Beacon Timeout Detection */ ++ prAdapter->fgDisBcnLostDetection = FALSE; ++ ++ } ++ ++ return rWlanStatus; ++} /* end of nicEnterCtiaMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to indicate firmware domain ++* for beacon generation parameters ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eIeUpdMethod, Update Method ++* eNetTypeIndex Index of Network ++* u2Capability Capability ++* aucIe Pointer to buffer of IEs ++* u2IELen Length of IEs ++* ++* @retval - WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++* WLAN_STATUS_PENDING ++* WLAN_STATUS_INVALID_DATA ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, ++ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ++ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen) ++{ ++ P_CMD_BEACON_TEMPLATE_UPDATE prCmdBcnUpdate; ++ UINT_16 u2CmdBufLen = 0; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_INFO_T prCmdInfo; ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_8 ucCmdSeqNum; ++ ++ DEBUGFUNC("wlanUpdateBeaconIETemplate"); ++ ++ DBGLOG(NIC, LOUD, "\nnicUpdateBeaconIETemplate\n"); ++ ++ ASSERT(prAdapter); ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (u2IELen > MAX_IE_LENGTH) ++ return WLAN_STATUS_INVALID_DATA; ++ ++ if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) { ++ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, aucIE) + u2IELen; ++ } else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) { ++ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, u2IELen); ++ } else { ++ ASSERT(0); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* prepare command info */ ++ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u2CmdBufLen)); ++ if (!prCmdInfo) { ++ DBGLOG(NIC, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* increase command sequence number */ ++ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); ++ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); ++ ++ /* Setup common CMD Info Packet */ ++ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; ++ prCmdInfo->eNetworkType = eNetTypeIndex; ++ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u2CmdBufLen); ++ prCmdInfo->pfCmdDoneHandler = NULL; /* @FIXME */ ++ prCmdInfo->pfCmdTimeoutHandler = NULL; /* @FIXME */ ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ prCmdInfo->fgDriverDomainMCR = FALSE; ++ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; ++ prCmdInfo->u4SetInfoLen = u2CmdBufLen; ++ prCmdInfo->pvInformationBuffer = NULL; ++ prCmdInfo->u4InformationBufferLength = 0; ++ ++ /* Setup WIFI_CMD_T (no payload) */ ++ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); ++ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; ++ prWifiCmd->ucCID = prCmdInfo->ucCID; ++ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; ++ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; ++ ++ prCmdBcnUpdate = (P_CMD_BEACON_TEMPLATE_UPDATE) (prWifiCmd->aucBuffer); ++ ++ /* fill beacon updating command */ ++ prCmdBcnUpdate->ucUpdateMethod = (UINT_8) eIeUpdMethod; ++ prCmdBcnUpdate->ucNetTypeIndex = (UINT_8) eNetTypeIndex; ++ prCmdBcnUpdate->u2Capability = u2Capability; ++ prCmdBcnUpdate->u2IELen = u2IELen; ++ if (u2IELen > 0) ++ kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen); ++ ++ /* insert into prCmdQueue */ ++ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ ++ /* wakeup txServiceThread later */ ++ GLUE_SET_EVENT(prGlueInfo); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to initialization PHY related ++* varaibles ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ ASSERT(prAdapter); ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ ++ if (prConnSettings->eDesiredPhyConfig >= PHY_CONFIG_NUM) { ++ ASSERT(0); ++ return; ++ } ++ ++ prAdapter->rWifiVar.ucAvailablePhyTypeSet = aucPhyCfg2PhyTypeSet[prConnSettings->eDesiredPhyConfig]; ++ ++ if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_BIT_ERP) ++ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_ERP_INDEX; ++ /* NOTE(Kevin): Because we don't have N only mode, TBD */ ++ else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ ++ ++ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_HR_DSSS_INDEX; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* eNetworkTypeIdx Index of BSS-INFO ++* ++* @retval - ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_BSS_INFO_T prBssInfo; ++ CMD_UPDATE_WMM_PARMS_T rCmdUpdateWmmParms; ++ ++ ASSERT(prAdapter); ++ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ DBGLOG(QM, EVENT, "sizeof(AC_QUE_PARMS_T): %zu\n", sizeof(AC_QUE_PARMS_T)); ++ DBGLOG(QM, EVENT, "sizeof(CMD_UPDATE_WMM_PARMS): %zu\n", sizeof(CMD_UPDATE_WMM_PARMS_T)); ++ DBGLOG(QM, EVENT, "sizeof(WIFI_CMD_T): %zu\n", sizeof(WIFI_CMD_T)); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); ++ rCmdUpdateWmmParms.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; ++ kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], &prBssInfo->arACQueParms[0], (sizeof(AC_QUE_PARMS_T) * AC_NUM)); ++ ++ rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_UPDATE_WMM_PARMS, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_UPDATE_WMM_PARMS_T), (PUINT_8)&rCmdUpdateWmmParms, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update TX power gain corresponding to ++* each band/modulation combination ++* ++* @param prAdapter Pointer of ADAPTER_T ++* prTxPwrParam Pointer of TX power parameters ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) ++{ ++ DEBUGFUNC("nicUpdateTxPower"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_TX_PWR, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to set auto tx power parameter ++* ++* @param prAdapter Pointer of ADAPTER_T ++* prTxPwrParam Pointer of Auto TX power parameters ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam) ++{ ++ DEBUGFUNC("nicSetAutoTxPower"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_AUTOPWR_CTRL, ++ TRUE, ++ FALSE, ++ FALSE, ++ NULL, NULL, sizeof(CMD_AUTO_POWER_PARAM_T), (PUINT_8) prAutoPwrParam, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update TX power gain corresponding to ++* each band/modulation combination ++* ++* @param prAdapter Pointer of ADAPTER_T ++* prTxPwrParam Pointer of TX power parameters ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicSetAutoTxPowerControl(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) ++{ ++ DEBUGFUNC("nicUpdateTxPower"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_TX_PWR, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update power offset around 5GHz band ++* ++* @param prAdapter Pointer of ADAPTER_T ++* pr5GPwrOffset Pointer of 5GHz power offset parameter ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset) ++{ ++ DEBUGFUNC("nicUpdate5GOffset"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_5G_PWR_OFFSET, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_5G_PWR_OFFSET_T), (PUINT_8) pr5GPwrOffset, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update DPD calibration result ++* ++* @param prAdapter Pointer of ADAPTER_T ++* pr5GPwrOffset Pointer of parameter for DPD calibration result ++* ++* @retval WLAN_STATUS_PENDING ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult) ++{ ++ DEBUGFUNC("nicUpdateDPD"); ++ ++ ASSERT(prAdapter); ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_PWR_PARAM, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_PWR_PARAM_T), (PUINT_8) prDpdCalResult, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function starts system service such as timer and ++* memory pools ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicInitSystemService(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* <1> Initialize MGMT Memory pool and STA_REC */ ++ cnmMemInit(prAdapter); ++ cnmStaRecInit(prAdapter); ++ cmdBufInitialize(prAdapter); ++ ++ /* <2> Mailbox Initialization */ ++ mboxInitialize(prAdapter); ++ ++ /* <3> Timer Initialization */ ++ cnmTimerInitialize(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function reset some specific system service, ++* such as STA-REC ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicResetSystemService(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ /* Timer Destruction */ ++ cnmTimerDestroy(prAdapter); ++ ++ /* Mailbox Destruction */ ++ mboxDestroy(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) ++{ ++ ASSERT(prAdapter); ++ ++ /* CNM Module - initialization */ ++ cnmInit(prAdapter); ++ ++ /* RLM Module - initialization */ ++ rlmFsmEventInit(prAdapter); ++ ++ /* SCN Module - initialization */ ++ scnInit(prAdapter); ++ ++ /* AIS Module - intiailization */ ++ aisInitializeConnectionSettings(prAdapter, prRegInfo); ++ aisFsmInit(prAdapter); ++ ++#if CFG_SUPPORT_ROAMING ++ /* Roaming Module - intiailization */ ++ roamingFsmInit(prAdapter); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++#if CFG_SUPPORT_SWCR ++ swCrDebugInit(prAdapter); ++#endif /* CFG_SUPPORT_SWCR */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexInit(prAdapter); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to update WMM Parms ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++#if CFG_SUPPORT_SWCR ++ swCrDebugUninit(prAdapter); ++#endif /* CFG_SUPPORT_SWCR */ ++ ++#if CFG_SUPPORT_ROAMING ++ /* Roaming Module - unintiailization */ ++ roamingFsmUninit(prAdapter); ++#endif /* CFG_SUPPORT_ROAMING */ ++ ++ /* AIS Module - unintiailization */ ++ aisFsmUninit(prAdapter); ++ ++ /* SCN Module - unintiailization */ ++ scnUninit(prAdapter); ++ ++ /* RLM Module - uninitialization */ ++ rlmFsmEventUninit(prAdapter); ++ ++ /* CNM Module - uninitialization */ ++ cnmUninit(prAdapter); ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexUninit(prAdapter); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++} ++ ++#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is to inform firmware to enable MCU clock gating ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4WHISR = 0; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsClockGatingEnabled == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ ++ nicSetSwIntr(prAdapter, REQ_GATING_ENABLE_H2D_INT); ++ ++ i = 0; ++ while (i < GATING_CONTROL_POLL_LIMIT) { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) ++ return WLAN_STATUS_FAILURE; ++ ++ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); ++ ++ if (u4WHISR & ACK_GATING_ENABLE_D2H_INT) { ++ prAdapter->fgIsClockGatingEnabled = TRUE; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++ ++ ASSERT(0); ++ return WLAN_STATUS_PENDING; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is to inform firmware to disable MCU clock gating ++* ++* @param prAdapter Pointer of ADAPTER_T ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4WHISR = 0; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsClockGatingEnabled == FALSE) ++ return WLAN_STATUS_SUCCESS; ++ ++ nicSetSwIntr(prAdapter, REQ_GATING_DISABLE_H2D_INT); ++ ++ i = 0; ++ while (i < GATING_CONTROL_POLL_LIMIT) { ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) ++ return WLAN_STATUS_FAILURE; ++ ++ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); ++ ++ if (u4WHISR & ACK_GATING_DISABLE_D2H_INT) { ++ prAdapter->fgIsClockGatingEnabled = FALSE; ++ return WLAN_STATUS_SUCCESS; ++ } ++ } ++ ++ ASSERT(0); ++ return WLAN_STATUS_PENDING; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is invoked to buffer scan result ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param rMacAddr BSSID ++* @param prSsid Pointer to SSID ++* @param u4Privacy Privacy settings (0: Open / 1: WEP/WPA/WPA2 enabled) ++* @param rRssi Received Strength (-10 ~ -200 dBm) ++* @param eNetworkType Network Type (a/b/g) ++* @param prConfiguration Network Parameter ++* @param eOpMode Infra/Ad-Hoc ++* @param rSupportedRates Supported basic rates ++* @param u2IELength IE Length ++* @param pucIEBuf Pointer to Information Elements(IEs) ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicAddScanResult(IN P_ADAPTER_T prAdapter, ++ IN PARAM_MAC_ADDRESS rMacAddr, ++ IN P_PARAM_SSID_T prSsid, ++ IN UINT_32 u4Privacy, ++ IN PARAM_RSSI rRssi, ++ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, ++ IN P_PARAM_802_11_CONFIG_T prConfiguration, ++ IN ENUM_PARAM_OP_MODE_T eOpMode, ++ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf) ++{ ++ BOOLEAN bReplace; ++ UINT_32 i; ++ UINT_32 u4IdxWeakest = 0; ++ PARAM_RSSI rWeakestRssi; ++ UINT_32 u4BufferSize; ++ ++ ASSERT(prAdapter); ++ ++ rWeakestRssi = (PARAM_RSSI) INT_MAX; ++ u4BufferSize = sizeof(prAdapter->rWlanInfo.aucScanIEBuf) / sizeof(prAdapter->rWlanInfo.aucScanIEBuf[0]); ++ ++ bReplace = FALSE; ++ ++ /* decide to replace or add */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ /* find weakest entry && not connected one */ ++ if (UNEQUAL_MAC_ADDR ++ (prAdapter->rWlanInfo.arScanResult[i].arMacAddress, prAdapter->rWlanInfo.rCurrBssId.arMacAddress) ++ && prAdapter->rWlanInfo.arScanResult[i].rRssi < rWeakestRssi) { ++ u4IdxWeakest = i; ++ rWeakestRssi = prAdapter->rWlanInfo.arScanResult[i].rRssi; ++ } ++ ++ if (prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode && ++ EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo.arScanResult[i].arMacAddress), rMacAddr) && ++ (EQUAL_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen) ++ || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == 0)) { ++ /* replace entry */ ++ bReplace = TRUE; ++ ++ /* free IE buffer then zero */ ++ nicFreeScanResultIE(prAdapter, i); ++ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /* then fill buffer */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length = ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; ++ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); ++ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen); ++ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; ++ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; ++ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), ++ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); ++ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; ++ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), ++ rSupportedRates, sizeof(PARAM_RATES_EX)); ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; ++ ++ /* IE - allocate buffer and update pointer */ ++ if (u2IELength > 0) { ++ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { ++ kalMemCopy(& ++ (prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), ++ pucIEBuf, u2IELength); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ &(prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); ++ } else { ++ /* buffer is not enough */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ ++ break; ++ } ++ } ++ ++ if (bReplace == FALSE) { ++ if (prAdapter->rWlanInfo.u4ScanResultNum < (CFG_MAX_NUM_BSS_LIST - 1)) { ++ i = prAdapter->rWlanInfo.u4ScanResultNum; ++ ++ /* zero */ ++ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /* then fill buffer */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length = ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; ++ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); ++ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen); ++ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; ++ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; ++ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), ++ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); ++ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; ++ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), ++ rSupportedRates, sizeof(PARAM_RATES_EX)); ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; ++ ++ /* IE - allocate buffer and update pointer */ ++ if (u2IELength > 0) { ++ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { ++ kalMemCopy(& ++ (prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), ++ pucIEBuf, u2IELength); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ &(prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); ++ } else { ++ /* buffer is not enough */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ ++ prAdapter->rWlanInfo.u4ScanResultNum++; ++ } else if (rWeakestRssi != (PARAM_RSSI) INT_MAX) { ++ /* replace weakest one */ ++ i = u4IdxWeakest; ++ ++ /* free IE buffer then zero */ ++ nicFreeScanResultIE(prAdapter, i); ++ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); ++ ++ /* then fill buffer */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length = ++ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; ++ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); ++ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, ++ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, ++ prSsid->aucSsid, prSsid->u4SsidLen); ++ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; ++ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; ++ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; ++ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), ++ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); ++ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; ++ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), ++ rSupportedRates, sizeof(PARAM_RATES_EX)); ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; ++ ++ if (u2IELength > 0) { ++ /* IE - allocate buffer and update pointer */ ++ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { ++ kalMemCopy(& ++ (prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), ++ pucIEBuf, u2IELength); ++ ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ &(prAdapter-> ++ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); ++ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); ++ } else { ++ /* buffer is not enough */ ++ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; ++ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } else { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is invoked to free IE buffer for dedicated scan result ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param u4Idx Index of Scan Result ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx) ++{ ++ UINT_32 i; ++ PUINT_8 pucPivot, pucMovePivot; ++ UINT_32 u4MoveSize, u4FreeSize, u4ReserveSize; ++ ++ ASSERT(prAdapter); ++ ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST); ++ ++ if (prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0 ++ || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) { ++ return; ++ } ++ ++ u4FreeSize = ALIGN_4(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength); ++ ++ pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]; ++ pucMovePivot = (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize); ++ ++ u4ReserveSize = ((ULONG) pucPivot) - (ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])); ++ u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - u4ReserveSize - u4FreeSize; ++ ++ /* 1. rest of buffer to move forward */ ++ kalMemCopy(pucPivot, pucMovePivot, u4MoveSize); ++ ++ /* 1.1 modify pointers */ ++ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { ++ if (i != u4Idx) { ++ if (prAdapter->rWlanInfo.apucScanResultIEs[i] >= pucMovePivot) { ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = ++ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[i]) - u4FreeSize); ++ } ++ } ++ } ++ ++ /* 1.2 reset the freed one */ ++ prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0; ++ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; ++ ++ /* 2. reduce IE buffer usage */ ++ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is to hack parameters for WLAN TABLE for ++* fixed rate settings ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param eRateSetting ++* @param pu2DesiredNonHTRateSet, ++* @param pu2BSSBasicRateSet, ++* @param pucMcsSet ++* @param pucSupMcs32 ++* @param pu2HtCapInfo ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicUpdateRateParams(IN P_ADAPTER_T prAdapter, ++ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, ++ IN PUINT_8 pucDesiredPhyTypeSet, ++ IN PUINT_16 pu2DesiredNonHTRateSet, ++ IN PUINT_16 pu2BSSBasicRateSet, ++ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 pu2HtCapInfo) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eRateSetting > FIXED_RATE_NONE && eRateSetting < FIXED_RATE_NUM); ++ ++ switch (prAdapter->rWifiVar.eRateSetting) { ++ case FIXED_RATE_1M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_1M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_1M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_2M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_2M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_2M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_5_5M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_5_5M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_11M: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_11M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_11M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_6M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_6M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_6M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_9M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_9M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_9M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_12M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_12M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_12M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_18M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_18M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_18M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_24M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_24M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_24M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_36M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_36M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_36M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_48M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_48M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_48M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_54M: ++ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; ++ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; ++ ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_54M; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_54M; ++ *pucMcsSet = 0; ++ *pucSupMcs32 = 0; ++ *pu2HtCapInfo = 0; ++ break; ++ ++ case FIXED_RATE_MCS0_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS1_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS2_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS3_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS4_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS5_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS6_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS7_20M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH ++ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ break; ++ ++ case FIXED_RATE_MCS0_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS1_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS2_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS3_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS4_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS5_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS6_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS7_20M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; ++ break; ++ ++ case FIXED_RATE_MCS0_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS1_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS2_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS3_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS4_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS5_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS6_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS7_40M_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS32_800NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS32_INDEX; ++ *pucSupMcs32 = 1; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; ++ break; ++ ++ case FIXED_RATE_MCS0_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS0_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS1_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS1_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS2_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS2_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS3_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS3_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS4_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS4_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS5_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS5_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS6_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS6_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS7_40M_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS7_INDEX; ++ *pucSupMcs32 = 0; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ case FIXED_RATE_MCS32_400NS: ++ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; ++ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; ++ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; ++ *pucMcsSet = HT_RATE_MCS32_INDEX; ++ *pucSupMcs32 = 1; ++ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); ++ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to write the register ++* ++* @param u4Address Register address ++* u4Value the value to be written ++* ++* @retval WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value) ++{ ++ CMD_ACCESS_REG rCmdAccessReg; ++ ++ rCmdAccessReg.u4Address = u4Address; ++ rCmdAccessReg.u4Data = u4Value; ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_ACCESS_REG, ++ TRUE, ++ FALSE, ++ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8) &rCmdAccessReg, NULL, 0); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to modify the auto rate parameters ++* ++* @param u4ArSysParam0 see description below ++* u4ArSysParam1 ++* u4ArSysParam2 ++* u4ArSysParam3 ++* ++* ++* @retval WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++* ++* @note ++* ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2) ++* ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2) ++* ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2) ++* ArSysParam0[8:15]-> HT rate clear mask ++* ArSysParam0[16:31]-> Legacy rate clear mask ++* ArSysParam1[0:7]-> Auto Rate check weighting window ++* ArSysParam1[8:15]-> Auto Rate v1 Force Rate down ++* ArSysParam1[16:23]-> Auto Rate v1 PerH ++* ArSysParam1[24:31]-> Auto Rate v1 PerL ++* ++* Examples ++* ArSysParam0 = 1, ++* Enable auto rate version 1 ++* ++* ArSysParam0 = 983041, ++* Enable auto rate version 1 ++* Remove CCK 1M, 2M, 5.5M, 11M ++* ++* ArSysParam0 = 786433 ++* Enable auto rate version 1 ++* Remove CCK 5.5M 11M ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS ++nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4ArSysParam0, ++ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3) ++{ ++ UINT_8 ucArVer, ucAbwVer, ucAgiVer; ++ UINT_16 u2HtClrMask; ++ UINT_16 u2LegacyClrMask; ++ UINT_8 ucArCheckWindow; ++ UINT_8 ucArPerL; ++ UINT_8 ucArPerH; ++ UINT_8 ucArPerForceRateDownPer; ++ ++ ucArVer = (UINT_8) (u4ArSysParam0 & BITS(0, 3)); ++ ucAbwVer = (UINT_8) ((u4ArSysParam0 & BITS(4, 5)) >> 4); ++ ucAgiVer = (UINT_8) ((u4ArSysParam0 & BITS(6, 7)) >> 6); ++ u2HtClrMask = (UINT_16) ((u4ArSysParam0 & BITS(8, 15)) >> 8); ++ u2LegacyClrMask = (UINT_16) ((u4ArSysParam0 & BITS(16, 31)) >> 16); ++ ++#if 0 ++ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); ++ ucArPerForceRateDownPer = (UINT_8) ((u4ArSysParam1 & BITS(8, 15) >> 8)); ++ ucArPerH = (UINT_8) ((u4ArSysParam1 & BITS(16, 23)) >> 16); ++ ucArPerL = (UINT_8) ((u4ArSysParam1 & BITS(24, 31)) >> 24); ++#endif ++ ++ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); ++ ucArPerForceRateDownPer = (UINT_8) (((u4ArSysParam1 >> 8) & BITS(0, 7))); ++ ucArPerH = (UINT_8) (((u4ArSysParam1 >> 16) & BITS(0, 7))); ++ ucArPerL = (UINT_8) (((u4ArSysParam1 >> 24) & BITS(0, 7))); ++ ++ DBGLOG(NIC, INFO, "ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3); ++ DBGLOG(NIC, INFO, "ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer); ++ DBGLOG(NIC, INFO, "HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask); ++ DBGLOG(NIC, INFO, ++ "CheckWin %u RateDownPer %u PerH %u PerL %u\n", ucArCheckWindow, ucArPerForceRateDownPer, ucArPerH, ++ ucArPerL); ++ ++#define SWCR_DATA_ADDR(MOD, ADDR) (0x90000000+(MOD<<8)+(ADDR)) ++#define SWCR_DATA_CMD(CATE, WRITE, INDEX, OPT0, OPT1) ((CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 << 8) | OPT1) ++#define SWCR_DATA0 0x0 ++#define SWCR_DATA1 0x4 ++#define SWCR_DATA2 0x8 ++#define SWCR_DATA3 0xC ++#define SWCR_DATA4 0x10 ++#define SWCR_WRITE 1 ++#define SWCR_READ 0 ++ ++ if (ucArVer > 0) { ++ /* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */ ++ /* dummy = WiFi.WriteMCR(&h90000100, &h00850000) */ ++ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 1); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); ++ } else { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 0); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); ++ } ++ ++ /* ucArVer 0: none 1:PER 2:Rcpi */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArVer); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 7, 0, 0)); ++ ++ /* Candidate rate Ht mask */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2HtClrMask); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1c, 0, 0)); ++ ++ /* Candidate rate legacy mask */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2LegacyClrMask); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1d, 0, 0)); ++ ++#if 0 ++ if (ucArCheckWindow != 0) { ++ /* TX DONE MCS INDEX CHECK STA RATE DOWN TH */ ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x14, 0, 0)); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0xc, 0, 0)); ++ } ++ ++ if (ucArPerForceRateDownPer != 0) { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerForceRateDownPer); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x18, 0, 0)); ++ } ++ if (ucArPerH != 0) { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerH); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1, 0, 0)); ++ } ++ if (ucArPerL != 0) { ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerL); ++ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x2, 0, 0)); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This utility function is used to enable roaming ++* ++* @param u4EnableRoaming ++* ++* ++* @retval WLAN_STATUS_SUCCESS ++* WLAN_STATUS_FAILURE ++* ++* @note ++* u4EnableRoaming -> Enable Romaing ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming) ++{ ++ P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); ++ prConnSettings->fgIsEnableRoaming = ((u4EnableRoaming > 0) ? (TRUE) : (FALSE)); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief dump firmware Assert message ++* ++* \param[in] ++* prAdapter ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4MailBox0, u4MailBox1; ++ UINT_32 line = 0; ++ UINT_8 aucAssertFile[7]; ++ UINT_32 u4ChipId; ++ ++#if CFG_SDIO_INTR_ENHANCE ++ u4MailBox0 = prAdapter->prSDIOCtrl->u4RcvMailbox0; ++ u4MailBox1 = prAdapter->prSDIOCtrl->u4RcvMailbox1; ++#else ++ nicGetMailbox(prAdapter, 0, &u4MailBox0); ++ nicGetMailbox(prAdapter, 1, &u4MailBox1); ++#endif ++ ++ line = u4MailBox0 & 0x0000FFFF; ++ ++ u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF); ++ ++ kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2); ++ kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4); ++ ++ aucAssertFile[6] = '\0'; ++ ++#if defined(MT6620) ++ u4ChipId = 6620; ++#elif defined(MT6628) ++ u4ChipId = 6582; ++#endif ++ ++ kalPrint("\n[MT%u][wifi][Firmware] Assert at \"%s\" #%u\n\n", u4ChipId, aucAssertFile, line); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update Link Quality information ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* eNetTypeIdx ++* prEventLinkQuality ++* cRssi ++* cLinkQuality ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ASSERT(prEventLinkQuality); ++ ++ switch (eNetTypeIdx) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* check is to prevent RSSI to be updated by incorrect initial RSSI from hardware */ ++ /* buffer statistics for further query */ ++ if (prAdapter->fgIsLinkQualityValid == FALSE ++ || (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { ++ nicUpdateRSSI(prAdapter, eNetTypeIdx, prEventLinkQuality->cRssi, ++ prEventLinkQuality->cLinkQuality); ++ } ++ ++ if (prAdapter->fgIsLinkRateValid == FALSE ++ || (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { ++ nicUpdateLinkSpeed(prAdapter, eNetTypeIdx, prEventLinkQuality->u2LinkSpeed); ++ } ++ } ++ break; ++#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY ++ case NETWORK_TYPE_P2P_INDEX: ++ if (prAdapter->fgIsP2pLinkQualityValid == FALSE ++ || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { ++ P_EVENT_LINK_QUALITY_EX prEventLQEx = (P_EVENT_LINK_QUALITY_EX) prEventLinkQuality; ++ ++ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, prEventLQEx->cRssiP2P, ++ prEventLQEx->cLinkQualityP2P); ++ } ++ break; ++#endif ++ default: ++ break; ++ ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update RSSI and Link Quality information ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* eNetTypeIdx ++* cRssi ++* cLinkQuality ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicUpdateRSSI(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ switch (eNetTypeIdx) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ prAdapter->fgIsLinkQualityValid = TRUE; ++ prAdapter->rLinkQualityUpdateTime = kalGetTimeTick(); ++ ++ prAdapter->rLinkQuality.cRssi = cRssi; ++ prAdapter->rLinkQuality.cLinkQuality = cLinkQuality; ++ ++ /* indicate to glue layer */ ++ kalUpdateRSSI(prAdapter->prGlueInfo, ++ KAL_NETWORK_TYPE_AIS_INDEX, ++ prAdapter->rLinkQuality.cRssi, prAdapter->rLinkQuality.cLinkQuality); ++ } ++ ++ break; ++#if CFG_ENABLE_WIFI_DIRECT ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ case NETWORK_TYPE_P2P_INDEX: ++ prAdapter->fgIsP2pLinkQualityValid = TRUE; ++ prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick(); ++ ++ prAdapter->rP2pLinkQuality.cRssi = cRssi; ++ prAdapter->rP2pLinkQuality.cLinkQuality = cLinkQuality; ++ ++ kalUpdateRSSI(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_P2P_INDEX, cRssi, cLinkQuality); ++ break; ++#endif ++#endif ++ default: ++ break; ++ ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called to update Link Quality information ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* eNetTypeIdx ++* prEventLinkQuality ++* cRssi ++* cLinkQuality ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed) ++{ ++ ASSERT(prAdapter); ++ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); ++ ++ switch (eNetTypeIdx) { ++ case NETWORK_TYPE_AIS_INDEX: ++ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ /* buffer statistics for further query */ ++ prAdapter->fgIsLinkRateValid = TRUE; ++ prAdapter->rLinkRateUpdateTime = kalGetTimeTick(); ++ ++ prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed; ++ } ++ break; ++ ++ default: ++ break; ++ ++ } ++ ++} ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam) ++{ ++ DEBUGFUNC("nicUpdateRddTestMode.\n"); ++ ++ ASSERT(prAdapter); ++ ++/* aisFsmScanRequest(prAdapter, NULL); */ ++ ++ return wlanSendSetQueryCmd(prAdapter, ++ CMD_ID_SET_RDD_CH, ++ TRUE, ++ FALSE, FALSE, NULL, NULL, sizeof(CMD_RDD_CH_T), (PUINT_8) prRddChParam, NULL, 0); ++} ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c +new file mode 100644 +index 000000000000..3c9c24f9542b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c +@@ -0,0 +1,1636 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_cmd_event.c#1 ++*/ ++ ++/*! \file nic_cmd_event.c ++ \brief Callback functions for Command packets. ++ ++ Various Event packet handlers which will be setup in the callback function of ++ a command packet. ++*/ ++ ++/* ++** Log: nic_cmd_event.c ++ * ++ * 04 10 2012 yuche.tsai ++ * NULL ++ * Update address for wifi direct connection issue. ++ * ++ * 06 15 2011 cm.chang ++ * [WCXRP00000785] [MT6620 Wi-Fi][Driver][FW] P2P/BOW MAC address is XOR with AIS MAC address ++ * P2P/BOW mac address XOR with local bit instead of OR ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000493] [MT6620 Wi-Fi][Driver] Do not indicate redundant disconnection to host when entering into RF ++ * test mode ++ * only indicate DISCONNECTION to host when entering RF test if necessary (connected -> disconnected cases) ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to ++ * system scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 12 01 2010 cp.wu ++ * [WCXRP00000223] MT6620 Wi-Fi][Driver][FW] Adopt NVRAM parameters when enter/exit RF test mode ++ * reload NVRAM settings before entering RF test mode and leaving from RF test mode. ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 20 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * use OID_CUSTOM_TEST_MODE as indication for driver reset ++ * by dropping pending TX packets ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 15 2010 yuche.tsai ++ * NULL ++ * Start to test AT GO only when P2P state is not IDLE. ++ * ++ * 09 09 2010 yuche.tsai ++ * NULL ++ * Add AT GO Test mode after MAC address available. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. ++ * There is no CFG_SUPPORT_BOW in driver domain source. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 11 2010 yuche.tsai ++ * NULL ++ * Add support for P2P Device Address query from FW. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 08 02 2010 cp.wu ++ * NULL ++ * reset FSMs before entering RF test mode. ++ * ++ * 07 22 2010 cp.wu ++ * ++ * 1) refine AIS-FSM indent. ++ * 2) when entering RF Test mode, flush 802.1X frames as well ++ * 3) when entering D3 state, flush 802.1X frames as well ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 05 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. ++ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 29 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change upon request: indicate as disconnected in driver domain when leaving from RF test mode ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * do not clear scanning list array after disassociation ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. ++ * 2) finish statistics OIDs ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * change OID behavior to meet WHQL requirement. ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct OID_802_11_DISASSOCIATE handling. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * are now handled in glue layer ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * are done in adapter layer. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glude code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * sync statistics data structure definition with firmware implementation ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * statistics information OIDs are now handled by querying from firmware domain ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * indicate media stream mode after set is done ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement custom OID: EEPROM read/write access ++ * ++ * 03 03 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_3_MULTICAST_LIST oid handling ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * limit RSSI return value to micxxsoft defined range. ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 29 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * block until firmware finished RF test enter/leave then indicate completion to upper layer ++ * ++ * 01 29 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when entering RF test mode and leaving from RF test mode, wait for W_FUNC_RDY bit to be asserted forever until it ++ * is set or card is removed. ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * * * 4. correct some HAL implementation ++ * ++ * 01 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * * * OID_802_11_RSSI, ++ * * * * * OID_802_11_RSSI_TRIGGER, ++ * * * * * OID_802_11_STATISTICS, ++ * * * * * OID_802_11_DISASSOCIATE, ++ * * * * * OID_802_11_POWER_MODE ++ * ++ * 01 21 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement OID_802_11_MEDIA_STREAM_MODE ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:47:47 GMT mtk02752 ++** only handle MCR read when accessing FW domain register ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 17:37:28 GMT mtk02752 ++** * refine nicCmdEventQueryMcrRead ++** + add TxStatus/RxStatus for RF test QueryInformation OIDs ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 22:05:45 GMT mtk02752 ++** kalOidComplete() will decrease i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-01 23:02:57 GMT mtk02752 ++** remove unnecessary spin locks ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-01 22:51:18 GMT mtk02752 ++** maintein i4OidPendingCount ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-30 10:55:03 GMT mtk02752 ++** modify for compatibility ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 14:46:32 GMT mtk02752 ++** add another version of command-done handler upon new event structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:33 GMT mtk01461 ++** Add comment ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 19:32:42 GMT mtk01461 ++** Add nicCmdEventSetCommon() for general set OID ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:35 GMT mtk01461 ++** Command Done Handler ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_ACCESS_REG prCmdAccessReg; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdAccessReg = (P_CMD_ACCESS_REG) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); ++ ++ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prMcrRdInfo->u4McrOffset = prCmdAccessReg->u4Address; ++ prMcrRdInfo->u4McrData = prCmdAccessReg->u4Data; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ return; ++ ++} ++ ++VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_CMD_SW_DBG_CTRL_T prCmdSwCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prCmdSwCtrl = (P_CMD_SW_DBG_CTRL_T) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); ++ ++ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prSwCtrlInfo->u4Id = prCmdSwCtrl->u4Id; ++ prSwCtrlInfo->u4Data = prCmdSwCtrl->u4Data; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ return; ++ ++} ++ ++VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4InformationBufferLength, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ } ++ ++ DBGLOG(NIC, TRACE, "DisByCmdE\n"); ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++#if !defined(LINUX) ++ prAdapter->fgIsRadioOff = TRUE; ++#endif ++ ++} ++ ++VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4Count; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ u4Count = (prCmdInfo->u4SetInfoLen - OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress)) ++ / sizeof(IPV4_NETWORK_ADDRESS); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, ++ OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress) + u4Count * ++ (OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP)), ++ WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_TEST_STATUS prTestStatus, prQueryBuffer; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prTestStatus = (P_EVENT_TEST_STATUS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prQueryBuffer = (P_EVENT_TEST_STATUS) prCmdInfo->pvInformationBuffer; ++ ++ kalMemCopy(prQueryBuffer, prTestStatus, sizeof(EVENT_TEST_STATUS)); ++ ++ u4QueryInfoLen = sizeof(EVENT_TEST_STATUS); ++ ++ /* Update Query Information Length */ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ PARAM_RSSI rRssi, *prRssi; ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ rRssi = (PARAM_RSSI) prLinkQuality->cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ ++ DBGLOG(NIC, INFO, " %s: rRssi = %d\n", __func__, rRssi); ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { ++ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) ++ rRssi = PARAM_WHQL_RSSI_MAX_DBM; ++ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ } else { ++ rRssi = PARAM_WHQL_RSSI_MIN_DBM; ++ } ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prRssi = (PARAM_RSSI *) prCmdInfo->pvInformationBuffer; ++ ++ kalMemCopy(prRssi, &rRssi, sizeof(PARAM_RSSI)); ++ u4QueryInfoLen = sizeof(PARAM_RSSI); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is in response of OID_GEN_LINK_SPEED query request ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the pending command info ++* @param pucEventBuf ++* ++* @retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_LINK_QUALITY prLinkQuality; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4LinkSpeed; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ pu4LinkSpeed = (PUINT_32) (prCmdInfo->pvInformationBuffer); ++ ++ *pu4LinkSpeed = prLinkQuality->u2LinkSpeed * 5000; ++ ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ u4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ ++ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); ++ prStatistics->rTransmittedFragmentCount = prEventStatistics->rTransmittedFragmentCount; ++ prStatistics->rMulticastTransmittedFrameCount = prEventStatistics->rMulticastTransmittedFrameCount; ++ prStatistics->rFailedCount = prEventStatistics->rFailedCount; ++ prStatistics->rRetryCount = prEventStatistics->rRetryCount; ++ prStatistics->rMultipleRetryCount = prEventStatistics->rMultipleRetryCount; ++ prStatistics->rRTSSuccessCount = prEventStatistics->rRTSSuccessCount; ++ prStatistics->rRTSFailureCount = prEventStatistics->rRTSFailureCount; ++ prStatistics->rACKFailureCount = prEventStatistics->rACKFailureCount; ++ prStatistics->rFrameDuplicateCount = prEventStatistics->rFrameDuplicateCount; ++ prStatistics->rReceivedFragmentCount = prEventStatistics->rReceivedFragmentCount; ++ prStatistics->rMulticastReceivedFrameCount = prEventStatistics->rMulticastReceivedFrameCount; ++ prStatistics->rFCSErrorCount = prEventStatistics->rFCSErrorCount; ++ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; ++ prStatistics->rTKIPICVErrors.QuadPart = 0; ++ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; ++ prStatistics->rTKIPReplays.QuadPart = 0; ++ prStatistics->rCCMPFormatErrors.QuadPart = 0; ++ prStatistics->rCCMPReplays.QuadPart = 0; ++ prStatistics->rCCMPDecryptErrors.QuadPart = 0; ++ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; ++ prStatistics->rWEPUndecryptableCount.QuadPart = 0; ++ prStatistics->rWEPICVErrorCount.QuadPart = 0; ++ prStatistics->rDecryptSuccessCount.QuadPart = 0; ++ prStatistics->rDecryptFailureCount.QuadPart = 0; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++#define WAIT_FW_READY_RETRY_CNT 200 ++ ++ UINT_32 u4WHISR = 0, u4Value = 0; ++ UINT_8 aucTxCount[8]; ++ UINT_16 u2RetryCnt = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* [driver-land] */ ++ prAdapter->fgTestMode = TRUE; ++ ++ /* 0. always indicate disconnection */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ /* 1. Remove pending TX */ ++ nicTxRelease(prAdapter); ++ ++ /* 1.1 clear pending Security / Management Frames */ ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++ kalClearMgmtFrames(prAdapter->prGlueInfo); ++ ++ /* 1.2 clear pending TX packet queued in glue layer */ ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* 2. Reset driver-domain FSMs */ ++ nicUninitMGMT(prAdapter); ++ ++ nicResetSystemService(prAdapter); ++ nicInitMGMT(prAdapter, NULL); ++ ++ /* 3. Disable Interrupt */ ++ HAL_INTR_DISABLE(prAdapter); ++ ++ /* 4. Block til firmware completed entering into RF test mode */ ++ kalMsleep(500); ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || ++ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, ++ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); ++ ++ } ++ return; ++ } ++ kalMsleep(10); ++ u2RetryCnt++; ++ } ++ ++ /* 5. Clear Interrupt Status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ /* 6. Reset TX Counter */ ++ nicTxResetResource(prAdapter); ++ ++ /* 7. Re-enable Interrupt */ ++ HAL_INTR_ENABLE(prAdapter); ++ ++ /* 8. completion indication */ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); ++ } ++#if CFG_SUPPORT_NVRAM ++ /* 9. load manufacture data */ ++ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); ++#endif ++ ++} ++ ++VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++#define WAIT_FW_READY_RETRY_CNT 200 ++ ++ UINT_32 u4WHISR = 0, u4Value = 0; ++ UINT_8 aucTxCount[8]; ++ UINT_16 u2RetryCnt = 0; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ /* 1. Disable Interrupt */ ++ HAL_INTR_DISABLE(prAdapter); ++ ++ /* 2. Block til firmware completed leaving from RF test mode */ ++ kalMsleep(500); ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || ++ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, ++ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); ++ ++ } ++ return; ++ } ++ kalMsleep(10); ++ u2RetryCnt++; ++ } ++ ++ /* 3. Clear Interrupt Status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ /* 4. Reset TX Counter */ ++ nicTxResetResource(prAdapter); ++ ++ /* 5. Re-enable Interrupt */ ++ HAL_INTR_ENABLE(prAdapter); ++ ++ /* 6. set driver-land variable */ ++ prAdapter->fgTestMode = FALSE; ++ ++ /* 7. completion indication */ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ /* 8. Indicate as disconnected */ ++ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ } ++#if CFG_SUPPORT_NVRAM ++ /* 9. load manufacture data */ ++ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); ++#endif ++ ++ /* 10. Override network address */ ++ wlanUpdateNetworkAddress(prAdapter); ++ ++} ++ ++VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_BASIC_CONFIG prEventBasicConfig; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (pucEventBuf); ++ ++ /* copy to adapter */ ++ kalMemCopy(&(prAdapter->rMyMacAddr), &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ kalMemCopy(prCmdInfo->pvInformationBuffer, &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); ++ u4QueryInfoLen = MAC_ADDR_LEN; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ /* 4 <3> Update new MAC address and all 3 networks */ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, prAdapter->rMyMacAddr); ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, prAdapter->rMyMacAddr); ++ prAdapter->rWifiVar.aucDeviceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress, prAdapter->rMyMacAddr); ++ prAdapter->rWifiVar.aucInterfaceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; ++ ++ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucOwnMacAddr, prAdapter->rMyMacAddr); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].aucOwnMacAddr, ++ prAdapter->rWifiVar.aucDeviceAddress); ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].aucOwnMacAddr, ++ prAdapter->rWifiVar.aucDeviceAddress); ++#endif ++ ++#if CFG_TEST_WIFI_DIRECT_GO ++ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_IDLE) { ++ wlanEnableP2pFunction(prAdapter); ++ ++ wlanEnableATGO(prAdapter); ++ } ++#endif ++ ++ kalUpdateMACAddress(prAdapter->prGlueInfo, prAdapter->rWifiVar.aucMacAddress); ++ ++} ++ ++VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_MAC_MCAST_ADDR prEventMacMcastAddr; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventMacMcastAddr = (P_EVENT_MAC_MCAST_ADDR) (pucEventBuf); ++ ++ u4QueryInfoLen = prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN; ++ ++ /* buffer length check */ ++ if (prCmdInfo->u4InformationBufferLength < u4QueryInfoLen) { ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_BUFFER_TOO_SHORT); ++ } else { ++ kalMemCopy(prCmdInfo->pvInformationBuffer, ++ prEventMacMcastAddr->arAddress, ++ prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ } ++} ++ ++VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRdInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_ACCESS_EEPROM prEventAccessEeprom; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventAccessEeprom = (P_EVENT_ACCESS_EEPROM) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); ++ ++ prEepromRdInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prEepromRdInfo->ucEepromIndex = (UINT_8) (prEventAccessEeprom->u2Offset); ++ prEepromRdInfo->u2EepromData = prEventAccessEeprom->u2Data; ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ return; ++ ++} ++ ++VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ PARAM_MEDIA_STREAMING_INDICATION rParamMediaStreamIndication; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ if (prCmdInfo->fgIsOid) { ++ /* Update Set Information Length */ ++ kalOidComplete(prAdapter->prGlueInfo, ++ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++ rParamMediaStreamIndication.rStatus.eStatusType = ENUM_STATUS_TYPE_MEDIA_STREAM_MODE; ++ rParamMediaStreamIndication.eMediaStreamMode = ++ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID)&rParamMediaStreamIndication, sizeof(PARAM_MEDIA_STREAMING_INDICATION)); ++} ++ ++/* Statistics responder */ ++VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rTransmittedFragmentCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rTransmittedFragmentCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rReceivedFragmentCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rReceivedFragmentCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; ++ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; ++ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = 0; /* @FIXME? */ ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = 0; /* @FIXME? */ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) 0; /* @FIXME */ ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = 0; /* @FIXME */ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = ++ (UINT_32) (prEventStatistics->rMultipleRetryCount.QuadPart - ++ prEventStatistics->rRetryCount.QuadPart); ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = ++ (UINT_64) (prEventStatistics->rMultipleRetryCount.QuadPart - ++ prEventStatistics->rRetryCount.QuadPart); ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rMultipleRetryCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = (UINT_64) prEventStatistics->rMultipleRetryCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ P_EVENT_STATISTICS prEventStatistics; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4QueryInfoLen; ++ PUINT_32 pu4Data; ++ PUINT_64 pu8Data; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { ++ u4QueryInfoLen = sizeof(UINT_32); ++ ++ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; ++ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; ++ } else { ++ u4QueryInfoLen = sizeof(UINT_64); ++ ++ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; ++ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when command by OID/ioctl has been timeout ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* ++* @return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is a generic command timeout handler ++* ++* @param pfnOidHandler Pointer to the OID handler ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when command for entering RF test has ++* failed sending due to timeout (highly possibly by firmware crash) ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) ++{ ++ ASSERT(prAdapter); ++ ++ /* 1. Remove pending TX frames */ ++ nicTxRelease(prAdapter); ++ ++ /* 1.1 clear pending Security / Management Frames */ ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++ kalClearMgmtFrames(prAdapter->prGlueInfo); ++ ++ /* 1.2 clear pending TX packet queued in glue layer */ ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* 2. indicate for OID failure */ ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when command for memory dump has ++* replied a event. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; ++ P_GLUE_INFO_T prGlueInfo; ++ P_EVENT_DUMP_MEM_T prEventDumpMem; ++ static UINT_8 aucPath[256]; ++ static UINT_32 u4CurTimeTick; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventDumpMem = (P_EVENT_DUMP_MEM_T) (pucEventBuf); ++ ++ u4QueryInfoLen = sizeof(P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T); ++ ++ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) prCmdInfo->pvInformationBuffer; ++ prMemDumpInfo->u4Address = prEventDumpMem->u4Address; ++ prMemDumpInfo->u4Length = prEventDumpMem->u4Length; ++ prMemDumpInfo->u4RemainLength = prEventDumpMem->u4RemainLength; ++ prMemDumpInfo->ucFragNum = prEventDumpMem->ucFragNum; ++ ++#if 0 ++ do { ++ UINT_32 i = 0; ++ ++ DBGLOG(REQ, TRACE, "Rx dump address 0x%X, Length %d, FragNum %d, remain %d\n", ++ prEventDumpMem->u4Address, ++ prEventDumpMem->u4Length, prEventDumpMem->ucFragNum, prEventDumpMem->u4RemainLength); ++#if 0 ++ for (i = 0; i < prEventDumpMem->u4Length; i++) { ++ DBGLOG(REQ, TRACE, "%02X ", prEventDumpMem->aucBuffer[i]); ++ if (i % 32 == 31) ++ DBGLOG(REQ, TRACE, "\n"); ++ } ++#endif ++ } while (FALSE); ++#endif ++ ++ if (prEventDumpMem->ucFragNum == 1) { ++ /* Store memory dump into sdcard, ++ * path /sdcard/dump___.hex ++ */ ++ u4CurTimeTick = kalGetTimeTick(); ++ sprintf(aucPath, "/sdcard/dump_%d_0x%08X_%d.hex", ++ u4CurTimeTick, ++ prEventDumpMem->u4Address, prEventDumpMem->u4Length + prEventDumpMem->u4RemainLength); ++ kalWriteToFile(aucPath, FALSE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); ++ } else { ++ /* Append current memory dump to the hex file */ ++ kalWriteToFile(aucPath, TRUE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); ++ } ++ ++ if (prEventDumpMem->u4RemainLength == 0 || prEventDumpMem->u4Address == 0xFFFFFFFF) { ++ /* The request is finished or firmware response a error */ ++ /* Reply time tick to iwpriv */ ++ *((PUINT_32) prCmdInfo->pvInformationBuffer) = u4CurTimeTick; ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } else { ++ /* The memory dump request is not finished, Send next command */ ++ wlanSendMemDumpCmd(prAdapter, ++ prCmdInfo->pvInformationBuffer, prCmdInfo->u4InformationBufferLength); ++ } ++ } ++ ++ return; ++ ++} ++ ++#if CFG_SUPPORT_BATCH_SCAN ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for SUPPORT_BATCH_SCAN ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_BATCH_RESULT_T prEventBatchResult; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DBGLOG(SCN, TRACE, "nicCmdEventBatchScanResult"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pucEventBuf; ++ ++ u4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); ++ kalMemCopy(prCmdInfo->pvInformationBuffer, prEventBatchResult, sizeof(EVENT_BATCH_RESULT_T)); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++#endif ++ ++#if CFG_SUPPORT_BUILD_DATE_CODE ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for build date code information ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_BUILD_DATE_CODE prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_BUILD_DATE_CODE) pucEventBuf; ++ ++ u4QueryInfoLen = sizeof(UINT_8) * 16; ++ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent->aucDateCode, sizeof(UINT_8) * 16); ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for query STA link status ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_STA_STATISTICS_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_GET_STA_STATISTICS prStaStatistics; ++ ++ if ((prAdapter == NULL) ++ || (prCmdInfo == NULL) ++ || (pucEventBuf == NULL) ++ || (prCmdInfo->pvInformationBuffer == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_STA_STATISTICS_T) pucEventBuf; ++ prStaStatistics = (P_PARAM_GET_STA_STATISTICS) prCmdInfo->pvInformationBuffer; ++ ++ u4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); ++ ++ /* Statistics from FW is valid */ ++ if (prEvent->u4Flags & BIT(0)) { ++ prStaStatistics->ucPer = prEvent->ucPer; ++ prStaStatistics->ucRcpi = prEvent->ucRcpi; ++ prStaStatistics->u4PhyMode = prEvent->u4PhyMode; ++ prStaStatistics->u2LinkSpeed = prEvent->u2LinkSpeed; ++ ++ prStaStatistics->u4TxFailCount = prEvent->u4TxFailCount; ++ prStaStatistics->u4TxLifeTimeoutCount = prEvent->u4TxLifeTimeoutCount; ++ ++ if (prEvent->u4TxCount) { ++ UINT_32 u4TxDoneAirTimeMs = USEC_TO_MSEC(prEvent->u4TxDoneAirTime * 32); ++ ++ prStaStatistics->u4TxAverageAirTime = (u4TxDoneAirTimeMs / prEvent->u4TxCount); ++ } else { ++ prStaStatistics->u4TxAverageAirTime = 0; ++ } ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++/* 4 Auto Channel Selection */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for query STA link status ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_CHN_LOAD_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_GET_CHN_LOAD prChnLoad; ++ ++ if ((prAdapter == NULL) ++ || (prCmdInfo == NULL) ++ || (pucEventBuf == NULL) ++ || (prCmdInfo->pvInformationBuffer == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_CHN_LOAD_T) pucEventBuf; /* 4 The firmware responsed data */ ++ /* 4 Fill the firmware data in and send it back to host */ ++ prChnLoad = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; ++ ++ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); ++ ++ /* Statistics from FW is valid */ ++ if (prEvent->u4Flags & BIT(0)) { ++ prChnLoad->rEachChnLoad[0].ucChannel = prEvent->ucChannel; ++ prChnLoad->rEachChnLoad[0].u2ChannelLoad = prEvent->u2ChannelLoad; ++ DBGLOG(P2P, INFO, "CHN[%d]=%d\n", prEvent->ucChannel, prEvent->u2ChannelLoad); ++ ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++ ++VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_8 ucIdx = 0; ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_LTE_MODE_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_PARAM_GET_CHN_LOAD prLteSafeChnInfo; ++ ++ if ((prAdapter == NULL) ++ || (prCmdInfo == NULL) ++ || (pucEventBuf == NULL) ++ || (prCmdInfo->pvInformationBuffer == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_LTE_MODE_T) pucEventBuf; /* 4 The firmware responsed data */ ++ ++ prLteSafeChnInfo = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; ++ ++ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); ++ ++ /* Statistics from FW is valid */ ++ if (prEvent->u4Flags & BIT(0)) { ++ for (ucIdx = 0; ucIdx < (NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1); ucIdx++) { ++ prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx] = ++ prEvent->rLteSafeChn.au4SafeChannelBitmask[ucIdx]; ++ ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]LTE safe channels [%d]=[%x]\n", ucIdx, ++ (UINT32) prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx]); ++ } ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is called when event for query FW bss info ++* has been retrieved ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prCmdInfo Pointer to the command information ++* @param pucEventBuf Pointer to the event buffer ++* ++* @return none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) ++{ ++ UINT_32 u4QueryInfoLen; ++ P_EVENT_AIS_BSS_INFO_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ P_BSS_INFO_T prAisBssInfo; ++ ++ ASSERT(prAdapter); ++ ++ ASSERT(prCmdInfo); ++ ASSERT(pucEventBuf); ++ ++ /* 4 <2> Update information of OID */ ++ if (prCmdInfo->fgIsOid) { ++ prGlueInfo = prAdapter->prGlueInfo; ++ prEvent = (P_EVENT_AIS_BSS_INFO_T) pucEventBuf; ++ ++ u4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); ++ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent, sizeof(EVENT_AIS_BSS_INFO_T)); ++ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ ++ if (prEvent->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { ++ if (prEvent->eConnectionState != prAisBssInfo->eConnectionState) { ++ DBGLOG(NIC, ERROR, "driver[%d] & FW[%d] status didn't sync !!!\n", ++ prAisBssInfo->eConnectionState, prEvent->eCurrentOPMode); ++ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, FALSE); ++ } ++ } ++ ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); ++ } ++ ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c +new file mode 100644 +index 000000000000..cf80fd999a24 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c +@@ -0,0 +1,669 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1 ++*/ ++ ++/*! \file "nic_pwr_mgt.c" ++ \brief In this file we define the STATE and EVENT for Power Management FSM. ++ ++ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter ++ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail ++ description. ++*/ ++ ++/* ++** Log: nic_pwr_mgt.c ++ * ++ * 11 28 2011 cp.wu ++ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when ++ * returining to ROM code ++ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware ++ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not ++ * ++ * 10 03 2011 cp.wu ++ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality ++ * add firmware download path in divided scatters. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * reuse firmware download logic of MT6620 for MT6628. ++ * ++ * 05 11 2011 cp.wu ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. ++ * ++ * 04 29 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * fix for compilation error when applied with FW_DOWNLOAD = 0 ++ * ++ * 04 18 2011 cp.wu ++ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) ++ * 1) add API for glue layer to query ACPI state ++ * 2) Windows glue should not access to hardware after switched into D3 state ++ * ++ * 04 13 2011 cp.wu ++ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete ++ * refine for MT5931/MT6620 logic separation. ++ * ++ * 04 13 2011 cp.wu ++ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete ++ * bugfix: firmware download procedure for ACPI state transition is not complete. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system ++ * scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * check success or failure for setting fw-own ++ * ++ * 12 30 2010 cp.wu ++ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side ++ * host driver not to set FW-own when there is still pending interrupts ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * add firmware download for MT5931. ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * reset ACPI power state before waking up MT6620 Wi-Fi firmware. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * Centralize mgmt/system service procedures into independent calls. ++ * ++ * 07 22 2010 cp.wu ++ * ++ * 1) refine AIS-FSM indent. ++ * 2) when entering RF Test mode, flush 802.1X frames as well ++ * 3) when entering D3 state, flush 802.1X frames as well ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll ++ * 2) correct address list parsing ++ * ++ * 05 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * sleepy notify is only used for sleepy state, ++ * while wake-up state is automatically set when host needs to access device ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct hibernation problem. ++ * ++ * 04 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) surpress compiler warning ++ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when acquiring driver-own, wait for up to 8 seconds. ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove redundant firmware image unloading ++ * * 2) use compile-time macros to separate logic related to accquiring own ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * * are now handled in glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * ePowerCtrl is not necessary as a glue variable. ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * always send CMD_NIC_POWER_CTRL packet when nic is being halted ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct typo. ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX ++ * response ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084 ++** remove CMD52 access ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084 ++** modify lines in nicpmSetDriverOwn() ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084 ++** modify nicpmSetDriverOwn() ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084 ++** update for basic power management functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084 ++** Initial version ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to process the POWER ON procedure. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt) ++{ ++ UINT_32 u4RegValue = 0; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsFwOwn == TRUE) ++ return; ++ ++ if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { ++ /* pending interrupts */ ++ return; ++ } ++ ++ if (fgEnableGlobalInt) { ++ prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; ++ } else { ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); ++ ++ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); ++ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { ++ /* if set firmware own not successful (possibly pending interrupts), */ ++ /* indicate an own clear event */ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ ++ return; ++ } ++ ++ prAdapter->fgIsFwOwn = TRUE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to process the POWER OFF procedure. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 u4OriRegValue = 0; ++BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) ++{ ++#define LP_OWN_BACK_TOTAL_DELAY_MS 2000 /* exponential of 2 */ ++#define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ ++#define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ ++ ++ BOOLEAN fgStatus = TRUE; ++ UINT_32 i, u4CurrTick; ++ UINT_32 u4RegValue = 0; ++ GL_HIF_INFO_T *HifInfo; ++ ++ ASSERT(prAdapter); ++ ++ if (prAdapter->fgIsFwOwn == FALSE) ++ return fgStatus; ++ ++ HifInfo = &prAdapter->prGlueInfo->rHifInfo; ++ ++ u4CurrTick = kalGetTimeTick(); ++ STATS_DRIVER_OWN_START_RECORD(); ++ i = 0; ++ ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); ++ ++ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); ++ prAdapter->fgIsFwOwn = FALSE; ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE ++ || fgIsBusAccessFailed == TRUE ++ || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { ++ /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */ ++ fgStatus = FALSE; ++ if (fgIsResetting != TRUE) { ++ UINT_32 u4FwCnt; ++ static unsigned int u4OwnCnt; ++ /* MCR_D2HRM2R: low 4 bit means interrupt times, ++ * high 4 bit means firmware response times. ++ * ORI_MCR_D2HRM2R: the last successful value. ++ * for example: ++ * MCR_D2HRM2R = 0x44, ORI_MCR_D2HRM2R = 0x44 ++ * means firmware no receive interrupt form hardware. ++ * MCR_D2HRM2R = 0x45, ORI_MCR_D2HRM2R = 0x44 ++ * means firmware no send response. ++ * MCR_D2HRM2R = 0x55, ORI_MCR_D2HRM2R = 0x44 ++ * means firmware send response, but driver no receive. */ ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); ++ DBGLOG(NIC, WARN, " [1]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", ++ u4RegValue, u4OriRegValue); ++ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); ++ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); ++ prAdapter->fgIsFwOwn = FALSE; ++ break; ++ } ++ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); ++ DBGLOG(NIC, WARN, " [2]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", ++ u4RegValue, u4OriRegValue); ++ DBGLOG(NIC, WARN, ++ " Fatal error! Driver own fail!!!!!!!!!!!! %d, fgIsBusAccessFailed: %d\n", ++ u4OwnCnt++, fgIsBusAccessFailed); ++ ++ DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n"); ++ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) ++ DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); ++ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ ++ kalSendAeeWarning("[Fatal error! Driver own fail!]", __func__); ++ glDoChipReset(); ++ } ++ break; ++ } ++ if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { ++ /* Software get LP ownership - per 256 iterations */ ++ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); ++ } ++ ++ /* Delay for LP engine to complete its operation. */ ++ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); ++ i++; ++ } ++ ++ STATS_DRIVER_OWN_END_RECORD(); ++ STATS_DRIVER_OWN_STOP(); ++ ++ return fgStatus; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set ACPI power mode to D0. ++* ++* \param[in] pvAdapter Pointer to the Adapter structure. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter) ++{ ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ UINT_32 u4Value = 0, u4WHISR = 0; ++ UINT_8 aucTxCount[8]; ++ UINT_32 i; ++#if CFG_ENABLE_FW_DOWNLOAD ++ UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize; ++ PVOID prFwMappingHandle; ++ PVOID pvFwImageMapFile = NULL; ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ UINT_32 j; ++ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; ++ BOOLEAN fgValidHead; ++ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); ++#endif ++#endif ++ ++ DEBUGFUNC("nicpmSetAcpiPowerD0"); ++ ASSERT(prAdapter); ++ ++ do { ++ /* 0. Reset variables in ADAPTER_T */ ++ prAdapter->fgIsFwOwn = TRUE; ++ prAdapter->fgWiFiInSleepyState = FALSE; ++ prAdapter->rAcpiState = ACPI_STATE_D0; ++ prAdapter->fgIsEnterD3ReqIssued = FALSE; ++ ++ /* 1. Request Ownership to enter F/W download state */ ++ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); ++#if !CFG_ENABLE_FULL_PM ++ nicpmSetDriverOwn(prAdapter); ++#endif ++ ++ /* 2. Initialize the Adapter */ ++ u4Status = nicInitializeAdapter(prAdapter); ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); ++ if (!prFwMappingHandle) { ++ DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n"); ++ pvFwImageMapFile = NULL; ++ } ++ ++ if (pvFwImageMapFile == NULL) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ ++ /* 3.1 disable interrupt, download is done by polling mode only */ ++ nicDisableInterrupt(prAdapter); ++ ++ /* 3.2 Initialize Tx Resource to fw download state */ ++ nicTxInitResetResource(prAdapter); ++ ++ /* 3.3 FW download here */ ++ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); ++ ++#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD ++ /* 3a. parse file header for decision of divided firmware download or not */ ++ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; ++ ++ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && ++ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, ++ u4FwImgLength - u4CRCOffset)) { ++ fgValidHead = TRUE; ++ } else { ++ fgValidHead = FALSE; ++ } ++ ++ /* 3b. engage divided firmware downloading */ ++ if (fgValidHead == TRUE) { ++ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ prFwHead->arSection[i].u4DestAddr, ++ prFwHead->arSection[i].u4Length, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset) != ++ WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ prFwHead->arSection[i].u4DestAddr + j, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + ++ prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ /* escape from loop if any pending error occurs */ ++ if (u4Status == WLAN_STATUS_FAILURE) ++ break; ++ } ++ } else ++#endif ++#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION ++ if (wlanImageSectionDownloadAggregated(prAdapter, ++ u4FwLoadAddr, ++ u4FwImgLength, ++ (PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ } ++#else ++ for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) { ++ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) ++ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; ++ else ++ u4ImgSecSize = u4FwImgLength - i; ++ ++ if (wlanImageSectionDownload(prAdapter, ++ u4FwLoadAddr + i, ++ u4ImgSecSize, ++ (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(NIC, ERROR, "wlanImageSectionDownload failed!\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ } ++#endif ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) { ++ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); ++ break; ++ } ++#if !CFG_ENABLE_FW_DOWNLOAD_ACK ++ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ ++ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { ++ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++#endif ++ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); ++ ++ /* 4. send Wi-Fi Start command */ ++#if CFG_OVERRIDE_FW_START_ADDRESS ++ wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo)); ++#else ++ wlanConfigWifiFunc(prAdapter, FALSE, 0); ++#endif ++#endif /* if CFG_ENABLE_FW_DOWNLOAD */ ++ ++ /* 5. check Wi-Fi FW asserts ready bit */ ++ DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); ++ i = 0; ++ while (1) { ++ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); ++ ++ if (u4Value & WCIR_WLAN_READY) { ++ DBGLOG(NIC, TRACE, "Ready bit asserted\n"); ++ break; ++ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { ++ DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n"); ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } ++ i++; ++ kalMsleep(10); ++ } ++ ++ if (u4Status == WLAN_STATUS_SUCCESS) { ++ /* 6.1 reset interrupt status */ ++ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)(&u4WHISR)); ++ if (HAL_IS_TX_DONE_INTR(u4WHISR)) ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); ++ ++ /* 6.2 reset TX Resource for normal operation */ ++ nicTxResetResource(prAdapter); ++ ++ /* 6.3 Enable interrupt */ ++ nicEnableInterrupt(prAdapter); ++ ++ /* 6.4 Override network address */ ++ wlanUpdateNetworkAddress(prAdapter); ++ ++ /* 6.5 indicate disconnection as default status */ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ } ++ ++ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); ++ ++ /* MGMT Initialization */ ++ nicInitMGMT(prAdapter, NULL); ++ ++ } while (FALSE); ++ ++ if (u4Status != WLAN_STATUS_SUCCESS) ++ return FALSE; ++ else ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is used to set ACPI power mode to D3. ++* ++* @param prAdapter pointer to the Adapter handler ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ ++ ASSERT(prAdapter); ++ ++ /* 1. MGMT - unitialization */ ++ nicUninitMGMT(prAdapter); ++ ++ /* 2. Disable Interrupt */ ++ nicDisableInterrupt(prAdapter); ++ ++ /* 3. emit CMD_NIC_POWER_CTRL command packet */ ++ wlanSendNicPowerCtrlCmd(prAdapter, 1); ++ ++ /* 4. Clear Interrupt Status */ ++ i = 0; ++ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { ++ i++; ++ }; ++ ++ /* 5. Remove pending TX */ ++ nicTxRelease(prAdapter); ++ ++ /* 5.1 clear pending Security / Management Frames */ ++ kalClearSecurityFrames(prAdapter->prGlueInfo); ++ kalClearMgmtFrames(prAdapter->prGlueInfo); ++ ++ /* 5.2 clear pending TX packet queued in glue layer */ ++ kalFlushPendingTxPackets(prAdapter->prGlueInfo); ++ ++ /* 6. Set Onwership to F/W */ ++ nicpmSetFWOwn(prAdapter, FALSE); ++ ++ /* 7. Set variables */ ++ prAdapter->rAcpiState = ACPI_STATE_D3; ++ ++ return TRUE; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c +new file mode 100644 +index 000000000000..ba4840414da8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c +@@ -0,0 +1,3782 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_rx.c#3 ++*/ ++ ++/*! \file nic_rx.c ++ \brief Functions that provide many rx-related functions ++ ++ This file includes the functions used to process RFB and dispatch RFBs to ++ the appropriate related rx functions for protocols. ++*/ ++ ++/* ++** Log: nic_rx.c ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, ++** one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 02 14 2012 cp.wu ++ * NULL ++ * remove another assertion by error message dump ++ * ++ * 01 05 2012 tsaiyuan.hsu ++ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v ++ * add timing measurement support for 802.11v. ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Update RSSI for P2P. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * avoid deactivating staRec when changing state from 3 to 3. ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 09 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog for beacon timeout and sta aging timeout. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 10 21 2011 eddie.chen ++ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout ++ * Add switch to ignore the STA aging timeout. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 08 26 2011 cp.wu ++ * [WCXRP00000958] [MT6620 Wi-Fi][Driver] Extend polling timeout from 25ms to 1sec due to RF calibration might took ++ * up to 600ms ++ * extend polling RX response timeout period from 25ms to 1000ms. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 27 2011 cp.wu ++ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count ++ * correct comment. ++ * ++ * 07 27 2011 cp.wu ++ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count ++ * take use of QUE_MGT exported function to estimate currently RX buffer usage count. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 09 2011 tsaiyuan.hsu ++ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size ++ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. ++ * ++ * 05 11 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Fix dest type when GO packet copying. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 05 05 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add delay after whole-chip resetting for MT5931 E1 ASIC. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support for GO. ++ * ++ * 04 01 2011 tsaiyuan.hsu ++ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues ++ * fix the klocwork issues, 57500, 57501, 57502 and 57503. ++ * ++ * 03 19 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Add beacon timeout support for WiFi Direct Network. ++ * ++ * 03 18 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * enable the Anti_piracy check at driver . ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to target station for AAA ++ * module. ++ * Remove Station Record after Aging timeout. ++ * ++ * 02 10 2011 cp.wu ++ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers ++ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add MLME deauthentication support for Hot-Spot mode. ++ * ++ * 02 09 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Adjust variable order. ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * . ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Remove comments. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Add destination decision in AP mode. ++ * ++ * 01 24 2011 cm.chang ++ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec ++ * is freed ++ * Process received 20/40 coexistence action frame for AP mode ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * update beacon for NoA ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 27 2010 george.huang ++ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB ++ * Support registry option for disable beacon lost detection. ++ * ++ * 10 20 2010 wh.su ++ * NULL ++ * add a cmd to reset the p2p key ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * fixed compilier error. ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * release RX packet to packet pool when in RF test mode ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ @ associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 08 2010 cp.wu ++ * NULL ++ * use static memory pool for storing IEs of scanning result. ++ * ++ * 09 07 2010 yuche.tsai ++ * NULL ++ * Add a common buffer, store the IE of a P2P device in this common buffer. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 20 2010 cm.chang ++ * NULL ++ * Migrate RLM code to host from FW ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * When enable WiFi Direct function, check each packet to tell which interface to indicate. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * Add P2P Device Discovery Function. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 george.huang ++ * NULL ++ * handle event for updating NOA parameters indicated from FW ++ * ++ * 08 02 2010 yuche.tsai ++ * NULL ++ * Add support API for RX public action frame. ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 30 2010 cp.wu ++ * NULL ++ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code ++ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead ++ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames ++ * ++ * 07 26 2010 yuche.tsai ++ * ++ * Update Device Capability Bitmap & Group Capability Bitmap from 16 bits to 8 bits. ++ * ++ * 07 24 2010 wh.su ++ * ++ * .support the Wi-Fi RSN ++ * ++ * 07 23 2010 cp.wu ++ * ++ * add AIS-FSM handling for beacon timeout event. ++ * ++ * 07 21 2010 yuche.tsai ++ * ++ * Add P2P Scan & Scan Result Parsing & Saving. ++ * ++ * 07 19 2010 cm.chang ++ * ++ * Set RLM parameters and enable CNM channel manager ++ * ++ * 07 19 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration. ++ * Add Ad-Hoc support to AIS-FSM ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 15 2010 cp.wu ++ * ++ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill ucStaRecIdx into SW_RFB_T. ++ * ++ * 07 02 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) for event packet, no need to fill RFB. ++ * 2) when wlanAdapterStart() failed, no need to initialize state machines ++ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed ++ * ++ * 07 01 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implementation of DRV-SCN and related mailbox message handling. ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * refine TX-DONE callback. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * implement TX_DONE callback path. ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add TX Done Event handle entry ++ * ++ * 06 21 2010 wh.su ++ * [WPD00003840][MT6620 5931] Security migration ++ * remove duplicate variable for migration. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * saa_fsm.c is migrated. ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add management dispatching function table. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 ++ * 2) when disconnected, indicate nic directly (no event is needed) ++ * ++ * 06 08 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * cnm_timer has been migrated. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * merge wlan_def.h. ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * sync with MT6620 driver for scan result replacement policy ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS ++ * 2) buffer statistics data for 2 seconds ++ * 3) use default value for adhoc parameters instead of 0 ++ * ++ * 05 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) do not take timeout mechanism for power mode oids ++ * 2) retrieve network type from connection status ++ * 3) after disassciation, set radio state to off ++ * 4) TCP option over IPv6 is supported ++ * ++ * 04 29 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * fixing the PMKID candicate indicate code. ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * basic implementation for EVENT_BT_OVER_WIFI ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 16 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * treat BUS access failure as kind of card removal. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * nicRxProcessEvent packet doesn't access spin-lock directly from now on. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * do not need to release the spin lock due to it is done inside nicGetPendingCmdInfo() ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add channel frequency <-> number conversion ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) add spinlock ++ * 2) add KAPI for handling association info ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 01 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve Linux supplicant compliance ++ * ++ * 03 31 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix ioctl which may cause cmdinfo memory leak ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * rWlanInfo is modified before data is indicated to OS ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * rWlanInfo is modified before data is indicated to OS ++ * ++ * 03 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a temporary flag for integration with CMD/EVENT v0.9. ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * * * the frequency is used for adhoc connection only ++ * * * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * . ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * * * ++ * ++ * 03 19 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add ACPI D0/D3 state switching support ++ * * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX ++ * response ++ * ++ * 03 15 2010 kevin.huang ++ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test ++ * Add event for activate STA_RECORD_T ++ * ++ * 03 12 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct fgSetQuery/fgNeedResp check ++ * ++ * 03 11 2010 cp.wu ++ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 ++ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING ++ * ++ * 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock ++ * * * * 2) ensure wlanReleasePendingOid will clear all command queues ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 02 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c ++ * * 'cause it involves OS dependent data structure handling ++ * ++ * 02 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Updated API interfaces for qmHandleEventRxAddBa() and qmHandleEventRxDelBa() ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement host-side firmware download logic ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * * * 4) nicRxWaitResponse() revised ++ * * * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 01 27 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * . ++ * ++ * 01 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * implement following 802.11 OIDs: ++ * * * * * * OID_802_11_RSSI, ++ * * * * * * OID_802_11_RSSI_TRIGGER, ++ * * * * * * OID_802_11_STATISTICS, ++ * * * * * * OID_802_11_DISASSOCIATE, ++ * * * * * * OID_802_11_POWER_MODE ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * * * 2) add 4 counter for recording aggregation statistics ++ * ++ * 12 23 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add a precheck: if free sw rfb is not enough, do not invoke read transactionu1rwduu`wvpghlqg|fu+rp ++ * ++ * 12 22 2009 cp.wu ++ * [WPD00003809][Bug] Host driver will crash when processing reordered MSDUs ++ * The root cause is pointer accessing by mistake. After dequeued from reordering-buffer, handling logic should access ++ * returned pointer instead of pointer which has been passed in before. ++** \main\maintrunk.MT6620WiFiDriver_Prj\58 2009-12-17 13:40:33 GMT mtk02752 ++** always update prAdapter->rSDIOCtrl when enhanced response is read by RX ++** \main\maintrunk.MT6620WiFiDriver_Prj\57 2009-12-16 18:01:38 GMT mtk02752 ++** if interrupt enhanced response is fetched by RX enhanced response, RX needs to invoke interrupt handlers too ++** \main\maintrunk.MT6620WiFiDriver_Prj\56 2009-12-16 14:16:52 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\55 2009-12-15 20:03:12 GMT mtk02752 ++** ASSERT when RX FreeSwRfb is not enough ++** \main\maintrunk.MT6620WiFiDriver_Prj\54 2009-12-15 17:01:29 GMT mtk02752 ++** when CFG_SDIO_RX_ENHANCE is enabled, after enhanced response is read, rx procedure should process ++** 1) TX_DONE_INT 2) D2H INT as well ++** \main\maintrunk.MT6620WiFiDriver_Prj\53 2009-12-14 20:45:28 GMT mtk02752 ++** when CFG_SDIO_RX_ENHANCE is set, TC counter must be updated each time RX enhance response is read ++** ++** \main\maintrunk.MT6620WiFiDriver_Prj\52 2009-12-14 11:34:16 GMT mtk02752 ++** correct a trivial logic issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\51 2009-12-14 10:28:25 GMT mtk02752 ++** add a protection to avoid out-of-boundary access ++** \main\maintrunk.MT6620WiFiDriver_Prj\50 2009-12-10 16:55:18 GMT mtk02752 ++** code clean ++** \main\maintrunk.MT6620WiFiDriver_Prj\49 2009-12-09 14:06:47 GMT MTK02468 ++** Added parsing event packets with EVENT_ID_RX_ADDBA or EVENT_ID_RX_DELBA ++** \main\maintrunk.MT6620WiFiDriver_Prj\48 2009-12-08 17:37:51 GMT mtk02752 ++** handle EVENT_ID_TEST_STATUS as well ++** \main\maintrunk.MT6620WiFiDriver_Prj\47 2009-12-04 17:59:11 GMT mtk02752 ++** to pass free-build compilation check ++** \main\maintrunk.MT6620WiFiDriver_Prj\46 2009-12-04 12:09:52 GMT mtk02752 ++** correct trivial mistake ++** \main\maintrunk.MT6620WiFiDriver_Prj\45 2009-12-04 11:53:37 GMT mtk02752 ++** all API should be compilable under SD1_SD3_DATAPATH_INTEGRATION == 0 ++** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-03 16:19:48 GMT mtk01461 ++** Fix the Connected Event ++** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-11-30 10:56:18 GMT mtk02752 ++** 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-11-30 10:11:27 GMT mtk02752 ++** implement replacement for bss scan result ++** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-11-27 11:08:05 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-11-26 09:38:59 GMT mtk02752 ++** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-11-26 09:29:40 GMT mtk02752 ++** enable packet forwarding path (for AP mode) ++** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-11-25 21:37:00 GMT mtk02752 ++** sync. with EVENT_SCAN_RESULT_T change, and add an assert for checking event size ++** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-25 20:17:41 GMT mtk02752 ++** fill HIF_TX_HEADER_T.u2SeqNo ++** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-25 18:18:57 GMT mtk02752 ++** buffer scan result to prGlueInfo->rWlanInfo.arScanResult directly. ++** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-24 22:42:45 GMT mtk02752 ++** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event (not implemented yet) ++** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-24 20:51:41 GMT mtk02752 ++** integrate with SD1's data path API ++** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-24 19:56:17 GMT mtk02752 ++** adopt P_HIF_RX_HEADER_T in new path ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-23 20:31:21 GMT mtk02752 ++** payload to send into pfCmdDoneHandler() will not include WIFI_EVENT_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-23 17:51:34 GMT mtk02752 ++** when event packet corresponding to some pendingOID is received, pendingOID should be cleared ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 14:46:54 GMT mtk02752 ++** implement nicRxProcessEventPacket() ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-17 22:40:54 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-16 21:48:22 GMT mtk02752 ++** add SD1_SD3_DATAPATH_INTEGRATION data path handling ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-16 15:41:18 GMT mtk01084 ++** modify the length to be read in emu mode ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-13 17:00:12 GMT mtk02752 ++** add blank function for event packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-13 13:54:24 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 14:41:51 GMT mtk02752 ++** fix typo ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-11 14:33:46 GMT mtk02752 ++** add protection when there is no packet avilable ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 12:33:36 GMT mtk02752 ++** add RX1 read path for aggregated/enhanced/normal packet read procedures ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:18 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-04 14:11:08 GMT mtk01084 ++** modify lines in RX aggregation ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:23 GMT mtk01084 ++** modify RX aggregation handling ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:56:12 GMT mtk01084 ++** modify HAL part ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:34 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:20 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-02 13:59:08 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-21 23:39:05 GMT mtk01461 ++** Fix the paste error of RX STATUS in OOB of HIF Loopback CTRL ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-20 12:25:32 GMT mtk01461 ++** Fix process of Read Done, and add u4MaxEventBufferLen to nicRxWaitResponse() ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 21:13:18 GMT mtk01426 ++** Fixed compiler error ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:05:29 GMT mtk01426 ++** Fixed nicRxSDIOAggReceiveRFBs() ASSERT issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:38:43 GMT mtk01461 ++** Fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode and refine nicRxSDIOAggeceiveRFBs() for RX Aggregation ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-22 09:12:17 GMT mtk01461 ++** Fix nicRxProcessHIFLoopbackPacket(), the size of HIF CTRL LENGTH field is 1 byte ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426 ++** Update RX OOB Setting ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426 ++** Fixed logical error ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461 ++** Rename the HIF_PKT_TYPE_DATA ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461 ++** Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket() ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426 ++** Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426 ++** Add nicRxWaitResponse function ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#ifndef LINUX ++#include ++#else ++#include ++#endif ++ ++#include "gl_os.h" ++#include "debug.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include ++#include ++#include ++#include "gl_cfg80211.h" ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define RX_RESPONSE_TIMEOUT (1000) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_MGMT_FRAME_HANDLING ++static PROCESS_RX_MGT_FUNCTION apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = { ++#if CFG_SUPPORT_AAA ++ aaaFsmRunEventRxAssoc, /* subtype 0000: Association request */ ++#else ++ NULL, /* subtype 0000: Association request */ ++#endif /* CFG_SUPPORT_AAA */ ++ saaFsmRunEventRxAssoc, /* subtype 0001: Association response */ ++#if CFG_SUPPORT_AAA ++ aaaFsmRunEventRxAssoc, /* subtype 0010: Reassociation request */ ++#else ++ NULL, /* subtype 0010: Reassociation request */ ++#endif /* CFG_SUPPORT_AAA */ ++ saaFsmRunEventRxAssoc, /* subtype 0011: Reassociation response */ ++#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) ++ bssProcessProbeRequest, /* subtype 0100: Probe request */ ++#else ++ NULL, /* subtype 0100: Probe request */ ++#endif /* CFG_SUPPORT_ADHOC */ ++ scanProcessBeaconAndProbeResp, /* subtype 0101: Probe response */ ++ NULL, /* subtype 0110: reserved */ ++ NULL, /* subtype 0111: reserved */ ++ scanProcessBeaconAndProbeResp, /* subtype 1000: Beacon */ ++ NULL, /* subtype 1001: ATIM */ ++ saaFsmRunEventRxDisassoc, /* subtype 1010: Disassociation */ ++ authCheckRxAuthFrameTransSeq, /* subtype 1011: Authentication */ ++ saaFsmRunEventRxDeauth, /* subtype 1100: Deauthentication */ ++ nicRxProcessActionFrame, /* subtype 1101: Action */ ++ NULL, /* subtype 1110: reserved */ ++ NULL /* subtype 1111: reserved */ ++}; ++#endif ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Initialize the RFBs ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucMemHandle; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ UINT_32 i; ++ ++ DEBUGFUNC("nicRxInitialize"); ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ /* 4 <0> Clear allocated memory. */ ++ kalMemZero((PVOID) prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize); ++ ++ /* 4 <1> Initialize the RFB lists */ ++ QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList); ++ QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList); ++ QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList); ++ ++ pucMemHandle = prRxCtrl->pucRxCached; ++ for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) { ++ prSwRfb = (P_SW_RFB_T) pucMemHandle; ++ ++ nicRxSetupRFB(prAdapter, prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++ pucMemHandle += ALIGN_4(sizeof(SW_RFB_T)); ++ } ++ ++ ASSERT(prRxCtrl->rFreeSwRfbList.u4NumElem == CFG_RX_MAX_PKT_NUM); ++ /* Check if the memory allocation consist with this initialization function */ ++ ASSERT((ULONG) (pucMemHandle - prRxCtrl->pucRxCached) == prRxCtrl->u4RxCachedSize); ++ ++ /* 4 <2> Clear all RX counters */ ++ RX_RESET_ALL_CNTS(prRxCtrl); ++ ++#if CFG_SDIO_RX_AGG ++ prRxCtrl->pucRxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; ++ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM); ++#else ++ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1); ++#endif ++ ++#if CFG_HIF_STATISTICS ++ prRxCtrl->u4TotalRxAccessNum = 0; ++ prRxCtrl->u4TotalRxPacketNum = 0; ++#endif ++ ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4QueuedCnt = 0; ++ prRxCtrl->u4DequeuedCnt = 0; ++#endif ++ ++} /* end of nicRxInitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Uninitialize the RFBs ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ nicRxFlush(prAdapter); ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ if (prSwRfb) { ++ if (prSwRfb->pvPacket) ++ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); ++ prSwRfb->pvPacket = NULL; ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ if (prSwRfb) { ++ if (prSwRfb->pvPacket) ++ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); ++ prSwRfb->pvPacket = NULL; ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++} /* end of nicRxUninitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Fill RFB ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb specify the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ UINT_32 u4PktLen = 0; ++ UINT_32 u4MacHeaderLen; ++ UINT_32 u4HeaderOffset; ++ ++ DEBUGFUNC("nicRxFillRFB"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ u4PktLen = prHifRxHdr->u2PacketLen; ++ ++ u4HeaderOffset = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); ++ u4MacHeaderLen = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_LEN) ++ >> HIF_RX_HDR_HEADER_LEN_OFFSET; ++ ++ /* DBGLOG(RX, TRACE, ("u4HeaderOffset = %d, u4MacHeaderLen = %d\n", */ ++ /* u4HeaderOffset, u4MacHeaderLen)); */ ++ ++ prSwRfb->u2HeaderLen = (UINT_16) u4MacHeaderLen; ++ prSwRfb->pvHeader = (PUINT_8) prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; ++ prSwRfb->u2PacketLen = (UINT_16) (u4PktLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); ++ ++ /* DBGLOG(RX, TRACE, ("Dump Rx packet, u2PacketLen = %d\n", prSwRfb->u2PacketLen)); */ ++ /* DBGLOG_MEM8(RX, TRACE, prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ ++ ++#if 0 ++ if (prHifRxHdr->ucReorder & HIF_RX_HDR_80211_HEADER_FORMAT) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n"); ++ } ++ ++ if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n"); ++ ++ /* Get Seq. No and TID, Wlan Index info */ ++ if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n"); ++ } ++ ++ prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_SEQ_NO_MASK; ++ prSwRfb->ucTid = (UINT_8) ((prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_TID_MASK) ++ >> HIF_RX_HDR_TID_OFFSET); ++ DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", prSwRfb->u2SSN, prSwRfb->ucTid); ++ } ++ ++ if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) { ++ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS; ++ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n"); ++ } ++#endif ++} ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Fill checksum status in RFB ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* @param u4TcpUdpIpCksStatus specify the Checksum status ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus) ++{ ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED) { ++ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv4) { /* IPv4 packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_IP) { /* IP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_SUCCESS; ++ } ++ ++ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; ++ } ++ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; ++ } ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ } ++ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv6) { /* IPv6 packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS; ++ ++ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; ++ } ++ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; ++ } ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; ++ } ++ } else { ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; ++ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; ++ } ++ } ++ ++} ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process packet doesn't need to do buffer reordering ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_TX_CTRL_T prTxCtrl; ++ BOOLEAN fgIsRetained = FALSE; ++ UINT_32 u4CurrentRxBufferCount; ++ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; ++ ++ DEBUGFUNC("nicRxProcessPktWithoutReorder"); ++ /* DBGLOG(RX, TRACE, ("\n")); */ ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem; ++ /* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C ++ * TOTAL = $A + $B + $C ++ * ++ * Case #1 (Retain) ++ * ------------------------------------------------------- ++ * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C := $TOTAL - THRESHOLD < $C ++ * => $C used too much, retain ++ * ++ * Case #2 (Non-Retain) ++ * ------------------------------------------------------- ++ * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C := $TOTAL - THRESHOLD > $C ++ * => still available for $C to use ++ * ++ */ ++ fgIsRetained = (((u4CurrentRxBufferCount + ++ qmGetRxReorderQueuedBufferCount(prAdapter) + ++ prTxCtrl->i4PendingFwdFrameCount) < CFG_RX_RETAINED_PKT_THRESHOLD) ? TRUE : FALSE); ++ ++ /* DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained)); */ ++ ++ if (kalProcessRxPacket(prAdapter->prGlueInfo, ++ prSwRfb->pvPacket, ++ prSwRfb->pvHeader, ++ (UINT_32) prSwRfb->u2PacketLen, fgIsRetained, prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(RX, ERROR, "kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n"); ++ ASSERT(0); ++ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ return; ++ } ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ++ if (prStaRec) { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX && prAdapter->fgIsP2PRegistered == TRUE) ++ GLUE_SET_PKT_FLAG_P2P(prSwRfb->pvPacket); ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) ++ GLUE_SET_PKT_FLAG_PAL(prSwRfb->pvPacket); ++#endif ++ ++ /* record the count to pass to os */ ++ STATS_RX_PASS2OS_INC(prStaRec, prSwRfb); ++ } ++ prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = prSwRfb->pvPacket; ++ prRxCtrl->ucNumIndPacket++; ++ ++ if (fgIsRetained) { ++ prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = prSwRfb->pvPacket; ++ prRxCtrl->ucNumRetainedPacket++; ++ /* TODO : error handling of nicRxSetupRFB */ ++ nicRxSetupRFB(prAdapter, prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ } else { ++ prSwRfb->pvPacket = NULL; ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process forwarding data packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_MSDU_INFO_T prMsduInfo, prRetMsduInfoList; ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxProcessForwardPkt"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ if (prMsduInfo && kalProcessRxPacket(prAdapter->prGlueInfo, ++ prSwRfb->pvPacket, ++ prSwRfb->pvHeader, ++ (UINT_32) prSwRfb->u2PacketLen, ++ prRxCtrl->rFreeSwRfbList.u4NumElem < ++ CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE, ++ prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) { ++ ++ prMsduInfo->eSrc = TX_PACKET_FORWARDING; ++ /* pack into MSDU_INFO_T */ ++ nicTxFillMsduInfo(prAdapter, prMsduInfo, (P_NATIVE_PACKET) (prSwRfb->pvPacket)); ++ /* Overwrite the ucNetworkType */ ++ prMsduInfo->ucNetworkType = HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr); ++ ++ /* release RX buffer (to rIndicatedRfbList) */ ++ prSwRfb->pvPacket = NULL; ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++ /* increase forward frame counter */ ++ GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); ++ ++ /* send into TX queue */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ if (prRetMsduInfoList != NULL) { /* TX queue refuses queuing the packet */ ++ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList); ++ nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList); ++ } ++ /* indicate service thread for sending */ ++ if (prTxCtrl->i4PendingFwdFrameCount > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ } else /* no TX resource */ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process broadcast data packet for both host and forwarding ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_SW_RFB_T prSwRfbDuplicated; ++ P_TX_CTRL_T prTxCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxProcessGOBroadcastPkt"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16); ++ ++ if (prRxCtrl->rFreeSwRfbList.u4NumElem ++ >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - 16 /* Reserved for others */))) { ++ ++ /* 1. Duplicate SW_RFB_T */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfbDuplicated, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (prSwRfbDuplicated) { ++ kalMemCopy(prSwRfbDuplicated->pucRecvBuff, ++ prSwRfb->pucRecvBuff, ALIGN_4(prHifRxHdr->u2PacketLen + HIF_RX_HW_APPENDED_LEN)); ++ ++ prSwRfbDuplicated->ucPacketType = HIF_RX_PKT_TYPE_DATA; ++ prSwRfbDuplicated->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ nicRxFillRFB(prAdapter, prSwRfbDuplicated); ++ ++ /* 2. Modify eDst */ ++ prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD; ++ ++ /* 4. Forward */ ++ nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated); ++ } ++ } else { ++ DBGLOG(RX, WARN, "Stop to forward BMC packet due to less free Sw Rfb %u\n", ++ prRxCtrl->rFreeSwRfbList.u4NumElem); ++ } ++ ++ /* 3. Indicate to host */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_HOST; ++ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process HIF data packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prRetSwRfb, prNextSwRfb; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_STA_RECORD_T prStaRec; ++ BOOLEAN fIsDummy = FALSE; ++ ++ DEBUGFUNC("nicRxProcessDataPacket"); ++ /* DBGLOG(RX, TRACE, ("\n")); */ ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ++ fIsDummy = (prHifRxHdr->u2PacketLen >= 12) ? FALSE : TRUE; ++ ++ nicRxFillRFB(prAdapter, prSwRfb); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++ { ++ UINT_32 u4TcpUdpIpCksStatus; ++ ++ u4TcpUdpIpCksStatus = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); ++ nicRxFillChksumStatus(prAdapter, prSwRfb, u4TcpUdpIpCksStatus); ++ ++ } ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prHifRxHdr->ucStaRecIdx); ++ if (secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE && prAdapter->fgTestMode == FALSE) { ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4QueuedCnt++; ++#endif ++ prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb); ++ if (prRetSwRfb != NULL) { ++ do { ++ /* save next first */ ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prRetSwRfb); ++ if (fIsDummy == TRUE) { ++ nicRxReturnRFB(prAdapter, prRetSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ DBGLOG(RX, WARN, "Drop Dummy Packets"); ++ ++ } else { ++ switch (prRetSwRfb->eDst) { ++ case RX_PKT_DESTINATION_HOST: ++#if ARP_MONITER_ENABLE ++ if (IS_STA_IN_AIS(prStaRec)) ++ qmHandleRxArpPackets(prAdapter, prRetSwRfb); ++#endif ++ nicRxProcessPktWithoutReorder(prAdapter, prRetSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_FORWARD: ++ nicRxProcessForwardPkt(prAdapter, prRetSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: ++ nicRxProcessGOBroadcastPkt(prAdapter, prRetSwRfb); ++ break; ++ ++ case RX_PKT_DESTINATION_NULL: ++ nicRxReturnRFB(prAdapter, prRetSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ break; ++ ++ default: ++ break; ++ } ++ } ++#if CFG_HIF_RX_STARVATION_WARNING ++ prRxCtrl->u4DequeuedCnt++; ++#endif ++ prRetSwRfb = prNextSwRfb; ++ } while (prRetSwRfb); ++ } ++ } else { ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process HIF event packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++UINT_8 nicRxProcessGSCNEvent(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_WIFI_EVENT_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ struct sk_buff *skb; ++ struct wiphy *wiphy; ++ ++ UINT_32 real_num = 0; ++ ++ P_EVENT_GSCAN_SCAN_AVAILABLE_T prEventGscnAvailable; ++ P_EVENT_GSCAN_RESULT_T prEventBuffer; ++ P_WIFI_GSCAN_RESULT_T prEventGscnResult; ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_32 scan_id; ++ UINT_8 scan_flag; ++ P_EVENT_GSCAN_CAPABILITY_T prEventGscnCapbiblity; ++ P_EVENT_GSCAN_SCAN_COMPLETE_T prEventGscnScnDone; ++ P_WIFI_GSCAN_RESULT_T prEventGscnFullResult; ++ P_PARAM_WIFI_GSCAN_RESULT prParamGscnFullResult; ++ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnSignificantChange; ++ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnGeofenceFound; ++ ++ P_PARAM_WIFI_GSCAN_RESULT prResults; ++ ++ DEBUGFUNC("nicRxProcessGSCNEvent"); ++ /* DBGLOG(RX, TRACE, ("\n")); */ ++ ++ DBGLOG(SCN, INFO, "nicRxProcessGSCNEvent\n"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* Push the data to the skb */ ++ wiphy = priv_to_wiphy(prGlueInfo); ++ ++ /* prGlueInfo-> */ ++ ++ /* Event Handling */ ++ switch (prEvent->ucEID) { ++ case EVENT_ID_GSCAN_SCAN_AVAILABLE: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n"); ++ ++ prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T)); ++ ++ mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, ++ prEventGscnAvailable->u2Num); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_RESULT: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_RESULT 2\n"); ++ ++ prEventBuffer = (P_EVENT_GSCAN_RESULT_T) (prEvent->aucBuffer); ++ prEventGscnResult = prEventBuffer->rResult; ++/* ++ the following event struct should moved to kal and use the kal api to avoid future porting effort ++ ++*/ ++ scan_id = prEventBuffer->u2ScanId; ++ scan_flag = prEventBuffer->u2ScanFlags; ++ real_num = prEventBuffer->u2NumOfResults; ++ ++ DBGLOG(SCN, INFO, "scan_id=%d, scan_flag =%d, real_num=%d\r\n", scan_id, scan_flag, real_num); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num); ++ if (!skb) { ++ DBGLOG(RX, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ attr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); ++ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_SCAN_ID, scan_id);*/ ++ { ++ unsigned int __tmp = scan_id; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_ID, sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, 1);*/ ++ { ++ unsigned char __tmp = 1; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, sizeof(u8), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, real_num);*/ ++ { ++ unsigned int __tmp = real_num; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ prResults = (P_PARAM_WIFI_GSCAN_RESULT) prEventGscnResult; ++ if (prResults) ++ DBGLOG(SCN, INFO, "ssid=%s, rssi=%d, channel=%d \r\n", ++ prResults->ssid, prResults->rssi, prResults->channel); ++ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num, ++ prResults);*/ ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, ++ sizeof(PARAM_WIFI_GSCAN_RESULT)*real_num, prResults) < 0)) ++ goto nla_put_failure; ++ ++ DBGLOG(SCN, INFO, "NLA_PUT scan results over\t"); ++ ++ if (attr) ++ nla_nest_end(skb, attr); ++ /* report_events=1 */ ++ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, 1);*/ ++ { ++ unsigned char __tmp = 1; ++ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ skb = NULL; ++ DBGLOG(SCN, INFO, " i4Status %d\n", i4Status); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_CAPABILITY: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_CAPABILITY\n"); ++ ++ prEventGscnCapbiblity = (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnCapbiblity, (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_CAPABILITY_T)); ++ ++ mtk_cfg80211_vendor_get_gscan_capabilities(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, ++ prEventGscnCapbiblity, sizeof(EVENT_GSCAN_CAPABILITY_T)); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_SCAN_COMPLETE: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n"); ++ prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SCAN_COMPLETE_T)); ++ ++ mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, ++ prEventGscnScnDone->ucScanState); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_FULL_RESULT: ++ { ++ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_FULL_RESULT\n"); ++ ++ prEventGscnFullResult = kalMemAlloc(sizeof(WIFI_GSCAN_RESULT_T), VIR_MEM_TYPE); ++ if (prEventGscnFullResult) ++ memcpy(prEventGscnFullResult, (P_WIFI_GSCAN_RESULT_T) (prEvent->aucBuffer), ++ sizeof(WIFI_GSCAN_RESULT_T)); ++ ++ prParamGscnFullResult = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_RESULT), VIR_MEM_TYPE); ++ if (prEventGscnFullResult && prParamGscnFullResult) { ++ kalMemZero(prParamGscnFullResult, sizeof(PARAM_WIFI_GSCAN_RESULT)); ++ memcpy(prParamGscnFullResult, prEventGscnFullResult, sizeof(WIFI_GSCAN_RESULT_T)); ++ ++ mtk_cfg80211_vendor_event_full_scan_results(wiphy, ++ prGlueInfo->prDevHandler->ieee80211_ptr, ++ prParamGscnFullResult, ++ sizeof(PARAM_WIFI_GSCAN_RESULT)); ++ } ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: ++ { ++ prEventGscnSignificantChange = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnSignificantChange, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); ++ } ++ break; ++ ++ case EVENT_ID_GSCAN_GEOFENCE_FOUND: ++ { ++ prEventGscnGeofenceFound = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); ++ memcpy(prEventGscnGeofenceFound, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), ++ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); ++ } ++ break; ++ ++ default: ++ DBGLOG(SCN, INFO, "not GSCN event ????\n"); ++ break; ++ } ++ ++ DBGLOG(SCN, INFO, "Done with GSCN event handling\n"); ++ return real_num; /* cfg80211_vendor_cmd_reply(skb); */ ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ DBGLOG(SCN, INFO, "nla_put_failure\n"); ++ return 0; /* cfg80211_vendor_cmd_reply(skb); */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process HIF event packet ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_CMD_INFO_T prCmdInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ P_WIFI_EVENT_T prEvent; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DEBUGFUNC("nicRxProcessEventPacket"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; ++ prGlueInfo = prAdapter->prGlueInfo; ++ ++ DBGLOG(RX, EVENT, "prEvent->ucEID = 0x%02x\n", prEvent->ucEID); ++ /* Event Handling */ ++ switch (prEvent->ucEID) { ++ case EVENT_ID_CMD_RESULT: ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ P_EVENT_CMD_RESULT prCmdResult; ++ ++ prCmdResult = (P_EVENT_CMD_RESULT) ((PUINT_8) prEvent + EVENT_HDR_SIZE); ++ ++ /* CMD_RESULT should be only in response to Set commands */ ++ ASSERT(prCmdInfo->fgSetQuery == FALSE || prCmdInfo->fgNeedResp == TRUE); ++ ++ if (prCmdResult->ucStatus == 0) { /* success */ ++ if (prCmdInfo->pfCmdDoneHandler) { ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ } else if (prCmdInfo->fgIsOid == TRUE) { ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, ++ WLAN_STATUS_SUCCESS); ++ } ++ } else if (prCmdResult->ucStatus == 1) { /* reject */ ++ if (prCmdInfo->fgIsOid == TRUE) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, ++ WLAN_STATUS_FAILURE); ++ } else if (prCmdResult->ucStatus == 2) { /* unknown CMD */ ++ if (prCmdInfo->fgIsOid == TRUE) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, ++ WLAN_STATUS_NOT_SUPPORTED); ++ } ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ ++#if 0 ++ case EVENT_ID_CONNECTION_STATUS: ++ /* OBSELETE */ ++ { ++ P_EVENT_CONNECTION_STATUS prConnectionStatus; ++ ++ prConnectionStatus = (P_EVENT_CONNECTION_STATUS) (prEvent->aucBuffer); ++ ++ DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", prConnectionStatus->ucMediaStatus); ++ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { ++ /* disconnected */ ++ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { ++ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); ++ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ } ++ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { ++ /* connected */ ++ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); ++ ++ /* fill information for association result */ ++ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, ++ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); ++ ++ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ prConnectionStatus->aucBssid, MAC_ADDR_LEN); ++ ++ /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.u4Privacy = prConnectionStatus->ucEncryptStatus; ++ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ ++ /* @FIXME */ ++ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse = PARAM_NETWORK_TYPE_AUTOMODE; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod ++ = prConnectionStatus->u2BeaconPeriod; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow ++ = prConnectionStatus->u2ATIMWindow; ++ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig ++ = prConnectionStatus->u4FreqInKHz; ++ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; ++ ++ switch (prConnectionStatus->ucInfraMode) { ++ case 0: ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_IBSS; ++ break; ++ case 1: ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_INFRA; ++ break; ++ case 2: ++ default: ++ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_AUTO_SWITCH; ++ break; ++ } ++ /* always indicate to OS according to MSDN (re-association/roaming) */ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); ++ } ++ } ++ break; ++ ++ case EVENT_ID_SCAN_RESULT: ++ /* OBSELETE */ ++ break; ++#endif ++ ++ case EVENT_ID_RX_ADDBA: ++ /* The FW indicates that an RX BA agreement will be established */ ++ qmHandleEventRxAddBa(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_RX_DELBA: ++ /* The FW indicates that an RX BA agreement has been deleted */ ++ qmHandleEventRxDelBa(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_LINK_QUALITY: ++#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY ++ if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof(EVENT_LINK_QUALITY_EX)) { ++ P_EVENT_LINK_QUALITY_EX prLqEx = (P_EVENT_LINK_QUALITY_EX) (prEvent->aucBuffer); ++ ++ if (prLqEx->ucIsLQ0Rdy) ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); ++ if (prLqEx->ucIsLQ1Rdy) ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_P2P_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); ++ } else { ++ /* For old FW, P2P may invoke link quality query, and make driver flag becone TRUE. */ ++ DBGLOG(P2P, WARN, "Old FW version, not support P2P RSSI query.\n"); ++ ++ /* Must not use NETWORK_TYPE_P2P_INDEX, cause the structure is mismatch. */ ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, ++ (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); ++ } ++#else ++ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); ++#endif ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++#ifndef LINUX ++ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_GREATER && ++ prAdapter->rWlanInfo.rRssiTriggerValue >= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; ++ ++ kalIndicateStatusAndComplete(prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), ++ sizeof(PARAM_RSSI)); ++ } else if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_LESS ++ && prAdapter->rWlanInfo.rRssiTriggerValue <= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { ++ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; ++ ++ kalIndicateStatusAndComplete(prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), ++ sizeof(PARAM_RSSI)); ++ } ++#endif ++ ++ break; ++ ++ case EVENT_ID_MIC_ERR_INFO: ++ { ++ P_EVENT_MIC_ERR_INFO prMicError; ++ /* P_PARAM_AUTH_EVENT_T prAuthEvent; */ ++ P_STA_RECORD_T prStaRec; ++ ++ DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n"); ++ ++ prMicError = (P_EVENT_MIC_ERR_INFO) (prEvent->aucBuffer); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ (UINT_8) NETWORK_TYPE_AIS_INDEX, ++ prAdapter->rWlanInfo.rCurrBssId.arMacAddress); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) ++ rsnTkipHandleMICFailure(prAdapter, prStaRec, (BOOLEAN) prMicError->u4Flags); ++ else ++ DBGLOG(RSN, WARN, "No STA rec!!\n"); ++#if 0 ++ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; ++ ++ /* Status type: Authentication Event */ ++ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; ++ ++ /* Authentication request */ ++ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); ++ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, ++ (PVOID) prAdapter->rWlanInfo.rCurrBssId.arMacAddress, ++ /* whsu:Todo? */PARAM_MAC_ADDR_LEN); ++ ++ if (prMicError->u4Flags != 0) ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; ++ else ++ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAuthEvent, ++ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); ++#endif ++ } ++ break; ++ ++ case EVENT_ID_ASSOC_INFO: ++ { ++ P_EVENT_ASSOC_INFO prAssocInfo; ++ ++ prAssocInfo = (P_EVENT_ASSOC_INFO) (prEvent->aucBuffer); ++ ++ kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo); ++ } ++ break; ++ ++ case EVENT_ID_802_11_PMKID: ++ { ++ P_PARAM_AUTH_EVENT_T prAuthEvent; ++ PUINT_8 cp; ++ UINT_32 u4LenOfUsedBuffer; ++ ++ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; ++ ++ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; ++ ++ u4LenOfUsedBuffer = (UINT_32) (prEvent->u2PacketLen - 8); ++ ++ prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer; ++ ++ cp = (PUINT_8) &prAuthEvent->arRequest[0]; ++ ++ /* Status type: PMKID Candidatelist Event */ ++ kalMemCopy(cp, (P_EVENT_PMKID_CANDIDATE_LIST_T) (prEvent->aucBuffer), prEvent->u2PacketLen - 8); ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, ++ (PVOID) prAuthEvent, ++ sizeof(PARAM_STATUS_INDICATION_T) + u4LenOfUsedBuffer); ++ } ++ break; ++ ++#if 0 ++ case EVENT_ID_ACTIVATE_STA_REC_T: ++ { ++ P_EVENT_ACTIVATE_STA_REC_T prActivateStaRec; ++ ++ prActivateStaRec = (P_EVENT_ACTIVATE_STA_REC_T) (prEvent->aucBuffer); ++ ++ DbgPrint("RX EVENT: EVENT_ID_ACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", ++ prActivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); ++ ++ qmActivateStaRec(prAdapter, ++ (UINT_32) prActivateStaRec->ucStaRecIdx, ++ ((prActivateStaRec->fgIsQoS) ? TRUE : FALSE), ++ prActivateStaRec->ucNetworkTypeIndex, ++ ((prActivateStaRec->fgIsAP) ? TRUE : FALSE), prActivateStaRec->aucMacAddr); ++ ++ } ++ break; ++ ++ case EVENT_ID_DEACTIVATE_STA_REC_T: ++ { ++ P_EVENT_DEACTIVATE_STA_REC_T prDeactivateStaRec; ++ ++ prDeactivateStaRec = (P_EVENT_DEACTIVATE_STA_REC_T) (prEvent->aucBuffer); ++ ++ DbgPrint("RX EVENT: EVENT_ID_DEACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", ++ prDeactivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); ++ ++ qmDeactivateStaRec(prAdapter, prDeactivateStaRec->ucStaRecIdx); ++ } ++ break; ++#endif ++ ++ case EVENT_ID_SCAN_DONE: ++ scnEventScanDone(prAdapter, (P_EVENT_SCAN_DONE) (prEvent->aucBuffer)); ++ break; ++ ++ case EVENT_ID_TX_DONE_STATUS: ++ STATS_TX_PKT_DONE_INFO_DISPLAY(prAdapter, prEvent->aucBuffer); ++ break; ++ ++ case EVENT_ID_TX_DONE: ++ { ++ P_EVENT_TX_DONE_T prTxDone; ++ ++ prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer); ++ if (prTxDone->ucStatus) ++ DBGLOG(RX, INFO, "EVENT_ID_TX_DONE PacketSeq:%u ucStatus: %u SN: %u\n", ++ prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber); ++ ++ /* call related TX Done Handler */ ++ prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucPacketSeq); ++ ++#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT ++ DBGLOG(RX, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n", ++ prTxDone->au4Reserved1, prTxDone->au4Reserved2); ++ ++ wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex, ++ prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2); ++#endif ++ ++ if (prMsduInfo) { ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, ++ (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus)); ++ ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } ++ } ++ break; ++ case EVENT_ID_SLEEPY_NOTIFY: ++ { ++ P_EVENT_SLEEPY_NOTIFY prEventSleepyNotify; ++ ++ prEventSleepyNotify = (P_EVENT_SLEEPY_NOTIFY) (prEvent->aucBuffer); ++ ++ /* DBGLOG(RX, INFO, ("ucSleepyState = %d\n", prEventSleepyNotify->ucSleepyState)); */ ++ ++ prAdapter->fgWiFiInSleepyState = (BOOLEAN) (prEventSleepyNotify->ucSleepyState); ++ } ++ break; ++ case EVENT_ID_BT_OVER_WIFI: ++#if CFG_ENABLE_BT_OVER_WIFI ++ { ++ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; ++ P_EVENT_BT_OVER_WIFI prEventBtOverWifi; ++ P_AMPC_EVENT prBowEvent; ++ P_BOW_LINK_CONNECTED prBowLinkConnected; ++ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; ++ ++ prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); ++ ++ /* construct event header */ ++ prBowEvent = (P_AMPC_EVENT) aucTmp; ++ ++ if (prEventBtOverWifi->ucLinkStatus == 0) { ++ /* Connection */ ++ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; ++ prBowEvent->rHeader.ucSeqNumber = 0; ++ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); ++ ++ /* fill event body */ ++ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prBowEvent->aucPayload); ++ prBowLinkConnected->rChannel.ucChannelNum = prEventBtOverWifi->ucSelectedChannel; ++ kalMemZero(prBowLinkConnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); ++ } else { ++ /* Disconnection */ ++ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; ++ prBowEvent->rHeader.ucSeqNumber = 0; ++ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); ++ ++ /* fill event body */ ++ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prBowEvent->aucPayload); ++ prBowLinkDisconnected->ucReason = 0; /* @FIXME */ ++ kalMemZero(prBowLinkDisconnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ ++ ++ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); ++ } ++ } ++ break; ++#endif ++ case EVENT_ID_STATISTICS: ++ /* buffer statistics for further query */ ++ prAdapter->fgIsStatValid = TRUE; ++ prAdapter->rStatUpdateTime = kalGetTimeTick(); ++ kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, sizeof(EVENT_STATISTICS)); ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ ++ case EVENT_ID_CH_PRIVILEGE: ++ cnmChMngrHandleChEvent(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_BSS_ABSENCE_PRESENCE: ++ qmHandleEventBssAbsencePresence(prAdapter, prEvent); ++ break; ++ ++ case EVENT_ID_STA_CHANGE_PS_MODE: ++ qmHandleEventStaChangePsMode(prAdapter, prEvent); ++ break; ++#if CFG_ENABLE_WIFI_DIRECT ++ case EVENT_ID_STA_UPDATE_FREE_QUOTA: ++ qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent); ++ break; ++#endif ++ case EVENT_ID_BSS_BEACON_TIMEOUT: ++ if (prAdapter->fgDisBcnLostDetection == FALSE) { ++ P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout; ++ ++ prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T) (prEvent->aucBuffer); ++ ++ DBGLOG(RX, INFO, "Beacon Timeout Reason = %u\n", prEventBssBeaconTimeout->ucReason); ++ ++ if (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { ++ /* Request stats report before beacon timeout */ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (prBssInfo) { ++ prStaRec = cnmGetStaRecByAddress(prAdapter, ++ NETWORK_TYPE_AIS_INDEX, ++ prBssInfo->aucBSSID); ++ if (prStaRec) ++ STATS_ENV_REPORT_DETECT(prAdapter, prStaRec->ucIndex); ++ } ++ aisBssBeaconTimeout(prAdapter); ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ else if ((prAdapter->fgIsP2PRegistered) && ++ (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) ++ ++ p2pFsmRunEventBeaconTimeout(prAdapter); ++#endif ++ else { ++ DBGLOG(RX, ERROR, "EVENT_ID_BSS_BEACON_TIMEOUT: (ucNetTypeIdx = %d)\n", ++ prEventBssBeaconTimeout->ucNetTypeIndex); ++ } ++ } ++ ++ break; ++ case EVENT_ID_UPDATE_NOA_PARAMS: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) { ++ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam; ++ ++ prEventUpdateNoaParam = (P_EVENT_UPDATE_NOA_PARAMS_T) (prEvent->aucBuffer); ++ ++ if (prEventUpdateNoaParam->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { ++ p2pProcessEvent_UpdateNOAParam(prAdapter, ++ prEventUpdateNoaParam->ucNetTypeIndex, ++ prEventUpdateNoaParam); ++ } else { ++ ASSERT(0); ++ } ++ } ++#else ++ ASSERT(0); ++#endif ++ break; ++ ++ case EVENT_ID_STA_AGING_TIMEOUT: ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) { ++ P_EVENT_STA_AGING_TIMEOUT_T prEventStaAgingTimeout; ++ P_STA_RECORD_T prStaRec; ++ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; ++ ++ prEventStaAgingTimeout = (P_EVENT_STA_AGING_TIMEOUT_T) (prEvent->aucBuffer); ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventStaAgingTimeout->ucStaRecIdx); ++ if (prStaRec == NULL) ++ break; ++ ++ DBGLOG(RX, INFO, "EVENT_ID_STA_AGING_TIMEOUT %u %pM\n", ++ prEventStaAgingTimeout->ucStaRecIdx, ++ prStaRec->aucMacAddr); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); ++ ++ /* Call False Auth */ ++ if (prAdapter->fgIsP2PRegistered) ++ p2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY); ++ ++ } ++ /* gDisStaAgingTimeoutDetection */ ++ } ++#endif ++ break; ++ ++ case EVENT_ID_AP_OBSS_STATUS: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ rlmHandleObssStatusEventPkt(prAdapter, (P_EVENT_AP_OBSS_STATUS_T) prEvent->aucBuffer); ++#endif ++ break; ++ ++ case EVENT_ID_ROAMING_STATUS: ++#if CFG_SUPPORT_ROAMING ++ { ++ P_ROAMING_PARAM_T prParam; ++ ++ prParam = (P_ROAMING_PARAM_T) (prEvent->aucBuffer); ++ roamingFsmProcessEvent(prAdapter, prParam); ++ } ++#endif /* CFG_SUPPORT_ROAMING */ ++ break; ++ case EVENT_ID_SEND_DEAUTH: ++ { ++ P_WLAN_MAC_HEADER_T prWlanMacHeader; ++ P_STA_RECORD_T prStaRec; ++ ++ prWlanMacHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; ++ DBGLOG(RSN, INFO, "nicRx: aucAddr1: %pM, nicRx: aucAddr2: %pM\n", ++ prWlanMacHeader->aucAddr1, prWlanMacHeader->aucAddr2); ++ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanMacHeader->aucAddr2); ++ if (prStaRec != NULL && prStaRec->ucStaState == STA_STATE_3) { ++ DBGLOG(RSN, WARN, "Ignore Deauth for Rx Class 3 error!\n"); ++ } else { ++ /* receive packets without StaRec */ ++ prSwRfb->pvHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; ++ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, ++ NULL, ++ prSwRfb, ++ REASON_CODE_CLASS_3_ERR, ++ (PFN_TX_DONE_HANDLER) NULL)) ++ DBGLOG(RSN, INFO, "Send Deauth for Rx Class3 Error\n"); ++ else ++ DBGLOG(RSN, WARN, "failed to send deauth for Rx class3 error\n"); ++ } ++ } ++ break; ++ ++#if CFG_SUPPORT_RDD_TEST_MODE ++ case EVENT_ID_UPDATE_RDD_STATUS: ++ { ++ P_EVENT_RDD_STATUS_T prEventRddStatus; ++ ++ prEventRddStatus = (P_EVENT_RDD_STATUS_T) (prEvent->aucBuffer); ++ ++ prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus; ++ } ++ ++ break; ++#endif ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ case EVENT_ID_UPDATE_BWCS_STATUS: ++ { ++ P_PTA_IPC_T prEventBwcsStatus; ++ ++ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); ++ ++#if CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(RSN, INFO, ++ "BCM BWCS Event: %02x%02x%02x%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); ++ ++ DBGLOG(RSN, INFO, ++ "BCM BWCS Event: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); ++#endif ++ ++ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, ++ WLAN_STATUS_BWCS_UPDATE, ++ (PVOID) prEventBwcsStatus, sizeof(PTA_IPC_T)); ++ } ++ ++ break; ++ ++ case EVENT_ID_UPDATE_BCM_DEBUG: ++ { ++ P_PTA_IPC_T prEventBwcsStatus; ++ ++ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); ++ ++#if CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(RSN, INFO, ++ "BCM FW status: %02x%02x%02x%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); ++ ++ DBGLOG(RSN, INFO, ++ "BCM FW status: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", ++ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], ++ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]; ++#endif ++ } ++ ++ break; ++#endif ++ ++ case EVENT_ID_DEBUG_CODE: /* only for debug */ ++ { ++ UINT_32 u4CodeId; ++ ++ DBGLOG(RSN, INFO, "[wlan-fw] function sequence: "); ++ for (u4CodeId = 0; u4CodeId < 1000; u4CodeId++) ++ DBGLOG(RSN, INFO, "%d ", prEvent->aucBuffer[u4CodeId]); ++ DBGLOG(RSN, INFO, "\n\n"); ++ } ++ break; ++ ++ case EVENT_ID_RFTEST_READY: ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ ++ case EVENT_ID_GSCAN_SCAN_AVAILABLE: ++ case EVENT_ID_GSCAN_CAPABILITY: ++ case EVENT_ID_GSCAN_SCAN_COMPLETE: ++ case EVENT_ID_GSCAN_FULL_RESULT: ++ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: ++ case EVENT_ID_GSCAN_GEOFENCE_FOUND: ++ nicRxProcessGSCNEvent(prAdapter, prSwRfb); ++ break; ++ ++ case EVENT_ID_GSCAN_RESULT: ++ { ++ ++ UINT_8 realnum = 0; ++ ++ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent ----->\n"); ++ realnum = nicRxProcessGSCNEvent(prAdapter, prSwRfb); ++ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent <-----\n"); ++ ++#if 0 /* workaround for FW events cnt mis-match with the actual reqirements from wifi_hal */ ++ if (g_GetResultsCmdCnt == 0) { ++ DBGLOG(SCN, INFO, ++ "FW report events more than the wifi_hal asked number, buffer the results\n"); ++ UINT_8 i = 0; ++ ++ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { ++#if 1 ++ if (!g_arGscanResultsIndicateNumber[i]) { ++ DBGLOG(SCN, INFO, ++ "found available index %d to insert results number %d into buffer\r\n", ++ i, realnum); ++ ++ g_arGscnResultsTempBuffer[i] = prSwRfb; ++ g_arGscanResultsIndicateNumber[i] = realnum; ++ g_GetResultsBufferedCnt++; ++ fgKeepprSwRfb = TRUE; ++ DBGLOG(SCN, INFO, "results buffered in index[%d] \r\n", i); ++ break; ++ } ++#endif ++ } ++ if (i == MAX_BUFFERED_GSCN_RESULTS) ++ DBGLOG(SCN, INFO, ++ "Gscn results buffer is full(all valid), no space to buffer result\r\n"); ++ } else if (g_GetResultsCmdCnt > 0) { ++ DBGLOG(SCN, INFO, "FW report events match the wifi_hal asked number\n"); ++ g_GetResultsCmdCnt--; ++ } else ++ DBGLOG(SCN, INFO, "g_GetResultsCmdCnt < 0 ??? unexpected case\n"); ++#endif ++ /* end of workaround */ ++ ++ } ++ break; ++ ++ case EVENT_ID_NLO_DONE: ++ prAdapter->rWifiVar.rScanInfo.fgPscnOnnning = FALSE; ++ ++ DBGLOG(INIT, INFO, "EVENT_ID_NLO_DONE\n"); ++ scnEventNloDone(prAdapter, (P_EVENT_NLO_DONE_T) (prEvent->aucBuffer)); ++ ++ break; ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ case EVENT_ID_BATCH_RESULT: ++ DBGLOG(SCN, TRACE, "Got EVENT_ID_BATCH_RESULT"); ++ ++ /* command response handling */ ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++#endif /* CFG_SUPPORT_BATCH_SCAN */ ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ case EVENT_ID_TDLS: ++ TdlsexEventHandle(prAdapter->prGlueInfo, ++ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); ++ break; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#if (CFG_SUPPORT_STATISTICS == 1) ++ case EVENT_ID_STATS_ENV: ++ statsEventHandle(prAdapter->prGlueInfo, ++ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); ++ break; ++#endif /* CFG_SUPPORT_STATISTICS */ ++ ++ case EVENT_ID_FW_LOG_ENV: ++ { ++ P_EVENT_FW_LOG_T prEventLog; ++ ++ prEventLog = (P_EVENT_FW_LOG_T) (prEvent->aucBuffer); ++ DBGLOG(RX, INFO, "[F-L]%s\n", prEventLog->log); ++ } ++ break; ++ ++ default: ++ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); ++ ++ if (prCmdInfo != NULL) { ++ if (prCmdInfo->pfCmdDoneHandler) ++ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); ++ else if (prCmdInfo->fgIsOid) ++ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); ++ /* return prCmdInfo */ ++ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); ++ } ++ ++ break; ++ } ++ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief nicRxProcessMgmtPacket is used to dispatch management frames ++* to corresponding modules ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prSWRfb the RFB to receive rx data ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ UINT_8 ucSubtype; ++#if CFG_SUPPORT_802_11W ++ BOOLEAN fgMfgDrop = FALSE; ++#endif ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ nicRxFillRFB(prAdapter, prSwRfb); ++ ++ ucSubtype = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; ++ ++#if 0 /* CFG_RX_PKTS_DUMP */ ++ { ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_16 u2TxFrameCtrl; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ u2TxFrameCtrl = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FRAME_TYPE); ++ /* if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_MANAGEMENT)) { */ ++ /* if (u2TxFrameCtrl == MAC_FRAME_BEACON || */ ++ /* u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { */ ++ ++ DBGLOG(RX, INFO, "QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n", ++ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), prHifRxHdr->ucStaRecIdx, ++ prSwRfb->ucWlanIdx, (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr),/* The new SN of the frame */ ++ prSwRfb->ucPacketType, ucSubtype, HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); ++ ++ /* DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ ++ /* } */ ++ /* } */ ++ } ++#endif ++ ++ if ((prAdapter->fgTestMode == FALSE) && (prAdapter->prGlueInfo->fgIsRegistered == TRUE)) { ++#if CFG_MGMT_FRAME_HANDLING ++#if CFG_SUPPORT_802_11W ++ fgMfgDrop = rsnCheckRxMgmt(prAdapter, prSwRfb, ucSubtype); ++ if (fgMfgDrop) { ++#if DBG ++ LOG_FUNC("QM RX MGT: Drop Unprotected Mgmt frame!!!\n"); ++#endif ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ return; ++ } ++#endif ++ if (apfnProcessRxMgtFrame[ucSubtype]) { ++ switch (apfnProcessRxMgtFrame[ucSubtype] (prAdapter, prSwRfb)) { ++ case WLAN_STATUS_PENDING: ++ return; ++ case WLAN_STATUS_SUCCESS: ++ case WLAN_STATUS_FAILURE: ++ break; ++ ++ default: ++ DBGLOG(RX, WARN, ++ "Unexpected MMPDU(0x%02X) returned with abnormal status\n", ucSubtype); ++ break; ++ } ++ } ++#endif ++ } ++ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++} ++ ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++static VOID nicRxCheckWakeupReason(P_SW_RFB_T prSwRfb) ++{ ++ PUINT_8 pvHeader = NULL; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_16 u2PktLen = 0; ++ UINT_32 u4HeaderOffset; ++ ++ if (!prSwRfb) ++ return; ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ if (!prHifRxHdr) ++ return; ++ ++ switch (prSwRfb->ucPacketType) { ++ case HIF_RX_PKT_TYPE_DATA: ++ { ++ UINT_16 u2Temp = 0; ++ ++ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { ++ DBGLOG(RX, INFO, "BAR frame[SSN:%d, TID:%d] wakeup host\n", ++ (UINT_16)HIF_RX_HDR_GET_SN(prHifRxHdr), (UINT_8)HIF_RX_HDR_GET_TID(prHifRxHdr)); ++ break; ++ } ++ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); ++ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; ++ u2PktLen = (UINT_16)(prHifRxHdr->u2PacketLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); ++ if (!pvHeader) { ++ DBGLOG(RX, ERROR, "data packet but pvHeader is NULL!\n"); ++ break; ++ } ++ u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | (pvHeader[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ switch (u2Temp) { ++ case ETH_P_IPV4: ++ u2Temp = *(UINT_16 *) &pvHeader[ETH_HLEN + 4]; ++ DBGLOG(RX, INFO, "IP Packet from:%d.%d.%d.%d, IP ID 0x%04x wakeup host\n", ++ pvHeader[ETH_HLEN + 12], pvHeader[ETH_HLEN + 13], ++ pvHeader[ETH_HLEN + 14], pvHeader[ETH_HLEN + 15], u2Temp); ++ break; ++ case ETH_P_ARP: ++ { ++ PUINT_8 pucEthBody = &pvHeader[ETH_HLEN]; ++ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; ++ ++ if (u2OpCode == ARP_PRO_REQ) ++ DBGLOG(RX, INFO, "Arp Req From IP: %d.%d.%d.%d wakeup host\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ else if (u2OpCode == ARP_PRO_RSP) ++ DBGLOG(RX, INFO, "Arp Rsp from IP: %d.%d.%d.%d wakeup host\n", ++ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); ++ break; ++ } ++ case ETH_P_1X: ++ case ETH_P_PRE_1X: ++#if CFG_SUPPORT_WAPI ++ case ETH_WPI_1X: ++#endif ++ case ETH_P_AARP: ++ case ETH_P_IPV6: ++ case ETH_P_IPX: ++ case 0x8100: /* VLAN */ ++ case 0x890d: /* TDLS */ ++ DBGLOG(RX, INFO, "Data Packet, EthType 0x%04x wakeup host\n", u2Temp); ++ break; ++ default: ++ DBGLOG(RX, WARN, "maybe abnormal data packet, EthType 0x%04x wakeup host, dump it\n", ++ u2Temp); ++ DBGLOG_MEM8(RX, INFO, pvHeader, u2PktLen > 50 ? 50:u2PacketLen); ++ break; ++ } ++ break; ++ } ++ case HIF_RX_PKT_TYPE_EVENT: ++ { ++ P_WIFI_EVENT_T prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; ++ ++ DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", prEvent->ucEID); ++ break; ++ } ++ case HIF_RX_PKT_TYPE_MANAGEMENT: ++ { ++ UINT_8 ucSubtype; ++ P_WLAN_MAC_MGMT_HEADER_T prWlanMgmtHeader; ++ ++ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); ++ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; ++ if (!pvHeader) { ++ DBGLOG(RX, ERROR, "Mgmt Frame but pvHeader is NULL!\n"); ++ break; ++ } ++ prWlanMgmtHeader = (P_WLAN_MAC_MGMT_HEADER_T)pvHeader; ++ ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> ++ OFFSET_OF_FC_SUBTYPE; ++ DBGLOG(RX, INFO, "MGMT frame subtype: %d SeqCtrl %d wakeup host\n", ++ ucSubtype, prWlanMgmtHeader->u2SeqCtrl); ++ break; ++ } ++ default: ++ DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", prSwRfb->ucPacketType); ++ break; ++ } ++} ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxProcessRFBs"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ prRxCtrl->ucNumIndPacket = 0; ++ prRxCtrl->ucNumRetainedPacket = 0; ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (prSwRfb) { ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++ if (kalIsWakeupByWlan(prAdapter)) ++ nicRxCheckWakeupReason(prSwRfb); ++#endif ++ switch (prSwRfb->ucPacketType) { ++ case HIF_RX_PKT_TYPE_DATA: ++ nicRxProcessDataPacket(prAdapter, prSwRfb); ++ break; ++ ++ case HIF_RX_PKT_TYPE_EVENT: ++ nicRxProcessEventPacket(prAdapter, prSwRfb); ++ break; ++ ++ case HIF_RX_PKT_TYPE_TX_LOOPBACK: ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ { ++ kalDevLoopbkRxHandle(prAdapter, prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ } ++#else ++ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ break; ++ ++ case HIF_RX_PKT_TYPE_MANAGEMENT: ++ nicRxProcessMgmtPacket(prAdapter, prSwRfb); ++ break; ++ ++ default: ++ RX_INC_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT); ++ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); ++ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); ++ nicRxReturnRFB(prAdapter, prSwRfb); /* need to free it */ ++ break; ++ } ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++ if (prRxCtrl->ucNumIndPacket > 0) { ++ RX_ADD_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT, prRxCtrl->ucNumIndPacket); ++ RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, prRxCtrl->ucNumRetainedPacket); ++ ++ /* DBGLOG(RX, INFO, ("%d packets indicated, Retained cnt = %d\n", */ ++ /* prRxCtrl->ucNumIndPacket, prRxCtrl->ucNumRetainedPacket)); */ ++#if CFG_NATIVE_802_11 ++ kalRxIndicatePkts(prAdapter->prGlueInfo, (UINT_32) prRxCtrl->ucNumIndPacket, ++ (UINT_32) prRxCtrl->ucNumRetainedPacket); ++#else ++ kalRxIndicatePkts(prAdapter->prGlueInfo, prRxCtrl->apvIndPacket, (UINT_32) prRxCtrl->ucNumIndPacket); ++#endif ++ } ++ ++} /* end of nicRxProcessRFBs() */ ++ ++#if !CFG_SDIO_INTR_ENHANCE ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read the rx data from data port and setup RFB ++* ++* @param prAdapter pointer to the Adapter handler ++* @param prSWRfb the RFB to receive rx data ++* ++* @retval WLAN_STATUS_SUCCESS: SUCCESS ++* @retval WLAN_STATUS_FAILURE: FAILURE ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucBuf; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_32 u4PktLen = 0, u4ReadBytes; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgResult = TRUE; ++ UINT_32 u4RegValue; ++ UINT_32 rxNum; ++ ++ DEBUGFUNC("nicRxReadBuffer"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ pucBuf = prSwRfb->pucRecvBuff; ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(pucBuf); ++ DBGLOG(RX, TRACE, "pucBuf= 0x%x, prHifRxHdr= 0x%x\n", pucBuf, prHifRxHdr); ++ ++ do { ++ /* Read the RFB DW length and packet length */ ++ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue); ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ /* 20091021 move the line to get the HIF RX header (for RX0/1) */ ++ if (u4RegValue == 0) { ++ DBGLOG(RX, ERROR, "No RX packet\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ u4PktLen = u4RegValue & BITS(0, 15); ++ if (u4PktLen != 0) { ++ rxNum = 0; ++ } else { ++ rxNum = 1; ++ u4PktLen = (u4RegValue & BITS(16, 31)) >> 16; ++ } ++ ++ DBGLOG(RX, TRACE, "RX%d: u4PktLen = %d\n", rxNum, u4PktLen); ++ ++ /* 4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status) */ ++ u4ReadBytes = ALIGN_4(u4PktLen) + 4; ++ HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE); ++ ++ /* 20091021 move the line to get the HIF RX header */ ++ /* u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen; */ ++ if (u4PktLen != (UINT_32) prHifRxHdr->u2PacketLen) { ++ DBGLOG(RX, ERROR, "Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n", ++ u4PktLen, prHifRxHdr->u2PacketLen); ++#if DBG ++ dumpMemory8((PUINT_8) prHifRxHdr, ++ (prHifRxHdr->u2PacketLen > 4096) ? 4096 : prHifRxHdr->u2PacketLen); ++#endif ++ ASSERT(0); ++ } ++ /* u4PktLen is byte unit, not inlude HW appended DW */ ++ ++ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); ++ DBGLOG(RX, TRACE, "ucPacketType = %d\n", prSwRfb->ucPacketType); ++ ++ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ ++ /* fgResult will be updated in MACRO */ ++ if (!fgResult) ++ return WLAN_STATUS_FAILURE; ++ ++ DBGLOG(RX, TRACE, "Dump RX buffer, length = 0x%x\n", u4ReadBytes); ++ DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes); ++ } while (FALSE); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port, fill RFB ++* and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ UINT_32 u4HwAppendDW; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxReceiveRFBs"); ++ ++ ASSERT(prAdapter); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (!prSwRfb) { ++ DBGLOG(RX, TRACE, "No More RFB\n"); ++ break; ++ } ++ /* need to consider */ ++ if (nicRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) { ++ DBGLOG(RX, TRACE, "halRxFillRFB failed\n"); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ break; ++ } ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); ++ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ u4HwAppendDW = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); ++ DBGLOG(RX, TRACE, "u4HwAppendDW = 0x%x\n", u4HwAppendDW); ++ DBGLOG(RX, TRACE, "u2PacketLen = 0x%x\n", prHifRxHdr->u2PacketLen); ++ } while (FALSE); /* while (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW)); */ ++ ++ return; ++ ++} /* end of nicReceiveRFBs() */ ++ ++#else ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port, fill RFB ++* and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param u4DataPort Specify which port to read ++* @param u2RxLength Specify to the the rx packet length in Byte. ++* @param prSwRfb the RFB to receive rx data. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS ++nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, ++ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucBuf; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ UINT_32 u4PktLen = 0; ++ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; ++ BOOLEAN fgResult = TRUE; ++ ++ DEBUGFUNC("nicRxEnhanceReadBuffer"); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ pucBuf = prSwRfb->pucRecvBuff; ++ ASSERT(pucBuf); ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ /* DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength)); */ ++ ++ do { ++ /* 4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW */ ++ HAL_READ_RX_PORT(prAdapter, ++ u4DataPort, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN), pucBuf, CFG_RX_MAX_PKT_SIZE); ++ ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); ++ break; ++ } ++ ++ u4PktLen = (UINT_32) (prHifRxHdr->u2PacketLen); ++ /* DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen)); */ ++ ++ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); ++ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ ++ ++ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ ++ /* 4 <2> if the RFB dw size or packet size is zero */ ++ if (u4PktLen == 0) { ++ DBGLOG(RX, ERROR, "Packet Length = %u\n", u4PktLen); ++ ASSERT(0); ++ break; ++ } ++ /* 4 <3> if the packet is too large or too small */ ++ if (u4PktLen > CFG_RX_MAX_PKT_SIZE) { ++ DBGLOG(RX, TRACE, "Read RX Packet Lentgh Error (%u)\n", u4PktLen); ++ ASSERT(0); ++ break; ++ } ++ ++ u4Status = WLAN_STATUS_SUCCESS; ++ } while (FALSE); ++ ++ DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN)); ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port for SDIO ++* I/F, fill RFB and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_SDIO_CTRL_T prSDIOCtrl; ++ P_RX_CTRL_T prRxCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ UINT_32 i, rxNum; ++ UINT_16 u2RxPktNum, u2RxLength = 0, u2Tmp = 0; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxSDIOReceiveRFBs"); ++ ++ ASSERT(prAdapter); ++ ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++ ASSERT(prSDIOCtrl); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ for (rxNum = 0; rxNum < 2; rxNum++) { ++ u2RxPktNum = ++ (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len); ++ ++ if (u2RxPktNum == 0) ++ continue; ++ ++ for (i = 0; i < u2RxPktNum; i++) { ++ if (rxNum == 0) { ++ /* HAL_READ_RX_LENGTH */ ++ HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp); ++ } else if (rxNum == 1) { ++ /* HAL_READ_RX_LENGTH */ ++ HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength); ++ } ++ ++ if (!u2RxLength) ++ break; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (!prSwRfb) { ++ DBGLOG(RX, TRACE, "No More RFB\n"); ++ break; ++ } ++ ASSERT(prSwRfb); ++ ++ if (nicRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) { ++ DBGLOG(RX, TRACE, "nicRxEnhanceRxReadBuffer failed\n"); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ break; ++ } ++ /* prSDIOCtrl->au4RxLength[i] = 0; */ ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); ++ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ } ++ } ++ ++ prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0; ++ prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0; ++ ++} /* end of nicRxSDIOReceiveRFBs() */ ++ ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++#if CFG_SDIO_RX_AGG ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read frames from the data port for SDIO with Rx aggregation enabled ++* I/F, fill RFB and put each frame into the rReceivedRFBList queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter) ++{ ++ P_ENHANCE_MODE_DATA_STRUCT_T prEnhDataStr; ++ P_RX_CTRL_T prRxCtrl; ++ P_SDIO_CTRL_T prSDIOCtrl; ++ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; ++ UINT_32 u4RxLength; ++ UINT_32 i, rxNum; ++ UINT_32 u4RxAggCount = 0, u4RxAggLength = 0; ++ UINT_32 u4RxAvailAggLen, u4CurrAvailFreeRfbCnt; ++ PUINT_8 pucSrcAddr; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ BOOLEAN fgResult = TRUE; ++ BOOLEAN fgIsRxEnhanceMode; ++ UINT_16 u2RxPktNum; ++#if CFG_SDIO_RX_ENHANCE ++ UINT_32 u4MaxLoopCount = CFG_MAX_RX_ENHANCE_LOOP_COUNT; ++#endif ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicRxSDIOAggReceiveRFBs"); ++ ++ ASSERT(prAdapter); ++ prEnhDataStr = prAdapter->prSDIOCtrl; ++ prRxCtrl = &prAdapter->rRxCtrl; ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++ ++#if CFG_SDIO_RX_ENHANCE ++ fgIsRxEnhanceMode = TRUE; ++#else ++ fgIsRxEnhanceMode = FALSE; ++#endif ++ ++ do { ++#if CFG_SDIO_RX_ENHANCE ++ /* to limit maximum loop for RX */ ++ u4MaxLoopCount--; ++ if (u4MaxLoopCount == 0) ++ break; ++#endif ++ ++ if (prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0) ++ break; ++ ++ for (rxNum = 0; rxNum < 2; rxNum++) { ++ u2RxPktNum = ++ (rxNum == ++ 0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : prEnhDataStr->rRxInfo.u.u2NumValidRx1Len); ++ ++ /* if this assertion happened, it is most likely a F/W bug */ ++ ASSERT(u2RxPktNum <= 16); ++ ++ if (u2RxPktNum > 16) ++ continue; ++ ++ if (u2RxPktNum == 0) ++ continue; ++ ++#if CFG_HIF_STATISTICS ++ prRxCtrl->u4TotalRxAccessNum++; ++ prRxCtrl->u4TotalRxPacketNum += u2RxPktNum; ++#endif ++ ++ u4CurrAvailFreeRfbCnt = prRxCtrl->rFreeSwRfbList.u4NumElem; ++ ++ /* if SwRfb is not enough, abort reading this time */ ++ if (u4CurrAvailFreeRfbCnt < u2RxPktNum) { ++#if CFG_HIF_RX_STARVATION_WARNING ++ DbgPrint("FreeRfb is not enough: %d available, need %d\n", u4CurrAvailFreeRfbCnt, ++ u2RxPktNum); ++ DbgPrint("Queued Count: %d / Dequeud Count: %d\n", prRxCtrl->u4QueuedCnt, ++ prRxCtrl->u4DequeuedCnt); ++#endif ++ continue; ++ } ++#if CFG_SDIO_RX_ENHANCE ++ u4RxAvailAggLen = ++ CFG_RX_COALESCING_BUFFER_SIZE - (sizeof(ENHANCE_MODE_DATA_STRUCT_T) + ++ 4 /* extra HW padding */); ++#else ++ u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE; ++#endif ++ u4RxAggCount = 0; ++ ++ for (i = 0; i < u2RxPktNum; i++) { ++ u4RxLength = (rxNum == 0 ? ++ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : ++ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); ++ ++ if (!u4RxLength) { ++ ASSERT(0); ++ break; ++ } ++ ++ if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) { ++ if (u4RxAggCount < u4CurrAvailFreeRfbCnt) { ++ u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN); ++ u4RxAggCount++; ++ } else { ++ /* no FreeSwRfb for rx packet */ ++ ASSERT(0); ++ break; ++ } ++ } else { ++ /* CFG_RX_COALESCING_BUFFER_SIZE is not large enough */ ++ ASSERT(0); ++ break; ++ } ++ } ++ ++ u4RxAggLength = (CFG_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen); ++ /* DBGLOG(RX, INFO, ("u4RxAggCount = %d, u4RxAggLength = %d\n", */ ++ /* u4RxAggCount, u4RxAggLength)); */ ++ ++ HAL_READ_RX_PORT(prAdapter, ++ rxNum, ++ u4RxAggLength, prRxCtrl->pucRxCoalescingBufPtr, CFG_RX_COALESCING_BUFFER_SIZE); ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read RX Agg Packet Error\n"); ++ continue; ++ } ++ ++ pucSrcAddr = prRxCtrl->pucRxCoalescingBufPtr; ++ for (i = 0; i < u4RxAggCount; i++) { ++ UINT_16 u2PktLength; ++ ++ u2PktLength = (rxNum == 0 ? ++ prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : ++ prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ ASSERT(prSwRfb); ++ kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr, ++ ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN)); ++ ++ /* record the rx time */ ++ STATS_RX_ARRIVE_TIME_RECORD(prSwRfb); /* ms */ ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ASSERT(prHifRxHdr); ++ ++ prSwRfb->ucPacketType = ++ (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); ++ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ ++ ++ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); ++ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN); ++ /* prEnhDataStr->au4RxLength[i] = 0; */ ++ } ++ ++#if CFG_SDIO_RX_ENHANCE ++ kalMemCopy(prAdapter->prSDIOCtrl, (pucSrcAddr + 4), sizeof(ENHANCE_MODE_DATA_STRUCT_T)); ++ ++ /* do the same thing what nicSDIOReadIntStatus() does */ ++ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && ++ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { ++ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; ++ } ++ ++ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && ++ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && ++ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { ++ prSDIOCtrl->u4WHISR |= BIT(31); ++ } ++ ++ /* dispatch to interrupt handler with RX bits masked */ ++ nicProcessIST_impl(prAdapter, ++ prSDIOCtrl->u4WHISR & (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT))); ++#endif ++ } ++ ++#if !CFG_SDIO_RX_ENHANCE ++ prEnhDataStr->rRxInfo.u.u2NumValidRx0Len = 0; ++ prEnhDataStr->rRxInfo.u.u2NumValidRx1Len = 0; ++#endif ++ } while ((prEnhDataStr->rRxInfo.u.u2NumValidRx0Len || prEnhDataStr->rRxInfo.u.u2NumValidRx1Len) ++ && fgIsRxEnhanceMode); ++ ++} ++#endif /* CFG_SDIO_RX_AGG */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Setup a RFB and allocate the os packet to the RFB ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prSwRfb Pointer to the RFB ++* ++* @retval WLAN_STATUS_SUCCESS ++* @retval WLAN_STATUS_RESOURCES ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ PVOID pvPacket; ++ PUINT_8 pucRecvBuff; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (!prSwRfb->pvPacket) { ++ kalMemZero(prSwRfb, sizeof(SW_RFB_T)); ++ pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, CFG_RX_MAX_PKT_SIZE, &pucRecvBuff); ++ if (pvPacket == NULL) ++ return WLAN_STATUS_RESOURCES; ++ ++ prSwRfb->pvPacket = pvPacket; ++ prSwRfb->pucRecvBuff = (PVOID) pucRecvBuff; ++ } else { ++ kalMemZero(((PUINT_8) prSwRfb + OFFSET_OF(SW_RFB_T, prHifRxHdr)), ++ (sizeof(SW_RFB_T) - OFFSET_OF(SW_RFB_T, prHifRxHdr))); ++ } ++ ++ prSwRfb->prHifRxHdr = (P_HIF_RX_HEADER_T) (prSwRfb->pucRecvBuff); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} /* end of nicRxSetupRFB() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is called to put a RFB back onto the "RFB with Buffer" list ++* or "RFB without buffer" list according to pvPacket. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prSwRfb Pointer to the RFB ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ P_QUE_ENTRY_T prQueEntry; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ prQueEntry = &prSwRfb->rQueEntry; ++ ++ ASSERT(prQueEntry); ++ ++ /* The processing on this RFB is done, so put it back on the tail of ++ our list */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++ ++ if (prSwRfb->pvPacket) { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry); ++ } else { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry); ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); ++} /* end of nicRxReturnRFB() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process rx interrupt. When the rx ++* Interrupt is asserted, it means there are frames in queue. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ prGlueInfo->IsrRxCnt++; ++#if CFG_SDIO_INTR_ENHANCE ++#if CFG_SDIO_RX_AGG ++ nicRxSDIOAggReceiveRFBs(prAdapter); ++#else ++ nicRxSDIOReceiveRFBs(prAdapter); ++#endif ++#else ++ nicRxReceiveRFBs(prAdapter); ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ nicRxProcessRFBs(prAdapter); ++ ++ return; ++ ++} /* end of nicProcessRxInterrupt() */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Used to update IP/TCP/UDP checksum statistics of RX Module. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param aeCSUM The array of checksum result. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(aeCSUM); ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) || ++ (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT); ++ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT); ++ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT); ++ } else { ++ ASSERT(0); ++ } ++ ++ if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) { ++ /* count success num */ ++ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT); ++ } else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT); ++ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT); ++ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT); ++ } else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) { ++ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT); ++ } else { ++ ASSERT(0); ++ } ++ ++} /* end of nicRxUpdateCSUMStatistics() */ ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to query current status of RX Module. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param pucBuffer Pointer to the message buffer. ++* @param pu4Count Pointer to the buffer of message length count. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucCurrBuf = pucBuffer; ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ ++ ASSERT(pu4Count); ++ ++ SPRINTF(pucCurrBuf, ("\n\nRX CTRL STATUS:")); ++ SPRINTF(pucCurrBuf, ("\n===============")); ++ SPRINTF(pucCurrBuf, ("\nFREE RFB w/i BUF LIST :%9u", prRxCtrl->rFreeSwRfbList.u4NumElem)); ++ SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9u", prRxCtrl->rIndicatedRfbList.u4NumElem)); ++ SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST :%9u", prRxCtrl->rReceivedRfbList.u4NumElem)); ++ ++ SPRINTF(pucCurrBuf, ("\n\n")); ++ ++ /* *pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); */ ++ ++} /* end of nicRxQueryStatus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Clear RX related counters ++* ++* @param prAdapter Pointer of Adapter Data Structure ++* ++* @return - (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ RX_RESET_ALL_CNTS(prRxCtrl); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to query current statistics of RX Module. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param pucBuffer Pointer to the message buffer. ++* @param pu4Count Pointer to the buffer of message length count. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) ++{ ++ P_RX_CTRL_T prRxCtrl; ++ PUINT_8 pucCurrBuf = pucBuffer; ++ ++ ASSERT(prAdapter); ++ prRxCtrl = &prAdapter->rRxCtrl; ++ ASSERT(prRxCtrl); ++ ++ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ ++ ASSERT(pu4Count); ++ ++#define SPRINTF_RX_COUNTER(eCounter) \ ++ SPRINTF(pucCurrBuf, ("%-30s : %u\n", #eCounter, (UINT_32)prRxCtrl->au8Statistics[eCounter])) ++ ++ SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT); ++ SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT); ++ SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT); ++ SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT); ++ SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 ++ SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT); ++ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT); ++ SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT); ++#endif ++ ++ /* *pu4Count = (UINT_32)(pucCurrBuf - pucBuffer); */ ++ ++ nicRxClearStatistics(prAdapter); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Read the Response data from data port ++* ++* @param prAdapter pointer to the Adapter handler ++* @param pucRspBuffer pointer to the Response buffer ++* ++* @retval WLAN_STATUS_SUCCESS: Response packet has been read ++* @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++nicRxWaitResponse(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length) ++{ ++ UINT_32 u4Value = 0, u4PktLen = 0; ++ UINT_32 i = 0; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgResult = TRUE; ++ UINT_32 u4Time, u4Current; ++ ++ DEBUGFUNC("nicRxWaitResponse"); ++ ++ ASSERT(prAdapter); ++ ASSERT(pucRspBuffer); ++ ASSERT(ucPortIdx < 2); ++ ++ u4Time = kalGetTimeTick(); ++ ++ do { ++ /* Read the packet length */ ++ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value); ++ ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ if (ucPortIdx == 0) ++ u4PktLen = u4Value & 0xFFFF; ++ else ++ u4PktLen = (u4Value >> 16) & 0xFFFF; ++ ++/* DBGLOG(RX, TRACE, ("i = %d, u4PktLen = %d\n", i, u4PktLen)); */ ++ ++ if (u4PktLen == 0) { ++ /* timeout exceeding check */ ++ u4Current = kalGetTimeTick(); ++ ++ if ((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) { ++ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT1 %u %d %u\n", u4PktLen, i, u4Current); ++ return WLAN_STATUS_FAILURE; ++ } else if (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) { ++ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT2 %u %d %u\n", u4PktLen, i, u4Current); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* Response packet is not ready */ ++ kalUdelay(50); ++ ++ i++; ++ continue; ++ } ++ if (u4PktLen > u4MaxRespBufferLen) { ++ /* ++ TO: buffer is not enough but we still need to read all data from HIF to avoid ++ HIF crazy. ++ */ ++ DBGLOG(RX, ERROR, ++ "Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n", ++ u4PktLen, u4MaxRespBufferLen); ++ DBGLOG(RX, ERROR, "i = %d, u4PktLen = %u\n", i, u4PktLen); ++ return WLAN_STATUS_FAILURE; ++ } ++ HAL_PORT_RD(prAdapter, ++ ucPortIdx == 0 ? MCR_WRDR0 : MCR_WRDR1, u4PktLen, pucRspBuffer, u4MaxRespBufferLen); ++ ++ /* fgResult will be updated in MACRO */ ++ if (!fgResult) { ++ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ DBGLOG(RX, TRACE, "Dump Response buffer, length = 0x%x\n", u4PktLen); ++ DBGLOG_MEM8(RX, TRACE, pucRspBuffer, u4PktLen); ++ ++ *pu4Length = u4PktLen; ++ break; ++ } while (TRUE); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Set filter to enable Promiscuous Mode ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++} /* end of nicRxEnablePromiscuousMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Set filter to disable Promiscuous Mode ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++} /* end of nicRxDisablePromiscuousMode() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function flushes all packets queued in reordering module ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Flushed successfully ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter) ++{ ++ P_SW_RFB_T prSwRfb; ++ ++ ASSERT(prAdapter); ++ ++ prSwRfb = qmFlushRxQueues(prAdapter); ++ if (prSwRfb != NULL) { ++ do { ++ P_SW_RFB_T prNextSwRfb; ++ ++ /* save next first */ ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); ++ ++ /* free */ ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ ++ prSwRfb = prNextSwRfb; ++ } while (prSwRfb); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief ++* ++* @param ++* ++* @retval ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) ++{ ++ P_WLAN_ACTION_FRAME prActFrame; ++ ++ ASSERT(prAdapter); ++ ASSERT(prSwRfb); ++ ++ if (prSwRfb->u2PacketLen < sizeof(WLAN_ACTION_FRAME) - 1) ++ return WLAN_STATUS_INVALID_PACKET; ++ prActFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; ++ DBGLOG(RX, INFO, "Category %u\n", prActFrame->ucCategory); ++ ++ switch (prActFrame->ucCategory) { ++ case CATEGORY_PUBLIC_ACTION: ++ if (HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) ++ aisFuncValidateRxActionFrame(prAdapter, prSwRfb); ++#if CFG_ENABLE_WIFI_DIRECT ++ else if (prAdapter->fgIsP2PRegistered) { ++ rlmProcessPublicAction(prAdapter, prSwRfb); ++ ++ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); ++ ++ } ++#endif ++ break; ++ ++ case CATEGORY_HT_ACTION: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ rlmProcessHtAction(prAdapter, prSwRfb); ++#endif ++ break; ++ case CATEGORY_VENDOR_SPECIFIC_ACTION: ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prAdapter->fgIsP2PRegistered) ++ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); ++#endif ++ break; ++#if CFG_SUPPORT_802_11W ++ case CATEGORY_SA_QUERT_ACTION: ++ { ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ ++ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) ++ && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { ++ if (!(prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC)) { ++ /* MFP test plan 5.3.3.4 */ ++ rsnSaQueryAction(prAdapter, prSwRfb); ++ } else { ++ DBGLOG(RSN, TRACE, "Un-Protected SA Query, do nothing\n"); ++ } ++ } ++ } ++ break; ++#endif ++#if CFG_SUPPORT_802_11V ++ case CATEGORY_WNM_ACTION: ++ { ++ wnmWNMAction(prAdapter, prSwRfb); ++ } ++ break; ++#endif ++ ++#if CFG_SUPPORT_DFS /* Add by Enlai */ ++ case CATEGORY_SPEC_MGT: ++ { ++ if (prAdapter->fgEnable5GBand == TRUE) ++ rlmProcessSpecMgtAction(prAdapter, prSwRfb); ++ } ++ break; ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ case 12: /* shall not be here */ ++ /* ++ A received TDLS Action frame with the Type field set to Management shall ++ be discarded. Note that the TDLS Discovery Response frame is not a TDLS ++ frame but a Public Action frame. ++ */ ++ break; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ default: ++ break; ++ } /* end of switch case */ ++ ++ return WLAN_STATUS_SUCCESS; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c +new file mode 100644 +index 000000000000..024bd9507603 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c +@@ -0,0 +1,2350 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#1 ++*/ ++ ++/*! \file nic_tx.c ++ \brief Functions that provide TX operation in NIC Layer. ++ ++ This file provides TX functions which are responsible for both Hardware and ++ Software Resource Management and keep their Synchronization. ++*/ ++ ++/* ++** Log: nic_tx.c ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 11 18 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add log counter for tx ++ * ++ * 11 09 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog for beacon timeout and sta aging timeout. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 05 17 2011 cp.wu ++ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss ++ * disconnection ++ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame ++ * dropping cases for TC4 path ++ * remove unused variables. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame ++ * dropping cases for TC4 path ++ * 1. add nicTxGetResource() API for QM to make decisions. ++ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 02 16 2011 cp.wu ++ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count ++ * and modify behavior ++ * 1. add new API: nicTxGetFreeCmdCount() ++ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation ++ * needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system ++ * scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add GPIO debug function ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore ++ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion ++ * 2. shorten polling count for shorter response time ++ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 09 29 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. ++ * ++ * 09 27 2010 wh.su ++ * NULL ++ * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error ++ * ++ * 09 24 2010 wh.su ++ * NULL ++ * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra ++ * bytes padding. ++ * ++ * 09 01 2010 cp.wu ++ * NULL ++ * HIFSYS Clock Source Workaround ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * API added: nicTxPendingPackets(), for simplifying porting layer ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * eliminate klockwork errors ++ * ++ * 08 20 2010 wh.su ++ * NULL ++ * adding the eapol callback setting. ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 05 2010 yuche.tsai ++ * NULL ++ * . ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * simplify post-handling after TX_DONE interrupt is handled. ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 13 2010 cp.wu ++ * ++ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets ++ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending ++ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network ++ * operation ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 24 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 22 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) add command warpper for STA-REC/BSS-INFO sync. ++ * 2) enhance command packet sending procedure for non-oid part ++ * 3) add command packet definitions for STA-REC/BSS-INFO sync. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add checking for TX descriptor poll. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * TX descriptors are now allocated once for reducing allocation overhead ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change zero-padding for TX port access to HAL. ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 15 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * . ++ * ++ * 06 14 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * fill extra information for revised HIF_TX_HEADER. ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 10 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change to enqueue TX frame infinitely. ++ * ++ * 06 09 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add TX_PACKET_MGMT to indicate the frame is coming from management modules ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * fill network type field while doing frame identification. ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Tag the packet for QoS on Tx path ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove driver-land statistics. ++ * ++ * 03 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++ * 03 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK ++ * * * * * ++ * ++* 03 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code clean: removing unused variables and structure definitions ++ * ++ * 03 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. ++ * * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds ++ * ++ * 03 02 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add mutex to avoid multiple access to qmTxQueue simultaneously. ++ * ++ * 02 26 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * avoid referring to NDIS-specific data structure directly from non-glue layer. ++ * ++ * 02 24 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add Ethernet destination address information in packet info for TX ++ * ++ * 02 10 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] ++ * * * * * * 2) firmware image length is now retrieved via NdisFileOpen ++ * * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore ++ * * * * * * 4) nicRxWaitResponse() revised ++ * * * * * * 5) another set of TQ counter default value is added for fw-download state ++ * * * * * * 6) Wi-Fi load address is now retrieved from registry too ++ * ++ * 02 09 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address ++ * * * * * * * * * 2. follow MSDN defined behavior when associates to another AP ++ * * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes ++ * ++ * 02 08 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * prepare for implementing fw download logic ++ * ++ * 01 27 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. eliminate improper variable in rHifInfo ++ * * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged ++ * * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode ++ * * * * * * * * * 4. correct some HAL implementation ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++ * ++ * 01 13 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo ++ * ++ * 12 30 2009 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) According to CMD/EVENT documentation v0.8, ++ * * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, ++ * * * * * * * * * * and result is retrieved by get ATInfo instead ++ * * * * * * * * * * 2) add 4 counter for recording aggregation statistics ++** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752 ++** remove unused API ++** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752 ++** correct assertion criterion ++** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752 ++** correct trivial mistake ++** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752 ++** + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data ++** + add more assertion for packet size check ++** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752 ++** nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort ++** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752 ++** add 2 assertion for size check ++** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461 ++** Add debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752 ++** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T ++** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752 ++** use TC4 instead of TC5 for command packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752 ++** add flush for reset ++** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752 ++** fill prMsduInfo->ucUserPriority ++** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752 ++** fill u2SeqNo ++** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752 ++** integration with SD1's data path API ++** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752 ++** nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList ++** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752 ++** add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum, ++** WIFI_CMD_T will be created inside oid handler ++** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752 ++** use TxAccquireResource instead of accessing TCQ directly. ++** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752 ++** add nicTxMsduInfoList () implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752 ++** add nicTxAdjustTcq() implementation ++** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752 ++** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752 ++** add SD1_SD3_DATAPATH_INTEGRATION data path handling ++** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084 ++** modify TX hdr format, fix tx retransmission issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084 ++** modify TX SW data structure ++** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084 ++** modify HAL part ++** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084 ++** update for new HW design ++** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725 ++** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461 ++** Assign SeqNum to CMD Packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461 ++** Add debug message ++** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461 ++** Fix Query Command need resp issue ++** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461 ++** Move OS dependent code to kalQueryTxOOBData() ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461 ++** Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461 ++** Update nicTxCmd() for moving wait RESP function call to wlanSendCommand() ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461 ++** Move the CMD_INFO_T related function to cmd_buf.c ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426 ++** Update OOB query for TX packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426 ++** Support PKGUIO ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461 ++** Add virtual OOB for HIF LOOPBACK SW PRETEST ++** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461 ++** Add function for SDIO_TX_ENHANCE ++** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461 ++** Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test. ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461 ++** Add code for TX Data & Cmd Packet ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461 ++** Fix LINT warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461 ++** Update TX PATH API ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will initial all variables in regard to SW TX Queues and ++* all free lists of MSDU_INFO_T and SW_TFCB_T. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxInitialize(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ PUINT_8 pucMemHandle; ++ P_MSDU_INFO_T prMsduInfo; ++ UINT_32 i; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicTxInitialize"); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ /* 4 <1> Initialization of Traffic Class Queue Parameters */ ++ nicTxResetResource(prAdapter); ++ ++#if CFG_SDIO_TX_AGG ++ prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; ++#endif /* CFG_SDIO_TX_AGG */ ++ ++ /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */ ++ QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList); ++ ++ pucMemHandle = prTxCtrl->pucTxCached; ++ for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) { ++ prMsduInfo = (P_MSDU_INFO_T) pucMemHandle; ++ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ ++ pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T)); ++ } ++ ++ ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM); ++ /* Check if the memory allocation consist with this initialization function */ ++ ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize); ++ ++ QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue); ++ prTxCtrl->i4TxMgmtPendingNum = 0; ++ ++#if CFG_HIF_STATISTICS ++ prTxCtrl->u4TotalTxAccessNum = 0; ++ prTxCtrl->u4TotalTxPacketNum = 0; ++#endif ++ ++ prTxCtrl->i4PendingFwdFrameCount = 0; ++ ++ qmInit(prAdapter); ++ ++ TX_RESET_ALL_CNTS(prTxCtrl); ++ ++} /* end of nicTxInitialize() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will check if has enough TC Buffer for incoming ++* packet and then update the value after promise to provide the resources. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] ucTC Specify the resource of TC ++* ++* \retval WLAN_STATUS_SUCCESS Resource is available and been assigned. ++* \retval WLAN_STATUS_RESOURCES Resource is not available. ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 u4CurrTick = 0; ++WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt) ++{ ++#define TC4_NO_RESOURCE_DELAY_MS 5 /* exponential of 5s */ ++ ++ P_TX_CTRL_T prTxCtrl; ++ WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES; ++ P_QUE_MGT_T prQM; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ prQM = &prAdapter->rQM; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++/* DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n", ++ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); */ ++ do { ++ if (pfgIsSecOrMgmt && (ucTC == TC4_INDEX)) { ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] < 2) { ++ DBGLOG(TX, EVENT, " aucFreeBufferCount = %d\n", ++ prTxCtrl->rTc.aucFreeBufferCount[ucTC]); ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) ++ u4CurrTick = 0; ++ ++ break; ++ } ++ } ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) { ++ ++ if (ucTC == TC4_INDEX) ++ u4CurrTick = 0; ++ /* get a available TX entry */ ++ prTxCtrl->rTc.aucFreeBufferCount[ucTC]--; ++ ++ prQM->au4ResourceUsedCounter[ucTC]++; ++ ++ DBGLOG(TX, EVENT, "Acquire: TC = %d aucFreeBufferCount = %d\n", ++ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); ++ ++ u4Status = WLAN_STATUS_SUCCESS; ++ } ++ } while (FALSE); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ if (ucTC == TC4_INDEX) { ++ if (u4CurrTick == 0) ++ u4CurrTick = kalGetTimeTick(); ++ if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick, ++ SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) { ++ wlanDumpTcResAndTxedCmd(NULL, 0); ++ cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, "waiting response CMD queue"); ++ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); ++ kalSendAeeWarning("[TC4 no resource delay 5s!]", __func__); ++ glDoChipReset(); ++ u4CurrTick = 0; ++ } ++ } ++ return u4Status; ++ ++} /* end of nicTxAcquireResourceAndTFCBs() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will do polling if FW has return the resource. ++* Used when driver start up before enable interrupt. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param ucTC Specify the resource of TC ++* ++* @retval WLAN_STATUS_SUCCESS Resource is available. ++* @retval WLAN_STATUS_FAILURE Resource is not available. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; ++ INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT; ++ UINT_32 au4WTSR[2]; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ if (ucTC >= TC_NUM) ++ return WLAN_STATUS_FAILURE; ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) ++ return WLAN_STATUS_SUCCESS; ++ ++ while (i-- > 0) { ++ HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR); ++ ++ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { ++ u4Status = WLAN_STATUS_FAILURE; ++ break; ++ } else if (nicTxReleaseResource(prAdapter, (PUINT_8) au4WTSR)) { ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) { ++ u4Status = WLAN_STATUS_SUCCESS; ++ break; ++ } ++ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); ++ ++ } else { ++ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); ++ } ++ } ++ ++ if (i <= 0 && ucTC == TC4_INDEX) { ++ DBGLOG(TX, ERROR, "polling Tx resource for Tc4 timeout\n"); ++ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); ++ } ++#if DBG ++ { ++ INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1); ++ ++ if (i4Times) { ++ DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %d times, %d msec\n", ++ i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC)); ++ } ++ } ++#endif /* DBG */ ++ ++ return u4Status; ++ ++} /* end of nicTxPollingResource() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will release TC Buffer count according to ++* the given TX_STATUS COUNTER after TX Done. ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* \param[in] u4TxStatusCnt Value of TX STATUS ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN unsigned char *aucTxRlsCnt) ++{ ++ PUINT_32 pu4Tmp = (PUINT_32) aucTxRlsCnt; ++ P_TX_CTRL_T prTxCtrl; ++ BOOLEAN bStatus = FALSE; ++ UINT_32 i; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ if (pu4Tmp[0] | pu4Tmp[1]) { ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ for (i = 0; i < TC_NUM; i++) ++ prTxCtrl->rTc.aucFreeBufferCount[i] += aucTxRlsCnt[i]; ++ for (i = 0; i < TC_NUM; i++) ++ prQM->au4QmTcResourceBackCounter[i] += aucTxRlsCnt[i]; ++ if (aucTxRlsCnt[TC4_INDEX] != 0) ++ wlanTraceReleaseTcRes(prAdapter, aucTxRlsCnt, prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX]); ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++#if 0 ++ for (i = 0; i < TC_NUM; i++) { ++ DBGLOG(TX, TRACE, "aucFreeBufferCount[%d]: %d, aucMaxNumOfBuffer[%d]: %d\n", ++ i, prTxCtrl->rTc.aucFreeBufferCount[i], i, ++ prTxCtrl->rTc.aucMaxNumOfBuffer[i]); ++ } ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[0]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[0]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[1]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[1]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[2]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[2]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[3]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[3]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[4]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[4]); ++ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[5]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[5]); ++#endif ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX]); ++ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX]); ++ bStatus = TRUE; ++ } ++ ++ return bStatus; ++} /* end of nicTxReleaseResource() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Reset TC Buffer Count to initialized value ++* ++* \param[in] prAdapter Pointer to the Adapter structure. ++* ++* @return WLAN_STATUS_SUCCESS ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ DEBUGFUNC("nicTxResetResource"); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; ++ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; ++ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; ++ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; ++ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; ++ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; ++ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Driver maintain a variable that is synchronous with the usage of individual ++* TC Buffer Count. This function will return the value for other component ++* which needs this information for making decisions ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param ucTC Specify the resource of TC ++* ++* @retval UINT_8 The number of corresponding TC number ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ ASSERT(prTxCtrl); ++ ++ if (ucTC >= TC_NUM) ++ return 0; ++ else ++ return prTxCtrl->rTc.aucFreeBufferCount[ucTC]; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief In this function, we'll aggregate frame(PACKET_INFO_T) ++* corresponding to HIF TX port ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfoListHead a link list of P_MSDU_INFO_T ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; ++ QUE_T qDataPort0, qDataPort1; ++ WLAN_STATUS status; ++ BOOLEAN pfgIsSecOrMgmt = FALSE; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfoListHead); ++ ++ prMsduInfo = prMsduInfoListHead; ++ ++ QUEUE_INITIALIZE(&qDataPort0); ++ QUEUE_INITIALIZE(&qDataPort1); ++ ++ /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++#if DBG && 0 ++ LOG_FUNC("nicTxMsduInfoList Acquire TC %d net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prMsduInfo->ucTC, ++ prMsduInfo->ucNetworkType, ++ prMsduInfo->ucMacHeaderLength, ++ prMsduInfo->u2FrameLength, ++ prMsduInfo->ucPacketType, prMsduInfo->fgIs802_1x, prMsduInfo->fgIs802_11); ++ ++ LOG_FUNC("Dest Mac: %pM\n", prMsduInfo->aucEthDestAddr); ++#endif ++ ++ /* double-check available TX resouce (need to sync with CONNSYS FW) */ ++ /* caller must guarantee that the TX resource is enough in the func; OR assert here */ ++ switch (prMsduInfo->ucTC) { ++ case TC0_INDEX: ++ case TC1_INDEX: ++ case TC2_INDEX: ++ case TC3_INDEX: ++ case TC5_INDEX: /* Broadcast/multicast data packets */ ++ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; ++ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); ++ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, FALSE); ++ ASSERT(status == WLAN_STATUS_SUCCESS) ++ ++ break; ++ ++ case TC4_INDEX: /* Command or 802.1x packets */ ++ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; ++ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); ++ ++ if ((prMsduInfo->fgIs802_1x == TRUE) || ++ (prMsduInfo->fgIs802_11 == TRUE)) ++ pfgIsSecOrMgmt = TRUE; ++ ++ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, pfgIsSecOrMgmt); ++ ASSERT(status == WLAN_STATUS_SUCCESS) ++ ++ break; ++ ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ } ++ ++ /* send packets to HIF port0 or port1 here */ ++ if (qDataPort0.u4NumElem > 0) ++ nicTxMsduQueue(prAdapter, 0, &qDataPort0); ++ ++ if (qDataPort1.u4NumElem > 0) ++ nicTxMsduQueue(prAdapter, 1, &qDataPort1); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ ++#if CFG_PRINT_RTP_PROFILE ++PKT_PROFILE_T rPrevRoundLastPkt; ++ ++BOOLEAN ++nicTxLifetimePrintCheckRTP(IN P_MSDU_INFO_T prPrevProfileMsduInfo, ++ IN P_PKT_PROFILE_T prPrevRoundLastPkt, ++ IN P_PKT_PROFILE_T prPktProfile, ++ IN OUT PBOOLEAN pfgGotFirst, IN UINT_32 u4MaxDeltaTime, IN UINT_8 ucSnToBePrinted) ++{ ++ BOOLEAN fgPrintCurPkt = FALSE; ++ ++ if (u4MaxDeltaTime) { ++ /* 4 1. check delta between current round first pkt and prevous round last pkt */ ++ if (!*pfgGotFirst) { ++ *pfgGotFirst = TRUE; ++ ++ if (prPrevRoundLastPkt->fgIsValid) { ++ if (CHK_PROFILES_DELTA(prPktProfile, prPrevRoundLastPkt, u4MaxDeltaTime)) { ++ PRINT_PKT_PROFILE(prPrevRoundLastPkt, "PR"); ++ fgPrintCurPkt = TRUE; ++ } ++ } ++ } ++ /* 4 2. check delta between current pkt and previous pkt */ ++ if (prPrevProfileMsduInfo) { ++ if (CHK_PROFILES_DELTA(prPktProfile, &prPrevProfileMsduInfo->rPktProfile, u4MaxDeltaTime)) { ++ PRINT_PKT_PROFILE(&prPrevProfileMsduInfo->rPktProfile, "P"); ++ fgPrintCurPkt = TRUE; ++ } ++ } ++ /* 4 3. check delta of current pkt lifetime */ ++ if (CHK_PROFILE_DELTA(prPktProfile, u4MaxDeltaTime)) ++ fgPrintCurPkt = TRUE; ++ } ++ /* 4 4. print every X RTP packets */ ++#if CFG_SUPPORT_WFD ++ if ((ucSnToBePrinted != 0) && (prPktProfile->u2RtpSn % ucSnToBePrinted) == 0) ++ fgPrintCurPkt = TRUE; ++#endif ++ ++ return fgPrintCurPkt; ++} ++ ++BOOLEAN ++nicTxLifetimePrintCheckSnOrder(IN P_MSDU_INFO_T prPrevProfileMsduInfo, ++ IN P_PKT_PROFILE_T prPrevRoundLastPkt, ++ IN P_PKT_PROFILE_T prPktProfile, IN OUT PBOOLEAN pfgGotFirst, IN UINT_8 ucLayer) ++{ ++ BOOLEAN fgPrintCurPkt = FALSE; ++ P_PKT_PROFILE_T prTarPktProfile = NULL; ++ UINT_16 u2PredictSn = 0; ++ UINT_16 u2CurrentSn = 0; ++ UINT_8 aucNote[8]; ++ ++ /* 4 1. Get the target packet profile to compare */ ++ ++ /* 4 1.1 check SN between current round first pkt and prevous round last pkt */ ++ if ((!*pfgGotFirst) && (prPrevRoundLastPkt->fgIsValid)) { ++ *pfgGotFirst = TRUE; ++ prTarPktProfile = prPrevRoundLastPkt; ++ kalMemCopy(aucNote, "PR\0", 3); ++ } ++ /* 4 1.2 check SN between current pkt and previous pkt */ ++ else if (prPrevProfileMsduInfo) { ++ prTarPktProfile = &prPrevProfileMsduInfo->rPktProfile; ++ kalMemCopy(aucNote, "P\0", 2); ++ } ++ ++ if (!prTarPktProfile) ++ return FALSE; ++ /* 4 2. Check IP or RTP SN */ ++ switch (ucLayer) { ++ /* Check IP SN */ ++ case 0: ++ u2PredictSn = prTarPktProfile->u2IpSn + 1; ++ u2CurrentSn = prPktProfile->u2IpSn; ++ break; ++ /* Check RTP SN */ ++ case 1: ++ default: ++ u2PredictSn = prTarPktProfile->u2RtpSn + 1; ++ u2CurrentSn = prPktProfile->u2RtpSn; ++ break; ++ ++ } ++ /* 4 */ ++ /* 4 3. Compare SN */ ++ if (u2CurrentSn != u2PredictSn) { ++ PRINT_PKT_PROFILE(prTarPktProfile, aucNote); ++ fgPrintCurPkt = TRUE; ++ } ++ ++ return fgPrintCurPkt; ++} ++#endif ++ ++VOID nicTxReturnMsduInfoProfiling(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; ++ P_PKT_PROFILE_T prPktProfile; ++ UINT_16 u2MagicCode = 0; ++ ++ UINT_8 ucDebugtMode = 0; ++#if CFG_PRINT_RTP_PROFILE ++ P_MSDU_INFO_T prPrevProfileMsduInfo = NULL; ++ P_PKT_PROFILE_T prPrevRoundLastPkt = &rPrevRoundLastPkt; ++ ++ BOOLEAN fgPrintCurPkt = FALSE; ++ BOOLEAN fgGotFirst = FALSE; ++ UINT_8 ucSnToBePrinted = 0; ++ ++ UINT_32 u4MaxDeltaTime = 50; /* in ms */ ++#endif ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ UINT_32 u4PktPrintPeriod = 0; ++#endif ++ ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ if (prAdapter->fgIsP2PRegistered) { ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ u2MagicCode = prWfdCfgSettings->u2WfdMaximumTp; ++ ucDebugtMode = prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode; ++ /* if(prWfdCfgSettings->ucWfdEnable && (prWfdCfgSettings->u4WfdFlag & BIT(0))) { */ ++ /* u2MagicCode = 0xE040; */ ++ /* } */ ++ } ++#endif ++ ++#if CFG_PRINT_RTP_PROFILE ++ if ((u2MagicCode >= 0xF000)) { ++ ucSnToBePrinted = (UINT_8) (u2MagicCode & BITS(0, 7)); ++ u4MaxDeltaTime = (UINT_8) (((u2MagicCode & BITS(8, 11)) >> 8) * 10); ++ } else { ++ ucSnToBePrinted = 0; ++ u4MaxDeltaTime = 0; ++ } ++ ++#endif ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ if ((u2MagicCode >= 0xE000) && (u2MagicCode < 0xF000)) ++ u4PktPrintPeriod = (UINT_32) ((u2MagicCode & BITS(0, 7)) * 32); ++ else ++ u4PktPrintPeriod = 0; ++#endif ++ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ prPktProfile = &prMsduInfo->rPktProfile; ++ ++ if (prPktProfile->fgIsValid) { ++ ++ prPktProfile->rHifTxDoneTimestamp = kalGetTimeTick(); ++ if (ucDebugtMode > 1) { ++ ++#if CFG_PRINT_RTP_PROFILE ++#if CFG_PRINT_RTP_SN_SKIP ++ fgPrintCurPkt = nicTxLifetimePrintCheckSnOrder(prPrevProfileMsduInfo, ++ prPrevRoundLastPkt, ++ prPktProfile, &fgGotFirst, 0); ++#else ++ fgPrintCurPkt = nicTxLifetimePrintCheckRTP(prPrevProfileMsduInfo, ++ prPrevRoundLastPkt, ++ prPktProfile, ++ &fgGotFirst, ++ u4MaxDeltaTime, ucSnToBePrinted); ++#endif ++ ++ /* Print current pkt profile */ ++ if (fgPrintCurPkt && ucDebugtMode > 1) ++ PRINT_PKT_PROFILE(prPktProfile, "C"); ++ ++ prPrevProfileMsduInfo = prMsduInfo; ++ fgPrintCurPkt = FALSE; ++#endif ++ } ++#if CFG_ENABLE_PER_STA_STATISTICS ++ { ++ P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ UINT_32 u4DeltaTime; ++ UINT_32 u4DeltaHifTime; ++#if 0 ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++#endif ++ UINT_8 ucNetIndex; ++ ++ if (prStaRec) { ++ ucNetIndex = prStaRec->ucNetTypeIndex; ++ u4DeltaTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - ++ prPktProfile->rHardXmitArrivalTimestamp); ++ u4DeltaHifTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - ++ prPktProfile->rDequeueTimestamp); ++ prStaRec->u4TotalTxPktsNumber++; ++ ++ prStaRec->u4TotalTxPktsTime += u4DeltaTime; ++ prStaRec->u4TotalTxPktsHifTime += u4DeltaHifTime; ++ ++ if (u4DeltaTime > prStaRec->u4MaxTxPktsTime) ++ prStaRec->u4MaxTxPktsTime = u4DeltaTime; ++ ++ if (u4DeltaHifTime > prStaRec->u4MaxTxPktsHifTime) ++ prStaRec->u4MaxTxPktsHifTime = u4DeltaHifTime; ++ ++ ++ if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD) ++ prStaRec->u4ThresholdCounter++; ++#if 0 ++ if (u4PktPrintPeriod && (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) { ++ ++ DBGLOG(TX, TRACE, "[%u]N[%4u]A[%5u]M[%4u]T[%4u]E[%4u]\n", ++ prStaRec->ucIndex, ++ prStaRec->u4TotalTxPktsNumber, ++ prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber, ++ prStaRec->u4MaxTxPktsTime, ++ prStaRec->u4ThresholdCounter, ++ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX]); ++ ++ prStaRec->u4TotalTxPktsNumber = 0; ++ prStaRec->u4TotalTxPktsTime = 0; ++ prStaRec->u4MaxTxPktsTime = 0; ++ prStaRec->u4ThresholdCounter = 0; ++ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX] = 0; ++ } ++#endif ++ } ++ ++ } ++#endif ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ }; ++ ++#if CFG_PRINT_RTP_PROFILE ++ /* 4 4. record the lifetime of current round last pkt */ ++ if (prPrevProfileMsduInfo) { ++ prPktProfile = &prPrevProfileMsduInfo->rPktProfile; ++ prPrevRoundLastPkt->u2IpSn = prPktProfile->u2IpSn; ++ prPrevRoundLastPkt->u2RtpSn = prPktProfile->u2RtpSn; ++ prPrevRoundLastPkt->rHardXmitArrivalTimestamp = prPktProfile->rHardXmitArrivalTimestamp; ++ prPrevRoundLastPkt->rEnqueueTimestamp = prPktProfile->rEnqueueTimestamp; ++ prPrevRoundLastPkt->rDequeueTimestamp = prPktProfile->rDequeueTimestamp; ++ prPrevRoundLastPkt->rHifTxDoneTimestamp = prPktProfile->rHifTxDoneTimestamp; ++ prPrevRoundLastPkt->ucTcxFreeCount = prPktProfile->ucTcxFreeCount; ++ prPrevRoundLastPkt->fgIsPrinted = prPktProfile->fgIsPrinted; ++ prPrevRoundLastPkt->fgIsValid = TRUE; ++ } ++#endif ++ ++ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); ++ ++} ++ ++VOID nicTxLifetimeRecordEn(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) ++{ ++ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; ++ ++ /* Enable packet lifetime profiling */ ++ prPktProfile->fgIsValid = TRUE; ++ ++ /* Packet arrival time at kernel Hard Xmit */ ++ prPktProfile->rHardXmitArrivalTimestamp = GLUE_GET_PKT_ARRIVAL_TIME(prPacket); ++ ++ /* Packet enqueue time */ ++ prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) kalGetTimeTick(); ++ ++} ++ ++#if CFG_PRINT_RTP_PROFILE ++/* ++ in: ++ data RTP packet pointer ++ size RTP size ++ return ++ 0:audio 1: video, -1:none ++*/ ++UINT8 checkRtpAV(PUINT_8 data, UINT_32 size) ++{ ++ PUINT_8 buf = data + 12; ++ ++ while (buf + 188 <= data + size) { ++ int pid = ((buf[1] << 8) & 0x1F00) | (buf[2] & 0xFF); ++ ++ if (pid == 0 || pid == 0x100 || pid == 0x1000) ++ buf += 188; ++ else if (pid == 0x1100) ++ return 0; ++ else if (pid == 0x1011) ++ return 1; ++ } ++ return -1; ++} ++ ++VOID ++nicTxLifetimeCheckRTP(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, ++ IN P_NATIVE_PACKET prPacket, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) ++{ ++ struct sk_buff *prSkb = (struct sk_buff *)prPacket; ++ UINT_16 u2EtherTypeLen; ++ PUINT_8 aucLookAheadBuf = NULL; ++ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; ++ ++ /* UINT_8 ucRtpHdrOffset = 28; */ ++ UINT_8 ucRtpSnOffset = 30; ++ /* UINT_32 u4RtpSrcPort = 15550; */ ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SUPPORT_WFD ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_WFD_DBG_CFG_SETTINGS_T prWfdDbgSettings = (P_WFD_DBG_CFG_SETTINGS_T) NULL; ++ ++ BOOLEAN fgEnProfiling = FALSE; ++ ++ if (prAdapter->fgIsP2PRegistered) { ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ prWfdDbgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting; ++#if CFG_PRINT_RTP_SN_SKIP ++ if (ucNetworkType == NETWORK_TYPE_P2P_INDEX) { ++ fgEnProfiling = TRUE; ++ } else ++#endif ++ if (((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000) || ++ (prWfdDbgSettings->ucWfdDebugMode > 0)) && (ucNetworkType == NETWORK_TYPE_P2P_INDEX)) { ++ fgEnProfiling = TRUE; ++ } ++ } ++ ++ if (fgEnProfiling == FALSE) { ++ /* prPktProfile->fgIsValid = FALSE; */ ++ return; ++ } ++#endif ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ /* prPktProfile->fgIsValid = FALSE; */ ++ ++ aucLookAheadBuf = prSkb->data; ++ ++ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { ++ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_16 u2tmpIpSN = 0; ++ UINT_8 ucIpVersion; ++ ++ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if (ucIpVersion == IPVERSION) { ++ if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) { ++ ++ /* if(checkRtpAV(&pucIpHdr[ucRtpHdrOffset], ++ (u4PacketLen - ETH_HLEN - ucRtpHdrOffset)) == 0) { */ ++ ++ if (prPktProfile->fgIsValid == FALSE) ++ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); ++ ++ prPktProfile->fgIsPrinted = FALSE; ++ ++ prPktProfile->ucTcxFreeCount = prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX]; ++ ++ /* RTP SN */ ++ prPktProfile->u2RtpSn = pucIpHdr[ucRtpSnOffset] << 8 | pucIpHdr[ucRtpSnOffset + 1]; ++ ++ /* IP SN */ ++ prPktProfile->u2IpSn = pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET] << 8 | ++ pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET + 1]; ++ u2tmpIpSN = prPktProfile->u2IpSn; ++ if (prWfdDbgSettings->ucWfdDebugMode == 1) { ++ if ((u2tmpIpSN & (prWfdDbgSettings->u2WfdSNShowPeiroid)) == 0) ++ DBGLOG(TX, TRACE, ++ "RtpSn=%d IPId=%d j=%lu\n", prPktProfile->u2RtpSn, ++ prPktProfile->u2IpSn, jiffies); ++ } ++ /* } */ ++ } ++ } ++ } ++ ++} ++#endif ++#if CFG_ENABLE_PER_STA_STATISTICS ++VOID ++nicTxLifetimeCheckByAC(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket, IN UINT_8 ucPriorityParam) ++{ ++ switch (ucPriorityParam) { ++ /* BK */ ++ /* case 1: */ ++ /* case 2: */ ++ ++ /* BE */ ++ /* case 0: */ ++ /* case 3: */ ++ ++ /* VI */ ++ case 4: ++ case 5: ++ ++ /* VO */ ++ case 6: ++ case 7: ++ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); ++ break; ++ default: ++ break; ++ } ++} ++ ++#endif ++ ++VOID ++nicTxLifetimeCheck(IN P_ADAPTER_T prAdapter, ++ IN P_MSDU_INFO_T prMsduInfo, ++ IN P_NATIVE_PACKET prPacket, ++ IN UINT_8 ucPriorityParam, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) ++{ ++ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; ++ ++ /* Reset packet profile */ ++ prPktProfile->fgIsValid = FALSE; ++ ++#if CFG_ENABLE_PER_STA_STATISTICS ++ nicTxLifetimeCheckByAC(prAdapter, prMsduInfo, prPacket, ucPriorityParam); ++#endif ++ ++#if CFG_PRINT_RTP_PROFILE ++ nicTxLifetimeCheckRTP(prAdapter, prMsduInfo, prPacket, u4PacketLen, ucNetworkType); ++#endif ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param ucPortIdx Port Number ++* @param prQue a link list of P_MSDU_INFO_T ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue) ++{ ++ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; ++ HIF_TX_HEADER_T rHwTxHeader; ++ P_NATIVE_PACKET prNativePacket; ++ UINT_16 u2OverallBufferLength; ++ UINT_8 ucEtherTypeOffsetInWord; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_32 u4TxHdrSize; ++ UINT_32 u4ValidBufSize; ++ UINT_32 u4TotalLength; ++ P_TX_CTRL_T prTxCtrl; ++ QUE_T rFreeQueue; ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ UINT_8 ucChksumFlag; ++#endif ++ ++ ASSERT(prAdapter); ++ ASSERT(ucPortIdx < 2); ++ ASSERT(prQue); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize; ++ ++#if CFG_HIF_STATISTICS ++ prTxCtrl->u4TotalTxAccessNum++; ++ prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem; ++#endif ++ ++ QUEUE_INITIALIZE(&rFreeQueue); ++ ++ if (prQue->u4NumElem > 0) { ++ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue); ++ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; ++ u4TotalLength = 0; ++ ++ while (prMsduInfo) { ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ UINT8 *pkt = prSkb->data; ++ UINT16 u2Identifier; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ DBGLOG(TX, TRACE, " %d\n", u2Identifier); ++ } ++ } ++#endif ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ kalMetProfilingFinish(prAdapter, prMsduInfo); ++#endif ++ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); ++ ++ prNativePacket = prMsduInfo->prPacket; ++ ++ ASSERT(prNativePacket); ++ ++ u4TxHdrSize = TX_HDR_SIZE; ++ ++ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & ++ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ /* init TX header */ ++ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; ++ rHwTxHeader.u2TxByteCount_UserPriority |= ++ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); ++ ++ if (prMsduInfo->fgIs802_11) { ++ ucEtherTypeOffsetInWord = ++ (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; ++ } else { ++ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; ++ } ++ ++ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; ++ ++ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; ++ rHwTxHeader.ucResource_PktType_CSflags |= ++ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & ++ (HIF_TX_HDR_PACKET_TYPE_MASK)); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ if (prAdapter->u4CSUMFlags & ++ (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) { ++ kalQueryTxChksumOffloadParam(prNativePacket, &ucChksumFlag); ++ ++ if (ucChksumFlag & TX_CS_IP_GEN) ++ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_IP_CSUM; ++ ++ if (ucChksumFlag & TX_CS_TCP_UDP_GEN) ++ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_TCP_CSUM; ++ } ++ } ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; ++ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; ++ rHwTxHeader.ucForwardingType_SessionID_Reserved = ++ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << ++ HIF_TX_HDR_PS_SESSION_ID_OFFSET) ++ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); ++ ++ rHwTxHeader.ucWlanHeaderLength = ++ (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); ++ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) ++ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & ++ HIF_TX_HDR_NETWORK_TYPE_MASK) ++ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & ++ HIF_TX_HDR_FLAG_1X_FRAME_MASK) ++ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & ++ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); ++ ++ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; ++ ++ if (prMsduInfo->pfTxDoneHandler) { ++ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; ++ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; ++ } else { ++ rHwTxHeader.ucPacketSeqNo = 0; ++ rHwTxHeader.ucAck_BIP_BasicRate = 0; ++ } ++ ++ if (prMsduInfo->fgNeedTxDoneStatus == TRUE) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_NEED_TX_DONE_STATUS; ++ ++ if (prMsduInfo->fgIsBIP) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; ++ ++ if (prMsduInfo->fgIsBasicRate) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ if (prMsduInfo->rPktProfile.fgIsValid) ++ prMsduInfo->rPktProfile.rDequeueTimestamp = kalGetTimeTick(); ++#endif ++ ++ /* record the queue time in driver */ ++ STATS_TX_TIME_TO_HIF(prMsduInfo, &rHwTxHeader); ++ ++#if CFG_SDIO_TX_AGG ++ /* attach to coalescing buffer */ ++ kalMemCopy(pucOutputBuf + u4TotalLength, &rHwTxHeader, u4TxHdrSize); ++ u4TotalLength += u4TxHdrSize; ++ ++ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) ++ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength); ++ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) ++ kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength); ++ else ++ ASSERT(0); ++ ++ u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength); ++ ++#else ++ kalMemCopy(pucOutputBuf, &rHwTxHeader, u4TxHdrSize); ++ ++ /* Copy Frame Body */ ++ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) ++ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TxHdrSize); ++ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) ++ kalMemCopy(pucOutputBuf + u4TxHdrSize, prNativePacket, prMsduInfo->u2FrameLength); ++ else ++ ASSERT(0); ++ ++ ASSERT(u2OverallBufferLength <= u4ValidBufSize); ++ ++ HAL_WRITE_TX_PORT(prAdapter, ++ ucPortIdx, ++ (UINT_32) u2OverallBufferLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); ++ ++ /* send immediately */ ++#endif ++ prNextMsduInfo = (P_MSDU_INFO_T) ++ QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry); ++ ++ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { ++ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ ++ if (prMsduInfo->pfTxDoneHandler == NULL) { ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } else { ++ KAL_SPIN_LOCK_DECLARATION(); ++ DBGLOG(TX, TRACE, "Wait TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ } ++ } else { ++ /* only free MSDU when it is not a MGMT frame */ ++ QUEUE_INSERT_TAIL(&rFreeQueue, (P_QUE_ENTRY_T) prMsduInfo); ++ ++ if (prMsduInfo->eSrc == TX_PACKET_OS) ++ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS); ++ else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) ++ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ } ++ ++#if CFG_SDIO_TX_AGG ++ ASSERT(u4TotalLength <= u4ValidBufSize); ++ ++#if CFG_DBG_GPIO_PINS ++ { ++ /* Start port write */ ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_LOW); ++ kalUdelay(1); ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_HIGH); ++ } ++#endif ++ ++ /* send coalescing buffer */ ++ HAL_WRITE_TX_PORT(prAdapter, ucPortIdx, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); ++#endif ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++#if CFG_SUPPORT_WFD && CFG_PRINT_RTP_PROFILE && !CFG_ENABLE_PER_STA_STATISTICS ++ do { ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ ++ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; ++ ++ if ((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000)) { ++ /* Enable profiling */ ++ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++ } else { ++ /* Skip profiling */ ++ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++ } ++ } while (FALSE); ++#else ++ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++#endif ++#else ++ /* return */ ++ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); ++#endif ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prPacketInfo Pointer of CMD_INFO_T ++* @param ucTC Specify the resource of TC ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) ++{ ++ P_WIFI_CMD_T prWifiCmd; ++ UINT_16 u2OverallBufferLength; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_8 ucPortIdx; ++ HIF_TX_HEADER_T rHwTxHeader; ++ P_NATIVE_PACKET prNativePacket; ++ UINT_8 ucEtherTypeOffsetInWord; ++ P_MSDU_INFO_T prMsduInfo; ++ P_TX_CTRL_T prTxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; ++ ++ /* <1> Assign Data Port */ ++ if (ucTC != TC4_INDEX) { ++ ucPortIdx = 0; ++ } else { ++ /* Broadcast/multicast data frames, 1x frames, command packets, MMPDU */ ++ ucPortIdx = 1; ++ } ++ wlanTraceTxCmd(prCmdInfo); ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { ++ /* <2> Compose HIF_TX_HEADER */ ++ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); ++ ++ prNativePacket = prCmdInfo->prPacket; ++ ++ ASSERT(prNativePacket); ++ ++ u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) ++ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ rHwTxHeader.u2TxByteCount_UserPriority = ((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) ++ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; ++ ++ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; ++ ++ rHwTxHeader.ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET); ++ ++ rHwTxHeader.ucStaRecIdx = prCmdInfo->ucStaRecIndex; ++ rHwTxHeader.ucForwardingType_SessionID_Reserved = HIF_TX_HDR_BURST_END_MASK; ++ ++ rHwTxHeader.ucWlanHeaderLength = (ETH_HLEN & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); ++ rHwTxHeader.ucPktFormtId_Flags = ++ (((UINT_8) (prCmdInfo->eNetworkType) << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & ++ HIF_TX_HDR_NETWORK_TYPE_MASK) ++ | ((1 << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK); ++ ++ rHwTxHeader.u2SeqNo = 0; ++ rHwTxHeader.ucPacketSeqNo = 0; ++ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_TX_DONE_STATUS; ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE /* | HIF_TX_HDR_RTS */; ++ ++ /* <2.3> Copy HIF TX HEADER */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); ++ ++ /* <3> Copy Frame Body Copy */ ++ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + TX_HDR_SIZE); ++ } else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; ++ ++ ASSERT(prMsduInfo->fgIs802_11 == TRUE); ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ /* <2> Compose HIF_TX_HEADER */ ++ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); ++ ++ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & ++ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; ++ rHwTxHeader.u2TxByteCount_UserPriority |= ++ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); ++ ++ ucEtherTypeOffsetInWord = (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; ++ ++ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; ++ ++ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; ++ rHwTxHeader.ucResource_PktType_CSflags |= ++ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & ++ (HIF_TX_HDR_PACKET_TYPE_MASK)); ++ ++ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; ++ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; ++ rHwTxHeader.ucForwardingType_SessionID_Reserved = ++ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << HIF_TX_HDR_PS_SESSION_ID_OFFSET) ++ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); ++ ++ rHwTxHeader.ucWlanHeaderLength = (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); ++ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) ++ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & HIF_TX_HDR_NETWORK_TYPE_MASK) ++ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK) ++ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & ++ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); ++ ++ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; ++ ++ if (prMsduInfo->pfTxDoneHandler) { ++ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; ++ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; ++ } else { ++ rHwTxHeader.ucPacketSeqNo = 0; ++ rHwTxHeader.ucAck_BIP_BasicRate = 0; ++ } ++ ++ if (prMsduInfo->fgIsBIP) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; ++ ++ if (prMsduInfo->fgIsBasicRate) ++ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; ++ /* <2.3> Copy HIF TX HEADER */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); ++ ++ /* <3> Copy Frame Body */ ++ kalMemCopy(pucOutputBuf + TX_HDR_SIZE, prMsduInfo->prPacket, prMsduInfo->u2FrameLength); ++ ++ /* <4> Management Frame Post-Processing */ ++ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ ++ if (prMsduInfo->pfTxDoneHandler == NULL) { ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } else { ++ ++ DBGLOG(TX, TRACE, "Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ } ++ } else { ++ prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer; ++ ++ /* <2> Compose the Header of Transmit Data Structure for CMD Packet */ ++ u2OverallBufferLength = ++ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ prWifiCmd->u2TxByteCount_UserPriority = u2OverallBufferLength; ++ prWifiCmd->ucEtherTypeOffset = 0; ++ prWifiCmd->ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET) ++ | (UINT_8) ((HIF_TX_PKT_TYPE_CMD << HIF_TX_HDR_PACKET_TYPE_OFFSET) & (HIF_TX_HDR_PACKET_TYPE_MASK)); ++ ++ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); ++ ++ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); ++ ++ if ((prCmdInfo->ucCID == CMD_ID_SCAN_REQ) || ++ (prCmdInfo->ucCID == CMD_ID_SCAN_CANCEL) || ++ (prCmdInfo->ucCID == CMD_ID_SCAN_REQ_V2)) ++ DBGLOG(TX, INFO, "ucCmdSeqNum =%d, ucCID =%d\n", prCmdInfo->ucCmdSeqNum, prCmdInfo->ucCID); ++ } ++ ++ /* <4> Write frame to data port */ ++ HAL_WRITE_TX_PORT(prAdapter, ++ ucPortIdx, ++ (UINT_32) u2OverallBufferLength, ++ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); ++ ++ return WLAN_STATUS_SUCCESS; ++} /* end of nicTxCmd() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function will clean up all the pending frames in internal SW Queues ++* by return the pending TX packet to the system. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxRelease(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ nicTxFlush(prAdapter); ++ ++ /* free MSDU_INFO_T from rTxMgmtMsduInfoList */ ++ do { ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); ++ ++ if (prMsduInfo) { ++ /* the packet must be mgmt frame with tx done callback */ ++ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); ++ ++ /* invoke done handler */ ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT); ++ ++ cnmMgtPktFree(prAdapter, prMsduInfo); ++ } else { ++ break; ++ } ++ } while (TRUE); ++ ++} /* end of nicTxRelease() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Process the TX Done interrupt and pull in more pending frames in SW ++* Queues for transmission. ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++#if CFG_SDIO_INTR_ENHANCE ++ P_SDIO_CTRL_T prSDIOCtrl; ++#else ++ UINT_32 au4TxCount[2]; ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ prGlueInfo->IsrTxCnt++; ++ ++ /* Get the TX STATUS */ ++#if CFG_SDIO_INTR_ENHANCE ++ ++ prSDIOCtrl = prAdapter->prSDIOCtrl; ++#if DBG ++ /* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */ ++#endif ++ ++ nicTxReleaseResource(prAdapter, (PUINT_8) &prSDIOCtrl->rTxInfo); ++ kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo)); ++ ++#else ++ ++ HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]); ++ HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]); ++ DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]); ++ ++ nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount); ++ ++#endif /* CFG_SDIO_INTR_ENHANCE */ ++ ++ nicTxAdjustTcq(prAdapter); ++ ++ /* Indicate Service Thread */ ++ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ ++} /* end of nicProcessTxInterrupt() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function frees packet of P_MSDU_INFO_T linked-list ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfoList a link list of P_MSDU_INFO_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_NATIVE_PACKET prNativePacket; ++ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead; ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfoListHead); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ while (prMsduInfo) { ++ prNativePacket = prMsduInfo->prPacket; ++ ++ if (prMsduInfo->eSrc == TX_PACKET_OS) { ++ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE); ++ } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) { ++ P_MSDU_INFO_T prTempMsduInfo = prMsduInfo; ++ ++ if (prMsduInfo->pfTxDoneHandler) ++ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); ++ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ cnmMgtPktFree(prAdapter, prTempMsduInfo); ++ continue; ++ } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); ++ } ++ ++ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfoList a link list of P_MSDU_INFO_T ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ ++ switch (prMsduInfo->eSrc) { ++ case TX_PACKET_FORWARDING: ++ wlanReturnPacket(prAdapter, prMsduInfo->prPacket); ++ break; ++ case TX_PACKET_OS: ++ case TX_PACKET_OS_OID: ++ case TX_PACKET_MGMT: ++ default: ++ break; ++ } ++ ++ /* Reset MSDU_INFO fields */ ++ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); ++ prMsduInfo = prNextMsduInfo; ++ }; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function fills packet information to P_MSDU_INFO_T ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prMsduInfo P_MSDU_INFO_T ++* @param prPacket P_NATIVE_PACKET ++* ++* @retval TRUE Success to extract information ++* @retval FALSE Fail to extract correct information ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_8 ucPriorityParam; ++ UINT_8 ucMacHeaderLen; ++ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; ++ BOOLEAN fgIs1x = FALSE; ++ BOOLEAN fgIsPAL = FALSE; ++ UINT_32 u4PacketLen; ++ ULONG u4SysTime; ++ UINT_8 ucNetworkType; ++ struct sk_buff *prSkb = (struct sk_buff *)prPacket; ++ ++ ASSERT(prAdapter); ++ ++ prGlueInfo = prAdapter->prGlueInfo; ++ ASSERT(prGlueInfo); ++ ++ if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo, ++ prPacket, ++ &ucPriorityParam, ++ &u4PacketLen, ++ aucEthDestAddr, ++ &fgIs1x, &fgIsPAL, &ucNetworkType, ++ NULL) == FALSE) { ++ return FALSE; ++ } ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ nicTxLifetimeCheck(prAdapter, prMsduInfo, prPacket, ucPriorityParam, u4PacketLen, ucNetworkType); ++#endif ++ ++ /* Save the value of Priority Parameter */ ++ GLUE_SET_PKT_TID(prPacket, ucPriorityParam); ++ ++ if (fgIs1x) ++ GLUE_SET_PKT_FLAG_1X(prPacket); ++ ++ if (fgIsPAL) ++ GLUE_SET_PKT_FLAG_PAL(prPacket); ++ ++ ucMacHeaderLen = ETH_HLEN; ++ ++ /* Save the value of Header Length */ ++ GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen); ++ ++ /* Save the value of Frame Length */ ++ GLUE_SET_PKT_FRAME_LEN(prPacket, (UINT_16) u4PacketLen); ++ ++ /* Save the value of Arrival Time */ ++ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); ++ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); ++ ++ prMsduInfo->prPacket = prPacket; ++ prMsduInfo->fgIs802_1x = fgIs1x; ++ prMsduInfo->fgIs802_11 = FALSE; ++ prMsduInfo->ucNetworkType = ucNetworkType; ++ prMsduInfo->ucUserPriority = ucPriorityParam; ++ prMsduInfo->ucMacHeaderLength = ucMacHeaderLen; ++ prMsduInfo->u2FrameLength = (UINT_16) u4PacketLen; ++ COPY_MAC_ADDR(prMsduInfo->aucEthDestAddr, aucEthDestAddr); ++ ++ if (prSkb->len > ETH_HLEN) ++ STATS_TX_PKT_CALLBACK(prSkb->data, prMsduInfo); ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function update TCQ values by passing current status to txAdjustTcQuotas ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Updated successfully ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4Num; ++ TX_TCQ_ADJUST_T rTcqAdjust; ++ P_TX_CTRL_T prTxCtrl; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ for (u4Num = 0; u4Num < TC_NUM; u4Num++) { ++ prTxCtrl->rTc.aucFreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num]; ++ prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num]; ++ } ++ ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief this function flushes all packets queued in STA/AC queue ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Flushed successfully ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter) ++{ ++ P_MSDU_INFO_T prMsduInfo; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ++ /* ask Per STA/AC queue to be fllushed and return all queued packets */ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prMsduInfo = qmFlushTxQueues(prAdapter); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ if (prMsduInfo != NULL) { ++ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo); ++ nicTxReturnMsduInfo(prAdapter, prMsduInfo); ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. ++* However this function is used for INIT_CMD. ++* ++* In order to avoid further maintenance issues, these 2 functions are separated ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prPacketInfo Pointer of CMD_INFO_T ++* @param ucTC Specify the resource of TC ++* ++* @retval WLAN_STATUS_SUCCESS Bus access ok. ++* @retval WLAN_STATUS_FAILURE Bus access fail. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) ++{ ++ P_INIT_HIF_TX_HEADER_T prInitTxHeader; ++ UINT_16 u2OverallBufferLength; ++ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ ++ UINT_32 ucPortIdx; ++ P_TX_CTRL_T prTxCtrl; ++ ++ ASSERT(prAdapter); ++ ASSERT(prCmdInfo); ++ ASSERT(ucTC == TC0_INDEX); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; ++ prInitTxHeader = (P_INIT_HIF_TX_HEADER_T) prCmdInfo->pucInfoBuffer; ++ ++ /* <1> Compose the Header of Transmit Data Structure for CMD Packet */ ++ u2OverallBufferLength = ++ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); ++ ++ prInitTxHeader->u2TxByteCount = u2OverallBufferLength; ++ prInitTxHeader->ucEtherTypeOffset = 0; ++ prInitTxHeader->ucCSflags = 0; ++ ++ /* <2> Assign Data Port */ ++ if (ucTC != TC4_INDEX) { ++ ucPortIdx = 0; ++ } else { /* Broadcast/multicast data packets */ ++ ucPortIdx = 1; ++ } ++ ++ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ ++ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); ++ ++ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); ++ ++ /* <4> Write frame to data port */ ++ HAL_WRITE_TX_PORT(prAdapter, ++ ucPortIdx, ++ (UINT_32) u2OverallBufferLength, ++ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief In this function, we'll reset TX resource counter to initial value used ++* in F/W download state ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval WLAN_STATUS_SUCCESS Reset is done successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ ++ DEBUGFUNC("nicTxInitResetResource"); ++ ++ ASSERT(prAdapter); ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; ++ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; ++ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; ++ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; ++ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; ++ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; ++ ++ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; ++ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; ++ ++ return WLAN_STATUS_SUCCESS; ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief this function enqueues MSDU_INFO_T into queue management, ++* or command queue ++* ++* @param prAdapter Pointer to the Adapter structure. ++* prMsduInfo Pointer to MSDU ++* ++* @retval WLAN_STATUS_SUCCESS Reset is done successfully. ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_TX_CTRL_T prTxCtrl; ++ P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead; ++ QUE_T qDataPort0, qDataPort1; ++ P_CMD_INFO_T prCmdInfo; ++ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; ++ ++ KAL_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prAdapter); ++ ASSERT(prMsduInfo); ++ ++ prTxCtrl = &prAdapter->rTxCtrl; ++ ASSERT(prTxCtrl); ++ ++ QUEUE_INITIALIZE(&qDataPort0); ++ QUEUE_INITIALIZE(&qDataPort1); ++ ++ /* check how many management frame are being queued */ ++ while (prMsduInfo) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); ++ ++ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; ++ ++ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { ++ /* MMPDU: force stick to TC4 */ ++ prMsduInfo->ucTC = TC4_INDEX; ++ ++ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); ++ } else { ++ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); ++ } ++ ++ prMsduInfo = prNextMsduInfo; ++ } ++ ++ if (qDataPort0.u4NumElem) { ++ /* send to QM: queue the packet to different TX queue by policy */ ++ KAL_SPIN_LOCK_DECLARATION(); ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort0)); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); ++ ++ /* post-process for "dropped" packets */ ++ if (prRetMsduInfo != NULL) { /* unable to enqueue */ ++ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo); ++ nicTxReturnMsduInfo(prAdapter, prRetMsduInfo); ++ } ++ } ++ ++ if (qDataPort1.u4NumElem) { ++ prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort1); ++ ++ if (qDataPort1.u4NumElem > nicTxGetFreeCmdCount(prAdapter)) { ++ /* not enough descriptors for sending */ ++ u4Status = WLAN_STATUS_FAILURE; ++ ++ /* free all MSDUs */ ++ while (prMsduInfoHead) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); ++ ++ if (prMsduInfoHead->pfTxDoneHandler != NULL) { ++ prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead, ++ TX_RESULT_DROPPED_IN_DRIVER); ++ } ++ ++ cnmMgtPktFree(prAdapter, prMsduInfoHead); ++ ++ prMsduInfoHead = prNextMsduInfo; ++ } ++ } else { ++ /* send to command queue */ ++ while (prMsduInfoHead) { ++ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); ++ ++ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); ++ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); ++ ++ if (prCmdInfo) { ++ GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); ++ ++ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); ++ ++ prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME; ++ prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength; ++ prCmdInfo->pucInfoBuffer = NULL; ++ prCmdInfo->prPacket = (P_NATIVE_PACKET) prMsduInfoHead; ++ prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex; ++ prCmdInfo->eNetworkType = prMsduInfoHead->ucNetworkType; ++ prCmdInfo->pfCmdDoneHandler = NULL; ++ prCmdInfo->pfCmdTimeoutHandler = NULL; ++ prCmdInfo->fgIsOid = FALSE; ++ prCmdInfo->fgSetQuery = TRUE; ++ prCmdInfo->fgNeedResp = FALSE; ++ ++ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); ++ } else { ++ /* Cmd free count is larger than expected, but allocation fail. */ ++ ASSERT(0); ++ ++ u4Status = WLAN_STATUS_FAILURE; ++ cnmMgtPktFree(prAdapter, prMsduInfoHead); ++ } ++ ++ prMsduInfoHead = prNextMsduInfo; ++ } ++ } ++ } ++ ++ /* indicate service thread for sending */ ++ if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0) ++ kalSetEvent(prAdapter->prGlueInfo); ++ ++ return u4Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief this function returns available count in command queue ++* ++* @param prAdapter Pointer to the Adapter structure. ++* ++* @retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter) ++{ ++ ASSERT(prAdapter); ++ ++ return prAdapter->rFreeCmdList.u4NumElem; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c +new file mode 100644 +index 000000000000..38e4569bc04f +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c +@@ -0,0 +1,192 @@ ++/* ++** Id: @(#) p2p_nic.c@@ ++*/ ++ ++/*! \file p2p_nic.c ++ \brief Wi-Fi Direct Functions that provide operation in NIC's (Network Interface Card) point of view. ++ ++ This file includes functions which unite multiple hal(Hardware) operations ++ and also take the responsibility of Software Resource Management in order ++ to keep the synchronization with Hardware Manipulation. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief When Probe Rsp & Beacon frame is received and decide a P2P device, ++* this function will be invoked to buffer scan result ++* ++* @param prAdapter Pointer to the Adapter structure. ++* @param prEventScanResult Pointer of EVENT_SCAN_RESULT_T. ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, ++ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength) ++{ ++ P_P2P_INFO_T prP2pInfo = (P_P2P_INFO_T) NULL; ++ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; ++ UINT_32 u4Idx = 0; ++ BOOLEAN bUpdate = FALSE; ++ ++ PUINT_8 pucIeBuf = (PUINT_8) NULL; ++ UINT_16 u2IELength = 0; ++ UINT_8 zeroMac[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; ++ ++ ASSERT(prAdapter); ++ ++ prP2pInfo = prAdapter->prP2pInfo; ++ ++ for (u4Idx = 0; u4Idx < prP2pInfo->u4DeviceNum; u4Idx++) { ++ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; ++ ++ if (EQUAL_MAC_ADDR(prTargetResult->aucDeviceAddr, prP2pResult->aucDeviceAddr)) { ++ bUpdate = TRUE; ++ ++ /* Backup OLD buffer result. */ ++ pucIeBuf = prTargetResult->pucIeBuf; ++ u2IELength = prTargetResult->u2IELength; ++ ++ /* Update Device Info. */ ++ /* zero */ ++ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* then buffer */ ++ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* See if new IE length is longer or not. */ ++ if ((u2RxIELength > u2IELength) && (u2IELength != 0)) { ++ /* Buffer is not enough. */ ++ u2RxIELength = u2IELength; ++ } else if ((u2IELength == 0) && (u2RxIELength != 0)) { ++ /* RX new IE buf. */ ++ ASSERT(pucIeBuf == NULL); ++ pucIeBuf = prP2pInfo->pucCurrIePtr; ++ ++ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > ++ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { ++ /* Common Buffer is no enough. */ ++ u2RxIELength = ++ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - ++ (ULONG) prP2pInfo->pucCurrIePtr); ++ } ++ ++ /* Step to next buffer address. */ ++ prP2pInfo->pucCurrIePtr = ++ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength); ++ } ++ ++ /* Restore buffer pointer. */ ++ prTargetResult->pucIeBuf = pucIeBuf; ++ ++ if (pucRxIEBuf) { ++ /* If new received IE is available. ++ * Replace the old one & update new IE length. ++ */ ++ kalMemCopy(pucIeBuf, pucRxIEBuf, u2RxIELength); ++ prTargetResult->u2IELength = u2RxIELength; ++ } else { ++ /* There is no new IE information, keep the old one. */ ++ prTargetResult->u2IELength = u2IELength; ++ } ++ } ++ } ++ ++ if (!bUpdate) { ++ /* We would flush the whole scan result after each scan request is issued. ++ * If P2P device is too many, it may over the scan list. ++ */ ++ if ((u4Idx < CFG_MAX_NUM_BSS_LIST) && (UNEQUAL_MAC_ADDR(zeroMac, prP2pResult->aucDeviceAddr))) { ++ /* whsu:XXX */ ++ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; ++ ++ /* zero */ ++ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* then buffer */ ++ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); ++ ++ /* printk("DVC FND %d %pM, %pM\n", ++ prP2pInfo->u4DeviceNum, ++ prP2pResult->aucDeviceAddr, ++ prTargetResult->aucDeviceAddr); */ ++ ++ if (u2RxIELength) { ++ prTargetResult->pucIeBuf = prP2pInfo->pucCurrIePtr; ++ ++ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > ++ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { ++ /* Common Buffer is no enough. */ ++ u2IELength = ++ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - ++ (ULONG) prP2pInfo->pucCurrIePtr); ++ } else { ++ u2IELength = u2RxIELength; ++ } ++ ++ prP2pInfo->pucCurrIePtr = ++ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2IELength); ++ ++ kalMemCopy((PVOID) prTargetResult->pucIeBuf, (PVOID) pucRxIEBuf, (UINT_32) u2IELength); ++ prTargetResult->u2IELength = u2IELength; ++ } else { ++ prTargetResult->pucIeBuf = NULL; ++ prTargetResult->u2IELength = 0; ++ } ++ ++ prP2pInfo->u4DeviceNum++; ++ ++ } else { ++ /* TODO: Fixme to replace an old one. (?) */ ++ ASSERT(FALSE); ++ } ++ } ++} /* nicRxAddP2pDevice */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c +new file mode 100644 +index 000000000000..dd00859d4608 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c +@@ -0,0 +1,5038 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/que_mgt.c#1 ++*/ ++ ++/*! \file "que_mgt.c" ++ \brief TX/RX queues management ++ ++ The main tasks of queue management include TC-based HIF TX flow control, ++ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save ++ forwarding control, RX packet reordering, and RX BA agreement management. ++*/ ++ ++/* ++** Log: que_mgt.c ++** ++** 04 11 2013 yuche.tsai ++** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. ++** Drop the probe response packet when absent. ++** ++** 04 09 2013 yuche.tsai ++** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. ++** Fix CMD buffer short issue. ++** ++** 04 09 2013 yuche.tsai ++** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. ++** Fix CMD buffer short issue. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 02 23 2012 eddie.chen ++ * [WCXRP00001194] [MT6620][DRV/FW] follow admission control bit to change the enqueue rule ++ * Change the enqueue policy when ACM = 1. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Code refine, remove one #if 0 code. ++ * ++ * 11 19 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog for tx ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 18 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Fix xlog format to hex format ++ * ++ * 11 17 2011 tsaiyuan.hsu ++ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. ++ * avoid deactivating staRec when changing state from 3 to 3. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug msg for xlog. ++ * ++ * 11 11 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters of bb and ar for xlog. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Use short name for xlog. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 10 2011 chinglan.wang ++ * NULL ++ * [WiFi WPS]Can't switch to new AP via WPS PBC when there existing a connection to another AP. ++ * ++ * 11 09 2011 chinglan.wang ++ * NULL ++ * [WiFi direct]Can't make P2P connect via PBC. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. ++ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to ++ * the AP.. ++ * ++ * 10 25 2011 wh.su ++ * [WCXRP00001059] [MT6620 Wi-Fi][Driver][P2P] Fixed sometimes data (1x) will not indicate to upper layer due ba check ++ * un-expect ++ * let the Rx BA accept even the sta not valid. ++ * ++ * 09 28 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * enlarge window size only by 4. ++ * ++ * 09 01 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * set rx window size as twice buffer size. ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix multicast address list issue. ++ * ++ * 08 03 2011 tsaiyuan.hsu ++ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX ++ * force window size at least 16. ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device ++ * issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 26 2011 eddie.chen ++ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter ++ * API for query the RX reorder queued packets counter. ++ * ++ * 07 07 2011 eddie.chen ++ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. ++ * Add setEvent when free quota is updated. ++ * ++ * 07 05 2011 eddie.chen ++ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. ++ * Send 1x when peer STA is in PS. ++ * ++ * 05 31 2011 eddie.chen ++ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 ++ * Fix the QM quota in MT5931. ++ * ++ * 05 11 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Fix dest type when GO packet copying. ++ * ++ * 05 09 2011 yuche.tsai ++ * [WCXRP00000712] [Volunteer Patch][MT6620][Driver] Sending deauth issue when Hot spot is disabled. (GO is dissolved) ++ * Deauthentication frame is not bound to network active status. ++ * ++ * 05 09 2011 eddie.chen ++ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet ++ * Check free number before copying broadcast packet. ++ * ++ * 04 14 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Check the SW RFB free. Fix the compile warning.. ++ * ++ * 04 12 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix the sta index in processing security frame ++ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 ++ * Add debug message. ++ * ++ * 04 11 2011 yuche.tsai ++ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. ++ * Fix kernel panic issue when MMPDU of P2P is pending in driver. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Fix Klockwork warning. ++ * ++ * 03 28 2011 eddie.chen ++ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW ++ * Fix wmm parameters in beacon for BOW. ++ * ++ * 03 15 2011 eddie.chen ++ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter ++ * Add sw debug counter for QM. ++ * ++ * 02 23 2011 eddie.chen ++ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap ++ * Fix parsing WMM INFO and bmp delivery bitmap definition. ++ * ++ * 02 17 2011 eddie.chen ++ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel ++ * 1) Change GetFrameAction decision when BSS is absent. ++ * 2) Check channel and resource in processing ProbeRequest ++ * ++ * 02 08 2011 eddie.chen ++ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode ++ * Add event STA agint timeout ++ * ++ * 01 27 2011 tsaiyuan.hsu ++ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support ++ * add roaming fsm ++ * 1. not support 11r, only use strength of signal to determine roaming. ++ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. ++ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw ++ * 4. assume that change of link quality in smooth way. ++ * ++ * 01 25 2011 yuche.tsai ++ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. ++ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Remove comments. ++ * ++ * 01 24 2011 eddie.chen ++ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets ++ * Add destination decision in AP mode. ++ * ++ * 01 14 2011 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out[WCXRP00000326] ++ * [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! ++ * Allow 802.1x can be send even the net is not active due the drver / fw sync issue. ++ * ++ * 01 13 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ * Fix typo and compile error. ++ * ++ * 01 12 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ * Fix WMM parameter condition for STA ++ * ++ * 01 12 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ * 1) Check Bss if support QoS before adding WMMIE ++ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control ++ * ++ * 01 12 2011 george.huang ++ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability ++ * Update MQM for WMM IE generation method ++ * ++ * 01 11 2011 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * Add per STA flow control when STA is in PS mode ++ * ++ * 01 03 2011 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * update prStaRec->fgIsUapsdSupported flag. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * Add WMM parameter for broadcast. ++ * ++ * 12 29 2010 eddie.chen ++ * [WCXRP00000322] Add WMM IE in beacon, ++Add per station flow control when STA is in PS ++ ++ * 1) PS flow control event ++ * ++ * 2) WMM IE in beacon, assoc resp, probe resp ++ * ++ * 12 23 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * 1. update WMM IE parsing, with ASSOC REQ handling ++ * 2. extend U-APSD parameter passing from driver to FW ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out ++ * use the #14 and modify the add code for check MMPDU. ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out ++ * only MMPDU not check the netActive flag. ++ * ++ * 10 14 2010 wh.su ++ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out ++ * not check the netActive flag for mgmt . ++ * ++ * 10 04 2010 cp.wu ++ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ++ * ENUM_NETWORK_TYPE_INDEX_T only ++ * remove ENUM_NETWORK_TYPE_T definitions ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 08 30 2010 yarco.yang ++ * NULL ++ * Fixed klockwork error message ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 10 2010 yarco.yang ++ * NULL ++ * Code refine ++ * ++ * 08 06 2010 yarco.yang ++ * NULL ++ * Update qmGetFrameAction() to allow P2P MGMT frame w/o STA_Record still can perform TX action ++ * ++ * 07 26 2010 cp.wu ++ * ++ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet ++ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found ++ * ++ * 07 20 2010 yarco.yang ++ * ++ * Add to SetEvent when BSS is from Absent to Present or STA from PS to Awake ++ * ++ * 07 16 2010 yarco.yang ++ * ++ * 1. Support BSS Absence/Presence Event ++ * 2. Support STA change PS mode Event ++ * 3. Support BMC forwarding for AP mode. ++ * ++ * 07 14 2010 yarco.yang ++ * ++ * 1. Remove CFG_MQM_MIGRATION ++ * 2. Add CMD_UPDATE_WMM_PARMS command ++ * ++ * 07 13 2010 yarco.yang ++ * ++ * [WPD00003849] ++ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing ++ * ++ * 07 09 2010 yarco.yang ++ * ++ * [MT6620 and MT5931] SW Migration: Add ADDBA support ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 07 08 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * . ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Use fgInUse instead of fgIsValid for De-queue judgement ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * For MMPDU, STA_REC will be decided by caller module ++ * ++ * 07 06 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Add MGMT Packet type for HIF_TX_HEADER ++ * ++ * 06 29 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * replace g_rQM with Adpater->rQM ++ * ++ * 06 25 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * add API in que_mgt to retrieve sta-rec index for security frames. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Support CFG_MQM_MIGRATION flag ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 31 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Refined the debug msg ++ * ++ * 03 30 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * comment out one assertion which refer to undefined data member. ++ * ++ * 03 30 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled adaptive TC resource control ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++ * ++* 03 17 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) ++ * ++ * 03 11 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Fixed buffer leak when processing BAR frames ++ * ++ * 03 02 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * For TX packets with STA_REC index = STA_REC_INDEX_NOT_FOUND, use TC5 ++ * ++ * 03 01 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Fixed STA_REC index determination bug (fgIsValid shall be checked) ++ * ++ * 02 25 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Refined function qmDetermineStaRecIndex() for BMCAST packets ++ * ++ * 02 25 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled multi-STA TX path with fairness ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled dynamically activating and deactivating STA_RECs ++ * ++ * 02 24 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Added code for dynamic activating and deactivating STA_RECs. ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the 802.1x path ++ * ++ * 01 13 2010 tehuang.liu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * Enabled the Burst_End Indication mechanism ++** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-14 15:01:37 GMT MTK02468 ++** Fixed casting for qmAddRxBaEntry() ++** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:51:03 GMT mtk02752 ++** remove SD1_SD3.. flag ++** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-09 14:07:25 GMT MTK02468 ++** Added RX buffer reordering functions ++** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-04 13:34:16 GMT MTK02468 ++** Modified Flush Queue function to let queues be reinitialized ++** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-04 13:18:25 GMT MTK02468 ++** Added flushing per-Type queues code ++** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 23:39:49 GMT MTK02468 ++** Added Debug msgs and fixed incorrect assert ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-26 23:50:27 GMT MTK02468 ++** Bug fixing (qmDequeueTxPackets local variable initialization) ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-26 09:39:25 GMT mtk02752 ++** correct and surpress PREfast warning ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-11-23 22:10:55 GMT mtk02468 ++** Used SD1_SD3_DATAPATH_INTEGRATION ++** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 22:02:30 GMT mtk02468 ++** Initial version ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++OS_SYSTIME g_arMissTimeout[CFG_STA_REC_NUM][CFG_RX_MAX_BA_TID_NUM]; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if ARP_MONITER_ENABLE ++static UINT_16 arpMoniter; ++static UINT_8 apIp[4]; ++#endif ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static inline VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++ ++static inline VOID ++qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, ++ OUT P_QUE_T prQue, ++ IN UINT_8 ucTC, IN UINT_8 ucCurrentAvailableQuota, IN UINT_8 ucTotalQuota); ++ ++static inline VOID ++qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Init Queue Management for TX ++* ++* \param[in] (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmInit(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 u4QueArrayIdx; ++ UINT_32 i; ++ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* DbgPrint("QM: Enter qmInit()\n"); */ ++#if CFG_SUPPORT_QOS ++ prAdapter->rWifiVar.fgSupportQoS = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportQoS = FALSE; ++#endif ++ ++#if CFG_SUPPORT_AMPDU_RX ++ prAdapter->rWifiVar.fgSupportAmpduRx = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportAmpduRx = FALSE; ++#endif ++ ++#if CFG_SUPPORT_AMPDU_TX ++ prAdapter->rWifiVar.fgSupportAmpduTx = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportAmpduTx = FALSE; ++#endif ++ ++#if CFG_SUPPORT_TSPEC ++ prAdapter->rWifiVar.fgSupportTspec = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportTspec = FALSE; ++#endif ++ ++#if CFG_SUPPORT_UAPSD ++ prAdapter->rWifiVar.fgSupportUAPSD = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportUAPSD = FALSE; ++#endif ++ ++#if CFG_SUPPORT_UL_PSMP ++ prAdapter->rWifiVar.fgSupportULPSMP = TRUE; ++#else ++ prAdapter->rWifiVar.fgSupportULPSMP = FALSE; ++#endif ++ ++#if CFG_SUPPORT_RX_SGI ++ prAdapter->rWifiVar.u8SupportRxSgi20 = 0; ++ prAdapter->rWifiVar.u8SupportRxSgi40 = 0; ++#else ++ prAdapter->rWifiVar.u8SupportRxSgi20 = 2; ++ prAdapter->rWifiVar.u8SupportRxSgi40 = 2; ++#endif ++ ++#if CFG_SUPPORT_RX_HT_GF ++ prAdapter->rWifiVar.u8SupportRxGf = 0; ++#else ++ prAdapter->rWifiVar.u8SupportRxGf = 2; ++#endif ++ ++ /* 4 <2> Initialize other TX queues (queues not in STA_RECs) */ ++ for (u4QueArrayIdx = 0; u4QueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; u4QueArrayIdx++) ++ QUEUE_INITIALIZE(&(prQM->arTxQueue[u4QueArrayIdx])); ++ ++ /* 4 <3> Initialize the RX BA table and RX queues */ ++ /* Initialize the RX Reordering Parameters and Queues */ ++ for (u4QueArrayIdx = 0; u4QueArrayIdx < CFG_NUM_OF_RX_BA_AGREEMENTS; u4QueArrayIdx++) { ++ prQM->arRxBaTable[u4QueArrayIdx].fgIsValid = FALSE; ++ QUEUE_INITIALIZE(&(prQM->arRxBaTable[u4QueArrayIdx].rReOrderQue)); ++ prQM->arRxBaTable[u4QueArrayIdx].u2WinStart = 0xFFFF; ++ prQM->arRxBaTable[u4QueArrayIdx].u2WinEnd = 0xFFFF; ++ ++ prQM->arRxBaTable[u4QueArrayIdx].fgIsWaitingForPktWithSsn = FALSE; ++ ++ } ++ prQM->ucRxBaCount = 0; ++ ++ kalMemSet(&g_arMissTimeout, 0, sizeof(g_arMissTimeout)); ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ /* 4 <4> Initialize TC resource control variables */ ++ for (i = 0; i < TC_NUM; i++) ++ prQM->au4AverageQueLen[i] = 0; ++ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; ++ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; ++ prQM->u4TxNumOfVi = 0; ++ prQM->u4TxNumOfVo = 0; ++ ++/* ASSERT(prQM->u4TimeToAdjust && prQM->u4TimeToUpdateQueLen); */ ++ ++ /* 1 20 1 1 4 1 */ ++ prQM->au4CurrentTcResource[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; ++ prQM->au4CurrentTcResource[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; ++ prQM->au4CurrentTcResource[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; ++ prQM->au4CurrentTcResource[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; ++ prQM->au4CurrentTcResource[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; /* Not adjustable (TX port 1) */ ++ prQM->au4CurrentTcResource[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC0 = %d\n", NIC_TX_BUFF_COUNT_TC0); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC1 = %d\n", NIC_TX_BUFF_COUNT_TC1); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC2 = %d\n", NIC_TX_BUFF_COUNT_TC2); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC3 = %d\n", NIC_TX_BUFF_COUNT_TC3); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC4 = %d\n", NIC_TX_BUFF_COUNT_TC4); ++ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC5 = %d\n", NIC_TX_BUFF_COUNT_TC5); ++ ++ /* 1 1 1 1 2 1 */ ++ prQM->au4MinReservedTcResource[TC0_INDEX] = QM_MIN_RESERVED_TC0_RESOURCE; ++ prQM->au4MinReservedTcResource[TC1_INDEX] = QM_MIN_RESERVED_TC1_RESOURCE; ++ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; ++ prQM->au4MinReservedTcResource[TC3_INDEX] = QM_MIN_RESERVED_TC3_RESOURCE; ++ prQM->au4MinReservedTcResource[TC4_INDEX] = QM_MIN_RESERVED_TC4_RESOURCE; /* Not adjustable (TX port 1) */ ++ prQM->au4MinReservedTcResource[TC5_INDEX] = QM_MIN_RESERVED_TC5_RESOURCE; ++ ++ /* 4 4 6 6 2 4 */ ++ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC3_INDEX] = QM_GUARANTEED_TC3_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC4_INDEX] = QM_GUARANTEED_TC4_RESOURCE; ++ prQM->au4GuaranteedTcResource[TC5_INDEX] = QM_GUARANTEED_TC5_RESOURCE; ++ ++ prQM->fgTcResourcePostAnnealing = FALSE; ++ ++ ASSERT(QM_INITIAL_RESIDUAL_TC_RESOURCE < 64); ++#endif ++ ++#if QM_TEST_MODE ++ prQM->u4PktCount = 0; ++ ++#if QM_TEST_FAIR_FORWARDING ++ ++ prQM->u4CurrentStaRecIndexToEnqueue = 0; ++ { ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ P_STA_RECORD_T prStaRec; ++ ++ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ ++ aucMacAddr[0] = 0x11; ++ aucMacAddr[1] = 0x22; ++ aucMacAddr[2] = 0xAA; ++ aucMacAddr[3] = 0xBB; ++ aucMacAddr[4] = 0xCC; ++ aucMacAddr[5] = 0xDD; ++ ++ prStaRec = &prAdapter->arStaRec[1]; ++ ASSERT(prStaRec); ++ ++ prStaRec->fgIsValid = TRUE; ++ prStaRec->fgIsQoS = TRUE; ++ prStaRec->fgIsInPS = FALSE; ++ prStaRec->ucPsSessionID = 0xFF; ++ prStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ prStaRec->fgIsAp = TRUE; ++ COPY_MAC_ADDR((prStaRec)->aucMacAddr, aucMacAddr); ++ ++ } ++ ++#endif ++ ++#endif ++ ++#if QM_FORWARDING_FAIRNESS ++ { ++ UINT_32 i; ++ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { ++ prQM->au4ForwardCount[i] = 0; ++ prQM->au4HeadStaRecIndex[i] = 0; ++ } ++ } ++#endif ++ ++#if QM_TC_RESOURCE_EMPTY_COUNTER ++ kalMemZero(prQM->au4QmTcResourceEmptyCounter, sizeof(prQM->au4QmTcResourceEmptyCounter)); ++#endif ++ ++} ++ ++#if QM_TEST_MODE ++VOID qmTestCases(IN P_ADAPTER_T prAdapter) ++{ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ DbgPrint("QM: ** TEST MODE **\n"); ++ ++ if (QM_TEST_STA_REC_DETERMINATION) { ++ if (prAdapter->arStaRec[0].fgIsValid) { ++ prAdapter->arStaRec[0].fgIsValid = FALSE; ++ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); ++ } else { ++ prAdapter->arStaRec[0].fgIsValid = TRUE; ++ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); ++ } ++ } ++ ++ if (QM_TEST_STA_REC_DEACTIVATION) { ++ /* Note that QM_STA_REC_HARD_CODING shall be set to 1 for this test */ ++ ++ if (prAdapter->arStaRec[0].fgIsValid) { ++ ++ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); ++ qmDeactivateStaRec(prAdapter, 0); ++ } else { ++ ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++ ++ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ ++ aucMacAddr[0] = 0x11; ++ aucMacAddr[1] = 0x22; ++ aucMacAddr[2] = 0xAA; ++ aucMacAddr[3] = 0xBB; ++ aucMacAddr[4] = 0xCC; ++ aucMacAddr[5] = 0xDD; ++ ++ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); ++ qmActivateStaRec(prAdapter, /* Adapter pointer */ ++ 0, /* STA_REC index from FW */ ++ TRUE, /* fgIsQoS */ ++ NETWORK_TYPE_AIS_INDEX, /* Network type */ ++ TRUE, /* fgIsAp */ ++ aucMacAddr /* MAC address */ ++ ); ++ } ++ } ++ ++ if (QM_TEST_FAIR_FORWARDING) { ++ if (prAdapter->arStaRec[1].fgIsValid) { ++ prQM->u4CurrentStaRecIndexToEnqueue++; ++ prQM->u4CurrentStaRecIndexToEnqueue %= 2; ++ DbgPrint("QM: (Test) Switch to STA_REC[%u]\n", prQM->u4CurrentStaRecIndexToEnqueue); ++ } ++ } ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Activate a STA_REC ++* ++* \param[in] prAdapter Pointer to the Adapter instance ++* \param[in] u4StaRecIdx The index of the STA_REC ++* \param[in] fgIsQoS Set to TRUE if this is a QoS STA ++* \param[in] pucMacAddr The MAC address of the STA ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) ++{ ++ ++ /* 4 <1> Deactivate first */ ++ ASSERT(prStaRec); ++ ++ if (prStaRec->fgIsValid) { /* The STA_REC has been activated */ ++ DBGLOG(QM, WARN, "QM: (WARNING) Activating a STA_REC which has been activated\n"); ++ DBGLOG(QM, WARN, "QM: (WARNING) Deactivating a STA_REC before re-activating\n"); ++ /* To flush TX/RX queues and del RX BA agreements */ ++ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); ++ } ++ /* 4 <2> Activate the STA_REC */ ++ /* Init the STA_REC */ ++ prStaRec->fgIsValid = TRUE; ++ prStaRec->fgIsInPS = FALSE; ++ prStaRec->ucPsSessionID = 0xFF; ++ prStaRec->fgIsAp = (IS_AP_STA(prStaRec)) ? TRUE : FALSE; ++ ++ /* Done in qmInit() or qmDeactivateStaRec() */ ++#if 0 ++ /* At the beginning, no RX BA agreements have been established */ ++ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) ++ (prStaRec->aprRxReorderParamRefTbl)[i] = NULL; ++#endif ++ ++ DBGLOG(QM, TRACE, "QM: +STA[%u]\n", (UINT_32) prStaRec->ucIndex); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Deactivate a STA_REC ++* ++* \param[in] prAdapter Pointer to the Adapter instance ++* \param[in] u4StaRecIdx The index of the STA_REC ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_32 i; ++ P_MSDU_INFO_T prFlushedTxPacketList = NULL; ++ ++ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* 4<1> Flush TX queues */ ++ prFlushedTxPacketList = qmFlushStaTxQueues(prAdapter, u4StaRecIdx); ++ ++ if (prFlushedTxPacketList) ++ wlanProcessQueuedMsduInfo(prAdapter, prFlushedTxPacketList); ++ /* 4 <2> Flush RX queues and delete RX BA agreements */ ++ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { ++ /* Delete the RX BA entry with TID = i */ ++ qmDelRxBaEntry(prAdapter, (UINT_8) u4StaRecIdx, (UINT_8) i, FALSE); ++ } ++ ++ /* 4 <3> Deactivate the STA_REC */ ++ prStaRec->fgIsValid = FALSE; ++ prStaRec->fgIsInPS = FALSE; ++ ++ /* To reduce printk for IOT sta to connect all the time, */ ++ /* DBGLOG(QM, INFO, ("QM: -STA[%ld]\n", u4StaRecIdx)); */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Deactivate a STA_REC ++* ++* \param[in] prAdapter Pointer to the Adapter instance ++* \param[in] u4StaRecIdx The index of the network ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ ++ P_QUE_MGT_T prQM; ++ P_QUE_T prQue; ++ QUE_T rNeedToFreeQue; ++ QUE_T rTempQue; ++ P_QUE_T prNeedToFreeQue; ++ P_QUE_T prTempQue; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ prQM = &prAdapter->rQM; ++ prQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; ++ ++ QUEUE_INITIALIZE(&rNeedToFreeQue); ++ QUEUE_INITIALIZE(&rTempQue); ++ ++ prNeedToFreeQue = &rNeedToFreeQue; ++ prTempQue = &rTempQue; ++ ++ QUEUE_MOVE_ALL(prTempQue, prQue); ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); ++ while (prMsduInfo) { ++ ++ if (prMsduInfo->ucNetworkType == eNetworkTypeIdx) { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(prNeedToFreeQue, (P_QUE_ENTRY_T) prMsduInfo); ++ } else { ++ /* QUEUE_INSERT_TAIL */ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prMsduInfo); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); ++ } ++ if (QUEUE_IS_NOT_EMPTY(prNeedToFreeQue)) ++ wlanProcessQueuedMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prNeedToFreeQue)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush all TX queues ++* ++* \param[in] (none) ++* ++* \return The flushed packets (in a list of MSDU_INFOs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_8 ucStaArrayIdx; ++ UINT_8 ucQueArrayIdx; ++ ++ P_MSDU_INFO_T prMsduInfoListHead; ++ P_MSDU_INFO_T prMsduInfoListTail; ++ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ DBGLOG(QM, TRACE, "QM: Enter qmFlushTxQueues()\n"); ++ ++ prMsduInfoListHead = NULL; ++ prMsduInfoListTail = NULL; ++ ++ /* Concatenate all MSDU_INFOs in per-STA queues */ ++ for (ucStaArrayIdx = 0; ucStaArrayIdx < CFG_NUM_OF_STA_RECORD; ucStaArrayIdx++) { ++ ++ /* Always check each STA_REC when flushing packets no matter it is inactive or active */ ++#if 0 ++ if (!prAdapter->arStaRec[ucStaArrayIdx].fgIsValid) ++ continue; /* Continue to check the next STA_REC */ ++#endif ++ ++ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { ++ if (QUEUE_IS_EMPTY(&(prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]))) ++ continue; /* Continue to check the next TX queue of the same STA */ ++ ++ if (!prMsduInfoListHead) { ++ ++ /* The first MSDU_INFO is found */ ++ prMsduInfoListHead = (P_MSDU_INFO_T) ++ QUEUE_GET_HEAD(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, ++ QUEUE_GET_HEAD(&prAdapter-> ++ arStaRec[ucStaArrayIdx].arTxQueue ++ [ucQueArrayIdx])); ++ ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ } ++ ++ QUEUE_INITIALIZE(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); ++ } ++ } ++ ++ /* Flush per-Type queues */ ++ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; ucQueArrayIdx++) { ++ ++ if (QUEUE_IS_EMPTY(&(prQM->arTxQueue[ucQueArrayIdx]))) ++ continue; /* Continue to check the next TX queue of the same STA */ ++ ++ if (!prMsduInfoListHead) { ++ ++ /* The first MSDU_INFO is found */ ++ prMsduInfoListHead = (P_MSDU_INFO_T) ++ QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx]); ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx])); ++ ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); ++ } ++ ++ QUEUE_INITIALIZE(&prQM->arTxQueue[ucQueArrayIdx]); ++ ++ } ++ ++ if (prMsduInfoListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, NULL); ++ } ++ ++ return prMsduInfoListHead; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush TX packets for a particular STA ++* ++* \param[in] u4StaRecIdx STA_REC index ++* ++* \return The flushed packets (in a list of MSDU_INFOs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) ++{ ++ UINT_8 ucQueArrayIdx; ++ P_MSDU_INFO_T prMsduInfoListHead; ++ P_MSDU_INFO_T prMsduInfoListTail; ++ P_STA_RECORD_T prStaRec; ++ ++ /* To reduce printk for IOT sta to connect all the time, */ ++ /* DBGLOG(QM, TRACE, ("QM: Enter qmFlushStaTxQueues(%ld)\n", u4StaRecIdx)); */ ++ ++ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ prMsduInfoListHead = NULL; ++ prMsduInfoListTail = NULL; ++ ++ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* No matter whether this is an activated STA_REC, do flush */ ++#if 0 ++ if (!prStaRec->fgIsValid) ++ return NULL; ++#endif ++ ++ /* Concatenate all MSDU_INFOs in TX queues of this STA_REC */ ++ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { ++ if (QUEUE_IS_EMPTY(&(prStaRec->arTxQueue[ucQueArrayIdx]))) ++ continue; ++ ++ if (!prMsduInfoListHead) { ++ /* The first MSDU_INFO is found */ ++ prMsduInfoListHead = (P_MSDU_INFO_T) ++ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ prMsduInfoListTail = (P_MSDU_INFO_T) ++ QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, ++ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx])); ++ ++ prMsduInfoListTail = (P_MSDU_INFO_T) QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ } ++ ++ QUEUE_INITIALIZE(&prStaRec->arTxQueue[ucQueArrayIdx]); ++ ++ } ++ ++#if 0 ++ if (prMsduInfoListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx)); ++ } else { ++ prMsduInfoListHead = nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx); ++ } ++#endif ++ ++ return prMsduInfoListHead; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush RX packets ++* ++* \param[in] (none) ++* ++* \return The flushed packets (in a list of SW_RFBs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i; ++ P_SW_RFB_T prSwRfbListHead; ++ P_SW_RFB_T prSwRfbListTail; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ prSwRfbListHead = prSwRfbListTail = NULL; ++ ++ DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n"); ++ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ if (QUEUE_IS_NOT_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) { ++ if (!prSwRfbListHead) { ++ ++ /* The first MSDU_INFO is found */ ++ prSwRfbListHead = (P_SW_RFB_T) ++ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue)); ++ prSwRfbListTail = (P_SW_RFB_T) ++ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); ++ } else { ++ /* Concatenate the MSDU_INFO list with the existing list */ ++ QM_TX_SET_NEXT_MSDU_INFO(prSwRfbListTail, ++ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue))); ++ ++ prSwRfbListTail = (P_SW_RFB_T) ++ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); ++ } ++ ++ QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue)); ++ ++ } else { ++ continue; ++ } ++ } ++ ++ if (prSwRfbListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); ++ } ++ return prSwRfbListHead; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Flush RX packets with respect to a particular STA ++* ++* \param[in] u4StaRecIdx STA_REC index ++* \param[in] u4Tid TID ++* ++* \return The flushed packets (in a list of SW_RFBs) ++*/ ++/*----------------------------------------------------------------------------*/ ++P_SW_RFB_T qmFlushStaRxQueue(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx, IN UINT_32 u4Tid) ++{ ++ /* UINT_32 i; */ ++ P_SW_RFB_T prSwRfbListHead; ++ P_SW_RFB_T prSwRfbListTail; ++ P_RX_BA_ENTRY_T prReorderQueParm; ++ P_STA_RECORD_T prStaRec; ++ ++ DBGLOG(QM, TRACE, "QM: Enter qmFlushStaRxQueues(%u)\n", u4StaRecIdx); ++ ++ prSwRfbListHead = prSwRfbListTail = NULL; ++ ++ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* No matter whether this is an activated STA_REC, do flush */ ++#if 0 ++ if (!prStaRec->fgIsValid) ++ return NULL; ++#endif ++ ++ /* Obtain the RX BA Entry pointer */ ++ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[u4Tid]); ++ ++ /* Note: For each queued packet, prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST */ ++ if (prReorderQueParm) { ++ ++ if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) { ++ ++ prSwRfbListHead = (P_SW_RFB_T) ++ QUEUE_GET_HEAD(&(prReorderQueParm->rReOrderQue)); ++ prSwRfbListTail = (P_SW_RFB_T) ++ QUEUE_GET_TAIL(&(prReorderQueParm->rReOrderQue)); ++ ++ QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue)); ++ ++ } ++ } ++ ++ if (prSwRfbListTail) { ++ /* Terminate the MSDU_INFO list with a NULL pointer */ ++ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); ++ } ++ return prSwRfbListHead; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Enqueue TX packets ++* ++* \param[in] prMsduInfoListHead Pointer to the list of TX packets ++* ++* \return The freed packets, which are not enqueued ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) ++{ ++ P_MSDU_INFO_T prMsduInfoReleaseList; ++ P_MSDU_INFO_T prCurrentMsduInfo; ++ P_MSDU_INFO_T prNextMsduInfo; ++ ++ P_STA_RECORD_T prStaRec; ++ QUE_T rNotEnqueuedQue; ++ P_QUE_T prTxQue = &rNotEnqueuedQue; ++ ++ UINT_8 ucPacketType; ++ UINT_8 ucTC; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ UINT_8 aucNextUP[WMM_AC_INDEX_NUM] = { 1 /* BEtoBK */ , 1 /*na */ , 0 /*VItoBE */ , 4 /*VOtoVI */ }; ++ ++ DBGLOG(QM, LOUD, "Enter qmEnqueueTxPackets\n"); ++ ++ ASSERT(prMsduInfoListHead); ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ { ++ /* UINT_32 i; */ ++ /* 4 <0> Update TC resource control related variables */ ++ /* Keep track of the queue length */ ++ if (--prQM->u4TimeToUpdateQueLen == 0) { /* -- only here */ ++ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; ++ qmUpdateAverageTxQueLen(prAdapter); ++ } ++ } ++#endif ++ ++ /* Push TX packets into STA_REC (for UNICAST) or prAdapter->rQM (for BMCAST) */ ++ prStaRec = NULL; ++ prMsduInfoReleaseList = NULL; ++ prCurrentMsduInfo = NULL; ++ QUEUE_INITIALIZE(&rNotEnqueuedQue); ++ prNextMsduInfo = prMsduInfoListHead; ++ ++ do { ++ P_BSS_INFO_T prBssInfo; ++ BOOLEAN fgCheckACMAgain; ++ ENUM_WMM_ACI_T eAci = WMM_AC_BE_INDEX; ++ ++ prCurrentMsduInfo = prNextMsduInfo; ++ prNextMsduInfo = QM_TX_GET_NEXT_MSDU_INFO(prCurrentMsduInfo); ++ ucTC = TC1_INDEX; ++ ++ /* 4 <1> Lookup the STA_REC index */ ++ /* The ucStaRecIndex will be set in this function */ ++ qmDetermineStaRecIndex(prAdapter, prCurrentMsduInfo); ++ ucPacketType = HIF_TX_PACKET_TYPE_DATA; ++ ++ STATS_ENV_REPORT_DETECT(prAdapter, prCurrentMsduInfo->ucStaRecIndex); ++ ++ DBGLOG(QM, LOUD, "***** ucStaRecIndex = %d *****\n", prCurrentMsduInfo->ucStaRecIndex); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prCurrentMsduInfo->ucNetworkType]); ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 0) ++ if (IS_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType)) { ++#else ++ /* force to send the loopback test packet */ ++ if (1) { ++ SET_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType); ++ prCurrentMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; ++ ucPacketType = HIF_TX_PKT_TYPE_HIF_LOOPBACK; ++#endif /* End of CONF_HIF_LOOPBACK_AUTO */ ++ ++ switch (prCurrentMsduInfo->ucStaRecIndex) { ++ case STA_REC_INDEX_BMCAST: ++ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; ++ ucTC = TC5_INDEX; ++#if 0 ++ if (prCurrentMsduInfo->ucNetworkType == NETWORK_TYPE_P2P_INDEX ++ && prCurrentMsduInfo->eSrc != TX_PACKET_MGMT) { ++ if (LINK_IS_EMPTY ++ (&prAdapter->rWifiVar. ++ arBssInfo[NETWORK_TYPE_P2P_INDEX].rStaRecOfClientList)) { ++ prTxQue = &rNotEnqueuedQue; ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_AP_BORADCAST_DROP); ++ } ++ } ++#endif ++ ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23); ++ break; ++ ++ case STA_REC_INDEX_NOT_FOUND: ++ ucTC = TC5_INDEX; ++ ++ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ ++ /* if the packet is the forward type. the packet should be freed */ ++ DBGLOG(QM, TRACE, "Forwarding packet but Sta is STA_REC_INDEX_NOT_FOUND\n"); ++ /* prTxQue = &rNotEnqueuedQue; */ ++ } ++ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_NO_STA_REC]; ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); ++ ++ break; ++ ++ default: ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prCurrentMsduInfo->ucStaRecIndex); ++ ++ if (!prStaRec) { ++ DBGLOG(QM, ERROR, "prStaRec is NULL\n"); ++ break; ++ } ++ ASSERT(prStaRec->fgIsValid); ++ ++ if (prCurrentMsduInfo->ucUserPriority < 8) { ++ QM_DBG_CNT_INC(prQM, prCurrentMsduInfo->ucUserPriority + 15); ++ /* QM_DBG_CNT_15 *//* QM_DBG_CNT_16 *//* QM_DBG_CNT_17 *//* QM_DBG_CNT_18 */ ++ /* QM_DBG_CNT_19 *//* QM_DBG_CNT_20 *//* QM_DBG_CNT_21 *//* QM_DBG_CNT_22 */ ++ } ++ ++ eAci = WMM_AC_BE_INDEX; ++ do { ++ fgCheckACMAgain = FALSE; ++ if (!prStaRec->fgIsQoS) { ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; ++ ucTC = TC1_INDEX; ++ break; ++ } ++ ++ switch (prCurrentMsduInfo->ucUserPriority) { ++ case 1: ++ case 2: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC0]; ++ ucTC = TC0_INDEX; ++ eAci = WMM_AC_BK_INDEX; ++ break; ++ case 0: ++ case 3: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; ++ ucTC = TC1_INDEX; ++ eAci = WMM_AC_BE_INDEX; ++ break; ++ case 4: ++ case 5: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC2]; ++ ucTC = TC2_INDEX; ++ eAci = WMM_AC_VI_INDEX; ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ prQM->u4TxNumOfVi++; ++#endif ++ break; ++ case 6: ++ case 7: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC3]; ++ ucTC = TC3_INDEX; ++ eAci = WMM_AC_VO_INDEX; ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ prQM->u4TxNumOfVo++; ++#endif ++ break; ++ default: ++ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; ++ ucTC = TC1_INDEX; ++ eAci = WMM_AC_BE_INDEX; ++ ASSERT(0); ++ break; ++ } ++ if (prBssInfo->arACQueParms[eAci].fgIsACMSet && eAci ++ != WMM_AC_BK_INDEX) { ++ prCurrentMsduInfo->ucUserPriority = aucNextUP[eAci]; ++ fgCheckACMAgain = TRUE; ++ } ++ } while (fgCheckACMAgain); ++ ++ /* LOG_FUNC ("QoS %u UP %u TC %u", */ ++ /* prStaRec->fgIsQoS,prCurrentMsduInfo->ucUserPriority, ucTC); */ ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ /* ++ In TDLS or AP mode, peer maybe enter "sleep mode". ++ ++ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, ++ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets ++ u4TimeToAdjustTcResource = 3, ++ then we will adjust TC resouce for VI or VO. ++ ++ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, ++ we will to wait about 12 seconds to collect 180 packets. ++ but the test time is only 20 seconds. ++ */ ++ if ((prQM->u4TxNumOfVi == 10) || (prQM->u4TxNumOfVo == 10)) { ++ /* force to do TC resouce update */ ++ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN; ++ prQM->u4TimeToAdjustTcResource = 1; ++ } ++#endif ++#if ARP_MONITER_ENABLE ++ if (IS_STA_IN_AIS(prStaRec) && prCurrentMsduInfo->eSrc == TX_PACKET_OS) ++ qmDetectArpNoResponse(prAdapter, prCurrentMsduInfo); ++#endif ++ ++ break; /*default */ ++ } /* switch (prCurrentMsduInfo->ucStaRecIndex) */ ++ ++ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { ++ if (prTxQue->u4NumElem > 32) { ++ DBGLOG(QM, WARN, ++ "Drop the Packet for full Tx queue (forwarding) Bss %u\n", ++ prCurrentMsduInfo->ucNetworkType); ++ prTxQue = &rNotEnqueuedQue; ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_FORWARD_OVERFLOW_DROP); ++ } ++ } ++ ++ } else { ++ ++ DBGLOG(QM, WARN, "Drop the Packet for inactive Bss %u\n", prCurrentMsduInfo->ucNetworkType); ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31); ++ prTxQue = &rNotEnqueuedQue; ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); ++ } ++ ++ /* 4 <3> Fill the MSDU_INFO for constructing HIF TX header */ ++ ++ /* TODO: Fill MSDU_INFO according to the network type, ++ * EtherType, and STA status (for PS forwarding control). ++ */ ++ ++ /* Note that the Network Type Index and STA_REC index are determined in ++ * qmDetermineStaRecIndex(prCurrentMsduInfo). ++ */ ++ QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(prCurrentMsduInfo, /* MSDU_INFO ptr */ ++ ucTC, /* TC tag */ ++ ucPacketType, /* Packet Type */ ++ 0, /* Format ID */ ++ prCurrentMsduInfo->fgIs802_1x, /* Flag 802.1x */ ++ prCurrentMsduInfo->fgIs802_11, /* Flag 802.11 */ ++ 0, /* PAL LLH */ ++ 0, /* ACL SN */ ++ PS_FORWARDING_TYPE_NON_PS, /* PS Forwarding Type */ ++ 0 /* PS Session ID */ ++ ); ++ ++ /* 4 <4> Enqueue the packet to different AC queue (max 5 AC queues) */ ++ QUEUE_INSERT_TAIL(prTxQue, (P_QUE_ENTRY_T) prCurrentMsduInfo); ++ ++ if (prTxQue != &rNotEnqueuedQue) { ++ prQM->u4EnqeueuCounter++; ++ prQM->au4ResourceWantedCounter[ucTC]++; ++ } ++ if (prStaRec) ++ prStaRec->u4EnqeueuCounter++; ++ ++#if QM_TC_RESOURCE_EMPTY_COUNTER ++ { ++ P_TX_CTRL_T prTxCtrl = &prAdapter->rTxCtrl; ++ ++ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] == 0) { ++ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC]++; ++ /* ++ DBGLOG(QM, TRACE, ("TC%d Q Empty Count: [%d]%ld\n", ++ ucTC, ++ prCurrentMsduInfo->ucNetworkType, ++ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC])); ++ */ ++ } ++ ++ } ++#endif ++ ++#if QM_TEST_MODE ++ if (++prQM->u4PktCount == QM_TEST_TRIGGER_TX_COUNT) { ++ prQM->u4PktCount = 0; ++ qmTestCases(prAdapter); ++ } ++#endif ++ ++ DBGLOG(QM, LOUD, "Current queue length = %u\n", prTxQue->u4NumElem); ++ } while (prNextMsduInfo); ++ ++ if (QUEUE_IS_NOT_EMPTY(&rNotEnqueuedQue)) { ++ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rNotEnqueuedQue), NULL); ++ prMsduInfoReleaseList = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rNotEnqueuedQue); ++ } ++ ++ return prMsduInfoReleaseList; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Determine the STA_REC index for a packet ++* ++* \param[in] prMsduInfo Pointer to the packet ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_32 i; ++ ++ P_STA_RECORD_T prTempStaRec; ++ /* P_QUE_MGT_T prQM = &prAdapter->rQM; */ ++ ++ prTempStaRec = NULL; ++ ++ ASSERT(prMsduInfo); ++ ++ /* 4 <1> DA = BMCAST */ ++ if (IS_BMCAST_MAC_ADDR(prMsduInfo->aucEthDestAddr)) { ++ /* For intrastructure mode and P2P (playing as a GC), BMCAST frames shall be sent to the AP. ++ * FW shall take care of this. The host driver is not able to distinguish these cases. */ ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; ++ DBGLOG(QM, LOUD, "TX with DA = BMCAST\n"); ++ return; ++ } ++#if (CFG_SUPPORT_TDLS == 1) ++ /* Check if the peer is TDLS one */ ++ if (TdlsexStaRecIdxGet(prAdapter, prMsduInfo) == TDLS_STATUS_SUCCESS) ++ return; /* find a TDLS record */ ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* 4 <2> Check if an AP STA is present */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ ++ if ((prTempStaRec->ucNetTypeIndex == prMsduInfo->ucNetworkType) ++ && (prTempStaRec->fgIsAp) ++ && (prTempStaRec->fgIsValid)) { ++ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; ++ return; ++ } ++ } ++ ++ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ if (prTempStaRec->fgIsValid) { ++ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prMsduInfo->aucEthDestAddr)) { ++ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; ++ return; ++ } ++ } ++ } ++ ++ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ ++ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; ++ DBGLOG(QM, LOUD, "QM: TX with STA_REC_INDEX_NOT_FOUND\n"); ++ ++#if (QM_TEST_MODE && QM_TEST_FAIR_FORWARDING) ++ prMsduInfo->ucStaRecIndex = (UINT_8) prQM->u4CurrentStaRecIndexToEnqueue; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dequeue TX packets from a STA_REC for a particular TC ++* ++* \param[out] prQue The queue to put the dequeued packets ++* \param[in] ucTC The TC index (TC0_INDEX to TC5_INDEX) ++* \param[in] ucMaxNum The maximum amount of dequeued packets ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, ++ OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucCurrentQuota, IN UINT_8 ucTotalQuota) ++{ ++ ++#if QM_FORWARDING_FAIRNESS ++ UINT_32 i; /* Loop for */ ++ ++ PUINT_32 pu4HeadStaRecIndex; /* The Head STA index */ ++ PUINT_32 pu4HeadStaRecForwardCount; /* The total forwarded packets for the head STA */ ++ ++ P_STA_RECORD_T prStaRec; /* The current focused STA */ ++ P_BSS_INFO_T prBssInfo; /* The Bss for current focused STA */ ++ P_QUE_T prCurrQueue; /* The current TX queue to dequeue */ ++ P_MSDU_INFO_T prDequeuedPkt; /* The dequeued packet */ ++ ++ UINT_32 u4ForwardCount; /* To remember the total forwarded packets for a STA */ ++ UINT_32 u4MaxForwardCount; /* The maximum number of packets a STA can forward */ ++ UINT_32 u4Resource; /* The TX resource amount */ ++ ++ BOOLEAN fgChangeHeadSta; /* Whether a new head STA shall be determined at the end of the function */ ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ PUINT_8 pucFreeQuota = NULL; ++#if CFG_ENABLE_WIFI_DIRECT ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; ++ /*NFC Beam + Indication */ ++#endif ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); ++ ++ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); ++ ++ if (!ucCurrentQuota) { ++ prQM->au4DequeueNoTcResourceCounter[ucTC]++; ++ DBGLOG(TX, LOUD, "@@@@@ TC = %u ucCurrentQuota = %u @@@@@\n", ucTC, ucCurrentQuota); ++ return; ++ } ++ ++ u4Resource = ucCurrentQuota; ++ ++ /* 4 <1> Determine the head STA */ ++ /* The head STA shall be an active STA */ ++ ++ pu4HeadStaRecIndex = &(prQM->au4HeadStaRecIndex[ucTC]); ++ pu4HeadStaRecForwardCount = &(prQM->au4ForwardCount[ucTC]); ++ ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Init Head STA = %u Resource = %u\n", ++ ucTC, *pu4HeadStaRecIndex, u4Resource); ++ ++ /* From STA[x] to STA[x+1] to STA[x+2] to ... to STA[x] */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD + 1; i++) { ++ prStaRec = &prAdapter->arStaRec[(*pu4HeadStaRecIndex)]; ++ ASSERT(prStaRec); ++ ++ /* Only Data frame (1x was not included) will be queued in */ ++ if (prStaRec->fgIsValid) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); ++ ++ /* Determine how many packets the head STA is allowed to send in a round */ ++ ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_25); ++ u4MaxForwardCount = ucTotalQuota; ++#if CFG_ENABLE_WIFI_DIRECT ++ ++ pucFreeQuota = NULL; ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ ++ /* u4MaxForwardCount = ucTotalQuota; */ ++ /* Per STA flow control when STA in PS mode */ ++ /* The PHASE 1: only update from ucFreeQuota (now) */ ++ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ ++ /* aucFreeQuotaPerQueue[] */ ++ /* NOTE: other method to set u4Resource */ ++ ++ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported ++ /* && prAdapter->rWifiVar.fgSupportQoS ++ && prAdapter->rWifiVar.fgSupportUAPSD */) { ++ ++ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; ++ } else { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } else { ++ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } /* fgIsInPS */ ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++ /*NFC Beam + Indication */ ++ ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { ++ if ((prChnlReqInfo->NFC_BEAM != 1) && ++ (u4MaxForwardCount > prBssInfo->ucBssFreeQuota)) ++ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; ++ } else { ++ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) ++ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; ++ } ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ /* Determine whether the head STA can continue to forward packets in this round */ ++ if ((*pu4HeadStaRecForwardCount) < u4MaxForwardCount) ++ break; ++ ++ } /* prStaRec->fgIsValid */ ++ else { ++ /* The current Head STA has been deactivated, so search for a new head STA */ ++ prStaRec = NULL; ++ prBssInfo = NULL; ++ (*pu4HeadStaRecIndex)++; ++ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; ++ ++ /* Reset the forwarding count before searching (since this is for a new selected STA) */ ++ (*pu4HeadStaRecForwardCount) = 0; ++ } ++ } /* i < CFG_NUM_OF_STA_RECORD + 1 */ ++ ++ /* All STA_RECs are inactive, so exit */ ++ if (!prStaRec) { ++ /* Under concurrent, it is possible that there is no candidcated STA. */ ++ /* DBGLOG(TX, EVENT, ("All STA_RECs are inactive\n")); */ ++ return; ++ } ++ ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Round Head STA = %u\n", ucTC, *pu4HeadStaRecIndex); ++ ++ /* 4 <2> Dequeue packets from the head STA */ ++ ++ prCurrQueue = &prStaRec->arTxQueue[ucTC]; ++ prDequeuedPkt = NULL; ++ fgChangeHeadSta = FALSE; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ if (pucFreeQuota != NULL) ++ TdlsexTxQuotaCheck(prAdapter->prGlueInfo, prStaRec, *pucFreeQuota); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ while (prCurrQueue) { ++ ++#if QM_DEBUG_COUNTER ++ ++ if (ucTC <= TC4_INDEX) { ++ if (QUEUE_IS_EMPTY(prCurrQueue)) { ++ QM_DBG_CNT_INC(prQM, ucTC); ++ /* QM_DBG_CNT_00 *//* QM_DBG_CNT_01 *//* QM_DBG_CNT_02 */ ++ /* QM_DBG_CNT_03 *//* QM_DBG_CNT_04 */ ++ } ++ if (u4Resource == 0) { ++ QM_DBG_CNT_INC(prQM, ucTC + 5); ++ /* QM_DBG_CNT_05 *//* QM_DBG_CNT_06 *//* QM_DBG_CNT_07 */ ++ /* QM_DBG_CNT_08 *//* QM_DBG_CNT_09 */ ++ } ++ if (((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { ++ QM_DBG_CNT_INC(prQM, ucTC + 10); ++ /* QM_DBG_CNT_10 *//* QM_DBG_CNT_11 *//* QM_DBG_CNT_12 */ ++ /* QM_DBG_CNT_13 *//* QM_DBG_CNT_14 */ ++ } ++ } ++#endif ++ ++ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ ++ if (QUEUE_IS_EMPTY(prCurrQueue) || ((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { ++ fgChangeHeadSta = TRUE; ++ break; ++ } else if (u4Resource == 0) { ++#if (CFG_SUPPORT_STATISTICS == 1) ++ prStaRec->u4NumOfNoTxQuota++; ++#endif /* CFG_SUPPORT_STATISTICS */ ++ break; ++ } ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ prStaRec->u4DeqeueuCounter++; ++ prQM->u4DequeueCounter++; ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ if (prDequeuedPkt != NULL) { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ UINT8 *pkt = prSkb->data; ++ UINT16 u2Identifier; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ DBGLOG(QM, LOUD, " %d\n", u2Identifier); ++ } ++ } ++#endif ++#if DBG && 0 ++ LOG_FUNC("Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prDequeuedPkt->ucTC, ++ prCurrQueue->u4NumElem, ++ prDequeuedPkt->ucNetworkType, ++ prDequeuedPkt->ucMacHeaderLength, ++ prDequeuedPkt->u2FrameLength, ++ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11); ++ ++ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); ++ ++#if LINUX ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ ++ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); ++ } ++#endif ++ ++#endif ++ ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ if (!QUEUE_IS_EMPTY(prCurrQueue)) { ++ /* XXX: check all queues for STA */ ++ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; ++ } ++ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ u4Resource--; ++ (*pu4HeadStaRecForwardCount)++; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ if ((pucFreeQuota) && (*pucFreeQuota > 0)) ++ *pucFreeQuota = *pucFreeQuota - 1; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (prBssInfo->ucBssFreeQuota > 0) ++ prBssInfo->ucBssFreeQuota--; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ } ++ ++ if (*pu4HeadStaRecForwardCount) { ++ DBGLOG(QM, LOUD, ++ "TC = %u Round Head STA = %u, u4HeadStaRecForwardCount = %u\n", ucTC, *pu4HeadStaRecIndex, ++ (*pu4HeadStaRecForwardCount)); ++ } ++#if QM_BURST_END_INFO_ENABLED ++ /* Let FW know which packet is the last one dequeued from the STA */ ++ if (prDequeuedPkt) ++ prDequeuedPkt->fgIsBurstEnd = TRUE; ++#endif ++ ++ /* 4 <3> Dequeue from the other STAs if there is residual TX resource */ ++ ++ /* Check all of the STAs to continue forwarding packets (including the head STA) */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ /* Break in case no reasource is available */ ++ if (u4Resource == 0) { ++ prQM->au4DequeueNoTcResourceCounter[ucTC]++; ++ break; ++ } ++ ++ /* The current head STA will be examined when i = CFG_NUM_OF_STA_RECORD-1 */ ++ prStaRec = &prAdapter->arStaRec[((*pu4HeadStaRecIndex) + i + 1) % CFG_NUM_OF_STA_RECORD]; ++ ASSERT(prStaRec); ++ ++ if (prStaRec->fgIsValid) { ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); ++ ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Sharing STA = %u Resource = %u\n", ++ ucTC, prStaRec->ucIndex, u4Resource); ++ ++ prCurrQueue = &prStaRec->arTxQueue[ucTC]; ++ u4ForwardCount = 0; ++ u4MaxForwardCount = ucTotalQuota; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ pucFreeQuota = NULL; ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ ++ /* u4MaxForwardCount = ucTotalQuota; */ ++ /* Per STA flow control when STA in PS mode */ ++ /* The PHASE 1: only update from ucFreeQuota (now) */ ++ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ ++ /* aucFreeQuotaPerQueue[] */ ++ /* NOTE: other method to set u4Resource */ ++ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported ++ /* && prAdapter->rWifiVar.fgSupportQoS ++ && prAdapter->rWifiVar.fgSupportUAPSD */) { ++ ++ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; ++ } else { ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } else { ++ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); ++ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; ++ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; ++ } ++ ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) ++ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ } /* prStaRec->fgIsValid */ ++ else { ++ prBssInfo = NULL; ++ /* Invalid STA, so check the next STA */ ++ continue; ++ } ++ ++ while (prCurrQueue) { ++ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ ++ if ((u4Resource == 0) || QUEUE_IS_EMPTY(prCurrQueue) || (u4ForwardCount >= u4MaxForwardCount)) ++ break; ++ ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ ++#if DBG && 0 ++ DBGLOG(QM, LOUD, "Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prDequeuedPkt->ucTC, ++ prCurrQueue->u4NumElem, ++ prDequeuedPkt->ucNetworkType, ++ prDequeuedPkt->ucMacHeaderLength, ++ prDequeuedPkt->u2FrameLength, ++ prDequeuedPkt->ucPacketType, ++ prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11)); ++ ++ DBGLOG(QM, LOUD, "Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); ++ ++#if LINUX ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ ++ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); ++ } ++#endif ++ ++#endif ++ ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ if (!QUEUE_IS_EMPTY(prCurrQueue)) ++ /* more data field ? */ ++ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; ++ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ if (prStaRec) ++ prStaRec->u4DeqeueuCounter++; ++ prQM->u4DequeueCounter++; ++ u4Resource--; ++ u4ForwardCount++; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ ++ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { ++ ASSERT(pucFreeQuota); ++ ASSERT(*pucFreeQuota > 0); ++ if (*pucFreeQuota > 0) ++ *pucFreeQuota = *pucFreeQuota - 1; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); ++ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { ++ if (prBssInfo->ucBssFreeQuota > 0) ++ prBssInfo->ucBssFreeQuota--; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT */ ++ ++ } ++ ++#if QM_BURST_END_INFO_ENABLED ++ /* Let FW know which packet is the last one dequeued from the STA */ ++ if (u4ForwardCount) ++ prDequeuedPkt->fgIsBurstEnd = TRUE; ++#endif ++ } ++ ++ if (fgChangeHeadSta) { ++ (*pu4HeadStaRecIndex)++; ++ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; ++ (*pu4HeadStaRecForwardCount) = 0; ++ DBGLOG(QM, LOUD, "(Fairness) TID = %u Scheduled Head STA = %u Left Resource = %u\n", ++ ucTC, (*pu4HeadStaRecIndex), u4Resource); ++ } ++ ++/***************************************************************************************/ ++#else ++ UINT_8 ucStaRecIndex; ++ P_STA_RECORD_T prStaRec; ++ P_QUE_T prCurrQueue; ++ UINT_8 ucPktCount; ++ P_MSDU_INFO_T prDequeuedPkt; ++ ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); ++ ++ if (ucCurrentQuota == 0) ++ return; ++ /* 4 <1> Determine the queue index and the head STA */ ++ ++ /* The head STA */ ++ ucStaRecIndex = 0; /* TODO: Get the current head STA */ ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ /* The queue to pull out packets */ ++ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); ++ prCurrQueue = &prStaRec->arTxQueue[ucTC]; ++ ++ ucPktCount = ucCurrentQuota; ++ prDequeuedPkt = NULL; ++ ++ /* 4 <2> Dequeue packets for the head STA */ ++ while (TRUE) { ++ if (!(prStaRec->fgIsValid) || ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) { ++ break; ++ ++ } else { ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ /* DbgPrint("QM: Remove Queue Head, TC= %d\n", prDequeuedPkt->ucTC); */ ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ ucPktCount--; ++ } ++ } ++ ++ /* DbgPrint("QM: Remaining number of queued packets = %d\n", prCurrQueue->u4NumElem); */ ++ ++#if QM_BURST_END_INFO_ENABLED ++ if (prDequeuedPkt) ++ prDequeuedPkt->fgIsBurstEnd = TRUE; ++#endif ++ ++ /* 4 <3> Update scheduling info */ ++ /* TODO */ ++ ++ /* 4 <4> Utilize the remainaing TX opportunities for non-head STAs */ ++ /* TODO */ ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dequeue TX packets from a per-Type-based Queue for a particular TC ++* ++* \param[out] prQue The queue to put the dequeued packets ++* \param[in] ucTC The TC index (Shall always be TC5_INDEX) ++* \param[in] ucMaxNum The maximum amount of dequeued packets ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID ++qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum) ++{ ++ /* UINT_8 ucQueIndex; */ ++ /* UINT_8 ucStaRecIndex; */ ++ P_BSS_INFO_T prBssInfo; ++ P_BSS_INFO_T parBssInfo; ++ P_QUE_T prCurrQueue; ++ UINT_8 ucPktCount; ++ P_MSDU_INFO_T prDequeuedPkt; ++ P_MSDU_INFO_T prBurstEndPkt; ++ QUE_T rMergeQue; ++ P_QUE_T prMergeQue; ++ P_QUE_MGT_T prQM; ++ ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerTypeQueues (TC = %d, Max = %d)\n", ucTC, ucMaxNum); ++ ++ /* TC5: Broadcast/Multicast data packets */ ++ ASSERT(ucTC == TC5_INDEX); ++ ++ if (ucMaxNum == 0) ++ return; ++ ++ prQM = &prAdapter->rQM; ++ /* 4 <1> Determine the queue */ ++ ++ prCurrQueue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; ++ ucPktCount = ucMaxNum; ++ prDequeuedPkt = NULL; ++ prBurstEndPkt = NULL; ++ ++ parBssInfo = prAdapter->rWifiVar.arBssInfo; ++ ++ QUEUE_INITIALIZE(&rMergeQue); ++ prMergeQue = &rMergeQue; ++ ++ /* 4 <2> Dequeue packets */ ++ while (TRUE) { ++ if (ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) ++ break; ++ ++ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); ++ ASSERT(prDequeuedPkt->ucTC == ucTC); ++ ++ ASSERT(prDequeuedPkt->ucNetworkType < NETWORK_TYPE_INDEX_NUM); ++ ++ prBssInfo = &parBssInfo[prDequeuedPkt->ucNetworkType]; ++ ++ if (IS_BSS_ACTIVE(prBssInfo)) { ++ if (!prBssInfo->fgIsNetAbsent) { ++ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ prQM->u4DequeueCounter++; ++ prBurstEndPkt = prDequeuedPkt; ++ ucPktCount--; ++ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_26); ++#if DBG && 0 ++ LOG_FUNC ++ ("DeqType TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", ++ prDequeuedPkt->ucTC, prCurrQueue->u4NumElem, prDequeuedPkt->ucNetworkType, ++ prDequeuedPkt->ucMacHeaderLength, prDequeuedPkt->u2FrameLength, ++ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, ++ prDequeuedPkt->fgIs802_11); ++ ++ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); ++ ++#if LINUX ++ { ++ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; ++ ++ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); ++ } ++#endif ++ ++#endif ++ } else { ++ QUEUE_INSERT_TAIL(prMergeQue, (P_QUE_ENTRY_T) prDequeuedPkt); ++ } ++ } else { ++ QM_TX_SET_NEXT_MSDU_INFO(prDequeuedPkt, NULL); ++ wlanProcessQueuedMsduInfo(prAdapter, prDequeuedPkt); ++ } ++ } ++ ++ if (QUEUE_IS_NOT_EMPTY(prMergeQue)) { ++ QUEUE_CONCATENATE_QUEUES(prMergeQue, prCurrQueue); ++ QUEUE_MOVE_ALL(prCurrQueue, prMergeQue); ++ if (QUEUE_GET_TAIL(prCurrQueue)) ++ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(prCurrQueue), NULL); ++ } ++#if QM_BURST_END_INFO_ENABLED ++ if (prBurstEndPkt) ++ prBurstEndPkt->fgIsBurstEnd = TRUE; ++#endif ++} /* qmDequeueTxPacketsFromPerTypeQueues */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dequeue TX packets to send to HIF TX ++* ++* \param[in] prTcqStatus Info about the maximum amount of dequeued packets ++* ++* \return The list of dequeued TX packets ++*/ ++/*----------------------------------------------------------------------------*/ ++P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus) ++{ ++ ++ INT32 i; ++ P_MSDU_INFO_T prReturnedPacketListHead; ++ QUE_T rReturnedQue; ++ ++ DBGLOG(QM, LOUD, "Enter qmDequeueTxPackets\n"); ++ ++ QUEUE_INITIALIZE(&rReturnedQue); ++ ++ prReturnedPacketListHead = NULL; ++ ++ /* dequeue packets from different AC queue based on available aucFreeBufferCount */ ++ /* TC0 to TC4: AC0~AC3, 802.1x (commands packets are not handled by QM) */ ++ for (i = TC4_INDEX; i >= TC0_INDEX; i--) { ++ DBGLOG(QM, LOUD, "Dequeue packets from Per-STA queue[%d]\n", i); ++ ++ /* ++ in the function, we will re-calculate the ucFreeQuota. ++ If any packet with any priority for the station will be sent, ucFreeQuota -- ++ ++ Note1: ucFreeQuota will be decrease only when station is in power save mode. ++ In active mode, we will sent the packet to the air directly. ++ ++ if(prStaRec->fgIsInPS && (ucTC!=TC4_INDEX)) { ++ ASSERT(pucFreeQuota); ++ ASSERT(*pucFreeQuota>0); ++ if ((pucFreeQuota) && (*pucFreeQuota>0)) { ++ *pucFreeQuota = *pucFreeQuota - 1; ++ } ++ } ++ ++ Note2: maximum queued number for a station is 10, TXM_MAX_BUFFER_PER_STA_DEF in fw ++ i.e. default prStaRec->ucFreeQuota = 10 ++ ++ Note3: In qmUpdateFreeQuota(), we will adjust ++ ucFreeQuotaForNonDelivery = ucFreeQuota>>1; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ */ ++ qmDequeueTxPacketsFromPerStaQueues(prAdapter, ++ &rReturnedQue, ++ (UINT_8) i, ++ prTcqStatus->aucFreeBufferCount[i], /* maximum dequeue number */ ++ prTcqStatus->aucMaxNumOfBuffer[i]); ++ ++ /* The aggregate number of dequeued packets */ ++ DBGLOG(QM, LOUD, "DQA)[%u](%u)\n", i, rReturnedQue.u4NumElem); ++ } ++ ++ /* TC5 (BMCAST or STA-NOT-FOUND packets) */ ++ qmDequeueTxPacketsFromPerTypeQueues(prAdapter, ++ &rReturnedQue, TC5_INDEX, prTcqStatus->aucFreeBufferCount[TC5_INDEX] ++ ); ++ ++ DBGLOG(QM, LOUD, "Current total number of dequeued packets = %u\n", rReturnedQue.u4NumElem); ++ ++ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) { ++ prReturnedPacketListHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rReturnedQue); ++ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); ++ } ++ ++ return prReturnedPacketListHead; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Adjust the TC quotas according to traffic demands ++* ++* \param[out] prTcqAdjust The resulting adjustment ++* \param[in] prTcqStatus Info about the current TC quotas and counters ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus) ++{ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++ UINT_32 i; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* Must reset */ ++ for (i = 0; i < TC_NUM; i++) ++ prTcqAdjust->acVariation[i] = 0; ++ ++ /* 4 <1> If TC resource is not just adjusted, exit directly */ ++ if (!prQM->fgTcResourcePostAnnealing) ++ return; ++ /* 4 <2> Adjust TcqStatus according to the updated prQM->au4CurrentTcResource */ ++ else { ++ INT_32 i4TotalExtraQuota = 0; ++ INT_32 ai4ExtraQuota[TC_NUM]; ++ BOOLEAN fgResourceRedistributed = TRUE; ++ ++ /* Obtain the free-to-distribute resource */ ++ for (i = 0; i < TC_NUM; i++) { ++ ai4ExtraQuota[i] = ++ (INT_32) prTcqStatus->aucMaxNumOfBuffer[i] - (INT_32) prQM->au4CurrentTcResource[i]; ++ ++ if (ai4ExtraQuota[i] > 0) { /* The resource shall be reallocated to other TCs */ ++ ++ if (ai4ExtraQuota[i] > prTcqStatus->aucFreeBufferCount[i]) { ++ /* ++ we have residunt TC resources for the TC: ++ EX: aucMaxNumOfBuffer[] = 20, au4CurrentTcResource[] = 5 ++ ai4ExtraQuota[] = 15, aucFreeBufferCount[] = 10 ++ ++ so ai4ExtraQuota[] = aucFreeBufferCount[] = 10 ++ because we available TC resources actually is 10, not 20 ++ */ ++ ai4ExtraQuota[i] = prTcqStatus->aucFreeBufferCount[i]; ++ ++ /* ++ FALSE means we can re-do TC resource adjustment in tx done ++ at next time, maybe more tx done is finished ++ */ ++ fgResourceRedistributed = FALSE; ++ } ++ ++ /* accumulate current all available TC resources */ ++ i4TotalExtraQuota += ai4ExtraQuota[i]; ++ ++ /* deduce unused TC resources for the TC */ ++ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); ++ } ++ } ++ ++ /* Distribute quotas to TCs which need extra resource according to prQM->au4CurrentTcResource */ ++ for (i = 0; i < TC_NUM; i++) { ++ if (ai4ExtraQuota[i] < 0) { ++ ++ /* The TC needs extra resources */ ++ if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) { ++ /* the number of needed extra resources is larger than total available */ ++ ai4ExtraQuota[i] = (-i4TotalExtraQuota); ++ ++ /* wait for next tx done to do adjustment */ ++ fgResourceRedistributed = FALSE; ++ } ++ ++ /* decrease the total available */ ++ i4TotalExtraQuota += ai4ExtraQuota[i]; ++ ++ /* mark to increase TC resources for the TC */ ++ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); ++ } ++ } ++ ++ /* In case some TC is waiting for TX Done, continue to adjust TC quotas upon TX Done */ ++ ++ /* ++ if fgResourceRedistributed == TRUE, it means we will adjust at this time so ++ we need to re-adjust TC resources (fgTcResourcePostAnnealing = FALSE). ++ */ ++ prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed); ++ ++#if QM_PRINT_TC_RESOURCE_CTRL ++ DBGLOG(QM, LOUD, "QM: Curr Quota [0]=%u [1]=%u [2]=%u [3]=%u [4]=%u [5]=%u\n", ++ prTcqStatus->aucFreeBufferCount[0], ++ prTcqStatus->aucFreeBufferCount[1], ++ prTcqStatus->aucFreeBufferCount[2], ++ prTcqStatus->aucFreeBufferCount[3], ++ prTcqStatus->aucFreeBufferCount[4], prTcqStatus->aucFreeBufferCount[5] ++ )); ++#endif ++ } ++ ++#else ++ UINT_32 i; ++ ++ for (i = 0; i < TC_NUM; i++) ++ prTcqAdjust->acVariation[i] = 0; ++ ++#endif ++} ++ ++#if QM_ADAPTIVE_TC_RESOURCE_CTRL ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Update the average TX queue length for the TC resource control mechanism ++* ++* \param (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter) ++{ ++ INT_32 u4CurrQueLen, i, k; ++ P_STA_RECORD_T prStaRec; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* 4 <1> Update the queue lengths for TC0 to TC3 (skip TC4) and TC5 */ ++ /* use moving average algorithm to calculate au4AverageQueLen for every TC queue */ ++ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES - 1; i++) { ++ u4CurrQueLen = 0; ++ ++ for (k = 0; k < CFG_NUM_OF_STA_RECORD; k++) { ++ prStaRec = &prAdapter->arStaRec[k]; ++ ASSERT(prStaRec); ++ ++ /* If the STA is activated, get the queue length */ ++ if (prStaRec->fgIsValid && ++ (!prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].fgIsNetAbsent) ++ ) { ++ ++ u4CurrQueLen += (prStaRec->arTxQueue[i].u4NumElem); ++ } ++ } ++ ++ if (prQM->au4AverageQueLen[i] == 0) { ++ prQM->au4AverageQueLen[i] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); /* *8 */ ++ } else { ++ /* len => len - len/8 = 7/8 * len + new len */ ++ prQM->au4AverageQueLen[i] -= (prQM->au4AverageQueLen[i] >> QM_QUE_LEN_MOVING_AVE_FACTOR); ++ prQM->au4AverageQueLen[i] += (u4CurrQueLen); ++ } ++ ++ } ++ ++ /* Update the queue length for TC5 (BMCAST) */ ++ u4CurrQueLen = prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST].u4NumElem; ++ ++ if (prQM->au4AverageQueLen[TC_NUM - 1] == 0) { ++ prQM->au4AverageQueLen[TC_NUM - 1] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); ++ } else { ++ prQM->au4AverageQueLen[TC_NUM - 1] -= ++ (prQM->au4AverageQueLen[TC_NUM - 1] >> QM_QUE_LEN_MOVING_AVE_FACTOR); ++ prQM->au4AverageQueLen[TC_NUM - 1] += (u4CurrQueLen); ++ } ++ ++ /* 4 <2> Adjust TC resource assignment every 3 times */ ++ /* Check whether it is time to adjust the TC resource assignment */ ++ if (--prQM->u4TimeToAdjustTcResource == 0) { /* u4TimeToAdjustTcResource = 3 */ ++ ++ /* The last assignment has not been completely applied */ ++ if (prQM->fgTcResourcePostAnnealing) { ++ /* Upon the next qmUpdateAverageTxQueLen function call, do this check again */ ++ ++ /* wait for next time to do qmReassignTcResource */ ++ prQM->u4TimeToAdjustTcResource = 1; ++ } else { /* The last assignment has been applied */ ++ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; ++ qmReassignTcResource(prAdapter); ++ } ++ } ++ ++ /* Debug */ ++#if QM_PRINT_TC_RESOURCE_CTRL ++ for (i = 0; i < TC_NUM; i++) { ++ if (QM_GET_TX_QUEUE_LEN(prAdapter, i) >= 100) { ++ DBGLOG(QM, LOUD, "QM: QueLen [%u %u %u %u %u %u]\n", ++ QM_GET_TX_QUEUE_LEN(prAdapter, 0), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 1), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 2), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 3), ++ QM_GET_TX_QUEUE_LEN(prAdapter, 4), QM_GET_TX_QUEUE_LEN(prAdapter, 5) ++ )); ++ break; ++ } ++ } ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Assign TX resource for each TC according to TX queue length and current assignment ++* ++* \param (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter) ++{ ++ INT_32 i4TotalResourceDemand = 0; ++ UINT_32 u4ResidualResource = 0; ++ UINT_32 i; ++ INT_32 ai4PerTcResourceDemand[TC_NUM]; ++ UINT_32 u4ShareCount = 0; ++ UINT_32 u4Share = 0; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* Note: After the new assignment is obtained, set prQM->fgTcResourcePostAnnealing to TRUE to ++ * start the TC-quota adjusting procedure, which will be invoked upon every TX Done ++ */ ++ /* tx done -> nicProcessTxInterrupt() -> nicTxAdjustTcq() ++ * -> qmAdjustTcQuotas() -> check fgTcResourcePostAnnealing */ ++ ++ /* 4 <1> Determine the demands */ ++ /* Determine the amount of extra resource to fulfill all of the demands */ ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4, which is not adjustable */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ /* ++ Define: extra_demand = average que_length (includes all station records) + ++ min_reserved_quota - ++ current available TC resources ++ ++ extra_demand means we need extra TC resources to transmit; other TCs can ++ borrow their resources to us? ++ */ ++ ai4PerTcResourceDemand[i] = ++ ((UINT_32) (QM_GET_TX_QUEUE_LEN(prAdapter, i)) + ++ prQM->au4MinReservedTcResource[i] - prQM->au4CurrentTcResource[i]); ++ ++ /* If there are queued packets, allocate extra resource for the TC (for TCP consideration) */ ++ if (QM_GET_TX_QUEUE_LEN(prAdapter, i)) ++ ai4PerTcResourceDemand[i] += QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY; /* 0 */ ++ ++ /* ++ accumulate all needed extra TC resources ++ maybe someone need + resource, maybe someone need - resource ++ */ ++ i4TotalResourceDemand += ai4PerTcResourceDemand[i]; ++ } ++ ++ /* 4 <2> Case 1: Demand <= Total Resource */ ++ if (i4TotalResourceDemand <= 0) { ++ /* 4 <2.1> Satisfy every TC */ ++ /* total TC resources are enough, no extra TC resources is needed */ ++ ++ /* adjust used TC resources to average TC resources + min reserve TC resources */ ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4 (not adjustable) */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ /* ++ the number of resources that one TC releases can be used for ++ other TCs ++ ++ EX: TC0 au4CurrentTcResource[0] = 10 ai4PerTcResourceDemand[0] = -5 ++ TC1 au4CurrentTcResource[1] = 5 ai4PerTcResourceDemand[0] = +5 ++ => TC0 au4CurrentTcResource[0] = 10 + (-5) = 5 ++ TC1 au4CurrentTcResource[1] = 5 + (+5) = 10 ++ */ ++ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; ++ } ++ ++ /* 4 <2.2> Share the residual resource evenly */ ++ u4ShareCount = (TC_NUM - 1); /* 5, excluding TC4 */ ++ ++ /* ++ EX: i4TotalResourceDemand = -10 ++ means we have 10 available resources can be used. ++ */ ++ u4ResidualResource = (UINT_32) (-i4TotalResourceDemand); ++ u4Share = (u4ResidualResource / u4ShareCount); ++ ++ /* share available TC resources to all TCs averagely */ ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4 (not adjustable) */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ /* allocate residual average resources to the TC */ ++ prQM->au4CurrentTcResource[i] += u4Share; ++ ++ /* Every TC is fully satisfied so no need extra resources */ ++ ai4PerTcResourceDemand[i] = 0; ++ ++ /* decrease the allocated resources */ ++ u4ResidualResource -= u4Share; ++ } ++ ++ /* if still have available resources, we decide to give them to VO (TC3) queue */ ++ /* 4 <2.3> Allocate the left resource to TC3 (VO) */ ++ prQM->au4CurrentTcResource[TC3_INDEX] += (u4ResidualResource); ++ ++ } ++ /* 4 <3> Case 2: Demand > Total Resource --> Guarantee a minimum amount of resource for each TC */ ++ else { ++ /* ++ u4ResidualResource means we at least need to keep ++ QM_INITIAL_RESIDUAL_TC_RESOURCE available TC resources ++ ++ in 6628, u4ResidualResource = 26, max 28 ++ */ ++ u4ResidualResource = QM_INITIAL_RESIDUAL_TC_RESOURCE; ++ ++ /* 4 <3.1> Allocated resource amount = minimum of (guaranteed, total demand) */ ++ for (i = 0; i < TC_NUM; i++) { ++ ++ if (i == TC4_INDEX) ++ continue; /* Skip TC4 (not adjustable) */ ++ ++ /* The demand can be fulfilled with the guaranteed resource amount 4 4 6 6 2 4 */ ++ ++ /* ++ ai4PerTcResourceDemand[i] = ++ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + ++ prQM->au4MinReservedTcResource[i] - ++ prQM->au4CurrentTcResource[i]); ++ ++ so au4CurrentTcResource + ai4PerTcResourceDemand = ++ ++ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + ++ prQM->au4MinReservedTcResource[i] = ++ ++ current average queue len + min TC resources ++ */ ++ if (prQM->au4CurrentTcResource[i] + ai4PerTcResourceDemand[i] < ++ prQM->au4GuaranteedTcResource[i]) { ++ ++ /* avg queue len + min reserve still smaller than guarantee so enough */ ++ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; ++ ++ /* accumulate available TC resources from the TC */ ++ u4ResidualResource += ++ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); ++ ai4PerTcResourceDemand[i] = 0; ++ } ++ ++ /* The demand can not be fulfilled with the guaranteed resource amount */ ++ else { ++ ++ /* means even we use all guarantee resources for the TC is still not enough */ ++ ++ /* ++ guarantee number is always for the TC so extra resource number cannot ++ include the guarantee number. ++ ++ EX: au4GuaranteedTcResource = 10, au4CurrentTcResource = 5 ++ ai4PerTcResourceDemand = 6 ++ ++ ai4PerTcResourceDemand -= (10 - 5) ==> 1 ++ only need extra 1 TC resouce is enough. ++ */ ++ ai4PerTcResourceDemand[i] -= ++ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); ++ ++ /* update current avg TC resource to guarantee number */ ++ prQM->au4CurrentTcResource[i] = prQM->au4GuaranteedTcResource[i]; ++ ++ /* count how many TC queues need to get extra resources */ ++ u4ShareCount++; ++ } ++ } ++ ++ /* 4 <3.2> Allocate the residual resource */ ++ do { ++ /* If there is no resource left, exit directly */ ++ if (u4ResidualResource == 0) ++ break; ++ ++ /* This shall not happen */ ++ if (u4ShareCount == 0) { ++ prQM->au4CurrentTcResource[TC1_INDEX] += u4ResidualResource; ++ DBGLOG(QM, ERROR, "QM: (Error) u4ShareCount = 0\n"); ++ break; ++ } ++ ++ /* Share the residual resource evenly */ ++ u4Share = (u4ResidualResource / u4ShareCount); ++ ++ if (u4Share) { ++ for (i = 0; i < TC_NUM; i++) { ++ /* Skip TC4 (not adjustable) */ ++ if (i == TC4_INDEX) ++ continue; ++ ++ if (ai4PerTcResourceDemand[i] == 0) ++ continue; ++ ++ if (ai4PerTcResourceDemand[i] - u4Share) { ++ /* still not enough but we just can give it u4Share resources */ ++ prQM->au4CurrentTcResource[i] += u4Share; ++ u4ResidualResource -= u4Share; ++ ai4PerTcResourceDemand[i] -= u4Share; ++ } else { ++ /* enough */ ++ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; ++ u4ResidualResource -= ai4PerTcResourceDemand[i]; ++ ai4PerTcResourceDemand[i] = 0; ++ } ++ } ++ } ++ ++ if (u4ResidualResource == 0) ++ break; ++ /* By priority, allocate the left resource that is not divisible by u4Share */ ++ ++ if (ai4PerTcResourceDemand[TC3_INDEX]) { /* VO */ ++ prQM->au4CurrentTcResource[TC3_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC2_INDEX]) { /* VI */ ++ prQM->au4CurrentTcResource[TC2_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC5_INDEX]) { /* BMCAST */ ++ prQM->au4CurrentTcResource[TC5_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC1_INDEX]) { /* BE */ ++ prQM->au4CurrentTcResource[TC1_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ if (ai4PerTcResourceDemand[TC0_INDEX]) { /* BK */ ++ prQM->au4CurrentTcResource[TC0_INDEX]++; ++ if (--u4ResidualResource == 0) ++ break; ++ } ++ ++ /* Allocate the left resource */ ++ prQM->au4CurrentTcResource[TC3_INDEX] += u4ResidualResource; ++ ++ } while (FALSE); ++ } ++ ++ /* mark the flag that we can start to do TC resource adjustment after TX done handle */ ++ prQM->fgTcResourcePostAnnealing = TRUE; ++ ++#if QM_PRINT_TC_RESOURCE_CTRL ++ /* Debug print */ ++ DBGLOG(QM, LOUD, "QM: TC Rsc %u %u %u %u %u %u\n", ++ prQM->au4CurrentTcResource[0], ++ prQM->au4CurrentTcResource[1], ++ prQM->au4CurrentTcResource[2], ++ prQM->au4CurrentTcResource[3], prQM->au4CurrentTcResource[4], prQM->au4CurrentTcResource[5] ++ )); ++#endif ++ ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* RX-Related Queue Management */ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Init Queue Management for RX ++* ++* \param[in] (none) ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter) ++{ ++ /* DbgPrint("QM: Enter qmInitRxQueues()\n"); */ ++ /* TODO */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle RX packets (buffer reordering) ++* ++* \param[in] prSwRfbListHead The list of RX packets ++* ++* \return The list of packets which are not buffered for reordering ++*/ ++/*----------------------------------------------------------------------------*/ ++P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) ++{ ++ ++#if CFG_RX_REORDERING_ENABLED ++ /* UINT_32 i; */ ++ P_SW_RFB_T prCurrSwRfb; ++ P_SW_RFB_T prNextSwRfb; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ QUE_T rReturnedQue; ++ PUINT_8 pucEthDestAddr; ++ BOOLEAN fgIsBMC; ++ ++ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ ++ ++ DEBUGFUNC("qmHandleRxPackets"); ++ ++ ASSERT(prSwRfbListHead); ++ ++ QUEUE_INITIALIZE(&rReturnedQue); ++ prNextSwRfb = prSwRfbListHead; ++ ++ do { ++ prCurrSwRfb = prNextSwRfb; ++ prNextSwRfb = QM_RX_GET_NEXT_SW_RFB(prCurrSwRfb); ++ ++ prHifRxHdr = prCurrSwRfb->prHifRxHdr; /* TODO: (Tehuang) Use macro to obtain the pointer */ ++ ++ /* TODO: (Tehuang) Check if relaying */ ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST; ++ ++ /* Decide the Destination */ ++#if CFG_RX_PKTS_DUMP ++ if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_DATA)) { ++ DBGLOG(SW4, INFO, "QM RX DATA: net %u sta idx %u wlan idx %u ssn %u tid %u ptype %u 11 %u\n", ++ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), ++ prHifRxHdr->ucStaRecIdx, prCurrSwRfb->ucWlanIdx, ++ (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr), /* The new SN of the frame */ ++ (UINT_32) HIF_RX_HDR_GET_TID(prHifRxHdr), ++ prCurrSwRfb->ucPacketType, ++ (UINT_32) HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); ++ ++ DBGLOG_MEM8(SW4, TRACE, (PUINT_8) prCurrSwRfb->pvHeader, prCurrSwRfb->u2PacketLen); ++ } ++#endif ++ ++ fgIsBMC = FALSE; ++ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { ++ ++ UINT_8 ucNetTypeIdx; ++ P_BSS_INFO_T prBssInfo; ++ ++ pucEthDestAddr = prCurrSwRfb->pvHeader; ++ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); ++ /* DBGLOG_MEM8(QM, TRACE,prCurrSwRfb->pvHeader, 16); */ ++ /* */ ++ ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) && (OP_MODE_ACCESS_POINT != prBssInfo->eCurrentOPMode)) ++ fgIsBMC = TRUE; ++ ++ if (prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem > ++ (CFG_RX_MAX_PKT_NUM - CFG_NUM_OF_QM_RX_PKT_NUM)) { ++ ++ if (!IS_BSS_ACTIVE(prBssInfo)) { ++ DBGLOG(QM, WARN, "Mark NULL the Packet for inactive Bss %u\n", ucNetTypeIdx); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++ ++ if (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode) { ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; ++ else if (UNEQUAL_MAC_ADDR(prBssInfo->aucOwnMacAddr, pucEthDestAddr) && ++ bssGetClientByAddress(prBssInfo, pucEthDestAddr)) ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_FORWARD; ++ /* TODO : need to check the dst mac is valid */ ++ /* If src mac is invalid, the packet will be freed in fw */ ++ } /* OP_MODE_ACCESS_POINT */ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ else if (hs20IsFrameFilterEnabled(prAdapter, prBssInfo) && ++ hs20IsUnsecuredFrame(prAdapter, prBssInfo, prCurrSwRfb)) { ++ DBGLOG(QM, WARN, ++ "Mark NULL the Packet for Dropped Packet %u\n", ucNetTypeIdx); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++#endif ++ } else { ++ /* Dont not occupy other SW RFB */ ++ DBGLOG(QM, WARN, "Mark NULL the Packet for less Free Sw Rfb\n"); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++ ++ } ++#if CFG_SUPPORT_WAPI ++ if (prCurrSwRfb->u2PacketLen > ETHER_HEADER_LEN) { ++ PUINT_8 pc = (PUINT_8) prCurrSwRfb->pvHeader; ++ UINT_16 u2Etype = 0; ++ ++ u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ /* for wapi integrity test. WPI_1x packet should be always in non-encrypted mode. ++ if we received any WPI(0x88b4) packet that is encrypted, drop here. */ ++ if (u2Etype == ETH_WPI_1X && HIF_RX_HDR_GET_SEC_MODE(prHifRxHdr) != 0) { ++ DBGLOG(QM, INFO, "drop wpi packet with sec mode\n"); ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ continue; ++ } ++ } ++#endif ++ /* BAR frame */ ++ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ qmProcessBarFrame(prAdapter, prCurrSwRfb, &rReturnedQue); ++ } ++ /* Reordering is not required for this packet, return it without buffering */ ++ else if (!HIF_RX_HDR_GET_REORDER_FLAG(prHifRxHdr) || fgIsBMC) { ++#if 0 ++ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { ++ UINT_8 ucNetTypeIdx; ++ P_BSS_INFO_T prBssInfo; ++ ++ pucEthDestAddr = prCurrSwRfb->pvHeader; ++ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); ++ ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) ++ && (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode)) { ++ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; ++ } ++ } ++#endif ++ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); ++ } ++ /* Reordering is required for this packet */ ++ else { ++ /* If this packet should dropped or indicated to the host immediately, ++ * it should be enqueued into the rReturnedQue with specific flags. If ++ * this packet should be buffered for reordering, it should be enqueued ++ * into the reordering queue in the STA_REC rather than into the ++ * rReturnedQue. ++ */ ++ qmProcessPktWithReordering(prAdapter, prCurrSwRfb, &rReturnedQue); ++ ++ } ++ } while (prNextSwRfb); ++ ++ /* RX_PKT_DESTINATION_HOST_WITH_FORWARD or RX_PKT_DESTINATION_FORWARD */ ++ /* The returned list of SW_RFBs must end with a NULL pointer */ ++ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) ++ QM_TX_SET_NEXT_MSDU_INFO((P_SW_RFB_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); ++ ++ return (P_SW_RFB_T) QUEUE_GET_HEAD(&rReturnedQue); ++ ++#else ++ ++ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ ++ return prSwRfbListHead; ++ ++#endif ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Reorder the received packet ++* ++* \param[in] prSwRfb The RX packet to process ++* \param[out] prReturnedQue The queue for indicating packets ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) ++{ ++ ++ P_STA_RECORD_T prStaRec; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_RX_BA_ENTRY_T prReorderQueParm; ++ ++ UINT_32 u4SeqNo; ++ UINT_32 u4WinStart; ++ UINT_32 u4WinEnd; ++ P_QUE_T prReorderQue; ++ /* P_SW_RFB_T prReorderedSwRfb; */ ++ BOOLEAN fgIsBaTimeout; ++ ++ DEBUGFUNC("qmProcessPktWithReordering"); ++ ++ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; ++ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SN of the frame */ ++ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); ++ /* prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ ++ ++ /* Incorrect STA_REC index */ ++ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ DBGLOG(QM, WARN, "Reordering for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Check whether the STA_REC is activated */ ++ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); ++ ASSERT(prStaRec); ++ ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ DBGLOG(QM, WARN, "Reordering for an invalid STA_REC\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++#endif ++ ++ /* Check whether the BA agreement exists */ ++ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); ++ if (!prReorderQueParm) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ DBGLOG(QM, WARN, "Reordering for a NULL ReorderQueParm\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Start to reorder packets */ ++ u4SeqNo = (UINT_32) (prSwRfb->u2SSN); ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); ++ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); ++ ++ /* Debug */ ++ /* DbgPrint("QM:(R)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ ++ ++ /* Case 1: Fall within */ ++ if /* 0 - start - sn - end - 4095 */ ++ (((u4WinStart <= u4SeqNo) && (u4SeqNo <= u4WinEnd)) ++ /* 0 - end - start - sn - 4095 */ ++ || ((u4WinEnd < u4WinStart) && (u4WinStart <= u4SeqNo)) ++ /* 0 - sn - end - start - 4095 */ ++ || ((u4SeqNo <= u4WinEnd) && (u4WinEnd < u4WinStart))) { ++ ++ qmInsertFallWithinReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); ++ ++#if QM_RX_WIN_SSN_AUTO_ADVANCING ++ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { ++ /* Let the first received packet pass the reorder check */ ++ DBGLOG(QM, LOUD, "QM:(A)[%d](%u){%u,%u}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); ++ ++ prReorderQueParm->u2WinStart = (UINT_16) u4SeqNo; ++ prReorderQueParm->u2WinEnd = ++ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; ++ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; ++ } ++#endif ++ ++ if (qmPopOutDueToFallWithin(prReorderQueParm, prReturnedQue, &fgIsBaTimeout) == FALSE) ++ STATS_RX_REORDER_HOLE_INC(prStaRec); /* record hole count */ ++ STATS_RX_REORDER_HOLE_TIMEOUT_INC(prStaRec, fgIsBaTimeout); ++ } ++ /* Case 2: Fall ahead */ ++ else if ++ /* 0 - start - end - sn - (start+2048) - 4095 */ ++ (((u4WinStart < u4WinEnd) ++ && (u4WinEnd < u4SeqNo) ++ && (u4SeqNo < (u4WinStart + HALF_SEQ_NO_COUNT))) ++ /* 0 - sn - (start+2048) - start - end - 4095 */ ++ || ((u4SeqNo < u4WinStart) ++ && (u4WinStart < u4WinEnd) ++ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT))) ++ /* 0 - end - sn - (start+2048) - start - 4095 */ ++ || ((u4WinEnd < u4SeqNo) ++ && (u4SeqNo < u4WinStart) ++ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT)))) { ++ ++#if QM_RX_WIN_SSN_AUTO_ADVANCING ++ if (prReorderQueParm->fgIsWaitingForPktWithSsn) ++ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; ++#endif ++ ++ qmInsertFallAheadReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); ++ ++ /* Advance the window after inserting a new tail */ ++ prReorderQueParm->u2WinEnd = (UINT_16) u4SeqNo; ++ prReorderQueParm->u2WinStart = ++ (((prReorderQueParm->u2WinEnd) - (prReorderQueParm->u2WinSize) + MAX_SEQ_NO_COUNT + 1) ++ % MAX_SEQ_NO_COUNT); ++ ++ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); ++ ++ STATS_RX_REORDER_FALL_AHEAD_INC(prStaRec); ++ ++ } ++ /* Case 3: Fall behind */ ++ else { ++ ++#if QM_RX_WIN_SSN_AUTO_ADVANCING ++#if QM_RX_INIT_FALL_BEHIND_PASS ++ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { ++ /* ?? prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ /* DbgPrint("QM:(P)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ ++ return; ++ } ++#endif ++#endif ++ ++ STATS_RX_REORDER_FALL_BEHIND_INC(prStaRec); ++ /* An erroneous packet */ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ /* DbgPrint("QM:(D)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ ++ return; ++ } ++ ++ return; ++ ++} ++ ++VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) ++{ ++ ++ P_STA_RECORD_T prStaRec; ++ P_HIF_RX_HEADER_T prHifRxHdr; ++ P_RX_BA_ENTRY_T prReorderQueParm; ++ ++ UINT_32 u4SSN; ++ UINT_32 u4WinStart; ++ UINT_32 u4WinEnd; ++ P_QUE_T prReorderQue; ++ /* P_SW_RFB_T prReorderedSwRfb; */ ++ ++ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prHifRxHdr = prSwRfb->prHifRxHdr; ++ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; ++ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SSN */ ++ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); ++ ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ ++ /* Incorrect STA_REC index */ ++ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { ++ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ /* Check whether the STA_REC is activated */ ++ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); ++ ASSERT(prStaRec); ++ ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ DbgPrint("QM: (Warning) BAR for an invalid STA_REC\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++#endif ++ ++ /* Check whether the BA agreement exists */ ++ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); ++ if (!prReorderQueParm) { ++ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ ++ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL ReorderQueParm\n"); ++ /* ASSERT(0); */ ++ return; ++ } ++ ++ u4SSN = (UINT_32) (prSwRfb->u2SSN); ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); ++ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); ++ ++ if (qmCompareSnIsLessThan(u4WinStart, u4SSN)) { ++ prReorderQueParm->u2WinStart = (UINT_16) u4SSN; ++ prReorderQueParm->u2WinEnd = ++ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; ++ DBGLOG(QM, TRACE, ++ "QM:(BAR)[%d](%u){%d,%d}\n", prSwRfb->ucTid, u4SSN, prReorderQueParm->u2WinStart, ++ prReorderQueParm->u2WinEnd); ++ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); ++ } else { ++ DBGLOG(QM, TRACE, "QM:(BAR)(%d)(%u){%u,%u}\n", prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd); ++ } ++} ++ ++VOID qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) ++{ ++ P_SW_RFB_T prExaminedQueuedSwRfb; ++ P_QUE_T prReorderQue; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prReorderQueParm); ++ ASSERT(prReturnedQue); ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ prExaminedQueuedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); ++ ++ /* There are no packets queued in the Reorder Queue */ ++ if (prExaminedQueuedSwRfb == NULL) { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; ++ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; ++ prReorderQue->u4NumElem++; ++ } ++ ++ /* Determine the insert position */ ++ else { ++ do { ++ /* Case 1: Terminate. A duplicate packet */ ++ if (((prExaminedQueuedSwRfb->u2SSN) == (prSwRfb->u2SSN))) { ++ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); ++ return; ++ } ++ ++ /* Case 2: Terminate. The insert point is found */ ++ else if (qmCompareSnIsLessThan((prSwRfb->u2SSN), (prExaminedQueuedSwRfb->u2SSN))) ++ break; ++ ++ /* Case 3: Insert point not found. Check the next SW_RFB in the Reorder Queue */ ++ else ++ prExaminedQueuedSwRfb = (P_SW_RFB_T) (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prNext); ++ } while (prExaminedQueuedSwRfb); ++ ++ /* Update the Reorder Queue Parameters according to the found insert position */ ++ if (prExaminedQueuedSwRfb == NULL) { ++ /* The received packet shall be placed at the tail */ ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); ++ prReorderQue->prTail = (P_QUE_ENTRY_T) (prSwRfb); ++ } else { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = (P_QUE_ENTRY_T) prExaminedQueuedSwRfb; ++ if (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb) == (prReorderQue->prHead)) { ++ /* The received packet will become the head */ ++ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; ++ } else { ++ (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev)->prNext = (P_QUE_ENTRY_T) prSwRfb; ++ } ++ ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev = (P_QUE_ENTRY_T) prSwRfb; ++ } ++ ++ prReorderQue->u4NumElem++; ++ ++ } ++ ++} ++ ++VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) ++{ ++ P_QUE_T prReorderQue; ++ ++ ASSERT(prSwRfb); ++ ASSERT(prReorderQueParm); ++ ASSERT(prReturnedQue); ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ ++ /* There are no packets queued in the Reorder Queue */ ++ if (QUEUE_IS_EMPTY(prReorderQue)) { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; ++ } else { ++ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; ++ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; ++ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); ++ } ++ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; ++ prReorderQue->u4NumElem++; ++ ++} ++ ++BOOLEAN ++qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout) ++{ ++ P_SW_RFB_T prReorderedSwRfb; ++ P_QUE_T prReorderQue; ++ BOOLEAN fgDequeuHead, fgMissing; ++ OS_SYSTIME rCurrentTime, *prMissTimeout; ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ ++ *fgIsTimeout = FALSE; ++ fgMissing = FALSE; ++ rCurrentTime = 0; ++ prMissTimeout = &(g_arMissTimeout[prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid]); ++ if ((*prMissTimeout)) { ++ fgMissing = TRUE; ++ GET_CURRENT_SYSTIME(&rCurrentTime); ++ } ++ ++ /* Check whether any packet can be indicated to the higher layer */ ++ while (TRUE) { ++ if (QUEUE_IS_EMPTY(prReorderQue)) ++ break; ++ ++ /* Always examine the head packet */ ++ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); ++ fgDequeuHead = FALSE; ++ ++ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ ++ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { ++ ++ fgDequeuHead = TRUE; ++ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); ++ } ++ /* SN > WinStart, break to update WinEnd */ ++ else { ++ if ((fgMissing == TRUE) && ++ CHECK_FOR_TIMEOUT(rCurrentTime, (*prMissTimeout), ++ MSEC_TO_SYSTIME(QM_RX_BA_ENTRY_MISS_TIMEOUT_MS))) { ++ DBGLOG(QM, TRACE, ++ "QM:RX BA Timout Next Tid %d SSN %d\n", prReorderQueParm->ucTid, ++ prReorderedSwRfb->u2SSN); ++ fgDequeuHead = TRUE; ++ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); ++ ++ fgMissing = FALSE; ++ *fgIsTimeout = TRUE; ++ } else ++ break; ++ } ++ ++ /* Dequeue the head packet */ ++ if (fgDequeuHead) { ++ ++ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { ++ prReorderQue->prHead = NULL; ++ prReorderQue->prTail = NULL; ++ } else { ++ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; ++ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; ++ } ++ prReorderQue->u4NumElem--; ++ /* DbgPrint("QM: [%d] %d (%d)\n", ++ prReorderQueParm->ucTid, ++ prReorderedSwRfb->u2PacketLen, ++ prReorderedSwRfb->u2SSN); */ ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); ++ } ++ } ++ ++ if (QUEUE_IS_EMPTY(prReorderQue)) ++ *prMissTimeout = 0; ++ else { ++ if (fgMissing == FALSE) ++ GET_CURRENT_SYSTIME(prMissTimeout); ++ } ++ ++ /* After WinStart has been determined, update the WinEnd */ ++ prReorderQueParm->u2WinEnd = ++ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); ++ return QUEUE_IS_EMPTY(prReorderQue); ++} ++ ++VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) ++{ ++ P_SW_RFB_T prReorderedSwRfb; ++ P_QUE_T prReorderQue; ++ BOOLEAN fgDequeuHead; ++ ++ prReorderQue = &(prReorderQueParm->rReOrderQue); ++ ++ /* Check whether any packet can be indicated to the higher layer */ ++ while (TRUE) { ++ if (QUEUE_IS_EMPTY(prReorderQue)) ++ break; ++ ++ /* Always examine the head packet */ ++ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); ++ fgDequeuHead = FALSE; ++ ++ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ ++ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { ++ ++ fgDequeuHead = TRUE; ++ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); ++ } ++ ++ /* SN < WinStart, so the head packet shall be indicated (do not advance the window) */ ++ else if (qmCompareSnIsLessThan((UINT_32) (prReorderedSwRfb->u2SSN), ++ (UINT_32) (prReorderQueParm->u2WinStart))) ++ fgDequeuHead = TRUE; ++ ++ /* SN > WinStart, break to update WinEnd */ ++ else ++ break; ++ ++ /* Dequeue the head packet */ ++ if (fgDequeuHead) { ++ ++ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { ++ prReorderQue->prHead = NULL; ++ prReorderQue->prTail = NULL; ++ } else { ++ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; ++ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; ++ } ++ prReorderQue->u4NumElem--; ++ /* DbgPrint("QM: [%d] %d (%d)\n", */ ++ /* prReorderQueParm->ucTid, prReorderedSwRfb->u2PacketLen, prReorderedSwRfb->u2SSN); */ ++ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); ++ } ++ } ++ ++ /* After WinStart has been determined, update the WinEnd */ ++ prReorderQueParm->u2WinEnd = ++ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); ++ ++} ++ ++BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater) ++{ ++ /* 0 <---> SnLess <--(gap>2048)--> SnGreater : SnLess > SnGreater */ ++ if ((u4SnLess + HALF_SEQ_NO_COUNT) <= u4SnGreater) /* Shall be <= */ ++ return FALSE; ++ ++ /* 0 <---> SnGreater <--(gap>2048)--> SnLess : SnLess < SnGreater */ ++ else if ((u4SnGreater + HALF_SEQ_NO_COUNT) < u4SnLess) ++ return TRUE; ++ ++ /* 0 <---> SnGreater <--(gap<2048)--> SnLess : SnLess > SnGreater */ ++ /* 0 <---> SnLess <--(gap<2048)--> SnGreater : SnLess < SnGreater */ ++ else if (u4SnLess < u4SnGreater) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle Mailbox RX messages ++* ++* \param[in] prMailboxRxMsg The received Mailbox message from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg) ++{ ++ /* DbgPrint("QM: Enter qmHandleMailboxRxMessage()\n"); */ ++ /* TODO */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle ADD RX BA Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_RX_ADDBA_T prEventRxAddBa; ++ P_STA_RECORD_T prStaRec; ++ UINT_32 u4Tid; ++ UINT_32 u4WinSize; ++ ++ DBGLOG(QM, INFO, "QM:Event +RxBa\n"); ++ ++ prEventRxAddBa = (P_EVENT_RX_ADDBA_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxAddBa->ucStaRecIdx); ++ ++ if (!prStaRec) { ++ /* Invalid STA_REC index, discard the event packet */ ++ /* ASSERT(0); */ ++ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for a NULL STA_REC\n"); ++ return; ++ } ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ ++ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for an invalid STA_REC\n"); ++ /* ASSERT(0); */ ++ /* return; */ ++ } ++#endif ++ ++ u4Tid = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_TID_MASK) ++ >> BA_PARAM_SET_TID_MASK_OFFSET); ++ ++ u4WinSize = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_BUFFER_SIZE_MASK) ++ >> BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); ++ ++ if (!qmAddRxBaEntry(prAdapter, ++ prStaRec->ucIndex, ++ (UINT_8) u4Tid, ++ (prEventRxAddBa->u2BAStartSeqCtrl >> OFFSET_BAR_SSC_SN), (UINT_16) u4WinSize)) { ++ ++ /* FW shall ensure the availabiilty of the free-to-use BA entry */ ++ DBGLOG(QM, ERROR, "QM: (Error) qmAddRxBaEntry() failure\n"); ++ ASSERT(0); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle DEL RX BA Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_RX_DELBA_T prEventRxDelBa; ++ P_STA_RECORD_T prStaRec; ++ ++ /* DbgPrint("QM:Event -RxBa\n"); */ ++ ++ prEventRxDelBa = (P_EVENT_RX_DELBA_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxDelBa->ucStaRecIdx); ++ ++ if (!prStaRec) ++ /* Invalid STA_REC index, discard the event packet */ ++ /* ASSERT(0); */ ++ return; ++#if 0 ++ if (!(prStaRec->fgIsValid)) ++ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ ++ /* ASSERT(0); */ ++ return; ++#endif ++ ++ qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, prEventRxDelBa->ucTid, TRUE); ++ ++} ++ ++P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, UINT_8 ucStaRecIdx, UINT_8 ucTid) ++{ ++ int i; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ /* DbgPrint("QM: Enter qmLookupRxBaEntry()\n"); */ ++ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ if (prQM->arRxBaTable[i].fgIsValid) { ++ if ((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) && (prQM->arRxBaTable[i].ucTid == ucTid)) ++ return &prQM->arRxBaTable[i]; ++ } ++ } ++ return NULL; ++} ++ ++BOOLEAN ++qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, ++ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize) ++{ ++ int i; ++ P_RX_BA_ENTRY_T prRxBaEntry = NULL; ++ P_STA_RECORD_T prStaRec; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ if (ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { ++ /* Invalid STA_REC index, discard the event packet */ ++ DBGLOG(QM, WARN, "QM: (WARNING) RX ADDBA Event for a invalid ucStaRecIdx = %d\n", ucStaRecIdx); ++ return FALSE; ++ } ++ ++ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; ++ ASSERT(prStaRec); ++ ++ /* if(!(prStaRec->fgIsValid)){ */ ++ /* DbgPrint("QM: (WARNING) Invalid STA when adding an RX BA\n"); */ ++ /* return FALSE; */ ++ /* } */ ++ ++ /* 4 <1> Delete before adding */ ++ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ ++ if (qmLookupRxBaEntry(prAdapter, ucStaRecIdx, ucTid)) ++ qmDelRxBaEntry(prAdapter, ucStaRecIdx, ucTid, TRUE); /* prQM->ucRxBaCount-- */ ++ /* 4 <2> Add a new BA entry */ ++ /* No available entry to store the BA agreement info. Retrun FALSE. */ ++ if (prQM->ucRxBaCount >= CFG_NUM_OF_RX_BA_AGREEMENTS) { ++ DBGLOG(QM, ERROR, "QM: **failure** (limited resource, ucRxBaCount=%d)\n", prQM->ucRxBaCount); ++ return FALSE; ++ } ++ /* Find the free-to-use BA entry */ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ if (!prQM->arRxBaTable[i].fgIsValid) { ++ prRxBaEntry = &(prQM->arRxBaTable[i]); ++ prQM->ucRxBaCount++; ++ DBGLOG(QM, LOUD, "QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); ++ break; ++ } ++ } ++ /* If a free-to-use entry is found, configure it and associate it with the STA_REC */ ++ u2WinSize += CFG_RX_BA_INC_SIZE; ++ if (prRxBaEntry) { ++ prRxBaEntry->ucStaRecIdx = ucStaRecIdx; ++ prRxBaEntry->ucTid = ucTid; ++ prRxBaEntry->u2WinStart = u2WinStart; ++ prRxBaEntry->u2WinSize = u2WinSize; ++ prRxBaEntry->u2WinEnd = ((u2WinStart + u2WinSize - 1) % MAX_SEQ_NO_COUNT); ++ prRxBaEntry->fgIsValid = TRUE; ++ prRxBaEntry->fgIsWaitingForPktWithSsn = TRUE; ++ ++ g_arMissTimeout[ucStaRecIdx][ucTid] = 0; ++ ++ DBGLOG(QM, INFO, "QM: +RxBA(STA=%d TID=%d WinStart=%d WinEnd=%d WinSize=%d)\n", ++ ucStaRecIdx, ucTid, ++ prRxBaEntry->u2WinStart, prRxBaEntry->u2WinEnd, prRxBaEntry->u2WinSize); ++ ++ /* Update the BA entry reference table for per-packet lookup */ ++ prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry; ++ } else { ++ /* This shall not happen because FW should keep track of the usage of RX BA entries */ ++ DBGLOG(QM, ERROR, "QM: **AddBA Error** (ucRxBaCount=%d)\n", prQM->ucRxBaCount); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost) ++{ ++ P_RX_BA_ENTRY_T prRxBaEntry; ++ P_STA_RECORD_T prStaRec; ++ P_SW_RFB_T prFlushedPacketList = NULL; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); ++ ++ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; ++ ASSERT(prStaRec); ++ ++#if 0 ++ if (!(prStaRec->fgIsValid)) { ++ DbgPrint("QM: (WARNING) Invalid STA when deleting an RX BA\n"); ++ return; ++ } ++#endif ++ ++ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ ++ prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[ucTid]; ++ ++ if (prRxBaEntry) { ++ ++ prFlushedPacketList = qmFlushStaRxQueue(prAdapter, ucStaRecIdx, ucTid); ++ ++ if (prFlushedPacketList) { ++ ++ if (fgFlushToHost) { ++ wlanProcessQueuedSwRfb(prAdapter, prFlushedPacketList); ++ } else { ++ ++ P_SW_RFB_T prSwRfb; ++ P_SW_RFB_T prNextSwRfb; ++ ++ prSwRfb = prFlushedPacketList; ++ ++ do { ++ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); ++ nicRxReturnRFB(prAdapter, prSwRfb); ++ prSwRfb = prNextSwRfb; ++ } while (prSwRfb); ++ ++ } ++ ++ } ++#if ((QM_TEST_MODE == 0) && (QM_TEST_STA_REC_DEACTIVATION == 0)) ++ /* Update RX BA entry state. Note that RX queue flush is not done here */ ++ prRxBaEntry->fgIsValid = FALSE; ++ prQM->ucRxBaCount--; ++ ++ /* Debug */ ++#if 0 ++ DbgPrint("QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); ++#endif ++ ++ /* Update STA RX BA table */ ++ prStaRec->aprRxReorderParamRefTbl[ucTid] = NULL; ++#endif ++ ++ DBGLOG(QM, INFO, "QM: -RxBA(STA=%d,TID=%d)\n", ucStaRecIdx, ucTid); ++ ++ } ++ ++ /* Debug */ ++#if CFG_HIF_RX_STARVATION_WARNING ++ { ++ P_RX_CTRL_T prRxCtrl; ++ ++ prRxCtrl = &prAdapter->rRxCtrl; ++ DBGLOG(QM, TRACE, ++ "QM: (RX DEBUG) Enqueued: %d / Dequeued: %d\n", prRxCtrl->u4QueuedCnt, ++ prRxCtrl->u4DequeuedCnt); ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To process WMM related IEs in ASSOC_RSP ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prSwRfb The received frame ++* \param[in] pucIE The pointer to the first IE in the frame ++* \param[in] u2IELength The total length of IEs in the frame ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ PUINT_8 pucIEStart; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ P_IE_WMM_INFO_T prIeWmmInfo; ++ UINT_8 ucQosInfo; ++ UINT_8 ucQosInfoAC; ++ UINT_8 ucBmpAC; ++ ++ DEBUGFUNC("mqmProcessAssocReq"); ++ ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ prStaRec->fgIsQoS = FALSE; ++ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; ++ ++ pucIEStart = pucIE; ++ ++ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ /* Determine whether QoS is enabled with the association */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_WMM: ++ ++ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && ++ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_INFO: ++ if (IE_LEN(pucIE) != 7) ++ break; /* WMM Info IE with a wrong length */ ++ prStaRec->fgIsQoS = TRUE; ++ prStaRec->fgIsWmmSupported = TRUE; ++ ++ prIeWmmInfo = (P_IE_WMM_INFO_T) pucIE; ++ ucQosInfo = prIeWmmInfo->ucQosInfo; ++ ucQosInfoAC = ucQosInfo & BITS(0, 3); ++ ++ prStaRec->fgIsUapsdSupported = ((ucQosInfoAC) ? TRUE : FALSE) & ++ prAdapter->rWifiVar.fgSupportUAPSD; ++ ++ ucBmpAC = 0; ++ ++ if (ucQosInfoAC & WMM_QOS_INFO_VO_UAPSD) ++ ucBmpAC |= BIT(ACI_VO); ++ if (ucQosInfoAC & WMM_QOS_INFO_VI_UAPSD) ++ ucBmpAC |= BIT(ACI_VI); ++ if (ucQosInfoAC & WMM_QOS_INFO_BE_UAPSD) ++ ucBmpAC |= BIT(ACI_BE); ++ if (ucQosInfoAC & WMM_QOS_INFO_BK_UAPSD) ++ ucBmpAC |= BIT(ACI_BK); ++ ++ prStaRec->ucBmpTriggerAC = prStaRec->ucBmpDeliveryAC = ucBmpAC; ++ ++ prStaRec->ucUapsdSp = ++ (ucQosInfo & WMM_QOS_INFO_MAX_SP_LEN_MASK) >> 5; ++ break; ++ default: ++ /* Other WMM QoS IEs. Ignore any */ ++ break; ++ } ++ } ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ ++ ++ break; ++ ++ case ELEM_ID_HT_CAP: ++ /* Some client won't put the WMM IE if client is 802.11n */ ++ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ DBGLOG(QM, TRACE, "MQM: Assoc_Req Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To process WMM related IEs in ASSOC_RSP ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prSwRfb The received frame ++* \param[in] pucIE The pointer to the first IE in the frame ++* \param[in] u2IELength The total length of IEs in the frame ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ PUINT_8 pucIEStart; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ DEBUGFUNC("mqmProcessAssocRsp"); ++ ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ prStaRec->fgIsQoS = FALSE; ++ ++ pucIEStart = pucIE; ++ ++ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgSupportQoS=%d)\n", ++ prStaRec->fgIsWmmSupported, prAdapter->rWifiVar.fgSupportQoS); ++ ++ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ ++ /* if((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported)) */ ++ if ((!prAdapter->rWifiVar.fgSupportQoS)) ++ return; ++ ++ /* Determine whether QoS is enabled with the association */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_WMM: ++ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && ++ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { ++ ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_PARAM: ++ if (IE_LEN(pucIE) != 24) ++ break; /* WMM Info IE with a wrong length */ ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ ++ case VENDOR_OUI_SUBTYPE_WMM_INFO: ++ if (IE_LEN(pucIE) != 7) ++ break; /* WMM Info IE with a wrong length */ ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ ++ default: ++ /* Other WMM QoS IEs. Ignore any */ ++ break; ++ } ++ } ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ ++ break; ++ ++ case ELEM_ID_HT_CAP: ++ /* Some AP won't put the WMM IE if client is 802.11n */ ++ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) ++ prStaRec->fgIsQoS = TRUE; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* Parse AC parameters and write to HW CRs */ ++ if ((prStaRec->fgIsQoS) && (prStaRec->eStaType == STA_TYPE_LEGACY_AP)) { ++ mqmParseEdcaParameters(prAdapter, prSwRfb, pucIEStart, u2IELength, TRUE); ++#if ARP_MONITER_ENABLE ++ qmResetArpDetect(); ++#endif ++ } ++ ++ DBGLOG(QM, TRACE, "MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); ++ if (prStaRec->fgIsWmmSupported) ++ nicQmUpdateWmmParms(prAdapter, prStaRec->ucNetTypeIndex); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To parse WMM Parameter IE (in BCN or Assoc_Rsp) ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prSwRfb The received frame ++* \param[in] pucIE The pointer to the first IE in the frame ++* \param[in] u2IELength The total length of IEs in the frame ++* \param[in] fgForceOverride TRUE: If EDCA parameters are found, always set to HW CRs. ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, ++ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride) ++{ ++ P_STA_RECORD_T prStaRec; ++ UINT_16 u2Offset; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ P_BSS_INFO_T prBssInfo; ++ P_AC_QUE_PARMS_T prAcQueParams; ++ P_IE_WMM_PARAM_T prIeWmmParam; ++ ENUM_WMM_ACI_T eAci; ++ PUINT_8 pucWmmParamSetCount; ++ ++ DEBUGFUNC("mqmParseEdcaParameters"); ++ ++ ASSERT(prSwRfb); ++ ASSERT(pucIE); ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); ++ ASSERT(prStaRec); ++ if (prStaRec == NULL) ++ return; ++ ++ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgIsQoS=%d)\n", prStaRec->fgIsWmmSupported, prStaRec->fgIsQoS); ++ ++ if ((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported) || (!prStaRec->fgIsQoS)) ++ return; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ /* Goal: Obtain the EDCA parameters */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_WMM: ++ if ((WMM_IE_OUI_TYPE(pucIE) != VENDOR_OUI_TYPE_WMM) || ++ (kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) ++ break; ++ ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_PARAM: ++ if (IE_LEN(pucIE) != 24) ++ break; /* WMM Param IE with a wrong length */ ++ ++ pucWmmParamSetCount = &(prBssInfo->ucWmmParamSetCount); ++ prIeWmmParam = (P_IE_WMM_PARAM_T) pucIE; ++ ++ /* Check the Parameter Set Count to determine whether EDCA parameters */ ++ /* have been changed */ ++ if (!fgForceOverride && (*pucWmmParamSetCount ++ == (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT))) ++ break; /* Ignore the IE without updating HW CRs */ ++ ++ /* Update Parameter Set Count */ ++ *pucWmmParamSetCount = ++ (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT); ++ ++ /* Update EDCA parameters */ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ prAcQueParams = &prBssInfo->arACQueParms[eAci]; ++ mqmFillAcQueParam(prIeWmmParam, eAci, prAcQueParams); ++ ++ prAcQueParams->fgIsACMSet = ++ (prAcQueParams->u2Aifsn & WMM_ACIAIFSN_ACM) ? TRUE : FALSE; ++ prAcQueParams->u2Aifsn &= WMM_ACIAIFSN_AIFSN; ++ ++ DBGLOG(QM, LOUD, ++ "eAci:%d, ACM:%d, Aifsn:%d, CWmin:%d, CWmax:%d, TxopLmt:%d\n", ++ eAci, prAcQueParams->fgIsACMSet, prAcQueParams->u2Aifsn, ++ prAcQueParams->u2CWmin, prAcQueParams->u2CWmax, ++ prAcQueParams->u2TxopLimit); ++ } ++ break; ++ default: ++ /* Other WMM QoS IEs. Ignore */ ++ break; ++ } ++ ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used for parsing EDCA parameters specified in the WMM Parameter IE ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prIeWmmParam The pointer to the WMM Parameter IE ++* \param[in] u4AcOffset The offset specifying the AC queue for parsing ++* \param[in] prHwAcParams The parameter structure used to configure the HW CRs ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams) ++{ ++ prAcQueParams->u2Aifsn = *((PUINT_8) (&(prIeWmmParam->ucAciAifsn_BE)) + (u4AcOffset * 4)); ++ ++ prAcQueParams->u2CWmax = BIT(((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMAX_MASK) ++ >> WMM_ECW_WMAX_OFFSET) - 1; ++ ++ prAcQueParams->u2CWmin = ++ BIT((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMIN_MASK) - 1; ++ ++ WLAN_GET_FIELD_16(((PUINT_8) (&(prIeWmmParam->aucTxopLimit_BE)) + (u4AcOffset * 4)), ++ &(prAcQueParams->u2TxopLimit)); ++ ++ prAcQueParams->ucGuradTime = TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To parse WMM/11n related IEs in scan results (only for AP peers) ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prScanResult The scan result which shall be parsed to obtain needed info ++* \param[out] prStaRec The obtained info is stored in the STA_REC ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++#if (CFG_SUPPORT_TDLS == 1) /* for test purpose */ ++BOOLEAN flgTdlsTestExtCapElm = FALSE; ++UINT8 aucTdlsTestExtCapElm[7]; ++#endif /* CFG_SUPPORT_TDLS */ ++VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec) ++{ ++ PUINT_8 pucIE; ++ UINT_16 u2IELength; ++ UINT_16 u2Offset; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ DEBUGFUNC("mqmProcessScanResult"); ++ ++ ASSERT(prScanResult); ++ ASSERT(prStaRec); ++ ++ /* Reset the flag before parsing */ ++ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; ++ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ u2IELength = prScanResult->u2IELength; ++ pucIE = prScanResult->aucIEBuf; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* TDLS test purpose */ ++ if (flgTdlsTestExtCapElm == TRUE) ++ TdlsexBssExtCapParse(prStaRec, aucTdlsTestExtCapElm); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ /* Goal: Determine whether the peer supports WMM/QoS and UAPSDU */ ++ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { ++ switch (IE_ID(pucIE)) { ++ case ELEM_ID_EXTENDED_CAP: ++#if (CFG_SUPPORT_TDLS == 1) ++ TdlsexBssExtCapParse(prStaRec, pucIE); ++#endif /* CFG_SUPPORT_TDLS */ ++ break; ++ ++ case ELEM_ID_WMM: ++ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && ++ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { ++ ++ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { ++ case VENDOR_OUI_SUBTYPE_WMM_PARAM: ++ if (IE_LEN(pucIE) != 24) ++ break; /* WMM Param IE with a wrong length */ ++ ++ prStaRec->fgIsWmmSupported = TRUE; ++ prStaRec->fgIsUapsdSupported = ++ (((((P_IE_WMM_PARAM_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? ++ TRUE : FALSE); ++ break; ++ ++ case VENDOR_OUI_SUBTYPE_WMM_INFO: ++ if (IE_LEN(pucIE) != 7) ++ break; /* WMM Info IE with a wrong length */ ++ ++ prStaRec->fgIsWmmSupported = TRUE; ++ prStaRec->fgIsUapsdSupported = ++ (((((P_IE_WMM_INFO_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? ++ TRUE : FALSE); ++ break; ++ ++ default: ++ /* A WMM QoS IE that doesn't matter. Ignore it. */ ++ break; ++ } ++ } ++ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ ++ ++ break; ++ ++ default: ++ /* A WMM IE that doesn't matter. Ignore it. */ ++ break; ++ } ++ } ++ DBGLOG(QM, LOUD, "MQM: Scan Result Parsing (WMM=%d, UAPSD=%d)\n", ++ prStaRec->fgIsWmmSupported, prStaRec->fgIsUapsdSupported); ++ ++} ++ ++UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) ++{ ++ UINT_32 i; ++ P_STA_RECORD_T prTempStaRec; ++ ++ prTempStaRec = NULL; ++ ++ ASSERT(prAdapter); ++ ++ /* 4 <1> DA = BMCAST */ ++ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) ++ return STA_REC_INDEX_BMCAST; ++ /* 4 <2> Check if an AP STA is present */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ if ((prTempStaRec->ucNetTypeIndex == eNetworkType) ++ && (prTempStaRec->fgIsAp) ++ && (prTempStaRec->fgIsValid)) { ++ return prTempStaRec->ucIndex; ++ } ++ } ++ ++ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ ++ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { ++ prTempStaRec = &(prAdapter->arStaRec[i]); ++ if (prTempStaRec->fgIsValid) { ++ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, pucEthDestAddr)) ++ return prTempStaRec->ucIndex; ++ } ++ } ++ ++ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ ++ return STA_REC_INDEX_NOT_FOUND; ++} ++ ++UINT_32 ++mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, ++ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf) ++{ ++ P_IE_WMM_INFO_T prIeWmmInfo; ++ UINT_32 ucUapsd[] = { ++ WMM_QOS_INFO_BE_UAPSD, ++ WMM_QOS_INFO_BK_UAPSD, ++ WMM_QOS_INFO_VI_UAPSD, ++ WMM_QOS_INFO_VO_UAPSD ++ }; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ ASSERT(pOutBuf); ++ ++ prIeWmmInfo = (P_IE_WMM_INFO_T) pOutBuf; ++ ++ prIeWmmInfo->ucId = ELEM_ID_WMM; ++ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; ++ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; ++ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; ++ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; ++ ++ prIeWmmInfo->ucVersion = VERSION_WMM; ++ prIeWmmInfo->ucQosInfo = 0; ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++ if (fgSupportUAPSD) { ++ ++ UINT_8 ucQosInfo = 0; ++ UINT_8 i; ++ ++ /* Static U-APSD setting */ ++ for (i = ACI_BE; i <= ACI_VO; i++) { ++ if (ucBmpDeliveryAC & ucBmpTriggerAC & BIT(i)) ++ ucQosInfo |= (UINT_8) ucUapsd[i]; ++ } ++ ++ if (ucBmpDeliveryAC & ucBmpTriggerAC) { ++ switch (ucUapsdSp) { ++ case WMM_MAX_SP_LENGTH_ALL: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_2: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_4: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_6: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; ++ break; ++ ++ default: ++ DBGLOG(QM, WARN, "MQM: Incorrect SP length\n"); ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ } ++ } ++ prIeWmmInfo->ucQosInfo = ucQosInfo; ++ ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ return IE_SIZE(prIeWmmInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Generate the WMM Info IE ++* ++* \param[in] prAdapter Adapter pointer ++* @param prMsduInfo The TX MMPDU ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_IE_WMM_INFO_T prIeWmmInfo; ++ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("mqmGenerateWmmInfoIE"); ++ ++ ASSERT(prMsduInfo); ++ ++ /* In case QoS is not turned off, exit directly */ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ASSERT(prStaRec); ++ ++ if (prStaRec == NULL) ++ return; ++ ++ if (!prStaRec->fgIsWmmSupported) ++ return; ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); ++ ++ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; ++ ++ prIeWmmInfo = (P_IE_WMM_INFO_T) ++ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); ++ ++#if 0 ++ prIeWmmInfo->ucId = ELEM_ID_WMM; ++ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; ++ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; ++ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; ++ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; ++ ++ prIeWmmInfo->ucVersion = VERSION_WMM; ++ prIeWmmInfo->ucQosInfo = 0; ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++/* if(prAdapter->rWifiVar.fgSupportUAPSD){ */ ++ if (prAdapter->rWifiVar.fgSupportUAPSD && prStaRec->fgIsUapsdSupported) { ++ ++ UINT_8 ucQosInfo = 0; ++ UINT_8 i; ++ ++ /* Static U-APSD setting */ ++ for (i = ACI_BE; i <= ACI_VO; i++) { ++ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC & BIT(i)) ++ ucQosInfo |= (UINT_8) ucUapsd[i]; ++ } ++ ++ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC) { ++ switch (prPmProfSetupInfo->ucUapsdSp) { ++ case WMM_MAX_SP_LENGTH_ALL: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_2: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_4: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; ++ break; ++ ++ case WMM_MAX_SP_LENGTH_6: ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; ++ break; ++ ++ default: ++ DBGLOG(QM, INFO, "MQM: Incorrect SP length\n"); ++ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; ++ break; ++ } ++ } ++ prIeWmmInfo->ucQosInfo = ucQosInfo; ++ ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmInfo); ++#else ++ ++ prMsduInfo->u2FrameLength += mqmGenerateWmmInfoIEByParam((prAdapter->rWifiVar.fgSupportUAPSD ++ && prStaRec->fgIsUapsdSupported), ++ prPmProfSetupInfo->ucBmpDeliveryAC, ++ prPmProfSetupInfo->ucBmpTriggerAC, ++ prPmProfSetupInfo->ucUapsdSp, (UINT_8 *) prIeWmmInfo); ++#endif ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief log2 calculation for CW ++* ++* @param[in] val value ++* ++* @return log2(val) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++UINT_32 cwlog2(UINT_32 val) ++{ ++ ++ UINT_32 n; ++ ++ n = 0; ++ ++ while (val >= 512) { ++ n += 9; ++ val = val >> 9; ++ } ++ while (val >= 16) { ++ n += 4; ++ val >>= 4; ++ } ++ while (val >= 2) { ++ n += 1; ++ val >>= 1; ++ } ++ return n; ++} ++#endif ++ ++UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, ++ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode) ++{ ++ P_IE_WMM_PARAM_T prIeWmmParam; ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ UINT_8 aucACI[] = { ++ WMM_ACI_AC_BE, ++ WMM_ACI_AC_BK, ++ WMM_ACI_AC_VI, ++ WMM_ACI_AC_VO ++ }; ++ ENUM_WMM_ACI_T eAci; ++ UCHAR *pucAciAifsn, *pucEcw, *pucTxopLimit; ++ ++ ASSERT(pOutBuf); ++ ++ prIeWmmParam = (P_IE_WMM_PARAM_T) pOutBuf; ++ ++ prIeWmmParam->ucId = ELEM_ID_WMM; ++ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmParam->aucOui[0] = aucWfaOui[0]; ++ prIeWmmParam->aucOui[1] = aucWfaOui[1]; ++ prIeWmmParam->aucOui[2] = aucWfaOui[2]; ++ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; ++ ++ prIeWmmParam->ucVersion = VERSION_WMM; ++ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++ if (prAdapter->rWifiVar.fgSupportUAPSD) { ++ if (ucOpMode == OP_MODE_INFRASTRUCTURE) ++ prIeWmmParam->ucQosInfo = 0xf; ++ else ++ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; ++ } ++ ++ /* EDCA parameter */ ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ /* DBGLOG(QM, LOUD, */ ++ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ ++ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ ++ ++#if 0 ++ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].fgIsACMSet ? ++ WMM_ACIAIFSN_ACM : 0) ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].u2Aifsn & ++ (WMM_ACIAIFSN_AIFSN))); ++#else ++ /* avoid compile warnings in Klockwork tool */ ++ if (eAci == WMM_AC_BE_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BE; ++ pucEcw = &prIeWmmParam->ucEcw_BE; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_BE; ++ } else if (eAci == WMM_AC_BK_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BG; ++ pucEcw = &prIeWmmParam->ucEcw_BG; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_BG; ++ } else if (eAci == WMM_AC_VI_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VI; ++ pucEcw = &prIeWmmParam->ucEcw_VI; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_VI; ++ } else if (eAci == WMM_AC_VO_INDEX) { ++ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VO; ++ pucEcw = &prIeWmmParam->ucEcw_VO; ++ pucTxopLimit = prIeWmmParam->aucTxopLimit_VO; ++ } ++ ++ *pucAciAifsn = (UINT_8) (aucACI[eAci] ++ | (prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet ? WMM_ACIAIFSN_ACM : 0) ++ | (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & (WMM_ACIAIFSN_AIFSN))); ++#endif ++ ++#if 1 ++/* *( ((PUINT_8)(&prIeWmmParam->ucEcw_BE)) + (eAci <<2) ) = (UINT_8) (0 */ ++ *pucEcw = (UINT_8) (0 | (((prBssInfo->aucCWminLog2ForBcast[eAci])) & WMM_ECW_WMIN_MASK) ++ | ((((prBssInfo->aucCWmaxLog2ForBcast[eAci])) << WMM_ECW_WMAX_OFFSET) & ++ WMM_ECW_WMAX_MASK) ++ ); ++#else ++ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 ++ | ++ (cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmin + ++ 1)) & WMM_ECW_WMIN_MASK) ++ | ++ ((cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmax + ++ 1)) << WMM_ECW_WMAX_OFFSET) & ++ WMM_ECW_WMAX_MASK) ++ ); ++#endif ++ ++#if 0 ++ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) ++ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); ++#else ++ WLAN_SET_FIELD_16(pucTxopLimit, prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); ++#endif ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ return IE_SIZE(prIeWmmParam); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Generate the WMM Param IE ++* ++* \param[in] prAdapter Adapter pointer ++* @param prMsduInfo The TX MMPDU ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ P_IE_WMM_PARAM_T prIeWmmParam; ++ ++#if 0 ++ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; ++ ++ UINT_8 aucACI[] = { ++ WMM_ACI_AC_BE, ++ WMM_ACI_AC_BK, ++ WMM_ACI_AC_VI, ++ WMM_ACI_AC_VO ++ }; ++ ENUM_WMM_ACI_T eAci; ++#endif ++ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ ++ DEBUGFUNC("mqmGenerateWmmParamIE"); ++ DBGLOG(QM, LOUD, "\n"); ++ ++ ASSERT(prMsduInfo); ++ ++ /* In case QoS is not turned off, exit directly */ ++ if (!prAdapter->rWifiVar.fgSupportQoS) ++ return; ++ ++ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); ++ ++ if (prStaRec) { ++ if (!prStaRec->fgIsQoS) ++ return; ++ } ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); ++ ++ if (!prBssInfo->fgIsQBSS) ++ return; ++/* 20120220 frog: update beacon content & change OP mode is a separate event for P2P network. */ ++#if 0 ++ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT && prBssInfo->eCurrentOPMode != OP_MODE_BOW) ++ return; ++#endif ++ ++ prIeWmmParam = (P_IE_WMM_PARAM_T) ++ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); ++ ++#if 0 ++ prIeWmmParam->ucId = ELEM_ID_WMM; ++ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; ++ ++ /* WMM-2.2.1 WMM Information Element Field Values */ ++ prIeWmmParam->aucOui[0] = aucWfaOui[0]; ++ prIeWmmParam->aucOui[1] = aucWfaOui[1]; ++ prIeWmmParam->aucOui[2] = aucWfaOui[2]; ++ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; ++ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; ++ ++ prIeWmmParam->ucVersion = VERSION_WMM; ++ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); ++ ++ /* UAPSD initial queue configurations (delivery and trigger enabled) */ ++ if (prAdapter->rWifiVar.fgSupportUAPSD) ++ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; ++ ++ /* EDCA parameter */ ++ ++ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { ++ ++ /* DBGLOG(QM, LOUD, */ ++ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ ++ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ ++ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ ++ ++ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].fgIsACMSet ? ++ WMM_ACIAIFSN_ACM : 0) ++ | ++ (prBssInfo->arACQueParmsForBcast ++ [eAci].u2Aifsn & ++ (WMM_ACIAIFSN_AIFSN))); ++#if 1 ++ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 ++ | ++ (((prBssInfo->aucCWminLog2ForBcast ++ [eAci])) & WMM_ECW_WMIN_MASK) ++ | ++ ((((prBssInfo->aucCWmaxLog2ForBcast ++ [eAci])) << WMM_ECW_WMAX_OFFSET) ++ & WMM_ECW_WMAX_MASK) ++ ); ++#else ++ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 ++ | ++ (cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmin + ++ 1)) & WMM_ECW_WMIN_MASK) ++ | ++ ((cwlog2 ++ ((prBssInfo->arACQueParmsForBcast ++ [eAci].u2CWmax + ++ 1)) << WMM_ECW_WMAX_OFFSET) & ++ WMM_ECW_WMAX_MASK) ++ ); ++#endif ++ ++ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) ++ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); ++ ++ } ++ ++ /* Increment the total IE length for the Element ID and Length fields. */ ++ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmParam); ++#else ++ ++ prMsduInfo->u2FrameLength += mqmGenerateWmmParamIEByParam(prAdapter, ++ prBssInfo, (UINT_8 *) prIeWmmParam, OP_MODE_ACCESS_POINT); ++#endif ++} ++ ++ENUM_FRAME_ACTION_T ++qmGetFrameAction(IN P_ADAPTER_T prAdapter, ++ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, ++ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType) ++{ ++ P_BSS_INFO_T prBssInfo; ++ P_STA_RECORD_T prStaRec; ++ P_WLAN_MAC_HEADER_T prWlanFrame; ++ UINT_16 u2TxFrameCtrl; ++ ++ DEBUGFUNC("qmGetFrameAction"); ++ ++#if (NIC_TX_BUFF_COUNT_TC4 > 2) ++#define QM_MGMT_QUUEUD_THRESHOLD 2 ++#else ++#define QM_MGMT_QUUEUD_THRESHOLD 1 ++#endif ++ ++ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD <= (NIC_TX_BUFF_COUNT_TC4)); ++ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD > 0); ++ ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkType]); ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx); ++ ++ /* XXX Check BOW P2P AIS time ot set active */ ++ if (!IS_BSS_ACTIVE(prBssInfo)) { ++ if (eFrameType == FRAME_TYPE_MMPDU) { ++ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; ++ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ ++ if (((u2TxFrameCtrl == MAC_FRAME_DEAUTH) ++ && (prMsduInfo->pfTxDoneHandler == NULL)) ++ || (u2TxFrameCtrl == MAC_FRAME_ACTION)) /* whsu */ ++ return FRAME_ACTION_TX_PKT; ++ } ++ ++ DBGLOG(QM, WARN, "Drop packets Action, eFrameType: %d (Bss Index %u).\n", ++ eFrameType, prBssInfo->ucNetTypeIndex); ++ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); ++ return FRAME_ACTION_DROP_PKT; ++ } ++ ++ /* TODO Handle disconnect issue */ ++ ++ /* P2P probe Request frame */ ++ do { ++ if (eFrameType == FRAME_TYPE_MMPDU) { ++ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; ++ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ ++ ++ if (u2TxFrameCtrl == MAC_FRAME_BEACON) { ++ if (prBssInfo->fgIsNetAbsent) ++ return FRAME_ACTION_DROP_PKT; ++ } else if (u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { ++ if (prBssInfo->fgIsNetAbsent) ++ return FRAME_ACTION_DROP_PKT; ++ } else if (u2TxFrameCtrl == MAC_FRAME_DEAUTH) { ++ if (prBssInfo->fgIsNetAbsent) ++ break; ++ DBGLOG(P2P, LOUD, "Sending DEAUTH Frame\n"); ++ return FRAME_ACTION_TX_PKT; ++ } ++ /* MMPDU with prStaRec && fgIsInUse not check fgIsNetActive */ ++ else if (u2TxFrameCtrl == MAC_FRAME_ASSOC_REQ ++ || u2TxFrameCtrl == MAC_FRAME_AUTH ++ || u2TxFrameCtrl == MAC_FRAME_REASSOC_REQ ++ || u2TxFrameCtrl == MAC_FRAME_PROBE_REQ || u2TxFrameCtrl == MAC_FRAME_ACTION) { ++ ++ if ((prStaRec) && (prStaRec->fgIsInPS)) { ++ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) ++ return FRAME_ACTION_TX_PKT; ++ else ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ return FRAME_ACTION_TX_PKT; ++ } ++ ++ if (!prStaRec) ++ return FRAME_ACTION_TX_PKT; ++ ++ if (!prStaRec->fgIsInUse) ++ return FRAME_ACTION_DROP_PKT; ++ ++ } /* FRAME_TYPE_MMPDU */ ++ else if (eFrameType == FRAME_TYPE_802_1X) { ++ ++ if (!prStaRec) ++ return FRAME_ACTION_TX_PKT; ++ ++ if (!prStaRec->fgIsInUse) ++ return FRAME_ACTION_DROP_PKT; ++ if (prStaRec->fgIsInPS) { ++ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) ++ return FRAME_ACTION_TX_PKT; ++ else ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ ++ } /* FRAME_TYPE_802_1X */ ++ else if ((!IS_BSS_ACTIVE(prBssInfo)) ++ || (!prStaRec) ++ || (!prStaRec->fgIsInUse)) { ++ return FRAME_ACTION_DROP_PKT; ++ } ++ } while (0); ++ ++ if (prBssInfo->fgIsNetAbsent) { ++ DBGLOG(QM, LOUD, "Queue packets (Absent %u).\n", prBssInfo->ucNetTypeIndex); ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ ++ if (prStaRec && prStaRec->fgIsInPS) { ++ DBGLOG(QM, LOUD, "Queue packets (PS %u).\n", prStaRec->fgIsInPS); ++ return FRAME_ACTION_QUEUE_PKT; ++ } ++ switch (eFrameType) { ++ case FRAME_TYPE_802_1X: ++ if (!prStaRec->fgIsValid) ++ return FRAME_ACTION_QUEUE_PKT; ++ break; ++ ++ case FRAME_TYPE_MMPDU: ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ return FRAME_ACTION_TX_PKT; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle BSS change operation Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_BSS_ABSENCE_PRESENCE_T prEventBssStatus; ++ P_BSS_INFO_T prBssInfo; ++ BOOLEAN fgIsNetAbsentOld; ++ ++ prEventBssStatus = (P_EVENT_BSS_ABSENCE_PRESENCE_T) prEvent; ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prEventBssStatus->ucNetTypeIdx]); ++ fgIsNetAbsentOld = prBssInfo->fgIsNetAbsent; ++ prBssInfo->fgIsNetAbsent = prEventBssStatus->fgIsAbsent; ++ prBssInfo->ucBssFreeQuota = prEventBssStatus->ucBssFreeQuota; ++ ++ /* DBGLOG(QM, TRACE, ("qmHandleEventBssAbsencePresence (ucNetTypeIdx=%d, fgIsAbsent=%d, FreeQuota=%d)\n", */ ++ /* prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota)); */ ++ ++ DBGLOG(QM, INFO, "NAF=%d,%d,%d\n", ++ prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota); ++ ++ if (!prBssInfo->fgIsNetAbsent) { ++ /* QM_DBG_CNT_27 */ ++ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_27); ++ } else { ++ /* QM_DBG_CNT_28 */ ++ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_28); ++ } ++ /* From Absent to Present */ ++ if ((fgIsNetAbsentOld) && (!prBssInfo->fgIsNetAbsent)) ++ kalSetEvent(prAdapter->prGlueInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Handle STA change PS mode Event from the FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_STA_CHANGE_PS_MODE_T prEventStaChangePsMode; ++ P_STA_RECORD_T prStaRec; ++ BOOLEAN fgIsInPSOld; ++ ++ /* DbgPrint("QM:Event -RxBa\n"); */ ++ ++ prEventStaChangePsMode = (P_EVENT_STA_CHANGE_PS_MODE_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaChangePsMode->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) { ++ ++ fgIsInPSOld = prStaRec->fgIsInPS; ++ prStaRec->fgIsInPS = prEventStaChangePsMode->fgIsInPs; ++ ++ qmUpdateFreeQuota(prAdapter, ++ prStaRec, ++ prEventStaChangePsMode->ucUpdateMode, prEventStaChangePsMode->ucFreeQuota, 0); ++ ++ /* DBGLOG(QM, TRACE, ("qmHandleEventStaChangePsMode (ucStaRecIdx=%d, fgIsInPs=%d)\n", */ ++ /* prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS)); */ ++ ++ DBGLOG(QM, TRACE, "PS=%d,%d\n", prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS); ++ ++ /* From PS to Awake */ ++ if ((fgIsInPSOld) && (!prStaRec->fgIsInPS)) ++ kalSetEvent(prAdapter->prGlueInfo); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Update STA free quota Event from FW ++* ++* \param[in] prAdapter Adapter pointer ++* \param[in] prEvent The event packet from the FW ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) ++{ ++ P_EVENT_STA_UPDATE_FREE_QUOTA_T prEventStaUpdateFreeQuota; ++ P_STA_RECORD_T prStaRec; ++ ++ prEventStaUpdateFreeQuota = (P_EVENT_STA_UPDATE_FREE_QUOTA_T) prEvent; ++ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaUpdateFreeQuota->ucStaRecIdx); ++ ASSERT(prStaRec); ++ ++ if (prStaRec) { ++ if (prStaRec->fgIsInPS) { ++ qmUpdateFreeQuota(prAdapter, ++ prStaRec, ++ prEventStaUpdateFreeQuota->ucUpdateMode, ++ prEventStaUpdateFreeQuota->ucFreeQuota, ++ prEventStaUpdateFreeQuota->aucReserved[0]); ++ ++ kalSetEvent(prAdapter->prGlueInfo); ++ } ++#if 0 ++ DBGLOG(QM, TRACE, ++ "qmHandleEventStaUpdateFreeQuota (ucStaRecIdx=%d, ucUpdateMode=%d, ucFreeQuota=%d)\n", ++ prEventStaUpdateFreeQuota->ucStaRecIdx, prEventStaUpdateFreeQuota->ucUpdateMode, ++ prEventStaUpdateFreeQuota->ucFreeQuota); ++#endif ++ ++ DBGLOG(QM, TRACE, "UFQ=%d,%d,%d\n", ++ prEventStaUpdateFreeQuota->ucStaRecIdx, ++ prEventStaUpdateFreeQuota->ucUpdateMode, prEventStaUpdateFreeQuota->ucFreeQuota); ++ ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Update STA free quota ++* ++* \param[in] prStaRec the STA ++* \param[in] ucUpdateMode the method to update free quota ++* \param[in] ucFreeQuota the value for update ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, ++ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone) ++{ ++ ++ UINT_8 ucFreeQuotaForNonDelivery; ++ UINT_8 ucFreeQuotaForDelivery; ++ BOOLEAN flgIsUpdateForcedToDelivery; ++ ++ ASSERT(prStaRec); ++ DBGLOG(QM, LOUD, "qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n", ++ prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota); ++ ++ if (!prStaRec->fgIsInPS) ++ return; ++ ++ flgIsUpdateForcedToDelivery = FALSE; ++ ++ if (ucNumOfTxDone > 0) { ++ /* ++ update free quota by ++ num of tx done + resident free quota (delivery + non-delivery) ++ */ ++ UINT_8 ucAvailQuota; ++ ++ ucAvailQuota = ucNumOfTxDone + prStaRec->ucFreeQuotaForDelivery + prStaRec->ucFreeQuotaForNonDelivery; ++ if (ucAvailQuota > ucFreeQuota) /* sanity check */ ++ ucAvailQuota = ucFreeQuota; ++ ++ /* update current free quota */ ++ ucFreeQuota = ucAvailQuota; ++ ++ /* check if the update is from last packet */ ++ if (ucFreeQuota == (prStaRec->ucFreeQuota + 1)) { ++ /* just add the extra quota to delivery queue */ ++ ++ /* ++ EX: ++ 1. TDLS peer enters power save ++ 2. When the last 2 VI packets are tx done, we will receive 2 update events ++ 3. 1st update event: ucFreeQuota = 9 ++ 4. We will correct new quota for delivey and non-delivery to 7:2 ++ 5. 2rd update event: ucFreeQuota = 10 ++ 6. We will re-correct new quota for delivery and non-delivery to 5:5 ++ ++ But non-delivery queue is not busy. ++ So in the case, we will have wrong decision, i.e. higher queue always quota 5 ++ ++ Solution: skip the 2rd update event and just add the extra quota to delivery. ++ */ ++ ++ flgIsUpdateForcedToDelivery = TRUE; ++ } ++ } ++ ++ switch (ucUpdateMode) { ++ case FREE_QUOTA_UPDATE_MODE_INIT: ++ case FREE_QUOTA_UPDATE_MODE_OVERWRITE: ++ prStaRec->ucFreeQuota = ucFreeQuota; ++ break; ++ case FREE_QUOTA_UPDATE_MODE_INCREASE: ++ prStaRec->ucFreeQuota += ucFreeQuota; ++ break; ++ case FREE_QUOTA_UPDATE_MODE_DECREASE: ++ prStaRec->ucFreeQuota -= ucFreeQuota; ++ break; ++ default: ++ ASSERT(0); ++ } ++ ++ DBGLOG(QM, LOUD, "qmUpdateFreeQuota new ucFreeQuota=%d)\n", prStaRec->ucFreeQuota); ++ ++ ucFreeQuota = prStaRec->ucFreeQuota; ++ ++ ucFreeQuotaForNonDelivery = 0; ++ ucFreeQuotaForDelivery = 0; ++ ++ if (ucFreeQuota > 0) { ++ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported ++ /* && prAdapter->rWifiVar.fgSupportQoS ++ && prAdapter->rWifiVar.fgSupportUAPSD */) { ++ /* XXX We should assign quota to aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES] */ ++ ++ if (flgIsUpdateForcedToDelivery == FALSE) { ++ if (prStaRec->ucFreeQuotaForNonDelivery > 0 && prStaRec->ucFreeQuotaForDelivery > 0) { ++ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } else if (prStaRec->ucFreeQuotaForNonDelivery == 0 ++ && prStaRec->ucFreeQuotaForDelivery == 0) { ++ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } else if (prStaRec->ucFreeQuotaForNonDelivery > 0) { ++ /* NonDelivery is not busy */ ++ if (ucFreeQuota >= 3) { ++ ucFreeQuotaForNonDelivery = 2; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } else { ++ ucFreeQuotaForDelivery = ucFreeQuota; ++ ucFreeQuotaForNonDelivery = 0; ++ } ++ } else if (prStaRec->ucFreeQuotaForDelivery > 0) { ++ /* Delivery is not busy */ ++ if (ucFreeQuota >= 3) { ++ ucFreeQuotaForDelivery = 2; ++ ucFreeQuotaForNonDelivery = ucFreeQuota - ucFreeQuotaForDelivery; ++ } else { ++ ucFreeQuotaForNonDelivery = ucFreeQuota; ++ ucFreeQuotaForDelivery = 0; ++ } ++ } ++ } else { ++ ucFreeQuotaForNonDelivery = 2; ++ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; ++ } ++ } else { ++ /* no use ? */ ++ /* !prStaRec->fgIsUapsdSupported */ ++ ucFreeQuotaForNonDelivery = ucFreeQuota; ++ ucFreeQuotaForDelivery = 0; ++ } ++ } ++ /* ucFreeQuota > 0 */ ++ prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery; ++ prStaRec->ucFreeQuotaForNonDelivery = ucFreeQuotaForNonDelivery; ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ if (IS_TDLS_STA(prStaRec)) ++ DBGLOG(QM, LOUD, " quota %d %d %d\n", ++ ucFreeQuota, ucFreeQuotaForDelivery, ucFreeQuotaForNonDelivery); ++#endif ++ ++ DBGLOG(QM, LOUD, "new QuotaForDelivery = %d QuotaForNonDelivery = %d\n", ++ prStaRec->ucFreeQuotaForDelivery, prStaRec->ucFreeQuotaForNonDelivery); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Return the reorder queued RX packets ++* ++* \param[in] (none) ++* ++* \return The number of queued RX packets ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter) ++{ ++ UINT_32 i, u4Total; ++ P_QUE_MGT_T prQM = &prAdapter->rQM; ++ ++ u4Total = 0; ++ /* XXX The summation may impact the performance */ ++ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { ++ u4Total += prQM->arRxBaTable[i].rReOrderQue.u4NumElem; ++#if DBG && 0 ++ if (QUEUE_IS_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) ++ ASSERT(prQM->arRxBaTable[i].rReOrderQue == 0); ++#endif ++ } ++ ASSERT(u4Total <= (CFG_NUM_OF_QM_RX_PKT_NUM * 2)); ++ return u4Total; ++} ++ ++#if ARP_MONITER_ENABLE ++VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) ++{ ++ struct sk_buff *prSkb = NULL; ++ PUINT_8 pucData = NULL; ++ UINT_16 u2EtherType = 0; ++ int arpOpCode = 0; ++ ++ prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ ++ if (!prSkb || (prSkb->len <= ETHER_HEADER_LEN)) ++ return; ++ ++ pucData = prSkb->data; ++ if (!pucData) ++ return; ++ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if (u2EtherType != ETH_P_ARP || (apIp[0] | apIp[1] | apIp[2] | apIp[3]) == 0) ++ return; ++ ++ if (strncmp(apIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], sizeof(apIp))) /* dest ip address */ ++ return; ++ ++ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); ++ if (arpOpCode == ARP_PRO_REQ) { ++ arpMoniter++; ++ if (arpMoniter > 20) { ++ DBGLOG(INIT, WARN, "IOT Critical issue, arp no resp, check AP!\n"); ++ aisBssBeaconTimeout(prAdapter); ++ arpMoniter = 0; ++ kalMemZero(apIp, sizeof(apIp)); ++ } ++ } ++} ++ ++VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) ++{ ++ PUINT_8 pucData = NULL; ++ UINT_16 u2EtherType = 0; ++ int arpOpCode = 0; ++ P_BSS_INFO_T prBssInfo = NULL; ++ ++ if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) ++ return; ++ ++ pucData = (PUINT_8)prSwRfb->pvHeader; ++ if (!pucData) ++ return; ++ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if (u2EtherType != ETH_P_ARP) ++ return; ++ ++ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); ++ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); ++ if (arpOpCode == ARP_PRO_RSP) { ++ arpMoniter = 0; ++ if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { ++ if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ ++ prBssInfo->prStaRecOfAP->aucMacAddr)) { ++ strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ ++ DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", ++ apIp[0], apIp[1], apIp[2], apIp[3]); ++ } ++ } ++ } ++} ++ ++VOID qmResetArpDetect(VOID) ++{ ++ arpMoniter = 0; ++ kalMemZero(apIp, sizeof(apIp)); ++} ++#endif ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c +new file mode 100644 +index 000000000000..6f5c0bcdd90b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c +@@ -0,0 +1,1177 @@ ++/* ++** Id: @(#) gl_bow.c@@ ++*/ ++ ++/*! \file gl_bow.c ++ \brief Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS) ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_bow.c ++ * ++ * 02 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * [ALPS00235223] [Rose][ICS][Cross Feature][AEE-IPANIC]The device reboot automatically and then the "KE" pops up ++ * after you turn on the "Airplane mode".(once) ++ * ++ * [Root Cause] ++ * PAL operates BOW char dev poll after BOW char dev is registered. ++ * ++ * [Solution] ++ * Rejects PAL char device operation after BOW is unregistered or when wlan GLUE_FLAG_HALT is set. ++ * ++ * This is a workaround for BOW driver robustness, happens only in ICS. ++ * ++ * Root cause should be fixed by CR [ALPS00231570] ++ * ++ * 02 03 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5) ++ * ++ * [Root Cause] ++ * PAL operates BOW char dev poll after BOW char dev is registered. ++ * ++ * [Solution] ++ * Rejects PAL char device operation after BOW is unregistered. ++ * ++ * Happens only in ICS. ++ * ++ * Notified PAL owener to reivew MTKBT/PAL closing BOW char dev procedure. ++ * ++ * [Side Effect] ++ * None. ++ * ++ * 01 16 2012 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support BOW for 5GHz band. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 25 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Modify ampc0 char device for major number 151 for all MT6575 projects. ++ * ++ * 07 28 2011 cp.wu ++ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl ++ * unlocked_ioctl returns as long instead of int. ++ * ++ * 07 28 2011 cp.wu ++ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl ++ * migrate to unlocked ioctl interface ++ * ++ * 04 12 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add WMM IE for BOW initiator data. ++ * ++ * 04 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. ++ * ++ * 04 09 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Change Link connection event procedure and change skb length check to 1512 bytes. ++ * ++ * 03 27 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Support multiple physical link. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * replace alloc_netdev to alloc_netdev_mq for BoW ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 02 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Update net register and BOW for concurrent features. ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 ++ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 ++ * with BOW and P2P enabled as default ++ * ++ * 02 08 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. ++ * Update BOW get MAC status, remove returning event for AIS network type. ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation ++ * needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 11 11 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix BoW timer assert issue. ++ * ++ * 09 14 2010 chinghwa.yu ++ * NULL ++ * Add bowRunEventAAAComplete. ++ * ++ * 09 14 2010 cp.wu ++ * NULL ++ * correct typo: POLLOUT instead of POLL_OUT ++ * ++ * 09 13 2010 cp.wu ++ * NULL ++ * add waitq for poll() and read(). ++ * ++ * 08 24 2010 chinghwa.yu ++ * NULL ++ * Update BOW for the 1st time. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 05 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change variable names for multiple physical link to match with coding convention ++ * ++ * 05 05 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * multiple BoW interfaces need to compare with peer address ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * fix kalIndicateBOWEvent. ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability ++ * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" ++#include "debug.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#include ++#include "bss.h" ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* @FIXME if there is command/event with payload length > 28 */ ++#define MAX_BUFFER_SIZE (64) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_BOW_TEST ++UINT_32 g_u4PrevSysTime = 0; ++UINT_32 g_u4CurrentSysTime = 0; ++UINT_32 g_arBowRevPalPacketTime[11]; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* forward declarations */ ++static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos); ++ ++static ssize_t ++mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos); ++ ++static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg); ++ ++static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait); ++ ++static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp); ++ ++static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp); ++ ++/* character file operations */ ++static const struct file_operations mt6620_ampc_fops = { ++ /* .owner = THIS_MODULE, */ ++ .read = mt6620_ampc_read, ++ .write = mt6620_ampc_write, ++ .unlocked_ioctl = mt6620_ampc_ioctl, ++ .poll = mt6620_ampc_poll, ++ .open = mt6620_ampc_open, ++ .release = mt6620_ampc_release, ++}; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Register for character device to communicate with 802.11 PAL ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glRegisterAmpc(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE) ++ return FALSE; ++ ++#if 0 ++ /* 1. allocate major number dynamically */ ++ ++ if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0, /* first minor number */ ++ 1, /* number */ ++ GLUE_BOW_DEVICE_NAME) != 0) ++ ++ return FALSE; ++#endif ++ ++#if 1 ++ ++#if defined(CONFIG_AMPC_CDEV_NUM) ++ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0); ++#else ++ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0); ++#endif ++ ++ if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1, /* number */ ++ GLUE_BOW_DEVICE_NAME) != 0) ++ ++ return FALSE; ++#endif ++ ++ /* 2. spin-lock initialization */ ++ /* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */ ++ ++ /* 3. initialize kfifo */ ++/* prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH, ++ GFP_KERNEL, ++ &(prGlueInfo->rBowInfo.rSpinLock));*/ ++ if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL))) ++ goto fail_kfifo_alloc; ++ ++/* if(prGlueInfo->rBowInfo.prKfifo == NULL) */ ++ if (&(prGlueInfo->rBowInfo.rKfifo) == NULL) ++ goto fail_kfifo_alloc; ++ ++ /* 4. initialize cdev */ ++ cdev_init(&(prGlueInfo->rBowInfo.cdev), &mt6620_ampc_fops); ++ /* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */ ++ prGlueInfo->rBowInfo.cdev.ops = &mt6620_ampc_fops; ++ ++ /* 5. add character device */ ++ if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1)) ++ goto fail_cdev_add; ++ ++ /* 6. in queue initialization */ ++ init_waitqueue_head(&(prGlueInfo->rBowInfo.outq)); ++ ++ /* 7. finish */ ++ prGlueInfo->rBowInfo.fgIsRegistered = TRUE; ++ return TRUE; ++ ++fail_cdev_add: ++ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); ++/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ ++fail_kfifo_alloc: ++ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); ++ return FALSE; ++} /* end of glRegisterAmpc */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Unregister character device for communicating with 802.11 PAL ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glUnregisterAmpc(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE) ++ return FALSE; ++ ++ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; ++ ++ /* 1. free netdev if necessary */ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ kalUninitBowDevice(prGlueInfo); ++#endif ++ ++ /* 2. removal of character device */ ++ cdev_del(&(prGlueInfo->rBowInfo.cdev)); ++ ++ /* 3. free kfifo */ ++/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ ++ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); ++/* prGlueInfo->rBowInfo.prKfifo = NULL; */ ++/* prGlueInfo->rBowInfo.rKfifo = NULL; */ ++ ++ /* 4. free device number */ ++ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); ++ ++ return TRUE; ++} /* end of glUnregisterAmpc */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief read handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos) ++{ ++ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; ++ ssize_t retval; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ /* size check */ ++/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */ ++ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size) ++ retval = size; ++ else ++ retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); ++/* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */ ++ ++/* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ ++/* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ ++ if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) { ++ retval = -EIO; ++ return retval; ++ } ++ ++ if (copy_to_user(buf, aucBuffer, retval)) ++ retval = -EIO; ++ ++ return retval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief write handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t ++mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos) ++{ ++#if CFG_BOW_TEST ++ UINT_8 i; ++#endif ++ ++ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; ++ P_AMPC_COMMAND prCmd; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ ++ if (size > MAX_BUFFER_SIZE) ++ return -EINVAL; ++ else if (copy_from_user(aucBuffer, buf, size)) ++ return -EIO; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size); ++ ++ for (i = 0; i < MAX_BUFFER_SIZE; i++) ++ DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]); ++ ++ DBGLOG(BOW, EVENT, "BoW CMD write.\n"); ++#endif ++ ++ prCmd = (P_AMPC_COMMAND) aucBuffer; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength); ++ ++ DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(AMPC_COMMAND_HEADER_T)); ++#endif ++ ++ /* size check */ ++ if (prCmd->rHeader.u2PayloadLength + sizeof(AMPC_COMMAND_HEADER_T) != size) { ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "Wrong CMD total length.\n"); ++#endif ++ ++ return -EINVAL; ++ } ++ ++ if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS) ++ return size; ++ else ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ioctl handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg) ++{ ++ int err = 0; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ /* permission check */ ++ if (_IOC_DIR(cmd) & _IOC_READ) ++ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); ++ else if (_IOC_DIR(cmd) & _IOC_WRITE) ++ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); ++ if (err) ++ return -EFAULT; ++ ++ /* no ioctl is implemented yet */ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ioctl handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait) ++{ ++ unsigned int retval; ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return -EFAULT; ++ ++ poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait); ++ ++ retval = (POLLOUT | POLLWRNORM); /* always accepts incoming command packets */ ++ ++/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */ ++ ++/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */ ++ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) { ++ retval |= (POLLIN | POLLRDNORM); ++ ++/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */ ++ ++ } ++ ++ return retval; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief open handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ P_GL_BOW_INFO prBowInfo; ++ ++ prBowInfo = container_of(inodep->i_cdev, GL_BOW_INFO, cdev); ++ ASSERT(prBowInfo); ++ ++ prGlueInfo = container_of(prBowInfo, GLUE_INFO_T, rBowInfo); ++ ASSERT(prGlueInfo); ++ ++ /* set-up private data */ ++ filp->private_data = prGlueInfo; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief close handler for character device to communicate with 802.11 PAL ++* ++* \param[in] ++* \return ++* Follows Linux Character Device Interface ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ++ ++ ASSERT(prGlueInfo); ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to indicate event for Bluetooth over Wi-Fi ++* ++* \param[in] ++* prGlueInfo ++* prEvent ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent) ++{ ++ size_t u4AvailSize, u4EventSize; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prEvent); ++ ++ /* check device */ ++ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) ++ return; ++ ++/* u4AvailSize = ++ GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo);*/ ++ ++ u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); ++ ++ u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(AMPC_EVENT_HEADER_T); ++ ++ /* check kfifo availability */ ++ if (u4AvailSize < u4EventSize) { ++ DBGLOG(BOW, EVENT, "[bow] no space for event: %zu/%zu\n", u4EventSize, u4AvailSize); ++ return; ++ } ++ /* queue into kfifo */ ++/* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ ++/* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ ++ kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (PUINT_8) prEvent, u4EventSize); ++ wake_up_interruptible(&(prGlueInfo->rBowInfo.outq)); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer ++* ++* \param[in] ++* prGlueInfo ++* rPeerAddr ++* \return ++* ENUM_BOW_DEVICE_STATE ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 i; ++ ++ ASSERT(prGlueInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalGetBowState.\n"); ++#endif ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, ++ prGlueInfo->rBowInfo.aeState[i]); ++ ++#endif ++ ++ return prGlueInfo->rBowInfo.aeState[i]; ++ } ++ } ++ ++ return BOW_DEVICE_STATE_DISCONNECTED; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Bluetooth-over-Wi-Fi state in glue layer ++* ++* \param[in] ++* prGlueInfo ++* eBowState ++* rPeerAddr ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, IN UINT_8 aucPeerAddress[6]) ++{ ++ UINT_8 i; ++ ++ ASSERT(prGlueInfo); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalSetBowState.\n"); ++ ++ DBGLOG(BOW, EVENT, "kalSetBowState, prGlueInfo->rBowInfo.arPeerAddr, %x:%x:%x:%x:%x:%x.\n", ++ prGlueInfo->rBowInfo.arPeerAddr[0], ++ prGlueInfo->rBowInfo.arPeerAddr[1], ++ prGlueInfo->rBowInfo.arPeerAddr[2], ++ prGlueInfo->rBowInfo.arPeerAddr[3], ++ prGlueInfo->rBowInfo.arPeerAddr[4], prGlueInfo->rBowInfo.arPeerAddr[5])); ++ ++ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); ++#endif ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { ++ prGlueInfo->rBowInfo.aeState[i] = eBowState; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, ++ aucPeerAddress[0], ++ aucPeerAddress[1], ++ aucPeerAddress[2], ++ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); ++ ++ DBGLOG(BOW, EVENT, ++ "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, ++ prGlueInfo->rBowInfo.aeState[i]); ++#endif ++ ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi global state ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* BOW_DEVICE_STATE_DISCONNECTED ++* in case there is no BoW connection or ++* BoW connection under initialization ++* ++* BOW_DEVICE_STATE_STARTING ++* in case there is no BoW connection but ++* some BoW connection under initialization ++* ++* BOW_DEVICE_STATE_CONNECTED ++* in case there is any BoW connection available ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ++/* Henry, can reduce this logic to indentify state change */ ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED) ++ return BOW_DEVICE_STATE_CONNECTED; ++ } ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING) ++ return BOW_DEVICE_STATE_STARTING; ++ } ++ ++ return BOW_DEVICE_STATE_DISCONNECTED; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi operating frequency ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* in unit of KHz ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rBowInfo.u4FreqInKHz; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi role ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* 0: Responder ++* 1: Initiator ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr) ++{ ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) ++ return prGlueInfo->rBowInfo.aucRole[i]; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Bluetooth-over-Wi-Fi role ++* ++* \param[in] ++* prGlueInfo ++* ucRole ++* 0: Responder ++* 1: Initiator ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr) ++{ ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ucRole <= 1); ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) ++ prGlueInfo->rBowInfo.aucRole[i] = ucRole; /* Henry, 0 : Responder, 1 : Initiator */ ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get available Bluetooth-over-Wi-Fi physical link number ++* ++* \param[in] ++* prGlueInfo ++* \return ++* UINT_32 ++* how many physical links are aviailable ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_8 i; ++ UINT_8 ucLinkCount = 0; ++ ++ ASSERT(prGlueInfo); ++ ++ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { ++ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED) ++ ucLinkCount++; ++ } ++ ++#if 0 /* CFG_BOW_TEST */ ++ DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount); ++#endif ++ ++ return ucLinkCount; ++} ++ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ ++/* Net Device Hooks */ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device open (ifup) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int bowOpen(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* 2. carrier on & start TX queue */ ++ netif_carrier_on(prDev); ++ netif_tx_start_all_queues(prDev); ++ ++ return 0; /* success */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device stop (ifdown) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int bowStop(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* 1. stop TX queue */ ++ netif_tx_stop_all_queues(prDev); ++ ++ /* 2. turn of carrier */ ++ if (netif_carrier_ok(prDev)) ++ netif_carrier_off(prDev); ++ ++ return 0; ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This function is TX entry point of NET DEVICE. ++ * ++ * \param[in] prSkb Pointer of the sk_buff to be sent ++ * \param[in] prDev Pointer to struct net_device ++ * ++ * \retval NETDEV_TX_OK - on success. ++ * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_QUE_T prTxQueue = NULL; ++ UINT_16 u2QueueIdx = 0; ++ UINT_8 ucDSAP, ucSSAP, ucControl; ++ UINT_8 aucOUI[3]; ++ PUINT_8 aucLookAheadBuf = NULL; ++ ++#if CFG_BOW_TEST ++ UINT_32 i; ++#endif ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prSkb); ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ ++ aucLookAheadBuf = prSkb->data; ++ ++ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; ++ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; ++ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; ++ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; ++ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; ++ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; ++ prGlueInfo->u8SkbToDriver++; ++ ++ if (!(ucDSAP == ETH_LLC_DSAP_SNAP && ++ ucSSAP == ETH_LLC_SSAP_SNAP && ++ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && ++ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && ++ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) { ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "Invalid BOW packet, skip tx\n"); ++#endif ++ ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n"); ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++ ++ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); ++ prTxQueue = &prGlueInfo->rTxQueue; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "Tx sk_buff->len: %d\n", prSkb->len); ++ DBGLOG(BOW, TRACE, "Tx sk_buff->data_len: %d\n", prSkb->data_len); ++ DBGLOG(BOW, TRACE, "Tx sk_buff->data:\n"); ++ ++ for (i = 0; i < prSkb->len; i++) { ++ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); ++ ++ if ((i + 1) % 16 == 0) ++ DBGLOG(BOW, TRACE, "\n"); ++ } ++ ++ DBGLOG(BOW, TRACE, "\n"; ++#endif ++#if CFG_BOW_TEST ++/* g_u4CurrentSysTime = (OS_SYSTIME)kalGetTimeTick(; */ ++ g_u4CurrentSysTime = (OS_SYSTIME) jiffies_to_usecs(jiffies); ++ i = g_u4CurrentSysTime - g_u4PrevSysTime; ++ if ((i >> 10) > 0) ++ i = 10; ++ else ++ i = i >> 7; ++ g_arBowRevPalPacketTime[i]++; ++ g_u4PrevSysTime = g_u4CurrentSysTime; ++#endif ++ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); ++ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx] >= ++ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) ++ DBGLOG(TX, INFO, "netif_stop_subqueue for BOW, Queue len: %d\n", ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); ++ ++ netif_stop_subqueue(prDev, u2QueueIdx); ++ } else { ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++ } ++ ++ kalSetEvent(prGlueInfo); ++ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ ++ return NETDEV_TX_OK; ++} ++ ++/* callbacks for netdevice */ ++static const struct net_device_ops bow_netdev_ops = { ++ .ndo_open = bowOpen, .ndo_stop = bowStop, .ndo_start_xmit = bowHardStartXmit,}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief initialize net device for Bluetooth-over-Wi-Fi ++* ++* \param[in] ++* prGlueInfo ++* prDevName ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName) ++{ ++ P_ADAPTER_T prAdapter; ++ P_GL_HIF_INFO_T prHif; ++ PARAM_MAC_ADDRESS rMacAddr; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ prHif = &prGlueInfo->rHifInfo; ++ ASSERT(prHif); ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) { ++ prGlueInfo->rBowInfo.prDevHandler = ++ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); ++ if (!prGlueInfo->rBowInfo.prDevHandler) ++ return FALSE; ++ ++ /* 1. setup netdev */ ++ /* 1.1 Point to shared glue structure */ ++ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo; ++ /* 1.2 fill hardware address */ ++ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); ++ rMacAddr[0] |= 0x2; ++ /* change to local administrated address */ ++ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr); ++ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->perm_addr, ++ prGlueInfo->rBowInfo.prDevHandler->dev_addr); ++ /* 1.3 register callback functions */ ++ prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops; ++#if (MTK_WCN_HIF_SDIO == 0) ++ SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, prHif->Dev); ++#endif ++ register_netdev(prGlueInfo->rBowInfo.prDevHandler); ++ /* 2. net device initialize */ ++ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); ++ /* 3. finish */ ++ prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE; ++ } ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief uninitialize net device for Bluetooth-over-Wi-Fi ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ /* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */ ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) { ++ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; ++ if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler)) ++ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); ++ ++ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); ++ /* netdevice unregistration & free */ ++ unregister_netdev(prGlueInfo->rBowInfo.prDevHandler); ++ free_netdev(prGlueInfo->rBowInfo.prDevHandler); ++ prGlueInfo->rBowInfo.prDevHandler = NULL; ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++#endif /* CFG_BOW_SEPARATE_DATA_PATH */ ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c +new file mode 100644 +index 000000000000..1fed65ebc60e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c +@@ -0,0 +1,3110 @@ ++/* ++** Id: @(#) gl_cfg80211.c@@ ++*/ ++ ++/*! \file gl_cfg80211.c ++ \brief Main routines for supporintg MT6620 cfg80211 control interface ++ ++ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_cfg80211.c ++** ++** 09 05 2013 cp.wu ++** correct length to pass to wlanoidSetBssid() ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 11 23 2012 yuche.tsai ++** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely ++** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" ++#include "debug.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#include ++#include ++#include ++#include "gl_cfg80211.h" ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor ++to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause ++is that there is no resource in TC4, so del key command was not able to set, and then oid ++timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this ++workaround */ ++static UINT_8 gucKeyIndex = 255; ++ ++P_SW_RFB_T g_arGscnResultsTempBuffer[MAX_BUFFERED_GSCN_RESULTS]; ++UINT_8 g_GscanResultsTempBufferIndex = 0; ++UINT_8 g_arGscanResultsIndicateNumber[MAX_BUFFERED_GSCN_RESULTS] = { 0, 0, 0, 0, 0 }; ++ ++UINT_8 g_GetResultsBufferedCnt = 0; ++UINT_8 g_GetResultsCmdCnt = 0; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for change STA type between ++ * 1. Infrastructure Client (Non-AP STA) ++ * 2. Ad-Hoc IBSS ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_change_iface(struct wiphy *wiphy, ++ struct net_device *ndev, enum nl80211_iftype type, /*u32 *flags,*/ struct vif_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (type == NL80211_IFTYPE_STATION) ++ eOpMode = NET_TYPE_INFRA; ++ else if (type == NL80211_IFTYPE_ADHOC) ++ eOpMode = NET_TYPE_IBSS; ++ else ++ return -EINVAL; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", rStatus); ++ ++ /* reset wpa info */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for adding key ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) ++{ ++ PARAM_KEY_T rKey; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Rslt = -EINVAL; ++ UINT_32 u4BufLen = 0; ++ UINT_8 tmp1[8]; ++ UINT_8 tmp2[8]; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(&rKey, sizeof(PARAM_KEY_T)); ++ ++ rKey.u4KeyIndex = key_index; ++ ++ if (mac_addr) { ++ COPY_MAC_ADDR(rKey.arBSSID, mac_addr); ++ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && ++ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ } ++ if (rKey.arBSSID[0] != 0xFF) { ++ rKey.u4KeyIndex |= BIT(31); ++ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || ++ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) ++ rKey.u4KeyIndex |= BIT(30); ++ } ++ } else { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ /* rKey.u4KeyIndex |= BIT(31);//Enable BIT 31 will make tx use bc key id,should use pairwise key id 0 */ ++ } ++ ++ if (params->key) { ++ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ ++ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); ++ if (params->key_len == 32) { ++ kalMemCopy(tmp1, ¶ms->key[16], 8); ++ kalMemCopy(tmp2, ¶ms->key[24], 8); ++ kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); ++ kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); ++ } ++ } ++ ++ rKey.u4KeyLength = params->key_len; ++ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) ++ i4Rslt = 0; ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for getting key for specified STA ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ /* not implemented */ ++ ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for removing key for specified STA ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ PARAM_REMOVE_KEY_T rRemoveKey; ++ UINT_32 u4BufLen = 0; ++ INT_32 i4Rslt = -EINVAL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); ++ if (mac_addr) ++ COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); ++ else if (key_index <= gucKeyIndex) { /* new operation, reset gucKeyIndex */ ++ gucKeyIndex = 255; ++ } else { /* bypass the next remove key operation */ ++ gucKeyIndex = key_index; ++ return -EBUSY; ++ } ++ rRemoveKey.u4KeyIndex = key_index; ++ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "remove key error:%x\n", rStatus); ++ if (WLAN_STATUS_FAILURE == rStatus && mac_addr) { ++ i4Rslt = -EBUSY; ++ gucKeyIndex = key_index; ++ } ++ } else { ++ gucKeyIndex = 255; ++ i4Rslt = 0; ++ } ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for setting default key on an interface ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ /* not implemented */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for setting set_default_mgmt_ke on an interface ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for getting station information such as RSSI ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo) ++{ ++#define LINKSPEED_MAX_RANGE_11BGN 3000 ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ PARAM_MAC_ADDRESS arBssid; ++ UINT_32 u4BufLen; ++ UINT_32 u4Rate = 0; ++ UINT_32 u8diffTxBad, u8diffRetry; ++ INT_32 i4Rssi = 0; ++ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(arBssid, MAC_ADDR_LEN); ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); ++ ++ /* 1. check BSSID */ ++ if (UNEQUAL_MAC_ADDR(arBssid, mac)) { ++ /* wrong MAC address */ ++ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", ++ mac, arBssid); ++ return -ENOENT; ++ } ++ ++ /* 2. fill TX rate */ ++ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { ++ /* not connected */ ++ DBGLOG(REQ, WARN, "not yet connected\n"); ++ } else { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); ++ ++ if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) { ++ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n")); */ ++ DBGLOG(REQ, WARN, "last link speed\n"); ++ sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache; ++ } else { ++ /* sinfo->filled |= STATION_INFO_TX_BITRATE; */ ++ sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */ ++ prGlueInfo->u4LinkSpeedCache = u4Rate / 1000; ++ } ++ } ++ ++ /* 3. fill RSSI */ ++ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { ++ /* not connected */ ++ DBGLOG(REQ, WARN, "not yet connected\n"); ++ } else { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM) ++ || (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) { ++ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n"); */ ++ DBGLOG(REQ, WARN, "last rssi\n"); ++ sinfo->signal = prGlueInfo->i4RssiCache; ++ } else { ++ /* in the cfg80211 layer, the signal is a signed char variable. */ ++ sinfo->signal = i4Rssi; /* dBm */ ++ prGlueInfo->i4RssiCache = i4Rssi; ++ } ++ sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets; ++ ++ /* 4. Fill Tx OK and Tx Bad */ ++ ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); ++ { ++ WLAN_STATUS rStatus; ++ ++ kalMemZero(&rStatistics, sizeof(rStatistics)); ++ /* Get Tx OK/Fail cnt from AIS statistic counter */ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatisticsPL, ++ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "unable to retrieive statistic\n"); ++ } else { ++ INT_32 i4RssiThreshold = -85; /* set rssi threshold -85dBm */ ++ UINT_32 u4LinkspeedThreshold = 55; /* set link speed threshold 5.5Mbps */ ++ BOOLEAN fgWeighted = 0; ++ ++ /* calculate difference */ ++ u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0]; ++ u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1]; ++ /* restore counters */ ++ prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart; ++ prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart; ++ ++ /* check threshold is valid */ ++ if (prGlueInfo->fgPoorlinkValid) { ++ if (prGlueInfo->i4RssiThreshold) ++ i4RssiThreshold = prGlueInfo->i4RssiThreshold; ++ if (prGlueInfo->u4LinkspeedThreshold) ++ u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold; ++ } ++ /* add weighted to fail counter */ ++ if (sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold) { ++ prGlueInfo->u8TotalFailCnt += (u8diffTxBad * 16 + u8diffRetry); ++ fgWeighted = 1; ++ } else { ++ prGlueInfo->u8TotalFailCnt += u8diffTxBad; ++ } ++ /* report counters */ ++ prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart; ++ prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt; ++ ++ sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets; ++ sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors; ++ /* Good Fail Bad Difference retry difference Linkspeed Rate Weighted */ ++ DBGLOG(REQ, TRACE, ++ "Poorlink State TxOK(%d) TxFail(%d) Bad(%d) Retry(%d)", ++ sinfo->tx_packets, ++ sinfo->tx_failed, ++ (int)u8diffTxBad, ++ (int)u8diffRetry); ++ DBGLOG(REQ, TRACE, ++ "Rate(%d) Signal(%d) Weight(%d) QuadPart(%d)\n", ++ sinfo->txrate.legacy, ++ sinfo->signal, ++ (int)fgWeighted, ++ (int)rStatistics.rMultipleRetryCount.QuadPart); ++ } ++ } ++ ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for adding a station information ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params) ++{ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* ++ EX: In supplicant, ++ (Supplicant) wpa_tdls_process_tpk_m3() -> ++ (Supplicant) wpa_tdls_enable_link() -> ++ (Supplicant) wpa_sm_tdls_peer_addset() -> ++ (Supplicant) ..tdls_peer_addset() -> ++ (Supplicant) wpa_supplicant_tdls_peer_addset() -> ++ (Supplicant) wpa_drv_sta_add() -> ++ (Supplicant) ..sta_add() -> ++ (Supplicant) wpa_driver_nl80211_sta_add() -> ++ (NL80211) nl80211_set_station() -> ++ (Driver) mtk_cfg80211_change_station() ++ ++ if nl80211_set_station fails, supplicant will tear down the link. ++ */ ++ P_GLUE_INFO_T prGlueInfo; ++ TDLS_CMD_PEER_UPDATE_T rCmdUpdate; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen, u4Temp; ++ ++ /* sanity check */ ++ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) ++ return -EINVAL; ++ ++ DBGLOG(TDLS, INFO, "%s: 0x%p 0x%x\n", __func__, params->supported_rates, params->sta_flags_set); ++ ++ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) ++ return -EOPNOTSUPP; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) ++ return -EINVAL; ++ ++ /* TODO: check if we are station mode, not AP mode */ ++ ++ /* init */ ++ kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate)); ++ kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6); ++ ++ if (params->supported_rates != NULL) { ++ u4Temp = params->supported_rates_len; ++ if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX) { ++ u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX; ++ DBGLOG(TDLS, ERROR, "%s sup rate too long: %d\n", __func__, params->supported_rates_len); ++ } ++ kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp); ++ rCmdUpdate.u2SupRateLen = u4Temp; ++ } ++ ++ /* ++ In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM ++ So force to support UAPSD here. ++ */ ++ rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */ ++ rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */ ++ ++ DBGLOG(TDLS, INFO, "%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n", ++ __func__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp); ++ ++ rCmdUpdate.u2Capability = params->capability; ++ ++ if (params->ext_capab != NULL) { ++ u4Temp = params->ext_capab_len; ++ if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN) { ++ u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN; ++ DBGLOG(TDLS, ERROR, "%s ext_capab too long: %d\n", __func__, params->ext_capab_len); ++ } ++ kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp); ++ rCmdUpdate.u2ExtCapLen = u4Temp; ++ } ++ ++ if (params->ht_capa != NULL) { ++ DBGLOG(TDLS, INFO, "%s: peer is 11n device\n", __func__); ++ ++ rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info; ++ rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info; ++ rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info; ++ rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info; ++ rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info; ++ kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask, ++ params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask)); ++ rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest; ++ rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params; ++ rCmdUpdate.fgIsSupHt = TRUE; ++ } ++ ++ /* update a TDLS peer record */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexPeerUpdate, ++ &rCmdUpdate, sizeof(TDLS_CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s update error:%x\n", __func__, rStatus); ++ return -EINVAL; ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for adding a station information ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params) ++{ ++#if (CFG_SUPPORT_TDLS == 1) ++ /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ ++ P_GLUE_INFO_T prGlueInfo; ++ TDLS_CMD_PEER_ADD_T rCmdCreate; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) ++ return -EINVAL; ++ ++ /* ++ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, ++ NULL, 0); ++ ++ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, ++ u16 aid, u16 capability, const u8 *supp_rates, ++ size_t supp_rates_len, ++ const struct ieee80211_ht_capabilities *ht_capab, ++ const struct ieee80211_vht_capabilities *vht_capab, ++ u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len) ++ ++ Only MAC address of the peer is valid. ++ */ ++ ++ DBGLOG(TDLS, INFO, "%s: 0x%p %d\n", __func__, params->supported_rates, params->supported_rates_len); ++ ++ /* sanity check */ ++ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) ++ return -EOPNOTSUPP; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (prGlueInfo == NULL) ++ return -EINVAL; ++ ++ /* TODO: check if we are station mode, not AP mode */ ++ ++ /* init */ ++ kalMemZero(&rCmdCreate, sizeof(rCmdCreate)); ++ kalMemCopy(rCmdCreate.aucPeerMac, mac, 6); ++ ++#if 0 ++ rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; ++ ++ rCmdCreate.u2CapInfo = params->capability; ++ ++ DBGLOG(TDLS, INFO, " %s: capability = 0x%x\n", __func__, rCmdCreate.u2CapInfo); ++ ++ if ((params->supported_rates != NULL) && (params->supported_rates_len != 0)) { ++ UINT32 u4Idx; ++ ++ DBGLOG(TDLS, INFO, " %s: sup rate = 0x", __func__); ++ ++ rIeSup.ucId = ELEM_ID_SUP_RATES; ++ rIeSup.ucLength = params->supported_rates_len; ++ for (u4Idx = 0; u4Idx < rIeSup.ucLength; u4Idx++) { ++ rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx]; ++ DBGLOG(TDLS, INFO, "%x ", rIeSup.aucSupportedRates[u4Idx]); ++ } ++ DBGLOG(TDLS, INFO, "\n"); ++ ++ rateGetRateSetFromIEs(&rIeSup, ++ NULL, ++ &rCmdCreate.u2OperationalRateSet, ++ &rCmdCreate.u2BSSBasicRateSet, &rCmdCreate.fgIsUnknownBssBasicRate); ++ } ++ ++ /* phy type */ ++#endif ++ ++ /* create a TDLS peer record */ ++ rStatus = kalIoctl(prGlueInfo, ++ TdlsexPeerAdd, ++ &rCmdCreate, sizeof(TDLS_CMD_PEER_ADD_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(TDLS, ERROR, "%s create error:%x\n", __func__, rStatus); ++ return -EINVAL; ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for deleting a station information ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ * ++ * @other ++ * must implement if you have add_station(). ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params) ++//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to do a scan ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++static PARAM_SCAN_REQUEST_EXT_T rScanRequest; ++int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++/* PARAM_SCAN_REQUEST_EXT_T rScanRequest; */ ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "mtk_cfg80211_scan\n"); ++ kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T)); ++ ++ /* check if there is any pending scan not yet finished */ ++ if (prGlueInfo->prScanRequest != NULL) { ++ DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n"); ++ return -EBUSY; ++ } ++ ++ if (request->n_ssids == 0) { ++ rScanRequest.rSsid.u4SsidLen = 0; ++ } else if (request->n_ssids == 1) { ++ COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid, ++ request->ssids[0].ssid_len); ++ } else { ++ DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", request->n_ssids); ++ return -EINVAL; ++ } ++ ++ if (request->ie_len > 0) { ++ rScanRequest.u4IELength = request->ie_len; ++ rScanRequest.pucIE = (PUINT_8) (request->ie); ++ } else { ++ rScanRequest.u4IELength = 0; ++ } ++#if 0 ++ prGlueInfo->prScanRequest = request; ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssidListScanExt, ++ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); ++ prGlueInfo->prScanRequest = NULL; ++ return -EINVAL; ++ } ++ ++ /*prGlueInfo->prScanRequest = request;*/ ++#endif ++ ++ prGlueInfo->prScanRequest = request; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssidListScanExt, ++ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ prGlueInfo->prScanRequest = NULL; ++ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static UINT_8 wepBuf[48]; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to connect to ++ * the ESS with the specified parameters ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ UINT_32 cipher; ++ PARAM_CONNECT_T rNewSsid; ++ BOOLEAN fgCarryWPSIE = FALSE; ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "[wlan] mtk_cfg80211_connect %p %zu\n", sme->ie, sme->ie_len); ++ ++ if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) ++ eOpMode = NET_TYPE_AUTO_SWITCH; ++ else ++ eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ /* after set operation mode, key table are cleared */ ++ ++ /* reset wpa info */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; ++ else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2; ++ else ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ ++ switch (sme->auth_type) { ++ case NL80211_AUTHTYPE_OPEN_SYSTEM: ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++ break; ++ case NL80211_AUTHTYPE_SHARED_KEY: ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; ++ break; ++ default: ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY; ++ break; ++ } ++ ++ if (sme->crypto.n_ciphers_pairwise) { ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = ++ sme->crypto.ciphers_pairwise[0]; ++ switch (sme->crypto.ciphers_pairwise[0]) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40; ++ break; ++ case WLAN_CIPHER_SUITE_WEP104: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104; ++ break; ++ case WLAN_CIPHER_SUITE_TKIP: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; ++ break; ++ case WLAN_CIPHER_SUITE_AES_CMAC: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]); ++ return -EINVAL; ++ } ++ } ++ ++ if (sme->crypto.cipher_group) { ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group; ++ switch (sme->crypto.cipher_group) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40; ++ break; ++ case WLAN_CIPHER_SUITE_WEP104: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104; ++ break; ++ case WLAN_CIPHER_SUITE_TKIP: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; ++ break; ++ case WLAN_CIPHER_SUITE_AES_CMAC: ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); ++ return -EINVAL; ++ } ++ } ++ ++ if (sme->crypto.n_akm_suites) { ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = ++ sme->crypto.akm_suites[0]; ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) { ++ switch (sme->crypto.akm_suites[0]) { ++ case WLAN_AKM_SUITE_8021X: ++ eAuthMode = AUTH_MODE_WPA; ++ break; ++ case WLAN_AKM_SUITE_PSK: ++ eAuthMode = AUTH_MODE_WPA_PSK; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); ++ return -EINVAL; ++ } ++ } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { ++ switch (sme->crypto.akm_suites[0]) { ++ case WLAN_AKM_SUITE_8021X: ++ eAuthMode = AUTH_MODE_WPA2; ++ break; ++ case WLAN_AKM_SUITE_PSK: ++ eAuthMode = AUTH_MODE_WPA2_PSK; ++ break; ++ default: ++ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); ++ return -EINVAL; ++ } ++ } ++ } ++ ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { ++ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? ++ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; ++ } ++ ++ prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy; ++ ++ prGlueInfo->fgWpsActive = FALSE; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ prGlueInfo->fgConnectHS20AP = FALSE; ++#endif ++ ++ if (sme->ie && sme->ie_len > 0) { ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ PUINT_8 prDesiredIE = NULL; ++ PUINT_8 pucIEStart = (PUINT_8)sme->ie; ++ ++#if CFG_SUPPORT_WAPI ++ if (wextSrchDesiredWAPIIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiAssocInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(SEC, WARN, "[wapi] set wapi assoc info error:%x\n", rStatus); ++ } ++#endif ++ ++ DBGLOG(REQ, TRACE, "[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n", ++ prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode); ++ ++#if CFG_SUPPORT_WPS2 ++ if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ prGlueInfo->fgWpsActive = TRUE; ++ fgCarryWPSIE = TRUE; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWSCAssocInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(SEC, WARN, "WSC] set WSC assoc info error:%x\n", rStatus); ++ } ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetHS20Info, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInterworkingInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRoamingConsortiumIEInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ ++ } ++ } ++#endif ++ } ++ ++ /* clear WSC Assoc IE buffer in case WPS IE is not detected */ ++ if (fgCarryWPSIE == FALSE) { ++ kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200); ++ prGlueInfo->u2WSCAssocInfoIELen = 0; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus); ++ ++ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; ++ ++ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) { ++ if (cipher & IW_AUTH_CIPHER_CCMP) { ++ eEncStatus = ENUM_ENCRYPTION3_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_TKIP) { ++ eEncStatus = ENUM_ENCRYPTION2_ENABLED; ++ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_NONE) { ++ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } else { ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } ++ } else { ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "set encryption mode error:%x\n", rStatus); ++ ++ if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { ++ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; ++ ++ prWepKey->u4Length = 12 + sme->key_len; ++ prWepKey->u4KeyLength = (UINT_32) sme->key_len; ++ prWepKey->u4KeyIndex = (UINT_32) sme->key_idx; ++ prWepKey->u4KeyIndex |= BIT(31); ++ if (prWepKey->u4KeyLength > 32) { ++ DBGLOG(REQ, ERROR, "Too long key length (%u)\n", prWepKey->u4KeyLength); ++ return -EINVAL; ++ } ++ kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddWep, ++ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ } ++ ++ if (sme->channel) ++ rNewSsid.u4CenterFreq = sme->channel->center_freq; ++ else ++ rNewSsid.u4CenterFreq = 0; ++ rNewSsid.pucBssid = (UINT_8 *)sme->bssid; ++ rNewSsid.pucSsid = (UINT_8 *)sme->ssid; ++ rNewSsid.u4SsidLen = sme->ssid_len; ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetConnect, ++ (PVOID)(&rNewSsid), sizeof(PARAM_CONNECT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "set SSID:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to disconnect from ++ * currently connected ESS ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to join an IBSS group ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params) ++{ ++ PARAM_SSID_T rNewSsid; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ ++ UINT_32 u4BufLen = 0; ++ WLAN_STATUS rStatus; ++ struct ieee80211_channel *channel = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ /* set channel */ ++ if (params->chandef.chan) ++ channel = params->chandef.chan; ++ if (channel) { ++ u4ChnlFreq = nicChannelNum2Freq(channel->hw_value); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetFrequency, ++ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ } ++ ++ /* set SSID */ ++ kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetSsid, ++ (PVOID)(&rNewSsid), sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++ ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to leave from IBSS group ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to configure ++ * WLAN power managemenet ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ PARAM_POWER_MODE ePowerMode; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (enabled) { ++ if (timeout == -1) ++ ePowerMode = Param_PowerModeFast_PSP; ++ else ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else { ++ ePowerMode = Param_PowerModeCAM; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSet802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to cache ++ * a PMKID for a BSSID ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_PARAM_PMKID_T prPmkid; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); ++ return -ENOMEM; ++ } ++ ++ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); ++ prPmkid->u4BSSIDInfoCount = 1; ++ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6); ++ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "add pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to remove ++ * a cached PMKID for a BSSID ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) ++{ ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to flush ++ * all cached PMKID ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_PARAM_PMKID_T prPmkid; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_FLUSH\n"); ++ return -ENOMEM; ++ } ++ ++ prPmkid->u4Length = 8; ++ prPmkid->u4BSSIDInfoCount = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, WARN, "flush pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); ++ ++ return 0; ++} ++ ++void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, ++ IN struct wireless_dev *wdev, ++ IN u16 frame_type, IN bool reg) ++{ ++#if 0 ++ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; ++#endif ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ do { ++ ++ DBGLOG(REQ, LOUD, "mtk_cfg80211_mgmt_frame_register\n"); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ switch (frame_type) { ++ case MAC_FRAME_PROBE_REQ: ++ if (reg) { ++ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(REQ, LOUD, "Open packet filer probe request\n"); ++ } else { ++ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(REQ, LOUD, "Close packet filer probe request\n"); ++ } ++ break; ++ case MAC_FRAME_ACTION: ++ if (reg) { ++ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(REQ, LOUD, "Open packet filer action frame.\n"); ++ } else { ++ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(REQ, LOUD, "Close packet filer action frame.\n"); ++ } ++ break; ++ default: ++ DBGLOG(REQ, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type); ++ break; ++ } ++ ++ if (prGlueInfo->prAdapter != NULL) { ++ /* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */ ++ set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ if (in_interrupt()) ++ DBGLOG(REQ, TRACE, "It is in interrupt level\n"); ++ } ++#if 0 ++ ++ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ sizeof ++ (MSG_P2P_MGMT_FRAME_REGISTER_T)); ++ ++ if (prMgmtFrameRegister == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; ++ ++ prMgmtFrameRegister->u2FrameType = frame_type; ++ prMgmtFrameRegister->fgIsRegister = reg; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); ++ ++#endif ++ ++ } while (FALSE); ++ ++} /* mtk_cfg80211_mgmt_frame_register */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to stay on a ++ * specified channel ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, ++ unsigned int duration, u64 *cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++#if 1 ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ *cookie = prGlueInfo->u8Cookie++; ++ ++ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T)); ++ ++ if (prMsgChnlReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ kalMemZero(prMsgChnlReq, sizeof(MSG_REMAIN_ON_CHANNEL_T)); ++ ++ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL; ++ prMsgChnlReq->u8Cookie = *cookie; ++ prMsgChnlReq->u4DurationMs = duration; ++ ++ prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000); ++ ++ switch (chan->band) { ++ case NL80211_BAND_2GHZ: ++ prMsgChnlReq->eBand = BAND_2G4; ++ break; ++ case NL80211_BAND_5GHZ: ++ prMsgChnlReq->eBand = BAND_5G; ++ break; ++ default: ++ prMsgChnlReq->eBand = BAND_2G4; ++ break; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to cancel staying ++ * on a specified channel ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ u64 cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL)) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++#if 1 ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ prMsgChnlAbort = ++ cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T)); ++ ++ if (prMsgChnlAbort == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL; ++ prMsgChnlAbort->u8Cookie = cookie; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to send a management frame ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL; ++ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; ++ PUINT_8 pucFrameBuf = (PUINT_8) NULL; ++ ++ do { ++#if 1 ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ *cookie = prGlueInfo->u8Cookie++; ++ ++ /* Channel & Channel Type & Wait time are ignored. */ ++ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T)); ++ ++ if (prMsgTxReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgTxReq->fgNoneCckRate = FALSE; ++ prMsgTxReq->fgIsWaitRsp = TRUE; ++ ++ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); ++ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; ++ if (prMsgTxReq->prMgmtMsduInfo == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgTxReq->u8Cookie = *cookie; ++ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX; ++ ++ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); ++ ++ kalMemCopy(pucFrameBuf, params->buf, params->len); ++ ++ prMgmtFrame->u2FrameLength = params->len; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { ++ if (prMsgTxReq->prMgmtMsduInfo != NULL) ++ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); ++ ++ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); ++ } ++ ++ return i4Rslt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for requesting to cancel the wait time ++ * from transmitting a management frame on another channel ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ u64 cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ /* not implemented */ ++ ++ return -EINVAL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for handling sched_scan start/stop request ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++ ++int ++mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, ++ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 i, u4BufLen; ++ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ ASSERT(prGlueInfo); ++ ++ /* check if there is any pending scan/sched_scan not yet finished */ ++ if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) { ++ DBGLOG(SCN, ERROR, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n"); ++ return -EBUSY; ++ } else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) { ++ DBGLOG(SCN, ERROR, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n"); ++ /* invalid scheduled scan request */ ++ return -EINVAL; ++ } else if (/* !request->n_ssids || */!request->n_match_sets) { ++ /* invalid scheduled scan request */ ++ return -EINVAL; ++ } ++ ++ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE); ++ if (prSchedScanRequest == NULL) { ++ DBGLOG(SCN, ERROR, "(prSchedScanRequest == NULL) kalMemAlloc fail\n"); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST)); ++ ++ prSchedScanRequest->u4SsidNum = request->n_match_sets; ++ for (i = 0; i < request->n_match_sets; i++) { ++ if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) { ++ prSchedScanRequest->arSsid[i].u4SsidLen = 0; ++ } else { ++ COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid, ++ prSchedScanRequest->arSsid[i].u4SsidLen, ++ request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len); ++ } ++ } ++ ++ prSchedScanRequest->u4IELength = request->ie_len; ++ if (request->ie_len > 0) ++ prSchedScanRequest->pucIE = (PUINT_8) (request->ie); ++ ++ prSchedScanRequest->u2ScanInterval = (UINT_16) (request->scan_plans[0].interval); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetStartSchedScan, ++ prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST)); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(SCN, ERROR, "scheduled scan error:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ prGlueInfo->prSchedScanRequest = request; ++ ++ return 0; ++} ++ ++int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev, u64 reqid) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ /* check if there is any pending scan/sched_scan not yet finished */ ++ if (prGlueInfo->prSchedScanRequest == NULL) { ++ DBGLOG(SCN, ERROR, "prGlueInfo->prSchedScanRequest == NULL\n"); ++ return -EBUSY; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(SCN, ERROR, "scheduled scan error, rStatus: %d\n", rStatus); ++ return -EINVAL; ++ } ++ ++ /* 1. reset first for newly incoming request */ ++ /* GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ ++ if (prGlueInfo->prSchedScanRequest != NULL) ++ prGlueInfo->prSchedScanRequest = NULL; ++ /* GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ ++ ++ DBGLOG(SCN, TRACE, "start work queue to send event\n"); ++ schedule_delayed_work(&sched_workq, 0); ++ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for handling association request ++ * ++ * @param ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_MAC_ADDRESS arBssid; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ PUINT_8 prDesiredIE = NULL; ++#endif ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(arBssid, MAC_ADDR_LEN); ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); ++ ++ /* 1. check BSSID */ ++ if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) { ++ /* wrong MAC address */ ++ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", ++ req->bss->bssid, arBssid); ++ return -ENOENT; ++ } ++ ++ if (req->ie && req->ie_len > 0) { ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetHS20Info, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ ++ if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInterworkingInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ ++ } ++ } ++ ++ if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRoamingConsortiumIEInfo, ++ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ ++ } ++ } ++#endif ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssid, ++ (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#if CONFIG_NL80211_TESTMODE ++/* ++#define NLA_PUT(skb, attrtype, attrlen, data) \ ++do { \ ++ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ ++ goto nla_put_failure; \ ++} while (0) ++ ++#define NLA_PUT_TYPE(skb, type, attrtype, value) \ ++do { \ ++ type __tmp = value; \ ++ NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ ++} while (0) ++ ++#define NLA_PUT_U8(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u8, attrtype, value) ++ ++#define NLA_PUT_U16(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u16, attrtype, value) ++ ++#define NLA_PUT_U32(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u32, attrtype, value) ++ ++#define NLA_PUT_U64(skb, attrtype, value) \ ++ NLA_PUT_TYPE(skb, u64, attrtype, value) ++*/ ++#if CFG_SUPPORT_WAPI ++int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL; ++ struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4BufLen = 0; ++ ++ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; ++ ++ memset(keyStructBuf, 0, sizeof(keyStructBuf)); ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data; ++ } else { ++ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_key_ext, data is NULL\n"); ++ return -EINVAL; ++ } ++ ++ if (prParams) ++ prIWEncExt = (struct iw_encode_exts *)&prParams->ext; ++ ++ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { ++ /* KeyID */ ++ prWpiKey->ucKeyID = prParams->key_index; ++ prWpiKey->ucKeyID--; ++ if (prWpiKey->ucKeyID > 1) { ++ /* key id is out of range */ ++ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ ++ return -EINVAL; ++ } ++ ++ if (prIWEncExt->key_len != 32) { ++ /* key length not valid */ ++ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ ++ return -EINVAL; ++ } ++ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ ++ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX; ++ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX_TX; ++ } ++/* #if CFG_SUPPORT_WAPI */ ++ /* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */ ++/* #endif */ ++ /* PN */ ++ memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE); ++ memcpy(prWpiKey->aucPN + IW_ENCODE_SEQ_MAX_SIZE, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); ++ ++ ++ /* BSSID */ ++ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6); ++ ++ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); ++ prWpiKey->u4LenWPIEK = 16; ++ ++ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); ++ prWpiKey->u4LenWPICK = 16; ++ ++ rstatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiKey, ++ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rstatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ ++ fgIsValid = -EFAULT; ++ } ++ ++ } ++ return fgIsValid; ++} ++#endif ++ ++int ++mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Status = -EINVAL; ++ UINT_32 u4BufLen; ++ UINT_32 u4LinkScore; ++ UINT_32 u4TotalError; ++ UINT_32 u4TxExceedThresholdCount; ++ UINT_32 u4TxTotalCount; ++ ++ P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; ++ PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics; ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data; ++ } else { ++ DBGLOG(QM, ERROR, "mtk_cfg80211_testmode_get_sta_statistics, data is NULL\n"); ++ return -EINVAL; ++ } ++/* ++ if (!prParams->aucMacAddr) { ++ DBGLOG(QM, INFO, "%s MAC Address is NULL\n", __func__); ++ return -EINVAL; ++ } ++*/ ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); ++ ++ if (!skb) { ++ DBGLOG(QM, ERROR, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ DBGLOG(QM, TRACE, "Get [ %pM ] STA statistics\n", prParams->aucMacAddr); ++ ++ kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics)); ++ COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStaStatistics, ++ &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ /* Calcute Link Score */ ++ u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount; ++ u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount; ++ u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount; ++ ++ /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */ ++ /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */ ++ if (u4TxTotalCount) { ++ if (u4TxExceedThresholdCount <= u4TxTotalCount) ++ u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount)); ++ else ++ u4LinkScore = 0; ++ } else { ++ u4LinkScore = 90; ++ } ++ ++ u4LinkScore += 10; ++ ++ if (u4LinkScore == 10) { ++ ++ if (u4TotalError <= u4TxTotalCount) ++ u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount)); ++ else ++ u4LinkScore = 0; ++ ++ } ++ ++ if (u4LinkScore > 100) ++ u4LinkScore = 100; ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);*/ ++ { ++ unsigned char __tmp = NL80211_DRIVER_TESTMODE_VERSION; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); */ ++ { ++ unsigned int __tmp = u4LinkScore; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, &prParams->aucMacAddr) < 0)) ++ goto nla_put_failure; ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4Flag; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ /* FW part STA link status */ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);*/ ++ { ++ unsigned char __tmp = rQueryStaStatistics.ucPer; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);*/ ++ { ++ unsigned char __tmp = rQueryStaStatistics.ucRcpi; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4PhyMode; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);*/ ++ { ++ unsigned short __tmp = rQueryStaStatistics.u2LinkSpeed; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, ++ sizeof(unsigned short), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxFailCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxAverageAirTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* Driver part link status */ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxTotalCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, ++ rQueryStaStatistics.u4TxExceedThresholdCount);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxExceedThresholdCount; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, ++ rQueryStaStatistics.u4TxAverageProcessTime);*/ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxAverageProcessTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxMaxTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxAverageHifTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4TxMaxHifTime; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, rQueryStaStatistics.u4EnqueueCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4EnqueueCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, rQueryStaStatistics.u4DequeueCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4DequeueCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, rQueryStaStatistics.u4EnqueueStaCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4EnqueueStaCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, rQueryStaStatistics.u4DequeueStaCounter); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.u4DequeueStaCounter; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, rQueryStaStatistics.IsrCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, rQueryStaStatistics.IsrPassCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrPassCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, rQueryStaStatistics.TaskIsrCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.TaskIsrCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, rQueryStaStatistics.IsrAbnormalCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrAbnormalCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, rQueryStaStatistics.IsrSoftWareCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrSoftWareCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, rQueryStaStatistics.IsrTxCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrTxCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* ++ *NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, rQueryStaStatistics.IsrRxCnt); ++ */ ++ { ++ unsigned int __tmp = rQueryStaStatistics.IsrRxCnt; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /* Network counter */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), &rQueryStaStatistics.au4TcResourceEmptyCount) < 0)) ++ goto nla_put_failure; ++ /* ++ NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, ++ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), rQueryStaStatistics.au4DequeueNoTcResource); ++ */ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, ++ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), &rQueryStaStatistics.au4DequeueNoTcResource) < 0)) ++ goto nla_put_failure; ++ /* ++ NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceBackCount), rQueryStaStatistics.au4TcResourceBackCount); ++ */ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceBackCount), &rQueryStaStatistics.au4TcResourceBackCount) < 0)) ++ goto nla_put_failure; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceUsedCount), &rQueryStaStatistics.au4TcResourceUsedCount) < 0)) ++ goto nla_put_failure; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcResourceWantedCount), ++ &rQueryStaStatistics.au4TcResourceWantedCount) < 0)) ++ goto nla_put_failure; ++ ++ /* Sta queue length */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcQueLen), &rQueryStaStatistics.au4TcQueLen) < 0)) ++ goto nla_put_failure; ++ ++ ++ /* Global QM counter */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcAverageQueLen), &rQueryStaStatistics.au4TcAverageQueLen) < 0)) ++ goto nla_put_failure; ++ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, ++ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), &rQueryStaStatistics.au4TcCurrentQueLen) < 0)) ++ goto nla_put_failure; ++ ++ ++ /* Reserved field */ ++ /*NLA_PUT(skb, ++ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, ++ sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved);*/ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, ++ sizeof(rQueryStaStatistics.au4Reserved), &rQueryStaStatistics.au4Reserved) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ skb = NULL; ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int ++mtk_cfg80211_testmode_get_link_detection(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Status = -EINVAL; ++ UINT_32 u4BufLen; ++ ++ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); ++ ++ if (!skb) { ++ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&rStatistics, sizeof(rStatistics)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rFailedCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rFailedCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rMultipleRetryCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rACKFailureCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);*/ ++ { ++ u64 __tmp = rStatistics.rFCSErrorCount.QuadPart; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, ++ sizeof(u64), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ skb = NULL; ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ if (data && len) ++ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; ++ ++ if (prParams) { ++ if (prParams->set == 1) { ++ rstatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, ++ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ } ++ ++ if (WLAN_STATUS_SUCCESS != rstatus) ++ fgIsValid = -EFAULT; ++ ++ return fgIsValid; ++} ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct wpa_driver_hs20_data_s *prParams = NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); ++ ++ if (data && len) { ++ prParams = (struct wpa_driver_hs20_data_s *)data; ++ ++ DBGLOG(REQ, TRACE, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType); ++ } ++ ++ if (prParams) { ++ int i; ++ ++ switch (prParams->CmdType) { ++ case HS20_CMD_ID_SET_BSSID_POOL: ++ DBGLOG(REQ, TRACE, "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n", ++ prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable, ++ prParams->hs20_set_bssid_pool.ucNumBssidPool); ++ for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) { ++ DBGLOG(REQ, TRACE, "[%d][ %pM ]\n", i, ++ (prParams->hs20_set_bssid_pool.arBssidPool[i])); ++ } ++ rstatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool, ++ &prParams->hs20_set_bssid_pool, ++ sizeof(struct param_hs20_set_bssid_pool), ++ FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ break; ++ default: ++ DBGLOG(REQ, TRACE, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType); ++ rstatus = WLAN_STATUS_FAILURE; ++ ++ } ++ ++ } ++ ++ if (WLAN_STATUS_SUCCESS != rstatus) ++ fgIsValid = -EFAULT; ++ ++ return fgIsValid; ++} ++ ++#endif ++int ++mtk_cfg80211_testmode_set_poorlink_param(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++ int fgIsValid = 0; ++ P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_POORLINK_PARAMS) data; ++ } else { ++ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_poorlink_param, data is NULL\n"); ++ return -EINVAL; ++ } ++ if (prParams->ucLinkSpeed) ++ prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed * 10; ++ if (prParams->cRssi) ++ prGlueInfo->i4RssiThreshold = prParams->cRssi; ++ if (!prGlueInfo->fgPoorlinkValid) ++ prGlueInfo->fgPoorlinkValid = 1; ++#if 0 ++ DBGLOG(REQ, TRACE, "poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n", ++ prGlueInfo->fgPoorlinkValid, prGlueInfo->i4RssiThreshold, prGlueInfo->u4LinkspeedThreshold); ++#endif ++ ++ return fgIsValid; ++ ++} ++ ++int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL; ++ INT_32 i4Status = -EINVAL; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ BOOLEAN fgIsValid = 0; ++#endif ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data; ++ } else { ++ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n"); ++ return i4Status; ++ } ++ ++ /* Clear the version byte */ ++ prParams->index = prParams->index & ~BITS(24, 31); ++ ++ if (prParams) { ++ switch (prParams->index) { ++ case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */ ++ i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len); ++ break; ++ case TESTMODE_CMD_ID_WAPI: /* WAPI */ ++#if CFG_SUPPORT_WAPI ++ i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len); ++#endif ++ break; ++ case TESTMODE_CMD_ID_SUSPEND: ++ { ++ P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS) data; ++ ++ if (prParams->suspend == 1) { ++ wlanHandleSystemSuspend(); ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pHandleSystemSuspend(); ++ i4Status = 0; ++ } else if (prParams->suspend == 0) { ++ wlanHandleSystemResume(); ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pHandleSystemResume(); ++ i4Status = 0; ++ } ++ break; ++ } ++ case TESTMODE_CMD_ID_STATISTICS: ++ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); ++ break; ++ case TESTMODE_CMD_ID_LINK_DETECT: ++ i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo); ++ break; ++ case TESTMODE_CMD_ID_POORLINK: ++ i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo); ++ break; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ case TESTMODE_CMD_ID_HS20: ++ if (mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len)) ++ fgIsValid = TRUE; ++ break; ++#endif ++ default: ++ i4Status = -EINVAL; ++ break; ++ } ++ } ++ ++ return i4Status; ++} ++ ++int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++#define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0 ++#define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1 ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0; ++ ++/* P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; */ ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32)); ++ READY_TO_BEAM = ++ (UINT_32) (prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo. ++ fgIsGOInitialDone) & ++ (!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); ++ DBGLOG(QM, TRACE, ++ "NFC:GOInitialDone[%d] and P2PScanning[%d]\n", ++ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone, ++ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); ++ ++ if (!skb) { ++ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);*/ ++ { ++ unsigned int __tmp = READY_TO_BEAM; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ skb = NULL; ++ ++nla_put_failure: ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++int ++mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) ++{ ++#define MAXMUN_2_4G_CHA_NUM 14 ++#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 ++ ++ BOOLEAN fgIsReady = FALSE, fgIsFistRecord = TRUE; ++ BOOLEAN fgIsPureAP, fgIsLteSafeChn = FALSE; ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucDefaultIdx = 0, ucArrayIdx = 0; ++ UINT_16 u2APNumScore = 0, u2UpThreshold = 0, u2LowThreshold = 0, ucInnerIdx = 0; ++ INT_32 i4Status = -EINVAL; ++ UINT_32 u4BufLen, u4LteSafeChnBitMask_2_4G = 0; ++ UINT32 AcsChnReport[4]; ++ /*RF_CHANNEL_INFO_T aucChannelList[MAXMUN_2_4G_CHA_NUM];*/ ++ ++ struct sk_buff *skb; ++ ++ /*PARAM_GET_CHN_LOAD rQueryLTEChn;*/ ++ P_PARAM_GET_CHN_LOAD prQueryLTEChn; ++ PARAM_PREFER_CHN_INFO rPreferChannels[2], ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM]; ++ P_PARAM_CHN_LOAD_INFO prChnLoad; ++ P_PARAM_GET_CHN_LOAD prGetChnLoad; ++ ++ P_DOMAIN_INFO_ENTRY prDomainInfo; ++ ++/* ++ P_PARAM_GET_CHN_LOAD prParams = NULL; ++*/ ++ ASSERT(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemZero(rPreferChannels, sizeof(rPreferChannels)); ++ fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; ++#if 0 ++ if (data && len) ++ prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS) data; ++#endif ++ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(AcsChnReport) + sizeof(UINT8) + 1); ++ if (!skb) { ++ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); ++ return -ENOMEM; ++ } ++ ++ DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n"); ++ prQueryLTEChn = kalMemAlloc(sizeof(PARAM_GET_CHN_LOAD), VIR_MEM_TYPE); ++ if (prQueryLTEChn == NULL) { ++ DBGLOG(QM, TRACE, "alloc QueryLTEChn fail\n"); ++ kalMemFree(skb, VIR_MEM_TYPE, sizeof(struct sk_buff)); ++ return -ENOMEM; ++ } ++ kalMemZero(prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD)); ++ ++ /* Query LTE Safe Channels */ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] ++ = 0xFFFFFFFF; ++ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] ++ = 0xFFFFFFFF; ++ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] ++ = 0xFFFFFFFF; ++ ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = ++ 0xFFFFFFFF; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryACSChannelList, prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD), ++ TRUE, FALSE, TRUE, TRUE, &u4BufLen); ++#if 0 ++ if (fgIsPureAP) { ++ ++ AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20; /* Channel 6 */ ++ } else ++#endif ++ { ++ fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit; ++ rPreferChannels[0].u2APNum = 0xFFFF; ++ rPreferChannels[1].u2APNum = 0xFFFF; ++ ++ /* 4 In LTE Mode, Hotspot pick up channels from ch4. */ ++ ucDefaultIdx = 0; ++ /* ++ if (fgIsPureAP) { ++ ucDefaultIdx=3; //SKIP LTE Channels 1~3 ++ } ++ */ ++ ++ /* 4 Get the Maximun channel List in 2.4G Bands */ ++ ++ prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter); ++ ASSERT(prDomainInfo); ++ ++ /* 4 ToDo: Enable Step 2 only if we could get Country Code from framework */ ++ /* 4 2. Get current domain channel list */ ++ ++#if 0 ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, ++ BAND_2G4, MAXMUN_2_4G_CHA_NUM, &ucMax_24G_Chn_List, aucChannelList); ++#endif ++ ++ prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo); ++ for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) { ++ DBGLOG(P2P, INFO, ++ "[Auto Channel] ch[%d]=%d\n", ucIdx, ++ prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx].u2APNum); ++ } ++ ++ /*Calculate Each Channel Direty Score */ ++ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { ++ ++#if 1 ++ u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND; ++ u2UpThreshold = u2LowThreshold = 3; ++ ++ if (ucIdx < 3) { ++ u2UpThreshold = ucIdx; ++ u2LowThreshold = 3; ++ } else if (ucIdx >= (ucMax_24G_Chn_List - 3)) { ++ u2UpThreshold = 3; ++ u2LowThreshold = ucMax_24G_Chn_List - (ucIdx + 1); ++ ++ } ++ ++ /*Calculate Lower Channel Dirty Score */ ++ for (ucInnerIdx = 0; ucInnerIdx < u2LowThreshold; ucInnerIdx++) { ++ ucArrayIdx = ucIdx + ucInnerIdx + 1; ++ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { ++ u2APNumScore += ++ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * ++ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); ++ } ++ } ++ ++ /*Calculate Upper Channel Dirty Score */ ++ for (ucInnerIdx = 0; ucInnerIdx < u2UpThreshold; ucInnerIdx++) { ++ ucArrayIdx = ucIdx - ucInnerIdx - 1; ++ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { ++ u2APNumScore += ++ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * ++ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); ++ } ++ } ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ ++ DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx, u2APNumScore); ++#else ++ if (ucIdx == 0) { ++ /* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = ++ (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ++ prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */ ++ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) ++ ((3 * ++ (prGetChnLoad-> ++ rEachChnLoad[ucIdx + ++ 1]. ++ u2APNum + ++ prGetChnLoad-> ++ rEachChnLoad[ucIdx + ++ 2]. ++ u2APNum)) / 4))); ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum)); ++ } ++ if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) { ++ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) ++ ((3 * ++ (prGetChnLoad-> ++ rEachChnLoad[ucIdx + ++ 1]. ++ u2APNum + ++ prGetChnLoad-> ++ rEachChnLoad[ucIdx - ++ 1]. ++ u2APNum)) / 4))); ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx, ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); ++ } ++ ++ if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) { ++ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ++ ((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4))); ++ ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, ++ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, ++ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); ++ } ++#endif ++ ++ } ++ ++ u4LteSafeChnBitMask_2_4G = ++ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; ++ ++ /*Find out the best channel */ ++ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { ++ /* 4 Skip LTE Unsafe Channel */ ++ fgIsLteSafeChn = ((u4LteSafeChnBitMask_2_4G & BIT(ucIdx + 1)) >> ucIdx); ++ if (!fgIsLteSafeChn) ++ continue; ++ ++ prChnLoad = ++ (P_PARAM_CHN_LOAD_INFO) &(prGlueInfo->prAdapter->rWifiVar. ++ rChnLoadInfo.rEachChnLoad[ucIdx]); ++ if (rPreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) { ++ rPreferChannels[1].ucChannel = rPreferChannels[0].ucChannel; ++ rPreferChannels[1].u2APNum = rPreferChannels[0].u2APNum; ++ ++ rPreferChannels[0].ucChannel = ucIdx; ++ rPreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; ++ } else { ++ if (rPreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum ++ || fgIsFistRecord == 1) { ++ fgIsFistRecord = FALSE; ++ rPreferChannels[1].ucChannel = ucIdx; ++ rPreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; ++ } ++ } ++ } ++ /* AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] = ++ BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1)); */ ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0; ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |= BIT(rPreferChannels[0].ucChannel); ++ } ++ ++ /* ToDo: Support 5G Channel Selection */ ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344; ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788; ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC; ++ ++ /*NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);*/ ++ { ++ unsigned char __tmp = 0; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, sizeof(unsigned char), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ ++ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]);*/ ++ { ++ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]; ++ ++ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ DBGLOG(P2P, INFO, ++ "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n", AcsChnReport[0], AcsChnReport[1], AcsChnReport[2], ++ AcsChnReport[3]); ++ ++ i4Status = cfg80211_testmode_reply(skb); ++ /*need confirm cfg80211_testmode_reply will free skb*/ ++ skb = NULL; ++ /*kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));*/ ++ ++nla_put_failure: ++ kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD)); ++ if (skb != NULL) ++ kfree_skb(skb); ++ return i4Status; ++ ++} ++#endif ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief cfg80211 suspend callback, will be invoked in wiphy_suspend ++ * ++ * @param wiphy: pointer to wiphy ++ * wow: pointer to cfg80211_wowlan ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (kalHaltTryLock()) ++ return 0; ++ ++ if (kalIsHalted() || !wiphy) ++ goto end; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prGlueInfo->prAdapter->ulSuspendFlag); ++ set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prGlueInfo->prAdapter->ulSuspendFlag); ++end: ++ kalHaltUnlock(); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief cfg80211 resume callback, will be invoked in wiphy_resume. ++ * ++ * @param wiphy: pointer to wiphy ++ * ++ * @retval 0: successful ++ * others: failure ++ */ ++/*----------------------------------------------------------------------------*/ ++int mtk_cfg80211_resume(struct wiphy *wiphy) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_BSS_DESC_T *pprBssDesc = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ UINT_8 i = 0; ++ ++ if (kalHaltTryLock()) ++ return 0; ++ ++ if (kalIsHalted() || !wiphy) ++ goto end; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ prAdapter = prGlueInfo->prAdapter; ++ clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag); ++ pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rNloParam.aprPendingBssDescToInd[0]; ++ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { ++ if (pprBssDesc[i] == NULL) ++ break; ++ if (pprBssDesc[i]->u2RawLength == 0) ++ continue; ++ kalIndicateBssInfo(prGlueInfo, ++ (PUINT_8) pprBssDesc[i]->aucRawBuf, ++ pprBssDesc[i]->u2RawLength, ++ pprBssDesc[i]->ucChannelNum, ++ RCPI_TO_dBm(pprBssDesc[i]->ucRCPI)); ++ } ++ DBGLOG(SCN, INFO, "pending %d sched scan results\n", i); ++ if (i > 0) ++ kalMemZero(&pprBssDesc[0], i * sizeof(P_BSS_DESC_T)); ++end: ++ kalHaltUnlock(); ++ return 0; ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c +new file mode 100644 +index 000000000000..95ca7546b1bb +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c +@@ -0,0 +1,3502 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7 ++*/ ++ ++/*! \file gl_init.c ++ \brief Main routines of Linux driver ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_init.c ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 05 25 2012 yuche.tsai ++ * NULL ++ * Fix reset KE issue. ++ * ++ * 05 11 2012 cp.wu ++ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience ++ * show MAC address & source while initiliazation ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Sync CFG80211 modification from branch 2,2. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Enable CFG80211 Support. ++ * ++ * 12 22 2011 george.huang ++ * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency ++ * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before ++ * TX thread handling ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 14 2011 yuche.tsai ++ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. ++ * Fix large network type index assert in FW issue. ++ * ++ * 11 14 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 06 2011 eddie.chen ++ * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation ++ * Add rlmDomainGetChnlList symbol. ++ * ++ * 09 22 2011 cm.chang ++ * NULL ++ * Safer writng stype to avoid unitialized regitry structure ++ * ++ * 09 21 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Avoid possible structure alignment problem ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 09 08 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM ++ * ++ * 08 31 2011 cm.chang ++ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code ++ * . ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * expose scnQuerySparseChannel() for P2P-FSM. ++ * ++ * 08 11 2011 cp.wu ++ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time ++ * sparse channel detection: ++ * driver: collect sparse channel information with scan-done event ++ * ++ * 08 02 2011 yuche.tsai ++ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting ++ * device issue. ++ * Fix GO send deauth frame issue. ++ * ++ * 07 07 2011 wh.su ++ * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL ++ * Add the dumpMemory8 symbol export for debug mode. ++ * ++ * 07 06 2011 terry.wu ++ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment ++ * Improve BoW connection establishment speed. ++ * ++ * 07 05 2011 yuche.tsai ++ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue ++ * Export one symbol for enhancement. ++ * ++ * 06 13 2011 eddie.chen ++ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni ++ * Add tx rx statistics and netif_rx_ni. ++ * ++ * 05 27 2011 cp.wu ++ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM ++ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain ++ * pass PHY_PARAM in NVRAM from driver to firmware. ++ * ++ * 05 09 2011 jeffrey.chang ++ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change ++ * support ARP filter through kernel notifier ++ * ++ * 05 03 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. ++ * ++ * 04 27 2011 george.huang ++ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter ++ * Support P2P ARP filter setting on early suspend/ late resume ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Modify some driver connection flow or behavior to pass Sigma test more easier.. ++ * ++ * 04 12 2011 cm.chang ++ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency ++ * . ++ * ++ * 04 11 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * export wlan functions to p2p ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 04 08 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair. ++ * ++ * 04 08 2011 eddie.chen ++ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma ++ * Fix for sigma ++ * ++ * 04 06 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port ++ * 2. update perm_addr as well for MAC address ++ * 3. not calling check_mem_region() anymore for eHPI ++ * 4. correct MSC_CS macro for 0-based notation ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * fix typo. ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism ++ * ++ * 03 23 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * apply multi-queue operation only for linux kernel > 2.6.26 ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability for compatible with linux 2.6.12. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 18 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * remove early suspend functions ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * reverse order to prevent probing racing. ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 15 2011 jeffrey.chang ++ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM ++ * refine the queue_select function ++ * ++ * 03 10 2011 cp.wu ++ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 ++ * deprecate configuration used by MT6620 E2 ++ * ++ * 03 10 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Remove unnecessary assert and message. ++ * ++ * 03 08 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Export nicQmUpdateWmmParms. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 02 24 2011 george.huang ++ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames ++ * Support ARP filter during suspended ++ * ++ * 02 21 2011 cp.wu ++ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain ++ * simplify logic for checking NVRAM existence only once. ++ * ++ * 02 17 2011 terry.wu ++ * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove ++ * Fix deference a null pointer problem in wlanRemove. ++ * ++ * 02 16 2011 jeffrey.chang ++ * NULL ++ * fix compilig error ++ * ++ * 02 16 2011 jeffrey.chang ++ * NULL ++ * Add query ipv4 and ipv6 address during early suspend and late resume ++ * ++ * 02 15 2011 jeffrey.chang ++ * NULL ++ * to support early suspend in android ++ * ++ * 02 11 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add one more export symbol. ++ * ++ * 02 10 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add RX deauthentication & disassociation process under Hot-Spot mode. ++ * ++ * 02 09 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * Halt p2p module init and exit until TxThread finished p2p register and unregister. ++ * ++ * 02 08 2011 george.huang ++ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler ++ * Support querying power mode OID. ++ * ++ * 02 08 2011 yuche.tsai ++ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue ++ * Export Deactivation Network. ++ * ++ * 02 01 2011 jeffrey.chang ++ * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded ++ * Unregister the KAL timer during driver unloading ++ * ++ * 01 26 2011 cm.chang ++ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument ++ * Allocate system RAM if fixed message or mgmt buffer is not available ++ * ++ * 01 19 2011 cp.wu ++ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 ++ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues ++ * due to multiple access ++ * use mutex to protect kalIoctl() for thread safe. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 15 2010 cp.wu ++ * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver ++ * remove set MAC address. MAC address is always loaded from NVRAM instead. ++ * ++ * 12 10 2010 kevin.huang ++ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check ++ * Add Linux Proc Support ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add GPIO debug function ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 21 2010 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * . ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK ++ * HIF by default ++ * Refine linux kernel module to the license of MTK and enable MTK HIF ++ * ++ * 10 18 2010 jeffrey.chang ++ * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android ++ * . ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 27 2010 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings ++ * Update BCM/BoW design and settings. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item ++ * use firmware reported mac address right after wlanAdapterStart() as permanent address ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 16 2010 yarco.yang ++ * NULL ++ * Support Linux x86 ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 29 2010 jeffrey.chang ++ * NULL ++ * fix memory leak for module unloading ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) remove unused spinlocks ++ * 2) enable encyption ioctls ++ * 3) fix scan ioctl which may cause supplicant to hang ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * bug fix: allocate regInfo when disabling firmware download ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * use glue layer api to decrease or increase counter atomically ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * add new spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * modify cmd/data path for new design ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) Modify set mac address code ++ * 2) remove power management macro ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * prevent supplicant accessing driver during resume ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) fix firmware download bug ++ * 2) remove query statistics for acelerating firmware download ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Query statistics from firmware ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * modify tcp/ip checksum offload flags ++ * ++ * 04 16 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix tcp/ip checksum offload bug ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler ++ * * * * * * * * * * * * * * * * * capability ++ * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix spinlock usage ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Set MAC address from firmware ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)improve none-glue code portability ++ * * (2) disable set Multicast address during atomic context ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding debug module ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix f/w download start and load address by using config.h ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download support ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090 ++** Fix compile error for Linux EHPI driver ++** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input ++** parameters and pointers. ++** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088 ++** remove non-used code ++** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088 ++** adding the module parameter for wapi ++** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088 ++** adding the code to check the wapi 1x frame ++** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461 ++** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY ++** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088 ++** set the tid and 1x value at same packet reserved field ++** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104 ++** Fix wrong variable name "prDev" in wlanStop() ++** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461 ++** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY ++** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461 ++** Update driver for Code review ++** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461 ++** Update Driver for Code Review ++** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461 ++** Update driver for code review ++** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461 ++** Add support for linux statistics ++** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461 ++** Fix ASSERT if removing module in BG_SSID_SCAN state ++** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461 ++** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS ++** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461 ++** Not use wlanoidSetCurrentAddrForLinux() ++** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461 ++** Remove WMM Assoc Flag ++** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084 ++** modify wlanISR interface ++** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461 ++** Fix Unset Broadcast filter when setMulticast ++** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461 ++** Move Query Media Status to GLUE ++** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461 ++** Revise set multicast function by using windows oid style for LP own back ++** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461 ++** Fix multicast setting in Linux and add comment ++** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461 ++** Fix set mac address func in Linux ++** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461 ++** Add set MAC Address ++** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461 ++** For Linux, set net_device has feature with checksum offload by default ++** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461 ++** Fix typo ++** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088 ++** add 1x decide code for sw port control ++** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461 ++** Rearrange the set off place of GLUE spin lock in HardStartXmit ++** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461 ++** Add debug option - Packet Order for Linux and add debug level - Event ++** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461 ++** Fix SPIN_LOCK protection ++** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425 ++** 1. Set Rx multicast packets mode before setting the address list ++** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461 ++** Add OS_TIMESTAMP to packet ++** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088 ++** fixed the unload module issue ++** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461 ++** Fix compile warnning ++** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425 ++** 1. Refine for multicast list ++** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461 ++** Add VOIP SCAN Support & Refine Roaming ++** Revision 1.4 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:50 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "gl_cfg80211.h" ++#include "precomp.h" ++#if CFG_SUPPORT_AGPS_ASSIST ++#include "gl_kal.h" ++#endif ++#if defined(CONFIG_MTK_TC1_FEATURE) ++#include ++#endif ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* #define MAX_IOREQ_NUM 10 */ ++ ++BOOLEAN fgIsUnderSuspend = false; ++ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++spinlock_t g_p2p_lock; ++int g_u4P2PEnding = 0; ++int g_u4P2POnOffing = 0; ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Tasklet mechanism is like buttom-half in Linux. We just want to ++ * send a signal to OS for interrupt defer processing. All resources ++ * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty. ++ */ ++typedef struct _WLANDEV_INFO_T { ++ struct net_device *prDev; ++} WLANDEV_INFO_T, *P_WLANDEV_INFO_T; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++#define CHAN2G(_channel, _freq, _flags) \ ++{ \ ++ .band = NL80211_BAND_2GHZ, \ ++ .center_freq = (_freq), \ ++ .hw_value = (_channel), \ ++ .flags = (_flags), \ ++ .max_antenna_gain = 0, \ ++ .max_power = 30, \ ++} ++ ++static struct ieee80211_channel mtk_2ghz_channels[] = { ++ CHAN2G(1, 2412, 0), ++ CHAN2G(2, 2417, 0), ++ CHAN2G(3, 2422, 0), ++ CHAN2G(4, 2427, 0), ++ CHAN2G(5, 2432, 0), ++ CHAN2G(6, 2437, 0), ++ CHAN2G(7, 2442, 0), ++ CHAN2G(8, 2447, 0), ++ CHAN2G(9, 2452, 0), ++ CHAN2G(10, 2457, 0), ++ CHAN2G(11, 2462, 0), ++ CHAN2G(12, 2467, 0), ++ CHAN2G(13, 2472, 0), ++ CHAN2G(14, 2484, 0), ++}; ++ ++#define CHAN5G(_channel, _flags) \ ++{ \ ++ .band = NL80211_BAND_5GHZ, \ ++ .center_freq = 5000 + (5 * (_channel)), \ ++ .hw_value = (_channel), \ ++ .flags = (_flags), \ ++ .max_antenna_gain = 0, \ ++ .max_power = 30, \ ++} ++ ++static struct ieee80211_channel mtk_5ghz_channels[] = { ++ CHAN5G(34, 0), CHAN5G(36, 0), ++ CHAN5G(38, 0), CHAN5G(40, 0), ++ CHAN5G(42, 0), CHAN5G(44, 0), ++ CHAN5G(46, 0), CHAN5G(48, 0), ++ CHAN5G(52, 0), CHAN5G(56, 0), ++ CHAN5G(60, 0), CHAN5G(64, 0), ++ CHAN5G(100, 0), CHAN5G(104, 0), ++ CHAN5G(108, 0), CHAN5G(112, 0), ++ CHAN5G(116, 0), CHAN5G(120, 0), ++ CHAN5G(124, 0), CHAN5G(128, 0), ++ CHAN5G(132, 0), CHAN5G(136, 0), ++ CHAN5G(140, 0), CHAN5G(149, 0), ++ CHAN5G(153, 0), CHAN5G(157, 0), ++ CHAN5G(161, 0), CHAN5G(165, 0), ++ CHAN5G(169, 0), CHAN5G(173, 0), ++ CHAN5G(184, 0), CHAN5G(188, 0), ++ CHAN5G(192, 0), CHAN5G(196, 0), ++ CHAN5G(200, 0), CHAN5G(204, 0), ++ CHAN5G(208, 0), CHAN5G(212, 0), ++ CHAN5G(216, 0), ++}; ++ ++#define RATETAB_ENT(_rate, _rateid, _flags) \ ++{ \ ++ .bitrate = (_rate), \ ++ .hw_value = (_rateid), \ ++ .flags = (_flags), \ ++} ++ ++/* for cfg80211 - rate table */ ++static struct ieee80211_rate mtk_rates[] = { ++ RATETAB_ENT(10, 0x1000, 0), ++ RATETAB_ENT(20, 0x1001, 0), ++ RATETAB_ENT(55, 0x1002, 0), ++ RATETAB_ENT(110, 0x1003, 0), /* 802.11b */ ++ RATETAB_ENT(60, 0x2000, 0), ++ RATETAB_ENT(90, 0x2001, 0), ++ RATETAB_ENT(120, 0x2002, 0), ++ RATETAB_ENT(180, 0x2003, 0), ++ RATETAB_ENT(240, 0x2004, 0), ++ RATETAB_ENT(360, 0x2005, 0), ++ RATETAB_ENT(480, 0x2006, 0), ++ RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */ ++}; ++ ++#define mtk_a_rates (mtk_rates + 4) ++#define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4) ++#define mtk_g_rates (mtk_rates + 0) ++#define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0) ++ ++#define WLAN_MCS_INFO \ ++{ \ ++ .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ ++ .rx_highest = 0, \ ++ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ ++} ++ ++#define WLAN_HT_CAP \ ++{ \ ++ .ht_supported = true, \ ++ .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \ ++ | IEEE80211_HT_CAP_SM_PS \ ++ | IEEE80211_HT_CAP_GRN_FLD \ ++ | IEEE80211_HT_CAP_SGI_20 \ ++ | IEEE80211_HT_CAP_SGI_40, \ ++ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ ++ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \ ++ .mcs = WLAN_MCS_INFO, \ ++} ++ ++/********************************************************** ++* Public for both legacy Wi-Fi and P2P to access ++**********************************************************/ ++struct ieee80211_supported_band mtk_band_2ghz = { ++ .band = NL80211_BAND_2GHZ, ++ .channels = mtk_2ghz_channels, ++ .n_channels = ARRAY_SIZE(mtk_2ghz_channels), ++ .bitrates = mtk_g_rates, ++ .n_bitrates = mtk_g_rates_size, ++ .ht_cap = WLAN_HT_CAP, ++}; ++ ++struct ieee80211_supported_band mtk_band_5ghz = { ++ .band = NL80211_BAND_5GHZ, ++ .channels = mtk_5ghz_channels, ++ .n_channels = ARRAY_SIZE(mtk_5ghz_channels), ++ .bitrates = mtk_a_rates, ++ .n_bitrates = mtk_a_rates_size, ++ .ht_cap = WLAN_HT_CAP, ++}; ++ ++const UINT_32 mtk_cipher_suites[5] = { ++ /* keep WEP first, it may be removed below */ ++ WLAN_CIPHER_SUITE_WEP40, ++ WLAN_CIPHER_SUITE_WEP104, ++ WLAN_CIPHER_SUITE_TKIP, ++ WLAN_CIPHER_SUITE_CCMP, ++ ++ /* keep last -- depends on hw flags! */ ++ WLAN_CIPHER_SUITE_AES_CMAC ++}; ++ ++/*********************************************************/ ++ ++#define NIC_INF_NAME "wlan%d" /* interface name */ ++#if CFG_TC1_FEATURE ++#define NIC_INF_NAME_IN_AP_MODE "legacy%d" ++#endif ++ ++/* support to change debug module info dynamically */ ++UINT_8 aucDebugModule[DBG_MODULE_NUM]; ++UINT_32 u4DebugModule = 0; ++ ++/* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */ ++static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} }; ++ ++static UINT_32 u4WlanDevNum; /* How many NICs coexist now */ ++ ++/**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/ ++struct delayed_work sched_workq; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++#if CFG_ENABLE_WIFI_DIRECT ++static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} }; ++#endif ++ ++static struct cfg80211_ops mtk_wlan_ops = { ++ .suspend = mtk_cfg80211_suspend, ++ .resume = mtk_cfg80211_resume, ++ .change_virtual_intf = mtk_cfg80211_change_iface, ++ .add_key = mtk_cfg80211_add_key, ++ .get_key = mtk_cfg80211_get_key, ++ .del_key = mtk_cfg80211_del_key, ++ .set_default_key = mtk_cfg80211_set_default_key, ++ .set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key, ++ .get_station = mtk_cfg80211_get_station, ++ .change_station = mtk_cfg80211_change_station, ++ .add_station = mtk_cfg80211_add_station, ++ .del_station = mtk_cfg80211_del_station, ++ .scan = mtk_cfg80211_scan, ++ .connect = mtk_cfg80211_connect, ++ .disconnect = mtk_cfg80211_disconnect, ++ .join_ibss = mtk_cfg80211_join_ibss, ++ .leave_ibss = mtk_cfg80211_leave_ibss, ++ .set_power_mgmt = mtk_cfg80211_set_power_mgmt, ++ .set_pmksa = mtk_cfg80211_set_pmksa, ++ .del_pmksa = mtk_cfg80211_del_pmksa, ++ .flush_pmksa = mtk_cfg80211_flush_pmksa, ++ .assoc = mtk_cfg80211_assoc, ++ /* Action Frame TX/RX */ ++ .remain_on_channel = mtk_cfg80211_remain_on_channel, ++ .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel, ++ .mgmt_tx = mtk_cfg80211_mgmt_tx, ++/* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */ ++ .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register, ++#ifdef CONFIG_NL80211_TESTMODE ++ .testmode_cmd = mtk_cfg80211_testmode_cmd, ++#endif ++#if (CFG_SUPPORT_TDLS == 1) ++ .tdls_mgmt = TdlsexCfg80211TdlsMgmt, ++ .tdls_oper = TdlsexCfg80211TdlsOper, ++#endif /* CFG_SUPPORT_TDLS */ ++#if 1 /* Remove schedule_scan because we need more verification for NLO */ ++ .sched_scan_start = mtk_cfg80211_sched_scan_start, ++ .sched_scan_stop = mtk_cfg80211_sched_scan_stop, ++#endif ++}; ++ ++static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = { ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_channel_list ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_country_code ++ }, ++ /* GSCAN */ ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_gscan_capabilities ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_CONFIG ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_config ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV, ++ .doit = mtk_cfg80211_vendor_set_scan_config ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_enable_scan ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_enable_full_scan_results ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_scan_results ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_significant_change ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_SUBCMD_SET_HOTLIST ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_hotlist ++ }, ++ /* RTT */ ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = RTT_SUBCMD_GETCAPABILITY ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_rtt_capabilities ++ }, ++ /* Link Layer Statistics */ ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = LSTATS_SUBCMD_GET_INFO ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_llstats_get_info ++ }, ++ ++}; ++ ++static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = RTT_EVENT_COMPLETE ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_COMPLETE_SCAN ++ }, ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST ++ }, ++}; ++ ++/* There isn't a lot of sense in it, but you can transmit anything you like */ ++static const struct ieee80211_txrx_stypes ++ mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { ++ [NL80211_IFTYPE_ADHOC] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_STATION] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_AP] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_AP_VLAN] = { ++ /* copy AP */ ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | ++ BIT(IEEE80211_STYPE_DISASSOC >> 4) | ++ BIT(IEEE80211_STYPE_AUTH >> 4) | ++ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_CLIENT] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_GO] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ } ++}; ++ ++#ifdef CONFIG_PM ++static const struct wiphy_wowlan_support mtk_wlan_wowlan_support = { ++ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, ++}; ++#endif ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Override the implementation of select queue ++* ++* \param[in] dev Pointer to struct net_device ++* \param[in] skb Pointer to struct skb_buff ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++unsigned int _cfg80211_classify8021d(struct sk_buff *skb) ++{ ++ unsigned int dscp = 0; ++ ++ /* skb->priority values from 256->263 are magic values ++ * directly indicate a specific 802.1d priority. This is ++ * to allow 802.1d priority to be passed directly in from ++ * tags ++ */ ++ ++ if (skb->priority >= 256 && skb->priority <= 263) ++ return skb->priority - 256; ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ dscp = ip_hdr(skb)->tos & 0xfc; ++ break; ++ } ++ return dscp >> 5; ++} ++ ++static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; ++ ++static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev, ++ select_queue_fallback_t fallback) ++{ ++ skb->priority = _cfg80211_classify8021d(skb); ++ ++ return au16Wlan1dToQueueIdx[skb->priority]; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Load NVRAM data and translate it into REG_INFO_T ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* \param[out] prRegInfo Pointer to struct REG_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo) ++{ ++ UINT_32 i, j; ++ UINT_8 aucTmp[2]; ++ PUINT_8 pucDest; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prRegInfo); ++ ++ if ((!prGlueInfo) || (!prRegInfo)) ++ return; ++ ++ if (kalCfgDataRead16(prGlueInfo, sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16), (PUINT_16) aucTmp) == TRUE) { ++ prGlueInfo->fgNvramAvailable = TRUE; ++ ++ /* load MAC Address */ ++#if !defined(CONFIG_MTK_TC1_FEATURE) ++ for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, ++ (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i)); ++ } ++#else ++ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr); ++#endif ++ ++ /* load country code */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp); ++ ++ /* cast to wide characters */ ++ prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0]; ++ prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1]; ++ ++ /* load default normal TX power */ ++ for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i, ++ (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i)); ++ } ++ ++ /* load feature flags */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp); ++ prRegInfo->ucTxPwrValid = aucTmp[0]; ++ prRegInfo->ucSupport5GBand = aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp); ++ prRegInfo->uc2G4BwFixed20M = aucTmp[0]; ++ prRegInfo->uc5GBwFixed20M = aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp); ++ prRegInfo->ucEnable5GBand = aucTmp[0]; ++ ++ /* load EFUSE overriding part */ ++ for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i, ++ (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i)); ++ } ++ ++ /* load band edge tx power control */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp); ++ prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0]; ++ if (aucTmp[0]) { ++ prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp); ++ prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0]; ++ prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1]; ++ } ++ ++ /* load regulation subbands */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp); ++ prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0]; ++ prRegInfo->ucRegChannelListIndex = aucTmp[1]; ++ ++ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { ++ for (i = 0; i < MAX_SUBBAND_NUM; i++) { ++ pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i]; ++ for (j = 0; j < 6; j += sizeof(UINT_16)) { ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) ++ + (i * 6 + j), (PUINT_16) aucTmp); ++ ++ *pucDest++ = aucTmp[0]; ++ *pucDest++ = aucTmp[1]; ++ } ++ } ++ } ++ /* load RSSI compensation */ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp); ++ prRegInfo->uc2GRssiCompensation = aucTmp[0]; ++ prRegInfo->uc5GRssiCompensation = aucTmp[1]; ++ ++ kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp); ++ prRegInfo->fgRssiCompensationValidbit = aucTmp[0]; ++ prRegInfo->ucRxAntennanumber = aucTmp[1]; ++ } else { ++ prGlueInfo->fgNvramAvailable = FALSE; ++ } ++ ++} ++ ++#if CFG_ENABLE_WIFI_DIRECT ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief called by txthread, run sub module init function ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo) ++{ ++ /*now, we only have p2p module */ ++ if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) { ++ rSubModHandler[P2P_MODULE].subModInit(prGlueInfo); ++ rSubModHandler[P2P_MODULE].fgIsInited = TRUE; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief called by txthread, run sub module exit function ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo) ++{ ++ /*now, we only have p2p module */ ++ if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) { ++ rSubModHandler[P2P_MODULE].subModExit(prGlueInfo); ++ rSubModHandler[P2P_MODULE].fgIsInited = FALSE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set sub module init flag, force TxThread to run sub modle init ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo) ++{ ++ /* 4 Mark HALT, notify main thread to finish current job */ ++ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT; ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread finish sub module INIT */ ++ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); ++ ++#if 0 ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pNetRegister(prGlueInfo); ++#endif ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set sub module exit flag, force TxThread to run sub modle exit ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo) ++{ ++#if 0 ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ p2pNetUnregister(prGlueInfo); ++#endif ++ ++ /* 4 Mark HALT, notify main thread to finish current job */ ++ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT; ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread finish sub module EXIT */ ++ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); ++ ++ return TRUE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set by sub module, indicate sub module is already inserted ++* ++* \param[in] rSubModInit, function pointer point to sub module init function ++* \param[in] rSubModExit, function pointer point to sub module exit function ++* \param[in] eSubModIdx, sub module index ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx) ++{ ++ rSubModHandler[eSubModIdx].subModInit = rSubModInit; ++ rSubModHandler[eSubModIdx].subModExit = rSubModExit; ++ rSubModHandler[eSubModIdx].fgIsInited = FALSE; ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief check wlan is launched or not ++* ++* \param[in] (none) ++* ++* \return TRUE, wlan is already started ++* FALSE, wlan is not started yet ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wlanIsLaunched(VOID) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ /* 4 <0> Sanity check */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (0 == u4WlanDevNum) ++ return FALSE; ++ ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ ++ ASSERT(prDev); ++ if (NULL == prDev) ++ return FALSE; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (NULL == prGlueInfo) ++ return FALSE; ++ ++ return prGlueInfo->prAdapter->fgIsWlanLaunched; ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Export wlan GLUE_INFO_T pointer to p2p module ++* ++* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T ++* ++* \return TRUE: get GlueInfo pointer successfully ++* FALSE: wlan is not started yet ++*/ ++/*---------------------------------------------------------------------------*/ ++BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (0 == u4WlanDevNum) ++ return FALSE; ++ ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ if (NULL == prDev) ++ return FALSE; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ if (NULL == prGlueInfo) ++ return FALSE; ++ ++ if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) ++ return FALSE; ++ ++ *prGlueInfoExpAddr = prGlueInfo; ++ return TRUE; ++} ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Release prDev from wlandev_array and free tasklet object related to it. ++* ++* \param[in] prDev Pointer to struct net_device ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void wlanClearDevIdx(struct net_device *prDev) ++{ ++ int i; ++ ++ ASSERT(prDev); ++ ++ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { ++ if (arWlanDevInfo[i].prDev == prDev) { ++ arWlanDevInfo[i].prDev = NULL; ++ u4WlanDevNum--; ++ } ++ } ++ ++} /* end of wlanClearDevIdx() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Allocate an unique interface index, net_device::ifindex member for this ++* wlan device. Store the net_device in wlandev_array, and initialize ++* tasklet object related to it. ++* ++* \param[in] prDev Pointer to struct net_device ++* ++* \retval >= 0 The device number. ++* \retval -1 Fail to get index. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanGetDevIdx(struct net_device *prDev) ++{ ++ int i; ++ ++ ASSERT(prDev); ++ ++ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { ++ if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) { ++ /* Reserve 2 bytes space to store one digit of ++ * device number and NULL terminator. ++ */ ++ arWlanDevInfo[i].prDev = prDev; ++ u4WlanDevNum++; ++ return i; ++ } ++ } ++ ++ return -1; ++} /* end of wlanGetDevIdx() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method of struct net_device, a primary SOCKET interface to configure ++* the interface lively. Handle an ioctl call on one of our devices. ++* Everything Linux ioctl specific is done here. Then we pass the contents ++* of the ifr->data to the request message handler. ++* ++* \param[in] prDev Linux kernel netdevice ++* ++* \param[in] prIfReq Our private ioctl request structure, typed for the generic ++* struct ifreq so we can use ptr to function ++* ++* \param[in] cmd Command ID ++* ++* \retval 0 The IOCTL command is executed successfully. ++* \retval <0 The execution of IOCTL command is failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ int ret = 0; ++ ++ /* Verify input parameters for the following functions */ ++ ASSERT(prDev && prIfReq); ++ if (!prDev || !prIfReq) { ++ DBGLOG(INIT, ERROR, "Invalid input data\n"); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ if (!prGlueInfo) { ++ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); ++ return -EFAULT; ++ } ++ ++ if (prGlueInfo->u4ReadyFlag == 0) { ++ DBGLOG(INIT, ERROR, "Adapter is not ready\n"); ++ return -EINVAL; ++ } ++ ++ if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) { ++ /* 0x8B00 ~ 0x8BDF, wireless extension region */ ++ ret = wext_support_ioctl(prDev, prIfReq, i4Cmd); ++ } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) { ++ /* 0x8BE0 ~ 0x8BFF, private ioctl region */ ++ ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); ++ } else if (i4Cmd == SIOCDEVPRIVATE + 1) { ++ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); ++ } else { ++ DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd); ++ ret = -EOPNOTSUPP; ++ } ++ ++ return ret; ++} /* end of wlanDoIOCTL() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is to set multicast list and set rx mode. ++* ++* \param[in] prDev Pointer to struct net_device ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++static struct delayed_work workq; ++static struct net_device *gPrDev; ++static BOOLEAN fgIsWorkMcStart = FALSE; ++static BOOLEAN fgIsWorkMcEverInit = FALSE; ++static struct wireless_dev *gprWdev; ++ ++static void createWirelessDevice(void) ++{ ++ struct wiphy *prWiphy = NULL; ++ struct wireless_dev *prWdev = NULL; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ struct net_device *prNetDev = NULL; ++#endif ++ ++ /* <1.1> Create wireless_dev */ ++ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); ++ return; ++ } ++ ++ ++ /* <1.2> Create wiphy */ ++ prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T)); ++ if (!prWiphy) { ++ DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n"); ++ goto free_wdev; ++ } ++ ++ /* <1.3> configure wireless_dev & wiphy */ ++ prWdev->iftype = NL80211_IFTYPE_STATION; ++ prWiphy->max_scan_ssids = 1; /* FIXME: for combo scan */ ++ prWiphy->max_scan_ie_len = 512; ++ ++ prWiphy->max_sched_scan_ssids = CFG_SCAN_SSID_MAX_NUM; ++ prWiphy->max_match_sets = CFG_SCAN_SSID_MATCH_MAX_NUM; ++ prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN; ++ prWiphy->max_sched_scan_reqs = 1; ++ ++ prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); ++ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; ++ /* always assign 5Ghz bands here, if the chip is not support 5Ghz, ++ bands[IEEE80211_BAND_5GHZ] will be assign to NULL */ ++ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; ++ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; ++ prWiphy->cipher_suites = mtk_cipher_suites; ++ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); ++ prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM ++ | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; ++ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; ++#if CFG_SUPPORT_TDLS ++ TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags); ++#endif /* CFG_SUPPORT_TDLS */ ++ prWiphy->max_remain_on_channel_duration = 5000; ++ prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes; ++ prWiphy->vendor_commands = mtk_wlan_vendor_ops; ++ prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command); ++ prWiphy->vendor_events = mtk_wlan_vendor_events; ++ prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events); ++ ++ /* <1.4> wowlan support */ ++#ifdef CONFIG_PM ++ prWiphy->wowlan = &mtk_wlan_wowlan_support; ++#endif ++#ifdef CONFIG_CFG80211_WEXT ++ /* <1.5> Use wireless extension to replace IOCTL */ ++ prWiphy->wext = &wext_handler_def; ++#endif ++ ++ if (wiphy_register(prWiphy) < 0) { ++ DBGLOG(INIT, ERROR, "wiphy_register error\n"); ++ goto free_wiphy; ++ } ++ prWdev->wiphy = prWiphy; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* <2> allocate and register net_device */ ++#if CFG_TC1_FEATURE ++ if (wlan_if_changed) ++ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++ else ++#else ++ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++#endif ++ if (!prNetDev) { ++ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); ++ goto unregister_wiphy; ++ } ++ ++ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy); ++ ++ prNetDev->netdev_ops = &wlan_netdev_ops; ++#ifdef CONFIG_WIRELESS_EXT ++ prNetDev->wireless_handlers = &wext_handler_def; ++#endif ++ netif_carrier_off(prNetDev); ++ netif_tx_stop_all_queues(prNetDev); ++ ++ /* <2.1> co-relate with wireless_dev bi-directionally */ ++ prNetDev->ieee80211_ptr = prWdev; ++ prWdev->netdev = prNetDev; ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prNetDev->features = NETIF_F_HW_CSUM; ++#endif ++ ++ /* <2.2> co-relate net device & device tree */ ++ SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy)); ++ ++ /* <2.3> register net_device */ ++ if (register_netdev(prWdev->netdev) < 0) { ++ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); ++ goto unregister_wiphy; ++ } ++#endif /* CFG_SUPPORT_PERSIST_NETDEV */ ++ gprWdev = prWdev; ++ DBGLOG(INIT, INFO, "create wireless device success\n"); ++ return; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++unregister_wiphy: ++ wiphy_unregister(prWiphy); ++#endif ++free_wiphy: ++ wiphy_free(prWiphy); ++free_wdev: ++ kfree(prWdev); ++} ++ ++static void destroyWirelessDevice(void) ++{ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ unregister_netdev(gprWdev->netdev); ++ free_netdev(gprWdev->netdev); ++#endif ++ wiphy_unregister(gprWdev->wiphy); ++ wiphy_free(gprWdev->wiphy); ++ kfree(gprWdev); ++ gprWdev = NULL; ++} ++ ++static void wlanSetMulticastList(struct net_device *prDev) ++{ ++ gPrDev = prDev; ++ schedule_delayed_work(&workq, 0); ++} ++ ++/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange ++ * another workqueue for sleeping. We don't want to block ++ * tx_thread, so we can't let tx_thread to do this */ ++ ++static void wlanSetMulticastListWorkQueue(struct work_struct *work) ++{ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4PacketFilter = 0; ++ UINT_32 u4SetInfoLen; ++ struct net_device *prDev = gPrDev; ++ ++ fgIsWorkMcStart = TRUE; ++ ++ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) ++ return; ++ if (kalIsHalted()) { ++ fgIsWorkMcStart = FALSE; ++ kalHaltUnlock(); ++ return; ++ } ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ if (!prDev || !prGlueInfo) { ++ DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); ++ fgIsWorkMcStart = FALSE; ++ kalHaltUnlock(); ++ return; ++ } ++ ++ if (prDev->flags & IFF_PROMISC) ++ u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; ++ ++ if (prDev->flags & IFF_BROADCAST) ++ u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; ++ ++ if (prDev->flags & IFF_MULTICAST) { ++ if ((prDev->flags & IFF_ALLMULTI) || ++ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { ++ ++ u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; ++ } else { ++ u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; ++ } ++ } ++ ++ kalHaltUnlock(); ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidSetCurrentPacketFilter, ++ &u4PacketFilter, ++ sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) { ++ fgIsWorkMcStart = FALSE; ++ DBGLOG(INIT, ERROR, "wlanSetMulticastListWorkQueue kalIoctl u4PacketFilter=%d\n", u4PacketFilter); ++ return; ++ } ++ ++ if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { ++ /* Prepare multicast address list */ ++ struct netdev_hw_addr *ha; ++ PUINT_8 prMCAddrList = NULL; ++ UINT_32 i = 0; ++ ++ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) ++ return; ++ if (kalIsHalted()) { ++ fgIsWorkMcStart = FALSE; ++ kalHaltUnlock(); ++ /*DBGLOG(INIT, WARN, "wlanSetMulticastListWorkQueue g_u4HaltFlag=%d\n", g_u4HaltFlag);*/ ++ return; ++ } ++ ++ prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE); ++ ++ netdev_for_each_mc_addr(ha, prDev) { ++ if (i < MAX_NUM_GROUP_ADDR) { ++ memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN); ++ i++; ++ } ++ } ++ ++ kalHaltUnlock(); ++ ++ kalIoctl(prGlueInfo, ++ wlanoidSetMulticastList, ++ prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ ++ kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN); ++ } ++ ++ fgIsWorkMcStart = FALSE; ++ ++} /* end of wlanSetMulticastList() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate scheduled scan has been stopped ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct net_device *prDev = gPrDev; ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ if (!prGlueInfo) { ++ DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n"); ++ return; ++ } ++ ++ /* 2. indication to cfg80211 */ ++ /* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */ ++ cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo),0); ++ DBGLOG(SCN, INFO, ++ "cfg80211_sched_scan_stopped event send done\n"); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is TX entry point of NET DEVICE. ++* ++* \param[in] prSkb Pointer of the sk_buff to be sent ++* \param[in] prDev Pointer to struct net_device ++* ++* \retval NETDEV_TX_OK - on success. ++* \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. ++*/ ++/*----------------------------------------------------------------------------*/ ++int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_QUE_T prTxQueue = NULL; ++ UINT_16 u2QueueIdx = 0; ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ UINT16 u2Identifier = 0; ++#endif ++ ++#if CFG_BOW_TEST ++ UINT_32 i; ++#endif ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prSkb); ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ prGlueInfo->u8SkbToDriver++; ++ ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ { ++ UINT8 *pkt = prSkb->data; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ /* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */ ++ DBGLOG(INIT, INFO, " %d\n", u2Identifier); ++ } ++ } ++#endif ++ /* check if WiFi is halt */ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n"); ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ if (prGlueInfo->fgIsDad) { ++ /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */ ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++ if (prGlueInfo->fgIs6Dad) { ++ /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */ ++ dev_kfree_skb(prSkb); ++ prGlueInfo->u8SkbFreed++; ++ return NETDEV_TX_OK; ++ } ++#endif ++ ++ STATS_TX_TIME_ARRIVE(prSkb); ++ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); ++ prTxQueue = &prGlueInfo->rTxQueue; ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len); ++ DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len); ++ DBGLOG(BOW, TRACE, "sk_buff->data:\n"); ++ ++ for (i = 0; i < prSkb->len; i++) { ++ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); ++ ++ if ((i + 1) % 16 == 0) ++ DBGLOG(BOW, TRACE, "\n"); ++ } ++ ++ DBGLOG(BOW, TRACE, "\n"); ++#endif ++ ++ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { ++ ++ /* non-1x packets */ ++ ++#if CFG_DBG_GPIO_PINS ++ { ++ /* TX request from OS */ ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW); ++ kalUdelay(1); ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH); ++ } ++#endif ++ ++ u2QueueIdx = skb_get_queue_mapping(prSkb); ++ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); ++ ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); ++#endif ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ if (u2QueueIdx < CFG_MAX_TXQ_NUM) ++ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++/* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */ ++/* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */ ++ ++ if (u2QueueIdx < CFG_MAX_TXQ_NUM) { ++ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= ++ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { ++ DBGLOG(TX, INFO, "netif_stop_subqueue for wlan0, Queue len: %d\n", ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); ++ ++ netif_stop_subqueue(prDev, u2QueueIdx); ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01; ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ } ++ } ++ } else { ++ /* printk("is security frame\n"); */ ++ ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++ } ++ ++ DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len); ++ prGlueInfo->rNetDevStats.tx_bytes += prSkb->len; ++ prGlueInfo->rNetDevStats.tx_packets++; ++ kalPerMonStart(prGlueInfo); ++ ++ /* set GLUE_FLAG_TXREQ_BIT */ ++ ++ /* pr->u4Flag |= GLUE_FLAG_TXREQ; */ ++ /* wake_up_interruptible(&prGlueInfo->waitq); */ ++ kalSetEvent(prGlueInfo); ++ ++ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ ++ return NETDEV_TX_OK; ++} /* end of wlanHardStartXmit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method of struct net_device, to get the network interface statistical ++* information. ++* ++* Whenever an application needs to get statistics for the interface, this method ++* is called. This happens, for example, when ifconfig or netstat -i is run. ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \return net_device_stats buffer pointer. ++*/ ++/*----------------------------------------------------------------------------*/ ++struct net_device_stats *wlanGetStats(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++#if 0 ++ WLAN_STATUS rStatus; ++ UINT_32 u4XmitError = 0; ++ UINT_32 u4XmitOk = 0; ++ UINT_32 u4RecvError = 0; ++ UINT_32 u4RecvOk = 0; ++ UINT_32 u4BufLen; ++ ++ ASSERT(prDev); ++ ++ /* @FIX ME: need a more clear way to do this */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); ++ prGlueInfo->rNetDevStats.rx_packets = u4RecvOk; ++ prGlueInfo->rNetDevStats.tx_packets = u4XmitOk; ++ prGlueInfo->rNetDevStats.tx_errors = u4XmitError; ++ prGlueInfo->rNetDevStats.rx_errors = u4RecvError; ++ /* prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes; */ ++ /* prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes; */ ++ /* prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors; */ ++ /* prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast; */ ++#endif ++ /* prGlueInfo->rNetDevStats.rx_packets = 0; */ ++ /* prGlueInfo->rNetDevStats.tx_packets = 0; */ ++ prGlueInfo->rNetDevStats.tx_errors = 0; ++ prGlueInfo->rNetDevStats.rx_errors = 0; ++ /* prGlueInfo->rNetDevStats.rx_bytes = 0; */ ++ /* prGlueInfo->rNetDevStats.tx_bytes = 0; */ ++ prGlueInfo->rNetDevStats.rx_errors = 0; ++ prGlueInfo->rNetDevStats.multicast = 0; ++ ++ return &prGlueInfo->rNetDevStats; ++ ++} /* end of wlanGetStats() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->init ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanInit succeeds. ++* \retval -ENXIO No such device. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanInit(struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (fgIsWorkMcEverInit == FALSE) { ++ if (!prDev) ++ return -ENXIO; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue); ++ ++ /* 20150205 work queue for sched_scan */ ++ INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue); ++ ++ fgIsWorkMcEverInit = TRUE; ++ } ++ ++ return 0; /* success */ ++} /* end of wlanInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->uninit ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void wlanUninit(struct net_device *prDev) ++{ ++ ++} /* end of wlanUninit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->open ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanOpen succeeds. ++* \retval < 0 The execution of wlanOpen failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanOpen(struct net_device *prDev) ++{ ++ ASSERT(prDev); ++ ++ netif_tx_start_all_queues(prDev); ++ ++ return 0; /* success */ ++} /* end of wlanOpen() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->stop ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanStop succeeds. ++* \retval < 0 The execution of wlanStop failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wlanStop(struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ ++ struct cfg80211_scan_info info = { ++ .aborted = true, ++ }; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ /* CFG80211 down */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueInfo->prScanRequest; ++ prGlueInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (prScanRequest) ++ cfg80211_scan_done(prScanRequest, &info); ++ netif_tx_stop_all_queues(prDev); ++ ++ return 0; /* success */ ++} /* end of wlanStop() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief Update channel table for cfg80211 based on current country domain ++ * ++ * \param[in] prGlueInfo Pointer to glue info ++ * ++ * \return none ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_8 i, j; ++ UINT_8 ucNumOfChannel; ++ RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)]; ++ ++ /* 1. Disable all channels */ ++ for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) { ++ mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; ++ mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) { ++ mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; ++ mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; ++ } ++ ++ /* 2. Get current domain channel list */ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, ++ BAND_NULL, FALSE, ++ ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels), ++ &ucNumOfChannel, aucChannelList); ++ ++ /* 3. Enable specific channel based on domain channel list */ ++ for (i = 0; i < ucNumOfChannel; i++) { ++ switch (aucChannelList[i].eBand) { ++ case BAND_2G4: ++ for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) { ++ if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { ++ mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; ++ mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; ++ break; ++ } ++ } ++ break; ++ ++ case BAND_5G: ++ for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) { ++ if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { ++ mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; ++ mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; ++ break; ++ } ++ } ++ break; ++ ++ default: ++ DBGLOG(INIT, WARN, "Unknown band %d\n", aucChannelList[i].eBand); ++ break; ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Register the device to the kernel and return the index. ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanNetRegister succeeds. ++* \retval < 0 The execution of wlanNetRegister failed. ++*/ ++/*----------------------------------------------------------------------------*/ ++static INT_32 wlanNetRegister(struct wireless_dev *prWdev) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ INT_32 i4DevIdx = -1; ++ ++ ASSERT(prWdev); ++ ++ do { ++ if (!prWdev) ++ break; ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ i4DevIdx = wlanGetDevIdx(prWdev->netdev); ++ if (i4DevIdx < 0) { ++ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n"); ++ break; ++ } ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ if (register_netdev(prWdev->netdev) < 0) { ++ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); ++ ++ wiphy_unregister(prWdev->wiphy); ++ wlanClearDevIdx(prWdev->netdev); ++ i4DevIdx = -1; ++ } ++#endif ++ if (i4DevIdx != -1) ++ prGlueInfo->fgIsRegistered = TRUE; ++ ++ } while (FALSE); ++ ++ return i4DevIdx; /* success */ ++} /* end of wlanNetRegister() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Unregister the device from the kernel ++* ++* \param[in] prWdev Pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID wlanNetUnregister(struct wireless_dev *prWdev) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n"); ++ return; ++ } ++ DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev); ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ wlanClearDevIdx(prWdev->netdev); ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ unregister_netdev(prWdev->netdev); ++#endif ++ prGlueInfo->fgIsRegistered = FALSE; ++ ++ DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex); ++ ++} /* end of wlanNetUnregister() */ ++ ++static const struct net_device_ops wlan_netdev_ops = { ++ .ndo_open = wlanOpen, ++ .ndo_stop = wlanStop, ++ .ndo_set_rx_mode = wlanSetMulticastList, ++ .ndo_get_stats = wlanGetStats, ++ .ndo_do_ioctl = wlanDoIOCTL, ++ .ndo_start_xmit = wlanHardStartXmit, ++ .ndo_init = wlanInit, ++ .ndo_uninit = wlanUninit, ++ .ndo_select_queue = wlanSelectQueue, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method for creating Linux NET4 struct net_device object and the ++* private data(prGlueInfo and prAdapter). Setup the IO address to the HIF. ++* Assign the function pointer to the net_device object ++* ++* \param[in] pvData Memory address for the device ++* ++* \retval Not null The wireless_dev object. ++* \retval NULL Fail to create wireless_dev object ++*/ ++/*----------------------------------------------------------------------------*/ ++static struct lock_class_key rSpinKey[SPIN_LOCK_NUM]; ++static struct wireless_dev *wlanNetCreate(PVOID pvData) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct wireless_dev *prWdev = gprWdev; ++ UINT_32 i; ++ struct device *prDev; ++ ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); ++ return NULL; ++ } ++ /* 4 <1> co-relate wiphy & prDev */ ++#if MTK_WCN_HIF_SDIO ++ mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev); ++#else ++/* prDev = &((struct sdio_func *) pvData)->dev; //samp */ ++ prDev = pvData; /* samp */ ++#endif ++ if (!prDev) ++ DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n"); ++ /* don't set prDev as parent of wiphy->dev, because we have done device_add ++ in driver init. if we set parent here, parent will be not able to know this child, ++ and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent ++ has been freed. */ ++ /*set_wiphy_dev(prWdev->wiphy, prDev);*/ ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ /* 4 <3> Initial Glue structure */ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T)); ++ /* 4 <3.1> Create net device */ ++#if CFG_TC1_FEATURE ++ if (wlan_if_changed) { ++ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, ++ NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); ++ } else { ++ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++ } ++#else ++ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++#endif ++ if (!prGlueInfo->prDevHandler) { ++ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); ++ return NULL; ++ } ++ DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n", ++ prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex); ++ ++ /* 4 <3.1.1> initialize net device varaiables */ ++ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo; ++ ++ prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops; ++#ifdef CONFIG_WIRELESS_EXT ++ prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def; ++#endif ++ netif_carrier_off(prGlueInfo->prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); ++ ++ /* 4 <3.1.2> co-relate with wiphy bi-directionally */ ++ prGlueInfo->prDevHandler->ieee80211_ptr = prWdev; ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM; ++#endif ++ prWdev->netdev = prGlueInfo->prDevHandler; ++ ++ /* 4 <3.1.3> co-relate net device & prDev */ ++ /*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/ ++ SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev); ++#else /* CFG_SUPPORT_PERSIST_NETDEV */ ++ prGlueInfo->prDevHandler = gprWdev->netdev; ++#endif /* CFG_SUPPORT_PERSIST_NETDEV */ ++ ++ /* 4 <3.2> initiali glue variables */ ++ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; ++ prGlueInfo->ePowerState = ParamDeviceStateD0; ++ prGlueInfo->fgIsMacAddrOverride = FALSE; ++ prGlueInfo->fgIsRegistered = FALSE; ++ prGlueInfo->prScanRequest = NULL; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ /* Init DAD */ ++ prGlueInfo->fgIsDad = FALSE; ++ prGlueInfo->fgIs6Dad = FALSE; ++ kalMemZero(prGlueInfo->aucDADipv4, 4); ++ kalMemZero(prGlueInfo->aucDADipv6, 16); ++#endif ++ ++ init_completion(&prGlueInfo->rScanComp); ++ init_completion(&prGlueInfo->rHaltComp); ++ init_completion(&prGlueInfo->rPendComp); ++#if CFG_ENABLE_WIFI_DIRECT ++ init_completion(&prGlueInfo->rSubModComp); ++#endif ++ ++ /* initialize timer for OID timeout checker */ ++ kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler); ++ ++ for (i = 0; i < SPIN_LOCK_NUM; i++) { ++ spin_lock_init(&prGlueInfo->rSpinLock[i]); ++ lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]); ++ } ++ ++ /* initialize semaphore for ioctl */ ++ sema_init(&prGlueInfo->ioctl_sem, 1); ++ ++ glSetHifInfo(prGlueInfo, (ULONG) pvData); ++ ++ /* 4 <8> Init Queues */ ++ init_waitqueue_head(&prGlueInfo->waitq); ++ QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); ++ QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); ++ ++ /* 4 <4> Create Adapter structure */ ++ prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo); ++ ++ if (!prGlueInfo->prAdapter) { ++ DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n"); ++ return NULL; ++ } ++ KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR"); ++#if CFG_SUPPORT_PERSIST_NETDEV ++ dev_open(prGlueInfo->prDevHandler); ++ netif_carrier_off(prGlueInfo->prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); ++#endif ++ ++ return prWdev; ++} /* end of wlanNetCreate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Destroying the struct net_device object and the private data. ++* ++* \param[in] prWdev Pointer to struct wireless_dev. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID wlanNetDestroy(struct wireless_dev *prWdev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prWdev); ++ ++ if (!prWdev) { ++ DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n"); ++ return; ++ } ++ ++ /* prGlueInfo is allocated with net_device */ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ ASSERT(prGlueInfo); ++ ++ /* destroy kal OS timer */ ++ kalCancelTimer(prGlueInfo); ++ ++ glClearHifInfo(prGlueInfo); ++ ++ wlanAdapterDestroy(prGlueInfo->prAdapter); ++ prGlueInfo->prAdapter = NULL; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* take the net_device to down state */ ++ dev_close(prGlueInfo->prDevHandler); ++#else ++ /* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */ ++ free_netdev(prWdev->netdev); ++#endif ++ ++} /* end of wlanNetDestroy() */ ++ ++#ifndef CONFIG_X86 ++UINT_8 g_aucBufIpAddr[32] = { 0 }; ++static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidNotifyFwSuspend, ++ (PVOID)&fgSuspend, ++ sizeof(fgSuspend), ++ FALSE, ++ FALSE, ++ TRUE, ++ FALSE, ++ &u4SetInfoLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n"); ++} ++ ++void wlanHandleSystemSuspend(void) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_8 ip[4] = { 0 }; ++ UINT_32 u4NumIPv4 = 0; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++ UINT_32 u4NumIPv6 = 0; ++#endif ++ UINT_32 i; ++ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; ++ ++ /* <1> Sanity check and acquire the net_device */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (u4WlanDevNum == 0) { ++ DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n"); ++ return; ++ } ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ ++ fgIsUnderSuspend = true; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ kalPerMonDisable(prGlueInfo); ++ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ goto notify_suspend; ++ } ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++ /* todo: traverse between list to find whole sets of IPv4 addresses */ ++ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) ++ u4NumIPv4++; ++#ifdef CONFIG_IPV6 ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ goto notify_suspend; ++ } ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ++ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] ++ ); ++ ++ /* todo: traverse between list to find whole sets of IPv6 addresses */ ++ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) { ++ /* Do nothing */ ++ /* u4NumIPv6++; */ ++ } ++#endif ++ ++ /* <7> set up the ARP filter */ ++ { ++ UINT_32 u4SetInfoLen = 0; ++ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = u4NumIPv4; ++#ifdef CONFIG_IPV6 ++ prParamNetAddrList->u4AddressCount += u4NumIPv6; ++#endif ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ for (i = 0; i < u4NumIPv4; i++) { ++ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; ++ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); ++ prParamNetAddr = ++ (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); ++ } ++#ifdef CONFIG_IPV6 ++ for (i = 0; i < u4NumIPv6; i++) { ++ prParamNetAddr->u2AddressLength = 6; ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); ++ } ++#endif ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ ++notify_suspend: ++ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ wlanNotifyFwSuspend(prGlueInfo, TRUE); ++} ++ ++void wlanHandleSystemResume(void) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_8 ip[4] = { 0 }; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++#endif ++ EVENT_AIS_BSS_INFO_T rParam; ++ UINT_32 u4BufLen = 0; ++ ++ /* <1> Sanity check and acquire the net_device */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (u4WlanDevNum == 0) { ++ DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n"); ++ return; ++ } ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ /* ASSERT(prDev); */ ++ ++ fgIsUnderSuspend = false; ++ ++ if (!prDev) { ++ DBGLOG(INIT, INFO, "prDev == NULL!!!\n"); ++ return; ++ } ++ /* <3> acquire the prGlueInfo */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ kalPerMonEnable(prGlueInfo); ++ ++ /* ++ We will receive the event in rx, we will check if the status is the same in driver ++ and FW, if not the same, trigger disconnetion procedure. ++ */ ++ ++ kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBSSInfo, ++ &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus); ++ } ++ ++ /* <2> get the IPv4 address */ ++ if (!(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ goto notify_resume; ++ } ++ /* <4> copy the IPv4 address */ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++#ifdef CONFIG_IPV6 ++ /* <5> get the IPv6 address */ ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ goto notify_resume; ++ } ++ /* <6> copy the IPv6 address */ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ++ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] ++ ); ++#endif ++ /* <7> clear the ARP filter */ ++ { ++ UINT_32 u4SetInfoLen = 0; ++/* UINT_8 aucBuf[32] = {0}; */ ++ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ /* aucBuf; */ ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = 0; ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ ++notify_resume: ++ DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n", ++ rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive, ++ ip[0], ip[1], ip[2], ip[3], rStatus); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ wlanNotifyFwSuspend(prGlueInfo, FALSE); ++ } ++} ++#endif /* ! CONFIG_X86 */ ++ ++int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode) ++{ ++#if 0 ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); ++ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ rSetP2P.u4Enable = p2pmode.u4Enable; ++ rSetP2P.u4Mode = p2pmode.u4Mode; ++ ++ if (!rSetP2P.u4Enable) ++ p2pNetUnregister(prGlueInfo, TRUE); ++ ++ rWlanStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pMode, ++ (PVOID) &rSetP2P, ++ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus); ++ if (rSetP2P.u4Enable) ++ p2pNetRegister(prGlueInfo, TRUE); ++ ++ return 0; ++ ++#else ++ ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); ++ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgIsP2PEnding; ++ UINT_32 u4BufLen = 0; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode); ++ ++ /* avoid remove & p2p off command simultaneously */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ fgIsP2PEnding = g_u4P2PEnding; ++ g_u4P2POnOffing = 1; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ ++ if (fgIsP2PEnding == 1) { ++ /* skip the command if we are removing */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ return 0; ++ } ++ ++ rSetP2P.u4Enable = p2pmode.u4Enable; ++ rSetP2P.u4Mode = p2pmode.u4Mode; ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE)) ++ p2pNetUnregister(prGlueInfo, TRUE); ++#endif ++ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ ++ /* ++ Scenario: ++ 1. System enters suspend/resume but not yet enter wlanearlysuspend() ++ or wlanlateresume(); ++ ++ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() ++ and get g_halt_sem then do glRegisterEarlySuspend() or ++ glUnregisterEarlySuspend(); ++ ++ But system suspend/resume procedure is not yet finished so we ++ suspend; ++ ++ 3. System switches back to do suspend/resume procedure and execute ++ kalIoctl(). But driver does not yet release g_halt_sem so system ++ suspend in wlanearlysuspend() or wlanlateresume(); ++ ++ ==> deadlock occurs. ++ */ ++ ++ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */ ++ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ /* Need to check fgIsP2PRegistered, in case of whole chip reset. ++ * in this case, kalIOCTL return success always, ++ * and prGlueInfo->prP2pInfo may be NULL */ ++ if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE)) ++ p2pNetRegister(prGlueInfo, TRUE); ++#endif ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ return 0; ++#endif ++} ++ ++static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM]) ++{ ++ kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule)); ++ kalPrint("[wlan] change debug level"); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Wlan probe function. This function probes and initializes the device. ++* ++* \param[in] pvData data passed by bus driver init function ++* _HIF_EHPI: NULL ++* _HIF_SDIO: sdio bus driver handle ++* ++* \retval 0 Success ++* \retval negative value Failed ++*/ ++/*----------------------------------------------------------------------------*/ ++static INT_32 wlanProbe(PVOID pvData) ++{ ++ struct wireless_dev *prWdev = NULL; ++ enum probe_fail_reason { ++ BUS_INIT_FAIL, ++ NET_CREATE_FAIL, ++ BUS_SET_IRQ_FAIL, ++ ADAPTER_START_FAIL, ++ NET_REGISTER_FAIL, ++ PROC_INIT_FAIL, ++ FAIL_REASON_NUM ++ } eFailReason; ++ P_WLANDEV_INFO_T prWlandevInfo = NULL; ++ INT_32 i4DevIdx = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ INT_32 i4Status = 0; ++ BOOLEAN bRet = FALSE; ++ ++ eFailReason = FAIL_REASON_NUM; ++ do { ++ /* 4 <1> Initialize the IO port of the interface */ ++ /* GeorgeKuo: pData has different meaning for _HIF_XXX: ++ * _HIF_EHPI: pointer to memory base variable, which will be ++ * initialized by glBusInit(). ++ * _HIF_SDIO: bus driver handle ++ */ ++ ++ bRet = glBusInit(pvData); ++ wlanDebugInit(); ++ /* Cannot get IO address from interface */ ++ if (FALSE == bRet) { ++ DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n"); ++ i4Status = -EIO; ++ eFailReason = BUS_INIT_FAIL; ++ break; ++ } ++ /* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */ ++ prWdev = wlanNetCreate(pvData); ++ if (prWdev == NULL) { ++ DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n"); ++ i4Status = -ENOMEM; ++ eFailReason = NET_CREATE_FAIL; ++ break; ++ } ++ /* 4 <2.5> Set the ioaddr to HIF Info */ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); ++ gPrDev = prGlueInfo->prDevHandler; ++ ++ /* 4 <4> Setup IRQ */ ++ prWlandevInfo = &arWlanDevInfo[i4DevIdx]; ++ ++ i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ ++ if (i4Status != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n"); ++ eFailReason = BUS_SET_IRQ_FAIL; ++ break; ++ } ++ ++ prGlueInfo->i4DevIdx = i4DevIdx; ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ prGlueInfo->u4ReadyFlag = 0; ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP); ++#endif ++#if CFG_SUPPORT_CFG_FILE ++ { ++ PUINT_8 pucConfigBuf; ++ UINT_32 u4ConfigReadLen; ++ ++ wlanCfgInit(prAdapter, NULL, 0, 0); ++ pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE); ++ u4ConfigReadLen = 0; ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n"); ++ if (pucConfigBuf) { ++ kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); ++ if (kalReadToFile("/data/misc/wifi.cfg", ++ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n"); ++ ++ } else if (kalReadToFile("/data/misc/wifi/wifi.cfg", ++ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n"); ++ } else if (kalReadToFile("/etc/firmware/wifi.cfg", ++ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { ++ DBGLOG(INIT, LOUD, "CFG_FILE: Read /etc/firmware/wifi.cfg\n"); ++ } ++ ++ if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) ++ wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0); ++ kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE); ++ } /* pucConfigBuf */ ++ } ++#endif ++ /* 4 <5> Start Device */ ++ /* */ ++#if CFG_ENABLE_FW_DOWNLOAD ++ DBGLOG(INIT, TRACE, "start to download firmware...\n"); ++ ++ /* before start adapter, we need to open and load firmware */ ++ { ++ UINT_32 u4FwSize = 0; ++ PVOID prFwBuffer = NULL; ++ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; ++ ++ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ ++ kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T)); ++ prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS; ++ prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS; ++ ++ /* Load NVRAM content to REG_INFO_T */ ++ glLoadNvram(prGlueInfo, prRegInfo); ++#if CFG_SUPPORT_CFG_FILE ++ wlanCfgApply(prAdapter); ++#endif ++ ++ /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */ ++ ++ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; ++ prRegInfo->fgEnArpFilter = TRUE; ++ ++ if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) { ++ i4Status = -EIO; ++ DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n"); ++ goto bailout; ++ } else { ++ ++ if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, ++ u4FwSize) != WLAN_STATUS_SUCCESS) { ++ i4Status = -EIO; ++ } ++ } ++ ++ kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer); ++ ++bailout: ++ /* kfree(prRegInfo); */ ++ ++ DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status); ++ ++ if (i4Status < 0) { ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4FwCnt; ++ ++ DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n"); ++ HifInfo = &prAdapter->prGlueInfo->rHifInfo; ++ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) ++ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); ++ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ ++ ++ /* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */ ++ /* dump HIF register may be hung */ ++ if (!fgIsBusAccessFailed) ++ HifRegDump(prGlueInfo->prAdapter); ++/* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */ ++/* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */ ++ eFailReason = ADAPTER_START_FAIL; ++ break; ++ } ++ } ++#else ++ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ ++ kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T)); ++ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; ++ ++ /* Load NVRAM content to REG_INFO_T */ ++ glLoadNvram(prGlueInfo, prRegInfo); ++ ++ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; ++ ++ if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) { ++ i4Status = -EIO; ++ eFailReason = ADAPTER_START_FAIL; ++ break; ++ } ++#endif ++ if (FALSE == prAdapter->fgEnable5GBand) ++ prWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; ++ ++ prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread"); ++ kalSetHalted(FALSE); ++#if CFG_SUPPORT_ROAMING_ENC ++ /* adjust roaming threshold */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ CMD_ROAMING_INFO_T rRoamingInfo; ++ UINT_32 u4SetInfoLen = 0; ++ ++ prAdapter->fgIsRoamingEncEnabled = TRUE; ++ ++ /* suggestion from Tsaiyuan.Hsu */ ++ kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T)); ++ rRoamingInfo.fgIsFastRoamingApplied = TRUE; ++ ++ DBGLOG(INIT, TRACE, "Enable roaming enhance function\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRoamingInfo, ++ &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus); ++ } ++#endif /* CFG_SUPPORT_ROAMING_ENC */ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++ /* adjust tx rate switch threshold */ ++ rlmTxRateEnhanceConfig(prGlueInfo->prAdapter); ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ ++ /* set MAC address */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ struct sockaddr MacAddr; ++ UINT_32 u4SetInfoLen = 0; ++ ++ kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data)); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryCurrentAddr, ++ &MacAddr.sa_data, ++ PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus); ++ prGlueInfo->u4ReadyFlag = 0; ++ } else { ++ ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data)); ++ ether_addr_copy(prGlueInfo->prDevHandler->perm_addr, ++ prGlueInfo->prDevHandler->dev_addr); ++ ++ /* card is ready */ ++ prGlueInfo->u4ReadyFlag = 1; ++#if CFG_SHOW_MACADDR_SOURCE ++ DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data)); ++#endif ++ } ++ } ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ /* set HW checksum offload */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; ++ UINT_32 u4SetInfoLen = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetCSUMOffload, ++ (PVOID) &u4CSUMFlags, ++ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus); ++ } ++#endif ++ ++ /* 4 <3> Register the card */ ++ DBGLOG(INIT, TRACE, "wlanNetRegister...\n"); ++ i4DevIdx = wlanNetRegister(prWdev); ++ if (i4DevIdx < 0) { ++ i4Status = -ENXIO; ++ DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n"); ++ eFailReason = NET_REGISTER_FAIL; ++ break; ++ } ++ ++ wlanRegisterNotifier(); ++ /* 4 <6> Initialize /proc filesystem */ ++#ifdef WLAN_INCLUDE_PROC ++ DBGLOG(INIT, TRACE, "init procfs...\n"); ++ i4Status = procCreateFsEntry(prGlueInfo); ++ if (i4Status < 0) { ++ DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n"); ++ eFailReason = PROC_INIT_FAIL; ++ break; ++ } ++#endif /* WLAN_INCLUDE_PROC */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; ++ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; ++ glRegisterAmpc(prGlueInfo); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ DBGLOG(INIT, TRACE, "wlanSubModInit...\n"); ++ ++ /* wlan is launched */ ++ prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE; ++ /* if p2p module is inserted, notify tx_thread to init p2p network */ ++ if (rSubModHandler[P2P_MODULE].subModInit) ++ wlanSubModInit(prGlueInfo); ++ /* register set_p2p_mode handler to mtk_wmt_wifi */ ++ register_set_p2p_mode_handler(set_p2p_mode_handler); ++#endif ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP"); ++#endif ++ } while (FALSE); ++ ++ if (i4Status != WLAN_STATUS_SUCCESS) { ++ switch (eFailReason) { ++ case PROC_INIT_FAIL: ++ wlanNetUnregister(prWdev); ++ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread stops */ ++ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ wlanAdapterStop(prAdapter); ++ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case NET_REGISTER_FAIL: ++ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ /* wait main thread stops */ ++ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); ++ wlanAdapterStop(prAdapter); ++ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case ADAPTER_START_FAIL: ++ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case BUS_SET_IRQ_FAIL: ++ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ wlanNetDestroy(prWdev); ++ break; ++ case NET_CREATE_FAIL: ++ break; ++ case BUS_INIT_FAIL: ++ break; ++ default: ++ break; ++ } ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ { ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2PEnding = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ } ++#endif ++#if CFG_SUPPORT_AGPS_ASSIST ++ if (i4Status == WLAN_STATUS_SUCCESS) ++ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0); ++#endif ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ { ++ int iMetInitRet = WLAN_STATUS_FAILURE; ++ ++ if (i4Status == WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, TRACE, "init MET procfs...\n"); ++ iMetInitRet = kalMetInitProcfs(prGlueInfo); ++ if (iMetInitRet < 0) ++ DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n"); ++ } ++ } ++#endif ++ if (i4Status == WLAN_STATUS_SUCCESS) { ++ /*Init performance monitor structure */ ++ kalPerMonInit(prGlueInfo); ++ /* probe ok */ ++ DBGLOG(INIT, TRACE, "wlanProbe ok\n"); ++ } else { ++ /* we don't care the return value of mtk_wcn_set_connsys_power_off_flag, ++ * because even this function returns ++ * error, we can also call core dump but only core dump failed. */ ++ if (g_IsNeedDoChipReset) ++ mtk_wcn_set_connsys_power_off_flag(0); ++ /* probe failed */ ++ DBGLOG(INIT, ERROR, "wlanProbe failed\n"); ++ } ++ ++ return i4Status; ++} /* end of wlanProbe() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method to stop driver operation and release all resources. Following ++* this call, no frame should go up or down through this interface. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID wlanRemove(VOID) ++{ ++#define KAL_WLAN_REMOVE_TIMEOUT_MSEC 3000 ++ struct net_device *prDev = NULL; ++ P_WLANDEV_INFO_T prWlandevInfo = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ ++ DBGLOG(INIT, LOUD, "Remove wlan!\n"); ++ ++ /* 4 <0> Sanity check */ ++ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); ++ if (0 == u4WlanDevNum) { ++ DBGLOG(INIT, ERROR, "0 == u4WlanDevNum\n"); ++ return; ++ } ++ /* unregister set_p2p_mode handler to mtk_wmt_wifi */ ++ register_set_p2p_mode_handler(NULL); ++ ++ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; ++ prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1]; ++ ++ ASSERT(prDev); ++ if (NULL == prDev) { ++ DBGLOG(INIT, ERROR, "NULL == prDev\n"); ++ return; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (NULL == prGlueInfo) { ++ DBGLOG(INIT, ERROR, "NULL == prGlueInfo\n"); ++ free_netdev(prDev); ++ return; ++ } ++ ++ kalPerMonDestroy(prGlueInfo); ++#if CFG_ENABLE_WIFI_DIRECT ++ /* avoid remove & p2p off command simultaneously */ ++ { ++ BOOLEAN fgIsP2POnOffing; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2PEnding = 1; ++ fgIsP2POnOffing = g_u4P2POnOffing; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ ++ DBGLOG(INIT, TRACE, "waiting for fgIsP2POnOffing...\n"); ++ ++ /* History: cannot use down() here, sometimes we cannot come back here */ ++ /* waiting for p2p off command finishes, we cannot skip the remove */ ++ while (1) { ++ if (fgIsP2POnOffing == 0) ++ break; ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ fgIsP2POnOffing = g_u4P2POnOffing; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ } ++ } ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered) { ++ bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter); ++ /* wait 300ms for BoW module to send deauth */ ++ kalMsleep(300); ++ } ++#endif ++ ++ /* 4 <1> Stopping handling interrupt and free IRQ */ ++ DBGLOG(INIT, TRACE, "free IRQ...\n"); ++ glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev))); ++ ++ kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); ++ ++ kalSetHalted(TRUE); /* before flush_delayed_work() */ ++ if (fgIsWorkMcStart == TRUE) { ++ DBGLOG(INIT, TRACE, "flush_delayed_work...\n"); ++ flush_delayed_work(&workq); /* flush_delayed_work_sync is deprecated */ ++ } ++ ++ flush_delayed_work(&sched_workq); ++ ++ DBGLOG(INIT, INFO, "down g_halt_sem...\n"); ++ kalHaltLock(KAL_WLAN_REMOVE_TIMEOUT_MSEC); ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); ++#endif ++ ++/* flush_delayed_work_sync(&workq); */ ++/* flush_delayed_work(&workq); */ /* flush_delayed_work_sync is deprecated */ ++ ++ /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */ ++/* prGlueInfo->u4Flag |= GLUE_FLAG_HALT; */ ++ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); ++ DBGLOG(INIT, TRACE, "waiting for tx_thread stop...\n"); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ DBGLOG(INIT, TRACE, "wait_for_completion_interruptible\n"); ++ ++ /* wait main thread stops */ ++ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); ++ ++ DBGLOG(INIT, TRACE, "mtk_sdiod stopped\n"); ++ ++ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rTxThreadWakeLock); ++ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->rAhbIsrWakeLock); ++ ++ /* prGlueInfo->rHifInfo.main_thread = NULL; */ ++ prGlueInfo->main_thread = NULL; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (prGlueInfo->rBowInfo.fgIsRegistered) ++ glUnregisterAmpc(prGlueInfo); ++#endif ++ ++ /* 4 <3> Remove /proc filesystem. */ ++#ifdef WLAN_INCLUDE_PROC ++ procRemoveProcfs(); ++#endif /* WLAN_INCLUDE_PROC */ ++ ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ kalMetRemoveProcfs(); ++#endif ++ ++ /* Force to do DMA reset */ ++ DBGLOG(INIT, TRACE, "glResetHif\n"); ++ glResetHif(prGlueInfo); ++ ++ /* 4 <4> wlanAdapterStop */ ++ prAdapter = prGlueInfo->prAdapter; ++#if CFG_SUPPORT_AGPS_ASSIST ++ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, 0); ++#endif ++ ++ wlanAdapterStop(prAdapter); ++ DBGLOG(INIT, TRACE, "Number of Stalled Packets = %d\n", prGlueInfo->i4TxPendingFrameNum); ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE; ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) { ++ DBGLOG(INIT, TRACE, "p2pNetUnregister...\n"); ++#if !CFG_SUPPORT_PERSIST_NETDEV ++ p2pNetUnregister(prGlueInfo, FALSE); ++#endif ++ DBGLOG(INIT, INFO, "p2pRemove...\n"); ++ p2pRemove(prGlueInfo); ++ } ++#endif ++ ++ /* 4 <5> Release the Bus */ ++ glBusRelease(prDev); ++ ++ kalHaltUnlock(); ++ wlanDebugUninit(); ++ /* 4 <6> Unregister the card */ ++ wlanNetUnregister(prDev->ieee80211_ptr); ++ ++ /* 4 <7> Destroy the device */ ++ wlanNetDestroy(prDev->ieee80211_ptr); ++ prDev = NULL; ++ ++ DBGLOG(INIT, LOUD, "wlanUnregisterNotifier...\n"); ++ wlanUnregisterNotifier(); ++ ++ DBGLOG(INIT, INFO, "wlanRemove ok\n"); ++} /* end of wlanRemove() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver entry point when the driver is configured as a Linux Module, and ++* is called once at module load time, by the user-level modutils ++* application: insmod or modprobe. ++* ++* \retval 0 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++/* 1 Module Entry Point */ ++static int initWlan(void) ++{ ++ int ret = 0, i; ++#if DBG ++ for (i = 0; i < DBG_MODULE_NUM; i++) ++ aucDebugModule[i] = DBG_CLASS_MASK; /* enable all */ ++#else ++ /* Initial debug level is D1 */ ++ for (i = 0; i < DBG_MODULE_NUM; i++) ++ aucDebugModule[i] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_INFO | DBG_CLASS_STATE; ++#endif /* DBG */ ++ DBGLOG(INIT, INFO, "initWlan\n"); ++ ++ spin_lock_init(&g_p2p_lock); ++ ++ /* memory pre-allocation */ ++ kalInitIOBuffer(); ++ procInitFs(); ++ createWirelessDevice(); ++ if (gprWdev) ++ glP2pCreateWirelessDevice((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy)); ++ ++ ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO); ++ ++ if (ret == -EIO) { ++ kalUninitIOBuffer(); ++ return ret; ++ } ++#if (CFG_CHIP_RESET_SUPPORT) ++ glResetInit(); ++#endif ++ ++ /* register set_dbg_level handler to mtk_wmt_wifi */ ++ register_set_dbg_level_handler(set_dbg_level_handler); ++ ++ /* Set the initial DEBUG CLASS of each module */ ++ return ret; ++} /* end of initWlan() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver exit point when the driver as a Linux Module is removed. Called ++* at module unload time, by the user level modutils application: rmmod. ++* This is our last chance to clean up after ourselves. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++/* 1 Module Leave Point */ ++static VOID exitWlan(void) ++{ ++ DBGLOG(INIT, INFO, "exitWlan\n"); ++ ++ /* unregister set_dbg_level handler to mtk_wmt_wifi */ ++ register_set_dbg_level_handler(NULL); ++ ++#if CFG_CHIP_RESET_SUPPORT ++ glResetUninit(); ++#endif ++ destroyWirelessDevice(); ++ glP2pDestroyWirelessDevice(); ++ ++ glUnregisterBus(wlanRemove); ++ ++ /* free pre-allocated memory */ ++ kalUninitIOBuffer(); ++ ++ DBGLOG(INIT, INFO, "exitWlan\n"); ++ procUninitProcFs(); ++ ++} /* end of exitWlan() */ ++ ++#ifdef MTK_WCN_BUILT_IN_DRIVER ++ ++int mtk_wcn_wlan_gen2_init(void) ++{ ++ return initWlan(); ++} ++EXPORT_SYMBOL(mtk_wcn_wlan_gen2_init); ++ ++void mtk_wcn_wlan_gen2_exit(void) ++{ ++ return exitWlan(); ++} ++EXPORT_SYMBOL(mtk_wcn_wlan_gen2_exit); ++ ++#else ++ ++module_init(initWlan); ++module_exit(exitWlan); ++ ++#endif ++ ++MODULE_AUTHOR(NIC_AUTHOR); ++MODULE_DESCRIPTION(NIC_DESC); ++MODULE_SUPPORTED_DEVICE(NIC_NAME); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +new file mode 100644 +index 000000000000..3a257c9f85c4 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +@@ -0,0 +1,4799 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#3 ++*/ ++ ++/*! \file gl_kal.c ++ \brief GLUE Layer will export the required procedures here for internal driver stack. ++ ++ This file contains all routines which are exported from GLUE Layer to internal ++ driver stack. ++*/ ++ ++/* ++** Log: gl_kal.c ++** ++** 08 20 2012 yuche.tsai ++** NULL ++** Fix possible KE issue. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 05 31 2012 terry.wu ++ * NULL ++ * . ++ * ++ * 03 26 2012 cp.wu ++ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist ++ * invoke put_cred() after get_current_cred() calls. ++ * ++ * 03 07 2012 yuche.tsai ++ * NULL ++ * Fix compile error when WiFi Direct is off. ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 02 20 2012 cp.wu ++ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist ++ * do not need to invoke free() while firmware image file doesn't exist ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 21 2011 cp.wu ++ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing ++ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer ++ * add more checking for such cases ++ * ++ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. ++ * add some tweaking to protect such cases because that net device has become invalid. ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 16 2011 yuche.tsai ++ * NULL ++ * Avoid using work thread. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 23 2011 yuche.tsai ++ * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue ++ * Regulation domain feature check in. ++ * ++ * 08 12 2011 cp.wu ++ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC ++ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 06 13 2011 eddie.chen ++ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni ++ * Add tx rx statistics and netif_rx_ni. ++ * ++ * 04 15 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW short range mode. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated ++ * network type ++ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected ++ * ++ * 04 08 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * correct i4TxPendingFrameNum decreasing. ++ * ++ * 03 23 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * apply multi-queue operation only for linux kernel > 2.6.26 ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability for compatible with linux 2.6.12. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * refix ... ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * correct compiling warning/error. ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * add more robust fault tolerance design when pre-allocation failed. (rarely happen) ++ * ++ * 03 17 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * use pre-allocated buffer for storing enhanced interrupt response as well ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 14 2011 jeffrey.chang ++ * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message ++ * fix kernel build warning message ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 21 2011 cp.wu ++ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain ++ * simplify logic for checking NVRAM existence only once. ++ * ++ * 01 24 2011 cp.wu ++ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving ++ * 1. add an extra counter for tracking pending forward frames. ++ * 2. notify TX service thread as well when there is pending forward frame ++ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module ++ * ++ * 01 19 2011 cp.wu ++ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 ++ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues ++ * due to multiple access ++ * use mutex to protect kalIoctl() for thread safe. ++ * ++ * 11 26 2010 cp.wu ++ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field ++ * checking ++ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used ++ * to indicate user is attached ++ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 11 02 2010 jeffrey.chang ++ * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets ++ * . ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 26 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] ++ * Support NIC capability query command ++ * 1) update NVRAM content template to ver 1.02 ++ * 2) add compile option for querying NIC capability (default: off) ++ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting ++ * 4) correct auto-rate compiler error under linux (treat warning as error) ++ * 5) simplify usage of NVRAM and REG_INFO_T ++ * 6) add version checking between driver and firmware ++ * ++ * 10 25 2010 jeffrey.chang ++ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform ++ * Remove redundant code which cause mismatch of power control release ++ * ++ * 10 25 2010 jeffrey.chang ++ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform ++ * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control ++ * ++ * 10 18 2010 jeffrey.chang ++ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue ++ * refine the scan ioctl to prevent hanging of Android UI ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * if there is NVRAM, then use MAC address on NVRAM as default MAC address. ++ * ++ * 10 06 2010 cp.wu ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * code reorganization to improve isolation between GLUE and CORE layers. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 30 2010 cp.wu ++ * NULL ++ * API added: nicTxPendingPackets(), for simplifying porting layer ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Support second interface indicate when enabling P2P. ++ * ++ * 08 18 2010 yarco.yang ++ * NULL ++ * 1. Fixed HW checksum offload function not work under Linux issue. ++ * 2. Add debug message. ++ * ++ * 08 16 2010 jeffrey.chang ++ * NULL ++ * remove redundant code which cause kernel panic ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * simplify post-handling after TX_DONE interrupt is handled. ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) remove unused spinlocks ++ * 2) enable encyption ioctls ++ * 3) fix scan ioctl which may cause supplicant to hang ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * add new KAL api ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * bug fix: allocate regInfo when disabling firmware download ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * use glue layer api to decrease or increase counter atomically ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * modify tx thread and remove some spinlock ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * use different spin lock for security frame ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * add new spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add spinlock for pending security frame count ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * adjust the timer unit to microsecond ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * timer should return value greater than zero ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add kal api for scanning done ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * modify cmd/data path for new design ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add new kal api ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * for linux driver migration ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 yarco.yang ++ * [WPD00003837][MT6620]Data Path Refine ++ * Merge g_arStaRec[] into adapter->arStaRec[] ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * remove unused files. ++ * ++ * 05 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix private ioctl for rftest ++ * ++ * 05 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * workaround for fixing request_firmware() failure on android 2.1 ++ * ++ * 05 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix kernel panic when debug mode enabled ++ * ++ * 05 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) Modify set mac address code ++ * 2) remove power management macro ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Disable network interface after disassociation ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * fill network type field while doing frame identification. ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * prevent supplicant accessing driver during resume ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) fix firmware download bug ++ * 2) remove query statistics for acelerating firmware download ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 15 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * change firmware name ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * flush pending TX packets while unloading driver ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Set driver own before handling cmd queue ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used ++ * 2) fix ioctl ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler ++ * * * * * * * * * * * * * * * * * * capability ++ * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix spinlock usage ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add spinlock for i4TxPendingFrameNum access ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) add spinlock ++ * * 2) add KAPI for handling association info ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix spinlock usage ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding firmware download KAPI ++ * ++ * 04 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Set MAC address from firmware ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1. free cmdinfo after command is emiited. ++ * 2. for BoW frames, user priority is extracted from sk_buff directly. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * * * are now handled in glue layer ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)deliver the kalOidComplete status to upper layer ++ * (2) fix spin lock ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add timeout check in the kalOidComplete ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * * * 2) add 2 kal API for later integration ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * raising the priority of processing interrupt ++ * ++ * 04 01 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding secondary command queue for improving non-glue code portability ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download kal api ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add Bluetooth-over-Wifi frame header check ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088 ++** fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding ++** \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461 ++** Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL ++** \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088 ++** remove non-used code for code review, add assert check ++** \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461 ++** \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461 ++** Rename KAL function ++** \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461 ++** \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084 ++** rename wlanoid ++** \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084 ++** remove un-used KAL function ++** \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461 ++** Move Query Media Status to GLUE ++** \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461 ++** change awake queue threshold and remove code which mark #if 0 ++** \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084 ++** add KAL function to setting pattern search function enable/ disable ++** \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461 ++** Add comment ++** \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461 ++** Add update MAC Address for Linux ++** \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084 ++** update function for initial value access ++** \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088 ++** use kal update associate request at linux ++** \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385 ++** 1. add Query Registry Mac address function. ++** \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084 ++** modify KAL set network address/ checksum offload part ++** \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461 ++** Add debug option - Packet Order for Linux ++** \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084 ++** modify the argument of kalQueryPacketInfo() ++** \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425 ++** 1. Revise csum offload ++** \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425 ++** 1. Fix bugs ++** ++** \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461 ++** Fix Windows RX multiple packet retain problem ++** \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088 ++** CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit ++** \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425 ++** 1. Modify for CSUM offloading with Tx Fragment ++** \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461 ++** Add Tx Fragmentation Support ++** \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088 ++** add the WPS code, indicate the mgmt frame to upper layer ++** \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425 ++** 1. Update wlanQueryInformation ++** \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425 ++** 1. Refine multicast list code ++** 2. Refine TCP/IP csum offload code ++** ++** Revision 1.5 2007/07/17 13:01:18 MTK01088 ++** add associate req and rsp function ++** ++** Revision 1.4 2007/07/13 05:19:19 MTK01084 ++** provide timer set functions ++** ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include "gl_os.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#if defined(CONFIG_MTK_TC1_FEATURE) ++#include ++#endif ++#if CFG_SUPPORT_AGPS_ASSIST ++#include ++#endif ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++#include ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++#if DBG ++int allocatedMemSize = 0; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++/* #define MTK_DMA_BUF_MEMCPY_SUP */ ++static PVOID pvIoBuffer; ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++static PVOID pvIoPhyBuf; ++static PVOID pvDmaBuffer; ++static PVOID pvDmaPhyBuf; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++static UINT_32 pvIoBufferSize; ++static UINT_32 pvIoBufferUsage; ++static struct KAL_HALT_CTRL_T rHaltCtrl = { ++ .lock = __SEMAPHORE_INITIALIZER(rHaltCtrl.lock, 1), ++ .owner = NULL, ++ .fgHalt = TRUE, ++ .fgHeldByKalIoctl = FALSE, ++ .u4HoldStart = 0, ++}; ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT ++typedef enum _ENUM_WMTHWVER_TYPE_T { ++ WMTHWVER_MT6620_E1 = 0x0, ++ WMTHWVER_MT6620_E2 = 0x1, ++ WMTHWVER_MT6620_E3 = 0x2, ++ WMTHWVER_MT6620_E4 = 0x3, ++ WMTHWVER_MT6620_E5 = 0x4, ++ WMTHWVER_MT6620_E6 = 0x5, ++ WMTHWVER_MT6620_MAX, ++ WMTHWVER_INVALID = 0xff ++} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &(prGlueInfo->rAhbIsrWakeLock), (HZ / 10)); /* 100ms */ ++} ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ ++static struct file *filp; ++static uid_t orgfsuid; ++static gid_t orgfsgid; ++static mm_segment_t orgfs; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* open firmware image in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalFirmwareOpen(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_8 aucFilePath[50]; ++ ++ /* FIX ME: since we don't have hotplug script in the filesystem ++ * , so the request_firmware() KAPI can not work properly ++ */ ++ ++ /* save uid and gid used for filesystem access. ++ * set user and group to 0(root) */ ++ struct cred *cred = (struct cred *)get_current_cred(); ++ ++ orgfsuid = cred->fsuid.val; ++ orgfsgid = cred->fsgid.val; ++ cred->fsuid.val = cred->fsgid.val = 0; ++ ++ ASSERT(prGlueInfo); ++ ++ orgfs = get_fs(); ++ set_fs(get_ds()); ++ ++ /* open the fw file */ ++#if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT ++ switch (mtk_wcn_wmt_hwver_get()) { ++ case WMTHWVER_MT6620_E1: ++ case WMTHWVER_MT6620_E2: ++ case WMTHWVER_MT6620_E3: ++ case WMTHWVER_MT6620_E4: ++ case WMTHWVER_MT6620_E5: ++ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); ++ break; ++ ++ case WMTHWVER_MT6620_E6: ++ default: ++ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME "_E6", O_RDONLY, 0); ++ break; ++ } ++#elif defined(MT6628) ++/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6628", O_RDONLY, 0); */ ++/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6582", O_RDONLY, 0); */ ++#if 0 /* new wifi ram code mechanism, waiting firmware ready, then we can enable these code */ ++ kalMemZero(aucFilePath, sizeof(aucFilePath)); ++ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_AD", sizeof("/etc/firmware/" CFG_FW_FILENAME "_AD")); ++ filp = filp_open(aucFilePath, O_RDONLY, 0); ++ if (!IS_ERR(filp)) ++ goto open_success; ++#endif ++ kalMemZero(aucFilePath, sizeof(aucFilePath)); ++ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_", strlen("/etc/firmware/" CFG_FW_FILENAME "_")); ++ glGetChipInfo(prGlueInfo, &aucFilePath[strlen("/etc/firmware/" CFG_FW_FILENAME "_")]); ++ ++ DBGLOG(INIT, INFO, "open file: %s\n", aucFilePath); ++ ++ filp = filp_open(aucFilePath, O_RDONLY, 0); ++#else ++ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); ++#endif ++ if (IS_ERR(filp)) { ++ DBGLOG(INIT, ERROR, "Open FW image: %s failed\n", CFG_FW_FILENAME); ++ goto error_open; ++ } ++#if 0 ++open_success: ++#endif ++ DBGLOG(INIT, TRACE, "Open FW image: %s done\n", CFG_FW_FILENAME); ++ return WLAN_STATUS_SUCCESS; ++ ++error_open: ++ /* restore */ ++ set_fs(orgfs); ++ cred->fsuid.val = orgfsuid; ++ cred->fsgid.val = orgfsgid; ++ put_cred(cred); ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* release firmware image in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalFirmwareClose(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ if ((filp != NULL) && !IS_ERR(filp)) { ++ /* close firmware file */ ++ filp_close(filp, NULL); ++ ++ /* restore */ ++ set_fs(orgfs); ++ { ++ struct cred *cred = (struct cred *)get_current_cred(); ++ ++ cred->fsuid.val = orgfsuid; ++ cred->fsgid.val = orgfsgid; ++ put_cred(cred); ++ } ++ filp = NULL; ++ } ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* load firmware image in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalFirmwareLoad(IN P_GLUE_INFO_T prGlueInfo, OUT PVOID prBuf, IN UINT_32 u4Offset, OUT PUINT_32 pu4Size) ++{ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4Size); ++ ASSERT(prBuf); ++ ++ /* l = filp->f_path.dentry->d_inode->i_size; */ ++#if 0 ++ /* the object must have a read method */ ++ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) { ++ goto error_read; ++ } else { ++ filp->f_pos = u4Offset; ++ *pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos); ++ } ++#else ++ /* the object must have a read method */ ++ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) ) { ++ goto error_read; ++ } else { ++ filp->f_pos = u4Offset; ++ *pu4Size = vfs_read(filp, prBuf, *pu4Size, &filp->f_pos); ++ } ++#endif ++ ++ return WLAN_STATUS_SUCCESS; ++ ++error_read: ++ return WLAN_STATUS_FAILURE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to ++* query firmware image size in kernel space ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++WLAN_STATUS kalFirmwareSize(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_32 pu4Size) ++{ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4Size); ++ ++ //*pu4Size = filp->f_path.dentry->d_inode->i_size; ++ *pu4Size = filp->f_op->llseek(filp, 0, 2); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to load firmware image ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image ++* \param pu4FileLength File length and memory mapped length as well ++ ++* \retval Map File Handle, used for unammping ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) ++{ ++ UINT_32 u4FwSize = 0; ++ PVOID prFwBuffer = NULL; ++ ++ DEBUGFUNC("kalFirmwareImageMapping"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ppvMapFileBuf); ++ ASSERT(pu4FileLength); ++ ++ do { ++ /* <1> Open firmware */ ++ if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) { ++ DBGLOG(INIT, TRACE, "kalFirmwareOpen fail!\n"); ++ break; ++ } ++ ++ /* <2> Query firmare size */ ++ kalFirmwareSize(prGlueInfo, &u4FwSize); ++ printk(KERN_ERR "%s firmware size %d\n", __FUNCTION__, u4FwSize); ++ /* <3> Use vmalloc for allocating large memory trunk */ ++ prFwBuffer = vmalloc(ALIGN_4(u4FwSize)); ++ /* <4> Load image binary into buffer */ ++ if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) { ++ vfree(prFwBuffer); ++ kalFirmwareClose(prGlueInfo); ++ DBGLOG(INIT, TRACE, "kalFirmwareLoad fail!\n"); ++ break; ++ } ++ /* <5> write back info */ ++ *pu4FileLength = u4FwSize; ++ *ppvMapFileBuf = prFwBuffer; ++ ++ return prFwBuffer; ++ ++ } while (FALSE); ++ ++ return NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to unload firmware image mapped memory ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param pvFwHandle Pointer to mapping handle ++* \param pvMapFileBuf Pointer to memory-mapped firmware image ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) ++{ ++ DEBUGFUNC("kalFirmwareImageUnmapping"); ++ ++ ASSERT(prGlueInfo); ++ ++ /* pvMapFileBuf might be NULL when file doesn't exist */ ++ if (pvMapFileBuf) ++ vfree(pvMapFileBuf); ++ ++ kalFirmwareClose(prGlueInfo); ++} ++ ++#endif ++ ++#if 0 ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to load firmware image ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image ++* \param pu4FileLength File length and memory mapped length as well ++ ++* \retval Map File Handle, used for unammping ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) ++{ ++ INT_32 i4Ret = 0; ++ ++ DEBUGFUNC("kalFirmwareImageMapping"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ppvMapFileBuf); ++ ASSERT(pu4FileLength); ++ ++ do { ++ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; ++ ++ prGlueInfo->prFw = NULL; ++ ++ /* <1> Open firmware */ ++ i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, prHifInfo->Dev); ++ ++ if (i4Ret) { ++ DBGLOG(INIT, TRACE, "fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret); ++ break; ++ } ++ *pu4FileLength = prGlueInfo->prFw->size; ++ *ppvMapFileBuf = prGlueInfo->prFw->data; ++ return prGlueInfo->prFw->data; ++ ++ } while (FALSE); ++ ++ return NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to unload firmware image mapped memory ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* \param pvFwHandle Pointer to mapping handle ++* \param pvMapFileBuf Pointer to memory-mapped firmware image ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) ++{ ++ DEBUGFUNC("kalFirmwareImageUnmapping"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pvMapFileBuf); ++ ++ release_firmware(prGlueInfo->prFw); ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to acquire ++* OS SPIN_LOCK. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[out] pu4Flags Pointer of a variable for saving IRQ flags ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags) ++{ ++ unsigned long u4Flags = 0; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4Flags); ++ ++ if (rLockCategory < SPIN_LOCK_NUM) { ++ ++#if CFG_USE_SPIN_LOCK_BOTTOM_HALF ++ spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]); ++#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); ++#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ ++ *pu4Flags = u4Flags; ++/* DBGLOG(INIT, TRACE, ("A+%d\n", rLockCategory)); */ ++ } ++ ++} /* end of kalAcquireSpinLock() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to release ++* OS SPIN_LOCK. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[in] u4Flags Saved IRQ flags ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (rLockCategory < SPIN_LOCK_NUM) { ++ /* DBGLOG(INIT, TRACE, ("A-%d %d %d\n", rLockCategory, u4MemAllocCnt, u4MemFreeCnt)); */ ++#if CFG_USE_SPIN_LOCK_BOTTOM_HALF ++ spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]); ++#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); ++#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ ++ } ++ ++} /* end of kalReleaseSpinLock() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is provided by GLUE Layer for internal driver stack to update ++* current MAC address. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pucMacAddr Pointer of current MAC address ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr) ++{ ++ ASSERT(prGlueInfo); ++ ASSERT(pucMacAddr); ++ ++ if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr)) ++ memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN); ++ ++} ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To query the packet information for offload related parameters. ++* ++* \param[in] pvPacket Pointer to the packet descriptor. ++* \param[in] pucFlag Points to the offload related parameter. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag) ++{ ++ struct sk_buff *skb = (struct sk_buff *)pvPacket; ++ UINT_8 ucFlag = 0; ++ ++ ASSERT(pvPacket); ++ ASSERT(pucFlag); ++ ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++#if DBG ++ /* Kevin: do double check, we can remove this part in Normal Driver. ++ * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so ++ * we'll process IP packet only. ++ */ ++ if (skb->protocol != htons(ETH_P_IP)) { ++ /* printk("Wrong skb->protocol( = %08x) for TX Checksum Offload.\n", skb->protocol); */ ++ } else ++#endif ++ ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN); ++ } ++ ++ *pucFlag = ucFlag; ++ ++} /* kalQueryChksumOffloadParam */ ++ ++/* 4 2007/10/8, mikewu, this is rewritten by Mike */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To update the checksum offload status to the packet to be indicated to OS. ++* ++* \param[in] pvPacket Pointer to the packet descriptor. ++* \param[in] pucFlag Points to the offload related parameter. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T aeCSUM[]) ++{ ++ struct sk_buff *skb = (struct sk_buff *)pvPacket; ++ ++ ASSERT(pvPacket); ++ ++ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS) && ++ ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) { ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ } else { ++ skb->ip_summed = CHECKSUM_NONE; ++#if DBG ++ if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE) ++ DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n"); ++ else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) ++ DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n"); ++ else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) ++ DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n"); ++ else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) ++ DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n"); ++ else ++ /* Do nothing */ ++#endif ++ } ++ ++} /* kalUpdateRxCSUMOffloadParam */ ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called to free packet allocated from kalPacketAlloc. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of the packet descriptor ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) ++{ ++ dev_kfree_skb((struct sk_buff *)pvPacket); ++ if (prGlueInfo) ++ prGlueInfo->u8SkbFreed++; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Only handles driver own creating packet (coalescing buffer). ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* \param u4Size Pointer of Packet Handle ++* \param ppucData Status Code for OS upper layer ++* ++* \return NULL: Failed to allocate skb, Not NULL get skb ++*/ ++/*----------------------------------------------------------------------------*/ ++PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData) ++{ ++ struct sk_buff *prSkb = dev_alloc_skb(u4Size); ++ ++ if (prSkb) ++ *ppucData = (PUINT_8) (prSkb->data); ++#if DBG ++ { ++ PUINT_32 pu4Head = (PUINT_32) &prSkb->cb[0]; ++ *pu4Head = (UINT_32) prSkb->head; ++ DBGLOG(RX, TRACE, "prSkb->head = %#x, prSkb->cb = %#x\n", (UINT_32) prSkb->head, *pu4Head); ++ } ++#endif ++ return (PVOID) prSkb; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Process the received packet for indicating to OS. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure. ++* \param[in] pvPacket Pointer of the packet descriptor ++* \param[in] pucPacketStart The starting address of the buffer of Rx packet. ++* \param[in] u4PacketLen The packet length. ++* \param[in] pfgIsRetain Is the packet to be retained. ++* \param[in] aerCSUM The result of TCP/ IP checksum offload. ++* ++* \retval WLAN_STATUS_SUCCESS. ++* \retval WLAN_STATUS_FAILURE. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS ++kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, ++ /* IN PBOOLEAN pfgIsRetain, */ ++ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[]) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ struct sk_buff *skb = (struct sk_buff *)pvPacket; ++ ++ skb->data = pucPacketStart; ++ skb_reset_tail_pointer(skb); /* reset tail pointer first, for 64bit kernel,we should call linux kernel API */ ++ skb_trim(skb, 0); /* only if skb->len > len, then skb_trim has effect */ ++ skb_put(skb, u4PacketLen); /* shift tail and skb->len to correct value */ ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ kalUpdateRxCSUMOffloadParam(skb, aerCSUM); ++#endif ++ ++ return rStatus; ++} ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Do HIF loopback test. ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++unsigned int testmode = 0; ++unsigned int testlen = 64; ++ ++void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo) ++{ ++#define HIF_LOOPBK_AUTO_TEST_LEN 1600 ++/* GL_HIF_INFO_T *HifInfo; */ ++ static unsigned int txcnt; ++ struct sk_buff *MsduInfo; ++ UINT_8 *Pkt; ++ UINT_32 RegVal; ++ UINT_32 PktLen = 16; ++ ++ /* Init */ ++ if (testmode != 0) { ++ PktLen = kalRandomNumber() % 1520; ++ if (PktLen < 64) ++ PktLen = 64; ++ } else { ++ PktLen = testlen++; ++ if (PktLen > 1520) { ++ testmode = 1; ++ PktLen = 64; ++ } ++ } ++ ++/* PktLen = 100; */ ++ DBGLOG(INIT, INFO, "kalDevLoopbkAuto> Send a packet to HIF (len = %d) (total = %d)...\n", PktLen, ++txcnt); ++/* HifInfo = &GlueInfo->rHifInfo; */ ++ ++ /* Allocate a MSDU_INFO_T */ ++ MsduInfo = kalPacketAlloc(GlueInfo, HIF_LOOPBK_AUTO_TEST_LEN, &Pkt); ++ if (MsduInfo == NULL) { ++ DBGLOG(INIT, WARN, "No PKT_INFO_T for sending loopback packet!\n"); ++ return; ++ } ++ ++ /* Init the packet */ ++ MsduInfo->dev = GlueInfo->prDevHandler; ++ if (MsduInfo->dev == NULL) { ++ DBGLOG(INIT, WARN, "MsduInfo->dev == NULL!!\n"); ++ kalPacketFree(GlueInfo, MsduInfo); ++ return; ++ } ++ ++ MsduInfo->len = PktLen; ++ kalMemSet(MsduInfo->data, 0xff, 6); ++ kalMemSet(MsduInfo->data + 6, 0x5a, PktLen - 6); ++ ++ /* Simulate OS to send the packet */ ++ wlanHardStartXmit(MsduInfo, MsduInfo->dev); ++ ++#if 0 ++ PktLen += 4; ++ if (PktLen >= 1600) ++ PktLen = 16; ++#endif ++ ++ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ ++/* HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(1000); */ ++/* add_timer(&(HifInfo->HifTmrLoopbkFn)); */ ++} ++ ++int kalDevLoopbkThread(IN void *data) ++{ ++ struct net_device *dev = data; ++ P_GLUE_INFO_T GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); ++ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; ++ int ret; ++ static int test; ++ ++ while (TRUE) { ++ ret = wait_event_interruptible(HifInfo->HifWaitq, (HifInfo->HifLoopbkFlg != 0)); ++ ++ if (HifInfo->HifLoopbkFlg == 0xFFFFFFFF) ++ break; ++ ++ while (TRUE) { ++ /* if ((HifInfo->HifLoopbkFlg & 0x01) == 0) */ ++ if (GlueInfo->i4TxPendingFrameNum < 64) { ++ DBGLOG(INIT, INFO, "GlueInfo->i4TxPendingFrameNum = %d\n", ++ GlueInfo->i4TxPendingFrameNum); ++ kalDevLoopbkAuto(GlueInfo); ++ ++ if (testmode == 0) ++ kalMsleep(3000); ++ } else ++ kalMsleep(1); ++ } ++ } ++} ++ ++void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) ++{ ++ static unsigned int rxcnt; ++ UINT_32 i; ++ UINT_8 *Buf = prSwRfb->pucRecvBuff + sizeof(HIF_TX_HEADER_T); ++ P_HIF_RX_HEADER_T prHifRxHdr = prSwRfb->prHifRxHdr; ++ UINT_32 len = prHifRxHdr->u2PacketLen - sizeof(HIF_TX_HEADER_T); ++ ++ if (len > 1600) { ++ while (1) ++ DBGLOG(INIT, ERROR, "HIF> Loopback len > 1600!!! error!!!\n"); ++ } ++ ++ for (i = 0; i < 6; i++) { ++ if (Buf[i] != 0xff) { ++ while (1) { ++ DBGLOG(INIT, ERROR, "HIF> Loopbk dst addr error (len = %d)!\n", len); ++ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); ++ } ++ } ++ } ++ ++ for (i = 6; i < len; i++) { ++ if (Buf[i] != 0x5a) { ++ while (1) { ++ DBGLOG(INIT, ERROR, "HIF> Loopbk error (len = %d)!\n", len); ++ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); ++ } ++ } ++ } ++ ++ DBGLOG(INIT, INFO, "HIF> Loopbk OK (len = %d) (total = %d)!\n", len, ++rxcnt); ++} ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate an array of received packets is available for higher ++* level protocol uses. ++* ++* \param[in] prGlueInfo Pointer to the Adapter structure. ++* \param[in] apvPkts The packet array to be indicated ++* \param[in] ucPktNum The number of packets to be indicated ++* ++* \retval TRUE Success. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum) ++{ ++ UINT_8 ucIdx = 0; ++ struct net_device *prNetDev = prGlueInfo->prDevHandler; ++ struct sk_buff *prSkb = NULL; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(apvPkts); ++ ++#if CFG_BOW_TEST ++ UINT_32 i; ++#endif ++ ++ for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++) { ++ prSkb = apvPkts[ucIdx]; ++#if DBG ++ do { ++ PUINT_8 pu4Head = (PUINT_8) &prSkb->cb[0]; ++ UINT_32 u4HeadValue = 0; ++ ++ kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue)); ++ DBGLOG(RX, TRACE, "prSkb->head = %p, prSkb->cb = 0x%x\n", pu4Head, u4HeadValue); ++ } while (0); ++#endif ++ ++ if (GLUE_GET_PKT_IS_P2P(prSkb)) { ++ /* P2P */ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ prNetDev = kalP2PGetDevHdlr(prGlueInfo); ++ /* prNetDev->stats.rx_bytes += prSkb->len; */ ++ /* prNetDev->stats.rx_packets++; */ ++ prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len; ++ prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++; ++ ++#else ++ prNetDev = prGlueInfo->prDevHandler; ++#endif ++ } else if (GLUE_GET_PKT_IS_PAL(prSkb)) { ++ /* BOW */ ++#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH ++ if (prGlueInfo->rBowInfo.fgIsNetRegistered) ++ prNetDev = prGlueInfo->rBowInfo.prDevHandler; ++#else ++ prNetDev = prGlueInfo->prDevHandler; ++#endif ++ } else { ++ /* AIS */ ++ prNetDev = prGlueInfo->prDevHandler; ++ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; ++ prGlueInfo->rNetDevStats.rx_packets++; ++ ++ } ++ ++ /* check if the "unicast" packet is from us */ ++ if (kalMemCmp(prSkb->data, prSkb->data + 6, 6) == 0) { ++ /* we will filter broadcast/multicast packet sent from us in hardware */ ++ /* source address = destination address ? */ ++ DBGLOG(RX, EVENT, ++ "kalRxIndicatePkts got from us!!! Drop it! ([ %pM ] len %d)\n", ++ prSkb->data, prSkb->len); ++ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); ++ continue; ++ } ++#if (CFG_SUPPORT_TDLS == 1) ++ if (TdlsexRxFrameDrop(prGlueInfo, prSkb->data) == TRUE) { ++ /* drop the received TDLS action frame */ ++ DBGLOG(TDLS, WARN, ++ " %s: drop a received packet from %pM %u\n", ++ __func__, prSkb->data, ++ (UINT32) ((P_ADAPTER_T) (prGlueInfo->prAdapter))->rRxCtrl.rFreeSwRfbList.u4NumElem); ++ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); ++ continue; ++ } ++ ++ /* ++ get a TDLS request/response/confirm, we need to parse the HT IE ++ because older supplicant does not pass HT IE to us ++ */ ++ TdlsexRxFrameHandle(prGlueInfo, prSkb->data, prSkb->len); ++#endif /* CFG_SUPPORT_TDLS */ ++ ++ STATS_RX_PKT_INFO_DISPLAY(prSkb->data); ++ ++ //prNetDev->last_rx = jiffies; ++ prSkb->protocol = eth_type_trans(prSkb, prNetDev); ++ prSkb->dev = prNetDev; ++ /* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */ ++ DBGLOG(RX, TRACE, "kalRxIndicatePkts len = %d\n", prSkb->len); ++ ++#if CFG_BOW_TEST ++ DBGLOG(BOW, TRACE, "Rx sk_buff->len: %d\n", prSkb->len); ++ DBGLOG(BOW, TRACE, "Rx sk_buff->data_len: %d\n", prSkb->data_len); ++ DBGLOG(BOW, TRACE, "Rx sk_buff->data:\n"); ++ ++ for (i = 0; i < prSkb->len; i++) { ++ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); ++ ++ if ((i + 1) % 16 == 0) ++ DBGLOG(BOW, TRACE, "\n"); ++ } ++ ++ DBGLOG(BOW, TRACE, "\n"); ++#endif ++ ++ if (!in_interrupt()) ++ netif_rx_ni(prSkb); /* only in non-interrupt context */ ++ else ++ netif_rx(prSkb); ++ ++ wlanReturnPacket(prGlueInfo->prAdapter, NULL); ++ } ++ ++ kalPerMonStart(prGlueInfo); ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Called by driver to indicate event to upper layer, for example, the wpa ++* supplicant or wireless tools. ++* ++* \param[in] pvAdapter Pointer to the adapter descriptor. ++* \param[in] eStatus Indicated status. ++* \param[in] pvBuf Indicated message buffer. ++* \param[in] u4BufLen Indicated message buffer size. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 ScanCnt = 0, ScanDoneFailCnt = 0; ++VOID ++kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen) ++{ ++ UINT_32 bufLen; ++ P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf; ++ P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus; ++ P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1); ++ PARAM_MAC_ADDRESS arBssid; ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ PARAM_SSID_T ssid; ++ struct ieee80211_channel *prChannel = NULL; ++ struct cfg80211_bss *bss; ++ UINT_8 ucChannelNum; ++ P_BSS_DESC_T prBssDesc = NULL; ++ struct cfg80211_scan_info info = { ++ .aborted = false, ++ }; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ kalMemZero(arBssid, MAC_ADDR_LEN); ++ ++ ASSERT(prGlueInfo); ++ ++ switch (eStatus) { ++ case WLAN_STATUS_ROAM_OUT_FIND_BEST: ++ case WLAN_STATUS_MEDIA_CONNECT: ++ ++ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED; ++ ++ /* indicate assoc event */ ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &bufLen); ++ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen); ++ ++ /* switch netif on */ ++ netif_carrier_on(prGlueInfo->prDevHandler); ++ ++ do { ++ /* print message on console */ ++ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen); ++ ++ ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ? ++ (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen] = '\0'; ++ DBGLOG(AIS, INFO, " %s netif_carrier_on [ssid:%s %pM ]\n", ++ prGlueInfo->prDevHandler->name, ssid.aucSsid, arBssid); ++ } while (0); ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ struct cfg80211_bss *bss_others = NULL; ++ UINT_8 ucLoopCnt = 15; /* only loop 15 times to avoid dead loop */ ++ ++ /* retrieve channel */ ++ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, ++ NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, ++ NL80211_BAND_5GHZ)); ++ } ++ ++ /* ensure BSS exists */ ++ bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid, ++ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); ++ ++ if (bss == NULL) { ++ /* create BSS on-the-fly */ ++ prBssDesc = ++ wlanGetTargetBssDescByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ if (prBssDesc != NULL) { ++ bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo), prChannel, ++ CFG80211_BSS_FTYPE_PRESP, ++ arBssid, 0, /* TSF */ ++ WLAN_CAPABILITY_ESS, ++ prBssDesc->u2BeaconInterval, /* beacon interval */ ++ prBssDesc->aucIEBuf, /* IE */ ++ prBssDesc->u2IELength, /* IE Length */ ++ RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */ ++ GFP_KERNEL); ++ } ++ } ++ /* remove all bsses that before and only channel different with the current connected one ++ if without this patch, UI will show channel A is connected even if AP has change channel ++ from A to B */ ++ while (ucLoopCnt--) { ++ bss_others = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), NULL, arBssid, ++ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); ++ if (bss && bss_others && bss_others != bss) { ++ DBGLOG(SCN, INFO, "remove BSSes that only channel different\n"); ++ cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss_others); ++ } else ++ break; ++ } ++ ++ /* CFG80211 Indication */ ++ if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) { ++ /*cfg80211_roamed_bss(prGlueInfo->prDevHandler, ++ bss, ++ prGlueInfo->aucReqIe, ++ prGlueInfo->u4ReqIeLength, ++ prGlueInfo->aucRspIe, prGlueInfo->u4RspIeLength, GFP_KERNEL); ++ */ ++ struct cfg80211_roam_info roam_info = { ++ .bss = bss, ++ .req_ie = prGlueInfo->aucReqIe, ++ .req_ie_len = prGlueInfo->u4ReqIeLength, ++ .resp_ie = prGlueInfo->aucRspIe, ++ .resp_ie_len = prGlueInfo->u4RspIeLength ++ }; ++ cfg80211_roamed(prGlueInfo->prDevHandler, ++ &roam_info, ++ GFP_KERNEL); ++ } else { ++ /* to support user space roaming, cfg80211 will change the sme_state to connecting ++ before reassociate */ ++ cfg80211_connect_result(prGlueInfo->prDevHandler, ++ arBssid, ++ prGlueInfo->aucReqIe, ++ prGlueInfo->u4ReqIeLength, ++ prGlueInfo->aucRspIe, ++ prGlueInfo->u4RspIeLength, WLAN_STATUS_SUCCESS, GFP_KERNEL); ++ } ++ } ++ ++ break; ++ ++ case WLAN_STATUS_MEDIA_DISCONNECT: ++ case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY: ++ /* indicate disassoc event */ ++ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0); ++ /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first, ++ after associated success, at joinComplete(), do netif_carier_on, ++ but for unknown reason, the supplicant 1x pkt will not called the driver ++ hardStartXmit, for template workaround these bugs, add this compiling flag ++ */ ++ /* switch netif off */ ++ ++ DBGLOG(AIS, INFO, "[wifi] %s netif_carrier_off\n", ++ prGlueInfo->prDevHandler->name); ++ ++ netif_carrier_off(prGlueInfo->prDevHandler); ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ P_WIFI_VAR_T prWifiVar = &prGlueInfo->prAdapter->rWifiVar; ++ UINT_16 u2DeauthReason = prWifiVar->arBssInfo[NETWORK_TYPE_AIS_INDEX].u2DeauthReason; ++ /* CFG80211 Indication */ ++ DBGLOG(AIS, INFO, "[wifi] %s cfg80211_disconnected\n", prGlueInfo->prDevHandler->name); ++ cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, false, GFP_KERNEL); ++ } ++ ++ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; ++ ++ break; ++ ++ case WLAN_STATUS_SCAN_COMPLETE: ++ /* indicate scan complete event */ ++ wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0); ++ ++ /* 1. reset first for newly incoming request */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueInfo->prScanRequest; ++ prGlueInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ /* 2. then CFG80211 Indication */ ++ DBGLOG(SCN, TRACE, "[ais] scan complete %p %d %d\n", prScanRequest, ScanCnt, ScanDoneFailCnt); ++ ++ if (prScanRequest != NULL) ++ cfg80211_scan_done(prScanRequest, &info); ++ break; ++ case WLAN_STATUS_CONNECT_INDICATION: ++ /* indicate AIS Jion fail event ++ if (prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) */ ++ cfg80211_connect_result(prGlueInfo->prDevHandler, ++ prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc->aucBSSID, ++ prGlueInfo->aucReqIe, ++ prGlueInfo->u4ReqIeLength, ++ prGlueInfo->aucRspIe, ++ prGlueInfo->u4RspIeLength, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); ++ break; ++ ++#if 0 ++ case WLAN_STATUS_MSDU_OK: ++ if (netif_running(prGlueInfo->prDevHandler)) ++ netif_wake_queue(prGlueInfo->prDevHandler); ++ break; ++#endif ++ ++ case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION: ++ if (pStatus) { ++ switch (pStatus->eStatusType) { ++ case ENUM_STATUS_TYPE_AUTHENTICATION: ++ /* ++ printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [ %pM ] F:%lx\n", ++ pAuth->Request[0].Length, ++ pAuth->Request[0].Bssid, ++ pAuth->Request[0].Flags); ++ */ ++ /* indicate (UC/GC) MIC ERROR event only */ ++ if ((pAuth->arRequest[0].u4Flags == ++ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) || ++ (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR)) { ++ cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL, ++ (pAuth->arRequest[0].u4Flags == ++ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ? ++ NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP, ++ 0, NULL, GFP_KERNEL); ++ wext_indicate_wext_event(prGlueInfo, IWEVMICHAELMICFAILURE, ++ (unsigned char *)&pAuth->arRequest[0], ++ pAuth->arRequest[0].u4Length); ++ } ++ break; ++ ++ case ENUM_STATUS_TYPE_CANDIDATE_LIST: ++ /* ++ printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n", ++ pPmkid->u2Version, ++ pPmkid->u4NumCandidates); ++ if (pPmkid->u4NumCandidates > 0) { ++ printk(KERN_NOTICE "candidate[ %pM ] preAuth Flag:%lx\n", ++ pPmkid->arCandidateList[0].rBSSID, ++ pPmkid->arCandidateList[0].fgFlags); ++ } ++ */ ++ { ++ UINT_32 i = 0; ++ /*struct net_device *prDev = prGlueInfo->prDevHandler; */ ++ P_PARAM_PMKID_CANDIDATE_T prCand = NULL; ++ /* indicate pmk candidate via cfg80211 to supplicant, ++ the second parameter is 1000 for ++ cfg80211_pmksa_candidate_notify, because wpa_supplicant defined it. */ ++ for (i = 0; i < pPmkid->u4NumCandidates; i++) { ++ prCand = &pPmkid->arCandidateList[i]; ++ cfg80211_pmksa_candidate_notify(prGlueInfo->prDevHandler, 1000, ++ prCand->arBSSID, prCand->u4Flags, ++ GFP_KERNEL); ++ ++ wext_indicate_wext_event(prGlueInfo, ++ IWEVPMKIDCAND, ++ (unsigned char *)prCand, ++ pPmkid->u4NumCandidates); ++ } ++ } ++ break; ++ ++ default: ++ /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */ ++ /* ++ printk(KERN_NOTICE "unknown media specific indication type:%x\n", ++ pStatus->StatusType); ++ */ ++ break; ++ } ++ } else { ++ /* ++ printk(KERN_WARNING "media specific indication buffer NULL\n"); ++ */ ++ } ++ break; ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ case WLAN_STATUS_BWCS_UPDATE: ++ { ++ wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T)); ++ } ++ ++ break; ++ ++#endif ++ ++ default: ++ /* ++ printk(KERN_WARNING "unknown indication:%lx\n", eStatus); ++ */ ++ break; ++ } ++} /* kalIndicateStatusAndComplete */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to update the (re)association request ++* information to the structure used to query and set ++* OID_802_11_ASSOCIATION_INFORMATION. ++* ++* \param[in] prGlueInfo Pointer to the Glue structure. ++* \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association ++* Request frame from the AP. ++* \param[in] u4FrameBodyLen The length of the frame body of the last ++* (Re)Association Request frame. ++* \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame. ++* ++* \return (none) ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) ++{ ++ PUINT_8 cp; ++ ++ ASSERT(prGlueInfo); ++ ++ /* reset */ ++ prGlueInfo->u4ReqIeLength = 0; ++ ++ if (fgReassocRequest) { ++ if (u4FrameBodyLen < 15) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } else { ++ if (u4FrameBodyLen < 9) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } ++ ++ cp = pucFrameBody; ++ ++ if (fgReassocRequest) { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ /* Current AP address 6 */ ++ cp += 10; ++ u4FrameBodyLen -= 10; ++ } else { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ cp += 4; ++ u4FrameBodyLen -= 4; ++ } ++ ++ wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen); ++ ++ if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) { ++ prGlueInfo->u4ReqIeLength = u4FrameBodyLen; ++ kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This routine is called to update the (re)association ++* response information to the structure used to reply with ++* cfg80211_connect_result ++* ++* @param prGlueInfo Pointer to adapter descriptor ++* @param pucFrameBody Pointer to the frame body of the last (Re)Association ++* Response frame from the AP ++* @param u4FrameBodyLen The length of the frame body of the last ++* (Re)Association Response frame ++* ++* @return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen) ++{ ++ UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */ ++ UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset; ++ ++ ASSERT(prGlueInfo); ++ ++ /* reset */ ++ prGlueInfo->u4RspIeLength = 0; ++ ++ if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) { ++ prGlueInfo->u4RspIeLength = u4IELength; ++ kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength); ++ } ++ ++} /* kalUpdateReAssocRspInfo */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Notify OS with SendComplete event of the specific packet. Linux should ++* free packets here. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* \param[in] status Status Code for OS upper layer ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) ++{ ++ ++ struct net_device *prDev = NULL; ++ struct sk_buff *prSkb = NULL; ++ UINT_16 u2QueueIdx = 0; ++ UINT_8 ucNetworkType = 0; ++ BOOLEAN fgIsValidDevice = TRUE; ++ ++ ASSERT(pvPacket); ++ ASSERT(prGlueInfo->i4TxPendingFrameNum); ++ ++ prSkb = (struct sk_buff *)pvPacket; ++ u2QueueIdx = skb_get_queue_mapping(prSkb); ++ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); ++ ++ if (GLUE_GET_PKT_IS_PAL(prSkb)) { ++ ucNetworkType = NETWORK_TYPE_BOW_INDEX; ++ } else if (GLUE_GET_PKT_IS_P2P(prSkb)) { ++ ucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /* in case packet was sent after P2P device is unregistered */ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) ++ fgIsValidDevice = FALSE; ++#endif ++ } else { ++ ucNetworkType = NETWORK_TYPE_AIS_INDEX; ++ } ++ ++ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ if (u2QueueIdx < CFG_MAX_TXQ_NUM) ++ GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); ++ prDev = prSkb->dev; ++ ++ ASSERT(prDev); ++ ++ if ((fgIsValidDevice == TRUE) && (u2QueueIdx < CFG_MAX_TXQ_NUM)) { ++ if (netif_subqueue_stopped(prDev, prSkb) && ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= ++ CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) { ++ DBGLOG(TX, INFO, "netif_wake_subqueue for bss: %d. Queue len: %d\n", ++ ucNetworkType, ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); ++ netif_wake_subqueue(prDev, u2QueueIdx); ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ prGlueInfo->rHifInfo.HifLoopbkFlg &= ~0x01; ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ } ++ } ++ ++ dev_kfree_skb((struct sk_buff *)pvPacket); ++ prGlueInfo->u8SkbFreed++; ++ ++ DBGLOG(TX, EVENT, "----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Copy Mac Address setting from registry. It's All Zeros in Linux. ++* ++* \param[in] prAdapter Pointer to the Adapter structure ++* ++* \param[out] paucMacAddr Pointer to the Mac Address buffer ++* ++* \retval WLAN_STATUS_SUCCESS ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalQueryRegistryMacAddr(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_8 paucMacAddr) ++{ ++ UINT_8 aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 } ++ ++ DEBUGFUNC("kalQueryRegistryMacAddr"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(paucMacAddr); ++ ++ kalMemCopy((PVOID) paucMacAddr, (PVOID) aucZeroMac, MAC_ADDR_LEN); ++ ++} /* end of kalQueryRegistryMacAddr() */ ++ ++#if CFG_SUPPORT_EXT_CONFIG ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Read external configuration, ex. NVRAM or file ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ /* External data is given from user space by ioctl or /proc, not read by ++ driver. ++ */ ++ if (0 != prGlueInfo->u4ExtCfgLength) ++ DBGLOG(INIT, TRACE, "Read external configuration data -- OK\n"); ++ else ++ DBGLOG(INIT, TRACE, "Read external configuration data -- fail\n"); ++ ++ return prGlueInfo->u4ExtCfgLength; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This inline function is to extract some packet information, including ++* user priority, packet length, destination address, 802.1x and BT over Wi-Fi ++* or not. ++* ++* @param prGlueInfo Pointer to the glue structure ++* @param prNdisPacket Packet descriptor ++* @param pucPriorityParam User priority ++* @param pu4PacketLen Packet length ++* @param pucEthDestAddr Destination address ++* @param pfgIs1X 802.1x packet or not ++* @param pfgIsPAL BT over Wi-Fi packet or not ++* @prGenUse General used param ++* ++* @retval TRUE Success to extract information ++* @retval FALSE Fail to extract correct information ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++BOOLEAN ++kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_NATIVE_PACKET prPacket, ++ OUT PUINT_8 pucPriorityParam, ++ OUT PUINT_32 pu4PacketLen, ++ OUT PUINT_8 pucEthDestAddr, ++ OUT PBOOLEAN pfgIs1X, ++ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, ++ OUT PVOID prGenUse) ++{ ++ ++ UINT_32 u4PacketLen; ++ ++ UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT; /* Default */ ++ UINT_16 u2EtherTypeLen; ++ struct sk_buff *prSkb = (struct sk_buff *)prPacket; ++ PUINT_8 aucLookAheadBuf = NULL; ++ ++ DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo"); ++ ++ u4PacketLen = prSkb->len; ++ ++ if (u4PacketLen < ETH_HLEN) { ++ DBGLOG(TX, WARN, "Invalid Ether packet length: %u\n", (UINT_32) u4PacketLen); ++ return FALSE; ++ } ++ ++ aucLookAheadBuf = prSkb->data; ++ ++ *pfgIs1X = FALSE; ++ *pfgIsPAL = FALSE; ++ ++ /* 4 <3> Obtain the User Priority for WMM */ ++ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); ++ ++ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { ++ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_8 ucIpVersion; ++ ++ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if (ucIpVersion == IPVERSION) { ++ UINT_8 ucIpTos; ++ /* Get the DSCP value from the header of IP packet. */ ++ ucIpTos = pucIpHdr[1]; ++ ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET); ++ } ++ ++ /* TODO(Kevin): Add TSPEC classifier here */ ++ } else if (u2EtherTypeLen == ETH_P_1X || u2EtherTypeLen == ETH_P_PRE_1X) { /* For Port Control */ ++ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_8 ucEapolType = pucEapol[1]; ++ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; ++ /* ++ * generate a seq number used to trace security frame TX ++ */ ++ if (prGenUse) ++ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); ++ ++ switch (ucEapolType) { ++ case 0: /* eap packet */ ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 1: /* eapol start */ ++ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 3: /* key */ ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x... seqNo %d\n", ++ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ } ++ *pfgIs1X = TRUE; ++ } ++#if CFG_SUPPORT_WAPI ++ else if (u2EtherTypeLen == ETH_WPI_1X) { ++ PUINT_8 pucEthBody = &aucLookAheadBuf[ETH_HLEN]; ++ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ ++ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; ++ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; ++ ++ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", ++ ucSubType, u2Length, u2Seq); ++ *pfgIs1X = TRUE; ++ } ++#endif ++#if (CFG_SUPPORT_TDLS == 1) ++ else if (u2EtherTypeLen == TDLS_FRM_PROT_TYPE) { ++ /* TDLS case */ ++ TDLSEX_UP_ASSIGN(ucUserPriority); ++ } ++#endif /* CFG_SUPPORT_TDLS */ ++ else if (u2EtherTypeLen <= 1500) { /* 802.3 Frame */ ++ UINT_8 ucDSAP, ucSSAP, ucControl; ++ UINT_8 aucOUI[3]; ++ ++ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; ++ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; ++ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; ++ ++ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; ++ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; ++ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; ++ ++ if (ucDSAP == ETH_LLC_DSAP_SNAP && ++ ucSSAP == ETH_LLC_SSAP_SNAP && ++ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && ++ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && ++ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) { ++ ++ UINT_16 tmp = ++ ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]); ++ ++ *pfgIsPAL = TRUE; ++ ucUserPriority = (UINT_8) prSkb->priority; ++ ++ if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) { ++ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_SNAP_OFFSET + 5]; ++ UINT_8 ucEapolType = pucEapol[1]; ++ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; ++ if (prGenUse) ++ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); ++ ++ switch (ucEapolType) { ++ case 0: /* eap packet */ ++ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", ++ pucEapol[4], pucEapol[5], pucEapol[7], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 1: /* eapol start */ ++ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ case 3: /* key */ ++ DBGLOG(TX, INFO, ++ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x seqNo %d\n", ++ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], ++ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], ++ prGenUse ? *(UINT_8 *)prGenUse : 0); ++ break; ++ } ++ *pfgIs1X = TRUE; ++ } ++ } ++ } ++ /* 4 <4> Return the value of Priority Parameter. */ ++ *pucPriorityParam = ucUserPriority; ++ ++ /* 4 <5> Retrieve Packet Information - DA */ ++ /* Packet Length/ Destination Address */ ++ *pu4PacketLen = u4PacketLen; ++ ++ kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN); ++ ++ /* <6> Network type */ ++#if CFG_ENABLE_BT_OVER_WIFI ++ if (*pfgIsPAL == TRUE) { ++ *pucNetworkType = NETWORK_TYPE_BOW_INDEX; ++ } else ++#endif ++ { ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) { ++ *pucNetworkType = NETWORK_TYPE_P2P_INDEX; ++ } else ++#endif ++ { ++ *pucNetworkType = NETWORK_TYPE_AIS_INDEX; ++ } ++ } ++ return TRUE; ++} /* end of kalQoSFrameClassifier() */ ++ ++VOID ++kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, ++ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus) ++{ ++ ++ ASSERT(prGlueInfo); ++ /* remove timeout check timer */ ++ wlanoidClearTimeoutCheck(prGlueInfo->prAdapter); ++ ++ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ ++ prGlueInfo->rPendStatus = rOidStatus; ++ DBGLOG(OID, TEMP, "kalOidComplete, caller: %p\n", __builtin_return_address(0)); ++ complete(&prGlueInfo->rPendComp); ++ prGlueInfo->u4OidCompleteFlag = 1; ++ /* } */ ++ /* else let it timeout on kalIoctl entry */ ++} ++ ++VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ ++ /* clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag); */ ++ if (prGlueInfo->u4OidCompleteFlag != 1) { ++ DBGLOG(OID, TEMP, "kalOidClearance, caller: %p\n", __builtin_return_address(0)); ++ complete(&prGlueInfo->rPendComp); ++ } ++ /* } */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is used to transfer linux ioctl to OID, and we ++* need to specify the behavior of the OID by ourself ++* ++* @param prGlueInfo Pointer to the glue structure ++* @param pvInfoBuf Data buffer ++* @param u4InfoBufLen Data buffer length ++* @param fgRead Is this a read OID ++* @param fgWaitResp does this OID need to wait for values ++* @param fgCmd does this OID compose command packet ++* @param pu4QryInfoLen The data length of the return values ++* ++* @retval TRUE Success to extract information ++* @retval FALSE Fail to extract correct information ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++/* todo: enqueue the i/o requests for multiple processes access */ ++/* */ ++/* currently, return -1 */ ++/* */ ++ ++/* static GL_IO_REQ_T OidEntry; */ ++ ++WLAN_STATUS ++kalIoctl(IN P_GLUE_INFO_T prGlueInfo, ++ IN PFN_OID_HANDLER_FUNC pfnOidHandler, ++ IN PVOID pvInfoBuf, ++ IN UINT_32 u4InfoBufLen, ++ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen) ++{ ++ P_GL_IO_REQ_T prIoReq = NULL; ++ WLAN_STATUS ret = WLAN_STATUS_SUCCESS; ++ ++ if (fgIsResetting == TRUE) ++ return WLAN_STATUS_SUCCESS; ++ ++ /* GLUE_SPIN_LOCK_DECLARATION(); */ ++ ASSERT(prGlueInfo); ++ ++ /* <1> Check if driver is halt */ ++ /* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */ ++ /* return WLAN_STATUS_ADAPTER_NOT_READY; */ ++ /* } */ ++ ++ /* if wait longer than double OID timeout timer, then will show backtrace who held halt lock. ++ at this case, we will return kalIoctl failure because tx_thread may be hung */ ++ if (kalHaltLock(2 * WLAN_OID_TIMEOUT_THRESHOLD)) ++ return WLAN_STATUS_FAILURE; ++ ++ if (kalIsHalted()) { ++ kalHaltUnlock(); ++ return WLAN_STATUS_ADAPTER_NOT_READY; ++ } ++ ++ if (down_interruptible(&prGlueInfo->ioctl_sem)) { ++ kalHaltUnlock(); ++ return WLAN_STATUS_FAILURE; ++ } ++ ++ /* <2> TODO: thread-safe */ ++ ++ /* <3> point to the OidEntry of Glue layer */ ++ ++ prIoReq = &(prGlueInfo->OidEntry); ++ ++ ASSERT(prIoReq); ++ ++ /* <4> Compose the I/O request */ ++ prIoReq->prAdapter = prGlueInfo->prAdapter; ++ prIoReq->pfnOidHandler = pfnOidHandler; ++ prIoReq->pvInfoBuf = pvInfoBuf; ++ prIoReq->u4InfoBufLen = u4InfoBufLen; ++ prIoReq->pu4QryInfoLen = pu4QryInfoLen; ++ prIoReq->fgRead = fgRead; ++ prIoReq->fgWaitResp = fgWaitResp; ++ prIoReq->rStatus = WLAN_STATUS_FAILURE; ++#if CFG_ENABLE_WIFI_DIRECT ++ prIoReq->fgIsP2pOid = fgIsP2pOid; ++#endif ++ ++ /* <5> Reset the status of pending OID */ ++ prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE; ++ /* prGlueInfo->u4TimeoutFlag = 0; */ ++ /* prGlueInfo->u4OidCompleteFlag = 0; */ ++ ++ /* <6> Check if we use the command queue */ ++ prIoReq->u4Flag = fgCmd; ++ ++ /* <7> schedule the OID bit */ ++ set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag); ++ ++ /* <8> Wake up tx thread to handle kick start the I/O request */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ /* <9> Block and wait for event or timeout, current the timeout is 5 secs */ ++ /* if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) { */ ++ /* if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) { */ ++ DBGLOG(OID, TEMP, "kalIoctl: before wait, caller: %p\n", __builtin_return_address(0)); ++ wait_for_completion(&prGlueInfo->rPendComp); { ++ /* Case 1: No timeout. */ ++ /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo */ ++ if (prIoReq->rStatus == WLAN_STATUS_PENDING) ++ ret = prGlueInfo->rPendStatus; ++ else ++ ret = prIoReq->rStatus; ++ } ++#if 0 ++ else { ++ /* Case 2: timeout */ ++ /* clear pending OID's cmd in CMD queue */ ++ if (fgCmd) { ++ prGlueInfo->u4TimeoutFlag = 1; ++ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); ++ } ++ ret = WLAN_STATUS_FAILURE; ++ } ++#endif ++ DBGLOG(OID, TEMP, "kalIoctl: done\n"); ++ up(&prGlueInfo->ioctl_sem); ++ kalHaltUnlock(); ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear all pending security frames ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending security frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { ++ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear pending security frames ++* belongs to dedicated network type ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* \param eNetworkTypeIdx Network Type Index ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending security frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME && prCmdInfo->eNetworkType == eNetworkTypeIdx) { ++ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear all pending management frames ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending management frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear all pending management frames ++* belongs to dedicated network type ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Clear pending management frames in prGlueInfo->rCmdQueue */ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ ++ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME && ++ prCmdInfo->eNetworkType == eNetworkTypeIdx) { ++ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } else { ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ } ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} /* kalClearMgmtFramesByNetType */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief This function is a kernel thread function for handling command packets ++* Tx requests and interrupt events ++* ++* @param data data pointer to private data of tx_thread ++* ++* @retval If the function succeeds, the return value is 0. ++* Otherwise, an error code is returned. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++int tx_thread(void *data) ++{ ++ struct net_device *dev = data; ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); ++ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_GL_IO_REQ_T prIoReq = NULL; ++ P_QUE_T prTxQueue = NULL; ++ P_QUE_T prCmdQue = NULL; ++ ++ int ret = 0; ++ ++ BOOLEAN fgNeedHwAccess = FALSE; ++ ++ struct sk_buff *prSkb = NULL; ++ ++ /* for spin lock acquire and release */ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ prTxQueue = &prGlueInfo->rTxQueue; ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ current->flags |= PF_NOFREEZE; ++ ++ DBGLOG(INIT, INFO, "tx_thread starts running...\n"); ++ ++ while (TRUE) { ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ /*run p2p multicast list work. */ ++ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) ++ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); ++#endif ++ ++ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { ++ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; ++ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ ++ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); ++ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; ++ } ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ DBGLOG(INIT, INFO, "tx_thread should stop now...\n"); ++ break; ++ } ++ ++ /* ++ * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT ++ * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT ++ * ++ */ ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ ++ ret = wait_event_interruptible(prGlueInfo->waitq, (prGlueInfo->ulFlag != 0)); ++ ++ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ ++/* #if (CONF_HIF_LOOPBACK_AUTO == 1) */ ++/* if (test_and_clear_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &prGlueInfo->u4Flag)) { */ ++/* kalDevLoopbkAuto(prGlueInfo); */ ++/* } */ ++/* #endif */ /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if CFG_DBG_GPIO_PINS ++ /* TX thread Wake up */ ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW); ++#endif ++#if CFG_ENABLE_WIFI_DIRECT ++ /*run p2p multicast list work. */ ++ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) ++ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); ++ ++ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag)) { ++ p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter); ++ } ++#endif ++ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { ++ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; ++ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ ++ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); ++ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; ++ } ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); ++ DBGLOG(INIT, INFO, "<1>tx_thread should stop now...\n"); ++ break; ++ } ++ ++ fgNeedHwAccess = FALSE; ++ ++ /* Handle Interrupt */ ++ if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) { ++ if (fgNeedHwAccess == FALSE) { ++ fgNeedHwAccess = TRUE; ++ ++ wlanAcquirePowerControl(prGlueInfo->prAdapter); ++ } ++ ++ /* the Wi-Fi interrupt is already disabled in mmc thread, ++ so we set the flag only to enable the interrupt later */ ++ prGlueInfo->prAdapter->fgIsIntEnable = FALSE; ++ /* wlanISR(prGlueInfo->prAdapter, TRUE); */ ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ /* Should stop now... skip pending interrupt */ ++ DBGLOG(INIT, INFO, "ignore pending interrupt\n"); ++ } else { ++ prGlueInfo->TaskIsrCnt++; ++ wlanIST(prGlueInfo->prAdapter); ++ } ++ } ++ ++ /* transfer ioctl to OID request */ ++#if 0 ++ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { ++ DBGLOG(INIT, INFO, "<2>tx_thread should stop now...\n"); ++ break; ++ } ++#endif ++ ++ do { ++ if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag)) { ++ /* get current prIoReq */ ++ prGlueInfo->u4OidCompleteFlag = 0; ++ ++ prIoReq = &(prGlueInfo->OidEntry); ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE && prIoReq->fgIsP2pOid == TRUE) { ++ /* if this Oid belongs to p2p and p2p module is removed ++ * do nothing, ++ */ ++ } else ++#endif ++ { ++ if (FALSE == prIoReq->fgRead) { ++ prIoReq->rStatus = wlanSetInformation(prIoReq->prAdapter, ++ prIoReq->pfnOidHandler, ++ prIoReq->pvInfoBuf, ++ prIoReq->u4InfoBufLen, ++ prIoReq->pu4QryInfoLen); ++ } else { ++ prIoReq->rStatus = wlanQueryInformation(prIoReq->prAdapter, ++ prIoReq->pfnOidHandler, ++ prIoReq->pvInfoBuf, ++ prIoReq->u4InfoBufLen, ++ prIoReq->pu4QryInfoLen); ++ } ++ ++ if (prIoReq->rStatus != WLAN_STATUS_PENDING) { ++ DBGLOG(OID, TEMP, "tx_thread, complete\n"); ++ complete(&prGlueInfo->rPendComp); ++ } else { ++ wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler); ++ } ++ } ++ } ++ ++ } while (FALSE); ++ ++ /* ++ * ++ * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent ++ * indicates the following requests occur ++ * ++ */ ++#if 0 ++ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { ++ DBGLOG(INIT, INFO, "<3>tx_thread should stop now...\n"); ++ break; ++ } ++#endif ++ ++ if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->ulFlag)) { ++ /* Process Mailbox Messages */ ++ wlanProcessMboxMessage(prGlueInfo->prAdapter); ++ ++ /* Process CMD request */ ++ do { ++ if (prCmdQue->u4NumElem > 0) { ++ if (fgNeedHwAccess == FALSE) { ++ fgNeedHwAccess = TRUE; ++ ++ wlanAcquirePowerControl(prGlueInfo->prAdapter); ++ } ++ wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue); ++ } ++ } while (FALSE); ++ ++ /* Handle Packet Tx */ ++ { ++ while (QUEUE_IS_NOT_EMPTY(prTxQueue)) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ ASSERT(prQueueEntry); ++ if (NULL == prQueueEntry) ++ break; ++ ++ prSkb = (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); ++ ASSERT(prSkb); ++ if (NULL == prSkb) { ++ DBGLOG(INIT, ERROR, "prSkb == NULL!\n"); ++ continue; ++ } ++#if (CFG_SUPPORT_TDLS_DBG == 1) ++ UINT8 *pkt = prSkb->data; ++ UINT16 u2Identifier; ++ ++ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { ++ /* ip */ ++ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); ++ DBGLOG(INIT, LOUD, " %d\n", u2Identifier); ++ } ++#endif ++ if (wlanEnqueueTxPacket(prGlueInfo->prAdapter, ++ (P_NATIVE_PACKET) prSkb) == WLAN_STATUS_RESOURCES) { ++ /* no available entry in rFreeMsduInfoList */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ break; ++ } ++ } ++ ++ if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) { ++ /* send packets to HIF here */ ++ wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess); ++ } ++ } ++ ++ } ++ ++ /* Process RX, In linux, we don't need to free sk_buff by ourself */ ++ ++ /* In linux, we don't need to free sk_buff by ourself */ ++ ++ /* In linux, we don't do reset */ ++ if (fgNeedHwAccess == TRUE) ++ wlanReleasePowerControl(prGlueInfo->prAdapter); ++ ++ /* handle cnmTimer time out */ ++ if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag)) ++ wlanTimerTimeoutCheck(prGlueInfo->prAdapter); ++#if CFG_DBG_GPIO_PINS ++ /* TX thread go to sleep */ ++ if (!prGlueInfo->ulFlag) ++ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH); ++#endif ++ } ++ ++#if 0 ++ if (fgNeedHwAccess == TRUE) ++ wlanReleasePowerControl(prGlueInfo->prAdapter); ++#endif ++ ++ /* exit while loop, tx thread is closed so we flush all pending packets */ ++ /* flush the pending TX packets */ ++ if (prGlueInfo->i4TxPendingFrameNum > 0) ++ kalFlushPendingTxPackets(prGlueInfo); ++ ++ /* flush pending security frames */ ++ if (prGlueInfo->i4TxPendingSecurityFrameNum > 0) ++ kalClearSecurityFrames(prGlueInfo); ++ ++ /* remove pending oid */ ++ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); ++ ++ /* In linux, we don't need to free sk_buff by ourself */ ++ ++ DBGLOG(INIT, INFO, "mtk_sdiod stops\n"); ++ complete(&prGlueInfo->rHaltComp); ++ ++ return 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to check if card is removed ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval TRUE: card is removed ++* FALSE: card is still attached ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return FALSE; ++ /* Linux MMC doesn't have removal notification yet */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This routine is used to send command to firmware for overriding netweork address ++ * ++ * \param pvGlueInfo Pointer of GLUE Data Structure ++ ++ * \retval TRUE ++ * FALSE ++ */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr) ++{ ++ ASSERT(prGlueInfo); ++ ++ if (prGlueInfo->fgIsMacAddrOverride == FALSE) { ++#if !defined(CONFIG_X86) ++#if !defined(CONFIG_MTK_TC1_FEATURE) ++ UINT_32 i; ++#endif ++ BOOLEAN fgIsReadError = FALSE; ++ ++#if !defined(CONFIG_MTK_TC1_FEATURE) ++ for (i = 0; i < MAC_ADDR_LEN; i += 2) { ++ if (kalCfgDataRead16(prGlueInfo, ++ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, ++ (PUINT_16) (((PUINT_8) prMacAddr) + i)) == FALSE) { ++ fgIsReadError = TRUE; ++ break; ++ } ++ } ++#else ++ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prMacAddr); ++#endif ++ ++ if (fgIsReadError == TRUE) ++ return FALSE; ++ else ++ return TRUE; ++#else ++ /* x86 Linux doesn't need to override network address so far */ ++ return FALSE; ++#endif ++ } else { ++ COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride); ++ ++ return TRUE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to flush pending TX packets in glue layer ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prTxQue; ++ P_QUE_ENTRY_T prQueueEntry; ++ PVOID prPacket; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ prTxQue = &(prGlueInfo->rTxQueue); ++ ++ if (prGlueInfo->i4TxPendingFrameNum) { ++ while (TRUE) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ if (prQueueEntry == NULL) ++ break; ++ ++ prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); ++ ++ kalSendComplete(prGlueInfo, prPacket, WLAN_STATUS_NOT_ACCEPTED); ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is get indicated media state ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->eParamMediaStateIndicated; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to set indicated media state ++* ++* \param pvGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate) ++{ ++ ASSERT(prGlueInfo); ++ ++ prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to clear pending OID staying in command queue ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ QUE_T rTempCmdQue; ++ P_QUE_T prTempCmdQue = &rTempCmdQue; ++ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; ++ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ while (prQueueEntry) { ++ ++ if (((P_CMD_INFO_T) prQueueEntry)->fgIsOid) { ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ break; ++ } ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ ++ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); ++ } ++ ++ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ ++ if (prCmdInfo) { ++ if (prCmdInfo->pfCmdTimeoutHandler) ++ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); ++ else ++ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_ACCEPTED); ++ ++ prGlueInfo->u4OidCompleteFlag = 1; ++ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to insert command into prCmdQueue ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* prQueueEntry Pointer of queue entry to be inserted ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry) ++{ ++ P_QUE_T prCmdQue; ++ P_CMD_INFO_T prCmdInfo; ++ P_MSDU_INFO_T prMsduInfo; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prQueueEntry); ++ ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; ++ if (prCmdInfo->prPacket && prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { ++ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); ++ prMsduInfo->eCmdType = prCmdInfo->eCmdType; ++ prMsduInfo->ucCID = prCmdInfo->ucCID; ++ prMsduInfo->u4InqueTime = kalGetTimeTick(); ++ } ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with ++* proper information ++* ++* @param pvGlueInfo Pointer of GLUE Data Structure ++* @param prAssocInfo Pointer of EVENT_ID_ASSOC_INFO Packet ++* ++* @return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo) ++{ ++ /* to do */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to get firmware load address from registry ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rRegInfo.u4LoadAddress; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to get firmware start address from registry ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rRegInfo.u4StartAddress; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * * @brief Notify OS with SendComplete event of the specific packet. Linux should ++ * * free packets here. ++ * * ++ * * @param pvGlueInfo Pointer of GLUE Data Structure ++ * * @param pvPacket Pointer of Packet Handle ++ * * @param status Status Code for OS upper layer ++ * * ++ * * @return none ++ * */ ++/*----------------------------------------------------------------------------*/ ++ ++/* / Todo */ ++VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus) ++{ ++ ASSERT(pvPacket); ++ ++ dev_kfree_skb((struct sk_buff *)pvPacket); ++ if (prGlueInfo) ++ prGlueInfo->u8SkbFreed++; ++ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++} ++ ++UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return (UINT_32) (prGlueInfo->i4TxPendingFrameNum); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to retrieve the number of pending commands ++* (including MMPDU, 802.1X and command packets) ++* ++* \param prGlueInfo Pointer of GLUE Data Structure ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_QUE_T prCmdQue; ++ ++ ASSERT(prGlueInfo); ++ prCmdQue = &prGlueInfo->rCmdQueue; ++ ++ return prCmdQue->u4NumElem; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Timer Initialization Procedure ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* \param[in] prTimerHandler Pointer to timer handling function, whose only ++* argument is "prAdapter" ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++/* static struct timer_list tickfn; */ ++ ++VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler) ++{ ++ ++ ASSERT(prGlueInfo); ++ ++ timer_setup(&(prGlueInfo->tickfn), prTimerHandler, 0); ++} ++ ++/* Todo */ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the time to do the time out check. ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* \param[in] rInterval Time out interval from current time. ++* ++* \retval TRUE Success. ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval) ++{ ++ ASSERT(prGlueInfo); ++ del_timer_sync(&(prGlueInfo->tickfn)); ++ ++ prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC; ++ add_timer(&(prGlueInfo->tickfn)); ++ ++ return TRUE; /* success */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to cancel ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* ++* \retval TRUE : Timer has been canceled ++* FALAE : Timer doens't exist ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); ++ ++ if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is a callback function for scanning done ++* ++* \param[in] prGlueInfo Pointer to GLUE Data Structure ++* ++* \retval none ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status) ++{ ++ P_AIS_FSM_INFO_T prAisFsmInfo; ++ ++ ASSERT(prGlueInfo); ++ ++ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); ++ /* report all queued beacon/probe response frames to upper layer */ ++ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); ++ cnmTimerStopTimer(prGlueInfo->prAdapter, &prAisFsmInfo->rScanDoneTimer); ++ ++ /* check for system configuration for generating error message on scan list */ ++ wlanCheckSystemConfiguration(prGlueInfo->prAdapter); ++ ++ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is used to generate a random number ++* ++* \param none ++* ++* \retval UINT_32 ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalRandomNumber(VOID) ++{ ++ UINT_32 number = 0; ++ ++ get_random_bytes(&number, 4); ++ ++ return number; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief command timeout call-back function ++ * ++ * \param[in] prGlueInfo Pointer to the GLUE data structure. ++ * ++ * \retval (none) ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID kalTimeoutHandler(struct timer_list *t) ++{ ++ ++ P_GLUE_INFO_T prGlueInfo = from_timer(prGlueInfo, t, tickfn); ++ ++ ASSERT(prGlueInfo); ++ ++ /* Notify tx thread for timeout event */ ++ set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++} ++ ++VOID kalSetEvent(P_GLUE_INFO_T pr) ++{ ++ set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag); ++ wake_up_interruptible(&pr->waitq); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if configuration file (NVRAM/Registry) exists ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo) ++{ ++#if !defined(CONFIG_X86) ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->fgNvramAvailable; ++#else ++ /* there is no configuration data for x86-linux */ ++ return FALSE; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Registry information ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* Pointer of REG_INFO_T ++*/ ++/*----------------------------------------------------------------------------*/ ++P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return &(prGlueInfo->rRegInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve version information of corresponding configuration file ++* ++* \param[in] ++* prGlueInfo ++* ++* \param[out] ++* pu2Part1CfgOwnVersion ++* pu2Part1CfgPeerVersion ++* pu2Part2CfgOwnVersion ++* pu2Part2CfgPeerVersion ++* ++* \return ++* NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PUINT_16 pu2Part1CfgOwnVersion, ++ OUT PUINT_16 pu2Part1CfgPeerVersion, ++ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion) ++{ ++ ASSERT(prGlueInfo); ++ ++ ASSERT(pu2Part1CfgOwnVersion); ++ ASSERT(pu2Part1CfgPeerVersion); ++ ASSERT(pu2Part2CfgOwnVersion); ++ ASSERT(pu2Part2CfgPeerVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion), pu2Part1CfgOwnVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion), pu2Part1CfgPeerVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion), pu2Part2CfgOwnVersion); ++ ++ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion), pu2Part2CfgPeerVersion); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if the WPS is active or not ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->fgWpsActive; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief update RSSI and LinkQuality to GLUE layer ++* ++* \param[in] ++* prGlueInfo ++* eNetTypeIdx ++* cRssi ++* cLinkQuality ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) ++{ ++ struct iw_statistics *pStats = (struct iw_statistics *)NULL; ++ ++ ASSERT(prGlueInfo); ++ ++ switch (eNetTypeIdx) { ++ case KAL_NETWORK_TYPE_AIS_INDEX: ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); ++ break; ++#if CFG_ENABLE_WIFI_DIRECT ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ case KAL_NETWORK_TYPE_P2P_INDEX: ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); ++ break; ++#endif ++#endif ++ default: ++ break; ++ ++ } ++ ++ if (pStats) { ++ pStats->qual.qual = cLinkQuality; ++ pStats->qual.noise = 0; ++ pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; ++ pStats->qual.level = 0x100 + cRssi; ++ pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED; ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Pre-allocate I/O buffer ++* ++* \param[in] ++* none ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitIOBuffer(VOID) ++{ ++ UINT_32 u4Size; ++ ++ if (CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE) ++ u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); ++ else ++ u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ pvDmaBuffer = dma_alloc_coherent(NULL, CFG_RX_MAX_PKT_SIZE, &pvDmaPhyBuf, GFP_KERNEL); ++ if (pvDmaBuffer == NULL) ++ return FALSE; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ pvIoBuffer = kmalloc(u4Size, GFP_KERNEL); ++/* pvIoBuffer = dma_alloc_coherent(NULL, u4Size, &pvIoPhyBuf, GFP_KERNEL); */ ++ if (pvIoBuffer) { ++ pvIoBufferSize = u4Size; ++ pvIoBufferUsage = 0; ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Free pre-allocated I/O buffer ++* ++* \param[in] ++* none ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalUninitIOBuffer(VOID) ++{ ++ kfree(pvIoBuffer); ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ dma_free_coherent(NULL, CFG_RX_MAX_PKT_SIZE, pvDmaBuffer, pvDmaPhyBuf); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ /* dma_free_coherent(NULL, pvIoBufferSize, pvIoBuffer, pvIoPhyBuf); */ ++ ++ pvIoBuffer = (PVOID) NULL; ++ pvIoBufferSize = 0; ++ pvIoBufferUsage = 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dispatch pre-allocated I/O buffer ++* ++* \param[in] ++* u4AllocSize ++* ++* \return ++* PVOID for pointer of pre-allocated I/O buffer ++*/ ++/*----------------------------------------------------------------------------*/ ++PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize) ++{ ++ PVOID ret = (PVOID) NULL; ++ ++ if (pvIoBuffer) { ++ if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) { ++ ret = (PVOID) &(((PUINT_8) (pvIoBuffer))[pvIoBufferUsage]); ++ pvIoBufferUsage += u4AllocSize; ++ } ++ } else { ++ /* fault tolerance */ ++ ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE); ++ } ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Release all dispatched I/O buffer ++* ++* \param[in] ++* none ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size) ++{ ++ if (pvIoBuffer) { ++ pvIoBufferUsage -= u4Size; ++ } else { ++ /* fault tolerance */ ++ kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) ++{ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, ++ pucNumOfChannel, paucChannelList); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo) ++{ ++#if CFG_ENABLE_WIFI_DIRECT ++ if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) && ++ p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo)) ++ return TRUE; ++#endif ++ ++ return FALSE; ++} ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function gets the physical address for Pre-allocate I/O buffer. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[out] pu4Flags Pointer of a variable for saving IRQ flags ++* ++* \return physical addr ++*/ ++/*----------------------------------------------------------------------------*/ ++ULONG kalIOPhyAddrGet(IN ULONG VirtAddr) ++{ ++ ULONG PhyAddr; ++ ++ if ((VirtAddr >= (ULONG) pvIoBuffer) && (VirtAddr <= ((ULONG) (pvIoBuffer) + pvIoBufferSize))) { ++ PhyAddr = (ULONG) pvIoPhyBuf; ++ PhyAddr += (VirtAddr - (ULONG) (pvIoBuffer)); ++ return PhyAddr; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function gets the physical address for Pre-allocate I/O buffer. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] rLockCategory Specify which SPIN_LOCK ++* \param[out] pu4Flags Pointer of a variable for saving IRQ flags ++* ++* \return physical addr ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr) ++{ ++ *VirtAddr = pvDmaBuffer; ++ *PhyAddr = pvDmaPhyBuf; ++} ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++#if CFG_SUPPORT_802_11W ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to check if the MFP is active or not ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->rWpaInfo.u4Mfp; ++} ++#endif ++ ++struct file *kalFileOpen(const char *path, int flags, int rights) ++{ ++ struct file *filp = NULL; ++ mm_segment_t oldfs; ++ int err = 0; ++ ++ oldfs = get_fs(); ++ set_fs(get_ds()); ++ filp = filp_open(path, flags, rights); ++ set_fs(oldfs); ++ if (IS_ERR(filp)) { ++ err = PTR_ERR(filp); ++ return NULL; ++ } ++ return filp; ++} ++ ++VOID kalFileClose(struct file *file) ++{ ++ filp_close(file, NULL); ++} ++ ++UINT_32 kalFileRead(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) ++{ ++ mm_segment_t oldfs; ++ INT_32 ret; ++ ++ oldfs = get_fs(); ++ set_fs(get_ds()); ++ ++ ret = vfs_read(file, data, size, &offset); ++ ++ set_fs(oldfs); ++ return ret; ++} ++ ++UINT_32 kalFileWrite(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) ++{ ++ mm_segment_t oldfs; ++ INT_32 ret; ++ ++ oldfs = get_fs(); ++ set_fs(get_ds()); ++ ++ ret = vfs_write(file, data, size, &offset); ++ ++ set_fs(oldfs); ++ return ret; ++} ++ ++UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size) ++{ ++ struct file *file = NULL; ++ UINT_32 ret = -1; ++ UINT_32 u4Flags = 0; ++ ++ if (fgDoAppend) ++ u4Flags = O_APPEND; ++ ++ file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU); ++ if (file) { ++ ret = kalFileWrite(file, 0, pucData, u4Size); ++ kalFileClose(file); ++ } ++ ++ return ret; ++} ++ ++INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize) ++{ ++ struct file *file = NULL; ++ INT_32 ret = -1; ++ UINT_32 u4ReadSize = 0; ++ ++ DBGLOG(INIT, LOUD, "kalReadToFile() path %s\n", pucPath); ++ ++ file = kalFileOpen(pucPath, O_RDONLY, 0); ++ ++ if ((file != NULL) && !IS_ERR(file)) { ++ u4ReadSize = kalFileRead(file, 0, pucData, u4Size); ++ kalFileClose(file); ++ if (pu4ReadSize) ++ *pu4ReadSize = u4ReadSize; ++ ret = 0; ++ } ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate BSS-INFO to NL80211 as scanning result ++* ++* \param[in] ++* prGlueInfo ++* pucBeaconProbeResp ++* u4FrameLen ++* ++* ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucBeaconProbeResp, ++ IN UINT_32 u4FrameLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength) ++{ ++ struct wiphy *wiphy; ++ struct ieee80211_channel *prChannel = NULL; ++ ++ ASSERT(prGlueInfo); ++ wiphy = priv_to_wiphy(prGlueInfo); ++ ++ /* search through channel entries */ ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); ++ } ++ ++ if (prChannel != NULL && (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)) { ++ struct cfg80211_bss *bss; ++#if CFG_SUPPORT_TSF_USING_BOOTTIME ++ struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt *)pucBeaconProbeResp; ++ ++ prMgmtFrame->u.beacon.timestamp = kalGetBootTime(); ++#endif ++ ScanCnt++; ++ ++ /* indicate to NL80211 subsystem */ ++ bss = cfg80211_inform_bss_frame(wiphy, ++ prChannel, ++ (struct ieee80211_mgmt *)pucBeaconProbeResp, ++ u4FrameLen, i4SignalStrength * 100, GFP_KERNEL); ++ ++ if (!bss) { ++ ScanDoneFailCnt++; ++ DBGLOG(SCN, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", ++ ucChannelNum, i4SignalStrength); ++ } else { ++ cfg80211_put_bss(wiphy, bss); ++ DBGLOG(SCN, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", ++ ucChannelNum, i4SignalStrength); ++ } ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate channel ready ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs) ++{ ++ struct ieee80211_channel *prChannel = NULL; ++ enum nl80211_channel_type rChannelType; ++ ++ /* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); */ ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); ++ } ++ ++ switch (eSco) { ++ case CHNL_EXT_SCN: ++ rChannelType = NL80211_CHAN_NO_HT; ++ break; ++ ++ case CHNL_EXT_SCA: ++ rChannelType = NL80211_CHAN_HT40MINUS; ++ break; ++ ++ case CHNL_EXT_SCB: ++ rChannelType = NL80211_CHAN_HT40PLUS; ++ break; ++ ++ case CHNL_EXT_RES: ++ default: ++ rChannelType = NL80211_CHAN_HT20; ++ break; ++ } ++ ++ cfg80211_ready_on_channel(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, u4DurationMs, ++ GFP_KERNEL); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate channel expiration ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum) ++{ ++ struct ieee80211_channel *prChannel = NULL; ++ enum nl80211_channel_type rChannelType; ++ ++ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); ++ ++ if (prGlueInfo->fgIsRegistered == TRUE) { ++ if (ucChannelNum <= 14) { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); ++ } else { ++ prChannel = ++ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ++ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); ++ } ++ ++ switch (eSco) { ++ case CHNL_EXT_SCN: ++ rChannelType = NL80211_CHAN_NO_HT; ++ break; ++ ++ case CHNL_EXT_SCA: ++ rChannelType = NL80211_CHAN_HT40MINUS; ++ break; ++ ++ case CHNL_EXT_SCB: ++ rChannelType = NL80211_CHAN_HT40PLUS; ++ break; ++ ++ case CHNL_EXT_RES: ++ default: ++ rChannelType = NL80211_CHAN_HT20; ++ break; ++ } ++ ++ cfg80211_remain_on_channel_expired(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, ++ GFP_KERNEL); ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate Mgmt tx status ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) ++{ ++ ++ do { ++ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { ++ DBGLOG(AIS, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", ++ prGlueInfo, pucFrameBuf, u4FrameLen); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ cfg80211_mgmt_tx_status(prGlueInfo->prDevHandler->ieee80211_ptr, ++ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); ++ } while (FALSE); ++ ++} /* kalIndicateMgmtTxStatus */ ++ ++VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) ++{ ++#define DBG_MGMT_FRAME_INDICATION 1 ++ INT_32 i4Freq = 0; ++ UINT_8 ucChnlNum = 0; ++#if DBG_MGMT_FRAME_INDICATION ++ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; ++#endif ++ ++ do { ++ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; ++ ++#if DBG_MGMT_FRAME_INDICATION ++ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; ++ ++ switch (prWlanHeader->u2FrameCtrl) { ++ case MAC_FRAME_PROBE_REQ: ++ DBGLOG(AIS, TRACE, "RX Probe Req at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_PROBE_RSP: ++ DBGLOG(AIS, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_ACTION: ++ DBGLOG(AIS, TRACE, "RX Action frame at channel %d ", ucChnlNum); ++ break; ++ default: ++ DBGLOG(AIS, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); ++ break; ++ } ++ ++#endif ++ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; ++ ++ cfg80211_rx_mgmt(prGlueInfo->prDevHandler->ieee80211_ptr, /* struct net_device * dev, */ ++ i4Freq, ++ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), ++ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_KERNEL); ++ } while (FALSE); ++ ++} /* kalIndicateRxMgmtFrame */ ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen) ++{ ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ struct sk_buff *skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy(prGlueInfo), ++ dataLen, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(AIS, ERROR, "kalIndicateAgpsNotify: alloc skb failed\n"); ++ return FALSE; ++ } ++ ++ /* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */ ++ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), &cmd) < 0)) ++ goto nla_put_failure; ++ if (dataLen > 0 && data && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, data) < 0)) ++ goto nla_put_failure; ++ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, sizeof(UINT_32), &prGlueInfo->prDevHandler->ifindex) < 0)) ++ goto nla_put_failure; ++ /* currently, the ifname maybe wlan0, p2p0, so the maximum name length will be 5 bytes */ ++ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, prGlueInfo->prDevHandler->name) < 0)) ++ goto nla_put_failure; ++ cfg80211_testmode_event(skb, GFP_KERNEL); ++ return TRUE; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return FALSE; ++} ++#endif ++ ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++#define PROC_MET_PROF_CTRL "met_ctrl" ++#define PROC_MET_PROF_PORT "met_port" ++ ++struct proc_dir_entry *pMetProcDir; ++void *pMetGlobalData = NULL; ++static unsigned long __read_mostly tracing_mark_write_addr; ++ ++static inline void __mt_update_tracing_mark_write_addr(void) ++{ ++ if (unlikely(0 == tracing_mark_write_addr)) ++ tracing_mark_write_addr = kallsyms_lookup_name("tracing_mark_write"); ++} ++ ++VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb) ++{ ++ UINT_8 ucIpVersion; ++ UINT_16 u2UdpSrcPort; ++ UINT_16 u2RtpSn; ++ PUINT_8 pucEthHdr = prSkb->data; ++ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; ++ ++ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ ++ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ ++ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ ++ /* printk("MET_PROF: MET enable=%d(HardXmit)\n", prGlueInfo->u8MetProfEnable); */ ++ if (prGlueInfo->u8MetProfEnable == 1) { ++ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; ++ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { ++ /* IP */ ++ pucIpHdr = pucEthHdr + ETH_HLEN; ++ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { ++ /* UDP */ ++ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; ++ /* check UDP port number */ ++ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { ++ /* RTP */ ++ pucRtpHdr = pucUdpHdr + 8; ++ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; ++ /* trace_printk("S|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); ++ //frm_sequence); */ ++#ifdef CONFIG_TRACING ++ __mt_update_tracing_mark_write_addr(); ++ if (tracing_mark_write_addr != 0) { ++ event_trace_printk(tracing_mark_write_addr, "S|%d|%s|%d\n", ++ current->tgid, "WIFI-CHIP", u2RtpSn); ++ } ++#endif ++ } ++ } ++ } ++ } ++} ++ ++VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) ++{ ++ UINT_8 ucIpVersion; ++ UINT_16 u2UdpSrcPort; ++ UINT_16 u2RtpSn; ++ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; ++ PUINT_8 pucEthHdr = prSkb->data; ++ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ ++ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ ++ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ ++ /* printk("MET_PROF: MET enable=%d(TxMsdu)\n", prGlueInfo->u8MetProfEnable); */ ++ if (prGlueInfo->u8MetProfEnable == 1) { ++ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; ++ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { ++ /* IP */ ++ pucIpHdr = pucEthHdr + ETH_HLEN; ++ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; ++ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { ++ /* UDP */ ++ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; ++ /* check UDP port number */ ++ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { ++ /* RTP */ ++ pucRtpHdr = pucUdpHdr + 8; ++ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; ++ /* trace_printk("F|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); ++ //frm_sequence); */ ++#ifdef CONFIG_TRACING ++ __mt_update_tracing_mark_write_addr(); ++ if (tracing_mark_write_addr != 0) { ++ event_trace_printk(tracing_mark_write_addr, "F|%d|%s|%d\n", ++ current->tgid, "WIFI-CHIP", u2RtpSn); ++ } ++#endif ++ } ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t kalMetCtrlWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) ++{ ++ char acBuf[128 + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ int u8MetProfEnable; ++ ++ IN P_GLUE_INFO_T prGlueInfo; ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ if (copy_from_user(acBuf, buffer, u4CopySize)) ++ return -1; ++ acBuf[u4CopySize] = '\0'; ++ ++ if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1) ++ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC Enable=%d\n", u8MetProfEnable); ++ if (pMetGlobalData != NULL) { ++ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; ++ prGlueInfo->u8MetProfEnable = (UINT_8) u8MetProfEnable; ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static ssize_t kalMetPortWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) ++{ ++ char acBuf[128 + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ int u16MetUdpPort; ++ ++ IN P_GLUE_INFO_T prGlueInfo; ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ if (copy_from_user(acBuf, buffer, u4CopySize)) ++ return -1; ++ acBuf[u4CopySize] = '\0'; ++ ++ if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1) ++ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC UDP_PORT=%d\n", u16MetUdpPort); ++ if (pMetGlobalData != NULL) { ++ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; ++ prGlueInfo->u16MetUdpPort = (UINT_16) u16MetUdpPort; ++ } ++ return count; ++} ++ ++const struct file_operations rMetProcCtrlFops = { ++.write = kalMetCtrlWriteProcfs ++}; ++ ++const struct file_operations rMetProcPortFops = { ++.write = kalMetPortWriteProcfs ++}; ++ ++int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ /* struct proc_dir_entry *pMetProcDir; */ ++ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { ++ DBGLOG(INIT, INFO, "init proc fs fail: proc_net == NULL\n"); ++ return -ENOENT; ++ } ++ /* ++ * Directory: Root (/proc/net/wlan0) ++ */ ++ pMetProcDir = proc_mkdir("wlan0", init_net.proc_net); ++ if (pMetProcDir == NULL) ++ return -ENOENT; ++ /* ++ /proc/net/wlan0 ++ |-- met_ctrl (PROC_MET_PROF_CTRL) ++ |-- met_port (PROC_MET_PROF_PORT) ++ */ ++ /* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); */ ++ proc_create(PROC_MET_PROF_CTRL, 0, pMetProcDir, &rMetProcCtrlFops); ++ proc_create(PROC_MET_PROF_PORT, 0, pMetProcDir, &rMetProcPortFops); ++ ++ pMetGlobalData = (void *)prGlueInfo; ++ ++ return 0; ++} ++ ++int kalMetRemoveProcfs(void) ++{ ++ ++ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { ++ DBGLOG(INIT, WARN, "remove proc fs fail: proc_net == NULL\n"); ++ return -ENOENT; ++ } ++ remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir); ++ remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir); ++ /* remove root directory (proc/net/wlan0) */ ++ remove_proc_entry("wlan0", init_net.proc_net); ++ /* clear MetGlobalData */ ++ pMetGlobalData = NULL; ++ ++ return 0; ++} ++#endif ++UINT_64 kalGetBootTime(void) ++{ ++ struct timespec ts; ++ UINT_64 bootTime = 0; ++ ++ get_monotonic_boottime(&ts); ++ /* we assign ts.tv_sec to bootTime first, then multiply USEC_PER_SEC ++ this will prevent multiply result turn to a negative value on 32bit system */ ++ bootTime = ts.tv_sec; ++ bootTime *= USEC_PER_SEC; ++ bootTime += ts.tv_nsec / NSEC_PER_USEC; ++ return bootTime; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate scheduled scan results are avilable ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo),0); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To indicate scheduled scan has been stopped ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* None ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prGlueInfo); ++ ++ /* 1. reset first for newly incoming request */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prSchedScanRequest != NULL) ++ prGlueInfo->prSchedScanRequest = NULL; ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ DBGLOG(SCN, INFO, "cfg80211_sched_scan_stopped send event\n"); ++ ++ /* 2. indication to cfg80211 */ ++ /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K thread to send event instead of Tx thread ++ due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds and send event in the same time */ ++ DBGLOG(SCN, TRACE, "start work queue to send event\n"); ++ schedule_delayed_work(&sched_workq, 0); ++ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); ++ ++} ++ ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++/* if SPM is not implement this function, we will use this default one */ ++wake_reason_t __weak slp_get_wake_reason(VOID) ++{ ++ return WR_NONE; ++} ++/* if SPM is not implement this function, we will use this default one */ ++UINT_32 __weak spm_get_last_wakeup_src(VOID) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To check if device if wake up by wlan ++* ++* \param[in] ++* prAdapter ++* ++* \return ++* TRUE: wake up by wlan; otherwise, FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter) ++{ ++ /* SUSPEND_FLAG_FOR_WAKEUP_REASON is set means system has suspended, but may be failed ++ duo to some driver suspend failed. so we need help of function slp_get_wake_reason */ ++ if (test_and_clear_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prAdapter->ulSuspendFlag) == 0) ++ return FALSE; ++ /* if slp_get_wake_reason or spm_get_last_wakeup_src is NULL, it means SPM module didn't implement ++ it. then we should return FALSE always. otherwise, if slp_get_wake_reason returns WR_WAKE_SRC, ++ then it means the host is suspend successfully. */ ++ if (slp_get_wake_reason() != WR_WAKE_SRC) ++ return FALSE; ++ /* spm_get_last_wakeup_src will returns the last wakeup source, ++ WAKE_SRC_CONN2AP is connsys */ ++ return !!(spm_get_last_wakeup_src() & WAKE_SRC_CONN2AP); ++} ++#endif ++ ++INT_32 kalHaltLock(UINT_32 waitMs) ++{ ++ INT_32 i4Ret = 0; ++ ++ if (waitMs) { ++ i4Ret = down_timeout(&rHaltCtrl.lock, MSEC_TO_JIFFIES(waitMs)); ++ if (!i4Ret) ++ goto success; ++ if (i4Ret != -ETIME) ++ return i4Ret; ++ if (rHaltCtrl.fgHeldByKalIoctl) { ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ wlanExportGlueInfo(&prGlueInfo); ++ ++ DBGLOG(INIT, ERROR, ++ "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", ++ kalGetTimeTick() - rHaltCtrl.u4HoldStart); ++ if (prGlueInfo) ++ show_stack(prGlueInfo->main_thread, NULL); ++ } else { ++ DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", ++ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, ++ kalGetTimeTick() - rHaltCtrl.u4HoldStart); ++ show_stack(rHaltCtrl.owner, NULL); ++ } ++ return i4Ret; ++ } ++ down(&rHaltCtrl.lock); ++success: ++ rHaltCtrl.owner = current; ++ rHaltCtrl.u4HoldStart = kalGetTimeTick(); ++ return 0; ++} ++ ++INT_32 kalHaltTryLock(VOID) ++{ ++ INT_32 i4Ret = 0; ++ ++ i4Ret = down_trylock(&rHaltCtrl.lock); ++ if (i4Ret) ++ return i4Ret; ++ rHaltCtrl.owner = current; ++ rHaltCtrl.u4HoldStart = kalGetTimeTick(); ++ return 0; ++} ++ ++VOID kalHaltUnlock(VOID) ++{ ++ if (kalGetTimeTick() - rHaltCtrl.u4HoldStart > WLAN_OID_TIMEOUT_THRESHOLD * 2 && ++ rHaltCtrl.owner) ++ DBGLOG(INIT, ERROR, "process %s pid %d hold halt lock longer than 4s!\n", ++ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid); ++ rHaltCtrl.owner = NULL; ++ up(&rHaltCtrl.lock); ++} ++ ++VOID kalSetHalted(BOOLEAN fgHalt) ++{ ++ rHaltCtrl.fgHalt = fgHalt; ++} ++ ++BOOLEAN kalIsHalted(VOID) ++{ ++ return rHaltCtrl.fgHalt; ++} ++VOID kalPerMonDump(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, WARN, "ulPerfMonFlag:0x%lx\n", prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, WARN, "ulLastTxBytes:%ld\n", prPerMonitor->ulLastTxBytes); ++ DBGLOG(SW4, WARN, "ulLastRxBytes:%ld\n", prPerMonitor->ulLastRxBytes); ++ DBGLOG(SW4, WARN, "ulP2PLastTxBytes:%ld\n", prPerMonitor->ulP2PLastTxBytes); ++ DBGLOG(SW4, WARN, "ulP2PLastRxBytes:%ld\n", prPerMonitor->ulP2PLastRxBytes); ++ DBGLOG(SW4, WARN, "ulThroughput:%ld\n", prPerMonitor->ulThroughput); ++ DBGLOG(SW4, WARN, "u4UpdatePeriod:%d\n", prPerMonitor->u4UpdatePeriod); ++ DBGLOG(SW4, WARN, "u4TarPerfLevel:%d\n", prPerMonitor->u4TarPerfLevel); ++ DBGLOG(SW4, WARN, "u4CurrPerfLevel:%d\n", prPerMonitor->u4CurrPerfLevel); ++ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.tx_bytes); ++ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.rx_bytes); ++ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes); ++ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes); ++} ++ ++inline INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, INFO, "enter %s\n", __func__); ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) ++ DBGLOG(SW4, WARN, "abnormal, perf monitory already running\n"); ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ prPerMonitor->u4UpdatePeriod = 1000; ++ cnmTimerInitTimer(prGlueInfo->prAdapter, ++ &prPerMonitor->rPerfMonTimer, ++ (PFN_MGMT_TIMEOUT_FUNC) kalPerMonHandler, (ULONG) NULL); ++ DBGLOG(SW4, INFO, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ ++ DBGLOG(SW4, INFO, "enter %s\n", __func__); ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "need to stop before disable\n"); ++ kalPerMonStop(prGlueInfo); ++ } ++ KAL_SET_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, TRACE, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ ++ DBGLOG(SW4, INFO, "enter %s\n", __func__); ++ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, TRACE, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, TRACE, "enter %s\n", __func__); ++ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) ++ return 0; ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "perf monitor already running\n"); ++ return 0; ++ } ++ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); ++ KAL_SET_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ KAL_CLR_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, INFO, "perf monitor started\n"); ++ return 0; ++} ++ ++inline INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; ++ DBGLOG(SW4, TRACE, "enter %s\n", __func__); ++ ++ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "perf monitory disabled\n"); ++ return 0; ++ } ++ ++ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ DBGLOG(SW4, TRACE, "perf monitory already stopped\n"); ++ return 0; ++ } ++ ++ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ cnmTimerStopTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer); ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ prPerMonitor->ulLastRxBytes = 0; ++ prPerMonitor->ulLastTxBytes = 0; ++ prPerMonitor->ulP2PLastRxBytes = 0; ++ prPerMonitor->ulP2PLastTxBytes = 0; ++ prPerMonitor->ulThroughput = 0; ++ prPerMonitor->u4CurrPerfLevel = 0; ++ prPerMonitor->u4TarPerfLevel = 0; ++ /*Cancel CPU performance mode request*/ ++ kalBoostCpu(0); ++ } ++ DBGLOG(SW4, TRACE, "exit %s\n", __func__); ++ return 0; ++} ++ ++inline INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ kalPerMonDisable(prGlueInfo); ++ return 0; ++} ++ ++VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam) ++{ ++ /*Calculate current throughput*/ ++ struct GL_PER_MON_T *prPerMonitor; ++ ++ LONG latestTxBytes, latestRxBytes, txDiffBytes, rxDiffBytes; ++ LONG p2pLatestTxBytes, p2pLatestRxBytes, p2pTxDiffBytes, p2pRxDiffBytes; ++ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; ++ ++ if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) || (!prAdapter->fgIsP2PRegistered)) ++ return; ++ ++ prPerMonitor = &prAdapter->rPerMonitor; ++ DBGLOG(SW4, TRACE, "enter kalPerMonHandler\n"); ++ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, WARN, "perf monitory disabled, omit timeout event\n"); ++ return; ++ } ++ ++ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { ++ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); ++ DBGLOG(SW4, WARN, "perf monitory stopped, omit timeout event\n"); ++ return; ++ } ++ latestTxBytes = prGlueInfo->rNetDevStats.tx_bytes; ++ latestRxBytes = prGlueInfo->rNetDevStats.rx_bytes; ++ p2pLatestTxBytes = prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes; ++ p2pLatestRxBytes = prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes; ++ if (0 == prPerMonitor->ulLastRxBytes && ++ 0 == prPerMonitor->ulLastTxBytes && ++ 0 == prPerMonitor->ulP2PLastRxBytes && ++ 0 == prPerMonitor->ulP2PLastTxBytes) { ++ prPerMonitor->ulThroughput = 0; ++ } else { ++ txDiffBytes = latestTxBytes - prPerMonitor->ulLastTxBytes; ++ rxDiffBytes = latestRxBytes - prPerMonitor->ulLastRxBytes; ++ if (0 > txDiffBytes) ++ txDiffBytes = -(txDiffBytes); ++ if (0 > rxDiffBytes) ++ rxDiffBytes = -(rxDiffBytes); ++ ++ p2pTxDiffBytes = p2pLatestTxBytes - prPerMonitor->ulP2PLastTxBytes; ++ p2pRxDiffBytes = p2pLatestRxBytes - prPerMonitor->ulP2PLastRxBytes; ++ if (0 > p2pTxDiffBytes) ++ p2pTxDiffBytes = -(p2pTxDiffBytes); ++ if (0 > p2pRxDiffBytes) ++ p2pRxDiffBytes = -(p2pRxDiffBytes); ++ ++ prPerMonitor->ulThroughput = txDiffBytes + rxDiffBytes + p2pTxDiffBytes + p2pRxDiffBytes; ++ prPerMonitor->ulThroughput *= 1000; ++ prPerMonitor->ulThroughput /= prPerMonitor->u4UpdatePeriod; ++ prPerMonitor->ulThroughput <<= 3; ++ } ++ /*start the timer again to make sure we can cancel performance mode request in the end*/ ++ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); ++ ++ prPerMonitor->ulLastTxBytes = latestTxBytes; ++ prPerMonitor->ulLastRxBytes = latestRxBytes; ++ prPerMonitor->ulP2PLastTxBytes = p2pLatestTxBytes; ++ prPerMonitor->ulP2PLastRxBytes = p2pLatestRxBytes; ++ ++ if (prPerMonitor->ulThroughput < THROUGHPUT_L1_THRESHOLD) ++ prPerMonitor->u4TarPerfLevel = 0; ++ else if (prPerMonitor->ulThroughput < THROUGHPUT_L2_THRESHOLD) ++ prPerMonitor->u4TarPerfLevel = 1; ++ else if (prPerMonitor->ulThroughput < THROUGHPUT_L3_THRESHOLD) ++ prPerMonitor->u4TarPerfLevel = 2; ++ else ++ prPerMonitor->u4TarPerfLevel = 3; ++ if (prPerMonitor->u4TarPerfLevel != prPerMonitor->u4CurrPerfLevel) { ++ if (0 == prPerMonitor->u4TarPerfLevel) { ++ /*cancel CPU performance mode request*/ ++ kalPerMonStop(prGlueInfo); ++ } else{ ++ DBGLOG(SW4, TRACE, "throughput:%ld bps\n", prPerMonitor->ulThroughput); ++ /*adjust CPU core number to prPerMonitor->u4TarPerfLevel+1*/ ++ kalBoostCpu(prPerMonitor->u4TarPerfLevel+1); ++ /*start the timer again to make sure we can cancel performance mode request in the end*/ ++ cnmTimerStartTimer(prGlueInfo->prAdapter, ++ &prPerMonitor->rPerfMonTimer, ++ prPerMonitor->u4UpdatePeriod); ++ } ++ } ++ prPerMonitor->u4CurrPerfLevel = prPerMonitor->u4TarPerfLevel; ++ DBGLOG(SW4, TRACE, "exit kalPerMonHandler\n"); ++} ++ ++INT32 __weak kalBoostCpu(UINT_32 core_num) ++{ ++ DBGLOG(SW4, WARN, "enter weak kalBoostCpu, core_num:%d\n", core_num); ++ return 0; ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c +new file mode 100644 +index 000000000000..945a6c03978b +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c +@@ -0,0 +1,4672 @@ ++/* ++** Id: @(#) gl_p2p.c@@ ++*/ ++ ++/*! \file gl_p2p.c ++ \brief Main routines of Linux driver interface for Wi-Fi Direct ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_p2p.c ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 17 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 16 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** FPB from ALPS.JB to phase 2 release. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 01 09 2012 terry.wu ++ * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork ++ * cfg80211 integration for p2p network. ++ * ++ * 12 19 2011 terry.wu ++ * [WCXRP00001142] [Wi-Fi] [P2P Driver] XOR local admin bit to generate p2p net device MAC ++ * XOR local administrated bit to generate net device MAC of p2p network. ++ * ++ * 12 02 2011 yuche.tsai ++ * NULL ++ * Fix possible KE when unload p2p. ++ * ++ * 11 24 2011 yuche.tsai ++ * NULL ++ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Update RSSI link quality of P2P Network query method. (Bug fix) ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 16 2011 yuche.tsai ++ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. ++ * Avoid using work thread in set p2p multicast address callback. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix default device name issue. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service ++ * discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 11 07 2011 yuche.tsai ++ * NULL ++ * [ALPS 00087243] KE in worker thread. ++ * The multicast address list is scheduled in worker thread. ++ * Before the worker thread is excuted, if P2P is unloaded, a KE may occur. ++ * ++ * 10 26 2011 terry.wu ++ * [WCXRP00001066] [MT6620 Wi-Fi] [P2P Driver] Fix P2P Oid Issue ++ * Fix some P2P OID functions didn't raise its flag "fgIsP2pOid" issue. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * . ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * Support Channel Query. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 26 2011 yuche.tsai ++ * NULL ++ * Fix bug of parsing secondary device list type issue. ++ * ++ * 08 24 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Abort. ++ * ++ * 08 23 2011 yuche.tsai ++ * NULL ++ * Fix multicast address list issue of P2P. ++ * ++ * 08 22 2011 chinglan.wang ++ * NULL ++ * Fix invitation indication bug.. ++ * ++ * 08 16 2011 cp.wu ++ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence ++ * auto channel decision for 2.4GHz hot spot mode ++ * ++ * 08 16 2011 chinglan.wang ++ * NULL ++ * Add the group id information in the invitation indication. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 08 05 2011 yuche.tsai ++ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. ++ * Add Password ID check for quick connection. ++ * Also modify some connection policy. ++ * ++ * 07 18 2011 chinglan.wang ++ * NULL ++ * Add IOC_P2P_GO_WSC_IE (p2p capability). ++ * ++ * 06 14 2011 yuche.tsai ++ * NULL ++ * Add compile flag to disable persistent group support. ++ * ++ * 05 04 2011 chinglan.wang ++ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver ++ * . ++ * ++ * 05 02 2011 yuche.tsai ++ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. ++ * Clear formation flag after formation timeout. ++ * ++ * 04 22 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * . ++ * ++ * 04 21 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * 1. Revise P2P power mode setting. ++ * 2. Revise fast-PS for concurrent ++ * ++ * 04 19 2011 wh.su ++ * NULL ++ * Adding length check before doing WPA RSN IE parsing for scan results indicate. ++ * ++ * 04 14 2011 yuche.tsai ++ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. ++ * Connection flow refine for Sigma test. ++ * ++ * 04 08 2011 yuche.tsai ++ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. ++ * Add device discoverability support. ++ * ++ * 04 08 2011 george.huang ++ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode ++ * separate settings of P2P and AIS ++ * ++ * 04 07 2011 terry.wu ++ * [WCXRP00000619] [MT6620 Wi-Fi][Driver] fix kernel panic may occur when removing wlan ++ * Fix kernel panic may occur when removing wlan driver. ++ * ++ * 03 31 2011 wh.su ++ * [WCXRP00000614] [MT6620 Wi-Fi][Driver] P2P: Update beacon content while setting WSC IE ++ * Update the wsc ie to beacon content. ++ * ++ * 03 25 2011 wh.su ++ * NULL ++ * add the sample code for set power mode and get power mode. ++ * ++ * 03 25 2011 yuche.tsai ++ * NULL ++ * Improve some error handleing. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 22 2011 yuche.tsai ++ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. ++ * Modify formation policy. ++ * ++ * 03 22 2011 yuche.tsai ++ * NULL ++ * Modify formation policy setting. ++ * ++ * 03 18 2011 yuche.tsai ++ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow ++ * Modify connection flow after Group Formation Complete, or device connect to a GO. ++ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. ++ * ++ * 03 15 2011 wh.su ++ * [WCXRP00000563] [MT6620 Wi-Fi] [P2P] Set local config method while set password Id ready ++ * set lccal config method method while set password Id ready. ++ * ++ * 03 15 2011 yuche.tsai ++ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue ++ * Fix some configure method issue. ++ * ++ * 03 15 2011 jeffrey.chang ++ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM ++ * refine queue_select function ++ * ++ * 03 13 2011 wh.su ++ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done ++ * add code for avoid compiling warning. ++ * ++ * 03 10 2011 yuche.tsai ++ * NULL ++ * Add P2P API. ++ * ++ * 03 10 2011 terry.wu ++ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration ++ * Remove unnecessary assert and message. ++ * ++ * 03 08 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * support the power save related p2p setting. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify P2P's netdevice functions to support multiple H/W queues ++ * ++ * 03 03 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * for get request, the buffer length to be copied is header + payload. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add code to let the beacon and probe response for Auto GO WSC . ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * add a missed break. ++ * ++ * 03 01 2011 yuche.tsai ++ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation ++ * Update channel issue when doing GO formation.. ++ * ++ * 02 25 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * add the Operation channel setting. ++ * ++ * 02 23 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * fixed the set int ioctl set index and value map to driver issue. ++ * ++ * 02 22 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * adding the ioctl set int from supplicant, and can used to set the p2p parameters ++ * ++ * 02 21 2011 terry.wu ++ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P ++ * Clean P2P scan list while removing P2P. ++ * ++ * 02 18 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * fixed the ioctl setting that index not map to spec defined config method. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE ++ * append the WSC IE config method attribute at provision discovery request. ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * modify the structure pointer for set WSC IE. ++ * ++ * 02 16 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * fixed the probe request send out without WSC IE issue (at P2P). ++ * ++ * 02 09 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * fix typo ++ * ++ * 02 09 2011 yuche.tsai ++ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. ++ * Add Support for MLME deauthentication for Hot-Spot. ++ * ++ * 01 25 2011 terry.wu ++ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter ++ * Add a new module parameter to indicate current runnig mode, P2P or AP. ++ * ++ * 01 12 2011 yuche.tsai ++ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue ++ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. ++ * 2. Call cnmP2pIsPermit() before active P2P network. ++ * 3. Add channel selection support for AP mode. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 12 15 2010 cp.wu ++ * NULL ++ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() ++ * ++ * 12 08 2010 yuche.tsai ++ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in ++ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 17 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] Set the Tx ++ * lowest rate at wlan table for normal operation ++ * fixed some ASSERT check. ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * add a kal function for set cipher. ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * fixed compiling error while enable p2p. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 10 2010 george.huang ++ * NULL ++ * update iwpriv LP related ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at win XP. ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 20 2010 cp.wu ++ * NULL ++ * correct typo. ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Invert Connection request provision status parameter. ++ * ++ * 08 19 2010 cp.wu ++ * NULL ++ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. ++ * ++ * 08 18 2010 cp.wu ++ * NULL ++ * modify pwp ioctls attribution by removing FIXED_SIZE. ++ * ++ * 08 18 2010 jeffrey.chang ++ * NULL ++ * support multi-function sdio ++ * ++ * 08 17 2010 cp.wu ++ * NULL ++ * correct p2p net device registration with NULL pointer access issue. ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * add subroutines for P2P to set multicast list. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * add wext handlers to link P2P set PS profile/ network address function (TBD) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * revised implementation of Wi-Fi Direct io controls. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * follow-up with ioctl interface update for Wi-Fi Direct application ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * add basic support for ioctl of getting scan result. (only address and SSID are reporterd though) ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * surpress compilation warning. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 23 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * p2p interface revised to be sync. with HAL ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl to configure scan mode for p2p connection ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement private io controls for Wi-Fi Direct ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement get scan result. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * 1) add timeout handler mechanism for pending command packets ++ * 2) add p2p add/removal key ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement wireless extension ioctls in iw_handler form. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++ ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "gl_p2p_os.h" ++#include "gl_p2p_ioctl.h" ++#include "gl_vendor.h" ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define ARGV_MAX_NUM (4) ++ ++/*For CFG80211 - wiphy parameters*/ ++#define MAX_SCAN_LIST_NUM (1) ++#define MAX_SCAN_IE_LEN (512) ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++static struct cfg80211_ops mtk_p2p_ops = { ++ .change_virtual_intf = mtk_p2p_cfg80211_change_iface, /* 1st */ ++ .change_bss = mtk_p2p_cfg80211_change_bss, ++ .scan = mtk_p2p_cfg80211_scan, ++ .remain_on_channel = mtk_p2p_cfg80211_remain_on_channel, ++ .cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel, ++ .mgmt_tx = mtk_p2p_cfg80211_mgmt_tx, ++ .connect = mtk_p2p_cfg80211_connect, ++ .disconnect = mtk_p2p_cfg80211_disconnect, ++ .deauth = mtk_p2p_cfg80211_deauth, ++ .disassoc = mtk_p2p_cfg80211_disassoc, ++ .start_ap = mtk_p2p_cfg80211_start_ap, ++ .change_beacon = mtk_p2p_cfg80211_change_beacon, ++ .stop_ap = mtk_p2p_cfg80211_stop_ap, ++ .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params, ++ .del_station = mtk_p2p_cfg80211_del_station, ++ .set_monitor_channel = mtk_p2p_cfg80211_set_channel, ++ .set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask, ++ .mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register, ++ .get_station = mtk_p2p_cfg80211_get_station, ++ .add_key = mtk_p2p_cfg80211_add_key, ++ .get_key = mtk_p2p_cfg80211_get_key, ++ .del_key = mtk_p2p_cfg80211_del_key, ++ .set_default_key = mtk_p2p_cfg80211_set_default_key, ++ .join_ibss = mtk_p2p_cfg80211_join_ibss, ++ .leave_ibss = mtk_p2p_cfg80211_leave_ibss, ++ .set_tx_power = mtk_p2p_cfg80211_set_txpower, ++ .get_tx_power = mtk_p2p_cfg80211_get_txpower, ++ .set_power_mgmt = mtk_p2p_cfg80211_set_power_mgmt, ++#ifdef CONFIG_NL80211_TESTMODE ++ .testmode_cmd = mtk_p2p_cfg80211_testmode_cmd, ++#endif ++}; ++ ++static const struct wiphy_vendor_command mtk_p2p_vendor_ops[] = { ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_get_channel_list ++ }, ++ { ++ { ++ .vendor_id = GOOGLE_OUI, ++ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE ++ }, ++ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, ++ .doit = mtk_cfg80211_vendor_set_country_code ++ }, ++}; ++ ++/* There isn't a lot of sense in it, but you can transmit anything you like */ ++static const struct ieee80211_txrx_stypes ++ mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { ++ [NL80211_IFTYPE_ADHOC] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_STATION] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_AP] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_AP_VLAN] = { ++ /* copy AP */ ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | ++ BIT(IEEE80211_STYPE_DISASSOC >> 4) | ++ BIT(IEEE80211_STYPE_AUTH >> 4) | ++ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_CLIENT] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_P2P_GO] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) ++ } ++}; ++ ++#endif ++ ++/* the legacy wireless extension stuff */ ++static const iw_handler rP2PIwStandardHandler[] = { ++ [SIOCGIWPRIV - SIOCIWFIRST] = mtk_p2p_wext_get_priv, ++ [SIOCGIWSCAN - SIOCIWFIRST] = mtk_p2p_wext_discovery_results, ++ [SIOCSIWESSID - SIOCIWFIRST] = mtk_p2p_wext_reconnect, ++ [SIOCSIWAUTH - SIOCIWFIRST] = mtk_p2p_wext_set_auth, ++ [SIOCSIWENCODEEXT - SIOCIWFIRST] = mtk_p2p_wext_set_key, ++ [SIOCSIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_set_powermode, ++ [SIOCGIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_get_powermode, ++ [SIOCSIWTXPOW - SIOCIWFIRST] = mtk_p2p_wext_set_txpow, ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ [SIOCGIWSTATS - SIOCIWFIRST] = mtk_p2p_wext_get_rssi, ++#endif ++ [SIOCSIWMLME - SIOCIWFIRST] = mtk_p2p_wext_mlme_handler, ++}; ++ ++static const iw_handler rP2PIwPrivHandler[] = { ++ [IOC_P2P_CFG_DEVICE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_local_dev_info, ++ [IOC_P2P_PROVISION_COMPLETE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_provision_complete, ++ [IOC_P2P_START_STOP_DISCOVERY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_start_stop_discovery, ++ [IOC_P2P_DISCOVERY_RESULTS - SIOCIWFIRSTPRIV] = mtk_p2p_wext_discovery_results, ++ [IOC_P2P_WSC_BEACON_PROBE_RSP_IE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_wsc_ie, ++ [IOC_P2P_CONNECT_DISCONNECT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_connect_disconnect, ++ [IOC_P2P_PASSWORD_READY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_password_ready, ++/* [IOC_P2P_SET_PWR_MGMT_PARAM - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_pm_param, */ ++ [IOC_P2P_SET_INT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_int, ++ [IOC_P2P_GET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_get_struct, ++ [IOC_P2P_SET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_struct, ++ [IOC_P2P_GET_REQ_DEVICE_INFO - SIOCIWFIRSTPRIV] = mtk_p2p_wext_request_dev_info, ++}; ++ ++static const struct iw_priv_args rP2PIwPrivTable[] = { ++ { ++ .cmd = IOC_P2P_CFG_DEVICE, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CFG_DEVICE_TYPE), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_CFG_DEVICE"} ++ , ++ { ++ .cmd = IOC_P2P_START_STOP_DISCOVERY, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_REQ_DEVICE_TYPE), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_DISCOVERY"} ++ , ++ { ++ .cmd = IOC_P2P_DISCOVERY_RESULTS, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_RESULT"} ++ , ++ { ++ .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_HOSTAPD_PARAM), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_WSC_IE"} ++ , ++ { ++ .cmd = IOC_P2P_CONNECT_DISCONNECT, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CONNECT_DEVICE), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_CONNECT"} ++ , ++ { ++ .cmd = IOC_P2P_PASSWORD_READY, ++ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_PASSWORD_READY), ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_PASSWD_RDY"} ++ , ++ { ++ .cmd = IOC_P2P_GET_STRUCT, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = 256, ++ .name = "P2P_GET_STRUCT"} ++ , ++ { ++ .cmd = IOC_P2P_SET_STRUCT, ++ .set_args = 256, ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "P2P_SET_STRUCT"} ++ , ++ { ++ .cmd = IOC_P2P_GET_REQ_DEVICE_INFO, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_DEVICE_REQ), ++ .name = "P2P_GET_REQDEV"} ++ , ++ { ++ /* SET STRUCT sub-ioctls commands */ ++ .cmd = PRIV_CMD_OID, ++ .set_args = 256, ++ .get_args = IW_PRIV_TYPE_NONE, ++ .name = "set_oid"} ++ , ++ { ++ /* GET STRUCT sub-ioctls commands */ ++ .cmd = PRIV_CMD_OID, ++ .set_args = IW_PRIV_TYPE_NONE, ++ .get_args = 256, ++ .name = "get_oid"} ++}; ++ ++const struct iw_handler_def mtk_p2p_wext_handler_def = { ++ .num_standard = (__u16) sizeof(rP2PIwStandardHandler) / sizeof(iw_handler), ++ .num_private = (__u16) sizeof(rP2PIwPrivHandler) / sizeof(iw_handler), ++ .num_private_args = (__u16) sizeof(rP2PIwPrivTable) / sizeof(struct iw_priv_args), ++ .standard = rP2PIwStandardHandler, ++ .private = rP2PIwPrivHandler, ++ .private_args = rP2PIwPrivTable, ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ .get_wireless_stats = mtk_p2p_wext_get_wireless_stats, ++#else ++ .get_wireless_stats = NULL, ++#endif ++}; ++ ++#ifdef CONFIG_PM ++static const struct wiphy_wowlan_support p2p_wowlan_support = { ++ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, ++}; ++#endif ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* for IE Searching */ ++extern BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++ ++#if CFG_SUPPORT_WPS ++extern BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++/* Net Device Hooks */ ++static int p2pOpen(IN struct net_device *prDev); ++ ++static int p2pStop(IN struct net_device *prDev); ++ ++static struct net_device_stats *p2pGetStats(IN struct net_device *prDev); ++ ++static void p2pSetMulticastList(IN struct net_device *prDev); ++ ++static int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev); ++ ++static int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd); ++ ++static int p2pSetMACAddress(IN struct net_device *prDev, void *addr); ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Override the implementation of select queue ++* ++* \param[in] dev Pointer to struct net_device ++* \param[in] skb Pointer to struct skb_buff ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++unsigned int _p2p_cfg80211_classify8021d(struct sk_buff *skb) ++{ ++ unsigned int dscp = 0; ++ ++ /* skb->priority values from 256->263 are magic values ++ * directly indicate a specific 802.1d priority. This is ++ * to allow 802.1d priority to be passed directly in from ++ * tags ++ */ ++ ++ if (skb->priority >= 256 && skb->priority <= 263) ++ return skb->priority - 256; ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ dscp = ip_hdr(skb)->tos & 0xfc; ++ break; ++ } ++ return dscp >> 5; ++} ++ ++static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; ++ ++static UINT_16 p2pSelectQueue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev, ++ select_queue_fallback_t fallback) ++{ ++ skb->priority = _p2p_cfg80211_classify8021d(skb); ++ ++ return au16Wlan1dToQueueIdx[skb->priority]; ++} ++ ++static struct net_device *g_P2pPrDev; ++static struct wireless_dev *gprP2pWdev; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->init ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \retval 0 The execution of wlanInit succeeds. ++* \retval -ENXIO No such device. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int p2pInit(struct net_device *prDev) ++{ ++/* P_GLUE_INFO_T prGlueInfo; */ ++ if (!prDev) ++ return -ENXIO; ++ ++ DBGLOG(P2P, INFO, "dev name=%s\n", prDev->name); ++ return 0; /* success */ ++} /* end of p2pInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A function for prDev->uninit ++* ++* \param[in] prDev Pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++static void p2pUninit(IN struct net_device *prDev) ++{ ++ ++} /* end of p2pUninit() */ ++ ++static const struct net_device_ops p2p_netdev_ops = { ++ .ndo_open = p2pOpen, ++ .ndo_stop = p2pStop, ++ .ndo_set_mac_address = p2pSetMACAddress, ++ .ndo_set_rx_mode = p2pSetMulticastList, ++ .ndo_get_stats = p2pGetStats, ++ .ndo_do_ioctl = p2pDoIOCTL, ++ .ndo_start_xmit = p2pHardStartXmit, ++ .ndo_select_queue = p2pSelectQueue, ++ .ndo_init = p2pInit, ++ .ndo_uninit = p2pUninit, ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS ++* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2PAllocInfo(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_WIFI_VAR_T prWifiVar = NULL; ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ prWifiVar = &(prAdapter->rWifiVar); ++ ++ if (!prWifiVar) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ do { ++ if (prGlueInfo->prP2PInfo == NULL) { ++ /*alloc memory for p2p info */ ++ prGlueInfo->prP2PInfo = kalMemAlloc(sizeof(GL_P2P_INFO_T), VIR_MEM_TYPE); ++ prAdapter->prP2pInfo = kalMemAlloc(sizeof(P2P_INFO_T), VIR_MEM_TYPE); ++ prWifiVar->prP2PConnSettings = kalMemAlloc(sizeof(P2P_CONNECTION_SETTINGS_T), VIR_MEM_TYPE); ++ prWifiVar->prP2pFsmInfo = kalMemAlloc(sizeof(P2P_FSM_INFO_T), VIR_MEM_TYPE); ++ prWifiVar->prP2pSpecificBssInfo = kalMemAlloc(sizeof(P2P_SPECIFIC_BSS_INFO_T), VIR_MEM_TYPE); ++ } else { ++ ASSERT(prAdapter->prP2pInfo != NULL); ++ ASSERT(prWifiVar->prP2PConnSettings != NULL); ++ ASSERT(prWifiVar->prP2pFsmInfo != NULL); ++ ASSERT(prWifiVar->prP2pSpecificBssInfo != NULL); ++ } ++ /*MUST set memory to 0 */ ++ if (prGlueInfo->prP2PInfo) ++ kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T)); ++ if (prAdapter->prP2pInfo) ++ kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T)); ++ if (prWifiVar->prP2PConnSettings) ++ kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T)); ++ if (prWifiVar->prP2pFsmInfo) ++ kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T)); ++ if (prWifiVar->prP2pSpecificBssInfo) ++ kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T)); ++ ++ } while (FALSE); ++ ++ /* chk if alloc successful or not */ ++ if (prGlueInfo->prP2PInfo && ++ prAdapter->prP2pInfo && ++ prWifiVar->prP2PConnSettings && prWifiVar->prP2pFsmInfo && prWifiVar->prP2pSpecificBssInfo) { ++ return TRUE; ++ } ++ ++ if (prWifiVar->prP2pSpecificBssInfo) { ++ kalMemFree(prWifiVar->prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T)); ++ ++ prWifiVar->prP2pSpecificBssInfo = NULL; ++ } ++ if (prWifiVar->prP2pFsmInfo) { ++ kalMemFree(prWifiVar->prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); ++ ++ prWifiVar->prP2pFsmInfo = NULL; ++ } ++ if (prWifiVar->prP2PConnSettings) { ++ kalMemFree(prWifiVar->prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T)); ++ ++ prWifiVar->prP2PConnSettings = NULL; ++ } ++ if (prGlueInfo->prP2PInfo) { ++ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); ++ ++ prGlueInfo->prP2PInfo = NULL; ++ } ++ if (prAdapter->prP2pInfo) { ++ kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); ++ ++ prAdapter->prP2pInfo = NULL; ++ } ++ return FALSE; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS ++* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo) ++{ ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ /* free memory after p2p module is ALREADY unregistered */ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { ++ ++ kalMemFree(prGlueInfo->prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); ++ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); ++ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings, VIR_MEM_TYPE, ++ sizeof(P2P_CONNECTION_SETTINGS_T)); ++ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); ++ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo, VIR_MEM_TYPE, ++ sizeof(P2P_SPECIFIC_BSS_INFO_T)); ++ ++ /*Reomve p2p bss scan list */ ++ scanRemoveAllP2pBssDesc(prGlueInfo->prAdapter); ++ ++ /*reset all pointer to NULL */ ++ prGlueInfo->prP2PInfo = NULL; ++ prGlueInfo->prAdapter->prP2pInfo = NULL; ++ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings = NULL; ++ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo = NULL; ++ prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo = NULL; ++ ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++ ++} ++ ++#if !CFG_SUPPORT_PERSIST_NETDEV ++BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) ++{ ++ BOOLEAN fgDoRegister = FALSE; ++/* BOOLEAN fgRollbackRtnlLock = FALSE; */ ++ BOOLEAN ret; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) { ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERING; ++ fgDoRegister = TRUE; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (!fgDoRegister) ++ return TRUE; ++ ++ /* net device initialize */ ++ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); ++ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ /* register for net device */ ++ if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) { ++ DBGLOG(P2P, WARN, "unable to register netdevice for p2p\n"); ++ ++ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ ret = FALSE; ++ } else { ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERED; ++ ret = TRUE; ++ } ++ return ret; ++} ++ ++BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) ++{ ++ BOOLEAN fgDoUnregister = FALSE; ++/* BOOLEAN fgRollbackRtnlLock = FALSE; */ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) { ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING; ++ fgDoUnregister = TRUE; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (!fgDoUnregister) ++ return TRUE; ++ ++ /* prepare for removal */ ++ if (netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) ++ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); ++ DBGLOG(P2P, INFO, "P2P unregister_netdev 0x%p\n", prGlueInfo->prP2PInfo->prDevHandler); ++ unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler); ++ ++ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; ++ ++ return TRUE; ++} ++#endif ++ ++BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo) ++{ ++ struct wiphy *prWiphy = NULL; ++ struct wireless_dev *prWdev = NULL; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ struct net_device *prNetDev = NULL; ++#endif ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); ++ if (!prWdev) { ++ DBGLOG(P2P, ERROR, "allocate p2p wireless device fail, no memory\n"); ++ return FALSE; ++ } ++ /* 1. allocate WIPHY */ ++ prWiphy = wiphy_new(&mtk_p2p_ops, sizeof(P_GLUE_INFO_T)); ++ if (!prWiphy) { ++ DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n"); ++ goto free_wdev; ++ } ++ ++ prWiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_STATION); ++ ++ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; ++ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; ++ ++ prWiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes; ++ prWiphy->max_remain_on_channel_duration = 5000; ++ prWiphy->cipher_suites = mtk_cipher_suites; ++ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); ++ prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_HAVE_AP_SME; ++ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; ++ prWiphy->ap_sme_capa = 1; ++ ++ prWiphy->max_scan_ssids = MAX_SCAN_LIST_NUM; ++ prWiphy->max_scan_ie_len = MAX_SCAN_IE_LEN; ++ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; ++ prWiphy->vendor_commands = mtk_p2p_vendor_ops; ++ prWiphy->n_vendor_commands = sizeof(mtk_p2p_vendor_ops) / sizeof(struct wiphy_vendor_command); ++ ++#ifdef CONFIG_PM ++ prWiphy->wowlan = &p2p_wowlan_support; ++#endif ++ ++ /* 2.1 set priv as pointer to glue structure */ ++ *((P_GLUE_INFO_T *) wiphy_priv(prWiphy)) = prGlueInfo; ++ if (wiphy_register(prWiphy) < 0) { ++ DBGLOG(P2P, ERROR, "fail to register wiphy for p2p\n"); ++ goto free_wiphy; ++ } ++ prWdev->wiphy = prWiphy; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* 3. allocate netdev */ ++ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), P2P_MODE_INF_NAME, NET_NAME_PREDICTABLE, ++ ether_setup, CFG_MAX_TXQ_NUM); ++ if (!prNetDev) { ++ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); ++ goto unregister_wiphy; ++ } ++ ++ /* 4. setup netdev */ ++ /* 4.1 Point to shared glue structure */ ++ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = prGlueInfo; ++ ++ /* 4.2 fill hardware address */ ++ /* COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); ++ rMacAddr[0] ^= 0x2; // change to local administrated address ++ memcpy(prGlueInfo->prP2PInfo->prDevHandler->dev_addr, rMacAddr, ETH_ALEN); ++ memcpy(prGlueInfo->prP2PInfo->prDevHandler->perm_addr, ++ prGlueInfo->prP2PInfo->prDevHandler->dev_addr, ETH_ALEN);*/ ++ ++ /* 4.3 register callback functions */ ++ prNetDev->netdev_ops = &p2p_netdev_ops; ++ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def;*/ ++ ++ prNetDev->ieee80211_ptr = prWdev; ++ prWdev->netdev = prNetDev; ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prNetDev->features = NETIF_F_IP_CSUM; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ /* net device initialize */ ++ netif_carrier_off(prNetDev); ++ netif_tx_stop_all_queues(prNetDev); ++ ++ /* register for net device */ ++ if (register_netdev(prNetDev) < 0) { ++ DBGLOG(P2P, ERROR, "unable to register netdevice for p2p\n"); ++ free_netdev(prNetDev); ++ goto unregister_wiphy; ++ } ++#endif ++ gprP2pWdev = prWdev; ++ return TRUE; ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++unregister_wiphy: ++ wiphy_unregister(prWiphy); ++#endif ++free_wiphy: ++ wiphy_free(prWiphy); ++free_wdev: ++ kfree(prWdev); ++#endif ++ return FALSE; ++} ++ ++void glP2pDestroyWirelessDevice(VOID) ++{ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#if CFG_SUPPORT_PERSIST_NETDEV ++ unregister_netdev(gprP2pWdev->netdev); ++ free_netdev(gprP2pWdev->netdev); ++#endif ++ wiphy_unregister(gprP2pWdev->wiphy); ++ wiphy_free(gprP2pWdev->wiphy); ++ kfree(gprP2pWdev); ++ gprP2pWdev = NULL; ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Register for cfg80211 for Wi-Fi Direct ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GL_HIF_INFO_T prHif = NULL; ++ PARAM_MAC_ADDRESS rMacAddr; ++ struct net_device *prDevHandler = NULL; ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ struct device *prDev; ++#endif ++ ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prHif = &prGlueInfo->rHifInfo; ++ ASSERT(prHif); ++ ++ DBGLOG(P2P, TRACE, "glRegisterP2P\n"); ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ if (!gprP2pWdev) { ++ DBGLOG(P2P, ERROR, "gl_p2p, wireless device is not exist\n"); ++ return FALSE; ++ } ++#endif ++ /*0. allocate p2pinfo */ ++ if (!p2PAllocInfo(prGlueInfo)) { ++ DBGLOG(P2P, ERROR, "Allocate memory for p2p FAILED\n"); ++ ASSERT(0); ++ return FALSE; ++ } ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ prGlueInfo->prP2PInfo->prWdev = gprP2pWdev; ++ /* 1. fill wiphy parameters */ ++#if MTK_WCN_HIF_SDIO ++ mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev); ++ if (!prDev) ++ DBGLOG(P2P, WARN, "unable to get struct dev for p2p\n"); ++#else ++ prDev = prHif->Dev; ++#endif ++ /*set_wiphy_dev(gprP2pWdev->wiphy, prDev);*/ ++ if (!prGlueInfo->prAdapter->fgEnable5GBand) ++ gprP2pWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; ++ ++ /* 2 set priv as pointer to glue structure */ ++ *(P_GLUE_INFO_T *) wiphy_priv(gprP2pWdev->wiphy) = prGlueInfo; ++ ++ if (fgIsApMode) { ++ gprP2pWdev->iftype = NL80211_IFTYPE_AP; ++#if CFG_SUPPORT_PERSIST_NETDEV ++ if (kalStrnCmp(gprP2pWdev->netdev->name, AP_MODE_INF_NAME, 2)) { ++ rtnl_lock(); ++ dev_change_name(gprP2pWdev->netdev->name, AP_MODE_INF_NAME); ++ rtnl_unlock(); ++ } ++#endif ++ } else { ++#if CFG_SUPPORT_PERSIST_NETDEV ++ if (kalStrnCmp(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME, 3)) { ++ rtnl_lock(); ++ dev_change_name(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME); ++ rtnl_unlock(); ++ } ++#endif ++ gprP2pWdev->iftype = NL80211_IFTYPE_P2P_CLIENT; ++ } ++#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ prP2PInfo->prDevHandler = gprP2pWdev->netdev; ++#else /* CFG_SUPPORT_PERSIST_NETDEV */ ++ /* 3. allocate netdev */ ++ prDevHandler = ++ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); ++ if (!prDevHandler) { ++ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); ++ return FALSE; ++ } ++ prGlueInfo->prP2PInfo->prDevHandler = prDevHandler; ++ /* 4. setup netdev */ ++ /* 4.1 Point to shared glue structure */ ++ *((P_GLUE_INFO_T *) netdev_priv(prDevHandler)) = prGlueInfo; ++ ++ /* 4.2 fill hardware address */ ++ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); ++ rMacAddr[0] ^= 0x2; /* change to local administrated address */ ++ ether_addr_copy(prDevHandler->dev_addr, rMacAddr); ++ ether_addr_copy(prDevHandler->perm_addr, prDevHandler->dev_addr); ++ ++ /* 4.3 register callback functions */ ++ prDevHandler->netdev_ops = &p2p_netdev_ops; ++ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def; */ ++ ++#if (MTK_WCN_HIF_SDIO == 0) ++ SET_NETDEV_DEV(prDevHandler, prHif->Dev); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ prDevHandler->ieee80211_ptr = gprP2pWdev; ++ gprP2pWdev->netdev = prDevHandler; ++#endif ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ prDevHandler->features = NETIF_F_IP_CSUM; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++#endif /* CFG_SUPPORT_PERSIST_NETDEV */ ++ ++ /* 5. set p2p net device register state */ ++ prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; ++ ++ /* 6. setup running mode */ ++ prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode; ++ ++ /* 7. finish */ ++ p2pFsmInit(prAdapter); ++ ++ p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings); ++ ++ /* Active network too early would cause HW not able to sleep. ++ * Defer the network active time. ++ */ ++/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ ++ ++ return TRUE; ++} /* end of glRegisterP2P() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Unregister Net Device for Wi-Fi Direct ++* ++* \param[in] prGlueInfo Pointer to glue info ++* ++* \return TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ /* normal flow: this func will called first before wlanRemove, and it can do fsmUninit/deactivateNetwork ++ gracefully. */ ++ /* when reset: because tx_thread with fw has stopped, so it can't do these job and the recovery will be ++ dependent on chip system reset. */ ++ /* if so, just skip it by flag GLUE_FLAG_HALT(warning: when tx_thread was stop, this flag was not cleared, ++ and NEED TO KEEP IT NOT CLEARED!). */ ++ if (!(prGlueInfo->ulFlag & GLUE_FLAG_HALT)) { ++ p2pFsmUninit(prGlueInfo->prAdapter); ++ nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); ++ } ++#if CFG_SUPPORT_PERSIST_NETDEV ++ dev_close(prGlueInfo->prP2PInfo->prDevHandler); ++#else ++ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); ++ prGlueInfo->prP2PInfo->prDevHandler = NULL; ++#endif ++ /* Free p2p memory */ ++ if (!p2PFreeInfo(prGlueInfo)) { ++ DBGLOG(P2P, ERROR, "Free memory for p2p FAILED\n"); ++ ASSERT(0); ++ return FALSE; ++ } ++ return TRUE; ++} /* end of glUnregisterP2P() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for stop p2p fsm immediate ++ * ++ * \param[in] prGlueInfo Pointer to struct P_GLUE_INFO_T. ++ * ++ * \retval TRUE The execution succeeds. ++ * \retval FALSE The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo) ++{ ++/* P_ADAPTER_T prAdapter = NULL; */ ++/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ ++ ++ ASSERT(prGlueInfo); ++ ++/* prAdapter = prGlueInfo->prAdapter; */ ++/* ASSERT(prAdapter); */ ++ ++ /* 1. stop TX queue */ ++ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); ++ ++#if 0 ++ /* 2. switch P2P-FSM off */ ++ /* 2.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ DBGLOG(P2P, ERROR, "Allocate for p2p mesasage FAILED\n"); ++ /* return -ENOMEM; */ ++ } ++ ++ /* 2.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = FALSE; ++ ++ /* 2.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_UNBUF); ++ ++#endif ++ ++ /* 3. stop queue and turn off carrier */ ++ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; ++ ++ return TRUE; ++} /* end of p2pStop() */ ++ ++/* Net Device Hooks */ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device open (ifup) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int p2pOpen(IN struct net_device *prDev) ++{ ++/* P_GLUE_INFO_T prGlueInfo = NULL; */ ++/* P_ADAPTER_T prAdapter = NULL; */ ++/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ ++ ++ ASSERT(prDev); ++ ++#if 0 /* Move after device name set. (mtk_p2p_set_local_dev_info) */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* 1. switch P2P-FSM on */ ++ /* 1.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = TRUE; ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ ++ /* 2. carrier on & start TX queue */ ++ netif_carrier_on(prDev); ++ netif_tx_start_all_queues(prDev); ++ ++ return 0; /* success */ ++} /* end of p2pOpen() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A function for net_device stop (ifdown) ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \retval 0 The execution succeeds. ++ * \retval < 0 The execution failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++static int p2pStop(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ /* P_ADAPTER_T prAdapter = NULL; */ ++/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ struct cfg80211_scan_info info = { ++ .aborted = true, ++ }; ++ ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ASSERT(prGlueP2pInfo); ++ ++ /* CFG80211 down */ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueP2pInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueP2pInfo->prScanRequest; ++ prGlueP2pInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ if (prScanRequest) ++ cfg80211_scan_done(prScanRequest, &info); ++#if 0 ++ ++ /* 1. stop TX queue */ ++ netif_tx_stop_all_queues(prDev); ++ ++ /* 2. switch P2P-FSM off */ ++ /* 2.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 2.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = FALSE; ++ ++ /* 2.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ /* 3. stop queue and turn off carrier */ ++ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; ++ ++ netif_tx_stop_all_queues(prDev); ++ if (netif_carrier_ok(prDev)) ++ netif_carrier_off(prDev); ++ ++ return 0; ++} /* end of p2pStop() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A method of struct net_device, to get the network interface statistical ++ * information. ++ * ++ * Whenever an application needs to get statistics for the interface, this method ++ * is called. This happens, for example, when ifconfig or netstat -i is run. ++ * ++ * \param[in] prDev Pointer to struct net_device. ++ * ++ * \return net_device_stats buffer pointer. ++ */ ++/*----------------------------------------------------------------------------*/ ++struct net_device_stats *p2pGetStats(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++#if CFG_SUPPORT_PERSIST_NETDEV ++ /* @FIXME */ ++ /* prDev->stats.rx_packets = 0; */ ++ /* prDev->stats.tx_packets = 0; */ ++ prDev->stats.tx_errors = 0; ++ prDev->stats.rx_errors = 0; ++ /* prDev->stats.rx_bytes = 0; */ ++ /* prDev->stats.tx_bytes = 0; */ ++ prDev->stats.multicast = 0; ++ ++ return &prDev->stats; ++ ++#else ++ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_packets = 0; */ ++ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_packets = 0; */ ++ prGlueInfo->prP2PInfo->rNetDevStats.tx_errors = 0; ++ prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; ++ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes = 0; */ ++ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes = 0; */ ++ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; */ ++ prGlueInfo->prP2PInfo->rNetDevStats.multicast = 0; ++ ++ return &prGlueInfo->prP2PInfo->rNetDevStats; ++#endif ++} /* end of p2pGetStats() */ ++ ++static void p2pSetMulticastList(IN struct net_device *prDev) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ if (!prDev || !prGlueInfo) { ++ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); ++ return; ++ } ++ ++ g_P2pPrDev = prDev; ++ ++ /* 4 Mark HALT, notify main thread to finish current job */ ++/* prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_MULTICAST; */ ++ set_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++} /* p2pSetMulticastList */ ++ ++/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange ++ * another workqueue for sleeping. We don't want to block ++ * tx_thread, so we can't let tx_thread to do this */ ++ ++void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo) ++{ ++ if (!prGlueInfo) { ++ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); ++ return; ++ } ++#if CFG_ENABLE_WIFI_DIRECT ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered) ++ mtk_p2p_wext_set_Multicastlist(prGlueInfo); ++#endif ++} /* end of p2pSetMulticastListWorkQueueWrapper() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief This function is to set multicast list and set rx mode. ++ * ++ * \param[in] prDev Pointer to struct net_device ++ * ++ * \return (none) ++ */ ++/*----------------------------------------------------------------------------*/ ++void mtk_p2p_wext_set_Multicastlist(P_GLUE_INFO_T prGlueInfo) ++{ ++ UINT_32 u4SetInfoLen = 0; ++ struct net_device *prDev = g_P2pPrDev; ++ ++ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; ++ ++ ASSERT(prDev); ++ ASSERT(prGlueInfo); ++ if (!prDev || !prGlueInfo) { ++ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); ++ return; ++ } ++ ++ if (prDev->flags & IFF_PROMISC) ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; ++ ++ if (prDev->flags & IFF_BROADCAST) ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; ++ ++ if (prDev->flags & IFF_MULTICAST) { ++ if ((prDev->flags & IFF_ALLMULTI) || ++ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; ++ } else { ++ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; ++ } ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { ++ /* Prepare multicast address list */ ++ struct netdev_hw_addr *ha; ++ UINT_32 i = 0; ++ ++ netdev_for_each_mc_addr(ha, prDev) { ++ if (i < MAX_NUM_GROUP_ADDR) { ++ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr); ++ i++; ++ } ++ } ++ ++ DBGLOG(P2P, TRACE, "SEt Multicast Address List\n"); ++ ++ if (i >= MAX_NUM_GROUP_ADDR) ++ return; ++ wlanoidSetP2PMulticastList(prGlueInfo->prAdapter, ++ &(prGlueInfo->prP2PInfo->aucMCAddrList[0]), (i * ETH_ALEN), &u4SetInfoLen); ++ ++ } ++ ++} /* end of mtk_p2p_wext_set_Multicastlist */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * * \brief This function is TX entry point of NET DEVICE. ++ * * ++ * * \param[in] prSkb Pointer of the sk_buff to be sent ++ * * \param[in] prDev Pointer to struct net_device ++ * * ++ * * \retval NETDEV_TX_OK - on success. ++ * * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. ++ * */ ++/*----------------------------------------------------------------------------*/ ++int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) ++{ ++ P_QUE_ENTRY_T prQueueEntry = NULL; ++ P_QUE_T prTxQueue = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_16 u2QueueIdx = 0; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(prSkb); ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prGlueInfo->u8SkbToDriver++; ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ DBGLOG(P2P, ERROR, "GLUE_FLAG_HALT skip tx\n"); ++ prGlueInfo->u8SkbFreed++; ++ dev_kfree_skb(prSkb); ++ return NETDEV_TX_OK; ++ } ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ kalMetProfilingStart(prGlueInfo, prSkb); ++#endif ++ ++ /* mark as P2P packets */ ++ GLUE_SET_PKT_FLAG_P2P(prSkb); ++#if CFG_ENABLE_PKT_LIFETIME_PROFILE ++ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); ++#endif ++ ++ STATS_TX_TIME_ARRIVE(prSkb); ++ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); ++ prTxQueue = &prGlueInfo->rTxQueue; ++ ++ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { ++ ++ u2QueueIdx = skb_get_queue_mapping(prSkb); ++ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); ++ ++ if (u2QueueIdx >= CFG_MAX_TXQ_NUM) { ++ DBGLOG(P2P, ERROR, "Incorrect queue index, skip this frame\n"); ++ prGlueInfo->u8SkbFreed++; ++ dev_kfree_skb(prSkb); ++ return NETDEV_TX_OK; ++ } ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); ++ ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); ++ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); ++ ++ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx] >= ++ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { ++ DBGLOG(TX, INFO, "netif_stop_subqueue for p2p0, Queue len: %d\n", ++ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); ++ netif_stop_subqueue(prDev, u2QueueIdx); ++ } ++ } else { ++ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); ++ } ++ ++ kalSetEvent(prGlueInfo); ++ ++ /* Statistic usage. */ ++ prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes += prSkb->len; ++ prGlueInfo->prP2PInfo->rNetDevStats.tx_packets++; ++ /* prDev->stats.tx_packets++; */ ++ kalPerMonStart(prGlueInfo); ++ return NETDEV_TX_OK; ++} /* end of p2pHardStartXmit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief A method of struct net_device, a primary SOCKET interface to configure ++ * the interface lively. Handle an ioctl call on one of our devices. ++ * Everything Linux ioctl specific is done here. Then we pass the contents ++ * of the ifr->data to the request message handler. ++ * ++ * \param[in] prDev Linux kernel netdevice ++ * ++ * \param[in] prIfReq Our private ioctl request structure, typed for the generic ++ * struct ifreq so we can use ptr to function ++ * ++ * \param[in] cmd Command ID ++ * ++ * \retval 0 The IOCTL command is executed successfully. ++ * \retval <0 The execution of IOCTL command is failed. ++ */ ++/*----------------------------------------------------------------------------*/ ++int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ int ret = 0; ++ char *prExtraBuf = NULL; ++ UINT_32 u4ExtraSize = 0; ++ struct iwreq *prIwReq = (struct iwreq *)prIfReq; ++ struct iw_request_info rIwReqInfo; ++ ++ ASSERT(prDev && prIfReq); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ if (!prGlueInfo) { ++ DBGLOG(P2P, ERROR, "prGlueInfo is NULL\n"); ++ return -EFAULT; ++ } ++ ++ if (prGlueInfo->u4ReadyFlag == 0) { ++ DBGLOG(P2P, ERROR, "Adapter is not ready\n"); ++ return -EINVAL; ++ } ++ ++ rIwReqInfo.cmd = (__u16) i4Cmd; ++ rIwReqInfo.flags = 0; ++ ++ switch (i4Cmd) { ++ case SIOCSIWENCODEEXT: ++ /* Set Encryption Material after 4-way handshaking is done */ ++ if (prIwReq->u.encoding.pointer) { ++ u4ExtraSize = prIwReq->u.encoding.length; ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, prIwReq->u.encoding.pointer, prIwReq->u.encoding.length)) ++ ret = -EFAULT; ++ } else if (prIwReq->u.encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret == 0) ++ ret = mtk_p2p_wext_set_key(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ break; ++ ++ case SIOCSIWMLME: ++ /* IW_MLME_DISASSOC used for disconnection */ ++ if (prIwReq->u.data.length != sizeof(struct iw_mlme)) { ++ DBGLOG(P2P, WARN, "MLME buffer strange:%d\n", prIwReq->u.data.length); ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (!prIwReq->u.data.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, prIwReq->u.data.pointer, sizeof(struct iw_mlme))) ++ ret = -EFAULT; ++ else ++ ret = mtk_p2p_wext_mlme_handler(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); ++ prExtraBuf = NULL; ++ break; ++ ++ case SIOCGIWPRIV: ++ /* This ioctl is used to list all IW privilege ioctls */ ++ ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++ ++ case SIOCGIWSCAN: ++ ret = mtk_p2p_wext_discovery_results(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++ ++ case SIOCSIWAUTH: ++ ret = mtk_p2p_wext_set_auth(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++ ++ case IOC_P2P_CFG_DEVICE: ++ case IOC_P2P_PROVISION_COMPLETE: ++ case IOC_P2P_START_STOP_DISCOVERY: ++ case IOC_P2P_DISCOVERY_RESULTS: ++ case IOC_P2P_WSC_BEACON_PROBE_RSP_IE: ++ case IOC_P2P_CONNECT_DISCONNECT: ++ case IOC_P2P_PASSWORD_READY: ++ case IOC_P2P_GET_STRUCT: ++ case IOC_P2P_SET_STRUCT: ++ case IOC_P2P_GET_REQ_DEVICE_INFO: ++ ret = ++ rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV] (prDev, &rIwReqInfo, &(prIwReq->u), ++ (char *)&(prIwReq->u)); ++ break; ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ case SIOCGIWSTATS: ++ ret = mtk_p2p_wext_get_rssi(prDev, &rIwReqInfo, &(prIwReq->u), NULL); ++ break; ++#endif ++ case IOC_GET_PRIVATE_IOCTL_CMD: ++ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); ++ ++ break; ++ default: ++ ret = -ENOTTY; ++ } ++ ++ return ret; ++} /* end of p2pDoIOCTL() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief To report the iw private args table to user space. ++ * ++ * \param[in] prDev Net device requested. ++ * \param[in] info Pointer to iw_request_info. ++ * \param[inout] wrqu Pointer to iwreq_data. ++ * \param[inout] extra ++ * ++ * \retval 0 For success. ++ * \retval -E2BIG For user's buffer size is too small. ++ * \retval -EFAULT For fail. ++ * ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_priv(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ UINT_16 u2BufferSize = prData->length; ++ ++ /* Update our private args table size */ ++ prData->length = (__u16)sizeof(rP2PIwPrivTable); ++ if (u2BufferSize < prData->length) ++ return -E2BIG; ++ ++ if (prData->length) { ++ if (copy_to_user(prData->pointer, rP2PIwPrivTable, sizeof(rP2PIwPrivTable))) ++ return -EFAULT; ++ } ++ ++ return 0; ++} /* end of mtk_p2p_wext_get_priv() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief To indicate P2P-FSM for re-associate to the connecting device ++ * ++ * \param[in] prDev Net device requested. ++ * \param[inout] wrqu Pointer to iwreq_data ++ * ++ * \retval 0 For success. ++ * \retval -EFAULT For fail. ++ * ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_reconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_MSG_HDR_T prMsgHdr; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); ++ if (!prMsgHdr) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_reconnect: P2P Reconnect\n"); ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); ++#endif ++ return 0; ++} /* end of mtk_p2p_wext_reconnect() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief MLME command handler ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_mlme *mlme = (struct iw_mlme *)extra; ++ P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_mlme_handler:\n"); ++ ++ switch (mlme->cmd) { ++ case IW_MLME_DISASSOC: ++ prMsgP2PConnAbt = ++ (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ if (!prMsgP2PConnAbt) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, mlme->addr.sa_data); ++ ++ prMsgP2PConnAbt->u2ReasonCode = mlme->reason_code; ++ ++ if (EQUAL_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prP2pBssInfo->aucOwnMacAddr)) { ++ DBGLOG(P2P, TRACE, "P2P Connection Abort:\n"); ++ ++ /* 1.2 fill message */ ++ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ } else { ++ DBGLOG(P2P, TRACE, "P2P Connection Pause:\n"); ++ ++ /* 1.2 fill message */ ++ } ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); ++ ++ break; ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++#endif ++ return 0; ++} /* end of mtk_p2p_wext_mlme_handler() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_PROVISION_COMPLETE) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_MSG_HDR_T prMsgHdr; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ switch (prData->flags) { ++ case P2P_PROVISIONING_SUCCESS: ++ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); ++ if (!prMsgHdr) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ ++ prGlueInfo->prP2PInfo->u4CipherPairwise = IW_AUTH_CIPHER_CCMP; ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); ++ ++ break; ++ ++ case P2P_PROVISIONING_FAIL: ++ ++ break; ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++#endif ++ ++ return 0; ++} /* end of mtk_p2p_wext_set_provision_complete() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_START_STOP_DISCOVERY) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++#if 0 ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_IW_P2P_REQ_DEVICE_TYPE prReqDeviceType = (P_IW_P2P_REQ_DEVICE_TYPE) extra; ++ UINT_8 au4IeBuf[MAX_IE_LENGTH]; ++ P_MSG_HDR_T prMsgHdr; ++ P_MSG_P2P_DEVICE_DISCOVER_T prDiscoverMsg; ++ P_P2P_CONNECTION_SETTINGS_T prConnSettings; ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ if (prData->flags == P2P_STOP_DISCOVERY) { ++ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); ++ ++ if (!prMsgHdr) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); ++ } else if (prData->flags == P2P_START_DISCOVERY) { ++ ++ /* retrieve IE for Probe Response */ ++ if (prReqDeviceType->probe_rsp_len > 0) { ++ if (prReqDeviceType->probe_rsp_len <= MAX_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[2], prReqDeviceType->probe_rsp_ie, ++ prReqDeviceType->probe_rsp_len)) { ++ return -EFAULT; ++ } ++ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prReqDeviceType->probe_rsp_len; ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ /* retrieve IE for Probe Request */ ++ if (prReqDeviceType->probe_req_len > 0) { ++ if (prReqDeviceType->probe_req_len <= MAX_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[1], prReqDeviceType->probe_req_ie, ++ prReqDeviceType->probe_req_len)) { ++ return -EFAULT; ++ } ++ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prReqDeviceType->probe_req_len; ++ } else { ++ return -E2BIG; ++ } ++ } ++ /* update IE for Probe Request */ ++ ++ if (prReqDeviceType->scan_type == P2P_LISTEN) { ++ /* update listening parameter */ ++ ++ /* @TODO: update prConnSettings for Probe Response IE */ ++ } else { ++ /* indicate P2P-FSM with MID_MNY_P2P_DEVICE_DISCOVERY */ ++ prDiscoverMsg = (P_MSG_P2P_DEVICE_DISCOVER_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ sizeof(MSG_P2P_DEVICE_DISCOVER_T)); ++ ++ if (!prDiscoverMsg) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ prDiscoverMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; ++ prDiscoverMsg->u4DevDiscoverTime = 0; /* unlimited */ ++ prDiscoverMsg->fgIsSpecificType = TRUE; ++ prDiscoverMsg->rTargetDeviceType.u2CategoryID = ++ *(PUINT_16) (&(prReqDeviceType->pri_device_type[0])); ++ prDiscoverMsg->rTargetDeviceType.u2SubCategoryID = ++ *(PUINT_16) (&(prReqDeviceType->pri_device_type[6])); ++ COPY_MAC_ADDR(prDiscoverMsg->aucTargetDeviceID, aucNullAddr); ++ ++ /* @FIXME: parameter to be refined, where to pass IE buffer ? */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDiscoverMsg, MSG_SEND_METHOD_BUF); ++ } ++ } else { ++ return -EINVAL; ++ } ++#endif ++ ++ return 0; ++} /* end of mtk_p2p_wext_start_stop_discovery() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int i4Status = 0; ++#if 0 ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_IW_P2P_IOCTL_INVITATION_STRUCT prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) NULL; ++ ++ do { ++ if ((prDev == NULL) || (extra == NULL)) { ++ ASSERT(FALSE); ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) extra; ++ ++ if (prGlueInfo == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ if (prAdapter == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ if (prIoctlInvitation->ucReinvoke == 1) { ++ /* TODO: Set Group ID */ ++ p2pFuncSetGroupID(prAdapter, prIoctlInvitation->aucGroupID, prIoctlInvitation->aucSsid, ++ prIoctlInvitation->u4SsidLen); ++ } ++ ++ else { ++ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; ++ ++ /* TODO: Do Invitation. */ ++ prMsgP2PInvitationReq = ++ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_INVITATION_REQUEST_T)); ++ if (!prMsgP2PInvitationReq) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ i4Status = -ENOMEM; ++ break; ++ } ++ ++ /* 1.2 fill message */ ++ kalMemCopy(prMsgP2PInvitationReq->aucDeviceID, prIoctlInvitation->aucDeviceID, MAC_ADDR_LEN); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationReq, MSG_SEND_METHOD_BUF); ++ ++ } ++ ++ } while (FALSE); ++#endif ++ ++ return i4Status; ++ ++} ++ ++/* mtk_p2p_wext_invitation_request */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_abort(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int i4Status = 0; ++#if 0 ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ P_IW_P2P_IOCTL_ABORT_INVITATION prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) NULL; ++ ++ UINT_8 bssid[MAC_ADDR_LEN]; ++ ++ do { ++ if ((prDev == NULL) || (extra == NULL)) { ++ ASSERT(FALSE); ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) extra; ++ ++ if (prGlueInfo == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ if (prAdapter == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; ++ ++ prMsgP2PInvitationAbort = ++ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_INVITATION_REQUEST_T)); ++ ++ if (!prMsgP2PInvitationAbort) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ i4Status = -ENOMEM; ++ break; ++ } ++ ++ /* 1.2 fill message */ ++ kalMemCopy(prMsgP2PInvitationAbort->aucDeviceID, prIoctlInvitationAbort->dev_addr, ++ MAC_ADDR_LEN); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationAbort, MSG_SEND_METHOD_BUF); ++ ++ ++ } while (FALSE); ++#endif ++ ++ return i4Status; ++ ++} ++ ++/* mtk_p2p_wext_invitation_abort */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief To override p2p interface address ++ * ++ * \param[in] prDev Net device requested. ++ * \param[in] addr Pointer to address ++ * ++ * \retval 0 For success. ++ * \retval -E2BIG For user's buffer size is too small. ++ * \retval -EFAULT For fail. ++ * ++ */ ++/*----------------------------------------------------------------------------*/ ++int p2pSetMACAddress(IN struct net_device *prDev, void *addr) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @FIXME */ ++ return eth_mac_addr(prDev, addr); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher suite ++* ++* \param[in] prDev Net device requested. ++* \param[out] ++* ++* \retval 0 Success. ++* \retval -EINVAL Invalid parameter ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_auth(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_param *prAuth = (struct iw_param *)wrqu; ++ ++ ASSERT(prDev); ++ ASSERT(prAuth); ++ if (FALSE == GLUE_CHK_PR2(prDev, prAuth)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ /* Save information to glue info and process later when ssid is set. */ ++ switch (prAuth->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ break; ++ case IW_AUTH_CIPHER_PAIRWISE: ++ prGlueInfo->prP2PInfo->u4CipherPairwise = prAuth->value; ++ break; ++ case IW_AUTH_CIPHER_GROUP: ++ case IW_AUTH_KEY_MGMT: ++ case IW_AUTH_TKIP_COUNTERMEASURES: ++ case IW_AUTH_DROP_UNENCRYPTED: ++ case IW_AUTH_80211_AUTH_ALG: ++ case IW_AUTH_WPA_ENABLED: ++ case IW_AUTH_RX_UNENCRYPTED_EAPOL: ++ case IW_AUTH_ROAMING_CONTROL: ++ case IW_AUTH_PRIVACY_INVOKED: ++ default: ++ /* @TODO */ ++ break; ++ } ++ ++ return 0; ++} /* end of mtk_p2p_wext_set_auth() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[out] prIfReq Pointer to ifreq structure, content is copied back to ++* user space buffer in gl_iwpriv_table. ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_key(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int ret = 0; ++ struct iw_encode_ext *prIWEncExt; ++ struct iw_point *prEnc; ++ char *prExtraBuf = NULL; ++ UINT_32 u4ExtraSize = 0; ++ UINT_8 keyStructBuf[100]; ++ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; ++ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ do { ++ if (wrqu->encoding.pointer) { ++ u4ExtraSize = wrqu->encoding.length; ++ /*need confirm u4ExtraSize > 0 but is not very large*/ ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ /* here should set prExtraBuf default value */ ++ memset(prExtraBuf, 0, u4ExtraSize); ++ if (copy_from_user(prExtraBuf, wrqu->encoding.pointer, wrqu->encoding.length)) { ++ ret = -EFAULT; ++ break; ++ } ++ } else if (wrqu->encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prEnc = &wrqu->encoding; ++ /* here, need confirm (struct iw_encode_ext) < u4ExtraSize */ ++ prIWEncExt = (struct iw_encode_ext *)prExtraBuf; ++ ++ if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) != TRUE) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ memset(keyStructBuf, 0, sizeof(keyStructBuf)); ++ ++ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { /* Key Removal */ ++ prRemoveKey->u4Length = sizeof(*prRemoveKey); ++ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveP2PKey, ++ prRemoveKey, ++ prRemoveKey->u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ ret = -EFAULT; ++ } else { ++ if (prIWEncExt->alg == IW_ENCODE_ALG_CCMP) { ++ /* KeyID */ ++ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? ++ ((prEnc->flags & IW_ENCODE_INDEX) - 1) : 0; ++ if (prKey->u4KeyIndex <= 3) { ++ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ ++ /* Tx Key Bit(31) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) ++ prKey->u4KeyIndex |= 0x1UL << 31; ++ ++ /* Pairwise Key Bit(30) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ /* group key */ ++ } else { ++ /* pairwise key */ ++ prKey->u4KeyIndex |= 0x1UL << 30; ++ } ++ ++ /* Rx SC Bit(29) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { ++ prKey->u4KeyIndex |= 0x1UL << 29; ++ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, ++ IW_ENCODE_SEQ_MAX_SIZE); ++ } ++ ++ /* BSSID */ ++ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); ++ ++ prKey->u4KeyLength = prIWEncExt->key_len; ++ prKey->u4Length = ++ ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + ++ prKey->u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddP2PKey, ++ prKey, ++ prKey->u4Length, ++ FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ ret = -EFAULT; ++ } else { ++ ret = -EINVAL; ++ } ++ } else { ++ ret = -EINVAL; ++ } ++ } ++ ++ } while (FALSE); ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ ++ return ret; ++} /* end of mtk_p2p_wext_set_key() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief set the p2p gc power mode ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_powermode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ /* printk("set_powermode = %d, value = %d\n", wrqu->power.disabled, wrqu->power.value); */ ++ struct iw_param *prPower = (struct iw_param *)&wrqu->power; ++#if 1 ++ PARAM_POWER_MODE ePowerMode; ++ INT_32 i4PowerValue; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ ++ /* prPower->value, prPower->disabled, prPower->flags); */ ++ ++ if (prPower->disabled) { ++ ePowerMode = Param_PowerModeCAM; ++ } else { ++ i4PowerValue = prPower->value; ++#if WIRELESS_EXT < 21 ++ i4PowerValue /= 1000000; ++#endif ++ if (i4PowerValue == 0) { ++ ePowerMode = Param_PowerModeCAM; ++ } else if (i4PowerValue == 1) { ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else if (i4PowerValue == 2) { ++ ePowerMode = Param_PowerModeFast_PSP; ++ } else { ++ DBGLOG(P2P, ERROR, "%s(): unsupported power management mode value = %d.\n", ++ __func__, prPower->value); ++ ++ return -EINVAL; ++ } ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++#endif ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief get the p2p gc power mode ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_powermode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ /* printk("mtk_p2p_wext_get_powermode\n"); */ ++ /* wrqu->power.disabled = 0; */ ++ /* wrqu->power.value = 1; */ ++ ++ struct iw_param *prPower = (struct iw_param *)&wrqu->power; ++ PARAM_POWER_MODE ePowerMode = Param_PowerModeMax; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ ++#if 1 ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryP2pPowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), TRUE, FALSE, FALSE, TRUE, &u4BufLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryP2pPowerSaveProfile, &ePowerMode, sizeof(ePowerMode), &u4BufLen); ++#endif ++ ++ prPower->value = 0; ++ prPower->disabled = 1; ++ ++ if (Param_PowerModeCAM == ePowerMode) { ++ prPower->value = 0; ++ prPower->disabled = 1; ++ } else if (Param_PowerModeMAX_PSP == ePowerMode) { ++ prPower->value = 1; ++ prPower->disabled = 0; ++ } else if (Param_PowerModeFast_PSP == ePowerMode) { ++ prPower->value = 2; ++ prPower->disabled = 0; ++ } ++ ++ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; ++#if WIRELESS_EXT < 21 ++ prPower->value *= 1000000; ++#endif ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_CFG_DEVICE) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_CFG_DEVICE_TYPE prDeviceCfg = (P_IW_P2P_CFG_DEVICE_TYPE) extra; ++ P_P2P_CONNECTION_SETTINGS_T prConnSettings; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ /* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL; */ ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ ++ /* update connection settings for P2P-FSM */ ++ /* 1. update SSID */ ++ if (prDeviceCfg->ssid_len > ELEM_MAX_LEN_SSID) ++ prConnSettings->ucSSIDLen = ELEM_MAX_LEN_SSID; ++ else ++ prConnSettings->ucSSIDLen = prDeviceCfg->ssid_len; ++ ++ if (copy_from_user(prConnSettings->aucSSID, prDeviceCfg->ssid, prConnSettings->ucSSIDLen)) ++ return -EFAULT; ++ /* 2. update device type (WPS IE) */ ++ kalMemCopy(&(prConnSettings->rPrimaryDevTypeBE), &(prDeviceCfg->pri_device_type), sizeof(DEVICE_TYPE_T)); ++#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT ++ kalMemCopy(&(prConnSettings->arSecondaryDevTypeBE[0]), &(prDeviceCfg->snd_device_type), sizeof(DEVICE_TYPE_T)); ++#endif ++ ++ /* 3. update device name */ ++ if (prDeviceCfg->device_name_len > WPS_ATTRI_MAX_LEN_DEVICE_NAME) ++ prConnSettings->ucDevNameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; ++ else ++ prConnSettings->ucDevNameLen = prDeviceCfg->device_name_len; ++ if (copy_from_user(prConnSettings->aucDevName, prDeviceCfg->device_name, prConnSettings->ucDevNameLen)) ++ return -EFAULT; ++ /* 4. update GO intent */ ++ prConnSettings->ucGoIntent = prDeviceCfg->intend; ++ ++ /* Preferred channel bandwidth */ ++ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; ++ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; ++ ++#if 0 ++ /* 1. switch P2P-FSM on */ ++ /* 1.1 allocate for message */ ++ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ ++ if (!prFuncSwitch) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ /* 1.2 fill message */ ++ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ prFuncSwitch->fgIsFuncOn = TRUE; ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ return 0; ++} /* end of mtk_p2p_wext_set_local_dev_info() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * \brief I/O Control handler for both ++ * IOC_P2P_START_STOP_DISCOVERY & SIOCGIWSCAN ++ * ++ * \param[in] prDev Net device requested. ++ * \param[inout] wrqu Pointer to iwreq_data ++ * ++ * \retval 0 Success. ++ * \retval -EFAULT Setting parameters to driver fail. ++ * \retval -EOPNOTSUPP Key size not supported. ++ * ++ * \note ++ */ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_discovery_results(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ struct iw_event iwe; ++ char *current_ev = extra; ++ UINT_32 i; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ P_P2P_INFO_T prP2PInfo = (P_P2P_INFO_T) NULL; ++ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; ++ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prP2PInfo = prAdapter->prP2pInfo; ++ ++ for (i = 0; i < prP2PInfo->u4DeviceNum; i++) { ++ prTargetResult = &prP2PInfo->arP2pDiscoverResult[i]; ++ ++ /* SIOCGIWAP */ ++ iwe.cmd = SIOCGIWAP; ++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; ++ memcpy(iwe.u.ap_addr.sa_data, prTargetResult->aucInterfaceAddr, 6); ++ ++ current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); ++ ++ /* SIOCGIWESSID */ ++ iwe.cmd = SIOCGIWESSID; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = prTargetResult->u2NameLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, prTargetResult->aucName); ++ ++ /* IWEVGENIE for WPA IE */ ++ if (prTargetResult->u2IELength <= 600 && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, ++ prTargetResult->u2IELength, ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); ++ } ++#if CFG_SUPPORT_WPS ++ ++ /* IWEVGENIE for WPS IE */ ++ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPSIE(prTargetResult->pucIeBuf, ++ prTargetResult->u2IELength, ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); ++ } ++#endif ++ ++ /* IWEVGENIE for RSN IE */ ++ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, ++ prTargetResult->u2IELength, ++ 0x30, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); ++ } ++ ++ /* IOC_P2P_GO_WSC_IE */ ++#if 1 ++ /* device capability */ ++ if (1) { ++ UINT_8 data[40]; ++ ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.flags = 0; ++ iwe.u.data.length = 9 + sizeof("p2p_cap="); ++ if (iwe.u.data.length > 40) ++ iwe.u.data.length = 40; ++ ++ snprintf(data, iwe.u.data.length, "p2p_cap=%02x%02x%02x%02x%c", ++ prTargetResult->ucDeviceCapabilityBitmap, prTargetResult->ucGroupCapabilityBitmap, ++ (UINT_8) prTargetResult->u2ConfigMethod, ++ (UINT_8) (prTargetResult->u2ConfigMethod >> 8), '\0'); ++ current_ev = ++ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); ++ ++ /* printk("%s\n", data); */ ++ kalMemZero(data, 40); ++ ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.flags = 0; ++ iwe.u.data.length = 13 + sizeof("p2p_dev_type="); ++ if (iwe.u.data.length > 40) ++ iwe.u.data.length = 40; ++ ++ snprintf(data, iwe.u.data.length, "p2p_dev_type=%02x%02x%02x%02x%02x%02x%c", ++ (UINT_8) prTargetResult->rPriDevType.u2CategoryID, ++ (UINT_8) prTargetResult->rPriDevType.u2SubCategoryID, ++ (UINT_8) prTargetResult->arSecDevType[0].u2CategoryID, ++ (UINT_8) prTargetResult->arSecDevType[0].u2SubCategoryID, ++ (UINT_8) prTargetResult->arSecDevType[1].u2CategoryID, ++ (UINT_8) prTargetResult->arSecDevType[1].u2SubCategoryID, '\0'); ++ current_ev = ++ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); ++ /* printk("%s\n", data); */ ++ ++ kalMemZero(data, 40); ++ ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.flags = 0; ++ iwe.u.data.length = 17 + sizeof("p2p_grp_bssid="); ++ if (iwe.u.data.length > 40) ++ iwe.u.data.length = 40; ++ ++ snprintf(data, iwe.u.data.length, "p2p_grp_bssid= %pM %c", ++ prTargetResult->aucBSSID, '\0'); ++ current_ev = iwe_stream_add_point(info, current_ev, ++ extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); ++ /* printk("%s\n", data); */ ++ ++ } ++#endif ++ } ++ ++ /* Length of data */ ++ wrqu->data.length = (current_ev - extra); ++ wrqu->data.flags = 0; ++ ++ return 0; ++} /* end of mtk_p2p_wext_discovery_results() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_WSC_BEACON_PROBE_RSP_IE) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_HOSTAPD_PARAM prHostapdParam = (P_IW_P2P_HOSTAPD_PARAM) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ if (prHostapdParam->len > 0) { ++ if (prHostapdParam->len <= MAX_WSC_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[0], prHostapdParam->data, prHostapdParam->len)) { ++ return -EFAULT; ++ } ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[2], prHostapdParam->data, prHostapdParam->len)) { ++ return -EFAULT; ++ } ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ prGlueInfo->prP2PInfo->u2WSCIELen[0] = prHostapdParam->len; ++ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prHostapdParam->len; ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); ++ ++ /* @TODO: send message to P2P-FSM */ ++ ++ return 0; ++} /* end of mtk_p2p_wext_wsc_ie() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_CONNECT_DISCONNECT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++/* P_IW_P2P_CONNECT_DEVICE prConnectDevice = (P_IW_P2P_CONNECT_DEVICE)extra; */ ++/* P_MSG_HDR_T prMsgHdr; */ ++/* P_MSG_P2P_CONNECTION_REQUEST_T prMsgP2PConnReq; */ ++/* P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt; */ ++/* UINT_8 aucBCAddr[] = BC_MAC_ADDR; */ ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ if (prData->flags == P2P_CONNECT) { ++#if 0 ++ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_REQ */ ++ prMsgP2PConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ ++ if (!prMsgP2PConnReq) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnReq, MSG_SEND_METHOD_BUF); ++#endif ++ } else if (prData->flags == P2P_DISCONNECT) { ++#if 0 ++ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_ABORT */ ++ prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ ++ if (!prMsgP2PConnAbt) { ++ ASSERT(0); /* Can't trigger P2P FSM */ ++ return -ENOMEM; ++ } ++ ++ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prConnectDevice->sta_addr); ++ ++ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); ++#endif ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} /* end of mtk_p2p_wext_connect_disconnect() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_PASSWORD_READY) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_password_ready(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY) extra; ++ P_P2P_CONNECTION_SETTINGS_T prConnSettings; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; ++ ++ /* retrieve IE for Probe Request */ ++ if (prPasswordReady->probe_req_len > 0) { ++ if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, ++ prPasswordReady->probe_req_len)) { ++ return -EFAULT; ++ } ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len; ++ ++ /* retrieve IE for Probe Response */ ++ if (prPasswordReady->probe_rsp_len > 0) { ++ if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) { ++ if (copy_from_user ++ (prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, ++ prPasswordReady->probe_rsp_len)) { ++ return -EFAULT; ++ } ++ } else { ++ return -E2BIG; ++ } ++ } ++ ++ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len; ++ ++ switch (prPasswordReady->active_config_method) { ++ case 1: ++ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_PUSH_BUTTON; ++ break; ++ case 2: ++ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_KEYPAD; ++ break; ++ case 3: ++ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_DISPLAY; ++ break; ++ default: ++ break; ++ } ++ ++ prConnSettings->fgIsPasswordIDRdy = TRUE; ++ return 0; ++} /* end of mtk_p2p_wext_password_ready() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_REQ_DEVICE_INFO) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_DEVICE_REQ prDeviceReq = (P_IW_P2P_DEVICE_REQ) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* specify data length */ ++ wrqu->data.length = sizeof(IW_P2P_DEVICE_REQ); ++ ++ /* copy to upper-layer supplied buffer */ ++ kalMemCopy(prDeviceReq->name, prGlueInfo->prP2PInfo->aucConnReqDevName, ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ prDeviceReq->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; ++ prDeviceReq->name[prDeviceReq->name_len] = '\0'; ++ COPY_MAC_ADDR(prDeviceReq->device_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); ++ prDeviceReq->device_type = prGlueInfo->prP2PInfo->ucConnReqDevType; ++ prDeviceReq->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; ++ prDeviceReq->active_config_method = prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod; ++ ++ return 0; ++} /* end of mtk_p2p_wext_request_dev_info() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_IOCTL_INVITATION_INDICATE prInvIndicate = (P_IW_P2P_IOCTL_INVITATION_INDICATE) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* specify data length */ ++ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_INDICATE); ++ ++ /* copy to upper-layer supplied buffer */ ++ kalMemCopy(prInvIndicate->dev_name, prGlueInfo->prP2PInfo->aucConnReqDevName, ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ kalMemCopy(prInvIndicate->group_bssid, prGlueInfo->prP2PInfo->rConnReqGroupAddr, MAC_ADDR_LEN); ++ prInvIndicate->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; ++ prInvIndicate->dev_name[prInvIndicate->name_len] = '\0'; ++ COPY_MAC_ADDR(prInvIndicate->dev_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); ++ prInvIndicate->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; ++ prInvIndicate->operating_channel = prGlueInfo->prP2PInfo->ucOperatingChnl; ++ prInvIndicate->invitation_type = prGlueInfo->prP2PInfo->ucInvitationType; ++ ++ return 0; ++} /* end of mtk_p2p_wext_invitation_indicate() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_invitation_status(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_IOCTL_INVITATION_STATUS prInvStatus = (P_IW_P2P_IOCTL_INVITATION_STATUS) extra; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* specify data length */ ++ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_STATUS); ++ ++ /* copy to upper-layer supplied buffer */ ++ prInvStatus->status_code = prGlueInfo->prP2PInfo->u4InvStatus; ++ ++ return 0; ++} /* end of mtk_p2p_wext_invitation_status() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief indicate an event to supplicant for device found ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval TRUE Success. ++* \retval FALSE Failure ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_FND"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PDVCFND event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++ return FALSE; ++} /* end of kalP2PIndicateFound() */ ++ ++int ++mtk_p2p_wext_set_network_address(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @TODO: invoke wlan_p2p functions */ ++#if 0 ++ rStatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pNetworkAddress, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); ++#endif ++ ++ return 0; ++ ++} ++ ++int ++mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @TODO: invoke wlan_p2p functions */ ++#if 0 ++ rStatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); ++#endif ++ ++ return 0; ++ ++} ++ ++int ++mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ASSERT(prAdapter); ++ ++ /* @TODO: invoke wlan_p2p functions */ ++#if 0 ++ rStatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); ++#endif ++ ++ return 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_start_formation(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int i4Status = 0; ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++/* struct iw_point *prData = (struct iw_point*)&wrqu->data; */ ++ P_IW_P2P_IOCTL_START_FORMATION prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) NULL; ++ ++ do { ++ if ((prDev == NULL) || (extra == NULL)) { ++ ASSERT(FALSE); ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) extra; ++ ++ if (prGlueInfo == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++ ++ if (prAdapter == NULL) { ++ i4Status = -EINVAL; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return i4Status; ++ ++} ++ ++/* mtk_p2p_wext_start_formation */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Setting parameters not support. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_int(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int status = 0; ++ UINT_32 u4SubCmd = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 index; ++ INT_32 value; ++ PUINT_32 pu4IntBuf; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; ++ UINT_32 u4Leng; ++ ++ ASSERT(prDev); ++ ASSERT(wrqu); ++ ++ /* printk("mtk_p2p_wext_set_int\n"); */ ++ pu4IntBuf = (PUINT_32) extra; ++ ++ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo; ++ ++ u4SubCmd = (UINT_32) wrqu->mode; ++ index = pu4IntBuf[1]; ++ value = pu4IntBuf[2]; ++ ++ DBGLOG(P2P, INFO, "set parameter, u4SubCmd=%d idx=%d value=%d\n", (INT_16) u4SubCmd, (INT_16) index, value); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_INT_P2P_SET: ++ switch (index) { ++ case 0: /* Listen CH */ ++ { ++ UINT_8 ucSuggestChnl = 0; ++ ++ prP2pConnSettings->ucListenChnl = value; ++ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ if (rlmFuncFindAvailableChannel ++ (prGlueInfo->prAdapter, value, &ucSuggestChnl, TRUE, TRUE)) { ++ prP2pSpecificBssInfo->ucListenChannel = value; ++ } else { ++ prP2pSpecificBssInfo->ucListenChannel = ucSuggestChnl; ++ } ++ ++ break; ++ } ++ case 1: /* P2p mode */ ++ break; ++ case 4: /* Noa duration */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, ++ (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 5: /* Noa interval */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, ++ (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 6: /* Noa count */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; ++ status = ++ mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); ++ break; ++ case 100: /* Oper CH */ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ prP2pConnSettings->ucOperatingChnl = value; ++ break; ++ case 101: /* Local config Method, for P2P SDK */ ++ /* prP2pConnSettings->u2LocalConfigMethod; */ ++ break; ++ case 102: /* Sigma P2p reset */ ++ kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); ++ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ ++ break; ++ case 103: /* WPS MODE */ ++ kalP2PSetWscMode(prGlueInfo, value); ++ break; ++ case 104: /* P2p send persence, duration */ ++ break; ++ case 105: /* P2p send persence, interval */ ++ break; ++ case 106: /* P2P set sleep */ ++ value = 1; ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, ++ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ case 107: /* P2P set opps, CTWindowl */ ++ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; ++ status = ++ mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rOppPsParam); ++ break; ++ case 108: /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, ++ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ ++ break; ++ ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_SET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int status = 0; ++ UINT_32 u4SubCmd = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; ++ ++ ASSERT(prDev); ++ ASSERT(wrqu); ++ ++ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ u4SubCmd = (UINT_32) wrqu->data.flags; ++ ++ kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0], sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_OID: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ ++ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) ++ DBGLOG(P2P, INFO, "extra buffer is valid\n"); ++ else ++ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_SEND_SD_RESPONSE: ++ status = mtk_p2p_wext_send_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_SEND_SD_REQUEST: ++ status = mtk_p2p_wext_send_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_TERMINATE_SD_PHASE: ++ status = mtk_p2p_wext_terminate_service_discovery_phase(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_INVITATION: ++ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_INVITATION_STRUCT)) { ++ /* Do nothing */ ++ /* status = mtk_p2p_wext_invitation_request(prDev, info, wrqu, ++ (char *)(prP2PReq->aucBuffer)); */ ++ } ++ break; ++ ++ case P2P_CMD_ID_INVITATION_ABORT: ++ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_ABORT_INVITATION)) { ++ /* Do nothing */ ++ /* status = mtk_p2p_wext_invitation_abort(prDev, info, wrqu, ++ (char *)(prP2PReq->aucBuffer)); */ ++ } ++ break; ++ ++ case P2P_CMD_ID_START_FORMATION: ++ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_START_FORMATION)) ++ status = mtk_p2p_wext_start_formation(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ } ++ ++ break; ++#if CFG_SUPPORT_ANTI_PIRACY ++ case PRIV_SEC_CHECK_OID: ++ if (wrqu->data.length > 256) { ++ status = -EOPNOTSUPP; ++ break; ++ } ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), wrqu->data.pointer, wrqu->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ ++ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length)) ++ DBGLOG(P2P, INFO, "extra buffer is valid\n"); ++ else ++ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_SEC_CHECK: ++ status = mtk_p2p_wext_set_sec_check_request(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ } ++ break; ++#endif ++ case PRIV_CMD_P2P_VERSION: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ ++ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) ++ DBGLOG(P2P, INFO, "extra buffer is valid\n"); ++ else ++ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_P2P_VERSION: ++ status = mtk_p2p_wext_set_p2p_version(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ break; ++ } ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ break; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ int status = 0; ++ UINT_32 u4SubCmd = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; ++ ++ ASSERT(prDev); ++ ASSERT(wrqu); ++ ++ if (!prDev || !wrqu) { ++ DBGLOG(P2P, WARN, "%s(): invalid param(0x%p, 0x%p)\n", __func__, prDev, wrqu); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ u4SubCmd = (UINT_32) wrqu->data.flags; ++ ++ kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_OID: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { ++ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); ++ return -EFAULT; ++ } ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_GET_SD_REQUEST: ++ status = mtk_p2p_wext_get_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_GET_SD_RESPONSE: ++ status = mtk_p2p_wext_get_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ ++ case P2P_CMD_ID_INVITATION_INDICATE: ++ { ++ status = ++ mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); ++ prP2PReq->outBufferLength = wrqu->data.length; ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++ break; ++ } ++ case P2P_CMD_ID_INVITATION_STATUS: ++ { ++ status = ++ mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); ++ prP2PReq->outBufferLength = wrqu->data.length; ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++ break; ++ } ++ case P2P_CMD_ID_GET_CH_LIST: ++ { ++ UINT_16 i; ++ UINT_8 NumOfChannel = 50; ++ RF_CHANNEL_INFO_T aucChannelList[50]; ++ UINT_8 ucMaxChannelNum = 50; ++ PUINT_8 pucChnlList = (PUINT_8) prP2PReq->aucBuffer; ++ ++ kalGetChnlList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList); ++ if (NumOfChannel > 50) ++ NumOfChannel = 50; ++ prP2PReq->outBufferLength = NumOfChannel; ++ /*here must confirm NumOfChannel < 16, for prP2PReq->aucBuffer 16 byte*/ ++ if (NumOfChannel >= 15) { ++ /*DBGLOG(P2P, ERROR, "channel num > 15\n", __func__);*/ ++ ASSERT(FALSE); ++ } ++ ++ for (i = 0; i < NumOfChannel; i++) { ++#if 0 ++ /* 20120208 frog: modify to avoid clockwork warning. */ ++ prP2PReq->aucBuffer[i] = aucChannelList[i].ucChannelNum; ++#else ++ *pucChnlList = aucChannelList[i].ucChannelNum; ++ pucChnlList++; ++#endif ++ } ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ NumOfChannel + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++ break; ++ } ++ ++ case P2P_CMD_ID_GET_OP_CH: ++ { ++ prP2PReq->inBufferLength = 4; ++ ++ status = wlanoidQueryP2pOpChannel(prGlueInfo->prAdapter, ++ prP2PReq->aucBuffer, ++ prP2PReq->inBufferLength, &prP2PReq->outBufferLength); ++ ++ if (status == 0) { /* WLAN_STATUS_SUCCESS */ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, ++ aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } else { ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } ++ break; ++ } ++ ++ default: ++ status = -EOPNOTSUPP; ++ } ++ ++ break; ++#if CFG_SUPPORT_ANTI_PIRACY ++ case PRIV_SEC_CHECK_OID: ++ if (wrqu->data.length > 256) { ++ status = -EOPNOTSUPP; ++ break; ++ } ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), ++ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { ++ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); ++ return -EFAULT; ++ } ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_SEC_CHECK: ++ status = mtk_p2p_wext_get_sec_check_response(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ } ++ break; ++#endif ++ case PRIV_CMD_P2P_VERSION: ++ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { ++ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); ++ return -EFAULT; ++ } ++ ++ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); ++ ++ switch (prP2PReq->u4CmdId) { ++ case P2P_CMD_ID_P2P_VERSION: ++ status = mtk_p2p_wext_get_p2p_version(prDev, info, wrqu, (char *)prP2PReq); ++ break; ++ default: ++ status = -EOPNOTSUPP; ++ break; ++ } ++ ++ /* Copy queried data to user. */ ++ if (status == 0) { /* WLAN_STATUS_SUCCESS */ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } ++ ++ else { ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ } ++ ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* getting service discovery request frame from driver ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidGetP2PSDRequest, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prP2PReq->outBufferLength = u4QueryInfoLen; ++ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } else { ++ return 0; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* getting service discovery response frame from driver ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidGetP2PSDResponse, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prP2PReq->outBufferLength = u4QueryInfoLen; ++ ++ if (copy_to_user(wrqu->data.pointer, ++ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), ++ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ return 0; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* sending service discovery request frame ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSendP2PSDRequest, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* sending service discovery response frame ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSendP2PSDResponse, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetSecCheckRequest, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_wext_get_sec_check_response\n"); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidGetSecCheckResponse, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prP2PReq->outBufferLength = u4QueryInfoLen; ++ ++ if (copy_to_user(wrqu->data.pointer, ++ prP2PReq->aucBuffer, u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { ++ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); ++ return -EIO; ++ } ++ return 0; ++ ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* terminating service discovery phase ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2PTerminateSDPhase, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++ /* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ ++ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_noa_param\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetNoaParam, prNoaParam, /* prP2PReq->aucBuffer, */ ++ sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ ++ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief P2P Private I/O Control handler for ++* ++* \param[in] prDev Net device requested. ++* \param[inout] wrqu Pointer to iwreq_data ++* ++* \retval 0 Success. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4SetInfoLen; ++/* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ ++ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_oppps_param\n"); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetOppPsParam, prOppPsParam, /* prP2PReq->aucBuffer, */ ++ sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ ++ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return 0; ++} ++ ++int ++mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ UINT_32 u4SetInfoLen; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pSupplicantVersion, ++ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return rStatus; ++ ++} ++ ++/* mtk_p2p_wext_set_p2p_version */ ++ ++int ++mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen; ++ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryP2pVersion, ++ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return rStatus; ++ ++} /* mtk_p2p_wext_get_p2p_version */ ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ ++int ++mtk_p2p_wext_get_rssi(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen; ++ struct iw_point *prData = (struct iw_point *)&wrqu->data; ++ UINT_16 u2BufferSize = 0; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rssi; ++ struct iw_statistics *pStats = NULL; ++ ++ ASSERT(prDev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ ++ if (!prGlueInfo) { ++ rStatus = WLAN_STATUS_FAILURE; ++ goto stat_out; ++ } ++ ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &u4QueryInfoLen); ++ ++ u2BufferSize = prData->length; ++ ++ if (u2BufferSize < sizeof(struct iw_statistics)) ++ return -E2BIG; ++ ++ if (copy_to_user(prData->pointer, pStats, sizeof(struct iw_statistics))) ++ rStatus = WLAN_STATUS_FAILURE; ++ ++stat_out: ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ else ++ return rStatus; ++ ++} /* mtk_p2p_wext_get_rssi */ ++ ++struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_statistics *pStats = NULL; ++ INT_32 i4Rssi; ++ UINT_32 bufLen = 0; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) ++ goto stat_out; ++ ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); ++ ++ if (!prDev || !netif_carrier_ok(prDev)) { ++ /* network not connected */ ++ goto stat_out; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &bufLen); ++ ++stat_out: ++ return pStats; ++} /* mtk_p2p_wext_get_wireless_stats */ ++ ++#endif /* CFG_SUPPORT_P2P_RSSI_QUERY */ ++ ++int ++mtk_p2p_wext_set_txpow(IN struct net_device *prDev, ++ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; ++#if 0 ++ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; ++#endif ++ int i4Ret = 0; ++ ++ ASSERT(prDev); ++ ASSERT(prTxPow); ++ ++ do { ++ if ((!prDev) || (!prTxPow)) { ++ i4Ret = -EINVAL; ++ break; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ if (!prGlueInfo) { ++ i4Ret = -EINVAL; ++ break; ++ } ++ ++ prAdapter = prGlueInfo->prAdapter; ++#if 0 ++ prMsgFuncSwitch = ++ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_FUNCTION_SWITCH_T)); ++ if (!prMsgFuncSwitch) { ++ ASSERT(0); ++ return -ENOMEM; ++ } ++ ++ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ ++ if (prTxPow->disabled) { ++ /* Dissolve. */ ++ prMsgFuncSwitch->fgIsFuncOn = FALSE; ++ } else { ++ ++ /* Re-enable function. */ ++ prMsgFuncSwitch->fgIsFuncOn = TRUE; ++ } ++ ++ /* 1.3 send message */ ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); ++#endif ++ ++ } while (FALSE); ++ ++ return i4Ret; ++} /* mtk_p2p_wext_set_txpow */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c +new file mode 100644 +index 000000000000..4d71e0c59b05 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c +@@ -0,0 +1,1935 @@ ++/* ++** Id: @(#) gl_p2p_cfg80211.c@@ ++*/ ++ ++/*! \file gl_p2p_cfg80211.c ++ \brief Main routines of Linux driver interface for Wi-Fi Direct ++ using cfg80211 interface ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_p2p_cfg80211.c ++** ++** 01 30 2013 yuche.tsai ++** [ALPS00455459] [GN_WIFI]??wifi direct??????????? ++** Fix possible race condition under GO mode. ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 09 05 2012 wh.su ++** [ALPS00351547] [6577JB][WiFi direct]The 3rd device fail to establish p2p connection with GO sometimes ++** sync with the ICS code. ++** ++** 08 31 2012 yuche.tsai ++** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, ++** one device reboots automatically with KE ++** Fix possible KE when concurrent & disconnect. ++** ++** 08 21 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 20 2012 yuche.tsai ++** NULL ++** Fix possible KE issue. ++** ++** 08 17 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 16 2012 yuche.tsai ++** NULL ++** Fix compile warning. ++** ++** 08 14 2012 yuche.tsai ++** NULL ++** Fix p2p bug find on ALPS.JB trunk. ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Fix compile error for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "config.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "precomp.h" ++#include "gl_cfg80211.h" ++#include "gl_p2p_ioctl.h" ++ ++#ifdef __GNUC__ ++#pragma GCC diagnostic ignored "-Wformat" ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++BOOLEAN ++mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, ++ IN enum nl80211_channel_type channel_type, ++ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Rslt = -EINVAL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ P2P_PARAM_KEY_T rKey; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ kalMemZero(&rKey, sizeof(P2P_PARAM_KEY_T)); ++ ++ rKey.u4KeyIndex = key_index; ++ if (mac_addr) { ++ ether_addr_copy(rKey.arBSSID, mac_addr); ++ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && ++ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ } ++ if (rKey.arBSSID[0] != 0xFF) { ++ rKey.u4KeyIndex |= BIT(31); ++ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || ++ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) ++ rKey.u4KeyIndex |= BIT(30); ++ } else { ++ rKey.u4KeyIndex |= BIT(31); ++ } ++ } else { ++ rKey.arBSSID[0] = 0xff; ++ rKey.arBSSID[1] = 0xff; ++ rKey.arBSSID[2] = 0xff; ++ rKey.arBSSID[3] = 0xff; ++ rKey.arBSSID[4] = 0xff; ++ rKey.arBSSID[5] = 0xff; ++ rKey.u4KeyIndex |= BIT(31); /* ???? */ ++ } ++ if (params->key) { ++ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ ++ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); ++ } ++ rKey.u4KeyLength = params->key_len; ++ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddP2PKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ if (rStatus == WLAN_STATUS_SUCCESS) ++ i4Rslt = 0; ++ ++ return i4Rslt; ++} ++ ++int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) ++) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, ++ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_REMOVE_KEY_T prRemoveKey; ++ INT_32 i4Rslt = -EINVAL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ i4Rslt = 0; ++ return i4Rslt; ++ } ++ ++ kalMemZero(&prRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); ++ if (mac_addr) ++ memcpy(prRemoveKey.arBSSID, mac_addr, PARAM_MAC_ADDR_LEN); ++ prRemoveKey.u4KeyIndex = key_index; ++ prRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveP2PKey, ++ &prRemoveKey, prRemoveKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_SUCCESS) ++ i4Rslt = 0; ++ ++ return i4Rslt; ++} ++ ++int ++mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, ++ struct net_device *netdev, u8 key_index, bool unicast, bool multicast) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return WLAN_STATUS_SUCCESS; ++} ++ ++int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_info *sinfo) ++{ ++ INT_32 i4RetRslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; ++ P2P_STATION_INFO_T rP2pStaInfo; ++ ++ ASSERT(wiphy); ++ ++ do { ++ if ((wiphy == NULL) || (ndev == NULL) || (sinfo == NULL) || (mac == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_get_station\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ prP2pGlueInfo = prGlueInfo->prP2PInfo; ++ ++ sinfo->filled = 0; ++ ++ /* Get station information. */ ++ /* 1. Inactive time? */ ++ p2pFuncGetStationInfo(prGlueInfo->prAdapter, (PUINT_8)mac, &rP2pStaInfo); ++ ++ /* Inactive time. */ ++ sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME; ++ sinfo->inactive_time = rP2pStaInfo.u4InactiveTime; ++ sinfo->generation = prP2pGlueInfo->i4Generation; ++ ++ i4RetRslt = 0; ++ } while (FALSE); ++ ++ return i4RetRslt; ++} ++ ++int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; ++ P_MSG_P2P_SCAN_REQUEST_T prMsgScanRequest = (P_MSG_P2P_SCAN_REQUEST_T) NULL; ++ UINT_32 u4MsgSize = 0, u4Idx = 0; ++ INT_32 i4RetRslt = -EINVAL; ++ P_RF_CHANNEL_INFO_T prRfChannelInfo = (P_RF_CHANNEL_INFO_T) NULL; ++ P_P2P_SSID_STRUCT_T prSsidStruct = (P_P2P_SSID_STRUCT_T) NULL; ++ struct ieee80211_channel *prChannel = NULL; ++ struct cfg80211_ssid *prSsid = NULL; ++ ++ /* [---------Channel---------] [---------SSID---------][---------IE---------] */ ++ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan\n"); ++ ++ do { ++ if ((wiphy == NULL) || (request == NULL)) ++ break; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prP2pGlueInfo = prGlueInfo->prP2PInfo; ++ ++ if (prP2pGlueInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_scan.\n"); ++ ++ if (prP2pGlueInfo->prScanRequest != NULL) { ++ /* There have been a scan request on-going processing. */ ++ DBGLOG(P2P, TRACE, "There have been a scan request on-going processing.\n"); ++ break; ++ } ++ ++ prP2pGlueInfo->prScanRequest = request; ++ ++ /* Should find out why the n_channels so many? */ ++ if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) { ++ request->n_channels = MAXIMUM_OPERATION_CHANNEL_LIST; ++ DBGLOG(P2P, TRACE, "Channel list exceed the maximun support.\n"); ++ } ++ ++ u4MsgSize = sizeof(MSG_P2P_SCAN_REQUEST_T) + ++ (request->n_channels * sizeof(RF_CHANNEL_INFO_T)) + ++ (request->n_ssids * sizeof(PARAM_SSID_T)) + request->ie_len; ++ ++ prMsgScanRequest = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, u4MsgSize); ++ ++ if (prMsgScanRequest == NULL) { ++ ASSERT(FALSE); ++ i4RetRslt = -ENOMEM; ++ prP2pGlueInfo->prScanRequest = NULL; ++ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan Allocate Mem failed\n"); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "Generating scan request message.\n"); ++ ++ prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; ++ ++ DBGLOG(P2P, INFO, "Requesting channel number:%d.\n", request->n_channels); ++ ++ for (u4Idx = 0; u4Idx < request->n_channels; u4Idx++) { ++ /* Translate Freq from MHz to channel number. */ ++ prRfChannelInfo = &(prMsgScanRequest->arChannelListInfo[u4Idx]); ++ prChannel = request->channels[u4Idx]; ++ ++ prRfChannelInfo->ucChannelNum = nicFreq2ChannelNum(prChannel->center_freq * 1000); ++ DBGLOG(P2P, TRACE, "Scanning Channel:%d, freq: %d\n", ++ prRfChannelInfo->ucChannelNum, prChannel->center_freq); ++ switch (prChannel->band) { ++ case NL80211_BAND_2GHZ: ++ prRfChannelInfo->eBand = BAND_2G4; ++ break; ++ case NL80211_BAND_5GHZ: ++ prRfChannelInfo->eBand = BAND_5G; ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "UNKNOWN Band info from supplicant\n"); ++ prRfChannelInfo->eBand = BAND_NULL; ++ break; ++ } ++ ++ /* Iteration. */ ++ prRfChannelInfo++; ++ } ++ prMsgScanRequest->u4NumChannel = request->n_channels; ++ ++ DBGLOG(P2P, TRACE, "Finish channel list.\n"); ++ ++ /* SSID */ ++ prSsid = request->ssids; ++ prSsidStruct = (P_P2P_SSID_STRUCT_T) prRfChannelInfo; ++ if (prSsidStruct) { ++ if (request->n_ssids) { ++ ASSERT((ULONG) prSsidStruct == (ULONG)&(prMsgScanRequest->arChannelListInfo[u4Idx])); ++ prMsgScanRequest->prSSID = prSsidStruct; ++ } ++ ++ for (u4Idx = 0; u4Idx < request->n_ssids; u4Idx++) { ++ COPY_SSID(prSsidStruct->aucSsid, ++ prSsidStruct->ucSsidLen, request->ssids->ssid, request->ssids->ssid_len); ++ ++ prSsidStruct++; ++ prSsid++; ++ } ++ ++ prMsgScanRequest->i4SsidNum = request->n_ssids; ++ ++ DBGLOG(P2P, TRACE, "Finish SSID list:%d.\n", request->n_ssids); ++ ++ /* IE BUFFERS */ ++ prMsgScanRequest->pucIEBuf = (PUINT_8) prSsidStruct; ++ if (request->ie_len) { ++ kalMemCopy(prMsgScanRequest->pucIEBuf, request->ie, request->ie_len); ++ prMsgScanRequest->u4IELen = request->ie_len; ++ } ++ } ++ ++ DBGLOG(P2P, TRACE, "Finish IE Buffer.\n"); ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = FALSE; ++#endif ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgScanRequest, MSG_SEND_METHOD_BUF); ++ ++ i4RetRslt = 0; ++ } while (FALSE); ++ ++ return i4RetRslt; ++} /* mtk_p2p_cfg80211_scan */ ++ ++int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ do { ++ if (wiphy == NULL) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_wiphy_params\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ if (changed & WIPHY_PARAM_RETRY_SHORT) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY short param is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_RETRY_LONG) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY long param is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY fragmentation threshold is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_RTS_THRESHOLD) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The RETRY RTS threshold is changed.\n"); ++ } ++ ++ if (changed & WIPHY_PARAM_COVERAGE_CLASS) { ++ /* TODO: */ ++ DBGLOG(P2P, TRACE, "The coverage class is changed???\n"); ++ } ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_set_wiphy_params */ ++ ++int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ enum nl80211_tx_power_setting type, int mbm) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ int *dbm) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} ++ ++int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 value; ++ UINT_32 u4Leng; ++ ++ ASSERT(wiphy); ++ ++ if (enabled) ++ value = 2; ++ else ++ value = 0; ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_power_mgmt ps=%d.\n", enabled); ++ ++ /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ return 0; ++} ++ ++/* &&&&&&&&&&&&&&&&&&&&&&&&&& Add for ICS Wi-Fi Direct Support. &&&&&&&&&&&&&&&&&&&&&&& */ ++int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; ++ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ /* P_IE_SSID_T prSsidIE = (P_IE_SSID_T)NULL; */ ++ ++ struct wireless_dev *wdev = dev->ieee80211_ptr; ++ struct cfg80211_chan_def *chandef = &wdev->preset_chandef; ++ ++ do { ++ if ((wiphy == NULL) || (settings == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_start_ap.\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++#if 1 ++ mtk_p2p_cfg80211_set_channel(wiphy, chandef); ++#else ++ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->ucOperatingChnl = ++ (chandef->chan->center_freq - 2407) / 5; ++ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->eBand = BAND_2G4; ++#endif ++ ++ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_BEACON_UPDATE_T) + ++ settings->beacon.head_len + ++ settings->beacon.tail_len)); ++ ++ if (prP2pBcnUpdateMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; ++ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; ++ ++ if (settings->beacon.head_len != 0) { ++ kalMemCopy(pucBuffer, settings->beacon.head, settings->beacon.head_len); ++ ++ prP2pBcnUpdateMsg->u4BcnHdrLen = settings->beacon.head_len; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) settings->beacon.head_len); ++ } else { ++ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = NULL; ++ } ++ ++ if (settings->beacon.tail_len != 0) { ++ UINT_32 ucLen = settings->beacon.tail_len; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; ++ ++ /*Add TIM IE */ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; ++ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ ++ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; ++ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; ++ /* will be overwrite by FW */ ++ ucLen += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ kalMemCopy(pucBuffer, settings->beacon.tail, settings->beacon.tail_len); ++ ++ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; ++ } else { ++ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = NULL; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); ++ ++ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, sizeof(MSG_P2P_START_AP_T)); ++ ++ if (prP2pStartAPMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pStartAPMsg->rMsgHdr.eMsgId = MID_MNY_P2P_START_AP; ++ ++ prP2pStartAPMsg->fgIsPrivacy = settings->privacy; ++ ++ prP2pStartAPMsg->u4BcnInterval = settings->beacon_interval; ++ ++ prP2pStartAPMsg->u4DtimPeriod = settings->dtim_period; ++ ++ /* Copy NO SSID. */ ++ prP2pStartAPMsg->ucHiddenSsidType = settings->hidden_ssid; ++ ++ COPY_SSID(prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen, settings->ssid, settings->ssid_len); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pStartAPMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); ++#endif ++ ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++/* /////////////////////// */ ++ /** ++ * struct cfg80211_ap_settings - AP configuration ++ * ++ * Used to configure an AP interface. ++ * ++ * @beacon: beacon data ++ * @beacon_interval: beacon interval ++ * @dtim_period: DTIM period ++ * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from ++ * user space) ++ * @ssid_len: length of @ssid ++ * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames ++ * @crypto: crypto settings ++ * @privacy: the BSS uses privacy ++ * @auth_type: Authentication type (algorithm) ++ * @inactivity_timeout: time in seconds to determine station's inactivity. ++ */ ++/* struct cfg80211_ap_settings { */ ++/* struct cfg80211_beacon_data beacon; */ ++/* */ ++/* int beacon_interval, dtim_period; */ ++/* const u8 *ssid; */ ++/* size_t ssid_len; */ ++/* enum nl80211_hidden_ssid hidden_ssid; */ ++/* struct cfg80211_crypto_settings crypto; */ ++/* bool privacy; */ ++/* enum nl80211_auth_type auth_type; */ ++/* int inactivity_timeout; */ ++/* }; */ ++/* ////////////////// */ ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_start_ap */ ++ ++int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; ++ PUINT_8 pucBuffer = (PUINT_8) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (info == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_beacon.\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_BEACON_UPDATE_T) + ++ info->head_len + info->tail_len)); ++ ++ if (prP2pBcnUpdateMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; ++ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; ++ ++ if (info->head_len != 0) { ++ kalMemCopy(pucBuffer, info->head, info->head_len); ++ ++ prP2pBcnUpdateMsg->u4BcnHdrLen = info->head_len; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; ++ ++ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) info->head_len); ++ } else { ++ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnHdr = NULL; ++ } ++ ++ if (info->tail_len != 0) { ++ UINT_32 ucLen = info->tail_len; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; ++ ++ /*Add TIM IE */ ++ /* IEEE 802.11 2007 - 7.3.2.6 */ ++ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; ++ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; ++ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ ++ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ ++ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; ++ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; ++ /* will be overwrite by FW */ ++ ucLen += IE_SIZE(pucBuffer); ++ pucBuffer += IE_SIZE(pucBuffer); ++ ++ kalMemCopy(pucBuffer, info->tail, info->tail_len); ++ ++ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; ++ } else { ++ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; ++ ++ prP2pBcnUpdateMsg->pucBcnBody = NULL; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); ++ ++/* ////////////////////////// */ ++/** ++ * struct cfg80211_beacon_data - beacon data ++ * @head: head portion of beacon (before TIM IE) ++ * or %NULL if not changed ++ * @tail: tail portion of beacon (after TIM IE) ++ * or %NULL if not changed ++ * @head_len: length of @head ++ * @tail_len: length of @tail ++ * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL ++ * @beacon_ies_len: length of beacon_ies in octets ++ * @proberesp_ies: extra information element(s) to add into Probe Response ++ * frames or %NULL ++ * @proberesp_ies_len: length of proberesp_ies in octets ++ * @assocresp_ies: extra information element(s) to add into (Re)Association ++ * Response frames or %NULL ++ * @assocresp_ies_len: length of assocresp_ies in octets ++ * @probe_resp_len: length of probe response template (@probe_resp) ++ * @probe_resp: probe response template (AP mode only) ++ */ ++/* struct cfg80211_beacon_data { */ ++/* const u8 *head, *tail; */ ++/* const u8 *beacon_ies; */ ++/* const u8 *proberesp_ies; */ ++/* const u8 *assocresp_ies; */ ++/* const u8 *probe_resp; */ ++ ++/* size_t head_len, tail_len; */ ++/* size_t beacon_ies_len; */ ++/* size_t proberesp_ies_len; */ ++/* size_t assocresp_ies_len; */ ++/* size_t probe_resp_len; */ ++/* }; */ ++ ++/* ////////////////////////// */ ++ ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_change_beacon */ ++ ++int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_SWITCH_OP_MODE_T prP2pSwitchMode = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; ++ ++ do { ++ if (wiphy == NULL) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_stop_ap.\n"); ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* Switch OP MOde. */ ++ prP2pSwitchMode = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_SWITCH_OP_MODE_T)); ++ ++ if (prP2pSwitchMode == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prP2pSwitchMode->rMsgHdr.eMsgId = MID_MNY_P2P_STOP_AP; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pSwitchMode, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++ if (glIsChipNeedWakelock(prGlueInfo)) ++ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); ++#endif ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_stop_ap */ ++ ++/* TODO: */ ++int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* not implemented yet */ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_deauth.\n"); ++ ++ return -EINVAL; ++} /* mtk_p2p_cfg80211_deauth */ ++ ++/* TODO: */ ++int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_disassoc.\n"); ++ ++ /* not implemented yet */ ++ ++ return -EINVAL; ++} /* mtk_p2p_cfg80211_disassoc */ ++ ++int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, ++ unsigned int duration, u64 *cookie) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ P_MSG_P2P_CHNL_REQUEST_T prMsgChnlReq = (P_MSG_P2P_CHNL_REQUEST_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) ++ break; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ *cookie = prGlueP2pInfo->u8Cookie++; ++ ++ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_REQUEST_T)); ++ ++ if (prMsgChnlReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_remain_on_channel\n"); ++ ++ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ; ++ prMsgChnlReq->u8Cookie = *cookie; ++ prMsgChnlReq->u4Duration = duration; ++ ++ mtk_p2p_cfg80211func_channel_format_switch(chan, NL80211_CHAN_HT20, /* 4 KH Need Check */ ++ &prMsgChnlReq->rChannelInfo, &prMsgChnlReq->eChnlSco); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} ++ ++/* mtk_p2p_cfg80211_remain_on_channel */ ++int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ u64 cookie) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_MSG_P2P_CHNL_ABORT_T prMsgChnlAbort = (P_MSG_P2P_CHNL_ABORT_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL)) ++ break; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_ABORT_T)); ++ ++ if (prMsgChnlAbort == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_cancel_remain_on_channel\n"); ++ ++ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT; ++ prMsgChnlAbort->u8Cookie = cookie; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_cancel_remain_on_channel */ ++ ++int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prMsgExtListenReq = NULL; ++ P_MSG_P2P_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; ++ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; ++ PUINT_8 pucFrameBuf = (PUINT_8) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) ++ break; ++ /* DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_mgmt_tx\n")); */ ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ *cookie = prGlueP2pInfo->u8Cookie++; ++ ++ /* Channel & Channel Type & Wait time are ignored. */ ++ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_MGMT_TX_REQUEST_T)); ++ ++ if (prMsgTxReq == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ /* Here need to extend the listen interval */ ++ prMsgExtListenReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T)); ++ if (prMsgExtListenReq) { ++ prMsgExtListenReq->rMsgHdr.eMsgId = MID_MNY_P2P_EXTEND_LISTEN_INTERVAL; ++ prMsgExtListenReq->wait = params->wait; ++ DBGLOG(P2P, INFO, "ext listen, wait: %d\n", prMsgExtListenReq->wait); ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T)prMsgExtListenReq, ++ MSG_SEND_METHOD_BUF); ++ } ++ ++ prMsgTxReq->fgNoneCckRate = FALSE; ++ prMsgTxReq->fgIsWaitRsp = TRUE; ++ ++ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); ++ ++ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; ++ if (prMsgTxReq->prMgmtMsduInfo == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prMsgTxReq->u8Cookie = *cookie; ++ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX; ++ ++ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); ++ ++ kalMemCopy(pucFrameBuf, params->buf, params->len); ++ ++ prMgmtFrame->u2FrameLength = params->len; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { ++ if (prMsgTxReq->prMgmtMsduInfo != NULL) ++ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); ++ ++ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); ++ } ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_mgmt_tx */ ++ ++int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ switch (params->use_cts_prot) { ++ case -1: ++ DBGLOG(P2P, TRACE, "CTS protection no change\n"); ++ break; ++ case 0: ++ DBGLOG(P2P, TRACE, "CTS protection disable.\n"); ++ break; ++ case 1: ++ DBGLOG(P2P, TRACE, "CTS protection enable\n"); ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "CTS protection unknown\n"); ++ break; ++ } ++ ++ switch (params->use_short_preamble) { ++ case -1: ++ DBGLOG(P2P, TRACE, "Short prreamble no change\n"); ++ break; ++ case 0: ++ DBGLOG(P2P, TRACE, "Short prreamble disable.\n"); ++ break; ++ case 1: ++ DBGLOG(P2P, TRACE, "Short prreamble enable\n"); ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Short prreamble unknown\n"); ++ break; ++ } ++ ++#if 0 ++ /* not implemented yet */ ++ p2pFuncChangeBssParam(prGlueInfo->prAdapter, ++ prBssInfo->fgIsProtection, ++ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortSlotTime, ++ /* Basic rates */ ++ /* basic rates len */ ++ /* ap isolate */ ++ /* ht opmode. */ ++ ); ++#else ++ i4Rslt = 0; ++#endif ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_change_bss */ ++ ++int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params) ++//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_CONNECTION_ABORT_T prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ UINT_8 aucBcMac[] = BC_MAC_ADDR; ++ const UINT_8 *mac = NULL; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL)) ++ break; ++ ++ if (params->mac == NULL) ++ mac = aucBcMac; ++ else ++ mac = params->mac; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_del_station.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(MSG_P2P_CONNECTION_ABORT_T), ++ VIR_MEM_TYPE); */ ++ prDisconnectMsg = ++ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ ++ if (prDisconnectMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); ++ prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnectMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++} /* mtk_p2p_cfg80211_del_station */ ++ ++int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL) || (sme == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_connect.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prConnReqMsg = ++ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ (sizeof(MSG_P2P_CONNECTION_REQUEST_T) + sme->ie_len)); ++ ++ if (prConnReqMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prConnReqMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; ++ ++ COPY_SSID(prConnReqMsg->rSsid.aucSsid, prConnReqMsg->rSsid.ucSsidLen, sme->ssid, sme->ssid_len); ++ ++ COPY_MAC_ADDR(prConnReqMsg->aucBssid, sme->bssid); ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_connect to %pM, IE len: %d\n", ++ prConnReqMsg->aucBssid, sme->ie_len); ++ ++ DBGLOG(P2P, TRACE, "Assoc Req IE Buffer Length:%d\n", sme->ie_len); ++ kalMemCopy(prConnReqMsg->aucIEBuf, sme->ie, sme->ie_len); ++ prConnReqMsg->u4IELen = sme->ie_len; ++ ++ mtk_p2p_cfg80211func_channel_format_switch(sme->channel, ++ NL80211_CHAN_NO_HT, ++ &prConnReqMsg->rChannelInfo, &prConnReqMsg->eChnlSco); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prConnReqMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_connect */ ++ ++int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; ++ UINT_8 aucBCAddr[] = BC_MAC_ADDR; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL)) ++ break; ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++/* prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(P_MSG_P2P_CONNECTION_ABORT_T), VIR_MEM_TYPE); */ ++ prDisconnMsg = ++ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_ABORT_T)); ++ ++ if (prDisconnMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.Allocate Memory Failed.\n"); ++ break; ++ } ++ ++ prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; ++ prDisconnMsg->u2ReasonCode = reason_code; ++ prDisconnMsg->fgSendDeauth = TRUE; ++ COPY_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCAddr); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_disconnect */ ++ ++int ++mtk_p2p_cfg80211_change_iface(IN struct wiphy *wiphy, ++ IN struct net_device *ndev, ++ IN enum nl80211_iftype type,/* IN u32 *flags,*/ IN struct vif_params *params) ++{ ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ INT_32 i4Rslt = -EINVAL; ++ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchModeMsg = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (ndev == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_iface.\n"); ++ ++ if (ndev->ieee80211_ptr) ++ ndev->ieee80211_ptr->iftype = type; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* Switch OP MOde. */ ++ prSwitchModeMsg = ++ (P_MSG_P2P_SWITCH_OP_MODE_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, ++ sizeof(MSG_P2P_SWITCH_OP_MODE_T)); ++ ++ if (prSwitchModeMsg == NULL) { ++ ASSERT(FALSE); ++ i4Rslt = -ENOMEM; ++ break; ++ } ++ ++ prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; ++ ++ switch (type) { ++ case NL80211_IFTYPE_P2P_CLIENT: ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n"); ++ case NL80211_IFTYPE_STATION: ++ if (type == NL80211_IFTYPE_STATION) ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n"); ++ prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; ++ break; ++ case NL80211_IFTYPE_AP: ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n"); ++ case NL80211_IFTYPE_P2P_GO: ++ if (type == NL80211_IFTYPE_P2P_GO) ++ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_GO not AP.\n"); ++ prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "Other type :%d .\n", type); ++ prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE; ++ break; ++ } ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSwitchModeMsg, MSG_SEND_METHOD_BUF); ++ ++ i4Rslt = 0; ++ ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++} /* mtk_p2p_cfg80211_change_iface */ ++ ++int mtk_p2p_cfg80211_set_channel(IN struct wiphy *wiphy, ++ struct cfg80211_chan_def *chandef) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ RF_CHANNEL_INFO_T rRfChnlInfo; ++ ++ do { ++ if (wiphy == NULL) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_channel.\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ mtk_p2p_cfg80211func_channel_format_switch(chandef->chan, chandef->width, &rRfChnlInfo, NULL); ++ p2pFuncSetChannel(prGlueInfo->prAdapter, &rRfChnlInfo); ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++ ++} ++ ++/* mtk_p2p_cfg80211_set_channel */ ++ ++int ++mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, ++ IN struct net_device *dev, ++ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask) ++{ ++ INT_32 i4Rslt = -EINVAL; ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (dev == NULL) || (mask == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_bitrate_mask\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ /* TODO: Set bitrate mask of the peer? */ ++ ++ i4Rslt = 0; ++ } while (FALSE); ++ ++ return i4Rslt; ++} /* mtk_p2p_cfg80211_set_bitrate_mask */ ++ ++void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ IN u16 frame_type, IN bool reg) ++{ ++#if 0 ++ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; ++#endif ++ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; ++ ++ do { ++ if ((wiphy == NULL) || (wdev == NULL)) ++ break; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_mgmt_frame_register\n"); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ switch (frame_type) { ++ case MAC_FRAME_PROBE_REQ: ++ if (reg) { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); ++ } else { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; ++ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); ++ } ++ break; ++ case MAC_FRAME_ACTION: ++ if (reg) { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); ++ } else { ++ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; ++ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); ++ } ++ break; ++ default: ++ DBGLOG(P2P, ERROR, "Ask frog to add code for mgmt:%x\n", frame_type); ++ break; ++ } ++ ++ if ((prGlueInfo->prAdapter != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { ++ ++ /* prGlueInfo->u4Flag |= GLUE_FLAG_FRAME_FILTER; */ ++ set_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag); ++ ++ /* wake up main thread */ ++ wake_up_interruptible(&prGlueInfo->waitq); ++ ++ if (in_interrupt()) ++ DBGLOG(P2P, TRACE, "It is in interrupt level\n"); ++ } ++#if 0 ++ ++ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ sizeof ++ (MSG_P2P_MGMT_FRAME_REGISTER_T)); ++ ++ if (prMgmtFrameRegister == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; ++ ++ prMgmtFrameRegister->u2FrameType = frame_type; ++ prMgmtFrameRegister->fgIsRegister = reg; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); ++ ++#endif ++ ++ } while (FALSE); ++ ++} /* mtk_p2p_cfg80211_mgmt_frame_register */ ++ ++BOOLEAN ++mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, ++ IN enum nl80211_channel_type channel_type, ++ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco) ++{ ++ BOOLEAN fgIsValid = FALSE; ++ ++ do { ++ if (channel == NULL) ++ break; ++ ++ if (prRfChnlInfo) { ++ prRfChnlInfo->ucChannelNum = nicFreq2ChannelNum(channel->center_freq * 1000); ++ ++ switch (channel->band) { ++ case NL80211_BAND_2GHZ: ++ prRfChnlInfo->eBand = BAND_2G4; ++ break; ++ case NL80211_BAND_5GHZ: ++ prRfChnlInfo->eBand = BAND_5G; ++ break; ++ default: ++ prRfChnlInfo->eBand = BAND_2G4; ++ break; ++ } ++ ++ } ++ ++ if (prChnlSco) { ++ ++ switch (channel_type) { ++ case NL80211_CHAN_NO_HT: ++ *prChnlSco = CHNL_EXT_SCN; ++ break; ++ case NL80211_CHAN_HT20: ++ *prChnlSco = CHNL_EXT_SCN; ++ break; ++ case NL80211_CHAN_HT40MINUS: ++ *prChnlSco = CHNL_EXT_SCA; ++ break; ++ case NL80211_CHAN_HT40PLUS: ++ *prChnlSco = CHNL_EXT_SCB; ++ break; ++ default: ++ ASSERT(FALSE); ++ *prChnlSco = CHNL_EXT_SCN; ++ break; ++ } ++ } ++ ++ fgIsValid = TRUE; ++ } while (FALSE); ++ ++ return fgIsValid; ++} ++ ++/* mtk_p2p_cfg80211func_channel_format_switch */ ++ ++#if CONFIG_NL80211_TESTMODE ++int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_TEST_PARAMS prParams = (P_NL80211_DRIVER_TEST_PARAMS) NULL; ++ INT_32 i4Status = -EINVAL; ++ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = NULL; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_cmd\n"); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_TEST_PARAMS) data; ++ } else { ++ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_cmd, data is NULL\n"); ++ return i4Status; ++ } ++ ++ if (prParams->index >> 24 == 0x01) { ++ /* New version */ ++ } else { ++ /* Old version */ ++ mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len); ++ i4Status = 0; ++ return i4Status; ++ } ++ ++ /* Clear the version byte */ ++ prParams->index = prParams->index & ~BITS(24, 31); ++ ++ if (prParams) { ++ switch (prParams->index) { ++ case 1: /* P2P Simga */ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ { ++ P_NL80211_DRIVER_SW_CMD_PARAMS prParamsCmd; ++ ++ prParamsCmd = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; ++ ++ if ((prParamsCmd->adr & 0xffff0000) == 0xffff0000) { ++ i4Status = mtk_p2p_cfg80211_testmode_sw_cmd(wiphy, data, len); ++ break; ++ } ++ } ++#endif ++ i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(wiphy, data, len); ++ break; ++#if CFG_SUPPORT_WFD ++ case 2: /* WFD */ ++ i4Status = mtk_p2p_cfg80211_testmode_wfd_update_cmd(wiphy, data, len); ++ break; ++#endif ++ case 3: /* Hotspot Client Management */ ++ i4Status = mtk_p2p_cfg80211_testmode_hotspot_block_cmd(wiphy, data, len); ++ break; ++ case 0x10: ++ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); ++ break; ++#if 1 ++ case 0x11: /*NFC Beam + Indication */ ++ prChnlReqInfo = &prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; ++ if (data && len) { ++ P_NL80211_DRIVER_SET_NFC_PARAMS prParams = (P_NL80211_DRIVER_SET_NFC_PARAMS) data; ++ ++ prChnlReqInfo->NFC_BEAM = prParams->NFC_Enable; ++ DBGLOG(P2P, INFO, "NFC: BEAM[%d]\n", prChnlReqInfo->NFC_BEAM); ++ } ++ break; ++ case 0x12: /*NFC Beam + Indication */ ++ DBGLOG(P2P, INFO, "NFC: Polling\n"); ++ i4Status = mtk_cfg80211_testmode_get_scan_done(wiphy, data, len, prGlueInfo); ++ break; ++#endif ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ case 0x30: ++ i4Status = mtk_cfg80211_testmode_get_lte_channel(wiphy, data, len, prGlueInfo); ++ break; ++#endif ++ ++ default: ++ i4Status = -EINVAL; ++ break; ++ } ++ } ++ ++ return i4Status; ++} ++ ++int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ NL80211_DRIVER_TEST_PRE_PARAMS rParams; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_32 index_mode; ++ UINT_32 index; ++ INT_32 value; ++ int status = 0; ++ UINT_32 u4Leng; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ kalMemZero(&rParams, sizeof(NL80211_DRIVER_TEST_PRE_PARAMS)); ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd\n"); ++ ++ if (data && len) ++ memcpy(&rParams, data, len); ++ ++ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA,idx_mode=%d idx=%d value=%u\n", ++ (INT_16) rParams.idx_mode, (INT_16) rParams.idx, rParams.value); ++ ++ index_mode = rParams.idx_mode; ++ index = rParams.idx; ++ value = rParams.value; ++ ++ switch (index) { ++ case 0: /* Listen CH */ ++ break; ++ case 1: /* P2p mode */ ++ break; ++ case 4: /* Noa duration */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 5: /* Noa interval */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 6: /* Noa count */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 100: /* Oper CH */ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ /* prP2pConnSettings->ucOperatingChnl = value; */ ++ break; ++ case 101: /* Local config Method, for P2P SDK */ ++ prP2pConnSettings->u2LocalConfigMethod = value; ++ break; ++ case 102: /* Sigma P2p reset */ ++ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ ++ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ ++ p2pFsmUninit(prGlueInfo->prAdapter); ++ p2pFsmInit(prGlueInfo->prAdapter); ++ break; ++ case 103: /* WPS MODE */ ++ kalP2PSetWscMode(prGlueInfo, value); ++ break; ++ case 104: /* P2p send persence, duration */ ++ break; ++ case 105: /* P2p send persence, interval */ ++ break; ++ case 106: /* P2P set sleep */ ++ value = 1; ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ case 107: /* P2P set opps, CTWindowl */ ++ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; ++ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ ++ break; ++ case 108: /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ ++ break; ++ default: ++ break; ++ } ++ ++ return status; ++ ++} ++ ++int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_P2P_SIGMA_PARAMS prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ UINT_32 index; ++ INT_32 value; ++ int status = 0; ++ UINT_32 u4Leng; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd\n"); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) data; ++ } else { ++ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd, data is NULL or len is 0\n"); ++ return -EINVAL; ++ } ++ ++ index = (INT_32) prParams->idx; ++ value = (INT_32) prParams->value; ++ ++ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA, idx=%d value=%d\n", ++ (INT_32) prParams->idx, (INT_32) prParams->value); ++ ++ switch (index) { ++ case 0: /* Listen CH */ ++ break; ++ case 1: /* P2p mode */ ++ break; ++ case 4: /* Noa duration */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 5: /* Noa interval */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; ++ /* only to apply setting when setting NOA count */ ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 6: /* Noa count */ ++ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; ++ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ ++ break; ++ case 100: /* Oper CH */ ++ /* 20110920 - frog: User configurations are placed in ConnSettings. */ ++ /* prP2pConnSettings->ucOperatingChnl = value; */ ++ break; ++ case 101: /* Local config Method, for P2P SDK */ ++ prP2pConnSettings->u2LocalConfigMethod = value; ++ break; ++ case 102: /* Sigma P2p reset */ ++ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ ++ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ ++ break; ++ case 103: /* WPS MODE */ ++ kalP2PSetWscMode(prGlueInfo, value); ++ break; ++ case 104: /* P2p send persence, duration */ ++ break; ++ case 105: /* P2p send persence, interval */ ++ break; ++ case 106: /* P2P set sleep */ ++ value = 1; ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ case 107: /* P2P set opps, CTWindowl */ ++ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; ++ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ ++ break; ++ case 108: /* p2p_set_power_save */ ++ kalIoctl(prGlueInfo, ++ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ ++ break; ++ case 109: /* Max Clients */ ++ kalP2PSetMaxClients(prGlueInfo, value); ++ break; ++ case 110: /* Hotspot WPS mode */ ++ kalIoctl(prGlueInfo, wlanoidSetP2pWPSmode, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); ++ break; ++ default: ++ break; ++ } ++ ++ return status; ++ ++} ++ ++#if CFG_SUPPORT_WFD ++int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_WFD_PARAMS prParams = (P_NL80211_DRIVER_WFD_PARAMS) NULL; ++ int status = 0; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; ++ static UINT_8 prevWfdEnable; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ prParams = (P_NL80211_DRIVER_WFD_PARAMS) data; ++ ++ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_wfd_update_cmd\n"); ++ ++ /* to reduce log, print when state changed */ ++ if (prevWfdEnable != prParams->WfdEnable) { ++ prevWfdEnable = prParams->WfdEnable; ++ DBGLOG(P2P, INFO, "WFD Enable:%x\n", prParams->WfdEnable); ++ DBGLOG(P2P, INFO, "WFD Session Available:%x\n", prParams->WfdSessionAvailable); ++ DBGLOG(P2P, INFO, "WFD Couple Sink Status:%x\n", prParams->WfdCoupleSinkStatus); ++ /* aucReserved0[2] */ ++ DBGLOG(P2P, INFO, "WFD Device Info:%x\n", prParams->WfdDevInfo); ++ DBGLOG(P2P, INFO, "WFD Control Port:%x\n", prParams->WfdControlPort); ++ DBGLOG(P2P, INFO, "WFD Maximum Throughput:%x\n", prParams->WfdMaximumTp); ++ DBGLOG(P2P, INFO, "WFD Extend Capability:%x\n", prParams->WfdExtendCap); ++ DBGLOG(P2P, INFO, "WFD Couple Sink Addr %pM\n", prParams->WfdCoupleSinkAddress); ++ DBGLOG(P2P, INFO, "WFD Associated BSSID %pM\n", prParams->WfdAssociatedBssid); ++ /* UINT_8 aucVideolp[4]; */ ++ /* UINT_8 aucAudiolp[4]; */ ++ DBGLOG(P2P, INFO, "WFD Video Port:%x\n", prParams->WfdVideoPort); ++ DBGLOG(P2P, INFO, "WFD Audio Port:%x\n", prParams->WfdAudioPort); ++ DBGLOG(P2P, INFO, "WFD Flag:%x\n", prParams->WfdFlag); ++ DBGLOG(P2P, INFO, "WFD Policy:%x\n", prParams->WfdPolicy); ++ DBGLOG(P2P, INFO, "WFD State:%x\n", prParams->WfdState); ++ /* UINT_8 aucWfdSessionInformationIE[24*8]; */ ++ DBGLOG(P2P, INFO, "WFD Session Info Length:%x\n", prParams->WfdSessionInformationIELen); ++ /* UINT_8 aucReserved1[2]; */ ++ DBGLOG(P2P, INFO, "WFD Primary Sink Addr %pM\n", prParams->aucWfdPrimarySinkMac); ++ DBGLOG(P2P, INFO, "WFD Secondary Sink Addr %pM\n", prParams->aucWfdSecondarySinkMac); ++ DBGLOG(P2P, INFO, "WFD Advanced Flag:%x\n", prParams->WfdAdvanceFlag); ++ DBGLOG(P2P, INFO, "WFD Sigma mode:%x\n", prParams->WfdSigmaMode); ++ /* UINT_8 aucReserved2[64]; */ ++ /* UINT_8 aucReserved3[64]; */ ++ /* UINT_8 aucReserved4[64]; */ ++ } ++ ++ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ ++ kalMemCopy(&prWfdCfgSettings->u4WfdCmdType, &prParams->WfdCmdType, sizeof(WFD_CFG_SETTINGS_T)); ++ ++ prMsgWfdCfgUpdate = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); ++ ++ if (prMsgWfdCfgUpdate == NULL) { ++ ASSERT(FALSE); ++ return status; ++ } ++ ++ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; ++ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); ++#if 0 /* Test Only */ ++/* prWfdCfgSettings->ucWfdEnable = 1; */ ++/* prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; */ ++ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; ++ prWfdCfgSettings->u2WfdDevInfo = 123; ++ prWfdCfgSettings->u2WfdControlPort = 456; ++ prWfdCfgSettings->u2WfdMaximumTp = 789; ++ ++ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_SINK_INFO_VALID; ++ prWfdCfgSettings->ucWfdCoupleSinkStatus = 0xAB; ++ { ++ UINT_8 aucTestAddr[MAC_ADDR_LEN] = { 0x77, 0x66, 0x55, 0x44, 0x33, 0x22 }; ++ ++ COPY_MAC_ADDR(prWfdCfgSettings->aucWfdCoupleSinkAddress, aucTestAddr); ++ } ++ ++ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_EXT_CAPABILITY_VALID; ++ prWfdCfgSettings->u2WfdExtendCap = 0xCDE; ++ ++#endif ++ ++ return status; ++ ++} ++#endif /* CFG_SUPPORT_WFD */ ++ ++int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) NULL; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++ if (data && len) { ++ prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) data; ++ } else { ++ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd, data is NULL or len is 0\n"); ++ return -EINVAL; ++ } ++ ++ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd\n"); ++ ++ return kalP2PSetBlackList(prGlueInfo, prParams->aucBssid, prParams->ucblocked); ++} ++ ++int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; ++ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; ++ int fgIsValid = 0; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(wiphy); ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); ++ ++#if 1 ++ DBGLOG(P2P, TRACE, "--> %s()\n", __func__); ++#endif ++ ++ if (data && len) ++ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; ++ ++ if (prParams) { ++ if (prParams->set == 1) { ++ rstatus = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, ++ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } ++ } ++ ++ if (WLAN_STATUS_SUCCESS != rstatus) ++ fgIsValid = -EFAULT; ++ ++ return fgIsValid; ++} ++ ++#endif ++ ++#endif /* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c +new file mode 100644 +index 000000000000..d0f2d25a4529 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c +@@ -0,0 +1,433 @@ ++/* ++* Copyright (C) 2011-2014 MediaTek Inc. ++* ++* This program is free software: you can redistribute it and/or modify it under the terms of the ++* GNU General Public License version 2 as published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ++* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See the GNU General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along with this program. ++* If not, see . ++*/ ++ ++/* ++** Id: @(#) gl_p2p_init.c@@ ++*/ ++ ++/*! \file gl_p2p_init.c ++ \brief init and exit routines of Linux driver interface for Wi-Fi Direct ++ ++ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define P2P_MODE_INF_NAME "p2p%d" ++#if CFG_TC1_FEATURE ++#define AP_MODE_INF_NAME "wlan%d" ++#else ++#define AP_MODE_INF_NAME "ap%d" ++#endif ++/* #define MAX_INF_NAME_LEN 15 */ ++/* #define MIN_INF_NAME_LEN 1 */ ++ ++#define RUNNING_P2P_MODE 0 ++#define RUNNING_AP_MODE 1 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* Get interface name and running mode from module insertion parameter ++* Usage: insmod p2p.ko mode=1 ++* default: interface name is p2p%d ++* running mode is P2P ++*/ ++static PUCHAR ifname = P2P_MODE_INF_NAME; ++static UINT_16 mode = RUNNING_P2P_MODE; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief check interface name parameter is valid or not ++* if invalid, set ifname to P2P_MODE_INF_NAME ++* ++* ++* \retval ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID p2pCheckInterfaceName(VOID) ++{ ++ ++ if (mode) { ++ mode = RUNNING_AP_MODE; ++ ifname = AP_MODE_INF_NAME; ++ } ++#if 0 ++ UINT_32 ifLen = 0; ++ ++ if (ifname) { ++ ifLen = strlen(ifname); ++ ++ if (ifLen > MAX_INF_NAME_LEN) ++ ifname[MAX_INF_NAME_LEN] = '\0'; ++ else if (ifLen < MIN_INF_NAME_LEN) ++ ifname = P2P_MODE_INF_NAME; ++ } else { ++ ifname = P2P_MODE_INF_NAME; ++ } ++#endif ++} ++ ++void p2pHandleSystemSuspend(void) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_8 ip[4] = { 0 }; ++ UINT_32 u4NumIPv4 = 0; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++ UINT_32 u4NumIPv6 = 0; ++#endif ++ UINT_32 i; ++ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; ++ ++ ++ if (!wlanExportGlueInfo(&prGlueInfo)) { ++ DBGLOG(P2P, INFO, "No glue info\n"); ++ return; ++ } ++ ++ ASSERT(prGlueInfo); ++ /* <1> Sanity check and acquire the net_device */ ++ prDev = prGlueInfo->prP2PInfo->prDevHandler; ++ ASSERT(prDev); ++ ++ /* <3> get the IPv4 address */ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ip is not available.\n"); ++ return; ++ } ++ /* <4> copy the IPv4 address */ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++ /* todo: traverse between list to find whole sets of IPv4 addresses */ ++ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) ++ u4NumIPv4++; ++#ifdef CONFIG_IPV6 ++ /* <5> get the IPv6 address */ ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); ++ return; ++ } ++ /* <6> copy the IPv6 address */ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); ++ /* todo: traverse between list to find whole sets of IPv6 addresses */ ++ ++ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) ++ ; /* Do nothing */ ++#endif ++ /* <7> set up the ARP filter */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen = 0; ++/* UINT_8 aucBuf[32] = {0}; */ ++ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ /* aucBuf; */ ++ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = u4NumIPv4; ++#ifdef CONFIG_IPV6 ++ prParamNetAddrList->u4AddressCount += u4NumIPv6; ++#endif ++ ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ for (i = 0; i < u4NumIPv4; i++) { ++ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++#if 0 ++ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr + sizeof(ip)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); ++#else ++ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; ++ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); ++ ++/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); ++// TODO: frog. The pointer is not right. */ ++ ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + ++ (ULONG) (prParamNetAddr->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP); ++#endif ++ } ++#ifdef CONFIG_IPV6 ++ for (i = 0; i < u4NumIPv6; i++) { ++ prParamNetAddr->u2AddressLength = 6; ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); ++/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6)); */ ++ ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + ++ (ULONG) (prParamNetAddr->u2AddressLength + ++ OFFSET_OF(PARAM_NETWORK_ADDRESS, ++ aucAddress))); ++ ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); ++ } ++#endif ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); ++ } ++} ++ ++void p2pHandleSystemResume(void) ++{ ++ struct net_device *prDev = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_8 ip[4] = { 0 }; ++#ifdef CONFIG_IPV6 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++#endif ++ ++ if (!wlanExportGlueInfo(&prGlueInfo)) { ++ DBGLOG(P2P, WARN, "no glue info\n"); ++ return; ++ } ++ ++ ASSERT(prGlueInfo); ++ /* <1> Sanity check and acquire the net_device */ ++ prDev = prGlueInfo->prP2PInfo->prDevHandler; ++ ASSERT(prDev); ++ ++ /* <3> get the IPv4 address */ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ip is not available.\n"); ++ return; ++ } ++ /* <4> copy the IPv4 address */ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ ++#ifdef CONFIG_IPV6 ++ /* <5> get the IPv6 address */ ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); ++ return; ++ } ++ /* <6> copy the IPv6 address */ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); ++#endif ++ /* <7> clear the ARP filter */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen = 0; ++/* UINT_8 aucBuf[32] = {0}; */ ++ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; ++ /* aucBuf; */ ++ ++ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); ++ ++ prParamNetAddrList->u4AddressCount = 0; ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ ++ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetP2pSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); ++ ++ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* run p2p init procedure, include register pointer to wlan ++* glue register p2p ++* set p2p registered flag ++* \retval 1 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo) ++{ ++ ++ DBGLOG(P2P, TRACE, "p2pLaunch\n"); ++ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) { ++ DBGLOG(P2P, INFO, "p2p already registered\n"); ++ return FALSE; ++ } else if (glRegisterP2P(prGlueInfo, ifname, (BOOLEAN) mode)) { ++ prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE; ++ ++ DBGLOG(P2P, TRACE, "Launch success, fgIsP2PRegistered TRUE.\n"); ++ return TRUE; ++ } ++ DBGLOG(P2P, ERROR, "Launch Fail\n"); ++ ++ return FALSE; ++} ++ ++VOID p2pSetMode(IN BOOLEAN fgIsAPMOde) ++{ ++ if (fgIsAPMOde) { ++ mode = RUNNING_AP_MODE; ++ ifname = AP_MODE_INF_NAME; ++ } else { ++ mode = RUNNING_P2P_MODE; ++ ifname = P2P_MODE_INF_NAME; ++ } ++ ++} /* p2pSetMode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* run p2p exit procedure, include unregister pointer to wlan ++* glue unregister p2p ++* set p2p registered flag ++ ++* \retval 1 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo) ++{ ++ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { ++ DBGLOG(P2P, INFO, "p2p is not Registered.\n"); ++ return FALSE; ++ } ++ /*Check p2p fsm is stop or not. If not then stop now */ ++ if (IS_P2P_ACTIVE(prGlueInfo->prAdapter)) ++ p2pStopImmediate(prGlueInfo); ++ prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE; ++ glUnregisterP2P(prGlueInfo); ++ /*p2p is removed successfully */ ++ return TRUE; ++ ++} ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver entry point when the driver is configured as a Linux Module, and ++* is called once at module load time, by the user-level modutils ++* application: insmod or modprobe. ++* ++* \retval 0 Success ++*/ ++/*----------------------------------------------------------------------------*/ ++static int initP2P(void) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ /*check interface name validation */ ++ p2pCheckInterfaceName(); ++ ++ DBGLOG(P2P, INFO, "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP" : "P2P"); ++ ++ /*register p2p init & exit function to wlan sub module handler */ ++ wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE); ++ ++ /*if wlan is not start yet, do nothing ++ * p2pLaunch will be called by txthread while wlan start ++ */ ++ /*if wlan is not started yet, return FALSE */ ++ if (wlanExportGlueInfo(&prGlueInfo)) { ++ wlanSubModInit(prGlueInfo); ++ return prGlueInfo->prAdapter->fgIsP2PRegistered ? 0 : -EIO; ++ } ++ ++ return 0; ++} /* end of initP2P() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Driver exit point when the driver as a Linux Module is removed. Called ++* at module unload time, by the user level modutils application: rmmod. ++* This is our last chance to clean up after ourselves. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++/* 1 Module Leave Point */ ++static VOID __exit exitP2P(void) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ ++ DBGLOG(P2P, INFO, KERN_INFO DRV_NAME "ExitP2P\n"); ++ ++ /*if wlan is not started yet, return FALSE */ ++ if (wlanExportGlueInfo(&prGlueInfo)) ++ wlanSubModExit(prGlueInfo); ++ /*UNregister p2p init & exit function to wlan sub module handler */ ++ wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE); ++} /* end of exitP2P() */ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c +new file mode 100644 +index 000000000000..11a417e4c74c +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c +@@ -0,0 +1,1314 @@ ++/* ++** Id: @(#) gl_p2p_cfg80211.c@@ ++*/ ++ ++/*! \file gl_p2p_kal.c ++ \brief ++ ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "net/cfg80211.h" ++#include "precomp.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Wi-Fi Direct state from glue layer ++* ++* \param[in] ++* prGlueInfo ++* rPeerAddr ++* \return ++* ENUM_BOW_DEVICE_STATE ++*/ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->prP2PInfo->eState; ++} /* end of kalP2PGetState() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to update the assoc req to p2p ++* ++* \param[in] ++* prGlueInfo ++* pucFrameBody ++* u4FrameBodyLen ++* fgReassocRequest ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) ++{ ++ union iwreq_data wrqu; ++ unsigned char *pucExtraInfo = NULL; ++ unsigned char *pucDesiredIE = NULL; ++/* unsigned char aucExtraInfoBuf[200]; */ ++ PUINT_8 cp; ++ ++ memset(&wrqu, 0, sizeof(wrqu)); ++ ++ if (fgReassocRequest) { ++ if (u4FrameBodyLen < 15) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } else { ++ if (u4FrameBodyLen < 9) { ++ /* ++ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); ++ */ ++ return; ++ } ++ } ++ ++ cp = pucFrameBody; ++ ++ if (fgReassocRequest) { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ /* Current AP address 6 */ ++ cp += 10; ++ u4FrameBodyLen -= 10; ++ } else { ++ /* Capability information field 2 */ ++ /* Listen interval field 2 */ ++ cp += 4; ++ u4FrameBodyLen -= 4; ++ } ++ ++ /* do supplicant a favor, parse to the start of WPA/RSN IE */ ++ if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { ++ /* printk("wextSrchDesiredWPSIE!!\n"); */ ++ /* WPS IE found */ ++ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0x30, &pucDesiredIE)) { ++ /* printk("wextSrchDesiredWPAIE!!\n"); */ ++ /* RSN IE found */ ++ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { ++ /* printk("wextSrchDesiredWPAIE!!\n"); */ ++ /* WPA IE found */ ++ } else { ++ /* no WPA/RSN IE found, skip this event */ ++ goto skip_indicate_event; ++ } ++ ++ /* IWEVASSOCREQIE, indicate binary string */ ++ pucExtraInfo = pucDesiredIE; ++ wrqu.data.length = pucDesiredIE[1] + 2; ++ ++ /* Send event to user space */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVASSOCREQIE, &wrqu, pucExtraInfo); ++ ++skip_indicate_event: ++ return; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Wi-Fi Direct state in glue layer ++* ++* \param[in] ++* prGlueInfo ++* eBowState ++* rPeerAddr ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ if (eState == PARAM_MEDIA_STATE_CONNECTED) { ++ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_CONNECTED; ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_CONNECT=%pM ", rPeerAddr); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++ } else if (eState == PARAM_MEDIA_STATE_DISCONNECTED) { ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_DISCONNECT=%pM ", rPeerAddr); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ } else { ++ ASSERT(0); ++ } ++ ++} /* end of kalP2PSetState() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Wi-Fi Direct operating frequency ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* in unit of KHz ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->prP2PInfo->u4FreqInKHz; ++} /* end of kalP2PGetFreqInKHz() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to retrieve Bluetooth-over-Wi-Fi role ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* 0: P2P Device ++* 1: Group Client ++* 2: Group Owner ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ ASSERT(prGlueInfo); ++ ++ return prGlueInfo->prP2PInfo->ucRole; ++} /* end of kalP2PGetRole() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set Wi-Fi Direct role ++* ++* \param[in] ++* prGlueInfo ++* ucResult ++* 0: successful ++* 1: error ++* ucRole ++* 0: P2P Device ++* 1: Group Client ++* 2: Group Owner ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(ucRole <= 2); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ if (ucResult == 0) ++ prGlueInfo->prP2PInfo->ucRole = ucRole; ++ ++ if (pucSSID) ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, ++ 1 /* persistence or not */ , pucSSID[7], pucSSID[8]); ++ else ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, ++ 1 /* persistence or not */ , '0', '0'); ++ ++ evt.data.length = strlen(aucBuffer); ++ ++ /* if (pucSSID) */ ++ /* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */ ++ ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PSetRole() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set the cipher for p2p ++* ++* \param[in] ++* prGlueInfo ++* u4Cipher ++* ++* \return ++* none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prGlueInfo->prP2PInfo->u4CipherPairwise = u4Cipher; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get the cipher, return for cipher is ccmp ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* TRUE: cipher is ccmp ++* FALSE: cipher is none ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) ++ return TRUE; ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) ++ return TRUE; ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) ++ return FALSE; ++ ++ return FALSE; ++} ++ ++BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) ++ return FALSE; ++ ++ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set the status of WSC ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ prGlueInfo->prP2PInfo->ucWSCRunning = ucWscMode; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get the status of WSC ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return 0; ++ } ++ ++ return prGlueInfo->prP2PInfo->ucWSCRunning; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to get the wsc ie length ++* ++* \param[in] ++* prGlueInfo ++* ucType : 0 for beacon, 1 for probe req, 2 for probe resp ++* ++* \return ++* The WSC IE length ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType) ++{ ++ ASSERT(prGlueInfo); ++ ++ ASSERT(ucType < 3); ++ ++ return prGlueInfo->prP2PInfo->u2WSCIELen[ucType]; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to copy the wsc ie setting from p2p supplicant ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++* The WPS IE length ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer) ++{ ++ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (ucType >= 3) || (pucBuffer == NULL)) ++ break; ++ ++ prGlP2pInfo = prGlueInfo->prP2PInfo; ++ ++ kalMemCopy(pucBuffer, prGlP2pInfo->aucWSCIE[ucType], prGlP2pInfo->u2WSCIELen[ucType]); ++ ++ } while (FALSE); ++ ++} ++ ++VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength) ++{ ++ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (ucType >= 3) || ((u2BufferLength > 0) && (pucBuffer == NULL))) ++ break; ++ ++ if (u2BufferLength > 400) { ++ DBGLOG(P2P, ERROR, ++ "Buffer length is not enough, GLUE only 400 bytes but %d received\n", u2BufferLength); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlP2pInfo = prGlueInfo->prP2PInfo; ++ ++ kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], pucBuffer, u2BufferLength); ++ ++ prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength; ++ ++ } while (FALSE); ++ ++} /* kalP2PUpdateWSC_IE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief indicate an event to supplicant for device connection request ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, ++ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ ++ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ /* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */ ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength; ++ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, pucDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, rPeerAddr); ++ prGlueInfo->prP2PInfo->ucConnReqDevType = ucDevType; ++ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = i4ConfigMethod; ++ prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod; ++ ++ /* prepare event structure */ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWEVCUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateConnReq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for device connection request from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* \param[in] pucGroupBssid Only valid when invitation Type equals to 0. ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, ++ IN PUINT_8 pucSsid, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid) ++{ ++#if 1 ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength = ++ (UINT_32) ((prP2pDevDesc->u2NameLength > 32) ? 32 : prP2pDevDesc->u2NameLength); ++ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, prP2pDevDesc->aucName, ++ prGlueInfo->prP2PInfo->u4ConnReqNameLength); ++ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, prP2pDevDesc->aucDeviceAddr); ++ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqGroupAddr, pucGroupBssid); ++ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = (INT_32) (prP2pDevDesc->u2ConfigMethod); ++ prGlueInfo->prP2PInfo->ucOperatingChnl = ucOperatingChnl; ++ prGlueInfo->prP2PInfo->ucInvitationType = ucInvitationType; ++ ++ /* prepare event structure */ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWEVCUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ return; ++ ++#else ++ P_MSG_P2P_CONNECTION_REQUEST_T prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; ++ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; ++ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; ++ ++ do { ++ ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL)); ++ ++ /* Not a real solution */ ++ ++ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; ++ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; ++ ++ prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, ++ RAM_TYPE_MSG, ++ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ ++ if (prP2pConnReq == NULL) ++ break; ++ ++ kalMemZero(prP2pConnReq, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); ++ ++ prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; ++ ++ prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; ++ ++ COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, prP2pDevDesc->aucDeviceAddr); ++ ++ prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod; ++ ++ if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) { ++ prP2pConnReq->fgIsPersistentGroup = FALSE; ++ prP2pConnReq->fgIsTobeGO = FALSE; ++ ++ } ++ ++ else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) { ++ DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n"); ++ prP2pConnReq->fgIsPersistentGroup = TRUE; ++ prP2pConnReq->fgIsTobeGO = (prGlueInfo->prP2PInfo->ucRole == 2) ? TRUE : FALSE; ++ ++ } ++ ++ p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL); ++ ++ if (ucOperatingChnl != 0) ++ prP2pSpecificBssInfo->ucPreferredChannel = ucOperatingChnl; ++ ++ if ((ucSsidLen < 32) && (pucSsid != NULL)) ++ COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, pucSsid, ucSsidLen); ++ ++ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pConnReq, MSG_SEND_METHOD_BUF); ++ ++ } while (FALSE); ++ ++ /* frog add. */ ++ /* TODO: Invitation Indication */ ++ ++ return; ++#endif ++ ++} /* kalP2PInvitationIndication */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an status to supplicant for device invitation status. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ ++ prGlueInfo->prP2PInfo->u4InvStatus = u4InvStatus; ++ ++ /* prepare event structure */ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS"); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate in IWEVCUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* kalP2PInvitationStatus */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for Service Discovery request from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_REQ %d", ucSeqNum); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PSDREQ event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateSDRequest() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for Service Discovery response ++* from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_RESP %d", ucSeqNum); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PSDREQ event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateSDResponse() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Indicate an event to supplicant for Service Discovery TX Done ++* from other device. ++* ++* \param[in] prGlueInfo Pointer of GLUE_INFO_T ++* \param[in] ucSeqNum Sequence number of the frame ++* \param[in] ucStatus Status code for TX ++* ++* \retval none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus); ++ evt.data.length = strlen(aucBuffer); ++ ++ /* indicate IWEVP2PSDREQ event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++ ++} /* end of kalP2PIndicateSDResponse() */ ++ ++struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return NULL; ++ } ++ ++ return prGlueInfo->prP2PInfo->prDevHandler; ++} ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen) ++{ ++ union iwreq_data evt; ++ UINT_8 aucBuffer[IW_CUSTOM_MAX]; ++ ++ ASSERT(prGlueInfo); ++ ++ memset(&evt, 0, sizeof(evt)); ++ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP="); ++ ++ kalMemCopy(prGlueInfo->prP2PInfo->aucSecCheckRsp, pucRsp, u2RspLen); ++ evt.data.length = strlen(aucBuffer); ++ ++#if DBG ++ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u2RspLen); ++#endif ++ /* indicate in IWECUSTOM event */ ++ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); ++} /* p2pFsmRunEventRxDisassociation */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ++* ++* \param[in] prAdapter Pointer of ADAPTER_T ++* ++* \return none ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) ++{ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, ++ pucNumOfChannel, paucChannelList); ++} /* kalGetChnlList */ ++ ++/* ////////////////////////////////////ICS SUPPORT////////////////////////////////////// */ ++ ++VOID ++kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8SeqNum, ++ IN UINT_32 u4ChannelNum, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration) ++{ ++ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; ++ RF_CHANNEL_INFO_T rChannelInfo; ++ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; ++ ++ do { ++ if (prGlueInfo == NULL) ++ break; ++ ++ kalMemZero(&rChannelInfo, sizeof(RF_CHANNEL_INFO_T)); ++ ++ rChannelInfo.ucChannelNum = u4ChannelNum; ++ rChannelInfo.eBand = eBand; ++ ++ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo, &rChannelInfo); ++ ++ kalP2pFuncGetChannelType(eSco, &eChnlType); ++ ++ cfg80211_ready_on_channel(prGlueInfo->prP2PInfo->prWdev, /* struct wireless_dev, */ ++ u8SeqNum, /* u64 cookie, */ ++ prIEEE80211ChnlStruct, /* struct ieee80211_channel * chan, */ ++ u4Duration, /* unsigned int duration, */ ++ GFP_KERNEL); /* gfp_t gfp */ /* allocation flags */ ++ } while (FALSE); ++ ++} /* kalP2PIndicateChannelReady */ ++ ++VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) ++{ ++ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; ++ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; ++ RF_CHANNEL_INFO_T rRfChannelInfo; ++ ++ do { ++ if ((prGlueInfo == NULL) || (prChnlReqInfo == NULL)) { ++ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prGlueP2pInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n"); ++ ++ rRfChannelInfo.eBand = prChnlReqInfo->eBand; ++ rRfChannelInfo.ucChannelNum = prChnlReqInfo->ucReqChnlNum; ++ ++ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueP2pInfo, &rRfChannelInfo); ++ ++ kalP2pFuncGetChannelType(prChnlReqInfo->eChnlSco, &eChnlType); ++ ++ cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev, /* struct wireless_dev, */ ++ prChnlReqInfo->u8Cookie, prIEEE80211ChnlStruct, GFP_KERNEL); ++ } while (FALSE); ++ ++} /* kalP2PIndicateChannelExpired */ ++ ++VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ struct cfg80211_scan_request *prScanRequest = NULL; ++ struct cfg80211_scan_info info = { ++ .aborted = true, ++ }; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ do { ++ if (prGlueInfo == NULL) { ++ ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prGlueP2pInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ DBGLOG(INIT, TRACE, "[p2p] scan complete %p\n", prGlueP2pInfo->prScanRequest); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ if (prGlueP2pInfo->prScanRequest != NULL) { ++ prScanRequest = prGlueP2pInfo->prScanRequest; ++ prGlueP2pInfo->prScanRequest = NULL; ++ } ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); ++ ++ /* 2. then CFG80211 Indication */ ++ ++ if (prScanRequest != NULL) { ++ ++ /* report all queued beacon/probe response frames to upper layer */ ++ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL); ++ ++ info.aborted = fgIsAbort; ++ DBGLOG(INIT, TRACE, "DBG:p2p_cfg_scan_done\n"); ++ cfg80211_scan_done(prScanRequest, &info); ++ } ++ ++ } while (FALSE); ++ ++} /* kalP2PIndicateScanDone */ ++ ++VOID ++kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBuf, ++ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ struct ieee80211_channel *prChannelEntry = (struct ieee80211_channel *)NULL; ++ struct ieee80211_mgmt *prBcnProbeRspFrame = (struct ieee80211_mgmt *)pucFrameBuf; ++ struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (prChannelInfo == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prGlueP2pInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prChannelEntry = kalP2pFuncGetChannelEntry(prGlueP2pInfo, prChannelInfo); ++ ++ if (prChannelEntry == NULL) { ++ DBGLOG(P2P, WARN, "Unknown channel info\n"); ++ break; ++ } ++ /* rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; */ ++ ++ prCfg80211Bss = cfg80211_inform_bss_frame(prGlueP2pInfo->prWdev->wiphy, /* struct wiphy * wiphy, */ ++ prChannelEntry, ++ prBcnProbeRspFrame, u4BufLen, i4SignalStrength, GFP_KERNEL); ++ ++ /* Return this structure. */ ++ if (!prCfg80211Bss) { ++ DBGLOG(P2P, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", ++ prChannelInfo->ucChannelNum, i4SignalStrength); ++ } else { ++ cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, prCfg80211Bss); ++ DBGLOG(P2P, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", ++ prChannelInfo->ucChannelNum, i4SignalStrength); ++ } ++ } while (FALSE); ++ ++} /* kalP2PIndicateBssInfo */ ++ ++VOID ++kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { ++ DBGLOG(P2P, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", ++ prGlueInfo, pucFrameBuf, u4FrameLen); ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ cfg80211_mgmt_tx_status(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ ++ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); ++ ++ } while (FALSE); ++ ++} /* kalP2PIndicateMgmtTxStatus */ ++ ++VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) ++{ ++#define DBG_P2P_MGMT_FRAME_INDICATION 0 ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ INT_32 i4Freq = 0; ++ UINT_8 ucChnlNum = 0; ++#if DBG_P2P_MGMT_FRAME_INDICATION ++ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; ++#endif ++ ++ do { ++ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; ++ ++#if DBG_P2P_MGMT_FRAME_INDICATION ++ ++ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; ++ ++ switch (prWlanHeader->u2FrameCtrl) { ++ case MAC_FRAME_PROBE_REQ: ++ DBGLOG(P2P, TRACE, "RX Probe Req at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_PROBE_RSP: ++ DBGLOG(P2P, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); ++ break; ++ case MAC_FRAME_ACTION: ++ DBGLOG(P2P, TRACE, "RX Action frame at channel %d ", ucChnlNum); ++ break; ++ default: ++ DBGLOG(P2P, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); ++ break; ++ } ++ ++ DBGLOG(P2P, TRACE, "from: %pM\n", prWlanHeader->aucAddr2); ++#endif ++ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; ++ ++ cfg80211_rx_mgmt(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ ++ i4Freq, ++ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), ++ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_ATOMIC); ++ } while (FALSE); ++ ++} /* kalP2PIndicateRxMgmtFrame */ ++ ++VOID ++kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, ++ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, ++ IN WLAN_STATUS eStatus) ++{ ++ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; ++ ++ do { ++ if (prGlueInfo == NULL) { ++ ASSERT(FALSE); ++ break; ++ } ++ ++ prGlueP2pInfo = prGlueInfo->prP2PInfo; ++ ++ if (prP2pConnInfo) { ++ cfg80211_connect_result(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ ++ prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, ++ prP2pConnInfo->u4BufLength, ++ pucRxIEBuf, u2RxIELen, u2StatusReason, GFP_KERNEL); ++ /* gfp_t gfp */ /* allocation flags */ ++ prP2pConnInfo->fgIsConnRequest = FALSE; ++ } else { ++ /* Disconnect, what if u2StatusReason == 0? */ ++ cfg80211_disconnected(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ ++ u2StatusReason, pucRxIEBuf, u2RxIELen, ++ eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ? true : false, ++ GFP_KERNEL); ++ } ++ ++ } while (FALSE); ++ ++} /* kalP2PGCIndicateConnectionStatus */ ++ ++VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew) ++{ ++ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; ++ struct station_info rStationInfo; ++ ++ memset(&rStationInfo, 0, sizeof(struct station_info)); ++ ++ do { ++ if ((prGlueInfo == NULL) || (prCliStaRec == NULL)) ++ break; ++ ++ prP2pGlueInfo = prGlueInfo->prP2PInfo; ++ ++ if (fgIsNew) { ++ //rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES; ++ rStationInfo.generation = ++prP2pGlueInfo->i4Generation; ++ ++ rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe; ++ rStationInfo.assoc_req_ies_len = prCliStaRec->u2AssocReqIeLen; ++/* rStationInfo.filled |= STATION_INFO_ASSOC_REQ_IES; */ ++ ++ cfg80211_new_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ ++ prCliStaRec->aucMacAddr, &rStationInfo, GFP_KERNEL); ++ } else { ++ ++prP2pGlueInfo->i4Generation; ++ ++ cfg80211_del_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ ++ prCliStaRec->aucMacAddr, GFP_KERNEL); ++ } ++ ++ } while (FALSE); ++ ++ return; ++ ++} /* kalP2PGOStationUpdate */ ++ ++BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type) ++{ ++ BOOLEAN fgIsValid = FALSE; ++ ++ do { ++ if (channel_type) { ++ ++ switch (rChnlSco) { ++ case CHNL_EXT_SCN: ++ *channel_type = NL80211_CHAN_NO_HT; ++ break; ++ case CHNL_EXT_SCA: ++ *channel_type = NL80211_CHAN_HT40MINUS; ++ break; ++ case CHNL_EXT_SCB: ++ *channel_type = NL80211_CHAN_HT40PLUS; ++ break; ++ default: ++ ASSERT(FALSE); ++ *channel_type = NL80211_CHAN_NO_HT; ++ break; ++ } ++ ++ } ++ ++ fgIsValid = TRUE; ++ } while (FALSE); ++ ++ return fgIsValid; ++} /* kalP2pFuncGetChannelType */ ++ ++struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo) ++{ ++ struct ieee80211_channel *prTargetChannelEntry = (struct ieee80211_channel *)NULL; ++ UINT_32 u4TblSize = 0, u4Idx = 0; ++ struct ieee80211_supported_band **bands; ++ ++ do { ++ if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) ++ break; ++ bands = &prP2pInfo->prWdev->wiphy->bands[0]; ++ switch (prChannelInfo->eBand) { ++ case BAND_2G4: ++ prTargetChannelEntry = bands[NL80211_BAND_2GHZ]->channels; ++ u4TblSize = bands[NL80211_BAND_2GHZ]->n_channels; ++ break; ++ case BAND_5G: ++ prTargetChannelEntry = bands[NL80211_BAND_5GHZ]->channels; ++ u4TblSize = bands[NL80211_BAND_5GHZ]->n_channels; ++ break; ++ default: ++ break; ++ } ++ ++ if (prTargetChannelEntry == NULL) ++ break; ++ ++ for (u4Idx = 0; u4Idx < u4TblSize; u4Idx++, prTargetChannelEntry++) { ++ if (prTargetChannelEntry->hw_value == prChannelInfo->ucChannelNum) ++ break; ++ } ++ ++ if (u4Idx == u4TblSize) { ++ prTargetChannelEntry = NULL; ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return prTargetChannelEntry; ++} /* kalP2pFuncGetChannelEntry */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to set the block list of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock) ++{ ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prGlueInfo->prP2PInfo); ++ ++ if (EQUAL_MAC_ADDR(rbssid, aucNullAddr)) ++ return -EINVAL; ++ ++ if (fgIsblock) { ++ for (i = 0; i < 8; i++) { ++ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { ++ break; ++ } else if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr)) { ++ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid); ++ break; ++ } ++ } ++ if (i >= 8) { ++ DBGLOG(P2P, ERROR, "AP black list is full, cannot block more STA!!\n"); ++ return -ENOBUFS; ++ } ++ } else { ++ for (i = 0; i < 8; i++) { ++ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { ++ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr); ++ break; ++ } ++ } ++ if (i >= 8) ++ DBGLOG(P2P, ERROR, "The STA is not found in black list!!\n"); ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to compare the black list of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid) ++{ ++ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; ++ BOOLEAN fgIsExsit = FALSE; ++ UINT_32 i; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(prGlueInfo->prP2PInfo); ++ ++ for (i = 0; i < 8; i++) { ++ if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { ++ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { ++ fgIsExsit = TRUE; ++ return fgIsExsit; ++ } ++ } ++ } ++ ++ return fgIsExsit; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to return the max clients of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return; ++ } ++ ++ if (u4MaxClient == 0 || prGlueInfo->prP2PInfo->ucMaxClients >= P2P_MAXIMUM_CLIENT_COUNT) ++ prGlueInfo->prP2PInfo->ucMaxClients = P2P_MAXIMUM_CLIENT_COUNT; ++ else ++ prGlueInfo->prP2PInfo->ucMaxClients = u4MaxClient; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief to return the max clients of Hotspot ++* ++* \param[in] ++* prGlueInfo ++* ++* \return ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient) ++{ ++ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { ++ ASSERT(FALSE); ++ return FALSE; ++ } ++ ++ if (prGlueInfo->prP2PInfo->ucMaxClients) { ++ if ((UINT_8) u4NumClient > prGlueInfo->prP2PInfo->ucMaxClients) ++ return TRUE; ++ else ++ return FALSE; ++ } ++ ++ return FALSE; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c +new file mode 100644 +index 000000000000..075045f547b7 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c +@@ -0,0 +1,1020 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_proc.c#1 ++*/ ++ ++/*! \file "gl_proc.c" ++ \brief This file defines the interface which can interact with users in /proc fs. ++ ++ Detail description. ++*/ ++ ++/* ++** Log: gl_proc.c ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 12 10 2010 kevin.huang ++ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check ++ * Add Linux Proc Support ++** \main\maintrunk.MT5921\19 2008-09-02 21:08:37 GMT mtk01461 ++** Fix the compile error of SPRINTF() ++** \main\maintrunk.MT5921\18 2008-08-10 18:48:28 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\17 2008-08-04 16:52:01 GMT mtk01461 ++** Add proc dbg print message of DOMAIN_INDEX level ++** \main\maintrunk.MT5921\16 2008-07-10 00:45:16 GMT mtk01461 ++** Remove the check of MCR offset, we may use the MCR address which is not align to DW boundary or proprietary usage. ++** \main\maintrunk.MT5921\15 2008-06-03 20:49:44 GMT mtk01461 ++** \main\maintrunk.MT5921\14 2008-06-02 22:56:00 GMT mtk01461 ++** Rename some functions for linux proc ++** \main\maintrunk.MT5921\13 2008-06-02 20:23:18 GMT mtk01461 ++** Revise PROC mcr read / write for supporting TELNET ++** \main\maintrunk.MT5921\12 2008-03-28 10:40:25 GMT mtk01461 ++** Remove temporary set desired rate in linux proc ++** \main\maintrunk.MT5921\11 2008-01-07 15:07:29 GMT mtk01461 ++** Add User Update Desired Rate Set for QA in Linux ++** \main\maintrunk.MT5921\10 2007-12-11 00:11:14 GMT mtk01461 ++** Fix SPIN_LOCK protection ++** \main\maintrunk.MT5921\9 2007-12-04 18:07:57 GMT mtk01461 ++** Add additional debug category to proc ++** \main\maintrunk.MT5921\8 2007-11-02 01:03:23 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** \main\maintrunk.MT5921\7 2007-10-25 18:08:14 GMT mtk01461 ++** Add VOIP SCAN Support & Refine Roaming ++** Revision 1.3 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.2 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "precomp.h" ++ ++/* #include "wlan_lib.h" */ ++/* #include "debug.h" */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#define PROC_WLAN_THERMO "wlanThermo" ++#define PROC_DRV_STATUS "status" ++#define PROC_RX_STATISTICS "rx_statistics" ++#define PROC_TX_STATISTICS "tx_statistics" ++#define PROC_DBG_LEVEL_NAME "dbgLevel" ++#define PROC_NEED_TX_DONE "TxDoneCfg" ++#define PROC_AUTO_PER_CFG "autoPerCfg" ++#define PROC_ROOT_NAME "wlan" ++#define PROC_CMD_DEBUG_NAME "cmdDebug" ++ ++#define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN 20 ++#define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN 10 ++#define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN 10 ++#define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN (20*10) ++#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN 8 ++ ++#define PROC_UID_SHELL 2000 ++#define PROC_GID_WIFI 1010 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++/* static UINT_32 u4McrOffset; */ ++#if CFG_SUPPORT_THERMO_THROTTLING ++static P_GLUE_INFO_T g_prGlueInfo_proc; ++#endif ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading MCR register to User Space, the offset of ++* the MCR is specified in u4McrOffset. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++#if 0 ++static int procMCRRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; ++ UINT_32 u4BufLen; ++ char *p = page; ++ UINT_32 u4Count; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); ++ ++ rMcrInfo.u4McrOffset = u4McrOffset; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryMcrRead, ++ (PVOID)&rMcrInfo, sizeof(rMcrInfo), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ ++ /* SPRINTF(p, ("MCR (0x%08lxh): 0x%08lx\n", */ ++ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData)); */ ++ ++ u4Count = (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procMCRRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for writing MCR register to HW or update u4McrOffset ++* for reading MCR later. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procMCRWrite(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ ++ int i4CopySize; ++ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; ++ UINT_32 u4BufLen; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(data); ++ ++ i4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ if (copy_from_user(acBuf, buffer, i4CopySize)) ++ return 0; ++ acBuf[i4CopySize] = '\0'; ++ ++ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 2) { ++ /* NOTE: Sometimes we want to test if bus will still be ok, after accessing ++ * the MCR which is not align to DW boundary. ++ */ ++ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); ++ ++ u4McrOffset = rMcrInfo.u4McrOffset; ++ ++ /* printk("Write 0x%lx to MCR 0x%04lx\n", */ ++ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData); */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetMcrWrite, ++ (PVOID)&rMcrInfo, sizeof(rMcrInfo), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ ++ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 1) { ++ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ ++ u4McrOffset = rMcrInfo.u4McrOffset; ++ } ++ ++ return count; ++ ++} /* end of procMCRWrite() */ ++#endif ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading Driver Status to User Space. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procDrvStatusRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char *p = page; ++ UINT_32 u4Count; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ SPRINTF(p, ("GLUE LAYER STATUS:")); ++ SPRINTF(p, ("\n==================")); ++ ++ SPRINTF(p, ("\n* Number of Pending Frames: %ld\n", prGlueInfo->u4TxPendingFrameNum)); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ u4Count += (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procDrvStatusRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading Driver RX Statistic Counters to User Space. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procRxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char *p = page; ++ UINT_32 u4Count; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ SPRINTF(p, ("RX STATISTICS (Write 1 to clear):")); ++ SPRINTF(p, ("\n=================================\n")); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ u4Count += (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procRxStatisticsRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reset Driver RX Statistic Counters. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procRxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ UINT_32 u4ClearCounter; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ copy_from_user(acBuf, buffer, u4CopySize); ++ acBuf[u4CopySize] = '\0'; ++ ++ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { ++ if (u4ClearCounter == 1) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidSetRxStatisticsForLinuxProc(prGlueInfo->prAdapter); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ } ++ } ++ ++ return count; ++ ++} /* end of procRxStatisticsWrite() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reading Driver TX Statistic Counters to User Space. ++* ++* \param[in] page Buffer provided by kernel. ++* \param[in out] start Start Address to read(3 methods). ++* \param[in] off Offset. ++* \param[in] count Allowable number to read. ++* \param[out] eof End of File indication. ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters print to the buffer from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procTxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char *p = page; ++ UINT_32 u4Count; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ /* Kevin: Apply PROC read method 1. */ ++ if (off != 0) ++ return 0; /* To indicate end of file. */ ++ ++ SPRINTF(p, ("TX STATISTICS (Write 1 to clear):")); ++ SPRINTF(p, ("\n=================================\n")); ++ ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ u4Count += (UINT_32) (p - page); ++ ++ *eof = 1; ++ ++ return (int)u4Count; ++ ++} /* end of procTxStatisticsRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The PROC function for reset Driver TX Statistic Counters. ++* ++* \param[in] file pointer to file. ++* \param[in] buffer Buffer from user space. ++* \param[in] count Number of characters to write ++* \param[in] data Pointer to the private data structure. ++* ++* \return number of characters write from User Space. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int procTxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) ++{ ++ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; ++ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ ++ UINT_32 u4CopySize; ++ UINT_32 u4ClearCounter; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ ASSERT(data); ++ ++ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); ++ copy_from_user(acBuf, buffer, u4CopySize); ++ acBuf[u4CopySize] = '\0'; ++ ++ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { ++ if (u4ClearCounter == 1) { ++ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ ++ wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter); ++ ++ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); ++ } ++ } ++ ++ return count; ++ ++} /* end of procTxStatisticsWrite() */ ++#endif ++static struct proc_dir_entry *gprProcRoot; ++static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = { ++ "INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", "SW1", "SW2", ++ "SW3", "SW4", "HEM", "AIS", "RLM", "MEM", "CNM", "RSN", "BSS", "SCN", ++ "SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "OID", ++ "NIC" ++}; ++static UINT_8 aucProcBuf[1536]; ++static ssize_t procDbgLevelRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_32 u4CopySize = 0; ++ UINT_16 i; ++ UINT_16 u2ModuleNum = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ kalStrCpy(temp, "\nTEMP |LOUD |INFO |TRACE|EVENT|STATE|WARN |ERROR\n" ++ "bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0\n\n" ++ "Debug Module\tIndex\tLevel\tDebug Module\tIndex\tLevel\n\n"); ++ temp += kalStrLen(temp); ++ ++ u2ModuleNum = (sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0xfe; ++ for (i = 0; i < u2ModuleNum; i += 2) ++ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\tDBG_%s_IDX\t(0x%02x):\t0x%02x\n", ++ &aucDbModuleName[i][0], i, aucDebugModule[i], ++ &aucDbModuleName[i+1][0], i+1, aucDebugModule[i+1])); ++ ++ if ((sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0x1) ++ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\n", ++ &aucDbModuleName[u2ModuleNum][0], u2ModuleNum, aucDebugModule[u2ModuleNum])); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static ssize_t procDbgLevelWrite(struct file *file, const char *buffer, size_t count, loff_t *data) ++{ ++ UINT_32 u4NewDbgModule, u4NewDbgLevel; ++ UINT_8 i = 0; ++ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); ++ UINT_8 *temp = &aucProcBuf[0]; ++ ++ if (u4CopySize >= count + 1) ++ u4CopySize = count; ++ ++ kalMemSet(aucProcBuf, 0, u4CopySize); ++ ++ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { ++ kalPrint("error of copy from user\n"); ++ return -EFAULT; ++ } ++ aucProcBuf[u4CopySize] = '\0'; ++ ++ while (temp) { ++ if (sscanf(temp, "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2) { ++ kalPrint("debug module and debug level should be one byte in length\n"); ++ break; ++ } ++ if (u4NewDbgModule == 0xFF) { ++ for (i = 0; i < DBG_MODULE_NUM; i++) ++ aucDebugModule[i] = u4NewDbgLevel & DBG_CLASS_MASK; ++ ++ break; ++ } else if (u4NewDbgModule >= DBG_MODULE_NUM) { ++ kalPrint("debug module index should less than %d\n", DBG_MODULE_NUM); ++ break; ++ } ++ aucDebugModule[u4NewDbgModule] = u4NewDbgLevel & DBG_CLASS_MASK; ++ temp = kalStrChr(temp, ','); ++ if (!temp) ++ break; ++ temp++; /* skip ',' */ ++ } ++ return count; ++} ++ ++ ++static const struct file_operations dbglevel_ops = { ++ .owner = THIS_MODULE, ++ .read = procDbgLevelRead, ++ .write = procDbgLevelWrite, ++}; ++ ++static ssize_t procTxDoneCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_32 u4CopySize = 0; ++ UINT_16 u2TxDoneCfg = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ u2TxDoneCfg = StatsGetCfgTxDone(); ++ SPRINTF(temp, ("Tx Done Configure:\nARP %d\tDNS %d\nTCP %d\tUDP %d\nEAPOL %d\tDHCP %d\nICMP %d\n", ++ !!(u2TxDoneCfg & CFG_ARP), !!(u2TxDoneCfg & CFG_DNS), !!(u2TxDoneCfg & CFG_TCP), ++ !!(u2TxDoneCfg & CFG_UDP), !!(u2TxDoneCfg & CFG_EAPOL), !!(u2TxDoneCfg & CFG_DHCP), ++ !!(u2TxDoneCfg & CFG_ICMP))); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static ssize_t procTxDoneCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) ++{ ++#define MODULE_NAME_LENGTH 6 ++ ++ UINT_8 i = 0; ++ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_16 u2SetTxDoneCfg = 0; ++ UINT_16 u2ClsTxDoneCfg = 0; ++ UINT_8 aucModule[MODULE_NAME_LENGTH]; ++ UINT_32 u4Enabled; ++ UINT_8 aucModuleArray[][MODULE_NAME_LENGTH] = {"ARP", "DNS", "TCP", "UDP", "EAPOL", "DHCP", "ICMP"}; ++ ++ if (u4CopySize >= count + 1) ++ u4CopySize = count; ++ ++ kalMemSet(aucProcBuf, 0, u4CopySize); ++ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { ++ kalPrint("error of copy from user\n"); ++ return -EFAULT; ++ } ++ aucProcBuf[u4CopySize] = '\0'; ++ temp = &aucProcBuf[0]; ++ while (temp) { ++ /* pick up a string and teminated after meet : */ ++ if (sscanf(temp, "%s %d", aucModule, &u4Enabled) != 2) { ++ kalPrint("read param fail, aucModule=%s\n", aucModule); ++ break; ++ } ++ for (i = 0; i < sizeof(aucModuleArray)/MODULE_NAME_LENGTH; i++) { ++ if (kalStrniCmp(aucModule, aucModuleArray[i], MODULE_NAME_LENGTH) == 0) { ++ if (u4Enabled) ++ u2SetTxDoneCfg |= 1 << i; ++ else ++ u2ClsTxDoneCfg |= 1 << i; ++ break; ++ } ++ } ++ temp = kalStrChr(temp, ','); ++ if (!temp) ++ break; ++ temp++; /* skip ',' */ ++ } ++ if (u2SetTxDoneCfg) ++ StatsSetCfgTxDone(u2SetTxDoneCfg, TRUE); ++ ++ if (u2ClsTxDoneCfg) ++ StatsSetCfgTxDone(u2ClsTxDoneCfg, FALSE); ++ return count; ++} ++ ++static const struct file_operations proc_txdone_ops = { ++ .owner = THIS_MODULE, ++ .read = procTxDoneCfgRead, ++ .write = procTxDoneCfgWrite, ++}; ++ ++static ssize_t procAutoPerCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_8 *temp = &aucProcBuf[0]; ++ UINT_32 u4CopySize = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ SPRINTF(temp, ("Auto Performance Configure:\nperiod\tL1\nL2\tL3\n")); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static ssize_t procAutoPerCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) ++{ ++ DBGLOG(INIT, WARN, "%s\n", __func__); ++ return 0; ++} ++ ++static const struct file_operations auto_per_ops = { ++ .owner = THIS_MODULE, ++ .read = procAutoPerCfgRead, ++ .write = procAutoPerCfgWrite, ++}; ++ ++ ++static ssize_t procCmdDebug(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ UINT_32 u4CopySize = 0; ++ ++ /* if *f_ops>0, we should return 0 to make cat command exit */ ++ if (*f_pos > 0) ++ return 0; ++ ++ wlanDumpTcResAndTxedCmd(aucProcBuf, sizeof(aucProcBuf)); ++ ++ u4CopySize = kalStrLen(aucProcBuf); ++ if (u4CopySize > count) ++ u4CopySize = count; ++ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { ++ kalPrint("copy to user failed\n"); ++ return -EFAULT; ++ } ++ ++ *f_pos += u4CopySize; ++ return (ssize_t)u4CopySize; ++} ++ ++static const struct file_operations proc_CmdDebug_ops = { ++ .owner = THIS_MODULE, ++ .read = procCmdDebug, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function create a PROC fs in linux /proc/net subdirectory. ++* ++* \param[in] prDev Pointer to the struct net_device. ++* \param[in] pucDevName Pointer to the name of net_device. ++* ++* \return N/A ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++#if CFG_SUPPORT_THERMO_THROTTLING ++ ++/** ++ * This function is called then the /proc file is read ++ * ++ */ ++typedef struct _COEX_BUF1 { ++ UINT8 buffer[128]; ++ INT32 availSize; ++} COEX_BUF1, *P_COEX_BUF1; ++ ++COEX_BUF1 gCoexBuf1; ++ ++static ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) ++{ ++ ++ INT32 retval = 0; ++ INT32 i_ret = 0; ++ CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; ++ ++ if (*f_pos > 0) { ++ retval = 0; ++ } else { ++ /*len = sprintf(page, "%d\n", g_psm_enable); */ ++#if 1 ++ if (gCoexBuf1.availSize <= 0) { ++ DBGLOG(INIT, WARN, "no data available\n"); ++ retval = strlen(warn_msg) + 1; ++ if (count < retval) ++ retval = count; ++ i_ret = copy_to_user(buf, warn_msg, retval); ++ if (i_ret) { ++ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ } else ++#endif ++ { ++ INT32 i = 0; ++ INT32 len = 0; ++ CHAR msg_info[128]; ++ INT32 max_num = 0; ++ /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page ++ buffer is not enough, a bomb is placed here on unexpected condition */ ++ ++ DBGLOG(INIT, TRACE, "%d bytes available\n", gCoexBuf1.availSize); ++ max_num = ((sizeof(msg_info) > count ? sizeof(msg_info) : count) - 1) / 5; ++ ++ if (max_num > gCoexBuf1.availSize) ++ max_num = gCoexBuf1.availSize; ++ else ++ DBGLOG(INIT, TRACE, ++ "round to %d bytes due to local buffer size limitation\n", max_num); ++ ++ for (i = 0; i < max_num; i++) ++ len += sprintf(msg_info + len, "%d", gCoexBuf1.buffer[i]); ++ ++ len += sprintf(msg_info + len, "\n"); ++ retval = len; ++ ++ i_ret = copy_to_user(buf, msg_info, retval); ++ if (i_ret) { ++ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); ++ retval = -EFAULT; ++ goto err_exit; ++ } ++ *f_pos += retval; ++ } ++ } ++ gCoexBuf1.availSize = 0; ++err_exit: ++ ++ return retval; ++} ++ ++#if 1 ++typedef INT32 (*WLAN_DEV_DBG_FUNC)(void); ++static INT32 wlan_get_thermo_power(void); ++static INT32 wlan_get_link_mode(void); ++ ++static const WLAN_DEV_DBG_FUNC wlan_dev_dbg_func[] = { ++ [0] = wlan_get_thermo_power, ++ [1] = wlan_get_link_mode, ++ ++}; ++ ++INT32 wlan_get_thermo_power(void) ++{ ++ P_ADAPTER_T prAdapter; ++ ++ prAdapter = g_prGlueInfo_proc->prAdapter; ++ ++ if (prAdapter->u4AirDelayTotal > 100) ++ gCoexBuf1.buffer[0] = 100; ++ else ++ gCoexBuf1.buffer[0] = prAdapter->u4AirDelayTotal; ++ gCoexBuf1.availSize = 1; ++ DBGLOG(RLM, TRACE, "PROC %s thrmo_power(%d)\n", __func__, gCoexBuf1.buffer[0]); ++ ++ return 0; ++} ++ ++INT32 wlan_get_link_mode(void) ++{ ++ UINT_8 ucLinkMode = 0; ++ P_ADAPTER_T prAdapter; ++ BOOLEAN fgIsAPmode; ++ ++ prAdapter = g_prGlueInfo_proc->prAdapter; ++ fgIsAPmode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); ++ ++ DBGLOG(RLM, TRACE, "PROC %s AIS(%d)P2P(%d)AP(%d)\n", ++ __func__, ++ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState, ++ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState, fgIsAPmode); ++ ++#if 1 ++ ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ ucLinkMode |= BIT(0); ++ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) ++ ucLinkMode |= BIT(1); ++ if (fgIsAPmode) ++ ucLinkMode |= BIT(2); ++ ++#endif ++ gCoexBuf1.buffer[0] = ucLinkMode; ++ gCoexBuf1.availSize = 1; ++ ++ return 0; ++} ++ ++static ssize_t procfile_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) ++{ ++ char buf[256]; ++ char *pBuf; ++ ULONG len = count; ++ INT32 x = 0, y = 0, z = 0; ++ char *pToken = NULL; ++ char *pDelimiter = " \t"; ++ INT32 i4Ret = 0; ++ ++ if (copy_from_user(gCoexBuf1.buffer, buffer, count)) ++ return -EFAULT; ++ /* gCoexBuf1.availSize = count; */ ++ ++ /* return gCoexBuf1.availSize; */ ++#if 1 ++ DBGLOG(INIT, TRACE, "write parameter len = %d\n\r", (INT32) len); ++ if (len >= sizeof(buf)) { ++ DBGLOG(INIT, ERROR, "input handling fail!\n"); ++ len = sizeof(buf) - 1; ++ return -1; ++ } ++ ++ if (copy_from_user(buf, buffer, len)) ++ return -EFAULT; ++ buf[len] = '\0'; ++ DBGLOG(INIT, TRACE, "write parameter data = %s\n\r", buf); ++ ++ pBuf = buf; ++ pToken = strsep(&pBuf, pDelimiter); ++ ++ if (pToken) /* x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; */ ++ i4Ret = kalkStrtos32(pToken, 16, &x); ++ if (!i4Ret) ++ DBGLOG(INIT, TRACE, "x = 0x%x\n", x); ++ ++#if 1 ++ pToken = strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ i4Ret = kalkStrtos32(pToken, 16, &y); /* y = simple_strtol(pToken, NULL, 16); */ ++ if (!i4Ret) ++ DBGLOG(INIT, TRACE, "y = 0x%08x\n\r", y); ++ } else { ++ y = 3000; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ y = 0x80000000; ++ } ++ ++ pToken = strsep(&pBuf, "\t\n "); ++ if (pToken != NULL) { ++ i4Ret = kalkStrtos32(pToken, 16, &z); /* z = simple_strtol(pToken, NULL, 16); */ ++ if (!i4Ret) ++ DBGLOG(INIT, TRACE, "z = 0x%08x\n\r", z); ++ } else { ++ z = 10; ++ /*efuse, register read write default value */ ++ if (0x11 == x || 0x12 == x || 0x13 == x) ++ z = 0xffffffff; ++ } ++ ++ DBGLOG(INIT, TRACE, " x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); ++#endif ++ ++ if (((sizeof(wlan_dev_dbg_func) / sizeof(wlan_dev_dbg_func[0])) > x) && NULL != wlan_dev_dbg_func[x]) ++ (*wlan_dev_dbg_func[x]) (); ++ else ++ DBGLOG(INIT, ERROR, "no handler defined for command id(0x%08x)\n\r", x); ++#endif ++ ++ /* len = gCoexBuf1.availSize; */ ++ return len; ++} ++#endif ++ static const struct file_operations proc_fops = { ++ .owner = THIS_MODULE, ++ .read = procfile_read, ++ .write = procfile_write, ++ }; ++#endif ++ ++INT_32 procInitFs(VOID) ++{ ++ struct proc_dir_entry *prEntry; ++ ++ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { ++ kalPrint("init proc fs fail: proc_net == NULL\n"); ++ return -ENOENT; ++ } ++ ++ /* ++ * Directory: Root (/proc/net/wlan0) ++ */ ++ ++ gprProcRoot = proc_mkdir(PROC_ROOT_NAME, init_net.proc_net); ++ if (!gprProcRoot) { ++ kalPrint("gprProcRoot == NULL\n"); ++ return -ENOENT; ++ } ++ proc_set_user(gprProcRoot, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ prEntry = proc_create(PROC_DBG_LEVEL_NAME, 0664, gprProcRoot, &dbglevel_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry dbgLevel\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ prEntry = proc_create(PROC_NEED_TX_DONE, 0664, gprProcRoot, &proc_txdone_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry dbgLevel\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ prEntry = proc_create(PROC_AUTO_PER_CFG, 0664, gprProcRoot, &auto_per_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry autoPerCfg\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ ++ return 0; ++} /* end of procInitProcfs() */ ++ ++INT_32 procUninitProcFs(VOID) ++{ ++ remove_proc_entry(PROC_DBG_LEVEL_NAME, gprProcRoot); ++ remove_proc_subtree(PROC_ROOT_NAME, init_net.proc_net); ++ remove_proc_entry(PROC_AUTO_PER_CFG, gprProcRoot); ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function clean up a PROC fs created by procInitProcfs(). ++* ++* \param[in] prDev Pointer to the struct net_device. ++* \param[in] pucDevName Pointer to the name of net_device. ++* ++* \return N/A ++*/ ++/*----------------------------------------------------------------------------*/ ++INT_32 procRemoveProcfs(VOID) ++{ ++ /* remove root directory (proc/net/wlan0) */ ++ /* remove_proc_entry(pucDevName, init_net.proc_net); */ ++ remove_proc_entry(PROC_WLAN_THERMO, gprProcRoot); ++ remove_proc_entry(PROC_CMD_DEBUG_NAME, gprProcRoot); ++#if CFG_SUPPORT_THERMO_THROTTLING ++ g_prGlueInfo_proc = NULL; ++#endif ++ return 0; ++} /* end of procRemoveProcfs() */ ++ ++INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo) ++{ ++ struct proc_dir_entry *prEntry; ++ ++ DBGLOG(INIT, TRACE, "[%s]\n", __func__); ++ ++#if CFG_SUPPORT_THERMO_THROTTLING ++ g_prGlueInfo_proc = prGlueInfo; ++#endif ++ ++ prGlueInfo->pProcRoot = gprProcRoot; ++ ++ prEntry = proc_create(PROC_WLAN_THERMO, 0664, gprProcRoot, &proc_fops); ++ if (prEntry == NULL) { ++ DBGLOG(INIT, ERROR, "Unable to create /proc entry\n\r"); ++ return -1; ++ } ++ ++ prEntry = proc_create(PROC_CMD_DEBUG_NAME, 0444, gprProcRoot, &proc_CmdDebug_ops); ++ if (prEntry == NULL) { ++ kalPrint("Unable to create /proc entry dbgLevel\n\r"); ++ return -1; ++ } ++ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); ++ return 0; ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +new file mode 100644 +index 000000000000..f97db8a69fd2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +@@ -0,0 +1,228 @@ ++/* ++** Id: @(#) gl_rst.c@@ ++*/ ++ ++/*! \file gl_rst.c ++ \brief Main routines for supporintg MT6620 whole-chip reset mechanism ++ ++ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_rst.c ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 04 22 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * skip power-off handshaking when RESET indication is received. ++ * ++ * 04 14 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected ++ * 2. add dummy function for both Win32 and Linux part. ++ * ++ * 03 30 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * use netlink unicast instead of broadcast ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++ ++#include "precomp.h" ++#include "gl_rst.h" ++ ++#if CFG_CHIP_RESET_SUPPORT ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++BOOLEAN fgIsResetting = FALSE; ++UINT_32 g_IsNeedDoChipReset = 0; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static RESET_STRUCT_T wifi_rst; ++ ++static void mtk_wifi_reset(struct work_struct *work); ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, ++ ENUM_WMTDRV_TYPE_T eDstType, ++ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for ++ * 1. register wifi reset callback ++ * 2. initialize wifi reset work ++ * ++ * @param none ++ * ++ * @retval none ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID glResetInit(VOID) ++{ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++ /* 1. Register reset callback */ ++ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB) glResetCallback); ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++ /* 2. Initialize reset work */ ++ INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is responsible for ++ * 1. deregister wifi reset callback ++ * ++ * @param none ++ * ++ * @retval none ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID glResetUninit(VOID) ++{ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++ /* 1. Deregister reset callback */ ++ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI); ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is invoked when there is reset messages indicated ++ * ++ * @param eSrcType ++ * eDstType ++ * eMsgType ++ * prMsgBody ++ * u4MsgLength ++ * ++ * @retval ++ */ ++/*----------------------------------------------------------------------------*/ ++static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, ++ ENUM_WMTDRV_TYPE_T eDstType, ++ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength) ++{ ++ switch (eMsgType) { ++ case WMTMSG_TYPE_RESET: ++ if (u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) { ++ P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody; ++ ++ switch (*prRstMsg) { ++ case WMTRSTMSG_RESET_START: ++ DBGLOG(INIT, WARN, "Whole chip reset start!\n"); ++ fgIsResetting = TRUE; ++ wifi_reset_start(); ++ break; ++ ++ case WMTRSTMSG_RESET_END: ++ DBGLOG(INIT, WARN, "Whole chip reset end!\n"); ++ fgIsResetting = FALSE; ++ wifi_rst.rst_data = RESET_SUCCESS; ++ schedule_work(&(wifi_rst.rst_work)); ++ break; ++ ++ case WMTRSTMSG_RESET_END_FAIL: ++ DBGLOG(INIT, WARN, "Whole chip reset fail!\n"); ++ fgIsResetting = FALSE; ++ wifi_rst.rst_data = RESET_FAIL; ++ schedule_work(&(wifi_rst.rst_work)); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is called for wifi reset ++ * ++ * @param skb ++ * info ++ * ++ * @retval 0 ++ * nonzero ++ */ ++/*----------------------------------------------------------------------------*/ ++static void mtk_wifi_reset(struct work_struct *work) ++{ ++ RESET_STRUCT_T *rst = container_of(work, RESET_STRUCT_T, rst_work); ++ ++ wifi_reset_end(rst->rst_data); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is called for generating reset request to WMT ++ * ++ * @param None ++ * ++ * @retval None ++ */ ++/*----------------------------------------------------------------------------*/ ++VOID glSendResetRequest(VOID) ++{ ++ /* WMT thread would trigger whole chip reset itself */ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++ * @brief This routine is called for checking if connectivity chip is resetting ++ * ++ * @param None ++ * ++ * @retval TRUE ++ * FALSE ++ */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsResetting(VOID) ++{ ++ return fgIsResetting; ++} ++ ++#endif /* CFG_CHIP_RESET_SUPPORT */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c +new file mode 100644 +index 000000000000..862d011a43df +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c +@@ -0,0 +1,1220 @@ ++/* ++** Id: @(#) gl_cfg80211.c@@ ++*/ ++ ++/*! \file gl_cfg80211.c ++ \brief Main routines for supporintg MT6620 cfg80211 control interface ++ ++ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 ++ Wireless LAN Adapters. ++*/ ++ ++/* ++** Log: gl_cfg80211.c ++** ++** 09 05 2013 cp.wu ++** correct length to pass to wlanoidSetBssid() ++** ++** 09 04 2013 cp.wu ++** fix typo ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 11 23 2012 yuche.tsai ++** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely ++** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++ ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "gl_wext.h" ++#include "precomp.h" ++#include "gl_cfg80211.h" ++#include "gl_vendor.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++static struct nla_policy nla_parse_policy[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1] = { ++ [GSCAN_ATTRIBUTE_NUM_BUCKETS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BASE_PERIOD] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKETS_BAND] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_ID] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_PERIOD] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BUCKET_CHANNELS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_REPORT_THRESHOLD] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_REPORT_EVENTS] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_BSSID] = {.type = NLA_UNSPEC}, ++ [GSCAN_ATTRIBUTE_RSSI_LOW] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_RSSI_HIGH] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE] = {.type = NLA_U16}, ++ [GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE] = {.type = NLA_U32}, ++ [GSCAN_ATTRIBUTE_MIN_BREACHING] = {.type = NLA_U16}, ++ [GSCAN_ATTRIBUTE_NUM_AP] = {.type = NLA_U16}, ++ [GSCAN_ATTRIBUTE_HOTLIST_FLUSH] = {.type = NLA_U8}, ++ [GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH] = {.type = NLA_U8}, ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ struct nlattr *attr; ++ UINT_32 band = 0; ++ UINT_8 ucNumOfChannel, i, j; ++ RF_CHANNEL_INFO_T aucChannelList[64]; ++ UINT_32 num_channels; ++ wifi_channel channels[64]; ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy && wdev); ++ if ((data == NULL) || !data_len) ++ return -EINVAL; ++ ++ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == WIFI_ATTRIBUTE_BAND) ++ band = nla_get_u32(attr); ++ ++ DBGLOG(REQ, INFO, "Get channel list for band: %d\n", band); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (!prGlueInfo) ++ return -EFAULT; ++ ++ if (band == 0) { /* 2.4G band */ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, ++ 64, &ucNumOfChannel, aucChannelList); ++ } else { /* 5G band */ ++ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, ++ 64, &ucNumOfChannel, aucChannelList); ++ } ++ ++ kalMemZero(channels, sizeof(channels)); ++ for (i = 0, j = 0; i < ucNumOfChannel; i++) { ++ /* We need to report frequency list to HAL */ ++ channels[j] = nicChannelNum2Freq(aucChannelList[i].ucChannelNum) / 1000; ++ if (channels[j] == 0) ++ continue; ++ else if ((prGlueInfo->prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_TW) && ++ (channels[j] >= 5180 && channels[j] <= 5260)) { ++ /* Taiwan NCC has resolution to follow FCC spec to support 5G Band 1/2/3/4 ++ * (CH36~CH48, CH52~CH64, CH100~CH140, CH149~CH165) ++ * Filter CH36~CH52 for compatible with some old devices. ++ */ ++ continue; ++ } else { ++ DBGLOG(REQ, INFO, "channels[%d] = %d\n", j, channels[j]); ++ j++; ++ } ++ } ++ num_channels = j; ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(channels)); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "Allocate skb failed\n"); ++ return -ENOMEM; ++ } ++ ++ if (unlikely(nla_put_u32(skb, WIFI_ATTRIBUTE_NUM_CHANNELS, num_channels) < 0)) ++ goto nla_put_failure; ++ ++ if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_CHANNEL_LIST, ++ (sizeof(wifi_channel) * num_channels), channels) < 0)) ++ goto nla_put_failure; ++ ++ return cfg80211_vendor_cmd_reply(skb); ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -EFAULT; ++} ++ ++int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ struct nlattr *attr; ++ UINT_8 country[2] = {0, 0}; ++ ++ ASSERT(wiphy && wdev); ++ if ((data == NULL) || (data_len == 0)) ++ return -EINVAL; ++ ++ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == WIFI_ATTRIBUTE_COUNTRY_CODE) { ++ country[0] = *((PUINT_8)nla_data(attr)); ++ country[1] = *((PUINT_8)nla_data(attr) + 1); ++ } ++ ++ DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], country[1]); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ if (!prGlueInfo) ++ return -EFAULT; ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, country, 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Status = -EINVAL; ++ PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T rGscanCapabilities; ++ struct sk_buff *skb; ++ /* UINT_32 u4BufLen; */ ++ ++ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rGscanCapabilities)); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&rGscanCapabilities, sizeof(rGscanCapabilities)); ++ ++ /*rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rGscanCapabilities, ++ sizeof(rGscanCapabilities), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4BufLen); */ ++ rGscanCapabilities.max_scan_cache_size = PSCAN_MAX_SCAN_CACHE_SIZE; ++ rGscanCapabilities.max_scan_buckets = GSCAN_MAX_BUCKETS; ++ rGscanCapabilities.max_ap_cache_per_scan = PSCAN_MAX_AP_CACHE_PER_SCAN; ++ rGscanCapabilities.max_rssi_sample_size = 10; ++ rGscanCapabilities.max_scan_reporting_threshold = GSCAN_MAX_REPORT_THRESHOLD; ++ rGscanCapabilities.max_hotlist_aps = MAX_HOTLIST_APS; ++ rGscanCapabilities.max_significant_wifi_change_aps = MAX_SIGNIFICANT_CHANGE_APS; ++ rGscanCapabilities.max_bssid_history_entries = PSCAN_MAX_AP_CACHE_PER_SCAN * PSCAN_MAX_SCAN_CACHE_SIZE; ++ ++ /* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); */ ++ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_ID, GOOGLE_OUI); */ ++ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_GET_CAPABILITIES); */ ++ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities);*/ ++ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CAPABILITIES, ++ sizeof(rGscanCapabilities), &rGscanCapabilities) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ return i4Status; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ /* CMD_GSCN_REQ_T rCmdGscnParam; */ ++ ++ /* INT_32 i4Status = -EINVAL; */ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; ++ struct nlattr *attr[GSCAN_ATTRIBUTE_REPORT_EVENTS + 1]; ++ struct nlattr *pbucket, *pchannel; ++ UINT_32 len_basic, len_bucket, len_channel; ++ int i, j, k; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ ++ prWifiScanCmd = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); ++ if (!prWifiScanCmd) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); ++ return -ENOMEM; ++ } ++ ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_REPORT_EVENTS + 1)); ++ ++ nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL); ++ len_basic = 0; ++ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BASE_PERIOD: ++ prWifiScanCmd->base_period = nla_get_u32(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_BUCKETS: ++ prWifiScanCmd->num_buckets = nla_get_u32(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "attr=0x%x, num_buckets=%d nla_len=%d, \r\n", ++ *(UINT_32 *) attr[k], prWifiScanCmd->num_buckets, attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ pbucket = (struct nlattr *)((UINT_8 *) data + len_basic); ++ DBGLOG(REQ, TRACE, "+++basic attribute size=%d pbucket=%p\r\n", len_basic, pbucket); ++ ++ for (i = 0; i < prWifiScanCmd->num_buckets; i++) { ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)pbucket, ++ nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ len_bucket = 0; ++ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BUCKETS_BAND: ++ prWifiScanCmd->buckets[i].band = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_BUCKET_ID: ++ prWifiScanCmd->buckets[i].bucket = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_BUCKET_PERIOD: ++ prWifiScanCmd->buckets[i].period = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_REPORT_EVENTS: ++ prWifiScanCmd->buckets[i].report_events = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: ++ prWifiScanCmd->buckets[i].num_channels = nla_get_u32(attr[k]); ++ len_bucket += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "bucket%d: attr=0x%x, num_channels=%d nla_len = %d, \r\n", ++ i, *(UINT_32 *) attr[k], nla_get_u32(attr[k]), attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ pbucket = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); ++ /* request.attr_start(i) as nested attribute */ ++ DBGLOG(REQ, TRACE, "+++pure bucket size=%d pbucket=%p \r\n", len_bucket, pbucket); ++ pbucket = (struct nlattr *)((UINT_8 *) pbucket + len_bucket); ++ /* pure bucket payload, not include channels */ ++ ++ /*don't need to use nla_parse_nested to parse channels */ ++ /* the header of channel in bucket i */ ++ pchannel = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); ++ for (j = 0; j < prWifiScanCmd->buckets[i].num_channels; j++) { ++ prWifiScanCmd->buckets[i].channels[j].channel = nla_get_u32(pchannel); ++ len_channel = NLA_ALIGN(pchannel->nla_len); ++ DBGLOG(REQ, TRACE, ++ "attr=0x%x, channel=%d, \r\n", *(UINT_32 *) pchannel, nla_get_u32(pchannel)); ++ ++ pchannel = (struct nlattr *)((UINT_8 *) pchannel + len_channel); ++ } ++ pbucket = pchannel; ++ } ++ ++ DBGLOG(REQ, TRACE, "base_period=%d, num_buckets=%d, bucket0: %d %d %d %d", ++ prWifiScanCmd->base_period, prWifiScanCmd->num_buckets, ++ prWifiScanCmd->buckets[0].bucket, prWifiScanCmd->buckets[0].period, ++ prWifiScanCmd->buckets[0].band, prWifiScanCmd->buckets[0].report_events); ++ ++ DBGLOG(REQ, TRACE, "num_channels=%d, channel0=%d, channel1=%d; num_channels=%d, channel0=%d, channel1=%d", ++ prWifiScanCmd->buckets[0].num_channels, ++ prWifiScanCmd->buckets[0].channels[0].channel, prWifiScanCmd->buckets[0].channels[1].channel, ++ prWifiScanCmd->buckets[1].num_channels, ++ prWifiScanCmd->buckets[1].channels[0].channel, prWifiScanCmd->buckets[1].channels[1].channel); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetGSCNAParam, ++ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiScanCmd != NULL) ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ INT_32 i4Status = -EINVAL; ++ /*PARAM_WIFI_GSCAN_CMD_PARAMS rWifiScanCmd;*/ ++ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; ++ struct nlattr *attr[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1]; ++ /* UINT_32 num_scans = 0; */ /* another attribute */ ++ int k; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ /*kalMemZero(&rWifiScanCmd, sizeof(rWifiScanCmd));*/ ++ prWifiScanCmd = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); ++ if (prWifiScanCmd == NULL) ++ goto nla_put_failure; ++ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1)); ++ ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, ++ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ for (k = GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN; k <= GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: ++ prWifiScanCmd->max_ap_per_scan = nla_get_u32(attr[k]); ++ break; ++ case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: ++ prWifiScanCmd->report_threshold = nla_get_u32(attr[k]); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: ++ prWifiScanCmd->num_scans = nla_get_u32(attr[k]); ++ break; ++ } ++ } ++ } ++ DBGLOG(REQ, TRACE, "attr=0x%x, attr2=0x%x ", *(UINT_32 *) attr[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN], ++ *(UINT_32 *) attr[GSCAN_ATTRIBUTE_REPORT_THRESHOLD]); ++ ++ DBGLOG(REQ, TRACE, "max_ap_per_scan=%d, report_threshold=%d num_scans=%d \r\n", ++ prWifiScanCmd->max_ap_per_scan, prWifiScanCmd->report_threshold, prWifiScanCmd->num_scans); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetGSCNAConfig, ++ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiScanCmd != NULL) ++ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len) ++{ ++ INT_32 i4Status = -EINVAL; ++ P_PARAM_WIFI_SIGNIFICANT_CHANGE prWifiChangeCmd = NULL; ++ UINT_8 flush = 0; ++ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ ++ struct nlattr **attr = NULL; ++ struct nlattr *paplist; ++ int i, k; ++ UINT_32 len_basic, len_aplist; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ for (i = 0; i < 6; i++) ++ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", ++ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), ++ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); ++ prWifiChangeCmd = kalMemAlloc(sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE), VIR_MEM_TYPE); ++ if (prWifiChangeCmd == NULL) ++ goto nla_put_failure; ++ kalMemZero(prWifiChangeCmd, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); ++ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); ++ if (attr == NULL) ++ goto nla_put_failure; ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, ++ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ len_basic = 0; ++ for (k = GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE; k <= GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: ++ prWifiChangeCmd->rssi_sample_size = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: ++ prWifiChangeCmd->lost_ap_sample_size = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_MIN_BREACHING: ++ prWifiChangeCmd->min_breaching = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_AP: ++ prWifiChangeCmd->num_ap = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", ++ *(UINT_32 *) attr[k], prWifiChangeCmd->num_ap, attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: ++ flush = nla_get_u8(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); ++ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); ++ ++ if (paplist->nla_type == GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS) ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ ++ for (i = 0; i < prWifiChangeCmd->num_ap; i++) { ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ /* request.attr_start(i) as nested attribute */ ++ len_aplist = 0; ++ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BSSID: ++ kalMemCopy(prWifiChangeCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_LOW: ++ prWifiChangeCmd->ap[i].low = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_HIGH: ++ prWifiChangeCmd->ap[i].high = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ if (((i + 1) % 4 == 0) || (i == prWifiChangeCmd->num_ap - 1)) ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); ++ else ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); ++ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); ++ } ++ ++ DBGLOG(REQ, TRACE, ++ "flush=%d, rssi_sample_size=%d lost_ap_sample_size=%d min_breaching=%d", ++ flush, prWifiChangeCmd->rssi_sample_size, prWifiChangeCmd->lost_ap_sample_size, ++ prWifiChangeCmd->min_breaching); ++ DBGLOG(REQ, TRACE, ++ "ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", ++ prWifiChangeCmd->ap[0].channel, prWifiChangeCmd->ap[0].low, prWifiChangeCmd->ap[0].high, ++ prWifiChangeCmd->ap[1].channel, prWifiChangeCmd->ap[1].low, prWifiChangeCmd->ap[1].high); ++ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); ++ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiChangeCmd) ++ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); ++ if (attr) ++ kalMemFree(attr, VIR_MEM_TYPE, ++ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ /*WLAN_STATUS rStatus;*/ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; ++ ++ INT_32 i4Status = -EINVAL; ++ P_PARAM_WIFI_BSSID_HOTLIST prWifiHotlistCmd = NULL; ++ UINT_8 flush = 0; ++ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ ++ struct nlattr **attr = NULL; ++ struct nlattr *paplist; ++ int i, k; ++ UINT_32 len_basic, len_aplist; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ for (i = 0; i < 5; i++) ++ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", ++ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), ++ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); ++ prWifiHotlistCmd = kalMemAlloc(sizeof(PARAM_WIFI_BSSID_HOTLIST), VIR_MEM_TYPE); ++ if (prWifiHotlistCmd == NULL) ++ goto nla_put_failure; ++ kalMemZero(prWifiHotlistCmd, sizeof(PARAM_WIFI_BSSID_HOTLIST)); ++ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); ++ if (attr == NULL) ++ goto nla_put_failure; ++ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_AP, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ len_basic = 0; ++ for (k = GSCAN_ATTRIBUTE_HOTLIST_FLUSH; k <= GSCAN_ATTRIBUTE_NUM_AP; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: ++ prWifiHotlistCmd->lost_ap_sample_size = nla_get_u32(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_NUM_AP: ++ prWifiHotlistCmd->num_ap = nla_get_u16(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", ++ *(UINT_32 *) attr[k], prWifiHotlistCmd->num_ap, attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: ++ flush = nla_get_u8(attr[k]); ++ len_basic += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); ++ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); ++ ++ if (paplist->nla_type == GSCAN_ATTRIBUTE_HOTLIST_BSSIDS) ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ ++ for (i = 0; i < prWifiHotlistCmd->num_ap; i++) { ++ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) ++ goto nla_put_failure; ++ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); ++ /* request.attr_start(i) as nested attribute */ ++ len_aplist = 0; ++ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { ++ if (attr[k]) { ++ switch (k) { ++ case GSCAN_ATTRIBUTE_BSSID: ++ kalMemCopy(prWifiHotlistCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_LOW: ++ prWifiHotlistCmd->ap[i].low = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ case GSCAN_ATTRIBUTE_RSSI_HIGH: ++ prWifiHotlistCmd->ap[i].high = nla_get_u32(attr[k]); ++ len_aplist += NLA_ALIGN(attr[k]->nla_len); ++ break; ++ } ++ } ++ } ++ if (((i + 1) % 4 == 0) || (i == prWifiHotlistCmd->num_ap - 1)) ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); ++ else ++ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); ++ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); ++ } ++ ++ DBGLOG(REQ, TRACE, ++ "flush=%d, lost_ap_sample_size=%d, Hotlist:ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", ++ flush, prWifiHotlistCmd->lost_ap_sample_size, ++ prWifiHotlistCmd->ap[0].channel, prWifiHotlistCmd->ap[0].low, prWifiHotlistCmd->ap[0].high, ++ prWifiHotlistCmd->ap[1].channel, prWifiHotlistCmd->ap[1].low, prWifiHotlistCmd->ap[1].high); ++ ++ memcpy(&(rCmdPscnAddHotlist.aucMacAddr), &(prWifiHotlistCmd->ap[0].bssid), 6 * sizeof(UINT_8)); ++ rCmdPscnAddHotlist.ucFlags = (UINT_8) TRUE; ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); ++ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return 0; ++ ++nla_put_failure: ++ if (prWifiHotlistCmd) ++ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); ++ if (attr) ++ kalMemFree(attr, VIR_MEM_TYPE, ++ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS rWifiScanActionCmd; ++ ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_8 gGScanEn = 0; ++ ++ static UINT_8 k; /* only for test */ ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", ++ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == GSCAN_ATTRIBUTE_ENABLE_FEATURE) ++ gGScanEn = nla_get_u32(attr); ++ DBGLOG(REQ, INFO, "gGScanEn=%d, \r\n", gGScanEn); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ if (gGScanEn == TRUE) ++ rWifiScanActionCmd.ucPscanAct = ENABLE; ++ else ++ rWifiScanActionCmd.ucPscanAct = DISABLE; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetGSCNAction, ++ &rWifiScanActionCmd, ++ sizeof(PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ /* mtk_cfg80211_vendor_get_scan_results(wiphy, wdev, data, data_len ); */ ++ ++ return 0; ++ ++ /* only for test */ ++ if (k % 3 == 1) { ++ mtk_cfg80211_vendor_event_significant_change_results(wiphy, wdev, NULL, 0); ++ mtk_cfg80211_vendor_event_hotlist_ap_found(wiphy, wdev, NULL, 0); ++ mtk_cfg80211_vendor_event_hotlist_ap_lost(wiphy, wdev, NULL, 0); ++ } ++ k++; ++ ++ return 0; ++ ++nla_put_failure: ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len) ++{ ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_8 gFullScanResultsEn = 0; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", ++ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == GSCAN_ENABLE_FULL_SCAN_RESULTS) ++ gFullScanResultsEn = nla_get_u32(attr); ++ DBGLOG(REQ, INFO, "gFullScanResultsEn=%d, \r\n", gFullScanResultsEn); ++ ++ return 0; ++ ++ /* only for test */ ++ mtk_cfg80211_vendor_event_complete_scan(wiphy, wdev, WIFI_SCAN_COMPLETE); ++ mtk_cfg80211_vendor_event_scan_results_available(wiphy, wdev, 4); ++ if (gFullScanResultsEn == TRUE) ++ mtk_cfg80211_vendor_event_full_scan_results(wiphy, wdev, NULL, 0); ++ ++ return 0; ++ ++nla_put_failure: ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ /*WLAN_STATUS rStatus;*/ ++ UINT_32 u4BufLen; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ PARAM_WIFI_GSCAN_GET_RESULT_PARAMS rGSscnResultParm; ++ ++ INT_32 i4Status = -EINVAL; ++ struct nlattr *attr; ++ UINT_32 get_num = 0, real_num = 0; ++ UINT_8 flush = 0; ++ /*PARAM_WIFI_GSCAN_RESULT result[4], *pResult; ++ struct sk_buff *skb;*/ ++ int i; /*int j;*/ ++ /*UINT_32 scan_id;*/ ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ if ((data == NULL) || !data_len) ++ goto nla_put_failure; ++ DBGLOG(REQ, TRACE, "%s for vendor command: data_len=%d \r\n", __func__, data_len); ++ for (i = 0; i < 2; i++) ++ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), ++ *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), ++ *((UINT_32 *) data + i * 4 + 3)); ++ ++ attr = (struct nlattr *)data; ++ if (attr->nla_type == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { ++ get_num = nla_get_u32(attr); ++ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); ++ } ++ if (attr->nla_type == GSCAN_ATTRIBUTE_FLUSH_RESULTS) { ++ flush = nla_get_u8(attr); ++ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); ++ } ++ DBGLOG(REQ, TRACE, "number=%d, flush=%d \r\n", get_num, flush); ++ ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ASSERT(prGlueInfo); ++ ++ real_num = (get_num < PSCAN_MAX_SCAN_CACHE_SIZE) ? get_num : PSCAN_MAX_SCAN_CACHE_SIZE; ++ get_num = real_num; ++ ++#if 0 /* driver buffer FW results and reports by buffer workaround for FW mismatch with hal results numbers */ ++ g_GetResultsCmdCnt++; ++ DBGLOG(REQ, INFO, ++ "(g_GetResultsCmdCnt [%d], g_GetResultsBufferedCnt [%d]\n", g_GetResultsCmdCnt, ++ g_GetResultsBufferedCnt); ++ ++ BOOLEAN fgIsGetResultFromBuffer = FALSE; ++ UINT_8 BufferedResultReportIndex = 0; ++ ++ if (g_GetResultsBufferedCnt > 0) { ++ ++ DBGLOG(REQ, INFO, ++ "(g_GetResultsBufferedCnt > 0), report buffered results instead of ask from FW\n"); ++ ++ /* reply the results to wifi_hal */ ++ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { ++ ++ if (g_arGscanResultsIndicateNumber[i] > 0) { ++ real_num = g_arGscanResultsIndicateNumber[i]; ++ get_num = real_num; ++ g_arGscanResultsIndicateNumber[i] = 0; ++ fgIsGetResultFromBuffer = TRUE; ++ BufferedResultReportIndex = i; ++ break; ++ } ++ } ++ if (i == MAX_BUFFERED_GSCN_RESULTS) ++ DBGLOG(REQ, TRACE, "all buffered results are invalid, unexpected case \r\n"); ++ DBGLOG(REQ, TRACE, "BufferedResultReportIndex[%d] i = %d real_num[%d] get_num[%d] \r\n", ++ BufferedResultReportIndex, i, real_num, get_num); ++ } ++#endif ++ ++ rGSscnResultParm.get_num = get_num; ++ rGSscnResultParm.flush = flush; ++#if 0/* //driver buffer FW results and reports by buffer workaround for FW results mismatch with hal results number */ ++ if (fgIsGetResultFromBuffer) { ++ nicRxProcessGSCNEvent(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); ++ g_GetResultsBufferedCnt--; ++ g_GetResultsCmdCnt--; ++ nicRxReturnRFB(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); ++ } else ++#endif ++ { ++ kalIoctl(prGlueInfo, ++ wlanoidGetGSCNResult, ++ &rGSscnResultParm, ++ sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ return 0; ++ ++nla_put_failure: ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4Status = -EINVAL; ++ PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities; ++ struct sk_buff *skb; ++ ++ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rRttCapabilities)); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities)); ++ ++ /*rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rRttCapabilities, ++ sizeof(rRttCapabilities), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4BufLen); */ ++ rRttCapabilities.rtt_one_sided_supported = 0; ++ rRttCapabilities.rtt_ftm_supported = 0; ++ rRttCapabilities.lci_support = 0; ++ rRttCapabilities.lcr_support = 0; ++ rRttCapabilities.preamble_support = 0; ++ rRttCapabilities.bw_support = 0; ++ ++ if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES, ++ sizeof(rRttCapabilities), &rRttCapabilities) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ return i4Status; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) ++{ ++ INT_32 i4Status = -EINVAL; ++ WIFI_RADIO_STAT *pRadioStat; ++ struct sk_buff *skb; ++ UINT_32 u4BufLen; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ ++ u4BufLen = sizeof(WIFI_RADIO_STAT) + sizeof(WIFI_IFACE_STAT); ++ pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE); ++ if (!pRadioStat) { ++ DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", __func__); ++ return -ENOMEM; ++ } ++ kalMemZero(pRadioStat, u4BufLen); ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen); ++ if (!skb) { ++ DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); ++ return -ENOMEM; ++ } ++ ++ /*rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryStatistics, ++ &rRadioStat, ++ sizeof(rRadioStat), ++ TRUE, ++ TRUE, ++ TRUE, ++ FALSE, ++ &u4BufLen); */ ++ /* only for test */ ++ pRadioStat->radio = 10; ++ pRadioStat->on_time = 11; ++ pRadioStat->tx_time = 12; ++ pRadioStat->num_channels = 4; ++ ++ /*NLA_PUT(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat);*/ ++ if (unlikely(nla_put(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat) < 0)) ++ goto nla_put_failure; ++ ++ i4Status = cfg80211_vendor_cmd_reply(skb); ++ kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); ++ return -1; /* not support LLS now*/ ++ /* return i4Status; */ ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return i4Status; ++} ++ ++int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete) ++{ ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ /* WIFI_SCAN_EVENT complete_scan; */ ++ ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(complete), GSCAN_EVENT_COMPLETE_SCAN, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ /* complete_scan = WIFI_SCAN_COMPLETE; */ ++ /*NLA_PUT_U32(skb, GSCAN_EVENT_COMPLETE_SCAN, complete);*/ ++ { ++ unsigned int __tmp = complete; ++ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_COMPLETE_SCAN, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num) ++{ ++ struct sk_buff *skb; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ /* UINT_32 scan_result; */ ++ ++ DBGLOG(REQ, INFO, "%s for vendor command %d \r\n", __func__, num); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(num), GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ /* scan_result = 2; */ ++ /*NLA_PUT_U32(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, num);*/ ++ { ++ unsigned int __tmp = num; ++ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, ++ sizeof(unsigned int), &__tmp) < 0)) ++ goto nla_put_failure; ++ } ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_GSCAN_RESULT result; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(result), GSCAN_EVENT_FULL_SCAN_RESULTS, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ kalMemZero(&result, sizeof(result)); ++ kalMemCopy(result.ssid, "Gscan_full_test", sizeof("Gscan_full_test")); ++ result.channel = 2437; ++ ++ /* kalMemCopy(&result, pdata, sizeof(PARAM_WIFI_GSCAN_RESULT); */ ++ /*NLA_PUT(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, sizeof(result), &result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, ++ sizeof(result), &result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_CHANGE_RESULT result[2], *presult; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_CHANGE_RESULT), ++ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ presult = result; ++ kalMemZero(presult, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2)); ++ /* only for test */ ++ kalMemCopy(presult->bssid, "213123", sizeof(mac_addr)); ++ presult->channel = 2437; ++ presult->rssi[0] = -45; ++ presult->rssi[1] = -46; ++ presult++; ++ presult->channel = 2439; ++ presult->rssi[0] = -47; ++ presult->rssi[1] = -48; ++ /*NLA_PUT(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, ++ (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_GSCAN_RESULT result[2], *presult; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), ++ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ presult = result; ++ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); ++ /* only for test */ ++ kalMemCopy(presult->bssid, "123123", sizeof(mac_addr)); ++ presult->channel = 2441; ++ presult->rssi = -45; ++ presult++; ++ presult->channel = 2443; ++ presult->rssi = -47; ++ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, ++ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) ++{ ++ struct sk_buff *skb; ++ PARAM_WIFI_GSCAN_RESULT result[2], *presult; ++ ++ ASSERT(wiphy); ++ ASSERT(wdev); ++ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); ++ ++ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), ++ GSCAN_EVENT_HOTLIST_RESULTS_LOST, GFP_KERNEL); ++ if (!skb) { ++ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ presult = result; ++ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); ++ /* only for test */ ++ kalMemCopy(presult->bssid, "321321", sizeof(mac_addr)); ++ presult->channel = 2445; ++ presult->rssi = -46; ++ presult++; ++ presult->channel = 2447; ++ presult->rssi = -48; ++ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ ++ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, ++ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) ++ goto nla_put_failure; ++ ++ cfg80211_vendor_event(skb, GFP_KERNEL); ++ return 0; ++ ++nla_put_failure: ++ kfree_skb(skb); ++ return -1; ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c +new file mode 100644 +index 000000000000..1793742e9802 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c +@@ -0,0 +1,4158 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3 ++*/ ++ ++/*! \file gl_wext.c ++ \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver. ++*/ ++ ++/* ++** Log: gl_wext.c ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 01 16 2012 wh.su ++ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl ++ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 23 2011 tsaiyuan.hsu ++ * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state ++ * avoid entering D3 state after deep sleep. ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 27 2011 wh.su ++ * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query ++ * the ap address ++ * Remove the netif check while query bssid and ssid ++ * ++ * 07 26 2011 chinglan.wang ++ * NULL ++ * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection.. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 05 17 2011 eddie.chen ++ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning ++ * Initialize the vairlabes. ++ * ++ * 05 11 2011 jeffrey.chang ++ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power ++ * modify set_tx_pow ioctl ++ * ++ * 03 29 2011 terry.wu ++ * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring ++ * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of ++ * essid storage array. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 02 21 2011 wh.su ++ * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get ++ * essid ++ * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running. ++ * ++ * 02 08 2011 george.huang ++ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler ++ * Support querying power mode OID. ++ * ++ * 01 29 2011 wh.su ++ * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0 ++ * not doing mem alloc. while set ie length already 0 ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Remove debug text. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Adjust OID order. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 11 2011 chinglan.wang ++ * NULL ++ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish ++ * successfully. ++ * Use the WPS function to connect AP, the privacy bit always is set to 1. . ++ * ++ * 01 07 2011 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add a new compiling option to control if MCR read/write is permitted ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous types ++ * to ease slab system pressure ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add some iwpriv commands to support test mode operation ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Support set PS profile and set WMM-PS related iwpriv. ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Allow change PS profile function (through wext_set_power()). ++ * ++ * 12 14 2010 jeffrey.chang ++ * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID ++ * handle hidden SSID ++ * ++ * 12 13 2010 chinglan.wang ++ * NULL ++ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * Fix compiling error ++ * ++ * 12 07 2010 cm.chang ++ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant ++ * 1. Country code is from NVRAM or supplicant ++ * 2. Change band definition in CMD/EVENT. ++ * ++ * 11 30 2010 cp.wu ++ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 ++ * . ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power ++ * saving ++ * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving ++ * ++ * 10 18 2010 jeffrey.chang ++ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue ++ * refine the scan ioctl to prevent hanging of Android UI ++ * ++ * 10 01 2010 wh.su ++ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function ++ * add the scan result with wapi ie. ++ * ++ * 09 30 2010 wh.su ++ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue ++ * fixed the wapi ie assigned issue. ++ * ++ * 09 27 2010 wh.su ++ * NULL ++ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 09 2010 cp.wu ++ * NULL ++ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. ++ * ++ * 09 06 2010 cp.wu ++ * NULL ++ * Androi/Linux: return current operating channel information ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * enable remove key ioctl ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) enable encyption ioctls ++ * 2) temporarily disable remove keys ioctl to prevent TX1 busy ++ * ++ * 07 28 2010 jeffrey.chang ++ * NULL ++ * 1) remove unused spinlocks ++ * 2) enable encyption ioctls ++ * 3) fix scan ioctl which may cause supplicant to hang ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add kal api for scanning done ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * for linux driver migration ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove unused macro and debug messages ++ * ++ * 05 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add dissassoication support for wpa supplicant ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Add ioctl of power management ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove debug message ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used ++ * * 2) fix ioctl ++ * ++ * 04 12 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove debug messages for pre-release ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * * are done in adapter layer. ++ * ++ * 04 02 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix ioctl type ++ * ++ * 04 01 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * enable pmksa cache operation ++ * ++ * 03 31 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix ioctl which may cause cmdinfo memory leak ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). ++** Add more checking for input parameters and pointers. ++** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090 ++** Remove unused variables ++** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088 ++** adding the wapi ioctl support ++** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089 ++** fix compiling warning ++** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089 ++** Add mandatory and private IO control for Linux BWCS ++** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088 ++** fixed the compiling error ++** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088 ++** add the privacy setting from linux supplicant ap selection ++** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088 ++** fixed the compling error ++** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088 ++** rename some variable with pre-fix to avoid the misunderstanding ++** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088 ++** fixed compiling error ++** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088 ++** adjust the code for meet the coding style, and add assert check ++** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461 ++** Update after wlanoidSetPowerMode changed ++** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084 ++** rename wlanoid ++** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461 ++** Add set desired rate in Linux STD IOCTL ++** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088 ++** add pmkid ioctl and indicate ++** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461 ++** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461 ++** Refine WPS related priv ioctl for unified interface ++** ++** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088 ++** move the configuration code from set essid function, ++** remove the non-used code ++** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461 ++** Fix CR[489] ++** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461 ++** Add Set Frequency & Channel oid support for Linux ++** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461 ++** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461 ++** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter ++** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425 ++** 1. Branch Test ++** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461 ++** fix typo ++** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425 ++** 1. Fix compiling erros ++** ++** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425 ++** 1. Add WMM-PS setting ++** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088 ++** fixed the compiler error ++** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088 ++** add WPS code ++** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425 ++** 1. Update wlanQueryInformation ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#include "gl_os.h" ++ ++#include "config.h" ++#include "wlan_oid.h" ++ ++#include "gl_wext.h" ++#include "gl_wext_priv.h" ++ ++#include "precomp.h" ++ ++#if CFG_SUPPORT_WAPI ++#include "gl_sec.h" ++#endif ++ ++/* compatibility to wireless extensions */ ++#ifdef WIRELESS_EXT ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++const long channel_freq[] = { ++ 2412, 2417, 2422, 2427, 2432, 2437, 2442, ++ 2447, 2452, 2457, 2462, 2467, 2472, 2484 ++}; ++ ++ ++#define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0])) ++ ++#define MAX_SSID_LEN 32 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++/* NOTE: name in iwpriv_args only have 16 bytes */ ++static const struct iw_priv_args rIwPrivTable[] = { ++ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, ++ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""}, ++ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""}, ++ ++ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, ++ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, ++ ++ {IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""}, ++ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_CHAR | 16, ""}, ++ ++ {IOCTL_SET_STRING, IW_PRIV_TYPE_CHAR | 256, 0, ""}, ++ ++ /* added for set_oid and get_oid */ ++ {IOCTL_SET_STRUCT, 256, 0, ""}, ++ {IOCTL_GET_STRUCT, 0, 256, ""}, ++ ++ /* sub-ioctl definitions */ ++#if 0 ++ {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain"}, ++ {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain"}, ++#endif ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum"}, ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode"}, ++ {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode"}, ++ ++ {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps"}, ++ ++ {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode"}, ++ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd"}, ++ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_test_result"}, ++#if CFG_SUPPORT_PRIV_MCR_RW ++ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr"}, ++ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_mcr"}, ++#endif ++ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl"}, ++ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_sw_ctrl"}, ++ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"}, ++ /* GET STRUCT sub-ioctls commands */ ++ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_bwcs"}, ++#endif ++ ++ /* SET STRUCT sub-ioctls commands */ ++ {PRIV_CMD_OID, 256, 0, "set_oid"}, ++ /* GET STRUCT sub-ioctls commands */ ++ {PRIV_CMD_OID, 0, 256, "get_oid"}, ++ ++ {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band"}, ++ {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band"}, ++ ++ {PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower"}, ++ {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list"}, ++ {PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ "get_mem"}, ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode"}, ++#endif ++ {PRIV_CMD_GET_BUILD_DATE_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_date_code"}, ++ {PRIV_CMD_GET_DEBUG_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_dbg_code"}, ++ /* handle any command with many input parameters */ ++ {PRIV_CMD_OTHER, IW_PRIV_TYPE_CHAR | 256, 0, "set_str_cmd"}, ++ ++ {PRIV_CMD_WFD_DEBUG_CODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_wfd_dbg_code"}, ++}; ++ ++static const iw_handler rIwPrivHandler[] = { ++ [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int, ++ [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int, ++ [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL, ++ [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct, ++ [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct, ++ [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct, ++ [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints, ++ [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints, ++ [IOCTL_SET_STRING - SIOCIWFIRSTPRIV] = priv_set_string, ++}; ++ ++const struct iw_handler_def wext_handler_def = { ++ .num_standard = 0, ++ .num_private = (__u16) sizeof(rIwPrivHandler) / sizeof(iw_handler), ++ .num_private_args = (__u16) sizeof(rIwPrivTable) / sizeof(struct iw_priv_args), ++ .standard = (iw_handler *) NULL, ++ .private = rIwPrivHandler, ++ .private_args = rIwPrivTable, ++ .get_wireless_stats = wext_get_wireless_stats, ++}; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired WPA/RSN Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { ++ if (ucDesiredElemId != 0xDD) { ++ /* Non 0xDD, OK! */ ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ /* EID == 0xDD, check WPA IE */ ++ if (pucIEStart[1] >= 4) { ++ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ } /* check WPA IE length */ ++ /* check EID == 0xDD */ ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* parseSearchDesiredWPAIE */ ++ ++#if CFG_SUPPORT_WAPI ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired WAPI Information Element . ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredWAPIIE */ ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired HS2.0 Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredHS20IE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { ++ if (pucCurIE[1] >= ELEM_MIN_LEN_HS20_INDICATION) { ++ if (memcmp(&pucCurIE[2], "\x50\x6f\x9a\x10", 4) == 0) ++ return TRUE; ++ } ++ } ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredHS20IE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired interworking Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredInterworkingIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { ++ switch (pucCurIE[1]) { ++ case IW_IE_LENGTH_ANO: ++ case IW_IE_LENGTH_ANO_HESSID: ++ case IW_IE_LENGTH_ANO_VENUE: ++ case IW_IE_LENGTH_ANO_VENUE_HESSID: ++ return TRUE; ++ ++ default: ++ break; ++ } ++ ++ } ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredInterworkingIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredAdvProtocolIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) ++ return TRUE; ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredAdvProtocolIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextIsDesiredRoamingConsortiumIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucCurIE); ++ ++ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; ++ ++ if (pucCurIE[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) ++ return TRUE; ++ /* check desired EID */ ++ return FALSE; ++} /* wextIsDesiredRoamingConsortiumIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired HS2.0 Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { ++ if (pucIEStart[1] >= ELEM_MIN_LEN_HS20_INDICATION) { ++ if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x10", 4) == 0) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ } ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredHS20IE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired interworking Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredInterworkingIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired Adv Protocol Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredAdvProtocolIE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired Roaming Consortium Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* wextSrchDesiredRoamingConsortiumIE */ ++#endif ++ ++#if CFG_SUPPORT_WPS ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Find the desired WPS Information Element according to desiredElemID. ++* ++* \param[in] pucIEStart IE starting address. ++* \param[in] i4TotalIeLen Total length of all the IE. ++* \param[in] ucDesiredElemId Desired element ID. ++* \param[out] ppucDesiredIE Pointer to the desired IE. ++* ++* \retval TRUE Find the desired IE. ++* \retval FALSE Desired IE not found. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) ++{ ++ INT_32 i4InfoElemLen; ++ ++ ASSERT(pucIEStart); ++ ASSERT(ppucDesiredIE); ++ ++ while (i4TotalIeLen >= 2) { ++ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; ++ ++ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { ++ if (ucDesiredElemId != 0xDD) { ++ /* Non 0xDD, OK! */ ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ /* EID == 0xDD, check WPS IE */ ++ if (pucIEStart[1] >= 4) { ++ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) { ++ *ppucDesiredIE = &pucIEStart[0]; ++ return TRUE; ++ } ++ } /* check WPS IE length */ ++ /* check EID == 0xDD */ ++ } ++ ++ /* check desired EID */ ++ /* Select next information element. */ ++ i4TotalIeLen -= i4InfoElemLen; ++ pucIEStart += i4InfoElemLen; ++ } ++ ++ return FALSE; ++} /* parseSearchDesiredWPSIE */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Get the name of the protocol used on the air. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] pcName Buffer to store protocol name string ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* ++* \note If netif_carrier_ok, protocol name is returned; ++* otherwise, "disconnected" is returned. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_name(IN struct net_device *prNetDev, IN struct iw_request_info *prIwrInfo, OUT char *pcName, IN char *pcExtra) ++{ ++ ENUM_PARAM_NETWORK_TYPE_T eNetWorkType = PARAM_NETWORK_TYPE_NUM; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pcName); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcName)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (netif_carrier_ok(prNetDev)) { ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryNetworkTypeInUse, ++ &eNetWorkType, sizeof(eNetWorkType), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ switch (eNetWorkType) { ++ case PARAM_NETWORK_TYPE_DS: ++ strcpy(pcName, "IEEE 802.11b"); ++ break; ++ case PARAM_NETWORK_TYPE_OFDM24: ++ strcpy(pcName, "IEEE 802.11bgn"); ++ break; ++ case PARAM_NETWORK_TYPE_AUTOMODE: ++ case PARAM_NETWORK_TYPE_OFDM5: ++ strcpy(pcName, "IEEE 802.11abgn"); ++ break; ++ case PARAM_NETWORK_TYPE_FH: ++ default: ++ strcpy(pcName, "IEEE 802.11"); ++ break; ++ } ++ } else { ++ strcpy(pcName, "Disconnected"); ++ } ++ ++ return 0; ++} /* wext_get_name */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set the operating channel in the wireless device. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL ++* \param[in] prFreq Buffer to store frequency information ++* \param[in] pcExtra NULL ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS. ++* \retval -EINVAL Invalid channel frequency. ++* ++* \note If infrastructure mode is IBSS, new channel frequency is set to device. ++* The range of channel number depends on different regulatory domain. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_freq(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN struct iw_freq *prIwFreq, IN char *pcExtra) ++{ ++ ++#if 0 ++ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwFreq); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* ++ printk("set m:%d, e:%d, i:%d, flags:%d\n", ++ prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags); ++ */ ++ ++ /* If setting by frequency, convert to a channel */ ++ if ((prIwFreq->e == 1) && (prIwFreq->m >= (int)2.412e8) && (prIwFreq->m <= (int)2.484e8)) { ++ ++ /* Change to KHz format */ ++ u4ChnlFreq = (UINT_32) (prIwFreq->m / (KILO / 10)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetFrequency, ++ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (WLAN_STATUS_SUCCESS != rStatus) ++ return -EINVAL; ++ } ++ /* Setting by channel number */ ++ else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) ++ return -EOPNOTSUPP; ++ ++ /* Change to channel number format */ ++ u4ChnlFreq = (UINT_32) prIwFreq->m; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetChannel, &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (WLAN_STATUS_SUCCESS != rStatus) ++ return -EINVAL; ++ ++#endif ++ ++ return 0; ++ ++} /* wext_set_freq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get the operating channel in the wireless device. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prFreq Buffer to store frequency information. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise ++* ++* \note If netif_carrier_ok, channel frequency information is stored in pFreq. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_freq(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_freq *prIwFreq, IN char *pcExtra) ++{ ++ UINT_32 u4Channel = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwFreq); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* GeorgeKuo: TODO skip checking in IBSS mode */ ++ if (!netif_carrier_ok(prNetDev)) ++ return -ENOTCONN; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryFrequency, &u4Channel, sizeof(u4Channel), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ prIwFreq->m = (int)u4Channel; /* freq in KHz */ ++ prIwFreq->e = 3; ++ ++ return 0; ++ ++} /* wext_get_freq */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set operating mode. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] pu4Mode Pointer to new operation mode. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If new mode is not supported. ++* ++* \note Device will run in new operation mode if it is valid. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_mode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN unsigned int *pu4Mode, IN char *pcExtra) ++{ ++ ENUM_PARAM_OP_MODE_T eOpMode; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pu4Mode); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ switch (*pu4Mode) { ++ case IW_MODE_AUTO: ++ eOpMode = NET_TYPE_AUTO_SWITCH; ++ break; ++ ++ case IW_MODE_ADHOC: ++ eOpMode = NET_TYPE_IBSS; ++ break; ++ ++ case IW_MODE_INFRA: ++ eOpMode = NET_TYPE_INFRA; ++ break; ++ ++ default: ++ DBGLOG(REQ, ERROR, "%s(): Set UNSUPPORTED Mode = %d.\n", __func__, *pu4Mode); ++ return -EOPNOTSUPP; ++ } ++ ++ /* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ /* after set operation mode, key table are cleared */ ++ ++ /* reset wpa info */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ return 0; ++} /* wext_set_mode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get operating mode. ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIwReqInfo NULL. ++* \param[out] pu4Mode Buffer to store operating mode information. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If data is valid. ++* \retval -EINVAL Otherwise. ++* ++* \note If netif_carrier_ok, operating mode information is stored in pu4Mode. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_mode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, OUT unsigned int *pu4Mode, IN char *pcExtra) ++{ ++ ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_NUM; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pu4Mode); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryInfrastructureMode, ++ &eOpMode, sizeof(eOpMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ switch (eOpMode) { ++ case NET_TYPE_IBSS: ++ *pu4Mode = IW_MODE_ADHOC; ++ break; ++ ++ case NET_TYPE_INFRA: ++ *pu4Mode = IW_MODE_INFRA; ++ break; ++ ++ case NET_TYPE_AUTO_SWITCH: ++ *pu4Mode = IW_MODE_AUTO; ++ break; ++ ++ default: ++ DBGLOG(REQ, ERROR, "%s(): Get UNKNOWN Mode.\n", __func__); ++ return -EINVAL; ++ } ++ ++ return 0; ++} /* wext_get_mode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get the valid range for each configurable STA setting value. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prData Pointer to iw_point structure, not used. ++* \param[out] pcExtra Pointer to buffer which is allocated by caller of this ++* function, wext_support_ioctl() or ioctl_standard_call() in ++* wireless.c. ++* ++* \retval 0 If data is valid. ++* ++* \note The extra buffer (pcExtra) is filled with information from driver. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_range(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, OUT char *pcExtra) ++{ ++ struct iw_range *prRange = NULL; ++ PARAM_RATES_EX aucSuppRate = { 0 }; /* data buffers */ ++ int i = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ prRange = (struct iw_range *)pcExtra; ++ ++ memset(prRange, 0, sizeof(*prRange)); ++ prRange->throughput = 20000000; /* 20Mbps */ ++ prRange->min_nwid = 0; /* not used */ ++ prRange->max_nwid = 0; /* not used */ ++ ++ /* scan_capa not implemented */ ++ ++ /* event_capa[6]: kernel + driver capabilities */ ++ prRange->event_capa[0] = (IW_EVENT_CAPA_K_0 | IW_EVENT_CAPA_MASK(SIOCGIWAP) ++ | IW_EVENT_CAPA_MASK(SIOCGIWSCAN) ++ /* can't display meaningful string in iwlist ++ | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW) ++ | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE) ++ | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE) ++ | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND) ++ */ ++ ); ++ prRange->event_capa[1] = IW_EVENT_CAPA_K_1; ++ ++ /* report 2.4G channel and frequency only */ ++ prRange->num_channels = (__u16) NUM_CHANNELS; ++ prRange->num_frequency = (__u8) NUM_CHANNELS; ++ for (i = 0; i < NUM_CHANNELS; i++) { ++ /* iwlib takes this number as channel number */ ++ prRange->freq[i].i = i + 1; ++ prRange->freq[i].m = channel_freq[i]; ++ prRange->freq[i].e = 6; /* Values in table in MHz */ ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQuerySupportedRates, ++ &aucSuppRate, sizeof(aucSuppRate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX; i++) { ++ if (aucSuppRate[i] == 0) ++ break; ++ prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000; /* 0.5Mbps */ ++ } ++ prRange->num_bitrates = i; ++ ++ prRange->min_rts = 0; ++ prRange->max_rts = 2347; ++ prRange->min_frag = 256; ++ prRange->max_frag = 2346; ++ ++ prRange->min_pmp = 0; /* power management by driver */ ++ prRange->max_pmp = 0; /* power management by driver */ ++ prRange->min_pmt = 0; /* power management by driver */ ++ prRange->max_pmt = 0; /* power management by driver */ ++ prRange->pmp_flags = IW_POWER_RELATIVE; /* pm default flag */ ++ prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */ ++ prRange->pm_capa = IW_POWER_ON; /* power management by driver */ ++ ++ prRange->encoding_size[0] = 5; /* wep40 */ ++ prRange->encoding_size[1] = 16; /* tkip */ ++ prRange->encoding_size[2] = 16; /* ckip */ ++ prRange->encoding_size[3] = 16; /* ccmp */ ++ prRange->encoding_size[4] = 13; /* wep104 */ ++ prRange->encoding_size[5] = 16; /* wep128 */ ++ prRange->num_encoding_sizes = 6; ++ prRange->max_encoding_tokens = 6; /* token? */ ++ ++#if WIRELESS_EXT < 17 ++ prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */ ++#else ++ prRange->txpower_capa = IW_TXPOW_RELATIVE; ++#endif ++ prRange->num_txpower = 5; ++ prRange->txpower[0] = 0; /* minimum */ ++ prRange->txpower[1] = 25; /* 25% */ ++ prRange->txpower[2] = 50; /* 50% */ ++ prRange->txpower[3] = 100; /* 100% */ ++ ++ prRange->we_version_compiled = WIRELESS_EXT; ++ prRange->we_version_source = WIRELESS_EXT; ++ ++ prRange->retry_capa = IW_RETRY_LIMIT; ++ prRange->retry_flags = IW_RETRY_LIMIT; ++ prRange->min_retry = 7; ++ prRange->max_retry = 7; ++ prRange->r_time_flags = IW_RETRY_ON; ++ prRange->min_r_time = 0; ++ prRange->max_r_time = 0; ++ ++ /* signal strength and link quality */ ++ /* Just define range here, reporting value moved to wext_get_stats() */ ++ prRange->sensitivity = -83; /* fixed value */ ++ prRange->max_qual.qual = 100; /* max 100% */ ++ prRange->max_qual.level = (__u8) (0x100 - 0); /* max 0 dbm */ ++ prRange->max_qual.noise = (__u8) (0x100 - 0); /* max 0 dbm */ ++ ++ /* enc_capa */ ++#if WIRELESS_EXT > 17 ++ prRange->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; ++#endif ++ ++ /* min_pms; Minimal PM saving */ ++ /* max_pms; Maximal PM saving */ ++ /* pms_flags; How to decode max/min PM saving */ ++ ++ /* modul_capa; IW_MODUL_* bit field */ ++ /* bitrate_capa; Types of bitrates supported */ ++ ++ return 0; ++} /* wext_get_range */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set BSSID of AP to connect. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* ++* \note Desired AP's BSSID is set to driver. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_ap(IN struct net_device *prDev, ++ IN struct iw_request_info *prIwrInfo, IN struct sockaddr *prAddr, IN char *pcExtra) ++{ ++ return 0; ++} /* wext_set_ap */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get AP MAC address. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise. ++* ++* \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_ap(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct sockaddr *prAddr, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prAddr); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* if (!netif_carrier_ok(prNetDev)) { */ ++ /* return -ENOTCONN; */ ++ /* } */ ++ ++ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED) { ++ /*memset(prAddr, 0, 6);*/ ++ memset(prAddr, 0, sizeof(struct sockaddr)); ++ return 0; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBssid, prAddr->sa_data, ETH_ALEN, TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ return 0; ++} /* wext_get_ap */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set mlme operation request. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prData Pointer of iw_point header. ++* \param[in] pcExtra Pointer to iw_mlme structure mlme request information. ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP unsupported IW_MLME_ command. ++* \retval -EINVAL Set MLME Fail, different bssid. ++* ++* \note Driver will start mlme operation if valid. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_mlme(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, IN char *pcExtra) ++{ ++ struct iw_mlme *prMlme = NULL; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ prMlme = (struct iw_mlme *)pcExtra; ++ if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) { ++ if (!netif_carrier_ok(prNetDev)) { ++ DBGLOG(REQ, WARN, "[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"); ++ return 0; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ return 0; ++ } ++ DBGLOG(REQ, WARN, "[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd); ++ return -EOPNOTSUPP; ++ ++} /* wext_set_mlme */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To issue scan request. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prData NULL. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* \retval -EFAULT Tx power is off. ++* ++* \note Device will start scanning. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_scan(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN union iwreq_data *prData, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ int essid_len = 0; ++ ++ ASSERT(prNetDev); ++ if (FALSE == GLUE_CHK_DEV(prNetDev)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++#if WIRELESS_EXT > 17 ++ /* retrieve SSID */ ++ if (prData) ++ essid_len = ((struct iw_scan_req *)(((struct iw_point *)prData)->pointer))->essid_len; ++#endif ++ ++ init_completion(&prGlueInfo->rScanComp); ++ ++ /* TODO: parse flags and issue different scan requests? */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetBssidListScan, pcExtra, essid_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ); */ ++ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ ++ ++ return 0; ++} /* wext_set_scan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To write the ie to buffer ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) ++{ ++ size_t i; ++ char *pos = buf, *end = buf + buf_size; ++ int ret; ++ ++ if (buf_size == 0) ++ return 0; ++ ++ for (i = 0; i < len; i++) { ++ ret = snprintf(pos, end - pos, "%02x", data[i]); ++ if (ret < 0 || ret >= end - pos) { ++ end[-1] = '\0'; ++ return pos - buf; ++ } ++ pos += ret; ++ } ++ end[-1] = '\0'; ++ return pos - buf; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get scan results, transform results from driver's format to WE's. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prData Pointer to iw_point structure, pData->length is the size of ++* pcExtra buffer before used, and is updated after filling scan ++* results. ++* \param[out] pcExtra Pointer to buffer which is allocated by caller of this ++* function, wext_support_ioctl() or ioctl_standard_call() in ++* wireless.c. ++* ++* \retval 0 For success. ++* \retval -ENOMEM If dynamic memory allocation fail. ++* \retval -E2BIG Invalid length. ++* ++* \note Scan results is filled into pcExtra buffer, data size is updated in ++* pData->length. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_scan(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN OUT struct iw_point *prData, IN char *pcExtra) ++{ ++ UINT_32 i = 0; ++ UINT_32 j = 0; ++ P_PARAM_BSSID_LIST_EX_T prList = NULL; ++ P_PARAM_BSSID_EX_T prBss = NULL; ++ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; ++ struct iw_event iwEvent; /* local iw_event buffer */ ++ ++ /* write pointer of extra buffer */ ++ char *pcCur = NULL; ++ /* pointer to the end of last full entry in extra buffer */ ++ char *pcValidEntryEnd = NULL; ++ char *pcEnd = NULL; /* end of extra buffer */ ++ ++ UINT_32 u4AllocBufLen = 0; ++ ++ /* arrange rate information */ ++ UINT_32 u4HighestRate = 0; ++ char aucRatesBuf[64]; ++ UINT_32 u4BufIndex; ++ ++ /* return value */ ++ int ret = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prData); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* Initialize local variables */ ++ pcCur = pcExtra; ++ pcValidEntryEnd = pcExtra; ++ pcEnd = pcExtra + prData->length; /* end of extra buffer */ ++ ++ /* Allocate another query buffer with the same size of extra buffer */ ++ u4AllocBufLen = prData->length; ++ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); ++ if (prList == NULL) { ++ DBGLOG(REQ, ERROR, "[wifi] no memory for scan list:%d\n", prData->length); ++ ret = -ENOMEM; ++ goto error; ++ } ++ prList->u4NumberOfItems = 0; ++ ++ /* wait scan done */ ++ /* printk ("wait for scan results\n"); */ ++ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ); */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { ++ /* Buffer length is not large enough. */ ++ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ ++ ++#if WIRELESS_EXT >= 17 ++ /* This feature is supported in WE-17 or above, limited by iwlist. ++ ** Return -E2BIG and iwlist will request again with a larger buffer. ++ */ ++ ret = -E2BIG; ++ /* Update length to give application a hint on result length */ ++ prData->length = (__u16) u4BufLen; ++ goto error; ++#else ++ /* Realloc a larger query buffer here, but don't write too much to extra ++ ** buffer when filling it later. ++ */ ++ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); ++ ++ u4AllocBufLen = u4BufLen; ++ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); ++ if (prList == NULL) { ++ DBGLOG(REQ, ERROR, "[wifi] no memory for larger scan list :%u\n", u4BufLen); ++ ret = -ENOMEM; ++ goto error; ++ } ++ prList->NumberOfItems = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { ++ DBGLOG(REQ, ERROR, "[wifi] larger buf:%u result:%u\n", u4AllocBufLen, u4BufLen); ++ ret = -E2BIG; ++ prData->length = (__u16) u4BufLen; ++ goto error; ++ } ++#endif /* WIRELESS_EXT >= 17 */ ++ ++ } ++ ++ if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) { ++ DBGLOG(REQ, WARN, "[wifi] strange scan result count:%u\n", prList->u4NumberOfItems); ++ goto error; ++ } ++ ++ /* Copy required data from pList to pcExtra */ ++ prBss = &prList->arBssid[0]; /* set to the first entry */ ++ for (i = 0; i < prList->u4NumberOfItems; ++i) { ++ /* BSSID */ ++ iwEvent.cmd = SIOCGIWAP; ++ iwEvent.len = IW_EV_ADDR_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER; ++ ether_addr_copy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress); ++ memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN); ++ pcCur += IW_EV_ADDR_LEN; ++ ++ /* SSID */ ++ iwEvent.cmd = SIOCGIWESSID; ++ /* Modification to user space pointer(essid.pointer) is not needed. */ ++ iwEvent.u.essid.length = (__u16) prBss->rSsid.u4SsidLen; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length; ++ ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.essid.flags = 1; ++ iwEvent.u.essid.pointer = NULL; ++ ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, iwEvent.len); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length); ++ pcCur += iwEvent.len; ++ /* Frequency */ ++ iwEvent.cmd = SIOCGIWFREQ; ++ iwEvent.len = IW_EV_FREQ_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig; ++ iwEvent.u.freq.e = 3; /* (in KHz) */ ++ iwEvent.u.freq.i = 0; ++ memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN); ++ pcCur += IW_EV_FREQ_LEN; ++ ++ /* Operation Mode */ ++ iwEvent.cmd = SIOCGIWMODE; ++ iwEvent.len = IW_EV_UINT_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ if (prBss->eOpMode == NET_TYPE_IBSS) ++ iwEvent.u.mode = IW_MODE_ADHOC; ++ else if (prBss->eOpMode == NET_TYPE_INFRA) ++ iwEvent.u.mode = IW_MODE_INFRA; ++ else ++ iwEvent.u.mode = IW_MODE_AUTO; ++ memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN); ++ pcCur += IW_EV_UINT_LEN; ++ ++ /* Quality */ ++ iwEvent.cmd = IWEVQUAL; ++ iwEvent.len = IW_EV_QUAL_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.qual.qual = 0; /* Quality not available now */ ++ /* -100 < Rssi < -10, normalized by adding 0x100 */ ++ iwEvent.u.qual.level = 0x100 + prBss->rRssi; ++ iwEvent.u.qual.noise = 0; /* Noise not available now */ ++ iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; ++ memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN); ++ pcCur += IW_EV_QUAL_LEN; ++ ++ /* Security Mode */ ++ iwEvent.cmd = SIOCGIWENCODE; ++ iwEvent.len = IW_EV_POINT_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.data.pointer = NULL; ++ iwEvent.u.data.flags = 0; ++ iwEvent.u.data.length = 0; ++ if (!prBss->u4Privacy) ++ iwEvent.u.data.flags |= IW_ENCODE_DISABLED; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ pcCur += IW_EV_POINT_LEN; ++ ++ /* rearrange rate information */ ++ u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):"); ++ u4HighestRate = 0; ++ for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) { ++ UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F; ++ ++ if (curRate == 0) ++ break; ++ ++ if (curRate > u4HighestRate) ++ u4HighestRate = curRate; ++ ++ if (curRate == RATE_5_5M) ++ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5"); ++ else ++ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2); ++#if DBG ++ if (u4BufIndex > sizeof(aucRatesBuf)) { ++ /* printk("rate info too long\n"); */ ++ break; ++ } ++#endif ++ } ++ /* Report Highest Rates */ ++ iwEvent.cmd = SIOCGIWRATE; ++ iwEvent.len = IW_EV_PARAM_LEN; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.bitrate.value = u4HighestRate * 500000; ++ iwEvent.u.bitrate.fixed = 0; ++ iwEvent.u.bitrate.disabled = 0; ++ iwEvent.u.bitrate.flags = 0; ++ memcpy(pcCur, &iwEvent, iwEvent.len); ++ pcCur += iwEvent.len; ++ ++#if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */ ++ /* Report Residual Rates */ ++ iwEvent.cmd = IWEVCUSTOM; ++ iwEvent.u.data.length = u4BufIndex; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.data.flags = 0; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex); ++ pcCur += iwEvent.len; ++#endif /* WIRELESS_EXT >= 15 */ ++ ++ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++ } ++#if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */ ++ if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++ } ++#endif ++ ++ /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */ ++ /* pBss->IEs starts from timestamp */ ++ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), ++ 0x30, (PUINT_8 *) &prDesiredIE)) { ++ ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++ } ++#if CFG_SUPPORT_WAPI /* Android+ */ ++ if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], ++ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), (PUINT_8 *) &prDesiredIE)) { ++ ++#if 0 ++ iwEvent.cmd = IWEVGENIE; ++ iwEvent.u.data.flags = 1; ++ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++#if WIRELESS_EXT <= 18 ++ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); ++#else ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++#endif ++ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); ++ pcCur += iwEvent.len; ++#else ++ iwEvent.cmd = IWEVCUSTOM; ++ iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */; ++ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; ++ if ((pcCur + iwEvent.len) > pcEnd) ++ break; ++ iwEvent.u.data.flags = 1; ++ ++ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); ++ memcpy(pcCur + IW_EV_LCP_LEN, ++ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); ++ ++ pcCur += (IW_EV_POINT_LEN); ++ ++ pcCur += sprintf(pcCur, "wapi_ie="); ++ ++ snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *) prDesiredIE, prDesiredIE->ucLength + 2); ++ ++ pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */; ++#endif ++ } ++#endif ++ /* Complete an entry. Update end of valid entry */ ++ pcValidEntryEnd = pcCur; ++ /* Extract next bss */ ++ prBss = (P_PARAM_BSSID_EX_T) ((char *)prBss + prBss->u4Length); ++ } ++ ++ /* Update valid data length for caller function and upper layer ++ * applications. ++ */ ++ prData->length = (pcValidEntryEnd - pcExtra); ++ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ ++ ++ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ ++ ++error: ++ /* free local query buffer */ ++ if (prList) ++ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); ++ ++ return ret; ++} /* wext_get_scan */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set desired network name ESSID. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEssid Pointer of iw_point header. ++* \param[in] pcExtra Pointer to buffer srtoring essid string. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -E2BIG Essid string length is too big. ++* \retval -EINVAL pcExtra is null pointer. ++* \retval -EFAULT Driver fail to set new essid. ++* ++* \note If string length is ok, device will try connecting to the new network. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_essid(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, IN char *pcExtra) ++{ ++ PARAM_SSID_T rNewSsid; ++ UINT_32 cipher; ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEssid); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (prEssid->length > IW_ESSID_MAX_SIZE) ++ return -E2BIG; ++ ++ /* set auth mode */ ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { ++ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? ++ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; ++ /* printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n", */ ++ /* (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); */ ++ } else { ++ /* set auth mode */ ++ switch (prGlueInfo->rWpaInfo.u4KeyMgmt) { ++ case IW_AUTH_KEY_MGMT_802_1X: ++ eAuthMode = ++ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? ++ AUTH_MODE_WPA : AUTH_MODE_WPA2; ++ /* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", */ ++ /* (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); */ ++ break; ++ case IW_AUTH_KEY_MGMT_PSK: ++ eAuthMode = ++ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? ++ AUTH_MODE_WPA_PSK : AUTH_MODE_WPA2_PSK; ++ /* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", */ ++ /* (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); */ ++ break; ++#if CFG_SUPPORT_WAPI /* Android+ */ ++ case IW_AUTH_KEY_MGMT_WAPI_PSK: ++ break; ++ case IW_AUTH_KEY_MGMT_WAPI_CERT: ++ break; ++#endif ++ ++/* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */ ++/* case IW_AUTH_KEY_MGMT_WPA_NONE: */ ++/* eAuthMode = AUTH_MODE_WPA_NONE; */ ++/* //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); */ ++/* break; */ ++/* #endif */ ++#if CFG_SUPPORT_802_11W ++ case IW_AUTH_KEY_MGMT_802_1X_SHA256: ++ eAuthMode = AUTH_MODE_WPA2; ++ break; ++ case IW_AUTH_KEY_MGMT_PSK_SHA256: ++ eAuthMode = AUTH_MODE_WPA2_PSK; ++ break; ++#endif ++ default: ++ /* printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n", */ ++ /* prGlueInfo->rWpaInfo.u4KeyMgmt); */ ++ eAuthMode = AUTH_MODE_AUTO_SWITCH; ++ break; ++ } ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ /* set encryption status */ ++ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; ++ if (cipher & IW_AUTH_CIPHER_CCMP) { ++ /* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */ ++ eEncStatus = ENUM_ENCRYPTION3_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_TKIP) { ++ /* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */ ++ eEncStatus = ENUM_ENCRYPTION2_ENABLED; ++ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { ++ /* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */ ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ } else if (cipher & IW_AUTH_CIPHER_NONE) { ++ /* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */ ++ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) ++ eEncStatus = ENUM_ENCRYPTION1_ENABLED; ++ else ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } else { ++ /* printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n"); */ ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++#if WIRELESS_EXT < 21 ++ /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before ++ ** 2.6.19. Cut the trailing '\0'. ++ */ ++ rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0; ++#else ++ rNewSsid.u4SsidLen = prEssid->length; ++#endif ++ kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen); ++ ++ /* ++ rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0'; ++ printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid); ++ */ ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidSetSsid, ++ (PVOID)&rNewSsid, ++ sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen) != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_WARNING "Fail to set ssid\n"); */ ++ return -EFAULT; ++ } ++ ++ return 0; ++} /* wext_set_essid */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get current network name ESSID. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEssid Pointer to iw_point structure containing essid information. ++* \param[out] pcExtra Pointer to buffer srtoring essid string. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise. ++* ++* \note If netif_carrier_ok, network essid is stored in pcExtra. ++*/ ++/*----------------------------------------------------------------------------*/ ++/* static PARAM_SSID_T ssid; */ ++static int ++wext_get_essid(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, OUT char *pcExtra) ++{ ++ /* PARAM_SSID_T ssid; */ ++ ++ P_PARAM_SSID_T prSsid; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEssid); ++ ASSERT(pcExtra); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* if (!netif_carrier_ok(prNetDev)) { */ ++ /* return -ENOTCONN; */ ++ /* } */ ++ ++ prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE); ++ ++ if (!prSsid) ++ return -ENOMEM; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQuerySsid, prSsid, sizeof(PARAM_SSID_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) { ++ kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen); ++ prEssid->length = prSsid->u4SsidLen; ++ prEssid->flags = 1; ++ } ++ ++ kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T)); ++ ++ return 0; ++} /* wext_get_essid */ ++ ++#if 0 ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set tx desired bit rate. Three cases here ++* iwconfig wlan0 auto -> Set to origianl supported rate set. ++* iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate. ++* iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps ++* ++* \param[in] prNetDev Pointer to the net_device handler. ++* \param[in] prIwReqInfo Pointer to the Request Info. ++* \param[in] prRate Pointer to the Rate Parameter. ++* \param[in] pcExtra Pointer to the extra buffer. ++* ++* \retval 0 Update desired rate. ++* \retval -EINVAL Wrong parameter ++*/ ++/*----------------------------------------------------------------------------*/ ++int ++wext_set_rate(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra) ++{ ++ PARAM_RATES_EX aucSuppRate = { 0 }; ++ PARAM_RATES_EX aucNewRate = { 0 }; ++ UINT_32 u4NewRateLen = 0; ++ UINT_32 i; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRate); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* ++ printk("value = %d, fixed = %d, disable = %d, flags = %d\n", ++ prRate->value, prRate->fixed, prRate->disabled, prRate->flags); ++ */ ++ ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuerySupportedRates, &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); ++ ++ /* Case: AUTO */ ++ if (prRate->value < 0) { ++ if (prRate->fixed == 0) { ++ /* iwconfig wlan0 rate auto */ ++ ++ /* set full supported rate to device */ ++ /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */ ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetDesiredRates, ++ &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); ++ return 0; ++ } ++ /* iwconfig wlan0 rate fixed */ ++ ++ /* fix rate to what? DO NOTHING */ ++ return -EINVAL; ++ } ++ ++ aucNewRate[0] = prRate->value / 500000; /* In unit of 500k */ ++ ++ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) { ++ /* check the given value is supported */ ++ if (aucSuppRate[i] == 0) ++ break; ++ ++ if (aucNewRate[0] == aucSuppRate[i]) { ++ u4NewRateLen = 1; ++ break; ++ } ++ } ++ ++ if (u4NewRateLen == 0) { ++ /* the given value is not supported */ ++ /* return error or use given rate as upper bound? */ ++ return -EINVAL; ++ } ++ ++ if (prRate->fixed == 0) { ++ /* add all rates lower than desired rate */ ++ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) { ++ if (aucSuppRate[i] == 0) ++ break; ++ ++ if (aucSuppRate[i] < aucNewRate[0]) ++ aucNewRate[u4NewRateLen++] = aucSuppRate[i]; ++ } ++ } ++ ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetDesiredRates, &aucNewRate, sizeof(aucNewRate), &u4BufLen); ++ return 0; ++} /* wext_set_rate */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get current tx bit rate. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prRate Pointer to iw_param structure to store current tx rate. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 If netif_carrier_ok. ++* \retval -ENOTCONN Otherwise. ++* ++* \note If netif_carrier_ok, current tx rate is stored in pRate. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_rate(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRate, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ UINT_32 u4Rate = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRate); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (!netif_carrier_ok(prNetDev)) ++ return -ENOTCONN; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prRate->value = u4Rate * 100; /* u4Rate is in unit of 100bps */ ++ prRate->fixed = 0; ++ ++ return 0; ++} /* wext_get_rate */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set RTS/CTS theshold. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prRts Pointer to iw_param structure containing rts threshold. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 For success. ++* \retval -EINVAL Given value is out of range. ++* ++* \note If given value is valid, device will follow the new setting. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_rts(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prRts, IN char *pcExtra) ++{ ++ PARAM_RTS_THRESHOLD u4RtsThresh; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRts); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (prRts->disabled == 1) ++ u4RtsThresh = 2347; ++ else if (prRts->value < 0 || prRts->value > 2347) ++ return -EINVAL; ++ ++ u4RtsThresh = (PARAM_RTS_THRESHOLD) prRts->value; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRtsThreshold, ++ &u4RtsThresh, sizeof(u4RtsThresh), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ prRts->value = (typeof(prRts->value)) u4RtsThresh; ++ prRts->disabled = (prRts->value > 2347) ? 1 : 0; ++ prRts->fixed = 1; ++ ++ return 0; ++} /* wext_set_rts */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get RTS/CTS theshold. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prRts Pointer to iw_param structure containing rts threshold. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note RTS threshold is stored in pRts. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_rts(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRts, IN char *pcExtra) ++{ ++ PARAM_RTS_THRESHOLD u4RtsThresh = 0; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prRts); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryRtsThreshold, ++ &u4RtsThresh, sizeof(u4RtsThresh), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ prRts->value = (typeof(prRts->value)) u4RtsThresh; ++ prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0; ++ prRts->fixed = 1; ++ ++ return 0; ++} /* wext_get_rts */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get fragmentation threshold. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prFrag Pointer to iw_param structure containing frag threshold. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note RTS threshold is stored in pFrag. Fragmentation is disabled. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_frag(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prFrag, IN char *pcExtra) ++{ ++ ASSERT(prFrag); ++ ++ prFrag->value = 2346; ++ prFrag->fixed = 1; ++ prFrag->disabled = 1; ++ return 0; ++} /* wext_get_frag */ ++ ++#if 1 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set TX power, or enable/disable the radio. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prTxPow Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used ++* to enable/disable the radio. ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++static int ++wext_set_txpow(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prTxPow, IN char *pcExtra) ++{ ++ int ret = 0; ++ /* PARAM_DEVICE_POWER_STATE ePowerState; */ ++ ENUM_ACPI_STATE_T ePowerState; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prTxPow); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (prTxPow->disabled) { ++ /* <1> disconnect */ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "######set disassoc failed\n"); ++ else ++ DBGLOG(REQ, TRACE, "######set assoc ok\n"); ++ /* <2> mark to power state flag */ ++ ePowerState = ACPI_STATE_D0; ++ DBGLOG(REQ, INFO, "set to acpi d3(0)\n"); ++ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); ++ ++ } else { ++ ePowerState = ACPI_STATE_D0; ++ DBGLOG(REQ, INFO, "set to acpi d0\n"); ++ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); ++ } ++ ++ prGlueInfo->ePowerState = ePowerState; ++ ++ return ret; ++} /* wext_set_txpow */ ++ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get TX power. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prTxPow Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note Tx power is stored in pTxPow. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_txpow(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prTxPow, IN char *pcExtra) ++{ ++ /* PARAM_DEVICE_POWER_STATE ePowerState; */ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prNetDev); ++ ASSERT(prTxPow); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not ++ * current state. Use GLUE_INFO_T to store state. ++ */ ++ /* ePowerState = prGlueInfo->ePowerState; */ ++ ++ /* TxPow parameters: Fixed at relative 100% */ ++#if WIRELESS_EXT < 17 ++ prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */ ++#else ++ prTxPow->flags = IW_TXPOW_RELATIVE; ++#endif ++ prTxPow->value = 100; ++ prTxPow->fixed = 1; ++ /* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE; */ ++ prTxPow->disabled = TRUE; ++ ++ return 0; ++} /* wext_get_txpow */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prEnc Pointer to iw_point structure containing securiry information. ++* \param[in] pcExtra Buffer to store key content. ++* ++* \retval 0 Success. ++* ++* \note Securiry information is stored in pEnc except key content. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_encode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_point *prEnc, IN char *pcExtra) ++{ ++#if 1 ++ /* ENUM_ENCRYPTION_STATUS_T eEncMode; */ ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode = ENUM_WEP_ENABLED; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEnc); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidQueryEncryptionStatus, ++ &eEncMode, sizeof(eEncMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ switch (eEncMode) { ++ case ENUM_WEP_DISABLED: ++ prEnc->flags = IW_ENCODE_DISABLED; ++ break; ++ case ENUM_WEP_ENABLED: ++ prEnc->flags = IW_ENCODE_ENABLED; ++ break; ++ case ENUM_WEP_KEY_ABSENT: ++ prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; ++ break; ++ default: ++ prEnc->flags = IW_ENCODE_ENABLED; ++ break; ++ } ++ ++ /* Cipher, Key Content, Key ID can't be queried */ ++ prEnc->flags |= IW_ENCODE_NOKEY; ++#endif ++ return 0; ++} /* wext_get_encode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEnc Pointer to iw_point structure containing securiry information. ++* \param[in] pcExtra Pointer to key string buffer. ++* ++* \retval 0 Success. ++* \retval -EINVAL Key ID error for WEP. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_8 wepBuf[48]; ++ ++static int ++wext_set_encode(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) ++{ ++#if 1 ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ /* UINT_8 wepBuf[48]; */ ++ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEnc); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* reset to default mode */ ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++#if CFG_SUPPORT_802_11W ++ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; ++#endif ++ ++ /* iwconfig wlan0 key off */ ++ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { ++ eAuthMode = AUTH_MODE_OPEN; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, ++ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ eEncStatus = ENUM_ENCRYPTION_DISABLED; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ return 0; ++ } ++ ++ /* iwconfig wlan0 key 0123456789 */ ++ /* iwconfig wlan0 key s:abcde */ ++ /* iwconfig wlan0 key 0123456789 [1] */ ++ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ ++ /* check key size for WEP */ ++ if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) { ++ /* prepare PARAM_WEP key structure */ ++ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; ++ if (prWepKey->u4KeyIndex > 3) { ++ /* key id is out of range */ ++ return -EINVAL; ++ } ++ prWepKey->u4KeyIndex |= 0x80000000; ++ prWepKey->u4Length = 12 + prEnc->length; ++ prWepKey->u4KeyLength = prEnc->length; ++ kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddWep, ++ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ /* change to auto switch */ ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; ++ eAuthMode = AUTH_MODE_AUTO_SWITCH; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, ++ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++ ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ ++ eEncStatus = ENUM_WEP_ENABLED; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, ++ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++ ++ return 0; ++ } ++#endif ++ return -EOPNOTSUPP; ++} /* wext_set_encode */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set power management. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prPower Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note New Power Management Mode is set to driver. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_power(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prPower, IN char *pcExtra) ++{ ++#if 1 ++ ++ PARAM_POWER_MODE ePowerMode; ++ INT_32 i4PowerValue; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ ++ /* prPower->value, prPower->disabled, prPower->flags); */ ++ ++ if (prPower->disabled) { ++ ePowerMode = Param_PowerModeCAM; ++ } else { ++ i4PowerValue = prPower->value; ++#if WIRELESS_EXT < 21 ++ i4PowerValue /= 1000000; ++#endif ++ if (i4PowerValue == 0) { ++ ePowerMode = Param_PowerModeCAM; ++ } else if (i4PowerValue == 1) { ++ ePowerMode = Param_PowerModeMAX_PSP; ++ } else if (i4PowerValue == 2) { ++ ePowerMode = Param_PowerModeFast_PSP; ++ } else { ++ DBGLOG(REQ, ERROR, "%s(): unsupported power management mode value = %d.\n", ++ __func__, prPower->value); ++ ++ return -EINVAL; ++ } ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSet802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ ++ return -EFAULT; ++ } ++#endif ++ return 0; ++} /* wext_set_power */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To get power management. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[out] prPower Pointer to iw_param structure containing tx power setting. ++* \param[in] pcExtra NULL. ++* ++* \retval 0 Success. ++* ++* \note Power management mode is stored in pTxPow->value. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_get_power(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prPower, IN char *pcExtra) ++{ ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM; ++ ++ ASSERT(prNetDev); ++ ASSERT(prPower); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++#if 0 ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidQuery802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), TRUE, TRUE, &u4BufLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuery802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), &u4BufLen); ++#endif ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuery802dot11PowerSaveProfile, ++ &ePowerMode, sizeof(ePowerMode), &u4BufLen); ++#endif ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return -EFAULT; ++ ++ prPower->value = 0; ++ prPower->disabled = 1; ++ ++ if (Param_PowerModeCAM == ePowerMode) { ++ prPower->value = 0; ++ prPower->disabled = 1; ++ } else if (Param_PowerModeMAX_PSP == ePowerMode) { ++ prPower->value = 1; ++ prPower->disabled = 0; ++ } else if (Param_PowerModeFast_PSP == ePowerMode) { ++ prPower->value = 2; ++ prPower->disabled = 0; ++ } ++ ++ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; ++#if WIRELESS_EXT < 21 ++ prPower->value *= 1000000; ++#endif ++ ++ /* printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", */ ++ /* prPower->value, prPower->disabled, prPower->flags); */ ++ ++ return 0; ++} /* wext_get_power */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set authentication parameters. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] rpAuth Pointer to iw_param structure containing authentication information. ++* \param[in] pcExtra Pointer to key string buffer. ++* ++* \retval 0 Success. ++* \retval -EINVAL Key ID error for WEP. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++wext_set_auth(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prAuth, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prNetDev); ++ ASSERT(prAuth); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ /* Save information to glue info and process later when ssid is set. */ ++ switch (prAuth->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++#if CFG_SUPPORT_WAPI ++ if (wlanQueryWapiMode(prGlueInfo->prAdapter)) { ++ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; ++ } else { ++ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; ++ } ++#else ++ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; ++#endif ++ break; ++ ++ case IW_AUTH_CIPHER_PAIRWISE: ++ prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value; ++ break; ++ ++ case IW_AUTH_CIPHER_GROUP: ++ prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value; ++ break; ++ ++ case IW_AUTH_KEY_MGMT: ++ prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value; ++#if CFG_SUPPORT_WAPI ++ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK || ++ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) { ++ UINT_32 u4BufLen; ++ WLAN_STATUS rStatus; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiMode, ++ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); ++ } ++#endif ++ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS) ++ prGlueInfo->fgWpsActive = TRUE; ++ else ++ prGlueInfo->fgWpsActive = FALSE; ++ break; ++ ++ case IW_AUTH_80211_AUTH_ALG: ++ prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value; ++ break; ++ ++ case IW_AUTH_PRIVACY_INVOKED: ++ prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value; ++ break; ++#if CFG_SUPPORT_802_11W ++ case IW_AUTH_MFP: ++ /* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */ ++ prGlueInfo->rWpaInfo.u4Mfp = prAuth->value; ++ break; ++#endif ++#if CFG_SUPPORT_WAPI ++ case IW_AUTH_WAPI_ENABLED: ++ { ++ UINT_32 u4BufLen; ++ WLAN_STATUS rStatus; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiMode, ++ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); ++ break; ++#endif ++ default: ++ /* ++ printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags); ++ */ ++ break; ++ } ++ return 0; ++} /* wext_set_auth */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To set encryption cipher and key. ++* ++* \param[in] prDev Net device requested. ++* \param[in] prIwrInfo NULL. ++* \param[in] prEnc Pointer to iw_point structure containing securiry information. ++* \param[in] pcExtra Pointer to key string buffer. ++* ++* \retval 0 Success. ++* \retval -EINVAL Key ID error for WEP. ++* \retval -EFAULT Setting parameters to driver fail. ++* \retval -EOPNOTSUPP Key size not supported. ++* ++* \note Securiry information is stored in pEnc. ++*/ ++/*----------------------------------------------------------------------------*/ ++#if CFG_SUPPORT_WAPI ++UINT_8 keyStructBuf[320]; /* add/remove key shared buffer */ ++#else ++UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ ++#endif ++ ++static int ++wext_set_encode_ext(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) ++{ ++ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; ++ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; ++ ++ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; ++ ++ struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *)pcExtra; ++ ++ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ++ ENUM_PARAM_AUTH_MODE_T eAuthMode; ++ /* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */ ++ ++#if CFG_SUPPORT_WAPI ++ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; ++#endif ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prEnc); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ memset(keyStructBuf, 0, sizeof(keyStructBuf)); ++ ++#if CFG_SUPPORT_WAPI ++ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { ++ if (prEnc->flags & IW_ENCODE_DISABLED) { ++ /* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */ ++ return 0; ++ } ++ /* KeyID */ ++ prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX); ++ prWpiKey->ucKeyID--; ++ if (prWpiKey->ucKeyID > 1) { ++ /* key id is out of range */ ++ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ ++ return -EINVAL; ++ } ++ ++ if (prIWEncExt->key_len != 32) { ++ /* key length not valid */ ++ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ ++ return -EINVAL; ++ } ++ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ ++ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX; ++ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ++ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; ++ prWpiKey->eDirection = ENUM_WPI_RX_TX; ++ } ++ ++ /* PN */ ++ { ++ UINT_32 i; ++ ++ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) ++ prWpiKey->aucPN[i] = prIWEncExt->tx_seq[i]; ++ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) ++ prWpiKey->aucPN[IW_ENCODE_SEQ_MAX_SIZE + i] = prIWEncExt->rx_seq[i]; ++ } ++ ++ /* BSSID */ ++ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6); ++ ++ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); ++ prWpiKey->u4LenWPIEK = 16; ++ ++ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); ++ prWpiKey->u4LenWPICK = 16; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiKey, ++ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* Do nothing */ ++ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ ++ } ++ } else ++#endif ++ { ++ ++ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { ++ prRemoveKey->u4Length = sizeof(*prRemoveKey); ++ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ /* ++ printk("IW_ENCODE_DISABLED: ID:%d, Addr:[ %pM ]\n", ++ prRemoveKey->KeyIndex, prRemoveKey->BSSID); ++ */ ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetRemoveKey, ++ prRemoveKey, prRemoveKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, INFO, "remove key error:%x\n", rStatus); ++ return 0; ++ } ++ /* return 0; */ ++ /* printk ("alg %x\n", prIWEncExt->alg); */ ++ ++ switch (prIWEncExt->alg) { ++ case IW_ENCODE_ALG_NONE: ++ break; ++ case IW_ENCODE_ALG_WEP: ++ /* iwconfig wlan0 key 0123456789 */ ++ /* iwconfig wlan0 key s:abcde */ ++ /* iwconfig wlan0 key 0123456789 [1] */ ++ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ ++ /* check key size for WEP */ ++ if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) { ++ /* prepare PARAM_WEP key structure */ ++ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? ++ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; ++ if (prWepKey->u4KeyIndex > 3) { ++ /* key id is out of range */ ++ return -EINVAL; ++ } ++ prWepKey->u4KeyIndex |= 0x80000000; ++ prWepKey->u4Length = 12 + prIWEncExt->key_len; ++ prWepKey->u4KeyLength = prIWEncExt->key_len; ++ /* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len); */ ++ kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddWep, ++ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ /* change to auto switch */ ++ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; ++ eAuthMode = AUTH_MODE_AUTO_SWITCH; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAuthMode, ++ &eAuthMode, ++ sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetAuthMode fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; ++ ++ eEncStatus = ENUM_WEP_ENABLED; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetEncryptionStatus, ++ &eEncStatus, ++ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), ++ FALSE, FALSE, FALSE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "wlanoidSetEncryptionStatus fail 0x%x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ } else { ++ DBGLOG(REQ, INFO, "key length %x\n", prIWEncExt->key_len); ++ DBGLOG(REQ, INFO, "key error\n"); ++ } ++ ++ break; ++ case IW_ENCODE_ALG_TKIP: ++ case IW_ENCODE_ALG_CCMP: ++#if CFG_SUPPORT_802_11W ++ case IW_ENCODE_ALG_AES_CMAC: ++#endif ++ { ++ ++ /* KeyID */ ++ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? ++ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; ++#if CFG_SUPPORT_802_11W ++ if (prKey->u4KeyIndex > 5) { ++#else ++ if (prKey->u4KeyIndex > 3) { ++#endif ++ DBGLOG(REQ, ERROR, "key index error:0x%x\n", prKey->u4KeyIndex); ++ /* key id is out of range */ ++ return -EINVAL; ++ } ++ ++ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ ++ /* Tx Key Bit(31) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ++ prKey->u4KeyIndex |= 0x1UL << 31; ++ /* Code style */ ++ } ++ /* Pairwise Key Bit(30) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ /* Do nothing */ ++ /* group key */ ++ } else { ++ /* pairwise key */ ++ prKey->u4KeyIndex |= 0x1UL << 30; ++ } ++ } ++ /* Rx SC Bit(29) */ ++ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { ++ prKey->u4KeyIndex |= 0x1UL << 29; ++ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); ++ } ++ ++ /* BSSID */ ++ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); ++ ++ /* switch tx/rx MIC key for sta */ ++ if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) { ++ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16); ++ memcpy(((PUINT_8) prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8); ++ memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8); ++ } else { ++ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); ++ } ++ ++ prKey->u4KeyLength = prIWEncExt->key_len; ++ prKey->u4Length = ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + prKey->u4KeyLength; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetAddKey, ++ prKey, prKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "add key error:%x\n", rStatus); ++ return -EFAULT; ++ } ++ break; ++ } ++ } ++ ++ return 0; ++} /* wext_set_encode_ext */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Set country code ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prData iwreq.u.data carries country code value. ++* ++* \retval 0 For success. ++* \retval -EEFAULT For fail. ++* ++* \note Country code is stored and channel list is updated based on current country domain. ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wext_set_country(IN struct net_device *prNetDev, IN struct iw_point *prData) ++{ ++ P_GLUE_INFO_T prGlueInfo; ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ UINT_8 aucCountry[2]; ++ ++ ASSERT(prNetDev); ++ ++ /* prData->pointer should be like "COUNTRY US", "COUNTRY EU" ++ * and "COUNTRY JP" ++ */ ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prData) || !prData->pointer || prData->length < 10) ++ return -EINVAL; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ aucCountry[0] = *((PUINT_8)prData->pointer + 8); ++ aucCountry[1] = *((PUINT_8)prData->pointer + 9); ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, &aucCountry[0], 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To report the iw private args table to user space. ++* ++* \param[in] prNetDev Net device requested. ++* \param[out] prData iwreq.u.data to carry the private args table. ++* ++* \retval 0 For success. ++* \retval -E2BIG For user's buffer size is too small. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int wext_get_priv(IN struct net_device *prNetDev, OUT struct iw_point *prData) ++{ ++ UINT_16 u2BufferSize = prData->length; ++ ++ /* Update our private args table size */ ++ prData->length = (__u16)sizeof(rIwPrivTable); ++ if (u2BufferSize < prData->length) ++ return -E2BIG; ++ ++ if (prData->length) { ++ if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable))) ++ return -EFAULT; ++ } ++ ++ return 0; ++} /* wext_get_priv */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief ioctl() (Linux Wireless Extensions) routines ++* ++* \param[in] prDev Net device requested. ++* \param[in] ifr The ifreq structure for seeting the wireless extension. ++* \param[in] i4Cmd The wireless extension ioctl command. ++* ++* \retval zero On success. ++* \retval -EOPNOTSUPP If the cmd is not supported. ++* \retval -EFAULT If copy_to_user goes wrong. ++* \retval -EINVAL If any value's out of range. ++* ++* \note ++*/ ++/*----------------------------------------------------------------------------*/ ++int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd) ++{ ++ struct iwreq *iwr = (struct iwreq *)prIfReq; ++ struct iw_request_info rIwReqInfo; ++ int ret = 0; ++ char *prExtraBuf = NULL; ++ UINT_32 u4ExtraSize = 0; ++ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ WLAN_STATUS rStatus; ++ UINT_32 u4BufLen; ++ P_PARAM_PMKID_T prPmkid; ++ ++ /* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */ ++ ++ rIwReqInfo.cmd = (__u16) i4Cmd; ++ rIwReqInfo.flags = 0; ++ ++ switch (i4Cmd) { ++ case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */ ++ ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL); ++ break; ++ ++ /* case SIOCSIWNWID: 0x8B02, deprecated */ ++ /* case SIOCGIWNWID: 0x8B03, deprecated */ ++ ++ case SIOCSIWFREQ: /* 0x8B04, set channel */ ++ ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL); ++ break; ++ ++ case SIOCGIWFREQ: /* 0x8B05, get channel */ ++ ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL); ++ break; ++ ++ case SIOCSIWMODE: /* 0x8B06, set operation mode */ ++ ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL); ++ /* ret = 0; */ ++ break; ++ ++ case SIOCGIWMODE: /* 0x8B07, get operation mode */ ++ ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL); ++ break; ++ ++ /* case SIOCSIWSENS: 0x8B08, unsupported */ ++ /* case SIOCGIWSENS: 0x8B09, unsupported */ ++ ++ /* case SIOCSIWRANGE: 0x8B0A, unused */ ++ case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */ ++ if (iwr->u.data.pointer != NULL) { ++ /* Buffer size should be large enough */ ++ if (iwr->u.data.length < sizeof(struct iw_range)) { ++ ret = -E2BIG; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ /* reset all fields */ ++ memset(prExtraBuf, 0, sizeof(struct iw_range)); ++ iwr->u.data.length = sizeof(struct iw_range); ++ ++ ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf); ++ /* Push up to the caller */ ++ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) ++ ret = -EFAULT; ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range)); ++ prExtraBuf = NULL; ++ } else { ++ ret = -EINVAL; ++ } ++ break; ++ ++ case SIOCSIWPRIV: /* 0x8B0C, set country code */ ++ ret = wext_set_country(prDev, &iwr->u.data); ++ break; ++ ++ case SIOCGIWPRIV: /* 0x8B0D, get private args table */ ++ ret = wext_get_priv(prDev, &iwr->u.data); ++ break; ++ ++ /* case SIOCSIWSTATS: 0x8B0E, unused */ ++ /* case SIOCGIWSTATS: ++ get statistics, intercepted by wireless_process_ioctl() in wireless.c, ++ redirected to dev_iwstats(), dev->get_wireless_stats(). ++ */ ++ /* case SIOCSIWSPY: 0x8B10, unsupported */ ++ /* case SIOCGIWSPY: 0x8B11, unsupported */ ++ /* case SIOCSIWTHRSPY: 0x8B12, unsupported */ ++ /* case SIOCGIWTHRSPY: 0x8B13, unsupported */ ++ ++ case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */ ++ if (iwr->u.ap_addr.sa_data[0] == 0 && ++ iwr->u.ap_addr.sa_data[1] == 0 && ++ iwr->u.ap_addr.sa_data[2] == 0 && ++ iwr->u.ap_addr.sa_data[3] == 0 && ++ iwr->u.ap_addr.sa_data[4] == 0 && iwr->u.ap_addr.sa_data[5] == 0) { ++ /* WPA Supplicant will set 000000000000 in ++ ** wpa_driver_wext_deinit(), do nothing here or disassoc again? ++ */ ++ ret = 0; ++ break; ++ } ++ ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL); ++ ++ break; ++ ++ case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */ ++ ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL); ++ break; ++ ++ case SIOCSIWMLME: /* 0x8B16, request MLME operation */ ++ /* Fixed length structure */ ++ if (iwr->u.data.length != sizeof(struct iw_mlme)) { ++ DBGLOG(REQ, ERROR, "MLME buffer strange:%d\n", iwr->u.data.length); ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (!iwr->u.data.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme))) ++ ret = -EFAULT; ++ else ++ ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf); ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); ++ prExtraBuf = NULL; ++ break; ++ ++ /* case SIOCGIWAPLIST: 0x8B17, deprecated */ ++ case SIOCSIWSCAN: /* 0x8B18, scan request */ ++ if (iwr->u.data.pointer == NULL) ++ ret = wext_set_scan(prDev, NULL, NULL, NULL); ++#if WIRELESS_EXT > 17 ++ else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { ++ prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ if (copy_from_user(prExtraBuf, ((struct iw_scan_req *)(iwr->u.data.pointer))->essid, ++ ((struct iw_scan_req *)(iwr->u.data.pointer))->essid_len)) { ++ ret = -EFAULT; ++ } else { ++ ret = wext_set_scan(prDev, NULL, (union iwreq_data *)&(iwr->u.data), prExtraBuf); ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN); ++ prExtraBuf = NULL; ++ } ++#endif ++ else ++ ret = -EINVAL; ++ break; ++#if 1 ++ case SIOCGIWSCAN: /* 0x8B19, get scan results */ ++ if (!iwr->u.data.pointer || !iwr->u.essid.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ u4ExtraSize = iwr->u.data.length; ++ /* allocate the same size of kernel buffer to store scan results. */ ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ /* iwr->u.data.length may be updated by wext_get_scan() */ ++ ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf); ++ if (ret != 0) { ++ if (ret == -E2BIG) ++ DBGLOG(REQ, WARN, "[wifi] wext_get_scan -E2BIG\n"); ++ } else { ++ /* check updated length is valid */ ++ ASSERT(iwr->u.data.length <= u4ExtraSize); ++ if (iwr->u.data.length > u4ExtraSize) { ++ DBGLOG(REQ, INFO, "Updated result length is larger than allocated (%d > %u)\n", ++ iwr->u.data.length, u4ExtraSize); ++ iwr->u.data.length = u4ExtraSize; ++ } ++ ++ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) ++ ret = -EFAULT; ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ ++ break; ++ ++#endif ++ ++#if 1 ++ case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */ ++ if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) { ++ ret = -E2BIG; ++ break; ++ } ++ if (!iwr->u.essid.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, iwr->u.essid.length)) { ++ ret = -EFAULT; ++ } else { ++ /* Add trailing '\0' for printk */ ++ /* prExtraBuf[iwr->u.essid.length] = 0; */ ++ /* printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length); */ ++ ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); ++ /* printk ("set essid %d\n", ret); */ ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4); ++ prExtraBuf = NULL; ++ break; ++ ++#endif ++ ++ case SIOCGIWESSID: /* 0x8B1B, get SSID */ ++ if (!iwr->u.essid.pointer) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) { ++ DBGLOG(REQ, ERROR, "[wifi] iwr->u.essid.length:%d too small\n", iwr->u.essid.length); ++ ret = -E2BIG; /* let caller try larger buffer */ ++ break; ++ } ++ ++ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ /* iwr->u.essid.length is updated by wext_get_essid() */ ++ ++ ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); ++ if (ret == 0) { ++ if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) ++ ret = -EFAULT; ++ } ++ ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE); ++ prExtraBuf = NULL; ++ ++ break; ++ ++ /* case SIOCSIWNICKN: 0x8B1C, not supported */ ++ /* case SIOCGIWNICKN: 0x8B1D, not supported */ ++ ++ case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */ ++ /* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL); */ ++ break; ++ ++ case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */ ++ ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL); ++ break; ++ ++ case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */ ++ ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL); ++ break; ++ ++ case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */ ++ ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL); ++ break; ++ ++ /* case SIOCSIWFRAG: 0x8B24, unsupported */ ++ case SIOCGIWFRAG: /* 0x8B25, get frag threshold */ ++ ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL); ++ break; ++ ++ case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */ ++ ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL); ++ break; ++ ++ case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */ ++ ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL); ++ break; ++ ++ /* case SIOCSIWRETRY: 0x8B28, unsupported */ ++ /* case SIOCGIWRETRY: 0x8B29, unsupported */ ++ ++#if 1 ++ case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */ ++ /* Only DISABLED case has NULL pointer and length == 0 */ ++ if (iwr->u.encoding.pointer) { ++ if (iwr->u.encoding.length > 16) { ++ ret = -E2BIG; ++ break; ++ } ++ ++ u4ExtraSize = iwr->u.encoding.length; ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) ++ ret = -EFAULT; ++ } else if (iwr->u.encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret == 0) ++ ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf); ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ break; ++ ++ case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */ ++ /* check pointer */ ++ ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL); ++ break; ++ ++ case SIOCSIWPOWER: /* 0x8B2C, set power management */ ++ ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL); ++ break; ++ ++ case SIOCGIWPOWER: /* 0x8B2D, get power management */ ++ ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL); ++ break; ++ ++#if WIRELESS_EXT > 17 ++ case SIOCSIWGENIE: /* 0x8B30, set gen ie */ ++ if (iwr->u.data.pointer == NULL) ++ break; ++ ++ if (0 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) ++ break; ++ ++ /* Fixed length structure */ ++#if CFG_SUPPORT_WAPI ++ if (iwr->u.data.length > 42 /* The max wapi ie buffer */) { ++ ret = -EINVAL; ++ break; ++ } ++#endif ++ u4ExtraSize = iwr->u.data.length; ++ if (u4ExtraSize == 0) ++ break; ++ ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, iwr->u.data.length)) { ++ ret = -EFAULT; ++ } else { ++#if CFG_SUPPORT_WAPI ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWapiAssocInfo, ++ prExtraBuf, ++ u4ExtraSize, FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", ++ rStatus); */ ++#endif ++#if CFG_SUPPORT_WPS2 ++ PUINT_8 prDesiredIE = NULL; ++ ++ if (wextSrchDesiredWPSIE(prExtraBuf, ++ u4ExtraSize, ++ 0xDD, (PUINT_8 *) &prDesiredIE)) { ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetWSCAssocInfo, ++ prDesiredIE, ++ IE_SIZE(prDesiredIE), ++ FALSE, ++ FALSE, TRUE, FALSE, &u4BufLen); ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ /* printk(KERN_INFO "[WSC] set WSC assoc info ++ error:%lx\n", rStatus); */ ++ } ++ } ++#endif ++#if CFG_SUPPORT_WAPI ++ } ++#endif ++ } ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ break; ++ ++ case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */ ++ break; ++ ++#endif ++ ++ case SIOCSIWAUTH: /* 0x8B32, set auth mode params */ ++ ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL); ++ break; ++ ++ /* case SIOCGIWAUTH: 0x8B33, unused? */ ++ case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */ ++ if (iwr->u.encoding.pointer) { ++ u4ExtraSize = iwr->u.encoding.length; ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) ++ ret = -EFAULT; ++ } else if (iwr->u.encoding.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (ret == 0) ++ ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf); ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ break; ++ ++ /* case SIOCGIWENCODEEXT: 0x8B35, unused? */ ++ ++ case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */ ++#if 1 ++ if (iwr->u.data.pointer) { ++ /* Fixed length structure */ ++ if (iwr->u.data.length != sizeof(struct iw_pmksa)) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ u4ExtraSize = sizeof(struct iw_pmksa); ++ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); ++ if (!prExtraBuf) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_pmksa))) { ++ ret = -EFAULT; ++ } else { ++ switch (((struct iw_pmksa *)prExtraBuf)->cmd) { ++ case IW_PMKSA_ADD: ++ /* ++ printk(KERN_INFO "IW_PMKSA_ADD [ %pM ]\n", ++ (((struct iw_pmksa *)pExtraBuf)->bssid.sa_data)); ++ */ ++ prPmkid = ++ (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), ++ VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); ++ ret = -ENOMEM; ++ break; ++ } ++ ++ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); ++ prPmkid->u4BSSIDInfoCount = 1; ++ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, ++ ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data, 6); ++ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, ++ ((struct iw_pmksa *)prExtraBuf)->pmkid, IW_PMKID_LEN); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, ++ prPmkid, ++ sizeof(PARAM_PMKID_T), ++ FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "add pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); ++ break; ++ case IW_PMKSA_REMOVE: ++ /* ++ printk(KERN_INFO "IW_PMKSA_REMOVE [ %pM ]\n", ++ (((struct iw_pmksa *)buf)->bssid.sa_data)); ++ */ ++ break; ++ case IW_PMKSA_FLUSH: ++ /* ++ printk(KERN_INFO "IW_PMKSA_FLUSH\n"); ++ */ ++ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); ++ if (!prPmkid) { ++ DBGLOG(REQ, ERROR, ++ "Can not alloc memory for IW_PMKSA_FLUSH\n"); ++ ret = -ENOMEM; ++ break; ++ } ++ ++ prPmkid->u4Length = 8; ++ prPmkid->u4BSSIDInfoCount = 0; ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetPmkid, ++ prPmkid, ++ sizeof(PARAM_PMKID_T), ++ FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "flush pmkid error:%x\n", rStatus); ++ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); ++ break; ++ default: ++ DBGLOG(REQ, WARN, "UNKNOWN iw_pmksa command:%d\n", ++ ((struct iw_pmksa *)prExtraBuf)->cmd); ++ ret = -EFAULT; ++ break; ++ } ++ } ++ ++ if (prExtraBuf) { ++ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); ++ prExtraBuf = NULL; ++ } ++ } else if (iwr->u.data.length != 0) { ++ ret = -EINVAL; ++ break; ++ } ++#endif ++ break; ++ ++#endif ++ ++ default: ++ /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */ ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ /* printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); */ ++ ++ return ret; ++} /* wext_support_ioctl */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief To send an event (RAW socket pacekt) to user process actively. ++* ++* \param[in] prGlueInfo Glue layer info. ++* \param[in] u4cmd Whcih event command we want to indicate to user process. ++* \param[in] pData Data buffer to be indicated. ++* \param[in] dataLen Available data size in pData. ++* ++* \return (none) ++* ++* \note Event is indicated to upper layer if cmd is supported and data is valid. ++* Using of kernel symbol wireless_send_event(), which is defined in ++* after WE-14 (2.4.20). ++*/ ++/*----------------------------------------------------------------------------*/ ++void ++wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, ++ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4dataLen) ++{ ++ union iwreq_data wrqu; ++ unsigned char *pucExtraInfo = NULL; ++#if WIRELESS_EXT >= 15 ++ unsigned char *pucDesiredIE = NULL; ++ unsigned char aucExtraInfoBuf[200]; ++#endif ++#if WIRELESS_EXT < 18 ++ int i; ++#endif ++ ++ memset(&wrqu, 0, sizeof(wrqu)); ++ ++ switch (u4Cmd) { ++ case SIOCGIWTXPOW: ++ memcpy(&wrqu.power, pucData, u4dataLen); ++ break; ++ case SIOCGIWSCAN: ++ complete_all(&prGlueInfo->rScanComp); ++ break; ++ ++ case SIOCGIWAP: ++ if (pucData) ++ ether_addr_copy((u8 *)&(wrqu.ap_addr.sa_data), pucData); ++ /*memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);*/ ++ else ++ memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN); ++ break; ++ ++ case IWEVASSOCREQIE: ++#if WIRELESS_EXT < 15 ++ /* under WE-15, no suitable Event can be used */ ++ goto skip_indicate_event; ++#else ++ /* do supplicant a favor, parse to the start of WPA/RSN IE */ ++ if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) { ++ /* RSN IE found */ ++ /* Do nothing */ ++#if 0 ++ } else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { ++ /* WPS IE found */ ++ /* Do nothing */ ++#endif ++ } else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { ++ /* WPA IE found */ ++ /* Do nothing*/ ++#if CFG_SUPPORT_WAPI /* Android+ */ ++ } else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) { ++ /* WAPI IE found */ ++ /* printk("wextSrchDesiredWAPIIE!!\n"); */ ++#endif ++ } else { ++ /* no WPA/RSN IE found, skip this event */ ++ goto skip_indicate_event; ++ } ++#if WIRELESS_EXT < 18 ++ /* under WE-18, only IWEVCUSTOM can be used */ ++ u4Cmd = IWEVCUSTOM; ++ pucExtraInfo = aucExtraInfoBuf; ++ pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs="); ++ /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */ ++ /* translate binary string to hex string, requirement of IWEVCUSTOM */ ++ for (i = 0; i < pucDesiredIE[1] + 2; ++i) ++ pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]); ++ pucExtraInfo = aucExtraInfoBuf; ++ wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2; ++#else ++ /* IWEVASSOCREQIE, indicate binary string */ ++ pucExtraInfo = pucDesiredIE; ++ wrqu.data.length = pucDesiredIE[1] + 2; ++#endif ++#endif /* WIRELESS_EXT < 15 */ ++ break; ++ ++ case IWEVMICHAELMICFAILURE: ++#if WIRELESS_EXT < 15 ++ /* under WE-15, no suitable Event can be used */ ++ goto skip_indicate_event; ++#else ++ if (pucData) { ++ P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T) pucData; ++ /* under WE-18, only IWEVCUSTOM can be used */ ++ u4Cmd = IWEVCUSTOM; ++ pucExtraInfo = aucExtraInfoBuf; ++ pucExtraInfo += sprintf(pucExtraInfo, "MLME-MICHAELMICFAILURE.indication "); ++ pucExtraInfo += sprintf(pucExtraInfo, ++ "%s", ++ (pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ? ++ "groupcast " : "unicast "); ++ ++ wrqu.data.length = pucExtraInfo - aucExtraInfoBuf; ++ pucExtraInfo = aucExtraInfoBuf; ++ } ++#endif /* WIRELESS_EXT < 15 */ ++ break; ++ ++ case IWEVPMKIDCAND: ++ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 && ++ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) { ++ ++ /* only used in WPA2 */ ++#if WIRELESS_EXT >= 18 ++ P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T) pucData; ++ ++ struct iw_pmkid_cand rPmkidCand; ++ ++ pucExtraInfo = aucExtraInfoBuf; ++ ++ rPmkidCand.flags = prPmkidCand->u4Flags; ++ rPmkidCand.index = 0; ++ rPmkidCand.bssid.sa_family = 0; ++ kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6); ++ ++ kalMemCopy(pucExtraInfo, (PUINT_8) &rPmkidCand, sizeof(struct iw_pmkid_cand)); ++ wrqu.data.length = sizeof(struct iw_pmkid_cand); ++ ++ /* pmkid canadidate list is supported after WE-18 */ ++ /* indicate struct iw_pmkid_cand */ ++#else ++ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */ ++ goto skip_indicate_event; ++#endif ++ } else { ++ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */ ++ goto skip_indicate_event; ++ } ++ break; ++ ++ case IWEVCUSTOM: ++ u4Cmd = IWEVCUSTOM; ++ pucExtraInfo = aucExtraInfoBuf; ++ kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T)); ++ wrqu.data.length = sizeof(PTA_IPC_T); ++ break; ++ ++ default: ++ /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */ ++ goto skip_indicate_event; ++ } ++ ++ /* Send event to user space */ ++ wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo); ++ ++skip_indicate_event: ++ return; ++} /* wext_indicate_wext_event */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief A method of struct net_device, to get the network interface statistical ++* information. ++* ++* Whenever an application needs to get statistics for the interface, this method ++* is called. This happens, for example, when ifconfig or netstat -i is run. ++* ++* \param[in] pDev Pointer to struct net_device. ++* ++* \return net_device_stats buffer pointer. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev) ++{ ++ ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ struct iw_statistics *pStats = NULL; ++ INT_32 i4Rssi; ++ UINT_32 bufLen = 0; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) ++ goto stat_out; ++ ++ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); ++ ++ if (!prDev || !netif_carrier_ok(prDev)) { ++ /* network not connected */ ++ goto stat_out; ++ } ++ ++ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, FALSE, &bufLen); ++ ++stat_out: ++ return pStats; ++} /* wlan_get_wireless_stats */ ++ ++ ++#endif /* WIRELESS_EXT */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c +new file mode 100644 +index 000000000000..2b6c3df84594 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c +@@ -0,0 +1,3142 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext_priv.c#4 ++*/ ++ ++/*! \file gl_wext_priv.c ++ \brief This file includes private ioctl support. ++*/ ++ ++/* ++** Log: gl_wext_priv.c ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Let netdev bring up. ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 03 20 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * [WCXRP00001202] [MT6628 Wi-Fi][FW] Adding the New PN init code ++ * use return to avoid the ioctl return not supported ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 01 16 2012 wh.su ++ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl ++ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 11 02 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Fixed typo. ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 07 28 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings ++ * Add BWCS cmd and event. ++ * ++ * 07 18 2011 chinghwa.yu ++ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm ++ * Add CMD/Event for RDD and BWCS. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 01 27 2011 cm.chang ++ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default ++ * . ++ * ++ * 01 26 2011 wh.su ++ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux ++ * adding the SW cmd ioctl support, use set/get structure ioctl. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Adjust OID order. ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 07 2011 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add a new compiling option to control if MCR read/write is permitted ++ * ++ * 12 31 2010 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add some iwpriv commands to support test mode operation ++ * ++ * 12 15 2010 george.huang ++ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function ++ * Support set PS profile and set WMM-PS related iwpriv. ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 24 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * correct typo for NVRAM access. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * enable OID_CUSTOM_MTK_WIFI_TEST for RFTest & META tool ++ * ++ * 05 29 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * fix private ioctl for rftest ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++** \main\maintrunk.MT5921\32 2009-10-08 10:33:25 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input ++** parameters and pointers. ++** \main\maintrunk.MT5921\31 2009-09-29 16:46:21 GMT mtk01090 ++** Remove unused functions ++** \main\maintrunk.MT5921\30 2009-09-29 14:46:47 GMT mtk01090 ++** Fix compile warning ++** \main\maintrunk.MT5921\29 2009-09-29 14:28:48 GMT mtk01090 ++** Fix compile warning ++** \main\maintrunk.MT5921\28 2009-09-28 22:21:38 GMT mtk01090 ++** Refine lines to suppress compile warning ++** \main\maintrunk.MT5921\27 2009-09-28 20:19:14 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\26 2009-08-18 22:56:53 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\25 2009-05-07 22:26:15 GMT mtk01089 ++** Add mandatory and private IO control for Linux BWCS ++** \main\maintrunk.MT5921\24 2009-04-29 10:07:05 GMT mtk01088 ++** fixed the compiling error at linux ++** \main\maintrunk.MT5921\23 2009-04-24 09:09:45 GMT mtk01088 ++** mark the code not used at linux supplicant v0.6.7 ++** \main\maintrunk.MT5921\22 2008-11-24 21:03:51 GMT mtk01425 ++** 1. Add PTA_ENABLED flag ++** \main\maintrunk.MT5921\21 2008-08-29 14:55:59 GMT mtk01088 ++** adjust the code for meet the coding style, and add assert check ++** \main\maintrunk.MT5921\20 2008-07-16 15:23:20 GMT mtk01104 ++** Support GPIO2 mode ++** \main\maintrunk.MT5921\19 2008-07-15 17:43:11 GMT mtk01084 ++** modify variable name ++** \main\maintrunk.MT5921\18 2008-07-14 14:37:58 GMT mtk01104 ++** Add exception handle about length in function priv_set_struct() ++** \main\maintrunk.MT5921\17 2008-07-14 13:55:32 GMT mtk01104 ++** Support PRIV_CMD_BT_COEXIST ++** \main\maintrunk.MT5921\16 2008-07-09 00:20:15 GMT mtk01461 ++** Add priv oid to support WMM_PS_TEST ++** \main\maintrunk.MT5921\15 2008-06-02 11:15:22 GMT mtk01461 ++** Update after wlanoidSetPowerMode changed ++** \main\maintrunk.MT5921\14 2008-05-30 19:31:07 GMT mtk01461 ++** Add IOCTL for Power Mode ++** \main\maintrunk.MT5921\13 2008-05-30 18:57:15 GMT mtk01461 ++** Not use wlanoidSetCSUMOffloadForLinux() ++** \main\maintrunk.MT5921\12 2008-05-30 15:13:18 GMT mtk01084 ++** rename wlanoid ++** \main\maintrunk.MT5921\11 2008-05-29 14:16:31 GMT mtk01084 ++** rename for wlanoidSetBeaconIntervalForLinux ++** \main\maintrunk.MT5921\10 2008-04-17 23:06:37 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\9 2008-03-31 21:00:55 GMT mtk01461 ++** Add priv IOCTL for VOIP setting ++** \main\maintrunk.MT5921\8 2008-03-31 13:49:43 GMT mtk01461 ++** Add priv ioctl to turn on / off roaming ++** \main\maintrunk.MT5921\7 2008-03-26 15:35:14 GMT mtk01461 ++** Add CSUM offload priv ioctl for Linux ++** \main\maintrunk.MT5921\6 2008-03-11 14:50:59 GMT mtk01461 ++** Unify priv ioctl ++** \main\maintrunk.MT5921\5 2007-11-06 19:32:30 GMT mtk01088 ++** add WPS code ++** \main\maintrunk.MT5921\4 2007-10-30 12:01:39 GMT MTK01425 ++** 1. Update wlanQueryInformation and wlanSetInformation ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "precomp.h" ++ ++#include "gl_os.h" ++#include "gl_wext_priv.h" ++#if CFG_SUPPORT_WAPI ++#include "gl_sec.h" ++#endif ++#if CFG_ENABLE_WIFI_DIRECT ++#include "gl_p2p_os.h" ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY)) ++#define CMD_START "START" ++#define CMD_STOP "STOP" ++#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" ++#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" ++#define CMD_RSSI "RSSI" ++#define CMD_LINKSPEED "LINKSPEED" ++#define CMD_RXFILTER_START "RXFILTER-START" ++#define CMD_RXFILTER_STOP "RXFILTER-STOP" ++#define CMD_RXFILTER_ADD "RXFILTER-ADD" ++#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" ++#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" ++#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" ++#define CMD_BTCOEXMODE "BTCOEXMODE" ++#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" ++#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" ++#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" ++#define CMD_SETFWPATH "SETFWPATH" ++#define CMD_SETBAND "SETBAND" ++#define CMD_GETBAND "GETBAND" ++#define CMD_COUNTRY "COUNTRY" ++#define CMD_P2P_SET_NOA "P2P_SET_NOA" ++#define CMD_P2P_GET_NOA "P2P_GET_NOA" ++#define CMD_P2P_SET_PS "P2P_SET_PS" ++#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" ++#define CMD_SETROAMMODE "SETROAMMODE" ++#define CMD_MIRACAST "MIRACAST" ++ ++#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" ++#define CMD_PNOSETUP_SET "PNOSETUP " ++#define CMD_PNOENABLE_SET "PNOFORCE" ++#define CMD_PNODEBUG_SET "PNODEBUG" ++#define CMD_WLS_BATCHING "WLS_BATCHING" ++ ++#define CMD_OKC_SET_PMK "SET_PMK" ++#define CMD_OKC_ENABLE "OKC_ENABLE" ++ ++/* miracast related definition */ ++#define MIRACAST_MODE_OFF 0 ++#define MIRACAST_MODE_SOURCE 1 ++#define MIRACAST_MODE_SINK 2 ++ ++#ifndef MIRACAST_AMPDU_SIZE ++#define MIRACAST_AMPDU_SIZE 8 ++#endif ++ ++#ifndef MIRACAST_MCHAN_ALGO ++#define MIRACAST_MCHAN_ALGO 1 ++#endif ++ ++#ifndef MIRACAST_MCHAN_BW ++#define MIRACAST_MCHAN_BW 25 ++#endif ++ ++#define CMD_BAND_AUTO 0 ++#define CMD_BAND_5G 1 ++#define CMD_BAND_2G 2 ++#define CMD_BAND_ALL 3 ++ ++/* Mediatek private command */ ++ ++#define CMD_SET_SW_CTRL "SET_SW_CTRL" ++#define CMD_GET_SW_CTRL "GET_SW_CTRL" ++#define CMD_SET_CFG "SET_CFG" ++#define CMD_GET_CFG "GET_CFG" ++#define CMD_SET_CHIP "SET_CHIP" ++#define CMD_GET_CHIP "GET_CHIP" ++#define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL" ++#define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL" ++#define PRIV_CMD_SIZE 512 ++ ++static UINT_32 g_ucMiracastMode = MIRACAST_MODE_OFF; ++ ++typedef struct cmd_tlv { ++ char prefix; ++ char version; ++ char subver; ++ char reserved; ++} cmd_tlv_t; ++ ++typedef struct priv_driver_cmd_s { ++ char buf[PRIV_CMD_SIZE]; ++ int used_len; ++ int total_len; ++} priv_driver_cmd_t; ++ ++#if CFG_SUPPORT_BATCH_SCAN ++#define CMD_BATCH_SET "WLS_BATCHING SET" ++#define CMD_BATCH_GET "WLS_BATCHING GET" ++#define CMD_BATCH_STOP "WLS_BATCHING STOP" ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static int ++priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); ++ ++static int ++priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); ++ ++#if 0 /* CFG_SUPPORT_WPS */ ++static int ++priv_set_appie(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); ++ ++static int ++priv_set_filter(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); ++#endif /* CFG_SUPPORT_WPS */ ++ ++static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY * ppWlanReqEntry); ++ ++#if 0 ++static WLAN_STATUS ++reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++static WLAN_STATUS ++reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++#endif ++ ++static WLAN_STATUS ++reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++static UINT_8 aucOidBuf[4096] = { 0 }; ++ ++/* OID processing table */ ++/* Order is important here because the OIDs should be in order of ++ increasing value for binary searching. */ ++static WLAN_REQ_ENTRY arWlanOidReqTable[] = { ++ /* ++ {(NDIS_OID)rOid, ++ (PUINT_8)pucOidName, ++ fgQryBufLenChecking, fgSetBufLenChecking, fgIsHandleInGlueLayerOnly, u4InfoBufLen, ++ pfOidQueryHandler, ++ pfOidSetHandler} ++ */ ++ /* General Operational Characteristics */ ++ ++ /* Ethernet Operational Characteristics */ ++ {OID_802_3_CURRENT_ADDRESS, ++ DISP_STRING("OID_802_3_CURRENT_ADDRESS"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr, ++ NULL}, ++ ++ /* OID_802_3_MULTICAST_LIST */ ++ /* OID_802_3_MAXIMUM_LIST_SIZE */ ++ /* Ethernet Statistics */ ++ ++ /* NDIS 802.11 Wireless LAN OIDs */ ++ {OID_802_11_SUPPORTED_RATES, ++ DISP_STRING("OID_802_11_SUPPORTED_RATES"), ++ TRUE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_RATES_EX), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates, ++ NULL} ++ , ++ /* ++ {OID_802_11_CONFIGURATION, ++ DISP_STRING("OID_802_11_CONFIGURATION"), ++ TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_802_11_CONFIG_T), ++ (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration, ++ (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration}, ++ */ ++ {OID_PNP_SET_POWER, ++ DISP_STRING("OID_PNP_SET_POWER"), ++ TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_DEVICE_POWER_STATE), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState} ++ , ++ ++ /* Custom OIDs */ ++ {OID_CUSTOM_OID_INTERFACE_VERSION, ++ DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"), ++ TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion, ++ NULL} ++ , ++ ++ /* ++ #if PTA_ENABLED ++ {OID_CUSTOM_BT_COEXIST_CTRL, ++ DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_BT_COEXIST_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl}, ++ #endif ++ */ ++ ++ /* ++ {OID_CUSTOM_POWER_MANAGEMENT_PROFILE, ++ DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam}, ++ {OID_CUSTOM_PATTERN_CONFIG, ++ DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUCT_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig}, ++ {OID_CUSTOM_BG_SSID_SEARCH_CONFIG, ++ DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam}, ++ {OID_CUSTOM_VOIP_SETUP, ++ DISP_STRING("OID_CUSTOM_VOIP_SETUP"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus}, ++ {OID_CUSTOM_ADD_TS, ++ DISP_STRING("OID_CUSTOM_ADD_TS"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS}, ++ {OID_CUSTOM_DEL_TS, ++ DISP_STRING("OID_CUSTOM_DEL_TS"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS}, ++ */ ++ ++ /* ++ #if CFG_LP_PATTERN_SEARCH_SLT ++ {OID_CUSTOM_SLT, ++ DISP_STRING("OID_CUSTOM_SLT"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode}, ++ #endif ++ ++ {OID_CUSTOM_ROAMING_EN, ++ DISP_STRING("OID_CUSTOM_ROAMING_EN"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction}, ++ {OID_CUSTOM_WMM_PS_TEST, ++ DISP_STRING("OID_CUSTOM_WMM_PS_TEST"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest}, ++ {OID_CUSTOM_COUNTRY_STRING, ++ DISP_STRING("OID_CUSTOM_COUNTRY_STRING"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry}, ++ ++ #if CFG_SUPPORT_802_11D ++ {OID_CUSTOM_MULTI_DOMAIN_CAPABILITY, ++ DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap}, ++ #endif ++ ++ {OID_CUSTOM_GPIO2_MODE, ++ DISP_STRING("OID_CUSTOM_GPIO2_MODE"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_PARAM_GPIO2_MODE_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode}, ++ {OID_CUSTOM_CONTINUOUS_POLL, ++ DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CONTINUOUS_POLL_T), ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile}, ++ {OID_CUSTOM_DISABLE_BEACON_DETECTION, ++ DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryDisableBeaconDetectionFunc, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc}, ++ */ ++ ++ /* WPS */ ++ /* ++ {OID_CUSTOM_DISABLE_PRIVACY_CHECK, ++ DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck}, ++ */ ++ ++ {OID_CUSTOM_MCR_RW, ++ DISP_STRING("OID_CUSTOM_MCR_RW"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite} ++ , ++ ++ {OID_CUSTOM_EEPROM_RW, ++ DISP_STRING("OID_CUSTOM_EEPROM_RW"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite} ++ , ++ ++ {OID_CUSTOM_SW_CTRL, ++ DISP_STRING("OID_CUSTOM_SW_CTRL"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite} ++ , ++ ++ {OID_CUSTOM_MEM_DUMP, ++ DISP_STRING("OID_CUSTOM_MEM_DUMP"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MEM_DUMP_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump, ++ NULL} ++ , ++ ++ {OID_CUSTOM_TEST_MODE, ++ DISP_STRING("OID_CUSTOM_TEST_MODE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode} ++ , ++ ++ /* ++ {OID_CUSTOM_TEST_RX_STATUS, ++ DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus, ++ NULL}, ++ {OID_CUSTOM_TEST_TX_STATUS, ++ DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus, ++ NULL}, ++ */ ++ {OID_CUSTOM_ABORT_TEST_MODE, ++ DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode} ++ , ++ {OID_CUSTOM_MTK_WIFI_TEST, ++ DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest} ++ , ++ ++ /* OID_CUSTOM_EMULATION_VERSION_CONTROL */ ++ ++ /* BWCS */ ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS ++ {OID_CUSTOM_BWCS_CMD, ++ DISP_STRING("OID_CUSTOM_BWCS_CMD"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PTA_IPC_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT} ++ , ++#endif ++ ++/* {OID_CUSTOM_SINGLE_ANTENNA, ++ DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna}, ++ {OID_CUSTOM_SET_PTA, ++ DISP_STRING("OID_CUSTOM_SET_PTA"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta, ++ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta}, ++ */ ++ ++ {OID_CUSTOM_MTK_NVRAM_RW, ++ DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"), ++ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite} ++ , ++ ++ {OID_CUSTOM_CFG_SRC_TYPE, ++ DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_CFG_SRC_TYPE_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType, ++ NULL} ++ , ++ ++ {OID_CUSTOM_EEPROM_TYPE, ++ DISP_STRING("OID_CUSTOM_EEPROM_TYPE"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_EEPROM_TYPE_T), ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType, ++ NULL} ++ , ++ ++#if CFG_SUPPORT_WAPI ++ {OID_802_11_WAPI_MODE, ++ DISP_STRING("OID_802_11_WAPI_MODE"), ++ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode} ++ , ++ {OID_802_11_WAPI_ASSOC_INFO, ++ DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo} ++ , ++ {OID_802_11_SET_WAPI_KEY, ++ DISP_STRING("OID_802_11_SET_WAPI_KEY"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_WPI_KEY_T), ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey} ++ , ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++ {OID_802_11_WSC_ASSOC_INFO, ++ DISP_STRING("OID_802_11_WSC_ASSOC_INFO"), ++ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, ++ NULL, ++ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWSCAssocInfo} ++ , ++#endif ++}; ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~ ++* SIOCIWLASTPRIV). ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIfReq Pointer to ifreq structure. ++* \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV. ++* ++* \retval 0 for success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++int priv_support_ioctl(IN struct net_device *prNetDev, IN OUT struct ifreq *prIfReq, IN int i4Cmd) ++{ ++ /* prIfReq is verified in the caller function wlanDoIOCTL() */ ++ struct iwreq *prIwReq = (struct iwreq *)prIfReq; ++ struct iw_request_info rIwReqInfo; ++ ++ /* prDev is verified in the caller function wlanDoIOCTL() */ ++ ++ /* Prepare the call */ ++ rIwReqInfo.cmd = (__u16) i4Cmd; ++ rIwReqInfo.flags = 0; ++ ++ switch (i4Cmd) { ++ case IOCTL_SET_INT: ++ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ ++ return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); ++ ++ case IOCTL_GET_INT: ++ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ ++ return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); ++ ++ case IOCTL_SET_STRUCT: ++ case IOCTL_SET_STRUCT_FOR_EM: ++ return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); ++ ++ case IOCTL_GET_STRUCT: ++ return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); ++ ++ default: ++ return -EOPNOTSUPP; ++ ++ } /* end of switch */ ++ ++} /* priv_support_ioctl */ ++ ++#if CFG_SUPPORT_BATCH_SCAN ++ ++EVENT_BATCH_RESULT_T g_rEventBatchResult[CFG_BATCH_MAX_MSCAN]; ++ ++UINT_32 batchChannelNum2Freq(UINT_32 u4ChannelNum) ++{ ++ UINT_32 u4ChannelInMHz; ++ ++ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) ++ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; ++ else if (u4ChannelNum == 14) ++ u4ChannelInMHz = 2484; ++ else if (u4ChannelNum == 133) ++ u4ChannelInMHz = 3665; /* 802.11y */ ++ else if (u4ChannelNum == 137) ++ u4ChannelInMHz = 3685; /* 802.11y */ ++ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) ++ u4ChannelInMHz = 5000 + u4ChannelNum * 5; ++ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) ++ u4ChannelInMHz = 4000 + u4ChannelNum * 5; ++ else ++ u4ChannelInMHz = 0; ++ ++ return u4ChannelInMHz; ++} ++ ++#define TMP_TEXT_LEN_S 40 ++#define TMP_TEXT_LEN_L 60 ++static UCHAR text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], text3[TMP_TEXT_LEN_L]; /* A safe len */ ++ ++WLAN_STATUS ++batchConvertResult(IN P_EVENT_BATCH_RESULT_T prEventBatchResult, ++ OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) ++{ ++ CHAR *p = pvBuffer; ++ CHAR ssid[ELEM_MAX_LEN_SSID + 1]; ++ INT_32 nsize = 0, nsize1, nsize2, nsize3, scancount; ++ INT_32 i, j, nleft; ++ UINT_32 freq; ++ ++ P_EVENT_BATCH_RESULT_ENTRY_T prEntry; ++ P_EVENT_BATCH_RESULT_T pBr; ++ ++ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ ++ ++ pBr = prEventBatchResult; ++ scancount = 0; ++ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { ++ scancount += pBr->ucScanCount; ++ pBr++; ++ } ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "scancount=%x\nnextcount=%x\n", scancount, scancount); ++ if (nsize1 < nleft) { ++ p += nsize1 = kalSprintf(p, "%s", text1); ++ nleft -= nsize1; ++ } else ++ goto short_buf; ++ ++ pBr = prEventBatchResult; ++ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { ++ DBGLOG(SCN, TRACE, "convert mscan = %d, apcount=%d, nleft=%d\n", j, pBr->ucScanCount, nleft); ++ ++ if (pBr->ucScanCount == 0) { ++ pBr++; ++ continue; ++ } ++ ++ nleft -= 5; /* -5 for "####\n" */ ++ ++ /* We only support one round scan result now. */ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", pBr->ucScanCount); ++ if (nsize1 < nleft) { ++ p += nsize1 = kalSprintf(p, "%s", text1); ++ nleft -= nsize1; ++ } else ++ goto short_buf; ++ ++ for (i = 0; i < pBr->ucScanCount; i++) { ++ prEntry = &pBr->arBatchResult[i]; ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "bssid=" MACSTR "\n", ++ prEntry->aucBssid[0], ++ prEntry->aucBssid[1], ++ prEntry->aucBssid[2], ++ prEntry->aucBssid[3], ++ prEntry->aucBssid[4], prEntry->aucBssid[5]); ++ ++ kalMemCopy(ssid, ++ prEntry->aucSSID, ++ (prEntry->ucSSIDLen < ELEM_MAX_LEN_SSID ? prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID)); ++ ssid[(prEntry->ucSSIDLen < ++ (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : (ELEM_MAX_LEN_SSID - 1))] = '\0'; ++ nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", ssid); ++ ++ freq = batchChannelNum2Freq(prEntry->ucFreq); ++ nsize3 = ++ kalSnprintf(text3, TMP_TEXT_LEN_L, ++ "freq=%u\nlevel=%d\ndist=%u\ndistSd=%u\n====\n", freq, ++ prEntry->cRssi, prEntry->u4Dist, prEntry->u4Distsd); ++ ++ nsize = nsize1 + nsize2 + nsize3; ++ if (nsize < nleft) { ++ ++ kalStrnCpy(p, text1, TMP_TEXT_LEN_S); ++ p += nsize1; ++ ++ kalStrnCpy(p, text2, TMP_TEXT_LEN_L); ++ p += nsize2; ++ ++ kalStrnCpy(p, text3, TMP_TEXT_LEN_L); ++ p += nsize3; ++ ++ nleft -= nsize; ++ } else { ++ DBGLOG(SCN, TRACE, "Warning: Early break! (%d)\n", i); ++ break; /* discard following entries, TODO: apcount? */ ++ } ++ } ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n"); ++ p += kalSprintf(p, "%s", text1); ++ ++ pBr++; ++ } ++ ++ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n"); ++ kalSprintf(p, "%s", text1); ++ ++ *pu4RetLen = u4MaxBufferLen - nleft; ++ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++short_buf: ++ DBGLOG(SCN, TRACE, ++ "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), ++ u4MaxBufferLen, (char *)pvBuffer); ++ return WLAN_STATUS_INVALID_LENGTH; ++} ++#endif ++ ++#if CFG_SUPPORT_GET_CH_ENV ++WLAN_STATUS ++scanEnvResult(P_GLUE_INFO_T prGlueInfo, OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ CHAR *p = pvBuffer; ++ INT_32 nsize; ++ INT_32 i, nleft; ++ P_SCAN_INFO_T prScanInfo; ++ P_LINK_T prBSSDescList; ++ P_BSS_DESC_T prBssDesc; ++ CH_ENV_T chEnvInfo[54]; /* 54: from FW define; TODO: sync MAXIMUM_OPERATION_CHANNEL_LIST */ ++ UINT_32 i4GetCh = 0; ++ INT_32 i4Argc = 0; ++ PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; ++ UINT_8 ucTextLen = 40; ++ UCHAR text[ucTextLen]; ++ INT_32 u4Ret; ++ ++ prAdapter = prGlueInfo->prAdapter; ++ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); ++ prBSSDescList = &prScanInfo->rBSSDescList; ++ ++ kalMemZero(chEnvInfo, sizeof(chEnvInfo)); ++ ++ DBGLOG(SCN, TRACE, "pvBuffer:%s, pu4RetLen:%d\n", (char *)pvBuffer, *pu4RetLen); ++ ++ wlanCfgParseArgument(pvBuffer, &i4Argc, apcArgv); ++ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); ++ ++ if (i4Argc >= 2) { ++ u4Ret = kalkStrtou32(apcArgv[1], 0, &i4GetCh); ++ if (u4Ret) ++ DBGLOG(SCN, TRACE, "parse pvBuffer error u4Ret=%d\n", u4Ret); ++ /* i4GetCh = kalStrtoul(apcArgv[1], NULL, 0); */ ++ } ++ ++ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ ++ ++ nsize = kalSnprintf(text, ucTextLen, "%s", "scanEnvResult\nResult:1\n");/* Always return 1 for alpha version. */ ++ ++ if (nsize < nleft) { ++ p += nsize = kalSnprintf(p, ucTextLen, "%s", text); ++ nleft -= nsize; ++ } else ++ goto short_buf; ++ ++ /* Search BSS Desc from current SCAN result list. */ ++ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { ++ if (prBssDesc->ucChannelNum > 0) { ++ if (prBssDesc->ucChannelNum <= 14) { /* 1~14 */ ++ chEnvInfo[prBssDesc->ucChannelNum - 1].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum - 1].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 64) { /* 15~22 */ ++ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 116) { /* 23~27 */ ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 140) { /* 28~30 */ ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucApNum++; ++ } else if (prBssDesc->ucChannelNum <= 165) { /* 31~35 */ ++ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucChNum = prBssDesc->ucChannelNum; ++ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucApNum++; ++ } ++ } ++ } ++ ++ for (i = 0; i < 54; i++) { ++ if (chEnvInfo[i].ucChNum != 0) { ++ if (i4GetCh == 0 || (chEnvInfo[i].ucChNum == (UINT_8)i4GetCh)) { ++ DBGLOG(SCN, TRACE, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, chEnvInfo[i].ucApNum); ++ p += nsize = ++ kalSnprintf(p, ucTextLen, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, ++ chEnvInfo[i].ucApNum); ++ nleft -= nsize; ++ } ++ } ++ } ++ ++ p += nsize = kalSnprintf(p, ucTextLen, "%s", "----\n"); ++ nleft -= nsize; ++ ++ *pu4RetLen = u4MaxBufferLen - nleft; ++ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); ++ ++ return WLAN_STATUS_SUCCESS; ++ ++short_buf: ++ DBGLOG(SCN, TRACE, "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), u4MaxBufferLen, p); ++ return WLAN_STATUS_INVALID_LENGTH; ++} ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl set int handler. ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIwReqInfo Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. ++* \param[in] pcExtra The buffer with input value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL If a value is out of range. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ UINT_32 u4SubCmd; ++ PUINT_32 pu4IntBuf; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4BufLen = 0; ++ int status = 0; ++ P_PTA_IPC_T prPtaIpc; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->mode; ++ pu4IntBuf = (PUINT_32) pcExtra; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_TEST_MODE: ++ /* printk("TestMode=%ld\n", pu4IntBuf[1]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) { ++ prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE; ++ } else if (pu4IntBuf[1] == 0) { ++ prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE; ++ } else { ++ status = 0; ++ break; ++ } ++ prNdisReq->inNdisOidlength = 0; ++ prNdisReq->outNdisOidLength = 0; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++ case PRIV_CMD_TEST_CMD: ++ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++#if CFG_SUPPORT_PRIV_MCR_RW ++ case PRIV_CMD_ACCESS_MCR: ++ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (!prGlueInfo->fgMcrAccessAllowed) { ++ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) ++ prGlueInfo->fgMcrAccessAllowed = TRUE; ++ status = 0; ++ break; ++ } ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++#endif ++ ++ case PRIV_CMD_SW_CTRL: ++ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++#if 0 ++ case PRIV_CMD_BEACON_PERIOD: ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBeaconInterval, ++ (PVOID)&pu4IntBuf[1],/* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(UINT_32), &u4BufLen); ++ break; ++#endif ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++ case PRIV_CMD_CSUM_OFFLOAD: ++ { ++ UINT_32 u4CSUMFlags; ++ ++ if (pu4IntBuf[1] == 1) ++ u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; ++ else if (pu4IntBuf[1] == 0) ++ u4CSUMFlags = 0; ++ else ++ return -EINVAL; ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidSetCSUMOffload, ++ (PVOID)&u4CSUMFlags, ++ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { ++ if (pu4IntBuf[1] == 1) ++ prNetDev->features |= NETIF_F_HW_CSUM; ++ else if (pu4IntBuf[1] == 0) ++ prNetDev->features &= ~NETIF_F_HW_CSUM; ++ } ++ } ++ break; ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++ case PRIV_CMD_POWER_MODE: ++ kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, ++ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ break; ++ ++ case PRIV_CMD_WMM_PS: ++ { ++ PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T rWmmPsTest; ++ ++ rWmmPsTest.bmfgApsdEnAc = (UINT_8) pu4IntBuf[1]; ++ rWmmPsTest.ucIsEnterPsAtOnce = (UINT_8) pu4IntBuf[2]; ++ rWmmPsTest.ucIsDisableUcTrigger = (UINT_8) pu4IntBuf[3]; ++ rWmmPsTest.reserved = 0; ++ ++ kalIoctl(prGlueInfo, ++ wlanoidSetWiFiWmmPsTest, ++ (PVOID)&rWmmPsTest, ++ sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ } ++ break; ++ ++#if 0 ++ case PRIV_CMD_ADHOC_MODE: ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetAdHocMode, ++ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(UINT_32), &u4BufLen); ++ break; ++#endif ++ ++ case PRIV_CUSTOM_BWCS_CMD: ++ ++ DBGLOG(REQ, INFO, "pu4IntBuf[1] = %x, size of PTA_IPC_T = %zu.\n", ++ pu4IntBuf[1], sizeof(PARAM_PTA_IPC_T)); ++ ++ prPtaIpc = (P_PTA_IPC_T) aucOidBuf; ++ prPtaIpc->u.aucBTPParams[0] = (UINT_8) (pu4IntBuf[1] >> 24); ++ prPtaIpc->u.aucBTPParams[1] = (UINT_8) (pu4IntBuf[1] >> 16); ++ prPtaIpc->u.aucBTPParams[2] = (UINT_8) (pu4IntBuf[1] >> 8); ++ prPtaIpc->u.aucBTPParams[3] = (UINT_8) (pu4IntBuf[1]); ++ ++ DBGLOG(REQ, INFO, ++ "BCM BWCS CMD : BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", ++ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], ++ prPtaIpc->u.aucBTPParams[3]); ++ ++#if 0 ++ status = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++#endif ++ ++ status = wlanoidSetBT(prGlueInfo->prAdapter, ++ (PVOID)&aucOidBuf[0], sizeof(PARAM_PTA_IPC_T), &u4BufLen); ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ status = -EFAULT; ++ ++ break; ++ ++ case PRIV_CMD_BAND_CONFIG: ++ { ++ DBGLOG(REQ, INFO, "CMD set_band=%u\n", (UINT_32) pu4IntBuf[1]); ++ } ++ break; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ case PRIV_CMD_P2P_MODE: ++ { ++ /* no use, move to set_p2p_mode_handler() */ ++ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; ++ ++ p2pmode.u4Enable = pu4IntBuf[1]; ++ p2pmode.u4Mode = pu4IntBuf[2]; ++ set_p2p_mode_handler(prNetDev, p2pmode); ++#if 0 ++ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; ++ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; ++ BOOLEAN fgIsP2PEnding; ++ ++ GLUE_SPIN_LOCK_DECLARATION(); ++ ++ /* avoid remove & p2p off command simultaneously */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ fgIsP2PEnding = g_u4P2PEnding; ++ g_u4P2POnOffing = 1; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ ++ if (fgIsP2PEnding == 1) { ++ /* skip the command if we are removing */ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++ break; ++ } ++ rSetP2P.u4Enable = pu4IntBuf[1]; ++ rSetP2P.u4Mode = pu4IntBuf[2]; ++ ++ if (!rSetP2P.u4Enable) ++ p2pNetUnregister(prGlueInfo, TRUE); ++ ++ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ ++ /* ++ Scenario: ++ 1. System enters suspend/resume but not yet enter wlanearlysuspend() ++ or wlanlateresume(); ++ ++ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() ++ and get g_halt_sem then do glRegisterEarlySuspend() or ++ glUnregisterEarlySuspend(); ++ ++ But system suspend/resume procedure is not yet finished so we ++ suspend; ++ ++ 3. System switches back to do suspend/resume procedure and execute ++ kalIoctl(). But driver does not yet release g_halt_sem so system ++ suspend in wlanearlysuspend() or wlanlateresume(); ++ ++ ==> deadlock occurs. ++ */ ++ if ((!rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { ++ /* fgIsP2PRegistered == TRUE means P2P is enabled */ ++ DBGLOG(P2P, INFO, "p2pEalySuspendReg\n"); ++ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p remove */ ++ } ++ ++ DBGLOG(P2P, INFO, ++ "wlanoidSetP2pMode 0x%p %d %d\n", &rSetP2P, rSetP2P.u4Enable, rSetP2P.u4Mode); ++ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, ++ (PVOID)&rSetP2P, /* pu4IntBuf[0] is used as input SubCmd */ ++ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), ++ FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ DBGLOG(P2P, INFO, "wlanoidSetP2pMode ok\n"); ++ ++ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ ++ if ((rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { ++ /* fgIsP2PRegistered == TRUE means P2P on successfully */ ++ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p on */ ++ } ++ ++ if (rSetP2P.u4Enable) ++ p2pNetRegister(prGlueInfo, TRUE); ++ ++ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); ++ g_u4P2POnOffing = 0; ++ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); ++#endif ++ } ++ break; ++#endif ++ ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ case PRIV_CMD_MET_PROFILING: ++ { ++ /* PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; */ ++ /* rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1]; */ ++ /* rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2]; */ ++ /* DBGLOG(REQ, INFO,("WFD Debug Mode:%d Period:%d\n", ++ rWfdDebugModeInfo.ucWFDDebugMode,rWfdDebugModeInfo.u2SNPeriod)); */ ++ prGlueInfo->u8MetProfEnable = (UINT_8) pu4IntBuf[1]; ++ prGlueInfo->u16MetUdpPort = (UINT_16) pu4IntBuf[2]; ++ DBGLOG(REQ, INFO, "MET_PROF: Enable=%d UDP_PORT=%d\n", prGlueInfo->u8MetProfEnable, ++ prGlueInfo->u16MetUdpPort); ++ ++ } ++ break; ++ ++#endif ++ case PRIV_CMD_WFD_DEBUG_CODE: ++ { ++ PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; ++ ++ rWfdDebugModeInfo.ucWFDDebugMode = (UINT_8) pu4IntBuf[1]; ++ rWfdDebugModeInfo.u2SNPeriod = (UINT_16) pu4IntBuf[2]; ++ DBGLOG(REQ, INFO, "WFD Debug Mode:%d Period:%d\n", rWfdDebugModeInfo.ucWFDDebugMode, ++ rWfdDebugModeInfo.u2SNPeriod); ++ kalIoctl(prGlueInfo, wlanoidSetWfdDebugMode, (PVOID)&rWfdDebugModeInfo, ++ sizeof(PARAM_CUSTOM_WFD_DEBUG_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); ++ ++ } ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl get int handler. ++* ++* \param[in] pDev Net device requested. ++* \param[out] pIwReq Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. ++* \param[out] pcExtra The buffer with put the return value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_8 gucBufDbgCode[1000]; ++ ++static int ++_priv_get_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ UINT_32 u4SubCmd; ++ PUINT_32 pu4IntBuf; ++ P_GLUE_INFO_T prGlueInfo; ++ UINT_32 u4BufLen = 0; ++ int status = 0; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->mode; ++ pu4IntBuf = (PUINT_32) pcExtra; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_TEST_CMD: ++ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; ++ /* ++ if (copy_to_user(prIwReqData->data.pointer, ++ &prNdisReq->ndisOidContent[4], 4)) { ++ printk(KERN_NOTICE "priv_get_int() copy_to_user oidBuf fail(3)\n"); ++ return -EFAULT; ++ } ++ */ ++ } ++ return status; ++ ++#if CFG_SUPPORT_PRIV_MCR_RW ++ case PRIV_CMD_ACCESS_MCR: ++ /* printk("addr=0x%08lx\n", pu4IntBuf[1]); */ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (!prGlueInfo->fgMcrAccessAllowed) { ++ status = 0; ++ return status; ++ } ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; ++ } ++ return status; ++#endif ++ ++ case PRIV_CMD_DUMP_MEM: ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++#if 1 ++ if (!prGlueInfo->fgMcrAccessAllowed) { ++ status = 0; ++ return status; ++ } ++#endif ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[0]; ++ return status; ++ ++ case PRIV_CMD_SW_CTRL: ++ /* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */ ++ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; ++ } ++ return status; ++ ++#if 0 ++ case PRIV_CMD_BEACON_PERIOD: ++ status = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryBeaconInterval, ++ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); ++ return status; ++ ++ case PRIV_CMD_POWER_MODE: ++ status = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQuery802dot11PowerSaveProfile, ++ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); ++ return status; ++ ++ case PRIV_CMD_ADHOC_MODE: ++ status = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryAdHocMode, (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); ++ return status; ++#endif ++ ++ case PRIV_CMD_BAND_CONFIG: ++ DBGLOG(REQ, INFO, "CMD get_band=\n"); ++ prIwReqData->mode = 0; ++ return status; ++ ++ default: ++ break; ++ } ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_GET_CH_LIST: ++ { ++ UINT_16 i, j = 0; ++ UINT_8 NumOfChannel = 50; ++ UINT_8 ucMaxChannelNum = 50; ++ INT_32 ch[50]; ++ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ ++ P_RF_CHANNEL_INFO_T paucChannelList; ++ P_RF_CHANNEL_INFO_T ChannelList_t; ++ ++ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); ++ if (paucChannelList == NULL) { ++ DBGLOG(REQ, INFO, "alloc ChannelList fail\n"); ++ return -EFAULT; ++ } ++ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); ++ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); ++ if (NumOfChannel > 50) { ++ ASSERT(0); ++ NumOfChannel = 50; ++ } ++ ++ ChannelList_t = paucChannelList; ++ if (kalIsAPmode(prGlueInfo)) { ++ for (i = 0; i < NumOfChannel; i++) { ++ if ((ChannelList_t->ucChannelNum <= 13) ++ || (ChannelList_t->ucChannelNum == 36 ++ || ChannelList_t->ucChannelNum == 40 ++ || ChannelList_t->ucChannelNum == 44 ++ || ChannelList_t->ucChannelNum == 48)) { ++ ch[j] = (INT_32) ChannelList_t->ucChannelNum; ++ ChannelList_t++; ++ j++; ++ } ++ } ++ } else { ++ for (j = 0; j < NumOfChannel; j++) { ++ ch[j] = (INT_32) ChannelList_t->ucChannelNum; ++ ChannelList_t++; ++ } ++ } ++ ++ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); ++ ++ prIwReqData->data.length = j; ++ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) ++ return -EFAULT; ++ else ++ return status; ++ } ++ ++ case PRIV_CMD_GET_BUILD_DATE_CODE: ++ { ++ UINT_8 aucBuffer[16]; ++ ++ if (kalIoctl(prGlueInfo, ++ wlanoidQueryBuildDateCode, ++ (PVOID) aucBuffer, ++ sizeof(UINT_8) * 16, TRUE, TRUE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { ++ prIwReqData->data.length = sizeof(UINT_8) * 16; ++ ++ if (copy_to_user(prIwReqData->data.pointer, aucBuffer, prIwReqData->data.length)) ++ return -EFAULT; ++ else ++ return status; ++ } else { ++ return -EFAULT; ++ } ++ } ++ ++ case PRIV_CMD_GET_DEBUG_CODE: ++ { ++ wlanQueryDebugCode(prGlueInfo->prAdapter); ++ ++ kalMemSet(gucBufDbgCode, '.', sizeof(gucBufDbgCode)); ++ if (copy_to_user(prIwReqData->data.pointer, gucBufDbgCode, prIwReqData->data.length)) ++ return -EFAULT; ++ else ++ return status; ++ } ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} /* priv_get_int */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl set int array handler. ++* ++* \param[in] prNetDev Net device requested. ++* \param[in] prIwReqInfo Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. ++* \param[in] pcExtra The buffer with input value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL If a value is out of range. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ UINT_32 u4SubCmd, u4BufLen; ++ P_GLUE_INFO_T prGlueInfo; ++ int status = 0; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_SET_TXPWR_CTRL_T prTxpwr; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_SET_TX_POWER: ++ { ++ INT_32 *setting = prIwReqData->data.pointer; ++ UINT_16 i; ++ ++#if 0 ++ DBGLOG(REQ, INFO, "Tx power num = %d\n", prIwReqData->data.length); ++ ++ DBGLOG(REQ, INFO, "Tx power setting = %d %d %d %d\n", ++ setting[0], setting[1], setting[2], setting[3]); ++#endif ++ prTxpwr = &prGlueInfo->rTxPwr; ++ if (setting[0] == 0 && prIwReqData->data.length == 4 /* argc num */) { ++ /* 0 (All networks), 1 (legacy STA), 2 (Hotspot AP), 3 (P2P), 4 (BT over Wi-Fi) */ ++ if (setting[1] == 1 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GLegacyStaPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GLegacyStaPwrOffset = setting[3]; ++ } ++ if (setting[1] == 2 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GHotspotPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GHotspotPwrOffset = setting[3]; ++ } ++ if (setting[1] == 3 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GP2pPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GP2pPwrOffset = setting[3]; ++ } ++ if (setting[1] == 4 || setting[1] == 0) { ++ if (setting[2] == 0 || setting[2] == 1) ++ prTxpwr->c2GBowPwrOffset = setting[3]; ++ if (setting[2] == 0 || setting[2] == 2) ++ prTxpwr->c5GBowPwrOffset = setting[3]; ++ } ++ } else if (setting[0] == 1 && prIwReqData->data.length == 2) { ++ prTxpwr->ucConcurrencePolicy = setting[1]; ++ } else if (setting[0] == 2 && prIwReqData->data.length == 3) { ++ if (setting[1] == 0) { ++ for (i = 0; i < 14; i++) ++ prTxpwr->acTxPwrLimit2G[i] = setting[2]; ++ } else if (setting[1] <= 14) ++ prTxpwr->acTxPwrLimit2G[setting[1] - 1] = setting[2]; ++ } else if (setting[0] == 3 && prIwReqData->data.length == 3) { ++ if (setting[1] == 0) { ++ for (i = 0; i < 4; i++) ++ prTxpwr->acTxPwrLimit5G[i] = setting[2]; ++ } else if (setting[1] <= 4) ++ prTxpwr->acTxPwrLimit5G[setting[1] - 1] = setting[2]; ++ } else if (setting[0] == 4 && prIwReqData->data.length == 2) { ++ if (setting[1] == 0) ++ wlanDefTxPowerCfg(prGlueInfo->prAdapter); ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetTxPower, ++ prTxpwr, ++ sizeof(SET_TXPWR_CTRL_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); ++ } else ++ return -EFAULT; ++ } ++ return status; ++ default: ++ break; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl get int array handler. ++* ++* \param[in] pDev Net device requested. ++* \param[out] pIwReq Pointer to iwreq structure. ++* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. ++* \param[out] pcExtra The buffer with put the return value ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EFAULT For fail. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_get_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ UINT_32 u4SubCmd; ++ P_GLUE_INFO_T prGlueInfo; ++ int status = 0; ++ INT_32 ch[50]; ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_GET_CH_LIST: ++ { ++ UINT_16 i; ++ UINT_8 NumOfChannel = 50; ++ UINT_8 ucMaxChannelNum = 50; ++ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ ++ P_RF_CHANNEL_INFO_T paucChannelList; ++ P_RF_CHANNEL_INFO_T ChannelList_t; ++ ++ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); ++ if (paucChannelList == NULL) { ++ DBGLOG(REQ, INFO, "alloc fail\n"); ++ return -EINVAL; ++ } ++ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); ++ ++ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); ++ if (NumOfChannel > 50) ++ NumOfChannel = 50; ++ ++ ChannelList_t = paucChannelList; ++ for (i = 0; i < NumOfChannel; i++) { ++ ch[i] = (INT_32) ChannelList_t->ucChannelNum; ++ ChannelList_t++; ++ } ++ ++ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); ++ prIwReqData->data.length = NumOfChannel; ++ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) ++ return -EFAULT; ++ else ++ return status; ++ } ++ default: ++ break; ++ } ++ ++ return status; ++} /* priv_get_int */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl set structure handler. ++* ++* \param[in] pDev Net device requested. ++* \param[in] prIwReqData Pointer to iwreq_data structure. ++* ++* \retval 0 For success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL If a value is out of range. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ UINT_32 u4SubCmd = 0; ++ int status = 0; ++ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ ++ UINT_32 u4CmdLen = 0; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq; ++ PUINT_32 pu4IntBuf = NULL; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4BufLen = 0; ++ ++ ASSERT(prNetDev); ++ /* ASSERT(prIwReqInfo); */ ++ ASSERT(prIwReqData); ++ /* ASSERT(pcExtra); */ ++ ++ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); ++ ++ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData)) ++ return -EINVAL; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ ++#if 0 ++ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", ++ prIwReqInfo->cmd, u4SubCmd); ++#endif ++ ++ switch (u4SubCmd) { ++#if 0 /* PTA_ENABLED */ ++ case PRIV_CMD_BT_COEXIST: ++ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); ++ ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen); ++ if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) ++ return -EFAULT; ++ ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { ++ status = -EFAULT; /* return -EFAULT; */ ++ break; ++ } ++ ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBtCoexistCtrl, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++ if (WLAN_STATUS_SUCCESS != rStatus) ++ status = -EFAULT; ++ break; ++#endif ++ ++ case PRIV_CUSTOM_BWCS_CMD: ++ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); ++ ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen); ++ if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen) ++ return -EFAULT; ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(REQ, INFO, ++ "ucCmdLen = %d, size of PTA_IPC_T = %d, prIwReqData->data = 0x%x.\n", u4CmdLen, ++ sizeof(PARAM_PTA_IPC_T), prIwReqData->data); ++ ++ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%u)\n", ++ prIwReqInfo->cmd, u4SubCmd); ++ ++ DBGLOG(REQ, INFO, "*pcExtra = 0x%x\n", *pcExtra); ++#endif ++ ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { ++ status = -EFAULT; /* return -EFAULT; */ ++ break; ++ } ++#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG ++ DBGLOG(REQ, INFO, "priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n", ++ aucOidBuf[2], aucOidBuf[3], aucOidBuf[4], aucOidBuf[5]); ++#endif ++ ++#if 0 ++ status = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++#endif ++ ++#if 1 ++ status = wlanoidSetBT(prGlueInfo->prAdapter, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); ++#endif ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ status = -EFAULT; ++ ++ break; ++ ++#if CFG_SUPPORT_WPS2 ++ case PRIV_CMD_WSC_PROBE_REQ: ++ { ++ /* retrieve IE for Probe Request */ ++ if (prIwReqData->data.length > 0) { ++ if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer, ++ prIwReqData->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ prGlueInfo->u2WSCIELen = prIwReqData->data.length; ++ } else { ++ prGlueInfo->u2WSCIELen = 0; ++ } ++ } ++ break; ++#endif ++ case PRIV_CMD_OID: ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) ++ DBGLOG(REQ, INFO, "pcExtra buffer is valid\n"); ++ else ++ DBGLOG(REQ, INFO, "pcExtra 0x%p\n", pcExtra); ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0], &u4BufLen); ++ /* Copy result to user space */ ++ ((P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0])->outNdisOidLength = u4BufLen; ++ ++ if (copy_to_user(prIwReqData->data.pointer, ++ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { ++ DBGLOG(REQ, INFO, "copy_to_user oidBuf fail\n"); ++ status = -EFAULT; ++ } ++ ++ break; ++ ++ case PRIV_CMD_SW_CTRL: ++ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ /* kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); */ ++ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, ++ prIwReqData->data.length)) { ++ status = -EFAULT; ++ break; ++ } ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ /* Execute this OID */ ++ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); ++ break; ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Private ioctl get struct handler. ++* ++* \param[in] pDev Net device requested. ++* \param[out] pIwReq Pointer to iwreq structure. ++* \param[in] cmd Private sub-command. ++* ++* \retval 0 For success. ++* \retval -EFAULT If copy from user space buffer fail. ++* \retval -EOPNOTSUPP Parameter "cmd" not recognized. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_get_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ UINT_32 u4SubCmd = 0; ++ P_NDIS_TRANSPORT_STRUCT prNdisReq = NULL; ++ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4BufLen = 0; ++ PUINT_32 pu4IntBuf = NULL; ++ int status = 0; ++ ++ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); ++ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqData); ++ if (!prNetDev || !prIwReqData) { ++ DBGLOG(REQ, INFO, "priv_get_struct(): invalid param(0x%p, 0x%p)\n", prNetDev, prIwReqData); ++ return -EINVAL; ++ } ++ ++ u4SubCmd = (UINT_32) prIwReqData->data.flags; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) { ++ DBGLOG(REQ, INFO, "priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n", ++ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); ++ return -EINVAL; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", ++ prIwReqInfo->cmd, u4SubCmd); ++#endif ++ memset(aucOidBuf, 0, sizeof(aucOidBuf)); ++ ++ switch (u4SubCmd) { ++ case PRIV_CMD_OID: ++ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, sizeof(NDIS_TRANSPORT_STRUCT))) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); ++ return -EFAULT; ++ } ++ ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++#if 0 ++ DBGLOG(REQ, INFO, "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n", ++ cmd, pIwReq->u.data.length, ndisReq->ndisOidCmd, ndisReq->inNdisOidlength); ++#endif ++ if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) { ++ prNdisReq->outNdisOidLength = u4BufLen; ++ if (copy_to_user(prIwReqData->data.pointer, ++ &aucOidBuf[0], ++ u4BufLen + sizeof(NDIS_TRANSPORT_STRUCT) - ++ sizeof(prNdisReq->ndisOidContent))) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(1)\n"); ++ return -EFAULT; ++ } ++ return 0; ++ } ++ prNdisReq->outNdisOidLength = u4BufLen; ++ if (copy_to_user(prIwReqData->data.pointer, ++ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); ++ } ++ return -EFAULT; ++ ++ case PRIV_CMD_SW_CTRL: ++ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; ++ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; ++ ++ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, ++ prIwReqData->data.length)) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); ++ return -EFAULT; ++ } ++ ++ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; ++ prNdisReq->inNdisOidlength = 8; ++ prNdisReq->outNdisOidLength = 8; ++ ++ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); ++ if (status == 0) { ++ prNdisReq->outNdisOidLength = u4BufLen; ++ /* printk("len=%d Result=%08lx\n", u4BufLen, *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ ++ ++ if (copy_to_user(prIwReqData->data.pointer, ++ &prNdisReq->ndisOidContent[4], ++ 4 /* OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent) */)) { ++ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); ++ } ++ } ++ return 0; ++ ++ default: ++ DBGLOG(REQ, WARN, "get struct cmd:0x%x\n", u4SubCmd); ++ return -EOPNOTSUPP; ++ } ++} /* priv_get_struct */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The routine handles a set operation for a single OID. ++* ++* \param[in] pDev Net device requested. ++* \param[in] ndisReq Ndis request OID information copy from user. ++* \param[out] outputLen_p If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed.. ++* ++* \retval 0 On success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) ++{ ++ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 u4SetInfoLen = 0; ++ ++ ASSERT(prNetDev); ++ ASSERT(prNdisReq); ++ ASSERT(pu4OutputLen); ++ ++ if (!prNetDev || !prNdisReq || !pu4OutputLen) { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", ++ prNetDev, prNdisReq, pu4OutputLen); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", ++ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); ++ return -EINVAL; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); ++#endif ++ ++ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { ++ /* WARNLOG(("Set OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ ++ return -EOPNOTSUPP; ++ } ++ ++ if (NULL == prWlanReqEntry->pfOidSetHandler) { ++ /* WARNLOG(("Set %s: Null set handler\n", prWlanReqEntry->pucOidName)); */ ++ return -EOPNOTSUPP; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_set_ndis(): %s\n", prWlanReqEntry->pucOidName); ++#endif ++ ++ if (prWlanReqEntry->fgSetBufLenChecking) { ++ if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) { ++ DBGLOG(REQ, WARN, "Set %s: Invalid length (current=%u, needed=%u)\n", ++ prWlanReqEntry->pucOidName, ++ prNdisReq->inNdisOidlength, prWlanReqEntry->u4InfoBufLen); ++ ++ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; ++ return -EINVAL; ++ } ++ } ++ ++ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { ++ /* GLUE sw info only */ ++ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4SetInfoLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { ++ /* multiple sw operations */ ++ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4SetInfoLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { ++ /* driver core */ ++ ++ status = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ } else { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); ++ return -EOPNOTSUPP; ++ } ++ ++ *pu4OutputLen = u4SetInfoLen; ++ ++ switch (status) { ++ case WLAN_STATUS_SUCCESS: ++ break; ++ ++ case WLAN_STATUS_INVALID_LENGTH: ++ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ ++ /* prWlanReqEntry->pucOidName, */ ++ /* prNdisReq->inNdisOidlength, */ ++ /* u4SetInfoLen)); */ ++ break; ++ } ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ return -EFAULT; ++ ++ return 0; ++} /* priv_set_ndis */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The routine handles a query operation for a single OID. Basically we ++* return information about the current state of the OID in question. ++* ++* \param[in] pDev Net device requested. ++* \param[in] ndisReq Ndis request OID information copy from user. ++* \param[out] outputLen_p If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed.. ++* ++* \retval 0 On success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* \retval -EINVAL invalid input parameters ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) ++{ ++ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; ++ UINT_32 u4BufLen = 0; ++ WLAN_STATUS status = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ ASSERT(prNetDev); ++ ASSERT(prNdisReq); ++ ASSERT(pu4OutputLen); ++ ++ if (!prNetDev || !prNdisReq || !pu4OutputLen) { ++ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", ++ prNetDev, prNdisReq, pu4OutputLen); ++ return -EINVAL; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ASSERT(prGlueInfo); ++ if (!prGlueInfo) { ++ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", ++ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); ++ return -EINVAL; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); ++#endif ++ ++ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { ++ /* WARNLOG(("Query OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ ++ return -EOPNOTSUPP; ++ } ++ ++ if (NULL == prWlanReqEntry->pfOidQueryHandler) { ++ /* WARNLOG(("Query %s: Null query handler\n", prWlanReqEntry->pucOidName)); */ ++ return -EOPNOTSUPP; ++ } ++#if 0 ++ DBGLOG(REQ, INFO, "priv_get_ndis(): %s\n", prWlanReqEntry->pucOidName); ++#endif ++ ++ if (prWlanReqEntry->fgQryBufLenChecking) { ++ if (prNdisReq->inNdisOidlength < prWlanReqEntry->u4InfoBufLen) { ++ /* Not enough room in InformationBuffer. Punt */ ++ /* WARNLOG(("Query %s: Buffer too short (current=%ld, needed=%ld)\n", */ ++ /* prWlanReqEntry->pucOidName, */ ++ /* prNdisReq->inNdisOidlength, */ ++ /* prWlanReqEntry->u4InfoBufLen)); */ ++ ++ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; ++ ++ status = WLAN_STATUS_INVALID_LENGTH; ++ return -EINVAL; ++ } ++ } ++ ++ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { ++ /* GLUE sw info only */ ++ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4BufLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { ++ /* multiple sw operations */ ++ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, &u4BufLen); ++ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { ++ /* driver core */ ++ ++ status = kalIoctl(prGlueInfo, ++ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidQueryHandler, ++ prNdisReq->ndisOidContent, ++ prNdisReq->inNdisOidlength, TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ } else { ++ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); ++ return -EOPNOTSUPP; ++ } ++ ++ *pu4OutputLen = u4BufLen; ++ ++ switch (status) { ++ case WLAN_STATUS_SUCCESS: ++ break; ++ ++ case WLAN_STATUS_INVALID_LENGTH: ++ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ ++ /* prWlanReqEntry->pucOidName, */ ++ /* prNdisReq->inNdisOidlength, */ ++ /* u4BufLen)); */ ++ break; ++ } ++ ++ if (WLAN_STATUS_SUCCESS != status) ++ return -EOPNOTSUPP; ++ ++ return 0; ++} /* priv_get_ndis */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse command value in a string. ++* ++* @param InStr Pointer to the string buffer. ++* @param OutStr Pointer to the next command value. ++* @param OutLen Record the resident buffer length. ++* ++* @retval Command value. ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen) ++{ ++ unsigned char Charc, *Buf; ++ unsigned int Num; ++ int Maxloop; ++ int ReadId; ++ int TotalLen; ++ ++ /* init */ ++ Num = 0; ++ Maxloop = 0; ++ ReadId = 0; ++ Buf = (unsigned char *)InStr; ++ TotalLen = *OutLen; ++ *OutStr = Buf; ++ ++ /* sanity check */ ++ if (Buf[0] == 0x00) ++ return 0; ++ ++ /* check the value is decimal or hex */ ++ if ((Buf[ReadId] == 'x') || ((Buf[ReadId] == '0') && (Buf[ReadId + 1] == 'x'))) { ++ /* skip x or 0x */ ++ if (Buf[ReadId] == 'x') ++ ReadId++; ++ else ++ ReadId += 2; ++ ++ /* translate the hex number */ ++ while (Maxloop++ < 10) { ++ Charc = Buf[ReadId]; ++ if ((Charc >= 0x30) && (Charc <= 0x39)) ++ Charc -= 0x30; ++ else if ((Charc >= 'a') && (Charc <= 'f')) ++ Charc -= 'a'; ++ else if ((Charc >= 'A') && (Charc <= 'F')) ++ Charc -= 'A'; ++ else ++ break; /* exit the parsing */ ++ Num = Num * 16 + Charc + 10; ++ ReadId++; ++ TotalLen--; ++ } ++ } else { ++ /* translate the decimal number */ ++ while (Maxloop++ < 10) { ++ Charc = Buf[ReadId]; ++ if ((Charc < 0x30) || (Charc > 0x39)) ++ break; /* exit the parsing */ ++ Charc -= 0x30; ++ Num = Num * 10 + Charc; ++ ReadId++; ++ TotalLen--; ++ } ++ } ++ ++ if (Buf[ReadId] == 0x00) ++ *OutStr = &Buf[ReadId]; ++ else ++ *OutStr = &Buf[ReadId + 1]; /* skip the character: _ */ ++ ++ *OutLen = TotalLen - 1; /* skip the character: _ */ ++ return Num; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* @brief Parse command MAC address in a string. ++* ++* @param InStr Pointer to the string buffer. ++* @param OutStr Pointer to the next command value. ++* @param OutLen Record the resident buffer length. ++* ++* @retval Command value. ++*/ ++/*----------------------------------------------------------------------------*/ ++UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac) ++{ ++ unsigned char Charc, *Buf; ++ unsigned int Num; ++ int Maxloop; ++ int ReadId; ++ int TotalLen; ++ ++ /* init */ ++ Num = 0; ++ Maxloop = 0; ++ ReadId = 0; ++ Buf = (unsigned char *)InStr; ++ TotalLen = *OutLen; ++ *OutStr = Buf; ++ ++ /* sanity check */ ++ if (Buf[0] == 0x00) ++ return 0; ++ ++ /* parse MAC */ ++ while (Maxloop < 6) { ++ Charc = Buf[ReadId]; ++ if ((Charc >= 0x30) && (Charc <= 0x39)) ++ Charc -= 0x30; ++ else if ((Charc >= 'a') && (Charc <= 'f')) ++ Charc = Charc - 'a' + 10; ++ else if ((Charc >= 'A') && (Charc <= 'F')) ++ Charc = Charc - 'A' + 10; ++ else ++ return -1; /* error, exit the parsing */ ++ ++ Num = Charc; ++ ReadId++; ++ TotalLen--; ++ ++ Charc = Buf[ReadId]; ++ if ((Charc >= 0x30) && (Charc <= 0x39)) ++ Charc -= 0x30; ++ else if ((Charc >= 'a') && (Charc <= 'f')) ++ Charc = Charc - 'a' + 10; ++ else if ((Charc >= 'A') && (Charc <= 'F')) ++ Charc = Charc - 'A' + 10; ++ else ++ return -1; /* error, exit the parsing */ ++ ++ Num = Num * 16 + Charc; ++ ReadId += 2; /* skip the character and ':' */ ++ TotalLen -= 2; ++ ++ OutMac[Maxloop] = Num; ++ Maxloop++; ++ } ++ ++ *OutStr = &Buf[ReadId]; /* skip the character: _ */ ++ *OutLen = TotalLen; /* skip the character: _ */ ++ return Num; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief The routine handles a set operation for a single OID. ++* ++* \param[in] pDev Net device requested. ++* \param[in] ndisReq Ndis request OID information copy from user. ++* \param[out] outputLen_p If the call is successful, returns the number of ++* bytes written into the query buffer. If the ++* call failed due to invalid length of the query ++* buffer, returns the amount of storage needed.. ++* ++* \retval 0 On success. ++* \retval -EOPNOTSUPP If cmd is not supported. ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static int ++_priv_set_string(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ P_GLUE_INFO_T GlueInfo; ++ INT_32 Status; ++ UINT_32 Subcmd; ++ UINT_8 *InBuf; ++ UINT_32 InBufLen; ++ ++ /* sanity check */ ++ ASSERT(prNetDev); ++ ASSERT(prIwReqInfo); ++ ASSERT(prIwReqData); ++ ASSERT(pcExtra); ++ ++ /* init */ ++ DBGLOG(REQ, INFO, "priv_set_string (%s)(%d)\n", ++ (UINT8 *) prIwReqData->data.pointer, (INT32) prIwReqData->data.length); ++ ++ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) ++ return -EINVAL; ++ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ InBuf = aucOidBuf; ++ InBufLen = prIwReqData->data.length; ++ Status = 0; ++ ++ if (copy_from_user(InBuf, prIwReqData->data.pointer, prIwReqData->data.length)) ++ return -EFAULT; ++ ++ Subcmd = CmdStringDecParse(prIwReqData->data.pointer, &InBuf, &InBufLen); ++ DBGLOG(REQ, INFO, "priv_set_string> command = %u\n", (UINT32) Subcmd); ++ ++ /* handle the command */ ++ switch (Subcmd) { ++#if (CFG_SUPPORT_TDLS == 1) ++ case PRIV_CMD_OTHER_TDLS: ++ TdlsexCmd(GlueInfo, InBuf, InBufLen); ++ break; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++ case PRIV_CMD_OTHER_TAR: ++ { ++ rlmCmd(GlueInfo, InBuf, InBufLen); ++ break; ++ } ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ default: ++ break; ++ } ++ ++ return Status; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to search desired OID. ++* ++* \param rOid[in] Desired NDIS_OID ++* \param ppWlanReqEntry[out] Found registered OID entry ++* ++* \retval TRUE: Matched OID is found ++* \retval FALSE: No matched OID is found ++*/ ++/*----------------------------------------------------------------------------*/ ++static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY *ppWlanReqEntry) ++{ ++ INT_32 i, j, k; ++ ++ i = 0; ++ j = NUM_SUPPORTED_OIDS - 1; ++ ++ while (i <= j) { ++ k = (i + j) / 2; ++ ++ if (rOid == arWlanOidReqTable[k].rOid) { ++ *ppWlanReqEntry = &arWlanOidReqTable[k]; ++ return TRUE; ++ } else if (rOid < arWlanOidReqTable[k].rOid) { ++ j = k - 1; ++ } else { ++ i = k + 1; ++ } ++ } ++ ++ return FALSE; ++} /* reqSearchSupportedOidEntry */ ++ ++#if 0 ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to query the radio configuration used in IBSS ++* mode and RF test mode. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[out] pvQueryBuffer Pointer to the buffer that holds the result of the query. ++* \param[in] u4QueryBufferLen The length of the query buffer. ++* \param[out] pu4QueryInfoLen If the call is successful, returns the number of ++* bytes written into the query buffer. If the call ++* failed due to invalid length of the query buffer, ++* returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) ++{ ++ P_PARAM_802_11_CONFIG_T prQueryConfig = (P_PARAM_802_11_CONFIG_T) pvQueryBuffer; ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ UINT_32 u4QueryInfoLen = 0; ++ ++ DEBUGFUNC("wlanoidQueryConfiguration"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4QueryInfoLen); ++ ++ *pu4QueryInfoLen = sizeof(PARAM_802_11_CONFIG_T); ++ if (u4QueryBufferLen < sizeof(PARAM_802_11_CONFIG_T)) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ ASSERT(pvQueryBuffer); ++ ++ kalMemZero(prQueryConfig, sizeof(PARAM_802_11_CONFIG_T)); ++ ++ /* Update the current radio configuration. */ ++ prQueryConfig->u4Length = sizeof(PARAM_802_11_CONFIG_T); ++ ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetBeaconInterval, ++ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryBeaconInterval, ++ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), &u4QueryInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidQueryAtimWindow, ++ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryAtimWindow, ++ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), &u4QueryInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidQueryFrequency, ++ &prQueryConfig->u4DSConfig, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); ++#else ++ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, ++ wlanoidQueryFrequency, ++ &prQueryConfig->u4DSConfig, sizeof(UINT_32), &u4QueryInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++ ++ prQueryConfig->rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); ++ ++ return rStatus; ++ ++} /* end of reqExtQueryConfiguration() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set the radio configuration used in IBSS ++* mode. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. ++* \param[in] u4SetBufferLen The length of the set buffer. ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed ++* due to invalid length of the set buffer, returns ++* the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_LENGTH ++* \retval WLAN_STATUS_NOT_ACCEPTED ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_PARAM_802_11_CONFIG_T prNewConfig = (P_PARAM_802_11_CONFIG_T) pvSetBuffer; ++ UINT_32 u4SetInfoLen = 0; ++ ++ DEBUGFUNC("wlanoidSetConfiguration"); ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pu4SetInfoLen); ++ ++ *pu4SetInfoLen = sizeof(PARAM_802_11_CONFIG_T); ++ ++ if (u4SetBufferLen < *pu4SetInfoLen) ++ return WLAN_STATUS_INVALID_LENGTH; ++ ++ /* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be returned. */ ++ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED) ++ return WLAN_STATUS_NOT_ACCEPTED; ++ ++ ASSERT(pvSetBuffer); ++ ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetBeaconInterval, ++ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); ++#else ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetBeaconInterval, ++ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), &u4SetInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetAtimWindow, ++ &prNewConfig->u4ATIMWindow, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); ++#else ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetAtimWindow, &prNewConfig->u4ATIMWindow, sizeof(UINT_32), &u4SetInfoLen); ++#endif ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++#if defined(_HIF_SDIO) ++ rStatus = sdio_io_ctrl(prGlueInfo, ++ wlanoidSetFrequency, ++ &prNewConfig->u4DSConfig, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); ++#else ++ rStatus = wlanSetInformation(prGlueInfo->prAdapter, ++ wlanoidSetFrequency, &prNewConfig->u4DSConfig, sizeof(UINT_32), &u4SetInfoLen); ++#endif ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ return rStatus; ++ ++ return rStatus; ++ ++} /* end of reqExtSetConfiguration() */ ++ ++#endif ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This routine is called to set beacon detection function enable/disable state ++* This is mainly designed for usage under BT inquiry state (disable function). ++* ++* \param[in] pvAdapter Pointer to the Adapter structure ++* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set ++* \param[in] u4SetBufferLen The length of the set buffer ++* \param[out] pu4SetInfoLen If the call is successful, returns the number of ++* bytes read from the set buffer. If the call failed due to invalid length of ++* the set buffer, returns the amount of storage needed. ++* ++* \retval WLAN_STATUS_SUCCESS ++* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. ++* \retval WLAN_STATUS_INVALID_LENGTH ++* ++*/ ++/*----------------------------------------------------------------------------*/ ++static WLAN_STATUS ++reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ ++ ASSERT(prGlueInfo); ++ ASSERT(pvSetBuffer); ++ ASSERT(pu4SetInfoLen); ++ ++ /* WIFI is enabled, when ACPI is D0 (ParamDeviceStateD0 = 1). And vice versa */ ++ ++ /* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */ ++ /* wlanoidSetAcpiDevicePowerState, */ ++ /* pvSetBuffer, */ ++ /* u4SetBufferLen, */ ++ /* pu4SetInfoLen); */ ++ return rStatus; ++} ++ ++int priv_driver_set_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) ++{ ++ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ P_ADAPTER_T prAdapter = NULL; ++ UINT_32 u4BufLen = 0; ++ INT_32 i4BytesWritten = 0; ++ UINT_32 u4CmdLen = 0; ++ UINT_32 u4PrefixLen = 0; ++ /* INT_32 i4Argc = 0; */ ++ /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */ ++ ++ PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T rChipConfigInfo; ++ ++ ASSERT(prNetDev); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) ++ return -1; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ prAdapter = prGlueInfo->prAdapter; ++ DBGLOG(REQ, INFO, "priv_driver_set_chip_config command is %s\n", pcCommand); ++ /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */ ++ /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */ ++ /* */ ++ u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); ++ u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */; ++ ++ kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); ++ ++ /* if(i4Argc >= 2) { */ ++ if (u4CmdLen > u4PrefixLen) { ++ ++ rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; ++ /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ ++ rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen; ++ /* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ ++ if (u4PrefixLen <= CHIP_CONFIG_RESP_SIZE) { ++ kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, ++ CHIP_CONFIG_RESP_SIZE - u4PrefixLen); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetChipConfig, ++ &rChipConfigInfo, ++ sizeof(rChipConfigInfo), FALSE, FALSE, TRUE, TRUE, &u4BufLen); ++ } else { ++ ++ DBGLOG(REQ, INFO, "%s: kalIoctl Command Len > %d\n", __func__, CHIP_CONFIG_RESP_SIZE); ++ rStatus = WLAN_STATUS_FAILURE; ++ } ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) { ++ DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, rStatus); ++ i4BytesWritten = -1; ++ } ++ } ++ ++ return i4BytesWritten; ++ ++} ++ ++int priv_driver_set_miracast(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) ++{ ++ P_ADAPTER_T prAdapter = NULL; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ UINT_32 i4BytesWritten = 0; ++ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ ++ /* UINT_32 u4BufLen = 0; */ ++ INT_32 i4Argc = 0; ++ UINT_32 ucMode = 0; ++ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; ++ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; ++ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; ++ INT_32 u4Ret; ++ ++ ASSERT(prNetDev); ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) ++ return -1; ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); ++ wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); ++ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); ++ ++ prAdapter = prGlueInfo->prAdapter; ++ if (i4Argc >= 2) { ++ u4Ret = kalkStrtou32(apcArgv[1], 0, &ucMode); /* ucMode = kalStrtoul(apcArgv[1], NULL, 0); */ ++ if (u4Ret) ++ DBGLOG(REQ, LOUD, "parse pcCommand error u4Ret=%d\n", u4Ret); ++ ++ if (g_ucMiracastMode == ucMode) ++ ; ++ /* XXX: continue or skip */ ++ ++ g_ucMiracastMode = ucMode; ++ prMsgWfdCfgUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); ++ ++ if (prMsgWfdCfgUpdate != NULL) { ++ ++ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); ++ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; ++ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; ++ ++ if (ucMode == MIRACAST_MODE_OFF) { ++ prWfdCfgSettings->ucWfdEnable = 0; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); ++ } else if (ucMode == MIRACAST_MODE_SOURCE) { ++ prWfdCfgSettings->ucWfdEnable = 1; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 1"); ++ } else if (ucMode == MIRACAST_MODE_SINK) { ++ prWfdCfgSettings->ucWfdEnable = 2; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 2"); ++ } else { ++ prWfdCfgSettings->ucWfdEnable = 0; ++ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); ++ } ++ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); ++ ++ priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); ++ ++ } /* prMsgWfdCfgUpdate */ ++ else { ++ ASSERT(FALSE); ++ i4BytesWritten = -1; ++ } ++ } ++ ++ /* i4Argc */ ++ return i4BytesWritten; ++} ++ ++int priv_support_driver_cmd(IN struct net_device *prNetDev, IN OUT struct ifreq *prReq, IN int i4Cmd) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ int ret = 0; ++ char *pcCommand = NULL; ++ priv_driver_cmd_t *priv_cmd = NULL; ++ int i4BytesWritten = 0; ++ int i4TotalLen = 0; ++ ++ if (!prReq->ifr_data) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (!prGlueInfo) { ++ DBGLOG(REQ, WARN, "No glue info\n"); ++ ret = -EFAULT; ++ goto exit; ++ } ++ if (prGlueInfo->u4ReadyFlag == 0) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ priv_cmd = kzalloc(sizeof(priv_driver_cmd_t), GFP_KERNEL); ++ if (!priv_cmd) { ++ DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(priv_cmd, prReq->ifr_data, sizeof(priv_driver_cmd_t))) { ++ DBGLOG(REQ, INFO, "%s: copy_from_user fail\n", __func__); ++ ret = -EFAULT; ++ goto exit; ++ } ++ ++ i4TotalLen = priv_cmd->total_len; ++ ++ if (i4TotalLen <= 0) { ++ ret = -EINVAL; ++ DBGLOG(REQ, INFO, "%s: i4TotalLen invalid\n", __func__); ++ goto exit; ++ } ++ ++ pcCommand = priv_cmd->buf; ++ ++ DBGLOG(REQ, INFO, "%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, prReq->ifr_name); ++ ++ i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen); ++ ++ if (i4BytesWritten < 0) { ++ DBGLOG(REQ, INFO, "%s: command %s failed; Written is %d\n", ++ __func__, pcCommand, i4BytesWritten); ++ ret = -EFAULT; ++ } ++ ++exit: ++ kfree(priv_cmd); ++ ++ return ret; ++} ++ ++#if CFG_SUPPORT_BATCH_SCAN ++#define CMD_BATCH_SET "WLS_BATCHING SET" ++#define CMD_BATCH_GET "WLS_BATCHING GET" ++#define CMD_BATCH_STOP "WLS_BATCHING STOP" ++#endif ++ ++#if CFG_SUPPORT_GET_CH_ENV ++#define CMD_CH_ENV_GET "CH_ENV_GET" ++#endif ++ ++INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen) ++{ ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ INT_32 i4BytesWritten = 0; ++ INT_32 i4CmdFound = 0; ++ ++ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) ++ return -1; ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); ++ ++ if (i4CmdFound == 0) { ++ i4CmdFound = 1; ++ ++ if (strnicmp(pcCommand, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) ++ i4BytesWritten = priv_driver_set_miracast(prNetDev, pcCommand, i4TotalLen); ++#if CFG_SUPPORT_BATCH_SCAN ++ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); ++ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { ++ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ ++ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ ++ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ ++ ++ UINT_32 u4BufLen; ++ int i; ++ /* int rlen=0; */ ++ ++ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { ++ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ ++ kalIoctl(prGlueInfo, ++ wlanoidQueryBatchScanResult, ++ (PVOID)&g_rEventBatchResult[i], ++ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); ++ } ++ ++#if 0 ++ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); ++ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { ++ prEntry = &g_rEventBatchResult.arBatchResult[i]; ++ DBGLOG(SCN, INFO, "Entry %u\n", i); ++ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); ++ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); ++ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); ++ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); ++ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); ++ } ++#endif ++ ++ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); ++ ++ /* Dump for debug */ ++ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, ++ i4BytesWritten, TRUE); */ ++ ++ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); ++ } ++#endif ++#if CFG_SUPPORT_GET_CH_ENV ++ else if (strnicmp(pcCommand, CMD_CH_ENV_GET, strlen(CMD_CH_ENV_GET)) == 0) ++ scanEnvResult(prGlueInfo, pcCommand, i4TotalLen, &i4BytesWritten); ++#endif ++ ++#if 0 ++ ++ else if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) { ++ /* i4BytesWritten = wl_android_get_rssi(net, command, i4TotalLen); */ ++ } else if (strnicmp(pcCommand, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { ++ i4BytesWritten = priv_driver_get_linkspeed(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { ++ /* Do nothing */ ++ } else if (strnicmp(pcCommand, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { ++ /* Do nothing */ ++ } else if (strnicmp(pcCommand, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { ++ /* Do nothing */ ++ } else if (strnicmp(pcCommand, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { ++ /* i4BytesWritten = wl_android_set_suspendopt(net, pcCommand, i4TotalLen); */ ++ } else if (strnicmp(pcCommand, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { ++ i4BytesWritten = priv_driver_set_suspend_mode(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { ++ i4BytesWritten = priv_driver_set_band(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { ++ /* i4BytesWritten = wl_android_get_band(net, pcCommand, i4TotalLen); */ ++ } else if (strnicmp(pcCommand, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { ++ i4BytesWritten = priv_driver_set_country(prNetDev, pcCommand, i4TotalLen); ++ } ++ /* Mediatek private command */ ++ else if (strnicmp(pcCommand, CMD_SET_SW_CTRL, strlen(CMD_SET_SW_CTRL)) == 0) { ++ i4BytesWritten = priv_driver_set_sw_ctrl(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_SW_CTRL, strlen(CMD_GET_SW_CTRL)) == 0) { ++ i4BytesWritten = priv_driver_get_sw_ctrl(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SET_CFG, strlen(CMD_SET_CFG)) == 0) { ++ i4BytesWritten = priv_driver_set_cfg(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_CFG, strlen(CMD_GET_CFG)) == 0) { ++ i4BytesWritten = priv_driver_get_cfg(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SET_CHIP, strlen(CMD_SET_CHIP)) == 0) { ++ i4BytesWritten = priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_CHIP, strlen(CMD_GET_CHIP)) == 0) { ++ i4BytesWritten = priv_driver_get_chip_config(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_SET_DBG_LEVEL, strlen(CMD_SET_DBG_LEVEL)) == 0) { ++ i4BytesWritten = priv_driver_set_dbg_level(prNetDev, pcCommand, i4TotalLen); ++ } else if (strnicmp(pcCommand, CMD_GET_DBG_LEVEL, strlen(CMD_GET_DBG_LEVEL)) == 0) { ++ i4BytesWritten = priv_driver_get_dbg_level(prNetDev, pcCommand, i4TotalLen); ++ } ++#if CFG_SUPPORT_BATCH_SCAN ++ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); ++ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { ++ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ ++ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ ++ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ ++ ++ UINT_32 u4BufLen; ++ int i; ++ /* int rlen=0; */ ++ ++ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { ++ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ ++ kalIoctl(prGlueInfo, ++ wlanoidQueryBatchScanResult, ++ (PVOID)&g_rEventBatchResult[i], ++ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, &u4BufLen); ++ } ++ ++#if 0 ++ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); ++ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { ++ prEntry = &g_rEventBatchResult.arBatchResult[i]; ++ DBGLOG(SCN, INFO, "Entry %u\n", i); ++ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); ++ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); ++ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); ++ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); ++ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); ++ } ++#endif ++ ++ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); ++ ++ /* Dump for debug */ ++ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, i4BytesWritten, ++ TRUE); */ ++ ++ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { ++ kalIoctl(prGlueInfo, ++ wlanoidSetBatchScanReq, ++ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); ++ } ++#endif ++ ++#endif ++ ++ else ++ i4CmdFound = 0; ++ } ++ ++ /* i4CmdFound */ ++ if (i4CmdFound == 0) ++ DBGLOG(REQ, TRACE, "Unknown driver command %s - ignored\n", pcCommand); ++ ++ if (i4BytesWritten >= 0) { ++ if ((i4BytesWritten == 0) && (i4TotalLen > 0)) { ++ /* reset the command buffer */ ++ pcCommand[0] = '\0'; ++ } ++ ++ if (i4BytesWritten >= i4TotalLen) { ++ DBGLOG(REQ, INFO, ++ "%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__, i4BytesWritten, i4TotalLen); ++ i4BytesWritten = i4TotalLen; ++ } else { ++ pcCommand[i4BytesWritten] = '\0'; ++ i4BytesWritten++; ++ } ++ } ++ ++ return i4BytesWritten; ++ ++} ++ ++static int compat_priv(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra, ++ int (*priv_func)(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)) ++{ ++ struct iw_point *prIwp; ++ int ret = 0; ++#ifdef CONFIG_COMPAT ++ struct compat_iw_point *iwp_compat = NULL; ++ struct iw_point iwp; ++#endif ++ ++ if (!prIwReqData) ++ return -EINVAL; ++ ++#ifdef CONFIG_COMPAT ++ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { ++ iwp_compat = (struct compat_iw_point *) &prIwReqData->data; ++ iwp.pointer = compat_ptr(iwp_compat->pointer); ++ iwp.length = iwp_compat->length; ++ iwp.flags = iwp_compat->flags; ++ prIwp = &iwp; ++ } else ++#endif ++ prIwp = &prIwReqData->data; ++ ++ ++ ret = priv_func(prNetDev, prIwReqInfo, (union iwreq_data *)prIwp, pcExtra); ++ ++#ifdef CONFIG_COMPAT ++ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { ++ iwp_compat->pointer = ptr_to_compat(iwp.pointer); ++ iwp_compat->length = iwp.length; ++ iwp_compat->flags = iwp.flags; ++ } ++#endif ++ return ret; ++} ++ ++int ++priv_set_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_int); ++} ++ ++int ++priv_get_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_int); ++} ++ ++int ++priv_set_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_ints); ++} ++ ++int ++priv_get_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_ints); ++} ++ ++int ++priv_set_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_struct); ++} ++ ++int ++priv_get_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_struct); ++} ++ ++int ++priv_set_string(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) ++{ ++ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_string); ++} ++ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c +new file mode 100644 +index 000000000000..c13d24906bf8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c +@@ -0,0 +1,1643 @@ ++/****************************************************************************** ++*[File] ahb.c ++*[Version] v1.0 ++*[Revision Date] 2013-01-16 ++*[Author] ++*[Description] ++* The program provides AHB HIF driver ++*[Copyright] ++* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. ++******************************************************************************/ ++ ++/* ++** Log: ahb.c ++ * ++ * 01 16 2013 vend_samp.lin ++ * Port sdio.c to ahb.c on MT6572/MT6582 ++ * 1) Initial version ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ * ++ * 02 14 2012 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * include correct header file upon setting. ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 09 20 2011 cp.wu ++ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized ++ * 1. always show error message for SDIO bus errors. ++ * 2. reset bus error flag when re-initialization ++ * ++ * 08 17 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * add MT6628 related definitions for Linux/Android driver. ++ * ++ * 05 18 2011 cp.wu ++ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC ++ * add device ID for MT5931. ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 18 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK. ++ * ++ * 03 15 2011 cp.wu ++ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous ++ * memory consumption ++ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK ++ * 2. Use common coalescing buffer for both TX/RX directions ++ * ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 11 15 2010 jeffrey.chang ++ * [WCXRP00000181] [MT6620 Wi-Fi][Driver] fix the driver message "GLUE_FLAG_HALT skip INT" during unloading ++ * Fix GLUE_FALG_HALT message which cause driver to hang ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * correct typo ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add code to run WlanIST in SDIO callback. ++ * ++ * 10 19 2010 cp.wu ++ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration ++ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK ++ * HIF by default ++ * Refine linux kernel module to the license of MTK and enable MTK HIF ++ * ++ * 08 21 2010 jeffrey.chang ++ * NULL ++ * 1) add sdio two setting ++ * 2) bug fix of sdio glue ++ * ++ * 08 18 2010 jeffrey.chang ++ * NULL ++ * support multi-function sdio ++ * ++ * 08 18 2010 cp.wu ++ * NULL ++ * #if defined(__X86__) is not working, change to use #ifdef CONFIG_X86. ++ * ++ * 08 17 2010 cp.wu ++ * NULL ++ * add ENE SDIO host workaround for x86 linux platform. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Fix hotplug bug ++ * ++ * 03 28 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * clear sdio interrupt ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++/* #include */ ++#include ++/* #include */ ++#include ++/* #include */ ++/* #include */ ++/* #include */ ++ ++#include ++#ifndef CONFIG_X86 ++#include ++#endif ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#else ++ ++#endif ++ ++/* #include ++#include */ ++ ++#include "gl_os.h" ++ ++#if defined(MT6620) ++#include "mt6620_reg.h" ++#elif defined(MT6628) ++#include "mtreg.h" ++#endif ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++#include ++#endif ++ ++/* #define MTK_DMA_BUF_MEMCPY_SUP */ /* no virt_to_phys() use */ ++/* #define HIF_DEBUG_SUP */ ++/* #define HIF_DEBUG_SUP_TX */ ++ ++#ifdef HIF_DEBUG_SUP ++#define HIF_DBG(msg) (printk msg) ++#else ++#define HIF_DBG(msg) ++#endif /* HIF_DEBUG_SUP */ ++ ++#ifdef HIF_DEBUG_SUP_TX ++#define HIF_DBG_TX(msg) (printk msg) ++#else ++#define HIF_DBG_TX(msg) ++#endif /* HIF_DEBUG_SUP */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++static UINT_32 ++HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T *GlueInfo, IN UINT_32 BurstLen, IN UINT_32 PortId, IN UINT_32 TransByte); ++ ++static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg); ++ ++static int HifAhbProbe(VOID); ++ ++static int HifAhbRemove(VOID); ++ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++static int HifAhbBusCntGet(VOID); ++ ++static int HifAhbBusCntClr(VOID); ++ ++static int HifTxCnt; ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++#if (CONF_HIF_DEV_MISC == 1) ++static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos); ++ ++static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos); ++ ++static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg); ++ ++static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp); ++ ++static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp); ++#else ++ ++static int HifAhbPltmProbe(IN struct platform_device *PDev); ++ ++static int __exit HifAhbPltmRemove(IN struct platform_device *PDev); ++ ++#ifdef CONFIG_PM ++static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message); ++ ++static int HifAhbPltmResume(IN struct platform_device *PDev); ++#endif /* CONFIG_PM */ ++ ++#endif /* CONF_HIF_DEV_MISC */ ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ ++static VOID HifAhbLoopbkAuto(IN unsigned long arg); ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if (CONF_HIF_DMA_INT == 1) ++static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg); ++#endif /* CONF_HIF_DMA_INT */ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/* initialiation function from other module */ ++static probe_card pfWlanProbe; ++ ++/* release function from other module */ ++static remove_card pfWlanRemove; ++ ++static BOOLEAN WlanDmaFatalErr; ++ ++#if (CONF_HIF_DEV_MISC == 1) ++static const struct file_operations MtkAhbOps = { ++ .owner = THIS_MODULE, ++ .read = HifAhbMiscRead, ++ .write = HifAhbMiscWrite, ++ .unlocked_ioctl = HifAhbMiscIoctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = HifAhbMiscIoctl, ++#endif ++ .open = HifAhbMiscOpen, ++ .release = HifAhbMiscClose, ++}; ++ ++static struct miscdevice MtkAhbDriver = { ++ .minor = MISC_DYNAMIC_MINOR, /* any minor number */ ++ .name = HIF_MOD_NAME, ++ .fops = &MtkAhbOps, ++}; ++#else ++ ++#ifdef CONFIG_OF ++static const struct of_device_id apwifi_of_ids[] = { ++ {.compatible = "mediatek,wifi", .data = (void *)0}, ++ {.compatible = "mediatek,mt7623-wifi", .data = (void *)0x7623}, ++ {} ++}; ++#endif ++ ++struct platform_driver MtkPltmAhbDriver = { ++ .driver = { ++ .name = "mt-wifi", ++ .owner = THIS_MODULE, ++#ifdef CONFIG_OF ++ .of_match_table = apwifi_of_ids, ++#endif ++ }, ++ .probe = HifAhbPltmProbe, ++#ifdef CONFIG_PM ++ .suspend = HifAhbPltmSuspend, ++ .resume = HifAhbPltmResume, ++#else ++ .suspend = NULL, ++ .resume = NULL, ++#endif /* CONFIG_PM */ ++ .remove = __exit_p(HifAhbPltmRemove), ++}; ++ ++static struct platform_device *HifAhbPDev; ++ ++#endif /* CONF_HIF_DEV_MISC */ ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will register sdio bus to the os ++* ++* \param[in] pfProbe Function pointer to detect card ++* \param[in] pfRemove Function pointer to remove card ++* ++* \return The result of registering HIF driver (WLAN_STATUS_SUCCESS = 0) ++*/ ++/*----------------------------------------------------------------------------*/ ++WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove) ++{ ++ WLAN_STATUS Ret; ++ ++ ASSERT(pfProbe); ++ ASSERT(pfRemove); ++ ++ pfWlanProbe = pfProbe; /* wlan card initialization in other modules = wlanProbe() */ ++ pfWlanRemove = pfRemove; ++ ++#if (CONF_HIF_DEV_MISC == 1) ++ Ret = misc_register(&MtkAhbDriver); ++ if (Ret != 0) ++ return Ret; ++ HifAhbProbe(); ++#else ++ Ret = platform_driver_register(&MtkPltmAhbDriver); ++#endif /* CONF_HIF_DEV_MISC */ ++ ++ return Ret; ++ ++} /* end of glRegisterBus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will unregister sdio bus to the os ++* ++* \param[in] pfRemove Function pointer to remove card ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glUnregisterBus(remove_card pfRemove) ++{ ++ ASSERT(pfRemove); ++ ++ pfRemove(); ++ ++#if (CONF_HIF_DEV_MISC == 1) ++ HifAhbRemove(); ++ ++ if ((misc_deregister(&MtkAhbDriver)) != 0) ++ ; ++#else ++ ++ platform_driver_unregister(&MtkPltmAhbDriver); ++#endif /* CONF_HIF_DEV_MISC */ ++ ++ return; ++ ++} /* end of glUnregisterBus() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will inform us whole chip reset start event. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glResetHif(GLUE_INFO_T *GlueInfo) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ if (HifInfo->DmaOps) ++ HifInfo->DmaOps->DmaReset(HifInfo); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function stores hif related info, which is initialized before. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glSetHifInfo(GLUE_INFO_T *GlueInfo, ULONG ulCookie) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ const struct of_device_id *of_id; ++ ++ /* Init HIF */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++#if (CONF_HIF_DEV_MISC == 1) ++ HifInfo->Dev = MtkAhbDriver.this_device; ++#else ++ HifInfo->Dev = &HifAhbPDev->dev; ++#endif /* CONF_HIF_DEV_MISC */ ++ SET_NETDEV_DEV(GlueInfo->prDevHandler, HifInfo->Dev); ++ ++ HifInfo->HifRegBaseAddr = ioremap(HIF_DRV_BASE, HIF_DRV_LENGTH); ++ HifInfo->McuRegBaseAddr = ioremap(CONN_MCU_DRV_BASE, CONN_MCU_REG_LENGTH); ++ DBGLOG(INIT, INFO, "[WiFi/HIF]HifInfo->HifRegBaseAddr=0x%p, HifInfo->McuRegBaseAddr=0x%p\n", ++ HifInfo->HifRegBaseAddr, HifInfo->McuRegBaseAddr); ++ ++ /* default disable DMA */ ++ HifInfo->fgDmaEnable = FALSE; ++ HifInfo->DmaRegBaseAddr = 0; ++ HifInfo->DmaOps = NULL; ++ of_id = of_match_node(apwifi_of_ids, HifAhbPDev->dev.of_node); ++ if (of_id && of_id->data) { ++ HifInfo->ChipID = (UINT_32)(unsigned long)of_id->data; ++ } else { ++ /* read chip ID */ ++ HifInfo->ChipID = HIF_REG_READL(HifInfo, MCR_WCIR) & 0xFFFF; ++ if (HifInfo->ChipID == 0x0321 || HifInfo->ChipID == 0x0335 || HifInfo->ChipID == 0x0337) ++ HifInfo->ChipID = 0x6735; /* Denali ChipID transition */ ++ if (HifInfo->ChipID == 0x0326) ++ HifInfo->ChipID = 0x6755; ++ } ++ DBGLOG(INIT, INFO, "[WiFi/HIF] ChipID = 0x%x\n", HifInfo->ChipID); ++#ifdef CONFIG_OF ++#if !defined(CONFIG_MTK_CLKMGR) ++ HifInfo->clk_wifi_dma = devm_clk_get(&HifAhbPDev->dev, "wifi-dma"); ++ if (IS_ERR(HifInfo->clk_wifi_dma)) ++ DBGLOG(INIT, ERROR, "[WiFi/HIF][CCF]cannot get HIF clk_wifi_dma clock.\n"); ++ DBGLOG(INIT, TRACE, "[WiFi/HIF][CCF]HIF clk_wifi_dma=0x%p\n", HifInfo->clk_wifi_dma); ++#endif ++#endif ++ ++ /* Init DMA */ ++ WlanDmaFatalErr = 0; /* reset error flag */ ++ ++#if (CONF_MTK_AHB_DMA == 1) ++ spin_lock_init(&HifInfo->DdmaLock); ++ ++ HifPdmaInit(HifInfo); ++#endif /* CONF_MTK_AHB_DMA */ ++ ++ /* Start loopback test after 10 seconds */ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ ++ { ++ init_timer(&(HifInfo->HifTmrLoopbkFn)); ++ HifInfo->HifTmrLoopbkFn.function = HifAhbLoopbkAuto; ++ HifInfo->HifTmrLoopbkFn.data = (unsigned long)GlueInfo; ++ ++ init_waitqueue_head(&HifInfo->HifWaitq); ++ HifInfo->HifTaskLoopbkFn = kthread_run(kalDevLoopbkThread, GlueInfo->prDevHandler, "LoopbkThread"); ++ HifInfo->HifLoopbkFlg = 0; ++ ++ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ ++ HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(30000); ++ add_timer(&(HifInfo->HifTmrLoopbkFn)); ++ ++ HIF_DBG(("[WiFi/HIF] Start loopback test after 10 seconds (jiffies = %u)...\n", jiffies)); ++ } ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if (CONF_HIF_DMA_INT == 1) ++ init_waitqueue_head(&HifInfo->HifDmaWaitq); ++ HifInfo->HifDmaWaitFlg = 0; ++#endif /* CONF_HIF_DMA_INT */ ++ ++} /* end of glSetHifInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function clears hif related info. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glClearHifInfo(GLUE_INFO_T *GlueInfo) ++{ ++ iounmap(GlueInfo->rHifInfo.HifRegBaseAddr); ++ iounmap(GlueInfo->rHifInfo.DmaRegBaseAddr); ++ iounmap(GlueInfo->rHifInfo.McuRegBaseAddr); ++ return; ++ ++} /* end of glClearHifInfo() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function clears hif related info. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ DBGLOG(INIT, TRACE, "glGetChipInfo ChipID = 0x%x\n", HifInfo->ChipID); ++ switch (HifInfo->ChipID) { ++ case MTK_CHIP_ID_6571: ++ case MTK_CHIP_ID_8127: ++ case MTK_CHIP_ID_6752: ++ case MTK_CHIP_ID_8163: ++ case MTK_CHIP_ID_6735: ++ case MTK_CHIP_ID_6580: ++ case MTK_CHIP_ID_6755: ++ case MTK_CHIP_ID_7623: ++ kalSprintf(pucChipBuf, "%04x", HifInfo->ChipID); ++ break; ++ default: ++ kalMemCopy(pucChipBuf, "SOC", strlen("SOC")); ++ } ++} /* end of glGetChipInfo() */ ++ ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function to check if we need wakelock under Hotspot mode. ++* ++* \param[in] GlueInfo Pointer to glue info structure ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ if (HifInfo->ChipID == MTK_CHIP_ID_6572 || HifInfo->ChipID == MTK_CHIP_ID_6582) ++ return TRUE; ++ else ++ return FALSE; ++} /* end of glIsChipNeedWakelock() */ ++#endif /* CFG_SPM_WORKAROUND_FOR_HOTSPOT */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Initialize bus operation and hif related information, request resources. ++* ++* \param[out] pvData A pointer to HIF-specific data type buffer. ++* For eHPI, pvData is a pointer to UINT_32 type and stores a ++* mapped base address. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN glBusInit(PVOID pvData) ++{ ++ return TRUE; ++} /* end of glBusInit() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Stop bus operation and release resources. ++* ++* \param[in] pvData A pointer to struct net_device. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glBusRelease(PVOID pvData) ++{ ++} /* end of glBusRelease() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Setup bus interrupt operation and interrupt handler for os. ++* ++* \param[in] pvData A pointer to struct net_device. ++* \param[in] pfnIsr A pointer to interrupt handler function. ++* \param[in] pvCookie Private data for pfnIsr function. ++* ++* \retval WLAN_STATUS_SUCCESS if success ++* NEGATIVE_VALUE if fail ++*/ ++/*----------------------------------------------------------------------------*/ ++#ifdef CONFIG_OF ++INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = { 0, 0, 0 }; ++ /* unsigned int phy_base; */ ++ unsigned int irq_id = 0; ++ unsigned int irq_flags = 0; ++ ++ struct net_device *prNetDevice; ++ ++ ASSERT(pvData); ++ if (!pvData) ++ return -1; ++ prNetDevice = (struct net_device *)pvData; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); ++ if (node) { ++ irq_id = irq_of_parse_and_map(node, 0); ++ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); ++ } else { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); ++ } ++ ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); ++ } else { ++ irq_flags = irq_info[2]; ++ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); ++ } ++ ++ /* Register AHB IRQ */ ++ if (request_irq(irq_id, HifAhbISR, irq_flags, HIF_MOD_NAME, prNetDevice)) { ++ DBGLOG(INIT, ERROR, "WIFI-OF: request irq %d fail!\n", irq_id); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) ++{ ++ struct device_node *node = NULL; ++ unsigned int irq_info[3] = { 0, 0, 0 }; ++ /* unsigned int phy_base; */ ++ unsigned int irq_id = 0; ++ unsigned int irq_flags = 0; ++ ++ struct net_device *prNetDevice; ++ ++ /* Init */ ++ ASSERT(pvData); ++ if (!pvData) ++ return; ++ prNetDevice = (struct net_device *)pvData; ++ ++ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); ++ if (node) { ++ irq_id = irq_of_parse_and_map(node, 0); ++ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); ++ } else { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); ++ } ++ ++ /* get the interrupt line behaviour */ ++ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { ++ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); ++ } else { ++ irq_flags = irq_info[2]; ++ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); ++ } ++ ++ /* Free the IRQ */ ++ free_irq(irq_id, prNetDevice); ++ return; ++ ++} ++#else ++/* the name is different in 72 and 82 */ ++#ifndef MT_WF_HIF_IRQ_ID /* for MT6572/82/92 */ ++#define MT_WF_HIF_IRQ_ID WF_HIF_IRQ_ID ++#endif /* MT_WF_HIF_IRQ_ID */ ++ ++INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) ++{ ++ int ret = 0; ++ struct net_device *prNetDevice; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ ASSERT(pvData); ++ if (!pvData) ++ return -1; ++ ++ prNetDevice = (struct net_device *)pvData; ++ GlueInfo = (GLUE_INFO_T *) pvCookie; ++ ASSERT(GlueInfo); ++ if (!GlueInfo) { ++ DBGLOG(INIT, ERROR, "GlueInfo == NULL!\n"); ++ return -1; ++ } ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* Register AHB IRQ */ ++ if (request_irq(MT_WF_HIF_IRQ_ID, HifAhbISR, IRQF_TRIGGER_LOW, HIF_MOD_NAME, prNetDevice)) { ++ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_WF_HIF_IRQ_ID); ++ return -1; ++ } ++#if (CONF_HIF_DMA_INT == 1) ++ if (request_irq(MT_GDMA2_IRQ_ID, HifDmaISR, IRQF_TRIGGER_LOW, "AHB_DMA", prNetDevice)) { ++ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_GDMA2_IRQ_ID); ++ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); ++ return -1; ++ } ++#endif /* CONF_HIF_DMA_INT */ ++ ++ return ret; ++ ++} /* end of glBusSetIrq() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Stop bus interrupt operation and disable interrupt handling for os. ++* ++* \param[in] pvData A pointer to struct net_device. ++* \param[in] pvCookie Private data for pfnIsr function. ++* ++* \return (none) ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) ++{ ++ struct net_device *prNetDevice; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ ASSERT(pvData); ++ if (!pvData) ++ return; ++ ++ prNetDevice = (struct net_device *)pvData; ++ GlueInfo = (GLUE_INFO_T *) pvCookie; ++ ASSERT(GlueInfo); ++ if (!GlueInfo) ++ return; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* Free the IRQ */ ++ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); ++ return; ++ ++} /* end of glBusreeIrq() */ ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Read a 32-bit device register ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] RegOffset Register offset ++* \param[in] pu4Value Pointer to variable used to store read value ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalDevRegRead(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, OUT UINT_32 *pu4Value) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* sanity check and init */ ++ ASSERT(GlueInfo); ++ ASSERT(pu4Value); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* use PIO mode to read register */ ++ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) ++ return FALSE; ++ *pu4Value = HIF_REG_READL(HifInfo, RegOffset); ++ ++ if ((RegOffset == MCR_WRDR0) || (RegOffset == MCR_WRDR1)) ++ HIF_DBG(("[WiFi/HIF] kalDevRegRead from Data Port 0 or 1\n")); ++ ++ return TRUE; ++ ++} /* end of kalDevRegRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Write a 32-bit device register ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] RegOffset Register offset ++* \param[in] RegValue RegValue to be written ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalDevRegWrite(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, IN UINT_32 RegValue) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* sanity check and init */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* use PIO mode to write register */ ++ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) ++ return FALSE; ++ HIF_REG_WRITEL(HifInfo, RegOffset, RegValue); ++ ++ if ((RegOffset == MCR_WTDR0) || (RegOffset == MCR_WTDR1)) ++ HIF_DBG(("[WiFi/HIF] kalDevRegWrite to Data Port 0 or 1\n")); ++ ++ return TRUE; ++ ++} /* end of kalDevRegWrite() */ ++ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Read device I/O port ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] Port I/O port offset ++* \param[in] Size Length to be read ++* \param[out] Buf Pointer to read buffer ++* \param[in] MaxBufSize Length of the buffer valid to be accessed ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++kalDevPortRead(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, OUT PUINT_8 Buf, IN UINT_32 MaxBufSize) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4HSTCRValue = 0; ++ UINT_32 RegWHLPCR = 0; ++ ++ /* sanity check */ ++ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { ++ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", ++ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); ++ return FALSE; ++ } ++ /* Init */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ ASSERT(Buf); ++ ASSERT(Size <= MaxBufSize); ++ ++ /* Note: burst length should be equal to the one used in DMA */ ++ if (Port == MCR_WRDR0) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD0, Size); ++ else if (Port == MCR_WRDR1) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD1, Size); ++ else if (Port == MCR_WHISR) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_WHISR, Size); ++ ++ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ /* Read */ ++#if (CONF_MTK_AHB_DMA == 1) ++ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) ++ && ((Port == MCR_WRDR0) || (Port == MCR_WRDR1))) { ++ /* only for data port */ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; ++ MTK_WCN_HIF_DMA_CONF DmaConf; ++ UINT_32 LoopCnt; ++ unsigned long PollTimeout; ++#if (CONF_HIF_DMA_INT == 1) ++ INT_32 RtnVal = 0; ++#endif ++ /* config DMA, Port = MCR_WRDR0 or MCR_WRDR1 */ ++ DmaConf.Count = Size; ++ DmaConf.Dir = HIF_DMA_DIR_RX; ++ DmaConf.Src = HIF_DRV_BASE + Port; /* must be physical addr */ ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ DmaConf.Dst = kalIOPhyAddrGet(Buf); /* must be physical addr */ ++ ++ /* TODO: use virt_to_phys() */ ++ if (DmaConf.Dst == NULL) { ++ HIF_DBG(("[WiFi/HIF] Use Dma Buffer to RX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); ++ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); ++ ++ kalDmaBufGet(&DmaVBuf, &DmaPBuf); ++ DmaConf.Dst = (ULONG) DmaPBuf; ++ } ++#else ++ /* ++ http://kernelnewbies.org/KernelMemoryAllocation ++ Since the cache-coherent mapping may be expensive, also a streaming allocation exists. ++ ++ This is a buffer for one-way communication, which means coherency is limited to ++ flushing the data from the cache after a write finishes. The buffer has to be ++ pre-allocated (e.g. using kmalloc()). DMA for it is set up with dma_map_single(). ++ ++ When the DMA is finished (e.g. when the device has sent an interrupt signaling end of ++ DMA), call dma_unmap_single(). Between map and unmap, the device is in control of the ++ buffer: if you write to the device, do it before dma_map_single(), if you read from ++ it, do it after dma_unmap_single(). ++ */ ++ /* DMA_FROM_DEVICE invalidated (without writeback) the cache */ ++ /* TODO: if dst_off was not cacheline aligned */ ++ DmaConf.Dst = dma_map_single(HifInfo->Dev, Buf, Size, DMA_FROM_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ /* start to read data */ ++ AP_DMA_HIF_LOCK(HifInfo); /* lock to avoid other codes config GDMA */ ++ ++ prDmaOps->DmaClockCtrl(TRUE); ++ prDmaOps->DmaConfig(HifInfo, &DmaConf); ++ prDmaOps->DmaStart(HifInfo); ++ ++#if (CONF_HIF_DMA_INT == 1) ++ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); ++ if (RtnVal <= 0) ++ DBGLOG(RX, ERROR, "fatal error1! reset DMA!\n"); ++ HifInfo->HifDmaWaitFlg = 0; ++#else ++ PollTimeout = jiffies + HZ * 5; ++ ++ do { ++ if (time_before(jiffies, PollTimeout)) ++ continue; ++ DBGLOG(RX, INFO, "RX DMA Timeout, HSTCR: 0x%08x, and dump WHISR EnhanceMode data\n", ++ u4HSTCRValue); ++ HifDumpEnhanceModeData(GlueInfo->prAdapter); ++ if (prDmaOps->DmaRegDump != NULL) ++ prDmaOps->DmaRegDump(HifInfo); ++ WlanDmaFatalErr = 1; ++ /* we still need complete dma progress even dma timeout */ ++ break; ++ } while (!prDmaOps->DmaPollIntr(HifInfo)); ++#endif /* CONF_HIF_DMA_INT */ ++ /* we should disable dma interrupt then clear dma interrupt, otherwise, ++ for dma timeout case, interrupt may be set after we clear it */ ++ prDmaOps->DmaStop(HifInfo); ++ prDmaOps->DmaAckIntr(HifInfo); ++ ++ LoopCnt = 0; ++ do { ++ if (LoopCnt++ > 100000) { ++ /* TODO: impossible! reset DMA */ ++ DBGLOG(RX, ERROR, "fatal error2! reset DMA!\n"); ++ break; ++ } ++ } while (prDmaOps->DmaPollStart(HifInfo) != 0); ++ ++ prDmaOps->DmaClockCtrl(FALSE); ++ ++ AP_DMA_HIF_UNLOCK(HifInfo); ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ if (DmaVBuf != NULL) ++ kalMemCopy(Buf, DmaVBuf, Size); ++#else ++ dma_unmap_single(HifInfo->Dev, DmaConf.Dst, Size, DMA_FROM_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++ if (WlanDmaFatalErr) { ++ if (!fgIsResetting) ++ glDoChipReset(); ++ return FALSE; ++ } ++ HIF_DBG(("[WiFi/HIF] DMA RX OK!\n")); ++ } else ++#endif /* CONF_MTK_AHB_DMA */ ++ { ++ UINT_32 IdLoop, MaxLoop; ++ UINT_32 *LoopBuf; ++ ++ /* default PIO mode */ ++ MaxLoop = Size >> 2; ++ if (Size & 0x3) ++ MaxLoop++; ++ LoopBuf = (UINT_32 *) Buf; ++ ++ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { ++ ++ *LoopBuf = HIF_REG_READL(HifInfo, Port); ++ LoopBuf++; ++ } ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ } ++ ++ return TRUE; ++ ++} /* end of kalDevPortRead() */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Write device I/O port ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] Port I/O port offset ++* \param[in] Size Length to be write ++* \param[in] Buf Pointer to write buffer ++* \param[in] MaxBufSize Length of the buffer valid to be accessed ++* ++* \retval TRUE operation success ++* \retval FALSE operation fail ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN ++kalDevPortWrite(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, IN PUINT_8 Buf, IN UINT_32 MaxBufSize) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 u4HSTCRValue = 0; ++ UINT_32 RegWHLPCR = 0; ++ ++ /* sanity check */ ++ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { ++ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", ++ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); ++ return FALSE; ++ } ++ ++ /* Init */ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ ASSERT(Buf); ++ ASSERT(Size <= MaxBufSize); ++ ++ HifTxCnt++; ++ ++ /* Note: burst length should be equal to the one used in DMA */ ++ if (Port == MCR_WTDR0) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD0, Size); ++ else if (Port == MCR_WTDR1) ++ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD1, Size); ++ /* else other non-data port */ ++ ++ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ /* Write */ ++#if (CONF_MTK_AHB_DMA == 1) ++ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) && ((Port == MCR_WTDR0) || ++ (Port == MCR_WTDR1))) { ++ /* only for data port */ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; ++ MTK_WCN_HIF_DMA_CONF DmaConf; ++ UINT_32 LoopCnt; ++ unsigned long PollTimeout; ++#if (CONF_HIF_DMA_INT == 1) ++ INT_32 RtnVal = 0; ++#endif ++ ++ /* config GDMA */ ++ HIF_DBG_TX(("[WiFi/HIF/DMA] Prepare to send data...\n")); ++ DmaConf.Count = Size; ++ DmaConf.Dir = HIF_DMA_DIR_TX; ++ DmaConf.Dst = HIF_DRV_BASE + Port; /* must be physical addr */ ++ ++#ifdef MTK_DMA_BUF_MEMCPY_SUP ++ DmaConf.Src = kalIOPhyAddrGet(Buf); /* must be physical addr */ ++ ++ /* TODO: use virt_to_phys() */ ++ if (DmaConf.Src == NULL) { ++ HIF_DBG_TX(("[WiFi/HIF] Use Dma Buffer to TX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); ++ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); ++ ++ kalDmaBufGet(&DmaVBuf, &DmaPBuf); ++ DmaConf.Src = (ULONG) DmaPBuf; ++ ++ kalMemCopy(DmaVBuf, Buf, Size); ++ } ++#else ++ ++ /* DMA_TO_DEVICE writeback the cache */ ++ DmaConf.Src = dma_map_single(HifInfo->Dev, Buf, Size, DMA_TO_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ /* start to write */ ++ AP_DMA_HIF_LOCK(HifInfo); ++ ++ prDmaOps->DmaClockCtrl(TRUE); ++ prDmaOps->DmaConfig(HifInfo, &DmaConf); ++ prDmaOps->DmaStart(HifInfo); ++ ++#if (CONF_HIF_DMA_INT == 1) ++ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); ++ if (RtnVal <= 0) ++ DBGLOG(TX, ERROR, "fatal error1! reset DMA!\n"); ++ HifInfo->HifDmaWaitFlg = 0; ++#else ++ ++ LoopCnt = 0; ++ PollTimeout = jiffies + HZ * 5; ++ ++ do { ++ if (time_before(jiffies, PollTimeout)) ++ continue; ++ DBGLOG(TX, INFO, "TX DMA Timeout, HSTCR: 0x%08x\n", u4HSTCRValue); ++ if (prDmaOps->DmaRegDump != NULL) ++ prDmaOps->DmaRegDump(HifInfo); ++ WlanDmaFatalErr = 1; ++ /* we still need complete dma progress even dma timeout */ ++ break; ++ } while (!prDmaOps->DmaPollIntr(HifInfo)); ++#endif /* CONF_HIF_DMA_INT */ ++ /* we should disable dma interrupt then clear dma interrupt, otherwise, ++ for dma timeout case, interrupt may be set after we clear it */ ++ prDmaOps->DmaStop(HifInfo); ++ prDmaOps->DmaAckIntr(HifInfo); ++ ++ LoopCnt = 0; ++ do { ++ if (LoopCnt++ > 100000) { ++ DBGLOG(TX, ERROR, "fatal error2! reset DMA!\n"); ++ break; ++ } ++ } while (prDmaOps->DmaPollStart(HifInfo) != 0); ++ ++ prDmaOps->DmaClockCtrl(FALSE); ++ ++ AP_DMA_HIF_UNLOCK(HifInfo); ++ ++#ifndef MTK_DMA_BUF_MEMCPY_SUP ++ dma_unmap_single(HifInfo->Dev, DmaConf.Src, Size, DMA_TO_DEVICE); ++#endif /* MTK_DMA_BUF_MEMCPY_SUP */ ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++ if (WlanDmaFatalErr) { ++ if (!fgIsResetting) ++ glDoChipReset(); ++ return FALSE; ++ } ++ HIF_DBG_TX(("[WiFi/HIF] DMA TX OK!\n")); ++ } else ++#endif /* CONF_MTK_AHB_DMA */ ++ { ++ UINT_32 IdLoop, MaxLoop; ++ UINT_32 *LoopBuf; ++ ++ /* PIO mode */ ++ MaxLoop = Size >> 2; ++ LoopBuf = (UINT_32 *) Buf; ++ ++ HIF_DBG_TX(("[WiFi/HIF/PIO] Prepare to send data (%d 0x%p-0x%p)...\n", ++ Size, LoopBuf, (((UINT8 *) LoopBuf) + (Size & (~0x03))))); ++ ++ if (Size & 0x3) ++ MaxLoop++; ++ ++ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { ++ HIF_REG_WRITEL(HifInfo, Port, *LoopBuf); ++ LoopBuf++; ++ } ++ ++ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); ++ ++ HIF_DBG_TX(("\n\n")); ++ } ++ ++ return TRUE; ++ ++} /* end of kalDevPortWrite() */ ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a SDIO interrupt callback function ++* ++* \param[in] func pointer to SDIO handle ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg) ++{ ++ struct net_device *prNetDevice = (struct net_device *)Arg; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ IsrCnt++; ++ ASSERT(prNetDevice); ++ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); ++ ASSERT(GlueInfo); ++ ++ if (!GlueInfo) ++ return IRQ_HANDLED; ++ ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ GlueInfo->IsrCnt++; ++ ++ if (GlueInfo->ulFlag & GLUE_FLAG_HALT) { ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ return IRQ_HANDLED; ++ } ++ ++ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); ++ ++ /* lock 100ms to avoid suspend */ ++ kalHifAhbKalWakeLockTimeout(GlueInfo); ++ ++ /* Wake up main thread */ ++ set_bit(GLUE_FLAG_INT_BIT, &GlueInfo->ulFlag); ++ ++ /* when we got sdio interrupt, we wake up the tx servie thread */ ++ wake_up_interruptible(&GlueInfo->waitq); ++ ++ IsrPassCnt++; ++ GlueInfo->IsrPassCnt++; ++ return IRQ_HANDLED; ++ ++} ++ ++#if (CONF_HIF_DMA_INT == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a SDIO interrupt callback function ++* ++* \param[in] func pointer to SDIO handle ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++ ++static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg) ++{ ++ struct net_device *prNetDevice = (struct net_device *)Arg; ++ GLUE_INFO_T *GlueInfo; ++ GL_HIF_INFO_T *HifInfo; ++ ++ /* Init */ ++ ASSERT(prNetDevice); ++ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); ++ ASSERT(GlueInfo); ++ ++ if (!GlueInfo) ++ return IRQ_HANDLED; ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ /* disable interrupt */ ++ HifInfo->DmaOps->DmaAckIntr(HifInfo); ++ ++ /* Wake up main thread */ ++ set_bit(1, &HifInfo->HifDmaWaitFlg); ++ ++ /* when we got sdio interrupt, we wake up the tx servie thread */ ++ wake_up_interruptible(&HifInfo->HifDmaWaitq); ++ ++ return IRQ_HANDLED; ++ ++} ++#endif /* CONF_HIF_DMA_INT */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is a SDIO probe function ++* ++* \param[in] func pointer to SDIO handle ++* \param[in] id pointer to SDIO device id table ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++#if defined(CONFIG_MTK_CLKMGR) ++#if defined(MTK_EXTERNAL_LDO) || defined(MTK_ALPS_BOX_SUPPORT) ++#include ++#endif ++#endif ++ ++static int HifAhbProbe(VOID) ++{ ++ int Ret = 0; ++ ++ DBGLOG(INIT, INFO, "HifAhbProbe()\n"); ++ ++ /* power on WiFi TX PA 3.3V and HIF GDMA clock */ ++ { ++#ifdef CONFIG_MTK_PMIC_MT6397 ++#if defined(CONFIG_MTK_CLKMGR) ++#ifdef MTK_EXTERNAL_LDO ++ /* for 8127 tablet */ ++ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_UP); ++#elif defined(MTK_ALPS_BOX_SUPPORT) ++ /* for 8127 box */ ++ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_UP); ++#else ++ hwPowerOn(MT65XX_POWER_LDO_VGP4, VOL_3300, "WLAN"); ++#endif ++#endif ++#else ++#ifdef CONFIG_OF /*for MT6752 */ ++ mtk_wcn_consys_hw_wifi_paldo_ctrl(1); /* switch to HW mode */ ++#else /*for MT6572/82/92 */ ++ hwPowerOn(MT6323_POWER_LDO_VCN33_WIFI, VOL_3300, "WLAN"); ++ upmu_set_vcn33_on_ctrl_wifi(1); /* switch to HW mode */ ++#endif ++#endif ++ ++ } ++ ++#if (CONF_HIF_DEV_MISC == 1) ++ if (pfWlanProbe((PVOID) &MtkAhbDriver.this_device) != WLAN_STATUS_SUCCESS) { ++#else ++ if (pfWlanProbe((PVOID) &HifAhbPDev->dev) != WLAN_STATUS_SUCCESS) { ++#endif /* CONF_HIF_DEV_MISC */ ++ ++ pfWlanRemove(); ++ Ret = -1; ++ } ++ ++ return Ret; ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function will do module remove. ++* ++* \param[in] None ++* ++* \return The result of remove (WLAN_STATUS_SUCCESS = 0) ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbRemove(VOID) ++{ ++ DBGLOG(INIT, INFO, "HifAhbRemove()\n"); ++ ++ pfWlanRemove(); ++ ++ { ++#ifdef CONFIG_MTK_PMIC_MT6397 ++#if defined(CONFIG_MTK_CLKMGR) ++#ifdef MTK_EXTERNAL_LDO ++ /* for 8127 tablet */ ++ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_DOWN); ++#elif defined(MTK_ALPS_BOX_SUPPORT) ++ /* for 8127 box */ ++ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); ++ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); ++ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); ++ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_DOWN); ++#else ++ hwPowerDown(MT65XX_POWER_LDO_VGP4, "WLAN"); ++#endif ++#endif ++#else ++#ifdef CONFIG_OF /*for MT6752 */ ++ mtk_wcn_consys_hw_wifi_paldo_ctrl(0); /* switch to SW mode */ ++#else /*for MT6572/82/92 */ ++ upmu_set_vcn33_on_ctrl_wifi(0); /* switch to SW mode */ ++ hwPowerDown(MT6323_POWER_LDO_VCN33_WIFI, "WLAN"); ++#endif ++#endif ++ ++ } ++ ++ return 0; ++} ++ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function gets the TX count pass through HIF AHB bus. ++* ++* \param[in] None ++* ++* \return TX count ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbBusCntGet(VOID) ++{ ++ return HifTxCnt; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function resets the TX count pass through HIF AHB bus. ++* ++* \param[in] None ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbBusCntClr(VOID) ++{ ++ HifTxCnt = 0; ++ return 0; ++} ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function configs the DMA TX/RX settings before any real TX/RX. ++* ++* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] BurstLen 0(1DW), 1(4DW), 2(8DW), Others(Reserved) ++* \param[in] PortId 0(TXD0), 1(TXD1), 2(RXD0), 3(RXD1), 4(WHISR enhance) ++* \param[in] TransByte Should be 4-byte align. ++* ++* \return void ++*/ ++/*----------------------------------------------------------------------------*/ ++static UINT_32 HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T * GlueInfo, UINT_32 BurstLen, UINT_32 PortId, UINT_32 TransByte) ++{ ++ GL_HIF_INFO_T *HifInfo; ++ UINT_32 RegHSTCR; ++ ++ ASSERT(GlueInfo); ++ HifInfo = &GlueInfo->rHifInfo; ++ ++ RegHSTCR = HIF_REG_READL(HifInfo, MCR_WHIER); ++ ++ RegHSTCR = HIF_REG_READL(HifInfo, MCR_HSTCR); ++ RegHSTCR = ++ ((BurstLen << HSTCR_AFF_BURST_LEN_OFFSET) & HSTCR_AFF_BURST_LEN) | ++ ((PortId << HSTCR_TRANS_TARGET_OFFSET) & HSTCR_TRANS_TARGET) | ++ (((TransByte & 0x3) == 0) ? (TransByte & HSTCR_HSIF_TRANS_CNT) : ((TransByte + 4) & HSTCR_HSIF_TRANS_CNT)); ++ HIF_REG_WRITEL(HifInfo, MCR_HSTCR, RegHSTCR); ++ return RegHSTCR; ++} ++ ++VOID glSetPowerState(IN GLUE_INFO_T *GlueInfo, IN UINT_32 ePowerMode) ++{ ++ ++} ++ ++#if (CONF_HIF_DEV_MISC == 1) ++/* no use */ ++static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos) ++{ ++ return 0; ++} ++ ++static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos) ++{ ++ return 0; ++} ++ ++static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg) ++{ ++ return 0; ++} ++ ++static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp) ++{ ++ return 0; ++} ++ ++static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp) ++{ ++ return 0; ++} ++#else ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbPltmProbe(IN struct platform_device *PDev) ++{ ++ HifAhbPDev = PDev; ++ ++ DBGLOG(INIT, INFO, "HifAhbPltmProbe\n"); ++ ++#if (CONF_HIF_PMIC_TEST == 1) ++ wmt_set_jtag_for_mcu(); ++ wmt_set_jtag_for_gps(); ++ ++#endif /* CONF_HIF_PMIC_TEST */ ++ ++#if (MTK_WCN_SINGLE_MODULE == 1) ++ HifAhbProbe(); /* only for test purpose without WMT module */ ++ ++#else ++ ++ /* register WiFi function to WMT */ ++ DBGLOG(INIT, INFO, "mtk_wcn_wmt_wlan_reg\n"); ++ { ++ MTK_WCN_WMT_WLAN_CB_INFO WmtCb; ++ ++ WmtCb.wlan_probe_cb = HifAhbProbe; ++ WmtCb.wlan_remove_cb = HifAhbRemove; ++ WmtCb.wlan_bus_cnt_get_cb = HifAhbBusCntGet; ++ WmtCb.wlan_bus_cnt_clr_cb = HifAhbBusCntClr; ++ mtk_wcn_wmt_wlan_reg(&WmtCb); ++ } ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int __exit HifAhbPltmRemove(IN struct platform_device *PDev) ++{ ++#if (MTK_WCN_SINGLE_MODULE == 0) ++ mtk_wcn_wmt_wlan_unreg(); ++#endif /* MTK_WCN_SINGLE_MODULE */ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* \param[in] Message ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message) ++{ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is called by OS platform device module. ++* ++* \param[in] PDev Pointer to the platform device structure. ++* ++* \return 0 ++*/ ++/*----------------------------------------------------------------------------*/ ++static int HifAhbPltmResume(IN struct platform_device *PDev) ++{ ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++#endif /* CONF_HIF_DEV_MISC */ ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Trigger to do HIF loopback test. ++* ++* \param[in] arg Pointer to the GLUE_INFO_T structure. ++* ++* \retval None ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifAhbLoopbkAuto(IN unsigned long arg) ++{ ++ ++ P_GLUE_INFO_T GlueInfo = (P_GLUE_INFO_T) arg; ++ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; ++ ++ ASSERT(GlueInfo); ++ ++ HIF_DBG(("[WiFi/HIF] Trigger to do loopback test...\n")); ++ ++ set_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &HifInfo->HifLoopbkFlg); ++ wake_up_interruptible(&HifInfo->HifWaitq); ++ ++} ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo) ++{ ++ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; ++ unsigned short j; ++ ++ for (j = 0; j < 512; j++) { ++ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(prHifInfo, CONN_MCU_CPUPCR)); ++ if ((j + 1) % 16 == 0) ++ DBGLOG(INIT, WARN, "\n"); ++ } ++} ++ ++/* End of ahb.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c +new file mode 100644 +index 000000000000..6b719028ae93 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c +@@ -0,0 +1,31 @@ ++/****************************************************************************** ++*[File] mt6516-evb.c ++*[Version] v1.0 ++*[Revision Date] 2010-03-01 ++*[Author] ++*[Description] ++* dummy file for build system ++*[Copyright] ++* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. ++******************************************************************************/ ++ ++/* ++** Log: mt6516-evb.c ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * remove debug message ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** ++*/ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h +new file mode 100644 +index 000000000000..1507d5560040 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h +@@ -0,0 +1,340 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 ++*/ ++ ++/*! \file "hif.h" ++ \brief Functions for the driver to register bus and setup the IRQ ++ ++ Functions for the driver to register bus and setup the IRQ ++*/ ++ ++/* ++** Log: hif.h ++ * ++ * 11 01 2010 yarco.yang ++ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform ++ * Add GPIO debug function ++ * ++ * 10 19 2010 jeffrey.chang ++ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK ++ * HIF by default ++ * Refine linux kernel module to the license of MTK and enable MTK HIF ++ * ++ * 08 18 2010 jeffrey.chang ++ * NULL ++ * support multi-function sdio ++ * ++ * 08 17 2010 cp.wu ++ * NULL ++ * add ENE SDIO host workaround for x86 linux platform. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\4 2009-10-20 17:38:28 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\3 2009-09-28 20:19:20 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\2 2009-08-18 22:57:05 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\2 2008-09-22 23:18:17 GMT mtk01461 ++** Update driver for code review ++** Revision 1.1 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++*/ ++ ++#ifndef _HIF_H ++#define _HIF_H ++ ++#include "gl_typedef.h" ++#include "mtk_porting.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++#define CONF_MTK_AHB_DMA 1 /* PIO mode is default mode if DMA is disabled */ ++ ++#define CONF_HIF_DEV_MISC 0 /* register as misc device */ ++#define CONF_HIF_LOOPBACK_AUTO 0 /* hif loopback test triggered by open() */ ++ /* only for development test */ ++ ++#define CONF_HIF_PMIC_TEST 0 /* test purpose: power on CONNSYS */ ++ ++#define CONF_HIF_DMA_INT 0 /* DMA interrupt mode */ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++extern phys_addr_t gConEmiPhyBase; ++extern BOOLEAN fgIsResetting; ++extern UINT_32 IsrCnt, IsrPassCnt; ++extern int kalDevLoopbkThread(IN void *data); ++ ++#ifdef CONFIG_MTK_PMIC_MT6397 ++#else ++#ifdef CONFIG_OF /*for MT6752 */ ++extern INT_32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT_32 enable); ++#else /*for MT6572/82/92 */ ++extern void upmu_set_vcn33_on_ctrl_wifi(UINT_32 val); ++#endif ++#endif ++ ++#if (CONF_HIF_DEV_MISC == 1) ++#else ++/* extern INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_en); */ ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#ifndef CONN_MCU_CONFIG_BASE ++#define CONN_MCU_CONFIG_BASE 0xF8070000 /* MT6572 */ ++#endif /* CONN_MCU_CONFIG_BASE */ ++ ++#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) ++#define CONSYS_REG_READ(addr) (*((volatile unsigned int *)(addr))) ++ ++#define CONN_MCU_DRV_BASE 0x18070000 ++#define CONN_MCU_REG_LENGTH 0x0200 ++#define CONN_MCU_CPUPCR 0x0160 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/* host interface's private data structure, which is attached to os glue ++** layer info structure. ++ */ ++typedef struct _GL_HIF_DMA_OPS_T { /* DMA Operators */ ++ VOID (*DmaConfig)(IN VOID *HifInfo, IN VOID *Conf); ++ ++ VOID (*DmaStart)(IN VOID *HifInfo); ++ ++ VOID (*DmaStop)(IN VOID *HifInfo); ++ ++ MTK_WCN_BOOL (*DmaPollStart)(IN VOID *HifInfo); ++ ++ MTK_WCN_BOOL (*DmaPollIntr)(IN VOID *HifInfo); ++ ++ VOID (*DmaAckIntr)(IN VOID *HifInfo); ++ ++ VOID (*DmaClockCtrl)(IN UINT_32 FlgIsEnabled); ++ ++ VOID (*DmaRegDump)(IN VOID *HifInfo); ++ ++ VOID (*DmaReset)(IN VOID *HifInfo); ++ ++} GL_HIF_DMA_OPS_T; ++ ++typedef struct _GL_HIF_INFO_T { ++ ++ /* General */ ++ VOID *Dev; /* struct device */ ++ ++#define MTK_CHIP_ID_6571 0x6571 ++#define MTK_CHIP_ID_6572 0x6572 ++#define MTK_CHIP_ID_6582 0x6582 ++#define MTK_CHIP_ID_8127 0x8127 ++#define MTK_CHIP_ID_6752 0x6752 ++#define MTK_CHIP_ID_8163 0x8163 ++#define MTK_CHIP_ID_6735 0x6735 ++#define MTK_CHIP_ID_6580 0x6580 ++#define MTK_CHIP_ID_6755 0x6755 ++#define MTK_CHIP_ID_7623 0x7623 ++ ++ UINT_32 ChipID; ++ ++ /* Control flag */ ++ BOOLEAN fgIntReadClear; ++ BOOLEAN fgMbxReadClear; ++ BOOLEAN fgDmaEnable; /* TRUE: DMA mode is used (default) */ ++ ++ /* HIF related */ ++ UINT_8 *HifRegBaseAddr; /* HIF register base */ ++ UINT_8 *McuRegBaseAddr; /* CONN MCU register base */ ++ ++#if (CONF_HIF_LOOPBACK_AUTO == 1) ++ struct timer_list HifTmrLoopbkFn; /* HIF loopback test trigger timer */ ++ wait_queue_head_t HifWaitq; ++ UINT_32 HifLoopbkFlg; ++ struct task_struct *HifTaskLoopbkFn; /* HIF loopback test task */ ++#endif /* CONF_HIF_LOOPBACK_AUTO */ ++ ++#if (CONF_HIF_DMA_INT == 1) ++ wait_queue_head_t HifDmaWaitq; ++ UINT_32 HifDmaWaitFlg; ++#endif /* CONF_HIF_DMA_INT */ ++ ++ /* DMA related */ ++#define AP_DMA_HIF_LOCK(_lock) /* spin_lock_bh(&(_lock)->DdmaLock) */ ++#define AP_DMA_HIF_UNLOCK(_lock) /* spin_unlock_bh(&(_lock)->DdmaLock) */ ++ spinlock_t DdmaLock; /* protect DMA access */ ++ ++ UINT_8 *DmaRegBaseAddr; /* DMA register base */ ++ GL_HIF_DMA_OPS_T *DmaOps; /* DMA Operators */ ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ struct clk *clk_wifi_dma; ++#endif ++} GL_HIF_INFO_T, *P_GL_HIF_INFO_T; ++ ++#define HIF_MOD_NAME "AHB_SLAVE_HIF" ++ ++#define HIF_DRV_BASE 0x180F0000 ++#define HIF_DRV_LENGTH 0x005c ++ ++typedef enum _MTK_WCN_HIF_BURST_LEN { ++ HIF_BURST_1DW = 0, ++ HIF_BURST_4DW, ++ HIF_BURST_8DW ++} MTK_WCN_HIF_BURST_LEN; ++ ++typedef enum _MTK_WCN_HIF_TXRX_TARGET { ++ HIF_TARGET_TXD0 = 0, ++ HIF_TARGET_TXD1, ++ HIF_TARGET_RXD0, ++ HIF_TARGET_RXD1, ++ HIF_TARGET_WHISR ++} MTK_WCN_HIF_TXRX_TARGET; ++ ++typedef enum _MTK_WCN_HIF_DMA_DIR { ++ HIF_DMA_DIR_TX = 0, ++ HIF_DMA_DIR_RX ++} MTK_WCN_HIF_DMA_DIR; ++ ++typedef struct _MTK_WCN_HIF_DMA_CONF { ++ UINT_32 Count; ++ MTK_WCN_HIF_DMA_DIR Dir; ++ UINT_32 Burst; ++ UINT_32 Wsize; ++ UINT_32 Ratio; ++ UINT_32 Connect; ++ UINT_32 Fix_en; ++ ULONG Src; ++ ULONG Dst; ++} MTK_WCN_HIF_DMA_CONF; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define MCU_REG_READL(_hif, _addr) \ ++ readl((volatile UINT_32 *)((_hif)->McuRegBaseAddr + _addr)) ++ ++/* PIO mode HIF register read/write */ ++#define HIF_REG_READL(_hif, _addr) \ ++ readl((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr)) ++ ++#define HIF_REG_WRITEL(_hif, _addr, _val) \ ++ writel(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) ++ ++#define HIF_REG_WRITEB(_hif, _addr, _val) \ ++ writeb(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) ++ ++/* PIO mode DMA register read/write */ ++#define HIF_DMAR_READL(_hif, _addr) \ ++ readl((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr)) ++ ++#define HIF_DMAR_WRITEL(_hif, _addr, _val) \ ++ writel(_val, ((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr))) ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#ifndef MODULE_AHB_DMA ++VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter); ++ ++VOID HifRegDump(P_ADAPTER_T prAdapter); ++ ++BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter); ++ ++WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove); ++ ++VOID glUnregisterBus(remove_card pfRemove); ++ ++VOID glResetHif(GLUE_INFO_T *GlueInfo); ++ ++VOID glSetHifInfo(P_GLUE_INFO_T prGlueInfo, ULONG ulCookie); ++ ++VOID glClearHifInfo(P_GLUE_INFO_T prGlueInfo); ++ ++VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf); ++ ++#if CFG_SPM_WORKAROUND_FOR_HOTSPOT ++BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo); ++#endif ++ ++BOOLEAN glBusInit(PVOID pvData); ++ ++VOID glBusRelease(PVOID pData); ++ ++INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie); ++ ++VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie); ++ ++VOID glSetPowerState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 ePowerMode); ++ ++VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo); ++ ++#endif /* MODULE_AHB_DMA */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config GDMA TX/RX. ++* ++* \param[in] DmaRegBaseAddr Pointer to the IO register base. ++* \param[in] Conf Pointer to the DMA operator. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID HifGdmaInit(GL_HIF_INFO_T *HifInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config PDMA TX/RX. ++* ++* \param[in] DmaRegBaseAddr Pointer to the IO register base. ++* \param[in] Conf Pointer to the DMA operator. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _HIF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h +new file mode 100644 +index 000000000000..094c07f98eff +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h +@@ -0,0 +1,154 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 ++*/ ++ ++/*! \file "hif_gdma.h" ++ \brief MARCO, definition, structure for GDMA. ++ ++ MARCO, definition, structure for GDMA. ++*/ ++ ++/* ++** Log: hif_gdma.h ++ * ++ * 01 16 2013 vend_samp.lin ++ * Add AHB GDMA support ++ * 1) Initial version ++** ++*/ ++ ++#ifndef _HIF_GDMA_H ++#define _HIF_GDMA_H ++ ++#include "mtk_porting.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _MTK_WCN_HIF_GDMA_BURST_LEN { ++ HIF_GDMA_BURST_1_8 = 0, ++ HIF_GDMA_BURST_2_8, ++ HIF_GDMA_BURST_3_8, ++ HIF_GDMA_BURST_4_8, ++ HIF_GDMA_BURST_5_8, ++ HIF_GDMA_BURST_6_8, ++ HIF_GDMA_BURST_7_8, ++ HIF_GDMA_BURST_8_8 /* same as HIF_GDMA_BURST_7_8 */ ++} MTK_WCN_HIF_GDMA_BURST_LEN; ++ ++typedef enum _MTK_WCN_HIF_GDMA_WRITE_LEN { ++ HIF_GDMA_WRITE_0 = 0, /* transaction size is 1 byte */ ++ HIF_GDMA_WRITE_1, /* transaction size is 2 byte */ ++ HIF_GDMA_WRITE_2, /* transaction size is 4 byte */ ++ HIF_GDMA_WRITE_3 /* transaction size is 1 byte */ ++} MTK_WCN_HIF_GDMA_WRITE_LEN; ++ ++typedef enum _MTK_WCN_HIF_GDMA_RATIO { ++ HIF_GDMA_RATIO_0 = 0, /* 1/2 */ ++ HIF_GDMA_RATIO_1 /* 1/1 */ ++} MTK_WCN_HIF_GDMA_RATIO; ++ ++typedef enum _MTK_WCN_HIF_GDMA_CONNECT { ++ HIF_GDMA_CONNECT_NO = 0, /* no connect */ ++ HIF_GDMA_CONNECT_SET1, /* connect set1 (req/ack) */ ++ HIF_GDMA_CONNECT_SET2, /* connect set2 (req/ack) */ ++ HIF_GDMA_CONNECT_SET3 /* connect set3 (req/ack) */ ++} MTK_WCN_HIF_GDMA_CONNECT; ++ ++/* reference to MT6572_AP_P_DMA_Spec.doc */ ++#define AP_DMA_HIF_BASE 0x11000100 ++ ++#define AP_P_DMA_G_DMA_2_INT_FLAG (0x0000) ++#define AP_P_DMA_G_DMA_2_CON (0x0018) ++#define AP_P_DMA_G_DMA_2_CONNECT (0x0034) ++#define AP_P_DMA_G_DMA_2_LEN1 (0x0024) ++#define AP_P_DMA_G_DMA_2_SRC_ADDR (0x001C) ++#define AP_P_DMA_G_DMA_2_DST_ADDR (0x0020) ++#define AP_P_DMA_G_DMA_2_INT_EN (0x0004) ++#define AP_P_DMA_G_DMA_2_EN (0x0008) ++#define AP_P_DMA_G_DMA_2_RST (0x000C) ++#define AP_P_DMA_G_DMA_2_STOP (0x0010) ++ ++#define AP_DMA_HIF_0_LENGTH 0x0038 ++ ++/* AP_DMA_HIF_0_INT_FLAG */ ++#define ADH_CR_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_INT_EN */ ++#define ADH_CR_INTEN_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_EN */ ++#define ADH_CR_EN BIT(0) ++#define ADH_CR_CONN_BUR_EN BIT(1) ++ ++/* AP_DMA_HIF_0_STOP */ ++#define ADH_CR_PAUSE BIT(1) ++#define ADH_CR_STOP BIT(0) ++ ++/* AP_P_DMA_G_DMA_2_CON */ ++#define ADH_CR_FLAG_FINISH BIT(30) ++#define ADH_CR_RSIZE BITS(28, 29) ++#define ADH_CR_RSIZE_OFFSET 28 ++#define ADH_CR_WSIZE BITS(24, 25) ++#define ADH_CR_WSIZE_OFFSET 24 ++#define ADH_CR_BURST_LEN BITS(16, 18) ++#define ADH_CR_BURST_LEN_OFFSET 16 ++#define ADH_CR_WADDR_FIX_EN BIT(3) ++#define ADH_CR_WADDR_FIX_EN_OFFSET 3 ++#define ADH_CR_RADDR_FIX_EN BIT(4) ++#define ADH_CR_RADDR_FIX_EN_OFFSET 4 ++ ++/* AP_P_DMA_G_DMA_2_CONNECT */ ++#define ADH_CR_RATIO BIT(3) ++#define ADH_CR_RATIO_OFFSET 3 ++#define ADH_CR_DIR BIT(2) ++#define ADH_CR_DIR_OFFSET 2 ++#define ADH_CR_CONNECT BITS(0, 1) ++ ++/* AP_DMA_HIF_0_LEN */ ++#define ADH_CR_LEN BITS(0, 19) ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _HIF_GDMA_H */ ++ ++/* End of hif_gdma.h */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h +new file mode 100644 +index 000000000000..32224e8f17d8 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h +@@ -0,0 +1,141 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 ++*/ ++ ++/*! \file "hif_pdma.h" ++ \brief MARCO, definition, structure for PDMA. ++ ++ MARCO, definition, structure for PDMA. ++*/ ++ ++/* ++** Log: hif_pdma.h ++ * ++ * 01 16 2013 vend_samp.lin ++ * Add AHB PDMA support ++ * 1) Initial version ++** ++*/ ++ ++#ifndef _HIF_PDMA_H ++#define _HIF_PDMA_H ++ ++#include "mtk_porting.h" ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++typedef enum _MTK_WCN_HIF_PDMA_BURST_LEN { ++ HIF_PDMA_BURST_1_4 = 0, ++ HIF_PDMA_BURST_2_4, ++ HIF_PDMA_BURST_3_4, ++ HIF_PDMA_BURST_4_4 ++} MTK_WCN_HIF_PDMA_BURST_LEN; ++ ++/* reference to MT6572_AP_P_DMA_Spec.doc */ ++#ifdef CONFIG_OF ++/*for MT6752*/ ++#define AP_DMA_HIF_BASE 0x11000080 ++#else ++/*for MT6572/82/92*/ ++#define AP_DMA_HIF_BASE 0x11000180 ++#endif ++ ++#define AP_DMA_HIF_0_INT_FLAG (0x0000) ++#define AP_DMA_HIF_0_INT_EN (0x0004) ++#define AP_DMA_HIF_0_EN (0x0008) ++#define AP_DMA_HIF_0_RST (0x000C) ++#define AP_DMA_HIF_0_STOP (0x0010) ++#define AP_DMA_HIF_0_FLUSH (0x0014) ++#define AP_DMA_HIF_0_CON (0x0018) ++#define AP_DMA_HIF_0_SRC_ADDR (0x001C) ++#define AP_DMA_HIF_0_DST_ADDR (0x0020) ++#define AP_DMA_HIF_0_LEN (0x0024) ++#define AP_DMA_HIF_0_INT_BUF_SIZE (0x0038) ++#define AP_DMA_HIF_0_DEBUG_STATUS (0x0050) ++#define AP_DMA_HIF_0_SRC_ADDR2 (0x0054) ++#define AP_DMA_HIF_0_DST_ADDR2 (0x0058) ++ ++#define AP_DMA_HIF_0_LENGTH 0x0080 ++ ++/* AP_DMA_HIF_0_INT_FLAG */ ++#define ADH_CR_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_INT_EN */ ++#define ADH_CR_INTEN_FLAG_0 BIT(0) ++ ++/* AP_DMA_HIF_0_EN */ ++#define ADH_CR_EN BIT(0) ++ ++/* AP_DMA_HIF_0_RST */ ++#define ADH_CR_HARD_RST BIT(1) ++#define ADH_CR_WARM_RST BIT(0) ++ ++/* AP_DMA_HIF_0_STOP */ ++#define ADH_CR_PAUSE BIT(1) ++#define ADH_CR_STOP BIT(0) ++ ++/* AP_DMA_HIF_0_FLUSH */ ++#define ADH_CR_FLUSH BIT(0) ++ ++/* AP_DMA_HIF_0_CON */ ++#define ADH_CR_BURST_LEN BITS(16, 17) ++#define ADH_CR_BURST_LEN_OFFSET 16 ++#define ADH_CR_SLOW_CNT BITS(5, 14) ++#define ADH_CR_SLOW_EN BIT(2) ++#define ADH_CR_FIX_EN BIT(1) ++#define ADH_CR_FIX_EN_OFFSET 1 ++#define ADH_CR_DIR BIT(0) ++ ++/* AP_DMA_HIF_0_LEN */ ++#define ADH_CR_LEN BITS(0, 19) ++ ++/* AP_DMA_HIF_0_SRC_ADDR2 */ ++#define ADH_CR_SRC_ADDR2 BIT(0) ++/* AP_DMA_HIF_0_DST_ADDR2 */ ++#define ADH_CR_DST_ADDR2 BIT(0) ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++#endif /* _HIF_PDMA_H */ ++ ++/* End of hif_gdma.h */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h +new file mode 100644 +index 000000000000..91557137af9a +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h +@@ -0,0 +1,91 @@ ++/* porting layer */ ++/* Android */ ++ ++#ifndef _MTK_PORTING_H_ ++#define _MTK_PORTING_H_ ++ ++#include /* include stddef.h for NULL */ ++ ++#define CONF_MTK_AHB_DMA 1 ++ ++/* Type definition for signed integers */ ++/*typedef signed char INT8, *PINT8; ++typedef signed short INT16, *PINT16; ++typedef signed int INT_32, *PINT32;*/ ++ ++/* Type definition for unsigned integers */ ++/*typedef unsigned char UINT8, *PUINT8; ++typedef unsigned short UINT16, *PUINT16; ++typedef unsigned int UINT32, *PUINT32;*/ ++ ++#ifndef VOID ++/*typedef void VOID, *PVOID;*/ ++#endif ++ ++#ifndef IN ++#define IN ++#endif ++ ++#ifndef OUT ++#define OUT ++#endif ++ ++#ifndef INTOUT ++#define INOUT ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef BIT ++#define BIT(n) ((UINT_32) 1U << (n)) ++#endif /* BIT */ ++ ++#ifndef BITS ++/* bits range: for example BITS(16,23) = 0xFF0000 ++ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 ++ * ==> (BIT(n+1)-1) = 0x00FFFFFF ++ */ ++#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) ++#endif /* BIT */ ++ ++#ifndef BOOLEAN ++#define BOOLEAN unsigned char ++#endif ++ ++typedef int MTK_WCN_BOOL; ++#ifndef MTK_WCN_BOOL_TRUE ++#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) ++#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) ++#endif ++ ++typedef int MTK_WCN_MUTEX; ++ ++typedef int MTK_WCN_TIMER; ++ ++/* system APIs */ ++/* mutex */ ++typedef MTK_WCN_MUTEX(*MUTEX_CREATE) (const char *const name); ++typedef INT_32(*MUTEX_DESTROY) (MTK_WCN_MUTEX mtx); ++typedef INT_32(*MUTEX_LOCK) (MTK_WCN_MUTEX mtx); ++typedef INT_32(*MUTEX_UNLOCK) (MTK_WCN_MUTEX mtx, unsigned long flags); ++/* debug */ ++typedef INT_32(*DBG_PRINT) (const char *str, ...); ++typedef INT_32(*DBG_ASSERT) (INT_32 expr, const char *file, INT_32 line); ++/* timer */ ++typedef void (*MTK_WCN_TIMER_CB) (void); ++typedef MTK_WCN_TIMER(*TIMER_CREATE) (const char *const name); ++typedef INT_32(*TIMER_DESTROY) (MTK_WCN_TIMER tmr); ++typedef INT_32(*TIMER_START) (MTK_WCN_TIMER tmr, UINT_32 timeout, MTK_WCN_TIMER_CB tmr_cb, void *param); ++typedef INT_32(*TIMER_STOP) (MTK_WCN_TIMER tmr); ++/* kernel lib */ ++typedef void *(*SYS_MEMCPY) (void *dest, const void *src, UINT_32 n); ++typedef void *(*SYS_MEMSET) (void *s, INT_32 c, UINT_32 n); ++typedef INT_32(*SYS_SPRINTF) (char *str, const char *format, ...); ++ ++#endif /* _MTK_PORTING_H_ */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c +new file mode 100644 +index 000000000000..94cc05ba3224 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c +@@ -0,0 +1,480 @@ ++/****************************************************************************** ++*[File] ahb_pdma.c ++*[Version] v1.0 ++*[Revision Date] 2013-03-13 ++*[Author] ++*[Description] ++* The program provides AHB PDMA driver ++*[Copyright] ++* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. ++******************************************************************************/ ++ ++/* ++** Log: ahb_pdma.c ++ * ++ * 03 13 2013 vend_samp.lin ++ * Add AHB PDMA support ++ * 1) Initial version ++** ++*/ ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#define MODULE_AHB_DMA ++ ++#include /* constant of kernel version */ ++ ++#include /* bitops.h */ ++ ++#include /* struct timer_list */ ++#include /* jiffies */ ++#include /* udelay and mdelay macro */ ++ ++#if 0 ++#if CONFIG_ANDROID ++#include ++#endif ++#endif ++ ++#include /* IRQT_FALLING */ ++ ++#include /* struct net_device, struct net_device_stats */ ++#include /* for eth_type_trans() function */ ++#include /* struct iw_statistics */ ++#include ++#include /* struct in_device */ ++ ++#include /* struct iphdr */ ++ ++#include /* for memcpy()/memset() function */ ++#include /* for offsetof() macro */ ++ ++#include /* The proc filesystem constants/structures */ ++ ++#include /* for rtnl_lock() and rtnl_unlock() */ ++#include /* kthread_should_stop(), kthread_run() */ ++#include /* for copy_from_user() */ ++#include /* for firmware download */ ++#include ++ ++#include /* for kfifo interface */ ++#include /* for cdev interface */ ++ ++#include /* for firmware download */ ++ ++#include ++ ++#include /* readw and writew */ ++ ++#include ++ ++#if defined(CONFIG_MTK_CLKMGR) ++#include ++#else ++#include ++#endif /* defined(CONFIG_MTK_CLKMGR) */ ++ ++#include "hif.h" ++#include "hif_pdma.h" ++#include "gl_os.h" ++ ++/* #include */ ++ ++/* #if (CONF_MTK_AHB_DMA == 1) */ ++ ++/* #define PDMA_DEBUG_SUP */ ++ ++#ifdef PDMA_DEBUG_SUP ++#define PDMA_DBG pr_debug ++#else ++#define PDMA_DBG(_fmt, ...) ++#endif /* PDMA_DEBUG_SUP */ ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++struct clk *g_clk_wifi_pdma; ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Conf); ++ ++static VOID HifPdmaStart(IN void *HifInfoSrc); ++ ++static VOID HifPdmaStop(IN void *HifInfoSrc); ++ ++static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc); ++ ++static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc); ++ ++static VOID HifPdmaAckIntr(IN void *HifInfoSrc); ++ ++static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled); ++ ++static VOID HifPdmaRegDump(IN void *HifInfoSrc); ++ ++static VOID HifPdmaReset(IN void *HifInfoSrc); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++GL_HIF_DMA_OPS_T HifPdmaOps = { ++ .DmaConfig = HifPdmaConfig, ++ .DmaStart = HifPdmaStart, ++ .DmaStop = HifPdmaStop, ++ .DmaPollStart = HifPdmaPollStart, ++ .DmaPollIntr = HifPdmaPollIntr, ++ .DmaAckIntr = HifPdmaAckIntr, ++ .DmaClockCtrl = HifPdmaClockCtrl, ++ .DmaRegDump = HifPdmaRegDump, ++ .DmaReset = HifPdmaReset ++}; ++ ++/******************************************************************************* ++* P U B L I C F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config PDMA TX/RX. ++* ++* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. ++* \param[in] Conf Pointer to the settings. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo) ++{ ++ /* IO remap PDMA register memory */ ++#ifdef AP_DMA_HIF_BASE ++#undef AP_DMA_HIF_BASE ++#define AP_DMA_HIF_BASE 0x11000180 ++#endif ++ HifInfo->DmaRegBaseAddr = ioremap(AP_DMA_HIF_BASE, AP_DMA_HIF_0_LENGTH); ++ ++ /* assign PDMA operators */ ++ HifInfo->DmaOps = &HifPdmaOps; ++ ++ /* enable PDMA mode */ ++ HifInfo->fgDmaEnable = TRUE; ++ ++ /* Set EMI protection here */ ++#if 0 ++#ifdef MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT ++ DBGLOG(INIT, INFO, "WIFI set EMI MPU for TEE project\n"); ++ emi_mpu_set_region_protection(gConEmiPhyBase, ++ gConEmiPhyBase + SZ_1M / 2, ++ 5, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); ++#else ++ DBGLOG(INIT, INFO, "WIFI set EMI MPU for non-TEE project\n"); ++ emi_mpu_set_region_protection(gConEmiPhyBase, ++ gConEmiPhyBase + SZ_1M / 2, ++ 4, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); ++#endif ++#endif ++ ++#if !defined(CONFIG_MTK_CLKMGR) ++ g_clk_wifi_pdma = HifInfo->clk_wifi_dma; ++#endif ++ ++ PDMA_DBG("PDMA> HifPdmaInit ok!\n"); ++} ++ ++/******************************************************************************* ++* P R I V A T E F U N C T I O N S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Config PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* \param[in] Param Pointer to the settings. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Param) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *) Param; ++ UINT32 RegVal; ++ ++ /* Assign fixed value */ ++ Conf->Burst = HIF_PDMA_BURST_4_4; /* vs. HIF_BURST_4DW */ ++ Conf->Fix_en = FALSE; ++ ++ /* AP_P_DMA_G_DMA_2_CON */ ++ PDMA_DBG("PDMA> Conf->Dir = %d\n", Conf->Dir); ++ ++ /* AP_DMA_HIF_0_CON */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_CON); ++ RegVal &= ~(ADH_CR_BURST_LEN | ADH_CR_FIX_EN | ADH_CR_DIR); ++ RegVal |= (((Conf->Burst << ADH_CR_BURST_LEN_OFFSET) & ADH_CR_BURST_LEN) | ++ (Conf->Fix_en << ADH_CR_FIX_EN_OFFSET) | (Conf->Dir)); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_CON, RegVal); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_CON = 0x%08x\n", RegVal); ++ ++ /* AP_DMA_HIF_0_SRC_ADDR */ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_SRC_ADDR, Conf->Src); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_SRC_ADDR = 0x%08lx\n", Conf->Src); ++ ++ /* AP_DMA_HIF_0_DST_ADDR */ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_DST_ADDR, Conf->Dst); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_DST_ADDR = 0x%08lx\n", Conf->Dst); ++ ++ /* AP_DMA_HIF_0_LEN */ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_LEN, (Conf->Count & ADH_CR_LEN)); ++ PDMA_DBG("PDMA> AP_DMA_HIF_0_LEN = %u\n", (UINT_32)(Conf->Count & ADH_CR_LEN)); ++ ++} /* End of HifPdmaConfig */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Start PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaStart(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ /* Enable interrupt */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0)); ++ ++ /* Start DMA */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_EN, (RegVal | ADH_CR_EN)); ++ ++ PDMA_DBG("PDMA> HifPdmaStart...\n"); ++ ++} /* End of HifPdmaStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Stop PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaStop(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++/* UINT32 pollcnt; */ ++ ++ /* Disable interrupt */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal & ~(ADH_CR_INTEN_FLAG_0))); ++ ++#if 0 /* DE says we donot need to do it */ ++ /* Stop DMA */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_STOP); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_STOP, (RegVal | ADH_CR_STOP)); ++ ++ /* Polling START bit turn to 0 */ ++ pollcnt = 0; ++ do { ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); ++ if (pollcnt++ > 100000) ++ ; /* TODO: warm reset PDMA */ ++ } while (RegVal & ADH_CR_EN); ++#endif ++ ++} /* End of HifPdmaStop */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Enable PDMA TX/RX. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); ++ return ((RegVal & ADH_CR_EN) != 0) ? TRUE : FALSE; ++ ++} /* End of HifPdmaPollStart */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Poll PDMA TX/RX done. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); ++ return ((RegVal & ADH_CR_FLAG_0) != 0) ? TRUE : FALSE; ++ ++} /* End of HifPdmaPollIntr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Acknowledge PDMA TX/RX done. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaAckIntr(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegVal; ++ ++ /* Write 0 to clear interrupt */ ++ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0)); ++ ++} /* End of HifPdmaAckIntr */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Acknowledge PDMA TX/RX done. ++* ++* \param[in] FlgIsEnabled TRUE: enable; FALSE: disable ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled) ++{ ++#if !defined(CONFIG_MTK_CLKMGR) ++ int ret = 0; ++#endif ++#if defined(CONFIG_MTK_CLKMGR) ++ if (FlgIsEnabled == TRUE) ++ enable_clock(MT_CG_INFRA_APDMA, "WLAN"); ++ else ++ disable_clock(MT_CG_INFRA_APDMA, "WLAN"); ++#else ++ if (FlgIsEnabled == TRUE) { ++ ret = clk_prepare_enable(g_clk_wifi_pdma); ++ if (ret) ++ DBGLOG(INIT, TRACE, "[CCF]clk_prepare_enable ret= %d\n", ret); ++ } else { ++ clk_disable_unprepare(g_clk_wifi_pdma); ++ } ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Dump PDMA related registers. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaRegDump(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 RegId, RegVal; ++ UINT32 RegNum = 0; ++ ++ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE); ++ for (RegId = 0; RegId < AP_DMA_HIF_0_LENGTH; RegId += 4) { ++ RegVal = HIF_DMAR_READL(HifInfo, RegId); ++ DBGLOG(INIT, INFO, "0x%08x ", RegVal); ++ ++ if (RegNum++ >= 3) { ++ DBGLOG(INIT, INFO, "\n"); ++ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE + RegId + 4); ++ RegNum = 0; ++ } ++ } ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Reset DMA. ++* ++* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. ++* ++* \retval NONE ++*/ ++/*----------------------------------------------------------------------------*/ ++static VOID HifPdmaReset(IN void *HifInfoSrc) ++{ ++ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; ++ UINT32 LoopCnt; ++ ++ /* do warm reset: DMA will wait for current traction finished */ ++ DBGLOG(INIT, INFO, "\nDMA> do warm reset...\n"); ++ ++ /* normally, we need to sure that bit0 of AP_P_DMA_G_DMA_2_EN is 1 here */ ++ ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x01); ++ ++ for (LoopCnt = 0; LoopCnt < 10000; LoopCnt++) { ++ if (!HifPdmaPollStart(HifInfo)) ++ break; /* reset ok */ ++ } ++ ++ if (HifPdmaPollStart(HifInfo)) { ++ /* do hard reset because warm reset fails */ ++ DBGLOG(INIT, INFO, "\nDMA> do hard reset...\n"); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x02); ++ mdelay(1); ++ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x00); ++ } ++} ++ ++/* #endif */ /* CONF_MTK_AHB_DMA */ ++ ++/* End of ahb_pdma.c */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h +new file mode 100644 +index 000000000000..ec9f46bdab2e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h +@@ -0,0 +1,341 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_cfg80211.h#1 ++*/ ++ ++/*! \file gl_cfg80211.h ++ \brief This file is for Portable Driver linux cfg80211 support. ++*/ ++ ++/* ++** Log: gl_cfg80211.h ++** ++** 09 03 2013 cp.wu ++** add path for reassociation ++** ++** 09 12 2012 wcpadmin ++** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages ++** . ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++*/ ++ ++#ifndef _GL_CFG80211_H ++#define _GL_CFG80211_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++ ++#include "gl_os.h" ++extern void wlanHandleSystemResume(void); ++extern void wlanHandleSystemSuspend(void); ++extern void p2pHandleSystemResume(void); ++extern void p2pHandleSystemSuspend(void); ++ ++#if CFG_SUPPORT_WAPI ++extern UINT_8 keyStructBuf[1024]; /* add/remove key shared buffer */ ++#else ++extern UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ ++#endif ++ ++extern struct delayed_work sched_workq; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#if CONFIG_NL80211_TESTMODE ++#define NL80211_DRIVER_TESTMODE_VERSION 2 ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++#if CONFIG_NL80211_TESTMODE ++ ++typedef struct _NL80211_DRIVER_GET_STA_STATISTICS_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 u4Version; ++ UINT_32 u4Flag; ++ UINT_8 aucMacAddr[MAC_ADDR_LEN]; ++} NL80211_DRIVER_GET_STA_STATISTICS_PARAMS, *P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS; ++ ++typedef struct _NL80211_DRIVER_POORLINK_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ INT_8 cRssi; /* cRssi=0 means it is a invalid value. */ ++ UINT_8 ucLinkSpeed; /* ucLinkSpeed=0 means it is a invalid value */ ++ UINT_16 u2Reserved; ++} NL80211_DRIVER_POORLINK_PARAMS, *P_NL80211_DRIVER_POORLINK_PARAMS; ++ ++typedef enum _ENUM_TESTMODE_STA_STATISTICS_ATTR { ++ NL80211_TESTMODE_STA_STATISTICS_INVALID = 0, ++ NL80211_TESTMODE_STA_STATISTICS_VERSION, ++ NL80211_TESTMODE_STA_STATISTICS_MAC, ++ NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, ++ NL80211_TESTMODE_STA_STATISTICS_FLAG, ++ ++ NL80211_TESTMODE_STA_STATISTICS_PER, ++ NL80211_TESTMODE_STA_STATISTICS_RSSI, ++ NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, ++ NL80211_TESTMODE_STA_STATISTICS_TX_RATE, ++ ++ NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, ++ ++ NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, ++ NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, ++ NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, ++ NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, ++ ++ NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, ++ ++ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, ++ ++ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, ++ ++ /* ++ * how many packages TX during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, ++ ++ /* ++ * how many packages this TX during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, ++ ++ /* ++ * how many packages dequeue during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, ++ ++ /* ++ * how many packages this sta dequeue during statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, ++ ++ /* ++ * how many TC[0-3] resource back from firmware during ++ * statistics interval ++ */ ++ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, ++ NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, ++ ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, ++ NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, ++ ++ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, ++ ++ NL80211_TESTMODE_STA_STATISTICS_NUM ++} ENUM_TESTMODE_STA_STATISTICS_ATTR; ++typedef struct _NL80211_DRIVER_SET_NFC_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 NFC_Enable; ++ ++} NL80211_DRIVER_SET_NFC_PARAMS, *P_NL80211_DRIVER_SET_NFC_PARAMS; ++typedef struct _NL80211_DRIVER_GET_SCANDONE_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 u4ScanDone; ++ ++} NL80211_DRIVER_GET_SCANDONE_PARAMS, *P_NL80211_DRIVER_GET_SCANDONE_PARAMS; ++ ++typedef enum _ENUM_TESTMODE_LINK_DETECTION_ATTR { ++ NL80211_TESTMODE_LINK_INVALID = 0, ++ NL80211_TESTMODE_LINK_TX_FAIL_CNT, ++ NL80211_TESTMODE_LINK_TX_RETRY_CNT, ++ NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, ++ NL80211_TESTMODE_LINK_ACK_FAIL_CNT, ++ NL80211_TESTMODE_LINK_FCS_ERR_CNT, ++ ++ NL80211_TESTMODE_LINK_DETECT_NUM, ++} ENUM_TESTMODE_LINK_DETECTION_ATTR; ++ ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++ ++typedef struct _NL80211_DRIVER_GET_LTE_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_32 u4Version; ++ UINT_32 u4Flag; ++ ++} NL80211_DRIVER_GET_LTE_PARAMS, *P_NL80211_DRIVER_GET_LTE_PARAMS; ++ ++/*typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR{ ++ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, ++ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, ++ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, ++ ++ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, ++}ENUM_TESTMODE_AVAILABLE_CHAN_ATTR;*/ ++ ++#endif ++#endif ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* cfg80211 hooks */ ++int ++mtk_cfg80211_change_iface(struct wiphy *wiphy, ++ struct net_device *ndev, enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); ++ ++int ++mtk_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); ++ ++int ++mtk_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) ++); ++ ++int ++mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); ++ ++int ++mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast); ++ ++int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); ++ ++int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo); ++ ++int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params); ++ ++int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_parameters *params); ++ ++int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params); ++//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac); ++ ++int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); ++ ++int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme); ++ ++int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code); ++ ++int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params); ++ ++int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev); ++ ++int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout); ++ ++int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); ++ ++int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); ++ ++int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev); ++ ++int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, ++ unsigned int duration, u64 *cookie); ++ ++int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); ++ ++int ++mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie); ++ ++void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, ++ IN struct wireless_dev *wdev, ++ IN u16 frame_type, IN bool reg); ++ ++int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); ++ ++int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req); ++ ++int ++mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, ++ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request); ++ ++int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev,u64 reqid); ++ ++#if CONFIG_NL80211_TESTMODE ++#if CFG_AUTO_CHANNEL_SEL_SUPPORT ++WLAN_STATUS ++wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, ++ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); ++ ++int ++mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); ++#endif ++int ++mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, ++ IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); ++ ++int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); ++ ++int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); ++ ++int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#if CFG_SUPPORT_WAPI ++int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++#else ++#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" ++#endif ++int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); ++int mtk_cfg80211_resume(struct wiphy *wiphy); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_CFG80211_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h +new file mode 100644 +index 000000000000..1406905095e6 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h +@@ -0,0 +1,1565 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_kal.h#1 ++*/ ++ ++/*! \file gl_kal.h ++ \brief Declaration of KAL functions - kal*() which is provided by GLUE Layer. ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/* ++** Log: gl_kal.h ++ * ++ * 06 13 2012 yuche.tsai ++ * NULL ++ * Update maintrunk driver. ++ * Add support for driver compose assoc request frame. ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Snc CFG80211 modification for ICS migration from branch 2.2. ++ * ++ * 02 06 2012 wh.su ++ * [WCXRP00001177] [MT6620 Wi-Fi][Driver][2.2] Adding the query channel filter for AP mode ++ * adding the channel query filter for AP mode. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 11 24 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adjust the code for Non-DBG and no XLOG. ++ * ++ * 11 22 2011 cp.wu ++ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to asynchronous ++ * approach to avoid incomplete state termination ++ * 1. change RDD related compile option brace position. ++ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state without join ++ * timeout timer ticking ++ * 3. otherwise, insert AIS_REQUEST into pending request queue ++ * ++ * 11 11 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * modify the xlog related code. ++ * ++ * 11 10 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Modify the QM xlog level and remove LOG_FUNC. ++ * ++ * 11 10 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Using the new XLOG define for dum Memory. ++ * ++ * 11 08 2011 eddie.chen ++ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) ++ * Add xlog function. ++ * ++ * 11 08 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters, eCurPsProf, for PS. ++ * ++ * 11 08 2011 cm.chang ++ * NULL ++ * Add RLM and CNM debug message for XLOG ++ * ++ * 11 07 2011 tsaiyuan.hsu ++ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered ++ * add debug counters and periodically dump counters for debugging. ++ * ++ * 11 03 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * Add dumpMemory8 at XLOG support. ++ * ++ * 11 02 2011 wh.su ++ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG ++ * adding the code for XLOG. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated ++ * network type ++ * include link.h for linux's port. ++ * ++ * 04 12 2011 cp.wu ++ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated ++ * network type ++ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected ++ * ++ * 04 01 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface ++ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR ++ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 ++ * ++ * 03 16 2011 cp.wu ++ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage ++ * after system running for a long period ++ * 1. pre-allocate physical continuous buffer while module is being loaded ++ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer ++ * ++ * The windows part remained the same as before, but added similar APIs to hide the difference. ++ * ++ * 03 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Add BOW table. ++ * ++ * 03 07 2011 terry.wu ++ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message ++ * Toggle non-standard debug messages to comments. ++ * ++ * 03 06 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Sync BOW Driver to latest person development branch version.. ++ * ++ * 03 02 2011 cp.wu ++ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after ++ * connection is built. ++ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. ++ * ++ * 02 24 2011 cp.wu ++ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep ++ * long enough for specified interval such as 500ms ++ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 04 2011 cp.wu ++ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease ++ * physically continuous memory demands ++ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure ++ * ++ * 12 31 2010 cp.wu ++ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system ++ * scheduling ++ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being ++ * loaded ++ * ++ * 12 31 2010 jeffrey.chang ++ * [WCXRP00000332] [MT6620 Wi-Fi][Driver] add kal sleep function for delay which use blocking call ++ * modify the implementation of kalDelay to msleep ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 11 30 2010 yuche.tsai ++ * NULL ++ * Invitation & Provision Discovery Indication. ++ * ++ * 11 26 2010 cp.wu ++ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field ++ * checking ++ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used ++ * to indicate user is attached ++ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown ++ * ++ * 11 08 2010 cp.wu ++ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period ++ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * add a kal function for set cipher. ++ * ++ * 10 04 2010 wh.su ++ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P ++ * fixed compiling error while enable p2p. ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 21 2010 cp.wu ++ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS ++ * associated ++ * Do a complete reset with STA-REC null checking for RF test re-entry ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning ++ * Eliminate Linux Compile Warning ++ * ++ * 09 10 2010 wh.su ++ * NULL ++ * fixed the compiling error at win XP. ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * modify kalSetEvent declaration ++ * ++ * 07 29 2010 cp.wu ++ * NULL ++ * simplify post-handling after TX_DONE interrupt is handled. ++ * ++ * 07 23 2010 cp.wu ++ * ++ * 1) re-enable AIS-FSM beacon timeout handling. ++ * 2) scan done API revised ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * fix kal header file ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * use different spin lock for security frame ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * add new spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add kal api for scanning done ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * modify cmd/data path for new design ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add new kal api ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * Linux port modification ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 21 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * change MAC address updating logic. ++ * ++ * 06 18 2010 cm.chang ++ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver ++ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf ++ * ++ * 06 11 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * 1) migrate assoc.c. ++ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness ++ * 3) add configuration options for CNM_MEM and RSN modules ++ * 4) add data path for management frames ++ * 5) eliminate rPacketInfo of MSDU_INFO_T ++ * ++ * 06 07 2010 cp.wu ++ * [WPD00003833][MT6620 and MT5931] Driver migration ++ * gl_kal merged ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic handling framework for wireless extension ioctls. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * fill network type field while doing frame identification. ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * modify kalMemAlloc method ++ * ++ * 04 28 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change prefix for data structure used to communicate with 802.11 PAL ++ * to avoid ambiguous naming with firmware interface ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 22 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * when acquiring driver-own, wait for up to 8 seconds. ++ * ++ * 04 22 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * ++ * 1) modify rx path code for supporting Wi-Fi direct ++ * 2) modify config.h since Linux dont need to consider retaining packet ++ * ++ * 04 21 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add for private ioctl support ++ * ++ * 04 20 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL ++ * * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. ++ * ++ * 04 14 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * information buffer for query oid/ioctl is now buffered in prCmdInfo ++ * * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler ++ * * * * * * * * * * * * * * * * * * * capability ++ * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) add spinlock ++ * * * 2) add KAPI for handling association info ++ * ++ * 04 09 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * adding firmware download KAPI ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * finish non-glue layer access to glue variables ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * accessing to firmware load/start address, and access to OID handling information ++ * * * * are now handled in glue layer ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * * * are done in adapter layer. ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * add KAL API: kalFlushPendingTxPackets(), and take use of the API ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) for some OID, never do timeout expiration ++ * * * * 2) add 2 kal API for later integration ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download KAPI ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\41 2009-09-28 20:19:23 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\40 2009-08-18 22:57:09 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\39 2009-06-23 23:19:15 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\38 2009-02-09 14:03:17 GMT mtk01090 ++** Add KAL function kalDevSetPowerState(). It is not implemented yet. Only add an empty macro. ++** ++** \main\maintrunk.MT5921\37 2009-01-22 13:05:59 GMT mtk01088 ++** new defeine to got 1x value at packet reserved field ++** \main\maintrunk.MT5921\36 2008-12-08 16:15:02 GMT mtk01461 ++** Add kalQueryValidBufferLength() macro ++** \main\maintrunk.MT5921\35 2008-11-13 20:33:15 GMT mtk01104 ++** Remove lint warning ++** \main\maintrunk.MT5921\34 2008-10-22 11:05:52 GMT mtk01461 ++** Remove unused macro ++** \main\maintrunk.MT5921\33 2008-10-16 15:48:17 GMT mtk01461 ++** Update driver to fix lint warning ++** \main\maintrunk.MT5921\32 2008-09-02 11:50:51 GMT mtk01461 ++** SPIN_LOCK_SDIO_DDK_TX_QUE ++** \main\maintrunk.MT5921\31 2008-08-29 15:58:30 GMT mtk01088 ++** remove non-used function for code refine ++** \main\maintrunk.MT5921\30 2008-08-21 00:33:29 GMT mtk01461 ++** Update for Driver Review ++** \main\maintrunk.MT5921\29 2008-06-19 13:29:14 GMT mtk01425 ++** 1. Add declaration of SPIN_LOCK_SDIO_DDK_TX_QUE and SPIN_LOCK_SDIO_DDK_RX_QUE ++** \main\maintrunk.MT5921\28 2008-05-30 20:27:34 GMT mtk01461 ++** Rename KAL function ++** \main\maintrunk.MT5921\27 2008-05-30 14:42:05 GMT mtk01461 ++** Remove WMM Assoc Flag in KAL ++** \main\maintrunk.MT5921\26 2008-05-29 14:15:18 GMT mtk01084 ++** remove un-used function ++** \main\maintrunk.MT5921\25 2008-04-23 14:02:20 GMT mtk01084 ++** modify KAL port access function prototype ++** \main\maintrunk.MT5921\24 2008-04-17 23:06:41 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\23 2008-04-08 15:38:50 GMT mtk01084 ++** add KAL function to setting pattern search function enable/ disable ++** \main\maintrunk.MT5921\22 2008-03-26 15:34:48 GMT mtk01461 ++** Add update MAC address func ++** \main\maintrunk.MT5921\21 2008-03-18 15:56:15 GMT mtk01084 ++** update ENUM_NIC_INITIAL_PARAM_E ++** \main\maintrunk.MT5921\20 2008-03-18 11:49:28 GMT mtk01084 ++** update function for initial value access ++** \main\maintrunk.MT5921\19 2008-03-18 10:21:31 GMT mtk01088 ++** use kal update associate request at linux ++** \main\maintrunk.MT5921\18 2008-03-14 18:03:41 GMT mtk01084 ++** refine register and port access function ++** \main\maintrunk.MT5921\17 2008-03-11 14:51:02 GMT mtk01461 ++** Add copy_to(from)_user macro ++** \main\maintrunk.MT5921\16 2008-03-06 23:42:21 GMT mtk01385 ++** 1. add Query Registry Mac address function. ++** \main\maintrunk.MT5921\15 2008-02-26 09:48:04 GMT mtk01084 ++** modify KAL set network address/ checksum offload part ++** \main\maintrunk.MT5921\14 2008-01-09 17:54:58 GMT mtk01084 ++** Modify the argument of kalQueryPacketInfo ++** \main\maintrunk.MT5921\13 2007-11-29 02:05:20 GMT mtk01461 ++** Fix Windows RX multiple packet retain problem ++** \main\maintrunk.MT5921\12 2007-11-26 19:43:45 GMT mtk01461 ++** Add OS_TIMESTAMP macro ++** ++** \main\maintrunk.MT5921\11 2007-11-09 16:36:15 GMT mtk01425 ++** 1. Modify for CSUM offloading with Tx Fragment ++** \main\maintrunk.MT5921\10 2007-11-07 18:38:37 GMT mtk01461 ++** Add Tx Fragmentation Support ++** \main\maintrunk.MT5921\9 2007-11-06 19:36:50 GMT mtk01088 ++** add the WPS related code ++** \main\maintrunk.MT5921\8 2007-11-02 01:03:57 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** Revision 1.4 2007/07/05 07:25:33 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:50 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:23 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++#ifndef _GL_KAL_H ++#define _GL_KAL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "config.h" ++#include "gl_typedef.h" ++#include "gl_os.h" ++#include "link.h" ++#include "nic/mac.h" ++#include "nic/wlan_def.h" ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "gl_wext_priv.h" ++#include ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++#include "nic/bow.h" ++#endif ++ ++#if DBG ++extern int allocatedMemSize; ++#endif ++ ++#if CFG_SUPPORT_MET_PROFILING ++#include "linux/kallsyms.h" ++#include ++#endif ++ ++extern BOOLEAN fgIsUnderSuspend; ++extern UINT_32 TaskIsrCnt; ++extern BOOLEAN fgIsResetting; ++extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); ++extern UINT_32 u4MemAllocCnt, u4MemFreeCnt; ++ ++ ++extern struct delayed_work sched_workq; ++ ++#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT ++extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* #define USEC_PER_MSEC (1000) */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum _ENUM_SPIN_LOCK_CATEGORY_E { ++ SPIN_LOCK_FSM = 0, ++ ++ /* FIX ME */ ++ SPIN_LOCK_RX_QUE, ++ SPIN_LOCK_TX_QUE, ++ SPIN_LOCK_CMD_QUE, ++ SPIN_LOCK_TX_RESOURCE, ++ SPIN_LOCK_CMD_RESOURCE, ++ SPIN_LOCK_QM_TX_QUEUE, ++ SPIN_LOCK_CMD_PENDING, ++ SPIN_LOCK_CMD_SEQ_NUM, ++ SPIN_LOCK_TX_MSDU_INFO_LIST, ++ SPIN_LOCK_TXING_MGMT_LIST, ++ SPIN_LOCK_TX_SEQ_NUM, ++ SPIN_LOCK_TX_COUNT, ++ SPIN_LOCK_TXS_COUNT, ++ /* end */ ++ SPIN_LOCK_TX, ++ SPIN_LOCK_IO_REQ, ++ SPIN_LOCK_INT, ++ ++ SPIN_LOCK_MGT_BUF, ++ SPIN_LOCK_MSG_BUF, ++ SPIN_LOCK_STA_REC, ++ ++ SPIN_LOCK_MAILBOX, ++ SPIN_LOCK_TIMER, ++ ++ SPIN_LOCK_BOW_TABLE, ++ ++ SPIN_LOCK_EHPI_BUS, /* only for EHPI */ ++ SPIN_LOCK_NET_DEV, ++ SPIN_LOCK_NUM ++} ENUM_SPIN_LOCK_CATEGORY_E; ++ ++/* event for assoc information update */ ++typedef struct _EVENT_ASSOC_INFO { ++ UINT_8 ucAssocReq; /* 1 for assoc req, 0 for assoc rsp */ ++ UINT_8 ucReassoc; /* 0 for assoc, 1 for reassoc */ ++ UINT_16 u2Length; ++ PUINT_8 pucIe; ++} EVENT_ASSOC_INFO, *P_EVENT_ASSOC_INFO; ++ ++typedef enum _ENUM_KAL_NETWORK_TYPE_INDEX_T { ++ KAL_NETWORK_TYPE_AIS_INDEX = 0, ++#if CFG_ENABLE_WIFI_DIRECT ++ KAL_NETWORK_TYPE_P2P_INDEX, ++#endif ++#if CFG_ENABLE_BT_OVER_WIFI ++ KAL_NETWORK_TYPE_BOW_INDEX, ++#endif ++ KAL_NETWORK_TYPE_INDEX_NUM ++} ENUM_KAL_NETWORK_TYPE_INDEX_T; ++ ++typedef enum _ENUM_KAL_MEM_ALLOCATION_TYPE_E { ++ PHY_MEM_TYPE, /* physically continuous */ ++ VIR_MEM_TYPE, /* virtually continuous */ ++ MEM_TYPE_NUM ++} ENUM_KAL_MEM_ALLOCATION_TYPE; ++ ++#if CONFIG_ANDROID /* Defined in Android kernel source */ ++typedef struct wake_lock KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; ++#else ++typedef UINT_32 KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; ++#endif ++ ++#if CFG_SUPPORT_AGPS_ASSIST ++typedef enum _ENUM_MTK_AGPS_ATTR { ++ MTK_ATTR_AGPS_INVALID, ++ MTK_ATTR_AGPS_CMD, ++ MTK_ATTR_AGPS_DATA, ++ MTK_ATTR_AGPS_IFINDEX, ++ MTK_ATTR_AGPS_IFNAME, ++ MTK_ATTR_AGPS_MAX ++} ENUM_MTK_CCX_ATTR; ++ ++typedef enum _ENUM_AGPS_EVENT { ++ AGPS_EVENT_WLAN_ON, ++ AGPS_EVENT_WLAN_OFF, ++ AGPS_EVENT_WLAN_AP_LIST, ++ WIFI_EVENT_CHIP_RESET, ++} ENUM_CCX_EVENT; ++BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen); ++#endif ++ ++struct KAL_HALT_CTRL_T { ++ struct semaphore lock; ++ struct task_struct *owner; ++ BOOLEAN fgHalt; ++ BOOLEAN fgHeldByKalIoctl; ++ OS_SYSTIME u4HoldStart; ++}; ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros of bit operation */ ++/*----------------------------------------------------------------------------*/ ++#define KAL_SET_BIT(bitOffset, value) set_bit(bitOffset, &value) ++#define KAL_CLR_BIT(bitOffset, value) clear_bit(bitOffset, &value) ++#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value) test_and_clear_bit(bitOffset, &value) ++#define KAL_TEST_BIT(bitOffset, value) test_bit(bitOffset, &value) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros of SPIN LOCK operations for using in Driver Layer */ ++/*----------------------------------------------------------------------------*/ ++#define KAL_SPIN_LOCK_DECLARATION() unsigned long __u4Flags ++ ++#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory) \ ++ kalAcquireSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, &__u4Flags) ++ ++#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory) \ ++ kalReleaseSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, __u4Flags) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for accessing Reserved Fields of native packet */ ++/*----------------------------------------------------------------------------*/ ++#define KAL_GET_PKT_QUEUE_ENTRY(_p) GLUE_GET_PKT_QUEUE_ENTRY(_p) ++#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry) GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) ++#define KAL_GET_PKT_TID(_p) GLUE_GET_PKT_TID(_p) ++#define KAL_GET_PKT_IS1X(_p) GLUE_GET_PKT_IS1X(_p) ++#define KAL_GET_PKT_HEADER_LEN(_p) GLUE_GET_PKT_HEADER_LEN(_p) ++#define KAL_GET_PKT_PAYLOAD_LEN(_p) GLUE_GET_PKT_PAYLOAD_LEN(_p) ++#define KAL_GET_PKT_ARRIVAL_TIME(_p) GLUE_GET_PKT_ARRIVAL_TIME(_p) ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros of wake_lock operations for using in Driver Layer */ ++/*----------------------------------------------------------------------------*/ ++#if CONFIG_ANDROID /* Defined in Android kernel source */ ++#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ ++ wake_lock_init(_prWakeLock, WAKE_LOCK_SUSPEND, _pcName) ++ ++#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ ++ wake_lock_destroy(_prWakeLock) ++ ++#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \ ++ wake_lock(_prWakeLock) ++ ++#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \ ++ wake_lock_timeout(_prWakeLock, _u4Timeout) ++ ++#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \ ++ wake_unlock(_prWakeLock) ++ ++#else ++#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) ++#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) ++#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) ++#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) ++#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Cache memory allocation ++* ++* \param[in] u4Size Required memory size. ++* \param[in] eMemType Memory allocation type ++* ++* \return Pointer to allocated memory ++* or NULL ++*/ ++/*----------------------------------------------------------------------------*/ ++#if DBG ++#define kalMemAlloc(u4Size, eMemType) ({ \ ++ void *pvAddr; \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ ++ } \ ++ else { \ ++ pvAddr = vmalloc(u4Size); \ ++ } \ ++ if (pvAddr) { \ ++ allocatedMemSize += u4Size; \ ++ DBGLOG(INIT, INFO, "%p(%u) allocated (%s:%s)\n", \ ++ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ ++ } \ ++ pvAddr; \ ++}) ++#else ++#define kalMemAlloc(u4Size, eMemType) ({ \ ++ void *pvAddr; \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ ++ } \ ++ else { \ ++ pvAddr = vmalloc(u4Size); \ ++ } \ ++ pvAddr; \ ++}) ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Free allocated cache memory ++* ++* \param[in] pvAddr Required memory size. ++* \param[in] eMemType Memory allocation type ++* \param[in] u4Size Allocated memory size. ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++#if DBG ++#define kalMemFree(pvAddr, eMemType, u4Size) \ ++{ \ ++ if (pvAddr) { \ ++ allocatedMemSize -= u4Size; \ ++ DBGLOG(INIT, INFO, "%p(%u) freed (%s:%s)\n", \ ++ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ ++ } \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ kfree(pvAddr); \ ++ } \ ++ else { \ ++ vfree(pvAddr); \ ++ } \ ++} ++#else ++#define kalMemFree(pvAddr, eMemType, u4Size) \ ++{ \ ++ if (eMemType == PHY_MEM_TYPE) { \ ++ kfree(pvAddr); \ ++ } \ ++ else { \ ++ vfree(pvAddr); \ ++ } \ ++} ++#endif ++ ++#define kalUdelay(u4USec) udelay(u4USec) ++ ++#define kalMdelay(u4MSec) mdelay(u4MSec) ++#define kalMsleep(u4MSec) msleep(u4MSec) ++ ++/* Copy memory from user space to kernel space */ ++#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N) copy_from_user(_pvTo, _pvFrom, _u4N) ++ ++/* Copy memory from kernel space to user space */ ++#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N) copy_to_user(_pvTo, _pvFrom, _u4N) ++ ++/* Copy memory block with specific size */ ++#define kalMemCopy(pvDst, pvSrc, u4Size) memcpy(pvDst, pvSrc, u4Size) ++ ++/* Set memory block with specific pattern */ ++#define kalMemSet(pvAddr, ucPattern, u4Size) memset(pvAddr, ucPattern, u4Size) ++ ++/* Compare two memory block with specific length. ++ * Return zero if they are the same. ++ */ ++#define kalMemCmp(pvAddr1, pvAddr2, u4Size) memcmp(pvAddr1, pvAddr2, u4Size) ++ ++/* Zero specific memory block */ ++#define kalMemZero(pvAddr, u4Size) memset(pvAddr, 0, u4Size) ++ ++/* string operation */ ++#define kalStrCpy(dest, src) strcpy(dest, src) ++#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) ++#define kalStrCmp(ct, cs) strcmp(ct, cs) ++#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) ++#define kalStrChr(s, c) strchr(s, c) ++#define kalStrrChr(s, c) strrchr(s, c) ++#define kalStrnChr(s, n, c) strnchr(s, n, c) ++#define kalStrLen(s) strlen(s) ++#define kalStrnLen(s, b) strnlen(s, b) ++//#define kalStrniCmp(s1, s2, n) strnicmp(s1, s2, n) ++#define kalStrniCmp(s1, s2, n) strncasecmp(s1, s2, n) ++#define strnicmp(s1, s2, n) strncasecmp(s1, s2, n) ++/* #define kalStrtoul(cp, endp, base) simple_strtoul(cp, endp, base) ++#define kalStrtol(cp, endp, base) simple_strtol(cp, endp, base) */ ++#define kalkStrtou32(cp, base, resp) kstrtou32(cp, base, resp) ++#define kalkStrtos32(cp, base, resp) kstrtos32(cp, base, resp) ++#define kalSnprintf(buf, size, fmt, ...) snprintf(buf, size, fmt, __VA_ARGS__) ++#define kalSprintf(buf, fmt, ...) sprintf(buf, fmt, __VA_ARGS__) ++/* remove for AOSP */ ++/* #define kalSScanf(buf, fmt, ...) sscanf(buf, fmt, __VA_ARGS__) */ ++#define kalStrStr(ct, cs) strstr(ct, cs) ++#define kalStrSep(s, ct) strsep(s, ct) ++#define kalStrCat(dest, src) strcat(dest, src) ++ ++/* defined for wince sdio driver only */ ++#if defined(_HIF_SDIO) ++#define kalDevSetPowerState(prGlueInfo, ePowerMode) glSetPowerState(prGlueInfo, ePowerMode) ++#else ++#define kalDevSetPowerState(prGlueInfo, ePowerMode) ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Notify OS with SendComplete event of the specific packet. Linux should ++* free packets here. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* \param[in] status Status Code for OS upper layer ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalSendComplete(prGlueInfo, pvPacket, status) \ ++ kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket) ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to locate the starting address of incoming ethernet ++* frame for skb. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* ++* \return starting address of ethernet frame buffer. ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalQueryBufferPointer(prGlueInfo, pvPacket) \ ++ ((PUINT_8)((struct sk_buff *)pvPacket)->data) ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to query the length of valid buffer which is accessible during ++* port read/write. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* ++* \return starting address of ethernet frame buffer. ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalQueryValidBufferLength(prGlueInfo, pvPacket) \ ++ ((UINT_32)((struct sk_buff *)pvPacket)->end - \ ++ (UINT_32)((struct sk_buff *)pvPacket)->data) ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief This function is used to copy the entire frame from skb to the destination ++* address in the input parameter. ++* ++* \param[in] prGlueInfo Pointer of GLUE Data Structure ++* \param[in] pvPacket Pointer of Packet Handle ++* \param[in] pucDestBuffer Destination Address ++* ++* \return - ++*/ ++/*----------------------------------------------------------------------------*/ ++#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer) \ ++ do {struct sk_buff *skb = (struct sk_buff *)pvPacket; \ ++ memcpy(pucDestBuffer, skb->data, skb->len); } while (0) ++ ++#define kalGetTimeTick() jiffies_to_msecs(jiffies) ++ ++#define kalPrint pr_debug ++ ++#if !DBG ++#define AIS_ERROR_LOGFUNC(_Fmt...) ++#define AIS_WARN_LOGFUNC(_Fmt...) ++#define AIS_INFO_LOGFUNC(_Fmt...) ++#define AIS_STATE_LOGFUNC(_Fmt...) ++#define AIS_EVENT_LOGFUNC(_Fmt...) ++#define AIS_TRACE_LOGFUNC(_Fmt...) ++#define AIS_LOUD_LOGFUNC(_Fmt...) ++#define AIS_TEMP_LOGFUNC(_Fmt...) ++ ++#define INTR_ERROR_LOGFUNC(_Fmt...) ++#define INTR_WARN_LOGFUNC(_Fmt...) ++#define INTR_INFO_LOGFUNC(_Fmt...) ++#define INTR_STATE_LOGFUNC(_Fmt...) ++#define INTR_EVENT_LOGFUNC(_Fmt...) ++#define INTR_TRACE_LOGFUNC(_Fmt...) ++#define INTR_LOUD_LOGFUNC(_Fmt...) ++#define INTR_TEMP_LOGFUNC(_Fmt...) ++ ++#define INIT_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define INIT_TRACE_LOGFUNC(_Fmt...) ++#define INIT_LOUD_LOGFUNC(_Fmt...) ++#define INIT_TEMP_LOGFUNC(_Fmt...) ++ ++#define AAA_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define AAA_LOUD_LOGFUNC(_Fmt...) ++#define AAA_TEMP_LOGFUNC(_Fmt...) ++ ++#define ROAMING_ERROR_LOGFUNC(_Fmt...) ++#define ROAMING_WARN_LOGFUNC(_Fmt...) ++#define ROAMING_INFO_LOGFUNC(_Fmt...) ++#define ROAMING_STATE_LOGFUNC(_Fmt...) ++#define ROAMING_EVENT_LOGFUNC(_Fmt...) ++#define ROAMING_TRACE_LOGFUNC(_Fmt...) ++#define ROAMING_LOUD_LOGFUNC(_Fmt...) ++#define ROAMING_TEMP_LOGFUNC(_Fmt...) ++ ++#define REQ_ERROR_LOGFUNC(_Fmt...) ++#define REQ_WARN_LOGFUNC(_Fmt...) ++#define REQ_INFO_LOGFUNC(_Fmt...) ++#define REQ_STATE_LOGFUNC(_Fmt...) ++#define REQ_EVENT_LOGFUNC(_Fmt...) ++#define REQ_TRACE_LOGFUNC(_Fmt...) ++#define REQ_LOUD_LOGFUNC(_Fmt...) ++#define REQ_TEMP_LOGFUNC(_Fmt...) ++ ++#define TX_ERROR_LOGFUNC(_Fmt...) ++#define TX_WARN_LOGFUNC(_Fmt...) ++#define TX_INFO_LOGFUNC(_Fmt...) ++#define TX_STATE_LOGFUNC(_Fmt...) ++#define TX_EVENT_LOGFUNC(_Fmt...) ++#define TX_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TX_LOUD_LOGFUNC(_Fmt...) ++#define TX_TEMP_LOGFUNC(_Fmt...) ++ ++#define RX_ERROR_LOGFUNC(_Fmt...) ++#define RX_WARN_LOGFUNC(_Fmt...) ++#define RX_INFO_LOGFUNC(_Fmt...) ++#define RX_STATE_LOGFUNC(_Fmt...) ++#define RX_EVENT_LOGFUNC(_Fmt...) ++#define RX_TRACE_LOGFUNC(_Fmt...) ++#define RX_LOUD_LOGFUNC(_Fmt...) ++#define RX_TEMP_LOGFUNC(_Fmt...) ++ ++#define RFTEST_ERROR_LOGFUNC(_Fmt...) ++#define RFTEST_WARN_LOGFUNC(_Fmt...) ++#define RFTEST_INFO_LOGFUNC(_Fmt...) ++#define RFTEST_STATE_LOGFUNC(_Fmt...) ++#define RFTEST_EVENT_LOGFUNC(_Fmt...) ++#define RFTEST_TRACE_LOGFUNC(_Fmt...) ++#define RFTEST_LOUD_LOGFUNC(_Fmt...) ++#define RFTEST_TEMP_LOGFUNC(_Fmt...) ++ ++#define EMU_ERROR_LOGFUNC(_Fmt...) ++#define EMU_WARN_LOGFUNC(_Fmt...) ++#define EMU_INFO_LOGFUNC(_Fmt...) ++#define EMU_STATE_LOGFUNC(_Fmt...) ++#define EMU_EVENT_LOGFUNC(_Fmt...) ++#define EMU_TRACE_LOGFUNC(_Fmt...) ++#define EMU_LOUD_LOGFUNC(_Fmt...) ++#define EMU_TEMP_LOGFUNC(_Fmt...) ++ ++#define HEM_ERROR_LOGFUNC(_Fmt...) ++#define HEM_WARN_LOGFUNC(_Fmt...) ++#define HEM_INFO_LOGFUNC(_Fmt...) ++#define HEM_STATE_LOGFUNC(_Fmt...) ++#define HEM_EVENT_LOGFUNC(_Fmt...) ++#define HEM_TRACE_LOGFUNC(_Fmt...) ++#define HEM_LOUD_LOGFUNC(_Fmt...) ++#define HEM_TEMP_LOGFUNC(_Fmt...) ++ ++#define RLM_ERROR_LOGFUNC(_Fmt...) ++#define RLM_WARN_LOGFUNC(_Fmt...) ++#define RLM_INFO_LOGFUNC(_Fmt...) ++#define RLM_STATE_LOGFUNC(_Fmt...) ++#define RLM_EVENT_LOGFUNC(_Fmt...) ++#define RLM_TRACE_LOGFUNC(_Fmt...) ++#define RLM_LOUD_LOGFUNC(_Fmt...) ++#define RLM_TEMP_LOGFUNC(_Fmt...) ++ ++#define MEM_ERROR_LOGFUNC(_Fmt...) ++#define MEM_WARN_LOGFUNC(_Fmt...) ++#define MEM_INFO_LOGFUNC(_Fmt...) ++#define MEM_STATE_LOGFUNC(_Fmt...) ++#define MEM_EVENT_LOGFUNC(_Fmt...) ++#define MEM_TRACE_LOGFUNC(_Fmt...) ++#define MEM_LOUD_LOGFUNC(_Fmt...) ++#define MEM_TEMP_LOGFUNC(_Fmt...) ++ ++#define CNM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define CNM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define CNM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define CNM_STATE_LOGFUNC(_Fmt...) ++#define CNM_EVENT_LOGFUNC(_Fmt...) ++#define CNM_TRACE_LOGFUNC(_Fmt...) ++#define CNM_LOUD_LOGFUNC(_Fmt...) ++#define CNM_TEMP_LOGFUNC(_Fmt...) ++ ++#define RSN_ERROR_LOGFUNC(_Fmt...) ++#define RSN_WARN_LOGFUNC(_Fmt...) ++#define RSN_INFO_LOGFUNC(_Fmt...) ++#define RSN_STATE_LOGFUNC(_Fmt...) ++#define RSN_EVENT_LOGFUNC(_Fmt...) ++#define RSN_TRACE_LOGFUNC(_Fmt...) ++#define RSN_LOUD_LOGFUNC(_Fmt...) ++#define RSN_TEMP_LOGFUNC(_Fmt...) ++ ++#define BSS_ERROR_LOGFUNC(_Fmt...) ++#define BSS_WARN_LOGFUNC(_Fmt...) ++#define BSS_INFO_LOGFUNC(_Fmt...) ++#define BSS_STATE_LOGFUNC(_Fmt...) ++#define BSS_EVENT_LOGFUNC(_Fmt...) ++#define BSS_TRACE_LOGFUNC(_Fmt...) ++#define BSS_LOUD_LOGFUNC(_Fmt...) ++#define BSS_TEMP_LOGFUNC(_Fmt...) ++ ++#define SCN_ERROR_LOGFUNC(_Fmt...) ++#define SCN_WARN_LOGFUNC(_Fmt...) ++#define SCN_INFO_LOGFUNC(_Fmt...) ++#define SCN_STATE_LOGFUNC(_Fmt...) ++#define SCN_EVENT_LOGFUNC(_Fmt...) ++#define SCN_TRACE_LOGFUNC(_Fmt...) ++#define SCN_LOUD_LOGFUNC(_Fmt...) ++#define SCN_TEMP_LOGFUNC(_Fmt...) ++ ++#define SAA_ERROR_LOGFUNC(_Fmt...) ++#define SAA_WARN_LOGFUNC(_Fmt...) ++#define SAA_INFO_LOGFUNC(_Fmt...) ++#define SAA_STATE_LOGFUNC(_Fmt...) ++#define SAA_EVENT_LOGFUNC(_Fmt...) ++#define SAA_TRACE_LOGFUNC(_Fmt...) ++#define SAA_LOUD_LOGFUNC(_Fmt...) ++#define SAA_TEMP_LOGFUNC(_Fmt...) ++ ++#define P2P_ERROR_LOGFUNC(_Fmt...) ++#define P2P_WARN_LOGFUNC(_Fmt...) ++#define P2P_INFO_LOGFUNC(_Fmt...) ++#define P2P_STATE_LOGFUNC(_Fmt...) ++#define P2P_EVENT_LOGFUNC(_Fmt...) ++#define P2P_TRACE_LOGFUNC(_Fmt...) ++#define P2P_LOUD_LOGFUNC(_Fmt...) ++#define P2P_TEMP_LOGFUNC(_Fmt...) ++ ++#define QM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_STATE_LOGFUNC(_Fmt...) ++#define QM_EVENT_LOGFUNC(_Fmt...) ++#define QM_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define QM_LOUD_LOGFUNC(_Fmt...) ++#define QM_TEMP_LOGFUNC(_Fmt...) ++ ++#define SEC_ERROR_LOGFUNC(_Fmt...) ++#define SEC_WARN_LOGFUNC(_Fmt...) ++#define SEC_INFO_LOGFUNC(_Fmt...) ++#define SEC_STATE_LOGFUNC(_Fmt...) ++#define SEC_EVENT_LOGFUNC(_Fmt...) ++#define SEC_TRACE_LOGFUNC(_Fmt...) ++#define SEC_LOUD_LOGFUNC(_Fmt...) ++#define SEC_TEMP_LOGFUNC(_Fmt...) ++ ++#define BOW_ERROR_LOGFUNC(_Fmt...) ++#define BOW_WARN_LOGFUNC(_Fmt...) ++#define BOW_INFO_LOGFUNC(_Fmt...) ++#define BOW_STATE_LOGFUNC(_Fmt...) ++#define BOW_EVENT_LOGFUNC(_Fmt...) ++#define BOW_TRACE_LOGFUNC(_Fmt...) ++#define BOW_LOUD_LOGFUNC(_Fmt...) ++#define BOW_TEMP_LOGFUNC(_Fmt...) ++ ++#define HAL_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define HAL_WARN_LOGFUNC(_Fmt...) ++#define HAL_INFO_LOGFUNC(_Fmt...) ++#define HAL_STATE_LOGFUNC(_Fmt...) ++#define HAL_EVENT_LOGFUNC(_Fmt...) ++#define HAL_TRACE_LOGFUNC(_Fmt...) ++#define HAL_LOUD_LOGFUNC(_Fmt...) ++#define HAL_TEMP_LOGFUNC(_Fmt...) ++ ++#define WAPI_ERROR_LOGFUNC(_Fmt...) ++#define WAPI_WARN_LOGFUNC(_Fmt...) ++#define WAPI_INFO_LOGFUNC(_Fmt...) ++#define WAPI_STATE_LOGFUNC(_Fmt...) ++#define WAPI_EVENT_LOGFUNC(_Fmt...) ++#define WAPI_TRACE_LOGFUNC(_Fmt...) ++#define WAPI_LOUD_LOGFUNC(_Fmt...) ++#define WAPI_TEMP_LOGFUNC(_Fmt...) ++ ++#define TDLS_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TDLS_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TDLS_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) ++#define TDLS_STATE_LOGFUNC(_Fmt...) ++#define TDLS_EVENT_LOGFUNC(_Fmt...) ++#define TDLS_TRACE_LOGFUNC(_Fmt...) ++#define TDLS_LOUD_LOGFUNC(_Fmt...) ++#define TDLS_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW1_ERROR_LOGFUNC(_Fmt...) ++#define SW1_WARN_LOGFUNC(_Fmt...) ++#define SW1_INFO_LOGFUNC(_Fmt...) ++#define SW1_STATE_LOGFUNC(_Fmt...) ++#define SW1_EVENT_LOGFUNC(_Fmt...) ++#define SW1_TRACE_LOGFUNC(_Fmt...) ++#define SW1_LOUD_LOGFUNC(_Fmt...) ++#define SW1_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW2_ERROR_LOGFUNC(_Fmt...) ++#define SW2_WARN_LOGFUNC(_Fmt...) ++#define SW2_INFO_LOGFUNC(_Fmt...) ++#define SW2_STATE_LOGFUNC(_Fmt...) ++#define SW2_EVENT_LOGFUNC(_Fmt...) ++#define SW2_TRACE_LOGFUNC(_Fmt...) ++#define SW2_LOUD_LOGFUNC(_Fmt...) ++#define SW2_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW3_ERROR_LOGFUNC(_Fmt...) ++#define SW3_WARN_LOGFUNC(_Fmt...) ++#define SW3_INFO_LOGFUNC(_Fmt...) ++#define SW3_STATE_LOGFUNC(_Fmt...) ++#define SW3_EVENT_LOGFUNC(_Fmt...) ++#define SW3_TRACE_LOGFUNC(_Fmt...) ++#define SW3_LOUD_LOGFUNC(_Fmt...) ++#define SW3_TEMP_LOGFUNC(_Fmt...) ++ ++#define SW4_ERROR_LOGFUNC(_Fmt...) ++#define SW4_WARN_LOGFUNC(_Fmt...) ++#define SW4_INFO_LOGFUNC(_Fmt...) ++#define SW4_STATE_LOGFUNC(_Fmt...) ++#define SW4_EVENT_LOGFUNC(_Fmt...) ++#define SW4_TRACE_LOGFUNC(_Fmt...) ++#define SW4_LOUD_LOGFUNC(_Fmt...) ++#define SW4_TEMP_LOGFUNC(_Fmt...) ++#endif ++ ++#define kalBreakPoint() \ ++do { \ ++ BUG(); \ ++ panic("Oops"); \ ++} while (0) ++ ++#if CFG_ENABLE_AEE_MSG ++#define kalSendAeeException aee_kernel_exception ++#define kalSendAeeWarning aee_kernel_warning ++#define kalSendAeeReminding aee_kernel_reminding ++#else ++#define kalSendAeeException(_module, _desc, ...) ++#define kalSendAeeWarning(_module, _desc, ...) ++#define kalSendAeeReminding(_module, _desc, ...) ++#endif ++ ++#define PRINTF_ARG(...) __VA_ARGS__ ++#define SPRINTF(buf, arg) {buf += sprintf((char *)(buf), PRINTF_ARG arg); } ++ ++#define USEC_TO_SYSTIME(_usec) ((_usec) / USEC_PER_MSEC) ++#define MSEC_TO_SYSTIME(_msec) (_msec) ++ ++#define MSEC_TO_JIFFIES(_msec) msecs_to_jiffies(_msec) ++ ++#define KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE 3000 /* 3s */ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Routines in gl_kal.c */ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags); ++ ++VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags); ++ ++VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr); ++ ++VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); ++ ++PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData); ++ ++VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler); ++ ++BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN OS_SYSTIME rInterval); ++ ++WLAN_STATUS ++kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, ++ /* IN PBOOLEAN pfgIsRetain, */ ++ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aeCSUM[] ++); ++ ++WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum); ++ ++VOID ++kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen); ++ ++VOID ++kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); ++ ++VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen); ++ ++#if CFG_TX_FRAGMENT ++BOOLEAN ++kalQueryTxPacketHeader(IN P_GLUE_INFO_T prGlueInfo, ++ IN PVOID pvPacket, OUT PUINT_16 pu2EtherTypeLen, OUT PUINT_8 pucEthDestAddr); ++#endif /* CFG_TX_FRAGMENT */ ++ ++VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag); ++ ++VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T eCSUM[] ++); ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr); ++ ++VOID ++kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs); ++ ++VOID ++kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum); ++ ++VOID ++kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); ++ ++VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); ++ ++/*----------------------------------------------------------------------------*/ ++/* Routines in interface - ehpi/sdio.c */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalDevRegRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value); ++ ++BOOLEAN kalDevRegWrite(P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value); ++ ++BOOLEAN ++kalDevPortRead(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_16 u2Port, IN UINT_32 u2Len, OUT PUINT_8 pucBuf, IN UINT_32 u2ValidOutBufSize); ++ ++BOOLEAN ++kalDevPortWrite(P_GLUE_INFO_T prGlueInfo, ++ IN UINT_16 u2Port, IN UINT_32 u2Len, IN PUINT_8 pucBuf, IN UINT_32 u2ValidInBufSize); ++ ++BOOLEAN kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData); ++ ++void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo); ++ ++#if CFG_SUPPORT_EXT_CONFIG ++UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo); ++#endif ++ ++BOOLEAN ++kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_NATIVE_PACKET prPacket, ++ OUT PUINT_8 pucPriorityParam, ++ OUT PUINT_32 pu4PacketLen, ++ OUT PUINT_8 pucEthDestAddr, ++ OUT PBOOLEAN pfgIs1X, ++ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, ++ OUT PVOID prGenUse); ++ ++VOID ++kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, ++ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus); ++ ++WLAN_STATUS ++kalIoctl(IN P_GLUE_INFO_T prGlueInfo, ++ IN PFN_OID_HANDLER_FUNC pfnOidHandler, ++ IN PVOID pvInfoBuf, ++ IN UINT_32 u4InfoBufLen, ++ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen); ++ ++VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo); ++ ++#if CFG_ENABLE_FW_DOWNLOAD ++ ++PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength); ++ ++VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf); ++#endif ++ ++/*----------------------------------------------------------------------------*/ ++/* Card Removal Check */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* TX */ ++/*----------------------------------------------------------------------------*/ ++VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Media State Indication */ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate); ++ ++/*----------------------------------------------------------------------------*/ ++/* OID handling */ ++/*----------------------------------------------------------------------------*/ ++VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry); ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++/*----------------------------------------------------------------------------*/ ++/* Bluetooth over Wi-Fi handling */ ++/*----------------------------------------------------------------------------*/ ++VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent); ++ ++ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); ++ ++BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, PARAM_MAC_ADDRESS rPeerAddr); ++ ++ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); ++ ++VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr); ++ ++UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo); ++ ++#if CFG_BOW_SEPARATE_DATA_PATH ++/*----------------------------------------------------------------------------*/ ++/* Bluetooth over Wi-Fi Net Device Init/Uninit */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName); ++ ++BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo); ++#endif /* CFG_BOW_SEPARATE_DATA_PATH */ ++#endif /* CFG_ENABLE_BT_OVER_WIFI */ ++ ++/*----------------------------------------------------------------------------*/ ++/* Firmware Download Handling */ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* Security Frame Clearance */ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Management Frame Clearance */ ++/*----------------------------------------------------------------------------*/ ++VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); ++ ++UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval); ++ ++BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status); ++ ++UINT_32 kalRandomNumber(VOID); ++ ++VOID kalTimeoutHandler(struct timer_list *t); ++ ++VOID kalSetEvent(P_GLUE_INFO_T pr); ++ ++/*----------------------------------------------------------------------------*/ ++/* NVRAM/Registry Service */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo); ++ ++P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, ++ OUT PUINT_16 pu2Part1CfgOwnVersion, ++ OUT PUINT_16 pu2Part1CfgPeerVersion, ++ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion); ++ ++BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data); ++ ++BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, IN UINT_16 u2Data); ++ ++/*----------------------------------------------------------------------------*/ ++/* WSC Connection */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo); ++ ++/*----------------------------------------------------------------------------*/ ++/* RSSI Updating */ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); ++ ++/*----------------------------------------------------------------------------*/ ++/* I/O Buffer Pre-allocation */ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalInitIOBuffer(VOID); ++ ++VOID kalUninitIOBuffer(VOID); ++ ++PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize); ++ ++VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size); ++ ++VOID ++kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); ++ ++BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo); ++ ++ULONG kalIOPhyAddrGet(IN ULONG VirtAddr); ++ ++VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr); ++ ++#if CFG_SUPPORT_802_11W ++/*----------------------------------------------------------------------------*/ ++/* 802.11W */ ++/*----------------------------------------------------------------------------*/ ++UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo); ++#endif ++ ++UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size); ++ ++/*----------------------------------------------------------------------------*/ ++/* NL80211 */ ++/*----------------------------------------------------------------------------*/ ++VOID ++kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBuf, IN UINT_32 u4BufLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength); ++ ++/*----------------------------------------------------------------------------*/ ++/* PNO Support */ ++/*----------------------------------------------------------------------------*/ ++VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++int tx_thread(void *data); ++ ++VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo); ++VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb); ++VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); ++int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo); ++int kalMetRemoveProcfs(void); ++ ++UINT_64 kalGetBootTime(void); ++ ++INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize); ++#if CFG_SUPPORT_WAKEUP_REASON_DEBUG ++BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter); ++#endif ++INT_32 kalHaltLock(UINT_32 waitMs); ++INT_32 kalHaltTryLock(VOID); ++VOID kalHaltUnlock(VOID); ++VOID kalSetHalted(BOOLEAN fgHalt); ++BOOLEAN kalIsHalted(VOID); ++ ++INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo); ++INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo); ++VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam); ++INT32 kalBoostCpu(UINT_32 core_num); ++ ++#endif /* _GL_KAL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h +new file mode 100644 +index 000000000000..a4321e7f9a11 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h +@@ -0,0 +1,1270 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_os.h#2 ++*/ ++ ++/*! \file gl_os.h ++ \brief List the external reference to OS for GLUE Layer. ++ ++ In this file we define the data structure - GLUE_INFO_T to store those objects ++ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the ++ external reference (header file, extern func() ..) to OS for GLUE Layer should ++ also list down here. ++*/ ++ ++/* ++** Log: gl_os.h ++** ++** 08 20 2012 yuche.tsai ++** NULL ++** Fix possible KE issue. ++** ++** 08 20 2012 yuche.tsai ++** [ALPS00339327] [Rose][6575JB][BSP Package][Free Test][KE][WIFI]There is no response when you tap the turn off/on ++** button,wait a minutes, the device will reboot automatically and "KE" will pop up. ++** Fix possible KE when netlink operate mgmt frame register. ++ * ++ * 04 12 2012 terry.wu ++ * NULL ++ * Add AEE message support ++ * 1) Show AEE warning(red screen) if SDIO access error occurs ++ ++ * ++ * 03 02 2012 terry.wu ++ * NULL ++ * Enable CFG80211 Support. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 12 13 2011 cm.chang ++ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer ++ * Add wake lock if timer timeout value is smaller than 5 seconds ++ * ++ * 11 18 2011 yuche.tsai ++ * NULL ++ * CONFIG P2P support RSSI query, default turned off. ++ * ++ * 11 16 2011 yuche.tsai ++ * NULL ++ * Avoid using work thread. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 29 2011 terry.wu ++ * NULL ++ * Show DRV_NAME by chip id. ++ * ++ * 04 18 2011 terry.wu ++ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED ++ * Remove flag CFG_WIFI_DIRECT_MOVED. ++ * ++ * 03 29 2011 cp.wu ++ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for ++ * RESET_START and RESET_END events ++ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * support concurrent network ++ * ++ * 03 03 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * modify net device relative functions to support multiple H/W queues ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 02 21 2011 cp.wu ++ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain ++ * simplify logic for checking NVRAM existence only once. ++ * ++ * 02 16 2011 jeffrey.chang ++ * NULL ++ * Add query ipv4 and ipv6 address during early suspend and late resume ++ * ++ * 02 10 2011 chinghwa.yu ++ * [WCXRP00000065] Update BoW design and settings ++ * Fix kernel API change issue. ++ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is ++ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); ++ * After ALPS 2.3, kfifo_alloc() is changed to ++ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); ++ * ++ * 02 09 2011 wh.su ++ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module with structure miss-align ++ * pointer issue ++ * always pre-allio WAPI related structure for align p2p module. ++ * ++ * 02 09 2011 terry.wu ++ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules ++ * Halt p2p module init and exit until TxThread finished p2p register and unregister. ++ * ++ * 02 01 2011 cm.chang ++ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode ++ * . ++ * ++ * 01 27 2011 cm.chang ++ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default ++ * . ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP ++ * implementation of separate BT_OVER_WIFI data path. ++ * ++ * 01 12 2011 cp.wu ++ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation ++ * needs such information ++ * fill mac header length information for 802.1x frames. ++ * ++ * 01 11 2011 chinglan.wang ++ * NULL ++ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish ++ * successfully. ++ * Use the WPS function to connect AP, the privacy bit always is set to 1. ++ * ++ * 01 10 2011 cp.wu ++ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues ++ * due to multiple access ++ * use mutex to protect kalIoctl() for thread safe. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 28 2010 wh.su ++ * NULL ++ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 09 13 2010 cp.wu ++ * NULL ++ * add waitq for poll() and read(). ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 09 06 2010 wh.su ++ * NULL ++ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. ++ * ++ * 09 03 2010 kevin.huang ++ * NULL ++ * Refine #include sequence and solve recursive/nested #include issue ++ * ++ * 09 01 2010 wh.su ++ * NULL ++ * adding the wapi support for integration test. ++ * ++ * 08 31 2010 kevin.huang ++ * NULL ++ * Use LINK LIST operation to process SCAN result ++ * ++ * 08 23 2010 cp.wu ++ * NULL ++ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * revised implementation of Wi-Fi Direct io controls. ++ * ++ * 08 11 2010 cp.wu ++ * NULL ++ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) ++ * 2) extending scanning result to 64 instead of 48 ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 08 02 2010 jeffrey.chang ++ * NULL ++ * 1) modify tx service thread to avoid busy looping ++ * 2) add spin lock declartion for linux build ++ * ++ * 07 23 2010 jeffrey.chang ++ * ++ * add new KAL api ++ * ++ * 07 22 2010 jeffrey.chang ++ * ++ * modify tx thread and remove some spinlock ++ * ++ * 07 19 2010 jeffrey.chang ++ * ++ * add security frame pending count ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl to configure scan mode for p2p connection ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++ * 05 10 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement basic wi-fi direct framework ++ * ++ * 05 07 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * prevent supplicant accessing driver during resume ++ * ++ * 05 07 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add basic framework for implementating P2P driver hook. ++ * ++ * 05 05 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * change variable names for multiple physical link to match with coding convention ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame ++ * ++ * 04 27 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add multiple physical link support ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * 1) fix firmware download bug ++ * 2) remove query statistics for acelerating firmware download ++ * ++ * 04 27 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * follow Linux's firmware framework, and remove unused kal API ++ * ++ * 04 23 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * surpress compiler warning ++ * ++ * 04 19 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * supporting power management ++ * ++ * 04 14 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * pvInformationBuffer and u4InformationBufferLength are no longer in glue ++ * ++ * 04 13 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add framework for BT-over-Wi-Fi support. ++ * * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple ++ * * * * * * * * * * * * * * * * * * * * handler capability ++ * * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically ++ * * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other ++ * * * * * * * * * * * * * * * * * * * * purpose ++ * ++ * 04 07 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * rWlanInfo should be placed at adapter rather than glue due to most operations ++ * * * * * * * * * * are done in adapter layer. ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * Tag the packet for QoS on Tx path ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * (1)deliver the kalOidComplete status to upper layer ++ * * (2) fix spin lock ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * add timeout check in the kalOidComplete ++ * ++ * 04 06 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * improve none-glue code portability ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved ++ * ++ * 04 06 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer ++ * ++ * 03 30 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * emulate NDIS Pending OID facility ++ * ++ * 03 26 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * [WPD00003826] Initial import for Linux port ++ * adding firmware download related data type ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00001943]Create WiFi test driver framework on WinXP ++ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. ++ * * * * the frequency is used for adhoc connection only ++ * * * * 2) update with SD1 v0.9 CMD/EVENT documentation ++ * ++ * 03 25 2010 cp.wu ++ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support ++ * add Bluetooth-over-Wifi frame header check ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\30 2009-10-20 17:38:31 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\29 2009-10-08 10:33:33 GMT mtk01090 ++** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input ++** parameters and pointers. ++** \main\maintrunk.MT5921\28 2009-09-28 20:19:26 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\27 2009-08-18 22:57:12 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\26 2009-07-06 21:42:25 GMT mtk01088 ++** fixed the compiling error at linux ++** \main\maintrunk.MT5921\25 2009-07-06 20:51:46 GMT mtk01088 ++** adding the wapi 1x ether type define ++** \main\maintrunk.MT5921\24 2009-06-23 23:19:18 GMT mtk01090 ++** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support ++** \main\maintrunk.MT5921\23 2009-02-07 15:05:06 GMT mtk01088 ++** add the privacy flag to ingo driver the supplicant selected ap's security ++** \main\maintrunk.MT5921\22 2009-02-05 15:34:09 GMT mtk01088 ++** fixed the compiling error for using bits marco for only one parameter ++** \main\maintrunk.MT5921\21 2009-01-22 13:02:13 GMT mtk01088 ++** data frame is or not 802.1x value share with tid, using the same reserved byte, provide the function to set and get ++** \main\maintrunk.MT5921\20 2008-10-24 12:04:16 GMT mtk01088 ++** move the config.h from precomp.h to here for lint check ++** \main\maintrunk.MT5921\19 2008-09-22 23:19:02 GMT mtk01461 ++** Update driver for code review ++** \main\maintrunk.MT5921\18 2008-09-05 17:25:13 GMT mtk01461 ++** Update Driver for Code Review ++** \main\maintrunk.MT5921\17 2008-08-01 13:32:47 GMT mtk01084 ++** Prevent redundent driver assertion in driver logic when BUS is detached ++** \main\maintrunk.MT5921\16 2008-05-30 14:41:43 GMT mtk01461 ++** Remove WMM Assoc Flag in KAL ++** \main\maintrunk.MT5921\15 2008-05-29 14:16:25 GMT mtk01084 ++** remoev un-used variable ++** \main\maintrunk.MT5921\14 2008-05-03 15:17:14 GMT mtk01461 ++** Add Media Status variable in Glue Layer ++** \main\maintrunk.MT5921\13 2008-04-24 11:58:41 GMT mtk01461 ++** change threshold to 256 ++** \main\maintrunk.MT5921\12 2008-03-11 14:51:05 GMT mtk01461 ++** Remove redundant GL_CONN_INFO_T ++** \main\maintrunk.MT5921\11 2008-01-07 15:07:41 GMT mtk01461 ++** Adjust the netif stop threshold to 150 ++** \main\maintrunk.MT5921\10 2007-11-26 19:43:46 GMT mtk01461 ++** Add OS_TIMESTAMP macro ++** ++** \main\maintrunk.MT5921\9 2007-11-07 18:38:38 GMT mtk01461 ++** Move definition ++** \main\maintrunk.MT5921\8 2007-11-02 01:04:00 GMT mtk01461 ++** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning ++** Revision 1.5 2007/07/12 11:04:28 MTK01084 ++** update macro to delay for ms order ++** ++** Revision 1.4 2007/07/05 07:25:34 MTK01461 ++** Add Linux initial code, modify doc, add 11BB, RF init code ++** ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++#ifndef _GL_OS_H ++#define _GL_OS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++/*------------------------------------------------------------------------------ ++ * Flags for LINUX(OS) dependent ++ *------------------------------------------------------------------------------ ++ */ ++#define CFG_MAX_WLAN_DEVICES 1 /* number of wlan card will coexist */ ++ ++#define CFG_MAX_TXQ_NUM 4 /* number of tx queue for support multi-queue h/w */ ++ ++#define CFG_USE_SPIN_LOCK_BOTTOM_HALF 0 /* 1: Enable use of SPIN LOCK Bottom Half for LINUX ++ 0: Disable - use SPIN LOCK IRQ SAVE instead */ ++ ++#define CFG_TX_PADDING_SMALL_ETH_PACKET 0 /* 1: Enable - Drop ethernet packet if it < 14 bytes. ++ And pad ethernet packet with dummy 0 if it < 60 bytes. ++ 0: Disable */ ++ ++#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD 256 /* packets */ ++ ++#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 256 /* packets */ ++#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 128 /* packets */ ++ ++#define ETH_P_1X 0x888E ++#define IPTOS_PREC_OFFSET 5 ++#define USER_PRIORITY_DEFAULT 0 ++ ++#define ETH_WPI_1X 0x88B4 ++ ++#define ETH_HLEN 14 ++#define ETH_TYPE_LEN_OFFSET 12 ++#define ETH_P_IP 0x0800 ++#define ETH_P_1X 0x888E ++#define ETH_P_PRE_1X 0x88C7 ++#define ETH_P_ARP 0x0806 ++ ++#define ARP_PRO_REQ 1 ++#define ARP_PRO_RSP 2 ++ ++#define IPVERSION 4 ++#define IP_HEADER_LEN 20 ++ ++#define IP_PRO_ICMP 0x01 ++#define IP_PRO_UDP 0x11 ++#define IP_PRO_TCP 0x06 ++ ++#define UDP_PORT_DHCPS 0x43 ++#define UDP_PORT_DHCPC 0x44 ++#define UDP_PORT_DNS 0x35 ++ ++#define IPVH_VERSION_OFFSET 4 /* For Little-Endian */ ++#define IPVH_VERSION_MASK 0xF0 ++#define IPTOS_PREC_OFFSET 5 ++#define IPTOS_PREC_MASK 0xE0 ++ ++#define SOURCE_PORT_LEN 2 ++/* NOTE(Kevin): Without IP Option Length */ ++#define LOOK_AHEAD_LEN (ETH_HLEN + IP_HEADER_LEN + SOURCE_PORT_LEN) ++ ++/* 802.2 LLC/SNAP */ ++#define ETH_LLC_OFFSET (ETH_HLEN) ++#define ETH_LLC_LEN 3 ++#define ETH_LLC_DSAP_SNAP 0xAA ++#define ETH_LLC_SSAP_SNAP 0xAA ++#define ETH_LLC_CONTROL_UNNUMBERED_INFORMATION 0x03 ++ ++/* Bluetooth SNAP */ ++#define ETH_SNAP_OFFSET (ETH_HLEN + ETH_LLC_LEN) ++#define ETH_SNAP_LEN 5 ++#define ETH_SNAP_BT_SIG_OUI_0 0x00 ++#define ETH_SNAP_BT_SIG_OUI_1 0x19 ++#define ETH_SNAP_BT_SIG_OUI_2 0x58 ++ ++#define BOW_PROTOCOL_ID_SECURITY_FRAME 0x0003 ++ ++#if defined(MT6620) ++#define CHIP_NAME "MT6620" ++#elif defined(MT6628) ++#define CHIP_NAME "MT6582" ++#endif ++ ++#define DRV_NAME "["CHIP_NAME"]: " ++ ++#define CONFIG_ANDROID 1 ++/* Define if target platform is Android. ++ * It should already be defined in Android kernel source ++ */ ++ ++/* for CFG80211 IE buffering mechanism */ ++#define CFG_CFG80211_IE_BUF_LEN (512) ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include /* constant of kernel version */ ++ ++#include /* bitops.h */ ++ ++#include /* struct timer_list */ ++#include /* jiffies */ ++#include /* udelay and mdelay macro */ ++ ++#if CONFIG_ANDROID ++#include ++#endif ++ ++#include /* IRQT_FALLING */ ++ ++#include /* struct net_device, struct net_device_stats */ ++#include /* for eth_type_trans() function */ ++#include /* struct iw_statistics */ ++#include ++#include /* struct in_device */ ++ ++#include /* struct iphdr */ ++ ++#include /* for memcpy()/memset() function */ ++#include /* for offsetof() macro */ ++ ++#include /* The proc filesystem constants/structures */ ++ ++#include /* for rtnl_lock() and rtnl_unlock() */ ++#include /* kthread_should_stop(), kthread_run() */ ++#include /* for copy_from_user() */ ++#include /* for firmware download */ ++#include ++ ++#include /* for kfifo interface */ ++#include /* for cdev interface */ ++ ++#include /* for firmware download */ ++ ++#if defined(_HIF_SDIO) ++#include ++#include ++#endif ++ ++#include ++ ++#include ++#include ++ ++#include /* readw and writew */ ++ ++#if WIRELESS_EXT > 12 ++#include ++#endif ++ ++#include "version.h" ++#include "config.h" ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#include ++#endif ++ ++#include ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++#include ++#endif ++ ++#include "gl_typedef.h" ++#include "typedef.h" ++#include "queue.h" ++#include "gl_kal.h" ++#include "hif.h" ++#if CFG_CHIP_RESET_SUPPORT ++#include "gl_rst.h" ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++#include "tdls_extr.h" ++#endif ++#include "debug.h" ++ ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++ ++#if CFG_ENABLE_AEE_MSG ++#include ++#endif ++ ++extern BOOLEAN fgIsBusAccessFailed; ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define GLUE_FLAG_HALT BIT(0) ++#define GLUE_FLAG_INT BIT(1) ++#define GLUE_FLAG_OID BIT(2) ++#define GLUE_FLAG_TIMEOUT BIT(3) ++#define GLUE_FLAG_TXREQ BIT(4) ++#define GLUE_FLAG_SUB_MOD_INIT BIT(5) ++#define GLUE_FLAG_SUB_MOD_EXIT BIT(6) ++#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7) ++#define GLUE_FLAG_FRAME_FILTER BIT(8) ++#define GLUE_FLAG_FRAME_FILTER_AIS BIT(9) ++#define GLUE_FLAG_HIF_LOOPBK_AUTO BIT(10) ++#define GLUE_FLAG_HALT_BIT (0) ++#define GLUE_FLAG_INT_BIT (1) ++#define GLUE_FLAG_OID_BIT (2) ++#define GLUE_FLAG_TIMEOUT_BIT (3) ++#define GLUE_FLAG_TXREQ_BIT (4) ++#define GLUE_FLAG_SUB_MOD_INIT_BIT (5) ++#define GLUE_FLAG_SUB_MOD_EXIT_BIT (6) ++#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7) ++#define GLUE_FLAG_FRAME_FILTER_BIT (8) ++#define GLUE_FLAG_FRAME_FILTER_AIS_BIT (9) ++#define GLUE_FLAG_HIF_LOOPBK_AUTO_BIT (10) ++ ++#define GLUE_BOW_KFIFO_DEPTH (1024) ++/* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ ++#define GLUE_BOW_DEVICE_NAME "ampc0" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _GL_WPA_INFO_T { ++ UINT_32 u4WpaVersion; ++ UINT_32 u4KeyMgmt; ++ UINT_32 u4CipherGroup; ++ UINT_32 u4CipherPairwise; ++ UINT_32 u4AuthAlg; ++ BOOLEAN fgPrivacyInvoke; ++#if CFG_SUPPORT_802_11W ++ UINT_32 u4Mfp; ++#endif ++} GL_WPA_INFO_T, *P_GL_WPA_INFO_T; ++ ++typedef enum _ENUM_RSSI_TRIGGER_TYPE { ++ ENUM_RSSI_TRIGGER_NONE, ++ ENUM_RSSI_TRIGGER_GREATER, ++ ENUM_RSSI_TRIGGER_LESS, ++ ENUM_RSSI_TRIGGER_TRIGGERED, ++ ENUM_RSSI_TRIGGER_NUM ++} ENUM_RSSI_TRIGGER_TYPE; ++ ++#if CFG_ENABLE_WIFI_DIRECT ++typedef enum _ENUM_SUB_MODULE_IDX_T { ++ P2P_MODULE = 0, ++ SUB_MODULE_NUM ++} ENUM_SUB_MODULE_IDX_T; ++ ++typedef enum _ENUM_NET_REG_STATE_T { ++ ENUM_NET_REG_STATE_UNREGISTERED, ++ ENUM_NET_REG_STATE_REGISTERING, ++ ENUM_NET_REG_STATE_REGISTERED, ++ ENUM_NET_REG_STATE_UNREGISTERING, ++ ENUM_NET_REG_STATE_NUM ++} ENUM_NET_REG_STATE_T; ++ ++#endif ++ ++typedef struct _GL_IO_REQ_T { ++ QUE_ENTRY_T rQueEntry; ++ /* wait_queue_head_t cmdwait_q; */ ++ BOOLEAN fgRead; ++ BOOLEAN fgWaitResp; ++#if CFG_ENABLE_WIFI_DIRECT ++ BOOLEAN fgIsP2pOid; ++#endif ++ P_ADAPTER_T prAdapter; ++ PFN_OID_HANDLER_FUNC pfnOidHandler; ++ PVOID pvInfoBuf; ++ UINT_32 u4InfoBufLen; ++ PUINT_32 pu4QryInfoLen; ++ WLAN_STATUS rStatus; ++ UINT_32 u4Flag; ++} GL_IO_REQ_T, *P_GL_IO_REQ_T; ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++typedef struct _GL_BOW_INFO { ++ BOOLEAN fgIsRegistered; ++ dev_t u4DeviceNumber; /* dynamic device number */ ++/* struct kfifo *prKfifo; */ /* for buffering indicated events */ ++ struct kfifo rKfifo; /* for buffering indicated events */ ++ spinlock_t rSpinLock; /* spin lock for kfifo */ ++ struct cdev cdev; ++ UINT_32 u4FreqInKHz; /* frequency */ ++ ++ UINT_8 aucRole[CFG_BOW_PHYSICAL_LINK_NUM]; /* 0: Responder, 1: Initiator */ ++ ENUM_BOW_DEVICE_STATE aeState[CFG_BOW_PHYSICAL_LINK_NUM]; ++ PARAM_MAC_ADDRESS arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM]; ++ ++ wait_queue_head_t outq; ++ ++#if CFG_BOW_SEPARATE_DATA_PATH ++ /* Device handle */ ++ struct net_device *prDevHandler; ++ BOOLEAN fgIsNetRegistered; ++#endif ++ ++} GL_BOW_INFO, *P_GL_BOW_INFO; ++#endif ++ ++#if (CFG_SUPPORT_TDLS == 1) ++typedef struct _TDLS_INFO_LINK_T { ++ /* start time when link is built, end time when link is broken */ ++ unsigned long jiffies_start, jiffies_end; ++ ++ /* the peer MAC */ ++ UINT8 aucPeerMac[6]; ++ ++ /* broken reason */ ++ UINT8 ucReasonCode; ++ ++ /* TRUE: torn down is triggerred by us */ ++ UINT8 fgIsFromUs; ++ ++ /* duplicate count; same reason */ ++ UINT8 ucDupCount; ++ ++ /* HT capability */ ++#define TDLS_INFO_LINK_HT_CAP_SUP 0x01 ++ UINT8 ucHtCap; ++#define TDLS_INFO_LINK_HT_BA_SETUP 0x01 ++#define TDLS_INFO_LINK_HT_BA_SETUP_OK 0x02 ++#define TDLS_INFO_LINK_HT_BA_SETUP_DECLINE 0x04 ++#define TDLS_INFO_LINK_HT_BA_PEER 0x10 ++#define TDLS_INFO_LINK_HT_BA_RSP_OK 0x20 ++#define TDLS_INFO_LINK_HT_BA_RSP_DECLINE 0x40 ++ UINT8 ucHtBa[8]; /* TID0 ~ TID7 */ ++} TDLS_INFO_LINK_T; ++ ++typedef struct _TDLS_INFO_T { ++ /* link history */ ++#define TDLS_LINK_HISTORY_MAX 30 ++ TDLS_INFO_LINK_T rLinkHistory[TDLS_LINK_HISTORY_MAX]; ++ UINT32 u4LinkIdx; ++ ++ /* TRUE: support 20/40 bandwidth in TDLS link */ ++ BOOLEAN fgIs2040Sup; ++ ++ /* total TDLS link count */ ++ INT8 cLinkCnt; ++} TDLS_INFO_T; ++#endif /* CFG_SUPPORT_TDLS */ ++ ++/* ++* type definition of pointer to p2p structure ++*/ ++typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; ++ ++struct _GLUE_INFO_T { ++ /* Device handle */ ++ struct net_device *prDevHandler; ++ ++ /* Device Index(index of arWlanDevInfo[]) */ ++ INT_32 i4DevIdx; ++ ++ /* Device statistics */ ++ struct net_device_stats rNetDevStats; ++ ++ /* Wireless statistics struct net_device */ ++ struct iw_statistics rIwStats; ++ ++ /* spinlock to sync power save mechanism */ ++ spinlock_t rSpinLock[SPIN_LOCK_NUM]; ++ ++ /* semaphore for ioctl */ ++ struct semaphore ioctl_sem; ++ ++ UINT_64 u8Cookie; ++ ++ ULONG ulFlag; /* GLUE_FLAG_XXX */ ++ UINT_32 u4PendFlag; ++ /* UINT_32 u4TimeoutFlag; */ ++ UINT_32 u4OidCompleteFlag; ++ UINT_32 u4ReadyFlag; /* check if card is ready */ ++ ++ UINT_32 u4OsMgmtFrameFilter; ++ ++ /* Number of pending frames, also used for debuging if any frame is ++ * missing during the process of unloading Driver. ++ * ++ * NOTE(Kevin): In Linux, we also use this variable as the threshold ++ * for manipulating the netif_stop(wake)_queue() func. ++ */ ++ INT_32 ai4TxPendingFrameNumPerQueue[4][CFG_MAX_TXQ_NUM]; ++ INT_32 i4TxPendingFrameNum; ++ INT_32 i4TxPendingSecurityFrameNum; ++ ++ /* current IO request for kalIoctl */ ++ GL_IO_REQ_T OidEntry; ++ ++ /* registry info */ ++ REG_INFO_T rRegInfo; ++ ++ /* firmware */ ++ struct firmware *prFw; ++ ++ /* Host interface related information */ ++ /* defined in related hif header file */ ++ GL_HIF_INFO_T rHifInfo; ++ ++ /*! \brief wext wpa related information */ ++ GL_WPA_INFO_T rWpaInfo; ++ ++ /* Pointer to ADAPTER_T - main data structure of internal protocol stack */ ++ P_ADAPTER_T prAdapter; ++ ++#ifdef WLAN_INCLUDE_PROC ++ struct proc_dir_entry *pProcRoot; ++#endif /* WLAN_INCLUDE_PROC */ ++ ++ /* Indicated media state */ ++ ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicated; ++ ++ /* Device power state D0~D3 */ ++ PARAM_DEVICE_POWER_STATE ePowerState; ++ ++ struct completion rScanComp; /* indicate scan complete */ ++ struct completion rHaltComp; /* indicate main thread halt complete */ ++ struct completion rPendComp; /* indicate main thread halt complete */ ++#if CFG_ENABLE_WIFI_DIRECT ++ struct completion rSubModComp; /*indicate sub module init or exit complete */ ++#endif ++ WLAN_STATUS rPendStatus; ++ ++ QUE_T rTxQueue; ++ ++ /* OID related */ ++ QUE_T rCmdQueue; ++ /* PVOID pvInformationBuffer; */ ++ /* UINT_32 u4InformationBufferLength; */ ++ /* PVOID pvOidEntry; */ ++ /* PUINT_8 pucIOReqBuff; */ ++ /* QUE_T rIOReqQueue; */ ++ /* QUE_T rFreeIOReqQueue; */ ++ ++ wait_queue_head_t waitq; ++ struct task_struct *main_thread; ++ ++ struct timer_list tickfn; ++ ++#if CFG_SUPPORT_EXT_CONFIG ++ UINT_16 au2ExtCfg[256]; /* NVRAM data buffer */ ++ UINT_32 u4ExtCfgLength; /* 0 means data is NOT valid */ ++#endif ++ ++#if 1 /* CFG_SUPPORT_WAPI */ ++ /* Should be large than the PARAM_WAPI_ASSOC_INFO_T */ ++ UINT_8 aucWapiAssocInfoIEs[42]; ++ UINT_16 u2WapiAssocInfoIESz; ++#endif ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++ GL_BOW_INFO rBowInfo; ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ P_GL_P2P_INFO_T prP2PInfo; ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++ /* Wireless statistics struct net_device */ ++ struct iw_statistics rP2pIwStats; ++#endif ++#endif ++ BOOLEAN fgWpsActive; ++ UINT_8 aucWSCIE[500]; /*for probe req */ ++ UINT_16 u2WSCIELen; ++ UINT_8 aucWSCAssocInfoIE[200]; /*for Assoc req */ ++ UINT_16 u2WSCAssocInfoIELen; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ UINT_8 aucHS20AssocInfoIE[200]; /*for Assoc req */ ++ UINT_16 u2HS20AssocInfoIELen; ++ UINT_8 ucHotspotConfig; ++ BOOLEAN fgConnectHS20AP; ++#endif ++ ++ /* NVRAM availability */ ++ BOOLEAN fgNvramAvailable; ++ ++ BOOLEAN fgMcrAccessAllowed; ++ ++ /* MAC Address Overridden by IOCTL */ ++ BOOLEAN fgIsMacAddrOverride; ++ PARAM_MAC_ADDRESS rMacAddrOverride; ++ ++ SET_TXPWR_CTRL_T rTxPwr; ++ ++ /* for cfg80211 scan done indication */ ++ struct cfg80211_scan_request *prScanRequest; ++ ++ /* for cfg80211 scheduled scan */ ++ struct cfg80211_sched_scan_request *prSchedScanRequest; ++ ++ /* to indicate registered or not */ ++ BOOLEAN fgIsRegistered; ++ ++ /* for cfg80211 connected indication */ ++ UINT_32 u4RspIeLength; ++ UINT_8 aucRspIe[CFG_CFG80211_IE_BUF_LEN]; ++ ++ UINT_32 u4ReqIeLength; ++ UINT_8 aucReqIe[CFG_CFG80211_IE_BUF_LEN]; ++ ++ KAL_WAKE_LOCK_T rAhbIsrWakeLock; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ BOOLEAN fgIsDad; ++ UINT_8 aucDADipv4[4]; ++ BOOLEAN fgIs6Dad; ++ UINT_8 aucDADipv6[16]; ++#endif ++#if (CFG_SUPPORT_MET_PROFILING == 1) ++ UINT_8 u8MetProfEnable; ++ INT_16 u16MetUdpPort; ++#endif ++ BOOLEAN fgPoorlinkValid; ++ UINT_64 u8Statistic[2]; ++ UINT_64 u8TotalFailCnt; ++ UINT_32 u4LinkspeedThreshold; ++ INT_32 i4RssiThreshold; ++ INT_32 i4RssiCache; ++ UINT_32 u4LinkSpeedCache; ++ ++#if (CFG_SUPPORT_TDLS == 1) ++ TDLS_INFO_T rTdlsLink; ++ ++ UINT8 aucTdlsHtPeerMac[6]; ++ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ ++ ++ /* ++ [0~7]: jiffies ++ [8~13]: Peer MAC ++ [14]: Reason Code ++ [15]: From us or peer ++ [16]: Duplicate Count ++ */ ++/* UINT8 aucTdlsDisconHistory[TDLS_DISCON_HISTORY_MAX][20]; */ ++/* UINT32 u4TdlsDisconIdx; */ ++#endif /* CFG_SUPPORT_TDLS */ ++ UINT_32 IsrCnt; ++ UINT_32 IsrPassCnt; ++ UINT_32 TaskIsrCnt; ++ ++ UINT_32 IsrPreCnt; ++ UINT_32 IsrPrePassCnt; ++ UINT_32 TaskPreIsrCnt; ++ ++ UINT_32 IsrAbnormalCnt; ++ UINT_32 IsrSoftWareCnt; ++ UINT_32 IsrTxCnt; ++ UINT_32 IsrRxCnt; ++ UINT_64 u8SkbToDriver; ++ UINT_64 u8SkbFreed; ++}; ++ ++typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, struct pt_regs *regs); ++ ++typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long); ++ ++/* generic sub module init/exit handler ++* now, we only have one sub module, p2p ++*/ ++#if CFG_ENABLE_WIFI_DIRECT ++typedef BOOLEAN(*SUB_MODULE_INIT) (P_GLUE_INFO_T prGlueInfo); ++typedef BOOLEAN(*SUB_MODULE_EXIT) (P_GLUE_INFO_T prGlueInfo); ++ ++typedef struct _SUB_MODULE_HANDLER { ++ SUB_MODULE_INIT subModInit; ++ SUB_MODULE_EXIT subModExit; ++ BOOLEAN fgIsInited; ++} SUB_MODULE_HANDLER, *P_SUB_MODULE_HANDLER; ++ ++#endif ++ ++ ++#ifdef CONFIG_NL80211_TESTMODE ++enum TestModeCmdType { ++ /* old test mode command id, compatible with exist testmode command */ ++ TESTMODE_CMD_ID_SW_CMD = 1, ++ TESTMODE_CMD_ID_WAPI = 2, ++ TESTMODE_CMD_ID_HS20 = 3, ++ TESTMODE_CMD_ID_POORLINK = 4, ++ TESTMODE_CMD_ID_STATISTICS = 0x10, ++ TESTMODE_CMD_ID_LINK_DETECT = 0x20, ++ /* old test mode command id, compatible with exist testmode command */ ++ ++ /* all new added test mode command should great than TESTMODE_CMD_ID_NEW_BEGIN */ ++ TESTMODE_CMD_ID_NEW_BEGIN = 100, ++ TESTMODE_CMD_ID_SUSPEND = 101, ++}; ++#if CFG_SUPPORT_HOTSPOT_2_0 ++enum Hs20CmdType { ++ HS20_CMD_ID_SET_BSSID_POOL = 0, ++ NUM_OF_HS20_CMD_ID ++}; ++#endif ++ ++typedef struct _NL80211_DRIVER_TEST_MODE_PARAMS { ++ UINT_32 index; ++ UINT_32 buflen; ++} NL80211_DRIVER_TEST_MODE_PARAMS, *P_NL80211_DRIVER_TEST_MODE_PARAMS; ++ ++/*SW CMD */ ++typedef struct _NL80211_DRIVER_SW_CMD_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_8 set; ++ UINT_32 adr; ++ UINT_32 data; ++} NL80211_DRIVER_SW_CMD_PARAMS, *P_NL80211_DRIVER_SW_CMD_PARAMS; ++ ++typedef struct _NL80211_DRIVER_SUSPEND_PARAMS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_8 suspend; ++} NL80211_DRIVER_SUSPEND_PARAMS, *P_NL80211_DRIVER_SUSPEND_PARAMS; ++struct iw_encode_exts { ++ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ ++ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ __u8 addr[MAC_ADDR_LEN]; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast ++ * (group) keys or unicast address for ++ * individual keys */ ++ __u16 alg; /*!< IW_ENCODE_ALG_* */ ++ __u16 key_len; ++ __u8 key[32]; ++}; ++ ++/*SET KEY EXT */ ++typedef struct _NL80211_DRIVER_SET_KEY_EXTS { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ UINT_8 key_index; ++ UINT_8 key_len; ++ struct iw_encode_exts ext; ++} NL80211_DRIVER_SET_KEY_EXTS, *P_NL80211_DRIVER_SET_KEY_EXTS; ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ ++struct param_hs20_set_bssid_pool { ++ u8 fgBssidPoolIsEnable; ++ u8 ucNumBssidPool; ++ u8 arBssidPool[8][ETH_ALEN]; ++}; ++ ++struct wpa_driver_hs20_data_s { ++ NL80211_DRIVER_TEST_MODE_PARAMS hdr; ++ enum Hs20CmdType CmdType; ++ struct param_hs20_set_bssid_pool hs20_set_bssid_pool; ++}; ++ ++#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ ++ ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Macros of SPIN LOCK operations for using in Glue Layer */ ++/*----------------------------------------------------------------------------*/ ++#if CFG_USE_SPIN_LOCK_BOTTOM_HALF ++#define GLUE_SPIN_LOCK_DECLARATION() ++#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_lock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ ++ } ++#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_unlock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ ++ } ++#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ ++ spin_lock_bh(prLock) ++#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ ++ spin_unlock_bh(prLock) ++ ++#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++#define GLUE_SPIN_LOCK_DECLARATION() unsigned long __u4Flags = 0 ++#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_lock_irqsave(&(prGlueInfo)->rSpinLock[rLockCategory], __u4Flags); \ ++ } ++#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ ++ { \ ++ if (rLockCategory < SPIN_LOCK_NUM) \ ++ spin_unlock_irqrestore(&(prGlueInfo->rSpinLock[rLockCategory]), __u4Flags); \ ++ } ++#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ ++ spin_lock_irqsave(prLock, __u4Flags) ++#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ ++ spin_unlock_irqrestore(prLock, __u4Flags) ++#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ ++ ++/*----------------------------------------------------------------------------*/ ++/* Macros for accessing Reserved Fields of native packet */ ++/*----------------------------------------------------------------------------*/ ++#define GLUE_CB_OFFSET 4 /* For 64-bit platform, avoiding that the cb ++ isoverwrited by "(prQueueEntry)->prNext = ++ (P_QUE_ENTRY_T)NULL;" in QUEUE_INSERT_TAIL */ ++#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ ++ (&(((struct sk_buff *)(_p))->cb[0])) ++ ++#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) \ ++ ((P_NATIVE_PACKET) ((ULONG)_prQueueEntry - offsetof(struct sk_buff, cb[0]))) ++ ++#define GLUE_SET_PKT_FLAG_802_11(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(7)) ++ ++#define GLUE_SET_PKT_FLAG_1X(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(6)) ++ ++#define GLUE_SET_PKT_FLAG_PAL(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(5)) ++ ++#define GLUE_SET_PKT_FLAG_P2P(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(4)) ++ ++#define GLUE_SET_PKT_TID(_p, _tid) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= (((UINT_8)((_tid) & (BITS(0, 3)))))) ++ ++#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ ++ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6])) = (UINT_16)(_u2PayloadLen)) ++ ++#define GLUE_GET_PKT_FRAME_LEN(_p) \ ++ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6]))) ++ ++#define GLUE_GET_PKT_IS_802_11(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(7))) ++ ++#define GLUE_GET_PKT_IS_1X(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(6))) ++ ++#define GLUE_GET_PKT_TID(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BITS(0, 3))) ++ ++#define GLUE_GET_PKT_IS_PAL(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(5))) ++ ++#define GLUE_GET_PKT_IS_P2P(_p) \ ++ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(4))) ++ ++#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5])) = (UINT_8)(_ucMacHeaderLen)) ++ ++#define GLUE_GET_PKT_HEADER_LEN(_p) \ ++ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5]))) ++ ++#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ ++ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8])) = (OS_SYSTIME)(_rSysTime)) ++ ++#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ ++ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8]))) ++ ++#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \ ++ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16])) = (UINT_64)(_rSysTime)) ++ ++#define GLUE_GET_PKT_XTIME(_p) \ ++ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16]))) ++ ++/* Check validity of prDev, private data, and pointers */ ++#define GLUE_CHK_DEV(prDev) \ ++ ((prDev && *((P_GLUE_INFO_T *) netdev_priv(prDev))) ? TRUE : FALSE) ++ ++#define GLUE_CHK_PR2(prDev, pr2) \ ++ ((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE) ++ ++#define GLUE_CHK_PR3(prDev, pr2, pr3) \ ++ ((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE) ++ ++#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \ ++ ((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE) ++ ++#define GLUE_SET_EVENT(pr) \ ++ kalSetEvent(pr) ++ ++#define GLUE_INC_REF_CNT(_refCount) atomic_inc((atomic_t *)&(_refCount)) ++#define GLUE_DEC_REF_CNT(_refCount) atomic_dec((atomic_t *)&(_refCount)) ++ ++#define DbgPrint(...) ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++#ifdef WLAN_INCLUDE_PROC ++INT_32 procRemoveProcfs(VOID); ++ ++INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo); ++INT_32 procInitFs(VOID); ++INT_32 procUninitProcFs(VOID); ++ ++#endif /* WLAN_INCLUDE_PROC */ ++ ++#if CFG_ENABLE_BT_OVER_WIFI ++BOOLEAN glRegisterAmpc(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN glUnregisterAmpc(P_GLUE_INFO_T prGlueInfo); ++#endif ++ ++#if CFG_ENABLE_WIFI_DIRECT ++ ++VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo); ++ ++VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx); ++ ++BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr); ++ ++BOOLEAN wlanIsLaunched(VOID); ++ ++VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo); ++ ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_OS_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h +new file mode 100644 +index 000000000000..a27294e33500 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h +@@ -0,0 +1,743 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_ioctl.h#9 ++*/ ++ ++/*! \file gl_p2p_ioctl.h ++ \brief This file is for custom ioctls for Wi-Fi Direct only ++*/ ++ ++/* ++** Log: gl_p2p_ioctl.h ++** ++** 07 26 2012 yuche.tsai ++** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot ++** Update driver code of ALPS.JB for hot-spot. ++** ++** 07 19 2012 yuche.tsai ++** NULL ++** Code update for JB. ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 06 07 2011 yuche.tsai ++ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue ++ * Fix RX SD request under AP mode issue. ++ * ++ * 03 25 2011 wh.su ++ * NULL ++ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. ++ * ++ * 11 22 2011 yuche.tsai ++ * NULL ++ * Update RSSI link quality of P2P Network query method. (Bug fix) ++ * ++ * 11 19 2011 yuche.tsai ++ * NULL ++ * Add RSSI support for P2P network. ++ * ++ * 11 11 2011 yuche.tsai ++ * NULL ++ * Fix work thread cancel issue. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service ++ * discovery version check. ++ * Add support for driver version query & p2p supplicant verseion set. ++ * For new service discovery mechanism sync. ++ * ++ * 10 25 2011 cm.chang ++ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode ++ * . ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 16 2011 chinglan.wang ++ * NULL ++ * Add the group id information in the invitation indication. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 05 04 2011 chinglan.wang ++ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver ++ * . ++ * ++ * 03 29 2011 wh.su ++ * [WCXRP00000095] [MT6620 Wi-Fi] [FW] Refine the P2P GO send broadcast protected code ++ * add the set power and get power function sample. ++ * ++ * 03 22 2011 george.huang ++ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command ++ * link with supplicant commands ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 03 01 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * fixed the ioctl sumcmd to meet the p2p_supplicant setting. ++ * ++ * 02 23 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * adding the ioctl set int define for p2p parameter. ++ * ++ * 02 22 2011 wh.su ++ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver ++ * adding the ioctl set int from supplicant, and can used to set the p2p parameters ++ * ++ * 02 17 2011 wh.su ++ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request ++ * adjust the set wsc ie structure. ++ * ++ * 01 05 2011 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * ioctl implementations for P2P Service Discovery ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++ * 12 15 2010 cp.wu ++ * NULL ++ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() ++ * ++ * 12 07 2010 cp.wu ++ * [WCXRP00000237] [MT6620 Wi-Fi][Wi-Fi Direct][Driver] Add interface for supporting service discovery ++ * define a pair of i/o control for multiplexing layer ++ * ++ * 11 04 2010 wh.su ++ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID ++ * adding the p2p random ssid support. ++ * ++ * 10 20 2010 wh.su ++ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group ++ * Add the code to support disconnect p2p group ++ * ++ * 09 21 2010 kevin.huang ++ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface ++ * Isolate P2P related function for Hardware Software Bundle ++ * ++ * 09 10 2010 george.huang ++ * NULL ++ * update iwpriv LP related ++ * ++ * 09 07 2010 wh.su ++ * NULL ++ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. ++ * ++ * 08 25 2010 cp.wu ++ * NULL ++ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater ++ * ++ * 08 20 2010 yuche.tsai ++ * NULL ++ * Refine a function parameter name. ++ * ++ * 08 19 2010 cp.wu ++ * NULL ++ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. ++ * ++ * 08 16 2010 george.huang ++ * NULL ++ * add wext handlers to link P2P set PS profile/ network address function (TBD) ++ * ++ * 08 16 2010 cp.wu ++ * NULL ++ * revised implementation of Wi-Fi Direct io controls. ++ * ++ * 08 12 2010 cp.wu ++ * NULL ++ * follow-up with ioctl interface update for Wi-Fi Direct application ++ * ++ * 08 06 2010 cp.wu ++ * NULL ++ * driver hook modifications corresponding to ioctl interface change. ++ * ++ * 08 03 2010 cp.wu ++ * NULL ++ * [Wi-Fi Direct] add framework for driver hooks ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 06 01 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl to configure scan mode for p2p connection ++ * ++ * 05 31 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add cfg80211 interface, which is to replace WE, for further extension ++ * ++ * 05 17 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement get scan result. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * implement wireless extension ioctls in iw_handler form. ++ * ++ * 05 14 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * p2p ioctls revised. ++ * ++ * 05 11 2010 cp.wu ++ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support ++ * add ioctl for controlling p2p scan phase parameters ++ * ++*/ ++ ++#ifndef _GL_P2P_IOCTL_H ++#define _GL_P2P_IOCTL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#include ++#endif ++ ++#include "wlan_oid.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Device private ioctl calls */ ++/* #define SIOCDEVPRIVATE 0x89F0*/ ++#define IOC_GET_PRIVATE_IOCTL_CMD (SIOCDEVPRIVATE+1) ++ ++/* (WirelessExtension) Private I/O Controls */ ++#define IOC_P2P_CFG_DEVICE (SIOCIWFIRSTPRIV+0) ++#define IOC_P2P_PROVISION_COMPLETE (SIOCIWFIRSTPRIV+2) ++#define IOC_P2P_START_STOP_DISCOVERY (SIOCIWFIRSTPRIV+4) ++#define IOC_P2P_DISCOVERY_RESULTS (SIOCIWFIRSTPRIV+5) ++#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6) ++#define IOC_P2P_GO_WSC_IE IOC_P2P_WSC_BEACON_PROBE_RSP_IE ++#define IOC_P2P_CONNECT_DISCONNECT (SIOCIWFIRSTPRIV+8) ++#define IOC_P2P_PASSWORD_READY (SIOCIWFIRSTPRIV+10) ++/* #define IOC_P2P_SET_PWR_MGMT_PARAM (SIOCIWFIRSTPRIV+12) */ ++#define IOC_P2P_SET_INT (SIOCIWFIRSTPRIV+12) ++#define IOC_P2P_GET_STRUCT (SIOCIWFIRSTPRIV+13) ++#define IOC_P2P_SET_STRUCT (SIOCIWFIRSTPRIV+14) ++#define IOC_P2P_GET_REQ_DEVICE_INFO (SIOCIWFIRSTPRIV+15) ++ ++#define PRIV_CMD_INT_P2P_SET 0 ++ ++/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */ ++#define P2P_PROVISIONING_SUCCESS 0 ++#define P2P_PROVISIONING_FAIL 1 ++ ++/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */ ++#define P2P_STOP_DISCOVERY 0 ++#define P2P_START_DISCOVERY 1 ++ ++/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */ ++#define P2P_CONNECT 0 ++#define P2P_DISCONNECT 1 ++ ++/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */ ++#define P2P_SCAN_FULL_AND_FIND 0 ++#define P2P_SCAN_FULL 1 ++#define P2P_SCAN_SEARCH_AND_LISTEN 2 ++#define P2P_LISTEN 3 ++ ++/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */ ++#define P2P_SEND_SD_RESPONSE 0 ++#define P2P_GET_SD_REQUEST 1 ++#define P2P_SEND_SD_REQUEST 2 ++#define P2P_GET_SD_RESPONSE 3 ++#define P2P_TERMINATE_SD_PHASE 4 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/*----------------------------------------------------------------------------*/ ++/* Wireless Extension: Private I/O Control */ ++/*----------------------------------------------------------------------------*/ ++typedef struct iw_p2p_cfg_device_type { ++ void __user *ssid; ++ UINT_8 ssid_len; ++ UINT_8 pri_device_type[8]; ++ UINT_8 snd_device_type[8]; ++ void __user *device_name; ++ UINT_8 device_name_len; ++ UINT_8 intend; ++ UINT_8 persistence; ++ UINT_8 sec_mode; ++ UINT_8 ch; ++ UINT_8 ch_width; /* 0: 20 Mhz 1:20/40 Mhz auto */ ++ UINT_8 max_scb; ++} IW_P2P_CFG_DEVICE_TYPE, *P_IW_P2P_CFG_DEVICE_TYPE; ++ ++typedef struct iw_p2p_hostapd_param { ++ UINT_8 cmd; ++ UINT_8 rsv[3]; ++ UINT_8 sta_addr[6]; ++ void __user *data; ++ UINT_16 len; ++} IW_P2P_HOSTAPD_PARAM, *P_IW_P2P_HOSTAPD_PARAM; ++ ++typedef struct iw_p2p_req_device_type { ++ UINT_8 scan_type; /* 0: Full scan + Find ++ * 1: Full scan ++ * 2: Scan (Search +Listen) ++ * 3: Listen ++ * other : reserved ++ */ ++ UINT_8 pri_device_type[8]; ++ void __user *probe_req_ie; ++ UINT_16 probe_req_len; ++ void __user *probe_rsp_ie; ++ UINT_16 probe_rsp_len; ++} IW_P2P_REQ_DEVICE_TYPE, *P_IW_P2P_REQ_DEVICE_TYPE; ++ ++typedef struct iw_p2p_connect_device { ++ UINT_8 sta_addr[6]; ++ UINT_8 p2pRole; /* 0: P2P Device, 1:GC, 2: GO */ ++ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ ++ UINT_8 authPeer; /* 1: auth peer invitation request */ ++ UINT_8 intend_config_method; /* Request Peer Device used config method */ ++} IW_P2P_CONNECT_DEVICE, *P_IW_P2P_CONNECT_DEVICE; ++ ++typedef struct iw_p2p_password_ready { ++ UINT_8 active_config_method; ++ void __user *probe_req_ie; ++ UINT_16 probe_req_len; ++ void __user *probe_rsp_ie; ++ UINT_16 probe_rsp_len; ++} IW_P2P_PASSWORD_READY, *P_IW_P2P_PASSWORD_READY; ++ ++typedef struct iw_p2p_device_req { ++ UINT_8 name[33]; ++ UINT_32 name_len; ++ UINT_8 device_addr[6]; ++ UINT_8 device_type; ++ INT_32 config_method; ++ INT_32 active_config_method; ++} IW_P2P_DEVICE_REQ, *P_IW_P2P_DEVICE_REQ; ++ ++typedef struct iw_p2p_transport_struct { ++ UINT_32 u4CmdId; ++ UINT_32 inBufferLength; ++ UINT_32 outBufferLength; ++ UINT_8 aucBuffer[16]; ++} IW_P2P_TRANSPORT_STRUCT, *P_IW_P2P_TRANSPORT_STRUCT; ++ ++/* For Invitation */ ++typedef struct iw_p2p_ioctl_invitation_struct { ++ UINT_8 aucDeviceID[6]; ++ UINT_8 aucGroupID[6]; /* BSSID */ ++ UINT_8 aucSsid[32]; ++ UINT_32 u4SsidLen; ++ UINT_8 ucReinvoke; ++} IW_P2P_IOCTL_INVITATION_STRUCT, *P_IW_P2P_IOCTL_INVITATION_STRUCT; ++ ++typedef struct iw_p2p_ioctl_abort_invitation { ++ UINT_8 dev_addr[6]; ++} IW_P2P_IOCTL_ABORT_INVITATION, *P_IW_P2P_IOCTL_ABORT_INVITATION; ++ ++typedef struct iw_p2p_ioctl_invitation_indicate { ++ UINT_8 dev_addr[6]; ++ UINT_8 group_bssid[6]; ++ INT_32 config_method; /* peer device supported config method */ ++ UINT_8 dev_name[32]; /* for reinvoke */ ++ UINT_32 name_len; ++ UINT_8 operating_channel; /* for re-invoke, target operating channel */ ++ UINT_8 invitation_type; /* invitation or re-invoke */ ++} IW_P2P_IOCTL_INVITATION_INDICATE, *P_IW_P2P_IOCTL_INVITATION_INDICATE; ++ ++typedef struct iw_p2p_ioctl_invitation_status { ++ UINT_32 status_code; ++} IW_P2P_IOCTL_INVITATION_STATUS, *P_IW_P2P_IOCTL_INVITATION_STATUS; ++ ++/* For Formation */ ++typedef struct iw_p2p_ioctl_start_formation { ++ UINT_8 dev_addr[6]; /* bssid */ ++ UINT_8 role; /* 0: P2P Device, 1:GC, 2: GO */ ++ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ ++ UINT_8 auth; /* 1: auth peer invitation request */ ++ UINT_8 config_method; /* Request Peer Device used config method */ ++} IW_P2P_IOCTL_START_FORMATION, *P_IW_P2P_IOCTL_START_FORMATION; ++ ++/* SET_STRUCT / GET_STRUCT */ ++typedef enum _ENUM_P2P_CMD_ID_T { ++ P2P_CMD_ID_SEND_SD_RESPONSE = 0, /* 0x00 (Set) */ ++ P2P_CMD_ID_GET_SD_REQUEST, /* 0x01 (Get) */ ++ P2P_CMD_ID_SEND_SD_REQUEST, /* 0x02 (Set) */ ++ P2P_CMD_ID_GET_SD_RESPONSE, /* 0x03 (Get) */ ++ P2P_CMD_ID_TERMINATE_SD_PHASE, /* 0x04 (Set) */ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ P2P_CMD_ID_SEC_CHECK, /* 0x05(Set) */ ++#endif ++ P2P_CMD_ID_INVITATION, /* 0x06 (Set) */ ++ P2P_CMD_ID_INVITATION_INDICATE, /* 0x07 (Get) */ ++ P2P_CMD_ID_INVITATION_STATUS, /* 0x08 (Get) */ ++ P2P_CMD_ID_INVITATION_ABORT, /* 0x09 (Set) */ ++ P2P_CMD_ID_START_FORMATION, /* 0x0A (Set) */ ++ P2P_CMD_ID_P2P_VERSION, /* 0x0B (Set/Get) */ ++ P2P_CMD_ID_GET_CH_LIST = 12, /* 0x0C (Get) */ ++ P2P_CMD_ID_GET_OP_CH = 14 /* 0x0E (Get) */ ++} ENUM_P2P_CMD_ID_T, *P_ENUM_P2P_CMD_ID_T; ++ ++/* Service Discovery */ ++typedef struct iw_p2p_cmd_send_sd_response { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucSeqNum; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_SEND_SD_RESPONSE, *P_IW_P2P_CMD_SEND_SD_RESPONSE; ++ ++typedef struct iw_p2p_cmd_get_sd_request { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_GET_SD_REQUEST, *P_IW_P2P_CMD_GET_SD_REQUEST; ++ ++typedef struct iw_p2p_cmd_send_service_discovery_request { ++ PARAM_MAC_ADDRESS rReceiverAddr; ++ UINT_8 fgNeedTxDoneIndication; ++ UINT_8 ucSeqNum; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_SEND_SD_REQUEST, *P_IW_P2P_CMD_SEND_SD_REQUEST; ++ ++typedef struct iw_p2p_cmd_get_sd_response { ++ PARAM_MAC_ADDRESS rTransmitterAddr; ++ UINT_16 u2PacketLength; ++ UINT_8 aucPacketContent[0]; /*native 802.11 */ ++} IW_P2P_CMD_GET_SD_RESPONSE, *P_IW_P2P_CMD_GET_SD_RESPONSE; ++ ++typedef struct iw_p2p_cmd_terminate_sd_phase { ++ PARAM_MAC_ADDRESS rPeerAddr; ++} IW_P2P_CMD_TERMINATE_SD_PHASE, *P_IW_P2P_CMD_TERMINATE_SD_PHASE; ++ ++typedef struct iw_p2p_version { ++ UINT_32 u4Version; ++} IW_P2P_VERSION, *P_IW_P2P_VERSION; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++extern struct ieee80211_supported_band mtk_band_2ghz; ++extern struct ieee80211_supported_band mtk_band_5ghz; ++extern UINT_32 mtk_cipher_suites[5]; ++#endif ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++int mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy, ++ struct net_device *ndev, ++ enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); ++ ++int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); ++ ++int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, ++ struct net_device *ndev, ++ u8 key_index, ++ bool pairwise, ++ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) ++); ++ ++int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, ++ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); ++ ++int ++mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, ++ struct net_device *netdev, u8 key_index, bool unicast, bool multicast); ++ ++int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *mac, struct station_info *sinfo); ++ ++int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); ++ ++int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme); ++ ++int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); ++ ++int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); ++ ++int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev); ++ ++int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); ++ ++int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); ++ ++int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct ieee80211_channel *chan, unsigned int duration, u64 *cookie); ++ ++int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); ++ ++int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); ++ ++int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, ++ struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm); ++ ++int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); ++ ++int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req); ++ ++int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req); ++ ++int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings); ++ ++int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info); ++ ++int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct cfg80211_mgmt_tx_params *params, ++ u64 *cookie); ++ ++int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev); ++ ++int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params); ++//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac); ++ ++int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef); ++ ++void mtk_p2p_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); ++ ++int ++mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, ++ IN struct net_device *dev, ++ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask); ++ ++#ifdef CONFIG_NL80211_TESTMODE ++int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); ++int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++ ++#if CFG_SUPPORT_WFD ++int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#endif ++ ++int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); ++#else ++#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" ++#endif ++ ++#endif ++ ++/* I/O control handlers */ ++ ++int ++mtk_p2p_wext_get_priv(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_reconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_auth(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_key(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_powermode(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_powermode(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++/* Private Wireless I/O Controls takes use of iw_handler */ ++int ++mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_discovery_results(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_password_ready(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_invitation_status(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_network_address(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_int(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */ ++int ++mtk_p2p_wext_set_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_struct(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */ ++int ++mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, ++ IN struct iw_request_info *info, ++ IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++int ++mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++#endif ++ ++int ++mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++int ++mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++void mtk_p2p_wext_set_Multicastlist(IN P_GLUE_INFO_T prGlueInfo); ++ ++#if CFG_SUPPORT_P2P_RSSI_QUERY ++int ++mtk_p2p_wext_get_rssi(IN struct net_device *prDev, ++ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); ++ ++struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev); ++ ++#endif ++ ++int ++mtk_p2p_wext_set_txpow(IN struct net_device *prDev, ++ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_P2P_IOCTL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h +new file mode 100644 +index 000000000000..bf9d8871ef48 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h +@@ -0,0 +1,243 @@ ++/* ++** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_kal.h#2 ++*/ ++ ++/*! \file gl_p2p_kal.h ++ \brief Declaration of KAL functions for Wi-Fi Direct support ++ - kal*() which is provided by GLUE Layer. ++ ++ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++/* ++** Log: gl_p2p_kal.h ++** ++** 08 30 2012 chinglan.wang ++** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only ++** . ++ * ++ * 07 17 2012 yuche.tsai ++ * NULL ++ * Compile no error before trial run. ++ * ++ * 10 18 2011 yuche.tsai ++ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. ++ * New 2.1 branch ++ ++ * ++ * 08 15 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Add group BSSID in invitation request indication. ++ * The BSSID is used for APP to decide the configure method. ++ * ++ * 08 09 2011 yuche.tsai ++ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. ++ * Invitation Feature add on. ++ * ++ * 03 19 2011 terry.wu ++ * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver ++ * create V2.0 p2p driver release based on label "MT6620_WIFI_P2P_DRIVER_V2_0_2100_0319_2011" from main trunk. ++ * ++ * 03 07 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * rename the define to anti_pviracy. ++ * ++ * 03 05 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * add the code to get the check rsponse and indicate to app. ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add Security check related code. ++ * ++ * 12 22 2010 cp.wu ++ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service ++ * Discovery ++ * 1. header file restructure for more clear module isolation ++ * 2. add function interface definition for implementing Service Discovery callbacks ++ * ++*/ ++ ++#ifndef _GL_P2P_KAL_H ++#define _GL_P2P_KAL_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "config.h" ++#include "gl_typedef.h" ++#include "gl_os.h" ++#include "wlan_lib.h" ++#include "wlan_oid.h" ++#include "wlan_p2p.h" ++#include "gl_kal.h" ++#include "gl_wext_priv.h" ++#include "nic/p2p.h" ++ ++#if DBG ++extern int allocatedMemSize; ++#endif ++ ++extern BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); ++ ++#if CFG_SUPPORT_WPS ++extern BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type); ++struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo); ++ ++/* Service Discovery */ ++VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); ++ ++void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); ++ ++VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus); ++ ++/*----------------------------------------------------------------------------*/ ++/* Wi-Fi Direct handling */ ++/*----------------------------------------------------------------------------*/ ++ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole); ++ ++VOID ++kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); ++ ++UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole); ++ ++VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher); ++ ++BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode); ++ ++UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo); ++ ++UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType); ++ ++VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer); ++ ++VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength); ++ ++BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo); ++ ++VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, ++ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ ++ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod); ++ ++VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus); ++ ++VOID ++kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, ++ IN PUINT_8 pucSsid, ++ IN UINT_8 ucSsidLen, ++ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid); ++ ++struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo); ++ ++VOID ++kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, ++ IN ENUM_BAND_T eSpecificBand, ++ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); ++ ++#if CFG_SUPPORT_ANTI_PIRACY ++VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID ++kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8SeqNum, ++ IN UINT_32 u4ChannelNum, ++ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration); ++ ++VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort); ++ ++VOID ++kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, ++ IN PUINT_8 pucFrameBuf, ++ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength); ++ ++VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); ++ ++VOID ++kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); ++ ++VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); ++ ++VOID ++kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, ++ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, ++ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, ++ IN WLAN_STATUS eStatus); ++ ++VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew); ++ ++INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock); ++ ++BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid); ++ ++VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient); ++ ++BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient); ++ ++#endif /* _GL_P2P_KAL_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h +new file mode 100644 +index 000000000000..e5026e7e6eec +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h +@@ -0,0 +1,242 @@ ++/* ++** Id: ++//Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/os/linux/include/gl_p2p_os.h#28 ++*/ ++ ++/*! \file gl_p2p_os.h ++ \brief List the external reference to OS for p2p GLUE Layer. ++ ++ In this file we define the data structure - GLUE_INFO_T to store those objects ++ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the ++ external reference (header file, extern func() ..) to OS for GLUE Layer should ++ also list down here. ++*/ ++ ++#ifndef _GL_P2P_OS_H ++#define _GL_P2P_OS_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++#include ++#endif ++ ++#include "wlan_oid.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++struct _GL_P2P_INFO_T { ++ ++ /* Device handle */ ++ struct net_device *prDevHandler; ++ ++#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 ++ /* cfg80211 */ ++ struct wireless_dev *prWdev; ++ ++ struct cfg80211_scan_request *prScanRequest; ++ ++ UINT_64 u8Cookie; ++ ++ /* Generation for station list update. */ ++ INT_32 i4Generation; ++ ++ UINT_32 u4OsMgmtFrameFilter; ++ ++#endif ++ ++ /* Device statistics */ ++ struct net_device_stats rNetDevStats; ++ ++ /* glue layer variables */ ++ UINT_32 u4FreqInKHz; /* frequency */ ++ UINT_8 ucRole; /* 0: P2P Device, 1: Group Client, 2: Group Owner */ ++ UINT_8 ucIntent; /* range: 0-15 */ ++ UINT_8 ucScanMode; /* 0: Search & Listen, 1: Scan without probe response */ ++ ++ ENUM_PARAM_MEDIA_STATE_T eState; ++ UINT_32 u4PacketFilter; ++ PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR]; ++ ++ /* connection-requested peer information */ ++ UINT_8 aucConnReqDevName[32]; ++ INT_32 u4ConnReqNameLength; ++ PARAM_MAC_ADDRESS rConnReqPeerAddr; ++ PARAM_MAC_ADDRESS rConnReqGroupAddr; /* For invitation group. */ ++ UINT_8 ucConnReqDevType; ++ INT_32 i4ConnReqConfigMethod; ++ INT_32 i4ConnReqActiveConfigMethod; ++ ++ UINT_32 u4CipherPairwise; ++ UINT_8 ucWSCRunning; ++ ++ UINT_8 aucWSCIE[3][400]; /* 0 for beacon, 1 for probe req, 2 for probe response */ ++ UINT_16 u2WSCIELen[3]; ++ ++#if CFG_SUPPORT_WFD ++ UINT_8 aucVenderIE[1024]; /* Save the other IE for prove resp */ ++ UINT_16 u2VenderIELen; ++#endif ++ ++ UINT_8 ucOperatingChnl; ++ UINT_8 ucInvitationType; ++ ++ UINT_32 u4InvStatus; ++ ++ /* For SET_STRUCT/GET_STRUCT */ ++ UINT_8 aucOidBuf[4096]; ++ ++#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ ++ UINT_8 aucSecCheck[256]; ++ UINT_8 aucSecCheckRsp[256]; ++#endif ++ ++ /* Hotspot Client Management */ ++ PARAM_MAC_ADDRESS aucblackMACList[8]; ++ UINT_8 ucMaxClients; ++ ++#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION ++ UINT_32 u4PsLevel; ++#endif ++}; ++ ++#ifdef CONFIG_NL80211_TESTMODE ++typedef struct _NL80211_DRIVER_TEST_PRE_PARAMS { ++ UINT_16 idx_mode; ++ UINT_16 idx; ++ UINT_32 value; ++} NL80211_DRIVER_TEST_PRE_PARAMS, *P_NL80211_DRIVER_TEST_PRE_PARAMS; ++ ++typedef struct _NL80211_DRIVER_TEST_PARAMS { ++ UINT_32 index; ++ UINT_32 buflen; ++} NL80211_DRIVER_TEST_PARAMS, *P_NL80211_DRIVER_TEST_PARAMS; ++ ++/* P2P Sigma*/ ++typedef struct _NL80211_DRIVER_P2P_SIGMA_PARAMS { ++ NL80211_DRIVER_TEST_PARAMS hdr; ++ UINT_32 idx; ++ UINT_32 value; ++} NL80211_DRIVER_P2P_SIGMA_PARAMS, *P_NL80211_DRIVER_P2P_SIGMA_PARAMS; ++ ++/* Hotspot Client Management */ ++typedef struct _NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS { ++ NL80211_DRIVER_TEST_PARAMS hdr; ++ UINT_8 ucblocked; ++ UINT_8 aucBssid[MAC_ADDR_LEN]; ++} NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS, *P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS; ++ ++#if CFG_SUPPORT_WFD ++typedef struct _NL80211_DRIVER_WFD_PARAMS { ++ NL80211_DRIVER_TEST_PARAMS hdr; ++ UINT_32 WfdCmdType; ++ UINT_8 WfdEnable; ++ UINT_8 WfdCoupleSinkStatus; ++ UINT_8 WfdSessionAvailable; ++ UINT_8 WfdSigmaMode; ++ UINT_16 WfdDevInfo; ++ UINT_16 WfdControlPort; ++ UINT_16 WfdMaximumTp; ++ UINT_16 WfdExtendCap; ++ UINT_8 WfdCoupleSinkAddress[MAC_ADDR_LEN]; ++ UINT_8 WfdAssociatedBssid[MAC_ADDR_LEN]; ++ UINT_8 WfdVideoIp[4]; ++ UINT_8 WfdAudioIp[4]; ++ UINT_16 WfdVideoPort; ++ UINT_16 WfdAudioPort; ++ UINT_32 WfdFlag; ++ UINT_32 WfdPolicy; ++ UINT_32 WfdState; ++ UINT_8 WfdSessionInformationIE[24 * 8]; /* Include Subelement ID, length */ ++ UINT_16 WfdSessionInformationIELen; ++ UINT_8 aucReserved1[2]; ++ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; ++ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; ++ UINT_32 WfdAdvanceFlag; ++ /* Group 1 64 bytes */ ++ UINT_8 aucWfdLocalIp[4]; ++ UINT_16 WfdLifetimeAc2; /* Unit is 2 TU */ ++ UINT_16 WfdLifetimeAc3; /* Unit is 2 TU */ ++ UINT_16 WfdCounterThreshold; /* Unit is ms */ ++ UINT_8 aucReserved2[54]; ++ /* Group 3 64 bytes */ ++ UINT_8 aucReserved3[64]; ++ /* Group 3 64 bytes */ ++ UINT_8 aucReserved4[64]; ++} NL80211_DRIVER_WFD_PARAMS, *P_NL80211_DRIVER_WFD_PARAMS; ++#endif ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo); ++ ++VOID p2pSetMode(IN BOOLEAN fgIsAPMOde); ++ ++BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode); ++ ++VOID p2pEalySuspendReg(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsEnable); ++ ++BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); ++ ++BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); ++ ++BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo); ++ ++BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo); ++ ++VOID glP2pDestroyWirelessDevice(VOID); ++ ++VOID p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo); ++ ++#endif +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h +new file mode 100644 +index 000000000000..f24ceee9e921 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h +@@ -0,0 +1,133 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_rst.h#1 ++*/ ++ ++/*! \file gl_rst.h ++ \brief Declaration of functions and finite state machine for ++ MT6620 Whole-Chip Reset Mechanism ++*/ ++ ++#ifndef _GL_RST_H ++#define _GL_RST_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include "gl_typedef.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++#if 1 ++typedef INT_32(*wmt_wlan_probe_cb) (VOID); ++typedef INT_32(*wmt_wlan_remove_cb) (VOID); ++typedef INT_32(*wmt_wlan_bus_cnt_get_cb) (VOID); ++typedef INT_32(*wmt_wlan_bus_cnt_clr_cb) (VOID); ++ ++typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { ++ wmt_wlan_probe_cb wlan_probe_cb; ++ wmt_wlan_remove_cb wlan_remove_cb; ++ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; ++ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; ++} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; ++ ++extern INT_32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); ++extern INT_32 mtk_wcn_wmt_wlan_unreg(VOID); ++#endif ++ ++typedef enum _ENUM_RESET_STATUS_T { ++ RESET_FAIL, ++ RESET_SUCCESS ++} ENUM_RESET_STATUS_T; ++ ++typedef struct _RESET_STRUCT_T { ++ ENUM_RESET_STATUS_T rst_data; ++ struct work_struct rst_work; ++} RESET_STRUCT_T; ++ ++typedef enum _ENUM_WMTRSTMSG_TYPE_T { ++ WMTRSTMSG_RESET_START = 0x0, ++ WMTRSTMSG_RESET_END = 0x1, ++ WMTRSTMSG_RESET_END_FAIL = 0x2, ++ WMTRSTMSG_RESET_MAX, ++ WMTRSTMSG_RESET_INVALID = 0xff ++} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; ++ ++typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ ++ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ ++ ENUM_WMTMSG_TYPE_T, /* Message type */ ++ void *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client ++ can't touch this buffer after this function return. */ ++ unsigned int /* Buffer size in unit of byte */ ++); ++ ++/******************************************************************************* ++* E X T E R N A L F U N C T I O N S ++******************************************************************************** ++*/ ++#define glDoChipReset() \ ++ do { \ ++ if (!kalStrnCmp(current->comm, "mtk_wmtd", 8)) { \ ++ g_IsNeedDoChipReset = 1; \ ++ DBGLOG(INIT, ERROR, "forbid core dump in mtk_wmtd %s line %d\n", __func__, __LINE__); \ ++ break; \ ++ } \ ++ DBGLOG(INIT, ERROR, "Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ ++ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 0x40); \ ++ } while (0) ++ ++#if CFG_CHIP_RESET_SUPPORT ++extern int mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); ++extern int mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); ++extern int wifi_reset_start(void); ++extern int wifi_reset_end(ENUM_RESET_STATUS_T); ++#endif ++extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); ++extern BOOLEAN mtk_wcn_set_connsys_power_off_flag(BOOLEAN value); ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern UINT_32 g_IsNeedDoChipReset; ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++VOID glResetInit(VOID); ++ ++VOID glResetUninit(VOID); ++ ++VOID glSendResetRequest(VOID); ++ ++BOOLEAN kalIsResetting(VOID); ++ ++#endif /* _GL_RST_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h +new file mode 100644 +index 000000000000..3cc57780f201 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h +@@ -0,0 +1,21 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_sec.h#1 ++*/ ++ ++/*! \file p2p_fsm.h ++ \brief Declaration of functions and finite state machine for P2P Module. ++ ++ Declaration of functions and finite state machine for P2P Module. ++*/ ++ ++#ifndef _GL_SEC_H ++#define _GL_SEC_H ++ ++extern void handle_sec_msg_1(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_2(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_3(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_4(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_5(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++extern void handle_sec_msg_final(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); ++ ++#endif /* _GL_SEC_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h +new file mode 100644 +index 000000000000..e9aa3e849eb2 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h +@@ -0,0 +1,298 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_typedef.h#1 ++*/ ++ ++/*! \file gl_typedef.h ++ \brief Definition of basic data type(os dependent). ++ ++ In this file we define the basic data type. ++*/ ++ ++/* ++** Log: gl_typedef.h ++ * ++ * 06 22 2012 cp.wu ++ * [WCXRP00001257] [MT6620][MT5931][MT6628][Driver][Linux] Modify KAL_HZ to align ms accuracy ++ * modify KAL_HZ to (1000) for correct definition. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * portability improvement ++ * ++ * 02 15 2011 jeffrey.chang ++ * NULL ++ * to support early suspend in android ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\6 2009-08-18 22:57:14 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\5 2008-09-22 23:19:30 GMT mtk01461 ++** Update comment for code review ++** \main\maintrunk.MT5921\4 2008-09-05 17:25:16 GMT mtk01461 ++** Update Driver for Code Review ++** \main\maintrunk.MT5921\3 2007-11-09 11:00:50 GMT mtk01425 ++** 1. Use macro to unify network-to-host and host-to-network related functions ++** Revision 1.3 2007/06/27 02:18:51 MTK01461 ++** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API ++** ++** Revision 1.2 2007/06/25 06:16:24 MTK01461 ++** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API ++** ++*/ ++ ++#ifndef _GL_TYPEDEF_H ++#define _GL_TYPEDEF_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* Define HZ of timer tick for function kalGetTimeTick() */ ++#define KAL_HZ (1000) ++ ++/* Miscellaneous Equates */ ++#ifndef FALSE ++#define FALSE ((BOOLEAN) 0) ++#define TRUE ((BOOLEAN) 1) ++#endif /* FALSE */ ++ ++#ifndef NULL ++#if defined(__cplusplus) ++#define NULL 0 ++#else ++#define NULL ((void *) 0) ++#endif ++#endif ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* Type definition for void */ ++/*mach/mt_typedefs.h define _TYPEDEFS_H, to avoid compile error*/ ++#ifndef _TYPEDEFS_H ++typedef void VOID; ++#endif ++typedef void *PVOID, **PPVOID; ++ ++/* Type definition for Boolean */ ++typedef unsigned char BOOLEAN, *PBOOLEAN; ++ ++/* Type definition for signed integers */ ++typedef signed char CHAR, *PCHAR, **PPCHAR; ++typedef signed char INT_8, *PINT_8, **PPINT_8; ++typedef signed short INT_16, *PINT_16, **PPINT_16; ++typedef signed int INT_32, *PINT_32, **PPINT_32; ++typedef long LONG, *PLONG, **PPLONG; ++typedef signed long long INT_64, *PINT_64, **PPINT_64; ++ ++/* Type definition for unsigned integers */ ++typedef unsigned char UCHAR, *PUCHAR, **PPUCHAR; ++typedef unsigned char UINT_8, *PUINT_8, **PPUINT_8, *P_UINT_8; ++typedef unsigned short UINT_16, *PUINT_16, **PPUINT_16; ++typedef unsigned int UINT32, *PUINT32; ++typedef unsigned int UINT_32, *PUINT_32, **PPUINT_32; ++typedef unsigned long ULONG, *PULONG, **PPULONG; ++typedef unsigned long long UINT_64, *PUINT_64, **PPUINT_64; ++ ++typedef unsigned int OS_SYSTIME, *POS_SYSTIME, **PPOS_SYSTIME; ++ ++#ifndef _TYPEDEFS_H ++typedef signed char INT8, *PINT8; ++typedef signed short INT16, *PINT16; ++typedef signed int INT32, *PINT32; ++typedef unsigned char UINT8, *PUINT8; ++typedef unsigned short UINT16, *PUINT16; ++typedef unsigned int UINT32, *PUINT32; ++#endif ++ ++/* Type definition of large integer (64bits) union to be comptaible with ++ * Windows definition, so we won't apply our own coding style to these data types. ++ * NOTE: LARGE_INTEGER must NOT be floating variable. ++ * : Check for big-endian compatibility. ++ */ ++typedef union _LARGE_INTEGER { ++ struct { ++ UINT_32 LowPart; ++ INT_32 HighPart; ++ } u; ++ INT_64 QuadPart; ++} LARGE_INTEGER, *PLARGE_INTEGER; ++ ++typedef union _ULARGE_INTEGER { ++ struct { ++ UINT_32 LowPart; ++ UINT_32 HighPart; ++ } u; ++ UINT_64 QuadPart; ++} ULARGE_INTEGER, *PULARGE_INTEGER; ++ ++typedef INT_32(*probe_card) (PVOID pvData); ++typedef VOID(*remove_card) (VOID); ++ ++/* duplicated from wmt_exp.h for better driver isolation */ ++typedef enum _ENUM_WMTDRV_TYPE_T { ++ WMTDRV_TYPE_BT = 0, ++ WMTDRV_TYPE_FM = 1, ++ WMTDRV_TYPE_GPS = 2, ++ WMTDRV_TYPE_WIFI = 3, ++ WMTDRV_TYPE_WMT = 4, ++ WMTDRV_TYPE_STP = 5, ++ WMTDRV_TYPE_SDIO1 = 6, ++ WMTDRV_TYPE_SDIO2 = 7, ++ WMTDRV_TYPE_LPBK = 8, ++ WMTDRV_TYPE_MAX ++} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; ++ ++typedef enum _ENUM_WMTMSG_TYPE_T { ++ WMTMSG_TYPE_POWER_ON = 0, ++ WMTMSG_TYPE_POWER_OFF = 1, ++ WMTMSG_TYPE_RESET = 2, ++ WMTMSG_TYPE_STP_RDY = 3, ++ WMTMSG_TYPE_HW_FUNC_ON = 4, ++ WMTMSG_TYPE_MAX ++} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; ++ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++#define IN /* volatile */ ++#define OUT /* volatile */ ++ ++#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) ++#define __KAL_ATTRIB_ALIGN_4__ __aligned(4) ++ ++#ifndef BIT ++#define BIT(n) ((UINT_32) 1U << (n)) ++#endif /* BIT */ ++ ++#ifndef BITS ++/* bits range: for example BITS(16,23) = 0xFF0000 ++ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 ++ * ==> (BIT(n+1)-1) = 0x00FFFFFF ++ */ ++#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) ++#endif /* BIT */ ++ ++/* This macro returns the byte offset of a named field in a known structure ++ type. ++ _type - structure name, ++ _field - field name of the structure */ ++#ifndef OFFSET_OF ++#define OFFSET_OF(_type, _field) ((ULONG)&(((_type *)0)->_field)) ++#endif /* OFFSET_OF */ ++ ++/* This macro returns the base address of an instance of a structure ++ * given the type of the structure and the address of a field within the ++ * containing structure. ++ * _addrOfField - address of current field of the structure, ++ * _type - structure name, ++ * _field - field name of the structure ++ */ ++#ifndef ENTRY_OF ++#define ENTRY_OF(_addrOfField, _type, _field) \ ++ ((_type *)((PINT_8)(_addrOfField) - (PINT_8)OFFSET_OF(_type, _field))) ++#endif /* ENTRY_OF */ ++ ++/* This macro align the input value to the DW boundary. ++ * _value - value need to check ++ */ ++#ifndef ALIGN_4 ++#define ALIGN_4(_value) (((_value) + 3) & ~3u) ++#endif /* ALIGN_4 */ ++ ++/* This macro check the DW alignment of the input value. ++ * _value - value of address need to check ++ */ ++#ifndef IS_ALIGN_4 ++#define IS_ALIGN_4(_value) (((_value) & 0x3) ? FALSE : TRUE) ++#endif /* IS_ALIGN_4 */ ++ ++#ifndef IS_NOT_ALIGN_4 ++#define IS_NOT_ALIGN_4(_value) (((_value) & 0x3) ? TRUE : FALSE) ++#endif /* IS_NOT_ALIGN_4 */ ++ ++/* This macro evaluate the input length in unit of Double Word(4 Bytes). ++ * _value - value in unit of Byte, output will round up to DW boundary. ++ */ ++#ifndef BYTE_TO_DWORD ++#define BYTE_TO_DWORD(_value) ((_value + 3) >> 2) ++#endif /* BYTE_TO_DWORD */ ++ ++/* This macro evaluate the input length in unit of Byte. ++ * _value - value in unit of DW, output is in unit of Byte. ++ */ ++#ifndef DWORD_TO_BYTE ++#define DWORD_TO_BYTE(_value) ((_value) << 2) ++#endif /* DWORD_TO_BYTE */ ++ ++#if 1 /* Little-Endian */ ++#define CONST_NTOHS(_x) ntohs(_x) ++ ++#define CONST_HTONS(_x) htons(_x) ++ ++#define NTOHS(_x) ntohs(_x) ++ ++#define HTONS(_x) htons(_x) ++ ++#define NTOHL(_x) ntohl(_x) ++ ++#define HTONL(_x) htonl(_x) ++ ++#else /* Big-Endian */ ++ ++#define CONST_NTOHS(_x) ++ ++#define CONST_HTONS(_x) ++ ++#define NTOHS(_x) ++ ++#define HTONS(_x) ++ ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_TYPEDEF_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h +new file mode 100644 +index 000000000000..d8d5b0fb6740 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h +@@ -0,0 +1,619 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_vendor.h#1 ++*/ ++ ++/*! \file gl_vendor.h ++ \brief This file is for Portable Driver linux gl_vendor support. ++*/ ++ ++/* ++** Log: gl_vendor.h ++** ++** 10 14 2014 ++** add vendor declaration ++** ++ * ++*/ ++ ++#ifndef _GL_VENDOR_H ++#define _GL_VENDOR_H ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "gl_os.h" ++ ++#include "wlan_lib.h" ++#include "gl_wext.h" ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define GOOGLE_OUI 0x001A11 ++ ++typedef enum { ++ /* Don't use 0 as a valid subcommand */ ++ ANDROID_NL80211_SUBCMD_UNSPECIFIED, ++ ++ /* Define all vendor startup commands between 0x0 and 0x0FFF */ ++ ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001, ++ ANDROID_NL80211_SUBCMD_WIFI_RANGE_END = 0x0FFF, ++ ++ /* Define all GScan related commands between 0x1000 and 0x10FF */ ++ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, ++ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, ++ ++ /* Define all RTT related commands between 0x1100 and 0x11FF */ ++ ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, ++ ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, ++ ++ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, ++ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, ++ ++ /* Define all Logger related commands between 0x1400 and 0x14FF */ ++ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, ++ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, ++ ++ /* Define all wifi offload related commands between 0x1600 and 0x16FF */ ++ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, ++ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, ++ ++ /* This is reserved for future usage */ ++ ++} ANDROID_VENDOR_SUB_COMMAND; ++ ++typedef enum { ++ WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START, ++ ++ WIFI_SUBCMD_GET_FEATURE_SET, /* 0x0001 */ ++ WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x0002 */ ++ WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x0003 */ ++ WIFI_SUBCMD_NODFS_SET, /* 0x0004 */ ++ WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x0005 */ ++ /* Add more sub commands here */ ++ ++} WIFI_SUB_COMMAND; ++ ++typedef enum { ++ GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, ++ ++ GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */ ++ GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */ ++ GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */ ++ GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */ ++ GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */ ++ ++ GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */ ++ ++ GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */ ++ GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */ ++ /* Add more sub commands here */ ++ ++} GSCAN_SUB_COMMAND; ++ ++typedef enum { ++ RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, ++ RTT_SUBCMD_CANCEL_CONFIG, ++ RTT_SUBCMD_GETCAPABILITY, ++} RTT_SUB_COMMAND; ++ ++typedef enum { ++ LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, ++} LSTATS_SUB_COMMAND; ++ ++typedef enum { ++ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, ++ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, ++ GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, ++ GSCAN_EVENT_FULL_SCAN_RESULTS, ++ RTT_EVENT_COMPLETE, ++ GSCAN_EVENT_COMPLETE_SCAN, ++ GSCAN_EVENT_HOTLIST_RESULTS_LOST ++} WIFI_VENDOR_EVENT; ++ ++typedef enum { ++ WIFI_ATTRIBUTE_BAND, ++ WIFI_ATTRIBUTE_NUM_CHANNELS, ++ WIFI_ATTRIBUTE_CHANNEL_LIST, ++ ++ WIFI_ATTRIBUTE_NUM_FEATURE_SET, ++ WIFI_ATTRIBUTE_FEATURE_SET, ++ WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, ++ WIFI_ATTRIBUTE_NODFS_VALUE, ++ WIFI_ATTRIBUTE_COUNTRY_CODE ++ ++} WIFI_ATTRIBUTE; ++ ++typedef enum { ++ GSCAN_ATTRIBUTE_CAPABILITIES = 1, ++ ++ GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, ++ GSCAN_ATTRIBUTE_BASE_PERIOD, ++ GSCAN_ATTRIBUTE_BUCKETS_BAND, ++ GSCAN_ATTRIBUTE_BUCKET_ID, ++ GSCAN_ATTRIBUTE_BUCKET_PERIOD, ++ GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, ++ GSCAN_ATTRIBUTE_BUCKET_CHANNELS, ++ GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, ++ GSCAN_ATTRIBUTE_REPORT_THRESHOLD, ++ GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, ++ ++ GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, ++ GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ ++ GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ ++ GSCAN_ENABLE_FULL_SCAN_RESULTS, ++ GSCAN_ATTRIBUTE_REPORT_EVENTS, ++ ++ GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, ++ GSCAN_ATTRIBUTE_FLUSH_RESULTS, ++ GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ ++ GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ ++ GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ ++ GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ ++ ++ GSCAN_ATTRIBUTE_SSID = 40, ++ GSCAN_ATTRIBUTE_BSSID, ++ GSCAN_ATTRIBUTE_CHANNEL, ++ GSCAN_ATTRIBUTE_RSSI, ++ GSCAN_ATTRIBUTE_TIMESTAMP, ++ GSCAN_ATTRIBUTE_RTT, ++ GSCAN_ATTRIBUTE_RTTSD, ++ ++ GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, ++ GSCAN_ATTRIBUTE_RSSI_LOW, ++ GSCAN_ATTRIBUTE_RSSI_HIGH, ++ GSCAN_ATTRIBUTE_HOTLIST_ELEM, ++ GSCAN_ATTRIBUTE_HOTLIST_FLUSH, ++ ++ GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, ++ GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, ++ GSCAN_ATTRIBUTE_MIN_BREACHING, ++ GSCAN_ATTRIBUTE_NUM_AP, ++ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, ++ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH ++ ++} GSCAN_ATTRIBUTE; ++ ++typedef enum { ++ RTT_ATTRIBUTE_CAPABILITIES = 1, ++ ++ RTT_ATTRIBUTE_TARGET_CNT = 10, ++ RTT_ATTRIBUTE_TARGET_INFO, ++ RTT_ATTRIBUTE_TARGET_MAC, ++ RTT_ATTRIBUTE_TARGET_TYPE, ++ RTT_ATTRIBUTE_TARGET_PEER, ++ RTT_ATTRIBUTE_TARGET_CHAN, ++ RTT_ATTRIBUTE_TARGET_PERIOD, ++ RTT_ATTRIBUTE_TARGET_NUM_BURST, ++ RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, ++ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, ++ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, ++ RTT_ATTRIBUTE_TARGET_LCI, ++ RTT_ATTRIBUTE_TARGET_LCR, ++ RTT_ATTRIBUTE_TARGET_BURST_DURATION, ++ RTT_ATTRIBUTE_TARGET_PREAMBLE, ++ RTT_ATTRIBUTE_TARGET_BW, ++ RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, ++ RTT_ATTRIBUTE_RESULTS_PER_TARGET, ++ RTT_ATTRIBUTE_RESULT_CNT, ++ RTT_ATTRIBUTE_RESULT ++} RTT_ATTRIBUTE; ++ ++typedef enum { ++ LSTATS_ATTRIBUTE_STATS = 2, ++} LSTATS_ATTRIBUTE; ++ ++typedef enum { ++ WIFI_BAND_UNSPECIFIED, ++ WIFI_BAND_BG = 1, /* 2.4 GHz */ ++ WIFI_BAND_A = 2, /* 5 GHz without DFS */ ++ WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */ ++ WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ ++ WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ ++ WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ ++} WIFI_BAND; ++ ++typedef enum { ++ WIFI_SCAN_BUFFER_FULL, ++ WIFI_SCAN_COMPLETE, ++} WIFI_SCAN_EVENT; ++ ++#define GSCAN_MAX_REPORT_THRESHOLD 1024000 ++#define GSCAN_MAX_CHANNELS 8 ++#define GSCAN_MAX_BUCKETS 8 ++#define MAX_HOTLIST_APS 16 ++#define MAX_SIGNIFICANT_CHANGE_APS 16 ++#define PSCAN_MAX_SCAN_CACHE_SIZE 16 ++#define PSCAN_MAX_AP_CACHE_PER_SCAN 16 ++#define PSCAN_VERSION 1 ++ ++#define MAX_BUFFERED_GSCN_RESULTS 5 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef UINT_64 wifi_timestamp; /* In microseconds (us) */ ++typedef UINT_64 wifi_timespan; /* In nanoseconds (ns) */ ++ ++typedef UINT_8 mac_addr[6]; ++typedef UINT_32 wifi_channel; /* Indicates channel frequency in MHz */ ++typedef INT_32 wifi_rssi; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++typedef struct _PARAM_WIFI_GSCAN_GET_RESULT_PARAMS { ++ UINT_32 get_num; ++ UINT_8 flush; ++} PARAM_WIFI_GSCAN_GET_RESULT_PARAMS, *P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS; ++ ++typedef struct _PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS { ++ UINT_8 ucPscanAct; ++ UINT_8 aucReserved[3]; ++} PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS; ++ ++typedef struct _PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T { ++ UINT_32 max_scan_cache_size; /* total space allocated for scan (in bytes) */ ++ UINT_32 max_scan_buckets; /* maximum number of channel buckets */ ++ UINT_32 max_ap_cache_per_scan; /* maximum number of APs that can be stored per scan */ ++ UINT_32 max_rssi_sample_size; /* number of RSSI samples used for averaging RSSI */ ++ UINT_32 max_scan_reporting_threshold; /* max possible report_threshold as described */ ++ /* in wifi_scan_cmd_params */ ++ UINT_32 max_hotlist_aps; /* maximum number of entries for hotlist APs */ ++ UINT_32 max_significant_wifi_change_aps; /* maximum number of entries for */ ++ /* significant wifi change APs */ ++ UINT_32 max_bssid_history_entries; /* number of BSSID/RSSI entries that device can hold */ ++} PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T, *P_PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T; ++ ++typedef struct _PARAM_WIFI_GSCAN_CHANNEL_SPEC { ++ UINT_32 channel; /* frequency */ ++ UINT_32 dwellTimeMs; /* dwell time hint */ ++ UINT_32 passive; /* 0 => active, 1 => passive scan; ignored for DFS */ ++ /* Add channel class */ ++} PARAM_WIFI_GSCAN_CHANNEL_SPEC, *P_PARAM_WIFI_GSCAN_CHANNEL_SPEC; ++ ++typedef struct _PARAM_WIFI_GSCAN_BUCKET_SPEC { ++ UINT_32 bucket; /* bucket index, 0 based */ ++ WIFI_BAND band; /* when UNSPECIFIED, use channel list */ ++ UINT_32 period; /* desired period, in millisecond; if this is too */ ++ /* low, the firmware should choose to generate results as */ ++ /* fast as it can instead of failing the command */ ++ /* report_events semantics - ++ * 0 => report only when scan history is % full ++ * 1 => same as 0 + report a scan completion event after scanning this bucket ++ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL ++ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to ++ supplicant as well (optional) . */ ++ UINT_8 report_events; ++ ++ UINT_32 num_channels; ++ PARAM_WIFI_GSCAN_CHANNEL_SPEC channels[GSCAN_MAX_CHANNELS]; /* channels to scan; ++ these may include DFS channels */ ++} PARAM_WIFI_GSCAN_BUCKET_SPEC, *P_PARAM_WIFI_GSCAN_BUCKET_SPEC; ++ ++typedef struct _PARAM_WIFI_GSCAN_CMD_PARAMS { ++ UINT_32 base_period; /* base timer period in ms */ ++ UINT_32 max_ap_per_scan; /* number of APs to store in each scan in the */ ++ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ ++ UINT_32 report_threshold; /* in %, when scan buffer is this much full, wake up AP */ ++ UINT_32 num_scans; ++ UINT_32 num_buckets; ++ PARAM_WIFI_GSCAN_BUCKET_SPEC buckets[GSCAN_MAX_BUCKETS]; ++} PARAM_WIFI_GSCAN_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_CMD_PARAMS; ++ ++typedef struct _PARAM_WIFI_GSCAN_RESULT { ++ wifi_timestamp ts; /* time since boot (in microsecond) when the result was */ ++ /* retrieved */ ++ UINT_8 ssid[32 + 1]; /* null terminated */ ++ mac_addr bssid; ++ wifi_channel channel; /* channel frequency in MHz */ ++ wifi_rssi rssi; /* in db */ ++ wifi_timespan rtt; /* in nanoseconds */ ++ wifi_timespan rtt_sd; /* standard deviation in rtt */ ++ UINT_16 beacon_period; /* period advertised in the beacon */ ++ UINT_16 capability; /* capabilities advertised in the beacon */ ++ UINT_32 ie_length; /* size of the ie_data blob */ ++ UINT_8 ie_data[1]; /* blob of all the information elements found in the */ ++ /* beacon; this data should be a packed list of */ ++ /* wifi_information_element objects, one after the other. */ ++ /* other fields */ ++} PARAM_WIFI_GSCAN_RESULT, *P_PARAM_WIFI_GSCAN_RESULT; ++ ++/* Significant wifi change*/ ++/*typedef struct _PARAM_WIFI_CHANGE_RESULT{ ++ mac_addr bssid; // BSSID ++ wifi_channel channel; // channel frequency in MHz ++ UINT_32 num_rssi; // number of rssi samples ++ wifi_rssi rssi[8]; // RSSI history in db ++} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT;*/ ++ ++typedef struct _PARAM_WIFI_CHANGE_RESULT { ++ UINT_16 flags; ++ UINT_16 channel; ++ mac_addr bssid; /* BSSID */ ++ INT_8 rssi[8]; /* RSSI history in db */ ++} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT; ++ ++typedef struct _PARAM_AP_THRESHOLD { ++ mac_addr bssid; /* AP BSSID */ ++ wifi_rssi low; /* low threshold */ ++ wifi_rssi high; /* high threshold */ ++ wifi_channel channel; /* channel hint */ ++} PARAM_AP_THRESHOLD, *P_PARAM_AP_THRESHOLD; ++ ++typedef struct _PARAM_WIFI_BSSID_HOTLIST { ++ UINT_32 lost_ap_sample_size; ++ UINT_32 num_ap; /* number of hotlist APs */ ++ PARAM_AP_THRESHOLD ap[MAX_HOTLIST_APS]; /* hotlist APs */ ++} PARAM_WIFI_BSSID_HOTLIST, *P_PARAM_WIFI_BSSID_HOTLIST; ++ ++typedef struct _PARAM_WIFI_SIGNIFICANT_CHANGE { ++ UINT_16 rssi_sample_size; /* number of samples for averaging RSSI */ ++ UINT_16 lost_ap_sample_size; /* number of samples to confirm AP loss */ ++ UINT_16 min_breaching; /* number of APs breaching threshold */ ++ UINT_16 num_ap; /* max 64 */ ++ PARAM_AP_THRESHOLD ap[MAX_SIGNIFICANT_CHANGE_APS]; ++} PARAM_WIFI_SIGNIFICANT_CHANGE, *P_PARAM_WIFI_SIGNIFICANT_CHANGE; ++ ++/* RTT Capabilities */ ++typedef struct _PARAM_WIFI_RTT_CAPABILITIES { ++ UINT_8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */ ++ UINT_8 rtt_ftm_supported; /* if ftm rtt data collection is supported */ ++ UINT_8 lci_support; /* if initiator supports LCI request. Applies to 2-sided RTT */ ++ UINT_8 lcr_support; /* if initiator supports LCR request. Applies to 2-sided RTT */ ++ UINT_8 preamble_support; /* bit mask indicates what preamble is supported by initiator */ ++ UINT_8 bw_support; /* bit mask indicates what BW is supported by initiator */ ++} PARAM_WIFI_RTT_CAPABILITIES, *P_PARAM_WIFI_RTT_CAPABILITIES; ++ ++/* channel operating width */ ++typedef enum { ++ WIFI_CHAN_WIDTH_20 = 0, ++ WIFI_CHAN_WIDTH_40 = 1, ++ WIFI_CHAN_WIDTH_80 = 2, ++ WIFI_CHAN_WIDTH_160 = 3, ++ WIFI_CHAN_WIDTH_80P80 = 4, ++ WIFI_CHAN_WIDTH_5 = 5, ++ WIFI_CHAN_WIDTH_10 = 6, ++ WIFI_CHAN_WIDTH_INVALID = -1 ++} WIFI_CHANNEL_WIDTH; ++ ++/* channel information */ ++typedef struct { ++ WIFI_CHANNEL_WIDTH width; /* channel width (20, 40, 80, 80+80, 160) */ ++ UINT_32 center_freq; /* primary 20 MHz channel */ ++ UINT_32 center_freq0; /* center frequency (MHz) first segment */ ++ UINT_32 center_freq1; /* center frequency (MHz) second segment */ ++} WIFI_CHANNEL_INFO; ++ ++/* channel statistics */ ++typedef struct { ++ WIFI_CHANNEL_INFO channel; /* channel */ ++ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ ++ UINT_32 cca_busy_time; /* msecs the CCA register is busy (32 bits number accruing over time) */ ++} WIFI_CHANNEL_STAT; ++ ++/* radio statistics */ ++typedef struct { ++ UINT_32 radio; /* wifi radio (if multiple radio supported) */ ++ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ ++ UINT_32 tx_time; /* msecs the radio is transmitting (32 bits number accruing over time) */ ++ UINT_32 rx_time; /* msecs the radio is in active receive (32 bits number accruing over time) */ ++ UINT_32 on_time_scan; /* msecs the radio is awake due to all scan (32 bits number accruing over time) */ ++ UINT_32 on_time_nbd; /* msecs the radio is awake due to NAN (32 bits number accruing over time) */ ++ UINT_32 on_time_gscan; /* msecs the radio is awake due to G?scan (32 bits number accruing over time) */ ++ UINT_32 on_time_roam_scan; /* msecs the radio is awake due to roam?scan ++ (32 bits number accruing over time) */ ++ UINT_32 on_time_pno_scan; /* msecs the radio is awake due to PNO scan ++ (32 bits number accruing over time) */ ++ UINT_32 on_time_hs20; /* msecs the radio is awake due to HS2.0 scans and GAS exchange ++ 32 bits number accruing over time) */ ++ UINT_32 num_channels; /* number of channels */ ++ WIFI_CHANNEL_STAT channels[]; /* channel statistics */ ++} WIFI_RADIO_STAT; ++ ++/* wifi rate */ ++typedef struct { ++ UINT_32 preamble:3; /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ ++ UINT_32 nss:2; /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ ++ UINT_32 bw:3; /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ ++ UINT_32 rateMcsIdx:8; /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ ++ /* HT/VHT it would be mcs index */ ++ UINT_32 reserved:16; /* reserved */ ++ UINT_32 bitrate; /* units of 100 Kbps */ ++} WIFI_RATE; ++ ++/* per rate statistics */ ++typedef struct { ++ WIFI_RATE rate; /* rate information */ ++ UINT_32 tx_mpdu; /* number of successfully transmitted data pkts (ACK rcvd) */ ++ UINT_32 rx_mpdu; /* number of received data pkts */ ++ UINT_32 mpdu_lost; /* number of data packet losses (no ACK) */ ++ UINT_32 retries; /* total number of data pkt retries */ ++ UINT_32 retries_short; /* number of short data pkt retries */ ++ UINT_32 retries_long; /* number of long data pkt retries */ ++} WIFI_RATE_STAT; ++ ++/*wifi_interface_link_layer_info*/ ++typedef enum { ++ WIFI_DISCONNECTED = 0, ++ WIFI_AUTHENTICATING = 1, ++ WIFI_ASSOCIATING = 2, ++ WIFI_ASSOCIATED = 3, ++ WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ ++ WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ ++} WIFI_CONNECTION_STATE; ++ ++typedef enum { ++ WIFI_ROAMING_IDLE = 0, ++ WIFI_ROAMING_ACTIVE = 1, ++} WIFI_ROAM_STATE; ++ ++typedef enum { ++ WIFI_INTERFACE_STA = 0, ++ WIFI_INTERFACE_SOFTAP = 1, ++ WIFI_INTERFACE_IBSS = 2, ++ WIFI_INTERFACE_P2P_CLIENT = 3, ++ WIFI_INTERFACE_P2P_GO = 4, ++ WIFI_INTERFACE_NAN = 5, ++ WIFI_INTERFACE_MESH = 6, ++ WIFI_INTERFACE_UNKNOWN = -1 ++} WIFI_INTERFACE_MODE; ++ ++typedef struct { ++ WIFI_INTERFACE_MODE mode; /* interface mode */ ++ u8 mac_addr[6]; /* interface mac address (self) */ ++ WIFI_CONNECTION_STATE state; /* connection state (valid for STA, CLI only) */ ++ WIFI_ROAM_STATE roaming; /* roaming state */ ++ u32 capabilities; /* WIFI_CAPABILITY_XXX (self) */ ++ u8 ssid[33]; /* null terminated SSID */ ++ u8 bssid[6]; /* bssid */ ++ u8 ap_country_str[3]; /* country string advertised by AP */ ++ u8 country_str[3]; /* country string for this association */ ++} WIFI_INTERFACE_LINK_LAYER_INFO; ++ ++/* access categories */ ++typedef enum { ++ WIFI_AC_VO = 0, ++ WIFI_AC_VI = 1, ++ WIFI_AC_BE = 2, ++ WIFI_AC_BK = 3, ++ WIFI_AC_MAX = 4, ++} WIFI_TRAFFIC_AC; ++ ++/* wifi peer type */ ++typedef enum { ++ WIFI_PEER_STA, ++ WIFI_PEER_AP, ++ WIFI_PEER_P2P_GO, ++ WIFI_PEER_P2P_CLIENT, ++ WIFI_PEER_NAN, ++ WIFI_PEER_TDLS, ++ WIFI_PEER_INVALID, ++} WIFI_PEER_TYPE; ++ ++/* per peer statistics */ ++typedef struct { ++ WIFI_PEER_TYPE type; /* peer type (AP, TDLS, GO etc.) */ ++ UINT_8 peer_mac_address[6]; /* mac address */ ++ UINT_32 capabilities; /* peer WIFI_CAPABILITY_XXX */ ++ UINT_32 num_rate; /* number of rates */ ++ WIFI_RATE_STAT rate_stats[]; /* per rate statistics, number of entries = num_rate */ ++} WIFI_PEER_INFO; ++ ++/* per access category statistics */ ++typedef struct { ++ WIFI_TRAFFIC_AC ac; /* access category (VI, VO, BE, BK) */ ++ UINT_32 tx_mpdu; /* number of successfully transmitted unicast data pkts (ACK rcvd) */ ++ UINT_32 rx_mpdu; /* number of received unicast mpdus */ ++ UINT_32 tx_mcast; /* number of successfully transmitted multicast data packets */ ++ /* STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent */ ++ UINT_32 rx_mcast; /* number of received multicast data packets */ ++ UINT_32 rx_ampdu; /* number of received unicast a-mpdus */ ++ UINT_32 tx_ampdu; /* number of transmitted unicast a-mpdus */ ++ UINT_32 mpdu_lost; /* number of data pkt losses (no ACK) */ ++ UINT_32 retries; /* total number of data pkt retries */ ++ UINT_32 retries_short; /* number of short data pkt retries */ ++ UINT_32 retries_long; /* number of long data pkt retries */ ++ UINT_32 contention_time_min; /* data pkt min contention time (usecs) */ ++ UINT_32 contention_time_max; /* data pkt max contention time (usecs) */ ++ UINT_32 contention_time_avg; /* data pkt avg contention time (usecs) */ ++ UINT_32 contention_num_samples; /* num of data pkts used for contention statistics */ ++} WIFI_WMM_AC_STAT; ++ ++/* interface statistics */ ++typedef struct { ++ /* wifi_interface_handle iface; // wifi interface */ ++ WIFI_INTERFACE_LINK_LAYER_INFO info; /* current state of the interface */ ++ UINT_32 beacon_rx; /* access point beacon received count from connected AP */ ++ UINT_32 mgmt_rx; /* access point mgmt frames received count from connected AP (including Beacon) */ ++ UINT_32 mgmt_action_rx; /* action frames received count */ ++ UINT_32 mgmt_action_tx; /* action frames transmit count */ ++ wifi_rssi rssi_mgmt; /* access Point Beacon and Management frames RSSI (averaged) */ ++ wifi_rssi rssi_data; /* access Point Data Frames RSSI (averaged) from connected AP */ ++ wifi_rssi rssi_ack; /* access Point ACK RSSI (averaged) from connected AP */ ++ WIFI_WMM_AC_STAT ac[WIFI_AC_MAX]; /* per ac data packet statistics */ ++ UINT_32 num_peers; /* number of peers */ ++ WIFI_PEER_INFO peer_info[]; /* per peer statistics */ ++} WIFI_IFACE_STAT; ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, ++ const void *data, int data_len); ++ ++int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete); ++ ++int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num); ++ ++int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); ++ ++int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len); ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); ++ ++int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, ++ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); ++ ++#endif /* _GL_VENDOR_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h +new file mode 100644 +index 000000000000..827ff92b1581 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h +@@ -0,0 +1,357 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext.h#1 ++*/ ++ ++/*! \file gl_wext.h ++ \brief This file is for Portable Driver linux wireless extension support. ++*/ ++ ++/* ++** Log: gl_wext.h ++ * ++ * 10 12 2011 wh.su ++ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP ++ * adding the 802.11w related function and define . ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 09 20 2011 chinglan.wang ++ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. ++ * . ++ * ++ * 01 11 2011 chinglan.wang ++ * NULL ++ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. ++ * Connection establish successfully. ++ * Use the WPS function to connect AP, the privacy bit always is set to 1. . ++ * ++ * 09 27 2010 wh.su ++ * NULL ++ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\12 2009-10-20 17:38:33 GMT mtk01090 ++** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, ++** and then stop hw. ++** \main\maintrunk.MT5921\11 2009-09-28 20:19:28 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\10 2009-09-03 12:12:35 GMT mtk01088 ++** adding the function declaration ++** \main\maintrunk.MT5921\9 2009-08-18 22:57:17 GMT mtk01090 ++** Add Linux SDIO (with mmc core) support. ++** Add Linux 2.6.21, 2.6.25, 2.6.26. ++** Fix compile warning in Linux. ++** \main\maintrunk.MT5921\8 2008-08-29 16:59:07 GMT mtk01088 ++** fixed compiling error ++** \main\maintrunk.MT5921\7 2008-08-29 14:13:28 GMT mtk01088 ++** adjust the header file for code refine ++** \main\maintrunk.MT5921\6 2008-03-28 10:40:31 GMT mtk01461 ++** Add set desired rate in Linux STD IOCTL ++** \main\maintrunk.MT5921\5 2008-03-11 14:51:08 GMT mtk01461 ++** Refine private IOCTL functions ++** \main\maintrunk.MT5921\4 2008-02-12 23:45:45 GMT mtk01461 ++** Add Set Frequency & Channel oid support for Linux ++** \main\maintrunk.MT5921\3 2007-11-06 19:36:19 GMT mtk01088 ++** add the WPS related code ++*/ ++ ++#ifndef _GL_WEXT_H ++#define _GL_WEXT_H ++ ++#ifdef WIRELESS_EXT ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define KILO 1000 ++#define RATE_5_5M 11 /* 5.5M */ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef struct _PARAM_FIXED_IEs { ++ UINT_8 aucTimestamp[8]; ++ UINT_16 u2BeaconInterval; ++ UINT_16 u2Capabilities; ++} PARAM_FIXED_IEs; ++ ++typedef struct _PARAM_VARIABLE_IE_T { ++ UINT_8 ucElementID; ++ UINT_8 ucLength; ++ UINT_8 aucData[1]; ++} PARAM_VARIABLE_IE_T, *P_PARAM_VARIABLE_IE_T; ++ ++#if WIRELESS_EXT < 18 ++ ++#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses struct iw_mlme */ ++/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ ++#define IW_MLME_DEAUTH 0 ++#define IW_MLME_DISASSOC 1 ++ ++/*! \brief SIOCSIWMLME data */ ++struct iw_mlme { ++ __u16 cmd; /*!< IW_MLME_* */ ++ __u16 reason_code; ++ struct sockaddr addr; ++}; ++ ++#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ ++#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ ++/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ ++#define IW_AUTH_INDEX 0x0FFF ++#define IW_AUTH_FLAGS 0xF000 ++/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) ++ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the ++ * parameter that is being set/get to; value will be read/written to ++ * struct iw_param value field) */ ++#define IW_AUTH_WPA_VERSION 0 ++#define IW_AUTH_CIPHER_PAIRWISE 1 ++#define IW_AUTH_CIPHER_GROUP 2 ++#define IW_AUTH_KEY_MGMT 3 ++#define IW_AUTH_TKIP_COUNTERMEASURES 4 ++#define IW_AUTH_DROP_UNENCRYPTED 5 ++#define IW_AUTH_80211_AUTH_ALG 6 ++#define IW_AUTH_WPA_ENABLED 7 ++#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 ++#define IW_AUTH_ROAMING_CONTROL 9 ++#define IW_AUTH_PRIVACY_INVOKED 10 ++#if CFG_SUPPORT_802_11W ++#define IW_AUTH_MFP 12 ++ ++#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ ++#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ ++#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ ++#endif ++ ++/* IW_AUTH_WPA_VERSION values (bit field) */ ++#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 ++#define IW_AUTH_WPA_VERSION_WPA 0x00000002 ++#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 ++ ++/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ ++#define IW_AUTH_CIPHER_NONE 0x00000001 ++#define IW_AUTH_CIPHER_WEP40 0x00000002 ++#define IW_AUTH_CIPHER_TKIP 0x00000004 ++#define IW_AUTH_CIPHER_CCMP 0x00000008 ++#define IW_AUTH_CIPHER_WEP104 0x00000010 ++ ++/* IW_AUTH_KEY_MGMT values (bit field) */ ++#define IW_AUTH_KEY_MGMT_802_1X 1 ++#define IW_AUTH_KEY_MGMT_PSK 2 ++#define IW_AUTH_KEY_MGMT_WPA_NONE 4 ++ ++/* IW_AUTH_80211_AUTH_ALG values (bit field) */ ++#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 ++#define IW_AUTH_ALG_SHARED_KEY 0x00000002 ++#define IW_AUTH_ALG_LEAP 0x00000004 ++ ++/* IW_AUTH_ROAMING_CONTROL values */ ++#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ ++#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming ++ * control */ ++ ++#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ ++#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ ++/* SIOCSIWENCODEEXT definitions */ ++#define IW_ENCODE_SEQ_MAX_SIZE 8 ++/* struct iw_encode_ext ->alg */ ++#define IW_ENCODE_ALG_NONE 0 ++#define IW_ENCODE_ALG_WEP 1 ++#define IW_ENCODE_ALG_TKIP 2 ++#define IW_ENCODE_ALG_CCMP 3 ++#if CFG_SUPPORT_802_11W ++#define IW_ENCODE_ALG_AES_CMAC 5 ++#endif ++ ++/* struct iw_encode_ext ->ext_flags */ ++#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 ++#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 ++#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 ++#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 ++ ++struct iw_encode_ext { ++ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ ++ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ ++ struct sockaddr addr; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast ++ * (group) keys or unicast address for ++ * individual keys */ ++ __u16 alg; /*!< IW_ENCODE_ALG_* */ ++ __u16 key_len; ++ __u8 key[0]; ++}; ++ ++#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ ++#define IW_PMKSA_ADD 1 ++#define IW_PMKSA_REMOVE 2 ++#define IW_PMKSA_FLUSH 3 ++ ++#define IW_PMKID_LEN 16 ++ ++struct iw_pmksa { ++ __u32 cmd; /*!< IW_PMKSA_* */ ++ struct sockaddr bssid; ++ __u8 pmkid[IW_PMKID_LEN]; ++}; ++ ++#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) ++ * (scan results); This includes id and ++ * length fields. One IWEVGENIE may ++ * contain more than one IE. Scan ++ * results may contain one or more ++ * IWEVGENIE events. */ ++#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure ++ * (struct iw_michaelmicfailure) ++ */ ++#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. ++ * The data includes id and length ++ * fields and may contain more than one ++ * IE. This event is required in ++ * Managed mode if the driver ++ * generates its own WPA/RSN IE. This ++ * should be sent just before ++ * IWEVREGISTERED event for the ++ * association. */ ++#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association ++ * Response. The data includes id and ++ * length fields and may contain more ++ * than one IE. This may be sent ++ * between IWEVASSOCREQIE and ++ * IWEVREGISTERED events for the ++ * association. */ ++#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN ++ * pre-authentication ++ * (struct iw_pmkid_cand) */ ++ ++#endif /* WIRELESS_EXT < 18 */ ++ ++#if WIRELESS_EXT < 17 ++/* Statistics flags (bitmask in updated) */ ++#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ ++#define IW_QUAL_LEVEL_UPDATED 0x2 ++#define IW_QUAL_NOISE_UPDATED 0x4 ++#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ ++#define IW_QUAL_LEVEL_INVALID 0x20 ++#define IW_QUAL_NOISE_INVALID 0x40 ++#endif ++ ++enum { ++ IEEE80211_FILTER_TYPE_BEACON = 1 << 0, ++ IEEE80211_FILTER_TYPE_PROBE_REQ = 1 << 1, ++ IEEE80211_FILTER_TYPE_PROBE_RESP = 1 << 2, ++ IEEE80211_FILTER_TYPE_ASSOC_REQ = 1 << 3, ++ IEEE80211_FILTER_TYPE_ASSOC_RESP = 1 << 4, ++ IEEE80211_FILTER_TYPE_AUTH = 1 << 5, ++ IEEE80211_FILTER_TYPE_DEAUTH = 1 << 6, ++ IEEE80211_FILTER_TYPE_DISASSOC = 1 << 7, ++ IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ ++}; ++ ++#if CFG_SUPPORT_WAPI ++#define IW_AUTH_WAPI_ENABLED 0x20 ++#define IW_ENCODE_ALG_SMS4 0x20 ++#endif ++ ++#if CFG_SUPPORT_WAPI /* Android+ */ ++#define IW_AUTH_KEY_MGMT_WAPI_PSK 3 ++#define IW_AUTH_KEY_MGMT_WAPI_CERT 4 ++#endif ++#define IW_AUTH_KEY_MGMT_WPS 5 ++ ++#if CFG_SUPPORT_802_11W ++#define IW_AUTH_KEY_MGMT_802_1X_SHA256 7 ++#define IW_AUTH_KEY_MGMT_PSK_SHA256 8 ++#endif ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++extern const struct iw_handler_def wext_handler_def; ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++/* wireless extensions' ioctls */ ++int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd); ++ ++int ++wext_set_rate(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra); ++ ++void ++wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, ++ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4DataLen); ++ ++struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev); ++ ++BOOLEAN ++wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++ ++#if CFG_SUPPORT_WPS ++BOOLEAN ++wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, ++ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++ ++BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++ ++BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++ ++BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++#if CFG_SUPPORT_WAPI ++BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); ++#endif ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* WIRELESS_EXT */ ++ ++#endif /* _GL_WEXT_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h +new file mode 100644 +index 000000000000..31933fc6a461 +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h +@@ -0,0 +1,402 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext_priv.h#3 ++*/ ++ ++/*! \file gl_wext_priv.h ++ \brief This file includes private ioctl support. ++*/ ++ ++/* ++** Log: gl_wext_priv.h ++ * ++ * 01 16 2012 wh.su ++ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl ++ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. ++ * ++ * 01 05 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the related ioctl / wlan oid function to set the Tx power cfg. ++ * ++ * 01 02 2012 wh.su ++ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function ++ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. ++ * ++ * 11 08 2011 yuche.tsai ++ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service ++ * discovery version check. ++ * Add a CMD ID for P2P driver version query. ++ * ++ * 03 17 2011 chinglan.wang ++ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature ++ * . ++ * ++ * 03 02 2011 wh.su ++ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code ++ * Add security check code. ++ * ++ * 01 27 2011 cm.chang ++ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default ++ * . ++ * ++ * 01 20 2011 eddie.chen ++ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control ++ * Add Oid for sw control debug command ++ * ++ * 01 07 2011 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add a new compiling option to control if MCR read/write is permitted ++ * ++ * 12 31 2010 cm.chang ++ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation ++ * Add some iwpriv commands to support test mode operation ++ * ++ * 11 08 2010 wh.su ++ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 ++ * add the message check code from mt5921. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 09 23 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * add skeleton for NVRAM integration ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * revert changelist #15371, efuse read/write access will be done by RF test approach ++ * ++ * 08 04 2010 cp.wu ++ * NULL ++ * add OID definitions for EFUSE read/write access. ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++ * ++ * 03 31 2010 wh.su ++ * [WPD00003816][MT6620 Wi-Fi] Adding the security support ++ * modify the wapi related code for new driver's design. ++ * ++ * 03 24 2010 jeffrey.chang ++ * [WPD00003826]Initial import for Linux port ++ * initial import for Linux port ++** \main\maintrunk.MT5921\16 2009-09-29 16:47:23 GMT mtk01090 ++** Remove unused functions ++** \main\maintrunk.MT5921\15 2009-09-28 20:19:31 GMT mtk01090 ++** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. ++** \main\maintrunk.MT5921\14 2009-05-07 22:26:06 GMT mtk01089 ++** add private IO control for Linux BWCS ++** \main\maintrunk.MT5921\13 2008-08-29 14:55:20 GMT mtk01088 ++** adjust the code to meet coding style ++** \main\maintrunk.MT5921\12 2008-07-16 15:23:45 GMT mtk01104 ++** Support GPIO2 mode ++** \main\maintrunk.MT5921\11 2008-07-14 13:55:58 GMT mtk01104 ++** Support PRIV_CMD_BT_COEXIST ++** \main\maintrunk.MT5921\10 2008-07-09 00:20:24 GMT mtk01461 ++** Add priv oid to support WMM_PS_TEST ++** \main\maintrunk.MT5921\9 2008-05-30 20:27:24 GMT mtk01461 ++** Add POWER_MODE Private IOCTL cmd ++** \main\maintrunk.MT5921\8 2008-04-17 23:06:44 GMT mtk01461 ++** Add iwpriv support for AdHocMode setting ++** \main\maintrunk.MT5921\7 2008-03-31 21:01:24 GMT mtk01461 ++** Add priv IOCTL for VOIP settings ++** \main\maintrunk.MT5921\6 2008-03-31 13:49:47 GMT mtk01461 ++** add priv ioctl arg definition for turning on / off roaming ++** \main\maintrunk.MT5921\5 2008-03-26 15:35:09 GMT mtk01461 ++** Add CSUM offload priv ioctl for Linux ++** \main\maintrunk.MT5921\4 2008-03-11 14:51:11 GMT mtk01461 ++** Refine private IOCTL functions ++** \main\maintrunk.MT5921\3 2007-11-06 19:36:25 GMT mtk01088 ++** add the WPS related code ++*/ ++ ++#ifndef _GL_WEXT_PRIV_H ++#define _GL_WEXT_PRIV_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++/* If it is set to 1, iwpriv will support register read/write */ ++#define CFG_SUPPORT_PRIV_MCR_RW 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++#if CFG_ENABLE_WIFI_DIRECT ++extern int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); ++#if 0 ++extern BOOLEAN fgIsResetting; ++extern BOOLEAN g_u4HaltFlag; ++extern spinlock_t g_p2p_lock; ++extern int g_u4P2PEnding; ++extern int g_u4P2POnOffing; ++#endif ++#endif ++ ++ ++#if (CFG_SUPPORT_TXR_ENC == 1) ++extern VOID rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); ++#endif /* CFG_SUPPORT_TXR_ENC */ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++/* New wireless extensions API - SET/GET convention (even ioctl numbers are ++ * root only) ++ */ ++#define IOCTL_SET_INT (SIOCIWFIRSTPRIV + 0) ++#define IOCTL_GET_INT (SIOCIWFIRSTPRIV + 1) ++ ++#define IOCTL_SET_ADDRESS (SIOCIWFIRSTPRIV + 2) ++#define IOCTL_GET_ADDRESS (SIOCIWFIRSTPRIV + 3) ++#define IOCTL_SET_STR (SIOCIWFIRSTPRIV + 4) ++#define IOCTL_GET_STR (SIOCIWFIRSTPRIV + 5) ++#define IOCTL_SET_KEY (SIOCIWFIRSTPRIV + 6) ++#define IOCTL_GET_KEY (SIOCIWFIRSTPRIV + 7) ++#define IOCTL_SET_STRUCT (SIOCIWFIRSTPRIV + 8) ++#define IOCTL_GET_STRUCT (SIOCIWFIRSTPRIV + 9) ++#define IOCTL_SET_STRUCT_FOR_EM (SIOCIWFIRSTPRIV + 11) ++#define IOCTL_SET_INTS (SIOCIWFIRSTPRIV + 12) ++#define IOCTL_GET_INTS (SIOCIWFIRSTPRIV + 13) ++#define IOCTL_SET_STRING (SIOCIWFIRSTPRIV + 14) ++ ++#define PRIV_CMD_REG_DOMAIN 0 ++#define PRIV_CMD_BEACON_PERIOD 1 ++#define PRIV_CMD_ADHOC_MODE 2 ++ ++#if CFG_TCP_IP_CHKSUM_OFFLOAD ++#define PRIV_CMD_CSUM_OFFLOAD 3 ++#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ ++ ++#define PRIV_CMD_ROAMING 4 ++#define PRIV_CMD_VOIP_DELAY 5 ++#define PRIV_CMD_POWER_MODE 6 ++ ++#define PRIV_CMD_WMM_PS 7 ++#define PRIV_CMD_BT_COEXIST 8 ++#define PRIV_GPIO2_MODE 9 ++ ++#define PRIV_CUSTOM_SET_PTA 10 ++#define PRIV_CUSTOM_CONTINUOUS_POLL 11 ++#define PRIV_CUSTOM_SINGLE_ANTENNA 12 ++#define PRIV_CUSTOM_BWCS_CMD 13 ++#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION 14 /* later */ ++#define PRIV_CMD_OID 15 ++#define PRIV_SEC_MSG_OID 16 ++ ++#define PRIV_CMD_TEST_MODE 17 ++#define PRIV_CMD_TEST_CMD 18 ++#define PRIV_CMD_ACCESS_MCR 19 ++#define PRIV_CMD_SW_CTRL 20 ++ ++#if 1 /* ANTI_PRIVCY */ ++#define PRIV_SEC_CHECK_OID 21 ++#endif ++ ++#define PRIV_CMD_WSC_PROBE_REQ 22 ++ ++#define PRIV_CMD_P2P_VERSION 23 ++ ++#define PRIV_CMD_GET_CH_LIST 24 ++ ++#define PRIV_CMD_SET_TX_POWER 25 ++ ++#define PRIV_CMD_BAND_CONFIG 26 ++ ++#define PRIV_CMD_DUMP_MEM 27 ++ ++#define PRIV_CMD_P2P_MODE 28 ++ ++#define PRIV_CMD_GET_BUILD_DATE_CODE 29 ++ ++#define PRIV_CMD_GET_DEBUG_CODE 30 ++ ++#define PRIV_CMD_OTHER 31 ++ ++#define PRIV_CMD_WFD_DEBUG_CODE 32 ++ ++#define PRIV_CMD_MET_PROFILING 33 ++ ++/* other string command ID */ ++#define PRIV_CMD_OTHER_TDLS 0x00 ++#define PRIV_CMD_OTHER_TAR 0x01 /* TX auto rate */ ++ ++/* 802.3 Objects (Ethernet) */ ++#define OID_802_3_CURRENT_ADDRESS 0x01010102 ++ ++/* IEEE 802.11 OIDs */ ++#define OID_802_11_SUPPORTED_RATES 0x0D01020E ++#define OID_802_11_CONFIGURATION 0x0D010211 ++ ++/* PnP and PM OIDs, NDIS default OIDS */ ++#define OID_PNP_SET_POWER 0xFD010101 ++ ++#define OID_CUSTOM_OID_INTERFACE_VERSION 0xFFA0C000 ++ ++/* MT5921 specific OIDs */ ++#define OID_CUSTOM_BT_COEXIST_CTRL 0xFFA0C580 ++#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE 0xFFA0C581 ++#define OID_CUSTOM_PATTERN_CONFIG 0xFFA0C582 ++#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG 0xFFA0C583 ++#define OID_CUSTOM_VOIP_SETUP 0xFFA0C584 ++#define OID_CUSTOM_ADD_TS 0xFFA0C585 ++#define OID_CUSTOM_DEL_TS 0xFFA0C586 ++#define OID_CUSTOM_SLT 0xFFA0C587 ++#define OID_CUSTOM_ROAMING_EN 0xFFA0C588 ++#define OID_CUSTOM_WMM_PS_TEST 0xFFA0C589 ++#define OID_CUSTOM_COUNTRY_STRING 0xFFA0C58A ++#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY 0xFFA0C58B ++#define OID_CUSTOM_GPIO2_MODE 0xFFA0C58C ++#define OID_CUSTOM_CONTINUOUS_POLL 0xFFA0C58D ++#define OID_CUSTOM_DISABLE_BEACON_DETECTION 0xFFA0C58E ++ ++/* CR1460, WPS privacy bit check disable */ ++#define OID_CUSTOM_DISABLE_PRIVACY_CHECK 0xFFA0C600 ++ ++/* Precedent OIDs */ ++#define OID_CUSTOM_MCR_RW 0xFFA0C801 ++#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 ++#define OID_CUSTOM_SW_CTRL 0xFFA0C805 ++#define OID_CUSTOM_MEM_DUMP 0xFFA0C807 ++ ++/* RF Test specific OIDs */ ++#define OID_CUSTOM_TEST_MODE 0xFFA0C901 ++#define OID_CUSTOM_TEST_RX_STATUS 0xFFA0C903 ++#define OID_CUSTOM_TEST_TX_STATUS 0xFFA0C905 ++#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 ++#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 ++ ++/* BWCS */ ++#define OID_CUSTOM_BWCS_CMD 0xFFA0C931 ++#define OID_CUSTOM_SINGLE_ANTENNA 0xFFA0C932 ++#define OID_CUSTOM_SET_PTA 0xFFA0C933 ++ ++/* NVRAM */ ++#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 ++#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 ++#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 ++ ++#if CFG_SUPPORT_WAPI ++#define OID_802_11_WAPI_MODE 0xFFA0CA00 ++#define OID_802_11_WAPI_ASSOC_INFO 0xFFA0CA01 ++#define OID_802_11_SET_WAPI_KEY 0xFFA0CA02 ++#endif ++ ++#if CFG_SUPPORT_WPS2 ++#define OID_802_11_WSC_ASSOC_INFO 0xFFA0CB00 ++#endif ++ ++/* Define magic key of test mode (Don't change it for future compatibity) */ ++#define PRIV_CMD_TEST_MAGIC_KEY 2011 ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++/* NIC BBCR configuration entry structure */ ++typedef struct _PRIV_CONFIG_ENTRY { ++ UINT_8 ucOffset; ++ UINT_8 ucValue; ++} PRIV_CONFIG_ENTRY, *PPRIV_CONFIG_ENTRY; ++ ++typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC_REQ) (IN PVOID prAdapter, ++ IN OUT PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); ++ ++typedef enum _ENUM_OID_METHOD_T { ++ ENUM_OID_GLUE_ONLY, ++ ENUM_OID_GLUE_EXTENSION, ++ ENUM_OID_DRIVER_CORE ++} ENUM_OID_METHOD_T, *P_ENUM_OID_METHOD_T; ++ ++/* OID set/query processing entry */ ++typedef struct _WLAN_REQ_ENTRY { ++ UINT_32 rOid; /* OID */ ++ PUINT_8 pucOidName; /* OID name text */ ++ BOOLEAN fgQryBufLenChecking; ++ BOOLEAN fgSetBufLenChecking; ++ ENUM_OID_METHOD_T eOidMethod; ++ UINT_32 u4InfoBufLen; ++ PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler; /* PFN_OID_HANDLER_FUNC */ ++ PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler; /* PFN_OID_HANDLER_FUNC */ ++} WLAN_REQ_ENTRY, *P_WLAN_REQ_ENTRY; ++ ++typedef struct _NDIS_TRANSPORT_STRUCT { ++ UINT_32 ndisOidCmd; ++ UINT_32 inNdisOidlength; ++ UINT_32 outNdisOidLength; ++ UINT_8 ndisOidContent[16]; ++} NDIS_TRANSPORT_STRUCT, *P_NDIS_TRANSPORT_STRUCT; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++int ++priv_set_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int ++priv_get_int(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); ++ ++int ++priv_set_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int ++priv_get_ints(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); ++ ++int ++priv_set_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int ++priv_get_struct(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); ++ ++UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen); ++ ++UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac); ++ ++int ++priv_set_string(IN struct net_device *prNetDev, ++ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); ++ ++int priv_support_ioctl(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); ++ ++int priv_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); ++ ++INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen); ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _GL_WEXT_PRIV_H */ +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c +new file mode 100644 +index 000000000000..fba854cfd68e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c +@@ -0,0 +1,542 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#1 ++*/ ++ ++/*! \file "platform.c" ++ \brief This file including the protocol layer privacy function. ++ ++ This file provided the macros and functions library support for the ++ protocol layer security setting from wlan_oid.c and for parse.c and ++ rsn.c and nic_privacy.c ++ ++*/ ++ ++/* ++** Log: platform.c ++ * ++ * 11 14 2011 cm.chang ++ * NULL ++ * Fix compiling warning ++ * ++ * 11 10 2011 cp.wu ++ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer ++ * 1. eliminaite direct calls to printk in porting layer. ++ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. ++ * ++ * 09 13 2011 jeffrey.chang ++ * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection ++ * fix the pointer casting ++ * ++ * 06 29 2011 george.huang ++ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 ++ * . ++ * ++ * 06 28 2011 george.huang ++ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 ++ * remove un-used code ++ * ++ * 05 11 2011 jeffrey.chang ++ * NULL ++ * fix build error ++ * ++ * 05 09 2011 jeffrey.chang ++ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change ++ * support ARP filter through kernel notifier ++ * ++ * 04 08 2011 pat.lu ++ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver ++ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver ++ * ++ * 03 22 2011 pat.lu ++ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build ++ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. ++ * ++ * 03 21 2011 cp.wu ++ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer ++ * improve portability for awareness of early version of linux kernel and wireless extension. ++ * ++ * 03 18 2011 jeffrey.chang ++ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue ++ * remove early suspend functions ++ * ++ * 03 03 2011 jeffrey.chang ++ * NULL ++ * add the ARP filter callback ++ * ++ * 02 15 2011 jeffrey.chang ++ * NULL ++ * to support early suspend in android ++ * ++ * 02 01 2011 cp.wu ++ * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 ++ * branch ++ * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/... ++ * ++ * 11 01 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] ++ * Add implementation for querying current TX rate from firmware auto rate module ++ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead ++ * 2) Remove CNM CH-RECOVER event handling ++ * 3) cfg read/write API renamed with kal prefix for unified naming rules. ++ * ++ * 10 18 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] ++ * The mac address is all zero at android ++ * complete implementation of Android NVRAM access ++ * ++ * 10 05 2010 cp.wu ++ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check ++ * 1) add NVRAM access API ++ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) ++ * 3) add OID implementation for NVRAM read/write service ++ * ++** ++*/ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "gl_os.h" ++ ++#ifndef CONFIG_X86 ++#if defined(CONFIG_HAS_EARLY_SUSPEND) ++#include ++#endif ++#endif ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++#define WIFI_NVRAM_FILE_NAME "/etc/firmware/nvram/WIFI" ++#define WIFI_NVRAM_CUSTOM_NAME "/etc/firmware/nvram/WIFI_CUSTOM" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) ++{ ++ UINT_8 ip[4] = { 0 }; ++ UINT_32 u4NumIPv4 = 0; ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ ++ UINT_32 u4NumIPv6 = 0; ++#endif ++ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; ++ struct net_device *prDev = ifa->ifa_dev->dev; ++ UINT_32 i; ++ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (prDev == NULL) { ++ DBGLOG(REQ, ERROR, "netdev_event: device is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ DBGLOG(REQ, INFO, "netdev_event, addr=%x, notification=%lx, dev_name=%s\n", ++ ifa->ifa_address, notification, prDev->name); ++ if (!fgIsUnderSuspend) ++ return NOTIFY_DONE; ++ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { ++ DBGLOG(REQ, WARN, "netdev_event: not our device\n"); ++ return NOTIFY_DONE; ++ } ++#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ ++ { ++ /* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */ ++ prGlueInfo->fgIsDad = FALSE; ++ } ++#endif ++ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ ++ if (prGlueInfo == NULL) { ++ DBGLOG(REQ, ERROR, "netdev_event: prGlueInfo is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ ASSERT(prGlueInfo); ++ ++ /* <3> get the IPv4 address */ ++ if (!prDev || !(prDev->ip_ptr) || ++ !((struct in_device *)(prDev->ip_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(REQ, INFO, "ip is not available.\n"); ++ return NOTIFY_DONE; ++ } ++ ++ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); ++ DBGLOG(REQ, INFO, "ip is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); ++ ++ /* todo: traverse between list to find whole sets of IPv4 addresses */ ++ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) ++ u4NumIPv4++; ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ if (!prDev || !(prDev->ip6_ptr) || ++ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || ++ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { ++ DBGLOG(REQ, INFO, "ipv6 is not available.\n"); ++ return NOTIFY_DONE; ++ } ++ ++ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); ++ DBGLOG(REQ, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ++ ip6[0], ip6[1], ip6[2], ip6[3], ++ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); ++ ++ /* todo: traverse between list to find whole sets of IPv6 addresses */ ++ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) ++ /* u4NumIPv6++; */ ++#endif ++ ++ /* here we can compare the dev with other network's netdev to */ ++ /* set the proper arp filter */ ++ /* */ ++ /* IMPORTANT: please make sure if the context can sleep, if the context can't sleep */ ++ /* we should schedule a kernel thread to do this for us */ ++ ++ /* <7> set up the ARP filter */ ++ { ++ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; ++ UINT_32 u4SetInfoLen = 0; ++ UINT_8 aucBuf[32] = { 0 }; ++ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); ++ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) aucBuf; ++ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; ++ ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6; ++#else ++ prParamNetAddrList->u4AddressCount = u4NumIPv4; ++#endif ++ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ for (i = 0; i < u4NumIPv4; i++) { ++ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++#if 0 ++ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); ++#else ++ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; ++ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); ++ prParamNetAddr = ++ (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); ++#endif ++ } ++/* #ifdef CONFIG_IPV6 */ ++#if 0 ++ for (i = 0; i < u4NumIPv6; i++) { ++ prParamNetAddr->u2AddressLength = 6; ++ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; ++ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); ++ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip6)); ++ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); ++ } ++#endif ++ ASSERT(u4Len <= sizeof(aucBuf)); ++ ++ DBGLOG(REQ, INFO, "kalIoctl (0x%p, 0x%p)\n", prGlueInfo, prParamNetAddrList); ++ ++ rStatus = kalIoctl(prGlueInfo, ++ wlanoidSetNetworkAddress, ++ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); ++ ++ if (rStatus != WLAN_STATUS_SUCCESS) ++ DBGLOG(REQ, ERROR, "set HW pattern filter fail 0x%x\n", rStatus); ++ } ++ ++ return NOTIFY_DONE; ++ ++} ++ ++/* #if CFG_SUPPORT_HOTSPOT_2_0 */ ++#if 0 ++static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr) ++{ ++ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; ++ struct net_device *prDev = ifa->idev->dev; ++ P_GLUE_INFO_T prGlueInfo = NULL; ++ ++ if (prDev == NULL) { ++ DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ ++ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { ++ DBGLOG(REQ, INFO, "net6dev_event: xxx\n"); ++ return NOTIFY_DONE; ++ } ++ ++ if (strncmp(prDev->name, "p2p", 3) == 0) { ++ /* because we store the address of prGlueInfo in p2p's private date of net device */ ++ /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */ ++ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); ++ } else { /* wlan0 */ ++ prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); ++ } ++ ++ if (prGlueInfo == NULL) { ++ DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n"); ++ return NOTIFY_DONE; ++ } ++ /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */ ++ prGlueInfo->fgIs6Dad = FALSE; ++ ++ return NOTIFY_DONE; ++} ++#endif ++ ++static struct notifier_block inetaddr_notifier = { ++ .notifier_call = netdev_event, ++}; ++ ++#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ ++static struct notifier_block inet6addr_notifier = { ++ .notifier_call = net6dev_event, ++}; ++#endif ++ ++void wlanRegisterNotifier(void) ++{ ++ register_inetaddr_notifier(&inetaddr_notifier); ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ /* register_inet6addr_notifier(&inet6addr_notifier); */ ++#endif ++} ++ ++/* EXPORT_SYMBOL(wlanRegisterNotifier); */ ++ ++void wlanUnregisterNotifier(void) ++{ ++ unregister_inetaddr_notifier(&inetaddr_notifier); ++ ++#if CFG_SUPPORT_HOTSPOT_2_0 ++ /* unregister_inetaddr_notifier(&inet6addr_notifier); */ ++#endif ++} ++ ++/* EXPORT_SYMBOL(wlanUnregisterNotifier); */ ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Utility function for reading data from files on NVRAM-FS ++* ++* \param[in] ++* filename ++* len ++* offset ++* \param[out] ++* buf ++* \return ++* actual length of data being read ++*/ ++/*----------------------------------------------------------------------------*/ ++static int nvram_read(char *filename, char *buf, ssize_t len, int offset) ++{ ++#if CFG_SUPPORT_NVRAM ++ struct file *fd; ++ int retLen = -1; ++ ++ mm_segment_t old_fs = get_fs(); ++ ++ set_fs(KERNEL_DS); ++ ++ fd = filp_open(filename, O_RDONLY, 0644); ++ ++ if (IS_ERR(fd)) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to open!!\n"); ++ return -1; ++ } ++ ++ do { ++ //if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) { ++ if ( fd->f_op == NULL ) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : file can not be read!!\n"); ++ break; ++ } ++ ++ if (fd->f_pos != offset) { ++ if (fd->f_op->llseek) { ++ if (fd->f_op->llseek(fd, offset, 0) != offset) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to seek!!\n"); ++ break; ++ } ++ } else { ++ fd->f_pos = offset; ++ } ++ } ++ ++ retLen = vfs_read(fd, buf, len, &fd->f_pos); ++ ++ } while (FALSE); ++ ++ filp_close(fd, NULL); ++ ++ set_fs(old_fs); ++ ++ return retLen; ++ ++#else /* !CFG_SUPPORT_NVRAM */ ++ ++ return -EIO; ++ ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief Utility function for writing data to files on NVRAM-FS ++* ++* \param[in] ++* filename ++* buf ++* len ++* offset ++* \return ++* actual length of data being written ++*/ ++/*----------------------------------------------------------------------------*/ ++static int nvram_write(char *filename, char *buf, ssize_t len, int offset) ++{ ++#if CFG_SUPPORT_NVRAM ++ struct file *fd; ++ int retLen = -1; ++ ++ mm_segment_t old_fs = get_fs(); ++ ++ set_fs(KERNEL_DS); ++ ++ fd = filp_open(filename, O_WRONLY | O_CREAT, 0644); ++ ++ if (IS_ERR(fd)) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to open!!\n"); ++ return -1; ++ } ++ ++ do { ++ if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : file can not be write!!\n"); ++ break; ++ } ++ /* End of if */ ++ if (fd->f_pos != offset) { ++ if (fd->f_op->llseek) { ++ if (fd->f_op->llseek(fd, offset, 0) != offset) { ++ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to seek!!\n"); ++ break; ++ } ++ } else { ++ fd->f_pos = offset; ++ } ++ } ++ ++ retLen = vfs_write(fd, buf, len, &fd->f_pos); ++ ++ } while (FALSE); ++ ++ filp_close(fd, NULL); ++ ++ set_fs(old_fs); ++ ++ return retLen; ++ ++#else /* !CFG_SUPPORT_NVRAMS */ ++ ++ return -EIO; ++ ++#endif ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief API for reading data on NVRAM ++* ++* \param[in] ++* prGlueInfo ++* u4Offset ++* \param[out] ++* pu2Data ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data) ++{ ++ if (pu2Data == NULL) ++ return FALSE; ++ ++ if (nvram_read(WIFI_NVRAM_FILE_NAME, ++ (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { ++ return FALSE; ++ } else { ++ return TRUE; ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*! ++* \brief API for writing data on NVRAM ++* ++* \param[in] ++* prGlueInfo ++* u4Offset ++* u2Data ++* \return ++* TRUE ++* FALSE ++*/ ++/*----------------------------------------------------------------------------*/ ++BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data) ++{ ++ if (nvram_write(WIFI_NVRAM_FILE_NAME, ++ (char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { ++ return FALSE; ++ } else { ++ return TRUE; ++ } ++} +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h +new file mode 100644 +index 000000000000..9444d415c60e +--- /dev/null ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h +@@ -0,0 +1,190 @@ ++/* ++** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/version.h#1 ++*/ ++ ++/*! \file "version.h" ++ \brief Driver's version definition ++ ++*/ ++ ++/* ++** Log: version.h ++ * ++ * 11 01 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.1.1. ++ * ++ * 08 26 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.9.. ++ * ++ * 08 23 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.8. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * correct typo. ++ * ++ * 08 15 2011 cp.wu ++ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree ++ * for building MT6628 Win32 driver environment ++ * ++ * 08 03 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.7. ++ * ++ * 07 24 2011 puff.wen ++ * NULL ++ * [MT5931][Beta 5]Change the version number to v0.2.2.0 ++ * ++ * 06 01 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.6.. ++ * ++ * 05 09 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.5.. ++ * ++ * 04 19 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.4. ++ * ++ * 04 18 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.3. ++ * ++ * 03 25 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.2. ++ * ++ * 03 21 2011 chinglan.wang ++ * NULL ++ * Change the version number to 2.0.0.1. ++ * ++ * 03 18 2011 chinglan.wang ++ * NULL ++ * Change the version number to v2.0.0.0. ++ * ++ * 02 11 2011 chinglan.wang ++ * NULL ++ * Change to the version 1.2.0.2. ++ * ++ * 02 10 2011 chinglan.wang ++ * NULL ++ * Change the version to 1.2.0.1. ++ * ++ * 02 08 2011 cp.wu ++ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number ++ * change version number to v1.2.0.0 for preparing v1.2 software package release. ++ * ++ * 12 10 2010 kevin.huang ++ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check ++ * Add Linux Proc Support ++ * ++ * 10 07 2010 cp.wu ++ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection ++ * [WINDDK] build system changes for MT5931 ++ * ++ * 07 08 2010 cp.wu ++ * ++ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. ++ * ++ * 06 06 2010 kevin.huang ++ * [WPD00003832][MT6620 5931] Create driver base ++ * [MT6620 5931] Create driver base ++** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-12-14 14:10:55 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-17 22:41:00 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-13 16:20:33 GMT mtk01084 ++** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:27:13 GMT mtk01426 ++** Init for develop ++** ++*/ ++ ++#ifndef _VERSION_H ++#define _VERSION_H ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++#ifndef NIC_AUTHOR ++#define NIC_AUTHOR "NIC_AUTHOR" ++#endif ++#ifndef NIC_DESC ++#define NIC_DESC "NIC_DESC" ++#endif ++ ++#ifndef NIC_NAME ++#if defined(MT6620) ++#define NIC_NAME "MT6620" ++#define NIC_DEVICE_ID "MT6620" ++#define NIC_DEVICE_ID_LOW "mt6620" ++#elif defined(MT6628) ++#define NIC_NAME "MT6582" ++#define NIC_DEVICE_ID "MT6582" ++#define NIC_DEVICE_ID_LOW "mt6582" ++#endif ++#endif ++ ++/* NIC driver information */ ++#define NIC_VENDOR "MediaTek Inc." ++#define NIC_VENDOR_OUI {0x00, 0x0C, 0xE7} ++ ++#if defined(MT6620) ++#define NIC_PRODUCT_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter" ++#define NIC_DRIVER_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter Driver" ++#elif defined(MT6628) ++/* #define NIC_PRODUCT_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter" */ ++/* #define NIC_DRIVER_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter Driver" */ ++#define NIC_PRODUCT_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter" ++#define NIC_DRIVER_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter Driver" ++#endif ++ ++/* Define our driver version */ ++#define NIC_DRIVER_MAJOR_VERSION 2 ++#define NIC_DRIVER_MINOR_VERSION 0 ++#define NIC_DRIVER_VERSION (2, 0, 1, 1) ++#define NIC_DRIVER_VERSION_STRING "2.0.1.1" ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _VERSION_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/aee.h b/drivers/misc/mediatek/include/mt-plat/aee.h +new file mode 100644 +index 000000000000..d1cf448dafb2 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/aee.h +@@ -0,0 +1,284 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#if !defined(__AEE_H__) ++#define __AEE_H__ ++ ++#include ++#include ++ ++#define AEE_MODULE_NAME_LENGTH 64 ++#define AEE_PROCESS_NAME_LENGTH 256 ++#define AEE_BACKTRACE_LENGTH 3072 ++ ++typedef enum { ++ AE_DEFECT_FATAL, ++ AE_DEFECT_EXCEPTION, ++ AE_DEFECT_WARNING, ++ AE_DEFECT_REMINDING, ++ AE_DEFECT_ATTR_END ++} AE_DEFECT_ATTR; ++ ++typedef enum { ++ AE_KE = 0, /* Fatal Exception */ ++ AE_HWT, ++ AE_REBOOT, ++ AE_NE, ++ AE_JE, ++ AE_SWT, ++ AE_EE, ++ AE_EXP_ERR_END, ++ AE_ANR, /* Error or Warning or Defect */ ++ AE_RESMON, ++ AE_MODEM_WARNING, ++ AE_WTF, ++ AE_WRN_ERR_END, ++ AE_MANUAL, /* Manual Raise */ ++ AE_EXP_CLASS_END, ++ ++ AE_KERNEL_PROBLEM_REPORT = 1000, ++ AE_SYSTEM_JAVA_DEFECT, ++ AE_SYSTEM_NATIVE_DEFECT, ++ AE_MANUAL_MRDUMP_KEY, ++} AE_EXP_CLASS; /* General Program Exception Class */ ++ ++typedef enum { ++ AEE_REBOOT_MODE_NORMAL = 0, ++ AEE_REBOOT_MODE_KERNEL_OOPS, ++ AEE_REBOOT_MODE_KERNEL_PANIC, ++ AEE_REBOOT_MODE_NESTED_EXCEPTION, ++ AEE_REBOOT_MODE_WDT, ++ AEE_REBOOT_MODE_MANUAL_KDUMP, ++} AEE_REBOOT_MODE; ++ ++#define AEE_SZ_SYMBOL_L 140 ++#define AEE_SZ_SYMBOL_S 80 ++struct aee_bt_frame { ++ __u64 pc; ++ __u64 lr; ++ __u32 pad[5]; ++ char pc_symbol[AEE_SZ_SYMBOL_S]; /* Now we use different symbol length for PC &LR */ ++ char lr_symbol[AEE_SZ_SYMBOL_L]; ++}; ++ ++/* aee_process_info struct should strictly small than ipanic_buffer, now 4KB */ ++struct aee_process_info { ++ char process_path[AEE_PROCESS_NAME_LENGTH]; ++ char backtrace[AEE_BACKTRACE_LENGTH]; ++ struct aee_bt_frame ke_frame; ++}; ++ ++struct aee_process_bt { ++ __u32 pid; ++ __u32 nr_entries; ++ struct aee_bt_frame *entries; ++}; ++ ++ ++struct aee_thread_reg { ++ pid_t tid; ++ struct pt_regs regs; ++}; ++ ++struct aee_user_thread_stack { ++ pid_t tid; ++ int StackLength; ++ unsigned char *Userthread_Stack; /*8k stack ,define to char only for match 64bit/32bit*/ ++}; ++ ++struct aee_user_thread_maps { ++ pid_t tid; ++ int Userthread_mapsLength; ++ unsigned char *Userthread_maps; /*8k stack ,define to char only for match 64bit/32bit*/ ++}; ++ ++ ++ ++struct aee_oops { ++ struct list_head list; ++ AE_DEFECT_ATTR attr; ++ AE_EXP_CLASS clazz; ++ ++ char module[AEE_MODULE_NAME_LENGTH]; ++ /* consist with struct aee_process_info */ ++ char process_path[AEE_PROCESS_NAME_LENGTH]; ++ char backtrace[AEE_BACKTRACE_LENGTH]; ++ struct aee_bt_frame ke_frame; ++ ++ char *detail; ++ int detail_len; ++ ++ char *console; ++ int console_len; ++ ++ char *android_main; ++ int android_main_len; ++ char *android_radio; ++ int android_radio_len; ++ char *android_system; ++ int android_system_len; ++ ++ char *userspace_info; ++ int userspace_info_len; ++ ++ char *mmprofile; ++ int mmprofile_len; ++ ++ char *mini_rdump; ++ int mini_rdump_len; ++ ++ ++ struct aee_user_thread_stack userthread_stack; ++ struct aee_thread_reg userthread_reg; ++ struct aee_user_thread_maps userthread_maps; ++ ++ int dump_option; ++}; ++ ++struct aee_kernel_api { ++ void (*kernel_reportAPI)(const AE_DEFECT_ATTR attr, const int db_opt, const char *module, ++ const char *msg); ++ void (*md_exception)(const char *assert_type, const int *log, int log_size, const int *phy, ++ int phy_size, const char *detail, const int db_opt); ++ void (*md32_exception)(const char *assert_type, const int *log, int log_size, ++ const int *phy, int phy_size, const char *detail, const int db_opt); ++ void (*combo_exception)(const char *assert_type, const int *log, int log_size, ++ const int *phy, int phy_size, const char *detail, const int db_opt); ++ void (*scp_exception)(const char *assert_type, const int *log, int log_size, ++ const int *phy, int phy_size, const char *detail, const int db_opt); ++}; ++ ++void aee_sram_printk(const char *fmt, ...); ++int aee_nested_printf(const char *fmt, ...); ++void aee_wdt_irq_info(void); ++void aee_wdt_fiq_info(void *arg, void *regs, void *svc_sp); ++void aee_trigger_kdb(void); ++struct aee_oops *aee_oops_create(AE_DEFECT_ATTR attr, AE_EXP_CLASS clazz, const char *module); ++void aee_oops_set_backtrace(struct aee_oops *oops, const char *backtrace); ++void aee_oops_set_process_path(struct aee_oops *oops, const char *process_path); ++void aee_oops_free(struct aee_oops *oops); ++/* powerkey press,modules use bits */ ++#define AE_WDT_Powerkey_DEVICE_PATH "/dev/kick_powerkey" ++#define WDT_SETBY_DEFAULT (0) ++#define WDT_SETBY_Backlight (1<<0) ++#define WDT_SETBY_Display (1<<1) ++#define WDT_SETBY_SF (1<<2) ++#define WDT_SETBY_PM (1<<3) ++#define WDT_SETBY_WMS_DISABLE_PWK_MONITOR (0xAEEAEE00) ++#define WDT_SETBY_WMS_ENABLE_PWK_MONITOR (0xAEEAEE01) ++#define WDT_PWK_HANG_FORCE_HWT (0xAEE0FFFF) ++ ++/* QHQ RT Monitor */ ++#define AEEIOCTL_RT_MON_Kick _IOR('p', 0x0A, int) ++#define AE_WDT_DEVICE_PATH "/dev/RT_Monitor" ++/* QHQ RT Monitor end */ ++ ++/* DB dump option bits, set relative bit to 1 to include related file in db */ ++#define DB_OPT_DEFAULT (0) ++#define DB_OPT_FTRACE (1<<0) ++#define DB_OPT_PRINTK_TOO_MUCH (1<<1) ++#define DB_OPT_NE_JBT_TRACES (1<<2) ++#define DB_OPT_SWT_JBT_TRACES (1<<3) ++#define DB_OPT_VM_TRACES (1<<4) ++#define DB_OPT_DUMPSYS_ACTIVITY (1<<5) ++#define DB_OPT_DUMPSYS_WINDOW (1<<6) ++#define DB_OPT_DUMPSYS_GFXINFO (1<<7) ++#define DB_OPT_DUMPSYS_SURFACEFLINGER (1<<8) ++#define DB_OPT_DISPLAY_HANG_DUMP (1<<9) ++#define DB_OPT_LOW_MEMORY_KILLER (1<<10) ++#define DB_OPT_PROC_MEM (1<<11) ++#define DB_OPT_FS_IO_LOG (1<<12) ++#define DB_OPT_PROCESS_COREDUMP (1<<13) ++#define DB_OPT_VM_HPROF (1<<14) ++#define DB_OPT_PROCMEM (1<<15) ++#define DB_OPT_DUMPSYS_INPUT (1<<16) ++#define DB_OPT_MMPROFILE_BUFFER (1<<17) ++#define DB_OPT_BINDER_INFO (1<<18) ++#define DB_OPT_WCN_ISSUE_INFO (1<<19) ++#define DB_OPT_DUMMY_DUMP (1<<20) ++#define DB_OPT_PID_MEMORY_INFO (1<<21) ++#define DB_OPT_VM_OOME_HPROF (1<<22) ++#define DB_OPT_PID_SMAPS (1<<23) ++#define DB_OPT_PROC_CMDQ_INFO (1<<24) ++#define DB_OPT_PROC_USKTRK (1<<25) ++#define DB_OPT_SF_RTT_DUMP (1<<26) ++#define DB_OPT_PAGETYPE_INFO (1<<27) ++#define DB_OPT_DUMPSYS_PROCSTATS (1<<28) ++#define DB_OPT_DUMP_DISPLAY (1<<29) ++#define DB_OPT_NATIVE_BACKTRACE (1<<30) ++#define DB_OPT_AARCH64 (1<<31) ++ ++#define aee_kernel_exception(module, msg...) \ ++ aee_kernel_exception_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) ++#define aee_kernel_warning(module, msg...) \ ++ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) ++#define aee_kernel_reminding(module, msg...) \ ++ aee_kernel_reminding_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) ++#define aee_kernel_dal_show(msg) \ ++ aee_kernel_dal_api(__FILE__, __LINE__, msg) ++ ++#define aed_md_exception(log, log_size, phy, phy_size, detail) \ ++ aed_md_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++#define aed_md32_exception(log, log_size, phy, phy_size, detail) \ ++ aed_md32_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++#define aed_scp_exception(log, log_size, phy, phy_size, detail) \ ++ aed_scp_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++#define aed_combo_exception(log, log_size, phy, phy_size, detail) \ ++ aed_combo_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) ++ ++void aee_kernel_exception_api(const char *file, const int line, const int db_opt, ++ const char *module, const char *msg, ...); ++void aee_kernel_warning_api(const char *file, const int line, const int db_opt, const char *module, ++ const char *msg, ...); ++void aee_kernel_reminding_api(const char *file, const int line, const int db_opt, ++ const char *module, const char *msg, ...); ++void aee_kernel_dal_api(const char *file, const int line, const char *msg); ++ ++void aed_md_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++void aed_md32_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++void aed_scp_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++void aed_combo_exception_api(const int *log, int log_size, const int *phy, int phy_size, ++ const char *detail, const int db_opt); ++ ++void aee_kernel_wdt_kick_Powkey_api(const char *module, int msg); ++int aee_kernel_wdt_kick_api(int kinterval); ++void aee_powerkey_notify_press(unsigned long pressed); ++int aee_kernel_Powerkey_is_press(void); ++ ++void ipanic_recursive_ke(struct pt_regs *regs, struct pt_regs *excp_regs, int cpu); ++ ++/* QHQ RT Monitor */ ++void aee_kernel_RT_Monitor_api(int lParam); ++/* QHQ RT Monitor end */ ++void mt_fiq_printf(const char *fmt, ...); ++void aee_register_api(struct aee_kernel_api *aee_api); ++int aee_in_nested_panic(void); ++void aee_stop_nested_panic(struct pt_regs *regs); ++void aee_wdt_dump_info(void); ++void aee_wdt_printf(const char *fmt, ...); ++ ++void aee_fiq_ipi_cpu_stop(void *arg, void *regs, void *svc_sp); ++ ++#if defined(CONFIG_MTK_AEE_DRAM_CONSOLE) ++void aee_dram_console_reserve_memory(void); ++#else ++static inline void aee_dram_console_reserve_memory(void) ++{ ++} ++#endif ++ ++extern void *aee_excp_regs; /* To store latest exception, in case of stack corruption */ ++#endif /* __AEE_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mrdump.h b/drivers/misc/mediatek/include/mt-plat/mrdump.h +new file mode 100644 +index 000000000000..b6bdfa2f7617 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mrdump.h +@@ -0,0 +1,204 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. ++ */ ++ ++#if !defined(__MRDUMP_H__) ++#define __MRDUMP_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __aarch64__ ++#define reg_pc pc ++#define reg_lr regs[30] ++#define reg_sp sp ++#define reg_fp regs[29] ++#else ++#define reg_pc ARM_pc ++#define reg_lr ARM_lr ++#define reg_sp ARM_sp ++#define reg_ip ARM_ip ++#define reg_fp ARM_fp ++#endif ++ ++#define MRDUMP_CPU_MAX 16 ++ ++#define MRDUMP_DEV_NULL 0 ++#define MRDUMP_DEV_SDCARD 1 ++#define MRDUMP_DEV_EMMC 2 ++ ++#define MRDUMP_FS_NULL 0 ++#define MRDUMP_FS_VFAT 1 ++#define MRDUMP_FS_EXT4 2 ++ ++#define MRDUMP_GO_DUMP "MRDUMP04" ++ ++typedef uint32_t arm32_gregset_t[18]; ++typedef uint64_t aarch64_gregset_t[34]; ++ ++struct mrdump_crash_record { ++ int reboot_mode; ++ ++ char msg[128]; ++ char backtrace[512]; ++ ++ uint32_t fault_cpu; ++ ++ union { ++ arm32_gregset_t arm32_regs; ++ aarch64_gregset_t aarch64_regs; ++ } cpu_regs[MRDUMP_CPU_MAX]; ++}; ++ ++struct mrdump_machdesc { ++ uint32_t crc; ++ ++ uint32_t output_device; ++ ++ uint32_t nr_cpus; ++ ++ uint64_t page_offset; ++ uint64_t high_memory; ++ ++ uint64_t vmalloc_start; ++ uint64_t vmalloc_end; ++ ++ uint64_t modules_start; ++ uint64_t modules_end; ++ ++ uint64_t phys_offset; ++ uint64_t master_page_table; ++ ++ uint32_t output_fstype; ++ uint32_t output_lbaooo; ++}; ++ ++struct mrdump_control_block { ++ char sig[8]; ++ ++ struct mrdump_machdesc machdesc; ++ struct mrdump_crash_record crash_record; ++}; ++ ++/* NOTE!! any change to this struct should be compatible in aed */ ++struct mrdump_mini_reg_desc { ++ unsigned long reg; /* register value */ ++ unsigned long kstart; /* start kernel addr of memory dump */ ++ unsigned long kend; /* end kernel addr of memory dump */ ++ unsigned long pos; /* next pos to dump */ ++ int valid; /* 1: valid regiser, 0: invalid regiser */ ++ int pad; /* reserved */ ++ loff_t offset; /* offset in buffer */ ++}; ++ ++/* it should always be smaller than MRDUMP_MINI_HEADER_SIZE */ ++struct mrdump_mini_header { ++ struct mrdump_mini_reg_desc reg_desc[ELF_NGREG]; ++}; ++ ++#define MRDUMP_MINI_NR_SECTION 60 ++#define MRDUMP_MINI_SECTION_SIZE (32 * 1024) ++#define NT_IPANIC_MISC 4095 ++#define MRDUMP_MINI_NR_MISC 20 ++ ++struct mrdump_mini_elf_misc { ++ unsigned long vaddr; ++ unsigned long paddr; ++ unsigned long start; ++ unsigned long size; ++}; ++ ++#define NOTE_NAME_SHORT 12 ++#define NOTE_NAME_LONG 20 ++ ++struct mrdump_mini_elf_psinfo { ++ struct elf_note note; ++ char name[NOTE_NAME_SHORT]; ++ struct elf_prpsinfo data; ++}; ++ ++struct mrdump_mini_elf_prstatus { ++ struct elf_note note; ++ char name[NOTE_NAME_SHORT]; ++ struct elf_prstatus data; ++}; ++ ++struct mrdump_mini_elf_note { ++ struct elf_note note; ++ char name[NOTE_NAME_LONG]; ++ struct mrdump_mini_elf_misc data; ++}; ++ ++struct mrdump_mini_elf_header { ++ struct elfhdr ehdr; ++ struct elf_phdr phdrs[MRDUMP_MINI_NR_SECTION]; ++ struct mrdump_mini_elf_psinfo psinfo; ++ struct mrdump_mini_elf_prstatus prstatus[NR_CPUS + 1]; ++ struct mrdump_mini_elf_note misc[MRDUMP_MINI_NR_MISC]; ++}; ++ ++typedef struct mrdump_rsvmem_block { ++ phys_addr_t start_addr; ++ phys_addr_t size; ++} mrdump_rsvmem_block_t; ++ ++ ++#define MRDUMP_MINI_HEADER_SIZE ALIGN(sizeof(struct mrdump_mini_elf_header), PAGE_SIZE) ++#define MRDUMP_MINI_DATA_SIZE (MRDUMP_MINI_NR_SECTION * MRDUMP_MINI_SECTION_SIZE) ++#define MRDUMP_MINI_BUF_SIZE (MRDUMP_MINI_HEADER_SIZE + MRDUMP_MINI_DATA_SIZE) ++ ++#ifdef CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR ++#define MRDUMP_MINI_BUF_PADDR (CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR + 0xf0000) ++#else ++#define MRDUMP_MINI_BUF_PADDR 0 ++#endif ++ ++int mrdump_init(void); ++void __mrdump_create_oops_dump(AEE_REBOOT_MODE reboot_mode, struct pt_regs *regs, const char *msg, ++ ...); ++#if defined(CONFIG_MTK_AEE_IPANIC) ++void mrdump_rsvmem(void); ++#else ++static inline void mrdump_rsvmem(void) ++{ ++} ++#endif ++ ++#if defined(CONFIG_MTK_AEE_MRDUMP) ++void aee_kdump_reboot(AEE_REBOOT_MODE, const char *msg, ...); ++#else ++static inline void aee_kdump_reboot(AEE_REBOOT_MODE reboot_mode, const char *msg, ...) ++{ ++} ++#endif ++ ++typedef int (*mrdump_write)(void *buf, int off, int len, int encrypt); ++#if defined(CONFIG_MTK_AEE_IPANIC) ++int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, ++ loff_t sd_offset, const char *msg, va_list ap); ++void mrdump_mini_reserve_memory(void); ++#else ++static inline int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, ++ loff_t sd_offset, const char *msg, va_list ap) ++{ ++ return 0; ++} ++ ++static inline void mrdump_mini_reserve_memory(void) ++{ ++} ++#endif ++ ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h +new file mode 100644 +index 000000000000..1b60f007d0fd +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h +@@ -0,0 +1,295 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++ ++#ifndef _MT8167_THERMAL_H ++#define _MT8167_THERMAL_H ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "sync_write.h" ++ ++extern void __iomem *thermal_base; ++extern void __iomem *auxadc_ts_base; ++extern void __iomem *apmixed_base; ++extern void __iomem *pericfg_base; ++extern int auxadc_ts_phy_base; ++extern int apmixed_phy_base; ++ ++#define THERM_CTRL_BASE_2 thermal_base ++#define AUXADC_BASE_2 auxadc_ts_base ++#define PERICFG_BASE pericfg_base ++#define APMIXED_BASE_2 apmixed_base ++ ++#define MT6752_EVB_BUILD_PASS /*Jerry fix build error FIX_ME*/ ++ ++/******************************************************************************* ++* AUXADC Register Definition ++******************************************************************************/ ++/*AUXADC_BASE: 0xF1001000 from Vincent Liang 2014.5.8*/ ++ ++#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /*yes, 0x11003000*/ ++#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) ++#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) ++#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) ++#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) ++/*#define AUXADC_CON3_V (AUXADC_BASE_2 + 0x014)*/ ++#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) ++#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) ++#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) ++#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) ++#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) ++#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) ++#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) ++#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) ++#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) ++#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) ++#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) ++#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) ++#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) ++ ++#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) ++#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) ++#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) ++#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) ++#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) ++/*#define AUXADC_CON3_P (auxadc_ts_phy_base + 0x014)*/ ++#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) ++#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) ++#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) ++#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) ++#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) ++#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) ++#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) ++#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) ++#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) ++#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) ++#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) ++#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) ++ ++#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) ++ ++/******************************************************************************* ++* Peripheral Configuration Register Definition ++******************************************************************************/ ++/*#define PERICFG_BASE (0x10002000)*/ ++#define PERI_GLOBALCON_RST0 (pericfg_base + 0x000) /*yes, 0x10002000*/ ++/******************************************************************************* ++ * APMixedSys Configuration Register Definition ++ ******************************************************************************/ ++#define TS_CON0 (APMIXED_BASE_2 + 0x600) /*yes 0x10209000*/ ++#define TS_CON1 (APMIXED_BASE_2 + 0x604) ++#define TS_CON0_TM (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ ++#define TS_CON1_TM (APMIXED_BASE_2 + 0x604) ++#define TS_CON0_P (apmixed_phy_base + 0x600) ++#define TS_CON1_P (apmixed_phy_base + 0x604) ++ ++/******************************************************************************* ++ * Thermal Controller Register Definition ++ ******************************************************************************/ ++#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /*yes 0x1100B000*/ ++#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) ++#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) ++#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) ++#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) ++#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) ++#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) ++#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) ++#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) ++#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) ++#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) ++#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) ++#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) ++#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) ++#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) ++#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) ++#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) ++#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) ++#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) ++#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) ++#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) ++ ++#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) ++#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) ++#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) ++#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) ++#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) ++#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) ++#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) ++#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) ++#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) ++#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) ++#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) ++#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) ++#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) ++#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) ++#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) ++#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) ++#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) ++#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) ++#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) ++ ++#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) ++#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) ++#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) ++#define TEMPIMMD3 (THERM_CTRL_BASE_2 + 0x0BC) ++ ++ ++#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) ++#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) ++#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) ++#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) ++ ++#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) ++#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) ++#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) ++#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) ++ ++#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) ++#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) ++#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) ++#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) ++#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) ++#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) ++#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) ++#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /*Only for DE debug*/ ++#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) ++#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) ++#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) ++#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) ++#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) ++ ++ ++#define PTPSPARE0_P (thermal_phy_base + 0x420) ++#define PTPSPARE1_P (thermal_phy_base + 0x424) ++#define PTPSPARE2_P (thermal_phy_base + 0x428) ++#define PTPSPARE3_P (thermal_phy_base + 0x42C) ++ ++/******************************************************************************* ++ * Thermal Controller Register Mask Definition ++ ******************************************************************************/ ++#define THERMAL_ENABLE_SEN0 0x1 ++#define THERMAL_ENABLE_SEN1 0x2 ++#define THERMAL_ENABLE_SEN2 0x4 ++#define THERMAL_MONCTL0_MASK 0x00000007 ++ ++#define THERMAL_PUNT_MASK 0x00000FFF ++#define THERMAL_FSINTVL_MASK 0x03FF0000 ++#define THERMAL_SPINTVL_MASK 0x000003FF ++#define THERMAL_MON_INT_MASK 0x0007FFFF ++ ++#define THERMAL_MON_CINTSTS0 0x000001 ++#define THERMAL_MON_HINTSTS0 0x000002 ++#define THERMAL_MON_LOINTSTS0 0x000004 ++#define THERMAL_MON_HOINTSTS0 0x000008 ++#define THERMAL_MON_NHINTSTS0 0x000010 ++#define THERMAL_MON_CINTSTS1 0x000020 ++#define THERMAL_MON_HINTSTS1 0x000040 ++#define THERMAL_MON_LOINTSTS1 0x000080 ++#define THERMAL_MON_HOINTSTS1 0x000100 ++#define THERMAL_MON_NHINTSTS1 0x000200 ++#define THERMAL_MON_CINTSTS2 0x000400 ++#define THERMAL_MON_HINTSTS2 0x000800 ++#define THERMAL_MON_LOINTSTS2 0x001000 ++#define THERMAL_MON_HOINTSTS2 0x002000 ++#define THERMAL_MON_NHINTSTS2 0x004000 ++#define THERMAL_MON_TOINTSTS 0x008000 ++#define THERMAL_MON_IMMDINTSTS0 0x010000 ++#define THERMAL_MON_IMMDINTSTS1 0x020000 ++#define THERMAL_MON_IMMDINTSTS2 0x040000 ++#define THERMAL_MON_FILTINTSTS0 0x080000 ++#define THERMAL_MON_FILTINTSTS1 0x100000 ++#define THERMAL_MON_FILTINTSTS2 0x200000 ++ ++ ++#define THERMAL_tri_SPM_State0 0x20000000 ++#define THERMAL_tri_SPM_State1 0x40000000 ++#define THERMAL_tri_SPM_State2 0x80000000 ++ ++ ++#define THERMAL_MSRCTL0_MASK 0x00000007 ++#define THERMAL_MSRCTL1_MASK 0x00000038 ++#define THERMAL_MSRCTL2_MASK 0x000001C0 ++ ++enum thermal_sensor_name { ++ THERMAL_SENSOR1 = 0,/*TS_MCU1*/ ++ THERMAL_SENSOR_NUM ++}; ++ ++enum thermal_bank_name { ++ THERMAL_BANK0 = 0, /*CPU (TS_MCU1) (TS1)*/ ++ THERMAL_BANK_NUM ++}; ++ ++struct TS_SVS { ++ unsigned int ts_MTS; ++ unsigned int ts_BTS; ++}; ++ ++struct mtk_gpu_power_info { ++ unsigned int gpufreq_khz; ++ unsigned int gpufreq_power; ++}; ++ ++/* svs driver need this function */ ++extern void get_thermal_slope_intercept(struct TS_SVS *ts_info, enum thermal_bank_name ts_bank); ++ ++/* mtk_thermal_platform.c need this */ ++extern void set_taklking_flag(bool flag); ++ ++#define THERMAL_WRAP_WR32(val, addr) mt_reg_sync_writel((val), ((void *)addr)) ++ ++enum MTK_THERMAL_SENSOR_CPU_ID_MET { ++ MTK_THERMAL_SENSOR_TS1 = 0, ++ MTK_THERMAL_SENSOR_TS2, ++ MTK_THERMAL_SENSOR_TS3, ++ MTK_THERMAL_SENSOR_TS4, ++ MTK_THERMAL_SENSOR_TSABB, ++ ++ ATM_CPU_LIMIT, ++ ATM_GPU_LIMIT, ++ ++ MTK_THERMAL_SENSOR_CPU_COUNT ++}; ++ ++extern int tscpu_get_cpu_temp_met(enum MTK_THERMAL_SENSOR_CPU_ID_MET id); ++extern int mtk_gpufreq_register(struct mtk_gpu_power_info *freqs, int num); ++ ++typedef void (*met_thermalsampler_funcMET)(void); ++void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); ++ ++void tscpu_start_thermal(void); ++void tscpu_stop_thermal(void); ++void tscpu_cancel_thermal_timer(void); ++void tscpu_start_thermal_timer(void); ++int mtkts_bts_get_hw_temp(void); ++ ++extern int get_immediate_ts1_wrap(void); ++extern int get_immediate_ts2_wrap(void); ++extern int get_immediate_ts3_wrap(void); ++ ++extern int is_cpu_power_unlimit(void); /* in mtk_ts_cpu.c */ ++extern int is_cpu_power_min(void); /* in mtk_ts_cpu.c */ ++extern int get_cpu_target_tj(void); ++extern int get_cpu_target_offset(void); ++ ++extern int mtktscpu_debug_log; ++ ++#endif ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h +new file mode 100644 +index 000000000000..142a007805b9 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (C) 2011 MediaTek, Inc. ++ * ++ * Author: Holmes Chiou ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef __MT_FREQHOPPING_H__ ++#define __MT_FREQHOPPING_H__ ++ ++#define MT_FHPLL_MAX 6 ++#define MT_SSC_NR_PREDEFINE_SETTING 10 /* TODO: is 10 a good number ? */ ++ ++#define MEMPLL_SSC 0 ++#define MAINPLL_SSC 1 ++ ++#define FHTAG "[FH]" ++ ++#define VERBOSE_DEBUG 0 ++ ++#if VERBOSE_DEBUG ++#define FH_MSG(fmt, args...) \ ++ pr_debug(FHTAG""fmt" <- %s(): L<%d> PID<%s><%d>\n", ##args, __func__, __LINE__, current->comm, current->pid) ++#else ++ ++#if 1 /* log level is 6 xlog */ ++#define FH_MSG(fmt, args...) pr_debug(fmt, ##args) ++#else /* log level is 4 (printk) */ ++#define FH_MSG(fmt, args...) printk(FHTAG""fmt"\n", ##args) ++#endif ++ ++#endif ++ ++/* not support at mt2701 yet */ ++/* DRAMC */ ++#define FULLY_VERSION_FHCTL 0 ++ ++enum FH_FH_STATUS { ++ FH_FH_DISABLE = 0, ++ FH_FH_ENABLE_SSC, ++ FH_FH_ENABLE_DFH, ++ FH_FH_ENABLE_DVFS, ++}; ++ ++enum FH_PLL_STATUS { ++ FH_PLL_DISABLE = 0, ++ FH_PLL_ENABLE = 1 ++}; ++ ++/* TODO: FREQ_MODIFIED should not be here */ ++/* FH_PLL_STATUS_FREQ_MODIFIED = 3 */ ++ ++ ++enum FH_CMD { ++ FH_CMD_ENABLE = 1, ++ FH_CMD_DISABLE, ++ FH_CMD_ENABLE_USR_DEFINED, ++ FH_CMD_DISABLE_USR_DEFINED, ++ FH_CMD_INTERNAL_MAX_CMD, ++/* TODO: do we need these cmds ? ++ * FH_CMD_PLL_ENABLE, ++ * FH_CMD_PLL_DISABLE, ++ * FH_CMD_EXT_ALL_FULL_RANGE_CMD, ++ * FH_CMD_EXT_ALL_HALF_RANGE_CMD, ++ * FH_CMD_EXT_DISABLE_ALL_CMD, ++ * FH_CMD_EXT_DESIGNATED_PLL_FULL_RANGE_CMD, ++ * FH_CMD_EXT_DESIGNATED_PLL_AND_SETTING_CMD ++*/ ++}; ++ ++/* ++ * enum FH_OPCODE{ ++ * FH_OPCODE_ENABLE_WITH_ID = 1, ++ * FH_OPCODE_ENABLE_WITHOUT_ID, ++ * FH_OPCODE_DISABLE, ++ * }; ++*/ ++ ++enum FH_PLL_ID { ++ MT658X_FH_MINIMUMM_PLL = 0, ++ MT658X_FH_ARM_PLL = MT658X_FH_MINIMUMM_PLL, ++ MT658X_FH_MAIN_PLL = 1, ++ MT658X_FH_MEM_PLL = 2, ++ MT658X_FH_MSDC_PLL = 3, ++ MT658X_FH_MM_PLL = 4, /* MT658X_FH_TVD_PLL = 4, */ ++ MT658X_FH_VENC_PLL = 5, /* MT658X_FH_LVDS_PLL = 5, */ ++ /* 8127 FHCTL MB */ ++ MT658X_FH_TVD_PLL = 6, /* MT658X_FH_TVD_PLL = 6, */ ++ MT658X_FH_MAXIMUMM_PLL = MT658X_FH_TVD_PLL, ++ /* 8127 FHCTL ME */ ++ MT658X_FH_PLL_TOTAL_NUM ++}; ++ ++/* keep track the status of each PLL */ ++/* TODO: do we need another "uint mode" for Dynamic FH */ ++typedef struct { ++ unsigned int fh_status; ++ unsigned int pll_status; ++ unsigned int setting_id; ++ unsigned int curr_freq; ++ unsigned int user_defined; ++} fh_pll_t; ++ ++ ++/* Record the owner of enable freq hopping <==TBD */ ++struct freqhopping_pll { ++ union { ++ int mt_pll[MT_FHPLL_MAX]; ++ struct { ++ int mt_arm_fhpll; ++ int mt_main_fhpll; ++ int mt_mem_fhpll; ++ int mt_msdc_fhpll; ++ int mt_mm_fhpll; ++ int mt_venc_fhpll; ++ }; ++ }; ++}; ++ ++struct freqhopping_ssc { ++ unsigned int freq; ++ unsigned int dt; ++ unsigned int df; ++ unsigned int upbnd; ++ unsigned int lowbnd; ++ unsigned int dds; ++}; ++ ++struct freqhopping_ioctl { ++ unsigned int pll_id; ++ struct freqhopping_ssc ssc_setting; /* used only when user-define */ ++ int result; ++}; ++ ++int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable); ++void mt_freqhopping_init(void); ++void mt_freqhopping_pll_init(void); ++int mt_h2l_mempll(void); ++int mt_l2h_mempll(void); ++int mt_h2l_dvfs_mempll(void); ++int mt_l2h_dvfs_mempll(void); ++int mt_dfs_armpll(unsigned int current_freq, unsigned int target_freq); ++int mt_is_support_DFS_mode(void); ++void mt_fh_popod_save(void); ++void mt_fh_popod_restore(void); ++int mt_fh_dram_overclock(int clk); ++int mt_fh_get_dramc(void); ++unsigned int mt_get_emi_freq(void); ++ ++#endif /* !__MT_FREQHOPPING_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h +new file mode 100644 +index 000000000000..0c049db9aa97 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++ ++#define STA_POWER_DOWN 0 ++#define STA_POWER_ON 1 ++ ++/* ++ * 1. for CPU MTCMOS: CPU0, CPU1, CPU2, CPU3, DBG0, CPU4, CPU5, CPU6, CPU7, DBG1, CPUSYS1 ++ * 2. call spm_mtcmos_cpu_lock/unlock() before/after any operations ++ */ ++extern int spm_mtcmos_cpu_init(void); ++extern void spm_mtcmos_cpu_lock(unsigned long *flags); ++extern void spm_mtcmos_cpu_unlock(unsigned long *flags); ++extern int spm_mtcmos_ctrl_cpu(unsigned int cpu, int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu0(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu1(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu2(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu3(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu4(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu5(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu6(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpu7(int state, int chkWfiBeforePdn); ++extern int spm_mtcmos_ctrl_cpusys0(int state, int chkWfiBeforePdn); ++extern bool spm_cpusys0_can_power_down(void); +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h +new file mode 100644 +index 000000000000..28176b3cd9af +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_BOOT_SHARE_PAGE_H__ ++#define __MTK_BOOT_SHARE_PAGE_H__ ++ ++#define BOOT_SHARE_BASE (0xC0002000) /* address in linux kernel */ ++#define BOOT_SHARE_SIZE (0x1000) /* page size 4K bytes */ ++ ++#define BOOT_SHARE_MAGIC (0x4545544D) /* MTEE */ ++ ++/* Memory map & defines for boot share page */ ++/* ++ * Note: ++ * 1. BOOT_SHARE_XXXXX_OFST is the address offset related to BOOT_SHARE_BASE ++ */ ++#define BOOT_SHARE_MAGIC1_OFST (0) ++#define BOOT_SHARE_MAGIC1_SIZE (4) ++ ++#define BOOT_SHARE_DEV_INFO_OFST (BOOT_SHARE_MAGIC1_OFST+BOOT_SHARE_MAGIC1_SIZE) ++#define BOOT_SHARE_DEV_INFO_SIZE (16) ++ ++#define BOOT_SHARE_HOTPLUG_OFST (1008) /* 16 bytes for hotplug/jump-reg */ ++#define BOOT_SHARE_HOTPLUG_SIZE (32) ++ ++#define BOOT_SHARE_MAGIC2_OFST (4092) ++#define BOOT_SHARE_MAGIC2_SIZE (4) ++ ++#endif /* __MTK_BOOT_SHARE_PAGE_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h +new file mode 100644 +index 000000000000..eefdaad4aaa5 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h +@@ -0,0 +1,301 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. ++ */ ++ ++#ifndef _MT8127_THERMAL_H ++#define _MT8127_THERMAL_H ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mt-plat/sync_write.h" ++#include ++ ++/* #include */ ++/* #include "../../../../../thermal/mt8127/inc/mt_gpufreq.h" */ ++ ++#if 1 ++extern void __iomem *thermal_base; ++extern void __iomem *auxadc_ts_base; ++extern void __iomem *pericfg_base; ++extern void __iomem *apmixed_ts_base; ++ ++extern int mtktscpu_limited_dmips; ++ ++void __attribute__ ((weak)) mt_gpufreq_thermal_protect(unsigned int limited_power) { ++} ++ ++unsigned int __attribute__ ((weak)) mt_gpufreq_get_cur_freq(void) { ++ return 0; ++} ++ ++u32 __attribute__ ((weak)) get_devinfo_with_index(u32 index) { ++ return 0; ++} ++ ++extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); ++extern int IMM_IsAdcInitReady(void); ++extern int PMIC_IMM_GetOneChannelValue(int dwChannel, int deCount, int trimd); ++extern int thermal_phy_base; ++extern int auxadc_ts_phy_base; ++extern int apmixed_phy_base; ++extern int pericfg_phy_base; ++ ++/* extern int last_abb_t; */ ++/* extern int last_CPU2_t; */ ++extern int get_immediate_temp2_wrap(void); ++extern void mtkts_dump_cali_info(void); ++extern u32 get_devinfo_with_index(u32 index); ++extern int bts_cur_temp; ++ ++#define THERM_CTRL_BASE_2 thermal_base ++#define AUXADC_BASE_2 auxadc_ts_base ++#define PERICFG_BASE_2 pericfg_base ++#define APMIXED_BASE_2 apmixed_ts_base ++#endif ++ ++/******************************************************************************* ++ * AUXADC Register Definition ++ ******************************************************************************/ ++#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /* yes, 0x11001000 */ ++#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) ++#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) ++#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) ++#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) ++#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) ++#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) ++#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) ++#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) ++#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) ++#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) ++#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) ++#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) ++#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) ++#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) ++#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) ++#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) ++#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) ++#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) ++#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) ++#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) ++#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) ++#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) ++#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) ++#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) ++#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) ++#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) ++#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) ++#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) ++#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) ++#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) ++#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) ++#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) ++#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) ++#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) ++#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) ++ ++/******************************************************************************* ++ * Peripheral Configuration Register Definition ++ ******************************************************************************/ ++#define PERI_GLOBALCON_RST0 (PERICFG_BASE_2 + 0x000) /* yes, 0x10003000 */ ++ ++/******************************************************************************* ++ * APMixedSys Configuration Register Definition ++ ******************************************************************************/ ++#define TS_CON0 (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ ++#define TS_CON1 (APMIXED_BASE_2 + 0x604) ++/******************************************************************************* ++ * Thermal Controller Register Definition ++ ******************************************************************************/ ++#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /* yes 0x1100B000 */ ++#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) ++#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) ++#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) ++#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) ++#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) ++#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) ++#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) ++#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) ++#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) ++#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) ++#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) ++#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) ++#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) ++#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) ++#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) ++#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) ++#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) ++#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) ++#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) ++#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) ++ ++#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) ++#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) ++#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) ++#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) ++#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) ++#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) ++#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) ++#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) ++#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) ++#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) ++#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) ++#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) ++#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) ++#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) ++#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) ++#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) ++#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) ++#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) ++#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) ++ ++#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) ++#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) ++#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) ++ ++#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) ++#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) ++#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) ++#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) ++ ++#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) ++#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) ++#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) ++#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) ++ ++#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) ++#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) ++#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) ++#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) ++#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) ++#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) ++#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) ++#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /* Only for DE debug */ ++#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) ++#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) ++#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) ++#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) ++#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) ++ ++/******************************************************************************* ++ * Thermal Controller Register Mask Definition ++ ******************************************************************************/ ++#define THERMAL_ENABLE_SEN0 0x1 ++#define THERMAL_ENABLE_SEN1 0x2 ++#define THERMAL_ENABLE_SEN2 0x4 ++#define THERMAL_MONCTL0_MASK 0x00000007 ++ ++#define THERMAL_PUNT_MASK 0x00000FFF ++#define THERMAL_FSINTVL_MASK 0x03FF0000 ++#define THERMAL_SPINTVL_MASK 0x000003FF ++#define THERMAL_MON_INT_MASK 0x0007FFFF ++ ++#define THERMAL_MON_CINTSTS0 0x000001 ++#define THERMAL_MON_HINTSTS0 0x000002 ++#define THERMAL_MON_LOINTSTS0 0x000004 ++#define THERMAL_MON_HOINTSTS0 0x000008 ++#define THERMAL_MON_NHINTSTS0 0x000010 ++#define THERMAL_MON_CINTSTS1 0x000020 ++#define THERMAL_MON_HINTSTS1 0x000040 ++#define THERMAL_MON_LOINTSTS1 0x000080 ++#define THERMAL_MON_HOINTSTS1 0x000100 ++#define THERMAL_MON_NHINTSTS1 0x000200 ++#define THERMAL_MON_CINTSTS2 0x000400 ++#define THERMAL_MON_HINTSTS2 0x000800 ++#define THERMAL_MON_LOINTSTS2 0x001000 ++#define THERMAL_MON_HOINTSTS2 0x002000 ++#define THERMAL_MON_NHINTSTS2 0x004000 ++#define THERMAL_MON_TOINTSTS 0x008000 ++#define THERMAL_MON_IMMDINTSTS0 0x010000 ++#define THERMAL_MON_IMMDINTSTS1 0x020000 ++#define THERMAL_MON_IMMDINTSTS2 0x040000 ++#define THERMAL_MON_FILTINTSTS0 0x080000 ++#define THERMAL_MON_FILTINTSTS1 0x100000 ++#define THERMAL_MON_FILTINTSTS2 0x200000 ++ ++ ++#define THERMAL_tri_SPM_State0 0x20000000 ++#define THERMAL_tri_SPM_State1 0x40000000 ++#define THERMAL_tri_SPM_State2 0x80000000 ++ ++ ++#define THERMAL_MSRCTL0_MASK 0x00000007 ++#define THERMAL_MSRCTL1_MASK 0x00000038 ++#define THERMAL_MSRCTL2_MASK 0x000001C0 ++ ++/* extern int thermal_one_shot_handler(int times); */ ++ ++typedef enum { ++ THERMAL_SENSOR1 = 0, /* TS1 */ ++ THERMAL_SENSOR_NUM ++} thermal_sensor_name; ++ ++struct TS_PTPOD { ++ unsigned int ts_MTS; ++ unsigned int ts_BTS; ++}; ++ ++extern void get_thermal_slope_intercept(struct TS_PTPOD *ts_info); ++extern void set_taklking_flag(bool flag); ++extern int tscpu_get_cpu_temp(void); ++ ++/*5 thermal sensors*/ ++typedef enum { ++ MTK_THERMAL_SENSOR_TS1 = 0, ++ ATM_CPU_LIMIT, ++ ATM_GPU_LIMIT, ++ MTK_THERMAL_SENSOR_CPU_COUNT ++} MTK_THERMAL_SENSOR_CPU_ID_MET; ++ ++struct mtk_cpu_power_info { ++ unsigned int cpufreq_khz; ++ unsigned int cpufreq_ncpu; ++ unsigned int cpufreq_power; ++}; ++extern int mtk_cpufreq_register(struct mtk_cpu_power_info *freqs, int num); ++ ++extern int tscpu_get_cpu_temp_met(MTK_THERMAL_SENSOR_CPU_ID_MET id); ++ ++ ++typedef void (*met_thermalsampler_funcMET) (void); ++void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); ++ ++void tscpu_start_thermal(void); ++void tscpu_stop_thermal(void); ++void tscpu_cancel_thermal_timer(void); ++void tscpu_start_thermal_timer(void); ++int mtkts_AP_get_hw_temp(void); ++ ++extern int amddulthro_backoff(int level); ++/* extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); */ ++/* extern int IMM_IsAdcInitReady(void); */ ++extern int get_immediate_temp2_wrap(void); ++extern void mtkts_dump_cali_info(void); ++extern unsigned int read_dram_temperature(void); ++extern int mtk_thermal_get_cpu_load_sum(void); ++ ++/********************************** ++ * Power table struct for thermal ++ **********************************/ ++struct mt_gpufreq_power_table_info { ++ unsigned int gpufreq_khz; ++ unsigned int gpufreq_volt; ++ unsigned int gpufreq_power; ++}; ++ ++extern int mtk_gpufreq_register(struct mt_gpufreq_power_table_info *freqs, int num); ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mt_sched.h b/drivers/misc/mediatek/include/mt-plat/mt_sched.h +new file mode 100644 +index 000000000000..71206f080548 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mt_sched.h +@@ -0,0 +1,34 @@ ++/* ++* Copyright (C) 2016 MediaTek Inc. ++* ++* This program is free software; you can redistribute it and/or modify ++* it under the terms of the GNU General Public License version 2 as ++* published by the Free Software Foundation. ++* ++* This program is distributed in the hope that it will be useful, ++* but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++* See http://www.gnu.org/licenses/gpl-2.0.html for more details. ++*/ ++ ++#ifdef CONFIG_MTK_SCHED_RQAVG_US ++/* ++ * @cpu: cpu id ++ * @reset: reset the statistic start time after this time query ++ * @use_maxfreq: caculate cpu loading with max cpu max frequency ++ * return: cpu loading as percentage (0~100) ++ */ ++extern unsigned int sched_get_percpu_load(int cpu, bool reset, bool use_maxfreq); ++ ++/* ++ * return: heavy task(loading>90%) number in the system ++ */ ++extern unsigned int sched_get_nr_heavy_task(void); ++ ++/* ++ * @threshold: heavy task loading threshold (0~1023) ++ * return: heavy task(loading>threshold) number in the system ++ */ ++extern unsigned int sched_get_nr_heavy_task_by_threshold(unsigned int threshold); ++#endif /* CONFIG_MTK_SCHED_RQAVG_US */ ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_io.h b/drivers/misc/mediatek/include/mt-plat/mtk_io.h +new file mode 100644 +index 000000000000..de17db505d3e +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_io.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MT_IO_H__ ++#define __MT_IO_H__ ++ ++/* only for arm64 */ ++#ifdef CONFIG_ARM64 ++#define IOMEM(a) ((void __force __iomem *)((a))) ++#endif ++ ++#endif /* !__MT_IO_H__ */ ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h +new file mode 100644 +index 000000000000..d679c5a1ce73 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_LPAE_H__ ++#define __MTK_LPAE_H__ ++#ifdef CONFIG_MTK_LM_MODE ++ ++#include ++ ++#define INTERAL_MAPPING_OFFSET (0x40000000) ++#define INTERAL_MAPPING_LIMIT (INTERAL_MAPPING_OFFSET + 0x80000000) ++ ++#define MT_OVERFLOW_ADDR_START 0x100000000ULL ++ ++unsigned int __attribute__((weak)) enable_4G(void) ++{ ++ return 0; ++} ++ ++/* For HW modules which support 33-bit address setting */ ++#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) \ ++ do { \ ++ ret = 0; \ ++ if (enable_4G()) {\ ++ if (((phys_addr_t)phy_addr < MT_OVERFLOW_ADDR_START)\ ++ && (((phys_addr_t)phy_addr + size) >= MT_OVERFLOW_ADDR_START)) \ ++ ret = MT_OVERFLOW_ADDR_START - phy_addr; \ ++ } \ ++ } while (0) \ ++ ++/* For SPM and MD32 only in ROME */ ++#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) \ ++ do { \ ++ if (enable_4G()) {\ ++ if (phy_addr >= INTERAL_MAPPING_OFFSET && phy_addr < INTERAL_MAPPING_LIMIT) \ ++ phy_addr += INTERAL_MAPPING_OFFSET; \ ++ } \ ++ } while (0)\ ++ ++#else /* !CONFIG_ARM_LPAE */ ++ ++#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) ++#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) ++#define MT_OVERFLOW_ADDR_START 0 ++ ++static inline unsigned int enable_4G(void) ++{ ++ return 0; ++} ++ ++#endif ++#endif /*!__MTK_LPAE_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h +new file mode 100644 +index 000000000000..7baafc4329bf +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_MDM_MONITOR_H ++#define _MTK_MDM_MONITOR_H ++ ++struct md_info { ++ char *attribute; ++ int value; ++ char *unit; ++ int invalid_value; ++ int index; ++}; ++ ++extern ++int mtk_mdm_get_md_info(struct md_info **p_inf, int *size); ++ ++extern ++int mtk_mdm_start_query(void); ++ ++extern ++int mtk_mdm_stop_query(void); ++ ++extern ++int mtk_mdm_set_signal_period(int second); ++ ++extern ++int mtk_mdm_set_md1_signal_period(int second); ++ ++extern ++int mtk_mdm_set_md2_signal_period(int second); ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h +new file mode 100644 +index 000000000000..8f20f38b75d6 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2016 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_PLATFORM_DEBUG_H__ ++#define __MTK_PLATFORM_DEBUG_H__ ++ ++#ifdef CONFIG_MTK_PLAT_SRAM_FLAG ++/* plat_sram_flag */ ++extern int set_sram_flag_lastpc_valid(void); ++extern int set_sram_flag_dfd_valid(void); ++extern int set_sram_flag_etb_user(unsigned int etb_id, unsigned int user_id); ++#endif ++ ++#ifdef CONFIG_MTK_DFD_INTERNAL_DUMP ++extern int dfd_setup(void); ++#endif ++ ++#endif /* __MTK_PLATFORM_DEBUG_H__ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h +new file mode 100644 +index 000000000000..3a94a1bbcd24 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MTK_RAM_CONSOLE_H__ ++#define __MTK_RAM_CONSOLE_H__ ++ ++#include ++#include ++ ++typedef enum { ++ AEE_FIQ_STEP_FIQ_ISR_BASE = 1, ++ AEE_FIQ_STEP_WDT_FIQ_INFO = 4, ++ AEE_FIQ_STEP_WDT_FIQ_STACK, ++ AEE_FIQ_STEP_WDT_FIQ_LOOP, ++ AEE_FIQ_STEP_WDT_FIQ_DONE, ++ AEE_FIQ_STEP_WDT_IRQ_INFO = 8, ++ AEE_FIQ_STEP_WDT_IRQ_KICK, ++ AEE_FIQ_STEP_WDT_IRQ_SMP_STOP, ++ AEE_FIQ_STEP_WDT_IRQ_TIME, ++ AEE_FIQ_STEP_WDT_IRQ_STACK, ++ AEE_FIQ_STEP_WDT_IRQ_GIC, ++ AEE_FIQ_STEP_WDT_IRQ_LOCALTIMER, ++ AEE_FIQ_STEP_WDT_IRQ_IDLE, ++ AEE_FIQ_STEP_WDT_IRQ_SCHED, ++ AEE_FIQ_STEP_WDT_IRQ_DONE, ++ AEE_FIQ_STEP_KE_WDT_INFO = 20, ++ AEE_FIQ_STEP_KE_WDT_PERCPU, ++ AEE_FIQ_STEP_KE_WDT_LOG, ++ AEE_FIQ_STEP_KE_SCHED_DEBUG, ++ AEE_FIQ_STEP_KE_EINT_DEBUG, ++ AEE_FIQ_STEP_KE_WDT_DONE, ++ AEE_FIQ_STEP_KE_IPANIC_DIE = 32, ++ AEE_FIQ_STEP_KE_IPANIC_START, ++ AEE_FIQ_STEP_KE_IPANIC_OOP_HEADER, ++ AEE_FIQ_STEP_KE_IPANIC_DETAIL, ++ AEE_FIQ_STEP_KE_IPANIC_CONSOLE, ++ AEE_FIQ_STEP_KE_IPANIC_USERSPACE, ++ AEE_FIQ_STEP_KE_IPANIC_ANDROID, ++ AEE_FIQ_STEP_KE_IPANIC_MMPROFILE, ++ AEE_FIQ_STEP_KE_IPANIC_HEADER, ++ AEE_FIQ_STEP_KE_IPANIC_DONE, ++ AEE_FIQ_STEP_KE_NESTED_PANIC = 64, ++} AEE_FIQ_STEP_NUM; ++ ++#ifdef CONFIG_MTK_RAM_CONSOLE ++extern int aee_rr_curr_fiq_step(void); ++extern void aee_rr_rec_fiq_step(u8 i); ++extern void aee_rr_rec_reboot_mode(u8 mode); ++extern void aee_rr_rec_kdump_params(void *params); ++extern void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j); ++extern void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j); ++extern void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm); ++extern void aee_sram_fiq_log(const char *msg); ++extern void ram_console_write(struct console *console, const char *s, unsigned int count); ++extern void aee_sram_fiq_save_bin(const char *buffer, size_t len); ++extern void aee_rr_rec_hotplug_footprint(int cpu, u8 fp); ++extern void aee_rr_rec_hotplug_cpu_event(u8 val); ++extern void aee_rr_rec_hotplug_cb_index(u8 val); ++extern void aee_rr_rec_hotplug_cb_fp(unsigned long val); ++#ifdef CONFIG_MTK_EMMC_SUPPORT ++extern void last_kmsg_store_to_emmc(void); ++#endif ++ ++#else ++static inline void aee_rr_rec_hotplug_footprint(int cpu, u8 fp) ++{ ++} ++static inline void aee_rr_rec_hotplug_cpu_event(u8 val) ++{ ++} ++static inline void aee_rr_rec_hotplug_cb_index(u8 val) ++{ ++} ++static inline void aee_rr_rec_hotplug_cb_fp(unsigned long val) ++{ ++} ++static inline int aee_rr_curr_fiq_step(void) ++{ ++ return 0; ++} ++ ++static inline void aee_rr_rec_fiq_step(u8 i) ++{ ++} ++ ++static inline unsigned int aee_rr_curr_exp_type(void) ++{ ++ return 0; ++} ++ ++static inline void aee_rr_rec_exp_type(unsigned int type) ++{ ++} ++ ++static inline void aee_rr_rec_reboot_mode(u8 mode) ++{ ++} ++ ++static inline void aee_rr_rec_kdump_params(void *params) ++{ ++} ++ ++static inline void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j) ++{ ++} ++ ++static inline void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j) ++{ ++} ++ ++static inline void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm) ++{ ++} ++ ++static inline void aee_sram_fiq_log(const char *msg) ++{ ++} ++ ++static inline void ram_console_write(struct console *console, const char *s, unsigned int count) ++{ ++} ++ ++static inline void aee_sram_fiq_save_bin(unsigned char *buffer, size_t len) ++{ ++} ++ ++#ifdef CONFIG_MTK_EMMC_SUPPORT ++static inline void last_kmsg_store_to_emmc(void) ++{ ++} ++#endif ++ ++#endif /* CONFIG_MTK_RAM_CONSOLE */ ++ ++#ifdef CONFIG_MTK_AEE_IPANIC ++extern int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size); ++extern int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, ++ char **buf, struct pstore_info *psi); ++#else ++static inline int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size) ++{ ++ return 0; ++} ++ ++static inline int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, ++ char **buf, struct pstore_info *psi) ++{ ++ return 0; ++} ++#endif /* CONFIG_MTK_AEE_IPANIC */ ++ ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h +new file mode 100644 +index 000000000000..2181e9989593 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h +@@ -0,0 +1,85 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef MTK_RTC_H ++#define MTK_RTC_H ++ ++#include ++#include ++#include ++ ++typedef enum { ++ RTC_GPIO_USER_WIFI = 8, ++ RTC_GPIO_USER_GPS = 9, ++ RTC_GPIO_USER_BT = 10, ++ RTC_GPIO_USER_FM = 11, ++ RTC_GPIO_USER_PMIC = 12, ++} rtc_gpio_user_t; ++ ++#ifdef CONFIG_MTK_RTC ++ ++/* ++ * NOTE: ++ * 1. RTC_GPIO always exports 32K enabled by some user even if the phone is powered off ++ */ ++ ++extern unsigned long rtc_read_hw_time(void); ++extern void rtc_gpio_enable_32k(rtc_gpio_user_t user); ++extern void rtc_gpio_disable_32k(rtc_gpio_user_t user); ++extern bool rtc_gpio_32k_status(void); ++ ++/* for AUDIOPLL (deprecated) */ ++extern void rtc_enable_abb_32k(void); ++extern void rtc_disable_abb_32k(void); ++ ++/* NOTE: used in Sleep driver to workaround Vrtc-Vore level shifter issue */ ++extern void rtc_enable_writeif(void); ++extern void rtc_disable_writeif(void); ++ ++extern void rtc_mark_recovery(void); ++#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) ++extern void rtc_mark_kpoc(void); ++#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ ++extern void rtc_mark_fast(void); ++extern u16 rtc_rdwr_uart_bits(u16 *val); ++extern void rtc_bbpu_power_down(void); ++extern void rtc_read_pwron_alarm(struct rtc_wkalrm *alm); ++extern int get_rtc_spare_fg_value(void); ++extern int set_rtc_spare_fg_value(int val); ++extern void rtc_irq_handler(void); ++extern bool crystal_exist_status(void); ++extern void mt_power_off(void); ++#else/*ifdef CONFIG_MTK_RTC*/ ++#define rtc_read_hw_time() ({ 0; }) ++#define rtc_gpio_enable_32k(user) do {} while (0) ++#define rtc_gpio_disable_32k(user) do {} while (0) ++#define rtc_gpio_32k_status() do {} while (0) ++#define rtc_enable_abb_32k() do {} while (0) ++#define rtc_disable_abb_32k() do {} while (0) ++#define rtc_enable_writeif() do {} while (0) ++#define rtc_disable_writeif() do {} while (0) ++#define rtc_mark_recovery() do {} while (0) ++#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) ++#define rtc_mark_kpoc() do {} while (0) ++#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ ++#define rtc_mark_fast() do {} while (0) ++#define rtc_rdwr_uart_bits(val) ({ 0; }) ++#define rtc_bbpu_power_down() do {} while (0) ++#define rtc_read_pwron_alarm(alm) do {} while (0) ++#define get_rtc_spare_fg_value() ({ 0; }) ++#define set_rtc_spare_fg_value(val) ({ 0; }) ++#define rtc_irq_handler() do {} while (0) ++#define crystal_exist_status() do {} while (0) ++__weak void mt_power_off(void); ++#endif/*ifdef CONFIG_MTK_RTC*/ ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h +new file mode 100644 +index 000000000000..eac6bc713c98 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (c) 2009 Travis Geiselbrecht ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files ++ * (the "Software"), to deal in the Software without restriction, ++ * including without limitation the rights to use, copy, modify, merge, ++ * publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, ++ * subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef _MTK_THERMAL_EXT_CONTROL_H ++#define _MTK_THERMAL_EXT_CONTROL_H ++ ++#define THERMAL_MD32_IPI_MSG_BASE 0x1F00 ++#define THERMAL_AP_IPI_MSG_BASE 0x2F00 ++ ++typedef enum { ++ THERMAL_AP_IPI_MSG_SET_TZ_THRESHOLD = THERMAL_AP_IPI_MSG_BASE, ++ THERMAL_AP_IPI_MSG_MD32_START, ++ ++ THERMAL_MD32_IPI_MSG_READY = THERMAL_MD32_IPI_MSG_BASE, ++ THERMAL_MD32_IPI_MSG_MD32_START_ACK, ++ THERMAL_MD32_IPI_MSG_REACH_THRESHOLD, ++} thermal_ipi_msg_id; ++ ++typedef enum { ++/* MTK_THERMAL_EXT_SENSOR_CPU = 0, */ ++ MTK_THERMAL_EXT_SENSOR_ABB = 0, ++ MTK_THERMAL_EXT_SENSOR_PMIC, ++ MTK_THERMAL_EXT_SENSOR_BATTERY, ++ MTK_THERMAL_EXT_SENSOR_COUNT ++} MTK_THERMAL_EXT_SENSOR_ID; ++ ++typedef struct { ++ int id; /* id of this tz */ ++ int polling_delay; /* polling delay of this tz */ ++ long high_trip_point; /* high threshold of this tz */ ++ long low_trip_point; /* low threshold of this tz */ ++} thermal_zone_data; ++ ++typedef struct { ++ int id; /* id of this tz */ ++ long high_trip_point; /* high threshold of this tz */ ++ long low_trip_point; /* low threshold of this tz */ ++ long temperature; /* Current temperature gotten from TS */ ++} thermal_zone_status; ++ ++typedef struct { ++ short id; ++ union { ++ thermal_zone_data tz; ++ thermal_zone_status tz_status; ++ } data; ++} thermal_ipi_msg; ++ ++#endif /* _MTK_THERMAL_EXT_CONTROL_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h +new file mode 100644 +index 000000000000..7903b49dc419 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h +@@ -0,0 +1,102 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_THERMAL_MONITOR_H ++#define _MTK_THERMAL_MONITOR_H ++ ++#include ++ ++/* ++ * MTK_THERMAL_WRAPPER_BYPASS = 1 (use original Linux Thermal API) ++ * MTK_THERMAL_WRAPPER_BYPASS = 0 (use MTK Thermal API Monitor) ++ */ ++#define MTK_THERMAL_WRAPPER_BYPASS 0 ++ ++#if MTK_THERMAL_WRAPPER_BYPASS ++/* Original LTF API */ ++#define mtk_thermal_zone_device_register thermal_zone_device_register ++#define mtk_thermal_zone_device_unregister thermal_zone_device_unregister ++#define mtk_thermal_cooling_device_unregister thermal_cooling_device_unregister ++#define mtk_thermal_cooling_device_register thermal_cooling_device_register ++#define mtk_thermal_zone_bind_cooling_device thermal_zone_bind_cooling_device ++ ++#else ++ ++struct thermal_cooling_device_ops_extra { ++ int (*set_cur_temp)(struct thermal_cooling_device *, unsigned long); ++}; ++ ++extern ++struct thermal_zone_device *mtk_thermal_zone_device_register_wrapper ++(char *type, int trips, void *devdata, const struct thermal_zone_device_ops *ops, ++int tc1, int tc2, int passive_delay, int polling_delay); ++ ++extern ++void mtk_thermal_zone_device_unregister_wrapper(struct thermal_zone_device *tz); ++ ++extern ++struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper ++(char *type, void *devdata, const struct thermal_cooling_device_ops *ops); ++ ++extern ++struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper_extra ++(char *type, void *devdata, const struct thermal_cooling_device_ops *ops, ++const struct thermal_cooling_device_ops_extra *ops_ext); ++ ++extern ++int mtk_thermal_cooling_device_add_exit_point ++(struct thermal_cooling_device *cdev, int exit_point); ++ ++extern ++void mtk_thermal_cooling_device_unregister_wrapper(struct thermal_cooling_device *cdev); ++ ++extern int mtk_thermal_zone_bind_cooling_device_wrapper ++(struct thermal_zone_device *tz, int trip, struct thermal_cooling_device *cdev); ++ ++extern int mtk_thermal_zone_bind_trigger_trip(struct thermal_zone_device *tz, int trip, int mode); ++#define mtk_thermal_zone_device_register mtk_thermal_zone_device_register_wrapper ++#define mtk_thermal_zone_device_unregister mtk_thermal_zone_device_unregister_wrapper ++#define mtk_thermal_cooling_device_unregister mtk_thermal_cooling_device_unregister_wrapper ++#define mtk_thermal_cooling_device_register mtk_thermal_cooling_device_register_wrapper ++#define mtk_thermal_zone_bind_cooling_device mtk_thermal_zone_bind_cooling_device_wrapper ++ ++#endif ++ ++typedef enum { ++ MTK_THERMAL_SENSOR_CPU = 0, ++ MTK_THERMAL_SENSOR_ABB, ++ MTK_THERMAL_SENSOR_PMIC, ++ MTK_THERMAL_SENSOR_BATTERY, ++ MTK_THERMAL_SENSOR_MD1, ++ MTK_THERMAL_SENSOR_MD2, ++ MTK_THERMAL_SENSOR_WIFI, ++ MTK_THERMAL_SENSOR_BATTERY2, ++ MTK_THERMAL_SENSOR_BUCK, ++ MTK_THERMAL_SENSOR_AP, ++ MTK_THERMAL_SENSOR_PCB1, ++ MTK_THERMAL_SENSOR_PCB2, ++ MTK_THERMAL_SENSOR_SKIN, ++ MTK_THERMAL_SENSOR_XTAL, ++ MTK_THERMAL_SENSOR_MD_PA, ++ ++ MTK_THERMAL_SENSOR_COUNT ++} MTK_THERMAL_SENSOR_ID; ++ ++extern int mtk_thermal_get_temp(MTK_THERMAL_SENSOR_ID id); ++extern struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void); ++ ++/* This API function is implemented in mediatek/kernel/drivers/leds/leds.c */ ++extern int setMaxbrightness(int max_level, int enable); ++ ++extern void machine_power_off(void); ++#endif +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h +new file mode 100644 +index 000000000000..305574031196 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MTK_THERMAL_PLATFORM_H ++#define _MTK_THERMAL_PLATFORM_H ++ ++#include ++#include ++ ++extern ++int mtk_thermal_get_cpu_info(int *nocores, int **cpufreq, int **cpuloading); ++ ++extern ++int mtk_thermal_get_gpu_info(int *nocores, int **gpufreq, int **gpuloading); ++ ++extern ++int mtk_thermal_get_batt_info(int *batt_voltage, int *batt_current, int *batt_temp); ++ ++extern ++int mtk_thermal_get_extra_info(int *no_extra_attr, ++ char ***attr_names, int **attr_values, char ***attr_unit); ++ ++extern ++int mtk_thermal_force_get_batt_temp(void); ++ ++ ++enum { ++ MTK_THERMAL_SCEN_CALL = 0x1 ++}; ++ ++extern ++unsigned int mtk_thermal_set_user_scenarios(unsigned int mask); ++ ++extern ++unsigned int mtk_thermal_clear_user_scenarios(unsigned int mask); ++ ++ ++#if defined(CONFIG_MTK_SMART_BATTERY) ++/* global variable from battery driver... */ ++extern kal_bool gFG_Is_Charging; ++#endif ++ ++extern int force_get_tbat(void); ++#endif /* _MTK_THERMAL_PLATFORM_H */ ++ ++ ++typedef enum { ++ TA_DAEMON_CMD_GET_INIT_FLAG = 0, ++ TA_DAEMON_CMD_SET_DAEMON_PID, ++ TA_DAEMON_CMD_NOTIFY_DAEMON, ++ TA_DAEMON_CMD_NOTIFY_DAEMON_CATMINIT, ++ TA_DAEMON_CMD_SET_TTJ, ++ TA_DAEMON_CMD_GET_TPCB, ++ ++ TA_DAEMON_CMD_TO_KERNEL_NUMBER ++} TA_DAEMON_CTRL_CMD_TO_KERNEL; /*must sync userspace/kernel: TA_DAEMON_CTRL_CMD_FROM_USER*/ ++ ++#define TAD_NL_MSG_T_HDR_LEN 12 ++#define TAD_NL_MSG_MAX_LEN 2048 ++ ++struct tad_nl_msg_t { ++ unsigned int tad_cmd; ++ unsigned int tad_data_len; ++ unsigned int tad_ret_data_len; ++ char tad_data[TAD_NL_MSG_MAX_LEN]; ++}; ++ ++enum { ++ TA_CATMPLUS = 1, ++ TA_CONTINUOUS = 2, ++ TA_CATMPLUS_TTJ = 3 ++}; ++ ++ ++struct cATM_params_t { ++ int CATM_ON; ++ int K_TT; ++ int K_SUM_TT_LOW; ++ int K_SUM_TT_HIGH; ++ int MIN_SUM_TT; ++ int MAX_SUM_TT; ++ int MIN_TTJ; ++ int CATMP_STEADY_TTJ_DELTA; ++}; ++struct continuetm_params_t { ++ int STEADY_TARGET_TJ; ++ int MAX_TARGET_TJ; ++ int TRIP_TPCB; ++ int STEADY_TARGET_TPCB; ++}; ++ ++ ++struct CATM_T { ++ struct cATM_params_t t_catm_par; ++ struct continuetm_params_t t_continuetm_par; ++}; ++extern struct CATM_T thermal_atm_t; ++int wakeup_ta_algo(int flow_state); ++int ta_get_ttj(void); ++ ++extern int mtk_thermal_get_tpcb_target(void); ++extern int tsatm_thermal_get_catm_type(void); ++ ++ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h +new file mode 100644 +index 000000000000..1c23a9f4a862 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM thermal ++ ++#if !defined(_MTK_THERMAL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _MTK_THERMAL_TRACE_H ++ ++#include ++ ++TRACE_EVENT(cooling_device_state, ++ TP_PROTO(int device, unsigned long state), ++ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) ++ __field(unsigned long, state) ++ ), ++ TP_fast_assign(__entry->device = device; ++ __entry->state = state;), ++ TP_printk("cooling_device=%d, state=%lu\n", __entry->device, __entry->state) ++); ++ ++TRACE_EVENT(thermal_zone_state, ++ TP_PROTO(int device, int state), ++ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) ++ __field(int, state) ++ ), ++ TP_fast_assign(__entry->device = device; ++ __entry->state = state;), ++ TP_printk("thermal_zone=%d, state=%d\n", __entry->device, __entry->state) ++); ++#endif /* _MTK_THERMAL_TRACE_H */ ++ ++/* This part must be outside protection */ ++#undef TRACE_INCLUDE_PATH ++#define TRACE_INCLUDE_PATH . ++#define TRACE_INCLUDE_FILE mach/mtk_thermal_trace ++#include +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h +new file mode 100644 +index 000000000000..dfcef3d952fc +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h +@@ -0,0 +1,241 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _TYPEDEFS_H ++#define _TYPEDEFS_H ++ ++#include ++ ++/* --------------------------------------------------------------------------- */ ++/* Basic Type Definitions */ ++/* --------------------------------------------------------------------------- */ ++ ++typedef volatile unsigned char *P_kal_uint8; ++typedef volatile unsigned short *P_kal_uint16; ++typedef volatile unsigned int *P_kal_uint32; ++ ++typedef long LONG; ++typedef unsigned char UBYTE; ++typedef short SHORT; ++ ++typedef signed char kal_int8; ++typedef signed short kal_int16; ++typedef signed int kal_int32; ++typedef long long kal_int64; ++typedef unsigned char kal_uint8; ++typedef unsigned short kal_uint16; ++typedef unsigned int kal_uint32; ++typedef unsigned long long kal_uint64; ++typedef char kal_char; ++ ++typedef unsigned int *UINT32P; ++typedef volatile unsigned short *UINT16P; ++typedef volatile unsigned char *UINT8P; ++typedef unsigned char *U8P; ++ ++typedef volatile unsigned char *P_U8; ++typedef volatile signed char *P_S8; ++typedef volatile unsigned short *P_U16; ++typedef volatile signed short *P_S16; ++typedef volatile unsigned int *P_U32; ++typedef volatile signed int *P_S32; ++typedef unsigned long long *P_U64; ++typedef signed long long *P_S64; ++ ++typedef unsigned char U8; ++typedef signed char S8; ++typedef unsigned short U16; ++typedef signed short S16; ++typedef unsigned int U32; ++typedef signed int S32; ++typedef unsigned long long U64; ++typedef signed long long S64; ++/* typedef unsigned char bool; */ ++ ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++typedef unsigned short USHORT; ++typedef signed char INT8; ++typedef signed short INT16; ++typedef signed int INT32; ++typedef unsigned int DWORD; ++typedef void VOID; ++typedef unsigned char BYTE; ++typedef float FLOAT; ++ ++typedef char *LPCSTR; ++typedef short *LPWSTR; ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Constants */ ++/* --------------------------------------------------------------------------- */ ++ ++#ifndef FALSE ++#define FALSE (0) ++#endif ++ ++#ifndef TRUE ++#define TRUE (1) ++#endif ++ ++#ifndef NULL ++#define NULL (0) ++#endif ++ ++/* enum boolean {false, true}; */ ++enum { RX, TX, NONE }; ++ ++#ifndef BOOL ++typedef unsigned char BOOL; ++#endif ++ ++#ifndef BATTERY_BOOL ++#define BATTERY_BOOL ++typedef enum { ++ KAL_FALSE = 0, ++ KAL_TRUE = 1, ++} kal_bool; ++#endif ++ ++/* --------------------------------------------------------------------------- */ ++/* Type Casting */ ++/* --------------------------------------------------------------------------- */ ++ ++#define AS_INT32(x) (*(INT32 *)((void *)x)) ++#define AS_INT16(x) (*(INT16 *)((void *)x)) ++#define AS_INT8(x) (*(INT8 *)((void *)x)) ++ ++#define AS_UINT32(x) (*(UINT32 *)((void *)x)) ++#define AS_UINT16(x) (*(UINT16 *)((void *)x)) ++#define AS_UINT8(x) (*(UINT8 *)((void *)x)) ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Register Manipulations */ ++/* --------------------------------------------------------------------------- */ ++ ++#define READ_REGISTER_UINT32(reg) \ ++ (*(volatile UINT32 * const)(reg)) ++ ++#define WRITE_REGISTER_UINT32(reg, val) \ ++ ((*(volatile UINT32 * const)(reg)) = (val)) ++ ++#define READ_REGISTER_UINT16(reg) \ ++ ((*(volatile UINT16 * const)(reg))) ++ ++#define WRITE_REGISTER_UINT16(reg, val) \ ++ ((*(volatile UINT16 * const)(reg)) = (val)) ++ ++#define READ_REGISTER_UINT8(reg) \ ++ ((*(volatile UINT8 * const)(reg))) ++ ++#define WRITE_REGISTER_UINT8(reg, val) \ ++ ((*(volatile UINT8 * const)(reg)) = (val)) ++ ++#define INREG8(x) READ_REGISTER_UINT8((UINT8 *)((void *)(x))) ++#define OUTREG8(x, y) WRITE_REGISTER_UINT8((UINT8 *)((void *)(x)), (UINT8)(y)) ++#define SETREG8(x, y) OUTREG8(x, INREG8(x)|(y)) ++#define CLRREG8(x, y) OUTREG8(x, INREG8(x)&~(y)) ++#define MASKREG8(x, y, z) OUTREG8(x, (INREG8(x)&~(y))|(z)) ++ ++#define INREG16(x) READ_REGISTER_UINT16((UINT16 *)((void *)(x))) ++#define OUTREG16(x, y) WRITE_REGISTER_UINT16((UINT16 *)((void *)(x)), (UINT16)(y)) ++#define SETREG16(x, y) OUTREG16(x, INREG16(x)|(y)) ++#define CLRREG16(x, y) OUTREG16(x, INREG16(x)&~(y)) ++#define MASKREG16(x, y, z) OUTREG16(x, (INREG16(x)&~(y))|(z)) ++ ++#define INREG32(x) READ_REGISTER_UINT32((UINT32 *)((void *)(x))) ++#define OUTREG32(x, y) WRITE_REGISTER_UINT32((UINT32 *)((void *)(x)), (UINT32)(y)) ++#define SETREG32(x, y) OUTREG32(x, INREG32(x)|(y)) ++#define CLRREG32(x, y) OUTREG32(x, INREG32(x)&~(y)) ++#define MASKREG32(x, y, z) OUTREG32(x, (INREG32(x)&~(y))|(z)) ++ ++ ++#define DRV_Reg8(addr) INREG8(addr) ++#define DRV_WriteReg8(addr, data) OUTREG8(addr, data) ++#define DRV_SetReg8(addr, data) SETREG8(addr, data) ++#define DRV_ClrReg8(addr, data) CLRREG8(addr, data) ++ ++#define DRV_Reg16(addr) INREG16(addr) ++#define DRV_WriteReg16(addr, data) OUTREG16(addr, data) ++#define DRV_SetReg16(addr, data) SETREG16(addr, data) ++#define DRV_ClrReg16(addr, data) CLRREG16(addr, data) ++ ++#define DRV_Reg32(addr) INREG32(addr) ++#define DRV_WriteReg32(addr, data) OUTREG32(addr, data) ++#define DRV_SetReg32(addr, data) SETREG32(addr, data) ++#define DRV_ClrReg32(addr, data) CLRREG32(addr, data) ++ ++/* !!! DEPRECATED, WILL BE REMOVED LATER !!! */ ++#define DRV_Reg(addr) DRV_Reg16(addr) ++#define DRV_WriteReg(addr, data) DRV_WriteReg16(addr, data) ++#define DRV_SetReg(addr, data) DRV_SetReg16(addr, data) ++#define DRV_ClrReg(addr, data) DRV_ClrReg16(addr, data) ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Compiler Time Deduction Macros */ ++/* --------------------------------------------------------------------------- */ ++ ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Assertions */ ++/* --------------------------------------------------------------------------- */ ++ ++/* ++*#ifndef ASSERT ++*#define ASSERT(expr) BUG_ON(!(expr)) ++*#endif ++* ++*#ifndef NOT_IMPLEMENTED ++*#define NOT_IMPLEMENTED() BUG_ON(1) ++*#endif ++*/ ++#define STATIC_ASSERT(pred) STATIC_ASSERT_X(pred, __LINE__) ++#define STATIC_ASSERT_X(pred, line) STATIC_ASSERT_XX(pred, line) ++#define STATIC_ASSERT_XX(pred, line) \ ++extern char assertion_failed_at_##line[(pred) ? 1 : -1] ++ ++/* --------------------------------------------------------------------------- */ ++/* Resolve Compiler Warnings */ ++/* --------------------------------------------------------------------------- */ ++ ++#define NOT_REFERENCED(x) { (x) = (x); } ++ ++ ++/* --------------------------------------------------------------------------- */ ++/* Utilities */ ++/* --------------------------------------------------------------------------- */ ++ ++#define MAXIMUM(A, B) (((A) > (B))?(A):(B)) ++#define MINIMUM(A, B) (((A) < (B))?(A):(B)) ++ ++#define ARY_SIZE(x) (sizeof((x)) / sizeof((x[0]))) ++#define DVT_DELAYMACRO(u4Num) \ ++{ \ ++ UINT32 u4Count = 0; \ ++ for (u4Count = 0; u4Count < u4Num; u4Count++) \ ++ ; \ ++} \ ++ ++#define A68351B 0 ++#define B68351B 1 ++#define B68351D 2 ++#define B68351E 3 ++#define UNKNOWN_IC_VERSION 0xFF ++ ++ ++#endif /* _TYPEDEFS_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h +new file mode 100644 +index 000000000000..0a4fda191654 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h +@@ -0,0 +1,185 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/*! \file ++ * \brief Declaration of library functions ++ * ++ * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. ++*/ ++ ++#ifndef _MTK_WCN_CMB_STUB_H_ ++#define _MTK_WCN_CMB_STUB_H_ ++ ++#include ++ ++/******************************************************************************* ++* C O M P I L E R F L A G S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* M A C R O S ++******************************************************************************** ++*/ ++/* Audio GPIO naming style for 73/75/77 */ ++/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_0 1 */ ++/* Audio GPIO naming style for 89/8135 */ ++/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_1 1 */ ++/* Audio GPIO naming style for 6592 */ ++/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_2 1 */ ++/* Audio GPIO naming style for 6595 */ ++#define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_3 1 ++#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 1 ++ ++/******************************************************************************* ++* E X T E R N A L R E F E R E N C E S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* C O N S T A N T S ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* D A T A T Y P E S ++******************************************************************************** ++*/ ++typedef enum { ++ CMB_STUB_AIF_0 = 0, /* 0000: BT_PCM_OFF & FM analog (line in/out) */ ++ CMB_STUB_AIF_1 = 1, /* 0001: BT_PCM_ON & FM analog (in/out) */ ++ CMB_STUB_AIF_2 = 2, /* 0010: BT_PCM_OFF & FM digital (I2S) */ ++ CMB_STUB_AIF_3 = 3, /* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */ ++ CMB_STUB_AIF_4 = 4, /* 0100: BT_I2S & FM disable in special projects, e.g. protea*/ ++ CMB_STUB_AIF_MAX = 5, ++} CMB_STUB_AIF_X; ++ ++/*COMBO_CHIP_AUDIO_PIN_CTRL*/ ++typedef enum { ++ CMB_STUB_AIF_CTRL_DIS = 0, ++ CMB_STUB_AIF_CTRL_EN = 1, ++ CMB_STUB_AIF_CTRL_MAX = 2, ++} CMB_STUB_AIF_CTRL; ++ ++typedef enum { ++ COMBO_FUNC_TYPE_BT = 0, ++ COMBO_FUNC_TYPE_FM = 1, ++ COMBO_FUNC_TYPE_GPS = 2, ++ COMBO_FUNC_TYPE_WIFI = 3, ++ COMBO_FUNC_TYPE_WMT = 4, ++ COMBO_FUNC_TYPE_STP = 5, ++ COMBO_FUNC_TYPE_NUM = 6 ++} COMBO_FUNC_TYPE; ++ ++typedef enum { ++ COMBO_IF_UART = 0, ++ COMBO_IF_MSDC = 1, ++ COMBO_IF_BTIF = 2, ++ COMBO_IF_MAX, ++} COMBO_IF; ++ ++typedef void (*wmt_bgf_eirq_cb) (void); ++typedef int (*wmt_aif_ctrl_cb) (CMB_STUB_AIF_X, CMB_STUB_AIF_CTRL); ++typedef void (*wmt_func_ctrl_cb) (unsigned int, unsigned int); ++typedef signed long (*wmt_thermal_query_cb) (void); ++typedef int (*wmt_deep_idle_ctrl_cb) (unsigned int); ++typedef int (*wmt_func_do_reset) (unsigned int); ++ ++/* for DVFS driver do 1v autok */ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++typedef unsigned int (*wmt_get_drv_status)(unsigned int); ++#endif ++ ++typedef void (*msdc_sdio_irq_handler_t) (void *); /* external irq handler */ ++typedef void (*pm_callback_t) (pm_message_t state, void *data); ++ ++struct sdio_ops { ++ void (*sdio_request_eirq)(msdc_sdio_irq_handler_t irq_handler, void *data); ++ void (*sdio_enable_eirq)(void); ++ void (*sdio_disable_eirq)(void); ++ void (*sdio_register_pm)(pm_callback_t pm_cb, void *data); ++}; ++ ++typedef struct _CMB_STUB_CB_ { ++ unsigned int size; /* structure size */ ++ /*wmt_bgf_eirq_cb bgf_eirq_cb; *//* remove bgf_eirq_cb from stub. handle it in platform */ ++ wmt_aif_ctrl_cb aif_ctrl_cb; ++ wmt_func_ctrl_cb func_ctrl_cb; ++ wmt_thermal_query_cb thermal_query_cb; ++ wmt_deep_idle_ctrl_cb deep_idle_ctrl_cb; ++ wmt_func_do_reset wmt_do_reset_cb; ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++ wmt_get_drv_status get_drv_status_cb; ++#endif ++} CMB_STUB_CB, *P_CMB_STUB_CB; ++ ++/******************************************************************************* ++* P U B L I C D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* P R I V A T E D A T A ++******************************************************************************** ++*/ ++ ++/******************************************************************************* ++* F U N C T I O N D E C L A R A T I O N S ++******************************************************************************** ++*/ ++ ++extern struct sdio_ops mt_sdio_ops[4]; ++ ++extern int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb); ++extern int mtk_wcn_cmb_stub_unreg(void); ++ ++extern int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); ++ ++static inline int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state) ++{ ++/* return mtk_wcn_cmb_stub_aif_ctrl(state, 1); */ ++ return 0; ++} ++ ++extern int mt_combo_plt_enter_deep_idle(COMBO_IF src); ++extern int mt_combo_plt_exit_deep_idle(COMBO_IF src); ++ ++/* Use new mtk_wcn_stub APIs instead of old mt_combo ones for kernel to control ++ * function on/off. ++ */ ++extern void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on); ++extern int mtk_wcn_cmb_stub_query_ctrl(void); ++extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); ++extern int mtk_wcn_sdio_irq_flag_set(int falg); ++ ++#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK ++extern int mtk_wcn_cmb_stub_1vautok_for_dvfs(void); ++#endif ++ ++extern int mtk_wcn_wmt_chipid_query(void); ++extern void mtk_wcn_wmt_set_chipid(int chipid); ++ ++/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver ++ * ++ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" ++ * @ enable - "1", enable deep idle; "0", disable deep idle ++ * ++ * Return 0 if success, else -1 ++ */ ++extern unsigned int mtk_uart_pdn_enable(char *port, int enable); ++/******************************************************************************* ++* F U N C T I O N S ++******************************************************************************** ++*/ ++ ++#endif /* _MTK_WCN_CMB_STUB_H_ */ +diff --git a/drivers/misc/mediatek/include/mt-plat/rt-regmap.h b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h +new file mode 100644 +index 000000000000..9a45e23005ca +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h +@@ -0,0 +1,291 @@ ++/* drivers/misc/mediatek/include/mt-plat/rt-regmap.h ++ * Header of Richtek regmap with debugfs Driver ++ * ++ * Copyright (C) 2014 Richtek Technology Corp. ++ * Jeff Chang ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef MISC_MEDIATEK_RT_REGMAP_H ++#define MISC_MEDIATEK_RT_REGMAP_H ++ ++#include ++#include ++ ++/* #define RT_REGMAP_VERSION "1.1.11_G" */ ++ ++enum rt_access_mode { ++ RT_1BYTE_MODE = 1, ++ RT_2BYTE_MODE = 2, ++ RT_4BYTE_MODE = 4, ++}; ++ ++/* start : the start address of group ++ * end : the end address of group ++ * mode : access mode (1,2,4 bytes) ++ */ ++struct rt_access_group { ++ u32 start; ++ u32 end; ++ enum rt_access_mode mode; ++}; ++ ++/* rt_reg_type ++ * RT_NORMAL : Write data without mask ++ * Read from cache ++ * RT_WBITS : Write data with mask ++ * Read from cache ++ * RT_VOLATILE : Write data to chip directly ++ * Read data from chip ++ * RT_RESERVE : Reserve registers (Write/Read as RT_NORMAL) ++ */ ++ ++#define RT_REG_TYPE_MASK (0x03) ++#define RT_NORMAL (0x00) ++#define RT_WBITS (0x01) ++#define RT_VOLATILE (0x02) ++#define RT_RESERVE (0x03) ++ ++/* RT_WR_ONCE : write once will check write data and cache data, ++ * if write data = cache data, data will not be writen. ++ */ ++#define RT_WR_ONCE (0x08) ++#define RT_NORMAL_WR_ONCE (RT_NORMAL|RT_WR_ONCE) ++#define RT_WBITS_WR_ONCE (RT_WBITS|RT_WR_ONCE) ++ ++enum rt_data_format { ++ RT_LITTLE_ENDIAN, ++ RT_BIG_ENDIAN, ++}; ++ ++/* rt_regmap_mode ++ * 0 0 0 0 0 0 0 0 ++ * | | | | | | ++ * | | | |__| byte_mode ++ * | |__| || ++ * | || Cache_mode ++ * | Block_mode ++ * Debug_mode ++ */ ++ ++#define RT_BYTE_MODE_MASK (0x01) ++/* 1 byte for each register*/ ++#define RT_SINGLE_BYTE (0 << 0) ++/* multi bytes for each regiseter*/ ++#define RT_MULTI_BYTE (1 << 0) ++ ++#define RT_CACHE_MODE_MASK (0x06) ++/* write to cache and chip synchronously */ ++#define RT_CACHE_WR_THROUGH (0 << 1) ++/* write to cache and chip asynchronously */ ++#define RT_CACHE_WR_BACK (1 << 1) ++/* disable cache */ ++#define RT_CACHE_DISABLE (2 << 1) ++ ++#define RT_IO_BLK_MODE_MASK (0x18) ++/* pass through all write function */ ++#define RT_IO_PASS_THROUGH (0 << 3) ++/* block all write function */ ++#define RT_IO_BLK_ALL (1 << 3) ++/* block cache write function */ ++#define RT_IO_BLK_CACHE (2 << 3) ++/* block chip write function */ ++#define RT_IO_BLK_CHIP (3 << 3) ++ ++#define DBG_MODE_MASK (0x20) ++/* create general debugfs for register map */ ++#define RT_DBG_GENERAL (0 << 5) ++/* create node for each regisetr map by register address*/ ++#define RT_DBG_SPECIAL (1 << 5) ++ ++ ++/* struct rt_register ++ * ++ * Ricktek register map structure for store mapping data ++ * @addr: register address. ++ * @name: register name. ++ * @size: register byte size. ++ * @reg_type: register R/W type ( RT_NORMAL, RT_WBITS, RT_VOLATILE, RT_RESERVE) ++ * @wbit_mask: register writeable bits mask; ++ * @cache_data: cache data for store cache value. ++ */ ++struct rt_register { ++ u32 addr; ++ const char *name; ++ unsigned int size; ++ unsigned char reg_type; ++ unsigned char *wbit_mask; ++ unsigned char *cache_data; ++}; ++ ++/* Declare a rt_register by RT_REG_DECL ++ * @_addr: regisetr address. ++ * @_reg_length: register data length. ++ * @_reg_type: register type (rt_reg_type). ++ * @_mask: register writealbe mask. ++ */ ++#define RT_REG_DECL(_addr, _reg_length, _reg_type, _mask_...) \ ++ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ ++ static struct rt_register rt_register_##_addr = { \ ++ .addr = _addr, \ ++ .size = _reg_length,\ ++ .reg_type = _reg_type,\ ++ .wbit_mask = rt_writable_mask_##_addr,\ ++ } ++ ++/* Declare a rt_register by RT_NAMED_REG_DECL ++ * @_name: a name for a rt_register. ++ */ ++#define RT_NAMED_REG_DECL(_addr, _name, _reg_length, _reg_type, _mask_...) \ ++ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ ++ static struct rt_register rt_register_##_addr = { \ ++ .addr = _addr, \ ++ .name = _name, \ ++ .size = _reg_length,\ ++ .reg_type = _reg_type,\ ++ .wbit_mask = rt_writable_mask_##_addr,\ ++ } ++ ++#define RT_REG(_addr) (&rt_register_##_addr) ++ ++/* rt_regmap_properties ++ * @name: the name of debug node. ++ * @aliases: alisis name of rt_regmap_device. ++ * @register_num: the number of rt_register_map registers. ++ * @rm: rt_regiseter_map pointer array. ++ * @group: register map access group. ++ * @rt_format: default is little endian. ++ * @rt_regmap_mode: rt_regmap_device mode. ++ * @io_log_en: enable/disable io log ++ */ ++struct rt_regmap_properties { ++ const char *name; ++ const char *aliases; ++ int register_num; ++ struct rt_register **rm; ++ struct rt_access_group *group; ++ enum rt_data_format rt_format; ++ unsigned char rt_regmap_mode; ++ unsigned char io_log_en:1; ++}; ++ ++/* A passing struct for rt_regmap_reg_read and rt_regmap_reg_write function ++ * reg: regmap addr. ++ * mask: mask for update bits. ++ * rt_data: register value. ++ */ ++struct rt_reg_data { ++ u32 reg; ++ u32 mask; ++ union { ++ u32 data_u32; ++ u16 data_u16; ++ u8 data_u8; ++ u8 data[4]; ++ } rt_data; ++}; ++ ++struct rt_regmap_device; ++ ++struct rt_debug_st { ++ void *info; ++ int id; ++}; ++ ++/* basic chip read/write function */ ++struct rt_regmap_fops { ++ int (*read_device)(void *client, u32 addr, int leng, void *dst); ++ int (*write_device)(void *client, u32 addr, int leng, const void *src); ++}; ++ ++/* with slave address */ ++extern struct rt_regmap_device* ++ rt_regmap_device_register_ex(struct rt_regmap_properties *props, ++ struct rt_regmap_fops *rops, ++ struct device *parent, ++ void *client, int slv_addr, void *drvdata); ++ ++static inline struct rt_regmap_device* ++ rt_regmap_device_register(struct rt_regmap_properties *props, ++ struct rt_regmap_fops *rops, ++ struct device *parent, ++ struct i2c_client *client, void *drvdata) ++{ ++ return rt_regmap_device_register_ex(props, rops, parent, ++ client, client->addr, drvdata); ++} ++ ++extern void rt_regmap_device_unregister(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_cache_init(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_cache_reload(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_block_write(struct rt_regmap_device *rd, u32 reg, ++ int bytes, const void *rc); ++extern int rt_asyn_regmap_block_write(struct rt_regmap_device *rd, u32 reg, ++ int bytes, const void *rc); ++extern int rt_regmap_block_read(struct rt_regmap_device *rd, u32 reg, ++ int bytes, void *dst); ++ ++extern int _rt_regmap_reg_read(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++extern int _rt_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++extern int _rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++extern int _rt_regmap_update_bits(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd); ++ ++static inline int rt_regmap_reg_read(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg) ++{ ++ rrd->reg = reg; ++ return _rt_regmap_reg_read(rd, rrd); ++}; ++ ++static inline int rt_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg, const u32 data) ++{ ++ rrd->reg = reg; ++ rrd->rt_data.data_u32 = data; ++ return _rt_regmap_reg_write(rd, rrd); ++}; ++ ++static inline int rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg, const u32 data) ++{ ++ rrd->reg = reg; ++ rrd->rt_data.data_u32 = data; ++ return _rt_asyn_regmap_reg_write(rd, rrd); ++}; ++ ++static inline int rt_regmap_update_bits(struct rt_regmap_device *rd, ++ struct rt_reg_data *rrd, u32 reg, u32 mask, u32 data) ++{ ++ rrd->reg = reg; ++ rrd->mask = mask; ++ rrd->rt_data.data_u32 = data; ++ return _rt_regmap_update_bits(rd, rrd); ++} ++ ++extern void rt_regmap_cache_backup(struct rt_regmap_device *rd); ++ ++extern void rt_regmap_cache_sync(struct rt_regmap_device *rd); ++extern void rt_regmap_cache_write_back(struct rt_regmap_device *rd, u32 reg); ++ ++extern int rt_is_reg_readable(struct rt_regmap_device *rd, u32 reg); ++extern int rt_is_reg_volatile(struct rt_regmap_device *rd, u32 reg); ++extern int rt_get_regsize(struct rt_regmap_device *rd, u32 reg); ++extern void rt_cache_getlasterror(struct rt_regmap_device *rd, char *buf); ++extern void rt_cache_clrlasterror(struct rt_regmap_device *rd); ++ ++extern int rt_regmap_add_debugfs(struct rt_regmap_device *rd, const char *name, ++ umode_t mode, void *data, const struct file_operations *fops); ++ ++#define to_rt_regmap_device(obj) container_of(obj, struct rt_regmap_device, dev) ++ ++#endif /*MISC_MEDIATEK_RT_REGMAP_H*/ +diff --git a/drivers/misc/mediatek/include/mt-plat/sync_write.h b/drivers/misc/mediatek/include/mt-plat/sync_write.h +new file mode 100644 +index 000000000000..f9e5fe4c23e1 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/sync_write.h +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _MT_SYNC_WRITE_H ++#define _MT_SYNC_WRITE_H ++ ++#if defined(__KERNEL__) ++ ++#include ++#include ++ ++/* ++ * Define macros. ++ */ ++#define mt_reg_sync_writel(v, a) \ ++ do { \ ++ __raw_writel((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writew(v, a) \ ++ do { \ ++ __raw_writew((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writeb(v, a) \ ++ do { \ ++ __raw_writeb((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++ ++#ifdef CONFIG_64BIT ++#define mt_reg_sync_writeq(v, a) \ ++ do { \ ++ __raw_writeq((v), (void __force __iomem *)((a))); \ ++ mb(); \ ++ } while (0) ++#endif ++ ++#else /* __KERNEL__ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define mt_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) ++#define mt_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) ++#define mt_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) ++ ++#define mb() \ ++ { \ ++ __asm__ __volatile__ ("dsb" : : : "memory"); \ ++ } ++ ++#define mt65xx_reg_sync_writel(v, a) \ ++ do { \ ++ *(volatile unsigned int *)(a) = (v); \ ++ mb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writew(v, a) \ ++ do { \ ++ *(volatile unsigned short *)(a) = (v); \ ++ mb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writeb(v, a) \ ++ do { \ ++ *(volatile unsigned char *)(a) = (v); \ ++ mb(); \ ++ } while (0) ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* !_MT_SYNC_WRITE_H */ +diff --git a/drivers/misc/mediatek/include/mt-plat/wakelock.h b/drivers/misc/mediatek/include/mt-plat/wakelock.h +new file mode 100644 +index 000000000000..f4a698a22880 +--- /dev/null ++++ b/drivers/misc/mediatek/include/mt-plat/wakelock.h +@@ -0,0 +1,67 @@ ++/* include/linux/wakelock.h ++ * ++ * Copyright (C) 2007-2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_WAKELOCK_H ++#define _LINUX_WAKELOCK_H ++ ++#include ++#include ++ ++/* A wake_lock prevents the system from entering suspend or other low power ++ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock ++ * prevents a full system suspend. ++ */ ++ ++enum { ++ WAKE_LOCK_SUSPEND, /* Prevent suspend */ ++ WAKE_LOCK_TYPE_COUNT ++}; ++ ++struct wake_lock { ++ struct wakeup_source ws; ++}; ++ ++static inline void wake_lock_init(struct wake_lock *lock, int type, ++ const char *name) ++{ ++ wakeup_source_init(&lock->ws, name); ++} ++ ++static inline void wake_lock_destroy(struct wake_lock *lock) ++{ ++ wakeup_source_trash(&lock->ws); ++} ++ ++static inline void wake_lock(struct wake_lock *lock) ++{ ++ __pm_stay_awake(&lock->ws); ++} ++ ++static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) ++{ ++ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); ++} ++ ++static inline void wake_unlock(struct wake_lock *lock) ++{ ++ __pm_relax(&lock->ws); ++} ++ ++static inline int wake_lock_active(struct wake_lock *lock) ++{ ++ return lock->ws.active; ++} ++ ++#endif +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch b/root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch new file mode 100755 index 00000000..c4e0a903 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch @@ -0,0 +1,846 @@ +From 83ffbaceffed1cd47a6f67fb20e39737dfb2d01a Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 28 Aug 2018 18:14:56 +0200 +Subject: [PATCH 07/77] [wifi] adding wifi-related changes outside + driver-directory + +--- + arch/arm/boot/dts/mt7623.dtsi | 41 +- + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 42 ++ + drivers/soc/mediatek/mtk-pmic-wrap.c | 12 + + drivers/watchdog/mtk_wdt.c | 377 +++++++++++++++++- + include/linux/wakelock.h | 67 ++++ + include/net/genetlink.h | 44 ++ + include/soc/mediatek/pmic_wrap.h | 19 + + include/uapi/linux/genetlink.h | 1 + + 8 files changed, 588 insertions(+), 15 deletions(-) + create mode 100644 include/linux/wakelock.h + create mode 100644 include/soc/mediatek/pmic_wrap.h + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 04228cf9ddbb..af6b6228f8a8 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -266,6 +266,8 @@ + compatible = "mediatek,mt7623-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x100>; ++ interrupts = ; ++ #reset-cells = <1>; + }; + + timer: timer@10008000 { +@@ -494,13 +496,26 @@ + "mediatek,mtk-btif"; + reg = <0 0x1100c000 0 0x1000>; + interrupts = ; +- clocks = <&pericfg CLK_PERI_BTIF>; +- clock-names = "main"; ++ clocks = <&pericfg CLK_PERI_BTIF>, <&pericfg CLK_PERI_AP_DMA>; ++ clock-names = "main", "apdmac"; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + ++ btif_tx: btif_tx@11000780 { ++ compatible = "mediatek,btif_tx"; ++ reg = <0 0x11000780 0 0x80>; ++ interrupts = ; ++ status = "okay"; ++ }; ++ btif_rx: btif_rx@11000800 { ++ compatible = "mediatek,btif_rx"; ++ reg = <0 0x11000800 0 0x80>; ++ interrupts = ; ++ status = "okay"; ++ }; ++ + nandc: nfi@1100d000 { + compatible = "mediatek,mt7623-nfc", + "mediatek,mt2701-nfc"; +@@ -683,6 +698,28 @@ + status = "disabled"; + }; + ++ consys: consys@18070000 { ++ compatible = "mediatek,mt7623-consys"; ++ reg = <0 0x18070000 0 0x0200>, /*CONN_MCU_CONFIG_BASE */ ++ <0 0x10001000 0 0x1600>; /*TOPCKGEN_BASE */ ++ clocks = <&infracfg CLK_INFRA_CONNMCU>; ++ clock-names = "consysbus"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_CONN>; ++ interrupts = , /* BGF_EINT */ ++ ; /* WDT_EINT */ ++ resets = <&watchdog MT2701_TOPRGU_CONN_MCU_RST>; ++ reset-names = "connsys"; ++ status="disabled"; ++ }; ++ wifi:wifi@180f0000 { ++ compatible = "mediatek,mt7623-wifi", ++ "mediatek,wifi"; ++ reg = <0 0x180f0000 0 0x005c>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_AP_DMA>; ++ clock-names = "wifi-dma"; ++ }; ++ + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 2b760f90f38c..465fb887b2ca 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -84,6 +84,18 @@ + }; + }; + ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ consys-reserve-memory { ++ compatible = "mediatek,consys-reserve-memory"; ++ no-map; ++ size = <0 0x100000>; ++ alignment = <0 0x100000>; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; +@@ -259,6 +271,36 @@ + }; + }; + ++&pio { ++ consys_pins_default: consys_pins_default { ++ adie { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ bias-disable; ++ }; ++ }; ++}; ++&consys { ++ mediatek,pwrap-regmap = <&pwrap>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&consys_pins_default>; ++ vcn18-supply = <&mt6323_vcn18_reg>; ++ vcn28-supply = <&mt6323_vcn28_reg>; ++ vcn33_bt-supply = <&mt6323_vcn33_bt_reg>; ++ vcn33_wifi-supply = <&mt6323_vcn33_wifi_reg>; ++ status = "okay"; ++}; ++ + &pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_default>; +diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c +index 4e931fdf4d09..6600396ee299 100644 +--- a/drivers/soc/mediatek/mtk-pmic-wrap.c ++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c +@@ -1530,6 +1530,18 @@ static const struct of_device_id of_pwrap_match_tbl[] = { + }; + MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl); + ++struct regmap *pwrap_node_to_regmap(struct device_node *np) ++{ ++ struct platform_device *pdev; ++ struct pmic_wrapper *wrp; ++ pdev = of_find_device_by_node(np); ++ if (!pdev) ++ return ERR_PTR(-ENODEV); ++ wrp = platform_get_drvdata(pdev); ++ return wrp->regmap; ++} ++EXPORT_SYMBOL_GPL(pwrap_node_to_regmap); ++ + static int pwrap_probe(struct platform_device *pdev) + { + int ret, irq; +diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c +index 4baf64f21aa1..6a361f808aed 100644 +--- a/drivers/watchdog/mtk_wdt.c ++++ b/drivers/watchdog/mtk_wdt.c +@@ -1,4 +1,3 @@ +-// SPDX-License-Identifier: GPL-2.0+ + /* + * Mediatek Watchdog Driver + * +@@ -6,20 +5,51 @@ + * + * Matthias Brugger + * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * + * Based on sunxi_wdt.c + */ + + #include + #include + #include ++#include + #include + #include + #include ++#include ++#include ++#include + #include ++#include + #include ++#ifdef CONFIG_FIQ_GLUE ++#include ++#include ++#endif + #include + #include ++#include ++#include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_MT6397_MISC ++#include ++#endif + + #define WDT_MAX_TIMEOUT 31 + #define WDT_MIN_TIMEOUT 1 +@@ -38,37 +68,167 @@ + #define WDT_MODE_EXRST_EN (1 << 2) + #define WDT_MODE_IRQ_EN (1 << 3) + #define WDT_MODE_AUTO_START (1 << 4) ++#define WDT_MODE_IRQ_LVL (1 << 5) + #define WDT_MODE_DUAL_EN (1 << 6) + #define WDT_MODE_KEY 0x22000000 + ++#define WDT_STATUS 0x0c ++#define WDT_NONRST_REG 0x20 ++#define WDT_NONRST_REG2 0x24 ++ + #define WDT_SWRST 0x14 + #define WDT_SWRST_KEY 0x1209 + ++#define WDT_SWSYSRST 0x18 ++#define WDT_SWSYSRST_KEY 0x88000000 ++ ++#define WDT_REQ_MODE 0x30 ++#define WDT_REQ_MODE_KEY 0x33000000 ++#define WDT_REQ_IRQ_EN 0x34 ++#define WDT_REQ_IRQ_KEY 0x44000000 ++#define WDT_REQ_MODE_DEBUG_EN 0x80000 ++ ++ + #define DRV_NAME "mtk-wdt" +-#define DRV_VERSION "1.0" ++#define DRV_VERSION "2.0" + + static bool nowayout = WATCHDOG_NOWAYOUT; +-static unsigned int timeout; ++static unsigned int timeout = WDT_MAX_TIMEOUT; ++ ++struct toprgu_reset { ++ spinlock_t lock; ++ void __iomem *toprgu_swrst_base; ++ int regofs; ++ struct reset_controller_dev rcdev; ++}; + + struct mtk_wdt_dev { + struct watchdog_device wdt_dev; + void __iomem *wdt_base; ++ int wdt_irq_id; ++ struct notifier_block restart_handler; ++ struct toprgu_reset reset_controller; + }; + +-static int mtk_wdt_restart(struct watchdog_device *wdt_dev, +- unsigned long action, void *data) ++static void __iomem *toprgu_base; ++static struct watchdog_device *wdt_dev; ++ ++static int toprgu_reset_assert(struct reset_controller_dev *rcdev, ++ unsigned long id) + { +- struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); ++ unsigned int tmp; ++ unsigned long flags; ++ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); ++ ++ spin_lock_irqsave(&data->lock, flags); ++ ++ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); ++ tmp |= BIT(id); ++ tmp |= WDT_SWSYSRST_KEY; ++ writel(tmp, data->toprgu_swrst_base + data->regofs); ++ ++ spin_unlock_irqrestore(&data->lock, flags); ++ ++ return 0; ++} ++ ++static int toprgu_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ unsigned int tmp; ++ unsigned long flags; ++ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); ++ ++ spin_lock_irqsave(&data->lock, flags); ++ ++ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); ++ tmp &= ~BIT(id); ++ tmp |= WDT_SWSYSRST_KEY; ++ writel(tmp, data->toprgu_swrst_base + data->regofs); ++ ++ spin_unlock_irqrestore(&data->lock, flags); ++ ++ return 0; ++} ++ ++static int toprgu_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = toprgu_reset_assert(rcdev, id); ++ if (ret) ++ return ret; ++ ++ return toprgu_reset_deassert(rcdev, id); ++} ++ ++static struct reset_control_ops toprgu_reset_ops = { ++ .assert = toprgu_reset_assert, ++ .deassert = toprgu_reset_deassert, ++ .reset = toprgu_reset, ++}; ++ ++static void toprgu_register_reset_controller(struct platform_device *pdev, int regofs) ++{ ++ int ret; ++ struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); ++ ++ spin_lock_init(&mtk_wdt->reset_controller.lock); ++ ++ mtk_wdt->reset_controller.toprgu_swrst_base = mtk_wdt->wdt_base; ++ mtk_wdt->reset_controller.regofs = regofs; ++ mtk_wdt->reset_controller.rcdev.owner = THIS_MODULE; ++ mtk_wdt->reset_controller.rcdev.nr_resets = 15; ++ mtk_wdt->reset_controller.rcdev.ops = &toprgu_reset_ops; ++ mtk_wdt->reset_controller.rcdev.of_node = pdev->dev.of_node; ++ ++ ret = reset_controller_register(&mtk_wdt->reset_controller.rcdev); ++ if (ret) ++ pr_err("could not register toprgu reset controller: %d\n", ret); ++} ++ ++static int mtk_reset_handler(struct notifier_block *this, unsigned long mode, ++ void *cmd) ++{ ++ struct mtk_wdt_dev *mtk_wdt; + void __iomem *wdt_base; ++ u32 reg; + ++ mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler); + wdt_base = mtk_wdt->wdt_base; + +- while (1) { +- writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); +- mdelay(5); ++ /* WDT_STATUS will be cleared to zero after writing to WDT_MODE, so we backup it in WDT_NONRST_REG, ++ * and then print it out in mtk_wdt_probe() after reset ++ */ ++ writel(__raw_readl(wdt_base + WDT_STATUS), wdt_base + WDT_NONRST_REG); ++ ++ reg = ioread32(wdt_base + WDT_MODE); ++ reg &= ~(WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EN); ++ reg |= WDT_MODE_KEY; ++ iowrite32(reg, wdt_base + WDT_MODE); ++ ++ if (cmd && !strcmp(cmd, "rpmbpk")) { ++ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 0), wdt_base + WDT_NONRST_REG2); ++ } else if (cmd && !strcmp(cmd, "recovery")) { ++ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 1), wdt_base + WDT_NONRST_REG2); ++ #ifdef CONFIG_MT6397_MISC ++ mtk_misc_mark_recovery(); ++ #endif ++ } else if (cmd && !strcmp(cmd, "bootloader")) { ++ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 2), wdt_base + WDT_NONRST_REG2); ++ #ifdef CONFIG_MT6397_MISC ++ mtk_misc_mark_fast(); ++ #endif + } + +- return 0; ++ if (!arm_pm_restart) { ++ while (1) { ++ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); ++ mdelay(5); ++ } ++ } ++ return NOTIFY_DONE; + } + + static int mtk_wdt_ping(struct watchdog_device *wdt_dev) +@@ -77,6 +237,7 @@ static int mtk_wdt_ping(struct watchdog_device *wdt_dev) + void __iomem *wdt_base = mtk_wdt->wdt_base; + + iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); ++ printk_deferred("[WDK]: kick Ex WDT\n"); + + return 0; + } +@@ -128,7 +289,8 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev) + return ret; + + reg = ioread32(wdt_base + WDT_MODE); +- reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); ++ reg |= (WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EXRST_EN); ++ reg &= ~(WDT_MODE_IRQ_LVL | WDT_MODE_EXT_POL_HIGH); + reg |= (WDT_MODE_EN | WDT_MODE_KEY); + iowrite32(reg, wdt_base + WDT_MODE); + +@@ -148,13 +310,56 @@ static const struct watchdog_ops mtk_wdt_ops = { + .stop = mtk_wdt_stop, + .ping = mtk_wdt_ping, + .set_timeout = mtk_wdt_set_timeout, +- .restart = mtk_wdt_restart, + }; + ++#ifdef CONFIG_FIQ_GLUE ++static void wdt_fiq(void *arg, void *regs, void *svc_sp) ++{ ++ unsigned int wdt_mode_val; ++ void __iomem *wdt_base = ((struct mtk_wdt_dev *)arg)->wdt_base; ++ ++ wdt_mode_val = __raw_readl(wdt_base + WDT_STATUS); ++ writel(wdt_mode_val, wdt_base + WDT_NONRST_REG); ++ ++ aee_wdt_fiq_info(arg, regs, svc_sp); ++} ++#else ++static void wdt_report_info(void) ++{ ++ struct task_struct *task; ++ ++ task = &init_task; ++ pr_debug("Qwdt: -- watchdog time out\n"); ++ ++ for_each_process(task) { ++ if (task->state == 0) { ++ pr_debug("PID: %d, name: %s\n backtrace:\n", task->pid, task->comm); ++ show_stack(task, NULL); ++ pr_debug("\n"); ++ } ++ } ++ ++ pr_debug("backtrace of current task:\n"); ++ show_stack(NULL, NULL); ++ pr_debug("Qwdt: -- watchdog time out\n"); ++} ++ ++static irqreturn_t mtk_wdt_isr(int irq, void *dev_id) ++{ ++ pr_err("fwq mtk_wdt_isr\n"); ++ ++ wdt_report_info(); ++ BUG(); ++ ++ return IRQ_HANDLED; ++} ++#endif ++ + static int mtk_wdt_probe(struct platform_device *pdev) + { + struct mtk_wdt_dev *mtk_wdt; + struct resource *res; ++ unsigned int tmp; + int err; + + mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL); +@@ -165,9 +370,32 @@ static int mtk_wdt_probe(struct platform_device *pdev) + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res); ++ + if (IS_ERR(mtk_wdt->wdt_base)) + return PTR_ERR(mtk_wdt->wdt_base); + ++ pr_err("MTK_WDT_NONRST_REG(%x)\n", __raw_readl(mtk_wdt->wdt_base + WDT_NONRST_REG)); ++ ++ mtk_wdt->wdt_irq_id = irq_of_parse_and_map(pdev->dev.of_node, 0); ++ if (!mtk_wdt->wdt_irq_id) { ++ pr_err("RGU get IRQ ID failed\n"); ++ return -ENODEV; ++ } ++ ++#ifndef CONFIG_FIQ_GLUE ++ err = request_irq(mtk_wdt->wdt_irq_id, (irq_handler_t)mtk_wdt_isr, IRQF_TRIGGER_NONE, DRV_NAME, mtk_wdt); ++#else ++ mtk_wdt->wdt_irq_id = get_hardware_irq(mtk_wdt->wdt_irq_id); ++ err = request_fiq(mtk_wdt->wdt_irq_id, wdt_fiq, IRQF_TRIGGER_FALLING, mtk_wdt); ++#endif ++ if (err != 0) { ++ pr_err("mtk_wdt_probe : failed to request irq (%d)\n", err); ++ return err; ++ } ++ ++ toprgu_base = mtk_wdt->wdt_base; ++ wdt_dev = &mtk_wdt->wdt_dev; ++ + mtk_wdt->wdt_dev.info = &mtk_wdt_info; + mtk_wdt->wdt_dev.ops = &mtk_wdt_ops; + mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT; +@@ -177,7 +405,6 @@ static int mtk_wdt_probe(struct platform_device *pdev) + + watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev); + watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout); +- watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128); + + watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); + +@@ -187,9 +414,40 @@ static int mtk_wdt_probe(struct platform_device *pdev) + if (unlikely(err)) + return err; + ++ mtk_wdt->restart_handler.notifier_call = mtk_reset_handler; ++ mtk_wdt->restart_handler.priority = 128; ++ ++ if (arm_pm_restart) { ++ dev_info(&pdev->dev, "register restart_handler on reboot_notifier_list for psci reset\n"); ++ err = register_reboot_notifier(&mtk_wdt->restart_handler); ++ if (err != 0) ++ dev_warn(&pdev->dev, ++ "cannot register reboot notifier (err=%d)\n", err); ++ } else { ++ err = register_restart_handler(&mtk_wdt->restart_handler); ++ if (err) ++ dev_warn(&pdev->dev, ++ "cannot register restart handler (err=%d)\n", err); ++ } ++ + dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", + mtk_wdt->wdt_dev.timeout, nowayout); + ++ writel(WDT_REQ_MODE_KEY | (__raw_readl(mtk_wdt->wdt_base + WDT_REQ_MODE) & ++ (~WDT_REQ_MODE_DEBUG_EN)), mtk_wdt->wdt_base + WDT_REQ_MODE); ++ ++ toprgu_register_reset_controller(pdev, WDT_SWSYSRST); ++ ++ /* enable scpsys thermal and thermal_controller request, and set to reset directly mode */ ++ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_MODE) | (1 << 18) | (1 << 0); ++ tmp |= WDT_REQ_MODE_KEY; ++ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_MODE); ++ ++ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); ++ tmp &= ~((1 << 18) | (1 << 0)); ++ tmp |= WDT_REQ_IRQ_KEY; ++ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); ++ + return 0; + } + +@@ -205,8 +463,12 @@ static int mtk_wdt_remove(struct platform_device *pdev) + { + struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); + ++ unregister_restart_handler(&mtk_wdt->restart_handler); ++ + watchdog_unregister_device(&mtk_wdt->wdt_dev); + ++ reset_controller_unregister(&mtk_wdt->reset_controller.rcdev); ++ + return 0; + } + +@@ -258,6 +520,95 @@ static struct platform_driver mtk_wdt_driver = { + + module_platform_driver(mtk_wdt_driver); + ++static int wk_proc_cmd_read(struct seq_file *s, void *v) ++{ ++ unsigned int enabled = 1; ++ ++ if (!(ioread32(toprgu_base + WDT_MODE) & WDT_MODE_EN)) ++ enabled = 0; ++ ++ seq_printf(s, "enabled timeout\n%-4d %-8d\n", enabled, wdt_dev->timeout); ++ ++ return 0; ++} ++ ++static int wk_proc_cmd_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, wk_proc_cmd_read, NULL); ++} ++ ++static ssize_t wk_proc_cmd_write(struct file *file, const char *buf, size_t count, loff_t *data) ++{ ++ int ret; ++ int enable; ++ int timeout; ++ char wk_cmd_buf[256]; ++ ++ if (count == 0) ++ return -1; ++ ++ if (count > 255) ++ count = 255; ++ ++ ret = copy_from_user(wk_cmd_buf, buf, count); ++ if (ret < 0) ++ return -1; ++ ++ wk_cmd_buf[count] = '\0'; ++ ++ pr_debug("Write %s\n", wk_cmd_buf); ++ ++ ret = sscanf(wk_cmd_buf, "%d %d", &enable, &timeout); ++ if (ret != 2) ++ pr_debug("%s: expect 2 numbers\n", __func__); ++ ++ pr_debug("[WDK] enable=%d timeout=%d\n", enable, timeout); ++ ++ if (timeout > 20 && timeout <= WDT_MAX_TIMEOUT) { ++ wdt_dev->timeout = timeout; ++ mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); ++ } else { ++ pr_err("[WDK] The timeout(%d) should bigger than 20 and not bigger than %d\n", ++ timeout, WDT_MAX_TIMEOUT); ++ ++ } ++ ++ if (enable == 1) { ++ mtk_wdt_start(wdt_dev); ++ set_bit(WDOG_ACTIVE, &wdt_dev->status); ++ pr_err("[WDK] enable wdt\n"); ++ } else if (enable == 0) { ++ mtk_wdt_stop(wdt_dev); ++ clear_bit(WDOG_ACTIVE, &wdt_dev->status); ++ pr_err("[WDK] disable wdt\n"); ++ } ++ ++ return count; ++} ++ ++static const struct file_operations wk_proc_cmd_fops = { ++ .owner = THIS_MODULE, ++ .open = wk_proc_cmd_open, ++ .read = seq_read, ++ .write = wk_proc_cmd_write, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int __init wk_proc_init(void) ++{ ++ struct proc_dir_entry *de = proc_create("wdk", 0660, NULL, &wk_proc_cmd_fops); ++ ++ if (!de) ++ pr_err("[wk_proc_init]: create /proc/wdk failed\n"); ++ ++ pr_debug("[WDK] Initialize proc\n"); ++ ++ return 0; ++} ++ ++late_initcall(wk_proc_init); ++ + module_param(timeout, uint, 0); + MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); + +diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h +new file mode 100644 +index 000000000000..f4a698a22880 +--- /dev/null ++++ b/include/linux/wakelock.h +@@ -0,0 +1,67 @@ ++/* include/linux/wakelock.h ++ * ++ * Copyright (C) 2007-2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_WAKELOCK_H ++#define _LINUX_WAKELOCK_H ++ ++#include ++#include ++ ++/* A wake_lock prevents the system from entering suspend or other low power ++ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock ++ * prevents a full system suspend. ++ */ ++ ++enum { ++ WAKE_LOCK_SUSPEND, /* Prevent suspend */ ++ WAKE_LOCK_TYPE_COUNT ++}; ++ ++struct wake_lock { ++ struct wakeup_source ws; ++}; ++ ++static inline void wake_lock_init(struct wake_lock *lock, int type, ++ const char *name) ++{ ++ wakeup_source_init(&lock->ws, name); ++} ++ ++static inline void wake_lock_destroy(struct wake_lock *lock) ++{ ++ wakeup_source_trash(&lock->ws); ++} ++ ++static inline void wake_lock(struct wake_lock *lock) ++{ ++ __pm_stay_awake(&lock->ws); ++} ++ ++static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) ++{ ++ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); ++} ++ ++static inline void wake_unlock(struct wake_lock *lock) ++{ ++ __pm_relax(&lock->ws); ++} ++ ++static inline int wake_lock_active(struct wake_lock *lock) ++{ ++ return lock->ws.active; ++} ++ ++#endif +diff --git a/include/net/genetlink.h b/include/net/genetlink.h +index decf6012a401..6471da92334a 100644 +--- a/include/net/genetlink.h ++++ b/include/net/genetlink.h +@@ -144,6 +144,50 @@ struct genl_ops { + }; + + int genl_register_family(struct genl_family *family); ++ ++/** ++ * genl_register_family_with_ops - register a generic netlink family with ops ++ * @family: generic netlink family ++ * @ops: operations to be registered ++ * @n_ops: number of elements to register ++ * ++ * Registers the specified family and operations from the specified table. ++ * Only one family may be registered with the same family name or identifier. ++ * ++ * The family id may equal GENL_ID_GENERATE causing an unique id to ++ * be automatically generated and assigned. ++ * ++ * Either a doit or dumpit callback must be specified for every registered ++ * operation or the function will fail. Only one operation structure per ++ * command identifier may be registered. ++ * ++ * See include/net/genetlink.h for more documenation on the operations ++ * structure. ++ * ++ * Return 0 on success or a negative error code. ++ */ ++static inline int ++_genl_register_family_with_ops_grps(struct genl_family *family, ++ const struct genl_ops *ops, size_t n_ops, ++ const struct genl_multicast_group *mcgrps, ++ size_t n_mcgrps) ++{ ++ family->module = THIS_MODULE; ++ family->ops = ops; ++ family->n_ops = n_ops; ++ family->mcgrps = mcgrps; ++ family->n_mcgrps = n_mcgrps; ++ return genl_register_family(family); ++} ++#define genl_register_family_with_ops(family, ops) \ ++ _genl_register_family_with_ops_grps((family), \ ++ (ops), ARRAY_SIZE(ops), \ ++ NULL, 0) ++#define genl_register_family_with_ops_groups(family, ops, grps) \ ++ _genl_register_family_with_ops_grps((family), \ ++ (ops), ARRAY_SIZE(ops), \ ++ (grps), ARRAY_SIZE(grps)) ++ + int genl_unregister_family(const struct genl_family *family); + void genl_notify(const struct genl_family *family, struct sk_buff *skb, + struct genl_info *info, u32 group, gfp_t flags); +diff --git a/include/soc/mediatek/pmic_wrap.h b/include/soc/mediatek/pmic_wrap.h +new file mode 100644 +index 000000000000..5b5c85272c58 +--- /dev/null ++++ b/include/soc/mediatek/pmic_wrap.h +@@ -0,0 +1,19 @@ ++/* ++ * Copyright (C) 2015 MediaTek Inc. ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __SOC_MEDIATEK_PMIC_WRAP_H ++#define __SOC_MEDIATEK_PMIC_WRAP_H ++ ++extern struct regmap *pwrap_node_to_regmap(struct device_node *np); ++ ++#endif /* __SOC_MEDIATEK_PMIC_WRAP_H */ +diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h +index 877f7fa95466..6a176b3d43f9 100644 +--- a/include/uapi/linux/genetlink.h ++++ b/include/uapi/linux/genetlink.h +@@ -27,6 +27,7 @@ struct genlmsghdr { + /* + * List of reserved static generic netlink identifiers: + */ ++#define GENL_ID_GENERATE 0 + #define GENL_ID_CTRL NLMSG_MIN_TYPE + #define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) + #define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch b/root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch new file mode 100755 index 00000000..ed80e2bb --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch @@ -0,0 +1,78 @@ +From 203a5a7727a80ab519ea00181a909e415c5567ab Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 29 Aug 2018 19:17:00 +0200 +Subject: [PATCH 08/77] [gcc] gcc8-fixes by Dominik Koch + nic_rx-patch from + https://bugs.linaro.org/show_bug.cgi?id=3823 + +--- + .../misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c | 10 ++++++---- + .../misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c | 2 +- + .../connectivity/wlan/gen2/os/linux/include/gl_kal.h | 2 +- + 3 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c +index ba4840414da8..65823023cec0 100644 +--- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c +@@ -2061,7 +2061,6 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb + case EVENT_ID_BT_OVER_WIFI: + #if CFG_ENABLE_BT_OVER_WIFI + { +- UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; + P_EVENT_BT_OVER_WIFI prEventBtOverWifi; + P_AMPC_EVENT prBowEvent; + P_BOW_LINK_CONNECTED prBowLinkConnected; +@@ -2069,11 +2068,11 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb + + prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); + +- /* construct event header */ +- prBowEvent = (P_AMPC_EVENT) aucTmp; +- + if (prEventBtOverWifi->ucLinkStatus == 0) { + /* Connection */ ++ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)]; ++ /* construct event header */ ++ prBowEvent = (P_AMPC_EVENT) aucTmp; + prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; + prBowEvent->rHeader.ucSeqNumber = 0; + prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); +@@ -2086,6 +2085,9 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb + kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); + } else { + /* Disconnection */ ++ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; ++ /* construct event header */ ++ prBowEvent = (P_AMPC_EVENT) aucTmp; + prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; + prBowEvent->rHeader.ucSeqNumber = 0; + prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c +index dd00859d4608..ad7107b1d9a4 100644 +--- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c +@@ -5021,7 +5021,7 @@ VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) + if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { + if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ + prBssInfo->prStaRecOfAP->aucMacAddr)) { +- strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ ++ memcpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ + DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", + apIp[0], apIp[1], apIp[2], apIp[3]); + } +diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h +index 1406905095e6..b1386918c08d 100644 +--- a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h +@@ -852,7 +852,7 @@ struct KAL_HALT_CTRL_T { + + /* string operation */ + #define kalStrCpy(dest, src) strcpy(dest, src) +-#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) ++#define kalStrnCpy(dest, src, n) memcpy(dest, src, n) + #define kalStrCmp(ct, cs) strcmp(ct, cs) + #define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) + #define kalStrChr(s, c) strchr(s, c) +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch b/root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch new file mode 100755 index 00000000..02d55f18 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch @@ -0,0 +1,52 @@ +From b3bf5911a5d9f6eb8112d294ffaf5f474dccc686 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 23 Oct 2018 13:31:20 +0200 +Subject: [PATCH 09/77] [wifi] activated wifi-options + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 09df75013c09..fe7532886ccc 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -141,8 +141,8 @@ CONFIG_NF_LOG_IPV6=m + CONFIG_NF_REJECT_IPV6=m + CONFIG_IP_NF_NAT=m + CONFIG_IP6_NF_NAT=m +-CONFIG_NF_NAT_MASQUERADE_IPV4=m +-CONFIG_NF_NAT_MASQUERADE_IPV6=m ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y + CONFIG_IP_NF_FILTER=m + CONFIG_IP6_NF_FILTER=m + CONFIG_IP_NF_TARGET_MASQUERADE=m +@@ -376,17 +376,17 @@ CONFIG_CFG80211=y + + #internal wlan (not working yet) + # CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set +-#CONFIG_MTK_COMBO=y +-#CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y ++CONFIG_MTK_COMBO=y ++CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y + #used in 4.4, but should be set in Kconfig by selecting mt7623 COMBO +-#CONFIG_MTK_PLATFORM="mt7623" ++CONFIG_MTK_PLATFORM="mt7623" + +-#CONFIG_MTK_COMBO_COMM=y +-#CONFIG_MTK_COMBO_WIFI=y +-#CONFIG_NL80211_TESTMODE=y ++CONFIG_MTK_COMBO_COMM=y ++CONFIG_MTK_COMBO_WIFI=y ++CONFIG_NL80211_TESTMODE=y + + #internal Bluetooth (also not working yet) +-#CONFIG_BT=y ++CONFIG_BT=y + #CONFIG_MTK_COMBO_BT=y + #CONFIG_MTK_COMBO_BT_HCI=y + #needed for BT? +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch b/root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch new file mode 100755 index 00000000..829e2c89 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch @@ -0,0 +1,34 @@ +From ec64b17f37390c32cd88ebddbabd423f438335fc Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 11 Nov 2018 09:52:44 +0100 +Subject: [PATCH 12/77] [defconfig] add missing CONFIG_PCI_MSI (needed for pcie + and maybe sata) and EARLY_PRINTK + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index d7741650941f..fe1edaa7680f 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -1,6 +1,8 @@ + CONFIG_LOCALVERSION="-bpi-r2" + CONFIG_LOCALVERSION_AUTO=n + ++CONFIG_EARLY_PRINTK=y ++ + #spectre/meltdown + CONFIG_PAGE_TABLE_ISOLATION=y + +@@ -58,6 +60,7 @@ CONFIG_PL310_ERRATA_753970=y + CONFIG_PL310_ERRATA_769419=y + + CONFIG_PCI=y ++CONFIG_PCI_MSI=y + CONFIG_SMP=y + CONFIG_HAVE_ARM_ARCH_TIMER=y + CONFIG_NR_CPUS=16 +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch b/root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch new file mode 100755 index 00000000..33a9e095 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch @@ -0,0 +1,34 @@ +From 961d318c99fb0019f0fa571a160af09e859d63e8 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Mon, 31 Dec 2018 17:00:56 +0100 +Subject: [PATCH 14/77] [dts] set mac-address (eth0) + +can be overwritten by uboot (ethaddr) if using separated fdt +or devicetree-overlay +--- + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 465fb887b2ca..a47022765326 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -15,6 +15,7 @@ + + aliases { + serial2 = &uart2; ++ ethernet0 = &gmac0; + }; + + chosen { +@@ -147,6 +148,7 @@ + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "trgmii"; ++ mac-address = [02 02 02 02 02 02]; + + fixed-link { + speed = <1000>; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch b/root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch new file mode 100755 index 00000000..92638e53 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch @@ -0,0 +1,40 @@ +From d226d27f0419a6d1f2fa42abbf67eb4315223372 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 5 Jan 2019 10:11:41 +0100 +Subject: [PATCH 16/77] [build.sh,dts] added devicetree-Overlay + +compile bpi-r2-mac.dts like this: + +dtc -@ -I dts -O dtb -o bpi-r2-mac.dtb bpi-r2-mac.dts + +in uboot you can load DTO with this (after loading base ftd): +loaddto=echo "loaddto:${dto}";fdt addr ${dtaddr};fdt resize 8192; setexpr fdtovaddr ${dtaddr} + F000; + fatload ${device} ${partition} ${fdtovaddr} ${bpi}/${board}/${service}/dtb/${dto} && fdt apply ${fdtovaddr} + +uboot needs option CONFIG_OF_LIBFDT_OVERLAY=y +--- + bpi-r2-mac.dts | 12 ++++++++++++ + 1 files changed, 12 insertions(+) + create mode 100644 bpi-r2-mac.dts + +diff --git a/bpi-r2-mac.dts b/bpi-r2-mac.dts +new file mode 100644 +index 000000000000..f4eed976e158 +--- /dev/null ++++ b/bpi-r2-mac.dts +@@ -0,0 +1,12 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ fragment@0 { ++ /*target = <&gmac0>;*/ ++ target-path = "/eth/gmac0"; ++ __overlay__ { ++ mac-address = [02 01 02 03 04 05]; ++ }; ++ }; ++}; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch b/root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch new file mode 100755 index 00000000..f8e8812a --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch @@ -0,0 +1,60 @@ +From 329ff45aafea77cd9f5c97d2988e7c399ef05d6d Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 29 Nov 2018 11:34:09 +0100 +Subject: [PATCH 19/77] net: dsa: adding fields for holding information about + upstream-port + +for multiple cpu-Ports aech port needs storing the the cpu-port to be used +this Patch adds the needed fields for this + +based on +https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch + +Signed-off-by: Frank Wunderlich +--- + include/net/dsa.h | 4 ++++ + net/dsa/dsa_priv.h | 5 +++++ + 2 files changed, 9 insertions(+) + +diff --git a/include/net/dsa.h b/include/net/dsa.h +index 461e8a7661b7..6e0c95625a21 100644 +--- a/include/net/dsa.h ++++ b/include/net/dsa.h +@@ -202,6 +202,10 @@ struct dsa_port { + struct net_device *bridge_dev; + struct devlink_port devlink_port; + struct phylink *pl; ++ ++ struct net_device *ethernet; ++ int upstream; ++ + /* + * Original copy of the master netdev ethtool_ops + */ +diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h +index 3964c6f7a7c0..559a3a250c88 100644 +--- a/net/dsa/dsa_priv.h ++++ b/net/dsa/dsa_priv.h +@@ -81,6 +81,8 @@ struct dsa_slave_priv { + + /* TC context */ + struct list_head mall_tc_list; ++ ++ struct net_device *master; + }; + + /* dsa.c */ +@@ -187,7 +189,10 @@ static inline struct net_device * + dsa_slave_to_master(const struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); ++ struct dsa_slave_priv *p = netdev_priv(dev); + ++ if (p->master) ++ return p->master; + return dp->cpu_dp->master; + } + +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch b/root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch new file mode 100755 index 00000000..feb001f8 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch @@ -0,0 +1,86 @@ +From 90adf38283688d8c25feeb7e3989cc2da3d58122 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 29 Nov 2018 11:27:12 +0100 +Subject: [PATCH 20/77] net: dsa: add helper functions + +for using mutliple cpu-Ports 3 additional functions are defined to read +dts-option (dsa_user_parse) and check if current port is a upstream-port +(dsa_port_upstream_port, dsa_is_upstream_port) + +based on +https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch + +Signed-off-by: Frank Wunderlich +--- + include/net/dsa.h | 18 ++++++++++++++++++ + net/dsa/dsa2.c | 18 ++++++++++++++++++ + 2 files changed, 36 insertions(+) + +diff --git a/include/net/dsa.h b/include/net/dsa.h +index 6e0c95625a21..36db2ee83da6 100644 +--- a/include/net/dsa.h ++++ b/include/net/dsa.h +@@ -318,6 +318,12 @@ static inline unsigned int dsa_towards_port(struct dsa_switch *ds, int device, + return ds->rtable[device]; + } + ++ ++static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p) ++{ ++ return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p); ++} ++ + /* Return the local port used to reach the dedicated CPU port */ + static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port) + { +@@ -330,6 +336,18 @@ static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port) + return dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index); + } + ++static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port) ++{ ++ /* ++ * If this port has a specific upstream cpu port, use it, ++ * otherwise use the switch default. ++ */ ++ if (ds->ports[port].upstream) ++ return ds->ports[port].upstream; ++ else ++ return dsa_upstream_port(ds, port); ++} ++ + typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid, + bool is_static, void *data); + struct dsa_switch_ops { +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index a1917025e155..b7c6da2f1f08 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -255,6 +255,24 @@ static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst) + dst->cpu_dp = NULL; + } + ++static int dsa_user_parse(struct dsa_port *port, u32 index, ++ struct dsa_switch *ds) ++{ ++ struct device_node *cpu_port; ++ const unsigned int *cpu_port_reg; ++ int cpu_port_index; ++ ++ cpu_port = of_parse_phandle(port->dn, "default_cpu", 0); ++ if (cpu_port) { ++ cpu_port_reg = of_get_property(cpu_port, "reg", NULL); ++ if (!cpu_port_reg) ++ return -EINVAL; ++ cpu_port_index = be32_to_cpup(cpu_port_reg); ++ ds->ports[index].upstream = cpu_port_index; ++ } ++ return 0; ++} ++ + static int dsa_port_setup(struct dsa_port *dp) + { + struct dsa_switch *ds = dp->ds; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch b/root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch new file mode 100755 index 00000000..8b5a9730 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch @@ -0,0 +1,102 @@ +From 8325a7cbf9648725163a7596ba3381775039fe69 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 29 Nov 2018 11:38:27 +0100 +Subject: [PATCH 21/77] net: dsa: adding handling of second CPU-Port + +this patch adds the core-functionality of multiple cpu-ports + +currently it uses definition in dts to make connection between cpu and user-port + +based on +https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch + +Signed-off-by: Frank Wunderlich +--- + net/dsa/dsa2.c | 18 ++++++++++++++++++ + net/dsa/slave.c | 3 ++- + 2 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index b7c6da2f1f08..8f64535fd2a0 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -303,6 +303,8 @@ static int dsa_port_setup(struct dsa_port *dp) + ds->index, dp->index); + return err; + } ++ if (dp->master) ++ dp->master->dsa_ptr = dp; + break; + case DSA_PORT_TYPE_DSA: + /* dp->index is used now as port_number. However +@@ -323,12 +325,17 @@ static int dsa_port_setup(struct dsa_port *dp) + devlink_port_attrs_set(&dp->devlink_port, + DEVLINK_PORT_FLAVOUR_PHYSICAL, + dp->index, false, 0); ++ err = dsa_user_parse(dp, dp->index, ds); ++ if (err) ++ return err; ++ + err = dsa_slave_create(dp); + if (err) + dev_err(ds->dev, "failed to create slave for port %d.%d\n", + ds->index, dp->index); + else + devlink_port_type_eth_set(&dp->devlink_port, dp->slave); ++ + break; + } + +@@ -344,6 +351,14 @@ static void dsa_port_teardown(struct dsa_port *dp) + case DSA_PORT_TYPE_UNUSED: + break; + case DSA_PORT_TYPE_CPU: ++ dsa_port_link_unregister_of(dp); ++ if (dp->master) ++ dp->master->dsa_ptr = NULL; ++ if (dp->ethernet) { ++ dev_put(dp->ethernet); ++ dp->ethernet = NULL; ++ } ++ break; + case DSA_PORT_TYPE_DSA: + dsa_port_link_unregister_of(dp); + break; +@@ -598,6 +613,9 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) + dp->master = master; + dp->dst = dst; + ++ dev_hold(master); ++ ds->ports[dp->index].ethernet = master; ++ + return 0; + } + +diff --git a/net/dsa/slave.c b/net/dsa/slave.c +index 1c45c1d6d241..3bdbd53d3420 100644 +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -1291,11 +1291,11 @@ static void dsa_slave_notify(struct net_device *dev, unsigned long val) + int dsa_slave_create(struct dsa_port *port) + { + const struct dsa_port *cpu_dp = port->cpu_dp; +- struct net_device *master = cpu_dp->master; + struct dsa_switch *ds = port->ds; + const char *name = port->name; + struct net_device *slave_dev; + struct dsa_slave_priv *p; ++ struct net_device *master = ds->ports[port->upstream].ethernet; + int ret; + + if (!ds->num_tx_queues) +@@ -1334,6 +1334,7 @@ int dsa_slave_create(struct dsa_port *port) + p->dp = port; + INIT_LIST_HEAD(&p->mall_tc_list); + p->xmit = cpu_dp->tag_ops->xmit; ++ p->master = master; + port->slave = slave_dev; + + netif_carrier_off(slave_dev); +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch b/root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch new file mode 100755 index 00000000..ade0497f --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch @@ -0,0 +1,34 @@ +From a80c992c93729c817267ea5575faa089a278e593 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 8 Dec 2018 19:22:22 +0100 +Subject: [PATCH 22/77] net: dsa: add support for GMAC2 wired to ext + +cpu-ports of mt7530 need some special flags to be set + +based on +https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch + +Signed-off-by: Frank Wunderlich +--- + drivers/net/dsa/mt7530.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index 62e486652e62..8ed0af6abe7d 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -1281,6 +1281,11 @@ mt7530_setup(struct dsa_switch *ds) + val = mt7530_read(priv, MT7530_MHWTRAP); + val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; + val |= MHWTRAP_MANUAL; ++ if (!dsa_is_cpu_port(ds, 5)) { ++ val |= MHWTRAP_P5_DIS; ++ val |= MHWTRAP_P5_MAC_SEL; ++ val |= MHWTRAP_P5_RGMII_MODE; ++ } + mt7530_write(priv, MT7530_MHWTRAP, val); + + /* Enable and reset MIB counters */ +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch b/root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch new file mode 100755 index 00000000..5a08b31e --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch @@ -0,0 +1,121 @@ +From 954b359077f770bdbb376db571a4710965684dc9 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 8 Dec 2018 19:25:57 +0100 +Subject: [PATCH 23/77] net: dsa: dsa multi cpu (mt7530.c) + +implementing changes to mt7530 switch driver for supporting multiple (2) +cpu-ports + +based on +https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch + +Signed-off-by: Frank Wunderlich +--- + drivers/net/dsa/mt7530.c | 34 +++++++++++++++++++--------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index 8ed0af6abe7d..fda1b67dfeac 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -678,6 +678,9 @@ static int + mt7530_cpu_port_enable(struct mt7530_priv *priv, + int port) + { ++ u8 port_mask = 0; ++ int i; ++ + /* Enable Mediatek header mode on the cpu port */ + mt7530_write(priv, MT7530_PVC_P(port), + PORT_SPEC_TAG); +@@ -694,8 +697,14 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv, + /* CPU port gets connected to all user ports of + * the switch + */ ++ ++ for (i = 0; i < MT7530_NUM_PORTS; i++) ++ if ((priv->ds->ports[port].type == DSA_PORT_TYPE_USER) && ++ (dsa_port_upstream_port(priv->ds, i) == port)) ++ port_mask |= BIT(i); ++ + mt7530_write(priv, MT7530_PCR_P(port), +- PCR_MATRIX(dsa_user_ports(priv->ds))); ++ PCR_MATRIX(port_mask)); + + return 0; + } +@@ -705,6 +714,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port, + struct phy_device *phy) + { + struct mt7530_priv *priv = ds->priv; ++ u8 upstream = dsa_port_upstream_port(ds, port); + + mutex_lock(&priv->reg_mutex); + +@@ -715,7 +725,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port, + * restore the port matrix if the port is the member of a certain + * bridge. + */ +- priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT)); ++ priv->ports[port].pm |= PCR_MATRIX(BIT(upstream)); + priv->ports[port].enable = true; + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, + priv->ports[port].pm); +@@ -778,7 +788,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port, + struct net_device *bridge) + { + struct mt7530_priv *priv = ds->priv; +- u32 port_bitmap = BIT(MT7530_CPU_PORT); ++ u8 upstream = dsa_port_upstream_port(ds, port); ++ u32 port_bitmap = BIT(upstream); + int i; + + mutex_lock(&priv->reg_mutex); +@@ -879,6 +890,7 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, + struct net_device *bridge) + { + struct mt7530_priv *priv = ds->priv; ++ u8 upstream = dsa_port_upstream_port(ds, port); + int i; + + mutex_lock(&priv->reg_mutex); +@@ -906,8 +918,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, + */ + if (priv->ports[port].enable) + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, +- PCR_MATRIX(BIT(MT7530_CPU_PORT))); +- priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT)); ++ PCR_MATRIX(BIT(upstream))); ++ priv->ports[port].pm = PCR_MATRIX(BIT(upstream)); + + mt7530_port_set_vlan_unaware(ds, port); + +@@ -1198,15 +1210,7 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port, + static enum dsa_tag_protocol + mtk_get_tag_protocol(struct dsa_switch *ds, int port) + { +- struct mt7530_priv *priv = ds->priv; +- +- if (port != MT7530_CPU_PORT) { +- dev_warn(priv->dev, +- "port not matched with tagging CPU port\n"); +- return DSA_TAG_PROTO_NONE; +- } else { +- return DSA_TAG_PROTO_MTK; +- } ++ return DSA_TAG_PROTO_MTK; + } + + static int +@@ -1279,7 +1283,7 @@ mt7530_setup(struct dsa_switch *ds) + + /* Enable Port 6 only; P5 as GMAC5 which currently is not supported */ + val = mt7530_read(priv, MT7530_MHWTRAP); +- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; ++ val &= ~MHWTRAP_P5_DIS & ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; + val |= MHWTRAP_MANUAL; + if (!dsa_is_cpu_port(ds, 5)) { + val |= MHWTRAP_P5_DIS; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch b/root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch new file mode 100755 index 00000000..00e6a555 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch @@ -0,0 +1,54 @@ +From 943ed2bae585cd595d8264a1f37fa3f3d5a5715b Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 8 Dec 2018 20:59:09 +0100 +Subject: [PATCH 24/77] net: dsa: tell GDMA when we are turning on the special + tag + +Enabling this bit will make the RX DMA descriptor enable the SP bit for +all ingress traffic inside the return descriptor. The PPE needs this to +know that a SP is present. + +based on +https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch + +Signed-off-by: Frank Wunderlich +--- + drivers/net/dsa/mt7530.c | 6 ++++++ + drivers/net/dsa/mt7530.h | 4 ++++ + 2 files changed, 10 insertions(+) + +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index fda1b67dfeac..9690a9b59fce 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -685,6 +685,12 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv, + mt7530_write(priv, MT7530_PVC_P(port), + PORT_SPEC_TAG); + ++ /* Enable Mediatek header mode on the GMAC that the cpu port ++ * connects to ++ */ ++ regmap_write_bits(priv->ethernet, MTK_GDMA_FWD_CFG(port), ++ GDMA_SPEC_TAG, GDMA_SPEC_TAG); ++ + /* Setup the MAC by default for the cpu port */ + mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPUP_LINK); + +diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h +index d9b407a22a58..310f2536175b 100644 +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -23,6 +23,10 @@ + + #define TRGMII_BASE(x) (0x10000 + (x)) + ++/* Registers for GDMA configuration access */ ++#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) ++#define GDMA_SPEC_TAG BIT(24) ++ + /* Registers to ethsys access */ + #define ETHSYS_CLKCFG0 0x2c + #define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11) +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch b/root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch new file mode 100755 index 00000000..117dd7b5 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch @@ -0,0 +1,47 @@ +From 0f5ff06adcb20916acaf55976975a8b8844e785a Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 8 Dec 2018 20:59:40 +0100 +Subject: [PATCH 25/77] net: dsa: mt7530 add linking to mdio + +switch (7530) needs to to be linked to mdio-bus + +based on +https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0045-net-dsa-mediatek-turn-into-platform-driver.patch + +Signed-off-by: Frank Wunderlich +--- + drivers/net/dsa/mt7530.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index 9690a9b59fce..8f95e22a33f6 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -1349,7 +1349,7 @@ static int + mt7530_probe(struct mdio_device *mdiodev) + { + struct mt7530_priv *priv; +- struct device_node *dn; ++ struct device_node *dn, *mdio; + + dn = mdiodev->dev.of_node; + +@@ -1396,8 +1396,14 @@ mt7530_probe(struct mdio_device *mdiodev) + return PTR_ERR(priv->reset); + } + } ++ mdio = of_get_parent(dn); ++ if (!mdio) ++ return -EINVAL; ++ ++ priv->bus = of_mdio_find_bus(mdio); ++ if (!priv->bus) ++ return -EPROBE_DEFER; + +- priv->bus = mdiodev->bus; + priv->dev = &mdiodev->dev; + priv->ds->priv = priv; + priv->ds->ops = &mt7530_switch_ops; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch b/root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch new file mode 100755 index 00000000..e3d37c86 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch @@ -0,0 +1,81 @@ +From 52365639697e10f1b641d25460c10d9ccc56a6d6 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 29 Nov 2018 10:53:44 +0100 +Subject: [PATCH 26/77] net: dsa: changes to dts + +--- + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 29 ++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index a47022765326..4c6e53d9e736 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -157,6 +157,18 @@ + }; + }; + ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; +@@ -175,29 +187,44 @@ + port@0 { + reg = <0>; + label = "wan"; ++ default_cpu = <&cpu_port1>; + }; + + port@1 { + reg = <1>; + label = "lan0"; ++ default_cpu = <&cpu_port0>; + }; + + port@2 { + reg = <2>; + label = "lan1"; ++ default_cpu = <&cpu_port0>; + }; + + port@3 { + reg = <3>; + label = "lan2"; ++ default_cpu = <&cpu_port0>; + }; + + port@4 { + reg = <4>; + label = "lan3"; ++ default_cpu = <&cpu_port0>; + }; + +- port@6 { ++ cpu_port1: port@5 { ++ reg = <5>; ++ label = "cpu"; ++ ethernet = <&gmac1>; ++ phy-mode = "trgmii"; ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ cpu_port0: port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch b/root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch new file mode 100755 index 00000000..375741bc --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch @@ -0,0 +1,171 @@ +From 49f64db56f05dc7ccb1d8836c19243b5620fc93d Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:41 +0800 +Subject: [PATCH 27/77] drm/mediatek: add refcount for DPI power on/off + +After the kernel 4.4, the DRM disable flow was changed, if DPI was +disableed before CRTC, it will cause warning message as following: + +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 1339 at ../../linux/linux-4.4.24-mtk/drivers/gpu/drm/drm_irq.c:1326 drm_wait_one_vblank+0x188/0x18c() +vblank wait timed out on crtc 0 +Modules linked in: bridge mt8521p_ir_shim(O) i2c_eeprom(O) mtk_m4(O) fuse_ctrl(O) virtual_block(O) caamkeys(PO) chk(PO) amperctl(O) ledctl(O) apple_auth(PO) micctl(O) sensors(PO) lla(O) sdd(PO) ice40_fpga(O) psmon(O) event_queue(PO) utils(O) blackbox(O) +CPU: 0 PID: 1339 Comm: kworker/0:1 Tainted: P W O 4.4.24 #1 +Hardware name: Mediatek Cortex-A7 (Device Tree) +Workqueue: events drm_mode_rmfb_work_fn +[] (unwind_backtrace) from [] (show_stack+0x20/0x24) +[] (show_stack) from [] (dump_stack+0x98/0xac) +[] (dump_stack) from [] (warn_slowpath_common+0x94/0xc4) +[] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x40/0x48) +[] (warn_slowpath_fmt) from [] (drm_wait_one_vblank+0x188/0x18c) +[] (drm_wait_one_vblank) from [] (drm_crtc_wait_one_vblank+0x28/0x2c) +[] (drm_crtc_wait_one_vblank) from [] (mtk_drm_crtc_disable+0x78/0x240) +[] (mtk_drm_crtc_disable) from [] (drm_atomic_helper_commit_modeset_disables+0x128/0x3b8) +[] (drm_atomic_helper_commit_modeset_disables) from [] (mtk_atomic_complete+0x74/0xb4) +[] (mtk_atomic_complete) from [] (mtk_atomic_commit+0x68/0x98) +[] (mtk_atomic_commit) from [] (drm_atomic_commit+0x54/0x74) +[] (drm_atomic_commit) from [] (drm_atomic_helper_set_config+0x7c/0xa0) +[] (drm_atomic_helper_set_config) from [] (drm_mode_set_config_internal+0x68/0xe4) +[] (drm_mode_set_config_internal) from [] (drm_framebuffer_remove+0xe4/0x120) +[] (drm_framebuffer_remove) from [] (drm_mode_rmfb_work_fn+0x48/0x58) +[] (drm_mode_rmfb_work_fn) from [] (process_one_work+0x154/0x50c) +[] (process_one_work) from [] (worker_thread+0x284/0x568) +[] (worker_thread) from [] (kthread+0xec/0x104) +[] (kthread) from [] (ret_from_fork+0x14/0x3c) +---[ end trace 12ae5358e992abd5 ]--- + +so, we add refcount for DPI power on/off to protect the flow. + +Signed-off-by: Bibby Hsieh +Signed-off-by: chunhui dai +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 43 +++++++++--------------------- + 1 file changed, 13 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 6c0ea39d5739..5ede1ddbaa1a 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -76,8 +76,7 @@ struct mtk_dpi { + enum mtk_dpi_out_yc_map yc_map; + enum mtk_dpi_out_bit_num bit_num; + enum mtk_dpi_out_channel_swap channel_swap; +- bool power_sta; +- u8 power_ctl; ++ int refcount; + }; + + static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e) +@@ -90,11 +89,6 @@ enum mtk_dpi_polarity { + MTK_DPI_POLARITY_FALLING, + }; + +-enum mtk_dpi_power_ctl { +- DPI_POWER_START = BIT(0), +- DPI_POWER_ENABLE = BIT(1), +-}; +- + struct mtk_dpi_polarities { + enum mtk_dpi_polarity de_pol; + enum mtk_dpi_polarity ck_pol; +@@ -367,40 +361,30 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, + } + } + +-static void mtk_dpi_power_off(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) ++static void mtk_dpi_power_off(struct mtk_dpi *dpi) + { +- dpi->power_ctl &= ~pctl; +- +- if ((dpi->power_ctl & DPI_POWER_START) || +- (dpi->power_ctl & DPI_POWER_ENABLE)) ++ if (WARN_ON(dpi->refcount == 0)) + return; + +- if (!dpi->power_sta) ++ if (--dpi->refcount != 0) + return; + + mtk_dpi_disable(dpi); + clk_disable_unprepare(dpi->pixel_clk); + clk_disable_unprepare(dpi->engine_clk); +- dpi->power_sta = false; + } + +-static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) ++static int mtk_dpi_power_on(struct mtk_dpi *dpi) + { + int ret; + +- dpi->power_ctl |= pctl; +- +- if (!(dpi->power_ctl & DPI_POWER_START) && +- !(dpi->power_ctl & DPI_POWER_ENABLE)) +- return 0; +- +- if (dpi->power_sta) ++ if (++dpi->refcount != 1) + return 0; + + ret = clk_prepare_enable(dpi->engine_clk); + if (ret) { + dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret); +- goto err_eng; ++ goto err_refcount; + } + + ret = clk_prepare_enable(dpi->pixel_clk); +@@ -410,13 +394,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) + } + + mtk_dpi_enable(dpi); +- dpi->power_sta = true; + return 0; + + err_pixel: + clk_disable_unprepare(dpi->engine_clk); +-err_eng: +- dpi->power_ctl &= ~pctl; ++err_refcount: ++ dpi->refcount--; + return ret; + } + +@@ -552,14 +535,14 @@ static void mtk_dpi_encoder_disable(struct drm_encoder *encoder) + { + struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); + +- mtk_dpi_power_off(dpi, DPI_POWER_ENABLE); ++ mtk_dpi_power_off(dpi); + } + + static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) + { + struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); + +- mtk_dpi_power_on(dpi, DPI_POWER_ENABLE); ++ mtk_dpi_power_on(dpi); + mtk_dpi_set_display_mode(dpi, &dpi->mode); + } + +@@ -582,14 +565,14 @@ static void mtk_dpi_start(struct mtk_ddp_comp *comp) + { + struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); + +- mtk_dpi_power_on(dpi, DPI_POWER_START); ++ mtk_dpi_power_on(dpi); + } + + static void mtk_dpi_stop(struct mtk_ddp_comp *comp) + { + struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); + +- mtk_dpi_power_off(dpi, DPI_POWER_START); ++ mtk_dpi_power_off(dpi); + } + + static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = { +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch b/root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch new file mode 100755 index 00000000..fc67fb41 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch @@ -0,0 +1,101 @@ +From c2b3363773bfc93b3e4082ccfa99cda18ea980be Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:42 +0800 +Subject: [PATCH 28/77] drm/mediatek: move hardware register to node data + +The address of register DPI_H_FRE_CON is different in different IC. +Using of_node data to find this address. + +Reviewed-by: CK Hu +Signed-off-by: chunhui dai +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 19 ++++++++++++++++--- + drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 1 - + 2 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 5ede1ddbaa1a..72aa43187731 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -72,6 +73,7 @@ struct mtk_dpi { + struct clk *tvd_clk; + int irq; + struct drm_display_mode mode; ++ const struct mtk_dpi_conf *conf; + enum mtk_dpi_out_color_format color_format; + enum mtk_dpi_out_yc_map yc_map; + enum mtk_dpi_out_bit_num bit_num; +@@ -110,6 +112,10 @@ struct mtk_dpi_yc_limit { + u16 c_bottom; + }; + ++struct mtk_dpi_conf { ++ u32 reg_h_fre_con; ++}; ++ + static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask) + { + u32 tmp = readl(dpi->regs + offset) & ~mask; +@@ -335,7 +341,7 @@ static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable) + + static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi) + { +- mtk_dpi_mask(dpi, DPI_H_FRE_CON, H_FRE_2N, H_FRE_2N); ++ mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N); + } + + static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, +@@ -639,6 +645,10 @@ static const struct component_ops mtk_dpi_component_ops = { + .unbind = mtk_dpi_unbind, + }; + ++static const struct mtk_dpi_conf mt8173_conf = { ++ .reg_h_fre_con = 0xe0, ++}; ++ + static int mtk_dpi_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -653,6 +663,7 @@ static int mtk_dpi_probe(struct platform_device *pdev) + return -ENOMEM; + + dpi->dev = dev; ++ dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dpi->regs = devm_ioremap_resource(dev, mem); +@@ -732,8 +743,10 @@ static int mtk_dpi_remove(struct platform_device *pdev) + } + + static const struct of_device_id mtk_dpi_of_ids[] = { +- { .compatible = "mediatek,mt8173-dpi", }, +- {} ++ { .compatible = "mediatek,mt8173-dpi", ++ .data = &mt8173_conf, ++ }, ++ { }, + }; + + struct platform_driver mtk_dpi_driver = { +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h +index 4b6ad4751a31..040444d7718d 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h ++++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h +@@ -223,6 +223,5 @@ + #define ESAV_CODE2 (0xFFF << 0) + #define ESAV_CODE3_MSB BIT(16) + +-#define DPI_H_FRE_CON 0xE0 + #define H_FRE_2N BIT(25) + #endif /* __MTK_DPI_REGS_H */ +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch b/root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch new file mode 100755 index 00000000..71118456 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch @@ -0,0 +1,62 @@ +From d0b9bb15fad38e8328f9436501e36697e4e1a89d Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:43 +0800 +Subject: [PATCH 29/77] drm/mediatek: adjust EDGE to match clock and data + +The default timing of DPI data and clock is not match. +We could adjust this bit to make them match. + +Signed-off-by: chunhui dai +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++++++++ + drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 1 + + 2 files changed, 9 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 72aa43187731..0ce4b61efaeb 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -114,6 +114,7 @@ struct mtk_dpi_yc_limit { + + struct mtk_dpi_conf { + u32 reg_h_fre_con; ++ bool edge_sel_en; + }; + + static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask) +@@ -344,6 +345,12 @@ static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi) + mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N); + } + ++static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) ++{ ++ if (dpi->conf->edge_sel_en) ++ mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN); ++} ++ + static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, + enum mtk_dpi_out_color_format format) + { +@@ -507,6 +514,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, + mtk_dpi_config_yc_map(dpi, dpi->yc_map); + mtk_dpi_config_color_format(dpi, dpi->color_format); + mtk_dpi_config_2n_h_fre(dpi); ++ mtk_dpi_config_disable_edge(dpi); + mtk_dpi_sw_reset(dpi, false); + + return 0; +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h +index 040444d7718d..d9db8c4cacd7 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h ++++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h +@@ -223,5 +223,6 @@ + #define ESAV_CODE2 (0xFFF << 0) + #define ESAV_CODE3_MSB BIT(16) + ++#define EDGE_SEL_EN BIT(5) + #define H_FRE_2N BIT(25) + #endif /* __MTK_DPI_REGS_H */ +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch b/root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch new file mode 100755 index 00000000..8977fbe6 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch @@ -0,0 +1,68 @@ +From 0a8f36a231341ac5d66c186bcb1600a5abc00132 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:44 +0800 +Subject: [PATCH 30/77] drm/mediatek: add clock factor for different IC + +different IC has different clock designed in HDMI, the factor for +calculate clock should be different. Usinng the data in of_node +to find this factor. + +Reviewed-by: CK Hu +Signed-off-by: chunhui dai +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 0ce4b61efaeb..0dbe9345fa2e 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -113,6 +113,7 @@ struct mtk_dpi_yc_limit { + }; + + struct mtk_dpi_conf { ++ unsigned int (*cal_factor)(int clock); + u32 reg_h_fre_con; + bool edge_sel_en; + }; +@@ -431,15 +432,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, + unsigned int factor; + + /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */ +- +- if (mode->clock <= 27000) +- factor = 3 << 4; +- else if (mode->clock <= 84000) +- factor = 3 << 3; +- else if (mode->clock <= 167000) +- factor = 3 << 2; +- else +- factor = 3 << 1; ++ factor = dpi->conf->cal_factor(mode->clock); + drm_display_mode_to_videomode(mode, &vm); + pll_rate = vm.pixelclock * factor; + +@@ -653,7 +646,20 @@ static const struct component_ops mtk_dpi_component_ops = { + .unbind = mtk_dpi_unbind, + }; + ++static unsigned int mt8173_calculate_factor(int clock) ++{ ++ if (clock <= 27000) ++ return 3 << 4; ++ else if (clock <= 84000) ++ return 3 << 3; ++ else if (clock <= 167000) ++ return 3 << 2; ++ else ++ return 3 << 1; ++} ++ + static const struct mtk_dpi_conf mt8173_conf = { ++ .cal_factor = mt8173_calculate_factor, + .reg_h_fre_con = 0xe0, + }; + +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch b/root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch new file mode 100755 index 00000000..25bd3912 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch @@ -0,0 +1,66 @@ +From ef9b74fc6412b2402f882b012f78bfb3031aa4c6 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:45 +0800 +Subject: [PATCH 31/77] drm/mediatek: convert dpi driver to use + drm_of_find_panel_or_bridge + +Convert dpi driver to use drm_of_find_panel_or_bridge. +This changes some error messages to debug messages (in the graph core). +Graph connections are often "no connects" depending on the particular +board, so we want to avoid spurious messages. Plus the kernel is not a +DT validator. +related links: +[1] https://lkml.org/lkml/2017/2/3/716 +[2] https://lkml.org/lkml/2017/2/3/719 + +Signed-off-by: chunhui dai +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 0dbe9345fa2e..08915e1765f8 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -668,7 +669,6 @@ static int mtk_dpi_probe(struct platform_device *pdev) + struct device *dev = &pdev->dev; + struct mtk_dpi *dpi; + struct resource *mem; +- struct device_node *bridge_node; + int comp_id; + int ret; + +@@ -714,16 +714,12 @@ static int mtk_dpi_probe(struct platform_device *pdev) + return -EINVAL; + } + +- bridge_node = of_graph_get_remote_node(dev->of_node, 0, 0); +- if (!bridge_node) +- return -ENODEV; +- +- dev_info(dev, "Found bridge node: %pOF\n", bridge_node); ++ ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, ++ NULL, &dpi->bridge); ++ if (ret) ++ return ret; + +- dpi->bridge = of_drm_find_bridge(bridge_node); +- of_node_put(bridge_node); +- if (!dpi->bridge) +- return -EPROBE_DEFER; ++ dev_info(dev, "Found bridge node: %pOF\n", dpi->bridge->of_node); + + comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); + if (comp_id < 0) { +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch b/root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch new file mode 100755 index 00000000..2aa37a7d --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch @@ -0,0 +1,76 @@ +From 5750b7268c5412e18a476482f92425eb0228564b Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:46 +0800 +Subject: [PATCH 32/77] drm/mediatek: add dpi driver for mt2701 and mt7623 + +This patch adds dpi dirver suppot for both mt2701 and mt7623. +And also support other (existing or future) chips that use +the same binding and driver. + +Reviewed-by: CK Hu +Signed-off-by: chunhui dai +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 21 +++++++++++++++++++++ + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++ + 2 files changed, 23 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 08915e1765f8..62a9d47df948 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -659,11 +659,29 @@ static unsigned int mt8173_calculate_factor(int clock) + return 3 << 1; + } + ++static unsigned int mt2701_calculate_factor(int clock) ++{ ++ if (clock <= 64000) ++ return 16; ++ else if (clock <= 128000) ++ return 8; ++ else if (clock <= 256000) ++ return 4; ++ else ++ return 2; ++} ++ + static const struct mtk_dpi_conf mt8173_conf = { + .cal_factor = mt8173_calculate_factor, + .reg_h_fre_con = 0xe0, + }; + ++static const struct mtk_dpi_conf mt2701_conf = { ++ .cal_factor = mt2701_calculate_factor, ++ .reg_h_fre_con = 0xb0, ++ .edge_sel_en = true, ++}; ++ + static int mtk_dpi_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -753,6 +771,9 @@ static int mtk_dpi_remove(struct platform_device *pdev) + } + + static const struct of_device_id mtk_dpi_of_ids[] = { ++ { .compatible = "mediatek,mt2701-dpi", ++ .data = &mt2701_conf, ++ }, + { .compatible = "mediatek,mt8173-dpi", + .data = &mt8173_conf, + }, +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +index 47ec604289b7..6422e99952fe 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +@@ -424,6 +424,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { + .data = (void *)MTK_DSI }, + { .compatible = "mediatek,mt8173-dsi", + .data = (void *)MTK_DSI }, ++ { .compatible = "mediatek,mt2701-dpi", ++ .data = (void *)MTK_DPI }, + { .compatible = "mediatek,mt8173-dpi", + .data = (void *)MTK_DPI }, + { .compatible = "mediatek,mt2701-disp-mutex", +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch b/root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch new file mode 100755 index 00000000..1c769415 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch @@ -0,0 +1,641 @@ +From 186643bd86d33f0a773139deb5af6e12354b5907 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:47 +0800 +Subject: [PATCH 33/77] drm/mediatek: separate hdmi phy to different file + +Different IC has different phy setting of HDMI. +This patch separates the phy hardware relate part for mt8173. + +Signed-off-by: chunhui dai +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/Makefile | 6 +- + drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 + + drivers/gpu/drm/mediatek/mtk_hdmi.h | 2 +- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 232 ++++++++++++++++++ + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 58 +++++ + .../gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 226 +---------------- + 6 files changed, 302 insertions(+), 223 deletions(-) + create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_phy.c + create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_phy.h + +diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile +index ce83c396a742..61cf0d2ab28a 100644 +--- a/drivers/gpu/drm/mediatek/Makefile ++++ b/drivers/gpu/drm/mediatek/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 ++ + mediatek-drm-y := mtk_disp_color.o \ + mtk_disp_ovl.o \ + mtk_disp_rdma.o \ +@@ -18,6 +19,7 @@ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o + mediatek-drm-hdmi-objs := mtk_cec.o \ + mtk_hdmi.o \ + mtk_hdmi_ddc.o \ +- mtk_mt8173_hdmi_phy.o ++ mtk_mt8173_hdmi_phy.o \ ++ mtk_hdmi_phy.o + +-obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o ++obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o +\ No newline at end of file +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c +index 643f5edd68fe..29bd2a144b19 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c +@@ -233,6 +233,7 @@ static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black) + static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable) + { + struct arm_smccc_res res; ++ struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(hdmi->phy); + + /* + * MT8173 HDMI hardware has an output control bit to enable/disable HDMI +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h +index 6371b3de1ff6..3e9fb8d19802 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.h +@@ -13,11 +13,11 @@ + */ + #ifndef _MTK_HDMI_CTRL_H + #define _MTK_HDMI_CTRL_H ++#include "mtk_hdmi_phy.h" + + struct platform_driver; + + extern struct platform_driver mtk_cec_driver; + extern struct platform_driver mtk_hdmi_ddc_driver; +-extern struct platform_driver mtk_hdmi_phy_driver; + + #endif /* _MTK_HDMI_CTRL_H */ +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +new file mode 100644 +index 000000000000..514f3e9a8767 +--- /dev/null ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -0,0 +1,232 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Jie Qiu ++ */ ++ ++#include "mtk_hdmi_phy.h" ++ ++static int mtk_hdmi_phy_power_on(struct phy *phy); ++static int mtk_hdmi_phy_power_off(struct phy *phy); ++ ++static const struct phy_ops mtk_hdmi_phy_dev_ops = { ++ .power_on = mtk_hdmi_phy_power_on, ++ .power_off = mtk_hdmi_phy_power_off, ++ .owner = THIS_MODULE, ++}; ++ ++long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ hdmi_phy->pll_rate = rate; ++ if (rate <= 74250000) ++ *parent_rate = rate; ++ else ++ *parent_rate = rate / 2; ++ ++ return rate; ++} ++ ++unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ return hdmi_phy->pll_rate; ++} ++ ++void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, ++ u32 bits) ++{ ++ void __iomem *reg = hdmi_phy->regs + offset; ++ u32 tmp; ++ ++ tmp = readl(reg); ++ tmp &= ~bits; ++ writel(tmp, reg); ++} ++ ++void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, ++ u32 bits) ++{ ++ void __iomem *reg = hdmi_phy->regs + offset; ++ u32 tmp; ++ ++ tmp = readl(reg); ++ tmp |= bits; ++ writel(tmp, reg); ++} ++ ++void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, ++ u32 val, u32 mask) ++{ ++ void __iomem *reg = hdmi_phy->regs + offset; ++ u32 tmp; ++ ++ tmp = readl(reg); ++ tmp = (tmp & ~mask) | (val & mask); ++ writel(tmp, reg); ++} ++ ++inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw) ++{ ++ return container_of(hw, struct mtk_hdmi_phy, pll_hw); ++} ++ ++static int mtk_hdmi_phy_power_on(struct phy *phy) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); ++ int ret; ++ ++ ret = clk_prepare_enable(hdmi_phy->pll); ++ if (ret < 0) ++ return ret; ++ ++ hdmi_phy->conf->hdmi_phy_enable_tmds(hdmi_phy); ++ return 0; ++} ++ ++static int mtk_hdmi_phy_power_off(struct phy *phy) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); ++ ++ hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy); ++ clk_disable_unprepare(hdmi_phy->pll); ++ ++ return 0; ++} ++ ++static const struct phy_ops * ++mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) ++{ ++ if (hdmi_phy && hdmi_phy->conf && ++ hdmi_phy->conf->hdmi_phy_enable_tmds && ++ hdmi_phy->conf->hdmi_phy_disable_tmds) ++ return &mtk_hdmi_phy_dev_ops; ++ ++ dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n"); ++ return NULL; ++} ++ ++static void mtk_hdmi_phy_clk_get_ops(struct mtk_hdmi_phy *hdmi_phy, ++ const struct clk_ops **ops) ++{ ++ if (hdmi_phy && hdmi_phy->conf && hdmi_phy->conf->hdmi_phy_clk_ops) ++ *ops = hdmi_phy->conf->hdmi_phy_clk_ops; ++ else ++ dev_err(hdmi_phy->dev, "Failed to get clk ops of phy\n"); ++} ++ ++static int mtk_hdmi_phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct mtk_hdmi_phy *hdmi_phy; ++ struct resource *mem; ++ struct clk *ref_clk; ++ const char *ref_clk_name; ++ struct clk_init_data clk_init = { ++ .num_parents = 1, ++ .parent_names = (const char * const *)&ref_clk_name, ++ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, ++ }; ++ ++ struct phy *phy; ++ struct phy_provider *phy_provider; ++ int ret; ++ ++ hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL); ++ if (!hdmi_phy) ++ return -ENOMEM; ++ ++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ hdmi_phy->regs = devm_ioremap_resource(dev, mem); ++ if (IS_ERR(hdmi_phy->regs)) { ++ ret = PTR_ERR(hdmi_phy->regs); ++ dev_err(dev, "Failed to get memory resource: %d\n", ret); ++ return ret; ++ } ++ ++ ref_clk = devm_clk_get(dev, "pll_ref"); ++ if (IS_ERR(ref_clk)) { ++ ret = PTR_ERR(ref_clk); ++ dev_err(&pdev->dev, "Failed to get PLL reference clock: %d\n", ++ ret); ++ return ret; ++ } ++ ref_clk_name = __clk_get_name(ref_clk); ++ ++ ret = of_property_read_string(dev->of_node, "clock-output-names", ++ &clk_init.name); ++ if (ret < 0) { ++ dev_err(dev, "Failed to read clock-output-names: %d\n", ret); ++ return ret; ++ } ++ ++ hdmi_phy->dev = dev; ++ hdmi_phy->conf = ++ (struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev); ++ mtk_hdmi_phy_clk_get_ops(hdmi_phy, &clk_init.ops); ++ hdmi_phy->pll_hw.init = &clk_init; ++ hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); ++ if (IS_ERR(hdmi_phy->pll)) { ++ ret = PTR_ERR(hdmi_phy->pll); ++ dev_err(dev, "Failed to register PLL: %d\n", ret); ++ return ret; ++ } ++ ++ ret = of_property_read_u32(dev->of_node, "mediatek,ibias", ++ &hdmi_phy->ibias); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret); ++ return ret; ++ } ++ ++ ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up", ++ &hdmi_phy->ibias_up); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "Failed to get ibias up: %d\n", ret); ++ return ret; ++ } ++ ++ dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n"); ++ hdmi_phy->drv_imp_clk = 0x30; ++ hdmi_phy->drv_imp_d2 = 0x30; ++ hdmi_phy->drv_imp_d1 = 0x30; ++ hdmi_phy->drv_imp_d0 = 0x30; ++ ++ phy = devm_phy_create(dev, NULL, mtk_hdmi_phy_dev_get_ops(hdmi_phy)); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "Failed to create HDMI PHY\n"); ++ return PTR_ERR(phy); ++ } ++ phy_set_drvdata(phy, hdmi_phy); ++ ++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ if (IS_ERR(phy_provider)) { ++ dev_err(dev, "Failed to register HDMI PHY\n"); ++ return PTR_ERR(phy_provider); ++ } ++ ++ return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, ++ hdmi_phy->pll); ++} ++ ++static const struct of_device_id mtk_hdmi_phy_match[] = { ++ { .compatible = "mediatek,mt8173-hdmi-phy", ++ .data = &mtk_hdmi_phy_8173_conf, ++ }, ++ {}, ++}; ++ ++struct platform_driver mtk_hdmi_phy_driver = { ++ .probe = mtk_hdmi_phy_probe, ++ .driver = { ++ .name = "mediatek-hdmi-phy", ++ .of_match_table = mtk_hdmi_phy_match, ++ }, ++}; ++ ++MODULE_DESCRIPTION("MediaTek HDMI PHY Driver"); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +new file mode 100644 +index 000000000000..09b8f525e6b8 +--- /dev/null ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -0,0 +1,58 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Chunhui Dai ++ */ ++ ++#ifndef _MTK_HDMI_PHY_H ++#define _MTK_HDMI_PHY_H ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct mtk_hdmi_phy; ++ ++struct mtk_hdmi_phy_conf { ++ const struct clk_ops *hdmi_phy_clk_ops; ++ void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); ++ void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); ++}; ++ ++struct mtk_hdmi_phy { ++ void __iomem *regs; ++ struct device *dev; ++ struct mtk_hdmi_phy_conf *conf; ++ struct clk *pll; ++ struct clk_hw pll_hw; ++ unsigned long pll_rate; ++ unsigned char drv_imp_clk; ++ unsigned char drv_imp_d2; ++ unsigned char drv_imp_d1; ++ unsigned char drv_imp_d0; ++ unsigned int ibias; ++ unsigned int ibias_up; ++}; ++ ++void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, ++ u32 bits); ++void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, ++ u32 bits); ++void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, ++ u32 val, u32 mask); ++struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); ++long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate); ++unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate); ++ ++extern struct platform_driver mtk_hdmi_phy_driver; ++extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; ++ ++#endif /* _MTK_HDMI_PHY_H */ +diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +index 51cb9cfb6646..ed5916b27658 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +@@ -12,15 +12,7 @@ + * GNU General Public License for more details. + */ + +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include ++#include "mtk_hdmi_phy.h" + + #define HDMI_CON0 0x00 + #define RG_HDMITX_PLL_EN BIT(31) +@@ -123,20 +115,6 @@ + #define RGS_HDMITX_5T1_EDG (0xf << 4) + #define RGS_HDMITX_PLUG_TST BIT(0) + +-struct mtk_hdmi_phy { +- void __iomem *regs; +- struct device *dev; +- struct clk *pll; +- struct clk_hw pll_hw; +- unsigned long pll_rate; +- u8 drv_imp_clk; +- u8 drv_imp_d2; +- u8 drv_imp_d1; +- u8 drv_imp_d0; +- u32 ibias; +- u32 ibias_up; +-}; +- + static const u8 PREDIV[3][4] = { + {0x0, 0x0, 0x0, 0x0}, /* 27Mhz */ + {0x1, 0x1, 0x1, 0x1}, /* 74Mhz */ +@@ -185,44 +163,6 @@ static const u8 HTPLLBR[3][4] = { + {0x1, 0x2, 0x2, 0x1} /* 148Mhz */ + }; + +-static void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, +- u32 bits) +-{ +- void __iomem *reg = hdmi_phy->regs + offset; +- u32 tmp; +- +- tmp = readl(reg); +- tmp &= ~bits; +- writel(tmp, reg); +-} +- +-static void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, +- u32 bits) +-{ +- void __iomem *reg = hdmi_phy->regs + offset; +- u32 tmp; +- +- tmp = readl(reg); +- tmp |= bits; +- writel(tmp, reg); +-} +- +-static void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, +- u32 val, u32 mask) +-{ +- void __iomem *reg = hdmi_phy->regs + offset; +- u32 tmp; +- +- tmp = readl(reg); +- tmp = (tmp & ~mask) | (val & mask); +- writel(tmp, reg); +-} +- +-static inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw) +-{ +- return container_of(hw, struct mtk_hdmi_phy, pll_hw); +-} +- + static int mtk_hdmi_pll_prepare(struct clk_hw *hw) + { + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); +@@ -345,29 +285,7 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + +-static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long *parent_rate) +-{ +- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); +- +- hdmi_phy->pll_rate = rate; +- if (rate <= 74250000) +- *parent_rate = rate; +- else +- *parent_rate = rate / 2; +- +- return rate; +-} +- +-static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) +-{ +- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); +- +- return hdmi_phy->pll_rate; +-} +- +-static const struct clk_ops mtk_hdmi_pll_ops = { ++static const struct clk_ops mtk_hdmi_phy_pll_ops = { + .prepare = mtk_hdmi_pll_prepare, + .unprepare = mtk_hdmi_pll_unprepare, + .set_rate = mtk_hdmi_pll_set_rate, +@@ -390,142 +308,10 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) + RG_HDMITX_SER_EN); + } + +-static int mtk_hdmi_phy_power_on(struct phy *phy) +-{ +- struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); +- int ret; +- +- ret = clk_prepare_enable(hdmi_phy->pll); +- if (ret < 0) +- return ret; +- +- mtk_hdmi_phy_enable_tmds(hdmi_phy); +- +- return 0; +-} +- +-static int mtk_hdmi_phy_power_off(struct phy *phy) +-{ +- struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); +- +- mtk_hdmi_phy_disable_tmds(hdmi_phy); +- clk_disable_unprepare(hdmi_phy->pll); +- +- return 0; +-} +- +-static const struct phy_ops mtk_hdmi_phy_ops = { +- .power_on = mtk_hdmi_phy_power_on, +- .power_off = mtk_hdmi_phy_power_off, +- .owner = THIS_MODULE, +-}; +- +-static int mtk_hdmi_phy_probe(struct platform_device *pdev) +-{ +- struct device *dev = &pdev->dev; +- struct mtk_hdmi_phy *hdmi_phy; +- struct resource *mem; +- struct clk *ref_clk; +- const char *ref_clk_name; +- struct clk_init_data clk_init = { +- .ops = &mtk_hdmi_pll_ops, +- .num_parents = 1, +- .parent_names = (const char * const *)&ref_clk_name, +- .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, +- }; +- struct phy *phy; +- struct phy_provider *phy_provider; +- int ret; +- +- hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL); +- if (!hdmi_phy) +- return -ENOMEM; +- +- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- hdmi_phy->regs = devm_ioremap_resource(dev, mem); +- if (IS_ERR(hdmi_phy->regs)) { +- ret = PTR_ERR(hdmi_phy->regs); +- dev_err(dev, "Failed to get memory resource: %d\n", ret); +- return ret; +- } +- +- ref_clk = devm_clk_get(dev, "pll_ref"); +- if (IS_ERR(ref_clk)) { +- ret = PTR_ERR(ref_clk); +- dev_err(&pdev->dev, "Failed to get PLL reference clock: %d\n", +- ret); +- return ret; +- } +- ref_clk_name = __clk_get_name(ref_clk); +- +- ret = of_property_read_string(dev->of_node, "clock-output-names", +- &clk_init.name); +- if (ret < 0) { +- dev_err(dev, "Failed to read clock-output-names: %d\n", ret); +- return ret; +- } +- +- hdmi_phy->pll_hw.init = &clk_init; +- hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); +- if (IS_ERR(hdmi_phy->pll)) { +- ret = PTR_ERR(hdmi_phy->pll); +- dev_err(dev, "Failed to register PLL: %d\n", ret); +- return ret; +- } +- +- ret = of_property_read_u32(dev->of_node, "mediatek,ibias", +- &hdmi_phy->ibias); +- if (ret < 0) { +- dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret); +- return ret; +- } +- +- ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up", +- &hdmi_phy->ibias_up); +- if (ret < 0) { +- dev_err(&pdev->dev, "Failed to get ibias up: %d\n", ret); +- return ret; +- } +- +- dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n"); +- hdmi_phy->drv_imp_clk = 0x30; +- hdmi_phy->drv_imp_d2 = 0x30; +- hdmi_phy->drv_imp_d1 = 0x30; +- hdmi_phy->drv_imp_d0 = 0x30; +- +- phy = devm_phy_create(dev, NULL, &mtk_hdmi_phy_ops); +- if (IS_ERR(phy)) { +- dev_err(dev, "Failed to create HDMI PHY\n"); +- return PTR_ERR(phy); +- } +- phy_set_drvdata(phy, hdmi_phy); +- +- phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); +- if (IS_ERR(phy_provider)) +- return PTR_ERR(phy_provider); +- +- hdmi_phy->dev = dev; +- return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, +- hdmi_phy->pll); +-} +- +-static int mtk_hdmi_phy_remove(struct platform_device *pdev) +-{ +- return 0; +-} +- +-static const struct of_device_id mtk_hdmi_phy_match[] = { +- { .compatible = "mediatek,mt8173-hdmi-phy", }, +- {}, +-}; +- +-struct platform_driver mtk_hdmi_phy_driver = { +- .probe = mtk_hdmi_phy_probe, +- .remove = mtk_hdmi_phy_remove, +- .driver = { +- .name = "mediatek-hdmi-phy", +- .of_match_table = mtk_hdmi_phy_match, +- }, ++struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = { ++ .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, ++ .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, ++ .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, + }; + + MODULE_AUTHOR("Jie Qiu "); +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch b/root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch new file mode 100755 index 00000000..8c3d0162 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch @@ -0,0 +1,32 @@ +From 93440802592c9acbec41645809dcae5eb350d966 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:48 +0800 +Subject: [PATCH 34/77] drm/mediatek: add support for SPDIF audio in HDMI + +add support for SPDIF audio in HDMI + +Signed-off-by: chunhui dai +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/mtk_hdmi.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c +index 29bd2a144b19..90e1139f02f8 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c +@@ -1577,6 +1577,11 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data, + hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT; + hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS; + break; ++ case HDMI_SPDIF: ++ hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; ++ hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16; ++ hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF; ++ break; + default: + dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__, + daifmt->fmt); +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch b/root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch new file mode 100755 index 00000000..b56c6315 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch @@ -0,0 +1,309 @@ +From 7ced4ebd71acd0677a73976bf6be399c2362ca6e Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 3 Oct 2018 11:41:49 +0800 +Subject: [PATCH 35/77] drm/mediatek: add hdmi driver for MT2701 and MT7623 + +This patch adds hdmi dirver suppot for both MT2701 and MT7623. +And also support other (existing or future) chips that use +the same binding and driver. + +Signed-off-by: chunhui dai +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/Makefile | 3 +- + drivers/gpu/drm/mediatek/mtk_hdmi.c | 9 +- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 3 + + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 + + .../gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 212 ++++++++++++++++++ + 5 files changed, 226 insertions(+), 3 deletions(-) + create mode 100644 drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c + +diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile +index 61cf0d2ab28a..82ae49c64221 100644 +--- a/drivers/gpu/drm/mediatek/Makefile ++++ b/drivers/gpu/drm/mediatek/Makefile +@@ -19,7 +19,8 @@ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o + mediatek-drm-hdmi-objs := mtk_cec.o \ + mtk_hdmi.o \ + mtk_hdmi_ddc.o \ ++ mtk_mt2701_hdmi_phy.o \ + mtk_mt8173_hdmi_phy.o \ + mtk_hdmi_phy.o + +-obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o +\ No newline at end of file ++obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c +index 90e1139f02f8..862f3ec22131 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c +@@ -241,8 +241,13 @@ static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable) + * The ARM trusted firmware provides an API for the HDMI driver to set + * this control bit to enable HDMI output in supervisor mode. + */ +- arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904, 0x80000000, +- 0, 0, 0, 0, 0, &res); ++ if (hdmi_phy->conf && hdmi_phy->conf->tz_disabled) ++ regmap_update_bits(hdmi->sys_regmap, ++ hdmi->sys_offset + HDMI_SYS_CFG20, ++ 0x80008005, enable ? 0x80000005 : 0x8000); ++ else ++ arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904, ++ 0x80000000, 0, 0, 0, 0, 0, &res); + + regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20, + HDMI_PCLK_FREE_RUN, enable ? HDMI_PCLK_FREE_RUN : 0); +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index 514f3e9a8767..4ef9c57ffd44 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -214,6 +214,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) + } + + static const struct of_device_id mtk_hdmi_phy_match[] = { ++ { .compatible = "mediatek,mt2701-hdmi-phy", ++ .data = &mtk_hdmi_phy_2701_conf, ++ }, + { .compatible = "mediatek,mt8173-hdmi-phy", + .data = &mtk_hdmi_phy_8173_conf, + }, +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index 09b8f525e6b8..f39b1fc66612 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -20,6 +20,7 @@ + struct mtk_hdmi_phy; + + struct mtk_hdmi_phy_conf { ++ bool tz_disabled; + const struct clk_ops *hdmi_phy_clk_ops; + void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); + void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); +@@ -54,5 +55,6 @@ unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, + + extern struct platform_driver mtk_hdmi_phy_driver; + extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; ++extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf; + + #endif /* _MTK_HDMI_PHY_H */ +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +new file mode 100644 +index 000000000000..fcc42dc6ea7f +--- /dev/null ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -0,0 +1,212 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Chunhui Dai ++ */ ++ ++#include "mtk_hdmi_phy.h" ++ ++#define HDMI_CON0 0x00 ++#define RG_HDMITX_DRV_IBIAS 0 ++#define RG_HDMITX_DRV_IBIAS_MASK (0x3f << 0) ++#define RG_HDMITX_EN_SER 12 ++#define RG_HDMITX_EN_SER_MASK (0x0f << 12) ++#define RG_HDMITX_EN_SLDO 16 ++#define RG_HDMITX_EN_SLDO_MASK (0x0f << 16) ++#define RG_HDMITX_EN_PRED 20 ++#define RG_HDMITX_EN_PRED_MASK (0x0f << 20) ++#define RG_HDMITX_EN_IMP 24 ++#define RG_HDMITX_EN_IMP_MASK (0x0f << 24) ++#define RG_HDMITX_EN_DRV 28 ++#define RG_HDMITX_EN_DRV_MASK (0x0f << 28) ++ ++#define HDMI_CON1 0x04 ++#define RG_HDMITX_PRED_IBIAS 18 ++#define RG_HDMITX_PRED_IBIAS_MASK (0x0f << 18) ++#define RG_HDMITX_PRED_IMP (0x01 << 22) ++#define RG_HDMITX_DRV_IMP 26 ++#define RG_HDMITX_DRV_IMP_MASK (0x3f << 26) ++ ++#define HDMI_CON2 0x08 ++#define RG_HDMITX_EN_TX_CKLDO (0x01 << 0) ++#define RG_HDMITX_EN_TX_POSDIV (0x01 << 1) ++#define RG_HDMITX_TX_POSDIV 3 ++#define RG_HDMITX_TX_POSDIV_MASK (0x03 << 3) ++#define RG_HDMITX_EN_MBIAS (0x01 << 6) ++#define RG_HDMITX_MBIAS_LPF_EN (0x01 << 7) ++ ++#define HDMI_CON4 0x10 ++#define RG_HDMITX_RESERVE_MASK (0xffffffff << 0) ++ ++#define HDMI_CON6 0x18 ++#define RG_HTPLL_BR 0 ++#define RG_HTPLL_BR_MASK (0x03 << 0) ++#define RG_HTPLL_BC 2 ++#define RG_HTPLL_BC_MASK (0x03 << 2) ++#define RG_HTPLL_BP 4 ++#define RG_HTPLL_BP_MASK (0x0f << 4) ++#define RG_HTPLL_IR 8 ++#define RG_HTPLL_IR_MASK (0x0f << 8) ++#define RG_HTPLL_IC 12 ++#define RG_HTPLL_IC_MASK (0x0f << 12) ++#define RG_HTPLL_POSDIV 16 ++#define RG_HTPLL_POSDIV_MASK (0x03 << 16) ++#define RG_HTPLL_PREDIV 18 ++#define RG_HTPLL_PREDIV_MASK (0x03 << 18) ++#define RG_HTPLL_FBKSEL 20 ++#define RG_HTPLL_FBKSEL_MASK (0x03 << 20) ++#define RG_HTPLL_RLH_EN (0x01 << 22) ++#define RG_HTPLL_FBKDIV 24 ++#define RG_HTPLL_FBKDIV_MASK (0x7f << 24) ++#define RG_HTPLL_EN (0x01 << 31) ++ ++#define HDMI_CON7 0x1c ++#define RG_HTPLL_AUTOK_EN (0x01 << 23) ++#define RG_HTPLL_DIVEN 28 ++#define RG_HTPLL_DIVEN_MASK (0x07 << 28) ++ ++static int mtk_hdmi_pll_prepare(struct clk_hw *hw) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); ++ usleep_range(80, 100); ++ return 0; ++} ++ ++static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); ++ usleep_range(80, 100); ++} ++ ++static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ u32 pos_div; ++ ++ if (rate <= 64000000) ++ pos_div = 3; ++ else if (rate <= 12800000) ++ pos_div = 1; ++ else ++ pos_div = 1; ++ ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC), ++ RG_HTPLL_IC_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR), ++ RG_HTPLL_IR_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON2, (pos_div << RG_HDMITX_TX_POSDIV), ++ RG_HDMITX_TX_POSDIV_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (1 << RG_HTPLL_FBKSEL), ++ RG_HTPLL_FBKSEL_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (19 << RG_HTPLL_FBKDIV), ++ RG_HTPLL_FBKDIV_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON7, (0x2 << RG_HTPLL_DIVEN), ++ RG_HTPLL_DIVEN_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0xc << RG_HTPLL_BP), ++ RG_HTPLL_BP_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x2 << RG_HTPLL_BC), ++ RG_HTPLL_BC_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_BR), ++ RG_HTPLL_BR_MASK); ++ ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PRED_IMP); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x3 << RG_HDMITX_PRED_IBIAS), ++ RG_HDMITX_PRED_IBIAS_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_IMP_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x28 << RG_HDMITX_DRV_IMP), ++ RG_HDMITX_DRV_IMP_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 0x28, RG_HDMITX_RESERVE_MASK); ++ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, (0xa << RG_HDMITX_DRV_IBIAS), ++ RG_HDMITX_DRV_IBIAS_MASK); ++ return 0; ++} ++ ++static const struct clk_ops mtk_hdmi_phy_pll_ops = { ++ .prepare = mtk_hdmi_pll_prepare, ++ .unprepare = mtk_hdmi_pll_unprepare, ++ .set_rate = mtk_hdmi_pll_set_rate, ++ .round_rate = mtk_hdmi_pll_round_rate, ++ .recalc_rate = mtk_hdmi_pll_recalc_rate, ++}; ++ ++static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) ++{ ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); ++ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); ++ usleep_range(80, 100); ++} ++ ++static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) ++{ ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); ++ usleep_range(80, 100); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); ++ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); ++ usleep_range(80, 100); ++} ++ ++struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { ++ .tz_disabled = true, ++ .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, ++ .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, ++ .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, ++}; ++ ++MODULE_AUTHOR("Chunhui Dai "); ++MODULE_DESCRIPTION("MediaTek HDMI PHY Driver"); ++MODULE_LICENSE("GPL v2"); +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch b/root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch new file mode 100755 index 00000000..ba5d1160 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch @@ -0,0 +1,58 @@ +From 2ac94b8b6a664bb66404b595da4789687f13bcc4 Mon Sep 17 00:00:00 2001 +From: Bibby Hsieh +Date: Wed, 3 Oct 2018 11:41:50 +0800 +Subject: [PATCH 36/77] drm/mediatek: implement connection from BLS to DPI0 + +Modify display driver to support connection from BLS to DPI. + +Signed-off-by: Bibby Hsieh +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c +index 546b3e3b300b..579ce28d801d 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c +@@ -39,6 +39,7 @@ + #define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030 + #define DISP_REG_CONFIG_OUT_SEL 0x04c + #define DISP_REG_CONFIG_DSI_SEL 0x050 ++#define DISP_REG_CONFIG_DPI_SEL 0x064 + + #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) + #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) +@@ -136,7 +137,10 @@ + + #define OVL_MOUT_EN_RDMA 0x1 + #define BLS_TO_DSI_RDMA1_TO_DPI1 0x8 ++#define BLS_TO_DPI_RDMA1_TO_DSI 0x2 + #define DSI_SEL_IN_BLS 0x0 ++#define DPI_SEL_IN_BLS 0x0 ++#define DSI_SEL_IN_RDMA 0x1 + + struct mtk_disp_mutex { + int id; +@@ -339,9 +343,17 @@ static void mtk_ddp_sout_sel(void __iomem *config_regs, + enum mtk_ddp_comp_id cur, + enum mtk_ddp_comp_id next) + { +- if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) ++ if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) { + writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1, + config_regs + DISP_REG_CONFIG_OUT_SEL); ++ } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) { ++ writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI, ++ config_regs + DISP_REG_CONFIG_OUT_SEL); ++ writel_relaxed(DSI_SEL_IN_RDMA, ++ config_regs + DISP_REG_CONFIG_DSI_SEL); ++ writel_relaxed(DPI_SEL_IN_BLS, ++ config_regs + DISP_REG_CONFIG_DPI_SEL); ++ } + } + + void mtk_ddp_add_comp_to_path(void __iomem *config_regs, +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch b/root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch new file mode 100755 index 00000000..0693a2d9 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch @@ -0,0 +1,32 @@ +From 4a50f2d17feb0b95488cb3f0769972f01e60209f Mon Sep 17 00:00:00 2001 +From: Bibby Hsieh +Date: Wed, 3 Oct 2018 11:41:51 +0800 +Subject: [PATCH 37/77] drm/mediatek: add a error return value when clock + driver has been prepared + +DRM driver get the comp->clk by of_clk_get(), we only +assign NULL to comp->clk when error happened, but do +not return the error number. + +Signed-off-by: Bibby Hsieh +Reviewed-by: CK Hu +--- + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +index ff974d82a4a6..54ca794db3e9 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +@@ -294,7 +294,7 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, + comp->irq = of_irq_get(node, 0); + comp->clk = of_clk_get(node, 0); + if (IS_ERR(comp->clk)) +- comp->clk = NULL; ++ return PTR_ERR(comp->clk); + + /* Only DMA capable components need the LARB property */ + comp->larb_dev = NULL; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch b/root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch new file mode 100755 index 00000000..831180aa --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch @@ -0,0 +1,142 @@ +From 9712ba59916d5a7cf568e8ba73d4fba4f2ebfd5f Mon Sep 17 00:00:00 2001 +From: Bibby Hsieh +Date: Fri, 21 Sep 2018 11:28:22 +0800 +Subject: [PATCH 38/77] drm/mediatek: config component output by device node + port + +We can select output component by decive node port. +Main path default output component is DSI. +External path default output component is DPI. + +Signed-off-by: Bibby Hsieh +Signed-off-by: Frank Wunderlich +--- + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 41 ++++++++++++++++++++++---- + drivers/gpu/drm/mediatek/mtk_drm_drv.h | 4 +-- + 2 files changed, 37 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +index 6422e99952fe..188b83d63c87 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +@@ -21,7 +21,9 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + +@@ -133,7 +135,7 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = { + .atomic_commit = mtk_atomic_commit, + }; + +-static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_RDMA0, + DDP_COMPONENT_COLOR0, +@@ -141,12 +143,12 @@ static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { + DDP_COMPONENT_DSI0, + }; + +-static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { + DDP_COMPONENT_RDMA1, + DDP_COMPONENT_DPI0, + }; + +-static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_AAL0, +@@ -156,7 +158,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { + DDP_COMPONENT_PWM0, + }; + +-static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { + DDP_COMPONENT_OVL1, + DDP_COMPONENT_COLOR1, + DDP_COMPONENT_AAL1, +@@ -172,7 +174,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = { + DDP_COMPONENT_PWM2, + }; + +-static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_AAL0, +@@ -183,7 +185,7 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { + DDP_COMPONENT_PWM0, + }; + +-static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { + DDP_COMPONENT_OVL1, + DDP_COMPONENT_COLOR1, + DDP_COMPONENT_GAMMA, +@@ -472,6 +474,7 @@ static int mtk_drm_probe(struct platform_device *pdev) + + /* Iterate over sibling DISP function blocks */ + for_each_child_of_node(dev->of_node->parent, node) { ++ struct device_node *port, *ep, *remote; + const struct of_device_id *of_id; + enum mtk_ddp_comp_type comp_type; + int comp_id; +@@ -531,6 +534,32 @@ static int mtk_drm_probe(struct platform_device *pdev) + + private->ddp_comp[comp_id] = comp; + } ++ ++ if (comp_type != MTK_DSI && comp_type != MTK_DPI) { ++ port = of_graph_get_port_by_id(node, 0); ++ if (!port) ++ continue; ++ ep = of_get_child_by_name(port, "endpoint"); ++ of_node_put(port); ++ if (!ep) ++ continue; ++ remote = of_graph_get_remote_port_parent(ep); ++ of_node_put(ep); ++ if (!remote) ++ continue; ++ of_id = of_match_node(mtk_ddp_comp_dt_ids, remote); ++ if (!of_id) ++ continue; ++ comp_type = (enum mtk_ddp_comp_type)of_id->data; ++ for (i = 0; i < private->data->main_len - 1; i++) ++ if (private->data->main_path[i] == comp_id) ++ private->data->main_path[i + 1] = ++ mtk_ddp_comp_get_id(node, comp_type); ++ for (i = 0; i < private->data->ext_len - 1; i++) ++ if (private->data->ext_path[i] == comp_id) ++ private->data->ext_path[i + 1] = ++ mtk_ddp_comp_get_id(node, comp_type); ++ } + } + + if (!private->mutex_node) { +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +index ecc00ca3221d..256a3ff2e66e 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +@@ -29,9 +29,9 @@ struct drm_property; + struct regmap; + + struct mtk_mmsys_driver_data { +- const enum mtk_ddp_comp_id *main_path; ++ enum mtk_ddp_comp_id *main_path; + unsigned int main_len; +- const enum mtk_ddp_comp_id *ext_path; ++ enum mtk_ddp_comp_id *ext_path; + unsigned int ext_len; + const enum mtk_ddp_comp_id *third_path; + unsigned int third_len; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch b/root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch new file mode 100755 index 00000000..8d61ae13 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch @@ -0,0 +1,36 @@ +From 687aeb6d2f7e36d8fffc23b5d767110b79beda59 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Wed, 5 Sep 2018 18:22:17 +0800 +Subject: [PATCH 39/77] arm: dts: mt7623: add a performance counter unit device + node + +Add ARM PMU device node to enable hardware perf events. + +Signed-off-by: Ryder Lee +--- + arch/arm/boot/dts/mt7623.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index af6b6228f8a8..d009b50f917e 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -121,6 +121,15 @@ + }; + }; + ++ pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = , ++ , ++ , ++ ; ++ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; ++ }; ++ + system_clk: dummy13m { + compatible = "fixed-clock"; + clock-frequency = <13000000>; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch b/root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch new file mode 100755 index 00000000..aa075e99 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch @@ -0,0 +1,76 @@ +From 63b2249cb5ccf8ff0625cd707f243b3e882bc366 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Wed, 5 Sep 2018 18:22:18 +0800 +Subject: [PATCH 40/77] arm: dts: mt7623: update subsystem clock controller + device nodes + +Update MT7623 subsystem clock controllers, inlcuding mmsys, imgsys, +vdecsys, g3dsys and bdpsys. + +Signed-off-by: Ryder Lee +--- + arch/arm/boot/dts/mt7623.dtsi | 41 +++++++++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index d009b50f917e..35b0fa4112b0 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -729,6 +729,39 @@ + clock-names = "wifi-dma"; + }; + ++ g3dsys: syscon@13000000 { ++ compatible = "mediatek,mt7623-g3dsys", ++ "mediatek,mt2701-g3dsys", ++ "syscon"; ++ reg = <0 0x13000000 0 0x200>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ mmsys: syscon@14000000 { ++ compatible = "mediatek,mt7623-mmsys", ++ "mediatek,mt2701-mmsys", ++ "syscon"; ++ reg = <0 0x14000000 0 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ imgsys: syscon@15000000 { ++ compatible = "mediatek,mt7623-imgsys", ++ "mediatek,mt2701-imgsys", ++ "syscon"; ++ reg = <0 0x15000000 0 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ vdecsys: syscon@16000000 { ++ compatible = "mediatek,mt7623-vdecsys", ++ "mediatek,mt2701-vdecsys", ++ "syscon"; ++ reg = <0 0x16000000 0 0x1000>; ++ #clock-cells = <1>; ++ }; ++ + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", +@@ -983,6 +1016,14 @@ + power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; + status = "disabled"; + }; ++ ++ bdpsys: syscon@1c000000 { ++ compatible = "mediatek,mt7623-bdpsys", ++ "mediatek,mt2701-bdpsys", ++ "syscon"; ++ reg = <0 0x1c000000 0 0x1000>; ++ #clock-cells = <1>; ++ }; + }; + + &pio { +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch b/root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch new file mode 100755 index 00000000..5a485788 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch @@ -0,0 +1,120 @@ +From d6515baf44e1f6aa4809edf0d0ca314ce9e35a66 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Wed, 5 Sep 2018 18:22:19 +0800 +Subject: [PATCH 41/77] arm: dts: mt7623: add iommu/smi device nodes + +Add iommu/smi device nodes for MT7623. + +Signed-off-by: Ryder Lee +--- + arch/arm/boot/dts/mt7623.dtsi | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 35b0fa4112b0..7864c3804377 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -288,6 +289,17 @@ + clock-names = "system-clk", "rtc-clk"; + }; + ++ smi_common: smi@1000c000 { ++ compatible = "mediatek,mt7623-smi-common", ++ "mediatek,mt2701-smi-common"; ++ reg = <0 0x1000c000 0 0x1000>; ++ clocks = <&infracfg CLK_INFRA_SMI>, ++ <&mmsys CLK_MM_SMI_COMMON>, ++ <&infracfg CLK_INFRA_SMI>; ++ clock-names = "apb", "smi", "async"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; ++ }; ++ + pwrap: pwrap@1000d000 { + compatible = "mediatek,mt7623-pwrap", + "mediatek,mt2701-pwrap"; +@@ -319,6 +331,17 @@ + reg = <0 0x10200100 0 0x1c>; + }; + ++ iommu: mmsys_iommu@10205000 { ++ compatible = "mediatek,mt7623-m4u", ++ "mediatek,mt2701-m4u"; ++ reg = <0 0x10205000 0 0x1000>; ++ interrupts = ; ++ clocks = <&infracfg CLK_INFRA_M4U>; ++ clock-names = "bclk"; ++ mediatek,larbs = <&larb0 &larb1 &larb2>; ++ #iommu-cells = <1>; ++ }; ++ + efuse: efuse@10206000 { + compatible = "mediatek,mt7623-efuse", + "mediatek,mt8173-efuse"; +@@ -746,6 +769,18 @@ + #clock-cells = <1>; + }; + ++ larb0: larb@14010000 { ++ compatible = "mediatek,mt7623-smi-larb", ++ "mediatek,mt2701-smi-larb"; ++ reg = <0 0x14010000 0 0x1000>; ++ mediatek,smi = <&smi_common>; ++ mediatek,larb-id = <0>; ++ clocks = <&mmsys CLK_MM_SMI_LARB0>, ++ <&mmsys CLK_MM_SMI_LARB0>; ++ clock-names = "apb", "smi"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; ++ }; ++ + imgsys: syscon@15000000 { + compatible = "mediatek,mt7623-imgsys", + "mediatek,mt2701-imgsys", +@@ -754,6 +789,18 @@ + #clock-cells = <1>; + }; + ++ larb2: larb@15001000 { ++ compatible = "mediatek,mt7623-smi-larb", ++ "mediatek,mt2701-smi-larb"; ++ reg = <0 0x15001000 0 0x1000>; ++ mediatek,smi = <&smi_common>; ++ mediatek,larb-id = <2>; ++ clocks = <&imgsys CLK_IMG_SMI_COMM>, ++ <&imgsys CLK_IMG_SMI_COMM>; ++ clock-names = "apb", "smi"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; ++ }; ++ + vdecsys: syscon@16000000 { + compatible = "mediatek,mt7623-vdecsys", + "mediatek,mt2701-vdecsys", +@@ -762,6 +809,18 @@ + #clock-cells = <1>; + }; + ++ larb1: larb@16010000 { ++ compatible = "mediatek,mt7623-smi-larb", ++ "mediatek,mt2701-smi-larb"; ++ reg = <0 0x16010000 0 0x1000>; ++ mediatek,smi = <&smi_common>; ++ mediatek,larb-id = <1>; ++ clocks = <&vdecsys CLK_VDEC_CKGEN>, ++ <&vdecsys CLK_VDEC_LARB>; ++ clock-names = "apb", "smi"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>; ++ }; ++ + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch b/root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch new file mode 100755 index 00000000..66edb33f --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch @@ -0,0 +1,41 @@ +From bd988dc66763555c2aa6509b060fa5b3ceb682a6 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Wed, 5 Sep 2018 18:22:20 +0800 +Subject: [PATCH 42/77] arm: dts: mt7623: add jpeg decoder device node + +Add a jpeg decoder device node for MT7623. + +Signed-off-by: Ryder Lee +--- + arch/arm/boot/dts/mt7623.dtsi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 7864c3804377..ce9fb23eb5cb 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -801,6 +801,21 @@ + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; + }; + ++ jpegdec: jpegdec@15004000 { ++ compatible = "mediatek,mt7623-jpgdec", ++ "mediatek,mt2701-jpgdec"; ++ reg = <0 0x15004000 0 0x1000>; ++ interrupts = ; ++ clocks = <&imgsys CLK_IMG_JPGDEC_SMI>, ++ <&imgsys CLK_IMG_JPGDEC>; ++ clock-names = "jpgdec-smi", ++ "jpgdec"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; ++ mediatek,larb = <&larb2>; ++ iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, ++ <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; ++ }; ++ + vdecsys: syscon@16000000 { + compatible = "mediatek,mt7623-vdecsys", + "mediatek,mt2701-vdecsys", +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch b/root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch new file mode 100755 index 00000000..de1842b4 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch @@ -0,0 +1,493 @@ +From c7dbe108de2c9f47f952910f424d1fa9a3470a5b Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Wed, 5 Sep 2018 22:09:27 +0800 +Subject: [PATCH 43/77] arm: dts: mt7623: add display subsystem related device + nodes + +Add display subsystem related device nodes for MT7623. + +Cc: CK Hu +Signed-off-by: chunhui dai +Signed-off-by: Bibby Hsieh +Signed-off-by: Ryder Lee +--- + arch/arm/boot/dts/mt7623.dtsi | 177 ++++++++++++++++++ + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 85 +++++++++ + arch/arm/boot/dts/mt7623n-rfb-emmc.dts | 85 +++++++++ + 3 files changed, 347 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index ce9fb23eb5cb..619843514d74 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -23,6 +23,11 @@ + #address-cells = <2>; + #size-cells = <2>; + ++ aliases { ++ rdma0 = &rdma0; ++ rdma1 = &rdma1; ++ }; ++ + cpu_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-shared; +@@ -313,6 +318,25 @@ + clock-names = "spi", "wrap"; + }; + ++ mipi_tx0: mipi-dphy@10010000 { ++ compatible = "mediatek,mt7623-mipi-tx", ++ "mediatek,mt2701-mipi-tx"; ++ reg = <0 0x10010000 0 0x90>; ++ clocks = <&clk26m>; ++ clock-output-names = "mipi_tx0_pll"; ++ #clock-cells = <0>; ++ #phy-cells = <0>; ++ }; ++ ++ cec: cec@10012000 { ++ compatible = "mediatek,mt7623-cec", ++ "mediatek,mt8173-cec"; ++ reg = <0 0x10012000 0 0xbc>; ++ interrupts = ; ++ clocks = <&infracfg CLK_INFRA_CEC>; ++ status = "disabled"; ++ }; ++ + cir: cir@10013000 { + compatible = "mediatek,mt7623-cir"; + reg = <0 0x10013000 0 0x1000>; +@@ -361,6 +385,18 @@ + #clock-cells = <1>; + }; + ++ hdmi_phy: phy@10209100 { ++ compatible = "mediatek,mt7623-hdmi-phy", ++ "mediatek,mt2701-hdmi-phy"; ++ reg = <0 0x10209100 0 0x24>; ++ clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; ++ clock-names = "pll_ref"; ++ clock-output-names = "hdmitx_dig_cts"; ++ #clock-cells = <0>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + rng: rng@1020f000 { + compatible = "mediatek,mt7623-rng"; + reg = <0 0x1020f000 0 0x1000>; +@@ -573,6 +609,16 @@ + status = "disabled"; + }; + ++ hdmiddc0: i2c@11013000 { ++ compatible = "mediatek,mt7623-hdmi-ddc", ++ "mediatek,mt8173-hdmi-ddc"; ++ interrupts = ; ++ reg = <0 0x11013000 0 0x1C>; ++ clocks = <&pericfg CLK_PERI_I2C3>; ++ clock-names = "ddc-i2c"; ++ status = "disabled"; ++ }; ++ + nor_flash: spi@11014000 { + compatible = "mediatek,mt7623-nor", + "mediatek,mt8173-nor"; +@@ -769,6 +815,84 @@ + #clock-cells = <1>; + }; + ++ display_components: dispsys@14000000 { ++ compatible = "mediatek,mt7623-mmsys", ++ "mediatek,mt2701-mmsys"; ++ reg = <0 0x14000000 0 0x1000>; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; ++ }; ++ ++ ovl@14007000 { ++ compatible = "mediatek,mt7623-disp-ovl", ++ "mediatek,mt2701-disp-ovl"; ++ reg = <0 0x14007000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_OVL>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_OVL_0>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ rdma0: rdma@14008000 { ++ compatible = "mediatek,mt7623-disp-rdma", ++ "mediatek,mt2701-disp-rdma"; ++ reg = <0 0x14008000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_RDMA>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ wdma@14009000 { ++ compatible = "mediatek,mt7623-disp-wdma", ++ "mediatek,mt2701-disp-wdma"; ++ reg = <0 0x14009000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_WDMA>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_WDMA>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ bls: pwm@1400a000 { ++ compatible = "mediatek,mt7623-disp-pwm", ++ "mediatek,mt2701-disp-pwm"; ++ reg = <0 0x1400a000 0 0x1000>; ++ #pwm-cells = <2>; ++ clocks = <&mmsys CLK_MM_MDP_BLS_26M>, ++ <&mmsys CLK_MM_DISP_BLS>; ++ clock-names = "main", "mm"; ++ status = "disabled"; ++ }; ++ ++ color@1400b000 { ++ compatible = "mediatek,mt7623-disp-color", ++ "mediatek,mt2701-disp-color"; ++ reg = <0 0x1400b000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_COLOR>; ++ }; ++ ++ dsi: dsi@1400c000 { ++ compatible = "mediatek,mt7623-dsi", ++ "mediatek,mt2701-dsi"; ++ reg = <0 0x1400c000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DSI_ENGINE>, ++ <&mmsys CLK_MM_DSI_DIG>, ++ <&mipi_tx0>; ++ clock-names = "engine", "digital", "hs"; ++ phys = <&mipi_tx0>; ++ phy-names = "dphy"; ++ status = "disabled"; ++ }; ++ ++ mutex: mutex@1400e000 { ++ compatible = "mediatek,mt7623-disp-mutex", ++ "mediatek,mt2701-disp-mutex"; ++ reg = <0 0x1400e000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_MUTEX_32K>; ++ }; ++ + larb0: larb@14010000 { + compatible = "mediatek,mt7623-smi-larb", + "mediatek,mt2701-smi-larb"; +@@ -781,6 +905,44 @@ + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; + }; + ++ rdma1: rdma@14012000 { ++ compatible = "mediatek,mt7623-disp-rdma", ++ "mediatek,mt2701-disp-rdma"; ++ reg = <0 0x14012000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_RDMA1>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA1>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ dpi0: dpi@14014000 { ++ compatible = "mediatek,mt7623-dpi", ++ "mediatek,mt2701-dpi"; ++ reg = <0 0x14014000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DPI1_DIGL>, ++ <&mmsys CLK_MM_DPI1_ENGINE>, ++ <&topckgen CLK_TOP_TVDPLL>; ++ clock-names = "pixel", "engine", "pll"; ++ status = "disabled"; ++ }; ++ ++ hdmi0: hdmi@14015000 { ++ compatible = "mediatek,mt7623-hdmi", ++ "mediatek,mt8173-hdmi"; ++ reg = <0 0x14015000 0 0x400>; ++ clocks = <&mmsys CLK_MM_HDMI_PIXEL>, ++ <&mmsys CLK_MM_HDMI_PLL>, ++ <&mmsys CLK_MM_HDMI_AUDIO>, ++ <&mmsys CLK_MM_HDMI_SPDIF>; ++ clock-names = "pixel", "pll", "bclk", "spdif"; ++ phys = <&hdmi_phy>; ++ phy-names = "hdmi"; ++ mediatek,syscon-hdmi = <&mmsys 0x900>; ++ cec = <&cec>; ++ status = "disabled"; ++ }; ++ + imgsys: syscon@15000000 { + compatible = "mediatek,mt7623-imgsys", + "mediatek,mt2701-imgsys", +@@ -1108,6 +1270,21 @@ + }; + }; + ++ hdmi_pins_a: hdmi-default { ++ pins-hdmi { ++ pinmux = ; ++ input-enable; ++ bias-pull-down; ++ }; ++ }; ++ ++ hdmi_ddc_pins_a: hdmi_ddc-default { ++ pins-hdmi-ddc { ++ pinmux = , ++ ; ++ }; ++ }; ++ + i2c0_pins_a: i2c0-default { + pins-i2c0 { + pinmux = , +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 4c6e53d9e736..d97edde586ad 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -22,6 +22,19 @@ + stdout-path = "serial2:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ label = "hdmi"; ++ type = "d"; ++ ddc-i2c-bus = <&hdmiddc0>; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi0_out>; ++ }; ++ }; ++ }; ++ + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; +@@ -127,10 +140,24 @@ + }; + }; + ++&bls { ++ status = "okay"; ++ ++ port { ++ bls_out: endpoint { ++ remote-endpoint = <&dpi0_in>; ++ }; ++ }; ++}; ++ + &btif { + status = "okay"; + }; + ++&cec { ++ status = "okay"; ++}; ++ + &cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; +@@ -141,6 +168,28 @@ + status = "okay"; + }; + ++&dpi0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ dpi0_out: endpoint { ++ remote-endpoint = <&hdmi0_in>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dpi0_in: endpoint { ++ remote-endpoint = <&bls_out>; ++ }; ++ }; ++ }; ++}; ++ + ð { + status = "okay"; + +@@ -240,6 +289,42 @@ + }; + }; + ++&hdmi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_pins_a>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ hdmi0_in: endpoint { ++ remote-endpoint = <&dpi0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ hdmi0_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++ }; ++ }; ++}; ++ ++&hdmiddc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_ddc_pins_a>; ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ mediatek,ibias = <0xa>; ++ mediatek,ibias_up = <0x1c>; ++ status = "okay"; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; +diff --git a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +index b7606130ade9..3e5911d8d6bc 100644 +--- a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts ++++ b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +@@ -24,6 +24,19 @@ + stdout-path = "serial2:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ label = "hdmi"; ++ type = "d"; ++ ddc-i2c-bus = <&hdmiddc0>; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi0_out>; ++ }; ++ }; ++ }; ++ + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; +@@ -106,10 +119,24 @@ + }; + }; + ++&bls { ++ status = "okay"; ++ ++ port { ++ bls_out: endpoint { ++ remote-endpoint = <&dpi0_in>; ++ }; ++ }; ++}; ++ + &btif { + status = "okay"; + }; + ++&cec { ++ status = "okay"; ++}; ++ + &cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; +@@ -120,6 +147,28 @@ + status = "okay"; + }; + ++&dpi0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ dpi0_out: endpoint { ++ remote-endpoint = <&hdmi0_in>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dpi0_in: endpoint { ++ remote-endpoint = <&bls_out>; ++ }; ++ }; ++ }; ++}; ++ + ð { + status = "okay"; + +@@ -202,6 +251,42 @@ + }; + }; + ++&hdmi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_pins_a>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ hdmi0_in: endpoint { ++ remote-endpoint = <&dpi0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ hdmi0_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++ }; ++ }; ++}; ++ ++&hdmiddc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_ddc_pins_a>; ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ mediatek,ibias = <0xa>; ++ mediatek,ibias_up = <0x1c>; ++ status = "okay"; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch b/root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch new file mode 100755 index 00000000..71dfebd4 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch @@ -0,0 +1,72 @@ +From fa095b2751309a70d42d9d2f2f0881731b090d18 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 31 Oct 2018 16:59:34 +0800 +Subject: [PATCH 44/77] fix boot up for 720 and 480 but 1080 + +1080 plg in/out with ng/ok + +[ALPSxxxxxxxx] + +[Detail] + +[Solution] + +Change-Id: Icd395eaf635a6cfe03f8f0508ed97ab40cbf6632 +CR-Id: +Feature: +--- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 3 +++ + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 + + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 3 ++- + 3 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index 4ef9c57ffd44..40e08df57f48 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -209,6 +209,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) + return PTR_ERR(phy_provider); + } + ++ if (hdmi_phy->conf->pll_default_off) ++ hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy); ++ + return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, + hdmi_phy->pll); + } +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index f39b1fc66612..a173a27d7a40 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -21,6 +21,7 @@ struct mtk_hdmi_phy; + + struct mtk_hdmi_phy_conf { + bool tz_disabled; ++ bool pll_default_off; + const struct clk_ops *hdmi_phy_clk_ops; + void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); + void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index fcc42dc6ea7f..534bcbc9f3b7 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -116,7 +116,7 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + + if (rate <= 64000000) + pos_div = 3; +- else if (rate <= 12800000) ++ else if (rate <= 128000000) + pos_div = 1; + else + pos_div = 1; +@@ -202,6 +202,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) + + struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { + .tz_disabled = true, ++ .pll_default_off = true, + .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, + .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, + .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch b/root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch new file mode 100755 index 00000000..5b2214a5 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch @@ -0,0 +1,103 @@ +From 4501501b8f55b277f219eaf7e863d91ddb1d8af7 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 31 Oct 2018 17:59:50 +0800 +Subject: [PATCH 45/77] using different round rate for mt7623 + +Change-Id: Ifac315b09d691fe2c056212dd59ae50212417d58 +CR-Id: +Feature: +--- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 -------------- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 -- + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 11 +++++++++++ + drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++ + 4 files changed, 25 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index 40e08df57f48..f014d65fa5ad 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = { + .owner = THIS_MODULE, + }; + +-long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long *parent_rate) +-{ +- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); +- +- hdmi_phy->pll_rate = rate; +- if (rate <= 74250000) +- *parent_rate = rate; +- else +- *parent_rate = rate / 2; +- +- return rate; +-} +- + unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) + { +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index a173a27d7a40..76e352d088d0 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -49,8 +49,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, + void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, + u32 val, u32 mask); + struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); +-long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long *parent_rate); + unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate); + +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index 534bcbc9f3b7..2f87d0320882 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -154,6 +154,17 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ hdmi_phy->pll_rate = rate; ++ *parent_rate = rate; ++ ++ return rate; ++} ++ + static const struct clk_ops mtk_hdmi_phy_pll_ops = { + .prepare = mtk_hdmi_pll_prepare, + .unprepare = mtk_hdmi_pll_unprepare, +diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +index ed5916b27658..d8cb252c6781 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +@@ -285,6 +285,20 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); ++ ++ hdmi_phy->pll_rate = rate; ++ if (rate <= 74250000) ++ *parent_rate = rate; ++ else ++ *parent_rate = rate / 2; ++ ++ return rate; ++} ++ + static const struct clk_ops mtk_hdmi_phy_pll_ops = { + .prepare = mtk_hdmi_pll_prepare, + .unprepare = mtk_hdmi_pll_unprepare, +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch b/root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch new file mode 100755 index 00000000..284ced83 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch @@ -0,0 +1,26 @@ +From 1c978fae6f6112b46d4815c0054fbeab0274a363 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Fri, 16 Nov 2018 16:33:00 +0100 +Subject: [PATCH 46/77] [hdmi] fix possible_crtcs + +source: http://forum.banana-pi.org/t/kernel-4-19-rc1-for-testers/6618/52 +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 62a9d47df948..a066b0755119 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -610,7 +610,7 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) + drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); + + /* Currently DPI0 is fixed to be driven by OVL1 */ +- dpi->encoder.possible_crtcs = BIT(1); ++ dpi->encoder.possible_crtcs = BIT(0)|BIT(1); + + ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL); + if (ret) { +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch b/root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch new file mode 100755 index 00000000..4e173116 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch @@ -0,0 +1,31 @@ +From 88aa4bffe7e5b38e8596e5f09e7b40e8bc112a24 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 16 Nov 2018 16:40:16 +0100 +Subject: [PATCH 47/77] [hdmi] added options to defconfig + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index f5e7a0edda0e..5932b552f2ea 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -652,3 +652,14 @@ CONFIG_POWER_RESET_MT6397_RTC=y + + #CONFIG_NET_MEDIATEK_HW_QOS=m + ++#Graphic ++CONFIG_DRM=y ++CONFIG_DRM_MEDIATEK=y ++CONFIG_DRM_MEDIATEK_HDMI=y ++CONFIG_DRM_ARM=y ++CONFIG_DRM_MALI_DISPLAY=y ++CONFIG_COMMON_CLK_MT2701_MMSYS=y ++CONFIG_COMMON_CLK_MT2701_IMGSYS=y ++CONFIG_COMMON_CLK_MT2701_VDECSYS=y ++#CONFIG_FRAMEBUFFER_CONSOLE=y ++#CONFIG_DRM_FBDEV_EMULATION=y +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch b/root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch new file mode 100755 index 00000000..4ca5483f --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch @@ -0,0 +1,24 @@ +From 7d0222b1fd42f22f0590b71c0e42660974c492d2 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 16 Nov 2018 17:27:50 +0100 +Subject: [PATCH 49/77] [hdmi] added fbdev-options + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 5932b552f2ea..668a6c45177d 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -661,5 +661,5 @@ CONFIG_DRM_MALI_DISPLAY=y + CONFIG_COMMON_CLK_MT2701_MMSYS=y + CONFIG_COMMON_CLK_MT2701_IMGSYS=y + CONFIG_COMMON_CLK_MT2701_VDECSYS=y +-#CONFIG_FRAMEBUFFER_CONSOLE=y +-#CONFIG_DRM_FBDEV_EMULATION=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_DRM_FBDEV_EMULATION=y +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch b/root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch new file mode 100755 index 00000000..e3f7ee41 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch @@ -0,0 +1,69 @@ +From c0603006d7f020bbcb42bed36127fbfe94b1b512 Mon Sep 17 00:00:00 2001 +From: Oleksii Shevchuk +Date: Fri, 11 Jan 2019 18:34:01 +0100 +Subject: [PATCH 50/77] [BT] fix Bluetooth +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +- first call wifi.sh or at least call + wmt_loader + stp-uart-launcher +- then load BT-module “modprobe stp_chrdev_bt†+--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 ++-- + .../common/common_detect/drv_init/bluetooth_drv_init.c | 3 ++- + .../connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c | 3 ++- + 3 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 668a6c45177d..343800fc24d6 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -390,8 +390,8 @@ CONFIG_NL80211_TESTMODE=y + + #internal Bluetooth (also not working yet) + CONFIG_BT=y +-#CONFIG_MTK_COMBO_BT=y +-#CONFIG_MTK_COMBO_BT_HCI=y ++CONFIG_MTK_COMBO_BT=m ++CONFIG_MTK_COMBO_BT_HCI=y + #needed for BT? + #Bluetooth Classic (BR/EDR) features + CONFIG_BT_BREDR=y +diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c +index 47b055433443..82b799f256b4 100644 +--- a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c ++++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c +@@ -23,13 +23,14 @@ + int do_bluetooth_drv_init(int chip_id) + { + int i_ret = -1; +- ++#if 0 + #if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI) + WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n"); + i_ret = mtk_wcn_stpbt_drv_init(); + WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret); + #else + WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n"); ++#endif + #endif + return i_ret; + } +diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c +index 190fa3944d80..5a85f68b092f 100644 +--- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c ++++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c +@@ -877,7 +877,8 @@ static void BT_exit(void) + BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME); + } + +-#ifdef MTK_WCN_REMOVE_KERNEL_MODULE ++#if 0 ++//#ifdef MTK_WCN_REMOVE_KERNEL_MODULE + + int mtk_wcn_stpbt_drv_init(void) + { +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch b/root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch new file mode 100755 index 00000000..7e2e22d2 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch @@ -0,0 +1,34 @@ +From 32d96a7e0127ae64f4c091e8c14f2961619f4fa2 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 20 Jan 2019 13:23:22 +0100 +Subject: [PATCH 53/77] [defconfig] disable some debug-messages (evbug,gpio) + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 343800fc24d6..2a9696b249e9 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -223,7 +223,7 @@ CONFIG_NET_MEDIATEK_SOC=y + + CONFIG_ICPLUS_PHY=y + CONFIG_INPUT_EVDEV=y +-CONFIG_INPUT_EVBUG=m ++#CONFIG_INPUT_EVBUG=m + CONFIG_KEYBOARD_MATRIX=y + CONFIG_KEYBOARD_SAMSUNG=y + CONFIG_KEYBOARD_MTK_PMIC=m +@@ -370,7 +370,7 @@ CONFIG_BTRFS_FS=m + + #GPIO + CONFIG_DEBUG_FS=y +-CONFIG_DEBUG_GPIO=y ++#CONFIG_DEBUG_GPIO=y + CONFIG_GPIO_SYSFS=y + + #wlan +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch b/root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch new file mode 100755 index 00000000..56f9cd2d --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch @@ -0,0 +1,25 @@ +From 04b3085371657fe44d7949168de9a080c61b1607 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 25 Jan 2019 15:08:26 +0100 +Subject: [PATCH 58/77] [defconfig] add multiple routing-tables for IPv4 + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 2a9696b249e9..16fbafbea0c3 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -101,6 +101,8 @@ CONFIG_DUMMY=m + CONFIG_PACKET=y + CONFIG_UNIX=y + CONFIG_INET=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y + CONFIG_IP_PNP=y + CONFIG_IP_PNP_DHCP=y + CONFIG_IP_PNP_BOOTP=y +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch b/root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch new file mode 100755 index 00000000..22ade4c8 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch @@ -0,0 +1,33 @@ +From 4ca583e03d89abdab30393529e048d5fadcffb2b Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 25 Jan 2019 15:53:58 +0100 +Subject: [PATCH 59/77] [defconfig] added options for Traffic Shaping + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 16fbafbea0c3..cd86a013b161 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -98,6 +98,7 @@ CONFIG_APM_EMULATION=y + + CONFIG_NET=y + CONFIG_DUMMY=m ++CONFIG_IFB=m + CONFIG_PACKET=y + CONFIG_UNIX=y + CONFIG_INET=y +@@ -525,6 +526,8 @@ CONFIG_NET_SCH_GRED=m + CONFIG_NET_SCH_DSMARK=m + CONFIG_NET_SCH_INGRESS=m + CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_SCH_FQ_CODEL=m ++CONFIG_NET_ACT_MIRRED=m + CONFIG_NET_QOS=y + CONFIG_NET_ESTIMATOR=y + CONFIG_NET_CLS=y +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch b/root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch new file mode 100755 index 00000000..f3a725b3 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch @@ -0,0 +1,60 @@ +From ac6c3841de57124c49f95da9f50448a82070cce3 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 8 Feb 2019 16:27:44 +0100 +Subject: [PATCH 61/77] [defconfig] add nftables + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 37 ++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index cd86a013b161..6ec6625102b3 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -179,6 +179,43 @@ CONFIG_IP_VS=m + CONFIG_NETFILTER_XT_MATCH_IPVS=m + CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m + ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_IPV4=y ++CONFIG_NF_TABLES_IPV6=y ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_MASQ_IPV4=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_CHAIN_NAT_IPV4=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_QUEUE=m ++CONFIG_NFT_FIB_IPV4=m ++CONFIG_NFT_FIB_IPV6=m ++CONFIG_NFT_FIB_INET=m ++CONFIG_NFT_FIB_NETDEV=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++CONFIG_NFT_FWD_NETDEV=m ++CONFIG_NFT_REDIR_IPV4=m ++CONFIG_NFT_REDIR_IPV6=m ++CONFIG_NFT_CHAIN_ROUTE_IPV4=m ++CONFIG_NFT_CHAIN_ROUTE_IPV6=m ++ + CONFIG_NET_MEDIATEK_HNAT=m + CONFIG_DEBUG_SECTION_MISMATCH=y + +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch b/root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch new file mode 100755 index 00000000..e6532ba2 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch @@ -0,0 +1,100 @@ +From 56aa779864c232422984341490eb1bb96259efe0 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 16 Feb 2019 09:39:43 +0100 +Subject: [PATCH 63/77] [defconfig] add all XT-matches/targets + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 71 +++++++++++++++++++--- + 1 file changed, 62 insertions(+), 9 deletions(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 6ec6625102b3..660b4c234ad2 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -163,21 +163,74 @@ CONFIG_NETFILTER_SYNPROXY=m + CONFIG_IP_NF_TARGET_SYNPROXY=m + CONFIG_IP6_NF_TARGET_SYNPROXY=m + ++CONFIG_IP_VS=m ++ + CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +-CONFIG_NETFILTER_XT_MATCH_LIMIT=m +-CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HL=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m + CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NETMAP=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_RATEEST=m ++CONFIG_NETFILTER_XT_TARGET_REDIRECT=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m + CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++# Xtables matches ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CGROUP=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m + CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +-CONFIG_NETFILTER_XT_MATCH_MAC=m +-CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ECN=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_HL=m ++CONFIG_NETFILTER_XT_MATCH_IPCOMP=m + CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +-CONFIG_NETFILTER_XT_MARK=m +-CONFIG_NETFILTER_XT_CONNMARK=m +-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +-CONFIG_IP_VS=m + CONFIG_NETFILTER_XT_MATCH_IPVS=m +-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_L2TP=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SCTP=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++ + + CONFIG_NF_TABLES=m + CONFIG_NF_TABLES_IPV4=y +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch b/root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch new file mode 100755 index 00000000..ff38a894 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch @@ -0,0 +1,34 @@ +From 769d236f61e884cc24897f23ede001744a77a469 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sat, 16 Feb 2019 17:26:51 +0100 +Subject: [PATCH 64/77] [dsa] fix oops in br_vlan_enabled + +--- + net/dsa/port.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/dsa/port.c b/net/dsa/port.c +index ed0595459df1..0891c6f554dc 100644 +--- a/net/dsa/port.c ++++ b/net/dsa/port.c +@@ -255,7 +255,7 @@ int dsa_port_vlan_add(struct dsa_port *dp, + if (netif_is_bridge_master(vlan->obj.orig_dev)) + return -EOPNOTSUPP; + +- if (br_vlan_enabled(dp->bridge_dev)) ++ if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) + return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); + + return 0; +@@ -273,7 +273,7 @@ int dsa_port_vlan_del(struct dsa_port *dp, + if (netif_is_bridge_master(vlan->obj.orig_dev)) + return -EOPNOTSUPP; + +- if (br_vlan_enabled(dp->bridge_dev)) ++ if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) + return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); + + return 0; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch b/root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch new file mode 100755 index 00000000..329d9bd2 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch @@ -0,0 +1,25 @@ +From b0ff7f6f16836ac39eb8a66f3cee3d7cee7cd3fc Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Sun, 17 Feb 2019 18:02:51 +0100 +Subject: [PATCH 66/77] [defconfig] enable mt76x2 + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 660b4c234ad2..44b34cac3614 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -506,7 +506,7 @@ CONFIG_RFKILL_INPUT=y + CONFIG_RFKILL_GPIO=y + + #if you use a mt76x2 or mt76x3 pcie-card +-#CONFIG_MT76=m ++CONFIG_MT76x2E=m + + #pcie + CONFIG_PCIEPORTBUS=y +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch b/root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch new file mode 100755 index 00000000..383766be --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch @@ -0,0 +1,34 @@ +From 4b2f75faab7f63d9cbddd99080632a8767cda28c Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 19 Feb 2019 17:25:57 +0100 +Subject: [PATCH 67/77] [dsa] fix from florian + +--- + net/dsa/port.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/dsa/port.c b/net/dsa/port.c +index 0891c6f554dc..792a13068c50 100644 +--- a/net/dsa/port.c ++++ b/net/dsa/port.c +@@ -255,7 +255,7 @@ int dsa_port_vlan_add(struct dsa_port *dp, + if (netif_is_bridge_master(vlan->obj.orig_dev)) + return -EOPNOTSUPP; + +- if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) ++ if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev)) + return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); + + return 0; +@@ -273,7 +273,7 @@ int dsa_port_vlan_del(struct dsa_port *dp, + if (netif_is_bridge_master(vlan->obj.orig_dev)) + return -EOPNOTSUPP; + +- if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) ++ if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev)) + return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); + + return 0; +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch b/root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch new file mode 100755 index 00000000..442b9c5a --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch @@ -0,0 +1,35 @@ +From 9cbdef979d2119a250d4b8724b247f2a4cad899c Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 20 Feb 2019 17:29:38 +0100 +Subject: [PATCH 68/77] [defconfig] add atheros wireless lan 9k/10k support + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index 44b34cac3614..ad85e0d37e3f 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -630,9 +630,17 @@ CONFIG_NET_CLS_RSVP=m + CONFIG_NET_CLS_RSVP6=m + CONFIG_NET_CLS_POLICE=y + ++CONFIG_WLAN_VENDOR_ATH=y ++CONFIG_ATH9K=m ++CONFIG_ATH9K_PCI=y ++CONFIG_ATH9K_RFKILL=y ++CONFIG_ATH9K_HWRNG=y ++CONFIG_ATH10K=m ++CONFIG_ATH10K_PCI=m ++ ++ + #unused drivers which are set by default + CONFIG_WLAN_VENDOR_ADMTEK=n +-CONFIG_WLAN_VENDOR_ATH=n + CONFIG_WLAN_VENDOR_ATMEL=n + CONFIG_WLAN_VENDOR_BROADCOM=n + CONFIG_WLAN_VENDOR_CISCO=n +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch b/root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch new file mode 100755 index 00000000..43390eae --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch @@ -0,0 +1,47 @@ +From e5c7c5e17a52863ff61fa7f8cdee9c8c4ae036ec Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 8 Mar 2019 17:17:41 +0100 +Subject: [PATCH 72/77] [defconfig] add ebtables + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 24 ++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index ad85e0d37e3f..b49b5feee3eb 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -269,6 +269,30 @@ CONFIG_NFT_REDIR_IPV6=m + CONFIG_NFT_CHAIN_ROUTE_IPV4=m + CONFIG_NFT_CHAIN_ROUTE_IPV6=m + ++#ebtables ++CONFIG_NF_TABLES_BRIDGE=y ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_IP6=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++ + CONFIG_NET_MEDIATEK_HNAT=m + CONFIG_DEBUG_SECTION_MISMATCH=y + +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch b/root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch new file mode 100755 index 00000000..7d993c37 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch @@ -0,0 +1,78 @@ +From f290d46885f04adeed948a332ff333e258fb6868 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 20 Mar 2019 17:29:14 +0100 +Subject: [PATCH 74/77] add compiler-gcc8.h + +--- + include/linux/compiler-gcc8.h | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + create mode 100644 include/linux/compiler-gcc8.h + +diff --git a/include/linux/compiler-gcc8.h b/include/linux/compiler-gcc8.h +new file mode 100644 +index 000000000000..eecd5e1fd781 +--- /dev/null ++++ b/include/linux/compiler-gcc8.h +@@ -0,0 +1,59 @@ ++#ifndef __LINUX_COMPILER_H ++#error "Please don't include directly, include instead." ++#endif ++ ++#define __used __attribute__((__used__)) ++#define __must_check __attribute__((warn_unused_result)) ++#define __compiler_offsetof(a, b) __builtin_offsetof(a, b) ++ ++/* Mark functions as cold. gcc will assume any path leading to a call ++ to them will be unlikely. This means a lot of manual unlikely()s ++ are unnecessary now for any paths leading to the usual suspects ++ like BUG(), printk(), panic() etc. [but let's keep them for now for ++ older compilers] ++ ++ gcc also has a __attribute__((__hot__)) to move hot functions into ++ a special section, but I don't see any sense in this right now in ++ the kernel context */ ++#define __cold __attribute__((__cold__)) ++ ++#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) ++ ++#ifndef __CHECKER__ ++# define __compiletime_warning(message) __attribute__((warning(message))) ++# define __compiletime_error(message) __attribute__((error(message))) ++#endif /* __CHECKER__ */ ++ ++/* ++ * Mark a position in code as unreachable. This can be used to ++ * suppress control flow warnings after asm blocks that transfer ++ * control elsewhere. ++ */ ++#define unreachable() __builtin_unreachable() ++ ++/* Mark a function definition as prohibited from being cloned. */ ++#define __noclone __attribute__((__noclone__)) ++ ++/* ++ * Tell the optimizer that something else uses this function or variable. ++ */ ++#define __visible __attribute__((externally_visible)) ++ ++/* ++ * GCC 'asm goto' miscompiles certain code sequences: ++ * ++ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 ++ * ++ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. ++ * ++ * (asm goto is automatically volatile - the naming reflects this.) ++ */ ++#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) ++ ++#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP ++#define __HAVE_BUILTIN_BSWAP32__ ++#define __HAVE_BUILTIN_BSWAP64__ ++#define __HAVE_BUILTIN_BSWAP16__ ++#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ ++ ++#define KASAN_ABI_VERSION 6 +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch b/root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch new file mode 100755 index 00000000..a733d587 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch @@ -0,0 +1,37 @@ +From f78e2765e6588afd6264c128a060642ed0f6b323 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 12 Apr 2019 11:43:37 +0200 +Subject: [PATCH 76/77] [defconfig] add mqueue and seccomp for docker + +--- + arch/arm/configs/mt7623n_evb_fwu_defconfig | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig +index b49b5feee3eb..314a07cf92fd 100644 +--- a/arch/arm/configs/mt7623n_evb_fwu_defconfig ++++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig +@@ -22,7 +22,6 @@ CONFIG_CGROUP_SCHED=y + CONFIG_CPUSETS=y + #some options for docker + CONFIG_CGROUP_FREEZER=y +-CONFIG_POSIX_MQUEUE=y + CONFIG_OVERLAY_FS=y + CONFIG_MEMCG_SWAP=y + CONFIG_MEMCG_SWAP_ENABLED=y +@@ -131,6 +130,12 @@ CONFIG_IP_PIMSM_V2=y + CONFIG_UNIX_DIAG=m + CONFIG_PACKET_DIAG=m + ++#added for docker ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_SECCOMP_FILTER=y ++CONFIG_SECCOMP=y + + CONFIG_IPV6=m + CONFIG_NETFILTER=y +-- +2.19.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch b/root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch new file mode 100755 index 00000000..348035d1 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch @@ -0,0 +1,397 @@ +From 004eb24e939b5b31f828333f37fb5cb2a877d6f2 Mon Sep 17 00:00:00 2001 +From: Kristian Evensen +Date: Sun, 17 Jun 2018 14:41:47 +0200 +Subject: [PATCH] arm: dts: Add Unielec U7623 DTS + +--- + arch/arm/boot/dts/Makefile | 1 + + .../dts/mt7623a-unielec-u7623-02-emmc-512M.dts | 18 + + .../boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi | 366 +++++++++++++++++++++ + 3 files changed, 385 insertions(+) + create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512M.dts + create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1062,7 +1062,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt6589-aquaris5.dtb \ + mt6592-evb.dtb \ + mt7623a-rfb-emmc.dtb \ ++ mt7623a-unielec-u7623-02-emmc-512M.dtb \ + mt7623a-rfb-nand.dtb \ + mt7623n-rfb-emmc.dtb \ + mt7623n-bananapi-bpi-r2.dtb \ + mt8127-moose.dtb \ +--- /dev/null ++++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512M.dts +@@ -0,0 +1,18 @@ ++/* ++ * Copyright 2018 Kristian Evensen ++ * ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ */ ++ ++/dts-v1/; ++#include "mt7623a-unielec-u7623-02-emmc.dtsi" ++ ++/ { ++ model = "UniElec U7623-02 eMMC (512M RAM)"; ++ compatible = "unielec,u7623-02-emmc-512m", "unielec,u7623-02-emmc", "mediatek,mt7623"; ++ ++ memory@80000000 { ++ device_type = "memory"; ++ reg = <0 0x80000000 0 0x20000000>; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi +@@ -0,0 +1,349 @@ ++/* ++ * Copyright 2018 Kristian Evensen ++ * ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ */ ++ ++#include ++#include "mt7623.dtsi" ++#include "mt6323.dtsi" ++ ++/ { ++ compatible = "unielec,u7623-02-emmc", "mediatek,mt7623"; ++ ++ aliases { ++ serial2 = &uart2; ++ }; ++ ++ chosen { ++ bootargs = "root=/dev/mmcblk0p2 rootfstype=squashfs,f2fs"; ++ stdout-path = "serial2:115200n8"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ ++ cpu@2 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ ++ cpu@3 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_5v: regulator-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&key_pins_a>; ++ ++ factory { ++ label = "factory"; ++ linux,code = ; ++ gpios = <&pio 256 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_pins_unielec>; ++ ++ led3 { ++ label = "u7623-01:green:led3"; ++ gpios = <&pio 14 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ led4 { ++ label = "u7623-01:green:led4"; ++ gpios = <&pio 15 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++ ++ mt7530: switch@0 { ++ compatible = "mediatek,mt7530"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++}; ++ ++&crypto { ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ mdio: mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ phy5: ethernet-phy@5 { ++ reg = <5>; ++ phy-mode = "rgmii-rxid"; ++ }; ++ }; ++}; ++ ++&mt7530 { ++ compatible = "mediatek,mt7530"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ pinctrl-names = "default"; ++ mediatek,mcm; ++ resets = <ðsys 2>; ++ reset-names = "mcm"; ++ core-supply = <&mt6323_vpa_reg>; ++ io-supply = <&mt6323_vemc3v3_reg>; ++ ++ dsa,mii-bus = <&mdio>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ ++ port@0 { ++ reg = <0>; ++ label = "lan0"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ label = "lan1"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ label = "lan2"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "lan3"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@4 { ++ reg = <4>; ++ label = "wan"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ cpu_port0: port@6 { ++ reg = <6>; ++ label = "cpu"; ++ ethernet = <&gmac0>; ++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ }; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default", "state_uhs"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ pinctrl-1 = <&mmc0_pins_uhs>; ++ status = "okay"; ++ bus-width = <8>; ++ max-frequency = <50000000>; ++ cap-mmc-highspeed; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_1p8v>; ++ non-removable; ++}; ++ ++&pio { ++ key_pins_a: keys-alt { ++ pins-keys { ++ pinmux = , ++ ; ++ input-enable; ++ }; ++ }; ++ ++ led_pins_unielec: leds-unielec { ++ pins-leds { ++ pinmux = , ++ ; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ pins_cmd_dat { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ pins_clk { ++ pinmux = ; ++ bias-pull-down; ++ }; ++ ++ pins_rst { ++ pinmux = ; ++ bias-pull-up; ++ }; ++ }; ++ ++ mmc0_pins_uhs: mmc0 { ++ pins_cmd_dat { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ pins_clk { ++ pinmux = ; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ pins_rst { ++ pinmux = ; ++ bias-pull-up; ++ }; ++ }; ++ ++ pcie_default: pcie_pin_default { ++ pins_cmd_dat { ++ pinmux = , ++ ; ++ bias-disable; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins_a>; ++ status = "okay"; ++}; ++ ++&pwrap { ++ mt6323 { ++ mt6323led: led { ++ compatible = "mediatek,mt6323-led"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ led@0 { ++ reg = <0>; ++ label = "led0"; ++ default-state = "off"; ++ }; ++ }; ++ }; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins_b>; ++ status = "okay"; ++}; ++ ++&usb1 { ++ vusb33-supply = <®_3p3v>; ++ vbus-supply = <®_3p3v>; ++ status = "okay"; ++}; ++ ++&u3phy1 { ++ status = "okay"; ++}; ++ ++&u3phy2 { ++ status = "okay"; ++ mediatek,phy-switch = <&hifsys>; ++}; ++ ++&pcie { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_default>; ++ status = "okay"; ++ ++ pcie@1,0 { ++ status = "okay"; ++ }; ++ ++ pcie@2,0 { ++ status = "okay"; ++ }; ++}; ++ ++&pcie1_phy { ++ status = "okay"; ++}; ++ diff --git a/root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch b/root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch new file mode 100755 index 00000000..5b8e6131 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch @@ -0,0 +1,35 @@ +From 16c20209050ce9dc0d67e256c3dfba902868c3ed Mon Sep 17 00:00:00 2001 +From: Nikolay Amiantov +Date: Tue, 3 Jul 2018 12:40:04 +0000 +Subject: [PATCH] Revert "fs: unexport vfs_read and vfs_write" + +This reverts commit bd8df82be66698042d11e7919e244c8d72b042ca. +--- + fs/read_write.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/read_write.c b/fs/read_write.c +index 0046d72efe94..62b9c341afa9 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -455,6 +455,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) + return ret; + } + ++EXPORT_SYMBOL(vfs_read); ++ + static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) + { + struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; +@@ -553,6 +555,8 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ + return ret; + } + ++EXPORT_SYMBOL(vfs_write); ++ + static inline loff_t file_pos_read(struct file *file) + { + return file->f_pos; +-- +2.17.1 + diff --git a/root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch b/root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch new file mode 100755 index 00000000..bc957ee1 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch @@ -0,0 +1,127 @@ +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c +@@ -519,6 +519,9 @@ INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl( + } + + #endif ++ ++EXPORT_SYMBOL(mtk_wcn_consys_hw_wifi_paldo_ctrl); ++ + INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) + { + if (enable) { +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c +@@ -4530,13 +4530,10 @@ INT_32 kalHaltLock(UINT_32 waitMs) + DBGLOG(INIT, ERROR, + "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", + kalGetTimeTick() - rHaltCtrl.u4HoldStart); +- if (prGlueInfo) +- show_stack(prGlueInfo->main_thread, NULL); + } else { + DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", + rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, + kalGetTimeTick() - rHaltCtrl.u4HoldStart); +- show_stack(rHaltCtrl.owner, NULL); + } + return i4Ret; + } +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c +@@ -58,7 +58,6 @@ + ******************************************************************************** + */ + BOOLEAN fgIsResetting = FALSE; +-UINT_32 g_IsNeedDoChipReset = 0; + + /******************************************************************************* + * P R I V A T E D A T A +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +@@ -44,6 +44,9 @@ MODULE_LICENSE("Dual BSD/GPL"); + #define WIFI_LOG_WARN 1 + #define WIFI_LOG_ERR 0 + ++UINT32 g_IsNeedDoChipReset = 0; ++EXPORT_SYMBOL(g_IsNeedDoChipReset); ++ + UINT32 gDbgLevel = WIFI_LOG_DBG; + + #define WIFI_DBG_FUNC(fmt, arg...)\ +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile +@@ -21,7 +21,11 @@ endif + obj-y += osal.o \ + bgw_desense.o \ + wmt_idc.o +-obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o +-obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o ++ifneq ($(CONFIG_MTK_COMBO_BT),) ++ obj-y += stp_chrdev_bt.o ++endif ++ifneq ($(CONFIG_MTK_COMBO_WIFI),) ++ obj-y += wmt_chrdev_wifi.o ++endif + + endif +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c +@@ -25,7 +25,7 @@ int do_wlan_drv_init(int chip_id) + { + int i_ret = 0; + +-#ifdef CONFIG_MTK_COMBO_WIFI ++#ifdef MTK_WIFI_ENABLED + int ret = 0; + + WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); +@@ -35,6 +35,7 @@ int do_wlan_drv_init(int chip_id) + WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); + i_ret += ret; + ++#ifdef CONFIG_MTK_COMBO_WIFI + switch (chip_id) { + case 0x6630: + case 0x6797: +@@ -61,13 +62,10 @@ int do_wlan_drv_init(int chip_id) + #endif + break; + } +- ++#endif + WMT_DETECT_INFO_FUNC("finish wlan module init\n"); +- + #else +- + WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); +- + #endif + + return i_ret; +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile +@@ -11,6 +11,10 @@ else ifneq ($(filter "CONSYS_%",$(CONFIG + ccflags-y += -D MTK_WCN_WLAN_GEN2 + endif + ++ifneq ($(CONFIG_MTK_COMBO_WIFI),) ++ ccflags-y += -D MTK_WIFI_ENABLED ++endif ++ + obj-y += conn_drv_init.o + obj-y += common_drv_init.o + obj-y += bluetooth_drv_init.o diff --git a/root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch b/root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch new file mode 100755 index 00000000..a9f2078c --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch @@ -0,0 +1,12 @@ +Index: linux-4.14.51/drivers/watchdog/mtk_wdt.c +=================================================================== +--- linux-4.14.51.orig/drivers/watchdog/mtk_wdt.c ++++ linux-4.14.51/drivers/watchdog/mtk_wdt.c +@@ -236,7 +236,6 @@ static int mtk_wdt_ping(struct watchdog_ + void __iomem *wdt_base = mtk_wdt->wdt_base; + + iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); +- printk_deferred("[WDK]: kick Ex WDT\n"); + + return 0; + } diff --git a/root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch b/root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch new file mode 100755 index 00000000..e1691fd3 --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch @@ -0,0 +1,13 @@ +Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +=================================================================== +--- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c ++++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c +@@ -62,7 +62,7 @@ UINT32 gDbgLevel = WIFI_LOG_DBG; + + #define VERSION "1.0" + +-#define WLAN_IFACE_NAME "wlan0" ++#define WLAN_IFACE_NAME "mtkwlan0" + #if CFG_TC1_FEATURE + #define LEGACY_IFACE_NAME "legacy0" + #endif diff --git a/root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch b/root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch new file mode 100755 index 00000000..4239690c --- /dev/null +++ b/root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch @@ -0,0 +1,20 @@ +--- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c 2019-11-19 10:19:47.020273630 +0100 ++++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c 2019-11-19 10:20:52.819020893 +0100 +@@ -1544,7 +1544,7 @@ + DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n"); + + prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer); +- memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), ++ memmove(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), + sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T)); + + mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, +@@ -1647,7 +1647,7 @@ + { + DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n"); + prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer); +- memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), ++ memmove(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), + sizeof(EVENT_GSCAN_SCAN_COMPLETE_T)); + + mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, diff --git a/root/target/linux/mediatek/patches-5.14/100-dts-update-mt7622-rfb1.patch b/root/target/linux/mediatek/patches-5.14/100-dts-update-mt7622-rfb1.patch new file mode 100755 index 00000000..f4e77cf6 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/100-dts-update-mt7622-rfb1.patch @@ -0,0 +1,119 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +@@ -1,7 +1,6 @@ + /* +- * Copyright (c) 2017 MediaTek Inc. +- * Author: Ming Huang +- * Sean Wang ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Ryder Lee + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ +@@ -23,7 +22,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; + }; + + cpus { +@@ -40,23 +39,22 @@ + + gpio-keys { + compatible = "gpio-keys"; +- poll-interval = <100>; + + factory { + label = "factory"; + linux,code = ; +- gpios = <&pio 0 0>; ++ gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + linux,code = ; +- gpios = <&pio 102 0>; ++ gpios = <&pio 102 GPIO_ACTIVE_LOW>; + }; + }; + + memory { +- reg = <0 0x40000000 0 0x20000000>; ++ reg = <0 0x40000000 0 0x40000000>; + }; + + reg_1p8v: regulator-1p8v { +@@ -132,22 +130,22 @@ + + port@0 { + reg = <0>; +- label = "lan0"; ++ label = "lan1"; + }; + + port@1 { + reg = <1>; +- label = "lan1"; ++ label = "lan2"; + }; + + port@2 { + reg = <2>; +- label = "lan2"; ++ label = "lan3"; + }; + + port@3 { + reg = <3>; +- label = "lan3"; ++ label = "lan4"; + }; + + port@4 { +@@ -236,15 +234,28 @@ + + &pcie { + pinctrl-names = "default"; +- pinctrl-0 = <&pcie0_pins>; ++ pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + }; ++ ++ pcie@1,0 { ++ status = "okay"; ++ }; + }; + + &pio { ++ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and ++ * SATA functions. i.e. output-high: PCIe, output-low: SATA ++ */ ++ asm_sel { ++ gpio-hog; ++ gpios = <90 GPIO_ACTIVE_HIGH>; ++ output-high; ++ }; ++ + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { +@@ -511,11 +522,11 @@ + }; + + &sata { +- status = "okay"; ++ status = "disabled"; + }; + + &sata_phy { +- status = "okay"; ++ status = "disabled"; + }; + + &spi0 { diff --git a/root/target/linux/mediatek/patches-5.14/101-dts-update-mt7629-rfb.patch b/root/target/linux/mediatek/patches-5.14/101-dts-update-mt7629-rfb.patch new file mode 100755 index 00000000..254b5f9e --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/101-dts-update-mt7629-rfb.patch @@ -0,0 +1,60 @@ +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -18,6 +18,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8"; + }; + + gpio-keys { +@@ -70,6 +71,10 @@ + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; ++ ++ nvmem-cells = <&macaddr_factory_2a>; ++ nvmem-cell-names = "mac-address"; ++ + fixed-link { + speed = <2500>; + full-duplex; +@@ -82,6 +87,9 @@ + reg = <1>; + phy-mode = "gmii"; + phy-handle = <&phy0>; ++ ++ nvmem-cells = <&macaddr_factory_24>; ++ nvmem-cell-names = "mac-address"; + }; + + mdio: mdio-bus { +@@ -133,8 +141,9 @@ + }; + + partition@b0000 { +- label = "kernel"; ++ label = "firmware"; + reg = <0xb0000 0xb50000>; ++ compatible = "denx,fit"; + }; + }; + }; +@@ -272,3 +281,17 @@ + pinctrl-0 = <&watchdog_pins>; + status = "okay"; + }; ++ ++&factory { ++ compatible = "nvmem-cells"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ macaddr_factory_24: macaddr@24 { ++ reg = <0x24 0x6>; ++ }; ++ ++ macaddr_factory_2a: macaddr@2a { ++ reg = <0x2a 0x6>; ++ }; ++}; diff --git a/root/target/linux/mediatek/patches-5.14/105-dts-mt7622-enable-pstore.patch b/root/target/linux/mediatek/patches-5.14/105-dts-mt7622-enable-pstore.patch new file mode 100755 index 00000000..6ef56f85 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/105-dts-mt7622-enable-pstore.patch @@ -0,0 +1,25 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -111,7 +111,7 @@ + }; + + psci { +- compatible = "arm,psci-0.2"; ++ compatible = "arm,psci-1.0"; + method = "smc"; + }; + +@@ -127,6 +127,13 @@ + #size-cells = <2>; + ranges; + ++ /* 64 KiB reserved for ramoops/pstore */ ++ ramoops@0x42ff0000 { ++ compatible = "ramoops"; ++ reg = <0 0x42ff0000 0 0x10000>; ++ record-size = <0x1000>; ++ }; ++ + /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + secmon_reserved: secmon@43000000 { + reg = <0 0x43000000 0 0x30000>; diff --git a/root/target/linux/mediatek/patches-5.14/110-dts-fix-bpi2-console.patch b/root/target/linux/mediatek/patches-5.14/110-dts-fix-bpi2-console.patch new file mode 100755 index 00000000..8dc53d29 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/110-dts-fix-bpi2-console.patch @@ -0,0 +1,10 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -19,6 +19,7 @@ + + chosen { + stdout-path = "serial2:115200n8"; ++ bootargs = "console=ttyS2,115200n8 console=tty1"; + }; + + connector { diff --git a/root/target/linux/mediatek/patches-5.14/111-dts-fix-bpi64-console.patch b/root/target/linux/mediatek/patches-5.14/111-dts-fix-bpi64-console.patch new file mode 100755 index 00000000..07a2eae2 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/111-dts-fix-bpi64-console.patch @@ -0,0 +1,11 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -22,7 +22,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; + }; + + cpus { diff --git a/root/target/linux/mediatek/patches-5.14/112-dts-fix-bpi64-lan-names.patch b/root/target/linux/mediatek/patches-5.14/112-dts-fix-bpi64-lan-names.patch new file mode 100755 index 00000000..6ce85efd --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/112-dts-fix-bpi64-lan-names.patch @@ -0,0 +1,37 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -18,6 +18,7 @@ + + aliases { + serial0 = &uart0; ++ ethernet0 = &gmac0; + }; + + chosen { +@@ -160,22 +161,22 @@ + + port@1 { + reg = <1>; +- label = "lan0"; ++ label = "lan1"; + }; + + port@2 { + reg = <2>; +- label = "lan1"; ++ label = "lan2"; + }; + + port@3 { + reg = <3>; +- label = "lan2"; ++ label = "lan3"; + }; + + port@4 { + reg = <4>; +- label = "lan3"; ++ label = "lan4"; + }; + + port@6 { diff --git a/root/target/linux/mediatek/patches-5.14/113-dts-fix-bpi64-leds-and-buttons.patch b/root/target/linux/mediatek/patches-5.14/113-dts-fix-bpi64-leds-and-buttons.patch new file mode 100755 index 00000000..f88dbc71 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/113-dts-fix-bpi64-leds-and-buttons.patch @@ -0,0 +1,56 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -19,6 +19,10 @@ + aliases { + serial0 = &uart0; + ethernet0 = &gmac0; ++ led-boot = &led_system_green; ++ led-failsafe = &led_system_blue; ++ led-running = &led_system_green; ++ led-upgrade = &led_system_blue; + }; + + chosen { +@@ -42,8 +46,8 @@ + compatible = "gpio-keys"; + + factory { +- label = "factory"; +- linux,code = ; ++ label = "reset"; ++ linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_HIGH>; + }; + +@@ -57,17 +61,25 @@ + leds { + compatible = "gpio-leds"; + +- green { +- label = "bpi-r64:pio:green"; +- gpios = <&pio 89 GPIO_ACTIVE_HIGH>; ++ led_system_blue: blue { ++ label = "bpi-r64:pio:blue"; ++ gpios = <&pio 85 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + +- red { +- label = "bpi-r64:pio:red"; +- gpios = <&pio 88 GPIO_ACTIVE_HIGH>; ++ led_system_green: green { ++ label = "bpi-r64:pio:green"; ++ gpios = <&pio 89 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; ++ ++/* ++ * red { ++ * label = "bpi-r64:pio:red"; ++ * gpios = <&pio 88 GPIO_ACTIVE_HIGH>; ++ * default-state = "off"; ++ * }; ++ */ + }; + + memory { diff --git a/root/target/linux/mediatek/patches-5.14/114-dts-bpi64-disable-rtc.patch b/root/target/linux/mediatek/patches-5.14/114-dts-bpi64-disable-rtc.patch new file mode 100755 index 00000000..261579bf --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/114-dts-bpi64-disable-rtc.patch @@ -0,0 +1,21 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -559,12 +559,16 @@ + status = "okay"; + }; + ++&rtc { ++ status = "disabled"; ++}; ++ + &sata { +- status = "disable"; ++ status = "disabled"; + }; + + &sata_phy { +- status = "disable"; ++ status = "disabled"; + }; + + &spi0 { diff --git a/root/target/linux/mediatek/patches-5.14/115-dts-bpi64-add-snand-support.patch b/root/target/linux/mediatek/patches-5.14/115-dts-bpi64-add-snand-support.patch new file mode 100755 index 00000000..39d81bd5 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/115-dts-bpi64-add-snand-support.patch @@ -0,0 +1,41 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -259,14 +259,32 @@ + status = "disabled"; + }; + +-&nor_flash { ++&snand { + pinctrl-names = "default"; +- pinctrl-0 = <&spi_nor_pins>; +- status = "disabled"; ++ pinctrl-0 = <&serial_nand_pins>; ++ mediatek,quad-spi; ++ status = "okay"; ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "bl2"; ++ reg = <0x0 0x80000>; ++ read-only; ++ }; ++ ++ partition@80000 { ++ label = "fip"; ++ reg = <0x80000 0x200000>; ++ read-only; ++ }; + +- flash@0 { +- compatible = "jedec,spi-nor"; +- reg = <0>; ++ partition@280000 { ++ label = "ubi"; ++ reg = <0x280000 0x7d80000>; ++ }; + }; + }; + diff --git a/root/target/linux/mediatek/patches-5.14/130-dts-mt7629-add-snand-support.patch b/root/target/linux/mediatek/patches-5.14/130-dts-mt7629-add-snand-support.patch new file mode 100755 index 00000000..e7c5d9b1 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/130-dts-mt7629-add-snand-support.patch @@ -0,0 +1,77 @@ +From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Thu, 6 Jun 2019 16:29:04 +0800 +Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629 + +Signed-off-by: Xiangsheng Hou +--- + arch/arm/boot/dts/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++ + arch/arm/boot/dts/mt7629.dtsi | 22 ++++++++++++++++ + 3 files changed, 79 insertions(+) + +--- a/arch/arm/boot/dts/mt7629.dtsi ++++ b/arch/arm/boot/dts/mt7629.dtsi +@@ -272,6 +272,22 @@ + status = "disabled"; + }; + ++ snand: snfi@1100d000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ compatible = "mediatek,mt7629-snand"; ++ reg = <0x1100d000 0x1000>, <0x1100e000 0x1000>; ++ reg-names = "nfi", "ecc"; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFI_PD>, ++ <&pericfg CLK_PERI_SNFI_PD>, ++ <&pericfg CLK_PERI_NFIECC_PD>; ++ clock-names = "nfi_clk", "pad_clk", "ecc_clk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + spi: spi@1100a000 { + compatible = "mediatek,mt7629-spi", + "mediatek,mt7622-spi"; +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -254,6 +254,38 @@ + }; + }; + ++&snand { ++ status = "okay"; ++ mediatek,quad-spi; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Bootloader"; ++ reg = <0x00000 0x0100000>; ++ read-only; ++ }; ++ ++ partition@100000 { ++ label = "Config"; ++ reg = <0x100000 0x0040000>; ++ }; ++ ++ partition@140000 { ++ label = "factory"; ++ reg = <0x140000 0x0080000>; ++ }; ++ ++ partition@1c0000 { ++ label = "firmware"; ++ reg = <0x1c0000 0x1000000>; ++ }; ++ }; ++}; ++ + &spi { + pinctrl-names = "default"; + pinctrl-0 = <&spi_pins>; diff --git a/root/target/linux/mediatek/patches-5.14/131-dts-mt7622-add-snand-support.patch b/root/target/linux/mediatek/patches-5.14/131-dts-mt7622-add-snand-support.patch new file mode 100755 index 00000000..fe136c24 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/131-dts-mt7622-add-snand-support.patch @@ -0,0 +1,81 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -561,6 +561,20 @@ + status = "disabled"; + }; + ++ snand: snfi@1100d000 { ++ compatible = "mediatek,mt7622-snand"; ++ reg = <0 0x1100d000 0 0x1000>, <0 0x1100e000 0 0x1000>; ++ reg-names = "nfi", "ecc"; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFI_PD>, ++ <&pericfg CLK_PERI_SNFI_PD>, ++ <&pericfg CLK_PERI_NFIECC_PD>; ++ clock-names = "nfi_clk", "pad_clk", "ecc_clk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + nor_flash: spi@11014000 { + compatible = "mediatek,mt7622-nor", + "mediatek,mt8173-nor"; +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +@@ -529,6 +529,55 @@ + status = "disabled"; + }; + ++&snand { ++ mediatek,quad-spi; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Preloader"; ++ reg = <0x00000 0x0080000>; ++ read-only; ++ }; ++ ++ partition@80000 { ++ label = "ATF"; ++ reg = <0x80000 0x0040000>; ++ }; ++ ++ partition@c0000 { ++ label = "Bootloader"; ++ reg = <0xc0000 0x0080000>; ++ }; ++ ++ partition@140000 { ++ label = "Config"; ++ reg = <0x140000 0x0080000>; ++ }; ++ ++ partition@1c0000 { ++ label = "Factory"; ++ reg = <0x1c0000 0x0100000>; ++ }; ++ ++ partition@200000 { ++ label = "firmware"; ++ reg = <0x2c0000 0x2000000>; ++ }; ++ ++ partition@2200000 { ++ label = "User_data"; ++ reg = <0x22c0000 0x4000000>; ++ }; ++ }; ++}; ++ + &spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; diff --git a/root/target/linux/mediatek/patches-5.14/150-dts-mt7623-eip97-inside-secure-support.patch b/root/target/linux/mediatek/patches-5.14/150-dts-mt7623-eip97-inside-secure-support.patch new file mode 100755 index 00000000..38947a3a --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/150-dts-mt7623-eip97-inside-secure-support.patch @@ -0,0 +1,23 @@ +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -949,17 +949,14 @@ + }; + + crypto: crypto@1b240000 { +- compatible = "mediatek,eip97-crypto"; ++ compatible = "inside-secure,safexcel-eip97"; + reg = <0 0x1b240000 0 0x20000>; + interrupts = , + , + , +- , +- ; ++ ; ++ interrupt-names = "ring0", "ring1", "ring2", "ring3"; + clocks = <ðsys CLK_ETHSYS_CRYPTO>; +- clock-names = "cryp"; +- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; +- status = "disabled"; + }; + + bdpsys: syscon@1c000000 { diff --git a/root/target/linux/mediatek/patches-5.14/160-dts-mt7623-bpi-r2-earlycon.patch b/root/target/linux/mediatek/patches-5.14/160-dts-mt7623-bpi-r2-earlycon.patch new file mode 100755 index 00000000..091cffc3 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/160-dts-mt7623-bpi-r2-earlycon.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -19,7 +19,7 @@ + + chosen { + stdout-path = "serial2:115200n8"; +- bootargs = "console=ttyS2,115200n8 console=tty1"; ++ bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1"; + }; + + connector { diff --git a/root/target/linux/mediatek/patches-5.14/161-dts-mt7623-bpi-r2-mmc-device-order.patch b/root/target/linux/mediatek/patches-5.14/161-dts-mt7623-bpi-r2-mmc-device-order.patch new file mode 100755 index 00000000..d1bafc15 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/161-dts-mt7623-bpi-r2-mmc-device-order.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -15,6 +15,8 @@ + + aliases { + serial2 = &uart2; ++ mmc0 = &mmc0; ++ mmc1 = &mmc1; + }; + + chosen { diff --git a/root/target/linux/mediatek/patches-5.14/172-dt-bindings-usb-mtk-musb-add-MT7623-compatible.patch b/root/target/linux/mediatek/patches-5.14/172-dt-bindings-usb-mtk-musb-add-MT7623-compatible.patch new file mode 100755 index 00000000..44415db5 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/172-dt-bindings-usb-mtk-musb-add-MT7623-compatible.patch @@ -0,0 +1,23 @@ +From b7e4218ece0b7a1b9142491056ae0c4f1af80041 Mon Sep 17 00:00:00 2001 +From: Sungbo Eo +Date: Sun, 8 Aug 2021 21:38:39 +0900 +Subject: [PATCH 1/2] dt-bindings: usb: mtk-musb: add MT7623 compatible + +Document MT7623 compatible for mtk-musb. + +Signed-off-by: Sungbo Eo +Reviewed-by: Matthias Brugger +--- + Documentation/devicetree/bindings/usb/mediatek,musb.yaml | 1 + + 1 file changed, 1 insertion(+) + +--- a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml ++++ b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml +@@ -19,6 +19,7 @@ properties: + - enum: + - mediatek,mt8516-musb + - mediatek,mt2701-musb ++ - mediatek,mt7623-musb + - const: mediatek,mtk-musb + + reg: diff --git a/root/target/linux/mediatek/patches-5.14/173-arm-dts-mt7623-add-musb-device-nodes.patch b/root/target/linux/mediatek/patches-5.14/173-arm-dts-mt7623-add-musb-device-nodes.patch new file mode 100755 index 00000000..ba1d1fe2 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/173-arm-dts-mt7623-add-musb-device-nodes.patch @@ -0,0 +1,69 @@ +From 21d106f15262f5a2ef7531636e0703ee61c33c61 Mon Sep 17 00:00:00 2001 +From: Sungbo Eo +Date: Sun, 8 Aug 2021 21:38:40 +0900 +Subject: [PATCH 2/2] arm: dts: mt7623: add musb device nodes + +MT7623 has an musb controller that is compatible with the one from MT2701. + +Signed-off-by: Sungbo Eo +--- + arch/arm/boot/dts/mt7623.dtsi | 34 ++++++++++++++++++++++++++++++++++ + arch/arm/boot/dts/mt7623a.dtsi | 4 ++++ + 2 files changed, 38 insertions(+) + +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -585,6 +585,40 @@ + status = "disabled"; + }; + ++ usb0: usb@11200000 { ++ compatible = "mediatek,mt7623-musb", ++ "mediatek,mtk-musb"; ++ reg = <0 0x11200000 0 0x1000>; ++ interrupts = ; ++ interrupt-names = "mc"; ++ phys = <&u2port2 PHY_TYPE_USB2>; ++ dr_mode = "otg"; ++ clocks = <&pericfg CLK_PERI_USB0>, ++ <&pericfg CLK_PERI_USB0_MCU>, ++ <&pericfg CLK_PERI_USB_SLV>; ++ clock-names = "main","mcu","univpll"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; ++ status = "disabled"; ++ }; ++ ++ u2phy1: t-phy@11210000 { ++ compatible = "mediatek,mt7623-tphy", ++ "mediatek,generic-tphy-v1"; ++ reg = <0 0x11210000 0 0x0800>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ status = "disabled"; ++ ++ u2port2: usb-phy@11210800 { ++ reg = <0 0x11210800 0 0x0100>; ++ clocks = <&topckgen CLK_TOP_USB_PHY48M>; ++ clock-names = "ref"; ++ #phy-cells = <1>; ++ status = "okay"; ++ }; ++ }; ++ + audsys: clock-controller@11220000 { + compatible = "mediatek,mt7623-audsys", + "mediatek,mt2701-audsys", +--- a/arch/arm/boot/dts/mt7623a.dtsi ++++ b/arch/arm/boot/dts/mt7623a.dtsi +@@ -35,6 +35,10 @@ + clock-names = "ethif"; + }; + ++&usb0 { ++ power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>; ++}; ++ + &usb1 { + power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>; + }; diff --git a/root/target/linux/mediatek/patches-5.14/200-phy-phy-mtk-tphy-Add-hifsys-support.patch b/root/target/linux/mediatek/patches-5.14/200-phy-phy-mtk-tphy-Add-hifsys-support.patch new file mode 100755 index 00000000..95f4be17 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/200-phy-phy-mtk-tphy-Add-hifsys-support.patch @@ -0,0 +1,66 @@ +From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001 +From: Kristian Evensen +Date: Mon, 30 Apr 2018 14:38:01 +0200 +Subject: [PATCH] phy: phy-mtk-tphy: Add hifsys-support + +--- + drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/phy/mediatek/phy-mtk-tphy.c ++++ b/drivers/phy/mediatek/phy-mtk-tphy.c +@@ -15,6 +15,8 @@ + #include + #include + #include ++#include ++#include + + /* version V1 sub-banks offset base address */ + /* banks shared by multiple phys */ +@@ -267,6 +269,9 @@ + #define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0) + #define RG_CDR_BIRLTD0_GEN3_VAL(x) (0x1f & (x)) + ++#define HIF_SYSCFG1 0x14 ++#define HIF_SYSCFG1_PHY2_MASK (0x3 << 20) ++ + enum mtk_phy_version { + MTK_PHY_V1 = 1, + MTK_PHY_V2, +@@ -315,6 +320,7 @@ struct mtk_tphy { + void __iomem *sif_base; /* only shared sif */ + const struct mtk_phy_pdata *pdata; + struct mtk_phy_instance **phys; ++ struct regmap *hif; + int nphys; + int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */ + int src_coef; /* coefficient for slew rate calibrate */ +@@ -634,6 +640,10 @@ static void pcie_phy_instance_init(struc + if (tphy->pdata->version != MTK_PHY_V1) + return; + ++ if (tphy->hif) ++ regmap_update_bits(tphy->hif, HIF_SYSCFG1, ++ HIF_SYSCFG1_PHY2_MASK, 0); ++ + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0); + tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H); + tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2); +@@ -1136,6 +1146,16 @@ static int mtk_tphy_probe(struct platfor + &tphy->src_ref_clk); + device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef); + ++ if (of_find_property(np, "mediatek,phy-switch", NULL)) { ++ tphy->hif = syscon_regmap_lookup_by_phandle(np, ++ "mediatek,phy-switch"); ++ if (IS_ERR(tphy->hif)) { ++ dev_err(&pdev->dev, ++ "missing \"mediatek,phy-switch\" phandle\n"); ++ return PTR_ERR(tphy->hif); ++ } ++ } ++ + port = 0; + for_each_child_of_node(np, child_np) { + struct mtk_phy_instance *instance; diff --git a/root/target/linux/mediatek/patches-5.14/330-mtk-bmt-support.patch b/root/target/linux/mediatek/patches-5.14/330-mtk-bmt-support.patch new file mode 100755 index 00000000..72a729c7 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/330-mtk-bmt-support.patch @@ -0,0 +1,864 @@ +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -15,6 +15,10 @@ config MTD_NAND_ECC + bool + depends on MTD_NAND_CORE + ++config MTD_NAND_MTK_BMT ++ bool "Support MediaTek NAND Bad-block Management Table" ++ default n ++ + endmenu + + endmenu +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -2,6 +2,7 @@ + + nandcore-objs := core.o bbt.o + obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o ++obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o + + obj-y += onenand/ + obj-y += raw/ +--- /dev/null ++++ b/drivers/mtd/nand/mtk_bmt.c +@@ -0,0 +1,781 @@ ++/* ++ * Copyright (c) 2017 MediaTek Inc. ++ * Author: Xiangsheng Hou ++ * Copyright (c) 2020 Felix Fietkau ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MAIN_SIGNATURE_OFFSET 0 ++#define OOB_SIGNATURE_OFFSET 1 ++#define BBPOOL_RATIO 2 ++ ++#define BBT_LOG(fmt, ...) pr_debug("[BBT][%s|%d] "fmt"\n", __func__, __LINE__, ##__VA_ARGS__) ++ ++/* Maximum 8k blocks */ ++#define BB_TABLE_MAX bmtd.table_size ++#define BMT_TABLE_MAX (BB_TABLE_MAX * BBPOOL_RATIO / 100) ++#define BMT_TBL_DEF_VAL 0x0 ++ ++/* ++ * Burner Bad Block Table ++ * --------- Only support SLC Nand Chips!!!!!!!!!!! ---------- ++ */ ++ ++struct bbbt { ++ char signature[3]; ++ /* This version is used to distinguish the legacy and new algorithm */ ++#define BBMT_VERSION 2 ++ unsigned char version; ++ /* Below 2 tables will be written in SLC */ ++ u16 bb_tbl[]; ++}; ++ ++struct bbmt { ++ u16 block; ++#define NO_MAPPED 0 ++#define NORMAL_MAPPED 1 ++#define BMT_MAPPED 2 ++ u16 mapped; ++}; ++ ++static struct bmt_desc { ++ struct mtd_info *mtd; ++ ++ int (*_read_oob) (struct mtd_info *mtd, loff_t from, ++ struct mtd_oob_ops *ops); ++ int (*_write_oob) (struct mtd_info *mtd, loff_t to, ++ struct mtd_oob_ops *ops); ++ const struct nand_ops *nand_ops; ++ ++ struct bbbt *bbt; ++ ++ struct dentry *debugfs_dir; ++ ++ u32 table_size; ++ u32 pg_size; ++ u32 blk_size; ++ u16 pg_shift; ++ u16 blk_shift; ++ /* bbt logical address */ ++ u16 pool_lba; ++ /* bbt physical address */ ++ u16 pool_pba; ++ /* Maximum count of bad blocks that the vendor guaranteed */ ++ u16 bb_max; ++ /* Total blocks of the Nand Chip */ ++ u16 total_blks; ++ /* The block(n) BMT is located at (bmt_tbl[n]) */ ++ u16 bmt_blk_idx; ++ /* How many pages needs to store 'struct bbbt' */ ++ u32 bmt_pgs; ++ ++ /* to compensate for driver level remapping */ ++ u8 oob_offset; ++} bmtd = {0}; ++ ++static unsigned char *nand_bbt_buf; ++static unsigned char *nand_data_buf; ++ ++/* -------- Unit conversions -------- */ ++static inline u32 blk_pg(u16 block) ++{ ++ return (u32)(block << (bmtd.blk_shift - bmtd.pg_shift)); ++} ++ ++/* -------- Nand operations wrapper -------- */ ++static inline int ++bbt_nand_read(u32 page, unsigned char *dat, int dat_len, ++ unsigned char *fdm, int fdm_len) ++{ ++ struct mtd_oob_ops ops = { ++ .mode = MTD_OPS_PLACE_OOB, ++ .ooboffs = bmtd.oob_offset, ++ .oobbuf = fdm, ++ .ooblen = fdm_len, ++ .datbuf = dat, ++ .len = dat_len, ++ }; ++ ++ return bmtd._read_oob(bmtd.mtd, page << bmtd.pg_shift, &ops); ++} ++ ++static inline int bbt_nand_erase(u16 block) ++{ ++ struct nand_device *nand = mtd_to_nanddev(bmtd.mtd); ++ loff_t addr = (loff_t)block << bmtd.blk_shift; ++ struct nand_pos pos; ++ ++ nanddev_offs_to_pos(nand, addr, &pos); ++ return bmtd.nand_ops->erase(nand, &pos); ++} ++ ++/* -------- Bad Blocks Management -------- */ ++static inline struct bbmt *bmt_tbl(struct bbbt *bbbt) ++{ ++ return (struct bbmt *)&bbbt->bb_tbl[bmtd.table_size]; ++} ++ ++static int ++read_bmt(u16 block, unsigned char *dat, unsigned char *fdm, int fdm_len) ++{ ++ u32 len = bmtd.bmt_pgs << bmtd.pg_shift; ++ ++ return bbt_nand_read(blk_pg(block), dat, len, fdm, fdm_len); ++} ++ ++static int write_bmt(u16 block, unsigned char *dat) ++{ ++ struct mtd_oob_ops ops = { ++ .mode = MTD_OPS_PLACE_OOB, ++ .ooboffs = OOB_SIGNATURE_OFFSET + bmtd.oob_offset, ++ .oobbuf = "bmt", ++ .ooblen = 3, ++ .datbuf = dat, ++ .len = bmtd.bmt_pgs << bmtd.pg_shift, ++ }; ++ loff_t addr = (loff_t)block << bmtd.blk_shift; ++ ++ return bmtd._write_oob(bmtd.mtd, addr, &ops); ++} ++ ++static u16 find_valid_block(u16 block) ++{ ++ u8 fdm[4]; ++ int ret; ++ int loop = 0; ++ ++retry: ++ if (block >= bmtd.total_blks) ++ return 0; ++ ++ ret = bbt_nand_read(blk_pg(block), nand_data_buf, bmtd.pg_size, ++ fdm, sizeof(fdm)); ++ /* Read the 1st byte of FDM to judge whether it's a bad ++ * or not ++ */ ++ if (ret || fdm[0] != 0xff) { ++ pr_info("nand: found bad block 0x%x\n", block); ++ if (loop >= bmtd.bb_max) { ++ pr_info("nand: FATAL ERR: too many bad blocks!!\n"); ++ return 0; ++ } ++ ++ loop++; ++ block++; ++ goto retry; ++ } ++ ++ return block; ++} ++ ++/* Find out all bad blocks, and fill in the mapping table */ ++static int scan_bad_blocks(struct bbbt *bbt) ++{ ++ int i; ++ u16 block = 0; ++ ++ /* First time download, the block0 MUST NOT be a bad block, ++ * this is guaranteed by vendor ++ */ ++ bbt->bb_tbl[0] = 0; ++ ++ /* ++ * Construct the mapping table of Normal data area(non-PMT/BMTPOOL) ++ * G - Good block; B - Bad block ++ * --------------------------- ++ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| ++ * --------------------------- ++ * What bb_tbl[i] looks like: ++ * physical block(i): ++ * 0 1 2 3 4 5 6 7 8 9 a b c ++ * mapped block(bb_tbl[i]): ++ * 0 1 3 6 7 8 9 b ...... ++ * ATTENTION: ++ * If new bad block ocurred(n), search bmt_tbl to find ++ * a available block(x), and fill in the bb_tbl[n] = x; ++ */ ++ for (i = 1; i < bmtd.pool_lba; i++) { ++ bbt->bb_tbl[i] = find_valid_block(bbt->bb_tbl[i - 1] + 1); ++ BBT_LOG("bb_tbl[0x%x] = 0x%x", i, bbt->bb_tbl[i]); ++ if (bbt->bb_tbl[i] == 0) ++ return -1; ++ } ++ ++ /* Physical Block start Address of BMT pool */ ++ bmtd.pool_pba = bbt->bb_tbl[i - 1] + 1; ++ if (bmtd.pool_pba >= bmtd.total_blks - 2) { ++ pr_info("nand: FATAL ERR: Too many bad blocks!!\n"); ++ return -1; ++ } ++ ++ BBT_LOG("pool_pba=0x%x", bmtd.pool_pba); ++ i = 0; ++ block = bmtd.pool_pba; ++ /* ++ * The bmt table is used for runtime bad block mapping ++ * G - Good block; B - Bad block ++ * --------------------------- ++ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| ++ * --------------------------- ++ * block: 0 1 2 3 4 5 6 7 8 9 a b c ++ * What bmt_tbl[i] looks like in initial state: ++ * i: ++ * 0 1 2 3 4 5 6 7 ++ * bmt_tbl[i].block: ++ * 0 1 3 6 7 8 9 b ++ * bmt_tbl[i].mapped: ++ * N N N N N N N B ++ * N - Not mapped(Available) ++ * M - Mapped ++ * B - BMT ++ * ATTENTION: ++ * BMT always in the last valid block in pool ++ */ ++ while ((block = find_valid_block(block)) != 0) { ++ bmt_tbl(bbt)[i].block = block; ++ bmt_tbl(bbt)[i].mapped = NO_MAPPED; ++ BBT_LOG("bmt_tbl[%d].block = 0x%x", i, block); ++ block++; ++ i++; ++ } ++ ++ /* i - How many available blocks in pool, which is the length of bmt_tbl[] ++ * bmtd.bmt_blk_idx - bmt_tbl[bmtd.bmt_blk_idx].block => the BMT block ++ */ ++ bmtd.bmt_blk_idx = i - 1; ++ bmt_tbl(bbt)[bmtd.bmt_blk_idx].mapped = BMT_MAPPED; ++ ++ if (i < 1) { ++ pr_info("nand: FATAL ERR: no space to store BMT!!\n"); ++ return -1; ++ } ++ ++ pr_info("[BBT] %d available blocks in BMT pool\n", i); ++ ++ return 0; ++} ++ ++static bool is_valid_bmt(unsigned char *buf, unsigned char *fdm) ++{ ++ struct bbbt *bbt = (struct bbbt *)buf; ++ u8 *sig = (u8*)bbt->signature + MAIN_SIGNATURE_OFFSET; ++ ++ ++ if (memcmp(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3) == 0 && ++ memcmp(fdm + OOB_SIGNATURE_OFFSET, "bmt", 3) == 0) { ++ if (bbt->version == BBMT_VERSION) ++ return true; ++ } ++ BBT_LOG("[BBT] BMT Version not match,upgrage preloader and uboot please! sig=%02x%02x%02x, fdm=%02x%02x%02x", ++ sig[0], sig[1], sig[2], ++ fdm[1], fdm[2], fdm[3]); ++ return false; ++} ++ ++static u16 get_bmt_index(struct bbmt *bmt) ++{ ++ int i = 0; ++ ++ while (bmt[i].block != BMT_TBL_DEF_VAL) { ++ if (bmt[i].mapped == BMT_MAPPED) ++ return i; ++ i++; ++ } ++ return 0; ++} ++ ++static struct bbbt *scan_bmt(u16 block) ++{ ++ u8 fdm[4]; ++ ++ if (block < bmtd.pool_lba) ++ return NULL; ++ ++ if (read_bmt(block, nand_bbt_buf, fdm, sizeof(fdm))) ++ return scan_bmt(block - 1); ++ ++ if (is_valid_bmt(nand_bbt_buf, fdm)) { ++ bmtd.bmt_blk_idx = get_bmt_index(bmt_tbl((struct bbbt *)nand_bbt_buf)); ++ if (bmtd.bmt_blk_idx == 0) { ++ pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n"); ++ return NULL; ++ } ++ pr_info("[BBT] BMT.v2 is found at 0x%x\n", block); ++ return (struct bbbt *)nand_bbt_buf; ++ } else ++ return scan_bmt(block - 1); ++} ++ ++/* Write the Burner Bad Block Table to Nand Flash ++ * n - write BMT to bmt_tbl[n] ++ */ ++static u16 upload_bmt(struct bbbt *bbt, int n) ++{ ++ u16 block; ++ ++retry: ++ if (n < 0 || bmt_tbl(bbt)[n].mapped == NORMAL_MAPPED) { ++ pr_info("nand: FATAL ERR: no space to store BMT!\n"); ++ return (u16)-1; ++ } ++ ++ block = bmt_tbl(bbt)[n].block; ++ BBT_LOG("n = 0x%x, block = 0x%x", n, block); ++ if (bbt_nand_erase(block)) { ++ bmt_tbl(bbt)[n].block = 0; ++ /* erase failed, try the previous block: bmt_tbl[n - 1].block */ ++ n--; ++ goto retry; ++ } ++ ++ /* The signature offset is fixed set to 0, ++ * oob signature offset is fixed set to 1 ++ */ ++ memcpy(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3); ++ bbt->version = BBMT_VERSION; ++ ++ if (write_bmt(block, (unsigned char *)bbt)) { ++ bmt_tbl(bbt)[n].block = 0; ++ ++ /* write failed, try the previous block in bmt_tbl[n - 1] */ ++ n--; ++ goto retry; ++ } ++ ++ /* Return the current index(n) of BMT pool (bmt_tbl[n]) */ ++ return n; ++} ++ ++static u16 find_valid_block_in_pool(struct bbbt *bbt) ++{ ++ int i; ++ ++ if (bmtd.bmt_blk_idx == 0) ++ goto error; ++ ++ for (i = 0; i < bmtd.bmt_blk_idx; i++) { ++ if (bmt_tbl(bbt)[i].block != 0 && bmt_tbl(bbt)[i].mapped == NO_MAPPED) { ++ bmt_tbl(bbt)[i].mapped = NORMAL_MAPPED; ++ return bmt_tbl(bbt)[i].block; ++ } ++ } ++ ++error: ++ pr_info("nand: FATAL ERR: BMT pool is run out!\n"); ++ return 0; ++} ++ ++/* We met a bad block, mark it as bad and map it to a valid block in pool, ++ * if it's a write failure, we need to write the data to mapped block ++ */ ++static bool update_bmt(u16 block) ++{ ++ u16 mapped_blk; ++ struct bbbt *bbt; ++ ++ bbt = bmtd.bbt; ++ mapped_blk = find_valid_block_in_pool(bbt); ++ if (mapped_blk == 0) ++ return false; ++ ++ /* Map new bad block to available block in pool */ ++ bbt->bb_tbl[block] = mapped_blk; ++ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); ++ ++ return true; ++} ++ ++u16 get_mapping_block_index(int block) ++{ ++ int mapping_block; ++ ++ if (block < bmtd.pool_lba) ++ mapping_block = bmtd.bbt->bb_tbl[block]; ++ else ++ mapping_block = block; ++ BBT_LOG("0x%x mapped to 0x%x", block, mapping_block); ++ ++ return mapping_block; ++} ++ ++static int ++mtk_bmt_read(struct mtd_info *mtd, loff_t from, ++ struct mtd_oob_ops *ops) ++{ ++ struct mtd_oob_ops cur_ops = *ops; ++ int retry_count = 0; ++ loff_t cur_from; ++ int ret; ++ ++ ops->retlen = 0; ++ ops->oobretlen = 0; ++ ++ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { ++ u32 offset = from & (bmtd.blk_size - 1); ++ u32 block = from >> bmtd.blk_shift; ++ u32 cur_block; ++ ++ cur_block = get_mapping_block_index(block); ++ cur_from = ((loff_t)cur_block << bmtd.blk_shift) + offset; ++ ++ cur_ops.oobretlen = 0; ++ cur_ops.retlen = 0; ++ cur_ops.len = min_t(u32, mtd->erasesize - offset, ++ ops->len - ops->retlen); ++ ret = bmtd._read_oob(mtd, cur_from, &cur_ops); ++ if (ret < 0) { ++ update_bmt(block); ++ if (retry_count++ < 10) ++ continue; ++ ++ return ret; ++ } ++ ++ ops->retlen += cur_ops.retlen; ++ ops->oobretlen += cur_ops.oobretlen; ++ ++ cur_ops.ooboffs = 0; ++ cur_ops.datbuf += cur_ops.retlen; ++ cur_ops.oobbuf += cur_ops.oobretlen; ++ cur_ops.ooblen -= cur_ops.oobretlen; ++ ++ if (!cur_ops.len) ++ cur_ops.len = mtd->erasesize - offset; ++ ++ from += cur_ops.len; ++ retry_count = 0; ++ } ++ ++ return 0; ++} ++ ++static int ++mtk_bmt_write(struct mtd_info *mtd, loff_t to, ++ struct mtd_oob_ops *ops) ++{ ++ struct mtd_oob_ops cur_ops = *ops; ++ int retry_count = 0; ++ loff_t cur_to; ++ int ret; ++ ++ ops->retlen = 0; ++ ops->oobretlen = 0; ++ ++ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { ++ u32 offset = to & (bmtd.blk_size - 1); ++ u32 block = to >> bmtd.blk_shift; ++ u32 cur_block; ++ ++ cur_block = get_mapping_block_index(block); ++ cur_to = ((loff_t)cur_block << bmtd.blk_shift) + offset; ++ ++ cur_ops.oobretlen = 0; ++ cur_ops.retlen = 0; ++ cur_ops.len = min_t(u32, bmtd.blk_size - offset, ++ ops->len - ops->retlen); ++ ret = bmtd._write_oob(mtd, cur_to, &cur_ops); ++ if (ret < 0) { ++ update_bmt(block); ++ if (retry_count++ < 10) ++ continue; ++ ++ return ret; ++ } ++ ++ ops->retlen += cur_ops.retlen; ++ ops->oobretlen += cur_ops.oobretlen; ++ ++ cur_ops.ooboffs = 0; ++ cur_ops.datbuf += cur_ops.retlen; ++ cur_ops.oobbuf += cur_ops.oobretlen; ++ cur_ops.ooblen -= cur_ops.oobretlen; ++ ++ if (!cur_ops.len) ++ cur_ops.len = mtd->erasesize - offset; ++ ++ to += cur_ops.len; ++ retry_count = 0; ++ } ++ ++ return 0; ++} ++ ++ ++ ++static int ++mtk_bmt_erase(struct nand_device *nand, const struct nand_pos *pos) ++{ ++ struct nand_pos new_pos = *pos; ++ int retry_count = 0; ++ int ret; ++ ++retry: ++ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock); ++ ++ ret = bmtd.nand_ops->erase(nand, &new_pos); ++ if (ret) { ++ update_bmt(pos->eraseblock); ++ if (retry_count++ < 10) ++ goto retry; ++ } ++ ++ return ret; ++} ++ ++static bool ++mtk_bmt_isbad(struct nand_device *nand, const struct nand_pos *pos) ++{ ++ struct nand_pos new_pos = *pos; ++ int retry_count = 0; ++ bool ret; ++ ++retry: ++ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock); ++ ++ ret = bmtd.nand_ops->isbad(nand, &new_pos); ++ if (ret) { ++ update_bmt(pos->eraseblock); ++ if (retry_count++ < 10) ++ goto retry; ++ } ++ ++ return ret; ++} ++ ++static int ++mtk_bmt_markbad(struct nand_device *nand, const struct nand_pos *pos) ++{ ++ struct nand_pos new_pos = *pos; ++ ++ new_pos.eraseblock = get_mapping_block_index(new_pos.eraseblock); ++ update_bmt(pos->eraseblock); ++ ++ return bmtd.nand_ops->markbad(nand, &new_pos); ++} ++ ++static void ++mtk_bmt_replace_ops(struct mtd_info *mtd) ++{ ++ static const struct nand_ops mtk_bmt_nand_ops = { ++ .erase = mtk_bmt_erase, ++ .isbad = mtk_bmt_isbad, ++ .markbad = mtk_bmt_markbad, ++ }; ++ struct nand_device *nand = mtd_to_nanddev(mtd); ++ ++ bmtd.nand_ops = nand->ops; ++ bmtd._read_oob = mtd->_read_oob; ++ bmtd._write_oob = mtd->_write_oob; ++ ++ mtd->_read_oob = mtk_bmt_read; ++ mtd->_write_oob = mtk_bmt_write; ++ nand->ops = &mtk_bmt_nand_ops; ++} ++ ++static int mtk_bmt_debug_mark_good(void *data, u64 val) ++{ ++ u32 block = val >> bmtd.blk_shift; ++ ++ bmtd.bbt->bb_tbl[block] = block; ++ bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx); ++ ++ return 0; ++} ++ ++static int mtk_bmt_debug_mark_bad(void *data, u64 val) ++{ ++ u32 block = val >> bmtd.blk_shift; ++ ++ update_bmt(block); ++ ++ return 0; ++} ++ ++DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_good, NULL, mtk_bmt_debug_mark_good, "%llu\n"); ++DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_bad, NULL, mtk_bmt_debug_mark_bad, "%llu\n"); ++ ++static void ++mtk_bmt_add_debugfs(void) ++{ ++ struct dentry *dir; ++ ++ dir = bmtd.debugfs_dir = debugfs_create_dir("mtk-bmt", NULL); ++ if (!dir) ++ return; ++ ++ debugfs_create_file_unsafe("mark_good", S_IWUSR, dir, NULL, &fops_mark_good); ++ debugfs_create_file_unsafe("mark_bad", S_IWUSR, dir, NULL, &fops_mark_bad); ++} ++ ++void mtk_bmt_detach(struct mtd_info *mtd) ++{ ++ struct nand_device *nand = mtd_to_nanddev(mtd); ++ ++ if (bmtd.mtd != mtd) ++ return; ++ ++ if (bmtd.debugfs_dir) ++ debugfs_remove_recursive(bmtd.debugfs_dir); ++ bmtd.debugfs_dir = NULL; ++ ++ kfree(nand_bbt_buf); ++ kfree(nand_data_buf); ++ ++ mtd->_read_oob = bmtd._read_oob; ++ mtd->_write_oob = bmtd._write_oob; ++ mtd->size = bmtd.total_blks << bmtd.blk_shift; ++ nand->ops = bmtd.nand_ops; ++ ++ memset(&bmtd, 0, sizeof(bmtd)); ++} ++ ++/* total_blocks - The total count of blocks that the Nand Chip has */ ++int mtk_bmt_attach(struct mtd_info *mtd) ++{ ++ struct device_node *np; ++ struct bbbt *bbt; ++ u32 bufsz; ++ u32 block; ++ u16 total_blocks, pmt_block; ++ int ret = 0; ++ u32 bmt_pool_size, bmt_table_size; ++ ++ if (bmtd.mtd) ++ return -ENOSPC; ++ ++ np = mtd_get_of_node(mtd); ++ if (!np) ++ return 0; ++ ++ if (!of_property_read_bool(np, "mediatek,bmt-v2")) ++ return 0; ++ ++ if (of_property_read_u32(np, "mediatek,bmt-pool-size", ++ &bmt_pool_size) != 0) ++ bmt_pool_size = 80; ++ ++ if (of_property_read_u8(np, "mediatek,bmt-oob-offset", ++ &bmtd.oob_offset) != 0) ++ bmtd.oob_offset = 0; ++ ++ if (of_property_read_u32(np, "mediatek,bmt-table-size", ++ &bmt_table_size) != 0) ++ bmt_table_size = 0x2000U; ++ ++ bmtd.mtd = mtd; ++ mtk_bmt_replace_ops(mtd); ++ ++ bmtd.table_size = bmt_table_size; ++ bmtd.blk_size = mtd->erasesize; ++ bmtd.blk_shift = ffs(bmtd.blk_size) - 1; ++ bmtd.pg_size = mtd->writesize; ++ bmtd.pg_shift = ffs(bmtd.pg_size) - 1; ++ total_blocks = mtd->size >> bmtd.blk_shift; ++ pmt_block = total_blocks - bmt_pool_size - 2; ++ ++ mtd->size = pmt_block << bmtd.blk_shift; ++ ++ /* ++ * --------------------------------------- ++ * | PMT(2blks) | BMT POOL(totalblks * 2%) | ++ * --------------------------------------- ++ * ^ ^ ++ * | | ++ * pmt_block pmt_block + 2blocks(pool_lba) ++ * ++ * ATTETION!!!!!! ++ * The blocks ahead of the boundary block are stored in bb_tbl ++ * and blocks behind are stored in bmt_tbl ++ */ ++ ++ bmtd.pool_lba = (u16)(pmt_block + 2); ++ bmtd.total_blks = total_blocks; ++ bmtd.bb_max = bmtd.total_blks * BBPOOL_RATIO / 100; ++ ++ /* 3 buffers we need */ ++ bufsz = round_up(sizeof(struct bbbt) + ++ bmt_table_size * sizeof(struct bbmt), bmtd.pg_size); ++ bmtd.bmt_pgs = bufsz >> bmtd.pg_shift; ++ ++ nand_bbt_buf = kzalloc(bufsz, GFP_KERNEL); ++ nand_data_buf = kzalloc(bmtd.pg_size, GFP_KERNEL); ++ ++ if (!nand_bbt_buf || !nand_data_buf) { ++ pr_info("nand: FATAL ERR: allocate buffer failed!\n"); ++ ret = -1; ++ goto error; ++ } ++ ++ memset(nand_bbt_buf, 0xff, bufsz); ++ memset(nand_data_buf, 0xff, bmtd.pg_size); ++ ++ BBT_LOG("bbtbuf=0x%p(0x%x) dat=0x%p(0x%x)", ++ nand_bbt_buf, bufsz, nand_data_buf, bmtd.pg_size); ++ BBT_LOG("pool_lba=0x%x total_blks=0x%x bb_max=0x%x", ++ bmtd.pool_lba, bmtd.total_blks, bmtd.bb_max); ++ ++ /* Scanning start from the first page of the last block ++ * of whole flash ++ */ ++ bbt = scan_bmt(bmtd.total_blks - 1); ++ if (!bbt) { ++ /* BMT not found */ ++ if (bmtd.total_blks > BB_TABLE_MAX + BMT_TABLE_MAX) { ++ pr_info("nand: FATAL: Too many blocks, can not support!\n"); ++ ret = -1; ++ goto error; ++ } ++ ++ bbt = (struct bbbt *)nand_bbt_buf; ++ memset(bmt_tbl(bbt), BMT_TBL_DEF_VAL, bmtd.table_size * sizeof(struct bbmt)); ++ ++ if (scan_bad_blocks(bbt)) { ++ ret = -1; ++ goto error; ++ } ++ ++ /* BMT always in the last valid block in pool */ ++ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); ++ block = bmt_tbl(bbt)[bmtd.bmt_blk_idx].block; ++ pr_notice("[BBT] BMT.v2 is written into PBA:0x%x\n", block); ++ ++ if (bmtd.bmt_blk_idx == 0) ++ pr_info("nand: Warning: no available block in BMT pool!\n"); ++ else if (bmtd.bmt_blk_idx == (u16)-1) { ++ ret = -1; ++ goto error; ++ } ++ } ++ mtk_bmt_add_debugfs(); ++ ++ bmtd.bbt = bbt; ++ return 0; ++ ++error: ++ mtk_bmt_detach(mtd); ++ return ret; ++} ++ ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Xiangsheng Hou , Felix Fietkau "); ++MODULE_DESCRIPTION("Bad Block mapping management v2 for MediaTek NAND Flash Driver"); ++ +--- /dev/null ++++ b/include/linux/mtd/mtk_bmt.h +@@ -0,0 +1,18 @@ ++#ifndef __MTK_BMT_H ++#define __MTK_BMT_H ++ ++#ifdef CONFIG_MTD_NAND_MTK_BMT ++int mtk_bmt_attach(struct mtd_info *mtd); ++void mtk_bmt_detach(struct mtd_info *mtd); ++#else ++static inline int mtk_bmt_attach(struct mtd_info *mtd) ++{ ++ return 0; ++} ++ ++static inline void mtk_bmt_detach(struct mtd_info *mtd) ++{ ++} ++#endif ++ ++#endif +--- a/drivers/mtd/mtk-snand/mtk-snand-mtd.c ++++ b/drivers/mtd/mtk-snand/mtk-snand-mtd.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -612,6 +613,8 @@ static int mtk_snand_probe(struct platfo + mtd->_block_isbad = mtk_snand_mtd_block_isbad; + mtd->_block_markbad = mtk_snand_mtd_block_markbad; + ++ mtk_bmt_attach(mtd); ++ + ret = mtd_device_register(mtd, NULL, 0); + if (ret) { + dev_err(msm->pdev.dev, "failed to register mtd partition\n"); +@@ -623,6 +626,7 @@ static int mtk_snand_probe(struct platfo + return 0; + + errout4: ++ mtk_bmt_detach(mtd); + devm_kfree(msm->pdev.dev, msm->page_cache); + + errout3: +@@ -650,6 +654,8 @@ static int mtk_snand_remove(struct platf + if (ret) + return ret; + ++ mtk_bmt_detach(mtd); ++ + mtk_snand_cleanup(msm->snf); + + if (msm->irq >= 0) diff --git a/root/target/linux/mediatek/patches-5.14/350-dt-bindings-mtd-brcm-trx-Add-brcm-trx-magic.patch b/root/target/linux/mediatek/patches-5.14/350-dt-bindings-mtd-brcm-trx-Add-brcm-trx-magic.patch new file mode 100755 index 00000000..1f346521 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/350-dt-bindings-mtd-brcm-trx-Add-brcm-trx-magic.patch @@ -0,0 +1,32 @@ +From a4d82940ff85a7e307953dfa715f65d5ab487e10 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 18 Apr 2021 23:46:14 +0200 +Subject: dt-bindings: mtd: brcm,trx: Add brcm,trx-magic + +This adds the description of an additional property which allows to +specify a custom partition parser magic to detect a trx partition. +Buffalo has multiple device which are using the trx format, but with +different magic values. + +Signed-off-by: Hauke Mehrtens +Acked-by: Rob Herring +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20210418214616.239574-2-hauke@hauke-m.de +--- + .../devicetree/bindings/mtd/partitions/brcm,trx.txt | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/Documentation/devicetree/bindings/mtd/partitions/brcm,trx.txt ++++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,trx.txt +@@ -28,6 +28,11 @@ detected by a software parsing TRX heade + Required properties: + - compatible : (required) must be "brcm,trx" + ++Optional properties: ++ ++- brcm,trx-magic: TRX magic, if it is different from the default magic ++ 0x30524448 as a u32. ++ + Example: + + flash@0 { diff --git a/root/target/linux/mediatek/patches-5.14/400-crypto-add-eip97-inside-secure-support.patch b/root/target/linux/mediatek/patches-5.14/400-crypto-add-eip97-inside-secure-support.patch new file mode 100755 index 00000000..e0941a95 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/400-crypto-add-eip97-inside-secure-support.patch @@ -0,0 +1,27 @@ +--- a/drivers/crypto/inside-secure/safexcel.c ++++ b/drivers/crypto/inside-secure/safexcel.c +@@ -600,6 +600,14 @@ static int safexcel_hw_init(struct safex + val |= EIP197_MST_CTRL_TX_MAX_CMD(5); + writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); + } ++ /* ++ * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3 ++ */ ++ else { ++ val = 0; ++ val |= EIP97_MST_CTRL_TX_MAX_CMD(4); ++ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); ++ } + + /* Configure wr/rd cache values */ + writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) | +--- a/drivers/crypto/inside-secure/safexcel.h ++++ b/drivers/crypto/inside-secure/safexcel.h +@@ -314,6 +314,7 @@ + #define EIP197_MST_CTRL_RD_CACHE(n) (((n) & 0xf) << 0) + #define EIP197_MST_CTRL_WD_CACHE(n) (((n) & 0xf) << 4) + #define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20) ++#define EIP97_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 4) + #define EIP197_MST_CTRL_BYTE_SWAP BIT(24) + #define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25) + #define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24) diff --git a/root/target/linux/mediatek/patches-5.14/401-crypto-fix-eip97-cache-incoherent.patch b/root/target/linux/mediatek/patches-5.14/401-crypto-fix-eip97-cache-incoherent.patch new file mode 100755 index 00000000..be2bffb7 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/401-crypto-fix-eip97-cache-incoherent.patch @@ -0,0 +1,26 @@ +--- a/drivers/crypto/inside-secure/safexcel.h ++++ b/drivers/crypto/inside-secure/safexcel.h +@@ -736,6 +736,9 @@ enum safexcel_eip_version { + /* Priority we use for advertising our algorithms */ + #define SAFEXCEL_CRA_PRIORITY 300 + ++/* System cache line size */ ++#define SYSTEM_CACHELINE_SIZE 64 ++ + /* SM3 digest result for zero length message */ + #define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \ + "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \ +--- a/drivers/crypto/inside-secure/safexcel_hash.c ++++ b/drivers/crypto/inside-secure/safexcel_hash.c +@@ -53,9 +53,9 @@ struct safexcel_ahash_req { + u8 block_sz; /* block size, only set once */ + u8 digest_sz; /* output digest size, only set once */ + __le32 state[SHA3_512_BLOCK_SIZE / +- sizeof(__le32)] __aligned(sizeof(__le32)); ++ sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE); + +- u64 len; ++ u64 len __aligned(SYSTEM_CACHELINE_SIZE); + u64 processed; + + u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32)); diff --git a/root/target/linux/mediatek/patches-5.14/410-bt-mtk-serial-fix.patch b/root/target/linux/mediatek/patches-5.14/410-bt-mtk-serial-fix.patch new file mode 100755 index 00000000..b82e174d --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/410-bt-mtk-serial-fix.patch @@ -0,0 +1,33 @@ +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -82,6 +82,7 @@ struct serial8250_config { + #define UART_CAP_MINI (1 << 17) /* Mini UART on BCM283X family lacks: + * STOP PARITY EPAR SPAR WLEN5 WLEN6 + */ ++#define UART_CAP_NMOD (1 << 18) /* UART doesn't do termios */ + + #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ + #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -287,7 +287,7 @@ static const struct serial8250_config ua + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, +- .flags = UART_CAP_FIFO, ++ .flags = UART_CAP_FIFO | UART_CAP_NMOD, + }, + [PORT_NPCM] = { + .name = "Nuvoton 16550", +@@ -2718,6 +2718,11 @@ serial8250_do_set_termios(struct uart_po + unsigned long flags; + unsigned int baud, quot, frac = 0; + ++ if (up->capabilities & UART_CAP_NMOD) { ++ termios->c_cflag = 0; ++ return; ++ } ++ + if (up->capabilities & UART_CAP_MINI) { + termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR); + if ((termios->c_cflag & CSIZE) == CS5 || diff --git a/root/target/linux/mediatek/patches-5.14/420-mtd-spi-nor-add-support-for-Winbond-W25Q512JV.patch b/root/target/linux/mediatek/patches-5.14/420-mtd-spi-nor-add-support-for-Winbond-W25Q512JV.patch new file mode 100755 index 00000000..f8527ba4 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/420-mtd-spi-nor-add-support-for-Winbond-W25Q512JV.patch @@ -0,0 +1,28 @@ +From: David Bauer +To: linux-mtd@lists.infradead.org +Subject: [PATCH] mtd: spi-nor: add support for Winbond W25Q512JV +Date: Sat, 13 Feb 2021 16:10:47 +0100 + +The Winbond W25Q512JV is a 512mb SPI-NOR chip. It supports 4K +sectors as well as block protection and Dual-/Quad-read. + +Tested on: Ubiquiti UniFi 6 LR + +Signed-off-by: David Bauer +--- + drivers/mtd/spi-nor/winbond.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/mtd/spi-nor/winbond.c ++++ b/drivers/mtd/spi-nor/winbond.c +@@ -95,6 +95,10 @@ static const struct flash_info winbond_p + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "w25q256jw", INFO(0xef6019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024, ++ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ | ++ SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | ++ SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) }, + { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024, + SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, + }; diff --git a/root/target/linux/mediatek/patches-5.14/500-gsw-rtl8367s-mt7622-support.patch b/root/target/linux/mediatek/patches-5.14/500-gsw-rtl8367s-mt7622-support.patch new file mode 100755 index 00000000..bdd482de --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/500-gsw-rtl8367s-mt7622-support.patch @@ -0,0 +1,25 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -334,6 +334,12 @@ config ROCKCHIP_PHY + help + Currently supports the integrated Ethernet PHY. + ++config RTL8367S_GSW ++ tristate "rtl8367 Gigabit Switch support for mt7622" ++ depends on NET_VENDOR_MEDIATEK ++ help ++ This driver supports rtl8367s in mt7622 ++ + config SMSC_PHY + tristate "SMSC PHYs" + help +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -88,6 +88,7 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o + obj-$(CONFIG_REALTEK_PHY) += realtek.o + obj-$(CONFIG_RENESAS_PHY) += uPD60620.o + obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o ++obj-$(CONFIG_RTL8367S_GSW) += rtk/ + obj-$(CONFIG_SMSC_PHY) += smsc.o + obj-$(CONFIG_STE10XP) += ste10Xp.o + obj-$(CONFIG_TERANETICS_PHY) += teranetics.o diff --git a/root/target/linux/mediatek/patches-5.14/510-net-mediatek-add-flow-offload-for-mt7623.patch b/root/target/linux/mediatek/patches-5.14/510-net-mediatek-add-flow-offload-for-mt7623.patch new file mode 100755 index 00000000..36f88a51 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/510-net-mediatek-add-flow-offload-for-mt7623.patch @@ -0,0 +1,24 @@ +From 4823778b116c08e9c55dbc5b5042223289ea6a0c Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Wed, 31 Mar 2021 15:34:37 +0200 +Subject: [PATCH] net: mediatek: add flow offload for mt7623 + +mt7623 uses offload version 2 too + +tested on Bananapi-R2 + +Signed-off-by: Frank Wunderlich +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3269,6 +3269,7 @@ static const struct mtk_soc_data mt7623_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, ++ .offload_version = 2, + }; + + static const struct mtk_soc_data mt7629_data = { diff --git a/root/target/linux/mediatek/patches-5.14/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch b/root/target/linux/mediatek/patches-5.14/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch new file mode 100755 index 00000000..02e4c130 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch @@ -0,0 +1,415 @@ +From patchwork Thu May 28 06:16:45 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Chuanjia Liu +X-Patchwork-Id: 11574793 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 391201392 + for ; + Thu, 28 May 2020 06:20:27 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id 104F620657 + for ; + Thu, 28 May 2020 06:20:27 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="raZHaWxs"; + dkim=fail reason="signature verification failed" (1024-bit key) + header.d=mediatek.com header.i=@mediatek.com header.b="YztrByG/" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 104F620657 +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=mediatek.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=aVtKU+Ey8KEM97+S66fz9ZMo+H8BP570jhAAvaRsNWc=; b=raZHaWxsfCxsrd + Byn/w1oLN/J82ApnNdBBXixq9Qj0uXIU2tBVqkiQ9lG6QDk7uguxQSJLeTqrsI/uxQmCI/PGQtZdP + sH0oboi2sbQSqJ/1ud4uL2pPaiLRJCxINF5oWjoZMsjn/b2fWvn52P6vTr/dxDTaabiVhY0HL0J+X + 7YGc1aYtO76HZHE2ke3puR42QkI8hE9E2cEhiLWeuUiLdUBegNM5MdYftu4nJTcCXnAeJjp/wIpYG + 7X737N9cmanDf6Bxr2bNPgaYzH+m7JK6eGxuAvWo0+PE9OX7MLrXY3KjixcjD/b0he0mfEM++gBAq + KBYKl5wh1mnlR2WIWXew==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBtx-0005JC-DJ; Thu, 28 May 2020 06:20:25 +0000 +Received: from mailgw01.mediatek.com ([216.200.240.184]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBtW-0002f2-75; Thu, 28 May 2020 06:20:01 +0000 +X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; + s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=EqjC+5cHgv6eykN7FPf2mtwK9UivJ3XSCE0jEvb8h+8=; + b=YztrByG/Ia304l9KDPBwoHFYkFCN6qBXPqwZgg56CA9VitadAg2+K1VgfEU+oHqsqcsGAMdZTRMQh17tpm4bJParw6MMzAQ28te2TcxvQMV8PZMkerJdZyyYblI7ybauPWuofAQgQMtuwSKVii8eTRJbf99OZ9vDGJP3zo2j1wU=; +X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527 +Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by + mailgw01.mediatek.com + (envelope-from ) + (musrelay.mediatek.com ESMTP with TLS) + with ESMTP id 681958707; Wed, 27 May 2020 22:20:16 -0800 +Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by + MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Wed, 27 May 2020 23:18:52 -0700 +Received: from mtkcas07.mediatek.inc (172.21.101.84) by + mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Thu, 28 May 2020 14:18:49 +0800 +Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend + Transport; Thu, 28 May 2020 14:18:47 +0800 +From: +To: , , +Subject: [PATCH v2 1/4] dt-bindings: PCI: Mediatek: Update PCIe binding +Date: Thu, 28 May 2020 14:16:45 +0800 +Message-ID: <20200528061648.32078-2-chuanjia.liu@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200527_231958_261064_608CC03E +X-CRM114-Status: GOOD ( 13.95 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 + encoding + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay + lines +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, + srv_heupstream@mediatek.com, "chuanjia.liu" , + linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, + jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, + yong.wu@mediatek.com, bhelgaas@google.com, + linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org + +From: "chuanjia.liu" + +There are two independent PCIe controllers in MT2712/MT7622 platform, +and each of them should contain an independent MSI domain. + +In current architecture, MSI domain will be inherited from the root +bridge, and all of the devices will share the same MSI domain. +Hence that, the PCIe devices will not work properly if the irq number +which required is more than 32. + +Split the PCIe node for MT2712/MT7622 platform to fix MSI issue and +comply with the hardware design. + +Signed-off-by: chuanjia.liu +--- + .../bindings/pci/mediatek-pcie-cfg.yaml | 38 +++++ + .../devicetree/bindings/pci/mediatek-pcie.txt | 144 +++++++++++------- + 2 files changed, 129 insertions(+), 53 deletions(-) + create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml +@@ -0,0 +1,38 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/pci/mediatek-pcie-cfg.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Mediatek PCIECFG controller ++ ++maintainers: ++ - Chuanjia Liu ++ - Jianjun Wang ++ ++description: | ++ The MediaTek PCIECFG controller controls some feature about ++ LTSSM, ASPM and so on. ++ ++properties: ++ compatible: ++ items: ++ - enum: ++ - mediatek,mt7622-pciecfg ++ - mediatek,mt7629-pciecfg ++ - const: syscon ++ ++ reg: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ ++examples: ++ - | ++ pciecfg: pciecfg@1a140000 { ++ compatible = "mediatek,mt7622-pciecfg", "syscon"; ++ reg = <0 0x1a140000 0 0x1000>; ++ }; ++... +--- a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt ++++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt +@@ -8,7 +8,7 @@ Required properties: + "mediatek,mt7623-pcie" + "mediatek,mt7629-pcie" + - device_type: Must be "pci" +-- reg: Base addresses and lengths of the PCIe subsys and root ports. ++- reg: Base addresses and lengths of the root ports. + - reg-names: Names of the above areas to use during resource lookup. + - #address-cells: Address representation for root ports (must be 3) + - #size-cells: Size representation for root ports (must be 2) +@@ -19,10 +19,10 @@ Required properties: + - sys_ckN :transaction layer and data link layer clock + Required entries for MT2701/MT7623: + - free_ck :for reference clock of PCIe subsys +- Required entries for MT2712/MT7622: ++ Required entries for MT2712/MT7622/MT7629: + - ahb_ckN :AHB slave interface operating clock for CSR access and RC + initiated MMIO access +- Required entries for MT7622: ++ Required entries for MT7622/MT7629: + - axi_ckN :application layer MMIO channel operating clock + - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when + pcie_mac_ck/pcie_pipe_ck is turned off +@@ -47,10 +47,13 @@ Required properties for MT7623/MT2701: + - reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the + number of root ports. + +-Required properties for MT2712/MT7622: ++Required properties for MT2712/MT7622/MT7629: + -interrupts: A list of interrupt outputs of the controller, must have one + entry for each PCIe port + ++Required properties for MT7622/MT7629: ++- mediatek,pcie-subsys: Should be a phandle of the pciecfg node. ++ + In addition, the device tree node must have sub-nodes describing each + PCIe port interface, having the following mandatory properties: + +@@ -143,56 +146,73 @@ Examples for MT7623: + + Examples for MT2712: + +- pcie: pcie@11700000 { ++ pcie1: pcie@112ff000 { + compatible = "mediatek,mt2712-pcie"; + device_type = "pci"; +- reg = <0 0x11700000 0 0x1000>, +- <0 0x112ff000 0 0x1000>; +- reg-names = "port0", "port1"; ++ reg = <0 0x112ff000 0 0x1000>; ++ reg-names = "port1"; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; +- clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, +- <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, +- <&pericfg CLK_PERI_PCIE0>, ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, + <&pericfg CLK_PERI_PCIE1>; +- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; +- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; +- phy-names = "pcie-phy0", "pcie-phy1"; ++ clock-names = "sys_ck1", "ahb_ck1"; ++ phys = <&u3port1 PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy1"; + bus-range = <0x00 0xff>; +- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>; ++ status = "disabled"; + +- pcie0: pcie@0,0 { +- reg = <0x0000 0 0 0 0>; ++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 7>; +- interrupt-map = <0 0 0 1 &pcie_intc0 0>, +- <0 0 0 2 &pcie_intc0 1>, +- <0 0 0 3 &pcie_intc0 2>, +- <0 0 0 4 &pcie_intc0 3>; +- pcie_intc0: interrupt-controller { ++ interrupt-map = <0 0 0 1 &pcie_intc1 0>, ++ <0 0 0 2 &pcie_intc1 1>, ++ <0 0 0 3 &pcie_intc1 2>, ++ <0 0 0 4 &pcie_intc1 3>; ++ pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; ++ }; + +- pcie1: pcie@1,0 { +- reg = <0x0800 0 0 0 0>; ++ pcie0: pcie@11700000 { ++ compatible = "mediatek,mt2712-pcie"; ++ device_type = "pci"; ++ reg = <0 0x11700000 0 0x1000>; ++ reg-names = "port0"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, ++ <&pericfg CLK_PERI_PCIE0>; ++ clock-names = "sys_ck0", "ahb_ck0"; ++ phys = <&u3port0 PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy0"; ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ status = "disabled"; ++ ++ slot0: pcie@0,0 { ++ reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 7>; +- interrupt-map = <0 0 0 1 &pcie_intc1 0>, +- <0 0 0 2 &pcie_intc1 1>, +- <0 0 0 3 &pcie_intc1 2>, +- <0 0 0 4 &pcie_intc1 3>; +- pcie_intc1: interrupt-controller { ++ interrupt-map = <0 0 0 1 &pcie_intc0 0>, ++ <0 0 0 2 &pcie_intc0 1>, ++ <0 0 0 3 &pcie_intc0 2>, ++ <0 0 0 4 &pcie_intc0 3>; ++ pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; +@@ -202,39 +222,31 @@ Examples for MT2712: + + Examples for MT7622: + +- pcie: pcie@1a140000 { ++ pcie0: pcie@1a143000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; +- reg = <0 0x1a140000 0 0x1000>, +- <0 0x1a143000 0 0x1000>, +- <0 0x1a145000 0 0x1000>; +- reg-names = "subsys", "port0", "port1"; ++ reg = <0 0x1a143000 0 0x1000>; ++ reg-names = "port0"; ++ mediatek,pcie-cfg = <&pciecfg>; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; + clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, +- <&pciesys CLK_PCIE_P1_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, +- <&pciesys CLK_PCIE_P1_AHB_EN>, + <&pciesys CLK_PCIE_P0_AUX_EN>, +- <&pciesys CLK_PCIE_P1_AUX_EN>, + <&pciesys CLK_PCIE_P0_AXI_EN>, +- <&pciesys CLK_PCIE_P1_AXI_EN>, + <&pciesys CLK_PCIE_P0_OBFF_EN>, +- <&pciesys CLK_PCIE_P1_OBFF_EN>, +- <&pciesys CLK_PCIE_P0_PIPE_EN>, +- <&pciesys CLK_PCIE_P1_PIPE_EN>; +- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", +- "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", +- "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; +- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; +- phy-names = "pcie-phy0", "pcie-phy1"; ++ <&pciesys CLK_PCIE_P0_PIPE_EN>; ++ clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", ++ "axi_ck0", "obff_ck0", "pipe_ck0"; ++ + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; +- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ ranges = <0x82000000 0 0x20000000 0 0x20000000 0 0x8000000>; ++ status = "disabled"; + +- pcie0: pcie@0,0 { ++ slot0: pcie@0,0 { + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -251,8 +263,34 @@ Examples for MT7622: + #interrupt-cells = <1>; + }; + }; ++ }; ++ ++ pcie1: pcie@1a145000 { ++ compatible = "mediatek,mt7622-pcie"; ++ device_type = "pci"; ++ reg = <0 0x1a145000 0 0x1000>; ++ reg-names = "port1"; ++ mediatek,pcie-cfg = <&pciecfg>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, ++ /* designer has connect RC1 with p0_ahb clock */ ++ <&pciesys CLK_PCIE_P0_AHB_EN>, ++ <&pciesys CLK_PCIE_P1_AUX_EN>, ++ <&pciesys CLK_PCIE_P1_AXI_EN>, ++ <&pciesys CLK_PCIE_P1_OBFF_EN>, ++ <&pciesys CLK_PCIE_P1_PIPE_EN>; ++ clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", ++ "axi_ck1", "obff_ck1", "pipe_ck1"; ++ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x28000000 0 0x28000000 0 0x8000000>; ++ status = "disabled"; + +- pcie1: pcie@1,0 { ++ slot1: pcie@1,0 { + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; diff --git a/root/target/linux/mediatek/patches-5.14/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch b/root/target/linux/mediatek/patches-5.14/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch new file mode 100755 index 00000000..fea9486d --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch @@ -0,0 +1,217 @@ +From patchwork Thu May 28 06:16:46 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Chuanjia Liu +X-Patchwork-Id: 11574781 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A99B60D + for ; + Thu, 28 May 2020 06:19:04 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id DCC99208FE + for ; + Thu, 28 May 2020 06:19:03 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="SpOi0ueF"; + dkim=fail reason="signature verification failed" (1024-bit key) + header.d=mediatek.com header.i=@mediatek.com header.b="UGIBoIEG" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DCC99208FE +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=mediatek.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=LIr5poLUT/UdH6/akh/pnICGGa3rUBkN+4FhE1DyOrU=; b=SpOi0ueFcoJ/ka + 4esa6cDd5oU4fp0z684ZVPaVvvhm/azSZBBMYinHaAW6EvzKcMNYIX9grP8eg/728lEPNTKVq0I8H + PQZ9KvD4uTu8Opo1hD8LsRSLr+YLpNKt3KPOY/4gpwQ97uU9rI5PwkuAxPBgR949Vh5EiG0Vaww1H + Ep+I5BFRn2LVVQZP1Z7U0A0VUcOTLJ4znoWRLEXxtM9/Wd4hwQsrEPQszeDFti/RbwGfJ5efOb5UL + fhwBzSxELEzAAgH7env/XD2sSSpVf2Qsn6WO8D3ZepMtWrRtARiaRKSNxSBQTg2SSHcjmBSJSzcX+ + w8wqWaUMs0crlBuZWS1g==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBsc-0001tI-88; Thu, 28 May 2020 06:19:02 +0000 +Received: from mailgw01.mediatek.com ([216.200.240.184]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBsZ-0001rp-6g; Thu, 28 May 2020 06:19:01 +0000 +X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; + s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=+IjWjsF/DhknqZB+lLSZ50cyvxDap+8w4tvqhp8Dv68=; + b=UGIBoIEGJUuq5pEvYEad1HVGpiv6yma+94hva83D2gD8lYmihRWkpJxB2yn+dVtNm7ZXXoQBf+jvvULOmslJgs1HZTLJTnjpdvLmQqo42OXRXSVpTE49HdRkJZDAIWIAReBfOEkFgNxcIX3uedrtnww/NLJ2lagrYPG5ET4lI2E=; +X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527 +Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com + (envelope-from ) + (musrelay.mediatek.com ESMTP with TLS) + with ESMTP id 603406343; Wed, 27 May 2020 22:19:17 -0800 +Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by + MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Wed, 27 May 2020 23:18:47 -0700 +Received: from mtkcas07.mediatek.inc (172.21.101.84) by + mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Thu, 28 May 2020 14:18:51 +0800 +Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend + Transport; Thu, 28 May 2020 14:18:49 +0800 +From: +To: , , +Subject: [PATCH v2 2/4] PCI: mediatek: Use regmap to get shared pcie-cfg base +Date: Thu, 28 May 2020 14:16:46 +0800 +Message-ID: <20200528061648.32078-3-chuanjia.liu@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200527_231859_251275_BED2B1E2 +X-CRM114-Status: GOOD ( 11.62 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 + encoding + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay + lines +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, + srv_heupstream@mediatek.com, "chuanjia.liu" , + linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, + jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, + yong.wu@mediatek.com, bhelgaas@google.com, + linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org + +From: "chuanjia.liu" + +Use regmap to get shared pcie-cfg base and change +the method to get pcie irq. + +Signed-off-by: chuanjia.liu +--- + drivers/pci/controller/pcie-mediatek.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,6 +24,7 @@ + #include + #include + #include ++#include + #include + + #include "../pci.h" +@@ -207,6 +209,7 @@ struct mtk_pcie_port { + * struct mtk_pcie - PCIe host information + * @dev: pointer to PCIe device + * @base: IO mapped register base ++ * @cfg: IO mapped register map for PCIe config + * @free_ck: free-run reference clock + * @mem: non-prefetchable memory resource + * @ports: pointer to PCIe port information +@@ -215,6 +218,7 @@ struct mtk_pcie_port { + struct mtk_pcie { + struct device *dev; + void __iomem *base; ++ struct regmap *cfg; + struct clk *free_ck; + + struct list_head ports; +@@ -650,7 +654,7 @@ static int mtk_pcie_setup_irq(struct mtk + return err; + } + +- port->irq = platform_get_irq(pdev, port->slot); ++ port->irq = platform_get_irq_byname(pdev, "pcie_irq"); + if (port->irq < 0) + return port->irq; + +@@ -676,12 +680,11 @@ static int mtk_pcie_startup_port_v2(stru + if (!mem) + return -EINVAL; + +- /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ +- if (pcie->base) { +- val = readl(pcie->base + PCIE_SYS_CFG_V2); +- val |= PCIE_CSR_LTSSM_EN(port->slot) | +- PCIE_CSR_ASPM_L1_EN(port->slot); +- writel(val, pcie->base + PCIE_SYS_CFG_V2); ++ /* MT7622/MT7629 platforms need to enable LTSSM and ASPM. */ ++ if (pcie->cfg) { ++ val = PCIE_CSR_LTSSM_EN(port->slot) | ++ PCIE_CSR_ASPM_L1_EN(port->slot); ++ regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val); + } + + /* Assert all reset signals */ +@@ -985,6 +988,7 @@ static int mtk_pcie_subsys_powerup(struc + struct device *dev = pcie->dev; + struct platform_device *pdev = to_platform_device(dev); + struct resource *regs; ++ struct device_node *cfg_node; + int err; + + /* get shared registers, which are optional */ +@@ -997,6 +1001,13 @@ static int mtk_pcie_subsys_powerup(struc + } + } + ++ cfg_node = of_parse_phandle(dev->of_node, "mediatek,pcie-cfg", 0); ++ if (cfg_node) { ++ pcie->cfg = syscon_node_to_regmap(cfg_node); ++ if (IS_ERR(pcie->cfg)) ++ return PTR_ERR(pcie->cfg); ++ } ++ + pcie->free_ck = devm_clk_get(dev, "free_ck"); + if (IS_ERR(pcie->free_ck)) { + if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER) diff --git a/root/target/linux/mediatek/patches-5.14/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch b/root/target/linux/mediatek/patches-5.14/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch new file mode 100755 index 00000000..0654241e --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch @@ -0,0 +1,417 @@ +From patchwork Thu May 28 06:16:47 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Chuanjia Liu +X-Patchwork-Id: 11574785 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 933301391 + for ; + Thu, 28 May 2020 06:19:16 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id D19F02078C + for ; + Thu, 28 May 2020 06:19:15 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="s8K7t7DF"; + dkim=fail reason="signature verification failed" (1024-bit key) + header.d=mediatek.com header.i=@mediatek.com header.b="RhX81Iqp" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D19F02078C +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=mediatek.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=NHyHqNMcE7LW10MwduOJoKiWe8cv+XayY+L6WDZeSu0=; b=s8K7t7DFh1iQ5w + eGvuMRgXEQv/YWRuSZRyX8lx8R2H9IuawEIgkhO6lEo6xv0VdsRuj8SptfoWg5afCItMhih373M21 + 6sUy3tEiuKGgklfxLU0reLEkaATkKRGLJDY3eSSs1mvZDrydKuZLDTka+YDGaiESlOhqMr95Nm6YM + yK8O00qTwSRPJUILRsBv1e/Kz8NRCmYhs56snABJkKeJ51NRAkb20R6qGTEd6UyBlz3jTVYwluLgF + bdqzywDT6+BNg/Agh6Zd+v2PpO4cmwCpGm62+3UUyZkfi/aQ4qZ/AFAfSQI+3ZBAgsKMC1PGifOi/ + FgGxIvAUk6atBy7DAHuw==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBsn-00025C-EF; Thu, 28 May 2020 06:19:13 +0000 +Received: from mailgw01.mediatek.com ([216.200.240.184]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBsZ-0001s4-6j; Thu, 28 May 2020 06:19:01 +0000 +X-UUID: c6210e6371fa445db0ae40a8b8a7a0a1-20200527 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; + s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=X9AwTdbhpWmlWY4LjTm8KLq4Cca3YI9UnyCX3O0BAak=; + b=RhX81Iqp0mWhBDyMQMFSEtt23+DGAWoin1SrFGP1bzp6GEtu38b2pK5RJVBshJtuxi/a1uMXZjeDsHJn02VGdNA07FrzZ7jq6YYEL+8cJs2DnhySmNElZazXPv2vKu9TWygfilTT24h/u8V/eszuRuhkdoUKWol8LwDlPl9gskg=; +X-UUID: c6210e6371fa445db0ae40a8b8a7a0a1-20200527 +Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com + (envelope-from ) + (musrelay.mediatek.com ESMTP with TLS) + with ESMTP id 7561992; Wed, 27 May 2020 22:19:17 -0800 +Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by + MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Wed, 27 May 2020 23:18:47 -0700 +Received: from mtkcas07.mediatek.inc (172.21.101.84) by + mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Thu, 28 May 2020 14:18:52 +0800 +Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend + Transport; Thu, 28 May 2020 14:18:51 +0800 +From: +To: , , +Subject: [PATCH v2 3/4] arm64: dts: mediatek: Split PCIe node for + MT2712/MT7622 +Date: Thu, 28 May 2020 14:16:47 +0800 +Message-ID: <20200528061648.32078-4-chuanjia.liu@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200527_231859_253529_B6751C5A +X-CRM114-Status: GOOD ( 12.20 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 + encoding + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay + lines +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, + srv_heupstream@mediatek.com, "chuanjia.liu" , + linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, + jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, + yong.wu@mediatek.com, bhelgaas@google.com, + linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org + +From: "chuanjia.liu" + +There are two independent PCIe controllers in MT2712/MT7622 platform, +and each of them should contain an independent MSI domain. + +In current architecture, MSI domain will be inherited from the root +bridge, and all of the devices will share the same MSI domain. +Hence that, the PCIe devices will not work properly if the irq number +which required is more than 32. + +Split the PCIe node for MT2712/MT7622 platform to fix MSI issue and +comply with the hardware design. + +Signed-off-by: chuanjia.liu +--- + arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 75 +++++++++++-------- + .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 16 ++-- + arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 6 +- + arch/arm64/boot/dts/mediatek/mt7622.dtsi | 68 +++++++++++------ + 4 files changed, 96 insertions(+), 69 deletions(-) + +--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +@@ -915,60 +915,73 @@ + }; + }; + +- pcie: pcie@11700000 { ++ pcie1: pcie@112ff000 { + compatible = "mediatek,mt2712-pcie"; + device_type = "pci"; +- reg = <0 0x11700000 0 0x1000>, +- <0 0x112ff000 0 0x1000>; +- reg-names = "port0", "port1"; ++ reg = <0 0x112ff000 0 0x1000>; ++ reg-names = "port1"; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; +- clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, +- <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, +- <&pericfg CLK_PERI_PCIE0>, ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, + <&pericfg CLK_PERI_PCIE1>; +- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; +- phys = <&u3port0 PHY_TYPE_PCIE>, <&u3port1 PHY_TYPE_PCIE>; +- phy-names = "pcie-phy0", "pcie-phy1"; ++ clock-names = "sys_ck1", "ahb_ck1"; ++ phys = <&u3port1 PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy1"; + bus-range = <0x00 0xff>; +- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>; ++ status = "disabled"; + +- pcie0: pcie@0,0 { +- device_type = "pci"; +- status = "disabled"; +- reg = <0x0000 0 0 0 0>; ++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 7>; +- interrupt-map = <0 0 0 1 &pcie_intc0 0>, +- <0 0 0 2 &pcie_intc0 1>, +- <0 0 0 3 &pcie_intc0 2>, +- <0 0 0 4 &pcie_intc0 3>; +- pcie_intc0: interrupt-controller { ++ interrupt-map = <0 0 0 1 &pcie_intc1 0>, ++ <0 0 0 2 &pcie_intc1 1>, ++ <0 0 0 3 &pcie_intc1 2>, ++ <0 0 0 4 &pcie_intc1 3>; ++ pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; ++ }; + +- pcie1: pcie@1,0 { +- device_type = "pci"; +- status = "disabled"; +- reg = <0x0800 0 0 0 0>; ++ pcie0: pcie@11700000 { ++ compatible = "mediatek,mt2712-pcie"; ++ device_type = "pci"; ++ reg = <0 0x11700000 0 0x1000>; ++ reg-names = "port0"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, ++ <&pericfg CLK_PERI_PCIE0>; ++ clock-names = "sys_ck0", "ahb_ck0"; ++ phys = <&u3port0 PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy0"; ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ status = "disabled"; ++ ++ slot0: pcie@0,0 { ++ reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 7>; +- interrupt-map = <0 0 0 1 &pcie_intc1 0>, +- <0 0 0 2 &pcie_intc1 1>, +- <0 0 0 3 &pcie_intc1 2>, +- <0 0 0 4 &pcie_intc1 3>; +- pcie_intc1: interrupt-controller { ++ interrupt-map = <0 0 0 1 &pcie_intc0 0>, ++ <0 0 0 2 &pcie_intc0 1>, ++ <0 0 0 3 &pcie_intc0 2>, ++ <0 0 0 4 &pcie_intc0 3>; ++ pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -288,18 +288,16 @@ + }; + }; + +-&pcie { ++&pcie0 { + pinctrl-names = "default"; +- pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; ++ pinctrl-0 = <&pcie0_pins>; + status = "okay"; ++}; + +- pcie@0,0 { +- status = "okay"; +- }; +- +- pcie@1,0 { +- status = "okay"; +- }; ++&pcie1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_pins>; ++ status = "okay"; + }; + + &pio { +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -802,45 +802,41 @@ + #reset-cells = <1>; + }; + +- pcie: pcie@1a140000 { ++ pciecfg: pciecfg@1a140000 { ++ compatible = "mediatek,mt7622-pciecfg", "syscon"; ++ reg = <0 0x1a140000 0 0x1000>; ++ }; ++ ++ pcie0: pcie@1a143000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; +- reg = <0 0x1a140000 0 0x1000>, +- <0 0x1a143000 0 0x1000>, +- <0 0x1a145000 0 0x1000>; +- reg-names = "subsys", "port0", "port1"; ++ reg = <0 0x1a143000 0 0x1000>; ++ reg-names = "port0"; ++ mediatek,pcie-cfg = <&pciecfg>; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; + clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, +- <&pciesys CLK_PCIE_P1_MAC_EN>, +- <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P0_AUX_EN>, +- <&pciesys CLK_PCIE_P1_AUX_EN>, + <&pciesys CLK_PCIE_P0_AXI_EN>, +- <&pciesys CLK_PCIE_P1_AXI_EN>, + <&pciesys CLK_PCIE_P0_OBFF_EN>, +- <&pciesys CLK_PCIE_P1_OBFF_EN>, +- <&pciesys CLK_PCIE_P0_PIPE_EN>, +- <&pciesys CLK_PCIE_P1_PIPE_EN>; +- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", +- "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", +- "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; ++ <&pciesys CLK_PCIE_P0_PIPE_EN>; ++ clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", ++ "axi_ck0", "obff_ck0", "pipe_ck0"; ++ + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; +- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; + status = "disabled"; + +- pcie0: pcie@0,0 { ++ slot0: pcie@0,0 { + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; +- status = "disabled"; +- + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, +@@ -852,15 +848,39 @@ + #interrupt-cells = <1>; + }; + }; ++ }; + +- pcie1: pcie@1,0 { ++ pcie1: pcie@1a145000 { ++ compatible = "mediatek,mt7622-pcie"; ++ device_type = "pci"; ++ reg = <0 0x1a145000 0 0x1000>; ++ reg-names = "port1"; ++ mediatek,pcie-cfg = <&pciecfg>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, ++ /* designer has connect RC1 with p0_ahb clock */ ++ <&pciesys CLK_PCIE_P0_AHB_EN>, ++ <&pciesys CLK_PCIE_P1_AUX_EN>, ++ <&pciesys CLK_PCIE_P1_AXI_EN>, ++ <&pciesys CLK_PCIE_P1_OBFF_EN>, ++ <&pciesys CLK_PCIE_P1_PIPE_EN>; ++ clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", ++ "axi_ck1", "obff_ck1", "pipe_ck1"; ++ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; ++ status = "disabled"; ++ ++ slot1: pcie@1,0 { + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; +- status = "disabled"; +- + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +@@ -232,18 +232,16 @@ + }; + }; + +-&pcie { ++&pcie0 { + pinctrl-names = "default"; +- pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; ++ pinctrl-0 = <&pcie0_pins>; + status = "okay"; ++}; + +- pcie@0,0 { +- status = "okay"; +- }; +- +- pcie@1,0 { +- status = "okay"; +- }; ++&pcie1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_pins>; ++ status = "okay"; + }; + + &pio { diff --git a/root/target/linux/mediatek/patches-5.14/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch b/root/target/linux/mediatek/patches-5.14/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch new file mode 100755 index 00000000..ce72ad65 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch @@ -0,0 +1,203 @@ +From patchwork Thu May 28 06:16:48 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Chuanjia Liu +X-Patchwork-Id: 11574797 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 30A5E1392 + for ; + Thu, 28 May 2020 06:29:05 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id 08B6320721 + for ; + Thu, 28 May 2020 06:29:05 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="auhxDafY"; + dkim=fail reason="signature verification failed" (1024-bit key) + header.d=mediatek.com header.i=@mediatek.com header.b="Kj09Arxb" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 08B6320721 +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=mediatek.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=+QPxF1vlOH7StIZYuXJa3V40x8QVDxCLF9AFXHblB9M=; b=auhxDafYBeaUZO + aYp2KVO8Aie0v4tYtRwBon7hF+x55JwD78SAxQR2RsSvrlOo9cMYYby+ToUWflVUWQ60FapAl+w+l + nkEjIOrLBErHwxNOcsD8T5kjyCBMqlz4OMAQYUDNJ3fSugRlGhOtxkjCGd9ebB8N2Rvu6/U8P1A9n + P15mEQoc+RLonR1+9mBgwTEXErjsraxkimTD4Txsp4IvMs3UdsMkP+r3OT5S/p+Uj6O9ES0h7xIon + aL79KaVqRLHrfZxnrVwuGiecAiTp8qLy9clHuJU32NA6ZcXH1OnWipKApgp8Ck7ys80WPKaMrat9B + XuskJ63w13DZAbCVvuGQ==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeC2J-00014n-M9; Thu, 28 May 2020 06:29:03 +0000 +Received: from mailgw02.mediatek.com ([216.200.240.185]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeC2H-00013t-Li; Thu, 28 May 2020 06:29:03 +0000 +X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; + s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=CIwcBFK1x0LbOjDt1BG6/knHFxDHRiqj8ov/jWEZDBY=; + b=Kj09ArxbnLVTc9bpaVPT3jQrIVjhL87sSYyVF9dFypS976k78Ce9gZd0f4K3zAZbYZHYoQtuyOQ9TOeufQfgD+Cr+j5VR7pTdO2E1iXHFs/eQAz5gAjvjlK01z1JiunrLnn9dvIr6c1gEkjQHny0VpuZ1duxx79jwYusg/Nw6Wc=; +X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527 +Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by + mailgw02.mediatek.com + (envelope-from ) + (musrelay.mediatek.com ESMTP with TLS) + with ESMTP id 899663677; Wed, 27 May 2020 22:29:21 -0800 +Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by + MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Wed, 27 May 2020 23:18:50 -0700 +Received: from mtkcas07.mediatek.inc (172.21.101.84) by + mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Thu, 28 May 2020 14:18:54 +0800 +Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend + Transport; Thu, 28 May 2020 14:18:52 +0800 +From: +To: , , +Subject: [PATCH v2 4/4] ARM: dts: mediatek: Update mt7629 PCIe node +Date: Thu, 28 May 2020 14:16:48 +0800 +Message-ID: <20200528061648.32078-5-chuanjia.liu@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200527_232901_719172_E5A99C62 +X-CRM114-Status: GOOD ( 11.61 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 + encoding + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay + lines +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, + srv_heupstream@mediatek.com, "chuanjia.liu" , + linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, + jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, + yong.wu@mediatek.com, bhelgaas@google.com, + linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org + +From: "chuanjia.liu" + +Remove unused property and add pciecfg node. + +Signed-off-by: chuanjia.liu +--- + arch/arm/boot/dts/mt7629-rfb.dts | 3 ++- + arch/arm/boot/dts/mt7629.dtsi | 23 +++++++++++++---------- + 2 files changed, 15 insertions(+), 11 deletions(-) + +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -149,9 +149,10 @@ + }; + }; + +-&pcie { ++&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pins>; ++ status = "okay"; + }; + + &pciephy1 { +--- a/arch/arm/boot/dts/mt7629.dtsi ++++ b/arch/arm/boot/dts/mt7629.dtsi +@@ -376,16 +376,21 @@ + #reset-cells = <1>; + }; + +- pcie: pcie@1a140000 { ++ pciecfg: pciecfg@1a140000 { ++ compatible = "mediatek,mt7629-pciecfg", "syscon"; ++ reg = <0x1a140000 0x1000>; ++ }; ++ ++ pcie1: pcie@1a145000 { + compatible = "mediatek,mt7629-pcie"; + device_type = "pci"; +- reg = <0x1a140000 0x1000>, +- <0x1a145000 0x1000>; +- reg-names = "subsys","port1"; ++ reg = <0x1a145000 0x1000>; ++ reg-names = "port1"; ++ mediatek,pcie-cfg = <&pciecfg>; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; + clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P1_AUX_EN>, +@@ -406,21 +411,19 @@ + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>; ++ status = "disabled"; + +- pcie1: pcie@1,0 { +- device_type = "pci"; ++ slot1: pcie@1,0 { + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; +- num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; +- + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; diff --git a/root/target/linux/mediatek/patches-5.14/610-pcie-mediatek-fix-clearing-interrupt-status.patch b/root/target/linux/mediatek/patches-5.14/610-pcie-mediatek-fix-clearing-interrupt-status.patch new file mode 100755 index 00000000..031582a7 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/610-pcie-mediatek-fix-clearing-interrupt-status.patch @@ -0,0 +1,24 @@ +From: Felix Fietkau +Date: Fri, 4 Sep 2020 18:33:27 +0200 +Subject: [PATCH] pcie-mediatek: fix clearing interrupt status + +Clearing the status needs to happen after running the handler, otherwise +we will get an extra spurious interrupt after the cause has been cleared + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -615,10 +615,10 @@ static void mtk_pcie_intr_handler(struct + if (status & INTX_MASK) { + for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { + /* Clear the INTx */ +- writel(1 << bit, port->base + PCIE_INT_STATUS); + virq = irq_find_mapping(port->irq_domain, + bit - INTX_SHIFT); + generic_handle_irq(virq); ++ writel(1 << bit, port->base + PCIE_INT_STATUS); + } + } + diff --git a/root/target/linux/mediatek/patches-5.14/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch b/root/target/linux/mediatek/patches-5.14/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch new file mode 100755 index 00000000..e75d4c7a --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch @@ -0,0 +1,85 @@ +From: Felix Fietkau +Date: Fri, 4 Sep 2020 18:36:06 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for coherent DMA + +It improves performance by eliminating the need for a cache flush on rx and tx + +Signed-off-by: Felix Fietkau +--- + +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -364,7 +364,7 @@ + }; + + cci_control2: slave-if@5000 { +- compatible = "arm,cci-400-ctrl-if"; ++ compatible = "arm,cci-400-ctrl-if", "syscon"; + interface-type = "ace"; + reg = <0x5000 0x1000>; + }; +@@ -977,6 +977,8 @@ + power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys>; ++ mediatek,cci-control = <&cci_control2>; ++ dma-coherent; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2494,6 +2495,13 @@ static int mtk_hw_init(struct mtk_eth *e + if (ret) + goto err_disable_pm; + ++ if (of_dma_is_coherent(eth->dev->of_node)) { ++ u32 mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | ++ ETHSYS_DMA_AG_MAP_PPE; ++ ++ regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, mask, mask); ++ } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { + ret = device_reset(eth->dev); + if (ret) { +@@ -3071,6 +3079,16 @@ static int mtk_probe(struct platform_dev + } + } + ++ if (of_dma_is_coherent(pdev->dev.of_node)) { ++ struct regmap *cci; ++ ++ cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, ++ "mediatek,cci-control"); ++ /* enable CPU/bus coherency */ ++ if (!IS_ERR(cci)) ++ regmap_write(cci, 0, 3); ++ } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { + eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii), + GFP_KERNEL); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -450,6 +450,12 @@ + #define RSTCTRL_FE BIT(6) + #define RSTCTRL_PPE BIT(31) + ++/* ethernet dma channel agent map */ ++#define ETHSYS_DMA_AG_MAP 0x408 ++#define ETHSYS_DMA_AG_MAP_PDMA BIT(0) ++#define ETHSYS_DMA_AG_MAP_QDMA BIT(1) ++#define ETHSYS_DMA_AG_MAP_PPE BIT(2) ++ + /* SGMII subsystem config registers */ + /* Register to auto-negotiation restart */ + #define SGMSYS_PCS_CONTROL_1 0x0 diff --git a/root/target/linux/mediatek/patches-5.14/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch b/root/target/linux/mediatek/patches-5.14/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch new file mode 100755 index 00000000..ec5f13b4 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch @@ -0,0 +1,108 @@ +From: Felix Fietkau +Date: Fri, 4 Sep 2020 18:42:42 +0200 +Subject: [PATCH] pci: pcie-mediatek: add support for coherent DMA + +It improves performance by eliminating the need for a cache flush for DMA on +attached devices + +Signed-off-by: Felix Fietkau +--- + +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -813,6 +813,8 @@ + reg = <0 0x1a143000 0 0x1000>; + reg-names = "port0"; + mediatek,pcie-cfg = <&pciecfg>; ++ mediatek,hifsys = <&hifsys>; ++ mediatek,cci-control = <&cci_control2>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; +@@ -830,6 +832,7 @@ + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; + status = "disabled"; ++ dma-coherent; + + slot0: pcie@0,0 { + reg = <0x0000 0 0 0 0>; +@@ -856,6 +859,8 @@ + reg = <0 0x1a145000 0 0x1000>; + reg-names = "port1"; + mediatek,pcie-cfg = <&pciecfg>; ++ mediatek,hifsys = <&hifsys>; ++ mediatek,cci-control = <&cci_control2>; + #address-cells = <3>; + #size-cells = <2>; + interrupts = ; +@@ -874,6 +879,7 @@ + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; + status = "disabled"; ++ dma-coherent; + + slot1: pcie@1,0 { + reg = <0x0800 0 0 0 0>; +@@ -933,6 +939,11 @@ + }; + }; + ++ hifsys: syscon@1af00000 { ++ compatible = "mediatek,mt7622-hifsys", "syscon"; ++ reg = <0 0x1af00000 0 0x70>; ++ }; ++ + ethsys: syscon@1b000000 { + compatible = "mediatek,mt7622-ethsys", + "syscon"; +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -139,6 +140,11 @@ + #define PCIE_LINK_STATUS_V2 0x804 + #define PCIE_PORT_LINKUP_V2 BIT(10) + ++/* DMA channel mapping */ ++#define HIFSYS_DMA_AG_MAP 0x008 ++#define HIFSYS_DMA_AG_MAP_PCIE0 BIT(0) ++#define HIFSYS_DMA_AG_MAP_PCIE1 BIT(1) ++ + struct mtk_pcie_port; + + /** +@@ -1042,6 +1048,27 @@ static int mtk_pcie_setup(struct mtk_pci + struct mtk_pcie_port *port, *tmp; + int err; + ++ if (of_dma_is_coherent(node)) { ++ struct regmap *con; ++ u32 mask; ++ ++ con = syscon_regmap_lookup_by_phandle(node, ++ "mediatek,cci-control"); ++ /* enable CPU/bus coherency */ ++ if (!IS_ERR(con)) ++ regmap_write(con, 0, 3); ++ ++ con = syscon_regmap_lookup_by_phandle(node, ++ "mediatek,hifsys"); ++ if (IS_ERR(con)) { ++ dev_err(dev, "missing hifsys node\n"); ++ return PTR_ERR(con); ++ } ++ ++ mask = HIFSYS_DMA_AG_MAP_PCIE0 | HIFSYS_DMA_AG_MAP_PCIE1; ++ regmap_update_bits(con, HIFSYS_DMA_AG_MAP, mask, mask); ++ } ++ + for_each_available_child_of_node(node, child) { + int slot; + diff --git a/root/target/linux/mediatek/patches-5.14/800-ubnt-ledbar-driver.patch b/root/target/linux/mediatek/patches-5.14/800-ubnt-ledbar-driver.patch new file mode 100755 index 00000000..92264eed --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/800-ubnt-ledbar-driver.patch @@ -0,0 +1,29 @@ +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -929,6 +929,16 @@ config LEDS_ACER_A500 + This option enables support for the Power Button LED of + Acer Iconia Tab A500. + ++config LEDS_UBNT_LEDBAR ++ tristate "LED support for Ubiquiti UniFi 6 LR" ++ depends on LEDS_CLASS && I2C && OF ++ help ++ This option enables support for the Ubiquiti LEDBAR ++ LED driver. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called leds-ubnt-ledbar. ++ + comment "LED Triggers" + source "drivers/leds/trigger/Kconfig" + +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -93,6 +93,7 @@ obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds + obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o + obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o + obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o ++obj-$(CONFIG_LEDS_UBNT_LEDBAR) += leds-ubnt-ledbar.o + + # LED SPI Drivers + obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o diff --git a/root/target/linux/mediatek/patches-5.14/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch b/root/target/linux/mediatek/patches-5.14/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch new file mode 100755 index 00000000..7e539be3 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.14/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch @@ -0,0 +1,80 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -297,14 +297,14 @@ + &pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie1_pins>; +- status = "okay"; ++ status = "disabled"; + }; + + &pio { + /* Attention: GPIO 90 is used to switch between PCIe@1,0 and + * SATA functions. i.e. output-high: PCIe, output-low: SATA + */ +- asm_sel { ++ asmsel: asm_sel { + gpio-hog; + gpios = <90 GPIO_ACTIVE_HIGH>; + output-high; +--- /dev/null ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dts +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ ++ ++#include ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "bananapi,bpi-r64", "mediatek,mt7622"; ++ ++ fragment@0 { ++ target = <&asmsel>; ++ __overlay__ { ++ gpios = <90 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&sata>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sata_phy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +--- /dev/null ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dts +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ ++ ++#include ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "bananapi,bpi-r64", "mediatek,mt7622"; ++ ++ fragment@0 { ++ target = <&asmsel>; ++ __overlay__ { ++ gpios = <90 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pcie1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; diff --git a/root/target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch b/root/target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch new file mode 100755 index 00000000..79ce15c3 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0001-v5.7-spi-make-spi-max-frequency-optional.patch @@ -0,0 +1,38 @@ +From 671c3bf50ae498dc12aef6c70abe5cfa066b1348 Mon Sep 17 00:00:00 2001 +From: Chuanhong Guo +Date: Fri, 6 Mar 2020 16:50:49 +0800 +Subject: [PATCH 1/2] spi: make spi-max-frequency optional + +We only need a spi-max-frequency when we specifically request a +spi frequency lower than the max speed of spi host. +This property is already documented as optional property and current +host drivers are implemented to operate at highest speed possible +when spi->max_speed_hz is 0. +This patch makes spi-max-frequency an optional property so that +we could just omit it to use max controller speed. + +Signed-off-by: Chuanhong Guo +Link: https://lore.kernel.org/r/20200306085052.28258-2-gch981213@gmail.com +Signed-off-by: Mark Brown +--- + drivers/spi/spi.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -1809,13 +1809,8 @@ static int of_spi_parse_dt(struct spi_co + spi->mode |= SPI_CS_HIGH; + + /* Device speed */ +- rc = of_property_read_u32(nc, "spi-max-frequency", &value); +- if (rc) { +- dev_err(&ctlr->dev, +- "%pOF has no valid 'spi-max-frequency' property (%d)\n", nc, rc); +- return rc; +- } +- spi->max_speed_hz = value; ++ if (!of_property_read_u32(nc, "spi-max-frequency", &value)) ++ spi->max_speed_hz = value; + + return 0; + } diff --git a/root/target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch b/root/target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch new file mode 100755 index 00000000..0a63bddd --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch @@ -0,0 +1,761 @@ +From 881d1ee9fe81ff2be1b90809a07621be97404a57 Mon Sep 17 00:00:00 2001 +From: Chuanhong Guo +Date: Fri, 6 Mar 2020 16:50:50 +0800 +Subject: [PATCH 2/2] spi: add support for mediatek spi-nor controller + +This is a driver for mtk spi-nor controller using spi-mem interface. +The same controller already has limited support provided by mtk-quadspi +driver under spi-nor framework and this new driver is a replacement +for the old one. + +Comparing to the old driver, this driver has following advantages: +1. It can handle any full-duplex spi transfer up to 6 bytes, and + this is implemented using generic spi interface. +2. It take account into command opcode properly. The reading routine + in this controller can only use 0x03 or 0x0b as opcode on 1-1-1 + transfers, but old driver doesn't implement this properly. This + driver checks supported opcode explicitly and use (1) to perform + unmatched operations. +3. It properly handles SFDP reading. Old driver can't read SFDP + due to the bug mentioned in (2). +4. It can do 1-2-2 and 1-4-4 fast reading on spi-nor. These two ops + requires parsing SFDP, which isn't possible in old driver. And + the old driver is only flagged to support 1-1-2 mode. +5. It takes advantage of the DMA feature in this controller for + long reads and supports IRQ on DMA requests to free cpu cycles + from polling status registers on long DMA reading. It achieves + up to 17.5MB/s reading speed (1-4-4 mode) which is way faster + than the old one. IRQ is implemented as optional to maintain + backward compatibility. + +Signed-off-by: Chuanhong Guo +Link: https://lore.kernel.org/r/20200306085052.28258-3-gch981213@gmail.com +Signed-off-by: Mark Brown +--- + drivers/spi/Kconfig | 10 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-mtk-nor.c | 689 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 700 insertions(+) + create mode 100644 drivers/spi/spi-mtk-nor.c + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -433,6 +433,16 @@ config SPI_MT7621 + help + This selects a driver for the MediaTek MT7621 SPI Controller. + ++config SPI_MTK_NOR ++ tristate "MediaTek SPI NOR controller" ++ depends on ARCH_MEDIATEK || COMPILE_TEST ++ help ++ This enables support for SPI NOR controller found on MediaTek ++ ARM SoCs. This is a controller specifically for SPI-NOR flash. ++ It can perform generic SPI transfers up to 6 bytes via generic ++ SPI interface as well as several SPI-NOR specific instructions ++ via SPI MEM interface. ++ + config SPI_NPCM_FIU + tristate "Nuvoton NPCM FLASH Interface Unit" + depends on ARCH_NPCM || COMPILE_TEST +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -61,6 +61,7 @@ obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mp + obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o + obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o + obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o ++obj-$(CONFIG_SPI_MTK_NOR) += spi-mtk-nor.o + obj-$(CONFIG_SPI_MXIC) += spi-mxic.o + obj-$(CONFIG_SPI_MXS) += spi-mxs.o + obj-$(CONFIG_SPI_NPCM_FIU) += spi-npcm-fiu.o +--- /dev/null ++++ b/drivers/spi/spi-mtk-nor.c +@@ -0,0 +1,689 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// Mediatek SPI NOR controller driver ++// ++// Copyright (C) 2020 Chuanhong Guo ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "mtk-spi-nor" ++ ++#define MTK_NOR_REG_CMD 0x00 ++#define MTK_NOR_CMD_WRITE BIT(4) ++#define MTK_NOR_CMD_PROGRAM BIT(2) ++#define MTK_NOR_CMD_READ BIT(0) ++#define MTK_NOR_CMD_MASK GENMASK(5, 0) ++ ++#define MTK_NOR_REG_PRG_CNT 0x04 ++#define MTK_NOR_REG_RDATA 0x0c ++ ++#define MTK_NOR_REG_RADR0 0x10 ++#define MTK_NOR_REG_RADR(n) (MTK_NOR_REG_RADR0 + 4 * (n)) ++#define MTK_NOR_REG_RADR3 0xc8 ++ ++#define MTK_NOR_REG_WDATA 0x1c ++ ++#define MTK_NOR_REG_PRGDATA0 0x20 ++#define MTK_NOR_REG_PRGDATA(n) (MTK_NOR_REG_PRGDATA0 + 4 * (n)) ++#define MTK_NOR_REG_PRGDATA_MAX 5 ++ ++#define MTK_NOR_REG_SHIFT0 0x38 ++#define MTK_NOR_REG_SHIFT(n) (MTK_NOR_REG_SHIFT0 + 4 * (n)) ++#define MTK_NOR_REG_SHIFT_MAX 9 ++ ++#define MTK_NOR_REG_CFG1 0x60 ++#define MTK_NOR_FAST_READ BIT(0) ++ ++#define MTK_NOR_REG_CFG2 0x64 ++#define MTK_NOR_WR_CUSTOM_OP_EN BIT(4) ++#define MTK_NOR_WR_BUF_EN BIT(0) ++ ++#define MTK_NOR_REG_PP_DATA 0x98 ++ ++#define MTK_NOR_REG_IRQ_STAT 0xa8 ++#define MTK_NOR_REG_IRQ_EN 0xac ++#define MTK_NOR_IRQ_DMA BIT(7) ++#define MTK_NOR_IRQ_MASK GENMASK(7, 0) ++ ++#define MTK_NOR_REG_CFG3 0xb4 ++#define MTK_NOR_DISABLE_WREN BIT(7) ++#define MTK_NOR_DISABLE_SR_POLL BIT(5) ++ ++#define MTK_NOR_REG_WP 0xc4 ++#define MTK_NOR_ENABLE_SF_CMD 0x30 ++ ++#define MTK_NOR_REG_BUSCFG 0xcc ++#define MTK_NOR_4B_ADDR BIT(4) ++#define MTK_NOR_QUAD_ADDR BIT(3) ++#define MTK_NOR_QUAD_READ BIT(2) ++#define MTK_NOR_DUAL_ADDR BIT(1) ++#define MTK_NOR_DUAL_READ BIT(0) ++#define MTK_NOR_BUS_MODE_MASK GENMASK(4, 0) ++ ++#define MTK_NOR_REG_DMA_CTL 0x718 ++#define MTK_NOR_DMA_START BIT(0) ++ ++#define MTK_NOR_REG_DMA_FADR 0x71c ++#define MTK_NOR_REG_DMA_DADR 0x720 ++#define MTK_NOR_REG_DMA_END_DADR 0x724 ++ ++#define MTK_NOR_PRG_MAX_SIZE 6 ++// Reading DMA src/dst addresses have to be 16-byte aligned ++#define MTK_NOR_DMA_ALIGN 16 ++#define MTK_NOR_DMA_ALIGN_MASK (MTK_NOR_DMA_ALIGN - 1) ++// and we allocate a bounce buffer if destination address isn't aligned. ++#define MTK_NOR_BOUNCE_BUF_SIZE PAGE_SIZE ++ ++// Buffered page program can do one 128-byte transfer ++#define MTK_NOR_PP_SIZE 128 ++ ++#define CLK_TO_US(sp, clkcnt) ((clkcnt) * 1000000 / sp->spi_freq) ++ ++struct mtk_nor { ++ struct spi_controller *ctlr; ++ struct device *dev; ++ void __iomem *base; ++ u8 *buffer; ++ struct clk *spi_clk; ++ struct clk *ctlr_clk; ++ unsigned int spi_freq; ++ bool wbuf_en; ++ bool has_irq; ++ struct completion op_done; ++}; ++ ++static inline void mtk_nor_rmw(struct mtk_nor *sp, u32 reg, u32 set, u32 clr) ++{ ++ u32 val = readl(sp->base + reg); ++ ++ val &= ~clr; ++ val |= set; ++ writel(val, sp->base + reg); ++} ++ ++static inline int mtk_nor_cmd_exec(struct mtk_nor *sp, u32 cmd, ulong clk) ++{ ++ ulong delay = CLK_TO_US(sp, clk); ++ u32 reg; ++ int ret; ++ ++ writel(cmd, sp->base + MTK_NOR_REG_CMD); ++ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CMD, reg, !(reg & cmd), ++ delay / 3, (delay + 1) * 200); ++ if (ret < 0) ++ dev_err(sp->dev, "command %u timeout.\n", cmd); ++ return ret; ++} ++ ++static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op) ++{ ++ u32 addr = op->addr.val; ++ int i; ++ ++ for (i = 0; i < 3; i++) { ++ writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR(i)); ++ addr >>= 8; ++ } ++ if (op->addr.nbytes == 4) { ++ writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR3); ++ mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, MTK_NOR_4B_ADDR, 0); ++ } else { ++ mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, 0, MTK_NOR_4B_ADDR); ++ } ++} ++ ++static bool mtk_nor_match_read(const struct spi_mem_op *op) ++{ ++ int dummy = 0; ++ ++ if (op->dummy.buswidth) ++ dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth; ++ ++ if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) { ++ if (op->addr.buswidth == 1) ++ return dummy == 8; ++ else if (op->addr.buswidth == 2) ++ return dummy == 4; ++ else if (op->addr.buswidth == 4) ++ return dummy == 6; ++ } else if ((op->addr.buswidth == 1) && (op->data.buswidth == 1)) { ++ if (op->cmd.opcode == 0x03) ++ return dummy == 0; ++ else if (op->cmd.opcode == 0x0b) ++ return dummy == 8; ++ } ++ return false; ++} ++ ++static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) ++{ ++ size_t len; ++ ++ if (!op->data.nbytes) ++ return 0; ++ ++ if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { ++ if ((op->data.dir == SPI_MEM_DATA_IN) && ++ mtk_nor_match_read(op)) { ++ if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) || ++ (op->data.nbytes < MTK_NOR_DMA_ALIGN)) ++ op->data.nbytes = 1; ++ else if (!((ulong)(op->data.buf.in) & ++ MTK_NOR_DMA_ALIGN_MASK)) ++ op->data.nbytes &= ~MTK_NOR_DMA_ALIGN_MASK; ++ else if (op->data.nbytes > MTK_NOR_BOUNCE_BUF_SIZE) ++ op->data.nbytes = MTK_NOR_BOUNCE_BUF_SIZE; ++ return 0; ++ } else if (op->data.dir == SPI_MEM_DATA_OUT) { ++ if (op->data.nbytes >= MTK_NOR_PP_SIZE) ++ op->data.nbytes = MTK_NOR_PP_SIZE; ++ else ++ op->data.nbytes = 1; ++ return 0; ++ } ++ } ++ ++ len = MTK_NOR_PRG_MAX_SIZE - sizeof(op->cmd.opcode) - op->addr.nbytes - ++ op->dummy.nbytes; ++ if (op->data.nbytes > len) ++ op->data.nbytes = len; ++ ++ return 0; ++} ++ ++static bool mtk_nor_supports_op(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ size_t len; ++ ++ if (op->cmd.buswidth != 1) ++ return false; ++ ++ if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { ++ if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) ++ return true; ++ else if (op->data.dir == SPI_MEM_DATA_OUT) ++ return (op->addr.buswidth == 1) && ++ (op->dummy.buswidth == 0) && ++ (op->data.buswidth == 1); ++ } ++ len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; ++ if ((len > MTK_NOR_PRG_MAX_SIZE) || ++ ((op->data.nbytes) && (len == MTK_NOR_PRG_MAX_SIZE))) ++ return false; ++ return true; ++} ++ ++static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op) ++{ ++ u32 reg = 0; ++ ++ if (op->addr.nbytes == 4) ++ reg |= MTK_NOR_4B_ADDR; ++ ++ if (op->data.buswidth == 4) { ++ reg |= MTK_NOR_QUAD_READ; ++ writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(4)); ++ if (op->addr.buswidth == 4) ++ reg |= MTK_NOR_QUAD_ADDR; ++ } else if (op->data.buswidth == 2) { ++ reg |= MTK_NOR_DUAL_READ; ++ writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(3)); ++ if (op->addr.buswidth == 2) ++ reg |= MTK_NOR_DUAL_ADDR; ++ } else { ++ if (op->cmd.opcode == 0x0b) ++ mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, MTK_NOR_FAST_READ, 0); ++ else ++ mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, 0, MTK_NOR_FAST_READ); ++ } ++ mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, reg, MTK_NOR_BUS_MODE_MASK); ++} ++ ++static int mtk_nor_read_dma(struct mtk_nor *sp, u32 from, unsigned int length, ++ u8 *buffer) ++{ ++ int ret = 0; ++ ulong delay; ++ u32 reg; ++ dma_addr_t dma_addr; ++ ++ dma_addr = dma_map_single(sp->dev, buffer, length, DMA_FROM_DEVICE); ++ if (dma_mapping_error(sp->dev, dma_addr)) { ++ dev_err(sp->dev, "failed to map dma buffer.\n"); ++ return -EINVAL; ++ } ++ ++ writel(from, sp->base + MTK_NOR_REG_DMA_FADR); ++ writel(dma_addr, sp->base + MTK_NOR_REG_DMA_DADR); ++ writel(dma_addr + length, sp->base + MTK_NOR_REG_DMA_END_DADR); ++ ++ if (sp->has_irq) { ++ reinit_completion(&sp->op_done); ++ mtk_nor_rmw(sp, MTK_NOR_REG_IRQ_EN, MTK_NOR_IRQ_DMA, 0); ++ } ++ ++ mtk_nor_rmw(sp, MTK_NOR_REG_DMA_CTL, MTK_NOR_DMA_START, 0); ++ ++ delay = CLK_TO_US(sp, (length + 5) * BITS_PER_BYTE); ++ ++ if (sp->has_irq) { ++ if (!wait_for_completion_timeout(&sp->op_done, ++ (delay + 1) * 100)) ++ ret = -ETIMEDOUT; ++ } else { ++ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_DMA_CTL, reg, ++ !(reg & MTK_NOR_DMA_START), delay / 3, ++ (delay + 1) * 100); ++ } ++ ++ dma_unmap_single(sp->dev, dma_addr, length, DMA_FROM_DEVICE); ++ if (ret < 0) ++ dev_err(sp->dev, "dma read timeout.\n"); ++ ++ return ret; ++} ++ ++static int mtk_nor_read_bounce(struct mtk_nor *sp, u32 from, ++ unsigned int length, u8 *buffer) ++{ ++ unsigned int rdlen; ++ int ret; ++ ++ if (length & MTK_NOR_DMA_ALIGN_MASK) ++ rdlen = (length + MTK_NOR_DMA_ALIGN) & ~MTK_NOR_DMA_ALIGN_MASK; ++ else ++ rdlen = length; ++ ++ ret = mtk_nor_read_dma(sp, from, rdlen, sp->buffer); ++ if (ret) ++ return ret; ++ ++ memcpy(buffer, sp->buffer, length); ++ return 0; ++} ++ ++static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op) ++{ ++ u8 *buf = op->data.buf.in; ++ int ret; ++ ++ ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_READ, 6 * BITS_PER_BYTE); ++ if (!ret) ++ buf[0] = readb(sp->base + MTK_NOR_REG_RDATA); ++ return ret; ++} ++ ++static int mtk_nor_write_buffer_enable(struct mtk_nor *sp) ++{ ++ int ret; ++ u32 val; ++ ++ if (sp->wbuf_en) ++ return 0; ++ ++ val = readl(sp->base + MTK_NOR_REG_CFG2); ++ writel(val | MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); ++ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, ++ val & MTK_NOR_WR_BUF_EN, 0, 10000); ++ if (!ret) ++ sp->wbuf_en = true; ++ return ret; ++} ++ ++static int mtk_nor_write_buffer_disable(struct mtk_nor *sp) ++{ ++ int ret; ++ u32 val; ++ ++ if (!sp->wbuf_en) ++ return 0; ++ val = readl(sp->base + MTK_NOR_REG_CFG2); ++ writel(val & ~MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); ++ ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, ++ !(val & MTK_NOR_WR_BUF_EN), 0, 10000); ++ if (!ret) ++ sp->wbuf_en = false; ++ return ret; ++} ++ ++static int mtk_nor_pp_buffered(struct mtk_nor *sp, const struct spi_mem_op *op) ++{ ++ const u8 *buf = op->data.buf.out; ++ u32 val; ++ int ret, i; ++ ++ ret = mtk_nor_write_buffer_enable(sp); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < op->data.nbytes; i += 4) { ++ val = buf[i + 3] << 24 | buf[i + 2] << 16 | buf[i + 1] << 8 | ++ buf[i]; ++ writel(val, sp->base + MTK_NOR_REG_PP_DATA); ++ } ++ return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, ++ (op->data.nbytes + 5) * BITS_PER_BYTE); ++} ++ ++static int mtk_nor_pp_unbuffered(struct mtk_nor *sp, ++ const struct spi_mem_op *op) ++{ ++ const u8 *buf = op->data.buf.out; ++ int ret; ++ ++ ret = mtk_nor_write_buffer_disable(sp); ++ if (ret < 0) ++ return ret; ++ writeb(buf[0], sp->base + MTK_NOR_REG_WDATA); ++ return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, 6 * BITS_PER_BYTE); ++} ++ ++int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) ++{ ++ struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->master); ++ int ret; ++ ++ if ((op->data.nbytes == 0) || ++ ((op->addr.nbytes != 3) && (op->addr.nbytes != 4))) ++ return -ENOTSUPP; ++ ++ if (op->data.dir == SPI_MEM_DATA_OUT) { ++ mtk_nor_set_addr(sp, op); ++ writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA0); ++ if (op->data.nbytes == MTK_NOR_PP_SIZE) ++ return mtk_nor_pp_buffered(sp, op); ++ return mtk_nor_pp_unbuffered(sp, op); ++ } ++ ++ if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) { ++ ret = mtk_nor_write_buffer_disable(sp); ++ if (ret < 0) ++ return ret; ++ mtk_nor_setup_bus(sp, op); ++ if (op->data.nbytes == 1) { ++ mtk_nor_set_addr(sp, op); ++ return mtk_nor_read_pio(sp, op); ++ } else if (((ulong)(op->data.buf.in) & ++ MTK_NOR_DMA_ALIGN_MASK)) { ++ return mtk_nor_read_bounce(sp, op->addr.val, ++ op->data.nbytes, ++ op->data.buf.in); ++ } else { ++ return mtk_nor_read_dma(sp, op->addr.val, ++ op->data.nbytes, ++ op->data.buf.in); ++ } ++ } ++ ++ return -ENOTSUPP; ++} ++ ++static int mtk_nor_setup(struct spi_device *spi) ++{ ++ struct mtk_nor *sp = spi_controller_get_devdata(spi->master); ++ ++ if (spi->max_speed_hz && (spi->max_speed_hz < sp->spi_freq)) { ++ dev_err(&spi->dev, "spi clock should be %u Hz.\n", ++ sp->spi_freq); ++ return -EINVAL; ++ } ++ spi->max_speed_hz = sp->spi_freq; ++ ++ return 0; ++} ++ ++static int mtk_nor_transfer_one_message(struct spi_controller *master, ++ struct spi_message *m) ++{ ++ struct mtk_nor *sp = spi_controller_get_devdata(master); ++ struct spi_transfer *t = NULL; ++ unsigned long trx_len = 0; ++ int stat = 0; ++ int reg_offset = MTK_NOR_REG_PRGDATA_MAX; ++ void __iomem *reg; ++ const u8 *txbuf; ++ u8 *rxbuf; ++ int i; ++ ++ list_for_each_entry(t, &m->transfers, transfer_list) { ++ txbuf = t->tx_buf; ++ for (i = 0; i < t->len; i++, reg_offset--) { ++ reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); ++ if (txbuf) ++ writeb(txbuf[i], reg); ++ else ++ writeb(0, reg); ++ } ++ trx_len += t->len; ++ } ++ ++ writel(trx_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); ++ ++ stat = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM, ++ trx_len * BITS_PER_BYTE); ++ if (stat < 0) ++ goto msg_done; ++ ++ reg_offset = trx_len - 1; ++ list_for_each_entry(t, &m->transfers, transfer_list) { ++ rxbuf = t->rx_buf; ++ for (i = 0; i < t->len; i++, reg_offset--) { ++ reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset); ++ if (rxbuf) ++ rxbuf[i] = readb(reg); ++ } ++ } ++ ++ m->actual_length = trx_len; ++msg_done: ++ m->status = stat; ++ spi_finalize_current_message(master); ++ ++ return 0; ++} ++ ++static void mtk_nor_disable_clk(struct mtk_nor *sp) ++{ ++ clk_disable_unprepare(sp->spi_clk); ++ clk_disable_unprepare(sp->ctlr_clk); ++} ++ ++static int mtk_nor_enable_clk(struct mtk_nor *sp) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(sp->spi_clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(sp->ctlr_clk); ++ if (ret) { ++ clk_disable_unprepare(sp->spi_clk); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mtk_nor_init(struct mtk_nor *sp) ++{ ++ int ret; ++ ++ ret = mtk_nor_enable_clk(sp); ++ if (ret) ++ return ret; ++ ++ sp->spi_freq = clk_get_rate(sp->spi_clk); ++ ++ writel(MTK_NOR_ENABLE_SF_CMD, sp->base + MTK_NOR_REG_WP); ++ mtk_nor_rmw(sp, MTK_NOR_REG_CFG2, MTK_NOR_WR_CUSTOM_OP_EN, 0); ++ mtk_nor_rmw(sp, MTK_NOR_REG_CFG3, ++ MTK_NOR_DISABLE_WREN | MTK_NOR_DISABLE_SR_POLL, 0); ++ ++ return ret; ++} ++ ++static irqreturn_t mtk_nor_irq_handler(int irq, void *data) ++{ ++ struct mtk_nor *sp = data; ++ u32 irq_status, irq_enabled; ++ ++ irq_status = readl(sp->base + MTK_NOR_REG_IRQ_STAT); ++ irq_enabled = readl(sp->base + MTK_NOR_REG_IRQ_EN); ++ // write status back to clear interrupt ++ writel(irq_status, sp->base + MTK_NOR_REG_IRQ_STAT); ++ ++ if (!(irq_status & irq_enabled)) ++ return IRQ_NONE; ++ ++ if (irq_status & MTK_NOR_IRQ_DMA) { ++ complete(&sp->op_done); ++ writel(0, sp->base + MTK_NOR_REG_IRQ_EN); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static size_t mtk_max_msg_size(struct spi_device *spi) ++{ ++ return MTK_NOR_PRG_MAX_SIZE; ++} ++ ++static const struct spi_controller_mem_ops mtk_nor_mem_ops = { ++ .adjust_op_size = mtk_nor_adjust_op_size, ++ .supports_op = mtk_nor_supports_op, ++ .exec_op = mtk_nor_exec_op ++}; ++ ++static const struct of_device_id mtk_nor_match[] = { ++ { .compatible = "mediatek,mt8173-nor" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mtk_nor_match); ++ ++static int mtk_nor_probe(struct platform_device *pdev) ++{ ++ struct spi_controller *ctlr; ++ struct mtk_nor *sp; ++ void __iomem *base; ++ u8 *buffer; ++ struct clk *spi_clk, *ctlr_clk; ++ int ret, irq; ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ spi_clk = devm_clk_get(&pdev->dev, "spi"); ++ if (IS_ERR(spi_clk)) ++ return PTR_ERR(spi_clk); ++ ++ ctlr_clk = devm_clk_get(&pdev->dev, "sf"); ++ if (IS_ERR(ctlr_clk)) ++ return PTR_ERR(ctlr_clk); ++ ++ buffer = devm_kmalloc(&pdev->dev, ++ MTK_NOR_BOUNCE_BUF_SIZE + MTK_NOR_DMA_ALIGN, ++ GFP_KERNEL); ++ if (!buffer) ++ return -ENOMEM; ++ ++ if ((ulong)buffer & MTK_NOR_DMA_ALIGN_MASK) ++ buffer = (u8 *)(((ulong)buffer + MTK_NOR_DMA_ALIGN) & ++ ~MTK_NOR_DMA_ALIGN_MASK); ++ ++ ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp)); ++ if (!ctlr) { ++ dev_err(&pdev->dev, "failed to allocate spi controller\n"); ++ return -ENOMEM; ++ } ++ ++ ctlr->bits_per_word_mask = SPI_BPW_MASK(8); ++ ctlr->dev.of_node = pdev->dev.of_node; ++ ctlr->max_message_size = mtk_max_msg_size; ++ ctlr->mem_ops = &mtk_nor_mem_ops; ++ ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; ++ ctlr->num_chipselect = 1; ++ ctlr->setup = mtk_nor_setup; ++ ctlr->transfer_one_message = mtk_nor_transfer_one_message; ++ ++ dev_set_drvdata(&pdev->dev, ctlr); ++ ++ sp = spi_controller_get_devdata(ctlr); ++ sp->base = base; ++ sp->buffer = buffer; ++ sp->has_irq = false; ++ sp->wbuf_en = false; ++ sp->ctlr = ctlr; ++ sp->dev = &pdev->dev; ++ sp->spi_clk = spi_clk; ++ sp->ctlr_clk = ctlr_clk; ++ ++ irq = platform_get_irq_optional(pdev, 0); ++ if (irq < 0) { ++ dev_warn(sp->dev, "IRQ not available."); ++ } else { ++ writel(MTK_NOR_IRQ_MASK, base + MTK_NOR_REG_IRQ_STAT); ++ writel(0, base + MTK_NOR_REG_IRQ_EN); ++ ret = devm_request_irq(sp->dev, irq, mtk_nor_irq_handler, 0, ++ pdev->name, sp); ++ if (ret < 0) { ++ dev_warn(sp->dev, "failed to request IRQ."); ++ } else { ++ init_completion(&sp->op_done); ++ sp->has_irq = true; ++ } ++ } ++ ++ ret = mtk_nor_init(sp); ++ if (ret < 0) { ++ kfree(ctlr); ++ return ret; ++ } ++ ++ dev_info(&pdev->dev, "spi frequency: %d Hz\n", sp->spi_freq); ++ ++ return devm_spi_register_controller(&pdev->dev, ctlr); ++} ++ ++static int mtk_nor_remove(struct platform_device *pdev) ++{ ++ struct spi_controller *ctlr; ++ struct mtk_nor *sp; ++ ++ ctlr = dev_get_drvdata(&pdev->dev); ++ sp = spi_controller_get_devdata(ctlr); ++ ++ mtk_nor_disable_clk(sp); ++ ++ return 0; ++} ++ ++static struct platform_driver mtk_nor_driver = { ++ .driver = { ++ .name = DRIVER_NAME, ++ .of_match_table = mtk_nor_match, ++ }, ++ .probe = mtk_nor_probe, ++ .remove = mtk_nor_remove, ++}; ++ ++module_platform_driver(mtk_nor_driver); ++ ++MODULE_DESCRIPTION("Mediatek SPI NOR controller driver"); ++MODULE_AUTHOR("Chuanhong Guo "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/root/target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch b/root/target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch new file mode 100755 index 00000000..6fae99c1 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0003-switch-add-mt7531.patch @@ -0,0 +1,19 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -329,6 +329,8 @@ config RTL8367B_PHY + + endif # RTL8366_SMI + ++source "drivers/net/phy/mtk/mt753x/Kconfig" ++ + comment "MII PHY device drivers" + + config SFP +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -109,3 +109,5 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o + obj-$(CONFIG_TERANETICS_PHY) += teranetics.o + obj-$(CONFIG_VITESSE_PHY) += vitesse.o + obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o ++obj-$(CONFIG_MT753X_GSW) += mtk/mt753x/ ++ diff --git a/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch b/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch new file mode 100755 index 00000000..6c1c2764 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch @@ -0,0 +1,51 @@ +From 0593f719ca873722c6ac66604f027a63663c9b64 Mon Sep 17 00:00:00 2001 +From: Alexey Loukianov +Date: Fri, 7 Jun 2019 12:33:45 +0300 +Subject: [PATCH 04/12] mediatek: fix packet corruption on bridged interface + + This fixes problem that was reported here: + http://forum.banana-pi.org/t/openwrt-18-06-malformed-ip-packets-at-bridged-interface/ + + Fix is to set both gmacs to use trgmii mode. + This fix is not technically correct as second gmac + does not support trgmii mode but current driver + implementation seems to handle it somehow and + it is the only way to have both gmacs enabled + and avoid corruption of the packets on brigded + lanX interfaces. + + Signed-off-by: Alexey Loukianov +--- + .../0067-dts-bpi-r2-fix-second-gmac.patch | 20 +++++++++++++++++++ + 1 file changed, 20 insertions(+) + create mode 100644 target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch + +diff --git a/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch b/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch +new file mode 100644 +index 0000000000..145c188972 +--- /dev/null ++++ b/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch +@@ -0,0 +1,20 @@ ++--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++@@ -141,7 +141,7 @@ ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++- phy-mode = "rgmii"; +++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++@@ -206,7 +206,7 @@ ++ reg = <5>; ++ label = "cpu"; ++ ethernet = <&gmac1>; ++- phy-mode = "rgmii"; +++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; +-- +2.23.0 + diff --git a/root/target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch b/root/target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch new file mode 100755 index 00000000..773a69f0 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0005-dts-mt7629-add-gsw.patch @@ -0,0 +1,67 @@ +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -18,6 +18,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8"; + }; + + gpio-keys { +@@ -36,6 +37,13 @@ + }; + }; + ++ gsw: gsw@0 { ++ compatible = "mediatek,mt753x"; ++ mediatek,ethsys = <ðsys>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ + memory@40000000 { + device_type = "memory"; + reg = <0x40000000 0x10000000>; +@@ -69,6 +77,7 @@ + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; ++ mtd-mac-address = <&factory 0x2a>; + phy-mode = "2500base-x"; + fixed-link { + speed = <2500>; +@@ -80,6 +89,7 @@ + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; ++ mtd-mac-address = <&factory 0x24>; + phy-mode = "gmii"; + phy-handle = <&phy0>; + }; +@@ -93,6 +103,26 @@ + }; + }; + }; ++ ++&gsw { ++ mediatek,mdio = <&mdio>; ++ mediatek,portmap = "llllw"; ++ mediatek,mdio_master_pinmux = <0>; ++ reset-gpios = <&pio 28 0>; ++ interrupt-parent = <&pio>; ++ interrupts = <6 IRQ_TYPE_LEVEL_HIGH>; ++ status = "okay"; ++ ++ port6: port@6 { ++ compatible = "mediatek,mt753x-port"; ++ reg = <6>; ++ phy-mode = "sgmii"; ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++ }; ++}; + + &i2c { + pinctrl-names = "default"; diff --git a/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch b/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch new file mode 100755 index 00000000..be378827 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch @@ -0,0 +1,10 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -19,6 +19,7 @@ + + chosen { + stdout-path = "serial2:115200n8"; ++ bootargs = "console=ttyS2,115200n8 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait vmalloc=496M"; + }; + + cpus { diff --git a/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch b/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch new file mode 100755 index 00000000..07a2eae2 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi64-console.patch @@ -0,0 +1,11 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +@@ -22,7 +22,7 @@ + + chosen { + stdout-path = "serial0:115200n8"; +- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; + }; + + cpus { diff --git a/root/target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch b/root/target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch new file mode 100755 index 00000000..5d0a19ed --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0010-dts-mt7629-rfb-fix-firmware-partition.patch @@ -0,0 +1,13 @@ +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -163,8 +163,9 @@ + }; + + partition@b0000 { +- label = "kernel"; ++ label = "firmware"; + reg = <0xb0000 0xb50000>; ++ compatible = "denx,fit"; + }; + }; + }; diff --git a/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch b/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch new file mode 100755 index 00000000..1c58130b --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch @@ -0,0 +1,39 @@ +From 934747eba782050ba87a29a3a59f805e36410685 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= +Date: Fri, 21 Jun 2019 10:04:05 +0200 +Subject: [PATCH] net: ethernet: mediatek: support net-labels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With this patch, device name can be set within dts file in the same way as dsa +port can. +Add: label = "wan"; to GMAC node. + +Signed-off-by: René van Dorst +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index c61069340f4f..87ced6269411 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2756,6 +2756,7 @@ static const struct net_device_ops mtk_netdev_ops = { + + static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + { ++ const char *name = of_get_property(np, "label", NULL); + const __be32 *_id = of_get_property(np, "reg", NULL); + struct phylink *phylink; + int phy_mode, id, err; +@@ -2846,6 +2847,9 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + eth->netdev[id]->irq = eth->irq[0]; + eth->netdev[id]->dev.of_node = np; + ++ if (name) ++ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ); ++ + return 0; + + free_netdev: diff --git a/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch b/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch new file mode 100755 index 00000000..bbb478e7 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch @@ -0,0 +1,249 @@ +--- a/drivers/rtc/rtc-mt6397.c 2020-03-05 23:43:52.000000000 +0800 ++++ b/drivers/rtc/rtc-mt6397.c 2020-03-18 00:54:20.445907453 +0800 +@@ -4,48 +4,18 @@ + * Author: Tianping.Fang + */ + +-#include +-#include ++#include ++#include ++#include + #include ++#include ++#include + #include + #include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define RTC_BBPU 0x0000 +-#define RTC_BBPU_CBUSY BIT(6) +- +-#define RTC_WRTGR 0x003c ++#include ++#include + +-#define RTC_IRQ_STA 0x0002 +-#define RTC_IRQ_STA_AL BIT(0) +-#define RTC_IRQ_STA_LP BIT(3) +- +-#define RTC_IRQ_EN 0x0004 +-#define RTC_IRQ_EN_AL BIT(0) +-#define RTC_IRQ_EN_ONESHOT BIT(2) +-#define RTC_IRQ_EN_LP BIT(3) +-#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) +- +-#define RTC_AL_MASK 0x0008 +-#define RTC_AL_MASK_DOW BIT(4) +- +-#define RTC_TC_SEC 0x000a +-/* Min, Hour, Dom... register offset to RTC_TC_SEC */ +-#define RTC_OFFSET_SEC 0 +-#define RTC_OFFSET_MIN 1 +-#define RTC_OFFSET_HOUR 2 +-#define RTC_OFFSET_DOM 3 +-#define RTC_OFFSET_DOW 4 +-#define RTC_OFFSET_MTH 5 +-#define RTC_OFFSET_YEAR 6 +-#define RTC_OFFSET_COUNT 7 +- +-#define RTC_AL_SEC 0x0018 ++#include + + #define RTC_AL_SEC_MASK 0x003f + #define RTC_AL_MIN_MASK 0x003f +@@ -55,26 +25,8 @@ + #define RTC_AL_MTH_MASK 0x000f + #define RTC_AL_YEA_MASK 0x007f + +-#define RTC_PDN2 0x002e +-#define RTC_PDN2_PWRON_ALARM BIT(4) +- +-#define RTC_MIN_YEAR 1968 +-#define RTC_BASE_YEAR 1900 +-#define RTC_NUM_YEARS 128 +-#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) +- +-struct mt6397_rtc { +- struct device *dev; +- struct rtc_device *rtc_dev; +- struct mutex lock; +- struct regmap *regmap; +- int irq; +- u32 addr_base; +-}; +- + static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) + { +- unsigned long timeout = jiffies + HZ; + int ret; + u32 data; + +@@ -82,19 +34,13 @@ static int mtk_rtc_write_trigger(struct + if (ret < 0) + return ret; + +- while (1) { +- ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU, +- &data); +- if (ret < 0) +- break; +- if (!(data & RTC_BBPU_CBUSY)) +- break; +- if (time_after(jiffies, timeout)) { +- ret = -ETIMEDOUT; +- break; +- } +- cpu_relax(); +- } ++ ret = regmap_read_poll_timeout(rtc->regmap, ++ rtc->addr_base + RTC_BBPU, data, ++ !(data & RTC_BBPU_CBUSY), ++ MTK_RTC_POLL_DELAY_US, ++ MTK_RTC_POLL_TIMEOUT); ++ if (ret < 0) ++ dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret); + + return ret; + } +@@ -338,19 +284,19 @@ static int mtk_rtc_probe(struct platform + return rtc->irq; + + rtc->regmap = mt6397_chip->regmap; +- rtc->dev = &pdev->dev; + mutex_init(&rtc->lock); + + platform_set_drvdata(pdev, rtc); + +- rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev); ++ rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + +- ret = request_threaded_irq(rtc->irq, NULL, +- mtk_rtc_irq_handler_thread, +- IRQF_ONESHOT | IRQF_TRIGGER_HIGH, +- "mt6397-rtc", rtc); ++ ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, ++ mtk_rtc_irq_handler_thread, ++ IRQF_ONESHOT | IRQF_TRIGGER_HIGH, ++ "mt6397-rtc", rtc); ++ + if (ret) { + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + rtc->irq, ret); +@@ -372,15 +318,6 @@ out_free_irq: + return ret; + } + +-static int mtk_rtc_remove(struct platform_device *pdev) +-{ +- struct mt6397_rtc *rtc = platform_get_drvdata(pdev); +- +- free_irq(rtc->irq, rtc); +- +- return 0; +-} +- + #ifdef CONFIG_PM_SLEEP + static int mt6397_rtc_suspend(struct device *dev) + { +@@ -407,6 +344,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, + mt6397_rtc_resume); + + static const struct of_device_id mt6397_rtc_of_match[] = { ++ { .compatible = "mediatek,mt6323-rtc", }, + { .compatible = "mediatek,mt6397-rtc", }, + { } + }; +@@ -419,7 +357,6 @@ static struct platform_driver mtk_rtc_dr + .pm = &mt6397_pm_ops, + }, + .probe = mtk_rtc_probe, +- .remove = mtk_rtc_remove, + }; + + module_platform_driver(mtk_rtc_driver); +diff --git a/include/linux/mfd/mt6397/rtc.h b/include/linux/mfd/mt6397/rtc.h +new file mode 100644 +index 000000000000..f84b9163c0ee +--- /dev/null ++++ b/include/linux/mfd/mt6397/rtc.h +@@ -0,0 +1,71 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2014-2019 MediaTek Inc. ++ * ++ * Author: Tianping.Fang ++ * Sean Wang ++ */ ++ ++#ifndef _LINUX_MFD_MT6397_RTC_H_ ++#define _LINUX_MFD_MT6397_RTC_H_ ++ ++#include ++#include ++#include ++#include ++ ++#define RTC_BBPU 0x0000 ++#define RTC_BBPU_CBUSY BIT(6) ++#define RTC_BBPU_KEY (0x43 << 8) ++ ++#define RTC_WRTGR 0x003c ++ ++#define RTC_IRQ_STA 0x0002 ++#define RTC_IRQ_STA_AL BIT(0) ++#define RTC_IRQ_STA_LP BIT(3) ++ ++#define RTC_IRQ_EN 0x0004 ++#define RTC_IRQ_EN_AL BIT(0) ++#define RTC_IRQ_EN_ONESHOT BIT(2) ++#define RTC_IRQ_EN_LP BIT(3) ++#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) ++ ++#define RTC_AL_MASK 0x0008 ++#define RTC_AL_MASK_DOW BIT(4) ++ ++#define RTC_TC_SEC 0x000a ++/* Min, Hour, Dom... register offset to RTC_TC_SEC */ ++#define RTC_OFFSET_SEC 0 ++#define RTC_OFFSET_MIN 1 ++#define RTC_OFFSET_HOUR 2 ++#define RTC_OFFSET_DOM 3 ++#define RTC_OFFSET_DOW 4 ++#define RTC_OFFSET_MTH 5 ++#define RTC_OFFSET_YEAR 6 ++#define RTC_OFFSET_COUNT 7 ++ ++#define RTC_AL_SEC 0x0018 ++ ++#define RTC_PDN2 0x002e ++#define RTC_PDN2_PWRON_ALARM BIT(4) ++ ++#define RTC_MIN_YEAR 1968 ++#define RTC_BASE_YEAR 1900 ++#define RTC_NUM_YEARS 128 ++#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) ++ ++#define MTK_RTC_POLL_DELAY_US 10 ++#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ)) ++ ++struct mt6397_rtc { ++ struct device *dev; ++ struct rtc_device *rtc_dev; ++ ++ /* Protect register access from multiple tasks */ ++ struct mutex lock; ++ struct regmap *regmap; ++ int irq; ++ u32 addr_base; ++}; ++ ++#endif /* _LINUX_MFD_MT6397_RTC_H_ */ + diff --git a/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch b/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch new file mode 100755 index 00000000..b8552824 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch @@ -0,0 +1,160 @@ +From 559614ab0ae2c85596218226f095be36c12cf0fa Mon Sep 17 00:00:00 2001 +From: Josef Friedl +Date: Wed, 3 Jul 2019 12:24:52 +0200 +Subject: [PATCH] power: reset: add driver for mt6323 poweroff + +add poweroff driver for mt6323 and make Makefile and Kconfig-Entries + +Suggested-by: Frank Wunderlich +Signed-off-by: Josef Friedl +Signed-off-by: Frank Wunderlich +Acked-by: Sebastian Reichel +--- +changes since v6: none +changes since v5: split out mfd/mt6397/core.h +changes since v4: none +changes since v3: none +changes since v2: none (=v2 part 5) +--- + drivers/power/reset/Kconfig | 10 +++ + drivers/power/reset/Makefile | 1 + + drivers/power/reset/mt6323-poweroff.c | 97 +++++++++++++++++++++++++++ + 3 files changed, 108 insertions(+) + create mode 100644 drivers/power/reset/mt6323-poweroff.c + +diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig +index a564237278ff..c721939767eb 100644 +--- a/drivers/power/reset/Kconfig ++++ b/drivers/power/reset/Kconfig +@@ -140,6 +140,16 @@ config POWER_RESET_LTC2952 + This driver supports an external powerdown trigger and board power + down via the LTC2952. Bindings are made in the device tree. + ++config POWER_RESET_MT6323 ++ bool "MediaTek MT6323 power-off driver" ++ depends on MFD_MT6397 ++ help ++ The power-off driver is responsible for externally shutdown down ++ the power of a remote MediaTek SoC MT6323 is connected to through ++ controlling a tiny circuit BBPU inside MT6323 RTC. ++ ++ Say Y if you have a board where MT6323 could be found. ++ + config POWER_RESET_QNAP + bool "QNAP power-off driver" + depends on OF_GPIO && PLAT_ORION +diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile +index 85da3198e4e0..da37f8b851dc 100644 +--- a/drivers/power/reset/Makefile ++++ b/drivers/power/reset/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o + obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o + obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o + obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o ++obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o + obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o + obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o + obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o +diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c +new file mode 100644 +index 000000000000..1caf43d9e46d +--- /dev/null ++++ b/drivers/power/reset/mt6323-poweroff.c +@@ -0,0 +1,97 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Power off through MediaTek PMIC ++ * ++ * Copyright (C) 2018 MediaTek Inc. ++ * ++ * Author: Sean Wang ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct mt6323_pwrc { ++ struct device *dev; ++ struct regmap *regmap; ++ u32 base; ++}; ++ ++static struct mt6323_pwrc *mt_pwrc; ++ ++static void mt6323_do_pwroff(void) ++{ ++ struct mt6323_pwrc *pwrc = mt_pwrc; ++ unsigned int val; ++ int ret; ++ ++ regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY); ++ regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1); ++ ++ ret = regmap_read_poll_timeout(pwrc->regmap, ++ pwrc->base + RTC_BBPU, val, ++ !(val & RTC_BBPU_CBUSY), ++ MTK_RTC_POLL_DELAY_US, ++ MTK_RTC_POLL_TIMEOUT); ++ if (ret) ++ dev_err(pwrc->dev, "failed to write BBPU: %d\n", ret); ++ ++ /* Wait some time until system down, otherwise, notice with a warn */ ++ mdelay(1000); ++ ++ WARN_ONCE(1, "Unable to power off system\n"); ++} ++ ++static int mt6323_pwrc_probe(struct platform_device *pdev) ++{ ++ struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); ++ struct mt6323_pwrc *pwrc; ++ struct resource *res; ++ ++ pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL); ++ if (!pwrc) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ pwrc->base = res->start; ++ pwrc->regmap = mt6397_chip->regmap; ++ pwrc->dev = &pdev->dev; ++ mt_pwrc = pwrc; ++ ++ pm_power_off = &mt6323_do_pwroff; ++ ++ return 0; ++} ++ ++static int mt6323_pwrc_remove(struct platform_device *pdev) ++{ ++ if (pm_power_off == &mt6323_do_pwroff) ++ pm_power_off = NULL; ++ ++ return 0; ++} ++ ++static const struct of_device_id mt6323_pwrc_dt_match[] = { ++ { .compatible = "mediatek,mt6323-pwrc" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match); ++ ++static struct platform_driver mt6323_pwrc_driver = { ++ .probe = mt6323_pwrc_probe, ++ .remove = mt6323_pwrc_remove, ++ .driver = { ++ .name = "mt6323-pwrc", ++ .of_match_table = mt6323_pwrc_dt_match, ++ }, ++}; ++ ++module_platform_driver(mt6323_pwrc_driver); ++ ++MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC"); ++MODULE_AUTHOR("Sean Wang "); ++MODULE_LICENSE("GPL v2"); diff --git a/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch b/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch new file mode 100755 index 00000000..41a4305c --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch @@ -0,0 +1,57 @@ +From c3db4c1163cc20ab0a456086a15c00acb022a67d Mon Sep 17 00:00:00 2001 +From: Josef Friedl +Date: Thu, 20 Dec 2018 18:27:17 +0100 +Subject: [PATCH] arm: dts: mt6323: add keys, power-controller, rtc and codec + +support poweroff and power-related keys on bpi-r2 + +Suggested-by: Frank Wunderlich +Signed-off-by: Josef Friedl +Signed-off-by: Frank Wunderlich +--- +changes since v6: none +changes since v5: none +changes since v4: none +changes since v3: none +changes since v2: none (=v2 part 7) +--- + arch/arm/boot/dts/mt6323.dtsi | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/arch/arm/boot/dts/mt6323.dtsi b/arch/arm/boot/dts/mt6323.dtsi +index ba397407c1dd..7fda40ab5fe8 100644 +--- a/arch/arm/boot/dts/mt6323.dtsi ++++ b/arch/arm/boot/dts/mt6323.dtsi +@@ -238,5 +238,32 @@ + regulator-enable-ramp-delay = <216>; + }; + }; ++ ++ mt6323keys: mt6323keys { ++ compatible = "mediatek,mt6323-keys"; ++ mediatek,long-press-mode = <1>; ++ power-off-time-sec = <0>; ++ ++ power { ++ linux,keycodes = <116>; ++ wakeup-source; ++ }; ++ ++ home { ++ linux,keycodes = <114>; ++ }; ++ }; ++ ++ codec: mt6397codec { ++ compatible = "mediatek,mt6397-codec"; ++ }; ++ ++ power-controller { ++ compatible = "mediatek,mt6323-pwrc"; ++ }; ++ ++ rtc { ++ compatible = "mediatek,mt6323-rtc"; ++ }; + }; + }; diff --git a/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch b/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch new file mode 100755 index 00000000..36c38786 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch @@ -0,0 +1,500 @@ +From ae7a8d61a108bb58af8c3ecb16d8e95aad0b1975 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Wed, 5 Sep 2018 22:09:27 +0800 +Subject: [PATCH] arm: dts: mt7623: add display subsystem related device nodes + +Add display subsystem related device nodes for MT7623. + +Cc: CK Hu +Signed-off-by: chunhui dai +Signed-off-by: Bibby Hsieh +Signed-off-by: Ryder Lee + +additional fixes: + +[hdmi,dts] fixed dts-warnings +author: Bibby Hsieh + +[dtsi] fix dpi0-node +author: Ryder Lee + +Signed-off-by: Frank Wunderlich +Tested-by: Frank Wunderlich +--- + arch/arm/boot/dts/mt7623.dtsi | 177 ++++++++++++++++++ + arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 85 +++++++++ + arch/arm/boot/dts/mt7623n-rfb-emmc.dts | 85 +++++++++ + 3 files changed, 347 insertions(+) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 59e69f3dffa2..f1880ff04193 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -23,6 +23,11 @@ + #address-cells = <2>; + #size-cells = <2>; + ++ aliases { ++ rdma0 = &rdma0; ++ rdma1 = &rdma1; ++ }; ++ + cpu_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-shared; +@@ -320,6 +325,25 @@ + clock-names = "spi", "wrap"; + }; + ++ mipi_tx0: mipi-dphy@10010000 { ++ compatible = "mediatek,mt7623-mipi-tx", ++ "mediatek,mt2701-mipi-tx"; ++ reg = <0 0x10010000 0 0x90>; ++ clocks = <&clk26m>; ++ clock-output-names = "mipi_tx0_pll"; ++ #clock-cells = <0>; ++ #phy-cells = <0>; ++ }; ++ ++ cec: cec@10012000 { ++ compatible = "mediatek,mt7623-cec", ++ "mediatek,mt8173-cec"; ++ reg = <0 0x10012000 0 0xbc>; ++ interrupts = ; ++ clocks = <&infracfg CLK_INFRA_CEC>; ++ status = "disabled"; ++ }; ++ + cir: cir@10013000 { + compatible = "mediatek,mt7623-cir"; + reg = <0 0x10013000 0 0x1000>; +@@ -368,6 +392,18 @@ + #clock-cells = <1>; + }; + ++ hdmi_phy: phy@10209100 { ++ compatible = "mediatek,mt7623-hdmi-phy", ++ "mediatek,mt2701-hdmi-phy"; ++ reg = <0 0x10209100 0 0x24>; ++ clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; ++ clock-names = "pll_ref"; ++ clock-output-names = "hdmitx_dig_cts"; ++ #clock-cells = <0>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + rng: rng@1020f000 { + compatible = "mediatek,mt7623-rng"; + reg = <0 0x1020f000 0 0x1000>; +@@ -567,6 +603,16 @@ + status = "disabled"; + }; + ++ hdmiddc0: i2c@11013000 { ++ compatible = "mediatek,mt7623-hdmi-ddc", ++ "mediatek,mt8173-hdmi-ddc"; ++ interrupts = ; ++ reg = <0 0x11013000 0 0x1C>; ++ clocks = <&pericfg CLK_PERI_I2C3>; ++ clock-names = "ddc-i2c"; ++ status = "disabled"; ++ }; ++ + nor_flash: spi@11014000 { + compatible = "mediatek,mt7623-nor", + "mediatek,mt8173-nor"; +@@ -741,6 +787,84 @@ + #clock-cells = <1>; + }; + ++ display_components: dispsys@14000000 { ++ compatible = "mediatek,mt7623-mmsys", ++ "mediatek,mt2701-mmsys"; ++ reg = <0 0x14000000 0 0x1000>; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; ++ }; ++ ++ ovl@14007000 { ++ compatible = "mediatek,mt7623-disp-ovl", ++ "mediatek,mt2701-disp-ovl"; ++ reg = <0 0x14007000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_OVL>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_OVL_0>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ rdma0: rdma@14008000 { ++ compatible = "mediatek,mt7623-disp-rdma", ++ "mediatek,mt2701-disp-rdma"; ++ reg = <0 0x14008000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_RDMA>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ wdma@14009000 { ++ compatible = "mediatek,mt7623-disp-wdma", ++ "mediatek,mt2701-disp-wdma"; ++ reg = <0 0x14009000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_WDMA>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_WDMA>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ bls: pwm@1400a000 { ++ compatible = "mediatek,mt7623-disp-pwm", ++ "mediatek,mt2701-disp-pwm"; ++ reg = <0 0x1400a000 0 0x1000>; ++ #pwm-cells = <2>; ++ clocks = <&mmsys CLK_MM_MDP_BLS_26M>, ++ <&mmsys CLK_MM_DISP_BLS>; ++ clock-names = "main", "mm"; ++ status = "disabled"; ++ }; ++ ++ color@1400b000 { ++ compatible = "mediatek,mt7623-disp-color", ++ "mediatek,mt2701-disp-color"; ++ reg = <0 0x1400b000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_COLOR>; ++ }; ++ ++ dsi: dsi@1400c000 { ++ compatible = "mediatek,mt7623-dsi", ++ "mediatek,mt2701-dsi"; ++ reg = <0 0x1400c000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DSI_ENGINE>, ++ <&mmsys CLK_MM_DSI_DIG>, ++ <&mipi_tx0>; ++ clock-names = "engine", "digital", "hs"; ++ phys = <&mipi_tx0>; ++ phy-names = "dphy"; ++ status = "disabled"; ++ }; ++ ++ mutex: mutex@1400e000 { ++ compatible = "mediatek,mt7623-disp-mutex", ++ "mediatek,mt2701-disp-mutex"; ++ reg = <0 0x1400e000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_MUTEX_32K>; ++ }; ++ + larb0: larb@14010000 { + compatible = "mediatek,mt7623-smi-larb", + "mediatek,mt2701-smi-larb"; +@@ -753,6 +877,44 @@ + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; + }; + ++ rdma1: rdma@14012000 { ++ compatible = "mediatek,mt7623-disp-rdma", ++ "mediatek,mt2701-disp-rdma"; ++ reg = <0 0x14012000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DISP_RDMA1>; ++ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA1>; ++ mediatek,larb = <&larb0>; ++ }; ++ ++ dpi0: dpi@14014000 { ++ compatible = "mediatek,mt7623-dpi", ++ "mediatek,mt2701-dpi"; ++ reg = <0 0x14014000 0 0x1000>; ++ interrupts = ; ++ clocks = <&mmsys CLK_MM_DPI1_DIGL>, ++ <&mmsys CLK_MM_DPI1_ENGINE>, ++ <&apmixedsys CLK_APMIXED_TVDPLL>; ++ clock-names = "pixel", "engine", "pll"; ++ status = "disabled"; ++ }; ++ ++ hdmi0: hdmi@14015000 { ++ compatible = "mediatek,mt7623-hdmi", ++ "mediatek,mt8173-hdmi"; ++ reg = <0 0x14015000 0 0x400>; ++ clocks = <&mmsys CLK_MM_HDMI_PIXEL>, ++ <&mmsys CLK_MM_HDMI_PLL>, ++ <&mmsys CLK_MM_HDMI_AUDIO>, ++ <&mmsys CLK_MM_HDMI_SPDIF>; ++ clock-names = "pixel", "pll", "bclk", "spdif"; ++ phys = <&hdmi_phy>; ++ phy-names = "hdmi"; ++ mediatek,syscon-hdmi = <&mmsys 0x900>; ++ cec = <&cec>; ++ status = "disabled"; ++ }; ++ + imgsys: syscon@15000000 { + compatible = "mediatek,mt7623-imgsys", + "mediatek,mt2701-imgsys", +@@ -1077,6 +1239,21 @@ + }; + }; + ++ hdmi_pins_a: hdmi-default { ++ pins-hdmi { ++ pinmux = ; ++ input-enable; ++ bias-pull-down; ++ }; ++ }; ++ ++ hdmi_ddc_pins_a: hdmi_ddc-default { ++ pins-hdmi-ddc { ++ pinmux = , ++ ; ++ }; ++ }; ++ + i2c0_pins_a: i2c0-default { + pins-i2c0 { + pinmux = , +diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +index 2b760f90f38c..7a1763472018 100644 +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -21,6 +21,19 @@ + stdout-path = "serial2:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ label = "hdmi"; ++ type = "d"; ++ ddc-i2c-bus = <&hdmiddc0>; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi0_out>; ++ }; ++ }; ++ }; ++ + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; +@@ -114,10 +127,24 @@ + }; + }; + ++&bls { ++ status = "okay"; ++ ++ port { ++ bls_out: endpoint { ++ remote-endpoint = <&dpi0_in>; ++ }; ++ }; ++}; ++ + &btif { + status = "okay"; + }; + ++&cec { ++ status = "okay"; ++}; ++ + &cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; +@@ -128,6 +155,28 @@ + status = "okay"; + }; + ++&dpi0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ dpi0_out: endpoint { ++ remote-endpoint = <&hdmi0_in>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dpi0_in: endpoint { ++ remote-endpoint = <&bls_out>; ++ }; ++ }; ++ }; ++}; ++ + ð { + status = "okay"; + +@@ -199,6 +248,42 @@ + }; + }; + ++&hdmi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_pins_a>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ hdmi0_in: endpoint { ++ remote-endpoint = <&dpi0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ hdmi0_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++ }; ++ }; ++}; ++ ++&hdmiddc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_ddc_pins_a>; ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ mediatek,ibias = <0xa>; ++ mediatek,ibias_up = <0x1c>; ++ status = "okay"; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; +diff --git a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +index b7606130ade9..3e5911d8d6bc 100644 +--- a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts ++++ b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +@@ -24,6 +24,19 @@ + stdout-path = "serial2:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ label = "hdmi"; ++ type = "d"; ++ ddc-i2c-bus = <&hdmiddc0>; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi0_out>; ++ }; ++ }; ++ }; ++ + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; +@@ -106,10 +119,24 @@ + }; + }; + ++&bls { ++ status = "okay"; ++ ++ port { ++ bls_out: endpoint { ++ remote-endpoint = <&dpi0_in>; ++ }; ++ }; ++}; ++ + &btif { + status = "okay"; + }; + ++&cec { ++ status = "okay"; ++}; ++ + &cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; +@@ -120,6 +147,28 @@ + status = "okay"; + }; + ++&dpi0 { ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ dpi0_out: endpoint { ++ remote-endpoint = <&hdmi0_in>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dpi0_in: endpoint { ++ remote-endpoint = <&bls_out>; ++ }; ++ }; ++ }; ++}; ++ + ð { + status = "okay"; + +@@ -202,6 +251,42 @@ + }; + }; + ++&hdmi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_pins_a>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ hdmi0_in: endpoint { ++ remote-endpoint = <&dpi0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ hdmi0_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++ }; ++ }; ++}; ++ ++&hdmiddc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_ddc_pins_a>; ++ status = "okay"; ++}; ++ ++&hdmi_phy { ++ mediatek,ibias = <0xa>; ++ mediatek,ibias_up = <0x1c>; ++ status = "okay"; ++}; ++ + &i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; diff --git a/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch b/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch new file mode 100755 index 00000000..c49690c5 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch @@ -0,0 +1,77 @@ +From 6468d187f12604f38f0a3acde430fdc5c5390771 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Tue, 23 Jul 2019 11:32:50 +0800 +Subject: [PATCH] arm: dts: mt7623: add Mali-450 device nodes + +Add nodes for Mali-450 and iommu larb3. + +Signed-off-by: Sean Wang +Signed-off-by: Ryder Lee +--- + arch/arm/boot/dts/mt7623.dtsi | 39 ++++++++++++++++++++++++++++++++++- + 1 file changed, 38 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index 8d0807fd9460..f7905561b30e 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -3,6 +3,7 @@ + * Copyright (c) 2017-2018 MediaTek Inc. + * Author: John Crispin + * Sean Wang ++ * Ryder Lee + * + */ + +@@ -371,7 +372,7 @@ + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; +- mediatek,larbs = <&larb0 &larb1 &larb2>; ++ mediatek,larbs = <&larb0 &larb1 &larb2 &larb3>; + #iommu-cells = <1>; + }; + +@@ -794,6 +795,42 @@ + #reset-cells = <1>; + }; + ++ larb3: larb@13010000 { ++ compatible = "mediatek,mt7623-smi-larb", ++ "mediatek,mt2701-smi-larb"; ++ reg = <0 0x13010000 0 0x1000>; ++ mediatek,smi = <&smi_common>; ++ mediatek,larb-id = <3>; ++ clocks = <&clk26m>, <&clk26m>; ++ clock-names = "apb", "smi"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; ++ }; ++ ++ mali: gpu@13040000 { ++ compatible = "mediatek,mt7623-mali", "arm,mali-450"; ++ reg = <0 0x13040000 0 0x30000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = "gp", "gpmmu", "pp0", "ppmmu0", "pp1", ++ "ppmmu1", "pp2", "ppmmu2", "pp3", "ppmmu3", ++ "pp"; ++ clocks = <&topckgen CLK_TOP_MMPLL>, ++ <&g3dsys CLK_G3DSYS_CORE>; ++ clock-names = "bus", "core"; ++ power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; ++ mediatek,larb = <&larb3>; ++ resets = <&g3dsys MT2701_G3DSYS_CORE_RST>; ++ }; ++ + mmsys: syscon@14000000 { + compatible = "mediatek,mt7623-mmsys", + "mediatek,mt2701-mmsys", diff --git a/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch b/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch new file mode 100755 index 00000000..fe4b742c --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch @@ -0,0 +1,68 @@ +From d87e1a23e51158f9c2923f6213a42d5e942a4091 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Thu, 23 Jan 2020 07:16:30 +0100 +Subject: [PATCH] lima: power on/off via register (function) + +--- + drivers/gpu/drm/lima/lima_device.c | 31 ++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c +index d86b8d81a483..7d5d45e176f2 100644 +--- a/drivers/gpu/drm/lima/lima_device.c ++++ b/drivers/gpu/drm/lima/lima_device.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include "lima_device.h" + #include "lima_gp.h" +@@ -287,11 +288,33 @@ static void lima_fini_pp_pipe(struct lima_device *dev) + lima_sched_pipe_fini(pipe); + } + ++void mtk_set_power(bool on) ++{ ++ if (on) { ++ void __iomem *wakeup_register; ++ wakeup_register = ioremap(0x10003014 , 0x04); ++ writel(0x00000001,wakeup_register); // this may be wrong, may need bitbang 0th bit to 1 ++ iounmap(wakeup_register); ++ }else { ++ void __iomem *powerdown_register; ++ powerdown_register = ioremap(0x1000300C , 0x04); // powerdown register ++ writel(0x00000001,powerdown_register); // this may be wrong, may need bitbang 0th bit to 1 ++ iounmap(powerdown_register); ++ } ++} ++ + int lima_device_init(struct lima_device *ldev) + { + int err, i; + struct resource *res; + ++ #ifdef CONFIG_MTK_COMBO_CHIP_CONSYS_7623 ++ mtk_set_power(true); ++ pm_runtime_enable(ldev->dev); ++ pm_runtime_set_active(ldev->dev); ++ pm_runtime_get_sync(ldev->dev); ++ #endif ++ + dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); + + err = lima_clk_init(ldev); +@@ -385,4 +408,12 @@ void lima_device_fini(struct lima_device *ldev) + lima_regulator_fini(ldev); + + lima_clk_fini(ldev); ++ ++ #ifdef CONFIG_MTK_COMBO_CHIP_CONSYS_7623 ++ pm_runtime_set_suspended(ldev->dev); ++ pm_runtime_put_noidle(ldev->dev); ++ pm_runtime_disable(ldev->dev); ++ ++ mtk_set_power(false); ++ #endif + } diff --git a/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch b/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch new file mode 100755 index 00000000..ff149dce --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch @@ -0,0 +1,84 @@ +From 452b508468a46ef0fe7357fab6b000c52fd047d3 Mon Sep 17 00:00:00 2001 +From: Stu Hsieh +Date: Fri, 16 Nov 2018 16:33:00 +0100 +Subject: [PATCH] drm: Add get_possible_crtc API for dpi, dsi + +Test: build pass and run ok + +Signed-off-by: Stu Hsieh +--- + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 40 +++++++++++++++++++++ + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 ++ + 2 files changed, 42 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +index efa85973e46b..29796e78b26a 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +@@ -237,6 +237,22 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { + [DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL }, + }; + ++static bool mtk_drm_find_comp_in_ddp(struct mtk_ddp_comp ddp_comp, ++ const enum mtk_ddp_comp_id *path, ++ unsigned int path_len) ++{ ++ unsigned int i; ++ ++ if (path == NULL) ++ return false; ++ ++ for (i = 0U; i < path_len; i++) ++ if (ddp_comp.id == path[i]) ++ return true; ++ ++ return false; ++} ++ + int mtk_ddp_comp_get_id(struct device_node *node, + enum mtk_ddp_comp_type comp_type) + { +@@ -252,6 +268,30 @@ int mtk_ddp_comp_get_id(struct device_node *node, + return -EINVAL; + } + ++unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, ++ struct mtk_ddp_comp ddp_comp) ++{ ++ struct mtk_drm_private *private = drm->dev_private; ++ unsigned int ret; ++ ++ if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->main_path, ++ private->data->main_len) == true) { ++ ret = BIT(0); ++ } else if (mtk_drm_find_comp_in_ddp(ddp_comp, ++ private->data->ext_path, ++ private->data->ext_len) == true) { ++ ret = BIT(1); ++ } else if (mtk_drm_find_comp_in_ddp(ddp_comp, ++ private->data->third_path, ++ private->data->third_len) == true) { ++ ret = BIT(2); ++ } else { ++ DRM_INFO("Failed to find comp in ddp table\n"); ++ ret = 0; ++ } ++ return ret; ++} ++ + int mtk_ddp_comp_init(struct device *dev, struct device_node *node, + struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, + const struct mtk_ddp_comp_funcs *funcs) +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +index 0ad287f427cc..97be111c3e52 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +@@ -160,6 +160,8 @@ static inline void mtk_ddp_gamma_set(struct mtk_ddp_comp *comp, + + int mtk_ddp_comp_get_id(struct device_node *node, + enum mtk_ddp_comp_type comp_type); ++unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, ++ struct mtk_ddp_comp ddp_comp); + int mtk_ddp_comp_init(struct device *dev, struct device_node *comp_node, + struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, + const struct mtk_ddp_comp_funcs *funcs); diff --git a/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch b/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch new file mode 100755 index 00000000..c92e18cc --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch @@ -0,0 +1,45 @@ +From f4ca44932ccf088f225062aafef04d2bd629b2c4 Mon Sep 17 00:00:00 2001 +From: Jitao Shi +Date: Fri, 3 May 2019 17:16:19 +0200 +Subject: [PATCH] drm/mediatek: dpi/dsi: change the getting possible_crtc way + +[Detail] +dpi/dsi get the possible_crtc by +mtk_drm_find_possible_crtc_by_comp(*drm_dev, ddp_comp) + +Test: build pass and boot to logo + +Signed-off-by: Jitao Shi +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 3 ++- + drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index be6d95c5ff25..00d31b5aa09f 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -604,7 +604,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) + drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); + + /* Currently DPI0 is fixed to be driven by OVL1 */ +- dpi->encoder.possible_crtcs = BIT(1); ++ dpi->encoder.possible_crtcs = ++ mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->ddp_comp); + + ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL); + if (ret) { +diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c +index 224afb666881..2c2d3643f3e8 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dsi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c +@@ -817,7 +817,8 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi) + * Currently display data paths are statically assigned to a crtc each. + * crtc 0 is OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 + */ +- dsi->encoder.possible_crtcs = 1; ++ dsi->encoder.possible_crtcs = ++ mtk_drm_find_possible_crtc_by_comp(drm, dsi->ddp_comp); + + /* If there's a bridge, attach to it and let it create the connector */ + if (dsi->bridge) { diff --git a/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch b/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch new file mode 100755 index 00000000..98bba9dc --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch @@ -0,0 +1,21 @@ +From 34dd2a86c9e3b3ad1a3a00add409edda2b2ed776 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Tue, 1 Oct 2019 11:21:03 +0200 +Subject: [PATCH] drm: fix implicit declaration of function 'DRM_INFO' + +--- + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +index 29796e78b26a..e65d83267563 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #include "mtk_drm_drv.h" + #include "mtk_drm_plane.h" diff --git a/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch b/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch new file mode 100755 index 00000000..adc35c7d --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch @@ -0,0 +1,146 @@ +From 6e3f7375acdcf714d1fcbae1238cd39cc9391560 Mon Sep 17 00:00:00 2001 +From: Bibby Hsieh +Date: Fri, 21 Sep 2018 11:28:22 +0800 +Subject: [PATCH] drm/mediatek: config component output by device node port + +We can select output component by decive node port. +Main path default output component is DSI. +External path default output component is DPI. + +Signed-off-by: Bibby Hsieh + +added small fixes for warnings + +Signed-off-by: Frank Wunderlich +Tested-by: Frank Wunderlich +--- + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 46 ++++++++++++++++++++++---- + drivers/gpu/drm/mediatek/mtk_drm_drv.h | 4 +-- + 2 files changed, 42 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +index 352b81a7a670..33511c77b800 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +@@ -21,6 +21,13 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + #include "mtk_drm_crtc.h" + #include "mtk_drm_ddp.h" +@@ -121,7 +128,7 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = { + .atomic_commit = mtk_atomic_commit, + }; + +-static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_RDMA0, + DDP_COMPONENT_COLOR0, +@@ -129,12 +136,12 @@ static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { + DDP_COMPONENT_DSI0, + }; + +-static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { + DDP_COMPONENT_RDMA1, + DDP_COMPONENT_DPI0, + }; + +-static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_AAL0, +@@ -144,7 +151,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { + DDP_COMPONENT_PWM0, + }; + +-static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { + DDP_COMPONENT_OVL1, + DDP_COMPONENT_COLOR1, + DDP_COMPONENT_AAL1, +@@ -160,7 +167,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = { + DDP_COMPONENT_PWM2, + }; + +-static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { ++static enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { + DDP_COMPONENT_OVL0, + DDP_COMPONENT_COLOR0, + DDP_COMPONENT_AAL0, +@@ -171,7 +178,7 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { + DDP_COMPONENT_PWM0, + }; + +-static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { ++static enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { + DDP_COMPONENT_OVL1, + DDP_COMPONENT_COLOR1, + DDP_COMPONENT_GAMMA, +@@ -510,6 +517,7 @@ static int mtk_drm_probe(struct platform_device *pdev) + + /* Iterate over sibling DISP function blocks */ + for_each_child_of_node(dev->of_node->parent, node) { ++ struct device_node *port, *ep, *remote; + const struct of_device_id *of_id; + enum mtk_ddp_comp_type comp_type; + int comp_id; +@@ -572,6 +580,32 @@ static int mtk_drm_probe(struct platform_device *pdev) + + private->ddp_comp[comp_id] = comp; + } ++ ++ if (comp_type != MTK_DSI && comp_type != MTK_DPI) { ++ port = of_graph_get_port_by_id(node, 0); ++ if (!port) ++ continue; ++ ep = of_get_child_by_name(port, "endpoint"); ++ of_node_put(port); ++ if (!ep) ++ continue; ++ remote = of_graph_get_remote_port_parent(ep); ++ of_node_put(ep); ++ if (!remote) ++ continue; ++ of_id = of_match_node(mtk_ddp_comp_dt_ids, remote); ++ if (!of_id) ++ continue; ++ comp_type = (enum mtk_ddp_comp_type)of_id->data; ++ for (i = 0; i < private->data->main_len - 1; i++) ++ if (private->data->main_path[i] == comp_id) ++ private->data->main_path[i + 1] = ++ mtk_ddp_comp_get_id(node, comp_type); ++ for (i = 0; i < private->data->ext_len - 1; i++) ++ if (private->data->ext_path[i] == comp_id) ++ private->data->ext_path[i + 1] = ++ mtk_ddp_comp_get_id(node, comp_type); ++ } + } + + if (!private->mutex_node) { +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +index e03fea12ff59..5fb723415ff6 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +@@ -21,9 +21,9 @@ struct drm_property; + struct regmap; + + struct mtk_mmsys_driver_data { +- const enum mtk_ddp_comp_id *main_path; ++ enum mtk_ddp_comp_id *main_path; + unsigned int main_len; +- const enum mtk_ddp_comp_id *ext_path; ++ enum mtk_ddp_comp_id *ext_path; + unsigned int ext_len; + const enum mtk_ddp_comp_id *third_path; + unsigned int third_len; diff --git a/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch b/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch new file mode 100755 index 00000000..247853f3 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch @@ -0,0 +1,55 @@ +From ba9c6527b05d294bdda7910db224e327f1460166 Mon Sep 17 00:00:00 2001 +From: chunhui dai +Date: Wed, 31 Oct 2018 16:59:34 +0800 +Subject: [PATCH] drm/mediatek: fix boot up for 720 and 480 but 1080 + +- 1080 plg in/out with ng/ok +- support other resolutions like 1280x1024 + +Signed-off-by: chunhui dai +Signed-off-by: Frank Wunderlich +Tested-by: Frank Wunderlich +--- + drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 3 +++ + drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 + + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 1 + + 3 files changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +index 5223498502c4..edadb7a700f1 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +@@ -184,6 +184,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) + return PTR_ERR(phy_provider); + } + ++ if (hdmi_phy->conf->pll_default_off) ++ hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy); ++ + return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, + hdmi_phy->pll); + } +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +index 2d8b3182470d..f472fdeb63dc 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +@@ -22,6 +22,7 @@ struct mtk_hdmi_phy; + struct mtk_hdmi_phy_conf { + bool tz_disabled; + unsigned long flags; ++ bool pll_default_off; + const struct clk_ops *hdmi_phy_clk_ops; + void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); + void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); +diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +index d3cc4022e988..6fbedacfc1e8 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c ++++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +@@ -239,6 +239,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) + struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { + .tz_disabled = true, + .flags = CLK_SET_RATE_GATE, ++ .pll_default_off = true, + .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, + .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, + .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, diff --git a/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch b/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch new file mode 100755 index 00000000..cc897705 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch @@ -0,0 +1,56 @@ +From aa97a44297179ab6ba1aa8f59e781541a320066b Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 31 Jan 2020 17:28:04 +0100 +Subject: [PATCH] thermal: mediatek: add sensors-support + +--- + drivers/thermal/mtk_thermal.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c +index d1b066383c45..8cf3a69bfa46 100644 +--- a/drivers/thermal/mtk_thermal.c ++++ b/drivers/thermal/mtk_thermal.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include "thermal_hwmon.h" ++ + /* AUXADC Registers */ + #define AUXADC_CON1_SET_V 0x008 + #define AUXADC_CON1_CLR_V 0x00c +@@ -990,6 +992,13 @@ static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt, + writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1); + } + ++static void mtk_thermal_hwmon_action(void *data) ++{ ++ struct thermal_zone_device *zone = data; ++ ++ thermal_remove_hwmon_sysfs(zone); ++} ++ + static int mtk_thermal_probe(struct platform_device *pdev) + { + int ret, i, ctrl_id; +@@ -1094,6 +1103,19 @@ static int mtk_thermal_probe(struct platform_device *pdev) + goto err_disable_clk_peri_therm; + } + ++ tzdev->tzp->no_hwmon = false; ++ ret = thermal_add_hwmon_sysfs(tzdev); ++ if (ret) ++ dev_err(&pdev->dev,"error in thermal_add_hwmon_sysfs"); ++ //goto err_disable_clk_peri_therm; ++ ++ ret = devm_add_action(&pdev->dev, mtk_thermal_hwmon_action, tzdev); ++ if (ret) { ++ dev_err(&pdev->dev,"error in devm_add_action"); ++ mtk_thermal_hwmon_action(tzdev); ++ //goto err_disable_clk_peri_therm; ++ } ++ + return 0; + + err_disable_clk_peri_therm: diff --git a/root/target/linux/mediatek/patches-5.4/0191-thermal.patch b/root/target/linux/mediatek/patches-5.4/0191-thermal.patch new file mode 100755 index 00000000..01ead975 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0191-thermal.patch @@ -0,0 +1,35 @@ +From 9847677bda4920bbba15499f28009ce095f02c99 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +Date: Fri, 31 Jan 2020 18:49:56 +0100 +Subject: [PATCH] thermal: mediatek: execute hwmon-code only if hwmon_thermal + is set + +--- + drivers/thermal/mtk_thermal.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c +index 8cf3a69bfa46..3a646b88f587 100644 +--- a/drivers/thermal/mtk_thermal.c ++++ b/drivers/thermal/mtk_thermal.c +@@ -1103,18 +1103,18 @@ static int mtk_thermal_probe(struct platform_device *pdev) + goto err_disable_clk_peri_therm; + } + ++#ifdef CONFIG_THERMAL_HWMON + tzdev->tzp->no_hwmon = false; + ret = thermal_add_hwmon_sysfs(tzdev); + if (ret) + dev_err(&pdev->dev,"error in thermal_add_hwmon_sysfs"); +- //goto err_disable_clk_peri_therm; + + ret = devm_add_action(&pdev->dev, mtk_thermal_hwmon_action, tzdev); + if (ret) { + dev_err(&pdev->dev,"error in devm_add_action"); + mtk_thermal_hwmon_action(tzdev); +- //goto err_disable_clk_peri_therm; + } ++#endif + + return 0; + diff --git a/root/target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch b/root/target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch new file mode 100755 index 00000000..f2647e8f --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0226-phy-phy-mtk-tphy-Add-hifsys-support.patch @@ -0,0 +1,66 @@ +From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001 +From: Kristian Evensen +Date: Mon, 30 Apr 2018 14:38:01 +0200 +Subject: [PATCH] phy: phy-mtk-tphy: Add hifsys-support + +--- + drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/phy/mediatek/phy-mtk-tphy.c ++++ b/drivers/phy/mediatek/phy-mtk-tphy.c +@@ -15,6 +15,8 @@ + #include + #include + #include ++#include ++#include + + /* version V1 sub-banks offset base address */ + /* banks shared by multiple phys */ +@@ -263,6 +265,9 @@ + #define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0) + #define RG_CDR_BIRLTD0_GEN3_VAL(x) (0x1f & (x)) + ++#define HIF_SYSCFG1 0x14 ++#define HIF_SYSCFG1_PHY2_MASK (0x3 << 20) ++ + enum mtk_phy_version { + MTK_PHY_V1 = 1, + MTK_PHY_V2, +@@ -310,6 +315,7 @@ struct mtk_tphy { + struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */ + const struct mtk_phy_pdata *pdata; + struct mtk_phy_instance **phys; ++ struct regmap *hif; + int nphys; + int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */ + int src_coef; /* coefficient for slew rate calibrate */ +@@ -629,6 +635,10 @@ static void pcie_phy_instance_init(struc + if (tphy->pdata->version != MTK_PHY_V1) + return; + ++ if (tphy->hif) ++ regmap_update_bits(tphy->hif, HIF_SYSCFG1, ++ HIF_SYSCFG1_PHY2_MASK, 0); ++ + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0); + tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H); + tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2); +@@ -1114,6 +1124,16 @@ static int mtk_tphy_probe(struct platfor + &tphy->src_ref_clk); + device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef); + ++ if (of_find_property(np, "mediatek,phy-switch", NULL)) { ++ tphy->hif = syscon_regmap_lookup_by_phandle(np, ++ "mediatek,phy-switch"); ++ if (IS_ERR(tphy->hif)) { ++ dev_err(&pdev->dev, ++ "missing \"mediatek,phy-switch\" phandle\n"); ++ return PTR_ERR(tphy->hif); ++ } ++ } ++ + port = 0; + for_each_child_of_node(np, child_np) { + struct mtk_phy_instance *instance; diff --git a/root/target/linux/mediatek/patches-5.4/0227-arm-dts-Add-Unielec-U7623-DTS.patch b/root/target/linux/mediatek/patches-5.4/0227-arm-dts-Add-Unielec-U7623-DTS.patch new file mode 100755 index 00000000..3cb1dab6 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0227-arm-dts-Add-Unielec-U7623-DTS.patch @@ -0,0 +1,387 @@ +From 004eb24e939b5b31f828333f37fb5cb2a877d6f2 Mon Sep 17 00:00:00 2001 +From: Kristian Evensen +Date: Sun, 17 Jun 2018 14:41:47 +0200 +Subject: [PATCH] arm: dts: Add Unielec U7623 DTS + +--- + arch/arm/boot/dts/Makefile | 1 + + .../dts/mt7623a-unielec-u7623-02-emmc-512m.dts | 18 + + .../boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi | 366 +++++++++++++++++++++ + 3 files changed, 385 insertions(+) + create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512m.dts + create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1272,6 +1272,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt7623a-rfb-nand.dtb \ + mt7623n-rfb-emmc.dtb \ + mt7623n-bananapi-bpi-r2.dtb \ ++ mt7623a-unielec-u7623-02-emmc-512m.dtb \ + mt7629-rfb.dtb \ + mt8127-moose.dtb \ + mt8135-evbp1.dtb +--- /dev/null ++++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512m.dts +@@ -0,0 +1,18 @@ ++/* ++ * Copyright 2018 Kristian Evensen ++ * ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ */ ++ ++/dts-v1/; ++#include "mt7623a-unielec-u7623-02-emmc.dtsi" ++ ++/ { ++ model = "UniElec U7623-02 eMMC (512M RAM)"; ++ compatible = "unielec,u7623-02-emmc-512m", "unielec,u7623-02-emmc", "mediatek,mt7623"; ++ ++ memory@80000000 { ++ device_type = "memory"; ++ reg = <0 0x80000000 0 0x20000000>; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi +@@ -0,0 +1,340 @@ ++/* ++ * Copyright 2018 Kristian Evensen ++ * ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ */ ++ ++#include ++#include "mt7623.dtsi" ++#include "mt6323.dtsi" ++ ++/ { ++ compatible = "unielec,u7623-02-emmc", "mediatek,mt7623"; ++ ++ aliases { ++ serial2 = &uart2; ++ }; ++ ++ chosen { ++ bootargs = "root=/dev/mmcblk0p2 rootfstype=squashfs,f2fs console=ttyS0,115200 blkdevparts=mmcblk0:3M@6M(recovery),256M@9M(root)"; ++ stdout-path = "serial2:115200n8"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ ++ cpu@2 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ ++ cpu@3 { ++ proc-supply = <&mt6323_vproc_reg>; ++ }; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_5v: regulator-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&key_pins_a>; ++ ++ factory { ++ label = "factory"; ++ linux,code = ; ++ gpios = <&pio 256 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_pins_unielec>; ++ ++ led3 { ++ label = "u7623-01:green:led3"; ++ gpios = <&pio 14 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led4 { ++ label = "u7623-01:green:led4"; ++ gpios = <&pio 15 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&crypto { ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ mdio: mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ mt7530: switch@0 { ++ compatible = "mediatek,mt7530"; ++ }; ++ }; ++}; ++ ++&mt7530 { ++ compatible = "mediatek,mt7530"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ pinctrl-names = "default"; ++ mediatek,mcm; ++ resets = <ðsys 2>; ++ reset-names = "mcm"; ++ core-supply = <&mt6323_vpa_reg>; ++ io-supply = <&mt6323_vemc3v3_reg>; ++ ++ dsa,mii-bus = <&mdio>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ ++ port@0 { ++ reg = <0>; ++ label = "lan0"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ label = "lan1"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ label = "lan2"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "lan3"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ port@4 { ++ reg = <4>; ++ label = "wan"; ++ cpu = <&cpu_port0>; ++ }; ++ ++ cpu_port0: port@6 { ++ reg = <6>; ++ label = "cpu"; ++ ethernet = <&gmac0>; ++ phy-mode = "trgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ }; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default", "state_uhs"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ pinctrl-1 = <&mmc0_pins_uhs>; ++ status = "okay"; ++ bus-width = <8>; ++ max-frequency = <50000000>; ++ cap-mmc-highspeed; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_1p8v>; ++ non-removable; ++}; ++ ++&pio { ++ key_pins_a: keys-alt { ++ pins-keys { ++ pinmux = , ++ ; ++ input-enable; ++ }; ++ }; ++ ++ led_pins_unielec: leds-unielec { ++ pins-leds { ++ pinmux = , ++ ; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ pins_cmd_dat { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ pins_clk { ++ pinmux = ; ++ bias-pull-down; ++ }; ++ ++ pins_rst { ++ pinmux = ; ++ bias-pull-up; ++ }; ++ }; ++ ++ mmc0_pins_uhs: mmc0 { ++ pins_cmd_dat { ++ pinmux = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ pins_clk { ++ pinmux = ; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ pins_rst { ++ pinmux = ; ++ bias-pull-up; ++ }; ++ }; ++ ++ pcie_default: pcie_pin_default { ++ pins_cmd_dat { ++ pinmux = , ++ ; ++ bias-disable; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins_a>; ++ status = "okay"; ++}; ++ ++&pwrap { ++ mt6323 { ++ mt6323led: led { ++ compatible = "mediatek,mt6323-led"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ led@0 { ++ reg = <0>; ++ label = "led0"; ++ }; ++ }; ++ }; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins_b>; ++ status = "okay"; ++}; ++ ++&usb1 { ++ vusb33-supply = <®_3p3v>; ++ vbus-supply = <®_3p3v>; ++ status = "okay"; ++}; ++ ++&u3phy1 { ++ status = "okay"; ++}; ++ ++&u3phy2 { ++ status = "okay"; ++ mediatek,phy-switch = <&hifsys>; ++}; ++ ++&pcie { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_default>; ++ status = "okay"; ++ ++ pcie@1,0 { ++ status = "okay"; ++ }; ++ ++ pcie@2,0 { ++ status = "okay"; ++ }; ++}; ++ ++&pcie1_phy { ++ status = "okay"; ++}; ++ diff --git a/root/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch b/root/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch new file mode 100755 index 00000000..d9ab339f --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch @@ -0,0 +1,139 @@ +From a2479dc254ebe31c84fbcfda73f35e2321576494 Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Tue, 19 Mar 2019 13:57:38 +0800 +Subject: [PATCH 1/6] mtd: mtk ecc: move mtk ecc header file to include/mtd + +Change-Id: I8dc1d30e21b40d68ef5efd9587012f82970156a5 +Signed-off-by: Xiangsheng Hou +--- + drivers/mtd/nand/raw/mtk_ecc.c | 3 +-- + drivers/mtd/nand/raw/mtk_nand.c | 2 +- + {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h | 0 + 3 files changed, 2 insertions(+), 3 deletions(-) + rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%) + +--- a/drivers/mtd/nand/raw/mtk_ecc.c ++++ b/drivers/mtd/nand/raw/mtk_ecc.c +@@ -15,8 +15,7 @@ + #include + #include + #include +- +-#include "mtk_ecc.h" ++#include + + #define ECC_IDLE_MASK BIT(0) + #define ECC_IRQ_EN BIT(0) +--- a/drivers/mtd/nand/raw/mtk_nand.c ++++ b/drivers/mtd/nand/raw/mtk_nand.c +@@ -17,7 +17,7 @@ + #include + #include + #include +-#include "mtk_ecc.h" ++#include + + /* NAND controller register definition */ + #define NFI_CNFG (0x00) +--- /dev/null ++++ b/include/linux/mtd/mtk_ecc.h +@@ -0,0 +1,49 @@ ++/* ++ * MTK SDG1 ECC controller ++ * ++ * Copyright (c) 2016 Mediatek ++ * Authors: Xiaolei Li ++ * Jorge Ramirez-Ortiz ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__ ++#define __DRIVERS_MTD_NAND_MTK_ECC_H__ ++ ++#include ++ ++enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1}; ++enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE}; ++ ++struct device_node; ++struct mtk_ecc; ++ ++struct mtk_ecc_stats { ++ u32 corrected; ++ u32 bitflips; ++ u32 failed; ++}; ++ ++struct mtk_ecc_config { ++ enum mtk_ecc_operation op; ++ enum mtk_ecc_mode mode; ++ dma_addr_t addr; ++ u32 strength; ++ u32 sectors; ++ u32 len; ++}; ++ ++int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32); ++void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int); ++int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation); ++int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *); ++void mtk_ecc_disable(struct mtk_ecc *); ++void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p); ++unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc); ++ ++struct mtk_ecc *of_mtk_ecc_get(struct device_node *); ++void mtk_ecc_release(struct mtk_ecc *); ++ ++#endif +--- a/drivers/mtd/nand/raw/mtk_ecc.h ++++ /dev/null +@@ -1,47 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +-/* +- * MTK SDG1 ECC controller +- * +- * Copyright (c) 2016 Mediatek +- * Authors: Xiaolei Li +- * Jorge Ramirez-Ortiz +- */ +- +-#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__ +-#define __DRIVERS_MTD_NAND_MTK_ECC_H__ +- +-#include +- +-enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1}; +-enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE}; +- +-struct device_node; +-struct mtk_ecc; +- +-struct mtk_ecc_stats { +- u32 corrected; +- u32 bitflips; +- u32 failed; +-}; +- +-struct mtk_ecc_config { +- enum mtk_ecc_operation op; +- enum mtk_ecc_mode mode; +- dma_addr_t addr; +- u32 strength; +- u32 sectors; +- u32 len; +-}; +- +-int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32); +-void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int); +-int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation); +-int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *); +-void mtk_ecc_disable(struct mtk_ecc *); +-void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p); +-unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc); +- +-struct mtk_ecc *of_mtk_ecc_get(struct device_node *); +-void mtk_ecc_release(struct mtk_ecc *); +- +-#endif diff --git a/root/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch b/root/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch new file mode 100755 index 00000000..5c18ea0f --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch @@ -0,0 +1,31 @@ +From b341f120cfc9ca1dfd48364b7f36ac2c1fbdea43 Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Wed, 3 Apr 2019 16:30:01 +0800 +Subject: [PATCH 3/6] mtd: spinand: disable on-die ECC + +Change-Id: I9745adaed5295202fabbe8ab8947885c57a5b847 +Signed-off-by: Xiangsheng Hou +--- + drivers/mtd/nand/spi/core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -491,7 +491,7 @@ static int spinand_mtd_read(struct mtd_i + int ret = 0; + + if (ops->mode != MTD_OPS_RAW && spinand->eccinfo.ooblayout) +- enable_ecc = true; ++ enable_ecc = false; + + mutex_lock(&spinand->lock); + +@@ -539,7 +539,7 @@ static int spinand_mtd_write(struct mtd_ + int ret = 0; + + if (ops->mode != MTD_OPS_RAW && mtd->ooblayout) +- enable_ecc = true; ++ enable_ecc = false; + + mutex_lock(&spinand->lock); + diff --git a/root/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch b/root/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch new file mode 100755 index 00000000..b3672e5b --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch @@ -0,0 +1,1246 @@ +From 1ecb38eabd90efe93957d0a822a167560c39308a Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Wed, 20 Mar 2019 16:19:51 +0800 +Subject: [PATCH 6/6] spi: spi-mem: MediaTek: Add SPI NAND Flash interface + driver for MediaTek MT7622 + +Change-Id: I3e78406bb9b46b0049d3988a5c71c7069e4f809c +Signed-off-by: Xiangsheng Hou +--- + drivers/spi/Kconfig | 9 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-mtk-snfi.c | 1183 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 1193 insertions(+) + create mode 100644 drivers/spi/spi-mtk-snfi.c + +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -60,6 +60,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mp + obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o + obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o + obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o ++obj-$(CONFIG_SPI_MTK_SNFI) += spi-mtk-snfi.o + obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o + obj-$(CONFIG_SPI_MTK_NOR) += spi-mtk-nor.o + obj-$(CONFIG_SPI_MXIC) += spi-mxic.o +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -427,6 +427,15 @@ config SPI_MT65XX + say Y or M here.If you are not sure, say N. + SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. + ++config SPI_MTK_SNFI ++ tristate "MediaTek SPI NAND interface" ++ select MTD_SPI_NAND ++ help ++ This selects the SPI NAND FLASH interface(SNFI), ++ which could be found on MediaTek Soc. ++ Say Y or M here.If you are not sure, say N. ++ Note Parallel Nand and SPI NAND is alternative on MediaTek SoCs. ++ + config SPI_MT7621 + tristate "MediaTek MT7621 SPI Controller" + depends on RALINK || COMPILE_TEST +--- /dev/null ++++ b/drivers/spi/spi-mtk-snfi.c +@@ -0,0 +1,1200 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Driver for MediaTek SPI Nand interface ++ * ++ * Copyright (C) 2018 MediaTek Inc. ++ * Authors: Xiangsheng Hou ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* NAND controller register definition */ ++/* NFI control */ ++#define NFI_CNFG 0x00 ++#define CNFG_DMA BIT(0) ++#define CNFG_READ_EN BIT(1) ++#define CNFG_DMA_BURST_EN BIT(2) ++#define CNFG_BYTE_RW BIT(6) ++#define CNFG_HW_ECC_EN BIT(8) ++#define CNFG_AUTO_FMT_EN BIT(9) ++#define CNFG_OP_PROGRAM (3UL << 12) ++#define CNFG_OP_CUST (6UL << 12) ++#define NFI_PAGEFMT 0x04 ++#define PAGEFMT_512 0 ++#define PAGEFMT_2K 1 ++#define PAGEFMT_4K 2 ++#define PAGEFMT_FDM_SHIFT 8 ++#define PAGEFMT_FDM_ECC_SHIFT 12 ++#define NFI_CON 0x08 ++#define CON_FIFO_FLUSH BIT(0) ++#define CON_NFI_RST BIT(1) ++#define CON_BRD BIT(8) ++#define CON_BWR BIT(9) ++#define CON_SEC_SHIFT 12 ++#define NFI_INTR_EN 0x10 ++#define INTR_AHB_DONE_EN BIT(6) ++#define NFI_INTR_STA 0x14 ++#define NFI_CMD 0x20 ++#define NFI_STA 0x60 ++#define STA_EMP_PAGE BIT(12) ++#define NAND_FSM_MASK (0x1f << 24) ++#define NFI_FSM_MASK (0xf << 16) ++#define NFI_ADDRCNTR 0x70 ++#define CNTR_MASK GENMASK(16, 12) ++#define ADDRCNTR_SEC_SHIFT 12 ++#define ADDRCNTR_SEC(val) \ ++ (((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT) ++#define NFI_STRADDR 0x80 ++#define NFI_BYTELEN 0x84 ++#define NFI_CSEL 0x90 ++#define NFI_FDML(x) (0xa0 + (x) * sizeof(u32) * 2) ++#define NFI_FDMM(x) (0xa4 + (x) * sizeof(u32) * 2) ++#define NFI_MASTER_STA 0x224 ++#define MASTER_STA_MASK 0x0fff ++/* NFI_SPI control */ ++#define SNFI_MAC_OUTL 0x504 ++#define SNFI_MAC_INL 0x508 ++#define SNFI_RD_CTL2 0x510 ++#define RD_CMD_MASK 0x00ff ++#define RD_DUMMY_SHIFT 8 ++#define SNFI_RD_CTL3 0x514 ++#define RD_ADDR_MASK 0xffff ++#define SNFI_MISC_CTL 0x538 ++#define RD_MODE_X2 BIT(16) ++#define RD_MODE_X4 (2UL << 16) ++#define RD_QDUAL_IO (4UL << 16) ++#define RD_MODE_MASK (7UL << 16) ++#define RD_CUSTOM_EN BIT(6) ++#define WR_CUSTOM_EN BIT(7) ++#define WR_X4_EN BIT(20) ++#define SW_RST BIT(28) ++#define SNFI_MISC_CTL2 0x53c ++#define WR_LEN_SHIFT 16 ++#define SNFI_PG_CTL1 0x524 ++#define WR_LOAD_CMD_SHIFT 8 ++#define SNFI_PG_CTL2 0x528 ++#define WR_LOAD_ADDR_MASK 0xffff ++#define SNFI_MAC_CTL 0x500 ++#define MAC_WIP BIT(0) ++#define MAC_WIP_READY BIT(1) ++#define MAC_TRIG BIT(2) ++#define MAC_EN BIT(3) ++#define MAC_SIO_SEL BIT(4) ++#define SNFI_STA_CTL1 0x550 ++#define SPI_STATE_IDLE 0xf ++#define SNFI_CNFG 0x55c ++#define SNFI_MODE_EN BIT(0) ++#define SNFI_GPRAM_DATA 0x800 ++#define SNFI_GPRAM_MAX_LEN 16 ++ ++/* Dummy command trigger NFI to spi mode */ ++#define NAND_CMD_DUMMYREAD 0x00 ++#define NAND_CMD_DUMMYPROG 0x80 ++ ++#define MTK_TIMEOUT 500000 ++#define MTK_RESET_TIMEOUT 1000000 ++#define MTK_SNFC_MIN_SPARE 16 ++#define KB(x) ((x) * 1024UL) ++ ++/* ++ * supported spare size of each IP. ++ * order should be the same with the spare size bitfiled defination of ++ * register NFI_PAGEFMT. ++ */ ++static const u8 spare_size_mt7622[] = { ++ 16, 26, 27, 28 ++}; ++ ++struct mtk_snfi_caps { ++ const u8 *spare_size; ++ u8 num_spare_size; ++ u32 nand_sec_size; ++ u8 nand_fdm_size; ++ u8 nand_fdm_ecc_size; ++ u8 ecc_parity_bits; ++ u8 pageformat_spare_shift; ++ u8 bad_mark_swap; ++}; ++ ++struct mtk_snfi_bad_mark_ctl { ++ void (*bm_swap)(struct spi_mem *mem, u8 *buf, int raw); ++ u32 sec; ++ u32 pos; ++}; ++ ++struct mtk_snfi_nand_chip { ++ struct mtk_snfi_bad_mark_ctl bad_mark; ++ u32 spare_per_sector; ++}; ++ ++struct mtk_snfi_clk { ++ struct clk *nfi_clk; ++ struct clk *spi_clk; ++}; ++ ++struct mtk_snfi { ++ const struct mtk_snfi_caps *caps; ++ struct mtk_snfi_nand_chip snfi_nand; ++ struct mtk_snfi_clk clk; ++ struct mtk_ecc_config ecc_cfg; ++ struct mtk_ecc *ecc; ++ struct completion done; ++ struct device *dev; ++ ++ void __iomem *regs; ++ ++ u8 *buffer; ++}; ++ ++static inline u8 *oob_ptr(struct spi_mem *mem, int i) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u8 *poi; ++ ++ /* map the sector's FDM data to free oob: ++ * the beginning of the oob area stores the FDM data of bad mark ++ */ ++ ++ if (i < snfi_nand->bad_mark.sec) ++ poi = spinand->oobbuf + (i + 1) * snfi->caps->nand_fdm_size; ++ else if (i == snfi_nand->bad_mark.sec) ++ poi = spinand->oobbuf; ++ else ++ poi = spinand->oobbuf + i * snfi->caps->nand_fdm_size; ++ ++ return poi; ++} ++ ++static inline int mtk_data_len(struct spi_mem *mem) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ ++ return snfi->caps->nand_sec_size + snfi_nand->spare_per_sector; ++} ++ ++static inline u8 *mtk_oob_ptr(struct spi_mem *mem, ++ const u8 *p, int i) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ ++ return (u8 *)p + i * mtk_data_len(mem) + snfi->caps->nand_sec_size; ++} ++ ++static void mtk_snfi_bad_mark_swap(struct spi_mem *mem, ++ u8 *buf, int raw) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 bad_pos = snfi_nand->bad_mark.pos; ++ ++ if (raw) ++ bad_pos += snfi_nand->bad_mark.sec * mtk_data_len(mem); ++ else ++ bad_pos += snfi_nand->bad_mark.sec * snfi->caps->nand_sec_size; ++ ++ swap(spinand->oobbuf[0], buf[bad_pos]); ++} ++ ++static void mtk_snfi_set_bad_mark_ctl(struct mtk_snfi_bad_mark_ctl *bm_ctl, ++ struct spi_mem *mem) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ ++ bm_ctl->bm_swap = mtk_snfi_bad_mark_swap; ++ bm_ctl->sec = mtd->writesize / mtk_data_len(mem); ++ bm_ctl->pos = mtd->writesize % mtk_data_len(mem); ++} ++ ++static void mtk_snfi_mac_enable(struct mtk_snfi *snfi) ++{ ++ u32 mac; ++ ++ mac = readl(snfi->regs + SNFI_MAC_CTL); ++ mac &= ~MAC_SIO_SEL; ++ mac |= MAC_EN; ++ ++ writel(mac, snfi->regs + SNFI_MAC_CTL); ++} ++ ++static int mtk_snfi_mac_trigger(struct mtk_snfi *snfi) ++{ ++ u32 mac, reg; ++ int ret = 0; ++ ++ mac = readl(snfi->regs + SNFI_MAC_CTL); ++ mac |= MAC_TRIG; ++ writel(mac, snfi->regs + SNFI_MAC_CTL); ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg, ++ reg & MAC_WIP_READY, 10, ++ MTK_TIMEOUT); ++ if (ret < 0) { ++ dev_err(snfi->dev, "polling wip ready for read timeout\n"); ++ return -EIO; ++ } ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg, ++ !(reg & MAC_WIP), 10, ++ MTK_TIMEOUT); ++ if (ret < 0) { ++ dev_err(snfi->dev, "polling flash update timeout\n"); ++ return -EIO; ++ } ++ ++ return ret; ++} ++ ++static void mtk_snfi_mac_leave(struct mtk_snfi *snfi) ++{ ++ u32 mac; ++ ++ mac = readl(snfi->regs + SNFI_MAC_CTL); ++ mac &= ~(MAC_TRIG | MAC_EN | MAC_SIO_SEL); ++ writel(mac, snfi->regs + SNFI_MAC_CTL); ++} ++ ++static int mtk_snfi_mac_op(struct mtk_snfi *snfi) ++{ ++ int ret = 0; ++ ++ mtk_snfi_mac_enable(snfi); ++ ++ ret = mtk_snfi_mac_trigger(snfi); ++ if (ret) ++ return ret; ++ ++ mtk_snfi_mac_leave(snfi); ++ ++ return ret; ++} ++ ++static irqreturn_t mtk_snfi_irq(int irq, void *id) ++{ ++ struct mtk_snfi *snfi = id; ++ u16 sta, ien; ++ ++ sta = readw(snfi->regs + NFI_INTR_STA); ++ ien = readw(snfi->regs + NFI_INTR_EN); ++ ++ if (!(sta & ien)) ++ return IRQ_NONE; ++ ++ writew(~sta & ien, snfi->regs + NFI_INTR_EN); ++ complete(&snfi->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int mtk_snfi_enable_clk(struct device *dev, struct mtk_snfi_clk *clk) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(clk->nfi_clk); ++ if (ret) { ++ dev_err(dev, "failed to enable nfi clk\n"); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(clk->spi_clk); ++ if (ret) { ++ dev_err(dev, "failed to enable spi clk\n"); ++ clk_disable_unprepare(clk->nfi_clk); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void mtk_snfi_disable_clk(struct mtk_snfi_clk *clk) ++{ ++ clk_disable_unprepare(clk->nfi_clk); ++ clk_disable_unprepare(clk->spi_clk); ++} ++ ++static int mtk_snfi_reset(struct mtk_snfi *snfi) ++{ ++ u32 val; ++ int ret; ++ ++ /* SW reset controller */ ++ val = readl(snfi->regs + SNFI_MISC_CTL) | SW_RST; ++ writel(val, snfi->regs + SNFI_MISC_CTL); ++ ++ ret = readw_poll_timeout(snfi->regs + SNFI_STA_CTL1, val, ++ !(val & SPI_STATE_IDLE), 50, ++ MTK_RESET_TIMEOUT); ++ if (ret) { ++ dev_warn(snfi->dev, "spi state active in reset [0x%x] = 0x%x\n", ++ SNFI_STA_CTL1, val); ++ return ret; ++ } ++ ++ val = readl(snfi->regs + SNFI_MISC_CTL); ++ val &= ~SW_RST; ++ writel(val, snfi->regs + SNFI_MISC_CTL); ++ ++ /* reset all registers and force the NFI master to terminate */ ++ writew(CON_FIFO_FLUSH | CON_NFI_RST, snfi->regs + NFI_CON); ++ ret = readw_poll_timeout(snfi->regs + NFI_STA, val, ++ !(val & (NFI_FSM_MASK | NAND_FSM_MASK)), 50, ++ MTK_RESET_TIMEOUT); ++ if (ret) { ++ dev_warn(snfi->dev, "nfi active in reset [0x%x] = 0x%x\n", ++ NFI_STA, val); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mtk_snfi_set_spare_per_sector(struct spinand_device *spinand, ++ const struct mtk_snfi_caps *caps, ++ u32 *sps) ++{ ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ const u8 *spare = caps->spare_size; ++ u32 sectors, i, closest_spare = 0; ++ ++ sectors = mtd->writesize / caps->nand_sec_size; ++ *sps = mtd->oobsize / sectors; ++ ++ if (*sps < MTK_SNFC_MIN_SPARE) ++ return -EINVAL; ++ ++ for (i = 0; i < caps->num_spare_size; i++) { ++ if (*sps >= spare[i] && spare[i] >= spare[closest_spare]) { ++ closest_spare = i; ++ if (*sps == spare[i]) ++ break; ++ } ++ } ++ ++ *sps = spare[closest_spare]; ++ ++ return 0; ++} ++ ++static void mtk_snfi_read_fdm_data(struct spi_mem *mem, ++ u32 sectors) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ const struct mtk_snfi_caps *caps = snfi->caps; ++ u32 vall, valm; ++ int i, j; ++ u8 *oobptr; ++ ++ for (i = 0; i < sectors; i++) { ++ oobptr = oob_ptr(mem, i); ++ vall = readl(snfi->regs + NFI_FDML(i)); ++ valm = readl(snfi->regs + NFI_FDMM(i)); ++ ++ for (j = 0; j < caps->nand_fdm_size; j++) ++ oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8); ++ } ++} ++ ++static void mtk_snfi_write_fdm_data(struct spi_mem *mem, ++ u32 sectors) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ const struct mtk_snfi_caps *caps = snfi->caps; ++ u32 vall, valm; ++ int i, j; ++ u8 *oobptr; ++ ++ for (i = 0; i < sectors; i++) { ++ oobptr = oob_ptr(mem, i); ++ vall = 0; ++ valm = 0; ++ for (j = 0; j < 8; j++) { ++ if (j < 4) ++ vall |= (j < caps->nand_fdm_size ? oobptr[j] : ++ 0xff) << (j * 8); ++ else ++ valm |= (j < caps->nand_fdm_size ? oobptr[j] : ++ 0xff) << ((j - 4) * 8); ++ } ++ writel(vall, snfi->regs + NFI_FDML(i)); ++ writel(valm, snfi->regs + NFI_FDMM(i)); ++ } ++} ++ ++static int mtk_snfi_update_ecc_stats(struct spi_mem *mem, ++ u8 *buf, u32 sectors) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_ecc_stats stats; ++ int rc, i; ++ ++ rc = readl(snfi->regs + NFI_STA) & STA_EMP_PAGE; ++ if (rc) { ++ memset(buf, 0xff, sectors * snfi->caps->nand_sec_size); ++ for (i = 0; i < sectors; i++) ++ memset(spinand->oobbuf, 0xff, ++ snfi->caps->nand_fdm_size); ++ return 0; ++ } ++ ++ mtk_ecc_get_stats(snfi->ecc, &stats, sectors); ++ mtd->ecc_stats.corrected += stats.corrected; ++ mtd->ecc_stats.failed += stats.failed; ++ ++ return 0; ++} ++ ++static int mtk_snfi_hw_runtime_config(struct spi_mem *mem) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct nand_device *nand = mtd_to_nanddev(mtd); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ const struct mtk_snfi_caps *caps = snfi->caps; ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 fmt, spare, i = 0; ++ int ret; ++ ++ ret = mtk_snfi_set_spare_per_sector(spinand, caps, &spare); ++ if (ret) ++ return ret; ++ ++ /* calculate usable oob bytes for ecc parity data */ ++ snfi_nand->spare_per_sector = spare; ++ spare -= caps->nand_fdm_size; ++ ++ nand->memorg.oobsize = snfi_nand->spare_per_sector ++ * (mtd->writesize / caps->nand_sec_size); ++ mtd->oobsize = nanddev_per_page_oobsize(nand); ++ ++ snfi->ecc_cfg.strength = (spare << 3) / caps->ecc_parity_bits; ++ mtk_ecc_adjust_strength(snfi->ecc, &snfi->ecc_cfg.strength); ++ ++ switch (mtd->writesize) { ++ case 512: ++ fmt = PAGEFMT_512; ++ break; ++ case KB(2): ++ fmt = PAGEFMT_2K; ++ break; ++ case KB(4): ++ fmt = PAGEFMT_4K; ++ break; ++ default: ++ dev_err(snfi->dev, "invalid page len: %d\n", mtd->writesize); ++ return -EINVAL; ++ } ++ ++ /* Setup PageFormat */ ++ while (caps->spare_size[i] != snfi_nand->spare_per_sector) { ++ i++; ++ if (i == (caps->num_spare_size - 1)) { ++ dev_err(snfi->dev, "invalid spare size %d\n", ++ snfi_nand->spare_per_sector); ++ return -EINVAL; ++ } ++ } ++ ++ fmt |= i << caps->pageformat_spare_shift; ++ fmt |= caps->nand_fdm_size << PAGEFMT_FDM_SHIFT; ++ fmt |= caps->nand_fdm_ecc_size << PAGEFMT_FDM_ECC_SHIFT; ++ writel(fmt, snfi->regs + NFI_PAGEFMT); ++ ++ snfi->ecc_cfg.len = caps->nand_sec_size + caps->nand_fdm_ecc_size; ++ ++ mtk_snfi_set_bad_mark_ctl(&snfi_nand->bad_mark, mem); ++ ++ return 0; ++} ++ ++static int mtk_snfi_read_from_cache(struct spi_mem *mem, ++ const struct spi_mem_op *op, int oob_on) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 reg, len, col_addr = 0; ++ int dummy_cycle, ret; ++ dma_addr_t dma_addr; ++ ++ len = sectors * (snfi->caps->nand_sec_size ++ + snfi_nand->spare_per_sector); ++ ++ dma_addr = dma_map_single(snfi->dev, snfi->buffer, ++ len, DMA_FROM_DEVICE); ++ ret = dma_mapping_error(snfi->dev, dma_addr); ++ if (ret) { ++ dev_err(snfi->dev, "dma mapping error\n"); ++ return -EINVAL; ++ } ++ ++ /* set Read cache command and dummy cycle */ ++ dummy_cycle = (op->dummy.nbytes << 3) >> (ffs(op->dummy.buswidth) - 1); ++ reg = ((op->cmd.opcode & RD_CMD_MASK) | ++ (dummy_cycle << RD_DUMMY_SHIFT)); ++ writel(reg, snfi->regs + SNFI_RD_CTL2); ++ ++ writel((col_addr & RD_ADDR_MASK), snfi->regs + SNFI_RD_CTL3); ++ ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg |= RD_CUSTOM_EN; ++ reg &= ~(RD_MODE_MASK | WR_X4_EN); ++ ++ /* set data and addr buswidth */ ++ if (op->data.buswidth == 4) ++ reg |= RD_MODE_X4; ++ else if (op->data.buswidth == 2) ++ reg |= RD_MODE_X2; ++ ++ if (op->addr.buswidth == 4 || op->addr.buswidth == 2) ++ reg |= RD_QDUAL_IO; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ writel(len, snfi->regs + SNFI_MISC_CTL2); ++ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON); ++ reg = readw(snfi->regs + NFI_CNFG); ++ reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA | CNFG_OP_CUST; ++ ++ if (!oob_on) { ++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; ++ writew(reg, snfi->regs + NFI_CNFG); ++ ++ snfi->ecc_cfg.mode = ECC_NFI_MODE; ++ snfi->ecc_cfg.sectors = sectors; ++ snfi->ecc_cfg.op = ECC_DECODE; ++ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg); ++ if (ret) { ++ dev_err(snfi->dev, "ecc enable failed\n"); ++ /* clear NFI_CNFG */ ++ reg &= ~(CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA | ++ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); ++ writew(reg, snfi->regs + NFI_CNFG); ++ goto out; ++ } ++ } else { ++ writew(reg, snfi->regs + NFI_CNFG); ++ } ++ ++ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR); ++ readw(snfi->regs + NFI_INTR_STA); ++ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN); ++ ++ init_completion(&snfi->done); ++ ++ /* set dummy command to trigger NFI enter SPI mode */ ++ writew(NAND_CMD_DUMMYREAD, snfi->regs + NFI_CMD); ++ reg = readl(snfi->regs + NFI_CON) | CON_BRD; ++ writew(reg, snfi->regs + NFI_CON); ++ ++ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500)); ++ if (!ret) { ++ dev_err(snfi->dev, "read ahb done timeout\n"); ++ writew(0, snfi->regs + NFI_INTR_EN); ++ ret = -ETIMEDOUT; ++ goto out; ++ } ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + NFI_BYTELEN, reg, ++ ADDRCNTR_SEC(reg) >= sectors, 10, ++ MTK_TIMEOUT); ++ if (ret < 0) { ++ dev_err(snfi->dev, "polling read byte len timeout\n"); ++ ret = -EIO; ++ } else { ++ if (!oob_on) { ++ ret = mtk_ecc_wait_done(snfi->ecc, ECC_DECODE); ++ if (ret) { ++ dev_warn(snfi->dev, "wait ecc done timeout\n"); ++ } else { ++ mtk_snfi_update_ecc_stats(mem, snfi->buffer, ++ sectors); ++ mtk_snfi_read_fdm_data(mem, sectors); ++ } ++ } ++ } ++ ++ if (oob_on) ++ goto out; ++ ++ mtk_ecc_disable(snfi->ecc); ++out: ++ dma_unmap_single(snfi->dev, dma_addr, len, DMA_FROM_DEVICE); ++ writel(0, snfi->regs + NFI_CON); ++ writel(0, snfi->regs + NFI_CNFG); ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg &= ~RD_CUSTOM_EN; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ return ret; ++} ++ ++static int mtk_snfi_write_to_cache(struct spi_mem *mem, ++ const struct spi_mem_op *op, ++ int oob_on) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 reg, len, col_addr = 0; ++ dma_addr_t dma_addr; ++ int ret; ++ ++ len = sectors * (snfi->caps->nand_sec_size ++ + snfi_nand->spare_per_sector); ++ ++ dma_addr = dma_map_single(snfi->dev, snfi->buffer, len, ++ DMA_TO_DEVICE); ++ ret = dma_mapping_error(snfi->dev, dma_addr); ++ if (ret) { ++ dev_err(snfi->dev, "dma mapping error\n"); ++ return -EINVAL; ++ } ++ ++ /* set program load cmd and address */ ++ reg = (op->cmd.opcode << WR_LOAD_CMD_SHIFT); ++ writel(reg, snfi->regs + SNFI_PG_CTL1); ++ writel(col_addr & WR_LOAD_ADDR_MASK, snfi->regs + SNFI_PG_CTL2); ++ ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg |= WR_CUSTOM_EN; ++ reg &= ~(RD_MODE_MASK | WR_X4_EN); ++ ++ if (op->data.buswidth == 4) ++ reg |= WR_X4_EN; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ writel(len << WR_LEN_SHIFT, snfi->regs + SNFI_MISC_CTL2); ++ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON); ++ ++ reg = readw(snfi->regs + NFI_CNFG); ++ reg &= ~(CNFG_READ_EN | CNFG_BYTE_RW); ++ reg |= CNFG_DMA | CNFG_DMA_BURST_EN | CNFG_OP_PROGRAM; ++ ++ if (!oob_on) { ++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; ++ writew(reg, snfi->regs + NFI_CNFG); ++ ++ snfi->ecc_cfg.mode = ECC_NFI_MODE; ++ snfi->ecc_cfg.op = ECC_ENCODE; ++ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg); ++ if (ret) { ++ dev_err(snfi->dev, "ecc enable failed\n"); ++ /* clear NFI_CNFG */ ++ reg &= ~(CNFG_DMA_BURST_EN | CNFG_DMA | ++ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); ++ writew(reg, snfi->regs + NFI_CNFG); ++ dma_unmap_single(snfi->dev, dma_addr, len, ++ DMA_FROM_DEVICE); ++ goto out; ++ } ++ /* write OOB into the FDM registers (OOB area in MTK NAND) */ ++ mtk_snfi_write_fdm_data(mem, sectors); ++ } else { ++ writew(reg, snfi->regs + NFI_CNFG); ++ } ++ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR); ++ readw(snfi->regs + NFI_INTR_STA); ++ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN); ++ ++ init_completion(&snfi->done); ++ ++ /* set dummy command to trigger NFI enter SPI mode */ ++ writew(NAND_CMD_DUMMYPROG, snfi->regs + NFI_CMD); ++ reg = readl(snfi->regs + NFI_CON) | CON_BWR; ++ writew(reg, snfi->regs + NFI_CON); ++ ++ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500)); ++ if (!ret) { ++ dev_err(snfi->dev, "custom program done timeout\n"); ++ writew(0, snfi->regs + NFI_INTR_EN); ++ ret = -ETIMEDOUT; ++ goto ecc_disable; ++ } ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + NFI_ADDRCNTR, reg, ++ ADDRCNTR_SEC(reg) >= sectors, ++ 10, MTK_TIMEOUT); ++ if (ret) ++ dev_err(snfi->dev, "hwecc write timeout\n"); ++ ++ecc_disable: ++ mtk_ecc_disable(snfi->ecc); ++ ++out: ++ dma_unmap_single(snfi->dev, dma_addr, len, DMA_TO_DEVICE); ++ writel(0, snfi->regs + NFI_CON); ++ writel(0, snfi->regs + NFI_CNFG); ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg &= ~WR_CUSTOM_EN; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ return ret; ++} ++ ++static int mtk_snfi_read(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 col_addr = op->addr.val; ++ int i, ret, sectors, oob_on = false; ++ ++ if (col_addr == mtd->writesize) ++ oob_on = true; ++ ++ ret = mtk_snfi_read_from_cache(mem, op, oob_on); ++ if (ret) { ++ dev_warn(snfi->dev, "read from cache fail\n"); ++ return ret; ++ } ++ ++ sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ for (i = 0; i < sectors; i++) { ++ if (oob_on) ++ memcpy(oob_ptr(mem, i), ++ mtk_oob_ptr(mem, snfi->buffer, i), ++ snfi->caps->nand_fdm_size); ++ ++ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap) ++ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer, ++ oob_on); ++ } ++ ++ if (!oob_on) ++ memcpy(spinand->databuf, snfi->buffer, mtd->writesize); ++ ++ return ret; ++} ++ ++static int mtk_snfi_write(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 ret, i, sectors, col_addr = op->addr.val; ++ int oob_on = false; ++ ++ if (col_addr == mtd->writesize) ++ oob_on = true; ++ ++ sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ memset(snfi->buffer, 0xff, mtd->writesize + mtd->oobsize); ++ ++ if (!oob_on) ++ memcpy(snfi->buffer, spinand->databuf, mtd->writesize); ++ ++ for (i = 0; i < sectors; i++) { ++ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap) ++ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer, oob_on); ++ ++ if (oob_on) ++ memcpy(mtk_oob_ptr(mem, snfi->buffer, i), ++ oob_ptr(mem, i), ++ snfi->caps->nand_fdm_size); ++ } ++ ++ ret = mtk_snfi_write_to_cache(mem, op, oob_on); ++ if (ret) ++ dev_warn(snfi->dev, "write to cache fail\n"); ++ ++ return ret; ++} ++ ++static int mtk_snfi_command_exec(struct mtk_snfi *snfi, ++ const u8 *txbuf, u8 *rxbuf, ++ const u32 txlen, const u32 rxlen) ++{ ++ u32 tmp, i, j, reg, m; ++ u8 *p_tmp = (u8 *)(&tmp); ++ int ret = 0; ++ ++ /* Moving tx data to NFI_SPI GPRAM */ ++ for (i = 0, m = 0; i < txlen; ) { ++ for (j = 0, tmp = 0; i < txlen && j < 4; i++, j++) ++ p_tmp[j] = txbuf[i]; ++ ++ writel(tmp, snfi->regs + SNFI_GPRAM_DATA + m); ++ m += 4; ++ } ++ ++ writel(txlen, snfi->regs + SNFI_MAC_OUTL); ++ writel(rxlen, snfi->regs + SNFI_MAC_INL); ++ ret = mtk_snfi_mac_op(snfi); ++ if (ret) ++ return ret; ++ ++ /* For NULL input data, this loop will be skipped */ ++ if (rxlen) ++ for (i = 0, m = 0; i < rxlen; ) { ++ reg = readl(snfi->regs + ++ SNFI_GPRAM_DATA + m); ++ for (j = 0; i < rxlen && j < 4; i++, j++, rxbuf++) { ++ if (m == 0 && i == 0) ++ j = i + txlen; ++ *rxbuf = (reg >> (j * 8)) & 0xFF; ++ } ++ m += 4; ++ } ++ ++ return ret; ++} ++ ++/* ++ * mtk_snfi_exec_op - to process command/data to send to the ++ * SPI NAND by mtk controller ++ */ ++static int mtk_snfi_exec_op(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++ ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct nand_device *nand = mtd_to_nanddev(mtd); ++ const struct spi_mem_op *read_cache; ++ const struct spi_mem_op *write_cache; ++ const struct spi_mem_op *update_cache; ++ u32 tmpbufsize, txlen = 0, rxlen = 0; ++ u8 *txbuf, *rxbuf = NULL, *buf; ++ int i, ret = 0; ++ ++ ret = mtk_snfi_reset(snfi); ++ if (ret) { ++ dev_warn(snfi->dev, "reset spi memory controller fail\n"); ++ return ret; ++ } ++ ++ /*if bbt initial, framework have detect nand information */ ++ if (nand->bbt.cache) { ++ read_cache = spinand->op_templates.read_cache; ++ write_cache = spinand->op_templates.write_cache; ++ update_cache = spinand->op_templates.update_cache; ++ ++ ret = mtk_snfi_hw_runtime_config(mem); ++ if (ret) ++ return ret; ++ ++ /* For Read/Write with cache, Erase use framework flow */ ++ if (op->cmd.opcode == read_cache->cmd.opcode) { ++ ret = mtk_snfi_read(mem, op); ++ if (ret) ++ dev_warn(snfi->dev, "snfi read fail\n"); ++ ++ return ret; ++ } else if ((op->cmd.opcode == write_cache->cmd.opcode) ++ || (op->cmd.opcode == update_cache->cmd.opcode)) { ++ ret = mtk_snfi_write(mem, op); ++ if (ret) ++ dev_warn(snfi->dev, "snfi write fail\n"); ++ ++ return ret; ++ } ++ } ++ ++ tmpbufsize = sizeof(op->cmd.opcode) + op->addr.nbytes + ++ op->dummy.nbytes + op->data.nbytes; ++ ++ txbuf = kzalloc(tmpbufsize, GFP_KERNEL); ++ if (!txbuf) ++ return -ENOMEM; ++ ++ txbuf[txlen++] = op->cmd.opcode; ++ ++ if (op->addr.nbytes) ++ for (i = 0; i < op->addr.nbytes; i++) ++ txbuf[txlen++] = op->addr.val >> ++ (8 * (op->addr.nbytes - i - 1)); ++ ++ txlen += op->dummy.nbytes; ++ ++ if (op->data.dir == SPI_MEM_DATA_OUT) ++ for (i = 0; i < op->data.nbytes; i++) { ++ buf = (u8 *)op->data.buf.out; ++ txbuf[txlen++] = buf[i]; ++ } ++ ++ if (op->data.dir == SPI_MEM_DATA_IN) { ++ rxbuf = (u8 *)op->data.buf.in; ++ rxlen += op->data.nbytes; ++ } ++ ++ ret = mtk_snfi_command_exec(snfi, txbuf, rxbuf, txlen, rxlen); ++ kfree(txbuf); ++ ++ return ret; ++} ++ ++static int mtk_snfi_init(struct mtk_snfi *snfi) ++{ ++ int ret; ++ ++ /* Reset the state machine and data FIFO */ ++ ret = mtk_snfi_reset(snfi); ++ if (ret) { ++ dev_warn(snfi->dev, "MTK reset controller fail\n"); ++ return ret; ++ } ++ ++ snfi->buffer = devm_kzalloc(snfi->dev, 4096 + 256, GFP_KERNEL); ++ if (!snfi->buffer) ++ return -ENOMEM; ++ ++ /* Clear interrupt, read clear. */ ++ readw(snfi->regs + NFI_INTR_STA); ++ writew(0, snfi->regs + NFI_INTR_EN); ++ ++ writel(0, snfi->regs + NFI_CON); ++ writel(0, snfi->regs + NFI_CNFG); ++ ++ /* Change to NFI_SPI mode. */ ++ writel(SNFI_MODE_EN, snfi->regs + SNFI_CNFG); ++ ++ return 0; ++} ++ ++static int mtk_snfi_check_buswidth(u8 width) ++{ ++ switch (width) { ++ case 1: ++ case 2: ++ case 4: ++ return 0; ++ ++ default: ++ break; ++ } ++ ++ return -ENOTSUPP; ++} ++ ++static bool mtk_snfi_supports_op(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ int ret = 0; ++ ++ /* For MTK Spi Nand controller, cmd buswidth just support 1 bit*/ ++ if (op->cmd.buswidth != 1) ++ ret = -ENOTSUPP; ++ ++ if (op->addr.nbytes) ++ ret |= mtk_snfi_check_buswidth(op->addr.buswidth); ++ ++ if (op->dummy.nbytes) ++ ret |= mtk_snfi_check_buswidth(op->dummy.buswidth); ++ ++ if (op->data.nbytes) ++ ret |= mtk_snfi_check_buswidth(op->data.buswidth); ++ ++ if (ret) ++ return false; ++ ++ return true; ++} ++ ++static const struct spi_controller_mem_ops mtk_snfi_ops = { ++ .supports_op = mtk_snfi_supports_op, ++ .exec_op = mtk_snfi_exec_op, ++}; ++ ++static const struct mtk_snfi_caps snfi_mt7622 = { ++ .spare_size = spare_size_mt7622, ++ .num_spare_size = 4, ++ .nand_sec_size = 512, ++ .nand_fdm_size = 8, ++ .nand_fdm_ecc_size = 1, ++ .ecc_parity_bits = 13, ++ .pageformat_spare_shift = 4, ++ .bad_mark_swap = 0, ++}; ++ ++static const struct mtk_snfi_caps snfi_mt7629 = { ++ .spare_size = spare_size_mt7622, ++ .num_spare_size = 4, ++ .nand_sec_size = 512, ++ .nand_fdm_size = 8, ++ .nand_fdm_ecc_size = 1, ++ .ecc_parity_bits = 13, ++ .pageformat_spare_shift = 4, ++ .bad_mark_swap = 1, ++}; ++ ++static const struct of_device_id mtk_snfi_id_table[] = { ++ { .compatible = "mediatek,mt7622-snfi", .data = &snfi_mt7622, }, ++ { .compatible = "mediatek,mt7629-snfi", .data = &snfi_mt7629, }, ++ { /* sentinel */ } ++}; ++ ++static int mtk_snfi_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct spi_controller *ctlr; ++ struct mtk_snfi *snfi; ++ struct resource *res; ++ int ret = 0, irq; ++ ++ ctlr = spi_alloc_master(&pdev->dev, sizeof(*snfi)); ++ if (!ctlr) ++ return -ENOMEM; ++ ++ snfi = spi_controller_get_devdata(ctlr); ++ snfi->caps = of_device_get_match_data(dev); ++ snfi->dev = dev; ++ ++ snfi->ecc = of_mtk_ecc_get(np); ++ if (IS_ERR_OR_NULL(snfi->ecc)) ++ goto err_put_master; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ snfi->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(snfi->regs)) { ++ ret = PTR_ERR(snfi->regs); ++ goto release_ecc; ++ } ++ ++ /* find the clocks */ ++ snfi->clk.nfi_clk = devm_clk_get(dev, "nfi_clk"); ++ if (IS_ERR(snfi->clk.nfi_clk)) { ++ dev_err(dev, "no nfi clk\n"); ++ ret = PTR_ERR(snfi->clk.nfi_clk); ++ goto release_ecc; ++ } ++ ++ snfi->clk.spi_clk = devm_clk_get(dev, "spi_clk"); ++ if (IS_ERR(snfi->clk.spi_clk)) { ++ dev_err(dev, "no spi clk\n"); ++ ret = PTR_ERR(snfi->clk.spi_clk); ++ goto release_ecc; ++ } ++ ++ ret = mtk_snfi_enable_clk(dev, &snfi->clk); ++ if (ret) ++ goto release_ecc; ++ ++ /* find the irq */ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no snfi irq resource\n"); ++ ret = -EINVAL; ++ goto clk_disable; ++ } ++ ++ ret = devm_request_irq(dev, irq, mtk_snfi_irq, 0, "mtk-snfi", snfi); ++ if (ret) { ++ dev_err(dev, "failed to request snfi irq\n"); ++ goto clk_disable; ++ } ++ ++ ret = dma_set_mask(dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ dev_err(dev, "failed to set dma mask\n"); ++ goto clk_disable; ++ } ++ ++ ctlr->dev.of_node = np; ++ ctlr->mem_ops = &mtk_snfi_ops; ++ ++ platform_set_drvdata(pdev, snfi); ++ ret = mtk_snfi_init(snfi); ++ if (ret) { ++ dev_err(dev, "failed to init snfi\n"); ++ goto clk_disable; ++ } ++ ++ ret = devm_spi_register_master(dev, ctlr); ++ if (ret) ++ goto clk_disable; ++ ++ return 0; ++ ++clk_disable: ++ mtk_snfi_disable_clk(&snfi->clk); ++ ++release_ecc: ++ mtk_ecc_release(snfi->ecc); ++ ++err_put_master: ++ spi_master_put(ctlr); ++ ++ dev_err(dev, "MediaTek SPI NAND interface probe failed %d\n", ret); ++ return ret; ++} ++ ++static int mtk_snfi_remove(struct platform_device *pdev) ++{ ++ struct mtk_snfi *snfi = platform_get_drvdata(pdev); ++ ++ mtk_snfi_disable_clk(&snfi->clk); ++ ++ return 0; ++} ++ ++static int mtk_snfi_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct mtk_snfi *snfi = platform_get_drvdata(pdev); ++ ++ mtk_snfi_disable_clk(&snfi->clk); ++ ++ return 0; ++} ++ ++static int mtk_snfi_resume(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct mtk_snfi *snfi = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = mtk_snfi_enable_clk(dev, &snfi->clk); ++ if (ret) ++ return ret; ++ ++ ret = mtk_snfi_init(snfi); ++ if (ret) ++ dev_err(dev, "failed to init snfi controller\n"); ++ ++ return ret; ++} ++ ++static struct platform_driver mtk_snfi_driver = { ++ .driver = { ++ .name = "mtk-snfi", ++ .of_match_table = mtk_snfi_id_table, ++ }, ++ .probe = mtk_snfi_probe, ++ .remove = mtk_snfi_remove, ++ .suspend = mtk_snfi_suspend, ++ .resume = mtk_snfi_resume, ++}; ++ ++module_platform_driver(mtk_snfi_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Xiangsheng Hou "); ++MODULE_DESCRIPTION("Mediatek SPI Memory Interface Driver"); diff --git a/root/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch b/root/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch new file mode 100755 index 00000000..753c1117 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch @@ -0,0 +1,97 @@ +From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Thu, 6 Jun 2019 16:29:04 +0800 +Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629 + +Signed-off-by: Xiangsheng Hou +--- + arch/arm/boot/dts/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++ + arch/arm/boot/dts/mt7629.dtsi | 22 ++++++++++++++++ + 3 files changed, 79 insertions(+) + +--- a/arch/arm/boot/dts/mt7629.dtsi ++++ b/arch/arm/boot/dts/mt7629.dtsi +@@ -258,6 +258,28 @@ + status = "disabled"; + }; + ++ bch: ecc@1100e000 { ++ compatible = "mediatek,mt7622-ecc"; ++ reg = <0x1100e000 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFIECC_PD>; ++ clock-names = "nfiecc_clk"; ++ status = "disabled"; ++ }; ++ ++ snfi: spi@1100d000 { ++ compatible = "mediatek,mt7629-snfi"; ++ reg = <0x1100d000 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFI_PD>, ++ <&pericfg CLK_PERI_SNFI_PD>; ++ clock-names = "nfi_clk", "spi_clk"; ++ ecc-engine = <&bch>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + spi: spi@1100a000 { + compatible = "mediatek,mt7629-spi", + "mediatek,mt7622-spi"; +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -276,6 +276,52 @@ + }; + }; + ++&bch { ++ status = "okay"; ++}; ++ ++&snfi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ spi_nand@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ spi-max-frequency = <104000000>; ++ reg = <0>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Bootloader"; ++ reg = <0x00000 0x0100000>; ++ read-only; ++ }; ++ ++ partition@100000 { ++ label = "Config"; ++ reg = <0x100000 0x0040000>; ++ }; ++ ++ partition@140000 { ++ label = "factory"; ++ reg = <0x140000 0x0080000>; ++ }; ++ ++ partition@1c0000 { ++ label = "firmware"; ++ reg = <0x1c0000 0x1000000>; ++ }; ++ ++ }; ++ }; ++}; ++ + &spi { + pinctrl-names = "default"; + pinctrl-0 = <&spi_pins>; diff --git a/root/target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch b/root/target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch new file mode 100755 index 00000000..2fae90ef --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0500-v5.6-crypto-backport-inside-secure.patch @@ -0,0 +1,5464 @@ +--- a/drivers/crypto/inside-secure/safexcel.c ++++ b/drivers/crypto/inside-secure/safexcel.c +@@ -75,9 +75,9 @@ static void eip197_trc_cache_banksel(str + } + + static u32 eip197_trc_cache_probe(struct safexcel_crypto_priv *priv, +- int maxbanks, u32 probemask) ++ int maxbanks, u32 probemask, u32 stride) + { +- u32 val, addrhi, addrlo, addrmid; ++ u32 val, addrhi, addrlo, addrmid, addralias, delta, marker; + int actbank; + + /* +@@ -87,32 +87,37 @@ static u32 eip197_trc_cache_probe(struct + addrhi = 1 << (16 + maxbanks); + addrlo = 0; + actbank = min(maxbanks - 1, 0); +- while ((addrhi - addrlo) > 32) { ++ while ((addrhi - addrlo) > stride) { + /* write marker to lowest address in top half */ + addrmid = (addrhi + addrlo) >> 1; ++ marker = (addrmid ^ 0xabadbabe) & probemask; /* Unique */ + eip197_trc_cache_banksel(priv, addrmid, &actbank); +- writel((addrmid | (addrlo << 16)) & probemask, ++ writel(marker, + priv->base + EIP197_CLASSIFICATION_RAMS + + (addrmid & 0xffff)); + +- /* write marker to lowest address in bottom half */ +- eip197_trc_cache_banksel(priv, addrlo, &actbank); +- writel((addrlo | (addrhi << 16)) & probemask, +- priv->base + EIP197_CLASSIFICATION_RAMS + +- (addrlo & 0xffff)); ++ /* write invalid markers to possible aliases */ ++ delta = 1 << __fls(addrmid); ++ while (delta >= stride) { ++ addralias = addrmid - delta; ++ eip197_trc_cache_banksel(priv, addralias, &actbank); ++ writel(~marker, ++ priv->base + EIP197_CLASSIFICATION_RAMS + ++ (addralias & 0xffff)); ++ delta >>= 1; ++ } + + /* read back marker from top half */ + eip197_trc_cache_banksel(priv, addrmid, &actbank); + val = readl(priv->base + EIP197_CLASSIFICATION_RAMS + + (addrmid & 0xffff)); + +- if (val == ((addrmid | (addrlo << 16)) & probemask)) { ++ if ((val & probemask) == marker) + /* read back correct, continue with top half */ + addrlo = addrmid; +- } else { ++ else + /* not read back correct, continue with bottom half */ + addrhi = addrmid; +- } + } + return addrhi; + } +@@ -150,7 +155,7 @@ static void eip197_trc_cache_clear(struc + htable_offset + i * sizeof(u32)); + } + +-static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv) ++static int eip197_trc_cache_init(struct safexcel_crypto_priv *priv) + { + u32 val, dsize, asize; + int cs_rc_max, cs_ht_wc, cs_trc_rec_wc, cs_trc_lg_rec_wc; +@@ -183,7 +188,7 @@ static void eip197_trc_cache_init(struct + writel(val, priv->base + EIP197_TRC_PARAMS); + + /* Probed data RAM size in bytes */ +- dsize = eip197_trc_cache_probe(priv, maxbanks, 0xffffffff); ++ dsize = eip197_trc_cache_probe(priv, maxbanks, 0xffffffff, 32); + + /* + * Now probe the administration RAM size pretty much the same way +@@ -196,11 +201,18 @@ static void eip197_trc_cache_init(struct + writel(val, priv->base + EIP197_TRC_PARAMS); + + /* Probed admin RAM size in admin words */ +- asize = eip197_trc_cache_probe(priv, 0, 0xbfffffff) >> 4; ++ asize = eip197_trc_cache_probe(priv, 0, 0x3fffffff, 16) >> 4; + + /* Clear any ECC errors detected while probing! */ + writel(0, priv->base + EIP197_TRC_ECCCTRL); + ++ /* Sanity check probing results */ ++ if (dsize < EIP197_MIN_DSIZE || asize < EIP197_MIN_ASIZE) { ++ dev_err(priv->dev, "Record cache probing failed (%d,%d).", ++ dsize, asize); ++ return -ENODEV; ++ } ++ + /* + * Determine optimal configuration from RAM sizes + * Note that we assume that the physical RAM configuration is sane +@@ -251,6 +263,7 @@ static void eip197_trc_cache_init(struct + + dev_info(priv->dev, "TRC init: %dd,%da (%dr,%dh)\n", + dsize, asize, cs_rc_max, cs_ht_wc + cs_ht_wc); ++ return 0; + } + + static void eip197_init_firmware(struct safexcel_crypto_priv *priv) +@@ -298,13 +311,14 @@ static void eip197_init_firmware(struct + static int eip197_write_firmware(struct safexcel_crypto_priv *priv, + const struct firmware *fw) + { +- const u32 *data = (const u32 *)fw->data; ++ const __be32 *data = (const __be32 *)fw->data; + int i; + + /* Write the firmware */ + for (i = 0; i < fw->size / sizeof(u32); i++) + writel(be32_to_cpu(data[i]), +- priv->base + EIP197_CLASSIFICATION_RAMS + i * sizeof(u32)); ++ priv->base + EIP197_CLASSIFICATION_RAMS + ++ i * sizeof(__be32)); + + /* Exclude final 2 NOPs from size */ + return i - EIP197_FW_TERMINAL_NOPS; +@@ -471,6 +485,14 @@ static int safexcel_hw_setup_cdesc_rings + cd_fetch_cnt = ((1 << priv->hwconfig.hwcfsize) / + cd_size_rnd) - 1; + } ++ /* ++ * Since we're using command desc's way larger than formally specified, ++ * we need to check whether we can fit even 1 for low-end EIP196's! ++ */ ++ if (!cd_fetch_cnt) { ++ dev_err(priv->dev, "Unable to fit even 1 command desc!\n"); ++ return -ENODEV; ++ } + + for (i = 0; i < priv->config.rings; i++) { + /* ring base address */ +@@ -479,12 +501,12 @@ static int safexcel_hw_setup_cdesc_rings + writel(upper_32_bits(priv->ring[i].cdr.base_dma), + EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI); + +- writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.cd_offset << 16) | +- priv->config.cd_size, ++ writel(EIP197_xDR_DESC_MODE_64BIT | EIP197_CDR_DESC_MODE_ADCP | ++ (priv->config.cd_offset << 14) | priv->config.cd_size, + EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_DESC_SIZE); + writel(((cd_fetch_cnt * + (cd_size_rnd << priv->hwconfig.hwdataw)) << 16) | +- (cd_fetch_cnt * priv->config.cd_offset), ++ (cd_fetch_cnt * (priv->config.cd_offset / sizeof(u32))), + EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_CFG); + + /* Configure DMA tx control */ +@@ -527,13 +549,13 @@ static int safexcel_hw_setup_rdesc_rings + writel(upper_32_bits(priv->ring[i].rdr.base_dma), + EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI); + +- writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.rd_offset << 16) | ++ writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.rd_offset << 14) | + priv->config.rd_size, + EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_DESC_SIZE); + + writel(((rd_fetch_cnt * + (rd_size_rnd << priv->hwconfig.hwdataw)) << 16) | +- (rd_fetch_cnt * priv->config.rd_offset), ++ (rd_fetch_cnt * (priv->config.rd_offset / sizeof(u32))), + EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_CFG); + + /* Configure DMA tx control */ +@@ -559,7 +581,7 @@ static int safexcel_hw_setup_rdesc_rings + static int safexcel_hw_init(struct safexcel_crypto_priv *priv) + { + u32 val; +- int i, ret, pe; ++ int i, ret, pe, opbuflo, opbufhi; + + dev_dbg(priv->dev, "HW init: using %d pipe(s) and %d ring(s)\n", + priv->config.pes, priv->config.rings); +@@ -595,8 +617,8 @@ static int safexcel_hw_init(struct safex + writel(EIP197_DxE_THR_CTRL_RESET_PE, + EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe)); + +- if (priv->flags & SAFEXCEL_HW_EIP197) +- /* Reset HIA input interface arbiter (EIP197 only) */ ++ if (priv->flags & EIP197_PE_ARB) ++ /* Reset HIA input interface arbiter (if present) */ + writel(EIP197_HIA_RA_PE_CTRL_RESET, + EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe)); + +@@ -639,9 +661,16 @@ static int safexcel_hw_init(struct safex + ; + + /* DMA transfer size to use */ ++ if (priv->hwconfig.hwnumpes > 4) { ++ opbuflo = 9; ++ opbufhi = 10; ++ } else { ++ opbuflo = 7; ++ opbufhi = 8; ++ } + val = EIP197_HIA_DSE_CFG_DIS_DEBUG; +- val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) | +- EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8); ++ val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(opbuflo) | ++ EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(opbufhi); + val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS); + val |= EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE; + /* FIXME: instability issues can occur for EIP97 but disabling +@@ -655,8 +684,8 @@ static int safexcel_hw_init(struct safex + writel(0, EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe)); + + /* Configure the procesing engine thresholds */ +- writel(EIP197_PE_OUT_DBUF_THRES_MIN(7) | +- EIP197_PE_OUT_DBUF_THRES_MAX(8), ++ writel(EIP197_PE_OUT_DBUF_THRES_MIN(opbuflo) | ++ EIP197_PE_OUT_DBUF_THRES_MAX(opbufhi), + EIP197_PE(priv) + EIP197_PE_OUT_DBUF_THRES(pe)); + + /* Processing Engine configuration */ +@@ -696,7 +725,7 @@ static int safexcel_hw_init(struct safex + writel(0, + EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_PROC_PNTR); + +- writel((EIP197_DEFAULT_RING_SIZE * priv->config.cd_offset) << 2, ++ writel((EIP197_DEFAULT_RING_SIZE * priv->config.cd_offset), + EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_SIZE); + } + +@@ -719,7 +748,7 @@ static int safexcel_hw_init(struct safex + EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_PROC_PNTR); + + /* Ring size */ +- writel((EIP197_DEFAULT_RING_SIZE * priv->config.rd_offset) << 2, ++ writel((EIP197_DEFAULT_RING_SIZE * priv->config.rd_offset), + EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_SIZE); + } + +@@ -736,19 +765,28 @@ static int safexcel_hw_init(struct safex + /* Clear any HIA interrupt */ + writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK); + +- if (priv->flags & SAFEXCEL_HW_EIP197) { +- eip197_trc_cache_init(priv); +- priv->flags |= EIP197_TRC_CACHE; ++ if (priv->flags & EIP197_SIMPLE_TRC) { ++ writel(EIP197_STRC_CONFIG_INIT | ++ EIP197_STRC_CONFIG_LARGE_REC(EIP197_CS_TRC_REC_WC) | ++ EIP197_STRC_CONFIG_SMALL_REC(EIP197_CS_TRC_REC_WC), ++ priv->base + EIP197_STRC_CONFIG); ++ writel(EIP197_PE_EIP96_TOKEN_CTRL2_CTX_DONE, ++ EIP197_PE(priv) + EIP197_PE_EIP96_TOKEN_CTRL2(0)); ++ } else if (priv->flags & SAFEXCEL_HW_EIP197) { ++ ret = eip197_trc_cache_init(priv); ++ if (ret) ++ return ret; ++ } + ++ if (priv->flags & EIP197_ICE) { + ret = eip197_load_firmwares(priv); + if (ret) + return ret; + } + +- safexcel_hw_setup_cdesc_rings(priv); +- safexcel_hw_setup_rdesc_rings(priv); +- +- return 0; ++ return safexcel_hw_setup_cdesc_rings(priv) ?: ++ safexcel_hw_setup_rdesc_rings(priv) ?: ++ 0; + } + + /* Called with ring's lock taken */ +@@ -836,20 +874,24 @@ finalize: + spin_unlock_bh(&priv->ring[ring].lock); + + /* let the RDR know we have pending descriptors */ +- writel((rdesc * priv->config.rd_offset) << 2, ++ writel((rdesc * priv->config.rd_offset), + EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT); + + /* let the CDR know we have pending descriptors */ +- writel((cdesc * priv->config.cd_offset) << 2, ++ writel((cdesc * priv->config.cd_offset), + EIP197_HIA_CDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT); + } + + inline int safexcel_rdesc_check_errors(struct safexcel_crypto_priv *priv, +- struct safexcel_result_desc *rdesc) ++ void *rdp) + { +- if (likely((!rdesc->descriptor_overflow) && +- (!rdesc->buffer_overflow) && +- (!rdesc->result_data.error_code))) ++ struct safexcel_result_desc *rdesc = rdp; ++ struct result_data_desc *result_data = rdp + priv->config.res_offset; ++ ++ if (likely((!rdesc->last_seg) || /* Rest only valid if last seg! */ ++ ((!rdesc->descriptor_overflow) && ++ (!rdesc->buffer_overflow) && ++ (!result_data->error_code)))) + return 0; + + if (rdesc->descriptor_overflow) +@@ -858,13 +900,14 @@ inline int safexcel_rdesc_check_errors(s + if (rdesc->buffer_overflow) + dev_err(priv->dev, "Buffer overflow detected"); + +- if (rdesc->result_data.error_code & 0x4066) { ++ if (result_data->error_code & 0x4066) { + /* Fatal error (bits 1,2,5,6 & 14) */ + dev_err(priv->dev, + "result descriptor error (%x)", +- rdesc->result_data.error_code); ++ result_data->error_code); ++ + return -EIO; +- } else if (rdesc->result_data.error_code & ++ } else if (result_data->error_code & + (BIT(7) | BIT(4) | BIT(3) | BIT(0))) { + /* + * Give priority over authentication fails: +@@ -872,7 +915,7 @@ inline int safexcel_rdesc_check_errors(s + * something wrong with the input! + */ + return -EINVAL; +- } else if (rdesc->result_data.error_code & BIT(9)) { ++ } else if (result_data->error_code & BIT(9)) { + /* Authentication failed */ + return -EBADMSG; + } +@@ -931,16 +974,18 @@ int safexcel_invalidate_cache(struct cry + { + struct safexcel_command_desc *cdesc; + struct safexcel_result_desc *rdesc; ++ struct safexcel_token *dmmy; + int ret = 0; + + /* Prepare command descriptor */ +- cdesc = safexcel_add_cdesc(priv, ring, true, true, 0, 0, 0, ctxr_dma); ++ cdesc = safexcel_add_cdesc(priv, ring, true, true, 0, 0, 0, ctxr_dma, ++ &dmmy); + if (IS_ERR(cdesc)) + return PTR_ERR(cdesc); + + cdesc->control_data.type = EIP197_TYPE_EXTENDED; + cdesc->control_data.options = 0; +- cdesc->control_data.refresh = 0; ++ cdesc->control_data.context_lo &= ~EIP197_CONTEXT_SIZE_MASK; + cdesc->control_data.control0 = CONTEXT_CONTROL_INV_TR; + + /* Prepare result descriptor */ +@@ -1003,7 +1048,7 @@ handle_results: + acknowledge: + if (i) + writel(EIP197_xDR_PROC_xD_PKT(i) | +- EIP197_xDR_PROC_xD_COUNT(tot_descs * priv->config.rd_offset), ++ (tot_descs * priv->config.rd_offset), + EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_PROC_COUNT); + + /* If the number of requests overflowed the counter, try to proceed more +@@ -1171,6 +1216,44 @@ static struct safexcel_alg_template *saf + &safexcel_alg_xts_aes, + &safexcel_alg_gcm, + &safexcel_alg_ccm, ++ &safexcel_alg_crc32, ++ &safexcel_alg_cbcmac, ++ &safexcel_alg_xcbcmac, ++ &safexcel_alg_cmac, ++ &safexcel_alg_chacha20, ++ &safexcel_alg_chachapoly, ++ &safexcel_alg_chachapoly_esp, ++ &safexcel_alg_sm3, ++ &safexcel_alg_hmac_sm3, ++ &safexcel_alg_ecb_sm4, ++ &safexcel_alg_cbc_sm4, ++ &safexcel_alg_ofb_sm4, ++ &safexcel_alg_cfb_sm4, ++ &safexcel_alg_ctr_sm4, ++ &safexcel_alg_authenc_hmac_sha1_cbc_sm4, ++ &safexcel_alg_authenc_hmac_sm3_cbc_sm4, ++ &safexcel_alg_authenc_hmac_sha1_ctr_sm4, ++ &safexcel_alg_authenc_hmac_sm3_ctr_sm4, ++ &safexcel_alg_sha3_224, ++ &safexcel_alg_sha3_256, ++ &safexcel_alg_sha3_384, ++ &safexcel_alg_sha3_512, ++ &safexcel_alg_hmac_sha3_224, ++ &safexcel_alg_hmac_sha3_256, ++ &safexcel_alg_hmac_sha3_384, ++ &safexcel_alg_hmac_sha3_512, ++ &safexcel_alg_authenc_hmac_sha1_cbc_des, ++ &safexcel_alg_authenc_hmac_sha256_cbc_des3_ede, ++ &safexcel_alg_authenc_hmac_sha224_cbc_des3_ede, ++ &safexcel_alg_authenc_hmac_sha512_cbc_des3_ede, ++ &safexcel_alg_authenc_hmac_sha384_cbc_des3_ede, ++ &safexcel_alg_authenc_hmac_sha256_cbc_des, ++ &safexcel_alg_authenc_hmac_sha224_cbc_des, ++ &safexcel_alg_authenc_hmac_sha512_cbc_des, ++ &safexcel_alg_authenc_hmac_sha384_cbc_des, ++ &safexcel_alg_rfc4106_gcm, ++ &safexcel_alg_rfc4543_gcm, ++ &safexcel_alg_rfc4309_ccm, + }; + + static int safexcel_register_algorithms(struct safexcel_crypto_priv *priv) +@@ -1240,30 +1323,30 @@ static void safexcel_unregister_algorith + + static void safexcel_configure(struct safexcel_crypto_priv *priv) + { +- u32 val, mask = 0; +- +- val = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS); +- +- /* Read number of PEs from the engine */ +- if (priv->flags & SAFEXCEL_HW_EIP197) +- /* Wider field width for all EIP197 type engines */ +- mask = EIP197_N_PES_MASK; +- else +- /* Narrow field width for EIP97 type engine */ +- mask = EIP97_N_PES_MASK; +- +- priv->config.pes = (val >> EIP197_N_PES_OFFSET) & mask; ++ u32 mask = BIT(priv->hwconfig.hwdataw) - 1; + +- priv->config.rings = min_t(u32, val & GENMASK(3, 0), max_rings); ++ priv->config.pes = priv->hwconfig.hwnumpes; ++ priv->config.rings = min_t(u32, priv->hwconfig.hwnumrings, max_rings); ++ /* Cannot currently support more rings than we have ring AICs! */ ++ priv->config.rings = min_t(u32, priv->config.rings, ++ priv->hwconfig.hwnumraic); + +- val = (val & GENMASK(27, 25)) >> 25; +- mask = BIT(val) - 1; +- +- priv->config.cd_size = (sizeof(struct safexcel_command_desc) / sizeof(u32)); ++ priv->config.cd_size = EIP197_CD64_FETCH_SIZE; + priv->config.cd_offset = (priv->config.cd_size + mask) & ~mask; ++ priv->config.cdsh_offset = (EIP197_MAX_TOKENS + mask) & ~mask; + +- priv->config.rd_size = (sizeof(struct safexcel_result_desc) / sizeof(u32)); ++ /* res token is behind the descr, but ofs must be rounded to buswdth */ ++ priv->config.res_offset = (EIP197_RD64_FETCH_SIZE + mask) & ~mask; ++ /* now the size of the descr is this 1st part plus the result struct */ ++ priv->config.rd_size = priv->config.res_offset + ++ EIP197_RD64_RESULT_SIZE; + priv->config.rd_offset = (priv->config.rd_size + mask) & ~mask; ++ ++ /* convert dwords to bytes */ ++ priv->config.cd_offset *= sizeof(u32); ++ priv->config.cdsh_offset *= sizeof(u32); ++ priv->config.rd_offset *= sizeof(u32); ++ priv->config.res_offset *= sizeof(u32); + } + + static void safexcel_init_register_offsets(struct safexcel_crypto_priv *priv) +@@ -1309,7 +1392,7 @@ static int safexcel_probe_generic(void * + int is_pci_dev) + { + struct device *dev = priv->dev; +- u32 peid, version, mask, val, hiaopt; ++ u32 peid, version, mask, val, hiaopt, hwopt, peopt; + int i, ret, hwctg; + + priv->context_pool = dmam_pool_create("safexcel-context", dev, +@@ -1371,13 +1454,16 @@ static int safexcel_probe_generic(void * + */ + version = readl(EIP197_GLOBAL(priv) + EIP197_VERSION); + if (((priv->flags & SAFEXCEL_HW_EIP197) && +- (EIP197_REG_LO16(version) != EIP197_VERSION_LE)) || ++ (EIP197_REG_LO16(version) != EIP197_VERSION_LE) && ++ (EIP197_REG_LO16(version) != EIP196_VERSION_LE)) || + ((!(priv->flags & SAFEXCEL_HW_EIP197) && + (EIP197_REG_LO16(version) != EIP97_VERSION_LE)))) { + /* + * We did not find the device that matched our initial probing + * (or our initial probing failed) Report appropriate error. + */ ++ dev_err(priv->dev, "Probing for EIP97/EIP19x failed - no such device (read %08x)\n", ++ version); + return -ENODEV; + } + +@@ -1385,6 +1471,14 @@ static int safexcel_probe_generic(void * + hwctg = version >> 28; + peid = version & 255; + ++ /* Detect EIP206 processing pipe */ ++ version = readl(EIP197_PE(priv) + + EIP197_PE_VERSION(0)); ++ if (EIP197_REG_LO16(version) != EIP206_VERSION_LE) { ++ dev_err(priv->dev, "EIP%d: EIP206 not detected\n", peid); ++ return -ENODEV; ++ } ++ priv->hwconfig.ppver = EIP197_VERSION_MASK(version); ++ + /* Detect EIP96 packet engine and version */ + version = readl(EIP197_PE(priv) + EIP197_PE_EIP96_VERSION(0)); + if (EIP197_REG_LO16(version) != EIP96_VERSION_LE) { +@@ -1393,10 +1487,13 @@ static int safexcel_probe_generic(void * + } + priv->hwconfig.pever = EIP197_VERSION_MASK(version); + ++ hwopt = readl(EIP197_GLOBAL(priv) + EIP197_OPTIONS); + hiaopt = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_OPTIONS); + + if (priv->flags & SAFEXCEL_HW_EIP197) { + /* EIP197 */ ++ peopt = readl(EIP197_PE(priv) + EIP197_PE_OPTIONS(0)); ++ + priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) & + EIP197_HWDATAW_MASK; + priv->hwconfig.hwcfsize = ((hiaopt >> EIP197_CFSIZE_OFFSET) & +@@ -1405,6 +1502,19 @@ static int safexcel_probe_generic(void * + priv->hwconfig.hwrfsize = ((hiaopt >> EIP197_RFSIZE_OFFSET) & + EIP197_RFSIZE_MASK) + + EIP197_RFSIZE_ADJUST; ++ priv->hwconfig.hwnumpes = (hiaopt >> EIP197_N_PES_OFFSET) & ++ EIP197_N_PES_MASK; ++ priv->hwconfig.hwnumrings = (hiaopt >> EIP197_N_RINGS_OFFSET) & ++ EIP197_N_RINGS_MASK; ++ if (hiaopt & EIP197_HIA_OPT_HAS_PE_ARB) ++ priv->flags |= EIP197_PE_ARB; ++ if (EIP206_OPT_ICE_TYPE(peopt) == 1) ++ priv->flags |= EIP197_ICE; ++ /* If not a full TRC, then assume simple TRC */ ++ if (!(hwopt & EIP197_OPT_HAS_TRC)) ++ priv->flags |= EIP197_SIMPLE_TRC; ++ /* EIP197 always has SOME form of TRC */ ++ priv->flags |= EIP197_TRC_CACHE; + } else { + /* EIP97 */ + priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) & +@@ -1413,6 +1523,23 @@ static int safexcel_probe_generic(void * + EIP97_CFSIZE_MASK; + priv->hwconfig.hwrfsize = (hiaopt >> EIP97_RFSIZE_OFFSET) & + EIP97_RFSIZE_MASK; ++ priv->hwconfig.hwnumpes = 1; /* by definition */ ++ priv->hwconfig.hwnumrings = (hiaopt >> EIP197_N_RINGS_OFFSET) & ++ EIP197_N_RINGS_MASK; ++ } ++ ++ /* Scan for ring AIC's */ ++ for (i = 0; i < EIP197_MAX_RING_AIC; i++) { ++ version = readl(EIP197_HIA_AIC_R(priv) + ++ EIP197_HIA_AIC_R_VERSION(i)); ++ if (EIP197_REG_LO16(version) != EIP201_VERSION_LE) ++ break; ++ } ++ priv->hwconfig.hwnumraic = i; ++ /* Low-end EIP196 may not have any ring AIC's ... */ ++ if (!priv->hwconfig.hwnumraic) { ++ dev_err(priv->dev, "No ring interrupt controller present!\n"); ++ return -ENODEV; + } + + /* Get supported algorithms from EIP96 transform engine */ +@@ -1420,10 +1547,12 @@ static int safexcel_probe_generic(void * + EIP197_PE_EIP96_OPTIONS(0)); + + /* Print single info line describing what we just detected */ +- dev_info(priv->dev, "EIP%d:%x(%d)-HIA:%x(%d,%d,%d),PE:%x,alg:%08x\n", +- peid, priv->hwconfig.hwver, hwctg, priv->hwconfig.hiaver, +- priv->hwconfig.hwdataw, priv->hwconfig.hwcfsize, +- priv->hwconfig.hwrfsize, priv->hwconfig.pever, ++ dev_info(priv->dev, "EIP%d:%x(%d,%d,%d,%d)-HIA:%x(%d,%d,%d),PE:%x/%x,alg:%08x\n", ++ peid, priv->hwconfig.hwver, hwctg, priv->hwconfig.hwnumpes, ++ priv->hwconfig.hwnumrings, priv->hwconfig.hwnumraic, ++ priv->hwconfig.hiaver, priv->hwconfig.hwdataw, ++ priv->hwconfig.hwcfsize, priv->hwconfig.hwrfsize, ++ priv->hwconfig.ppver, priv->hwconfig.pever, + priv->hwconfig.algo_flags); + + safexcel_configure(priv); +@@ -1547,7 +1676,6 @@ static void safexcel_hw_reset_rings(stru + } + } + +-#if IS_ENABLED(CONFIG_OF) + /* for Device Tree platform driver */ + + static int safexcel_probe(struct platform_device *pdev) +@@ -1625,6 +1753,7 @@ static int safexcel_remove(struct platfo + safexcel_unregister_algorithms(priv); + safexcel_hw_reset_rings(priv); + ++ clk_disable_unprepare(priv->reg_clk); + clk_disable_unprepare(priv->clk); + + for (i = 0; i < priv->config.rings; i++) +@@ -1666,9 +1795,7 @@ static struct platform_driver crypto_sa + .of_match_table = safexcel_of_match_table, + }, + }; +-#endif + +-#if IS_ENABLED(CONFIG_PCI) + /* PCIE devices - i.e. Inside Secure development boards */ + + static int safexcel_pci_probe(struct pci_dev *pdev, +@@ -1759,7 +1886,7 @@ static int safexcel_pci_probe(struct pci + return rc; + } + +-void safexcel_pci_remove(struct pci_dev *pdev) ++static void safexcel_pci_remove(struct pci_dev *pdev) + { + struct safexcel_crypto_priv *priv = pci_get_drvdata(pdev); + int i; +@@ -1789,54 +1916,32 @@ static struct pci_driver safexcel_pci_dr + .probe = safexcel_pci_probe, + .remove = safexcel_pci_remove, + }; +-#endif +- +-/* Unfortunately, we have to resort to global variables here */ +-#if IS_ENABLED(CONFIG_PCI) +-int pcireg_rc = -EINVAL; /* Default safe value */ +-#endif +-#if IS_ENABLED(CONFIG_OF) +-int ofreg_rc = -EINVAL; /* Default safe value */ +-#endif + + static int __init safexcel_init(void) + { +-#if IS_ENABLED(CONFIG_PCI) ++ int ret; ++ + /* Register PCI driver */ +- pcireg_rc = pci_register_driver(&safexcel_pci_driver); +-#endif ++ ret = pci_register_driver(&safexcel_pci_driver); + +-#if IS_ENABLED(CONFIG_OF) + /* Register platform driver */ +- ofreg_rc = platform_driver_register(&crypto_safexcel); +- #if IS_ENABLED(CONFIG_PCI) +- /* Return success if either PCI or OF registered OK */ +- return pcireg_rc ? ofreg_rc : 0; +- #else +- return ofreg_rc; +- #endif +-#else +- #if IS_ENABLED(CONFIG_PCI) +- return pcireg_rc; +- #else +- return -EINVAL; +- #endif +-#endif ++ if (IS_ENABLED(CONFIG_OF) && !ret) { ++ ret = platform_driver_register(&crypto_safexcel); ++ if (ret) ++ pci_unregister_driver(&safexcel_pci_driver); ++ } ++ ++ return ret; + } + + static void __exit safexcel_exit(void) + { +-#if IS_ENABLED(CONFIG_OF) + /* Unregister platform driver */ +- if (!ofreg_rc) ++ if (IS_ENABLED(CONFIG_OF)) + platform_driver_unregister(&crypto_safexcel); +-#endif + +-#if IS_ENABLED(CONFIG_PCI) + /* Unregister PCI driver if successfully registered before */ +- if (!pcireg_rc) +- pci_unregister_driver(&safexcel_pci_driver); +-#endif ++ pci_unregister_driver(&safexcel_pci_driver); + } + + module_init(safexcel_init); +--- a/drivers/crypto/inside-secure/safexcel_cipher.c ++++ b/drivers/crypto/inside-secure/safexcel_cipher.c +@@ -5,18 +5,22 @@ + * Antoine Tenart + */ + ++#include + #include + #include + #include +- + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include ++#include ++#include + #include + #include + #include +@@ -33,6 +37,8 @@ enum safexcel_cipher_alg { + SAFEXCEL_DES, + SAFEXCEL_3DES, + SAFEXCEL_AES, ++ SAFEXCEL_CHACHA20, ++ SAFEXCEL_SM4, + }; + + struct safexcel_cipher_ctx { +@@ -41,8 +47,12 @@ struct safexcel_cipher_ctx { + + u32 mode; + enum safexcel_cipher_alg alg; +- bool aead; +- int xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */ ++ u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */ ++ u8 xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */ ++ u8 aadskip; ++ u8 blocksz; ++ u32 ivmask; ++ u32 ctrinit; + + __le32 key[16]; + u32 nonce; +@@ -51,10 +61,11 @@ struct safexcel_cipher_ctx { + /* All the below is AEAD specific */ + u32 hash_alg; + u32 state_sz; +- u32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)]; +- u32 opad[SHA512_DIGEST_SIZE / sizeof(u32)]; ++ __be32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)]; ++ __be32 opad[SHA512_DIGEST_SIZE / sizeof(u32)]; + + struct crypto_cipher *hkaes; ++ struct crypto_aead *fback; + }; + + struct safexcel_cipher_req { +@@ -65,206 +76,298 @@ struct safexcel_cipher_req { + int nr_src, nr_dst; + }; + +-static void safexcel_cipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, +- struct safexcel_command_desc *cdesc) ++static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, ++ struct safexcel_command_desc *cdesc) + { +- u32 block_sz = 0; +- + if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { + cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; +- + /* 32 bit nonce */ + cdesc->control_data.token[0] = ctx->nonce; + /* 64 bit IV part */ + memcpy(&cdesc->control_data.token[1], iv, 8); +- /* 32 bit counter, start at 1 (big endian!) */ +- cdesc->control_data.token[3] = cpu_to_be32(1); +- +- return; +- } else if (ctx->xcm == EIP197_XCM_MODE_GCM) { +- cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; +- +- /* 96 bit IV part */ +- memcpy(&cdesc->control_data.token[0], iv, 12); +- /* 32 bit counter, start at 1 (big endian!) */ +- cdesc->control_data.token[3] = cpu_to_be32(1); +- +- return; +- } else if (ctx->xcm == EIP197_XCM_MODE_CCM) { ++ /* 32 bit counter, start at 0 or 1 (big endian!) */ ++ cdesc->control_data.token[3] = ++ (__force u32)cpu_to_be32(ctx->ctrinit); ++ return 4; ++ } ++ if (ctx->alg == SAFEXCEL_CHACHA20) { + cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; +- +- /* Variable length IV part */ +- memcpy(&cdesc->control_data.token[0], iv, 15 - iv[0]); +- /* Start variable length counter at 0 */ +- memset((u8 *)&cdesc->control_data.token[0] + 15 - iv[0], +- 0, iv[0] + 1); +- +- return; ++ /* 96 bit nonce part */ ++ memcpy(&cdesc->control_data.token[0], &iv[4], 12); ++ /* 32 bit counter */ ++ cdesc->control_data.token[3] = *(u32 *)iv; ++ return 4; + } + +- if (ctx->mode != CONTEXT_CONTROL_CRYPTO_MODE_ECB) { +- switch (ctx->alg) { +- case SAFEXCEL_DES: +- block_sz = DES_BLOCK_SIZE; +- cdesc->control_data.options |= EIP197_OPTION_2_TOKEN_IV_CMD; +- break; +- case SAFEXCEL_3DES: +- block_sz = DES3_EDE_BLOCK_SIZE; +- cdesc->control_data.options |= EIP197_OPTION_2_TOKEN_IV_CMD; +- break; +- case SAFEXCEL_AES: +- block_sz = AES_BLOCK_SIZE; +- cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; +- break; +- } +- memcpy(cdesc->control_data.token, iv, block_sz); +- } ++ cdesc->control_data.options |= ctx->ivmask; ++ memcpy(cdesc->control_data.token, iv, ctx->blocksz); ++ return ctx->blocksz / sizeof(u32); + } + + static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv, + struct safexcel_command_desc *cdesc, ++ struct safexcel_token *atoken, + u32 length) + { + struct safexcel_token *token; ++ int ivlen; + +- safexcel_cipher_token(ctx, iv, cdesc); +- +- /* skip over worst case IV of 4 dwords, no need to be exact */ +- token = (struct safexcel_token *)(cdesc->control_data.token + 4); ++ ivlen = safexcel_skcipher_iv(ctx, iv, cdesc); ++ if (ivlen == 4) { ++ /* No space in cdesc, instruction moves to atoken */ ++ cdesc->additional_cdata_size = 1; ++ token = atoken; ++ } else { ++ /* Everything fits in cdesc */ ++ token = (struct safexcel_token *)(cdesc->control_data.token + 2); ++ /* Need to pad with NOP */ ++ eip197_noop_token(&token[1]); ++ } ++ ++ token->opcode = EIP197_TOKEN_OPCODE_DIRECTION; ++ token->packet_length = length; ++ token->stat = EIP197_TOKEN_STAT_LAST_PACKET | ++ EIP197_TOKEN_STAT_LAST_HASH; ++ token->instructions = EIP197_TOKEN_INS_LAST | ++ EIP197_TOKEN_INS_TYPE_CRYPTO | ++ EIP197_TOKEN_INS_TYPE_OUTPUT; ++} + +- token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION; +- token[0].packet_length = length; +- token[0].stat = EIP197_TOKEN_STAT_LAST_PACKET | +- EIP197_TOKEN_STAT_LAST_HASH; +- token[0].instructions = EIP197_TOKEN_INS_LAST | +- EIP197_TOKEN_INS_TYPE_CRYPTO | +- EIP197_TOKEN_INS_TYPE_OUTPUT; ++static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv, ++ struct safexcel_command_desc *cdesc) ++{ ++ if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD || ++ ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */ ++ /* 32 bit nonce */ ++ cdesc->control_data.token[0] = ctx->nonce; ++ /* 64 bit IV part */ ++ memcpy(&cdesc->control_data.token[1], iv, 8); ++ /* 32 bit counter, start at 0 or 1 (big endian!) */ ++ cdesc->control_data.token[3] = ++ (__force u32)cpu_to_be32(ctx->ctrinit); ++ return; ++ } ++ if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) { ++ /* 96 bit IV part */ ++ memcpy(&cdesc->control_data.token[0], iv, 12); ++ /* 32 bit counter, start at 0 or 1 (big endian!) */ ++ cdesc->control_data.token[3] = ++ (__force u32)cpu_to_be32(ctx->ctrinit); ++ return; ++ } ++ /* CBC */ ++ memcpy(cdesc->control_data.token, iv, ctx->blocksz); + } + + static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv, + struct safexcel_command_desc *cdesc, ++ struct safexcel_token *atoken, + enum safexcel_cipher_direction direction, + u32 cryptlen, u32 assoclen, u32 digestsize) + { +- struct safexcel_token *token; ++ struct safexcel_token *aadref; ++ int atoksize = 2; /* Start with minimum size */ ++ int assocadj = assoclen - ctx->aadskip, aadalign; + +- safexcel_cipher_token(ctx, iv, cdesc); ++ /* Always 4 dwords of embedded IV for AEAD modes */ ++ cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD; + +- if (direction == SAFEXCEL_ENCRYPT) { +- /* align end of instruction sequence to end of token */ +- token = (struct safexcel_token *)(cdesc->control_data.token + +- EIP197_MAX_TOKENS - 13); +- +- token[12].opcode = EIP197_TOKEN_OPCODE_INSERT; +- token[12].packet_length = digestsize; +- token[12].stat = EIP197_TOKEN_STAT_LAST_HASH | +- EIP197_TOKEN_STAT_LAST_PACKET; +- token[12].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | +- EIP197_TOKEN_INS_INSERT_HASH_DIGEST; +- } else { ++ if (direction == SAFEXCEL_DECRYPT) + cryptlen -= digestsize; + +- /* align end of instruction sequence to end of token */ +- token = (struct safexcel_token *)(cdesc->control_data.token + +- EIP197_MAX_TOKENS - 14); +- +- token[12].opcode = EIP197_TOKEN_OPCODE_RETRIEVE; +- token[12].packet_length = digestsize; +- token[12].stat = EIP197_TOKEN_STAT_LAST_HASH | +- EIP197_TOKEN_STAT_LAST_PACKET; +- token[12].instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; +- +- token[13].opcode = EIP197_TOKEN_OPCODE_VERIFY; +- token[13].packet_length = digestsize | +- EIP197_TOKEN_HASH_RESULT_VERIFY; +- token[13].stat = EIP197_TOKEN_STAT_LAST_HASH | +- EIP197_TOKEN_STAT_LAST_PACKET; +- token[13].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; +- } +- +- token[6].opcode = EIP197_TOKEN_OPCODE_DIRECTION; +- token[6].packet_length = assoclen; +- +- if (likely(cryptlen)) { +- token[6].instructions = EIP197_TOKEN_INS_TYPE_HASH; +- +- token[10].opcode = EIP197_TOKEN_OPCODE_DIRECTION; +- token[10].packet_length = cryptlen; +- token[10].stat = EIP197_TOKEN_STAT_LAST_HASH; +- token[10].instructions = EIP197_TOKEN_INS_LAST | +- EIP197_TOKEN_INS_TYPE_CRYPTO | +- EIP197_TOKEN_INS_TYPE_HASH | +- EIP197_TOKEN_INS_TYPE_OUTPUT; +- } else if (ctx->xcm != EIP197_XCM_MODE_CCM) { +- token[6].stat = EIP197_TOKEN_STAT_LAST_HASH; +- token[6].instructions = EIP197_TOKEN_INS_LAST | +- EIP197_TOKEN_INS_TYPE_HASH; +- } +- +- if (!ctx->xcm) +- return; +- +- token[8].opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; +- token[8].packet_length = 0; +- token[8].instructions = AES_BLOCK_SIZE; +- +- token[9].opcode = EIP197_TOKEN_OPCODE_INSERT; +- token[9].packet_length = AES_BLOCK_SIZE; +- token[9].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | +- EIP197_TOKEN_INS_TYPE_CRYPTO; +- +- if (ctx->xcm == EIP197_XCM_MODE_GCM) { +- token[6].instructions = EIP197_TOKEN_INS_LAST | +- EIP197_TOKEN_INS_TYPE_HASH; +- } else { +- u8 *cbcmaciv = (u8 *)&token[1]; +- u32 *aadlen = (u32 *)&token[5]; +- ++ if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) { + /* Construct IV block B0 for the CBC-MAC */ +- token[0].opcode = EIP197_TOKEN_OPCODE_INSERT; +- token[0].packet_length = AES_BLOCK_SIZE + +- ((assoclen > 0) << 1); +- token[0].instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | +- EIP197_TOKEN_INS_TYPE_HASH; +- /* Variable length IV part */ +- memcpy(cbcmaciv, iv, 15 - iv[0]); +- /* fixup flags byte */ +- cbcmaciv[0] |= ((assoclen > 0) << 6) | ((digestsize - 2) << 2); +- /* Clear upper bytes of variable message length to 0 */ +- memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1); +- /* insert lower 2 bytes of message length */ +- cbcmaciv[14] = cryptlen >> 8; +- cbcmaciv[15] = cryptlen & 255; +- +- if (assoclen) { +- *aadlen = cpu_to_le32(cpu_to_be16(assoclen)); +- assoclen += 2; ++ u8 *final_iv = (u8 *)cdesc->control_data.token; ++ u8 *cbcmaciv = (u8 *)&atoken[1]; ++ __le32 *aadlen = (__le32 *)&atoken[5]; ++ ++ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { ++ /* Length + nonce */ ++ cdesc->control_data.token[0] = ctx->nonce; ++ /* Fixup flags byte */ ++ *(__le32 *)cbcmaciv = ++ cpu_to_le32(ctx->nonce | ++ ((assocadj > 0) << 6) | ++ ((digestsize - 2) << 2)); ++ /* 64 bit IV part */ ++ memcpy(&cdesc->control_data.token[1], iv, 8); ++ memcpy(cbcmaciv + 4, iv, 8); ++ /* Start counter at 0 */ ++ cdesc->control_data.token[3] = 0; ++ /* Message length */ ++ *(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen); ++ } else { ++ /* Variable length IV part */ ++ memcpy(final_iv, iv, 15 - iv[0]); ++ memcpy(cbcmaciv, iv, 15 - iv[0]); ++ /* Start variable length counter at 0 */ ++ memset(final_iv + 15 - iv[0], 0, iv[0] + 1); ++ memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1); ++ /* fixup flags byte */ ++ cbcmaciv[0] |= ((assocadj > 0) << 6) | ++ ((digestsize - 2) << 2); ++ /* insert lower 2 bytes of message length */ ++ cbcmaciv[14] = cryptlen >> 8; ++ cbcmaciv[15] = cryptlen & 255; ++ } ++ ++ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; ++ atoken->packet_length = AES_BLOCK_SIZE + ++ ((assocadj > 0) << 1); ++ atoken->stat = 0; ++ atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN | ++ EIP197_TOKEN_INS_TYPE_HASH; ++ ++ if (likely(assocadj)) { ++ *aadlen = cpu_to_le32((assocadj >> 8) | ++ (assocadj & 255) << 8); ++ atoken += 6; ++ atoksize += 7; ++ } else { ++ atoken += 5; ++ atoksize += 6; + } + +- token[6].instructions = EIP197_TOKEN_INS_TYPE_HASH; +- +- /* Align AAD data towards hash engine */ +- token[7].opcode = EIP197_TOKEN_OPCODE_INSERT; +- assoclen &= 15; +- token[7].packet_length = assoclen ? 16 - assoclen : 0; +- ++ /* Process AAD data */ ++ aadref = atoken; ++ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; ++ atoken->packet_length = assocadj; ++ atoken->stat = 0; ++ atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; ++ atoken++; ++ ++ /* For CCM only, align AAD data towards hash engine */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; ++ aadalign = (assocadj + 2) & 15; ++ atoken->packet_length = assocadj && aadalign ? ++ 16 - aadalign : ++ 0; + if (likely(cryptlen)) { +- token[7].instructions = EIP197_TOKEN_INS_TYPE_HASH; +- +- /* Align crypto data towards hash engine */ +- token[10].stat = 0; ++ atoken->stat = 0; ++ atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; ++ } else { ++ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; ++ atoken->instructions = EIP197_TOKEN_INS_LAST | ++ EIP197_TOKEN_INS_TYPE_HASH; ++ } ++ } else { ++ safexcel_aead_iv(ctx, iv, cdesc); + +- token[11].opcode = EIP197_TOKEN_OPCODE_INSERT; +- cryptlen &= 15; +- token[11].packet_length = cryptlen ? 16 - cryptlen : 0; +- token[11].stat = EIP197_TOKEN_STAT_LAST_HASH; +- token[11].instructions = EIP197_TOKEN_INS_TYPE_HASH; ++ /* Process AAD data */ ++ aadref = atoken; ++ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; ++ atoken->packet_length = assocadj; ++ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; ++ atoken->instructions = EIP197_TOKEN_INS_LAST | ++ EIP197_TOKEN_INS_TYPE_HASH; ++ } ++ atoken++; ++ ++ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { ++ /* For ESP mode (and not GMAC), skip over the IV */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; ++ atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE; ++ atoken->stat = 0; ++ atoken->instructions = 0; ++ atoken++; ++ atoksize++; ++ } else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 && ++ direction == SAFEXCEL_DECRYPT)) { ++ /* Poly-chacha decryption needs a dummy NOP here ... */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; ++ atoken->packet_length = 16; /* According to Op Manual */ ++ atoken->stat = 0; ++ atoken->instructions = 0; ++ atoken++; ++ atoksize++; ++ } ++ ++ if (ctx->xcm) { ++ /* For GCM and CCM, obtain enc(Y0) */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES; ++ atoken->packet_length = 0; ++ atoken->stat = 0; ++ atoken->instructions = AES_BLOCK_SIZE; ++ atoken++; ++ ++ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; ++ atoken->packet_length = AES_BLOCK_SIZE; ++ atoken->stat = 0; ++ atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | ++ EIP197_TOKEN_INS_TYPE_CRYPTO; ++ atoken++; ++ atoksize += 2; ++ } ++ ++ if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) { ++ /* Fixup stat field for AAD direction instruction */ ++ aadref->stat = 0; ++ ++ /* Process crypto data */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION; ++ atoken->packet_length = cryptlen; ++ ++ if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) { ++ /* Fixup instruction field for AAD dir instruction */ ++ aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH; ++ ++ /* Do not send to crypt engine in case of GMAC */ ++ atoken->instructions = EIP197_TOKEN_INS_LAST | ++ EIP197_TOKEN_INS_TYPE_HASH | ++ EIP197_TOKEN_INS_TYPE_OUTPUT; ++ } else { ++ atoken->instructions = EIP197_TOKEN_INS_LAST | ++ EIP197_TOKEN_INS_TYPE_CRYPTO | ++ EIP197_TOKEN_INS_TYPE_HASH | ++ EIP197_TOKEN_INS_TYPE_OUTPUT; ++ } ++ ++ cryptlen &= 15; ++ if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) { ++ atoken->stat = 0; ++ /* For CCM only, pad crypto data to the hash engine */ ++ atoken++; ++ atoksize++; ++ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; ++ atoken->packet_length = 16 - cryptlen; ++ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; ++ atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH; + } else { +- token[7].stat = EIP197_TOKEN_STAT_LAST_HASH; +- token[7].instructions = EIP197_TOKEN_INS_LAST | +- EIP197_TOKEN_INS_TYPE_HASH; ++ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH; + } ++ atoken++; ++ atoksize++; + } ++ ++ if (direction == SAFEXCEL_ENCRYPT) { ++ /* Append ICV */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_INSERT; ++ atoken->packet_length = digestsize; ++ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | ++ EIP197_TOKEN_STAT_LAST_PACKET; ++ atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | ++ EIP197_TOKEN_INS_INSERT_HASH_DIGEST; ++ } else { ++ /* Extract ICV */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE; ++ atoken->packet_length = digestsize; ++ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | ++ EIP197_TOKEN_STAT_LAST_PACKET; ++ atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST; ++ atoken++; ++ atoksize++; ++ ++ /* Verify ICV */ ++ atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY; ++ atoken->packet_length = digestsize | ++ EIP197_TOKEN_HASH_RESULT_VERIFY; ++ atoken->stat = EIP197_TOKEN_STAT_LAST_HASH | ++ EIP197_TOKEN_STAT_LAST_PACKET; ++ atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT; ++ } ++ ++ /* Fixup length of the token in the command descriptor */ ++ cdesc->additional_cdata_size = atoksize; + } + + static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, +@@ -277,14 +380,12 @@ static int safexcel_skcipher_aes_setkey( + int ret, i; + + ret = aes_expandkey(&aes, key, len); +- if (ret) { +- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ if (ret) + return ret; +- } + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < len / sizeof(u32); i++) { +- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) { ++ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { + ctx->base.needs_inv = true; + break; + } +@@ -309,43 +410,57 @@ static int safexcel_aead_setkey(struct c + struct safexcel_crypto_priv *priv = ctx->priv; + struct crypto_authenc_keys keys; + struct crypto_aes_ctx aes; +- int err = -EINVAL; ++ int err = -EINVAL, i; + +- if (crypto_authenc_extractkeys(&keys, key, len) != 0) ++ if (unlikely(crypto_authenc_extractkeys(&keys, key, len))) + goto badkey; + + if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) { +- /* Minimum keysize is minimum AES key size + nonce size */ +- if (keys.enckeylen < (AES_MIN_KEY_SIZE + +- CTR_RFC3686_NONCE_SIZE)) ++ /* Must have at least space for the nonce here */ ++ if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE)) + goto badkey; + /* last 4 bytes of key are the nonce! */ + ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen - + CTR_RFC3686_NONCE_SIZE); + /* exclude the nonce here */ +- keys.enckeylen -= CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; ++ keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; + } + + /* Encryption key */ + switch (ctx->alg) { ++ case SAFEXCEL_DES: ++ err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); ++ if (unlikely(err)) ++ goto badkey; ++ break; + case SAFEXCEL_3DES: + err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); + if (unlikely(err)) +- goto badkey_expflags; ++ goto badkey; + break; + case SAFEXCEL_AES: + err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); + if (unlikely(err)) + goto badkey; + break; ++ case SAFEXCEL_SM4: ++ if (unlikely(keys.enckeylen != SM4_KEY_SIZE)) ++ goto badkey; ++ break; + default: + dev_err(priv->dev, "aead: unsupported cipher algorithm\n"); + goto badkey; + } + +- if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma && +- memcmp(ctx->key, keys.enckey, keys.enckeylen)) +- ctx->base.needs_inv = true; ++ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { ++ for (i = 0; i < keys.enckeylen / sizeof(u32); i++) { ++ if (le32_to_cpu(ctx->key[i]) != ++ ((u32 *)keys.enckey)[i]) { ++ ctx->base.needs_inv = true; ++ break; ++ } ++ } ++ } + + /* Auth key */ + switch (ctx->hash_alg) { +@@ -374,21 +489,24 @@ static int safexcel_aead_setkey(struct c + keys.authkeylen, &istate, &ostate)) + goto badkey; + break; ++ case CONTEXT_CONTROL_CRYPTO_ALG_SM3: ++ if (safexcel_hmac_setkey("safexcel-sm3", keys.authkey, ++ keys.authkeylen, &istate, &ostate)) ++ goto badkey; ++ break; + default: + dev_err(priv->dev, "aead: unsupported hash algorithm\n"); + goto badkey; + } + +- crypto_aead_set_flags(ctfm, crypto_aead_get_flags(ctfm) & +- CRYPTO_TFM_RES_MASK); +- + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma && + (memcmp(ctx->ipad, istate.state, ctx->state_sz) || + memcmp(ctx->opad, ostate.state, ctx->state_sz))) + ctx->base.needs_inv = true; + + /* Now copy the keys into the context */ +- memcpy(ctx->key, keys.enckey, keys.enckeylen); ++ for (i = 0; i < keys.enckeylen / sizeof(u32); i++) ++ ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]); + ctx->key_len = keys.enckeylen; + + memcpy(ctx->ipad, &istate.state, ctx->state_sz); +@@ -398,8 +516,6 @@ static int safexcel_aead_setkey(struct c + return 0; + + badkey: +- crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); +-badkey_expflags: + memzero_explicit(&keys, sizeof(keys)); + return err; + } +@@ -423,6 +539,17 @@ static int safexcel_context_control(stru + CONTEXT_CONTROL_DIGEST_XCM | + ctx->hash_alg | + CONTEXT_CONTROL_SIZE(ctrl_size); ++ } else if (ctx->alg == SAFEXCEL_CHACHA20) { ++ /* Chacha20-Poly1305 */ ++ cdesc->control_data.control0 = ++ CONTEXT_CONTROL_KEY_EN | ++ CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 | ++ (sreq->direction == SAFEXCEL_ENCRYPT ? ++ CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT : ++ CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) | ++ ctx->hash_alg | ++ CONTEXT_CONTROL_SIZE(ctrl_size); ++ return 0; + } else { + ctrl_size += ctx->state_sz / sizeof(u32) * 2; + cdesc->control_data.control0 = +@@ -431,17 +558,21 @@ static int safexcel_context_control(stru + ctx->hash_alg | + CONTEXT_CONTROL_SIZE(ctrl_size); + } +- if (sreq->direction == SAFEXCEL_ENCRYPT) +- cdesc->control_data.control0 |= +- (ctx->xcm == EIP197_XCM_MODE_CCM) ? +- CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT : +- CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; + ++ if (sreq->direction == SAFEXCEL_ENCRYPT && ++ (ctx->xcm == EIP197_XCM_MODE_CCM || ++ ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) ++ cdesc->control_data.control0 |= ++ CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT; ++ else if (sreq->direction == SAFEXCEL_ENCRYPT) ++ cdesc->control_data.control0 |= ++ CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT; ++ else if (ctx->xcm == EIP197_XCM_MODE_CCM) ++ cdesc->control_data.control0 |= ++ CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN; + else + cdesc->control_data.control0 |= +- (ctx->xcm == EIP197_XCM_MODE_CCM) ? +- CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN : +- CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; ++ CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN; + } else { + if (sreq->direction == SAFEXCEL_ENCRYPT) + cdesc->control_data.control0 = +@@ -480,6 +611,12 @@ static int safexcel_context_control(stru + ctx->key_len >> ctx->xts); + return -EINVAL; + } ++ } else if (ctx->alg == SAFEXCEL_CHACHA20) { ++ cdesc->control_data.control0 |= ++ CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20; ++ } else if (ctx->alg == SAFEXCEL_SM4) { ++ cdesc->control_data.control0 |= ++ CONTEXT_CONTROL_CRYPTO_ALG_SM4; + } + + return 0; +@@ -563,6 +700,7 @@ static int safexcel_send_req(struct cryp + unsigned int totlen; + unsigned int totlen_src = cryptlen + assoclen; + unsigned int totlen_dst = totlen_src; ++ struct safexcel_token *atoken; + int n_cdesc = 0, n_rdesc = 0; + int queued, i, ret = 0; + bool first = true; +@@ -637,56 +775,60 @@ static int safexcel_send_req(struct cryp + + memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); + +- /* The EIP cannot deal with zero length input packets! */ +- if (totlen == 0) +- totlen = 1; ++ if (!totlen) { ++ /* ++ * The EIP97 cannot deal with zero length input packets! ++ * So stuff a dummy command descriptor indicating a 1 byte ++ * (dummy) input packet, using the context record as source. ++ */ ++ first_cdesc = safexcel_add_cdesc(priv, ring, ++ 1, 1, ctx->base.ctxr_dma, ++ 1, 1, ctx->base.ctxr_dma, ++ &atoken); ++ if (IS_ERR(first_cdesc)) { ++ /* No space left in the command descriptor ring */ ++ ret = PTR_ERR(first_cdesc); ++ goto cdesc_rollback; ++ } ++ n_cdesc = 1; ++ goto skip_cdesc; ++ } + + /* command descriptors */ + for_each_sg(src, sg, sreq->nr_src, i) { + int len = sg_dma_len(sg); + + /* Do not overflow the request */ +- if (queued - len < 0) ++ if (queued < len) + len = queued; + + cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, + !(queued - len), + sg_dma_address(sg), len, totlen, +- ctx->base.ctxr_dma); ++ ctx->base.ctxr_dma, &atoken); + if (IS_ERR(cdesc)) { + /* No space left in the command descriptor ring */ + ret = PTR_ERR(cdesc); + goto cdesc_rollback; + } +- n_cdesc++; + +- if (n_cdesc == 1) { ++ if (!n_cdesc) + first_cdesc = cdesc; +- } + ++ n_cdesc++; + queued -= len; + if (!queued) + break; + } +- +- if (unlikely(!n_cdesc)) { +- /* +- * Special case: zero length input buffer. +- * The engine always needs the 1st command descriptor, however! +- */ +- first_cdesc = safexcel_add_cdesc(priv, ring, 1, 1, 0, 0, totlen, +- ctx->base.ctxr_dma); +- n_cdesc = 1; +- } +- ++skip_cdesc: + /* Add context control words and token to first command descriptor */ + safexcel_context_control(ctx, base, sreq, first_cdesc); + if (ctx->aead) +- safexcel_aead_token(ctx, iv, first_cdesc, ++ safexcel_aead_token(ctx, iv, first_cdesc, atoken, + sreq->direction, cryptlen, + assoclen, digestsize); + else +- safexcel_skcipher_token(ctx, iv, first_cdesc, ++ safexcel_skcipher_token(ctx, iv, first_cdesc, atoken, + cryptlen); + + /* result descriptors */ +@@ -1073,6 +1215,8 @@ static int safexcel_skcipher_cra_init(st + + ctx->base.send = safexcel_skcipher_send; + ctx->base.handle_result = safexcel_skcipher_handle_result; ++ ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; ++ ctx->ctrinit = 1; + return 0; + } + +@@ -1137,6 +1281,8 @@ static int safexcel_skcipher_aes_ecb_cra + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_AES; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; ++ ctx->blocksz = 0; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; + return 0; + } + +@@ -1171,6 +1317,7 @@ static int safexcel_skcipher_aes_cbc_cra + + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_AES; ++ ctx->blocksz = AES_BLOCK_SIZE; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; + return 0; + } +@@ -1207,6 +1354,7 @@ static int safexcel_skcipher_aes_cfb_cra + + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_AES; ++ ctx->blocksz = AES_BLOCK_SIZE; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; + return 0; + } +@@ -1243,6 +1391,7 @@ static int safexcel_skcipher_aes_ofb_cra + + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_AES; ++ ctx->blocksz = AES_BLOCK_SIZE; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; + return 0; + } +@@ -1288,14 +1437,12 @@ static int safexcel_skcipher_aesctr_setk + /* exclude the nonce here */ + keylen = len - CTR_RFC3686_NONCE_SIZE; + ret = aes_expandkey(&aes, key, keylen); +- if (ret) { +- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ if (ret) + return ret; +- } + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < keylen / sizeof(u32); i++) { +- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) { ++ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { + ctx->base.needs_inv = true; + break; + } +@@ -1317,6 +1464,7 @@ static int safexcel_skcipher_aes_ctr_cra + + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_AES; ++ ctx->blocksz = AES_BLOCK_SIZE; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; + return 0; + } +@@ -1352,6 +1500,7 @@ static int safexcel_des_setkey(struct cr + unsigned int len) + { + struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); ++ struct safexcel_crypto_priv *priv = ctx->priv; + int ret; + + ret = verify_skcipher_des_key(ctfm, key); +@@ -1359,7 +1508,7 @@ static int safexcel_des_setkey(struct cr + return ret; + + /* if context exits and key changed, need to invalidate it */ +- if (ctx->base.ctxr_dma) ++ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) + if (memcmp(ctx->key, key, len)) + ctx->base.needs_inv = true; + +@@ -1375,6 +1524,8 @@ static int safexcel_skcipher_des_cbc_cra + + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_DES; ++ ctx->blocksz = DES_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; + return 0; + } +@@ -1412,6 +1563,8 @@ static int safexcel_skcipher_des_ecb_cra + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_DES; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; ++ ctx->blocksz = 0; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; + return 0; + } + +@@ -1444,6 +1597,7 @@ static int safexcel_des3_ede_setkey(stru + const u8 *key, unsigned int len) + { + struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); ++ struct safexcel_crypto_priv *priv = ctx->priv; + int err; + + err = verify_skcipher_des3_key(ctfm, key); +@@ -1451,13 +1605,11 @@ static int safexcel_des3_ede_setkey(stru + return err; + + /* if context exits and key changed, need to invalidate it */ +- if (ctx->base.ctxr_dma) { ++ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) + if (memcmp(ctx->key, key, len)) + ctx->base.needs_inv = true; +- } + + memcpy(ctx->key, key, len); +- + ctx->key_len = len; + + return 0; +@@ -1469,6 +1621,8 @@ static int safexcel_skcipher_des3_cbc_cr + + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_3DES; ++ ctx->blocksz = DES3_EDE_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; + return 0; + } +@@ -1506,6 +1660,8 @@ static int safexcel_skcipher_des3_ecb_cr + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_3DES; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; ++ ctx->blocksz = 0; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; + return 0; + } + +@@ -1561,6 +1717,9 @@ static int safexcel_aead_cra_init(struct + ctx->priv = tmpl->priv; + + ctx->alg = SAFEXCEL_AES; /* default */ ++ ctx->blocksz = AES_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD; ++ ctx->ctrinit = 1; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */ + ctx->aead = true; + ctx->base.send = safexcel_aead_send; +@@ -1749,6 +1908,8 @@ static int safexcel_aead_sha1_des3_cra_i + + safexcel_aead_sha1_cra_init(tfm); + ctx->alg = SAFEXCEL_3DES; /* override default */ ++ ctx->blocksz = DES3_EDE_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; + return 0; + } + +@@ -1777,6 +1938,330 @@ struct safexcel_alg_template safexcel_al + }, + }; + ++static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha256_cra_init(tfm); ++ ctx->alg = SAFEXCEL_3DES; /* override default */ ++ ctx->blocksz = DES3_EDE_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .maxauthsize = SHA256_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha256_des3_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha224_cra_init(tfm); ++ ctx->alg = SAFEXCEL_3DES; /* override default */ ++ ctx->blocksz = DES3_EDE_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .maxauthsize = SHA224_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha224_des3_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha512_cra_init(tfm); ++ ctx->alg = SAFEXCEL_3DES; /* override default */ ++ ctx->blocksz = DES3_EDE_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .maxauthsize = SHA512_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha512),cbc(des3_ede))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha512_des3_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha384_cra_init(tfm); ++ ctx->alg = SAFEXCEL_3DES; /* override default */ ++ ctx->blocksz = DES3_EDE_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .maxauthsize = SHA384_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha384),cbc(des3_ede))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha384_des3_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha1_cra_init(tfm); ++ ctx->alg = SAFEXCEL_DES; /* override default */ ++ ctx->blocksz = DES_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .maxauthsize = SHA1_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha1),cbc(des))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha1_des_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha256_cra_init(tfm); ++ ctx->alg = SAFEXCEL_DES; /* override default */ ++ ctx->blocksz = DES_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .maxauthsize = SHA256_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha256),cbc(des))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha256_des_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha224_cra_init(tfm); ++ ctx->alg = SAFEXCEL_DES; /* override default */ ++ ctx->blocksz = DES_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .maxauthsize = SHA224_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha224),cbc(des))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha224_des_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha512_cra_init(tfm); ++ ctx->alg = SAFEXCEL_DES; /* override default */ ++ ctx->blocksz = DES_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .maxauthsize = SHA512_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha512),cbc(des))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha512_des_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sha384_cra_init(tfm); ++ ctx->alg = SAFEXCEL_DES; /* override default */ ++ ctx->blocksz = DES_BLOCK_SIZE; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .maxauthsize = SHA384_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha384),cbc(des))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sha384_des_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ + static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm) + { + struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); +@@ -1965,14 +2450,12 @@ static int safexcel_skcipher_aesxts_setk + /* Only half of the key data is cipher key */ + keylen = (len >> 1); + ret = aes_expandkey(&aes, key, keylen); +- if (ret) { +- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ if (ret) + return ret; +- } + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < keylen / sizeof(u32); i++) { +- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) { ++ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { + ctx->base.needs_inv = true; + break; + } +@@ -1984,15 +2467,13 @@ static int safexcel_skcipher_aesxts_setk + + /* The other half is the tweak key */ + ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen); +- if (ret) { +- crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ if (ret) + return ret; +- } + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < keylen / sizeof(u32); i++) { +- if (ctx->key[i + keylen / sizeof(u32)] != +- cpu_to_le32(aes.key_enc[i])) { ++ if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) != ++ aes.key_enc[i]) { + ctx->base.needs_inv = true; + break; + } +@@ -2015,6 +2496,7 @@ static int safexcel_skcipher_aes_xts_cra + + safexcel_skcipher_cra_init(tfm); + ctx->alg = SAFEXCEL_AES; ++ ctx->blocksz = AES_BLOCK_SIZE; + ctx->xts = 1; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS; + return 0; +@@ -2075,14 +2557,13 @@ static int safexcel_aead_gcm_setkey(stru + + ret = aes_expandkey(&aes, key, len); + if (ret) { +- crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + memzero_explicit(&aes, sizeof(aes)); + return ret; + } + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < len / sizeof(u32); i++) { +- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) { ++ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { + ctx->base.needs_inv = true; + break; + } +@@ -2099,8 +2580,6 @@ static int safexcel_aead_gcm_setkey(stru + crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) & + CRYPTO_TFM_REQ_MASK); + ret = crypto_cipher_setkey(ctx->hkaes, key, len); +- crypto_aead_set_flags(ctfm, crypto_cipher_get_flags(ctx->hkaes) & +- CRYPTO_TFM_RES_MASK); + if (ret) + return ret; + +@@ -2109,7 +2588,7 @@ static int safexcel_aead_gcm_setkey(stru + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) { +- if (ctx->ipad[i] != cpu_to_be32(hashkey[i])) { ++ if (be32_to_cpu(ctx->ipad[i]) != hashkey[i]) { + ctx->base.needs_inv = true; + break; + } +@@ -2135,10 +2614,7 @@ static int safexcel_aead_gcm_cra_init(st + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ + + ctx->hkaes = crypto_alloc_cipher("aes", 0, 0); +- if (IS_ERR(ctx->hkaes)) +- return PTR_ERR(ctx->hkaes); +- +- return 0; ++ return PTR_ERR_OR_ZERO(ctx->hkaes); + } + + static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm) +@@ -2192,14 +2668,13 @@ static int safexcel_aead_ccm_setkey(stru + + ret = aes_expandkey(&aes, key, len); + if (ret) { +- crypto_aead_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + memzero_explicit(&aes, sizeof(aes)); + return ret; + } + + if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) { + for (i = 0; i < len / sizeof(u32); i++) { +- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) { ++ if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) { + ctx->base.needs_inv = true; + break; + } +@@ -2235,6 +2710,7 @@ static int safexcel_aead_ccm_cra_init(st + ctx->state_sz = 3 * AES_BLOCK_SIZE; + ctx->xcm = EIP197_XCM_MODE_CCM; + ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */ ++ ctx->ctrinit = 0; + return 0; + } + +@@ -2301,5 +2777,949 @@ struct safexcel_alg_template safexcel_al + .cra_exit = safexcel_aead_cra_exit, + .cra_module = THIS_MODULE, + }, ++ }, ++}; ++ ++static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx, ++ const u8 *key) ++{ ++ struct safexcel_crypto_priv *priv = ctx->priv; ++ ++ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) ++ if (memcmp(ctx->key, key, CHACHA_KEY_SIZE)) ++ ctx->base.needs_inv = true; ++ ++ memcpy(ctx->key, key, CHACHA_KEY_SIZE); ++ ctx->key_len = CHACHA_KEY_SIZE; ++} ++ ++static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm, ++ const u8 *key, unsigned int len) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm); ++ ++ if (len != CHACHA_KEY_SIZE) ++ return -EINVAL; ++ ++ safexcel_chacha20_setkey(ctx, key); ++ ++ return 0; ++} ++ ++static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_skcipher_cra_init(tfm); ++ ctx->alg = SAFEXCEL_CHACHA20; ++ ctx->ctrinit = 0; ++ ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_chacha20 = { ++ .type = SAFEXCEL_ALG_TYPE_SKCIPHER, ++ .algo_mask = SAFEXCEL_ALG_CHACHA20, ++ .alg.skcipher = { ++ .setkey = safexcel_skcipher_chacha20_setkey, ++ .encrypt = safexcel_encrypt, ++ .decrypt = safexcel_decrypt, ++ .min_keysize = CHACHA_KEY_SIZE, ++ .max_keysize = CHACHA_KEY_SIZE, ++ .ivsize = CHACHA_IV_SIZE, ++ .base = { ++ .cra_name = "chacha20", ++ .cra_driver_name = "safexcel-chacha20", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_skcipher_chacha20_cra_init, ++ .cra_exit = safexcel_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm, ++ const u8 *key, unsigned int len) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm); ++ ++ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP && ++ len > EIP197_AEAD_IPSEC_NONCE_SIZE) { ++ /* ESP variant has nonce appended to key */ ++ len -= EIP197_AEAD_IPSEC_NONCE_SIZE; ++ ctx->nonce = *(u32 *)(key + len); ++ } ++ if (len != CHACHA_KEY_SIZE) ++ return -EINVAL; ++ ++ safexcel_chacha20_setkey(ctx, key); ++ ++ return 0; ++} ++ ++static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm, ++ unsigned int authsize) ++{ ++ if (authsize != POLY1305_DIGEST_SIZE) ++ return -EINVAL; ++ return 0; ++} ++ ++static int safexcel_aead_chachapoly_crypt(struct aead_request *req, ++ enum safexcel_cipher_direction dir) ++{ ++ struct safexcel_cipher_req *creq = aead_request_ctx(req); ++ struct crypto_aead *aead = crypto_aead_reqtfm(req); ++ struct crypto_tfm *tfm = crypto_aead_tfm(aead); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct aead_request *subreq = aead_request_ctx(req); ++ u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1]; ++ int ret = 0; ++ ++ /* ++ * Instead of wasting time detecting umpteen silly corner cases, ++ * just dump all "small" requests to the fallback implementation. ++ * HW would not be faster on such small requests anyway. ++ */ ++ if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP || ++ req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) && ++ req->cryptlen > POLY1305_DIGEST_SIZE)) { ++ return safexcel_queue_req(&req->base, creq, dir); ++ } ++ ++ /* HW cannot do full (AAD+payload) zero length, use fallback */ ++ memcpy(key, ctx->key, CHACHA_KEY_SIZE); ++ if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) { ++ /* ESP variant has nonce appended to the key */ ++ key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce; ++ ret = crypto_aead_setkey(ctx->fback, (u8 *)key, ++ CHACHA_KEY_SIZE + ++ EIP197_AEAD_IPSEC_NONCE_SIZE); ++ } else { ++ ret = crypto_aead_setkey(ctx->fback, (u8 *)key, ++ CHACHA_KEY_SIZE); ++ } ++ if (ret) { ++ crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK); ++ crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) & ++ CRYPTO_TFM_REQ_MASK); ++ return ret; ++ } ++ ++ aead_request_set_tfm(subreq, ctx->fback); ++ aead_request_set_callback(subreq, req->base.flags, req->base.complete, ++ req->base.data); ++ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, ++ req->iv); ++ aead_request_set_ad(subreq, req->assoclen); ++ ++ return (dir == SAFEXCEL_ENCRYPT) ? ++ crypto_aead_encrypt(subreq) : ++ crypto_aead_decrypt(subreq); ++} ++ ++static int safexcel_aead_chachapoly_encrypt(struct aead_request *req) ++{ ++ return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT); ++} ++ ++static int safexcel_aead_chachapoly_decrypt(struct aead_request *req) ++{ ++ return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT); ++} ++ ++static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm) ++{ ++ struct crypto_aead *aead = __crypto_aead_cast(tfm); ++ struct aead_alg *alg = crypto_aead_alg(aead); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_cra_init(tfm); ++ ++ /* Allocate fallback implementation */ ++ ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0, ++ CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fback)) ++ return PTR_ERR(ctx->fback); ++ ++ crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req), ++ sizeof(struct aead_request) + ++ crypto_aead_reqsize(ctx->fback))); ++ ++ return 0; ++} ++ ++static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_fallback_cra_init(tfm); ++ ctx->alg = SAFEXCEL_CHACHA20; ++ ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 | ++ CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK; ++ ctx->ctrinit = 0; ++ ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305; ++ ctx->state_sz = 0; /* Precomputed by HW */ ++ return 0; ++} ++ ++static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ crypto_free_aead(ctx->fback); ++ safexcel_aead_cra_exit(tfm); ++} ++ ++struct safexcel_alg_template safexcel_alg_chachapoly = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, ++ .alg.aead = { ++ .setkey = safexcel_aead_chachapoly_setkey, ++ .setauthsize = safexcel_aead_chachapoly_setauthsize, ++ .encrypt = safexcel_aead_chachapoly_encrypt, ++ .decrypt = safexcel_aead_chachapoly_decrypt, ++ .ivsize = CHACHAPOLY_IV_SIZE, ++ .maxauthsize = POLY1305_DIGEST_SIZE, ++ .base = { ++ .cra_name = "rfc7539(chacha20,poly1305)", ++ .cra_driver_name = "safexcel-chacha20-poly1305", ++ /* +1 to put it above HW chacha + SW poly */ ++ .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_chachapoly_cra_init, ++ .cra_exit = safexcel_aead_fallback_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ int ret; ++ ++ ret = safexcel_aead_chachapoly_cra_init(tfm); ++ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; ++ ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; ++ return ret; ++} ++ ++struct safexcel_alg_template safexcel_alg_chachapoly_esp = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305, ++ .alg.aead = { ++ .setkey = safexcel_aead_chachapoly_setkey, ++ .setauthsize = safexcel_aead_chachapoly_setauthsize, ++ .encrypt = safexcel_aead_chachapoly_encrypt, ++ .decrypt = safexcel_aead_chachapoly_decrypt, ++ .ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE, ++ .maxauthsize = POLY1305_DIGEST_SIZE, ++ .base = { ++ .cra_name = "rfc7539esp(chacha20,poly1305)", ++ .cra_driver_name = "safexcel-chacha20-poly1305-esp", ++ /* +1 to put it above HW chacha + SW poly */ ++ .cra_priority = SAFEXCEL_CRA_PRIORITY + 1, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_chachapolyesp_cra_init, ++ .cra_exit = safexcel_aead_fallback_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm, ++ const u8 *key, unsigned int len) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct safexcel_crypto_priv *priv = ctx->priv; ++ ++ if (len != SM4_KEY_SIZE) ++ return -EINVAL; ++ ++ if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) ++ if (memcmp(ctx->key, key, SM4_KEY_SIZE)) ++ ctx->base.needs_inv = true; ++ ++ memcpy(ctx->key, key, SM4_KEY_SIZE); ++ ctx->key_len = SM4_KEY_SIZE; ++ ++ return 0; ++} ++ ++static int safexcel_sm4_blk_encrypt(struct skcipher_request *req) ++{ ++ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ ++ if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) ++ return -EINVAL; ++ else ++ return safexcel_queue_req(&req->base, skcipher_request_ctx(req), ++ SAFEXCEL_ENCRYPT); ++} ++ ++static int safexcel_sm4_blk_decrypt(struct skcipher_request *req) ++{ ++ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ ++ if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) ++ return -EINVAL; ++ else ++ return safexcel_queue_req(&req->base, skcipher_request_ctx(req), ++ SAFEXCEL_DECRYPT); ++} ++ ++static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_skcipher_cra_init(tfm); ++ ctx->alg = SAFEXCEL_SM4; ++ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB; ++ ctx->blocksz = 0; ++ ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_ecb_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_SKCIPHER, ++ .algo_mask = SAFEXCEL_ALG_SM4, ++ .alg.skcipher = { ++ .setkey = safexcel_skcipher_sm4_setkey, ++ .encrypt = safexcel_sm4_blk_encrypt, ++ .decrypt = safexcel_sm4_blk_decrypt, ++ .min_keysize = SM4_KEY_SIZE, ++ .max_keysize = SM4_KEY_SIZE, ++ .base = { ++ .cra_name = "ecb(sm4)", ++ .cra_driver_name = "safexcel-ecb-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = SM4_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_skcipher_sm4_ecb_cra_init, ++ .cra_exit = safexcel_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_skcipher_cra_init(tfm); ++ ctx->alg = SAFEXCEL_SM4; ++ ctx->blocksz = SM4_BLOCK_SIZE; ++ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_cbc_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_SKCIPHER, ++ .algo_mask = SAFEXCEL_ALG_SM4, ++ .alg.skcipher = { ++ .setkey = safexcel_skcipher_sm4_setkey, ++ .encrypt = safexcel_sm4_blk_encrypt, ++ .decrypt = safexcel_sm4_blk_decrypt, ++ .min_keysize = SM4_KEY_SIZE, ++ .max_keysize = SM4_KEY_SIZE, ++ .ivsize = SM4_BLOCK_SIZE, ++ .base = { ++ .cra_name = "cbc(sm4)", ++ .cra_driver_name = "safexcel-cbc-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = SM4_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_skcipher_sm4_cbc_cra_init, ++ .cra_exit = safexcel_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_skcipher_cra_init(tfm); ++ ctx->alg = SAFEXCEL_SM4; ++ ctx->blocksz = SM4_BLOCK_SIZE; ++ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_ofb_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_SKCIPHER, ++ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, ++ .alg.skcipher = { ++ .setkey = safexcel_skcipher_sm4_setkey, ++ .encrypt = safexcel_encrypt, ++ .decrypt = safexcel_decrypt, ++ .min_keysize = SM4_KEY_SIZE, ++ .max_keysize = SM4_KEY_SIZE, ++ .ivsize = SM4_BLOCK_SIZE, ++ .base = { ++ .cra_name = "ofb(sm4)", ++ .cra_driver_name = "safexcel-ofb-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_skcipher_sm4_ofb_cra_init, ++ .cra_exit = safexcel_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_skcipher_cra_init(tfm); ++ ctx->alg = SAFEXCEL_SM4; ++ ctx->blocksz = SM4_BLOCK_SIZE; ++ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_cfb_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_SKCIPHER, ++ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB, ++ .alg.skcipher = { ++ .setkey = safexcel_skcipher_sm4_setkey, ++ .encrypt = safexcel_encrypt, ++ .decrypt = safexcel_decrypt, ++ .min_keysize = SM4_KEY_SIZE, ++ .max_keysize = SM4_KEY_SIZE, ++ .ivsize = SM4_BLOCK_SIZE, ++ .base = { ++ .cra_name = "cfb(sm4)", ++ .cra_driver_name = "safexcel-cfb-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_skcipher_sm4_cfb_cra_init, ++ .cra_exit = safexcel_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm, ++ const u8 *key, unsigned int len) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ /* last 4 bytes of key are the nonce! */ ++ ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); ++ /* exclude the nonce here */ ++ len -= CTR_RFC3686_NONCE_SIZE; ++ ++ return safexcel_skcipher_sm4_setkey(ctfm, key, len); ++} ++ ++static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_skcipher_cra_init(tfm); ++ ctx->alg = SAFEXCEL_SM4; ++ ctx->blocksz = SM4_BLOCK_SIZE; ++ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_ctr_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_SKCIPHER, ++ .algo_mask = SAFEXCEL_ALG_SM4, ++ .alg.skcipher = { ++ .setkey = safexcel_skcipher_sm4ctr_setkey, ++ .encrypt = safexcel_encrypt, ++ .decrypt = safexcel_decrypt, ++ /* Add nonce size */ ++ .min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .base = { ++ .cra_name = "rfc3686(ctr(sm4))", ++ .cra_driver_name = "safexcel-ctr-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_skcipher_sm4_ctr_cra_init, ++ .cra_exit = safexcel_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req) ++{ ++ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ ++ if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) ++ return -EINVAL; ++ ++ return safexcel_queue_req(&req->base, aead_request_ctx(req), ++ SAFEXCEL_ENCRYPT); ++} ++ ++static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req) ++{ ++ struct crypto_aead *tfm = crypto_aead_reqtfm(req); ++ ++ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ ++ if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) ++ return -EINVAL; ++ ++ return safexcel_queue_req(&req->base, aead_request_ctx(req), ++ SAFEXCEL_DECRYPT); ++} ++ ++static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_cra_init(tfm); ++ ctx->alg = SAFEXCEL_SM4; ++ ctx->blocksz = SM4_BLOCK_SIZE; ++ ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; ++ ctx->state_sz = SHA1_DIGEST_SIZE; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_sm4_blk_encrypt, ++ .decrypt = safexcel_aead_sm4_blk_decrypt, ++ .ivsize = SM4_BLOCK_SIZE, ++ .maxauthsize = SHA1_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha1),cbc(sm4))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = SM4_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sm4cbc_sha1_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm, ++ const u8 *key, unsigned int len) ++{ ++ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ /* Keep fallback cipher synchronized */ ++ return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?: ++ safexcel_aead_setkey(ctfm, key, len); ++} ++ ++static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm, ++ unsigned int authsize) ++{ ++ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ /* Keep fallback cipher synchronized */ ++ return crypto_aead_setauthsize(ctx->fback, authsize); ++} ++ ++static int safexcel_aead_fallback_crypt(struct aead_request *req, ++ enum safexcel_cipher_direction dir) ++{ ++ struct crypto_aead *aead = crypto_aead_reqtfm(req); ++ struct crypto_tfm *tfm = crypto_aead_tfm(aead); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct aead_request *subreq = aead_request_ctx(req); ++ ++ aead_request_set_tfm(subreq, ctx->fback); ++ aead_request_set_callback(subreq, req->base.flags, req->base.complete, ++ req->base.data); ++ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, ++ req->iv); ++ aead_request_set_ad(subreq, req->assoclen); ++ ++ return (dir == SAFEXCEL_ENCRYPT) ? ++ crypto_aead_encrypt(subreq) : ++ crypto_aead_decrypt(subreq); ++} ++ ++static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req) ++{ ++ struct safexcel_cipher_req *creq = aead_request_ctx(req); ++ ++ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ ++ if (req->cryptlen & (SM4_BLOCK_SIZE - 1)) ++ return -EINVAL; ++ else if (req->cryptlen || req->assoclen) /* If input length > 0 only */ ++ return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); ++ ++ /* HW cannot do full (AAD+payload) zero length, use fallback */ ++ return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT); ++} ++ ++static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req) ++{ ++ struct safexcel_cipher_req *creq = aead_request_ctx(req); ++ struct crypto_aead *tfm = crypto_aead_reqtfm(req); ++ ++ /* Workaround for HW bug: EIP96 4.3 does not report blocksize error */ ++ if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1)) ++ return -EINVAL; ++ else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen) ++ /* If input length > 0 only */ ++ return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); ++ ++ /* HW cannot do full (AAD+payload) zero length, use fallback */ ++ return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT); ++} ++ ++static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_fallback_cra_init(tfm); ++ ctx->alg = SAFEXCEL_SM4; ++ ctx->blocksz = SM4_BLOCK_SIZE; ++ ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; ++ ctx->state_sz = SM3_DIGEST_SIZE; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, ++ .alg.aead = { ++ .setkey = safexcel_aead_fallback_setkey, ++ .setauthsize = safexcel_aead_fallback_setauthsize, ++ .encrypt = safexcel_aead_sm4cbc_sm3_encrypt, ++ .decrypt = safexcel_aead_sm4cbc_sm3_decrypt, ++ .ivsize = SM4_BLOCK_SIZE, ++ .maxauthsize = SM3_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sm3),cbc(sm4))", ++ .cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SM4_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sm4cbc_sm3_cra_init, ++ .cra_exit = safexcel_aead_fallback_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sm4cbc_sha1_cra_init(tfm); ++ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .maxauthsize = SHA1_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))", ++ .cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sm4ctr_sha1_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_aead_sm4cbc_sm3_cra_init(tfm); ++ ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3, ++ .alg.aead = { ++ .setkey = safexcel_aead_setkey, ++ .encrypt = safexcel_aead_encrypt, ++ .decrypt = safexcel_aead_decrypt, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .maxauthsize = SM3_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))", ++ .cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_aead_sm4ctr_sm3_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, ++ unsigned int len) ++{ ++ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ /* last 4 bytes of key are the nonce! */ ++ ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE); ++ ++ len -= CTR_RFC3686_NONCE_SIZE; ++ return safexcel_aead_gcm_setkey(ctfm, key, len); ++} ++ ++static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm, ++ unsigned int authsize) ++{ ++ return crypto_rfc4106_check_authsize(authsize); ++} ++ ++static int safexcel_rfc4106_encrypt(struct aead_request *req) ++{ ++ return crypto_ipsec_check_assoclen(req->assoclen) ?: ++ safexcel_aead_encrypt(req); ++} ++ ++static int safexcel_rfc4106_decrypt(struct aead_request *req) ++{ ++ return crypto_ipsec_check_assoclen(req->assoclen) ?: ++ safexcel_aead_decrypt(req); ++} ++ ++static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ int ret; ++ ++ ret = safexcel_aead_gcm_cra_init(tfm); ++ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; ++ ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; ++ return ret; ++} ++ ++struct safexcel_alg_template safexcel_alg_rfc4106_gcm = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, ++ .alg.aead = { ++ .setkey = safexcel_rfc4106_gcm_setkey, ++ .setauthsize = safexcel_rfc4106_gcm_setauthsize, ++ .encrypt = safexcel_rfc4106_encrypt, ++ .decrypt = safexcel_rfc4106_decrypt, ++ .ivsize = GCM_RFC4106_IV_SIZE, ++ .maxauthsize = GHASH_DIGEST_SIZE, ++ .base = { ++ .cra_name = "rfc4106(gcm(aes))", ++ .cra_driver_name = "safexcel-rfc4106-gcm-aes", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_rfc4106_gcm_cra_init, ++ .cra_exit = safexcel_aead_gcm_cra_exit, ++ }, ++ }, ++}; ++ ++static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm, ++ unsigned int authsize) ++{ ++ if (authsize != GHASH_DIGEST_SIZE) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ int ret; ++ ++ ret = safexcel_aead_gcm_cra_init(tfm); ++ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC; ++ return ret; ++} ++ ++struct safexcel_alg_template safexcel_alg_rfc4543_gcm = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH, ++ .alg.aead = { ++ .setkey = safexcel_rfc4106_gcm_setkey, ++ .setauthsize = safexcel_rfc4543_gcm_setauthsize, ++ .encrypt = safexcel_rfc4106_encrypt, ++ .decrypt = safexcel_rfc4106_decrypt, ++ .ivsize = GCM_RFC4543_IV_SIZE, ++ .maxauthsize = GHASH_DIGEST_SIZE, ++ .base = { ++ .cra_name = "rfc4543(gcm(aes))", ++ .cra_driver_name = "safexcel-rfc4543-gcm-aes", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_rfc4543_gcm_cra_init, ++ .cra_exit = safexcel_aead_gcm_cra_exit, ++ }, ++ }, ++}; ++ ++static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, ++ unsigned int len) ++{ ++ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ /* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */ ++ *(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1; ++ /* last 3 bytes of key are the nonce! */ ++ memcpy((u8 *)&ctx->nonce + 1, key + len - ++ EIP197_AEAD_IPSEC_CCM_NONCE_SIZE, ++ EIP197_AEAD_IPSEC_CCM_NONCE_SIZE); ++ ++ len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE; ++ return safexcel_aead_ccm_setkey(ctfm, key, len); ++} ++ ++static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm, ++ unsigned int authsize) ++{ ++ /* Borrowed from crypto/ccm.c */ ++ switch (authsize) { ++ case 8: ++ case 12: ++ case 16: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req) ++{ ++ struct safexcel_cipher_req *creq = aead_request_ctx(req); ++ ++ /* Borrowed from crypto/ccm.c */ ++ if (req->assoclen != 16 && req->assoclen != 20) ++ return -EINVAL; ++ ++ return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT); ++} ++ ++static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req) ++{ ++ struct safexcel_cipher_req *creq = aead_request_ctx(req); ++ ++ /* Borrowed from crypto/ccm.c */ ++ if (req->assoclen != 16 && req->assoclen != 20) ++ return -EINVAL; ++ ++ return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT); ++} ++ ++static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ int ret; ++ ++ ret = safexcel_aead_ccm_cra_init(tfm); ++ ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP; ++ ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE; ++ return ret; ++} ++ ++struct safexcel_alg_template safexcel_alg_rfc4309_ccm = { ++ .type = SAFEXCEL_ALG_TYPE_AEAD, ++ .algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL, ++ .alg.aead = { ++ .setkey = safexcel_rfc4309_ccm_setkey, ++ .setauthsize = safexcel_rfc4309_ccm_setauthsize, ++ .encrypt = safexcel_rfc4309_ccm_encrypt, ++ .decrypt = safexcel_rfc4309_ccm_decrypt, ++ .ivsize = EIP197_AEAD_IPSEC_IV_SIZE, ++ .maxauthsize = AES_BLOCK_SIZE, ++ .base = { ++ .cra_name = "rfc4309(ccm(aes))", ++ .cra_driver_name = "safexcel-rfc4309-ccm-aes", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_cipher_ctx), ++ .cra_alignmask = 0, ++ .cra_init = safexcel_rfc4309_ccm_cra_init, ++ .cra_exit = safexcel_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, + }, + }; +--- a/drivers/crypto/inside-secure/safexcel.h ++++ b/drivers/crypto/inside-secure/safexcel.h +@@ -17,8 +17,11 @@ + #define EIP197_HIA_VERSION_BE 0xca35 + #define EIP197_HIA_VERSION_LE 0x35ca + #define EIP97_VERSION_LE 0x9e61 ++#define EIP196_VERSION_LE 0x3bc4 + #define EIP197_VERSION_LE 0x3ac5 + #define EIP96_VERSION_LE 0x9f60 ++#define EIP201_VERSION_LE 0x36c9 ++#define EIP206_VERSION_LE 0x31ce + #define EIP197_REG_LO16(reg) (reg & 0xffff) + #define EIP197_REG_HI16(reg) ((reg >> 16) & 0xffff) + #define EIP197_VERSION_MASK(reg) ((reg >> 16) & 0xfff) +@@ -26,12 +29,23 @@ + ((reg >> 4) & 0xf0) | \ + ((reg >> 12) & 0xf)) + ++/* EIP197 HIA OPTIONS ENCODING */ ++#define EIP197_HIA_OPT_HAS_PE_ARB BIT(29) ++ ++/* EIP206 OPTIONS ENCODING */ ++#define EIP206_OPT_ICE_TYPE(n) ((n>>8)&3) ++ ++/* EIP197 OPTIONS ENCODING */ ++#define EIP197_OPT_HAS_TRC BIT(31) ++ + /* Static configuration */ + #define EIP197_DEFAULT_RING_SIZE 400 +-#define EIP197_MAX_TOKENS 18 ++#define EIP197_EMB_TOKENS 4 /* Pad CD to 16 dwords */ ++#define EIP197_MAX_TOKENS 16 + #define EIP197_MAX_RINGS 4 + #define EIP197_FETCH_DEPTH 2 + #define EIP197_MAX_BATCH_SZ 64 ++#define EIP197_MAX_RING_AIC 14 + + #define EIP197_GFP_FLAGS(base) ((base).flags & CRYPTO_TFM_REQ_MAY_SLEEP ? \ + GFP_KERNEL : GFP_ATOMIC) +@@ -138,6 +152,7 @@ + #define EIP197_HIA_AIC_R_ENABLED_STAT(r) (0xe010 - EIP197_HIA_AIC_R_OFF(r)) + #define EIP197_HIA_AIC_R_ACK(r) (0xe010 - EIP197_HIA_AIC_R_OFF(r)) + #define EIP197_HIA_AIC_R_ENABLE_CLR(r) (0xe014 - EIP197_HIA_AIC_R_OFF(r)) ++#define EIP197_HIA_AIC_R_VERSION(r) (0xe01c - EIP197_HIA_AIC_R_OFF(r)) + #define EIP197_HIA_AIC_G_ENABLE_CTRL 0xf808 + #define EIP197_HIA_AIC_G_ENABLED_STAT 0xf810 + #define EIP197_HIA_AIC_G_ACK 0xf810 +@@ -157,12 +172,16 @@ + #define EIP197_PE_EIP96_FUNCTION_EN(n) (0x1004 + (0x2000 * (n))) + #define EIP197_PE_EIP96_CONTEXT_CTRL(n) (0x1008 + (0x2000 * (n))) + #define EIP197_PE_EIP96_CONTEXT_STAT(n) (0x100c + (0x2000 * (n))) ++#define EIP197_PE_EIP96_TOKEN_CTRL2(n) (0x102c + (0x2000 * (n))) + #define EIP197_PE_EIP96_FUNCTION2_EN(n) (0x1030 + (0x2000 * (n))) + #define EIP197_PE_EIP96_OPTIONS(n) (0x13f8 + (0x2000 * (n))) + #define EIP197_PE_EIP96_VERSION(n) (0x13fc + (0x2000 * (n))) + #define EIP197_PE_OUT_DBUF_THRES(n) (0x1c00 + (0x2000 * (n))) + #define EIP197_PE_OUT_TBUF_THRES(n) (0x1d00 + (0x2000 * (n))) ++#define EIP197_PE_OPTIONS(n) (0x1ff8 + (0x2000 * (n))) ++#define EIP197_PE_VERSION(n) (0x1ffc + (0x2000 * (n))) + #define EIP197_MST_CTRL 0xfff4 ++#define EIP197_OPTIONS 0xfff8 + #define EIP197_VERSION 0xfffc + + /* EIP197-specific registers, no indirection */ +@@ -178,6 +197,7 @@ + #define EIP197_TRC_ECCADMINSTAT 0xf0838 + #define EIP197_TRC_ECCDATASTAT 0xf083c + #define EIP197_TRC_ECCDATA 0xf0840 ++#define EIP197_STRC_CONFIG 0xf43f0 + #define EIP197_FLUE_CACHEBASE_LO(n) (0xf6000 + (32 * (n))) + #define EIP197_FLUE_CACHEBASE_HI(n) (0xf6004 + (32 * (n))) + #define EIP197_FLUE_CONFIG(n) (0xf6010 + (32 * (n))) +@@ -188,6 +208,7 @@ + + /* EIP197_HIA_xDR_DESC_SIZE */ + #define EIP197_xDR_DESC_MODE_64BIT BIT(31) ++#define EIP197_CDR_DESC_MODE_ADCP BIT(30) + + /* EIP197_HIA_xDR_DMA_CFG */ + #define EIP197_HIA_xDR_WR_RES_BUF BIT(22) +@@ -213,7 +234,6 @@ + /* EIP197_HIA_xDR_PROC_COUNT */ + #define EIP197_xDR_PROC_xD_PKT_OFFSET 24 + #define EIP197_xDR_PROC_xD_PKT_MASK GENMASK(6, 0) +-#define EIP197_xDR_PROC_xD_COUNT(n) ((n) << 2) + #define EIP197_xDR_PROC_xD_PKT(n) ((n) << 24) + #define EIP197_xDR_PROC_CLR_COUNT BIT(31) + +@@ -228,6 +248,8 @@ + #define EIP197_HIA_RA_PE_CTRL_EN BIT(30) + + /* EIP197_HIA_OPTIONS */ ++#define EIP197_N_RINGS_OFFSET 0 ++#define EIP197_N_RINGS_MASK GENMASK(3, 0) + #define EIP197_N_PES_OFFSET 4 + #define EIP197_N_PES_MASK GENMASK(4, 0) + #define EIP97_N_PES_MASK GENMASK(2, 0) +@@ -237,13 +259,13 @@ + #define EIP197_CFSIZE_OFFSET 9 + #define EIP197_CFSIZE_ADJUST 4 + #define EIP97_CFSIZE_OFFSET 8 +-#define EIP197_CFSIZE_MASK GENMASK(3, 0) +-#define EIP97_CFSIZE_MASK GENMASK(4, 0) ++#define EIP197_CFSIZE_MASK GENMASK(2, 0) ++#define EIP97_CFSIZE_MASK GENMASK(3, 0) + #define EIP197_RFSIZE_OFFSET 12 + #define EIP197_RFSIZE_ADJUST 4 + #define EIP97_RFSIZE_OFFSET 12 +-#define EIP197_RFSIZE_MASK GENMASK(3, 0) +-#define EIP97_RFSIZE_MASK GENMASK(4, 0) ++#define EIP197_RFSIZE_MASK GENMASK(2, 0) ++#define EIP97_RFSIZE_MASK GENMASK(3, 0) + + /* EIP197_HIA_AIC_R_ENABLE_CTRL */ + #define EIP197_CDR_IRQ(n) BIT((n) * 2) +@@ -257,9 +279,9 @@ + #define EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(n) ((n) << 16) + #define EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(n) (((n) & 0x7) << 20) + #define EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(n) ((n) << 24) +-#define EIP197_HIA_DFE_CFG_DIS_DEBUG (BIT(31) | BIT(29)) ++#define EIP197_HIA_DFE_CFG_DIS_DEBUG GENMASK(31, 29) + #define EIP197_HIA_DSE_CFG_EN_SINGLE_WR BIT(29) +-#define EIP197_HIA_DSE_CFG_DIS_DEBUG BIT(31) ++#define EIP197_HIA_DSE_CFG_DIS_DEBUG GENMASK(31, 30) + + /* EIP197_HIA_DFE/DSE_THR_CTRL */ + #define EIP197_DxE_THR_CTRL_EN BIT(30) +@@ -327,13 +349,21 @@ + #define EIP197_ADDRESS_MODE BIT(8) + #define EIP197_CONTROL_MODE BIT(9) + ++/* EIP197_PE_EIP96_TOKEN_CTRL2 */ ++#define EIP197_PE_EIP96_TOKEN_CTRL2_CTX_DONE BIT(3) ++ ++/* EIP197_STRC_CONFIG */ ++#define EIP197_STRC_CONFIG_INIT BIT(31) ++#define EIP197_STRC_CONFIG_LARGE_REC(s) (s<<8) ++#define EIP197_STRC_CONFIG_SMALL_REC(s) (s<<0) ++ + /* EIP197_FLUE_CONFIG */ + #define EIP197_FLUE_CONFIG_MAGIC 0xc7000004 + + /* Context Control */ + struct safexcel_context_record { +- u32 control0; +- u32 control1; ++ __le32 control0; ++ __le32 control1; + + __le32 data[40]; + } __packed; +@@ -358,10 +388,14 @@ struct safexcel_context_record { + #define CONTEXT_CONTROL_CRYPTO_ALG_AES128 (0x5 << 17) + #define CONTEXT_CONTROL_CRYPTO_ALG_AES192 (0x6 << 17) + #define CONTEXT_CONTROL_CRYPTO_ALG_AES256 (0x7 << 17) ++#define CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 (0x8 << 17) ++#define CONTEXT_CONTROL_CRYPTO_ALG_SM4 (0xd << 17) ++#define CONTEXT_CONTROL_DIGEST_INITIAL (0x0 << 21) + #define CONTEXT_CONTROL_DIGEST_PRECOMPUTED (0x1 << 21) + #define CONTEXT_CONTROL_DIGEST_XCM (0x2 << 21) + #define CONTEXT_CONTROL_DIGEST_HMAC (0x3 << 21) + #define CONTEXT_CONTROL_CRYPTO_ALG_MD5 (0x0 << 23) ++#define CONTEXT_CONTROL_CRYPTO_ALG_CRC32 (0x0 << 23) + #define CONTEXT_CONTROL_CRYPTO_ALG_SHA1 (0x2 << 23) + #define CONTEXT_CONTROL_CRYPTO_ALG_SHA224 (0x4 << 23) + #define CONTEXT_CONTROL_CRYPTO_ALG_SHA256 (0x3 << 23) +@@ -371,17 +405,25 @@ struct safexcel_context_record { + #define CONTEXT_CONTROL_CRYPTO_ALG_XCBC128 (0x1 << 23) + #define CONTEXT_CONTROL_CRYPTO_ALG_XCBC192 (0x2 << 23) + #define CONTEXT_CONTROL_CRYPTO_ALG_XCBC256 (0x3 << 23) ++#define CONTEXT_CONTROL_CRYPTO_ALG_SM3 (0x7 << 23) ++#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_256 (0xb << 23) ++#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_224 (0xc << 23) ++#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_512 (0xd << 23) ++#define CONTEXT_CONTROL_CRYPTO_ALG_SHA3_384 (0xe << 23) ++#define CONTEXT_CONTROL_CRYPTO_ALG_POLY1305 (0xf << 23) + #define CONTEXT_CONTROL_INV_FR (0x5 << 24) + #define CONTEXT_CONTROL_INV_TR (0x6 << 24) + + /* control1 */ + #define CONTEXT_CONTROL_CRYPTO_MODE_ECB (0 << 0) + #define CONTEXT_CONTROL_CRYPTO_MODE_CBC (1 << 0) ++#define CONTEXT_CONTROL_CHACHA20_MODE_256_32 (2 << 0) + #define CONTEXT_CONTROL_CRYPTO_MODE_OFB (4 << 0) + #define CONTEXT_CONTROL_CRYPTO_MODE_CFB (5 << 0) + #define CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD (6 << 0) + #define CONTEXT_CONTROL_CRYPTO_MODE_XTS (7 << 0) + #define CONTEXT_CONTROL_CRYPTO_MODE_XCM ((6 << 0) | BIT(17)) ++#define CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK (12 << 0) + #define CONTEXT_CONTROL_IV0 BIT(5) + #define CONTEXT_CONTROL_IV1 BIT(6) + #define CONTEXT_CONTROL_IV2 BIT(7) +@@ -394,6 +436,13 @@ struct safexcel_context_record { + #define EIP197_XCM_MODE_GCM 1 + #define EIP197_XCM_MODE_CCM 2 + ++#define EIP197_AEAD_TYPE_IPSEC_ESP 2 ++#define EIP197_AEAD_TYPE_IPSEC_ESP_GMAC 3 ++#define EIP197_AEAD_IPSEC_IV_SIZE 8 ++#define EIP197_AEAD_IPSEC_NONCE_SIZE 4 ++#define EIP197_AEAD_IPSEC_COUNTER_SIZE 4 ++#define EIP197_AEAD_IPSEC_CCM_NONCE_SIZE 3 ++ + /* The hash counter given to the engine in the context has a granularity of + * 64 bits. + */ +@@ -423,6 +472,8 @@ struct safexcel_context_record { + #define EIP197_TRC_PARAMS2_RC_SZ_SMALL(n) ((n) << 18) + + /* Cache helpers */ ++#define EIP197_MIN_DSIZE 1024 ++#define EIP197_MIN_ASIZE 8 + #define EIP197_CS_TRC_REC_WC 64 + #define EIP197_CS_RC_SIZE (4 * sizeof(u32)) + #define EIP197_CS_RC_NEXT(x) (x) +@@ -447,7 +498,7 @@ struct result_data_desc { + u16 application_id; + u16 rsvd1; + +- u32 rsvd2; ++ u32 rsvd2[5]; + } __packed; + + +@@ -465,16 +516,15 @@ struct safexcel_result_desc { + + u32 data_lo; + u32 data_hi; +- +- struct result_data_desc result_data; + } __packed; + + /* + * The EIP(1)97 only needs to fetch the descriptor part of + * the result descriptor, not the result token part! + */ +-#define EIP197_RD64_FETCH_SIZE ((sizeof(struct safexcel_result_desc) -\ +- sizeof(struct result_data_desc)) /\ ++#define EIP197_RD64_FETCH_SIZE (sizeof(struct safexcel_result_desc) /\ ++ sizeof(u32)) ++#define EIP197_RD64_RESULT_SIZE (sizeof(struct result_data_desc) /\ + sizeof(u32)) + + struct safexcel_token { +@@ -505,6 +555,8 @@ static inline void eip197_noop_token(str + { + token->opcode = EIP197_TOKEN_OPCODE_NOOP; + token->packet_length = BIT(2); ++ token->stat = 0; ++ token->instructions = 0; + } + + /* Instructions */ +@@ -526,14 +578,13 @@ struct safexcel_control_data_desc { + u16 application_id; + u16 rsvd; + +- u8 refresh:2; +- u32 context_lo:30; ++ u32 context_lo; + u32 context_hi; + + u32 control0; + u32 control1; + +- u32 token[EIP197_MAX_TOKENS]; ++ u32 token[EIP197_EMB_TOKENS]; + } __packed; + + #define EIP197_OPTION_MAGIC_VALUE BIT(0) +@@ -543,7 +594,10 @@ struct safexcel_control_data_desc { + #define EIP197_OPTION_2_TOKEN_IV_CMD GENMASK(11, 10) + #define EIP197_OPTION_4_TOKEN_IV_CMD GENMASK(11, 9) + ++#define EIP197_TYPE_BCLA 0x0 + #define EIP197_TYPE_EXTENDED 0x3 ++#define EIP197_CONTEXT_SMALL 0x2 ++#define EIP197_CONTEXT_SIZE_MASK 0x3 + + /* Basic Command Descriptor format */ + struct safexcel_command_desc { +@@ -551,16 +605,22 @@ struct safexcel_command_desc { + u8 rsvd0:5; + u8 last_seg:1; + u8 first_seg:1; +- u16 additional_cdata_size:8; ++ u8 additional_cdata_size:8; + + u32 rsvd1; + + u32 data_lo; + u32 data_hi; + ++ u32 atok_lo; ++ u32 atok_hi; ++ + struct safexcel_control_data_desc control_data; + } __packed; + ++#define EIP197_CD64_FETCH_SIZE (sizeof(struct safexcel_command_desc) /\ ++ sizeof(u32)) ++ + /* + * Internal structures & functions + */ +@@ -578,15 +638,20 @@ enum eip197_fw { + + struct safexcel_desc_ring { + void *base; ++ void *shbase; + void *base_end; ++ void *shbase_end; + dma_addr_t base_dma; ++ dma_addr_t shbase_dma; + + /* write and read pointers */ + void *write; ++ void *shwrite; + void *read; + + /* descriptor element offset */ +- unsigned offset; ++ unsigned int offset; ++ unsigned int shoffset; + }; + + enum safexcel_alg_type { +@@ -601,9 +666,11 @@ struct safexcel_config { + + u32 cd_size; + u32 cd_offset; ++ u32 cdsh_offset; + + u32 rd_size; + u32 rd_offset; ++ u32 res_offset; + }; + + struct safexcel_work_data { +@@ -654,6 +721,12 @@ enum safexcel_eip_version { + /* Priority we use for advertising our algorithms */ + #define SAFEXCEL_CRA_PRIORITY 300 + ++/* SM3 digest result for zero length message */ ++#define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \ ++ "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \ ++ "\x22\xBE\xC8\xC7\x28\xFE\xFB\x74" \ ++ "\x7E\xD0\x35\xEB\x50\x82\xAA\x2B" ++ + /* EIP algorithm presence flags */ + enum safexcel_eip_algorithms { + SAFEXCEL_ALG_BC0 = BIT(5), +@@ -697,16 +770,23 @@ struct safexcel_register_offsets { + enum safexcel_flags { + EIP197_TRC_CACHE = BIT(0), + SAFEXCEL_HW_EIP197 = BIT(1), ++ EIP197_PE_ARB = BIT(2), ++ EIP197_ICE = BIT(3), ++ EIP197_SIMPLE_TRC = BIT(4), + }; + + struct safexcel_hwconfig { + enum safexcel_eip_algorithms algo_flags; + int hwver; + int hiaver; ++ int ppver; + int pever; + int hwdataw; + int hwcfsize; + int hwrfsize; ++ int hwnumpes; ++ int hwnumrings; ++ int hwnumraic; + }; + + struct safexcel_crypto_priv { +@@ -778,7 +858,7 @@ struct safexcel_inv_result { + + void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring); + int safexcel_rdesc_check_errors(struct safexcel_crypto_priv *priv, +- struct safexcel_result_desc *rdesc); ++ void *rdp); + void safexcel_complete(struct safexcel_crypto_priv *priv, int ring); + int safexcel_invalidate_cache(struct crypto_async_request *async, + struct safexcel_crypto_priv *priv, +@@ -797,7 +877,8 @@ struct safexcel_command_desc *safexcel_a + bool first, bool last, + dma_addr_t data, u32 len, + u32 full_data_len, +- dma_addr_t context); ++ dma_addr_t context, ++ struct safexcel_token **atoken); + struct safexcel_result_desc *safexcel_add_rdesc(struct safexcel_crypto_priv *priv, + int ring_id, + bool first, bool last, +@@ -853,5 +934,43 @@ extern struct safexcel_alg_template safe + extern struct safexcel_alg_template safexcel_alg_xts_aes; + extern struct safexcel_alg_template safexcel_alg_gcm; + extern struct safexcel_alg_template safexcel_alg_ccm; ++extern struct safexcel_alg_template safexcel_alg_crc32; ++extern struct safexcel_alg_template safexcel_alg_cbcmac; ++extern struct safexcel_alg_template safexcel_alg_xcbcmac; ++extern struct safexcel_alg_template safexcel_alg_cmac; ++extern struct safexcel_alg_template safexcel_alg_chacha20; ++extern struct safexcel_alg_template safexcel_alg_chachapoly; ++extern struct safexcel_alg_template safexcel_alg_chachapoly_esp; ++extern struct safexcel_alg_template safexcel_alg_sm3; ++extern struct safexcel_alg_template safexcel_alg_hmac_sm3; ++extern struct safexcel_alg_template safexcel_alg_ecb_sm4; ++extern struct safexcel_alg_template safexcel_alg_cbc_sm4; ++extern struct safexcel_alg_template safexcel_alg_ofb_sm4; ++extern struct safexcel_alg_template safexcel_alg_cfb_sm4; ++extern struct safexcel_alg_template safexcel_alg_ctr_sm4; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4; ++extern struct safexcel_alg_template safexcel_alg_sha3_224; ++extern struct safexcel_alg_template safexcel_alg_sha3_256; ++extern struct safexcel_alg_template safexcel_alg_sha3_384; ++extern struct safexcel_alg_template safexcel_alg_sha3_512; ++extern struct safexcel_alg_template safexcel_alg_hmac_sha3_224; ++extern struct safexcel_alg_template safexcel_alg_hmac_sha3_256; ++extern struct safexcel_alg_template safexcel_alg_hmac_sha3_384; ++extern struct safexcel_alg_template safexcel_alg_hmac_sha3_512; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des; ++extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des; ++extern struct safexcel_alg_template safexcel_alg_rfc4106_gcm; ++extern struct safexcel_alg_template safexcel_alg_rfc4543_gcm; ++extern struct safexcel_alg_template safexcel_alg_rfc4309_ccm; + + #endif +--- a/drivers/crypto/inside-secure/safexcel_hash.c ++++ b/drivers/crypto/inside-secure/safexcel_hash.c +@@ -5,9 +5,13 @@ + * Antoine Tenart + */ + ++#include + #include + #include + #include ++#include ++#include ++#include + #include + #include + #include +@@ -19,9 +23,19 @@ struct safexcel_ahash_ctx { + struct safexcel_crypto_priv *priv; + + u32 alg; +- +- u32 ipad[SHA512_DIGEST_SIZE / sizeof(u32)]; +- u32 opad[SHA512_DIGEST_SIZE / sizeof(u32)]; ++ u8 key_sz; ++ bool cbcmac; ++ bool do_fallback; ++ bool fb_init_done; ++ bool fb_do_setkey; ++ ++ __le32 ipad[SHA3_512_BLOCK_SIZE / sizeof(__le32)]; ++ __le32 opad[SHA3_512_BLOCK_SIZE / sizeof(__le32)]; ++ ++ struct crypto_cipher *kaes; ++ struct crypto_ahash *fback; ++ struct crypto_shash *shpre; ++ struct shash_desc *shdesc; + }; + + struct safexcel_ahash_req { +@@ -31,6 +45,8 @@ struct safexcel_ahash_req { + bool needs_inv; + bool hmac_zlen; + bool len_is_le; ++ bool not_first; ++ bool xcbcmac; + + int nents; + dma_addr_t result_dma; +@@ -39,7 +55,9 @@ struct safexcel_ahash_req { + + u8 state_sz; /* expected state size, only set once */ + u8 block_sz; /* block size, only set once */ +- u32 state[SHA512_DIGEST_SIZE / sizeof(u32)] __aligned(sizeof(u32)); ++ u8 digest_sz; /* output digest size, only set once */ ++ __le32 state[SHA3_512_BLOCK_SIZE / ++ sizeof(__le32)] __aligned(sizeof(__le32)); + + u64 len; + u64 processed; +@@ -57,22 +75,36 @@ static inline u64 safexcel_queued_len(st + } + + static void safexcel_hash_token(struct safexcel_command_desc *cdesc, +- u32 input_length, u32 result_length) ++ u32 input_length, u32 result_length, ++ bool cbcmac) + { + struct safexcel_token *token = + (struct safexcel_token *)cdesc->control_data.token; + + token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION; + token[0].packet_length = input_length; +- token[0].stat = EIP197_TOKEN_STAT_LAST_HASH; + token[0].instructions = EIP197_TOKEN_INS_TYPE_HASH; + +- token[1].opcode = EIP197_TOKEN_OPCODE_INSERT; +- token[1].packet_length = result_length; +- token[1].stat = EIP197_TOKEN_STAT_LAST_HASH | ++ input_length &= 15; ++ if (unlikely(cbcmac && input_length)) { ++ token[0].stat = 0; ++ token[1].opcode = EIP197_TOKEN_OPCODE_INSERT; ++ token[1].packet_length = 16 - input_length; ++ token[1].stat = EIP197_TOKEN_STAT_LAST_HASH; ++ token[1].instructions = EIP197_TOKEN_INS_TYPE_HASH; ++ } else { ++ token[0].stat = EIP197_TOKEN_STAT_LAST_HASH; ++ eip197_noop_token(&token[1]); ++ } ++ ++ token[2].opcode = EIP197_TOKEN_OPCODE_INSERT; ++ token[2].stat = EIP197_TOKEN_STAT_LAST_HASH | + EIP197_TOKEN_STAT_LAST_PACKET; +- token[1].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | ++ token[2].packet_length = result_length; ++ token[2].instructions = EIP197_TOKEN_INS_TYPE_OUTPUT | + EIP197_TOKEN_INS_INSERT_HASH_DIGEST; ++ ++ eip197_noop_token(&token[3]); + } + + static void safexcel_context_control(struct safexcel_ahash_ctx *ctx, +@@ -82,29 +114,49 @@ static void safexcel_context_control(str + struct safexcel_crypto_priv *priv = ctx->priv; + u64 count = 0; + +- cdesc->control_data.control0 |= ctx->alg; ++ cdesc->control_data.control0 = ctx->alg; ++ cdesc->control_data.control1 = 0; + + /* + * Copy the input digest if needed, and setup the context + * fields. Do this now as we need it to setup the first command + * descriptor. + */ +- if (!req->processed) { +- /* First - and possibly only - block of basic hash only */ +- if (req->finish) { ++ if (unlikely(req->digest == CONTEXT_CONTROL_DIGEST_XCM)) { ++ if (req->xcbcmac) ++ memcpy(ctx->base.ctxr->data, ctx->ipad, ctx->key_sz); ++ else ++ memcpy(ctx->base.ctxr->data, req->state, req->state_sz); ++ ++ if (!req->finish && req->xcbcmac) ++ cdesc->control_data.control0 |= ++ CONTEXT_CONTROL_DIGEST_XCM | ++ CONTEXT_CONTROL_TYPE_HASH_OUT | ++ CONTEXT_CONTROL_NO_FINISH_HASH | ++ CONTEXT_CONTROL_SIZE(req->state_sz / ++ sizeof(u32)); ++ else + cdesc->control_data.control0 |= ++ CONTEXT_CONTROL_DIGEST_XCM | ++ CONTEXT_CONTROL_TYPE_HASH_OUT | ++ CONTEXT_CONTROL_SIZE(req->state_sz / ++ sizeof(u32)); ++ return; ++ } else if (!req->processed) { ++ /* First - and possibly only - block of basic hash only */ ++ if (req->finish) ++ cdesc->control_data.control0 |= req->digest | + CONTEXT_CONTROL_TYPE_HASH_OUT | + CONTEXT_CONTROL_RESTART_HASH | + /* ensure its not 0! */ + CONTEXT_CONTROL_SIZE(1); +- } else { +- cdesc->control_data.control0 |= ++ else ++ cdesc->control_data.control0 |= req->digest | + CONTEXT_CONTROL_TYPE_HASH_OUT | + CONTEXT_CONTROL_RESTART_HASH | + CONTEXT_CONTROL_NO_FINISH_HASH | + /* ensure its not 0! */ + CONTEXT_CONTROL_SIZE(1); +- } + return; + } + +@@ -204,7 +256,7 @@ static int safexcel_handle_req_result(st + } + + if (sreq->result_dma) { +- dma_unmap_single(priv->dev, sreq->result_dma, sreq->state_sz, ++ dma_unmap_single(priv->dev, sreq->result_dma, sreq->digest_sz, + DMA_FROM_DEVICE); + sreq->result_dma = 0; + } +@@ -223,14 +275,15 @@ static int safexcel_handle_req_result(st + memcpy(sreq->cache, sreq->state, + crypto_ahash_digestsize(ahash)); + +- memcpy(sreq->state, ctx->opad, sreq->state_sz); ++ memcpy(sreq->state, ctx->opad, sreq->digest_sz); + + sreq->len = sreq->block_sz + + crypto_ahash_digestsize(ahash); + sreq->processed = sreq->block_sz; + sreq->hmac = 0; + +- ctx->base.needs_inv = true; ++ if (priv->flags & EIP197_TRC_CACHE) ++ ctx->base.needs_inv = true; + areq->nbytes = 0; + safexcel_ahash_enqueue(areq); + +@@ -238,8 +291,14 @@ static int safexcel_handle_req_result(st + return 1; + } + +- memcpy(areq->result, sreq->state, +- crypto_ahash_digestsize(ahash)); ++ if (unlikely(sreq->digest == CONTEXT_CONTROL_DIGEST_XCM && ++ ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_CRC32)) { ++ /* Undo final XOR with 0xffffffff ...*/ ++ *(__le32 *)areq->result = ~sreq->state[0]; ++ } else { ++ memcpy(areq->result, sreq->state, ++ crypto_ahash_digestsize(ahash)); ++ } + } + + cache_len = safexcel_queued_len(sreq); +@@ -261,10 +320,11 @@ static int safexcel_ahash_send_req(struc + struct safexcel_command_desc *cdesc, *first_cdesc = NULL; + struct safexcel_result_desc *rdesc; + struct scatterlist *sg; +- int i, extra = 0, n_cdesc = 0, ret = 0; +- u64 queued, len, cache_len; ++ struct safexcel_token *dmmy; ++ int i, extra = 0, n_cdesc = 0, ret = 0, cache_len, skip = 0; ++ u64 queued, len; + +- queued = len = safexcel_queued_len(req); ++ queued = safexcel_queued_len(req); + if (queued <= HASH_CACHE_SIZE) + cache_len = queued; + else +@@ -287,15 +347,52 @@ static int safexcel_ahash_send_req(struc + areq->nbytes - extra); + + queued -= extra; +- len -= extra; + + if (!queued) { + *commands = 0; + *results = 0; + return 0; + } ++ ++ extra = 0; ++ } ++ ++ if (unlikely(req->xcbcmac && req->processed > AES_BLOCK_SIZE)) { ++ if (unlikely(cache_len < AES_BLOCK_SIZE)) { ++ /* ++ * Cache contains less than 1 full block, complete. ++ */ ++ extra = AES_BLOCK_SIZE - cache_len; ++ if (queued > cache_len) { ++ /* More data follows: borrow bytes */ ++ u64 tmp = queued - cache_len; ++ ++ skip = min_t(u64, tmp, extra); ++ sg_pcopy_to_buffer(areq->src, ++ sg_nents(areq->src), ++ req->cache + cache_len, ++ skip, 0); ++ } ++ extra -= skip; ++ memset(req->cache + cache_len + skip, 0, extra); ++ if (!ctx->cbcmac && extra) { ++ // 10- padding for XCBCMAC & CMAC ++ req->cache[cache_len + skip] = 0x80; ++ // HW will use K2 iso K3 - compensate! ++ for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) ++ ((__be32 *)req->cache)[i] ^= ++ cpu_to_be32(le32_to_cpu( ++ ctx->ipad[i] ^ ctx->ipad[i + 4])); ++ } ++ cache_len = AES_BLOCK_SIZE; ++ queued = queued + extra; ++ } ++ ++ /* XCBC continue: XOR previous result into 1st word */ ++ crypto_xor(req->cache, (const u8 *)req->state, AES_BLOCK_SIZE); + } + ++ len = queued; + /* Add a command descriptor for the cached data, if any */ + if (cache_len) { + req->cache_dma = dma_map_single(priv->dev, req->cache, +@@ -306,8 +403,9 @@ static int safexcel_ahash_send_req(struc + req->cache_sz = cache_len; + first_cdesc = safexcel_add_cdesc(priv, ring, 1, + (cache_len == len), +- req->cache_dma, cache_len, len, +- ctx->base.ctxr_dma); ++ req->cache_dma, cache_len, ++ len, ctx->base.ctxr_dma, ++ &dmmy); + if (IS_ERR(first_cdesc)) { + ret = PTR_ERR(first_cdesc); + goto unmap_cache; +@@ -319,10 +417,6 @@ static int safexcel_ahash_send_req(struc + goto send_command; + } + +- /* Skip descriptor generation for zero-length requests */ +- if (!areq->nbytes) +- goto send_command; +- + /* Now handle the current ahash request buffer(s) */ + req->nents = dma_map_sg(priv->dev, areq->src, + sg_nents_for_len(areq->src, +@@ -336,26 +430,34 @@ static int safexcel_ahash_send_req(struc + for_each_sg(areq->src, sg, req->nents, i) { + int sglen = sg_dma_len(sg); + ++ if (unlikely(sglen <= skip)) { ++ skip -= sglen; ++ continue; ++ } ++ + /* Do not overflow the request */ +- if (queued < sglen) ++ if ((queued + skip) <= sglen) + sglen = queued; ++ else ++ sglen -= skip; + + cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc, + !(queued - sglen), +- sg_dma_address(sg), +- sglen, len, ctx->base.ctxr_dma); ++ sg_dma_address(sg) + skip, sglen, ++ len, ctx->base.ctxr_dma, &dmmy); + if (IS_ERR(cdesc)) { + ret = PTR_ERR(cdesc); + goto unmap_sg; + } +- n_cdesc++; + +- if (n_cdesc == 1) ++ if (!n_cdesc) + first_cdesc = cdesc; ++ n_cdesc++; + + queued -= sglen; + if (!queued) + break; ++ skip = 0; + } + + send_command: +@@ -363,9 +465,9 @@ send_command: + safexcel_context_control(ctx, req, first_cdesc); + + /* Add the token */ +- safexcel_hash_token(first_cdesc, len, req->state_sz); ++ safexcel_hash_token(first_cdesc, len, req->digest_sz, ctx->cbcmac); + +- req->result_dma = dma_map_single(priv->dev, req->state, req->state_sz, ++ req->result_dma = dma_map_single(priv->dev, req->state, req->digest_sz, + DMA_FROM_DEVICE); + if (dma_mapping_error(priv->dev, req->result_dma)) { + ret = -EINVAL; +@@ -374,7 +476,7 @@ send_command: + + /* Add a result descriptor */ + rdesc = safexcel_add_rdesc(priv, ring, 1, 1, req->result_dma, +- req->state_sz); ++ req->digest_sz); + if (IS_ERR(rdesc)) { + ret = PTR_ERR(rdesc); + goto unmap_result; +@@ -382,17 +484,20 @@ send_command: + + safexcel_rdr_req_set(priv, ring, rdesc, &areq->base); + +- req->processed += len; ++ req->processed += len - extra; + + *commands = n_cdesc; + *results = 1; + return 0; + + unmap_result: +- dma_unmap_single(priv->dev, req->result_dma, req->state_sz, ++ dma_unmap_single(priv->dev, req->result_dma, req->digest_sz, + DMA_FROM_DEVICE); + unmap_sg: +- dma_unmap_sg(priv->dev, areq->src, req->nents, DMA_TO_DEVICE); ++ if (req->nents) { ++ dma_unmap_sg(priv->dev, areq->src, req->nents, DMA_TO_DEVICE); ++ req->nents = 0; ++ } + cdesc_rollback: + for (i = 0; i < n_cdesc; i++) + safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr); +@@ -590,16 +695,12 @@ static int safexcel_ahash_enqueue(struct + + if (ctx->base.ctxr) { + if (priv->flags & EIP197_TRC_CACHE && !ctx->base.needs_inv && +- req->processed && +- (/* invalidate for basic hash continuation finish */ +- (req->finish && +- (req->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)) || ++ /* invalidate for *any* non-XCBC continuation */ ++ ((req->not_first && !req->xcbcmac) || + /* invalidate if (i)digest changed */ + memcmp(ctx->base.ctxr->data, req->state, req->state_sz) || +- /* invalidate for HMAC continuation finish */ +- (req->finish && (req->processed != req->block_sz)) || + /* invalidate for HMAC finish with odigest changed */ +- (req->finish && ++ (req->finish && req->hmac && + memcmp(ctx->base.ctxr->data + (req->state_sz>>2), + ctx->opad, req->state_sz)))) + /* +@@ -622,6 +723,7 @@ static int safexcel_ahash_enqueue(struct + if (!ctx->base.ctxr) + return -ENOMEM; + } ++ req->not_first = true; + + ring = ctx->base.ring; + +@@ -691,8 +793,34 @@ static int safexcel_ahash_final(struct a + else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA512) + memcpy(areq->result, sha512_zero_message_hash, + SHA512_DIGEST_SIZE); ++ else if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SM3) { ++ memcpy(areq->result, ++ EIP197_SM3_ZEROM_HASH, SM3_DIGEST_SIZE); ++ } + + return 0; ++ } else if (unlikely(req->digest == CONTEXT_CONTROL_DIGEST_XCM && ++ ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_MD5 && ++ req->len == sizeof(u32) && !areq->nbytes)) { ++ /* Zero length CRC32 */ ++ memcpy(areq->result, ctx->ipad, sizeof(u32)); ++ return 0; ++ } else if (unlikely(ctx->cbcmac && req->len == AES_BLOCK_SIZE && ++ !areq->nbytes)) { ++ /* Zero length CBC MAC */ ++ memset(areq->result, 0, AES_BLOCK_SIZE); ++ return 0; ++ } else if (unlikely(req->xcbcmac && req->len == AES_BLOCK_SIZE && ++ !areq->nbytes)) { ++ /* Zero length (X)CBC/CMAC */ ++ int i; ++ ++ for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) ++ ((__be32 *)areq->result)[i] = ++ cpu_to_be32(le32_to_cpu(ctx->ipad[i + 4]));//K3 ++ areq->result[0] ^= 0x80; // 10- padding ++ crypto_cipher_encrypt_one(ctx->kaes, areq->result, areq->result); ++ return 0; + } else if (unlikely(req->hmac && + (req->len == req->block_sz) && + !areq->nbytes)) { +@@ -792,6 +920,7 @@ static int safexcel_ahash_cra_init(struc + ctx->priv = tmpl->priv; + ctx->base.send = safexcel_ahash_send; + ctx->base.handle_result = safexcel_handle_result; ++ ctx->fb_do_setkey = false; + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct safexcel_ahash_req)); +@@ -808,6 +937,7 @@ static int safexcel_sha1_init(struct aha + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA1_DIGEST_SIZE; ++ req->digest_sz = SHA1_DIGEST_SIZE; + req->block_sz = SHA1_BLOCK_SIZE; + + return 0; +@@ -889,6 +1019,7 @@ static int safexcel_hmac_sha1_init(struc + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA1_DIGEST_SIZE; ++ req->digest_sz = SHA1_DIGEST_SIZE; + req->block_sz = SHA1_BLOCK_SIZE; + req->hmac = true; + +@@ -1125,6 +1256,7 @@ static int safexcel_sha256_init(struct a + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA256_DIGEST_SIZE; ++ req->digest_sz = SHA256_DIGEST_SIZE; + req->block_sz = SHA256_BLOCK_SIZE; + + return 0; +@@ -1180,6 +1312,7 @@ static int safexcel_sha224_init(struct a + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA256_DIGEST_SIZE; ++ req->digest_sz = SHA256_DIGEST_SIZE; + req->block_sz = SHA256_BLOCK_SIZE; + + return 0; +@@ -1248,6 +1381,7 @@ static int safexcel_hmac_sha224_init(str + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA256_DIGEST_SIZE; ++ req->digest_sz = SHA256_DIGEST_SIZE; + req->block_sz = SHA256_BLOCK_SIZE; + req->hmac = true; + +@@ -1318,6 +1452,7 @@ static int safexcel_hmac_sha256_init(str + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA256_DIGEST_SIZE; ++ req->digest_sz = SHA256_DIGEST_SIZE; + req->block_sz = SHA256_BLOCK_SIZE; + req->hmac = true; + +@@ -1375,6 +1510,7 @@ static int safexcel_sha512_init(struct a + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA512_DIGEST_SIZE; ++ req->digest_sz = SHA512_DIGEST_SIZE; + req->block_sz = SHA512_BLOCK_SIZE; + + return 0; +@@ -1430,6 +1566,7 @@ static int safexcel_sha384_init(struct a + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA512_DIGEST_SIZE; ++ req->digest_sz = SHA512_DIGEST_SIZE; + req->block_sz = SHA512_BLOCK_SIZE; + + return 0; +@@ -1498,6 +1635,7 @@ static int safexcel_hmac_sha512_init(str + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA512_DIGEST_SIZE; ++ req->digest_sz = SHA512_DIGEST_SIZE; + req->block_sz = SHA512_BLOCK_SIZE; + req->hmac = true; + +@@ -1568,6 +1706,7 @@ static int safexcel_hmac_sha384_init(str + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = SHA512_DIGEST_SIZE; ++ req->digest_sz = SHA512_DIGEST_SIZE; + req->block_sz = SHA512_BLOCK_SIZE; + req->hmac = true; + +@@ -1625,6 +1764,7 @@ static int safexcel_md5_init(struct ahas + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_MD5; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = MD5_DIGEST_SIZE; ++ req->digest_sz = MD5_DIGEST_SIZE; + req->block_sz = MD5_HMAC_BLOCK_SIZE; + + return 0; +@@ -1686,6 +1826,7 @@ static int safexcel_hmac_md5_init(struct + ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_MD5; + req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; + req->state_sz = MD5_DIGEST_SIZE; ++ req->digest_sz = MD5_DIGEST_SIZE; + req->block_sz = MD5_HMAC_BLOCK_SIZE; + req->len_is_le = true; /* MD5 is little endian! ... */ + req->hmac = true; +@@ -1738,5 +1879,1235 @@ struct safexcel_alg_template safexcel_al + .cra_module = THIS_MODULE, + }, + }, ++ }, ++}; ++ ++static int safexcel_crc32_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); ++ int ret = safexcel_ahash_cra_init(tfm); ++ ++ /* Default 'key' is all zeroes */ ++ memset(ctx->ipad, 0, sizeof(u32)); ++ return ret; ++} ++ ++static int safexcel_crc32_init(struct ahash_request *areq) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq)); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ /* Start from loaded key */ ++ req->state[0] = (__force __le32)le32_to_cpu(~ctx->ipad[0]); ++ /* Set processed to non-zero to enable invalidation detection */ ++ req->len = sizeof(u32); ++ req->processed = sizeof(u32); ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_CRC32; ++ req->digest = CONTEXT_CONTROL_DIGEST_XCM; ++ req->state_sz = sizeof(u32); ++ req->digest_sz = sizeof(u32); ++ req->block_sz = sizeof(u32); ++ ++ return 0; ++} ++ ++static int safexcel_crc32_setkey(struct crypto_ahash *tfm, const u8 *key, ++ unsigned int keylen) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); ++ ++ if (keylen != sizeof(u32)) ++ return -EINVAL; ++ ++ memcpy(ctx->ipad, key, sizeof(u32)); ++ return 0; ++} ++ ++static int safexcel_crc32_digest(struct ahash_request *areq) ++{ ++ return safexcel_crc32_init(areq) ?: safexcel_ahash_finup(areq); ++} ++ ++struct safexcel_alg_template safexcel_alg_crc32 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = 0, ++ .alg.ahash = { ++ .init = safexcel_crc32_init, ++ .update = safexcel_ahash_update, ++ .final = safexcel_ahash_final, ++ .finup = safexcel_ahash_finup, ++ .digest = safexcel_crc32_digest, ++ .setkey = safexcel_crc32_setkey, ++ .export = safexcel_ahash_export, ++ .import = safexcel_ahash_import, ++ .halg = { ++ .digestsize = sizeof(u32), ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "crc32", ++ .cra_driver_name = "safexcel-crc32", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY | ++ CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_crc32_cra_init, ++ .cra_exit = safexcel_ahash_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_cbcmac_init(struct ahash_request *areq) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq)); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ /* Start from loaded keys */ ++ memcpy(req->state, ctx->ipad, ctx->key_sz); ++ /* Set processed to non-zero to enable invalidation detection */ ++ req->len = AES_BLOCK_SIZE; ++ req->processed = AES_BLOCK_SIZE; ++ ++ req->digest = CONTEXT_CONTROL_DIGEST_XCM; ++ req->state_sz = ctx->key_sz; ++ req->digest_sz = AES_BLOCK_SIZE; ++ req->block_sz = AES_BLOCK_SIZE; ++ req->xcbcmac = true; ++ ++ return 0; ++} ++ ++static int safexcel_cbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, ++ unsigned int len) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); ++ struct crypto_aes_ctx aes; ++ int ret, i; ++ ++ ret = aes_expandkey(&aes, key, len); ++ if (ret) ++ return ret; ++ ++ memset(ctx->ipad, 0, 2 * AES_BLOCK_SIZE); ++ for (i = 0; i < len / sizeof(u32); i++) ++ ctx->ipad[i + 8] = (__force __le32)cpu_to_be32(aes.key_enc[i]); ++ ++ if (len == AES_KEYSIZE_192) { ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; ++ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE; ++ } else if (len == AES_KEYSIZE_256) { ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; ++ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE; ++ } else { ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; ++ ctx->key_sz = AES_MIN_KEY_SIZE + 2 * AES_BLOCK_SIZE; ++ } ++ ctx->cbcmac = true; ++ ++ memzero_explicit(&aes, sizeof(aes)); ++ return 0; ++} ++ ++static int safexcel_cbcmac_digest(struct ahash_request *areq) ++{ ++ return safexcel_cbcmac_init(areq) ?: safexcel_ahash_finup(areq); ++} ++ ++struct safexcel_alg_template safexcel_alg_cbcmac = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = 0, ++ .alg.ahash = { ++ .init = safexcel_cbcmac_init, ++ .update = safexcel_ahash_update, ++ .final = safexcel_ahash_final, ++ .finup = safexcel_ahash_finup, ++ .digest = safexcel_cbcmac_digest, ++ .setkey = safexcel_cbcmac_setkey, ++ .export = safexcel_ahash_export, ++ .import = safexcel_ahash_import, ++ .halg = { ++ .digestsize = AES_BLOCK_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "cbcmac(aes)", ++ .cra_driver_name = "safexcel-cbcmac-aes", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_ahash_cra_init, ++ .cra_exit = safexcel_ahash_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, ++ unsigned int len) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); ++ struct crypto_aes_ctx aes; ++ u32 key_tmp[3 * AES_BLOCK_SIZE / sizeof(u32)]; ++ int ret, i; ++ ++ ret = aes_expandkey(&aes, key, len); ++ if (ret) ++ return ret; ++ ++ /* precompute the XCBC key material */ ++ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); ++ crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & ++ CRYPTO_TFM_REQ_MASK); ++ ret = crypto_cipher_setkey(ctx->kaes, key, len); ++ if (ret) ++ return ret; ++ ++ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, ++ "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1"); ++ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp, ++ "\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2"); ++ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + AES_BLOCK_SIZE, ++ "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"); ++ for (i = 0; i < 3 * AES_BLOCK_SIZE / sizeof(u32); i++) ++ ctx->ipad[i] = ++ cpu_to_le32((__force u32)cpu_to_be32(key_tmp[i])); ++ ++ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); ++ crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & ++ CRYPTO_TFM_REQ_MASK); ++ ret = crypto_cipher_setkey(ctx->kaes, ++ (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, ++ AES_MIN_KEY_SIZE); ++ if (ret) ++ return ret; ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; ++ ctx->key_sz = AES_MIN_KEY_SIZE + 2 * AES_BLOCK_SIZE; ++ ctx->cbcmac = false; ++ ++ memzero_explicit(&aes, sizeof(aes)); ++ return 0; ++} ++ ++static int safexcel_xcbcmac_cra_init(struct crypto_tfm *tfm) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_ahash_cra_init(tfm); ++ ctx->kaes = crypto_alloc_cipher("aes", 0, 0); ++ return PTR_ERR_OR_ZERO(ctx->kaes); ++} ++ ++static void safexcel_xcbcmac_cra_exit(struct crypto_tfm *tfm) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ crypto_free_cipher(ctx->kaes); ++ safexcel_ahash_cra_exit(tfm); ++} ++ ++struct safexcel_alg_template safexcel_alg_xcbcmac = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = 0, ++ .alg.ahash = { ++ .init = safexcel_cbcmac_init, ++ .update = safexcel_ahash_update, ++ .final = safexcel_ahash_final, ++ .finup = safexcel_ahash_finup, ++ .digest = safexcel_cbcmac_digest, ++ .setkey = safexcel_xcbcmac_setkey, ++ .export = safexcel_ahash_export, ++ .import = safexcel_ahash_import, ++ .halg = { ++ .digestsize = AES_BLOCK_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "xcbc(aes)", ++ .cra_driver_name = "safexcel-xcbc-aes", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_xcbcmac_cra_init, ++ .cra_exit = safexcel_xcbcmac_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, ++ unsigned int len) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); ++ struct crypto_aes_ctx aes; ++ __be64 consts[4]; ++ u64 _const[2]; ++ u8 msb_mask, gfmask; ++ int ret, i; ++ ++ ret = aes_expandkey(&aes, key, len); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < len / sizeof(u32); i++) ++ ctx->ipad[i + 8] = ++ cpu_to_le32((__force u32)cpu_to_be32(aes.key_enc[i])); ++ ++ /* precompute the CMAC key material */ ++ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); ++ crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & ++ CRYPTO_TFM_REQ_MASK); ++ ret = crypto_cipher_setkey(ctx->kaes, key, len); ++ if (ret) ++ return ret; ++ ++ /* code below borrowed from crypto/cmac.c */ ++ /* encrypt the zero block */ ++ memset(consts, 0, AES_BLOCK_SIZE); ++ crypto_cipher_encrypt_one(ctx->kaes, (u8 *)consts, (u8 *)consts); ++ ++ gfmask = 0x87; ++ _const[0] = be64_to_cpu(consts[1]); ++ _const[1] = be64_to_cpu(consts[0]); ++ ++ /* gf(2^128) multiply zero-ciphertext with u and u^2 */ ++ for (i = 0; i < 4; i += 2) { ++ msb_mask = ((s64)_const[1] >> 63) & gfmask; ++ _const[1] = (_const[1] << 1) | (_const[0] >> 63); ++ _const[0] = (_const[0] << 1) ^ msb_mask; ++ ++ consts[i + 0] = cpu_to_be64(_const[1]); ++ consts[i + 1] = cpu_to_be64(_const[0]); ++ } ++ /* end of code borrowed from crypto/cmac.c */ ++ ++ for (i = 0; i < 2 * AES_BLOCK_SIZE / sizeof(u32); i++) ++ ctx->ipad[i] = (__force __le32)cpu_to_be32(((u32 *)consts)[i]); ++ ++ if (len == AES_KEYSIZE_192) { ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192; ++ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE; ++ } else if (len == AES_KEYSIZE_256) { ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256; ++ ctx->key_sz = AES_MAX_KEY_SIZE + 2 * AES_BLOCK_SIZE; ++ } else { ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; ++ ctx->key_sz = AES_MIN_KEY_SIZE + 2 * AES_BLOCK_SIZE; ++ } ++ ctx->cbcmac = false; ++ ++ memzero_explicit(&aes, sizeof(aes)); ++ return 0; ++} ++ ++struct safexcel_alg_template safexcel_alg_cmac = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = 0, ++ .alg.ahash = { ++ .init = safexcel_cbcmac_init, ++ .update = safexcel_ahash_update, ++ .final = safexcel_ahash_final, ++ .finup = safexcel_ahash_finup, ++ .digest = safexcel_cbcmac_digest, ++ .setkey = safexcel_cmac_setkey, ++ .export = safexcel_ahash_export, ++ .import = safexcel_ahash_import, ++ .halg = { ++ .digestsize = AES_BLOCK_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "cmac(aes)", ++ .cra_driver_name = "safexcel-cmac-aes", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_xcbcmac_cra_init, ++ .cra_exit = safexcel_xcbcmac_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_sm3_init(struct ahash_request *areq) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq)); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; ++ req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; ++ req->state_sz = SM3_DIGEST_SIZE; ++ req->digest_sz = SM3_DIGEST_SIZE; ++ req->block_sz = SM3_BLOCK_SIZE; ++ ++ return 0; ++} ++ ++static int safexcel_sm3_digest(struct ahash_request *areq) ++{ ++ int ret = safexcel_sm3_init(areq); ++ ++ if (ret) ++ return ret; ++ ++ return safexcel_ahash_finup(areq); ++} ++ ++struct safexcel_alg_template safexcel_alg_sm3 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SM3, ++ .alg.ahash = { ++ .init = safexcel_sm3_init, ++ .update = safexcel_ahash_update, ++ .final = safexcel_ahash_final, ++ .finup = safexcel_ahash_finup, ++ .digest = safexcel_sm3_digest, ++ .export = safexcel_ahash_export, ++ .import = safexcel_ahash_import, ++ .halg = { ++ .digestsize = SM3_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "sm3", ++ .cra_driver_name = "safexcel-sm3", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = SM3_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_ahash_cra_init, ++ .cra_exit = safexcel_ahash_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_hmac_sm3_setkey(struct crypto_ahash *tfm, const u8 *key, ++ unsigned int keylen) ++{ ++ return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sm3", ++ SM3_DIGEST_SIZE); ++} ++ ++static int safexcel_hmac_sm3_init(struct ahash_request *areq) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq)); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ /* Start from ipad precompute */ ++ memcpy(req->state, ctx->ipad, SM3_DIGEST_SIZE); ++ /* Already processed the key^ipad part now! */ ++ req->len = SM3_BLOCK_SIZE; ++ req->processed = SM3_BLOCK_SIZE; ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3; ++ req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED; ++ req->state_sz = SM3_DIGEST_SIZE; ++ req->digest_sz = SM3_DIGEST_SIZE; ++ req->block_sz = SM3_BLOCK_SIZE; ++ req->hmac = true; ++ ++ return 0; ++} ++ ++static int safexcel_hmac_sm3_digest(struct ahash_request *areq) ++{ ++ int ret = safexcel_hmac_sm3_init(areq); ++ ++ if (ret) ++ return ret; ++ ++ return safexcel_ahash_finup(areq); ++} ++ ++struct safexcel_alg_template safexcel_alg_hmac_sm3 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SM3, ++ .alg.ahash = { ++ .init = safexcel_hmac_sm3_init, ++ .update = safexcel_ahash_update, ++ .final = safexcel_ahash_final, ++ .finup = safexcel_ahash_finup, ++ .digest = safexcel_hmac_sm3_digest, ++ .setkey = safexcel_hmac_sm3_setkey, ++ .export = safexcel_ahash_export, ++ .import = safexcel_ahash_import, ++ .halg = { ++ .digestsize = SM3_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "hmac(sm3)", ++ .cra_driver_name = "safexcel-hmac-sm3", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = SM3_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_ahash_cra_init, ++ .cra_exit = safexcel_ahash_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_sha3_224_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_224; ++ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL; ++ req->state_sz = SHA3_224_DIGEST_SIZE; ++ req->digest_sz = SHA3_224_DIGEST_SIZE; ++ req->block_sz = SHA3_224_BLOCK_SIZE; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_sha3_fbcheck(struct ahash_request *req) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct ahash_request *subreq = ahash_request_ctx(req); ++ int ret = 0; ++ ++ if (ctx->do_fallback) { ++ ahash_request_set_tfm(subreq, ctx->fback); ++ ahash_request_set_callback(subreq, req->base.flags, ++ req->base.complete, req->base.data); ++ ahash_request_set_crypt(subreq, req->src, req->result, ++ req->nbytes); ++ if (!ctx->fb_init_done) { ++ if (ctx->fb_do_setkey) { ++ /* Set fallback cipher HMAC key */ ++ u8 key[SHA3_224_BLOCK_SIZE]; ++ ++ memcpy(key, ctx->ipad, ++ crypto_ahash_blocksize(ctx->fback) / 2); ++ memcpy(key + ++ crypto_ahash_blocksize(ctx->fback) / 2, ++ ctx->opad, ++ crypto_ahash_blocksize(ctx->fback) / 2); ++ ret = crypto_ahash_setkey(ctx->fback, key, ++ crypto_ahash_blocksize(ctx->fback)); ++ memzero_explicit(key, ++ crypto_ahash_blocksize(ctx->fback)); ++ ctx->fb_do_setkey = false; ++ } ++ ret = ret ?: crypto_ahash_init(subreq); ++ ctx->fb_init_done = true; ++ } ++ } ++ return ret; ++} ++ ++static int safexcel_sha3_update(struct ahash_request *req) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct ahash_request *subreq = ahash_request_ctx(req); ++ ++ ctx->do_fallback = true; ++ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_update(subreq); ++} ++ ++static int safexcel_sha3_final(struct ahash_request *req) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct ahash_request *subreq = ahash_request_ctx(req); ++ ++ ctx->do_fallback = true; ++ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_final(subreq); ++} ++ ++static int safexcel_sha3_finup(struct ahash_request *req) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct ahash_request *subreq = ahash_request_ctx(req); ++ ++ ctx->do_fallback |= !req->nbytes; ++ if (ctx->do_fallback) ++ /* Update or ex/import happened or len 0, cannot use the HW */ ++ return safexcel_sha3_fbcheck(req) ?: ++ crypto_ahash_finup(subreq); ++ else ++ return safexcel_ahash_finup(req); ++} ++ ++static int safexcel_sha3_digest_fallback(struct ahash_request *req) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct ahash_request *subreq = ahash_request_ctx(req); ++ ++ ctx->do_fallback = true; ++ ctx->fb_init_done = false; ++ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_finup(subreq); ++} ++ ++static int safexcel_sha3_224_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_sha3_224_init(req) ?: safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length hash, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++static int safexcel_sha3_export(struct ahash_request *req, void *out) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct ahash_request *subreq = ahash_request_ctx(req); ++ ++ ctx->do_fallback = true; ++ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_export(subreq, out); ++} ++ ++static int safexcel_sha3_import(struct ahash_request *req, const void *in) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct ahash_request *subreq = ahash_request_ctx(req); ++ ++ ctx->do_fallback = true; ++ return safexcel_sha3_fbcheck(req) ?: crypto_ahash_import(subreq, in); ++ // return safexcel_ahash_import(req, in); ++} ++ ++static int safexcel_sha3_cra_init(struct crypto_tfm *tfm) ++{ ++ struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ safexcel_ahash_cra_init(tfm); ++ ++ /* Allocate fallback implementation */ ++ ctx->fback = crypto_alloc_ahash(crypto_tfm_alg_name(tfm), 0, ++ CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fback)) ++ return PTR_ERR(ctx->fback); ++ ++ /* Update statesize from fallback algorithm! */ ++ crypto_hash_alg_common(ahash)->statesize = ++ crypto_ahash_statesize(ctx->fback); ++ crypto_ahash_set_reqsize(ahash, max(sizeof(struct safexcel_ahash_req), ++ sizeof(struct ahash_request) + ++ crypto_ahash_reqsize(ctx->fback))); ++ return 0; ++} ++ ++static void safexcel_sha3_cra_exit(struct crypto_tfm *tfm) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ crypto_free_ahash(ctx->fback); ++ safexcel_ahash_cra_exit(tfm); ++} ++ ++struct safexcel_alg_template safexcel_alg_sha3_224 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_sha3_224_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_sha3_224_digest, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_224_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "sha3-224", ++ .cra_driver_name = "safexcel-sha3-224", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_224_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_sha3_cra_init, ++ .cra_exit = safexcel_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_sha3_256_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_256; ++ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL; ++ req->state_sz = SHA3_256_DIGEST_SIZE; ++ req->digest_sz = SHA3_256_DIGEST_SIZE; ++ req->block_sz = SHA3_256_BLOCK_SIZE; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_sha3_256_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_sha3_256_init(req) ?: safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length hash, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++struct safexcel_alg_template safexcel_alg_sha3_256 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_sha3_256_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_sha3_256_digest, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_256_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "sha3-256", ++ .cra_driver_name = "safexcel-sha3-256", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_256_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_sha3_cra_init, ++ .cra_exit = safexcel_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_sha3_384_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_384; ++ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL; ++ req->state_sz = SHA3_384_DIGEST_SIZE; ++ req->digest_sz = SHA3_384_DIGEST_SIZE; ++ req->block_sz = SHA3_384_BLOCK_SIZE; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_sha3_384_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_sha3_384_init(req) ?: safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length hash, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++struct safexcel_alg_template safexcel_alg_sha3_384 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_sha3_384_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_sha3_384_digest, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_384_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "sha3-384", ++ .cra_driver_name = "safexcel-sha3-384", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_384_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_sha3_cra_init, ++ .cra_exit = safexcel_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_sha3_512_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_512; ++ req->digest = CONTEXT_CONTROL_DIGEST_INITIAL; ++ req->state_sz = SHA3_512_DIGEST_SIZE; ++ req->digest_sz = SHA3_512_DIGEST_SIZE; ++ req->block_sz = SHA3_512_BLOCK_SIZE; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_sha3_512_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_sha3_512_init(req) ?: safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length hash, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++struct safexcel_alg_template safexcel_alg_sha3_512 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_sha3_512_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_sha3_512_digest, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_512_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "sha3-512", ++ .cra_driver_name = "safexcel-sha3-512", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_512_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_sha3_cra_init, ++ .cra_exit = safexcel_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_hmac_sha3_cra_init(struct crypto_tfm *tfm, const char *alg) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); ++ int ret; ++ ++ ret = safexcel_sha3_cra_init(tfm); ++ if (ret) ++ return ret; ++ ++ /* Allocate precalc basic digest implementation */ ++ ctx->shpre = crypto_alloc_shash(alg, 0, CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->shpre)) ++ return PTR_ERR(ctx->shpre); ++ ++ ctx->shdesc = kmalloc(sizeof(*ctx->shdesc) + ++ crypto_shash_descsize(ctx->shpre), GFP_KERNEL); ++ if (!ctx->shdesc) { ++ crypto_free_shash(ctx->shpre); ++ return -ENOMEM; ++ } ++ ctx->shdesc->tfm = ctx->shpre; ++ return 0; ++} ++ ++static void safexcel_hmac_sha3_cra_exit(struct crypto_tfm *tfm) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ crypto_free_ahash(ctx->fback); ++ crypto_free_shash(ctx->shpre); ++ kfree(ctx->shdesc); ++ safexcel_ahash_cra_exit(tfm); ++} ++ ++static int safexcel_hmac_sha3_setkey(struct crypto_ahash *tfm, const u8 *key, ++ unsigned int keylen) ++{ ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ int ret = 0; ++ ++ if (keylen > crypto_ahash_blocksize(tfm)) { ++ /* ++ * If the key is larger than the blocksize, then hash it ++ * first using our fallback cipher ++ */ ++ ret = crypto_shash_digest(ctx->shdesc, key, keylen, ++ (u8 *)ctx->ipad); ++ keylen = crypto_shash_digestsize(ctx->shpre); ++ ++ /* ++ * If the digest is larger than half the blocksize, we need to ++ * move the rest to opad due to the way our HMAC infra works. ++ */ ++ if (keylen > crypto_ahash_blocksize(tfm) / 2) ++ /* Buffers overlap, need to use memmove iso memcpy! */ ++ memmove(ctx->opad, ++ (u8 *)ctx->ipad + ++ crypto_ahash_blocksize(tfm) / 2, ++ keylen - crypto_ahash_blocksize(tfm) / 2); ++ } else { ++ /* ++ * Copy the key to our ipad & opad buffers ++ * Note that ipad and opad each contain one half of the key, ++ * to match the existing HMAC driver infrastructure. ++ */ ++ if (keylen <= crypto_ahash_blocksize(tfm) / 2) { ++ memcpy(ctx->ipad, key, keylen); ++ } else { ++ memcpy(ctx->ipad, key, ++ crypto_ahash_blocksize(tfm) / 2); ++ memcpy(ctx->opad, ++ key + crypto_ahash_blocksize(tfm) / 2, ++ keylen - crypto_ahash_blocksize(tfm) / 2); ++ } ++ } ++ ++ /* Pad key with zeroes */ ++ if (keylen <= crypto_ahash_blocksize(tfm) / 2) { ++ memset((u8 *)ctx->ipad + keylen, 0, ++ crypto_ahash_blocksize(tfm) / 2 - keylen); ++ memset(ctx->opad, 0, crypto_ahash_blocksize(tfm) / 2); ++ } else { ++ memset((u8 *)ctx->opad + keylen - ++ crypto_ahash_blocksize(tfm) / 2, 0, ++ crypto_ahash_blocksize(tfm) - keylen); ++ } ++ ++ /* If doing fallback, still need to set the new key! */ ++ ctx->fb_do_setkey = true; ++ return ret; ++} ++ ++static int safexcel_hmac_sha3_224_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ /* Copy (half of) the key */ ++ memcpy(req->state, ctx->ipad, SHA3_224_BLOCK_SIZE / 2); ++ /* Start of HMAC should have len == processed == blocksize */ ++ req->len = SHA3_224_BLOCK_SIZE; ++ req->processed = SHA3_224_BLOCK_SIZE; ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_224; ++ req->digest = CONTEXT_CONTROL_DIGEST_HMAC; ++ req->state_sz = SHA3_224_BLOCK_SIZE / 2; ++ req->digest_sz = SHA3_224_DIGEST_SIZE; ++ req->block_sz = SHA3_224_BLOCK_SIZE; ++ req->hmac = true; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_hmac_sha3_224_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_hmac_sha3_224_init(req) ?: ++ safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length HMAC, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++static int safexcel_hmac_sha3_224_cra_init(struct crypto_tfm *tfm) ++{ ++ return safexcel_hmac_sha3_cra_init(tfm, "sha3-224"); ++} ++ ++struct safexcel_alg_template safexcel_alg_hmac_sha3_224 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_hmac_sha3_224_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_hmac_sha3_224_digest, ++ .setkey = safexcel_hmac_sha3_setkey, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_224_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "hmac(sha3-224)", ++ .cra_driver_name = "safexcel-hmac-sha3-224", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_224_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_hmac_sha3_224_cra_init, ++ .cra_exit = safexcel_hmac_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_hmac_sha3_256_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ /* Copy (half of) the key */ ++ memcpy(req->state, ctx->ipad, SHA3_256_BLOCK_SIZE / 2); ++ /* Start of HMAC should have len == processed == blocksize */ ++ req->len = SHA3_256_BLOCK_SIZE; ++ req->processed = SHA3_256_BLOCK_SIZE; ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_256; ++ req->digest = CONTEXT_CONTROL_DIGEST_HMAC; ++ req->state_sz = SHA3_256_BLOCK_SIZE / 2; ++ req->digest_sz = SHA3_256_DIGEST_SIZE; ++ req->block_sz = SHA3_256_BLOCK_SIZE; ++ req->hmac = true; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_hmac_sha3_256_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_hmac_sha3_256_init(req) ?: ++ safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length HMAC, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++static int safexcel_hmac_sha3_256_cra_init(struct crypto_tfm *tfm) ++{ ++ return safexcel_hmac_sha3_cra_init(tfm, "sha3-256"); ++} ++ ++struct safexcel_alg_template safexcel_alg_hmac_sha3_256 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_hmac_sha3_256_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_hmac_sha3_256_digest, ++ .setkey = safexcel_hmac_sha3_setkey, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_256_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "hmac(sha3-256)", ++ .cra_driver_name = "safexcel-hmac-sha3-256", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_256_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_hmac_sha3_256_cra_init, ++ .cra_exit = safexcel_hmac_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_hmac_sha3_384_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ /* Copy (half of) the key */ ++ memcpy(req->state, ctx->ipad, SHA3_384_BLOCK_SIZE / 2); ++ /* Start of HMAC should have len == processed == blocksize */ ++ req->len = SHA3_384_BLOCK_SIZE; ++ req->processed = SHA3_384_BLOCK_SIZE; ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_384; ++ req->digest = CONTEXT_CONTROL_DIGEST_HMAC; ++ req->state_sz = SHA3_384_BLOCK_SIZE / 2; ++ req->digest_sz = SHA3_384_DIGEST_SIZE; ++ req->block_sz = SHA3_384_BLOCK_SIZE; ++ req->hmac = true; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_hmac_sha3_384_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_hmac_sha3_384_init(req) ?: ++ safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length HMAC, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++static int safexcel_hmac_sha3_384_cra_init(struct crypto_tfm *tfm) ++{ ++ return safexcel_hmac_sha3_cra_init(tfm, "sha3-384"); ++} ++ ++struct safexcel_alg_template safexcel_alg_hmac_sha3_384 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_hmac_sha3_384_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_hmac_sha3_384_digest, ++ .setkey = safexcel_hmac_sha3_setkey, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_384_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "hmac(sha3-384)", ++ .cra_driver_name = "safexcel-hmac-sha3-384", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_384_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_hmac_sha3_384_cra_init, ++ .cra_exit = safexcel_hmac_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++ }, ++}; ++ ++static int safexcel_hmac_sha3_512_init(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ struct safexcel_ahash_req *req = ahash_request_ctx(areq); ++ ++ memset(req, 0, sizeof(*req)); ++ ++ /* Copy (half of) the key */ ++ memcpy(req->state, ctx->ipad, SHA3_512_BLOCK_SIZE / 2); ++ /* Start of HMAC should have len == processed == blocksize */ ++ req->len = SHA3_512_BLOCK_SIZE; ++ req->processed = SHA3_512_BLOCK_SIZE; ++ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA3_512; ++ req->digest = CONTEXT_CONTROL_DIGEST_HMAC; ++ req->state_sz = SHA3_512_BLOCK_SIZE / 2; ++ req->digest_sz = SHA3_512_DIGEST_SIZE; ++ req->block_sz = SHA3_512_BLOCK_SIZE; ++ req->hmac = true; ++ ctx->do_fallback = false; ++ ctx->fb_init_done = false; ++ return 0; ++} ++ ++static int safexcel_hmac_sha3_512_digest(struct ahash_request *req) ++{ ++ if (req->nbytes) ++ return safexcel_hmac_sha3_512_init(req) ?: ++ safexcel_ahash_finup(req); ++ ++ /* HW cannot do zero length HMAC, use fallback instead */ ++ return safexcel_sha3_digest_fallback(req); ++} ++ ++static int safexcel_hmac_sha3_512_cra_init(struct crypto_tfm *tfm) ++{ ++ return safexcel_hmac_sha3_cra_init(tfm, "sha3-512"); ++} ++struct safexcel_alg_template safexcel_alg_hmac_sha3_512 = { ++ .type = SAFEXCEL_ALG_TYPE_AHASH, ++ .algo_mask = SAFEXCEL_ALG_SHA3, ++ .alg.ahash = { ++ .init = safexcel_hmac_sha3_512_init, ++ .update = safexcel_sha3_update, ++ .final = safexcel_sha3_final, ++ .finup = safexcel_sha3_finup, ++ .digest = safexcel_hmac_sha3_512_digest, ++ .setkey = safexcel_hmac_sha3_setkey, ++ .export = safexcel_sha3_export, ++ .import = safexcel_sha3_import, ++ .halg = { ++ .digestsize = SHA3_512_DIGEST_SIZE, ++ .statesize = sizeof(struct safexcel_ahash_export_state), ++ .base = { ++ .cra_name = "hmac(sha3-512)", ++ .cra_driver_name = "safexcel-hmac-sha3-512", ++ .cra_priority = SAFEXCEL_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA3_512_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx), ++ .cra_init = safexcel_hmac_sha3_512_cra_init, ++ .cra_exit = safexcel_hmac_sha3_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, + }, + }; +--- a/drivers/crypto/inside-secure/safexcel_ring.c ++++ b/drivers/crypto/inside-secure/safexcel_ring.c +@@ -14,7 +14,12 @@ int safexcel_init_ring_descriptors(struc + struct safexcel_desc_ring *cdr, + struct safexcel_desc_ring *rdr) + { +- cdr->offset = sizeof(u32) * priv->config.cd_offset; ++ int i; ++ struct safexcel_command_desc *cdesc; ++ dma_addr_t atok; ++ ++ /* Actual command descriptor ring */ ++ cdr->offset = priv->config.cd_offset; + cdr->base = dmam_alloc_coherent(priv->dev, + cdr->offset * EIP197_DEFAULT_RING_SIZE, + &cdr->base_dma, GFP_KERNEL); +@@ -24,7 +29,34 @@ int safexcel_init_ring_descriptors(struc + cdr->base_end = cdr->base + cdr->offset * (EIP197_DEFAULT_RING_SIZE - 1); + cdr->read = cdr->base; + +- rdr->offset = sizeof(u32) * priv->config.rd_offset; ++ /* Command descriptor shadow ring for storing additional token data */ ++ cdr->shoffset = priv->config.cdsh_offset; ++ cdr->shbase = dmam_alloc_coherent(priv->dev, ++ cdr->shoffset * ++ EIP197_DEFAULT_RING_SIZE, ++ &cdr->shbase_dma, GFP_KERNEL); ++ if (!cdr->shbase) ++ return -ENOMEM; ++ cdr->shwrite = cdr->shbase; ++ cdr->shbase_end = cdr->shbase + cdr->shoffset * ++ (EIP197_DEFAULT_RING_SIZE - 1); ++ ++ /* ++ * Populate command descriptors with physical pointers to shadow descs. ++ * Note that we only need to do this once if we don't overwrite them. ++ */ ++ cdesc = cdr->base; ++ atok = cdr->shbase_dma; ++ for (i = 0; i < EIP197_DEFAULT_RING_SIZE; i++) { ++ cdesc->atok_lo = lower_32_bits(atok); ++ cdesc->atok_hi = upper_32_bits(atok); ++ cdesc = (void *)cdesc + cdr->offset; ++ atok += cdr->shoffset; ++ } ++ ++ rdr->offset = priv->config.rd_offset; ++ /* Use shoffset for result token offset here */ ++ rdr->shoffset = priv->config.res_offset; + rdr->base = dmam_alloc_coherent(priv->dev, + rdr->offset * EIP197_DEFAULT_RING_SIZE, + &rdr->base_dma, GFP_KERNEL); +@@ -42,11 +74,40 @@ inline int safexcel_select_ring(struct s + return (atomic_inc_return(&priv->ring_used) % priv->config.rings); + } + +-static void *safexcel_ring_next_wptr(struct safexcel_crypto_priv *priv, +- struct safexcel_desc_ring *ring) ++static void *safexcel_ring_next_cwptr(struct safexcel_crypto_priv *priv, ++ struct safexcel_desc_ring *ring, ++ bool first, ++ struct safexcel_token **atoken) + { + void *ptr = ring->write; + ++ if (first) ++ *atoken = ring->shwrite; ++ ++ if ((ring->write == ring->read - ring->offset) || ++ (ring->read == ring->base && ring->write == ring->base_end)) ++ return ERR_PTR(-ENOMEM); ++ ++ if (ring->write == ring->base_end) { ++ ring->write = ring->base; ++ ring->shwrite = ring->shbase; ++ } else { ++ ring->write += ring->offset; ++ ring->shwrite += ring->shoffset; ++ } ++ ++ return ptr; ++} ++ ++static void *safexcel_ring_next_rwptr(struct safexcel_crypto_priv *priv, ++ struct safexcel_desc_ring *ring, ++ struct result_data_desc **rtoken) ++{ ++ void *ptr = ring->write; ++ ++ /* Result token at relative offset shoffset */ ++ *rtoken = ring->write + ring->shoffset; ++ + if ((ring->write == ring->read - ring->offset) || + (ring->read == ring->base && ring->write == ring->base_end)) + return ERR_PTR(-ENOMEM); +@@ -106,10 +167,13 @@ void safexcel_ring_rollback_wptr(struct + if (ring->write == ring->read) + return; + +- if (ring->write == ring->base) ++ if (ring->write == ring->base) { + ring->write = ring->base_end; +- else ++ ring->shwrite = ring->shbase_end; ++ } else { + ring->write -= ring->offset; ++ ring->shwrite -= ring->shoffset; ++ } + } + + struct safexcel_command_desc *safexcel_add_cdesc(struct safexcel_crypto_priv *priv, +@@ -117,26 +181,26 @@ struct safexcel_command_desc *safexcel_a + bool first, bool last, + dma_addr_t data, u32 data_len, + u32 full_data_len, +- dma_addr_t context) { ++ dma_addr_t context, ++ struct safexcel_token **atoken) ++{ + struct safexcel_command_desc *cdesc; +- int i; + +- cdesc = safexcel_ring_next_wptr(priv, &priv->ring[ring_id].cdr); ++ cdesc = safexcel_ring_next_cwptr(priv, &priv->ring[ring_id].cdr, ++ first, atoken); + if (IS_ERR(cdesc)) + return cdesc; + +- memset(cdesc, 0, sizeof(struct safexcel_command_desc)); +- +- cdesc->first_seg = first; +- cdesc->last_seg = last; + cdesc->particle_size = data_len; ++ cdesc->rsvd0 = 0; ++ cdesc->last_seg = last; ++ cdesc->first_seg = first; ++ cdesc->additional_cdata_size = 0; ++ cdesc->rsvd1 = 0; + cdesc->data_lo = lower_32_bits(data); + cdesc->data_hi = upper_32_bits(data); + +- if (first && context) { +- struct safexcel_token *token = +- (struct safexcel_token *)cdesc->control_data.token; +- ++ if (first) { + /* + * Note that the length here MUST be >0 or else the EIP(1)97 + * may hang. Newer EIP197 firmware actually incorporates this +@@ -146,20 +210,12 @@ struct safexcel_command_desc *safexcel_a + cdesc->control_data.packet_length = full_data_len ?: 1; + cdesc->control_data.options = EIP197_OPTION_MAGIC_VALUE | + EIP197_OPTION_64BIT_CTX | +- EIP197_OPTION_CTX_CTRL_IN_CMD; +- cdesc->control_data.context_lo = +- (lower_32_bits(context) & GENMASK(31, 2)) >> 2; ++ EIP197_OPTION_CTX_CTRL_IN_CMD | ++ EIP197_OPTION_RC_AUTO; ++ cdesc->control_data.type = EIP197_TYPE_BCLA; ++ cdesc->control_data.context_lo = lower_32_bits(context) | ++ EIP197_CONTEXT_SMALL; + cdesc->control_data.context_hi = upper_32_bits(context); +- +- if (priv->version == EIP197B_MRVL || +- priv->version == EIP197D_MRVL) +- cdesc->control_data.options |= EIP197_OPTION_RC_AUTO; +- +- /* TODO: large xform HMAC with SHA-384/512 uses refresh = 3 */ +- cdesc->control_data.refresh = 2; +- +- for (i = 0; i < EIP197_MAX_TOKENS; i++) +- eip197_noop_token(&token[i]); + } + + return cdesc; +@@ -171,18 +227,27 @@ struct safexcel_result_desc *safexcel_ad + dma_addr_t data, u32 len) + { + struct safexcel_result_desc *rdesc; ++ struct result_data_desc *rtoken; + +- rdesc = safexcel_ring_next_wptr(priv, &priv->ring[ring_id].rdr); ++ rdesc = safexcel_ring_next_rwptr(priv, &priv->ring[ring_id].rdr, ++ &rtoken); + if (IS_ERR(rdesc)) + return rdesc; + +- memset(rdesc, 0, sizeof(struct safexcel_result_desc)); +- +- rdesc->first_seg = first; +- rdesc->last_seg = last; + rdesc->particle_size = len; ++ rdesc->rsvd0 = 0; ++ rdesc->descriptor_overflow = 0; ++ rdesc->buffer_overflow = 0; ++ rdesc->last_seg = last; ++ rdesc->first_seg = first; ++ rdesc->result_size = EIP197_RD64_RESULT_SIZE; ++ rdesc->rsvd1 = 0; + rdesc->data_lo = lower_32_bits(data); + rdesc->data_hi = upper_32_bits(data); + ++ /* Clear length & error code in result token */ ++ rtoken->packet_length = 0; ++ rtoken->error_code = 0; ++ + return rdesc; + } diff --git a/root/target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch b/root/target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch new file mode 100755 index 00000000..3eda4f29 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0501-crypto-add-eip97-inside-secure-support.patch @@ -0,0 +1,27 @@ +--- a/drivers/crypto/inside-secure/safexcel.c ++++ b/drivers/crypto/inside-secure/safexcel.c +@@ -595,6 +595,14 @@ static int safexcel_hw_init(struct safex + val |= EIP197_MST_CTRL_TX_MAX_CMD(5); + writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); + } ++ /* ++ * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3 ++ */ ++ else { ++ val = 0; ++ val |= EIP97_MST_CTRL_TX_MAX_CMD(4); ++ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); ++ } + + /* Configure wr/rd cache values */ + writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) | +--- a/drivers/crypto/inside-secure/safexcel.h ++++ b/drivers/crypto/inside-secure/safexcel.h +@@ -306,6 +306,7 @@ + #define EIP197_MST_CTRL_RD_CACHE(n) (((n) & 0xf) << 0) + #define EIP197_MST_CTRL_WD_CACHE(n) (((n) & 0xf) << 4) + #define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20) ++#define EIP97_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 4) + #define EIP197_MST_CTRL_BYTE_SWAP BIT(24) + #define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25) + #define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24) diff --git a/root/target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch b/root/target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch new file mode 100755 index 00000000..06077fb9 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0502-dts-mt7623-eip97-inside-secure-support.patch @@ -0,0 +1,23 @@ +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -1047,17 +1047,14 @@ + }; + + crypto: crypto@1b240000 { +- compatible = "mediatek,eip97-crypto"; ++ compatible = "inside-secure,safexcel-eip97"; + reg = <0 0x1b240000 0 0x20000>; + interrupts = , + , + , +- , +- ; ++ ; ++ interrupt-names = "ring0", "ring1", "ring2", "ring3"; + clocks = <ðsys CLK_ETHSYS_CRYPTO>; +- clock-names = "cryp"; +- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; +- status = "disabled"; + }; + + bdpsys: syscon@1c000000 { diff --git a/root/target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch b/root/target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch new file mode 100755 index 00000000..5bc0fd0b --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0503-crypto-fix-eip97-cache-incoherent.patch @@ -0,0 +1,26 @@ +--- a/drivers/crypto/inside-secure/safexcel.h ++++ b/drivers/crypto/inside-secure/safexcel.h +@@ -722,6 +722,9 @@ enum safexcel_eip_version { + /* Priority we use for advertising our algorithms */ + #define SAFEXCEL_CRA_PRIORITY 300 + ++/* System cache line size */ ++#define SYSTEM_CACHELINE_SIZE 64 ++ + /* SM3 digest result for zero length message */ + #define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \ + "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \ +--- a/drivers/crypto/inside-secure/safexcel_hash.c ++++ b/drivers/crypto/inside-secure/safexcel_hash.c +@@ -57,9 +57,9 @@ struct safexcel_ahash_req { + u8 block_sz; /* block size, only set once */ + u8 digest_sz; /* output digest size, only set once */ + __le32 state[SHA3_512_BLOCK_SIZE / +- sizeof(__le32)] __aligned(sizeof(__le32)); ++ sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE); + +- u64 len; ++ u64 len __aligned(SYSTEM_CACHELINE_SIZE); + u64 processed; + + u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32)); diff --git a/root/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch b/root/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch new file mode 100755 index 00000000..13a9a51e --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch @@ -0,0 +1,246 @@ +From: Russell King +Date: Wed, 26 Feb 2020 10:23:41 +0000 +Subject: [PATCH] net: phylink: propagate resolved link config via + mac_link_up() + +Propagate the resolved link parameters via the mac_link_up() call for +MACs that do not automatically track their PCS state. We propagate the +link parameters via function arguments so that inappropriate members +of struct phylink_link_state can't be accessed, and creating a new +structure just for this adds needless complexity to the API. + +Tested-by: Andre Przywara +Tested-by: Alexandre Belloni +Tested-by: Vladimir Oltean +Signed-off-by: Russell King +Signed-off-by: David S. Miller +--- + +--- a/Documentation/networking/sfp-phylink.rst ++++ b/Documentation/networking/sfp-phylink.rst +@@ -74,10 +74,13 @@ phylib to the sfp/phylink support. Plea + this documentation. + + 1. Optionally split the network driver's phylib update function into +- three parts dealing with link-down, link-up and reconfiguring the +- MAC settings. This can be done as a separate preparation commit. ++ two parts dealing with link-down and link-up. This can be done as ++ a separate preparation commit. + +- An example of this preparation can be found in git commit fc548b991fb0. ++ An older example of this preparation can be found in git commit ++ fc548b991fb0, although this was splitting into three parts; the ++ link-up part now includes configuring the MAC for the link settings. ++ Please see :c:func:`mac_link_up` for more information on this. + + 2. Replace:: + +@@ -207,6 +210,14 @@ this documentation. + using. This is particularly important for in-band negotiation + methods such as 1000base-X and SGMII. + ++ The :c:func:`mac_link_up` method is used to inform the MAC that the ++ link has come up. The call includes the negotiation mode and interface ++ for reference only. The finalised link parameters are also supplied ++ (speed, duplex and flow control/pause enablement settings) which ++ should be used to configure the MAC when the MAC and PCS are not ++ tightly integrated, or when the settings are not coming from in-band ++ negotiation. ++ + The :c:func:`mac_config` method is used to update the MAC with the + requested state, and must avoid unnecessarily taking the link down + when making changes to the MAC configuration. This means the +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -3655,9 +3655,11 @@ static void mvneta_mac_link_down(struct + mvneta_set_eee(pp, false); + } + +-static void mvneta_mac_link_up(struct phylink_config *config, unsigned int mode, +- phy_interface_t interface, +- struct phy_device *phy) ++static void mvneta_mac_link_up(struct phylink_config *config, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct net_device *ndev = to_net_dev(config->dev); + struct mvneta_port *pp = netdev_priv(ndev); +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -58,8 +58,11 @@ static struct { + */ + static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode, + const struct phylink_link_state *state); +-static void mvpp2_mac_link_up(struct phylink_config *config, unsigned int mode, +- phy_interface_t interface, struct phy_device *phy); ++static void mvpp2_mac_link_up(struct phylink_config *config, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause); + + /* Queue modes */ + #define MVPP2_QDIST_SINGLE_MODE 0 +@@ -3468,8 +3471,9 @@ static void mvpp2_start_dev(struct mvpp2 + .interface = port->phy_interface, + }; + mvpp2_mac_config(&port->phylink_config, MLO_AN_INBAND, &state); +- mvpp2_mac_link_up(&port->phylink_config, MLO_AN_INBAND, +- port->phy_interface, NULL); ++ mvpp2_mac_link_up(&port->phylink_config, NULL, ++ MLO_AN_INBAND, port->phy_interface, ++ SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false); + } + + netif_tx_start_all_queues(port->dev); +@@ -5125,8 +5129,11 @@ static void mvpp2_mac_config(struct phyl + mvpp2_port_enable(port); + } + +-static void mvpp2_mac_link_up(struct phylink_config *config, unsigned int mode, +- phy_interface_t interface, struct phy_device *phy) ++static void mvpp2_mac_link_up(struct phylink_config *config, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct mvpp2_port *port = mvpp2_phylink_to_port(config); + u32 val; +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -449,9 +449,10 @@ static void mtk_mac_link_down(struct phy + mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); + } + +-static void mtk_mac_link_up(struct phylink_config *config, unsigned int mode, +- phy_interface_t interface, +- struct phy_device *phy) ++static void mtk_mac_link_up(struct phylink_config *config, ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, bool tx_pause, bool rx_pause) + { + struct mtk_mac *mac = container_of(config, struct mtk_mac, + phylink_config); +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -925,8 +925,10 @@ static void stmmac_mac_link_down(struct + } + + static void stmmac_mac_link_up(struct phylink_config *config, ++ struct phy_device *phy, + unsigned int mode, phy_interface_t interface, +- struct phy_device *phy) ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); + +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1501,9 +1501,10 @@ static void axienet_mac_link_down(struct + } + + static void axienet_mac_link_up(struct phylink_config *config, +- unsigned int mode, +- phy_interface_t interface, +- struct phy_device *phy) ++ struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + /* nothing meaningful to do */ + } +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -447,8 +447,11 @@ static void phylink_mac_link_up(struct p + struct net_device *ndev = pl->netdev; + + pl->cur_interface = link_state.interface; +- pl->ops->mac_link_up(pl->config, pl->cur_link_an_mode, +- pl->cur_interface, pl->phydev); ++ pl->ops->mac_link_up(pl->config, pl->phydev, ++ pl->cur_link_an_mode, pl->cur_interface, ++ link_state.speed, link_state.duplex, ++ !!(link_state.pause & MLO_PAUSE_TX), ++ !!(link_state.pause & MLO_PAUSE_RX)); + + if (ndev) + netif_carrier_on(ndev); +--- a/include/linux/phylink.h ++++ b/include/linux/phylink.h +@@ -91,9 +91,10 @@ struct phylink_mac_ops { + void (*mac_an_restart)(struct phylink_config *config); + void (*mac_link_down)(struct phylink_config *config, unsigned int mode, + phy_interface_t interface); +- void (*mac_link_up)(struct phylink_config *config, unsigned int mode, +- phy_interface_t interface, +- struct phy_device *phy); ++ void (*mac_link_up)(struct phylink_config *config, ++ struct phy_device *phy, unsigned int mode, ++ phy_interface_t interface, int speed, int duplex, ++ bool tx_pause, bool rx_pause); + }; + + #if 0 /* For kernel-doc purposes only. */ +@@ -217,19 +218,34 @@ void mac_link_down(struct phylink_config + /** + * mac_link_up() - allow the link to come up + * @config: a pointer to a &struct phylink_config. ++ * @phy: any attached phy + * @mode: link autonegotiation mode + * @interface: link &typedef phy_interface_t mode +- * @phy: any attached phy ++ * @speed: link speed ++ * @duplex: link duplex ++ * @tx_pause: link transmit pause enablement status ++ * @rx_pause: link receive pause enablement status ++ * ++ * Configure the MAC for an established link. ++ * ++ * @speed, @duplex, @tx_pause and @rx_pause indicate the finalised link ++ * settings, and should be used to configure the MAC block appropriately ++ * where these settings are not automatically conveyed from the PCS block, ++ * or if in-band negotiation (as defined by phylink_autoneg_inband(@mode)) ++ * is disabled. ++ * ++ * Note that when 802.3z in-band negotiation is in use, it is possible ++ * that the user wishes to override the pause settings, and this should ++ * be allowed when considering the implementation of this method. + * +- * If @mode is not an in-band negotiation mode (as defined by +- * phylink_autoneg_inband()), allow the link to come up. If @phy +- * is non-%NULL, configure Energy Efficient Ethernet by calling ++ * If in-band negotiation mode is disabled, allow the link to come up. If ++ * @phy is non-%NULL, configure Energy Efficient Ethernet by calling + * phy_init_eee() and perform appropriate MAC configuration for EEE. + * Interface type selection must be done in mac_config(). + */ +-void mac_link_up(struct phylink_config *config, unsigned int mode, +- phy_interface_t interface, +- struct phy_device *phy); ++void mac_link_up(struct phylink_config *config, struct phy_device *phy, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex, bool tx_pause, bool rx_pause); + #endif + + struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *, +--- a/net/dsa/port.c ++++ b/net/dsa/port.c +@@ -529,9 +529,11 @@ void dsa_port_phylink_mac_link_down(stru + EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_link_down); + + void dsa_port_phylink_mac_link_up(struct phylink_config *config, ++ struct phy_device *phydev, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev) ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); + struct dsa_switch *ds = dp->ds; diff --git a/root/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch b/root/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch new file mode 100755 index 00000000..ee5a52ea --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch @@ -0,0 +1,143 @@ +From: Russell King +Date: Wed, 26 Feb 2020 10:23:46 +0000 +Subject: [PATCH] net: dsa: propagate resolved link config via mac_link_up() + +Propagate the resolved link configuration down via DSA's +phylink_mac_link_up() operation to allow split PCS/MAC to work. + +Tested-by: Vladimir Oltean +Signed-off-by: Russell King +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1284,7 +1284,9 @@ EXPORT_SYMBOL(b53_phylink_mac_link_down) + void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev) ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct b53_device *dev = ds->priv; + +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -337,7 +337,9 @@ void b53_phylink_mac_link_down(struct ds + void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev); ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause); + int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering); + int b53_vlan_prepare(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan); +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -636,7 +636,9 @@ static void bcm_sf2_sw_mac_link_down(str + static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev) ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); + struct ethtool_eee *p = &priv->dev->ports[port].eee; +--- a/drivers/net/dsa/lantiq_gswip.c ++++ b/drivers/net/dsa/lantiq_gswip.c +@@ -1664,7 +1664,9 @@ static void gswip_phylink_mac_link_down( + static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev) ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct gswip_priv *priv = ds->priv; + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -1440,7 +1440,9 @@ static void mt7530_phylink_mac_link_down + static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev) ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + struct mt7530_priv *priv = ds->priv; + +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -652,7 +652,9 @@ static void mv88e6xxx_mac_link_down(stru + + static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, phy_interface_t interface, +- struct phy_device *phydev) ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + if (mode == MLO_AN_FIXED) + mv88e6xxx_mac_link_force(ds, port, LINK_FORCED_UP); +--- a/drivers/net/dsa/sja1105/sja1105_main.c ++++ b/drivers/net/dsa/sja1105/sja1105_main.c +@@ -831,7 +831,9 @@ static void sja1105_mac_link_down(struct + static void sja1105_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev) ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause) + { + sja1105_inhibit_tx(ds->priv, BIT(port), false); + } +--- a/include/net/dsa.h ++++ b/include/net/dsa.h +@@ -406,7 +406,9 @@ struct dsa_switch_ops { + void (*phylink_mac_link_up)(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev); ++ struct phy_device *phydev, ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause); + void (*phylink_fixed_state)(struct dsa_switch *ds, int port, + struct phylink_link_state *state); + /* +--- a/net/dsa/port.c ++++ b/net/dsa/port.c +@@ -544,7 +544,8 @@ void dsa_port_phylink_mac_link_up(struct + return; + } + +- ds->ops->phylink_mac_link_up(ds, dp->index, mode, interface, phydev); ++ ds->ops->phylink_mac_link_up(ds, dp->index, mode, interface, phydev, ++ speed, duplex, tx_pause, rx_pause); + } + EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_link_up); + +--- a/net/dsa/dsa_priv.h ++++ b/net/dsa/dsa_priv.h +@@ -192,9 +192,11 @@ void dsa_port_phylink_mac_link_down(stru + unsigned int mode, + phy_interface_t interface); + void dsa_port_phylink_mac_link_up(struct phylink_config *config, ++ struct phy_device *phydev, + unsigned int mode, + phy_interface_t interface, +- struct phy_device *phydev); ++ int speed, int duplex, ++ bool tx_pause, bool rx_pause); + extern const struct phylink_mac_ops dsa_port_phylink_mac_ops; + + /* slave.c */ diff --git a/root/target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch b/root/target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch new file mode 100755 index 00000000..23fba852 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch @@ -0,0 +1,145 @@ +From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= +Date: Fri, 27 Mar 2020 15:44:12 +0100 +Subject: [PATCH] net: dsa: mt7530: use resolved link config in mac_link_up() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Convert the mt7530 switch driver to use the finalised link +parameters in mac_link_up() rather than the parameters in mac_config(). + +Signed-off-by: René van Dorst +Tested-by: Sean Wang +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -489,17 +489,6 @@ mt7530_mib_reset(struct dsa_switch *ds) + mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_ACTIVATE); + } + +-static void +-mt7530_port_set_status(struct mt7530_priv *priv, int port, int enable) +-{ +- u32 mask = PMCR_TX_EN | PMCR_RX_EN | PMCR_FORCE_LNK; +- +- if (enable) +- mt7530_set(priv, MT7530_PMCR_P(port), mask); +- else +- mt7530_clear(priv, MT7530_PMCR_P(port), mask); +-} +- + static int mt7530_phy_read(struct dsa_switch *ds, int port, int regnum) + { + struct mt7530_priv *priv = ds->priv; +@@ -673,7 +662,7 @@ mt7530_port_enable(struct dsa_switch *ds + priv->ports[port].enable = true; + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, + priv->ports[port].pm); +- mt7530_port_set_status(priv, port, 0); ++ mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); + + mutex_unlock(&priv->reg_mutex); + +@@ -696,7 +685,7 @@ mt7530_port_disable(struct dsa_switch *d + priv->ports[port].enable = false; + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, + PCR_MATRIX_CLR); +- mt7530_port_set_status(priv, port, 0); ++ mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); + + mutex_unlock(&priv->reg_mutex); + } +@@ -1395,8 +1384,7 @@ static void mt7530_phylink_mac_config(st + + mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); + mcr_new = mcr_cur; +- mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 | +- PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN); ++ mcr_new &= ~PMCR_LINK_SETTINGS_MASK; + mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN | + PMCR_BACKPR_EN | PMCR_FORCE_MODE; + +@@ -1404,26 +1392,6 @@ static void mt7530_phylink_mac_config(st + if (port == 5 && dsa_is_user_port(ds, 5)) + mcr_new |= PMCR_EXT_PHY; + +- switch (state->speed) { +- case SPEED_1000: +- mcr_new |= PMCR_FORCE_SPEED_1000; +- if (priv->eee_enable & BIT(port)) +- mcr_new |= PMCR_FORCE_EEE1G; +- break; +- case SPEED_100: +- mcr_new |= PMCR_FORCE_SPEED_100; +- if (priv->eee_enable & BIT(port)) +- mcr_new |= PMCR_FORCE_EEE100; +- break; +- } +- if (state->duplex == DUPLEX_FULL) { +- mcr_new |= PMCR_FORCE_FDX; +- if (state->pause & MLO_PAUSE_TX) +- mcr_new |= PMCR_TX_FC_EN; +- if (state->pause & MLO_PAUSE_RX) +- mcr_new |= PMCR_RX_FC_EN; +- } +- + if (mcr_new != mcr_cur) + mt7530_write(priv, MT7530_PMCR_P(port), mcr_new); + } +@@ -1434,7 +1402,7 @@ static void mt7530_phylink_mac_link_down + { + struct mt7530_priv *priv = ds->priv; + +- mt7530_port_set_status(priv, port, 0); ++ mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); + } + + static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port, +@@ -1445,8 +1413,31 @@ static void mt7530_phylink_mac_link_up(s + bool tx_pause, bool rx_pause) + { + struct mt7530_priv *priv = ds->priv; ++ u32 mcr; ++ ++ mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; ++ ++ switch (speed) { ++ case SPEED_1000: ++ mcr |= PMCR_FORCE_SPEED_1000; ++ if (priv->eee_enable & BIT(port)) ++ mcr_new |= PMCR_FORCE_EEE1G; ++ break; ++ case SPEED_100: ++ mcr |= PMCR_FORCE_SPEED_100; ++ if (priv->eee_enable & BIT(port)) ++ mcr_new |= PMCR_FORCE_EEE100; ++ break; ++ } ++ if (duplex == DUPLEX_FULL) { ++ mcr |= PMCR_FORCE_FDX; ++ if (tx_pause) ++ mcr |= PMCR_TX_FC_EN; ++ if (rx_pause) ++ mcr |= PMCR_RX_FC_EN; ++ } + +- mt7530_port_set_status(priv, port, 1); ++ mt7530_set(priv, MT7530_PMCR_P(port), mcr); + } + + static void mt7530_phylink_validate(struct dsa_switch *ds, int port, +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -222,6 +222,10 @@ enum mt7530_vlan_port_attr { + #define PMCR_FORCE_LNK BIT(0) + #define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \ + PMCR_FORCE_SPEED_1000) ++#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ ++ PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ ++ PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ ++ PMCR_FORCE_FDX | PMCR_FORCE_LNK) + + #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100) + #define PMSR_EEE1G BIT(7) diff --git a/root/target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch b/root/target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch new file mode 100755 index 00000000..718ed8ea --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch @@ -0,0 +1,458 @@ +From: Landen Chao +Date: Fri, 4 Sep 2020 22:21:57 +0800 +Subject: [PATCH] net: dsa: mt7530: Extend device data ready for adding a + new hardware + +Add a structure holding required operations for each device such as device +initialization, PHY port read or write, a checker whether PHY interface is +supported on a certain port, MAC port setup for either bus pad or a +specific PHY interface. + +The patch is done for ready adding a new hardware MT7531, and keep the +same setup logic of existing hardware. + +Signed-off-by: Landen Chao +Signed-off-by: Sean Wang +--- + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -373,8 +373,9 @@ mt7530_fdb_write(struct mt7530_priv *pri + mt7530_write(priv, MT7530_ATA1 + (i * 4), reg[i]); + } + ++/* Setup TX circuit including relevant PAD and driving */ + static int +-mt7530_pad_clk_setup(struct dsa_switch *ds, int mode) ++mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface) + { + struct mt7530_priv *priv = ds->priv; + u32 ncpo1, ssc_delta, trgint, i, xtal; +@@ -388,7 +389,7 @@ mt7530_pad_clk_setup(struct dsa_switch * + return -EINVAL; + } + +- switch (mode) { ++ switch (interface) { + case PHY_INTERFACE_MODE_RGMII: + trgint = 0; + /* PLL frequency: 125MHz */ +@@ -410,7 +411,8 @@ mt7530_pad_clk_setup(struct dsa_switch * + } + break; + default: +- dev_err(priv->dev, "xMII mode %d not supported\n", mode); ++ dev_err(priv->dev, "xMII interface %d not supported\n", ++ interface); + return -EINVAL; + } + +@@ -1332,12 +1334,11 @@ mt7530_setup(struct dsa_switch *ds) + return 0; + } + +-static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port, +- unsigned int mode, +- const struct phylink_link_state *state) ++static bool ++mt7530_phy_mode_supported(struct dsa_switch *ds, int port, ++ const struct phylink_link_state *state) + { + struct mt7530_priv *priv = ds->priv; +- u32 mcr_cur, mcr_new; + + switch (port) { + case 0: /* Internal phy */ +@@ -1346,33 +1347,114 @@ static void mt7530_phylink_mac_config(st + case 3: + case 4: + if (state->interface != PHY_INTERFACE_MODE_GMII) +- return; ++ goto unsupported; + break; + case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ +- if (priv->p5_interface == state->interface) +- break; + if (!phy_interface_mode_is_rgmii(state->interface) && + state->interface != PHY_INTERFACE_MODE_MII && + state->interface != PHY_INTERFACE_MODE_GMII) +- return; ++ goto unsupported; ++ break; ++ case 6: /* 1st cpu port */ ++ if (state->interface != PHY_INTERFACE_MODE_RGMII && ++ state->interface != PHY_INTERFACE_MODE_TRGMII) ++ goto unsupported; ++ break; ++ default: ++ dev_err(priv->dev, "%s: unsupported port: %i\n", __func__, ++ port); ++ goto unsupported; ++ } ++ ++ return true; ++ ++unsupported: ++ return false; ++} ++ ++static bool ++mt753x_phy_mode_supported(struct dsa_switch *ds, int port, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->phy_mode_supported(ds, port, state); ++} ++ ++static int ++mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->pad_setup(ds, state->interface); ++} ++ ++static int ++mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode, ++ phy_interface_t interface) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ /* Only need to setup port5. */ ++ if (port != 5) ++ return 0; ++ ++ mt7530_setup_port5(priv->ds, interface); ++ ++ return 0; ++} ++ ++static int ++mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->mac_port_config(ds, port, mode, state->interface); ++} ++ ++static void ++mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ u32 mcr_cur, mcr_new; ++ ++ if (!mt753x_phy_mode_supported(ds, port, state)) ++ goto unsupported; ++ ++ switch (port) { ++ case 0: /* Internal phy */ ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ if (state->interface != PHY_INTERFACE_MODE_GMII) ++ goto unsupported; ++ break; ++ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ ++ if (priv->p5_interface == state->interface) ++ break; ++ ++ if (mt753x_mac_config(ds, port, mode, state) < 0) ++ goto unsupported; + +- mt7530_setup_port5(ds, state->interface); + break; + case 6: /* 1st cpu port */ + if (priv->p6_interface == state->interface) + break; + +- if (state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_TRGMII) +- return; ++ mt753x_pad_setup(ds, state); + +- /* Setup TX circuit incluing relevant PAD and driving */ +- mt7530_pad_clk_setup(ds, state->interface); ++ if (mt753x_mac_config(ds, port, mode, state) < 0) ++ goto unsupported; + + priv->p6_interface = state->interface; + break; + default: +- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); ++unsupported: ++ dev_err(ds->dev, "%s: unsupported %s port: %i\n", ++ __func__, phy_modes(state->interface), port); + return; + } + +@@ -1440,61 +1522,44 @@ static void mt7530_phylink_mac_link_up(s + mt7530_set(priv, MT7530_PMCR_P(port), mcr); + } + +-static void mt7530_phylink_validate(struct dsa_switch *ds, int port, +- unsigned long *supported, +- struct phylink_link_state *state) ++static void ++mt7530_mac_port_validate(struct dsa_switch *ds, int port, ++ unsigned long *supported) + { ++ if (port == 5) ++ phylink_set(supported, 1000baseX_Full); ++} ++ ++static void ++mt753x_phylink_validate(struct dsa_switch *ds, int port, ++ unsigned long *supported, ++ struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; + +- switch (port) { +- case 0: /* Internal phy */ +- case 1: +- case 2: +- case 3: +- case 4: +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_GMII) +- goto unsupported; +- break; +- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- !phy_interface_mode_is_rgmii(state->interface) && +- state->interface != PHY_INTERFACE_MODE_MII && +- state->interface != PHY_INTERFACE_MODE_GMII) +- goto unsupported; +- break; +- case 6: /* 1st cpu port */ +- if (state->interface != PHY_INTERFACE_MODE_NA && +- state->interface != PHY_INTERFACE_MODE_RGMII && +- state->interface != PHY_INTERFACE_MODE_TRGMII) +- goto unsupported; +- break; +- default: +- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); +-unsupported: ++ if (state->interface != PHY_INTERFACE_MODE_NA && ++ !mt753x_phy_mode_supported(ds, port, state)) { + linkmode_zero(supported); + return; + } + + phylink_set_port_modes(mask); +- phylink_set(mask, Autoneg); + +- if (state->interface == PHY_INTERFACE_MODE_TRGMII) { +- phylink_set(mask, 1000baseT_Full); +- } else { ++ if (state->interface != PHY_INTERFACE_MODE_TRGMII) { + phylink_set(mask, 10baseT_Half); + phylink_set(mask, 10baseT_Full); + phylink_set(mask, 100baseT_Half); + phylink_set(mask, 100baseT_Full); +- +- if (state->interface != PHY_INTERFACE_MODE_MII) { +- /* This switch only supports 1G full-duplex. */ +- phylink_set(mask, 1000baseT_Full); +- if (port == 5) +- phylink_set(mask, 1000baseX_Full); +- } ++ phylink_set(mask, Autoneg); + } + ++ /* This switch only supports 1G full-duplex. */ ++ if (state->interface != PHY_INTERFACE_MODE_MII) ++ phylink_set(mask, 1000baseT_Full); ++ ++ priv->info->mac_port_validate(ds, port, mask); ++ + phylink_set(mask, Pause); + phylink_set(mask, Asym_Pause); + +@@ -1590,12 +1655,45 @@ static int mt7530_set_mac_eee(struct dsa + return 0; + } + ++static int ++mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port, ++ struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->mac_port_get_state(ds, port, state); ++} ++ ++static int ++mt753x_setup(struct dsa_switch *ds) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->sw_setup(ds); ++} ++ ++static int ++mt753x_phy_read(struct dsa_switch *ds, int port, int regnum) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->phy_read(ds, port, regnum); ++} ++ ++static int ++mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ return priv->info->phy_write(ds, port, regnum, val); ++} ++ + static const struct dsa_switch_ops mt7530_switch_ops = { + .get_tag_protocol = mtk_get_tag_protocol, +- .setup = mt7530_setup, ++ .setup = mt753x_setup, + .get_strings = mt7530_get_strings, +- .phy_read = mt7530_phy_read, +- .phy_write = mt7530_phy_write, ++ .phy_read = mt753x_phy_read, ++ .phy_write = mt753x_phy_write, + .get_ethtool_stats = mt7530_get_ethtool_stats, + .get_sset_count = mt7530_get_sset_count, + .port_enable = mt7530_port_enable, +@@ -1612,18 +1710,43 @@ static const struct dsa_switch_ops mt753 + .port_vlan_del = mt7530_port_vlan_del, + .port_mirror_add = mt7530_port_mirror_add, + .port_mirror_del = mt7530_port_mirror_del, +- .phylink_validate = mt7530_phylink_validate, +- .phylink_mac_link_state = mt7530_phylink_mac_link_state, +- .phylink_mac_config = mt7530_phylink_mac_config, ++ .phylink_validate = mt753x_phylink_validate, ++ .phylink_mac_link_state = mt753x_phylink_mac_link_state, ++ .phylink_mac_config = mt753x_phylink_mac_config, + .phylink_mac_link_down = mt7530_phylink_mac_link_down, + .phylink_mac_link_up = mt7530_phylink_mac_link_up, + .get_mac_eee = mt7530_get_mac_eee, + .set_mac_eee = mt7530_set_mac_eee, + }; + ++static const struct mt753x_info mt753x_table[] = { ++ [ID_MT7621] = { ++ .id = ID_MT7621, ++ .sw_setup = mt7530_setup, ++ .phy_read = mt7530_phy_read, ++ .phy_write = mt7530_phy_write, ++ .pad_setup = mt7530_pad_clk_setup, ++ .phy_mode_supported = mt7530_phy_mode_supported, ++ .mac_port_validate = mt7530_mac_port_validate, ++ .mac_port_get_state = mt7530_phylink_mac_link_state, ++ .mac_port_config = mt7530_mac_config, ++ }, ++ [ID_MT7530] = { ++ .id = ID_MT7530, ++ .sw_setup = mt7530_setup, ++ .phy_read = mt7530_phy_read, ++ .phy_write = mt7530_phy_write, ++ .pad_setup = mt7530_pad_clk_setup, ++ .phy_mode_supported = mt7530_phy_mode_supported, ++ .mac_port_validate = mt7530_mac_port_validate, ++ .mac_port_get_state = mt7530_phylink_mac_link_state, ++ .mac_port_config = mt7530_mac_config, ++ }, ++}; ++ + static const struct of_device_id mt7530_of_match[] = { +- { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, }, +- { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, }, ++ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, ++ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, mt7530_of_match); +@@ -1661,8 +1784,21 @@ mt7530_probe(struct mdio_device *mdiodev + /* Get the hardware identifier from the devicetree node. + * We will need it for some of the clock and regulator setup. + */ +- priv->id = (unsigned int)(unsigned long) +- of_device_get_match_data(&mdiodev->dev); ++ priv->info = of_device_get_match_data(&mdiodev->dev); ++ if (!priv->info) ++ return -EINVAL; ++ ++ /* Sanity check if these required device operations are filled ++ * properly. ++ */ ++ if (!priv->info->sw_setup || !priv->info->pad_setup || ++ !priv->info->phy_read || !priv->info->phy_write || ++ !priv->info->phy_mode_supported || ++ !priv->info->mac_port_validate || ++ !priv->info->mac_port_get_state || !priv->info->mac_port_config) ++ return -EINVAL; ++ ++ priv->id = priv->info->id; + + if (priv->id == ID_MT7530) { + priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -11,7 +11,7 @@ + #define MT7530_NUM_FDB_RECORDS 2048 + #define MT7530_ALL_MEMBERS 0xff + +-enum { ++enum mt753x_id { + ID_MT7530 = 0, + ID_MT7621 = 1, + }; +@@ -451,6 +451,40 @@ static const char *p5_intf_modes(unsigne + } + } + ++/* struct mt753x_info - This is the main data structure for holding the specific ++ * part for each supported device ++ * @sw_setup: Holding the handler to a device initialization ++ * @phy_read: Holding the way reading PHY port ++ * @phy_write: Holding the way writing PHY port ++ * @pad_setup: Holding the way setting up the bus pad for a certain ++ * MAC port ++ * @phy_mode_supported: Check if the PHY type is being supported on a certain ++ * port ++ * @mac_port_validate: Holding the way to set addition validate type for a ++ * certan MAC port ++ * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain ++ * MAC port ++ * @mac_port_config: Holding the way setting up the PHY attribute to a ++ * certain MAC port ++ */ ++struct mt753x_info { ++ enum mt753x_id id; ++ ++ int (*sw_setup)(struct dsa_switch *ds); ++ int (*phy_read)(struct dsa_switch *ds, int port, int regnum); ++ int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val); ++ int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface); ++ bool (*phy_mode_supported)(struct dsa_switch *ds, int port, ++ const struct phylink_link_state *state); ++ void (*mac_port_validate)(struct dsa_switch *ds, int port, ++ unsigned long *supported); ++ int (*mac_port_get_state)(struct dsa_switch *ds, int port, ++ struct phylink_link_state *state); ++ int (*mac_port_config)(struct dsa_switch *ds, int port, ++ unsigned int mode, ++ phy_interface_t interface); ++}; ++ + /* struct mt7530_priv - This is the main data structure for holding the state + * of the driver + * @dev: The device pointer +@@ -476,6 +510,7 @@ struct mt7530_priv { + struct regulator *core_pwr; + struct regulator *io_pwr; + struct gpio_desc *reset; ++ const struct mt753x_info *info; + unsigned int id; + bool mcm; + phy_interface_t p6_interface; diff --git a/root/target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch b/root/target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch new file mode 100755 index 00000000..8ede8622 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch @@ -0,0 +1,1510 @@ +From: Landen Chao +Date: Fri, 4 Sep 2020 22:21:59 +0800 +Subject: [PATCH] net: dsa: mt7530: Add the support of MT7531 switch + +Add new support for MT7531: + +MT7531 is the next generation of MT7530. It is also a 7-ports switch with +5 giga embedded phys, 2 cpu ports, and the same MAC logic of MT7530. Cpu +port 6 only supports SGMII interface. Cpu port 5 supports either RGMII +or SGMII in different HW sku, but cannot be muxed to PHY of port 0/4 like +mt7530. Due to SGMII interface support, pll, and pad setting are different +from MT7530. This patch adds different initial setting, and SGMII phylink +handlers of MT7531. + +MT7531 SGMII interface can be configured in following mode: +- 'SGMII AN mode' with in-band negotiation capability + which is compatible with PHY_INTERFACE_MODE_SGMII. +- 'SGMII force mode' without in-band negotiation + which is compatible with 10B/8B encoding of + PHY_INTERFACE_MODE_1000BASEX with fixed full-duplex and fixed pause. +- 2.5 times faster clocked 'SGMII force mode' without in-band negotiation + which is compatible with 10B/8B encoding of + PHY_INTERFACE_MODE_2500BASEX with fixed full-duplex and fixed pause. + +Signed-off-by: Landen Chao +Signed-off-by: Sean Wang +--- + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -235,6 +235,12 @@ mt7530_write(struct mt7530_priv *priv, u + } + + static u32 ++_mt7530_unlocked_read(struct mt7530_dummy_poll *p) ++{ ++ return mt7530_mii_read(p->priv, p->reg); ++} ++ ++static u32 + _mt7530_read(struct mt7530_dummy_poll *p) + { + struct mii_bus *bus = p->priv->bus; +@@ -482,6 +488,108 @@ mt7530_pad_clk_setup(struct dsa_switch * + return 0; + } + ++static bool mt7531_dual_sgmii_supported(struct mt7530_priv *priv) ++{ ++ u32 val; ++ ++ val = mt7530_read(priv, MT7531_TOP_SIG_SR); ++ ++ return (val & PAD_DUAL_SGMII_EN) != 0; ++} ++ ++static int ++mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ u32 val; ++ u32 top_sig; ++ u32 hwstrap; ++ u32 xtal; ++ ++ if (mt7531_dual_sgmii_supported(priv)) ++ return 0; ++ ++ val = mt7530_read(priv, MT7531_CREV); ++ top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR); ++ hwstrap = mt7530_read(priv, MT7531_HWTRAP); ++ if ((val & CHIP_REV_M) > 0) ++ xtal = (top_sig & PAD_MCM_SMI_EN) ? HWTRAP_XTAL_FSEL_40MHZ : ++ HWTRAP_XTAL_FSEL_25MHZ; ++ else ++ xtal = hwstrap & HWTRAP_XTAL_FSEL_MASK; ++ ++ /* Step 1 : Disable MT7531 COREPLL */ ++ val = mt7530_read(priv, MT7531_PLLGP_EN); ++ val &= ~EN_COREPLL; ++ mt7530_write(priv, MT7531_PLLGP_EN, val); ++ ++ /* Step 2: switch to XTAL output */ ++ val = mt7530_read(priv, MT7531_PLLGP_EN); ++ val |= SW_CLKSW; ++ mt7530_write(priv, MT7531_PLLGP_EN, val); ++ ++ val = mt7530_read(priv, MT7531_PLLGP_CR0); ++ val &= ~RG_COREPLL_EN; ++ mt7530_write(priv, MT7531_PLLGP_CR0, val); ++ ++ /* Step 3: disable PLLGP and enable program PLLGP */ ++ val = mt7530_read(priv, MT7531_PLLGP_EN); ++ val |= SW_PLLGP; ++ mt7530_write(priv, MT7531_PLLGP_EN, val); ++ ++ /* Step 4: program COREPLL output frequency to 500MHz */ ++ val = mt7530_read(priv, MT7531_PLLGP_CR0); ++ val &= ~RG_COREPLL_POSDIV_M; ++ val |= 2 << RG_COREPLL_POSDIV_S; ++ mt7530_write(priv, MT7531_PLLGP_CR0, val); ++ usleep_range(25, 35); ++ ++ switch (xtal) { ++ case HWTRAP_XTAL_FSEL_25MHZ: ++ val = mt7530_read(priv, MT7531_PLLGP_CR0); ++ val &= ~RG_COREPLL_SDM_PCW_M; ++ val |= 0x140000 << RG_COREPLL_SDM_PCW_S; ++ mt7530_write(priv, MT7531_PLLGP_CR0, val); ++ break; ++ case HWTRAP_XTAL_FSEL_40MHZ: ++ val = mt7530_read(priv, MT7531_PLLGP_CR0); ++ val &= ~RG_COREPLL_SDM_PCW_M; ++ val |= 0x190000 << RG_COREPLL_SDM_PCW_S; ++ mt7530_write(priv, MT7531_PLLGP_CR0, val); ++ break; ++ }; ++ ++ /* Set feedback divide ratio update signal to high */ ++ val = mt7530_read(priv, MT7531_PLLGP_CR0); ++ val |= RG_COREPLL_SDM_PCW_CHG; ++ mt7530_write(priv, MT7531_PLLGP_CR0, val); ++ /* Wait for at least 16 XTAL clocks */ ++ usleep_range(10, 20); ++ ++ /* Step 5: set feedback divide ratio update signal to low */ ++ val = mt7530_read(priv, MT7531_PLLGP_CR0); ++ val &= ~RG_COREPLL_SDM_PCW_CHG; ++ mt7530_write(priv, MT7531_PLLGP_CR0, val); ++ ++ /* Enable 325M clock for SGMII */ ++ mt7530_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000); ++ ++ /* Enable 250SSC clock for RGMII */ ++ mt7530_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000); ++ ++ /* Step 6: Enable MT7531 PLL */ ++ val = mt7530_read(priv, MT7531_PLLGP_CR0); ++ val |= RG_COREPLL_EN; ++ mt7530_write(priv, MT7531_PLLGP_CR0, val); ++ ++ val = mt7530_read(priv, MT7531_PLLGP_EN); ++ val |= EN_COREPLL; ++ mt7530_write(priv, MT7531_PLLGP_EN, val); ++ usleep_range(25, 35); ++ ++ return 0; ++} ++ + static void + mt7530_mib_reset(struct dsa_switch *ds) + { +@@ -506,6 +614,217 @@ static int mt7530_phy_write(struct dsa_s + return mdiobus_write_nested(priv->bus, port, regnum, val); + } + ++static int ++mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad, ++ int regnum) ++{ ++ struct mii_bus *bus = priv->bus; ++ struct mt7530_dummy_poll p; ++ u32 reg, val; ++ int ret; ++ ++ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) | ++ MT7531_MDIO_DEV_ADDR(devad) | regnum; ++ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ reg = MT7531_MDIO_CL45_READ | MT7531_MDIO_PHY_ADDR(port) | ++ MT7531_MDIO_DEV_ADDR(devad); ++ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ ret = val & MT7531_MDIO_RW_DATA_MASK; ++out: ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static int ++mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad, ++ int regnum, u32 data) ++{ ++ struct mii_bus *bus = priv->bus; ++ struct mt7530_dummy_poll p; ++ u32 val, reg; ++ int ret; ++ ++ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ reg = MT7531_MDIO_CL45_ADDR | MT7531_MDIO_PHY_ADDR(port) | ++ MT7531_MDIO_DEV_ADDR(devad) | regnum; ++ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ reg = MT7531_MDIO_CL45_WRITE | MT7531_MDIO_PHY_ADDR(port) | ++ MT7531_MDIO_DEV_ADDR(devad) | data; ++ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++out: ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static int ++mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum) ++{ ++ struct mii_bus *bus = priv->bus; ++ struct mt7530_dummy_poll p; ++ int ret; ++ u32 val; ++ ++ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ val = MT7531_MDIO_CL22_READ | MT7531_MDIO_PHY_ADDR(port) | ++ MT7531_MDIO_REG_ADDR(regnum); ++ ++ mt7530_mii_write(priv, MT7531_PHY_IAC, val | MT7531_PHY_ACS_ST); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, ++ !(val & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ ret = val & MT7531_MDIO_RW_DATA_MASK; ++out: ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static int ++mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, ++ u16 data) ++{ ++ struct mii_bus *bus = priv->bus; ++ struct mt7530_dummy_poll p; ++ int ret; ++ u32 reg; ++ ++ INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg, ++ !(reg & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++ reg = MT7531_MDIO_CL22_WRITE | MT7531_MDIO_PHY_ADDR(port) | ++ MT7531_MDIO_REG_ADDR(regnum) | data; ++ ++ mt7530_mii_write(priv, MT7531_PHY_IAC, reg | MT7531_PHY_ACS_ST); ++ ++ ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg, ++ !(reg & MT7531_PHY_ACS_ST), 20, 100000); ++ if (ret < 0) { ++ dev_err(priv->dev, "poll timeout\n"); ++ goto out; ++ } ++ ++out: ++ mutex_unlock(&bus->mdio_lock); ++ ++ return ret; ++} ++ ++static int ++mt7531_ind_phy_read(struct dsa_switch *ds, int port, int regnum) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ int devad; ++ int ret; ++ ++ if (regnum & MII_ADDR_C45) { ++ devad = (regnum >> MII_DEVADDR_C45_SHIFT) & 0x1f; ++ ret = mt7531_ind_c45_phy_read(priv, port, devad, ++ regnum & MII_REGADDR_C45_MASK); ++ } else { ++ ret = mt7531_ind_c22_phy_read(priv, port, regnum); ++ } ++ ++ return ret; ++} ++ ++static int ++mt7531_ind_phy_write(struct dsa_switch *ds, int port, int regnum, ++ u16 data) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ int devad; ++ int ret; ++ ++ if (regnum & MII_ADDR_C45) { ++ devad = (regnum >> MII_DEVADDR_C45_SHIFT) & 0x1f; ++ ret = mt7531_ind_c45_phy_write(priv, port, devad, ++ regnum & MII_REGADDR_C45_MASK, ++ data); ++ } else { ++ ret = mt7531_ind_c22_phy_write(priv, port, regnum, data); ++ } ++ ++ return ret; ++} ++ + static void + mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset, + uint8_t *data) +@@ -622,9 +941,14 @@ unlock_exit: + } + + static int +-mt7530_cpu_port_enable(struct mt7530_priv *priv, +- int port) ++mt753x_cpu_port_enable(struct dsa_switch *ds, int port) + { ++ struct mt7530_priv *priv = ds->priv; ++ ++ /* Setup max capability of CPU port at first */ ++ if (priv->info->cpu_port_config) ++ priv->info->cpu_port_config(ds, port); ++ + /* Enable Mediatek header mode on the cpu port */ + mt7530_write(priv, MT7530_PVC_P(port), + PORT_SPEC_TAG); +@@ -637,7 +961,7 @@ mt7530_cpu_port_enable(struct mt7530_pri + mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port)); + + /* CPU port gets connected to all user ports of +- * the switch ++ * the switch. + */ + mt7530_write(priv, MT7530_PCR_P(port), + PCR_MATRIX(dsa_user_ports(priv->ds))); +@@ -1120,27 +1444,42 @@ mt7530_port_vlan_del(struct dsa_switch * + return 0; + } + +-static int mt7530_port_mirror_add(struct dsa_switch *ds, int port, ++static int mt753x_mirror_port_get(unsigned int id, u32 val) ++{ ++ return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) : ++ MIRROR_PORT(val); ++} ++ ++static int mt753x_mirror_port_set(unsigned int id, u32 val) ++{ ++ return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) : ++ MIRROR_PORT(val); ++} ++ ++static int mt753x_port_mirror_add(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror, + bool ingress) + { + struct mt7530_priv *priv = ds->priv; ++ int monitor_port; + u32 val; + + /* Check for existent entry */ + if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) + return -EEXIST; + +- val = mt7530_read(priv, MT7530_MFC); ++ val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id)); + + /* MT7530 only supports one monitor port */ +- if (val & MIRROR_EN && MIRROR_PORT(val) != mirror->to_local_port) ++ monitor_port = mt753x_mirror_port_get(priv->id, val); ++ if (val & MT753X_MIRROR_EN(priv->id) && ++ monitor_port != mirror->to_local_port) + return -EEXIST; + +- val |= MIRROR_EN; +- val &= ~MIRROR_MASK; +- val |= mirror->to_local_port; +- mt7530_write(priv, MT7530_MFC, val); ++ val |= MT753X_MIRROR_EN(priv->id); ++ val &= ~MT753X_MIRROR_MASK(priv->id); ++ val |= mt753x_mirror_port_set(priv->id, mirror->to_local_port); ++ mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val); + + val = mt7530_read(priv, MT7530_PCR_P(port)); + if (ingress) { +@@ -1155,7 +1494,7 @@ static int mt7530_port_mirror_add(struct + return 0; + } + +-static void mt7530_port_mirror_del(struct dsa_switch *ds, int port, ++static void mt753x_port_mirror_del(struct dsa_switch *ds, int port, + struct dsa_mall_mirror_tc_entry *mirror) + { + struct mt7530_priv *priv = ds->priv; +@@ -1172,9 +1511,9 @@ static void mt7530_port_mirror_del(struc + mt7530_write(priv, MT7530_PCR_P(port), val); + + if (!priv->mirror_rx && !priv->mirror_tx) { +- val = mt7530_read(priv, MT7530_MFC); +- val &= ~MIRROR_EN; +- mt7530_write(priv, MT7530_MFC, val); ++ val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id)); ++ val &= ~MT753X_MIRROR_EN(priv->id); ++ mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val); + } + } + +@@ -1280,7 +1619,7 @@ mt7530_setup(struct dsa_switch *ds) + PCR_MATRIX_CLR); + + if (dsa_is_cpu_port(ds, i)) +- mt7530_cpu_port_enable(priv, i); ++ mt753x_cpu_port_enable(ds, i); + else + mt7530_port_disable(ds, i); + +@@ -1334,6 +1673,118 @@ mt7530_setup(struct dsa_switch *ds) + return 0; + } + ++static int ++mt7531_setup(struct dsa_switch *ds) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ struct mt7530_dummy_poll p; ++ u32 val, id; ++ int ret, i; ++ ++ /* Reset whole chip through gpio pin or memory-mapped registers for ++ * different type of hardware ++ */ ++ if (priv->mcm) { ++ reset_control_assert(priv->rstc); ++ usleep_range(1000, 1100); ++ reset_control_deassert(priv->rstc); ++ } else { ++ gpiod_set_value_cansleep(priv->reset, 0); ++ usleep_range(1000, 1100); ++ gpiod_set_value_cansleep(priv->reset, 1); ++ } ++ ++ /* Waiting for MT7530 got to stable */ ++ INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP); ++ ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0, ++ 20, 1000000); ++ if (ret < 0) { ++ dev_err(priv->dev, "reset timeout\n"); ++ return ret; ++ } ++ ++ id = mt7530_read(priv, MT7531_CREV); ++ id >>= CHIP_NAME_SHIFT; ++ ++ if (id != MT7531_ID) { ++ dev_err(priv->dev, "chip %x can't be supported\n", id); ++ return -ENODEV; ++ } ++ ++ /* Reset the switch through internal reset */ ++ mt7530_write(priv, MT7530_SYS_CTRL, ++ SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST | ++ SYS_CTRL_REG_RST); ++ ++ if (mt7531_dual_sgmii_supported(priv)) { ++ priv->p5_intf_sel = P5_INTF_SEL_GMAC5_SGMII; ++ ++ /* Let ds->slave_mii_bus be able to access external phy. */ ++ mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK, ++ MT7531_EXT_P_MDC_11); ++ mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK, ++ MT7531_EXT_P_MDIO_12); ++ } else { ++ priv->p5_intf_sel = P5_INTF_SEL_GMAC5; ++ } ++ dev_dbg(ds->dev, "P5 support %s interface\n", ++ p5_intf_modes(priv->p5_intf_sel)); ++ ++ mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK, ++ MT7531_GPIO0_INTERRUPT); ++ ++ /* Let phylink decide the interface later. */ ++ priv->p5_interface = PHY_INTERFACE_MODE_NA; ++ priv->p6_interface = PHY_INTERFACE_MODE_NA; ++ ++ /* Enable PHY core PLL, since phy_device has not yet been created ++ * provided for phy_[read,write]_mmd_indirect is called, we provide ++ * our own mt7531_ind_mmd_phy_[read,write] to complete this ++ * function. ++ */ ++ val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR, ++ MDIO_MMD_VEND2, CORE_PLL_GROUP4); ++ val |= MT7531_PHY_PLL_BYPASS_MODE; ++ val &= ~MT7531_PHY_PLL_OFF; ++ mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2, ++ CORE_PLL_GROUP4, val); ++ ++ /* BPDU to CPU port */ ++ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, ++ BIT(MT7530_CPU_PORT)); ++ mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, ++ MT753X_BPDU_CPU_ONLY); ++ ++ /* Enable and reset MIB counters */ ++ mt7530_mib_reset(ds); ++ ++ for (i = 0; i < MT7530_NUM_PORTS; i++) { ++ /* Disable forwarding by default on all ports */ ++ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, ++ PCR_MATRIX_CLR); ++ ++ mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR); ++ ++ if (dsa_is_cpu_port(ds, i)) ++ mt753x_cpu_port_enable(ds, i); ++ else ++ mt7530_port_disable(ds, i); ++ ++ /* Enable consistent egress tag */ ++ mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK, ++ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); ++ } ++ ++ ds->configure_vlan_while_not_filtering = true; ++ ++ /* Flush the FDB table */ ++ ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ + static bool + mt7530_phy_mode_supported(struct dsa_switch *ds, int port, + const struct phylink_link_state *state) +@@ -1372,6 +1823,47 @@ unsupported: + return false; + } + ++static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port) ++{ ++ return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); ++} ++ ++static bool ++mt7531_phy_supported(struct dsa_switch *ds, int port, ++ const struct phylink_link_state *state) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ switch (port) { ++ case 0: /* Internal phy */ ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ if (state->interface != PHY_INTERFACE_MODE_GMII) ++ goto unsupported; ++ break; ++ case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */ ++ if (mt7531_is_rgmii_port(priv, port)) ++ return phy_interface_mode_is_rgmii(state->interface); ++ fallthrough; ++ case 6: /* 1st cpu port supports sgmii/8023z only */ ++ if (state->interface != PHY_INTERFACE_MODE_SGMII && ++ !phy_interface_mode_is_8023z(state->interface)) ++ goto unsupported; ++ break; ++ default: ++ dev_err(priv->dev, "%s: unsupported port: %i\n", __func__, ++ port); ++ goto unsupported; ++ } ++ ++ return true; ++ ++unsupported: ++ return false; ++} ++ + static bool + mt753x_phy_mode_supported(struct dsa_switch *ds, int port, + const struct phylink_link_state *state) +@@ -1404,6 +1896,227 @@ mt7530_mac_config(struct dsa_switch *ds, + return 0; + } + ++static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port, ++ phy_interface_t interface, ++ struct phy_device *phydev) ++{ ++ u32 val; ++ ++ if (!mt7531_is_rgmii_port(priv, port)) { ++ dev_err(priv->dev, "RGMII mode is not available for port %d\n", ++ port); ++ return -EINVAL; ++ } ++ ++ val = mt7530_read(priv, MT7531_CLKGEN_CTRL); ++ val |= GP_CLK_EN; ++ val &= ~GP_MODE_MASK; ++ val |= GP_MODE(MT7531_GP_MODE_RGMII); ++ val &= ~CLK_SKEW_IN_MASK; ++ val |= CLK_SKEW_IN(MT7531_CLK_SKEW_NO_CHG); ++ val &= ~CLK_SKEW_OUT_MASK; ++ val |= CLK_SKEW_OUT(MT7531_CLK_SKEW_NO_CHG); ++ val |= TXCLK_NO_REVERSE | RXCLK_NO_DELAY; ++ ++ /* Do not adjust rgmii delay when vendor phy driver presents. */ ++ if (!phydev || phy_driver_is_genphy(phydev)) { ++ val &= ~(TXCLK_NO_REVERSE | RXCLK_NO_DELAY); ++ switch (interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ val |= TXCLK_NO_REVERSE; ++ val |= RXCLK_NO_DELAY; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ val |= TXCLK_NO_REVERSE; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ val |= RXCLK_NO_DELAY; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ mt7530_write(priv, MT7531_CLKGEN_CTRL, val); ++ ++ return 0; ++} ++ ++static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port, ++ unsigned long *supported) ++{ ++ /* Port5 supports ethier RGMII or SGMII. ++ * Port6 supports SGMII only. ++ */ ++ switch (port) { ++ case 5: ++ if (mt7531_is_rgmii_port(priv, port)) ++ break; ++ fallthrough; ++ case 6: ++ phylink_set(supported, 1000baseX_Full); ++ phylink_set(supported, 2500baseX_Full); ++ phylink_set(supported, 2500baseT_Full); ++ } ++} ++ ++static void ++mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ unsigned int val; ++ ++ /* For adjusting speed and duplex of SGMII force mode. */ ++ if (interface != PHY_INTERFACE_MODE_SGMII || ++ phylink_autoneg_inband(mode)) ++ return; ++ ++ /* SGMII force mode setting */ ++ val = mt7530_read(priv, MT7531_SGMII_MODE(port)); ++ val &= ~MT7531_SGMII_IF_MODE_MASK; ++ ++ switch (speed) { ++ case SPEED_10: ++ val |= MT7531_SGMII_FORCE_SPEED_10; ++ break; ++ case SPEED_100: ++ val |= MT7531_SGMII_FORCE_SPEED_100; ++ break; ++ case SPEED_1000: ++ val |= MT7531_SGMII_FORCE_SPEED_1000; ++ break; ++ } ++ ++ /* MT7531 SGMII 1G force mode can only work in full duplex mode, ++ * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. ++ */ ++ if ((speed == SPEED_10 || speed == SPEED_100) && ++ duplex != DUPLEX_FULL) ++ val |= MT7531_SGMII_FORCE_HALF_DUPLEX; ++ ++ mt7530_write(priv, MT7531_SGMII_MODE(port), val); ++} ++ ++static bool mt753x_is_mac_port(u32 port) ++{ ++ return (port == 5 || port == 6); ++} ++ ++static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port, ++ phy_interface_t interface) ++{ ++ u32 val; ++ ++ if (!mt753x_is_mac_port(port)) ++ return -EINVAL; ++ ++ mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), ++ MT7531_SGMII_PHYA_PWD); ++ ++ val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port)); ++ val &= ~MT7531_RG_TPHY_SPEED_MASK; ++ /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B ++ * encoding. ++ */ ++ val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ? ++ MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G; ++ mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val); ++ ++ mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); ++ ++ /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex ++ * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. ++ */ ++ mt7530_rmw(priv, MT7531_SGMII_MODE(port), ++ MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS, ++ MT7531_SGMII_FORCE_SPEED_1000); ++ ++ mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); ++ ++ return 0; ++} ++ ++static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port, ++ phy_interface_t interface) ++{ ++ if (!mt753x_is_mac_port(port)) ++ return -EINVAL; ++ ++ mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), ++ MT7531_SGMII_PHYA_PWD); ++ ++ mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port), ++ MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G); ++ ++ mt7530_set(priv, MT7531_SGMII_MODE(port), ++ MT7531_SGMII_REMOTE_FAULT_DIS | ++ MT7531_SGMII_SPEED_DUPLEX_AN); ++ ++ mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port), ++ MT7531_SGMII_TX_CONFIG_MASK, 1); ++ ++ mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); ++ ++ mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART); ++ ++ mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); ++ ++ return 0; ++} ++ ++static void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ u32 val; ++ ++ /* Only restart AN when AN is enabled */ ++ val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); ++ if (val & MT7531_SGMII_AN_ENABLE) { ++ val |= MT7531_SGMII_AN_RESTART; ++ mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val); ++ } ++} ++ ++static int ++mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, ++ phy_interface_t interface) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ struct phy_device *phydev; ++ const struct dsa_port *dp; ++ ++ if (!mt753x_is_mac_port(port)) { ++ dev_err(priv->dev, "port %d is not a MAC port\n", port); ++ return -EINVAL; ++ } ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ dp = dsa_to_port(ds, port); ++ phydev = dp->slave->phydev; ++ return mt7531_rgmii_setup(priv, port, interface, phydev); ++ case PHY_INTERFACE_MODE_SGMII: ++ return mt7531_sgmii_setup_mode_an(priv, port, interface); ++ case PHY_INTERFACE_MODE_NA: ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ if (phylink_autoneg_inband(mode)) ++ return -EINVAL; ++ ++ return mt7531_sgmii_setup_mode_force(priv, port, interface); ++ default: ++ return -EINVAL; ++ } ++ ++ return -EINVAL; ++} ++ + static int + mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode, + const struct phylink_link_state *state) +@@ -1439,6 +2152,8 @@ mt753x_phylink_mac_config(struct dsa_swi + if (mt753x_mac_config(ds, port, mode, state) < 0) + goto unsupported; + ++ if (priv->p5_intf_sel != P5_DISABLED) ++ priv->p5_interface = state->interface; + break; + case 6: /* 1st cpu port */ + if (priv->p6_interface == state->interface) +@@ -1458,7 +2173,8 @@ unsupported: + return; + } + +- if (phylink_autoneg_inband(mode)) { ++ if (phylink_autoneg_inband(mode) && ++ state->interface != PHY_INTERFACE_MODE_SGMII) { + dev_err(ds->dev, "%s: in-band negotiation unsupported\n", + __func__); + return; +@@ -1468,7 +2184,7 @@ unsupported: + mcr_new = mcr_cur; + mcr_new &= ~PMCR_LINK_SETTINGS_MASK; + mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN | +- PMCR_BACKPR_EN | PMCR_FORCE_MODE; ++ PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id); + + /* Are we connected to external phy */ + if (port == 5 && dsa_is_user_port(ds, 5)) +@@ -1478,7 +2194,18 @@ unsupported: + mt7530_write(priv, MT7530_PMCR_P(port), mcr_new); + } + +-static void mt7530_phylink_mac_link_down(struct dsa_switch *ds, int port, ++static void ++mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ if (!priv->info->mac_pcs_an_restart) ++ return; ++ ++ priv->info->mac_pcs_an_restart(ds, port); ++} ++ ++static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface) + { +@@ -1487,7 +2214,19 @@ static void mt7530_phylink_mac_link_down + mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); + } + +-static void mt7530_phylink_mac_link_up(struct dsa_switch *ds, int port, ++static void mt753x_mac_pcs_link_up(struct dsa_switch *ds, int port, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ if (!priv->info->mac_pcs_link_up) ++ return; ++ ++ priv->info->mac_pcs_link_up(ds, port, mode, interface, speed, duplex); ++} ++ ++static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, + struct phy_device *phydev, +@@ -1497,18 +2236,29 @@ static void mt7530_phylink_mac_link_up(s + struct mt7530_priv *priv = ds->priv; + u32 mcr; + ++ mt753x_mac_pcs_link_up(ds, port, mode, interface, speed, duplex); ++ + mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; + ++ /* MT753x MAC works in 1G full duplex mode for all up-clocked ++ * variants. ++ */ ++ if (interface == PHY_INTERFACE_MODE_TRGMII || ++ (phy_interface_mode_is_8023z(interface))) { ++ speed = SPEED_1000; ++ duplex = DUPLEX_FULL; ++ } ++ + switch (speed) { + case SPEED_1000: + mcr |= PMCR_FORCE_SPEED_1000; + if (priv->eee_enable & BIT(port)) +- mcr_new |= PMCR_FORCE_EEE1G; ++ mcr |= PMCR_FORCE_EEE1G; + break; + case SPEED_100: + mcr |= PMCR_FORCE_SPEED_100; + if (priv->eee_enable & BIT(port)) +- mcr_new |= PMCR_FORCE_EEE100; ++ mcr |= PMCR_FORCE_EEE100; + break; + } + if (duplex == DUPLEX_FULL) { +@@ -1522,6 +2272,45 @@ static void mt7530_phylink_mac_link_up(s + mt7530_set(priv, MT7530_PMCR_P(port), mcr); + } + ++static int ++mt7531_cpu_port_config(struct dsa_switch *ds, int port) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ phy_interface_t interface; ++ int speed; ++ ++ switch (port) { ++ case 5: ++ if (mt7531_is_rgmii_port(priv, port)) ++ interface = PHY_INTERFACE_MODE_RGMII; ++ else ++ interface = PHY_INTERFACE_MODE_2500BASEX; ++ ++ priv->p5_interface = interface; ++ break; ++ case 6: ++ interface = PHY_INTERFACE_MODE_2500BASEX; ++ ++ mt7531_pad_setup(ds, interface); ++ ++ priv->p6_interface = interface; ++ break; ++ }; ++ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) ++ speed = SPEED_2500; ++ else ++ speed = SPEED_1000; ++ ++ mt7531_mac_config(ds, port, MLO_AN_FIXED, interface); ++ mt7530_write(priv, MT7530_PMCR_P(port), ++ PMCR_CPU_PORT_SETTING(priv->id)); ++ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, ++ speed, DUPLEX_FULL, true, true); ++ ++ return 0; ++} ++ + static void + mt7530_mac_port_validate(struct dsa_switch *ds, int port, + unsigned long *supported) +@@ -1530,6 +2319,14 @@ mt7530_mac_port_validate(struct dsa_swit + phylink_set(supported, 1000baseX_Full); + } + ++static void mt7531_mac_port_validate(struct dsa_switch *ds, int port, ++ unsigned long *supported) ++{ ++ struct mt7530_priv *priv = ds->priv; ++ ++ mt7531_sgmii_validate(priv, port, supported); ++} ++ + static void + mt753x_phylink_validate(struct dsa_switch *ds, int port, + unsigned long *supported, +@@ -1546,7 +2343,8 @@ mt753x_phylink_validate(struct dsa_switc + + phylink_set_port_modes(mask); + +- if (state->interface != PHY_INTERFACE_MODE_TRGMII) { ++ if (state->interface != PHY_INTERFACE_MODE_TRGMII || ++ !phy_interface_mode_is_8023z(state->interface)) { + phylink_set(mask, 10baseT_Half); + phylink_set(mask, 10baseT_Full); + phylink_set(mask, 100baseT_Half); +@@ -1565,6 +2363,11 @@ mt753x_phylink_validate(struct dsa_switc + + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); ++ ++ /* We can only operate at 2500BaseX or 1000BaseX. If requested ++ * to advertise both, only report advertising at 2500BaseX. ++ */ ++ phylink_helper_basex_speed(state); + } + + static int +@@ -1655,6 +2458,63 @@ static int mt7530_set_mac_eee(struct dsa + return 0; + } + ++#ifdef notyet ++static int ++mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port, ++ struct phylink_link_state *state) ++{ ++ u32 status, val; ++ u16 config_reg; ++ ++ status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); ++ state->link = !!(status & MT7531_SGMII_LINK_STATUS); ++ if (state->interface == PHY_INTERFACE_MODE_SGMII && ++ (status & MT7531_SGMII_AN_ENABLE)) { ++ val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); ++ config_reg = val >> 16; ++ ++ switch (config_reg & LPA_SGMII_SPD_MASK) { ++ case LPA_SGMII_1000: ++ state->speed = SPEED_1000; ++ break; ++ case LPA_SGMII_100: ++ state->speed = SPEED_100; ++ break; ++ case LPA_SGMII_10: ++ state->speed = SPEED_10; ++ break; ++ default: ++ dev_err(priv->dev, "invalid sgmii PHY speed\n"); ++ state->link = false; ++ return -EINVAL; ++ } ++ ++ if (config_reg & LPA_SGMII_FULL_DUPLEX) ++ state->duplex = DUPLEX_FULL; ++ else ++ state->duplex = DUPLEX_HALF; ++ } ++ ++ return 0; ++} ++#endif ++ ++static int ++mt7531_phylink_mac_link_state(struct dsa_switch *ds, int port, ++ struct phylink_link_state *state) ++{ ++#ifdef notyet ++ struct mt7530_priv *priv = ds->priv; ++ ++ if (state->interface == PHY_INTERFACE_MODE_SGMII) ++ return mt7531_sgmii_pcs_get_state_an(priv, port, state); ++#else ++ return mt7530_phylink_mac_link_state(ds, port, state); ++#endif ++ ++ return -EOPNOTSUPP; ++} ++ + static int + mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port, + struct phylink_link_state *state) +@@ -1708,13 +2568,14 @@ static const struct dsa_switch_ops mt753 + .port_vlan_prepare = mt7530_port_vlan_prepare, + .port_vlan_add = mt7530_port_vlan_add, + .port_vlan_del = mt7530_port_vlan_del, +- .port_mirror_add = mt7530_port_mirror_add, +- .port_mirror_del = mt7530_port_mirror_del, ++ .port_mirror_add = mt753x_port_mirror_add, ++ .port_mirror_del = mt753x_port_mirror_del, + .phylink_validate = mt753x_phylink_validate, + .phylink_mac_link_state = mt753x_phylink_mac_link_state, + .phylink_mac_config = mt753x_phylink_mac_config, +- .phylink_mac_link_down = mt7530_phylink_mac_link_down, +- .phylink_mac_link_up = mt7530_phylink_mac_link_up, ++ .phylink_mac_an_restart = mt753x_phylink_mac_an_restart, ++ .phylink_mac_link_down = mt753x_phylink_mac_link_down, ++ .phylink_mac_link_up = mt753x_phylink_mac_link_up, + .get_mac_eee = mt7530_get_mac_eee, + .set_mac_eee = mt7530_set_mac_eee, + }; +@@ -1742,11 +2603,26 @@ static const struct mt753x_info mt753x_t + .mac_port_get_state = mt7530_phylink_mac_link_state, + .mac_port_config = mt7530_mac_config, + }, ++ [ID_MT7531] = { ++ .id = ID_MT7531, ++ .sw_setup = mt7531_setup, ++ .phy_read = mt7531_ind_phy_read, ++ .phy_write = mt7531_ind_phy_write, ++ .pad_setup = mt7531_pad_setup, ++ .cpu_port_config = mt7531_cpu_port_config, ++ .phy_mode_supported = mt7531_phy_supported, ++ .mac_port_validate = mt7531_mac_port_validate, ++ .mac_port_get_state = mt7531_phylink_mac_link_state, ++ .mac_port_config = mt7531_mac_config, ++ .mac_pcs_an_restart = mt7531_sgmii_restart_an, ++ .mac_pcs_link_up = mt7531_sgmii_link_up_force, ++ }, + }; + + static const struct of_device_id mt7530_of_match[] = { + { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, + { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, ++ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, mt7530_of_match); +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -14,6 +14,7 @@ + enum mt753x_id { + ID_MT7530 = 0, + ID_MT7621 = 1, ++ ID_MT7531 = 2, + }; + + #define NUM_TRGMII_CTRL 5 +@@ -41,6 +42,33 @@ enum mt753x_id { + #define MIRROR_PORT(x) ((x) & 0x7) + #define MIRROR_MASK 0x7 + ++/* Registers for CPU forward control */ ++#define MT7531_CFC 0x4 ++#define MT7531_MIRROR_EN BIT(19) ++#define MT7531_MIRROR_MASK (MIRROR_MASK << 16) ++#define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK) ++#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16) ++#define MT7531_CPU_PMAP_MASK GENMASK(7, 0) ++ ++#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \ ++ MT7531_CFC : MT7530_MFC) ++#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \ ++ MT7531_MIRROR_EN : MIRROR_EN) ++#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \ ++ MT7531_MIRROR_MASK : MIRROR_MASK) ++ ++/* Registers for BPDU and PAE frame control*/ ++#define MT753X_BPC 0x24 ++#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0) ++ ++enum mt753x_bpdu_port_fw { ++ MT753X_BPDU_FOLLOW_MFC, ++ MT753X_BPDU_CPU_EXCLUDE = 4, ++ MT753X_BPDU_CPU_INCLUDE = 5, ++ MT753X_BPDU_CPU_ONLY = 6, ++ MT753X_BPDU_DROP = 7, ++}; ++ + /* Registers for address table access */ + #define MT7530_ATA1 0x74 + #define STATIC_EMP 0 +@@ -222,10 +250,30 @@ enum mt7530_vlan_port_attr { + #define PMCR_FORCE_LNK BIT(0) + #define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \ + PMCR_FORCE_SPEED_1000) ++#define MT7531_FORCE_LNK BIT(31) ++#define MT7531_FORCE_SPD BIT(30) ++#define MT7531_FORCE_DPX BIT(29) ++#define MT7531_FORCE_RX_FC BIT(28) ++#define MT7531_FORCE_TX_FC BIT(27) ++#define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \ ++ MT7531_FORCE_SPD | \ ++ MT7531_FORCE_DPX | \ ++ MT7531_FORCE_RX_FC | \ ++ MT7531_FORCE_TX_FC) ++#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \ ++ MT7531_FORCE_MODE : \ ++ PMCR_FORCE_MODE) + #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ + PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ + PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ + PMCR_FORCE_FDX | PMCR_FORCE_LNK) ++#define PMCR_CPU_PORT_SETTING(id) (PMCR_FORCE_MODE_ID((id)) | \ ++ PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \ ++ PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \ ++ PMCR_TX_EN | PMCR_RX_EN | \ ++ PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ ++ PMCR_FORCE_SPEED_1000 | \ ++ PMCR_FORCE_FDX | PMCR_FORCE_LNK) + + #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100) + #define PMSR_EEE1G BIT(7) +@@ -245,6 +293,10 @@ enum mt7530_vlan_port_attr { + #define LPI_THRESH(x) ((x & 0xFFF) << 4) + #define LPI_MODE_EN BIT(0) + ++/* Register for port debug count */ ++#define MT7531_DBG_CNT(x) (0x3018 + (x) * 0x100) ++#define MT7531_DIS_CLR BIT(31) ++ + /* Register for MIB */ + #define MT7530_PORT_MIB_COUNTER(x) (0x4000 + (x) * 0x100) + #define MT7530_MIB_CCR 0x4fe0 +@@ -262,12 +314,118 @@ enum mt7530_vlan_port_attr { + CCR_RX_OCT_CNT_BAD | \ + CCR_TX_OCT_CNT_GOOD | \ + CCR_TX_OCT_CNT_BAD) ++ ++/* MT7531 SGMII register group */ ++#define MT7531_SGMII_REG_BASE 0x5000 ++#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \ ++ ((p) - 5) * 0x1000 + (r)) ++ ++/* Register forSGMII PCS_CONTROL_1 */ ++#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00) ++#define MT7531_SGMII_LINK_STATUS BIT(18) ++#define MT7531_SGMII_AN_ENABLE BIT(12) ++#define MT7531_SGMII_AN_RESTART BIT(9) ++ ++/* Register for SGMII PCS_SPPED_ABILITY */ ++#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08) ++#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0) ++#define MT7531_SGMII_TX_CONFIG BIT(0) ++ ++/* Register for SGMII_MODE */ ++#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20) ++#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8) ++#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1) ++#define MT7531_SGMII_FORCE_DUPLEX BIT(4) ++#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2) ++#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3) ++#define MT7531_SGMII_FORCE_SPEED_100 BIT(2) ++#define MT7531_SGMII_FORCE_SPEED_10 0 ++#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1) ++ ++enum mt7531_sgmii_force_duplex { ++ MT7531_SGMII_FORCE_FULL_DUPLEX = 0, ++ MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10, ++}; ++ ++/* Fields of QPHY_PWR_STATE_CTRL */ ++#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8) ++#define MT7531_SGMII_PHYA_PWD BIT(4) ++ ++/* Values of SGMII SPEED */ ++#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128) ++#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3)) ++#define MT7531_RG_TPHY_SPEED_1_25G 0x0 ++#define MT7531_RG_TPHY_SPEED_3_125G BIT(2) ++ + /* Register for system reset */ + #define MT7530_SYS_CTRL 0x7000 + #define SYS_CTRL_PHY_RST BIT(2) + #define SYS_CTRL_SW_RST BIT(1) + #define SYS_CTRL_REG_RST BIT(0) + ++/* Register for PHY Indirect Access Control */ ++#define MT7531_PHY_IAC 0x701C ++#define MT7531_PHY_ACS_ST BIT(31) ++#define MT7531_MDIO_REG_ADDR_MASK (0x1f << 25) ++#define MT7531_MDIO_PHY_ADDR_MASK (0x1f << 20) ++#define MT7531_MDIO_CMD_MASK (0x3 << 18) ++#define MT7531_MDIO_ST_MASK (0x3 << 16) ++#define MT7531_MDIO_RW_DATA_MASK (0xffff) ++#define MT7531_MDIO_REG_ADDR(x) (((x) & 0x1f) << 25) ++#define MT7531_MDIO_DEV_ADDR(x) (((x) & 0x1f) << 25) ++#define MT7531_MDIO_PHY_ADDR(x) (((x) & 0x1f) << 20) ++#define MT7531_MDIO_CMD(x) (((x) & 0x3) << 18) ++#define MT7531_MDIO_ST(x) (((x) & 0x3) << 16) ++ ++enum mt7531_phy_iac_cmd { ++ MT7531_MDIO_ADDR = 0, ++ MT7531_MDIO_WRITE = 1, ++ MT7531_MDIO_READ = 2, ++ MT7531_MDIO_READ_CL45 = 3, ++}; ++ ++/* MDIO_ST: MDIO start field */ ++enum mt7531_mdio_st { ++ MT7531_MDIO_ST_CL45 = 0, ++ MT7531_MDIO_ST_CL22 = 1, ++}; ++ ++#define MT7531_MDIO_CL22_READ (MT7531_MDIO_ST(MT7531_MDIO_ST_CL22) | \ ++ MT7531_MDIO_CMD(MT7531_MDIO_READ)) ++#define MT7531_MDIO_CL22_WRITE (MT7531_MDIO_ST(MT7531_MDIO_ST_CL22) | \ ++ MT7531_MDIO_CMD(MT7531_MDIO_WRITE)) ++#define MT7531_MDIO_CL45_ADDR (MT7531_MDIO_ST(MT7531_MDIO_ST_CL45) | \ ++ MT7531_MDIO_CMD(MT7531_MDIO_ADDR)) ++#define MT7531_MDIO_CL45_READ (MT7531_MDIO_ST(MT7531_MDIO_ST_CL45) | \ ++ MT7531_MDIO_CMD(MT7531_MDIO_READ)) ++#define MT7531_MDIO_CL45_WRITE (MT7531_MDIO_ST(MT7531_MDIO_ST_CL45) | \ ++ MT7531_MDIO_CMD(MT7531_MDIO_WRITE)) ++ ++/* Register for RGMII clock phase */ ++#define MT7531_CLKGEN_CTRL 0x7500 ++#define CLK_SKEW_OUT(x) (((x) & 0x3) << 8) ++#define CLK_SKEW_OUT_MASK GENMASK(9, 8) ++#define CLK_SKEW_IN(x) (((x) & 0x3) << 6) ++#define CLK_SKEW_IN_MASK GENMASK(7, 6) ++#define RXCLK_NO_DELAY BIT(5) ++#define TXCLK_NO_REVERSE BIT(4) ++#define GP_MODE(x) (((x) & 0x3) << 1) ++#define GP_MODE_MASK GENMASK(2, 1) ++#define GP_CLK_EN BIT(0) ++ ++enum mt7531_gp_mode { ++ MT7531_GP_MODE_RGMII = 0, ++ MT7531_GP_MODE_MII = 1, ++ MT7531_GP_MODE_REV_MII = 2 ++}; ++ ++enum mt7531_clk_skew { ++ MT7531_CLK_SKEW_NO_CHG = 0, ++ MT7531_CLK_SKEW_DLY_100PPS = 1, ++ MT7531_CLK_SKEW_DLY_200PPS = 2, ++ MT7531_CLK_SKEW_REVERSE = 3, ++}; ++ + /* Register for hw trap status */ + #define MT7530_HWTRAP 0x7800 + #define HWTRAP_XTAL_MASK (BIT(10) | BIT(9)) +@@ -275,6 +433,16 @@ enum mt7530_vlan_port_attr { + #define HWTRAP_XTAL_40MHZ (BIT(10)) + #define HWTRAP_XTAL_20MHZ (BIT(9)) + ++#define MT7531_HWTRAP 0x7800 ++#define HWTRAP_XTAL_FSEL_MASK BIT(7) ++#define HWTRAP_XTAL_FSEL_25MHZ BIT(7) ++#define HWTRAP_XTAL_FSEL_40MHZ 0 ++/* Unique fields of (M)HWSTRAP for MT7531 */ ++#define XTAL_FSEL_S 7 ++#define XTAL_FSEL_M BIT(7) ++#define PHY_EN BIT(6) ++#define CHG_STRAP BIT(8) ++ + /* Register for hw trap modification */ + #define MT7530_MHWTRAP 0x7804 + #define MHWTRAP_PHY0_SEL BIT(20) +@@ -289,14 +457,37 @@ enum mt7530_vlan_port_attr { + #define MT7530_TOP_SIG_CTRL 0x7808 + #define TOP_SIG_CTRL_NORMAL (BIT(17) | BIT(16)) + ++#define MT7531_TOP_SIG_SR 0x780c ++#define PAD_DUAL_SGMII_EN BIT(1) ++#define PAD_MCM_SMI_EN BIT(0) ++ + #define MT7530_IO_DRV_CR 0x7810 + #define P5_IO_CLK_DRV(x) ((x) & 0x3) + #define P5_IO_DATA_DRV(x) (((x) & 0x3) << 4) + ++#define MT7531_CHIP_REV 0x781C ++ ++#define MT7531_PLLGP_EN 0x7820 ++#define EN_COREPLL BIT(2) ++#define SW_CLKSW BIT(1) ++#define SW_PLLGP BIT(0) ++ + #define MT7530_P6ECR 0x7830 + #define P6_INTF_MODE_MASK 0x3 + #define P6_INTF_MODE(x) ((x) & 0x3) + ++#define MT7531_PLLGP_CR0 0x78a8 ++#define RG_COREPLL_EN BIT(22) ++#define RG_COREPLL_POSDIV_S 23 ++#define RG_COREPLL_POSDIV_M 0x3800000 ++#define RG_COREPLL_SDM_PCW_S 1 ++#define RG_COREPLL_SDM_PCW_M 0x3ffffe ++#define RG_COREPLL_SDM_PCW_CHG BIT(0) ++ ++/* Registers for RGMII and SGMII PLL clock */ ++#define MT7531_ANA_PLLGP_CR2 0x78b0 ++#define MT7531_ANA_PLLGP_CR5 0x78bc ++ + /* Registers for TRGMII on the both side */ + #define MT7530_TRGMII_RCK_CTRL 0x7a00 + #define RX_RST BIT(31) +@@ -335,10 +526,25 @@ enum mt7530_vlan_port_attr { + #define MT7530_P5RGMIITXCR 0x7b04 + #define CSR_RGMII_TXC_CFG(x) ((x) & 0x1f) + ++/* Registers for GPIO mode */ ++#define MT7531_GPIO_MODE0 0x7c0c ++#define MT7531_GPIO0_MASK GENMASK(3, 0) ++#define MT7531_GPIO0_INTERRUPT 1 ++ ++#define MT7531_GPIO_MODE1 0x7c10 ++#define MT7531_GPIO11_RG_RXD2_MASK GENMASK(15, 12) ++#define MT7531_EXT_P_MDC_11 (2 << 12) ++#define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16) ++#define MT7531_EXT_P_MDIO_12 (2 << 16) ++ + #define MT7530_CREV 0x7ffc + #define CHIP_NAME_SHIFT 16 + #define MT7530_ID 0x7530 + ++#define MT7531_CREV 0x781C ++#define CHIP_REV_M 0x0f ++#define MT7531_ID 0x7531 ++ + /* Registers for core PLL access through mmd indirect */ + #define CORE_PLL_GROUP2 0x401 + #define RG_SYSPLL_EN_NORMAL BIT(15) +@@ -355,6 +561,10 @@ enum mt7530_vlan_port_attr { + #define RG_SYSPLL_DDSFBK_EN BIT(12) + #define RG_SYSPLL_BIAS_EN BIT(11) + #define RG_SYSPLL_BIAS_LPF_EN BIT(10) ++#define MT7531_PHY_PLL_OFF BIT(5) ++#define MT7531_PHY_PLL_BYPASS_MODE BIT(4) ++ ++#define MT753X_CTRL_PHY_ADDR 0 + + #define CORE_PLL_GROUP5 0x404 + #define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff) +@@ -433,6 +643,7 @@ enum p5_interface_select { + P5_INTF_SEL_PHY_P0, + P5_INTF_SEL_PHY_P4, + P5_INTF_SEL_GMAC5, ++ P5_INTF_SEL_GMAC5_SGMII, + }; + + static const char *p5_intf_modes(unsigned int p5_interface) +@@ -446,6 +657,8 @@ static const char *p5_intf_modes(unsigne + return "PHY P4"; + case P5_INTF_SEL_GMAC5: + return "GMAC5"; ++ case P5_INTF_SEL_GMAC5_SGMII: ++ return "GMAC5_SGMII"; + default: + return "unknown"; + } +@@ -466,6 +679,10 @@ static const char *p5_intf_modes(unsigne + * MAC port + * @mac_port_config: Holding the way setting up the PHY attribute to a + * certain MAC port ++ * @mac_pcs_an_restart Holding the way restarting PCS autonegotiation for a ++ * certain MAC port ++ * @mac_pcs_link_up: Holding the way setting up the PHY attribute to the pcs ++ * of the certain MAC port + */ + struct mt753x_info { + enum mt753x_id id; +@@ -474,6 +691,7 @@ struct mt753x_info { + int (*phy_read)(struct dsa_switch *ds, int port, int regnum); + int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val); + int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface); ++ int (*cpu_port_config)(struct dsa_switch *ds, int port); + bool (*phy_mode_supported)(struct dsa_switch *ds, int port, + const struct phylink_link_state *state); + void (*mac_port_validate)(struct dsa_switch *ds, int port, +@@ -483,6 +701,10 @@ struct mt753x_info { + int (*mac_port_config)(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface); ++ void (*mac_pcs_an_restart)(struct dsa_switch *ds, int port); ++ void (*mac_pcs_link_up)(struct dsa_switch *ds, int port, ++ unsigned int mode, phy_interface_t interface, ++ int speed, int duplex); + }; + + /* struct mt7530_priv - This is the main data structure for holding the state diff --git a/root/target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch b/root/target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch new file mode 100755 index 00000000..2b3a4ae1 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0900-bt-mtk-serial-fix.patch @@ -0,0 +1,33 @@ +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -82,6 +82,7 @@ struct serial8250_config { + #define UART_CAP_MINI (1 << 17) /* Mini UART on BCM283X family lacks: + * STOP PARITY EPAR SPAR WLEN5 WLEN6 + */ ++#define UART_CAP_NMOD (1 << 18) /* UART doesn't do termios */ + + #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ + #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -291,7 +291,7 @@ static const struct serial8250_config ua + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, +- .flags = UART_CAP_FIFO, ++ .flags = UART_CAP_FIFO | UART_CAP_NMOD, + }, + [PORT_NPCM] = { + .name = "Nuvoton 16550", +@@ -2598,6 +2598,11 @@ serial8250_do_set_termios(struct uart_po + unsigned long flags; + unsigned int baud, quot, frac = 0; + ++ if (up->capabilities & UART_CAP_NMOD) { ++ termios->c_cflag = 0; ++ return; ++ } ++ + if (up->capabilities & UART_CAP_MINI) { + termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR); + if ((termios->c_cflag & CSIZE) == CS5 || diff --git a/root/target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch b/root/target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch new file mode 100755 index 00000000..a3d49e90 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0990-gsw-rtl8367s-mt7622-support.patch @@ -0,0 +1,23 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -42,6 +42,12 @@ config MDIO_BCM_IPROC + This module provides a driver for the MDIO busses found in the + Broadcom iProc SoC's. + ++config RTL8367S_GSW ++ tristate "rtl8367 Gigabit Switch support for mt7622" ++ depends on NET_VENDOR_MEDIATEK ++ help ++ This driver supports rtl8367s in mt7622 ++ + config MDIO_BCM_UNIMAC + tristate "Broadcom UniMAC MDIO bus controller" + depends on HAS_IOMEM +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -110,4 +110,5 @@ obj-$(CONFIG_TERANETICS_PHY) += teraneti + obj-$(CONFIG_VITESSE_PHY) += vitesse.o + obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o + obj-$(CONFIG_MT753X_GSW) += mtk/mt753x/ ++obj-$(CONFIG_RTL8367S_GSW) += rtk/ + diff --git a/root/target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch b/root/target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch new file mode 100755 index 00000000..02e4c130 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch @@ -0,0 +1,415 @@ +From patchwork Thu May 28 06:16:45 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Chuanjia Liu +X-Patchwork-Id: 11574793 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 391201392 + for ; + Thu, 28 May 2020 06:20:27 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id 104F620657 + for ; + Thu, 28 May 2020 06:20:27 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="raZHaWxs"; + dkim=fail reason="signature verification failed" (1024-bit key) + header.d=mediatek.com header.i=@mediatek.com header.b="YztrByG/" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 104F620657 +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=mediatek.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=aVtKU+Ey8KEM97+S66fz9ZMo+H8BP570jhAAvaRsNWc=; b=raZHaWxsfCxsrd + Byn/w1oLN/J82ApnNdBBXixq9Qj0uXIU2tBVqkiQ9lG6QDk7uguxQSJLeTqrsI/uxQmCI/PGQtZdP + sH0oboi2sbQSqJ/1ud4uL2pPaiLRJCxINF5oWjoZMsjn/b2fWvn52P6vTr/dxDTaabiVhY0HL0J+X + 7YGc1aYtO76HZHE2ke3puR42QkI8hE9E2cEhiLWeuUiLdUBegNM5MdYftu4nJTcCXnAeJjp/wIpYG + 7X737N9cmanDf6Bxr2bNPgaYzH+m7JK6eGxuAvWo0+PE9OX7MLrXY3KjixcjD/b0he0mfEM++gBAq + KBYKl5wh1mnlR2WIWXew==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBtx-0005JC-DJ; Thu, 28 May 2020 06:20:25 +0000 +Received: from mailgw01.mediatek.com ([216.200.240.184]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBtW-0002f2-75; Thu, 28 May 2020 06:20:01 +0000 +X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; + s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=EqjC+5cHgv6eykN7FPf2mtwK9UivJ3XSCE0jEvb8h+8=; + b=YztrByG/Ia304l9KDPBwoHFYkFCN6qBXPqwZgg56CA9VitadAg2+K1VgfEU+oHqsqcsGAMdZTRMQh17tpm4bJParw6MMzAQ28te2TcxvQMV8PZMkerJdZyyYblI7ybauPWuofAQgQMtuwSKVii8eTRJbf99OZ9vDGJP3zo2j1wU=; +X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527 +Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by + mailgw01.mediatek.com + (envelope-from ) + (musrelay.mediatek.com ESMTP with TLS) + with ESMTP id 681958707; Wed, 27 May 2020 22:20:16 -0800 +Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by + MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Wed, 27 May 2020 23:18:52 -0700 +Received: from mtkcas07.mediatek.inc (172.21.101.84) by + mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Thu, 28 May 2020 14:18:49 +0800 +Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend + Transport; Thu, 28 May 2020 14:18:47 +0800 +From: +To: , , +Subject: [PATCH v2 1/4] dt-bindings: PCI: Mediatek: Update PCIe binding +Date: Thu, 28 May 2020 14:16:45 +0800 +Message-ID: <20200528061648.32078-2-chuanjia.liu@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200527_231958_261064_608CC03E +X-CRM114-Status: GOOD ( 13.95 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 + encoding + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay + lines +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, + srv_heupstream@mediatek.com, "chuanjia.liu" , + linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, + jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, + yong.wu@mediatek.com, bhelgaas@google.com, + linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org + +From: "chuanjia.liu" + +There are two independent PCIe controllers in MT2712/MT7622 platform, +and each of them should contain an independent MSI domain. + +In current architecture, MSI domain will be inherited from the root +bridge, and all of the devices will share the same MSI domain. +Hence that, the PCIe devices will not work properly if the irq number +which required is more than 32. + +Split the PCIe node for MT2712/MT7622 platform to fix MSI issue and +comply with the hardware design. + +Signed-off-by: chuanjia.liu +--- + .../bindings/pci/mediatek-pcie-cfg.yaml | 38 +++++ + .../devicetree/bindings/pci/mediatek-pcie.txt | 144 +++++++++++------- + 2 files changed, 129 insertions(+), 53 deletions(-) + create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml +@@ -0,0 +1,38 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/pci/mediatek-pcie-cfg.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Mediatek PCIECFG controller ++ ++maintainers: ++ - Chuanjia Liu ++ - Jianjun Wang ++ ++description: | ++ The MediaTek PCIECFG controller controls some feature about ++ LTSSM, ASPM and so on. ++ ++properties: ++ compatible: ++ items: ++ - enum: ++ - mediatek,mt7622-pciecfg ++ - mediatek,mt7629-pciecfg ++ - const: syscon ++ ++ reg: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ ++examples: ++ - | ++ pciecfg: pciecfg@1a140000 { ++ compatible = "mediatek,mt7622-pciecfg", "syscon"; ++ reg = <0 0x1a140000 0 0x1000>; ++ }; ++... +--- a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt ++++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt +@@ -8,7 +8,7 @@ Required properties: + "mediatek,mt7623-pcie" + "mediatek,mt7629-pcie" + - device_type: Must be "pci" +-- reg: Base addresses and lengths of the PCIe subsys and root ports. ++- reg: Base addresses and lengths of the root ports. + - reg-names: Names of the above areas to use during resource lookup. + - #address-cells: Address representation for root ports (must be 3) + - #size-cells: Size representation for root ports (must be 2) +@@ -19,10 +19,10 @@ Required properties: + - sys_ckN :transaction layer and data link layer clock + Required entries for MT2701/MT7623: + - free_ck :for reference clock of PCIe subsys +- Required entries for MT2712/MT7622: ++ Required entries for MT2712/MT7622/MT7629: + - ahb_ckN :AHB slave interface operating clock for CSR access and RC + initiated MMIO access +- Required entries for MT7622: ++ Required entries for MT7622/MT7629: + - axi_ckN :application layer MMIO channel operating clock + - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when + pcie_mac_ck/pcie_pipe_ck is turned off +@@ -47,10 +47,13 @@ Required properties for MT7623/MT2701: + - reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the + number of root ports. + +-Required properties for MT2712/MT7622: ++Required properties for MT2712/MT7622/MT7629: + -interrupts: A list of interrupt outputs of the controller, must have one + entry for each PCIe port + ++Required properties for MT7622/MT7629: ++- mediatek,pcie-subsys: Should be a phandle of the pciecfg node. ++ + In addition, the device tree node must have sub-nodes describing each + PCIe port interface, having the following mandatory properties: + +@@ -143,56 +146,73 @@ Examples for MT7623: + + Examples for MT2712: + +- pcie: pcie@11700000 { ++ pcie1: pcie@112ff000 { + compatible = "mediatek,mt2712-pcie"; + device_type = "pci"; +- reg = <0 0x11700000 0 0x1000>, +- <0 0x112ff000 0 0x1000>; +- reg-names = "port0", "port1"; ++ reg = <0 0x112ff000 0 0x1000>; ++ reg-names = "port1"; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; +- clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, +- <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, +- <&pericfg CLK_PERI_PCIE0>, ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, + <&pericfg CLK_PERI_PCIE1>; +- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; +- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; +- phy-names = "pcie-phy0", "pcie-phy1"; ++ clock-names = "sys_ck1", "ahb_ck1"; ++ phys = <&u3port1 PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy1"; + bus-range = <0x00 0xff>; +- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>; ++ status = "disabled"; + +- pcie0: pcie@0,0 { +- reg = <0x0000 0 0 0 0>; ++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 7>; +- interrupt-map = <0 0 0 1 &pcie_intc0 0>, +- <0 0 0 2 &pcie_intc0 1>, +- <0 0 0 3 &pcie_intc0 2>, +- <0 0 0 4 &pcie_intc0 3>; +- pcie_intc0: interrupt-controller { ++ interrupt-map = <0 0 0 1 &pcie_intc1 0>, ++ <0 0 0 2 &pcie_intc1 1>, ++ <0 0 0 3 &pcie_intc1 2>, ++ <0 0 0 4 &pcie_intc1 3>; ++ pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; ++ }; + +- pcie1: pcie@1,0 { +- reg = <0x0800 0 0 0 0>; ++ pcie0: pcie@11700000 { ++ compatible = "mediatek,mt2712-pcie"; ++ device_type = "pci"; ++ reg = <0 0x11700000 0 0x1000>; ++ reg-names = "port0"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, ++ <&pericfg CLK_PERI_PCIE0>; ++ clock-names = "sys_ck0", "ahb_ck0"; ++ phys = <&u3port0 PHY_TYPE_PCIE>; ++ phy-names = "pcie-phy0"; ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ status = "disabled"; ++ ++ slot0: pcie@0,0 { ++ reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 7>; +- interrupt-map = <0 0 0 1 &pcie_intc1 0>, +- <0 0 0 2 &pcie_intc1 1>, +- <0 0 0 3 &pcie_intc1 2>, +- <0 0 0 4 &pcie_intc1 3>; +- pcie_intc1: interrupt-controller { ++ interrupt-map = <0 0 0 1 &pcie_intc0 0>, ++ <0 0 0 2 &pcie_intc0 1>, ++ <0 0 0 3 &pcie_intc0 2>, ++ <0 0 0 4 &pcie_intc0 3>; ++ pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; +@@ -202,39 +222,31 @@ Examples for MT2712: + + Examples for MT7622: + +- pcie: pcie@1a140000 { ++ pcie0: pcie@1a143000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; +- reg = <0 0x1a140000 0 0x1000>, +- <0 0x1a143000 0 0x1000>, +- <0 0x1a145000 0 0x1000>; +- reg-names = "subsys", "port0", "port1"; ++ reg = <0 0x1a143000 0 0x1000>; ++ reg-names = "port0"; ++ mediatek,pcie-cfg = <&pciecfg>; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; + clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, +- <&pciesys CLK_PCIE_P1_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, +- <&pciesys CLK_PCIE_P1_AHB_EN>, + <&pciesys CLK_PCIE_P0_AUX_EN>, +- <&pciesys CLK_PCIE_P1_AUX_EN>, + <&pciesys CLK_PCIE_P0_AXI_EN>, +- <&pciesys CLK_PCIE_P1_AXI_EN>, + <&pciesys CLK_PCIE_P0_OBFF_EN>, +- <&pciesys CLK_PCIE_P1_OBFF_EN>, +- <&pciesys CLK_PCIE_P0_PIPE_EN>, +- <&pciesys CLK_PCIE_P1_PIPE_EN>; +- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", +- "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", +- "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; +- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; +- phy-names = "pcie-phy0", "pcie-phy1"; ++ <&pciesys CLK_PCIE_P0_PIPE_EN>; ++ clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", ++ "axi_ck0", "obff_ck0", "pipe_ck0"; ++ + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; +- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; ++ ranges = <0x82000000 0 0x20000000 0 0x20000000 0 0x8000000>; ++ status = "disabled"; + +- pcie0: pcie@0,0 { ++ slot0: pcie@0,0 { + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -251,8 +263,34 @@ Examples for MT7622: + #interrupt-cells = <1>; + }; + }; ++ }; ++ ++ pcie1: pcie@1a145000 { ++ compatible = "mediatek,mt7622-pcie"; ++ device_type = "pci"; ++ reg = <0 0x1a145000 0 0x1000>; ++ reg-names = "port1"; ++ mediatek,pcie-cfg = <&pciecfg>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; ++ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, ++ /* designer has connect RC1 with p0_ahb clock */ ++ <&pciesys CLK_PCIE_P0_AHB_EN>, ++ <&pciesys CLK_PCIE_P1_AUX_EN>, ++ <&pciesys CLK_PCIE_P1_AXI_EN>, ++ <&pciesys CLK_PCIE_P1_OBFF_EN>, ++ <&pciesys CLK_PCIE_P1_PIPE_EN>; ++ clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", ++ "axi_ck1", "obff_ck1", "pipe_ck1"; ++ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x28000000 0 0x28000000 0 0x8000000>; ++ status = "disabled"; + +- pcie1: pcie@1,0 { ++ slot1: pcie@1,0 { + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; diff --git a/root/target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch b/root/target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch new file mode 100755 index 00000000..3e4d44f5 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch @@ -0,0 +1,217 @@ +From patchwork Thu May 28 06:16:46 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Chuanjia Liu +X-Patchwork-Id: 11574781 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A99B60D + for ; + Thu, 28 May 2020 06:19:04 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id DCC99208FE + for ; + Thu, 28 May 2020 06:19:03 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="SpOi0ueF"; + dkim=fail reason="signature verification failed" (1024-bit key) + header.d=mediatek.com header.i=@mediatek.com header.b="UGIBoIEG" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DCC99208FE +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=mediatek.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=LIr5poLUT/UdH6/akh/pnICGGa3rUBkN+4FhE1DyOrU=; b=SpOi0ueFcoJ/ka + 4esa6cDd5oU4fp0z684ZVPaVvvhm/azSZBBMYinHaAW6EvzKcMNYIX9grP8eg/728lEPNTKVq0I8H + PQZ9KvD4uTu8Opo1hD8LsRSLr+YLpNKt3KPOY/4gpwQ97uU9rI5PwkuAxPBgR949Vh5EiG0Vaww1H + Ep+I5BFRn2LVVQZP1Z7U0A0VUcOTLJ4znoWRLEXxtM9/Wd4hwQsrEPQszeDFti/RbwGfJ5efOb5UL + fhwBzSxELEzAAgH7env/XD2sSSpVf2Qsn6WO8D3ZepMtWrRtARiaRKSNxSBQTg2SSHcjmBSJSzcX+ + w8wqWaUMs0crlBuZWS1g==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBsc-0001tI-88; Thu, 28 May 2020 06:19:02 +0000 +Received: from mailgw01.mediatek.com ([216.200.240.184]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeBsZ-0001rp-6g; Thu, 28 May 2020 06:19:01 +0000 +X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; + s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=+IjWjsF/DhknqZB+lLSZ50cyvxDap+8w4tvqhp8Dv68=; + b=UGIBoIEGJUuq5pEvYEad1HVGpiv6yma+94hva83D2gD8lYmihRWkpJxB2yn+dVtNm7ZXXoQBf+jvvULOmslJgs1HZTLJTnjpdvLmQqo42OXRXSVpTE49HdRkJZDAIWIAReBfOEkFgNxcIX3uedrtnww/NLJ2lagrYPG5ET4lI2E=; +X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527 +Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com + (envelope-from ) + (musrelay.mediatek.com ESMTP with TLS) + with ESMTP id 603406343; Wed, 27 May 2020 22:19:17 -0800 +Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by + MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Wed, 27 May 2020 23:18:47 -0700 +Received: from mtkcas07.mediatek.inc (172.21.101.84) by + mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Thu, 28 May 2020 14:18:51 +0800 +Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend + Transport; Thu, 28 May 2020 14:18:49 +0800 +From: +To: , , +Subject: [PATCH v2 2/4] PCI: mediatek: Use regmap to get shared pcie-cfg base +Date: Thu, 28 May 2020 14:16:46 +0800 +Message-ID: <20200528061648.32078-3-chuanjia.liu@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200527_231859_251275_BED2B1E2 +X-CRM114-Status: GOOD ( 11.62 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 + encoding + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay + lines +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, + srv_heupstream@mediatek.com, "chuanjia.liu" , + linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, + jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, + yong.wu@mediatek.com, bhelgaas@google.com, + linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org + +From: "chuanjia.liu" + +Use regmap to get shared pcie-cfg base and change +the method to get pcie irq. + +Signed-off-by: chuanjia.liu +--- + drivers/pci/controller/pcie-mediatek.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,6 +24,7 @@ + #include + #include + #include ++#include + #include + + #include "../pci.h" +@@ -205,6 +207,7 @@ struct mtk_pcie_port { + * struct mtk_pcie - PCIe host information + * @dev: pointer to PCIe device + * @base: IO mapped register base ++ * @cfg: IO mapped register map for PCIe config + * @free_ck: free-run reference clock + * @mem: non-prefetchable memory resource + * @ports: pointer to PCIe port information +@@ -214,6 +217,7 @@ struct mtk_pcie_port { + struct mtk_pcie { + struct device *dev; + void __iomem *base; ++ struct regmap *cfg; + struct clk *free_ck; + + struct resource mem; +@@ -651,7 +655,7 @@ static int mtk_pcie_setup_irq(struct mtk + return err; + } + +- port->irq = platform_get_irq(pdev, port->slot); ++ port->irq = platform_get_irq_byname(pdev, "pcie_irq"); + irq_set_chained_handler_and_data(port->irq, + mtk_pcie_intr_handler, port); + +@@ -666,12 +670,11 @@ static int mtk_pcie_startup_port_v2(stru + u32 val; + int err; + +- /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ +- if (pcie->base) { +- val = readl(pcie->base + PCIE_SYS_CFG_V2); +- val |= PCIE_CSR_LTSSM_EN(port->slot) | +- PCIE_CSR_ASPM_L1_EN(port->slot); +- writel(val, pcie->base + PCIE_SYS_CFG_V2); ++ /* MT7622/MT7629 platforms need to enable LTSSM and ASPM. */ ++ if (pcie->cfg) { ++ val = PCIE_CSR_LTSSM_EN(port->slot) | ++ PCIE_CSR_ASPM_L1_EN(port->slot); ++ regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val); + } + + /* Assert all reset signals */ +@@ -977,6 +980,7 @@ static int mtk_pcie_subsys_powerup(struc + struct device *dev = pcie->dev; + struct platform_device *pdev = to_platform_device(dev); + struct resource *regs; ++ struct device_node *cfg_node; + int err; + + /* get shared registers, which are optional */ +@@ -989,6 +993,13 @@ static int mtk_pcie_subsys_powerup(struc + } + } + ++ cfg_node = of_parse_phandle(dev->of_node, "mediatek,pcie-cfg", 0); ++ if (cfg_node) { ++ pcie->cfg = syscon_node_to_regmap(cfg_node); ++ if (IS_ERR(pcie->cfg)) ++ return PTR_ERR(pcie->cfg); ++ } ++ + pcie->free_ck = devm_clk_get(dev, "free_ck"); + if (IS_ERR(pcie->free_ck)) { + if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER) diff --git a/root/target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch b/root/target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch new file mode 100755 index 00000000..b20e1fce --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch @@ -0,0 +1,203 @@ +From patchwork Thu May 28 06:16:48 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Chuanjia Liu +X-Patchwork-Id: 11574797 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 30A5E1392 + for ; + Thu, 28 May 2020 06:29:05 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id 08B6320721 + for ; + Thu, 28 May 2020 06:29:05 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="auhxDafY"; + dkim=fail reason="signature verification failed" (1024-bit key) + header.d=mediatek.com header.i=@mediatek.com header.b="Kj09Arxb" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 08B6320721 +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=mediatek.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: + Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: + Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: + List-Owner; bh=+QPxF1vlOH7StIZYuXJa3V40x8QVDxCLF9AFXHblB9M=; b=auhxDafYBeaUZO + aYp2KVO8Aie0v4tYtRwBon7hF+x55JwD78SAxQR2RsSvrlOo9cMYYby+ToUWflVUWQ60FapAl+w+l + nkEjIOrLBErHwxNOcsD8T5kjyCBMqlz4OMAQYUDNJ3fSugRlGhOtxkjCGd9ebB8N2Rvu6/U8P1A9n + P15mEQoc+RLonR1+9mBgwTEXErjsraxkimTD4Txsp4IvMs3UdsMkP+r3OT5S/p+Uj6O9ES0h7xIon + aL79KaVqRLHrfZxnrVwuGiecAiTp8qLy9clHuJU32NA6ZcXH1OnWipKApgp8Ck7ys80WPKaMrat9B + XuskJ63w13DZAbCVvuGQ==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeC2J-00014n-M9; Thu, 28 May 2020 06:29:03 +0000 +Received: from mailgw02.mediatek.com ([216.200.240.185]) + by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1jeC2H-00013t-Li; Thu, 28 May 2020 06:29:03 +0000 +X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; + s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=CIwcBFK1x0LbOjDt1BG6/knHFxDHRiqj8ov/jWEZDBY=; + b=Kj09ArxbnLVTc9bpaVPT3jQrIVjhL87sSYyVF9dFypS976k78Ce9gZd0f4K3zAZbYZHYoQtuyOQ9TOeufQfgD+Cr+j5VR7pTdO2E1iXHFs/eQAz5gAjvjlK01z1JiunrLnn9dvIr6c1gEkjQHny0VpuZ1duxx79jwYusg/Nw6Wc=; +X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527 +Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by + mailgw02.mediatek.com + (envelope-from ) + (musrelay.mediatek.com ESMTP with TLS) + with ESMTP id 899663677; Wed, 27 May 2020 22:29:21 -0800 +Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by + MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Wed, 27 May 2020 23:18:50 -0700 +Received: from mtkcas07.mediatek.inc (172.21.101.84) by + mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id + 15.0.1497.2; Thu, 28 May 2020 14:18:54 +0800 +Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend + Transport; Thu, 28 May 2020 14:18:52 +0800 +From: +To: , , +Subject: [PATCH v2 4/4] ARM: dts: mediatek: Update mt7629 PCIe node +Date: Thu, 28 May 2020 14:16:48 +0800 +Message-ID: <20200528061648.32078-5-chuanjia.liu@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200527_232901_719172_E5A99C62 +X-CRM114-Status: GOOD ( 11.61 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 + encoding + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay + lines +X-BeenThere: linux-mediatek@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, + srv_heupstream@mediatek.com, "chuanjia.liu" , + linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, + jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, + yong.wu@mediatek.com, bhelgaas@google.com, + linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk +Sender: "Linux-mediatek" +Errors-To: + linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org + +From: "chuanjia.liu" + +Remove unused property and add pciecfg node. + +Signed-off-by: chuanjia.liu +--- + arch/arm/boot/dts/mt7629-rfb.dts | 3 ++- + arch/arm/boot/dts/mt7629.dtsi | 23 +++++++++++++---------- + 2 files changed, 15 insertions(+), 11 deletions(-) + +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -171,9 +171,10 @@ + }; + }; + +-&pcie { ++&pcie1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pins>; ++ status = "okay"; + }; + + &pciephy1 { +--- a/arch/arm/boot/dts/mt7629.dtsi ++++ b/arch/arm/boot/dts/mt7629.dtsi +@@ -368,16 +368,21 @@ + #reset-cells = <1>; + }; + +- pcie: pcie@1a140000 { ++ pciecfg: pciecfg@1a140000 { ++ compatible = "mediatek,mt7629-pciecfg", "syscon"; ++ reg = <0x1a140000 0x1000>; ++ }; ++ ++ pcie1: pcie@1a145000 { + compatible = "mediatek,mt7629-pcie"; + device_type = "pci"; +- reg = <0x1a140000 0x1000>, +- <0x1a145000 0x1000>; +- reg-names = "subsys","port1"; ++ reg = <0x1a145000 0x1000>; ++ reg-names = "port1"; ++ mediatek,pcie-cfg = <&pciecfg>; + #address-cells = <3>; + #size-cells = <2>; +- interrupts = , +- ; ++ interrupts = ; ++ interrupt-names = "pcie_irq"; + clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P1_AUX_EN>, +@@ -398,21 +403,19 @@ + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>; ++ status = "disabled"; + +- pcie1: pcie@1,0 { +- device_type = "pci"; ++ slot1: pcie@1,0 { + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; +- num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; +- + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; diff --git a/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch b/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch new file mode 100755 index 00000000..65a2246b --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch @@ -0,0 +1,35 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts.anc 2020-11-16 15:48:00.852410183 +0100 ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2020-11-16 15:49:23.878965822 +0100 +@@ -210,27 +210,27 @@ + + port@0 { + reg = <0>; +- label = "wan"; ++ label = "lan"; + }; + + port@1 { + reg = <1>; +- label = "lan0"; ++ label = "wan1"; + }; + + port@2 { + reg = <2>; +- label = "lan1"; ++ label = "wan2"; + }; + + port@3 { + reg = <3>; +- label = "lan2"; ++ label = "wan3"; + }; + + port@4 { + reg = <4>; +- label = "lan3"; ++ label = "wan4"; + }; + + port@6 { diff --git a/root/target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch b/root/target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch new file mode 100755 index 00000000..d3ef78dc --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/1010-pcie-mediatek-fix-clearing-interrupt-status.patch @@ -0,0 +1,24 @@ +From: Felix Fietkau +Date: Fri, 4 Sep 2020 18:33:27 +0200 +Subject: [PATCH] pcie-mediatek: fix clearing interrupt status + +Clearing the status needs to happen after running the handler, otherwise +we will get an extra spurious interrupt after the cause has been cleared + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -616,10 +616,10 @@ static void mtk_pcie_intr_handler(struct + if (status & INTX_MASK) { + for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { + /* Clear the INTx */ +- writel(1 << bit, port->base + PCIE_INT_STATUS); + virq = irq_find_mapping(port->irq_domain, + bit - INTX_SHIFT); + generic_handle_irq(virq); ++ writel(1 << bit, port->base + PCIE_INT_STATUS); + } + } + diff --git a/root/target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch b/root/target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch new file mode 100755 index 00000000..e75d76b9 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/1011-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch @@ -0,0 +1,85 @@ +From: Felix Fietkau +Date: Fri, 4 Sep 2020 18:36:06 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for coherent DMA + +It improves performance by eliminating the need for a cache flush on rx and tx + +Signed-off-by: Felix Fietkau +--- + +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -357,7 +357,7 @@ + }; + + cci_control2: slave-if@5000 { +- compatible = "arm,cci-400-ctrl-if"; ++ compatible = "arm,cci-400-ctrl-if", "syscon"; + interface-type = "ace"; + reg = <0x5000 0x1000>; + }; +@@ -969,6 +969,8 @@ + power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys>; ++ mediatek,cci-control = <&cci_control2>; ++ dma-coherent; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2506,6 +2507,13 @@ static int mtk_hw_init(struct mtk_eth *e + if (ret) + goto err_disable_pm; + ++ if (of_dma_is_coherent(eth->dev->of_node)) { ++ u32 mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | ++ ETHSYS_DMA_AG_MAP_PPE; ++ ++ regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, mask, mask); ++ } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { + ret = device_reset(eth->dev); + if (ret) { +@@ -3104,6 +3112,16 @@ static int mtk_probe(struct platform_dev + } + } + ++ if (of_dma_is_coherent(pdev->dev.of_node)) { ++ struct regmap *cci; ++ ++ cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, ++ "mediatek,cci-control"); ++ /* enable CPU/bus coherency */ ++ if (!IS_ERR(cci)) ++ regmap_write(cci, 0, 3); ++ } ++ + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { + eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii), + GFP_KERNEL); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -448,6 +448,12 @@ + #define RSTCTRL_FE BIT(6) + #define RSTCTRL_PPE BIT(31) + ++/* ethernet dma channel agent map */ ++#define ETHSYS_DMA_AG_MAP 0x408 ++#define ETHSYS_DMA_AG_MAP_PDMA BIT(0) ++#define ETHSYS_DMA_AG_MAP_QDMA BIT(1) ++#define ETHSYS_DMA_AG_MAP_PPE BIT(2) ++ + /* SGMII subsystem config registers */ + /* Register to auto-negotiation restart */ + #define SGMSYS_PCS_CONTROL_1 0x0 diff --git a/root/target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch b/root/target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch new file mode 100755 index 00000000..a2345555 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/1020-spi-nor-w25q512jv.patch @@ -0,0 +1,25 @@ +From: David Bauer +Date: Thu, 11 Feb 2021 19:57:26 +0100 +Subject: [PATCH] mtd: spi-nor: add support for Winbond W25Q512 + +The Winbond W25Q512 is a 512mb SPI-NOR chip. It supports 4K sectors as +well as block protection and Dual-/Quad-read. + +Tested on: Ubiquiti UniFi 6 LR + +Signed-off-by: David Bauer + +Ref: https://patchwork.ozlabs.org/project/linux-mtd/patch/20210213151047.11700-1-mail@david-bauer.net/ + +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -2552,6 +2552,9 @@ static const struct flash_info spi_nor_i + .fixups = &w25q256_fixups }, + { "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024, ++ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ | ++ SPI_NOR_HAS_TB | SPI_NOR_HAS_LOCK) }, + { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024, + SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, + diff --git a/root/target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch b/root/target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch new file mode 100755 index 00000000..41ab094e --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/1021-ubnt-ledbar-driver.patch @@ -0,0 +1,29 @@ +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -824,6 +824,16 @@ config LEDS_LM36274 + Say Y to enable the LM36274 LED driver for TI LMU devices. + This supports the LED device LM36274. + ++config LEDS_UBNT_LEDBAR ++ tristate "LED support for Ubiquiti UniFi 6 LR" ++ depends on LEDS_CLASS && I2C && OF ++ help ++ This option enables support for the Ubiquiti LEDBAR ++ LED driver. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called leds-ubnt-ledbar. ++ + comment "LED Triggers" + source "drivers/leds/trigger/Kconfig" + +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X) += leds-lm36 + obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o + obj-$(CONFIG_LEDS_LM3697) += leds-lm3697.o + obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o ++obj-$(CONFIG_LEDS_UBNT_LEDBAR) += leds-ubnt-ledbar.o + + # LED SPI Drivers + obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o diff --git a/root/target/linux/mediatek/patches-5.4/120-14-arm64-dts-mediatek-add-mtk-snfi-for-mt7622.patch b/root/target/linux/mediatek/patches-5.4/120-14-arm64-dts-mediatek-add-mtk-snfi-for-mt7622.patch new file mode 100755 index 00000000..d5285676 --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/120-14-arm64-dts-mediatek-add-mtk-snfi-for-mt7622.patch @@ -0,0 +1,35 @@ +From 9ba7c246063ae43baf2e53ccc8c8b5f8d025aaaa Mon Sep 17 00:00:00 2001 +From: Chuanhong Guo +Date: Sun, 3 Apr 2022 10:19:29 +0800 +Subject: [PATCH 15/15] arm64: dts: mediatek: add mtk-snfi for mt7622 + +This patch adds a device-tree node for the MTK SPI-NAND Flash Interface +for MT7622 device tree. + +Signed-off-by: Chuanhong Guo +(cherry picked from commit 2e022641709011ef0843d0416b0f264b5fc217af) +--- + arch/arm64/boot/dts/mediatek/mt7622.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -552,6 +552,18 @@ + status = "disabled"; + }; + ++ snfi: spi@1100d000 { ++ compatible = "mediatek,mt7622-snand"; ++ reg = <0 0x1100d000 0 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFI_PD>, <&pericfg CLK_PERI_SNFI_PD>; ++ clock-names = "nfi_clk", "pad_clk"; ++ nand-ecc-engine = <&bch>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + bch: ecc@1100e000 { + compatible = "mediatek,mt7622-ecc"; + reg = <0 0x1100e000 0 0x1000>; diff --git a/root/target/linux/mediatek/patches-5.4/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch b/root/target/linux/mediatek/patches-5.4/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch new file mode 100755 index 00000000..4ac5685c --- /dev/null +++ b/root/target/linux/mediatek/patches-5.4/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch @@ -0,0 +1,28 @@ +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +@@ -847,6 +847,12 @@ + #address-cells = <0>; + #interrupt-cells = <1>; + }; ++ ++ slot0: pcie@0,0 { ++ reg = <0x0000 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ }; + }; + + pcie1: pcie@1a145000 { +@@ -885,6 +891,12 @@ + #address-cells = <0>; + #interrupt-cells = <1>; + }; ++ ++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ }; + }; + + sata: sata@1a200000 {